From 9983247cd43e4ce874d9d27427bdc075dd9ad36a Mon Sep 17 00:00:00 2001 From: Kitae Kim Date: Tue, 18 Sep 2012 15:15:39 +0900 Subject: [PATCH] Upload Tizen 2.0.0a sources. --- CODING_STYLE | 4 + Changelog | 8 +- HACKING | 11 +- MAINTAINERS | 93 +- Makefile | 222 +- Makefile.hw | 5 +- Makefile.objs | 188 +- Makefile.target | 246 +- Makefile.user | 4 +- NOTICE | 2 - QMP/qmp-shell | 0 QMP/qmp.py | 54 +- VERSION | 2 +- a.out.h | 2 +- acl.c | 19 +- aio.c | 6 +- alpha-dis.c | 4 - arch_init.c | 45 +- arch_init.h | 19 +- arm-semi.c | 119 +- arm.ld | 12 +- async.c | 126 +- audio/alsaaudio.c | 10 +- audio/audio.c | 70 +- audio/audio_pt_int.c | 2 - audio/audio_template.h | 20 +- audio/coreaudio.c | 8 +- audio/esdaudio.c | 8 +- audio/fmodaudio.c | 6 +- audio/mixeng.c | 2 +- audio/mixeng_template.h | 4 +- audio/noaudio.c | 4 +- audio/ossaudio.c | 4 +- audio/paaudio.c | 8 +- audio/sdlaudio.c | 21 +- audio/spiceaudio.c | 4 +- audio/wavaudio.c | 52 +- audio/wavcapture.c | 87 +- audio/winwaveaudio.c | 27 +- balloon.c | 128 +- balloon.h | 15 +- block-migration.c | 104 +- block.c | 1428 ++- block.h | 161 +- block/blkdebug.c | 10 +- block/blkverify.c | 9 - block/bochs.c | 19 +- block/cloop.c | 136 +- block/cow.c | 50 +- block/curl.c | 124 +- block/dmg.c | 29 +- block/nbd.c | 188 +- block/parallels.c | 23 +- block/qcow.c | 485 +- block/qcow2-cache.c | 20 +- block/qcow2-cluster.c | 81 +- block/qcow2-refcount.c | 105 +- block/qcow2-snapshot.c | 71 +- block/qcow2.c | 636 +- block/qcow2.h | 14 +- block/qed-check.c | 9 +- block/qed-cluster.c | 35 +- block/qed-gencb.c | 4 +- block/qed-l2-cache.c | 6 +- block/qed-table.c | 20 +- block/qed.c | 189 +- block/qed.h | 35 + block/raw-posix.c | 478 +- block/raw-win32.c | 181 +- block/raw.c | 75 +- block/rbd.c | 999 +- block/rbd_types.h | 71 - block/sheepdog.c | 394 +- block/vdi.c | 114 +- block/vmdk.c | 1572 ++- block/vpc.c | 84 +- block/vvfat.c | 306 +- block_int.h | 102 +- blockdev.c | 115 +- blockdev.h | 1 + bsd-user/main.c | 57 +- bsd-user/mmap.c | 16 +- bsd-user/qemu.h | 2 +- bsd-user/syscall.c | 5 +- bswap.h | 473 + bt-host.c | 3 +- bt-vhci.c | 3 +- buffered_file.c | 59 +- check-qdict.c | 9 +- check-qfloat.c | 2 +- check-qint.c | 2 +- check-qjson.c | 3 +- check-qlist.c | 8 +- check-qstring.c | 4 +- cmd.c | 176 +- compatfd.c | 61 +- compatfd.h | 1 + config.h | 2 +- configure | 1384 ++- console.c | 134 +- console.h | 44 +- cpu-all.h | 543 +- cpu-common.h | 66 +- cpu-defs.h | 20 +- cpu-exec.c | 921 +- cpus.c | 1141 +- cpus.h | 13 +- cris-dis.c | 12 +- cursor.c | 4 +- cutils.c | 110 +- darwin-user/commpage.c | 2 +- darwin-user/machload.c | 4 +- darwin-user/main.c | 55 +- darwin-user/signal.c | 4 - darwin-user/syscall.c | 2 +- default-configs/i386-softmmu.mak | 4 + default-configs/microblaze-softmmu.mak | 1 + default-configs/mips-softmmu.mak | 2 + default-configs/mips64-softmmu.mak | 2 + default-configs/mips64el-softmmu.mak | 2 + default-configs/mipsel-softmmu.mak | 2 + default-configs/pci.mak | 1 + default-configs/ppc-softmmu.mak | 1 + default-configs/ppc64-softmmu.mak | 1 + default-configs/ppcemb-softmmu.mak | 1 + default-configs/x86_64-softmmu.mak | 4 + device_tree.c | 98 +- device_tree.h | 4 +- dis-asm.h | 4 + disas.c | 17 +- dma-helpers.c | 86 +- dma.h | 38 +- docs/qdev-device-use.txt | 182 +- docs/specs/qed_spec.txt | 8 + docs/tracing.txt | 147 +- dyngen-exec.h | 34 +- elf.h | 24 + exec-all.h | 82 +- exec.c | 858 +- fpu/softfloat-macros.h | 216 +- fpu/softfloat-native.c | 514 - fpu/softfloat-native.h | 492 - fpu/softfloat-specialize.h | 495 +- fpu/softfloat.c | 1725 ++- fpu/softfloat.h | 294 +- fsdev/qemu-fsdev.c | 84 +- fsdev/qemu-fsdev.h | 24 +- gdbstub.c | 337 +- gen-icount.h | 2 +- hmp-commands.hx | 71 +- host-utils.h | 2 +- hpet.h | 22 - hppa-dis.c | 8 +- hppa.ld | 18 +- hw/3D.h | 37 - hw/a9mpcore.c | 2 +- hw/ac97.c | 317 +- hw/acpi.c | 491 +- hw/acpi.h | 68 + hw/acpi_piix4.c | 271 +- hw/adb.c | 89 +- hw/adlib.c | 11 +- hw/ads7846.c | 41 +- hw/ak8973.c | 277 - hw/ak8973.h | 10 - hw/alpha_palcode.c | 1048 -- hw/an5206.c | 25 +- hw/apb_pci.c | 109 +- hw/apic.c | 59 +- hw/apic.h | 6 +- hw/applesmc.c | 2 +- hw/arm-misc.h | 9 +- hw/arm11mpcore.c | 10 +- hw/arm_boot.c | 33 +- hw/arm_gic.c | 79 +- hw/arm_pic.c | 15 +- hw/arm_sysctl.c | 210 +- hw/arm_timer.c | 127 +- hw/armv7m.c | 51 +- hw/armv7m_nvic.c | 52 +- hw/audiodev.h | 2 +- hw/axis_dev88.c | 46 +- hw/baum.c | 56 +- hw/baum.h | 2 +- hw/bitbang_i2c.c | 9 +- hw/blizzard.c | 9 +- hw/boards.h | 1 + hw/bonito.c | 38 +- hw/bt-hci-csr.c | 7 +- hw/bt-hci.c | 32 +- hw/bt-hid.c | 66 +- hw/bt-l2cap.c | 18 +- hw/bt-sdp.c | 20 +- hw/bt.c | 6 +- hw/bt.h | 332 +- hw/cbus.c | 6 +- hw/cirrus_vga.c | 485 +- hw/cris-boot.c | 1 - hw/cris_pic_cpu.c | 7 +- hw/cs4231a.c | 38 +- hw/cuda.c | 173 +- hw/debugcon.c | 2 +- hw/dec_pci.c | 39 +- hw/devices.h | 16 +- hw/dma.c | 10 + hw/dp8393x.c | 12 +- hw/ds1225y.c | 172 +- hw/ds1338.c | 2 +- hw/dummy_m68k.c | 10 +- hw/e1000.c | 249 +- hw/e1000_hw.h | 17 + hw/eepro100.c | 592 +- hw/eeprom93xx.c | 14 +- hw/elf_ops.h | 26 +- hw/empty_slot.c | 21 +- hw/es1370.c | 73 +- hw/escc.c | 115 +- hw/escc.h | 2 +- hw/esp.c | 204 +- hw/etraxfs.c | 160 - hw/etraxfs.h | 20 +- hw/etraxfs_dma.c | 59 +- hw/etraxfs_eth.c | 108 +- hw/etraxfs_pic.c | 30 +- hw/etraxfs_ser.c | 67 +- hw/etraxfs_timer.c | 33 +- hw/event_notifier.c | 62 - hw/event_notifier.h | 16 - hw/fdc.c | 267 +- hw/fdc.h | 34 +- hw/file-op-9p.h | 107 - hw/flash.h | 33 +- hw/fmopl.c | 8 +- hw/framebuffer.c | 3 + hw/fw_cfg.c | 140 +- hw/g364fb.c | 383 +- hw/gles1_calls.c | 1396 --- hw/gles2.c | 754 -- hw/gles2.h | 357 - hw/gles2_calls.c | 2796 ----- hw/gles2_calls.h | 278 - hw/gles2_types.h | 92 - hw/grackle_pci.c | 58 +- hw/grlib_apbuart.c | 4 +- hw/grlib_gptimer.c | 31 +- hw/grlib_irqmp.c | 6 +- hw/gt64xxx.c | 90 +- hw/gumstix.c | 14 +- hw/gus.c | 43 +- hw/hda-audio.c | 26 +- hw/heathrow_pic.c | 93 +- hw/hpet.c | 30 +- hw/hpet_emul.h | 4 +- hw/hw.h | 156 +- hw/i2c-addressable.c | 86 - hw/i2c-addressable.h | 61 - hw/i2c.c | 4 +- hw/i2c.h | 7 +- hw/i8254.c | 85 +- hw/i8259.c | 440 +- hw/ide.h | 6 +- hw/ide/ahci.c | 152 +- hw/ide/ahci.h | 22 +- hw/ide/cmd646.c | 215 +- hw/ide/core.c | 1512 +-- hw/ide/ich.c | 55 +- hw/ide/internal.h | 294 +- hw/ide/isa.c | 6 +- hw/ide/macio.c | 95 +- hw/ide/microdrive.c | 6 +- hw/ide/mmio.c | 4 +- hw/ide/pci.c | 140 +- hw/ide/pci.h | 23 +- hw/ide/piix.c | 129 +- hw/ide/qdev.c | 93 +- hw/ide/via.c | 80 +- hw/integratorcp.c | 47 +- hw/intel-hda.c | 115 +- hw/intel-hda.h | 2 +- hw/ioapic.c | 12 +- hw/ioapic.h | 7 + hw/ioh3420.c | 7 +- hw/iommu.c | 386 - hw/irq.c | 37 +- hw/irq.h | 10 +- hw/isa-bus.c | 60 +- hw/isa.h | 43 +- hw/isa_mmio.c | 29 +- hw/ivshmem.c | 192 +- hw/jazz_led.c | 2 +- hw/lan9118.c | 50 +- hw/lance.c | 32 +- hw/leon3.c | 17 +- hw/lm832x.c | 10 +- hw/loader.c | 61 +- hw/loader.h | 4 +- hw/lsi53c895a.c | 558 +- hw/m48t59.c | 72 +- hw/mac_dbdma.c | 118 +- hw/mac_dbdma.h | 5 +- hw/mac_nvram.c | 73 +- hw/macio.c | 73 +- hw/mainstone.c | 64 +- hw/mainstone.h | 38 - hw/marvell_88w8618_audio.c | 2 +- hw/max111x.c | 51 +- hw/max7310.c | 26 +- hw/mc146818rtc.c | 51 +- hw/mcf5206.c | 6 +- hw/mcf5208.c | 76 +- hw/mcf_fec.c | 8 +- hw/mcf_intc.c | 4 +- hw/mcf_uart.c | 6 +- hw/mcs5000_tk.c | 247 - hw/microblaze_pic_cpu.c | 8 +- hw/mips.h | 12 - hw/mips_fulong2e.c | 53 +- hw/mips_jazz.c | 147 +- hw/mips_malta.c | 255 +- hw/mips_mipssim.c | 39 +- hw/mips_r4k.c | 74 +- hw/mips_timer.c | 10 +- hw/mipsnet.c | 155 +- hw/mpcore.c | 45 +- hw/msi.c | 18 +- hw/msix.c | 162 +- hw/msix.h | 6 +- hw/msmouse.c | 11 +- hw/msmouse.h | 2 +- hw/mst_fpga.c | 159 +- hw/multiboot.c | 46 +- hw/musicpal.c | 275 +- hw/nand.c | 424 +- hw/ne2000-isa.c | 29 +- hw/ne2000.c | 90 +- hw/ne2000.h | 8 +- hw/nseries.c | 114 +- hw/omap.h | 84 +- hw/omap1.c | 1033 +- hw/omap2.c | 148 +- hw/omap_clk.c | 8 +- hw/omap_dma.c | 4 +- hw/omap_dss.c | 13 +- hw/omap_gpio.c | 260 +- hw/omap_gpmc.c | 753 +- hw/omap_gptimer.c | 16 +- hw/omap_i2c.c | 4 +- hw/omap_intc.c | 181 +- hw/omap_l4.c | 24 +- hw/omap_lcdc.c | 9 +- hw/omap_mmc.c | 4 +- hw/omap_sdrc.c | 2 +- hw/omap_spi.c | 2 +- hw/omap_sx1.c | 13 +- hw/omap_synctimer.c | 4 +- hw/omap_uart.c | 29 +- hw/onenand.c | 372 +- hw/openpic.c | 579 +- hw/openpic.h | 6 +- hw/palm.c | 83 +- hw/parallel.c | 102 +- hw/pc.c | 288 +- hw/pc.h | 195 +- hw/pc_piix.c | 351 +- hw/pci-hotplug.c | 8 +- hw/pci-stub.c | 17 +- hw/pci.c | 687 +- hw/pci.h | 129 +- hw/pci_bridge.c | 85 +- hw/pci_host.c | 112 +- hw/pci_host.h | 23 +- hw/pci_host_template.h | 109 - hw/pci_ids.h | 21 +- hw/pci_internals.h | 25 +- hw/pci_regs.h | 63 +- hw/pcie.c | 17 +- hw/pcie.h | 2 +- hw/pcie_aer.c | 36 +- hw/pcie_host.c | 131 +- hw/pcie_host.h | 12 +- hw/pcie_port.c | 2 +- hw/pckbd.c | 61 +- hw/pcnet-pci.c | 135 +- hw/pcnet.c | 104 +- hw/pcnet.h | 26 +- hw/pcspk.c | 6 +- hw/petalogix_s3adsp1800_mmu.c | 40 +- hw/pflash_cfi01.c | 85 +- hw/pflash_cfi02.c | 122 +- hw/piix4.c | 52 +- hw/piix_pci.c | 338 +- hw/pl011.c | 80 +- hw/pl022.c | 86 +- hw/pl031.c | 10 +- hw/pl050.c | 2 +- hw/pl061.c | 206 +- hw/pl080.c | 10 +- hw/pl110.c | 117 +- hw/pl110_template.h | 104 +- hw/pl181.c | 8 +- hw/pl190.c | 2 +- hw/pl192.c | 588 - hw/pl330.c | 1571 --- hw/ppc.c | 249 +- hw/ppc.h | 38 +- hw/ppc405.h | 23 +- hw/ppc405_boards.c | 150 +- hw/ppc405_uc.c | 239 +- hw/ppc440.c | 32 +- hw/ppc440.h | 6 +- hw/ppc440_bamboo.c | 28 +- hw/ppc4xx.h | 2 + hw/ppc4xx_devs.c | 59 +- hw/ppc4xx_pci.c | 100 +- hw/ppc_mac.h | 75 +- hw/ppc_newworld.c | 112 +- hw/ppc_oldworld.c | 80 +- hw/ppc_prep.c | 138 +- hw/ppce500.h | 22 - hw/ppce500_mpc8544ds.c | 302 +- hw/ppce500_pci.c | 288 +- hw/prep_pci.c | 25 +- hw/prep_pci.h | 5 +- hw/primecell.h | 4 + hw/ps2.c | 94 +- hw/ptimer.c | 77 +- hw/pxa.h | 68 +- hw/pxa2xx.c | 827 +- hw/pxa2xx_dma.c | 219 +- hw/pxa2xx_gpio.c | 11 +- hw/pxa2xx_keypad.c | 163 +- hw/pxa2xx_lcd.c | 251 +- hw/pxa2xx_mmci.c | 18 +- hw/pxa2xx_pcmcia.c | 2 +- hw/pxa2xx_pic.c | 91 +- hw/pxa2xx_timer.c | 296 +- hw/qdev-properties.c | 54 +- hw/qdev.c | 94 +- hw/qdev.h | 8 +- hw/qt602240_ts.c | 454 - hw/qxl-logger.c | 4 +- hw/qxl-render.c | 69 +- hw/qxl.c | 773 +- hw/qxl.h | 46 +- hw/r2d.c | 48 +- hw/rc4030.c | 16 +- hw/realview.c | 126 +- hw/realview_gic.c | 40 +- hw/rtl8139.c | 877 +- hw/s390-virtio-bus.c | 47 +- hw/s390-virtio-bus.h | 7 +- hw/s390-virtio.c | 112 +- hw/s5pc1xx.c | 710 -- hw/s5pc1xx.h | 107 - hw/s5pc1xx_ac97.c | 630 - hw/s5pc1xx_clk.c | 827 -- hw/s5pc1xx_debug.c | 582 - hw/s5pc1xx_gpio.c | 621 - hw/s5pc1xx_gpio_regs.h | 228 - hw/s5pc1xx_hsmmc_regs.h | 258 - hw/s5pc1xx_i2c.c | 263 - hw/s5pc1xx_i2c_gpio.c | 147 - hw/s5pc1xx_i2s.c | 546 - hw/s5pc1xx_jpeg.c | 1034 -- hw/s5pc1xx_keyif.c | 547 - hw/s5pc1xx_lcd.c | 1505 --- hw/s5pc1xx_mmc.c | 725 -- hw/s5pc1xx_nand.c | 273 - hw/s5pc1xx_onedram.c | 1112 -- hw/s5pc1xx_onedram.h | 397 - hw/s5pc1xx_onenand.c | 382 - hw/s5pc1xx_pcm.c | 717 -- hw/s5pc1xx_pmu.c | 1295 -- hw/s5pc1xx_pwm.c | 458 - hw/s5pc1xx_rtc.c | 488 - hw/s5pc1xx_spdif.c | 807 -- hw/s5pc1xx_spi.c | 215 - hw/s5pc1xx_srom.c | 162 - hw/s5pc1xx_st.c | 408 - hw/s5pc1xx_tsadc.c | 467 - hw/s5pc1xx_uart.c | 485 - hw/s5pc1xx_usb_otg.c | 812 -- hw/s5pc1xx_wdt.c | 208 - hw/sb16.c | 36 +- hw/scsi-bus.c | 1154 +- hw/scsi-defs.h | 170 +- hw/scsi-disk.c | 1506 ++- hw/scsi-generic.c | 471 +- hw/scsi.h | 175 +- hw/sd.c | 52 +- hw/serial.c | 210 +- hw/sh7750.c | 3 +- hw/sh7750_regs.h | 6 +- hw/sh_intc.c | 13 +- hw/sh_pci.c | 73 +- hw/sh_serial.c | 4 +- hw/sh_timer.c | 6 +- hw/shix.c | 11 - hw/slavio_intctl.c | 8 +- hw/slavio_misc.c | 2 +- hw/slavio_timer.c | 8 +- hw/sm501.c | 160 +- hw/sm501_template.h | 2 +- hw/smb380.c | 326 - hw/smbios.c | 14 +- hw/smbios.h | 22 +- hw/smbus.c | 2 +- hw/smbus.h | 3 + hw/smbus_eeprom.c | 22 +- hw/smbus_smb380.c | 350 - hw/smc91c111.c | 40 +- hw/soc_dma.c | 12 +- hw/soc_dma.h | 8 +- hw/spitz.c | 74 +- hw/ssd0303.c | 4 +- hw/ssd0323.c | 2 +- hw/ssi-sd.c | 2 +- hw/ssi.c | 8 +- hw/stellaris.c | 413 +- hw/stellaris_enet.c | 33 +- hw/stellaris_input.c | 56 +- hw/sun4m.c | 85 +- hw/sun4m.h | 4 + hw/sun4m_iommu.c | 4 +- hw/sun4u.c | 147 +- hw/syborg.c | 9 +- hw/syborg_fb.c | 15 +- hw/syborg_interrupt.c | 2 +- hw/syborg_keyboard.c | 59 +- hw/syborg_pointer.c | 75 +- hw/syborg_rtc.c | 36 +- hw/syborg_serial.c | 68 +- hw/syborg_timer.c | 46 +- hw/syborg_virtio.c | 9 +- hw/sysbus.c | 109 +- hw/sysbus.h | 26 +- hw/tc58128.c | 7 +- hw/tc6393xb.c | 83 +- hw/tcx.c | 156 +- hw/tosa.c | 21 +- hw/tsc2005.c | 6 +- hw/tsc210x.c | 24 +- hw/tusb6010.c | 130 +- hw/twl92230.c | 9 +- hw/unin_pci.c | 172 +- hw/usb-bt.c | 70 +- hw/usb-bus.c | 184 +- hw/usb-desc.c | 76 +- hw/usb-desc.h | 26 +- hw/usb-ehci.c | 1993 +-- hw/usb-ehci.h | 8 - hw/usb-hid.c | 551 +- hw/usb-hub.c | 156 +- hw/usb-msd.c | 369 +- hw/usb-musb.c | 146 +- hw/usb-net.c | 83 +- hw/usb-ohci.c | 276 +- hw/usb-serial.c | 58 +- hw/usb-uhci.c | 398 +- hw/usb-wacom.c | 102 +- hw/usb.c | 233 +- hw/usb.h | 109 +- hw/versatile_pci.c | 100 +- hw/versatilepb.c | 37 +- hw/vga-isa-mm.c | 57 +- hw/vga-isa.c | 49 +- hw/vga-pci.c | 108 +- hw/vga.c | 441 +- hw/vga_int.h | 31 +- hw/vhost.c | 155 +- hw/vhost.h | 2 + hw/vhost_net.c | 30 +- hw/virtex_ml507.c | 31 +- hw/virtio-9p-debug.c | 645 - hw/virtio-9p-debug.h | 6 - hw/virtio-9p-local.c | 563 - hw/virtio-9p-posix-acl.c | 140 - hw/virtio-9p-xattr-user.c | 109 - hw/virtio-9p-xattr.c | 159 - hw/virtio-9p-xattr.h | 102 - hw/virtio-9p.c | 3744 ------ hw/virtio-9p.h | 507 - hw/virtio-balloon.c | 133 +- hw/virtio-balloon.h | 2 +- hw/virtio-blk.c | 101 +- hw/virtio-blk.h | 4 +- hw/virtio-console.c | 93 +- hw/virtio-gpi.c | 209 - hw/virtio-net.c | 21 +- hw/virtio-net.h | 2 +- hw/virtio-pci.c | 1340 +- hw/virtio-serial-bus.c | 215 +- hw/virtio-serial.h | 27 +- hw/virtio.c | 171 +- hw/virtio.h | 37 +- hw/vmmouse.c | 64 +- hw/vmport.c | 61 +- hw/vmware_vga.c | 377 +- hw/vmware_vga.h | 12 +- hw/vt82c686.c | 159 +- hw/watchdog.c | 2 +- hw/wdt_i6300esb.c | 66 +- hw/wdt_ib700.c | 4 +- hw/wm8750.c | 2 +- hw/wm8994.c | 308 - hw/wm8994_reg.h | 232 - hw/xen.h | 33 + hw/xen_backend.c | 461 +- hw/xen_backend.h | 9 +- hw/xen_common.h | 132 +- hw/xen_console.c | 36 +- hw/xen_devconfig.c | 10 +- hw/xen_disk.c | 562 +- hw/xen_domainbuild.c | 10 +- hw/xen_machine_pv.c | 2 +- hw/xen_nic.c | 274 +- hw/xenfb.c | 55 +- hw/xilinx.h | 44 +- hw/xilinx_ethlite.c | 44 +- hw/xilinx_intc.c | 29 +- hw/xilinx_timer.c | 34 +- hw/xilinx_uartlite.c | 34 +- hw/xio3130_downstream.c | 6 +- hw/xio3130_upstream.c | 6 +- hw/zaurus.c | 22 +- i386.ld | 8 +- ia64-dis.c | 3 + input.c | 131 +- ioport.c | 137 +- ioport.h | 23 +- iov.c | 103 +- iov.h | 14 +- json-lexer.c | 53 +- json-lexer.h | 1 + json-parser.c | 83 +- json-parser.h | 2 + json-streamer.c | 42 +- json-streamer.h | 1 + kvm-all.c | 2017 +-- kvm-stub.c | 36 +- kvm.h | 37 +- libfdt_env.h | 8 +- linux-aio.c | 74 +- linux-user/alpha/syscall_nr.h | 30 +- linux-user/arm/nwfpe/fpa11.c | 2 +- linux-user/arm/nwfpe/fpa11.h | 2 +- linux-user/arm/nwfpe/fpa11_cpdt.c | 10 +- linux-user/arm/nwfpe/fpa11_cprt.c | 2 +- linux-user/arm/nwfpe/fpopcode.c | 32 +- linux-user/arm/syscall_nr.h | 13 + linux-user/cris/syscall_nr.h | 2 + linux-user/elfload.c | 476 +- linux-user/elfload32.c | 30 - linux-user/flatload.c | 46 +- linux-user/i386/syscall_nr.h | 12 + linux-user/ioctls.h | 17 +- linux-user/linuxload.c | 27 +- linux-user/m68k/syscall_nr.h | 16 + linux-user/main.c | 1003 +- linux-user/microblaze/syscall_nr.h | 14 +- linux-user/mips/syscall_nr.h | 13 + linux-user/mips64/syscall_nr.h | 13 + linux-user/mipsn32/syscall_nr.h | 14 + linux-user/mmap.c | 6 +- linux-user/ppc/syscall_nr.h | 30 + linux-user/qemu-types.h | 12 + linux-user/qemu.h | 23 +- linux-user/sh4/syscall_nr.h | 34 +- linux-user/signal.c | 435 +- linux-user/sparc/syscall_nr.h | 15 + linux-user/sparc64/syscall_nr.h | 12 + linux-user/strace.c | 274 +- linux-user/strace.list | 15 +- linux-user/syscall.c | 1137 +- linux-user/syscall_defs.h | 167 +- linux-user/syscall_types.h | 20 + linux-user/vm86.c | 4 +- linux-user/x86_64/syscall_nr.h | 12 + m68k-semi.c | 9 +- migration-exec.c | 40 +- migration-fd.c | 66 +- migration-tcp.c | 81 +- migration-unix.c | 116 +- migration.c | 560 +- migration.h | 105 +- mips-dis.c | 2 +- mips.ld | 18 +- module.c | 2 +- module.h | 2 + monitor.c | 1050 +- monitor.h | 2 + nbd.c | 1045 +- nbd.h | 31 +- net-checksum.c | 86 - net.c | 234 +- net.h | 16 +- net/dump.c | 4 +- net/queue.c | 14 +- net/slirp.c | 66 +- net/socket.c | 28 +- net/tap-bsd.c | 26 +- net/tap-linux.c | 6 +- net/tap-win32.c | 14 +- net/tap.c | 1 - net/vde.c | 1 - notify.c | 4 +- notify.h | 4 +- os-posix.c | 41 +- os-win32.c | 155 +- osdep.c | 1 - osdep.h | 40 +- oslib-posix.c | 82 +- oslib-win32.c | 115 +- package/build.linux | 40 - package/build.windows | 44 - package/emulator.install.linux | 40 - package/emulator.install.windows | 17 - package/emulator.remove.linux | 10 - package/emulator.remove.windows | 9 - package/pkginfo.manifest | 38 +- path.c | 28 +- pc-bios/README | 34 +- pc-bios/bios.bin | Bin 131072 -> 131072 bytes pc-bios/gpxe-eepro100-80861209.rom | Bin 56832 -> 0 bytes pc-bios/linuxboot.bin | Bin 1024 -> 1024 bytes pc-bios/mpc8544ds.dtb | Bin 12288 -> 2028 bytes pc-bios/mpc8544ds.dts | 21 +- pc-bios/multiboot.bin | Bin 1024 -> 1024 bytes pc-bios/openbios-ppc | Bin 729876 -> 729876 bytes pc-bios/openbios-sparc32 | Bin 377388 -> 381484 bytes pc-bios/openbios-sparc64 | Bin 1598328 -> 1598328 bytes pc-bios/optionrom/multiboot.S | 2 + pc-bios/optionrom/optionrom.h | 40 +- pc-bios/pxe-e1000.bin | Bin 72192 -> 0 bytes pc-bios/pxe-ne2k_pci.bin | Bin 56320 -> 0 bytes pc-bios/pxe-pcnet.bin | Bin 56832 -> 0 bytes pc-bios/pxe-rtl8139.bin | Bin 56320 -> 0 bytes pc-bios/pxe-virtio.bin | Bin 56320 -> 0 bytes pc-bios/s390-zipl.rom | Bin 3336 -> 3304 bytes pc-bios/vgabios-tizenvga.bin | Bin 38912 -> 0 bytes pflib.c | 10 +- poison.h | 23 +- posix-aio-compat.c | 125 +- ppc.ld | 34 +- ppc64.ld | 26 +- qbool.c | 4 +- qdict.c | 12 +- qemu-barrier.h | 34 +- qemu-char.c | 738 +- qemu-char.h | 176 +- qemu-common.h | 136 +- qemu-config.c | 96 +- qemu-doc.texi | 129 +- qemu-error.c | 3 +- qemu-img-cmds.hx | 12 +- qemu-img.c | 336 +- qemu-img.texi | 23 +- qemu-io.c | 2679 ++-- qemu-lock.h | 210 +- qemu-malloc.c | 98 - qemu-nbd.c | 315 +- qemu-option.c | 67 +- qemu-option.h | 3 +- qemu-options.hx | 476 +- qemu-os-posix.h | 7 +- qemu-os-win32.h | 19 +- qemu-queue.h | 13 + qemu-sockets.c | 33 +- qemu-tech.texi | 42 +- qemu-thread.c | 192 - qemu-thread.h | 36 +- qemu-timer.c | 854 +- qemu-timer.h | 69 +- qemu-tool.c | 52 +- qemu_configure.sh | 42 - qemu_socket.h | 6 +- qerror.c | 138 +- qerror.h | 36 + qfloat.c | 4 +- qint.c | 4 +- qlist.c | 10 +- qlist.h | 11 + qmp-commands.hx | 341 +- qstring.c | 10 +- readline.c | 10 +- roms/seabios/COPYING | 674 - roms/seabios/COPYING.LESSER | 165 - roms/seabios/Makefile | 202 - roms/seabios/README | 190 - roms/seabios/TODO | 29 - roms/seabios/src/acpi-dsdt.dsl | 860 -- roms/seabios/src/acpi-dsdt.hex | 1030 -- roms/seabios/src/acpi.c | 694 -- roms/seabios/src/acpi.h | 101 - roms/seabios/src/apm.c | 232 - roms/seabios/src/asm-offsets.c | 31 - roms/seabios/src/ata.c | 1042 -- roms/seabios/src/ata.h | 151 - roms/seabios/src/biosvar.h | 332 - roms/seabios/src/block.c | 342 - roms/seabios/src/blockcmd.c | 78 - roms/seabios/src/blockcmd.h | 77 - roms/seabios/src/boot.c | 508 - roms/seabios/src/boot.h | 48 - roms/seabios/src/bootsplash.c | 258 - roms/seabios/src/bregs.h | 96 - roms/seabios/src/cdrom.c | 380 - roms/seabios/src/clock.c | 651 - roms/seabios/src/cmos.h | 74 - roms/seabios/src/config.h | 230 - roms/seabios/src/coreboot.c | 607 - roms/seabios/src/dev-i440fx.c | 116 - roms/seabios/src/dev-i440fx.h | 14 - roms/seabios/src/disk.c | 864 -- roms/seabios/src/disk.h | 258 - roms/seabios/src/entryfuncs.S | 173 - roms/seabios/src/farptr.h | 204 - roms/seabios/src/floppy.c | 614 - roms/seabios/src/font.c | 139 - roms/seabios/src/gen-defs.h | 19 - roms/seabios/src/ioport.h | 134 - roms/seabios/src/jpeg.c | 1041 -- roms/seabios/src/jpeg.h | 11 - roms/seabios/src/kbd.c | 573 - roms/seabios/src/lzmadecode.c | 398 - roms/seabios/src/lzmadecode.h | 67 - roms/seabios/src/memmap.c | 134 - roms/seabios/src/memmap.h | 33 - roms/seabios/src/misc.c | 190 - roms/seabios/src/mouse.c | 344 - roms/seabios/src/mptable.c | 206 - roms/seabios/src/mptable.h | 80 - roms/seabios/src/mtrr.c | 102 - roms/seabios/src/optionroms.c | 464 - roms/seabios/src/output.c | 556 - roms/seabios/src/paravirt.c | 359 - roms/seabios/src/paravirt.h | 101 - roms/seabios/src/pci.c | 217 - roms/seabios/src/pci.h | 138 - roms/seabios/src/pci_ids.h | 2610 ---- roms/seabios/src/pci_regs.h | 556 - roms/seabios/src/pcibios.c | 234 - roms/seabios/src/pciinit.c | 420 - roms/seabios/src/pic.c | 52 - roms/seabios/src/pic.h | 97 - roms/seabios/src/pirtable.c | 105 - roms/seabios/src/pmm.c | 602 - roms/seabios/src/pnpbios.c | 103 - roms/seabios/src/post.c | 274 - roms/seabios/src/ps2port.c | 460 - roms/seabios/src/ps2port.h | 64 - roms/seabios/src/ramdisk.c | 100 - roms/seabios/src/resume.c | 125 - roms/seabios/src/romlayout.S | 582 - roms/seabios/src/serial.c | 315 - roms/seabios/src/shadow.c | 145 - roms/seabios/src/smbios.c | 514 - roms/seabios/src/smbios.h | 166 - roms/seabios/src/smm.c | 127 - roms/seabios/src/smp.c | 137 - roms/seabios/src/ssdt-proc.dsl | 50 - roms/seabios/src/stacks.c | 404 - roms/seabios/src/system.c | 365 - roms/seabios/src/types.h | 138 - roms/seabios/src/usb-ehci.c | 760 -- roms/seabios/src/usb-ehci.h | 173 - roms/seabios/src/usb-hid.c | 427 - roms/seabios/src/usb-hid.h | 32 - roms/seabios/src/usb-hub.c | 185 - roms/seabios/src/usb-hub.h | 60 - roms/seabios/src/usb-msc.c | 252 - roms/seabios/src/usb-msc.h | 27 - roms/seabios/src/usb-ohci.c | 516 - roms/seabios/src/usb-ohci.h | 141 - roms/seabios/src/usb-uhci.c | 603 - roms/seabios/src/usb-uhci.h | 128 - roms/seabios/src/usb.c | 471 - roms/seabios/src/usb.h | 214 - roms/seabios/src/util.c | 296 - roms/seabios/src/util.h | 455 - roms/seabios/src/vgahooks.c | 317 - roms/seabios/src/virtio-blk.c | 190 - roms/seabios/src/virtio-blk.h | 43 - roms/seabios/src/virtio-pci.c | 69 - roms/seabios/src/virtio-pci.h | 104 - roms/seabios/src/virtio-ring.c | 151 - roms/seabios/src/virtio-ring.h | 131 - roms/seabios/tools/buildrom.py | 43 - roms/seabios/tools/checkrom.py | 61 - roms/seabios/tools/checkstack.py | 225 - roms/seabios/tools/checksum.py | 16 - roms/seabios/tools/gen-offsets.sh | 17 - roms/seabios/tools/layoutrom.py | 436 - roms/seabios/tools/readserial.py | 129 - roms/seabios/tools/test-gcc.sh | 88 - roms/seabios/tools/transdump.py | 50 - roms/seabios/vgasrc/clext.c | 390 - roms/seabios/vgasrc/vga.c | 1387 --- roms/seabios/vgasrc/vgaentry.S | 48 - roms/seabios/vgasrc/vgafb.c | 512 - roms/seabios/vgasrc/vgafonts.c | 785 -- roms/seabios/vgasrc/vgaio.c | 555 - roms/seabios/vgasrc/vgalayout.lds.S | 24 - roms/seabios/vgasrc/vgatables.c | 438 - roms/seabios/vgasrc/vgatables.h | 217 - roms/vgabios/.cvsignore | 1 - roms/vgabios/BUGS | 3 - roms/vgabios/COPYING | 504 - roms/vgabios/ChangeLog | 1311 -- roms/vgabios/Makefile | 103 - roms/vgabios/Notes | 11 - roms/vgabios/README | 226 - roms/vgabios/TODO | 26 - roms/vgabios/biossums.c | 282 - roms/vgabios/clext.c | 1641 --- roms/vgabios/dataseghack | 23 - roms/vgabios/tests/lfbprof/Makefile | 5 - roms/vgabios/tests/lfbprof/lfbprof.c | 594 - roms/vgabios/tests/lfbprof/lfbprof.h | 149 - roms/vgabios/tests/testbios.c | 353 - roms/vgabios/vbe.c | 1456 --- roms/vgabios/vbe.h | 315 - roms/vgabios/vbe_display_api.txt | 237 - roms/vgabios/vbetables-gen.c | 261 - roms/vgabios/vgabios.c | 3923 ------ roms/vgabios/vgabios.h | 47 - roms/vgabios/vgafonts.h | 784 -- roms/vgabios/vgatables.h | 622 - rules.mak | 16 +- rwhandler.c | 87 - rwhandler.h | 27 - savevm.c | 433 +- scripts/checkpatch.pl | 17 +- scripts/create_config | 0 scripts/qemu-binfmt-conf.sh | 4 +- scripts/signrom.sh | 0 scripts/simpletrace.py | 126 +- scripts/texi2pod.pl | 0 scripts/tracetool | 158 +- sdb.c | 351 - sdb.h | 112 - simpletrace.c | 255 - simpletrace.h | 40 - slirp/bootp.c | 23 +- slirp/if.c | 22 +- slirp/ip.h | 24 +- slirp/ip_icmp.c | 163 +- slirp/ip_icmp.h | 3 + slirp/ip_input.c | 34 +- slirp/ip_output.c | 4 +- slirp/libslirp.h | 13 +- slirp/main.h | 2 +- slirp/mbuf.c | 2 + slirp/mbuf.h | 6 +- slirp/misc.c | 23 +- slirp/slirp.c | 193 +- slirp/slirp.h | 52 +- slirp/socket.c | 8 +- slirp/tcp.h | 4 +- slirp/tcp_input.c | 41 +- slirp/tcp_subr.c | 4 +- slirp/tftp.c | 20 +- slirp/tftp.h | 2 +- slirp/udp.c | 23 +- softmmu-semi.h | 2 +- softmmu_defs.h | 8 + softmmu_exec.h | 12 +- softmmu_header.h | 9 + softmmu_template.h | 216 +- sparc.ld | 12 +- spice-qemu-char.c | 80 +- sysemu.h | 79 +- target-alpha/cpu.h | 406 +- target-alpha/exec.h | 61 - target-alpha/helper.c | 592 +- target-alpha/helper.h | 37 +- target-alpha/op_helper.c | 320 +- target-alpha/translate.c | 875 +- target-arm/cpu.h | 48 +- target-arm/exec.h | 58 - target-arm/helper.c | 891 +- target-arm/helper_gpi_dummy.c | 9 - target-arm/helpers.h | 458 - target-arm/iwmmxt_helper.c | 2 +- target-arm/machine.c | 16 +- target-arm/neon_helper.c | 676 +- target-arm/op_addsub.h | 2 +- target-arm/op_helper.c | 28 +- target-arm/opengl_dummy.c | 24 - target-arm/translate.c | 2930 +++-- target-cris/cpu.h | 20 +- target-cris/exec.h | 53 - target-cris/helper.c | 13 +- target-cris/mmu.c | 1 - target-cris/op_helper.c | 19 +- target-cris/opcode-cris.h | 12 +- target-cris/translate.c | 8 +- target-cris/translate_v10.c | 77 +- target-i386/TODO | 1 - target-i386/cpu.h | 133 +- target-i386/cpuid.c | 123 +- target-i386/exec.h | 391 - target-i386/gl_func_perso.h | 135 - target-i386/glgetv_cst.h | 468 - target-i386/helper.c | 225 +- target-i386/helper.h | 4 +- target-i386/helper_gpi.c | 115 - target-i386/helper_gpi.h | 43 - target-i386/helper_gpi_test.c | 70 - target-i386/helper_opengl.c | 1434 --- target-i386/helper_opengl.h | 5 - target-i386/kvm.c | 928 +- target-i386/kvm_x86.h | 25 - target-i386/machine.c | 209 +- target-i386/mesa_enums.c | 4890 -------- target-i386/mesa_get.c | 5563 --------- target-i386/mesa_gl.h | 2267 ---- target-i386/mesa_glext.h | 7278 ----------- target-i386/mesa_glu.h | 366 - target-i386/mesa_glx.h | 631 - target-i386/mesa_glxext.h | 1137 -- target-i386/mesa_mipmap.c | 828 -- target-i386/op_helper.c | 5675 --------- target-i386/opengl32.def | 991 -- target-i386/opengl_client.c | 12382 ------------------- target-i386/opengl_client_xfonts.c | 302 - target-i386/opengl_exec.c | 7230 ----------- target-i386/opengl_func.h | 922 -- target-i386/opengl_player.c | 1489 --- target-i386/opengl_server.c | 958 -- target-i386/opengl_server.h | 88 - target-i386/opengl_utils.h | 472 - target-i386/ops_sse.h | 149 +- target-i386/parse_gl_h.c | 1501 --- target-i386/parse_mesa_get_c.c | 224 - target-i386/svm.h | 8 +- target-i386/translate.c | 329 +- target-m68k/cpu.h | 17 +- target-m68k/exec.h | 50 - target-m68k/helper.c | 11 +- target-m68k/op_helper.c | 51 +- target-m68k/translate.c | 49 +- target-microblaze/cpu.h | 39 +- target-microblaze/exec.h | 52 - target-microblaze/helper.c | 7 +- target-microblaze/helper.h | 3 + target-microblaze/microblaze-decode.h | 3 + target-microblaze/mmu.c | 1 - target-microblaze/op_helper.c | 73 +- target-microblaze/translate.c | 67 +- target-mips/cpu.h | 89 +- target-mips/exec.h | 98 - target-mips/helper.c | 27 +- target-mips/helper.h | 10 + target-mips/machine.c | 2 +- target-mips/op_helper.c | 945 +- target-mips/translate.c | 120 +- target-mips/translate_init.c | 12 +- target-ppc/STATUS | 2 +- target-ppc/cpu.h | 540 +- target-ppc/exec.h | 57 - target-ppc/helper.c | 1018 +- target-ppc/helper.h | 15 +- target-ppc/kvm.c | 599 +- target-ppc/kvm_ppc.c | 73 +- target-ppc/kvm_ppc.h | 96 +- target-ppc/machine.c | 22 +- target-ppc/op_helper.c | 377 +- target-ppc/translate.c | 1070 +- target-ppc/translate_init.c | 644 +- target-s390x/cpu.h | 812 +- target-s390x/exec.h | 53 - target-s390x/helper.c | 594 +- target-s390x/kvm.c | 105 +- target-s390x/op_helper.c | 2971 ++++- target-s390x/translate.c | 5206 +++++++- target-sh4/cpu.h | 17 +- target-sh4/exec.h | 56 - target-sh4/helper.c | 9 +- target-sh4/helper.h | 48 +- target-sh4/op_helper.c | 228 +- target-sh4/translate.c | 22 +- target-sparc/cpu.h | 157 +- target-sparc/exec.h | 41 - target-sparc/helper.c | 1543 +-- target-sparc/helper.h | 246 +- target-sparc/machine.c | 48 +- target-sparc/op_helper.c | 4479 +------ target-sparc/translate.c | 1639 ++- tcg/README | 10 +- tcg/arm/tcg-target.c | 82 +- tcg/arm/tcg-target.h | 35 +- tcg/hppa/tcg-target.c | 79 +- tcg/hppa/tcg-target.h | 36 +- tcg/i386/tcg-target.c | 180 +- tcg/i386/tcg-target.h | 77 +- tcg/ia64/tcg-target.c | 43 +- tcg/ia64/tcg-target.h | 72 +- tcg/mips/tcg-target.c | 23 +- tcg/mips/tcg-target.h | 40 +- tcg/optimize.c | 806 +- tcg/ppc/tcg-target.c | 56 +- tcg/ppc/tcg-target.h | 40 +- tcg/ppc64/tcg-target.c | 53 +- tcg/ppc64/tcg-target.h | 73 +- tcg/s390/tcg-target.c | 16 +- tcg/s390/tcg-target.h | 74 +- tcg/sparc/tcg-target.c | 32 +- tcg/sparc/tcg-target.h | 78 +- tcg/tcg-op.h | 1076 +- tcg/tcg-opc.h | 248 +- tcg/tcg.c | 278 +- tcg/tcg.h | 224 +- tests/Makefile | 4 + tests/cris/check_openpf1.c | 2 +- tests/cris/check_openpf2.c | 2 +- tests/cris/check_stat3.c | 2 +- tests/cris/check_stat4.c | 2 +- tests/linux-test.c | 2 + tests/qruncom.c | 8 +- tests/test-i386.c | 14 +- tests/test-mmap.c | 6 +- tests/test_path.c | 2 +- tizen/AUTHOR | 13 - tizen/COPYING | 341 - tizen/Makefile.in | 23 - tizen/NOTICE | 1 - tizen/README | 10 - tizen/build.sh | 9 +- tizen/configure.ac | 101 - tizen/data/pc-bios/bios.bin | Bin 131072 -> 0 bytes tizen/data/pc-bios/linuxboot.bin | Bin 1024 -> 0 bytes tizen/data/pc-bios/pxe-rtl8139.bin | Bin 56320 -> 0 bytes tizen/data/pc-bios/pxe-virtio.bin | Bin 56320 -> 0 bytes tizen/data/pc-bios/vgabios-tizenvga.bin | Bin 38912 -> 0 bytes tizen/data/pc-bios/vgabios.bin | Bin 36352 -> 0 bytes tizen/data/sdcard_1024.img | Bin 2097152 -> 0 bytes tizen/data/sdcard_1536.img | Bin 2621440 -> 0 bytes tizen/data/sdcard_256.img | Bin 5308416 -> 0 bytes tizen/data/sdcard_512.img | Bin 1245184 -> 0 bytes tizen/distrib/ffmpeg/COPYING.GPLv2 | 339 - tizen/distrib/ffmpeg/COPYING.GPLv3 | 674 - tizen/distrib/ffmpeg/COPYING.LGPLv2.1 | 504 - tizen/distrib/ffmpeg/COPYING.LGPLv3 | 165 - tizen/distrib/ffmpeg/CREDITS | 53 - tizen/distrib/ffmpeg/Changelog | 596 - tizen/distrib/ffmpeg/Doxyfile | 1037 -- tizen/distrib/ffmpeg/INSTALL | 11 - tizen/distrib/ffmpeg/LICENSE | 50 - tizen/distrib/ffmpeg/MAINTAINERS | 359 - tizen/distrib/ffmpeg/Makefile | 353 - tizen/distrib/ffmpeg/README | 12 - tizen/distrib/ffmpeg/RELEASE | 96 - tizen/distrib/ffmpeg/VERSION | 1 - tizen/distrib/ffmpeg/cmdutils.c | 664 - tizen/distrib/ffmpeg/cmdutils.h | 223 - tizen/distrib/ffmpeg/cmdutils_common_opts.h | 13 - tizen/distrib/ffmpeg/common.mak | 109 - tizen/distrib/ffmpeg/configure | 3172 ----- tizen/distrib/ffmpeg/doc/APIchanges | 239 - tizen/distrib/ffmpeg/doc/TODO | 90 - tizen/distrib/ffmpeg/doc/avutil.txt | 37 - tizen/distrib/ffmpeg/doc/developer.texi | 436 - tizen/distrib/ffmpeg/doc/faq.texi | 503 - tizen/distrib/ffmpeg/doc/ffmpeg-doc.texi | 956 -- ...ffmpeg_powerpc_performance_evaluation_howto.txt | 172 - tizen/distrib/ffmpeg/doc/ffplay-doc.texi | 160 - tizen/distrib/ffmpeg/doc/ffprobe-doc.texi | 121 - tizen/distrib/ffmpeg/doc/ffserver-doc.texi | 274 - tizen/distrib/ffmpeg/doc/ffserver.conf | 356 - tizen/distrib/ffmpeg/doc/fftools-common-opts.texi | 72 - tizen/distrib/ffmpeg/doc/general.texi | 1061 -- tizen/distrib/ffmpeg/doc/issue_tracker.txt | 228 - tizen/distrib/ffmpeg/doc/libavfilter.texi | 307 - tizen/distrib/ffmpeg/doc/optimization.txt | 235 - tizen/distrib/ffmpeg/doc/rate_distortion.txt | 61 - tizen/distrib/ffmpeg/doc/snow.txt | 630 - tizen/distrib/ffmpeg/doc/soc.txt | 24 - tizen/distrib/ffmpeg/doc/swscale.txt | 99 - tizen/distrib/ffmpeg/doc/tablegen.txt | 64 - tizen/distrib/ffmpeg/doc/texi2pod.pl | 427 - tizen/distrib/ffmpeg/doc/viterbi.txt | 110 - tizen/distrib/ffmpeg/ffmpeg.c | 4173 ------- tizen/distrib/ffmpeg/ffplay.c | 3166 ----- .../ffmpeg/ffpresets/libx264-baseline.ffpreset | 4 - .../ffmpeg/ffpresets/libx264-default.ffpreset | 22 - .../distrib/ffmpeg/ffpresets/libx264-fast.ffpreset | 23 - .../ffpresets/libx264-fast_firstpass.ffpreset | 23 - .../ffmpeg/ffpresets/libx264-faster.ffpreset | 23 - .../ffpresets/libx264-faster_firstpass.ffpreset | 23 - .../ffpresets/libx264-fastfirstpass.ffpreset | 22 - tizen/distrib/ffmpeg/ffpresets/libx264-hq.ffpreset | 22 - .../ffmpeg/ffpresets/libx264-ipod320.ffpreset | 7 - .../ffmpeg/ffpresets/libx264-ipod640.ffpreset | 8 - .../ffpresets/libx264-lossless_fast.ffpreset | 20 - .../ffmpeg/ffpresets/libx264-lossless_max.ffpreset | 21 - .../ffpresets/libx264-lossless_medium.ffpreset | 20 - .../ffpresets/libx264-lossless_slow.ffpreset | 21 - .../ffpresets/libx264-lossless_slower.ffpreset | 21 - .../ffpresets/libx264-lossless_ultrafast.ffpreset | 19 - .../distrib/ffmpeg/ffpresets/libx264-main.ffpreset | 1 - .../distrib/ffmpeg/ffpresets/libx264-max.ffpreset | 22 - .../ffmpeg/ffpresets/libx264-medium.ffpreset | 22 - .../ffpresets/libx264-medium_firstpass.ffpreset | 22 - .../ffmpeg/ffpresets/libx264-normal.ffpreset | 22 - .../ffmpeg/ffpresets/libx264-placebo.ffpreset | 23 - .../ffpresets/libx264-placebo_firstpass.ffpreset | 23 - .../distrib/ffmpeg/ffpresets/libx264-slow.ffpreset | 23 - .../ffpresets/libx264-slow_firstpass.ffpreset | 23 - .../ffmpeg/ffpresets/libx264-slower.ffpreset | 23 - .../ffpresets/libx264-slower_firstpass.ffpreset | 23 - .../ffpresets/libx264-slowfirstpass.ffpreset | 22 - .../ffmpeg/ffpresets/libx264-superfast.ffpreset | 22 - .../ffpresets/libx264-superfast_firstpass.ffpreset | 22 - .../ffmpeg/ffpresets/libx264-ultrafast.ffpreset | 23 - .../ffpresets/libx264-ultrafast_firstpass.ffpreset | 23 - .../ffmpeg/ffpresets/libx264-veryfast.ffpreset | 22 - .../ffpresets/libx264-veryfast_firstpass.ffpreset | 22 - .../ffmpeg/ffpresets/libx264-veryslow.ffpreset | 23 - .../ffpresets/libx264-veryslow_firstpass.ffpreset | 23 - tizen/distrib/ffmpeg/ffprobe.c | 367 - tizen/distrib/ffmpeg/ffserver.c | 4697 ------- tizen/distrib/ffmpeg/ffserver.h | 28 - tizen/distrib/ffmpeg/include/libavcodec/avcodec.h | 4021 ------ tizen/distrib/ffmpeg/include/libavcodec/avfft.h | 99 - tizen/distrib/ffmpeg/include/libavcodec/dxva2.h | 68 - tizen/distrib/ffmpeg/include/libavcodec/opt.h | 211 - tizen/distrib/ffmpeg/include/libavcodec/vaapi.h | 167 - tizen/distrib/ffmpeg/include/libavcodec/vdpau.h | 89 - tizen/distrib/ffmpeg/include/libavcodec/xvmc.h | 172 - .../distrib/ffmpeg/include/libavdevice/avdevice.h | 58 - .../distrib/ffmpeg/include/libavfilter/avfilter.h | 703 -- .../distrib/ffmpeg/include/libavformat/avformat.h | 1355 -- tizen/distrib/ffmpeg/include/libavformat/avio.h | 525 - tizen/distrib/ffmpeg/include/libavutil/adler32.h | 30 - .../distrib/ffmpeg/include/libavutil/attributes.h | 113 - tizen/distrib/ffmpeg/include/libavutil/avconfig.h | 5 - tizen/distrib/ffmpeg/include/libavutil/avstring.h | 117 - tizen/distrib/ffmpeg/include/libavutil/avutil.h | 89 - tizen/distrib/ffmpeg/include/libavutil/base64.h | 49 - tizen/distrib/ffmpeg/include/libavutil/common.h | 308 - tizen/distrib/ffmpeg/include/libavutil/crc.h | 44 - tizen/distrib/ffmpeg/include/libavutil/error.h | 72 - tizen/distrib/ffmpeg/include/libavutil/fifo.h | 116 - .../ffmpeg/include/libavutil/intfloat_readwrite.h | 40 - tizen/distrib/ffmpeg/include/libavutil/log.h | 123 - tizen/distrib/ffmpeg/include/libavutil/lzo.h | 66 - .../distrib/ffmpeg/include/libavutil/mathematics.h | 98 - tizen/distrib/ffmpeg/include/libavutil/md5.h | 36 - tizen/distrib/ffmpeg/include/libavutil/mem.h | 125 - tizen/distrib/ffmpeg/include/libavutil/pixdesc.h | 154 - tizen/distrib/ffmpeg/include/libavutil/pixfmt.h | 163 - tizen/distrib/ffmpeg/include/libavutil/rational.h | 129 - tizen/distrib/ffmpeg/include/libavutil/sha1.h | 57 - tizen/distrib/ffmpeg/include/libswscale/swscale.h | 330 - tizen/distrib/ffmpeg/lib/libavcodec.a | Bin 9931482 -> 0 bytes tizen/distrib/ffmpeg/lib/libavcodec.dll.a | Bin 415906 -> 0 bytes tizen/distrib/ffmpeg/lib/libavdevice.a | Bin 46974 -> 0 bytes tizen/distrib/ffmpeg/lib/libavdevice.dll.a | Bin 3464 -> 0 bytes tizen/distrib/ffmpeg/lib/libavfilter.a | Bin 307068 -> 0 bytes tizen/distrib/ffmpeg/lib/libavformat.a | Bin 557054 -> 0 bytes tizen/distrib/ffmpeg/lib/libavformat.dll.a | Bin 109306 -> 0 bytes tizen/distrib/ffmpeg/lib/libavutil.a | Bin 276800 -> 0 bytes tizen/distrib/ffmpeg/lib/libavutil.dll.a | Bin 61512 -> 0 bytes tizen/distrib/ffmpeg/lib/libswscale.a | Bin 1051848 -> 0 bytes tizen/distrib/ffmpeg/lib/pkgconfig/libavcodec.pc | 14 - tizen/distrib/ffmpeg/lib/pkgconfig/libavdevice.pc | 14 - tizen/distrib/ffmpeg/lib/pkgconfig/libavfilter.pc | 14 - tizen/distrib/ffmpeg/lib/pkgconfig/libavformat.pc | 14 - tizen/distrib/ffmpeg/lib/pkgconfig/libavutil.pc | 14 - tizen/distrib/ffmpeg/lib/pkgconfig/libswscale.pc | 14 - tizen/distrib/ffmpeg/libavcodec/4xm.c | 855 -- tizen/distrib/ffmpeg/libavcodec/8bps.c | 233 - tizen/distrib/ffmpeg/libavcodec/8svx.c | 113 - tizen/distrib/ffmpeg/libavcodec/Makefile | 655 - tizen/distrib/ffmpeg/libavcodec/aac.c | 2108 ---- tizen/distrib/ffmpeg/libavcodec/aac.h | 295 - tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.c | 102 - tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.h | 65 - .../distrib/ffmpeg/libavcodec/aac_adtstoasc_bsf.c | 114 - tizen/distrib/ffmpeg/libavcodec/aac_parser.c | 112 - tizen/distrib/ffmpeg/libavcodec/aac_parser.h | 55 - tizen/distrib/ffmpeg/libavcodec/aaccoder.c | 960 -- tizen/distrib/ffmpeg/libavcodec/aacdectab.h | 95 - tizen/distrib/ffmpeg/libavcodec/aacenc.c | 651 - tizen/distrib/ffmpeg/libavcodec/aacenc.h | 71 - tizen/distrib/ffmpeg/libavcodec/aacpsy.c | 318 - tizen/distrib/ffmpeg/libavcodec/aacpsy.h | 50 - tizen/distrib/ffmpeg/libavcodec/aacsbr.c | 1766 --- tizen/distrib/ffmpeg/libavcodec/aacsbr.h | 49 - tizen/distrib/ffmpeg/libavcodec/aacsbrdata.h | 614 - tizen/distrib/ffmpeg/libavcodec/aactab.c | 1332 -- tizen/distrib/ffmpeg/libavcodec/aactab.h | 82 - tizen/distrib/ffmpeg/libavcodec/aandcttab.c | 47 - tizen/distrib/ffmpeg/libavcodec/aandcttab.h | 32 - tizen/distrib/ffmpeg/libavcodec/aasc.c | 123 - tizen/distrib/ffmpeg/libavcodec/ac3.c | 281 - tizen/distrib/ffmpeg/libavcodec/ac3.h | 187 - tizen/distrib/ffmpeg/libavcodec/ac3_parser.c | 207 - tizen/distrib/ffmpeg/libavcodec/ac3_parser.h | 52 - tizen/distrib/ffmpeg/libavcodec/ac3dec.c | 1462 --- tizen/distrib/ffmpeg/libavcodec/ac3dec.h | 232 - tizen/distrib/ffmpeg/libavcodec/ac3dec_data.c | 72 - tizen/distrib/ffmpeg/libavcodec/ac3dec_data.h | 34 - tizen/distrib/ffmpeg/libavcodec/ac3enc.c | 1425 --- tizen/distrib/ffmpeg/libavcodec/ac3tab.c | 305 - tizen/distrib/ffmpeg/libavcodec/ac3tab.h | 62 - tizen/distrib/ffmpeg/libavcodec/acelp_filters.c | 145 - tizen/distrib/ffmpeg/libavcodec/acelp_filters.h | 120 - .../distrib/ffmpeg/libavcodec/acelp_pitch_delay.c | 186 - .../distrib/ffmpeg/libavcodec/acelp_pitch_delay.h | 255 - tizen/distrib/ffmpeg/libavcodec/acelp_vectors.c | 270 - tizen/distrib/ffmpeg/libavcodec/acelp_vectors.h | 264 - tizen/distrib/ffmpeg/libavcodec/adpcm.c | 1701 --- tizen/distrib/ffmpeg/libavcodec/adx.h | 49 - tizen/distrib/ffmpeg/libavcodec/adxdec.c | 180 - tizen/distrib/ffmpeg/libavcodec/adxenc.c | 197 - tizen/distrib/ffmpeg/libavcodec/alac.c | 712 -- tizen/distrib/ffmpeg/libavcodec/alacenc.c | 532 - tizen/distrib/ffmpeg/libavcodec/allcodecs.c | 385 - tizen/distrib/ffmpeg/libavcodec/alpha/Makefile | 6 - tizen/distrib/ffmpeg/libavcodec/alpha/asm.h | 186 - .../ffmpeg/libavcodec/alpha/dsputil_alpha.c | 341 - .../ffmpeg/libavcodec/alpha/dsputil_alpha.h | 50 - .../ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S | 285 - .../ffmpeg/libavcodec/alpha/motion_est_alpha.c | 346 - .../ffmpeg/libavcodec/alpha/motion_est_mvi_asm.S | 184 - .../ffmpeg/libavcodec/alpha/mpegvideo_alpha.c | 110 - tizen/distrib/ffmpeg/libavcodec/alpha/regdef.h | 66 - .../ffmpeg/libavcodec/alpha/simple_idct_alpha.c | 304 - tizen/distrib/ffmpeg/libavcodec/alsdec.c | 1636 --- tizen/distrib/ffmpeg/libavcodec/amrnbdata.h | 1672 --- tizen/distrib/ffmpeg/libavcodec/amrnbdec.c | 1076 -- tizen/distrib/ffmpeg/libavcodec/anm.c | 197 - tizen/distrib/ffmpeg/libavcodec/apedec.c | 891 -- tizen/distrib/ffmpeg/libavcodec/api-example.c | 467 - tizen/distrib/ffmpeg/libavcodec/arm/Makefile | 53 - tizen/distrib/ffmpeg/libavcodec/arm/aac.h | 137 - tizen/distrib/ffmpeg/libavcodec/arm/asm.S | 72 - .../ffmpeg/libavcodec/arm/dcadsp_init_arm.c | 32 - tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_neon.S | 61 - tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.S | 712 -- tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.h | 33 - .../distrib/ffmpeg/libavcodec/arm/dsputil_armv6.S | 623 - .../ffmpeg/libavcodec/arm/dsputil_init_arm.c | 126 - .../ffmpeg/libavcodec/arm/dsputil_init_armv5te.c | 41 - .../ffmpeg/libavcodec/arm/dsputil_init_armv6.c | 121 - .../ffmpeg/libavcodec/arm/dsputil_init_neon.c | 327 - .../ffmpeg/libavcodec/arm/dsputil_init_vfp.c | 36 - .../distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt.c | 205 - .../libavcodec/arm/dsputil_iwmmxt_rnd_template.c | 1114 -- tizen/distrib/ffmpeg/libavcodec/arm/dsputil_neon.S | 1146 -- tizen/distrib/ffmpeg/libavcodec/arm/dsputil_vfp.S | 189 - tizen/distrib/ffmpeg/libavcodec/arm/fft_init_arm.c | 65 - tizen/distrib/ffmpeg/libavcodec/arm/fft_neon.S | 371 - .../ffmpeg/libavcodec/arm/h264dsp_init_arm.c | 126 - tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_neon.S | 1883 --- .../distrib/ffmpeg/libavcodec/arm/h264idct_neon.S | 180 - .../ffmpeg/libavcodec/arm/h264pred_init_arm.c | 76 - .../distrib/ffmpeg/libavcodec/arm/h264pred_neon.S | 362 - tizen/distrib/ffmpeg/libavcodec/arm/int_neon.S | 118 - tizen/distrib/ffmpeg/libavcodec/arm/jrevdct_arm.S | 388 - tizen/distrib/ffmpeg/libavcodec/arm/mathops.h | 116 - tizen/distrib/ffmpeg/libavcodec/arm/mdct_neon.S | 303 - .../distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.c | 38 - .../distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.h | 27 - .../ffmpeg/libavcodec/arm/mpegvideo_armv5te.c | 101 - .../ffmpeg/libavcodec/arm/mpegvideo_armv5te_s.S | 117 - .../ffmpeg/libavcodec/arm/mpegvideo_iwmmxt.c | 120 - tizen/distrib/ffmpeg/libavcodec/arm/rdft_neon.S | 151 - .../ffmpeg/libavcodec/arm/simple_idct_arm.S | 486 - .../ffmpeg/libavcodec/arm/simple_idct_armv5te.S | 703 -- .../ffmpeg/libavcodec/arm/simple_idct_armv6.S | 433 - .../ffmpeg/libavcodec/arm/simple_idct_neon.S | 373 - .../ffmpeg/libavcodec/arm/synth_filter_neon.S | 117 - tizen/distrib/ffmpeg/libavcodec/arm/vp3dsp_neon.S | 420 - .../ffmpeg/libavcodec/arm/vp56dsp_init_arm.c | 34 - tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_neon.S | 121 - tizen/distrib/ffmpeg/libavcodec/asv1.c | 668 - tizen/distrib/ffmpeg/libavcodec/atrac.c | 120 - tizen/distrib/ffmpeg/libavcodec/atrac.h | 38 - tizen/distrib/ffmpeg/libavcodec/atrac1.c | 377 - tizen/distrib/ffmpeg/libavcodec/atrac1data.h | 64 - tizen/distrib/ffmpeg/libavcodec/atrac3.c | 1026 -- tizen/distrib/ffmpeg/libavcodec/atrac3data.h | 133 - tizen/distrib/ffmpeg/libavcodec/audioconvert.c | 243 - tizen/distrib/ffmpeg/libavcodec/audioconvert.h | 115 - tizen/distrib/ffmpeg/libavcodec/aura.c | 138 - tizen/distrib/ffmpeg/libavcodec/avcodec.h | 4021 ------ tizen/distrib/ffmpeg/libavcodec/avfft.c | 142 - tizen/distrib/ffmpeg/libavcodec/avfft.h | 99 - tizen/distrib/ffmpeg/libavcodec/avpacket.c | 99 - tizen/distrib/ffmpeg/libavcodec/avr32/mathops.h | 101 - tizen/distrib/ffmpeg/libavcodec/avs.c | 164 - tizen/distrib/ffmpeg/libavcodec/beosthread.c | 183 - tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.c | 143 - tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.h | 36 - tizen/distrib/ffmpeg/libavcodec/bfi.c | 184 - tizen/distrib/ffmpeg/libavcodec/bfin/Makefile | 7 - tizen/distrib/ffmpeg/libavcodec/bfin/config_bfin.h | 65 - .../distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c | 280 - .../distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h | 108 - tizen/distrib/ffmpeg/libavcodec/bfin/fdct_bfin.S | 333 - tizen/distrib/ffmpeg/libavcodec/bfin/idct_bfin.S | 306 - tizen/distrib/ffmpeg/libavcodec/bfin/mathops.h | 54 - .../ffmpeg/libavcodec/bfin/mpegvideo_bfin.c | 148 - tizen/distrib/ffmpeg/libavcodec/bfin/pixels_bfin.S | 741 -- tizen/distrib/ffmpeg/libavcodec/bfin/vp3_bfin.c | 45 - .../distrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S | 282 - tizen/distrib/ffmpeg/libavcodec/bgmc.c | 567 - tizen/distrib/ffmpeg/libavcodec/bgmc.h | 56 - tizen/distrib/ffmpeg/libavcodec/bink.c | 1012 -- tizen/distrib/ffmpeg/libavcodec/binkaudio.c | 311 - tizen/distrib/ffmpeg/libavcodec/binkdata.h | 614 - tizen/distrib/ffmpeg/libavcodec/binkidct.c | 112 - tizen/distrib/ffmpeg/libavcodec/bitstream.c | 336 - tizen/distrib/ffmpeg/libavcodec/bitstream_filter.c | 65 - tizen/distrib/ffmpeg/libavcodec/bmp.c | 349 - tizen/distrib/ffmpeg/libavcodec/bmp.h | 38 - tizen/distrib/ffmpeg/libavcodec/bmpenc.c | 149 - tizen/distrib/ffmpeg/libavcodec/bytestream.h | 71 - tizen/distrib/ffmpeg/libavcodec/c93.c | 256 - tizen/distrib/ffmpeg/libavcodec/cabac.c | 268 - tizen/distrib/ffmpeg/libavcodec/cabac.h | 758 -- tizen/distrib/ffmpeg/libavcodec/cavs.c | 715 -- tizen/distrib/ffmpeg/libavcodec/cavs.h | 318 - tizen/distrib/ffmpeg/libavcodec/cavs_parser.c | 107 - tizen/distrib/ffmpeg/libavcodec/cavsdata.h | 505 - tizen/distrib/ffmpeg/libavcodec/cavsdec.c | 724 -- tizen/distrib/ffmpeg/libavcodec/cavsdsp.c | 540 - tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.c | 39 - tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.h | 51 - tizen/distrib/ffmpeg/libavcodec/cdgraphics.c | 381 - tizen/distrib/ffmpeg/libavcodec/celp_filters.c | 210 - tizen/distrib/ffmpeg/libavcodec/celp_filters.h | 119 - tizen/distrib/ffmpeg/libavcodec/celp_math.c | 208 - tizen/distrib/ffmpeg/libavcodec/celp_math.h | 76 - tizen/distrib/ffmpeg/libavcodec/cga_data.c | 157 - tizen/distrib/ffmpeg/libavcodec/cga_data.h | 29 - tizen/distrib/ffmpeg/libavcodec/cinepak.c | 469 - tizen/distrib/ffmpeg/libavcodec/cljr.c | 162 - tizen/distrib/ffmpeg/libavcodec/colorspace.h | 111 - tizen/distrib/ffmpeg/libavcodec/cook.c | 1298 -- tizen/distrib/ffmpeg/libavcodec/cookdata.h | 563 - tizen/distrib/ffmpeg/libavcodec/costablegen.c | 56 - tizen/distrib/ffmpeg/libavcodec/cscd.c | 262 - tizen/distrib/ffmpeg/libavcodec/cyuv.c | 210 - tizen/distrib/ffmpeg/libavcodec/dca.c | 1333 -- tizen/distrib/ffmpeg/libavcodec/dca.h | 37 - tizen/distrib/ffmpeg/libavcodec/dca_parser.c | 134 - tizen/distrib/ffmpeg/libavcodec/dcadata.h | 7636 ------------ tizen/distrib/ffmpeg/libavcodec/dcadsp.c | 51 - tizen/distrib/ffmpeg/libavcodec/dcadsp.h | 30 - tizen/distrib/ffmpeg/libavcodec/dcahuff.h | 1076 -- tizen/distrib/ffmpeg/libavcodec/dct-test.c | 599 - tizen/distrib/ffmpeg/libavcodec/dct.c | 210 - tizen/distrib/ffmpeg/libavcodec/dctref.c | 123 - tizen/distrib/ffmpeg/libavcodec/dctref.h | 31 - tizen/distrib/ffmpeg/libavcodec/dirac.c | 284 - tizen/distrib/ffmpeg/libavcodec/dirac.h | 57 - tizen/distrib/ffmpeg/libavcodec/dirac_parser.c | 256 - tizen/distrib/ffmpeg/libavcodec/dnxhd_parser.c | 95 - tizen/distrib/ffmpeg/libavcodec/dnxhddata.c | 428 - tizen/distrib/ffmpeg/libavcodec/dnxhddata.h | 51 - tizen/distrib/ffmpeg/libavcodec/dnxhddec.c | 358 - tizen/distrib/ffmpeg/libavcodec/dnxhdenc.c | 861 -- tizen/distrib/ffmpeg/libavcodec/dnxhdenc.h | 91 - tizen/distrib/ffmpeg/libavcodec/dpcm.c | 317 - tizen/distrib/ffmpeg/libavcodec/dpx.c | 229 - tizen/distrib/ffmpeg/libavcodec/dsicinav.c | 369 - tizen/distrib/ffmpeg/libavcodec/dsputil.c | 4566 ------- tizen/distrib/ffmpeg/libavcodec/dsputil.h | 810 -- .../distrib/ffmpeg/libavcodec/dump_extradata_bsf.c | 50 - tizen/distrib/ffmpeg/libavcodec/dv.c | 1309 -- tizen/distrib/ffmpeg/libavcodec/dv_tablegen.c | 47 - tizen/distrib/ffmpeg/libavcodec/dv_tablegen.h | 96 - tizen/distrib/ffmpeg/libavcodec/dv_vlc_data.h | 259 - tizen/distrib/ffmpeg/libavcodec/dvbsub.c | 413 - tizen/distrib/ffmpeg/libavcodec/dvbsub_parser.c | 188 - tizen/distrib/ffmpeg/libavcodec/dvbsubdec.c | 1424 --- tizen/distrib/ffmpeg/libavcodec/dvdata.c | 285 - tizen/distrib/ffmpeg/libavcodec/dvdata.h | 316 - tizen/distrib/ffmpeg/libavcodec/dvdsub_parser.c | 85 - tizen/distrib/ffmpeg/libavcodec/dvdsubdec.c | 499 - tizen/distrib/ffmpeg/libavcodec/dvdsubenc.c | 226 - tizen/distrib/ffmpeg/libavcodec/dwt.c | 843 -- tizen/distrib/ffmpeg/libavcodec/dwt.h | 156 - tizen/distrib/ffmpeg/libavcodec/dxa.c | 332 - tizen/distrib/ffmpeg/libavcodec/dxva2.c | 154 - tizen/distrib/ffmpeg/libavcodec/dxva2.h | 68 - tizen/distrib/ffmpeg/libavcodec/dxva2_h264.c | 437 - tizen/distrib/ffmpeg/libavcodec/dxva2_internal.h | 48 - tizen/distrib/ffmpeg/libavcodec/dxva2_vc1.c | 291 - tizen/distrib/ffmpeg/libavcodec/eac3dec.c | 607 - tizen/distrib/ffmpeg/libavcodec/eac3dec_data.c | 1134 -- tizen/distrib/ffmpeg/libavcodec/eac3dec_data.h | 36 - tizen/distrib/ffmpeg/libavcodec/eacmv.c | 217 - tizen/distrib/ffmpeg/libavcodec/eaidct.c | 87 - tizen/distrib/ffmpeg/libavcodec/eamad.c | 319 - tizen/distrib/ffmpeg/libavcodec/eatgq.c | 257 - tizen/distrib/ffmpeg/libavcodec/eatgv.c | 346 - tizen/distrib/ffmpeg/libavcodec/eatqi.c | 168 - tizen/distrib/ffmpeg/libavcodec/elbg.c | 428 - tizen/distrib/ffmpeg/libavcodec/elbg.h | 55 - tizen/distrib/ffmpeg/libavcodec/error_resilience.c | 1122 -- tizen/distrib/ffmpeg/libavcodec/escape124.c | 387 - tizen/distrib/ffmpeg/libavcodec/eval.c | 451 - tizen/distrib/ffmpeg/libavcodec/eval.h | 102 - tizen/distrib/ffmpeg/libavcodec/faandct.c | 232 - tizen/distrib/ffmpeg/libavcodec/faandct.h | 39 - tizen/distrib/ffmpeg/libavcodec/faanidct.c | 168 - tizen/distrib/ffmpeg/libavcodec/faanidct.h | 32 - tizen/distrib/ffmpeg/libavcodec/faxcompr.c | 319 - tizen/distrib/ffmpeg/libavcodec/faxcompr.h | 46 - tizen/distrib/ffmpeg/libavcodec/fft-test.c | 446 - tizen/distrib/ffmpeg/libavcodec/fft.c | 368 - tizen/distrib/ffmpeg/libavcodec/fft.h | 240 - tizen/distrib/ffmpeg/libavcodec/ffv1.c | 1197 -- tizen/distrib/ffmpeg/libavcodec/flac.c | 43 - tizen/distrib/ffmpeg/libavcodec/flac.h | 123 - tizen/distrib/ffmpeg/libavcodec/flacdata.c | 33 - tizen/distrib/ffmpeg/libavcodec/flacdata.h | 31 - tizen/distrib/ffmpeg/libavcodec/flacdec.c | 814 -- tizen/distrib/ffmpeg/libavcodec/flacenc.c | 1266 -- tizen/distrib/ffmpeg/libavcodec/flashsv.c | 265 - tizen/distrib/ffmpeg/libavcodec/flashsvenc.c | 294 - tizen/distrib/ffmpeg/libavcodec/flicvideo.c | 755 -- tizen/distrib/ffmpeg/libavcodec/flv.h | 34 - tizen/distrib/ffmpeg/libavcodec/flvdec.c | 132 - tizen/distrib/ffmpeg/libavcodec/flvenc.c | 97 - tizen/distrib/ffmpeg/libavcodec/fraps.c | 378 - tizen/distrib/ffmpeg/libavcodec/frwu.c | 123 - tizen/distrib/ffmpeg/libavcodec/g726.c | 412 - tizen/distrib/ffmpeg/libavcodec/g729.h | 29 - tizen/distrib/ffmpeg/libavcodec/g729data.h | 278 - tizen/distrib/ffmpeg/libavcodec/g729dec.c | 326 - tizen/distrib/ffmpeg/libavcodec/get_bits.h | 691 -- tizen/distrib/ffmpeg/libavcodec/gif.c | 179 - tizen/distrib/ffmpeg/libavcodec/gifdec.c | 340 - tizen/distrib/ffmpeg/libavcodec/golomb.c | 173 - tizen/distrib/ffmpeg/libavcodec/golomb.h | 530 - tizen/distrib/ffmpeg/libavcodec/h261.c | 54 - tizen/distrib/ffmpeg/libavcodec/h261.h | 51 - tizen/distrib/ffmpeg/libavcodec/h261_parser.c | 90 - tizen/distrib/ffmpeg/libavcodec/h261data.h | 164 - tizen/distrib/ffmpeg/libavcodec/h261dec.c | 655 - tizen/distrib/ffmpeg/libavcodec/h261enc.c | 335 - tizen/distrib/ffmpeg/libavcodec/h263.c | 385 - tizen/distrib/ffmpeg/libavcodec/h263.h | 251 - tizen/distrib/ffmpeg/libavcodec/h263_parser.c | 92 - tizen/distrib/ffmpeg/libavcodec/h263_parser.h | 29 - tizen/distrib/ffmpeg/libavcodec/h263data.h | 299 - tizen/distrib/ffmpeg/libavcodec/h263dec.c | 743 -- tizen/distrib/ffmpeg/libavcodec/h264.c | 3392 ----- tizen/distrib/ffmpeg/libavcodec/h264.h | 1299 -- tizen/distrib/ffmpeg/libavcodec/h264_cabac.c | 1720 --- tizen/distrib/ffmpeg/libavcodec/h264_cavlc.c | 1030 -- tizen/distrib/ffmpeg/libavcodec/h264_direct.c | 590 - tizen/distrib/ffmpeg/libavcodec/h264_loopfilter.c | 752 -- .../ffmpeg/libavcodec/h264_mp4toannexb_bsf.c | 169 - tizen/distrib/ffmpeg/libavcodec/h264_mvpred.h | 236 - tizen/distrib/ffmpeg/libavcodec/h264_parser.c | 329 - tizen/distrib/ffmpeg/libavcodec/h264_parser.h | 39 - tizen/distrib/ffmpeg/libavcodec/h264_ps.c | 537 - tizen/distrib/ffmpeg/libavcodec/h264_refs.c | 694 -- tizen/distrib/ffmpeg/libavcodec/h264_sei.c | 206 - tizen/distrib/ffmpeg/libavcodec/h264data.h | 262 - tizen/distrib/ffmpeg/libavcodec/h264dsp.c | 320 - tizen/distrib/ffmpeg/libavcodec/h264dsp.h | 80 - tizen/distrib/ffmpeg/libavcodec/h264dspenc.c | 78 - tizen/distrib/ffmpeg/libavcodec/h264enc.c | 260 - tizen/distrib/ffmpeg/libavcodec/h264idct.c | 218 - tizen/distrib/ffmpeg/libavcodec/h264pred.c | 1177 -- tizen/distrib/ffmpeg/libavcodec/h264pred.h | 89 - tizen/distrib/ffmpeg/libavcodec/huffman.c | 109 - tizen/distrib/ffmpeg/libavcodec/huffman.h | 42 - tizen/distrib/ffmpeg/libavcodec/huffyuv.c | 1475 --- tizen/distrib/ffmpeg/libavcodec/idcinvideo.c | 268 - tizen/distrib/ffmpeg/libavcodec/iff.c | 290 - tizen/distrib/ffmpeg/libavcodec/iff.h | 30 - tizen/distrib/ffmpeg/libavcodec/iirfilter.c | 215 - tizen/distrib/ffmpeg/libavcodec/iirfilter.h | 103 - tizen/distrib/ffmpeg/libavcodec/imc.c | 834 -- tizen/distrib/ffmpeg/libavcodec/imcdata.h | 169 - tizen/distrib/ffmpeg/libavcodec/imgconvert.c | 1478 --- tizen/distrib/ffmpeg/libavcodec/imgconvert.h | 38 - .../ffmpeg/libavcodec/imx_dump_header_bsf.c | 59 - tizen/distrib/ffmpeg/libavcodec/indeo2.c | 238 - tizen/distrib/ffmpeg/libavcodec/indeo2data.h | 141 - tizen/distrib/ffmpeg/libavcodec/indeo3.c | 1151 -- tizen/distrib/ffmpeg/libavcodec/indeo3data.h | 2342 ---- tizen/distrib/ffmpeg/libavcodec/indeo5.c | 827 -- tizen/distrib/ffmpeg/libavcodec/indeo5data.h | 185 - tizen/distrib/ffmpeg/libavcodec/intelh263dec.c | 131 - tizen/distrib/ffmpeg/libavcodec/internal.h | 51 - tizen/distrib/ffmpeg/libavcodec/interplayvideo.c | 1107 -- tizen/distrib/ffmpeg/libavcodec/intrax8.c | 789 -- tizen/distrib/ffmpeg/libavcodec/intrax8.h | 57 - tizen/distrib/ffmpeg/libavcodec/intrax8dsp.c | 432 - tizen/distrib/ffmpeg/libavcodec/intrax8huf.h | 918 -- tizen/distrib/ffmpeg/libavcodec/ituh263dec.c | 1131 -- tizen/distrib/ffmpeg/libavcodec/ituh263enc.c | 842 -- tizen/distrib/ffmpeg/libavcodec/ivi_common.c | 1000 -- tizen/distrib/ffmpeg/libavcodec/ivi_common.h | 342 - tizen/distrib/ffmpeg/libavcodec/ivi_dsp.c | 467 - tizen/distrib/ffmpeg/libavcodec/ivi_dsp.h | 170 - tizen/distrib/ffmpeg/libavcodec/jfdctfst.c | 334 - tizen/distrib/ffmpeg/libavcodec/jfdctint.c | 402 - tizen/distrib/ffmpeg/libavcodec/jpegls.c | 89 - tizen/distrib/ffmpeg/libavcodec/jpegls.h | 111 - tizen/distrib/ffmpeg/libavcodec/jpeglsdec.c | 377 - tizen/distrib/ffmpeg/libavcodec/jpeglsdec.h | 41 - tizen/distrib/ffmpeg/libavcodec/jpeglsenc.c | 395 - tizen/distrib/ffmpeg/libavcodec/jrevdct.c | 1157 -- tizen/distrib/ffmpeg/libavcodec/kgv1dec.c | 176 - tizen/distrib/ffmpeg/libavcodec/kmvc.c | 415 - tizen/distrib/ffmpeg/libavcodec/lcl.h | 49 - tizen/distrib/ffmpeg/libavcodec/lcldec.c | 639 - tizen/distrib/ffmpeg/libavcodec/lclenc.c | 190 - tizen/distrib/ffmpeg/libavcodec/libavcodec.v | 3 - tizen/distrib/ffmpeg/libavcodec/libdirac.h | 44 - .../distrib/ffmpeg/libavcodec/libdirac_libschro.c | 113 - .../distrib/ffmpeg/libavcodec/libdirac_libschro.h | 105 - tizen/distrib/ffmpeg/libavcodec/libdiracdec.c | 208 - tizen/distrib/ffmpeg/libavcodec/libdiracenc.c | 405 - tizen/distrib/ffmpeg/libavcodec/libfaac.c | 158 - tizen/distrib/ffmpeg/libavcodec/libfaad.c | 333 - tizen/distrib/ffmpeg/libavcodec/libgsm.c | 181 - tizen/distrib/ffmpeg/libavcodec/libmp3lame.c | 229 - tizen/distrib/ffmpeg/libavcodec/libopencore-amr.c | 325 - tizen/distrib/ffmpeg/libavcodec/libopenjpeg.c | 197 - tizen/distrib/ffmpeg/libavcodec/libschroedinger.c | 132 - tizen/distrib/ffmpeg/libavcodec/libschroedinger.h | 63 - .../distrib/ffmpeg/libavcodec/libschroedingerdec.c | 360 - .../distrib/ffmpeg/libavcodec/libschroedingerenc.c | 419 - tizen/distrib/ffmpeg/libavcodec/libspeexdec.c | 151 - tizen/distrib/ffmpeg/libavcodec/libtheoraenc.c | 371 - tizen/distrib/ffmpeg/libavcodec/libvorbis.c | 229 - tizen/distrib/ffmpeg/libavcodec/libvpxdec.c | 124 - tizen/distrib/ffmpeg/libavcodec/libvpxenc.c | 489 - tizen/distrib/ffmpeg/libavcodec/libx264.c | 329 - tizen/distrib/ffmpeg/libavcodec/libxvid_internal.h | 32 - tizen/distrib/ffmpeg/libavcodec/libxvid_rc.c | 148 - tizen/distrib/ffmpeg/libavcodec/libxvidff.c | 780 -- tizen/distrib/ffmpeg/libavcodec/ljpegenc.c | 198 - tizen/distrib/ffmpeg/libavcodec/loco.c | 299 - tizen/distrib/ffmpeg/libavcodec/lpc.c | 236 - tizen/distrib/ffmpeg/libavcodec/lpc.h | 105 - tizen/distrib/ffmpeg/libavcodec/lsp.c | 174 - tizen/distrib/ffmpeg/libavcodec/lsp.h | 119 - tizen/distrib/ffmpeg/libavcodec/lzw.c | 229 - tizen/distrib/ffmpeg/libavcodec/lzw.h | 64 - tizen/distrib/ffmpeg/libavcodec/lzwenc.c | 269 - tizen/distrib/ffmpeg/libavcodec/mace.c | 305 - tizen/distrib/ffmpeg/libavcodec/mathops.h | 150 - tizen/distrib/ffmpeg/libavcodec/mdct.c | 232 - tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.c | 49 - tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.h | 60 - tizen/distrib/ffmpeg/libavcodec/mdec.c | 263 - tizen/distrib/ffmpeg/libavcodec/mimic.c | 392 - tizen/distrib/ffmpeg/libavcodec/mips/Makefile | 3 - tizen/distrib/ffmpeg/libavcodec/mips/mathops.h | 76 - tizen/distrib/ffmpeg/libavcodec/mjpeg.c | 145 - tizen/distrib/ffmpeg/libavcodec/mjpeg.h | 155 - tizen/distrib/ffmpeg/libavcodec/mjpeg_parser.c | 105 - .../ffmpeg/libavcodec/mjpega_dump_header_bsf.c | 94 - tizen/distrib/ffmpeg/libavcodec/mjpegbdec.c | 160 - tizen/distrib/ffmpeg/libavcodec/mjpegdec.c | 1560 --- tizen/distrib/ffmpeg/libavcodec/mjpegdec.h | 120 - tizen/distrib/ffmpeg/libavcodec/mjpegenc.c | 456 - tizen/distrib/ffmpeg/libavcodec/mjpegenc.h | 60 - .../distrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c | 464 - tizen/distrib/ffmpeg/libavcodec/mlp.c | 115 - tizen/distrib/ffmpeg/libavcodec/mlp.h | 127 - tizen/distrib/ffmpeg/libavcodec/mlp_parser.c | 297 - tizen/distrib/ffmpeg/libavcodec/mlp_parser.h | 59 - tizen/distrib/ffmpeg/libavcodec/mlpdec.c | 1164 -- tizen/distrib/ffmpeg/libavcodec/mlpdsp.c | 63 - tizen/distrib/ffmpeg/libavcodec/mmvideo.c | 212 - tizen/distrib/ffmpeg/libavcodec/motion-test.c | 167 - tizen/distrib/ffmpeg/libavcodec/motion_est.c | 2016 --- .../ffmpeg/libavcodec/motion_est_template.c | 1285 -- tizen/distrib/ffmpeg/libavcodec/motionpixels.c | 316 - .../ffmpeg/libavcodec/motionpixels_tablegen.c | 41 - .../ffmpeg/libavcodec/motionpixels_tablegen.h | 91 - tizen/distrib/ffmpeg/libavcodec/movsub_bsf.c | 56 - .../ffmpeg/libavcodec/mp3_header_compress_bsf.c | 86 - .../ffmpeg/libavcodec/mp3_header_decompress_bsf.c | 96 - tizen/distrib/ffmpeg/libavcodec/mpc.c | 102 - tizen/distrib/ffmpeg/libavcodec/mpc.h | 77 - tizen/distrib/ffmpeg/libavcodec/mpc7.c | 302 - tizen/distrib/ffmpeg/libavcodec/mpc7data.h | 171 - tizen/distrib/ffmpeg/libavcodec/mpc8.c | 412 - tizen/distrib/ffmpeg/libavcodec/mpc8data.h | 121 - tizen/distrib/ffmpeg/libavcodec/mpc8huff.h | 578 - tizen/distrib/ffmpeg/libavcodec/mpcdata.h | 68 - tizen/distrib/ffmpeg/libavcodec/mpeg12.c | 2610 ---- tizen/distrib/ffmpeg/libavcodec/mpeg12.h | 61 - tizen/distrib/ffmpeg/libavcodec/mpeg12data.c | 366 - tizen/distrib/ffmpeg/libavcodec/mpeg12data.h | 56 - tizen/distrib/ffmpeg/libavcodec/mpeg12decdata.h | 93 - tizen/distrib/ffmpeg/libavcodec/mpeg12enc.c | 959 -- tizen/distrib/ffmpeg/libavcodec/mpeg4audio.c | 175 - tizen/distrib/ffmpeg/libavcodec/mpeg4audio.h | 106 - tizen/distrib/ffmpeg/libavcodec/mpeg4data.h | 376 - tizen/distrib/ffmpeg/libavcodec/mpeg4video.c | 171 - tizen/distrib/ffmpeg/libavcodec/mpeg4video.h | 202 - .../distrib/ffmpeg/libavcodec/mpeg4video_parser.c | 139 - .../distrib/ffmpeg/libavcodec/mpeg4video_parser.h | 34 - tizen/distrib/ffmpeg/libavcodec/mpeg4videodec.c | 2267 ---- tizen/distrib/ffmpeg/libavcodec/mpeg4videoenc.c | 1352 -- tizen/distrib/ffmpeg/libavcodec/mpegaudio.c | 50 - tizen/distrib/ffmpeg/libavcodec/mpegaudio.h | 183 - tizen/distrib/ffmpeg/libavcodec/mpegaudio3.h | 53 - tizen/distrib/ffmpeg/libavcodec/mpegaudio_parser.c | 149 - .../distrib/ffmpeg/libavcodec/mpegaudio_tablegen.c | 51 - .../distrib/ffmpeg/libavcodec/mpegaudio_tablegen.h | 67 - tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.c | 184 - tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.h | 43 - tizen/distrib/ffmpeg/libavcodec/mpegaudiodec.c | 2571 ---- .../distrib/ffmpeg/libavcodec/mpegaudiodecheader.c | 110 - .../distrib/ffmpeg/libavcodec/mpegaudiodecheader.h | 39 - tizen/distrib/ffmpeg/libavcodec/mpegaudiodectab.h | 606 - tizen/distrib/ffmpeg/libavcodec/mpegaudioenc.c | 805 -- tizen/distrib/ffmpeg/libavcodec/mpegaudiotab.h | 118 - tizen/distrib/ffmpeg/libavcodec/mpegvideo.c | 2414 ---- tizen/distrib/ffmpeg/libavcodec/mpegvideo.h | 832 -- tizen/distrib/ffmpeg/libavcodec/mpegvideo_common.h | 901 -- tizen/distrib/ffmpeg/libavcodec/mpegvideo_enc.c | 3842 ------ tizen/distrib/ffmpeg/libavcodec/mpegvideo_parser.c | 186 - tizen/distrib/ffmpeg/libavcodec/mpegvideo_xvmc.c | 332 - tizen/distrib/ffmpeg/libavcodec/msmpeg4.c | 1976 --- tizen/distrib/ffmpeg/libavcodec/msmpeg4.h | 62 - tizen/distrib/ffmpeg/libavcodec/msmpeg4data.c | 2001 --- tizen/distrib/ffmpeg/libavcodec/msmpeg4data.h | 86 - tizen/distrib/ffmpeg/libavcodec/msrle.c | 157 - tizen/distrib/ffmpeg/libavcodec/msrledec.c | 260 - tizen/distrib/ffmpeg/libavcodec/msrledec.h | 40 - tizen/distrib/ffmpeg/libavcodec/msvideo1.c | 345 - tizen/distrib/ffmpeg/libavcodec/nellymoser.c | 226 - tizen/distrib/ffmpeg/libavcodec/nellymoser.h | 57 - tizen/distrib/ffmpeg/libavcodec/nellymoserdec.c | 212 - tizen/distrib/ffmpeg/libavcodec/nellymoserenc.c | 395 - tizen/distrib/ffmpeg/libavcodec/noise_bsf.c | 46 - tizen/distrib/ffmpeg/libavcodec/nuv.c | 287 - tizen/distrib/ffmpeg/libavcodec/opt.c | 455 - tizen/distrib/ffmpeg/libavcodec/opt.h | 211 - tizen/distrib/ffmpeg/libavcodec/options.c | 533 - tizen/distrib/ffmpeg/libavcodec/os2thread.c | 148 - tizen/distrib/ffmpeg/libavcodec/pamenc.c | 120 - tizen/distrib/ffmpeg/libavcodec/parser.c | 343 - tizen/distrib/ffmpeg/libavcodec/parser.h | 70 - tizen/distrib/ffmpeg/libavcodec/pcm-mpeg.c | 310 - tizen/distrib/ffmpeg/libavcodec/pcm.c | 505 - tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.c | 45 - tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.h | 119 - tizen/distrib/ffmpeg/libavcodec/pcx.c | 257 - tizen/distrib/ffmpeg/libavcodec/pcxenc.c | 206 - tizen/distrib/ffmpeg/libavcodec/pgssubdec.c | 465 - tizen/distrib/ffmpeg/libavcodec/png.c | 83 - tizen/distrib/ffmpeg/libavcodec/png.h | 78 - tizen/distrib/ffmpeg/libavcodec/pngdec.c | 671 - tizen/distrib/ffmpeg/libavcodec/pngenc.c | 449 - tizen/distrib/ffmpeg/libavcodec/pnm.c | 189 - tizen/distrib/ffmpeg/libavcodec/pnm.h | 40 - tizen/distrib/ffmpeg/libavcodec/pnm_parser.c | 92 - tizen/distrib/ffmpeg/libavcodec/pnmdec.c | 268 - tizen/distrib/ffmpeg/libavcodec/pnmenc.c | 165 - tizen/distrib/ffmpeg/libavcodec/ppc/Makefile | 18 - .../distrib/ffmpeg/libavcodec/ppc/check_altivec.c | 87 - .../ffmpeg/libavcodec/ppc/dsputil_altivec.c | 1457 --- .../ffmpeg/libavcodec/ppc/dsputil_altivec.h | 52 - tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c | 297 - tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h | 154 - tizen/distrib/ffmpeg/libavcodec/ppc/fdct_altivec.c | 494 - tizen/distrib/ffmpeg/libavcodec/ppc/fft_altivec.c | 143 - .../distrib/ffmpeg/libavcodec/ppc/float_altivec.c | 251 - tizen/distrib/ffmpeg/libavcodec/ppc/gmc_altivec.c | 138 - tizen/distrib/ffmpeg/libavcodec/ppc/h264_altivec.c | 1028 -- .../ffmpeg/libavcodec/ppc/h264_template_altivec.c | 783 -- tizen/distrib/ffmpeg/libavcodec/ppc/idct_altivec.c | 232 - tizen/distrib/ffmpeg/libavcodec/ppc/int_altivec.c | 152 - tizen/distrib/ffmpeg/libavcodec/ppc/mathops.h | 79 - .../ffmpeg/libavcodec/ppc/mpegvideo_altivec.c | 612 - .../distrib/ffmpeg/libavcodec/ppc/types_altivec.h | 46 - tizen/distrib/ffmpeg/libavcodec/ppc/util_altivec.h | 105 - .../distrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c | 329 - .../distrib/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c | 185 - tizen/distrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c | 163 - tizen/distrib/ffmpeg/libavcodec/ps2/idct_mmi.c | 362 - tizen/distrib/ffmpeg/libavcodec/ps2/mmi.h | 171 - .../distrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c | 89 - tizen/distrib/ffmpeg/libavcodec/psymodel.c | 127 - tizen/distrib/ffmpeg/libavcodec/psymodel.h | 158 - tizen/distrib/ffmpeg/libavcodec/pthread.c | 186 - tizen/distrib/ffmpeg/libavcodec/ptx.c | 120 - tizen/distrib/ffmpeg/libavcodec/put_bits.h | 343 - tizen/distrib/ffmpeg/libavcodec/qcelpdata.h | 552 - tizen/distrib/ffmpeg/libavcodec/qcelpdec.c | 854 -- tizen/distrib/ffmpeg/libavcodec/qdm2.c | 1984 --- tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.c | 57 - tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.h | 102 - tizen/distrib/ffmpeg/libavcodec/qdm2data.h | 531 - tizen/distrib/ffmpeg/libavcodec/qdrw.c | 164 - tizen/distrib/ffmpeg/libavcodec/qpeg.c | 325 - tizen/distrib/ffmpeg/libavcodec/qtrle.c | 552 - tizen/distrib/ffmpeg/libavcodec/qtrleenc.c | 333 - tizen/distrib/ffmpeg/libavcodec/r210dec.c | 104 - tizen/distrib/ffmpeg/libavcodec/ra144.c | 364 - tizen/distrib/ffmpeg/libavcodec/ra144.h | 1506 --- tizen/distrib/ffmpeg/libavcodec/ra288.c | 213 - tizen/distrib/ffmpeg/libavcodec/ra288.h | 147 - tizen/distrib/ffmpeg/libavcodec/rangecoder.c | 157 - tizen/distrib/ffmpeg/libavcodec/rangecoder.h | 141 - tizen/distrib/ffmpeg/libavcodec/ratecontrol.c | 961 -- tizen/distrib/ffmpeg/libavcodec/ratecontrol.h | 105 - tizen/distrib/ffmpeg/libavcodec/raw.c | 85 - tizen/distrib/ffmpeg/libavcodec/raw.h | 39 - tizen/distrib/ffmpeg/libavcodec/rawdec.c | 198 - tizen/distrib/ffmpeg/libavcodec/rawenc.c | 66 - tizen/distrib/ffmpeg/libavcodec/rdft.c | 133 - tizen/distrib/ffmpeg/libavcodec/rectangle.h | 125 - .../ffmpeg/libavcodec/remove_extradata_bsf.c | 55 - tizen/distrib/ffmpeg/libavcodec/resample.c | 374 - tizen/distrib/ffmpeg/libavcodec/resample2.c | 302 - tizen/distrib/ffmpeg/libavcodec/rl.h | 86 - tizen/distrib/ffmpeg/libavcodec/rl2.c | 243 - tizen/distrib/ffmpeg/libavcodec/rle.c | 84 - tizen/distrib/ffmpeg/libavcodec/rle.h | 39 - tizen/distrib/ffmpeg/libavcodec/roqaudioenc.c | 167 - tizen/distrib/ffmpeg/libavcodec/roqvideo.c | 138 - tizen/distrib/ffmpeg/libavcodec/roqvideo.h | 95 - tizen/distrib/ffmpeg/libavcodec/roqvideodec.c | 224 - tizen/distrib/ffmpeg/libavcodec/roqvideoenc.c | 1069 -- tizen/distrib/ffmpeg/libavcodec/rpza.c | 289 - tizen/distrib/ffmpeg/libavcodec/rtjpeg.c | 173 - tizen/distrib/ffmpeg/libavcodec/rtjpeg.h | 43 - tizen/distrib/ffmpeg/libavcodec/rv10.c | 736 -- tizen/distrib/ffmpeg/libavcodec/rv10enc.c | 69 - tizen/distrib/ffmpeg/libavcodec/rv20enc.c | 70 - tizen/distrib/ffmpeg/libavcodec/rv30.c | 282 - tizen/distrib/ffmpeg/libavcodec/rv30data.h | 181 - tizen/distrib/ffmpeg/libavcodec/rv30dsp.c | 291 - tizen/distrib/ffmpeg/libavcodec/rv34.c | 1531 --- tizen/distrib/ffmpeg/libavcodec/rv34.h | 130 - tizen/distrib/ffmpeg/libavcodec/rv34data.h | 148 - tizen/distrib/ffmpeg/libavcodec/rv34vlc.h | 4054 ------ tizen/distrib/ffmpeg/libavcodec/rv40.c | 682 - tizen/distrib/ffmpeg/libavcodec/rv40data.h | 115 - tizen/distrib/ffmpeg/libavcodec/rv40dsp.c | 353 - tizen/distrib/ffmpeg/libavcodec/rv40vlc2.h | 706 -- tizen/distrib/ffmpeg/libavcodec/s3tc.c | 97 - tizen/distrib/ffmpeg/libavcodec/s3tc.h | 53 - tizen/distrib/ffmpeg/libavcodec/sbr.h | 183 - tizen/distrib/ffmpeg/libavcodec/sgi.h | 36 - tizen/distrib/ffmpeg/libavcodec/sgidec.c | 272 - tizen/distrib/ffmpeg/libavcodec/sgienc.c | 172 - tizen/distrib/ffmpeg/libavcodec/sh4/Makefile | 3 - .../distrib/ffmpeg/libavcodec/sh4/dsputil_align.c | 432 - tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c | 104 - tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.h | 28 - tizen/distrib/ffmpeg/libavcodec/sh4/idct_sh4.c | 362 - tizen/distrib/ffmpeg/libavcodec/sh4/qpel.c | 1409 --- tizen/distrib/ffmpeg/libavcodec/sh4/sh4.h | 44 - tizen/distrib/ffmpeg/libavcodec/shorten.c | 539 - tizen/distrib/ffmpeg/libavcodec/simple_idct.c | 582 - tizen/distrib/ffmpeg/libavcodec/simple_idct.h | 47 - tizen/distrib/ffmpeg/libavcodec/sipr.c | 588 - tizen/distrib/ffmpeg/libavcodec/sipr.h | 107 - tizen/distrib/ffmpeg/libavcodec/sipr16k.c | 280 - tizen/distrib/ffmpeg/libavcodec/sipr16kdata.h | 533 - tizen/distrib/ffmpeg/libavcodec/siprdata.h | 263 - tizen/distrib/ffmpeg/libavcodec/smacker.c | 716 -- tizen/distrib/ffmpeg/libavcodec/smc.c | 485 - tizen/distrib/ffmpeg/libavcodec/snow.c | 4150 ------- tizen/distrib/ffmpeg/libavcodec/snow.h | 78 - tizen/distrib/ffmpeg/libavcodec/sonic.c | 977 -- tizen/distrib/ffmpeg/libavcodec/sp5x.h | 334 - tizen/distrib/ffmpeg/libavcodec/sp5xdec.c | 221 - tizen/distrib/ffmpeg/libavcodec/sparc/Makefile | 2 - .../distrib/ffmpeg/libavcodec/sparc/dsputil_vis.c | 4005 ------ .../distrib/ffmpeg/libavcodec/sparc/dsputil_vis.h | 29 - .../ffmpeg/libavcodec/sparc/simple_idct_vis.c | 529 - tizen/distrib/ffmpeg/libavcodec/sparc/vis.h | 331 - tizen/distrib/ffmpeg/libavcodec/sunrast.c | 198 - tizen/distrib/ffmpeg/libavcodec/svq1.c | 43 - tizen/distrib/ffmpeg/libavcodec/svq1.h | 64 - tizen/distrib/ffmpeg/libavcodec/svq1_cb.h | 1525 --- tizen/distrib/ffmpeg/libavcodec/svq1_vlc.h | 283 - tizen/distrib/ffmpeg/libavcodec/svq1dec.c | 842 -- tizen/distrib/ffmpeg/libavcodec/svq1enc.c | 585 - tizen/distrib/ffmpeg/libavcodec/svq1enc_cb.h | 96 - tizen/distrib/ffmpeg/libavcodec/svq3.c | 1084 -- tizen/distrib/ffmpeg/libavcodec/synth_filter.c | 64 - tizen/distrib/ffmpeg/libavcodec/synth_filter.h | 37 - tizen/distrib/ffmpeg/libavcodec/tableprint.c | 40 - tizen/distrib/ffmpeg/libavcodec/tableprint.h | 74 - tizen/distrib/ffmpeg/libavcodec/targa.c | 256 - tizen/distrib/ffmpeg/libavcodec/targaenc.c | 163 - tizen/distrib/ffmpeg/libavcodec/tiertexseqv.c | 233 - tizen/distrib/ffmpeg/libavcodec/tiff.c | 605 - tizen/distrib/ffmpeg/libavcodec/tiff.h | 89 - tizen/distrib/ffmpeg/libavcodec/tiffenc.c | 464 - tizen/distrib/ffmpeg/libavcodec/tmv.c | 110 - tizen/distrib/ffmpeg/libavcodec/truemotion1.c | 904 -- tizen/distrib/ffmpeg/libavcodec/truemotion1data.h | 832 -- tizen/distrib/ffmpeg/libavcodec/truemotion2.c | 884 -- tizen/distrib/ffmpeg/libavcodec/truespeech.c | 389 - tizen/distrib/ffmpeg/libavcodec/truespeech_data.h | 159 - tizen/distrib/ffmpeg/libavcodec/tscc.c | 212 - tizen/distrib/ffmpeg/libavcodec/tta.c | 460 - tizen/distrib/ffmpeg/libavcodec/twinvq.c | 1127 -- tizen/distrib/ffmpeg/libavcodec/twinvq_data.h | 11137 ----------------- tizen/distrib/ffmpeg/libavcodec/txd.c | 169 - tizen/distrib/ffmpeg/libavcodec/ulti.c | 420 - tizen/distrib/ffmpeg/libavcodec/ulti_cb.h | 4124 ------ tizen/distrib/ffmpeg/libavcodec/unary.h | 56 - tizen/distrib/ffmpeg/libavcodec/utils.c | 1299 -- tizen/distrib/ffmpeg/libavcodec/v210dec.c | 134 - tizen/distrib/ffmpeg/libavcodec/v210enc.c | 130 - tizen/distrib/ffmpeg/libavcodec/v210x.c | 146 - tizen/distrib/ffmpeg/libavcodec/vaapi.c | 208 - tizen/distrib/ffmpeg/libavcodec/vaapi.h | 167 - tizen/distrib/ffmpeg/libavcodec/vaapi_h264.c | 347 - tizen/distrib/ffmpeg/libavcodec/vaapi_internal.h | 68 - tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg2.c | 151 - tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg4.c | 177 - tizen/distrib/ffmpeg/libavcodec/vaapi_vc1.c | 352 - tizen/distrib/ffmpeg/libavcodec/vb.c | 301 - tizen/distrib/ffmpeg/libavcodec/vc1.c | 1033 -- tizen/distrib/ffmpeg/libavcodec/vc1.h | 368 - tizen/distrib/ffmpeg/libavcodec/vc1_parser.c | 179 - tizen/distrib/ffmpeg/libavcodec/vc1acdata.h | 592 - tizen/distrib/ffmpeg/libavcodec/vc1data.c | 645 - tizen/distrib/ffmpeg/libavcodec/vc1data.h | 157 - tizen/distrib/ffmpeg/libavcodec/vc1dec.c | 3384 ----- tizen/distrib/ffmpeg/libavcodec/vc1dsp.c | 662 - tizen/distrib/ffmpeg/libavcodec/vcr1.c | 203 - tizen/distrib/ffmpeg/libavcodec/vdpau.c | 372 - tizen/distrib/ffmpeg/libavcodec/vdpau.h | 89 - tizen/distrib/ffmpeg/libavcodec/vdpau_internal.h | 46 - tizen/distrib/ffmpeg/libavcodec/vmdav.c | 591 - tizen/distrib/ffmpeg/libavcodec/vmnc.c | 523 - tizen/distrib/ffmpeg/libavcodec/vorbis.c | 231 - tizen/distrib/ffmpeg/libavcodec/vorbis.h | 48 - tizen/distrib/ffmpeg/libavcodec/vorbis_data.c | 2181 ---- tizen/distrib/ffmpeg/libavcodec/vorbis_dec.c | 1658 --- tizen/distrib/ffmpeg/libavcodec/vorbis_enc.c | 1105 -- tizen/distrib/ffmpeg/libavcodec/vorbis_enc_data.h | 504 - tizen/distrib/ffmpeg/libavcodec/vp3.c | 2233 ---- tizen/distrib/ffmpeg/libavcodec/vp3_parser.c | 44 - tizen/distrib/ffmpeg/libavcodec/vp3data.h | 3181 ----- tizen/distrib/ffmpeg/libavcodec/vp3dsp.c | 274 - tizen/distrib/ffmpeg/libavcodec/vp5.c | 280 - tizen/distrib/ffmpeg/libavcodec/vp56.c | 696 -- tizen/distrib/ffmpeg/libavcodec/vp56.h | 270 - tizen/distrib/ffmpeg/libavcodec/vp56data.c | 66 - tizen/distrib/ffmpeg/libavcodec/vp56data.h | 252 - tizen/distrib/ffmpeg/libavcodec/vp56dsp.c | 88 - tizen/distrib/ffmpeg/libavcodec/vp56dsp.h | 34 - tizen/distrib/ffmpeg/libavcodec/vp5data.h | 175 - tizen/distrib/ffmpeg/libavcodec/vp6.c | 647 - tizen/distrib/ffmpeg/libavcodec/vp6data.h | 308 - tizen/distrib/ffmpeg/libavcodec/vp6dsp.c | 59 - tizen/distrib/ffmpeg/libavcodec/vqavideo.c | 622 - tizen/distrib/ffmpeg/libavcodec/w32thread.c | 168 - tizen/distrib/ffmpeg/libavcodec/wavpack.c | 1032 -- tizen/distrib/ffmpeg/libavcodec/wma.c | 523 - tizen/distrib/ffmpeg/libavcodec/wma.h | 163 - tizen/distrib/ffmpeg/libavcodec/wmadata.h | 1403 --- tizen/distrib/ffmpeg/libavcodec/wmadec.c | 968 -- tizen/distrib/ffmpeg/libavcodec/wmaenc.c | 410 - tizen/distrib/ffmpeg/libavcodec/wmaprodata.h | 604 - tizen/distrib/ffmpeg/libavcodec/wmaprodec.c | 1579 --- tizen/distrib/ffmpeg/libavcodec/wmavoice.c | 2030 --- tizen/distrib/ffmpeg/libavcodec/wmavoice_data.h | 3259 ----- tizen/distrib/ffmpeg/libavcodec/wmv2.c | 159 - tizen/distrib/ffmpeg/libavcodec/wmv2.h | 58 - tizen/distrib/ffmpeg/libavcodec/wmv2dec.c | 499 - tizen/distrib/ffmpeg/libavcodec/wmv2enc.c | 224 - tizen/distrib/ffmpeg/libavcodec/wnv1.c | 168 - tizen/distrib/ffmpeg/libavcodec/ws-snd1.c | 158 - tizen/distrib/ffmpeg/libavcodec/x86/Makefile | 39 - tizen/distrib/ffmpeg/libavcodec/x86/cavsdsp_mmx.c | 470 - tizen/distrib/ffmpeg/libavcodec/x86/cpuid.c | 135 - tizen/distrib/ffmpeg/libavcodec/x86/dnxhd_mmx.c | 58 - .../libavcodec/x86/dsputil_h264_template_mmx.c | 304 - .../libavcodec/x86/dsputil_h264_template_ssse3.c | 208 - tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.c | 3002 ----- tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.h | 176 - .../libavcodec/x86/dsputil_mmx_avg_template.c | 896 -- .../libavcodec/x86/dsputil_mmx_qns_template.c | 101 - .../libavcodec/x86/dsputil_mmx_rnd_template.c | 590 - .../distrib/ffmpeg/libavcodec/x86/dsputil_yasm.asm | 423 - .../distrib/ffmpeg/libavcodec/x86/dsputilenc_mmx.c | 1438 --- tizen/distrib/ffmpeg/libavcodec/x86/fdct_mmx.c | 578 - tizen/distrib/ffmpeg/libavcodec/x86/fft.c | 44 - tizen/distrib/ffmpeg/libavcodec/x86/fft.h | 36 - tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn.c | 23 - tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn2.c | 174 - tizen/distrib/ffmpeg/libavcodec/x86/fft_mmx.asm | 480 - tizen/distrib/ffmpeg/libavcodec/x86/fft_sse.c | 203 - .../ffmpeg/libavcodec/x86/h264_deblock_sse2.asm | 759 -- tizen/distrib/ffmpeg/libavcodec/x86/h264_i386.h | 153 - .../ffmpeg/libavcodec/x86/h264_idct_sse2.asm | 54 - tizen/distrib/ffmpeg/libavcodec/x86/h264dsp_mmx.c | 2324 ---- tizen/distrib/ffmpeg/libavcodec/x86/idct_mmx.c | 601 - .../distrib/ffmpeg/libavcodec/x86/idct_mmx_xvid.c | 526 - .../distrib/ffmpeg/libavcodec/x86/idct_sse2_xvid.c | 395 - tizen/distrib/ffmpeg/libavcodec/x86/idct_xvid.h | 37 - tizen/distrib/ffmpeg/libavcodec/x86/lpc_mmx.c | 140 - tizen/distrib/ffmpeg/libavcodec/x86/mathops.h | 100 - tizen/distrib/ffmpeg/libavcodec/x86/mlpdsp.c | 181 - tizen/distrib/ffmpeg/libavcodec/x86/mmx.h | 267 - .../distrib/ffmpeg/libavcodec/x86/motion_est_mmx.c | 462 - .../distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx.c | 660 - .../ffmpeg/libavcodec/x86/mpegvideo_mmx_template.c | 376 - tizen/distrib/ffmpeg/libavcodec/x86/rv40dsp_mmx.c | 61 - .../ffmpeg/libavcodec/x86/simple_idct_mmx.c | 1296 -- tizen/distrib/ffmpeg/libavcodec/x86/snowdsp_mmx.c | 897 -- tizen/distrib/ffmpeg/libavcodec/x86/vc1dsp_mmx.c | 741 -- tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.c | 438 - tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.h | 36 - tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.c | 187 - tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.h | 31 - tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.c | 108 - tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.h | 30 - tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.c | 98 - tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.h | 30 - tizen/distrib/ffmpeg/libavcodec/x86/x86inc.asm | 625 - tizen/distrib/ffmpeg/libavcodec/x86/x86util.asm | 515 - tizen/distrib/ffmpeg/libavcodec/xan.c | 444 - tizen/distrib/ffmpeg/libavcodec/xiph.c | 63 - tizen/distrib/ffmpeg/libavcodec/xiph.h | 43 - tizen/distrib/ffmpeg/libavcodec/xl.c | 152 - tizen/distrib/ffmpeg/libavcodec/xsubdec.c | 143 - tizen/distrib/ffmpeg/libavcodec/xsubenc.c | 222 - tizen/distrib/ffmpeg/libavcodec/xvmc.h | 172 - tizen/distrib/ffmpeg/libavcodec/xvmc_internal.h | 33 - tizen/distrib/ffmpeg/libavcodec/yop.c | 260 - tizen/distrib/ffmpeg/libavcodec/zmbv.c | 668 - tizen/distrib/ffmpeg/libavcodec/zmbvenc.c | 336 - tizen/distrib/ffmpeg/libavdevice/Makefile | 33 - tizen/distrib/ffmpeg/libavdevice/alldevices.c | 55 - .../distrib/ffmpeg/libavdevice/alsa-audio-common.c | 186 - tizen/distrib/ffmpeg/libavdevice/alsa-audio-dec.c | 175 - tizen/distrib/ffmpeg/libavdevice/alsa-audio-enc.c | 108 - tizen/distrib/ffmpeg/libavdevice/alsa-audio.h | 89 - tizen/distrib/ffmpeg/libavdevice/avdevice.c | 35 - tizen/distrib/ffmpeg/libavdevice/avdevice.h | 58 - tizen/distrib/ffmpeg/libavdevice/beosaudio.cpp | 467 - tizen/distrib/ffmpeg/libavdevice/bktr.c | 326 - tizen/distrib/ffmpeg/libavdevice/dv1394.c | 238 - tizen/distrib/ffmpeg/libavdevice/dv1394.h | 356 - tizen/distrib/ffmpeg/libavdevice/jack_audio.c | 326 - tizen/distrib/ffmpeg/libavdevice/libavdevice.v | 4 - tizen/distrib/ffmpeg/libavdevice/libdc1394.c | 372 - tizen/distrib/ffmpeg/libavdevice/oss_audio.c | 329 - tizen/distrib/ffmpeg/libavdevice/v4l.c | 350 - tizen/distrib/ffmpeg/libavdevice/v4l2.c | 712 -- tizen/distrib/ffmpeg/libavdevice/vfwcap.c | 448 - tizen/distrib/ffmpeg/libavdevice/x11grab.c | 440 - tizen/distrib/ffmpeg/libavfilter/Makefile | 32 - tizen/distrib/ffmpeg/libavfilter/allfilters.c | 51 - tizen/distrib/ffmpeg/libavfilter/avfilter.c | 459 - tizen/distrib/ffmpeg/libavfilter/avfilter.h | 703 -- tizen/distrib/ffmpeg/libavfilter/avfiltergraph.c | 205 - tizen/distrib/ffmpeg/libavfilter/avfiltergraph.h | 77 - tizen/distrib/ffmpeg/libavfilter/defaults.c | 187 - tizen/distrib/ffmpeg/libavfilter/formats.c | 166 - tizen/distrib/ffmpeg/libavfilter/graphparser.c | 357 - tizen/distrib/ffmpeg/libavfilter/graphparser.h | 52 - tizen/distrib/ffmpeg/libavfilter/libavfilter.v | 4 - tizen/distrib/ffmpeg/libavfilter/parseutils.c | 475 - tizen/distrib/ffmpeg/libavfilter/parseutils.h | 75 - tizen/distrib/ffmpeg/libavfilter/vf_aspect.c | 123 - tizen/distrib/ffmpeg/libavfilter/vf_crop.c | 227 - tizen/distrib/ffmpeg/libavfilter/vf_format.c | 147 - tizen/distrib/ffmpeg/libavfilter/vf_null.c | 42 - tizen/distrib/ffmpeg/libavfilter/vf_scale.c | 209 - tizen/distrib/ffmpeg/libavfilter/vf_slicify.c | 117 - tizen/distrib/ffmpeg/libavfilter/vf_unsharp.c | 236 - tizen/distrib/ffmpeg/libavfilter/vf_vflip.c | 104 - tizen/distrib/ffmpeg/libavfilter/vsink_nullsink.c | 45 - tizen/distrib/ffmpeg/libavfilter/vsrc_nullsrc.c | 83 - tizen/distrib/ffmpeg/libavformat/4xm.c | 347 - tizen/distrib/ffmpeg/libavformat/Makefile | 299 - tizen/distrib/ffmpeg/libavformat/adts.h | 45 - tizen/distrib/ffmpeg/libavformat/adtsenc.c | 147 - tizen/distrib/ffmpeg/libavformat/aea.c | 108 - tizen/distrib/ffmpeg/libavformat/aiff.h | 53 - tizen/distrib/ffmpeg/libavformat/aiffdec.c | 324 - tizen/distrib/ffmpeg/libavformat/aiffenc.c | 160 - tizen/distrib/ffmpeg/libavformat/allformats.c | 233 - tizen/distrib/ffmpeg/libavformat/amr.c | 193 - tizen/distrib/ffmpeg/libavformat/anm.c | 235 - tizen/distrib/ffmpeg/libavformat/apc.c | 90 - tizen/distrib/ffmpeg/libavformat/ape.c | 404 - tizen/distrib/ffmpeg/libavformat/apetag.c | 112 - tizen/distrib/ffmpeg/libavformat/apetag.h | 33 - tizen/distrib/ffmpeg/libavformat/asf.c | 171 - tizen/distrib/ffmpeg/libavformat/asf.h | 234 - tizen/distrib/ffmpeg/libavformat/asfcrypt.c | 176 - tizen/distrib/ffmpeg/libavformat/asfcrypt.h | 29 - tizen/distrib/ffmpeg/libavformat/asfdec.c | 1205 -- tizen/distrib/ffmpeg/libavformat/asfenc.c | 897 -- tizen/distrib/ffmpeg/libavformat/assdec.c | 187 - tizen/distrib/ffmpeg/libavformat/assenc.c | 92 - tizen/distrib/ffmpeg/libavformat/au.c | 208 - tizen/distrib/ffmpeg/libavformat/audiointerleave.c | 133 - tizen/distrib/ffmpeg/libavformat/audiointerleave.h | 56 - tizen/distrib/ffmpeg/libavformat/avc.c | 155 - tizen/distrib/ffmpeg/libavformat/avc.h | 33 - tizen/distrib/ffmpeg/libavformat/avformat.h | 1355 -- tizen/distrib/ffmpeg/libavformat/avi.c | 45 - tizen/distrib/ffmpeg/libavformat/avi.h | 46 - tizen/distrib/ffmpeg/libavformat/avidec.c | 1198 -- tizen/distrib/ffmpeg/libavformat/avienc.c | 648 - tizen/distrib/ffmpeg/libavformat/avio.c | 290 - tizen/distrib/ffmpeg/libavformat/avio.h | 525 - tizen/distrib/ffmpeg/libavformat/aviobuf.c | 906 -- tizen/distrib/ffmpeg/libavformat/avisynth.c | 222 - tizen/distrib/ffmpeg/libavformat/avlanguage.c | 764 -- tizen/distrib/ffmpeg/libavformat/avlanguage.h | 39 - tizen/distrib/ffmpeg/libavformat/avs.c | 226 - tizen/distrib/ffmpeg/libavformat/bethsoftvid.c | 234 - tizen/distrib/ffmpeg/libavformat/bfi.c | 168 - tizen/distrib/ffmpeg/libavformat/bink.c | 269 - tizen/distrib/ffmpeg/libavformat/c93.c | 202 - tizen/distrib/ffmpeg/libavformat/caf.c | 58 - tizen/distrib/ffmpeg/libavformat/caf.h | 34 - tizen/distrib/ffmpeg/libavformat/cafdec.c | 379 - tizen/distrib/ffmpeg/libavformat/cdg.c | 66 - tizen/distrib/ffmpeg/libavformat/concat.c | 198 - tizen/distrib/ffmpeg/libavformat/crcenc.c | 68 - tizen/distrib/ffmpeg/libavformat/cutils.c | 188 - tizen/distrib/ffmpeg/libavformat/daud.c | 95 - tizen/distrib/ffmpeg/libavformat/dsicin.c | 226 - tizen/distrib/ffmpeg/libavformat/dv.c | 532 - tizen/distrib/ffmpeg/libavformat/dv.h | 44 - tizen/distrib/ffmpeg/libavformat/dvenc.c | 415 - tizen/distrib/ffmpeg/libavformat/dxa.c | 219 - tizen/distrib/ffmpeg/libavformat/eacdata.c | 101 - tizen/distrib/ffmpeg/libavformat/electronicarts.c | 567 - tizen/distrib/ffmpeg/libavformat/ffm.h | 58 - tizen/distrib/ffmpeg/libavformat/ffmdec.c | 534 - tizen/distrib/ffmpeg/libavformat/ffmenc.c | 255 - tizen/distrib/ffmpeg/libavformat/file.c | 136 - tizen/distrib/ffmpeg/libavformat/filmstripdec.c | 111 - tizen/distrib/ffmpeg/libavformat/filmstripenc.c | 85 - tizen/distrib/ffmpeg/libavformat/flacdec.c | 151 - tizen/distrib/ffmpeg/libavformat/flacenc.c | 132 - tizen/distrib/ffmpeg/libavformat/flacenc.h | 32 - tizen/distrib/ffmpeg/libavformat/flacenc_header.c | 49 - tizen/distrib/ffmpeg/libavformat/flic.c | 269 - tizen/distrib/ffmpeg/libavformat/flv.h | 115 - tizen/distrib/ffmpeg/libavformat/flvdec.c | 498 - tizen/distrib/ffmpeg/libavformat/flvenc.c | 420 - tizen/distrib/ffmpeg/libavformat/framecrcenc.c | 47 - tizen/distrib/ffmpeg/libavformat/gif.c | 358 - tizen/distrib/ffmpeg/libavformat/gopher.c | 129 - tizen/distrib/ffmpeg/libavformat/gxf.c | 518 - tizen/distrib/ffmpeg/libavformat/gxf.h | 52 - tizen/distrib/ffmpeg/libavformat/gxfenc.c | 938 -- tizen/distrib/ffmpeg/libavformat/http.c | 455 - tizen/distrib/ffmpeg/libavformat/httpauth.c | 321 - tizen/distrib/ffmpeg/libavformat/httpauth.h | 72 - tizen/distrib/ffmpeg/libavformat/id3v1.c | 241 - tizen/distrib/ffmpeg/libavformat/id3v1.h | 42 - tizen/distrib/ffmpeg/libavformat/id3v2.c | 273 - tizen/distrib/ffmpeg/libavformat/id3v2.h | 63 - tizen/distrib/ffmpeg/libavformat/idcin.c | 296 - tizen/distrib/ffmpeg/libavformat/idroq.c | 226 - tizen/distrib/ffmpeg/libavformat/iff.c | 309 - tizen/distrib/ffmpeg/libavformat/img2.c | 467 - tizen/distrib/ffmpeg/libavformat/internal.h | 157 - tizen/distrib/ffmpeg/libavformat/ipmovie.c | 630 - tizen/distrib/ffmpeg/libavformat/isom.c | 316 - tizen/distrib/ffmpeg/libavformat/isom.h | 148 - tizen/distrib/ffmpeg/libavformat/iss.c | 133 - tizen/distrib/ffmpeg/libavformat/iv8.c | 96 - tizen/distrib/ffmpeg/libavformat/libavformat.v | 3 - tizen/distrib/ffmpeg/libavformat/libnut.c | 310 - tizen/distrib/ffmpeg/libavformat/librtmp.c | 226 - tizen/distrib/ffmpeg/libavformat/lmlm4.c | 127 - tizen/distrib/ffmpeg/libavformat/matroska.c | 100 - tizen/distrib/ffmpeg/libavformat/matroska.h | 241 - tizen/distrib/ffmpeg/libavformat/matroskadec.c | 1891 --- tizen/distrib/ffmpeg/libavformat/matroskaenc.c | 1042 -- tizen/distrib/ffmpeg/libavformat/metadata.c | 153 - tizen/distrib/ffmpeg/libavformat/metadata.h | 51 - tizen/distrib/ffmpeg/libavformat/metadata_compat.c | 147 - tizen/distrib/ffmpeg/libavformat/mm.c | 198 - tizen/distrib/ffmpeg/libavformat/mmf.c | 318 - tizen/distrib/ffmpeg/libavformat/mov.c | 2595 ---- tizen/distrib/ffmpeg/libavformat/movenc.c | 2278 ---- tizen/distrib/ffmpeg/libavformat/movenc.h | 120 - tizen/distrib/ffmpeg/libavformat/movenchint.c | 504 - tizen/distrib/ffmpeg/libavformat/mp3.c | 366 - tizen/distrib/ffmpeg/libavformat/mpc.c | 249 - tizen/distrib/ffmpeg/libavformat/mpc8.c | 291 - tizen/distrib/ffmpeg/libavformat/mpeg.c | 620 - tizen/distrib/ffmpeg/libavformat/mpeg.h | 72 - tizen/distrib/ffmpeg/libavformat/mpegenc.c | 1302 -- tizen/distrib/ffmpeg/libavformat/mpegts.c | 1785 --- tizen/distrib/ffmpeg/libavformat/mpegts.h | 66 - tizen/distrib/ffmpeg/libavformat/mpegtsenc.c | 920 -- tizen/distrib/ffmpeg/libavformat/mpjpeg.c | 67 - tizen/distrib/ffmpeg/libavformat/msnwc_tcp.c | 140 - tizen/distrib/ffmpeg/libavformat/mtv.c | 206 - tizen/distrib/ffmpeg/libavformat/mvi.c | 134 - tizen/distrib/ffmpeg/libavformat/mxf.c | 53 - tizen/distrib/ffmpeg/libavformat/mxf.h | 71 - tizen/distrib/ffmpeg/libavformat/mxfdec.c | 1014 -- tizen/distrib/ffmpeg/libavformat/mxfenc.c | 1908 --- tizen/distrib/ffmpeg/libavformat/ncdec.c | 101 - tizen/distrib/ffmpeg/libavformat/network.h | 154 - tizen/distrib/ffmpeg/libavformat/nsvdec.c | 786 -- tizen/distrib/ffmpeg/libavformat/nut.c | 106 - tizen/distrib/ffmpeg/libavformat/nut.h | 119 - tizen/distrib/ffmpeg/libavformat/nutdec.c | 928 -- tizen/distrib/ffmpeg/libavformat/nutenc.c | 828 -- tizen/distrib/ffmpeg/libavformat/nuv.c | 270 - tizen/distrib/ffmpeg/libavformat/oggdec.c | 646 - tizen/distrib/ffmpeg/libavformat/oggdec.h | 146 - tizen/distrib/ffmpeg/libavformat/oggenc.c | 451 - tizen/distrib/ffmpeg/libavformat/oggparsedirac.c | 115 - tizen/distrib/ffmpeg/libavformat/oggparseflac.c | 97 - tizen/distrib/ffmpeg/libavformat/oggparseogm.c | 188 - .../distrib/ffmpeg/libavformat/oggparseskeleton.c | 87 - tizen/distrib/ffmpeg/libavformat/oggparsespeex.c | 128 - tizen/distrib/ffmpeg/libavformat/oggparsetheora.c | 152 - tizen/distrib/ffmpeg/libavformat/oggparsevorbis.c | 260 - tizen/distrib/ffmpeg/libavformat/oma.c | 207 - tizen/distrib/ffmpeg/libavformat/options.c | 96 - tizen/distrib/ffmpeg/libavformat/os_support.c | 309 - tizen/distrib/ffmpeg/libavformat/os_support.h | 103 - tizen/distrib/ffmpeg/libavformat/output-example.c | 554 - tizen/distrib/ffmpeg/libavformat/psxstr.c | 269 - tizen/distrib/ffmpeg/libavformat/pva.c | 211 - tizen/distrib/ffmpeg/libavformat/qcp.c | 197 - tizen/distrib/ffmpeg/libavformat/qtpalette.h | 313 - tizen/distrib/ffmpeg/libavformat/r3d.c | 389 - tizen/distrib/ffmpeg/libavformat/raw.c | 1363 -- tizen/distrib/ffmpeg/libavformat/raw.h | 32 - tizen/distrib/ffmpeg/libavformat/rdt.c | 560 - tizen/distrib/ffmpeg/libavformat/rdt.h | 112 - tizen/distrib/ffmpeg/libavformat/riff.c | 543 - tizen/distrib/ffmpeg/libavformat/riff.h | 54 - tizen/distrib/ffmpeg/libavformat/rl2.c | 300 - tizen/distrib/ffmpeg/libavformat/rm.c | 29 - tizen/distrib/ffmpeg/libavformat/rm.h | 101 - tizen/distrib/ffmpeg/libavformat/rmdec.c | 977 -- tizen/distrib/ffmpeg/libavformat/rmenc.c | 459 - tizen/distrib/ffmpeg/libavformat/rpl.c | 359 - tizen/distrib/ffmpeg/libavformat/rtmp.h | 42 - tizen/distrib/ffmpeg/libavformat/rtmppkt.c | 446 - tizen/distrib/ffmpeg/libavformat/rtmppkt.h | 222 - tizen/distrib/ffmpeg/libavformat/rtmpproto.c | 998 -- tizen/distrib/ffmpeg/libavformat/rtp.c | 131 - tizen/distrib/ffmpeg/libavformat/rtp.h | 79 - tizen/distrib/ffmpeg/libavformat/rtpdec.c | 615 - tizen/distrib/ffmpeg/libavformat/rtpdec.h | 206 - tizen/distrib/ffmpeg/libavformat/rtpdec_amr.c | 186 - tizen/distrib/ffmpeg/libavformat/rtpdec_amr.h | 30 - tizen/distrib/ffmpeg/libavformat/rtpdec_asf.c | 281 - tizen/distrib/ffmpeg/libavformat/rtpdec_asf.h | 43 - tizen/distrib/ffmpeg/libavformat/rtpdec_h263.c | 108 - tizen/distrib/ffmpeg/libavformat/rtpdec_h263.h | 30 - tizen/distrib/ffmpeg/libavformat/rtpdec_h264.c | 420 - tizen/distrib/ffmpeg/libavformat/rtpdec_h264.h | 29 - tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.c | 398 - tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.h | 40 - tizen/distrib/ffmpeg/libavformat/rtpenc.c | 420 - tizen/distrib/ffmpeg/libavformat/rtpenc.h | 65 - tizen/distrib/ffmpeg/libavformat/rtpenc_aac.c | 85 - tizen/distrib/ffmpeg/libavformat/rtpenc_amr.c | 66 - tizen/distrib/ffmpeg/libavformat/rtpenc_h263.c | 80 - tizen/distrib/ffmpeg/libavformat/rtpenc_h264.c | 78 - tizen/distrib/ffmpeg/libavformat/rtpenc_mpv.c | 119 - tizen/distrib/ffmpeg/libavformat/rtpproto.c | 384 - tizen/distrib/ffmpeg/libavformat/rtsp.c | 2091 ---- tizen/distrib/ffmpeg/libavformat/rtsp.h | 437 - tizen/distrib/ffmpeg/libavformat/rtspcodes.h | 40 - tizen/distrib/ffmpeg/libavformat/rtspenc.c | 182 - tizen/distrib/ffmpeg/libavformat/sdp.c | 377 - tizen/distrib/ffmpeg/libavformat/seek.c | 518 - tizen/distrib/ffmpeg/libavformat/seek.h | 126 - tizen/distrib/ffmpeg/libavformat/segafilm.c | 293 - tizen/distrib/ffmpeg/libavformat/sierravmd.c | 291 - tizen/distrib/ffmpeg/libavformat/siff.c | 238 - tizen/distrib/ffmpeg/libavformat/smacker.c | 355 - tizen/distrib/ffmpeg/libavformat/sol.c | 153 - tizen/distrib/ffmpeg/libavformat/sox.h | 29 - tizen/distrib/ffmpeg/libavformat/soxdec.c | 152 - tizen/distrib/ffmpeg/libavformat/soxenc.c | 126 - tizen/distrib/ffmpeg/libavformat/spdif.c | 306 - tizen/distrib/ffmpeg/libavformat/swf.h | 96 - tizen/distrib/ffmpeg/libavformat/swfdec.c | 217 - tizen/distrib/ffmpeg/libavformat/swfenc.c | 535 - tizen/distrib/ffmpeg/libavformat/tcp.c | 215 - tizen/distrib/ffmpeg/libavformat/thp.c | 197 - tizen/distrib/ffmpeg/libavformat/tiertexseq.c | 313 - tizen/distrib/ffmpeg/libavformat/timefilter.c | 149 - tizen/distrib/ffmpeg/libavformat/timefilter.h | 97 - tizen/distrib/ffmpeg/libavformat/tmv.c | 191 - tizen/distrib/ffmpeg/libavformat/tta.c | 164 - tizen/distrib/ffmpeg/libavformat/txd.c | 101 - tizen/distrib/ffmpeg/libavformat/udp.c | 498 - tizen/distrib/ffmpeg/libavformat/utils.c | 3591 ------ tizen/distrib/ffmpeg/libavformat/vc1test.c | 120 - tizen/distrib/ffmpeg/libavformat/vc1testenc.c | 94 - tizen/distrib/ffmpeg/libavformat/voc.c | 36 - tizen/distrib/ffmpeg/libavformat/voc.h | 51 - tizen/distrib/ffmpeg/libavformat/vocdec.c | 151 - tizen/distrib/ffmpeg/libavformat/vocenc.c | 103 - tizen/distrib/ffmpeg/libavformat/vorbiscomment.c | 73 - tizen/distrib/ffmpeg/libavformat/vorbiscomment.h | 57 - tizen/distrib/ffmpeg/libavformat/vqf.c | 260 - tizen/distrib/ffmpeg/libavformat/wav.c | 415 - tizen/distrib/ffmpeg/libavformat/wc3movie.c | 386 - tizen/distrib/ffmpeg/libavformat/westwood.c | 388 - tizen/distrib/ffmpeg/libavformat/wv.c | 255 - tizen/distrib/ffmpeg/libavformat/xa.c | 128 - tizen/distrib/ffmpeg/libavformat/yop.c | 216 - tizen/distrib/ffmpeg/libavformat/yuv4mpeg.c | 402 - tizen/distrib/ffmpeg/libavutil/Makefile | 60 - tizen/distrib/ffmpeg/libavutil/adler32.c | 73 - tizen/distrib/ffmpeg/libavutil/adler32.h | 30 - tizen/distrib/ffmpeg/libavutil/aes.c | 244 - tizen/distrib/ffmpeg/libavutil/aes.h | 47 - tizen/distrib/ffmpeg/libavutil/arm/bswap.h | 72 - tizen/distrib/ffmpeg/libavutil/arm/intmath.h | 54 - tizen/distrib/ffmpeg/libavutil/arm/intreadwrite.h | 78 - tizen/distrib/ffmpeg/libavutil/arm/timer.h | 40 - tizen/distrib/ffmpeg/libavutil/attributes.h | 113 - tizen/distrib/ffmpeg/libavutil/avr32/bswap.h | 44 - .../distrib/ffmpeg/libavutil/avr32/intreadwrite.h | 182 - tizen/distrib/ffmpeg/libavutil/avstring.c | 99 - tizen/distrib/ffmpeg/libavutil/avstring.h | 117 - tizen/distrib/ffmpeg/libavutil/avutil.h | 89 - tizen/distrib/ffmpeg/libavutil/base64.c | 164 - tizen/distrib/ffmpeg/libavutil/base64.h | 49 - tizen/distrib/ffmpeg/libavutil/bfin/bswap.h | 45 - tizen/distrib/ffmpeg/libavutil/bfin/timer.h | 41 - tizen/distrib/ffmpeg/libavutil/bswap.h | 118 - tizen/distrib/ffmpeg/libavutil/common.h | 308 - tizen/distrib/ffmpeg/libavutil/crc.c | 158 - tizen/distrib/ffmpeg/libavutil/crc.h | 44 - tizen/distrib/ffmpeg/libavutil/crc_data.h | 213 - tizen/distrib/ffmpeg/libavutil/des.c | 435 - tizen/distrib/ffmpeg/libavutil/des.h | 52 - tizen/distrib/ffmpeg/libavutil/error.c | 47 - tizen/distrib/ffmpeg/libavutil/error.h | 72 - tizen/distrib/ffmpeg/libavutil/fifo.c | 129 - tizen/distrib/ffmpeg/libavutil/fifo.h | 116 - tizen/distrib/ffmpeg/libavutil/integer.c | 197 - tizen/distrib/ffmpeg/libavutil/integer.h | 86 - tizen/distrib/ffmpeg/libavutil/internal.h | 218 - .../distrib/ffmpeg/libavutil/intfloat_readwrite.c | 98 - .../distrib/ffmpeg/libavutil/intfloat_readwrite.h | 40 - tizen/distrib/ffmpeg/libavutil/intmath.h | 98 - tizen/distrib/ffmpeg/libavutil/intreadwrite.h | 516 - tizen/distrib/ffmpeg/libavutil/lfg.c | 98 - tizen/distrib/ffmpeg/libavutil/lfg.h | 62 - tizen/distrib/ffmpeg/libavutil/libavutil.v | 4 - tizen/distrib/ffmpeg/libavutil/libm.h | 96 - tizen/distrib/ffmpeg/libavutil/lls.c | 137 - tizen/distrib/ffmpeg/libavutil/lls.h | 45 - tizen/distrib/ffmpeg/libavutil/log.c | 116 - tizen/distrib/ffmpeg/libavutil/log.h | 123 - tizen/distrib/ffmpeg/libavutil/lzo.c | 279 - tizen/distrib/ffmpeg/libavutil/lzo.h | 66 - tizen/distrib/ffmpeg/libavutil/mathematics.c | 174 - tizen/distrib/ffmpeg/libavutil/mathematics.h | 98 - tizen/distrib/ffmpeg/libavutil/md5.c | 183 - tizen/distrib/ffmpeg/libavutil/md5.h | 36 - tizen/distrib/ffmpeg/libavutil/mem.c | 176 - tizen/distrib/ffmpeg/libavutil/mem.h | 125 - tizen/distrib/ffmpeg/libavutil/mips/intreadwrite.h | 94 - tizen/distrib/ffmpeg/libavutil/pca.c | 246 - tizen/distrib/ffmpeg/libavutil/pca.h | 35 - tizen/distrib/ffmpeg/libavutil/pixdesc.c | 840 -- tizen/distrib/ffmpeg/libavutil/pixdesc.h | 154 - tizen/distrib/ffmpeg/libavutil/pixfmt.h | 163 - tizen/distrib/ffmpeg/libavutil/ppc/intreadwrite.h | 108 - tizen/distrib/ffmpeg/libavutil/ppc/timer.h | 47 - tizen/distrib/ffmpeg/libavutil/random_seed.c | 44 - tizen/distrib/ffmpeg/libavutil/random_seed.h | 31 - tizen/distrib/ffmpeg/libavutil/rational.c | 131 - tizen/distrib/ffmpeg/libavutil/rational.h | 129 - tizen/distrib/ffmpeg/libavutil/rc4.c | 61 - tizen/distrib/ffmpeg/libavutil/rc4.h | 50 - tizen/distrib/ffmpeg/libavutil/sh4/bswap.h | 48 - tizen/distrib/ffmpeg/libavutil/sha.c | 401 - tizen/distrib/ffmpeg/libavutil/sha.h | 56 - tizen/distrib/ffmpeg/libavutil/sha1.h | 57 - tizen/distrib/ffmpeg/libavutil/softfloat.c | 72 - tizen/distrib/ffmpeg/libavutil/softfloat.h | 126 - tizen/distrib/ffmpeg/libavutil/timer.h | 71 - tizen/distrib/ffmpeg/libavutil/tomi/intreadwrite.h | 148 - tizen/distrib/ffmpeg/libavutil/tree.c | 213 - tizen/distrib/ffmpeg/libavutil/tree.h | 95 - tizen/distrib/ffmpeg/libavutil/utils.c | 41 - tizen/distrib/ffmpeg/libavutil/x86/bswap.h | 61 - tizen/distrib/ffmpeg/libavutil/x86/intmath.h | 35 - tizen/distrib/ffmpeg/libavutil/x86/intreadwrite.h | 97 - tizen/distrib/ffmpeg/libavutil/x86/timer.h | 35 - tizen/distrib/ffmpeg/libavutil/x86_cpu.h | 76 - tizen/distrib/ffmpeg/libpostproc/Makefile | 10 - tizen/distrib/ffmpeg/libpostproc/libpostproc.v | 4 - tizen/distrib/ffmpeg/libpostproc/postprocess.c | 1106 -- tizen/distrib/ffmpeg/libpostproc/postprocess.h | 109 - .../libpostproc/postprocess_altivec_template.c | 1214 -- .../ffmpeg/libpostproc/postprocess_internal.h | 178 - .../ffmpeg/libpostproc/postprocess_template.c | 3632 ------ tizen/distrib/ffmpeg/libswscale/Makefile | 22 - .../distrib/ffmpeg/libswscale/bfin/internal_bfin.S | 613 - .../distrib/ffmpeg/libswscale/bfin/swscale_bfin.c | 93 - .../distrib/ffmpeg/libswscale/bfin/yuv2rgb_bfin.c | 203 - tizen/distrib/ffmpeg/libswscale/colorspace-test.c | 178 - tizen/distrib/ffmpeg/libswscale/libswscale.v | 4 - .../distrib/ffmpeg/libswscale/mlib/yuv2rgb_mlib.c | 88 - tizen/distrib/ffmpeg/libswscale/options.c | 61 - .../libswscale/ppc/swscale_altivec_template.c | 545 - .../ffmpeg/libswscale/ppc/yuv2rgb_altivec.c | 953 -- tizen/distrib/ffmpeg/libswscale/rgb2rgb.c | 431 - tizen/distrib/ffmpeg/libswscale/rgb2rgb.h | 172 - tizen/distrib/ffmpeg/libswscale/rgb2rgb_template.c | 2944 ----- .../distrib/ffmpeg/libswscale/sparc/yuv2rgb_vis.c | 212 - tizen/distrib/ffmpeg/libswscale/swscale-test.c | 260 - tizen/distrib/ffmpeg/libswscale/swscale.c | 1987 --- tizen/distrib/ffmpeg/libswscale/swscale.h | 330 - tizen/distrib/ffmpeg/libswscale/swscale_internal.h | 469 - tizen/distrib/ffmpeg/libswscale/swscale_template.c | 3066 ----- tizen/distrib/ffmpeg/libswscale/utils.c | 1591 --- tizen/distrib/ffmpeg/libswscale/x86/yuv2rgb_mmx.c | 109 - .../ffmpeg/libswscale/x86/yuv2rgb_template.c | 564 - .../ffmpeg/libswscale/x86/yuv2rgb_template2.c | 459 - tizen/distrib/ffmpeg/libswscale/yuv2rgb.c | 825 -- tizen/distrib/ffmpeg/subdir.mak | 101 - tizen/distrib/ffmpeg/tests/audiogen.c | 187 - tizen/distrib/ffmpeg/tests/codec-regression.sh | 352 - tizen/distrib/ffmpeg/tests/copy.regression.ref | 465 - tizen/distrib/ffmpeg/tests/copycooker.sh | 30 - tizen/distrib/ffmpeg/tests/fate-run.sh | 19 - tizen/distrib/ffmpeg/tests/fate-update.sh | 36 - tizen/distrib/ffmpeg/tests/fate.mak | 694 -- tizen/distrib/ffmpeg/tests/ffserver-regression.sh | 39 - tizen/distrib/ffmpeg/tests/ffserver.conf | 307 - tizen/distrib/ffmpeg/tests/ffserver.regression.ref | 10 - tizen/distrib/ffmpeg/tests/lavf-regression.sh | 226 - tizen/distrib/ffmpeg/tests/lavfi-regression.sh | 43 - tizen/distrib/ffmpeg/tests/lena.pnm | 109 - tizen/distrib/ffmpeg/tests/md5.sh | 11 - tizen/distrib/ffmpeg/tests/ref/acodec/ac3 | 2 - tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_ima_qt | 4 - .../distrib/ffmpeg/tests/ref/acodec/adpcm_ima_wav | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_ms | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_swf | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_yam | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/alac | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/flac | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/g726 | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/mp2 | 5 - tizen/distrib/ffmpeg/tests/ref/acodec/pcm | 72 - tizen/distrib/ffmpeg/tests/ref/acodec/wmav1 | 4 - tizen/distrib/ffmpeg/tests/ref/acodec/wmav2 | 4 - tizen/distrib/ffmpeg/tests/ref/fate/4xm | 1 - tizen/distrib/ffmpeg/tests/ref/fate/8bps | 35 - tizen/distrib/ffmpeg/tests/ref/fate/aac-demux | 1 - tizen/distrib/ffmpeg/tests/ref/fate/aasc | 23 - tizen/distrib/ffmpeg/tests/ref/fate/adpcm-ea-r2 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/adpcm-ea-r3 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/aea-demux | 1 - tizen/distrib/ffmpeg/tests/ref/fate/alg-mm | 31 - tizen/distrib/ffmpeg/tests/ref/fate/amv | 320 - .../ffmpeg/tests/ref/fate/armovie-escape124 | 104 - tizen/distrib/ffmpeg/tests/ref/fate/auravision | 24 - tizen/distrib/ffmpeg/tests/ref/fate/auravision-v2 | 2 - tizen/distrib/ffmpeg/tests/ref/fate/bethsoft-vid | 141 - tizen/distrib/ffmpeg/tests/ref/fate/bfi | 114 - tizen/distrib/ffmpeg/tests/ref/fate/bink-demux | 1 - .../distrib/ffmpeg/tests/ref/fate/bink-demux-video | 20 - tizen/distrib/ffmpeg/tests/ref/fate/caf | 1 - tizen/distrib/ffmpeg/tests/ref/fate/cdgraphics | 299 - tizen/distrib/ffmpeg/tests/ref/fate/cljr | 36 - tizen/distrib/ffmpeg/tests/ref/fate/corepng | 37 - tizen/distrib/ffmpeg/tests/ref/fate/creative-adpcm | 1 - .../ffmpeg/tests/ref/fate/creative-adpcm-8-2.6bit | 1 - .../ffmpeg/tests/ref/fate/creative-adpcm-8-2bit | 1 - .../ffmpeg/tests/ref/fate/creative-adpcm-8-4bit | 1 - .../ffmpeg/tests/ref/fate/creatureshock-avs | 92 - tizen/distrib/ffmpeg/tests/ref/fate/cryo-apc | 1 - tizen/distrib/ffmpeg/tests/ref/fate/cscd | 208 - tizen/distrib/ffmpeg/tests/ref/fate/cvid | 78 - tizen/distrib/ffmpeg/tests/ref/fate/cvid-palette | 56 - tizen/distrib/ffmpeg/tests/ref/fate/cyberia-c93 | 42 - tizen/distrib/ffmpeg/tests/ref/fate/cyuv | 150 - tizen/distrib/ffmpeg/tests/ref/fate/d-cinema-demux | 4 - tizen/distrib/ffmpeg/tests/ref/fate/delphine-cin | 183 - .../distrib/ffmpeg/tests/ref/fate/deluxepaint-anm | 155 - tizen/distrib/ffmpeg/tests/ref/fate/dpx | 1 - tizen/distrib/ffmpeg/tests/ref/fate/duck-dk3 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/duck-dk4 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/duck-tm2 | 30 - tizen/distrib/ffmpeg/tests/ref/fate/ea-cdata | 1 - tizen/distrib/ffmpeg/tests/ref/fate/ea-cmv | 194 - tizen/distrib/ffmpeg/tests/ref/fate/ea-dct | 267 - .../ffmpeg/tests/ref/fate/ea-mad-adpcm-ea-r1 | 191 - .../ffmpeg/tests/ref/fate/ea-mad-pcm-planar | 292 - tizen/distrib/ffmpeg/tests/ref/fate/ea-tgq | 278 - .../ffmpeg/tests/ref/fate/ea-tgv-ima-ea-eacs | 94 - .../ffmpeg/tests/ref/fate/ea-tgv-ima-ea-sead | 87 - tizen/distrib/ffmpeg/tests/ref/fate/ea-tqi-adpcm | 52 - tizen/distrib/ffmpeg/tests/ref/fate/ea-vp60 | 133 - tizen/distrib/ffmpeg/tests/ref/fate/ea-vp61 | 120 - tizen/distrib/ffmpeg/tests/ref/fate/feeble-dxa | 65 - .../tests/ref/fate/film-cvid-pcm-stereo-8bit | 247 - .../ffmpeg/tests/ref/fate/flic-af11-palette-change | 116 - tizen/distrib/ffmpeg/tests/ref/fate/flic-af12 | 27 - .../distrib/ffmpeg/tests/ref/fate/flic-magiccarpet | 42 - tizen/distrib/ffmpeg/tests/ref/fate/fraps-v0 | 20 - tizen/distrib/ffmpeg/tests/ref/fate/fraps-v1 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/fraps-v2 | 10 - tizen/distrib/ffmpeg/tests/ref/fate/fraps-v3 | 9 - tizen/distrib/ffmpeg/tests/ref/fate/fraps-v4 | 7 - tizen/distrib/ffmpeg/tests/ref/fate/fraps-v5 | 58 - tizen/distrib/ffmpeg/tests/ref/fate/frwu | 10 - tizen/distrib/ffmpeg/tests/ref/fate/funcom-iss | 1 - .../tests/ref/fate/h264-conformance-aud_mw_e | 100 - .../tests/ref/fate/h264-conformance-ba1_ft_c | 299 - .../tests/ref/fate/h264-conformance-ba1_sony_d | 17 - .../tests/ref/fate/h264-conformance-ba2_sony_f | 300 - .../tests/ref/fate/h264-conformance-ba3_sva_c | 33 - .../ffmpeg/tests/ref/fate/h264-conformance-ba_mw_d | 100 - .../tests/ref/fate/h264-conformance-bamq1_jvc_c | 30 - .../tests/ref/fate/h264-conformance-bamq2_jvc_c | 30 - .../tests/ref/fate/h264-conformance-banm_mw_d | 100 - .../tests/ref/fate/h264-conformance-basqp1_sony_c | 4 - .../tests/ref/fate/h264-conformance-caba1_sony_d | 50 - .../tests/ref/fate/h264-conformance-caba1_sva_b | 17 - .../tests/ref/fate/h264-conformance-caba2_sony_e | 300 - .../tests/ref/fate/h264-conformance-caba2_sva_b | 17 - .../tests/ref/fate/h264-conformance-caba3_sony_c | 300 - .../tests/ref/fate/h264-conformance-caba3_sva_b | 33 - .../ref/fate/h264-conformance-caba3_toshiba_e | 300 - .../ref/fate/h264-conformance-cabac_mot_fld0_full | 30 - .../ref/fate/h264-conformance-cabac_mot_frm0_full | 30 - .../fate/h264-conformance-cabac_mot_mbaff0_full | 30 - .../fate/h264-conformance-cabac_mot_picaff0_full | 30 - .../tests/ref/fate/h264-conformance-cabaci3_sony_b | 300 - .../tests/ref/fate/h264-conformance-cabast3_sony_e | 25 - .../ref/fate/h264-conformance-cabastbr3_sony_b | 25 - .../tests/ref/fate/h264-conformance-cabref3_sand_d | 50 - .../tests/ref/fate/h264-conformance-cacqp3_sony_d | 50 - .../tests/ref/fate/h264-conformance-cafi1_sva_c | 33 - .../tests/ref/fate/h264-conformance-cama1_sony_c | 5 - .../ref/fate/h264-conformance-cama1_toshiba_b | 90 - .../tests/ref/fate/h264-conformance-cama1_vtc_c | 4 - .../tests/ref/fate/h264-conformance-cama2_vtc_b | 4 - .../tests/ref/fate/h264-conformance-cama3_sand_e | 50 - .../tests/ref/fate/h264-conformance-cama3_vtc_b | 4 - .../tests/ref/fate/h264-conformance-camaci3_sony_c | 17 - .../ref/fate/h264-conformance-camanl1_toshiba_b | 90 - .../ref/fate/h264-conformance-camanl2_toshiba_b | 90 - .../tests/ref/fate/h264-conformance-camanl3_sand_e | 50 - .../tests/ref/fate/h264-conformance-camasl3_sony_b | 17 - .../ref/fate/h264-conformance-camp_mot_mbaff_l30 | 30 - .../ref/fate/h264-conformance-camp_mot_mbaff_l31 | 30 - .../tests/ref/fate/h264-conformance-canl1_sony_e | 50 - .../tests/ref/fate/h264-conformance-canl1_sva_b | 17 - .../ref/fate/h264-conformance-canl1_toshiba_g | 300 - .../tests/ref/fate/h264-conformance-canl2_sony_e | 300 - .../tests/ref/fate/h264-conformance-canl2_sva_b | 17 - .../tests/ref/fate/h264-conformance-canl3_sony_c | 300 - .../tests/ref/fate/h264-conformance-canl3_sva_b | 17 - .../tests/ref/fate/h264-conformance-canl4_sva_b | 33 - .../tests/ref/fate/h264-conformance-canlma2_sony_c | 17 - .../tests/ref/fate/h264-conformance-canlma3_sony_c | 17 - .../ref/fate/h264-conformance-capa1_toshiba_b | 90 - .../tests/ref/fate/h264-conformance-capama3_sand_f | 50 - .../tests/ref/fate/h264-conformance-capcm1_sand_e | 30 - .../ref/fate/h264-conformance-capcmnl1_sand_e | 30 - .../tests/ref/fate/h264-conformance-capm3_sony_d | 300 - .../tests/ref/fate/h264-conformance-caqp1_sony_b | 50 - .../fate/h264-conformance-cavlc_mot_fld0_full_b | 30 - .../fate/h264-conformance-cavlc_mot_frm0_full_b | 30 - .../fate/h264-conformance-cavlc_mot_mbaff0_full_b | 30 - .../fate/h264-conformance-cavlc_mot_picaff0_full_b | 30 - .../ref/fate/h264-conformance-cawp1_toshiba_e | 90 - .../ref/fate/h264-conformance-cawp5_toshiba_e | 90 - .../tests/ref/fate/h264-conformance-ci1_ft_b | 291 - .../ffmpeg/tests/ref/fate/h264-conformance-ci_mw_d | 100 - .../tests/ref/fate/h264-conformance-cvbs3_sony_c | 300 - .../ref/fate/h264-conformance-cvcanlma2_sony_c | 17 - .../tests/ref/fate/h264-conformance-cvfi1_sony_d | 17 - .../tests/ref/fate/h264-conformance-cvfi1_sva_c | 7 - .../tests/ref/fate/h264-conformance-cvfi2_sony_h | 17 - .../tests/ref/fate/h264-conformance-cvfi2_sva_c | 13 - .../tests/ref/fate/h264-conformance-cvma1_sony_d | 5 - .../ref/fate/h264-conformance-cvma1_toshiba_b | 90 - .../ref/fate/h264-conformance-cvmanl1_toshiba_b | 90 - .../ref/fate/h264-conformance-cvmanl2_toshiba_b | 90 - .../ref/fate/h264-conformance-cvmapaqp3_sony_e | 8 - .../tests/ref/fate/h264-conformance-cvmaqp2_sony_g | 17 - .../tests/ref/fate/h264-conformance-cvmaqp3_sony_d | 17 - .../ref/fate/h264-conformance-cvmp_mot_fld_l30_b | 30 - .../ref/fate/h264-conformance-cvmp_mot_frm_l31_b | 30 - .../tests/ref/fate/h264-conformance-cvnlfi1_sony_c | 17 - .../tests/ref/fate/h264-conformance-cvnlfi2_sony_h | 17 - .../ref/fate/h264-conformance-cvpa1_toshiba_b | 90 - .../tests/ref/fate/h264-conformance-cvpcmnl1_sva_c | 30 - .../tests/ref/fate/h264-conformance-cvpcmnl2_sva_c | 2 - .../ref/fate/h264-conformance-cvwp1_toshiba_e | 90 - .../ref/fate/h264-conformance-cvwp2_toshiba_e | 90 - .../ref/fate/h264-conformance-cvwp3_toshiba_e | 90 - .../ref/fate/h264-conformance-cvwp5_toshiba_e | 90 - .../tests/ref/fate/h264-conformance-fi1_sony_e | 17 - .../fate/h264-conformance-frext-alphaconformanceg | 43 - .../ref/fate/h264-conformance-frext-bcrm_freh10 | 100 - .../ref/fate/h264-conformance-frext-brcm_freh11 | 100 - .../ref/fate/h264-conformance-frext-brcm_freh3 | 100 - .../ref/fate/h264-conformance-frext-brcm_freh4 | 100 - .../ref/fate/h264-conformance-frext-brcm_freh5 | 100 - .../ref/fate/h264-conformance-frext-brcm_freh8 | 100 - .../ref/fate/h264-conformance-frext-brcm_freh9 | 100 - .../tests/ref/fate/h264-conformance-frext-freh12_b | 100 - .../tests/ref/fate/h264-conformance-frext-freh1_b | 100 - .../tests/ref/fate/h264-conformance-frext-freh2_b | 100 - .../tests/ref/fate/h264-conformance-frext-freh6 | 100 - .../tests/ref/fate/h264-conformance-frext-freh7_b | 100 - .../ref/fate/h264-conformance-frext-frext01_jvc_d | 16 - .../ref/fate/h264-conformance-frext-frext02_jvc_c | 16 - .../fate/h264-conformance-frext-frext1_panasonic_c | 8 - .../fate/h264-conformance-frext-frext2_panasonic_b | 15 - .../fate/h264-conformance-frext-frext3_panasonic_d | 11 - .../fate/h264-conformance-frext-frext4_panasonic_a | 10 - .../fate/h264-conformance-frext-frext_mmco4_sony_b | 60 - .../ref/fate/h264-conformance-frext-hcaff1_hhi_b | 10 - .../ref/fate/h264-conformance-frext-hcafr1_hhi_c | 10 - .../ref/fate/h264-conformance-frext-hcafr2_hhi_a | 10 - .../ref/fate/h264-conformance-frext-hcafr3_hhi_a | 10 - .../ref/fate/h264-conformance-frext-hcafr4_hhi_a | 10 - .../ref/fate/h264-conformance-frext-hcamff1_hhi_b | 10 - .../ref/fate/h264-conformance-frext-hpca_brcm_c | 300 - .../ref/fate/h264-conformance-frext-hpcadq_brcm_b | 300 - .../ref/fate/h264-conformance-frext-hpcafl_bcrm_c | 300 - .../fate/h264-conformance-frext-hpcaflnl_bcrm_c | 300 - .../ref/fate/h264-conformance-frext-hpcalq_brcm_b | 300 - .../fate/h264-conformance-frext-hpcamapalq_bcrm_b | 300 - .../fate/h264-conformance-frext-hpcamolq_brcm_b | 100 - .../ref/fate/h264-conformance-frext-hpcanl_brcm_c | 300 - .../fate/h264-conformance-frext-hpcaq2lq_brcm_b | 100 - .../ref/fate/h264-conformance-frext-hpcv_brcm_a | 300 - .../ref/fate/h264-conformance-frext-hpcvfl_bcrm_a | 300 - .../fate/h264-conformance-frext-hpcvflnl_bcrm_a | 300 - .../fate/h264-conformance-frext-hpcvmolq_brcm_b | 100 - .../ref/fate/h264-conformance-frext-hpcvnl_brcm_a | 300 - .../tests/ref/fate/h264-conformance-hcbp2_hhi_a | 250 - .../tests/ref/fate/h264-conformance-hcmp1_hhi_a | 250 - .../tests/ref/fate/h264-conformance-ls_sva_d | 1700 --- .../tests/ref/fate/h264-conformance-midr_mw_d | 100 - .../tests/ref/fate/h264-conformance-mps_mw_a | 150 - .../tests/ref/fate/h264-conformance-mr1_bt_a | 62 - .../tests/ref/fate/h264-conformance-mr1_mw_a | 150 - .../tests/ref/fate/h264-conformance-mr2_mw_a | 300 - .../tests/ref/fate/h264-conformance-mr2_tandberg_e | 300 - .../tests/ref/fate/h264-conformance-mr3_tandberg_b | 300 - .../tests/ref/fate/h264-conformance-mr4_tandberg_c | 300 - .../tests/ref/fate/h264-conformance-mr5_tandberg_c | 300 - .../tests/ref/fate/h264-conformance-mr6_bt_b | 60 - .../tests/ref/fate/h264-conformance-mr7_bt_b | 60 - .../tests/ref/fate/h264-conformance-mr8_bt_b | 58 - .../tests/ref/fate/h264-conformance-mr9_bt_b | 58 - .../tests/ref/fate/h264-conformance-mv1_brcm_d | 257 - .../tests/ref/fate/h264-conformance-nl1_sony_d | 17 - .../tests/ref/fate/h264-conformance-nl2_sony_h | 300 - .../tests/ref/fate/h264-conformance-nl3_sva_e | 33 - .../tests/ref/fate/h264-conformance-nlmq1_jvc_c | 30 - .../tests/ref/fate/h264-conformance-nlmq2_jvc_c | 30 - .../tests/ref/fate/h264-conformance-nrf_mw_e | 100 - .../ref/fate/h264-conformance-sharp_mp_field_1_b | 15 - .../ref/fate/h264-conformance-sharp_mp_field_2_b | 15 - .../ref/fate/h264-conformance-sharp_mp_field_3_b | 15 - .../ref/fate/h264-conformance-sharp_mp_paff_1r2 | 15 - .../ref/fate/h264-conformance-sharp_mp_paff_2r | 15 - .../tests/ref/fate/h264-conformance-sl1_sva_b | 33 - .../tests/ref/fate/h264-conformance-sva_ba1_b | 17 - .../tests/ref/fate/h264-conformance-sva_ba2_d | 17 - .../tests/ref/fate/h264-conformance-sva_base_b | 17 - .../tests/ref/fate/h264-conformance-sva_cl1_e | 50 - .../tests/ref/fate/h264-conformance-sva_fm1_e | 17 - .../tests/ref/fate/h264-conformance-sva_nl1_b | 17 - .../tests/ref/fate/h264-conformance-sva_nl2_e | 17 - tizen/distrib/ffmpeg/tests/ref/fate/id-cin-video | 105 - .../distrib/ffmpeg/tests/ref/fate/idroq-video-dpcm | 377 - .../ffmpeg/tests/ref/fate/idroq-video-encode | 1 - tizen/distrib/ffmpeg/tests/ref/fate/iff-byterun1 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/iff-fibonacci | 1 - tizen/distrib/ffmpeg/tests/ref/fate/iff-ilbm | 1 - tizen/distrib/ffmpeg/tests/ref/fate/iff-pcm | 1 - tizen/distrib/ffmpeg/tests/ref/fate/indeo2 | 130 - tizen/distrib/ffmpeg/tests/ref/fate/indeo3 | 40 - tizen/distrib/ffmpeg/tests/ref/fate/indeo5 | 134 - .../ffmpeg/tests/ref/fate/interplay-mve-16bit | 129 - .../ffmpeg/tests/ref/fate/interplay-mve-8bit | 234 - tizen/distrib/ffmpeg/tests/ref/fate/iv8-demux | 25 - tizen/distrib/ffmpeg/tests/ref/fate/kmvc | 75 - tizen/distrib/ffmpeg/tests/ref/fate/lmlm4-demux | 547 - tizen/distrib/ffmpeg/tests/ref/fate/loco-rgb | 5 - tizen/distrib/ffmpeg/tests/ref/fate/loco-yuy2 | 3 - .../ffmpeg/tests/ref/fate/lossless-appleaudio | 1 - .../ffmpeg/tests/ref/fate/lossless-meridianaudio | 1 - .../ffmpeg/tests/ref/fate/lossless-monkeysaudio | 1 - .../ffmpeg/tests/ref/fate/lossless-shortenaudio | 1 - tizen/distrib/ffmpeg/tests/ref/fate/lossless-tta | 1 - .../ffmpeg/tests/ref/fate/lossless-wavpackaudio | 1 - tizen/distrib/ffmpeg/tests/ref/fate/maxis-xa | 1 - tizen/distrib/ffmpeg/tests/ref/fate/mimic | 76 - tizen/distrib/ffmpeg/tests/ref/fate/motionpixels | 112 - tizen/distrib/ffmpeg/tests/ref/fate/mpc7-demux | 1 - tizen/distrib/ffmpeg/tests/ref/fate/mpc8-demux | 1 - .../ffmpeg/tests/ref/fate/mpeg4-als-conformance-00 | 1 - .../ffmpeg/tests/ref/fate/mpeg4-als-conformance-01 | 1 - .../ffmpeg/tests/ref/fate/mpeg4-als-conformance-02 | 1 - .../ffmpeg/tests/ref/fate/mpeg4-als-conformance-03 | 1 - .../ffmpeg/tests/ref/fate/mpeg4-als-conformance-04 | 1 - .../ffmpeg/tests/ref/fate/mpeg4-als-conformance-05 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/msrle-8bit | 29 - tizen/distrib/ffmpeg/tests/ref/fate/msvideo1-16bit | 30 - tizen/distrib/ffmpeg/tests/ref/fate/msvideo1-8bit | 31 - tizen/distrib/ffmpeg/tests/ref/fate/mszh | 1 - tizen/distrib/ffmpeg/tests/ref/fate/mtv | 135 - tizen/distrib/ffmpeg/tests/ref/fate/mxf-demux | 97 - tizen/distrib/ffmpeg/tests/ref/fate/nc-demux | 91 - tizen/distrib/ffmpeg/tests/ref/fate/nsv-demux | 171 - tizen/distrib/ffmpeg/tests/ref/fate/nuv | 30 - tizen/distrib/ffmpeg/tests/ref/fate/oma-demux | 1 - tizen/distrib/ffmpeg/tests/ref/fate/pcm_dvd | 123 - tizen/distrib/ffmpeg/tests/ref/fate/psx-str | 200 - tizen/distrib/ffmpeg/tests/ref/fate/ptx | 1 - tizen/distrib/ffmpeg/tests/ref/fate/pva-demux | 25 - tizen/distrib/ffmpeg/tests/ref/fate/qcp-demux | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qpeg | 100 - tizen/distrib/ffmpeg/tests/ref/fate/qt-alaw-mono | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-alaw-stereo | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-ima4-mono | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-ima4-stereo | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-mac3-mono | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-mac3-stereo | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-mac6-mono | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-mac6-stereo | 1 - .../ffmpeg/tests/ref/fate/qt-msadpcm-stereo | 1 - .../ffmpeg/tests/ref/fate/qt-msimaadpcm-stereo | 1 - .../ref/fate/qt-rawpcm-16bit-stereo-signed-be | 1 - .../ref/fate/qt-rawpcm-16bit-stereo-signed-le | 1 - .../tests/ref/fate/qt-rawpcm-8bit-mono-unsigned | 1 - .../tests/ref/fate/qt-rawpcm-8bit-stereo-unsigned | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-ulaw-mono | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qt-ulaw-stereo | 1 - tizen/distrib/ffmpeg/tests/ref/fate/qtrle-16bit | 83 - tizen/distrib/ffmpeg/tests/ref/fate/qtrle-1bit | 107 - tizen/distrib/ffmpeg/tests/ref/fate/qtrle-24bit | 34 - tizen/distrib/ffmpeg/tests/ref/fate/qtrle-2bit | 107 - tizen/distrib/ffmpeg/tests/ref/fate/qtrle-32bit | 26 - tizen/distrib/ffmpeg/tests/ref/fate/qtrle-4bit | 38 - tizen/distrib/ffmpeg/tests/ref/fate/qtrle-8bit | 167 - tizen/distrib/ffmpeg/tests/ref/fate/quickdraw | 2 - tizen/distrib/ffmpeg/tests/ref/fate/real-14_4 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/real-rv40 | 121 - tizen/distrib/ffmpeg/tests/ref/fate/redcode-demux | 5 - tizen/distrib/ffmpeg/tests/ref/fate/rl2 | 108 - tizen/distrib/ffmpeg/tests/ref/fate/rpza | 30 - tizen/distrib/ffmpeg/tests/ref/fate/sierra-audio | 1 - tizen/distrib/ffmpeg/tests/ref/fate/sierra-vmd | 303 - tizen/distrib/ffmpeg/tests/ref/fate/siff | 39 - tizen/distrib/ffmpeg/tests/ref/fate/smacker | 186 - tizen/distrib/ffmpeg/tests/ref/fate/smc | 120 - tizen/distrib/ffmpeg/tests/ref/fate/sp5x | 19 - .../ffmpeg/tests/ref/fate/sunraster-1bit-raw | 1 - .../ffmpeg/tests/ref/fate/sunraster-1bit-rle | 1 - .../ffmpeg/tests/ref/fate/sunraster-24bit-raw | 1 - .../ffmpeg/tests/ref/fate/sunraster-24bit-rle | 1 - .../ffmpeg/tests/ref/fate/sunraster-8bit-raw | 1 - .../ffmpeg/tests/ref/fate/sunraster-8bit-rle | 1 - tizen/distrib/ffmpeg/tests/ref/fate/svq1 | 150 - tizen/distrib/ffmpeg/tests/ref/fate/svq3 | 180 - .../distrib/ffmpeg/tests/ref/fate/thp-mjpeg-adpcm | 143 - tizen/distrib/ffmpeg/tests/ref/fate/tiertex-seq | 149 - tizen/distrib/ffmpeg/tests/ref/fate/tmv | 220 - tizen/distrib/ffmpeg/tests/ref/fate/tscc-15bit | 240 - tizen/distrib/ffmpeg/tests/ref/fate/tscc-32bit | 159 - tizen/distrib/ffmpeg/tests/ref/fate/ulti | 62 - tizen/distrib/ffmpeg/tests/ref/fate/v210 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/vc1 | 2 - tizen/distrib/ffmpeg/tests/ref/fate/vcr1 | 128 - tizen/distrib/ffmpeg/tests/ref/fate/video-xl | 40 - tizen/distrib/ffmpeg/tests/ref/fate/vmnc-16bit | 192 - tizen/distrib/ffmpeg/tests/ref/fate/vmnc-32bit | 171 - tizen/distrib/ffmpeg/tests/ref/fate/vp5 | 246 - tizen/distrib/ffmpeg/tests/ref/fate/vp6a | 93 - tizen/distrib/ffmpeg/tests/ref/fate/vp6f | 174 - tizen/distrib/ffmpeg/tests/ref/fate/vqa-cc | 78 - tizen/distrib/ffmpeg/tests/ref/fate/vqf-demux | 1 - tizen/distrib/ffmpeg/tests/ref/fate/w64 | 1 - tizen/distrib/ffmpeg/tests/ref/fate/wc3movie-xan | 70 - tizen/distrib/ffmpeg/tests/ref/fate/westwood-aud | 1 - tizen/distrib/ffmpeg/tests/ref/fate/wnv1 | 86 - tizen/distrib/ffmpeg/tests/ref/fate/xan-dpcm | 1 - tizen/distrib/ffmpeg/tests/ref/fate/zlib | 1 - tizen/distrib/ffmpeg/tests/ref/fate/zmbv-15bit | 159 - tizen/distrib/ffmpeg/tests/ref/fate/zmbv-16bit | 159 - tizen/distrib/ffmpeg/tests/ref/fate/zmbv-32bit | 159 - tizen/distrib/ffmpeg/tests/ref/fate/zmbv-8bit | 275 - tizen/distrib/ffmpeg/tests/ref/lavf/aiff | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/alaw | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/asf | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/au | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/avi | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/bmp | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/dv_fmt | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/ffm | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/flv_fmt | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/gif | 2 - tizen/distrib/ffmpeg/tests/ref/lavf/gxf | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/jpg | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/mkv | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/mmf | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/mov | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/mpg | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/mulaw | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/mxf | 6 - tizen/distrib/ffmpeg/tests/ref/lavf/nut | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/ogg | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/pbmpipe | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/pcx | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/pgm | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/pgmpipe | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/pixfmt | 38 - tizen/distrib/ffmpeg/tests/ref/lavf/ppm | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/ppmpipe | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/rm | 2 - tizen/distrib/ffmpeg/tests/ref/lavf/sgi | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/swf | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/tga | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/tiff | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/ts | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/voc | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/wav | 3 - tizen/distrib/ffmpeg/tests/ref/lavf/yuv4mpeg | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/crop | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/crop_scale | 2 - .../ffmpeg/tests/ref/lavfi/crop_scale_vflip | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/crop_vflip | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/null | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/scale200 | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/scale500 | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/vflip | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/vflip_crop | 2 - tizen/distrib/ffmpeg/tests/ref/lavfi/vflip_vflip | 2 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.bmp.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.jpg.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.pcx.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.pgm.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.ppm.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.sgi.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.tga.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/%02d.tiff.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/ac3.rm.ref | 39 - .../ffmpeg/tests/ref/seek/adpcm_ima.wav.ref | 53 - .../distrib/ffmpeg/tests/ref/seek/adpcm_ms.wav.ref | 53 - .../ffmpeg/tests/ref/seek/adpcm_qt.aiff.ref | 53 - .../ffmpeg/tests/ref/seek/adpcm_swf.flv.ref | 49 - .../ffmpeg/tests/ref/seek/adpcm_yam.wav.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/alac.m4a.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/asv1.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/asv2.avi.ref | 46 - .../ffmpeg/tests/ref/seek/dnxhd-1080i.mov.ref | 44 - .../ffmpeg/tests/ref/seek/dnxhd-720p-rd.dnxhd.ref | 40 - .../ffmpeg/tests/ref/seek/dnxhd-720p.dnxhd.ref | 40 - tizen/distrib/ffmpeg/tests/ref/seek/dv.dv.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/dv411.dv.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/dv50.dv.ref | 53 - .../ffmpeg/tests/ref/seek/error-mpeg4-adv.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/ffv1.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/flac.flac.ref | 27 - .../distrib/ffmpeg/tests/ref/seek/flashsv.flv.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/flv.flv.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/g726.wav.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/h261.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/h263.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/h263p.avi.ref | 46 - .../distrib/ffmpeg/tests/ref/seek/huffyuv.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/jpegls.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.aif.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.al.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.asf.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.au.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.avi.ref | 44 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.dv.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.ffm.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.flv.ref | 44 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.gif.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.gxf.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.mkv.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.mmf.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.mov.ref | 48 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.mpg.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.mxf.ref | 53 - .../distrib/ffmpeg/tests/ref/seek/lavf.mxf_d10.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.nut.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.ogg.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.rm.ref | 47 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.swf.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.ts.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.ul.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.voc.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.wav.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/lavf.y4m.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/ljpeg.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/mjpeg.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/mp2.mp2.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/mpeg1.mpg.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/mpeg1b.mpg.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/mpeg2.mpg.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg2_422.mpg.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/mpeg2i.mpg.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg2ivlc-qprd.mpg.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg2reuse.mpg.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg2thread.mpg.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg2threadivlc.mpg.ref | 46 - .../distrib/ffmpeg/tests/ref/seek/mpeg4-Q.avi.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg4-adap.avi.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg4-adv.avi.ref | 46 - .../distrib/ffmpeg/tests/ref/seek/mpeg4-nr.avi.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg4-qprd.avi.ref | 46 - .../distrib/ffmpeg/tests/ref/seek/mpeg4-rc.avi.ref | 46 - .../ffmpeg/tests/ref/seek/mpeg4-thread.avi.ref | 46 - .../distrib/ffmpeg/tests/ref/seek/msmpeg4.avi.ref | 46 - .../ffmpeg/tests/ref/seek/msmpeg4v2.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/odivx.mp4.ref | 50 - .../distrib/ffmpeg/tests/ref/seek/pbmpipe.pbm.ref | 27 - .../distrib/ffmpeg/tests/ref/seek/pcm_alaw.wav.ref | 53 - .../distrib/ffmpeg/tests/ref/seek/pcm_f32be.au.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_f32le.wav.ref | 53 - .../distrib/ffmpeg/tests/ref/seek/pcm_f64be.au.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_f64le.wav.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_mulaw.wav.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s16be.mkv.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s16be.mov.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s16le.mkv.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s16le.wav.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s24be.mov.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s24daud.302.ref | 27 - .../ffmpeg/tests/ref/seek/pcm_s24le.wav.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s32be.mov.ref | 53 - .../ffmpeg/tests/ref/seek/pcm_s32le.wav.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/pcm_s8.mov.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/pcm_u8.wav.ref | 53 - .../distrib/ffmpeg/tests/ref/seek/pcm_zork.wav.ref | 53 - .../distrib/ffmpeg/tests/ref/seek/pgmpipe.pgm.ref | 27 - .../distrib/ffmpeg/tests/ref/seek/ppmpipe.ppm.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/roqav.roq.ref | 27 - tizen/distrib/ffmpeg/tests/ref/seek/rv10.rm.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/rv20.rm.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/snow.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/snow53.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/svq1.mov.ref | 50 - tizen/distrib/ffmpeg/tests/ref/seek/wmav1.asf.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/wmav2.asf.ref | 53 - tizen/distrib/ffmpeg/tests/ref/seek/wmv1.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/seek/wmv2.avi.ref | 46 - tizen/distrib/ffmpeg/tests/ref/vsynth1/asv1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/asv2 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/dnxhd_1080i | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/dnxhd_720p | 4 - .../distrib/ffmpeg/tests/ref/vsynth1/dnxhd_720p_rd | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/dv | 8 - tizen/distrib/ffmpeg/tests/ref/vsynth1/dv50 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/error | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/ffv1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/flashsv | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/flv | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/h261 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/h263 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/h263p | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/huffyuv | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/jpegls | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/ljpeg | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mjpeg | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg1b | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg2 | 20 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg2thread | 12 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4adv | 16 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4nr | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4thread | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/msmpeg4 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/msmpeg4v2 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/rc | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/roq | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/rv10 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/rv20 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/snow | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/snowll | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/svq1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/wmv1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth1/wmv2 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/asv1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/asv2 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/dnxhd_1080i | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/dnxhd_720p | 4 - .../distrib/ffmpeg/tests/ref/vsynth2/dnxhd_720p_rd | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/dv | 8 - tizen/distrib/ffmpeg/tests/ref/vsynth2/dv50 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/error | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/ffv1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/flashsv | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/flv | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/h261 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/h263 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/h263p | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/huffyuv | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/jpegls | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/ljpeg | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mjpeg | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg1b | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg2 | 20 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg2thread | 12 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4adv | 16 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4nr | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4thread | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/msmpeg4 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/msmpeg4v2 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/rc | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/roq | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/rv10 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/rv20 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/snow | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/snowll | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/svq1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/wmv1 | 4 - tizen/distrib/ffmpeg/tests/ref/vsynth2/wmv2 | 4 - tizen/distrib/ffmpeg/tests/regression-funcs.sh | 124 - tizen/distrib/ffmpeg/tests/rotozoom.c | 304 - tizen/distrib/ffmpeg/tests/seek-regression.sh | 38 - tizen/distrib/ffmpeg/tests/seek_test.c | 132 - tizen/distrib/ffmpeg/tests/tiny_psnr.c | 169 - tizen/distrib/ffmpeg/tests/videogen.c | 292 - tizen/distrib/ffmpeg/tizen_configure | 13 - tizen/distrib/ffmpeg/tools/build_avopt | 9 - tizen/distrib/ffmpeg/tools/clean-diff | 11 - tizen/distrib/ffmpeg/tools/cws2fws.c | 130 - tizen/distrib/ffmpeg/tools/graph2dot.c | 163 - tizen/distrib/ffmpeg/tools/patcheck | 161 - tizen/distrib/ffmpeg/tools/pktdumper.c | 122 - tizen/distrib/ffmpeg/tools/probetest.c | 120 - tizen/distrib/ffmpeg/tools/qt-faststart.c | 332 - tizen/distrib/ffmpeg/tools/trasher.c | 73 - tizen/distrib/ffmpeg/tools/unwrap-diff | 2 - tizen/distrib/ffmpeg/version.sh | 40 - tizen/skins/emul_320x480/default.dbi | 432 - tizen/skins/emul_320x480/default.png | Bin 31843 -> 0 bytes tizen/skins/emul_320x480/default_180.png | Bin 31522 -> 0 bytes tizen/skins/emul_320x480/default_180_p.png | Bin 33097 -> 0 bytes tizen/skins/emul_320x480/default_p.png | Bin 33038 -> 0 bytes tizen/skins/emul_320x480/default_w.png | Bin 28181 -> 0 bytes tizen/skins/emul_320x480/default_w90.png | Bin 28944 -> 0 bytes tizen/skins/emul_320x480/default_w90_p.png | Bin 30381 -> 0 bytes tizen/skins/emul_320x480/default_w_p.png | Bin 30057 -> 0 bytes tizen/skins/emul_3keys_320x480/default.dbi | 592 - tizen/skins/emul_3keys_320x480/default.png | Bin 32138 -> 0 bytes tizen/skins/emul_3keys_320x480/default_180.png | Bin 32171 -> 0 bytes tizen/skins/emul_3keys_320x480/default_180_p.png | Bin 35737 -> 0 bytes tizen/skins/emul_3keys_320x480/default_p.png | Bin 34903 -> 0 bytes tizen/skins/emul_3keys_320x480/default_w.png | Bin 28735 -> 0 bytes tizen/skins/emul_3keys_320x480/default_w90.png | Bin 29494 -> 0 bytes tizen/skins/emul_3keys_320x480/default_w90_p.png | Bin 33242 -> 0 bytes tizen/skins/emul_3keys_320x480/default_w_p.png | Bin 32847 -> 0 bytes tizen/skins/emul_3keys_480x800/default.dbi | 592 - tizen/skins/emul_3keys_480x800/default.png | Bin 52823 -> 0 bytes tizen/skins/emul_3keys_480x800/default_180.png | Bin 52622 -> 0 bytes tizen/skins/emul_3keys_480x800/default_180_p.png | Bin 58106 -> 0 bytes tizen/skins/emul_3keys_480x800/default_p.png | Bin 56938 -> 0 bytes tizen/skins/emul_3keys_480x800/default_w.png | Bin 47478 -> 0 bytes tizen/skins/emul_3keys_480x800/default_w90.png | Bin 48670 -> 0 bytes tizen/skins/emul_3keys_480x800/default_w90_p.png | Bin 54051 -> 0 bytes tizen/skins/emul_3keys_480x800/default_w_p.png | Bin 53533 -> 0 bytes tizen/skins/emul_3keys_600x1024/default.dbi | 592 - tizen/skins/emul_3keys_600x1024/default.png | Bin 68771 -> 0 bytes tizen/skins/emul_3keys_600x1024/default_180.png | Bin 68427 -> 0 bytes tizen/skins/emul_3keys_600x1024/default_180_p.png | Bin 75535 -> 0 bytes tizen/skins/emul_3keys_600x1024/default_p.png | Bin 73990 -> 0 bytes tizen/skins/emul_3keys_600x1024/default_w.png | Bin 64770 -> 0 bytes tizen/skins/emul_3keys_600x1024/default_w90.png | Bin 65387 -> 0 bytes tizen/skins/emul_3keys_600x1024/default_w90_p.png | Bin 72788 -> 0 bytes tizen/skins/emul_3keys_600x1024/default_w_p.png | Bin 73135 -> 0 bytes tizen/skins/emul_3keys_720x1280/default.dbi | 592 - tizen/skins/emul_3keys_720x1280/default.png | Bin 83969 -> 0 bytes tizen/skins/emul_3keys_720x1280/default_180.png | Bin 84060 -> 0 bytes tizen/skins/emul_3keys_720x1280/default_180_p.png | Bin 93522 -> 0 bytes tizen/skins/emul_3keys_720x1280/default_p.png | Bin 90796 -> 0 bytes tizen/skins/emul_3keys_720x1280/default_w.png | Bin 79535 -> 0 bytes tizen/skins/emul_3keys_720x1280/default_w90.png | Bin 80087 -> 0 bytes tizen/skins/emul_3keys_720x1280/default_w90_p.png | Bin 89604 -> 0 bytes tizen/skins/emul_3keys_720x1280/default_w_p.png | Bin 89976 -> 0 bytes tizen/skins/emul_480x800/default.dbi | 432 - tizen/skins/emul_480x800/default.png | Bin 52469 -> 0 bytes tizen/skins/emul_480x800/default_180.png | Bin 52169 -> 0 bytes tizen/skins/emul_480x800/default_180_p.png | Bin 55315 -> 0 bytes tizen/skins/emul_480x800/default_p.png | Bin 54897 -> 0 bytes tizen/skins/emul_480x800/default_w.png | Bin 46793 -> 0 bytes tizen/skins/emul_480x800/default_w90.png | Bin 47991 -> 0 bytes tizen/skins/emul_480x800/default_w90_p.png | Bin 50686 -> 0 bytes tizen/skins/emul_480x800/default_w_p.png | Bin 50292 -> 0 bytes tizen/skins/emul_600x1024/default.dbi | 432 - tizen/skins/emul_600x1024/default.png | Bin 68407 -> 0 bytes tizen/skins/emul_600x1024/default_180.png | Bin 67941 -> 0 bytes tizen/skins/emul_600x1024/default_180_p.png | Bin 71523 -> 0 bytes tizen/skins/emul_600x1024/default_p.png | Bin 71074 -> 0 bytes tizen/skins/emul_600x1024/default_w.png | Bin 64040 -> 0 bytes tizen/skins/emul_600x1024/default_w90.png | Bin 64865 -> 0 bytes tizen/skins/emul_600x1024/default_w90_p.png | Bin 67889 -> 0 bytes tizen/skins/emul_600x1024/default_w_p.png | Bin 68103 -> 0 bytes tizen/skins/emul_720x1280/default.dbi | 432 - tizen/skins/emul_720x1280/default.png | Bin 83440 -> 0 bytes tizen/skins/emul_720x1280/default_180.png | Bin 83287 -> 0 bytes tizen/skins/emul_720x1280/default_180_p.png | Bin 88195 -> 0 bytes tizen/skins/emul_720x1280/default_p.png | Bin 86865 -> 0 bytes tizen/skins/emul_720x1280/default_w.png | Bin 78391 -> 0 bytes tizen/skins/emul_720x1280/default_w90.png | Bin 79088 -> 0 bytes tizen/skins/emul_720x1280/default_w90_p.png | Bin 82776 -> 0 bytes tizen/skins/emul_720x1280/default_w_p.png | Bin 83262 -> 0 bytes tizen/skins/icons/01_SHELL.png | Bin 879 -> 0 bytes tizen/skins/icons/02_ADVANCED.png | Bin 583 -> 0 bytes tizen/skins/icons/03_TELEPHONY-EMULATOR.png | Bin 1243 -> 0 bytes tizen/skins/icons/04_KEYPAD.png | Bin 1148 -> 0 bytes tizen/skins/icons/05_GPS.png | Bin 1164 -> 0 bytes tizen/skins/icons/06_SCREEN-SHOT.png | Bin 1305 -> 0 bytes tizen/skins/icons/07_EXECUTE_APP.png | Bin 991 -> 0 bytes tizen/skins/icons/08_OPEN.png | Bin 956 -> 0 bytes tizen/skins/icons/09_ROTATE.png | Bin 1245 -> 0 bytes tizen/skins/icons/10_PROPERTIES.png | Bin 1216 -> 0 bytes tizen/skins/icons/11_OPTION.png | Bin 1201 -> 0 bytes tizen/skins/icons/12_DEVICE-INFO.png | Bin 970 -> 0 bytes tizen/skins/icons/13_ABOUT.png | Bin 1112 -> 0 bytes tizen/skins/icons/14_CLOSE.png | Bin 1036 -> 0 bytes tizen/skins/icons/15_COMPASS.png | Bin 3380 -> 0 bytes tizen/skins/icons/Emulator.ico | Bin 4286 -> 0 bytes tizen/skins/icons/Emulator_20x20.png | Bin 3633 -> 0 bytes tizen/skins/icons/Icon_Toolbar.gif | Bin 1784 -> 0 bytes tizen/skins/icons/vtm.ico | Bin 4286 -> 0 bytes tizen/src/DEBUGCH | 3 - tizen/src/Makefile.in | 243 - tizen/src/Makefile_win32 | 87 - tizen/src/NOTICE | 2 - tizen/src/VERSION | 2 +- tizen/src/about_version.h | 46 - tizen/src/arch_arm.c | 80 - tizen/src/arch_x86.c | 80 - tizen/src/command.c | 100 - tizen/src/command.h | 72 - tizen/src/config_dbg_x86.ini | 32 - tizen/src/config_x86.ini | 32 - tizen/src/configuration.c | 863 -- tizen/src/configuration.h | 99 - tizen/src/dbi_parser.c | 556 - tizen/src/dbi_parser.h | 75 - tizen/src/debug_ch.c | 96 +- tizen/src/debug_ch.h | 8 +- tizen/src/debug_ch_vtm.c | 454 - tizen/src/defines.h | 705 -- tizen/src/dialog.c | 243 - tizen/src/dialog.h | 57 - tizen/src/emul_debug.bat | 1 - tizen/src/emul_debug.sh | 4 - tizen/src/emulator.c | 1564 +-- tizen/src/emulator.h | 96 +- tizen/src/emulator.sh | 429 - tizen/src/emulator.sh.old | 413 - tizen/src/emulsignal.c | 278 - tizen/src/emulsignal.h | 60 - tizen/src/event_handler.c | 1270 -- tizen/src/event_handler.h | 78 - tizen/src/extern.h | 78 - tizen/src/fileio.c | 616 - tizen/src/fileio.h | 91 - tizen/src/hw/brightness.c | 206 - .../hw/camera_win32_dll/hwcfilter/hwcfilter.sln | 20 - .../hw/camera_win32_dll/hwcfilter/hwcfilter.suo | Bin 33280 -> 0 bytes .../hwcfilter/hwcfilter/ReadMe.txt | 38 - .../hwcfilter/hwcfilter/dllmain.cpp | 19 - .../hwcfilter/hwcfilter/hwccallback_h.h | 155 - .../hwcfilter/hwcfilter/hwcfilter.cpp | 616 - .../hwcfilter/hwcfilter/hwcfilter.def | 4 - .../hwcfilter/hwcfilter/hwcfilter.h | 120 - .../hwcfilter/hwcfilter/hwcfilter.vcxproj | 109 - .../hwcfilter/hwcfilter/hwcfilter.vcxproj.filters | 57 - .../hwcfilter/hwcfilter/hwcfilter.vcxproj.user | 3 - .../hwcfilter/hwcfilter/hwcfilter_h.h | 279 - .../camera_win32_dll/hwcfilter/hwcfilter/hwcsp.cpp | 882 -- .../camera_win32_dll/hwcfilter/hwcfilter/hwcsp.h | 141 - .../hwcfilter/hwcfilter/stdafx.cpp | 8 - .../camera_win32_dll/hwcfilter/hwcfilter/stdafx.h | 16 - .../hwcfilter/hwcfilter/targetver.h | 8 - tizen/src/hw/maru_codec.c | 1735 ++- tizen/src/hw/maru_codec.h | 154 +- tizen/src/hw/maru_pm.c | 331 +- tizen/src/hw/maru_pm.h | 2 +- tizen/src/hw/maru_touchscreen.c | 312 - tizen/src/hw/overlay.c | 226 - tizen/src/hw/svcamera.h | 121 - tizen/src/hw/svcamera_linux.c | 665 - tizen/src/hw/svcamera_pci.c | 262 - tizen/src/hw/svcamera_win32.c | 745 -- tizen/src/hw/tizen-ac97.c | 1395 --- tizen/src/hw/tizen-board.c | 296 - tizen/src/menu.c | 338 - tizen/src/menu.h | 66 - tizen/src/menu_callback.c | 773 -- tizen/src/menu_callback.h | 87 - tizen/src/option.c | 920 +- tizen/src/option.h | 39 +- tizen/src/option_callback.c | 440 - tizen/src/option_callback.h | 99 - tizen/src/qemu_gtk_widget.c | 693 -- tizen/src/qemu_gtk_widget.h | 119 - tizen/src/savevm.glade | 44 - tizen/src/screen_shot.c | 910 -- tizen/src/screen_shot.h | 76 - tizen/src/sensor_server.c | 485 - tizen/src/sensor_server.h | 47 - tizen/src/tools.c | 403 - tizen/src/tools.h | 78 - tizen/src/ui_imageid.h | 137 - tizen/src/utils.c | 481 - tizen/src/utils.h | 67 - tizen/src/vinit_process.c | 170 - tizen/src/vinit_process.h | 61 - tizen/src/vt_utils.c | 155 - tizen/src/vt_utils.h | 58 - tizen/src/vtm.c | 3000 ----- tizen/src/vtm.glade | 932 -- tizen/src/vtm.h | 137 - trace-events | 723 +- translate-all.c | 8 +- ui/cocoa.m | 33 +- ui/curses.c | 3 +- ui/keymaps.c | 16 +- ui/qemu-spice.h | 28 +- ui/sdl.c | 710 +- ui/sdl_keysym.h | 4 - ui/sdl_rotate.c | 1610 --- ui/sdl_rotate.h | 99 - ui/spice-core.c | 316 +- ui/spice-display.c | 171 +- ui/spice-display.h | 56 +- ui/spice-input.c | 8 +- ui/vnc-auth-sasl.c | 44 +- ui/vnc-auth-vencrypt.c | 18 +- ui/vnc-enc-hextile.c | 8 +- ui/vnc-enc-tight.c | 101 +- ui/vnc-enc-zlib.c | 4 +- ui/vnc-jobs-async.c | 22 +- ui/vnc-palette.c | 62 +- ui/vnc-palette.h | 7 +- ui/vnc-tls.c | 90 +- ui/vnc.c | 554 +- ui/vnc.h | 64 +- ui/vnc_keysym.h | 18 + usb-bsd.c | 22 +- usb-linux.c | 1374 +- vl.c | 1400 ++- vl.h | 41 - x86_64.ld | 14 +- 3279 files changed, 78465 insertions(+), 772169 deletions(-) mode change 100644 => 100755 Makefile.target delete mode 100644 NOTICE mode change 100644 => 100755 QMP/qmp-shell delete mode 100644 block/rbd_types.h delete mode 100644 fpu/softfloat-native.c delete mode 100644 fpu/softfloat-native.h delete mode 100644 hpet.h delete mode 100644 hw/3D.h delete mode 100644 hw/ak8973.c delete mode 100644 hw/ak8973.h delete mode 100644 hw/alpha_palcode.c delete mode 100644 hw/etraxfs.c delete mode 100644 hw/event_notifier.c delete mode 100644 hw/event_notifier.h delete mode 100644 hw/file-op-9p.h delete mode 100644 hw/gles1_calls.c delete mode 100644 hw/gles2.c delete mode 100644 hw/gles2.h delete mode 100644 hw/gles2_calls.c delete mode 100644 hw/gles2_calls.h delete mode 100644 hw/gles2_types.h delete mode 100644 hw/i2c-addressable.c delete mode 100644 hw/i2c-addressable.h delete mode 100644 hw/iommu.c delete mode 100644 hw/mainstone.h delete mode 100644 hw/mcs5000_tk.c mode change 100755 => 100644 hw/pc.h delete mode 100644 hw/pci_host_template.h delete mode 100644 hw/pl192.c delete mode 100644 hw/pl330.c delete mode 100644 hw/ppce500.h delete mode 100644 hw/qt602240_ts.c delete mode 100644 hw/s5pc1xx.c delete mode 100644 hw/s5pc1xx.h delete mode 100644 hw/s5pc1xx_ac97.c delete mode 100644 hw/s5pc1xx_clk.c delete mode 100644 hw/s5pc1xx_debug.c delete mode 100644 hw/s5pc1xx_gpio.c delete mode 100644 hw/s5pc1xx_gpio_regs.h delete mode 100644 hw/s5pc1xx_hsmmc_regs.h delete mode 100644 hw/s5pc1xx_i2c.c delete mode 100644 hw/s5pc1xx_i2c_gpio.c delete mode 100644 hw/s5pc1xx_i2s.c delete mode 100644 hw/s5pc1xx_jpeg.c delete mode 100644 hw/s5pc1xx_keyif.c delete mode 100644 hw/s5pc1xx_lcd.c delete mode 100644 hw/s5pc1xx_mmc.c delete mode 100644 hw/s5pc1xx_nand.c delete mode 100644 hw/s5pc1xx_onedram.c delete mode 100644 hw/s5pc1xx_onedram.h delete mode 100644 hw/s5pc1xx_onenand.c delete mode 100644 hw/s5pc1xx_pcm.c delete mode 100644 hw/s5pc1xx_pmu.c delete mode 100644 hw/s5pc1xx_pwm.c delete mode 100644 hw/s5pc1xx_rtc.c delete mode 100644 hw/s5pc1xx_spdif.c delete mode 100644 hw/s5pc1xx_spi.c delete mode 100644 hw/s5pc1xx_srom.c delete mode 100644 hw/s5pc1xx_st.c delete mode 100644 hw/s5pc1xx_tsadc.c delete mode 100644 hw/s5pc1xx_uart.c delete mode 100644 hw/s5pc1xx_usb_otg.c delete mode 100644 hw/s5pc1xx_wdt.c delete mode 100644 hw/smb380.c delete mode 100644 hw/smbus_smb380.c delete mode 100644 hw/usb-ehci.h mode change 100755 => 100644 hw/vga.c delete mode 100644 hw/virtio-9p-debug.c delete mode 100644 hw/virtio-9p-debug.h delete mode 100644 hw/virtio-9p-local.c delete mode 100644 hw/virtio-9p-posix-acl.c delete mode 100644 hw/virtio-9p-xattr-user.c delete mode 100644 hw/virtio-9p-xattr.c delete mode 100644 hw/virtio-9p-xattr.h delete mode 100644 hw/virtio-9p.c delete mode 100644 hw/virtio-9p.h delete mode 100644 hw/virtio-gpi.c delete mode 100644 hw/wm8994.c delete mode 100644 hw/wm8994_reg.h delete mode 100644 linux-user/elfload32.c delete mode 100644 net-checksum.c delete mode 100755 package/build.linux delete mode 100755 package/build.windows delete mode 100755 package/emulator.install.linux delete mode 100755 package/emulator.install.windows delete mode 100755 package/emulator.remove.linux delete mode 100755 package/emulator.remove.windows delete mode 100644 pc-bios/gpxe-eepro100-80861209.rom mode change 100755 => 100644 pc-bios/linuxboot.bin delete mode 100644 pc-bios/pxe-e1000.bin delete mode 100644 pc-bios/pxe-ne2k_pci.bin delete mode 100644 pc-bios/pxe-pcnet.bin delete mode 100644 pc-bios/pxe-rtl8139.bin delete mode 100644 pc-bios/pxe-virtio.bin delete mode 100644 pc-bios/vgabios-tizenvga.bin delete mode 100644 qemu-malloc.c delete mode 100644 qemu-thread.c delete mode 100755 qemu_configure.sh delete mode 100644 roms/seabios/COPYING delete mode 100644 roms/seabios/COPYING.LESSER delete mode 100644 roms/seabios/Makefile delete mode 100644 roms/seabios/README delete mode 100644 roms/seabios/TODO delete mode 100644 roms/seabios/src/acpi-dsdt.dsl delete mode 100644 roms/seabios/src/acpi-dsdt.hex delete mode 100644 roms/seabios/src/acpi.c delete mode 100644 roms/seabios/src/acpi.h delete mode 100644 roms/seabios/src/apm.c delete mode 100644 roms/seabios/src/asm-offsets.c delete mode 100644 roms/seabios/src/ata.c delete mode 100644 roms/seabios/src/ata.h delete mode 100644 roms/seabios/src/biosvar.h delete mode 100644 roms/seabios/src/block.c delete mode 100644 roms/seabios/src/blockcmd.c delete mode 100644 roms/seabios/src/blockcmd.h delete mode 100644 roms/seabios/src/boot.c delete mode 100644 roms/seabios/src/boot.h delete mode 100644 roms/seabios/src/bootsplash.c delete mode 100644 roms/seabios/src/bregs.h delete mode 100644 roms/seabios/src/cdrom.c delete mode 100644 roms/seabios/src/clock.c delete mode 100644 roms/seabios/src/cmos.h delete mode 100644 roms/seabios/src/config.h delete mode 100644 roms/seabios/src/coreboot.c delete mode 100644 roms/seabios/src/dev-i440fx.c delete mode 100644 roms/seabios/src/dev-i440fx.h delete mode 100644 roms/seabios/src/disk.c delete mode 100644 roms/seabios/src/disk.h delete mode 100644 roms/seabios/src/entryfuncs.S delete mode 100644 roms/seabios/src/farptr.h delete mode 100644 roms/seabios/src/floppy.c delete mode 100644 roms/seabios/src/font.c delete mode 100644 roms/seabios/src/gen-defs.h delete mode 100644 roms/seabios/src/ioport.h delete mode 100644 roms/seabios/src/jpeg.c delete mode 100644 roms/seabios/src/jpeg.h delete mode 100644 roms/seabios/src/kbd.c delete mode 100644 roms/seabios/src/lzmadecode.c delete mode 100644 roms/seabios/src/lzmadecode.h delete mode 100644 roms/seabios/src/memmap.c delete mode 100644 roms/seabios/src/memmap.h delete mode 100644 roms/seabios/src/misc.c delete mode 100644 roms/seabios/src/mouse.c delete mode 100644 roms/seabios/src/mptable.c delete mode 100644 roms/seabios/src/mptable.h delete mode 100644 roms/seabios/src/mtrr.c delete mode 100644 roms/seabios/src/optionroms.c delete mode 100644 roms/seabios/src/output.c delete mode 100644 roms/seabios/src/paravirt.c delete mode 100644 roms/seabios/src/paravirt.h delete mode 100644 roms/seabios/src/pci.c delete mode 100644 roms/seabios/src/pci.h delete mode 100644 roms/seabios/src/pci_ids.h delete mode 100644 roms/seabios/src/pci_regs.h delete mode 100644 roms/seabios/src/pcibios.c delete mode 100644 roms/seabios/src/pciinit.c delete mode 100644 roms/seabios/src/pic.c delete mode 100644 roms/seabios/src/pic.h delete mode 100644 roms/seabios/src/pirtable.c delete mode 100644 roms/seabios/src/pmm.c delete mode 100644 roms/seabios/src/pnpbios.c delete mode 100644 roms/seabios/src/post.c delete mode 100644 roms/seabios/src/ps2port.c delete mode 100644 roms/seabios/src/ps2port.h delete mode 100644 roms/seabios/src/ramdisk.c delete mode 100644 roms/seabios/src/resume.c delete mode 100644 roms/seabios/src/romlayout.S delete mode 100644 roms/seabios/src/serial.c delete mode 100644 roms/seabios/src/shadow.c delete mode 100644 roms/seabios/src/smbios.c delete mode 100644 roms/seabios/src/smbios.h delete mode 100644 roms/seabios/src/smm.c delete mode 100644 roms/seabios/src/smp.c delete mode 100644 roms/seabios/src/ssdt-proc.dsl delete mode 100644 roms/seabios/src/stacks.c delete mode 100644 roms/seabios/src/system.c delete mode 100644 roms/seabios/src/types.h delete mode 100644 roms/seabios/src/usb-ehci.c delete mode 100644 roms/seabios/src/usb-ehci.h delete mode 100644 roms/seabios/src/usb-hid.c delete mode 100644 roms/seabios/src/usb-hid.h delete mode 100644 roms/seabios/src/usb-hub.c delete mode 100644 roms/seabios/src/usb-hub.h delete mode 100644 roms/seabios/src/usb-msc.c delete mode 100644 roms/seabios/src/usb-msc.h delete mode 100644 roms/seabios/src/usb-ohci.c delete mode 100644 roms/seabios/src/usb-ohci.h delete mode 100644 roms/seabios/src/usb-uhci.c delete mode 100644 roms/seabios/src/usb-uhci.h delete mode 100644 roms/seabios/src/usb.c delete mode 100644 roms/seabios/src/usb.h delete mode 100644 roms/seabios/src/util.c delete mode 100644 roms/seabios/src/util.h delete mode 100644 roms/seabios/src/vgahooks.c delete mode 100644 roms/seabios/src/virtio-blk.c delete mode 100644 roms/seabios/src/virtio-blk.h delete mode 100644 roms/seabios/src/virtio-pci.c delete mode 100644 roms/seabios/src/virtio-pci.h delete mode 100644 roms/seabios/src/virtio-ring.c delete mode 100644 roms/seabios/src/virtio-ring.h delete mode 100644 roms/seabios/tools/buildrom.py delete mode 100644 roms/seabios/tools/checkrom.py delete mode 100644 roms/seabios/tools/checkstack.py delete mode 100644 roms/seabios/tools/checksum.py delete mode 100644 roms/seabios/tools/gen-offsets.sh delete mode 100644 roms/seabios/tools/layoutrom.py delete mode 100644 roms/seabios/tools/readserial.py delete mode 100644 roms/seabios/tools/test-gcc.sh delete mode 100644 roms/seabios/tools/transdump.py delete mode 100644 roms/seabios/vgasrc/clext.c delete mode 100644 roms/seabios/vgasrc/vga.c delete mode 100644 roms/seabios/vgasrc/vgaentry.S delete mode 100644 roms/seabios/vgasrc/vgafb.c delete mode 100644 roms/seabios/vgasrc/vgafonts.c delete mode 100644 roms/seabios/vgasrc/vgaio.c delete mode 100644 roms/seabios/vgasrc/vgalayout.lds.S delete mode 100644 roms/seabios/vgasrc/vgatables.c delete mode 100644 roms/seabios/vgasrc/vgatables.h delete mode 100644 roms/vgabios/.cvsignore delete mode 100644 roms/vgabios/BUGS delete mode 100644 roms/vgabios/COPYING delete mode 100644 roms/vgabios/ChangeLog delete mode 100644 roms/vgabios/Makefile delete mode 100644 roms/vgabios/Notes delete mode 100644 roms/vgabios/README delete mode 100644 roms/vgabios/TODO delete mode 100644 roms/vgabios/biossums.c delete mode 100644 roms/vgabios/clext.c delete mode 100644 roms/vgabios/dataseghack delete mode 100644 roms/vgabios/tests/lfbprof/Makefile delete mode 100644 roms/vgabios/tests/lfbprof/lfbprof.c delete mode 100644 roms/vgabios/tests/lfbprof/lfbprof.h delete mode 100644 roms/vgabios/tests/testbios.c delete mode 100644 roms/vgabios/vbe.c delete mode 100644 roms/vgabios/vbe.h delete mode 100644 roms/vgabios/vbe_display_api.txt delete mode 100644 roms/vgabios/vbetables-gen.c delete mode 100644 roms/vgabios/vgabios.c delete mode 100644 roms/vgabios/vgabios.h delete mode 100644 roms/vgabios/vgafonts.h delete mode 100644 roms/vgabios/vgatables.h delete mode 100644 rwhandler.c delete mode 100644 rwhandler.h mode change 100644 => 100755 scripts/checkpatch.pl mode change 100644 => 100755 scripts/create_config mode change 100644 => 100755 scripts/signrom.sh mode change 100644 => 100755 scripts/simpletrace.py mode change 100644 => 100755 scripts/texi2pod.pl mode change 100644 => 100755 scripts/tracetool delete mode 100644 sdb.c delete mode 100644 sdb.h delete mode 100644 simpletrace.c delete mode 100644 simpletrace.h delete mode 100644 target-alpha/exec.h delete mode 100644 target-arm/exec.h delete mode 100644 target-arm/helper_gpi_dummy.c delete mode 100644 target-arm/helpers.h delete mode 100644 target-arm/opengl_dummy.c delete mode 100644 target-cris/exec.h delete mode 100644 target-i386/exec.h delete mode 100644 target-i386/gl_func_perso.h delete mode 100644 target-i386/glgetv_cst.h delete mode 100644 target-i386/helper_gpi.c delete mode 100644 target-i386/helper_gpi.h delete mode 100644 target-i386/helper_gpi_test.c delete mode 100755 target-i386/helper_opengl.c delete mode 100644 target-i386/helper_opengl.h delete mode 100644 target-i386/kvm_x86.h delete mode 100644 target-i386/mesa_enums.c delete mode 100644 target-i386/mesa_get.c delete mode 100644 target-i386/mesa_gl.h delete mode 100644 target-i386/mesa_glext.h delete mode 100644 target-i386/mesa_glu.h delete mode 100644 target-i386/mesa_glx.h delete mode 100644 target-i386/mesa_glxext.h delete mode 100644 target-i386/mesa_mipmap.c delete mode 100644 target-i386/op_helper.c delete mode 100755 target-i386/opengl32.def delete mode 100755 target-i386/opengl_client.c delete mode 100644 target-i386/opengl_client_xfonts.c delete mode 100755 target-i386/opengl_exec.c delete mode 100644 target-i386/opengl_func.h delete mode 100644 target-i386/opengl_player.c delete mode 100755 target-i386/opengl_server.c delete mode 100644 target-i386/opengl_server.h delete mode 100644 target-i386/opengl_utils.h delete mode 100644 target-i386/parse_gl_h.c delete mode 100644 target-i386/parse_mesa_get_c.c delete mode 100644 target-m68k/exec.h delete mode 100644 target-microblaze/exec.h delete mode 100644 target-mips/exec.h delete mode 100644 target-ppc/exec.h delete mode 100644 target-s390x/exec.h delete mode 100644 target-sh4/exec.h delete mode 100644 target-sparc/exec.h delete mode 100644 tizen/AUTHOR delete mode 100644 tizen/COPYING delete mode 100644 tizen/Makefile.in delete mode 100644 tizen/NOTICE delete mode 100644 tizen/README delete mode 100755 tizen/configure.ac delete mode 100644 tizen/data/pc-bios/bios.bin delete mode 100644 tizen/data/pc-bios/linuxboot.bin delete mode 100644 tizen/data/pc-bios/pxe-rtl8139.bin delete mode 100644 tizen/data/pc-bios/pxe-virtio.bin delete mode 100644 tizen/data/pc-bios/vgabios-tizenvga.bin delete mode 100644 tizen/data/pc-bios/vgabios.bin delete mode 100644 tizen/data/sdcard_1024.img delete mode 100644 tizen/data/sdcard_1536.img delete mode 100644 tizen/data/sdcard_256.img delete mode 100644 tizen/data/sdcard_512.img delete mode 100644 tizen/distrib/ffmpeg/COPYING.GPLv2 delete mode 100644 tizen/distrib/ffmpeg/COPYING.GPLv3 delete mode 100644 tizen/distrib/ffmpeg/COPYING.LGPLv2.1 delete mode 100644 tizen/distrib/ffmpeg/COPYING.LGPLv3 delete mode 100644 tizen/distrib/ffmpeg/CREDITS delete mode 100644 tizen/distrib/ffmpeg/Changelog delete mode 100644 tizen/distrib/ffmpeg/Doxyfile delete mode 100644 tizen/distrib/ffmpeg/INSTALL delete mode 100644 tizen/distrib/ffmpeg/LICENSE delete mode 100644 tizen/distrib/ffmpeg/MAINTAINERS delete mode 100644 tizen/distrib/ffmpeg/Makefile delete mode 100644 tizen/distrib/ffmpeg/README delete mode 100644 tizen/distrib/ffmpeg/RELEASE delete mode 100644 tizen/distrib/ffmpeg/VERSION delete mode 100644 tizen/distrib/ffmpeg/cmdutils.c delete mode 100644 tizen/distrib/ffmpeg/cmdutils.h delete mode 100644 tizen/distrib/ffmpeg/cmdutils_common_opts.h delete mode 100644 tizen/distrib/ffmpeg/common.mak delete mode 100755 tizen/distrib/ffmpeg/configure delete mode 100644 tizen/distrib/ffmpeg/doc/APIchanges delete mode 100644 tizen/distrib/ffmpeg/doc/TODO delete mode 100644 tizen/distrib/ffmpeg/doc/avutil.txt delete mode 100644 tizen/distrib/ffmpeg/doc/developer.texi delete mode 100644 tizen/distrib/ffmpeg/doc/faq.texi delete mode 100644 tizen/distrib/ffmpeg/doc/ffmpeg-doc.texi delete mode 100644 tizen/distrib/ffmpeg/doc/ffmpeg_powerpc_performance_evaluation_howto.txt delete mode 100644 tizen/distrib/ffmpeg/doc/ffplay-doc.texi delete mode 100644 tizen/distrib/ffmpeg/doc/ffprobe-doc.texi delete mode 100644 tizen/distrib/ffmpeg/doc/ffserver-doc.texi delete mode 100644 tizen/distrib/ffmpeg/doc/ffserver.conf delete mode 100644 tizen/distrib/ffmpeg/doc/fftools-common-opts.texi delete mode 100644 tizen/distrib/ffmpeg/doc/general.texi delete mode 100644 tizen/distrib/ffmpeg/doc/issue_tracker.txt delete mode 100644 tizen/distrib/ffmpeg/doc/libavfilter.texi delete mode 100644 tizen/distrib/ffmpeg/doc/optimization.txt delete mode 100644 tizen/distrib/ffmpeg/doc/rate_distortion.txt delete mode 100644 tizen/distrib/ffmpeg/doc/snow.txt delete mode 100644 tizen/distrib/ffmpeg/doc/soc.txt delete mode 100644 tizen/distrib/ffmpeg/doc/swscale.txt delete mode 100644 tizen/distrib/ffmpeg/doc/tablegen.txt delete mode 100755 tizen/distrib/ffmpeg/doc/texi2pod.pl delete mode 100644 tizen/distrib/ffmpeg/doc/viterbi.txt delete mode 100644 tizen/distrib/ffmpeg/ffmpeg.c delete mode 100644 tizen/distrib/ffmpeg/ffplay.c delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-baseline.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-default.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-fast.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-fast_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-faster.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-faster_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-fastfirstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-hq.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-ipod320.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-ipod640.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-lossless_fast.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-lossless_max.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-lossless_medium.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slow.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slower.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-lossless_ultrafast.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-main.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-max.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-medium.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-medium_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-normal.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-placebo.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-placebo_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-slow.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-slow_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-slower.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-slower_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-slowfirstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-superfast.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-superfast_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-veryfast.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-veryfast_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-veryslow.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffpresets/libx264-veryslow_firstpass.ffpreset delete mode 100644 tizen/distrib/ffmpeg/ffprobe.c delete mode 100644 tizen/distrib/ffmpeg/ffserver.c delete mode 100644 tizen/distrib/ffmpeg/ffserver.h delete mode 100644 tizen/distrib/ffmpeg/include/libavcodec/avcodec.h delete mode 100644 tizen/distrib/ffmpeg/include/libavcodec/avfft.h delete mode 100644 tizen/distrib/ffmpeg/include/libavcodec/dxva2.h delete mode 100644 tizen/distrib/ffmpeg/include/libavcodec/opt.h delete mode 100644 tizen/distrib/ffmpeg/include/libavcodec/vaapi.h delete mode 100644 tizen/distrib/ffmpeg/include/libavcodec/vdpau.h delete mode 100644 tizen/distrib/ffmpeg/include/libavcodec/xvmc.h delete mode 100644 tizen/distrib/ffmpeg/include/libavdevice/avdevice.h delete mode 100644 tizen/distrib/ffmpeg/include/libavfilter/avfilter.h delete mode 100644 tizen/distrib/ffmpeg/include/libavformat/avformat.h delete mode 100644 tizen/distrib/ffmpeg/include/libavformat/avio.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/adler32.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/attributes.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/avconfig.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/avstring.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/avutil.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/base64.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/common.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/crc.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/error.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/fifo.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/intfloat_readwrite.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/log.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/lzo.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/mathematics.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/md5.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/mem.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/pixdesc.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/pixfmt.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/rational.h delete mode 100644 tizen/distrib/ffmpeg/include/libavutil/sha1.h delete mode 100644 tizen/distrib/ffmpeg/include/libswscale/swscale.h delete mode 100644 tizen/distrib/ffmpeg/lib/libavcodec.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavcodec.dll.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavdevice.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavdevice.dll.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavfilter.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavformat.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavformat.dll.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavutil.a delete mode 100644 tizen/distrib/ffmpeg/lib/libavutil.dll.a delete mode 100644 tizen/distrib/ffmpeg/lib/libswscale.a delete mode 100644 tizen/distrib/ffmpeg/lib/pkgconfig/libavcodec.pc delete mode 100644 tizen/distrib/ffmpeg/lib/pkgconfig/libavdevice.pc delete mode 100644 tizen/distrib/ffmpeg/lib/pkgconfig/libavfilter.pc delete mode 100644 tizen/distrib/ffmpeg/lib/pkgconfig/libavformat.pc delete mode 100644 tizen/distrib/ffmpeg/lib/pkgconfig/libavutil.pc delete mode 100644 tizen/distrib/ffmpeg/lib/pkgconfig/libswscale.pc delete mode 100644 tizen/distrib/ffmpeg/libavcodec/4xm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/8bps.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/8svx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aac.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aac_adtstoasc_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aac_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aac_parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aaccoder.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacdectab.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacenc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacpsy.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacpsy.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacsbr.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacsbr.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aacsbrdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aactab.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aactab.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aandcttab.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aandcttab.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aasc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3_parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3dec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3dec_data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3dec_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3tab.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ac3tab.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/acelp_filters.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/acelp_filters.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/acelp_vectors.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/acelp_vectors.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/adpcm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/adx.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/adxdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/adxenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alacenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/allcodecs.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/asm.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_mvi_asm.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/regdef.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/alsdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/amrnbdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/amrnbdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/anm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/apedec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/api-example.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/aac.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/asm.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_init_arm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_armv6.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_arm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv5te.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv6.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_neon.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_vfp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt_rnd_template.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/dsputil_vfp.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/fft_init_arm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/fft_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_init_arm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/h264idct_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/h264pred_init_arm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/h264pred_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/int_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/jrevdct_arm.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/mathops.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/mdct_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te_s.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_iwmmxt.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/rdft_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_arm.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv5te.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv6.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/synth_filter_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/vp3dsp_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_init_arm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_neon.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/asv1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/atrac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/atrac.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/atrac1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/atrac1data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/atrac3.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/atrac3data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/audioconvert.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/audioconvert.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/aura.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/avcodec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/avfft.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/avfft.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/avpacket.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/avr32/mathops.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/avs.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/beosthread.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfi.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/config_bfin.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/fdct_bfin.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/idct_bfin.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/mathops.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/mpegvideo_bfin.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/pixels_bfin.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/vp3_bfin.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bgmc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bgmc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bink.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/binkaudio.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/binkdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/binkidct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bitstream.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bitstream_filter.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bmp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bmp.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bmpenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/bytestream.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/c93.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cabac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cabac.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cavs.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cavs.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cavs_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cavsdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cavsdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cavsdsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cdgraphics.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/celp_filters.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/celp_filters.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/celp_math.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/celp_math.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cga_data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cga_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cinepak.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cljr.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/colorspace.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cook.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cookdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/costablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cscd.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/cyuv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dca.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dca.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dca_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dcadata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dcadsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dcadsp.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dcahuff.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dct-test.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dctref.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dctref.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dirac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dirac.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dirac_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dnxhd_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dnxhddata.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dnxhddata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dnxhddec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dnxhdenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dnxhdenc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dpcm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dpx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dsicinav.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dsputil.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dsputil.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dump_extradata_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dv_tablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dv_tablegen.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dv_vlc_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvbsub.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvbsub_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvbsubdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvdata.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvdsub_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvdsubdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dvdsubenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dwt.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dwt.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dxa.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dxva2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dxva2.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dxva2_h264.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dxva2_internal.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/dxva2_vc1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eac3dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eac3dec_data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eac3dec_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eacmv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eaidct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eamad.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eatgq.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eatgv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eatqi.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/elbg.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/elbg.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/error_resilience.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/escape124.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eval.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/eval.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/faandct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/faandct.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/faanidct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/faanidct.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/faxcompr.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/faxcompr.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/fft-test.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/fft.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/fft.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ffv1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flac.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flacdata.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flacdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flacdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flacenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flashsv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flashsvenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flicvideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flv.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flvdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/flvenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/fraps.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/frwu.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/g726.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/g729.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/g729data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/g729dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/get_bits.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/gif.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/gifdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/golomb.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/golomb.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h261.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h261.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h261_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h261data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h261dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h261enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h263.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h263.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h263_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h263_parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h263data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h263dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_cabac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_cavlc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_direct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_loopfilter.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_mvpred.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_ps.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_refs.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264_sei.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264dsp.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264dspenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264idct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264pred.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/h264pred.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/huffman.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/huffman.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/huffyuv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/idcinvideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/iff.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/iff.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/iirfilter.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/iirfilter.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/imc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/imcdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/imgconvert.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/imgconvert.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/imx_dump_header_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/indeo2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/indeo2data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/indeo3.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/indeo3data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/indeo5.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/indeo5data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/intelh263dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/internal.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/interplayvideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/intrax8.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/intrax8.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/intrax8dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/intrax8huf.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ituh263dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ituh263enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ivi_common.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ivi_common.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ivi_dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ivi_dsp.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jfdctfst.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jfdctint.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jpegls.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jpegls.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jpeglsdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jpeglsdec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jpeglsenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/jrevdct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/kgv1dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/kmvc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lcl.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lcldec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lclenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libavcodec.v delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libdirac.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libdiracdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libdiracenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libfaac.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libfaad.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libgsm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libmp3lame.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libopencore-amr.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libopenjpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libschroedinger.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libschroedinger.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libschroedingerdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libschroedingerenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libspeexdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libtheoraenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libvorbis.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libvpxdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libvpxenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libx264.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libxvid_internal.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libxvid_rc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/libxvidff.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ljpegenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/loco.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lpc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lpc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lsp.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lzw.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lzw.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/lzwenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mace.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mathops.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mdct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mimic.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mips/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mips/mathops.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpeg.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpeg_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpega_dump_header_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpegbdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpegdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpegdec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpegenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mjpegenc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mlp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mlp.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mlp_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mlp_parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mlpdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mlpdsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mmvideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/motion-test.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/motion_est.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/motion_est_template.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/motionpixels.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/movsub_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mp3_header_compress_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mp3_header_decompress_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpc7.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpc7data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpc8.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpc8data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpc8huff.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpcdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg12.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg12.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg12data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg12data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg12decdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg12enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4audio.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4audio.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4video.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4video.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4videodec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpeg4videoenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudio.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudio.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudio3.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudio_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudiodec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudiodectab.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudioenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegaudiotab.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegvideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegvideo.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegvideo_common.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegvideo_enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegvideo_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/mpegvideo_xvmc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msmpeg4.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msmpeg4.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msmpeg4data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msmpeg4data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msrle.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msrledec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msrledec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/msvideo1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/nellymoser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/nellymoser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/nellymoserdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/nellymoserenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/noise_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/nuv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/opt.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/opt.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/options.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/os2thread.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pamenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/parser.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pcm-mpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pcm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pcx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pcxenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pgssubdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/png.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/png.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pngdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pngenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pnm.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pnm.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pnm_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pnmdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pnmenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/check_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/fdct_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/fft_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/float_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/gmc_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/h264_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/idct_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/int_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/mathops.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/types_altivec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/util_altivec.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ps2/idct_mmi.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ps2/mmi.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/psymodel.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/psymodel.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/pthread.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ptx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/put_bits.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qcelpdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qcelpdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qdm2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qdm2data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qdrw.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qtrle.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/qtrleenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/r210dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ra144.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ra144.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ra288.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ra288.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rangecoder.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rangecoder.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ratecontrol.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ratecontrol.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/raw.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/raw.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rawdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rawenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rdft.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rectangle.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/remove_extradata_bsf.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/resample.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/resample2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rl.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rl2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rle.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rle.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/roqaudioenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/roqvideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/roqvideo.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/roqvideodec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/roqvideoenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rpza.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rtjpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rtjpeg.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv10.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv10enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv20enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv30.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv30data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv30dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv34.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv34.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv34data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv34vlc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv40.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv40data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv40dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/rv40vlc2.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/s3tc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/s3tc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sbr.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sgi.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sgidec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sgienc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sh4/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_align.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sh4/idct_sh4.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sh4/qpel.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sh4/sh4.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/shorten.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/simple_idct.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/simple_idct.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sipr.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sipr.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sipr16k.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sipr16kdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/siprdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/smacker.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/smc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/snow.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/snow.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sonic.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sp5x.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sp5xdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sparc/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sparc/simple_idct_vis.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sparc/vis.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/sunrast.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq1.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq1_cb.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq1_vlc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq1dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq1enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq1enc_cb.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/svq3.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/synth_filter.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/synth_filter.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tableprint.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tableprint.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/targa.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/targaenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tiertexseqv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tiff.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tiff.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tiffenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tmv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/truemotion1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/truemotion1data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/truemotion2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/truespeech.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/truespeech_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tscc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/tta.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/twinvq.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/twinvq_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/txd.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ulti.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ulti_cb.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/unary.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/utils.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/v210dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/v210enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/v210x.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vaapi.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vaapi.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vaapi_h264.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vaapi_internal.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg4.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vaapi_vc1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vb.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1acdata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vc1dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vcr1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vdpau.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vdpau.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vdpau_internal.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vmdav.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vmnc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vorbis.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vorbis.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vorbis_data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vorbis_dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vorbis_enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vorbis_enc_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp3.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp3_parser.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp3data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp3dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp5.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp56.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp56.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp56data.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp56data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp56dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp56dsp.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp5data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp6.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp6data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vp6dsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/vqavideo.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/w32thread.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wavpack.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wma.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wma.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmadata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmadec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmaenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmaprodata.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmaprodec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmavoice.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmavoice_data.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmv2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmv2.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmv2dec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wmv2enc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/wnv1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/ws-snd1.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/cavsdsp_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/cpuid.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dnxhd_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_ssse3.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_avg_template.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_qns_template.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_rnd_template.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputil_yasm.asm delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/dsputilenc_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/fdct_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/fft.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/fft.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/fft_mmx.asm delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/fft_sse.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/h264_deblock_sse2.asm delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/h264_i386.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/h264_idct_sse2.asm delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/h264dsp_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/idct_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/idct_mmx_xvid.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/idct_sse2_xvid.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/idct_xvid.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/lpc_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/mathops.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/mlpdsp.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/mmx.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/motion_est_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx_template.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/rv40dsp_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/simple_idct_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/snowdsp_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vc1dsp_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/x86inc.asm delete mode 100644 tizen/distrib/ffmpeg/libavcodec/x86/x86util.asm delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xan.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xiph.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xiph.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xl.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xsubdec.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xsubenc.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xvmc.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/xvmc_internal.h delete mode 100644 tizen/distrib/ffmpeg/libavcodec/yop.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/zmbv.c delete mode 100644 tizen/distrib/ffmpeg/libavcodec/zmbvenc.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavdevice/alldevices.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/alsa-audio-common.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/alsa-audio-dec.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/alsa-audio-enc.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/alsa-audio.h delete mode 100644 tizen/distrib/ffmpeg/libavdevice/avdevice.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/avdevice.h delete mode 100644 tizen/distrib/ffmpeg/libavdevice/beosaudio.cpp delete mode 100644 tizen/distrib/ffmpeg/libavdevice/bktr.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/dv1394.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/dv1394.h delete mode 100644 tizen/distrib/ffmpeg/libavdevice/jack_audio.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/libavdevice.v delete mode 100644 tizen/distrib/ffmpeg/libavdevice/libdc1394.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/oss_audio.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/v4l.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/v4l2.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/vfwcap.c delete mode 100644 tizen/distrib/ffmpeg/libavdevice/x11grab.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavfilter/allfilters.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/avfilter.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/avfilter.h delete mode 100644 tizen/distrib/ffmpeg/libavfilter/avfiltergraph.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/avfiltergraph.h delete mode 100644 tizen/distrib/ffmpeg/libavfilter/defaults.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/formats.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/graphparser.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/graphparser.h delete mode 100644 tizen/distrib/ffmpeg/libavfilter/libavfilter.v delete mode 100644 tizen/distrib/ffmpeg/libavfilter/parseutils.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/parseutils.h delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_aspect.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_crop.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_format.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_null.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_scale.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_slicify.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_unsharp.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vf_vflip.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vsink_nullsink.c delete mode 100644 tizen/distrib/ffmpeg/libavfilter/vsrc_nullsrc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/4xm.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavformat/adts.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/adtsenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/aea.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/aiff.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/aiffdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/aiffenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/allformats.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/amr.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/anm.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/apc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/ape.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/apetag.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/apetag.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/asf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/asf.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/asfcrypt.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/asfcrypt.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/asfdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/asfenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/assdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/assenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/au.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/audiointerleave.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/audiointerleave.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/avc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avc.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/avformat.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/avi.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avi.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/avidec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avienc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avio.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avio.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/aviobuf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avisynth.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avlanguage.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/avlanguage.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/avs.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/bethsoftvid.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/bfi.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/bink.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/c93.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/caf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/caf.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/cafdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/cdg.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/concat.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/crcenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/cutils.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/daud.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/dsicin.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/dv.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/dv.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/dvenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/dxa.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/eacdata.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/electronicarts.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/ffm.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/ffmdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/ffmenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/file.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/filmstripdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/filmstripenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/flacdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/flacenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/flacenc.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/flacenc_header.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/flic.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/flv.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/flvdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/flvenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/framecrcenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/gif.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/gopher.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/gxf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/gxf.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/gxfenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/http.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/httpauth.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/httpauth.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/id3v1.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/id3v1.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/id3v2.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/id3v2.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/idcin.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/idroq.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/iff.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/img2.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/internal.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/ipmovie.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/isom.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/isom.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/iss.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/iv8.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/libavformat.v delete mode 100644 tizen/distrib/ffmpeg/libavformat/libnut.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/librtmp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/lmlm4.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/matroska.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/matroska.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/matroskadec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/matroskaenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/metadata.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/metadata.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/metadata_compat.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mm.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mmf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mov.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/movenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/movenc.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/movenchint.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mp3.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpc8.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpeg.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpegenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpegts.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpegts.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpegtsenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mpjpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/msnwc_tcp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mtv.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mvi.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mxf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mxf.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/mxfdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/mxfenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/ncdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/network.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/nsvdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/nut.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/nut.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/nutdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/nutenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/nuv.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggdec.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggparsedirac.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggparseflac.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggparseogm.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggparseskeleton.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggparsespeex.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggparsetheora.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oggparsevorbis.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/oma.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/options.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/os_support.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/os_support.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/output-example.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/psxstr.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/pva.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/qcp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/qtpalette.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/r3d.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/raw.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/raw.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rdt.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rdt.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/riff.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/riff.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rl2.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rm.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rm.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rmdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rmenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rpl.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtmp.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtmppkt.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtmppkt.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtmpproto.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtp.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_amr.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_amr.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_asf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_asf.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_h263.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_h263.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_h264.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_h264.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpenc.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpenc_aac.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpenc_amr.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpenc_h263.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpenc_h264.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpenc_mpv.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtpproto.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtsp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtsp.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtspcodes.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/rtspenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/sdp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/seek.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/seek.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/segafilm.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/sierravmd.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/siff.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/smacker.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/sol.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/sox.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/soxdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/soxenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/spdif.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/swf.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/swfdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/swfenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/tcp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/thp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/tiertexseq.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/timefilter.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/timefilter.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/tmv.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/tta.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/txd.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/udp.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/utils.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/vc1test.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/vc1testenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/voc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/voc.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/vocdec.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/vocenc.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/vorbiscomment.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/vorbiscomment.h delete mode 100644 tizen/distrib/ffmpeg/libavformat/vqf.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/wav.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/wc3movie.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/westwood.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/wv.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/xa.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/yop.c delete mode 100644 tizen/distrib/ffmpeg/libavformat/yuv4mpeg.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/Makefile delete mode 100644 tizen/distrib/ffmpeg/libavutil/adler32.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/adler32.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/aes.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/aes.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/arm/bswap.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/arm/intmath.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/arm/intreadwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/arm/timer.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/attributes.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/avr32/bswap.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/avr32/intreadwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/avstring.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/avstring.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/avutil.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/base64.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/base64.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/bfin/bswap.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/bfin/timer.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/bswap.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/common.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/crc.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/crc.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/crc_data.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/des.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/des.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/error.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/error.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/fifo.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/fifo.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/integer.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/integer.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/internal.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/intmath.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/intreadwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/lfg.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/lfg.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/libavutil.v delete mode 100644 tizen/distrib/ffmpeg/libavutil/libm.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/lls.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/lls.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/log.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/log.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/lzo.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/lzo.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/mathematics.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/mathematics.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/md5.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/md5.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/mem.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/mem.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/mips/intreadwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/pca.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/pca.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/pixdesc.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/pixdesc.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/pixfmt.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/ppc/intreadwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/ppc/timer.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/random_seed.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/random_seed.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/rational.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/rational.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/rc4.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/rc4.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/sh4/bswap.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/sha.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/sha.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/sha1.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/softfloat.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/softfloat.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/timer.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/tomi/intreadwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/tree.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/tree.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/utils.c delete mode 100644 tizen/distrib/ffmpeg/libavutil/x86/bswap.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/x86/intmath.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/x86/intreadwrite.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/x86/timer.h delete mode 100644 tizen/distrib/ffmpeg/libavutil/x86_cpu.h delete mode 100644 tizen/distrib/ffmpeg/libpostproc/Makefile delete mode 100644 tizen/distrib/ffmpeg/libpostproc/libpostproc.v delete mode 100644 tizen/distrib/ffmpeg/libpostproc/postprocess.c delete mode 100644 tizen/distrib/ffmpeg/libpostproc/postprocess.h delete mode 100644 tizen/distrib/ffmpeg/libpostproc/postprocess_altivec_template.c delete mode 100644 tizen/distrib/ffmpeg/libpostproc/postprocess_internal.h delete mode 100644 tizen/distrib/ffmpeg/libpostproc/postprocess_template.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/Makefile delete mode 100644 tizen/distrib/ffmpeg/libswscale/bfin/internal_bfin.S delete mode 100644 tizen/distrib/ffmpeg/libswscale/bfin/swscale_bfin.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/bfin/yuv2rgb_bfin.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/colorspace-test.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/libswscale.v delete mode 100644 tizen/distrib/ffmpeg/libswscale/mlib/yuv2rgb_mlib.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/options.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/ppc/swscale_altivec_template.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/ppc/yuv2rgb_altivec.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/rgb2rgb.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/rgb2rgb.h delete mode 100644 tizen/distrib/ffmpeg/libswscale/rgb2rgb_template.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/sparc/yuv2rgb_vis.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/swscale-test.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/swscale.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/swscale.h delete mode 100644 tizen/distrib/ffmpeg/libswscale/swscale_internal.h delete mode 100644 tizen/distrib/ffmpeg/libswscale/swscale_template.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/utils.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/x86/yuv2rgb_mmx.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/x86/yuv2rgb_template.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/x86/yuv2rgb_template2.c delete mode 100644 tizen/distrib/ffmpeg/libswscale/yuv2rgb.c delete mode 100644 tizen/distrib/ffmpeg/subdir.mak delete mode 100644 tizen/distrib/ffmpeg/tests/audiogen.c delete mode 100755 tizen/distrib/ffmpeg/tests/codec-regression.sh delete mode 100644 tizen/distrib/ffmpeg/tests/copy.regression.ref delete mode 100755 tizen/distrib/ffmpeg/tests/copycooker.sh delete mode 100755 tizen/distrib/ffmpeg/tests/fate-run.sh delete mode 100755 tizen/distrib/ffmpeg/tests/fate-update.sh delete mode 100644 tizen/distrib/ffmpeg/tests/fate.mak delete mode 100755 tizen/distrib/ffmpeg/tests/ffserver-regression.sh delete mode 100644 tizen/distrib/ffmpeg/tests/ffserver.conf delete mode 100644 tizen/distrib/ffmpeg/tests/ffserver.regression.ref delete mode 100755 tizen/distrib/ffmpeg/tests/lavf-regression.sh delete mode 100755 tizen/distrib/ffmpeg/tests/lavfi-regression.sh delete mode 100644 tizen/distrib/ffmpeg/tests/lena.pnm delete mode 100644 tizen/distrib/ffmpeg/tests/md5.sh delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/ac3 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_ima_qt delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_ima_wav delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_ms delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_swf delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/adpcm_yam delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/alac delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/flac delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/g726 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/mp2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/pcm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/wmav1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/acodec/wmav2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/4xm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/8bps delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/aac-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/aasc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/adpcm-ea-r2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/adpcm-ea-r3 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/aea-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/alg-mm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/amv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/armovie-escape124 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/auravision delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/auravision-v2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/bethsoft-vid delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/bfi delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/bink-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/bink-demux-video delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/caf delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cdgraphics delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cljr delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/corepng delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/creative-adpcm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/creative-adpcm-8-2.6bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/creative-adpcm-8-2bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/creative-adpcm-8-4bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/creatureshock-avs delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cryo-apc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cscd delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cvid delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cvid-palette delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cyberia-c93 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/cyuv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/d-cinema-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/delphine-cin delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/deluxepaint-anm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/dpx delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/duck-dk3 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/duck-dk4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/duck-tm2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-cdata delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-cmv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-dct delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-mad-adpcm-ea-r1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-mad-pcm-planar delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-tgq delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-tgv-ima-ea-eacs delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-tgv-ima-ea-sead delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-tqi-adpcm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-vp60 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ea-vp61 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/feeble-dxa delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/film-cvid-pcm-stereo-8bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/flic-af11-palette-change delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/flic-af12 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/flic-magiccarpet delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/fraps-v0 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/fraps-v1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/fraps-v2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/fraps-v3 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/fraps-v4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/fraps-v5 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/frwu delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/funcom-iss delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-aud_mw_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ba1_ft_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ba1_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ba2_sony_f delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ba3_sva_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ba_mw_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-bamq1_jvc_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-bamq2_jvc_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-banm_mw_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-basqp1_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caba1_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caba1_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caba2_sony_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caba2_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caba3_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caba3_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caba3_toshiba_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabac_mot_fld0_full delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabac_mot_frm0_full delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabac_mot_mbaff0_full delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabaci3_sony_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabast3_sony_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabastbr3_sony_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cabref3_sand_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cacqp3_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cafi1_sva_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cama1_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cama1_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cama1_vtc_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cama2_vtc_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cama3_sand_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cama3_vtc_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-camaci3_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-camanl1_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-camanl2_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-camanl3_sand_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-camasl3_sony_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-camp_mot_mbaff_l30 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-camp_mot_mbaff_l31 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl1_sony_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl1_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl1_toshiba_g delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl2_sony_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl2_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl3_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl3_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canl4_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canlma2_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-canlma3_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-capa1_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-capama3_sand_f delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-capcm1_sand_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-capcmnl1_sand_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-capm3_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-caqp1_sony_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cavlc_mot_frm0_full_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cavlc_mot_mbaff0_full_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cawp1_toshiba_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cawp5_toshiba_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ci1_ft_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ci_mw_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvbs3_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvcanlma2_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvfi1_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvfi1_sva_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvfi2_sony_h delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvfi2_sva_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvma1_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvma1_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvmanl1_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvmanl2_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvmaqp2_sony_g delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvmaqp3_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvnlfi1_sony_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvnlfi2_sony_h delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvpa1_toshiba_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvpcmnl1_sva_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvpcmnl2_sva_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvwp1_toshiba_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvwp2_toshiba_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvwp3_toshiba_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-cvwp5_toshiba_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-fi1_sony_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-alphaconformanceg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-bcrm_freh10 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-brcm_freh11 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-brcm_freh3 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-brcm_freh4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-brcm_freh5 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-brcm_freh8 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-brcm_freh9 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-freh12_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-freh1_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-freh2_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-freh6 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-freh7_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-frext01_jvc_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-frext02_jvc_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-frext1_panasonic_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-frext3_panasonic_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-frext_mmco4_sony_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hcafr1_hhi_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hcafr2_hhi_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hcafr3_hhi_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hcafr4_hhi_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hcamff1_hhi_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpca_brcm_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcadq_brcm_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcalq_brcm_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcanl_brcm_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcaq2lq_brcm_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcv_brcm_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-frext-hpcvnl_brcm_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-hcbp2_hhi_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-hcmp1_hhi_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-ls_sva_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-midr_mw_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mps_mw_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr1_bt_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr1_mw_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr2_mw_a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr2_tandberg_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr3_tandberg_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr4_tandberg_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr5_tandberg_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr6_bt_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr7_bt_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr8_bt_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mr9_bt_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-mv1_brcm_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-nl1_sony_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-nl2_sony_h delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-nl3_sva_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-nlmq1_jvc_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-nlmq2_jvc_c delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-nrf_mw_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sharp_mp_field_1_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sharp_mp_field_2_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sharp_mp_field_3_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sharp_mp_paff_2r delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sl1_sva_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sva_ba1_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sva_ba2_d delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sva_base_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sva_cl1_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sva_fm1_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sva_nl1_b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/h264-conformance-sva_nl2_e delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/id-cin-video delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/idroq-video-dpcm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/idroq-video-encode delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/iff-byterun1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/iff-fibonacci delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/iff-ilbm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/iff-pcm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/indeo2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/indeo3 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/indeo5 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/interplay-mve-16bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/interplay-mve-8bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/iv8-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/kmvc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/lmlm4-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/loco-rgb delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/loco-yuy2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/lossless-appleaudio delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/lossless-meridianaudio delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/lossless-monkeysaudio delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/lossless-shortenaudio delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/lossless-tta delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/lossless-wavpackaudio delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/maxis-xa delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mimic delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/motionpixels delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpc7-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpc8-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpeg4-als-conformance-00 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpeg4-als-conformance-01 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpeg4-als-conformance-02 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpeg4-als-conformance-03 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpeg4-als-conformance-04 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mpeg4-als-conformance-05 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/msrle-8bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/msvideo1-16bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/msvideo1-8bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mszh delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mtv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/mxf-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/nc-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/nsv-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/nuv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/oma-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/pcm_dvd delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/psx-str delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ptx delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/pva-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qcp-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-alaw-mono delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-alaw-stereo delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-ima4-mono delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-ima4-stereo delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-mac3-mono delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-mac3-stereo delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-mac6-mono delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-mac6-stereo delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-msadpcm-stereo delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-msimaadpcm-stereo delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-rawpcm-16bit-stereo-signed-be delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-rawpcm-16bit-stereo-signed-le delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-rawpcm-8bit-mono-unsigned delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-rawpcm-8bit-stereo-unsigned delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-ulaw-mono delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qt-ulaw-stereo delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qtrle-16bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qtrle-1bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qtrle-24bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qtrle-2bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qtrle-32bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qtrle-4bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/qtrle-8bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/quickdraw delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/real-14_4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/real-rv40 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/redcode-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/rl2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/rpza delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sierra-audio delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sierra-vmd delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/siff delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/smacker delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/smc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sp5x delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sunraster-1bit-raw delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sunraster-1bit-rle delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sunraster-24bit-raw delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sunraster-24bit-rle delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sunraster-8bit-raw delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/sunraster-8bit-rle delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/svq1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/svq3 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/thp-mjpeg-adpcm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/tiertex-seq delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/tmv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/tscc-15bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/tscc-32bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/ulti delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/v210 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vc1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vcr1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/video-xl delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vmnc-16bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vmnc-32bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vp5 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vp6a delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vp6f delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vqa-cc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/vqf-demux delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/w64 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/wc3movie-xan delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/westwood-aud delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/wnv1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/xan-dpcm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/zlib delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/zmbv-15bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/zmbv-16bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/zmbv-32bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/fate/zmbv-8bit delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/aiff delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/alaw delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/asf delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/au delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/avi delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/bmp delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/dv_fmt delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/ffm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/flv_fmt delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/gif delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/gxf delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/jpg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/mkv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/mmf delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/mov delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/mpg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/mulaw delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/mxf delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/nut delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/ogg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/pbmpipe delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/pcx delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/pgm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/pgmpipe delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/pixfmt delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/ppm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/ppmpipe delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/rm delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/sgi delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/swf delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/tga delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/tiff delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/ts delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/voc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/wav delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavf/yuv4mpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/crop delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/crop_scale delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/crop_scale_vflip delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/crop_vflip delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/null delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/scale200 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/scale500 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/vflip delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/vflip_crop delete mode 100644 tizen/distrib/ffmpeg/tests/ref/lavfi/vflip_vflip delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.bmp.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.jpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.pcx.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.pgm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.ppm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.sgi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.tga.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/%02d.tiff.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/ac3.rm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/adpcm_ima.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/adpcm_ms.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/adpcm_qt.aiff.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/adpcm_swf.flv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/adpcm_yam.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/alac.m4a.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/asv1.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/asv2.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/dnxhd-1080i.mov.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/dnxhd-720p-rd.dnxhd.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/dnxhd-720p.dnxhd.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/dv.dv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/dv411.dv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/dv50.dv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/error-mpeg4-adv.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/ffv1.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/flac.flac.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/flashsv.flv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/flv.flv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/g726.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/h261.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/h263.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/h263p.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/huffyuv.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/jpegls.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.aif.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.al.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.asf.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.au.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.dv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.ffm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.flv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.gif.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.gxf.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.mkv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.mmf.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.mov.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.mxf.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.mxf_d10.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.nut.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.ogg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.rm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.swf.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.ts.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.ul.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.voc.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/lavf.y4m.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/ljpeg.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mjpeg.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mp2.mp2.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg1.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg1b.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg2.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg2_422.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg2i.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg2ivlc-qprd.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg2reuse.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg2thread.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg2threadivlc.mpg.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg4-Q.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg4-adap.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg4-adv.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg4-nr.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg4-qprd.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg4-rc.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/mpeg4-thread.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/msmpeg4.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/msmpeg4v2.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/odivx.mp4.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pbmpipe.pbm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_alaw.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_f32be.au.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_f32le.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_f64be.au.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_f64le.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_mulaw.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s16be.mkv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s16be.mov.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s16le.mkv.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s16le.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s24be.mov.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s24daud.302.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s24le.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s32be.mov.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s32le.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_s8.mov.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_u8.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pcm_zork.wav.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/pgmpipe.pgm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/ppmpipe.ppm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/roqav.roq.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/rv10.rm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/rv20.rm.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/snow.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/snow53.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/svq1.mov.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/wmav1.asf.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/wmav2.asf.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/wmv1.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/seek/wmv2.avi.ref delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/asv1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/asv2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/dnxhd_1080i delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/dnxhd_720p delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/dnxhd_720p_rd delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/dv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/dv50 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/error delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/ffv1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/flashsv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/flv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/h261 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/h263 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/h263p delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/huffyuv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/jpegls delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/ljpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mjpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg1b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg2thread delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4adv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4nr delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/mpeg4thread delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/msmpeg4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/msmpeg4v2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/rc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/roq delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/rv10 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/rv20 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/snow delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/snowll delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/svq1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/wmv1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth1/wmv2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/asv1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/asv2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/dnxhd_1080i delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/dnxhd_720p delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/dnxhd_720p_rd delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/dv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/dv50 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/error delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/ffv1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/flashsv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/flv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/h261 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/h263 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/h263p delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/huffyuv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/jpegls delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/ljpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mjpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg1b delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg2thread delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4adv delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4nr delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/mpeg4thread delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/msmpeg4 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/msmpeg4v2 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/rc delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/roq delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/rv10 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/rv20 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/snow delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/snowll delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/svq1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/wmv1 delete mode 100644 tizen/distrib/ffmpeg/tests/ref/vsynth2/wmv2 delete mode 100755 tizen/distrib/ffmpeg/tests/regression-funcs.sh delete mode 100644 tizen/distrib/ffmpeg/tests/rotozoom.c delete mode 100755 tizen/distrib/ffmpeg/tests/seek-regression.sh delete mode 100644 tizen/distrib/ffmpeg/tests/seek_test.c delete mode 100644 tizen/distrib/ffmpeg/tests/tiny_psnr.c delete mode 100644 tizen/distrib/ffmpeg/tests/videogen.c delete mode 100755 tizen/distrib/ffmpeg/tizen_configure delete mode 100755 tizen/distrib/ffmpeg/tools/build_avopt delete mode 100755 tizen/distrib/ffmpeg/tools/clean-diff delete mode 100644 tizen/distrib/ffmpeg/tools/cws2fws.c delete mode 100644 tizen/distrib/ffmpeg/tools/graph2dot.c delete mode 100755 tizen/distrib/ffmpeg/tools/patcheck delete mode 100644 tizen/distrib/ffmpeg/tools/pktdumper.c delete mode 100644 tizen/distrib/ffmpeg/tools/probetest.c delete mode 100644 tizen/distrib/ffmpeg/tools/qt-faststart.c delete mode 100644 tizen/distrib/ffmpeg/tools/trasher.c delete mode 100755 tizen/distrib/ffmpeg/tools/unwrap-diff delete mode 100755 tizen/distrib/ffmpeg/version.sh delete mode 100644 tizen/skins/emul_320x480/default.dbi delete mode 100644 tizen/skins/emul_320x480/default.png delete mode 100644 tizen/skins/emul_320x480/default_180.png delete mode 100644 tizen/skins/emul_320x480/default_180_p.png delete mode 100644 tizen/skins/emul_320x480/default_p.png delete mode 100644 tizen/skins/emul_320x480/default_w.png delete mode 100644 tizen/skins/emul_320x480/default_w90.png delete mode 100644 tizen/skins/emul_320x480/default_w90_p.png delete mode 100644 tizen/skins/emul_320x480/default_w_p.png delete mode 100644 tizen/skins/emul_3keys_320x480/default.dbi delete mode 100644 tizen/skins/emul_3keys_320x480/default.png delete mode 100644 tizen/skins/emul_3keys_320x480/default_180.png delete mode 100644 tizen/skins/emul_3keys_320x480/default_180_p.png delete mode 100644 tizen/skins/emul_3keys_320x480/default_p.png delete mode 100644 tizen/skins/emul_3keys_320x480/default_w.png delete mode 100644 tizen/skins/emul_3keys_320x480/default_w90.png delete mode 100644 tizen/skins/emul_3keys_320x480/default_w90_p.png delete mode 100644 tizen/skins/emul_3keys_320x480/default_w_p.png delete mode 100644 tizen/skins/emul_3keys_480x800/default.dbi delete mode 100644 tizen/skins/emul_3keys_480x800/default.png delete mode 100644 tizen/skins/emul_3keys_480x800/default_180.png delete mode 100644 tizen/skins/emul_3keys_480x800/default_180_p.png delete mode 100644 tizen/skins/emul_3keys_480x800/default_p.png delete mode 100644 tizen/skins/emul_3keys_480x800/default_w.png delete mode 100644 tizen/skins/emul_3keys_480x800/default_w90.png delete mode 100644 tizen/skins/emul_3keys_480x800/default_w90_p.png delete mode 100644 tizen/skins/emul_3keys_480x800/default_w_p.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default.dbi delete mode 100644 tizen/skins/emul_3keys_600x1024/default.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default_180.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default_180_p.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default_p.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default_w.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default_w90.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default_w90_p.png delete mode 100644 tizen/skins/emul_3keys_600x1024/default_w_p.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default.dbi delete mode 100644 tizen/skins/emul_3keys_720x1280/default.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default_180.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default_180_p.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default_p.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default_w.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default_w90.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default_w90_p.png delete mode 100644 tizen/skins/emul_3keys_720x1280/default_w_p.png delete mode 100644 tizen/skins/emul_480x800/default.dbi delete mode 100644 tizen/skins/emul_480x800/default.png delete mode 100644 tizen/skins/emul_480x800/default_180.png delete mode 100644 tizen/skins/emul_480x800/default_180_p.png delete mode 100644 tizen/skins/emul_480x800/default_p.png delete mode 100644 tizen/skins/emul_480x800/default_w.png delete mode 100644 tizen/skins/emul_480x800/default_w90.png delete mode 100644 tizen/skins/emul_480x800/default_w90_p.png delete mode 100644 tizen/skins/emul_480x800/default_w_p.png delete mode 100644 tizen/skins/emul_600x1024/default.dbi delete mode 100644 tizen/skins/emul_600x1024/default.png delete mode 100644 tizen/skins/emul_600x1024/default_180.png delete mode 100644 tizen/skins/emul_600x1024/default_180_p.png delete mode 100644 tizen/skins/emul_600x1024/default_p.png delete mode 100644 tizen/skins/emul_600x1024/default_w.png delete mode 100644 tizen/skins/emul_600x1024/default_w90.png delete mode 100644 tizen/skins/emul_600x1024/default_w90_p.png delete mode 100644 tizen/skins/emul_600x1024/default_w_p.png delete mode 100644 tizen/skins/emul_720x1280/default.dbi delete mode 100644 tizen/skins/emul_720x1280/default.png delete mode 100644 tizen/skins/emul_720x1280/default_180.png delete mode 100644 tizen/skins/emul_720x1280/default_180_p.png delete mode 100644 tizen/skins/emul_720x1280/default_p.png delete mode 100644 tizen/skins/emul_720x1280/default_w.png delete mode 100644 tizen/skins/emul_720x1280/default_w90.png delete mode 100644 tizen/skins/emul_720x1280/default_w90_p.png delete mode 100644 tizen/skins/emul_720x1280/default_w_p.png delete mode 100644 tizen/skins/icons/01_SHELL.png delete mode 100644 tizen/skins/icons/02_ADVANCED.png delete mode 100644 tizen/skins/icons/03_TELEPHONY-EMULATOR.png delete mode 100644 tizen/skins/icons/04_KEYPAD.png delete mode 100644 tizen/skins/icons/05_GPS.png delete mode 100644 tizen/skins/icons/06_SCREEN-SHOT.png delete mode 100644 tizen/skins/icons/07_EXECUTE_APP.png delete mode 100644 tizen/skins/icons/08_OPEN.png delete mode 100644 tizen/skins/icons/09_ROTATE.png delete mode 100644 tizen/skins/icons/10_PROPERTIES.png delete mode 100644 tizen/skins/icons/11_OPTION.png delete mode 100644 tizen/skins/icons/12_DEVICE-INFO.png delete mode 100644 tizen/skins/icons/13_ABOUT.png delete mode 100644 tizen/skins/icons/14_CLOSE.png delete mode 100644 tizen/skins/icons/15_COMPASS.png delete mode 100644 tizen/skins/icons/Emulator.ico delete mode 100644 tizen/skins/icons/Emulator_20x20.png delete mode 100644 tizen/skins/icons/Icon_Toolbar.gif delete mode 100644 tizen/skins/icons/vtm.ico delete mode 100644 tizen/src/DEBUGCH delete mode 100644 tizen/src/Makefile.in delete mode 100644 tizen/src/Makefile_win32 delete mode 100644 tizen/src/NOTICE delete mode 100644 tizen/src/about_version.h delete mode 100644 tizen/src/arch_arm.c delete mode 100644 tizen/src/arch_x86.c delete mode 100644 tizen/src/command.c delete mode 100644 tizen/src/command.h delete mode 100644 tizen/src/config_dbg_x86.ini delete mode 100644 tizen/src/config_x86.ini delete mode 100644 tizen/src/configuration.c delete mode 100644 tizen/src/configuration.h delete mode 100644 tizen/src/dbi_parser.c delete mode 100644 tizen/src/dbi_parser.h delete mode 100644 tizen/src/debug_ch_vtm.c delete mode 100644 tizen/src/defines.h delete mode 100644 tizen/src/dialog.c delete mode 100644 tizen/src/dialog.h delete mode 100644 tizen/src/emul_debug.bat delete mode 100755 tizen/src/emul_debug.sh delete mode 100755 tizen/src/emulator.sh delete mode 100755 tizen/src/emulator.sh.old delete mode 100644 tizen/src/emulsignal.c delete mode 100644 tizen/src/emulsignal.h delete mode 100644 tizen/src/event_handler.c delete mode 100644 tizen/src/event_handler.h delete mode 100644 tizen/src/extern.h delete mode 100644 tizen/src/fileio.c delete mode 100644 tizen/src/fileio.h delete mode 100644 tizen/src/hw/brightness.c delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter.sln delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter.suo delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/ReadMe.txt delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/dllmain.cpp delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwccallback_h.h delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcfilter.cpp delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcfilter.def delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcfilter.h delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcfilter.vcxproj delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcfilter.vcxproj.filters delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcfilter.vcxproj.user delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcfilter_h.h delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcsp.cpp delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/hwcsp.h delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/stdafx.cpp delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/stdafx.h delete mode 100644 tizen/src/hw/camera_win32_dll/hwcfilter/hwcfilter/targetver.h delete mode 100644 tizen/src/hw/maru_touchscreen.c delete mode 100644 tizen/src/hw/overlay.c delete mode 100644 tizen/src/hw/svcamera.h delete mode 100644 tizen/src/hw/svcamera_linux.c delete mode 100644 tizen/src/hw/svcamera_pci.c delete mode 100644 tizen/src/hw/svcamera_win32.c delete mode 100644 tizen/src/hw/tizen-ac97.c delete mode 100644 tizen/src/hw/tizen-board.c delete mode 100644 tizen/src/menu.c delete mode 100644 tizen/src/menu.h delete mode 100644 tizen/src/menu_callback.c delete mode 100644 tizen/src/menu_callback.h delete mode 100644 tizen/src/option_callback.c delete mode 100644 tizen/src/option_callback.h delete mode 100644 tizen/src/qemu_gtk_widget.c delete mode 100644 tizen/src/qemu_gtk_widget.h delete mode 100644 tizen/src/savevm.glade delete mode 100644 tizen/src/screen_shot.c delete mode 100644 tizen/src/screen_shot.h delete mode 100644 tizen/src/sensor_server.c delete mode 100644 tizen/src/sensor_server.h delete mode 100644 tizen/src/tools.c delete mode 100644 tizen/src/tools.h delete mode 100644 tizen/src/ui_imageid.h delete mode 100644 tizen/src/utils.c delete mode 100644 tizen/src/utils.h delete mode 100644 tizen/src/vinit_process.c delete mode 100644 tizen/src/vinit_process.h delete mode 100644 tizen/src/vt_utils.c delete mode 100644 tizen/src/vt_utils.h delete mode 100644 tizen/src/vtm.c delete mode 100644 tizen/src/vtm.glade delete mode 100644 tizen/src/vtm.h delete mode 100644 ui/sdl_rotate.c delete mode 100644 ui/sdl_rotate.h delete mode 100644 vl.h diff --git a/CODING_STYLE b/CODING_STYLE index 5ecfa22..6e61c49 100644 --- a/CODING_STYLE +++ b/CODING_STYLE @@ -68,6 +68,10 @@ keyword. Example: printf("a was something else entirely.\n"); } +Note that 'else if' is considered a single statement; otherwise a long if/ +else if/else if/.../else sequence would need an indent for every else +statement. + An exception is the opening brace for a function; for reasons of tradition and clarity it comes on a line by itself: diff --git a/Changelog b/Changelog index 152feaa..28a69af 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,9 @@ +This file documents changes for QEMU releases 0.12 and earlier. +For changelog information for later releases, see +http://wiki.qemu.org/ChangeLog or look at the git history for +more detailed information. + + version 0.12.0: - Update to SeaBIOS 0.5.0 @@ -525,7 +531,7 @@ version 0.1.5: - ppc64 support + personality() patch (Rusty Russell) - first Alpha CPU patches (Falk Hueffner) - - removed bfd.h dependancy + - removed bfd.h dependency - fixed shrd, shld, idivl and divl on PowerPC. - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC). diff --git a/HACKING b/HACKING index 6ba9d7e..733eab2 100644 --- a/HACKING +++ b/HACKING @@ -77,11 +77,11 @@ avoided. Use of the malloc/free/realloc/calloc/valloc/memalign/posix_memalign APIs is not allowed in the QEMU codebase. Instead of these routines, -use the replacement qemu_malloc/qemu_mallocz/qemu_realloc/qemu_free or +use the replacement g_malloc/g_malloc0/g_realloc/g_free or qemu_vmalloc/qemu_memalign/qemu_vfree APIs. -Please note that NULL check for the qemu_malloc result is redundant and -that qemu_malloc() call with zero size is not allowed. +Please note that NULL check for the g_malloc result is redundant and +that g_malloc() call with zero size is not allowed. Memory allocated by qemu_vmalloc or qemu_memalign must be freed with qemu_vfree, since breaking this will cause problems on Win32 and user @@ -108,7 +108,7 @@ int qemu_strnlen(const char *s, int max_len) There are also replacement character processing macros for isxyz and toxyz, so instead of e.g. isalnum you should use qemu_isalnum. -Because of the memory management rules, you must use qemu_strdup/qemu_strndup +Because of the memory management rules, you must use g_strdup/g_strndup instead of plain strdup/strndup. 5. Printf-style functions @@ -120,6 +120,3 @@ gcc's printf attribute directive in the prototype. This makes it so gcc's -Wformat and -Wformat-security options can do their jobs and cross-check format strings with the number and types of arguments. - -Currently many functions in QEMU are not following this rule but -patches to add the attribute would be very much appreciated. diff --git a/MAINTAINERS b/MAINTAINERS index ab48380..06df70c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -56,12 +56,13 @@ M: Paul Brook Guest CPU cores (TCG): ---------------------- Alpha -M: qemu-devel@nongnu.org -S: Orphan +M: Richard Henderson +S: Maintained F: target-alpha/ ARM M: Paul Brook +M: Peter Maydell S: Maintained F: target-arm/ @@ -70,6 +71,11 @@ M: Edgar E. Iglesias S: Maintained F: target-cris/ +LM32 +M: Michael Walle +S: Maintained +F: target-lm32/ + M68K M: Paul Brook S: Maintained @@ -110,6 +116,12 @@ M: qemu-devel@nongnu.org S: Odd Fixes F: target-i386/ +Xtensa +M: Max Filippov +W: http://wiki.osll.spb.ru/doku.php?id=etc:users:jcmvbkbc:qemu-target-xtensa +S: Maintained +F: target-xtensa/ + Guest CPU Cores (KVM): ---------------------- @@ -138,6 +150,16 @@ L: kvm@vger.kernel.org S: Supported F: target-i386/kvm.c +Guest CPU Cores (Xen): +---------------------- + +X86 +M: Stefano Stabellini +L: xen-devel@lists.xensource.com +S: Supported +F: xen-* +F: */xen* + ARM Machines ------------ Gumstix @@ -147,6 +169,7 @@ F: hw/gumstix.c Integrator CP M: Paul Brook +M: Peter Maydell S: Maintained F: hw/integratorcp.c @@ -172,6 +195,7 @@ F: hw/palm.c Real View M: Paul Brook +M: Peter Maydell S: Maintained F: hw/realview* @@ -182,11 +206,13 @@ F: hw/spitz.c Stellaris M: Paul Brook +M: Peter Maydell S: Maintained F: hw/stellaris.c Versatile PB M: Paul Brook +M: Peter Maydell S: Maintained F: hw/versatilepb.c @@ -202,6 +228,18 @@ M: Edgar E. Iglesias S: Maintained F: hw/etraxfs.c +LM32 Machines +------------- +EVR32 and uclinux BSP +M: Michael Walle +S: Maintained +F: hw/lm32_boards.c + +milkymist +M: Michael Walle +S: Maintained +F: hw/milkymist.c + M68K Machines ------------- an5206 @@ -265,9 +303,9 @@ M: Alexander Graf S: Maintained F: hw/ppc_oldworld.c -Prep -M: qemu-devel@nongnu.org -S: Orphan +PReP +M: Andreas Färber +S: Odd Fixes F: hw/ppc_prep.c SH4 Machines @@ -308,6 +346,18 @@ M: Anthony Liguori S: Supported F: hw/pc.[ch] hw/pc_piix.c +Xtensa Machines +--------------- +sim +M: Max Filippov +S: Maintained +F: hw/xtensa_sim.c + +Avnet LX60 +M: Max Filippov +S: Maintained +F: hw/xtensa_lx60.c + Devices ------- IDE @@ -315,6 +365,11 @@ M: Kevin Wolf S: Odd Fixes F: hw/ide/ +OMAP +M: Peter Maydell +S: Maintained +F: hw/omap* + PCI M: Michael S. Tsirkin S: Supported @@ -396,6 +451,11 @@ M: Anthony Liguori S: Maintained F: ui/ +Cocoa graphics +M: Andreas Färber +S: Odd Fixes +F: ui/cocoa.m + Main loop M: Anthony Liguori S: Supported @@ -414,9 +474,21 @@ S: Maintained F: net/ SLIRP -M: qemu-devel@nongnu.org -S: Orphan +M: Jan Kiszka +S: Maintained F: slirp/ +T: git://git.kiszka.org/qemu.git queues/slirp + +Tracing +M: Stefan Hajnoczi +S: Maintained +F: trace/ +T: git://repo.or.cz/qemu/stefanha.git tracing + +Checkpatch +M: Blue Swirl +S: Odd Fixes +F: scripts/checkpatch.pl Usermode Emulation ------------------ @@ -463,7 +535,7 @@ S: Maintained F: tcg/ia64/ MIPS target -M: Aurelien Jarno +M: Aurelien Jarno S: Maintained F: tcg/mips/ @@ -487,3 +559,8 @@ SPARC target M: Blue Swirl S: Maintained F: tcg/sparc/ + +TCI target +M: Stefan Weil +S: Maintained +F: tcg/tci diff --git a/Makefile b/Makefile index 37f22ea..301c75e 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,14 @@ # Makefile for QEMU. +# Always point to the root of the build tree (needs GNU make). +BUILD_DIR=$(CURDIR) + GENERATED_HEADERS = config-host.h trace.h qemu-options.def ifeq ($(TRACE_BACKEND),dtrace) GENERATED_HEADERS += trace-dtrace.h endif +GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h +GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c ifneq ($(wildcard config-host.mak),) # Put the all: rule here so that config-host.mak can contain dependencies. @@ -37,7 +42,7 @@ else DOCS= endif -SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory) +SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory) BUILD_DIR=$(BUILD_DIR) SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS)) SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %/config-devices.mak.d, $(TARGET_DIRS)) @@ -71,7 +76,7 @@ defconfig: -include config-all-devices.mak -build-all: $(DOCS) $(TOOLS) recurse-all +build-all: $(DOCS) $(TOOLS) $(CHECKS) recurse-all config-host.h: config-host.h-timestamp config-host.h-timestamp: config-host.mak @@ -88,6 +93,8 @@ include $(SRC_PATH)/Makefile.objs endif $(common-obj-y): $(GENERATED_HEADERS) +subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o + $(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis $(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) $(trace-obj-y) subdir-libdis-user subdir-libuser @@ -104,87 +111,128 @@ audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS) QEMU_CFLAGS+=$(CURL_CFLAGS) +QEMU_CFLAGS+=$(GLIB_CFLAGS) + ui/cocoa.o: ui/cocoa.m -ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o ui/sdl_rotate.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) +ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS) bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS) -ifeq ($(TRACE_BACKEND),dtrace) -trace.h: trace.h-timestamp trace-dtrace.h -else -trace.h: trace.h-timestamp -endif -trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h") - @cmp -s $@ trace.h || cp $@ trace.h - -trace.c: trace.c-timestamp -trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c") - @cmp -s $@ trace.c || cp $@ trace.c - -trace.o: trace.c $(GENERATED_HEADERS) - -trace-dtrace.h: trace-dtrace.dtrace - $(call quiet-command,dtrace -o $@ -h -s $<, " GEN trace-dtrace.h") - -# Normal practice is to name DTrace probe file with a '.d' extension -# but that gets picked up by QEMU's Makefile as an external dependancy -# rule file. So we use '.dtrace' instead -trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp -trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace") - @cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace +version.o: $(SRC_PATH)/version.rc config-host.h + $(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@") -trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS) - $(call quiet-command,dtrace -o $@ -G -s $<, " GEN trace-dtrace.o") +version-obj-$(CONFIG_WIN32) += version.o +###################################################################### +# Support building shared library libcacard -simpletrace.o: simpletrace.c $(GENERATED_HEADERS) +.PHONY: libcacard.la install-libcacard +ifeq ($(LIBTOOL),) +libcacard.la: + @echo "libtool is missing, please install and rerun configure"; exit 1 -version.o: $(SRC_PATH)/version.rc config-host.mak - $(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@") +install-libcacard: + @echo "libtool is missing, please install and rerun configure"; exit 1 +else +libcacard.la: $(GENERATED_HEADERS) $(oslib-obj-y) qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y))) + $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" libcacard.la,) -version-obj-$(CONFIG_WIN32) += version.o +install-libcacard: libcacard.la + $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" install-libcacard,) +endif ###################################################################### qemu-img.o: qemu-img-cmds.h -qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o: $(GENERATED_HEADERS) - -qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o cmd.o qemu-ga.o: $(GENERATED_HEADERS) -qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +tools-obj-y = qemu-tool.o $(oslib-obj-y) $(trace-obj-y) \ + qemu-timer-common.o cutils.o -qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o +qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) +qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y) +qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $@") -check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o: $(GENERATED_HEADERS) - -CHECK_PROG_DEPS = qemu-malloc.o $(oslib-obj-y) $(trace-obj-y) - -check-qint: check-qint.o qint.o $(CHECK_PROG_DEPS) -check-qstring: check-qstring.o qstring.o $(CHECK_PROG_DEPS) -check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(CHECK_PROG_DEPS) -check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS) -check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS) -check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o $(CHECK_PROG_DEPS) +check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o test-coroutine.o: $(GENERATED_HEADERS) + +check-qint: check-qint.o qint.o $(tools-obj-y) +check-qstring: check-qstring.o qstring.o $(tools-obj-y) +check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(tools-obj-y) +check-qlist: check-qlist.o qlist.o qint.o $(tools-obj-y) +check-qfloat: check-qfloat.o qfloat.o $(tools-obj-y) +check-qjson: check-qjson.o $(qobject-obj-y) $(tools-obj-y) +test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y) $(tools-obj-y) + +$(qapi-obj-y): $(GENERATED_HEADERS) +qapi-dir := $(BUILD_DIR)/qapi-generated +test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir) +qemu-ga$(EXESUF): LIBS = $(LIBS_QGA) + +$(qapi-dir)/test-qapi-types.c $(qapi-dir)/test-qapi-types.h :\ +$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@") +$(qapi-dir)/test-qapi-visit.c $(qapi-dir)/test-qapi-visit.h :\ +$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@") +$(qapi-dir)/test-qmp-commands.h $(qapi-dir)/test-qmp-marshal.c :\ +$(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@") + +$(qapi-dir)/qga-qapi-types.c $(qapi-dir)/qga-qapi-types.h :\ +$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-types.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@") +$(qapi-dir)/qga-qapi-visit.c $(qapi-dir)/qga-qapi-visit.h :\ +$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-visit.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@") +$(qapi-dir)/qga-qmp-commands.h $(qapi-dir)/qga-qmp-marshal.c :\ +$(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/scripts/qapi-commands.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "qga-" < $<, " GEN $@") + +qapi-types.c qapi-types.h :\ +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py -o "." < $<, " GEN $@") +qapi-visit.c qapi-visit.h :\ +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py -o "." < $<, " GEN $@") +qmp-commands.h qmp-marshal.c :\ +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -m -o "." < $<, " GEN $@") + +test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y) +test-visitor: test-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o + +test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y) +test-qmp-commands: test-qmp-commands.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o + +QGALIB_OBJ=$(addprefix $(qapi-dir)/, qga-qapi-types.o qga-qapi-visit.o qga-qmp-marshal.o) +QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h) +$(QGALIB_OBJ): $(QGALIB_GEN) $(GENERATED_HEADERS) +$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN) $(GENERATED_HEADERS) + +qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qobject-obj-y) $(version-obj-y) $(QGALIB_OBJ) + +QEMULIBS=libhw32 libhw64 libuser libdis libdis-user clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f qemu-options.def - rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~ - rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d + rm -f *.o *.d *.a *.lo $(TOOLS) $(CHECKS) qemu-ga TAGS cscope.* *.pod *~ */*~ + rm -Rf .libs + rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d rm -f qemu-img-cmds.h + rm -f trace/*.o trace/*.d rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp rm -f trace-dtrace.h trace-dtrace.h-timestamp + rm -f $(GENERATED_SOURCES) + rm -rf $(qapi-dir) $(MAKE) -C tests clean - for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \ + for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \ if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \ rm -f $$d/qemu-options.def; \ done @@ -193,9 +241,13 @@ distclean: clean rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi rm -f config-all-devices.mak rm -f roms/seabios/config.mak roms/vgabios/config.mak - rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp qemu-doc.vr + rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.cps qemu-doc.dvi + rm -f qemu-doc.fn qemu-doc.fns qemu-doc.info qemu-doc.ky qemu-doc.kys + rm -f qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp + rm -f qemu-doc.vr + rm -f config.log rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr - for d in $(TARGET_DIRS) libhw32 libhw64 libuser libdis libdis-user; do \ + for d in $(TARGET_DIRS) $(QEMULIBS); do \ rm -rf $$d || exit 1 ; \ done @@ -204,16 +256,17 @@ ar de en-us fi fr-be hr it lv nl pl ru th \ common de-ch es fo fr-ca hu ja mk nl-be pt sl tr ifdef INSTALL_BLOBS -BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin \ +BLOBS=bios.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \ vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \ ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \ -gpxe-eepro100-80861209.rom \ -pxe-e1000.bin \ -pxe-ne2k_pci.bin pxe-pcnet.bin \ -pxe-rtl8139.bin pxe-virtio.bin \ -bamboo.dtb petalogix-s3adsp1800.dtb \ +pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \ +pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \ +bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \ +mpc8544ds.dtb \ multiboot.bin linuxboot.bin \ -s390-zipl.rom +s390-zipl.rom \ +spapr-rtas.bin slof.bin \ +palcode-clipper else BLOBS= endif @@ -255,13 +308,19 @@ endif test speed: all $(MAKE) -C tests $@ +.PHONY: check +check: $(patsubst %,run-check-%,$(CHECKS)) + +run-check-%: % + ./$< + .PHONY: TAGS TAGS: find "$(SRC_PATH)" -name '*.[hc]' -print0 | xargs -0 etags cscope: rm -f ./cscope.* - find . -name "*.[ch]" -print | sed 's,^\./,,' > ./cscope.files + find "$(SRC_PATH)" -name "*.[chsS]" -print | sed 's,^\./,,' > ./cscope.files cscope -b # documentation @@ -330,40 +389,5 @@ tar: cd /tmp && tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS --exclude .git --exclude .svn rm -rf /tmp/$(FILE) -SYSTEM_TARGETS=$(filter %-softmmu,$(TARGET_DIRS)) -SYSTEM_PROGS=$(patsubst qemu-system-i386,qemu, \ - $(patsubst %-softmmu,qemu-system-%, \ - $(SYSTEM_TARGETS))) - -USER_TARGETS=$(filter %-user,$(TARGET_DIRS)) -USER_PROGS=$(patsubst %-bsd-user,qemu-%, \ - $(patsubst %-darwin-user,qemu-%, \ - $(patsubst %-linux-user,qemu-%, \ - $(USER_TARGETS)))) - -# generate a binary distribution -tarbin: - cd / && tar zcvf ~/qemu-$(VERSION)-$(ARCH).tar.gz \ - $(patsubst %,$(bindir)/%, $(SYSTEM_PROGS)) \ - $(patsubst %,$(bindir)/%, $(USER_PROGS)) \ - $(bindir)/qemu-img \ - $(bindir)/qemu-nbd \ - $(datadir)/bios.bin \ - $(datadir)/vgabios.bin \ - $(datadir)/vgabios-cirrus.bin \ - $(datadir)/ppc_rom.bin \ - $(datadir)/openbios-sparc32 \ - $(datadir)/openbios-sparc64 \ - $(datadir)/openbios-ppc \ - $(datadir)/pxe-ne2k_pci.bin \ - $(datadir)/pxe-rtl8139.bin \ - $(datadir)/pxe-pcnet.bin \ - $(datadir)/pxe-e1000.bin \ - $(docdir)/qemu-doc.html \ - $(docdir)/qemu-tech.html \ - $(mandir)/man1/qemu.1 \ - $(mandir)/man1/qemu-img.1 \ - $(mandir)/man8/qemu-nbd.8 - # Include automatically generated dependency files --include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d) +-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d qga/*.d) diff --git a/Makefile.hw b/Makefile.hw index f2e63b4..63eb7e4 100644 --- a/Makefile.hw +++ b/Makefile.hw @@ -7,9 +7,10 @@ include $(SRC_PATH)/rules.mak .PHONY: all -$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/tizen/src/hw) +$(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw) -QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu -I$(SRC_PATH)/hw +QEMU_CFLAGS+=-I.. +QEMU_CFLAGS += $(GLIB_CFLAGS) include $(SRC_PATH)/Makefile.objs diff --git a/Makefile.objs b/Makefile.objs index 3b52e33..3a699ee 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -2,19 +2,30 @@ # QObject qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o -qobject-obj-y += qerror.o +qobject-obj-y += qerror.o error.o qemu-error.o ####################################################################### # oslib-obj-y is code depending on the OS (win32 vs posix) oslib-obj-y = osdep.o -oslib-obj-$(CONFIG_WIN32) += oslib-win32.o -oslib-obj-$(CONFIG_POSIX) += oslib-posix.o +oslib-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o +oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o + +####################################################################### +# coroutines +coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o +ifeq ($(CONFIG_UCONTEXT_COROUTINE),y) +coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o +else +coroutine-obj-$(CONFIG_POSIX) += coroutine-gthread.o +endif +coroutine-obj-$(CONFIG_WIN32) += coroutine-win32.o ####################################################################### # block-obj-y is code used by both qemu system emulation and qemu-img -block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o -block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o +block-obj-y = cutils.o cache-utils.o qemu-option.o module.o async.o +block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o qemu-sockets.o +block-obj-y += $(coroutine-obj-y) $(qobject-obj-y) $(version-obj-y) block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o @@ -25,6 +36,7 @@ block-nested-y += qed-check.o block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o block-nested-$(CONFIG_WIN32) += raw-win32.o block-nested-$(CONFIG_POSIX) += raw-posix.o +block-nested-$(CONFIG_LIBISCSI) += iscsi.o block-nested-$(CONFIG_CURL) += curl.o block-nested-$(CONFIG_RBD) += rbd.o @@ -45,12 +57,14 @@ net-nested-$(CONFIG_SLIRP) += slirp.o net-nested-$(CONFIG_VDE) += vde.o net-obj-y += $(addprefix net/, $(net-nested-y)) -ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS),yy) +ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy) # Lots of the fsdev/9pcode is pulled in by vl.c via qemu_fsdev_add. # only pull in the actual virtio-9p device if we also enabled virtio. CONFIG_REALLY_VIRTFS=y +fsdev-nested-y = qemu-fsdev.o +else +fsdev-nested-y = qemu-fsdev-dummy.o endif -fsdev-nested-$(CONFIG_VIRTFS) = qemu-fsdev.o fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) ###################################################################### @@ -63,13 +77,13 @@ common-obj-y = $(block-obj-y) blockdev.o common-obj-y += $(net-obj-y) common-obj-y += $(qobject-obj-y) common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX)) -common-obj-y += readline.o console.o cursor.o async.o qemu-error.o +common-obj-y += readline.o console.o cursor.o common-obj-y += $(oslib-obj-y) common-obj-$(CONFIG_WIN32) += os-win32.o common-obj-$(CONFIG_POSIX) += os-posix.o -common-obj-y += tcg-runtime.o host-utils.o -common-obj-y += irq.o ioport.o input.o +common-obj-y += tcg-runtime.o host-utils.o main-loop.o +common-obj-y += irq.o input.o common-obj-$(CONFIG_PTIMER) += ptimer.o common-obj-$(CONFIG_MAX7310) += max7310.o common-obj-$(CONFIG_WM8750) += wm8750.o @@ -87,6 +101,7 @@ common-obj-y += i2c.o smbus.o smbus_eeprom.o common-obj-y += eeprom93xx.o common-obj-y += scsi-disk.o cdrom.o common-obj-y += scsi-generic.o scsi-bus.o +common-obj-y += hid.o common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o common-obj-$(CONFIG_SSI) += ssi.o @@ -94,12 +109,13 @@ common-obj-$(CONFIG_SSI_SD) += ssi-sd.o common-obj-$(CONFIG_SD) += sd.o common-obj-y += bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o common-obj-y += bt-hci-csr.o -common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o +common-obj-y += buffered_file.o migration.o migration-tcp.o common-obj-y += qemu-char.o savevm.o #aio.o common-obj-y += msmouse.o ps2.o common-obj-y += qdev.o qdev-properties.o -common-obj-y += block-migration.o +common-obj-y += block-migration.o iohandler.o common-obj-y += pflib.o +common-obj-y += bitmap.o bitops.o common-obj-$(CONFIG_BRLAPI) += baum.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o @@ -124,35 +140,36 @@ audio-obj-y += wavcapture.o common-obj-y += $(addprefix audio/, $(audio-obj-y)) ui-obj-y += keymaps.o -ui-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o sdl_rotate.o x_keymap.o -ui-obj-$(CONFIG_CURSES) += curses.o -ui-obj-y += vnc.o d3des.o -ui-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o -ui-obj-y += vnc-enc-tight.o vnc-palette.o -ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o -ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o +ui-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o ui-obj-$(CONFIG_COCOA) += cocoa.o +ui-obj-$(CONFIG_CURSES) += curses.o +vnc-obj-y += vnc.o d3des.o +vnc-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o +vnc-obj-y += vnc-enc-tight.o vnc-palette.o +vnc-obj-y += vnc-enc-zrle.o +vnc-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o +vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o ifdef CONFIG_VNC_THREAD -ui-obj-y += vnc-jobs-async.o +vnc-obj-y += vnc-jobs-async.o else -ui-obj-y += vnc-jobs-sync.o +vnc-obj-y += vnc-jobs-sync.o endif common-obj-y += $(addprefix ui/, $(ui-obj-y)) +common-obj-$(CONFIG_VNC) += $(addprefix ui/, $(vnc-obj-y)) common-obj-y += iov.o acl.o -common-obj-$(CONFIG_THREAD) += qemu-thread.o -common-obj-$(CONFIG_IOTHREAD) += compatfd.o +common-obj-$(CONFIG_POSIX) += compatfd.o common-obj-y += notify.o event_notifier.o common-obj-y += qemu-timer.o qemu-timer-common.o slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o -slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o +slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y)) # xen backend driver support -common-obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o -common-obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o +common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o +common-obj-$(CONFIG_XEN_BACKEND) += xen_console.o xenfb.o xen_disk.o xen_nic.o ###################################################################### # libuser @@ -161,13 +178,16 @@ user-obj-y = user-obj-y += envlist.o path.o user-obj-y += tcg-runtime.o host-utils.o user-obj-y += cutils.o cache-utils.o +user-obj-y += $(trace-obj-y) ###################################################################### # libhw hw-obj-y = hw-obj-y += vl.o loader.o -hw-obj-$(CONFIG_VIRTIO) += virtio.o virtio-console.o +hw-obj-$(CONFIG_VIRTIO) += virtio-console.o +hw-obj-y += usb-libhw.o +hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o hw-obj-y += fw_cfg.o hw-obj-$(CONFIG_PCI) += pci.o pci_bridge.o hw-obj-$(CONFIG_PCI) += msix.o msi.o @@ -191,13 +211,19 @@ hw-obj-$(CONFIG_PCSPK) += pcspk.o hw-obj-$(CONFIG_PCKBD) += pckbd.o hw-obj-$(CONFIG_USB_UHCI) += usb-uhci.o hw-obj-$(CONFIG_USB_OHCI) += usb-ohci.o +hw-obj-$(CONFIG_USB_EHCI) += usb-ehci.o hw-obj-$(CONFIG_FDC) += fdc.o hw-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o hw-obj-$(CONFIG_DMA) += dma.o +hw-obj-$(CONFIG_HPET) += hpet.o +hw-obj-$(CONFIG_APPLESMC) += applesmc.o +hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o +hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o +hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o +hw-obj-$(CONFIG_I8259) += i8259.o # PPC devices -hw-obj-$(CONFIG_OPENPIC) += openpic.o hw-obj-$(CONFIG_PREP_PCI) += prep_pci.o # Mac shared devices hw-obj-$(CONFIG_MACIO) += macio.o @@ -216,6 +242,7 @@ hw-obj-$(CONFIG_PPCE500_PCI) += ppce500_pci.o # MIPS devices hw-obj-$(CONFIG_PIIX4) += piix4.o +hw-obj-$(CONFIG_G364FB) += g364fb.o # PCI watchdog devices hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o @@ -233,9 +260,10 @@ hw-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o hw-obj-$(CONFIG_SMC91C111) += smc91c111.o hw-obj-$(CONFIG_LAN9118) += lan9118.o hw-obj-$(CONFIG_NE2000_ISA) += ne2000-isa.o +hw-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o # IDE -hw-obj-$(CONFIG_IDE_CORE) += ide/core.o +hw-obj-$(CONFIG_IDE_CORE) += ide/core.o ide/atapi.o hw-obj-$(CONFIG_IDE_QDEV) += ide/qdev.o hw-obj-$(CONFIG_IDE_PCI) += ide/pci.o hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o @@ -258,6 +286,7 @@ hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o hw-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o +hw-obj-$(CONFIG_VMMOUSE) += vmmouse.o hw-obj-$(CONFIG_RC4030) += rc4030.o hw-obj-$(CONFIG_DP8393X) += dp8393x.o @@ -273,17 +302,20 @@ sound-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o sound-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o sound-obj-$(CONFIG_CS4231A) += cs4231a.o sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o -# Haptic -hw-obj-$(CONFIG_SVIBE) += svibe.o - - adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y) -hw-obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p-debug.o -hw-obj-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o -hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o +9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o +9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o +9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o +9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o +9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-synth.o +9pfs-nested-$(CONFIG_OPEN_BY_HANDLE) += virtio-9p-handle.o + +hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y)) +$(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS) + ###################################################################### # libdis @@ -308,16 +340,90 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o # trace ifeq ($(TRACE_BACKEND),dtrace) -trace-obj-y = trace-dtrace.o +trace.h: trace.h-timestamp trace-dtrace.h else -trace-obj-y = trace.o -ifeq ($(TRACE_BACKEND),simple) -trace-obj-y += simpletrace.o -user-obj-y += qemu-timer-common.o +trace.h: trace.h-timestamp +endif +trace.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h") + @cmp -s $@ trace.h || cp $@ trace.h + +trace.c: trace.c-timestamp +trace.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c") + @cmp -s $@ trace.c || cp $@ trace.c + +trace.o: trace.c $(GENERATED_HEADERS) + +trace-dtrace.h: trace-dtrace.dtrace + $(call quiet-command,dtrace -o $@ -h -s $<, " GEN trace-dtrace.h") + +# Normal practice is to name DTrace probe file with a '.d' extension +# but that gets picked up by QEMU's Makefile as an external dependency +# rule file. So we use '.dtrace' instead +trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp +trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace") + @cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace + +trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS) + $(call quiet-command,dtrace -o $@ -G -s $<, " GEN trace-dtrace.o") + +ifeq ($(LIBTOOL),) +trace-dtrace.lo: trace-dtrace.dtrace + @echo "missing libtool. please install and rerun configure."; exit 1 +else +trace-dtrace.lo: trace-dtrace.dtrace + $(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC dtrace -o $@ -G -s $<, " lt GEN trace-dtrace.o") endif + +trace/simple.o: trace/simple.c $(GENERATED_HEADERS) + +trace-obj-$(CONFIG_TRACE_DTRACE) += trace-dtrace.o +ifneq ($(TRACE_BACKEND),dtrace) +trace-obj-y = trace.o endif +trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o + +trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o +trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o + +trace-nested-$(CONFIG_TRACE_STDERR) += stderr.o + +trace-nested-y += control.o + +trace-obj-y += $(addprefix trace/, $(trace-nested-y)) + +$(trace-obj-y): $(GENERATED_HEADERS) + +###################################################################### +# smartcard + +libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o + +###################################################################### +# qapi + +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o qapi-dealloc-visitor.o +qapi-nested-y += qmp-registry.o qmp-dispatch.o +qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) + +common-obj-y += qmp-marshal.o qapi-visit.o qapi-types.o $(qapi-obj-y) +common-obj-y += qmp.o hmp.o + +###################################################################### +# guest agent + +qga-nested-y = guest-agent-commands.o guest-agent-command-state.o +qga-obj-y = $(addprefix qga/, $(qga-nested-y)) +qga-obj-y += qemu-ga.o qemu-sockets.o module.o qemu-option.o +qga-obj-$(CONFIG_WIN32) += oslib-win32.o +qga-obj-$(CONFIG_POSIX) += oslib-posix.o + vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) +QEMU_CFLAGS+=$(GLIB_CFLAGS) + diff --git a/Makefile.target b/Makefile.target old mode 100644 new mode 100755 index 9791d4c..b19e96e --- a/Makefile.target +++ b/Makefile.target @@ -3,6 +3,7 @@ GENERATED_HEADERS = config-target.h CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y) CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y) +CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y) include ../config-host.mak include config-devices.mak @@ -13,8 +14,12 @@ include $(HWDIR)/config.mak endif TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -$(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/tizen/src/hw) -QEMU_CFLAGS+= -I.. -I$(TARGET_PATH) -I$(SRC_PATH)/hw -DNEED_CPU_H +$(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw) + +ifdef CONFIG_LINUX +QEMU_CFLAGS += -I../linux-headers +endif +QEMU_CFLAGS += -I.. -I$(TARGET_PATH) -DNEED_CPU_H include $(SRC_PATH)/Makefile.objs @@ -23,13 +28,7 @@ ifdef CONFIG_USER_ONLY QEMU_PROG=qemu-$(TARGET_ARCH2) else # system emulator name -ifeq ($(TARGET_ARCH), i386) -QEMU_PROG=qemu$(EXESUF) -GUEST_GL_LIB=$(TARGET_PATH)/libGL.so.1 -else QEMU_PROG=qemu-system-$(TARGET_ARCH2)$(EXESUF) -GUEST_GL_LIB= -endif endif PROGS=$(QEMU_PROG) @@ -39,12 +38,10 @@ ifndef CONFIG_HAIKU LIBS+=-lm endif -kvm.o kvm-all.o vhost.o vhost_net.o: QEMU_CFLAGS+=$(KVM_CFLAGS) - config-target.h: config-target.h-timestamp config-target.h-timestamp: config-target.mak -ifdef CONFIG_SYSTEMTAP_TRACE +ifdef CONFIG_TRACE_SYSTEMTAP stap: $(QEMU_PROG).stp ifdef CONFIG_USER_ONLY @@ -64,8 +61,7 @@ else stap: endif -#all: $(PROGS) $(GUEST_GL_LIB) stap -all: libccc.a $(GUEST_GL_LIB) +all: $(PROGS) stap # Dummy command so that make thinks it has done something @true @@ -74,16 +70,26 @@ all: libccc.a $(GUEST_GL_LIB) # cpu emulator library libobj-y = exec.o translate-all.o cpu-exec.o translate.o libobj-y += tcg/tcg.o tcg/optimize.o -libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o -libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o +libobj-$(CONFIG_TCG_INTERPRETER) += tci.o +libobj-y += fpu/softfloat.o libobj-y += op_helper.o helper.o ifeq ($(TARGET_BASE_ARCH), i386) libobj-y += cpuid.o endif +libobj-$(TARGET_SPARC64) += vis_helper.o libobj-$(CONFIG_NEED_MMU) += mmu.o libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o +ifeq ($(TARGET_BASE_ARCH), sparc) +libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o +libobj-y += cpu_init.o +endif +libobj-$(TARGET_SPARC) += int32_helper.o +libobj-$(TARGET_SPARC64) += int64_helper.o libobj-y += disas.o +libobj-$(CONFIG_TCI_DIS) += tci-dis.o + +tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci $(libobj-y): $(GENERATED_HEADERS) @@ -97,10 +103,10 @@ tcg/tcg.o: cpu.h # HELPER_CFLAGS is used for all the code compiled with static register # variables -op_helper.o cpu-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) +op_helper.o ldst_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) # Note: this is a workaround. The real fix is to avoid compiling -# cpu_signal_handler() in cpu-exec.c. +# cpu_signal_handler() in user-exec.c. signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS) ######################################################### @@ -110,10 +116,10 @@ ifdef CONFIG_LINUX_USER $(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)) -QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) +QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \ elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \ - qemu-malloc.o $(oslib-obj-y) + user-exec.o $(oslib-obj-y) obj-$(TARGET_HAS_BFLT) += flatload.o @@ -151,7 +157,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000 LIBS+=-lmx obj-y = main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \ - gdbstub.o + gdbstub.o user-exec.o obj-i386-y += ioport-user.o @@ -173,7 +179,7 @@ $(call set-vpath, $(SRC_PATH)/bsd-user) QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH) obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \ - gdbstub.o uaccess.o + gdbstub.o uaccess.o user-exec.o obj-i386-y += ioport-user.o @@ -189,71 +195,86 @@ endif #CONFIG_BSD_USER # System emulator target ifdef CONFIG_SOFTMMU -obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o +obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o # virtio has to be here due to weird dependency between PCI and virtio-net. # need to fix this properly obj-$(CONFIG_NO_PCI) += pci-stub.o -obj-$(CONFIG_VIRTIO) += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o virtio-gpi.o -obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o +obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o obj-y += vhost_net.o obj-$(CONFIG_VHOST_NET) += vhost.o -obj-$(CONFIG_REALLY_VIRTFS) += virtio-9p.o -obj-y += rwhandler.o -obj-y += sdb.o +obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o +obj-y += memory.o LIBS+=-lz QEMU_CFLAGS += $(VNC_TLS_CFLAGS) QEMU_CFLAGS += $(VNC_SASL_CFLAGS) QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) QEMU_CFLAGS += $(VNC_PNG_CFLAGS) +QEMU_CFLAGS += $(GLIB_CFLAGS) + +# xen support +obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o +obj-$(CONFIG_NO_XEN) += xen-stub.o + +obj-i386-$(CONFIG_XEN) += xen_platform.o -# xen backend driver support -obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o + +# HAX support +ifeq ($(TARGET_ARCH), i386) +ifdef CONFIG_WIN32 +obj-$(CONFIG_HAX) += \ + hax-all.o \ + hax-windows.o +endif +endif # Inter-VM PCI shared memory -obj-$(CONFIG_KVM) += ivshmem.o +CONFIG_IVSHMEM = +ifeq ($(CONFIG_KVM), y) + ifeq ($(CONFIG_PCI), y) + CONFIG_IVSHMEM = y + endif +endif +obj-$(CONFIG_IVSHMEM) += ivshmem.o # Hardware support obj-i386-y += vga.o -obj-i386-y += mc146818rtc.o i8259.o pc.o -obj-i386-y += cirrus_vga.o apic.o ioapic.o piix_pci.o -obj-i386-y += vmmouse.o vmport.o hpet.o applesmc.o +obj-i386-y += mc146818rtc.o pc.o +obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o +obj-i386-y += vmport.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o obj-i386-y += debugcon.o multiboot.o obj-i386-y += pc_piix.o +obj-i386-$(CONFIG_KVM) += kvmclock.o obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o -########################################################## -# opengl library for i386 -obj-i386-y += helper_opengl.o opengl_exec.o opengl_server.o -########################################################## - -########################################################## -# general purpose interface for i386 -obj-i386-y += helper_gpi.o -########################################################## - # shared objects -obj-ppc-y = ppc.o +obj-ppc-y = ppc.o ppc_booke.o obj-ppc-y += vga.o # PREP target -obj-ppc-y += i8259.o mc146818rtc.o +obj-ppc-y += mc146818rtc.o obj-ppc-y += ppc_prep.o # OldWorld PowerMac obj-ppc-y += ppc_oldworld.o # NewWorld PowerMac obj-ppc-y += ppc_newworld.o +# IBM pSeries (sPAPR) +obj-ppc-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o +obj-ppc-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o +obj-ppc-$(CONFIG_PSERIES) += spapr_pci.o device-hotplug.o pci-hotplug.o # PowerPC 4xx boards obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o obj-ppc-y += ppc440.o ppc440_bamboo.o # PowerPC E500 boards -obj-ppc-y += ppce500_mpc8544ds.o +obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o # PowerPC 440 Xilinx ML507 reference board. obj-ppc-y += virtex_ml507.o obj-ppc-$(CONFIG_KVM) += kvm_ppc.o obj-ppc-$(CONFIG_FDT) += device_tree.o +# PowerPC OpenPIC +obj-ppc-y += openpic.o # Xilinx PPC peripherals obj-ppc-y += xilinx_intc.o @@ -261,28 +282,52 @@ obj-ppc-y += xilinx_timer.o obj-ppc-y += xilinx_uartlite.o obj-ppc-y += xilinx_ethlite.o +# LM32 boards +obj-lm32-y += lm32_boards.o +obj-lm32-y += milkymist.o + +# LM32 peripherals +obj-lm32-y += lm32_pic.o +obj-lm32-y += lm32_juart.o +obj-lm32-y += lm32_timer.o +obj-lm32-y += lm32_uart.o +obj-lm32-y += lm32_sys.o +obj-lm32-y += milkymist-ac97.o +obj-lm32-y += milkymist-hpdmc.o +obj-lm32-y += milkymist-memcard.o +obj-lm32-y += milkymist-minimac2.o +obj-lm32-y += milkymist-pfpu.o +obj-lm32-y += milkymist-softusb.o +obj-lm32-y += milkymist-sysctl.o +obj-lm32-$(CONFIG_OPENGL) += milkymist-tmu2.o +obj-lm32-y += milkymist-uart.o +obj-lm32-y += milkymist-vgafb.o +obj-lm32-y += framebuffer.o + obj-mips-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o obj-mips-y += mips_addr.o mips_timer.o mips_int.o -obj-mips-y += vga.o i8259.o -obj-mips-y += g364fb.o jazz_led.o +obj-mips-y += vga.o +obj-mips-y += jazz_led.o obj-mips-y += gt64xxx.o mc146818rtc.o obj-mips-y += cirrus_vga.o obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o obj-microblaze-y = petalogix_s3adsp1800_mmu.o +obj-microblaze-y += petalogix_ml605_mmu.o obj-microblaze-y += microblaze_pic_cpu.o obj-microblaze-y += xilinx_intc.o obj-microblaze-y += xilinx_timer.o obj-microblaze-y += xilinx_uartlite.o obj-microblaze-y += xilinx_ethlite.o +obj-microblaze-y += xilinx_axidma.o +obj-microblaze-y += xilinx_axienet.o obj-microblaze-$(CONFIG_FDT) += device_tree.o # Boards obj-cris-y = cris_pic_cpu.o obj-cris-y += cris-boot.o -obj-cris-y += etraxfs.o axis_dev88.o obj-cris-y += axis_dev88.o # IO blocks @@ -324,11 +369,16 @@ obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ obj-arm-y += omap_sx1.o palm.o tsc210x.o obj-arm-y += nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o obj-arm-y += mst_fpga.o mainstone.o +obj-arm-y += z2.o obj-arm-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o obj-arm-y += framebuffer.o obj-arm-y += syborg.o syborg_fb.o syborg_interrupt.o syborg_keyboard.o obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o obj-arm-y += syborg_virtio.o +obj-arm-y += vexpress.o +obj-arm-y += strongarm.o +obj-arm-y += collie.o +obj-arm-y += pl041.o lm4549.o obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o @@ -339,37 +389,20 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o obj-s390x-y = s390-virtio-bus.o s390-virtio.o -obj-alpha-y = alpha_palcode.o - -# -# TIZEN hw -# - -# x86 -obj-i386-y += tizen-board.o -obj-i386-y += tizen-ac97.o -obj-i386-y += overlay.o -obj-i386-y += brightness.o -obj-i386-y += maru_touchscreen.o -obj-i386-y += maru_pm.o -obj-i386-$(CONFIG_PCI) += svcamera_pci.o -obj-i386-$(CONFIG_LINUX) += svcamera_linux.o -obj-i386-$(CONFIG_WIN32) += svcamera_win32.o - -ifdef CONFIG_FFMPEG -obj-i386-y += maru_codec.o -LIBS+=-lavformat -lavcodec -lavutil -lswscale -lbz2 -CFLAGS+=$(FFMPEG_CFLAGS) -endif - -# arm -# common - +obj-alpha-y = mc146818rtc.o +obj-alpha-y += vga.o cirrus_vga.o +obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o +obj-xtensa-y += xtensa_pic.o +obj-xtensa-y += xtensa_sim.o +obj-xtensa-y += xtensa_lx60.o +obj-xtensa-y += xtensa-semi.o +obj-xtensa-y += core-dc232b.o +obj-xtensa-y += core-fsf.o main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) -monitor.o: hmp-commands.h qmp-commands.h +monitor.o: hmp-commands.h qmp-commands-old.h $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) @@ -377,19 +410,28 @@ obj-y += $(addprefix ../, $(common-obj-y)) obj-y += $(addprefix ../libdis/, $(libdis-y)) obj-y += $(libobj-y) obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y)) +obj-y += $(addprefix ../, $(trace-obj-y)) -endif # CONFIG_SOFTMMU +# Makefile for TIZEN-maru +ifdef CONFIG_MARU +include $(SRC_PATH)/tizen/src/Makefile.tizen +endif +## -obj-y += $(addprefix ../, $(trace-obj-y)) -obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o +endif # CONFIG_SOFTMMU -#$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) -# $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) +ifndef CONFIG_LINUX_USER +ifndef CONFIG_BSD_USER +# libcacard needs qemu-thread support, and besides is only needed by devices +# so not requires with linux-user / bsd-user targets +obj-$(CONFIG_SMARTCARD_NSS) += $(addprefix ../libcacard/, $(libcacard-y)) +endif # CONFIG_BSD_USER +endif # CONFIG_LINUX_USER -libccc.a: $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) - rm -f libccc.a-$(TARGET_ARCH2) - @$(AR) rcs libccc.a $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) +obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o +$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) + $(call LINK,$^) gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh @@ -398,40 +440,14 @@ gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh hmp-commands.h: $(SRC_PATH)/hmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") -qmp-commands.h: $(SRC_PATH)/qmp-commands.hx +qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") -########################################################## -# Build openGL -# i386 -ifeq ($(TARGET_ARCH), i386) -parse_gl_h: $(TARGET_PATH)/parse_gl_h.c - $(CC) -Wall -O2 -g $< -o $@ - -client_stub.c server_stub.c gl_func.h: parse_gl_h - ./parse_gl_h - -opengl_exec.o: opengl_exec.c server_stub.c gl_func.h - -opengl_server.o: opengl_server.c opengl_exec.c - -helper_opengl.o: gl_func.h - -$(TARGET_PATH)/libGL.so.1: opengl_client.c gl_func.h - $(CC) -I$(TARGET_PATH) -I. -Wall -g -O2 $< -shared -o $@ -endif - -# arm -#gles1_calls.o: gles1_calls.c gles2.h gles2_calls.h -#gles2_calls.o: gles2_calls.c gles2.h gles2_calls.h -#gles2.o: gles2.c gles2.h gles2_calls.h - -########################################################## clean: rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o - rm -f *.d */*.d tcg/*.o ide/*.o - rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c -ifdef CONFIG_SYSTEMTAP_TRACE + rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o + rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c +ifdef CONFIG_TRACE_SYSTEMTAP rm -f *.stp endif @@ -442,7 +458,7 @@ ifneq ($(STRIP),) $(STRIP) $(patsubst %,"$(DESTDIR)$(bindir)/%",$(PROGS)) endif endif -ifdef CONFIG_SYSTEMTAP_TRACE +ifdef CONFIG_TRACE_SYSTEMTAP $(INSTALL_DIR) "$(DESTDIR)$(datadir)/../systemtap/tapset" $(INSTALL_DATA) $(QEMU_PROG).stp "$(DESTDIR)$(datadir)/../systemtap/tapset" endif diff --git a/Makefile.user b/Makefile.user index 024b773..2b1e4d1 100644 --- a/Makefile.user +++ b/Makefile.user @@ -17,7 +17,9 @@ all: $(user-obj-y) @true clean: - rm -f *.o *.d *.a *~ + for d in . trace; do \ + rm -f $$d/*.o $$d/*.d $$d/*.a $$d/*~; \ + done # Include automatically generated dependency files -include $(wildcard *.d */*.d) diff --git a/NOTICE b/NOTICE deleted file mode 100644 index a7e961c..0000000 --- a/NOTICE +++ /dev/null @@ -1,2 +0,0 @@ -2011-12-16 Munkyu Im - * sdb.c sdb.h : Modify checking port diff --git a/QMP/qmp-shell b/QMP/qmp-shell old mode 100644 new mode 100755 diff --git a/QMP/qmp.py b/QMP/qmp.py index 14ce8b0..c7dbea0 100644 --- a/QMP/qmp.py +++ b/QMP/qmp.py @@ -22,19 +22,24 @@ class QMPCapabilitiesError(QMPError): pass class QEMUMonitorProtocol: - def __init__(self, address): + def __init__(self, address, server=False): """ Create a QEMUMonitorProtocol class. @param address: QEMU address, can be either a unix socket path (string) or a tuple in the form ( address, port ) for a TCP connection - @note No connection is established, this is done by the connect() method + @param server: server mode listens on the socket (bool) + @raise socket.error on socket connection errors + @note No connection is established, this is done by the connect() or + accept() methods """ self.__events = [] self.__address = address self.__sock = self.__get_sock() - self.__sockfile = self.__sock.makefile() + if server: + self.__sock.bind(self.__address) + self.__sock.listen(1) def __get_sock(self): if isinstance(self.__address, tuple): @@ -43,7 +48,18 @@ class QEMUMonitorProtocol: family = socket.AF_UNIX return socket.socket(family, socket.SOCK_STREAM) - def __json_read(self): + def __negotiate_capabilities(self): + self.__sockfile = self.__sock.makefile() + greeting = self.__json_read() + if greeting is None or not greeting.has_key('QMP'): + raise QMPConnectError + # Greeting seems ok, negotiate capabilities + resp = self.cmd('qmp_capabilities') + if "return" in resp: + return greeting + raise QMPCapabilitiesError + + def __json_read(self, only_event=False): while True: data = self.__sockfile.readline() if not data: @@ -51,7 +67,8 @@ class QEMUMonitorProtocol: resp = json.loads(data) if 'event' in resp: self.__events.append(resp) - continue + if not only_event: + continue return resp error = socket.error @@ -66,14 +83,19 @@ class QEMUMonitorProtocol: @raise QMPCapabilitiesError if fails to negotiate capabilities """ self.__sock.connect(self.__address) - greeting = self.__json_read() - if greeting is None or not greeting.has_key('QMP'): - raise QMPConnectError - # Greeting seems ok, negotiate capabilities - resp = self.cmd('qmp_capabilities') - if "return" in resp: - return greeting - raise QMPCapabilitiesError + return self.__negotiate_capabilities() + + def accept(self): + """ + Await connection from QMP Monitor and perform capabilities negotiation. + + @return QMP greeting dict + @raise socket.error on socket connection errors + @raise QMPConnectError if the greeting is not received + @raise QMPCapabilitiesError if fails to negotiate capabilities + """ + self.__sock, _ = self.__sock.accept() + return self.__negotiate_capabilities() def cmd_obj(self, qmp_cmd): """ @@ -106,9 +128,11 @@ class QEMUMonitorProtocol: qmp_cmd['id'] = id return self.cmd_obj(qmp_cmd) - def get_events(self): + def get_events(self, wait=False): """ Get a list of available QMP events. + + @param wait: block until an event is available (bool) """ self.__sock.setblocking(0) try: @@ -118,6 +142,8 @@ class QEMUMonitorProtocol: # No data available pass self.__sock.setblocking(1) + if not self.__events and wait: + self.__json_read(only_event=True) return self.__events def clear_events(self): diff --git a/VERSION b/VERSION index 930e300..7dea76e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.14.1 +1.0.1 diff --git a/a.out.h b/a.out.h index dfc104e..33ca7f7 100644 --- a/a.out.h +++ b/a.out.h @@ -151,7 +151,7 @@ struct external_lineno { #define E_FILNMLEN 14 /* # characters in a file name */ #define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ -struct __attribute__((packed)) external_syment +struct QEMU_PACKED external_syment { union { char e_name[E_SYMNMLEN]; diff --git a/acl.c b/acl.c index 311dade..e840b9b 100644 --- a/acl.c +++ b/acl.c @@ -24,7 +24,6 @@ #include "qemu-common.h" -#include "sysemu.h" #include "acl.h" #ifdef CONFIG_FNMATCH @@ -56,8 +55,8 @@ qemu_acl *qemu_acl_init(const char *aclname) if (acl) return acl; - acl = qemu_malloc(sizeof(*acl)); - acl->aclname = qemu_strdup(aclname); + acl = g_malloc(sizeof(*acl)); + acl->aclname = g_strdup(aclname); /* Deny by default, so there is no window of "open * access" between QEMU starting, and the user setting * up ACLs in the monitor */ @@ -66,7 +65,7 @@ qemu_acl *qemu_acl_init(const char *aclname) acl->nentries = 0; QTAILQ_INIT(&acl->entries); - acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1)); + acls = g_realloc(acls, sizeof(*acls) * (nacls +1)); acls[nacls] = acl; nacls++; @@ -96,13 +95,13 @@ int qemu_acl_party_is_allowed(qemu_acl *acl, void qemu_acl_reset(qemu_acl *acl) { - qemu_acl_entry *entry; + qemu_acl_entry *entry, *next_entry; /* Put back to deny by default, so there is no window * of "open access" while the user re-initializes the * access control list */ acl->defaultDeny = 1; - QTAILQ_FOREACH(entry, &acl->entries, next) { + QTAILQ_FOREACH_SAFE(entry, &acl->entries, next, next_entry) { QTAILQ_REMOVE(&acl->entries, entry, next); free(entry->match); free(entry); @@ -117,8 +116,8 @@ int qemu_acl_append(qemu_acl *acl, { qemu_acl_entry *entry; - entry = qemu_malloc(sizeof(*entry)); - entry->match = qemu_strdup(match); + entry = g_malloc(sizeof(*entry)); + entry->match = g_strdup(match); entry->deny = deny; QTAILQ_INSERT_TAIL(&acl->entries, entry, next); @@ -143,8 +142,8 @@ int qemu_acl_insert(qemu_acl *acl, return qemu_acl_append(acl, deny, match); - entry = qemu_malloc(sizeof(*entry)); - entry->match = qemu_strdup(match); + entry = g_malloc(sizeof(*entry)); + entry->match = g_strdup(match); entry->deny = deny; QTAILQ_FOREACH(tmp, &acl->entries, next) { diff --git a/aio.c b/aio.c index 2f08655..1239ca7 100644 --- a/aio.c +++ b/aio.c @@ -75,13 +75,13 @@ int qemu_aio_set_fd_handler(int fd, * releasing the walking_handlers lock. */ QLIST_REMOVE(node, node); - qemu_free(node); + g_free(node); } } } else { if (node == NULL) { /* Alloc and insert if it's not already there */ - node = qemu_mallocz(sizeof(AioHandler)); + node = g_malloc0(sizeof(AioHandler)); node->fd = fd; QLIST_INSERT_HEAD(&aio_handlers, node, node); } @@ -220,7 +220,7 @@ void qemu_aio_wait(void) if (tmp->deleted) { QLIST_REMOVE(tmp, node); - qemu_free(tmp); + g_free(tmp); } } diff --git a/alpha-dis.c b/alpha-dis.c index 8a2411e..ae331b3 100644 --- a/alpha-dis.c +++ b/alpha-dis.c @@ -238,10 +238,6 @@ extern const unsigned alpha_num_operands; #define AXP_REG_SP 30 #define AXP_REG_ZERO 31 -#define bfd_mach_alpha_ev4 0x10 -#define bfd_mach_alpha_ev5 0x20 -#define bfd_mach_alpha_ev6 0x30 - enum bfd_reloc_code_real { BFD_RELOC_23_PCREL_S2, BFD_RELOC_ALPHA_HINT diff --git a/arch_init.c b/arch_init.c index ba59a61..7995c27 100644 --- a/arch_init.c +++ b/arch_init.c @@ -64,6 +64,8 @@ const char arch_config_name[] = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".con #define QEMU_ARCH QEMU_ARCH_I386 #elif defined(TARGET_M68K) #define QEMU_ARCH QEMU_ARCH_M68K +#elif defined(TARGET_LM32) +#define QEMU_ARCH QEMU_ARCH_LM32 #elif defined(TARGET_MICROBLAZE) #define QEMU_ARCH QEMU_ARCH_MICROBLAZE #elif defined(TARGET_MIPS) @@ -76,6 +78,8 @@ const char arch_config_name[] = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".con #define QEMU_ARCH QEMU_ARCH_SH4 #elif defined(TARGET_SPARC) #define QEMU_ARCH QEMU_ARCH_SPARC +#elif defined(TARGET_XTENSA) +#define QEMU_ARCH QEMU_ARCH_XTENSA #endif const uint32_t arch_type = QEMU_ARCH; @@ -233,7 +237,7 @@ static void sort_ram_list(void) QLIST_FOREACH(block, &ram_list.blocks, next) { ++n; } - blocks = qemu_malloc(n * sizeof *blocks); + blocks = g_malloc(n * sizeof *blocks); n = 0; QLIST_FOREACH_SAFE(block, &ram_list.blocks, next, nblock) { blocks[n++] = block; @@ -243,7 +247,7 @@ static void sort_ram_list(void) while (--n >= 0) { QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next); } - qemu_free(blocks); + g_free(blocks); } int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) @@ -252,6 +256,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) uint64_t bytes_transferred_last; double bwidth = 0; uint64_t expected_time = 0; + int ret; if (stage < 0) { cpu_physical_memory_set_dirty_tracking(0); @@ -259,8 +264,8 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) } if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) { - qemu_file_set_error(f); - return 0; + qemu_file_set_error(f, -EINVAL); + return -EINVAL; } if (stage == 1) { @@ -296,17 +301,20 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_transferred_last = bytes_transferred; bwidth = qemu_get_clock_ns(rt_clock); - while (!qemu_file_rate_limit(f)) { + while ((ret = qemu_file_rate_limit(f)) == 0) { int bytes_sent; bytes_sent = ram_save_block(f); bytes_transferred += bytes_sent; - monitor_printf(mon, "Completed=%f\n",(float)bytes_transferred/(float)ram_bytes_total()); if (bytes_sent == 0) { /* no more blocks */ break; } } + if (ret < 0) { + return ret; + } + bwidth = qemu_get_clock_ns(rt_clock) - bwidth; bwidth = (bytes_transferred - bytes_transferred_last) / bwidth; @@ -368,6 +376,7 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) { ram_addr_t addr; int flags; + int error; if (version_id < 3 || version_id > 4) { return -EINVAL; @@ -448,19 +457,15 @@ int ram_load(QEMUFile *f, void *opaque, int version_id) qemu_get_buffer(f, host, TARGET_PAGE_SIZE); } - if (qemu_file_has_error(f)) { - return -EIO; + error = qemu_file_get_error(f); + if (error) { + return error; } } while (!(flags & RAM_SAVE_FLAG_EOS)); return 0; } -void qemu_service_io(void) -{ - qemu_notify_event(); -} - #ifdef HAS_AUDIO struct soundhw { const char *name; @@ -708,6 +713,11 @@ int audio_available(void) #endif } +int tcg_available(void) +{ + return 1; +} + int kvm_available(void) { #ifdef CONFIG_KVM @@ -725,3 +735,12 @@ int xen_available(void) return 0; #endif } + +int hax_available(void) +{ +#ifdef CONFIG_HAX + return 1; +#else + return 0; +#endif +} diff --git a/arch_init.h b/arch_init.h index 17c9164..f538758 100644 --- a/arch_init.h +++ b/arch_init.h @@ -10,25 +10,26 @@ enum { QEMU_ARCH_CRIS = 4, QEMU_ARCH_I386 = 8, QEMU_ARCH_M68K = 16, - QEMU_ARCH_MICROBLAZE = 32, - QEMU_ARCH_MIPS = 64, - QEMU_ARCH_PPC = 128, - QEMU_ARCH_S390X = 256, - QEMU_ARCH_SH4 = 512, - QEMU_ARCH_SPARC = 1024, + QEMU_ARCH_LM32 = 32, + QEMU_ARCH_MICROBLAZE = 64, + QEMU_ARCH_MIPS = 128, + QEMU_ARCH_PPC = 256, + QEMU_ARCH_S390X = 512, + QEMU_ARCH_SH4 = 1024, + QEMU_ARCH_SPARC = 2048, + QEMU_ARCH_XTENSA = 4096, }; extern const uint32_t arch_type; void select_soundhw(const char *optarg); -int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque); -int ram_load(QEMUFile *f, void *opaque, int version_id); void do_acpitable_option(const char *optarg); void do_smbios_option(const char *optarg); void cpudef_init(void); int audio_available(void); void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus); +int tcg_available(void); int kvm_available(void); int xen_available(void); - +int hax_available(void); #endif diff --git a/arm-semi.c b/arm-semi.c index 1d5179b..873518a 100644 --- a/arm-semi.c +++ b/arm-semi.c @@ -33,8 +33,8 @@ #define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024) #else #include "qemu-common.h" -#include "sysemu.h" #include "gdbstub.h" +#include "hw/arm-misc.h" #endif #define SYS_OPEN 0x01 @@ -370,68 +370,88 @@ uint32_t do_arm_semihosting(CPUState *env) return syscall_err; #endif case SYS_GET_CMDLINE: -#ifdef CONFIG_USER_ONLY - /* Build a commandline from the original argv. */ { - char *arm_cmdline_buffer; - const char *host_cmdline_buffer; + /* Build a command-line from the original argv. + * + * The inputs are: + * * ARG(0), pointer to a buffer of at least the size + * specified in ARG(1). + * * ARG(1), size of the buffer pointed to by ARG(0) in + * bytes. + * + * The outputs are: + * * ARG(0), pointer to null-terminated string of the + * command line. + * * ARG(1), length of the string pointed to by ARG(0). + */ - unsigned int i; - unsigned int arm_cmdline_len = ARG(1); - unsigned int host_cmdline_len = - ts->info->arg_end-ts->info->arg_start; + char *output_buffer; + size_t input_size = ARG(1); + size_t output_size; + int status = 0; - if (!arm_cmdline_len || host_cmdline_len > arm_cmdline_len) { - return -1; /* not enough space to store command line */ - } + /* Compute the size of the output string. */ +#if !defined(CONFIG_USER_ONLY) + output_size = strlen(ts->boot_info->kernel_filename) + + 1 /* Separating space. */ + + strlen(ts->boot_info->kernel_cmdline) + + 1; /* Terminating null byte. */ +#else + unsigned int i; - if (!host_cmdline_len) { + output_size = ts->info->arg_end - ts->info->arg_start; + if (!output_size) { /* We special-case the "empty command line" case (argc==0). Just provide the terminating 0. */ - arm_cmdline_buffer = lock_user(VERIFY_WRITE, ARG(0), 1, 0); - arm_cmdline_buffer[0] = 0; - unlock_user(arm_cmdline_buffer, ARG(0), 1); + output_size = 1; + } +#endif - /* Adjust the commandline length argument. */ - SET_ARG(1, 0); - return 0; + if (output_size > input_size) { + /* Not enough space to store command-line arguments. */ + return -1; } - /* lock the buffers on the ARM side */ - arm_cmdline_buffer = - lock_user(VERIFY_WRITE, ARG(0), host_cmdline_len, 0); - host_cmdline_buffer = - lock_user(VERIFY_READ, ts->info->arg_start, - host_cmdline_len, 1); + /* Adjust the command-line length. */ + SET_ARG(1, output_size - 1); - if (arm_cmdline_buffer && host_cmdline_buffer) - { - /* the last argument is zero-terminated; - no need for additional termination */ - memcpy(arm_cmdline_buffer, host_cmdline_buffer, - host_cmdline_len); + /* Lock the buffer on the ARM side. */ + output_buffer = lock_user(VERIFY_WRITE, ARG(0), output_size, 0); + if (!output_buffer) { + return -1; + } - /* separate arguments by white spaces */ - for (i = 0; i < host_cmdline_len-1; i++) { - if (arm_cmdline_buffer[i] == 0) { - arm_cmdline_buffer[i] = ' '; - } - } + /* Copy the command-line arguments. */ +#if !defined(CONFIG_USER_ONLY) + pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename); + pstrcat(output_buffer, output_size, " "); + pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline); +#else + if (output_size == 1) { + /* Empty command-line. */ + output_buffer[0] = '\0'; + goto out; + } - /* Adjust the commandline length argument. */ - SET_ARG(1, host_cmdline_len-1); + if (copy_from_user(output_buffer, ts->info->arg_start, + output_size)) { + status = -1; + goto out; } - /* Unlock the buffers on the ARM side. */ - unlock_user(arm_cmdline_buffer, ARG(0), host_cmdline_len); - unlock_user((void*)host_cmdline_buffer, ts->info->arg_start, 0); + /* Separate arguments by white spaces. */ + for (i = 0; i < output_size - 1; i++) { + if (output_buffer[i] == 0) { + output_buffer[i] = ' '; + } + } + out: +#endif + /* Unlock the buffer on the ARM side. */ + unlock_user(output_buffer, ARG(0), output_size); - /* Return success if we could return a commandline. */ - return (arm_cmdline_buffer && host_cmdline_buffer) ? 0 : -1; + return status; } -#else - return -1; -#endif case SYS_HEAPINFO: { uint32_t *ptr; @@ -441,15 +461,16 @@ uint32_t do_arm_semihosting(CPUState *env) /* Some C libraries assume the heap immediately follows .bss, so allocate it using sbrk. */ if (!ts->heap_limit) { - long ret; + abi_ulong ret; ts->heap_base = do_brk(0); limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; /* Try a big heap, and reduce the size if that fails. */ for (;;) { ret = do_brk(limit); - if (ret != -1) + if (ret >= limit) { break; + } limit = (ts->heap_base >> 1) + (limit >> 1); } ts->heap_limit = limit; diff --git a/arm.ld b/arm.ld index 12b3edb..7f13da9 100644 --- a/arm.ld +++ b/arm.ld @@ -71,23 +71,23 @@ SECTIONS .data1 : { *(.data1) } .preinit_array : { - PROVIDE_HIDDEN (__preinit_array_start = .); + PROVIDE (__preinit_array_start = .); KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE (__preinit_array_end = .); } .init_array : { - PROVIDE_HIDDEN (__init_array_start = .); + PROVIDE (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE (__init_array_end = .); } .fini_array : { - PROVIDE_HIDDEN (__fini_array_start = .); + PROVIDE (__fini_array_start = .); KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE (__fini_array_end = .); } .ctors : { diff --git a/async.c b/async.c index 57ac3a8..332d511 100644 --- a/async.c +++ b/async.c @@ -24,93 +24,10 @@ #include "qemu-common.h" #include "qemu-aio.h" +#include "main-loop.h" -/* - * An AsyncContext protects the callbacks of AIO requests and Bottom Halves - * against interfering with each other. A typical example is qcow2 that accepts - * asynchronous requests, but relies for manipulation of its metadata on - * synchronous bdrv_read/write that doesn't trigger any callbacks. - * - * However, these functions are often emulated using AIO which means that AIO - * callbacks must be run - but at the same time we must not run callbacks of - * other requests as they might start to modify metadata and corrupt the - * internal state of the caller of bdrv_read/write. - * - * To achieve the desired semantics we switch into a new AsyncContext. - * Callbacks must only be run if they belong to the current AsyncContext. - * Otherwise they need to be queued until their own context is active again. - * This is how you can make qemu_aio_wait() wait only for your own callbacks. - * - * The AsyncContexts form a stack. When you leave a AsyncContexts, you always - * return to the old ("parent") context. - */ -struct AsyncContext { - /* Consecutive number of the AsyncContext (position in the stack) */ - int id; - - /* Anchor of the list of Bottom Halves belonging to the context */ - struct QEMUBH *first_bh; - - /* Link to parent context */ - struct AsyncContext *parent; -}; - -/* The currently active AsyncContext */ -static struct AsyncContext *async_context = &(struct AsyncContext) { 0 }; - -/* - * Enter a new AsyncContext. Already scheduled Bottom Halves and AIO callbacks - * won't be called until this context is left again. - */ -void async_context_push(void) -{ - struct AsyncContext *new = qemu_mallocz(sizeof(*new)); - new->parent = async_context; - new->id = async_context->id + 1; - async_context = new; -} - -/* Run queued AIO completions and destroy Bottom Half */ -static void bh_run_aio_completions(void *opaque) -{ - QEMUBH **bh = opaque; - qemu_bh_delete(*bh); - qemu_free(bh); - qemu_aio_process_queue(); -} -/* - * Leave the currently active AsyncContext. All Bottom Halves belonging to the - * old context are executed before changing the context. - */ -void async_context_pop(void) -{ - struct AsyncContext *old = async_context; - QEMUBH **bh; - - /* Flush the bottom halves, we don't want to lose them */ - while (qemu_bh_poll()); - - /* Switch back to the parent context */ - async_context = async_context->parent; - qemu_free(old); - - if (async_context == NULL) { - abort(); - } - - /* Schedule BH to run any queued AIO completions as soon as possible */ - bh = qemu_malloc(sizeof(*bh)); - *bh = qemu_bh_new(bh_run_aio_completions, bh); - qemu_bh_schedule(*bh); -} - -/* - * Returns the ID of the currently active AsyncContext - */ -int get_async_context_id(void) -{ - return async_context->id; -} +/* Anchor of the list of Bottom Halves belonging to the context */ +static struct QEMUBH *first_bh; /***********************************************************/ /* bottom halves (can be seen as timers which expire ASAP) */ @@ -127,21 +44,25 @@ struct QEMUBH { QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque) { QEMUBH *bh; - bh = qemu_mallocz(sizeof(QEMUBH)); + bh = g_malloc0(sizeof(QEMUBH)); bh->cb = cb; bh->opaque = opaque; - bh->next = async_context->first_bh; - async_context->first_bh = bh; + bh->next = first_bh; + first_bh = bh; return bh; } int qemu_bh_poll(void) { - QEMUBH *bh, **bhp; + QEMUBH *bh, **bhp, *next; int ret; + static int nesting = 0; + + nesting++; ret = 0; - for (bh = async_context->first_bh; bh; bh = bh->next) { + for (bh = first_bh; bh; bh = next) { + next = bh->next; if (!bh->deleted && bh->scheduled) { bh->scheduled = 0; if (!bh->idle) @@ -151,15 +72,20 @@ int qemu_bh_poll(void) } } + nesting--; + /* remove deleted bhs */ - bhp = &async_context->first_bh; - while (*bhp) { - bh = *bhp; - if (bh->deleted) { - *bhp = bh->next; - qemu_free(bh); - } else - bhp = &bh->next; + if (!nesting) { + bhp = &first_bh; + while (*bhp) { + bh = *bhp; + if (bh->deleted) { + *bhp = bh->next; + g_free(bh); + } else { + bhp = &bh->next; + } + } } return ret; @@ -198,7 +124,7 @@ void qemu_bh_update_timeout(int *timeout) { QEMUBH *bh; - for (bh = async_context->first_bh; bh; bh = bh->next) { + for (bh = first_bh; bh; bh = bh->next) { if (!bh->deleted && bh->scheduled) { if (bh->idle) { /* idle bottom halves will be polled at least diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 4d72014..cb45b49 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -136,7 +136,7 @@ static void alsa_fini_poll (struct pollhlp *hlp) for (i = 0; i < hlp->count; ++i) { qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL); } - qemu_free (pfds); + g_free (pfds); } hlp->pfds = NULL; hlp->count = 0; @@ -260,7 +260,7 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask) if (err < 0) { alsa_logerr (err, "Could not initialize poll mode\n" "Could not obtain poll descriptors\n"); - qemu_free (pfds); + g_free (pfds); return -1; } @@ -288,7 +288,7 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask) while (i--) { qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL); } - qemu_free (pfds); + g_free (pfds); return -1; } } @@ -816,7 +816,7 @@ static void alsa_fini_out (HWVoiceOut *hw) alsa_anal_close (&alsa->handle, &alsa->pollhlp); if (alsa->pcm_buf) { - qemu_free (alsa->pcm_buf); + g_free (alsa->pcm_buf); alsa->pcm_buf = NULL; } } @@ -979,7 +979,7 @@ static void alsa_fini_in (HWVoiceIn *hw) alsa_anal_close (&alsa->handle, &alsa->pollhlp); if (alsa->pcm_buf) { - qemu_free (alsa->pcm_buf); + g_free (alsa->pcm_buf); alsa->pcm_buf = NULL; } } diff --git a/audio/audio.c b/audio/audio.c index 1729c0b..cf1a30e 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -39,6 +39,11 @@ #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown" +#ifdef CONFIG_MARU +#include "../tizen/src/debug_ch.h" +MULTI_DEBUG_CHANNEL(tizen, qemu_audio); +#endif + /* Order of CONFIG_AUDIO_DRIVERS is import. The 1st one is the one used by default, that is the reason that we generate the list. @@ -196,7 +201,7 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size) return NULL; } - return qemu_mallocz (len); + return g_malloc0 (len); } static char *audio_alloc_prefix (const char *s) @@ -210,7 +215,7 @@ static char *audio_alloc_prefix (const char *s) } len = strlen (s); - r = qemu_malloc (len + sizeof (qemu_prefix)); + r = g_malloc (len + sizeof (qemu_prefix)); u = r + sizeof (qemu_prefix) - 1; @@ -339,11 +344,15 @@ void AUD_vlog (const char *cap, const char *fmt, va_list ap) monitor_vprintf(default_mon, fmt, ap); } else { +#ifdef CONFIG_MARU + TRACE(fmt, ap); +#else if (cap) { fprintf (stderr, "%s: ", cap); } vfprintf (stderr, fmt, ap); +#endif } } @@ -425,7 +434,7 @@ static void audio_print_options (const char *prefix, printf (" %s\n", opt->descr); } - qemu_free (uprefix); + g_free (uprefix); } static void audio_process_options (const char *prefix, @@ -462,7 +471,7 @@ static void audio_process_options (const char *prefix, * (includes trailing zero) + zero + underscore (on behalf of * sizeof) */ optlen = len + preflen + sizeof (qemu_prefix) + 1; - optname = qemu_malloc (optlen); + optname = g_malloc (optlen); pstrcpy (optname, optlen, qemu_prefix); @@ -507,7 +516,7 @@ static void audio_process_options (const char *prefix, opt->overriddenp = &opt->overridden; } *opt->overriddenp = !def; - qemu_free (optname); + g_free (optname); } } @@ -778,7 +787,7 @@ static void audio_detach_capture (HWVoiceOut *hw) QLIST_REMOVE (sw, entries); QLIST_REMOVE (sc, entries); - qemu_free (sc); + g_free (sc); if (was_active) { /* We have removed soft voice from the capture: this might have changed the overall status of the capture @@ -818,7 +827,7 @@ static int audio_attach_capture (HWVoiceOut *hw) sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq); if (!sw->rate) { dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw)); - qemu_free (sw); + g_free (sw); return -1; } QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries); @@ -1114,7 +1123,7 @@ static int audio_is_timer_needed (void) static void audio_reset_timer (AudioState *s) { if (audio_is_timer_needed ()) { - qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1); + qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1); } else { qemu_del_timer (s->ts); @@ -1743,7 +1752,7 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv) } static void audio_vm_change_state_handler (void *opaque, int running, - int reason) + RunState state) { AudioState *s = opaque; HWVoiceOut *hwo = NULL; @@ -1820,7 +1829,7 @@ static void audio_init (void) QLIST_INIT (&s->cap_head); atexit (audio_atexit); - s->ts = qemu_new_timer (vm_clock, audio_timer, s); + s->ts = qemu_new_timer_ns (vm_clock, audio_timer, s); if (!s->ts) { hw_error("Could not create audio timer\n"); } @@ -1872,6 +1881,31 @@ static void audio_init (void) } } +#ifdef CONFIG_MARU +// Try to avoid certain wave out locking action in recent Windows... +// If wave out is locked (because nothing is wired to output jack, ...), +// QEMU can find voice out device, but open will failed. And it will cause guest audio lock-up. +// So, we test whether opening is success or not. +// It can not prevent lock-up caused by runtime voice out lock. +// To prevent it, QEMU audio backend structure must be changed. +// We should do it, but now we used simple fix temporarily. + HWVoiceOut* hw = audio_calloc(AUDIO_FUNC, 1, s->drv->voice_size_out); + if (!hw) { + dolog ("Can not allocate voice `%s' size %d\n", + s->drv->name, s->drv->voice_size_out); + } + if(s->drv->pcm_ops->init_out(hw, &conf.fixed_out.settings)) { + INFO("Host audio out [%s] is malfunction. Change to noaudio driver\n", + s->drv->name); + done = 0; + } + else { + INFO("Host audio out [%s] is normal.\n", s->drv->name); + s->drv->pcm_ops->fini_out(hw); + } + g_free(hw); +#endif + if (!done) { done = !audio_driver_init (s, &no_audio_driver); if (!done) { @@ -1907,7 +1941,7 @@ static void audio_init (void) void AUD_register_card (const char *name, QEMUSoundCard *card) { audio_init (); - card->name = qemu_strdup (name); + card->name = g_strdup (name); memset (&card->entries, 0, sizeof (card->entries)); QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries); } @@ -1915,7 +1949,7 @@ void AUD_register_card (const char *name, QEMUSoundCard *card) void AUD_remove_card (QEMUSoundCard *card) { QLIST_REMOVE (card, entries); - qemu_free (card->name); + g_free (card->name); } @@ -2000,11 +2034,11 @@ CaptureVoiceOut *AUD_add_capture ( return cap; err3: - qemu_free (cap->hw.mix_buf); + g_free (cap->hw.mix_buf); err2: - qemu_free (cap); + g_free (cap); err1: - qemu_free (cb); + g_free (cb); err0: return NULL; } @@ -2018,7 +2052,7 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque) if (cb->opaque == cb_opaque) { cb->ops.destroy (cb_opaque); QLIST_REMOVE (cb, entries); - qemu_free (cb); + g_free (cb); if (!cap->cb_head.lh_first) { SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1; @@ -2036,11 +2070,11 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque) } QLIST_REMOVE (sw, entries); QLIST_REMOVE (sc, entries); - qemu_free (sc); + g_free (sc); sw = sw1; } QLIST_REMOVE (cap, entries); - qemu_free (cap); + g_free (cap); } return; } diff --git a/audio/audio_pt_int.c b/audio/audio_pt_int.c index 908c569..9a9c306 100644 --- a/audio/audio_pt_int.c +++ b/audio/audio_pt_int.c @@ -6,8 +6,6 @@ #include "audio_int.h" #include "audio_pt_int.h" -#include - static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err, const char *fmt, ...) { diff --git a/audio/audio_template.h b/audio/audio_template.h index fd4469e..e62a713 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -72,7 +72,7 @@ static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv) static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) { if (HWBUF) { - qemu_free (HWBUF); + g_free (HWBUF); } HWBUF = NULL; @@ -93,7 +93,7 @@ static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw) static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) { if (sw->buf) { - qemu_free (sw->buf); + g_free (sw->buf); } if (sw->rate) { @@ -123,7 +123,7 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq); #endif if (!sw->rate) { - qemu_free (sw->buf); + g_free (sw->buf); sw->buf = NULL; return -1; } @@ -160,10 +160,10 @@ static int glue (audio_pcm_sw_init_, TYPE) ( [sw->info.swap_endianness] [audio_bits_to_index (sw->info.bits)]; - sw->name = qemu_strdup (name); + sw->name = g_strdup (name); err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw); if (err) { - qemu_free (sw->name); + g_free (sw->name); sw->name = NULL; } return err; @@ -173,7 +173,7 @@ static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw) { glue (audio_pcm_sw_free_resources_, TYPE) (sw); if (sw->name) { - qemu_free (sw->name); + g_free (sw->name); sw->name = NULL; } } @@ -201,7 +201,7 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp) glue (s->nb_hw_voices_, TYPE) += 1; glue (audio_pcm_hw_free_resources_ ,TYPE) (hw); glue (hw->pcm_ops->fini_, TYPE) (hw); - qemu_free (hw); + g_free (hw); *hwp = NULL; } } @@ -300,7 +300,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) err1: glue (hw->pcm_ops->fini_, TYPE) (hw); err0: - qemu_free (hw); + g_free (hw); return NULL; } @@ -368,7 +368,7 @@ err3: glue (audio_pcm_hw_del_sw_, TYPE) (sw); glue (audio_pcm_hw_gc_, TYPE) (&hw); err2: - qemu_free (sw); + g_free (sw); err1: return NULL; } @@ -378,7 +378,7 @@ static void glue (audio_close_, TYPE) (SW *sw) glue (audio_pcm_sw_fini_, TYPE) (sw); glue (audio_pcm_hw_del_sw_, TYPE) (sw); glue (audio_pcm_hw_gc_, TYPE) (&sw->hw); - qemu_free (sw); + g_free (sw); } void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw) diff --git a/audio/coreaudio.c b/audio/coreaudio.c index 0a26413..5964c62 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -56,7 +56,7 @@ typedef struct coreaudioVoiceOut { static void coreaudio_logstatus (OSStatus status) { - char *str = "BUG"; + const char *str = "BUG"; switch(status) { case kAudioHardwareNoError: @@ -104,7 +104,7 @@ static void coreaudio_logstatus (OSStatus status) break; default: - AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status); + AUD_log (AUDIO_CAP, "Reason: status code %" PRId32 "\n", (int32_t)status); return; } @@ -360,8 +360,8 @@ static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as) &core->audioDevicePropertyBufferFrameSize); if (status != kAudioHardwareNoError) { coreaudio_logerr2 (status, typ, - "Could not set device buffer frame size %ld\n", - core->audioDevicePropertyBufferFrameSize); + "Could not set device buffer frame size %" PRIu32 "\n", + (uint32_t)core->audioDevicePropertyBufferFrameSize); return -1; } diff --git a/audio/esdaudio.c b/audio/esdaudio.c index ff97b39..bd6e1cc 100644 --- a/audio/esdaudio.c +++ b/audio/esdaudio.c @@ -246,7 +246,7 @@ static int qesd_init_out (HWVoiceOut *hw, struct audsettings *as) esd->fd = -1; fail1: - qemu_free (esd->pcm_buf); + g_free (esd->pcm_buf); esd->pcm_buf = NULL; return -1; } @@ -270,7 +270,7 @@ static void qesd_fini_out (HWVoiceOut *hw) audio_pt_fini (&esd->pt, AUDIO_FUNC); - qemu_free (esd->pcm_buf); + g_free (esd->pcm_buf); esd->pcm_buf = NULL; } @@ -453,7 +453,7 @@ static int qesd_init_in (HWVoiceIn *hw, struct audsettings *as) esd->fd = -1; fail1: - qemu_free (esd->pcm_buf); + g_free (esd->pcm_buf); esd->pcm_buf = NULL; return -1; } @@ -477,7 +477,7 @@ static void qesd_fini_in (HWVoiceIn *hw) audio_pt_fini (&esd->pt, AUDIO_FUNC); - qemu_free (esd->pcm_buf); + g_free (esd->pcm_buf); esd->pcm_buf = NULL; } diff --git a/audio/fmodaudio.c b/audio/fmodaudio.c index c34cf53..fabf84d 100644 --- a/audio/fmodaudio.c +++ b/audio/fmodaudio.c @@ -343,7 +343,7 @@ static void fmod_fini_out (HWVoiceOut *hw) static int fmod_init_out (HWVoiceOut *hw, struct audsettings *as) { - int bits16, mode, channel; + int mode, channel; FMODVoiceOut *fmd = (FMODVoiceOut *) hw; struct audsettings obt_as = *as; @@ -374,7 +374,6 @@ static int fmod_init_out (HWVoiceOut *hw, struct audsettings *as) /* FMOD always operates on little endian frames? */ obt_as.endianness = 0; audio_pcm_init_info (&hw->info, &obt_as); - bits16 = (mode & FSOUND_16BITS) != 0; hw->samples = conf.nb_samples; return 0; } @@ -405,7 +404,7 @@ static int fmod_ctl_out (HWVoiceOut *hw, int cmd, ...) static int fmod_init_in (HWVoiceIn *hw, struct audsettings *as) { - int bits16, mode; + int mode; FMODVoiceIn *fmd = (FMODVoiceIn *) hw; struct audsettings obt_as = *as; @@ -432,7 +431,6 @@ static int fmod_init_in (HWVoiceIn *hw, struct audsettings *as) /* FMOD always operates on little endian frames? */ obt_as.endianness = 0; audio_pcm_init_info (&hw->info, &obt_as); - bits16 = (mode & FSOUND_16BITS) != 0; hw->samples = conf.nb_samples; return 0; } diff --git a/audio/mixeng.c b/audio/mixeng.c index 4a9e8eb..5446be6 100644 --- a/audio/mixeng.c +++ b/audio/mixeng.c @@ -326,7 +326,7 @@ void *st_rate_start (int inrate, int outrate) void st_rate_stop (void *opaque) { - qemu_free (opaque); + g_free (opaque); } void mixeng_clear (struct st_sample *buf, int len) diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h index a2d0ef8..e644c23 100644 --- a/audio/mixeng_template.h +++ b/audio/mixeng_template.h @@ -46,7 +46,7 @@ static mixeng_real inline glue (conv_, ET) (IN_T v) #endif #else /* !RECIPROCAL */ #ifdef SIGNED - return nv / (mixeng_real) (IN_MAX - IN_MIN); + return nv / (mixeng_real) ((mixeng_real) IN_MAX - IN_MIN); #else return (nv - HALF) / (mixeng_real) IN_MAX; #endif @@ -63,7 +63,7 @@ static IN_T inline glue (clip_, ET) (mixeng_real v) } #ifdef SIGNED - return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN))); + return ENDIAN_CONVERT ((IN_T) (v * ((mixeng_real) IN_MAX - IN_MIN))); #else return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF)); #endif diff --git a/audio/noaudio.c b/audio/noaudio.c index 0304094..54958f8 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -46,7 +46,7 @@ static int no_run_out (HWVoiceOut *hw, int live) int64_t ticks; int64_t bytes; - now = qemu_get_clock (vm_clock); + now = qemu_get_clock_ns (vm_clock); ticks = now - no->old_ticks; bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ()); bytes = audio_MIN (bytes, INT_MAX); @@ -102,7 +102,7 @@ static int no_run_in (HWVoiceIn *hw) int samples = 0; if (dead) { - int64_t now = qemu_get_clock (vm_clock); + int64_t now = qemu_get_clock_ns (vm_clock); int64_t ticks = now - no->old_ticks; int64_t bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ()); diff --git a/audio/ossaudio.c b/audio/ossaudio.c index b49e102..df51b7c 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -508,7 +508,7 @@ static void oss_fini_out (HWVoiceOut *hw) } } else { - qemu_free (oss->pcm_buf); + g_free (oss->pcm_buf); } oss->pcm_buf = NULL; } @@ -741,7 +741,7 @@ static void oss_fini_in (HWVoiceIn *hw) oss_anal_close (&oss->fd); if (oss->pcm_buf) { - qemu_free (oss->pcm_buf); + g_free (oss->pcm_buf); oss->pcm_buf = NULL; } } diff --git a/audio/paaudio.c b/audio/paaudio.c index fb4510e..d1f3912 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -339,7 +339,7 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as) return 0; fail3: - qemu_free (pa->pcm_buf); + g_free (pa->pcm_buf); pa->pcm_buf = NULL; fail2: pa_simple_free (pa->s); @@ -394,7 +394,7 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as) return 0; fail3: - qemu_free (pa->pcm_buf); + g_free (pa->pcm_buf); pa->pcm_buf = NULL; fail2: pa_simple_free (pa->s); @@ -419,7 +419,7 @@ static void qpa_fini_out (HWVoiceOut *hw) } audio_pt_fini (&pa->pt, AUDIO_FUNC); - qemu_free (pa->pcm_buf); + g_free (pa->pcm_buf); pa->pcm_buf = NULL; } @@ -439,7 +439,7 @@ static void qpa_fini_in (HWVoiceIn *hw) } audio_pt_fini (&pa->pt, AUDIO_FUNC); - qemu_free (pa->pcm_buf); + g_free (pa->pcm_buf); pa->pcm_buf = NULL; } diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index b74dcfa..d24daa5 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -32,7 +32,6 @@ #elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) #include #endif -#include #endif #define AUDIO_CAP "sdl" @@ -139,36 +138,36 @@ static int aud_to_sdlfmt (audfmt_e fmt) } } -static int sdl_to_audfmt (int sdlfmt, audfmt_e *fmt, int *endianess) +static int sdl_to_audfmt(int sdlfmt, audfmt_e *fmt, int *endianness) { switch (sdlfmt) { case AUDIO_S8: - *endianess = 0; + *endianness = 0; *fmt = AUD_FMT_S8; break; case AUDIO_U8: - *endianess = 0; + *endianness = 0; *fmt = AUD_FMT_U8; break; case AUDIO_S16LSB: - *endianess = 0; + *endianness = 0; *fmt = AUD_FMT_S16; break; case AUDIO_U16LSB: - *endianess = 0; + *endianness = 0; *fmt = AUD_FMT_U16; break; case AUDIO_S16MSB: - *endianess = 1; + *endianness = 1; *fmt = AUD_FMT_S16; break; case AUDIO_U16MSB: - *endianess = 1; + *endianness = 1; *fmt = AUD_FMT_U16; break; @@ -338,7 +337,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as) SDLVoiceOut *sdl = (SDLVoiceOut *) hw; SDLAudioState *s = &glob_sdl; SDL_AudioSpec req, obt; - int endianess; + int endianness; int err; audfmt_e effective_fmt; struct audsettings obt_as; @@ -354,7 +353,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as) return -1; } - err = sdl_to_audfmt (obt.format, &effective_fmt, &endianess); + err = sdl_to_audfmt(obt.format, &effective_fmt, &endianness); if (err) { sdl_close (s); return -1; @@ -363,7 +362,7 @@ static int sdl_init_out (HWVoiceOut *hw, struct audsettings *as) obt_as.freq = obt.freq; obt_as.nchannels = obt.channels; obt_as.fmt = effective_fmt; - obt_as.endianness = endianess; + obt_as.endianness = endianness; audio_pcm_init_info (&hw->info, &obt_as); hw->samples = obt.samples; diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index a5c0d6b..f972110 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -81,7 +81,7 @@ static void spice_audio_fini (void *opaque) static void rate_start (SpiceRateCtl *rate) { memset (rate, 0, sizeof (*rate)); - rate->start_ticks = qemu_get_clock (vm_clock); + rate->start_ticks = qemu_get_clock_ns (vm_clock); } static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate) @@ -91,7 +91,7 @@ static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate) int64_t bytes; int64_t samples; - now = qemu_get_clock (vm_clock); + now = qemu_get_clock_ns (vm_clock); ticks = now - rate->start_ticks; bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ()); samples = (bytes - rate->bytes_sent) >> info->shift; diff --git a/audio/wavaudio.c b/audio/wavaudio.c index c522be4..a449b51 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -30,7 +30,7 @@ typedef struct WAVVoiceOut { HWVoiceOut hw; - QEMUFile *f; + FILE *f; int64_t old_ticks; void *pcm_buf; int total_samples; @@ -52,7 +52,7 @@ static int wav_run_out (HWVoiceOut *hw, int live) int rpos, decr, samples; uint8_t *dst; struct st_sample *src; - int64_t now = qemu_get_clock (vm_clock); + int64_t now = qemu_get_clock_ns (vm_clock); int64_t ticks = now - wav->old_ticks; int64_t bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ()); @@ -76,7 +76,10 @@ static int wav_run_out (HWVoiceOut *hw, int live) dst = advance (wav->pcm_buf, rpos << hw->info.shift); hw->clip (dst, src, convert_samples); - qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift); + if (fwrite (dst, convert_samples << hw->info.shift, 1, wav->f) != 1) { + dolog ("wav_run_out: fwrite of %d bytes failed\nReaons: %s\n", + convert_samples << hw->info.shift, strerror (errno)); + } rpos = (rpos + convert_samples) % hw->samples; samples -= convert_samples; @@ -152,16 +155,20 @@ static int wav_init_out (HWVoiceOut *hw, struct audsettings *as) le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4); le_store (hdr + 32, 1 << (bits16 + stereo), 2); - wav->f = qemu_fopen (conf.wav_path, "wb"); + wav->f = fopen (conf.wav_path, "wb"); if (!wav->f) { dolog ("Failed to open wave file `%s'\nReason: %s\n", conf.wav_path, strerror (errno)); - qemu_free (wav->pcm_buf); + g_free (wav->pcm_buf); wav->pcm_buf = NULL; return -1; } - qemu_put_buffer (wav->f, hdr, sizeof (hdr)); + if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) { + dolog ("wav_init_out: failed to write header\nReason: %s\n", + strerror(errno)); + return -1; + } return 0; } @@ -180,16 +187,35 @@ static void wav_fini_out (HWVoiceOut *hw) le_store (rlen, rifflen, 4); le_store (dlen, datalen, 4); - qemu_fseek (wav->f, 4, SEEK_SET); - qemu_put_buffer (wav->f, rlen, 4); - - qemu_fseek (wav->f, 32, SEEK_CUR); - qemu_put_buffer (wav->f, dlen, 4); + if (fseek (wav->f, 4, SEEK_SET)) { + dolog ("wav_fini_out: fseek to rlen failed\nReason: %s\n", + strerror(errno)); + goto doclose; + } + if (fwrite (rlen, 4, 1, wav->f) != 1) { + dolog ("wav_fini_out: failed to write rlen\nReason: %s\n", + strerror (errno)); + goto doclose; + } + if (fseek (wav->f, 32, SEEK_CUR)) { + dolog ("wav_fini_out: fseek to dlen failed\nReason: %s\n", + strerror (errno)); + goto doclose; + } + if (fwrite (dlen, 4, 1, wav->f) != 1) { + dolog ("wav_fini_out: failed to write dlen\nReaons: %s\n", + strerror (errno)); + goto doclose; + } - qemu_fclose (wav->f); + doclose: + if (fclose (wav->f)) { + dolog ("wav_fini_out: fclose %p failed\nReason: %s\n", + wav->f, strerror (errno)); + } wav->f = NULL; - qemu_free (wav->pcm_buf); + g_free (wav->pcm_buf); wav->pcm_buf = NULL; } diff --git a/audio/wavcapture.c b/audio/wavcapture.c index 1f49cd1..4f785f5 100644 --- a/audio/wavcapture.c +++ b/audio/wavcapture.c @@ -3,7 +3,7 @@ #include "audio.h" typedef struct { - QEMUFile *f; + FILE *f; int bytes; char *path; int freq; @@ -35,27 +35,50 @@ static void wav_destroy (void *opaque) uint8_t dlen[4]; uint32_t datalen = wav->bytes; uint32_t rifflen = datalen + 36; + Monitor *mon = cur_mon; if (wav->f) { le_store (rlen, rifflen, 4); le_store (dlen, datalen, 4); - qemu_fseek (wav->f, 4, SEEK_SET); - qemu_put_buffer (wav->f, rlen, 4); - - qemu_fseek (wav->f, 32, SEEK_CUR); - qemu_put_buffer (wav->f, dlen, 4); - qemu_fclose (wav->f); + if (fseek (wav->f, 4, SEEK_SET)) { + monitor_printf (mon, "wav_destroy: rlen fseek failed\nReason: %s\n", + strerror (errno)); + goto doclose; + } + if (fwrite (rlen, 4, 1, wav->f) != 1) { + monitor_printf (mon, "wav_destroy: rlen fwrite failed\nReason %s\n", + strerror (errno)); + goto doclose; + } + if (fseek (wav->f, 32, SEEK_CUR)) { + monitor_printf (mon, "wav_destroy: dlen fseek failed\nReason %s\n", + strerror (errno)); + goto doclose; + } + if (fwrite (dlen, 1, 4, wav->f) != 4) { + monitor_printf (mon, "wav_destroy: dlen fwrite failed\nReason %s\n", + strerror (errno)); + goto doclose; + } + doclose: + if (fclose (wav->f)) { + fprintf (stderr, "wav_destroy: fclose failed: %s", + strerror (errno)); + } } - qemu_free (wav->path); + g_free (wav->path); } static void wav_capture (void *opaque, void *buf, int size) { WAVState *wav = opaque; - qemu_put_buffer (wav->f, buf, size); + if (fwrite (buf, size, 1, wav->f) != 1) { + monitor_printf (cur_mon, "wav_capture: fwrite error\nReason: %s", + strerror (errno)); + } wav->bytes += size; } @@ -71,9 +94,9 @@ static void wav_capture_info (void *opaque) WAVState *wav = opaque; char *path = wav->path; - monitor_printf(cur_mon, "Capturing audio(%d,%d,%d) to %s: %d bytes\n", - wav->freq, wav->bits, wav->nchannels, - path ? path : "", wav->bytes); + monitor_printf (cur_mon, "Capturing audio(%d,%d,%d) to %s: %d bytes\n", + wav->freq, wav->bits, wav->nchannels, + path ? path : "", wav->bytes); } static struct capture_ops wav_capture_ops = { @@ -98,13 +121,13 @@ int wav_start_capture (CaptureState *s, const char *path, int freq, CaptureVoiceOut *cap; if (bits != 8 && bits != 16) { - monitor_printf(mon, "incorrect bit count %d, must be 8 or 16\n", bits); + monitor_printf (mon, "incorrect bit count %d, must be 8 or 16\n", bits); return -1; } if (nchannels != 1 && nchannels != 2) { - monitor_printf(mon, "incorrect channel count %d, must be 1 or 2\n", - nchannels); + monitor_printf (mon, "incorrect channel count %d, must be 1 or 2\n", + nchannels); return -1; } @@ -120,7 +143,7 @@ int wav_start_capture (CaptureState *s, const char *path, int freq, ops.capture = wav_capture; ops.destroy = wav_destroy; - wav = qemu_mallocz (sizeof (*wav)); + wav = g_malloc0 (sizeof (*wav)); shift = bits16 + stereo; hdr[34] = bits16 ? 0x10 : 0x08; @@ -130,32 +153,42 @@ int wav_start_capture (CaptureState *s, const char *path, int freq, le_store (hdr + 28, freq << shift, 4); le_store (hdr + 32, 1 << shift, 2); - wav->f = qemu_fopen (path, "wb"); + wav->f = fopen (path, "wb"); if (!wav->f) { - monitor_printf(mon, "Failed to open wave file `%s'\nReason: %s\n", - path, strerror (errno)); - qemu_free (wav); + monitor_printf (mon, "Failed to open wave file `%s'\nReason: %s\n", + path, strerror (errno)); + g_free (wav); return -1; } - wav->path = qemu_strdup (path); + wav->path = g_strdup (path); wav->bits = bits; wav->nchannels = nchannels; wav->freq = freq; - qemu_put_buffer (wav->f, hdr, sizeof (hdr)); + if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) { + monitor_printf (mon, "Failed to write header\nReason: %s\n", + strerror (errno)); + goto error_free; + } cap = AUD_add_capture (&as, &ops, wav); if (!cap) { - monitor_printf(mon, "Failed to add audio capture\n"); - qemu_free (wav->path); - qemu_fclose (wav->f); - qemu_free (wav); - return -1; + monitor_printf (mon, "Failed to add audio capture\n"); + goto error_free; } wav->cap = cap; s->opaque = wav; s->ops = wav_capture_ops; return 0; + +error_free: + g_free (wav->path); + if (fclose (wav->f)) { + monitor_printf (mon, "Failed to close wave file\nReason: %s\n", + strerror (errno)); + } + g_free (wav); + return -1; } diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c index e5ad3c6..3d6f8f7 100644 --- a/audio/winwaveaudio.c +++ b/audio/winwaveaudio.c @@ -222,9 +222,9 @@ static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as) return 0; err4: - qemu_free (wave->pcm_buf); + g_free (wave->pcm_buf); err3: - qemu_free (wave->hdrs); + g_free (wave->hdrs); err2: winwave_anal_close_out (wave); err1: @@ -310,10 +310,10 @@ static void winwave_fini_out (HWVoiceOut *hw) wave->event = NULL; } - qemu_free (wave->pcm_buf); + g_free (wave->pcm_buf); wave->pcm_buf = NULL; - qemu_free (wave->hdrs); + g_free (wave->hdrs); wave->hdrs = NULL; } @@ -349,6 +349,9 @@ static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...) else { hw->poll_mode = 0; } +#if defined(CONFIG_MARU) + wave->paused = 0; +#else if (wave->paused) { mr = waveOutRestart (wave->hwo); if (mr != MMSYSERR_NOERROR) { @@ -356,15 +359,23 @@ static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...) } wave->paused = 0; } +#endif } return 0; case VOICE_DISABLE: if (!wave->paused) { +#if defined(CONFIG_MARU) + mr = waveOutReset (wave->hwo); + if (mr != MMSYSERR_NOERROR) { + winwave_logerr (mr, "waveOutReset"); + } +#else mr = waveOutPause (wave->hwo); if (mr != MMSYSERR_NOERROR) { winwave_logerr (mr, "waveOutPause"); } +#endif else { wave->paused = 1; } @@ -511,9 +522,9 @@ static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as) return 0; err4: - qemu_free (wave->pcm_buf); + g_free (wave->pcm_buf); err3: - qemu_free (wave->hdrs); + g_free (wave->hdrs); err2: winwave_anal_close_in (wave); err1: @@ -550,10 +561,10 @@ static void winwave_fini_in (HWVoiceIn *hw) wave->event = NULL; } - qemu_free (wave->pcm_buf); + g_free (wave->pcm_buf); wave->pcm_buf = NULL; - qemu_free (wave->hdrs); + g_free (wave->hdrs); wave->hdrs = NULL; } diff --git a/balloon.c b/balloon.c index 0021fef..e1cd5fa 100644 --- a/balloon.c +++ b/balloon.c @@ -1,7 +1,9 @@ /* - * QEMU System Emulator + * Generic Balloon handlers and management * * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2011 Amit Shah * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,106 +24,80 @@ * THE SOFTWARE. */ -#include "sysemu.h" #include "monitor.h" -#include "qjson.h" -#include "qint.h" #include "cpu-common.h" #include "kvm.h" #include "balloon.h" #include "trace.h" +#include "qmp-commands.h" +static QEMUBalloonEvent *balloon_event_fn; +static QEMUBalloonStatus *balloon_stat_fn; +static void *balloon_opaque; -static QEMUBalloonEvent *qemu_balloon_event; -void *qemu_balloon_event_opaque; - -void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque) +int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, + QEMUBalloonStatus *stat_func, void *opaque) { - qemu_balloon_event = func; - qemu_balloon_event_opaque = opaque; + if (balloon_event_fn || balloon_stat_fn || balloon_opaque) { + /* We're already registered one balloon handler. How many can + * a guest really have? + */ + error_report("Another balloon device already registered"); + return -1; + } + balloon_event_fn = event_func; + balloon_stat_fn = stat_func; + balloon_opaque = opaque; + return 0; } -int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque) +void qemu_remove_balloon_handler(void *opaque) { - if (qemu_balloon_event) { - trace_balloon_event(qemu_balloon_event_opaque, target); - qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque); - return 1; - } else { - return 0; + if (balloon_opaque != opaque) { + return; } + balloon_event_fn = NULL; + balloon_stat_fn = NULL; + balloon_opaque = NULL; } -int qemu_balloon_status(MonitorCompletion cb, void *opaque) +static int qemu_balloon(ram_addr_t target) { - if (qemu_balloon_event) { - qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque); - return 1; - } else { + if (!balloon_event_fn) { return 0; } + trace_balloon_event(balloon_opaque, target); + balloon_event_fn(balloon_opaque, target); + return 1; } -static void print_balloon_stat(const char *key, QObject *obj, void *opaque) +static int qemu_balloon_status(BalloonInfo *info) { - Monitor *mon = opaque; - - if (strcmp(key, "actual")) - monitor_printf(mon, ",%s=%" PRId64, key, - qint_get_int(qobject_to_qint(obj))); -} - -void monitor_print_balloon(Monitor *mon, const QObject *data) -{ - QDict *qdict; - - qdict = qobject_to_qdict(data); - if (!qdict_haskey(qdict, "actual")) - return; - - monitor_printf(mon, "balloon: actual=%" PRId64, - qdict_get_int(qdict, "actual") >> 20); - qdict_iter(qdict, print_balloon_stat, mon); - monitor_printf(mon, "\n"); + if (!balloon_stat_fn) { + return 0; + } + balloon_stat_fn(balloon_opaque, info); + return 1; } -/** - * do_info_balloon(): Balloon information - * - * Make an asynchronous request for balloon info. When the request completes - * a QDict will be returned according to the following specification: - * - * - "actual": current balloon value in bytes - * The following fields may or may not be present: - * - "mem_swapped_in": Amount of memory swapped in (bytes) - * - "mem_swapped_out": Amount of memory swapped out (bytes) - * - "major_page_faults": Number of major faults - * - "minor_page_faults": Number of minor faults - * - "free_mem": Total amount of free and unused memory (bytes) - * - "total_mem": Total amount of available memory (bytes) - * - * Example: - * - * { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0, - * "major_page_faults": 142, "minor_page_faults": 239245, - * "free_mem": 1014185984, "total_mem": 1044668416 } - */ -int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque) +BalloonInfo *qmp_query_balloon(Error **errp) { - int ret; + BalloonInfo *info; if (kvm_enabled() && !kvm_has_sync_mmu()) { - qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon"); - return -1; + error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon"); + return NULL; } - ret = qemu_balloon_status(cb, opaque); - if (!ret) { - qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon"); - return -1; + info = g_malloc0(sizeof(*info)); + + if (qemu_balloon_status(info) == 0) { + error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon"); + qapi_free_BalloonInfo(info); + return NULL; } - return 0; + return info; } /** @@ -130,6 +106,7 @@ int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque) int do_balloon(Monitor *mon, const QDict *params, MonitorCompletion cb, void *opaque) { + int64_t target; int ret; if (kvm_enabled() && !kvm_has_sync_mmu()) { @@ -137,7 +114,12 @@ int do_balloon(Monitor *mon, const QDict *params, return -1; } - ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque); + target = qdict_get_int(params, "value"); + if (target <= 0) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "target", "a size"); + return -1; + } + ret = qemu_balloon(target); if (ret == 0) { qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon"); return -1; diff --git a/balloon.h b/balloon.h index d478e28..b36abea 100644 --- a/balloon.h +++ b/balloon.h @@ -15,18 +15,15 @@ #define _QEMU_BALLOON_H #include "monitor.h" +#include "qapi-types.h" -typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target, - MonitorCompletion cb, void *cb_data); +typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target); +typedef void (QEMUBalloonStatus)(void *opaque, BalloonInfo *info); -void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque); +int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, + QEMUBalloonStatus *stat_func, void *opaque); +void qemu_remove_balloon_handler(void *opaque); -int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque); - -int qemu_balloon_status(MonitorCompletion cb, void *opaque); - -void monitor_print_balloon(Monitor *mon, const QObject *data); -int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque); int do_balloon(Monitor *mon, const QDict *params, MonitorCompletion cb, void *opaque); diff --git a/block-migration.c b/block-migration.c index 8218bac..5f10486 100644 --- a/block-migration.c +++ b/block-migration.c @@ -62,7 +62,6 @@ typedef struct BlkMigBlock { QEMUIOVector qiov; BlockDriverAIOCB *aiocb; int ret; - int64_t time; QSIMPLEQ_ENTRY(BlkMigBlock) entry; } BlkMigBlock; @@ -78,6 +77,7 @@ typedef struct BlkMigState { int prev_progress; int bulk_completed; long double total_time; + long double prev_time_offset; int reads; } BlkMigState; @@ -131,16 +131,10 @@ uint64_t blk_mig_bytes_total(void) return sum << BDRV_SECTOR_BITS; } -static inline void add_avg_read_time(int64_t time) -{ - block_mig_state.reads++; - block_mig_state.total_time += time; -} - static inline long double compute_read_bwidth(void) { assert(block_mig_state.total_time != 0); - return (block_mig_state.reads * BLOCK_SIZE)/ block_mig_state.total_time; + return (block_mig_state.reads / block_mig_state.total_time) * BLOCK_SIZE; } static int bmds_aio_inflight(BlkMigDevState *bmds, int64_t sector) @@ -186,18 +180,19 @@ static void alloc_aio_bitmap(BlkMigDevState *bmds) BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; - bmds->aio_bitmap = qemu_mallocz(bitmap_size); + bmds->aio_bitmap = g_malloc0(bitmap_size); } static void blk_mig_read_cb(void *opaque, int ret) { + long double curr_time = qemu_get_clock_ns(rt_clock); BlkMigBlock *blk = opaque; blk->ret = ret; - blk->time = qemu_get_clock_ns(rt_clock) - blk->time; - - add_avg_read_time(blk->time); + block_mig_state.reads++; + block_mig_state.total_time += (curr_time - block_mig_state.prev_time_offset); + block_mig_state.prev_time_offset = curr_time; QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry); bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0); @@ -240,8 +235,8 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f, nr_sectors = total_sectors - cur_sector; } - blk = qemu_malloc(sizeof(BlkMigBlock)); - blk->buf = qemu_malloc(BLOCK_SIZE); + blk = g_malloc(sizeof(BlkMigBlock)); + blk->buf = g_malloc(BLOCK_SIZE); blk->bmds = bmds; blk->sector = cur_sector; blk->nr_sectors = nr_sectors; @@ -250,7 +245,9 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f, blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); - blk->time = qemu_get_clock_ns(rt_clock); + if (block_mig_state.submitted == 0) { + block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock); + } blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, nr_sectors, blk_mig_read_cb, blk); @@ -266,9 +263,9 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f, error: monitor_printf(mon, "Error reading sector %" PRId64 "\n", cur_sector); - qemu_file_set_error(f); - qemu_free(blk->buf); - qemu_free(blk); + qemu_file_set_error(f, -EIO); + g_free(blk->buf); + g_free(blk); return 0; } @@ -293,7 +290,7 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs) return; } - bmds = qemu_mallocz(sizeof(BlkMigDevState)); + bmds = g_malloc0(sizeof(BlkMigDevState)); bmds->bs = bs; bmds->bulk_completed = 0; bmds->total_sectors = sectors; @@ -386,6 +383,7 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, int64_t total_sectors = bmds->total_sectors; int64_t sector; int nr_sectors; + int ret = -EIO; for (sector = bmds->cur_dirty; sector < bmds->total_sectors;) { if (bmds_aio_inflight(bmds, sector)) { @@ -398,8 +396,8 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, } else { nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK; } - blk = qemu_malloc(sizeof(BlkMigBlock)); - blk->buf = qemu_malloc(BLOCK_SIZE); + blk = g_malloc(sizeof(BlkMigBlock)); + blk->buf = g_malloc(BLOCK_SIZE); blk->bmds = bmds; blk->sector = sector; blk->nr_sectors = nr_sectors; @@ -409,7 +407,9 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE; qemu_iovec_init_external(&blk->qiov, &blk->iov, 1); - blk->time = qemu_get_clock_ns(rt_clock); + if (block_mig_state.submitted == 0) { + block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock); + } blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov, nr_sectors, blk_mig_read_cb, blk); @@ -419,14 +419,14 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, block_mig_state.submitted++; bmds_set_aio_inflight(bmds, sector, nr_sectors, 1); } else { - if (bdrv_read(bmds->bs, sector, blk->buf, - nr_sectors) < 0) { + ret = bdrv_read(bmds->bs, sector, blk->buf, nr_sectors); + if (ret < 0) { goto error; } blk_send(f, blk); - qemu_free(blk->buf); - qemu_free(blk); + g_free(blk->buf); + g_free(blk); } bdrv_reset_dirty(bmds->bs, sector, nr_sectors); @@ -440,9 +440,9 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, error: monitor_printf(mon, "Error reading sector %" PRId64 "\n", sector); - qemu_file_set_error(f); - qemu_free(blk->buf); - qemu_free(blk); + qemu_file_set_error(f, ret); + g_free(blk->buf); + g_free(blk); return 0; } @@ -474,14 +474,14 @@ static void flush_blks(QEMUFile* f) break; } if (blk->ret < 0) { - qemu_file_set_error(f); + qemu_file_set_error(f, blk->ret); break; } blk_send(f, blk); QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry); - qemu_free(blk->buf); - qemu_free(blk); + g_free(blk->buf); + g_free(blk); block_mig_state.read_done--; block_mig_state.transferred++; @@ -521,7 +521,7 @@ static int is_stage2_completed(void) if ((remaining_dirty / bwidth) <= migrate_max_downtime()) { - /* finish stage2 because we think that we can finish remaing work + /* finish stage2 because we think that we can finish remaining work below max_downtime */ return 1; @@ -542,14 +542,14 @@ static void blk_mig_cleanup(Monitor *mon) QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry); bdrv_set_in_use(bmds->bs, 0); drive_put_ref(drive_get_by_blockdev(bmds->bs)); - qemu_free(bmds->aio_bitmap); - qemu_free(bmds); + g_free(bmds->aio_bitmap); + g_free(bmds); } while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) { QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry); - qemu_free(blk->buf); - qemu_free(blk); + g_free(blk->buf); + g_free(blk); } monitor_printf(mon, "\n"); @@ -557,6 +557,8 @@ static void blk_mig_cleanup(Monitor *mon) static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) { + int ret; + DPRINTF("Enter save live stage %d submitted %d transferred %d\n", stage, block_mig_state.submitted, block_mig_state.transferred); @@ -580,9 +582,10 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) flush_blks(f); - if (qemu_file_has_error(f)) { + ret = qemu_file_get_error(f); + if (ret) { blk_mig_cleanup(mon); - return 0; + return ret; } blk_mig_reset_dirty_cursor(); @@ -608,9 +611,10 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) flush_blks(f); - if (qemu_file_has_error(f)) { + ret = qemu_file_get_error(f); + if (ret) { blk_mig_cleanup(mon); - return 0; + return ret; } } @@ -625,8 +629,9 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) /* report completion */ qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS); - if (qemu_file_has_error(f)) { - return 0; + ret = qemu_file_get_error(f); + if (ret) { + return ret; } monitor_printf(mon, "Block migration completed\n"); @@ -647,6 +652,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) uint8_t *buf; int64_t total_sectors = 0; int nr_sectors; + int ret; do { addr = qemu_get_be64(f); @@ -655,7 +661,6 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) addr >>= BDRV_SECTOR_BITS; if (flags & BLK_MIG_FLAG_DEVICE_BLOCK) { - int ret; /* get device name */ len = qemu_get_byte(f); qemu_get_buffer(f, (uint8_t *)device_name, len); @@ -672,7 +677,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) bs_prev = bs; total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; if (total_sectors <= 0) { - error_report("Error getting length of block device %s\n", + error_report("Error getting length of block device %s", device_name); return -EINVAL; } @@ -684,12 +689,12 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK; } - buf = qemu_malloc(BLOCK_SIZE); + buf = g_malloc(BLOCK_SIZE); qemu_get_buffer(f, buf, BLOCK_SIZE); ret = bdrv_write(bs, addr, buf, nr_sectors); - qemu_free(buf); + g_free(buf); if (ret < 0) { return ret; } @@ -705,8 +710,9 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) fprintf(stderr, "Unknown flags\n"); return -EINVAL; } - if (qemu_file_has_error(f)) { - return -EIO; + ret = qemu_file_get_error(f); + if (ret != 0) { + return ret; } } while (!(flags & BLK_MIG_FLAG_EOS)); diff --git a/block.c b/block.c index b203875..d015887 100644 --- a/block.c +++ b/block.c @@ -27,7 +27,9 @@ #include "monitor.h" #include "block_int.h" #include "module.h" -#include "qemu-objects.h" +#include "qjson.h" +#include "qemu-coroutine.h" +#include "qmp-commands.h" #ifdef CONFIG_BSD #include @@ -43,20 +45,33 @@ #include #endif +#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ + +static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load); static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); -static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque); -static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque); -static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors); -static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors); +static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + QEMUIOVector *iov); +static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + QEMUIOVector *iov); +static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); +static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); +static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, + int64_t sector_num, + QEMUIOVector *qiov, + int nb_sectors, + BlockDriverCompletionFunc *cb, + void *opaque, + bool is_write); +static void coroutine_fn bdrv_co_do_rw(void *opaque); static QTAILQ_HEAD(, BlockDriverState) bdrv_states = QTAILQ_HEAD_INITIALIZER(bdrv_states); @@ -169,19 +184,21 @@ void path_combine(char *dest, int dest_size, void bdrv_register(BlockDriver *bdrv) { - if (!bdrv->bdrv_aio_readv) { - /* add AIO emulation layer */ - bdrv->bdrv_aio_readv = bdrv_aio_readv_em; - bdrv->bdrv_aio_writev = bdrv_aio_writev_em; - } else if (!bdrv->bdrv_read) { - /* add synchronous IO emulation layer */ - bdrv->bdrv_read = bdrv_read_em; - bdrv->bdrv_write = bdrv_write_em; + /* Block drivers without coroutine functions need emulation */ + if (!bdrv->bdrv_co_readv) { + bdrv->bdrv_co_readv = bdrv_co_readv_em; + bdrv->bdrv_co_writev = bdrv_co_writev_em; + + /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if + * the block driver lacks aio we need to emulate that too. + */ + if (!bdrv->bdrv_aio_readv) { + /* add AIO emulation layer */ + bdrv->bdrv_aio_readv = bdrv_aio_readv_em; + bdrv->bdrv_aio_writev = bdrv_aio_writev_em; + } } - if (!bdrv->bdrv_aio_flush) - bdrv->bdrv_aio_flush = bdrv_aio_flush_em; - QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); } @@ -190,11 +207,12 @@ BlockDriverState *bdrv_new(const char *device_name) { BlockDriverState *bs; - bs = qemu_mallocz(sizeof(BlockDriverState)); + bs = g_malloc0(sizeof(BlockDriverState)); pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); if (device_name[0] != '\0') { QTAILQ_INSERT_TAIL(&bdrv_states, bs, list); } + bdrv_iostatus_disable(bs); return bs; } @@ -412,6 +430,33 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) return 0; } +/** + * Set open flags for a given cache mode + * + * Return 0 on success, -1 if the cache mode was invalid. + */ +int bdrv_parse_cache_flags(const char *mode, int *flags) +{ + *flags &= ~BDRV_O_CACHE_MASK; + + if (!strcmp(mode, "off") || !strcmp(mode, "none")) { + *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; + } else if (!strcmp(mode, "directsync")) { + *flags |= BDRV_O_NOCACHE; + } else if (!strcmp(mode, "writeback")) { + *flags |= BDRV_O_CACHE_WB; + } else if (!strcmp(mode, "unsafe")) { + *flags |= BDRV_O_CACHE_WB; + *flags |= BDRV_O_NO_FLUSH; + } else if (!strcmp(mode, "writethrough")) { + /* this is the default */ + } else { + return -1; + } + + return 0; +} + /* * Common part for opening disk images and files */ @@ -422,31 +467,28 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename, assert(drv != NULL); + trace_bdrv_open_common(bs, filename, flags, drv->format_name); + bs->file = NULL; bs->total_sectors = 0; bs->encrypted = 0; bs->valid_key = 0; + bs->sg = 0; bs->open_flags = flags; - /* buffer_alignment defaulted to 512, drivers can change this value */ + bs->growable = 0; bs->buffer_alignment = 512; pstrcpy(bs->filename, sizeof(bs->filename), filename); + bs->backing_file[0] = '\0'; if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { return -ENOTSUP; } bs->drv = drv; - bs->opaque = qemu_mallocz(drv->instance_size); + bs->opaque = g_malloc0(drv->instance_size); - /* - * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a - * write cache to the guest. We do need the fdatasync to flush - * out transactions for block allocations, and we maybe have a - * volatile write cache in our backing device to deal with. - */ - if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE)) - bs->enable_write_cache = 1; + bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB); /* * Clear flags that are internal to the block layer before opening the @@ -455,12 +497,14 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename, open_flags = flags & ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); /* - * Snapshots should be writeable. + * Snapshots should be writable. */ if (bs->is_temporary) { open_flags |= BDRV_O_RDWR; } + bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR); + /* Open the image, either directly or using a protocol */ if (drv->bdrv_file_open) { ret = drv->bdrv_file_open(bs, filename, open_flags); @@ -475,8 +519,6 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename, goto free_and_fail; } - bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR); - ret = refresh_total_sectors(bs, bs->total_sectors); if (ret < 0) { goto free_and_fail; @@ -494,7 +536,7 @@ free_and_fail: bdrv_delete(bs->file); bs->file = NULL; } - qemu_free(bs->opaque); + g_free(bs->opaque); bs->opaque = NULL; bs->drv = NULL; return ret; @@ -532,6 +574,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv) { int ret; + char tmp_filename[PATH_MAX]; if (flags & BDRV_O_SNAPSHOT) { BlockDriverState *bs1; @@ -539,7 +582,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; - char tmp_filename[PATH_MAX]; char backing_filename[PATH_MAX]; /* if snapshot, we create a temporary backing file and open it @@ -642,10 +684,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, } if (!bdrv_key_required(bs)) { - /* call the change callback */ - bs->media_changed = 1; - if (bs->change_cb) - bs->change_cb(bs->change_opaque, CHANGE_MEDIA); + bdrv_dev_change_media_cb(bs, true); } return 0; @@ -668,7 +707,7 @@ void bdrv_close(BlockDriverState *bs) bs->backing_hd = NULL; } bs->drv->bdrv_close(bs); - qemu_free(bs->opaque); + g_free(bs->opaque); #ifdef _WIN32 if (bs->is_temporary) { unlink(bs->filename); @@ -681,10 +720,7 @@ void bdrv_close(BlockDriverState *bs) bdrv_close(bs->file); } - /* call the change callback */ - bs->media_changed = 1; - if (bs->change_cb) - bs->change_cb(bs->change_opaque, CHANGE_MEDIA); + bdrv_dev_change_media_cb(bs, false); } } @@ -709,7 +745,7 @@ void bdrv_make_anon(BlockDriverState *bs) void bdrv_delete(BlockDriverState *bs) { - assert(!bs->peer); + assert(!bs->dev); /* remove from list, if necessary */ bdrv_make_anon(bs); @@ -720,34 +756,101 @@ void bdrv_delete(BlockDriverState *bs) } assert(bs != bs_snapshots); - qemu_free(bs); + g_free(bs); } -int bdrv_attach(BlockDriverState *bs, DeviceState *qdev) +int bdrv_attach_dev(BlockDriverState *bs, void *dev) +/* TODO change to DeviceState *dev when all users are qdevified */ { - if (bs->peer) { + if (bs->dev) { return -EBUSY; } - bs->peer = qdev; + bs->dev = dev; + bdrv_iostatus_reset(bs); return 0; } -void bdrv_detach(BlockDriverState *bs, DeviceState *qdev) +/* TODO qdevified devices don't use this, remove when devices are qdevified */ +void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev) +{ + if (bdrv_attach_dev(bs, dev) < 0) { + abort(); + } +} + +void bdrv_detach_dev(BlockDriverState *bs, void *dev) +/* TODO change to DeviceState *dev when all users are qdevified */ +{ + assert(bs->dev == dev); + bs->dev = NULL; + bs->dev_ops = NULL; + bs->dev_opaque = NULL; + bs->buffer_alignment = 512; +} + +/* TODO change to return DeviceState * when all users are qdevified */ +void *bdrv_get_attached_dev(BlockDriverState *bs) +{ + return bs->dev; +} + +void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, + void *opaque) +{ + bs->dev_ops = ops; + bs->dev_opaque = opaque; + if (bdrv_dev_has_removable_media(bs) && bs == bs_snapshots) { + bs_snapshots = NULL; + } +} + +static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load) +{ + if (bs->dev_ops && bs->dev_ops->change_media_cb) { + bs->dev_ops->change_media_cb(bs->dev_opaque, load); + } +} + +bool bdrv_dev_has_removable_media(BlockDriverState *bs) +{ + return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb); +} + +void bdrv_dev_eject_request(BlockDriverState *bs, bool force) +{ + if (bs->dev_ops && bs->dev_ops->eject_request_cb) { + bs->dev_ops->eject_request_cb(bs->dev_opaque, force); + } +} + +bool bdrv_dev_is_tray_open(BlockDriverState *bs) +{ + if (bs->dev_ops && bs->dev_ops->is_tray_open) { + return bs->dev_ops->is_tray_open(bs->dev_opaque); + } + return false; +} + +static void bdrv_dev_resize_cb(BlockDriverState *bs) { - assert(bs->peer == qdev); - bs->peer = NULL; + if (bs->dev_ops && bs->dev_ops->resize_cb) { + bs->dev_ops->resize_cb(bs->dev_opaque); + } } -DeviceState *bdrv_get_attached(BlockDriverState *bs) +bool bdrv_dev_is_medium_locked(BlockDriverState *bs) { - return bs->peer; + if (bs->dev_ops && bs->dev_ops->is_medium_locked) { + return bs->dev_ops->is_medium_locked(bs->dev_opaque); + } + return false; } /* * Run consistency checks on an image * * Returns 0 if the check could be completed (it doesn't mean that the image is - * free of errors) or -errno when an internal error occured. The results of the + * free of errors) or -errno when an internal error occurred. The results of the * check are stored in res. */ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res) @@ -816,7 +919,7 @@ int bdrv_commit(BlockDriverState *bs) } total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; - buf = qemu_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); + buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); for (sector = 0; sector < total_sectors; sector += n) { if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) { @@ -846,7 +949,7 @@ int bdrv_commit(BlockDriverState *bs) bdrv_flush(bs->backing_hd); ro_cleanup: - qemu_free(buf); + g_free(buf); if (ro) { /* re-open as RO */ @@ -926,18 +1029,69 @@ static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num, nb_sectors * BDRV_SECTOR_SIZE); } +typedef struct RwCo { + BlockDriverState *bs; + int64_t sector_num; + int nb_sectors; + QEMUIOVector *qiov; + bool is_write; + int ret; +} RwCo; + +static void coroutine_fn bdrv_rw_co_entry(void *opaque) +{ + RwCo *rwco = opaque; + + if (!rwco->is_write) { + rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num, + rwco->nb_sectors, rwco->qiov); + } else { + rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num, + rwco->nb_sectors, rwco->qiov); + } +} + +/* + * Process a synchronous request using coroutines + */ +static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, + int nb_sectors, bool is_write) +{ + QEMUIOVector qiov; + struct iovec iov = { + .iov_base = (void *)buf, + .iov_len = nb_sectors * BDRV_SECTOR_SIZE, + }; + Coroutine *co; + RwCo rwco = { + .bs = bs, + .sector_num = sector_num, + .nb_sectors = nb_sectors, + .qiov = &qiov, + .is_write = is_write, + .ret = NOT_DONE, + }; + + qemu_iovec_init_external(&qiov, &iov, 1); + + if (qemu_in_coroutine()) { + /* Fast-path if already in coroutine context */ + bdrv_rw_co_entry(&rwco); + } else { + co = qemu_coroutine_create(bdrv_rw_co_entry); + qemu_coroutine_enter(co, &rwco); + while (rwco.ret == NOT_DONE) { + qemu_aio_wait(); + } + } + return rwco.ret; +} + /* return < 0 if error. See bdrv_write() for the return codes */ int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { - BlockDriver *drv = bs->drv; - - if (!drv) - return -ENOMEDIUM; - if (bdrv_check_request(bs, sector_num, nb_sectors)) - return -EIO; - - return drv->bdrv_read(bs, sector_num, buf, nb_sectors); + return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false); } static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num, @@ -977,23 +1131,7 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num, int bdrv_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { - BlockDriver *drv = bs->drv; - if (!bs->drv) - return -ENOMEDIUM; - if (bs->read_only) - return -EACCES; - if (bdrv_check_request(bs, sector_num, nb_sectors)) - return -EIO; - - if (bs->dirty_bitmap) { - set_dirty_bitmap(bs, sector_num, nb_sectors, 1); - } - - if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { - bs->wr_highest_sector = sector_num + nb_sectors - 1; - } - - return drv->bdrv_write(bs, sector_num, buf, nb_sectors); + return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true); } int bdrv_pread(BlockDriverState *bs, int64_t offset, @@ -1106,8 +1244,8 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, return ret; } - /* No flush needed for cache=writethrough, it uses O_DSYNC */ - if ((bs->open_flags & BDRV_O_CACHE_MASK) != 0) { + /* No flush needed for cache modes that use O_DSYNC */ + if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) { bdrv_flush(bs); } @@ -1115,16 +1253,69 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, } /* - * Writes to the file and ensures that no writes are reordered across this - * request (acts as a barrier) - * - * Returns 0 on success, -errno in error cases. + * Handle a read request in coroutine context + */ +static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) +{ + BlockDriver *drv = bs->drv; + + if (!drv) { + return -ENOMEDIUM; + } + if (bdrv_check_request(bs, sector_num, nb_sectors)) { + return -EIO; + } + + return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); +} + +int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) +{ + trace_bdrv_co_readv(bs, sector_num, nb_sectors); + + return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov); +} + +/* + * Handle a write request in coroutine context */ -int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) +{ + BlockDriver *drv = bs->drv; + int ret; + + if (!bs->drv) { + return -ENOMEDIUM; + } + if (bs->read_only) { + return -EACCES; + } + if (bdrv_check_request(bs, sector_num, nb_sectors)) { + return -EIO; + } + + ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov); + + if (bs->dirty_bitmap) { + set_dirty_bitmap(bs, sector_num, nb_sectors, 1); + } + + if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { + bs->wr_highest_sector = sector_num + nb_sectors - 1; + } + + return ret; +} + +int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { - return bdrv_pwrite_sync(bs, BDRV_SECTOR_SIZE * sector_num, - buf, BDRV_SECTOR_SIZE * nb_sectors); + trace_bdrv_co_writev(bs, sector_num, nb_sectors); + + return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov); } /** @@ -1145,14 +1336,31 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset) ret = drv->bdrv_truncate(bs, offset); if (ret == 0) { ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); - if (bs->change_cb) { - bs->change_cb(bs->change_opaque, CHANGE_SIZE); - } + bdrv_dev_resize_cb(bs); } return ret; } /** + * Length of a allocated file in bytes. Sparse files are counted by actual + * allocated space. Return < 0 if error or unknown. + */ +int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) +{ + BlockDriver *drv = bs->drv; + if (!drv) { + return -ENOMEDIUM; + } + if (drv->bdrv_get_allocated_file_size) { + return drv->bdrv_get_allocated_file_size(bs); + } + if (bs->file) { + return bdrv_get_allocated_file_size(bs->file); + } + return -ENOTSUP; +} + +/** * Length of a file in bytes. Return < 0 if error or unknown. */ int64_t bdrv_getlength(BlockDriverState *bs) @@ -1161,14 +1369,12 @@ int64_t bdrv_getlength(BlockDriverState *bs) if (!drv) return -ENOMEDIUM; - /* Fixed size devices use the total_sectors value for speed instead of - issuing a length query (like lseek) on each call. Also, legacy block - drivers don't provide a bdrv_getlength function and must use - total_sectors. */ - if (!bs->growable || !drv->bdrv_getlength) { - return bs->total_sectors * BDRV_SECTOR_SIZE; + if (bs->growable || bdrv_dev_has_removable_media(bs)) { + if (drv->bdrv_getlength) { + return drv->bdrv_getlength(bs); + } } - return drv->bdrv_getlength(bs); + return bs->total_sectors * BDRV_SECTOR_SIZE; } /* return 0 as number of sectors if no device present or error */ @@ -1194,7 +1400,7 @@ struct partition { uint8_t end_cyl; /* end cylinder */ uint32_t start_sect; /* starting sector counting from 0 */ uint32_t nr_sects; /* nr of sectors in partition */ -} __attribute__((packed)); +} QEMU_PACKED; /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ static int guess_disk_lchs(BlockDriverState *bs, @@ -1307,13 +1513,6 @@ void bdrv_set_geometry_hint(BlockDriverState *bs, bs->secs = secs; } -void bdrv_set_type_hint(BlockDriverState *bs, int type) -{ - bs->type = type; - bs->removable = ((type == BDRV_TYPE_CDROM || - type == BDRV_TYPE_FLOPPY)); -} - void bdrv_set_translation_hint(BlockDriverState *bs, int translation) { bs->translation = translation; @@ -1327,9 +1526,107 @@ void bdrv_get_geometry_hint(BlockDriverState *bs, *psecs = bs->secs; } -int bdrv_get_type_hint(BlockDriverState *bs) +/* Recognize floppy formats */ +typedef struct FDFormat { + FDriveType drive; + uint8_t last_sect; + uint8_t max_track; + uint8_t max_head; +} FDFormat; + +static const FDFormat fd_formats[] = { + /* First entry is default format */ + /* 1.44 MB 3"1/2 floppy disks */ + { FDRIVE_DRV_144, 18, 80, 1, }, + { FDRIVE_DRV_144, 20, 80, 1, }, + { FDRIVE_DRV_144, 21, 80, 1, }, + { FDRIVE_DRV_144, 21, 82, 1, }, + { FDRIVE_DRV_144, 21, 83, 1, }, + { FDRIVE_DRV_144, 22, 80, 1, }, + { FDRIVE_DRV_144, 23, 80, 1, }, + { FDRIVE_DRV_144, 24, 80, 1, }, + /* 2.88 MB 3"1/2 floppy disks */ + { FDRIVE_DRV_288, 36, 80, 1, }, + { FDRIVE_DRV_288, 39, 80, 1, }, + { FDRIVE_DRV_288, 40, 80, 1, }, + { FDRIVE_DRV_288, 44, 80, 1, }, + { FDRIVE_DRV_288, 48, 80, 1, }, + /* 720 kB 3"1/2 floppy disks */ + { FDRIVE_DRV_144, 9, 80, 1, }, + { FDRIVE_DRV_144, 10, 80, 1, }, + { FDRIVE_DRV_144, 10, 82, 1, }, + { FDRIVE_DRV_144, 10, 83, 1, }, + { FDRIVE_DRV_144, 13, 80, 1, }, + { FDRIVE_DRV_144, 14, 80, 1, }, + /* 1.2 MB 5"1/4 floppy disks */ + { FDRIVE_DRV_120, 15, 80, 1, }, + { FDRIVE_DRV_120, 18, 80, 1, }, + { FDRIVE_DRV_120, 18, 82, 1, }, + { FDRIVE_DRV_120, 18, 83, 1, }, + { FDRIVE_DRV_120, 20, 80, 1, }, + /* 720 kB 5"1/4 floppy disks */ + { FDRIVE_DRV_120, 9, 80, 1, }, + { FDRIVE_DRV_120, 11, 80, 1, }, + /* 360 kB 5"1/4 floppy disks */ + { FDRIVE_DRV_120, 9, 40, 1, }, + { FDRIVE_DRV_120, 9, 40, 0, }, + { FDRIVE_DRV_120, 10, 41, 1, }, + { FDRIVE_DRV_120, 10, 42, 1, }, + /* 320 kB 5"1/4 floppy disks */ + { FDRIVE_DRV_120, 8, 40, 1, }, + { FDRIVE_DRV_120, 8, 40, 0, }, + /* 360 kB must match 5"1/4 better than 3"1/2... */ + { FDRIVE_DRV_144, 9, 80, 0, }, + /* end */ + { FDRIVE_DRV_NONE, -1, -1, 0, }, +}; + +void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads, + int *max_track, int *last_sect, + FDriveType drive_in, FDriveType *drive) { - return bs->type; + const FDFormat *parse; + uint64_t nb_sectors, size; + int i, first_match, match; + + bdrv_get_geometry_hint(bs, nb_heads, max_track, last_sect); + if (*nb_heads != 0 && *max_track != 0 && *last_sect != 0) { + /* User defined disk */ + } else { + bdrv_get_geometry(bs, &nb_sectors); + match = -1; + first_match = -1; + for (i = 0; ; i++) { + parse = &fd_formats[i]; + if (parse->drive == FDRIVE_DRV_NONE) { + break; + } + if (drive_in == parse->drive || + drive_in == FDRIVE_DRV_NONE) { + size = (parse->max_head + 1) * parse->max_track * + parse->last_sect; + if (nb_sectors == size) { + match = i; + break; + } + if (first_match == -1) { + first_match = i; + } + } + } + if (match == -1) { + if (first_match == -1) { + match = 1; + } else { + match = first_match; + } + parse = &fd_formats[match]; + } + *nb_heads = parse->max_head + 1; + *max_track = parse->max_track; + *last_sect = parse->last_sect; + *drive = parse->drive; + } } int bdrv_get_translation_hint(BlockDriverState *bs) @@ -1349,19 +1646,6 @@ BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read) return is_read ? bs->on_read_error : bs->on_write_error; } -void bdrv_set_removable(BlockDriverState *bs, int removable) -{ - bs->removable = removable; - if (removable && bs == bs_snapshots) { - bs_snapshots = NULL; - } -} - -int bdrv_is_removable(BlockDriverState *bs) -{ - return bs->removable; -} - int bdrv_is_read_only(BlockDriverState *bs) { return bs->read_only; @@ -1377,15 +1661,6 @@ int bdrv_enable_write_cache(BlockDriverState *bs) return bs->enable_write_cache; } -/* XXX: no longer used */ -void bdrv_set_change_cb(BlockDriverState *bs, - void (*change_cb)(void *opaque, int reason), - void *opaque) -{ - bs->change_cb = change_cb; - bs->change_opaque = opaque; -} - int bdrv_is_encrypted(BlockDriverState *bs) { if (bs->backing_hd && bs->backing_hd->encrypted) @@ -1423,9 +1698,7 @@ int bdrv_set_key(BlockDriverState *bs, const char *key) } else if (!bs->valid_key) { bs->valid_key = 1; /* call the change callback now, we skipped it on open */ - bs->media_changed = 1; - if (bs->change_cb) - bs->change_cb(bs->change_opaque, CHANGE_MEDIA); + bdrv_dev_change_media_cb(bs, true); } return ret; } @@ -1483,36 +1756,12 @@ const char *bdrv_get_device_name(BlockDriverState *bs) return bs->device_name; } -int bdrv_flush(BlockDriverState *bs) -{ - if (bs->open_flags & BDRV_O_NO_FLUSH) { - return 0; - } - - if (bs->drv && bs->drv->bdrv_flush) { - return bs->drv->bdrv_flush(bs); - } - - /* - * Some block drivers always operate in either writethrough or unsafe mode - * and don't support bdrv_flush therefore. Usually qemu doesn't know how - * the server works (because the behaviour is hardcoded or depends on - * server-side configuration), so we can't ensure that everything is safe - * on disk. Returning an error doesn't work because that would break guests - * even if the server operates in writethrough mode. - * - * Let's hope the user knows what he's doing. - */ - return 0; -} - void bdrv_flush_all(void) { BlockDriverState *bs; QTAILQ_FOREACH(bs, &bdrv_states, list) { - if (bs->drv && !bdrv_is_read_only(bs) && - (!bdrv_is_removable(bs) || bdrv_is_inserted(bs))) { + if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) { bdrv_flush(bs); } } @@ -1529,17 +1778,6 @@ int bdrv_has_zero_init(BlockDriverState *bs) return 1; } -int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) -{ - if (!bs->drv) { - return -ENOMEDIUM; - } - if (!bs->drv->bdrv_discard) { - return 0; - } - return bs->drv->bdrv_discard(bs, sector_num, nb_sectors); -} - /* * Returns true iff the specified sector is present in the disk image. Drivers * not implementing the functionality are assumed to not support backing files, @@ -1596,167 +1834,105 @@ void bdrv_mon_event(const BlockDriverState *bdrv, qobject_decref(data); } -static void bdrv_print_dict(QObject *obj, void *opaque) +BlockInfoList *qmp_query_block(Error **errp) { - QDict *bs_dict; - Monitor *mon = opaque; - - bs_dict = qobject_to_qdict(obj); - - monitor_printf(mon, "%s: type=%s removable=%d", - qdict_get_str(bs_dict, "device"), - qdict_get_str(bs_dict, "type"), - qdict_get_bool(bs_dict, "removable")); + BlockInfoList *head = NULL, *cur_item = NULL; + BlockDriverState *bs; - if (qdict_get_bool(bs_dict, "removable")) { - monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked")); - } + QTAILQ_FOREACH(bs, &bdrv_states, list) { + BlockInfoList *info = g_malloc0(sizeof(*info)); - if (qdict_haskey(bs_dict, "inserted")) { - QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); + info->value = g_malloc0(sizeof(*info->value)); + info->value->device = g_strdup(bs->device_name); + info->value->type = g_strdup("unknown"); + info->value->locked = bdrv_dev_is_medium_locked(bs); + info->value->removable = bdrv_dev_has_removable_media(bs); - monitor_printf(mon, " file="); - monitor_print_filename(mon, qdict_get_str(qdict, "file")); - if (qdict_haskey(qdict, "backing_file")) { - monitor_printf(mon, " backing_file="); - monitor_print_filename(mon, qdict_get_str(qdict, "backing_file")); + if (bdrv_dev_has_removable_media(bs)) { + info->value->has_tray_open = true; + info->value->tray_open = bdrv_dev_is_tray_open(bs); } - monitor_printf(mon, " ro=%d drv=%s encrypted=%d", - qdict_get_bool(qdict, "ro"), - qdict_get_str(qdict, "drv"), - qdict_get_bool(qdict, "encrypted")); - } else { - monitor_printf(mon, " [not inserted]"); - } - - monitor_printf(mon, "\n"); -} - -void bdrv_info_print(Monitor *mon, const QObject *data) -{ - qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); -} - -void bdrv_info(Monitor *mon, QObject **ret_data) -{ - QList *bs_list; - BlockDriverState *bs; - - bs_list = qlist_new(); - QTAILQ_FOREACH(bs, &bdrv_states, list) { - QObject *bs_obj; - const char *type = "unknown"; - - switch(bs->type) { - case BDRV_TYPE_HD: - type = "hd"; - break; - case BDRV_TYPE_CDROM: - type = "cdrom"; - break; - case BDRV_TYPE_FLOPPY: - type = "floppy"; - break; - } - - bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, " - "'removable': %i, 'locked': %i }", - bs->device_name, type, bs->removable, - bs->locked); + if (bdrv_iostatus_is_enabled(bs)) { + info->value->has_io_status = true; + info->value->io_status = bs->iostatus; + } if (bs->drv) { - QObject *obj; - QDict *bs_dict = qobject_to_qdict(bs_obj); - - obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, " - "'encrypted': %i }", - bs->filename, bs->read_only, - bs->drv->format_name, - bdrv_is_encrypted(bs)); - if (bs->backing_file[0] != '\0') { - QDict *qdict = qobject_to_qdict(obj); - qdict_put(qdict, "backing_file", - qstring_from_str(bs->backing_file)); + info->value->has_inserted = true; + info->value->inserted = g_malloc0(sizeof(*info->value->inserted)); + info->value->inserted->file = g_strdup(bs->filename); + info->value->inserted->ro = bs->read_only; + info->value->inserted->drv = g_strdup(bs->drv->format_name); + info->value->inserted->encrypted = bs->encrypted; + if (bs->backing_file[0]) { + info->value->inserted->has_backing_file = true; + info->value->inserted->backing_file = g_strdup(bs->backing_file); } + } - qdict_put_obj(bs_dict, "inserted", obj); + /* XXX: waiting for the qapi to support GSList */ + if (!cur_item) { + head = cur_item = info; + } else { + cur_item->next = info; + cur_item = info; } - qlist_append_obj(bs_list, bs_obj); } - *ret_data = QOBJECT(bs_list); -} - -static void bdrv_stats_iter(QObject *data, void *opaque) -{ - QDict *qdict; - Monitor *mon = opaque; - - qdict = qobject_to_qdict(data); - monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); - - qdict = qobject_to_qdict(qdict_get(qdict, "stats")); - monitor_printf(mon, " rd_bytes=%" PRId64 - " wr_bytes=%" PRId64 - " rd_operations=%" PRId64 - " wr_operations=%" PRId64 - "\n", - qdict_get_int(qdict, "rd_bytes"), - qdict_get_int(qdict, "wr_bytes"), - qdict_get_int(qdict, "rd_operations"), - qdict_get_int(qdict, "wr_operations")); -} - -void bdrv_stats_print(Monitor *mon, const QObject *data) -{ - qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); + return head; } -static QObject* bdrv_info_stats_bs(BlockDriverState *bs) +/* Consider exposing this as a full fledged QMP command */ +static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp) { - QObject *res; - QDict *dict; + BlockStats *s; - res = qobject_from_jsonf("{ 'stats': {" - "'rd_bytes': %" PRId64 "," - "'wr_bytes': %" PRId64 "," - "'rd_operations': %" PRId64 "," - "'wr_operations': %" PRId64 "," - "'wr_highest_offset': %" PRId64 - "} }", - bs->rd_bytes, bs->wr_bytes, - bs->rd_ops, bs->wr_ops, - bs->wr_highest_sector * - (uint64_t)BDRV_SECTOR_SIZE); - dict = qobject_to_qdict(res); + s = g_malloc0(sizeof(*s)); - if (*bs->device_name) { - qdict_put(dict, "device", qstring_from_str(bs->device_name)); + if (bs->device_name[0]) { + s->has_device = true; + s->device = g_strdup(bs->device_name); } + s->stats = g_malloc0(sizeof(*s->stats)); + s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ]; + s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE]; + s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ]; + s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE]; + s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE; + s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH]; + s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE]; + s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ]; + s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH]; + if (bs->file) { - QObject *parent = bdrv_info_stats_bs(bs->file); - qdict_put_obj(dict, "parent", parent); + s->has_parent = true; + s->parent = qmp_query_blockstat(bs->file, NULL); } - return res; + return s; } -void bdrv_info_stats(Monitor *mon, QObject **ret_data) +BlockStatsList *qmp_query_blockstats(Error **errp) { - QObject *obj; - QList *devices; + BlockStatsList *head = NULL, *cur_item = NULL; BlockDriverState *bs; - devices = qlist_new(); - QTAILQ_FOREACH(bs, &bdrv_states, list) { - obj = bdrv_info_stats_bs(bs); - qlist_append_obj(devices, obj); + BlockStatsList *info = g_malloc0(sizeof(*info)); + info->value = qmp_query_blockstat(bs, NULL); + + /* XXX: waiting for the qapi to support GSList */ + if (!cur_item) { + head = cur_item = info; + } else { + cur_item->next = info; + cur_item = info; + } } - *ret_data = QOBJECT(devices); + return head; } const char *bdrv_get_encrypted_filename(BlockDriverState *bs) @@ -1772,11 +1948,7 @@ const char *bdrv_get_encrypted_filename(BlockDriverState *bs) void bdrv_get_backing_filename(BlockDriverState *bs, char *filename, int filename_size) { - if (!bs->backing_file) { - pstrcpy(filename, filename_size, ""); - } else { - pstrcpy(filename, filename_size, bs->backing_file); - } + pstrcpy(filename, filename_size, bs->backing_file); } int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, @@ -1852,7 +2024,7 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) int bdrv_can_snapshot(BlockDriverState *bs) { BlockDriver *drv = bs->drv; - if (!drv || bdrv_is_removable(bs) || bdrv_is_read_only(bs)) { + if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { return 0; } @@ -2042,7 +2214,6 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn) return buf; } - /**************************************************************/ /* async I/Os */ @@ -2050,101 +2221,20 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { - BlockDriver *drv = bs->drv; - BlockDriverAIOCB *ret; - trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); - if (!drv) - return NULL; - if (bdrv_check_request(bs, sector_num, nb_sectors)) - return NULL; - - ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors, - cb, opaque); - - if (ret) { - /* Update stats even though technically transfer has not happened. */ - bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE; - bs->rd_ops ++; - } - - return ret; -} - -typedef struct BlockCompleteData { - BlockDriverCompletionFunc *cb; - void *opaque; - BlockDriverState *bs; - int64_t sector_num; - int nb_sectors; -} BlockCompleteData; - -static void block_complete_cb(void *opaque, int ret) -{ - BlockCompleteData *b = opaque; - - if (b->bs->dirty_bitmap) { - set_dirty_bitmap(b->bs, b->sector_num, b->nb_sectors, 1); - } - b->cb(b->opaque, ret); - qemu_free(b); -} - -static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, - BlockDriverCompletionFunc *cb, - void *opaque) -{ - BlockCompleteData *blkdata = qemu_mallocz(sizeof(BlockCompleteData)); - - blkdata->bs = bs; - blkdata->cb = cb; - blkdata->opaque = opaque; - blkdata->sector_num = sector_num; - blkdata->nb_sectors = nb_sectors; - - return blkdata; + return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, + cb, opaque, false); } BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { - BlockDriver *drv = bs->drv; - BlockDriverAIOCB *ret; - BlockCompleteData *blk_cb_data; - trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); - if (!drv) - return NULL; - if (bs->read_only) - return NULL; - if (bdrv_check_request(bs, sector_num, nb_sectors)) - return NULL; - - if (bs->dirty_bitmap) { - blk_cb_data = blk_dirty_cb_alloc(bs, sector_num, nb_sectors, cb, - opaque); - cb = &block_complete_cb; - opaque = blk_cb_data; - } - - ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors, - cb, opaque); - - if (ret) { - /* Update stats even though technically transfer has not happened. */ - bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE; - bs->wr_ops ++; - if (bs->wr_highest_sector < sector_num + nb_sectors - 1) { - bs->wr_highest_sector = sector_num + nb_sectors - 1; - } - } - - return ret; + return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, + cb, opaque, true); } @@ -2169,7 +2259,7 @@ static void multiwrite_user_cb(MultiwriteCB *mcb) if (mcb->callbacks[i].free_qiov) { qemu_iovec_destroy(mcb->callbacks[i].free_qiov); } - qemu_free(mcb->callbacks[i].free_qiov); + g_free(mcb->callbacks[i].free_qiov); qemu_vfree(mcb->callbacks[i].free_buf); } } @@ -2187,7 +2277,7 @@ static void multiwrite_cb(void *opaque, int ret) mcb->num_requests--; if (mcb->num_requests == 0) { multiwrite_user_cb(mcb); - qemu_free(mcb); + g_free(mcb); } } @@ -2247,7 +2337,7 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, if (merge) { size_t size; - QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov)); + QEMUIOVector *qiov = g_malloc0(sizeof(*qiov)); qemu_iovec_init(qiov, reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1); @@ -2316,7 +2406,7 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) } // Create MultiwriteCB structure - mcb = qemu_mallocz(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); + mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks)); mcb->num_requests = 0; mcb->num_callbacks = num_reqs; @@ -2381,24 +2471,10 @@ fail: for (i = 0; i < mcb->num_callbacks; i++) { reqs[i].error = -EIO; } - qemu_free(mcb); + g_free(mcb); return -1; } -BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque) -{ - BlockDriver *drv = bs->drv; - - if (bs->open_flags & BDRV_O_NO_FLUSH) { - return bdrv_aio_noop_em(bs, cb, opaque); - } - - if (!drv) - return NULL; - return drv->bdrv_aio_flush(bs, cb, opaque); -} - void bdrv_aio_cancel(BlockDriverAIOCB *acb) { acb->pool->cancel(acb); @@ -2466,9 +2542,9 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, if (is_write) { qemu_iovec_to_buffer(acb->qiov, acb->bounce); - acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors); + acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors); } else { - acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors); + acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors); } qemu_bh_schedule(acb->bh); @@ -2490,112 +2566,125 @@ static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs, return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); } -static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque) + +typedef struct BlockDriverAIOCBCoroutine { + BlockDriverAIOCB common; + BlockRequest req; + bool is_write; + QEMUBH* bh; +} BlockDriverAIOCBCoroutine; + +static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb) { - BlockDriverAIOCBSync *acb; + qemu_aio_flush(); +} - acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); - acb->is_write = 1; /* don't bounce in the completion hadler */ - acb->qiov = NULL; - acb->bounce = NULL; - acb->ret = 0; +static AIOPool bdrv_em_co_aio_pool = { + .aiocb_size = sizeof(BlockDriverAIOCBCoroutine), + .cancel = bdrv_aio_co_cancel_em, +}; - if (!acb->bh) - acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); +static void bdrv_co_em_bh(void *opaque) +{ + BlockDriverAIOCBCoroutine *acb = opaque; - bdrv_flush(bs); - qemu_bh_schedule(acb->bh); - return &acb->common; + acb->common.cb(acb->common.opaque, acb->req.error); + qemu_bh_delete(acb->bh); + qemu_aio_release(acb); } -static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque) +/* Invoke bdrv_co_do_readv/bdrv_co_do_writev */ +static void coroutine_fn bdrv_co_do_rw(void *opaque) { - BlockDriverAIOCBSync *acb; - - acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque); - acb->is_write = 1; /* don't bounce in the completion handler */ - acb->qiov = NULL; - acb->bounce = NULL; - acb->ret = 0; + BlockDriverAIOCBCoroutine *acb = opaque; + BlockDriverState *bs = acb->common.bs; - if (!acb->bh) { - acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); + if (!acb->is_write) { + acb->req.error = bdrv_co_do_readv(bs, acb->req.sector, + acb->req.nb_sectors, acb->req.qiov); + } else { + acb->req.error = bdrv_co_do_writev(bs, acb->req.sector, + acb->req.nb_sectors, acb->req.qiov); } + acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); qemu_bh_schedule(acb->bh); - return &acb->common; } -/**************************************************************/ -/* sync block device emulation */ - -static void bdrv_rw_em_cb(void *opaque, int ret) +static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, + int64_t sector_num, + QEMUIOVector *qiov, + int nb_sectors, + BlockDriverCompletionFunc *cb, + void *opaque, + bool is_write) { - *(int *)opaque = ret; + Coroutine *co; + BlockDriverAIOCBCoroutine *acb; + + acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); + acb->req.sector = sector_num; + acb->req.nb_sectors = nb_sectors; + acb->req.qiov = qiov; + acb->is_write = is_write; + + co = qemu_coroutine_create(bdrv_co_do_rw); + qemu_coroutine_enter(co, acb); + + return &acb->common; } -#define NOT_DONE 0x7fffffff +static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque) +{ + BlockDriverAIOCBCoroutine *acb = opaque; + BlockDriverState *bs = acb->common.bs; + + acb->req.error = bdrv_co_flush(bs); + acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); + qemu_bh_schedule(acb->bh); +} -static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, + BlockDriverCompletionFunc *cb, void *opaque) { - int async_ret; - BlockDriverAIOCB *acb; - struct iovec iov; - QEMUIOVector qiov; + trace_bdrv_aio_flush(bs, opaque); - async_context_push(); + Coroutine *co; + BlockDriverAIOCBCoroutine *acb; - async_ret = NOT_DONE; - iov.iov_base = (void *)buf; - iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE; - qemu_iovec_init_external(&qiov, &iov, 1); - acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors, - bdrv_rw_em_cb, &async_ret); - if (acb == NULL) { - async_ret = -1; - goto fail; - } + acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); + co = qemu_coroutine_create(bdrv_aio_flush_co_entry); + qemu_coroutine_enter(co, acb); - while (async_ret == NOT_DONE) { - qemu_aio_wait(); - } + return &acb->common; +} +static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque) +{ + BlockDriverAIOCBCoroutine *acb = opaque; + BlockDriverState *bs = acb->common.bs; -fail: - async_context_pop(); - return async_ret; + acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors); + acb->bh = qemu_bh_new(bdrv_co_em_bh, acb); + qemu_bh_schedule(acb->bh); } -static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) { - int async_ret; - BlockDriverAIOCB *acb; - struct iovec iov; - QEMUIOVector qiov; + Coroutine *co; + BlockDriverAIOCBCoroutine *acb; - async_context_push(); + trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque); - async_ret = NOT_DONE; - iov.iov_base = (void *)buf; - iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE; - qemu_iovec_init_external(&qiov, &iov, 1); - acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors, - bdrv_rw_em_cb, &async_ret); - if (acb == NULL) { - async_ret = -1; - goto fail; - } - while (async_ret == NOT_DONE) { - qemu_aio_wait(); - } + acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque); + acb->req.sector = sector_num; + acb->req.nb_sectors = nb_sectors; + co = qemu_coroutine_create(bdrv_aio_discard_co_entry); + qemu_coroutine_enter(co, acb); -fail: - async_context_pop(); - return async_ret; + return &acb->common; } void bdrv_init(void) @@ -2618,7 +2707,7 @@ void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, acb = pool->free_aiocb; pool->free_aiocb = acb->next; } else { - acb = qemu_mallocz(pool->aiocb_size); + acb = g_malloc0(pool->aiocb_size); acb->pool = pool; } acb->bs = bs; @@ -2636,6 +2725,220 @@ void qemu_aio_release(void *p) } /**************************************************************/ +/* Coroutine block device emulation */ + +typedef struct CoroutineIOCompletion { + Coroutine *coroutine; + int ret; +} CoroutineIOCompletion; + +static void bdrv_co_io_em_complete(void *opaque, int ret) +{ + CoroutineIOCompletion *co = opaque; + + co->ret = ret; + qemu_coroutine_enter(co->coroutine, NULL); +} + +static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *iov, + bool is_write) +{ + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + BlockDriverAIOCB *acb; + + if (is_write) { + acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors, + bdrv_co_io_em_complete, &co); + } else { + acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors, + bdrv_co_io_em_complete, &co); + } + + trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb); + if (!acb) { + return -EIO; + } + qemu_coroutine_yield(); + + return co.ret; +} + +static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + QEMUIOVector *iov) +{ + return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false); +} + +static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + QEMUIOVector *iov) +{ + return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true); +} + +static void coroutine_fn bdrv_flush_co_entry(void *opaque) +{ + RwCo *rwco = opaque; + + rwco->ret = bdrv_co_flush(rwco->bs); +} + +int coroutine_fn bdrv_co_flush(BlockDriverState *bs) +{ + int ret; + + if (!bs->drv) { + return 0; + } + + /* Write back cached data to the OS even with cache=unsafe */ + if (bs->drv->bdrv_co_flush_to_os) { + ret = bs->drv->bdrv_co_flush_to_os(bs); + if (ret < 0) { + return ret; + } + } + + /* But don't actually force it to the disk with cache=unsafe */ + if (bs->open_flags & BDRV_O_NO_FLUSH) { + return 0; + } + + if (bs->drv->bdrv_co_flush_to_disk) { + return bs->drv->bdrv_co_flush_to_disk(bs); + } else if (bs->drv->bdrv_aio_flush) { + BlockDriverAIOCB *acb; + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + + acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co); + if (acb == NULL) { + return -EIO; + } else { + qemu_coroutine_yield(); + return co.ret; + } + } else { + /* + * Some block drivers always operate in either writethrough or unsafe + * mode and don't support bdrv_flush therefore. Usually qemu doesn't + * know how the server works (because the behaviour is hardcoded or + * depends on server-side configuration), so we can't ensure that + * everything is safe on disk. Returning an error doesn't work because + * that would break guests even if the server operates in writethrough + * mode. + * + * Let's hope the user knows what he's doing. + */ + return 0; + } +} + +void bdrv_invalidate_cache(BlockDriverState *bs) +{ + if (bs->drv && bs->drv->bdrv_invalidate_cache) { + bs->drv->bdrv_invalidate_cache(bs); + } +} + +void bdrv_invalidate_cache_all(void) +{ + BlockDriverState *bs; + + QTAILQ_FOREACH(bs, &bdrv_states, list) { + bdrv_invalidate_cache(bs); + } +} + +int bdrv_flush(BlockDriverState *bs) +{ + Coroutine *co; + RwCo rwco = { + .bs = bs, + .ret = NOT_DONE, + }; + + if (qemu_in_coroutine()) { + /* Fast-path if already in coroutine context */ + bdrv_flush_co_entry(&rwco); + } else { + co = qemu_coroutine_create(bdrv_flush_co_entry); + qemu_coroutine_enter(co, &rwco); + while (rwco.ret == NOT_DONE) { + qemu_aio_wait(); + } + } + + return rwco.ret; +} + +static void coroutine_fn bdrv_discard_co_entry(void *opaque) +{ + RwCo *rwco = opaque; + + rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors); +} + +int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, + int nb_sectors) +{ + if (!bs->drv) { + return -ENOMEDIUM; + } else if (bdrv_check_request(bs, sector_num, nb_sectors)) { + return -EIO; + } else if (bs->read_only) { + return -EROFS; + } else if (bs->drv->bdrv_co_discard) { + return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors); + } else if (bs->drv->bdrv_aio_discard) { + BlockDriverAIOCB *acb; + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + + acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors, + bdrv_co_io_em_complete, &co); + if (acb == NULL) { + return -EIO; + } else { + qemu_coroutine_yield(); + return co.ret; + } + } else { + return 0; + } +} + +int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) +{ + Coroutine *co; + RwCo rwco = { + .bs = bs, + .sector_num = sector_num, + .nb_sectors = nb_sectors, + .ret = NOT_DONE, + }; + + if (qemu_in_coroutine()) { + /* Fast-path if already in coroutine context */ + bdrv_discard_co_entry(&rwco); + } else { + co = qemu_coroutine_create(bdrv_discard_co_entry); + qemu_coroutine_enter(co, &rwco); + while (rwco.ret == NOT_DONE) { + qemu_aio_wait(); + } + } + + return rwco.ret; +} + +/**************************************************************/ /* removable device support */ /** @@ -2644,77 +2947,52 @@ void qemu_aio_release(void *p) int bdrv_is_inserted(BlockDriverState *bs) { BlockDriver *drv = bs->drv; - int ret; + if (!drv) return 0; if (!drv->bdrv_is_inserted) - return !bs->tray_open; - ret = drv->bdrv_is_inserted(bs); - return ret; + return 1; + return drv->bdrv_is_inserted(bs); } /** - * Return TRUE if the media changed since the last call to this - * function. It is currently only used for floppy disks + * Return whether the media changed since the last call to this + * function, or -ENOTSUP if we don't know. Most drivers don't know. */ int bdrv_media_changed(BlockDriverState *bs) { BlockDriver *drv = bs->drv; - int ret; - if (!drv || !drv->bdrv_media_changed) - ret = -ENOTSUP; - else - ret = drv->bdrv_media_changed(bs); - if (ret == -ENOTSUP) - ret = bs->media_changed; - bs->media_changed = 0; - return ret; + if (drv && drv->bdrv_media_changed) { + return drv->bdrv_media_changed(bs); + } + return -ENOTSUP; } /** * If eject_flag is TRUE, eject the media. Otherwise, close the tray */ -int bdrv_eject(BlockDriverState *bs, int eject_flag) +void bdrv_eject(BlockDriverState *bs, int eject_flag) { BlockDriver *drv = bs->drv; - int ret; - if (bs->locked) { - return -EBUSY; - } - - if (!drv || !drv->bdrv_eject) { - ret = -ENOTSUP; - } else { - ret = drv->bdrv_eject(bs, eject_flag); + if (drv && drv->bdrv_eject) { + drv->bdrv_eject(bs, eject_flag); } - if (ret == -ENOTSUP) { - ret = 0; - } - if (ret >= 0) { - bs->tray_open = eject_flag; - } - - return ret; -} - -int bdrv_is_locked(BlockDriverState *bs) -{ - return bs->locked; } /** * Lock or unlock the media (if it is locked, the user won't be able * to eject it manually). */ -void bdrv_set_locked(BlockDriverState *bs, int locked) +void bdrv_lock_medium(BlockDriverState *bs, bool locked) { BlockDriver *drv = bs->drv; - bs->locked = locked; - if (drv && drv->bdrv_set_locked) { - drv->bdrv_set_locked(bs, locked); + trace_bdrv_lock_medium(bs, locked); + + if (drv && drv->bdrv_lock_medium) { + drv->bdrv_lock_medium(bs, locked); } } @@ -2740,7 +3018,10 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, return NULL; } - +void bdrv_set_buffer_alignment(BlockDriverState *bs, int align) +{ + bs->buffer_alignment = align; +} void *qemu_blockalign(BlockDriverState *bs, size_t size) { @@ -2758,11 +3039,11 @@ void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable) BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; - bs->dirty_bitmap = qemu_mallocz(bitmap_size); + bs->dirty_bitmap = g_malloc0(bitmap_size); } } else { if (bs->dirty_bitmap) { - qemu_free(bs->dirty_bitmap); + g_free(bs->dirty_bitmap); bs->dirty_bitmap = NULL; } } @@ -2803,12 +3084,74 @@ int bdrv_in_use(BlockDriverState *bs) return bs->in_use; } +void bdrv_iostatus_enable(BlockDriverState *bs) +{ + bs->iostatus_enabled = true; + bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK; +} + +/* The I/O status is only enabled if the drive explicitly + * enables it _and_ the VM is configured to stop on errors */ +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs) +{ + return (bs->iostatus_enabled && + (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC || + bs->on_write_error == BLOCK_ERR_STOP_ANY || + bs->on_read_error == BLOCK_ERR_STOP_ANY)); +} + +void bdrv_iostatus_disable(BlockDriverState *bs) +{ + bs->iostatus_enabled = false; +} + +void bdrv_iostatus_reset(BlockDriverState *bs) +{ + if (bdrv_iostatus_is_enabled(bs)) { + bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK; + } +} + +/* XXX: Today this is set by device models because it makes the implementation + quite simple. However, the block layer knows about the error, so it's + possible to implement this without device models being involved */ +void bdrv_iostatus_set_err(BlockDriverState *bs, int error) +{ + if (bdrv_iostatus_is_enabled(bs) && + bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) { + assert(error >= 0); + bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE : + BLOCK_DEVICE_IO_STATUS_FAILED; + } +} + +void +bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes, + enum BlockAcctType type) +{ + assert(type < BDRV_MAX_IOTYPE); + + cookie->bytes = bytes; + cookie->start_time_ns = get_clock(); + cookie->type = type; +} + +void +bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie) +{ + assert(cookie->type < BDRV_MAX_IOTYPE); + + bs->nr_bytes[cookie->type] += cookie->bytes; + bs->nr_ops[cookie->type]++; + bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns; +} + int bdrv_img_create(const char *filename, const char *fmt, const char *base_filename, const char *base_fmt, char *options, uint64_t img_size, int flags) { QEMUOptionParameter *param = NULL, *create_options = NULL; - QEMUOptionParameter *backing_fmt, *backing_file; + QEMUOptionParameter *backing_fmt, *backing_file, *size; BlockDriverState *bs = NULL; BlockDriver *drv, *proto_drv; BlockDriver *backing_drv = NULL; @@ -2891,7 +3234,8 @@ int bdrv_img_create(const char *filename, const char *fmt, // The size for the image must always be specified, with one exception: // If we are using a backing file, we can obtain the size from there - if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) { + size = get_option_parameter(param, BLOCK_OPT_SIZE); + if (size && size->value.n == -1) { if (backing_file && backing_file->value.s) { uint64_t size; char buf[32]; diff --git a/block.h b/block.h index 097b789..a826059 100644 --- a/block.h +++ b/block.h @@ -4,6 +4,7 @@ #include "qemu-aio.h" #include "qemu-common.h" #include "qemu-option.h" +#include "qemu-coroutine.h" #include "qobject.h" /* block.c */ @@ -27,6 +28,41 @@ typedef struct QEMUSnapshotInfo { uint64_t vm_clock_nsec; /* VM clock relative to boot */ } QEMUSnapshotInfo; +/* Callbacks for block device models */ +typedef struct BlockDevOps { + /* + * Runs when virtual media changed (monitor commands eject, change) + * Argument load is true on load and false on eject. + * Beware: doesn't run when a host device's physical media + * changes. Sure would be useful if it did. + * Device models with removable media must implement this callback. + */ + void (*change_media_cb)(void *opaque, bool load); + /* + * Runs when an eject request is issued from the monitor, the tray + * is closed, and the medium is locked. + * Device models that do not implement is_medium_locked will not need + * this callback. Device models that can lock the medium or tray might + * want to implement the callback and unlock the tray when "force" is + * true, even if they do not support eject requests. + */ + void (*eject_request_cb)(void *opaque, bool force); + /* + * Is the virtual tray open? + * Device models implement this only when the device has a tray. + */ + bool (*is_tray_open)(void *opaque); + /* + * Is the virtual medium locked into the device? + * Device models implement this only when device has such a lock. + */ + bool (*is_medium_locked)(void *opaque); + /* + * Runs when the size changed (e.g. monitor command block_resize) + */ + void (*resize_cb)(void *opaque); +} BlockDevOps; + #define BDRV_O_RDWR 0x0002 #define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */ #define BDRV_O_NOCACHE 0x0020 /* do not use the host page cache */ @@ -50,6 +86,11 @@ typedef enum { BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP } BlockMonEventAction; +void bdrv_iostatus_enable(BlockDriverState *bs); +void bdrv_iostatus_reset(BlockDriverState *bs); +void bdrv_iostatus_disable(BlockDriverState *bs); +bool bdrv_iostatus_is_enabled(const BlockDriverState *bs); +void bdrv_iostatus_set_err(BlockDriverState *bs, int error); void bdrv_mon_event(const BlockDriverState *bdrv, BlockMonEventAction action, int is_read); void bdrv_info_print(Monitor *mon, const QObject *data); @@ -68,13 +109,21 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options); BlockDriverState *bdrv_new(const char *device_name); void bdrv_make_anon(BlockDriverState *bs); void bdrv_delete(BlockDriverState *bs); +int bdrv_parse_cache_flags(const char *mode, int *flags); int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags); int bdrv_open(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv); void bdrv_close(BlockDriverState *bs); -int bdrv_attach(BlockDriverState *bs, DeviceState *qdev); -void bdrv_detach(BlockDriverState *bs, DeviceState *qdev); -DeviceState *bdrv_get_attached(BlockDriverState *bs); +int bdrv_attach_dev(BlockDriverState *bs, void *dev); +void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev); +void bdrv_detach_dev(BlockDriverState *bs, void *dev); +void *bdrv_get_attached_dev(BlockDriverState *bs); +void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops, + void *opaque); +void bdrv_dev_eject_request(BlockDriverState *bs, bool force); +bool bdrv_dev_has_removable_media(BlockDriverState *bs); +bool bdrv_dev_is_tray_open(BlockDriverState *bs); +bool bdrv_dev_is_medium_locked(BlockDriverState *bs); int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); int bdrv_write(BlockDriverState *bs, int64_t sector_num, @@ -85,10 +134,13 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset, const void *buf, int count); int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset, const void *buf, int count); -int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors); +int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov); +int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov); int bdrv_truncate(BlockDriverState *bs, int64_t offset); int64_t bdrv_getlength(BlockDriverState *bs); +int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs); int bdrv_commit(BlockDriverState *bs); @@ -110,7 +162,7 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res); typedef struct BlockDriverAIOCB BlockDriverAIOCB; typedef void BlockDriverCompletionFunc(void *opaque, int ret); typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector, - int sector_num); + int sector_num); BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *iov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); @@ -118,7 +170,10 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *iov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque); + BlockDriverCompletionFunc *cb, void *opaque); +BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); void bdrv_aio_cancel(BlockDriverAIOCB *acb); typedef struct BlockRequest { @@ -142,19 +197,22 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, unsigned long int req, void *buf, BlockDriverCompletionFunc *cb, void *opaque); +/* Invalidate any cached metadata used by image formats */ +void bdrv_invalidate_cache(BlockDriverState *bs); +void bdrv_invalidate_cache_all(void); + /* Ensure contents are flushed to disk. */ int bdrv_flush(BlockDriverState *bs); +int coroutine_fn bdrv_co_flush(BlockDriverState *bs); void bdrv_flush_all(void); void bdrv_close_all(void); int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); +int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int bdrv_has_zero_init(BlockDriverState *bs); int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, - int *pnum); + int *pnum); -#define BDRV_TYPE_HD 0 -#define BDRV_TYPE_CDROM 1 -#define BDRV_TYPE_FLOPPY 2 #define BIOS_ATA_TRANSLATION_AUTO 0 #define BIOS_ATA_TRANSLATION_NONE 1 #define BIOS_ATA_TRANSLATION_LBA 2 @@ -163,28 +221,30 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, void bdrv_set_geometry_hint(BlockDriverState *bs, int cyls, int heads, int secs); -void bdrv_set_type_hint(BlockDriverState *bs, int type); void bdrv_set_translation_hint(BlockDriverState *bs, int translation); void bdrv_get_geometry_hint(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs); -int bdrv_get_type_hint(BlockDriverState *bs); +typedef enum FDriveType { + FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */ + FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */ + FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */ + FDRIVE_DRV_NONE = 0x03, /* No drive connected */ +} FDriveType; + +void bdrv_get_floppy_geometry_hint(BlockDriverState *bs, int *nb_heads, + int *max_track, int *last_sect, + FDriveType drive_in, FDriveType *drive); int bdrv_get_translation_hint(BlockDriverState *bs); void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error, BlockErrorAction on_write_error); BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read); -void bdrv_set_removable(BlockDriverState *bs, int removable); -int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); int bdrv_is_sg(BlockDriverState *bs); int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); -int bdrv_is_locked(BlockDriverState *bs); -void bdrv_set_locked(BlockDriverState *bs, int locked); -int bdrv_eject(BlockDriverState *bs, int eject_flag); -void bdrv_set_change_cb(BlockDriverState *bs, - void (*change_cb)(void *opaque, int reason), - void *opaque); +void bdrv_lock_medium(BlockDriverState *bs, bool locked); +void bdrv_eject(BlockDriverState *bs, int eject_flag); void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size); BlockDriverState *bdrv_find(const char *name); BlockDriverState *bdrv_next(BlockDriverState *bs); @@ -234,6 +294,9 @@ int bdrv_img_create(const char *filename, const char *fmt, const char *base_filename, const char *base_fmt, char *options, uint64_t img_size, int flags); +void bdrv_set_buffer_alignment(BlockDriverState *bs, int align); +void *qemu_blockalign(BlockDriverState *bs, size_t size); + #define BDRV_SECTORS_PER_DIRTY_CHUNK 2048 void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable); @@ -245,6 +308,23 @@ int64_t bdrv_get_dirty_count(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +enum BlockAcctType { + BDRV_ACCT_READ, + BDRV_ACCT_WRITE, + BDRV_ACCT_FLUSH, + BDRV_MAX_IOTYPE, +}; + +typedef struct BlockAcctCookie { + int64_t bytes; + int64_t start_time_ns; + enum BlockAcctType type; +} BlockAcctCookie; + +void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, + int64_t bytes, enum BlockAcctType type); +void bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie); + typedef enum { BLKDBG_L1_UPDATE, @@ -296,4 +376,43 @@ typedef enum { #define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt) void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event); + +/* Convenience for block device models */ + +typedef struct BlockConf { + BlockDriverState *bs; + uint16_t physical_block_size; + uint16_t logical_block_size; + uint16_t min_io_size; + uint32_t opt_io_size; + int32_t bootindex; + uint32_t discard_granularity; +} BlockConf; + +static inline unsigned int get_physical_block_exp(BlockConf *conf) +{ + unsigned int exp = 0, size; + + for (size = conf->physical_block_size; + size > conf->logical_block_size; + size >>= 1) { + exp++; + } + + return exp; +} + +#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \ + DEFINE_PROP_DRIVE("drive", _state, _conf.bs), \ + DEFINE_PROP_UINT16("logical_block_size", _state, \ + _conf.logical_block_size, 512), \ + DEFINE_PROP_UINT16("physical_block_size", _state, \ + _conf.physical_block_size, 512), \ + DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \ + DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \ + DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1), \ + DEFINE_PROP_UINT32("discard_granularity", _state, \ + _conf.discard_granularity, 0) + #endif + diff --git a/block/blkdebug.c b/block/blkdebug.c index cd9eb80..9b88535 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -214,7 +214,7 @@ static int add_rule(QemuOpts *opts, void *opaque) } /* Set attributes common for all actions */ - rule = qemu_mallocz(sizeof(*rule)); + rule = g_malloc0(sizeof(*rule)); *rule = (struct BlkdebugRule) { .event = event, .action = d->action, @@ -392,16 +392,11 @@ static void blkdebug_close(BlockDriverState *bs) for (i = 0; i < BLKDBG_EVENT_MAX; i++) { QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { QLIST_REMOVE(rule, next); - qemu_free(rule); + g_free(rule); } } } -static int blkdebug_flush(BlockDriverState *bs) -{ - return bdrv_flush(bs->file); -} - static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque) { @@ -454,7 +449,6 @@ static BlockDriver bdrv_blkdebug = { .bdrv_file_open = blkdebug_open, .bdrv_close = blkdebug_close, - .bdrv_flush = blkdebug_flush, .bdrv_aio_readv = blkdebug_aio_readv, .bdrv_aio_writev = blkdebug_aio_writev, diff --git a/block/blkverify.c b/block/blkverify.c index c7522b4..483f3b3 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -116,14 +116,6 @@ static void blkverify_close(BlockDriverState *bs) s->test_file = NULL; } -static int blkverify_flush(BlockDriverState *bs) -{ - BDRVBlkverifyState *s = bs->opaque; - - /* Only flush test file, the raw file is not important */ - return bdrv_flush(s->test_file); -} - static int64_t blkverify_getlength(BlockDriverState *bs) { BDRVBlkverifyState *s = bs->opaque; @@ -368,7 +360,6 @@ static BlockDriver bdrv_blkverify = { .bdrv_file_open = blkverify_open, .bdrv_close = blkverify_close, - .bdrv_flush = blkverify_flush, .bdrv_aio_readv = blkverify_aio_readv, .bdrv_aio_writev = blkverify_aio_writev, diff --git a/block/bochs.c b/block/bochs.c index 5fe2fa3..ab7944d 100644 --- a/block/bochs.c +++ b/block/bochs.c @@ -80,6 +80,7 @@ struct bochs_header { }; typedef struct BDRVBochsState { + CoMutex lock; uint32_t *catalog_bitmap; int catalog_size; @@ -136,7 +137,7 @@ static int bochs_open(BlockDriverState *bs, int flags) } s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog); - s->catalog_bitmap = qemu_malloc(s->catalog_size * 4); + s->catalog_bitmap = g_malloc(s->catalog_size * 4); if (bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap, s->catalog_size * 4) != s->catalog_size * 4) goto fail; @@ -150,6 +151,7 @@ static int bochs_open(BlockDriverState *bs, int flags) s->extent_size = le32_to_cpu(bochs.extra.redolog.extent); + qemu_co_mutex_init(&s->lock); return 0; fail: return -1; @@ -207,10 +209,21 @@ static int bochs_read(BlockDriverState *bs, int64_t sector_num, return 0; } +static coroutine_fn int bochs_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVBochsState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = bochs_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static void bochs_close(BlockDriverState *bs) { BDRVBochsState *s = bs->opaque; - qemu_free(s->catalog_bitmap); + g_free(s->catalog_bitmap); } static BlockDriver bdrv_bochs = { @@ -218,7 +231,7 @@ static BlockDriver bdrv_bochs = { .instance_size = sizeof(BDRVBochsState), .bdrv_probe = bochs_probe, .bdrv_open = bochs_open, - .bdrv_read = bochs_read, + .bdrv_read = bochs_co_read, .bdrv_close = bochs_close, }; diff --git a/block/cloop.c b/block/cloop.c index fe015c4..7570eb8 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -27,9 +27,10 @@ #include typedef struct BDRVCloopState { + CoMutex lock; uint32_t block_size; uint32_t n_blocks; - uint64_t* offsets; + uint64_t *offsets; uint32_t sectors_per_block; uint32_t current_block; uint8_t *compressed_block; @@ -39,21 +40,23 @@ typedef struct BDRVCloopState { static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename) { - const char* magic_version_2_0="#!/bin/sh\n" - "#V2.0 Format\n" - "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n"; - int length=strlen(magic_version_2_0); - if(length>buf_size) - length=buf_size; - if(!memcmp(magic_version_2_0,buf,length)) - return 2; + const char *magic_version_2_0 = "#!/bin/sh\n" + "#V2.0 Format\n" + "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n"; + int length = strlen(magic_version_2_0); + if (length > buf_size) { + length = buf_size; + } + if (!memcmp(magic_version_2_0, buf, length)) { + return 2; + } return 0; } static int cloop_open(BlockDriverState *bs, int flags) { BDRVCloopState *s = bs->opaque; - uint32_t offsets_size,max_compressed_block_size=1,i; + uint32_t offsets_size, max_compressed_block_size = 1, i; bs->read_only = 1; @@ -70,29 +73,32 @@ static int cloop_open(BlockDriverState *bs, int flags) /* read offsets */ offsets_size = s->n_blocks * sizeof(uint64_t); - s->offsets = qemu_malloc(offsets_size); + s->offsets = g_malloc(offsets_size); if (bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size) < offsets_size) { - goto cloop_close; + goto cloop_close; } for(i=0;in_blocks;i++) { - s->offsets[i]=be64_to_cpu(s->offsets[i]); - if(i>0) { - uint32_t size=s->offsets[i]-s->offsets[i-1]; - if(size>max_compressed_block_size) - max_compressed_block_size=size; - } + s->offsets[i] = be64_to_cpu(s->offsets[i]); + if (i > 0) { + uint32_t size = s->offsets[i] - s->offsets[i - 1]; + if (size > max_compressed_block_size) { + max_compressed_block_size = size; + } + } } /* initialize zlib engine */ - s->compressed_block = qemu_malloc(max_compressed_block_size+1); - s->uncompressed_block = qemu_malloc(s->block_size); - if(inflateInit(&s->zstream) != Z_OK) - goto cloop_close; - s->current_block=s->n_blocks; + s->compressed_block = g_malloc(max_compressed_block_size + 1); + s->uncompressed_block = g_malloc(s->block_size); + if (inflateInit(&s->zstream) != Z_OK) { + goto cloop_close; + } + s->current_block = s->n_blocks; s->sectors_per_block = s->block_size/512; - bs->total_sectors = s->n_blocks*s->sectors_per_block; + bs->total_sectors = s->n_blocks * s->sectors_per_block; + qemu_co_mutex_init(&s->lock); return 0; cloop_close: @@ -103,27 +109,30 @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num) { BDRVCloopState *s = bs->opaque; - if(s->current_block != block_num) { - int ret; - uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num]; + if (s->current_block != block_num) { + int ret; + uint32_t bytes = s->offsets[block_num + 1] - s->offsets[block_num]; ret = bdrv_pread(bs->file, s->offsets[block_num], s->compressed_block, bytes); - if (ret != bytes) + if (ret != bytes) { + return -1; + } + + s->zstream.next_in = s->compressed_block; + s->zstream.avail_in = bytes; + s->zstream.next_out = s->uncompressed_block; + s->zstream.avail_out = s->block_size; + ret = inflateReset(&s->zstream); + if (ret != Z_OK) { + return -1; + } + ret = inflate(&s->zstream, Z_FINISH); + if (ret != Z_STREAM_END || s->zstream.total_out != s->block_size) { return -1; + } - s->zstream.next_in = s->compressed_block; - s->zstream.avail_in = bytes; - s->zstream.next_out = s->uncompressed_block; - s->zstream.avail_out = s->block_size; - ret = inflateReset(&s->zstream); - if(ret != Z_OK) - return -1; - ret = inflate(&s->zstream, Z_FINISH); - if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size) - return -1; - - s->current_block = block_num; + s->current_block = block_num; } return 0; } @@ -134,33 +143,48 @@ static int cloop_read(BlockDriverState *bs, int64_t sector_num, BDRVCloopState *s = bs->opaque; int i; - for(i=0;isectors_per_block), - block_num=(sector_num+i)/s->sectors_per_block; - if(cloop_read_block(bs, block_num) != 0) - return -1; - memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512); + for (i = 0; i < nb_sectors; i++) { + uint32_t sector_offset_in_block = + ((sector_num + i) % s->sectors_per_block), + block_num = (sector_num + i) / s->sectors_per_block; + if (cloop_read_block(bs, block_num) != 0) { + return -1; + } + memcpy(buf + i * 512, + s->uncompressed_block + sector_offset_in_block * 512, 512); } return 0; } +static coroutine_fn int cloop_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVCloopState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = cloop_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static void cloop_close(BlockDriverState *bs) { BDRVCloopState *s = bs->opaque; - if(s->n_blocks>0) - free(s->offsets); - free(s->compressed_block); - free(s->uncompressed_block); + if (s->n_blocks > 0) { + g_free(s->offsets); + } + g_free(s->compressed_block); + g_free(s->uncompressed_block); inflateEnd(&s->zstream); } static BlockDriver bdrv_cloop = { - .format_name = "cloop", - .instance_size = sizeof(BDRVCloopState), - .bdrv_probe = cloop_probe, - .bdrv_open = cloop_open, - .bdrv_read = cloop_read, - .bdrv_close = cloop_close, + .format_name = "cloop", + .instance_size = sizeof(BDRVCloopState), + .bdrv_probe = cloop_probe, + .bdrv_open = cloop_open, + .bdrv_read = cloop_co_read, + .bdrv_close = cloop_close, }; static void bdrv_cloop_init(void) diff --git a/block/cow.c b/block/cow.c index 4cf543c..089d395 100644 --- a/block/cow.c +++ b/block/cow.c @@ -42,6 +42,7 @@ struct cow_header_v2 { }; typedef struct BDRVCowState { + CoMutex lock; int64_t cow_sectors_offset; } BDRVCowState; @@ -84,6 +85,7 @@ static int cow_open(BlockDriverState *bs, int flags) bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header); s->cow_sectors_offset = (bitmap_size + 511) & ~511; + qemu_co_mutex_init(&s->lock); return 0; fail: return -1; @@ -199,6 +201,17 @@ static int cow_read(BlockDriverState *bs, int64_t sector_num, return 0; } +static coroutine_fn int cow_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVCowState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = cow_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static int cow_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { @@ -213,6 +226,17 @@ static int cow_write(BlockDriverState *bs, int64_t sector_num, return cow_update_bitmap(bs, sector_num, nb_sectors); } +static coroutine_fn int cow_co_write(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVCowState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = cow_write(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static void cow_close(BlockDriverState *bs) { } @@ -282,9 +306,9 @@ exit: return ret; } -static int cow_flush(BlockDriverState *bs) +static coroutine_fn int cow_co_flush(BlockDriverState *bs) { - return bdrv_flush(bs->file); + return bdrv_co_flush(bs->file); } static QEMUOptionParameter cow_create_options[] = { @@ -302,16 +326,18 @@ static QEMUOptionParameter cow_create_options[] = { }; static BlockDriver bdrv_cow = { - .format_name = "cow", - .instance_size = sizeof(BDRVCowState), - .bdrv_probe = cow_probe, - .bdrv_open = cow_open, - .bdrv_read = cow_read, - .bdrv_write = cow_write, - .bdrv_close = cow_close, - .bdrv_create = cow_create, - .bdrv_flush = cow_flush, - .bdrv_is_allocated = cow_is_allocated, + .format_name = "cow", + .instance_size = sizeof(BDRVCowState), + + .bdrv_probe = cow_probe, + .bdrv_open = cow_open, + .bdrv_close = cow_close, + .bdrv_create = cow_create, + + .bdrv_read = cow_co_read, + .bdrv_write = cow_co_write, + .bdrv_co_flush_to_disk = cow_co_flush, + .bdrv_is_allocated = cow_is_allocated, .create_options = cow_create_options, }; diff --git a/block/curl.c b/block/curl.c index 407f095..4209ac8 100644 --- a/block/curl.c +++ b/block/curl.c @@ -47,7 +47,12 @@ struct BDRVCURLState; typedef struct CURLAIOCB { BlockDriverAIOCB common; + QEMUBH *bh; QEMUIOVector *qiov; + + int64_t sector_num; + int nb_sectors; + size_t start; size_t end; } CURLAIOCB; @@ -76,6 +81,7 @@ typedef struct BDRVCURLState { static void curl_clean_state(CURLState *s); static void curl_multi_do(void *arg); +static int curl_aio_flush(void *opaque); static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, void *s, void *sp) @@ -83,14 +89,16 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd); switch (action) { case CURL_POLL_IN: - qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, NULL, NULL, s); + qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, curl_aio_flush, + NULL, s); break; case CURL_POLL_OUT: - qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, NULL, NULL, s); + qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, curl_aio_flush, + NULL, s); break; case CURL_POLL_INOUT: - qemu_aio_set_fd_handler(fd, curl_multi_do, - curl_multi_do, NULL, NULL, s); + qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do, + curl_aio_flush, NULL, s); break; case CURL_POLL_REMOVE: qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL, NULL); @@ -229,6 +237,23 @@ static void curl_multi_do(void *arg) { CURLState *state = NULL; curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char**)&state); + + /* ACBs for successful messages get completed in curl_read_cb */ + if (msg->data.result != CURLE_OK) { + int i; + for (i = 0; i < CURL_NUM_ACB; i++) { + CURLAIOCB *acb = state->acb[i]; + + if (acb == NULL) { + continue; + } + + acb->common.cb(acb->common.opaque, -EIO); + qemu_aio_release(acb); + state->acb[i] = NULL; + } + } + curl_clean_state(state); break; } @@ -277,7 +302,8 @@ static CURLState *curl_init_state(BDRVCURLState *s) curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg); - + curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1); + #ifdef DEBUG_VERBOSE curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1); #endif @@ -310,7 +336,7 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags) static int inited = 0; - file = qemu_strdup(filename); + file = g_strdup(filename); s->readahead_size = READ_AHEAD_SIZE; /* Parse a trailing ":readahead=#:" param, if present. */ @@ -390,10 +416,25 @@ out: curl_easy_cleanup(state->curl); state->curl = NULL; out_noclean: - qemu_free(file); + g_free(file); return -EINVAL; } +static int curl_aio_flush(void *opaque) +{ + BDRVCURLState *s = opaque; + int i, j; + + for (i=0; i < CURL_NUM_STATES; i++) { + for(j=0; j < CURL_NUM_ACB; j++) { + if (s->states[i].acb[j]) { + return 1; + } + } + } + return 0; +} + static void curl_aio_cancel(BlockDriverAIOCB *blockacb) { // Do we have to implement canceling? Seems to work without... @@ -404,61 +445,86 @@ static AIOPool curl_aio_pool = { .cancel = curl_aio_cancel, }; -static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) + +static void curl_readv_bh_cb(void *p) { - BDRVCURLState *s = bs->opaque; - CURLAIOCB *acb; - size_t start = sector_num * SECTOR_SIZE; - size_t end; CURLState *state; - acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque); - if (!acb) - return NULL; + CURLAIOCB *acb = p; + BDRVCURLState *s = acb->common.bs->opaque; - acb->qiov = qiov; + qemu_bh_delete(acb->bh); + acb->bh = NULL; + + size_t start = acb->sector_num * SECTOR_SIZE; + size_t end; // In case we have the requested data already (e.g. read-ahead), // we can just call the callback and be done. - - switch (curl_find_buf(s, start, nb_sectors * SECTOR_SIZE, acb)) { + switch (curl_find_buf(s, start, acb->nb_sectors * SECTOR_SIZE, acb)) { case FIND_RET_OK: qemu_aio_release(acb); // fall through case FIND_RET_WAIT: - return &acb->common; + return; default: break; } // No cache found, so let's start a new request - state = curl_init_state(s); - if (!state) - return NULL; + if (!state) { + acb->common.cb(acb->common.opaque, -EIO); + qemu_aio_release(acb); + return; + } acb->start = 0; - acb->end = (nb_sectors * SECTOR_SIZE); + acb->end = (acb->nb_sectors * SECTOR_SIZE); state->buf_off = 0; if (state->orig_buf) - qemu_free(state->orig_buf); + g_free(state->orig_buf); state->buf_start = start; state->buf_len = acb->end + s->readahead_size; end = MIN(start + state->buf_len, s->len) - 1; - state->orig_buf = qemu_malloc(state->buf_len); + state->orig_buf = g_malloc(state->buf_len); state->acb[0] = acb; snprintf(state->range, 127, "%zd-%zd", start, end); DPRINTF("CURL (AIO): Reading %d at %zd (%s)\n", - (nb_sectors * SECTOR_SIZE), start, state->range); + (acb->nb_sectors * SECTOR_SIZE), start, state->range); curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range); curl_multi_add_handle(s->multi, state->curl); curl_multi_do(s); +} + +static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + CURLAIOCB *acb; + + acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque); + + if (!acb) { + return NULL; + } + + acb->qiov = qiov; + acb->sector_num = sector_num; + acb->nb_sectors = nb_sectors; + + acb->bh = qemu_bh_new(curl_readv_bh_cb, acb); + + if (!acb->bh) { + DPRINTF("CURL: qemu_bh_new failed\n"); + return NULL; + } + + qemu_bh_schedule(acb->bh); return &acb->common; } @@ -476,7 +542,7 @@ static void curl_close(BlockDriverState *bs) s->states[i].curl = NULL; } if (s->states[i].orig_buf) { - qemu_free(s->states[i].orig_buf); + g_free(s->states[i].orig_buf); s->states[i].orig_buf = NULL; } } diff --git a/block/dmg.c b/block/dmg.c index a3c815b..37902a4 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -28,6 +28,7 @@ #include typedef struct BDRVDMGState { + CoMutex lock; /* each chunk contains a certain number of sectors, * offsets[i] is the offset in the .dmg file, * lengths[i] is the length of the compressed chunk, @@ -127,11 +128,11 @@ static int dmg_open(BlockDriverState *bs, int flags) chunk_count = (count-204)/40; new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count); - s->types = qemu_realloc(s->types, new_size/2); - s->offsets = qemu_realloc(s->offsets, new_size); - s->lengths = qemu_realloc(s->lengths, new_size); - s->sectors = qemu_realloc(s->sectors, new_size); - s->sectorcounts = qemu_realloc(s->sectorcounts, new_size); + s->types = g_realloc(s->types, new_size/2); + s->offsets = g_realloc(s->offsets, new_size); + s->lengths = g_realloc(s->lengths, new_size); + s->sectors = g_realloc(s->sectors, new_size); + s->sectorcounts = g_realloc(s->sectorcounts, new_size); for(i=s->n_chunks;in_chunks+chunk_count;i++) { s->types[i] = read_uint32(bs, offset); @@ -170,13 +171,14 @@ static int dmg_open(BlockDriverState *bs, int flags) } /* initialize zlib engine */ - s->compressed_chunk = qemu_malloc(max_compressed_size+1); - s->uncompressed_chunk = qemu_malloc(512*max_sectors_per_chunk); + s->compressed_chunk = g_malloc(max_compressed_size+1); + s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk); if(inflateInit(&s->zstream) != Z_OK) goto fail; s->current_chunk = s->n_chunks; + qemu_co_mutex_init(&s->lock); return 0; fail: return -1; @@ -280,6 +282,17 @@ static int dmg_read(BlockDriverState *bs, int64_t sector_num, return 0; } +static coroutine_fn int dmg_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVDMGState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = dmg_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static void dmg_close(BlockDriverState *bs) { BDRVDMGState *s = bs->opaque; @@ -300,7 +313,7 @@ static BlockDriver bdrv_dmg = { .instance_size = sizeof(BDRVDMGState), .bdrv_probe = dmg_probe, .bdrv_open = dmg_open, - .bdrv_read = dmg_read, + .bdrv_read = dmg_co_read, .bdrv_close = dmg_close, }; diff --git a/block/nbd.c b/block/nbd.c index c8dc763..882b2dc 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -28,97 +28,156 @@ #include "qemu-common.h" #include "nbd.h" +#include "block_int.h" #include "module.h" +#include "qemu_socket.h" #include #include #define EN_OPTSTR ":exportname=" +/* #define DEBUG_NBD */ + +#if defined(DEBUG_NBD) +#define logout(fmt, ...) \ + fprintf(stderr, "nbd\t%-24s" fmt, __func__, ##__VA_ARGS__) +#else +#define logout(fmt, ...) ((void)0) +#endif + typedef struct BDRVNBDState { + CoMutex lock; int sock; + uint32_t nbdflags; off_t size; size_t blocksize; + char *export_name; /* An NBD server may export several devices */ + + /* If it begins with '/', this is a UNIX domain socket. Otherwise, + * it's a string of the form :port + */ + char *host_spec; } BDRVNBDState; -static int nbd_open(BlockDriverState *bs, const char* filename, int flags) +static int nbd_config(BDRVNBDState *s, const char *filename, int flags) { - BDRVNBDState *s = bs->opaque; - uint32_t nbdflags; - char *file; - char *name; - const char *host; + char *export_name; + const char *host_spec; const char *unixpath; - int sock; - off_t size; - size_t blocksize; - int ret; int err = -EINVAL; - file = qemu_strdup(filename); + file = g_strdup(filename); - name = strstr(file, EN_OPTSTR); - if (name) { - if (name[strlen(EN_OPTSTR)] == 0) { + export_name = strstr(file, EN_OPTSTR); + if (export_name) { + if (export_name[strlen(EN_OPTSTR)] == 0) { goto out; } - name[0] = 0; - name += strlen(EN_OPTSTR); + export_name[0] = 0; /* truncate 'file' */ + export_name += strlen(EN_OPTSTR); + s->export_name = g_strdup(export_name); } - if (!strstart(file, "nbd:", &host)) { + /* extract the host_spec - fail if it's not nbd:... */ + if (!strstart(file, "nbd:", &host_spec)) { goto out; } - if (strstart(host, "unix:", &unixpath)) { - - if (unixpath[0] != '/') { + /* are we a UNIX or TCP socket? */ + if (strstart(host_spec, "unix:", &unixpath)) { + if (unixpath[0] != '/') { /* We demand an absolute path*/ goto out; } - - sock = unix_socket_outgoing(unixpath); - + s->host_spec = g_strdup(unixpath); } else { - uint16_t port = NBD_DEFAULT_PORT; - char *p, *r; - char hostname[128]; + s->host_spec = g_strdup(host_spec); + } - pstrcpy(hostname, 128, host); + err = 0; - p = strchr(hostname, ':'); - if (p != NULL) { - *p = '\0'; - p++; +out: + g_free(file); + if (err != 0) { + g_free(s->export_name); + g_free(s->host_spec); + } + return err; +} - port = strtol(p, &r, 0); - if (r == p) { - goto out; - } - } +static int nbd_establish_connection(BlockDriverState *bs) +{ + BDRVNBDState *s = bs->opaque; + int sock; + int ret; + off_t size; + size_t blocksize; - sock = tcp_socket_outgoing(hostname, port); + if (s->host_spec[0] == '/') { + sock = unix_socket_outgoing(s->host_spec); + } else { + sock = tcp_socket_outgoing_spec(s->host_spec); } + /* Failed to establish connection */ if (sock == -1) { - err = -errno; - goto out; + logout("Failed to establish connection to NBD server\n"); + return -errno; } - ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize); + /* NBD handshake */ + ret = nbd_receive_negotiate(sock, s->export_name, &s->nbdflags, &size, + &blocksize); if (ret == -1) { - err = -errno; - goto out; + logout("Failed to negotiate with the NBD server\n"); + closesocket(sock); + return -errno; } + /* Now that we're connected, set the socket to be non-blocking */ + socket_set_nonblock(sock); + s->sock = sock; s->size = size; s->blocksize = blocksize; - err = 0; -out: - qemu_free(file); - return err; + logout("Established connection with NBD server\n"); + return 0; +} + +static void nbd_teardown_connection(BlockDriverState *bs) +{ + BDRVNBDState *s = bs->opaque; + struct nbd_request request; + + request.type = NBD_CMD_DISC; + request.handle = (uint64_t)(intptr_t)bs; + request.from = 0; + request.len = 0; + nbd_send_request(s->sock, &request); + + closesocket(s->sock); +} + +static int nbd_open(BlockDriverState *bs, const char* filename, int flags) +{ + BDRVNBDState *s = bs->opaque; + int result; + + /* Pop the config into our state object. Exit if invalid. */ + result = nbd_config(s, filename, flags); + if (result != 0) { + return result; + } + + /* establish TCP connection, return error if it fails + * TODO: Configurable retry-until-timeout behaviour. + */ + result = nbd_establish_connection(bs); + + qemu_co_mutex_init(&s->lock); + return result; } static int nbd_read(BlockDriverState *bs, int64_t sector_num, @@ -181,18 +240,35 @@ static int nbd_write(BlockDriverState *bs, int64_t sector_num, return 0; } -static void nbd_close(BlockDriverState *bs) +static coroutine_fn int nbd_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) { + int ret; BDRVNBDState *s = bs->opaque; - struct nbd_request request; + qemu_co_mutex_lock(&s->lock); + ret = nbd_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} - request.type = NBD_CMD_DISC; - request.handle = (uint64_t)(intptr_t)bs; - request.from = 0; - request.len = 0; - nbd_send_request(s->sock, &request); +static coroutine_fn int nbd_co_write(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVNBDState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = nbd_write(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + +static void nbd_close(BlockDriverState *bs) +{ + BDRVNBDState *s = bs->opaque; + g_free(s->export_name); + g_free(s->host_spec); - close(s->sock); + nbd_teardown_connection(bs); } static int64_t nbd_getlength(BlockDriverState *bs) @@ -206,8 +282,8 @@ static BlockDriver bdrv_nbd = { .format_name = "nbd", .instance_size = sizeof(BDRVNBDState), .bdrv_file_open = nbd_open, - .bdrv_read = nbd_read, - .bdrv_write = nbd_write, + .bdrv_read = nbd_co_read, + .bdrv_write = nbd_co_write, .bdrv_close = nbd_close, .bdrv_getlength = nbd_getlength, .protocol_name = "nbd", diff --git a/block/parallels.c b/block/parallels.c index 35a14aa..d30f0ec 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -43,9 +43,10 @@ struct parallels_header { uint32_t catalog_entries; uint32_t nb_sectors; char padding[24]; -} __attribute__((packed)); +} QEMU_PACKED; typedef struct BDRVParallelsState { + CoMutex lock; uint32_t *catalog_bitmap; int catalog_size; @@ -88,17 +89,18 @@ static int parallels_open(BlockDriverState *bs, int flags) s->tracks = le32_to_cpu(ph.tracks); s->catalog_size = le32_to_cpu(ph.catalog_entries); - s->catalog_bitmap = qemu_malloc(s->catalog_size * 4); + s->catalog_bitmap = g_malloc(s->catalog_size * 4); if (bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4) != s->catalog_size * 4) goto fail; for (i = 0; i < s->catalog_size; i++) le32_to_cpus(&s->catalog_bitmap[i]); + qemu_co_mutex_init(&s->lock); return 0; fail: if (s->catalog_bitmap) - qemu_free(s->catalog_bitmap); + g_free(s->catalog_bitmap); return -1; } @@ -134,10 +136,21 @@ static int parallels_read(BlockDriverState *bs, int64_t sector_num, return 0; } +static coroutine_fn int parallels_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVParallelsState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = parallels_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static void parallels_close(BlockDriverState *bs) { BDRVParallelsState *s = bs->opaque; - qemu_free(s->catalog_bitmap); + g_free(s->catalog_bitmap); } static BlockDriver bdrv_parallels = { @@ -145,7 +158,7 @@ static BlockDriver bdrv_parallels = { .instance_size = sizeof(BDRVParallelsState), .bdrv_probe = parallels_probe, .bdrv_open = parallels_open, - .bdrv_read = parallels_read, + .bdrv_read = parallels_co_read, .bdrv_close = parallels_close, }; diff --git a/block/qcow.c b/block/qcow.c index f67d3d3..4814ed0 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -26,6 +26,7 @@ #include "module.h" #include #include "aes.h" +#include "migration.h" /**************************************************************/ /* QEMU COW block driver with compression and encryption support */ @@ -73,6 +74,8 @@ typedef struct BDRVQcowState { uint32_t crypt_method_header; AES_KEY aes_encrypt_key; AES_KEY aes_decrypt_key; + CoMutex lock; + Error *migration_blocker; } BDRVQcowState; static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); @@ -128,7 +131,7 @@ static int qcow_open(BlockDriverState *bs, int flags) s->l1_size = (header.size + (1LL << shift) - 1) >> shift; s->l1_table_offset = header.l1_table_offset; - s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t)); + s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t)); if (!s->l1_table) goto fail; if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) != @@ -138,13 +141,13 @@ static int qcow_open(BlockDriverState *bs, int flags) be64_to_cpus(&s->l1_table[i]); } /* alloc L2 cache */ - s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); + s->l2_cache = g_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); if (!s->l2_cache) goto fail; - s->cluster_cache = qemu_malloc(s->cluster_size); + s->cluster_cache = g_malloc(s->cluster_size); if (!s->cluster_cache) goto fail; - s->cluster_data = qemu_malloc(s->cluster_size); + s->cluster_data = g_malloc(s->cluster_size); if (!s->cluster_data) goto fail; s->cluster_cache_offset = -1; @@ -158,13 +161,21 @@ static int qcow_open(BlockDriverState *bs, int flags) goto fail; bs->backing_file[len] = '\0'; } + + /* Disable migration when qcow images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "qcow", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + + qemu_co_mutex_init(&s->lock); return 0; fail: - qemu_free(s->l1_table); - qemu_free(s->l2_cache); - qemu_free(s->cluster_cache); - qemu_free(s->cluster_data); + g_free(s->l1_table); + g_free(s->l2_cache); + g_free(s->cluster_cache); + g_free(s->cluster_data); return -1; } @@ -189,24 +200,6 @@ static int qcow_set_key(BlockDriverState *bs, const char *key) return -1; if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0) return -1; -#if 0 - /* test */ - { - uint8_t in[16]; - uint8_t out[16]; - uint8_t tmp[16]; - for(i=0;i<16;i++) - in[i] = i; - AES_encrypt(in, tmp, &s->aes_encrypt_key); - AES_decrypt(tmp, out, &s->aes_decrypt_key); - for(i = 0; i < 16; i++) - printf(" %02x", tmp[i]); - printf("\n"); - for(i = 0; i < 16; i++) - printf(" %02x", out[i]); - printf("\n"); - } -#endif return 0; } @@ -440,302 +433,193 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) return 0; } -#if 0 - -static int qcow_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { BDRVQcowState *s = bs->opaque; - int ret, index_in_cluster, n; + int index_in_cluster; + int ret = 0, n; uint64_t cluster_offset; + struct iovec hd_iov; + QEMUIOVector hd_qiov; + uint8_t *buf; + void *orig_buf; + + if (qiov->niov > 1) { + buf = orig_buf = qemu_blockalign(bs, qiov->size); + } else { + orig_buf = NULL; + buf = (uint8_t *)qiov->iov->iov_base; + } + + qemu_co_mutex_lock(&s->lock); - while (nb_sectors > 0) { - cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0); + while (nb_sectors != 0) { + /* prepare next request */ + cluster_offset = get_cluster_offset(bs, sector_num << 9, + 0, 0, 0, 0); index_in_cluster = sector_num & (s->cluster_sectors - 1); n = s->cluster_sectors - index_in_cluster; - if (n > nb_sectors) + if (n > nb_sectors) { n = nb_sectors; + } + if (!cluster_offset) { if (bs->backing_hd) { /* read from the base image */ - ret = bdrv_read(bs->backing_hd, sector_num, buf, n); - if (ret < 0) - return -1; + hd_iov.iov_base = (void *)buf; + hd_iov.iov_len = n * 512; + qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_readv(bs->backing_hd, sector_num, + n, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + goto fail; + } } else { + /* Note: in this case, no need to wait */ memset(buf, 0, 512 * n); } } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { - if (decompress_cluster(bs, cluster_offset) < 0) - return -1; - memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n); + /* add AIO support for compressed blocks ? */ + if (decompress_cluster(bs, cluster_offset) < 0) { + goto fail; + } + memcpy(buf, + s->cluster_cache + index_in_cluster * 512, 512 * n); } else { - ret = bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512); - if (ret != n * 512) - return -1; + if ((cluster_offset & 511) != 0) { + goto fail; + } + hd_iov.iov_base = (void *)buf; + hd_iov.iov_len = n * 512; + qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_readv(bs->file, + (cluster_offset >> 9) + index_in_cluster, + n, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + break; + } if (s->crypt_method) { - encrypt_sectors(s, sector_num, buf, buf, n, 0, + encrypt_sectors(s, sector_num, buf, buf, + n, 0, &s->aes_decrypt_key); } } + ret = 0; + nb_sectors -= n; sector_num += n; buf += n * 512; } - return 0; -} -#endif - -typedef struct QCowAIOCB { - BlockDriverAIOCB common; - int64_t sector_num; - QEMUIOVector *qiov; - uint8_t *buf; - void *orig_buf; - int nb_sectors; - int n; - uint64_t cluster_offset; - uint8_t *cluster_data; - struct iovec hd_iov; - QEMUIOVector hd_qiov; - BlockDriverAIOCB *hd_aiocb; -} QCowAIOCB; - -static void qcow_aio_cancel(BlockDriverAIOCB *blockacb) -{ - QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common); - if (acb->hd_aiocb) - bdrv_aio_cancel(acb->hd_aiocb); - qemu_aio_release(acb); -} -static AIOPool qcow_aio_pool = { - .aiocb_size = sizeof(QCowAIOCB), - .cancel = qcow_aio_cancel, -}; +done: + qemu_co_mutex_unlock(&s->lock); -static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque, int is_write) -{ - QCowAIOCB *acb; - - acb = qemu_aio_get(&qcow_aio_pool, bs, cb, opaque); - if (!acb) - return NULL; - acb->hd_aiocb = NULL; - acb->sector_num = sector_num; - acb->qiov = qiov; if (qiov->niov > 1) { - acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size); - if (is_write) - qemu_iovec_to_buffer(qiov, acb->buf); - } else { - acb->buf = (uint8_t *)qiov->iov->iov_base; + qemu_iovec_from_buffer(qiov, orig_buf, qiov->size); + qemu_vfree(orig_buf); } - acb->nb_sectors = nb_sectors; - acb->n = 0; - acb->cluster_offset = 0; - return acb; + + return ret; + +fail: + ret = -EIO; + goto done; } -static void qcow_aio_read_cb(void *opaque, int ret) +static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { - QCowAIOCB *acb = opaque; - BlockDriverState *bs = acb->common.bs; BDRVQcowState *s = bs->opaque; int index_in_cluster; + uint64_t cluster_offset; + const uint8_t *src_buf; + int ret = 0, n; + uint8_t *cluster_data = NULL; + struct iovec hd_iov; + QEMUIOVector hd_qiov; + uint8_t *buf; + void *orig_buf; - acb->hd_aiocb = NULL; - if (ret < 0) - goto done; - - redo: - /* post process the read buffer */ - if (!acb->cluster_offset) { - /* nothing to do */ - } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* nothing to do */ + s->cluster_cache_offset = -1; /* disable compressed cache */ + + if (qiov->niov > 1) { + buf = orig_buf = qemu_blockalign(bs, qiov->size); + qemu_iovec_to_buffer(qiov, buf); } else { - if (s->crypt_method) { - encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf, - acb->n, 0, - &s->aes_decrypt_key); - } + orig_buf = NULL; + buf = (uint8_t *)qiov->iov->iov_base; } - acb->nb_sectors -= acb->n; - acb->sector_num += acb->n; - acb->buf += acb->n * 512; + qemu_co_mutex_lock(&s->lock); - if (acb->nb_sectors == 0) { - /* request completed */ - ret = 0; - goto done; - } + while (nb_sectors != 0) { - /* prepare next AIO request */ - acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, - 0, 0, 0, 0); - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - acb->n = s->cluster_sectors - index_in_cluster; - if (acb->n > acb->nb_sectors) - acb->n = acb->nb_sectors; - - if (!acb->cluster_offset) { - if (bs->backing_hd) { - /* read from the base image */ - acb->hd_iov.iov_base = (void *)acb->buf; - acb->hd_iov.iov_len = acb->n * 512; - qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); - acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num, - &acb->hd_qiov, acb->n, qcow_aio_read_cb, acb); - if (acb->hd_aiocb == NULL) - goto done; - } else { - /* Note: in this case, no need to wait */ - memset(acb->buf, 0, 512 * acb->n); - goto redo; + index_in_cluster = sector_num & (s->cluster_sectors - 1); + n = s->cluster_sectors - index_in_cluster; + if (n > nb_sectors) { + n = nb_sectors; } - } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* add AIO support for compressed blocks ? */ - if (decompress_cluster(bs, acb->cluster_offset) < 0) - goto done; - memcpy(acb->buf, - s->cluster_cache + index_in_cluster * 512, 512 * acb->n); - goto redo; - } else { - if ((acb->cluster_offset & 511) != 0) { + cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0, + index_in_cluster, + index_in_cluster + n); + if (!cluster_offset || (cluster_offset & 511) != 0) { ret = -EIO; - goto done; + break; + } + if (s->crypt_method) { + if (!cluster_data) { + cluster_data = g_malloc0(s->cluster_size); + } + encrypt_sectors(s, sector_num, cluster_data, buf, + n, 1, &s->aes_encrypt_key); + src_buf = cluster_data; + } else { + src_buf = buf; } - acb->hd_iov.iov_base = (void *)acb->buf; - acb->hd_iov.iov_len = acb->n * 512; - qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); - acb->hd_aiocb = bdrv_aio_readv(bs->file, - (acb->cluster_offset >> 9) + index_in_cluster, - &acb->hd_qiov, acb->n, qcow_aio_read_cb, acb); - if (acb->hd_aiocb == NULL) - goto done; - } - - return; - -done: - if (acb->qiov->niov > 1) { - qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size); - qemu_vfree(acb->orig_buf); - } - acb->common.cb(acb->common.opaque, ret); - qemu_aio_release(acb); -} - -static BlockDriverAIOCB *qcow_aio_readv(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) -{ - QCowAIOCB *acb; - - acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); - if (!acb) - return NULL; - - qcow_aio_read_cb(acb, 0); - return &acb->common; -} - -static void qcow_aio_write_cb(void *opaque, int ret) -{ - QCowAIOCB *acb = opaque; - BlockDriverState *bs = acb->common.bs; - BDRVQcowState *s = bs->opaque; - int index_in_cluster; - uint64_t cluster_offset; - const uint8_t *src_buf; - - acb->hd_aiocb = NULL; - - if (ret < 0) - goto done; - - acb->nb_sectors -= acb->n; - acb->sector_num += acb->n; - acb->buf += acb->n * 512; - if (acb->nb_sectors == 0) { - /* request completed */ + hd_iov.iov_base = (void *)src_buf; + hd_iov.iov_len = n * 512; + qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_writev(bs->file, + (cluster_offset >> 9) + index_in_cluster, + n, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + break; + } ret = 0; - goto done; - } - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - acb->n = s->cluster_sectors - index_in_cluster; - if (acb->n > acb->nb_sectors) - acb->n = acb->nb_sectors; - cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0, - index_in_cluster, - index_in_cluster + acb->n); - if (!cluster_offset || (cluster_offset & 511) != 0) { - ret = -EIO; - goto done; - } - if (s->crypt_method) { - if (!acb->cluster_data) { - acb->cluster_data = qemu_mallocz(s->cluster_size); - if (!acb->cluster_data) { - ret = -ENOMEM; - goto done; - } - } - encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf, - acb->n, 1, &s->aes_encrypt_key); - src_buf = acb->cluster_data; - } else { - src_buf = acb->buf; + nb_sectors -= n; + sector_num += n; + buf += n * 512; } + qemu_co_mutex_unlock(&s->lock); - acb->hd_iov.iov_base = (void *)src_buf; - acb->hd_iov.iov_len = acb->n * 512; - qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); - acb->hd_aiocb = bdrv_aio_writev(bs->file, - (cluster_offset >> 9) + index_in_cluster, - &acb->hd_qiov, acb->n, - qcow_aio_write_cb, acb); - if (acb->hd_aiocb == NULL) - goto done; - return; + if (qiov->niov > 1) { + qemu_vfree(orig_buf); + } + g_free(cluster_data); -done: - if (acb->qiov->niov > 1) - qemu_vfree(acb->orig_buf); - acb->common.cb(acb->common.opaque, ret); - qemu_aio_release(acb); + return ret; } -static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) +static void qcow_close(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; - QCowAIOCB *acb; - s->cluster_cache_offset = -1; /* disable compressed cache */ + g_free(s->l1_table); + g_free(s->l2_cache); + g_free(s->cluster_cache); + g_free(s->cluster_data); - acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); - if (!acb) - return NULL; - - - qcow_aio_write_cb(acb, 0); - return &acb->common; -} - -static void qcow_close(BlockDriverState *bs) -{ - BDRVQcowState *s = bs->opaque; - qemu_free(s->l1_table); - qemu_free(s->l2_cache); - qemu_free(s->cluster_cache); - qemu_free(s->cluster_data); + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } static int qcow_create(const char *filename, QEMUOptionParameter *options) @@ -863,9 +747,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, if (nb_sectors != s->cluster_sectors) return -EINVAL; - out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128); - if (!out_buf) - return -1; + out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128); /* best compression, small window, no zlib header */ memset(&strm, 0, sizeof(strm)); @@ -873,8 +755,8 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY); if (ret != 0) { - qemu_free(out_buf); - return -1; + ret = -EINVAL; + goto fail; } strm.avail_in = s->cluster_size; @@ -884,9 +766,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, ret = deflate(&strm, Z_FINISH); if (ret != Z_STREAM_END && ret != Z_OK) { - qemu_free(out_buf); deflateEnd(&strm); - return -1; + ret = -EINVAL; + goto fail; } out_len = strm.next_out - out_buf; @@ -894,30 +776,34 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num, if (ret != Z_STREAM_END || out_len >= s->cluster_size) { /* could not compress: write normal cluster */ - bdrv_write(bs, sector_num, buf, s->cluster_sectors); + ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors); + if (ret < 0) { + goto fail; + } } else { cluster_offset = get_cluster_offset(bs, sector_num << 9, 2, out_len, 0, 0); + if (cluster_offset == 0) { + ret = -EIO; + goto fail; + } + cluster_offset &= s->cluster_offset_mask; - if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) { - qemu_free(out_buf); - return -1; + ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len); + if (ret < 0) { + goto fail; } } - qemu_free(out_buf); - return 0; -} - -static int qcow_flush(BlockDriverState *bs) -{ - return bdrv_flush(bs->file); + ret = 0; +fail: + g_free(out_buf); + return ret; } -static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque) +static coroutine_fn int qcow_co_flush(BlockDriverState *bs) { - return bdrv_aio_flush(bs->file, cb, opaque); + return bdrv_co_flush(bs->file); } static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) @@ -954,15 +840,16 @@ static BlockDriver bdrv_qcow = { .bdrv_open = qcow_open, .bdrv_close = qcow_close, .bdrv_create = qcow_create, - .bdrv_flush = qcow_flush, - .bdrv_is_allocated = qcow_is_allocated, - .bdrv_set_key = qcow_set_key, - .bdrv_make_empty = qcow_make_empty, - .bdrv_aio_readv = qcow_aio_readv, - .bdrv_aio_writev = qcow_aio_writev, - .bdrv_aio_flush = qcow_aio_flush, - .bdrv_write_compressed = qcow_write_compressed, - .bdrv_get_info = qcow_get_info, + + .bdrv_co_readv = qcow_co_readv, + .bdrv_co_writev = qcow_co_writev, + .bdrv_co_flush_to_disk = qcow_co_flush, + .bdrv_is_allocated = qcow_is_allocated, + + .bdrv_set_key = qcow_set_key, + .bdrv_make_empty = qcow_make_empty, + .bdrv_write_compressed = qcow_write_compressed, + .bdrv_get_info = qcow_get_info, .create_options = qcow_create_options, }; diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 3824739..340a6f2 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -49,9 +49,9 @@ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables, Qcow2Cache *c; int i; - c = qemu_mallocz(sizeof(*c)); + c = g_malloc0(sizeof(*c)); c->size = num_tables; - c->entries = qemu_mallocz(sizeof(*c->entries) * num_tables); + c->entries = g_malloc0(sizeof(*c->entries) * num_tables); c->writethrough = writethrough; for (i = 0; i < c->size; i++) { @@ -70,8 +70,8 @@ int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c) qemu_vfree(c->entries[i].table); } - qemu_free(c->entries); - qemu_free(c); + g_free(c->entries); + g_free(c); return 0; } @@ -312,3 +312,15 @@ found: c->entries[i].dirty = true; } +bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c, + bool enable) +{ + bool old = c->writethrough; + + if (!old && enable) { + qcow2_cache_flush(bs, c); + } + + c->writethrough = enable; + return old; +} diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 750abe3..f4e049f 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -53,24 +53,24 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size) } #ifdef DEBUG_ALLOC2 - printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size); + fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, new_l1_size); #endif new_l1_size2 = sizeof(uint64_t) * new_l1_size; - new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512)); + new_l1_table = g_malloc0(align_offset(new_l1_size2, 512)); memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t)); /* write new table (align to cluster) */ BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE); new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2); if (new_l1_table_offset < 0) { - qemu_free(new_l1_table); + g_free(new_l1_table); return new_l1_table_offset; } ret = qcow2_cache_flush(bs, s->refcount_block_cache); if (ret < 0) { - return ret; + goto fail; } BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE); @@ -90,14 +90,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size) if (ret < 0) { goto fail; } - qemu_free(s->l1_table); + g_free(s->l1_table); qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t)); s->l1_table_offset = new_l1_table_offset; s->l1_table = new_l1_table; s->l1_size = new_l1_size; return 0; fail: - qemu_free(new_l1_table); + g_free(new_l1_table); qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2); return ret; } @@ -381,10 +381,10 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect, * For a given offset of the disk image, find the cluster offset in * qcow2 file. The offset is stored in *cluster_offset. * - * on entry, *num is the number of contiguous clusters we'd like to + * on entry, *num is the number of contiguous sectors we'd like to * access following offset. * - * on exit, *num is the number of contiguous clusters we can read. + * on exit, *num is the number of contiguous sectors we can read. * * Return 0, if the offset is found * Return -errno, otherwise. @@ -568,8 +568,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, } cluster_offset = be64_to_cpu(l2_table[l2_index]); - if (cluster_offset & QCOW_OFLAG_COPIED) - return cluster_offset & ~QCOW_OFLAG_COPIED; + if (cluster_offset & QCOW_OFLAG_COPIED) { + qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); + return 0; + } if (cluster_offset) qcow2_free_any_clusters(bs, cluster_offset, 1); @@ -612,7 +614,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) if (m->nb_clusters == 0) return 0; - old_cluster = qemu_malloc(m->nb_clusters * sizeof(uint64_t)); + old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t)); /* copy content of unmodified sectors */ start_sect = (m->offset & ~(s->cluster_size - 1)) >> 9; @@ -683,7 +685,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) ret = 0; err: - qemu_free(old_cluster); + g_free(old_cluster); return ret; } @@ -694,15 +696,15 @@ err: * If the offset is not found, allocate a new cluster. * * If the cluster was already allocated, m->nb_clusters is set to 0, - * m->depends_on is set to NULL and the other fields in m are meaningless. + * other fields in m are meaningless. * * If the cluster is newly allocated, m->nb_clusters is set to the number of - * contiguous clusters that have been allocated. This may be 0 if the request - * conflict with another write request in flight; in this case, m->depends_on - * is set and the remaining fields of m are meaningless. + * contiguous clusters that have been allocated. In this case, the other + * fields of m are valid and contain information about the first allocated + * cluster. * - * If m->nb_clusters is non-zero, the other fields of m are valid and contain - * information about the first allocated cluster. + * If the request conflicts with another write request in flight, the coroutine + * is queued and will be reentered when the dependency has completed. * * Return 0 on success and -errno in error cases */ @@ -721,6 +723,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, return ret; } +again: nb_clusters = size_to_clusters(s, n_end << 9); nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); @@ -735,7 +738,6 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, cluster_offset &= ~QCOW_OFLAG_COPIED; m->nb_clusters = 0; - m->depends_on = NULL; goto out; } @@ -776,28 +778,28 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, */ QLIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) { - uint64_t end_offset = offset + nb_clusters * s->cluster_size; - uint64_t old_offset = old_alloc->offset; - uint64_t old_end_offset = old_alloc->offset + - old_alloc->nb_clusters * s->cluster_size; + uint64_t start = offset >> s->cluster_bits; + uint64_t end = start + nb_clusters; + uint64_t old_start = old_alloc->offset >> s->cluster_bits; + uint64_t old_end = old_start + old_alloc->nb_clusters; - if (end_offset < old_offset || offset > old_end_offset) { + if (end < old_start || start > old_end) { /* No intersection */ } else { - if (offset < old_offset) { + if (start < old_start) { /* Stop at the start of a running allocation */ - nb_clusters = (old_offset - offset) >> s->cluster_bits; + nb_clusters = old_start - start; } else { nb_clusters = 0; } if (nb_clusters == 0) { - /* Set dependency and wait for a callback */ - m->depends_on = old_alloc; - m->nb_clusters = 0; - *num = 0; - ret = 0; - goto fail; + /* Wait for the dependency to complete. We need to recheck + * the free/allocated clusters when we continue. */ + qemu_co_mutex_unlock(&s->lock); + qemu_co_queue_wait(&old_alloc->dependent_requests); + qemu_co_mutex_lock(&s->lock); + goto again; } } } @@ -806,26 +808,25 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, abort(); } + /* save info needed for meta data update */ + m->offset = offset; + m->n_start = n_start; + m->nb_clusters = nb_clusters; + QLIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight); /* allocate a new cluster */ cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size); if (cluster_offset < 0) { - QLIST_REMOVE(m, next_in_flight); ret = cluster_offset; goto fail; } - /* save info needed for meta data update */ - m->offset = offset; - m->n_start = n_start; - m->nb_clusters = nb_clusters; - out: ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); if (ret < 0) { - return ret; + goto fail_put; } m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end); @@ -837,6 +838,8 @@ out: fail: qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); +fail_put: + QLIST_REMOVE(m, next_in_flight); return ret; } diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 915d85a..9605367 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -41,7 +41,7 @@ int qcow2_refcount_init(BlockDriverState *bs) int ret, refcount_table_size2, i; refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t); - s->refcount_table = qemu_malloc(refcount_table_size2); + s->refcount_table = g_malloc(refcount_table_size2); if (s->refcount_table_size > 0) { BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD); ret = bdrv_pread(bs->file, s->refcount_table_offset, @@ -59,7 +59,7 @@ int qcow2_refcount_init(BlockDriverState *bs) void qcow2_refcount_close(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; - qemu_free(s->refcount_table); + g_free(s->refcount_table); } @@ -323,8 +323,8 @@ static int alloc_refcount_block(BlockDriverState *bs, uint64_t meta_offset = (blocks_used * refcount_block_clusters) * s->cluster_size; uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size; - uint16_t *new_blocks = qemu_mallocz(blocks_clusters * s->cluster_size); - uint64_t *new_table = qemu_mallocz(table_size * sizeof(uint64_t)); + uint16_t *new_blocks = g_malloc0(blocks_clusters * s->cluster_size); + uint64_t *new_table = g_malloc0(table_size * sizeof(uint64_t)); assert(meta_offset >= (s->free_cluster_index * s->cluster_size)); @@ -349,7 +349,7 @@ static int alloc_refcount_block(BlockDriverState *bs, BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS); ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks, blocks_clusters * s->cluster_size); - qemu_free(new_blocks); + g_free(new_blocks); if (ret < 0) { goto fail_table; } @@ -385,7 +385,7 @@ static int alloc_refcount_block(BlockDriverState *bs, uint64_t old_table_offset = s->refcount_table_offset; uint64_t old_table_size = s->refcount_table_size; - qemu_free(s->refcount_table); + g_free(s->refcount_table); s->refcount_table = new_table; s->refcount_table_size = table_size; s->refcount_table_offset = table_offset; @@ -403,7 +403,7 @@ static int alloc_refcount_block(BlockDriverState *bs, return new_block; fail_table: - qemu_free(new_table); + g_free(new_table); fail_block: if (*refcount_block != NULL) { qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block); @@ -422,7 +422,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, int ret; #ifdef DEBUG_ALLOC2 - printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n", + fprintf(stderr, "update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n", offset, length, addend); #endif if (length < 0) { @@ -556,7 +556,7 @@ retry: } } #ifdef DEBUG_ALLOC2 - printf("alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n", + fprintf(stderr, "alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n", size, (s->free_cluster_index - nb_clusters) << s->cluster_bits); #endif @@ -680,24 +680,6 @@ void qcow2_free_any_clusters(BlockDriverState *bs, -void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset, - int64_t size) -{ - int refcount; - int64_t start, last, cluster_offset; - uint16_t *p; - - start = offset & ~(s->cluster_size - 1); - last = (offset + size - 1) & ~(s->cluster_size - 1); - for(cluster_offset = start; cluster_offset <= last; - cluster_offset += s->cluster_size) { - p = &s->refcount_block[cluster_offset >> s->cluster_bits]; - refcount = be16_to_cpu(*p); - refcount++; - *p = cpu_to_be16(refcount); - } -} - /* update the refcounts of snapshots and the copied flag */ int qcow2_update_snapshot_refcount(BlockDriverState *bs, int64_t l1_table_offset, int l1_size, int addend) @@ -705,22 +687,33 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, BDRVQcowState *s = bs->opaque; uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated; int64_t old_offset, old_l2_offset; - int i, j, l1_modified, nb_csectors, refcount; + int i, j, l1_modified = 0, nb_csectors, refcount; int ret; + bool old_l2_writethrough, old_refcount_writethrough; + + /* Switch caches to writeback mode during update */ + old_l2_writethrough = + qcow2_cache_set_writethrough(bs, s->l2_table_cache, false); + old_refcount_writethrough = + qcow2_cache_set_writethrough(bs, s->refcount_block_cache, false); l2_table = NULL; l1_table = NULL; l1_size2 = l1_size * sizeof(uint64_t); if (l1_table_offset != s->l1_table_offset) { if (l1_size2 != 0) { - l1_table = qemu_mallocz(align_offset(l1_size2, 512)); + l1_table = g_malloc0(align_offset(l1_size2, 512)); } else { l1_table = NULL; } l1_allocated = 1; if (bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2) != l1_size2) + { + ret = -EIO; goto fail; + } + for(i = 0;i < l1_size; i++) be64_to_cpus(&l1_table[i]); } else { @@ -729,7 +722,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, l1_allocated = 0; } - l1_modified = 0; for(i = 0; i < l1_size; i++) { l2_offset = l1_table[i]; if (l2_offset) { @@ -773,6 +765,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, } if (refcount < 0) { + ret = -EIO; goto fail; } } @@ -803,6 +796,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, refcount = get_refcount(bs, l2_offset >> s->cluster_bits); } if (refcount < 0) { + ret = -EIO; goto fail; } else if (refcount == 1) { l2_offset |= QCOW_OFLAG_COPIED; @@ -813,6 +807,18 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, } } } + + ret = 0; +fail: + if (l2_table) { + qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); + } + + /* Enable writethrough cache mode again */ + qcow2_cache_set_writethrough(bs, s->l2_table_cache, old_l2_writethrough); + qcow2_cache_set_writethrough(bs, s->refcount_block_cache, + old_refcount_writethrough); + if (l1_modified) { for(i = 0; i < l1_size; i++) cpu_to_be64s(&l1_table[i]); @@ -823,16 +829,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs, be64_to_cpus(&l1_table[i]); } if (l1_allocated) - qemu_free(l1_table); - return 0; - fail: - if (l2_table) { - qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); - } - - if (l1_allocated) - qemu_free(l1_table); - return -EIO; + g_free(l1_table); + return ret; } @@ -905,7 +903,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, /* Read L2 table from disk */ l2_size = s->l2_size * sizeof(uint64_t); - l2_table = qemu_malloc(l2_size); + l2_table = g_malloc(l2_size); if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size) goto fail; @@ -963,12 +961,12 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, } } - qemu_free(l2_table); + g_free(l2_table); return 0; fail: fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n"); - qemu_free(l2_table); + g_free(l2_table); return -EIO; } @@ -1001,7 +999,7 @@ static int check_refcounts_l1(BlockDriverState *bs, if (l1_size2 == 0) { l1_table = NULL; } else { - l1_table = qemu_malloc(l1_size2); + l1_table = g_malloc(l1_size2); if (bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2) != l1_size2) goto fail; @@ -1049,13 +1047,13 @@ static int check_refcounts_l1(BlockDriverState *bs, } } } - qemu_free(l1_table); + g_free(l1_table); return 0; fail: fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n"); res->check_errors++; - qemu_free(l1_table); + g_free(l1_table); return -EIO; } @@ -1063,7 +1061,7 @@ fail: * Checks an image for refcount consistency. * * Returns 0 if no errors are found, the number of errors in case the image is - * detected as corrupted, and -errno when an internal error occured. + * detected as corrupted, and -errno when an internal error occurred. */ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) { @@ -1076,7 +1074,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) size = bdrv_getlength(bs->file); nb_clusters = size_to_clusters(s, size); - refcount_table = qemu_mallocz(nb_clusters * sizeof(uint16_t)); + refcount_table = g_malloc0(nb_clusters * sizeof(uint16_t)); /* header */ inc_refcounts(bs, res, refcount_table, nb_clusters, @@ -1086,7 +1084,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, s->l1_table_offset, s->l1_size, 1); if (ret < 0) { - return ret; + goto fail; } /* snapshots */ @@ -1095,7 +1093,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, sn->l1_table_offset, sn->l1_size, 0); if (ret < 0) { - return ret; + goto fail; } } inc_refcounts(bs, res, refcount_table, nb_clusters, @@ -1159,8 +1157,11 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) } } - qemu_free(refcount_table); + ret = 0; - return 0; +fail: + g_free(refcount_table); + + return ret; } diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 74823a5..bdc33ba 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -26,7 +26,7 @@ #include "block_int.h" #include "block/qcow2.h" -typedef struct __attribute__((packed)) QCowSnapshotHeader { +typedef struct QEMU_PACKED QCowSnapshotHeader { /* header is 8 byte aligned */ uint64_t l1_table_offset; @@ -52,10 +52,10 @@ void qcow2_free_snapshots(BlockDriverState *bs) int i; for(i = 0; i < s->nb_snapshots; i++) { - qemu_free(s->snapshots[i].name); - qemu_free(s->snapshots[i].id_str); + g_free(s->snapshots[i].name); + g_free(s->snapshots[i].id_str); } - qemu_free(s->snapshots); + g_free(s->snapshots); s->snapshots = NULL; s->nb_snapshots = 0; } @@ -76,7 +76,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) } offset = s->snapshots_offset; - s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot)); + s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot)); for(i = 0; i < s->nb_snapshots; i++) { offset = align_offset(offset, 8); if (bdrv_pread(bs->file, offset, &h, sizeof(h)) != sizeof(h)) @@ -96,13 +96,13 @@ int qcow2_read_snapshots(BlockDriverState *bs) offset += extra_data_size; - sn->id_str = qemu_malloc(id_str_size + 1); + sn->id_str = g_malloc(id_str_size + 1); if (bdrv_pread(bs->file, offset, sn->id_str, id_str_size) != id_str_size) goto fail; offset += id_str_size; sn->id_str[id_str_size] = '\0'; - sn->name = qemu_malloc(name_size + 1); + sn->name = g_malloc(name_size + 1); if (bdrv_pread(bs->file, offset, sn->name, name_size) != name_size) goto fail; offset += name_size; @@ -252,10 +252,10 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) return -ENOENT; - sn->id_str = qemu_strdup(sn_info->id_str); + sn->id_str = g_strdup(sn_info->id_str); if (!sn->id_str) goto fail; - sn->name = qemu_strdup(sn_info->name); + sn->name = g_strdup(sn_info->name); if (!sn->name) goto fail; sn->vm_state_size = sn_info->vm_state_size; @@ -278,7 +278,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) sn->l1_size = s->l1_size; if (s->l1_size != 0) { - l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t)); + l1_table = g_malloc(s->l1_size * sizeof(uint64_t)); } else { l1_table = NULL; } @@ -289,13 +289,13 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) if (bdrv_pwrite_sync(bs->file, sn->l1_table_offset, l1_table, s->l1_size * sizeof(uint64_t)) < 0) goto fail; - qemu_free(l1_table); + g_free(l1_table); l1_table = NULL; - snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot)); + snapshots1 = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot)); if (s->snapshots) { memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot)); - qemu_free(s->snapshots); + g_free(s->snapshots); } s->snapshots = snapshots1; s->snapshots[s->nb_snapshots++] = *sn; @@ -303,12 +303,15 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) if (qcow2_write_snapshots(bs) < 0) goto fail; #ifdef DEBUG_ALLOC - qcow2_check_refcounts(bs); + { + BdrvCheckResult result = {0}; + qcow2_check_refcounts(bs, &result); + } #endif return 0; fail: - qemu_free(sn->name); - qemu_free(l1_table); + g_free(sn->name); + g_free(l1_table); return -1; } @@ -317,7 +320,8 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) { BDRVQcowState *s = bs->opaque; QCowSnapshot *sn; - int i, snapshot_index, l1_size2; + int i, snapshot_index; + int cur_l1_bytes, sn_l1_bytes; snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); if (snapshot_index < 0) @@ -330,14 +334,19 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0) goto fail; - s->l1_size = sn->l1_size; - l1_size2 = s->l1_size * sizeof(uint64_t); + cur_l1_bytes = s->l1_size * sizeof(uint64_t); + sn_l1_bytes = sn->l1_size * sizeof(uint64_t); + + if (cur_l1_bytes > sn_l1_bytes) { + memset(s->l1_table + sn->l1_size, 0, cur_l1_bytes - sn_l1_bytes); + } + /* copy the snapshot l1 table to the current l1 table */ if (bdrv_pread(bs->file, sn->l1_table_offset, - s->l1_table, l1_size2) != l1_size2) + s->l1_table, sn_l1_bytes) < 0) goto fail; if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, - s->l1_table, l1_size2) < 0) + s->l1_table, cur_l1_bytes) < 0) goto fail; for(i = 0;i < s->l1_size; i++) { be64_to_cpus(&s->l1_table[i]); @@ -347,7 +356,10 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) goto fail; #ifdef DEBUG_ALLOC - qcow2_check_refcounts(bs); + { + BdrvCheckResult result = {0}; + qcow2_check_refcounts(bs, &result); + } #endif return 0; fail: @@ -374,8 +386,8 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) return ret; qcow2_free_clusters(bs, sn->l1_table_offset, sn->l1_size * sizeof(uint64_t)); - qemu_free(sn->id_str); - qemu_free(sn->name); + g_free(sn->id_str); + g_free(sn->name); memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn)); s->nb_snapshots--; ret = qcow2_write_snapshots(bs); @@ -384,7 +396,10 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) return ret; } #ifdef DEBUG_ALLOC - qcow2_check_refcounts(bs); + { + BdrvCheckResult result = {0}; + qcow2_check_refcounts(bs, &result); + } #endif return 0; } @@ -401,7 +416,7 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) return s->nb_snapshots; } - sn_tab = qemu_mallocz(s->nb_snapshots * sizeof(QEMUSnapshotInfo)); + sn_tab = g_malloc0(s->nb_snapshots * sizeof(QEMUSnapshotInfo)); for(i = 0; i < s->nb_snapshots; i++) { sn_info = sn_tab + i; sn = s->snapshots + i; @@ -433,11 +448,11 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name) s->l1_size = sn->l1_size; l1_size2 = s->l1_size * sizeof(uint64_t); if (s->l1_table != NULL) { - qemu_free(s->l1_table); + g_free(s->l1_table); } s->l1_table_offset = sn->l1_table_offset; - s->l1_table = qemu_mallocz(align_offset(l1_size2, 512)); + s->l1_table = g_malloc0(align_offset(l1_size2, 512)); if (bdrv_pread(bs->file, sn->l1_table_offset, s->l1_table, l1_size2) != l1_size2) { diff --git a/block/qcow2.c b/block/qcow2.c index 75b8bec..d7805ce 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -87,6 +87,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, while (offset < end_offset) { #ifdef DEBUG_EXT + BDRVQcowState *s = bs->opaque; /* Sanity check */ if (offset > s->cluster_size) printf("qcow2_read_extension: suspicious offset %lu\n", offset); @@ -216,7 +217,7 @@ static int qcow2_open(BlockDriverState *bs, int flags) } s->l1_table_offset = header.l1_table_offset; if (s->l1_size > 0) { - s->l1_table = qemu_mallocz( + s->l1_table = g_malloc0( align_offset(s->l1_size * sizeof(uint64_t), 512)); ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)); @@ -229,16 +230,17 @@ static int qcow2_open(BlockDriverState *bs, int flags) } /* alloc L2 table/refcount block cache */ - writethrough = ((flags & BDRV_O_CACHE_MASK) == 0); + writethrough = ((flags & BDRV_O_CACHE_WB) == 0); s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE, writethrough); s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE, writethrough); - s->cluster_cache = qemu_malloc(s->cluster_size); + s->cluster_cache = g_malloc(s->cluster_size); /* one more sector for decompressed data alignment */ - s->cluster_data = qemu_malloc(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size + s->cluster_data = qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size + 512); s->cluster_cache_offset = -1; + s->flags = flags; ret = qcow2_refcount_init(bs); if (ret != 0) { @@ -276,20 +278,26 @@ static int qcow2_open(BlockDriverState *bs, int flags) goto fail; } + /* Initialise locks */ + qemu_co_mutex_init(&s->lock); + #ifdef DEBUG_ALLOC - qcow2_check_refcounts(bs); + { + BdrvCheckResult result = {0}; + qcow2_check_refcounts(bs, &result); + } #endif return ret; fail: qcow2_free_snapshots(bs); qcow2_refcount_close(bs); - qemu_free(s->l1_table); + g_free(s->l1_table); if (s->l2_table_cache) { qcow2_cache_destroy(bs, s->l2_table_cache); } - qemu_free(s->cluster_cache); - qemu_free(s->cluster_data); + g_free(s->cluster_cache); + qemu_vfree(s->cluster_data); return ret; } @@ -369,376 +377,250 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, return n1; } -typedef struct QCowAIOCB { - BlockDriverAIOCB common; - int64_t sector_num; - QEMUIOVector *qiov; - int remaining_sectors; - int cur_nr_sectors; /* number of sectors in current iteration */ - uint64_t bytes_done; - uint64_t cluster_offset; - uint8_t *cluster_data; - BlockDriverAIOCB *hd_aiocb; - QEMUIOVector hd_qiov; - QEMUBH *bh; - QCowL2Meta l2meta; - QLIST_ENTRY(QCowAIOCB) next_depend; -} QCowAIOCB; - -static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb) -{ - QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common); - if (acb->hd_aiocb) - bdrv_aio_cancel(acb->hd_aiocb); - qemu_aio_release(acb); -} - -static AIOPool qcow2_aio_pool = { - .aiocb_size = sizeof(QCowAIOCB), - .cancel = qcow2_aio_cancel, -}; - -static void qcow2_aio_read_cb(void *opaque, int ret); -static void qcow2_aio_read_bh(void *opaque) -{ - QCowAIOCB *acb = opaque; - qemu_bh_delete(acb->bh); - acb->bh = NULL; - qcow2_aio_read_cb(opaque, 0); -} - -static int qcow2_schedule_bh(QEMUBHFunc *cb, QCowAIOCB *acb) -{ - if (acb->bh) - return -EIO; - - acb->bh = qemu_bh_new(cb, acb); - if (!acb->bh) - return -EIO; - - qemu_bh_schedule(acb->bh); - - return 0; -} - -static void qcow2_aio_read_cb(void *opaque, int ret) +static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num, + int remaining_sectors, QEMUIOVector *qiov) { - QCowAIOCB *acb = opaque; - BlockDriverState *bs = acb->common.bs; BDRVQcowState *s = bs->opaque; int index_in_cluster, n1; + int ret; + int cur_nr_sectors; /* number of sectors in current iteration */ + uint64_t cluster_offset = 0; + uint64_t bytes_done = 0; + QEMUIOVector hd_qiov; + uint8_t *cluster_data = NULL; - acb->hd_aiocb = NULL; - if (ret < 0) - goto done; + qemu_iovec_init(&hd_qiov, qiov->niov); - /* post process the read buffer */ - if (!acb->cluster_offset) { - /* nothing to do */ - } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* nothing to do */ - } else { - if (s->crypt_method) { - qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, acb->cur_nr_sectors, 0, &s->aes_decrypt_key); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - acb->cur_nr_sectors * 512); - qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data, - 512 * acb->cur_nr_sectors); - } - } + qemu_co_mutex_lock(&s->lock); - acb->remaining_sectors -= acb->cur_nr_sectors; - acb->sector_num += acb->cur_nr_sectors; - acb->bytes_done += acb->cur_nr_sectors * 512; + while (remaining_sectors != 0) { - if (acb->remaining_sectors == 0) { - /* request completed */ - ret = 0; - goto done; - } - - /* prepare next AIO request */ - acb->cur_nr_sectors = acb->remaining_sectors; - if (s->crypt_method) { - acb->cur_nr_sectors = MIN(acb->cur_nr_sectors, - QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); - } + /* prepare next request */ + cur_nr_sectors = remaining_sectors; + if (s->crypt_method) { + cur_nr_sectors = MIN(cur_nr_sectors, + QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); + } - ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9, - &acb->cur_nr_sectors, &acb->cluster_offset); - if (ret < 0) { - goto done; - } + ret = qcow2_get_cluster_offset(bs, sector_num << 9, + &cur_nr_sectors, &cluster_offset); + if (ret < 0) { + goto fail; + } - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - acb->cur_nr_sectors * 512); - - if (!acb->cluster_offset) { - - if (bs->backing_hd) { - /* read from the base image */ - n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov, - acb->sector_num, acb->cur_nr_sectors); - if (n1 > 0) { - BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); - acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num, - &acb->hd_qiov, n1, qcow2_aio_read_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto done; + index_in_cluster = sector_num & (s->cluster_sectors - 1); + + qemu_iovec_reset(&hd_qiov); + qemu_iovec_copy(&hd_qiov, qiov, bytes_done, + cur_nr_sectors * 512); + + if (!cluster_offset) { + + if (bs->backing_hd) { + /* read from the base image */ + n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov, + sector_num, cur_nr_sectors); + if (n1 > 0) { + BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_readv(bs->backing_hd, sector_num, + n1, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + goto fail; + } } } else { - ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb); - if (ret < 0) - goto done; + /* Note: in this case, no need to wait */ + qemu_iovec_memset(&hd_qiov, 0, 512 * cur_nr_sectors); + } + } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { + /* add AIO support for compressed blocks ? */ + ret = qcow2_decompress_cluster(bs, cluster_offset); + if (ret < 0) { + goto fail; } - } else { - /* Note: in this case, no need to wait */ - qemu_iovec_memset(&acb->hd_qiov, 0, 512 * acb->cur_nr_sectors); - ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb); - if (ret < 0) - goto done; - } - } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* add AIO support for compressed blocks ? */ - ret = qcow2_decompress_cluster(bs, acb->cluster_offset); - if (ret < 0) { - goto done; - } - qemu_iovec_from_buffer(&acb->hd_qiov, - s->cluster_cache + index_in_cluster * 512, - 512 * acb->cur_nr_sectors); + qemu_iovec_from_buffer(&hd_qiov, + s->cluster_cache + index_in_cluster * 512, + 512 * cur_nr_sectors); + } else { + if ((cluster_offset & 511) != 0) { + ret = -EIO; + goto fail; + } - ret = qcow2_schedule_bh(qcow2_aio_read_bh, acb); - if (ret < 0) - goto done; - } else { - if ((acb->cluster_offset & 511) != 0) { - ret = -EIO; - goto done; - } + if (s->crypt_method) { + /* + * For encrypted images, read everything into a temporary + * contiguous buffer on which the AES functions can work. + */ + if (!cluster_data) { + cluster_data = + qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); + } - if (s->crypt_method) { - /* - * For encrypted images, read everything into a temporary - * contiguous buffer on which the AES functions can work. - */ - if (!acb->cluster_data) { - acb->cluster_data = - qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); + assert(cur_nr_sectors <= + QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); + qemu_iovec_reset(&hd_qiov); + qemu_iovec_add(&hd_qiov, cluster_data, + 512 * cur_nr_sectors); } - assert(acb->cur_nr_sectors <= - QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, - 512 * acb->cur_nr_sectors); + BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_readv(bs->file, + (cluster_offset >> 9) + index_in_cluster, + cur_nr_sectors, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + goto fail; + } + if (s->crypt_method) { + qcow2_encrypt_sectors(s, sector_num, cluster_data, + cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key); + qemu_iovec_reset(&hd_qiov); + qemu_iovec_copy(&hd_qiov, qiov, bytes_done, + cur_nr_sectors * 512); + qemu_iovec_from_buffer(&hd_qiov, cluster_data, + 512 * cur_nr_sectors); + } } - BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - acb->hd_aiocb = bdrv_aio_readv(bs->file, - (acb->cluster_offset >> 9) + index_in_cluster, - &acb->hd_qiov, acb->cur_nr_sectors, - qcow2_aio_read_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto done; - } + remaining_sectors -= cur_nr_sectors; + sector_num += cur_nr_sectors; + bytes_done += cur_nr_sectors * 512; } + ret = 0; - return; -done: - acb->common.cb(acb->common.opaque, ret); - qemu_iovec_destroy(&acb->hd_qiov); - qemu_aio_release(acb); -} - -static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num, - QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, - void *opaque, int is_write) -{ - QCowAIOCB *acb; - - acb = qemu_aio_get(&qcow2_aio_pool, bs, cb, opaque); - if (!acb) - return NULL; - acb->hd_aiocb = NULL; - acb->sector_num = sector_num; - acb->qiov = qiov; - - qemu_iovec_init(&acb->hd_qiov, qiov->niov); - - acb->bytes_done = 0; - acb->remaining_sectors = nb_sectors; - acb->cur_nr_sectors = 0; - acb->cluster_offset = 0; - acb->l2meta.nb_clusters = 0; - QLIST_INIT(&acb->l2meta.dependent_requests); - return acb; -} - -static BlockDriverAIOCB *qcow2_aio_readv(BlockDriverState *bs, - int64_t sector_num, - QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, - void *opaque) -{ - QCowAIOCB *acb; +fail: + qemu_co_mutex_unlock(&s->lock); - acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); - if (!acb) - return NULL; + qemu_iovec_destroy(&hd_qiov); + qemu_vfree(cluster_data); - qcow2_aio_read_cb(acb, 0); - return &acb->common; + return ret; } -static void qcow2_aio_write_cb(void *opaque, int ret); - -static void run_dependent_requests(QCowL2Meta *m) +static void run_dependent_requests(BDRVQcowState *s, QCowL2Meta *m) { - QCowAIOCB *req; - QCowAIOCB *next; - /* Take the request off the list of running requests */ if (m->nb_clusters != 0) { QLIST_REMOVE(m, next_in_flight); } /* Restart all dependent requests */ - QLIST_FOREACH_SAFE(req, &m->dependent_requests, next_depend, next) { - qcow2_aio_write_cb(req, 0); + if (!qemu_co_queue_empty(&m->dependent_requests)) { + qemu_co_mutex_unlock(&s->lock); + while(qemu_co_queue_next(&m->dependent_requests)); + qemu_co_mutex_lock(&s->lock); } - - /* Empty the list for the next part of the request */ - QLIST_INIT(&m->dependent_requests); } -static void qcow2_aio_write_cb(void *opaque, int ret) +static int qcow2_co_writev(BlockDriverState *bs, + int64_t sector_num, + int remaining_sectors, + QEMUIOVector *qiov) { - QCowAIOCB *acb = opaque; - BlockDriverState *bs = acb->common.bs; BDRVQcowState *s = bs->opaque; int index_in_cluster; int n_end; + int ret; + int cur_nr_sectors; /* number of sectors in current iteration */ + uint64_t cluster_offset; + QEMUIOVector hd_qiov; + uint64_t bytes_done = 0; + uint8_t *cluster_data = NULL; + QCowL2Meta l2meta = { + .nb_clusters = 0, + }; - acb->hd_aiocb = NULL; + qemu_co_queue_init(&l2meta.dependent_requests); - if (ret >= 0) { - ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta); - } + qemu_iovec_init(&hd_qiov, qiov->niov); - run_dependent_requests(&acb->l2meta); + s->cluster_cache_offset = -1; /* disable compressed cache */ - if (ret < 0) - goto done; + qemu_co_mutex_lock(&s->lock); - acb->remaining_sectors -= acb->cur_nr_sectors; - acb->sector_num += acb->cur_nr_sectors; - acb->bytes_done += acb->cur_nr_sectors * 512; + while (remaining_sectors != 0) { - if (acb->remaining_sectors == 0) { - /* request completed */ - ret = 0; - goto done; - } + index_in_cluster = sector_num & (s->cluster_sectors - 1); + n_end = index_in_cluster + remaining_sectors; + if (s->crypt_method && + n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) { + n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; + } - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - n_end = index_in_cluster + acb->remaining_sectors; - if (s->crypt_method && - n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) - n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; + ret = qcow2_alloc_cluster_offset(bs, sector_num << 9, + index_in_cluster, n_end, &cur_nr_sectors, &l2meta); + if (ret < 0) { + goto fail; + } - ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9, - index_in_cluster, n_end, &acb->cur_nr_sectors, &acb->l2meta); - if (ret < 0) { - goto done; - } + cluster_offset = l2meta.cluster_offset; + assert((cluster_offset & 511) == 0); - acb->cluster_offset = acb->l2meta.cluster_offset; + qemu_iovec_reset(&hd_qiov); + qemu_iovec_copy(&hd_qiov, qiov, bytes_done, + cur_nr_sectors * 512); - /* Need to wait for another request? If so, we are done for now. */ - if (acb->l2meta.nb_clusters == 0 && acb->l2meta.depends_on != NULL) { - QLIST_INSERT_HEAD(&acb->l2meta.depends_on->dependent_requests, - acb, next_depend); - return; - } + if (s->crypt_method) { + if (!cluster_data) { + cluster_data = qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * + s->cluster_size); + } - assert((acb->cluster_offset & 511) == 0); + assert(hd_qiov.size <= + QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); + qemu_iovec_to_buffer(&hd_qiov, cluster_data); - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done, - acb->cur_nr_sectors * 512); + qcow2_encrypt_sectors(s, sector_num, cluster_data, + cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); - if (s->crypt_method) { - if (!acb->cluster_data) { - acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS * - s->cluster_size); + qemu_iovec_reset(&hd_qiov); + qemu_iovec_add(&hd_qiov, cluster_data, + cur_nr_sectors * 512); } - assert(acb->hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); - qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data); + BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_writev(bs->file, + (cluster_offset >> 9) + index_in_cluster, + cur_nr_sectors, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + goto fail; + } - qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data, - acb->cluster_data, acb->cur_nr_sectors, 1, &s->aes_encrypt_key); + ret = qcow2_alloc_cluster_link_l2(bs, &l2meta); + if (ret < 0) { + goto fail; + } - qemu_iovec_reset(&acb->hd_qiov); - qemu_iovec_add(&acb->hd_qiov, acb->cluster_data, - acb->cur_nr_sectors * 512); - } + run_dependent_requests(s, &l2meta); - BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - acb->hd_aiocb = bdrv_aio_writev(bs->file, - (acb->cluster_offset >> 9) + index_in_cluster, - &acb->hd_qiov, acb->cur_nr_sectors, - qcow2_aio_write_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto fail; + remaining_sectors -= cur_nr_sectors; + sector_num += cur_nr_sectors; + bytes_done += cur_nr_sectors * 512; } - - return; + ret = 0; fail: - if (acb->l2meta.nb_clusters != 0) { - QLIST_REMOVE(&acb->l2meta, next_in_flight); - } -done: - acb->common.cb(acb->common.opaque, ret); - qemu_iovec_destroy(&acb->hd_qiov); - qemu_aio_release(acb); -} - -static BlockDriverAIOCB *qcow2_aio_writev(BlockDriverState *bs, - int64_t sector_num, - QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, - void *opaque) -{ - BDRVQcowState *s = bs->opaque; - QCowAIOCB *acb; + run_dependent_requests(s, &l2meta); - s->cluster_cache_offset = -1; /* disable compressed cache */ + qemu_co_mutex_unlock(&s->lock); - acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); - if (!acb) - return NULL; + qemu_iovec_destroy(&hd_qiov); + qemu_vfree(cluster_data); - qcow2_aio_write_cb(acb, 0); - return &acb->common; + return ret; } static void qcow2_close(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; - qemu_free(s->l1_table); + g_free(s->l1_table); qcow2_cache_flush(bs, s->l2_table_cache); qcow2_cache_flush(bs, s->refcount_block_cache); @@ -746,11 +628,42 @@ static void qcow2_close(BlockDriverState *bs) qcow2_cache_destroy(bs, s->l2_table_cache); qcow2_cache_destroy(bs, s->refcount_block_cache); - qemu_free(s->cluster_cache); - qemu_free(s->cluster_data); + g_free(s->cluster_cache); + qemu_vfree(s->cluster_data); qcow2_refcount_close(bs); } +static void qcow2_invalidate_cache(BlockDriverState *bs) +{ + BDRVQcowState *s = bs->opaque; + int flags = s->flags; + AES_KEY aes_encrypt_key; + AES_KEY aes_decrypt_key; + uint32_t crypt_method = 0; + + /* + * Backing files are read-only which makes all of their metadata immutable, + * that means we don't have to worry about reopening them here. + */ + + if (s->crypt_method) { + crypt_method = s->crypt_method; + memcpy(&aes_encrypt_key, &s->aes_encrypt_key, sizeof(aes_encrypt_key)); + memcpy(&aes_decrypt_key, &s->aes_decrypt_key, sizeof(aes_decrypt_key)); + } + + qcow2_close(bs); + + memset(s, 0, sizeof(BDRVQcowState)); + qcow2_open(bs, flags); + + if (crypt_method) { + s->crypt_method = crypt_method; + memcpy(&s->aes_encrypt_key, &aes_encrypt_key, sizeof(aes_encrypt_key)); + memcpy(&s->aes_decrypt_key, &aes_decrypt_key, sizeof(aes_decrypt_key)); + } +} + /* * Updates the variable length parts of the qcow2 header, i.e. the backing file * name and all extensions. qcow2 was not designed to allow such changes, so if @@ -860,7 +773,7 @@ static int preallocate(BlockDriverState *bs) nb_sectors = bdrv_getlength(bs) >> 9; offset = 0; - QLIST_INIT(&meta.dependent_requests); + qemu_co_queue_init(&meta.dependent_requests); meta.cluster_offset = 0; while (nb_sectors) { @@ -878,7 +791,7 @@ static int preallocate(BlockDriverState *bs) /* There are no dependent requests, but we need to remove our request * from the list of in-flight requests */ - run_dependent_requests(&meta); + run_dependent_requests(bs->opaque, &meta); /* TODO Preallocate data if requested */ @@ -915,7 +828,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, (1 << cluster_bits) != cluster_size) { error_report( - "Cluster size must be a power of two between %d and %dk\n", + "Cluster size must be a power of two between %d and %dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10)); return -EINVAL; } @@ -970,9 +883,9 @@ static int qcow2_create2(const char *filename, int64_t total_size, } /* Write an empty refcount table */ - refcount_table = qemu_mallocz(cluster_size); + refcount_table = g_malloc0(cluster_size); ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size); - qemu_free(refcount_table); + g_free(refcount_table); if (ret < 0) { goto out; @@ -1036,7 +949,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options) const char *backing_fmt = NULL; uint64_t sectors = 0; int flags = 0; - size_t cluster_size = 65536; + size_t cluster_size = DEFAULT_CLUSTER_SIZE; int prealloc = 0; /* Read out options */ @@ -1097,11 +1010,17 @@ static int qcow2_make_empty(BlockDriverState *bs) return 0; } -static int qcow2_discard(BlockDriverState *bs, int64_t sector_num, - int nb_sectors) +static coroutine_fn int qcow2_co_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors) { - return qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS, + int ret; + BDRVQcowState *s = bs->opaque; + + qemu_co_mutex_lock(&s->lock); + ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; } static int qcow2_truncate(BlockDriverState *bs, int64_t offset) @@ -1164,7 +1083,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num, if (nb_sectors != s->cluster_sectors) return -EINVAL; - out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128); + out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128); /* best compression, small window, no zlib header */ memset(&strm, 0, sizeof(strm)); @@ -1172,8 +1091,8 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num, Z_DEFLATED, -12, 9, Z_DEFAULT_STRATEGY); if (ret != 0) { - qemu_free(out_buf); - return -1; + ret = -EINVAL; + goto fail; } strm.avail_in = s->cluster_size; @@ -1183,9 +1102,9 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num, ret = deflate(&strm, Z_FINISH); if (ret != Z_STREAM_END && ret != Z_OK) { - qemu_free(out_buf); deflateEnd(&strm); - return -1; + ret = -EINVAL; + goto fail; } out_len = strm.next_out - out_buf; @@ -1193,60 +1112,56 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num, if (ret != Z_STREAM_END || out_len >= s->cluster_size) { /* could not compress: write normal cluster */ - bdrv_write(bs, sector_num, buf, s->cluster_sectors); + ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors); + if (ret < 0) { + goto fail; + } } else { cluster_offset = qcow2_alloc_compressed_cluster_offset(bs, sector_num << 9, out_len); - if (!cluster_offset) - return -1; + if (!cluster_offset) { + ret = -EIO; + goto fail; + } cluster_offset &= s->cluster_offset_mask; BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED); - if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) { - qemu_free(out_buf); - return -1; + ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len); + if (ret < 0) { + goto fail; } } - qemu_free(out_buf); - return 0; + ret = 0; +fail: + g_free(out_buf); + return ret; } -static int qcow2_flush(BlockDriverState *bs) +static int qcow2_co_flush_to_os(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; int ret; + qemu_co_mutex_lock(&s->lock); ret = qcow2_cache_flush(bs, s->l2_table_cache); if (ret < 0) { + qemu_co_mutex_unlock(&s->lock); return ret; } ret = qcow2_cache_flush(bs, s->refcount_block_cache); if (ret < 0) { + qemu_co_mutex_unlock(&s->lock); return ret; } + qemu_co_mutex_unlock(&s->lock); - return bdrv_flush(bs->file); + return 0; } -static BlockDriverAIOCB *qcow2_aio_flush(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, - void *opaque) +static int qcow2_co_flush_to_disk(BlockDriverState *bs) { - BDRVQcowState *s = bs->opaque; - int ret; - - ret = qcow2_cache_flush(bs, s->l2_table_cache); - if (ret < 0) { - return NULL; - } - - ret = qcow2_cache_flush(bs, s->refcount_block_cache); - if (ret < 0) { - return NULL; - } - - return bdrv_aio_flush(bs->file, cb, opaque); + return bdrv_co_flush(bs->file); } static int64_t qcow2_vm_state_offset(BDRVQcowState *s) @@ -1343,7 +1258,8 @@ static QEMUOptionParameter qcow2_create_options[] = { { .name = BLOCK_OPT_CLUSTER_SIZE, .type = OPT_SIZE, - .help = "qcow2 cluster size" + .help = "qcow2 cluster size", + .value = { .n = DEFAULT_CLUSTER_SIZE }, }, { .name = BLOCK_OPT_PREALLOC, @@ -1360,16 +1276,16 @@ static BlockDriver bdrv_qcow2 = { .bdrv_open = qcow2_open, .bdrv_close = qcow2_close, .bdrv_create = qcow2_create, - .bdrv_flush = qcow2_flush, .bdrv_is_allocated = qcow2_is_allocated, .bdrv_set_key = qcow2_set_key, .bdrv_make_empty = qcow2_make_empty, - .bdrv_aio_readv = qcow2_aio_readv, - .bdrv_aio_writev = qcow2_aio_writev, - .bdrv_aio_flush = qcow2_aio_flush, + .bdrv_co_readv = qcow2_co_readv, + .bdrv_co_writev = qcow2_co_writev, + .bdrv_co_flush_to_os = qcow2_co_flush_to_os, + .bdrv_co_flush_to_disk = qcow2_co_flush_to_disk, - .bdrv_discard = qcow2_discard, + .bdrv_co_discard = qcow2_co_discard, .bdrv_truncate = qcow2_truncate, .bdrv_write_compressed = qcow2_write_compressed, @@ -1385,6 +1301,8 @@ static BlockDriver bdrv_qcow2 = { .bdrv_change_backing_file = qcow2_change_backing_file, + .bdrv_invalidate_cache = qcow2_invalidate_cache, + .create_options = qcow2_create_options, .bdrv_check = qcow2_check, }; diff --git a/block/qcow2.h b/block/qcow2.h index a019831..4e44eea 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -26,6 +26,7 @@ #define BLOCK_QCOW2_H #include "aes.h" +#include "qemu-coroutine.h" //#define DEBUG_ALLOC //#define DEBUG_ALLOC2 @@ -54,6 +55,8 @@ /* Must be at least 4 to cover all cases of refcount table growth */ #define REFCOUNT_CACHE_SIZE 4 +#define DEFAULT_CLUSTER_SIZE 65536 + typedef struct QCowHeader { uint32_t magic; uint32_t version; @@ -112,6 +115,8 @@ typedef struct BDRVQcowState { int64_t free_cluster_index; int64_t free_byte_offset; + CoMutex lock; + uint32_t crypt_method; /* current crypt method, 0 if no key yet */ uint32_t crypt_method_header; AES_KEY aes_encrypt_key; @@ -120,6 +125,8 @@ typedef struct BDRVQcowState { int snapshots_size; int nb_snapshots; QCowSnapshot *snapshots; + + int flags; } BDRVQcowState; /* XXX: use std qcow open function ? */ @@ -143,8 +150,7 @@ typedef struct QCowL2Meta int n_start; int nb_available; int nb_clusters; - struct QCowL2Meta *depends_on; - QLIST_HEAD(QCowAioDependencies, QCowAIOCB) dependent_requests; + CoQueue dependent_requests; QLIST_ENTRY(QCowL2Meta) next_in_flight; } QCowL2Meta; @@ -184,8 +190,6 @@ void qcow2_free_clusters(BlockDriverState *bs, void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t cluster_offset, int nb_clusters); -void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset, - int64_t size); int qcow2_update_snapshot_refcount(BlockDriverState *bs, int64_t l1_table_offset, int l1_size, int addend); @@ -226,6 +230,8 @@ int qcow2_read_snapshots(BlockDriverState *bs); Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables, bool writethrough); int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c); +bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c, + bool enable); void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table); int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c); diff --git a/block/qed-check.c b/block/qed-check.c index 474c847..e4a49ce 100644 --- a/block/qed-check.c +++ b/block/qed-check.c @@ -72,7 +72,8 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table) for (i = 0; i < s->table_nelems; i++) { uint64_t offset = table->offsets[i]; - if (!offset) { + if (qed_offset_is_unalloc_cluster(offset) || + qed_offset_is_zero_cluster(offset)) { continue; } @@ -111,7 +112,7 @@ static int qed_check_l1_table(QEDCheck *check, QEDTable *table) unsigned int num_invalid_l2; uint64_t offset = table->offsets[i]; - if (!offset) { + if (qed_offset_is_unalloc_cluster(offset)) { continue; } @@ -196,7 +197,7 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix) }; int ret; - check.used_clusters = qemu_mallocz(((check.nclusters + 31) / 32) * + check.used_clusters = g_malloc0(((check.nclusters + 31) / 32) * sizeof(check.used_clusters[0])); ret = qed_check_l1_table(&check, s->l1_table); @@ -205,6 +206,6 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix) qed_check_for_leaks(&check); } - qemu_free(check.used_clusters); + g_free(check.used_clusters); return ret; } diff --git a/block/qed-cluster.c b/block/qed-cluster.c index 0ec864b..f64b2af 100644 --- a/block/qed-cluster.c +++ b/block/qed-cluster.c @@ -23,7 +23,8 @@ * @n: Maximum number of clusters * @offset: Set to first cluster offset * - * This function scans tables for contiguous allocated or free clusters. + * This function scans tables for contiguous clusters. A contiguous run of + * clusters may be allocated, unallocated, or zero. */ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s, QEDTable *table, @@ -38,9 +39,14 @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s, *offset = last; for (i = index + 1; i < end; i++) { - if (last == 0) { - /* Counting free clusters */ - if (table->offsets[i] != 0) { + if (qed_offset_is_unalloc_cluster(last)) { + /* Counting unallocated clusters */ + if (!qed_offset_is_unalloc_cluster(table->offsets[i])) { + break; + } + } else if (qed_offset_is_zero_cluster(last)) { + /* Counting zero clusters */ + if (!qed_offset_is_zero_cluster(table->offsets[i])) { break; } } else { @@ -87,17 +93,22 @@ static void qed_find_cluster_cb(void *opaque, int ret) n = qed_count_contiguous_clusters(s, request->l2_table->table, index, n, &offset); - ret = offset ? QED_CLUSTER_FOUND : QED_CLUSTER_L2; - len = MIN(find_cluster_cb->len, n * s->header.cluster_size - - qed_offset_into_cluster(s, find_cluster_cb->pos)); - - if (offset && !qed_check_cluster_offset(s, offset)) { + if (qed_offset_is_unalloc_cluster(offset)) { + ret = QED_CLUSTER_L2; + } else if (qed_offset_is_zero_cluster(offset)) { + ret = QED_CLUSTER_ZERO; + } else if (qed_check_cluster_offset(s, offset)) { + ret = QED_CLUSTER_FOUND; + } else { ret = -EINVAL; } + len = MIN(find_cluster_cb->len, n * s->header.cluster_size - + qed_offset_into_cluster(s, find_cluster_cb->pos)); + out: find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len); - qemu_free(find_cluster_cb); + g_free(find_cluster_cb); } /** @@ -132,7 +143,7 @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos); l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)]; - if (!l2_offset) { + if (qed_offset_is_unalloc_cluster(l2_offset)) { cb(opaque, QED_CLUSTER_L1, 0, len); return; } @@ -141,7 +152,7 @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos, return; } - find_cluster_cb = qemu_malloc(sizeof(*find_cluster_cb)); + find_cluster_cb = g_malloc(sizeof(*find_cluster_cb)); find_cluster_cb->s = s; find_cluster_cb->pos = pos; find_cluster_cb->len = len; diff --git a/block/qed-gencb.c b/block/qed-gencb.c index 1513dc6..7d7ac1f 100644 --- a/block/qed-gencb.c +++ b/block/qed-gencb.c @@ -15,7 +15,7 @@ void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque) { - GenericCB *gencb = qemu_malloc(len); + GenericCB *gencb = g_malloc(len); gencb->cb = cb; gencb->opaque = opaque; return gencb; @@ -27,6 +27,6 @@ void gencb_complete(void *opaque, int ret) BlockDriverCompletionFunc *cb = gencb->cb; void *user_opaque = gencb->opaque; - qemu_free(gencb); + g_free(gencb); cb(user_opaque, ret); } diff --git a/block/qed-l2-cache.c b/block/qed-l2-cache.c index 57518a4..02b81a2 100644 --- a/block/qed-l2-cache.c +++ b/block/qed-l2-cache.c @@ -74,7 +74,7 @@ void qed_free_l2_cache(L2TableCache *l2_cache) QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next_entry) { qemu_vfree(entry->table); - qemu_free(entry); + g_free(entry); } } @@ -89,7 +89,7 @@ CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache) { CachedL2Table *entry; - entry = qemu_mallocz(sizeof(*entry)); + entry = g_malloc0(sizeof(*entry)); entry->ref++; trace_qed_alloc_l2_cache_entry(l2_cache, entry); @@ -111,7 +111,7 @@ void qed_unref_l2_cache_entry(CachedL2Table *entry) trace_qed_unref_l2_cache_entry(entry, entry->ref); if (entry->ref == 0) { qemu_vfree(entry->table); - qemu_free(entry); + g_free(entry); } } diff --git a/block/qed-table.c b/block/qed-table.c index d38c673..f31f9ff 100644 --- a/block/qed-table.c +++ b/block/qed-table.c @@ -179,16 +179,12 @@ int qed_read_l1_table_sync(BDRVQEDState *s) { int ret = -EINPROGRESS; - async_context_push(); - qed_read_table(s, s->header.l1_table_offset, s->l1_table, qed_sync_cb, &ret); while (ret == -EINPROGRESS) { qemu_aio_wait(); } - async_context_pop(); - return ret; } @@ -205,15 +201,11 @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, { int ret = -EINPROGRESS; - async_context_push(); - qed_write_l1_table(s, index, n, qed_sync_cb, &ret); while (ret == -EINPROGRESS) { qemu_aio_wait(); } - async_context_pop(); - return ret; } @@ -230,21 +222,21 @@ static void qed_read_l2_table_cb(void *opaque, int ret) QEDRequest *request = read_l2_table_cb->request; BDRVQEDState *s = read_l2_table_cb->s; CachedL2Table *l2_table = request->l2_table; + uint64_t l2_offset = read_l2_table_cb->l2_offset; if (ret) { /* can't trust loaded L2 table anymore */ qed_unref_l2_cache_entry(l2_table); request->l2_table = NULL; } else { - l2_table->offset = read_l2_table_cb->l2_offset; + l2_table->offset = l2_offset; qed_commit_l2_cache_entry(&s->l2_cache, l2_table); /* This is guaranteed to succeed because we just committed the entry * to the cache. */ - request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, - l2_table->offset); + request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset); assert(request->l2_table != NULL); } @@ -282,14 +274,11 @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset { int ret = -EINPROGRESS; - async_context_push(); - qed_read_l2_table(s, request, offset, qed_sync_cb, &ret); while (ret == -EINPROGRESS) { qemu_aio_wait(); } - async_context_pop(); return ret; } @@ -307,13 +296,10 @@ int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, { int ret = -EINPROGRESS; - async_context_push(); - qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret); while (ret == -EINPROGRESS) { qemu_aio_wait(); } - async_context_pop(); return ret; } diff --git a/block/qed.c b/block/qed.c index 75ae244..7e22e77 100644 --- a/block/qed.c +++ b/block/qed.c @@ -12,9 +12,11 @@ * */ +#include "qemu-timer.h" #include "trace.h" #include "qed.h" #include "qerror.h" +#include "migration.h" static void qed_aio_cancel(BlockDriverAIOCB *blockacb) { @@ -291,6 +293,88 @@ static CachedL2Table *qed_new_l2_table(BDRVQEDState *s) static void qed_aio_next_io(void *opaque, int ret); +static void qed_plug_allocating_write_reqs(BDRVQEDState *s) +{ + assert(!s->allocating_write_reqs_plugged); + + s->allocating_write_reqs_plugged = true; +} + +static void qed_unplug_allocating_write_reqs(BDRVQEDState *s) +{ + QEDAIOCB *acb; + + assert(s->allocating_write_reqs_plugged); + + s->allocating_write_reqs_plugged = false; + + acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs); + if (acb) { + qed_aio_next_io(acb, 0); + } +} + +static void qed_finish_clear_need_check(void *opaque, int ret) +{ + /* Do nothing */ +} + +static void qed_flush_after_clear_need_check(void *opaque, int ret) +{ + BDRVQEDState *s = opaque; + + bdrv_aio_flush(s->bs, qed_finish_clear_need_check, s); + + /* No need to wait until flush completes */ + qed_unplug_allocating_write_reqs(s); +} + +static void qed_clear_need_check(void *opaque, int ret) +{ + BDRVQEDState *s = opaque; + + if (ret) { + qed_unplug_allocating_write_reqs(s); + return; + } + + s->header.features &= ~QED_F_NEED_CHECK; + qed_write_header(s, qed_flush_after_clear_need_check, s); +} + +static void qed_need_check_timer_cb(void *opaque) +{ + BDRVQEDState *s = opaque; + + /* The timer should only fire when allocating writes have drained */ + assert(!QSIMPLEQ_FIRST(&s->allocating_write_reqs)); + + trace_qed_need_check_timer_cb(s); + + qed_plug_allocating_write_reqs(s); + + /* Ensure writes are on disk before clearing flag */ + bdrv_aio_flush(s->bs, qed_clear_need_check, s); +} + +static void qed_start_need_check_timer(BDRVQEDState *s) +{ + trace_qed_start_need_check_timer(s); + + /* Use vm_clock so we don't alter the image file while suspended for + * migration. + */ + qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) + + get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT); +} + +/* It's okay to call this multiple times or when no timer is started */ +static void qed_cancel_need_check_timer(BDRVQEDState *s) +{ + trace_qed_cancel_need_check_timer(s); + qemu_del_timer(s->need_check_timer); +} + static int bdrv_qed_open(BlockDriverState *bs, int flags) { BDRVQEDState *s = bs->opaque; @@ -305,7 +389,6 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags) if (ret < 0) { return ret; } - ret = 0; /* ret should always be 0 or -errno */ qed_header_le_to_cpu(&le_header, &s->header); if (s->header.magic != QED_MAGIC) { @@ -406,7 +489,10 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags) BdrvCheckResult result = {0}; ret = qed_check(s, &result, true); - if (!ret && !result.corruptions && !result.check_errors) { + if (ret) { + goto out; + } + if (!result.corruptions && !result.check_errors) { /* Ensure fixes reach storage before clearing check bit */ bdrv_flush(s->bs); @@ -416,6 +502,15 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags) } } + s->need_check_timer = qemu_new_timer_ns(vm_clock, + qed_need_check_timer_cb, s); + + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "qed", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + + out: if (ret) { qed_free_l2_cache(&s->l2_cache); @@ -428,6 +523,12 @@ static void bdrv_qed_close(BlockDriverState *bs) { BDRVQEDState *s = bs->opaque; + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); + + qed_cancel_need_check_timer(s); + qemu_free_timer(s->need_check_timer); + /* Ensure writes reach stable storage */ bdrv_flush(bs->file); @@ -441,11 +542,6 @@ static void bdrv_qed_close(BlockDriverState *bs) qemu_vfree(s->l1_table); } -static int bdrv_qed_flush(BlockDriverState *bs) -{ - return bdrv_flush(bs->file); -} - static int qed_create(const char *filename, uint32_t cluster_size, uint64_t image_size, uint32_t table_size, const char *backing_file, const char *backing_fmt) @@ -503,7 +599,7 @@ static int qed_create(const char *filename, uint32_t cluster_size, goto out; } - l1_table = qemu_mallocz(l1_size); + l1_table = g_malloc0(l1_size); ret = bdrv_pwrite(bs, header.l1_table_offset, l1_table, l1_size); if (ret < 0) { goto out; @@ -511,7 +607,7 @@ static int qed_create(const char *filename, uint32_t cluster_size, ret = 0; /* success */ out: - qemu_free(l1_table); + g_free(l1_table); bdrv_delete(bs); return ret; } @@ -573,7 +669,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l { QEDIsAllocatedCB *cb = opaque; *cb->pnum = len / BDRV_SECTOR_SIZE; - cb->is_allocated = ret == QED_CLUSTER_FOUND; + cb->is_allocated = (ret == QED_CLUSTER_FOUND || ret == QED_CLUSTER_ZERO); } static int bdrv_qed_is_allocated(BlockDriverState *bs, int64_t sector_num, @@ -588,16 +684,12 @@ static int bdrv_qed_is_allocated(BlockDriverState *bs, int64_t sector_num, }; QEDRequest request = { .l2_table = NULL }; - async_context_push(); - qed_find_cluster(s, &request, pos, len, qed_is_allocated_cb, &cb); while (cb.is_allocated == -1) { qemu_aio_wait(); } - async_context_pop(); - qed_unref_l2_cache_entry(request.l2_table); return cb.is_allocated; @@ -745,7 +837,10 @@ static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, * @table: L2 table * @index: First cluster index * @n: Number of contiguous clusters - * @cluster: First cluster byte offset in image file + * @cluster: First cluster offset + * + * The cluster offset may be an allocated byte offset in the image file, the + * zero cluster marker, or the unallocated cluster marker. */ static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index, unsigned int n, uint64_t cluster) @@ -753,7 +848,10 @@ static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index, int i; for (i = index; i < index + n; i++) { table->offsets[i] = cluster; - cluster += s->header.cluster_size; + if (!qed_offset_is_unalloc_cluster(cluster) && + !qed_offset_is_zero_cluster(cluster)) { + cluster += s->header.cluster_size; + } } } @@ -803,6 +901,8 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret) acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs); if (acb) { qed_aio_next_io(acb, 0); + } else if (s->header.features & QED_F_NEED_CHECK) { + qed_start_need_check_timer(s); } } } @@ -815,14 +915,14 @@ static void qed_commit_l2_update(void *opaque, int ret) QEDAIOCB *acb = opaque; BDRVQEDState *s = acb_to_s(acb); CachedL2Table *l2_table = acb->request.l2_table; + uint64_t l2_offset = l2_table->offset; qed_commit_l2_cache_entry(&s->l2_cache, l2_table); /* This is guaranteed to succeed because we just committed the entry to the * cache. */ - acb->request.l2_table = qed_find_l2_cache_entry(&s->l2_cache, - l2_table->offset); + acb->request.l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset); assert(acb->request.l2_table != NULL); qed_aio_next_io(opaque, ret); @@ -1008,11 +1108,17 @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len) { BDRVQEDState *s = acb_to_s(acb); + /* Cancel timer when the first allocating request comes in */ + if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) { + qed_cancel_need_check_timer(s); + } + /* Freeze this request if another allocating write is in progress */ if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) { QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next); } - if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) { + if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) || + s->allocating_write_reqs_plugged) { return; /* wait for existing request to finish */ } @@ -1075,6 +1181,7 @@ static void qed_aio_write_data(void *opaque, int ret, case QED_CLUSTER_L2: case QED_CLUSTER_L1: + case QED_CLUSTER_ZERO: qed_aio_write_alloc(acb, len); break; @@ -1114,8 +1221,12 @@ static void qed_aio_read_data(void *opaque, int ret, qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len); - /* Handle backing file and unallocated sparse hole reads */ - if (ret != QED_CLUSTER_FOUND) { + /* Handle zero cluster and backing file reads */ + if (ret == QED_CLUSTER_ZERO) { + qemu_iovec_memset(&acb->cur_qiov, 0, acb->cur_qiov.size); + qed_aio_next_io(acb, 0); + return; + } else if (ret != QED_CLUSTER_FOUND) { qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov, qed_aio_next_io, acb); return; @@ -1222,7 +1333,27 @@ static BlockDriverAIOCB *bdrv_qed_aio_flush(BlockDriverState *bs, static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset) { - return -ENOTSUP; + BDRVQEDState *s = bs->opaque; + uint64_t old_image_size; + int ret; + + if (!qed_is_image_size_valid(offset, s->header.cluster_size, + s->header.table_size)) { + return -EINVAL; + } + + /* Shrinking is currently not supported */ + if ((uint64_t)offset < s->header.image_size) { + return -ENOTSUP; + } + + old_image_size = s->header.image_size; + s->header.image_size = offset; + ret = qed_write_header_sync(s); + if (ret < 0) { + s->header.image_size = old_image_size; + } + return ret; } static int64_t bdrv_qed_getlength(BlockDriverState *bs) @@ -1292,18 +1423,20 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs, } /* Prepare new header */ - buffer = qemu_malloc(buffer_len); + buffer = g_malloc(buffer_len); qed_header_cpu_to_le(&new_header, &le_header); memcpy(buffer, &le_header, sizeof(le_header)); buffer_len = sizeof(le_header); - memcpy(buffer + buffer_len, backing_file, backing_file_len); - buffer_len += backing_file_len; + if (backing_file) { + memcpy(buffer + buffer_len, backing_file, backing_file_len); + buffer_len += backing_file_len; + } /* Write new header */ ret = bdrv_pwrite_sync(bs->file, 0, buffer, buffer_len); - qemu_free(buffer); + g_free(buffer); if (ret == 0) { memcpy(&s->header, &new_header, sizeof(new_header)); } @@ -1333,7 +1466,8 @@ static QEMUOptionParameter qed_create_options[] = { }, { .name = BLOCK_OPT_CLUSTER_SIZE, .type = OPT_SIZE, - .help = "Cluster size (in bytes)" + .help = "Cluster size (in bytes)", + .value = { .n = QED_DEFAULT_CLUSTER_SIZE }, }, { .name = BLOCK_OPT_TABLE_SIZE, .type = OPT_SIZE, @@ -1351,7 +1485,6 @@ static BlockDriver bdrv_qed = { .bdrv_open = bdrv_qed_open, .bdrv_close = bdrv_qed_close, .bdrv_create = bdrv_qed_create, - .bdrv_flush = bdrv_qed_flush, .bdrv_is_allocated = bdrv_qed_is_allocated, .bdrv_make_empty = bdrv_qed_make_empty, .bdrv_aio_readv = bdrv_qed_aio_readv, diff --git a/block/qed.h b/block/qed.h index 9f72ad5..62cbd3b 100644 --- a/block/qed.h +++ b/block/qed.h @@ -78,6 +78,9 @@ enum { QED_MIN_TABLE_SIZE = 1, /* in clusters */ QED_MAX_TABLE_SIZE = 16, QED_DEFAULT_TABLE_SIZE = 4, + + /* Delay to flush and clean image after last allocating write completes */ + QED_NEED_CHECK_TIMEOUT = 5, /* in seconds */ }; typedef struct { @@ -157,10 +160,17 @@ typedef struct { /* Allocating write request queue */ QSIMPLEQ_HEAD(, QEDAIOCB) allocating_write_reqs; + bool allocating_write_reqs_plugged; + + /* Periodic flush and clear need check flag */ + QEMUTimer *need_check_timer; + + Error *migration_blocker; } BDRVQEDState; enum { QED_CLUSTER_FOUND, /* cluster found */ + QED_CLUSTER_ZERO, /* zero cluster found */ QED_CLUSTER_L2, /* cluster missing in L2 */ QED_CLUSTER_L1, /* cluster missing in L1 */ }; @@ -298,4 +308,29 @@ static inline bool qed_check_table_offset(BDRVQEDState *s, uint64_t offset) qed_check_cluster_offset(s, end_offset); } +static inline bool qed_offset_is_cluster_aligned(BDRVQEDState *s, + uint64_t offset) +{ + if (qed_offset_into_cluster(s, offset)) { + return false; + } + return true; +} + +static inline bool qed_offset_is_unalloc_cluster(uint64_t offset) +{ + if (offset == 0) { + return true; + } + return false; +} + +static inline bool qed_offset_is_zero_cluster(uint64_t offset) +{ + if (offset == 1) { + return true; + } + return false; +} + #endif /* BLOCK_QED_H */ diff --git a/block/raw-posix.c b/block/raw-posix.c index 6b72470..a3de373 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -43,17 +43,17 @@ #ifdef __sun__ #define _POSIX_PTHREAD_SEMANTICS 1 -#include #include #endif #ifdef __linux__ +#include +#include #include #include #include #include #endif #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) -#include #include #include #endif @@ -64,6 +64,13 @@ #include #endif +#ifdef __NetBSD__ +#include +#include +#include +#include +#endif + #ifdef __DragonFly__ #include #include @@ -136,12 +143,55 @@ static int64_t raw_getlength(BlockDriverState *bs); static int cdrom_reopen(BlockDriverState *bs); #endif +#if defined(__NetBSD__) +static int raw_normalize_devicepath(const char **filename) +{ + static char namebuf[PATH_MAX]; + const char *dp, *fname; + struct stat sb; + + fname = *filename; + dp = strrchr(fname, '/'); + if (lstat(fname, &sb) < 0) { + fprintf(stderr, "%s: stat failed: %s\n", + fname, strerror(errno)); + return -errno; + } + + if (!S_ISBLK(sb.st_mode)) { + return 0; + } + + if (dp == NULL) { + snprintf(namebuf, PATH_MAX, "r%s", fname); + } else { + snprintf(namebuf, PATH_MAX, "%.*s/r%s", + (int)(dp - fname), fname, dp + 1); + } + fprintf(stderr, "%s is a block device", fname); + *filename = namebuf; + fprintf(stderr, ", using %s\n", *filename); + + return 0; +} +#else +static int raw_normalize_devicepath(const char **filename) +{ + return 0; +} +#endif + static int raw_open_common(BlockDriverState *bs, const char *filename, int bdrv_flags, int open_flags) { BDRVRawState *s = bs->opaque; int fd, ret; + ret = raw_normalize_devicepath(&filename); + if (ret != 0) { + return ret; + } + s->open_flags = open_flags | O_BINARY; s->open_flags &= ~O_ACCMODE; if (bdrv_flags & BDRV_O_RDWR) { @@ -154,7 +204,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, * and O_DIRECT for no caching. */ if ((bdrv_flags & BDRV_O_NOCACHE)) s->open_flags |= O_DIRECT; - else if (!(bdrv_flags & BDRV_O_CACHE_WB)) + if (!(bdrv_flags & BDRV_O_CACHE_WB)) s->open_flags |= O_DSYNC; s->fd = -1; @@ -180,13 +230,19 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, } } + /* We're falling back to POSIX AIO in some cases so init always */ + if (paio_init() < 0) { + goto out_free_buf; + } + #ifdef CONFIG_LINUX_AIO + /* + * Currently Linux do AIO only for files opened with O_DIRECT + * specified so check NOCACHE flag too + */ if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) == (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) { - /* We're falling back to POSIX AIO in some cases */ - paio_init(); - s->aio_ctx = laio_init(); if (!s->aio_ctx) { goto out_free_buf; @@ -195,9 +251,6 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, } else #endif { - if (paio_init() < 0) { - goto out_free_buf; - } #ifdef CONFIG_LINUX_AIO s->use_aio = 0; #endif @@ -244,273 +297,6 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) */ /* - * offset and count are in bytes, but must be multiples of 512 for files - * opened with O_DIRECT. buf must be aligned to 512 bytes then. - * - * This function may be called without alignment if the caller ensures - * that O_DIRECT is not in effect. - */ -static int raw_pread_aligned(BlockDriverState *bs, int64_t offset, - uint8_t *buf, int count) -{ - BDRVRawState *s = bs->opaque; - int ret; - - ret = fd_open(bs); - if (ret < 0) - return ret; - - ret = pread(s->fd, buf, count, offset); - if (ret == count) - return ret; - - /* Allow reads beyond the end (needed for pwrite) */ - if ((ret == 0) && bs->growable) { - int64_t size = raw_getlength(bs); - if (offset >= size) { - memset(buf, 0, count); - return count; - } - } - - DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 - "] read failed %d : %d = %s\n", - s->fd, bs->filename, offset, buf, count, - bs->total_sectors, ret, errno, strerror(errno)); - - /* Try harder for CDrom. */ - if (s->type != FTYPE_FILE) { - ret = pread(s->fd, buf, count, offset); - if (ret == count) - return ret; - ret = pread(s->fd, buf, count, offset); - if (ret == count) - return ret; - - DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 - "] retry read failed %d : %d = %s\n", - s->fd, bs->filename, offset, buf, count, - bs->total_sectors, ret, errno, strerror(errno)); - } - - return (ret < 0) ? -errno : ret; -} - -/* - * offset and count are in bytes, but must be multiples of the sector size - * for files opened with O_DIRECT. buf must be aligned to sector size bytes - * then. - * - * This function may be called without alignment if the caller ensures - * that O_DIRECT is not in effect. - */ -static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset, - const uint8_t *buf, int count) -{ - BDRVRawState *s = bs->opaque; - int ret; - - ret = fd_open(bs); - if (ret < 0) - return -errno; - - ret = pwrite(s->fd, buf, count, offset); - if (ret == count) - return ret; - - DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 - "] write failed %d : %d = %s\n", - s->fd, bs->filename, offset, buf, count, - bs->total_sectors, ret, errno, strerror(errno)); - - return (ret < 0) ? -errno : ret; -} - - -/* - * offset and count are in bytes and possibly not aligned. For files opened - * with O_DIRECT, necessary alignments are ensured before calling - * raw_pread_aligned to do the actual read. - */ -static int raw_pread(BlockDriverState *bs, int64_t offset, - uint8_t *buf, int count) -{ - BDRVRawState *s = bs->opaque; - unsigned sector_mask = bs->buffer_alignment - 1; - int size, ret, shift, sum; - - sum = 0; - - if (s->aligned_buf != NULL) { - - if (offset & sector_mask) { - /* align offset on a sector size bytes boundary */ - - shift = offset & sector_mask; - size = (shift + count + sector_mask) & ~sector_mask; - if (size > s->aligned_buf_size) - size = s->aligned_buf_size; - ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size); - if (ret < 0) - return ret; - - size = bs->buffer_alignment - shift; - if (size > count) - size = count; - memcpy(buf, s->aligned_buf + shift, size); - - buf += size; - offset += size; - count -= size; - sum += size; - - if (count == 0) - return sum; - } - if (count & sector_mask || (uintptr_t) buf & sector_mask) { - - /* read on aligned buffer */ - - while (count) { - - size = (count + sector_mask) & ~sector_mask; - if (size > s->aligned_buf_size) - size = s->aligned_buf_size; - - ret = raw_pread_aligned(bs, offset, s->aligned_buf, size); - if (ret < 0) { - return ret; - } else if (ret == 0) { - fprintf(stderr, "raw_pread: read beyond end of file\n"); - abort(); - } - - size = ret; - if (size > count) - size = count; - - memcpy(buf, s->aligned_buf, size); - - buf += size; - offset += size; - count -= size; - sum += size; - } - - return sum; - } - } - - return raw_pread_aligned(bs, offset, buf, count) + sum; -} - -static int raw_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) -{ - int ret; - - ret = raw_pread(bs, sector_num * BDRV_SECTOR_SIZE, buf, - nb_sectors * BDRV_SECTOR_SIZE); - if (ret == (nb_sectors * BDRV_SECTOR_SIZE)) - ret = 0; - return ret; -} - -/* - * offset and count are in bytes and possibly not aligned. For files opened - * with O_DIRECT, necessary alignments are ensured before calling - * raw_pwrite_aligned to do the actual write. - */ -static int raw_pwrite(BlockDriverState *bs, int64_t offset, - const uint8_t *buf, int count) -{ - BDRVRawState *s = bs->opaque; - unsigned sector_mask = bs->buffer_alignment - 1; - int size, ret, shift, sum; - - sum = 0; - - if (s->aligned_buf != NULL) { - - if (offset & sector_mask) { - /* align offset on a sector size bytes boundary */ - shift = offset & sector_mask; - ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, - bs->buffer_alignment); - if (ret < 0) - return ret; - - size = bs->buffer_alignment - shift; - if (size > count) - size = count; - memcpy(s->aligned_buf + shift, buf, size); - - ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, - bs->buffer_alignment); - if (ret < 0) - return ret; - - buf += size; - offset += size; - count -= size; - sum += size; - - if (count == 0) - return sum; - } - if (count & sector_mask || (uintptr_t) buf & sector_mask) { - - while ((size = (count & ~sector_mask)) != 0) { - - if (size > s->aligned_buf_size) - size = s->aligned_buf_size; - - memcpy(s->aligned_buf, buf, size); - - ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size); - if (ret < 0) - return ret; - - buf += ret; - offset += ret; - count -= ret; - sum += ret; - } - /* here, count < sector_size because (count & ~sector_mask) == 0 */ - if (count) { - ret = raw_pread_aligned(bs, offset, s->aligned_buf, - bs->buffer_alignment); - if (ret < 0) - return ret; - memcpy(s->aligned_buf, buf, count); - - ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, - bs->buffer_alignment); - if (ret < 0) - return ret; - if (count < ret) - ret = count; - - sum += ret; - } - return sum; - } - } - return raw_pwrite_aligned(bs, offset, buf, count) + sum; -} - -static int raw_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) -{ - int ret; - ret = raw_pwrite(bs, sector_num * BDRV_SECTOR_SIZE, buf, - nb_sectors * BDRV_SECTOR_SIZE); - if (ret == (nb_sectors * BDRV_SECTOR_SIZE)) - ret = 0; - return ret; -} - -/* * Check if all memory in this vector is sector aligned. */ static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) @@ -537,7 +323,7 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs, /* * If O_DIRECT is used the buffer needs to be aligned on a sector - * boundary. Check if this is the case or telll the low-level + * boundary. Check if this is the case or tell the low-level * driver that it needs to copy the buffer. */ if (s->aligned_buf) { @@ -596,10 +382,24 @@ static void raw_close(BlockDriverState *bs) static int raw_truncate(BlockDriverState *bs, int64_t offset) { BDRVRawState *s = bs->opaque; - if (s->type != FTYPE_FILE) - return -ENOTSUP; - if (ftruncate(s->fd, offset) < 0) + struct stat st; + + if (fstat(s->fd, &st)) { return -errno; + } + + if (S_ISREG(st.st_mode)) { + if (ftruncate(s->fd, offset) < 0) { + return -errno; + } + } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { + if (offset > raw_getlength(bs)) { + return -EINVAL; + } + } else { + return -ENOTSUP; + } + return 0; } @@ -622,6 +422,31 @@ static int64_t raw_getlength(BlockDriverState *bs) } else return st.st_size; } +#elif defined(__NetBSD__) +static int64_t raw_getlength(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + int fd = s->fd; + struct stat st; + + if (fstat(fd, &st)) + return -1; + if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { + struct dkwedge_info dkw; + + if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) { + return dkw.dkw_size * 512; + } else { + struct disklabel dl; + + if (ioctl(fd, DIOCGDINFO, &dl)) + return -1; + return (uint64_t)dl.d_secsize * + dl.d_partitions[DISKPART(st.st_rdev)].p_size; + } + } else + return st.st_size; +} #elif defined(__sun__) static int64_t raw_getlength(BlockDriverState *bs) { @@ -718,6 +543,17 @@ static int64_t raw_getlength(BlockDriverState *bs) } #endif +static int64_t raw_get_allocated_file_size(BlockDriverState *bs) +{ + struct stat st; + BDRVRawState *s = bs->opaque; + + if (fstat(s->fd, &st) < 0) { + return -errno; + } + return (int64_t)st.st_blocks * 512; +} + static int raw_create(const char *filename, QEMUOptionParameter *options) { int fd; @@ -747,12 +583,6 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) return result; } -static int raw_flush(BlockDriverState *bs) -{ - BDRVRawState *s = bs->opaque; - return qemu_fdatasync(s->fd); -} - #ifdef CONFIG_XFS static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors) { @@ -772,7 +602,8 @@ static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors) } #endif -static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) +static coroutine_fn int raw_co_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors) { #ifdef CONFIG_XFS BDRVRawState *s = bs->opaque; @@ -800,12 +631,9 @@ static BlockDriver bdrv_file = { .instance_size = sizeof(BDRVRawState), .bdrv_probe = NULL, /* no probe for protocols */ .bdrv_file_open = raw_open, - .bdrv_read = raw_read, - .bdrv_write = raw_write, .bdrv_close = raw_close, .bdrv_create = raw_create, - .bdrv_flush = raw_flush, - .bdrv_discard = raw_discard, + .bdrv_co_discard = raw_co_discard, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, @@ -813,6 +641,8 @@ static BlockDriver bdrv_file = { .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, .create_options = raw_create_options, }; @@ -1072,15 +902,15 @@ static BlockDriver bdrv_host_device = { .bdrv_create = hdev_create, .create_options = raw_create_options, .bdrv_has_zero_init = hdev_has_zero_init, - .bdrv_flush = raw_flush, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, - .bdrv_read = raw_read, - .bdrv_write = raw_write, + .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, /* generic scsi device */ #ifdef __linux__ @@ -1115,6 +945,7 @@ static int floppy_probe_device(const char *filename) int fd, ret; int prio = 0; struct floppy_struct fdparam; + struct stat st; if (strstart(filename, "/dev/fd", NULL)) prio = 50; @@ -1123,12 +954,17 @@ static int floppy_probe_device(const char *filename) if (fd < 0) { goto out; } + ret = fstat(fd, &st); + if (ret == -1 || !S_ISBLK(st.st_mode)) { + goto outc; + } /* Attempt to detect via a floppy specific ioctl */ ret = ioctl(fd, FDGETPRM, &fdparam); if (ret >= 0) prio = 100; +outc: close(fd); out: return prio; @@ -1158,7 +994,7 @@ static int floppy_media_changed(BlockDriverState *bs) return ret; } -static int floppy_eject(BlockDriverState *bs, int eject_flag) +static void floppy_eject(BlockDriverState *bs, int eject_flag) { BDRVRawState *s = bs->opaque; int fd; @@ -1173,8 +1009,6 @@ static int floppy_eject(BlockDriverState *bs, int eject_flag) perror("FDEJECT"); close(fd); } - - return 0; } static BlockDriver bdrv_host_floppy = { @@ -1187,15 +1021,15 @@ static BlockDriver bdrv_host_floppy = { .bdrv_create = hdev_create, .create_options = raw_create_options, .bdrv_has_zero_init = hdev_has_zero_init, - .bdrv_flush = raw_flush, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, - .bdrv_read = raw_read, - .bdrv_write = raw_write, + .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, /* removable device support */ .bdrv_is_inserted = floppy_is_inserted, @@ -1217,17 +1051,23 @@ static int cdrom_probe_device(const char *filename) { int fd, ret; int prio = 0; + struct stat st; fd = open(filename, O_RDONLY | O_NONBLOCK); if (fd < 0) { goto out; } + ret = fstat(fd, &st); + if (ret == -1 || !S_ISBLK(st.st_mode)) { + goto outc; + } /* Attempt to detect via a CDROM specific ioctl */ ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); if (ret >= 0) prio = 100; +outc: close(fd); out: return prio; @@ -1244,7 +1084,7 @@ static int cdrom_is_inserted(BlockDriverState *bs) return 0; } -static int cdrom_eject(BlockDriverState *bs, int eject_flag) +static void cdrom_eject(BlockDriverState *bs, int eject_flag) { BDRVRawState *s = bs->opaque; @@ -1255,11 +1095,9 @@ static int cdrom_eject(BlockDriverState *bs, int eject_flag) if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0) perror("CDROMEJECT"); } - - return 0; } -static int cdrom_set_locked(BlockDriverState *bs, int locked) +static void cdrom_lock_medium(BlockDriverState *bs, bool locked) { BDRVRawState *s = bs->opaque; @@ -1270,8 +1108,6 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked) */ /* perror("CDROM_LOCKDOOR"); */ } - - return 0; } static BlockDriver bdrv_host_cdrom = { @@ -1284,20 +1120,20 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_create = hdev_create, .create_options = raw_create_options, .bdrv_has_zero_init = hdev_has_zero_init, - .bdrv_flush = raw_flush, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, - .bdrv_read = raw_read, - .bdrv_write = raw_write, + .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, /* removable device support */ .bdrv_is_inserted = cdrom_is_inserted, .bdrv_eject = cdrom_eject, - .bdrv_set_locked = cdrom_set_locked, + .bdrv_lock_medium = cdrom_lock_medium, /* generic scsi device */ .bdrv_ioctl = hdev_ioctl, @@ -1358,12 +1194,12 @@ static int cdrom_is_inserted(BlockDriverState *bs) return raw_getlength(bs) > 0; } -static int cdrom_eject(BlockDriverState *bs, int eject_flag) +static void cdrom_eject(BlockDriverState *bs, int eject_flag) { BDRVRawState *s = bs->opaque; if (s->fd < 0) - return -ENOTSUP; + return; (void) ioctl(s->fd, CDIOCALLOW); @@ -1375,17 +1211,15 @@ static int cdrom_eject(BlockDriverState *bs, int eject_flag) perror("CDIOCCLOSE"); } - if (cdrom_reopen(bs) < 0) - return -ENOTSUP; - return 0; + cdrom_reopen(bs); } -static int cdrom_set_locked(BlockDriverState *bs, int locked) +static void cdrom_lock_medium(BlockDriverState *bs, bool locked) { BDRVRawState *s = bs->opaque; if (s->fd < 0) - return -ENOTSUP; + return; if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) { /* * Note: an error can happen if the distribution automatically @@ -1393,8 +1227,6 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked) */ /* perror("CDROM_LOCKDOOR"); */ } - - return 0; } static BlockDriver bdrv_host_cdrom = { @@ -1407,20 +1239,20 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_create = hdev_create, .create_options = raw_create_options, .bdrv_has_zero_init = hdev_has_zero_init, - .bdrv_flush = raw_flush, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, .bdrv_aio_flush = raw_aio_flush, - .bdrv_read = raw_read, - .bdrv_write = raw_write, + .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, /* removable device support */ .bdrv_is_inserted = cdrom_is_inserted, .bdrv_eject = cdrom_eject, - .bdrv_set_locked = cdrom_set_locked, + .bdrv_lock_medium = cdrom_lock_medium, }; #endif /* __FreeBSD__ */ diff --git a/block/raw-win32.c b/block/raw-win32.c index c204a80..bbd4a57 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -41,6 +41,7 @@ typedef struct BDRVRawState { int qemu_ftruncate64(int fd, int64_t length) { LARGE_INTEGER li; + DWORD dw; LONG high; HANDLE h; BOOL res; @@ -53,12 +54,15 @@ int qemu_ftruncate64(int fd, int64_t length) /* get current position, ftruncate do not change position */ li.HighPart = 0; li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT); - if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR) + if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { return -1; + } high = length >> 32; - if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN)) + dw = SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN); + if (dw == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { return -1; + } res = SetEndOfFile(h); /* back to old position */ @@ -81,6 +85,7 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) s->type = FTYPE_FILE; +#ifndef CONFIG_MARU if (flags & BDRV_O_RDWR) { access_flags = GENERIC_READ | GENERIC_WRITE; } else { @@ -88,21 +93,52 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) } overlapped = FILE_ATTRIBUTE_NORMAL; - if ((flags & BDRV_O_NOCACHE)) - overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; - else if (!(flags & BDRV_O_CACHE_WB)) + if (flags & BDRV_O_NOCACHE) + overlapped |= FILE_FLAG_NO_BUFFERING; + if (!(flags & BDRV_O_CACHE_WB)) overlapped |= FILE_FLAG_WRITE_THROUGH; - s->hfile = CreateFile(filename, access_flags, + s->hfile = CreateFile(filename, + access_flags, FILE_SHARE_READ, NULL, OPEN_EXISTING, overlapped, NULL); - if (s->hfile == INVALID_HANDLE_VALUE) { + if (s->hfile == INVALID_HANDLE_VALUE) { int err = GetLastError(); if (err == ERROR_ACCESS_DENIED) return -EACCES; return -1; } - return 0; + +#else +#include + int open_flags = O_BINARY; + open_flags &= ~O_ACCMODE; + if (flags & BDRV_O_RDWR) { + open_flags |= O_RDWR; + } else { + open_flags |= O_RDONLY; + } + + /* Use O_DSYNC for write-through caching, no flags for write-back caching, + * and O_DIRECT for no caching. */ + /* + if ((flags & BDRV_O_NOCACHE)) { + open_flags |= O_DIRECT; + } + if (!(flags & BDRV_O_CACHE_WB)) { + open_flags |= O_DSYNC; + } + */ + + int ret = qemu_open(filename, open_flags, 0644); + if (ret < 0) { + error_report("raw_open failed(%d) \n", ret); + return -errno; + } + s->hfile = (HANDLE)_get_osfhandle(ret); + +#endif + return 0; } static int raw_read(BlockDriverState *bs, int64_t sector_num, @@ -213,6 +249,31 @@ static int64_t raw_getlength(BlockDriverState *bs) return l.QuadPart; } +static int64_t raw_get_allocated_file_size(BlockDriverState *bs) +{ + typedef DWORD (WINAPI * get_compressed_t)(const char *filename, + DWORD * high); + get_compressed_t get_compressed; + struct _stati64 st; + const char *filename = bs->filename; + /* WinNT support GetCompressedFileSize to determine allocate size */ + get_compressed = + (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), + "GetCompressedFileSizeA"); + if (get_compressed) { + DWORD high, low; + low = get_compressed(filename, &high); + if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR) { + return (((int64_t) high) << 32) + low; + } + } + + if (_stati64(filename, &st) < 0) { + return -1; + } + return st.st_size; +} + static int raw_create(const char *filename, QEMUOptionParameter *options) { int fd; @@ -252,11 +313,15 @@ static BlockDriver bdrv_file = { .bdrv_file_open = raw_open, .bdrv_close = raw_close, .bdrv_create = raw_create, - .bdrv_flush = raw_flush, - .bdrv_read = raw_read, - .bdrv_write = raw_write, + + .bdrv_read = raw_read, + .bdrv_write = raw_write, + .bdrv_co_flush_to_disk = raw_flush, + .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, .create_options = raw_create_options, }; @@ -341,7 +406,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) } s->type = find_device_type(bs, filename); - if (flags & BDRV_O_RDWR) { +#ifndef CONFIG_MARU + if (flags & BDRV_O_RDWR) { access_flags = GENERIC_READ | GENERIC_WRITE; } else { access_flags = GENERIC_READ; @@ -349,57 +415,61 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) create_flags = OPEN_EXISTING; overlapped = FILE_ATTRIBUTE_NORMAL; - if ((flags & BDRV_O_NOCACHE)) - overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; - else if (!(flags & BDRV_O_CACHE_WB)) + if (flags & BDRV_O_NOCACHE) + overlapped |= FILE_FLAG_NO_BUFFERING; + if (!(flags & BDRV_O_CACHE_WB)) overlapped |= FILE_FLAG_WRITE_THROUGH; - s->hfile = CreateFile(filename, access_flags, + + s->hfile = CreateFile(filename, + access_flags, FILE_SHARE_READ, NULL, create_flags, overlapped, NULL); - if (s->hfile == INVALID_HANDLE_VALUE) { + if (s->hfile == INVALID_HANDLE_VALUE) { int err = GetLastError(); if (err == ERROR_ACCESS_DENIED) return -EACCES; return -1; } - return 0; -} -#if 0 -/***********************************************/ -/* removable device additional commands */ - -static int raw_is_inserted(BlockDriverState *bs) -{ - return 1; -} - -static int raw_media_changed(BlockDriverState *bs) -{ - return -ENOTSUP; -} - -static int raw_eject(BlockDriverState *bs, int eject_flag) -{ - DWORD ret_count; - - if (s->type == FTYPE_FILE) - return -ENOTSUP; - if (eject_flag) { - DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA, - NULL, 0, NULL, 0, &lpBytesReturned, NULL); - } else { - DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA, - NULL, 0, NULL, 0, &lpBytesReturned, NULL); - } -} +#else + /* + s->hfile = CreateFile(g_win32_locale_filename_from_utf8(filename), + access_flags, + FILE_SHARE_READ, NULL, + create_flags, overlapped, NULL); + */ +#include + + int open_flags = O_BINARY; + open_flags &= ~O_ACCMODE; + if (flags & BDRV_O_RDWR) { + open_flags |= O_RDWR; + } else { + open_flags |= O_RDONLY; + } + + /* Use O_DSYNC for write-through caching, no flags for write-back caching, + * and O_DIRECT for no caching. */ + /* + if ((flags & BDRV_O_NOCACHE)) { + open_flags |= O_DIRECT; + } + if (!(flags & BDRV_O_CACHE_WB)) { + open_flags |= O_DSYNC; + } + */ + + int ret = qemu_open(filename, open_flags, 0644); + if (ret < 0) { + error_report("raw_open failed(%d) \n", ret); + return -errno; + } + s->hfile = (HANDLE)_get_osfhandle(ret); -static int raw_set_locked(BlockDriverState *bs, int locked) -{ - return -ENOTSUP; -} #endif + return 0; +} static int hdev_has_zero_init(BlockDriverState *bs) { @@ -413,12 +483,15 @@ static BlockDriver bdrv_host_device = { .bdrv_probe_device = hdev_probe_device, .bdrv_file_open = hdev_open, .bdrv_close = raw_close, - .bdrv_flush = raw_flush, .bdrv_has_zero_init = hdev_has_zero_init, - .bdrv_read = raw_read, - .bdrv_write = raw_write, + .bdrv_read = raw_read, + .bdrv_write = raw_write, + .bdrv_co_flush_to_disk = raw_flush, + .bdrv_getlength = raw_getlength, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, }; static void bdrv_file_init(void) diff --git a/block/raw.c b/block/raw.c index b0f72d6..6098070 100644 --- a/block/raw.c +++ b/block/raw.c @@ -9,45 +9,25 @@ static int raw_open(BlockDriverState *bs, int flags) return 0; } -static int raw_read(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors) +static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { - return bdrv_read(bs->file, sector_num, buf, nb_sectors); + return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov); } -static int raw_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) +static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { - return bdrv_write(bs->file, sector_num, buf, nb_sectors); -} - -static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) -{ - return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque); -} - -static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) -{ - return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque); + return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov); } static void raw_close(BlockDriverState *bs) { } -static int raw_flush(BlockDriverState *bs) -{ - return bdrv_flush(bs->file); -} - -static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque) +static int coroutine_fn raw_co_flush(BlockDriverState *bs) { - return bdrv_aio_flush(bs->file, cb, opaque); + return bdrv_co_flush(bs->file); } static int64_t raw_getlength(BlockDriverState *bs) @@ -65,9 +45,10 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename) return 1; /* everything can be opened as raw image */ } -static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) +static int coroutine_fn raw_co_discard(BlockDriverState *bs, + int64_t sector_num, int nb_sectors) { - return bdrv_discard(bs->file, sector_num, nb_sectors); + return bdrv_co_discard(bs->file, sector_num, nb_sectors); } static int raw_is_inserted(BlockDriverState *bs) @@ -75,15 +56,19 @@ static int raw_is_inserted(BlockDriverState *bs) return bdrv_is_inserted(bs->file); } -static int raw_eject(BlockDriverState *bs, int eject_flag) +static int raw_media_changed(BlockDriverState *bs) { - return bdrv_eject(bs->file, eject_flag); + return bdrv_media_changed(bs->file); } -static int raw_set_locked(BlockDriverState *bs, int locked) +static void raw_eject(BlockDriverState *bs, int eject_flag) { - bdrv_set_locked(bs->file, locked); - return 0; + bdrv_eject(bs->file, eject_flag); +} + +static void raw_lock_medium(BlockDriverState *bs, bool locked) +{ + bdrv_lock_medium(bs->file, locked); } static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf) @@ -120,26 +105,26 @@ static int raw_has_zero_init(BlockDriverState *bs) static BlockDriver bdrv_raw = { .format_name = "raw", - /* It's really 0, but we need to make qemu_malloc() happy */ + /* It's really 0, but we need to make g_malloc() happy */ .instance_size = 1, .bdrv_open = raw_open, .bdrv_close = raw_close, - .bdrv_read = raw_read, - .bdrv_write = raw_write, - .bdrv_flush = raw_flush, + + .bdrv_co_readv = raw_co_readv, + .bdrv_co_writev = raw_co_writev, + .bdrv_co_flush_to_disk = raw_co_flush, + .bdrv_co_discard = raw_co_discard, + .bdrv_probe = raw_probe, .bdrv_getlength = raw_getlength, .bdrv_truncate = raw_truncate, - .bdrv_aio_readv = raw_aio_readv, - .bdrv_aio_writev = raw_aio_writev, - .bdrv_aio_flush = raw_aio_flush, - .bdrv_discard = raw_discard, - .bdrv_is_inserted = raw_is_inserted, + .bdrv_media_changed = raw_media_changed, .bdrv_eject = raw_eject, - .bdrv_set_locked = raw_set_locked, + .bdrv_lock_medium = raw_lock_medium, + .bdrv_ioctl = raw_ioctl, .bdrv_aio_ioctl = raw_aio_ioctl, diff --git a/block/rbd.c b/block/rbd.c index 249a590..54a6961 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -1,45 +1,56 @@ /* * QEMU Block driver for RADOS (Ceph) * - * Copyright (C) 2010 Christian Brunner + * Copyright (C) 2010-2011 Christian Brunner , + * Josh Durgin * * This work is licensed under the terms of the GNU GPL, version 2. See * the COPYING file in the top-level directory. * */ +#include + #include "qemu-common.h" #include "qemu-error.h" - -#include "rbd_types.h" #include "block_int.h" -#include - - +#include /* * When specifying the image filename use: * - * rbd:poolname/devicename + * rbd:poolname/devicename[@snapshotname][:option1=value1[:option2=value2...]] + * + * poolname must be the name of an existing rados pool. * - * poolname must be the name of an existing rados pool + * devicename is the name of the rbd image. * - * devicename is the basename for all objects used to - * emulate the raw device. + * Each option given is used to configure rados, and may be any valid + * Ceph option, "id", or "conf". * - * Metadata information (image size, ...) is stored in an - * object with the name "devicename.rbd". + * The "id" option indicates what user we should authenticate as to + * the Ceph cluster. If it is excluded we will use the Ceph default + * (normally 'admin'). * - * The raw device is split into 4MB sized objects by default. - * The sequencenumber is encoded in a 12 byte long hex-string, - * and is attached to the devicename, separated by a dot. - * e.g. "devicename.1234567890ab" + * The "conf" option specifies a Ceph configuration file to read. If + * it is not specified, we will read from the default Ceph locations + * (e.g., /etc/ceph/ceph.conf). To avoid reading _any_ configuration + * file, specify conf=/dev/null. * + * Configuration values containing :, @, or = can be escaped with a + * leading "\". */ #define OBJ_MAX_SIZE (1UL << OBJ_DEFAULT_OBJ_ORDER) +#define RBD_MAX_CONF_NAME_SIZE 128 +#define RBD_MAX_CONF_VAL_SIZE 512 +#define RBD_MAX_CONF_SIZE 1024 +#define RBD_MAX_POOL_NAME_SIZE 128 +#define RBD_MAX_SNAP_NAME_SIZE 128 +#define RBD_MAX_SNAPS 100 + typedef struct RBDAIOCB { BlockDriverAIOCB common; QEMUBH *bh; @@ -48,7 +59,6 @@ typedef struct RBDAIOCB { char *bounce; int write; int64_t sector_num; - int aiocnt; int error; struct BDRVRBDState *s; int cancelled; @@ -59,7 +69,7 @@ typedef struct RADOSCB { RBDAIOCB *acb; struct BDRVRBDState *s; int done; - int64_t segsize; + int64_t size; char *buf; int ret; } RADOSCB; @@ -69,25 +79,22 @@ typedef struct RADOSCB { typedef struct BDRVRBDState { int fds[2]; - rados_pool_t pool; - rados_pool_t header_pool; - char name[RBD_MAX_OBJ_NAME_SIZE]; - char block_name[RBD_MAX_BLOCK_NAME_SIZE]; - uint64_t size; - uint64_t objsize; + rados_t cluster; + rados_ioctx_t io_ctx; + rbd_image_t image; + char name[RBD_MAX_IMAGE_NAME_SIZE]; int qemu_aio_count; + char *snap; int event_reader_pos; RADOSCB *event_rcb; } BDRVRBDState; -typedef struct rbd_obj_header_ondisk RbdHeader1; - static void rbd_aio_bh_cb(void *opaque); -static int rbd_next_tok(char *dst, int dst_len, - char *src, char delim, - const char *name, - char **p) +static int qemu_rbd_next_tok(char *dst, int dst_len, + char *src, char delim, + const char *name, + char **p) { int l; char *end; @@ -95,8 +102,15 @@ static int rbd_next_tok(char *dst, int dst_len, *p = NULL; if (delim != '\0') { - end = strchr(src, delim); - if (end) { + for (end = src; *end; ++end) { + if (*end == delim) { + break; + } + if (*end == '\\' && end[1] != '\0') { + end++; + } + } + if (*end == delim) { *p = end + 1; *end = '\0'; } @@ -115,10 +129,24 @@ static int rbd_next_tok(char *dst, int dst_len, return 0; } -static int rbd_parsename(const char *filename, - char *pool, int pool_len, - char *snap, int snap_len, - char *name, int name_len) +static void qemu_rbd_unescape(char *src) +{ + char *p; + + for (p = src; *src; ++src, ++p) { + if (*src == '\\' && src[1] != '\0') { + src++; + } + *p = *src; + } + *p = '\0'; +} + +static int qemu_rbd_parsename(const char *filename, + char *pool, int pool_len, + char *snap, int snap_len, + char *name, int name_len, + char *conf, int conf_len) { const char *start; char *p, *buf; @@ -128,139 +156,142 @@ static int rbd_parsename(const char *filename, return -EINVAL; } - buf = qemu_strdup(start); + buf = g_strdup(start); p = buf; + *snap = '\0'; + *conf = '\0'; - ret = rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); + ret = qemu_rbd_next_tok(pool, pool_len, p, '/', "pool name", &p); if (ret < 0 || !p) { ret = -EINVAL; goto done; } - ret = rbd_next_tok(name, name_len, p, '@', "object name", &p); - if (ret < 0) { - goto done; + qemu_rbd_unescape(pool); + + if (strchr(p, '@')) { + ret = qemu_rbd_next_tok(name, name_len, p, '@', "object name", &p); + if (ret < 0) { + goto done; + } + ret = qemu_rbd_next_tok(snap, snap_len, p, ':', "snap name", &p); + qemu_rbd_unescape(snap); + } else { + ret = qemu_rbd_next_tok(name, name_len, p, ':', "object name", &p); } - if (!p) { - *snap = '\0'; + qemu_rbd_unescape(name); + if (ret < 0 || !p) { goto done; } - ret = rbd_next_tok(snap, snap_len, p, '\0', "snap name", &p); + ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p); done: - qemu_free(buf); + g_free(buf); return ret; } -static int create_tmap_op(uint8_t op, const char *name, char **tmap_desc) +static char *qemu_rbd_parse_clientname(const char *conf, char *clientname) { - uint32_t len = strlen(name); - uint32_t len_le = cpu_to_le32(len); - /* total_len = encoding op + name + empty buffer */ - uint32_t total_len = 1 + (sizeof(uint32_t) + len) + sizeof(uint32_t); - uint8_t *desc = NULL; - - desc = qemu_malloc(total_len); - - *tmap_desc = (char *)desc; - - *desc = op; - desc++; - memcpy(desc, &len_le, sizeof(len_le)); - desc += sizeof(len_le); - memcpy(desc, name, len); - desc += len; - len = 0; /* no need for endian conversion for 0 */ - memcpy(desc, &len, sizeof(len)); - desc += sizeof(len); - - return (char *)desc - *tmap_desc; -} + const char *p = conf; -static void free_tmap_op(char *tmap_desc) -{ - qemu_free(tmap_desc); -} + while (*p) { + int len; + const char *end = strchr(p, ':'); -static int rbd_register_image(rados_pool_t pool, const char *name) -{ - char *tmap_desc; - const char *dir = RBD_DIRECTORY; - int ret; + if (end) { + len = end - p; + } else { + len = strlen(p); + } - ret = create_tmap_op(CEPH_OSD_TMAP_SET, name, &tmap_desc); - if (ret < 0) { - return ret; + if (strncmp(p, "id=", 3) == 0) { + len -= 3; + strncpy(clientname, p + 3, len); + clientname[len] = '\0'; + return clientname; + } + if (end == NULL) { + break; + } + p = end + 1; } - - ret = rados_tmap_update(pool, dir, tmap_desc, ret); - free_tmap_op(tmap_desc); - - return ret; + return NULL; } -static int touch_rbd_info(rados_pool_t pool, const char *info_oid) +static int qemu_rbd_set_conf(rados_t cluster, const char *conf) { - int r = rados_write(pool, info_oid, 0, NULL, 0); - if (r < 0) { - return r; - } - return 0; -} + char *p, *buf; + char name[RBD_MAX_CONF_NAME_SIZE]; + char value[RBD_MAX_CONF_VAL_SIZE]; + int ret = 0; -static int rbd_assign_bid(rados_pool_t pool, uint64_t *id) -{ - uint64_t out[1]; - const char *info_oid = RBD_INFO; + buf = g_strdup(conf); + p = buf; - *id = 0; + while (p) { + ret = qemu_rbd_next_tok(name, sizeof(name), p, + '=', "conf option name", &p); + if (ret < 0) { + break; + } + qemu_rbd_unescape(name); - int r = touch_rbd_info(pool, info_oid); - if (r < 0) { - return r; - } + if (!p) { + error_report("conf option %s has no value", name); + ret = -EINVAL; + break; + } - r = rados_exec(pool, info_oid, "rbd", "assign_bid", NULL, - 0, (char *)out, sizeof(out)); - if (r < 0) { - return r; - } + ret = qemu_rbd_next_tok(value, sizeof(value), p, + ':', "conf option value", &p); + if (ret < 0) { + break; + } + qemu_rbd_unescape(value); - le64_to_cpus(out); - *id = out[0]; + if (strcmp(name, "conf") == 0) { + ret = rados_conf_read_file(cluster, value); + if (ret < 0) { + error_report("error reading conf file %s", value); + break; + } + } else if (strcmp(name, "id") == 0) { + /* ignore, this is parsed by qemu_rbd_parse_clientname() */ + } else { + ret = rados_conf_set(cluster, name, value); + if (ret < 0) { + error_report("invalid conf option %s", name); + ret = -EINVAL; + break; + } + } + } - return 0; + g_free(buf); + return ret; } -static int rbd_create(const char *filename, QEMUOptionParameter *options) +static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options) { int64_t bytes = 0; int64_t objsize; - uint64_t size; - time_t mtime; - uint8_t obj_order = RBD_DEFAULT_OBJ_ORDER; - char pool[RBD_MAX_SEG_NAME_SIZE]; - char n[RBD_MAX_SEG_NAME_SIZE]; - char name[RBD_MAX_OBJ_NAME_SIZE]; - char snap_buf[RBD_MAX_SEG_NAME_SIZE]; - char *snap = NULL; - RbdHeader1 header; - rados_pool_t p; - uint64_t bid; - uint32_t hi, lo; + int obj_order = 0; + char pool[RBD_MAX_POOL_NAME_SIZE]; + char name[RBD_MAX_IMAGE_NAME_SIZE]; + char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; + char conf[RBD_MAX_CONF_SIZE]; + char clientname_buf[RBD_MAX_CONF_SIZE]; + char *clientname; + rados_t cluster; + rados_ioctx_t io_ctx; int ret; - if (rbd_parsename(filename, - pool, sizeof(pool), - snap_buf, sizeof(snap_buf), - name, sizeof(name)) < 0) { + if (qemu_rbd_parsename(filename, pool, sizeof(pool), + snap_buf, sizeof(snap_buf), + name, sizeof(name), + conf, sizeof(conf)) < 0) { return -EINVAL; } - if (snap_buf[0] != '\0') { - snap = snap_buf; - } - - snprintf(n, sizeof(n), "%s%s", name, RBD_SUFFIX); /* Read out options */ while (options && options->name) { @@ -277,82 +308,62 @@ static int rbd_create(const char *filename, QEMUOptionParameter *options) error_report("obj size too small"); return -EINVAL; } - obj_order = ffs(objsize) - 1; + obj_order = ffs(objsize) - 1; } } options++; } - memset(&header, 0, sizeof(header)); - pstrcpy(header.text, sizeof(header.text), RBD_HEADER_TEXT); - pstrcpy(header.signature, sizeof(header.signature), RBD_HEADER_SIGNATURE); - pstrcpy(header.version, sizeof(header.version), RBD_HEADER_VERSION); - header.image_size = cpu_to_le64(bytes); - header.options.order = obj_order; - header.options.crypt_type = RBD_CRYPT_NONE; - header.options.comp_type = RBD_COMP_NONE; - header.snap_seq = 0; - header.snap_count = 0; - - if (rados_initialize(0, NULL) < 0) { + clientname = qemu_rbd_parse_clientname(conf, clientname_buf); + if (rados_create(&cluster, clientname) < 0) { error_report("error initializing"); return -EIO; } - if (rados_open_pool(pool, &p)) { - error_report("error opening pool %s", pool); - rados_deinitialize(); - return -EIO; + if (strstr(conf, "conf=") == NULL) { + /* try default location, but ignore failure */ + rados_conf_read_file(cluster, NULL); } - /* check for existing rbd header file */ - ret = rados_stat(p, n, &size, &mtime); - if (ret == 0) { - ret=-EEXIST; - goto done; + if (conf[0] != '\0' && + qemu_rbd_set_conf(cluster, conf) < 0) { + error_report("error setting config options"); + rados_shutdown(cluster); + return -EIO; } - ret = rbd_assign_bid(p, &bid); - if (ret < 0) { - error_report("failed assigning block id"); - rados_deinitialize(); + if (rados_connect(cluster) < 0) { + error_report("error connecting"); + rados_shutdown(cluster); return -EIO; } - hi = bid >> 32; - lo = bid & 0xFFFFFFFF; - snprintf(header.block_name, sizeof(header.block_name), "rb.%x.%x", hi, lo); - /* create header file */ - ret = rados_write(p, n, 0, (const char *)&header, sizeof(header)); - if (ret < 0) { - goto done; + if (rados_ioctx_create(cluster, pool, &io_ctx) < 0) { + error_report("error opening pool %s", pool); + rados_shutdown(cluster); + return -EIO; } - ret = rbd_register_image(p, name); -done: - rados_close_pool(p); - rados_deinitialize(); + ret = rbd_create(io_ctx, name, bytes, &obj_order); + rados_ioctx_destroy(io_ctx); + rados_shutdown(cluster); return ret; } /* - * This aio completion is being called from rbd_aio_event_reader() and - * runs in qemu context. It schedules a bh, but just in case the aio + * This aio completion is being called from qemu_rbd_aio_event_reader() + * and runs in qemu context. It schedules a bh, but just in case the aio * was not cancelled before. */ -static void rbd_complete_aio(RADOSCB *rcb) +static void qemu_rbd_complete_aio(RADOSCB *rcb) { RBDAIOCB *acb = rcb->acb; int64_t r; - acb->aiocnt--; - if (acb->cancelled) { - if (!acb->aiocnt) { - qemu_vfree(acb->bounce); - qemu_aio_release(acb); - } + qemu_vfree(acb->bounce); + qemu_aio_release(acb); goto done; } @@ -363,41 +374,34 @@ static void rbd_complete_aio(RADOSCB *rcb) acb->ret = r; acb->error = 1; } else if (!acb->error) { - acb->ret += rcb->segsize; + acb->ret = rcb->size; } } else { - if (r == -ENOENT) { - memset(rcb->buf, 0, rcb->segsize); - if (!acb->error) { - acb->ret += rcb->segsize; - } - } else if (r < 0) { - memset(rcb->buf, 0, rcb->segsize); + if (r < 0) { + memset(rcb->buf, 0, rcb->size); acb->ret = r; acb->error = 1; - } else if (r < rcb->segsize) { - memset(rcb->buf + r, 0, rcb->segsize - r); + } else if (r < rcb->size) { + memset(rcb->buf + r, 0, rcb->size - r); if (!acb->error) { - acb->ret += rcb->segsize; + acb->ret = rcb->size; } } else if (!acb->error) { - acb->ret += r; + acb->ret = r; } } /* Note that acb->bh can be NULL in case where the aio was cancelled */ - if (!acb->aiocnt) { - acb->bh = qemu_bh_new(rbd_aio_bh_cb, acb); - qemu_bh_schedule(acb->bh); - } + acb->bh = qemu_bh_new(rbd_aio_bh_cb, acb); + qemu_bh_schedule(acb->bh); done: - qemu_free(rcb); + g_free(rcb); } /* * aio fd read handler. It runs in the qemu context and calls the * completion handling of completed rados aio operations. */ -static void rbd_aio_event_reader(void *opaque) +static void qemu_rbd_aio_event_reader(void *opaque) { BDRVRBDState *s = opaque; @@ -407,182 +411,87 @@ static void rbd_aio_event_reader(void *opaque) char *p = (char *)&s->event_rcb; /* now read the rcb pointer that was sent from a non qemu thread */ - if ((ret = read(s->fds[RBD_FD_READ], p + s->event_reader_pos, - sizeof(s->event_rcb) - s->event_reader_pos)) > 0) { - if (ret > 0) { - s->event_reader_pos += ret; - if (s->event_reader_pos == sizeof(s->event_rcb)) { - s->event_reader_pos = 0; - rbd_complete_aio(s->event_rcb); - s->qemu_aio_count --; - } + ret = read(s->fds[RBD_FD_READ], p + s->event_reader_pos, + sizeof(s->event_rcb) - s->event_reader_pos); + if (ret > 0) { + s->event_reader_pos += ret; + if (s->event_reader_pos == sizeof(s->event_rcb)) { + s->event_reader_pos = 0; + qemu_rbd_complete_aio(s->event_rcb); + s->qemu_aio_count--; } } } while (ret < 0 && errno == EINTR); } -static int rbd_aio_flush_cb(void *opaque) +static int qemu_rbd_aio_flush_cb(void *opaque) { BDRVRBDState *s = opaque; return (s->qemu_aio_count > 0); } - -static int rbd_set_snapc(rados_pool_t pool, const char *snap, RbdHeader1 *header) -{ - uint32_t snap_count = le32_to_cpu(header->snap_count); - rados_snap_t *snaps = NULL; - rados_snap_t seq; - uint32_t i; - uint64_t snap_names_len = le64_to_cpu(header->snap_names_len); - int r; - rados_snap_t snapid = 0; - - if (snap_count) { - const char *header_snap = (const char *)&header->snaps[snap_count]; - const char *end = header_snap + snap_names_len; - snaps = qemu_malloc(sizeof(rados_snap_t) * header->snap_count); - - for (i=0; i < snap_count; i++) { - snaps[i] = le64_to_cpu(header->snaps[i].id); - - if (snap && strcmp(snap, header_snap) == 0) { - snapid = snaps[i]; - } - - header_snap += strlen(header_snap) + 1; - if (header_snap > end) { - error_report("bad header, snapshot list broken"); - } - } - } - - if (snap && !snapid) { - error_report("snapshot not found"); - qemu_free(snaps); - return -ENOENT; - } - seq = le32_to_cpu(header->snap_seq); - - r = rados_set_snap_context(pool, seq, snaps, snap_count); - - rados_set_snap(pool, snapid); - - qemu_free(snaps); - - return r; -} - -#define BUF_READ_START_LEN 4096 - -static int rbd_read_header(BDRVRBDState *s, char **hbuf) -{ - char *buf = NULL; - char n[RBD_MAX_SEG_NAME_SIZE]; - uint64_t len = BUF_READ_START_LEN; - int r; - - snprintf(n, sizeof(n), "%s%s", s->name, RBD_SUFFIX); - - buf = qemu_malloc(len); - - r = rados_read(s->header_pool, n, 0, buf, len); - if (r < 0) { - goto failed; - } - - if (r < len) { - goto done; - } - - qemu_free(buf); - buf = qemu_malloc(len); - - r = rados_stat(s->header_pool, n, &len, NULL); - if (r < 0) { - goto failed; - } - - r = rados_read(s->header_pool, n, 0, buf, len); - if (r < 0) { - goto failed; - } - -done: - *hbuf = buf; - return 0; - -failed: - qemu_free(buf); - return r; -} - -static int rbd_open(BlockDriverState *bs, const char *filename, int flags) +static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags) { BDRVRBDState *s = bs->opaque; - RbdHeader1 *header; - char pool[RBD_MAX_SEG_NAME_SIZE]; - char snap_buf[RBD_MAX_SEG_NAME_SIZE]; - char *snap = NULL; - char *hbuf = NULL; + char pool[RBD_MAX_POOL_NAME_SIZE]; + char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; + char conf[RBD_MAX_CONF_SIZE]; + char clientname_buf[RBD_MAX_CONF_SIZE]; + char *clientname; int r; - if (rbd_parsename(filename, pool, sizeof(pool), - snap_buf, sizeof(snap_buf), - s->name, sizeof(s->name)) < 0) { + if (qemu_rbd_parsename(filename, pool, sizeof(pool), + snap_buf, sizeof(snap_buf), + s->name, sizeof(s->name), + conf, sizeof(conf)) < 0) { return -EINVAL; } - if (snap_buf[0] != '\0') { - snap = snap_buf; - } - if ((r = rados_initialize(0, NULL)) < 0) { + clientname = qemu_rbd_parse_clientname(conf, clientname_buf); + r = rados_create(&s->cluster, clientname); + if (r < 0) { error_report("error initializing"); return r; } - if ((r = rados_open_pool(pool, &s->pool))) { - error_report("error opening pool %s", pool); - rados_deinitialize(); - return r; + s->snap = NULL; + if (snap_buf[0] != '\0') { + s->snap = g_strdup(snap_buf); } - if ((r = rados_open_pool(pool, &s->header_pool))) { - error_report("error opening pool %s", pool); - rados_deinitialize(); - return r; + if (strstr(conf, "conf=") == NULL) { + /* try default location, but ignore failure */ + rados_conf_read_file(s->cluster, NULL); } - if ((r = rbd_read_header(s, &hbuf)) < 0) { - error_report("error reading header from %s", s->name); - goto failed; + if (conf[0] != '\0') { + r = qemu_rbd_set_conf(s->cluster, conf); + if (r < 0) { + error_report("error setting config options"); + goto failed_shutdown; + } } - if (memcmp(hbuf + 64, RBD_HEADER_SIGNATURE, 4)) { - error_report("Invalid header signature"); - r = -EMEDIUMTYPE; - goto failed; + r = rados_connect(s->cluster); + if (r < 0) { + error_report("error connecting"); + goto failed_shutdown; } - if (memcmp(hbuf + 68, RBD_HEADER_VERSION, 8)) { - error_report("Unknown image version"); - r = -EMEDIUMTYPE; - goto failed; + r = rados_ioctx_create(s->cluster, pool, &s->io_ctx); + if (r < 0) { + error_report("error opening pool %s", pool); + goto failed_shutdown; } - header = (RbdHeader1 *) hbuf; - s->size = le64_to_cpu(header->image_size); - s->objsize = 1ULL << header->options.order; - memcpy(s->block_name, header->block_name, sizeof(header->block_name)); - - r = rbd_set_snapc(s->pool, snap, header); + r = rbd_open(s->io_ctx, s->name, &s->image, s->snap); if (r < 0) { - error_report("failed setting snap context: %s", strerror(-r)); - goto failed; + error_report("error reading header from %s", s->name); + goto failed_open; } - bs->read_only = (snap != NULL); + bs->read_only = (s->snap != NULL); s->event_reader_pos = 0; r = qemu_pipe(s->fds); @@ -592,23 +501,23 @@ static int rbd_open(BlockDriverState *bs, const char *filename, int flags) } fcntl(s->fds[0], F_SETFL, O_NONBLOCK); fcntl(s->fds[1], F_SETFL, O_NONBLOCK); - qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], rbd_aio_event_reader, NULL, - rbd_aio_flush_cb, NULL, s); + qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], qemu_rbd_aio_event_reader, + NULL, qemu_rbd_aio_flush_cb, NULL, s); - qemu_free(hbuf); return 0; failed: - qemu_free(hbuf); - - rados_close_pool(s->header_pool); - rados_close_pool(s->pool); - rados_deinitialize(); + rbd_close(s->image); +failed_open: + rados_ioctx_destroy(s->io_ctx); +failed_shutdown: + rados_shutdown(s->cluster); + g_free(s->snap); return r; } -static void rbd_close(BlockDriverState *bs) +static void qemu_rbd_close(BlockDriverState *bs) { BDRVRBDState *s = bs->opaque; @@ -617,16 +526,17 @@ static void rbd_close(BlockDriverState *bs) qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL , NULL, NULL, NULL, NULL); - rados_close_pool(s->header_pool); - rados_close_pool(s->pool); - rados_deinitialize(); + rbd_close(s->image); + rados_ioctx_destroy(s->io_ctx); + g_free(s->snap); + rados_shutdown(s->cluster); } /* * Cancel aio. Since we don't reference acb in a non qemu threads, * it is safe to access it here. */ -static void rbd_aio_cancel(BlockDriverAIOCB *blockacb) +static void qemu_rbd_aio_cancel(BlockDriverAIOCB *blockacb) { RBDAIOCB *acb = (RBDAIOCB *) blockacb; acb->cancelled = 1; @@ -634,39 +544,28 @@ static void rbd_aio_cancel(BlockDriverAIOCB *blockacb) static AIOPool rbd_aio_pool = { .aiocb_size = sizeof(RBDAIOCB), - .cancel = rbd_aio_cancel, + .cancel = qemu_rbd_aio_cancel, }; -/* - * This is the callback function for rados_aio_read and _write - * - * Note: this function is being called from a non qemu thread so - * we need to be careful about what we do here. Generally we only - * write to the block notification pipe, and do the rest of the - * io completion handling from rbd_aio_event_reader() which - * runs in a qemu context. - */ -static void rbd_finish_aiocb(rados_completion_t c, RADOSCB *rcb) +static int qemu_rbd_send_pipe(BDRVRBDState *s, RADOSCB *rcb) { - int ret; - rcb->ret = rados_aio_get_return_value(c); - rados_aio_release(c); + int ret = 0; while (1) { fd_set wfd; - int fd = rcb->s->fds[RBD_FD_WRITE]; + int fd = s->fds[RBD_FD_WRITE]; - /* send the rcb pointer to the qemu thread that is responsible - for the aio completion. Must do it in a qemu thread context */ + /* send the op pointer to the qemu thread that is responsible + for the aio/op completion. Must do it in a qemu thread context */ ret = write(fd, (void *)&rcb, sizeof(rcb)); if (ret >= 0) { break; } if (errno == EINTR) { continue; - } + } if (errno != EAGAIN) { break; - } + } FD_ZERO(&wfd); FD_SET(fd, &wfd); @@ -675,13 +574,31 @@ static void rbd_finish_aiocb(rados_completion_t c, RADOSCB *rcb) } while (ret < 0 && errno == EINTR); } + return ret; +} + +/* + * This is the callback function for rbd_aio_read and _write + * + * Note: this function is being called from a non qemu thread so + * we need to be careful about what we do here. Generally we only + * write to the block notification pipe, and do the rest of the + * io completion handling from qemu_rbd_aio_event_reader() which + * runs in a qemu context. + */ +static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb) +{ + int ret; + rcb->ret = rbd_aio_get_return_value(c); + rbd_aio_release(c); + ret = qemu_rbd_send_pipe(rcb->s, rcb); if (ret < 0) { - error_report("failed writing to acb->s->fds\n"); - qemu_free(rcb); + error_report("failed writing to acb->s->fds"); + g_free(rcb); } } -/* Callback when all queued rados_aio requests are complete */ +/* Callback when all queued rbd_aio requests are complete */ static void rbd_aio_bh_cb(void *opaque) { @@ -707,19 +624,20 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs, { RBDAIOCB *acb; RADOSCB *rcb; - rados_completion_t c; - char n[RBD_MAX_SEG_NAME_SIZE]; - int64_t segnr, segoffs, segsize, last_segnr; + rbd_completion_t c; int64_t off, size; char *buf; + int r; BDRVRBDState *s = bs->opaque; acb = qemu_aio_get(&rbd_aio_pool, bs, cb, opaque); + if (!acb) { + return NULL; + } acb->write = write; acb->qiov = qiov; acb->bounce = qemu_blockalign(bs, qiov->size); - acb->aiocnt = 0; acb->ret = 0; acb->error = 0; acb->s = s; @@ -734,292 +652,187 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs, off = sector_num * BDRV_SECTOR_SIZE; size = nb_sectors * BDRV_SECTOR_SIZE; - segnr = off / s->objsize; - segoffs = off % s->objsize; - segsize = s->objsize - segoffs; - - last_segnr = ((off + size - 1) / s->objsize); - acb->aiocnt = (last_segnr - segnr) + 1; - s->qemu_aio_count += acb->aiocnt; /* All the RADOSCB */ + s->qemu_aio_count++; /* All the RADOSCB */ - while (size > 0) { - if (size < segsize) { - segsize = size; - } + rcb = g_malloc(sizeof(RADOSCB)); + rcb->done = 0; + rcb->acb = acb; + rcb->buf = buf; + rcb->s = acb->s; + rcb->size = size; + r = rbd_aio_create_completion(rcb, (rbd_callback_t) rbd_finish_aiocb, &c); + if (r < 0) { + goto failed; + } - snprintf(n, sizeof(n), "%s.%012" PRIx64, s->block_name, - segnr); - - rcb = qemu_malloc(sizeof(RADOSCB)); - rcb->done = 0; - rcb->acb = acb; - rcb->segsize = segsize; - rcb->buf = buf; - rcb->s = acb->s; - - if (write) { - rados_aio_create_completion(rcb, NULL, - (rados_callback_t) rbd_finish_aiocb, - &c); - rados_aio_write(s->pool, n, segoffs, buf, segsize, c); - } else { - rados_aio_create_completion(rcb, - (rados_callback_t) rbd_finish_aiocb, - NULL, &c); - rados_aio_read(s->pool, n, segoffs, buf, segsize, c); - } + if (write) { + r = rbd_aio_write(s->image, off, size, buf, c); + } else { + r = rbd_aio_read(s->image, off, size, buf, c); + } - buf += segsize; - size -= segsize; - segoffs = 0; - segsize = s->objsize; - segnr++; + if (r < 0) { + goto failed; } return &acb->common; + +failed: + g_free(rcb); + s->qemu_aio_count--; + qemu_aio_release(acb); + return NULL; } -static BlockDriverAIOCB *rbd_aio_readv(BlockDriverState * bs, - int64_t sector_num, QEMUIOVector * qiov, - int nb_sectors, - BlockDriverCompletionFunc * cb, - void *opaque) +static BlockDriverAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs, + int64_t sector_num, + QEMUIOVector *qiov, + int nb_sectors, + BlockDriverCompletionFunc *cb, + void *opaque) { return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); } -static BlockDriverAIOCB *rbd_aio_writev(BlockDriverState * bs, - int64_t sector_num, QEMUIOVector * qiov, - int nb_sectors, - BlockDriverCompletionFunc * cb, - void *opaque) +static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs, + int64_t sector_num, + QEMUIOVector *qiov, + int nb_sectors, + BlockDriverCompletionFunc *cb, + void *opaque) { return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); } -static int rbd_getinfo(BlockDriverState * bs, BlockDriverInfo * bdi) +static int qemu_rbd_co_flush(BlockDriverState *bs) { +#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1) + /* rbd_flush added in 0.1.1 */ BDRVRBDState *s = bs->opaque; - bdi->cluster_size = s->objsize; + return rbd_flush(s->image); +#else return 0; +#endif } -static int64_t rbd_getlength(BlockDriverState * bs) -{ - BDRVRBDState *s = bs->opaque; - - return s->size; -} - -static int rbd_snap_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) +static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi) { BDRVRBDState *s = bs->opaque; - char inbuf[512], outbuf[128]; - uint64_t snap_id; + rbd_image_info_t info; int r; - char *p = inbuf; - char *end = inbuf + sizeof(inbuf); - char n[RBD_MAX_SEG_NAME_SIZE]; - char *hbuf = NULL; - RbdHeader1 *header; - - if (sn_info->name[0] == '\0') { - return -EINVAL; /* we need a name for rbd snapshots */ - } - - /* - * rbd snapshots are using the name as the user controlled unique identifier - * we can't use the rbd snapid for that purpose, as it can't be set - */ - if (sn_info->id_str[0] != '\0' && - strcmp(sn_info->id_str, sn_info->name) != 0) { - return -EINVAL; - } - - if (strlen(sn_info->name) >= sizeof(sn_info->id_str)) { - return -ERANGE; - } - r = rados_selfmanaged_snap_create(s->header_pool, &snap_id); + r = rbd_stat(s->image, &info, sizeof(info)); if (r < 0) { - error_report("failed to create snap id: %s", strerror(-r)); return r; } - *(uint32_t *)p = strlen(sn_info->name); - cpu_to_le32s((uint32_t *)p); - p += sizeof(uint32_t); - strncpy(p, sn_info->name, end - p); - p += strlen(p); - if (p + sizeof(snap_id) > end) { - error_report("invalid input parameter"); - return -EINVAL; - } - - *(uint64_t *)p = snap_id; - cpu_to_le64s((uint64_t *)p); + bdi->cluster_size = info.obj_size; + return 0; +} - snprintf(n, sizeof(n), "%s%s", s->name, RBD_SUFFIX); +static int64_t qemu_rbd_getlength(BlockDriverState *bs) +{ + BDRVRBDState *s = bs->opaque; + rbd_image_info_t info; + int r; - r = rados_exec(s->header_pool, n, "rbd", "snap_add", inbuf, - sizeof(inbuf), outbuf, sizeof(outbuf)); + r = rbd_stat(s->image, &info, sizeof(info)); if (r < 0) { - error_report("rbd.snap_add execution failed failed: %s", strerror(-r)); return r; } - sprintf(sn_info->id_str, "%s", sn_info->name); + return info.size; +} - r = rbd_read_header(s, &hbuf); - if (r < 0) { - error_report("failed reading header: %s", strerror(-r)); - return r; - } +static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset) +{ + BDRVRBDState *s = bs->opaque; + int r; - header = (RbdHeader1 *) hbuf; - r = rbd_set_snapc(s->pool, sn_info->name, header); + r = rbd_resize(s->image, offset); if (r < 0) { - error_report("failed setting snap context: %s", strerror(-r)); - goto failed; + return r; } return 0; - -failed: - qemu_free(header); - return r; } -static int decode32(char **p, const char *end, uint32_t *v) +static int qemu_rbd_snap_create(BlockDriverState *bs, + QEMUSnapshotInfo *sn_info) { - if (*p + 4 > end) { - return -ERANGE; + BDRVRBDState *s = bs->opaque; + int r; + + if (sn_info->name[0] == '\0') { + return -EINVAL; /* we need a name for rbd snapshots */ } - *v = *(uint32_t *)(*p); - le32_to_cpus(v); - *p += 4; - return 0; -} + /* + * rbd snapshots are using the name as the user controlled unique identifier + * we can't use the rbd snapid for that purpose, as it can't be set + */ + if (sn_info->id_str[0] != '\0' && + strcmp(sn_info->id_str, sn_info->name) != 0) { + return -EINVAL; + } -static int decode64(char **p, const char *end, uint64_t *v) -{ - if (*p + 8 > end) { + if (strlen(sn_info->name) >= sizeof(sn_info->id_str)) { return -ERANGE; } - *v = *(uint64_t *)(*p); - le64_to_cpus(v); - *p += 8; - return 0; -} - -static int decode_str(char **p, const char *end, char **s) -{ - uint32_t len; - int r; - - if ((r = decode32(p, end, &len)) < 0) { + r = rbd_snap_create(s->image, sn_info->name); + if (r < 0) { + error_report("failed to create snap: %s", strerror(-r)); return r; } - *s = qemu_malloc(len + 1); - memcpy(*s, *p, len); - *p += len; - (*s)[len] = '\0'; - - return len; + return 0; } -static int rbd_snap_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) +static int qemu_rbd_snap_list(BlockDriverState *bs, + QEMUSnapshotInfo **psn_tab) { BDRVRBDState *s = bs->opaque; - char n[RBD_MAX_SEG_NAME_SIZE]; QEMUSnapshotInfo *sn_info, *sn_tab = NULL; - RbdHeader1 *header; - char *hbuf = NULL; - char *outbuf = NULL, *end, *buf; - uint64_t len; - uint64_t snap_seq; - uint32_t snap_count; - int r, i; - - /* read header to estimate how much space we need to read the snap - * list */ - if ((r = rbd_read_header(s, &hbuf)) < 0) { - goto done_err; - } - header = (RbdHeader1 *)hbuf; - len = le64_to_cpu(header->snap_names_len); - len += 1024; /* should have already been enough, but new snapshots might - already been created since we read the header. just allocate - a bit more, so that in most cases it'll suffice anyway */ - qemu_free(hbuf); - - snprintf(n, sizeof(n), "%s%s", s->name, RBD_SUFFIX); - while (1) { - qemu_free(outbuf); - outbuf = qemu_malloc(len); + int i, snap_count; + rbd_snap_info_t *snaps; + int max_snaps = RBD_MAX_SNAPS; - r = rados_exec(s->header_pool, n, "rbd", "snap_list", NULL, 0, - outbuf, len); - if (r < 0) { - error_report("rbd.snap_list execution failed failed: %s", strerror(-r)); - goto done_err; + do { + snaps = g_malloc(sizeof(*snaps) * max_snaps); + snap_count = rbd_snap_list(s->image, snaps, &max_snaps); + if (snap_count < 0) { + g_free(snaps); } - if (r != len) { - break; - } + } while (snap_count == -ERANGE); - /* if we're here, we probably raced with some snaps creation */ - len *= 2; + if (snap_count <= 0) { + goto done; } - buf = outbuf; - end = buf + len; - if ((r = decode64(&buf, end, &snap_seq)) < 0) { - goto done_err; - } - if ((r = decode32(&buf, end, &snap_count)) < 0) { - goto done_err; - } + sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo)); - sn_tab = qemu_mallocz(snap_count * sizeof(QEMUSnapshotInfo)); for (i = 0; i < snap_count; i++) { - uint64_t id, image_size; - char *snap_name; - - if ((r = decode64(&buf, end, &id)) < 0) { - goto done_err; - } - if ((r = decode64(&buf, end, &image_size)) < 0) { - goto done_err; - } - if ((r = decode_str(&buf, end, &snap_name)) < 0) { - goto done_err; - } + const char *snap_name = snaps[i].name; sn_info = sn_tab + i; pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), snap_name); pstrcpy(sn_info->name, sizeof(sn_info->name), snap_name); - qemu_free(snap_name); - sn_info->vm_state_size = image_size; + sn_info->vm_state_size = snaps[i].size; sn_info->date_sec = 0; sn_info->date_nsec = 0; sn_info->vm_clock_nsec = 0; } + rbd_snap_list_end(snaps); + + done: *psn_tab = sn_tab; - qemu_free(outbuf); return snap_count; -done_err: - qemu_free(sn_tab); - qemu_free(outbuf); - return r; } -static QEMUOptionParameter rbd_create_options[] = { +static QEMUOptionParameter qemu_rbd_create_options[] = { { .name = BLOCK_OPT_SIZE, .type = OPT_SIZE, @@ -1036,19 +849,21 @@ static QEMUOptionParameter rbd_create_options[] = { static BlockDriver bdrv_rbd = { .format_name = "rbd", .instance_size = sizeof(BDRVRBDState), - .bdrv_file_open = rbd_open, - .bdrv_close = rbd_close, - .bdrv_create = rbd_create, - .bdrv_get_info = rbd_getinfo, - .create_options = rbd_create_options, - .bdrv_getlength = rbd_getlength, + .bdrv_file_open = qemu_rbd_open, + .bdrv_close = qemu_rbd_close, + .bdrv_create = qemu_rbd_create, + .bdrv_get_info = qemu_rbd_getinfo, + .create_options = qemu_rbd_create_options, + .bdrv_getlength = qemu_rbd_getlength, + .bdrv_truncate = qemu_rbd_truncate, .protocol_name = "rbd", - .bdrv_aio_readv = rbd_aio_readv, - .bdrv_aio_writev = rbd_aio_writev, + .bdrv_aio_readv = qemu_rbd_aio_readv, + .bdrv_aio_writev = qemu_rbd_aio_writev, + .bdrv_co_flush_to_disk = qemu_rbd_co_flush, - .bdrv_snapshot_create = rbd_snap_create, - .bdrv_snapshot_list = rbd_snap_list, + .bdrv_snapshot_create = qemu_rbd_snap_create, + .bdrv_snapshot_list = qemu_rbd_snap_list, }; static void bdrv_rbd_init(void) diff --git a/block/rbd_types.h b/block/rbd_types.h deleted file mode 100644 index f4cca99..0000000 --- a/block/rbd_types.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2010 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING.LIB. - * - */ - -#ifndef CEPH_RBD_TYPES_H -#define CEPH_RBD_TYPES_H - - -/* - * rbd image 'foo' consists of objects - * foo.rbd - image metadata - * foo.00000000 - * foo.00000001 - * ... - data - */ - -#define RBD_SUFFIX ".rbd" -#define RBD_DIRECTORY "rbd_directory" -#define RBD_INFO "rbd_info" - -#define RBD_DEFAULT_OBJ_ORDER 22 /* 4MB */ - -#define RBD_MAX_OBJ_NAME_SIZE 96 -#define RBD_MAX_BLOCK_NAME_SIZE 24 -#define RBD_MAX_SEG_NAME_SIZE 128 - -#define RBD_COMP_NONE 0 -#define RBD_CRYPT_NONE 0 - -#define RBD_HEADER_TEXT "<<< Rados Block Device Image >>>\n" -#define RBD_HEADER_SIGNATURE "RBD" -#define RBD_HEADER_VERSION "001.005" - -struct rbd_info { - uint64_t max_id; -} __attribute__ ((packed)); - -struct rbd_obj_snap_ondisk { - uint64_t id; - uint64_t image_size; -} __attribute__((packed)); - -struct rbd_obj_header_ondisk { - char text[40]; - char block_name[RBD_MAX_BLOCK_NAME_SIZE]; - char signature[4]; - char version[8]; - struct { - uint8_t order; - uint8_t crypt_type; - uint8_t comp_type; - uint8_t unused; - } __attribute__((packed)) options; - uint64_t image_size; - uint64_t snap_seq; - uint32_t snap_count; - uint32_t reserved; - uint64_t snap_names_len; - struct rbd_obj_snap_ondisk snaps[0]; -} __attribute__((packed)); - - -#endif diff --git a/block/sheepdog.c b/block/sheepdog.c index a54e0de..62f1f3a 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -13,6 +13,7 @@ #include "qemu-error.h" #include "qemu_socket.h" #include "block_int.h" +#include "bitops.h" #define SD_PROTO_VER 0x01 @@ -65,7 +66,7 @@ * 20 - 31 (12 bits): reserved data object space * 32 - 55 (24 bits): vdi object space * 56 - 59 ( 4 bits): reserved vdi object space - * 60 - 63 ( 4 bits): object type indentifier space + * 60 - 63 ( 4 bits): object type identifier space */ #define VDI_SPACE_SHIFT 32 @@ -195,7 +196,7 @@ static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval) return hval; } -static inline int is_data_obj_writeable(SheepdogInode *inode, unsigned int idx) +static inline int is_data_obj_writable(SheepdogInode *inode, unsigned int idx) { return inode->vdi_id == inode->data_vdi_id[idx]; } @@ -273,7 +274,7 @@ struct SheepdogAIOCB { int ret; enum AIOCBState aiocb_type; - QEMUBH *bh; + Coroutine *coroutine; void (*aio_done_func)(SheepdogAIOCB *); int canceled; @@ -294,6 +295,10 @@ typedef struct BDRVSheepdogState { char *port; int fd; + CoMutex lock; + Coroutine *co_send; + Coroutine *co_recv; + uint32_t aioreq_seq_num; QLIST_HEAD(outstanding_aio_head, AIOReq) outstanding_aio_head; } BDRVSheepdogState; @@ -345,19 +350,16 @@ static const char * sd_strerror(int err) /* * Sheepdog I/O handling: * - * 1. In the sd_aio_readv/writev, read/write requests are added to the - * QEMU Bottom Halves. - * - * 2. In sd_readv_writev_bh_cb, the callbacks of BHs, we send the I/O - * requests to the server and link the requests to the - * outstanding_list in the BDRVSheepdogState. we exits the - * function without waiting for receiving the response. + * 1. In sd_co_rw_vector, we send the I/O requests to the server and + * link the requests to the outstanding_list in the + * BDRVSheepdogState. The function exits without waiting for + * receiving the response. * - * 3. We receive the response in aio_read_response, the fd handler to + * 2. We receive the response in aio_read_response, the fd handler to * the sheepdog connection. If metadata update is needed, we send * the write request to the vdi object in sd_write_done, the write - * completion function. The AIOCB callback is not called until all - * the requests belonging to the AIOCB are finished. + * completion function. We switch back to sd_co_readv/writev after + * all the requests belonging to the AIOCB are finished. */ static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb, @@ -367,7 +369,7 @@ static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb, { AIOReq *aio_req; - aio_req = qemu_malloc(sizeof(*aio_req)); + aio_req = g_malloc(sizeof(*aio_req)); aio_req->aiocb = acb; aio_req->iov_offset = iov_offset; aio_req->oid = oid; @@ -389,15 +391,15 @@ static inline int free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req) SheepdogAIOCB *acb = aio_req->aiocb; QLIST_REMOVE(aio_req, outstanding_aio_siblings); QLIST_REMOVE(aio_req, aioreq_siblings); - qemu_free(aio_req); + g_free(aio_req); return !QLIST_EMPTY(&acb->aioreq_head); } -static void sd_finish_aiocb(SheepdogAIOCB *acb) +static void coroutine_fn sd_finish_aiocb(SheepdogAIOCB *acb) { if (!acb->canceled) { - acb->common.cb(acb->common.opaque, acb->ret); + qemu_coroutine_enter(acb->coroutine, NULL); } qemu_aio_release(acb); } @@ -410,7 +412,8 @@ static void sd_aio_cancel(BlockDriverAIOCB *blockacb) * Sheepdog cannot cancel the requests which are already sent to * the servers, so we just complete the request with -EIO here. */ - acb->common.cb(acb->common.opaque, -EIO); + acb->ret = -EIO; + qemu_coroutine_enter(acb->coroutine, NULL); acb->canceled = 1; } @@ -434,30 +437,12 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov, acb->aio_done_func = NULL; acb->canceled = 0; - acb->bh = NULL; + acb->coroutine = qemu_coroutine_self(); acb->ret = 0; QLIST_INIT(&acb->aioreq_head); return acb; } -static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb) -{ - if (acb->bh) { - error_report("bug: %d %d\n", acb->aiocb_type, acb->aiocb_type); - return -EIO; - } - - acb->bh = qemu_bh_new(cb, acb); - if (!acb->bh) { - error_report("oom: %d %d\n", acb->aiocb_type, acb->aiocb_type); - return -EIO; - } - - qemu_bh_schedule(acb->bh); - - return 0; -} - #ifdef _WIN32 struct msghdr { @@ -475,7 +460,7 @@ static ssize_t sendmsg(int s, const struct msghdr *msg, int flags) for (i = 0; i < msg->msg_iovlen; i++) { size += msg->msg_iov[i].iov_len; } - buf = qemu_malloc(size); + buf = g_malloc(size); p = buf; for (i = 0; i < msg->msg_iovlen; i++) { @@ -485,7 +470,7 @@ static ssize_t sendmsg(int s, const struct msghdr *msg, int flags) ret = send(s, buf, size, flags); - qemu_free(buf); + g_free(buf); return ret; } @@ -499,9 +484,9 @@ static ssize_t recvmsg(int s, struct msghdr *msg, int flags) for (i = 0; i < msg->msg_iovlen; i++) { size += msg->msg_iov[i].iov_len; } - buf = qemu_malloc(size); + buf = g_malloc(size); - ret = recv(s, buf, size, flags); + ret = qemu_recv(s, buf, size, flags); if (ret < 0) { goto out; } @@ -512,7 +497,7 @@ static ssize_t recvmsg(int s, struct msghdr *msg, int flags) p += msg->msg_iov[i].iov_len; } out: - qemu_free(buf); + g_free(buf); return ret; } @@ -597,7 +582,7 @@ static int connect_to_sdog(const char *addr, const char *port) ret = getaddrinfo(addr, port, &hints, &res0); if (ret) { - error_report("unable to get address info %s, %s\n", + error_report("unable to get address info %s, %s", addr, strerror(errno)); return -1; } @@ -627,7 +612,7 @@ static int connect_to_sdog(const char *addr, const char *port) goto success; } fd = -1; - error_report("failed connect to %s:%s\n", addr, port); + error_report("failed connect to %s:%s", addr, port); success: freeaddrinfo(res0); return fd; @@ -640,10 +625,16 @@ static int do_readv_writev(int sockfd, struct iovec *iov, int len, again: ret = do_send_recv(sockfd, iov, len, iov_offset, write); if (ret < 0) { - if (errno == EINTR || errno == EAGAIN) { + if (errno == EINTR) { + goto again; + } + if (errno == EAGAIN) { + if (qemu_in_coroutine()) { + qemu_coroutine_yield(); + } goto again; } - error_report("failed to recv a rsp, %s\n", strerror(errno)); + error_report("failed to recv a rsp, %s", strerror(errno)); return 1; } @@ -702,7 +693,7 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data, ret = do_writev(sockfd, iov, sizeof(*hdr) + *wlen, 0); if (ret) { - error_report("failed to send a req, %s\n", strerror(errno)); + error_report("failed to send a req, %s", strerror(errno)); ret = -1; } @@ -722,7 +713,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data, ret = do_read(sockfd, hdr, sizeof(*hdr)); if (ret) { - error_report("failed to get a rsp, %s\n", strerror(errno)); + error_report("failed to get a rsp, %s", strerror(errno)); ret = -1; goto out; } @@ -734,7 +725,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data, if (*rlen) { ret = do_read(sockfd, data, *rlen); if (ret) { - error_report("failed to get the data, %s\n", strerror(errno)); + error_report("failed to get the data, %s", strerror(errno)); ret = -1; goto out; } @@ -744,7 +735,7 @@ out: return ret; } -static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, +static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, struct iovec *iov, int niov, int create, enum AIOCBState aiocb_type); @@ -752,7 +743,7 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, * This function searchs pending requests to the object `oid', and * sends them. */ -static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id) +static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id) { AIOReq *aio_req, *next; SheepdogAIOCB *acb; @@ -771,7 +762,7 @@ static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id) ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, 0, acb->aiocb_type); if (ret < 0) { - error_report("add_aio_request is failed\n"); + error_report("add_aio_request is failed"); free_aio_req(s, aio_req); if (QLIST_EMPTY(&acb->aioreq_head)) { sd_finish_aiocb(acb); @@ -786,7 +777,7 @@ static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id) * This function is registered as a fd handler, and called from the * main loop when s->fd is ready for reading responses. */ -static void aio_read_response(void *opaque) +static void coroutine_fn aio_read_response(void *opaque) { SheepdogObjRsp rsp; BDRVSheepdogState *s = opaque; @@ -798,14 +789,14 @@ static void aio_read_response(void *opaque) unsigned long idx; if (QLIST_EMPTY(&s->outstanding_aio_head)) { - return; + goto out; } /* read a header */ ret = do_read(fd, &rsp, sizeof(rsp)); if (ret) { - error_report("failed to get the header, %s\n", strerror(errno)); - return; + error_report("failed to get the header, %s", strerror(errno)); + goto out; } /* find the right aio_req from the outstanding_aio list */ @@ -815,8 +806,8 @@ static void aio_read_response(void *opaque) } } if (!aio_req) { - error_report("cannot find aio_req %x\n", rsp.id); - return; + error_report("cannot find aio_req %x", rsp.id); + goto out; } acb = aio_req->aiocb; @@ -851,25 +842,45 @@ static void aio_read_response(void *opaque) ret = do_readv(fd, acb->qiov->iov, rsp.data_length, aio_req->iov_offset); if (ret) { - error_report("failed to get the data, %s\n", strerror(errno)); - return; + error_report("failed to get the data, %s", strerror(errno)); + goto out; } break; } if (rsp.result != SD_RES_SUCCESS) { acb->ret = -EIO; - error_report("%s\n", sd_strerror(rsp.result)); + error_report("%s", sd_strerror(rsp.result)); } rest = free_aio_req(s, aio_req); if (!rest) { /* * We've finished all requests which belong to the AIOCB, so - * we can call the callback now. + * we can switch back to sd_co_readv/writev now. */ acb->aio_done_func(acb); } +out: + s->co_recv = NULL; +} + +static void co_read_response(void *opaque) +{ + BDRVSheepdogState *s = opaque; + + if (!s->co_recv) { + s->co_recv = qemu_coroutine_create(aio_read_response); + } + + qemu_coroutine_enter(s->co_recv, opaque); +} + +static void co_write_request(void *opaque) +{ + BDRVSheepdogState *s = opaque; + + qemu_coroutine_enter(s->co_send, NULL); } static int aio_flush_request(void *opaque) @@ -916,7 +927,7 @@ static int get_sheep_fd(BDRVSheepdogState *s) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("%s\n", strerror(errno)); + error_report("%s", strerror(errno)); return -1; } @@ -924,12 +935,12 @@ static int get_sheep_fd(BDRVSheepdogState *s) ret = set_nodelay(fd); if (ret) { - error_report("%s\n", strerror(errno)); + error_report("%s", strerror(errno)); closesocket(fd); return -1; } - qemu_aio_set_fd_handler(fd, aio_read_response, NULL, aio_flush_request, + qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, NULL, s); return fd; } @@ -957,7 +968,7 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename, char *p, *q; int nr_sep; - p = q = qemu_strdup(filename); + p = q = g_strdup(filename); /* count the number of separators */ nr_sep = 0; @@ -997,7 +1008,7 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename, } if (s->addr == NULL) { - qemu_free(q); + g_free(q); } return 0; @@ -1040,7 +1051,7 @@ static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid, } if (rsp->result != SD_RES_SUCCESS) { - error_report("cannot get vdi info, %s, %s %d %s\n", + error_report("cannot get vdi info, %s, %s %d %s", sd_strerror(rsp->result), filename, snapid, tag); ret = -1; goto out; @@ -1053,7 +1064,7 @@ out: return ret; } -static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, +static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, struct iovec *iov, int niov, int create, enum AIOCBState aiocb_type) { @@ -1068,7 +1079,7 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, uint64_t old_oid = aio_req->base_oid; if (!nr_copies) { - error_report("bug\n"); + error_report("bug"); } memset(&hdr, 0, sizeof(hdr)); @@ -1096,24 +1107,33 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, hdr.id = aio_req->id; + qemu_co_mutex_lock(&s->lock); + s->co_send = qemu_coroutine_self(); + qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request, + aio_flush_request, NULL, s); set_cork(s->fd, 1); /* send a header */ ret = do_write(s->fd, &hdr, sizeof(hdr)); if (ret) { - error_report("failed to send a req, %s\n", strerror(errno)); + qemu_co_mutex_unlock(&s->lock); + error_report("failed to send a req, %s", strerror(errno)); return -EIO; } if (wlen) { ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset); if (ret) { - error_report("failed to send a data, %s\n", strerror(errno)); + qemu_co_mutex_unlock(&s->lock); + error_report("failed to send a data, %s", strerror(errno)); return -EIO; } } set_cork(s->fd, 0); + qemu_aio_set_fd_handler(s->fd, co_read_response, NULL, + aio_flush_request, NULL, s); + qemu_co_mutex_unlock(&s->lock); return 0; } @@ -1150,7 +1170,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen); if (ret) { - error_report("failed to send a request to the sheep\n"); + error_report("failed to send a request to the sheep"); return -1; } @@ -1158,7 +1178,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, case SD_RES_SUCCESS: return 0; default: - error_report("%s\n", sd_strerror(rsp->result)); + error_report("%s", sd_strerror(rsp->result)); return -1; } } @@ -1211,11 +1231,11 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } - buf = qemu_malloc(SD_INODE_SIZE); + buf = g_malloc(SD_INODE_SIZE); ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0); closesocket(fd); @@ -1230,14 +1250,15 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags) bs->total_sectors = s->inode.vdi_size / SECTOR_SIZE; strncpy(s->name, vdi, sizeof(s->name)); - qemu_free(buf); + qemu_co_mutex_init(&s->lock); + g_free(buf); return 0; out: qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL); if (s->fd >= 0) { closesocket(s->fd); } - qemu_free(buf); + g_free(buf); return -1; } @@ -1280,7 +1301,7 @@ static int do_sd_create(char *filename, int64_t vdi_size, } if (rsp->result != SD_RES_SUCCESS) { - error_report("%s, %s\n", sd_strerror(rsp->result), filename); + error_report("%s, %s", sd_strerror(rsp->result), filename); return -EIO; } @@ -1291,6 +1312,49 @@ static int do_sd_create(char *filename, int64_t vdi_size, return 0; } +static int sd_prealloc(const char *filename) +{ + BlockDriverState *bs = NULL; + uint32_t idx, max_idx; + int64_t vdi_size; + void *buf = g_malloc0(SD_DATA_OBJ_SIZE); + int ret; + + ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR); + if (ret < 0) { + goto out; + } + + vdi_size = bdrv_getlength(bs); + if (vdi_size < 0) { + ret = vdi_size; + goto out; + } + max_idx = DIV_ROUND_UP(vdi_size, SD_DATA_OBJ_SIZE); + + for (idx = 0; idx < max_idx; idx++) { + /* + * The created image can be a cloned image, so we need to read + * a data from the source image. + */ + ret = bdrv_pread(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE); + if (ret < 0) { + goto out; + } + ret = bdrv_pwrite(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE); + if (ret < 0) { + goto out; + } + } +out: + if (bs) { + bdrv_delete(bs); + } + g_free(buf); + + return ret; +} + static int sd_create(const char *filename, QEMUOptionParameter *options) { int ret; @@ -1300,14 +1364,16 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) BDRVSheepdogState s; char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; + int prealloc = 0; + const char *vdiname; - strstart(filename, "sheepdog:", (const char **)&filename); + strstart(filename, "sheepdog:", &vdiname); memset(&s, 0, sizeof(s)); memset(vdi, 0, sizeof(vdi)); memset(tag, 0, sizeof(tag)); - if (parse_vdiname(&s, filename, vdi, &snapid, tag) < 0) { - error_report("invalid filename\n"); + if (parse_vdiname(&s, vdiname, vdi, &snapid, tag) < 0) { + error_report("invalid filename"); return -EINVAL; } @@ -1316,12 +1382,22 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) vdi_size = options->value.n; } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { backing_file = options->value.s; + } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { + if (!options->value.s || !strcmp(options->value.s, "off")) { + prealloc = 0; + } else if (!strcmp(options->value.s, "full")) { + prealloc = 1; + } else { + error_report("Invalid preallocation mode: '%s'", + options->value.s); + return -EINVAL; + } } options++; } if (vdi_size > SD_MAX_VDI_SIZE) { - error_report("too big image size\n"); + error_report("too big image size"); return -EINVAL; } @@ -1333,7 +1409,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) /* Currently, only Sheepdog backing image is supported. */ drv = bdrv_find_protocol(backing_file); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { - error_report("backing_file must be a sheepdog image\n"); + error_report("backing_file must be a sheepdog image"); return -EINVAL; } @@ -1344,7 +1420,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) s = bs->opaque; if (!is_snapshot(&s->inode)) { - error_report("cannot clone from a non snapshot vdi\n"); + error_report("cannot clone from a non snapshot vdi"); bdrv_delete(bs); return -EINVAL; } @@ -1353,7 +1429,12 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) bdrv_delete(bs); } - return do_sd_create((char *)vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port); + ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s.addr, s.port); + if (!prealloc || ret) { + return ret; + } + + return sd_prealloc(filename); } static void sd_close(BlockDriverState *bs) @@ -1384,12 +1465,12 @@ static void sd_close(BlockDriverState *bs) if (!ret && rsp->result != SD_RES_SUCCESS && rsp->result != SD_RES_VDI_NOT_LOCKED) { - error_report("%s, %s\n", sd_strerror(rsp->result), s->name); + error_report("%s, %s", sd_strerror(rsp->result), s->name); } qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL); closesocket(s->fd); - qemu_free(s->addr); + g_free(s->addr); } static int64_t sd_getlength(BlockDriverState *bs) @@ -1406,10 +1487,10 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) unsigned int datalen; if (offset < s->inode.vdi_size) { - error_report("shrinking is not supported\n"); + error_report("shrinking is not supported"); return -EINVAL; } else if (offset > SD_MAX_VDI_SIZE) { - error_report("too big image size\n"); + error_report("too big image size"); return -EINVAL; } @@ -1426,7 +1507,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) close(fd); if (ret < 0) { - error_report("failed to update an inode.\n"); + error_report("failed to update an inode."); return -EIO; } @@ -1436,9 +1517,9 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) /* * This function is called after writing data objects. If we need to * update metadata, this sends a write request to the vdi object. - * Otherwise, this calls the AIOCB callback. + * Otherwise, this switches back to sd_co_readv/writev. */ -static void sd_write_done(SheepdogAIOCB *acb) +static void coroutine_fn sd_write_done(SheepdogAIOCB *acb) { int ret; BDRVSheepdogState *s = acb->common.bs->opaque; @@ -1487,7 +1568,7 @@ static int sd_create_branch(BDRVSheepdogState *s) dprintf("%" PRIx32 " is snapshot.\n", s->inode.vdi_id); - buf = qemu_malloc(SD_INODE_SIZE); + buf = g_malloc(SD_INODE_SIZE); ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, 1, s->addr, s->port); @@ -1499,7 +1580,7 @@ static int sd_create_branch(BDRVSheepdogState *s) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } @@ -1519,7 +1600,7 @@ static int sd_create_branch(BDRVSheepdogState *s) dprintf("%" PRIx32 " was newly created.\n", s->inode.vdi_id); out: - qemu_free(buf); + g_free(buf); return ret; } @@ -1532,8 +1613,11 @@ out: * waiting the response. The responses are received in the * `aio_read_response' function which is called from the main loop as * a fd handler. + * + * Returns 1 when we need to wait a response, 0 when there is no sent + * request and -errno in error cases. */ -static void sd_readv_writev_bh_cb(void *p) +static int coroutine_fn sd_co_rw_vector(void *p) { SheepdogAIOCB *acb = p; int ret = 0; @@ -1545,9 +1629,6 @@ static void sd_readv_writev_bh_cb(void *p) SheepdogInode *inode = &s->inode; AIOReq *aio_req; - qemu_bh_delete(acb->bh); - acb->bh = NULL; - if (acb->aiocb_type == AIOCB_WRITE_UDATA && s->is_snapshot) { /* * In the case we open the snapshot VDI, Sheepdog creates the @@ -1576,7 +1657,7 @@ static void sd_readv_writev_bh_cb(void *p) create = 1; } else if (acb->aiocb_type == AIOCB_WRITE_UDATA - && !is_data_obj_writeable(inode, idx)) { + && !is_data_obj_writable(inode, idx)) { /* Copy-On-Write */ create = 1; old_oid = oid; @@ -1617,7 +1698,7 @@ static void sd_readv_writev_bh_cb(void *p) ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create, acb->aiocb_type); if (ret < 0) { - error_report("add_aio_request is failed\n"); + error_report("add_aio_request is failed"); free_aio_req(s, aio_req); acb->ret = -EIO; goto out; @@ -1629,42 +1710,47 @@ static void sd_readv_writev_bh_cb(void *p) } out: if (QLIST_EMPTY(&acb->aioreq_head)) { - sd_finish_aiocb(acb); + return acb->ret; } + return 1; } -static BlockDriverAIOCB *sd_aio_writev(BlockDriverState *bs, int64_t sector_num, - QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, - void *opaque) +static int sd_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { SheepdogAIOCB *acb; + int ret; if (bs->growable && sector_num + nb_sectors > bs->total_sectors) { /* TODO: shouldn't block here */ if (sd_truncate(bs, (sector_num + nb_sectors) * SECTOR_SIZE) < 0) { - return NULL; + return -EIO; } bs->total_sectors = sector_num + nb_sectors; } - acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, cb, opaque); + acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL); acb->aio_done_func = sd_write_done; acb->aiocb_type = AIOCB_WRITE_UDATA; - sd_schedule_bh(sd_readv_writev_bh_cb, acb); - return &acb->common; + ret = sd_co_rw_vector(acb); + if (ret <= 0) { + qemu_aio_release(acb); + return ret; + } + + qemu_coroutine_yield(); + + return acb->ret; } -static BlockDriverAIOCB *sd_aio_readv(BlockDriverState *bs, int64_t sector_num, - QEMUIOVector *qiov, int nb_sectors, - BlockDriverCompletionFunc *cb, - void *opaque) +static int sd_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { SheepdogAIOCB *acb; - int i; + int i, ret; - acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, cb, opaque); + acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL); acb->aiocb_type = AIOCB_READ_UDATA; acb->aio_done_func = sd_finish_aiocb; @@ -1676,8 +1762,15 @@ static BlockDriverAIOCB *sd_aio_readv(BlockDriverState *bs, int64_t sector_num, memset(qiov->iov[i].iov_base, 0, qiov->iov[i].iov_len); } - sd_schedule_bh(sd_readv_writev_bh_cb, acb); - return &acb->common; + ret = sd_co_rw_vector(acb); + if (ret <= 0) { + qemu_aio_release(acb); + return ret; + } + + qemu_coroutine_yield(); + + return acb->ret; } static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) @@ -1694,7 +1787,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) if (s->is_snapshot) { error_report("You can't create a snapshot of a snapshot VDI, " - "%s (%" PRIu32 ").\n", s->name, s->inode.vdi_id); + "%s (%" PRIu32 ").", s->name, s->inode.vdi_id); return -EINVAL; } @@ -1717,7 +1810,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies, datalen, 0, 0); if (ret < 0) { - error_report("failed to write snapshot's inode.\n"); + error_report("failed to write snapshot's inode."); ret = -EIO; goto cleanup; } @@ -1725,19 +1818,19 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1, s->addr, s->port); if (ret < 0) { - error_report("failed to create inode for snapshot. %s\n", + error_report("failed to create inode for snapshot. %s", strerror(errno)); ret = -EIO; goto cleanup; } - inode = (SheepdogInode *)qemu_malloc(datalen); + inode = (SheepdogInode *)g_malloc(datalen); ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid), s->inode.nr_copies, datalen, 0); if (ret < 0) { - error_report("failed to read new inode info. %s\n", strerror(errno)); + error_report("failed to read new inode info. %s", strerror(errno)); ret = -EIO; goto cleanup; } @@ -1761,7 +1854,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) uint32_t snapid = 0; int ret = -ENOENT, fd; - old_s = qemu_malloc(sizeof(BDRVSheepdogState)); + old_s = g_malloc(sizeof(BDRVSheepdogState)); memcpy(old_s, s, sizeof(BDRVSheepdogState)); @@ -1776,18 +1869,18 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) ret = find_vdi_name(s, vdi, snapid, tag, &vid, 1); if (ret) { - error_report("Failed to find_vdi_name\n"); + error_report("Failed to find_vdi_name"); ret = -ENOENT; goto out; } fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } - buf = qemu_malloc(SD_INODE_SIZE); + buf = g_malloc(SD_INODE_SIZE); ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies, SD_INODE_SIZE, 0); @@ -1801,24 +1894,24 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) memcpy(&s->inode, buf, sizeof(s->inode)); if (!s->inode.vm_state_size) { - error_report("Invalid snapshot\n"); + error_report("Invalid snapshot"); ret = -ENOENT; goto out; } s->is_snapshot = 1; - qemu_free(buf); - qemu_free(old_s); + g_free(buf); + g_free(old_s); return 0; out: /* recover bdrv_sd_state */ memcpy(s, old_s, sizeof(BDRVSheepdogState)); - qemu_free(buf); - qemu_free(old_s); + g_free(buf); + g_free(old_s); - error_report("failed to open. recover old bdrv_sd_state.\n"); + error_report("failed to open. recover old bdrv_sd_state."); return ret; } @@ -1829,20 +1922,6 @@ static int sd_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) return 0; } -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define BITS_PER_BYTE 8 -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) -#define DECLARE_BITMAP(name,bits) \ - unsigned long name[BITS_TO_LONGS(bits)] - -#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long)) - -static inline int test_bit(unsigned int nr, const unsigned long *addr) -{ - return ((1UL << (nr % BITS_PER_LONG)) & - (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; -} - static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) { BDRVSheepdogState *s = bs->opaque; @@ -1857,7 +1936,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) uint64_t hval; uint32_t vid; - vdi_inuse = qemu_malloc(max); + vdi_inuse = g_malloc(max); fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { @@ -1879,7 +1958,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) goto out; } - sn_tab = qemu_mallocz(nr * sizeof(*sn_tab)); + sn_tab = g_malloc0(nr * sizeof(*sn_tab)); /* calculate a vdi id with hash function */ hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT); @@ -1887,7 +1966,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } @@ -1922,7 +2001,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) out: *psn_tab = sn_tab; - qemu_free(vdi_inuse); + g_free(vdi_inuse); return found; } @@ -1961,7 +2040,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data, } if (ret < 0) { - error_report("failed to save vmstate %s\n", strerror(errno)); + error_report("failed to save vmstate %s", strerror(errno)); ret = -EIO; goto cleanup; } @@ -2003,6 +2082,11 @@ static QEMUOptionParameter sd_create_options[] = { .type = OPT_STRING, .help = "File name of a base image" }, + { + .name = BLOCK_OPT_PREALLOC, + .type = OPT_STRING, + .help = "Preallocation mode (allowed values: off, full)" + }, { NULL } }; @@ -2016,8 +2100,8 @@ BlockDriver bdrv_sheepdog = { .bdrv_getlength = sd_getlength, .bdrv_truncate = sd_truncate, - .bdrv_aio_readv = sd_aio_readv, - .bdrv_aio_writev = sd_aio_writev, + .bdrv_co_readv = sd_co_readv, + .bdrv_co_writev = sd_co_writev, .bdrv_snapshot_create = sd_snapshot_create, .bdrv_snapshot_goto = sd_snapshot_goto, diff --git a/block/vdi.c b/block/vdi.c index 116b25b..02da6b4 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -52,6 +52,7 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" #if defined(CONFIG_UUID) #include @@ -87,6 +88,7 @@ void uuid_unparse(const uuid_t uu, char *out); #define MiB (KiB * KiB) #define SECTOR_SIZE 512 +#define DEFAULT_CLUSTER_SIZE (1 * MiB) #if defined(CONFIG_VDI_DEBUG) #define logout(fmt, ...) \ @@ -113,8 +115,13 @@ void uuid_unparse(const uuid_t uu, char *out); */ #define VDI_TEXT "<<< QEMU VM Virtual Disk Image >>>\n" -/* Unallocated blocks use this index (no need to convert endianess). */ -#define VDI_UNALLOCATED UINT32_MAX +/* A never-allocated block; semantically arbitrary content. */ +#define VDI_UNALLOCATED 0xffffffffU + +/* A discarded (no longer allocated) block; semantically zero-filled. */ +#define VDI_DISCARDED 0xfffffffeU + +#define VDI_IS_ALLOCATED(X) ((X) < VDI_DISCARDED) #if !defined(CONFIG_UUID) void uuid_generate(uuid_t out) @@ -151,6 +158,7 @@ typedef struct { /* Buffer for new allocated block. */ void *block_buffer; void *orig_buf; + bool is_write; int header_modified; BlockDriverAIOCB *hd_aiocb; struct iovec hd_iov; @@ -194,8 +202,10 @@ typedef struct { uint32_t block_sectors; /* First sector of block map. */ uint32_t bmap_sector; - /* VDI header (converted to host endianess). */ + /* VDI header (converted to host endianness). */ VdiHeader header; + + Error *migration_blocker; } BDRVVdiState; /* Change UUID from little endian (IPRT = VirtualBox format) to big endian @@ -299,16 +309,16 @@ static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res) uint32_t *bmap; logout("\n"); - bmap = qemu_malloc(s->header.blocks_in_image * sizeof(uint32_t)); + bmap = g_malloc(s->header.blocks_in_image * sizeof(uint32_t)); memset(bmap, 0xff, s->header.blocks_in_image * sizeof(uint32_t)); /* Check block map and value of blocks_allocated. */ for (block = 0; block < s->header.blocks_in_image; block++) { uint32_t bmap_entry = le32_to_cpu(s->bmap[block]); - if (bmap_entry != VDI_UNALLOCATED) { + if (VDI_IS_ALLOCATED(bmap_entry)) { if (bmap_entry < s->header.blocks_in_image) { blocks_allocated++; - if (bmap[bmap_entry] == VDI_UNALLOCATED) { + if (!VDI_IS_ALLOCATED(bmap[bmap_entry])) { bmap[bmap_entry] = bmap_entry; } else { fprintf(stderr, "ERROR: block index %" PRIu32 @@ -329,7 +339,7 @@ static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res) res->corruptions++; } - qemu_free(bmap); + g_free(bmap); return 0; } @@ -441,16 +451,22 @@ static int vdi_open(BlockDriverState *bs, int flags) bmap_size = header.blocks_in_image * sizeof(uint32_t); bmap_size = (bmap_size + SECTOR_SIZE - 1) / SECTOR_SIZE; if (bmap_size > 0) { - s->bmap = qemu_malloc(bmap_size * SECTOR_SIZE); + s->bmap = g_malloc(bmap_size * SECTOR_SIZE); } if (bdrv_read(bs->file, s->bmap_sector, (uint8_t *)s->bmap, bmap_size) < 0) { goto fail_free_bmap; } + /* Disable migration when vdi images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vdi", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + return 0; fail_free_bmap: - qemu_free(s->bmap); + g_free(s->bmap); fail: return -1; @@ -470,7 +486,7 @@ static int vdi_is_allocated(BlockDriverState *bs, int64_t sector_num, n_sectors = nb_sectors; } *pnum = n_sectors; - return bmap_entry != VDI_UNALLOCATED; + return VDI_IS_ALLOCATED(bmap_entry); } static void vdi_aio_cancel(BlockDriverAIOCB *blockacb) @@ -503,6 +519,8 @@ static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, int64_t sector_num, acb->hd_aiocb = NULL; acb->sector_num = sector_num; acb->qiov = qiov; + acb->is_write = is_write; + if (qiov->niov > 1) { acb->buf = qemu_blockalign(bs, qiov->size); acb->orig_buf = acb->buf; @@ -541,14 +559,20 @@ static int vdi_schedule_bh(QEMUBHFunc *cb, VdiAIOCB *acb) } static void vdi_aio_read_cb(void *opaque, int ret); +static void vdi_aio_write_cb(void *opaque, int ret); -static void vdi_aio_read_bh(void *opaque) +static void vdi_aio_rw_bh(void *opaque) { VdiAIOCB *acb = opaque; logout("\n"); qemu_bh_delete(acb->bh); acb->bh = NULL; - vdi_aio_read_cb(opaque, 0); + + if (acb->is_write) { + vdi_aio_write_cb(opaque, 0); + } else { + vdi_aio_read_cb(opaque, 0); + } } static void vdi_aio_read_cb(void *opaque, int ret) @@ -593,10 +617,10 @@ static void vdi_aio_read_cb(void *opaque, int ret) /* prepare next AIO request */ acb->n_sectors = n_sectors; bmap_entry = le32_to_cpu(s->bmap[block_index]); - if (bmap_entry == VDI_UNALLOCATED) { + if (!VDI_IS_ALLOCATED(bmap_entry)) { /* Block not allocated, return zeros, no need to wait. */ memset(acb->buf, 0, n_sectors * SECTOR_SIZE); - ret = vdi_schedule_bh(vdi_aio_read_bh, acb); + ret = vdi_schedule_bh(vdi_aio_rw_bh, acb); if (ret < 0) { goto done; } @@ -610,6 +634,7 @@ static void vdi_aio_read_cb(void *opaque, int ret) acb->hd_aiocb = bdrv_aio_readv(bs->file, offset, &acb->hd_qiov, n_sectors, vdi_aio_read_cb, acb); if (acb->hd_aiocb == NULL) { + ret = -EIO; goto done; } } @@ -628,12 +653,23 @@ static BlockDriverAIOCB *vdi_aio_readv(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque) { VdiAIOCB *acb; + int ret; + logout("\n"); acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); if (!acb) { return NULL; } - vdi_aio_read_cb(acb, 0); + + ret = vdi_schedule_bh(vdi_aio_rw_bh, acb); + if (ret < 0) { + if (acb->qiov->niov > 1) { + qemu_vfree(acb->orig_buf); + } + qemu_aio_release(acb); + return NULL; + } + return &acb->common; } @@ -663,7 +699,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) if (acb->header_modified) { VdiHeader *header = acb->block_buffer; logout("now writing modified header\n"); - assert(acb->bmap_first != VDI_UNALLOCATED); + assert(VDI_IS_ALLOCATED(acb->bmap_first)); *header = s->header; vdi_header_to_le(header); acb->header_modified = 0; @@ -673,15 +709,16 @@ static void vdi_aio_write_cb(void *opaque, int ret) acb->hd_aiocb = bdrv_aio_writev(bs->file, 0, &acb->hd_qiov, 1, vdi_aio_write_cb, acb); if (acb->hd_aiocb == NULL) { + ret = -EIO; goto done; } return; - } else if (acb->bmap_first != VDI_UNALLOCATED) { + } else if (VDI_IS_ALLOCATED(acb->bmap_first)) { /* One or more new blocks were allocated. */ uint64_t offset; uint32_t bmap_first; uint32_t bmap_last; - qemu_free(acb->block_buffer); + g_free(acb->block_buffer); acb->block_buffer = NULL; bmap_first = acb->bmap_first; bmap_last = acb->bmap_last; @@ -702,6 +739,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov, n_sectors, vdi_aio_write_cb, acb); if (acb->hd_aiocb == NULL) { + ret = -EIO; goto done; } return; @@ -725,7 +763,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) /* prepare next AIO request */ acb->n_sectors = n_sectors; bmap_entry = le32_to_cpu(s->bmap[block_index]); - if (bmap_entry == VDI_UNALLOCATED) { + if (!VDI_IS_ALLOCATED(bmap_entry)) { /* Allocate new block and write to it. */ uint64_t offset; uint8_t *block; @@ -736,7 +774,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) (uint64_t)bmap_entry * s->block_sectors; block = acb->block_buffer; if (block == NULL) { - block = qemu_mallocz(s->block_size); + block = g_malloc0(s->block_size); acb->block_buffer = block; acb->bmap_first = block_index; assert(!acb->header_modified); @@ -752,6 +790,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) &acb->hd_qiov, s->block_sectors, vdi_aio_write_cb, acb); if (acb->hd_aiocb == NULL) { + ret = -EIO; goto done; } } else { @@ -764,6 +803,7 @@ static void vdi_aio_write_cb(void *opaque, int ret) acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov, n_sectors, vdi_aio_write_cb, acb); if (acb->hd_aiocb == NULL) { + ret = -EIO; goto done; } } @@ -783,12 +823,23 @@ static BlockDriverAIOCB *vdi_aio_writev(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque) { VdiAIOCB *acb; + int ret; + logout("\n"); acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); if (!acb) { return NULL; } - vdi_aio_write_cb(acb, 0); + + ret = vdi_schedule_bh(vdi_aio_rw_bh, acb); + if (ret < 0) { + if (acb->qiov->niov > 1) { + qemu_vfree(acb->orig_buf); + } + qemu_aio_release(acb); + return NULL; + } + return &acb->common; } @@ -798,7 +849,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options) int result = 0; uint64_t bytes = 0; uint32_t blocks; - size_t block_size = 1 * MiB; + size_t block_size = DEFAULT_CLUSTER_SIZE; uint32_t image_type = VDI_TYPE_DYNAMIC; VdiHeader header; size_t i; @@ -869,7 +920,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options) bmap = NULL; if (bmap_size > 0) { - bmap = (uint32_t *)qemu_mallocz(bmap_size); + bmap = (uint32_t *)g_malloc0(bmap_size); } for (i = 0; i < blocks; i++) { if (image_type == VDI_TYPE_STATIC) { @@ -881,7 +932,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options) if (write(fd, bmap, bmap_size) < 0) { result = -errno; } - qemu_free(bmap); + g_free(bmap); if (image_type == VDI_TYPE_STATIC) { if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) { result = -errno; @@ -897,12 +948,18 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options) static void vdi_close(BlockDriverState *bs) { + BDRVVdiState *s = bs->opaque; + + g_free(s->bmap); + + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } -static int vdi_flush(BlockDriverState *bs) +static coroutine_fn int vdi_co_flush(BlockDriverState *bs) { logout("\n"); - return bdrv_flush(bs->file); + return bdrv_co_flush(bs->file); } @@ -916,7 +973,8 @@ static QEMUOptionParameter vdi_create_options[] = { { .name = BLOCK_OPT_CLUSTER_SIZE, .type = OPT_SIZE, - .help = "VDI cluster (block) size" + .help = "VDI cluster (block) size", + .value = { .n = DEFAULT_CLUSTER_SIZE }, }, #endif #if defined(CONFIG_VDI_STATIC_IMAGE) @@ -937,7 +995,7 @@ static BlockDriver bdrv_vdi = { .bdrv_open = vdi_open, .bdrv_close = vdi_close, .bdrv_create = vdi_create, - .bdrv_flush = vdi_flush, + .bdrv_co_flush_to_disk = vdi_co_flush, .bdrv_is_allocated = vdi_is_allocated, .bdrv_make_empty = vdi_make_empty, diff --git a/block/vmdk.c b/block/vmdk.c index 8fc9d67..f544159 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -26,9 +26,15 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" +#include #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D') #define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V') +#define VMDK4_COMPRESSION_DEFLATE 1 +#define VMDK4_FLAG_RGD (1 << 1) +#define VMDK4_FLAG_COMPRESS (1 << 16) +#define VMDK4_FLAG_MARKER (1 << 17) typedef struct { uint32_t version; @@ -51,16 +57,24 @@ typedef struct { int64_t desc_offset; int64_t desc_size; int32_t num_gtes_per_gte; - int64_t rgd_offset; int64_t gd_offset; + int64_t rgd_offset; int64_t grain_offset; char filler[1]; char check_bytes[4]; -} __attribute__((packed)) VMDK4Header; + uint16_t compressAlgorithm; +} QEMU_PACKED VMDK4Header; #define L2_CACHE_SIZE 16 -typedef struct BDRVVmdkState { +typedef struct VmdkExtent { + BlockDriverState *file; + bool flat; + bool compressed; + bool has_marker; + int64_t sectors; + int64_t end_sector; + int64_t flat_start_offset; int64_t l1_table_offset; int64_t l1_backup_table_offset; uint32_t *l1_table; @@ -74,7 +88,17 @@ typedef struct BDRVVmdkState { uint32_t l2_cache_counts[L2_CACHE_SIZE]; unsigned int cluster_sectors; +} VmdkExtent; + +typedef struct BDRVVmdkState { + CoMutex lock; + int desc_offset; + bool cid_updated; uint32_t parent_cid; + int num_extents; + /* Extent array with num_extents entries, ascend ordered by address */ + VmdkExtent *extents; + Error *migration_blocker; } BDRVVmdkState; typedef struct VmdkMetaData { @@ -85,36 +109,117 @@ typedef struct VmdkMetaData { int valid; } VmdkMetaData; +typedef struct VmdkGrainMarker { + uint64_t lba; + uint32_t size; + uint8_t data[0]; +} VmdkGrainMarker; + static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) { uint32_t magic; - if (buf_size < 4) + if (buf_size < 4) { return 0; + } magic = be32_to_cpu(*(uint32_t *)buf); if (magic == VMDK3_MAGIC || - magic == VMDK4_MAGIC) + magic == VMDK4_MAGIC) { return 100; - else + } else { + const char *p = (const char *)buf; + const char *end = p + buf_size; + while (p < end) { + if (*p == '#') { + /* skip comment line */ + while (p < end && *p != '\n') { + p++; + } + p++; + continue; + } + if (*p == ' ') { + while (p < end && *p == ' ') { + p++; + } + /* skip '\r' if windows line endings used. */ + if (p < end && *p == '\r') { + p++; + } + /* only accept blank lines before 'version=' line */ + if (p == end || *p != '\n') { + return 0; + } + p++; + continue; + } + if (end - p >= strlen("version=X\n")) { + if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 || + strncmp("version=2\n", p, strlen("version=2\n")) == 0) { + return 100; + } + } + if (end - p >= strlen("version=X\r\n")) { + if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 || + strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) { + return 100; + } + } + return 0; + } return 0; + } } #define CHECK_CID 1 #define SECTOR_SIZE 512 -#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each -#define HEADER_SIZE 512 // first sector of 512 bytes +#define DESC_SIZE (20 * SECTOR_SIZE) /* 20 sectors of 512 bytes each */ +#define BUF_SIZE 4096 +#define HEADER_SIZE 512 /* first sector of 512 bytes */ + +static void vmdk_free_extents(BlockDriverState *bs) +{ + int i; + BDRVVmdkState *s = bs->opaque; + VmdkExtent *e; + + for (i = 0; i < s->num_extents; i++) { + e = &s->extents[i]; + g_free(e->l1_table); + g_free(e->l2_cache); + g_free(e->l1_backup_table); + if (e->file != bs->file) { + bdrv_delete(e->file); + } + } + g_free(s->extents); +} + +static void vmdk_free_last_extent(BlockDriverState *bs) +{ + BDRVVmdkState *s = bs->opaque; + + if (s->num_extents == 0) { + return; + } + s->num_extents--; + s->extents = g_realloc(s->extents, s->num_extents * sizeof(VmdkExtent)); +} static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent) { char desc[DESC_SIZE]; - uint32_t cid; + uint32_t cid = 0xffffffff; const char *p_name, *cid_str; size_t cid_str_size; + BDRVVmdkState *s = bs->opaque; + int ret; - /* the descriptor offset = 0x200 */ - if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE) + ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE); + if (ret < 0) { return 0; + } if (parent) { cid_str = "parentCID"; @@ -124,9 +229,11 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent) cid_str_size = sizeof("CID"); } - if ((p_name = strstr(desc,cid_str)) != NULL) { + desc[DESC_SIZE - 1] = '\0'; + p_name = strstr(desc, cid_str); + if (p_name != NULL) { p_name += cid_str_size; - sscanf(p_name,"%x",&cid); + sscanf(p_name, "%x", &cid); } return cid; @@ -136,21 +243,33 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid) { char desc[DESC_SIZE], tmp_desc[DESC_SIZE]; char *p_name, *tmp_str; + BDRVVmdkState *s = bs->opaque; + int ret; - /* the descriptor offset = 0x200 */ - if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE) - return -1; + ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE); + if (ret < 0) { + return ret; + } + + desc[DESC_SIZE - 1] = '\0'; + tmp_str = strstr(desc, "parentCID"); + if (tmp_str == NULL) { + return -EINVAL; + } - tmp_str = strstr(desc,"parentCID"); pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str); - if ((p_name = strstr(desc,"CID")) != NULL) { + p_name = strstr(desc, "CID"); + if (p_name != NULL) { p_name += sizeof("CID"); snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid); pstrcat(desc, sizeof(desc), tmp_desc); } - if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0) - return -1; + ret = bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE); + if (ret < 0) { + return ret; + } + return 0; } @@ -162,302 +281,429 @@ static int vmdk_is_cid_valid(BlockDriverState *bs) uint32_t cur_pcid; if (p_bs) { - cur_pcid = vmdk_read_cid(p_bs,0); - if (s->parent_cid != cur_pcid) - // CID not valid + cur_pcid = vmdk_read_cid(p_bs, 0); + if (s->parent_cid != cur_pcid) { + /* CID not valid */ return 0; + } } #endif - // CID valid + /* CID valid */ return 1; } -static int vmdk_snapshot_create(const char *filename, const char *backing_file) +static int vmdk_parent_open(BlockDriverState *bs) { - int snp_fd, p_fd; + char *p_name; + char desc[DESC_SIZE + 1]; + BDRVVmdkState *s = bs->opaque; int ret; - uint32_t p_cid; - char *p_name, *gd_buf, *rgd_buf; - const char *real_filename, *temp_str; - VMDK4Header header; - uint32_t gde_entries, gd_size; - int64_t gd_offset, rgd_offset, capacity, gt_size; - char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE]; - static const char desc_template[] = - "# Disk DescriptorFile\n" - "version=1\n" - "CID=%x\n" - "parentCID=%x\n" - "createType=\"monolithicSparse\"\n" - "parentFileNameHint=\"%s\"\n" - "\n" - "# Extent description\n" - "RW %u SPARSE \"%s\"\n" - "\n" - "# The Disk Data Base \n" - "#DDB\n" - "\n"; - - snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644); - if (snp_fd < 0) - return -errno; - p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE); - if (p_fd < 0) { - close(snp_fd); - return -errno; - } - /* read the header */ - if (lseek(p_fd, 0x0, SEEK_SET) == -1) { - ret = -errno; - goto fail; - } - if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) { - ret = -errno; - goto fail; + desc[DESC_SIZE] = '\0'; + ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE); + if (ret < 0) { + return ret; } - /* write the header */ - if (lseek(snp_fd, 0x0, SEEK_SET) == -1) { - ret = -errno; - goto fail; - } - if (write(snp_fd, hdr, HEADER_SIZE) == -1) { - ret = -errno; - goto fail; + p_name = strstr(desc, "parentFileNameHint"); + if (p_name != NULL) { + char *end_name; + + p_name += sizeof("parentFileNameHint") + 1; + end_name = strchr(p_name, '\"'); + if (end_name == NULL) { + return -EINVAL; + } + if ((end_name - p_name) > sizeof(bs->backing_file) - 1) { + return -EINVAL; + } + + pstrcpy(bs->backing_file, end_name - p_name + 1, p_name); } - memset(&header, 0, sizeof(header)); - memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC + return 0; +} - if (ftruncate(snp_fd, header.grain_offset << 9)) { - ret = -errno; - goto fail; +/* Create and append extent to the extent array. Return the added VmdkExtent + * address. return NULL if allocation failed. */ +static VmdkExtent *vmdk_add_extent(BlockDriverState *bs, + BlockDriverState *file, bool flat, int64_t sectors, + int64_t l1_offset, int64_t l1_backup_offset, + uint32_t l1_size, + int l2_size, unsigned int cluster_sectors) +{ + VmdkExtent *extent; + BDRVVmdkState *s = bs->opaque; + + s->extents = g_realloc(s->extents, + (s->num_extents + 1) * sizeof(VmdkExtent)); + extent = &s->extents[s->num_extents]; + s->num_extents++; + + memset(extent, 0, sizeof(VmdkExtent)); + extent->file = file; + extent->flat = flat; + extent->sectors = sectors; + extent->l1_table_offset = l1_offset; + extent->l1_backup_table_offset = l1_backup_offset; + extent->l1_size = l1_size; + extent->l1_entry_sectors = l2_size * cluster_sectors; + extent->l2_size = l2_size; + extent->cluster_sectors = cluster_sectors; + + if (s->num_extents > 1) { + extent->end_sector = (*(extent - 1)).end_sector + extent->sectors; + } else { + extent->end_sector = extent->sectors; } - /* the descriptor offset = 0x200 */ - if (lseek(p_fd, 0x200, SEEK_SET) == -1) { - ret = -errno; - goto fail; + bs->total_sectors = extent->end_sector; + return extent; +} + +static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent) +{ + int ret; + int l1_size, i; + + /* read the L1 table */ + l1_size = extent->l1_size * sizeof(uint32_t); + extent->l1_table = g_malloc(l1_size); + ret = bdrv_pread(extent->file, + extent->l1_table_offset, + extent->l1_table, + l1_size); + if (ret < 0) { + goto fail_l1; } - if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) { - ret = -errno; - goto fail; + for (i = 0; i < extent->l1_size; i++) { + le32_to_cpus(&extent->l1_table[i]); } - if ((p_name = strstr(p_desc,"CID")) != NULL) { - p_name += sizeof("CID"); - sscanf(p_name,"%x",&p_cid); + if (extent->l1_backup_table_offset) { + extent->l1_backup_table = g_malloc(l1_size); + ret = bdrv_pread(extent->file, + extent->l1_backup_table_offset, + extent->l1_backup_table, + l1_size); + if (ret < 0) { + goto fail_l1b; + } + for (i = 0; i < extent->l1_size; i++) { + le32_to_cpus(&extent->l1_backup_table[i]); + } } - real_filename = filename; - if ((temp_str = strrchr(real_filename, '\\')) != NULL) - real_filename = temp_str + 1; - if ((temp_str = strrchr(real_filename, '/')) != NULL) - real_filename = temp_str + 1; - if ((temp_str = strrchr(real_filename, ':')) != NULL) - real_filename = temp_str + 1; + extent->l2_cache = + g_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t)); + return 0; + fail_l1b: + g_free(extent->l1_backup_table); + fail_l1: + g_free(extent->l1_table); + return ret; +} - snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file, - (uint32_t)header.capacity, real_filename); +static int vmdk_open_vmdk3(BlockDriverState *bs, + BlockDriverState *file, + int flags) +{ + int ret; + uint32_t magic; + VMDK3Header header; + VmdkExtent *extent; - /* write the descriptor */ - if (lseek(snp_fd, 0x200, SEEK_SET) == -1) { - ret = -errno; - goto fail; + ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header)); + if (ret < 0) { + return ret; } - if (write(snp_fd, s_desc, strlen(s_desc)) == -1) { - ret = -errno; - goto fail; + extent = vmdk_add_extent(bs, + bs->file, false, + le32_to_cpu(header.disk_sectors), + le32_to_cpu(header.l1dir_offset) << 9, + 0, 1 << 6, 1 << 9, + le32_to_cpu(header.granularity)); + ret = vmdk_init_tables(bs, extent); + if (ret) { + /* free extent allocated by vmdk_add_extent */ + vmdk_free_last_extent(bs); } + return ret; +} - gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table - rgd_offset = header.rgd_offset * SECTOR_SIZE; // offset of RGD table - capacity = header.capacity * SECTOR_SIZE; // Extent size - /* - * Each GDE span 32M disk, means: - * 512 GTE per GT, each GTE points to grain - */ - gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE; - if (!gt_size) { - ret = -EINVAL; - goto fail; - } - gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde - gd_size = gde_entries * sizeof(uint32_t); +static int vmdk_open_desc_file(BlockDriverState *bs, int flags, + int64_t desc_offset); - /* write RGD */ - rgd_buf = qemu_malloc(gd_size); - if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) { - ret = -errno; - goto fail_rgd; +static int vmdk_open_vmdk4(BlockDriverState *bs, + BlockDriverState *file, + int flags) +{ + int ret; + uint32_t magic; + uint32_t l1_size, l1_entry_sectors; + VMDK4Header header; + VmdkExtent *extent; + int64_t l1_backup_offset = 0; + + ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header)); + if (ret < 0) { + return ret; } - if (read(p_fd, rgd_buf, gd_size) != gd_size) { - ret = -errno; - goto fail_rgd; + if (header.capacity == 0 && header.desc_offset) { + return vmdk_open_desc_file(bs, flags, header.desc_offset << 9); } - if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) { - ret = -errno; - goto fail_rgd; + l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte) + * le64_to_cpu(header.granularity); + if (l1_entry_sectors <= 0) { + return -EINVAL; } - if (write(snp_fd, rgd_buf, gd_size) == -1) { - ret = -errno; - goto fail_rgd; + l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1) + / l1_entry_sectors; + if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) { + l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9; + } + extent = vmdk_add_extent(bs, file, false, + le64_to_cpu(header.capacity), + le64_to_cpu(header.gd_offset) << 9, + l1_backup_offset, + l1_size, + le32_to_cpu(header.num_gtes_per_gte), + le64_to_cpu(header.granularity)); + extent->compressed = + le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE; + extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER; + ret = vmdk_init_tables(bs, extent); + if (ret) { + /* free extent allocated by vmdk_add_extent */ + vmdk_free_last_extent(bs); } + return ret; +} - /* write GD */ - gd_buf = qemu_malloc(gd_size); - if (lseek(p_fd, gd_offset, SEEK_SET) == -1) { - ret = -errno; - goto fail_gd; +/* find an option value out of descriptor file */ +static int vmdk_parse_description(const char *desc, const char *opt_name, + char *buf, int buf_size) +{ + char *opt_pos, *opt_end; + const char *end = desc + strlen(desc); + + opt_pos = strstr(desc, opt_name); + if (!opt_pos) { + return -1; } - if (read(p_fd, gd_buf, gd_size) != gd_size) { - ret = -errno; - goto fail_gd; + /* Skip "=\"" following opt_name */ + opt_pos += strlen(opt_name) + 2; + if (opt_pos >= end) { + return -1; } - if (lseek(snp_fd, gd_offset, SEEK_SET) == -1) { - ret = -errno; - goto fail_gd; + opt_end = opt_pos; + while (opt_end < end && *opt_end != '"') { + opt_end++; } - if (write(snp_fd, gd_buf, gd_size) == -1) { - ret = -errno; - goto fail_gd; + if (opt_end == end || buf_size < opt_end - opt_pos + 1) { + return -1; } - ret = 0; - -fail_gd: - qemu_free(gd_buf); -fail_rgd: - qemu_free(rgd_buf); -fail: - close(p_fd); - close(snp_fd); - return ret; + pstrcpy(buf, opt_end - opt_pos + 1, opt_pos); + return 0; } -static int vmdk_parent_open(BlockDriverState *bs) +/* Open an extent file and append to bs array */ +static int vmdk_open_sparse(BlockDriverState *bs, + BlockDriverState *file, + int flags) { - char *p_name; - char desc[DESC_SIZE]; + uint32_t magic; - /* the descriptor offset = 0x200 */ - if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE) - return -1; + if (bdrv_pread(file, 0, &magic, sizeof(magic)) != sizeof(magic)) { + return -EIO; + } - if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) { - char *end_name; + magic = be32_to_cpu(magic); + switch (magic) { + case VMDK3_MAGIC: + return vmdk_open_vmdk3(bs, file, flags); + break; + case VMDK4_MAGIC: + return vmdk_open_vmdk4(bs, file, flags); + break; + default: + return -EINVAL; + break; + } +} - p_name += sizeof("parentFileNameHint") + 1; - if ((end_name = strchr(p_name,'\"')) == NULL) - return -1; - if ((end_name - p_name) > sizeof (bs->backing_file) - 1) - return -1; +static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, + const char *desc_file_path) +{ + int ret; + char access[11]; + char type[11]; + char fname[512]; + const char *p = desc; + int64_t sectors = 0; + int64_t flat_offset; + char extent_path[PATH_MAX]; + BlockDriverState *extent_file; + + while (*p) { + /* parse extent line: + * RW [size in sectors] FLAT "file-name.vmdk" OFFSET + * or + * RW [size in sectors] SPARSE "file-name.vmdk" + */ + flat_offset = -1; + ret = sscanf(p, "%10s %" SCNd64 " %10s %511s %" SCNd64, + access, §ors, type, fname, &flat_offset); + if (ret < 4 || strcmp(access, "RW")) { + goto next_line; + } else if (!strcmp(type, "FLAT")) { + if (ret != 5 || flat_offset < 0) { + return -EINVAL; + } + } else if (ret != 4) { + return -EINVAL; + } - pstrcpy(bs->backing_file, end_name - p_name + 1, p_name); - } + /* trim the quotation marks around */ + if (fname[0] == '"') { + memmove(fname, fname + 1, strlen(fname)); + if (strlen(fname) <= 1 || fname[strlen(fname) - 1] != '"') { + return -EINVAL; + } + fname[strlen(fname) - 1] = '\0'; + } + if (sectors <= 0 || + (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) || + (strcmp(access, "RW"))) { + goto next_line; + } + + path_combine(extent_path, sizeof(extent_path), + desc_file_path, fname); + ret = bdrv_file_open(&extent_file, extent_path, bs->open_flags); + if (ret) { + return ret; + } + /* save to extents array */ + if (!strcmp(type, "FLAT")) { + /* FLAT extent */ + VmdkExtent *extent; + + extent = vmdk_add_extent(bs, extent_file, true, sectors, + 0, 0, 0, 0, sectors); + extent->flat_start_offset = flat_offset << 9; + } else if (!strcmp(type, "SPARSE")) { + /* SPARSE extent */ + ret = vmdk_open_sparse(bs, extent_file, bs->open_flags); + if (ret) { + bdrv_delete(extent_file); + return ret; + } + } else { + fprintf(stderr, + "VMDK: Not supported extent type \"%s\""".\n", type); + return -ENOTSUP; + } +next_line: + /* move to next line */ + while (*p && *p != '\n') { + p++; + } + p++; + } return 0; } -static int vmdk_open(BlockDriverState *bs, int flags) +static int vmdk_open_desc_file(BlockDriverState *bs, int flags, + int64_t desc_offset) { + int ret; + char buf[2048]; + char ct[128]; BDRVVmdkState *s = bs->opaque; - uint32_t magic; - int l1_size, i; - - if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) - goto fail; - magic = be32_to_cpu(magic); - if (magic == VMDK3_MAGIC) { - VMDK3Header header; + ret = bdrv_pread(bs->file, desc_offset, buf, sizeof(buf)); + if (ret < 0) { + return ret; + } + buf[2047] = '\0'; + if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) { + return -EINVAL; + } + if (strcmp(ct, "monolithicFlat") && + strcmp(ct, "twoGbMaxExtentSparse") && + strcmp(ct, "twoGbMaxExtentFlat")) { + fprintf(stderr, + "VMDK: Not supported image type \"%s\""".\n", ct); + return -ENOTSUP; + } + s->desc_offset = 0; + return vmdk_parse_extents(buf, bs, bs->file->filename); +} - if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header)) - goto fail; - s->cluster_sectors = le32_to_cpu(header.granularity); - s->l2_size = 1 << 9; - s->l1_size = 1 << 6; - bs->total_sectors = le32_to_cpu(header.disk_sectors); - s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9; - s->l1_backup_table_offset = 0; - s->l1_entry_sectors = s->l2_size * s->cluster_sectors; - } else if (magic == VMDK4_MAGIC) { - VMDK4Header header; - - if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header)) - goto fail; - bs->total_sectors = le64_to_cpu(header.capacity); - s->cluster_sectors = le64_to_cpu(header.granularity); - s->l2_size = le32_to_cpu(header.num_gtes_per_gte); - s->l1_entry_sectors = s->l2_size * s->cluster_sectors; - if (s->l1_entry_sectors <= 0) - goto fail; - s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1) - / s->l1_entry_sectors; - s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9; - s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9; +static int vmdk_open(BlockDriverState *bs, int flags) +{ + int ret; + BDRVVmdkState *s = bs->opaque; - // try to open parent images, if exist - if (vmdk_parent_open(bs) != 0) - goto fail; - // write the CID once after the image creation - s->parent_cid = vmdk_read_cid(bs,1); + if (vmdk_open_sparse(bs, bs->file, flags) == 0) { + s->desc_offset = 0x200; } else { - goto fail; + ret = vmdk_open_desc_file(bs, flags, 0); + if (ret) { + goto fail; + } } - - /* read the L1 table */ - l1_size = s->l1_size * sizeof(uint32_t); - s->l1_table = qemu_malloc(l1_size); - if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, l1_size) != l1_size) + /* try to open parent images, if exist */ + ret = vmdk_parent_open(bs); + if (ret) { goto fail; - for(i = 0; i < s->l1_size; i++) { - le32_to_cpus(&s->l1_table[i]); } + s->parent_cid = vmdk_read_cid(bs, 1); + qemu_co_mutex_init(&s->lock); - if (s->l1_backup_table_offset) { - s->l1_backup_table = qemu_malloc(l1_size); - if (bdrv_pread(bs->file, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size) - goto fail; - for(i = 0; i < s->l1_size; i++) { - le32_to_cpus(&s->l1_backup_table[i]); - } - } + /* Disable migration when VMDK images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vmdk", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); - s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t)); return 0; - fail: - qemu_free(s->l1_backup_table); - qemu_free(s->l1_table); - qemu_free(s->l2_cache); - return -1; -} -static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data, - uint64_t offset, int allocate); +fail: + vmdk_free_extents(bs); + return ret; +} -static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset, - uint64_t offset, int allocate) +static int get_whole_cluster(BlockDriverState *bs, + VmdkExtent *extent, + uint64_t cluster_offset, + uint64_t offset, + bool allocate) { - BDRVVmdkState *s = bs->opaque; - uint8_t whole_grain[s->cluster_sectors*512]; // 128 sectors * 512 bytes each = grain size 64KB + /* 128 sectors * 512 bytes each = grain size 64KB */ + uint8_t whole_grain[extent->cluster_sectors * 512]; - // we will be here if it's first write on non-exist grain(cluster). - // try to read from parent image, if exist + /* we will be here if it's first write on non-exist grain(cluster). + * try to read from parent image, if exist */ if (bs->backing_hd) { int ret; - if (!vmdk_is_cid_valid(bs)) + if (!vmdk_is_cid_valid(bs)) { return -1; + } + /* floor offset to cluster */ + offset -= offset % (extent->cluster_sectors * 512); ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain, - s->cluster_sectors); + extent->cluster_sectors); if (ret < 0) { return -1; } - //Write grain only into the active image - ret = bdrv_write(bs->file, cluster_offset, whole_grain, - s->cluster_sectors); + /* Write grain only into the active image */ + ret = bdrv_write(extent->file, cluster_offset, whole_grain, + extent->cluster_sectors); if (ret < 0) { return -1; } @@ -465,85 +711,115 @@ static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset, return 0; } -static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data) +static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data) { - BDRVVmdkState *s = bs->opaque; - /* update L2 table */ - if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)), - &(m_data->offset), sizeof(m_data->offset)) < 0) + if (bdrv_pwrite_sync( + extent->file, + ((int64_t)m_data->l2_offset * 512) + + (m_data->l2_index * sizeof(m_data->offset)), + &(m_data->offset), + sizeof(m_data->offset) + ) < 0) { return -1; + } /* update backup L2 table */ - if (s->l1_backup_table_offset != 0) { - m_data->l2_offset = s->l1_backup_table[m_data->l1_index]; - if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)), - &(m_data->offset), sizeof(m_data->offset)) < 0) + if (extent->l1_backup_table_offset != 0) { + m_data->l2_offset = extent->l1_backup_table[m_data->l1_index]; + if (bdrv_pwrite_sync( + extent->file, + ((int64_t)m_data->l2_offset * 512) + + (m_data->l2_index * sizeof(m_data->offset)), + &(m_data->offset), sizeof(m_data->offset) + ) < 0) { return -1; + } } return 0; } -static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data, - uint64_t offset, int allocate) +static int get_cluster_offset(BlockDriverState *bs, + VmdkExtent *extent, + VmdkMetaData *m_data, + uint64_t offset, + int allocate, + uint64_t *cluster_offset) { - BDRVVmdkState *s = bs->opaque; unsigned int l1_index, l2_offset, l2_index; int min_index, i, j; uint32_t min_count, *l2_table, tmp = 0; - uint64_t cluster_offset; - if (m_data) + if (m_data) { m_data->valid = 0; - - l1_index = (offset >> 9) / s->l1_entry_sectors; - if (l1_index >= s->l1_size) - return 0; - l2_offset = s->l1_table[l1_index]; - if (!l2_offset) + } + if (extent->flat) { + *cluster_offset = extent->flat_start_offset; return 0; - for(i = 0; i < L2_CACHE_SIZE; i++) { - if (l2_offset == s->l2_cache_offsets[i]) { + } + + offset -= (extent->end_sector - extent->sectors) * SECTOR_SIZE; + l1_index = (offset >> 9) / extent->l1_entry_sectors; + if (l1_index >= extent->l1_size) { + return -1; + } + l2_offset = extent->l1_table[l1_index]; + if (!l2_offset) { + return -1; + } + for (i = 0; i < L2_CACHE_SIZE; i++) { + if (l2_offset == extent->l2_cache_offsets[i]) { /* increment the hit count */ - if (++s->l2_cache_counts[i] == 0xffffffff) { - for(j = 0; j < L2_CACHE_SIZE; j++) { - s->l2_cache_counts[j] >>= 1; + if (++extent->l2_cache_counts[i] == 0xffffffff) { + for (j = 0; j < L2_CACHE_SIZE; j++) { + extent->l2_cache_counts[j] >>= 1; } } - l2_table = s->l2_cache + (i * s->l2_size); + l2_table = extent->l2_cache + (i * extent->l2_size); goto found; } } /* not found: load a new entry in the least used one */ min_index = 0; min_count = 0xffffffff; - for(i = 0; i < L2_CACHE_SIZE; i++) { - if (s->l2_cache_counts[i] < min_count) { - min_count = s->l2_cache_counts[i]; + for (i = 0; i < L2_CACHE_SIZE; i++) { + if (extent->l2_cache_counts[i] < min_count) { + min_count = extent->l2_cache_counts[i]; min_index = i; } } - l2_table = s->l2_cache + (min_index * s->l2_size); - if (bdrv_pread(bs->file, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) != - s->l2_size * sizeof(uint32_t)) - return 0; + l2_table = extent->l2_cache + (min_index * extent->l2_size); + if (bdrv_pread( + extent->file, + (int64_t)l2_offset * 512, + l2_table, + extent->l2_size * sizeof(uint32_t) + ) != extent->l2_size * sizeof(uint32_t)) { + return -1; + } - s->l2_cache_offsets[min_index] = l2_offset; - s->l2_cache_counts[min_index] = 1; + extent->l2_cache_offsets[min_index] = l2_offset; + extent->l2_cache_counts[min_index] = 1; found: - l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size; - cluster_offset = le32_to_cpu(l2_table[l2_index]); + l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size; + *cluster_offset = le32_to_cpu(l2_table[l2_index]); - if (!cluster_offset) { - if (!allocate) - return 0; + if (!*cluster_offset) { + if (!allocate) { + return -1; + } - // Avoid the L2 tables update for the images that have snapshots. - cluster_offset = bdrv_getlength(bs->file); - bdrv_truncate(bs->file, cluster_offset + (s->cluster_sectors << 9)); + /* Avoid the L2 tables update for the images that have snapshots. */ + *cluster_offset = bdrv_getlength(extent->file); + if (!extent->compressed) { + bdrv_truncate( + extent->file, + *cluster_offset + (extent->cluster_sectors << 9) + ); + } - cluster_offset >>= 9; - tmp = cpu_to_le32(cluster_offset); + *cluster_offset >>= 9; + tmp = cpu_to_le32(*cluster_offset); l2_table[l2_index] = tmp; /* First of all we write grain itself, to avoid race condition @@ -551,8 +827,10 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data, * This problem may occur because of insufficient space on host disk * or inappropriate VM shutdown. */ - if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1) - return 0; + if (get_whole_cluster( + bs, extent, *cluster_offset, offset, allocate) == -1) { + return -1; + } if (m_data) { m_data->offset = tmp; @@ -562,53 +840,202 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data, m_data->valid = 1; } } - cluster_offset <<= 9; - return cluster_offset; + *cluster_offset <<= 9; + return 0; +} + +static VmdkExtent *find_extent(BDRVVmdkState *s, + int64_t sector_num, VmdkExtent *start_hint) +{ + VmdkExtent *extent = start_hint; + + if (!extent) { + extent = &s->extents[0]; + } + while (extent < &s->extents[s->num_extents]) { + if (sector_num < extent->end_sector) { + return extent; + } + extent++; + } + return NULL; } static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { BDRVVmdkState *s = bs->opaque; - int index_in_cluster, n; - uint64_t cluster_offset; + int64_t index_in_cluster, n, ret; + uint64_t offset; + VmdkExtent *extent; - cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0); - index_in_cluster = sector_num % s->cluster_sectors; - n = s->cluster_sectors - index_in_cluster; - if (n > nb_sectors) + extent = find_extent(s, sector_num, NULL); + if (!extent) { + return 0; + } + ret = get_cluster_offset(bs, extent, NULL, + sector_num * 512, 0, &offset); + /* get_cluster_offset returning 0 means success */ + ret = !ret; + + index_in_cluster = sector_num % extent->cluster_sectors; + n = extent->cluster_sectors - index_in_cluster; + if (n > nb_sectors) { n = nb_sectors; + } *pnum = n; - return (cluster_offset != 0); + return ret; +} + +static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, + int64_t offset_in_cluster, const uint8_t *buf, + int nb_sectors, int64_t sector_num) +{ + int ret; + VmdkGrainMarker *data = NULL; + uLongf buf_len; + const uint8_t *write_buf = buf; + int write_len = nb_sectors * 512; + + if (extent->compressed) { + if (!extent->has_marker) { + ret = -EINVAL; + goto out; + } + buf_len = (extent->cluster_sectors << 9) * 2; + data = g_malloc(buf_len + sizeof(VmdkGrainMarker)); + if (compress(data->data, &buf_len, buf, nb_sectors << 9) != Z_OK || + buf_len == 0) { + ret = -EINVAL; + goto out; + } + data->lba = sector_num; + data->size = buf_len; + write_buf = (uint8_t *)data; + write_len = buf_len + sizeof(VmdkGrainMarker); + } + ret = bdrv_pwrite(extent->file, + cluster_offset + offset_in_cluster, + write_buf, + write_len); + if (ret != write_len) { + ret = ret < 0 ? ret : -EIO; + goto out; + } + ret = 0; + out: + g_free(data); + return ret; +} + +static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, + int64_t offset_in_cluster, uint8_t *buf, + int nb_sectors) +{ + int ret; + int cluster_bytes, buf_bytes; + uint8_t *cluster_buf, *compressed_data; + uint8_t *uncomp_buf; + uint32_t data_len; + VmdkGrainMarker *marker; + uLongf buf_len; + + + if (!extent->compressed) { + ret = bdrv_pread(extent->file, + cluster_offset + offset_in_cluster, + buf, nb_sectors * 512); + if (ret == nb_sectors * 512) { + return 0; + } else { + return -EIO; + } + } + cluster_bytes = extent->cluster_sectors * 512; + /* Read two clusters in case GrainMarker + compressed data > one cluster */ + buf_bytes = cluster_bytes * 2; + cluster_buf = g_malloc(buf_bytes); + uncomp_buf = g_malloc(cluster_bytes); + ret = bdrv_pread(extent->file, + cluster_offset, + cluster_buf, buf_bytes); + if (ret < 0) { + goto out; + } + compressed_data = cluster_buf; + buf_len = cluster_bytes; + data_len = cluster_bytes; + if (extent->has_marker) { + marker = (VmdkGrainMarker *)cluster_buf; + compressed_data = marker->data; + data_len = le32_to_cpu(marker->size); + } + if (!data_len || data_len > buf_bytes) { + ret = -EINVAL; + goto out; + } + ret = uncompress(uncomp_buf, &buf_len, compressed_data, data_len); + if (ret != Z_OK) { + ret = -EINVAL; + goto out; + + } + if (offset_in_cluster < 0 || + offset_in_cluster + nb_sectors * 512 > buf_len) { + ret = -EINVAL; + goto out; + } + memcpy(buf, uncomp_buf + offset_in_cluster, nb_sectors * 512); + ret = 0; + + out: + g_free(uncomp_buf); + g_free(cluster_buf); + return ret; } static int vmdk_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { BDRVVmdkState *s = bs->opaque; - int index_in_cluster, n, ret; + int ret; + uint64_t n, index_in_cluster; + VmdkExtent *extent = NULL; uint64_t cluster_offset; while (nb_sectors > 0) { - cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0); - index_in_cluster = sector_num % s->cluster_sectors; - n = s->cluster_sectors - index_in_cluster; - if (n > nb_sectors) + extent = find_extent(s, sector_num, extent); + if (!extent) { + return -EIO; + } + ret = get_cluster_offset( + bs, extent, NULL, + sector_num << 9, 0, &cluster_offset); + index_in_cluster = sector_num % extent->cluster_sectors; + n = extent->cluster_sectors - index_in_cluster; + if (n > nb_sectors) { n = nb_sectors; - if (!cluster_offset) { - // try to read from parent image, if exist + } + if (ret) { + /* if not allocated, try to read from parent image, if exist */ if (bs->backing_hd) { - if (!vmdk_is_cid_valid(bs)) - return -1; + if (!vmdk_is_cid_valid(bs)) { + return -EINVAL; + } ret = bdrv_read(bs->backing_hd, sector_num, buf, n); - if (ret < 0) - return -1; + if (ret < 0) { + return ret; + } } else { memset(buf, 0, 512 * n); } } else { - if(bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512) - return -1; + ret = vmdk_read_extent(extent, + cluster_offset, index_in_cluster * 512, + buf, n); + if (ret) { + return ret; + } } nb_sectors -= n; sector_num += n; @@ -617,114 +1044,149 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num, return 0; } +static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVVmdkState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = vmdk_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static int vmdk_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { BDRVVmdkState *s = bs->opaque; - VmdkMetaData m_data; - int index_in_cluster, n; + VmdkExtent *extent = NULL; + int n, ret; + int64_t index_in_cluster; uint64_t cluster_offset; - static int cid_update = 0; + VmdkMetaData m_data; if (sector_num > bs->total_sectors) { fprintf(stderr, "(VMDK) Wrong offset: sector_num=0x%" PRIx64 " total_sectors=0x%" PRIx64 "\n", sector_num, bs->total_sectors); - return -1; + return -EIO; } while (nb_sectors > 0) { - index_in_cluster = sector_num & (s->cluster_sectors - 1); - n = s->cluster_sectors - index_in_cluster; - if (n > nb_sectors) + extent = find_extent(s, sector_num, extent); + if (!extent) { + return -EIO; + } + ret = get_cluster_offset( + bs, + extent, + &m_data, + sector_num << 9, !extent->compressed, + &cluster_offset); + if (extent->compressed) { + if (ret == 0) { + /* Refuse write to allocated cluster for streamOptimized */ + fprintf(stderr, + "VMDK: can't write to allocated cluster" + " for streamOptimized\n"); + return -EIO; + } else { + /* allocate */ + ret = get_cluster_offset( + bs, + extent, + &m_data, + sector_num << 9, 1, + &cluster_offset); + } + } + if (ret) { + return -EINVAL; + } + index_in_cluster = sector_num % extent->cluster_sectors; + n = extent->cluster_sectors - index_in_cluster; + if (n > nb_sectors) { n = nb_sectors; - cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1); - if (!cluster_offset) - return -1; + } - if (bdrv_pwrite(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512) - return -1; + ret = vmdk_write_extent(extent, + cluster_offset, index_in_cluster * 512, + buf, n, sector_num); + if (ret) { + return ret; + } if (m_data.valid) { /* update L2 tables */ - if (vmdk_L2update(bs, &m_data) == -1) - return -1; + if (vmdk_L2update(extent, &m_data) == -1) { + return -EIO; + } } nb_sectors -= n; sector_num += n; buf += n * 512; - // update CID on the first write every time the virtual disk is opened - if (!cid_update) { - vmdk_write_cid(bs, time(NULL)); - cid_update++; + /* update CID on the first write every time the virtual disk is + * opened */ + if (!s->cid_updated) { + ret = vmdk_write_cid(bs, time(NULL)); + if (ret < 0) { + return ret; + } + s->cid_updated = true; } } return 0; } -static int vmdk_create(const char *filename, QEMUOptionParameter *options) +static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) { - int fd, i; - VMDK4Header header; - uint32_t tmp, magic, grains, gd_size, gt_size, gt_count; - static const char desc_template[] = - "# Disk DescriptorFile\n" - "version=1\n" - "CID=%x\n" - "parentCID=ffffffff\n" - "createType=\"monolithicSparse\"\n" - "\n" - "# Extent description\n" - "RW %" PRId64 " SPARSE \"%s\"\n" - "\n" - "# The Disk Data Base \n" - "#DDB\n" - "\n" - "ddb.virtualHWVersion = \"%d\"\n" - "ddb.geometry.cylinders = \"%" PRId64 "\"\n" - "ddb.geometry.heads = \"16\"\n" - "ddb.geometry.sectors = \"63\"\n" - "ddb.adapterType = \"ide\"\n"; - char desc[1024]; - const char *real_filename, *temp_str; - int64_t total_size = 0; - const char *backing_file = NULL; - int flags = 0; int ret; + BDRVVmdkState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = vmdk_write(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} - // Read out options - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - total_size = options->value.n / 512; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { - backing_file = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) { - flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0; - } - options++; - } - /* XXX: add support for backing file */ - if (backing_file) { - return vmdk_snapshot_create(filename, backing_file); - } +static int vmdk_create_extent(const char *filename, int64_t filesize, + bool flat, bool compress) +{ + int ret, i; + int fd = 0; + VMDK4Header header; + uint32_t tmp, magic, grains, gd_size, gt_size, gt_count; - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, - 0644); - if (fd < 0) + fd = open( + filename, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, + 0644); + if (fd < 0) { return -errno; + } + if (flat) { + ret = ftruncate(fd, filesize); + if (ret < 0) { + ret = -errno; + } + goto exit; + } magic = cpu_to_be32(VMDK4_MAGIC); memset(&header, 0, sizeof(header)); - header.version = cpu_to_le32(1); - header.flags = cpu_to_le32(3); /* ?? */ - header.capacity = cpu_to_le64(total_size); - header.granularity = cpu_to_le64(128); - header.num_gtes_per_gte = cpu_to_le32(512); - - grains = (total_size + header.granularity - 1) / header.granularity; + header.version = 1; + header.flags = + 3 | (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0); + header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0; + header.capacity = filesize / 512; + header.granularity = 128; + header.num_gtes_per_gte = 512; + + grains = (filesize / 512 + header.granularity - 1) / header.granularity; gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9; - gt_count = (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte; + gt_count = + (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte; gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9; header.desc_offset = 1; @@ -735,12 +1197,18 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) ((header.gd_offset + gd_size + (gt_size * gt_count) + header.granularity - 1) / header.granularity) * header.granularity; - + /* swap endianness for all header fields */ + header.version = cpu_to_le32(header.version); + header.flags = cpu_to_le32(header.flags); + header.capacity = cpu_to_le64(header.capacity); + header.granularity = cpu_to_le64(header.granularity); + header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte); header.desc_offset = cpu_to_le64(header.desc_offset); header.desc_size = cpu_to_le64(header.desc_size); header.rgd_offset = cpu_to_le64(header.rgd_offset); header.gd_offset = cpu_to_le64(header.gd_offset); header.grain_offset = cpu_to_le64(header.grain_offset); + header.compressAlgorithm = cpu_to_le16(header.compressAlgorithm); header.check_bytes[0] = 0xa; header.check_bytes[1] = 0x20; @@ -759,7 +1227,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) goto exit; } - ret = ftruncate(fd, header.grain_offset << 9); + ret = ftruncate(fd, le64_to_cpu(header.grain_offset) << 9); if (ret < 0) { ret = -errno; goto exit; @@ -767,7 +1235,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) /* write grain directory */ lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET); - for (i = 0, tmp = header.rgd_offset + gd_size; + for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_size; i < gt_count; i++, tmp += gt_size) { ret = qemu_write_full(fd, &tmp, sizeof(tmp)); if (ret != sizeof(tmp)) { @@ -778,7 +1246,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) /* write backup grain directory */ lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET); - for (i = 0, tmp = header.gd_offset + gd_size; + for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_size; i < gt_count; i++, tmp += gt_size) { ret = qemu_write_full(fd, &tmp, sizeof(tmp)); if (ret != sizeof(tmp)) { @@ -787,27 +1255,256 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) } } - /* compose the descriptor */ - real_filename = filename; - if ((temp_str = strrchr(real_filename, '\\')) != NULL) - real_filename = temp_str + 1; - if ((temp_str = strrchr(real_filename, '/')) != NULL) - real_filename = temp_str + 1; - if ((temp_str = strrchr(real_filename, ':')) != NULL) - real_filename = temp_str + 1; - snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL), - total_size, real_filename, - (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), - total_size / (int64_t)(63 * 16)); + ret = 0; + exit: + close(fd); + return ret; +} + +static int filename_decompose(const char *filename, char *path, char *prefix, + char *postfix, size_t buf_len) +{ + const char *p, *q; - /* write the descriptor */ - lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET); + if (filename == NULL || !strlen(filename)) { + fprintf(stderr, "Vmdk: no filename provided.\n"); + return -1; + } + p = strrchr(filename, '/'); + if (p == NULL) { + p = strrchr(filename, '\\'); + } + if (p == NULL) { + p = strrchr(filename, ':'); + } + if (p != NULL) { + p++; + if (p - filename >= buf_len) { + return -1; + } + pstrcpy(path, p - filename + 1, filename); + } else { + p = filename; + path[0] = '\0'; + } + q = strrchr(p, '.'); + if (q == NULL) { + pstrcpy(prefix, buf_len, p); + postfix[0] = '\0'; + } else { + if (q - p >= buf_len) { + return -1; + } + pstrcpy(prefix, q - p + 1, p); + pstrcpy(postfix, buf_len, q); + } + return 0; +} + +static int relative_path(char *dest, int dest_size, + const char *base, const char *target) +{ + int i = 0; + int n = 0; + const char *p, *q; +#ifdef _WIN32 + const char *sep = "\\"; +#else + const char *sep = "/"; +#endif + + if (!(dest && base && target)) { + return -1; + } + if (path_is_absolute(target)) { + dest[dest_size - 1] = '\0'; + strncpy(dest, target, dest_size - 1); + return 0; + } + while (base[i] == target[i]) { + i++; + } + p = &base[i]; + q = &target[i]; + while (*p) { + if (*p == *sep) { + n++; + } + p++; + } + dest[0] = '\0'; + for (; n; n--) { + pstrcat(dest, dest_size, ".."); + pstrcat(dest, dest_size, sep); + } + pstrcat(dest, dest_size, q); + return 0; +} + +static int vmdk_create(const char *filename, QEMUOptionParameter *options) +{ + int fd, idx = 0; + char desc[BUF_SIZE]; + int64_t total_size = 0, filesize; + const char *backing_file = NULL; + const char *fmt = NULL; + int flags = 0; + int ret = 0; + bool flat, split, compress; + char ext_desc_lines[BUF_SIZE] = ""; + char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX]; + const int64_t split_size = 0x80000000; /* VMDK has constant split size */ + const char *desc_extent_line; + char parent_desc_line[BUF_SIZE] = ""; + uint32_t parent_cid = 0xffffffff; + const char desc_template[] = + "# Disk DescriptorFile\n" + "version=1\n" + "CID=%x\n" + "parentCID=%x\n" + "createType=\"%s\"\n" + "%s" + "\n" + "# Extent description\n" + "%s" + "\n" + "# The Disk Data Base\n" + "#DDB\n" + "\n" + "ddb.virtualHWVersion = \"%d\"\n" + "ddb.geometry.cylinders = \"%" PRId64 "\"\n" + "ddb.geometry.heads = \"16\"\n" + "ddb.geometry.sectors = \"63\"\n" + "ddb.adapterType = \"ide\"\n"; + + if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) { + return -EINVAL; + } + /* Read out options */ + while (options && options->name) { + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { + total_size = options->value.n; + } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { + backing_file = options->value.s; + } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) { + flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0; + } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) { + fmt = options->value.s; + } + options++; + } + if (!fmt) { + /* Default format to monolithicSparse */ + fmt = "monolithicSparse"; + } else if (strcmp(fmt, "monolithicFlat") && + strcmp(fmt, "monolithicSparse") && + strcmp(fmt, "twoGbMaxExtentSparse") && + strcmp(fmt, "twoGbMaxExtentFlat") && + strcmp(fmt, "streamOptimized")) { + fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt); + return -EINVAL; + } + split = !(strcmp(fmt, "twoGbMaxExtentFlat") && + strcmp(fmt, "twoGbMaxExtentSparse")); + flat = !(strcmp(fmt, "monolithicFlat") && + strcmp(fmt, "twoGbMaxExtentFlat")); + compress = !strcmp(fmt, "streamOptimized"); + if (flat) { + desc_extent_line = "RW %lld FLAT \"%s\" 0\n"; + } else { + desc_extent_line = "RW %lld SPARSE \"%s\"\n"; + } + if (flat && backing_file) { + /* not supporting backing file for flat image */ + return -ENOTSUP; + } + if (backing_file) { + char parent_filename[PATH_MAX]; + BlockDriverState *bs = bdrv_new(""); + ret = bdrv_open(bs, backing_file, 0, NULL); + if (ret != 0) { + bdrv_delete(bs); + return ret; + } + if (strcmp(bs->drv->format_name, "vmdk")) { + bdrv_delete(bs); + return -EINVAL; + } + parent_cid = vmdk_read_cid(bs, 0); + bdrv_delete(bs); + relative_path(parent_filename, sizeof(parent_filename), + filename, backing_file); + snprintf(parent_desc_line, sizeof(parent_desc_line), + "parentFileNameHint=\"%s\"", parent_filename); + } + + /* Create extents */ + filesize = total_size; + while (filesize > 0) { + char desc_line[BUF_SIZE]; + char ext_filename[PATH_MAX]; + char desc_filename[PATH_MAX]; + int64_t size = filesize; + + if (split && size > split_size) { + size = split_size; + } + if (split) { + snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s", + prefix, flat ? 'f' : 's', ++idx, postfix); + } else if (flat) { + snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s", + prefix, postfix); + } else { + snprintf(desc_filename, sizeof(desc_filename), "%s%s", + prefix, postfix); + } + snprintf(ext_filename, sizeof(ext_filename), "%s%s", + path, desc_filename); + + if (vmdk_create_extent(ext_filename, size, flat, compress)) { + return -EINVAL; + } + filesize -= size; + + /* Format description line */ + snprintf(desc_line, sizeof(desc_line), + desc_extent_line, size / 512, desc_filename); + pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line); + } + /* generate descriptor file */ + snprintf(desc, sizeof(desc), desc_template, + (unsigned int)time(NULL), + parent_cid, + fmt, + parent_desc_line, + ext_desc_lines, + (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4), + total_size / (int64_t)(63 * 16 * 512)); + if (split || flat) { + fd = open( + filename, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, + 0644); + } else { + fd = open( + filename, + O_WRONLY | O_BINARY | O_LARGEFILE, + 0644); + } + if (fd < 0) { + return -errno; + } + /* the descriptor offset = 0x200 */ + if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) { + ret = -errno; + goto exit; + } ret = qemu_write_full(fd, desc, strlen(desc)); if (ret != strlen(desc)) { ret = -errno; goto exit; } - ret = 0; exit: close(fd); @@ -818,15 +1515,50 @@ static void vmdk_close(BlockDriverState *bs) { BDRVVmdkState *s = bs->opaque; - qemu_free(s->l1_table); - qemu_free(s->l2_cache); + vmdk_free_extents(bs); + + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } -static int vmdk_flush(BlockDriverState *bs) +static coroutine_fn int vmdk_co_flush(BlockDriverState *bs) { - return bdrv_flush(bs->file); + int i, ret, err; + BDRVVmdkState *s = bs->opaque; + + ret = bdrv_co_flush(bs->file); + for (i = 0; i < s->num_extents; i++) { + err = bdrv_co_flush(s->extents[i].file); + if (err < 0) { + ret = err; + } + } + return ret; } +static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs) +{ + int i; + int64_t ret = 0; + int64_t r; + BDRVVmdkState *s = bs->opaque; + + ret = bdrv_get_allocated_file_size(bs->file); + if (ret < 0) { + return ret; + } + for (i = 0; i < s->num_extents; i++) { + if (s->extents[i].file == bs->file) { + continue; + } + r = bdrv_get_allocated_file_size(s->extents[i].file); + if (r < 0) { + return r; + } + ret += r; + } + return ret; +} static QEMUOptionParameter vmdk_create_options[] = { { @@ -844,20 +1576,28 @@ static QEMUOptionParameter vmdk_create_options[] = { .type = OPT_FLAG, .help = "VMDK version 6 image" }, + { + .name = BLOCK_OPT_SUBFMT, + .type = OPT_STRING, + .help = + "VMDK flat extent format, can be one of " + "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} " + }, { NULL } }; static BlockDriver bdrv_vmdk = { - .format_name = "vmdk", - .instance_size = sizeof(BDRVVmdkState), - .bdrv_probe = vmdk_probe, + .format_name = "vmdk", + .instance_size = sizeof(BDRVVmdkState), + .bdrv_probe = vmdk_probe, .bdrv_open = vmdk_open, - .bdrv_read = vmdk_read, - .bdrv_write = vmdk_write, - .bdrv_close = vmdk_close, - .bdrv_create = vmdk_create, - .bdrv_flush = vmdk_flush, - .bdrv_is_allocated = vmdk_is_allocated, + .bdrv_read = vmdk_co_read, + .bdrv_write = vmdk_co_write, + .bdrv_close = vmdk_close, + .bdrv_create = vmdk_create, + .bdrv_co_flush_to_disk = vmdk_co_flush, + .bdrv_is_allocated = vmdk_is_allocated, + .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size, .create_options = vmdk_create_options, }; diff --git a/block/vpc.c b/block/vpc.c index 7b025be..89a5ee2 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -25,6 +25,7 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" /**************************************************************/ @@ -110,6 +111,7 @@ struct vhd_dyndisk_header { }; typedef struct BDRVVPCState { + CoMutex lock; uint8_t footer_buf[HEADER_SIZE]; uint64_t free_data_block_offset; int max_table_entries; @@ -127,6 +129,8 @@ typedef struct BDRVVPCState { uint64_t last_bitmap; #endif + + Error *migration_blocker; } BDRVVPCState; static uint32_t vpc_checksum(uint8_t* buf, size_t size) @@ -156,6 +160,7 @@ static int vpc_open(BlockDriverState *bs, int flags) struct vhd_dyndisk_header* dyndisk_header; uint8_t buf[HEADER_SIZE]; uint32_t checksum; + int err = -1; if (bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE) != HEADER_SIZE) goto fail; @@ -176,6 +181,11 @@ static int vpc_open(BlockDriverState *bs, int flags) bs->total_sectors = (int64_t) be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl; + if (bs->total_sectors >= 65535 * 16 * 255) { + err = -EFBIG; + goto fail; + } + if (bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf, HEADER_SIZE) != HEADER_SIZE) goto fail; @@ -190,7 +200,7 @@ static int vpc_open(BlockDriverState *bs, int flags) s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511; s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries); - s->pagetable = qemu_malloc(s->max_table_entries * 4); + s->pagetable = g_malloc(s->max_table_entries * 4); s->bat_offset = be64_to_cpu(dyndisk_header->table_offset); if (bdrv_pread(bs->file, s->bat_offset, s->pagetable, @@ -214,15 +224,23 @@ static int vpc_open(BlockDriverState *bs, int flags) s->last_bitmap_offset = (int64_t) -1; #ifdef CACHE - s->pageentry_u8 = qemu_malloc(512); + s->pageentry_u8 = g_malloc(512); s->pageentry_u32 = s->pageentry_u8; s->pageentry_u16 = s->pageentry_u8; s->last_pagetable = -1; #endif + qemu_co_mutex_init(&s->lock); + + /* Disable migration when VHD images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vpc", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + return 0; fail: - return -1; + return err; } /* @@ -344,8 +362,11 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num) // Initialize the block's bitmap memset(bitmap, 0xff, s->bitmap_size); - bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap, + ret = bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap, s->bitmap_size); + if (ret < 0) { + return ret; + } // Write new footer (the old one will be overwritten) s->free_data_block_offset += s->block_size + s->bitmap_size; @@ -401,6 +422,17 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num, return 0; } +static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVVPCState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = vpc_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static int vpc_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { @@ -437,9 +469,20 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num, return 0; } -static int vpc_flush(BlockDriverState *bs) +static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) { - return bdrv_flush(bs->file); + int ret; + BDRVVPCState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = vpc_write(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + +static coroutine_fn int vpc_co_flush(BlockDriverState *bs) +{ + return bdrv_co_flush(bs->file); } /* @@ -505,12 +548,8 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options) int ret = -EIO; // Read out options - while (options && options->name) { - if (!strcmp(options->name, "size")) { - total_sectors = options->value.n / 512; - } - options++; - } + total_sectors = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n / + BDRV_SECTOR_SIZE; // Create the file fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); @@ -591,7 +630,11 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options) memcpy(dyndisk_header->magic, "cxsparse", 8); - dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFF); + /* + * Note: The spec is actually wrong here for data_offset, it says + * 0xFFFFFFFF, but MS tools expect all 64 bits to be set. + */ + dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL); dyndisk_header->table_offset = be64_to_cpu(3 * 512); dyndisk_header->version = be32_to_cpu(0x00010000); dyndisk_header->block_size = be32_to_cpu(block_size); @@ -617,10 +660,13 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options) static void vpc_close(BlockDriverState *bs) { BDRVVPCState *s = bs->opaque; - qemu_free(s->pagetable); + g_free(s->pagetable); #ifdef CACHE - qemu_free(s->pageentry_u8); + g_free(s->pageentry_u8); #endif + + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } static QEMUOptionParameter vpc_create_options[] = { @@ -635,14 +681,16 @@ static QEMUOptionParameter vpc_create_options[] = { static BlockDriver bdrv_vpc = { .format_name = "vpc", .instance_size = sizeof(BDRVVPCState), + .bdrv_probe = vpc_probe, .bdrv_open = vpc_open, - .bdrv_read = vpc_read, - .bdrv_write = vpc_write, - .bdrv_flush = vpc_flush, .bdrv_close = vpc_close, .bdrv_create = vpc_create, + .bdrv_read = vpc_co_read, + .bdrv_write = vpc_co_write, + .bdrv_co_flush_to_disk = vpc_co_flush, + .create_options = vpc_create_options, }; diff --git a/block/vvfat.c b/block/vvfat.c index fe568fe..a310ce8 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -27,6 +27,7 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" #ifndef S_IWGRP #define S_IWGRP 0 @@ -86,8 +87,7 @@ static inline void array_init(array_t* array,unsigned int item_size) static inline void array_free(array_t* array) { - if(array->pointer) - free(array->pointer); + g_free(array->pointer); array->size=array->next=0; } @@ -101,7 +101,7 @@ static inline int array_ensure_allocated(array_t* array, int index) { if((index + 1) * array->item_size > array->size) { int new_size = (index + 32) * array->item_size; - array->pointer = qemu_realloc(array->pointer, new_size); + array->pointer = g_realloc(array->pointer, new_size); if (!array->pointer) return -1; array->size = new_size; @@ -127,7 +127,7 @@ static inline void* array_get_next(array_t* array) { static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) { if((array->next+count)*array->item_size>array->size) { int increment=count*array->item_size; - array->pointer=qemu_realloc(array->pointer,array->size+increment); + array->pointer=g_realloc(array->pointer,array->size+increment); if(!array->pointer) return NULL; array->size+=increment; @@ -159,7 +159,7 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun is=array->item_size; from=array->pointer+index_from*is; to=array->pointer+index_to*is; - buf=qemu_malloc(is*count); + buf=g_malloc(is*count); memcpy(buf,from,is*count); if(index_tod_name); if(stat(buffer,&st)<0) { - free(buffer); + g_free(buffer); continue; } @@ -755,7 +758,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) direntry->begin=0; /* do that later */ if (st.st_size > 0x7fffffff) { fprintf(stderr, "File %s is larger than 2GB\n", buffer); - free(buffer); + g_free(buffer); closedir(dir); return -2; } @@ -799,6 +802,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index) /* root directory */ int cur = s->directory.next; array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1); + s->directory.next = ROOT_ENTRIES; memset(array_get(&(s->directory), cur), 0, (ROOT_ENTRIES - cur) * sizeof(direntry_t)); } @@ -825,20 +829,6 @@ static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num) return s->faked_sectors + s->sectors_per_cluster * cluster_num; } -static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num) -{ - return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster; -} - -#ifdef DBG -static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping) -{ - if(mapping->mode==MODE_UNDEFINED) - return 0; - return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index); -} -#endif - static int init_directories(BDRVVVFATState* s, const char* dirname) { @@ -850,7 +840,7 @@ static int init_directories(BDRVVVFATState* s, memset(&(s->first_sectors[0]),0,0x40*0x200); s->cluster_size=s->sectors_per_cluster*0x200; - s->cluster_buffer=qemu_malloc(s->cluster_size); + s->cluster_buffer=g_malloc(s->cluster_size); /* * The formula: sc = spf+1+spf*spc*(512*8/fat_type), @@ -884,7 +874,7 @@ static int init_directories(BDRVVVFATState* s, mapping->dir_index = 0; mapping->info.dir.parent_mapping_index = -1; mapping->first_mapping_index = -1; - mapping->path = qemu_strdup(dirname); + mapping->path = g_strdup(dirname); i = strlen(mapping->path); if (i > 0 && mapping->path[i - 1] == '/') mapping->path[i - 1] = '\0'; @@ -929,11 +919,8 @@ static int init_directories(BDRVVVFATState* s, cluster = mapping->end; if(cluster > s->cluster_count) { - fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n", - s->fat_type, - s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB" - : "2.88 MB" - : "504MB"); + fprintf(stderr,"Directory does not fit in FAT%d (capacity %.2f MB)\n", + s->fat_type, s->sector_count / 2000.0); return -EINVAL; } @@ -967,7 +954,7 @@ static int init_directories(BDRVVVFATState* s, bootsector->number_of_fats=0x2; /* number of FATs */ bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10); bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count); - bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */ + bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/ s->fat.pointer[0] = bootsector->media_type; bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat); bootsector->sectors_per_track=cpu_to_le16(s->bs->secs); @@ -976,7 +963,7 @@ static int init_directories(BDRVVVFATState* s, bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0); /* LATER TODO: if FAT32, this is wrong */ - bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */ + bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */ bootsector->u.fat16.current_head=0; bootsector->u.fat16.signature=0x29; bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd); @@ -998,7 +985,6 @@ static int is_consistent(BDRVVVFATState *s); static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags) { BDRVVVFATState *s = bs->opaque; - int floppy = 0; int i; #ifdef DEBUG @@ -1012,11 +998,8 @@ DLOG(if (stderr == NULL) { s->bs = bs; - s->fat_type=16; /* LATER TODO: if FAT32, adjust */ s->sectors_per_cluster=0x10; - /* 504MB disk*/ - bs->cyls=1024; bs->heads=16; bs->secs=63; s->current_cluster=0xffffffff; @@ -1031,16 +1014,6 @@ DLOG(if (stderr == NULL) { if (!strstart(dirname, "fat:", NULL)) return -1; - if (strstr(dirname, ":floppy:")) { - floppy = 1; - s->fat_type = 12; - s->first_sectors_number = 1; - s->sectors_per_cluster=2; - bs->cyls = 80; bs->heads = 2; bs->secs = 36; - } - - s->sector_count=bs->cyls*bs->heads*bs->secs; - if (strstr(dirname, ":32:")) { fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n"); s->fat_type = 32; @@ -1048,9 +1021,31 @@ DLOG(if (stderr == NULL) { s->fat_type = 16; } else if (strstr(dirname, ":12:")) { s->fat_type = 12; - s->sector_count=2880; } + if (strstr(dirname, ":floppy:")) { + /* 1.44MB or 2.88MB floppy. 2.88MB can be FAT12 (default) or FAT16. */ + if (!s->fat_type) { + s->fat_type = 12; + bs->secs = 36; + s->sectors_per_cluster=2; + } else { + bs->secs=(s->fat_type == 12 ? 18 : 36); + s->sectors_per_cluster=1; + } + s->first_sectors_number = 1; + bs->cyls=80; bs->heads=2; + } else { + /* 32MB or 504MB disk*/ + if (!s->fat_type) { + s->fat_type = 16; + } + bs->cyls=(s->fat_type == 12 ? 64 : 1024); + bs->heads=16; bs->secs=63; + } + + s->sector_count=bs->cyls*bs->heads*bs->secs-(s->first_sectors_number-1); + if (strstr(dirname, ":rw:")) { if (enable_write_target(s)) return -1; @@ -1074,12 +1069,22 @@ DLOG(if (stderr == NULL) { if(s->first_sectors_number==0x40) init_mbr(s); - - /* for some reason or other, MS-DOS does not like to know about CHS... */ - if (floppy) + else { + /* MS-DOS does not like to know about CHS (?). */ bs->heads = bs->cyls = bs->secs = 0; + } // assert(is_consistent(s)); + qemu_co_mutex_init(&s->lock); + + /* Disable migration when vvfat is used rw */ + if (s->qcow) { + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vvfat (rw)", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + } + return 0; } @@ -1138,25 +1143,6 @@ static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_ return mapping; } -/* - * This function simply compares path == mapping->path. Since the mappings - * are sorted by cluster, this is expensive: O(n). - */ -static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s, - const char* path) -{ - int i; - - for (i = 0; i < s->mapping.next; i++) { - mapping_t* mapping = array_get(&(s->mapping), i); - if (mapping->first_mapping_index < 0 && - !strcmp(path, mapping->path)) - return mapping; - } - - return NULL; -} - static int open_file(BDRVVVFATState* s,mapping_t* mapping) { if(!mapping) @@ -1223,23 +1209,6 @@ read_cluster_directory: } #ifdef DEBUG -static void hexdump(const void* address, uint32_t len) -{ - const unsigned char* p = address; - int i, j; - - for (i = 0; i < len; i += 16) { - for (j = 0; j < 16 && i + j < len; j++) - fprintf(stderr, "%02x ", p[i + j]); - for (; j < 16; j++) - fprintf(stderr, " "); - fprintf(stderr, " "); - for (j = 0; j < 16 && i + j < len; j++) - fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]); - fprintf(stderr, "\n"); - } -} - static void print_direntry(const direntry_t* direntry) { int j = 0; @@ -1293,19 +1262,19 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num, int i; for(i=0;i= s->sector_count) + if (sector_num >= bs->total_sectors) return -1; if (s->qcow) { int n; - if (s->qcow->drv->bdrv_is_allocated(s->qcow, - sector_num, nb_sectors-i, &n)) { + if (bdrv_is_allocated(s->qcow, sector_num, nb_sectors-i, &n)) { DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n)); - if (s->qcow->drv->bdrv_read(s->qcow, sector_num, buf+i*0x200, n)) - return -1; - i += n - 1; - sector_num += n - 1; - continue; - } + if (bdrv_read(s->qcow, sector_num, buf + i*0x200, n)) { + return -1; + } + i += n - 1; + sector_num += n - 1; + continue; + } DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num)); } if(sector_numfaked_sectors) { @@ -1319,7 +1288,7 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num)); uint32_t sector=sector_num-s->faked_sectors, sector_offset_in_cluster=(sector%s->sectors_per_cluster), cluster_num=sector/s->sectors_per_cluster; - if(read_cluster(s, cluster_num) != 0) { + if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) { /* LATER TODO: strict: return -1; */ memset(buf+i*0x200,0,0x200); continue; @@ -1330,6 +1299,17 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num)); return 0; } +static coroutine_fn int vvfat_co_read(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVVVFATState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = vvfat_read(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + /* LATER TODO: statify all functions */ /* @@ -1375,7 +1355,7 @@ DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next)); assert(commit->path || commit->action == ACTION_WRITEOUT); if (commit->action != ACTION_WRITEOUT) { assert(commit->path); - free(commit->path); + g_free(commit->path); } else assert(commit->path == NULL); } @@ -1548,7 +1528,7 @@ static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num) return 0; for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) - was_modified = s->qcow->drv->bdrv_is_allocated(s->qcow, + was_modified = bdrv_is_allocated(s->qcow, cluster2sector(s, cluster_num) + i, 1, &dummy); return was_modified; @@ -1638,10 +1618,10 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s, /* rename */ if (strcmp(basename, basename2)) - schedule_rename(s, cluster_num, qemu_strdup(path)); + schedule_rename(s, cluster_num, g_strdup(path)); } else if (is_file(direntry)) /* new file */ - schedule_new_file(s, qemu_strdup(path), cluster_num); + schedule_new_file(s, g_strdup(path), cluster_num); else { abort(); return 0; @@ -1697,16 +1677,16 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s, int64_t offset = cluster2sector(s, cluster_num); vvfat_close_current_file(s); - for (i = 0; i < s->sectors_per_cluster; i++) - if (!s->qcow->drv->bdrv_is_allocated(s->qcow, - offset + i, 1, &dummy)) { - if (vvfat_read(s->bs, - offset, s->cluster_buffer, 1)) - return -1; - if (s->qcow->drv->bdrv_write(s->qcow, - offset, s->cluster_buffer, 1)) - return -2; - } + for (i = 0; i < s->sectors_per_cluster; i++) { + if (!bdrv_is_allocated(s->qcow, offset + i, 1, &dummy)) { + if (vvfat_read(s->bs, offset, s->cluster_buffer, 1)) { + return -1; + } + if (bdrv_write(s->qcow, offset, s->cluster_buffer, 1)) { + return -2; + } + } + } } } @@ -1735,13 +1715,13 @@ static int check_directory_consistency(BDRVVVFATState *s, int cluster_num, const char* path) { int ret = 0; - unsigned char* cluster = qemu_malloc(s->cluster_size); + unsigned char* cluster = g_malloc(s->cluster_size); direntry_t* direntries = (direntry_t*)cluster; mapping_t* mapping = find_mapping_for_cluster(s, cluster_num); long_file_name lfn; int path_len = strlen(path); - char path2[PATH_MAX]; + char path2[PATH_MAX + 1]; assert(path_len < PATH_MAX); /* len was tested before! */ pstrcpy(path2, sizeof(path2), path); @@ -1758,10 +1738,10 @@ static int check_directory_consistency(BDRVVVFATState *s, mapping->mode &= ~MODE_DELETED; if (strcmp(basename, basename2)) - schedule_rename(s, cluster_num, qemu_strdup(path)); + schedule_rename(s, cluster_num, g_strdup(path)); } else /* new directory */ - schedule_mkdir(s, cluster_num, qemu_strdup(path)); + schedule_mkdir(s, cluster_num, g_strdup(path)); lfn_init(&lfn); do { @@ -1782,14 +1762,14 @@ DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)clu if (subret) { fprintf(stderr, "Error fetching direntries\n"); fail: - free(cluster); + g_free(cluster); return 0; } for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) { int cluster_count = 0; -DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i)); +DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i)); if (is_volume_label(direntries + i) || is_dot(direntries + i) || is_free(direntries + i)) continue; @@ -1850,7 +1830,7 @@ DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i) cluster_num = modified_fat_get(s, cluster_num); } while(!fat_eof(s, cluster_num)); - free(cluster); + g_free(cluster); return ret; } @@ -1876,7 +1856,7 @@ DLOG(checkpoint()); */ if (s->fat2 == NULL) { int size = 0x200 * s->sectors_per_fat; - s->fat2 = qemu_malloc(size); + s->fat2 = g_malloc(size); memcpy(s->fat2, s->fat.pointer, size); } check = vvfat_read(s->bs, @@ -1995,8 +1975,9 @@ static int remove_mapping(BDRVVVFATState* s, int mapping_index) mapping_t* first_mapping = array_get(&(s->mapping), 0); /* free mapping */ - if (mapping->first_mapping_index < 0) - free(mapping->path); + if (mapping->first_mapping_index < 0) { + g_free(mapping->path); + } /* remove from s->mapping */ array_remove(&(s->mapping), mapping_index); @@ -2218,7 +2199,7 @@ static int commit_one_file(BDRVVVFATState* s, uint32_t first_cluster = c; mapping_t* mapping = find_mapping_for_cluster(s, c); uint32_t size = filesize_of_direntry(direntry); - char* cluster = qemu_malloc(s->cluster_size); + char* cluster = g_malloc(s->cluster_size); uint32_t i; int fd = 0; @@ -2232,11 +2213,15 @@ static int commit_one_file(BDRVVVFATState* s, if (fd < 0) { fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path, strerror(errno), errno); + g_free(cluster); return fd; } - if (offset > 0) - if (lseek(fd, offset, SEEK_SET) != offset) - return -3; + if (offset > 0) { + if (lseek(fd, offset, SEEK_SET) != offset) { + g_free(cluster); + return -3; + } + } while (offset < size) { uint32_t c1; @@ -2252,11 +2237,15 @@ static int commit_one_file(BDRVVVFATState* s, ret = vvfat_read(s->bs, cluster2sector(s, c), (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200); - if (ret < 0) - return ret; + if (ret < 0) { + g_free(cluster); + return ret; + } - if (write(fd, cluster, rest_size) < 0) - return -2; + if (write(fd, cluster, rest_size) < 0) { + g_free(cluster); + return -2; + } offset += rest_size; c = c1; @@ -2265,9 +2254,11 @@ static int commit_one_file(BDRVVVFATState* s, if (ftruncate(fd, size)) { perror("ftruncate()"); close(fd); + g_free(cluster); return -4; } close(fd); + g_free(cluster); return commit_mappings(s, first_cluster, dir_index); } @@ -2383,7 +2374,7 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s) mapping_t* m = find_mapping_for_cluster(s, begin_of_direntry(d)); int l = strlen(m->path); - char* new_path = qemu_malloc(l + diff + 1); + char* new_path = g_malloc(l + diff + 1); assert(!strncmp(m->path, mapping->path, l2)); @@ -2399,7 +2390,7 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s) } } - free(old_path); + g_free(old_path); array_remove(&(s->commits), i); continue; } else if (commit->action == ACTION_MKDIR) { @@ -2640,7 +2631,9 @@ static int do_commit(BDRVVVFATState* s) return ret; } - s->qcow->drv->bdrv_make_empty(s->qcow); + if (s->qcow->drv->bdrv_make_empty) { + s->qcow->drv->bdrv_make_empty(s->qcow); + } memset(s->used_clusters, 0, sector2cluster(s, s->sector_count)); @@ -2735,7 +2728,7 @@ DLOG(checkpoint()); * Use qcow backend. Commit later. */ DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors)); - ret = s->qcow->drv->bdrv_write(s->qcow, sector_num, buf, nb_sectors); + ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors); if (ret < 0) { fprintf(stderr, "Error writing to qcow backend\n"); return ret; @@ -2754,6 +2747,17 @@ DLOG(checkpoint()); return 0; } +static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors) +{ + int ret; + BDRVVVFATState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = vvfat_write(bs, sector_num, buf, nb_sectors); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + static int vvfat_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int* n) { @@ -2775,7 +2779,7 @@ static int write_target_commit(BlockDriverState *bs, int64_t sector_num, static void write_target_close(BlockDriverState *bs) { BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque); bdrv_delete(s->qcow); - free(s->qcow_filename); + g_free(s->qcow_filename); } static BlockDriver vvfat_write_target = { @@ -2794,7 +2798,7 @@ static int enable_write_target(BDRVVVFATState *s) array_init(&(s->commits), sizeof(commit_t)); - s->qcow_filename = qemu_malloc(1024); + s->qcow_filename = g_malloc(1024); get_tmp_filename(s->qcow_filename, 1024); bdrv_qcow = bdrv_find_format("qcow"); @@ -2822,7 +2826,7 @@ static int enable_write_target(BDRVVVFATState *s) s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1); s->bs->backing_hd->drv = &vvfat_write_target; - s->bs->backing_hd->opaque = qemu_malloc(sizeof(void*)); + s->bs->backing_hd->opaque = g_malloc(sizeof(void*)); *(void**)s->bs->backing_hd->opaque = s; return 0; @@ -2836,16 +2840,20 @@ static void vvfat_close(BlockDriverState *bs) array_free(&(s->fat)); array_free(&(s->directory)); array_free(&(s->mapping)); - if(s->cluster_buffer) - free(s->cluster_buffer); + g_free(s->cluster_buffer); + + if (s->qcow) { + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); + } } static BlockDriver bdrv_vvfat = { .format_name = "vvfat", .instance_size = sizeof(BDRVVVFATState), .bdrv_file_open = vvfat_open, - .bdrv_read = vvfat_read, - .bdrv_write = vvfat_write, + .bdrv_read = vvfat_co_read, + .bdrv_write = vvfat_co_write, .bdrv_close = vvfat_close, .bdrv_is_allocated = vvfat_is_allocated, .protocol_name = "fat", @@ -2878,11 +2886,5 @@ static void checkpoint(void) { direntry = array_get(&(vvv->directory), mapping->dir_index); assert(!memcmp(direntry->name, "USB H ", 11) || direntry->name[0]==0); #endif - return; - /* avoid compiler warnings: */ - hexdump(NULL, 100); - remove_mapping(vvv, 0); - print_mapping(NULL); - print_direntry(NULL); } #endif diff --git a/block_int.h b/block_int.h index 545ad11..77c0187 100644 --- a/block_int.h +++ b/block_int.h @@ -27,6 +27,9 @@ #include "block.h" #include "qemu-option.h" #include "qemu-queue.h" +#include "qemu-coroutine.h" +#include "qemu-timer.h" +#include "qapi-types.h" #define BLOCK_FLAG_ENCRYPT 1 #define BLOCK_FLAG_COMPAT6 4 @@ -39,6 +42,7 @@ #define BLOCK_OPT_CLUSTER_SIZE "cluster_size" #define BLOCK_OPT_TABLE_SIZE "table_size" #define BLOCK_OPT_PREALLOC "preallocation" +#define BLOCK_OPT_SUBFMT "subformat" typedef struct AIOPool { void (*cancel)(BlockDriverAIOCB *acb); @@ -59,7 +63,6 @@ struct BlockDriver { const uint8_t *buf, int nb_sectors); void (*bdrv_close)(BlockDriverState *bs); int (*bdrv_create)(const char *filename, QEMUOptionParameter *options); - int (*bdrv_flush)(BlockDriverState *bs); int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); int (*bdrv_set_key)(BlockDriverState *bs, const char *key); @@ -73,8 +76,34 @@ struct BlockDriver { BlockDriverCompletionFunc *cb, void *opaque); BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); - int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num, - int nb_sectors); + BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); + + int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); + int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); + int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs, + int64_t sector_num, int nb_sectors); + + /* + * Invalidate any cached meta-data. + */ + void (*bdrv_invalidate_cache)(BlockDriverState *bs); + + /* + * Flushes all data that was already written to the OS all the way down to + * the disk (for example raw-posix calls fsync()). + */ + int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs); + + /* + * Flushes all internal caches to the OS. The data may still sit in a + * writeback cache of the host OS, but it will survive a crash of the qemu + * process. + */ + int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs); int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs, int num_reqs); @@ -85,6 +114,7 @@ struct BlockDriver { const char *protocol_name; int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset); int64_t (*bdrv_getlength)(BlockDriverState *bs); + int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs); int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); @@ -110,8 +140,8 @@ struct BlockDriver { /* removable device specific */ int (*bdrv_is_inserted)(BlockDriverState *bs); int (*bdrv_media_changed)(BlockDriverState *bs); - int (*bdrv_eject)(BlockDriverState *bs, int eject_flag); - int (*bdrv_set_locked)(BlockDriverState *bs, int locked); + void (*bdrv_eject)(BlockDriverState *bs, int eject_flag); + void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked); /* to control generic scsi devices */ int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf); @@ -146,27 +176,23 @@ struct BlockDriverState { int read_only; /* if true, the media is read only */ int keep_read_only; /* if true, the media was requested to stay read only */ int open_flags; /* flags used to open the file, re-used for re-open */ - int removable; /* if true, the media can be removed */ - int locked; /* if true, the media cannot temporarily be ejected */ - int tray_open; /* if true, the virtual tray is open */ int encrypted; /* if true, the media is encrypted */ int valid_key; /* if true, a valid encryption key has been set */ int sg; /* if true, the device is a /dev/sg* */ - /* event callback when inserting/removing */ - void (*change_cb)(void *opaque, int reason); - void *change_opaque; BlockDriver *drv; /* NULL means no media */ void *opaque; - DeviceState *peer; + void *dev; /* attached device model, if any */ + /* TODO change to DeviceState when all users are qdevified */ + const BlockDevOps *dev_ops; + void *dev_opaque; char filename[1024]; char backing_file[1024]; /* if non zero, the image is a diff of this file image */ char backing_format[16]; /* if non-zero and backing_file exists */ int is_temporary; - int media_changed; BlockDriverState *backing_hd; BlockDriverState *file; @@ -176,10 +202,9 @@ struct BlockDriverState { void *sync_aiocb; /* I/O stats (display with "info blockstats"). */ - uint64_t rd_bytes; - uint64_t wr_bytes; - uint64_t rd_ops; - uint64_t wr_ops; + uint64_t nr_bytes[BDRV_MAX_IOTYPE]; + uint64_t nr_ops[BDRV_MAX_IOTYPE]; + uint64_t total_time_ns[BDRV_MAX_IOTYPE]; uint64_t wr_highest_sector; /* Whether the disk can expand beyond total_sectors */ @@ -194,8 +219,9 @@ struct BlockDriverState { /* NOTE: the following infos are only hints for real hardware drivers. They are not used by the block driver */ int cyls, heads, secs, translation; - int type; BlockErrorAction on_read_error, on_write_error; + bool iostatus_enabled; + BlockDeviceIoStatus iostatus; char device_name[32]; unsigned long *dirty_bitmap; int64_t dirty_count; @@ -204,9 +230,6 @@ struct BlockDriverState { void *private; }; -#define CHANGE_MEDIA 0x01 -#define CHANGE_SIZE 0x02 - struct BlockDriverAIOCB { AIOPool *pool; BlockDriverState *bs; @@ -221,45 +244,8 @@ void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); void qemu_aio_release(void *p); -void *qemu_blockalign(BlockDriverState *bs, size_t size); - #ifdef _WIN32 int is_windows_drive(const char *filename); #endif -typedef struct BlockConf { - BlockDriverState *bs; - uint16_t physical_block_size; - uint16_t logical_block_size; - uint16_t min_io_size; - uint32_t opt_io_size; - int32_t bootindex; - uint32_t discard_granularity; -} BlockConf; - -static inline unsigned int get_physical_block_exp(BlockConf *conf) -{ - unsigned int exp = 0, size; - - for (size = conf->physical_block_size; - size > conf->logical_block_size; - size >>= 1) { - exp++; - } - - return exp; -} - -#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \ - DEFINE_PROP_DRIVE("drive", _state, _conf.bs), \ - DEFINE_PROP_UINT16("logical_block_size", _state, \ - _conf.logical_block_size, 512), \ - DEFINE_PROP_UINT16("physical_block_size", _state, \ - _conf.physical_block_size, 512), \ - DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \ - DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \ - DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1), \ - DEFINE_PROP_UINT32("discard_granularity", _state, \ - _conf.discard_granularity, 0) - #endif /* BLOCK_INT_H */ diff --git a/blockdev.c b/blockdev.c index 8c96754..98184b3 100644 --- a/blockdev.c +++ b/blockdev.c @@ -14,7 +14,6 @@ #include "qemu-option.h" #include "qemu-config.h" #include "sysemu.h" -#include "hw/qdev.h" #include "block_int.h" static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives); @@ -182,9 +181,9 @@ static void drive_uninit(DriveInfo *dinfo) { qemu_opts_del(dinfo->opts); bdrv_delete(dinfo->bdrv); - qemu_free(dinfo->id); + g_free(dinfo->id); QTAILQ_REMOVE(&drives, dinfo, next); - qemu_free(dinfo); + g_free(dinfo); } void drive_put_ref(DriveInfo *dinfo) @@ -217,6 +216,11 @@ static int parse_block_error_action(const char *buf, int is_read) } } +#ifdef CONFIG_MARU +extern int start_simple_client(char* msg); +extern char* maru_convert_path(char* msg, const char *path); +#endif + DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) { const char *buf; @@ -240,14 +244,6 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) int ret; translation = BIOS_ATA_TRANSLATION_AUTO; - - if (default_to_scsi) { - type = IF_SCSI; - pstrcpy(devname, sizeof(devname), "scsi"); - } else { - type = IF_IDE; - pstrcpy(devname, sizeof(devname), "ide"); - } media = MEDIA_DISK; /* extract parameters */ @@ -273,7 +269,11 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) error_report("unsupported bus type '%s'", buf); return NULL; } + } else { + type = default_to_scsi ? IF_SCSI : IF_IDE; + pstrcpy(devname, sizeof(devname), if_name[type]); } + max_devs = if_max_devs[type]; if (cyls || heads || secs) { @@ -293,7 +293,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) if ((buf = qemu_opt_get(opts, "trans")) != NULL) { if (!cyls) { - error_report("'%s' trans must be used with cyls,heads and secs", + error_report("'%s' trans must be used with cyls, heads and secs", buf); return NULL; } @@ -314,7 +314,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) media = MEDIA_DISK; } else if (!strcmp(buf, "cdrom")) { if (cyls || secs || heads) { - error_report("'%s' invalid physical CHS format", buf); + error_report("CHS can't be set with media=%s", buf); return NULL; } media = MEDIA_CDROM; @@ -325,18 +325,9 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) } if ((buf = qemu_opt_get(opts, "cache")) != NULL) { - if (!strcmp(buf, "off") || !strcmp(buf, "none")) { - bdrv_flags |= BDRV_O_NOCACHE; - } else if (!strcmp(buf, "writeback")) { - bdrv_flags |= BDRV_O_CACHE_WB; - } else if (!strcmp(buf, "unsafe")) { - bdrv_flags |= BDRV_O_CACHE_WB; - bdrv_flags |= BDRV_O_NO_FLUSH; - } else if (!strcmp(buf, "writethrough")) { - /* this is the default */ - } else { - error_report("invalid cache option"); - return NULL; + if (bdrv_parse_cache_flags(buf, &bdrv_flags) != 0) { + error_report("invalid cache option"); + return NULL; } } @@ -446,12 +437,12 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) /* init */ - dinfo = qemu_mallocz(sizeof(*dinfo)); + dinfo = g_malloc0(sizeof(*dinfo)); if ((buf = qemu_opts_id(opts)) != NULL) { - dinfo->id = qemu_strdup(buf); + dinfo->id = g_strdup(buf); } else { /* no id supplied -> create one */ - dinfo->id = qemu_mallocz(32); + dinfo->id = g_malloc0(32); if (type == IF_IDE || type == IF_SCSI) mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd"; if (max_devs) @@ -487,23 +478,19 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) } break; case MEDIA_CDROM: - bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM); + dinfo->media_cd = 1; break; } break; case IF_SD: - /* FIXME: This isn't really a floppy, but it's a reasonable - approximation. */ case IF_FLOPPY: - bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY); - break; case IF_PFLASH: case IF_MTD: break; case IF_VIRTIO: /* add virtio block device */ opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0); - qemu_opt_set(opts, "driver", "virtio-blk-pci"); + qemu_opt_set(opts, "driver", "virtio-blk"); qemu_opt_set(opts, "drive", dinfo->id); if (devaddr) qemu_opt_set(opts, "addr", devaddr); @@ -536,6 +523,17 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) if (ret < 0) { error_report("could not open disk image %s: %s", file, strerror(-ret)); + +#ifdef CONFIG_MARU + const char _msg[] = "Failed to load disk file from the following path. Check if the file is corrupted or missing.\n\n"; + char* err_msg = NULL; + err_msg = maru_convert_path((char*)_msg, file); + start_simple_client(err_msg); + if (err_msg) { + g_free(err_msg); + } +#endif + goto err; } @@ -545,9 +543,9 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) err: bdrv_delete(dinfo->bdrv); - qemu_free(dinfo->id); + g_free(dinfo->id); QTAILQ_REMOVE(&drives, dinfo, next); - qemu_free(dinfo); + g_free(dinfo); return NULL; } @@ -571,15 +569,16 @@ void do_commit(Monitor *mon, const QDict *qdict) int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *device = qdict_get_str(qdict, "device"); - const char *filename = qdict_get_try_str(qdict, "snapshot_file"); + const char *filename = qdict_get_try_str(qdict, "snapshot-file"); const char *format = qdict_get_try_str(qdict, "format"); BlockDriverState *bs; - BlockDriver *drv, *proto_drv; + BlockDriver *drv, *old_drv, *proto_drv; int ret = 0; int flags; + char old_filename[1024]; if (!filename) { - qerror_report(QERR_MISSING_PARAMETER, "snapshot_file"); + qerror_report(QERR_MISSING_PARAMETER, "snapshot-file"); ret = -1; goto out; } @@ -591,6 +590,11 @@ int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data) goto out; } + pstrcpy(old_filename, sizeof(old_filename), bs->filename); + + old_drv = bs->drv; + flags = bs->open_flags; + if (!format) { format = "qcow2"; } @@ -610,7 +614,7 @@ int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data) } ret = bdrv_img_create(filename, format, bs->filename, - bs->drv->format_name, NULL, -1, bs->open_flags); + bs->drv->format_name, NULL, -1, flags); if (ret) { goto out; } @@ -618,15 +622,20 @@ int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data) qemu_aio_flush(); bdrv_flush(bs); - flags = bs->open_flags; bdrv_close(bs); ret = bdrv_open(bs, filename, flags, drv); /* - * If reopening the image file we just created fails, we really - * are in trouble :( + * If reopening the image file we just created fails, fall back + * and try to re-open the original image. If that fails too, we + * are in serious trouble. */ if (ret != 0) { - abort(); + ret = bdrv_open(bs, old_filename, flags, old_drv); + if (ret != 0) { + qerror_report(QERR_OPEN_FILE_FAILED, old_filename); + } else { + qerror_report(QERR_OPEN_FILE_FAILED, filename); + } } out: if (ret) { @@ -638,13 +647,13 @@ out: static int eject_device(Monitor *mon, BlockDriverState *bs, int force) { - if (!force) { - if (!bdrv_is_removable(bs)) { - qerror_report(QERR_DEVICE_NOT_REMOVABLE, - bdrv_get_device_name(bs)); - return -1; - } - if (bdrv_is_locked(bs)) { + if (!bdrv_dev_has_removable_media(bs)) { + qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs)); + return -1; + } + if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) { + bdrv_dev_eject_request(bs, force); + if (!force) { qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); return -1; } @@ -742,12 +751,12 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) bdrv_flush(bs); bdrv_close(bs); - /* if we have a device associated with this BlockDriverState (bs->peer) + /* if we have a device attached to this BlockDriverState * then we need to make the drive anonymous until the device * can be removed. If this is a drive with no device backing * then we can just get rid of the block driver state right here. */ - if (bs->peer) { + if (bdrv_get_attached_dev(bs)) { bdrv_make_anon(bs); } else { drive_uninit(drive_get_by_blockdev(bs)); diff --git a/blockdev.h b/blockdev.h index 2c9e780..3587786 100644 --- a/blockdev.h +++ b/blockdev.h @@ -33,6 +33,7 @@ struct DriveInfo { int bus; int unit; int auto_del; /* see blockdev_mark_auto_del() */ + int media_cd; QemuOpts *opts; char serial[BLOCK_SERIAL_STRLEN + 1]; QTAILQ_ENTRY(DriveInfo) next; diff --git a/bsd-user/main.c b/bsd-user/main.c index 6b12f8b..cc7d4a3 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -29,7 +29,7 @@ #include "qemu.h" #include "qemu-common.h" /* For tb_lock */ -#include "exec-all.h" +#include "cpu.h" #include "tcg.h" #include "qemu-timer.h" #include "envlist.h" @@ -237,7 +237,7 @@ void cpu_loop(CPUX86State *env) break; #ifndef TARGET_ABI32 case EXCP_SYSCALL: - /* syscall from syscall intruction */ + /* syscall from syscall instruction */ if (bsd_type == target_freebsd) env->regs[R_EAX] = do_freebsd_syscall(env, env->regs[R_EAX], @@ -690,7 +690,8 @@ static void usage(void) "-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n" "\n" "Debug options:\n" - "-d options activate log (logfile=%s)\n" + "-d options activate log (default logfile=%s)\n" + "-D logfile override default logfile location\n" "-p pagesize set the host page size to 'pagesize'\n" "-singlestep always run in singlestep mode\n" "-strace log system calls\n" @@ -731,6 +732,8 @@ int main(int argc, char **argv) { const char *filename; const char *cpu_model; + const char *log_file = DEBUG_LOGFILE; + const char *log_mask = NULL; struct target_pt_regs regs1, *regs = ®s1; struct image_info info1, *info = &info1; TaskState ts1, *ts = &ts1; @@ -745,9 +748,6 @@ int main(int argc, char **argv) if (argc <= 1) usage(); - /* init debug */ - cpu_set_log_filename(DEBUG_LOGFILE); - if ((envlist = envlist_create()) == NULL) { (void) fprintf(stderr, "Unable to allocate envlist\n"); exit(1); @@ -775,22 +775,15 @@ int main(int argc, char **argv) if (!strcmp(r, "-")) { break; } else if (!strcmp(r, "d")) { - int mask; - const CPULogItem *item; - - if (optind >= argc) + if (optind >= argc) { + break; + } + log_mask = argv[optind++]; + } else if (!strcmp(r, "D")) { + if (optind >= argc) { break; - - r = argv[optind++]; - mask = cpu_str_to_log_mask(r); - if (!mask) { - printf("Log items (comma separated):\n"); - for(item = cpu_log_items; item->mask != 0; item++) { - printf("%-10s %s\n", item->name, item->help); - } - exit(1); } - cpu_set_log(mask); + log_file = argv[optind++]; } else if (!strcmp(r, "E")) { r = argv[optind++]; if (envlist_setenv(envlist, r) != 0) @@ -863,8 +856,27 @@ int main(int argc, char **argv) usage(); } } - if (optind >= argc) + + /* init debug */ + cpu_set_log_filename(log_file); + if (log_mask) { + int mask; + const CPULogItem *item; + + mask = cpu_str_to_log_mask(log_mask); + if (!mask) { + printf("Log items (comma separated):\n"); + for (item = cpu_log_items; item->mask != 0; item++) { + printf("%-10s %s\n", item->name, item->help); + } + exit(1); + } + cpu_set_log(mask); + } + + if (optind >= argc) { usage(); + } filename = argv[optind]; /* Zero out regs */ @@ -893,7 +905,8 @@ int main(int argc, char **argv) cpu_model = "any"; #endif } - cpu_exec_init_all(0); + tcg_exec_init(0); + cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(cpu_model); diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 207c774..5d6cffc 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -94,7 +94,7 @@ void *qemu_vmalloc(size_t size) return p; } -void *qemu_malloc(size_t size) +void *g_malloc(size_t size) { char * p; size += 16; @@ -104,12 +104,12 @@ void *qemu_malloc(size_t size) } /* We use map, which is always zero initialized. */ -void * qemu_mallocz(size_t size) +void * g_malloc0(size_t size) { - return qemu_malloc(size); + return g_malloc(size); } -void qemu_free(void *ptr) +void g_free(void *ptr) { /* FIXME: We should unmark the reserved pages here. However this gets complicated when one target page spans multiple host pages, so we @@ -119,18 +119,18 @@ void qemu_free(void *ptr) munmap(p, *p); } -void *qemu_realloc(void *ptr, size_t size) +void *g_realloc(void *ptr, size_t size) { size_t old_size, copy; void *new_ptr; if (!ptr) - return qemu_malloc(size); + return g_malloc(size); old_size = *(size_t *)((char *)ptr - 16); copy = old_size < size ? old_size : size; - new_ptr = qemu_malloc(size); + new_ptr = g_malloc(size); memcpy(new_ptr, ptr, copy); - qemu_free(ptr); + g_free(ptr); return new_ptr; } diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index e343894..1ba2d08 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -323,7 +323,7 @@ abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len); abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len); /* Functions for accessing guest memory. The tget and tput functions - read/write single values, byteswapping as neccessary. The lock_user + read/write single values, byteswapping as necessary. The lock_user gets a pointer to a contiguous area of guest memory, but does not perform and byteswapping. lock_user may return either a pointer to the guest memory, or a temporary buffer. */ diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index eb1cdf2..18b43f1 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "qemu.h" @@ -232,7 +231,7 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol void *hnamep, *holdp, *hnewp = NULL; size_t holdlen; abi_ulong oldlen = 0; - int32_t *snamep = qemu_malloc(sizeof(int32_t) * namelen), *p, *q, i; + int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i; uint32_t kind = 0; if (oldlenp) @@ -256,7 +255,7 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol unlock_user(holdp, oldp, holdlen); if (hnewp) unlock_user(hnewp, newp, 0); - qemu_free(snamep); + g_free(snamep); return ret; } #endif diff --git a/bswap.h b/bswap.h index 82a7951..cc7f84d 100644 --- a/bswap.h +++ b/bswap.h @@ -4,6 +4,7 @@ #include "config-host.h" #include +#include "softfloat.h" #ifdef CONFIG_MACHINE_BSWAP_H #include @@ -237,4 +238,476 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int len) return bswap32(value) >> (32 - 8 * len); } +typedef union { + float32 f; + uint32_t l; +} CPU_FloatU; + +typedef union { + float64 d; +#if defined(HOST_WORDS_BIGENDIAN) + struct { + uint32_t upper; + uint32_t lower; + } l; +#else + struct { + uint32_t lower; + uint32_t upper; + } l; +#endif + uint64_t ll; +} CPU_DoubleU; + +typedef union { + floatx80 d; + struct { + uint64_t lower; + uint16_t upper; + } l; +} CPU_LDoubleU; + +typedef union { + float128 q; +#if defined(HOST_WORDS_BIGENDIAN) + struct { + uint32_t upmost; + uint32_t upper; + uint32_t lower; + uint32_t lowest; + } l; + struct { + uint64_t upper; + uint64_t lower; + } ll; +#else + struct { + uint32_t lowest; + uint32_t lower; + uint32_t upper; + uint32_t upmost; + } l; + struct { + uint64_t lower; + uint64_t upper; + } ll; +#endif +} CPU_QuadU; + +/* unaligned/endian-independent pointer access */ + +/* + * the generic syntax is: + * + * load: ld{type}{sign}{size}{endian}_p(ptr) + * + * store: st{type}{size}{endian}_p(ptr, val) + * + * Note there are small differences with the softmmu access API! + * + * type is: + * (empty): integer access + * f : float access + * + * sign is: + * (empty): for floats or 32 bit size + * u : unsigned + * s : signed + * + * size is: + * b: 8 bits + * w: 16 bits + * l: 32 bits + * q: 64 bits + * + * endian is: + * (empty): 8 bit access + * be : big endian + * le : little endian + */ +static inline int ldub_p(const void *ptr) +{ + return *(uint8_t *)ptr; +} + +static inline int ldsb_p(const void *ptr) +{ + return *(int8_t *)ptr; +} + +static inline void stb_p(void *ptr, int v) +{ + *(uint8_t *)ptr = v; +} + +/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the + kernel handles unaligned load/stores may give better results, but + it is a system wide setting : bad */ +#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED) + +/* conservative code for little endian unaligned accesses */ +static inline int lduw_le_p(const void *ptr) +{ +#ifdef _ARCH_PPC + int val; + __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); + return val; +#else + const uint8_t *p = ptr; + return p[0] | (p[1] << 8); +#endif +} + +static inline int ldsw_le_p(const void *ptr) +{ +#ifdef _ARCH_PPC + int val; + __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); + return (int16_t)val; +#else + const uint8_t *p = ptr; + return (int16_t)(p[0] | (p[1] << 8)); +#endif +} + +static inline int ldl_le_p(const void *ptr) +{ +#ifdef _ARCH_PPC + int val; + __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); + return val; +#else + const uint8_t *p = ptr; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +#endif +} + +static inline uint64_t ldq_le_p(const void *ptr) +{ + const uint8_t *p = ptr; + uint32_t v1, v2; + v1 = ldl_le_p(p); + v2 = ldl_le_p(p + 4); + return v1 | ((uint64_t)v2 << 32); +} + +static inline void stw_le_p(void *ptr, int v) +{ +#ifdef _ARCH_PPC + __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); +#else + uint8_t *p = ptr; + p[0] = v; + p[1] = v >> 8; +#endif +} + +static inline void stl_le_p(void *ptr, int v) +{ +#ifdef _ARCH_PPC + __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); +#else + uint8_t *p = ptr; + p[0] = v; + p[1] = v >> 8; + p[2] = v >> 16; + p[3] = v >> 24; +#endif +} + +static inline void stq_le_p(void *ptr, uint64_t v) +{ + uint8_t *p = ptr; + stl_le_p(p, (uint32_t)v); + stl_le_p(p + 4, v >> 32); +} + +/* float access */ + +static inline float32 ldfl_le_p(const void *ptr) +{ + union { + float32 f; + uint32_t i; + } u; + u.i = ldl_le_p(ptr); + return u.f; +} + +static inline void stfl_le_p(void *ptr, float32 v) +{ + union { + float32 f; + uint32_t i; + } u; + u.f = v; + stl_le_p(ptr, u.i); +} + +static inline float64 ldfq_le_p(const void *ptr) +{ + CPU_DoubleU u; + u.l.lower = ldl_le_p(ptr); + u.l.upper = ldl_le_p(ptr + 4); + return u.d; +} + +static inline void stfq_le_p(void *ptr, float64 v) +{ + CPU_DoubleU u; + u.d = v; + stl_le_p(ptr, u.l.lower); + stl_le_p(ptr + 4, u.l.upper); +} + +#else + +static inline int lduw_le_p(const void *ptr) +{ + return *(uint16_t *)ptr; +} + +static inline int ldsw_le_p(const void *ptr) +{ + return *(int16_t *)ptr; +} + +static inline int ldl_le_p(const void *ptr) +{ + return *(uint32_t *)ptr; +} + +static inline uint64_t ldq_le_p(const void *ptr) +{ + return *(uint64_t *)ptr; +} + +static inline void stw_le_p(void *ptr, int v) +{ + *(uint16_t *)ptr = v; +} + +static inline void stl_le_p(void *ptr, int v) +{ + *(uint32_t *)ptr = v; +} + +static inline void stq_le_p(void *ptr, uint64_t v) +{ + *(uint64_t *)ptr = v; +} + +/* float access */ + +static inline float32 ldfl_le_p(const void *ptr) +{ + return *(float32 *)ptr; +} + +static inline float64 ldfq_le_p(const void *ptr) +{ + return *(float64 *)ptr; +} + +static inline void stfl_le_p(void *ptr, float32 v) +{ + *(float32 *)ptr = v; +} + +static inline void stfq_le_p(void *ptr, float64 v) +{ + *(float64 *)ptr = v; +} +#endif + +#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED) + +static inline int lduw_be_p(const void *ptr) +{ +#if defined(__i386__) + int val; + asm volatile ("movzwl %1, %0\n" + "xchgb %b0, %h0\n" + : "=q" (val) + : "m" (*(uint16_t *)ptr)); + return val; +#else + const uint8_t *b = ptr; + return ((b[0] << 8) | b[1]); +#endif +} + +static inline int ldsw_be_p(const void *ptr) +{ +#if defined(__i386__) + int val; + asm volatile ("movzwl %1, %0\n" + "xchgb %b0, %h0\n" + : "=q" (val) + : "m" (*(uint16_t *)ptr)); + return (int16_t)val; +#else + const uint8_t *b = ptr; + return (int16_t)((b[0] << 8) | b[1]); +#endif +} + +static inline int ldl_be_p(const void *ptr) +{ +#if defined(__i386__) || defined(__x86_64__) + int val; + asm volatile ("movl %1, %0\n" + "bswap %0\n" + : "=r" (val) + : "m" (*(uint32_t *)ptr)); + return val; +#else + const uint8_t *b = ptr; + return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; +#endif +} + +static inline uint64_t ldq_be_p(const void *ptr) +{ + uint32_t a,b; + a = ldl_be_p(ptr); + b = ldl_be_p((uint8_t *)ptr + 4); + return (((uint64_t)a<<32)|b); +} + +static inline void stw_be_p(void *ptr, int v) +{ +#if defined(__i386__) + asm volatile ("xchgb %b0, %h0\n" + "movw %w0, %1\n" + : "=q" (v) + : "m" (*(uint16_t *)ptr), "0" (v)); +#else + uint8_t *d = (uint8_t *) ptr; + d[0] = v >> 8; + d[1] = v; +#endif +} + +static inline void stl_be_p(void *ptr, int v) +{ +#if defined(__i386__) || defined(__x86_64__) + asm volatile ("bswap %0\n" + "movl %0, %1\n" + : "=r" (v) + : "m" (*(uint32_t *)ptr), "0" (v)); +#else + uint8_t *d = (uint8_t *) ptr; + d[0] = v >> 24; + d[1] = v >> 16; + d[2] = v >> 8; + d[3] = v; +#endif +} + +static inline void stq_be_p(void *ptr, uint64_t v) +{ + stl_be_p(ptr, v >> 32); + stl_be_p((uint8_t *)ptr + 4, v); +} + +/* float access */ + +static inline float32 ldfl_be_p(const void *ptr) +{ + union { + float32 f; + uint32_t i; + } u; + u.i = ldl_be_p(ptr); + return u.f; +} + +static inline void stfl_be_p(void *ptr, float32 v) +{ + union { + float32 f; + uint32_t i; + } u; + u.f = v; + stl_be_p(ptr, u.i); +} + +static inline float64 ldfq_be_p(const void *ptr) +{ + CPU_DoubleU u; + u.l.upper = ldl_be_p(ptr); + u.l.lower = ldl_be_p((uint8_t *)ptr + 4); + return u.d; +} + +static inline void stfq_be_p(void *ptr, float64 v) +{ + CPU_DoubleU u; + u.d = v; + stl_be_p(ptr, u.l.upper); + stl_be_p((uint8_t *)ptr + 4, u.l.lower); +} + +#else + +static inline int lduw_be_p(const void *ptr) +{ + return *(uint16_t *)ptr; +} + +static inline int ldsw_be_p(const void *ptr) +{ + return *(int16_t *)ptr; +} + +static inline int ldl_be_p(const void *ptr) +{ + return *(uint32_t *)ptr; +} + +static inline uint64_t ldq_be_p(const void *ptr) +{ + return *(uint64_t *)ptr; +} + +static inline void stw_be_p(void *ptr, int v) +{ + *(uint16_t *)ptr = v; +} + +static inline void stl_be_p(void *ptr, int v) +{ + *(uint32_t *)ptr = v; +} + +static inline void stq_be_p(void *ptr, uint64_t v) +{ + *(uint64_t *)ptr = v; +} + +/* float access */ + +static inline float32 ldfl_be_p(const void *ptr) +{ + return *(float32 *)ptr; +} + +static inline float64 ldfq_be_p(const void *ptr) +{ + return *(float64 *)ptr; +} + +static inline void stfl_be_p(void *ptr, float32 v) +{ + *(float32 *)ptr = v; +} + +static inline void stfq_be_p(void *ptr, float64 v) +{ + *(float64 *)ptr = v; +} + +#endif + #endif /* BSWAP_H */ diff --git a/bt-host.c b/bt-host.c index 6931e7c..df5b7cd 100644 --- a/bt-host.c +++ b/bt-host.c @@ -19,7 +19,6 @@ #include "qemu-common.h" #include "qemu-char.h" -#include "sysemu.h" #include "net.h" #include "bt-host.h" @@ -178,7 +177,7 @@ struct HCIInfo *bt_host_hci(const char *id) } # endif - s = qemu_mallocz(sizeof(struct bt_host_hci_s)); + s = g_malloc0(sizeof(struct bt_host_hci_s)); s->fd = fd; s->hci.cmd_send = bt_host_cmd; s->hci.sco_send = bt_host_sco; diff --git a/bt-vhci.c b/bt-vhci.c index 679c5e0..bbc1029 100644 --- a/bt-vhci.c +++ b/bt-vhci.c @@ -19,7 +19,6 @@ #include "qemu-common.h" #include "qemu-char.h" -#include "sysemu.h" #include "net.h" #include "hw/bt.h" @@ -157,7 +156,7 @@ void bt_vhci_init(struct HCIInfo *info) exit(-1); } - s = qemu_mallocz(sizeof(struct bt_vhci_s)); + s = g_malloc0(sizeof(struct bt_vhci_s)); s->fd = fd; s->info = info ?: qemu_next_hci(); s->info->opaque = s; diff --git a/buffered_file.c b/buffered_file.c index 8435a31..fed9a22 100644 --- a/buffered_file.c +++ b/buffered_file.c @@ -14,7 +14,6 @@ #include "qemu-common.h" #include "hw/hw.h" #include "qemu-timer.h" -#include "sysemu.h" #include "qemu-char.h" #include "buffered_file.h" @@ -28,7 +27,6 @@ typedef struct QEMUFileBuffered BufferedCloseFunc *close; void *opaque; QEMUFile *file; - int has_error; int freeze_output; size_t bytes_xfer; size_t xfer_limit; @@ -57,7 +55,7 @@ static void buffered_append(QEMUFileBuffered *s, s->buffer_capacity += size + 1024; - tmp = qemu_realloc(s->buffer, s->buffer_capacity); + tmp = g_realloc(s->buffer, s->buffer_capacity); if (tmp == NULL) { fprintf(stderr, "qemu file buffer expansion failed\n"); exit(1); @@ -73,9 +71,11 @@ static void buffered_append(QEMUFileBuffered *s, static void buffered_flush(QEMUFileBuffered *s) { size_t offset = 0; + int error; - if (s->has_error) { - DPRINTF("flush when error, bailing\n"); + error = qemu_file_get_error(s->file); + if (error != 0) { + DPRINTF("flush when error, bailing: %s\n", strerror(-error)); return; } @@ -94,7 +94,7 @@ static void buffered_flush(QEMUFileBuffered *s) if (ret <= 0) { DPRINTF("error flushing data, %zd\n", ret); - s->has_error = 1; + qemu_file_set_error(s->file, ret); break; } else { DPRINTF("flushed %zd byte(s)\n", ret); @@ -110,14 +110,15 @@ static void buffered_flush(QEMUFileBuffered *s) static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size) { QEMUFileBuffered *s = opaque; - int offset = 0; + int offset = 0, error; ssize_t ret; DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); - if (s->has_error) { - DPRINTF("flush when error, bailing\n"); - return -EINVAL; + error = qemu_file_get_error(s->file); + if (error) { + DPRINTF("flush when error, bailing: %s\n", strerror(-error)); + return error; } DPRINTF("unfreezing output\n"); @@ -140,7 +141,7 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in if (ret <= 0) { DPRINTF("error putting\n"); - s->has_error = 1; + qemu_file_set_error(s->file, ret); offset = -EINVAL; break; } @@ -174,29 +175,37 @@ static int buffered_close(void *opaque) DPRINTF("closing\n"); - while (!s->has_error && s->buffer_size) { + while (!qemu_file_get_error(s->file) && s->buffer_size) { buffered_flush(s); if (s->freeze_output) - s->wait_for_unfreeze(s); + s->wait_for_unfreeze(s->opaque); } ret = s->close(s->opaque); qemu_del_timer(s->timer); qemu_free_timer(s->timer); - qemu_free(s->buffer); - qemu_free(s); + g_free(s->buffer); + g_free(s); return ret; } +/* + * The meaning of the return values is: + * 0: We can continue sending + * 1: Time to stop + * negative: There has been an error + */ static int buffered_rate_limit(void *opaque) { QEMUFileBuffered *s = opaque; + int ret; - if (s->has_error) - return 0; - + ret = qemu_file_get_error(s->file); + if (ret) { + return ret; + } if (s->freeze_output) return 1; @@ -209,9 +218,9 @@ static int buffered_rate_limit(void *opaque) static int64_t buffered_set_rate_limit(void *opaque, int64_t new_rate) { QEMUFileBuffered *s = opaque; - if (s->has_error) + if (qemu_file_get_error(s->file)) { goto out; - + } if (new_rate > SIZE_MAX) { new_rate = SIZE_MAX; } @@ -233,12 +242,12 @@ static void buffered_rate_tick(void *opaque) { QEMUFileBuffered *s = opaque; - if (s->has_error) { + if (qemu_file_get_error(s->file)) { buffered_close(s); return; } - qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100); + qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100); if (s->freeze_output) return; @@ -260,7 +269,7 @@ QEMUFile *qemu_fopen_ops_buffered(void *opaque, { QEMUFileBuffered *s; - s = qemu_mallocz(sizeof(*s)); + s = g_malloc0(sizeof(*s)); s->opaque = opaque; s->xfer_limit = bytes_per_sec / 10; @@ -274,9 +283,9 @@ QEMUFile *qemu_fopen_ops_buffered(void *opaque, buffered_set_rate_limit, buffered_get_rate_limit); - s->timer = qemu_new_timer(rt_clock, buffered_rate_tick, s); + s->timer = qemu_new_timer_ms(rt_clock, buffered_rate_tick, s); - qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100); + qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100); return s->file; } diff --git a/check-qdict.c b/check-qdict.c index 6afce5a..5515773 100644 --- a/check-qdict.c +++ b/check-qdict.c @@ -56,9 +56,9 @@ START_TEST(qdict_put_obj_test) // destroy doesn't exit yet QDECREF(qi); - qemu_free(ent->key); - qemu_free(ent); - qemu_free(qdict); + g_free(ent->key); + g_free(ent); + g_free(qdict); } END_TEST @@ -267,8 +267,9 @@ static QString *read_line(FILE *file, char *key) { char value[128]; - if (fscanf(file, "%s%s", key, value) == EOF) + if (fscanf(file, "%127s%127s", key, value) == EOF) { return NULL; + } remove_dots(key); return qstring_from_str(value); } diff --git a/check-qfloat.c b/check-qfloat.c index b71d983..3344057 100644 --- a/check-qfloat.c +++ b/check-qfloat.c @@ -33,7 +33,7 @@ START_TEST(qfloat_from_double_test) fail_unless(qobject_type(QOBJECT(qf)) == QTYPE_QFLOAT); // destroy doesn't exit yet - qemu_free(qf); + g_free(qf); } END_TEST diff --git a/check-qint.c b/check-qint.c index f3b0316..3af51f2 100644 --- a/check-qint.c +++ b/check-qint.c @@ -32,7 +32,7 @@ START_TEST(qint_from_int_test) fail_unless(qobject_type(QOBJECT(qi)) == QTYPE_QINT); // destroy doesn't exit yet - qemu_free(qi); + g_free(qi); } END_TEST diff --git a/check-qjson.c b/check-qjson.c index 64fcdcb..36d4ac2 100644 --- a/check-qjson.c +++ b/check-qjson.c @@ -33,7 +33,8 @@ START_TEST(escaped_string) { "\"\\n\"", "\n" }, { "\"\\r\"", "\r" }, { "\"\\t\"", "\t" }, - { "\"\\/\"", "\\/" }, + { "\"/\"", "/" }, + { "\"\\/\"", "/", .skip = 1 }, { "\"\\\\\"", "\\" }, { "\"\\\"\"", "\"" }, { "\"hello world \\\"embedded string\\\"\"", diff --git a/check-qlist.c b/check-qlist.c index 58984cb..ee2454a 100644 --- a/check-qlist.c +++ b/check-qlist.c @@ -30,7 +30,7 @@ START_TEST(qlist_new_test) fail_unless(qobject_type(QOBJECT(qlist)) == QTYPE_QLIST); // destroy doesn't exist yet - qemu_free(qlist); + g_free(qlist); } END_TEST @@ -51,8 +51,8 @@ START_TEST(qlist_append_test) // destroy doesn't exist yet QDECREF(qi); - qemu_free(entry); - qemu_free(qlist); + g_free(entry); + g_free(qlist); } END_TEST @@ -65,7 +65,7 @@ START_TEST(qobject_to_qlist_test) fail_unless(qobject_to_qlist(QOBJECT(qlist)) == qlist); // destroy doesn't exist yet - qemu_free(qlist); + g_free(qlist); } END_TEST diff --git a/check-qstring.c b/check-qstring.c index c9bafc2..93bd475 100644 --- a/check-qstring.c +++ b/check-qstring.c @@ -32,8 +32,8 @@ START_TEST(qstring_from_str_test) fail_unless(qobject_type(QOBJECT(qstring)) == QTYPE_QSTRING); // destroy doesn't exit yet - qemu_free(qstring->string); - qemu_free(qstring); + g_free(qstring->string); + g_free(qstring); } END_TEST diff --git a/cmd.c b/cmd.c index db2c9c4..0806e18 100644 --- a/cmd.c +++ b/cmd.c @@ -45,13 +45,11 @@ compare(const void *a, const void *b) ((const cmdinfo_t *)b)->name); } -void -add_command( - const cmdinfo_t *ci) +void add_command(const cmdinfo_t *ci) { - cmdtab = realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); - cmdtab[ncmds - 1] = *ci; - qsort(cmdtab, ncmds, sizeof(*cmdtab), compare); + cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab)); + cmdtab[ncmds - 1] = *ci; + qsort(cmdtab, ncmds, sizeof(*cmdtab), compare); } static int @@ -122,16 +120,10 @@ find_command( return NULL; } -void -add_user_command(char *optarg) +void add_user_command(char *optarg) { - ncmdline++; - cmdline = realloc(cmdline, sizeof(char*) * (ncmdline)); - if (!cmdline) { - perror("realloc"); - exit(1); - } - cmdline[ncmdline-1] = optarg; + cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *)); + cmdline[ncmdline-1] = optarg; } static int @@ -160,45 +152,44 @@ static void prep_fetchline(void *opaque) static char *get_prompt(void); -void -command_loop(void) +void command_loop(void) { - int c, i, j = 0, done = 0, fetchable = 0, prompted = 0; - char *input; - char **v; - const cmdinfo_t *ct; - - for (i = 0; !done && i < ncmdline; i++) { - input = strdup(cmdline[i]); - if (!input) { - fprintf(stderr, - _("cannot strdup command '%s': %s\n"), - cmdline[i], strerror(errno)); - exit(1); - } - v = breakline(input, &c); - if (c) { - ct = find_command(v[0]); - if (ct) { - if (ct->flags & CMD_FLAG_GLOBAL) - done = command(ct, c, v); - else { - j = 0; - while (!done && (j = args_command(j))) - done = command(ct, c, v); - } - } else - fprintf(stderr, _("command \"%s\" not found\n"), - v[0]); - } - doneline(input, v); - } - if (cmdline) { - free(cmdline); - return; + int c, i, j = 0, done = 0, fetchable = 0, prompted = 0; + char *input; + char **v; + const cmdinfo_t *ct; + + for (i = 0; !done && i < ncmdline; i++) { + input = strdup(cmdline[i]); + if (!input) { + fprintf(stderr, _("cannot strdup command '%s': %s\n"), + cmdline[i], strerror(errno)); + exit(1); + } + v = breakline(input, &c); + if (c) { + ct = find_command(v[0]); + if (ct) { + if (ct->flags & CMD_FLAG_GLOBAL) { + done = command(ct, c, v); + } else { + j = 0; + while (!done && (j = args_command(j))) { + done = command(ct, c, v); + } + } + } else { + fprintf(stderr, _("command \"%s\" not found\n"), v[0]); + } } + doneline(input, v); + } + if (cmdline) { + g_free(cmdline); + return; + } - while (!done) { + while (!done) { if (!prompted) { printf("%s", get_prompt()); fflush(stdout); @@ -212,22 +203,24 @@ command_loop(void) if (!fetchable) { continue; } - if ((input = fetchline()) == NULL) - break; - v = breakline(input, &c); - if (c) { - ct = find_command(v[0]); - if (ct) - done = command(ct, c, v); - else - fprintf(stderr, _("command \"%s\" not found\n"), - v[0]); - } - doneline(input, v); + input = fetchline(); + if (input == NULL) { + break; + } + v = breakline(input, &c); + if (c) { + ct = find_command(v[0]); + if (ct) { + done = command(ct, c, v); + } else { + fprintf(stderr, _("command \"%s\" not found\n"), v[0]); + } + } + doneline(input, v); prompted = 0; fetchable = 0; - } + } qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL); } @@ -331,29 +324,32 @@ static char *qemu_strsep(char **input, const char *delim) return result; } -char ** -breakline( - char *input, - int *count) +char **breakline(char *input, int *count) { - int c = 0; - char *p; - char **rval = calloc(sizeof(char *), 1); - - while (rval && (p = qemu_strsep(&input, " ")) != NULL) { - if (!*p) - continue; - c++; - rval = realloc(rval, sizeof(*rval) * (c + 1)); - if (!rval) { - c = 0; - break; - } - rval[c - 1] = p; - rval[c] = NULL; - } - *count = c; - return rval; + int c = 0; + char *p; + char **rval = calloc(sizeof(char *), 1); + char **tmp; + + while (rval && (p = qemu_strsep(&input, " ")) != NULL) { + if (!*p) { + continue; + } + c++; + tmp = realloc(rval, sizeof(*rval) * (c + 1)); + if (!tmp) { + free(rval); + rval = NULL; + c = 0; + break; + } else { + rval = tmp; + } + rval[c - 1] = p; + rval[c] = NULL; + } + *count = c; + return rval; } void @@ -389,7 +385,7 @@ cvtnum( if (sp[1] != '\0') return -1LL; - c = tolower(*sp); + c = qemu_tolower(*sp); switch (c) { default: return i; @@ -486,7 +482,7 @@ timestr( snprintf(ts, size, "%u:%02u.%02u", (unsigned int) MINUTES(tv->tv_sec), (unsigned int) SECONDS(tv->tv_sec), - (unsigned int) usec * 100); + (unsigned int) (usec * 100)); return; } format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */ @@ -497,9 +493,9 @@ timestr( (unsigned int) HOURS(tv->tv_sec), (unsigned int) MINUTES(tv->tv_sec), (unsigned int) SECONDS(tv->tv_sec), - (unsigned int) usec * 100); + (unsigned int) (usec * 100)); } else { - snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000); + snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000)); } } diff --git a/compatfd.c b/compatfd.c index a7cebc4..02306a4 100644 --- a/compatfd.c +++ b/compatfd.c @@ -26,45 +26,45 @@ struct sigfd_compat_info static void *sigwait_compat(void *opaque) { struct sigfd_compat_info *info = opaque; - int err; sigset_t all; sigfillset(&all); - sigprocmask(SIG_BLOCK, &all, NULL); - - do { - siginfo_t siginfo; - - err = sigwaitinfo(&info->mask, &siginfo); - if (err == -1 && errno == EINTR) { - err = 0; - continue; - } - - if (err > 0) { - char buffer[128]; + pthread_sigmask(SIG_BLOCK, &all, NULL); + + while (1) { + int sig; + int err; + + err = sigwait(&info->mask, &sig); + if (err != 0) { + if (errno == EINTR) { + continue; + } else { + return NULL; + } + } else { + struct qemu_signalfd_siginfo buffer; size_t offset = 0; - memcpy(buffer, &err, sizeof(err)); + memset(&buffer, 0, sizeof(buffer)); + buffer.ssi_signo = sig; + while (offset < sizeof(buffer)) { ssize_t len; - len = write(info->fd, buffer + offset, + len = write(info->fd, (char *)&buffer + offset, sizeof(buffer) - offset); if (len == -1 && errno == EINTR) continue; if (len <= 0) { - err = -1; - break; + return NULL; } offset += len; } } - } while (err >= 0); - - return NULL; + } } static int qemu_signalfd_compat(const sigset_t *mask) @@ -115,3 +115,22 @@ int qemu_signalfd(const sigset_t *mask) return qemu_signalfd_compat(mask); } + +bool qemu_signalfd_available(void) +{ +#ifdef CONFIG_SIGNALFD + sigset_t mask; + int fd; + bool ok; + sigemptyset(&mask); + errno = 0; + fd = syscall(SYS_signalfd, -1, &mask, _NSIG / 8); + ok = (errno != ENOSYS); + if (fd >= 0) { + close(fd); + } + return ok; +#else + return false; +#endif +} diff --git a/compatfd.h b/compatfd.h index fc37915..6b04877 100644 --- a/compatfd.h +++ b/compatfd.h @@ -39,5 +39,6 @@ struct qemu_signalfd_siginfo { }; int qemu_signalfd(const sigset_t *mask); +bool qemu_signalfd_available(void); #endif diff --git a/config.h b/config.h index e20f786..82c0ab2 100644 --- a/config.h +++ b/config.h @@ -1,2 +1,2 @@ #include "config-host.h" -#include "config-target.h" +#include "i386-softmmu/config-target.h" diff --git a/configure b/configure index ab540e1..528e025 100755 --- a/configure +++ b/configure @@ -92,6 +92,7 @@ libs_tools="" audio_pt_int="" audio_win_int="" cc_i386=i386-pc-linux-gnu-gcc +libs_qga="" target_list="" @@ -113,10 +114,9 @@ curl="" curses="" docs="" fdt="" -kvm="" -kvm_para="" nptl="" sdl="" +vnc="yes" sparse="no" uuid="" vde="" @@ -126,19 +126,21 @@ vnc_jpeg="" vnc_png="" vnc_thread="no" xen="" +xen_ctrl_version="" linux_aio="" attr="" -vhost_net="" +libattr="" xfs="" -ffmpeg="no" -ffmpeg_inc="distrib/ffmpeg" -v4l2="no" -v4l2_inc="" + +vhost_net="no" +kvm="no" +hax="no" gprof="no" debug_tcg="no" debug_mon="no" debug="no" strip_opt="yes" +tcg_interpreter="no" bigendian="no" mingw32="no" EXESUF="" @@ -147,6 +149,8 @@ mandir="\${prefix}/share/man" datadir="\${prefix}/share/qemu" docdir="\${prefix}/share/doc/qemu" bindir="\${prefix}/bin" +libdir="\${prefix}/lib" +includedir="\${prefix}/include" sysconfdir="\${prefix}/etc" confsuffix="/qemu" slirp="yes" @@ -157,6 +161,7 @@ bsd="no" linux="no" solaris="no" profiler="no" +ldst_optimization="no" cocoa="no" softmmu="yes" linux_user="no" @@ -164,19 +169,29 @@ darwin_user="no" bsd_user="no" guest_base="" uname_release="" -io_thread="no" mixemu="no" -kerneldir="" aix="no" blobs="yes" pkgversion="" -check_utests="no" -user_pie="no" +check_utests="" +pie="" zero_malloc="" trace_backend="nop" trace_file="trace" spice="" rbd="" +smartcard="" +smartcard_nss="" +usb_redir="" +opengl="" +zlib="yes" +guest_agent="yes" +libiscsi="" +gl="yes" + +# for TIZEN-maru +maru="no" +# # parse CC options first for opt do @@ -215,23 +230,24 @@ done # Using uname is really, really broken. Once we have the right set of checks # we can eliminate it's usage altogether -cc="${cross_prefix}${CC-gcc}" -ar="${cross_prefix}${AR-ar}" -objcopy="${cross_prefix}${OBJCOPY-objcopy}" -ld="${cross_prefix}${LD-ld}" -strip="${cross_prefix}${STRIP-strip}" -windres="${cross_prefix}${WINDRES-windres}" -pkg_config="${cross_prefix}${PKG_CONFIG-pkg-config}" -sdl_config="${cross_prefix}${SDL_CONFIG-sdl-config}" +cc="${CC-${cross_prefix}gcc}" +ar="${AR-${cross_prefix}ar}" +objcopy="${OBJCOPY-${cross_prefix}objcopy}" +ld="${LD-${cross_prefix}ld}" +libtool="${LIBTOOL-${cross_prefix}libtool}" +strip="${STRIP-${cross_prefix}strip}" +windres="${WINDRES-${cross_prefix}windres}" +pkg_config="${PKG_CONFIG-${cross_prefix}pkg-config}" +sdl_config="${SDL_CONFIG-${cross_prefix}sdl-config}" # default flags for all hosts QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS" CFLAGS="-g $CFLAGS" -QEMU_CFLAGS="-Wall -Wundef -Wendif-labels -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS" +QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS" QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS" QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS" QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS" -QEMU_INCLUDES="-I. -I\$(SRC_PATH)" +QEMU_INCLUDES="-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/fpu" LDFLAGS="-g $LDFLAGS" # make source path absolute @@ -278,12 +294,18 @@ elif check_define __s390__ ; then else cpu="s390" fi +elif check_define __ARMEB__ ; then + cpu="armv4b" +elif check_define __ARMEL__ ; then + cpu="armv4l" +elif check_define __hppa__ ; then + cpu="hppa" else cpu=`uname -m` fi case "$cpu" in - alpha|cris|ia64|m68k|microblaze|ppc|ppc64|sparc64) + alpha|cris|ia64|lm32|m68k|microblaze|ppc|ppc64|sparc64|unicore32) cpu="$cpu" ;; i386|i486|i586|i686|i86pc|BePC) @@ -298,7 +320,7 @@ case "$cpu" in armv*l) cpu="armv4l" ;; - parisc|parisc64) + hppa|parisc|parisc64) cpu="hppa" ;; mips*) @@ -395,7 +417,7 @@ Darwin) QEMU_CFLAGS="-mdynamic-no-pic $QEMU_CFLAGS" fi darwin_user="yes" - cocoa="yes" + cocoa="no" audio_drv_list="coreaudio" audio_possible_drivers="coreaudio sdl fmod" LDFLAGS="-framework CoreFoundation -framework IOKit $LDFLAGS" @@ -406,6 +428,7 @@ SunOS) make="${MAKE-gmake}" install="${INSTALL-ginstall}" ld="gld" + smbd="${SMBD-/usr/sfw/sbin/smbd}" needs_libsunmath="no" solarisrev=`uname -r | cut -f2 -d.` # have to select again, because `uname -m` returns i86pc @@ -456,6 +479,8 @@ Haiku) linux="yes" linux_user="yes" usb="linux" + kvm="yes" + vhost_net="yes" if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then audio_possible_drivers="$audio_possible_drivers fmod" fi @@ -471,13 +496,15 @@ fi : ${make=${MAKE-make}} : ${install=${INSTALL-install}} +: ${python=${PYTHON-python}} +: ${smbd=${SMBD-/usr/sbin/smbd}} if test "$mingw32" = "yes" ; then EXESUF=".exe" QEMU_CFLAGS="-DWIN32_LEAN_AND_MEAN -DWINVER=0x501 $QEMU_CFLAGS" # enable C99/POSIX format strings (needs mingw32-runtime 3.15 or later) QEMU_CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $QEMU_CFLAGS" - LIBS="-lwinmm -lws2_32 -liphlpapi $LIBS" + LIBS="-lwinmm -lws2_32 -liberty -liphlpapi $LIBS" prefix="c:/Program Files/Qemu" mandir="\${prefix}" datadir="\${prefix}" @@ -485,6 +512,7 @@ if test "$mingw32" = "yes" ; then bindir="\${prefix}" sysconfdir="\${prefix}" confsuffix="" + guest_agent="no" fi werror="" @@ -494,6 +522,8 @@ for opt do case "$opt" in --help|-h) show_help=yes ;; + --version|-V) exec cat $source_path/VERSION + ;; --prefix=*) prefix="$optarg" ;; --interp-prefix=*) interp_prefix="$optarg" @@ -510,6 +540,10 @@ for opt do ;; --install=*) install="$optarg" ;; + --python=*) python="$optarg" + ;; + --smbd=*) smbd="$optarg" + ;; --extra-cflags=*) ;; --extra-ldflags=*) @@ -532,23 +566,35 @@ for opt do ;; --bindir=*) bindir="$optarg" ;; + --libdir=*) libdir="$optarg" + ;; + --includedir=*) includedir="$optarg" + ;; --datadir=*) datadir="$optarg" ;; --docdir=*) docdir="$optarg" ;; --sysconfdir=*) sysconfdir="$optarg" ;; + --sbindir=*|--libexecdir=*|--sharedstatedir=*|--localstatedir=*|\ + --oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\ + --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*) + # These switches are silently ignored, for compatibility with + # autoconf-generated configure scripts. This allows QEMU's + # configure to be used by RPM and similar macros that set + # lots of directory switches by default. + ;; --disable-sdl) sdl="no" ;; --enable-sdl) sdl="yes" ;; - --fmod-lib=*) fmod_lib="$optarg" + --disable-vnc) vnc="no" ;; - --fmod-inc=*) fmod_inc="$optarg" + --enable-vnc) vnc="yes" ;; - --ffmpeg-inc=*) ffmpeg_inc="$optarg" + --fmod-lib=*) fmod_lib="$optarg" ;; - --v4l2-inc=*) v4l2_inc="$optarg" + --fmod-inc=*) fmod_inc="$optarg" ;; --oss-lib=*) oss_lib="$optarg" ;; @@ -579,11 +625,6 @@ for opt do ;; --disable-strip) strip_opt="no" ;; - --disable-jpeg) jpeg="no" - ;; - --enable-jpeg) jpeg="yes" - ;; - --disable-vnc-tls) vnc_tls="no" ;; --enable-vnc-tls) vnc_tls="yes" @@ -604,14 +645,6 @@ for opt do ;; --enable-vnc-thread) vnc_thread="yes" ;; - --disable-ffmpeg) ffmpeg="no" - ;; - --enable-ffmpeg) ffmpeg="yes" - ;; - --disable-v4l2) v4l2="no" - ;; - --enable-v4l2) v4l2="yes" - ;; --disable-slirp) slirp="no" ;; --disable-uuid) uuid="no" @@ -638,13 +671,29 @@ for opt do ;; --enable-kvm) kvm="yes" ;; + --disable-gl) gl="no" + ;; + --enable-gl) gl="yes" + ;; + --disable-hax) hax="no" + ;; + --enable-hax) hax="yes" + ;; + --disable-tcg-interpreter) tcg_interpreter="no" + ;; + --enable-tcg-interpreter) tcg_interpreter="yes" + ;; --disable-spice) spice="no" ;; --enable-spice) spice="yes" ;; + --disable-libiscsi) libiscsi="no" + ;; + --enable-libiscsi) libiscsi="yes" + ;; --enable-profiler) profiler="yes" ;; - --enable-tcg-x86-opt) tcg_x86_opt="yes" + --enable-ldst-optimization) ldst_optimization="yes" ;; --enable-cocoa) cocoa="yes" ; @@ -677,9 +726,9 @@ for opt do ;; --disable-guest-base) guest_base="no" ;; - --enable-user-pie) user_pie="yes" + --enable-pie) pie="yes" ;; - --disable-user-pie) user_pie="no" + --disable-pie) pie="no" ;; --enable-uname-release=*) uname_release="$optarg" ;; @@ -719,12 +768,8 @@ for opt do ;; --enable-attr) attr="yes" ;; - --enable-io-thread) io_thread="yes" - ;; --disable-blobs) blobs="no" ;; - --kerneldir=*) kerneldir="$optarg" - ;; --with-pkgversion=*) pkgversion=" ($optarg)" ;; --disable-docs) docs="no" @@ -735,12 +780,36 @@ for opt do ;; --enable-vhost-net) vhost_net="yes" ;; - --*dir) + --disable-opengl) opengl="no" + ;; + --enable-opengl) opengl="yes" ;; --disable-rbd) rbd="no" ;; --enable-rbd) rbd="yes" ;; + --disable-smartcard) smartcard="no" + ;; + --enable-smartcard) smartcard="yes" + ;; + --disable-smartcard-nss) smartcard_nss="no" + ;; + --enable-smartcard-nss) smartcard_nss="yes" + ;; + --disable-usb-redir) usb_redir="no" + ;; + --enable-usb-redir) usb_redir="yes" + ;; + --disable-zlib-test) zlib="no" + ;; + --enable-guest-agent) guest_agent="yes" + ;; + --disable-guest-agent) guest_agent="no" + ;; +# for TIZEN-maru + --enable-maru) maru="yes" + ;; +# *) echo "ERROR: unknown option $opt"; show_help="yes" ;; esac @@ -815,10 +884,84 @@ case "$cpu" in hppa*) host_guest_base="yes" ;; + unicore32*) + host_guest_base="yes" + ;; esac [ -z "$guest_base" ] && guest_base="$host_guest_base" + +default_target_list="" + +# these targets are portable +if [ "$softmmu" = "yes" ] ; then + default_target_list="\ +i386-softmmu \ +x86_64-softmmu \ +alpha-softmmu \ +arm-softmmu \ +cris-softmmu \ +lm32-softmmu \ +m68k-softmmu \ +microblaze-softmmu \ +microblazeel-softmmu \ +mips-softmmu \ +mipsel-softmmu \ +mips64-softmmu \ +mips64el-softmmu \ +ppc-softmmu \ +ppcemb-softmmu \ +ppc64-softmmu \ +sh4-softmmu \ +sh4eb-softmmu \ +sparc-softmmu \ +sparc64-softmmu \ +s390x-softmmu \ +xtensa-softmmu \ +xtensaeb-softmmu \ +" +fi +# the following are Linux specific +if [ "$linux_user" = "yes" ] ; then + default_target_list="${default_target_list}\ +i386-linux-user \ +x86_64-linux-user \ +alpha-linux-user \ +arm-linux-user \ +armeb-linux-user \ +cris-linux-user \ +m68k-linux-user \ +microblaze-linux-user \ +microblazeel-linux-user \ +mips-linux-user \ +mipsel-linux-user \ +ppc-linux-user \ +ppc64-linux-user \ +ppc64abi32-linux-user \ +sh4-linux-user \ +sh4eb-linux-user \ +sparc-linux-user \ +sparc64-linux-user \ +sparc32plus-linux-user \ +unicore32-linux-user \ +s390x-linux-user \ +" +fi +# the following are Darwin specific +if [ "$darwin_user" = "yes" ] ; then + default_target_list="$default_target_list i386-darwin-user ppc-darwin-user " +fi +# the following are BSD specific +if [ "$bsd_user" = "yes" ] ; then + default_target_list="${default_target_list}\ +i386-bsd-user \ +x86_64-bsd-user \ +sparc-bsd-user \ +sparc64-bsd-user \ +" +fi + if test x"$show_help" = x"yes" ; then cat << EOF @@ -831,7 +974,9 @@ echo " --help print this message" echo " --prefix=PREFIX install in PREFIX [$prefix]" echo " --interp-prefix=PREFIX where to find shared libraries, etc." echo " use %M for cpu name [$interp_prefix]" -echo " --target-list=LIST set target list [$target_list]" +echo " --target-list=LIST set target list (default: build everything)" +echo "Available targets: $default_target_list" | \ + fold -s -w 53 | sed -e 's/^/ /' echo "" echo "Advanced options (experts only):" echo " --source-path=PATH path of source code [$source_path]" @@ -843,6 +988,8 @@ echo " --extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS" echo " --extra-ldflags=LDFLAGS append extra linker flags LDFLAGS" echo " --make=MAKE use specified make [$make]" echo " --install=INSTALL use specified install [$install]" +echo " --python=PYTHON use specified python [$python]" +echo " --smbd=SMBD use specified smbd [$smbd]" echo " --static enable static build [$static]" echo " --mandir=PATH install man pages in PATH" echo " --datadir=PATH install firmware in PATH" @@ -858,6 +1005,8 @@ echo " --disable-strip disable stripping binaries" echo " --disable-werror disable compilation abort on warning" echo " --disable-sdl disable SDL" echo " --enable-sdl enable SDL" +echo " --disable-vnc disable VNC" +echo " --enable-vnc enable VNC" echo " --enable-cocoa enable COCOA (Mac OS X only)" echo " --audio-drv-list=LIST set audio drivers list:" echo " Available drivers: $audio_possible_drivers" @@ -880,10 +1029,6 @@ echo " --disable-vnc-png disable PNG compression for VNC server (default echo " --enable-vnc-png enable PNG compression for VNC server" echo " --disable-vnc-thread disable threaded VNC server" echo " --enable-vnc-thread enable threaded VNC server" -echo " --disable-ffmpeg disable FFMPEG lossy compression" -echo " --enable-ffmpeg enable FFMPEG lossy compression" -echo " --disable-v4l2 disable camera using v4l2" -echo " --enable-v4l2 enable camera using v4l2" echo " --disable-curses disable curses output" echo " --enable-curses enable curses output" echo " --disable-curl disable curl connectivity" @@ -894,8 +1039,17 @@ echo " --disable-check-utests disable check unit-tests" echo " --enable-check-utests enable check unit-tests" echo " --disable-bluez disable bluez stack connectivity" echo " --enable-bluez enable bluez stack connectivity" +echo " --disable-slirp disable SLIRP userspace network connectivity" echo " --disable-kvm disable KVM acceleration support" echo " --enable-kvm enable KVM acceleration support" +echo " --disable-gl disable GL acceleration support" + +echo " --disable-hax disable HAX acceleration support" +echo " --enable-hax enable HAX acceleration support" + +echo " --disable-gl disable GL acceleration support" +echo " --enable-gl enable GL acceleration support" +echo " --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)" echo " --disable-nptl disable usermode NPTL support" echo " --enable-nptl enable usermode NPTL support" echo " --enable-system enable all system emulation targets" @@ -911,14 +1065,13 @@ echo " --disable-bsd-user disable all BSD usermode emulation targets" echo " --enable-guest-base enable GUEST_BASE support for usermode" echo " emulation targets" echo " --disable-guest-base disable GUEST_BASE support" -echo " --enable-user-pie build usermode emulation targets as PIE" -echo " --disable-user-pie do not build usermode emulation targets as PIE" +echo " --enable-pie build Position Independent Executables" +echo " --disable-pie do not build Position Independent Executables" echo " --fmod-lib path to FMOD library" echo " --fmod-inc path to FMOD includes" -echo " --ffmpeg-inc path to FFMPEG includes" -echo " --v4l2-inc path to V4L2 includes" echo " --oss-lib path to OSS library" echo " --enable-uname-release=R Return R for uname -r in usermode emulation" +echo " --cpu=CPU Build for host CPU [$cpu]" echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9" echo " --disable-uuid disable uuid support" echo " --enable-uuid enable uuid support" @@ -928,9 +1081,7 @@ echo " --disable-linux-aio disable Linux AIO support" echo " --enable-linux-aio enable Linux AIO support" echo " --disable-attr disables attr and xattr support" echo " --enable-attr enable attr and xattr support" -echo " --enable-io-thread enable IO thread" echo " --disable-blobs disable installing provided firmware blobs" -echo " --kerneldir=PATH look for kernel includes in PATH" echo " --enable-docs enable documentation build" echo " --disable-docs disable documentation build" echo " --disable-vhost-net disable vhost-net acceleration support" @@ -942,7 +1093,22 @@ echo " Default:trace-" echo " --disable-spice disable spice" echo " --enable-spice enable spice" echo " --enable-rbd enable building the rados block device (rbd)" +echo " --disable-libiscsi disable iscsi support" +echo " --enable-libiscsi enable iscsi support" +echo " --disable-smartcard disable smartcard support" +echo " --enable-smartcard enable smartcard support" +echo " --disable-smartcard-nss disable smartcard nss support" +echo " --enable-smartcard-nss enable smartcard nss support" +echo " --disable-usb-redir disable usb network redirection support" +echo " --enable-usb-redir enable usb network redirection support" +echo " --disable-guest-agent disable building of the QEMU Guest Agent" +echo " --enable-guest-agent enable building of the QEMU Guest Agent" +echo "" +# for TIZEN-maru +echo "TIZEN-maru options:" +echo " --enable-maru enable maru board" echo "" +# echo "NOTE: The object files are built at the place where configure is launched" exit 1 fi @@ -962,19 +1128,67 @@ fi gcc_flags="-Wold-style-declaration -Wold-style-definition -Wtype-limits" gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_flags" gcc_flags="-Wmissing-include-dirs -Wempty-body -Wnested-externs $gcc_flags" - -# TODO: build on i386 fails to use -fstack-protector-all option. -gcc_flags="-fnostack-protector-all $gcc_flags" - +gcc_flags="-fstack-protector-all -Wendif-labels $gcc_flags" cat > $TMPC << EOF int main(void) { return 0; } EOF for flag in $gcc_flags; do - if compile_prog "-Werror $QEMU_CFLAGS" "-Werror $flag" ; then + if compile_prog "$flag -Werror" "" ; then QEMU_CFLAGS="$QEMU_CFLAGS $flag" fi done +if test "$static" = "yes" ; then + if test "$pie" = "yes" ; then + echo "static and pie are mutually incompatible" + exit 1 + else + pie="no" + fi +fi + +if test "$pie" = ""; then + case "$cpu-$targetos" in + i386-Linux|x86_64-Linux|i386-OpenBSD|x86_64-OpenBSD) + ;; + *) + pie="no" + ;; + esac +fi + +if test "$pie" != "no" ; then + cat > $TMPC << EOF + +#ifdef __linux__ +# define THREAD __thread +#else +# define THREAD +#endif + +static THREAD int tls_var; + +int main(void) { return tls_var; } + +EOF + if compile_prog "-fPIE -DPIE" "-pie"; then + QEMU_CFLAGS="-fPIE -DPIE $QEMU_CFLAGS" + LDFLAGS="-pie $LDFLAGS" + pie="yes" + if compile_prog "" "-Wl,-z,relro -Wl,-z,now" ; then + LDFLAGS="-Wl,-z,relro -Wl,-z,now $LDFLAGS" + fi + else + if test "$pie" = "yes"; then + echo "PIE not available due to missing toolchain support" + exit 1 + else + echo "Disabling PIE due to missing toolchain support" + pie="no" + fi + fi +fi + # # Solaris specific configure tool chain decisions # @@ -1004,66 +1218,17 @@ if test "$solaris" = "yes" ; then fi fi +if test "$guest_agent" != "no" ; then + if has $python; then + : + else + echo "Python not found. Use --python=/path/to/python" + exit 1 + fi +fi if test -z "$target_list" ; then -# these targets are portable - if [ "$softmmu" = "yes" ] ; then - target_list="\ -i386-softmmu \ -x86_64-softmmu \ -arm-softmmu \ -cris-softmmu \ -m68k-softmmu \ -microblaze-softmmu \ -mips-softmmu \ -mipsel-softmmu \ -mips64-softmmu \ -mips64el-softmmu \ -ppc-softmmu \ -ppcemb-softmmu \ -ppc64-softmmu \ -sh4-softmmu \ -sh4eb-softmmu \ -sparc-softmmu \ -sparc64-softmmu \ -" - fi -# the following are Linux specific - if [ "$linux_user" = "yes" ] ; then - target_list="${target_list}\ -i386-linux-user \ -x86_64-linux-user \ -alpha-linux-user \ -arm-linux-user \ -armeb-linux-user \ -cris-linux-user \ -m68k-linux-user \ -microblaze-linux-user \ -mips-linux-user \ -mipsel-linux-user \ -ppc-linux-user \ -ppc64-linux-user \ -ppc64abi32-linux-user \ -sh4-linux-user \ -sh4eb-linux-user \ -sparc-linux-user \ -sparc64-linux-user \ -sparc32plus-linux-user \ -" - fi -# the following are Darwin specific - if [ "$darwin_user" = "yes" ] ; then - target_list="$target_list i386-darwin-user ppc-darwin-user " - fi -# the following are BSD specific - if [ "$bsd_user" = "yes" ] ; then - target_list="${target_list}\ -i386-bsd-user \ -x86_64-bsd-user \ -sparc-bsd-user \ -sparc64-bsd-user \ -" - fi + target_list="$default_target_list" else target_list=`echo "$target_list" | sed -e 's/,/ /g'` fi @@ -1157,18 +1322,20 @@ fi ########################################## # zlib check -cat > $TMPC << EOF +if test "$zlib" != "no" ; then + cat > $TMPC << EOF #include int main(void) { zlibVersion(); return 0; } EOF -if compile_prog "" "-lz" ; then - : -else - echo - echo "Error: zlib check failed" - echo "Make sure to have the zlib libs and headers installed." - echo - exit 1 + if compile_prog "" "-lz" ; then + : + else + echo + echo "Error: zlib check failed" + echo "Make sure to have the zlib libs and headers installed." + echo + exit 1 + fi fi ########################################## @@ -1176,28 +1343,123 @@ fi if test "$xen" != "no" ; then xen_libs="-lxenstore -lxenctrl -lxenguest" + + # Xen unstable cat > $TMPC < #include -int main(void) { xs_daemon_open(); xc_interface_open(); return 0; } +#include +#include +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + xc_interface *xc; + xs_daemon_open(); + xc = xc_interface_open(0, 0, 0); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_gnttab_open(NULL, 0); + xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0); + return 0; +} EOF if compile_prog "" "$xen_libs" ; then + xen_ctrl_version=410 xen=yes - libs_softmmu="$xen_libs $libs_softmmu" + + # Xen 4.0.0 + elif ( + cat > $TMPC < +#include +#include +#include +#if !defined(HVM_MAX_VCPUS) +# error HVM_MAX_VCPUS not defined +#endif +int main(void) { + struct xen_add_to_physmap xatp = { + .domid = 0, .space = XENMAPSPACE_gmfn, .idx = 0, .gpfn = 0, + }; + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_memory_op(0, XENMEM_add_to_physmap, &xatp); + return 0; +} +EOF + compile_prog "" "$xen_libs" + ) ; then + xen_ctrl_version=400 + xen=yes + + # Xen 3.4.0 + elif ( + cat > $TMPC < +#include +int main(void) { + struct xen_add_to_physmap xatp = { + .domid = 0, .space = XENMAPSPACE_gmfn, .idx = 0, .gpfn = 0, + }; + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + xc_memory_op(0, XENMEM_add_to_physmap, &xatp); + return 0; +} +EOF + compile_prog "" "$xen_libs" + ) ; then + xen_ctrl_version=340 + xen=yes + + # Xen 3.3.0 + elif ( + cat > $TMPC < +#include +int main(void) { + xs_daemon_open(); + xc_interface_open(); + xc_gnttab_open(); + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); + return 0; +} +EOF + compile_prog "" "$xen_libs" + ) ; then + xen_ctrl_version=330 + xen=yes + + # Xen not found or unsupported else if test "$xen" = "yes" ; then feature_not_found "xen" fi xen=no fi + + if test "$xen" = yes; then + libs_softmmu="$xen_libs $libs_softmmu" + fi fi ########################################## # pkg-config probe if ! has $pkg_config; then - echo warning: proceeding without "$pkg_config" >&2 - pkg_config=/bin/false + echo "Error: pkg-config binary '$pkg_config' not found" + exit 1 +fi + +########################################## +# libtool probe + +if ! has $libtool; then + libtool= fi ########################################## @@ -1234,7 +1496,7 @@ else fi sdl=no fi -if test -n "$cross_prefix" && test "`basename $sdlconfig`" = sdl-config; then +if test -n "$cross_prefix" && test "$(basename "$sdlconfig")" = sdl-config; then echo warning: using "\"$sdlconfig\"" to detect cross-compiled sdl >&2 fi @@ -1301,7 +1563,7 @@ fi ########################################## # VNC TLS detection -if test "$vnc_tls" != "no" ; then +if test "$vnc" = "yes" -a "$vnc_tls" != "no" ; then cat > $TMPC < int main(void) { gnutls_session_t s; gnutls_init(&s, GNUTLS_SERVER); return 0; } @@ -1321,7 +1583,7 @@ fi ########################################## # VNC SASL detection -if test "$vnc_sasl" != "no" ; then +if test "$vnc" = "yes" -a "$vnc_sasl" != "no" ; then cat > $TMPC < #include @@ -1343,7 +1605,7 @@ fi ########################################## # VNC JPEG detection -if test "$vnc_jpeg" != "no" ; then +if test "$vnc" = "yes" -a "$vnc_jpeg" != "no" ; then cat > $TMPC < #include @@ -1364,7 +1626,7 @@ fi ########################################## # VNC PNG detection -if test "$vnc_png" != "no" ; then +if test "$vnc" = "yes" -a "$vnc_png" != "no" ; then cat > $TMPC < #include @@ -1375,80 +1637,22 @@ int main(void) { return 0; } EOF + if $pkg_config libpng --modversion >/dev/null 2>&1; then + vnc_png_cflags=`$pkg_config libpng --cflags 2> /dev/null` + vnc_png_libs=`$pkg_config libpng --libs 2> /dev/null` + else vnc_png_cflags="" vnc_png_libs="-lpng" + fi if compile_prog "$vnc_png_cflags" "$vnc_png_libs" ; then vnc_png=yes libs_softmmu="$vnc_png_libs $libs_softmmu" + QEMU_CFLAGS="$QEMU_CFLAGS $vnc_png_cflags" else if test "$vnc_png" = "yes" ; then feature_not_found "vnc-png" fi - vnc_png=no - fi -fi - -########################################## -# FFMPEG detection -if test "$ffmpeg" = "yes" ; then -cat > $TMPC < -#include -#include - -#include -#include - -int main(void) { AVFormatContext *pFormatCtx = NULL; av_find_stream_info(pFormatCtx); return 0; } -EOF - ffmpeg_cflags="-I$source_path/tizen/$ffmpeg_inc/include" - if test "$linux" = "yes" ; then - ffmpeg_libs="-lavformat -lavcodec -lavutil -lm" - elif test "$mingw32" = "yes" ; then - ffmpeg_libs="-lavformat.dll -lavcodec.dll -lavutil.dll -lm" - fi - ffmpeg_libpath="-L$source_path/tizen/$ffmpeg_inc/lib" - ffmpeg_libs="$ffmpeg_libpath $ffmpeg_libs" - if compile_prog "$ffmpeg_cflags" "$ffmpeg_libs" ; then - ffmpeg=yes - libs_softmmu="$ffmpeg_libs $libs_softmmu" - else - if test "$ffmpeg" = "yes" ; then - feature_not_found "ffmpeg" - exit 1; - fi - ffmpeg=no - fi -fi - -########################################## -# V4L2 detection -if test "$v4l2" = "yes" ; then -cat > $TMPC < -#include -#include - -#include -#include - -int main(void) {v4l2_open("/dev/video0", O_RDWR); return 0; } -EOF - -# v4l2_cflags="-I$v4l2_inc" - if test "$linux" = "yes" ; then - v4l2_libs="-lv4l2 -lv4lconvert" - fi - if compile_prog "$v4l2_cflags" "$v4l2_libs" ; then - v4l2=yes - libs_softmmu="$v4l2_libs $libs_softmmu" - else - if test "$v4l2" = "yes" ; then - feature_not_found "v4l2" - fi - v4l2=no + vnc_png=no fi fi @@ -1654,7 +1858,11 @@ fi ########################################## # curses probe -curses_list="-lncurses -lcurses" +if test "$mingw32" = "yes" ; then + curses_list="-lpdcurses" +else + curses_list="-lncurses -lcurses" +fi if test "$curses" != "no" ; then curses_found=no @@ -1694,7 +1902,7 @@ fi if test "$curl" != "no" ; then cat > $TMPC << EOF #include -int main(void) { return curl_easy_init(); } +int main(void) { curl_easy_init(); curl_multi_setopt(0, 0, 0); return 0; } EOF curl_cflags=`$curlconfig --cflags 2>/dev/null` curl_libs=`$curlconfig --libs 2>/dev/null` @@ -1718,7 +1926,7 @@ if test "$check_utests" != "no" ; then #include int main(void) { suite_create("qemu test"); return 0; } EOF - check_libs=`$pkg_config --libs check` + check_libs=`$pkg_config --libs check 2>/dev/null` if compile_prog "" $check_libs ; then check_utests=yes libs_tools="$check_libs $libs_tools" @@ -1751,111 +1959,20 @@ EOF fi ########################################## -# kvm probe -if test "$kvm" != "no" ; then - cat > $TMPC < -#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12 -#error Invalid KVM version -#endif -EOF - must_have_caps="KVM_CAP_USER_MEMORY \ - KVM_CAP_DESTROY_MEMORY_REGION_WORKS \ - KVM_CAP_COALESCED_MMIO \ - KVM_CAP_SYNC_MMU \ - " - if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) ; then - must_have_caps="$caps \ - KVM_CAP_SET_TSS_ADDR \ - KVM_CAP_EXT_CPUID \ - KVM_CAP_CLOCKSOURCE \ - KVM_CAP_NOP_IO_DELAY \ - KVM_CAP_PV_MMU \ - KVM_CAP_MP_STATE \ - KVM_CAP_USER_NMI \ - " - fi - for c in $must_have_caps ; do - cat >> $TMPC <> $TMPC </dev/null` - fi - if compile_prog "$kvm_cflags" "" ; then - kvm=yes - cat > $TMPC < -int main(void) { return 0; } -EOF - if compile_prog "$kvm_cflags" "" ; then - kvm_para=yes - fi - else - if test "$kvm" = "yes" ; then - if has awk && has grep; then - kvmerr=`LANG=C $cc $QEMU_CFLAGS -o $TMPE $kvm_cflags $TMPC 2>&1 \ - | grep "error: " \ - | awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'` - if test "$kvmerr" != "" ; then - echo -e "${kvmerr}\n\ -NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \ -recent kvm-kmod from http://sourceforge.net/projects/kvm." - fi - fi - feature_not_found "kvm" - fi - kvm=no - fi -fi - -########################################## -# test for vhost net - -if test "$vhost_net" != "no"; then - if test "$kvm" != "no"; then - cat > $TMPC < - int main(void) { return 0; } -EOF - if compile_prog "$kvm_cflags" "" ; then - vhost_net=yes - else - if test "$vhost_net" = "yes" ; then - feature_not_found "vhost-net" - fi - vhost_net=no - fi - else - if test "$vhost_net" = "yes" ; then - echo "NOTE: vhost-net feature requires KVM (--enable-kvm)." - feature_not_found "vhost-net" - fi - vhost_net=no - fi +# glib support probe +if $pkg_config --modversion gthread-2.0 > /dev/null 2>&1 ; then + glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null` + glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null` + LIBS="$glib_libs $LIBS" + libs_qga="$glib_libs $libs_qga" +else + echo "glib-2.0 required to compile QEMU" + exit 1 fi ########################################## # pthread probe -PTHREADLIBS_LIST="-lpthread -lpthreadGC2" +PTHREADLIBS_LIST="-pthread -lpthread -lpthreadGC2" pthread=no cat > $TMPC << EOF @@ -1887,41 +2004,24 @@ fi if test "$rbd" != "no" ; then cat > $TMPC < -#include -int main(void) { rados_initialize(0, NULL); return 0; } -EOF - rbd_libs="-lrados" - if compile_prog "" "$rbd_libs" ; then - librados_too_old=no - cat > $TMPC < -#include -#ifndef CEPH_OSD_TMAP_SET -#error missing CEPH_OSD_TMAP_SET -#endif +#include int main(void) { - int (*func)(const rados_pool_t pool, uint64_t *snapid) = rados_selfmanaged_snap_create; - rados_initialize(0, NULL); + rados_t cluster; + rados_create(&cluster, NULL); return 0; } EOF - if compile_prog "" "$rbd_libs" ; then - rbd=yes - libs_tools="$rbd_libs $libs_tools" - libs_softmmu="$rbd_libs $libs_softmmu" - else - rbd=no - librados_too_old=yes - fi + rbd_libs="-lrbd -lrados" + if compile_prog "" "$rbd_libs" ; then + rbd=yes + libs_tools="$rbd_libs $libs_tools" + libs_softmmu="$rbd_libs $libs_softmmu" else if test "$rbd" = "yes" ; then feature_not_found "rados block device" fi rbd=no fi - if test "$librados_too_old" = "yes" ; then - echo "-> Your librados version is too old - upgrade needed to have rbd support" - fi fi ########################################## @@ -1953,12 +2053,20 @@ if test "$attr" != "no" ; then cat > $TMPC < #include +#ifdef CONFIG_LIBATTR #include +#else +#include +#endif int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; } EOF - if compile_prog "" "-lattr" ; then + if compile_prog "" "" ; then + attr=yes + # Older distros have , and need -lattr: + elif compile_prog "-DCONFIG_LIBATTR" "-lattr" ; then attr=yes LIBS="-lattr $LIBS" + libattr=yes else if test "$attr" = "yes" ; then feature_not_found "ATTR" @@ -2002,15 +2110,36 @@ int main(void) { return 0; } EOF if compile_prog "" "$fdt_libs" ; then fdt=yes - libs_softmmu="$fdt_libs $libs_softmmu" else if test "$fdt" = "yes" ; then feature_not_found "fdt" fi + fdt_libs= fdt=no fi fi +########################################## +# opengl probe, used by milkymist-tmu2 +if test "$opengl" != "no" ; then + opengl_libs="-lGL" + cat > $TMPC << EOF +#include +#include +#include +int main(void) { GL_VERSION; return 0; } +EOF + if compile_prog "" "-lGL" ; then + opengl=yes + else + if test "$opengl" = "yes" ; then + feature_not_found "opengl" + fi + opengl_libs= + opengl=no + fi +fi + # # Check for xxxat() functions when we are building linux-user # emulator. This is done because older glibc versions don't @@ -2161,7 +2290,7 @@ cat > $TMPC << EOF int main(void) { - int efd = eventfd(0, 0); + int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); return 0; } EOF @@ -2231,6 +2360,59 @@ if compile_prog "" "" ; then dup3=yes fi +# check for epoll support +epoll=no +cat > $TMPC << EOF +#include + +int main(void) +{ + epoll_create(0); + return 0; +} +EOF +if compile_prog "$ARCH_CFLAGS" "" ; then + epoll=yes +fi + +# epoll_create1 and epoll_pwait are later additions +# so we must check separately for their presence +epoll_create1=no +cat > $TMPC << EOF +#include + +int main(void) +{ + /* Note that we use epoll_create1 as a value, not as + * a function being called. This is necessary so that on + * old SPARC glibc versions where the function was present in + * the library but not declared in the header file we will + * fail the configure check. (Otherwise we will get a compiler + * warning but not an error, and will proceed to fail the + * qemu compile where we compile with -Werror.) + */ + epoll_create1; + return 0; +} +EOF +if compile_prog "$ARCH_CFLAGS" "" ; then + epoll_create1=yes +fi + +epoll_pwait=no +cat > $TMPC << EOF +#include + +int main(void) +{ + epoll_pwait(0, 0, 0, 0, 0); + return 0; +} +EOF +if compile_prog "$ARCH_CFLAGS" "" ; then + epoll_pwait=yes +fi + # Check if tools are available to build documentation. if test "$docs" != "no" ; then if has makeinfo && has pod2man; then @@ -2266,6 +2448,25 @@ if compile_prog "" "" ; then fi ########################################## +# Do we have libiscsi +if test "$libiscsi" != "no" ; then + cat > $TMPC << EOF +#include +int main(void) { iscsi_create_context(""); return 0; } +EOF + if compile_prog "-Werror" "-liscsi" ; then + libiscsi="yes" + LIBS="$LIBS -liscsi" + else + if test "$libiscsi" = "yes" ; then + feature_not_found "libiscsi" + fi + libiscsi="no" + fi +fi + + +########################################## # Do we need librt cat > $TMPC < @@ -2296,23 +2497,6 @@ if compile_prog "" "" ; then need_offsetof=no fi -########################################## -# check if the compiler understands attribute warn_unused_result -# -# This could be smarter, but gcc -Werror does not error out even when warning -# about attribute warn_unused_result - -gcc_attribute_warn_unused_result=no -cat > $TMPC << EOF -#if defined(__GNUC__) && (__GNUC__ < 4) && defined(__GNUC_MINOR__) && (__GNUC__ < 4) -#error gcc 3.3 or older -#endif -int main(void) { return 0;} -EOF -if compile_prog "" ""; then - gcc_attribute_warn_unused_result=yes -fi - # spice probe if test "$spice" != "no" ; then cat > $TMPC << EOF @@ -2321,7 +2505,7 @@ int main(void) { spice_server_new(); return 0; } EOF spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null) spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null) - if $pkg_config --atleast-version=0.5.3 spice-server >/dev/null 2>&1 && \ + if $pkg_config --atleast-version=0.6.0 spice-server >/dev/null 2>&1 && \ compile_prog "$spice_cflags" "$spice_libs" ; then spice="yes" libs_softmmu="$libs_softmmu $spice_libs" @@ -2334,6 +2518,47 @@ EOF fi fi +# check for libcacard for smartcard support +if test "$smartcard" != "no" ; then + smartcard="yes" + smartcard_cflags="" + # TODO - what's the minimal nss version we support? + if test "$smartcard_nss" != "no"; then + if $pkg_config --atleast-version=3.12.8 nss >/dev/null 2>&1 ; then + smartcard_nss="yes" + smartcard_cflags="-I\$(SRC_PATH)/libcacard" + libcacard_libs=$($pkg_config --libs nss 2>/dev/null) + libcacard_cflags=$($pkg_config --cflags nss 2>/dev/null) + QEMU_CFLAGS="$QEMU_CFLAGS $smartcard_cflags $libcacard_cflags" + LIBS="$libcacard_libs $LIBS" + else + if test "$smartcard_nss" = "yes"; then + feature_not_found "nss" + fi + smartcard_nss="no" + fi + fi +fi +if test "$smartcard" = "no" ; then + smartcard_nss="no" +fi + +# check for usbredirparser for usb network redirection support +if test "$usb_redir" != "no" ; then + if $pkg_config libusbredirparser >/dev/null 2>&1 ; then + usb_redir="yes" + usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null) + usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null) + QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags" + LIBS="$LIBS $usb_redir_libs" + else + if test "$usb_redir" = "yes"; then + feature_not_found "usb-redir" + fi + usb_redir="no" + fi +fi + ########################################## ########################################## @@ -2342,7 +2567,13 @@ fi fdatasync=no cat > $TMPC << EOF #include -int main(void) { return fdatasync(0); } +int main(void) { +#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 +return fdatasync(0); +#else +#abort Not supported +#endif +} EOF if compile_prog "" "" ; then fdatasync=yes @@ -2421,6 +2652,68 @@ if test "$trace_backend" = "dtrace"; then fi ########################################## +# __sync_fetch_and_and requires at least -march=i486. Many toolchains +# use i686 as default anyway, but for those that don't, an explicit +# specification is necessary +if test "$vhost_net" = "yes" && test "$cpu" = "i386"; then + cat > $TMPC << EOF +int sfaa(unsigned *ptr) +{ + return __sync_fetch_and_and(ptr, 0); +} + +int main(int argc, char **argv) +{ + int val = 42; + sfaa(&val); + return val; +} +EOF + if ! compile_prog "" "" ; then + CFLAGS+="-march=i486" + fi +fi + +########################################## +# check if we have makecontext + +ucontext_coroutine=no +if test "$darwin" != "yes"; then + cat > $TMPC << EOF +#include +int main(void) { makecontext(0, 0, 0); } +EOF + if compile_prog "" "" ; then + ucontext_coroutine=yes + fi +fi + +########################################## +# check if we have open_by_handle_at + +open_by_hande_at=no +cat > $TMPC << EOF +#include +int main(void) { struct file_handle fh; open_by_handle_at(0, &fh, 0); } +EOF +if compile_prog "" "" ; then + open_by_handle_at=yes +fi + +######################################## +# check if we have linux/magic.h + +linux_magic_h=no +cat > $TMPC << EOF +#include +int main(void) { +} +EOF +if compile_prog "" "" ; then + linux_magic_h=yes +fi + +########################################## # End of CC checks # After here, no more $cc or $ld runs @@ -2477,9 +2770,12 @@ if test "$softmmu" = yes ; then tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools" if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then tools="qemu-nbd\$(EXESUF) $tools" + if [ "$guest_agent" = "yes" ]; then + tools="qemu-ga\$(EXESUF) $tools" + fi if [ "$check_utests" = "yes" ]; then - tools="check-qint check-qstring check-qdict check-qlist $tools" - tools="check-qfloat check-qjson $tools" + checks="check-qint check-qstring check-qdict check-qlist" + checks="check-qfloat check-qjson test-coroutine $checks" fi fi fi @@ -2491,11 +2787,15 @@ if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) -a \ "$softmmu" = yes ; then roms="optionrom" fi - +if test "$cpu" = "ppc64" -a "$targetos" != "Darwin" ; then + roms="$roms spapr-rtas" +fi echo "Install prefix $prefix" echo "BIOS directory `eval echo $datadir`" echo "binary directory `eval echo $bindir`" +echo "library directory `eval echo $libdir`" +echo "include directory `eval echo $includedir`" echo "config directory `eval echo $sysconfdir`" if test "$mingw32" = "no" ; then echo "Manual directory `eval echo $mandir`" @@ -2509,6 +2809,10 @@ echo "QEMU_CFLAGS $QEMU_CFLAGS" echo "LDFLAGS $LDFLAGS" echo "make $make" echo "install $install" +echo "python $python" +if test "$slirp" = "yes" ; then + echo "smbd $smbd" +fi echo "host CPU $cpu" echo "host big endian $bigendian" echo "target list $target_list" @@ -2518,7 +2822,7 @@ echo "gprof enabled $gprof" echo "sparse enabled $sparse" echo "strip binaries $strip_opt" echo "profiler $profiler" -echo "TCG optimization $tcg_x86_opt" +echo "Fast TCG ld/st $ldst_optimization" echo "static build $static" echo "-Werror enabled $werror" if test "$darwin" = "yes" ; then @@ -2533,13 +2837,14 @@ echo "Audio drivers $audio_drv_list" echo "Extra audio cards $audio_card_list" echo "Block whitelist $block_drv_whitelist" echo "Mixer emulation $mixemu" -echo "VNC TLS support $vnc_tls" -echo "VNC SASL support $vnc_sasl" -echo "VNC JPEG support $vnc_jpeg" -echo "VNC PNG support $vnc_png" -echo "VNC thread $vnc_thread" -echo "FFMPEG support $ffmpeg" -echo "V4L2 support $v4l2" +echo "VNC support $vnc" +if test "$vnc" = "yes" ; then + echo "VNC TLS support $vnc_tls" + echo "VNC SASL support $vnc_sasl" + echo "VNC JPEG support $vnc_jpeg" + echo "VNC PNG support $vnc_png" + echo "VNC thread $vnc_thread" +fi if test -n "$sparc_cpu"; then echo "Target Sparc Arch $sparc_cpu" fi @@ -2551,13 +2856,15 @@ echo "Documentation $docs" echo "uname -r $uname_release" echo "NPTL support $nptl" echo "GUEST_BASE $guest_base" -echo "PIE user targets $user_pie" +echo "PIE $pie" echo "vde support $vde" -echo "IO thread $io_thread" echo "Linux AIO support $linux_aio" echo "ATTR/XATTR support $attr" echo "Install blobs $blobs" echo "KVM support $kvm" +echo "HAX support $hax" +echo "GL support $gl" +echo "TCG interpreter $tcg_interpreter" echo "fdt support $fdt" echo "preadv support $preadv" echo "fdatasync $fdatasync" @@ -2570,8 +2877,17 @@ echo "Trace output file $trace_file-" echo "spice support $spice" echo "rbd support $rbd" echo "xfsctl support $xfs" +echo "nss used $smartcard_nss" +echo "usb net redir $usb_redir" +echo "OpenGL support $opengl" +echo "libiscsi support $libiscsi" +echo "build guest agent $guest_agent" + +# for TIZEN-maru +echo "TIZEN-maru support $maru" +# -if test $sdl_too_old = "yes"; then +if test "$sdl_too_old" = "yes"; then echo "-> Your SDL version is too old - please upgrade to have SDL support" fi @@ -2586,6 +2902,8 @@ echo >> $config_host_mak echo all: >> $config_host_mak echo "prefix=$prefix" >> $config_host_mak echo "bindir=$bindir" >> $config_host_mak +echo "libdir=$libdir" >> $config_host_mak +echo "includedir=$includedir" >> $config_host_mak echo "mandir=$mandir" >> $config_host_mak echo "datadir=$datadir" >> $config_host_mak echo "sysconfdir=$sysconfdir" >> $config_host_mak @@ -2593,12 +2911,21 @@ echo "docdir=$docdir" >> $config_host_mak echo "confdir=$confdir" >> $config_host_mak case "$cpu" in - i386|x86_64|alpha|cris|hppa|ia64|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64) + i386|x86_64|alpha|cris|hppa|ia64|lm32|m68k|microblaze|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64|unicore32) ARCH=$cpu ;; armv4b|armv4l) ARCH=arm ;; + *) + if test "$tcg_interpreter" = "yes" ; then + echo "Unsupported CPU = $cpu, will use TCG with TCI (experimental)" + ARCH=tci + else + echo "Unsupported CPU = $cpu, try --enable-tcg-interpreter" + exit 1 + fi + ;; esac echo "ARCH=$ARCH" >> $config_host_mak if test "$debug_tcg" = "yes" ; then @@ -2657,14 +2984,15 @@ fi if test "$static" = "yes" ; then echo "CONFIG_STATIC=y" >> $config_host_mak fi -if test $profiler = "yes" ; then +if test "$profiler" = "yes" ; then echo "CONFIG_PROFILER=y" >> $config_host_mak fi -if test $tcg_x86_opt = "yes" ; then - echo "CONFIG_TCG_TARGET_X86_OPT=y" >> $config_host_mak +if test "$ldst_optimization" = "yes" ; then + echo "CONFIG_QEMU_LDST_OPTIMIZATION=y" >> $config_host_mak fi if test "$slirp" = "yes" ; then echo "CONFIG_SLIRP=y" >> $config_host_mak + echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak QEMU_INCLUDES="-I\$(SRC_PATH)/slirp $QEMU_INCLUDES" fi if test "$vde" = "yes" ; then @@ -2692,6 +3020,9 @@ echo "CONFIG_BDRV_WHITELIST=$block_drv_whitelist" >> $config_host_mak if test "$mixemu" = "yes" ; then echo "CONFIG_MIXEMU=y" >> $config_host_mak fi +if test "$vnc" = "yes" ; then + echo "CONFIG_VNC=y" >> $config_host_mak +fi if test "$vnc_tls" = "yes" ; then echo "CONFIG_VNC_TLS=y" >> $config_host_mak echo "VNC_TLS_CFLAGS=$vnc_tls_cflags" >> $config_host_mak @@ -2700,27 +3031,17 @@ if test "$vnc_sasl" = "yes" ; then echo "CONFIG_VNC_SASL=y" >> $config_host_mak echo "VNC_SASL_CFLAGS=$vnc_sasl_cflags" >> $config_host_mak fi -if test "$vnc_jpeg" != "no" ; then +if test "$vnc_jpeg" = "yes" ; then echo "CONFIG_VNC_JPEG=y" >> $config_host_mak echo "VNC_JPEG_CFLAGS=$vnc_jpeg_cflags" >> $config_host_mak fi -if test "$vnc_png" != "no" ; then +if test "$vnc_png" = "yes" ; then echo "CONFIG_VNC_PNG=y" >> $config_host_mak echo "VNC_PNG_CFLAGS=$vnc_png_cflags" >> $config_host_mak fi -if test "$vnc_thread" != "no" ; then +if test "$vnc_thread" = "yes" ; then echo "CONFIG_VNC_THREAD=y" >> $config_host_mak - echo "CONFIG_THREAD=y" >> $config_host_mak -fi -if test "$ffmpeg" = "yes" ; then - echo "CONFIG_FFMPEG=y" >> $config_host_mak - echo "FFMPEG_CFLAGS=$ffmpeg_cflags" >> $config_host_mak -fi -if test "$v4l2" = "yes" ; then - echo "CONFIG_V4L2=y" >> $config_host_mak - echo "V4L2_CFLAGS=$v4l2_cflags" >> $config_host_mak fi - if test "$fnmatch" = "yes" ; then echo "CONFIG_FNMATCH=y" >> $config_host_mak fi @@ -2740,8 +3061,6 @@ if [ "$docs" = "yes" ] ; then fi if test "$sdl" = "yes" ; then echo "CONFIG_SDL=y" >> $config_host_mak - echo "SDL_LIBS=$sdl_libs -lSDL_image -lSDL_gfx" >> $config_host_mak - echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak fi if test "$cocoa" = "yes" ; then @@ -2780,6 +3099,15 @@ fi if test "$dup3" = "yes" ; then echo "CONFIG_DUP3=y" >> $config_host_mak fi +if test "$epoll" = "yes" ; then + echo "CONFIG_EPOLL=y" >> $config_host_mak +fi +if test "$epoll_create1" = "yes" ; then + echo "CONFIG_EPOLL_CREATE1=y" >> $config_host_mak +fi +if test "$epoll_pwait" = "yes" ; then + echo "CONFIG_EPOLL_PWAIT=y" >> $config_host_mak +fi if test "$inotify" = "yes" ; then echo "CONFIG_INOTIFY=y" >> $config_host_mak fi @@ -2803,12 +3131,10 @@ if test "$bluez" = "yes" ; then echo "CONFIG_BLUEZ=y" >> $config_host_mak echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak fi +echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak if test "$xen" = "yes" ; then - echo "CONFIG_XEN=y" >> $config_host_mak -fi -if test "$io_thread" = "yes" ; then - echo "CONFIG_IOTHREAD=y" >> $config_host_mak - echo "CONFIG_THREAD=y" >> $config_host_mak + echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak + echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak fi if test "$linux_aio" = "yes" ; then echo "CONFIG_LINUX_AIO=y" >> $config_host_mak @@ -2816,6 +3142,9 @@ fi if test "$attr" = "yes" ; then echo "CONFIG_ATTR=y" >> $config_host_mak fi +if test "$libattr" = "yes" ; then + echo "CONFIG_LIBATTR=y" >> $config_host_mak +fi if test "$linux" = "yes" ; then if test "$attr" = "yes" ; then echo "CONFIG_VIRTFS=y" >> $config_host_mak @@ -2836,12 +3165,12 @@ fi if test "$signalfd" = "yes" ; then echo "CONFIG_SIGNALFD=y" >> $config_host_mak fi +if test "$tcg_interpreter" = "yes" ; then + echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak +fi if test "$need_offsetof" = "yes" ; then echo "CONFIG_NEED_OFFSETOF=y" >> $config_host_mak fi -if test "$gcc_attribute_warn_unused_result" = "yes" ; then - echo "CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT=y" >> $config_host_mak -fi if test "$fdatasync" = "yes" ; then echo "CONFIG_FDATASYNC=y" >> $config_host_mak fi @@ -2856,6 +3185,26 @@ if test "$spice" = "yes" ; then echo "CONFIG_SPICE=y" >> $config_host_mak fi +if test "$smartcard" = "yes" ; then + echo "CONFIG_SMARTCARD=y" >> $config_host_mak +fi + +if test "$smartcard_nss" = "yes" ; then + echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak +fi + +if test "$usb_redir" = "yes" ; then + echo "CONFIG_USB_REDIR=y" >> $config_host_mak +fi + +if test "$opengl" = "yes" ; then + echo "CONFIG_OPENGL=y" >> $config_host_mak +fi + +if test "$libiscsi" = "yes" ; then + echo "CONFIG_LIBISCSI=y" >> $config_host_mak +fi + # XXX: suppress that if [ "$bsd" = "yes" ] ; then echo "CONFIG_BSD=y" >> $config_host_mak @@ -2870,6 +3219,18 @@ if test "$rbd" = "yes" ; then echo "CONFIG_RBD=y" >> $config_host_mak fi +if test "$ucontext_coroutine" = "yes" ; then + echo "CONFIG_UCONTEXT_COROUTINE=y" >> $config_host_mak +fi + +if test "$open_by_handle_at" = "yes" ; then + echo "CONFIG_OPEN_BY_HANDLE=y" >> $config_host_mak +fi + +if test "$linux_magic_h" = "yes" ; then + echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak +fi + # USB host support case "$usb" in linux) @@ -2883,26 +3244,51 @@ bsd) ;; esac +# for TIZEN-maru +if test "$maru" = "yes" ; then + echo "CONFIG_MARU=y" >> $config_host_mak +fi +# + +# use default implementation for tracing backend-specific routines +trace_default=yes echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak -if test "$trace_backend" = "simple"; then - echo "CONFIG_SIMPLE_TRACE=y" >> $config_host_mak +if test "$trace_backend" = "nop"; then + echo "CONFIG_TRACE_NOP=y" >> $config_host_mak fi -# Set the appropriate trace file. if test "$trace_backend" = "simple"; then - trace_file="\"$trace_file-%u\"" + echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak + trace_default=no + # Set the appropriate trace file. + trace_file="\"$trace_file-\" FMT_pid" +fi +if test "$trace_backend" = "stderr"; then + echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak + trace_default=no +fi +if test "$trace_backend" = "ust"; then + echo "CONFIG_TRACE_UST=y" >> $config_host_mak fi -if test "$trace_backend" = "dtrace" -a "$trace_backend_stap" = "yes" ; then - echo "CONFIG_SYSTEMTAP_TRACE=y" >> $config_host_mak +if test "$trace_backend" = "dtrace"; then + echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak + if test "$trace_backend_stap" = "yes" ; then + echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak + fi fi echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak +if test "$trace_default" = "yes"; then + echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak +fi echo "TOOLS=$tools" >> $config_host_mak +echo "CHECKS=$checks" >> $config_host_mak echo "ROMS=$roms" >> $config_host_mak echo "MAKE=$make" >> $config_host_mak echo "INSTALL=$install" >> $config_host_mak -echo "INSTALL_DIR=$install -d -m0755 -p" >> $config_host_mak -echo "INSTALL_DATA=$install -m0644 -p" >> $config_host_mak -echo "INSTALL_PROG=$install -m0755 -p" >> $config_host_mak +echo "INSTALL_DIR=$install -d -m 0755" >> $config_host_mak +echo "INSTALL_DATA=$install -c -m 0644" >> $config_host_mak +echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak +echo "PYTHON=$python" >> $config_host_mak echo "CC=$cc" >> $config_host_mak echo "CC_I386=$cc_i386" >> $config_host_mak echo "HOST_CC=$host_cc" >> $config_host_mak @@ -2910,6 +3296,7 @@ echo "AR=$ar" >> $config_host_mak echo "OBJCOPY=$objcopy" >> $config_host_mak echo "LD=$ld" >> $config_host_mak echo "WINDRES=$windres" >> $config_host_mak +echo "LIBTOOL=$libtool" >> $config_host_mak echo "CFLAGS=$CFLAGS" >> $config_host_mak echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak echo "QEMU_INCLUDES=$QEMU_INCLUDES" >> $config_host_mak @@ -2925,6 +3312,7 @@ echo "ARLIBS_END=$arlibs_end" >> $config_host_mak echo "LIBS+=$LIBS" >> $config_host_mak echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak echo "EXESUF=$EXESUF" >> $config_host_mak +echo "LIBS_QGA+=$libs_qga" >> $config_host_mak # generate list of library paths for linker script @@ -2943,9 +3331,6 @@ for d in libdis libdis-user; do symlink $source_path/Makefile.dis $d/Makefile echo > $d/config.mak done -if test "$static" = "no" -a "$user_pie" = "yes" ; then - echo "QEMU_CFLAGS+=-fpie" > libdis-user/config.mak -fi for target in $target_list; do target_dir="$target" @@ -2954,7 +3339,7 @@ target_arch2=`echo $target | cut -d '-' -f 1` target_bigendian="no" case "$target_arch2" in - armeb|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus) + armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) target_bigendian=yes ;; esac @@ -3001,6 +3386,7 @@ mkdir -p $target_dir mkdir -p $target_dir/fpu mkdir -p $target_dir/tcg mkdir -p $target_dir/ide +mkdir -p $target_dir/9pfs if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" -o "$target" = "arm-bsd-user" -o "$target" = "armeb-bsd-user" ; then mkdir -p $target_dir/nwfpe fi @@ -3014,6 +3400,11 @@ target_nptl="no" interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_arch2/g"` echo "CONFIG_QEMU_INTERP_PREFIX=\"$interp_prefix1\"" >> $config_target_mak gdb_xml_files="" +target_short_alignment=2 +target_int_alignment=4 +target_long_alignment=4 +target_llong_alignment=8 +target_libs_softmmu= TARGET_ARCH="$target_arch2" TARGET_BASE_ARCH="" @@ -3021,14 +3412,16 @@ TARGET_ABI_DIR="" case "$target_arch2" in i386) - target_phys_bits=32 + target_phys_bits=64 ;; x86_64) TARGET_BASE_ARCH=i386 target_phys_bits=64 + target_long_alignment=8 ;; alpha) target_phys_bits=64 + target_long_alignment=8 target_nptl="yes" ;; arm|armeb) @@ -3037,20 +3430,30 @@ case "$target_arch2" in target_nptl="yes" gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml" target_phys_bits=32 + target_llong_alignment=4 ;; cris) target_nptl="yes" target_phys_bits=32 ;; + lm32) + target_phys_bits=32 + target_libs_softmmu="$opengl_libs" + ;; m68k) bflt="yes" gdb_xml_files="cf-core.xml cf-fp.xml" target_phys_bits=32 + target_int_alignment=2 + target_long_alignment=2 + target_llong_alignment=2 ;; - microblaze) + microblaze|microblazeel) + TARGET_ARCH=microblaze bflt="yes" target_nptl="yes" target_phys_bits=32 + target_libs_softmmu="$fdt_libs" ;; mips|mipsel) TARGET_ARCH=mips @@ -3069,11 +3472,13 @@ case "$target_arch2" in TARGET_BASE_ARCH=mips echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak target_phys_bits=64 + target_long_alignment=8 ;; ppc) gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml" - target_phys_bits=32 + target_phys_bits=64 target_nptl="yes" + target_libs_softmmu="$fdt_libs" ;; ppcemb) TARGET_BASE_ARCH=ppc @@ -3081,12 +3486,15 @@ case "$target_arch2" in gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml" target_phys_bits=64 target_nptl="yes" + target_libs_softmmu="$fdt_libs" ;; ppc64) TARGET_BASE_ARCH=ppc TARGET_ABI_DIR=ppc gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml" target_phys_bits=64 + target_long_alignment=8 + target_libs_softmmu="$fdt_libs" ;; ppc64abi32) TARGET_ARCH=ppc64 @@ -3095,6 +3503,7 @@ case "$target_arch2" in echo "TARGET_ABI32=y" >> $config_target_mak gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml" target_phys_bits=64 + target_libs_softmmu="$fdt_libs" ;; sh4|sh4eb) TARGET_ARCH=sh4 @@ -3108,6 +3517,7 @@ case "$target_arch2" in sparc64) TARGET_BASE_ARCH=sparc target_phys_bits=64 + target_long_alignment=8 ;; sparc32plus) TARGET_ARCH=sparc64 @@ -3117,13 +3527,26 @@ case "$target_arch2" in target_phys_bits=64 ;; s390x) + target_nptl="yes" target_phys_bits=64 + target_long_alignment=8 + ;; + unicore32) + target_phys_bits=32 + ;; + xtensa|xtensaeb) + TARGET_ARCH=xtensa + target_phys_bits=32 ;; *) echo "Unsupported target CPU" exit 1 ;; esac +echo "TARGET_SHORT_ALIGNMENT=$target_short_alignment" >> $config_target_mak +echo "TARGET_INT_ALIGNMENT=$target_int_alignment" >> $config_target_mak +echo "TARGET_LONG_ALIGNMENT=$target_long_alignment" >> $config_target_mak +echo "TARGET_LLONG_ALIGNMENT=$target_llong_alignment" >> $config_target_mak echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak target_arch_name="`echo $TARGET_ARCH | tr '[:lower:]' '[:upper:]'`" echo "TARGET_$target_arch_name=y" >> $config_target_mak @@ -3140,8 +3563,17 @@ echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak case "$target_arch2" in i386|x86_64) if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then + target_phys_bits=64 echo "CONFIG_XEN=y" >> $config_target_mak + else + echo "CONFIG_NO_XEN=y" >> $config_target_mak fi + if test "$gl" = "yes" ; then + echo "CONFIG_GL=y" >> $config_target_mak + fi + ;; + *) + echo "CONFIG_NO_XEN=y" >> $config_target_mak esac case "$target_arch2" in i386|x86_64|ppcemb|ppc|ppc64|s390x) @@ -3150,25 +3582,35 @@ case "$target_arch2" in \( "$target_arch2" = "$cpu" -o \ \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc" \) -o \ \( "$target_arch2" = "ppc64" -a "$cpu" = "ppc" \) -o \ + \( "$target_arch2" = "ppc" -a "$cpu" = "ppc64" \) -o \ + \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc64" \) -o \ \( "$target_arch2" = "x86_64" -a "$cpu" = "i386" \) -o \ \( "$target_arch2" = "i386" -a "$cpu" = "x86_64" \) \) ; then echo "CONFIG_KVM=y" >> $config_target_mak - echo "KVM_CFLAGS=$kvm_cflags" >> $config_target_mak - if test "$kvm_para" = "yes"; then - echo "CONFIG_KVM_PARA=y" >> $config_target_mak - fi - if test $vhost_net = "yes" ; then + if test "$vhost_net" = "yes" ; then echo "CONFIG_VHOST_NET=y" >> $config_target_mak fi fi esac + +case "$target_arch2" in + i386|x86_64) + if test "$hax" = "yes" ; then + echo "CONFIG_HAX=y" >> $config_target_mak + echo "CONFIG_HAX=y" >> $config_host_mak + fi +esac + +if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then + echo "CONFIG_PSERIES=y" >> $config_target_mak +fi if test "$target_bigendian" = "yes" ; then echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak fi if test "$target_softmmu" = "yes" ; then echo "TARGET_PHYS_ADDR_BITS=$target_phys_bits" >> $config_target_mak echo "CONFIG_SOFTMMU=y" >> $config_target_mak - echo "LIBS+=$libs_softmmu" >> $config_target_mak + echo "LIBS+=$libs_softmmu $target_libs_softmmu" >> $config_target_mak echo "HWDIR=../libhw$target_phys_bits" >> $config_target_mak echo "subdir-$target: subdir-libhw$target_phys_bits" >> $config_host_mak fi @@ -3181,6 +3623,11 @@ fi if test "$target_darwin_user" = "yes" ; then echo "CONFIG_DARWIN_USER=y" >> $config_target_mak fi +if test "$smartcard_nss" = "yes" ; then + echo "subdir-$target: subdir-libcacard" >> $config_host_mak + echo "libcacard_libs=$libcacard_libs" >> $config_host_mak + echo "libcacard_cflags=$libcacard_cflags" >> $config_host_mak +fi list="" if test ! -z "$gdb_xml_files" ; then for x in $gdb_xml_files; do @@ -3189,15 +3636,6 @@ if test ! -z "$gdb_xml_files" ; then echo "TARGET_XML_FILES=$list" >> $config_target_mak fi -case "$target_arch2" in - i386|x86_64) - echo "CONFIG_NOSOFTFLOAT=y" >> $config_target_mak - ;; - *) - echo "CONFIG_SOFTFLOAT=y" >> $config_target_mak - ;; -esac - if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then echo "TARGET_HAS_BFLT=y" >> $config_target_mak fi @@ -3218,7 +3656,9 @@ cflags="" includes="" ldflags="" -if test "$ARCH" = "sparc64" ; then +if test "$tcg_interpreter" = "yes"; then + includes="-I\$(SRC_PATH)/tcg/tci $includes" +elif test "$ARCH" = "sparc64" ; then includes="-I\$(SRC_PATH)/tcg/sparc $includes" elif test "$ARCH" = "s390x" ; then includes="-I\$(SRC_PATH)/tcg/s390 $includes" @@ -3228,7 +3668,6 @@ else includes="-I\$(SRC_PATH)/tcg/\$(ARCH) $includes" fi includes="-I\$(SRC_PATH)/tcg $includes" -includes="-I\$(SRC_PATH)/fpu $includes" if test "$target_user_only" = "yes" ; then libdis_config_mak=libdis-user/config.mak @@ -3266,7 +3705,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_M68K_DIS=y" >> $config_target_mak echo "CONFIG_M68K_DIS=y" >> $libdis_config_mak ;; - microblaze) + microblaze*) echo "CONFIG_MICROBLAZE_DIS=y" >> $config_target_mak echo "CONFIG_MICROBLAZE_DIS=y" >> $libdis_config_mak ;; @@ -3290,8 +3729,16 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_SPARC_DIS=y" >> $config_target_mak echo "CONFIG_SPARC_DIS=y" >> $libdis_config_mak ;; + xtensa*) + echo "CONFIG_XTENSA_DIS=y" >> $config_target_mak + echo "CONFIG_XTENSA_DIS=y" >> $libdis_config_mak + ;; esac done +if test "$tcg_interpreter" = "yes" ; then + echo "CONFIG_TCI_DIS=y" >> $config_target_mak + echo "CONFIG_TCI_DIS=y" >> $libdis_config_mak +fi case "$ARCH" in alpha) @@ -3305,18 +3752,23 @@ if test "$target_softmmu" = "yes" ; then arm) cflags="-DHAS_AUDIO $cflags" ;; + lm32) + cflags="-DHAS_AUDIO $cflags" + ;; i386|mips|ppc) cflags="-DHAS_AUDIO -DHAS_AUDIO_CHOICE $cflags" + if test "$gl" = "yes" ; then + echo "CONFIG_GL=y" >> $config_host_mak + if test "$mingw32" = "yes" ; then + echo "LIBS+=-lopengl32 -lglu32" >> $config_host_mak + else + echo "LIBS+=-lGL -lGLU -lXcomposite -lXext -ldl" >> $config_host_mak + fi + fi ;; esac fi -if test "$target_user_only" = "yes" -a "$static" = "no" -a \ - "$user_pie" = "yes" ; then - cflags="-fpie $cflags" - ldflags="-pie $ldflags" -fi - if test "$target_softmmu" = "yes" -a \( \ "$TARGET_ARCH" = "microblaze" -o \ "$TARGET_ARCH" = "cris" \) ; then @@ -3335,7 +3787,12 @@ if test "$gprof" = "yes" ; then fi fi -linker_script="-Wl,-T../config-host.ld -Wl,-T,\$(SRC_PATH)/\$(ARCH).ld" +if test "$ARCH" = "tci"; then + linker_script="" +else + linker_script="-Wl,-T../config-host.ld -Wl,-T,\$(SRC_PATH)/\$(ARCH).ld" +fi + if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then case "$ARCH" in sparc) @@ -3351,6 +3808,23 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then esac fi +# use included Linux headers +if test "$linux" = "yes" ; then + includes="-I\$(SRC_PATH)/linux-headers $includes" + mkdir -p linux-headers + case "$cpu" in + i386|x86_64) + symlink $source_path/linux-headers/asm-x86 linux-headers/asm + ;; + ppcemb|ppc|ppc64) + symlink $source_path/linux-headers/asm-powerpc linux-headers/asm + ;; + s390x) + symlink $source_path/linux-headers/asm-s390 linux-headers/asm + ;; + esac +fi + echo "LDFLAGS+=$ldflags" >> $config_target_mak echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak echo "QEMU_INCLUDES+=$includes" >> $config_target_mak @@ -3359,18 +3833,30 @@ done # for target in $targets # build tree in object directory in case the source is not in the current directory DIRS="tests tests/cris slirp audio block net pc-bios/optionrom" +DIRS="$DIRS pc-bios/spapr-rtas" DIRS="$DIRS roms/seabios roms/vgabios" DIRS="$DIRS fsdev ui" -FILES="Makefile tests/Makefile" +DIRS="$DIRS qapi qapi-generated" +DIRS="$DIRS qga trace" +FILES="Makefile tests/Makefile qdict-test-data.txt" FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit" FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps" +FILES="$FILES pc-bios/spapr-rtas/Makefile" FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile" -for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do +for bios_file in \ + $source_path/pc-bios/*.bin \ + $source_path/pc-bios/*.rom \ + $source_path/pc-bios/*.dtb \ + $source_path/pc-bios/openbios-* \ + $source_path/pc-bios/palcode-* +do FILES="$FILES pc-bios/`basename $bios_file`" done mkdir -p $DIRS for f in $FILES ; do - test -e $f || symlink $source_path/$f $f + if [ -e "$source_path/$f" ] && ! [ -e "$f" ]; then + symlink "$source_path/$f" "$f" + fi done # temporary config to build submodules @@ -3391,15 +3877,21 @@ for hwlib in 32 64; do mkdir -p $d mkdir -p $d/ide symlink $source_path/Makefile.hw $d/Makefile + mkdir -p $d/9pfs echo "QEMU_CFLAGS+=-DTARGET_PHYS_ADDR_BITS=$hwlib" > $d/config.mak done +if [ "$source_path" != `pwd` ]; then + # out of tree build + mkdir -p libcacard + rm -f libcacard/Makefile + symlink "$source_path/libcacard/Makefile" libcacard/Makefile +fi + d=libuser mkdir -p $d +mkdir -p $d/trace symlink $source_path/Makefile.user $d/Makefile -if test "$static" = "no" -a "$user_pie" = "yes" ; then - echo "QEMU_CFLAGS+=-fpie" > $d/config.mak -fi if test "$docs" = "yes" ; then mkdir -p QMP diff --git a/console.c b/console.c index 57d6eb5..ed6a653 100644 --- a/console.c +++ b/console.c @@ -115,6 +115,7 @@ typedef enum { /* ??? This is mis-named. It is used for both text and graphical consoles. */ struct TextConsole { + int index; console_type_t console_type; DisplayState *ds; /* Graphic console state. */ @@ -177,12 +178,17 @@ void vga_hw_screen_dump(const char *filename) TextConsole *previous_active_console; previous_active_console = active_console; - active_console = consoles[0]; + /* There is currently no way of specifying which screen we want to dump, so always dump the first one. */ - if (consoles[0]->hw_screen_dump) + console_select(0); + if (consoles[0] && consoles[0]->hw_screen_dump) { consoles[0]->hw_screen_dump(consoles[0]->hw, filename); - active_console = previous_active_console; + } + + if (previous_active_console) { + console_select(previous_active_console->index); + } } void vga_hw_text_update(console_ch_t *chardata) @@ -343,6 +349,7 @@ static const uint32_t dmask4[4] = { static uint32_t color_table[2][8]; +#ifndef CONFIG_CURSES enum color_names { COLOR_BLACK = 0, COLOR_RED = 1, @@ -353,6 +360,7 @@ enum color_names { COLOR_CYAN = 6, COLOR_WHITE = 7 }; +#endif static const uint32_t color_table_rgb[2][8] = { { /* dark */ @@ -461,7 +469,7 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, font_data = *font_ptr++; if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) { - font_data = 0xFFFF; + font_data = 0xFF; } ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol; ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; @@ -474,7 +482,7 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, font_data = *font_ptr++; if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) { - font_data = 0xFFFF; + font_data = 0xFF; } ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol; @@ -487,7 +495,7 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, for(i = 0; i < FONT_HEIGHT; i++) { font_data = *font_ptr++; if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) { - font_data = 0xFFFF; + font_data = 0xFF; } ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; @@ -516,7 +524,7 @@ static void text_console_resize(TextConsole *s) if (s->width < w1) w1 = s->width; - cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell)); + cells = g_malloc(s->width * s->total_height * sizeof(TextCell)); for(y = 0; y < s->total_height; y++) { c = &cells[y * s->width]; if (w1 > 0) { @@ -531,7 +539,7 @@ static void text_console_resize(TextConsole *s) c++; } } - qemu_free(s->cells); + g_free(s->cells); s->cells = cells; } @@ -1102,40 +1110,25 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) return len; } -static void console_send_event(CharDriverState *chr, int event) -{ - TextConsole *s = chr->opaque; - int i; - - if (event == CHR_EVENT_FOCUS) { - for(i = 0; i < nb_consoles; i++) { - if (consoles[i] == s) { - console_select(i); - break; - } - } - } -} - static void kbd_send_chars(void *opaque) { TextConsole *s = opaque; int len; uint8_t buf[16]; - len = qemu_chr_can_read(s->chr); + len = qemu_chr_be_can_write(s->chr); if (len > s->out_fifo.count) len = s->out_fifo.count; if (len > 0) { if (len > sizeof(buf)) len = sizeof(buf); qemu_fifo_read(&s->out_fifo, buf, len); - qemu_chr_read(s->chr, buf, len); + qemu_chr_be_write(s->chr, buf, len); } /* characters are pending: we send them a bit later (XXX: horrible, should change char device API) */ if (s->out_fifo.count > 0) { - qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1); + qemu_mod_timer(s->kbd_timer, qemu_get_clock_ms(rt_clock) + 1); } } @@ -1252,7 +1245,7 @@ static TextConsole *new_console(DisplayState *ds, console_type_t console_type) if (nb_consoles >= MAX_CONSOLES) return NULL; - s = qemu_mallocz(sizeof(TextConsole)); + s = g_malloc0(sizeof(TextConsole)); if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) && (console_type == GRAPHIC_CONSOLE))) { active_console = s; @@ -1260,6 +1253,7 @@ static TextConsole *new_console(DisplayState *ds, console_type_t console_type) s->ds = ds; s->console_type = console_type; if (console_type != GRAPHIC_CONSOLE) { + s->index = nb_consoles; consoles[nb_consoles++] = s; } else { /* HACK: Put graphical consoles before text consoles. */ @@ -1267,7 +1261,9 @@ static TextConsole *new_console(DisplayState *ds, console_type_t console_type) if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE) break; consoles[i] = consoles[i - 1]; + consoles[i]->index = i; } + s->index = i; consoles[i] = s; nb_consoles++; } @@ -1276,46 +1272,48 @@ static TextConsole *new_console(DisplayState *ds, console_type_t console_type) static DisplaySurface* defaultallocator_create_displaysurface(int width, int height) { - DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface)); - - surface->width = width; - surface->height = height; - surface->linesize = width * 4; - surface->pf = qemu_default_pixelformat(32); -#ifdef HOST_WORDS_BIGENDIAN - surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG; -#else - surface->flags = QEMU_ALLOCATED_FLAG; -#endif - surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height); + DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface)); + int linesize = width * 4; + qemu_alloc_display(surface, width, height, linesize, + qemu_default_pixelformat(32), 0); return surface; } static DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface, int width, int height) { + int linesize = width * 4; + qemu_alloc_display(surface, width, height, linesize, + qemu_default_pixelformat(32), 0); + return surface; +} + +void qemu_alloc_display(DisplaySurface *surface, int width, int height, + int linesize, PixelFormat pf, int newflags) +{ + void *data; surface->width = width; surface->height = height; - surface->linesize = width * 4; - surface->pf = qemu_default_pixelformat(32); - if (surface->flags & QEMU_ALLOCATED_FLAG) - surface->data = (uint8_t*) qemu_realloc(surface->data, surface->linesize * surface->height); - else - surface->data = (uint8_t*) qemu_malloc(surface->linesize * surface->height); + surface->linesize = linesize; + surface->pf = pf; + if (surface->flags & QEMU_ALLOCATED_FLAG) { + data = g_realloc(surface->data, + surface->linesize * surface->height); + } else { + data = g_malloc(surface->linesize * surface->height); + } + surface->data = (uint8_t *)data; + surface->flags = newflags | QEMU_ALLOCATED_FLAG; #ifdef HOST_WORDS_BIGENDIAN - surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG; -#else - surface->flags = QEMU_ALLOCATED_FLAG; + surface->flags |= QEMU_BIG_ENDIAN_FLAG; #endif - - return surface; } DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp, int linesize, uint8_t *data) { - DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface)); + DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface)); surface->width = width; surface->height = height; @@ -1334,8 +1332,8 @@ static void defaultallocator_free_displaysurface(DisplaySurface *surface) if (surface == NULL) return; if (surface->flags & QEMU_ALLOCATED_FLAG) - qemu_free(surface->data); - qemu_free(surface); + g_free(surface->data); + g_free(surface); } static struct DisplayAllocator default_allocator = { @@ -1346,9 +1344,16 @@ static struct DisplayAllocator default_allocator = { static void dumb_display_init(void) { - DisplayState *ds = qemu_mallocz(sizeof(DisplayState)); + DisplayState *ds = g_malloc0(sizeof(DisplayState)); + int width = 640; + int height = 480; + ds->allocator = &default_allocator; - ds->surface = qemu_create_displaysurface(ds, 640, 480); + if (is_fixedsize_console()) { + width = active_console->g_width; + height = active_console->g_height; + } + ds->surface = qemu_create_displaysurface(ds, width, height); register_displaystate(ds); } @@ -1394,14 +1399,14 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update, TextConsole *s; DisplayState *ds; - ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState)); + ds = (DisplayState *) g_malloc0(sizeof(DisplayState)); ds->allocator = &default_allocator; ds->surface = qemu_create_displaysurface(ds, 640, 480); s = new_console(ds, GRAPHIC_CONSOLE); if (s == NULL) { qemu_free_displaysurface(ds); - qemu_free(ds); + g_free(ds); return NULL; } s->hw_update = update; @@ -1453,11 +1458,10 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds) s = chr->opaque; chr->chr_write = console_puts; - chr->chr_send_event = console_send_event; s->out_fifo.buf = s->out_fifo_buf; s->out_fifo.buf_size = sizeof(s->out_fifo_buf); - s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s); + s->kbd_timer = qemu_new_timer_ms(rt_clock, kbd_send_chars, s); s->ds = ds; if (!color_inited) { @@ -1505,14 +1509,14 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds) chr->init(chr); } -CharDriverState *text_console_init(QemuOpts *opts) +int text_console_init(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; TextConsole *s; unsigned width; unsigned height; - chr = qemu_mallocz(sizeof(CharDriverState)); + chr = g_malloc0(sizeof(CharDriverState)); if (n_text_consoles == 128) { fprintf(stderr, "Too many text consoles\n"); @@ -1536,8 +1540,8 @@ CharDriverState *text_console_init(QemuOpts *opts) } if (!s) { - free(chr); - return NULL; + g_free(chr); + return -EBUSY; } s->chr = chr; @@ -1545,7 +1549,9 @@ CharDriverState *text_console_init(QemuOpts *opts) s->g_height = height; chr->opaque = s; chr->chr_set_echo = text_console_set_echo; - return chr; + + *_chr = chr; + return 0; } void text_consoles_set_display(DisplayState *ds) diff --git a/console.h b/console.h index ed88432..3f490f5 100644 --- a/console.h +++ b/console.h @@ -4,6 +4,8 @@ #include "qemu-char.h" #include "qdict.h" #include "notify.h" +#include "qerror.h" +#include "monitor.h" /* keyboard/mouse support */ @@ -43,8 +45,6 @@ typedef struct QEMUPutLEDEntry { void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); void qemu_remove_kbd_event_handler(void); -void qemu_add_ps2kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); -void qemu_remove_ps2kbd_event_handler(void); QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute, const char *name); @@ -55,7 +55,11 @@ QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, void *opaque) void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry); void kbd_put_keycode(int keycode); +#ifdef CONFIG_MARU +void qemu_add_ps2kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); +void qemu_remove_ps2kbd_event_handler(void); void ps2kbd_put_keycode(int keycode); +#endif void kbd_put_ledstate(int ledstate); void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); @@ -110,7 +114,7 @@ void kbd_put_keysym(int keysym); #define QEMU_ALLOCATED_FLAG 0x02 #define QEMU_REALPIXELS_FLAG 0x04 -struct QEMU_PixelFormat { +struct PixelFormat { uint8_t bits_per_pixel; uint8_t bytes_per_pixel; uint8_t depth; /* color depth in bits */ @@ -127,7 +131,7 @@ struct DisplaySurface { int linesize; /* bytes per line */ uint8_t *data; - struct QEMU_PixelFormat pf; + struct PixelFormat pf; }; /* cursor data format is 32bit RGBA */ @@ -192,6 +196,8 @@ void register_displaystate(DisplayState *ds); DisplayState *get_displaystate(void); DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp, int linesize, uint8_t *data); +void qemu_alloc_display(DisplaySurface *surface, int width, int height, + int linesize, PixelFormat pf, int newflags); PixelFormat qemu_different_endianness_pixelformat(int bpp); PixelFormat qemu_default_pixelformat(int bpp); @@ -327,7 +333,12 @@ static inline int ds_get_bytes_per_pixel(DisplayState *ds) return ds->surface->pf.bytes_per_pixel; } +#ifdef CONFIG_CURSES +#include +typedef chtype console_ch_t; +#else typedef unsigned long console_ch_t; +#endif static inline void console_write_ch(console_ch_t *dest, uint32_t ch) { if (!(ch & 0xff)) @@ -353,7 +364,7 @@ void vga_hw_text_update(console_ch_t *chardata); int is_graphic_console(void); int is_fixedsize_console(void); -CharDriverState *text_console_init(QemuOpts *opts); +int text_console_init(QemuOpts *opts, CharDriverState **_chr); void text_consoles_set_display(DisplayState *ds); void console_select(unsigned int index); void console_color_init(DisplayState *ds); @@ -363,9 +374,6 @@ void qemu_console_copy(DisplayState *ds, int src_x, int src_y, /* sdl.c */ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame); -void sdl_display_set_rotation(int rot); -void sdl_display_set_window_size(int w, int h); -void sdl_display_force_refresh(void); /* cocoa.m */ void cocoa_display_init(DisplayState *ds, int full_screen); @@ -374,12 +382,24 @@ void cocoa_display_init(DisplayState *ds, int full_screen); void vnc_display_init(DisplayState *ds); void vnc_display_close(DisplayState *ds); int vnc_display_open(DisplayState *ds, const char *display); -int vnc_display_password(DisplayState *ds, const char *password); +void vnc_display_add_client(DisplayState *ds, int csock, int skipauth); int vnc_display_disable_login(DisplayState *ds); -int vnc_display_pw_expire(DisplayState *ds, time_t expires); -void do_info_vnc_print(Monitor *mon, const QObject *data); -void do_info_vnc(Monitor *mon, QObject **ret_data); char *vnc_display_local_addr(DisplayState *ds); +#ifdef CONFIG_VNC +int vnc_display_password(DisplayState *ds, const char *password); +int vnc_display_pw_expire(DisplayState *ds, time_t expires); +#else +static inline int vnc_display_password(DisplayState *ds, const char *password) +{ + qerror_report(QERR_FEATURE_DISABLED, "vnc"); + return -ENODEV; +} +static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires) +{ + qerror_report(QERR_FEATURE_DISABLED, "vnc"); + return -ENODEV; +}; +#endif /* curses.c */ void curses_display_init(DisplayState *ds, int full_screen); diff --git a/cpu-all.h b/cpu-all.h index ffbd6a4..5f47ab8 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -20,6 +20,7 @@ #define CPU_ALL_H #include "qemu-common.h" +#include "qemu-tls.h" #include "cpu-common.h" /* some important defines: @@ -35,8 +36,6 @@ * TARGET_WORDS_BIGENDIAN : same for target cpu */ -#include "softfloat.h" - #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) #define BSWAP_NEEDED #endif @@ -114,60 +113,6 @@ static inline void tswap64s(uint64_t *s) #define bswaptls(s) bswap64s(s) #endif -typedef union { - float32 f; - uint32_t l; -} CPU_FloatU; - -/* NOTE: arm FPA is horrible as double 32 bit words are stored in big - endian ! */ -typedef union { - float64 d; -#if defined(HOST_WORDS_BIGENDIAN) \ - || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT)) - struct { - uint32_t upper; - uint32_t lower; - } l; -#else - struct { - uint32_t lower; - uint32_t upper; - } l; -#endif - uint64_t ll; -} CPU_DoubleU; - -#ifdef TARGET_SPARC -typedef union { - float128 q; -#if defined(HOST_WORDS_BIGENDIAN) \ - || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT)) - struct { - uint32_t upmost; - uint32_t upper; - uint32_t lower; - uint32_t lowest; - } l; - struct { - uint64_t upper; - uint64_t lower; - } ll; -#else - struct { - uint32_t lowest; - uint32_t lower; - uint32_t upper; - uint32_t upmost; - } l; - struct { - uint64_t lower; - uint64_t upper; - } ll; -#endif -} CPU_QuadU; -#endif - /* CPU memory access without any memory or io remapping */ /* @@ -203,392 +148,8 @@ typedef union { * user : user mode access using soft MMU * kernel : kernel mode access using soft MMU */ -static inline int ldub_p(const void *ptr) -{ - return *(uint8_t *)ptr; -} - -static inline int ldsb_p(const void *ptr) -{ - return *(int8_t *)ptr; -} - -static inline void stb_p(void *ptr, int v) -{ - *(uint8_t *)ptr = v; -} - -/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the - kernel handles unaligned load/stores may give better results, but - it is a system wide setting : bad */ -#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED) - -/* conservative code for little endian unaligned accesses */ -static inline int lduw_le_p(const void *ptr) -{ -#ifdef _ARCH_PPC - int val; - __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); - return val; -#else - const uint8_t *p = ptr; - return p[0] | (p[1] << 8); -#endif -} - -static inline int ldsw_le_p(const void *ptr) -{ -#ifdef _ARCH_PPC - int val; - __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); - return (int16_t)val; -#else - const uint8_t *p = ptr; - return (int16_t)(p[0] | (p[1] << 8)); -#endif -} - -static inline int ldl_le_p(const void *ptr) -{ -#ifdef _ARCH_PPC - int val; - __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); - return val; -#else - const uint8_t *p = ptr; - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -#endif -} - -static inline uint64_t ldq_le_p(const void *ptr) -{ - const uint8_t *p = ptr; - uint32_t v1, v2; - v1 = ldl_le_p(p); - v2 = ldl_le_p(p + 4); - return v1 | ((uint64_t)v2 << 32); -} - -static inline void stw_le_p(void *ptr, int v) -{ -#ifdef _ARCH_PPC - __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); -#else - uint8_t *p = ptr; - p[0] = v; - p[1] = v >> 8; -#endif -} - -static inline void stl_le_p(void *ptr, int v) -{ -#ifdef _ARCH_PPC - __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); -#else - uint8_t *p = ptr; - p[0] = v; - p[1] = v >> 8; - p[2] = v >> 16; - p[3] = v >> 24; -#endif -} - -static inline void stq_le_p(void *ptr, uint64_t v) -{ - uint8_t *p = ptr; - stl_le_p(p, (uint32_t)v); - stl_le_p(p + 4, v >> 32); -} - -/* float access */ - -static inline float32 ldfl_le_p(const void *ptr) -{ - union { - float32 f; - uint32_t i; - } u; - u.i = ldl_le_p(ptr); - return u.f; -} - -static inline void stfl_le_p(void *ptr, float32 v) -{ - union { - float32 f; - uint32_t i; - } u; - u.f = v; - stl_le_p(ptr, u.i); -} - -static inline float64 ldfq_le_p(const void *ptr) -{ - CPU_DoubleU u; - u.l.lower = ldl_le_p(ptr); - u.l.upper = ldl_le_p(ptr + 4); - return u.d; -} - -static inline void stfq_le_p(void *ptr, float64 v) -{ - CPU_DoubleU u; - u.d = v; - stl_le_p(ptr, u.l.lower); - stl_le_p(ptr + 4, u.l.upper); -} - -#else - -static inline int lduw_le_p(const void *ptr) -{ - return *(uint16_t *)ptr; -} - -static inline int ldsw_le_p(const void *ptr) -{ - return *(int16_t *)ptr; -} - -static inline int ldl_le_p(const void *ptr) -{ - return *(uint32_t *)ptr; -} - -static inline uint64_t ldq_le_p(const void *ptr) -{ - return *(uint64_t *)ptr; -} - -static inline void stw_le_p(void *ptr, int v) -{ - *(uint16_t *)ptr = v; -} - -static inline void stl_le_p(void *ptr, int v) -{ - *(uint32_t *)ptr = v; -} - -static inline void stq_le_p(void *ptr, uint64_t v) -{ - *(uint64_t *)ptr = v; -} - -/* float access */ - -static inline float32 ldfl_le_p(const void *ptr) -{ - return *(float32 *)ptr; -} - -static inline float64 ldfq_le_p(const void *ptr) -{ - return *(float64 *)ptr; -} - -static inline void stfl_le_p(void *ptr, float32 v) -{ - *(float32 *)ptr = v; -} - -static inline void stfq_le_p(void *ptr, float64 v) -{ - *(float64 *)ptr = v; -} -#endif - -#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED) - -static inline int lduw_be_p(const void *ptr) -{ -#if defined(__i386__) - int val; - asm volatile ("movzwl %1, %0\n" - "xchgb %b0, %h0\n" - : "=q" (val) - : "m" (*(uint16_t *)ptr)); - return val; -#else - const uint8_t *b = ptr; - return ((b[0] << 8) | b[1]); -#endif -} - -static inline int ldsw_be_p(const void *ptr) -{ -#if defined(__i386__) - int val; - asm volatile ("movzwl %1, %0\n" - "xchgb %b0, %h0\n" - : "=q" (val) - : "m" (*(uint16_t *)ptr)); - return (int16_t)val; -#else - const uint8_t *b = ptr; - return (int16_t)((b[0] << 8) | b[1]); -#endif -} - -static inline int ldl_be_p(const void *ptr) -{ -#if defined(__i386__) || defined(__x86_64__) - int val; - asm volatile ("movl %1, %0\n" - "bswap %0\n" - : "=r" (val) - : "m" (*(uint32_t *)ptr)); - return val; -#else - const uint8_t *b = ptr; - return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; -#endif -} - -static inline uint64_t ldq_be_p(const void *ptr) -{ - uint32_t a,b; - a = ldl_be_p(ptr); - b = ldl_be_p((uint8_t *)ptr + 4); - return (((uint64_t)a<<32)|b); -} - -static inline void stw_be_p(void *ptr, int v) -{ -#if defined(__i386__) - asm volatile ("xchgb %b0, %h0\n" - "movw %w0, %1\n" - : "=q" (v) - : "m" (*(uint16_t *)ptr), "0" (v)); -#else - uint8_t *d = (uint8_t *) ptr; - d[0] = v >> 8; - d[1] = v; -#endif -} - -static inline void stl_be_p(void *ptr, int v) -{ -#if defined(__i386__) || defined(__x86_64__) - asm volatile ("bswap %0\n" - "movl %0, %1\n" - : "=r" (v) - : "m" (*(uint32_t *)ptr), "0" (v)); -#else - uint8_t *d = (uint8_t *) ptr; - d[0] = v >> 24; - d[1] = v >> 16; - d[2] = v >> 8; - d[3] = v; -#endif -} - -static inline void stq_be_p(void *ptr, uint64_t v) -{ - stl_be_p(ptr, v >> 32); - stl_be_p((uint8_t *)ptr + 4, v); -} - -/* float access */ - -static inline float32 ldfl_be_p(const void *ptr) -{ - union { - float32 f; - uint32_t i; - } u; - u.i = ldl_be_p(ptr); - return u.f; -} - -static inline void stfl_be_p(void *ptr, float32 v) -{ - union { - float32 f; - uint32_t i; - } u; - u.f = v; - stl_be_p(ptr, u.i); -} - -static inline float64 ldfq_be_p(const void *ptr) -{ - CPU_DoubleU u; - u.l.upper = ldl_be_p(ptr); - u.l.lower = ldl_be_p((uint8_t *)ptr + 4); - return u.d; -} - -static inline void stfq_be_p(void *ptr, float64 v) -{ - CPU_DoubleU u; - u.d = v; - stl_be_p(ptr, u.l.upper); - stl_be_p((uint8_t *)ptr + 4, u.l.lower); -} - -#else - -static inline int lduw_be_p(const void *ptr) -{ - return *(uint16_t *)ptr; -} - -static inline int ldsw_be_p(const void *ptr) -{ - return *(int16_t *)ptr; -} -static inline int ldl_be_p(const void *ptr) -{ - return *(uint32_t *)ptr; -} - -static inline uint64_t ldq_be_p(const void *ptr) -{ - return *(uint64_t *)ptr; -} - -static inline void stw_be_p(void *ptr, int v) -{ - *(uint16_t *)ptr = v; -} - -static inline void stl_be_p(void *ptr, int v) -{ - *(uint32_t *)ptr = v; -} - -static inline void stq_be_p(void *ptr, uint64_t v) -{ - *(uint64_t *)ptr = v; -} - -/* float access */ - -static inline float32 ldfl_be_p(const void *ptr) -{ - return *(float32 *)ptr; -} - -static inline float64 ldfq_be_p(const void *ptr) -{ - return *(float64 *)ptr; -} - -static inline void stfl_be_p(void *ptr, float32 v) -{ - *(float32 *)ptr = v; -} - -static inline void stfq_be_p(void *ptr, float64 v) -{ - *(float64 *)ptr = v; -} - -#endif - -/* target CPU memory access functions */ +/* target-endianness CPU memory access functions */ #if defined(TARGET_WORDS_BIGENDIAN) #define lduw_p(p) lduw_be_p(p) #define ldsw_p(p) ldsw_be_p(p) @@ -730,7 +291,6 @@ extern unsigned long reserved_va; /* ??? These should be the larger of unsigned long and target_ulong. */ extern unsigned long qemu_real_host_page_size; -extern unsigned long qemu_host_page_bits; extern unsigned long qemu_host_page_size; extern unsigned long qemu_host_page_mask; @@ -775,27 +335,76 @@ void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf, void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...) GCC_FMT_ATTR(2, 3); extern CPUState *first_cpu; -extern CPUState *cpu_single_env; - -#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */ -#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */ -#define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */ -#define CPU_INTERRUPT_FIQ 0x10 /* Fast interrupt pending. */ -#define CPU_INTERRUPT_HALT 0x20 /* CPU halt wanted */ -#define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */ -#define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */ -#define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */ -#define CPU_INTERRUPT_NMI 0x200 /* NMI pending. */ -#define CPU_INTERRUPT_INIT 0x400 /* INIT pending. */ -#define CPU_INTERRUPT_SIPI 0x800 /* SIPI pending. */ -#define CPU_INTERRUPT_MCE 0x1000 /* (x86 only) MCE pending. */ - -void cpu_interrupt(CPUState *s, int mask); +DECLARE_TLS(CPUState *,cpu_single_env); +#define cpu_single_env get_tls(cpu_single_env) + +/* Flags for use in ENV->INTERRUPT_PENDING. + + The numbers assigned here are non-sequential in order to preserve + binary compatibility with the vmstate dump. Bit 0 (0x0001) was + previously used for CPU_INTERRUPT_EXIT, and is cleared when loading + the vmstate dump. */ + +/* External hardware interrupt pending. This is typically used for + interrupts from devices. */ +#define CPU_INTERRUPT_HARD 0x0002 + +/* Exit the current TB. This is typically used when some system-level device + makes some change to the memory mapping. E.g. the a20 line change. */ +#define CPU_INTERRUPT_EXITTB 0x0004 + +/* Halt the CPU. */ +#define CPU_INTERRUPT_HALT 0x0020 + +/* Debug event pending. */ +#define CPU_INTERRUPT_DEBUG 0x0080 + +/* Several target-specific external hardware interrupts. Each target/cpu.h + should define proper names based on these defines. */ +#define CPU_INTERRUPT_TGT_EXT_0 0x0008 +#define CPU_INTERRUPT_TGT_EXT_1 0x0010 +#define CPU_INTERRUPT_TGT_EXT_2 0x0040 +#define CPU_INTERRUPT_TGT_EXT_3 0x0200 +#define CPU_INTERRUPT_TGT_EXT_4 0x1000 + +/* Several target-specific internal interrupts. These differ from the + preceeding target-specific interrupts in that they are intended to + originate from within the cpu itself, typically in response to some + instruction being executed. These, therefore, are not masked while + single-stepping within the debugger. */ +#define CPU_INTERRUPT_TGT_INT_0 0x0100 +#define CPU_INTERRUPT_TGT_INT_1 0x0400 +#define CPU_INTERRUPT_TGT_INT_2 0x0800 + +/* First unused bit: 0x2000. */ + +/* The set of all bits that should be masked when single-stepping. */ +#define CPU_INTERRUPT_SSTEP_MASK \ + (CPU_INTERRUPT_HARD \ + | CPU_INTERRUPT_TGT_EXT_0 \ + | CPU_INTERRUPT_TGT_EXT_1 \ + | CPU_INTERRUPT_TGT_EXT_2 \ + | CPU_INTERRUPT_TGT_EXT_3 \ + | CPU_INTERRUPT_TGT_EXT_4) + +#ifndef CONFIG_USER_ONLY +typedef void (*CPUInterruptHandler)(CPUState *, int); + +extern CPUInterruptHandler cpu_interrupt_handler; + +static inline void cpu_interrupt(CPUState *s, int mask) +{ + cpu_interrupt_handler(s, mask); +} +#else /* USER_ONLY */ +void cpu_interrupt(CPUState *env, int mask); +#endif /* USER_ONLY */ + void cpu_reset_interrupt(CPUState *env, int mask); void cpu_exit(CPUState *s); -int qemu_cpu_has_work(CPUState *env); +bool qemu_cpu_has_work(CPUState *env); /* Breakpoint/watchpoint flags */ #define BP_MEM_READ 0x01 @@ -863,10 +472,14 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr); extern int phys_ram_fd; extern ram_addr_t ram_size; +/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */ +#define RAM_PREALLOC_MASK (1 << 0) + typedef struct RAMBlock { uint8_t *host; ram_addr_t offset; ram_addr_t length; + uint32_t flags; char idstr[256]; QLIST_ENTRY(RAMBlock) next; #if defined(__linux__) && !defined(TARGET_S390X) @@ -876,7 +489,7 @@ typedef struct RAMBlock { typedef struct RAMList { uint8_t *phys_dirty; - QLIST_HEAD(ram, RAMBlock) blocks; + QLIST_HEAD(, RAMBlock) blocks; } RAMList; extern RAMList ram_list; @@ -959,14 +572,16 @@ int cpu_physical_memory_get_dirty_tracking(void); int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, target_phys_addr_t end_addr); +int cpu_physical_log_start(target_phys_addr_t start_addr, + ram_addr_t size); + +int cpu_physical_log_stop(target_phys_addr_t start_addr, + ram_addr_t size); + void dump_exec_info(FILE *f, fprintf_function cpu_fprintf); #endif /* !CONFIG_USER_ONLY */ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, uint8_t *buf, int len, int is_write); -void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, - uint64_t mcg_status, uint64_t addr, uint64_t misc, - int broadcast); - #endif /* CPU_ALL_H */ diff --git a/cpu-common.h b/cpu-common.h index 6d4a898..3f45428 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -3,10 +3,6 @@ /* CPU interfaces that are target indpendent. */ -#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__) -#define WORDS_ALIGNED -#endif - #ifdef TARGET_PHYS_ADDR_BITS #include "targphys.h" #endif @@ -27,17 +23,36 @@ enum device_endian { }; /* address in the RAM (different from a physical address) */ +#if defined(CONFIG_XEN_BACKEND) && TARGET_PHYS_ADDR_BITS == 64 +typedef uint64_t ram_addr_t; +# define RAM_ADDR_MAX UINT64_MAX +# define RAM_ADDR_FMT "%" PRIx64 +#else typedef unsigned long ram_addr_t; +# define RAM_ADDR_MAX ULONG_MAX +# define RAM_ADDR_FMT "%lx" +#endif /* memory API */ typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); -void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, - ram_addr_t size, - ram_addr_t phys_offset, - ram_addr_t region_offset); +void cpu_register_physical_memory_log(target_phys_addr_t start_addr, + ram_addr_t size, + ram_addr_t phys_offset, + ram_addr_t region_offset, + bool log_dirty); + +static inline void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, + ram_addr_t size, + ram_addr_t phys_offset, + ram_addr_t region_offset) +{ + cpu_register_physical_memory_log(start_addr, size, phys_offset, + region_offset, false); +} + static inline void cpu_register_physical_memory(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) @@ -50,11 +65,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, ram_addr_t size, void *host); ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size); void qemu_ram_free(ram_addr_t addr); +void qemu_ram_free_from_ptr(ram_addr_t addr); +void qemu_ram_remap(ram_addr_t addr, ram_addr_t length); /* This should only be used for ram local to a device. */ void *qemu_get_ram_ptr(ram_addr_t addr); +void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size); /* Same but slower, to use for migration, where the order of * RAMBlocks must not change. */ void *qemu_safe_ram_ptr(ram_addr_t addr); +void qemu_put_ram_ptr(void *addr); /* This should not be used by devices. */ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr); ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr); @@ -67,14 +86,14 @@ void cpu_unregister_io_memory(int table_address); void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write); static inline void cpu_physical_memory_read(target_phys_addr_t addr, - uint8_t *buf, int len) + void *buf, int len) { cpu_physical_memory_rw(addr, buf, len, 0); } static inline void cpu_physical_memory_write(target_phys_addr_t addr, - const uint8_t *buf, int len) + const void *buf, int len) { - cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1); + cpu_physical_memory_rw(addr, (void *)buf, len, 1); } void *cpu_physical_memory_map(target_phys_addr_t addr, target_phys_addr_t *plen, @@ -90,12 +109,17 @@ struct CPUPhysMemoryClient { void (*set_memory)(struct CPUPhysMemoryClient *client, target_phys_addr_t start_addr, ram_addr_t size, - ram_addr_t phys_offset); + ram_addr_t phys_offset, + bool log_dirty); int (*sync_dirty_bitmap)(struct CPUPhysMemoryClient *client, target_phys_addr_t start_addr, target_phys_addr_t end_addr); int (*migration_log)(struct CPUPhysMemoryClient *client, int enable); + int (*log_start)(struct CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size); + int (*log_stop)(struct CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size); QLIST_ENTRY(CPUPhysMemoryClient) list; }; @@ -114,15 +138,30 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size); void qemu_flush_coalesced_mmio_buffer(void); uint32_t ldub_phys(target_phys_addr_t addr); +uint32_t lduw_le_phys(target_phys_addr_t addr); +uint32_t lduw_be_phys(target_phys_addr_t addr); +uint32_t ldl_le_phys(target_phys_addr_t addr); +uint32_t ldl_be_phys(target_phys_addr_t addr); +uint64_t ldq_le_phys(target_phys_addr_t addr); +uint64_t ldq_be_phys(target_phys_addr_t addr); +void stb_phys(target_phys_addr_t addr, uint32_t val); +void stw_le_phys(target_phys_addr_t addr, uint32_t val); +void stw_be_phys(target_phys_addr_t addr, uint32_t val); +void stl_le_phys(target_phys_addr_t addr, uint32_t val); +void stl_be_phys(target_phys_addr_t addr, uint32_t val); +void stq_le_phys(target_phys_addr_t addr, uint64_t val); +void stq_be_phys(target_phys_addr_t addr, uint64_t val); + +#ifdef NEED_CPU_H uint32_t lduw_phys(target_phys_addr_t addr); uint32_t ldl_phys(target_phys_addr_t addr); uint64_t ldq_phys(target_phys_addr_t addr); void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val); void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val); -void stb_phys(target_phys_addr_t addr, uint32_t val); void stw_phys(target_phys_addr_t addr, uint32_t val); void stl_phys(target_phys_addr_t addr, uint32_t val); void stq_phys(target_phys_addr_t addr, uint64_t val); +#endif void cpu_physical_memory_write_rom(target_phys_addr_t addr, const uint8_t *buf, int len); @@ -133,6 +172,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) #define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT) +#define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT) /* Acts like a ROM when read and like a device when written. */ #define IO_MEM_ROMD (1) diff --git a/cpu-defs.h b/cpu-defs.h index 8d4bf86..5e22d83 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -37,16 +37,22 @@ #define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8) +typedef int16_t target_short __attribute__ ((aligned(TARGET_SHORT_ALIGNMENT))); +typedef uint16_t target_ushort __attribute__((aligned(TARGET_SHORT_ALIGNMENT))); +typedef int32_t target_int __attribute__((aligned(TARGET_INT_ALIGNMENT))); +typedef uint32_t target_uint __attribute__((aligned(TARGET_INT_ALIGNMENT))); +typedef int64_t target_llong __attribute__((aligned(TARGET_LLONG_ALIGNMENT))); +typedef uint64_t target_ullong __attribute__((aligned(TARGET_LLONG_ALIGNMENT))); /* target_ulong is the type of a virtual address */ #if TARGET_LONG_SIZE == 4 -typedef int32_t target_long; -typedef uint32_t target_ulong; +typedef int32_t target_long __attribute__((aligned(TARGET_LONG_ALIGNMENT))); +typedef uint32_t target_ulong __attribute__((aligned(TARGET_LONG_ALIGNMENT))); #define TARGET_FMT_lx "%08x" #define TARGET_FMT_ld "%d" #define TARGET_FMT_lu "%u" #elif TARGET_LONG_SIZE == 8 -typedef int64_t target_long; -typedef uint64_t target_ulong; +typedef int64_t target_long __attribute__((aligned(TARGET_LONG_ALIGNMENT))); +typedef uint64_t target_ulong __attribute__((aligned(TARGET_LONG_ALIGNMENT))); #define TARGET_FMT_lx "%016" PRIx64 #define TARGET_FMT_ld "%" PRId64 #define TARGET_FMT_lu "%" PRIu64 @@ -197,6 +203,7 @@ typedef struct CPUWatchpoint { int nr_cores; /* number of cores within this CPU package */ \ int nr_threads;/* number of threads within this CPU */ \ int running; /* Nonzero if cpu is currently running(usermode). */ \ + int thread_id; \ /* user data */ \ void *opaque; \ \ @@ -205,11 +212,14 @@ typedef struct CPUWatchpoint { uint32_t stopped; /* Artificially stopped */ \ struct QemuThread *thread; \ struct QemuCond *halt_cond; \ + int thread_kicked; \ struct qemu_work_item *queued_work_first, *queued_work_last; \ const char *cpu_model_str; \ struct KVMState *kvm_state; \ struct kvm_run *kvm_run; \ int kvm_fd; \ - int kvm_vcpu_dirty; + int kvm_vcpu_dirty; \ + int hax_vcpu_dirty; \ + struct hax_vcpu_state *hax_vcpu; #endif diff --git a/cpu-exec.c b/cpu-exec.c index 8c9fb8b..989f28e 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -17,45 +17,22 @@ * License along with this library; if not, see . */ #include "config.h" -#include "exec.h" +#include "cpu.h" #include "disas.h" #include "tcg.h" -#include "kvm.h" +#include "hax.h" #include "qemu-barrier.h" -#if !defined(CONFIG_SOFTMMU) -#undef EAX -#undef ECX -#undef EDX -#undef EBX -#undef ESP -#undef EBP -#undef ESI -#undef EDI -#undef EIP -#include -#ifdef __linux__ -#include -#endif -#endif - -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -// Work around ugly bugs in glibc that mangle global register contents -#undef env -#define env cpu_single_env -#endif - int tb_invalidated_flag; //#define CONFIG_DEBUG_EXEC -//#define DEBUG_SIGNAL -int qemu_cpu_has_work(CPUState *env) +bool qemu_cpu_has_work(CPUState *env) { return cpu_has_work(env); } -void cpu_loop_exit(void) +void cpu_loop_exit(CPUState *env) { env->current_tb = NULL; longjmp(env->jmp_env, 1); @@ -64,41 +41,20 @@ void cpu_loop_exit(void) /* exit the current TB from a signal handler. The host registers are restored in a state compatible with the CPU emulator */ -void cpu_resume_from_signal(CPUState *env1, void *puc) +#if defined(CONFIG_SOFTMMU) +void cpu_resume_from_signal(CPUState *env, void *puc) { -#if !defined(CONFIG_SOFTMMU) -#ifdef __linux__ - struct ucontext *uc = puc; -#elif defined(__OpenBSD__) - struct sigcontext *uc = puc; -#endif -#endif - - env = env1; - /* XXX: restore cpu registers saved in host registers */ -#if !defined(CONFIG_SOFTMMU) - if (puc) { - /* XXX: use siglongjmp ? */ -#ifdef __linux__ -#ifdef __ia64 - sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL); -#else - sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); -#endif -#elif defined(__OpenBSD__) - sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL); -#endif - } -#endif env->exception_index = -1; longjmp(env->jmp_env, 1); } +#endif /* Execute the code without caching the generated code. An interpreter could be used if available. */ -static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb) +static void cpu_exec_nocache(CPUState *env, int max_cycles, + TranslationBlock *orig_tb) { unsigned long next_tb; TranslationBlock *tb; @@ -112,7 +68,7 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb) max_cycles); env->current_tb = tb; /* execute the generated code */ - next_tb = tcg_qemu_tb_exec(tb->tc_ptr); + next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr); env->current_tb = NULL; if ((next_tb & 3) == 2) { @@ -124,13 +80,14 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb) tb_free(tb); } -static TranslationBlock *tb_find_slow(target_ulong pc, +static TranslationBlock *tb_find_slow(CPUState *env, + target_ulong pc, target_ulong cs_base, uint64_t flags) { TranslationBlock *tb, **ptb1; unsigned int h; - tb_page_addr_t phys_pc, phys_page1, phys_page2; + tb_page_addr_t phys_pc, phys_page1; target_ulong virt_page2; tb_invalidated_flag = 0; @@ -138,7 +95,6 @@ static TranslationBlock *tb_find_slow(target_ulong pc, /* find translated block using physical mappings */ phys_pc = get_page_addr_code(env, pc); phys_page1 = phys_pc & TARGET_PAGE_MASK; - phys_page2 = -1; h = tb_phys_hash_func(phys_pc); ptb1 = &tb_phys_hash[h]; for(;;) { @@ -151,6 +107,8 @@ static TranslationBlock *tb_find_slow(target_ulong pc, tb->flags == flags) { /* check next page if needed */ if (tb->page_addr[1] != -1) { + tb_page_addr_t phys_page2; + virt_page2 = (pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; phys_page2 = get_page_addr_code(env, virt_page2); @@ -178,7 +136,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc, return tb; } -static inline TranslationBlock *tb_find_fast(void) +static inline TranslationBlock *tb_find_fast(CPUState *env) { TranslationBlock *tb; target_ulong cs_base, pc; @@ -191,7 +149,7 @@ static inline TranslationBlock *tb_find_fast(void) tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || tb->flags != flags)) { - tb = tb_find_slow(pc, cs_base, flags); + tb = tb_find_slow(env, pc, cs_base, flags); } return tb; } @@ -210,51 +168,65 @@ static void cpu_handle_debug_exception(CPUState *env) { CPUWatchpoint *wp; - if (!env->watchpoint_hit) - QTAILQ_FOREACH(wp, &env->watchpoints, entry) + if (!env->watchpoint_hit) { + QTAILQ_FOREACH(wp, &env->watchpoints, entry) { wp->flags &= ~BP_WATCHPOINT_HIT; - - if (debug_excp_handler) + } + } + if (debug_excp_handler) { debug_excp_handler(env); + } } /* main execution loop */ volatile sig_atomic_t exit_request; -int cpu_exec(CPUState *env1) +/* + * QEMU emulate can happens because of MMIO or emulation mode, i.e. non-PG mode, + * when it's because of MMIO, the MMIO, the interrupt should not be emulated, + * because MMIO is emulated for only one instruction now and then back to + * HAX kernel + */ +int need_handle_intr_request(CPUState *env) +{ +#ifdef CONFIG_HAX + if (!hax_enabled() || hax_vcpu_emulation_mode(env)) + return env->interrupt_request; + return 0; +#else + return env->interrupt_request; +#endif +} + + +int cpu_exec(CPUState *env) { - volatile host_reg_t saved_env_reg; int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; unsigned long next_tb; - if (cpu_halted(env1) == EXCP_HALTED) - return EXCP_HALTED; + if (env->halted) { + if (!cpu_has_work(env)) { + return EXCP_HALTED; + } - cpu_single_env = env1; + env->halted = 0; + } - /* the access to env below is actually saving the global register's - value, so that files not including target-xyz/exec.h are free to - use it. */ - QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env)); - saved_env_reg = (host_reg_t) env; - barrier(); - env = env1; + cpu_single_env = env; if (unlikely(exit_request)) { env->exit_request = 1; } #if defined(TARGET_I386) - if (!kvm_enabled()) { - /* put eflags in CPU temporary format */ - CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((env->eflags >> 10) & 1)); - CC_OP = CC_OP_EFLAGS; - env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - } + /* put eflags in CPU temporary format */ + CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + DF = 1 - (2 * ((env->eflags >> 10) & 1)); + CC_OP = CC_OP_EFLAGS; + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_SPARC) #elif defined(TARGET_M68K) env->cc_op = CC_OP_FLAGS; @@ -262,12 +234,16 @@ int cpu_exec(CPUState *env1) env->cc_x = (env->sr >> 4) & 1; #elif defined(TARGET_ALPHA) #elif defined(TARGET_ARM) +#elif defined(TARGET_UNICORE32) #elif defined(TARGET_PPC) + env->reserve_addr = -1; +#elif defined(TARGET_LM32) #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) #elif defined(TARGET_SH4) #elif defined(TARGET_CRIS) #elif defined(TARGET_S390X) +#elif defined(TARGET_XTENSA) /* XXXXX */ #else #error unsupported target CPU @@ -277,18 +253,14 @@ int cpu_exec(CPUState *env1) /* prepare setjmp context for exception handling */ for(;;) { if (setjmp(env->jmp_env) == 0) { -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -#undef env - env = cpu_single_env; -#define env cpu_single_env -#endif /* if an exception is pending, we execute it here */ if (env->exception_index >= 0) { if (env->exception_index >= EXCP_INTERRUPT) { /* exit request from the cpu execution loop */ ret = env->exception_index; - if (ret == EXCP_DEBUG) + if (ret == EXCP_DEBUG) { cpu_handle_debug_exception(env); + } break; } else { #if defined(CONFIG_USER_ONLY) @@ -296,105 +268,69 @@ int cpu_exec(CPUState *env1) which will be handled outside the cpu execution loop */ #if defined(TARGET_I386) - do_interrupt_user(env->exception_index, - env->exception_is_int, - env->error_code, - env->exception_next_eip); - /* successfully delivered */ - env->old_exception = -1; + do_interrupt(env); #endif ret = env->exception_index; break; #else -#if defined(TARGET_I386) - /* simulate a real cpu exception. On i386, it can - trigger new exceptions, but we do not handle - double or triple faults yet. */ - do_interrupt(env->exception_index, - env->exception_is_int, - env->error_code, - env->exception_next_eip, 0); - /* successfully delivered */ - env->old_exception = -1; -#elif defined(TARGET_PPC) - do_interrupt(env); -#elif defined(TARGET_MICROBLAZE) - do_interrupt(env); -#elif defined(TARGET_MIPS) - do_interrupt(env); -#elif defined(TARGET_SPARC) - do_interrupt(env); -#elif defined(TARGET_ARM) do_interrupt(env); -#elif defined(TARGET_SH4) - do_interrupt(env); -#elif defined(TARGET_ALPHA) - do_interrupt(env); -#elif defined(TARGET_CRIS) - do_interrupt(env); -#elif defined(TARGET_M68K) - do_interrupt(0); -#endif env->exception_index = -1; #endif } } - if (kvm_enabled()) { - kvm_cpu_exec(env); +#ifdef CONFIG_HAX + if (hax_enabled() && !hax_vcpu_exec(env)) longjmp(env->jmp_env, 1); - } +#endif next_tb = 0; /* force lookup of first TB */ for(;;) { interrupt_request = env->interrupt_request; - if (unlikely(interrupt_request)) { + if (unlikely(need_handle_intr_request(env))) { if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) { /* Mask out external interrupts for this step. */ - interrupt_request &= ~(CPU_INTERRUPT_HARD | - CPU_INTERRUPT_FIQ | - CPU_INTERRUPT_SMI | - CPU_INTERRUPT_NMI); + interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK; } if (interrupt_request & CPU_INTERRUPT_DEBUG) { env->interrupt_request &= ~CPU_INTERRUPT_DEBUG; env->exception_index = EXCP_DEBUG; - cpu_loop_exit(); + cpu_loop_exit(env); } #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \ defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \ - defined(TARGET_MICROBLAZE) + defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32) if (interrupt_request & CPU_INTERRUPT_HALT) { env->interrupt_request &= ~CPU_INTERRUPT_HALT; env->halted = 1; env->exception_index = EXCP_HLT; - cpu_loop_exit(); + cpu_loop_exit(env); } #endif #if defined(TARGET_I386) if (interrupt_request & CPU_INTERRUPT_INIT) { - svm_check_intercept(SVM_EXIT_INIT); + svm_check_intercept(env, SVM_EXIT_INIT); do_cpu_init(env); env->exception_index = EXCP_HALTED; - cpu_loop_exit(); + cpu_loop_exit(env); } else if (interrupt_request & CPU_INTERRUPT_SIPI) { do_cpu_sipi(env); } else if (env->hflags2 & HF2_GIF_MASK) { if ((interrupt_request & CPU_INTERRUPT_SMI) && !(env->hflags & HF_SMM_MASK)) { - svm_check_intercept(SVM_EXIT_SMI); + svm_check_intercept(env, SVM_EXIT_SMI); env->interrupt_request &= ~CPU_INTERRUPT_SMI; - do_smm_enter(); + do_smm_enter(env); next_tb = 0; } else if ((interrupt_request & CPU_INTERRUPT_NMI) && !(env->hflags2 & HF2_NMI_MASK)) { env->interrupt_request &= ~CPU_INTERRUPT_NMI; env->hflags2 |= HF2_NMI_MASK; - do_interrupt(EXCP02_NMI, 0, 0, 0, 1); + do_interrupt_x86_hardirq(env, EXCP02_NMI, 1); next_tb = 0; } else if (interrupt_request & CPU_INTERRUPT_MCE) { env->interrupt_request &= ~CPU_INTERRUPT_MCE; - do_interrupt(EXCP12_MCHK, 0, 0, 0, 0); + do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0); next_tb = 0; } else if ((interrupt_request & CPU_INTERRUPT_HARD) && (((env->hflags2 & HF2_VINTR_MASK) && @@ -403,16 +339,11 @@ int cpu_exec(CPUState *env1) (env->eflags & IF_MASK && !(env->hflags & HF_INHIBIT_IRQ_MASK))))) { int intno; - svm_check_intercept(SVM_EXIT_INTR); + svm_check_intercept(env, SVM_EXIT_INTR); env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -#undef env - env = cpu_single_env; -#define env cpu_single_env -#endif - do_interrupt(intno, 0, 0, 0, 1); + do_interrupt_x86_hardirq(env, intno, 1); /* ensure that no TB jump will be modified as the program flow was changed */ next_tb = 0; @@ -422,10 +353,10 @@ int cpu_exec(CPUState *env1) !(env->hflags & HF_INHIBIT_IRQ_MASK)) { int intno; /* FIXME: this should respect TPR */ - svm_check_intercept(SVM_EXIT_VINTR); + svm_check_intercept(env, SVM_EXIT_VINTR); intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno); - do_interrupt(intno, 0, 0, 0, 1); + do_interrupt_x86_hardirq(env, intno, 1); env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; next_tb = 0; #endif @@ -443,6 +374,13 @@ int cpu_exec(CPUState *env1) env->interrupt_request &= ~CPU_INTERRUPT_HARD; next_tb = 0; } +#elif defined(TARGET_LM32) + if ((interrupt_request & CPU_INTERRUPT_HARD) + && (env->ie & IE_IE)) { + env->exception_index = EXCP_IRQ; + do_interrupt(env); + next_tb = 0; + } #elif defined(TARGET_MICROBLAZE) if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sregs[SR_MSR] & MSR_IE) @@ -476,9 +414,6 @@ int cpu_exec(CPUState *env1) next_tb = 0; } } - } else if (interrupt_request & CPU_INTERRUPT_TIMER) { - //do_interrupt(0, 0, 0, 0, 0); - env->interrupt_request &= ~CPU_INTERRUPT_TIMER; } #elif defined(TARGET_ARM) if (interrupt_request & CPU_INTERRUPT_FIQ @@ -493,7 +428,7 @@ int cpu_exec(CPUState *env1) jump normally, then does the exception return when the CPU tries to execute code at the magic address. This will cause the magic PC value to be pushed to - the stack if an interrupt occured at the wrong time. + the stack if an interrupt occurred at the wrong time. We avoid this by disabling interrupts when pc contains a magic address. */ if (interrupt_request & CPU_INTERRUPT_HARD @@ -503,16 +438,49 @@ int cpu_exec(CPUState *env1) do_interrupt(env); next_tb = 0; } -#elif defined(TARGET_SH4) - if (interrupt_request & CPU_INTERRUPT_HARD) { +#elif defined(TARGET_UNICORE32) + if (interrupt_request & CPU_INTERRUPT_HARD + && !(env->uncached_asr & ASR_I)) { do_interrupt(env); next_tb = 0; } -#elif defined(TARGET_ALPHA) +#elif defined(TARGET_SH4) if (interrupt_request & CPU_INTERRUPT_HARD) { do_interrupt(env); next_tb = 0; } +#elif defined(TARGET_ALPHA) + { + int idx = -1; + /* ??? This hard-codes the OSF/1 interrupt levels. */ + switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) { + case 0 ... 3: + if (interrupt_request & CPU_INTERRUPT_HARD) { + idx = EXCP_DEV_INTERRUPT; + } + /* FALLTHRU */ + case 4: + if (interrupt_request & CPU_INTERRUPT_TIMER) { + idx = EXCP_CLK_INTERRUPT; + } + /* FALLTHRU */ + case 5: + if (interrupt_request & CPU_INTERRUPT_SMP) { + idx = EXCP_SMP_INTERRUPT; + } + /* FALLTHRU */ + case 6: + if (interrupt_request & CPU_INTERRUPT_MCHK) { + idx = EXCP_MCHK; + } + } + if (idx >= 0) { + env->exception_index = idx; + env->error_code = 0; + do_interrupt(env); + next_tb = 0; + } + } #elif defined(TARGET_CRIS) if (interrupt_request & CPU_INTERRUPT_HARD && (env->pregs[PR_CCS] & I_FLAG) @@ -537,11 +505,23 @@ int cpu_exec(CPUState *env1) provide/save the vector when the interrupt is first signalled. */ env->exception_index = env->pending_vector; - do_interrupt(1); + do_interrupt_m68k_hardirq(env); + next_tb = 0; + } +#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY) + if ((interrupt_request & CPU_INTERRUPT_HARD) && + (env->psw.mask & PSW_MASK_EXT)) { + do_interrupt(env); + next_tb = 0; + } +#elif defined(TARGET_XTENSA) + if (interrupt_request & CPU_INTERRUPT_HARD) { + env->exception_index = EXC_IRQ; + do_interrupt(env); next_tb = 0; } #endif - /* Don't use the cached interupt_request value, + /* Don't use the cached interrupt_request value, do_interrupt may have updated the EXITTB flag. */ if (env->interrupt_request & CPU_INTERRUPT_EXITTB) { env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; @@ -553,13 +533,14 @@ int cpu_exec(CPUState *env1) if (unlikely(env->exit_request)) { env->exit_request = 0; env->exception_index = EXCP_INTERRUPT; - cpu_loop_exit(); + cpu_loop_exit(env); } #if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC) if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { /* restore flags in standard format */ #if defined(TARGET_I386) - env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); + env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP) + | (DF & DF_MASK); log_cpu_state(env, X86_DUMP_CCOP); env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_M68K) @@ -574,7 +555,7 @@ int cpu_exec(CPUState *env1) } #endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */ spin_lock(&tb_lock); - tb = tb_find_fast(); + tb = tb_find_fast(env); /* Note: we do it here to avoid a gcc bug on Mac OS X when doing it in tb_find_slow */ if (tb_invalidated_flag) { @@ -606,12 +587,7 @@ int cpu_exec(CPUState *env1) if (likely(!env->exit_request)) { tc_ptr = tb->tc_ptr; /* execute the generated code */ -#if defined(__sparc__) && !defined(CONFIG_SOLARIS) -#undef env - env = cpu_single_env; -#define env cpu_single_env -#endif - next_tb = tcg_qemu_tb_exec(tc_ptr); + next_tb = tcg_qemu_tb_exec(env, tc_ptr); if ((next_tb & 3) == 2) { /* Instruction counter expired. */ int insns_left; @@ -632,29 +608,41 @@ int cpu_exec(CPUState *env1) } else { if (insns_left > 0) { /* Execute remaining instructions. */ - cpu_exec_nocache(insns_left, tb); + cpu_exec_nocache(env, insns_left, tb); } env->exception_index = EXCP_INTERRUPT; next_tb = 0; - cpu_loop_exit(); + cpu_loop_exit(env); } } } env->current_tb = NULL; +#ifdef CONFIG_HAX + if (hax_enabled() && hax_stop_emulation(env)) + cpu_loop_exit(env); +#endif + /* reset soft MMU for next block (it can currently only be set by a memory fault) */ } /* for(;;) */ + } else { + /* Reload env after longjmp - the compiler may have smashed all + * local variables as longjmp is marked 'noreturn'. */ + env = cpu_single_env; } } /* for(;;) */ #if defined(TARGET_I386) /* restore flags in standard format */ - env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); + env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP) + | (DF & DF_MASK); #elif defined(TARGET_ARM) /* XXX: Save/restore host fpu exception state?. */ +#elif defined(TARGET_UNICORE32) #elif defined(TARGET_SPARC) #elif defined(TARGET_PPC) +#elif defined(TARGET_LM32) #elif defined(TARGET_M68K) cpu_m68k_flush_flags(env, env->cc_op); env->cc_op = CC_OP_FLAGS; @@ -666,606 +654,13 @@ int cpu_exec(CPUState *env1) #elif defined(TARGET_ALPHA) #elif defined(TARGET_CRIS) #elif defined(TARGET_S390X) +#elif defined(TARGET_XTENSA) /* XXXXX */ #else #error unsupported target CPU #endif - /* restore global registers */ - barrier(); - env = (void *) saved_env_reg; - /* fail safe : never use cpu_single_env outside cpu_exec() */ cpu_single_env = NULL; return ret; } - -/* must only be called from the generated code as an exception can be - generated */ -void tb_invalidate_page_range(target_ulong start, target_ulong end) -{ - /* XXX: cannot enable it yet because it yields to MMU exception - where NIP != read address on PowerPC */ -#if 0 - target_ulong phys_addr; - phys_addr = get_phys_addr_code(env, start); - tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0); -#endif -} - -#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY) - -void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) -{ - CPUX86State *saved_env; - - saved_env = env; - env = s; - if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { - selector &= 0xffff; - cpu_x86_load_seg_cache(env, seg_reg, selector, - (selector << 4), 0xffff, 0); - } else { - helper_load_seg(seg_reg, selector); - } - env = saved_env; -} - -void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32) -{ - CPUX86State *saved_env; - - saved_env = env; - env = s; - - helper_fsave(ptr, data32); - - env = saved_env; -} - -void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32) -{ - CPUX86State *saved_env; - - saved_env = env; - env = s; - - helper_frstor(ptr, data32); - - env = saved_env; -} - -#endif /* TARGET_I386 */ - -#if !defined(CONFIG_SOFTMMU) - -#if defined(TARGET_I386) -#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code) -#else -#define EXCEPTION_ACTION cpu_loop_exit() -#endif - -/* 'pc' is the host PC at which the exception was raised. 'address' is - the effective address of the memory exception. 'is_write' is 1 if a - write caused the exception and otherwise 0'. 'old_set' is the - signal set which should be restored */ -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - - /* see if it is an MMU fault */ - ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } - - /* we restore the process signal mask as the sigreturn should - do it (XXX: use sigsetjmp) */ - sigprocmask(SIG_SETMASK, old_set, NULL); - EXCEPTION_ACTION; - - /* never comes here */ - return 1; -} - -#if defined(__i386__) - -#if defined(__APPLE__) -# include - -# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.eip)) -# define TRAP_sig(context) ((context)->uc_mcontext->es.trapno) -# define ERROR_sig(context) ((context)->uc_mcontext->es.err) -# define MASK_sig(context) ((context)->uc_sigmask) -#elif defined (__NetBSD__) -# include - -# define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP]) -# define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) -# define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) -# define MASK_sig(context) ((context)->uc_sigmask) -#elif defined (__FreeBSD__) || defined(__DragonFly__) -# include - -# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_eip)) -# define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno) -# define ERROR_sig(context) ((context)->uc_mcontext.mc_err) -# define MASK_sig(context) ((context)->uc_sigmask) -#elif defined(__OpenBSD__) -# define EIP_sig(context) ((context)->sc_eip) -# define TRAP_sig(context) ((context)->sc_trapno) -# define ERROR_sig(context) ((context)->sc_err) -# define MASK_sig(context) ((context)->sc_mask) -#else -# define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP]) -# define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) -# define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) -# define MASK_sig(context) ((context)->uc_sigmask) -#endif - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; -#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__) - ucontext_t *uc = puc; -#elif defined(__OpenBSD__) - struct sigcontext *uc = puc; -#else - struct ucontext *uc = puc; -#endif - unsigned long pc; - int trapno; - -#ifndef REG_EIP -/* for glibc 2.1 */ -#define REG_EIP EIP -#define REG_ERR ERR -#define REG_TRAPNO TRAPNO -#endif - pc = EIP_sig(uc); - trapno = TRAP_sig(uc); - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - trapno == 0xe ? - (ERROR_sig(uc) >> 1) & 1 : 0, - &MASK_sig(uc), puc); -} - -#elif defined(__x86_64__) - -#ifdef __NetBSD__ -#define PC_sig(context) _UC_MACHINE_PC(context) -#define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) -#define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) -#define MASK_sig(context) ((context)->uc_sigmask) -#elif defined(__OpenBSD__) -#define PC_sig(context) ((context)->sc_rip) -#define TRAP_sig(context) ((context)->sc_trapno) -#define ERROR_sig(context) ((context)->sc_err) -#define MASK_sig(context) ((context)->sc_mask) -#elif defined (__FreeBSD__) || defined(__DragonFly__) -#include - -#define PC_sig(context) (*((unsigned long*)&(context)->uc_mcontext.mc_rip)) -#define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno) -#define ERROR_sig(context) ((context)->uc_mcontext.mc_err) -#define MASK_sig(context) ((context)->uc_sigmask) -#else -#define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP]) -#define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) -#define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) -#define MASK_sig(context) ((context)->uc_sigmask) -#endif - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; - unsigned long pc; -#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__) - ucontext_t *uc = puc; -#elif defined(__OpenBSD__) - struct sigcontext *uc = puc; -#else - struct ucontext *uc = puc; -#endif - - pc = PC_sig(uc); - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - TRAP_sig(uc) == 0xe ? - (ERROR_sig(uc) >> 1) & 1 : 0, - &MASK_sig(uc), puc); -} - -#elif defined(_ARCH_PPC) - -/*********************************************************************** - * signal context platform-specific definitions - * From Wine - */ -#ifdef linux -/* All Registers access - only for local access */ -# define REG_sig(reg_name, context) ((context)->uc_mcontext.regs->reg_name) -/* Gpr Registers access */ -# define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context) -# define IAR_sig(context) REG_sig(nip, context) /* Program counter */ -# define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */ -# define CTR_sig(context) REG_sig(ctr, context) /* Count register */ -# define XER_sig(context) REG_sig(xer, context) /* User's integer exception register */ -# define LR_sig(context) REG_sig(link, context) /* Link register */ -# define CR_sig(context) REG_sig(ccr, context) /* Condition register */ -/* Float Registers access */ -# define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num]) -# define FPSCR_sig(context) (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4))) -/* Exception Registers access */ -# define DAR_sig(context) REG_sig(dar, context) -# define DSISR_sig(context) REG_sig(dsisr, context) -# define TRAP_sig(context) REG_sig(trap, context) -#endif /* linux */ - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -# define IAR_sig(context) ((context)->uc_mcontext.mc_srr0) -# define MSR_sig(context) ((context)->uc_mcontext.mc_srr1) -# define CTR_sig(context) ((context)->uc_mcontext.mc_ctr) -# define XER_sig(context) ((context)->uc_mcontext.mc_xer) -# define LR_sig(context) ((context)->uc_mcontext.mc_lr) -# define CR_sig(context) ((context)->uc_mcontext.mc_cr) -/* Exception Registers access */ -# define DAR_sig(context) ((context)->uc_mcontext.mc_dar) -# define DSISR_sig(context) ((context)->uc_mcontext.mc_dsisr) -# define TRAP_sig(context) ((context)->uc_mcontext.mc_exc) -#endif /* __FreeBSD__|| __FreeBSD_kernel__ */ - -#ifdef __APPLE__ -# include -typedef struct ucontext SIGCONTEXT; -/* All Registers access - only for local access */ -# define REG_sig(reg_name, context) ((context)->uc_mcontext->ss.reg_name) -# define FLOATREG_sig(reg_name, context) ((context)->uc_mcontext->fs.reg_name) -# define EXCEPREG_sig(reg_name, context) ((context)->uc_mcontext->es.reg_name) -# define VECREG_sig(reg_name, context) ((context)->uc_mcontext->vs.reg_name) -/* Gpr Registers access */ -# define GPR_sig(reg_num, context) REG_sig(r##reg_num, context) -# define IAR_sig(context) REG_sig(srr0, context) /* Program counter */ -# define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */ -# define CTR_sig(context) REG_sig(ctr, context) -# define XER_sig(context) REG_sig(xer, context) /* Link register */ -# define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */ -# define CR_sig(context) REG_sig(cr, context) /* Condition register */ -/* Float Registers access */ -# define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context) -# define FPSCR_sig(context) ((double)FLOATREG_sig(fpscr, context)) -/* Exception Registers access */ -# define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */ -# define DSISR_sig(context) EXCEPREG_sig(dsisr, context) -# define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */ -#endif /* __APPLE__ */ - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - ucontext_t *uc = puc; -#else - struct ucontext *uc = puc; -#endif - unsigned long pc; - int is_write; - - pc = IAR_sig(uc); - is_write = 0; -#if 0 - /* ppc 4xx case */ - if (DSISR_sig(uc) & 0x00800000) - is_write = 1; -#else - if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) - is_write = 1; -#endif - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, &uc->uc_sigmask, puc); -} - -#elif defined(__alpha__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; - struct ucontext *uc = puc; - uint32_t *pc = uc->uc_mcontext.sc_pc; - uint32_t insn = *pc; - int is_write = 0; - - /* XXX: need kernel patch to get write flag faster */ - switch (insn >> 26) { - case 0x0d: // stw - case 0x0e: // stb - case 0x0f: // stq_u - case 0x24: // stf - case 0x25: // stg - case 0x26: // sts - case 0x27: // stt - case 0x2c: // stl - case 0x2d: // stq - case 0x2e: // stl_c - case 0x2f: // stq_c - is_write = 1; - } - - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, &uc->uc_sigmask, puc); -} -#elif defined(__sparc__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; - int is_write; - uint32_t insn; -#if !defined(__arch64__) || defined(CONFIG_SOLARIS) - uint32_t *regs = (uint32_t *)(info + 1); - void *sigmask = (regs + 20); - /* XXX: is there a standard glibc define ? */ - unsigned long pc = regs[1]; -#else -#ifdef __linux__ - struct sigcontext *sc = puc; - unsigned long pc = sc->sigc_regs.tpc; - void *sigmask = (void *)sc->sigc_mask; -#elif defined(__OpenBSD__) - struct sigcontext *uc = puc; - unsigned long pc = uc->sc_pc; - void *sigmask = (void *)(long)uc->sc_mask; -#endif -#endif - - /* XXX: need kernel patch to get write flag faster */ - is_write = 0; - insn = *(uint32_t *)pc; - if ((insn >> 30) == 3) { - switch((insn >> 19) & 0x3f) { - case 0x05: // stb - case 0x15: // stba - case 0x06: // sth - case 0x16: // stha - case 0x04: // st - case 0x14: // sta - case 0x07: // std - case 0x17: // stda - case 0x0e: // stx - case 0x1e: // stxa - case 0x24: // stf - case 0x34: // stfa - case 0x27: // stdf - case 0x37: // stdfa - case 0x26: // stqf - case 0x36: // stqfa - case 0x25: // stfsr - case 0x3c: // casa - case 0x3e: // casxa - is_write = 1; - break; - } - } - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, sigmask, NULL); -} - -#elif defined(__arm__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; - struct ucontext *uc = puc; - unsigned long pc; - int is_write; - -#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) - pc = uc->uc_mcontext.gregs[R15]; -#else - pc = uc->uc_mcontext.arm_pc; -#endif - /* XXX: compute is_write */ - is_write = 0; - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, - &uc->uc_sigmask, puc); -} - -#elif defined(__mc68000) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; - struct ucontext *uc = puc; - unsigned long pc; - int is_write; - - pc = uc->uc_mcontext.gregs[16]; - /* XXX: compute is_write */ - is_write = 0; - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, - &uc->uc_sigmask, puc); -} - -#elif defined(__ia64) - -#ifndef __ISR_VALID - /* This ought to be in ... */ -# define __ISR_VALID 1 -#endif - -int cpu_signal_handler(int host_signum, void *pinfo, void *puc) -{ - siginfo_t *info = pinfo; - struct ucontext *uc = puc; - unsigned long ip; - int is_write = 0; - - ip = uc->uc_mcontext.sc_ip; - switch (host_signum) { - case SIGILL: - case SIGFPE: - case SIGSEGV: - case SIGBUS: - case SIGTRAP: - if (info->si_code && (info->si_segvflags & __ISR_VALID)) - /* ISR.W (write-access) is bit 33: */ - is_write = (info->si_isr >> 33) & 1; - break; - - default: - break; - } - return handle_cpu_signal(ip, (unsigned long)info->si_addr, - is_write, - (sigset_t *)&uc->uc_sigmask, puc); -} - -#elif defined(__s390__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; - struct ucontext *uc = puc; - unsigned long pc; - uint16_t *pinsn; - int is_write = 0; - - pc = uc->uc_mcontext.psw.addr; - - /* ??? On linux, the non-rt signal handler has 4 (!) arguments instead - of the normal 2 arguments. The 3rd argument contains the "int_code" - from the hardware which does in fact contain the is_write value. - The rt signal handler, as far as I can tell, does not give this value - at all. Not that we could get to it from here even if it were. */ - /* ??? This is not even close to complete, since it ignores all - of the read-modify-write instructions. */ - pinsn = (uint16_t *)pc; - switch (pinsn[0] >> 8) { - case 0x50: /* ST */ - case 0x42: /* STC */ - case 0x40: /* STH */ - is_write = 1; - break; - case 0xc4: /* RIL format insns */ - switch (pinsn[0] & 0xf) { - case 0xf: /* STRL */ - case 0xb: /* STGRL */ - case 0x7: /* STHRL */ - is_write = 1; - } - break; - case 0xe3: /* RXY format insns */ - switch (pinsn[2] & 0xff) { - case 0x50: /* STY */ - case 0x24: /* STG */ - case 0x72: /* STCY */ - case 0x70: /* STHY */ - case 0x8e: /* STPQ */ - case 0x3f: /* STRVH */ - case 0x3e: /* STRV */ - case 0x2f: /* STRVG */ - is_write = 1; - } - break; - } - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, &uc->uc_sigmask, puc); -} - -#elif defined(__mips__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info = pinfo; - struct ucontext *uc = puc; - greg_t pc = uc->uc_mcontext.pc; - int is_write; - - /* XXX: compute is_write */ - is_write = 0; - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, &uc->uc_sigmask, puc); -} - -#elif defined(__hppa__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - struct siginfo *info = pinfo; - struct ucontext *uc = puc; - unsigned long pc = uc->uc_mcontext.sc_iaoq[0]; - uint32_t insn = *(uint32_t *)pc; - int is_write = 0; - - /* XXX: need kernel patch to get write flag faster. */ - switch (insn >> 26) { - case 0x1a: /* STW */ - case 0x19: /* STH */ - case 0x18: /* STB */ - case 0x1b: /* STWM */ - is_write = 1; - break; - - case 0x09: /* CSTWX, FSTWX, FSTWS */ - case 0x0b: /* CSTDX, FSTDX, FSTDS */ - /* Distinguish from coprocessor load ... */ - is_write = (insn >> 9) & 1; - break; - - case 0x03: - switch ((insn >> 6) & 15) { - case 0xa: /* STWS */ - case 0x9: /* STHS */ - case 0x8: /* STBS */ - case 0xe: /* STWAS */ - case 0xc: /* STBYS */ - is_write = 1; - } - break; - } - - return handle_cpu_signal(pc, (unsigned long)info->si_addr, - is_write, &uc->uc_sigmask, puc); -} - -#else - -#error host CPU specific signal handler needed - -#endif - -#endif /* !defined(CONFIG_SOFTMMU) */ diff --git a/cpus.c b/cpus.c index 4c9928e..6d0ad82 100644 --- a/cpus.c +++ b/cpus.c @@ -30,27 +30,313 @@ #include "gdbstub.h" #include "dma.h" #include "kvm.h" -#include "exec-all.h" +#include "hax.h" +#include "qmp-commands.h" +#include "qemu-thread.h" #include "cpus.h" +#include "main-loop.h" + +#ifndef _WIN32 #include "compatfd.h" +#endif + #ifdef CONFIG_LINUX + #include + +#ifndef PR_MCE_KILL +#define PR_MCE_KILL 33 #endif -#ifdef SIGRTMIN -#define SIG_IPI (SIGRTMIN+4) -#else -#define SIG_IPI SIGUSR1 +#ifndef PR_MCE_KILL_SET +#define PR_MCE_KILL_SET 1 #endif -#ifndef PR_MCE_KILL -#define PR_MCE_KILL 33 +#ifndef PR_MCE_KILL_EARLY +#define PR_MCE_KILL_EARLY 1 #endif +#endif /* CONFIG_LINUX */ + static CPUState *next_cpu; /***********************************************************/ +/* guest cycle counter */ + +/* Conversion factor from emulated instructions to virtual clock ticks. */ +static int icount_time_shift; +/* Arbitrarily pick 1MIPS as the minimum allowable speed. */ +#define MAX_ICOUNT_SHIFT 10 +/* Compensate for varying guest execution speed. */ +static int64_t qemu_icount_bias; +static QEMUTimer *icount_rt_timer; +static QEMUTimer *icount_vm_timer; +static QEMUTimer *icount_warp_timer; +static int64_t vm_clock_warp_start; +static int64_t qemu_icount; + +typedef struct TimersState { + int64_t cpu_ticks_prev; + int64_t cpu_ticks_offset; + int64_t cpu_clock_offset; + int32_t cpu_ticks_enabled; + int64_t dummy; +} TimersState; + +TimersState timers_state; + +/* Return the virtual CPU time, based on the instruction counter. */ +int64_t cpu_get_icount(void) +{ + int64_t icount; + CPUState *env = cpu_single_env;; + + icount = qemu_icount; + if (env) { + if (!can_do_io(env)) { + fprintf(stderr, "Bad clock read\n"); + } + icount -= (env->icount_decr.u16.low + env->icount_extra); + } + return qemu_icount_bias + (icount << icount_time_shift); +} + +/* return the host CPU cycle counter and handle stop/restart */ +int64_t cpu_get_ticks(void) +{ + if (use_icount) { + return cpu_get_icount(); + } + if (!timers_state.cpu_ticks_enabled) { + return timers_state.cpu_ticks_offset; + } else { + int64_t ticks; + ticks = cpu_get_real_ticks(); + if (timers_state.cpu_ticks_prev > ticks) { + /* Note: non increasing ticks may happen if the host uses + software suspend */ + timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks; + } + timers_state.cpu_ticks_prev = ticks; + return ticks + timers_state.cpu_ticks_offset; + } +} + +/* return the host CPU monotonic timer and handle stop/restart */ +int64_t cpu_get_clock(void) +{ + int64_t ti; + if (!timers_state.cpu_ticks_enabled) { + return timers_state.cpu_clock_offset; + } else { + ti = get_clock(); + return ti + timers_state.cpu_clock_offset; + } +} + +/* enable cpu_get_ticks() */ +void cpu_enable_ticks(void) +{ + if (!timers_state.cpu_ticks_enabled) { + timers_state.cpu_ticks_offset -= cpu_get_real_ticks(); + timers_state.cpu_clock_offset -= get_clock(); + timers_state.cpu_ticks_enabled = 1; + } +} + +/* disable cpu_get_ticks() : the clock is stopped. You must not call + cpu_get_ticks() after that. */ +void cpu_disable_ticks(void) +{ + if (timers_state.cpu_ticks_enabled) { + timers_state.cpu_ticks_offset = cpu_get_ticks(); + timers_state.cpu_clock_offset = cpu_get_clock(); + timers_state.cpu_ticks_enabled = 0; + } +} + +/* Correlation between real and virtual time is always going to be + fairly approximate, so ignore small variation. + When the guest is idle real and virtual time will be aligned in + the IO wait loop. */ +#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10) + +static void icount_adjust(void) +{ + int64_t cur_time; + int64_t cur_icount; + int64_t delta; + static int64_t last_delta; + /* If the VM is not running, then do nothing. */ + if (!runstate_is_running()) { + return; + } + cur_time = cpu_get_clock(); + cur_icount = qemu_get_clock_ns(vm_clock); + delta = cur_icount - cur_time; + /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ + if (delta > 0 + && last_delta + ICOUNT_WOBBLE < delta * 2 + && icount_time_shift > 0) { + /* The guest is getting too far ahead. Slow time down. */ + icount_time_shift--; + } + if (delta < 0 + && last_delta - ICOUNT_WOBBLE > delta * 2 + && icount_time_shift < MAX_ICOUNT_SHIFT) { + /* The guest is getting too far behind. Speed time up. */ + icount_time_shift++; + } + last_delta = delta; + qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift); +} + +static void icount_adjust_rt(void *opaque) +{ + qemu_mod_timer(icount_rt_timer, + qemu_get_clock_ms(rt_clock) + 1000); + icount_adjust(); +} + +static void icount_adjust_vm(void *opaque) +{ + qemu_mod_timer(icount_vm_timer, + qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10); + icount_adjust(); +} + +static int64_t qemu_icount_round(int64_t count) +{ + return (count + (1 << icount_time_shift) - 1) >> icount_time_shift; +} + +static void icount_warp_rt(void *opaque) +{ + if (vm_clock_warp_start == -1) { + return; + } + + if (runstate_is_running()) { + int64_t clock = qemu_get_clock_ns(rt_clock); + int64_t warp_delta = clock - vm_clock_warp_start; + if (use_icount == 1) { + qemu_icount_bias += warp_delta; + } else { + /* + * In adaptive mode, do not let the vm_clock run too + * far ahead of real time. + */ + int64_t cur_time = cpu_get_clock(); + int64_t cur_icount = qemu_get_clock_ns(vm_clock); + int64_t delta = cur_time - cur_icount; + qemu_icount_bias += MIN(warp_delta, delta); + } + if (qemu_clock_expired(vm_clock)) { + qemu_notify_event(); + } + } + vm_clock_warp_start = -1; +} + +void qemu_clock_warp(QEMUClock *clock) +{ + int64_t deadline; + + /* + * There are too many global variables to make the "warp" behavior + * applicable to other clocks. But a clock argument removes the + * need for if statements all over the place. + */ + if (clock != vm_clock || !use_icount) { + return; + } + + /* + * If the CPUs have been sleeping, advance the vm_clock timer now. This + * ensures that the deadline for the timer is computed correctly below. + * This also makes sure that the insn counter is synchronized before the + * CPU starts running, in case the CPU is woken by an event other than + * the earliest vm_clock timer. + */ + icount_warp_rt(NULL); + if (!all_cpu_threads_idle() || !qemu_clock_has_timers(vm_clock)) { + qemu_del_timer(icount_warp_timer); + return; + } + + vm_clock_warp_start = qemu_get_clock_ns(rt_clock); + deadline = qemu_clock_deadline(vm_clock); + if (deadline > 0) { + /* + * Ensure the vm_clock proceeds even when the virtual CPU goes to + * sleep. Otherwise, the CPU might be waiting for a future timer + * interrupt to wake it up, but the interrupt never comes because + * the vCPU isn't running any insns and thus doesn't advance the + * vm_clock. + * + * An extreme solution for this problem would be to never let VCPUs + * sleep in icount mode if there is a pending vm_clock timer; rather + * time could just advance to the next vm_clock event. Instead, we + * do stop VCPUs and only advance vm_clock after some "real" time, + * (related to the time left until the next event) has passed. This + * rt_clock timer will do this. This avoids that the warps are too + * visible externally---for example, you will not be sending network + * packets continously instead of every 100ms. + */ + qemu_mod_timer(icount_warp_timer, vm_clock_warp_start + deadline); + } else { + qemu_notify_event(); + } +} + +static const VMStateDescription vmstate_timers = { + .name = "timer", + .version_id = 2, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT64(cpu_ticks_offset, TimersState), + VMSTATE_INT64(dummy, TimersState), + VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2), + VMSTATE_END_OF_LIST() + } +}; + +void configure_icount(const char *option) +{ + vmstate_register(NULL, 0, &vmstate_timers, &timers_state); + if (!option) { + return; + } + + icount_warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL); + if (strcmp(option, "auto") != 0) { + icount_time_shift = strtol(option, NULL, 0); + use_icount = 1; + return; + } + + use_icount = 2; + + /* 125MIPS seems a reasonable initial guess at the guest speed. + It will be corrected fairly quickly anyway. */ + icount_time_shift = 3; + + /* Have both realtime and virtual time triggers for speed adjustment. + The realtime trigger catches emulated time passing too slowly, + the virtual time trigger catches emulated time passing too fast. + Realtime triggers occur even when idle, so use them less frequently + than VM triggers. */ + icount_rt_timer = qemu_new_timer_ms(rt_clock, icount_adjust_rt, NULL); + qemu_mod_timer(icount_rt_timer, + qemu_get_clock_ms(rt_clock) + 1000); + icount_vm_timer = qemu_new_timer_ns(vm_clock, icount_adjust_vm, NULL); + qemu_mod_timer(icount_vm_timer, + qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10); +} + +/***********************************************************/ void hw_error(const char *fmt, ...) { va_list ap; @@ -101,16 +387,16 @@ void cpu_synchronize_all_post_init(void) int cpu_is_stopped(CPUState *env) { - return !vm_running || env->stopped; + return !runstate_is_running() || env->stopped; } -static void do_vm_stop(int reason) +static void do_vm_stop(RunState state) { - if (vm_running) { + if (runstate_is_running()) { cpu_disable_ticks(); - vm_running = 0; pause_all_vcpus(); - vm_state_notify(0, reason); + runstate_set(state); + vm_state_notify(0, state); qemu_aio_flush(); bdrv_flush_all(); monitor_protocol_event(QEVENT_STOP, NULL); @@ -119,331 +405,248 @@ static void do_vm_stop(int reason) static int cpu_can_run(CPUState *env) { - if (env->stop) + if (env->stop) { return 0; - if (env->stopped || !vm_running) + } + if (env->stopped || !runstate_is_running()) { return 0; + } return 1; } -static int cpu_has_work(CPUState *env) +static bool cpu_thread_is_idle(CPUState *env) { - if (env->stop) - return 1; - if (env->queued_work_first) - return 1; - if (env->stopped || !vm_running) - return 0; - if (!env->halted) - return 1; - if (qemu_cpu_has_work(env)) - return 1; - return 0; + if (env->stop || env->queued_work_first) { + return false; + } + if (env->stopped || !runstate_is_running()) { + return true; + } + if (!env->halted || qemu_cpu_has_work(env) || + (kvm_enabled() && kvm_irqchip_in_kernel()) || + hax_enabled()) { + return false; + } + return true; } -static int any_cpu_has_work(void) +bool all_cpu_threads_idle(void) { CPUState *env; - for (env = first_cpu; env != NULL; env = env->next_cpu) - if (cpu_has_work(env)) - return 1; - return 0; + for (env = first_cpu; env != NULL; env = env->next_cpu) { + if (!cpu_thread_is_idle(env)) { + return false; + } + } + return true; } -static void cpu_debug_handler(CPUState *env) +static void cpu_handle_guest_debug(CPUState *env) { gdb_set_stop_cpu(env); - debug_requested = EXCP_DEBUG; - vm_stop(EXCP_DEBUG); + qemu_system_debug_request(); + env->stopped = 1; } -#ifndef _WIN32 -static int io_thread_fd = -1; - -static void qemu_event_increment(void) +static void cpu_signal(int sig) { - /* Write 8 bytes to be compatible with eventfd. */ - static const uint64_t val = 1; - ssize_t ret; - - if (io_thread_fd == -1) - return; + if (cpu_single_env) { + cpu_exit(cpu_single_env); + } + exit_request = 1; +} - do { - ret = write(io_thread_fd, &val, sizeof(val)); - } while (ret < 0 && errno == EINTR); +#ifdef CONFIG_LINUX +static void sigbus_reraise(void) +{ + sigset_t set; + struct sigaction action; - /* EAGAIN is fine, a read must be pending. */ - if (ret < 0 && errno != EAGAIN) { - fprintf(stderr, "qemu_event_increment: write() filed: %s\n", - strerror(errno)); - exit (1); + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_DFL; + if (!sigaction(SIGBUS, &action, NULL)) { + raise(SIGBUS); + sigemptyset(&set); + sigaddset(&set, SIGBUS); + sigprocmask(SIG_UNBLOCK, &set, NULL); } + perror("Failed to re-raise SIGBUS!\n"); + abort(); } -static void qemu_event_read(void *opaque) +static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, + void *ctx) { - int fd = (unsigned long)opaque; - ssize_t len; - char buffer[512]; - - /* Drain the notify pipe. For eventfd, only 8 bytes will be read. */ - do { - len = read(fd, buffer, sizeof(buffer)); - } while ((len == -1 && errno == EINTR) || len == sizeof(buffer)); + if (kvm_on_sigbus(siginfo->ssi_code, + (void *)(intptr_t)siginfo->ssi_addr)) { + sigbus_reraise(); + } } -static int qemu_event_init(void) +static void qemu_init_sigbus(void) { - int err; - int fds[2]; + struct sigaction action; - err = qemu_eventfd(fds); - if (err == -1) - return -errno; + memset(&action, 0, sizeof(action)); + action.sa_flags = SA_SIGINFO; + action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; + sigaction(SIGBUS, &action, NULL); - err = fcntl_setfl(fds[0], O_NONBLOCK); - if (err < 0) - goto fail; + prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0); +} - err = fcntl_setfl(fds[1], O_NONBLOCK); - if (err < 0) - goto fail; +static void qemu_kvm_eat_signals(CPUState *env) +{ + struct timespec ts = { 0, 0 }; + siginfo_t siginfo; + sigset_t waitset; + sigset_t chkset; + int r; - qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL, - (void *)(unsigned long)fds[0]); + sigemptyset(&waitset); + sigaddset(&waitset, SIG_IPI); + sigaddset(&waitset, SIGBUS); - io_thread_fd = fds[1]; - return 0; + do { + r = sigtimedwait(&waitset, &siginfo, &ts); + if (r == -1 && !(errno == EAGAIN || errno == EINTR)) { + perror("sigtimedwait"); + exit(1); + } -fail: - close(fds[0]); - close(fds[1]); - return err; -} -#else -HANDLE qemu_event_handle; + switch (r) { + case SIGBUS: + if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) { + sigbus_reraise(); + } + break; + default: + break; + } -static void dummy_event_handler(void *opaque) -{ + r = sigpending(&chkset); + if (r == -1) { + perror("sigpending"); + exit(1); + } + } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); } -static int qemu_event_init(void) -{ - qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!qemu_event_handle) { - fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError()); - return -1; - } - qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL); - return 0; -} +#else /* !CONFIG_LINUX */ -static void qemu_event_increment(void) +static void qemu_init_sigbus(void) { - if (!SetEvent(qemu_event_handle)) { - fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n", - GetLastError()); - exit (1); - } } -#endif -#ifndef CONFIG_IOTHREAD -int qemu_init_main_loop(void) +static void qemu_kvm_eat_signals(CPUState *env) { - cpu_set_debug_excp_handler(cpu_debug_handler); - - return qemu_event_init(); } -void qemu_main_loop_start(void) +#endif /* !CONFIG_LINUX */ + +#ifndef _WIN32 +static void dummy_signal(int sig) { } -void qemu_init_vcpu(void *_env) +static void qemu_kvm_init_cpu_signals(CPUState *env) { - CPUState *env = _env; + int r; + sigset_t set; + struct sigaction sigact; - env->nr_cores = smp_cores; - env->nr_threads = smp_threads; - if (kvm_enabled()) - kvm_init_vcpu(env); - return; -} + memset(&sigact, 0, sizeof(sigact)); + sigact.sa_handler = dummy_signal; + sigaction(SIG_IPI, &sigact, NULL); -int qemu_cpu_self(void *env) -{ - return 1; -} + pthread_sigmask(SIG_BLOCK, NULL, &set); + sigdelset(&set, SIG_IPI); + sigdelset(&set, SIGBUS); + r = kvm_set_signal_mask(env, &set); + if (r) { + fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r)); + exit(1); + } -void run_on_cpu(CPUState *env, void (*func)(void *data), void *data) -{ - func(data); + sigdelset(&set, SIG_IPI); + sigdelset(&set, SIGBUS); + r = kvm_set_signal_mask(env, &set); + if (r) { + fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r)); + exit(1); + } } -void resume_all_vcpus(void) +static void qemu_tcg_init_cpu_signals(void) { -} + sigset_t set; + struct sigaction sigact; -void pause_all_vcpus(void) -{ -} + memset(&sigact, 0, sizeof(sigact)); + sigact.sa_handler = cpu_signal; + sigaction(SIG_IPI, &sigact, NULL); -void qemu_cpu_kick(void *env) -{ - return; + sigemptyset(&set); + sigaddset(&set, SIG_IPI); + pthread_sigmask(SIG_UNBLOCK, &set, NULL); } -void qemu_notify_event(void) +#else /* _WIN32 */ +static void qemu_kvm_init_cpu_signals(CPUState *env) { - CPUState *env = cpu_single_env; - - qemu_event_increment (); - if (env) { - cpu_exit(env); - } - if (next_cpu && env != next_cpu) { - cpu_exit(next_cpu); - } + abort(); } -void qemu_mutex_lock_iothread(void) {} -void qemu_mutex_unlock_iothread(void) {} - -void vm_stop(int reason) +static void qemu_tcg_init_cpu_signals(void) { - do_vm_stop(reason); } -#else /* CONFIG_IOTHREAD */ - -#include "qemu-thread.h" +#endif /* _WIN32 */ QemuMutex qemu_global_mutex; -static QemuMutex qemu_fair_mutex; +static QemuCond qemu_io_proceeded_cond; +static bool iothread_requesting_mutex; static QemuThread io_thread; static QemuThread *tcg_cpu_thread; static QemuCond *tcg_halt_cond; -static int qemu_system_ready; /* cpu creation */ static QemuCond qemu_cpu_cond; /* system init */ -static QemuCond qemu_system_cond; static QemuCond qemu_pause_cond; static QemuCond qemu_work_cond; -static void tcg_init_ipi(void); -static void kvm_init_ipi(CPUState *env); -static sigset_t block_io_signals(void); - -/* If we have signalfd, we mask out the signals we want to handle and then - * use signalfd to listen for them. We rely on whatever the current signal - * handler is to dispatch the signals when we receive them. - */ -static void sigfd_handler(void *opaque) +void qemu_init_cpu_loop(void) { - int fd = (unsigned long) opaque; - struct qemu_signalfd_siginfo info; - struct sigaction action; - ssize_t len; - - while (1) { - do { - len = read(fd, &info, sizeof(info)); - } while (len == -1 && errno == EINTR); - - if (len == -1 && errno == EAGAIN) { - break; - } - - if (len != sizeof(info)) { - printf("read from sigfd returned %zd: %m\n", len); - return; - } - - sigaction(info.ssi_signo, NULL, &action); - if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) { - action.sa_sigaction(info.ssi_signo, - (siginfo_t *)&info, NULL); - } else if (action.sa_handler) { - action.sa_handler(info.ssi_signo); - } - } -} - -static int qemu_signalfd_init(sigset_t mask) -{ - int sigfd; - - sigfd = qemu_signalfd(&mask); - if (sigfd == -1) { - fprintf(stderr, "failed to create signalfd\n"); - return -errno; - } - - fcntl_setfl(sigfd, O_NONBLOCK); - - qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL, - (void *)(unsigned long) sigfd); - - return 0; -} - -int qemu_init_main_loop(void) -{ - int ret; - sigset_t blocked_signals; - - cpu_set_debug_excp_handler(cpu_debug_handler); - - blocked_signals = block_io_signals(); - - ret = qemu_signalfd_init(blocked_signals); - if (ret) - return ret; - - /* Note eventfd must be drained before signalfd handlers run */ - ret = qemu_event_init(); - if (ret) - return ret; - + qemu_init_sigbus(); + qemu_cond_init(&qemu_cpu_cond); qemu_cond_init(&qemu_pause_cond); - qemu_cond_init(&qemu_system_cond); - qemu_mutex_init(&qemu_fair_mutex); + qemu_cond_init(&qemu_work_cond); + qemu_cond_init(&qemu_io_proceeded_cond); qemu_mutex_init(&qemu_global_mutex); - qemu_mutex_lock(&qemu_global_mutex); - - qemu_thread_self(&io_thread); - - return 0; -} -void qemu_main_loop_start(void) -{ - qemu_system_ready = 1; - qemu_cond_broadcast(&qemu_system_cond); + qemu_thread_get_self(&io_thread); } void run_on_cpu(CPUState *env, void (*func)(void *data), void *data) { struct qemu_work_item wi; - if (qemu_cpu_self(env)) { + if (qemu_cpu_is_self(env)) { func(data); return; } wi.func = func; wi.data = data; - if (!env->queued_work_first) + if (!env->queued_work_first) { env->queued_work_first = &wi; - else + } else { env->queued_work_last->next = &wi; + } env->queued_work_last = &wi; wi.next = NULL; wi.done = false; @@ -461,8 +664,9 @@ static void flush_queued_work(CPUState *env) { struct qemu_work_item *wi; - if (!env->queued_work_first) + if (!env->queued_work_first) { return; + } while ((wi = env->queued_work_first)) { env->queued_work_first = wi->next; @@ -481,255 +685,155 @@ static void qemu_wait_io_event_common(CPUState *env) qemu_cond_signal(&qemu_pause_cond); } flush_queued_work(env); + env->thread_kicked = false; } static void qemu_tcg_wait_io_event(void) { CPUState *env; - while (!any_cpu_has_work()) - qemu_cond_timedwait(tcg_halt_cond, &qemu_global_mutex, 1000); - - qemu_mutex_unlock(&qemu_global_mutex); - - /* - * Users of qemu_global_mutex can be starved, having no chance - * to acquire it since this path will get to it first. - * So use another lock to provide fairness. - */ - qemu_mutex_lock(&qemu_fair_mutex); - qemu_mutex_unlock(&qemu_fair_mutex); + while (all_cpu_threads_idle()) { + /* Start accounting real time to the virtual clock if the CPUs + are idle. */ + qemu_clock_warp(vm_clock); + qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); + } - qemu_mutex_lock(&qemu_global_mutex); + while (iothread_requesting_mutex) { + qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex); + } for (env = first_cpu; env != NULL; env = env->next_cpu) { qemu_wait_io_event_common(env); } } -static void sigbus_reraise(void) -{ - sigset_t set; - struct sigaction action; - - memset(&action, 0, sizeof(action)); - action.sa_handler = SIG_DFL; - if (!sigaction(SIGBUS, &action, NULL)) { - raise(SIGBUS); - sigemptyset(&set); - sigaddset(&set, SIGBUS); - sigprocmask(SIG_UNBLOCK, &set, NULL); - } - perror("Failed to re-raise SIGBUS!\n"); - abort(); -} - -static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, - void *ctx) -{ -#if defined(TARGET_I386) - if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) -#endif - sigbus_reraise(); -} - -static void qemu_kvm_eat_signal(CPUState *env, int timeout) -{ - struct timespec ts; - int r, e; - siginfo_t siginfo; - sigset_t waitset; - sigset_t chkset; - - ts.tv_sec = timeout / 1000; - ts.tv_nsec = (timeout % 1000) * 1000000; - - sigemptyset(&waitset); - sigaddset(&waitset, SIG_IPI); - sigaddset(&waitset, SIGBUS); - - do { - qemu_mutex_unlock(&qemu_global_mutex); - - r = sigtimedwait(&waitset, &siginfo, &ts); - e = errno; - - qemu_mutex_lock(&qemu_global_mutex); - - if (r == -1 && !(e == EAGAIN || e == EINTR)) { - fprintf(stderr, "sigtimedwait: %s\n", strerror(e)); - exit(1); - } - - switch (r) { - case SIGBUS: -#ifdef TARGET_I386 - if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) -#endif - sigbus_reraise(); - break; - default: - break; - } - - r = sigpending(&chkset); - if (r == -1) { - fprintf(stderr, "sigpending: %s\n", strerror(e)); - exit(1); - } - } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); -} - static void qemu_kvm_wait_io_event(CPUState *env) { - while (!cpu_has_work(env)) - qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000); + while (cpu_thread_is_idle(env)) { + qemu_cond_wait(env->halt_cond, &qemu_global_mutex); + } - qemu_kvm_eat_signal(env, 0); + qemu_kvm_eat_signals(env); qemu_wait_io_event_common(env); } -static int qemu_cpu_exec(CPUState *env); - -static void *kvm_cpu_thread_fn(void *arg) +static void *qemu_kvm_cpu_thread_fn(void *arg) { CPUState *env = arg; + int r; qemu_mutex_lock(&qemu_global_mutex); - qemu_thread_self(env->thread); - if (kvm_enabled()) - kvm_init_vcpu(env); + qemu_thread_get_self(env->thread); + env->thread_id = qemu_get_thread_id(); - kvm_init_ipi(env); + r = kvm_init_vcpu(env); + if (r < 0) { + fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r)); + exit(1); + } + + qemu_kvm_init_cpu_signals(env); /* signal CPU creation */ env->created = 1; qemu_cond_signal(&qemu_cpu_cond); - /* and wait for machine initialization */ - while (!qemu_system_ready) - qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100); - while (1) { - if (cpu_can_run(env)) - qemu_cpu_exec(env); + if (cpu_can_run(env)) { + r = kvm_cpu_exec(env); + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(env); + } + } qemu_kvm_wait_io_event(env); } return NULL; } -static void *tcg_cpu_thread_fn(void *arg) +static void tcg_exec_all(void); + +static void *qemu_tcg_cpu_thread_fn(void *arg) { CPUState *env = arg; - tcg_init_ipi(); - qemu_thread_self(env->thread); + qemu_tcg_init_cpu_signals(); + qemu_thread_get_self(env->thread); /* signal CPU creation */ qemu_mutex_lock(&qemu_global_mutex); - for (env = first_cpu; env != NULL; env = env->next_cpu) + for (env = first_cpu; env != NULL; env = env->next_cpu) { + env->thread_id = qemu_get_thread_id(); env->created = 1; + } qemu_cond_signal(&qemu_cpu_cond); - /* and wait for machine initialization */ - while (!qemu_system_ready) - qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100); + /* wait for initial kick-off after machine start */ + while (first_cpu->stopped) { + qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); + } while (1) { - cpu_exec_all(); + tcg_exec_all(); + if (use_icount && qemu_clock_deadline(vm_clock) <= 0) { + qemu_notify_event(); + } qemu_tcg_wait_io_event(); } return NULL; } -void qemu_cpu_kick(void *_env) +static void qemu_cpu_kick_thread(CPUState *env) { - CPUState *env = _env; - qemu_cond_broadcast(env->halt_cond); - qemu_thread_signal(env->thread, SIG_IPI); -} - -int qemu_cpu_self(void *_env) -{ - CPUState *env = _env; - QemuThread this; - - qemu_thread_self(&this); - - return qemu_thread_equal(&this, env->thread); -} +#ifndef _WIN32 + int err; -static void cpu_signal(int sig) -{ - if (cpu_single_env) - cpu_exit(cpu_single_env); - exit_request = 1; + err = pthread_kill(env->thread->thread, SIG_IPI); + if (err) { + fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); + exit(1); + } +#else /* _WIN32 */ + if (!qemu_cpu_is_self(env)) { + SuspendThread(env->thread->thread); + cpu_signal(0); + ResumeThread(env->thread->thread); + } +#endif } -static void tcg_init_ipi(void) +void qemu_cpu_kick(void *_env) { - sigset_t set; - struct sigaction sigact; - - memset(&sigact, 0, sizeof(sigact)); - sigact.sa_handler = cpu_signal; - sigaction(SIG_IPI, &sigact, NULL); - - sigemptyset(&set); - sigaddset(&set, SIG_IPI); - pthread_sigmask(SIG_UNBLOCK, &set, NULL); -} + CPUState *env = _env; -static void dummy_signal(int sig) -{ + qemu_cond_broadcast(env->halt_cond); + if ((kvm_enabled()) && !env->thread_kicked) { + qemu_cpu_kick_thread(env); + env->thread_kicked = true; + } } -static void kvm_init_ipi(CPUState *env) +void qemu_cpu_kick_self(void) { - int r; - sigset_t set; - struct sigaction sigact; - - memset(&sigact, 0, sizeof(sigact)); - sigact.sa_handler = dummy_signal; - sigaction(SIG_IPI, &sigact, NULL); +#ifndef _WIN32 + assert(cpu_single_env); - pthread_sigmask(SIG_BLOCK, NULL, &set); - sigdelset(&set, SIG_IPI); - sigdelset(&set, SIGBUS); - r = kvm_set_signal_mask(env, &set); - if (r) { - fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r)); - exit(1); + if (!cpu_single_env->thread_kicked) { + qemu_cpu_kick_thread(cpu_single_env); + cpu_single_env->thread_kicked = true; } +#else + abort(); +#endif } -static sigset_t block_io_signals(void) +int qemu_cpu_is_self(void *_env) { - sigset_t set; - struct sigaction action; - - /* SIGUSR2 used by posix-aio-compat.c */ - sigemptyset(&set); - sigaddset(&set, SIGUSR2); - pthread_sigmask(SIG_UNBLOCK, &set, NULL); - - sigemptyset(&set); - sigaddset(&set, SIGIO); - sigaddset(&set, SIGALRM); - sigaddset(&set, SIG_IPI); - sigaddset(&set, SIGBUS); - pthread_sigmask(SIG_BLOCK, &set, NULL); - - memset(&action, 0, sizeof(action)); - action.sa_flags = SA_SIGINFO; - action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; - sigaction(SIGBUS, &action, NULL); - prctl(PR_MCE_KILL, 1, 1, 0, 0); + CPUState *env = _env; - return set; + return qemu_thread_is_self(env->thread); } void qemu_mutex_lock_iothread(void) @@ -737,12 +841,13 @@ void qemu_mutex_lock_iothread(void) if (kvm_enabled()) { qemu_mutex_lock(&qemu_global_mutex); } else { - qemu_mutex_lock(&qemu_fair_mutex); + iothread_requesting_mutex = true; if (qemu_mutex_trylock(&qemu_global_mutex)) { - qemu_thread_signal(tcg_cpu_thread, SIG_IPI); + qemu_cpu_kick_thread(first_cpu); qemu_mutex_lock(&qemu_global_mutex); } - qemu_mutex_unlock(&qemu_fair_mutex); + iothread_requesting_mutex = false; + qemu_cond_broadcast(&qemu_io_proceeded_cond); } } @@ -756,8 +861,9 @@ static int all_vcpus_paused(void) CPUState *penv = first_cpu; while (penv) { - if (!penv->stopped) + if (!penv->stopped) { return 0; + } penv = (CPUState *)penv->next_cpu; } @@ -768,6 +874,7 @@ void pause_all_vcpus(void) { CPUState *penv = first_cpu; + qemu_clock_enable(vm_clock, false); while (penv) { penv->stop = 1; qemu_cpu_kick(penv); @@ -775,7 +882,7 @@ void pause_all_vcpus(void) } while (!all_vcpus_paused()) { - qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100); + qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); penv = first_cpu; while (penv) { qemu_cpu_kick(penv); @@ -788,6 +895,7 @@ void resume_all_vcpus(void) { CPUState *penv = first_cpu; + qemu_clock_enable(vm_clock, true); while (penv) { penv->stop = 0; penv->stopped = 0; @@ -796,33 +904,40 @@ void resume_all_vcpus(void) } } -static void tcg_init_vcpu(void *_env) +static void qemu_tcg_init_vcpu(void *_env) { CPUState *env = _env; + +#ifdef CONFIG_HAX + if (hax_enabled()) + hax_init_vcpu(env); +#endif /* share a single thread for all cpus with TCG */ if (!tcg_cpu_thread) { - env->thread = qemu_mallocz(sizeof(QemuThread)); - env->halt_cond = qemu_mallocz(sizeof(QemuCond)); + env->thread = g_malloc0(sizeof(QemuThread)); + env->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(env->halt_cond); - qemu_thread_create(env->thread, tcg_cpu_thread_fn, env); - while (env->created == 0) - qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100); - tcg_cpu_thread = env->thread; tcg_halt_cond = env->halt_cond; + qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env); + while (env->created == 0) { + qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); + } + tcg_cpu_thread = env->thread; } else { env->thread = tcg_cpu_thread; env->halt_cond = tcg_halt_cond; } } -static void kvm_start_vcpu(CPUState *env) +static void qemu_kvm_start_vcpu(CPUState *env) { - env->thread = qemu_mallocz(sizeof(QemuThread)); - env->halt_cond = qemu_mallocz(sizeof(QemuCond)); + env->thread = g_malloc0(sizeof(QemuThread)); + env->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(env->halt_cond); - qemu_thread_create(env->thread, kvm_cpu_thread_fn, env); - while (env->created == 0) - qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100); + qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env); + while (env->created == 0) { + qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); + } } void qemu_init_vcpu(void *_env) @@ -831,46 +946,50 @@ void qemu_init_vcpu(void *_env) env->nr_cores = smp_cores; env->nr_threads = smp_threads; - if (kvm_enabled()) - kvm_start_vcpu(env); + env->stopped = 1; + if (kvm_enabled()) { + qemu_kvm_start_vcpu(env); + } else - tcg_init_vcpu(env); -} - -void qemu_notify_event(void) -{ - qemu_event_increment(); + qemu_tcg_init_vcpu(env); } -static void qemu_system_vmstop_request(int reason) +void cpu_stop_current(void) { - vmstop_requested = reason; - qemu_notify_event(); + if (cpu_single_env) { + cpu_single_env->stop = 0; + cpu_single_env->stopped = 1; + cpu_exit(cpu_single_env); + qemu_cond_signal(&qemu_pause_cond); + } } -void vm_stop(int reason) +void vm_stop(RunState state) { - QemuThread me; - qemu_thread_self(&me); - - if (!qemu_thread_equal(&me, &io_thread)) { - qemu_system_vmstop_request(reason); + if (!qemu_thread_is_self(&io_thread)) { + qemu_system_vmstop_request(state); /* * FIXME: should not return to device code in case * vm_stop() has been requested. */ - if (cpu_single_env) { - cpu_exit(cpu_single_env); - cpu_single_env->stop = 1; - } + cpu_stop_current(); return; } - do_vm_stop(reason); + do_vm_stop(state); } -#endif +/* does a state transition even if the VM is already stopped, + current state is forgotten forever */ +void vm_stop_force_state(RunState state) +{ + if (runstate_is_running()) { + vm_stop(state); + } else { + runstate_set(state); + } +} -static int qemu_cpu_exec(CPUState *env) +static int tcg_cpu_exec(CPUState *env) { int ret; #ifdef CONFIG_PROFILER @@ -886,7 +1005,7 @@ static int qemu_cpu_exec(CPUState *env) qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); env->icount_decr.u16.low = 0; env->icount_extra = 0; - count = qemu_icount_round (qemu_next_deadline()); + count = qemu_icount_round(qemu_clock_deadline(vm_clock)); qemu_icount += count; decr = (count > 0xffff) ? 0xffff : count; count -= decr; @@ -908,28 +1027,33 @@ static int qemu_cpu_exec(CPUState *env) return ret; } -bool cpu_exec_all(void) +static void tcg_exec_all(void) { - if (next_cpu == NULL) + int r; + + /* Account partial waits to the vm_clock. */ + qemu_clock_warp(vm_clock); + + if (next_cpu == NULL) { next_cpu = first_cpu; + } for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) { CPUState *env = next_cpu; qemu_clock_enable(vm_clock, (env->singlestep_enabled & SSTEP_NOTIMER) == 0); - if (qemu_alarm_pending()) - break; if (cpu_can_run(env)) { - if (qemu_cpu_exec(env) == EXCP_DEBUG) { + r = tcg_cpu_exec(env); + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(env); break; } - } else if (env->stop) { + } else if (env->stop || env->stopped) { break; } } exit_request = 0; - return any_cpu_has_work(); } void set_numa_modes(void) @@ -962,20 +1086,9 @@ void set_cpu_log(const char *optarg) cpu_set_log(mask); } -/* Return the virtual CPU time, based on the instruction counter. */ -int64_t cpu_get_icount(void) +void set_cpu_log_filename(const char *optarg) { - int64_t icount; - CPUState *env = cpu_single_env;; - - icount = qemu_icount; - if (env) { - if (!can_do_io(env)) { - fprintf(stderr, "Bad clock read\n"); - } - icount -= (env->icount_decr.u16.low + env->icount_extra); - } - return qemu_icount_bias + (icount << icount_time_shift); + cpu_set_log_filename(optarg); } void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg) @@ -987,3 +1100,57 @@ void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg) cpu_list(f, cpu_fprintf); /* deprecated */ #endif } + +CpuInfoList *qmp_query_cpus(Error **errp) +{ + CpuInfoList *head = NULL, *cur_item = NULL; + CPUState *env; + + for(env = first_cpu; env != NULL; env = env->next_cpu) { + CpuInfoList *info; + + cpu_synchronize_state(env); + + info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->CPU = env->cpu_index; + info->value->current = (env == first_cpu); + info->value->halted = env->halted; + info->value->thread_id = env->thread_id; +#if defined(TARGET_I386) + info->value->has_pc = true; + info->value->pc = env->eip + env->segs[R_CS].base; +#elif defined(TARGET_PPC) + info->value->has_nip = true; + info->value->nip = env->nip; +#elif defined(TARGET_SPARC) + info->value->has_pc = true; + info->value->pc = env->pc; + info->value->has_npc = true; + info->value->npc = env->npc; +#elif defined(TARGET_MIPS) + info->value->has_PC = true; + info->value->PC = env->active_tc.PC; +#endif + + /* XXX: waiting for the qapi to support GSList */ + if (!cur_item) { + head = cur_item = info; + } else { + cur_item->next = info; + cur_item = info; + } + } + + return head; +} + +#ifdef CONFIG_HAX +void qemu_notify_hax_event(void) +{ + CPUState *env = cpu_single_env; + + if (hax_enabled() && env) + hax_raise_event(env); +} +#endif diff --git a/cpus.h b/cpus.h index bf4d9bb..4ea2fe2 100644 --- a/cpus.h +++ b/cpus.h @@ -2,20 +2,21 @@ #define QEMU_CPUS_H /* cpus.c */ -int qemu_init_main_loop(void); -void qemu_main_loop_start(void); +void qemu_init_cpu_loop(void); void resume_all_vcpus(void); void pause_all_vcpus(void); +void cpu_stop_current(void); + +void cpu_synchronize_all_states(void); +void cpu_synchronize_all_post_reset(void); +void cpu_synchronize_all_post_init(void); /* vl.c */ extern int smp_cores; extern int smp_threads; -extern int debug_requested; -extern int vmstop_requested; -void vm_state_notify(int running, int reason); -bool cpu_exec_all(void); void set_numa_modes(void); void set_cpu_log(const char *optarg); +void set_cpu_log_filename(const char *optarg); void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg); #endif diff --git a/cris-dis.c b/cris-dis.c index 5fa67d9..5b8e90b 100644 --- a/cris-dis.c +++ b/cris-dis.c @@ -1396,32 +1396,32 @@ get_opcode_entry (unsigned int insn, /* Allocate and clear the opcode-table. */ if (opc_table == NULL) { - opc_table = qemu_malloc (65536 * sizeof (opc_table[0])); + opc_table = g_malloc (65536 * sizeof (opc_table[0])); memset (opc_table, 0, 65536 * sizeof (const struct cris_opcode *)); dip_prefixes - = qemu_malloc (65536 * sizeof (const struct cris_opcode **)); + = g_malloc (65536 * sizeof (const struct cris_opcode **)); memset (dip_prefixes, 0, 65536 * sizeof (dip_prefixes[0])); bdapq_m1_prefixes - = qemu_malloc (65536 * sizeof (const struct cris_opcode **)); + = g_malloc (65536 * sizeof (const struct cris_opcode **)); memset (bdapq_m1_prefixes, 0, 65536 * sizeof (bdapq_m1_prefixes[0])); bdapq_m2_prefixes - = qemu_malloc (65536 * sizeof (const struct cris_opcode **)); + = g_malloc (65536 * sizeof (const struct cris_opcode **)); memset (bdapq_m2_prefixes, 0, 65536 * sizeof (bdapq_m2_prefixes[0])); bdapq_m4_prefixes - = qemu_malloc (65536 * sizeof (const struct cris_opcode **)); + = g_malloc (65536 * sizeof (const struct cris_opcode **)); memset (bdapq_m4_prefixes, 0, 65536 * sizeof (bdapq_m4_prefixes[0])); rest_prefixes - = qemu_malloc (65536 * sizeof (const struct cris_opcode **)); + = g_malloc (65536 * sizeof (const struct cris_opcode **)); memset (rest_prefixes, 0, 65536 * sizeof (rest_prefixes[0])); } diff --git a/cursor.c b/cursor.c index dfb9eef..efc5917 100644 --- a/cursor.c +++ b/cursor.c @@ -98,7 +98,7 @@ QEMUCursor *cursor_alloc(int width, int height) QEMUCursor *c; int datasize = width * height * sizeof(uint32_t); - c = qemu_mallocz(sizeof(QEMUCursor) + datasize); + c = g_malloc0(sizeof(QEMUCursor) + datasize); c->width = width; c->height = height; c->refcount = 1; @@ -117,7 +117,7 @@ void cursor_put(QEMUCursor *c) c->refcount--; if (c->refcount) return; - qemu_free(c); + g_free(c); } int cursor_get_mono_bpl(QEMUCursor *c) diff --git a/cutils.c b/cutils.c index f9a7e36..24b3fe3 100644 --- a/cutils.c +++ b/cutils.c @@ -136,7 +136,7 @@ int qemu_fdatasync(int fd) void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint) { - qiov->iov = qemu_malloc(alloc_hint * sizeof(struct iovec)); + qiov->iov = g_malloc(alloc_hint * sizeof(struct iovec)); qiov->niov = 0; qiov->nalloc = alloc_hint; qiov->size = 0; @@ -160,7 +160,7 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len) if (qiov->niov == qiov->nalloc) { qiov->nalloc = 2 * qiov->nalloc + 1; - qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec)); + qiov->iov = g_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec)); } qiov->iov[qiov->niov].iov_base = base; qiov->iov[qiov->niov].iov_len = len; @@ -217,7 +217,10 @@ void qemu_iovec_destroy(QEMUIOVector *qiov) { assert(qiov->nalloc != -1); - qemu_free(qiov->iov); + qemu_iovec_reset(qiov); + g_free(qiov->iov); + qiov->nalloc = 0; + qiov->iov = NULL; } void qemu_iovec_reset(QEMUIOVector *qiov) @@ -315,18 +318,34 @@ int fcntl_setfl(int fd, int flag) } #endif +static int64_t suffix_mul(char suffix, int64_t unit) +{ + switch (qemu_toupper(suffix)) { + case STRTOSZ_DEFSUFFIX_B: + return 1; + case STRTOSZ_DEFSUFFIX_KB: + return unit; + case STRTOSZ_DEFSUFFIX_MB: + return unit * unit; + case STRTOSZ_DEFSUFFIX_GB: + return unit * unit * unit; + case STRTOSZ_DEFSUFFIX_TB: + return unit * unit * unit * unit; + } + return -1; +} + /* * Convert string to bytes, allowing either B/b for bytes, K/k for KB, - * M/m for MB, G/g for GB or T/t for TB. Default without any postfix - * is MB. End pointer will be returned in *end, if not NULL. A valid - * value must be terminated by whitespace, ',' or '\0'. Return -1 on - * error. + * M/m for MB, G/g for GB or T/t for TB. End pointer will be returned + * in *end, if not NULL. Return -1 on error. */ -int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) +int64_t strtosz_suffix_unit(const char *nptr, char **end, + const char default_suffix, int64_t unit) { int64_t retval = -1; char *endptr; - unsigned char c, d; + unsigned char c; int mul_required = 0; double val, mul, integral, fraction; @@ -339,59 +358,17 @@ int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) if (fraction != 0) { mul_required = 1; } - /* - * Any whitespace character is fine for terminating the number, - * in addition we accept ',' to handle strings where the size is - * part of a multi token argument. - */ c = *endptr; - d = c; - if (qemu_isspace(c) || c == '\0' || c == ',') { - c = 0; - if (default_suffix) { - d = default_suffix; - } else { - d = c; - } + mul = suffix_mul(c, unit); + if (mul >= 0) { + endptr++; + } else { + mul = suffix_mul(default_suffix, unit); + assert(mul >= 0); } - switch (qemu_toupper(d)) { - case STRTOSZ_DEFSUFFIX_B: - mul = 1; - if (mul_required) { - goto fail; - } - break; - case STRTOSZ_DEFSUFFIX_KB: - mul = 1 << 10; - break; - case 0: - if (mul_required) { - goto fail; - } - case STRTOSZ_DEFSUFFIX_MB: - mul = 1ULL << 20; - break; - case STRTOSZ_DEFSUFFIX_GB: - mul = 1ULL << 30; - break; - case STRTOSZ_DEFSUFFIX_TB: - mul = 1ULL << 40; - break; - default: + if (mul == 1 && mul_required) { goto fail; } - /* - * If not terminated by whitespace, ',', or \0, increment endptr - * to point to next character, then check that we are terminated - * by an appropriate separating character, ie. whitespace, ',', or - * \0. If not, we are seeing trailing garbage, thus fail. - */ - if (c != 0) { - endptr++; - if (!qemu_isspace(*endptr) && *endptr != ',' && *endptr != 0) { - goto fail; - } - } if ((val * mul >= INT64_MAX) || val < 0) { goto fail; } @@ -405,7 +382,24 @@ fail: return retval; } +int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) +{ + return strtosz_suffix_unit(nptr, end, default_suffix, 1024); +} + int64_t strtosz(const char *nptr, char **end) { return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB); } + +int qemu_parse_fd(const char *param) +{ + int fd; + char *endptr = NULL; + + fd = strtol(param, &endptr, 10); + if (*endptr || (fd == 0 && param == endptr)) { + return -1; + } + return fd; +} diff --git a/darwin-user/commpage.c b/darwin-user/commpage.c index f6aa71e..cc29bdd 100644 --- a/darwin-user/commpage.c +++ b/darwin-user/commpage.c @@ -211,7 +211,7 @@ void do_compare_and_swap32(void *cpu_env, int num) uint32_t *value = (uint32_t*)((CPUX86State*)cpu_env)->regs[R_ECX]; DPRINTF("commpage: compare_and_swap32(%x,new,%p)\n", old, value); - if(value && old == tswap32(*value)) + if(old == tswap32(*value)) { uint32_t new = ((CPUX86State*)cpu_env)->regs[R_EDX]; *value = tswap32(new); diff --git a/darwin-user/machload.c b/darwin-user/machload.c index 3bc3b65..0aa8282 100644 --- a/darwin-user/machload.c +++ b/darwin-user/machload.c @@ -865,11 +865,11 @@ unsigned long setup_arg_pages(void * mh, char ** argv, char ** env) page_set_flags((int)argv[i], (int)(argv[i]+strlen(argv[i])), PROT_READ | PAGE_VALID); } - DPRINTF("pushing argc %d \n", argc); + DPRINTF("pushing argc %d\n", argc); stl(stack, argc); stack--; - DPRINTF("pushing mh 0x%x \n", (int)mh); + DPRINTF("pushing mh 0x%x\n", (int)mh); stl(stack, (int) mh); /* Stack points on the mh */ diff --git a/darwin-user/main.c b/darwin-user/main.c index 175e12f..c0f14f8 100644 --- a/darwin-user/main.c +++ b/darwin-user/main.c @@ -729,8 +729,6 @@ static void usage(void) /* XXX: currently only used for async signals (see signal.c) */ CPUState *global_env; -/* used only if single thread */ -CPUState *cpu_single_env = NULL; /* used to free thread contexts */ TaskState *first_task_state; @@ -738,6 +736,8 @@ TaskState *first_task_state; int main(int argc, char **argv) { const char *filename; + const char *log_file = DEBUG_LOGFILE; + const char *log_mask = NULL; struct target_pt_regs regs1, *regs = ®s1; TaskState ts1, *ts = &ts1; CPUState *env; @@ -749,9 +749,6 @@ int main(int argc, char **argv) if (argc <= 1) usage(); - /* init debug */ - cpu_set_log_filename(DEBUG_LOGFILE); - optind = 1; for(;;) { if (optind >= argc) @@ -764,22 +761,15 @@ int main(int argc, char **argv) if (!strcmp(r, "-")) { break; } else if (!strcmp(r, "d")) { - int mask; - CPULogItem *item; - - if (optind >= argc) - break; - - r = argv[optind++]; - mask = cpu_str_to_log_mask(r); - if (!mask) { - printf("Log items (comma separated):\n"); - for(item = cpu_log_items; item->mask != 0; item++) { - printf("%-10s %s\n", item->name, item->help); - } - exit(1); + if (optind >= argc) { + break; + } + log_mask = argv[optind++]; + } else if (!strcmp(r, "D")) { + if (optind >= argc) { + break; } - cpu_set_log(mask); + log_file = argv[optind++]; } else if (!strcmp(r, "s")) { r = argv[optind++]; stack_size = strtol(r, (char **)&r, 0); @@ -817,8 +807,27 @@ int main(int argc, char **argv) usage(); } } - if (optind >= argc) + + /* init debug */ + cpu_set_log_filename(log_file); + if (log_mask) { + int mask; + CPULogItem *item; + + mask = cpu_str_to_log_mask(log_mask); + if (!mask) { + printf("Log items (comma separated):\n"); + for (item = cpu_log_items; item->mask != 0; item++) { + printf("%-10s %s\n", item->name, item->help); + } + exit(1); + } + cpu_set_log(mask); + } + + if (optind >= argc) { usage(); + } filename = argv[optind]; /* Zero out regs */ @@ -841,8 +850,8 @@ int main(int argc, char **argv) #error unsupported CPU #endif } - - cpu_exec_init_all(0); + tcg_exec_init(0); + cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(cpu_model); diff --git a/darwin-user/signal.c b/darwin-user/signal.c index 4862018..c530227 100644 --- a/darwin-user/signal.c +++ b/darwin-user/signal.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -32,8 +31,6 @@ #undef uc_link #endif -#include - #include "qemu.h" #include "qemu-common.h" @@ -322,7 +319,6 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, void *set, CPUState *env) { void *frame; - int i, err = 0; fprintf(stderr, "setup_frame %d\n", sig); frame = get_sigframe(ka, env, sizeof(*frame)); diff --git a/darwin-user/syscall.c b/darwin-user/syscall.c index 060acc8..f3cc1f8 100644 --- a/darwin-user/syscall.c +++ b/darwin-user/syscall.c @@ -977,7 +977,7 @@ long do_unix_syscall_indirect(void *cpu_env, int num) #elif TARGET_PPC { int i; - /* XXX: not really needed those regs are volatile accross calls */ + /* XXX: not really needed those regs are volatile across calls */ uint32_t **regs = ((CPUPPCState*)cpu_env)->gpr; for(i = 11; i > 3; i--) *regs[i] = *regs[i-1]; diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 323fafb..e67ebb3 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -4,6 +4,7 @@ include pci.mak CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y CONFIG_VMWARE_VGA=y +CONFIG_VMMOUSE=y CONFIG_SERIAL=y CONFIG_PARALLEL=y CONFIG_I8254=y @@ -18,3 +19,6 @@ CONFIG_IDE_PIIX=y CONFIG_NE2000_ISA=y CONFIG_PIIX_PCI=y CONFIG_SOUND=y +CONFIG_HPET=y +CONFIG_APPLESMC=y +CONFIG_I8259=y diff --git a/default-configs/microblaze-softmmu.mak b/default-configs/microblaze-softmmu.mak index 4399b8b3..613edab 100644 --- a/default-configs/microblaze-softmmu.mak +++ b/default-configs/microblaze-softmmu.mak @@ -2,3 +2,4 @@ CONFIG_PTIMER=y CONFIG_PFLASH_CFI01=y +CONFIG_SERIAL=y diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak index f524971..94a3486 100644 --- a/default-configs/mips-softmmu.mak +++ b/default-configs/mips-softmmu.mak @@ -26,3 +26,5 @@ CONFIG_DP8393X=y CONFIG_DS1225Y=y CONFIG_MIPSNET=y CONFIG_PFLASH_CFI01=y +CONFIG_G364FB=y +CONFIG_I8259=y diff --git a/default-configs/mips64-softmmu.mak b/default-configs/mips64-softmmu.mak index aeab6b2..b5d3108 100644 --- a/default-configs/mips64-softmmu.mak +++ b/default-configs/mips64-softmmu.mak @@ -26,3 +26,5 @@ CONFIG_DP8393X=y CONFIG_DS1225Y=y CONFIG_MIPSNET=y CONFIG_PFLASH_CFI01=y +CONFIG_G364FB=y +CONFIG_I8259=y diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index 8e6511c..2831f44 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -28,3 +28,5 @@ CONFIG_DS1225Y=y CONFIG_MIPSNET=y CONFIG_PFLASH_CFI01=y CONFIG_FULONG=y +CONFIG_G364FB=y +CONFIG_I8259=y diff --git a/default-configs/mipsel-softmmu.mak b/default-configs/mipsel-softmmu.mak index a05ac25..14c949d 100644 --- a/default-configs/mipsel-softmmu.mak +++ b/default-configs/mipsel-softmmu.mak @@ -26,3 +26,5 @@ CONFIG_DP8393X=y CONFIG_DS1225Y=y CONFIG_MIPSNET=y CONFIG_PFLASH_CFI01=y +CONFIG_G364FB=y +CONFIG_I8259=y diff --git a/default-configs/pci.mak b/default-configs/pci.mak index 0471efb..22bd350 100644 --- a/default-configs/pci.mak +++ b/default-configs/pci.mak @@ -3,6 +3,7 @@ CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO=y CONFIG_USB_UHCI=y CONFIG_USB_OHCI=y +CONFIG_USB_EHCI=y CONFIG_NE2000_PCI=y CONFIG_EEPRO100_PCI=y CONFIG_PCNET_PCI=y diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index 4563742..c85cdce 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -31,3 +31,4 @@ CONFIG_SOUND=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y CONFIG_PTIMER=y +CONFIG_I8259=y diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index d5073b3..8874115 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -31,3 +31,4 @@ CONFIG_SOUND=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y CONFIG_PTIMER=y +CONFIG_I8259=y diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak index 9f0730c..5db7205 100644 --- a/default-configs/ppcemb-softmmu.mak +++ b/default-configs/ppcemb-softmmu.mak @@ -31,3 +31,4 @@ CONFIG_SOUND=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y CONFIG_PTIMER=y +CONFIG_I8259=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index eff26d2..b75757e 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -4,6 +4,7 @@ include pci.mak CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y CONFIG_VMWARE_VGA=y +CONFIG_VMMOUSE=y CONFIG_SERIAL=y CONFIG_PARALLEL=y CONFIG_I8254=y @@ -18,3 +19,6 @@ CONFIG_IDE_PIIX=y CONFIG_NE2000_ISA=y CONFIG_PIIX_PCI=y CONFIG_SOUND=y +CONFIG_HPET=y +CONFIG_APPLESMC=y +CONFIG_I8259=y diff --git a/device_tree.c b/device_tree.c index 426a631..86a694c 100644 --- a/device_tree.c +++ b/device_tree.c @@ -20,7 +20,6 @@ #include "config.h" #include "qemu-common.h" -#include "sysemu.h" #include "device_tree.h" #include "hw/loader.h" @@ -42,9 +41,10 @@ void *load_device_tree(const char *filename_path, int *sizep) } /* Expand to 2x size to give enough room for manipulation. */ + dt_size += 10000; dt_size *= 2; /* First allocate space in qemu for device tree */ - fdt = qemu_mallocz(dt_size); + fdt = g_malloc0(dt_size); dt_file_load_size = load_image(filename_path, fdt); if (dt_file_load_size < 0) { @@ -69,42 +69,104 @@ void *load_device_tree(const char *filename_path, int *sizep) return fdt; fail: - qemu_free(fdt); + g_free(fdt); return NULL; } -int qemu_devtree_setprop(void *fdt, const char *node_path, - const char *property, uint32_t *val_array, int size) +static int findnode_nofail(void *fdt, const char *node_path) { int offset; offset = fdt_path_offset(fdt, node_path); - if (offset < 0) - return offset; + if (offset < 0) { + fprintf(stderr, "%s Couldn't find node %s: %s\n", __func__, node_path, + fdt_strerror(offset)); + exit(1); + } - return fdt_setprop(fdt, offset, property, val_array, size); + return offset; +} + +int qemu_devtree_setprop(void *fdt, const char *node_path, + const char *property, void *val_array, int size) +{ + int r; + + r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val_array, size); + if (r < 0) { + fprintf(stderr, "%s: Couldn't set %s/%s: %s\n", __func__, node_path, + property, fdt_strerror(r)); + exit(1); + } + + return r; } int qemu_devtree_setprop_cell(void *fdt, const char *node_path, const char *property, uint32_t val) { - int offset; + int r; - offset = fdt_path_offset(fdt, node_path); - if (offset < 0) - return offset; + r = fdt_setprop_cell(fdt, findnode_nofail(fdt, node_path), property, val); + if (r < 0) { + fprintf(stderr, "%s: Couldn't set %s/%s = %#08x: %s\n", __func__, + node_path, property, val, fdt_strerror(r)); + exit(1); + } - return fdt_setprop_cell(fdt, offset, property, val); + return r; } int qemu_devtree_setprop_string(void *fdt, const char *node_path, const char *property, const char *string) { - int offset; + int r; - offset = fdt_path_offset(fdt, node_path); - if (offset < 0) - return offset; + r = fdt_setprop_string(fdt, findnode_nofail(fdt, node_path), property, string); + if (r < 0) { + fprintf(stderr, "%s: Couldn't set %s/%s = %s: %s\n", __func__, + node_path, property, string, fdt_strerror(r)); + exit(1); + } + + return r; +} + +int qemu_devtree_nop_node(void *fdt, const char *node_path) +{ + int r; + + r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path)); + if (r < 0) { + fprintf(stderr, "%s: Couldn't nop node %s: %s\n", __func__, node_path, + fdt_strerror(r)); + exit(1); + } + + return r; +} + +int qemu_devtree_add_subnode(void *fdt, const char *name) +{ + char *dupname = g_strdup(name); + char *basename = strrchr(dupname, '/'); + int retval; + + if (!basename) { + g_free(dupname); + return -1; + } + + basename[0] = '\0'; + basename++; + + retval = fdt_add_subnode(fdt, findnode_nofail(fdt, dupname), basename); + if (retval < 0) { + fprintf(stderr, "FDT: Failed to create subnode %s: %s\n", name, + fdt_strerror(retval)); + exit(1); + } - return fdt_setprop_string(fdt, offset, property, string); + g_free(dupname); + return retval; } diff --git a/device_tree.h b/device_tree.h index f05c4e7..4378685 100644 --- a/device_tree.h +++ b/device_tree.h @@ -17,10 +17,12 @@ void *load_device_tree(const char *filename_path, int *sizep); int qemu_devtree_setprop(void *fdt, const char *node_path, - const char *property, uint32_t *val_array, int size); + const char *property, void *val_array, int size); int qemu_devtree_setprop_cell(void *fdt, const char *node_path, const char *property, uint32_t val); int qemu_devtree_setprop_string(void *fdt, const char *node_path, const char *property, const char *string); +int qemu_devtree_nop_node(void *fdt, const char *node_path); +int qemu_devtree_add_subnode(void *fdt, const char *name); #endif /* __DEVICE_TREE_H__ */ diff --git a/dis-asm.h b/dis-asm.h index 296537a..4f15fad 100644 --- a/dis-asm.h +++ b/dis-asm.h @@ -184,6 +184,9 @@ enum bfd_architecture #define bfd_mach_sh5 0x50 bfd_arch_alpha, /* Dec Alpha */ #define bfd_mach_alpha 1 +#define bfd_mach_alpha_ev4 0x10 +#define bfd_mach_alpha_ev5 0x20 +#define bfd_mach_alpha_ev6 0x30 bfd_arch_arm, /* Advanced Risc Machines ARM */ #define bfd_mach_arm_unknown 0 #define bfd_mach_arm_2 1 @@ -362,6 +365,7 @@ typedef struct disassemble_info { target address. Return number of bytes processed. */ typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); +int print_insn_tci(bfd_vma, disassemble_info*); int print_insn_big_mips (bfd_vma, disassemble_info*); int print_insn_little_mips (bfd_vma, disassemble_info*); int print_insn_i386 (bfd_vma, disassemble_info*); diff --git a/disas.c b/disas.c index c76f36f..3b1fd97 100644 --- a/disas.c +++ b/disas.c @@ -5,7 +5,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" /* Filled in by elfload.c. Simplistic, but will do for now. */ @@ -138,7 +137,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info) /* Disassemble this for me please... (debugging). 'flags' has the following values: - i386 - nonzero means 16 bit code + i386 - 1 means 16 bit code, 2 means 64 bit code arm - nonzero means thumb code ppc - nonzero means little endian other targets - unused @@ -205,7 +204,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) disasm_info.mach = bfd_mach_sh4; print_insn = print_insn_sh; #elif defined(TARGET_ALPHA) - disasm_info.mach = bfd_mach_alpha; + disasm_info.mach = bfd_mach_alpha_ev6; print_insn = print_insn_alpha; #elif defined(TARGET_CRIS) if (flags != 32) { @@ -215,6 +214,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) disasm_info.mach = bfd_mach_cris_v32; print_insn = print_insn_crisv32; } +#elif defined(TARGET_S390X) + disasm_info.mach = bfd_mach_s390_64; + print_insn = print_insn_s390; #elif defined(TARGET_MICROBLAZE) disasm_info.mach = bfd_arch_microblaze; print_insn = print_insn_microblaze; @@ -271,7 +273,9 @@ void disas(FILE *out, void *code, unsigned long size) #else disasm_info.endian = BFD_ENDIAN_LITTLE; #endif -#if defined(__i386__) +#if defined(CONFIG_TCG_INTERPRETER) + print_insn = print_insn_tci; +#elif defined(__i386__) disasm_info.mach = bfd_mach_i386_i386; print_insn = print_insn_i386; #elif defined(__x86_64__) @@ -342,7 +346,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length, struct disassemble_info *info) { if (monitor_disas_is_physical) { - cpu_physical_memory_rw(memaddr, myaddr, length, 0); + cpu_physical_memory_read(memaddr, myaddr, length); } else { cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0); } @@ -414,6 +418,9 @@ void monitor_disas(Monitor *mon, CPUState *env, #elif defined(TARGET_SH4) disasm_info.mach = bfd_mach_sh4; print_insn = print_insn_sh; +#elif defined(TARGET_S390X) + disasm_info.mach = bfd_mach_s390_64; + print_insn = print_insn_s390; #else monitor_printf(mon, "0x" TARGET_FMT_lx ": Asm output not supported on this arch\n", pc); diff --git a/dma-helpers.c b/dma-helpers.c index 712ed89..bdcd38c 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -12,18 +12,17 @@ void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint) { - qsg->sg = qemu_malloc(alloc_hint * sizeof(ScatterGatherEntry)); + qsg->sg = g_malloc(alloc_hint * sizeof(ScatterGatherEntry)); qsg->nsg = 0; qsg->nalloc = alloc_hint; qsg->size = 0; } -void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, - target_phys_addr_t len) +void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len) { if (qsg->nsg == qsg->nalloc) { qsg->nalloc = 2 * qsg->nalloc + 1; - qsg->sg = qemu_realloc(qsg->sg, qsg->nalloc * sizeof(ScatterGatherEntry)); + qsg->sg = g_realloc(qsg->sg, qsg->nalloc * sizeof(ScatterGatherEntry)); } qsg->sg[qsg->nsg].base = base; qsg->sg[qsg->nsg].len = len; @@ -33,7 +32,7 @@ void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, void qemu_sglist_destroy(QEMUSGList *qsg) { - qemu_free(qsg->sg); + g_free(qsg->sg); } typedef struct { @@ -42,11 +41,13 @@ typedef struct { BlockDriverAIOCB *acb; QEMUSGList *sg; uint64_t sector_num; - int is_write; + bool to_dev; + bool in_cancel; int sg_cur_index; - target_phys_addr_t sg_cur_byte; + dma_addr_t sg_cur_byte; QEMUIOVector iov; QEMUBH *bh; + DMAIOFunc *io_func; } DMAAIOCB; static void dma_bdrv_cb(void *opaque, int ret); @@ -57,7 +58,7 @@ static void reschedule_dma(void *opaque) qemu_bh_delete(dbs->bh); dbs->bh = NULL; - dma_bdrv_cb(opaque, 0); + dma_bdrv_cb(dbs, 0); } static void continue_after_map_failure(void *opaque) @@ -74,9 +75,29 @@ static void dma_bdrv_unmap(DMAAIOCB *dbs) for (i = 0; i < dbs->iov.niov; ++i) { cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base, - dbs->iov.iov[i].iov_len, !dbs->is_write, + dbs->iov.iov[i].iov_len, !dbs->to_dev, dbs->iov.iov[i].iov_len); } + qemu_iovec_reset(&dbs->iov); +} + +static void dma_complete(DMAAIOCB *dbs, int ret) +{ + dma_bdrv_unmap(dbs); + if (dbs->common.cb) { + dbs->common.cb(dbs->common.opaque, ret); + } + qemu_iovec_destroy(&dbs->iov); + if (dbs->bh) { + qemu_bh_delete(dbs->bh); + dbs->bh = NULL; + } + if (!dbs->in_cancel) { + /* Requests may complete while dma_aio_cancel is in progress. In + * this case, the AIOCB should not be released because it is still + * referenced by dma_aio_cancel. */ + qemu_aio_release(dbs); + } } static void dma_bdrv_cb(void *opaque, int ret) @@ -88,19 +109,16 @@ static void dma_bdrv_cb(void *opaque, int ret) dbs->acb = NULL; dbs->sector_num += dbs->iov.size / 512; dma_bdrv_unmap(dbs); - qemu_iovec_reset(&dbs->iov); if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) { - dbs->common.cb(dbs->common.opaque, ret); - qemu_iovec_destroy(&dbs->iov); - qemu_aio_release(dbs); + dma_complete(dbs, ret); return; } while (dbs->sg_cur_index < dbs->sg->nsg) { cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte; cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte; - mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->is_write); + mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->to_dev); if (!mem) break; qemu_iovec_add(&dbs->iov, mem, cur_len); @@ -116,17 +134,10 @@ static void dma_bdrv_cb(void *opaque, int ret) return; } - if (dbs->is_write) { - dbs->acb = bdrv_aio_writev(dbs->bs, dbs->sector_num, &dbs->iov, - dbs->iov.size / 512, dma_bdrv_cb, dbs); - } else { - dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov, - dbs->iov.size / 512, dma_bdrv_cb, dbs); - } + dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov, + dbs->iov.size / 512, dma_bdrv_cb, dbs); if (!dbs->acb) { - dma_bdrv_unmap(dbs); - qemu_iovec_destroy(&dbs->iov); - return; + dma_complete(dbs, -EIO); } } @@ -135,8 +146,14 @@ static void dma_aio_cancel(BlockDriverAIOCB *acb) DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common); if (dbs->acb) { - bdrv_aio_cancel(dbs->acb); + BlockDriverAIOCB *acb = dbs->acb; + dbs->acb = NULL; + dbs->in_cancel = true; + bdrv_aio_cancel(acb); + dbs->in_cancel = false; } + dbs->common.cb = NULL; + dma_complete(dbs, 0); } static AIOPool dma_aio_pool = { @@ -144,12 +161,12 @@ static AIOPool dma_aio_pool = { .cancel = dma_aio_cancel, }; -static BlockDriverAIOCB *dma_bdrv_io( +BlockDriverAIOCB *dma_bdrv_io( BlockDriverState *bs, QEMUSGList *sg, uint64_t sector_num, - BlockDriverCompletionFunc *cb, void *opaque, - int is_write) + DMAIOFunc *io_func, BlockDriverCompletionFunc *cb, + void *opaque, bool to_dev) { - DMAAIOCB *dbs = qemu_aio_get(&dma_aio_pool, bs, cb, opaque); + DMAAIOCB *dbs = qemu_aio_get(&dma_aio_pool, bs, cb, opaque); dbs->acb = NULL; dbs->bs = bs; @@ -157,14 +174,11 @@ static BlockDriverAIOCB *dma_bdrv_io( dbs->sector_num = sector_num; dbs->sg_cur_index = 0; dbs->sg_cur_byte = 0; - dbs->is_write = is_write; + dbs->to_dev = to_dev; + dbs->io_func = io_func; dbs->bh = NULL; qemu_iovec_init(&dbs->iov, sg->nsg); dma_bdrv_cb(dbs, 0); - if (!dbs->acb) { - qemu_aio_release(dbs); - return NULL; - } return &dbs->common; } @@ -173,12 +187,12 @@ BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs, QEMUSGList *sg, uint64_t sector, void (*cb)(void *opaque, int ret), void *opaque) { - return dma_bdrv_io(bs, sg, sector, cb, opaque, 0); + return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque, false); } BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs, QEMUSGList *sg, uint64_t sector, void (*cb)(void *opaque, int ret), void *opaque) { - return dma_bdrv_io(bs, sg, sector, cb, opaque, 1); + return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, true); } diff --git a/dma.h b/dma.h index f3bb275..a13209d 100644 --- a/dma.h +++ b/dma.h @@ -15,23 +15,43 @@ #include "hw/hw.h" #include "block.h" -typedef struct { - target_phys_addr_t base; - target_phys_addr_t len; -} ScatterGatherEntry; +typedef struct ScatterGatherEntry ScatterGatherEntry; -typedef struct { +#if defined(TARGET_PHYS_ADDR_BITS) +typedef target_phys_addr_t dma_addr_t; + +#define DMA_ADDR_FMT TARGET_FMT_plx + +typedef enum { + DMA_DIRECTION_TO_DEVICE = 0, + DMA_DIRECTION_FROM_DEVICE = 1, +} DMADirection; + +struct ScatterGatherEntry { + dma_addr_t base; + dma_addr_t len; +}; + +struct QEMUSGList { ScatterGatherEntry *sg; int nsg; int nalloc; - target_phys_addr_t size; -} QEMUSGList; + dma_addr_t size; +}; void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint); -void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base, - target_phys_addr_t len); +void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len); void qemu_sglist_destroy(QEMUSGList *qsg); +#endif + +typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num, + QEMUIOVector *iov, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); +BlockDriverAIOCB *dma_bdrv_io(BlockDriverState *bs, + QEMUSGList *sg, uint64_t sector_num, + DMAIOFunc *io_func, BlockDriverCompletionFunc *cb, + void *opaque, bool to_dev); BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs, QEMUSGList *sg, uint64_t sector, BlockDriverCompletionFunc *cb, void *opaque); diff --git a/docs/qdev-device-use.txt b/docs/qdev-device-use.txt index 4bb2be8..136d271 100644 --- a/docs/qdev-device-use.txt +++ b/docs/qdev-device-use.txt @@ -8,20 +8,23 @@ more buses for children. You can specify a device's parent bus with A device typically has a device address on its parent bus. For buses where this address can be configured, devices provide a bus-specific -property. These are - - bus property name value format - PCI addr %x.%x (dev.fn, .fn optional) - I2C address %u - SCSI scsi-id %u +property. Examples: + + bus property name value format + PCI addr %x.%x (dev.fn, .fn optional) + I2C address %u + SCSI scsi-id %u + IDE unit %u + HDA cad %u + virtio-serial-bus nr %u + ccid-bus slot %u + USB port %d(.%d)* (port.port...) Example: device i440FX-pcihost is on the root bus, and provides a PCI bus named pci.0. To put a FOO device into its slot 4, use -device FOO,bus=/i440FX-pcihost/pci.0,addr=4. The abbreviated form bus=pci.0 also works as long as the bus name is unique. -Note: the USB device address can't be controlled at this time. - === Block Devices === A QEMU block device (drive) has a host and a guest part. @@ -44,28 +47,43 @@ The new way keeps the parts separate: you create the host part with The various old ways to define drives all boil down to the common form - -drive if=TYPE,index=IDX,bus=BUS,unit=UNIT,HOST-OPTS... + -drive if=TYPE,bus=BUS,unit=UNIT,OPTS... TYPE, BUS and UNIT identify the controller device, which of its buses to use, and the drive's address on that bus. Details depend on TYPE. -IDX is an alternative way to specify BUS and UNIT. + +Instead of bus=BUS,unit=UNIT, you can also say index=IDX. In the new way, this becomes something like -drive if=none,id=DRIVE-ID,HOST-OPTS... -device DEVNAME,drive=DRIVE-ID,DEV-OPTS... -The -device argument differs in detail for each kind of drive: +The old OPTS get split into HOST-OPTS and DEV-OPTS as follows: -* if=ide +* file, format, snapshot, cache, aio, readonly, rerror, werror go into + HOST-OPTS. + +* cyls, head, secs and trans go into HOST-OPTS. Future work: they + should go into DEV-OPTS instead. + +* serial goes into DEV-OPTS, for devices supporting serial numbers. + For other devices, it goes nowhere. - -device ide-drive,drive=DRIVE-ID,bus=IDE-BUS,unit=UNIT +* media is special. In the old way, it selects disk vs. CD-ROM with + if=ide, if=scsi and if=xen. The new way uses DEVNAME for that. + Additionally, readonly=on goes into HOST-OPTS. - where IDE-BUS identifies an IDE bus, normally either ide.0 or ide.1, - and UNIT is either 0 or 1. +* addr is special, see if=virtio below. - Bug: new way does not work for ide.1 unit 0 (in old terms: index=2) - unless you disable the default CD-ROM with -nodefaults. +The -device argument differs in detail for each type of drive: + +* if=ide + + -device DEVNAME,drive=DRIVE-ID,bus=IDE-BUS,unit=UNIT + + where DEVNAME is either ide-hd or ide-cd, IDE-BUS identifies an IDE + bus, normally either ide.0 or ide.1, and UNIT is either 0 or 1. * if=scsi @@ -77,27 +95,25 @@ The -device argument differs in detail for each kind of drive: As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to control the PCI device address. - This SCSI controller a single SCSI bus, named ID.0. Put a disk on - it: + This SCSI controller provides a single SCSI bus, named ID.0. Put a + disk on it: - -device scsi-disk,drive=DRIVE-ID,bus=ID.0,scsi-id=SCSI-ID,removable=RMB + -device DEVNAME,drive=DRIVE-ID,bus=ID.0,scsi-id=UNIT - The (optional) removable parameter lets you override the SCSI INQUIRY - removable (RMB) bit for non CD-ROM devices. It is ignored for CD-ROM devices - which are always removable. RMB is "on" or "off". + where DEVNAME is either scsi-hd, scsi-cd or scsi-generic. * if=floppy - -global isa-fdc,driveA=DRIVE-ID,driveB=DRIVE-ID + -global isa-fdc.driveA=DRIVE-ID + -global isa-fdc.driveB=DRIVE-ID This is -global instead of -device, because the floppy controller is created automatically, and we want to configure that one, not create a second one (which isn't possible anyway). - Omitting a drive parameter makes that drive empty. - - Bug: driveA works only if you disable the default floppy drive with - -nodefaults. + Without any -global isa-fdc,... you get an empty driveA and no + driveB. You can use -nodefaults to suppress the default driveA, see + "Default Devices". * if=virtio @@ -105,11 +121,12 @@ The -device argument differs in detail for each kind of drive: This lets you control PCI device class and MSI-X vectors. - IOEVENTFD controls whether or not ioeventfd is used for virtqueue notify. It - can be set to on (default) or off. + IOEVENTFD controls whether or not ioeventfd is used for virtqueue + notify. It can be set to on (default) or off. As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to - control the PCI device address. + control the PCI device address. This replaces option addr available + with -drive if=virtio. * if=pflash, if=mtd, if=sd, if=xen are not yet available with -device @@ -117,15 +134,20 @@ For USB devices, the old way is actually different: -usbdevice disk:format=FMT:FILENAME -Provides much less control than -drive's HOST-OPTS... The new way -fixes that: +Provides much less control than -drive's OPTS... The new way fixes +that: -device usb-storage,drive=DRIVE-ID,removable=RMB -The removable parameter gives control over the SCSI INQUIRY removable (RMB) -bit. USB thumbdrives usually set removable=on, while USB hard disks set -removable=off. See the if=scsi description above for details on the removable -parameter, which applies only to scsi-disk devices and not to scsi-generic. +The removable parameter gives control over the SCSI INQUIRY removable +(RMB) bit. USB thumbdrives usually set removable=on, while USB hard +disks set removable=off. + +Bug: usb-storage pretends to be a block device, but it's really a SCSI +controller that can serve only a single device, which it creates +automatically. The automatic creation guesses what kind of guest part +to create from the host part, like -drive if=scsi. Host and guest +part are not cleanly separated. === Character Devices === @@ -170,7 +192,9 @@ The appropriate DEVNAME depends on the machine type. For type "pc": -device usb-braille,chardev=braille,vendorid=VID,productid=PRID -chardev braille,id=braille -* -virtioconsole is still being worked on +* -virtioconsole becomes + -device virtio-serial-pci,class=C,vectors=V,ioeventfd=IOEVENTFD,max_ports=N + -device virtconsole,is_console=NUM,nr=NR,name=NAME LEGACY-CHARDEV translates to -chardev HOST-OPTS... as follows: @@ -184,7 +208,7 @@ LEGACY-CHARDEV translates to -chardev HOST-OPTS... as follows: * con: becomes -chardev console -* COM becomes -chardev serial,path= +* COM becomes -chardev serial,path=COM * file:FNAME becomes -chardev file,path=FNAME @@ -219,38 +243,29 @@ LEGACY-CHARDEV to refer to a host part defined with -chardev. === Network Devices === -A QEMU network device (NIC) has a host and a guest part. +Host and guest part of network devices have always been separate. -The old ways to define NICs define host and guest part together. It -looks like this: +The old way to define the guest part looks like this: - -net nic,vlan=VLAN,macaddr=MACADDR,model=MODEL,name=ID,addr=STR,vectors=V + -net nic,netdev=NET-ID,macaddr=MACADDR,model=MODEL,name=ID,addr=STR,vectors=V Except for USB it looks like this: - -usbdevice net:vlan=VLAN,macaddr=MACADDR,name=ID,addr=STR,vectors=V + -usbdevice net:netdev=NET-ID,macaddr=MACADDR,name=ID -The new way keeps the parts separate: you create the host part with --netdev, and the guest device with -device, like this: +The new way is -device: - -netdev type=TYPE,id=NET-ID -device DEVNAME,netdev=NET-ID,mac=MACADDR,DEV-OPTS... -Unlike the old way, this creates just a network device, not a VLAN. -If you really want a VLAN, create it the usual way, then create the -guest device like this: - - -device DEVNAME,vlan=VLAN,mac=MACADDR,DEV-OPTS... - DEVNAME equals MODEL, except for virtio you have to name the virtio device appropriate for the bus (virtio-net-pci for PCI), and for USB -NIC you have to use usb-net. +you have to use usb-net. The old name=ID parameter becomes the usual id=ID with -device. For PCI devices, you can add bus=PCI-BUS,addr=DEVFN to control the PCI device address, as usual. The old -net nic provides parameter addr -for that, it is silently ignored when the NIC is not a PCI device. +for that, which is silently ignored when the NIC is not a PCI device. For virtio-net-pci, you can control whether or not ioeventfd is used for virtqueue notify by setting ioeventfd= to on or off (default). @@ -264,20 +279,25 @@ devices and ne2k_isa are. Some PCI devices aren't available with -net nic, e.g. i82558a. -Bug: usb-net does not work, yet. Patch posted. +To connect to a VLAN instead of an ordinary host part, replace +netdev=NET-ID by vlan=VLAN. === Graphics Devices === Host and guest part of graphics devices have always been separate. -The old way to define the guest graphics device is -vga VGA. +The old way to define the guest graphics device is -vga VGA. Not all +machines support all -vga options. -The new way is -device. Map from -vga argument to -device: +The new way is -device. The mapping from -vga argument to -device +depends on the machine type. For machine "pc", it's: std -device VGA cirrus -device cirrus-vga vmware -device vmware-svga - xenfb not yet available with -device + qxl -device qxl-vga + none -nodefaults + disables more than just VGA, see "Default Devices" As for all PCI devices, you can add bus=PCI-BUS,addr=DEVFN to control the PCI device address. @@ -285,13 +305,16 @@ the PCI device address. -device VGA supports properties bios-offset and bios-size, but they aren't used with machine type "pc". -Bug: -device cirrus-vga and -device vmware-svga require -nodefaults. +For machine "isapc", it's -Bug: the new way requires PCI; ISA VGA is not yet available with --device. + std -device isa-vga + cirrus not yet available with -device + none -nodefaults + disables more than just VGA, see "Default Devices" -Bug: the new way doesn't work for machine type "pc", because it -violates obscure device initialization ordering constraints. +Bug: the new way doesn't work for machine types "pc" and "isapc", +because it violates obscure device initialization ordering +constraints. === Audio Devices === @@ -308,6 +331,7 @@ Map from -soundhw sound card name to -device: cs4231a -device cs4231a,iobase=IOADDR,irq=IRQ,dma=DMA es1370 -device ES1370 gus -device gus,iobase=IOADDR,irq=IRQ,dma=DMA,freq=F + hda -device intel-hda,msi=MSI -device hda-duplex sb16 -device sb16,iobase=IOADDR,irq=IRQ,dma=DMA,dma16=DMA16,version=V adlib not yet available with -device pcspk not yet available with -device @@ -321,9 +345,10 @@ The old way to define a virtual USB device is -usbdevice DRIVER:OPTS... The new way is -device DEVNAME,DEV-OPTS... Details depend on DRIVER: +* ccid -device usb-ccid +* keyboard -device usb-kbd * mouse -device usb-mouse * tablet -device usb-tablet -* keyboard -device usb-kdb * wacom-tablet -device usb-wacom-tablet * host:... See "Host Device Assignment" * disk:... See "Block Devices" @@ -353,7 +378,7 @@ The new way is -device pci-assign,host=ADDR,iommu=IOMMU,id=ID -The old dma=none becomes iommu=0 with -device. +The old dma=none becomes iommu=off with -device. The old way to assign a host USB device is @@ -365,4 +390,27 @@ The new way is -device usb-host,hostbus=BUS,hostaddr=ADDR,vendorid=VID,productid=PRID -where left out or zero BUS, ADDR, VID, PRID serve as wildcard. +Omitted options match anything, just like the old way's wildcard. + +=== Default Devices === + +QEMU creates a number of devices by default, depending on the machine +type. + +-device DEVNAME... and global DEVNAME... suppress default devices for +some DEVNAMEs: + + default device suppressing DEVNAMEs + CD-ROM ide-cd, ide-drive, scsi-cd + isa-fdc's driveA isa-fdc + parallel isa-parallel + serial isa-serial + VGA VGA, cirrus-vga, vmware-svga + virtioconsole virtio-serial-pci, virtio-serial-s390, virtio-serial + +The default NIC is connected to a default part created along with it. +It is *not* suppressed by configuring a NIC with -device (you may call +that a bug). -net and -netdev suppress the default NIC. + +-nodefaults suppresses all the default devices mentioned above, plus a +few other things such as default SD-Card drive and default monitor. diff --git a/docs/specs/qed_spec.txt b/docs/specs/qed_spec.txt index 1d5fa87..7982e05 100644 --- a/docs/specs/qed_spec.txt +++ b/docs/specs/qed_spec.txt @@ -89,6 +89,7 @@ L1, L2, and data cluster offsets must be aligned to header.cluster_size. The fo ===Data cluster offsets=== * 0 - unallocated. The data cluster is not yet allocated. +* 1 - zero. The data cluster contents are all zeroes and no cluster is allocated. Future format extensions may wish to store per-offset information. The least significant 12 bits of an offset are reserved for this purpose and must be set to zero. Image files with cluster_size > 2^12 will have more unused bits which should also be zeroed. @@ -97,6 +98,13 @@ Reads to an unallocated area of the image file access the backing file. If ther Writes to an unallocated area cause a new data clusters to be allocated, and a new L2 table if that is also unallocated. The new data cluster is populated with data from the backing file (or zeroes if no backing file) and the data being written. +===Zero data clusters=== +Zero data clusters are a space-efficient way of storing zeroed regions of the image. + +Reads to a zero data cluster produce zeroes. Note that the difference between an unallocated and a zero data cluster is that zero data clusters stop the reading of contents from the backing file. + +Writes to a zero data cluster cause a new data cluster to be allocated. The new data cluster is populated with zeroes and the data being written. + ===Logical offset translation=== Logical offsets are translated into cluster offsets as follows: diff --git a/docs/tracing.txt b/docs/tracing.txt index 21183f9..ea29f2c 100644 --- a/docs/tracing.txt +++ b/docs/tracing.txt @@ -12,13 +12,14 @@ for debugging, profiling, and observing execution. ./configure --trace-backend=simple make -2. Enable trace events you are interested in: +2. Create a file with the events you want to trace: - $EDITOR trace-events # remove "disable" from events you want + echo bdrv_aio_readv > /tmp/events + echo bdrv_aio_writev >> /tmp/events 3. Run the virtual machine to produce a trace file: - qemu ... # your normal QEMU invocation + qemu -trace events=/tmp/events ... # your normal QEMU invocation 4. Pretty-print the binary trace file: @@ -26,36 +27,38 @@ for debugging, profiling, and observing execution. == Trace events == -There is a set of static trace events declared in the trace-events source +There is a set of static trace events declared in the "trace-events" source file. Each trace event declaration names the event, its arguments, and the format string which can be used for pretty-printing: - qemu_malloc(size_t size, void *ptr) "size %zu ptr %p" - qemu_free(void *ptr) "ptr %p" + qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p" + qemu_vfree(void *ptr) "ptr %p" -The trace-events file is processed by the tracetool script during build to +The "trace-events" file is processed by the "tracetool" script during build to generate code for the trace events. Trace events are invoked directly from source code like this: #include "trace.h" /* needed for trace event prototype */ - - void *qemu_malloc(size_t size) + + void *qemu_vmalloc(size_t size) { void *ptr; - if (!size && !allow_zero_malloc()) { - abort(); + size_t align = QEMU_VMALLOC_ALIGN; + + if (size < align) { + align = getpagesize(); } - ptr = oom_check(malloc(size ? size : 1)); - trace_qemu_malloc(size, ptr); /* <-- trace event */ + ptr = qemu_memalign(align, size); + trace_qemu_vmalloc(size, ptr); return ptr; } === Declaring trace events === -The tracetool script produces the trace.h header file which is included by +The "tracetool" script produces the trace.h header file which is included by every source file that uses trace events. Since many source files include -trace.h, it uses a minimum of types and other header files included to keep -the namespace clean and compile times and dependencies down. +trace.h, it uses a minimum of types and other header files included to keep the +namespace clean and compile times and dependencies down. Trace events should use types as follows: @@ -74,10 +77,7 @@ Trace events should use types as follows: Format strings should reflect the types defined in the trace event. Take special care to use PRId64 and PRIu64 for int64_t and uint64_t types, -respectively. This ensures portability between 32- and 64-bit platforms. Note -that format strings must begin and end with double quotes. When using -portability macros, ensure they are preceded and followed by double quotes: -"value %"PRIx64"". +respectively. This ensures portability between 32- and 64-bit platforms. === Hints for adding new trace events === @@ -98,17 +98,59 @@ portability macros, ensure they are preceded and followed by double quotes: 4. Name trace events after their function. If there are multiple trace events in one function, append a unique distinguisher at the end of the name. -5. Declare trace events with the "disable" keyword. Some trace events can - produce a lot of output and users are typically only interested in a subset - of trace events. Marking trace events disabled by default saves the user - from having to manually disable noisy trace events. +5. If specific trace events are going to be called a huge number of times, this + might have a noticeable performance impact even when the trace events are + programmatically disabled. In this case you should declare the trace event + with the "disable" property, which will effectively disable it at compile + time (using the "nop" backend). + +== Generic interface and monitor commands == + +You can programmatically query and control the dynamic state of trace events +through a backend-agnostic interface: + +* trace_print_events + +* trace_event_set_state + Enables or disables trace events at runtime inside QEMU. + The function returns "true" if the state of the event has been successfully + changed, or "false" otherwise: + + #include "trace/control.h" + + trace_event_set_state("virtio_irq", true); /* enable */ + [...] + trace_event_set_state("virtio_irq", false); /* disable */ + +Note that some of the backends do not provide an implementation for this +interface, in which case QEMU will just print a warning. + +This functionality is also provided through monitor commands: + +* info trace-events + View available trace events and their state. State 1 means enabled, state 0 + means disabled. + +* trace-event NAME on|off + Enable/disable a given trace event or a group of events having common prefix + through wildcard. + +The "-trace events=" command line argument can be used to enable the +events listed in from the very beginning of the program. This file must +contain one event name per line. + +A basic wildcard matching is supported in both the monitor command "trace +-event" and the events list file. That means you can enable/disable the events +having a common prefix in a batch. For example, virtio-blk trace events could +be enabled using: + trace-event virtio_blk_* on == Trace backends == -The tracetool script automates tedious trace event code generation and also +The "tracetool" script automates tedious trace event code generation and also keeps the trace event declarations independent of the trace backend. The trace events are not tightly coupled to a specific trace backend, such as LTTng or -SystemTap. Support for trace backends can be added by extending the tracetool +SystemTap. Support for trace backends can be added by extending the "tracetool" script. The trace backend is chosen at configure time and only one trace backend can @@ -126,6 +168,17 @@ The "nop" backend generates empty trace event functions so that the compiler can optimize out trace events completely. This is the default and imposes no performance penalty. +Note that regardless of the selected trace backend, events with the "disable" +property will be generated with the "nop" backend. + +=== Stderr === + +The "stderr" backend sends trace events directly to standard error. This +effectively turns trace events into debug printfs. + +This is the simplest backend and can be used together with existing code that +uses DPRINTF(). + === Simpletrace === The "simple" backend supports common use cases and comes as part of the QEMU @@ -133,10 +186,8 @@ source tree. It may not be as powerful as platform-specific or third-party trace backends but it is portable. This is the recommended trace backend unless you have specific needs for more advanced backends. -=== Stderr === - -The "stderr" backend sends trace events directly to standard error output -during emulation. +The "simple" backend currently does not capture string arguments, it simply +records the char* pointer value instead of the string that is pointed to. ==== Monitor commands ==== @@ -149,36 +200,18 @@ during emulation. flushed and emptied. This means the 'info trace' will display few or no entries if the buffer has just been flushed. -* info trace-events - View available trace events and their state. State 1 means enabled, state 0 - means disabled. - -* trace-event NAME on|off - Enable/disable a given trace event. - * trace-file on|off|flush|set Enable/disable/flush the trace file or set the trace file name. -==== Enabling/disabling trace events programmatically ==== - -The st_change_trace_event_state() function can be used to enable or disable trace -events at runtime inside QEMU: - - #include "trace.h" - - st_change_trace_event_state("virtio_irq", true); /* enable */ - [...] - st_change_trace_event_state("virtio_irq", false); /* disable */ - ==== Analyzing trace files ==== The "simple" backend produces binary trace files that can be formatted with the -simpletrace.py script. The script takes the trace-events file and the binary +simpletrace.py script. The script takes the "trace-events" file and the binary trace: ./simpletrace.py trace-events trace-12345 -You must ensure that the same trace-events file was used to build QEMU, +You must ensure that the same "trace-events" file was used to build QEMU, otherwise trace event declarations may have changed and output will not be consistent. @@ -187,3 +220,17 @@ consistent. The "ust" backend uses the LTTng Userspace Tracer library. There are no monitor commands built into QEMU, instead UST utilities should be used to list, enable/disable, and dump traces. + +=== SystemTap === + +The "dtrace" backend uses DTrace sdt probes but has only been tested with +SystemTap. When SystemTap support is detected a .stp file with wrapper probes +is generated to make use in scripts more convenient. This step can also be +performed manually after a build in order to change the binary name in the .stp +probes: + + scripts/tracetool --dtrace --stap \ + --binary path/to/qemu-binary \ + --target-type system \ + --target-arch x86_64 \ + qemu.stp diff --git a/dyngen-exec.h b/dyngen-exec.h index db00fba..3544372 100644 --- a/dyngen-exec.h +++ b/dyngen-exec.h @@ -19,16 +19,12 @@ #if !defined(__DYNGEN_EXEC_H__) #define __DYNGEN_EXEC_H__ -#include "qemu-common.h" - -#ifdef __OpenBSD__ -#include -#endif - -/* XXX: This may be wrong for 64-bit ILP32 hosts. */ -typedef void * host_reg_t; - -#if defined(__i386__) +#if defined(CONFIG_TCG_INTERPRETER) +/* The TCG interpreter does not need a special register AREG0, + * but it is possible to use one by defining AREG0. + * On i386, register edi seems to work. */ +/* Run without special register AREG0 or use a value defined elsewhere. */ +#elif defined(__i386__) #define AREG0 "ebp" #elif defined(__x86_64__) #define AREG0 "r14" @@ -64,21 +60,11 @@ typedef void * host_reg_t; #error unsupported CPU #endif -#define xglue(x, y) x ## y -#define glue(x, y) xglue(x, y) -#define stringify(s) tostring(s) -#define tostring(s) #s - -/* The return address may point to the start of the next instruction. - Subtracting one gets us the call instruction itself. */ -#if defined(__s390__) && !defined(__s390x__) -# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1)) -#elif defined(__arm__) -/* Thumb return addresses have the low bit set, so we need to subtract two. - This is still safe in ARM mode because instructions are 4 bytes. */ -# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2)) +#if defined(AREG0) +register CPUState *env asm(AREG0); #else -# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1)) +/* TODO: Try env = cpu_single_env. */ +extern CPUState *env; #endif #endif /* !defined(__DYNGEN_EXEC_H__) */ diff --git a/elf.h b/elf.h index 7067c90..2e05d34 100644 --- a/elf.h +++ b/elf.h @@ -104,6 +104,9 @@ typedef int64_t Elf64_Sxword; #define EM_H8_300H 47 /* Hitachi H8/300H */ #define EM_H8S 48 /* Hitachi H8S */ +#define EM_LATTICEMICO32 138 /* LatticeMico32 */ + +#define EM_UNICORE32 110 /* UniCore32 */ /* * This is an interim value that we will use until the committee comes @@ -122,6 +125,8 @@ typedef int64_t Elf64_Sxword; #define EM_MICROBLAZE 189 #define EM_MICROBLAZE_OLD 0xBAAB +#define EM_XTENSA 94 /* Tensilica Xtensa */ + /* This is the info that is needed to parse the dynamic section of the file */ #define DT_NULL 0 #define DT_NEEDED 1 @@ -1191,6 +1196,25 @@ typedef struct elf64_note { Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; + +/* This data structure represents a PT_LOAD segment. */ +struct elf32_fdpic_loadseg { + /* Core address to which the segment is mapped. */ + Elf32_Addr addr; + /* VMA recorded in the program header. */ + Elf32_Addr p_vaddr; + /* Size of this segment in memory. */ + Elf32_Word p_memsz; +}; +struct elf32_fdpic_loadmap { + /* Protocol version number, must be zero. */ + Elf32_Half version; + /* Number of segments in this map. */ + Elf32_Half nsegs; + /* The actual memory map. */ + struct elf32_fdpic_loadseg segs[/*nsegs*/]; +}; + #ifdef ELF_CLASS #if ELF_CLASS == ELFCLASS32 diff --git a/exec-all.h b/exec-all.h index 8871d9a..3819bef 100644 --- a/exec-all.h +++ b/exec-all.h @@ -40,10 +40,11 @@ typedef ram_addr_t tb_page_addr_t; #define DISAS_UPDATE 2 /* cpu state was modified dynamically */ #define DISAS_TB_JUMP 3 /* only pc was modified statically */ +struct TranslationBlock; typedef struct TranslationBlock TranslationBlock; /* XXX: make safe guess about sizes */ -#define MAX_OP_PER_INSTR 96 +#define MAX_OP_PER_INSTR 208 #if HOST_LONG_BITS == 32 #define MAX_OPC_PARAM_PER_ARG 2 @@ -77,26 +78,24 @@ extern uint16_t gen_opc_icount[OPC_BUF_SIZE]; void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); -void gen_pc_load(CPUState *env, struct TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc); +void restore_state_to_opc(CPUState *env, struct TranslationBlock *tb, + int pc_pos); void cpu_gen_init(void); int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, int *gen_code_size_ptr); int cpu_restore_state(struct TranslationBlock *tb, - CPUState *env, unsigned long searched_pc, - void *puc); + CPUState *env, unsigned long searched_pc); void cpu_resume_from_signal(CPUState *env1, void *puc); void cpu_io_recompile(CPUState *env, void *retaddr); TranslationBlock *tb_gen_code(CPUState *env, target_ulong pc, target_ulong cs_base, int flags, int cflags); void cpu_exec_init(CPUState *env); -void QEMU_NORETURN cpu_loop_exit(void); +void QEMU_NORETURN cpu_loop_exit(CPUState *env1); int page_unprotect(target_ulong address, unsigned long pc, void *puc); void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, int is_cpu_write_access); -void tb_invalidate_page_range(target_ulong start, target_ulong end); void tlb_flush_page(CPUState *env, target_ulong addr); void tlb_flush(CPUState *env, int flush_global); #if !defined(CONFIG_USER_ONLY) @@ -123,6 +122,8 @@ void tlb_set_page(CPUState *env, target_ulong vaddr, #if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__) #define USE_DIRECT_JUMP +#elif defined(CONFIG_TCG_INTERPRETER) +#define USE_DIRECT_JUMP #endif struct TranslationBlock { @@ -158,9 +159,6 @@ struct TranslationBlock { struct TranslationBlock *jmp_next[2]; struct TranslationBlock *jmp_first; uint32_t icount; -#ifdef CONFIG_EXEC_PROFILE - uint32_t tbexec_count[2]; -#endif }; static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) @@ -183,7 +181,6 @@ static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc) return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1); } -TranslationBlock *tb_alloc(target_ulong pc); void tb_free(TranslationBlock *tb); void tb_flush(CPUState *env); void tb_link_page(TranslationBlock *tb, @@ -194,7 +191,14 @@ extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; #if defined(USE_DIRECT_JUMP) -#if defined(_ARCH_PPC) +#if defined(CONFIG_TCG_INTERPRETER) +static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) +{ + /* patch the branch destination */ + *(uint32_t *)jmp_addr = addr - (jmp_addr + 4); + /* no need to flush icache explicitly */ +} +#elif defined(_ARCH_PPC) void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr); #define tb_set_jmp_target1 ppc_tb_set_jmp_target #elif defined(__i386__) || defined(__x86_64__) @@ -228,6 +232,8 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg)); #endif } +#else +#error tb_set_jmp_target1 is missing #endif static inline void tb_set_jmp_target(TranslationBlock *tb, @@ -272,13 +278,32 @@ extern spinlock_t tb_lock; extern int tb_invalidated_flag; +/* The return address may point to the start of the next instruction. + Subtracting one gets us the call instruction itself. */ +#if defined(CONFIG_TCG_INTERPRETER) +/* Alpha and SH4 user mode emulations and Softmmu call GETPC(). + For all others, GETPC remains undefined (which makes TCI a little faster. */ +# if defined(CONFIG_SOFTMMU) || defined(TARGET_ALPHA) || defined(TARGET_SH4) +extern void *tci_tb_ptr; +# define GETPC() tci_tb_ptr +# endif +#elif defined(__s390__) && !defined(__s390x__) +# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1)) +#elif defined(__arm__) +/* Thumb return addresses have the low bit set, so we need to subtract two. + This is still safe in ARM mode because instructions are 4 bytes. */ +# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2)) +#else +# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1)) +#endif + #if !defined(CONFIG_USER_ONLY) extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; -void tlb_fill(target_ulong addr, int is_write, int mmu_idx, +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, void *retaddr); #include "softmmu_defs.h" @@ -327,19 +352,20 @@ static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong add } pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK; if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { -#if defined(TARGET_SPARC) || defined(TARGET_MIPS) - do_unassigned_access(addr, 0, 1, 0, 4); +#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC) + cpu_unassigned_access(env1, addr, 0, 1, 0, 4); #else cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr); #endif } - p = (void *)(unsigned long)addr - + env1->tlb_table[mmu_idx][page_index].addend; + p = (void *)((uintptr_t)addr + env1->tlb_table[mmu_idx][page_index].addend); return qemu_ram_addr_from_host_nofail(p); } -#if defined(CONFIG_TCG_TARGET_X86_OPT) -/* extended versions of MMU helpers for x86 TCG target optimization */ +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) +/* Extended versions of MMU helpers for qemu_ld/st optimization. + They get return address arguments because the caller PCs are not where helpers return to. */ +#if defined(__i386__) || defined(__x86_64__) uint8_t REGPARM __ldextb_mmu(target_ulong addr, int mmu_idx, void *ra); void REGPARM __stextb_mmu(target_ulong addr, uint8_t val, int mmu_idx, void *ra); uint16_t REGPARM __ldextw_mmu(target_ulong addr, int mmu_idx, void *ra); @@ -348,7 +374,9 @@ uint32_t REGPARM __ldextl_mmu(target_ulong addr, int mmu_idx, void *ra); void REGPARM __stextl_mmu(target_ulong addr, uint32_t val, int mmu_idx, void *ra); uint64_t REGPARM __ldextq_mmu(target_ulong addr, int mmu_idx, void *ra); void REGPARM __stextq_mmu(target_ulong addr, uint64_t val, int mmu_idx, void *ra); -#endif /* CONFIG_TCG_TARGET_X86_OPT */ +#endif +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */ + #endif typedef void (CPUDebugExcpHandler)(CPUState *env); @@ -361,4 +389,18 @@ extern int singlestep; /* cpu-exec.c */ extern volatile sig_atomic_t exit_request; +/* Deterministic execution requires that IO only be performed on the last + instruction of a TB so that interrupts take effect immediately. */ +static inline int can_do_io(CPUState *env) +{ + if (!use_icount) { + return 1; + } + /* If not executing code then assume we are ok. */ + if (!env->current_tb) { + return 1; + } + return env->can_do_io != 0; +} + #endif diff --git a/exec.c b/exec.c index e950df2..a027be9 100644 --- a/exec.c +++ b/exec.c @@ -26,16 +26,18 @@ #include "qemu-common.h" #include "cpu.h" -#include "exec-all.h" #include "tcg.h" #include "hw/hw.h" #include "hw/qdev.h" #include "osdep.h" #include "kvm.h" +#include "hax.h" +#include "hw/xen.h" #include "qemu-timer.h" +#include "memory.h" +#include "exec-memory.h" #if defined(CONFIG_USER_ONLY) #include -#include #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include #if __FreeBSD_version >= 700104 @@ -51,6 +53,9 @@ #include #endif #endif +#else /* !CONFIG_USER_ONLY */ +#include "xen-mapcache.h" +#include "trace.h" #endif //#define DEBUG_TB_INVALIDATE @@ -106,20 +111,21 @@ static uint8_t *code_gen_ptr; int phys_ram_fd; static int in_migration; -RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) }; +RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) }; + +static MemoryRegion *system_memory; +static MemoryRegion *system_io; + #endif CPUState *first_cpu; /* current CPU in the current thread. It is only valid inside cpu_exec() */ -CPUState *cpu_single_env; +DEFINE_TLS(CPUState *,cpu_single_env); /* 0 = Do not count executed instructions. 1 = Precise instruction counting. 2 = Adaptive rate instruction counting. */ int use_icount = 0; -/* Current instruction counter. While executing translated code this may - include some instructions that have not yet been executed. */ -int64_t qemu_icount; typedef struct PageDesc { /* list of TBs intersecting this ram page */ @@ -175,7 +181,6 @@ typedef struct PageDesc { #define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS) unsigned long qemu_real_host_page_size; -unsigned long qemu_host_page_bits; unsigned long qemu_host_page_size; unsigned long qemu_host_page_mask; @@ -195,6 +200,7 @@ typedef struct PhysPageDesc { static void *l1_phys_map[P_L1_SIZE]; static void io_mem_init(void); +static void memory_map_init(void); /* io memory support */ CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; @@ -265,9 +271,6 @@ static void page_init(void) qemu_host_page_size = qemu_real_host_page_size; if (qemu_host_page_size < TARGET_PAGE_SIZE) qemu_host_page_size = TARGET_PAGE_SIZE; - qemu_host_page_bits = 0; - while ((1 << qemu_host_page_bits) < qemu_host_page_size) - qemu_host_page_bits++; qemu_host_page_mask = ~(qemu_host_page_size - 1); #if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY) @@ -343,7 +346,7 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc) int i; #if defined(CONFIG_USER_ONLY) - /* We can't use qemu_malloc because it may recurse into a locked mutex. */ + /* We can't use g_malloc because it may recurse into a locked mutex. */ # define ALLOC(P, SIZE) \ do { \ P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \ @@ -351,7 +354,7 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc) } while (0) #else # define ALLOC(P, SIZE) \ - do { P = qemu_mallocz(SIZE); } while (0) + do { P = g_malloc0(SIZE); } while (0) #endif /* Level 1. Always allocated. */ @@ -408,7 +411,7 @@ static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc) if (!alloc) { return NULL; } - *lp = p = qemu_mallocz(sizeof(void *) * L2_SIZE); + *lp = p = g_malloc0(sizeof(void *) * L2_SIZE); } lp = p + ((index >> (i * L2_BITS)) & (L2_SIZE - 1)); } @@ -421,7 +424,7 @@ static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc) return NULL; } - *lp = pd = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE); + *lp = pd = g_malloc(sizeof(PhysPageDesc) * L2_SIZE); for (i = 0; i < L2_SIZE; i++) { pd[i].phys_offset = IO_MEM_UNASSIGNED; @@ -467,7 +470,6 @@ static void code_gen_alloc(unsigned long tb_size) code_gen_buffer_size = tb_size; if (code_gen_buffer_size == 0) { #if defined(CONFIG_USER_ONLY) - /* in user mode, phys_ram_size is not meaningful */ code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE; #else /* XXX: needs adjustments */ @@ -518,7 +520,8 @@ static void code_gen_alloc(unsigned long tb_size) } } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \ - || defined(__DragonFly__) || defined(__OpenBSD__) + || defined(__DragonFly__) || defined(__OpenBSD__) \ + || defined(__NetBSD__) { int flags; void *addr = NULL; @@ -548,29 +551,26 @@ static void code_gen_alloc(unsigned long tb_size) } } #else - code_gen_buffer = qemu_malloc(code_gen_buffer_size); + code_gen_buffer = g_malloc(code_gen_buffer_size); map_exec(code_gen_buffer, code_gen_buffer_size); #endif #endif /* !USE_STATIC_CODE_GEN_BUFFER */ map_exec(code_gen_prologue, sizeof(code_gen_prologue)); - code_gen_buffer_max_size = code_gen_buffer_size - - (TCG_MAX_OP_SIZE * OPC_MAX_SIZE); + code_gen_buffer_max_size = code_gen_buffer_size - + (TCG_MAX_OP_SIZE * OPC_BUF_SIZE); code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE; - tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock)); + tbs = g_malloc(code_gen_max_blocks * sizeof(TranslationBlock)); } /* Must be called before using the QEMU cpus. 'tb_size' is the size (in bytes) allocated to the translation buffer. Zero means default size. */ -void cpu_exec_init_all(unsigned long tb_size) +void tcg_exec_init(unsigned long tb_size) { cpu_gen_init(); code_gen_alloc(tb_size); code_gen_ptr = code_gen_buffer; page_init(); -#if !defined(CONFIG_USER_ONLY) - io_mem_init(); -#endif #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE) /* There's no guest base to take into account, so go ahead and initialize the prologue now. */ @@ -578,6 +578,19 @@ void cpu_exec_init_all(unsigned long tb_size) #endif } +bool tcg_enabled(void) +{ + return code_gen_buffer != NULL; +} + +void cpu_exec_init_all(void) +{ +#if !defined(CONFIG_USER_ONLY) + memory_map_init(); + io_mem_init(); +#endif +} + #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) static int cpu_common_post_load(void *opaque, int version_id) @@ -638,6 +651,9 @@ void cpu_exec_init(CPUState *env) env->numa_node = 0; QTAILQ_INIT(&env->breakpoints); QTAILQ_INIT(&env->watchpoints); +#ifndef CONFIG_USER_ONLY + env->thread_id = qemu_get_thread_id(); +#endif *penv = env; #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); @@ -649,10 +665,36 @@ void cpu_exec_init(CPUState *env) #endif } +/* Allocate a new translation block. Flush the translation buffer if + too many translation blocks or too much generated code. */ +static TranslationBlock *tb_alloc(target_ulong pc) +{ + TranslationBlock *tb; + + if (nb_tbs >= code_gen_max_blocks || + (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) + return NULL; + tb = &tbs[nb_tbs++]; + tb->pc = pc; + tb->cflags = 0; + return tb; +} + +void tb_free(TranslationBlock *tb) +{ + /* In practice this is mostly used for single use temporary TB + Ignore the hard cases and just back up if this TB happens to + be the last one generated. */ + if (nb_tbs > 0 && tb == &tbs[nb_tbs - 1]) { + code_gen_ptr = tb->tc_ptr; + nb_tbs--; + } +} + static inline void invalidate_page_bitmap(PageDesc *p) { if (p->code_bitmap) { - qemu_free(p->code_bitmap); + g_free(p->code_bitmap); p->code_bitmap = NULL; } p->code_write_count = 0; @@ -912,7 +954,7 @@ static void build_page_bitmap(PageDesc *p) int n, tb_start, tb_end; TranslationBlock *tb; - p->code_bitmap = qemu_mallocz(TARGET_PAGE_SIZE / 8); + p->code_bitmap = g_malloc0(TARGET_PAGE_SIZE / 8); tb = p->first_tb; while (tb != NULL) { @@ -1041,8 +1083,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, restore the CPU state */ current_tb_modified = 1; - cpu_restore_state(current_tb, env, - env->mem_io_pc, NULL); + cpu_restore_state(current_tb, env, env->mem_io_pc); cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, ¤t_flags); } @@ -1150,7 +1191,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr, restore the CPU state */ current_tb_modified = 1; - cpu_restore_state(current_tb, env, pc, puc); + cpu_restore_state(current_tb, env, pc); cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, ¤t_flags); } @@ -1177,12 +1218,16 @@ static inline void tb_alloc_page(TranslationBlock *tb, unsigned int n, tb_page_addr_t page_addr) { PageDesc *p; - TranslationBlock *last_first_tb; +#ifndef CONFIG_USER_ONLY + bool page_already_protected; +#endif tb->page_addr[n] = page_addr; p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1); tb->page_next[n] = p->first_tb; - last_first_tb = p->first_tb; +#ifndef CONFIG_USER_ONLY + page_already_protected = p->first_tb != NULL; +#endif p->first_tb = (TranslationBlock *)((long)tb | n); invalidate_page_bitmap(p); @@ -1218,7 +1263,7 @@ static inline void tb_alloc_page(TranslationBlock *tb, /* if some code is already present, then the pages are already protected. So we handle the case where only the first TB is allocated in a physical page */ - if (!last_first_tb) { + if (!page_already_protected) { tlb_protect_code(page_addr); } #endif @@ -1226,32 +1271,6 @@ static inline void tb_alloc_page(TranslationBlock *tb, #endif /* TARGET_HAS_SMC */ } -/* Allocate a new translation block. Flush the translation buffer if - too many translation blocks or too much generated code. */ -TranslationBlock *tb_alloc(target_ulong pc) -{ - TranslationBlock *tb; - - if (nb_tbs >= code_gen_max_blocks || - (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) - return NULL; - tb = &tbs[nb_tbs++]; - tb->pc = pc; - tb->cflags = 0; - return tb; -} - -void tb_free(TranslationBlock *tb) -{ - /* In practice this is mostly used for single use temporary TB - Ignore the hard cases and just back up if this TB happens to - be the last one generated. */ - if (nb_tbs > 0 && tb == &tbs[nb_tbs - 1]) { - code_gen_ptr = tb->tc_ptr; - nb_tbs--; - } -} - /* add a new TB and link it to the physical page tables. phys_page2 is (-1) to indicate that only one page contains the TB. */ void tb_link_page(TranslationBlock *tb, @@ -1422,7 +1441,7 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len, TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len); return -EINVAL; } - wp = qemu_malloc(sizeof(*wp)); + wp = g_malloc(sizeof(*wp)); wp->vaddr = addr; wp->len_mask = len_mask; @@ -1465,7 +1484,7 @@ void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint) tlb_flush_page(env, watchpoint->vaddr); - qemu_free(watchpoint); + g_free(watchpoint); } /* Remove all matching watchpoints. */ @@ -1487,7 +1506,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags, #if defined(TARGET_HAS_ICE) CPUBreakpoint *bp; - bp = qemu_malloc(sizeof(*bp)); + bp = g_malloc(sizeof(*bp)); bp->pc = pc; bp->flags = flags; @@ -1534,7 +1553,7 @@ void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint) breakpoint_invalidate(env, breakpoint->pc); - qemu_free(breakpoint); + g_free(breakpoint); #endif } @@ -1627,38 +1646,46 @@ static void cpu_unlink_tb(CPUState *env) spin_unlock(&interrupt_lock); } +#ifndef CONFIG_USER_ONLY /* mask must never be zero, except for A20 change call */ -void cpu_interrupt(CPUState *env, int mask) +static void tcg_handle_interrupt(CPUState *env, int mask) { int old_mask; old_mask = env->interrupt_request; env->interrupt_request |= mask; -#ifndef CONFIG_USER_ONLY /* * If called from iothread context, wake the target cpu in * case its halted. */ - if (!qemu_cpu_self(env)) { + if (!qemu_cpu_is_self(env)) { qemu_cpu_kick(env); return; } -#endif if (use_icount) { env->icount_decr.u16.high = 0xffff; -#ifndef CONFIG_USER_ONLY if (!can_do_io(env) && (mask & ~old_mask) != 0) { cpu_abort(env, "Raised interrupt while not in I/O function"); } -#endif } else { cpu_unlink_tb(env); } } +CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt; + +#else /* CONFIG_USER_ONLY */ + +void cpu_interrupt(CPUState *env, int mask) +{ + env->interrupt_request |= mask; + cpu_unlink_tb(env); +} +#endif /* CONFIG_USER_ONLY */ + void cpu_reset_interrupt(CPUState *env, int mask) { env->interrupt_request &= ~mask; @@ -1708,11 +1735,12 @@ static QLIST_HEAD(memory_client_list, CPUPhysMemoryClient) memory_client_list static void cpu_notify_set_memory(target_phys_addr_t start_addr, ram_addr_t size, - ram_addr_t phys_offset) + ram_addr_t phys_offset, + bool log_dirty) { CPUPhysMemoryClient *client; QLIST_FOREACH(client, &memory_client_list, list) { - client->set_memory(client, start_addr, size, phys_offset); + client->set_memory(client, start_addr, size, phys_offset, log_dirty); } } @@ -1739,8 +1767,21 @@ static int cpu_notify_migration_log(int enable) return 0; } -static void phys_page_for_each_1(CPUPhysMemoryClient *client, - int level, void **lp) +struct last_map { + target_phys_addr_t start_addr; + ram_addr_t size; + ram_addr_t phys_offset; +}; + +/* The l1_phys_map provides the upper P_L1_BITs of the guest physical + * address. Each intermediate table provides the next L2_BITs of guest + * physical address space. The number of levels vary based on host and + * guest configuration, making it efficient to build the final guest + * physical address by seeding the L1 offset and shifting and adding in + * each L2 offset as we recurse through them. */ +static void phys_page_for_each_1(CPUPhysMemoryClient *client, int level, + void **lp, target_phys_addr_t addr, + struct last_map *map) { int i; @@ -1749,16 +1790,32 @@ static void phys_page_for_each_1(CPUPhysMemoryClient *client, } if (level == 0) { PhysPageDesc *pd = *lp; + addr <<= L2_BITS + TARGET_PAGE_BITS; for (i = 0; i < L2_SIZE; ++i) { if (pd[i].phys_offset != IO_MEM_UNASSIGNED) { - client->set_memory(client, pd[i].region_offset, - TARGET_PAGE_SIZE, pd[i].phys_offset); + target_phys_addr_t start_addr = addr | i << TARGET_PAGE_BITS; + + if (map->size && + start_addr == map->start_addr + map->size && + pd[i].phys_offset == map->phys_offset + map->size) { + + map->size += TARGET_PAGE_SIZE; + continue; + } else if (map->size) { + client->set_memory(client, map->start_addr, + map->size, map->phys_offset, false); + } + + map->start_addr = start_addr; + map->size = TARGET_PAGE_SIZE; + map->phys_offset = pd[i].phys_offset; } } } else { void **pp = *lp; for (i = 0; i < L2_SIZE; ++i) { - phys_page_for_each_1(client, level - 1, pp + i); + phys_page_for_each_1(client, level - 1, pp + i, + (addr << L2_BITS) | i, map); } } } @@ -1766,9 +1823,15 @@ static void phys_page_for_each_1(CPUPhysMemoryClient *client, static void phys_page_for_each(CPUPhysMemoryClient *client) { int i; + struct last_map map = { }; + for (i = 0; i < P_L1_SIZE; ++i) { phys_page_for_each_1(client, P_L1_SHIFT / L2_BITS - 1, - l1_phys_map + 1); + l1_phys_map + i, i, &map); + } + if (map.size) { + client->set_memory(client, map.start_addr, map.size, map.phys_offset, + false); } } @@ -2039,7 +2102,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, /* we modify the TLB cache so that the dirty bit will be set again when accessing the range */ start1 = (unsigned long)qemu_safe_ram_ptr(start); - /* Chek that we don't span multiple blocks - this breaks the + /* Check that we don't span multiple blocks - this breaks the address comparisons below. */ if ((unsigned long)qemu_safe_ram_ptr(end - 1) - start1 != (end - 1) - start) { @@ -2078,6 +2141,36 @@ int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, return ret; } +int cpu_physical_log_start(target_phys_addr_t start_addr, + ram_addr_t size) +{ + CPUPhysMemoryClient *client; + QLIST_FOREACH(client, &memory_client_list, list) { + if (client->log_start) { + int r = client->log_start(client, start_addr, size); + if (r < 0) { + return r; + } + } + } + return 0; +} + +int cpu_physical_log_stop(target_phys_addr_t start_addr, + ram_addr_t size) +{ + CPUPhysMemoryClient *client; + QLIST_FOREACH(client, &memory_client_list, list) { + if (client->log_stop) { + int r = client->log_stop(client, start_addr, size); + if (r < 0) { + return r; + } + } + } + return 0; +} + static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) { ram_addr_t ram_addr; @@ -2567,10 +2660,11 @@ static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys, start_addr and region_offset are rounded down to a page boundary before calculating this offset. This should not be a problem unless the low bits of start_addr and region_offset differ. */ -void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, +void cpu_register_physical_memory_log(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset, - ram_addr_t region_offset) + ram_addr_t region_offset, + bool log_dirty) { target_phys_addr_t addr, end_addr; PhysPageDesc *p; @@ -2578,7 +2672,9 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t orig_size = size; subpage_t *subpage; - cpu_notify_set_memory(start_addr, size, phys_offset); + assert(size); + + cpu_notify_set_memory(start_addr, size, phys_offset, log_dirty); if (phys_offset == IO_MEM_UNASSIGNED) { region_offset = start_addr; @@ -2586,7 +2682,9 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, region_offset &= TARGET_PAGE_MASK; size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; end_addr = start_addr + (target_phys_addr_t)size; - for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { + + addr = start_addr; + do { p = phys_page_find(addr >> TARGET_PAGE_BITS); if (p && p->phys_offset != IO_MEM_UNASSIGNED) { ram_addr_t orig_memory = p->phys_offset; @@ -2638,7 +2736,8 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, } } region_offset += TARGET_PAGE_SIZE; - } + addr += TARGET_PAGE_SIZE; + } while (addr != end_addr); /* since each CPU stores ram addresses in its TLB cache, we must reset the modified entries */ @@ -2776,13 +2875,13 @@ static void *file_ram_alloc(RAMBlock *block, static ram_addr_t find_ram_offset(ram_addr_t size) { RAMBlock *block, *next_block; - ram_addr_t offset = 0, mingap = ULONG_MAX; + ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX; if (QLIST_EMPTY(&ram_list.blocks)) return 0; QLIST_FOREACH(block, &ram_list.blocks, next) { - ram_addr_t end, next = ULONG_MAX; + ram_addr_t end, next = RAM_ADDR_MAX; end = block->offset + block->length; @@ -2792,10 +2891,17 @@ static ram_addr_t find_ram_offset(ram_addr_t size) } } if (next - end >= size && next - end < mingap) { - offset = end; + offset = end; mingap = next - end; } } + + if (offset == RAM_ADDR_MAX) { + fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n", + (uint64_t)size); + abort(); + } + return offset; } @@ -2816,13 +2922,13 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, RAMBlock *new_block, *block; size = TARGET_PAGE_ALIGN(size); - new_block = qemu_mallocz(sizeof(*new_block)); + new_block = g_malloc0(sizeof(*new_block)); if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) { char *id = dev->parent_bus->info->get_dev_path(dev); if (id) { snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id); - qemu_free(id); + g_free(id); } } pstrcat(new_block->idstr, sizeof(new_block->idstr), name); @@ -2835,8 +2941,10 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, } } + new_block->offset = find_ram_offset(size); if (host) { new_block->host = host; + new_block->flags |= RAM_PREALLOC_MASK; } else { if (mem_path) { #if defined (__linux__) && !defined(TARGET_S390X) @@ -2851,23 +2959,50 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, #endif } else { #if defined(TARGET_S390X) && defined(CONFIG_KVM) - /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */ - new_block->host = mmap((void*)0x1000000, size, + /* S390 KVM requires the topmost vma of the RAM to be smaller than + an system defined value, which is at least 256GB. Larger systems + have larger values. We put the guest between the end of data + segment (system break) and this value. We use 32GB as a base to + have enough room for the system break to grow. */ + new_block->host = mmap((void*)0x800000000, size, PROT_EXEC|PROT_READ|PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, -1, 0); + MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + if (new_block->host == MAP_FAILED) { + fprintf(stderr, "Allocating RAM failed\n"); + abort(); + } #else - new_block->host = qemu_vmalloc(size); + if (xen_enabled()) { + xen_ram_alloc(new_block->offset, size); + } else { + new_block->host = qemu_vmalloc(size); +#ifdef CONFIG_HAX + /* + * In Hax, the qemu allocate the virtual address, and HAX kernel + * populate the memory with physical memory. Currently we have no + * paging, so user should make sure enough free memory in advance + */ + if (hax_enabled()) + { + int ret; + ret = hax_populate_ram((uint64_t)new_block->host, size); + if (ret < 0) + { + fprintf(stderr, "Hax failed to populate ram\n"); + exit(-1); + } + } +#endif + } #endif qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE); } } - - new_block->offset = find_ram_offset(size); new_block->length = size; QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); - ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty, + ram_list.phys_dirty = g_realloc(ram_list.phys_dirty, last_ram_offset() >> TARGET_PAGE_BITS); memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS), 0xff, size >> TARGET_PAGE_BITS); @@ -2883,6 +3018,19 @@ ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size) return qemu_ram_alloc_from_ptr(dev, name, size, NULL); } +void qemu_ram_free_from_ptr(ram_addr_t addr) +{ + RAMBlock *block; + + QLIST_FOREACH(block, &ram_list.blocks, next) { + if (addr == block->offset) { + QLIST_REMOVE(block, next); + g_free(block); + return; + } + } +} + void qemu_ram_free(ram_addr_t addr) { RAMBlock *block; @@ -2890,7 +3038,9 @@ void qemu_ram_free(ram_addr_t addr) QLIST_FOREACH(block, &ram_list.blocks, next) { if (addr == block->offset) { QLIST_REMOVE(block, next); - if (mem_path) { + if (block->flags & RAM_PREALLOC_MASK) { + ; + } else if (mem_path) { #if defined (__linux__) && !defined(TARGET_S390X) if (block->fd) { munmap(block->host, block->length); @@ -2898,21 +3048,88 @@ void qemu_ram_free(ram_addr_t addr) } else { qemu_vfree(block->host); } +#else + abort(); #endif } else { #if defined(TARGET_S390X) && defined(CONFIG_KVM) munmap(block->host, block->length); #else - qemu_vfree(block->host); + if (xen_enabled()) { + xen_invalidate_map_cache_entry(block->host); + } else { + qemu_vfree(block->host); + } #endif } - qemu_free(block); + g_free(block); return; } } } +#ifndef _WIN32 +void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) +{ + RAMBlock *block; + ram_addr_t offset; + int flags; + void *area, *vaddr; + + QLIST_FOREACH(block, &ram_list.blocks, next) { + offset = addr - block->offset; + if (offset < block->length) { + vaddr = block->host + offset; + if (block->flags & RAM_PREALLOC_MASK) { + ; + } else { + flags = MAP_FIXED; + munmap(vaddr, length); + if (mem_path) { +#if defined(__linux__) && !defined(TARGET_S390X) + if (block->fd) { +#ifdef MAP_POPULATE + flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED : + MAP_PRIVATE; +#else + flags |= MAP_PRIVATE; +#endif + area = mmap(vaddr, length, PROT_READ | PROT_WRITE, + flags, block->fd, offset); + } else { + flags |= MAP_PRIVATE | MAP_ANONYMOUS; + area = mmap(vaddr, length, PROT_READ | PROT_WRITE, + flags, -1, 0); + } +#else + abort(); +#endif + } else { +#if defined(TARGET_S390X) && defined(CONFIG_KVM) + flags |= MAP_SHARED | MAP_ANONYMOUS; + area = mmap(vaddr, length, PROT_EXEC|PROT_READ|PROT_WRITE, + flags, -1, 0); +#else + flags |= MAP_PRIVATE | MAP_ANONYMOUS; + area = mmap(vaddr, length, PROT_READ | PROT_WRITE, + flags, -1, 0); +#endif + } + if (area != vaddr) { + fprintf(stderr, "Could not remap addr: " + RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n", + length, addr); + exit(1); + } + qemu_madvise(vaddr, length, QEMU_MADV_MERGEABLE); + } + return; + } + } +} +#endif /* !_WIN32 */ + /* Return a host pointer to ram allocated with qemu_ram_alloc. With the exception of the softmmu code in this file, this should only be used for local memory (e.g. video ram) that the device owns, @@ -2927,8 +3144,23 @@ void *qemu_get_ram_ptr(ram_addr_t addr) QLIST_FOREACH(block, &ram_list.blocks, next) { if (addr - block->offset < block->length) { - QLIST_REMOVE(block, next); - QLIST_INSERT_HEAD(&ram_list.blocks, block, next); + /* Move this entry to to start of the list. */ + if (block != QLIST_FIRST(&ram_list.blocks)) { + QLIST_REMOVE(block, next); + QLIST_INSERT_HEAD(&ram_list.blocks, block, next); + } + if (xen_enabled()) { + /* We need to check if the requested address is in the RAM + * because we don't want to map the entire memory in QEMU. + * In that case just map until the end of the page. + */ + if (block->offset == 0) { + return xen_map_cache(addr, 0, 0); + } else if (block->host == NULL) { + block->host = + xen_map_cache(block->offset, block->length, 1); + } + } return block->host + (addr - block->offset); } } @@ -2948,6 +3180,18 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) QLIST_FOREACH(block, &ram_list.blocks, next) { if (addr - block->offset < block->length) { + if (xen_enabled()) { + /* We need to check if the requested address is in the RAM + * because we don't want to map the entire memory in QEMU. + * In that case just map until the end of the page. + */ + if (block->offset == 0) { + return xen_map_cache(addr, 0, 0); + } else if (block->host == NULL) { + block->host = + xen_map_cache(block->offset, block->length, 1); + } + } return block->host + (addr - block->offset); } } @@ -2958,17 +3202,57 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) return NULL; } +/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr + * but takes a size argument */ +void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size) +{ + if (*size == 0) { + return NULL; + } + if (xen_enabled()) { + return xen_map_cache(addr, *size, 1); + } else { + RAMBlock *block; + + QLIST_FOREACH(block, &ram_list.blocks, next) { + if (addr - block->offset < block->length) { + if (addr - block->offset + *size > block->length) + *size = block->length - addr + block->offset; + return block->host + (addr - block->offset); + } + } + + fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr); + abort(); + } +} + +void qemu_put_ram_ptr(void *addr) +{ + trace_qemu_put_ram_ptr(addr); +} + int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr) { RAMBlock *block; uint8_t *host = ptr; + if (xen_enabled()) { + *ram_addr = xen_ram_addr_from_mapcache(ptr); + return 0; + } + QLIST_FOREACH(block, &ram_list.blocks, next) { + /* This case append when the block is not mapped. */ + if (block->host == NULL) { + continue; + } if (host - block->host < block->length) { *ram_addr = block->offset + (host - block->host); return 0; } } + return -1; } @@ -2990,8 +3274,8 @@ static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr) #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif -#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 0, 0, 0, 1); +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 1); #endif return 0; } @@ -3001,8 +3285,8 @@ static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr) #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif -#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 0, 0, 0, 2); +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 2); #endif return 0; } @@ -3012,8 +3296,8 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr) #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif -#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 0, 0, 0, 4); +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 4); #endif return 0; } @@ -3023,8 +3307,8 @@ static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_ #ifdef DEBUG_UNASSIGNED printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif -#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 1, 0, 0, 1); +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 1); #endif } @@ -3033,8 +3317,8 @@ static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_ #ifdef DEBUG_UNASSIGNED printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif -#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 1, 0, 0, 2); +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 2); #endif } @@ -3043,8 +3327,8 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_ #ifdef DEBUG_UNASSIGNED printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif -#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 1, 0, 0, 4); +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 4); #endif } @@ -3161,7 +3445,7 @@ static void check_watchpoint(int offset, int len_mask, int flags) cpu_abort(env, "check_watchpoint: could not find TB for " "pc=%p", (void *)env->mem_io_pc); } - cpu_restore_state(tb, env, env->mem_io_pc, NULL); + cpu_restore_state(tb, env, env->mem_io_pc); tb_phys_invalidate(tb, -1); if (wp->flags & BP_STOP_BEFORE_ACCESS) { env->exception_index = EXCP_DEBUG; @@ -3305,6 +3589,63 @@ static CPUWriteMemoryFunc * const subpage_write[] = { &subpage_writel, }; +static uint32_t subpage_ram_readb(void *opaque, target_phys_addr_t addr) +{ + ram_addr_t raddr = addr; + void *ptr = qemu_get_ram_ptr(raddr); + return ldub_p(ptr); +} + +static void subpage_ram_writeb(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + ram_addr_t raddr = addr; + void *ptr = qemu_get_ram_ptr(raddr); + stb_p(ptr, value); +} + +static uint32_t subpage_ram_readw(void *opaque, target_phys_addr_t addr) +{ + ram_addr_t raddr = addr; + void *ptr = qemu_get_ram_ptr(raddr); + return lduw_p(ptr); +} + +static void subpage_ram_writew(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + ram_addr_t raddr = addr; + void *ptr = qemu_get_ram_ptr(raddr); + stw_p(ptr, value); +} + +static uint32_t subpage_ram_readl(void *opaque, target_phys_addr_t addr) +{ + ram_addr_t raddr = addr; + void *ptr = qemu_get_ram_ptr(raddr); + return ldl_p(ptr); +} + +static void subpage_ram_writel(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + ram_addr_t raddr = addr; + void *ptr = qemu_get_ram_ptr(raddr); + stl_p(ptr, value); +} + +static CPUReadMemoryFunc * const subpage_ram_read[] = { + &subpage_ram_readb, + &subpage_ram_readw, + &subpage_ram_readl, +}; + +static CPUWriteMemoryFunc * const subpage_ram_write[] = { + &subpage_ram_writeb, + &subpage_ram_writew, + &subpage_ram_writel, +}; + static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory, ram_addr_t region_offset) { @@ -3318,8 +3659,9 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__, mmio, start, end, idx, eidx, memory); #endif - if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) - memory = IO_MEM_UNASSIGNED; + if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) { + memory = IO_MEM_SUBPAGE_RAM; + } memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); for (; idx <= eidx; idx++) { mmio->sub_io_index[idx] = memory; @@ -3336,7 +3678,7 @@ static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys, subpage_t *mmio; int subpage_memory; - mmio = qemu_mallocz(sizeof(subpage_t)); + mmio = g_malloc0(sizeof(subpage_t)); mmio->base = base; subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio, @@ -3442,7 +3784,7 @@ static CPUWriteMemoryFunc * const swapendian_writefn[3]={ static void swapendian_init(int io_index) { - SwapEndianContainer *c = qemu_malloc(sizeof(SwapEndianContainer)); + SwapEndianContainer *c = g_malloc(sizeof(SwapEndianContainer)); int i; /* Swap mmio for big endian targets */ @@ -3460,7 +3802,7 @@ static void swapendian_init(int io_index) static void swapendian_del(int io_index) { if (io_mem_read[io_index][0] == swapendian_readfn[0]) { - qemu_free(io_mem_opaque[io_index]); + g_free(io_mem_opaque[io_index]); } } @@ -3552,6 +3894,9 @@ static void io_mem_init(void) cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read, notdirty_mem_write, NULL, DEVICE_NATIVE_ENDIAN); + cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read, + subpage_ram_write, NULL, + DEVICE_NATIVE_ENDIAN); for (i=0; i<5; i++) io_mem_used[i] = 1; @@ -3560,6 +3905,27 @@ static void io_mem_init(void) DEVICE_NATIVE_ENDIAN); } +static void memory_map_init(void) +{ + system_memory = g_malloc(sizeof(*system_memory)); + memory_region_init(system_memory, "system", INT64_MAX); + set_system_memory_map(system_memory); + + system_io = g_malloc(sizeof(*system_io)); + memory_region_init(system_io, "io", 65536); + set_system_io_map(system_io); +} + +MemoryRegion *get_system_memory(void) +{ + return system_memory; +} + +MemoryRegion *get_system_io(void) +{ + return system_io; +} + #endif /* !defined(CONFIG_USER_ONLY) */ /* physical memory access (slow version, mainly for debug) */ @@ -3611,7 +3977,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, uint8_t *ptr; uint32_t val; target_phys_addr_t page; - unsigned long pd; + ram_addr_t pd; PhysPageDesc *p; while (len > 0) { @@ -3651,7 +4017,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, l = 1; } } else { - unsigned long addr1; + ram_addr_t addr1; addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); /* RAM case */ ptr = qemu_get_ram_ptr(addr1); @@ -3663,6 +4029,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, cpu_physical_memory_set_dirty_flags( addr1, (0xff & ~CODE_DIRTY_FLAG)); } + qemu_put_ram_ptr(ptr); } } else { if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && @@ -3690,9 +4057,9 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, } } else { /* RAM case */ - ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + - (addr & ~TARGET_PAGE_MASK); - memcpy(buf, ptr, l); + ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK); + memcpy(buf, ptr + (addr & ~TARGET_PAGE_MASK), l); + qemu_put_ram_ptr(ptr); } } len -= l; @@ -3733,6 +4100,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, /* ROM/RAM case */ ptr = qemu_get_ram_ptr(addr1); memcpy(ptr, buf, l); + qemu_put_ram_ptr(ptr); } len -= l; buf += l; @@ -3759,7 +4127,7 @@ static QLIST_HEAD(map_client_list, MapClient) map_client_list void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque)) { - MapClient *client = qemu_malloc(sizeof(*client)); + MapClient *client = g_malloc(sizeof(*client)); client->opaque = opaque; client->callback = callback; @@ -3772,7 +4140,7 @@ void cpu_unregister_map_client(void *_client) MapClient *client = (MapClient *)_client; QLIST_REMOVE(client, link); - qemu_free(client); + g_free(client); } static void cpu_notify_map_clients(void) @@ -3798,14 +4166,14 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, int is_write) { target_phys_addr_t len = *plen; - target_phys_addr_t done = 0; + target_phys_addr_t todo = 0; int l; - uint8_t *ret = NULL; - uint8_t *ptr; target_phys_addr_t page; unsigned long pd; PhysPageDesc *p; - unsigned long addr1; + ram_addr_t raddr = RAM_ADDR_MAX; + ram_addr_t rlen; + void *ret; while (len > 0) { page = addr & TARGET_PAGE_MASK; @@ -3820,31 +4188,30 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, } if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { - if (done || bounce.buffer) { + if (todo || bounce.buffer) { break; } bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, TARGET_PAGE_SIZE); bounce.addr = addr; bounce.len = l; if (!is_write) { - cpu_physical_memory_rw(addr, bounce.buffer, l, 0); + cpu_physical_memory_read(addr, bounce.buffer, l); } - ptr = bounce.buffer; - } else { - addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); - ptr = qemu_get_ram_ptr(addr1); + + *plen = l; + return bounce.buffer; } - if (!done) { - ret = ptr; - } else if (ret + done != ptr) { - break; + if (!todo) { + raddr = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); } len -= l; addr += l; - done += l; + todo += l; } - *plen = done; + rlen = todo; + ret = qemu_ram_ptr_length(raddr, &rlen); + *plen = rlen; return ret; } @@ -3874,6 +4241,9 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, access_len -= l; } } + if (xen_enabled()) { + xen_invalidate_map_cache_entry(buffer); + } return; } if (is_write) { @@ -3885,7 +4255,8 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, } /* warning: addr must be aligned */ -uint32_t ldl_phys(target_phys_addr_t addr) +static inline uint32_t ldl_phys_internal(target_phys_addr_t addr, + enum device_endian endian) { int io_index; uint8_t *ptr; @@ -3907,17 +4278,52 @@ uint32_t ldl_phys(target_phys_addr_t addr) if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap32(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap32(val); + } +#endif } else { /* RAM case */ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); - val = ldl_p(ptr); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + val = ldl_le_p(ptr); + break; + case DEVICE_BIG_ENDIAN: + val = ldl_be_p(ptr); + break; + default: + val = ldl_p(ptr); + break; + } } return val; } +uint32_t ldl_phys(target_phys_addr_t addr) +{ + return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN); +} + +uint32_t ldl_le_phys(target_phys_addr_t addr) +{ + return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN); +} + +uint32_t ldl_be_phys(target_phys_addr_t addr) +{ + return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN); +} + /* warning: addr must be aligned */ -uint64_t ldq_phys(target_phys_addr_t addr) +static inline uint64_t ldq_phys_internal(target_phys_addr_t addr, + enum device_endian endian) { int io_index; uint8_t *ptr; @@ -3938,6 +4344,9 @@ uint64_t ldq_phys(target_phys_addr_t addr) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; + + /* XXX This is broken when device endian != cpu endian. + Fix and add "endian" variable check */ #ifdef TARGET_WORDS_BIGENDIAN val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32; val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4); @@ -3949,11 +4358,36 @@ uint64_t ldq_phys(target_phys_addr_t addr) /* RAM case */ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); - val = ldq_p(ptr); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + val = ldq_le_p(ptr); + break; + case DEVICE_BIG_ENDIAN: + val = ldq_be_p(ptr); + break; + default: + val = ldq_p(ptr); + break; + } } return val; } +uint64_t ldq_phys(target_phys_addr_t addr) +{ + return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN); +} + +uint64_t ldq_le_phys(target_phys_addr_t addr) +{ + return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN); +} + +uint64_t ldq_be_phys(target_phys_addr_t addr) +{ + return ldq_phys_internal(addr, DEVICE_BIG_ENDIAN); +} + /* XXX: optimize */ uint32_t ldub_phys(target_phys_addr_t addr) { @@ -3963,7 +4397,8 @@ uint32_t ldub_phys(target_phys_addr_t addr) } /* warning: addr must be aligned */ -uint32_t lduw_phys(target_phys_addr_t addr) +static inline uint32_t lduw_phys_internal(target_phys_addr_t addr, + enum device_endian endian) { int io_index; uint8_t *ptr; @@ -3985,15 +4420,49 @@ uint32_t lduw_phys(target_phys_addr_t addr) if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr); +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap16(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap16(val); + } +#endif } else { /* RAM case */ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); - val = lduw_p(ptr); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + val = lduw_le_p(ptr); + break; + case DEVICE_BIG_ENDIAN: + val = lduw_be_p(ptr); + break; + default: + val = lduw_p(ptr); + break; + } } return val; } +uint32_t lduw_phys(target_phys_addr_t addr) +{ + return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN); +} + +uint32_t lduw_le_phys(target_phys_addr_t addr) +{ + return lduw_phys_internal(addr, DEVICE_LITTLE_ENDIAN); +} + +uint32_t lduw_be_phys(target_phys_addr_t addr) +{ + return lduw_phys_internal(addr, DEVICE_BIG_ENDIAN); +} + /* warning: addr must be aligned. The ram page is not masked as dirty and the code inside is not invalidated. It is useful if the dirty bits are used to track modified PTEs */ @@ -4066,7 +4535,8 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val) } /* warning: addr must be aligned */ -void stl_phys(target_phys_addr_t addr, uint32_t val) +static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val, + enum device_endian endian) { int io_index; uint8_t *ptr; @@ -4084,13 +4554,32 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap32(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap32(val); + } +#endif io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1; addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); /* RAM case */ ptr = qemu_get_ram_ptr(addr1); - stl_p(ptr, val); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + stl_le_p(ptr, val); + break; + case DEVICE_BIG_ENDIAN: + stl_be_p(ptr, val); + break; + default: + stl_p(ptr, val); + break; + } if (!cpu_physical_memory_is_dirty(addr1)) { /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); @@ -4101,6 +4590,21 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) } } +void stl_phys(target_phys_addr_t addr, uint32_t val) +{ + stl_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN); +} + +void stl_le_phys(target_phys_addr_t addr, uint32_t val) +{ + stl_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN); +} + +void stl_be_phys(target_phys_addr_t addr, uint32_t val) +{ + stl_phys_internal(addr, val, DEVICE_BIG_ENDIAN); +} + /* XXX: optimize */ void stb_phys(target_phys_addr_t addr, uint32_t val) { @@ -4109,7 +4613,8 @@ void stb_phys(target_phys_addr_t addr, uint32_t val) } /* warning: addr must be aligned */ -void stw_phys(target_phys_addr_t addr, uint32_t val) +static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val, + enum device_endian endian) { int io_index; uint8_t *ptr; @@ -4127,13 +4632,32 @@ void stw_phys(target_phys_addr_t addr, uint32_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap16(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap16(val); + } +#endif io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val); } else { unsigned long addr1; addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); /* RAM case */ ptr = qemu_get_ram_ptr(addr1); - stw_p(ptr, val); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + stw_le_p(ptr, val); + break; + case DEVICE_BIG_ENDIAN: + stw_be_p(ptr, val); + break; + default: + stw_p(ptr, val); + break; + } if (!cpu_physical_memory_is_dirty(addr1)) { /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + 2, 0); @@ -4144,11 +4668,38 @@ void stw_phys(target_phys_addr_t addr, uint32_t val) } } +void stw_phys(target_phys_addr_t addr, uint32_t val) +{ + stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN); +} + +void stw_le_phys(target_phys_addr_t addr, uint32_t val) +{ + stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN); +} + +void stw_be_phys(target_phys_addr_t addr, uint32_t val) +{ + stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN); +} + /* XXX: optimize */ void stq_phys(target_phys_addr_t addr, uint64_t val) { val = tswap64(val); - cpu_physical_memory_write(addr, (const uint8_t *)&val, 8); + cpu_physical_memory_write(addr, &val, 8); +} + +void stq_le_phys(target_phys_addr_t addr, uint64_t val) +{ + val = cpu_to_le64(val); + cpu_physical_memory_write(addr, &val, 8); +} + +void stq_be_phys(target_phys_addr_t addr, uint64_t val) +{ + val = cpu_to_be64(val); + cpu_physical_memory_write(addr, &val, 8); } /* virtual memory access for debug (includes writing to ROM) */ @@ -4196,7 +4747,7 @@ void cpu_io_recompile(CPUState *env, void *retaddr) retaddr); } n = env->icount_decr.u16.low + tb->icount; - cpu_restore_state(tb, env, (unsigned long)retaddr, NULL); + cpu_restore_state(tb, env, (unsigned long)retaddr); /* Calculate how many instructions had been executed before the fault occurred. */ n = n - env->icount_decr.u16.low; @@ -4295,6 +4846,7 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf) } #define MMUSUFFIX _cmmu +#undef GETPC #define GETPC() NULL #define env cpu_single_env #define SOFTMMU_CODE_ACCESS diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h index 7838228..e82ce233 100644 --- a/fpu/softfloat-macros.h +++ b/fpu/softfloat-macros.h @@ -1,3 +1,8 @@ +/* + * QEMU float support macros + * + * Derived from SoftFloat. + */ /*============================================================================ @@ -31,6 +36,17 @@ these four paragraphs for those parts of this code that are retained. =============================================================================*/ /*---------------------------------------------------------------------------- +| This macro tests for minimum version of the GNU C compiler. +*----------------------------------------------------------------------------*/ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define SOFTFLOAT_GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +# define SOFTFLOAT_GNUC_PREREQ(maj, min) 0 +#endif + + +/*---------------------------------------------------------------------------- | Shifts `a' right by the number of bits given in `count'. If any nonzero | bits are shifted off, they are ``jammed'' into the least significant bit of | the result by setting the least significant bit to 1. The value of `count' @@ -39,9 +55,9 @@ these four paragraphs for those parts of this code that are retained. | The result is stored in the location pointed to by `zPtr'. *----------------------------------------------------------------------------*/ -INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) +INLINE void shift32RightJamming( uint32_t a, int16 count, uint32_t *zPtr ) { - bits32 z; + uint32_t z; if ( count == 0 ) { z = a; @@ -65,9 +81,9 @@ INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) | The result is stored in the location pointed to by `zPtr'. *----------------------------------------------------------------------------*/ -INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) +INLINE void shift64RightJamming( uint64_t a, int16 count, uint64_t *zPtr ) { - bits64 z; + uint64_t z; if ( count == 0 ) { z = a; @@ -101,9 +117,9 @@ INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) INLINE void shift64ExtraRightJamming( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) + uint64_t a0, uint64_t a1, int16 count, uint64_t *z0Ptr, uint64_t *z1Ptr ) { - bits64 z0, z1; + uint64_t z0, z1; int8 negCount = ( - count ) & 63; if ( count == 0 ) { @@ -138,9 +154,9 @@ INLINE void INLINE void shift128Right( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) + uint64_t a0, uint64_t a1, int16 count, uint64_t *z0Ptr, uint64_t *z1Ptr ) { - bits64 z0, z1; + uint64_t z0, z1; int8 negCount = ( - count ) & 63; if ( count == 0 ) { @@ -173,9 +189,9 @@ INLINE void INLINE void shift128RightJamming( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) + uint64_t a0, uint64_t a1, int16 count, uint64_t *z0Ptr, uint64_t *z1Ptr ) { - bits64 z0, z1; + uint64_t z0, z1; int8 negCount = ( - count ) & 63; if ( count == 0 ) { @@ -224,16 +240,16 @@ INLINE void INLINE void shift128ExtraRightJamming( - bits64 a0, - bits64 a1, - bits64 a2, + uint64_t a0, + uint64_t a1, + uint64_t a2, int16 count, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr + uint64_t *z0Ptr, + uint64_t *z1Ptr, + uint64_t *z2Ptr ) { - bits64 z0, z1, z2; + uint64_t z0, z1, z2; int8 negCount = ( - count ) & 63; if ( count == 0 ) { @@ -282,7 +298,7 @@ INLINE void INLINE void shortShift128Left( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) + uint64_t a0, uint64_t a1, int16 count, uint64_t *z0Ptr, uint64_t *z1Ptr ) { *z1Ptr = a1<>32; bLow = b; bHigh = b>>32; - z1 = ( (bits64) aLow ) * bLow; - zMiddleA = ( (bits64) aLow ) * bHigh; - zMiddleB = ( (bits64) aHigh ) * bLow; - z0 = ( (bits64) aHigh ) * bHigh; + z1 = ( (uint64_t) aLow ) * bLow; + zMiddleA = ( (uint64_t) aLow ) * bHigh; + zMiddleB = ( (uint64_t) aHigh ) * bLow; + z0 = ( (uint64_t) aHigh ) * bHigh; zMiddleA += zMiddleB; - z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); + z0 += ( ( (uint64_t) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); zMiddleA <<= 32; z1 += zMiddleA; z0 += ( z1 < zMiddleA ); @@ -478,15 +494,15 @@ INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) INLINE void mul128By64To192( - bits64 a0, - bits64 a1, - bits64 b, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr + uint64_t a0, + uint64_t a1, + uint64_t b, + uint64_t *z0Ptr, + uint64_t *z1Ptr, + uint64_t *z2Ptr ) { - bits64 z0, z1, z2, more1; + uint64_t z0, z1, z2, more1; mul64To128( a1, b, &z1, &z2 ); mul64To128( a0, b, &z0, &more1 ); @@ -506,18 +522,18 @@ INLINE void INLINE void mul128To256( - bits64 a0, - bits64 a1, - bits64 b0, - bits64 b1, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr, - bits64 *z3Ptr + uint64_t a0, + uint64_t a1, + uint64_t b0, + uint64_t b1, + uint64_t *z0Ptr, + uint64_t *z1Ptr, + uint64_t *z2Ptr, + uint64_t *z3Ptr ) { - bits64 z0, z1, z2, z3; - bits64 more1, more2; + uint64_t z0, z1, z2, z3; + uint64_t more1, more2; mul64To128( a1, b1, &z2, &z3 ); mul64To128( a1, b0, &z1, &more2 ); @@ -543,18 +559,18 @@ INLINE void | unsigned integer is returned. *----------------------------------------------------------------------------*/ -static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) +static uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b ) { - bits64 b0, b1; - bits64 rem0, rem1, term0, term1; - bits64 z; + uint64_t b0, b1; + uint64_t rem0, rem1, term0, term1; + uint64_t z; if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); b0 = b>>32; z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; mul64To128( b, z, &term0, &term1 ); sub128( a0, a1, term0, term1, &rem0, &rem1 ); - while ( ( (sbits64) rem0 ) < 0 ) { + while ( ( (int64_t) rem0 ) < 0 ) { z -= LIT64( 0x100000000 ); b1 = b<<32; add128( rem0, rem1, b0, b1, &rem0, &rem1 ); @@ -575,18 +591,18 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) | value. *----------------------------------------------------------------------------*/ -static bits32 estimateSqrt32( int16 aExp, bits32 a ) +static uint32_t estimateSqrt32( int16 aExp, uint32_t a ) { - static const bits16 sqrtOddAdjustments[] = { + static const uint16_t sqrtOddAdjustments[] = { 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 }; - static const bits16 sqrtEvenAdjustments[] = { + static const uint16_t sqrtEvenAdjustments[] = { 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 }; int8 index; - bits32 z; + uint32_t z; index = ( a>>27 ) & 15; if ( aExp & 1 ) { @@ -598,9 +614,9 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a ) z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ (int)index ]; z = a / z + z; z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); - if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); + if ( z <= a ) return (uint32_t) ( ( (int32_t) a )>>1 ); } - return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); + return ( (uint32_t) ( ( ( (uint64_t) a )<<31 ) / z ) ) + ( z>>1 ); } @@ -609,8 +625,15 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a ) | `a'. If `a' is zero, 32 is returned. *----------------------------------------------------------------------------*/ -static int8 countLeadingZeros32( bits32 a ) +static int8 countLeadingZeros32( uint32_t a ) { +#if SOFTFLOAT_GNUC_PREREQ(3, 4) + if (a) { + return __builtin_clz(a); + } else { + return 32; + } +#else static const int8 countLeadingZerosHigh[] = { 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, @@ -642,7 +665,7 @@ static int8 countLeadingZeros32( bits32 a ) } shiftCount += countLeadingZerosHigh[ a>>24 ]; return shiftCount; - +#endif } /*---------------------------------------------------------------------------- @@ -650,12 +673,19 @@ static int8 countLeadingZeros32( bits32 a ) | `a'. If `a' is zero, 64 is returned. *----------------------------------------------------------------------------*/ -static int8 countLeadingZeros64( bits64 a ) +static int8 countLeadingZeros64( uint64_t a ) { +#if SOFTFLOAT_GNUC_PREREQ(3, 4) + if (a) { + return __builtin_clzll(a); + } else { + return 64; + } +#else int8 shiftCount; shiftCount = 0; - if ( a < ( (bits64) 1 )<<32 ) { + if ( a < ( (uint64_t) 1 )<<32 ) { shiftCount += 32; } else { @@ -663,7 +693,7 @@ static int8 countLeadingZeros64( bits64 a ) } shiftCount += countLeadingZeros32( a ); return shiftCount; - +#endif } /*---------------------------------------------------------------------------- @@ -672,7 +702,7 @@ static int8 countLeadingZeros64( bits64 a ) | Otherwise, returns 0. *----------------------------------------------------------------------------*/ -INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +INLINE flag eq128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) { return ( a0 == b0 ) && ( a1 == b1 ); @@ -685,7 +715,7 @@ INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) | Otherwise, returns 0. *----------------------------------------------------------------------------*/ -INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +INLINE flag le128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) { return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); @@ -698,7 +728,7 @@ INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) | returns 0. *----------------------------------------------------------------------------*/ -INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +INLINE flag lt128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) { return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); @@ -711,7 +741,7 @@ INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) | Otherwise, returns 0. *----------------------------------------------------------------------------*/ -INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +INLINE flag ne128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) { return ( a0 != b0 ) || ( a1 != b1 ); diff --git a/fpu/softfloat-native.c b/fpu/softfloat-native.c deleted file mode 100644 index 008bb53..0000000 --- a/fpu/softfloat-native.c +++ /dev/null @@ -1,514 +0,0 @@ -/* Native implementation of soft float functions. Only a single status - context is supported */ -#include "softfloat.h" -#include -#if defined(CONFIG_SOLARIS) -#include -#endif - -void set_float_rounding_mode(int val STATUS_PARAM) -{ - STATUS(float_rounding_mode) = val; -#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) || \ - (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10) - fpsetround(val); -#else - fesetround(val); -#endif -} - -#ifdef FLOATX80 -void set_floatx80_rounding_precision(int val STATUS_PARAM) -{ - STATUS(floatx80_rounding_precision) = val; -} -#endif - -#if defined(CONFIG_BSD) || \ - (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10) -#define lrint(d) ((int32_t)rint(d)) -#define llrint(d) ((int64_t)rint(d)) -#define lrintf(f) ((int32_t)rint(f)) -#define llrintf(f) ((int64_t)rint(f)) -#define sqrtf(f) ((float)sqrt(f)) -#define remainderf(fa, fb) ((float)remainder(fa, fb)) -#define rintf(f) ((float)rint(f)) -#if !defined(__sparc__) && \ - (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10) -extern long double rintl(long double); -extern long double scalbnl(long double, int); - -long long -llrintl(long double x) { - return ((long long) rintl(x)); -} - -long -lrintl(long double x) { - return ((long) rintl(x)); -} - -long double -ldexpl(long double x, int n) { - return (scalbnl(x, n)); -} -#endif -#endif - -#if defined(_ARCH_PPC) - -/* correct (but slow) PowerPC rint() (glibc version is incorrect) */ -static double qemu_rint(double x) -{ - double y = 4503599627370496.0; - if (fabs(x) >= y) - return x; - if (x < 0) - y = -y; - y = (x + y) - y; - if (y == 0.0) - y = copysign(y, x); - return y; -} - -#define rint qemu_rint -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float32 int32_to_float32(int v STATUS_PARAM) -{ - return (float32)v; -} - -float32 uint32_to_float32(unsigned int v STATUS_PARAM) -{ - return (float32)v; -} - -float64 int32_to_float64(int v STATUS_PARAM) -{ - return (float64)v; -} - -float64 uint32_to_float64(unsigned int v STATUS_PARAM) -{ - return (float64)v; -} - -#ifdef FLOATX80 -floatx80 int32_to_floatx80(int v STATUS_PARAM) -{ - return (floatx80)v; -} -#endif -float32 int64_to_float32( int64_t v STATUS_PARAM) -{ - return (float32)v; -} -float32 uint64_to_float32( uint64_t v STATUS_PARAM) -{ - return (float32)v; -} -float64 int64_to_float64( int64_t v STATUS_PARAM) -{ - return (float64)v; -} -float64 uint64_to_float64( uint64_t v STATUS_PARAM) -{ - return (float64)v; -} -#ifdef FLOATX80 -floatx80 int64_to_floatx80( int64_t v STATUS_PARAM) -{ - return (floatx80)v; -} -#endif - -/* XXX: this code implements the x86 behaviour, not the IEEE one. */ -#if HOST_LONG_BITS == 32 -static inline int long_to_int32(long a) -{ - return a; -} -#else -static inline int long_to_int32(long a) -{ - if (a != (int32_t)a) - a = 0x80000000; - return a; -} -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision conversion routines. -*----------------------------------------------------------------------------*/ -int float32_to_int32( float32 a STATUS_PARAM) -{ - return long_to_int32(lrintf(a)); -} -int float32_to_int32_round_to_zero( float32 a STATUS_PARAM) -{ - return (int)a; -} -int64_t float32_to_int64( float32 a STATUS_PARAM) -{ - return llrintf(a); -} - -int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM) -{ - return (int64_t)a; -} - -float64 float32_to_float64( float32 a STATUS_PARAM) -{ - return a; -} -#ifdef FLOATX80 -floatx80 float32_to_floatx80( float32 a STATUS_PARAM) -{ - return a; -} -#endif - -unsigned int float32_to_uint32( float32 a STATUS_PARAM) -{ - int64_t v; - unsigned int res; - - v = llrintf(a); - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 0xffffffff; - } else { - res = v; - } - return res; -} -unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM) -{ - int64_t v; - unsigned int res; - - v = (int64_t)a; - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 0xffffffff; - } else { - res = v; - } - return res; -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision operations. -*----------------------------------------------------------------------------*/ -float32 float32_round_to_int( float32 a STATUS_PARAM) -{ - return rintf(a); -} - -float32 float32_rem( float32 a, float32 b STATUS_PARAM) -{ - return remainderf(a, b); -} - -float32 float32_sqrt( float32 a STATUS_PARAM) -{ - return sqrtf(a); -} -int float32_compare( float32 a, float32 b STATUS_PARAM ) -{ - if (a < b) { - return float_relation_less; - } else if (a == b) { - return float_relation_equal; - } else if (a > b) { - return float_relation_greater; - } else { - return float_relation_unordered; - } -} -int float32_compare_quiet( float32 a, float32 b STATUS_PARAM ) -{ - if (isless(a, b)) { - return float_relation_less; - } else if (a == b) { - return float_relation_equal; - } else if (isgreater(a, b)) { - return float_relation_greater; - } else { - return float_relation_unordered; - } -} -int float32_is_signaling_nan( float32 a1) -{ - float32u u; - uint32_t a; - u.f = a1; - a = u.i; - return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); -} - -int float32_is_quiet_nan( float32 a1 ) -{ - float32u u; - uint64_t a; - u.f = a1; - a = u.i; - return ( 0xFF800000 < ( a<<1 ) ); -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int float64_to_int32( float64 a STATUS_PARAM) -{ - return long_to_int32(lrint(a)); -} -int float64_to_int32_round_to_zero( float64 a STATUS_PARAM) -{ - return (int)a; -} -int64_t float64_to_int64( float64 a STATUS_PARAM) -{ - return llrint(a); -} -int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM) -{ - return (int64_t)a; -} -float32 float64_to_float32( float64 a STATUS_PARAM) -{ - return a; -} -#ifdef FLOATX80 -floatx80 float64_to_floatx80( float64 a STATUS_PARAM) -{ - return a; -} -#endif -#ifdef FLOAT128 -float128 float64_to_float128( float64 a STATUS_PARAM) -{ - return a; -} -#endif - -unsigned int float64_to_uint32( float64 a STATUS_PARAM) -{ - int64_t v; - unsigned int res; - - v = llrint(a); - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 0xffffffff; - } else { - res = v; - } - return res; -} -unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM) -{ - int64_t v; - unsigned int res; - - v = (int64_t)a; - if (v < 0) { - res = 0; - } else if (v > 0xffffffff) { - res = 0xffffffff; - } else { - res = v; - } - return res; -} -uint64_t float64_to_uint64 (float64 a STATUS_PARAM) -{ - int64_t v; - - v = llrint(a + (float64)INT64_MIN); - - return v - INT64_MIN; -} -uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM) -{ - int64_t v; - - v = (int64_t)(a + (float64)INT64_MIN); - - return v - INT64_MIN; -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision operations. -*----------------------------------------------------------------------------*/ -#if defined(__sun__) && \ - (defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10) -static inline float64 trunc(float64 x) -{ - return x < 0 ? -floor(-x) : floor(x); -} -#endif -float64 float64_trunc_to_int( float64 a STATUS_PARAM ) -{ - return trunc(a); -} - -float64 float64_round_to_int( float64 a STATUS_PARAM ) -{ - return rint(a); -} - -float64 float64_rem( float64 a, float64 b STATUS_PARAM) -{ - return remainder(a, b); -} - -float64 float64_sqrt( float64 a STATUS_PARAM) -{ - return sqrt(a); -} -int float64_compare( float64 a, float64 b STATUS_PARAM ) -{ - if (a < b) { - return float_relation_less; - } else if (a == b) { - return float_relation_equal; - } else if (a > b) { - return float_relation_greater; - } else { - return float_relation_unordered; - } -} -int float64_compare_quiet( float64 a, float64 b STATUS_PARAM ) -{ - if (isless(a, b)) { - return float_relation_less; - } else if (a == b) { - return float_relation_equal; - } else if (isgreater(a, b)) { - return float_relation_greater; - } else { - return float_relation_unordered; - } -} -int float64_is_signaling_nan( float64 a1) -{ - float64u u; - uint64_t a; - u.f = a1; - a = u.i; - return - ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) - && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); - -} - -int float64_is_quiet_nan( float64 a1 ) -{ - float64u u; - uint64_t a; - u.f = a1; - a = u.i; - - return ( LIT64( 0xFFF0000000000000 ) < (bits64) ( a<<1 ) ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int floatx80_to_int32( floatx80 a STATUS_PARAM) -{ - return long_to_int32(lrintl(a)); -} -int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM) -{ - return (int)a; -} -int64_t floatx80_to_int64( floatx80 a STATUS_PARAM) -{ - return llrintl(a); -} -int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM) -{ - return (int64_t)a; -} -float32 floatx80_to_float32( floatx80 a STATUS_PARAM) -{ - return a; -} -float64 floatx80_to_float64( floatx80 a STATUS_PARAM) -{ - return a; -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ -floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM) -{ - return rintl(a); -} -floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM) -{ - return remainderl(a, b); -} -floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM) -{ - return sqrtl(a); -} -int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM ) -{ - if (a < b) { - return float_relation_less; - } else if (a == b) { - return float_relation_equal; - } else if (a > b) { - return float_relation_greater; - } else { - return float_relation_unordered; - } -} -int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM ) -{ - if (isless(a, b)) { - return float_relation_less; - } else if (a == b) { - return float_relation_equal; - } else if (isgreater(a, b)) { - return float_relation_greater; - } else { - return float_relation_unordered; - } -} -int floatx80_is_signaling_nan( floatx80 a1) -{ - floatx80u u; - uint64_t aLow; - u.f = a1; - - aLow = u.i.low & ~ LIT64( 0x4000000000000000 ); - return - ( ( u.i.high & 0x7FFF ) == 0x7FFF ) - && (bits64) ( aLow<<1 ) - && ( u.i.low == aLow ); -} - -int floatx80_is_quiet_nan( floatx80 a1 ) -{ - floatx80u u; - u.f = a1; - return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 ); -} - -#endif diff --git a/fpu/softfloat-native.h b/fpu/softfloat-native.h deleted file mode 100644 index 80b5f28..0000000 --- a/fpu/softfloat-native.h +++ /dev/null @@ -1,492 +0,0 @@ -/* Native implementation of soft float functions */ -#include - -#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) \ - || defined(CONFIG_SOLARIS) -#include -#define fabsf(f) ((float)fabs(f)) -#else -#include -#endif - -#if defined(__OpenBSD__) || defined(__NetBSD__) -#include -#endif - -/* - * Define some C99-7.12.3 classification macros and - * some C99-.12.4 for Solaris systems OS less than 10, - * or Solaris 10 systems running GCC 3.x or less. - * Solaris 10 with GCC4 does not need these macros as they - * are defined in with a compiler directive - */ -#if defined(CONFIG_SOLARIS) && \ - ((CONFIG_SOLARIS_VERSION <= 9 ) || \ - ((CONFIG_SOLARIS_VERSION == 10) && (__GNUC__ < 4))) \ - || (defined(__OpenBSD__) && (OpenBSD < 200811)) -/* - * C99 7.12.3 classification macros - * and - * C99 7.12.14 comparison macros - * - * ... do not work on Solaris 10 using GNU CC 3.4.x. - * Try to workaround the missing / broken C99 math macros. - */ -#if defined(__OpenBSD__) -#define unordered(x, y) (isnan(x) || isnan(y)) -#endif - -#ifdef __NetBSD__ -#ifndef isgreater -#define isgreater(x, y) __builtin_isgreater(x, y) -#endif -#ifndef isgreaterequal -#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y) -#endif -#ifndef isless -#define isless(x, y) __builtin_isless(x, y) -#endif -#ifndef islessequal -#define islessequal(x, y) __builtin_islessequal(x, y) -#endif -#ifndef isunordered -#define isunordered(x, y) __builtin_isunordered(x, y) -#endif -#endif - - -#define isnormal(x) (fpclass(x) >= FP_NZERO) -#define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y))) -#define isgreaterequal(x, y) ((!unordered(x, y)) && ((x) >= (y))) -#define isless(x, y) ((!unordered(x, y)) && ((x) < (y))) -#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y))) -#define isunordered(x,y) unordered(x, y) -#endif - -#if defined(__sun__) && !defined(CONFIG_NEEDS_LIBSUNMATH) - -#ifndef isnan -# define isnan(x) \ - (sizeof (x) == sizeof (long double) ? isnan_ld (x) \ - : sizeof (x) == sizeof (double) ? isnan_d (x) \ - : isnan_f (x)) -static inline int isnan_f (float x) { return x != x; } -static inline int isnan_d (double x) { return x != x; } -static inline int isnan_ld (long double x) { return x != x; } -#endif - -#ifndef isinf -# define isinf(x) \ - (sizeof (x) == sizeof (long double) ? isinf_ld (x) \ - : sizeof (x) == sizeof (double) ? isinf_d (x) \ - : isinf_f (x)) -static inline int isinf_f (float x) { return isnan (x - x); } -static inline int isinf_d (double x) { return isnan (x - x); } -static inline int isinf_ld (long double x) { return isnan (x - x); } -#endif -#endif - -typedef float float32; -typedef double float64; -#ifdef FLOATX80 -typedef long double floatx80; -#endif - -typedef union { - float32 f; - uint32_t i; -} float32u; -typedef union { - float64 f; - uint64_t i; -} float64u; -#ifdef FLOATX80 -typedef union { - floatx80 f; - struct { - uint64_t low; - uint16_t high; - } i; -} floatx80u; -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point rounding mode. -*----------------------------------------------------------------------------*/ -#if (defined(CONFIG_BSD) && !defined(__APPLE__) && !defined(__GLIBC__)) \ - || defined(CONFIG_SOLARIS) -#if defined(__OpenBSD__) -#define FE_RM FP_RM -#define FE_RP FP_RP -#define FE_RZ FP_RZ -#endif -enum { - float_round_nearest_even = FP_RN, - float_round_down = FP_RM, - float_round_up = FP_RP, - float_round_to_zero = FP_RZ -}; -#else -enum { - float_round_nearest_even = FE_TONEAREST, - float_round_down = FE_DOWNWARD, - float_round_up = FE_UPWARD, - float_round_to_zero = FE_TOWARDZERO -}; -#endif - -typedef struct float_status { - int float_rounding_mode; -#ifdef FLOATX80 - int floatx80_rounding_precision; -#endif -} float_status; - -void set_float_rounding_mode(int val STATUS_PARAM); -#ifdef FLOATX80 -void set_floatx80_rounding_precision(int val STATUS_PARAM); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float32 int32_to_float32( int STATUS_PARAM); -float32 uint32_to_float32( unsigned int STATUS_PARAM); -float64 int32_to_float64( int STATUS_PARAM); -float64 uint32_to_float64( unsigned int STATUS_PARAM); -#ifdef FLOATX80 -floatx80 int32_to_floatx80( int STATUS_PARAM); -#endif -#ifdef FLOAT128 -float128 int32_to_float128( int STATUS_PARAM); -#endif -float32 int64_to_float32( int64_t STATUS_PARAM); -float32 uint64_to_float32( uint64_t STATUS_PARAM); -float64 int64_to_float64( int64_t STATUS_PARAM); -float64 uint64_to_float64( uint64_t v STATUS_PARAM); -#ifdef FLOATX80 -floatx80 int64_to_floatx80( int64_t STATUS_PARAM); -#endif -#ifdef FLOAT128 -float128 int64_to_float128( int64_t STATUS_PARAM); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision conversion routines. -*----------------------------------------------------------------------------*/ -int float32_to_int32( float32 STATUS_PARAM); -int float32_to_int32_round_to_zero( float32 STATUS_PARAM); -unsigned int float32_to_uint32( float32 a STATUS_PARAM); -unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM); -int64_t float32_to_int64( float32 STATUS_PARAM); -int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM); -float64 float32_to_float64( float32 STATUS_PARAM); -#ifdef FLOATX80 -floatx80 float32_to_floatx80( float32 STATUS_PARAM); -#endif -#ifdef FLOAT128 -float128 float32_to_float128( float32 STATUS_PARAM); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision operations. -*----------------------------------------------------------------------------*/ -float32 float32_round_to_int( float32 STATUS_PARAM); -INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM) -{ - return a + b; -} -INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM) -{ - return a - b; -} -INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM) -{ - return a * b; -} -INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM) -{ - return a / b; -} -float32 float32_rem( float32, float32 STATUS_PARAM); -float32 float32_sqrt( float32 STATUS_PARAM); -INLINE int float32_eq( float32 a, float32 b STATUS_PARAM) -{ - return a == b; -} -INLINE int float32_le( float32 a, float32 b STATUS_PARAM) -{ - return a <= b; -} -INLINE int float32_lt( float32 a, float32 b STATUS_PARAM) -{ - return a < b; -} -INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM) -{ - return a <= b && a >= b; -} -INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM) -{ - return islessequal(a, b); -} -INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM) -{ - return isless(a, b); -} -INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM) -{ - return isunordered(a, b); - -} -int float32_compare( float32, float32 STATUS_PARAM ); -int float32_compare_quiet( float32, float32 STATUS_PARAM ); -int float32_is_signaling_nan( float32 ); -int float32_is_quiet_nan( float32 ); - -INLINE float32 float32_abs(float32 a) -{ - return fabsf(a); -} - -INLINE float32 float32_chs(float32 a) -{ - return -a; -} - -INLINE float32 float32_is_infinity(float32 a) -{ - return fpclassify(a) == FP_INFINITE; -} - -INLINE float32 float32_is_neg(float32 a) -{ - float32u u; - u.f = a; - return u.i >> 31; -} - -INLINE float32 float32_is_zero(float32 a) -{ - return fpclassify(a) == FP_ZERO; -} - -INLINE float32 float32_scalbn(float32 a, int n) -{ - return scalbnf(a, n); -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int float64_to_int32( float64 STATUS_PARAM ); -int float64_to_int32_round_to_zero( float64 STATUS_PARAM ); -unsigned int float64_to_uint32( float64 STATUS_PARAM ); -unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM ); -int64_t float64_to_int64( float64 STATUS_PARAM ); -int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM ); -uint64_t float64_to_uint64( float64 STATUS_PARAM ); -uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM ); -float32 float64_to_float32( float64 STATUS_PARAM ); -#ifdef FLOATX80 -floatx80 float64_to_floatx80( float64 STATUS_PARAM ); -#endif -#ifdef FLOAT128 -float128 float64_to_float128( float64 STATUS_PARAM ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision operations. -*----------------------------------------------------------------------------*/ -float64 float64_round_to_int( float64 STATUS_PARAM ); -float64 float64_trunc_to_int( float64 STATUS_PARAM ); -INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM) -{ - return a + b; -} -INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM) -{ - return a - b; -} -INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM) -{ - return a * b; -} -INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM) -{ - return a / b; -} -float64 float64_rem( float64, float64 STATUS_PARAM ); -float64 float64_sqrt( float64 STATUS_PARAM ); -INLINE int float64_eq( float64 a, float64 b STATUS_PARAM) -{ - return a == b; -} -INLINE int float64_le( float64 a, float64 b STATUS_PARAM) -{ - return a <= b; -} -INLINE int float64_lt( float64 a, float64 b STATUS_PARAM) -{ - return a < b; -} -INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM) -{ - return a <= b && a >= b; -} -INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM) -{ - return islessequal(a, b); -} -INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM) -{ - return isless(a, b); - -} -INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM) -{ - return isunordered(a, b); - -} -int float64_compare( float64, float64 STATUS_PARAM ); -int float64_compare_quiet( float64, float64 STATUS_PARAM ); -int float64_is_signaling_nan( float64 ); -int float64_is_quiet_nan( float64 ); - -INLINE float64 float64_abs(float64 a) -{ - return fabs(a); -} - -INLINE float64 float64_chs(float64 a) -{ - return -a; -} - -INLINE float64 float64_is_infinity(float64 a) -{ - return fpclassify(a) == FP_INFINITE; -} - -INLINE float64 float64_is_neg(float64 a) -{ - float64u u; - u.f = a; - return u.i >> 63; -} - -INLINE float64 float64_is_zero(float64 a) -{ - return fpclassify(a) == FP_ZERO; -} - -INLINE float64 float64_scalbn(float64 a, int n) -{ - return scalbn(a, n); -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int floatx80_to_int32( floatx80 STATUS_PARAM ); -int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM ); -int64_t floatx80_to_int64( floatx80 STATUS_PARAM); -int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM); -float32 floatx80_to_float32( floatx80 STATUS_PARAM ); -float64 floatx80_to_float64( floatx80 STATUS_PARAM ); -#ifdef FLOAT128 -float128 floatx80_to_float128( floatx80 STATUS_PARAM ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ -floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM ); -INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a + b; -} -INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a - b; -} -INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a * b; -} -INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a / b; -} -floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM ); -floatx80 floatx80_sqrt( floatx80 STATUS_PARAM ); -INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a == b; -} -INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a <= b; -} -INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a < b; -} -INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM) -{ - return a <= b && a >= b; -} -INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM) -{ - return islessequal(a, b); -} -INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM) -{ - return isless(a, b); - -} -INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM) -{ - return isunordered(a, b); - -} -int floatx80_compare( floatx80, floatx80 STATUS_PARAM ); -int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM ); -int floatx80_is_signaling_nan( floatx80 ); -int floatx80_is_quiet_nan( floatx80 ); - -INLINE floatx80 floatx80_abs(floatx80 a) -{ - return fabsl(a); -} - -INLINE floatx80 floatx80_chs(floatx80 a) -{ - return -a; -} - -INLINE floatx80 floatx80_is_infinity(floatx80 a) -{ - return fpclassify(a) == FP_INFINITE; -} - -INLINE floatx80 floatx80_is_neg(floatx80 a) -{ - floatx80u u; - u.f = a; - return u.i.high >> 15; -} - -INLINE floatx80 floatx80_is_zero(floatx80 a) -{ - return fpclassify(a) == FP_ZERO; -} - -INLINE floatx80 floatx80_scalbn(floatx80 a, int n) -{ - return scalbnl(a, n); -} - -#endif diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index eb644b2..c5e2dab 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -1,3 +1,8 @@ +/* + * QEMU float support + * + * Derived from SoftFloat. + */ /*============================================================================ @@ -30,13 +35,79 @@ these four paragraphs for those parts of this code that are retained. =============================================================================*/ -#if defined(TARGET_MIPS) || defined(TARGET_SH4) +#if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) #define SNAN_BIT_IS_ONE 1 #else #define SNAN_BIT_IS_ONE 0 #endif /*---------------------------------------------------------------------------- +| The pattern for a default generated half-precision NaN. +*----------------------------------------------------------------------------*/ +#if defined(TARGET_ARM) +const float16 float16_default_nan = const_float16(0x7E00); +#elif SNAN_BIT_IS_ONE +const float16 float16_default_nan = const_float16(0x7DFF); +#else +const float16 float16_default_nan = const_float16(0xFE00); +#endif + +/*---------------------------------------------------------------------------- +| The pattern for a default generated single-precision NaN. +*----------------------------------------------------------------------------*/ +#if defined(TARGET_SPARC) +const float32 float32_default_nan = const_float32(0x7FFFFFFF); +#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) +const float32 float32_default_nan = const_float32(0x7FC00000); +#elif SNAN_BIT_IS_ONE +const float32 float32_default_nan = const_float32(0x7FBFFFFF); +#else +const float32 float32_default_nan = const_float32(0xFFC00000); +#endif + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +#if defined(TARGET_SPARC) +const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF )); +#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) +const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 )); +#elif SNAN_BIT_IS_ONE +const float64 float64_default_nan = const_float64(LIT64( 0x7FF7FFFFFFFFFFFF )); +#else +const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 )); +#endif + +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. +*----------------------------------------------------------------------------*/ +#if SNAN_BIT_IS_ONE +#define floatx80_default_nan_high 0x7FFF +#define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF ) +#else +#define floatx80_default_nan_high 0xFFFF +#define floatx80_default_nan_low LIT64( 0xC000000000000000 ) +#endif + +const floatx80 floatx80_default_nan = make_floatx80(floatx80_default_nan_high, + floatx80_default_nan_low); + +/*---------------------------------------------------------------------------- +| The pattern for a default generated quadruple-precision NaN. The `high' and +| `low' values hold the most- and least-significant bits, respectively. +*----------------------------------------------------------------------------*/ +#if SNAN_BIT_IS_ONE +#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF ) +#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) +#else +#define float128_default_nan_high LIT64( 0xFFFF800000000000 ) +#define float128_default_nan_low LIT64( 0x0000000000000000 ) +#endif + +const float128 float128_default_nan = make_float128(float128_default_nan_high, + float128_default_nan_low); + +/*---------------------------------------------------------------------------- | Raises the exceptions specified by `flags'. Floating-point traps can be | defined here if desired. It is currently not possible for such a trap | to substitute a result value. If traps are not implemented, this routine @@ -53,21 +124,98 @@ void float_raise( int8 flags STATUS_PARAM ) *----------------------------------------------------------------------------*/ typedef struct { flag sign; - bits64 high, low; + uint64_t high, low; } commonNaNT; /*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. +| Returns 1 if the half-precision floating-point value `a' is a quiet +| NaN; otherwise returns 0. *----------------------------------------------------------------------------*/ -#if defined(TARGET_SPARC) -#define float32_default_nan make_float32(0x7FFFFFFF) -#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) -#define float32_default_nan make_float32(0x7FC00000) -#elif SNAN_BIT_IS_ONE -#define float32_default_nan make_float32(0x7FBFFFFF) + +int float16_is_quiet_nan(float16 a_) +{ + uint16_t a = float16_val(a_); +#if SNAN_BIT_IS_ONE + return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); +#else + return ((a & ~0x8000) >= 0x7c80); +#endif +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the half-precision floating-point value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +int float16_is_signaling_nan(float16 a_) +{ + uint16_t a = float16_val(a_); +#if SNAN_BIT_IS_ONE + return ((a & ~0x8000) >= 0x7c80); +#else + return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); +#endif +} + +/*---------------------------------------------------------------------------- +| Returns a quiet NaN if the half-precision floating point value `a' is a +| signaling NaN; otherwise returns `a'. +*----------------------------------------------------------------------------*/ +float16 float16_maybe_silence_nan(float16 a_) +{ + if (float16_is_signaling_nan(a_)) { +#if SNAN_BIT_IS_ONE +# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) + return float16_default_nan; +# else +# error Rules for silencing a signaling NaN are target-specific +# endif #else -#define float32_default_nan make_float32(0xFFC00000) + uint16_t a = float16_val(a_); + a |= (1 << 9); + return make_float16(a); #endif + } + return a_; +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the half-precision floating-point NaN +| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM ) +{ + commonNaNT z; + + if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); + z.sign = float16_val(a) >> 15; + z.low = 0; + z.high = ((uint64_t) float16_val(a))<<54; + return z; +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the half- +| precision floating-point format. +*----------------------------------------------------------------------------*/ + +static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM) +{ + uint16_t mantissa = a.high>>54; + + if (STATUS(default_nan_mode)) { + return float16_default_nan; + } + + if (mantissa) { + return make_float16(((((uint16_t) a.sign) << 15) + | (0x1F << 10) | mantissa)); + } else { + return float16_default_nan; + } +} /*---------------------------------------------------------------------------- | Returns 1 if the single-precision floating-point value `a' is a quiet @@ -80,7 +228,7 @@ int float32_is_quiet_nan( float32 a_ ) #if SNAN_BIT_IS_ONE return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); #else - return ( 0xFF800000 <= (bits32) ( a<<1 ) ); + return ( 0xFF800000 <= (uint32_t) ( a<<1 ) ); #endif } @@ -93,7 +241,7 @@ int float32_is_signaling_nan( float32 a_ ) { uint32_t a = float32_val(a_); #if SNAN_BIT_IS_ONE - return ( 0xFF800000 <= (bits32) ( a<<1 ) ); + return ( 0xFF800000 <= (uint32_t) ( a<<1 ) ); #else return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); #endif @@ -108,13 +256,13 @@ float32 float32_maybe_silence_nan( float32 a_ ) { if (float32_is_signaling_nan(a_)) { #if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) +# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) return float32_default_nan; # else # error Rules for silencing a signaling NaN are target-specific # endif #else - bits32 a = float32_val(a_); + uint32_t a = float32_val(a_); a |= (1 << 22); return make_float32(a); #endif @@ -135,7 +283,7 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); z.sign = float32_val(a)>>31; z.low = 0; - z.high = ( (bits64) float32_val(a) )<<41; + z.high = ( (uint64_t) float32_val(a) )<<41; return z; } @@ -144,12 +292,17 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | precision floating-point format. *----------------------------------------------------------------------------*/ -static float32 commonNaNToFloat32( commonNaNT a ) +static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM) { - bits32 mantissa = a.high>>41; + uint32_t mantissa = a.high>>41; + + if ( STATUS(default_nan_mode) ) { + return float32_default_nan; + } + if ( mantissa ) return make_float32( - ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) ); + ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) ); else return float32_default_nan; } @@ -267,6 +420,82 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, #endif /*---------------------------------------------------------------------------- +| Select which NaN to propagate for a three-input operation. +| For the moment we assume that no CPU needs the 'larger significand' +| information. +| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN +*----------------------------------------------------------------------------*/ +#if defined(TARGET_ARM) +static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, + flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM) +{ + /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns + * the default NaN + */ + if (infzero && cIsQNaN) { + float_raise(float_flag_invalid STATUS_VAR); + return 3; + } + + /* This looks different from the ARM ARM pseudocode, because the ARM ARM + * puts the operands to a fused mac operation (a*b)+c in the order c,a,b. + */ + if (cIsSNaN) { + return 2; + } else if (aIsSNaN) { + return 0; + } else if (bIsSNaN) { + return 1; + } else if (cIsQNaN) { + return 2; + } else if (aIsQNaN) { + return 0; + } else { + return 1; + } +} +#elif defined(TARGET_PPC) +static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, + flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM) +{ + /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer + * to return an input NaN if we have one (ie c) rather than generating + * a default NaN + */ + if (infzero) { + float_raise(float_flag_invalid STATUS_VAR); + return 2; + } + + /* If fRA is a NaN return it; otherwise if fRB is a NaN return it; + * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB + */ + if (aIsSNaN || aIsQNaN) { + return 0; + } else if (cIsSNaN || cIsQNaN) { + return 2; + } else { + return 1; + } +} +#else +/* A default implementation: prefer a to b to c. + * This is unlikely to actually match any real implementation. + */ +static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, + flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM) +{ + if (aIsSNaN || aIsQNaN) { + return 0; + } else if (bIsSNaN || bIsQNaN) { + return 1; + } else { + return 2; + } +} +#endif + +/*---------------------------------------------------------------------------- | Takes two single-precision floating-point values `a' and `b', one of which | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a | signaling NaN, the invalid exception is raised. @@ -276,7 +505,7 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) { flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; flag aIsLargerSignificand; - bits32 av, bv; + uint32_t av, bv; aIsQuietNaN = float32_is_quiet_nan( a ); aIsSignalingNaN = float32_is_signaling_nan( a ); @@ -290,9 +519,9 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) if ( STATUS(default_nan_mode) ) return float32_default_nan; - if ((bits32)(av<<1) < (bits32)(bv<<1)) { + if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) { aIsLargerSignificand = 0; - } else if ((bits32)(bv<<1) < (bits32)(av<<1)) { + } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) { aIsLargerSignificand = 1; } else { aIsLargerSignificand = (av < bv) ? 1 : 0; @@ -307,17 +536,55 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) } /*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. +| Takes three single-precision floating-point values `a', `b' and `c', one of +| which is a NaN, and returns the appropriate NaN result. If any of `a', +| `b' or `c' is a signaling NaN, the invalid exception is raised. +| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case +| obviously c is a NaN, and whether to propagate c or some other NaN is +| implementation defined). *----------------------------------------------------------------------------*/ -#if defined(TARGET_SPARC) -#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF )) -#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) -#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 )) -#elif SNAN_BIT_IS_ONE -#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF )) -#else -#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 )) -#endif + +static float32 propagateFloat32MulAddNaN(float32 a, float32 b, + float32 c, flag infzero STATUS_PARAM) +{ + flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, + cIsQuietNaN, cIsSignalingNaN; + int which; + + aIsQuietNaN = float32_is_quiet_nan(a); + aIsSignalingNaN = float32_is_signaling_nan(a); + bIsQuietNaN = float32_is_quiet_nan(b); + bIsSignalingNaN = float32_is_signaling_nan(b); + cIsQuietNaN = float32_is_quiet_nan(c); + cIsSignalingNaN = float32_is_signaling_nan(c); + + if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { + float_raise(float_flag_invalid STATUS_VAR); + } + + which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, + bIsQuietNaN, bIsSignalingNaN, + cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR); + + if (STATUS(default_nan_mode)) { + /* Note that this check is after pickNaNMulAdd so that function + * has an opportunity to set the Invalid flag. + */ + return float32_default_nan; + } + + switch (which) { + case 0: + return float32_maybe_silence_nan(a); + case 1: + return float32_maybe_silence_nan(b); + case 2: + return float32_maybe_silence_nan(c); + case 3: + default: + return float32_default_nan; + } +} /*---------------------------------------------------------------------------- | Returns 1 if the double-precision floating-point value `a' is a quiet @@ -326,13 +593,13 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) int float64_is_quiet_nan( float64 a_ ) { - bits64 a = float64_val(a_); + uint64_t a = float64_val(a_); #if SNAN_BIT_IS_ONE return ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); #else - return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); + return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) ); #endif } @@ -343,9 +610,9 @@ int float64_is_quiet_nan( float64 a_ ) int float64_is_signaling_nan( float64 a_ ) { - bits64 a = float64_val(a_); + uint64_t a = float64_val(a_); #if SNAN_BIT_IS_ONE - return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); + return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) ); #else return ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) @@ -362,13 +629,13 @@ float64 float64_maybe_silence_nan( float64 a_ ) { if (float64_is_signaling_nan(a_)) { #if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) +# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) return float64_default_nan; # else # error Rules for silencing a signaling NaN are target-specific # endif #else - bits64 a = float64_val(a_); + uint64_t a = float64_val(a_); a |= LIT64( 0x0008000000000000 ); return make_float64(a); #endif @@ -398,13 +665,17 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | precision floating-point format. *----------------------------------------------------------------------------*/ -static float64 commonNaNToFloat64( commonNaNT a ) +static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM) { - bits64 mantissa = a.high>>12; + uint64_t mantissa = a.high>>12; + + if ( STATUS(default_nan_mode) ) { + return float64_default_nan; + } if ( mantissa ) return make_float64( - ( ( (bits64) a.sign )<<63 ) + ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FF0000000000000 ) | ( a.high>>12 )); else @@ -421,7 +692,7 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) { flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; flag aIsLargerSignificand; - bits64 av, bv; + uint64_t av, bv; aIsQuietNaN = float64_is_quiet_nan( a ); aIsSignalingNaN = float64_is_signaling_nan( a ); @@ -435,9 +706,9 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) if ( STATUS(default_nan_mode) ) return float64_default_nan; - if ((bits64)(av<<1) < (bits64)(bv<<1)) { + if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) { aIsLargerSignificand = 0; - } else if ((bits64)(bv<<1) < (bits64)(av<<1)) { + } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) { aIsLargerSignificand = 1; } else { aIsLargerSignificand = (av < bv) ? 1 : 0; @@ -451,20 +722,56 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) } } -#ifdef FLOATX80 - /*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. The -| `high' and `low' values hold the most- and least-significant bits, -| respectively. +| Takes three double-precision floating-point values `a', `b' and `c', one of +| which is a NaN, and returns the appropriate NaN result. If any of `a', +| `b' or `c' is a signaling NaN, the invalid exception is raised. +| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case +| obviously c is a NaN, and whether to propagate c or some other NaN is +| implementation defined). *----------------------------------------------------------------------------*/ -#if SNAN_BIT_IS_ONE -#define floatx80_default_nan_high 0x7FFF -#define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF ) -#else -#define floatx80_default_nan_high 0xFFFF -#define floatx80_default_nan_low LIT64( 0xC000000000000000 ) -#endif + +static float64 propagateFloat64MulAddNaN(float64 a, float64 b, + float64 c, flag infzero STATUS_PARAM) +{ + flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, + cIsQuietNaN, cIsSignalingNaN; + int which; + + aIsQuietNaN = float64_is_quiet_nan(a); + aIsSignalingNaN = float64_is_signaling_nan(a); + bIsQuietNaN = float64_is_quiet_nan(b); + bIsSignalingNaN = float64_is_signaling_nan(b); + cIsQuietNaN = float64_is_quiet_nan(c); + cIsSignalingNaN = float64_is_signaling_nan(c); + + if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { + float_raise(float_flag_invalid STATUS_VAR); + } + + which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, + bIsQuietNaN, bIsSignalingNaN, + cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR); + + if (STATUS(default_nan_mode)) { + /* Note that this check is after pickNaNMulAdd so that function + * has an opportunity to set the Invalid flag. + */ + return float64_default_nan; + } + + switch (which) { + case 0: + return float64_maybe_silence_nan(a); + case 1: + return float64_maybe_silence_nan(b); + case 2: + return float64_maybe_silence_nan(c); + case 3: + default: + return float64_default_nan; + } +} /*---------------------------------------------------------------------------- | Returns 1 if the extended double-precision floating-point value `a' is a @@ -475,16 +782,16 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) int floatx80_is_quiet_nan( floatx80 a ) { #if SNAN_BIT_IS_ONE - bits64 aLow; + uint64_t aLow; aLow = a.low & ~ LIT64( 0x4000000000000000 ); return ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (bits64) ( aLow<<1 ) + && (uint64_t) ( aLow<<1 ) && ( a.low == aLow ); #else return ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 ))); + && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 ))); #endif } @@ -498,14 +805,14 @@ int floatx80_is_signaling_nan( floatx80 a ) { #if SNAN_BIT_IS_ONE return ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 ))); + && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 ))); #else - bits64 aLow; + uint64_t aLow; aLow = a.low & ~ LIT64( 0x4000000000000000 ); return ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (bits64) ( aLow<<1 ) + && (uint64_t) ( aLow<<1 ) && ( a.low == aLow ); #endif } @@ -519,7 +826,7 @@ floatx80 floatx80_maybe_silence_nan( floatx80 a ) { if (floatx80_is_signaling_nan(a)) { #if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) +# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) a.low = floatx80_default_nan_low; a.high = floatx80_default_nan_high; # else @@ -544,9 +851,15 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM) commonNaNT z; if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); - z.sign = a.high>>15; - z.low = 0; - z.high = a.low; + if ( a.low >> 63 ) { + z.sign = a.high >> 15; + z.low = 0; + z.high = a.low << 1; + } else { + z.sign = floatx80_default_nan_high >> 15; + z.low = 0; + z.high = floatx80_default_nan_low << 1; + } return z; } @@ -555,15 +868,24 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM) | double-precision floating-point format. *----------------------------------------------------------------------------*/ -static floatx80 commonNaNToFloatx80( commonNaNT a ) +static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM) { floatx80 z; - if (a.high) - z.low = a.high; - else + if ( STATUS(default_nan_mode) ) { + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + + if (a.high >> 1) { + z.low = LIT64( 0x8000000000000000 ) | a.high >> 1; + z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF; + } else { z.low = floatx80_default_nan_low; - z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; + z.high = floatx80_default_nan_high; + } + return z; } @@ -607,22 +929,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) } } -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. The `high' and -| `low' values hold the most- and least-significant bits, respectively. -*----------------------------------------------------------------------------*/ -#if SNAN_BIT_IS_ONE -#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF ) -#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) -#else -#define float128_default_nan_high LIT64( 0xFFFF800000000000 ) -#define float128_default_nan_low LIT64( 0x0000000000000000 ) -#endif - /*---------------------------------------------------------------------------- | Returns 1 if the quadruple-precision floating-point value `a' is a quiet | NaN; otherwise returns 0. @@ -636,7 +942,7 @@ int float128_is_quiet_nan( float128 a ) && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); #else return - ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) + ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) ) && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); #endif } @@ -650,7 +956,7 @@ int float128_is_signaling_nan( float128 a ) { #if SNAN_BIT_IS_ONE return - ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) + ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) ) && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); #else return @@ -668,7 +974,7 @@ float128 float128_maybe_silence_nan( float128 a ) { if (float128_is_signaling_nan(a)) { #if SNAN_BIT_IS_ONE -# if defined(TARGET_MIPS) || defined(TARGET_SH4) +# if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) a.low = float128_default_nan_low; a.high = float128_default_nan_high; # else @@ -703,12 +1009,18 @@ static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM) | precision floating-point format. *----------------------------------------------------------------------------*/ -static float128 commonNaNToFloat128( commonNaNT a ) +static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM) { float128 z; + if ( STATUS(default_nan_mode) ) { + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + shift128Right( a.high, a.low, 16, &z.high, &z.low ); - z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 ); + z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 ); return z; } @@ -752,4 +1064,3 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) } } -#endif diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 17842f4..81a7d1a 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1,3 +1,8 @@ +/* + * QEMU float support + * + * Derived from SoftFloat. + */ /*============================================================================ @@ -30,6 +35,11 @@ these four paragraphs for those parts of this code that are retained. =============================================================================*/ +/* softfloat (and in particular the code in softfloat-specialize.h) is + * target-dependent and needs the TARGET_* macros. + */ +#include "config.h" + #include "softfloat.h" /*---------------------------------------------------------------------------- @@ -59,12 +69,37 @@ void set_float_exception_flags(int val STATUS_PARAM) STATUS(float_exception_flags) = val; } -#ifdef FLOATX80 void set_floatx80_rounding_precision(int val STATUS_PARAM) { STATUS(floatx80_rounding_precision) = val; } -#endif + +/*---------------------------------------------------------------------------- +| Returns the fraction bits of the half-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE uint32_t extractFloat16Frac(float16 a) +{ + return float16_val(a) & 0x3ff; +} + +/*---------------------------------------------------------------------------- +| Returns the exponent bits of the half-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE int16 extractFloat16Exp(float16 a) +{ + return (float16_val(a) >> 10) & 0x1f; +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE flag extractFloat16Sign(float16 a) +{ + return float16_val(a)>>15; +} /*---------------------------------------------------------------------------- | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 @@ -77,7 +112,7 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM) | positive or negative integer is returned. *----------------------------------------------------------------------------*/ -static int32 roundAndPackInt32( flag zSign, bits64 absZ STATUS_PARAM) +static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM) { int8 roundingMode; flag roundNearestEven; @@ -108,7 +143,7 @@ static int32 roundAndPackInt32( flag zSign, bits64 absZ STATUS_PARAM) if ( zSign ) z = - z; if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { float_raise( float_flag_invalid STATUS_VAR); - return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + return zSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; } if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact; return z; @@ -127,7 +162,7 @@ static int32 roundAndPackInt32( flag zSign, bits64 absZ STATUS_PARAM) | returned. *----------------------------------------------------------------------------*/ -static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PARAM) +static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATUS_PARAM) { int8 roundingMode; flag roundNearestEven, increment; @@ -135,7 +170,7 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PA roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) absZ1 < 0 ); + increment = ( (int64_t) absZ1 < 0 ); if ( ! roundNearestEven ) { if ( roundingMode == float_round_to_zero ) { increment = 0; @@ -152,7 +187,7 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PA if ( increment ) { ++absZ0; if ( absZ0 == 0 ) goto overflow; - absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); + absZ0 &= ~ ( ( (uint64_t) ( absZ1<<1 ) == 0 ) & roundNearestEven ); } z = absZ0; if ( zSign ) z = - z; @@ -160,7 +195,7 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PA overflow: float_raise( float_flag_invalid STATUS_VAR); return - zSign ? (sbits64) LIT64( 0x8000000000000000 ) + zSign ? (int64_t) LIT64( 0x8000000000000000 ) : LIT64( 0x7FFFFFFFFFFFFFFF ); } if ( absZ1 ) STATUS(float_exception_flags) |= float_flag_inexact; @@ -172,7 +207,7 @@ static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PA | Returns the fraction bits of the single-precision floating-point value `a'. *----------------------------------------------------------------------------*/ -INLINE bits32 extractFloat32Frac( float32 a ) +INLINE uint32_t extractFloat32Frac( float32 a ) { return float32_val(a) & 0x007FFFFF; @@ -224,7 +259,7 @@ static float32 float32_squash_input_denormal(float32 a STATUS_PARAM) *----------------------------------------------------------------------------*/ static void - normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) + normalizeFloat32Subnormal( uint32_t aSig, int16 *zExpPtr, uint32_t *zSigPtr ) { int8 shiftCount; @@ -245,11 +280,11 @@ static void | significand. *----------------------------------------------------------------------------*/ -INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig ) +INLINE float32 packFloat32( flag zSign, int16 zExp, uint32_t zSig ) { return make_float32( - ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig); + ( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig); } @@ -275,7 +310,7 @@ INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig ) | Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM) +static float32 roundAndPackFloat32( flag zSign, int16 zExp, uint32_t zSig STATUS_PARAM) { int8 roundingMode; flag roundNearestEven; @@ -300,16 +335,19 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_P } } roundBits = zSig & 0x7F; - if ( 0xFD <= (bits16) zExp ) { + if ( 0xFD <= (uint16_t) zExp ) { if ( ( 0xFD < zExp ) || ( ( zExp == 0xFD ) - && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) + && ( (int32_t) ( zSig + roundIncrement ) < 0 ) ) ) { float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 )); } if ( zExp < 0 ) { - if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 ); + if (STATUS(flush_to_zero)) { + float_raise(float_flag_output_denormal STATUS_VAR); + return packFloat32(zSign, 0, 0); + } isTiny = ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) || ( zExp < -1 ) @@ -338,7 +376,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_P *----------------------------------------------------------------------------*/ static float32 - normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM) + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, uint32_t zSig STATUS_PARAM) { int8 shiftCount; @@ -351,7 +389,7 @@ static float32 | Returns the fraction bits of the double-precision floating-point value `a'. *----------------------------------------------------------------------------*/ -INLINE bits64 extractFloat64Frac( float64 a ) +INLINE uint64_t extractFloat64Frac( float64 a ) { return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF ); @@ -403,7 +441,7 @@ static float64 float64_squash_input_denormal(float64 a STATUS_PARAM) *----------------------------------------------------------------------------*/ static void - normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) + normalizeFloat64Subnormal( uint64_t aSig, int16 *zExpPtr, uint64_t *zSigPtr ) { int8 shiftCount; @@ -424,11 +462,11 @@ static void | significand. *----------------------------------------------------------------------------*/ -INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig ) +INLINE float64 packFloat64( flag zSign, int16 zExp, uint64_t zSig ) { return make_float64( - ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig); + ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<52 ) + zSig); } @@ -454,7 +492,7 @@ INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig ) | Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM) +static float64 roundAndPackFloat64( flag zSign, int16 zExp, uint64_t zSig STATUS_PARAM) { int8 roundingMode; flag roundNearestEven; @@ -479,16 +517,19 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_P } } roundBits = zSig & 0x3FF; - if ( 0x7FD <= (bits16) zExp ) { + if ( 0x7FD <= (uint16_t) zExp ) { if ( ( 0x7FD < zExp ) || ( ( zExp == 0x7FD ) - && ( (sbits64) ( zSig + roundIncrement ) < 0 ) ) + && ( (int64_t) ( zSig + roundIncrement ) < 0 ) ) ) { float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 )); } if ( zExp < 0 ) { - if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 ); + if (STATUS(flush_to_zero)) { + float_raise(float_flag_output_denormal STATUS_VAR); + return packFloat64(zSign, 0, 0); + } isTiny = ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) || ( zExp < -1 ) @@ -517,7 +558,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_P *----------------------------------------------------------------------------*/ static float64 - normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM) + normalizeRoundAndPackFloat64( flag zSign, int16 zExp, uint64_t zSig STATUS_PARAM) { int8 shiftCount; @@ -526,14 +567,12 @@ static float64 } -#ifdef FLOATX80 - /*---------------------------------------------------------------------------- | Returns the fraction bits of the extended double-precision floating-point | value `a'. *----------------------------------------------------------------------------*/ -INLINE bits64 extractFloatx80Frac( floatx80 a ) +INLINE uint64_t extractFloatx80Frac( floatx80 a ) { return a.low; @@ -572,7 +611,7 @@ INLINE flag extractFloatx80Sign( floatx80 a ) *----------------------------------------------------------------------------*/ static void - normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr ) + normalizeFloatx80Subnormal( uint64_t aSig, int32 *zExpPtr, uint64_t *zSigPtr ) { int8 shiftCount; @@ -587,12 +626,12 @@ static void | extended double-precision floating-point value, returning the result. *----------------------------------------------------------------------------*/ -INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) +INLINE floatx80 packFloatx80( flag zSign, int32 zExp, uint64_t zSig ) { floatx80 z; z.low = zSig; - z.high = ( ( (bits16) zSign )<<15 ) + zExp; + z.high = ( ( (uint16_t) zSign )<<15 ) + zExp; return z; } @@ -623,7 +662,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) static floatx80 roundAndPackFloatx80( - int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 + int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 STATUS_PARAM) { int8 roundingMode; @@ -660,14 +699,17 @@ static floatx80 } } roundBits = zSig0 & roundMask; - if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) { + if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) { if ( ( 0x7FFE < zExp ) || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) ) ) { goto overflow; } if ( zExp <= 0 ) { - if ( STATUS(flush_to_zero) ) return packFloatx80( zSign, 0, 0 ); + if (STATUS(flush_to_zero)) { + float_raise(float_flag_output_denormal STATUS_VAR); + return packFloatx80(zSign, 0, 0); + } isTiny = ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) || ( zExp < 0 ) @@ -678,7 +720,7 @@ static floatx80 if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR); if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact; zSig0 += roundIncrement; - if ( (sbits64) zSig0 < 0 ) zExp = 1; + if ( (int64_t) zSig0 < 0 ) zExp = 1; roundIncrement = roundMask + 1; if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) { roundMask |= roundIncrement; @@ -701,7 +743,7 @@ static floatx80 if ( zSig0 == 0 ) zExp = 0; return packFloatx80( zSign, zExp, zSig0 ); precision80: - increment = ( (sbits64) zSig1 < 0 ); + increment = ( (int64_t) zSig1 < 0 ); if ( ! roundNearestEven ) { if ( roundingMode == float_round_to_zero ) { increment = 0; @@ -715,7 +757,7 @@ static floatx80 } } } - if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) { + if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) { if ( ( 0x7FFE < zExp ) || ( ( zExp == 0x7FFE ) && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) ) @@ -744,7 +786,7 @@ static floatx80 if ( isTiny && zSig1 ) float_raise( float_flag_underflow STATUS_VAR); if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact; if ( roundNearestEven ) { - increment = ( (sbits64) zSig1 < 0 ); + increment = ( (int64_t) zSig1 < 0 ); } else { if ( zSign ) { @@ -757,8 +799,8 @@ static floatx80 if ( increment ) { ++zSig0; zSig0 &= - ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven ); - if ( (sbits64) zSig0 < 0 ) zExp = 1; + ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven ); + if ( (int64_t) zSig0 < 0 ) zExp = 1; } return packFloatx80( zSign, zExp, zSig0 ); } @@ -771,7 +813,7 @@ static floatx80 zSig0 = LIT64( 0x8000000000000000 ); } else { - zSig0 &= ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven ); + zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven ); } } else { @@ -792,7 +834,7 @@ static floatx80 static floatx80 normalizeRoundAndPackFloatx80( - int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 + int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 STATUS_PARAM) { int8 shiftCount; @@ -810,16 +852,12 @@ static floatx80 } -#endif - -#ifdef FLOAT128 - /*---------------------------------------------------------------------------- | Returns the least-significant 64 fraction bits of the quadruple-precision | floating-point value `a'. *----------------------------------------------------------------------------*/ -INLINE bits64 extractFloat128Frac1( float128 a ) +INLINE uint64_t extractFloat128Frac1( float128 a ) { return a.low; @@ -831,7 +869,7 @@ INLINE bits64 extractFloat128Frac1( float128 a ) | floating-point value `a'. *----------------------------------------------------------------------------*/ -INLINE bits64 extractFloat128Frac0( float128 a ) +INLINE uint64_t extractFloat128Frac0( float128 a ) { return a.high & LIT64( 0x0000FFFFFFFFFFFF ); @@ -873,11 +911,11 @@ INLINE flag extractFloat128Sign( float128 a ) static void normalizeFloat128Subnormal( - bits64 aSig0, - bits64 aSig1, + uint64_t aSig0, + uint64_t aSig1, int32 *zExpPtr, - bits64 *zSig0Ptr, - bits64 *zSig1Ptr + uint64_t *zSig0Ptr, + uint64_t *zSig1Ptr ) { int8 shiftCount; @@ -916,12 +954,12 @@ static void *----------------------------------------------------------------------------*/ INLINE float128 - packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) + packFloat128( flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 ) { float128 z; z.low = zSig1; - z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; + z.high = ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<48 ) + zSig0; return z; } @@ -949,14 +987,14 @@ INLINE float128 static float128 roundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 STATUS_PARAM) + flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1, uint64_t zSig2 STATUS_PARAM) { int8 roundingMode; flag roundNearestEven, increment, isTiny; roundingMode = STATUS(float_rounding_mode); roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) zSig2 < 0 ); + increment = ( (int64_t) zSig2 < 0 ); if ( ! roundNearestEven ) { if ( roundingMode == float_round_to_zero ) { increment = 0; @@ -970,7 +1008,7 @@ static float128 } } } - if ( 0x7FFD <= (bits32) zExp ) { + if ( 0x7FFD <= (uint32_t) zExp ) { if ( ( 0x7FFD < zExp ) || ( ( zExp == 0x7FFD ) && eq128( @@ -998,7 +1036,10 @@ static float128 return packFloat128( zSign, 0x7FFF, 0, 0 ); } if ( zExp < 0 ) { - if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 ); + if (STATUS(flush_to_zero)) { + float_raise(float_flag_output_denormal STATUS_VAR); + return packFloat128(zSign, 0, 0, 0); + } isTiny = ( STATUS(float_detect_tininess) == float_tininess_before_rounding ) || ( zExp < -1 ) @@ -1014,7 +1055,7 @@ static float128 zExp = 0; if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR); if ( roundNearestEven ) { - increment = ( (sbits64) zSig2 < 0 ); + increment = ( (int64_t) zSig2 < 0 ); } else { if ( zSign ) { @@ -1050,10 +1091,10 @@ static float128 static float128 normalizeRoundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 STATUS_PARAM) + flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 STATUS_PARAM) { int8 shiftCount; - bits64 zSig2; + uint64_t zSig2; if ( zSig0 == 0 ) { zSig0 = zSig1; @@ -1074,8 +1115,6 @@ static float128 } -#endif - /*---------------------------------------------------------------------------- | Returns the result of converting the 32-bit two's complement integer `a' | to the single-precision floating-point format. The conversion is performed @@ -1087,7 +1126,7 @@ float32 int32_to_float32( int32 a STATUS_PARAM ) flag zSign; if ( a == 0 ) return float32_zero; - if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); + if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); zSign = ( a < 0 ); return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR ); @@ -1104,7 +1143,7 @@ float64 int32_to_float64( int32 a STATUS_PARAM ) flag zSign; uint32 absA; int8 shiftCount; - bits64 zSig; + uint64_t zSig; if ( a == 0 ) return float64_zero; zSign = ( a < 0 ); @@ -1115,8 +1154,6 @@ float64 int32_to_float64( int32 a STATUS_PARAM ) } -#ifdef FLOATX80 - /*---------------------------------------------------------------------------- | Returns the result of converting the 32-bit two's complement integer `a' | to the extended double-precision floating-point format. The conversion @@ -1129,7 +1166,7 @@ floatx80 int32_to_floatx80( int32 a STATUS_PARAM ) flag zSign; uint32 absA; int8 shiftCount; - bits64 zSig; + uint64_t zSig; if ( a == 0 ) return packFloatx80( 0, 0, 0 ); zSign = ( a < 0 ); @@ -1140,10 +1177,6 @@ floatx80 int32_to_floatx80( int32 a STATUS_PARAM ) } -#endif - -#ifdef FLOAT128 - /*---------------------------------------------------------------------------- | Returns the result of converting the 32-bit two's complement integer `a' to | the quadruple-precision floating-point format. The conversion is performed @@ -1155,7 +1188,7 @@ float128 int32_to_float128( int32 a STATUS_PARAM ) flag zSign; uint32 absA; int8 shiftCount; - bits64 zSig0; + uint64_t zSig0; if ( a == 0 ) return packFloat128( 0, 0, 0, 0 ); zSign = ( a < 0 ); @@ -1166,8 +1199,6 @@ float128 int32_to_float128( int32 a STATUS_PARAM ) } -#endif - /*---------------------------------------------------------------------------- | Returns the result of converting the 64-bit two's complement integer `a' | to the single-precision floating-point format. The conversion is performed @@ -1232,7 +1263,7 @@ float64 int64_to_float64( int64 a STATUS_PARAM ) flag zSign; if ( a == 0 ) return float64_zero; - if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) { + if ( a == (int64_t) LIT64( 0x8000000000000000 ) ) { return packFloat64( 1, 0x43E, 0 ); } zSign = ( a < 0 ); @@ -1247,8 +1278,6 @@ float64 uint64_to_float64( uint64 a STATUS_PARAM ) } -#ifdef FLOATX80 - /*---------------------------------------------------------------------------- | Returns the result of converting the 64-bit two's complement integer `a' | to the extended double-precision floating-point format. The conversion @@ -1270,10 +1299,6 @@ floatx80 int64_to_floatx80( int64 a STATUS_PARAM ) } -#endif - -#ifdef FLOAT128 - /*---------------------------------------------------------------------------- | Returns the result of converting the 64-bit two's complement integer `a' to | the quadruple-precision floating-point format. The conversion is performed @@ -1286,7 +1311,7 @@ float128 int64_to_float128( int64 a STATUS_PARAM ) uint64 absA; int8 shiftCount; int32 zExp; - bits64 zSig0, zSig1; + uint64_t zSig0, zSig1; if ( a == 0 ) return packFloat128( 0, 0, 0, 0 ); zSign = ( a < 0 ); @@ -1307,8 +1332,6 @@ float128 int64_to_float128( int64 a STATUS_PARAM ) } -#endif - /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value | `a' to the 32-bit two's complement integer format. The conversion is @@ -1323,8 +1346,8 @@ int32 float32_to_int32( float32 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64; + uint32_t aSig; + uint64_t aSig64; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); @@ -1354,7 +1377,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; - bits32 aSig; + uint32_t aSig; int32 z; a = float32_squash_input_denormal(a STATUS_VAR); @@ -1367,7 +1390,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM ) float_raise( float_flag_invalid STATUS_VAR); if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; } - return (sbits32) 0x80000000; + return (int32_t) 0x80000000; } else if ( aExp <= 0x7E ) { if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact; @@ -1375,7 +1398,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM ) } aSig = ( aSig | 0x00800000 )<<8; z = aSig>>( - shiftCount ); - if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { STATUS(float_exception_flags) |= float_flag_inexact; } if ( aSign ) z = - z; @@ -1397,7 +1420,7 @@ int16 float32_to_int16_round_to_zero( float32 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; - bits32 aSig; + uint32_t aSig; int32 z; aSig = extractFloat32Frac( a ); @@ -1411,7 +1434,7 @@ int16 float32_to_int16_round_to_zero( float32 a STATUS_PARAM ) return 0x7FFF; } } - return (sbits32) 0xffff8000; + return (int32_t) 0xffff8000; } else if ( aExp <= 0x7E ) { if ( aExp | aSig ) { @@ -1422,7 +1445,7 @@ int16 float32_to_int16_round_to_zero( float32 a STATUS_PARAM ) shiftCount -= 0x10; aSig = ( aSig | 0x00800000 )<<8; z = aSig>>( - shiftCount ); - if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { STATUS(float_exception_flags) |= float_flag_inexact; } if ( aSign ) { @@ -1446,8 +1469,8 @@ int64 float32_to_int64( float32 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64, aSigExtra; + uint32_t aSig; + uint64_t aSig64, aSigExtra; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); @@ -1459,7 +1482,7 @@ int64 float32_to_int64( float32 a STATUS_PARAM ) if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { return LIT64( 0x7FFFFFFFFFFFFFFF ); } - return (sbits64) LIT64( 0x8000000000000000 ); + return (int64_t) LIT64( 0x8000000000000000 ); } if ( aExp ) aSig |= 0x00800000; aSig64 = aSig; @@ -1483,8 +1506,8 @@ int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64; + uint32_t aSig; + uint64_t aSig64; int64 z; a = float32_squash_input_denormal(a STATUS_VAR); @@ -1499,7 +1522,7 @@ int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM ) return LIT64( 0x7FFFFFFFFFFFFFFF ); } } - return (sbits64) LIT64( 0x8000000000000000 ); + return (int64_t) LIT64( 0x8000000000000000 ); } else if ( aExp <= 0x7E ) { if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact; @@ -1508,7 +1531,7 @@ int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM ) aSig64 = aSig | 0x00800000; aSig64 <<= 40; z = aSig64>>( - shiftCount ); - if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { + if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) { STATUS(float_exception_flags) |= float_flag_inexact; } if ( aSign ) z = - z; @@ -1527,14 +1550,14 @@ float64 float32_to_float64( float32 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits32 aSig; + uint32_t aSig; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); aExp = extractFloat32Exp( a ); aSign = extractFloat32Sign( a ); if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR )); + if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloat64( aSign, 0x7FF, 0 ); } if ( aExp == 0 ) { @@ -1542,12 +1565,10 @@ float64 float32_to_float64( float32 a STATUS_PARAM ) normalizeFloat32Subnormal( aSig, &aExp, &aSig ); --aExp; } - return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); + return packFloat64( aSign, aExp + 0x380, ( (uint64_t) aSig )<<29 ); } -#ifdef FLOATX80 - /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value | `a' to the extended double-precision floating-point format. The conversion @@ -1559,14 +1580,14 @@ floatx80 float32_to_floatx80( float32 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits32 aSig; + uint32_t aSig; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); aExp = extractFloat32Exp( a ); aSign = extractFloat32Sign( a ); if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) ); + if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); } if ( aExp == 0 ) { @@ -1574,14 +1595,10 @@ floatx80 float32_to_floatx80( float32 a STATUS_PARAM ) normalizeFloat32Subnormal( aSig, &aExp, &aSig ); } aSig |= 0x00800000; - return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); + return packFloatx80( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<40 ); } -#endif - -#ifdef FLOAT128 - /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value | `a' to the double-precision floating-point format. The conversion is @@ -1593,14 +1610,14 @@ float128 float32_to_float128( float32 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits32 aSig; + uint32_t aSig; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); aExp = extractFloat32Exp( a ); aSign = extractFloat32Sign( a ); if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) ); + if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloat128( aSign, 0x7FFF, 0, 0 ); } if ( aExp == 0 ) { @@ -1608,12 +1625,10 @@ float128 float32_to_float128( float32 a STATUS_PARAM ) normalizeFloat32Subnormal( aSig, &aExp, &aSig ); --aExp; } - return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); + return packFloat128( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<25, 0 ); } -#endif - /*---------------------------------------------------------------------------- | Rounds the single-precision floating-point value `a' to an integer, and | returns the result as a single-precision floating-point value. The @@ -1625,9 +1640,9 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) { flag aSign; int16 aExp; - bits32 lastBitMask, roundBitsMask; + uint32_t lastBitMask, roundBitsMask; int8 roundingMode; - bits32 z; + uint32_t z; a = float32_squash_input_denormal(a STATUS_VAR); aExp = extractFloat32Exp( a ); @@ -1638,7 +1653,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) return a; } if ( aExp <= 0x7E ) { - if ( (bits32) ( float32_val(a)<<1 ) == 0 ) return a; + if ( (uint32_t) ( float32_val(a)<<1 ) == 0 ) return a; STATUS(float_exception_flags) |= float_flag_inexact; aSign = extractFloat32Sign( a ); switch ( STATUS(float_rounding_mode) ) { @@ -1685,7 +1700,7 @@ float32 float32_round_to_int( float32 a STATUS_PARAM) static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM) { int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; + uint32_t aSig, bSig, zSig; int16 expDiff; aSig = extractFloat32Frac( a ); @@ -1729,7 +1744,12 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM) return a; } if ( aExp == 0 ) { - if ( STATUS(flush_to_zero) ) return packFloat32( zSign, 0, 0 ); + if (STATUS(flush_to_zero)) { + if (aSig | bSig) { + float_raise(float_flag_output_denormal STATUS_VAR); + } + return packFloat32(zSign, 0, 0); + } return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); } zSig = 0x40000000 + aSig + bSig; @@ -1739,7 +1759,7 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM) aSig |= 0x20000000; zSig = ( aSig + bSig )<<1; --zExp; - if ( (sbits32) zSig < 0 ) { + if ( (int32_t) zSig < 0 ) { zSig = aSig + bSig; ++zExp; } @@ -1759,7 +1779,7 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM) static float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM) { int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; + uint32_t aSig, bSig, zSig; int16 expDiff; aSig = extractFloat32Frac( a ); @@ -1879,9 +1899,9 @@ float32 float32_mul( float32 a, float32 b STATUS_PARAM ) { flag aSign, bSign, zSign; int16 aExp, bExp, zExp; - bits32 aSig, bSig; - bits64 zSig64; - bits32 zSig; + uint32_t aSig, bSig; + uint64_t zSig64; + uint32_t zSig; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -1922,9 +1942,9 @@ float32 float32_mul( float32 a, float32 b STATUS_PARAM ) zExp = aExp + bExp - 0x7F; aSig = ( aSig | 0x00800000 )<<7; bSig = ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); + shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 ); zSig = zSig64; - if ( 0 <= (sbits32) ( zSig<<1 ) ) { + if ( 0 <= (int32_t) ( zSig<<1 ) ) { zSig <<= 1; --zExp; } @@ -1942,7 +1962,7 @@ float32 float32_div( float32 a, float32 b STATUS_PARAM ) { flag aSign, bSign, zSign; int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; + uint32_t aSig, bSig, zSig; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -1988,9 +2008,9 @@ float32 float32_div( float32 a, float32 b STATUS_PARAM ) aSig >>= 1; ++zExp; } - zSig = ( ( (bits64) aSig )<<32 ) / bSig; + zSig = ( ( (uint64_t) aSig )<<32 ) / bSig; if ( ( zSig & 0x3F ) == 0 ) { - zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); + zSig |= ( (uint64_t) bSig * zSig != ( (uint64_t) aSig )<<32 ); } return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR ); @@ -2006,11 +2026,11 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM ) { flag aSign, zSign; int16 aExp, bExp, expDiff; - bits32 aSig, bSig; - bits32 q; - bits64 aSig64, bSig64, q64; - bits32 alternateASig; - sbits32 sigMean; + uint32_t aSig, bSig; + uint32_t q; + uint64_t aSig64, bSig64, q64; + uint32_t alternateASig; + int32_t sigMean; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -2054,7 +2074,7 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM ) q = ( bSig <= aSig ); if ( q ) aSig -= bSig; if ( 0 < expDiff ) { - q = ( ( (bits64) aSig )<<32 ) / bSig; + q = ( ( (uint64_t) aSig )<<32 ) / bSig; q >>= 32 - expDiff; bSig >>= 2; aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; @@ -2066,8 +2086,8 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM ) } else { if ( bSig <= aSig ) aSig -= bSig; - aSig64 = ( (bits64) aSig )<<40; - bSig64 = ( (bits64) bSig )<<40; + aSig64 = ( (uint64_t) aSig )<<40; + bSig64 = ( (uint64_t) bSig )<<40; expDiff -= 64; while ( 0 < expDiff ) { q64 = estimateDiv128To64( aSig64, 0, bSig64 ); @@ -2086,18 +2106,225 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM ) alternateASig = aSig; ++q; aSig -= bSig; - } while ( 0 <= (sbits32) aSig ); + } while ( 0 <= (int32_t) aSig ); sigMean = aSig + alternateASig; if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { aSig = alternateASig; } - zSign = ( (sbits32) aSig < 0 ); + zSign = ( (int32_t) aSig < 0 ); if ( zSign ) aSig = - aSig; return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR ); } /*---------------------------------------------------------------------------- +| Returns the result of multiplying the single-precision floating-point values +| `a' and `b' then adding 'c', with no intermediate rounding step after the +| multiplication. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic 754-2008. +| The flags argument allows the caller to select negation of the +| addend, the intermediate product, or the final result. (The difference +| between this and having the caller do a separate negation is that negating +| externally will flip the sign bit on NaNs.) +*----------------------------------------------------------------------------*/ + +float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM) +{ + flag aSign, bSign, cSign, zSign; + int aExp, bExp, cExp, pExp, zExp, expDiff; + uint32_t aSig, bSig, cSig; + flag pInf, pZero, pSign; + uint64_t pSig64, cSig64, zSig64; + uint32_t pSig; + int shiftcount; + flag signflip, infzero; + + a = float32_squash_input_denormal(a STATUS_VAR); + b = float32_squash_input_denormal(b STATUS_VAR); + c = float32_squash_input_denormal(c STATUS_VAR); + aSig = extractFloat32Frac(a); + aExp = extractFloat32Exp(a); + aSign = extractFloat32Sign(a); + bSig = extractFloat32Frac(b); + bExp = extractFloat32Exp(b); + bSign = extractFloat32Sign(b); + cSig = extractFloat32Frac(c); + cExp = extractFloat32Exp(c); + cSign = extractFloat32Sign(c); + + infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) || + (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0)); + + /* It is implementation-defined whether the cases of (0,inf,qnan) + * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN + * they return if they do), so we have to hand this information + * off to the target-specific pick-a-NaN routine. + */ + if (((aExp == 0xff) && aSig) || + ((bExp == 0xff) && bSig) || + ((cExp == 0xff) && cSig)) { + return propagateFloat32MulAddNaN(a, b, c, infzero STATUS_VAR); + } + + if (infzero) { + float_raise(float_flag_invalid STATUS_VAR); + return float32_default_nan; + } + + if (flags & float_muladd_negate_c) { + cSign ^= 1; + } + + signflip = (flags & float_muladd_negate_result) ? 1 : 0; + + /* Work out the sign and type of the product */ + pSign = aSign ^ bSign; + if (flags & float_muladd_negate_product) { + pSign ^= 1; + } + pInf = (aExp == 0xff) || (bExp == 0xff); + pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); + + if (cExp == 0xff) { + if (pInf && (pSign ^ cSign)) { + /* addition of opposite-signed infinities => InvalidOperation */ + float_raise(float_flag_invalid STATUS_VAR); + return float32_default_nan; + } + /* Otherwise generate an infinity of the same sign */ + return packFloat32(cSign ^ signflip, 0xff, 0); + } + + if (pInf) { + return packFloat32(pSign ^ signflip, 0xff, 0); + } + + if (pZero) { + if (cExp == 0) { + if (cSig == 0) { + /* Adding two exact zeroes */ + if (pSign == cSign) { + zSign = pSign; + } else if (STATUS(float_rounding_mode) == float_round_down) { + zSign = 1; + } else { + zSign = 0; + } + return packFloat32(zSign ^ signflip, 0, 0); + } + /* Exact zero plus a denorm */ + if (STATUS(flush_to_zero)) { + float_raise(float_flag_output_denormal STATUS_VAR); + return packFloat32(cSign ^ signflip, 0, 0); + } + } + /* Zero plus something non-zero : just return the something */ + return c ^ (signflip << 31); + } + + if (aExp == 0) { + normalizeFloat32Subnormal(aSig, &aExp, &aSig); + } + if (bExp == 0) { + normalizeFloat32Subnormal(bSig, &bExp, &bSig); + } + + /* Calculate the actual result a * b + c */ + + /* Multiply first; this is easy. */ + /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f + * because we want the true exponent, not the "one-less-than" + * flavour that roundAndPackFloat32() takes. + */ + pExp = aExp + bExp - 0x7e; + aSig = (aSig | 0x00800000) << 7; + bSig = (bSig | 0x00800000) << 8; + pSig64 = (uint64_t)aSig * bSig; + if ((int64_t)(pSig64 << 1) >= 0) { + pSig64 <<= 1; + pExp--; + } + + zSign = pSign ^ signflip; + + /* Now pSig64 is the significand of the multiply, with the explicit bit in + * position 62. + */ + if (cExp == 0) { + if (!cSig) { + /* Throw out the special case of c being an exact zero now */ + shift64RightJamming(pSig64, 32, &pSig64); + pSig = pSig64; + return roundAndPackFloat32(zSign, pExp - 1, + pSig STATUS_VAR); + } + normalizeFloat32Subnormal(cSig, &cExp, &cSig); + } + + cSig64 = (uint64_t)cSig << (62 - 23); + cSig64 |= LIT64(0x4000000000000000); + expDiff = pExp - cExp; + + if (pSign == cSign) { + /* Addition */ + if (expDiff > 0) { + /* scale c to match p */ + shift64RightJamming(cSig64, expDiff, &cSig64); + zExp = pExp; + } else if (expDiff < 0) { + /* scale p to match c */ + shift64RightJamming(pSig64, -expDiff, &pSig64); + zExp = cExp; + } else { + /* no scaling needed */ + zExp = cExp; + } + /* Add significands and make sure explicit bit ends up in posn 62 */ + zSig64 = pSig64 + cSig64; + if ((int64_t)zSig64 < 0) { + shift64RightJamming(zSig64, 1, &zSig64); + } else { + zExp--; + } + } else { + /* Subtraction */ + if (expDiff > 0) { + shift64RightJamming(cSig64, expDiff, &cSig64); + zSig64 = pSig64 - cSig64; + zExp = pExp; + } else if (expDiff < 0) { + shift64RightJamming(pSig64, -expDiff, &pSig64); + zSig64 = cSig64 - pSig64; + zExp = cExp; + zSign ^= 1; + } else { + zExp = pExp; + if (cSig64 < pSig64) { + zSig64 = pSig64 - cSig64; + } else if (pSig64 < cSig64) { + zSig64 = cSig64 - pSig64; + zSign ^= 1; + } else { + /* Exact zero */ + zSign = signflip; + if (STATUS(float_rounding_mode) == float_round_down) { + zSign ^= 1; + } + return packFloat32(zSign, 0, 0); + } + } + --zExp; + /* Normalize to put the explicit bit back into bit 62. */ + shiftcount = countLeadingZeros64(zSig64) - 1; + zSig64 <<= shiftcount; + zExp -= shiftcount; + } + shift64RightJamming(zSig64, 32, &zSig64); + return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR); +} + + +/*---------------------------------------------------------------------------- | Returns the square root of the single-precision floating-point value `a'. | The operation is performed according to the IEC/IEEE Standard for Binary | Floating-Point Arithmetic. @@ -2107,8 +2334,8 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) { flag aSign; int16 aExp, zExp; - bits32 aSig, zSig; - bits64 rem, term; + uint32_t aSig, zSig; + uint64_t rem, term; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); @@ -2138,11 +2365,11 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) goto roundAndPack; } aSig >>= aExp & 1; - term = ( (bits64) zSig ) * zSig; - rem = ( ( (bits64) aSig )<<32 ) - term; - while ( (sbits64) rem < 0 ) { + term = ( (uint64_t) zSig ) * zSig; + rem = ( ( (uint64_t) aSig )<<32 ) - term; + while ( (int64_t) rem < 0 ) { --zSig; - rem += ( ( (bits64) zSig )<<1 ) | 1; + rem += ( ( (uint64_t) zSig )<<1 ) | 1; } zSig |= ( rem != 0 ); } @@ -2172,28 +2399,28 @@ float32 float32_sqrt( float32 a STATUS_PARAM ) static const float64 float32_exp2_coefficients[15] = { - make_float64( 0x3ff0000000000000ll ), /* 1 */ - make_float64( 0x3fe0000000000000ll ), /* 2 */ - make_float64( 0x3fc5555555555555ll ), /* 3 */ - make_float64( 0x3fa5555555555555ll ), /* 4 */ - make_float64( 0x3f81111111111111ll ), /* 5 */ - make_float64( 0x3f56c16c16c16c17ll ), /* 6 */ - make_float64( 0x3f2a01a01a01a01all ), /* 7 */ - make_float64( 0x3efa01a01a01a01all ), /* 8 */ - make_float64( 0x3ec71de3a556c734ll ), /* 9 */ - make_float64( 0x3e927e4fb7789f5cll ), /* 10 */ - make_float64( 0x3e5ae64567f544e4ll ), /* 11 */ - make_float64( 0x3e21eed8eff8d898ll ), /* 12 */ - make_float64( 0x3de6124613a86d09ll ), /* 13 */ - make_float64( 0x3da93974a8c07c9dll ), /* 14 */ - make_float64( 0x3d6ae7f3e733b81fll ), /* 15 */ + const_float64( 0x3ff0000000000000ll ), /* 1 */ + const_float64( 0x3fe0000000000000ll ), /* 2 */ + const_float64( 0x3fc5555555555555ll ), /* 3 */ + const_float64( 0x3fa5555555555555ll ), /* 4 */ + const_float64( 0x3f81111111111111ll ), /* 5 */ + const_float64( 0x3f56c16c16c16c17ll ), /* 6 */ + const_float64( 0x3f2a01a01a01a01all ), /* 7 */ + const_float64( 0x3efa01a01a01a01all ), /* 8 */ + const_float64( 0x3ec71de3a556c734ll ), /* 9 */ + const_float64( 0x3e927e4fb7789f5cll ), /* 10 */ + const_float64( 0x3e5ae64567f544e4ll ), /* 11 */ + const_float64( 0x3e21eed8eff8d898ll ), /* 12 */ + const_float64( 0x3de6124613a86d09ll ), /* 13 */ + const_float64( 0x3da93974a8c07c9dll ), /* 14 */ + const_float64( 0x3d6ae7f3e733b81fll ), /* 15 */ }; float32 float32_exp2( float32 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits32 aSig; + uint32_t aSig; float64 r, x, xn; int i; a = float32_squash_input_denormal(a STATUS_VAR); @@ -2241,7 +2468,7 @@ float32 float32_log2( float32 a STATUS_PARAM ) { flag aSign, zSign; int16 aExp; - bits32 aSig, zSig, i; + uint32_t aSig, zSig, i; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); @@ -2267,7 +2494,7 @@ float32 float32_log2( float32 a STATUS_PARAM ) zSig = aExp << 23; for (i = 1 << 22; i > 0; i >>= 1) { - aSig = ( (bits64)aSig * aSig ) >> 23; + aSig = ( (uint64_t)aSig * aSig ) >> 23; if ( aSig & 0x01000000 ) { aSig >>= 1; zSig |= i; @@ -2282,39 +2509,39 @@ float32 float32_log2( float32 a STATUS_PARAM ) /*---------------------------------------------------------------------------- | Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float32_eq( float32 a, float32 b STATUS_PARAM ) { + uint32_t av, bv; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid STATUS_VAR); - } + float_raise( float_flag_invalid STATUS_VAR); return 0; } - return ( float32_val(a) == float32_val(b) ) || - ( (bits32) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 ); - + av = float32_val(a); + bv = float32_val(b); + return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 ); } /*---------------------------------------------------------------------------- | Returns 1 if the single-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. +| or equal to the corresponding value `b', and 0 otherwise. The invalid +| exception is raised if either operand is a NaN. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float32_le( float32 a, float32 b STATUS_PARAM ) { flag aSign, bSign; - bits32 av, bv; + uint32_t av, bv; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -2328,21 +2555,22 @@ int float32_le( float32 a, float32 b STATUS_PARAM ) bSign = extractFloat32Sign( b ); av = float32_val(a); bv = float32_val(b); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 ); + if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 ); return ( av == bv ) || ( aSign ^ ( av < bv ) ); } /*---------------------------------------------------------------------------- | Returns 1 if the single-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. The comparison is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float32_lt( float32 a, float32 b STATUS_PARAM ) { flag aSign, bSign; - bits32 av, bv; + uint32_t av, bv; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -2356,21 +2584,20 @@ int float32_lt( float32 a, float32 b STATUS_PARAM ) bSign = extractFloat32Sign( b ); av = float32_val(a); bv = float32_val(b); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 ); + if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 ); return ( av != bv ) && ( aSign ^ ( av < bv ) ); } /*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| Returns 1 if the single-precision floating-point values `a' and `b' cannot +| be compared, and 0 otherwise. The invalid exception is raised if either +| operand is a NaN. The comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) +int float32_unordered( float32 a, float32 b STATUS_PARAM ) { - bits32 av, bv; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -2378,12 +2605,33 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ) { float_raise( float_flag_invalid STATUS_VAR); - return 0; + return 1; } - av = float32_val(a); - bv = float32_val(b); - return ( av == bv ) || ( (bits32) ( ( av | bv )<<1 ) == 0 ); + return 0; +} +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. The comparison is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +int float32_eq_quiet( float32 a, float32 b STATUS_PARAM ) +{ + a = float32_squash_input_denormal(a STATUS_VAR); + b = float32_squash_input_denormal(b STATUS_VAR); + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } + return 0; + } + return ( float32_val(a) == float32_val(b) ) || + ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 ); } /*---------------------------------------------------------------------------- @@ -2396,7 +2644,7 @@ int float32_eq_signaling( float32 a, float32 b STATUS_PARAM ) int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) { flag aSign, bSign; - bits32 av, bv; + uint32_t av, bv; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -2412,7 +2660,7 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) bSign = extractFloat32Sign( b ); av = float32_val(a); bv = float32_val(b); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 ); + if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 ); return ( av == bv ) || ( aSign ^ ( av < bv ) ); } @@ -2427,7 +2675,7 @@ int float32_le_quiet( float32 a, float32 b STATUS_PARAM ) int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) { flag aSign, bSign; - bits32 av, bv; + uint32_t av, bv; a = float32_squash_input_denormal(a STATUS_VAR); b = float32_squash_input_denormal(b STATUS_VAR); @@ -2443,12 +2691,35 @@ int float32_lt_quiet( float32 a, float32 b STATUS_PARAM ) bSign = extractFloat32Sign( b ); av = float32_val(a); bv = float32_val(b); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 ); + if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 ); return ( av != bv ) && ( aSign ^ ( av < bv ) ); } /*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point values `a' and `b' cannot +| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM ) +{ + a = float32_squash_input_denormal(a STATUS_VAR); + b = float32_squash_input_denormal(b STATUS_VAR); + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } + return 1; + } + return 0; +} + +/*---------------------------------------------------------------------------- | Returns the result of converting the double-precision floating-point value | `a' to the 32-bit two's complement integer format. The conversion is | performed according to the IEC/IEEE Standard for Binary Floating-Point @@ -2462,7 +2733,7 @@ int32 float64_to_int32( float64 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; - bits64 aSig; + uint64_t aSig; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); @@ -2490,7 +2761,7 @@ int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; - bits64 aSig, savedASig; + uint64_t aSig, savedASig; int32 z; a = float64_squash_input_denormal(a STATUS_VAR); @@ -2514,7 +2785,7 @@ int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM ) if ( ( z < 0 ) ^ aSign ) { invalid: float_raise( float_flag_invalid STATUS_VAR); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; } if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) { STATUS(float_exception_flags) |= float_flag_inexact; } } @@ -2681,15 +2952,15 @@ float32 float64_to_float32( float64 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits64 aSig; - bits32 zSig; + uint64_t aSig; + uint32_t zSig; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) ); + if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloat32( aSign, 0xFF, 0 ); } shift64RightJamming( aSig, 22, &aSig ); @@ -2713,29 +2984,28 @@ float32 float64_to_float32( float64 a STATUS_PARAM ) | than the desired result exponent whenever `zSig' is a complete, normalized | significand. *----------------------------------------------------------------------------*/ -static bits16 packFloat16(flag zSign, int16 zExp, bits16 zSig) +static float16 packFloat16(flag zSign, int16 zExp, uint16_t zSig) { - return (((bits32)zSign) << 15) + (((bits32)zExp) << 10) + zSig; + return make_float16( + (((uint32_t)zSign) << 15) + (((uint32_t)zExp) << 10) + zSig); } /* Half precision floats come in two formats: standard IEEE and "ARM" format. The latter gains extra exponent range by omitting the NaN/Inf encodings. */ - -float32 float16_to_float32( bits16 a, flag ieee STATUS_PARAM ) + +float32 float16_to_float32(float16 a, flag ieee STATUS_PARAM) { flag aSign; int16 aExp; - bits32 aSig; + uint32_t aSig; - aSign = a >> 15; - aExp = (a >> 10) & 0x1f; - aSig = a & 0x3ff; + aSign = extractFloat16Sign(a); + aExp = extractFloat16Exp(a); + aSig = extractFloat16Frac(a); if (aExp == 0x1f && ieee) { if (aSig) { - /* Make sure correct exceptions are raised. */ - float32ToCommonNaN(a STATUS_VAR); - aSig |= 0x200; + return commonNaNToFloat32(float16ToCommonNaN(a STATUS_VAR) STATUS_VAR); } return packFloat32(aSign, 0xff, aSig << 13); } @@ -2753,13 +3023,13 @@ float32 float16_to_float32( bits16 a, flag ieee STATUS_PARAM ) return packFloat32( aSign, aExp + 0x70, aSig << 13); } -bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM) +float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM) { flag aSign; int16 aExp; - bits32 aSig; - bits32 mask; - bits32 increment; + uint32_t aSig; + uint32_t mask; + uint32_t increment; int8 roundingMode; a = float32_squash_input_denormal(a STATUS_VAR); @@ -2768,24 +3038,30 @@ bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM) aSign = extractFloat32Sign( a ); if ( aExp == 0xFF ) { if (aSig) { - /* Make sure correct exceptions are raised. */ - float32ToCommonNaN(a STATUS_VAR); - aSig |= 0x00400000; + /* Input is a NaN */ + float16 r = commonNaNToFloat16( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); + if (!ieee) { + return packFloat16(aSign, 0, 0); + } + return r; + } + /* Infinity */ + if (!ieee) { + float_raise(float_flag_invalid STATUS_VAR); + return packFloat16(aSign, 0x1f, 0x3ff); } - return packFloat16(aSign, 0x1f, aSig >> 13); + return packFloat16(aSign, 0x1f, 0); } - if (aExp == 0 && aSign == 0) { + if (aExp == 0 && aSig == 0) { return packFloat16(aSign, 0, 0); } /* Decimal point between bits 22 and 23. */ aSig |= 0x00800000; aExp -= 0x7f; if (aExp < -14) { - mask = 0x007fffff; - if (aExp < -24) { - aExp = -25; - } else { - mask >>= 24 + aExp; + mask = 0x00ffffff; + if (aExp >= -24) { + mask >>= 25 + aExp; } } else { mask = 0x00001fff; @@ -2827,7 +3103,7 @@ bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM) } } else { if (aExp > 16) { - float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR); + float_raise(float_flag_invalid | float_flag_inexact STATUS_VAR); return packFloat16(aSign, 0x1f, 0x3ff); } } @@ -2841,8 +3117,6 @@ bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM) return packFloat16(aSign, aExp + 14, aSig >> 13); } -#ifdef FLOATX80 - /*---------------------------------------------------------------------------- | Returns the result of converting the double-precision floating-point value | `a' to the extended double-precision floating-point format. The conversion @@ -2854,14 +3128,14 @@ floatx80 float64_to_floatx80( float64 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits64 aSig; + uint64_t aSig; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) ); + if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); } if ( aExp == 0 ) { @@ -2874,10 +3148,6 @@ floatx80 float64_to_floatx80( float64 a STATUS_PARAM ) } -#endif - -#ifdef FLOAT128 - /*---------------------------------------------------------------------------- | Returns the result of converting the double-precision floating-point value | `a' to the quadruple-precision floating-point format. The conversion is @@ -2889,14 +3159,14 @@ float128 float64_to_float128( float64 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits64 aSig, zSig0, zSig1; + uint64_t aSig, zSig0, zSig1; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) ); + if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloat128( aSign, 0x7FFF, 0, 0 ); } if ( aExp == 0 ) { @@ -2909,8 +3179,6 @@ float128 float64_to_float128( float64 a STATUS_PARAM ) } -#endif - /*---------------------------------------------------------------------------- | Rounds the double-precision floating-point value `a' to an integer, and | returns the result as a double-precision floating-point value. The @@ -2922,9 +3190,9 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits64 lastBitMask, roundBitsMask; + uint64_t lastBitMask, roundBitsMask; int8 roundingMode; - bits64 z; + uint64_t z; a = float64_squash_input_denormal(a STATUS_VAR); aExp = extractFloat64Exp( a ); @@ -2935,7 +3203,7 @@ float64 float64_round_to_int( float64 a STATUS_PARAM ) return a; } if ( aExp < 0x3FF ) { - if ( (bits64) ( float64_val(a)<<1 ) == 0 ) return a; + if ( (uint64_t) ( float64_val(a)<<1 ) == 0 ) return a; STATUS(float_exception_flags) |= float_flag_inexact; aSign = extractFloat64Sign( a ); switch ( STATUS(float_rounding_mode) ) { @@ -2995,7 +3263,7 @@ float64 float64_trunc_to_int( float64 a STATUS_PARAM) static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM ) { int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; + uint64_t aSig, bSig, zSig; int16 expDiff; aSig = extractFloat64Frac( a ); @@ -3039,7 +3307,12 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM ) return a; } if ( aExp == 0 ) { - if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 ); + if (STATUS(flush_to_zero)) { + if (aSig | bSig) { + float_raise(float_flag_output_denormal STATUS_VAR); + } + return packFloat64(zSign, 0, 0); + } return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); } zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; @@ -3049,7 +3322,7 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM ) aSig |= LIT64( 0x2000000000000000 ); zSig = ( aSig + bSig )<<1; --zExp; - if ( (sbits64) zSig < 0 ) { + if ( (int64_t) zSig < 0 ) { zSig = aSig + bSig; ++zExp; } @@ -3069,7 +3342,7 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM ) static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM ) { int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; + uint64_t aSig, bSig, zSig; int16 expDiff; aSig = extractFloat64Frac( a ); @@ -3189,7 +3462,7 @@ float64 float64_mul( float64 a, float64 b STATUS_PARAM ) { flag aSign, bSign, zSign; int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; + uint64_t aSig, bSig, zSig0, zSig1; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3232,7 +3505,7 @@ float64 float64_mul( float64 a, float64 b STATUS_PARAM ) bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; mul64To128( aSig, bSig, &zSig0, &zSig1 ); zSig0 |= ( zSig1 != 0 ); - if ( 0 <= (sbits64) ( zSig0<<1 ) ) { + if ( 0 <= (int64_t) ( zSig0<<1 ) ) { zSig0 <<= 1; --zExp; } @@ -3250,9 +3523,9 @@ float64 float64_div( float64 a, float64 b STATUS_PARAM ) { flag aSign, bSign, zSign; int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - bits64 rem0, rem1; - bits64 term0, term1; + uint64_t aSig, bSig, zSig; + uint64_t rem0, rem1; + uint64_t term0, term1; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3302,7 +3575,7 @@ float64 float64_div( float64 a, float64 b STATUS_PARAM ) if ( ( zSig & 0x1FF ) <= 2 ) { mul64To128( bSig, zSig, &term0, &term1 ); sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { + while ( (int64_t) rem0 < 0 ) { --zSig; add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); } @@ -3322,9 +3595,9 @@ float64 float64_rem( float64 a, float64 b STATUS_PARAM ) { flag aSign, zSign; int16 aExp, bExp, expDiff; - bits64 aSig, bSig; - bits64 q, alternateASig; - sbits64 sigMean; + uint64_t aSig, bSig; + uint64_t q, alternateASig; + int64_t sigMean; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3387,18 +3660,238 @@ float64 float64_rem( float64 a, float64 b STATUS_PARAM ) alternateASig = aSig; ++q; aSig -= bSig; - } while ( 0 <= (sbits64) aSig ); + } while ( 0 <= (int64_t) aSig ); sigMean = aSig + alternateASig; if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { aSig = alternateASig; } - zSign = ( (sbits64) aSig < 0 ); + zSign = ( (int64_t) aSig < 0 ); if ( zSign ) aSig = - aSig; return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR ); } /*---------------------------------------------------------------------------- +| Returns the result of multiplying the double-precision floating-point values +| `a' and `b' then adding 'c', with no intermediate rounding step after the +| multiplication. The operation is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic 754-2008. +| The flags argument allows the caller to select negation of the +| addend, the intermediate product, or the final result. (The difference +| between this and having the caller do a separate negation is that negating +| externally will flip the sign bit on NaNs.) +*----------------------------------------------------------------------------*/ + +float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM) +{ + flag aSign, bSign, cSign, zSign; + int aExp, bExp, cExp, pExp, zExp, expDiff; + uint64_t aSig, bSig, cSig; + flag pInf, pZero, pSign; + uint64_t pSig0, pSig1, cSig0, cSig1, zSig0, zSig1; + int shiftcount; + flag signflip, infzero; + + a = float64_squash_input_denormal(a STATUS_VAR); + b = float64_squash_input_denormal(b STATUS_VAR); + c = float64_squash_input_denormal(c STATUS_VAR); + aSig = extractFloat64Frac(a); + aExp = extractFloat64Exp(a); + aSign = extractFloat64Sign(a); + bSig = extractFloat64Frac(b); + bExp = extractFloat64Exp(b); + bSign = extractFloat64Sign(b); + cSig = extractFloat64Frac(c); + cExp = extractFloat64Exp(c); + cSign = extractFloat64Sign(c); + + infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) || + (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 0)); + + /* It is implementation-defined whether the cases of (0,inf,qnan) + * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN + * they return if they do), so we have to hand this information + * off to the target-specific pick-a-NaN routine. + */ + if (((aExp == 0x7ff) && aSig) || + ((bExp == 0x7ff) && bSig) || + ((cExp == 0x7ff) && cSig)) { + return propagateFloat64MulAddNaN(a, b, c, infzero STATUS_VAR); + } + + if (infzero) { + float_raise(float_flag_invalid STATUS_VAR); + return float64_default_nan; + } + + if (flags & float_muladd_negate_c) { + cSign ^= 1; + } + + signflip = (flags & float_muladd_negate_result) ? 1 : 0; + + /* Work out the sign and type of the product */ + pSign = aSign ^ bSign; + if (flags & float_muladd_negate_product) { + pSign ^= 1; + } + pInf = (aExp == 0x7ff) || (bExp == 0x7ff); + pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0); + + if (cExp == 0x7ff) { + if (pInf && (pSign ^ cSign)) { + /* addition of opposite-signed infinities => InvalidOperation */ + float_raise(float_flag_invalid STATUS_VAR); + return float64_default_nan; + } + /* Otherwise generate an infinity of the same sign */ + return packFloat64(cSign ^ signflip, 0x7ff, 0); + } + + if (pInf) { + return packFloat64(pSign ^ signflip, 0x7ff, 0); + } + + if (pZero) { + if (cExp == 0) { + if (cSig == 0) { + /* Adding two exact zeroes */ + if (pSign == cSign) { + zSign = pSign; + } else if (STATUS(float_rounding_mode) == float_round_down) { + zSign = 1; + } else { + zSign = 0; + } + return packFloat64(zSign ^ signflip, 0, 0); + } + /* Exact zero plus a denorm */ + if (STATUS(flush_to_zero)) { + float_raise(float_flag_output_denormal STATUS_VAR); + return packFloat64(cSign ^ signflip, 0, 0); + } + } + /* Zero plus something non-zero : just return the something */ + return c ^ ((uint64_t)signflip << 63); + } + + if (aExp == 0) { + normalizeFloat64Subnormal(aSig, &aExp, &aSig); + } + if (bExp == 0) { + normalizeFloat64Subnormal(bSig, &bExp, &bSig); + } + + /* Calculate the actual result a * b + c */ + + /* Multiply first; this is easy. */ + /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff + * because we want the true exponent, not the "one-less-than" + * flavour that roundAndPackFloat64() takes. + */ + pExp = aExp + bExp - 0x3fe; + aSig = (aSig | LIT64(0x0010000000000000))<<10; + bSig = (bSig | LIT64(0x0010000000000000))<<11; + mul64To128(aSig, bSig, &pSig0, &pSig1); + if ((int64_t)(pSig0 << 1) >= 0) { + shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1); + pExp--; + } + + zSign = pSign ^ signflip; + + /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit + * bit in position 126. + */ + if (cExp == 0) { + if (!cSig) { + /* Throw out the special case of c being an exact zero now */ + shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1); + return roundAndPackFloat64(zSign, pExp - 1, + pSig1 STATUS_VAR); + } + normalizeFloat64Subnormal(cSig, &cExp, &cSig); + } + + /* Shift cSig and add the explicit bit so [cSig0:cSig1] is the + * significand of the addend, with the explicit bit in position 126. + */ + cSig0 = cSig << (126 - 64 - 52); + cSig1 = 0; + cSig0 |= LIT64(0x4000000000000000); + expDiff = pExp - cExp; + + if (pSign == cSign) { + /* Addition */ + if (expDiff > 0) { + /* scale c to match p */ + shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); + zExp = pExp; + } else if (expDiff < 0) { + /* scale p to match c */ + shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); + zExp = cExp; + } else { + /* no scaling needed */ + zExp = cExp; + } + /* Add significands and make sure explicit bit ends up in posn 126 */ + add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); + if ((int64_t)zSig0 < 0) { + shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1); + } else { + zExp--; + } + shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1); + return roundAndPackFloat64(zSign, zExp, zSig1 STATUS_VAR); + } else { + /* Subtraction */ + if (expDiff > 0) { + shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1); + sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); + zExp = pExp; + } else if (expDiff < 0) { + shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1); + sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); + zExp = cExp; + zSign ^= 1; + } else { + zExp = pExp; + if (lt128(cSig0, cSig1, pSig0, pSig1)) { + sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1); + } else if (lt128(pSig0, pSig1, cSig0, cSig1)) { + sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1); + zSign ^= 1; + } else { + /* Exact zero */ + zSign = signflip; + if (STATUS(float_rounding_mode) == float_round_down) { + zSign ^= 1; + } + return packFloat64(zSign, 0, 0); + } + } + --zExp; + /* Do the equivalent of normalizeRoundAndPackFloat64() but + * starting with the significand in a pair of uint64_t. + */ + if (zSig0) { + shiftcount = countLeadingZeros64(zSig0) - 1; + shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1); + if (zSig1) { + zSig0 |= 1; + } + zExp -= shiftcount; + } else { + shiftcount = countLeadingZeros64(zSig1) - 1; + zSig0 = zSig1 << shiftcount; + zExp -= (shiftcount + 64); + } + return roundAndPackFloat64(zSign, zExp, zSig0 STATUS_VAR); + } +} + +/*---------------------------------------------------------------------------- | Returns the square root of the double-precision floating-point value `a'. | The operation is performed according to the IEC/IEEE Standard for Binary | Floating-Point Arithmetic. @@ -3408,8 +3901,8 @@ float64 float64_sqrt( float64 a STATUS_PARAM ) { flag aSign; int16 aExp, zExp; - bits64 aSig, zSig, doubleZSig; - bits64 rem0, rem1, term0, term1; + uint64_t aSig, zSig, doubleZSig; + uint64_t rem0, rem1, term0, term1; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); @@ -3439,7 +3932,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM ) doubleZSig = zSig<<1; mul64To128( zSig, zSig, &term0, &term1 ); sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { + while ( (int64_t) rem0 < 0 ) { --zSig; doubleZSig -= 2; add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); @@ -3459,7 +3952,7 @@ float64 float64_log2( float64 a STATUS_PARAM ) { flag aSign, zSign; int16 aExp; - bits64 aSig, aSig0, aSig1, zSig, i; + uint64_t aSig, aSig0, aSig1, zSig, i; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); @@ -3482,7 +3975,7 @@ float64 float64_log2( float64 a STATUS_PARAM ) aExp -= 0x3FF; aSig |= LIT64( 0x0010000000000000 ); zSign = aExp < 0; - zSig = (bits64)aExp << 52; + zSig = (uint64_t)aExp << 52; for (i = 1LL << 51; i > 0; i >>= 1) { mul64To128( aSig, aSig, &aSig0, &aSig1 ); aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 ); @@ -3499,41 +3992,40 @@ float64 float64_log2( float64 a STATUS_PARAM ) /*---------------------------------------------------------------------------- | Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The comparison is performed +| corresponding value `b', and 0 otherwise. The invalid exception is raised +| if either operand is a NaN. Otherwise, the comparison is performed | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float64_eq( float64 a, float64 b STATUS_PARAM ) { - bits64 av, bv; + uint64_t av, bv; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid STATUS_VAR); - } + float_raise( float_flag_invalid STATUS_VAR); return 0; } av = float64_val(a); bv = float64_val(b); - return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 ); + return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 ); } /*---------------------------------------------------------------------------- | Returns 1 if the double-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. +| equal to the corresponding value `b', and 0 otherwise. The invalid +| exception is raised if either operand is a NaN. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float64_le( float64 a, float64 b STATUS_PARAM ) { flag aSign, bSign; - bits64 av, bv; + uint64_t av, bv; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3547,21 +4039,22 @@ int float64_le( float64 a, float64 b STATUS_PARAM ) bSign = extractFloat64Sign( b ); av = float64_val(a); bv = float64_val(b); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 ); + if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 ); return ( av == bv ) || ( aSign ^ ( av < bv ) ); } /*---------------------------------------------------------------------------- | Returns 1 if the double-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. The comparison is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float64_lt( float64 a, float64 b STATUS_PARAM ) { flag aSign, bSign; - bits64 av, bv; + uint64_t av, bv; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3575,21 +4068,20 @@ int float64_lt( float64 a, float64 b STATUS_PARAM ) bSign = extractFloat64Sign( b ); av = float64_val(a); bv = float64_val(b); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 ); + if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 ); return ( av != bv ) && ( aSign ^ ( av < bv ) ); } /*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The invalid exception is raised -| if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| Returns 1 if the double-precision floating-point values `a' and `b' cannot +| be compared, and 0 otherwise. The invalid exception is raised if either +| operand is a NaN. The comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) +int float64_unordered( float64 a, float64 b STATUS_PARAM ) { - bits64 av, bv; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3597,11 +4089,35 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) ) { float_raise( float_flag_invalid STATUS_VAR); + return 1; + } + return 0; +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is equal to the +| corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception.The comparison is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +int float64_eq_quiet( float64 a, float64 b STATUS_PARAM ) +{ + uint64_t av, bv; + a = float64_squash_input_denormal(a STATUS_VAR); + b = float64_squash_input_denormal(b STATUS_VAR); + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } return 0; } av = float64_val(a); bv = float64_val(b); - return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 ); + return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 ); } @@ -3615,7 +4131,7 @@ int float64_eq_signaling( float64 a, float64 b STATUS_PARAM ) int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) { flag aSign, bSign; - bits64 av, bv; + uint64_t av, bv; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3631,7 +4147,7 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) bSign = extractFloat64Sign( b ); av = float64_val(a); bv = float64_val(b); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 ); + if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 ); return ( av == bv ) || ( aSign ^ ( av < bv ) ); } @@ -3646,7 +4162,7 @@ int float64_le_quiet( float64 a, float64 b STATUS_PARAM ) int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) { flag aSign, bSign; - bits64 av, bv; + uint64_t av, bv; a = float64_squash_input_denormal(a STATUS_VAR); b = float64_squash_input_denormal(b STATUS_VAR); @@ -3662,12 +4178,33 @@ int float64_lt_quiet( float64 a, float64 b STATUS_PARAM ) bSign = extractFloat64Sign( b ); av = float64_val(a); bv = float64_val(b); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 ); + if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 ); return ( av != bv ) && ( aSign ^ ( av < bv ) ); } -#ifdef FLOATX80 +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point values `a' and `b' cannot +| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM ) +{ + a = float64_squash_input_denormal(a STATUS_VAR); + b = float64_squash_input_denormal(b STATUS_VAR); + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } + return 1; + } + return 0; +} /*---------------------------------------------------------------------------- | Returns the result of converting the extended double-precision floating- @@ -3683,12 +4220,12 @@ int32 floatx80_to_int32( floatx80 a STATUS_PARAM ) { flag aSign; int32 aExp, shiftCount; - bits64 aSig; + uint64_t aSig; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0; shiftCount = 0x4037 - aExp; if ( shiftCount <= 0 ) shiftCount = 1; shift64RightJamming( aSig, shiftCount, &aSig ); @@ -3710,14 +4247,14 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM ) { flag aSign; int32 aExp, shiftCount; - bits64 aSig, savedASig; + uint64_t aSig, savedASig; int32 z; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0; goto invalid; } else if ( aExp < 0x3FFF ) { @@ -3732,7 +4269,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM ) if ( ( z < 0 ) ^ aSign ) { invalid: float_raise( float_flag_invalid STATUS_VAR); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; } if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) { STATUS(float_exception_flags) |= float_flag_inexact; } if ( aSign ) z = - z; @@ -3836,14 +4373,14 @@ float32 floatx80_to_float32( floatx80 a STATUS_PARAM ) { flag aSign; int32 aExp; - bits64 aSig; + uint64_t aSig; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) ); + if ( (uint64_t) ( aSig<<1 ) ) { + return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat32( aSign, 0xFF, 0 ); } @@ -3864,14 +4401,14 @@ float64 floatx80_to_float64( floatx80 a STATUS_PARAM ) { flag aSign; int32 aExp; - bits64 aSig, zSig; + uint64_t aSig, zSig; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) ); + if ( (uint64_t) ( aSig<<1 ) ) { + return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat64( aSign, 0x7FF, 0 ); } @@ -3881,8 +4418,6 @@ float64 floatx80_to_float64( floatx80 a STATUS_PARAM ) } -#ifdef FLOAT128 - /*---------------------------------------------------------------------------- | Returns the result of converting the extended double-precision floating- | point value `a' to the quadruple-precision floating-point format. The @@ -3894,21 +4429,19 @@ float128 floatx80_to_float128( floatx80 a STATUS_PARAM ) { flag aSign; int16 aExp; - bits64 aSig, zSig0, zSig1; + uint64_t aSig, zSig0, zSig1; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) ); + if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) { + return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); return packFloat128( aSign, aExp, zSig0, zSig1 ); } -#endif - /*---------------------------------------------------------------------------- | Rounds the extended double-precision floating-point value `a' to an integer, | and returns the result as an extended quadruple-precision floating-point @@ -3920,27 +4453,27 @@ floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM ) { flag aSign; int32 aExp; - bits64 lastBitMask, roundBitsMask; + uint64_t lastBitMask, roundBitsMask; int8 roundingMode; floatx80 z; aExp = extractFloatx80Exp( a ); if ( 0x403E <= aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { + if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) { return propagateFloatx80NaN( a, a STATUS_VAR ); } return a; } if ( aExp < 0x3FFF ) { if ( ( aExp == 0 ) - && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { + && ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { return a; } STATUS(float_exception_flags) |= float_flag_inexact; aSign = extractFloatx80Sign( a ); switch ( STATUS(float_rounding_mode) ) { case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) + if ( ( aExp == 0x3FFE ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) { return packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); @@ -3993,7 +4526,7 @@ floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM ) static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM) { int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; + uint64_t aSig, bSig, zSig0, zSig1; int32 expDiff; aSig = extractFloatx80Frac( a ); @@ -4003,7 +4536,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM expDiff = aExp - bExp; if ( 0 < expDiff ) { if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); return a; } if ( bExp == 0 ) --expDiff; @@ -4012,7 +4545,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM } else if ( expDiff < 0 ) { if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); } if ( aExp == 0 ) ++expDiff; @@ -4021,7 +4554,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM } else { if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) { return propagateFloatx80NaN( a, b STATUS_VAR ); } return a; @@ -4036,7 +4569,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM goto shiftRight1; } zSig0 = aSig + bSig; - if ( (sbits64) zSig0 < 0 ) goto roundAndPack; + if ( (int64_t) zSig0 < 0 ) goto roundAndPack; shiftRight1: shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); zSig0 |= LIT64( 0x8000000000000000 ); @@ -4059,7 +4592,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM ) { int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; + uint64_t aSig, bSig, zSig0, zSig1; int32 expDiff; floatx80 z; @@ -4071,7 +4604,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM if ( 0 < expDiff ) goto aExpBigger; if ( expDiff < 0 ) goto bExpBigger; if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) { return propagateFloatx80NaN( a, b STATUS_VAR ); } float_raise( float_flag_invalid STATUS_VAR); @@ -4089,7 +4622,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 ); bExpBigger: if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); } if ( aExp == 0 ) ++expDiff; @@ -4101,7 +4634,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM goto normalizeRoundAndPack; aExpBigger: if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); return a; } if ( bExp == 0 ) --expDiff; @@ -4168,7 +4701,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM ) { flag aSign, bSign, zSign; int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; + uint64_t aSig, bSig, zSig0, zSig1; floatx80 z; aSig = extractFloatx80Frac( a ); @@ -4179,15 +4712,15 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM ) bSign = extractFloatx80Sign( b ); zSign = aSign ^ bSign; if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + if ( (uint64_t) ( aSig<<1 ) + || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) { return propagateFloatx80NaN( a, b STATUS_VAR ); } if ( ( bExp | bSig ) == 0 ) goto invalid; return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); } if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); if ( ( aExp | aSig ) == 0 ) { invalid: float_raise( float_flag_invalid STATUS_VAR); @@ -4207,7 +4740,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM ) } zExp = aExp + bExp - 0x3FFE; mul64To128( aSig, bSig, &zSig0, &zSig1 ); - if ( 0 < (sbits64) zSig0 ) { + if ( 0 < (int64_t) zSig0 ) { shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); --zExp; } @@ -4227,8 +4760,8 @@ floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM ) { flag aSign, bSign, zSign; int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - bits64 rem0, rem1, rem2, term0, term1, term2; + uint64_t aSig, bSig, zSig0, zSig1; + uint64_t rem0, rem1, rem2, term0, term1, term2; floatx80 z; aSig = extractFloatx80Frac( a ); @@ -4239,15 +4772,15 @@ floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM ) bSign = extractFloatx80Sign( b ); zSign = aSign ^ bSign; if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); goto invalid; } return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); } if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); return packFloatx80( zSign, 0, 0 ); } if ( bExp == 0 ) { @@ -4277,15 +4810,15 @@ floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM ) zSig0 = estimateDiv128To64( aSig, rem1, bSig ); mul64To128( bSig, zSig0, &term0, &term1 ); sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { + while ( (int64_t) rem0 < 0 ) { --zSig0; add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); } zSig1 = estimateDiv128To64( rem1, 0, bSig ); - if ( (bits64) ( zSig1<<1 ) <= 8 ) { + if ( (uint64_t) ( zSig1<<1 ) <= 8 ) { mul64To128( bSig, zSig1, &term1, &term2 ); sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - while ( (sbits64) rem1 < 0 ) { + while ( (int64_t) rem1 < 0 ) { --zSig1; add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); } @@ -4307,8 +4840,8 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM ) { flag aSign, zSign; int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig; - bits64 q, term0, term1, alternateASig0, alternateASig1; + uint64_t aSig0, aSig1, bSig; + uint64_t q, term0, term1, alternateASig0, alternateASig1; floatx80 z; aSig0 = extractFloatx80Frac( a ); @@ -4317,14 +4850,14 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM ) bSig = extractFloatx80Frac( b ); bExp = extractFloatx80Exp( b ); if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + if ( (uint64_t) ( aSig0<<1 ) + || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) { return propagateFloatx80NaN( a, b STATUS_VAR ); } goto invalid; } if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); + if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR ); return a; } if ( bExp == 0 ) { @@ -4338,7 +4871,7 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM ) normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); } if ( aExp == 0 ) { - if ( (bits64) ( aSig0<<1 ) == 0 ) return a; + if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a; normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); } bSig |= LIT64( 0x8000000000000000 ); @@ -4403,15 +4936,15 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM ) { flag aSign; int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0; + uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3; floatx80 z; aSig0 = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR ); + if ( (uint64_t) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR ); if ( ! aSign ) return a; goto invalid; } @@ -4434,7 +4967,7 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM ) doubleZSig0 = zSig0<<1; mul64To128( zSig0, zSig0, &term0, &term1 ); sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { + while ( (int64_t) rem0 < 0 ) { --zSig0; doubleZSig0 -= 2; add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); @@ -4446,7 +4979,7 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM ) sub128( rem1, 0, term1, term2, &rem1, &rem2 ); mul64To128( zSig1, zSig1, &term2, &term3 ); sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { + while ( (int64_t) rem1 < 0 ) { --zSig1; shortShift128Left( 0, zSig1, 1, &term2, &term3 ); term3 |= 1; @@ -4464,31 +4997,28 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM ) } /*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. +| Returns 1 if the extended double-precision floating-point value `a' is equal +| to the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM ) { if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid STATUS_VAR); - } + float_raise( float_flag_invalid STATUS_VAR); return 0; } return ( a.low == b.low ) && ( ( a.high == b.high ) || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) ) ); } @@ -4496,8 +5026,9 @@ int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM ) /*---------------------------------------------------------------------------- | Returns 1 if the extended double-precision floating-point value `a' is | less than or equal to the corresponding value `b', and 0 otherwise. The -| comparison is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. +| invalid exception is raised if either operand is a NaN. The comparison is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic. *----------------------------------------------------------------------------*/ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM ) @@ -4505,9 +5036,9 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM ) flag aSign, bSign; if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) ) { float_raise( float_flag_invalid STATUS_VAR); return 0; @@ -4517,7 +5048,7 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + || ( ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) == 0 ); } return @@ -4528,9 +5059,9 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM ) /*---------------------------------------------------------------------------- | Returns 1 if the extended double-precision floating-point value `a' is -| less than the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. +| less than the corresponding value `b', and 0 otherwise. The invalid +| exception is raised if either operand is a NaN. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM ) @@ -4538,9 +5069,9 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM ) flag aSign, bSign; if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) ) { float_raise( float_flag_invalid STATUS_VAR); return 0; @@ -4550,7 +5081,7 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + && ( ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) != 0 ); } return @@ -4560,28 +5091,50 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM ) } /*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is equal -| to the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| Returns 1 if the extended double-precision floating-point values `a' and `b' +| cannot be compared, and 0 otherwise. The invalid exception is raised if +| either operand is a NaN. The comparison is performed according to the +| IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ +int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM ) +{ + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid STATUS_VAR); + return 1; + } + return 0; +} -int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM ) +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point value `a' is +| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. The comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM ) { if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) ) { - float_raise( float_flag_invalid STATUS_VAR); + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } return 0; } return ( a.low == b.low ) && ( ( a.high == b.high ) || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) ) ); } @@ -4598,9 +5151,9 @@ int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM ) flag aSign, bSign; if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) ) { if ( floatx80_is_signaling_nan( a ) || floatx80_is_signaling_nan( b ) ) { @@ -4613,7 +5166,7 @@ int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + || ( ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) == 0 ); } return @@ -4634,9 +5187,9 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM ) flag aSign, bSign; if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) ) { if ( floatx80_is_signaling_nan( a ) || floatx80_is_signaling_nan( b ) ) { @@ -4649,7 +5202,7 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + && ( ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) != 0 ); } return @@ -4658,9 +5211,27 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM ) } -#endif - -#ifdef FLOAT128 +/*---------------------------------------------------------------------------- +| Returns 1 if the extended double-precision floating-point values `a' and `b' +| cannot be compared, and 0 otherwise. Quiet NaNs do not cause an exception. +| The comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ +int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM ) +{ + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (uint64_t) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } + return 1; + } + return 0; +} /*---------------------------------------------------------------------------- | Returns the result of converting the quadruple-precision floating-point @@ -4676,7 +5247,7 @@ int32 float128_to_int32( float128 a STATUS_PARAM ) { flag aSign; int32 aExp, shiftCount; - bits64 aSig0, aSig1; + uint64_t aSig0, aSig1; aSig1 = extractFloat128Frac1( a ); aSig0 = extractFloat128Frac0( a ); @@ -4705,7 +5276,7 @@ int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM ) { flag aSign; int32 aExp, shiftCount; - bits64 aSig0, aSig1, savedASig; + uint64_t aSig0, aSig1, savedASig; int32 z; aSig1 = extractFloat128Frac1( a ); @@ -4730,7 +5301,7 @@ int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM ) if ( ( z < 0 ) ^ aSign ) { invalid: float_raise( float_flag_invalid STATUS_VAR); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF; } if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); - if ( (bits64) ( aSig1<>( - shiftCount ); if ( aSig1 - || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { + || ( shiftCount && (uint64_t) ( aSig0<<( shiftCount & 63 ) ) ) ) { STATUS(float_exception_flags) |= float_flag_inexact; } } @@ -4854,8 +5425,8 @@ float32 float128_to_float32( float128 a STATUS_PARAM ) { flag aSign; int32 aExp; - bits64 aSig0, aSig1; - bits32 zSig; + uint64_t aSig0, aSig1; + uint32_t zSig; aSig1 = extractFloat128Frac1( a ); aSig0 = extractFloat128Frac0( a ); @@ -4863,7 +5434,7 @@ float32 float128_to_float32( float128 a STATUS_PARAM ) aSign = extractFloat128Sign( a ); if ( aExp == 0x7FFF ) { if ( aSig0 | aSig1 ) { - return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) ); + return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat32( aSign, 0xFF, 0 ); } @@ -4889,7 +5460,7 @@ float64 float128_to_float64( float128 a STATUS_PARAM ) { flag aSign; int32 aExp; - bits64 aSig0, aSig1; + uint64_t aSig0, aSig1; aSig1 = extractFloat128Frac1( a ); aSig0 = extractFloat128Frac0( a ); @@ -4897,7 +5468,7 @@ float64 float128_to_float64( float128 a STATUS_PARAM ) aSign = extractFloat128Sign( a ); if ( aExp == 0x7FFF ) { if ( aSig0 | aSig1 ) { - return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) ); + return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat64( aSign, 0x7FF, 0 ); } @@ -4911,8 +5482,6 @@ float64 float128_to_float64( float128 a STATUS_PARAM ) } -#ifdef FLOATX80 - /*---------------------------------------------------------------------------- | Returns the result of converting the quadruple-precision floating-point | value `a' to the extended double-precision floating-point format. The @@ -4924,7 +5493,7 @@ floatx80 float128_to_floatx80( float128 a STATUS_PARAM ) { flag aSign; int32 aExp; - bits64 aSig0, aSig1; + uint64_t aSig0, aSig1; aSig1 = extractFloat128Frac1( a ); aSig0 = extractFloat128Frac0( a ); @@ -4932,7 +5501,7 @@ floatx80 float128_to_floatx80( float128 a STATUS_PARAM ) aSign = extractFloat128Sign( a ); if ( aExp == 0x7FFF ) { if ( aSig0 | aSig1 ) { - return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) ); + return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); } @@ -4948,8 +5517,6 @@ floatx80 float128_to_floatx80( float128 a STATUS_PARAM ) } -#endif - /*---------------------------------------------------------------------------- | Rounds the quadruple-precision floating-point value `a' to an integer, and | returns the result as a quadruple-precision floating-point value. The @@ -4961,7 +5528,7 @@ float128 float128_round_to_int( float128 a STATUS_PARAM ) { flag aSign; int32 aExp; - bits64 lastBitMask, roundBitsMask; + uint64_t lastBitMask, roundBitsMask; int8 roundingMode; float128 z; @@ -4986,9 +5553,9 @@ float128 float128_round_to_int( float128 a STATUS_PARAM ) if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; } else { - if ( (sbits64) z.low < 0 ) { + if ( (int64_t) z.low < 0 ) { ++z.high; - if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; + if ( (uint64_t) ( z.low<<1 ) == 0 ) z.high &= ~1; } } } @@ -5002,7 +5569,7 @@ float128 float128_round_to_int( float128 a STATUS_PARAM ) } else { if ( aExp < 0x3FFF ) { - if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; + if ( ( ( (uint64_t) ( a.high<<1 ) ) | a.low ) == 0 ) return a; STATUS(float_exception_flags) |= float_flag_inexact; aSign = extractFloat128Sign( a ); switch ( STATUS(float_rounding_mode) ) { @@ -5064,7 +5631,7 @@ float128 float128_round_to_int( float128 a STATUS_PARAM ) static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM) { int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; int32 expDiff; aSig1 = extractFloat128Frac1( a ); @@ -5113,7 +5680,12 @@ static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM } add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); if ( aExp == 0 ) { - if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 ); + if (STATUS(flush_to_zero)) { + if (zSig0 | zSig1) { + float_raise(float_flag_output_denormal STATUS_VAR); + } + return packFloat128(zSign, 0, 0, 0); + } return packFloat128( zSign, 0, zSig0, zSig1 ); } zSig2 = 0; @@ -5145,7 +5717,7 @@ static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM) { int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; + uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; int32 expDiff; float128 z; @@ -5270,7 +5842,7 @@ float128 float128_mul( float128 a, float128 b STATUS_PARAM ) { flag aSign, bSign, zSign; int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; + uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; float128 z; aSig1 = extractFloat128Frac1( a ); @@ -5334,8 +5906,8 @@ float128 float128_div( float128 a, float128 b STATUS_PARAM ) { flag aSign, bSign, zSign; int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3; float128 z; aSig1 = extractFloat128Frac1( a ); @@ -5389,7 +5961,7 @@ float128 float128_div( float128 a, float128 b STATUS_PARAM ) zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); - while ( (sbits64) rem0 < 0 ) { + while ( (int64_t) rem0 < 0 ) { --zSig0; add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); } @@ -5397,7 +5969,7 @@ float128 float128_div( float128 a, float128 b STATUS_PARAM ) if ( ( zSig1 & 0x3FFF ) <= 4 ) { mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { + while ( (int64_t) rem1 < 0 ) { --zSig1; add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); } @@ -5418,9 +5990,9 @@ float128 float128_rem( float128 a, float128 b STATUS_PARAM ) { flag aSign, zSign; int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; - bits64 allZero, alternateASig0, alternateASig1, sigMean1; - sbits64 sigMean0; + uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; + uint64_t allZero, alternateASig0, alternateASig1, sigMean1; + int64_t sigMean0; float128 z; aSig1 = extractFloat128Frac1( a ); @@ -5502,15 +6074,15 @@ float128 float128_rem( float128 a, float128 b STATUS_PARAM ) alternateASig1 = aSig1; ++q; sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - } while ( 0 <= (sbits64) aSig0 ); + } while ( 0 <= (int64_t) aSig0 ); add128( - aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); + aSig0, aSig1, alternateASig0, alternateASig1, (uint64_t *)&sigMean0, &sigMean1 ); if ( ( sigMean0 < 0 ) || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { aSig0 = alternateASig0; aSig1 = alternateASig1; } - zSign = ( (sbits64) aSig0 < 0 ); + zSign = ( (int64_t) aSig0 < 0 ); if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); return normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR ); @@ -5527,8 +6099,8 @@ float128 float128_sqrt( float128 a STATUS_PARAM ) { flag aSign; int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + uint64_t aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; + uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3; float128 z; aSig1 = extractFloat128Frac1( a ); @@ -5560,7 +6132,7 @@ float128 float128_sqrt( float128 a STATUS_PARAM ) doubleZSig0 = zSig0<<1; mul64To128( zSig0, zSig0, &term0, &term1 ); sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { + while ( (int64_t) rem0 < 0 ) { --zSig0; doubleZSig0 -= 2; add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); @@ -5572,7 +6144,7 @@ float128 float128_sqrt( float128 a STATUS_PARAM ) sub128( rem1, 0, term1, term2, &rem1, &rem2 ); mul64To128( zSig1, zSig1, &term2, &term3 ); sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { + while ( (int64_t) rem1 < 0 ) { --zSig1; shortShift128Left( 0, zSig1, 1, &term2, &term3 ); term3 |= 1; @@ -5588,7 +6160,8 @@ float128 float128_sqrt( float128 a STATUS_PARAM ) /*---------------------------------------------------------------------------- | Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ @@ -5600,26 +6173,23 @@ int float128_eq( float128 a, float128 b STATUS_PARAM ) || ( ( extractFloat128Exp( b ) == 0x7FFF ) && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid STATUS_VAR); - } + float_raise( float_flag_invalid STATUS_VAR); return 0; } return ( a.low == b.low ) && ( ( a.high == b.high ) || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) ) ); } /*---------------------------------------------------------------------------- | Returns 1 if the quadruple-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. +| or equal to the corresponding value `b', and 0 otherwise. The invalid +| exception is raised if either operand is a NaN. The comparison is performed +| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float128_le( float128 a, float128 b STATUS_PARAM ) @@ -5639,7 +6209,7 @@ int float128_le( float128 a, float128 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + || ( ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) == 0 ); } return @@ -5650,8 +6220,9 @@ int float128_le( float128 a, float128 b STATUS_PARAM ) /*---------------------------------------------------------------------------- | Returns 1 if the quadruple-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. The comparison is performed according +| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ int float128_lt( float128 a, float128 b STATUS_PARAM ) @@ -5671,7 +6242,7 @@ int float128_lt( float128 a, float128 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + && ( ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) != 0 ); } return @@ -5681,13 +6252,33 @@ int float128_lt( float128 a, float128 b STATUS_PARAM ) } /*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot +| be compared, and 0 otherwise. The invalid exception is raised if either +| operand is a NaN. The comparison is performed according to the IEC/IEEE +| Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +int float128_unordered( float128 a, float128 b STATUS_PARAM ) +{ + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid STATUS_VAR); + return 1; + } + return 0; +} + +/*---------------------------------------------------------------------------- | Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. The comparison is performed according to the IEC/IEEE Standard +| for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -int float128_eq_signaling( float128 a, float128 b STATUS_PARAM ) +int float128_eq_quiet( float128 a, float128 b STATUS_PARAM ) { if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) @@ -5695,14 +6286,17 @@ int float128_eq_signaling( float128 a, float128 b STATUS_PARAM ) || ( ( extractFloat128Exp( b ) == 0x7FFF ) && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) ) { - float_raise( float_flag_invalid STATUS_VAR); + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } return 0; } return ( a.low == b.low ) && ( ( a.high == b.high ) || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) ) ); } @@ -5734,7 +6328,7 @@ int float128_le_quiet( float128 a, float128 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + || ( ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) == 0 ); } return @@ -5770,7 +6364,7 @@ int float128_lt_quiet( float128 a, float128 b STATUS_PARAM ) if ( aSign != bSign ) { return aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + && ( ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) != 0 ); } return @@ -5779,23 +6373,44 @@ int float128_lt_quiet( float128 a, float128 b STATUS_PARAM ) } -#endif +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot +| be compared, and 0 otherwise. Quiet NaNs do not cause an exception. The +| comparison is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM ) +{ + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } + return 1; + } + return 0; +} /* misc functions */ -float32 uint32_to_float32( unsigned int a STATUS_PARAM ) +float32 uint32_to_float32( uint32 a STATUS_PARAM ) { return int64_to_float32(a STATUS_VAR); } -float64 uint32_to_float64( unsigned int a STATUS_PARAM ) +float64 uint32_to_float64( uint32 a STATUS_PARAM ) { return int64_to_float64(a STATUS_VAR); } -unsigned int float32_to_uint32( float32 a STATUS_PARAM ) +uint32 float32_to_uint32( float32 a STATUS_PARAM ) { int64_t v; - unsigned int res; + uint32 res; v = float32_to_int64(a STATUS_VAR); if (v < 0) { @@ -5810,10 +6425,10 @@ unsigned int float32_to_uint32( float32 a STATUS_PARAM ) return res; } -unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM ) +uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM ) { int64_t v; - unsigned int res; + uint32 res; v = float32_to_int64_round_to_zero(a STATUS_VAR); if (v < 0) { @@ -5828,10 +6443,10 @@ unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM ) return res; } -unsigned int float32_to_uint16_round_to_zero( float32 a STATUS_PARAM ) +uint16 float32_to_uint16_round_to_zero( float32 a STATUS_PARAM ) { int64_t v; - unsigned int res; + uint16 res; v = float32_to_int64_round_to_zero(a STATUS_VAR); if (v < 0) { @@ -5846,10 +6461,10 @@ unsigned int float32_to_uint16_round_to_zero( float32 a STATUS_PARAM ) return res; } -unsigned int float64_to_uint32( float64 a STATUS_PARAM ) +uint32 float64_to_uint32( float64 a STATUS_PARAM ) { int64_t v; - unsigned int res; + uint32 res; v = float64_to_int64(a STATUS_VAR); if (v < 0) { @@ -5864,10 +6479,10 @@ unsigned int float64_to_uint32( float64 a STATUS_PARAM ) return res; } -unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) +uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) { int64_t v; - unsigned int res; + uint32 res; v = float64_to_int64_round_to_zero(a STATUS_VAR); if (v < 0) { @@ -5882,10 +6497,10 @@ unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM ) return res; } -unsigned int float64_to_uint16_round_to_zero( float64 a STATUS_PARAM ) +uint16 float64_to_uint16_round_to_zero( float64 a STATUS_PARAM ) { int64_t v; - unsigned int res; + uint16 res; v = float64_to_int64_round_to_zero(a STATUS_VAR); if (v < 0) { @@ -5928,7 +6543,7 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ int is_quiet STATUS_PARAM ) \ { \ flag aSign, bSign; \ - bits ## s av, bv; \ + uint ## s ## _t av, bv; \ a = float ## s ## _squash_input_denormal(a STATUS_VAR); \ b = float ## s ## _squash_input_denormal(b STATUS_VAR); \ \ @@ -5948,7 +6563,7 @@ INLINE int float ## s ## _compare_internal( float ## s a, float ## s b, \ av = float ## s ## _val(a); \ bv = float ## s ## _val(b); \ if ( aSign != bSign ) { \ - if ( (bits ## s) ( ( av | bv )<<1 ) == 0 ) { \ + if ( (uint ## s ## _t) ( ( av | bv )<<1 ) == 0 ) { \ /* zero case */ \ return float_relation_equal; \ } else { \ @@ -5976,6 +6591,52 @@ int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \ COMPARE(32, 0xff) COMPARE(64, 0x7ff) +INLINE int floatx80_compare_internal( floatx80 a, floatx80 b, + int is_quiet STATUS_PARAM ) +{ + flag aSign, bSign; + + if (( ( extractFloatx80Exp( a ) == 0x7fff ) && + ( extractFloatx80Frac( a )<<1 ) ) || + ( ( extractFloatx80Exp( b ) == 0x7fff ) && + ( extractFloatx80Frac( b )<<1 ) )) { + if (!is_quiet || + floatx80_is_signaling_nan( a ) || + floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid STATUS_VAR); + } + return float_relation_unordered; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + + if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) && + ( ( a.low | b.low ) == 0 ) ) { + /* zero case */ + return float_relation_equal; + } else { + return 1 - (2 * aSign); + } + } else { + if (a.low == b.low && a.high == b.high) { + return float_relation_equal; + } else { + return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) )); + } + } +} + +int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM ) +{ + return floatx80_compare_internal(a, b, 0 STATUS_VAR); +} + +int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM ) +{ + return floatx80_compare_internal(a, b, 1 STATUS_VAR); +} + INLINE int float128_compare_internal( float128 a, float128 b, int is_quiet STATUS_PARAM ) { @@ -6020,12 +6681,61 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM ) return float128_compare_internal(a, b, 1 STATUS_VAR); } +/* min() and max() functions. These can't be implemented as + * 'compare and pick one input' because that would mishandle + * NaNs and +0 vs -0. + */ +#define MINMAX(s, nan_exp) \ +INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b, \ + int ismin STATUS_PARAM ) \ +{ \ + flag aSign, bSign; \ + uint ## s ## _t av, bv; \ + a = float ## s ## _squash_input_denormal(a STATUS_VAR); \ + b = float ## s ## _squash_input_denormal(b STATUS_VAR); \ + if (float ## s ## _is_any_nan(a) || \ + float ## s ## _is_any_nan(b)) { \ + return propagateFloat ## s ## NaN(a, b STATUS_VAR); \ + } \ + aSign = extractFloat ## s ## Sign(a); \ + bSign = extractFloat ## s ## Sign(b); \ + av = float ## s ## _val(a); \ + bv = float ## s ## _val(b); \ + if (aSign != bSign) { \ + if (ismin) { \ + return aSign ? a : b; \ + } else { \ + return aSign ? b : a; \ + } \ + } else { \ + if (ismin) { \ + return (aSign ^ (av < bv)) ? a : b; \ + } else { \ + return (aSign ^ (av < bv)) ? b : a; \ + } \ + } \ +} \ + \ +float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM) \ +{ \ + return float ## s ## _minmax(a, b, 1 STATUS_VAR); \ +} \ + \ +float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM) \ +{ \ + return float ## s ## _minmax(a, b, 0 STATUS_VAR); \ +} + +MINMAX(32, 0xff) +MINMAX(64, 0x7ff) + + /* Multiply A by 2 raised to the power N. */ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) { flag aSign; - int16 aExp; - bits32 aSig; + int16_t aExp; + uint32_t aSig; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); @@ -6033,6 +6743,9 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) aSign = extractFloat32Sign( a ); if ( aExp == 0xFF ) { + if ( aSig ) { + return propagateFloat32NaN( a, a STATUS_VAR ); + } return a; } if ( aExp != 0 ) @@ -6040,6 +6753,12 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) else if ( aSig == 0 ) return a; + if (n > 0x200) { + n = 0x200; + } else if (n < -0x200) { + n = -0x200; + } + aExp += n - 1; aSig <<= 7; return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); @@ -6048,8 +6767,8 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) float64 float64_scalbn( float64 a, int n STATUS_PARAM ) { flag aSign; - int16 aExp; - bits64 aSig; + int16_t aExp; + uint64_t aSig; a = float64_squash_input_denormal(a STATUS_VAR); aSig = extractFloat64Frac( a ); @@ -6057,6 +6776,9 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM ) aSign = extractFloat64Sign( a ); if ( aExp == 0x7FF ) { + if ( aSig ) { + return propagateFloat64NaN( a, a STATUS_VAR ); + } return a; } if ( aExp != 0 ) @@ -6064,46 +6786,62 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM ) else if ( aSig == 0 ) return a; + if (n > 0x1000) { + n = 0x1000; + } else if (n < -0x1000) { + n = -0x1000; + } + aExp += n - 1; aSig <<= 10; return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); } -#ifdef FLOATX80 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM ) { flag aSign; - int16 aExp; - bits64 aSig; + int32_t aExp; + uint64_t aSig; aSig = extractFloatx80Frac( a ); aExp = extractFloatx80Exp( a ); aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FF ) { + if ( aExp == 0x7FFF ) { + if ( aSig<<1 ) { + return propagateFloatx80NaN( a, a STATUS_VAR ); + } return a; } + if (aExp == 0 && aSig == 0) return a; + if (n > 0x10000) { + n = 0x10000; + } else if (n < -0x10000) { + n = -0x10000; + } + aExp += n; return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision), aSign, aExp, aSig, 0 STATUS_VAR ); } -#endif -#ifdef FLOAT128 float128 float128_scalbn( float128 a, int n STATUS_PARAM ) { flag aSign; - int32 aExp; - bits64 aSig0, aSig1; + int32_t aExp; + uint64_t aSig0, aSig1; aSig1 = extractFloat128Frac1( a ); aSig0 = extractFloat128Frac0( a ); aExp = extractFloat128Exp( a ); aSign = extractFloat128Sign( a ); if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return propagateFloat128NaN( a, a STATUS_VAR ); + } return a; } if ( aExp != 0 ) @@ -6111,9 +6849,14 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM ) else if ( aSig0 == 0 && aSig1 == 0 ) return a; + if (n > 0x10000) { + n = 0x10000; + } else if (n < -0x10000) { + n = -0x10000; + } + aExp += n - 1; return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1 STATUS_VAR ); } -#endif diff --git a/fpu/softfloat.h b/fpu/softfloat.h index 4a5345c..937d7fa 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -1,3 +1,9 @@ +/* + * QEMU float support + * + * Derived from SoftFloat. + */ + /*============================================================================ This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic @@ -37,7 +43,7 @@ these four paragraphs for those parts of this code that are retained. #endif #include -#include "config.h" +#include "config-host.h" /*---------------------------------------------------------------------------- | Each of the following `typedef's defines the most convenient type that holds @@ -51,7 +57,10 @@ typedef uint8_t flag; typedef uint8_t uint8; typedef int8_t int8; #ifndef _AIX -typedef int uint16; +#if !(defined(__APPLE__) && defined(_UINT16)) +typedef int16_t uint16; +#define _UINT16 +#endif typedef int int16; #endif typedef unsigned int uint32; @@ -59,42 +68,9 @@ typedef signed int int32; typedef uint64_t uint64; typedef int64_t int64; -/*---------------------------------------------------------------------------- -| Each of the following `typedef's defines a type that holds integers -| of _exactly_ the number of bits specified. For instance, for most -| implementation of C, `bits16' and `sbits16' should be `typedef'ed to -| `unsigned short int' and `signed short int' (or `short int'), respectively. -*----------------------------------------------------------------------------*/ -typedef uint8_t bits8; -typedef int8_t sbits8; -typedef uint16_t bits16; -typedef int16_t sbits16; -typedef uint32_t bits32; -typedef int32_t sbits32; -typedef uint64_t bits64; -typedef int64_t sbits64; - #define LIT64( a ) a##LL #define INLINE static inline -/*---------------------------------------------------------------------------- -| The macro `FLOATX80' must be defined to enable the extended double-precision -| floating-point format `floatx80'. If this macro is not defined, the -| `floatx80' type will not be defined, and none of the functions that either -| input or output the `floatx80' type will be defined. The same applies to -| the `FLOAT128' macro and the quadruple-precision format `float128'. -*----------------------------------------------------------------------------*/ -#ifdef CONFIG_SOFTFLOAT -/* bit exact soft float support */ -#define FLOATX80 -#define FLOAT128 -#else -/* native float support */ -#if (defined(__i386__) || defined(__x86_64__)) && !defined(CONFIG_BSD) -#define FLOATX80 -#endif -#endif /* !CONFIG_SOFTFLOAT */ - #define STATUS_PARAM , float_status *status #define STATUS(field) status->field #define STATUS_VAR , status @@ -109,7 +85,6 @@ enum { float_relation_unordered = 2 }; -#ifdef CONFIG_SOFTFLOAT /*---------------------------------------------------------------------------- | Software IEC/IEEE floating-point types. *----------------------------------------------------------------------------*/ @@ -120,31 +95,43 @@ enum { //#define USE_SOFTFLOAT_STRUCT_TYPES #ifdef USE_SOFTFLOAT_STRUCT_TYPES typedef struct { + uint16_t v; +} float16; +#define float16_val(x) (((float16)(x)).v) +#define make_float16(x) __extension__ ({ float16 f16_val = {x}; f16_val; }) +#define const_float16(x) { x } +typedef struct { uint32_t v; } float32; /* The cast ensures an error if the wrong type is passed. */ #define float32_val(x) (((float32)(x)).v) #define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; }) +#define const_float32(x) { x } typedef struct { uint64_t v; } float64; #define float64_val(x) (((float64)(x)).v) #define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; }) +#define const_float64(x) { x } #else +typedef uint16_t float16; typedef uint32_t float32; typedef uint64_t float64; +#define float16_val(x) (x) #define float32_val(x) (x) #define float64_val(x) (x) +#define make_float16(x) (x) #define make_float32(x) (x) #define make_float64(x) (x) +#define const_float16(x) (x) +#define const_float32(x) (x) +#define const_float64(x) (x) #endif -#ifdef FLOATX80 typedef struct { uint64_t low; uint16_t high; } floatx80; -#endif -#ifdef FLOAT128 +#define make_floatx80(exp, mant) ((floatx80) { mant, exp }) typedef struct { #ifdef HOST_WORDS_BIGENDIAN uint64_t high, low; @@ -152,7 +139,7 @@ typedef struct { uint64_t low, high; #endif } float128; -#endif +#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ }) /*---------------------------------------------------------------------------- | Software IEC/IEEE floating-point underflow tininess-detection mode. @@ -181,16 +168,15 @@ enum { float_flag_overflow = 8, float_flag_underflow = 16, float_flag_inexact = 32, - float_flag_input_denormal = 64 + float_flag_input_denormal = 64, + float_flag_output_denormal = 128 }; typedef struct float_status { signed char float_detect_tininess; signed char float_rounding_mode; signed char float_exception_flags; -#ifdef FLOATX80 signed char floatx80_rounding_precision; -#endif /* should denormalised results go to zero and set the inexact flag? */ flag flush_to_zero; /* should denormalised inputs go to zero and set the input_denormal flag? */ @@ -200,6 +186,10 @@ typedef struct float_status { void set_float_rounding_mode(int val STATUS_PARAM); void set_float_exception_flags(int val STATUS_PARAM); +INLINE void set_float_detect_tininess(int val STATUS_PARAM) +{ + STATUS(float_detect_tininess) = val; +} INLINE void set_flush_to_zero(flag val STATUS_PARAM) { STATUS(flush_to_zero) = val; @@ -216,9 +206,7 @@ INLINE int get_float_exception_flags(float_status *status) { return STATUS(float_exception_flags); } -#ifdef FLOATX80 void set_floatx80_rounding_precision(int val STATUS_PARAM); -#endif /*---------------------------------------------------------------------------- | Routine to raise any or all of the software IEC/IEEE floating-point @@ -227,53 +215,65 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM); void float_raise( int8 flags STATUS_PARAM); /*---------------------------------------------------------------------------- +| Options to indicate which negations to perform in float*_muladd() +| Using these differs from negating an input or output before calling +| the muladd function in that this means that a NaN doesn't have its +| sign bit inverted before it is propagated. +*----------------------------------------------------------------------------*/ +enum { + float_muladd_negate_c = 1, + float_muladd_negate_product = 2, + float_muladd_negate_result = 3, +}; + +/*---------------------------------------------------------------------------- | Software IEC/IEEE integer-to-floating-point conversion routines. *----------------------------------------------------------------------------*/ -float32 int32_to_float32( int STATUS_PARAM ); -float64 int32_to_float64( int STATUS_PARAM ); -float32 uint32_to_float32( unsigned int STATUS_PARAM ); -float64 uint32_to_float64( unsigned int STATUS_PARAM ); -#ifdef FLOATX80 -floatx80 int32_to_floatx80( int STATUS_PARAM ); -#endif -#ifdef FLOAT128 -float128 int32_to_float128( int STATUS_PARAM ); -#endif -float32 int64_to_float32( int64_t STATUS_PARAM ); -float32 uint64_to_float32( uint64_t STATUS_PARAM ); -float64 int64_to_float64( int64_t STATUS_PARAM ); -float64 uint64_to_float64( uint64_t STATUS_PARAM ); -#ifdef FLOATX80 -floatx80 int64_to_floatx80( int64_t STATUS_PARAM ); -#endif -#ifdef FLOAT128 -float128 int64_to_float128( int64_t STATUS_PARAM ); -#endif +float32 int32_to_float32( int32 STATUS_PARAM ); +float64 int32_to_float64( int32 STATUS_PARAM ); +float32 uint32_to_float32( uint32 STATUS_PARAM ); +float64 uint32_to_float64( uint32 STATUS_PARAM ); +floatx80 int32_to_floatx80( int32 STATUS_PARAM ); +float128 int32_to_float128( int32 STATUS_PARAM ); +float32 int64_to_float32( int64 STATUS_PARAM ); +float32 uint64_to_float32( uint64 STATUS_PARAM ); +float64 int64_to_float64( int64 STATUS_PARAM ); +float64 uint64_to_float64( uint64 STATUS_PARAM ); +floatx80 int64_to_floatx80( int64 STATUS_PARAM ); +float128 int64_to_float128( int64 STATUS_PARAM ); /*---------------------------------------------------------------------------- | Software half-precision conversion routines. *----------------------------------------------------------------------------*/ -bits16 float32_to_float16( float32, flag STATUS_PARAM ); -float32 float16_to_float32( bits16, flag STATUS_PARAM ); +float16 float32_to_float16( float32, flag STATUS_PARAM ); +float32 float16_to_float32( float16, flag STATUS_PARAM ); + +/*---------------------------------------------------------------------------- +| Software half-precision operations. +*----------------------------------------------------------------------------*/ +int float16_is_quiet_nan( float16 ); +int float16_is_signaling_nan( float16 ); +float16 float16_maybe_silence_nan( float16 ); + +/*---------------------------------------------------------------------------- +| The pattern for a default generated half-precision NaN. +*----------------------------------------------------------------------------*/ +extern const float16 float16_default_nan; /*---------------------------------------------------------------------------- | Software IEC/IEEE single-precision conversion routines. *----------------------------------------------------------------------------*/ -int float32_to_int16_round_to_zero( float32 STATUS_PARAM ); -unsigned int float32_to_uint16_round_to_zero( float32 STATUS_PARAM ); -int float32_to_int32( float32 STATUS_PARAM ); -int float32_to_int32_round_to_zero( float32 STATUS_PARAM ); -unsigned int float32_to_uint32( float32 STATUS_PARAM ); -unsigned int float32_to_uint32_round_to_zero( float32 STATUS_PARAM ); -int64_t float32_to_int64( float32 STATUS_PARAM ); -int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM ); +int16 float32_to_int16_round_to_zero( float32 STATUS_PARAM ); +uint16 float32_to_uint16_round_to_zero( float32 STATUS_PARAM ); +int32 float32_to_int32( float32 STATUS_PARAM ); +int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM ); +uint32 float32_to_uint32( float32 STATUS_PARAM ); +uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM ); +int64 float32_to_int64( float32 STATUS_PARAM ); +int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM ); float64 float32_to_float64( float32 STATUS_PARAM ); -#ifdef FLOATX80 floatx80 float32_to_floatx80( float32 STATUS_PARAM ); -#endif -#ifdef FLOAT128 float128 float32_to_float128( float32 STATUS_PARAM ); -#endif /*---------------------------------------------------------------------------- | Software IEC/IEEE single-precision operations. @@ -284,17 +284,22 @@ float32 float32_sub( float32, float32 STATUS_PARAM ); float32 float32_mul( float32, float32 STATUS_PARAM ); float32 float32_div( float32, float32 STATUS_PARAM ); float32 float32_rem( float32, float32 STATUS_PARAM ); +float32 float32_muladd(float32, float32, float32, int STATUS_PARAM); float32 float32_sqrt( float32 STATUS_PARAM ); float32 float32_exp2( float32 STATUS_PARAM ); float32 float32_log2( float32 STATUS_PARAM ); int float32_eq( float32, float32 STATUS_PARAM ); int float32_le( float32, float32 STATUS_PARAM ); int float32_lt( float32, float32 STATUS_PARAM ); -int float32_eq_signaling( float32, float32 STATUS_PARAM ); +int float32_unordered( float32, float32 STATUS_PARAM ); +int float32_eq_quiet( float32, float32 STATUS_PARAM ); int float32_le_quiet( float32, float32 STATUS_PARAM ); int float32_lt_quiet( float32, float32 STATUS_PARAM ); +int float32_unordered_quiet( float32, float32 STATUS_PARAM ); int float32_compare( float32, float32 STATUS_PARAM ); int float32_compare_quiet( float32, float32 STATUS_PARAM ); +float32 float32_min(float32, float32 STATUS_PARAM); +float32 float32_max(float32, float32 STATUS_PARAM); int float32_is_quiet_nan( float32 ); int float32_is_signaling_nan( float32 ); float32 float32_maybe_silence_nan( float32 ); @@ -341,30 +346,40 @@ INLINE int float32_is_zero_or_denormal(float32 a) return (float32_val(a) & 0x7f800000) == 0; } +INLINE float32 float32_set_sign(float32 a, int sign) +{ + return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31)); +} + #define float32_zero make_float32(0) #define float32_one make_float32(0x3f800000) #define float32_ln2 make_float32(0x3f317218) +#define float32_pi make_float32(0x40490fdb) +#define float32_half make_float32(0x3f000000) +#define float32_infinity make_float32(0x7f800000) + + +/*---------------------------------------------------------------------------- +| The pattern for a default generated single-precision NaN. +*----------------------------------------------------------------------------*/ +extern const float32 float32_default_nan; /*---------------------------------------------------------------------------- | Software IEC/IEEE double-precision conversion routines. *----------------------------------------------------------------------------*/ -int float64_to_int16_round_to_zero( float64 STATUS_PARAM ); -unsigned int float64_to_uint16_round_to_zero( float64 STATUS_PARAM ); -int float64_to_int32( float64 STATUS_PARAM ); -int float64_to_int32_round_to_zero( float64 STATUS_PARAM ); -unsigned int float64_to_uint32( float64 STATUS_PARAM ); -unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM ); -int64_t float64_to_int64( float64 STATUS_PARAM ); -int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM ); -uint64_t float64_to_uint64 (float64 a STATUS_PARAM); -uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM); +int16 float64_to_int16_round_to_zero( float64 STATUS_PARAM ); +uint16 float64_to_uint16_round_to_zero( float64 STATUS_PARAM ); +int32 float64_to_int32( float64 STATUS_PARAM ); +int32 float64_to_int32_round_to_zero( float64 STATUS_PARAM ); +uint32 float64_to_uint32( float64 STATUS_PARAM ); +uint32 float64_to_uint32_round_to_zero( float64 STATUS_PARAM ); +int64 float64_to_int64( float64 STATUS_PARAM ); +int64 float64_to_int64_round_to_zero( float64 STATUS_PARAM ); +uint64 float64_to_uint64 (float64 a STATUS_PARAM); +uint64 float64_to_uint64_round_to_zero (float64 a STATUS_PARAM); float32 float64_to_float32( float64 STATUS_PARAM ); -#ifdef FLOATX80 floatx80 float64_to_floatx80( float64 STATUS_PARAM ); -#endif -#ifdef FLOAT128 float128 float64_to_float128( float64 STATUS_PARAM ); -#endif /*---------------------------------------------------------------------------- | Software IEC/IEEE double-precision operations. @@ -376,16 +391,21 @@ float64 float64_sub( float64, float64 STATUS_PARAM ); float64 float64_mul( float64, float64 STATUS_PARAM ); float64 float64_div( float64, float64 STATUS_PARAM ); float64 float64_rem( float64, float64 STATUS_PARAM ); +float64 float64_muladd(float64, float64, float64, int STATUS_PARAM); float64 float64_sqrt( float64 STATUS_PARAM ); float64 float64_log2( float64 STATUS_PARAM ); int float64_eq( float64, float64 STATUS_PARAM ); int float64_le( float64, float64 STATUS_PARAM ); int float64_lt( float64, float64 STATUS_PARAM ); -int float64_eq_signaling( float64, float64 STATUS_PARAM ); +int float64_unordered( float64, float64 STATUS_PARAM ); +int float64_eq_quiet( float64, float64 STATUS_PARAM ); int float64_le_quiet( float64, float64 STATUS_PARAM ); int float64_lt_quiet( float64, float64 STATUS_PARAM ); +int float64_unordered_quiet( float64, float64 STATUS_PARAM ); int float64_compare( float64, float64 STATUS_PARAM ); int float64_compare_quiet( float64, float64 STATUS_PARAM ); +float64 float64_min(float64, float64 STATUS_PARAM); +float64 float64_max(float64, float64 STATUS_PARAM); int float64_is_quiet_nan( float64 a ); int float64_is_signaling_nan( float64 ); float64 float64_maybe_silence_nan( float64 ); @@ -427,24 +447,39 @@ INLINE int float64_is_any_nan(float64 a) return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL); } +INLINE int float64_is_zero_or_denormal(float64 a) +{ + return (float64_val(a) & 0x7ff0000000000000LL) == 0; +} + +INLINE float64 float64_set_sign(float64 a, int sign) +{ + return make_float64((float64_val(a) & 0x7fffffffffffffffULL) + | ((int64_t)sign << 63)); +} + #define float64_zero make_float64(0) #define float64_one make_float64(0x3ff0000000000000LL) #define float64_ln2 make_float64(0x3fe62e42fefa39efLL) +#define float64_pi make_float64(0x400921fb54442d18LL) +#define float64_half make_float64(0x3fe0000000000000LL) +#define float64_infinity make_float64(0x7ff0000000000000LL) -#ifdef FLOATX80 +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +extern const float64 float64_default_nan; /*---------------------------------------------------------------------------- | Software IEC/IEEE extended double-precision conversion routines. *----------------------------------------------------------------------------*/ -int floatx80_to_int32( floatx80 STATUS_PARAM ); -int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM ); -int64_t floatx80_to_int64( floatx80 STATUS_PARAM ); -int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM ); +int32 floatx80_to_int32( floatx80 STATUS_PARAM ); +int32 floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM ); +int64 floatx80_to_int64( floatx80 STATUS_PARAM ); +int64 floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM ); float32 floatx80_to_float32( floatx80 STATUS_PARAM ); float64 floatx80_to_float64( floatx80 STATUS_PARAM ); -#ifdef FLOAT128 float128 floatx80_to_float128( floatx80 STATUS_PARAM ); -#endif /*---------------------------------------------------------------------------- | Software IEC/IEEE extended double-precision operations. @@ -459,9 +494,13 @@ floatx80 floatx80_sqrt( floatx80 STATUS_PARAM ); int floatx80_eq( floatx80, floatx80 STATUS_PARAM ); int floatx80_le( floatx80, floatx80 STATUS_PARAM ); int floatx80_lt( floatx80, floatx80 STATUS_PARAM ); -int floatx80_eq_signaling( floatx80, floatx80 STATUS_PARAM ); +int floatx80_unordered( floatx80, floatx80 STATUS_PARAM ); +int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM ); int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM ); int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM ); +int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM ); +int floatx80_compare( floatx80, floatx80 STATUS_PARAM ); +int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM ); int floatx80_is_quiet_nan( floatx80 ); int floatx80_is_signaling_nan( floatx80 ); floatx80 floatx80_maybe_silence_nan( floatx80 ); @@ -481,7 +520,7 @@ INLINE floatx80 floatx80_chs(floatx80 a) INLINE int floatx80_is_infinity(floatx80 a) { - return (a.high & 0x7fff) == 0x7fff && a.low == 0; + return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL; } INLINE int floatx80_is_neg(floatx80 a) @@ -494,27 +533,38 @@ INLINE int floatx80_is_zero(floatx80 a) return (a.high & 0x7fff) == 0 && a.low == 0; } +INLINE int floatx80_is_zero_or_denormal(floatx80 a) +{ + return (a.high & 0x7fff) == 0; +} + INLINE int floatx80_is_any_nan(floatx80 a) { return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1); } -#endif +#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL) +#define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL) +#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL) +#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL) +#define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL) +#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL) -#ifdef FLOAT128 +/*---------------------------------------------------------------------------- +| The pattern for a default generated extended double-precision NaN. +*----------------------------------------------------------------------------*/ +extern const floatx80 floatx80_default_nan; /*---------------------------------------------------------------------------- | Software IEC/IEEE quadruple-precision conversion routines. *----------------------------------------------------------------------------*/ -int float128_to_int32( float128 STATUS_PARAM ); -int float128_to_int32_round_to_zero( float128 STATUS_PARAM ); -int64_t float128_to_int64( float128 STATUS_PARAM ); -int64_t float128_to_int64_round_to_zero( float128 STATUS_PARAM ); +int32 float128_to_int32( float128 STATUS_PARAM ); +int32 float128_to_int32_round_to_zero( float128 STATUS_PARAM ); +int64 float128_to_int64( float128 STATUS_PARAM ); +int64 float128_to_int64_round_to_zero( float128 STATUS_PARAM ); float32 float128_to_float32( float128 STATUS_PARAM ); float64 float128_to_float64( float128 STATUS_PARAM ); -#ifdef FLOATX80 floatx80 float128_to_floatx80( float128 STATUS_PARAM ); -#endif /*---------------------------------------------------------------------------- | Software IEC/IEEE quadruple-precision operations. @@ -529,9 +579,11 @@ float128 float128_sqrt( float128 STATUS_PARAM ); int float128_eq( float128, float128 STATUS_PARAM ); int float128_le( float128, float128 STATUS_PARAM ); int float128_lt( float128, float128 STATUS_PARAM ); -int float128_eq_signaling( float128, float128 STATUS_PARAM ); +int float128_unordered( float128, float128 STATUS_PARAM ); +int float128_eq_quiet( float128, float128 STATUS_PARAM ); int float128_le_quiet( float128, float128 STATUS_PARAM ); int float128_lt_quiet( float128, float128 STATUS_PARAM ); +int float128_unordered_quiet( float128, float128 STATUS_PARAM ); int float128_compare( float128, float128 STATUS_PARAM ); int float128_compare_quiet( float128, float128 STATUS_PARAM ); int float128_is_quiet_nan( float128 ); @@ -566,18 +618,20 @@ INLINE int float128_is_zero(float128 a) return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0; } +INLINE int float128_is_zero_or_denormal(float128 a) +{ + return (a.high & 0x7fff000000000000LL) == 0; +} + INLINE int float128_is_any_nan(float128 a) { return ((a.high >> 48) & 0x7fff) == 0x7fff && ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0)); } -#endif - -#else /* CONFIG_SOFTFLOAT */ - -#include "softfloat-native.h" - -#endif /* !CONFIG_SOFTFLOAT */ +/*---------------------------------------------------------------------------- +| The pattern for a default generated quadruple-precision NaN. +*----------------------------------------------------------------------------*/ +extern const float128 float128_default_nan; #endif /* !SOFTFLOAT_H */ diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c index 0b33290..6684f7e 100644 --- a/fsdev/qemu-fsdev.c +++ b/fsdev/qemu-fsdev.c @@ -18,45 +18,58 @@ #include "qemu-common.h" #include "qemu-config.h" -static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries = - QTAILQ_HEAD_INITIALIZER(fstype_entries); +static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries = + QTAILQ_HEAD_INITIALIZER(fsdriver_entries); -static FsTypeTable FsTypes[] = { +static FsDriverTable FsDrivers[] = { { .name = "local", .ops = &local_ops}, +#ifdef CONFIG_OPEN_BY_HANDLE + { .name = "handle", .ops = &handle_ops}, +#endif + { .name = "synth", .ops = &synth_ops}, }; int qemu_fsdev_add(QemuOpts *opts) { - struct FsTypeListEntry *fsle; + struct FsDriverListEntry *fsle; int i; const char *fsdev_id = qemu_opts_id(opts); - const char *fstype = qemu_opt_get(opts, "fstype"); + const char *fsdriver = qemu_opt_get(opts, "fsdriver"); const char *path = qemu_opt_get(opts, "path"); const char *sec_model = qemu_opt_get(opts, "security_model"); + const char *writeout = qemu_opt_get(opts, "writeout"); + bool ro = qemu_opt_get_bool(opts, "readonly", 0); if (!fsdev_id) { fprintf(stderr, "fsdev: No id specified\n"); return -1; } - if (fstype) { - for (i = 0; i < ARRAY_SIZE(FsTypes); i++) { - if (strcmp(FsTypes[i].name, fstype) == 0) { + if (fsdriver) { + for (i = 0; i < ARRAY_SIZE(FsDrivers); i++) { + if (strcmp(FsDrivers[i].name, fsdriver) == 0) { break; } } - if (i == ARRAY_SIZE(FsTypes)) { - fprintf(stderr, "fsdev: fstype %s not found\n", fstype); + if (i == ARRAY_SIZE(FsDrivers)) { + fprintf(stderr, "fsdev: fsdriver %s not found\n", fsdriver); return -1; } } else { - fprintf(stderr, "fsdev: No fstype specified\n"); + fprintf(stderr, "fsdev: No fsdriver specified\n"); return -1; } - if (!sec_model) { - fprintf(stderr, "fsdev: No security_model specified.\n"); + if (!strcmp(fsdriver, "local") && !sec_model) { + fprintf(stderr, "security model not specified, " + "local fs needs security model\nvalid options are:" + "\tsecurity_model=[passthrough|mapped|none]\n"); + return -1; + } + + if (strcmp(fsdriver, "local") && sec_model) { + fprintf(stderr, "only local fs driver needs security model\n"); return -1; } @@ -65,24 +78,49 @@ int qemu_fsdev_add(QemuOpts *opts) return -1; } - fsle = qemu_malloc(sizeof(*fsle)); + fsle = g_malloc(sizeof(*fsle)); - fsle->fse.fsdev_id = qemu_strdup(fsdev_id); - fsle->fse.path = qemu_strdup(path); - fsle->fse.security_model = qemu_strdup(sec_model); - fsle->fse.ops = FsTypes[i].ops; + fsle->fse.fsdev_id = g_strdup(fsdev_id); + fsle->fse.path = g_strdup(path); + fsle->fse.ops = FsDrivers[i].ops; + fsle->fse.export_flags = 0; + if (writeout) { + if (!strcmp(writeout, "immediate")) { + fsle->fse.export_flags |= V9FS_IMMEDIATE_WRITEOUT; + } + } + if (ro) { + fsle->fse.export_flags |= V9FS_RDONLY; + } else { + fsle->fse.export_flags &= ~V9FS_RDONLY; + } - QTAILQ_INSERT_TAIL(&fstype_entries, fsle, next); - return 0; + if (strcmp(fsdriver, "local")) { + goto done; + } + if (!strcmp(sec_model, "passthrough")) { + fsle->fse.export_flags |= V9FS_SM_PASSTHROUGH; + } else if (!strcmp(sec_model, "mapped")) { + fsle->fse.export_flags |= V9FS_SM_MAPPED; + } else if (!strcmp(sec_model, "none")) { + fsle->fse.export_flags |= V9FS_SM_NONE; + } else { + fprintf(stderr, "Invalid security model %s specified, valid options are" + "\n\t [passthrough|mapped|none]\n", sec_model); + return -1; + } +done: + QTAILQ_INSERT_TAIL(&fsdriver_entries, fsle, next); + return 0; } -FsTypeEntry *get_fsdev_fsentry(char *id) +FsDriverEntry *get_fsdev_fsentry(char *id) { if (id) { - struct FsTypeListEntry *fsle; + struct FsDriverListEntry *fsle; - QTAILQ_FOREACH(fsle, &fstype_entries, next) { + QTAILQ_FOREACH(fsle, &fsdriver_entries, next) { if (strcmp(fsle->fse.fsdev_id, id) == 0) { return &fsle->fse; } diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h index a704043..8ef8473 100644 --- a/fsdev/qemu-fsdev.h +++ b/fsdev/qemu-fsdev.h @@ -13,7 +13,7 @@ #ifndef QEMU_FSDEV_H #define QEMU_FSDEV_H #include "qemu-option.h" -#include "hw/file-op-9p.h" +#include "file-op-9p.h" /* @@ -29,27 +29,29 @@ * ----------------- * etc */ -typedef struct FsTypeTable { +typedef struct FsDriverTable { const char *name; FileOperations *ops; -} FsTypeTable; +} FsDriverTable; /* * Structure to store the various fsdev's passed through command line. */ -typedef struct FsTypeEntry { +typedef struct FsDriverEntry { char *fsdev_id; char *path; - char *security_model; + int export_flags; FileOperations *ops; -} FsTypeEntry; +} FsDriverEntry; -typedef struct FsTypeListEntry { - FsTypeEntry fse; - QTAILQ_ENTRY(FsTypeListEntry) next; -} FsTypeListEntry; +typedef struct FsDriverListEntry { + FsDriverEntry fse; + QTAILQ_ENTRY(FsDriverListEntry) next; +} FsDriverListEntry; int qemu_fsdev_add(QemuOpts *opts); -FsTypeEntry *get_fsdev_fsentry(char *id); +FsDriverEntry *get_fsdev_fsentry(char *id); extern FileOperations local_ops; +extern FileOperations handle_ops; +extern FileOperations synth_ops; #endif diff --git a/gdbstub.c b/gdbstub.c index d6556c9..640cf4e 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -37,15 +37,29 @@ #define MAX_PACKET_LENGTH 4096 -#include "exec-all.h" +#include "cpu.h" #include "qemu_socket.h" #include "kvm.h" +#ifndef TARGET_CPU_MEMORY_RW_DEBUG +static inline int target_memory_rw_debug(CPUState *env, target_ulong addr, + uint8_t *buf, int len, int is_write) +{ + return cpu_memory_rw_debug(env, addr, buf, len, is_write); +} +#else +/* target_memory_rw_debug() defined in cpu.h */ +#endif enum { GDB_SIGNAL_0 = 0, GDB_SIGNAL_INT = 2, + GDB_SIGNAL_QUIT = 3, GDB_SIGNAL_TRAP = 5, + GDB_SIGNAL_ABRT = 6, + GDB_SIGNAL_ALRM = 14, + GDB_SIGNAL_IO = 23, + GDB_SIGNAL_XCPU = 24, GDB_SIGNAL_UNKNOWN = 143 }; @@ -314,7 +328,7 @@ static int get_char(GDBState *s) int ret; for(;;) { - ret = recv(s->fd, &ch, 1, 0); + ret = qemu_recv(s->fd, &ch, 1, 0); if (ret < 0) { if (errno == ECONNRESET) s->fd = -1; @@ -377,7 +391,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len) } } #else - qemu_chr_write(s->chr, buf, len); + qemu_chr_fe_write(s->chr, buf, len); #endif } @@ -719,7 +733,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) { if (gdb_has_xml) return 0; - GET_REG32(0); /* fpscr */ + GET_REG32(env->fpscr); } } } @@ -800,7 +814,11 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) if (n < 64) { /* fprs */ - GET_REG32(*((uint32_t *)&env->fpr[n - 32])); + if (n & 1) { + GET_REG32(env->fpr[(n - 32) / 2].l.lower); + } else { + GET_REG32(env->fpr[(n - 32) / 2].l.upper); + } } /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ switch (n) { @@ -817,15 +835,15 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) #else if (n < 64) { /* f0-f31 */ - GET_REG32(*((uint32_t *)&env->fpr[n - 32])); + if (n & 1) { + GET_REG32(env->fpr[(n - 32) / 2].l.lower); + } else { + GET_REG32(env->fpr[(n - 32) / 2].l.upper); + } } if (n < 80) { /* f32-f62 (double width, even numbers only) */ - uint64_t val; - - val = (uint64_t)*((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) << 32; - val |= *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]); - GET_REG64(val); + GET_REG64(env->fpr[(n - 32) / 2].ll); } switch (n) { case 80: GET_REGL(env->pc); @@ -864,7 +882,12 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) else if (n < 64) { /* fprs */ - *((uint32_t *)&env->fpr[n - 32]) = tmp; + /* f0-f31 */ + if (n & 1) { + env->fpr[(n - 32) / 2].l.lower = tmp; + } else { + env->fpr[(n - 32) / 2].l.upper = tmp; + } } else { /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ switch (n) { @@ -882,12 +905,16 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #else else if (n < 64) { /* f0-f31 */ - env->fpr[n] = ldfl_p(mem_buf); + tmp = ldl_p(mem_buf); + if (n & 1) { + env->fpr[(n - 32) / 2].l.lower = tmp; + } else { + env->fpr[(n - 32) / 2].l.upper = tmp; + } return 4; } else if (n < 80) { /* f32-f62 (double width, even numbers only) */ - *((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) = tmp >> 32; - *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]) = tmp; + env->fpr[(n - 32) / 2].ll = tmp; } else { switch (n) { case 80: env->pc = tmp; break; @@ -1100,10 +1127,6 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) env->active_fpu.fcr31 = tmp & 0xFF83FFFF; /* set rounding mode */ RESTORE_ROUNDING_MODE; -#ifndef CONFIG_SOFTFLOAT - /* no floating point exception for native float */ - SET_FP_ENABLE(env->active_fpu.fcr31, 0); -#endif break; case 71: env->active_fpu.fcr0 = tmp; break; } @@ -1431,7 +1454,11 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) /* XXX */ break; case S390_PC_REGNUM: GET_REGL(env->psw.addr); break; - case S390_CC_REGNUM: GET_REG32(env->cc); break; + case S390_CC_REGNUM: + env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, + env->cc_vr); + GET_REG32(env->cc_op); + break; } return 0; @@ -1457,11 +1484,173 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) /* XXX */ break; case S390_PC_REGNUM: env->psw.addr = tmpl; break; - case S390_CC_REGNUM: env->cc = tmp32; r=4; break; + case S390_CC_REGNUM: env->cc_op = tmp32; r=4; break; } return r; } +#elif defined (TARGET_LM32) + +#include "hw/lm32_pic.h" +#define NUM_CORE_REGS (32 + 7) + +static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + GET_REG32(env->regs[n]); + } else { + switch (n) { + case 32: + GET_REG32(env->pc); + break; + /* FIXME: put in right exception ID */ + case 33: + GET_REG32(0); + break; + case 34: + GET_REG32(env->eba); + break; + case 35: + GET_REG32(env->deba); + break; + case 36: + GET_REG32(env->ie); + break; + case 37: + GET_REG32(lm32_pic_get_im(env->pic_state)); + break; + case 38: + GET_REG32(lm32_pic_get_ip(env->pic_state)); + break; + } + } + return 0; +} + +static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + + if (n > NUM_CORE_REGS) { + return 0; + } + + tmp = ldl_p(mem_buf); + + if (n < 32) { + env->regs[n] = tmp; + } else { + switch (n) { + case 32: + env->pc = tmp; + break; + case 34: + env->eba = tmp; + break; + case 35: + env->deba = tmp; + break; + case 36: + env->ie = tmp; + break; + case 37: + lm32_pic_set_im(env->pic_state, tmp); + break; + case 38: + lm32_pic_set_ip(env->pic_state, tmp); + break; + } + } + return 4; +} +#elif defined(TARGET_XTENSA) + +/* Use num_core_regs to see only non-privileged registers in an unmodified gdb. + * Use num_regs to see all registers. gdb modification is required for that: + * reset bit 0 in the 'flags' field of the registers definitions in the + * gdb/xtensa-config.c inside gdb source tree or inside gdb overlay. + */ +#define NUM_CORE_REGS (env->config->gdb_regmap.num_regs) +#define num_g_regs NUM_CORE_REGS + +static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +{ + const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; + + if (n < 0 || n >= env->config->gdb_regmap.num_regs) { + return 0; + } + + switch (reg->type) { + case 9: /*pc*/ + GET_REG32(env->pc); + break; + + case 1: /*ar*/ + xtensa_sync_phys_from_window(env); + GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]); + break; + + case 2: /*SR*/ + GET_REG32(env->sregs[reg->targno & 0xff]); + break; + + case 3: /*UR*/ + GET_REG32(env->uregs[reg->targno & 0xff]); + break; + + case 8: /*a*/ + GET_REG32(env->regs[reg->targno & 0x0f]); + break; + + default: + qemu_log("%s from reg %d of unsupported type %d\n", + __func__, n, reg->type); + return 0; + } +} + +static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +{ + uint32_t tmp; + const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; + + if (n < 0 || n >= env->config->gdb_regmap.num_regs) { + return 0; + } + + tmp = ldl_p(mem_buf); + + switch (reg->type) { + case 9: /*pc*/ + env->pc = tmp; + break; + + case 1: /*ar*/ + env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp; + xtensa_sync_window_from_phys(env); + break; + + case 2: /*SR*/ + env->sregs[reg->targno & 0xff] = tmp; + break; + + case 3: /*UR*/ + env->uregs[reg->targno & 0xff] = tmp; + break; + + case 8: /*a*/ + env->regs[reg->targno & 0x0f] = tmp; + break; + + default: + qemu_log("%s to reg %d of unsupported type %d\n", + __func__, n, reg->type); + return 0; + } + + return 4; +} #else #define NUM_CORE_REGS 0 @@ -1478,7 +1667,9 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #endif +#if !defined(TARGET_XTENSA) static int num_g_regs = NUM_CORE_REGS; +#endif #ifdef GDB_CORE_XML /* Encode data using the encoding for 'x' packets. */ @@ -1575,6 +1766,7 @@ static int gdb_write_register(CPUState *env, uint8_t *mem_buf, int reg) return 0; } +#if !defined(TARGET_XTENSA) /* Register a supplemental set of CPU registers. If g_pos is nonzero it specifies the first register number and these registers are included in a standard "g" packet. Direction is relative to gdb, i.e. get_reg is @@ -1589,12 +1781,6 @@ void gdb_register_coprocessor(CPUState * env, GDBRegisterState **p; static int last_reg = NUM_CORE_REGS; - s = (GDBRegisterState *)qemu_mallocz(sizeof(GDBRegisterState)); - s->base_reg = last_reg; - s->num_regs = num_regs; - s->get_reg = get_reg; - s->set_reg = set_reg; - s->xml = xml; p = &env->gdb_regs; while (*p) { /* Check for duplicates. */ @@ -1602,6 +1788,14 @@ void gdb_register_coprocessor(CPUState * env, return; p = &(*p)->next; } + + s = g_new0(GDBRegisterState, 1); + s->base_reg = last_reg; + s->num_regs = num_regs; + s->get_reg = get_reg; + s->set_reg = set_reg; + s->xml = xml; + /* Add to end of list. */ last_reg += num_regs; *p = s; @@ -1614,6 +1808,7 @@ void gdb_register_coprocessor(CPUState * env, } } } +#endif #ifndef CONFIG_USER_ONLY static const int xlat_gdb_type[] = { @@ -1737,6 +1932,10 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) #elif defined (TARGET_S390X) cpu_synchronize_state(s->c_cpu); s->c_cpu->psw.addr = pc; +#elif defined (TARGET_LM32) + s->c_cpu->pc = pc; +#elif defined(TARGET_XTENSA) + s->c_cpu->pc = pc; #endif } @@ -1907,6 +2106,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'g': cpu_synchronize_state(s->g_cpu); + env = s->g_cpu; len = 0; for (addr = 0; addr < num_g_regs; addr++) { reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); @@ -1917,6 +2117,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'G': cpu_synchronize_state(s->g_cpu); + env = s->g_cpu; registers = mem_buf; len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); @@ -1932,7 +2133,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; len = strtoull(p, NULL, 16); - if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) { + if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) { put_packet (s, "E14"); } else { memtohex(buf, mem_buf, len); @@ -1947,10 +2148,11 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ':') p++; hextomem(mem_buf, p, len); - if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) + if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) { put_packet(s, "E14"); - else + } else { put_packet(s, "OK"); + } break; case 'p': /* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable. @@ -2113,7 +2315,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) hextomem(mem_buf, p + 5, len); len = len / 2; mem_buf[len++] = 0; - qemu_chr_read(s->mon_chr, mem_buf, len); + qemu_chr_be_write(s->mon_chr, mem_buf, len); put_packet(s, "OK"); break; } @@ -2186,7 +2388,7 @@ void gdb_set_stop_cpu(CPUState *env) } #ifndef CONFIG_USER_ONLY -static void gdb_vm_state_change(void *opaque, int running, int reason) +static void gdb_vm_state_change(void *opaque, int running, RunState state) { GDBState *s = gdbserver_state; CPUState *env = s->c_cpu; @@ -2194,14 +2396,11 @@ static void gdb_vm_state_change(void *opaque, int running, int reason) const char *type; int ret; - if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) || - s->state == RS_INACTIVE || s->state == RS_SYSCALL) + if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) { return; - - /* disable single step if it was enable */ - cpu_single_step(env, 0); - - if (reason == EXCP_DEBUG) { + } + switch (state) { + case RUN_STATE_DEBUG: if (env->watchpoint_hit) { switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) { case BP_MEM_READ: @@ -2218,17 +2417,44 @@ static void gdb_vm_state_change(void *opaque, int running, int reason) "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";", GDB_SIGNAL_TRAP, gdb_id(env), type, env->watchpoint_hit->vaddr); - put_packet(s, buf); env->watchpoint_hit = NULL; - return; + goto send_packet; } - tb_flush(env); + tb_flush(env); ret = GDB_SIGNAL_TRAP; - } else { + break; + case RUN_STATE_PAUSED: ret = GDB_SIGNAL_INT; + break; + case RUN_STATE_SHUTDOWN: + ret = GDB_SIGNAL_QUIT; + break; + case RUN_STATE_IO_ERROR: + ret = GDB_SIGNAL_IO; + break; + case RUN_STATE_WATCHDOG: + ret = GDB_SIGNAL_ALRM; + break; + case RUN_STATE_INTERNAL_ERROR: + ret = GDB_SIGNAL_ABRT; + break; + case RUN_STATE_SAVE_VM: + case RUN_STATE_RESTORE_VM: + return; + case RUN_STATE_FINISH_MIGRATE: + ret = GDB_SIGNAL_XCPU; + break; + default: + ret = GDB_SIGNAL_UNKNOWN; + break; } snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env)); + +send_packet: put_packet(s, buf); + + /* disable single step if it was enabled */ + cpu_single_step(env, 0); } #endif @@ -2252,7 +2478,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) gdb_current_syscall_cb = cb; s->state = RS_SYSCALL; #ifndef CONFIG_USER_ONLY - vm_stop(EXCP_DEBUG); + vm_stop(RUN_STATE_DEBUG); #endif s->state = RS_IDLE; va_start(va, fmt); @@ -2323,10 +2549,10 @@ static void gdb_read_byte(GDBState *s, int ch) if (ch != '$') return; } - if (vm_running) { + if (runstate_is_running()) { /* when the CPU is running, we cannot do anything except stop it when receiving a char */ - vm_stop(EXCP_INTERRUPT); + vm_stop(RUN_STATE_PAUSED); } else #endif { @@ -2394,7 +2620,7 @@ void gdb_exit(CPUState *env, int code) #ifndef CONFIG_USER_ONLY if (s->chr) { - qemu_chr_close(s->chr); + qemu_chr_delete(s->chr); } #endif } @@ -2501,7 +2727,7 @@ static void gdb_accept(void) val = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); - s = qemu_mallocz(sizeof(GDBState)); + s = g_malloc0(sizeof(GDBState)); s->c_cpu = first_cpu; s->g_cpu = first_cpu; s->fd = fd; @@ -2588,7 +2814,7 @@ static void gdb_chr_event(void *opaque, int event) { switch (event) { case CHR_EVENT_OPENED: - vm_stop(EXCP_INTERRUPT); + vm_stop(RUN_STATE_PAUSED); gdb_has_xml = 0; break; default: @@ -2628,8 +2854,9 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len) #ifndef _WIN32 static void gdb_sigterm_handler(int signal) { - if (vm_running) - vm_stop(EXCP_INTERRUPT); + if (runstate_is_running()) { + vm_stop(RUN_STATE_PAUSED); + } } #endif @@ -2658,7 +2885,7 @@ int gdbserver_start(const char *device) sigaction(SIGINT, &act, NULL); } #endif - chr = qemu_chr_open("gdb", device, NULL); + chr = qemu_chr_new("gdb", device, NULL); if (!chr) return -1; @@ -2668,18 +2895,18 @@ int gdbserver_start(const char *device) s = gdbserver_state; if (!s) { - s = qemu_mallocz(sizeof(GDBState)); + s = g_malloc0(sizeof(GDBState)); gdbserver_state = s; qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL); /* Initialize a monitor terminal for gdb */ - mon_chr = qemu_mallocz(sizeof(*mon_chr)); + mon_chr = g_malloc0(sizeof(*mon_chr)); mon_chr->chr_write = gdb_monitor_write; monitor_init(mon_chr, 0); } else { if (s->chr) - qemu_chr_close(s->chr); + qemu_chr_delete(s->chr); mon_chr = s->mon_chr; memset(s, 0, sizeof(GDBState)); } diff --git a/gen-icount.h b/gen-icount.h index 8879da6..5fb3829 100644 --- a/gen-icount.h +++ b/gen-icount.h @@ -29,7 +29,7 @@ static void gen_icount_end(TranslationBlock *tb, int num_insns) if (use_icount) { *icount_arg = num_insns; gen_set_label(icount_label); - tcg_gen_exit_tb((long)tb + 2); + tcg_gen_exit_tb((tcg_target_long)tb + 2); } } diff --git a/hmp-commands.hx b/hmp-commands.hx index 372bef4..089c1ac 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -43,7 +43,7 @@ ETEXI .params = "", .help = "quit the emulator", .user_print = monitor_user_noop, - .mhandler.cmd_new = do_quit, + .mhandler.cmd = hmp_quit, }, STEXI @@ -180,13 +180,12 @@ STEXI Output logs to @var{filename}. ETEXI -#ifdef CONFIG_SIMPLE_TRACE { .name = "trace-event", .args_type = "name:s,option:b", .params = "name on|off", .help = "changes status of a specific trace event", - .mhandler.cmd = do_change_trace_event_state, + .mhandler.cmd = do_trace_event_set_state, }, STEXI @@ -195,6 +194,7 @@ STEXI changes status of a trace event ETEXI +#if defined(CONFIG_TRACE_SIMPLE) { .name = "trace-file", .args_type = "op:s?,arg:F?", @@ -290,8 +290,7 @@ ETEXI .args_type = "", .params = "", .help = "stop emulation", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_stop, + .mhandler.cmd = hmp_stop, }, STEXI @@ -478,8 +477,7 @@ ETEXI .args_type = "", .params = "", .help = "reset the system", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_system_reset, + .mhandler.cmd = hmp_system_reset, }, STEXI @@ -494,8 +492,7 @@ ETEXI .args_type = "", .params = "", .help = "send system power down event", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_system_powerdown, + .mhandler.cmd = hmp_system_powerdown, }, STEXI @@ -590,8 +587,7 @@ ETEXI .args_type = "index:i", .params = "index", .help = "set the default CPU", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_cpu_set, + .mhandler.cmd = hmp_cpu, }, STEXI @@ -740,10 +736,11 @@ ETEXI #if defined(TARGET_I386) { .name = "nmi", - .args_type = "cpu_index:i", - .params = "cpu", - .help = "inject an NMI on the given CPU", - .mhandler.cmd = do_inject_nmi, + .args_type = "", + .params = "", + .help = "inject an NMI on all guest's CPUs", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_inject_nmi, }, #endif STEXI @@ -821,16 +818,13 @@ Set maximum tolerated downtime (in seconds) for migration. ETEXI { - .name = "snapshot_blkdev", - .args_type = "device:B,snapshot_file:s?,format:s?", - .params = "device [new-image-file] [format]", - .help = "initiates a live snapshot\n\t\t\t" - "of device. If a new image file is specified, the\n\t\t\t" - "new image file will become the new root image.\n\t\t\t" - "If format is specified, the snapshot file will\n\t\t\t" - "be created in that format. Otherwise the\n\t\t\t" - "snapshot will be internal! (currently unsupported)", - .mhandler.cmd_new = do_snapshot_blkdev, + .name = "client_migrate_info", + .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?", + .params = "protocol hostname port tls-port cert-subject", + .help = "send migration info to spice/vnc client", + .user_print = monitor_user_noop, + .mhandler.cmd_async = client_migrate_info, + .flags = MONITOR_CMD_ASYNC, }, STEXI @@ -842,12 +836,16 @@ new parameters (if specified) once the vm migration finished successfully. ETEXI { - .name = "client_migrate_info", - .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?", - .params = "protocol hostname port tls-port cert-subject", - .help = "send migration info to spice/vnc client", - .user_print = monitor_user_noop, - .mhandler.cmd_new = client_migrate_info, + .name = "snapshot_blkdev", + .args_type = "device:B,snapshot-file:s?,format:s?", + .params = "device [new-image-file] [format]", + .help = "initiates a live snapshot\n\t\t\t" + "of device. If a new image file is specified, the\n\t\t\t" + "new image file will become the new root image.\n\t\t\t" + "If format is specified, the snapshot file will\n\t\t\t" + "be created in that format. Otherwise the\n\t\t\t" + "snapshot will be internal! (currently unsupported)", + .mhandler.cmd_new = do_snapshot_blkdev, }, STEXI @@ -1305,13 +1303,11 @@ show i8259 (PIC) state @item info pci show emulated PCI device info @item info tlb -show virtual to physical memory mappings (i386, SH4 and SPARC only) +show virtual to physical memory mappings (i386, SH4, SPARC, and PPC only) @item info mem show the active virtual memory mappings (i386 only) @item info jit show dynamic compiler info -@item info kvm -show KVM information @item info numa show NUMA information @item info kvm @@ -1355,14 +1351,17 @@ show roms @end table ETEXI -#ifdef CONFIG_SIMPLE_TRACE +#ifdef CONFIG_TRACE_SIMPLE STEXI @item info trace show contents of trace buffer +ETEXI +#endif + +STEXI @item info trace-events show available trace events and their state ETEXI -#endif STEXI @end table diff --git a/host-utils.h b/host-utils.h index 0ddc176..821db93 100644 --- a/host-utils.h +++ b/host-utils.h @@ -23,7 +23,7 @@ * THE SOFTWARE. */ -#include "osdep.h" +#include "compiler.h" /* QEMU_GNUC_PREREQ */ #if defined(__x86_64__) #define __HAVE_FAST_MULU64__ diff --git a/hpet.h b/hpet.h deleted file mode 100644 index 754051a..0000000 --- a/hpet.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __HPET__ -#define __HPET__ 1 - - - -struct hpet_info { - unsigned long hi_ireqfreq; /* Hz */ - unsigned long hi_flags; /* information */ - unsigned short hi_hpet; - unsigned short hi_timer; -}; - -#define HPET_INFO_PERIODIC 0x0001 /* timer is periodic */ - -#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */ -#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */ -#define HPET_INFO _IOR('h', 0x03, struct hpet_info) -#define HPET_EPI _IO('h', 0x04) /* enable periodic */ -#define HPET_DPI _IO('h', 0x05) /* disable periodic */ -#define HPET_IRQFREQ _IOW('h', 0x6, unsigned long) /* IRQFREQ usec */ - -#endif /* !__HPET__ */ diff --git a/hppa-dis.c b/hppa-dis.c index 49f99c8..435da73 100644 --- a/hppa-dis.c +++ b/hppa-dis.c @@ -1645,7 +1645,7 @@ static const char *const fp_reg_names[] = typedef unsigned int CORE_ADDR; -/* Get at various relevent fields of an instruction word. */ +/* Get at various relevant fields of an instruction word. */ #define MASK_5 0x1f #define MASK_10 0x3ff @@ -1771,13 +1771,13 @@ static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" }; static void fput_reg (unsigned reg, disassemble_info *info) { - (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0"); + (*info->fprintf_func) (info->stream, "%s", reg ? reg_names[reg] : "r0"); } static void fput_fp_reg (unsigned reg, disassemble_info *info) { - (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0"); + (*info->fprintf_func) (info->stream, "%s", reg ? fp_reg_names[reg] : "fr0"); } static void @@ -1794,7 +1794,7 @@ fput_fp_reg_r (unsigned reg, disassemble_info *info) static void fput_creg (unsigned reg, disassemble_info *info) { - (*info->fprintf_func) (info->stream, control_reg[reg]); + (*info->fprintf_func) (info->stream, "%s", control_reg[reg]); } /* Print constants with sign. */ diff --git a/hppa.ld b/hppa.ld index 9a4b22c..3555b3e 100644 --- a/hppa.ld +++ b/hppa.ld @@ -75,36 +75,34 @@ SECTIONS .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } .PARISC.unwind : { *(.PARISC.unwind) } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. */ . = ALIGN(0x10000) + (. & (0x10000 - 1)); /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } /* Thread Local Storage sections */ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } .preinit_array : { - PROVIDE_HIDDEN (__preinit_array_start = .); + PROVIDE (__preinit_array_start = .); KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE (__preinit_array_end = .); } .init_array : { - PROVIDE_HIDDEN (__init_array_start = .); + PROVIDE (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE (__init_array_end = .); } .fini_array : { - PROVIDE_HIDDEN (__fini_array_start = .); + PROVIDE (__fini_array_start = .); KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE (__fini_array_end = .); } .ctors : { diff --git a/hw/3D.h b/hw/3D.h deleted file mode 100644 index bd38e3c..0000000 --- a/hw/3D.h +++ /dev/null @@ -1,37 +0,0 @@ -#include "hw.h" -#include "pc.h" -#include "pci.h" - -#if defined (DEBUG_ACCEL) -# define DEBUG_PRINT(x) do { printf x ; } while (0) -#else -# define DEBUG_PRINT(x) -#endif - -#define PCI_VENDOR_ID_SAMSUNG 0x144d -#define PCI_DEVICE_ID_VIRTIO_OPENGL 0x1004 - -#define FUNC 0x00 -#define PID 0x01 -#define TRS 0x02 -#define IA 0x03 -#define IAS 0x04 - -#define RUN_OPENGL 0x10 - -typedef struct AccelState { - PCIDevice dev; - int ret; - int Accel_mmio_io_addr; - uint32_t function_number; - uint32_t pid; - uint32_t target_ret_string; - uint32_t in_args; - uint32_t in_args_size; -} AccelState; - -uint32_t fn; -uint32_t p; -uint32_t trs; -uint32_t ia; -uint32_t ias; diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c index b5e5328..6f108f4 100644 --- a/hw/a9mpcore.c +++ b/hw/a9mpcore.c @@ -4,7 +4,7 @@ * Copyright (c) 2009 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ /* 64 external IRQ lines. */ diff --git a/hw/ac97.c b/hw/ac97.c index d71072d..557f7b0 100644 --- a/hw/ac97.c +++ b/hw/ac97.c @@ -18,6 +18,7 @@ #include "audiodev.h" #include "audio/audio.h" #include "pci.h" +#include "dma.h" enum { AC97_Reset = 0x00, @@ -50,6 +51,8 @@ enum { AC97_6Ch_Vol_C_LFE_Mute = 0x36, AC97_6Ch_Vol_L_R_Surround_Mute = 0x38, AC97_Vendor_Reserved = 0x58, + AC97_Sigmatel_Analog = 0x6c, /* We emulate a Sigmatel codec */ + AC97_Sigmatel_Dac2Invert = 0x6e, /* We emulate a Sigmatel codec */ AC97_Vendor_ID1 = 0x7c, AC97_Vendor_ID2 = 0x7e }; @@ -114,7 +117,6 @@ enum { #define EACS_VRA 1 #define EACS_VRM 8 -#define VOL_MASK 0x1f #define MUTE_SHIFT 15 #define REC_MASK 7 @@ -149,6 +151,7 @@ typedef struct AC97BusMasterRegs { typedef struct AC97LinkState { PCIDevice dev; QEMUSoundCard card; + uint32_t use_broken_id; uint32_t glob_cnt; uint32_t glob_sta; uint32_t cas; @@ -160,8 +163,9 @@ typedef struct AC97LinkState { SWVoiceIn *voice_mc; int invalid_freq[3]; uint8_t silence[128]; - uint32_t base[2]; int bup_flag; + MemoryRegion io_nam; + MemoryRegion io_nabm; } AC97LinkState; enum { @@ -223,7 +227,7 @@ static void fetch_bd (AC97LinkState *s, AC97BusMasterRegs *r) { uint8_t b[8]; - cpu_physical_memory_read (r->bdbar + r->civ * 8, b, 8); + pci_dma_read (&s->dev, r->bdbar + r->civ * 8, b, 8); r->bd_valid = 1; r->bd.addr = le32_to_cpu (*(uint32_t *) &b[0]) & ~3; r->bd.ctl_len = le32_to_cpu (*(uint32_t *) &b[4]); @@ -337,7 +341,7 @@ static uint16_t mixer_load (AC97LinkState *s, uint32_t i) uint16_t val = 0xffff; if (i + 2 > sizeof (s->mixer_data)) { - dolog ("mixer_store: index %d out of bounds %zd\n", + dolog ("mixer_load: index %d out of bounds %zd\n", i, sizeof (s->mixer_data)); } else { @@ -431,83 +435,65 @@ static void reset_voices (AC97LinkState *s, uint8_t active[LAST_INDEX]) AUD_set_active_in (s->voice_mc, active[MC_INDEX]); } -#ifdef USE_MIXER -static void set_volume (AC97LinkState *s, int index, - audmixerctl_t mt, uint32_t val) +static void get_volume (uint16_t vol, uint16_t mask, int inverse, + int *mute, uint8_t *lvol, uint8_t *rvol) { - int mute = (val >> MUTE_SHIFT) & 1; - uint8_t rvol = VOL_MASK - (val & VOL_MASK); - uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK); - rvol = 255 * rvol / VOL_MASK; - lvol = 255 * lvol / VOL_MASK; - -#ifdef SOFT_VOLUME - if (index == AC97_Master_Volume_Mute) { - AUD_set_volume_out (s->voice_po, mute, lvol, rvol); - } - else { - AUD_set_volume (mt, &mute, &lvol, &rvol); - } -#else - AUD_set_volume (mt, &mute, &lvol, &rvol); -#endif + *mute = (vol >> MUTE_SHIFT) & 1; + *rvol = (255 * (vol & mask)) / mask; + *lvol = (255 * ((vol >> 8) & mask)) / mask; - rvol = VOL_MASK - ((VOL_MASK * rvol) / 255); - lvol = VOL_MASK - ((VOL_MASK * lvol) / 255); - mixer_store (s, index, val); + if (inverse) { + *rvol = 255 - *rvol; + *lvol = 255 - *lvol; + } } -static audrecsource_t ac97_to_aud_record_source (uint8_t i) +static void update_combined_volume_out (AC97LinkState *s) { - switch (i) { - case REC_MIC: - return AUD_REC_MIC; - - case REC_CD: - return AUD_REC_CD; + uint8_t lvol, rvol, plvol, prvol; + int mute, pmute; - case REC_VIDEO: - return AUD_REC_VIDEO; + get_volume (mixer_load (s, AC97_Master_Volume_Mute), 0x3f, 1, + &mute, &lvol, &rvol); + get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x1f, 1, + &pmute, &plvol, &prvol); - case REC_AUX: - return AUD_REC_AUX; + mute = mute | pmute; + lvol = (lvol * plvol) / 255; + rvol = (rvol * prvol) / 255; - case REC_LINE_IN: - return AUD_REC_LINE_IN; - - case REC_PHONE: - return AUD_REC_PHONE; - - default: - dolog ("Unknown record source %d, using MIC\n", i); - return AUD_REC_MIC; - } + AUD_set_volume_out (s->voice_po, mute, lvol, rvol); } -static uint8_t aud_to_ac97_record_source (audrecsource_t rs) +static void update_volume_in (AC97LinkState *s) { - switch (rs) { - case AUD_REC_MIC: - return REC_MIC; + uint8_t lvol, rvol; + int mute; - case AUD_REC_CD: - return REC_CD; + get_volume (mixer_load (s, AC97_Record_Gain_Mute), 0x0f, 0, + &mute, &lvol, &rvol); - case AUD_REC_VIDEO: - return REC_VIDEO; - - case AUD_REC_AUX: - return REC_AUX; - - case AUD_REC_LINE_IN: - return REC_LINE_IN; - - case AUD_REC_PHONE: - return REC_PHONE; + AUD_set_volume_in (s->voice_pi, mute, lvol, rvol); +} - default: - dolog ("Unknown audio recording source %d using MIC\n", rs); - return REC_MIC; +static void set_volume (AC97LinkState *s, int index, uint32_t val) +{ + switch (index) { + case AC97_Master_Volume_Mute: + val &= 0xbf3f; + mixer_store (s, index, val); + update_combined_volume_out (s); + break; + case AC97_PCM_Out_Volume_Mute: + val &= 0x9f1f; + mixer_store (s, index, val); + update_combined_volume_out (s); + break; + case AC97_Record_Gain_Mute: + val &= 0x8f0f; + mixer_store (s, index, val); + update_volume_in (s); + break; } } @@ -515,14 +501,8 @@ static void record_select (AC97LinkState *s, uint32_t val) { uint8_t rs = val & REC_MASK; uint8_t ls = (val >> 8) & REC_MASK; - audrecsource_t ars = ac97_to_aud_record_source (rs); - audrecsource_t als = ac97_to_aud_record_source (ls); - AUD_set_record_source (&als, &ars); - rs = aud_to_ac97_record_source (ars); - ls = aud_to_ac97_record_source (als); mixer_store (s, AC97_Record_Select, rs | (ls << 8)); } -#endif static void mixer_reset (AC97LinkState *s) { @@ -532,14 +512,17 @@ static void mixer_reset (AC97LinkState *s) memset (s->mixer_data, 0, sizeof (s->mixer_data)); memset (active, 0, sizeof (active)); mixer_store (s, AC97_Reset , 0x0000); /* 6940 */ - mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x8000); + mixer_store (s, AC97_Headphone_Volume_Mute , 0x0000); + mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x0000); + mixer_store (s, AC97_Master_Tone_RL, 0x0000); mixer_store (s, AC97_PC_BEEP_Volume_Mute , 0x0000); - - mixer_store (s, AC97_Phone_Volume_Mute , 0x8008); - mixer_store (s, AC97_Mic_Volume_Mute , 0x8008); - mixer_store (s, AC97_CD_Volume_Mute , 0x8808); - mixer_store (s, AC97_Aux_Volume_Mute , 0x8808); - mixer_store (s, AC97_Record_Gain_Mic_Mute , 0x8000); + mixer_store (s, AC97_Phone_Volume_Mute , 0x0000); + mixer_store (s, AC97_Mic_Volume_Mute , 0x0000); + mixer_store (s, AC97_Line_In_Volume_Mute , 0x0000); + mixer_store (s, AC97_CD_Volume_Mute , 0x0000); + mixer_store (s, AC97_Video_Volume_Mute , 0x0000); + mixer_store (s, AC97_Aux_Volume_Mute , 0x0000); + mixer_store (s, AC97_Record_Gain_Mic_Mute , 0x0000); mixer_store (s, AC97_General_Purpose , 0x0000); mixer_store (s, AC97_3D_Control , 0x0000); mixer_store (s, AC97_Powerdown_Ctrl_Stat , 0x000f); @@ -558,12 +541,11 @@ static void mixer_reset (AC97LinkState *s) mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80); mixer_store (s, AC97_MIC_ADC_Rate , 0xbb80); -#ifdef USE_MIXER record_select (s, 0); - set_volume (s, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME , 0x8000); - set_volume (s, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM , 0x8808); - set_volume (s, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808); -#endif + set_volume (s, AC97_Master_Volume_Mute, 0x8000); + set_volume (s, AC97_PCM_Out_Volume_Mute, 0x8808); + set_volume (s, AC97_Record_Gain_Mute, 0x8808); + reset_voices (s, active); } @@ -583,7 +565,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; uint32_t val = ~0U; - uint32_t index = addr - s->base[0]; + uint32_t index = addr; s->cas = 0; val = mixer_load (s, index); return val; @@ -611,31 +593,25 @@ static void nam_writeb (void *opaque, uint32_t addr, uint32_t val) static void nam_writew (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; - uint32_t index = addr - s->base[0]; + uint32_t index = addr; s->cas = 0; switch (index) { case AC97_Reset: mixer_reset (s); break; case AC97_Powerdown_Ctrl_Stat: - val &= ~0xf; + val &= ~0x800f; val |= mixer_load (s, index) & 0xf; mixer_store (s, index, val); break; -#ifdef USE_MIXER - case AC97_Master_Volume_Mute: - set_volume (s, index, AUD_MIXER_VOLUME, val); - break; case AC97_PCM_Out_Volume_Mute: - set_volume (s, index, AUD_MIXER_PCM, val); - break; - case AC97_Line_In_Volume_Mute: - set_volume (s, index, AUD_MIXER_LINE_IN, val); + case AC97_Master_Volume_Mute: + case AC97_Record_Gain_Mute: + set_volume (s, index, val); break; case AC97_Record_Select: record_select (s, val); break; -#endif case AC97_Vendor_ID1: case AC97_Vendor_ID2: dolog ("Attempt to write vendor ID to %#x\n", val); @@ -692,6 +668,23 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val) val); } break; + case AC97_Headphone_Volume_Mute: + case AC97_Master_Volume_Mono_Mute: + case AC97_Master_Tone_RL: + case AC97_PC_BEEP_Volume_Mute: + case AC97_Phone_Volume_Mute: + case AC97_Mic_Volume_Mute: + case AC97_Line_In_Volume_Mute: + case AC97_CD_Volume_Mute: + case AC97_Video_Volume_Mute: + case AC97_Aux_Volume_Mute: + case AC97_Record_Gain_Mic_Mute: + case AC97_General_Purpose: + case AC97_3D_Control: + case AC97_Sigmatel_Analog: + case AC97_Sigmatel_Dac2Invert: + /* None of the features in these regs are emulated, so they are RO */ + break; default: dolog ("U nam writew %#x <- %#x\n", addr, val); mixer_store (s, index, val); @@ -714,7 +707,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; uint32_t val = ~0U; switch (index) { @@ -769,7 +762,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; uint32_t val = ~0U; switch (index) { @@ -798,7 +791,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; uint32_t val = ~0U; switch (index) { @@ -848,7 +841,7 @@ static void nabm_writeb (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; switch (index) { case PI_LVI: case PO_LVI: @@ -904,7 +897,7 @@ static void nabm_writew (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; switch (index) { case PI_SR: case PO_SR: @@ -924,7 +917,7 @@ static void nabm_writel (void *opaque, uint32_t addr, uint32_t val) { AC97LinkState *s = opaque; AC97BusMasterRegs *r = NULL; - uint32_t index = addr - s->base[1]; + uint32_t index = addr; switch (index) { case PI_BDBAR: case PO_BDBAR: @@ -972,7 +965,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r, while (temp) { int copied; to_copy = audio_MIN (temp, sizeof (tmpbuf)); - cpu_physical_memory_read (addr, tmpbuf, to_copy); + pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied = AUD_write (s->voice_po, tmpbuf, to_copy); dolog ("write_audio max=%x to_copy=%x copied=%x\n", max, to_copy, copied); @@ -1001,8 +994,6 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r, static void write_bup (AC97LinkState *s, int elapsed) { - int written = 0; - dolog ("write_bup\n"); if (!(s->bup_flag & BUP_SET)) { if (s->bup_flag & BUP_LAST) { @@ -1026,7 +1017,6 @@ static void write_bup (AC97LinkState *s, int elapsed) return; temp -= copied; elapsed -= copied; - written += copied; } } } @@ -1056,7 +1046,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r, *stop = 1; break; } - cpu_physical_memory_write (addr, tmpbuf, acquired); + pci_dma_write (&s->dev, addr, tmpbuf, acquired); temp -= acquired; addr += acquired; nread += acquired; @@ -1069,7 +1059,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r, static void transfer_audio (AC97LinkState *s, int index, int elapsed) { AC97BusMasterRegs *r = &s->bm_regs[index]; - int written = 0, stop = 0; + int stop = 0; if (s->invalid_freq[index]) { AUD_log ("ac97", "attempt to use voice %d with invalid frequency %d\n", @@ -1114,7 +1104,6 @@ static void transfer_audio (AC97LinkState *s, int index, int elapsed) switch (index) { case PO_INDEX: temp = write_audio (s, r, elapsed, &stop); - written += temp; elapsed -= temp; r->picb -= (temp >> 1); break; @@ -1192,14 +1181,14 @@ static int ac97_post_load (void *opaque, int version_id) uint8_t active[LAST_INDEX]; AC97LinkState *s = opaque; -#ifdef USE_MIXER record_select (s, mixer_load (s, AC97_Record_Select)); -#define V_(a, b) set_volume (s, a, b, mixer_load (s, a)) - V_ (AC97_Master_Volume_Mute, AUD_MIXER_VOLUME); - V_ (AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM); - V_ (AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN); -#undef V_ -#endif + set_volume (s, AC97_Master_Volume_Mute, + mixer_load (s, AC97_Master_Volume_Mute)); + set_volume (s, AC97_PCM_Out_Volume_Mute, + mixer_load (s, AC97_PCM_Out_Volume_Mute)); + set_volume (s, AC97_Record_Gain_Mute, + mixer_load (s, AC97_Record_Gain_Mute)); + active[PI_INDEX] = !!(s->bm_regs[PI_INDEX].cr & CR_RPBM); active[PO_INDEX] = !!(s->bm_regs[PO_INDEX].cr & CR_RPBM); active[MC_INDEX] = !!(s->bm_regs[MC_INDEX].cr & CR_RPBM); @@ -1234,31 +1223,33 @@ static const VMStateDescription vmstate_ac97 = { } }; -static void ac97_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev); - PCIDevice *d = &s->dev; - - if (!region_num) { - s->base[0] = addr; - register_ioport_read (addr, 256 * 1, 1, nam_readb, d); - register_ioport_read (addr, 256 * 2, 2, nam_readw, d); - register_ioport_read (addr, 256 * 4, 4, nam_readl, d); - register_ioport_write (addr, 256 * 1, 1, nam_writeb, d); - register_ioport_write (addr, 256 * 2, 2, nam_writew, d); - register_ioport_write (addr, 256 * 4, 4, nam_writel, d); - } - else { - s->base[1] = addr; - register_ioport_read (addr, 64 * 1, 1, nabm_readb, d); - register_ioport_read (addr, 64 * 2, 2, nabm_readw, d); - register_ioport_read (addr, 64 * 4, 4, nabm_readl, d); - register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d); - register_ioport_write (addr, 64 * 2, 2, nabm_writew, d); - register_ioport_write (addr, 64 * 4, 4, nabm_writel, d); - } -} +static const MemoryRegionPortio nam_portio[] = { + { 0, 256 * 1, 1, .read = nam_readb, }, + { 0, 256 * 2, 2, .read = nam_readw, }, + { 0, 256 * 4, 4, .read = nam_readl, }, + { 0, 256 * 1, 1, .write = nam_writeb, }, + { 0, 256 * 2, 2, .write = nam_writew, }, + { 0, 256 * 4, 4, .write = nam_writel, }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionOps ac97_io_nam_ops = { + .old_portio = nam_portio, +}; + +static const MemoryRegionPortio nabm_portio[] = { + { 0, 64 * 1, 1, .read = nabm_readb, }, + { 0, 64 * 2, 2, .read = nabm_readw, }, + { 0, 64 * 4, 4, .read = nabm_readl, }, + { 0, 64 * 1, 1, .write = nabm_writeb, }, + { 0, 64 * 2, 2, .write = nabm_writew, }, + { 0, 64 * 4, 4, .write = nabm_writel, }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps ac97_io_nabm_ops = { + .old_portio = nabm_portio, +}; static void ac97_on_reset (void *opaque) { @@ -1281,9 +1272,6 @@ static int ac97_initfn (PCIDevice *dev) AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev); uint8_t *c = s->dev.config; - pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */ - pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */ - /* TODO: no need to override */ c[PCI_COMMAND] = 0x00; /* pcicmd pci command rw, ro */ c[PCI_COMMAND + 1] = 0x00; @@ -1292,9 +1280,7 @@ static int ac97_initfn (PCIDevice *dev) c[PCI_STATUS] = PCI_STATUS_FAST_BACK; /* pcists pci status rwc, ro */ c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8; - c[PCI_REVISION_ID] = 0x01; /* rid revision ro */ c[PCI_CLASS_PROG] = 0x00; /* pi programming interface ro */ - pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO); /* ro */ /* TODO set when bar is registered. no need to override. */ /* nabmar native audio mixer base address rw */ @@ -1310,25 +1296,35 @@ static int ac97_initfn (PCIDevice *dev) c[PCI_BASE_ADDRESS_0 + 6] = 0x00; c[PCI_BASE_ADDRESS_0 + 7] = 0x00; - c[PCI_SUBSYSTEM_VENDOR_ID] = 0x86; /* svid subsystem vendor id rwo */ - c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x80; - - c[PCI_SUBSYSTEM_ID] = 0x00; /* sid subsystem id rwo */ - c[PCI_SUBSYSTEM_ID + 1] = 0x00; + if (s->use_broken_id) { + c[PCI_SUBSYSTEM_VENDOR_ID] = 0x86; + c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x80; + c[PCI_SUBSYSTEM_ID] = 0x00; + c[PCI_SUBSYSTEM_ID + 1] = 0x00; + } c[PCI_INTERRUPT_LINE] = 0x00; /* intr_ln interrupt line rw */ - /* TODO: RST# value should be 0. */ c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */ - pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO, - ac97_map); - pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, ac97_map); + memory_region_init_io (&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024); + memory_region_init_io (&s->io_nabm, &ac97_io_nabm_ops, s, "ac97-nabm", 256); + pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam); + pci_register_bar (&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm); qemu_register_reset (ac97_on_reset, s); AUD_register_card ("ac97", &s->card); ac97_on_reset (s); return 0; } +static int ac97_exitfn (PCIDevice *dev) +{ + AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev); + + memory_region_destroy (&s->io_nam); + memory_region_destroy (&s->io_nabm); + return 0; +} + int ac97_init (PCIBus *bus) { pci_create_simple (bus, -1, "AC97"); @@ -1341,6 +1337,15 @@ static PCIDeviceInfo ac97_info = { .qdev.size = sizeof (AC97LinkState), .qdev.vmsd = &vmstate_ac97, .init = ac97_initfn, + .exit = ac97_exitfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82801AA_5, + .revision = 0x01, + .class_id = PCI_CLASS_MULTIMEDIA_AUDIO, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0), + DEFINE_PROP_END_OF_LIST(), + } }; static void ac97_register (void) diff --git a/hw/acpi.c b/hw/acpi.c index 8071e7b..1cf35e1 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -15,22 +15,34 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see */ +#include "sysemu.h" #include "hw.h" #include "pc.h" #include "acpi.h" -struct acpi_table_header -{ - char signature [4]; /* ACPI signature (4 ASCII characters) */ +struct acpi_table_header { + uint16_t _length; /* our length, not actual part of the hdr */ + /* XXX why we have 2 length fields here? */ + char sig[4]; /* ACPI signature (4 ASCII characters) */ uint32_t length; /* Length of table, in bytes, including header */ uint8_t revision; /* ACPI Specification minor version # */ uint8_t checksum; /* To make sum of entire table == 0 */ - char oem_id [6]; /* OEM identification */ - char oem_table_id [8]; /* OEM table identification */ + char oem_id[6]; /* OEM identification */ + char oem_table_id[8]; /* OEM table identification */ uint32_t oem_revision; /* OEM revision number */ - char asl_compiler_id [4]; /* ASL compiler vendor ID */ + char asl_compiler_id[4]; /* ASL compiler vendor ID */ uint32_t asl_compiler_revision; /* ASL compiler revision number */ -} __attribute__((packed)); +} QEMU_PACKED; + +#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header) +#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */ + +static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] = + "\0\0" /* fake _length (2) */ + "QEMU\0\0\0\0\1\0" /* sig (4), len(4), revno (1), csum (1) */ + "QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */ + "QEMU\1\0\0\0" /* ASL compiler ID (4), version (4) */ + ; char *acpi_tables; size_t acpi_tables_len; @@ -39,161 +51,392 @@ static int acpi_checksum(const uint8_t *data, int len) { int sum, i; sum = 0; - for(i = 0; i < len; i++) + for (i = 0; i < len; i++) { sum += data[i]; + } return (-sum) & 0xff; } +/* like strncpy() but zero-fills the tail of destination */ +static void strzcpy(char *dst, const char *src, size_t size) +{ + size_t len = strlen(src); + if (len >= size) { + len = size; + } else { + memset(dst + len, 0, size - len); + } + memcpy(dst, src, len); +} + +/* XXX fixme: this function uses obsolete argument parsing interface */ int acpi_table_add(const char *t) { - static const char *dfl_id = "QEMUQEMU"; char buf[1024], *p, *f; - struct acpi_table_header acpi_hdr; unsigned long val; - uint32_t length; - struct acpi_table_header *acpi_hdr_p; - size_t off; + size_t len, start, allen; + bool has_header; + int changed; + int r; + struct acpi_table_header hdr; - memset(&acpi_hdr, 0, sizeof(acpi_hdr)); - - if (get_param_value(buf, sizeof(buf), "sig", t)) { - strncpy(acpi_hdr.signature, buf, 4); + r = 0; + r |= get_param_value(buf, sizeof(buf), "data", t) ? 1 : 0; + r |= get_param_value(buf, sizeof(buf), "file", t) ? 2 : 0; + switch (r) { + case 0: + buf[0] = '\0'; + /* fallthrough for default behavior */ + case 1: + has_header = false; + break; + case 2: + has_header = true; + break; + default: + fprintf(stderr, "acpitable: both data and file are specified\n"); + return -1; + } + + if (!acpi_tables) { + allen = sizeof(uint16_t); + acpi_tables = g_malloc0(allen); } else { - strncpy(acpi_hdr.signature, dfl_id, 4); + allen = acpi_tables_len; + } + + start = allen; + acpi_tables = g_realloc(acpi_tables, start + ACPI_TABLE_HDR_SIZE); + allen += has_header ? ACPI_TABLE_PFX_SIZE : ACPI_TABLE_HDR_SIZE; + + /* now read in the data files, reallocating buffer as needed */ + + for (f = strtok(buf, ":"); f; f = strtok(NULL, ":")) { + int fd = open(f, O_RDONLY); + + if (fd < 0) { + fprintf(stderr, "can't open file %s: %s\n", f, strerror(errno)); + return -1; + } + + for (;;) { + char data[8192]; + r = read(fd, data, sizeof(data)); + if (r == 0) { + break; + } else if (r > 0) { + acpi_tables = g_realloc(acpi_tables, allen + r); + memcpy(acpi_tables + allen, data, r); + allen += r; + } else if (errno != EINTR) { + fprintf(stderr, "can't read file %s: %s\n", + f, strerror(errno)); + close(fd); + return -1; + } + } + + close(fd); + } + + /* now fill in the header fields */ + + f = acpi_tables + start; /* start of the table */ + changed = 0; + + /* copy the header to temp place to align the fields */ + memcpy(&hdr, has_header ? f : dfl_hdr, ACPI_TABLE_HDR_SIZE); + + /* length of the table minus our prefix */ + len = allen - start - ACPI_TABLE_PFX_SIZE; + + hdr._length = cpu_to_le16(len); + + if (get_param_value(buf, sizeof(buf), "sig", t)) { + strzcpy(hdr.sig, buf, sizeof(hdr.sig)); + ++changed; + } + + /* length of the table including header, in bytes */ + if (has_header) { + /* check if actual length is correct */ + val = le32_to_cpu(hdr.length); + if (val != len) { + fprintf(stderr, + "warning: acpitable has wrong length," + " header says %lu, actual size %zu bytes\n", + val, len); + ++changed; + } } + /* we may avoid putting length here if has_header is true */ + hdr.length = cpu_to_le32(len); + if (get_param_value(buf, sizeof(buf), "rev", t)) { - val = strtoul(buf, &p, 10); - if (val > 255 || *p != '\0') - goto out; - } else { - val = 1; + val = strtoul(buf, &p, 0); + if (val > 255 || *p) { + fprintf(stderr, "acpitable: \"rev=%s\" is invalid\n", buf); + return -1; + } + hdr.revision = (uint8_t)val; + ++changed; } - acpi_hdr.revision = (int8_t)val; if (get_param_value(buf, sizeof(buf), "oem_id", t)) { - strncpy(acpi_hdr.oem_id, buf, 6); - } else { - strncpy(acpi_hdr.oem_id, dfl_id, 6); + strzcpy(hdr.oem_id, buf, sizeof(hdr.oem_id)); + ++changed; } if (get_param_value(buf, sizeof(buf), "oem_table_id", t)) { - strncpy(acpi_hdr.oem_table_id, buf, 8); - } else { - strncpy(acpi_hdr.oem_table_id, dfl_id, 8); + strzcpy(hdr.oem_table_id, buf, sizeof(hdr.oem_table_id)); + ++changed; } if (get_param_value(buf, sizeof(buf), "oem_rev", t)) { - val = strtol(buf, &p, 10); - if(*p != '\0') - goto out; - } else { - val = 1; + val = strtol(buf, &p, 0); + if (*p) { + fprintf(stderr, "acpitable: \"oem_rev=%s\" is invalid\n", buf); + return -1; + } + hdr.oem_revision = cpu_to_le32(val); + ++changed; } - acpi_hdr.oem_revision = cpu_to_le32(val); if (get_param_value(buf, sizeof(buf), "asl_compiler_id", t)) { - strncpy(acpi_hdr.asl_compiler_id, buf, 4); - } else { - strncpy(acpi_hdr.asl_compiler_id, dfl_id, 4); + strzcpy(hdr.asl_compiler_id, buf, sizeof(hdr.asl_compiler_id)); + ++changed; } if (get_param_value(buf, sizeof(buf), "asl_compiler_rev", t)) { - val = strtol(buf, &p, 10); - if(*p != '\0') - goto out; - } else { - val = 1; + val = strtol(buf, &p, 0); + if (*p) { + fprintf(stderr, "acpitable: \"%s=%s\" is invalid\n", + "asl_compiler_rev", buf); + return -1; + } + hdr.asl_compiler_revision = cpu_to_le32(val); + ++changed; } - acpi_hdr.asl_compiler_revision = cpu_to_le32(val); - - if (!get_param_value(buf, sizeof(buf), "data", t)) { - buf[0] = '\0'; + + if (!has_header && !changed) { + fprintf(stderr, "warning: acpitable: no table headers are specified\n"); } - length = sizeof(acpi_hdr); - f = buf; - while (buf[0]) { - struct stat s; - char *n = strchr(f, ':'); - if (n) - *n = '\0'; - if(stat(f, &s) < 0) { - fprintf(stderr, "Can't stat file '%s': %s\n", f, strerror(errno)); - goto out; - } - length += s.st_size; - if (!n) - break; - *n = ':'; - f = n + 1; + /* now calculate checksum of the table, complete with the header */ + /* we may as well leave checksum intact if has_header is true */ + /* alternatively there may be a way to set cksum to a given value */ + hdr.checksum = 0; /* for checksum calculation */ + + /* put header back */ + memcpy(f, &hdr, sizeof(hdr)); + + if (changed || !has_header || 1) { + ((struct acpi_table_header *)f)->checksum = + acpi_checksum((uint8_t *)f + ACPI_TABLE_PFX_SIZE, len); } - if (!acpi_tables) { - acpi_tables_len = sizeof(uint16_t); - acpi_tables = qemu_mallocz(acpi_tables_len); - } - acpi_tables = qemu_realloc(acpi_tables, - acpi_tables_len + sizeof(uint16_t) + length); - p = acpi_tables + acpi_tables_len; - acpi_tables_len += sizeof(uint16_t) + length; - - *(uint16_t*)p = cpu_to_le32(length); - p += sizeof(uint16_t); - memcpy(p, &acpi_hdr, sizeof(acpi_hdr)); - off = sizeof(acpi_hdr); - - f = buf; - while (buf[0]) { - struct stat s; - int fd; - char *n = strchr(f, ':'); - if (n) - *n = '\0'; - fd = open(f, O_RDONLY); - - if(fd < 0) - goto out; - if(fstat(fd, &s) < 0) { - close(fd); - goto out; - } + /* increase number of tables */ + (*(uint16_t *)acpi_tables) = + cpu_to_le32(le32_to_cpu(*(uint16_t *)acpi_tables) + 1); - /* off < length is necessary because file size can be changed - under our foot */ - while(s.st_size && off < length) { - int r; - r = read(fd, p + off, s.st_size); - if (r > 0) { - off += r; - s.st_size -= r; - } else if ((r < 0 && errno != EINTR) || r == 0) { - close(fd); - goto out; - } - } + acpi_tables_len = allen; + return 0; - close(fd); - if (!n) +} + +/* ACPI PM1a EVT */ +uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time) +{ + int64_t d = acpi_pm_tmr_get_clock(); + if (d >= overflow_time) { + pm1->sts |= ACPI_BITMASK_TIMER_STATUS; + } + return pm1->sts; +} + +void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val) +{ + uint16_t pm1_sts = acpi_pm1_evt_get_sts(pm1, tmr->overflow_time); + if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { + /* if TMRSTS is reset, then compute the new overflow time */ + acpi_pm_tmr_calc_overflow_time(tmr); + } + pm1->sts &= ~val; +} + +void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr) +{ + if (!pm1) { + qemu_system_shutdown_request(); + } else if (pm1->en & ACPI_BITMASK_POWER_BUTTON_ENABLE) { + pm1->sts |= ACPI_BITMASK_POWER_BUTTON_STATUS; + tmr->update_sci(tmr); + } +} + +void acpi_pm1_evt_reset(ACPIPM1EVT *pm1) +{ + pm1->sts = 0; + pm1->en = 0; +} + +/* ACPI PM_TMR */ +void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable) +{ + int64_t expire_time; + + /* schedule a timer interruption if needed */ + if (enable) { + expire_time = muldiv64(tmr->overflow_time, get_ticks_per_sec(), + PM_TIMER_FREQUENCY); + qemu_mod_timer(tmr->timer, expire_time); + } else { + qemu_del_timer(tmr->timer); + } +} + +void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr) +{ + int64_t d = acpi_pm_tmr_get_clock(); + tmr->overflow_time = (d + 0x800000LL) & ~0x7fffffLL; +} + +uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr) +{ + uint32_t d = acpi_pm_tmr_get_clock();; + return d & 0xffffff; +} + +static void acpi_pm_tmr_timer(void *opaque) +{ + ACPIPMTimer *tmr = opaque; + tmr->update_sci(tmr); +} + +void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci) +{ + tmr->update_sci = update_sci; + tmr->timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, tmr); +} + +void acpi_pm_tmr_reset(ACPIPMTimer *tmr) +{ + tmr->overflow_time = 0; + qemu_del_timer(tmr->timer); +} + +/* ACPI PM1aCNT */ +void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3) +{ + pm1_cnt->cmos_s3 = cmos_s3; +} + +void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val) +{ + pm1_cnt->cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); + + if (val & ACPI_BITMASK_SLEEP_ENABLE) { + /* change suspend type */ + uint16_t sus_typ = (val >> 10) & 7; + switch(sus_typ) { + case 0: /* soft power off */ + qemu_system_shutdown_request(); + break; + case 1: + /* ACPI_BITMASK_WAKE_STATUS should be set on resume. + Pretend that resume was caused by power button */ + pm1a->sts |= + (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); + qemu_system_reset_request(); + qemu_irq_raise(pm1_cnt->cmos_s3); + default: break; - f = n + 1; + } } - if (off < length) { - /* don't pass random value in process to guest */ - memset(p + off, 0, length - off); +} + +void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt, + bool sci_enable, bool sci_disable) +{ + /* ACPI specs 3.0, 4.7.2.5 */ + if (sci_enable) { + pm1_cnt->cnt |= ACPI_BITMASK_SCI_ENABLE; + } else if (sci_disable) { + pm1_cnt->cnt &= ~ACPI_BITMASK_SCI_ENABLE; } +} - acpi_hdr_p = (struct acpi_table_header*)p; - acpi_hdr_p->length = cpu_to_le32(length); - acpi_hdr_p->checksum = acpi_checksum((uint8_t*)p, length); - /* increase number of tables */ - (*(uint16_t*)acpi_tables) = - cpu_to_le32(le32_to_cpu(*(uint16_t*)acpi_tables) + 1); - return 0; -out: - if (acpi_tables) { - qemu_free(acpi_tables); - acpi_tables = NULL; +void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt) +{ + pm1_cnt->cnt = 0; + if (pm1_cnt->cmos_s3) { + qemu_irq_lower(pm1_cnt->cmos_s3); + } +} + +/* ACPI GPE */ +void acpi_gpe_init(ACPIGPE *gpe, uint8_t len) +{ + gpe->len = len; + gpe->sts = g_malloc0(len / 2); + gpe->en = g_malloc0(len / 2); +} + +void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk) +{ + gpe->blk = blk; +} + +void acpi_gpe_reset(ACPIGPE *gpe) +{ + memset(gpe->sts, 0, gpe->len / 2); + memset(gpe->en, 0, gpe->len / 2); +} + +static uint8_t *acpi_gpe_ioport_get_ptr(ACPIGPE *gpe, uint32_t addr) +{ + uint8_t *cur = NULL; + + if (addr < gpe->len / 2) { + cur = gpe->sts + addr; + } else if (addr < gpe->len) { + cur = gpe->en + addr - gpe->len / 2; + } else { + abort(); } - return -1; + + return cur; +} + +void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val) +{ + uint8_t *cur; + + addr -= gpe->blk; + cur = acpi_gpe_ioport_get_ptr(gpe, addr); + if (addr < gpe->len / 2) { + /* GPE_STS */ + *cur = (*cur) & ~val; + } else if (addr < gpe->len) { + /* GPE_EN */ + *cur = val; + } else { + abort(); + } +} + +uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr) +{ + uint8_t *cur; + uint32_t val; + + addr -= gpe->blk; + cur = acpi_gpe_ioport_get_ptr(gpe, addr); + val = 0; + if (cur != NULL) { + val = *cur; + } + + return val; } diff --git a/hw/acpi.h b/hw/acpi.h index 5949958..c141e65 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -74,5 +74,73 @@ #define ACPI_BITMASK_ARB_DISABLE 0x0001 /* PM_TMR */ +struct ACPIPMTimer; +typedef struct ACPIPMTimer ACPIPMTimer; + +typedef void (*acpi_update_sci_fn)(ACPIPMTimer *tmr); + +struct ACPIPMTimer { + QEMUTimer *timer; + int64_t overflow_time; + + acpi_update_sci_fn update_sci; +}; + +void acpi_pm_tmr_update(ACPIPMTimer *tmr, bool enable); +void acpi_pm_tmr_calc_overflow_time(ACPIPMTimer *tmr); +uint32_t acpi_pm_tmr_get(ACPIPMTimer *tmr); +void acpi_pm_tmr_init(ACPIPMTimer *tmr, acpi_update_sci_fn update_sci); +void acpi_pm_tmr_reset(ACPIPMTimer *tmr); + +#include "qemu-timer.h" +static inline int64_t acpi_pm_tmr_get_clock(void) +{ + return muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, + get_ticks_per_sec()); +} + +/* PM1a_EVT: piix and ich9 don't implement PM1b. */ +struct ACPIPM1EVT +{ + uint16_t sts; + uint16_t en; +}; +typedef struct ACPIPM1EVT ACPIPM1EVT; + +uint16_t acpi_pm1_evt_get_sts(ACPIPM1EVT *pm1, int64_t overflow_time); +void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val); +void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr); +void acpi_pm1_evt_reset(ACPIPM1EVT *pm1); + +/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */ +struct ACPIPM1CNT { + uint16_t cnt; + + qemu_irq cmos_s3; +}; +typedef struct ACPIPM1CNT ACPIPM1CNT; + +void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3); +void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val); +void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt, + bool sci_enable, bool sci_disable); +void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt); + +/* GPE0 */ +struct ACPIGPE { + uint32_t blk; + uint8_t len; + + uint8_t *sts; + uint8_t *en; +}; +typedef struct ACPIGPE ACPIGPE; + +void acpi_gpe_init(ACPIGPE *gpe, uint8_t len); +void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk); +void acpi_gpe_reset(ACPIGPE *gpe); + +void acpi_gpe_ioport_writeb(ACPIGPE *gpe, uint32_t addr, uint32_t val); +uint32_t acpi_gpe_ioport_readb(ACPIGPE *gpe, uint32_t addr); #endif /* !QEMU_HW_ACPI_H */ diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 5bbc2b5..be3a2a1 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -23,6 +23,7 @@ #include "acpi.h" #include "sysemu.h" #include "range.h" +#include "ioport.h" //#define DEBUG @@ -35,17 +36,13 @@ #define ACPI_DBG_IO_ADDR 0xb044 #define GPE_BASE 0xafe0 +#define GPE_LEN 4 #define PCI_BASE 0xae00 #define PCI_EJ_BASE 0xae08 #define PCI_RMV_BASE 0xae0c #define PIIX4_PCI_HOTPLUG_STATUS 2 -struct gpe_regs { - uint16_t sts; /* status */ - uint16_t en; /* enabled */ -}; - struct pci_status { uint32_t up; uint32_t down; @@ -54,25 +51,23 @@ struct pci_status { typedef struct PIIX4PMState { PCIDevice dev; IORange ioport; - uint16_t pmsts; - uint16_t pmen; - uint16_t pmcntrl; + ACPIPM1EVT pm1a; + ACPIPM1CNT pm1_cnt; APMState apm; - QEMUTimer *tmr_timer; - int64_t tmr_overflow_time; + ACPIPMTimer tmr; PMSMBus smb; uint32_t smb_io_base; qemu_irq irq; - qemu_irq cmos_s3; qemu_irq smi_irq; int kvm_enabled; + Notifier machine_ready; /* for pci hotplug */ - struct gpe_regs gpe; + ACPIGPE gpe; struct pci_status pci0_status; uint32_t pci0_hotplug_enable; } PIIX4PMState; @@ -82,52 +77,27 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s); #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 -static uint32_t get_pmtmr(PIIX4PMState *s) -{ - uint32_t d; - d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec()); - return d & 0xffffff; -} - -static int get_pmsts(PIIX4PMState *s) -{ - int64_t d; - - d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, - get_ticks_per_sec()); - if (d >= s->tmr_overflow_time) - s->pmsts |= ACPI_BITMASK_TIMER_STATUS; - return s->pmsts; -} - static void pm_update_sci(PIIX4PMState *s) { int sci_level, pmsts; - int64_t expire_time; - pmsts = get_pmsts(s); - sci_level = (((pmsts & s->pmen) & + pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time); + sci_level = (((pmsts & s->pm1a.en) & (ACPI_BITMASK_RT_CLOCK_ENABLE | ACPI_BITMASK_POWER_BUTTON_ENABLE | ACPI_BITMASK_GLOBAL_LOCK_ENABLE | ACPI_BITMASK_TIMER_ENABLE)) != 0) || - (((s->gpe.sts & s->gpe.en) & PIIX4_PCI_HOTPLUG_STATUS) != 0); + (((s->gpe.sts[0] & s->gpe.en[0]) & PIIX4_PCI_HOTPLUG_STATUS) != 0); qemu_set_irq(s->irq, sci_level); /* schedule a timer interruption if needed */ - if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) && - !(pmsts & ACPI_BITMASK_TIMER_STATUS)) { - expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(), - PM_TIMER_FREQUENCY); - qemu_mod_timer(s->tmr_timer, expire_time); - } else { - qemu_del_timer(s->tmr_timer); - } + acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) && + !(pmsts & ACPI_BITMASK_TIMER_STATUS)); } -static void pm_tmr_timer(void *opaque) +static void pm_tmr_timer(ACPIPMTimer *tmr) { - PIIX4PMState *s = opaque; + PIIX4PMState *s = container_of(tmr, PIIX4PMState, tmr); pm_update_sci(s); } @@ -143,54 +113,21 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width, switch(addr) { case 0x00: - { - int64_t d; - int pmsts; - pmsts = get_pmsts(s); - if (pmsts & val & ACPI_BITMASK_TIMER_STATUS) { - /* if TMRSTS is reset, then compute the new overflow time */ - d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, - get_ticks_per_sec()); - s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL; - } - s->pmsts &= ~val; - pm_update_sci(s); - } + acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val); + pm_update_sci(s); break; case 0x02: - s->pmen = val; + s->pm1a.en = val; pm_update_sci(s); break; case 0x04: - { - int sus_typ; - s->pmcntrl = val & ~(ACPI_BITMASK_SLEEP_ENABLE); - if (val & ACPI_BITMASK_SLEEP_ENABLE) { - /* change suspend type */ - sus_typ = (val >> 10) & 7; - switch(sus_typ) { - case 0: /* soft power off */ - qemu_system_shutdown_request(); - break; - case 1: - /* ACPI_BITMASK_WAKE_STATUS should be set on resume. - Pretend that resume was caused by power button */ - s->pmsts |= (ACPI_BITMASK_WAKE_STATUS | - ACPI_BITMASK_POWER_BUTTON_STATUS); - qemu_system_reset_request(); - if (s->cmos_s3) { - qemu_irq_raise(s->cmos_s3); - } - default: - break; - } - } - } + acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val); break; default: break; } - PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", addr, val); + PIIX4_DPRINTF("PM writew port=0x%04x val=0x%04x\n", (unsigned int)addr, + (unsigned int)val); } static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width, @@ -201,22 +138,22 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width, switch(addr) { case 0x00: - val = get_pmsts(s); + val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time); break; case 0x02: - val = s->pmen; + val = s->pm1a.en; break; case 0x04: - val = s->pmcntrl; + val = s->pm1_cnt.cnt; break; case 0x08: - val = get_pmtmr(s); + val = acpi_pm_tmr_get(&s->tmr); break; default: val = 0; break; } - PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", addr, val); + PIIX4_DPRINTF("PM readw port=0x%04x val=0x%04x\n", (unsigned int)addr, val); *data = val; } @@ -230,11 +167,7 @@ static void apm_ctrl_changed(uint32_t val, void *arg) PIIX4PMState *s = arg; /* ACPI specs 3.0, 4.7.2.5 */ - if (val == ACPI_ENABLE) { - s->pmcntrl |= ACPI_BITMASK_SCI_ENABLE; - } else if (val == ACPI_DISABLE) { - s->pmcntrl &= ~ACPI_BITMASK_SCI_ENABLE; - } + acpi_pm1_cnt_update(&s->pm1_cnt, val == ACPI_ENABLE, val == ACPI_DISABLE); if (s->dev.config[0x5b] & (1 << 1)) { if (s->smi_irq) { @@ -279,14 +212,25 @@ static int vmstate_acpi_post_load(void *opaque, int version_id) return 0; } +#define VMSTATE_GPE_ARRAY(_field, _state) \ + { \ + .name = (stringify(_field)), \ + .version_id = 0, \ + .num = GPE_LEN, \ + .info = &vmstate_info_uint16, \ + .size = sizeof(uint16_t), \ + .flags = VMS_ARRAY | VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ + } + static const VMStateDescription vmstate_gpe = { .name = "gpe", .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT16(sts, struct gpe_regs), - VMSTATE_UINT16(en, struct gpe_regs), + VMSTATE_GPE_ARRAY(sts, ACPIGPE), + VMSTATE_GPE_ARRAY(en, ACPIGPE), VMSTATE_END_OF_LIST() } }; @@ -311,13 +255,13 @@ static const VMStateDescription vmstate_acpi = { .post_load = vmstate_acpi_post_load, .fields = (VMStateField []) { VMSTATE_PCI_DEVICE(dev, PIIX4PMState), - VMSTATE_UINT16(pmsts, PIIX4PMState), - VMSTATE_UINT16(pmen, PIIX4PMState), - VMSTATE_UINT16(pmcntrl, PIIX4PMState), + VMSTATE_UINT16(pm1a.sts, PIIX4PMState), + VMSTATE_UINT16(pm1a.en, PIIX4PMState), + VMSTATE_UINT16(pm1_cnt.cnt, PIIX4PMState), VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState), - VMSTATE_TIMER(tmr_timer, PIIX4PMState), - VMSTATE_INT64(tmr_overflow_time, PIIX4PMState), - VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, struct gpe_regs), + VMSTATE_TIMER(tmr.timer, PIIX4PMState), + VMSTATE_INT64(tmr.overflow_time, PIIX4PMState), + VMSTATE_STRUCT(gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status, struct pci_status), VMSTATE_END_OF_LIST() @@ -332,7 +276,7 @@ static void piix4_update_hotplug(PIIX4PMState *s) s->pci0_hotplug_enable = ~0; - QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) { + QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) { PCIDeviceInfo *info = container_of(qdev->info, PCIDeviceInfo, qdev); PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, qdev); int slot = PCI_SLOT(pdev->devfn); @@ -363,13 +307,23 @@ static void piix4_reset(void *opaque) static void piix4_powerdown(void *opaque, int irq, int power_failing) { PIIX4PMState *s = opaque; + ACPIPM1EVT *pm1a = s? &s->pm1a: NULL; + ACPIPMTimer *tmr = s? &s->tmr: NULL; + + acpi_pm1_evt_power_down(pm1a, tmr); +} + +static void piix4_pm_machine_ready(Notifier *n, void *opaque) +{ + PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); + uint8_t *pci_conf; + + pci_conf = s->dev.config; + pci_conf[0x5f] = (isa_is_ioport_assigned(0x378) ? 0x80 : 0) | 0x10; + pci_conf[0x63] = 0x60; + pci_conf[0x67] = (isa_is_ioport_assigned(0x3f8) ? 0x08 : 0) | + (isa_is_ioport_assigned(0x2f8) ? 0x90 : 0); - if (!s) { - qemu_system_shutdown_request(); - } else if (s->pmen & ACPI_BITMASK_POWER_BUTTON_ENABLE) { - s->pmsts |= ACPI_BITMASK_POWER_BUTTON_STATUS; - pm_update_sci(s); - } } static int piix4_pm_initfn(PCIDevice *dev) @@ -378,13 +332,9 @@ static int piix4_pm_initfn(PCIDevice *dev) uint8_t *pci_conf; pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_3); pci_conf[0x06] = 0x80; pci_conf[0x07] = 0x02; - pci_conf[0x08] = 0x03; // revision number pci_conf[0x09] = 0x00; - pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER); pci_conf[0x3d] = 0x01; // interrupt pin 1 pci_conf[0x40] = 0x01; /* PM io base read only bit */ @@ -402,22 +352,20 @@ static int piix4_pm_initfn(PCIDevice *dev) /* XXX: which specification is used ? The i82731AB has different mappings */ - pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10; - pci_conf[0x63] = 0x60; - pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) | - (serial_hds[1] != NULL ? 0x90 : 0); - pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x09; register_ioport_write(s->smb_io_base, 64, 1, smb_ioport_writeb, &s->smb); register_ioport_read(s->smb_io_base, 64, 1, smb_ioport_readb, &s->smb); - s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s); + acpi_pm_tmr_init(&s->tmr, pm_tmr_timer); + acpi_gpe_init(&s->gpe, GPE_LEN); qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1); pm_smbus_init(&s->dev.qdev, &s->smb); + s->machine_ready.notify = piix4_pm_machine_ready; + qemu_add_machine_init_done_notifier(&s->machine_ready); qemu_register_reset(piix4_reset, s); piix4_acpi_system_hot_add_init(dev->bus, s); @@ -431,12 +379,16 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, PCIDevice *dev; PIIX4PMState *s; +#if defined(CONFIG_MARU) && defined(__x86_64__) + dev = pci_create(bus, devfn, "MARU_PM"); +#else dev = pci_create(bus, devfn, "PIIX4_PM"); +#endif qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base); s = DO_UPCAST(PIIX4PMState, dev, dev); s->irq = sci_irq; - s->cmos_s3 = cmos_s3; + acpi_pm1_cnt_init(&s->pm1_cnt, cmos_s3); s->smi_irq = smi_irq; s->kvm_enabled = kvm_enabled; @@ -446,7 +398,11 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, } static PCIDeviceInfo piix4_pm_info = { +#if defined(CONFIG_MARU) && defined(__x86_64__) + .qdev.name = "MARU_PM", +#else .qdev.name = "PIIX4_PM", +#endif .qdev.desc = "PM", .qdev.size = sizeof(PIIX4PMState), .qdev.vmsd = &vmstate_acpi, @@ -454,6 +410,10 @@ static PCIDeviceInfo piix4_pm_info = { .no_hotplug = 1, .init = piix4_pm_initfn, .config_write = pm_write_config, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371AB_3, + .revision = 0x03, + .class_id = PCI_CLASS_BRIDGE_OTHER, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), DEFINE_PROP_END_OF_LIST(), @@ -467,74 +427,20 @@ static void piix4_pm_register(void) device_init(piix4_pm_register); -static uint32_t gpe_read_val(uint16_t val, uint32_t addr) -{ - if (addr & 1) - return (val >> 8) & 0xff; - return val & 0xff; -} - static uint32_t gpe_readb(void *opaque, uint32_t addr) { - uint32_t val = 0; PIIX4PMState *s = opaque; - struct gpe_regs *g = &s->gpe; - - switch (addr) { - case GPE_BASE: - case GPE_BASE + 1: - val = gpe_read_val(g->sts, addr); - break; - case GPE_BASE + 2: - case GPE_BASE + 3: - val = gpe_read_val(g->en, addr); - break; - default: - break; - } + uint32_t val = acpi_gpe_ioport_readb(&s->gpe, addr); PIIX4_DPRINTF("gpe read %x == %x\n", addr, val); return val; } -static void gpe_write_val(uint16_t *cur, int addr, uint32_t val) -{ - if (addr & 1) - *cur = (*cur & 0xff) | (val << 8); - else - *cur = (*cur & 0xff00) | (val & 0xff); -} - -static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val) -{ - uint16_t x1, x0 = val & 0xff; - int shift = (addr & 1) ? 8 : 0; - - x1 = (*cur >> shift) & 0xff; - - x1 = x1 & ~x0; - - *cur = (*cur & (0xff << (8 - shift))) | (x1 << shift); -} - static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) { PIIX4PMState *s = opaque; - struct gpe_regs *g = &s->gpe; - - switch (addr) { - case GPE_BASE: - case GPE_BASE + 1: - gpe_reset_val(&g->sts, addr, val); - break; - case GPE_BASE + 2: - case GPE_BASE + 3: - gpe_write_val(&g->en, addr, val); - break; - default: - break; - } + acpi_gpe_ioport_writeb(&s->gpe, addr, val); pm_update_sci(s); PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val); @@ -585,11 +491,13 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val) BusState *bus = opaque; DeviceState *qdev, *next; PCIDevice *dev; + PCIDeviceInfo *info; int slot = ffs(val) - 1; - QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) { + QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) { dev = DO_UPCAST(PCIDevice, qdev, qdev); - if (PCI_SLOT(dev->devfn) == slot) { + info = container_of(qdev->info, PCIDeviceInfo, qdev); + if (PCI_SLOT(dev->devfn) == slot && !info->no_hotplug) { qdev_free(qdev); } } @@ -617,8 +525,9 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) { struct pci_status *pci0_status = &s->pci0_status; - register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, s); - register_ioport_read(GPE_BASE, 4, 1, gpe_readb, s); + register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s); + register_ioport_read(GPE_BASE, GPE_LEN, 1, gpe_readb, s); + acpi_gpe_blk(&s->gpe, GPE_BASE); register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status); register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, pci0_status); @@ -634,13 +543,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s) static void enable_device(PIIX4PMState *s, int slot) { - s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS; + s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; s->pci0_status.up |= (1 << slot); } static void disable_device(PIIX4PMState *s, int slot) { - s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS; + s->gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; s->pci0_status.down |= (1 << slot); } diff --git a/hw/adb.c b/hw/adb.c index 99b30f6..aa15f55 100644 --- a/hw/adb.c +++ b/hw/adb.c @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #include "hw.h" -#include "ppc_mac.h" +#include "adb.h" #include "console.h" /* debug ADB */ @@ -261,30 +261,19 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, return olen; } -static void adb_kbd_save(QEMUFile *f, void *opaque) -{ - KBDState *s = (KBDState *)opaque; - - qemu_put_buffer(f, s->data, sizeof(s->data)); - qemu_put_sbe32s(f, &s->rptr); - qemu_put_sbe32s(f, &s->wptr); - qemu_put_sbe32s(f, &s->count); -} - -static int adb_kbd_load(QEMUFile *f, void *opaque, int version_id) -{ - KBDState *s = (KBDState *)opaque; - - if (version_id != 1) - return -EINVAL; - - qemu_get_buffer(f, s->data, sizeof(s->data)); - qemu_get_sbe32s(f, &s->rptr); - qemu_get_sbe32s(f, &s->wptr); - qemu_get_sbe32s(f, &s->count); - - return 0; -} +static const VMStateDescription vmstate_adb_kbd = { + .name = "adb_kbd", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_BUFFER(data, KBDState), + VMSTATE_INT32(rptr, KBDState), + VMSTATE_INT32(wptr, KBDState), + VMSTATE_INT32(count, KBDState), + VMSTATE_END_OF_LIST() + } +}; static int adb_kbd_reset(ADBDevice *d) { @@ -301,12 +290,11 @@ void adb_kbd_init(ADBBusState *bus) { ADBDevice *d; KBDState *s; - s = qemu_mallocz(sizeof(KBDState)); + s = g_malloc0(sizeof(KBDState)); d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, adb_kbd_reset, s); qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); - register_savevm(NULL, "adb_kbd", -1, 1, adb_kbd_save, - adb_kbd_load, s); + vmstate_register(NULL, -1, &vmstate_adb_kbd, s); } /***************************************************************/ @@ -439,42 +427,29 @@ static int adb_mouse_reset(ADBDevice *d) return 0; } -static void adb_mouse_save(QEMUFile *f, void *opaque) -{ - MouseState *s = (MouseState *)opaque; - - qemu_put_sbe32s(f, &s->buttons_state); - qemu_put_sbe32s(f, &s->last_buttons_state); - qemu_put_sbe32s(f, &s->dx); - qemu_put_sbe32s(f, &s->dy); - qemu_put_sbe32s(f, &s->dz); -} - -static int adb_mouse_load(QEMUFile *f, void *opaque, int version_id) -{ - MouseState *s = (MouseState *)opaque; - - if (version_id != 1) - return -EINVAL; - - qemu_get_sbe32s(f, &s->buttons_state); - qemu_get_sbe32s(f, &s->last_buttons_state); - qemu_get_sbe32s(f, &s->dx); - qemu_get_sbe32s(f, &s->dy); - qemu_get_sbe32s(f, &s->dz); - - return 0; -} +static const VMStateDescription vmstate_adb_mouse = { + .name = "adb_mouse", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(buttons_state, MouseState), + VMSTATE_INT32(last_buttons_state, MouseState), + VMSTATE_INT32(dx, MouseState), + VMSTATE_INT32(dy, MouseState), + VMSTATE_INT32(dz, MouseState), + VMSTATE_END_OF_LIST() + } +}; void adb_mouse_init(ADBBusState *bus) { ADBDevice *d; MouseState *s; - s = qemu_mallocz(sizeof(MouseState)); + s = g_malloc0(sizeof(MouseState)); d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, adb_mouse_reset, s); qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse"); - register_savevm(NULL, "adb_mouse", -1, 1, adb_mouse_save, - adb_mouse_load, s); + vmstate_register(NULL, -1, &vmstate_adb_mouse, s); } diff --git a/hw/adlib.c b/hw/adlib.c index 1d8092b..e4bfcc6 100644 --- a/hw/adlib.c +++ b/hw/adlib.c @@ -119,7 +119,6 @@ static IO_WRITE_PROTO (adlib_write) { AdlibState *s = opaque; int a = nport & 3; - int status; s->active = 1; AUD_set_active_out (s->voice, 1); @@ -127,9 +126,9 @@ static IO_WRITE_PROTO (adlib_write) adlib_kill_timers (s); #ifdef HAS_YMF262 - status = YMF262Write (0, a, val); + YMF262Write (0, a, val); #else - status = OPLWrite (s->opl, a, val); + OPLWrite (s->opl, a, val); #endif } @@ -166,7 +165,7 @@ static void timer_handler (int c, double interval_Sec) s->ticking[n] = 1; #ifdef DEBUG interval = get_ticks_per_sec() * interval_Sec; - exp = qemu_get_clock (vm_clock) + interval; + exp = qemu_get_clock_ns (vm_clock) + interval; s->exp[n] = exp; #endif @@ -268,7 +267,7 @@ static void Adlib_fini (AdlibState *s) #endif if (s->mixbuf) { - qemu_free (s->mixbuf); + g_free (s->mixbuf); } s->active = 0; @@ -323,7 +322,7 @@ int Adlib_init (qemu_irq *pic) } s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT; - s->mixbuf = qemu_mallocz (s->samples << SHIFT); + s->mixbuf = g_malloc0 (s->samples << SHIFT); register_ioport_read (0x388, 4, 1, adlib_read, s); register_ioport_write (0x388, 4, 1, adlib_write, s); diff --git a/hw/ads7846.c b/hw/ads7846.c index b3bbeaf..9c58a5f 100644 --- a/hw/ads7846.c +++ b/hw/ads7846.c @@ -105,35 +105,30 @@ static void ads7846_ts_event(void *opaque, } } -static void ads7846_save(QEMUFile *f, void *opaque) +static int ads7856_post_load(void *opaque, int version_id) { - ADS7846State *s = (ADS7846State *) opaque; - int i; - - for (i = 0; i < 8; i ++) - qemu_put_be32(f, s->input[i]); - qemu_put_be32(f, s->noise); - qemu_put_be32(f, s->cycle); - qemu_put_be32(f, s->output); -} - -static int ads7846_load(QEMUFile *f, void *opaque, int version_id) -{ - ADS7846State *s = (ADS7846State *) opaque; - int i; - - for (i = 0; i < 8; i ++) - s->input[i] = qemu_get_be32(f); - s->noise = qemu_get_be32(f); - s->cycle = qemu_get_be32(f); - s->output = qemu_get_be32(f); + ADS7846State *s = opaque; s->pressure = 0; ads7846_int_update(s); - return 0; } +static const VMStateDescription vmstate_ads7846 = { + .name = "ads7846", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = ads7856_post_load, + .fields = (VMStateField[]) { + VMSTATE_INT32_ARRAY(input, ADS7846State, 8), + VMSTATE_INT32(noise, ADS7846State), + VMSTATE_INT32(cycle, ADS7846State), + VMSTATE_INT32(output, ADS7846State), + VMSTATE_END_OF_LIST() + } +}; + static int ads7846_init(SSISlave *dev) { ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev); @@ -151,7 +146,7 @@ static int ads7846_init(SSISlave *dev) ads7846_int_update(s); - register_savevm(NULL, "ads7846", -1, 0, ads7846_save, ads7846_load, s); + vmstate_register(NULL, -1, &vmstate_ads7846, s); return 0; } diff --git a/hw/ak8973.c b/hw/ak8973.c deleted file mode 100644 index bed951a..0000000 --- a/hw/ak8973.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * AK8973 Compass Emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Junsik.Park - */ - -#include "i2c-addressable.h" -#include "ak8973.h" - -//#define DEBUG - -#define AK8973_ST 0xC0 -#define AK8973_TMPS 0xC1 -#define AK8973_H1X 0xC2 -#define AK8973_H1Y 0xC3 -#define AK8973_H1Z 0xC4 - -#define AK8973_MS1 0xE0 -#define AK8973_HXDA 0xE1 -#define AK8973_HYDA 0xE2 -#define AK8973_HZDA 0xE3 -#define AK8973_HXGA 0xE4 -#define AK8973_HYGA 0xE5 -#define AK8973_HZGA 0xE6 - -#define AK8973_ETS 0x62 -#define AK8973_EVIR 0x63 -#define AK8973_EIHE 0x64 -#define AK8973_ETST 0x65 -#define AK8973_EHXGA 0x66 -#define AK8973_EHYGA 0x67 -#define AK8973_EHZGA 0x68 -#define AK8973_WRAL1 0x60 - - -typedef struct AK8973State { - I2CAddressableState i2c_addressable; - - uint8_t status; - uint8_t x; - uint8_t y; - uint8_t z; - uint8_t temp; - uint8_t ms1; - uint8_t dac[3]; - uint8_t gain[3]; - qemu_irq irq; -} AK8973State; - - -static void ak8973_reset(DeviceState *d) -{ - AK8973State *s = - FROM_I2CADDR_SLAVE(AK8973State, I2CADDR_SLAVE_FROM_QDEV(d)); - - s->status = 0; - /* Random coordinates */ - s->x = 10; - s->y = 20; - s->z = 30; - - /* 20 degree Celsius */ - s->temp = 0x90; - - /* EEPROM data-write disable / Powerdown mode */ - s->ms1 = 0x3; - - /* TODO: get the defaults */ - s->dac[0] = 0; - s->dac[1] = 0; - s->dac[2] = 0; - s->gain[0] = 0; - s->gain[1] = 0; - s->gain[2] = 0; - - return; -} - -static uint8_t ak8973_read(void *opaque, uint32_t address, uint8_t offset) -{ - struct AK8973State *s = (struct AK8973State *)opaque; - uint32_t ret = 0, index = address + offset; - - switch (index) { - case AK8973_ST: - ret = s->status; - break; - case AK8973_TMPS: - /* IRQ is lowered when any of data registers are read */ - qemu_irq_lower(s->irq); - s->status &= ~1; - ret = s->temp; - break; - case AK8973_H1X: - qemu_irq_lower(s->irq); - s->status &= ~1; - ret = s->x; - break; - case AK8973_H1Y: - qemu_irq_lower(s->irq); - s->status &= ~1; - ret = s->y; - break; - case AK8973_H1Z: - qemu_irq_lower(s->irq); - s->status &= ~1; - ret = s->z; - break; - case AK8973_MS1: - ret = s->ms1; - break; - case AK8973_HXDA: - case AK8973_HYDA: - case AK8973_HZDA: - ret = s->dac[index - AK8973_HXDA]; - break; - case AK8973_HXGA: - case AK8973_HYGA: - case AK8973_HZGA: - ret = s->gain[index - AK8973_HXGA]; - break; - case AK8973_ETS: - case AK8973_EVIR: - case AK8973_EIHE: - case AK8973_ETST: - case AK8973_EHXGA: - case AK8973_EHYGA: - case AK8973_EHZGA: - case AK8973_WRAL1: - if ((s->ms1 & 3) == 2 && (s->ms1 & 0xF8) != 0xA8) { - /* TODO: implement EEPROM reading */ - ret = 0; - } else { - ret = 0; - } - break; - default: - hw_error("ak8973: bad read offset 0x%x\n", index); - } - -#ifdef DEBUG - printf("ak8973_read IDX = 0x%x, Data = 0x%x\n", index, ret); -#endif - - return ret; -} - -static void ak8973_write(void *opaque, uint32_t address, uint8_t offset, - uint8_t val) -{ - struct AK8973State *s = (struct AK8973State *)opaque; - uint32_t index = address + offset; - -#ifdef DEBUG - printf("ak8973_write IDX = 0x%x, Data = 0x%x\n", index, val); -#endif - - switch (index) { - case AK8973_MS1: - if ((val & 3) == 2) { - /* EEPROM access mode */ - /* TODO: implement this mode */ - s->ms1 = val; - } else { - /* All other mode setting finishes in power-down mode */ - s->ms1 |= 3; - } - if ((val & 3) == 0) { - /* Measurement mode */ - qemu_irq_raise(s->irq); - s->status |= 1; - /* TODO: change measurement registers accordingly */ - } - break; - case AK8973_HXDA: - case AK8973_HYDA: - case AK8973_HZDA: - /* TODO: implement DAC changes influence on reported data */ - s->dac[index - AK8973_HXDA] = val; - break; - case AK8973_HXGA: - case AK8973_HYGA: - case AK8973_HZGA: - /* TODO: implement gain changes influence on reported data */ - s->gain[index - AK8973_HXGA] = val; - break; - case AK8973_ETS: - case AK8973_EVIR: - case AK8973_EIHE: - case AK8973_ETST: - case AK8973_EHXGA: - case AK8973_EHYGA: - case AK8973_EHZGA: - case AK8973_WRAL1: - if ((s->ms1 & 3) == 2 && (s->ms1 & 0xF8) == 0xA8) { - /* TODO: implement EEPROM writing */ - } - break; - default: - hw_error("ak8973: bad write offset 0x%x\n", index); - } -} - -static void ak8973_save(QEMUFile *f, void *opaque) -{ - struct AK8973State *s = (struct AK8973State *)opaque; - - qemu_put_8s(f, &s->status); - qemu_put_8s(f, &s->ms1); - qemu_put_buffer(f, s->dac, 3); - qemu_put_buffer(f, s->gain, 3); -} - -static int ak8973_load(QEMUFile *f, void *opaque, int version_id) -{ - struct AK8973State *s = (struct AK8973State *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_8s(f, &s->status); - qemu_get_8s(f, &s->ms1); - qemu_get_buffer(f, s->dac, 3); - qemu_get_buffer(f, s->gain, 3); - - return 0; -} - -void ak8973_update(DeviceState *dev, - uint8_t x, uint8_t y, uint8_t z, uint8_t temp) -{ - AK8973State *s = - FROM_I2CADDR_SLAVE(AK8973State, I2CADDR_SLAVE_FROM_QDEV(dev)); - s->x = x; - s->y = y; - s->z = z; - s->temp = temp; -#ifdef DEBUG - printf("compass update : %d %d %d %d\n", x, y, z, temp); -#endif -} - - -static int ak8973_init(I2CAddressableState *s) -{ - AK8973State *t = FROM_I2CADDR_SLAVE(AK8973State, s); - - /* Set irq address */ - qdev_init_gpio_out(&s->i2c.qdev, &t->irq, 1); - - ak8973_reset(&s->i2c.qdev); - - register_savevm(&s->i2c.qdev, "ak8973", -1, 1, - ak8973_save, ak8973_load, s); - - return 0; -} - -static I2CAddressableDeviceInfo ak8973_info = { - .i2c.qdev.name = "ak8973", - .i2c.qdev.size = sizeof(AK8973State), - .i2c.qdev.reset = ak8973_reset, - .init = ak8973_init, - .read = ak8973_read, - .write = ak8973_write, - .size = 1, - .rev = 0 -}; - -static void ak8973_register_devices(void) -{ - i2c_addressable_register_device(&ak8973_info); -} - -device_init(ak8973_register_devices) diff --git a/hw/ak8973.h b/hw/ak8973.h deleted file mode 100644 index 366b2a2..0000000 --- a/hw/ak8973.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * AK8973 Compass Emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Junsik.Park - * Dmitry Zhurikhin - */ - -void ak8973_update(DeviceState *dev, - uint8_t x, uint8_t y, uint8_t z, uint8_t temp); diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c deleted file mode 100644 index 033b542..0000000 --- a/hw/alpha_palcode.c +++ /dev/null @@ -1,1048 +0,0 @@ -/* - * Alpha emulation - PALcode emulation for qemu. - * - * Copyright (c) 2007 Jocelyn Mayer - * - * 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, see . - */ - -#include -#include -#include - -#include "cpu.h" -#include "exec-all.h" - -/* Shared handlers */ -static void pal_reset (CPUState *env); -/* Console handlers */ -static void pal_console_call (CPUState *env, uint32_t palcode); -/* OpenVMS handlers */ -static void pal_openvms_call (CPUState *env, uint32_t palcode); -/* UNIX / Linux handlers */ -static void pal_unix_call (CPUState *env, uint32_t palcode); - -pal_handler_t pal_handlers[] = { - /* Console handler */ - { - .reset = &pal_reset, - .call_pal = &pal_console_call, - }, - /* OpenVMS handler */ - { - .reset = &pal_reset, - .call_pal = &pal_openvms_call, - }, - /* UNIX / Linux handler */ - { - .reset = &pal_reset, - .call_pal = &pal_unix_call, - }, -}; - -#if 0 -/* One must explicitly check that the TB is valid and the FOE bit is reset */ -static void update_itb (void) -{ - /* This writes into a temp register, not the actual one */ - mtpr(TB_TAG); - mtpr(TB_CTL); - /* This commits the TB update */ - mtpr(ITB_PTE); -} - -static void update_dtb (void); -{ - mtpr(TB_CTL); - /* This write into a temp register, not the actual one */ - mtpr(TB_TAG); - /* This commits the TB update */ - mtpr(DTB_PTE); -} -#endif - -static void pal_reset (CPUState *env) -{ -} - -static void do_swappal (CPUState *env, uint64_t palid) -{ - pal_handler_t *pal_handler; - - switch (palid) { - case 0 ... 2: - pal_handler = &pal_handlers[palid]; - env->pal_handler = pal_handler; - env->ipr[IPR_PAL_BASE] = -1ULL; - (*pal_handler->reset)(env); - break; - case 3 ... 255: - /* Unknown identifier */ - env->ir[0] = 1; - return; - default: - /* We were given the entry point address */ - env->pal_handler = NULL; - env->ipr[IPR_PAL_BASE] = palid; - env->pc = env->ipr[IPR_PAL_BASE]; - cpu_loop_exit(); - } -} - -static void pal_console_call (CPUState *env, uint32_t palcode) -{ - uint64_t palid; - - if (palcode < 0x00000080) { - /* Privileged palcodes */ - if (!(env->ps >> 3)) { - /* TODO: generate privilege exception */ - } - } - switch (palcode) { - case 0x00000000: - /* HALT */ - /* REQUIRED */ - break; - case 0x00000001: - /* CFLUSH */ - break; - case 0x00000002: - /* DRAINA */ - /* REQUIRED */ - /* Implemented as no-op */ - break; - case 0x00000009: - /* CSERVE */ - /* REQUIRED */ - break; - case 0x0000000A: - /* SWPPAL */ - /* REQUIRED */ - palid = env->ir[16]; - do_swappal(env, palid); - break; - case 0x00000080: - /* BPT */ - /* REQUIRED */ - break; - case 0x00000081: - /* BUGCHK */ - /* REQUIRED */ - break; - case 0x00000086: - /* IMB */ - /* REQUIRED */ - /* Implemented as no-op */ - break; - case 0x0000009E: - /* RDUNIQUE */ - /* REQUIRED */ - break; - case 0x0000009F: - /* WRUNIQUE */ - /* REQUIRED */ - break; - case 0x000000AA: - /* GENTRAP */ - /* REQUIRED */ - break; - default: - break; - } -} - -static void pal_openvms_call (CPUState *env, uint32_t palcode) -{ - uint64_t palid, val, oldval; - - if (palcode < 0x00000080) { - /* Privileged palcodes */ - if (!(env->ps >> 3)) { - /* TODO: generate privilege exception */ - } - } - switch (palcode) { - case 0x00000000: - /* HALT */ - /* REQUIRED */ - break; - case 0x00000001: - /* CFLUSH */ - break; - case 0x00000002: - /* DRAINA */ - /* REQUIRED */ - /* Implemented as no-op */ - break; - case 0x00000003: - /* LDQP */ - break; - case 0x00000004: - /* STQP */ - break; - case 0x00000005: - /* SWPCTX */ - break; - case 0x00000006: - /* MFPR_ASN */ - if (cpu_alpha_mfpr(env, IPR_ASN, &val) == 0) - env->ir[0] = val; - break; - case 0x00000007: - /* MTPR_ASTEN */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_ASTEN, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000008: - /* MTPR_ASTSR */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_ASTSR, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000009: - /* CSERVE */ - /* REQUIRED */ - break; - case 0x0000000A: - /* SWPPAL */ - /* REQUIRED */ - palid = env->ir[16]; - do_swappal(env, palid); - break; - case 0x0000000B: - /* MFPR_FEN */ - if (cpu_alpha_mfpr(env, IPR_FEN, &val) == 0) - env->ir[0] = val; - break; - case 0x0000000C: - /* MTPR_FEN */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_FEN, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000000D: - /* MTPR_IPIR */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000000E: - /* MFPR_IPL */ - if (cpu_alpha_mfpr(env, IPR_IPL, &val) == 0) - env->ir[0] = val; - break; - case 0x0000000F: - /* MTPR_IPL */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_IPL, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000010: - /* MFPR_MCES */ - if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0) - env->ir[0] = val; - break; - case 0x00000011: - /* MTPR_MCES */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000012: - /* MFPR_PCBB */ - if (cpu_alpha_mfpr(env, IPR_PCBB, &val) == 0) - env->ir[0] = val; - break; - case 0x00000013: - /* MFPR_PRBR */ - if (cpu_alpha_mfpr(env, IPR_PRBR, &val) == 0) - env->ir[0] = val; - break; - case 0x00000014: - /* MTPR_PRBR */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_PRBR, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000015: - /* MFPR_PTBR */ - if (cpu_alpha_mfpr(env, IPR_PTBR, &val) == 0) - env->ir[0] = val; - break; - case 0x00000016: - /* MFPR_SCBB */ - if (cpu_alpha_mfpr(env, IPR_SCBB, &val) == 0) - env->ir[0] = val; - break; - case 0x00000017: - /* MTPR_SCBB */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_SCBB, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000018: - /* MTPR_SIRR */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_SIRR, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000019: - /* MFPR_SISR */ - if (cpu_alpha_mfpr(env, IPR_SISR, &val) == 0) - env->ir[0] = val; - break; - case 0x0000001A: - /* MFPR_TBCHK */ - if (cpu_alpha_mfpr(env, IPR_TBCHK, &val) == 0) - env->ir[0] = val; - break; - case 0x0000001B: - /* MTPR_TBIA */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_TBIA, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000001C: - /* MTPR_TBIAP */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_TBIAP, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000001D: - /* MTPR_TBIS */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000001E: - /* MFPR_ESP */ - if (cpu_alpha_mfpr(env, IPR_ESP, &val) == 0) - env->ir[0] = val; - break; - case 0x0000001F: - /* MTPR_ESP */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_ESP, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000020: - /* MFPR_SSP */ - if (cpu_alpha_mfpr(env, IPR_SSP, &val) == 0) - env->ir[0] = val; - break; - case 0x00000021: - /* MTPR_SSP */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_SSP, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000022: - /* MFPR_USP */ - if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0) - env->ir[0] = val; - break; - case 0x00000023: - /* MTPR_USP */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000024: - /* MTPR_TBISD */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_TBISD, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000025: - /* MTPR_TBISI */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_TBISI, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000026: - /* MFPR_ASTEN */ - if (cpu_alpha_mfpr(env, IPR_ASTEN, &val) == 0) - env->ir[0] = val; - break; - case 0x00000027: - /* MFPR_ASTSR */ - if (cpu_alpha_mfpr(env, IPR_ASTSR, &val) == 0) - env->ir[0] = val; - break; - case 0x00000029: - /* MFPR_VPTB */ - if (cpu_alpha_mfpr(env, IPR_VPTB, &val) == 0) - env->ir[0] = val; - break; - case 0x0000002A: - /* MTPR_VPTB */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_VPTB, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000002B: - /* MTPR_PERFMON */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000002E: - /* MTPR_DATFX */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_DATFX, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000003E: - /* WTINT */ - break; - case 0x0000003F: - /* MFPR_WHAMI */ - if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0) - env->ir[0] = val; - break; - case 0x00000080: - /* BPT */ - /* REQUIRED */ - break; - case 0x00000081: - /* BUGCHK */ - /* REQUIRED */ - break; - case 0x00000082: - /* CHME */ - break; - case 0x00000083: - /* CHMK */ - break; - case 0x00000084: - /* CHMS */ - break; - case 0x00000085: - /* CHMU */ - break; - case 0x00000086: - /* IMB */ - /* REQUIRED */ - /* Implemented as no-op */ - break; - case 0x00000087: - /* INSQHIL */ - break; - case 0x00000088: - /* INSQTIL */ - break; - case 0x00000089: - /* INSQHIQ */ - break; - case 0x0000008A: - /* INSQTIQ */ - break; - case 0x0000008B: - /* INSQUEL */ - break; - case 0x0000008C: - /* INSQUEQ */ - break; - case 0x0000008D: - /* INSQUEL/D */ - break; - case 0x0000008E: - /* INSQUEQ/D */ - break; - case 0x0000008F: - /* PROBER */ - break; - case 0x00000090: - /* PROBEW */ - break; - case 0x00000091: - /* RD_PS */ - break; - case 0x00000092: - /* REI */ - break; - case 0x00000093: - /* REMQHIL */ - break; - case 0x00000094: - /* REMQTIL */ - break; - case 0x00000095: - /* REMQHIQ */ - break; - case 0x00000096: - /* REMQTIQ */ - break; - case 0x00000097: - /* REMQUEL */ - break; - case 0x00000098: - /* REMQUEQ */ - break; - case 0x00000099: - /* REMQUEL/D */ - break; - case 0x0000009A: - /* REMQUEQ/D */ - break; - case 0x0000009B: - /* SWASTEN */ - break; - case 0x0000009C: - /* WR_PS_SW */ - break; - case 0x0000009D: - /* RSCC */ - break; - case 0x0000009E: - /* READ_UNQ */ - /* REQUIRED */ - break; - case 0x0000009F: - /* WRITE_UNQ */ - /* REQUIRED */ - break; - case 0x000000A0: - /* AMOVRR */ - break; - case 0x000000A1: - /* AMOVRM */ - break; - case 0x000000A2: - /* INSQHILR */ - break; - case 0x000000A3: - /* INSQTILR */ - break; - case 0x000000A4: - /* INSQHIQR */ - break; - case 0x000000A5: - /* INSQTIQR */ - break; - case 0x000000A6: - /* REMQHILR */ - break; - case 0x000000A7: - /* REMQTILR */ - break; - case 0x000000A8: - /* REMQHIQR */ - break; - case 0x000000A9: - /* REMQTIQR */ - break; - case 0x000000AA: - /* GENTRAP */ - /* REQUIRED */ - break; - case 0x000000AE: - /* CLRFEN */ - break; - default: - break; - } -} - -static void pal_unix_call (CPUState *env, uint32_t palcode) -{ - uint64_t palid, val, oldval; - - if (palcode < 0x00000080) { - /* Privileged palcodes */ - if (!(env->ps >> 3)) { - /* TODO: generate privilege exception */ - } - } - switch (palcode) { - case 0x00000000: - /* HALT */ - /* REQUIRED */ - break; - case 0x00000001: - /* CFLUSH */ - break; - case 0x00000002: - /* DRAINA */ - /* REQUIRED */ - /* Implemented as no-op */ - break; - case 0x00000009: - /* CSERVE */ - /* REQUIRED */ - break; - case 0x0000000A: - /* SWPPAL */ - /* REQUIRED */ - palid = env->ir[16]; - do_swappal(env, palid); - break; - case 0x0000000D: - /* WRIPIR */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000010: - /* RDMCES */ - if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0) - env->ir[0] = val; - break; - case 0x00000011: - /* WRMCES */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000002B: - /* WRFEN */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000002D: - /* WRVPTPTR */ - break; - case 0x00000030: - /* SWPCTX */ - break; - case 0x00000031: - /* WRVAL */ - break; - case 0x00000032: - /* RDVAL */ - break; - case 0x00000033: - /* TBI */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000034: - /* WRENT */ - break; - case 0x00000035: - /* SWPIPL */ - break; - case 0x00000036: - /* RDPS */ - break; - case 0x00000037: - /* WRKGP */ - break; - case 0x00000038: - /* WRUSP */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x00000039: - /* WRPERFMON */ - val = env->ir[16]; - if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1) - env->ir[0] = val; - break; - case 0x0000003A: - /* RDUSP */ - if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0) - env->ir[0] = val; - break; - case 0x0000003C: - /* WHAMI */ - if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0) - env->ir[0] = val; - break; - case 0x0000003D: - /* RETSYS */ - break; - case 0x0000003E: - /* WTINT */ - break; - case 0x0000003F: - /* RTI */ - if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0) - env->ir[0] = val; - break; - case 0x00000080: - /* BPT */ - /* REQUIRED */ - break; - case 0x00000081: - /* BUGCHK */ - /* REQUIRED */ - break; - case 0x00000083: - /* CALLSYS */ - break; - case 0x00000086: - /* IMB */ - /* REQUIRED */ - /* Implemented as no-op */ - break; - case 0x00000092: - /* URTI */ - break; - case 0x0000009E: - /* RDUNIQUE */ - /* REQUIRED */ - break; - case 0x0000009F: - /* WRUNIQUE */ - /* REQUIRED */ - break; - case 0x000000AA: - /* GENTRAP */ - /* REQUIRED */ - break; - case 0x000000AE: - /* CLRFEN */ - break; - default: - break; - } -} - -void call_pal (CPUState *env) -{ - pal_handler_t *pal_handler = env->pal_handler; - - switch (env->exception_index) { - case EXCP_RESET: - (*pal_handler->reset)(env); - break; - case EXCP_MCHK: - (*pal_handler->machine_check)(env); - break; - case EXCP_ARITH: - (*pal_handler->arithmetic)(env); - break; - case EXCP_INTERRUPT: - (*pal_handler->interrupt)(env); - break; - case EXCP_DFAULT: - (*pal_handler->dfault)(env); - break; - case EXCP_DTB_MISS_PAL: - (*pal_handler->dtb_miss_pal)(env); - break; - case EXCP_DTB_MISS_NATIVE: - (*pal_handler->dtb_miss_native)(env); - break; - case EXCP_UNALIGN: - (*pal_handler->unalign)(env); - break; - case EXCP_ITB_MISS: - (*pal_handler->itb_miss)(env); - break; - case EXCP_ITB_ACV: - (*pal_handler->itb_acv)(env); - break; - case EXCP_OPCDEC: - (*pal_handler->opcdec)(env); - break; - case EXCP_FEN: - (*pal_handler->fen)(env); - break; - default: - if (env->exception_index >= EXCP_CALL_PAL && - env->exception_index < EXCP_CALL_PALP) { - /* Unprivileged PAL call */ - (*pal_handler->call_pal) - (env, (env->exception_index - EXCP_CALL_PAL) >> 6); - } else if (env->exception_index >= EXCP_CALL_PALP && - env->exception_index < EXCP_CALL_PALE) { - /* Privileged PAL call */ - (*pal_handler->call_pal) - (env, ((env->exception_index - EXCP_CALL_PALP) >> 6) + 0x80); - } else { - /* Should never happen */ - } - break; - } - env->ipr[IPR_EXC_ADDR] &= ~1; -} - -void pal_init (CPUState *env) -{ - do_swappal(env, 0); -} - -#if 0 -static uint64_t get_ptebase (CPUState *env, uint64_t vaddr) -{ - uint64_t virbnd, ptbr; - - if ((env->features & FEATURE_VIRBND)) { - cpu_alpha_mfpr(env, IPR_VIRBND, &virbnd); - if (vaddr >= virbnd) - cpu_alpha_mfpr(env, IPR_SYSPTBR, &ptbr); - else - cpu_alpha_mfpr(env, IPR_PTBR, &ptbr); - } else { - cpu_alpha_mfpr(env, IPR_PTBR, &ptbr); - } - - return ptbr; -} - -static int get_page_bits (CPUState *env) -{ - /* XXX */ - return 13; -} - -static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp, - uint64_t ptebase, int page_bits, uint64_t level, - int mmu_idx, int rw) -{ - uint64_t pteaddr, pte, pfn; - uint8_t gh; - int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user; - - /* XXX: TOFIX */ - is_user = mmu_idx == MMU_USER_IDX; - pteaddr = (ptebase << page_bits) + (8 * level); - pte = ldq_raw(pteaddr); - /* Decode all interresting PTE fields */ - pfn = pte >> 32; - uwe = (pte >> 13) & 1; - kwe = (pte >> 12) & 1; - ure = (pte >> 9) & 1; - kre = (pte >> 8) & 1; - gh = (pte >> 5) & 3; - foE = (pte >> 3) & 1; - foW = (pte >> 2) & 1; - foR = (pte >> 1) & 1; - v = pte & 1; - ret = 0; - if (!v) - ret = 0x1; - /* Check access rights */ - ar = 0; - if (is_user) { - if (ure) - ar |= PAGE_READ; - if (uwe) - ar |= PAGE_WRITE; - if (rw == 1 && !uwe) - ret |= 0x2; - if (rw != 1 && !ure) - ret |= 0x2; - } else { - if (kre) - ar |= PAGE_READ; - if (kwe) - ar |= PAGE_WRITE; - if (rw == 1 && !kwe) - ret |= 0x2; - if (rw != 1 && !kre) - ret |= 0x2; - } - if (rw == 0 && foR) - ret |= 0x4; - if (rw == 2 && foE) - ret |= 0x8; - if (rw == 1 && foW) - ret |= 0xC; - *pfnp = pfn; - if (zbitsp != NULL) - *zbitsp = page_bits + (3 * gh); - if (protp != NULL) - *protp = ar; - - return ret; -} - -static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot, - uint64_t ptebase, int page_bits, - uint64_t vaddr, int mmu_idx, int rw) -{ - uint64_t pfn, page_mask, lvl_mask, level1, level2, level3; - int lvl_bits, ret; - - page_mask = (1ULL << page_bits) - 1ULL; - lvl_bits = page_bits - 3; - lvl_mask = (1ULL << lvl_bits) - 1ULL; - level3 = (vaddr >> page_bits) & lvl_mask; - level2 = (vaddr >> (page_bits + lvl_bits)) & lvl_mask; - level1 = (vaddr >> (page_bits + (2 * lvl_bits))) & lvl_mask; - /* Level 1 PTE */ - ret = get_pte(&pfn, NULL, NULL, ptebase, page_bits, level1, 0, 0); - switch (ret) { - case 3: - /* Access violation */ - return 2; - case 2: - /* translation not valid */ - return 1; - default: - /* OK */ - break; - } - /* Level 2 PTE */ - ret = get_pte(&pfn, NULL, NULL, pfn, page_bits, level2, 0, 0); - switch (ret) { - case 3: - /* Access violation */ - return 2; - case 2: - /* translation not valid */ - return 1; - default: - /* OK */ - break; - } - /* Level 3 PTE */ - ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw); - if (ret & 0x1) { - /* Translation not valid */ - ret = 1; - } else if (ret & 2) { - /* Access violation */ - ret = 2; - } else { - switch (ret & 0xC) { - case 0: - /* OK */ - ret = 0; - break; - case 0x4: - /* Fault on read */ - ret = 3; - break; - case 0x8: - /* Fault on execute */ - ret = 4; - break; - case 0xC: - /* Fault on write */ - ret = 5; - break; - } - } - *paddr = (pfn << page_bits) | (vaddr & page_mask); - - return 0; -} - -static int virtual_to_physical (CPUState *env, uint64_t *physp, - int *zbitsp, int *protp, - uint64_t virtual, int mmu_idx, int rw) -{ - uint64_t sva, ptebase; - int seg, page_bits, ret; - - sva = ((int64_t)(virtual << (64 - VA_BITS))) >> (64 - VA_BITS); - if (sva != virtual) - seg = -1; - else - seg = sva >> (VA_BITS - 2); - virtual &= ~(0xFFFFFC0000000000ULL << (VA_BITS - 43)); - ptebase = get_ptebase(env, virtual); - page_bits = get_page_bits(env); - ret = 0; - switch (seg) { - case 0: - /* seg1: 3 levels of PTE */ - ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, - virtual, mmu_idx, rw); - break; - case 1: - /* seg1: 2 levels of PTE */ - ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, - virtual, mmu_idx, rw); - break; - case 2: - /* kernel segment */ - if (mmu_idx != 0) { - ret = 2; - } else { - *physp = virtual; - } - break; - case 3: - /* seg1: TB mapped */ - ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, - virtual, mmu_idx, rw); - break; - default: - ret = 1; - break; - } - - return ret; -} - -/* XXX: code provision */ -int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, - int mmu_idx, int is_softmmu) -{ - uint64_t physical, page_size, end; - int prot, zbits, ret; - - ret = virtual_to_physical(env, &physical, &zbits, &prot, - address, mmu_idx, rw); - - switch (ret) { - case 0: - /* No fault */ - page_size = 1ULL << zbits; - address &= ~(page_size - 1); - /* FIXME: page_size should probably be passed to tlb_set_page, - and this loop removed. */ - for (end = physical + page_size; physical < end; physical += 0x1000) { - tlb_set_page(env, address, physical, prot, mmu_idx, - TARGET_PAGE_SIZE); - address += 0x1000; - } - ret = 0; - break; -#if 0 - case 1: - env->exception_index = EXCP_DFAULT; - env->ipr[IPR_EXC_ADDR] = address; - ret = 1; - break; - case 2: - env->exception_index = EXCP_ACCESS_VIOLATION; - env->ipr[IPR_EXC_ADDR] = address; - ret = 1; - break; - case 3: - env->exception_index = EXCP_FAULT_ON_READ; - env->ipr[IPR_EXC_ADDR] = address; - ret = 1; - break; - case 4: - env->exception_index = EXCP_FAULT_ON_EXECUTE; - env->ipr[IPR_EXC_ADDR] = address; - ret = 1; - case 5: - env->exception_index = EXCP_FAULT_ON_WRITE; - env->ipr[IPR_EXC_ADDR] = address; - ret = 1; -#endif - default: - /* Should never happen */ - env->exception_index = EXCP_MCHK; - env->ipr[IPR_EXC_ADDR] = address; - ret = 1; - break; - } - - return ret; -} -#endif diff --git a/hw/an5206.c b/hw/an5206.c index b9f19a9..3fe1f00 100644 --- a/hw/an5206.c +++ b/hw/an5206.c @@ -3,30 +3,20 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "hw.h" -#include "pc.h" #include "mcf.h" -#include "sysemu.h" #include "boards.h" #include "loader.h" #include "elf.h" +#include "exec-memory.h" #define KERNEL_LOAD_ADDR 0x10000 #define AN5206_MBAR_ADDR 0x10000000 #define AN5206_RAMBAR_ADDR 0x20000000 -/* Stub functions for hardware that doesn't exist. */ -void pic_info(Monitor *mon) -{ -} - -void irq_info(Monitor *mon) -{ -} - /* Board init. */ static void an5206_init(ram_addr_t ram_size, @@ -38,6 +28,9 @@ static void an5206_init(ram_addr_t ram_size, int kernel_size; uint64_t elf_entry; target_phys_addr_t entry; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *sram = g_new(MemoryRegion, 1); if (!cpu_model) cpu_model = "m5206"; @@ -53,12 +46,12 @@ static void an5206_init(ram_addr_t ram_size, env->rambar0 = AN5206_RAMBAR_ADDR | 1; /* DRAM at address zero */ - cpu_register_physical_memory(0, ram_size, - qemu_ram_alloc(NULL, "an5206.ram", ram_size) | IO_MEM_RAM); + memory_region_init_ram(ram, NULL, "an5206.ram", ram_size); + memory_region_add_subregion(address_space_mem, 0, ram); /* Internal SRAM. */ - cpu_register_physical_memory(AN5206_RAMBAR_ADDR, 512, - qemu_ram_alloc(NULL, "an5206.sram", 512) | IO_MEM_RAM); + memory_region_init_ram(sram, NULL, "an5206.sram", 512); + memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram); mcf5206_init(AN5206_MBAR_ADDR, env); diff --git a/hw/apb_pci.c b/hw/apb_pci.c index 84e9af7..c232946 100644 --- a/hw/apb_pci.c +++ b/hw/apb_pci.c @@ -31,9 +31,9 @@ #include "pci_host.h" #include "pci_bridge.h" #include "pci_internals.h" -#include "rwhandler.h" #include "apb_pci.h" #include "sysemu.h" +#include "exec-memory.h" /* debug APB */ //#define DEBUG_APB @@ -69,7 +69,10 @@ do { printf("APB: " fmt , ## __VA_ARGS__); } while (0) typedef struct APBState { SysBusDevice busdev; PCIBus *bus; - ReadWriteHandler pci_config_handler; + MemoryRegion apb_config; + MemoryRegion pci_config; + MemoryRegion pci_mmio; + MemoryRegion pci_ioport; uint32_t iommu[4]; uint32_t pci_control[16]; uint32_t pci_irq_map[8]; @@ -80,7 +83,7 @@ typedef struct APBState { } APBState; static void apb_config_writel (void *opaque, target_phys_addr_t addr, - uint32_t val) + uint64_t val, unsigned size) { APBState *s = opaque; @@ -127,8 +130,8 @@ static void apb_config_writel (void *opaque, target_phys_addr_t addr, } } -static uint32_t apb_config_readl (void *opaque, - target_phys_addr_t addr) +static uint64_t apb_config_readl (void *opaque, + target_phys_addr_t addr, unsigned size) { APBState *s = opaque; uint32_t val; @@ -175,33 +178,27 @@ static uint32_t apb_config_readl (void *opaque, return val; } -static CPUWriteMemoryFunc * const apb_config_write[] = { - &apb_config_writel, - &apb_config_writel, - &apb_config_writel, +static const MemoryRegionOps apb_config_ops = { + .read = apb_config_readl, + .write = apb_config_writel, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUReadMemoryFunc * const apb_config_read[] = { - &apb_config_readl, - &apb_config_readl, - &apb_config_readl, -}; - -static void apb_pci_config_write(ReadWriteHandler *h, pcibus_t addr, - uint32_t val, int size) +static void apb_pci_config_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - APBState *s = container_of(h, APBState, pci_config_handler); + APBState *s = opaque; val = qemu_bswap_len(val, size); APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val); pci_data_write(s->bus, addr, val, size); } -static uint32_t apb_pci_config_read(ReadWriteHandler *h, pcibus_t addr, - int size) +static uint64_t apb_pci_config_read(void *opaque, target_phys_addr_t addr, + unsigned size) { uint32_t ret; - APBState *s = container_of(h, APBState, pci_config_handler); + APBState *s = opaque; ret = pci_data_read(s->bus, addr, size); ret = qemu_bswap_len(ret, size); @@ -251,16 +248,12 @@ static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr) return val; } -static CPUWriteMemoryFunc * const pci_apb_iowrite[] = { - &pci_apb_iowriteb, - &pci_apb_iowritew, - &pci_apb_iowritel, -}; - -static CPUReadMemoryFunc * const pci_apb_ioread[] = { - &pci_apb_ioreadb, - &pci_apb_ioreadw, - &pci_apb_ioreadl, +static const MemoryRegionOps pci_ioport_ops = { + .old_mmio = { + .read = { pci_apb_ioreadb, pci_apb_ioreadw, pci_apb_ioreadl }, + .write = { pci_apb_iowriteb, pci_apb_iowritew, pci_apb_iowritel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; /* The APB host has an IRQ line for each IRQ line of each slot. */ @@ -304,9 +297,6 @@ static int apb_pci_bridge_initfn(PCIDevice *dev) return rc; } - pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_SUN); - pci_config_set_device_id(dev->config, PCI_DEVICE_ID_SUN_SIMBA); - /* * command register: * According to PCI bridge spec, after reset @@ -321,7 +311,6 @@ static int apb_pci_bridge_initfn(PCIDevice *dev) pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); - pci_set_byte(dev->config + PCI_REVISION_ID, 0x11); return 0; } @@ -348,10 +337,14 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, sysbus_mmio_map(s, 2, special_base + 0x2000000ULL); d = FROM_SYSBUS(APBState, s); + memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL); + memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio); + d->bus = pci_register_bus(&d->busdev.qdev, "pci", - pci_apb_set_irq, pci_pbm_map_irq, d, - 0, 32); - pci_bus_set_mem_base(d->bus, mem_base); + pci_apb_set_irq, pci_pbm_map_irq, d, + &d->pci_mmio, + get_system_io(), + 0, 32); for (i = 0; i < 32; i++) { sysbus_connect_irq(s, i, pic[i]); @@ -394,10 +387,15 @@ static void pci_pbm_reset(DeviceState *d) } } +static const MemoryRegionOps pci_config_ops = { + .read = apb_pci_config_read, + .write = apb_pci_config_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + static int pci_pbm_init_device(SysBusDevice *dev) { APBState *s; - int pci_config, apb_config, pci_ioport; unsigned int i; s = FROM_SYSBUS(APBState, dev); @@ -409,41 +407,32 @@ static int pci_pbm_init_device(SysBusDevice *dev) } /* apb_config */ - apb_config = cpu_register_io_memory(apb_config_read, - apb_config_write, s, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config", + 0x10000); /* at region 0 */ - sysbus_init_mmio(dev, 0x10000ULL, apb_config); + sysbus_init_mmio_region(dev, &s->apb_config); - /* PCI configuration space */ - s->pci_config_handler.read = apb_pci_config_read; - s->pci_config_handler.write = apb_pci_config_write; - pci_config = cpu_register_io_memory_simple(&s->pci_config_handler, - DEVICE_NATIVE_ENDIAN); - assert(pci_config >= 0); + memory_region_init_io(&s->pci_config, &pci_config_ops, s, "apb-pci-config", + 0x1000000); /* at region 1 */ - sysbus_init_mmio(dev, 0x1000000ULL, pci_config); + sysbus_init_mmio_region(dev, &s->pci_config); /* pci_ioport */ - pci_ioport = cpu_register_io_memory(pci_apb_ioread, - pci_apb_iowrite, s, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->pci_ioport, &pci_ioport_ops, s, + "apb-pci-ioport", 0x10000); /* at region 2 */ - sysbus_init_mmio(dev, 0x10000ULL, pci_ioport); + sysbus_init_mmio_region(dev, &s->pci_ioport); return 0; } static int pbm_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE); pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); pci_set_word(d->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); return 0; } @@ -451,6 +440,9 @@ static PCIDeviceInfo pbm_pci_host_info = { .qdev.name = "pbm", .qdev.size = sizeof(PCIDevice), .init = pbm_pci_host_init, + .vendor_id = PCI_VENDOR_ID_SUN, + .device_id = PCI_DEVICE_ID_SUN_SABRE, + .class_id = PCI_CLASS_BRIDGE_HOST, .is_bridge = 1, }; @@ -468,6 +460,9 @@ static PCIDeviceInfo pbm_pci_bridge_info = { .qdev.reset = pci_bridge_reset, .init = apb_pci_bridge_initfn, .exit = pci_bridge_exitfn, + .vendor_id = PCI_VENDOR_ID_SUN, + .device_id = PCI_DEVICE_ID_SUN_SIMBA, + .revision = 0x11, .config_write = pci_bridge_write_config, .is_bridge = 1, }; diff --git a/hw/apic.c b/hw/apic.c index 218d1bb..8289eef 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -23,6 +23,7 @@ #include "host-utils.h" #include "sysbus.h" #include "trace.h" +#include "pc.h" /* APIC Local Vector Table */ #define APIC_LVT_TIMER 0 @@ -80,6 +81,7 @@ typedef struct APICState APICState; struct APICState { SysBusDevice busdev; + MemoryRegion io_memory; void *cpu_env; uint32_t apicbase; uint8_t id; @@ -222,8 +224,7 @@ void apic_deliver_pic_intr(DeviceState *d, int level) } static void apic_bus_deliver(const uint32_t *deliver_bitmask, - uint8_t delivery_mode, - uint8_t vector_num, uint8_t polarity, + uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) { APICState *apic_iter; @@ -280,18 +281,16 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask, apic_set_irq(apic_iter, vector_num, trigger_mode) ); } -void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, - uint8_t delivery_mode, uint8_t vector_num, - uint8_t polarity, uint8_t trigger_mode) +void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, + uint8_t vector_num, uint8_t trigger_mode) { uint32_t deliver_bitmask[MAX_APIC_WORDS]; trace_apic_deliver_irq(dest, dest_mode, delivery_mode, vector_num, - polarity, trigger_mode); + trigger_mode); apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode); - apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity, - trigger_mode); + apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode); } void cpu_set_apic_base(DeviceState *d, uint64_t val) @@ -401,6 +400,9 @@ static void apic_update_irq(APICState *s) } if (apic_irq_pending(s) > 0) { cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); + } else if (apic_accept_pic_intr(&s->busdev.qdev) && + pic_get_output(isa_pic)) { + apic_deliver_pic_intr(&s->busdev.qdev, 1); } } @@ -548,7 +550,7 @@ void apic_sipi(DeviceState *d) static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, - uint8_t polarity, uint8_t trigger_mode) + uint8_t trigger_mode) { APICState *s = DO_UPCAST(APICState, busdev.qdev, d); uint32_t deliver_bitmask[MAX_APIC_WORDS]; @@ -591,8 +593,7 @@ static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode, return; } - apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity, - trigger_mode); + apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode); } int apic_get_interrupt(DeviceState *d) @@ -641,7 +642,7 @@ static uint32_t apic_get_current_count(APICState *s) { int64_t d; uint32_t val; - d = (qemu_get_clock(vm_clock) - s->initial_count_load_time) >> + d = (qemu_get_clock_ns(vm_clock) - s->initial_count_load_time) >> s->count_shift; if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) { /* periodic */ @@ -794,7 +795,7 @@ static void apic_send_msi(target_phys_addr_t addr, uint32_t data) uint8_t trigger_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1; uint8_t delivery = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7; /* XXX: Ignore redirection hint. */ - apic_deliver_irq(dest, dest_mode, delivery, vector, 0, trigger_mode); + apic_deliver_irq(dest, dest_mode, delivery, vector, trigger_mode); } static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) @@ -855,7 +856,7 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) s->icr[0] = val; apic_deliver(d, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff), - (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1); + (s->icr[0] >> 15) & 1); break; case 0x31: s->icr[1] = val; @@ -865,12 +866,12 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) int n = index - 0x32; s->lvt[n] = val; if (n == APIC_LVT_TIMER) - apic_timer_update(s, qemu_get_clock(vm_clock)); + apic_timer_update(s, qemu_get_clock_ns(vm_clock)); } break; case 0x38: s->initial_count = val; - s->initial_count_load_time = qemu_get_clock(vm_clock); + s->initial_count_load_time = qemu_get_clock_ns(vm_clock); apic_timer_update(s, s->initial_count_load_time); break; case 0x39: @@ -979,33 +980,27 @@ static void apic_reset(DeviceState *d) } } -static CPUReadMemoryFunc * const apic_mem_read[3] = { - apic_mem_readb, - apic_mem_readw, - apic_mem_readl, -}; - -static CPUWriteMemoryFunc * const apic_mem_write[3] = { - apic_mem_writeb, - apic_mem_writew, - apic_mem_writel, +static const MemoryRegionOps apic_io_ops = { + .old_mmio = { + .read = { apic_mem_readb, apic_mem_readw, apic_mem_readl, }, + .write = { apic_mem_writeb, apic_mem_writew, apic_mem_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int apic_init1(SysBusDevice *dev) { APICState *s = FROM_SYSBUS(APICState, dev); - int apic_io_memory; static int last_apic_idx; if (last_apic_idx >= MAX_APICS) { return -1; } - apic_io_memory = cpu_register_io_memory(apic_mem_read, - apic_mem_write, NULL, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MSI_ADDR_SIZE, apic_io_memory); + memory_region_init_io(&s->io_memory, &apic_io_ops, s, "apic", + MSI_ADDR_SIZE); + sysbus_init_mmio_region(dev, &s->io_memory); - s->timer = qemu_new_timer(vm_clock, apic_timer, s); + s->timer = qemu_new_timer_ns(vm_clock, apic_timer, s); s->idx = last_apic_idx++; local_apics[s->idx] = s; return 0; diff --git a/hw/apic.h b/hw/apic.h index 8a0c9d0..a5c910f 100644 --- a/hw/apic.h +++ b/hw/apic.h @@ -4,10 +4,8 @@ #include "qemu-common.h" /* apic.c */ -void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, - uint8_t delivery_mode, - uint8_t vector_num, uint8_t polarity, - uint8_t trigger_mode); +void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, + uint8_t vector_num, uint8_t trigger_mode); int apic_accept_pic_intr(DeviceState *s); void apic_deliver_pic_intr(DeviceState *s, int level); int apic_get_interrupt(DeviceState *s); diff --git a/hw/applesmc.c b/hw/applesmc.c index 23ed328..c47b592 100644 --- a/hw/applesmc.c +++ b/hw/applesmc.c @@ -170,7 +170,7 @@ static void applesmc_add_key(struct AppleSMCStatus *s, const char *key, { struct AppleSMCData *def; - def = qemu_mallocz(sizeof(struct AppleSMCData)); + def = g_malloc0(sizeof(struct AppleSMCData)); def->key = key; def->len = len; def->data = data; diff --git a/hw/arm-misc.h b/hw/arm-misc.h index 010acb4..af403a1 100644 --- a/hw/arm-misc.h +++ b/hw/arm-misc.h @@ -4,20 +4,23 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. * */ #ifndef ARM_MISC_H #define ARM_MISC_H 1 +#include "memory.h" + /* The CPU is also modeled as an interrupt controller. */ #define ARM_PIC_CPU_IRQ 0 #define ARM_PIC_CPU_FIQ 1 qemu_irq *arm_pic_init_cpu(CPUState *env); /* armv7m.c */ -qemu_irq *armv7m_init(int flash_size, int sram_size, +qemu_irq *armv7m_init(MemoryRegion *address_space_mem, + int flash_size, int sram_size, const char *kernel_filename, const char *cpu_model); /* arm_boot.c */ @@ -31,7 +34,7 @@ struct arm_boot_info { target_phys_addr_t smp_priv_base; int nb_cpus; int board_id; - int (*atag_board)(struct arm_boot_info *info, void *p); + int (*atag_board)(const struct arm_boot_info *info, void *p); /* Used internally by arm_boot.c */ int is_linux; target_phys_addr_t initrd_size; diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c index 3bbd885..974a0d8 100644 --- a/hw/arm11mpcore.c +++ b/hw/arm11mpcore.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ /* ??? The MPCore TRM says the on-chip controller has 224 external IRQ lines @@ -48,12 +48,6 @@ static void mpcore_rirq_set_irq(void *opaque, int irq, int level) } } -static void mpcore_rirq_map(SysBusDevice *dev, target_phys_addr_t base) -{ - mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev); - sysbus_mmio_map(s->priv, 0, base); -} - static int realview_mpcore_init(SysBusDevice *dev) { mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev); @@ -79,7 +73,7 @@ static int realview_mpcore_init(SysBusDevice *dev) } } qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64); - sysbus_init_mmio_cb(dev, 0x2000, mpcore_rirq_map); + sysbus_init_mmio_region(dev, sysbus_mmio_get_region(s->priv, 0)); return 0; } diff --git a/hw/arm_boot.c b/hw/arm_boot.c index 620550b..215d5de 100644 --- a/hw/arm_boot.c +++ b/hw/arm_boot.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "hw.h" @@ -15,7 +15,7 @@ #define KERNEL_ARGS_ADDR 0x100 #define KERNEL_LOAD_ADDR 0x00010000 -#define INITRD_LOAD_ADDR 0x00800000 +#define INITRD_LOAD_ADDR 0x00d00000 /* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */ static uint32_t bootloader[] = { @@ -49,7 +49,7 @@ static uint32_t smpboot[] = { p += 4; \ } while (0) -static void set_kernel_args(struct arm_boot_info *info, +static void set_kernel_args(const struct arm_boot_info *info, int initrd_size, target_phys_addr_t base) { target_phys_addr_t p; @@ -102,7 +102,7 @@ static void set_kernel_args(struct arm_boot_info *info, WRITE_WORD(p, 0); } -static void set_kernel_args_old(struct arm_boot_info *info, +static void set_kernel_args_old(const struct arm_boot_info *info, int initrd_size, target_phys_addr_t base) { target_phys_addr_t p; @@ -175,10 +175,10 @@ static void set_kernel_args_old(struct arm_boot_info *info, } } -static void main_cpu_reset(void *opaque) +static void do_cpu_reset(void *opaque) { CPUState *env = opaque; - struct arm_boot_info *info = env->boot_info; + const struct arm_boot_info *info = env->boot_info; cpu_reset(env); if (info) { @@ -187,16 +187,20 @@ static void main_cpu_reset(void *opaque) env->regs[15] = info->entry & 0xfffffffe; env->thumb = info->entry & 1; } else { - env->regs[15] = info->loader_start; - if (old_param) { - set_kernel_args_old(info, info->initrd_size, + if (env == first_cpu) { + env->regs[15] = info->loader_start; + if (old_param) { + set_kernel_args_old(info, info->initrd_size, + info->loader_start); + } else { + set_kernel_args(info, info->initrd_size, info->loader_start); + } } else { - set_kernel_args(info, info->initrd_size, info->loader_start); + env->regs[15] = info->smp_loader_start; } } } - /* TODO: Reset secondary CPUs. */ } void arm_load_kernel(CPUState *env, struct arm_boot_info *info) @@ -217,7 +221,6 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) if (info->nb_cpus == 0) info->nb_cpus = 1; - env->boot_info = info; #ifdef TARGET_WORDS_BIGENDIAN big_endian = 1; @@ -279,5 +282,9 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) info->initrd_size = initrd_size; } info->is_linux = is_linux; - qemu_register_reset(main_cpu_reset, env); + + for (; env; env = env->next_cpu) { + env->boot_info = info; + qemu_register_reset(do_cpu_reset, env); + } } diff --git a/hw/arm_gic.c b/hw/arm_gic.c index e6b1953..f3f3516 100644 --- a/hw/arm_gic.c +++ b/hw/arm_gic.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ /* This file contains implementation code for the RealView EB interrupt @@ -37,9 +37,8 @@ static const uint8_t gic_id[] = typedef struct gic_irq_state { - /* ??? The documentation seems to imply the enable bits are global, even - for per-cpu interrupts. This seems strange. */ - unsigned enabled:1; + /* The enable bits are only banked for per-cpu interrupts. */ + unsigned enabled:NCPU; unsigned pending:NCPU; unsigned active:NCPU; unsigned level:NCPU; @@ -54,9 +53,9 @@ typedef struct gic_irq_state #define NUM_CPU(s) 1 #endif -#define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1 -#define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0 -#define GIC_TEST_ENABLED(irq) s->irq_state[irq].enabled +#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm) +#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm) +#define GIC_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm)) != 0) #define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |= (cm) #define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &= ~(cm) #define GIC_TEST_PENDING(irq, cm) ((s->irq_state[irq].pending & (cm)) != 0) @@ -104,7 +103,7 @@ typedef struct gic_state int num_cpu; #endif - int iomemtype; + MemoryRegion iomem; } gic_state; /* TODO: Many places that call this routine could be optimized. */ @@ -128,7 +127,7 @@ static void gic_update(gic_state *s) best_prio = 0x100; best_irq = 1023; for (irq = 0; irq < GIC_NIRQ; irq++) { - if (GIC_TEST_ENABLED(irq) && GIC_TEST_PENDING(irq, cm)) { + if (GIC_TEST_ENABLED(irq, cm) && GIC_TEST_PENDING(irq, cm)) { if (GIC_GET_PRIORITY(irq, cpu) < best_prio) { best_prio = GIC_GET_PRIORITY(irq, cpu); best_irq = irq; @@ -171,7 +170,7 @@ static void gic_set_irq(void *opaque, int irq, int level) if (level) { GIC_SET_LEVEL(irq, ALL_CPU_MASK); - if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq)) { + if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, ALL_CPU_MASK)) { DPRINTF("Set %d pending mask %x\n", irq, GIC_TARGET(irq)); GIC_SET_PENDING(irq, GIC_TARGET(irq)); } @@ -221,7 +220,7 @@ static void gic_complete_irq(gic_state * s, int cpu, int irq) if (irq != 1023) { /* Mark level triggered interrupts as pending if they are still raised. */ - if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq) + if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq, cm) && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) != 0) { DPRINTF("Set %d pending mask %x\n", irq, cm); GIC_SET_PENDING(irq, cm); @@ -280,7 +279,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) goto bad_reg; res = 0; for (i = 0; i < 8; i++) { - if (GIC_TEST_ENABLED(irq + i)) { + if (GIC_TEST_ENABLED(irq + i, cm)) { res |= (1 << i); } } @@ -412,9 +411,12 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, for (i = 0; i < 8; i++) { if (value & (1 << i)) { int mask = (irq < 32) ? (1 << cpu) : GIC_TARGET(irq); - if (!GIC_TEST_ENABLED(irq + i)) + int cm = (irq < 32) ? (1 << cpu) : ALL_CPU_MASK; + + if (!GIC_TEST_ENABLED(irq + i, cm)) { DPRINTF("Enabled IRQ %d\n", irq + i); - GIC_SET_ENABLED(irq + i); + } + GIC_SET_ENABLED(irq + i, cm); /* If a raised level triggered IRQ enabled then mark is as pending. */ if (GIC_TEST_LEVEL(irq + i, mask) @@ -433,9 +435,12 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, value = 0; for (i = 0; i < 8; i++) { if (value & (1 << i)) { - if (GIC_TEST_ENABLED(irq + i)) + int cm = (irq < 32) ? (1 << cpu) : ALL_CPU_MASK; + + if (GIC_TEST_ENABLED(irq + i, cm)) { DPRINTF("Disabled IRQ %d\n", irq + i); - GIC_CLEAR_ENABLED(irq + i); + } + GIC_CLEAR_ENABLED(irq + i, cm); } } } else if (offset < 0x280) { @@ -549,10 +554,10 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset, mask = (value >> 16) & ALL_CPU_MASK; break; case 1: - mask = 1 << cpu; + mask = ALL_CPU_MASK ^ (1 << cpu); break; case 2: - mask = ALL_CPU_MASK ^ (1 << cpu); + mask = 1 << cpu; break; default: DPRINTF("Bad Soft Int target filter\n"); @@ -567,16 +572,12 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset, gic_dist_writew(opaque, offset + 2, value >> 16); } -static CPUReadMemoryFunc * const gic_dist_readfn[] = { - gic_dist_readb, - gic_dist_readw, - gic_dist_readl -}; - -static CPUWriteMemoryFunc * const gic_dist_writefn[] = { - gic_dist_writeb, - gic_dist_writew, - gic_dist_writel +static const MemoryRegionOps gic_dist_ops = { + .old_mmio = { + .read = { gic_dist_readb, gic_dist_readw, gic_dist_readl, }, + .write = { gic_dist_writeb, gic_dist_writew, gic_dist_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; #ifndef NVIC @@ -642,7 +643,7 @@ static void gic_reset(gic_state *s) #endif } for (i = 0; i < 16; i++) { - GIC_SET_ENABLED(i); + GIC_SET_ENABLED(i, ALL_CPU_MASK); GIC_SET_TRIGGER(i); } #ifdef NVIC @@ -662,9 +663,6 @@ static void gic_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->enabled); for (i = 0; i < NUM_CPU(s); i++) { qemu_put_be32(f, s->cpu_enabled[i]); -#ifndef NVIC - qemu_put_be32(f, s->irq_target[i]); -#endif for (j = 0; j < 32; j++) qemu_put_be32(f, s->priority1[j][i]); for (j = 0; j < GIC_NIRQ; j++) @@ -678,6 +676,9 @@ static void gic_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->priority2[i]); } for (i = 0; i < GIC_NIRQ; i++) { +#ifndef NVIC + qemu_put_be32(f, s->irq_target[i]); +#endif qemu_put_byte(f, s->irq_state[i].enabled); qemu_put_byte(f, s->irq_state[i].pending); qemu_put_byte(f, s->irq_state[i].active); @@ -693,15 +694,12 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id) int i; int j; - if (version_id != 1) + if (version_id != 2) return -EINVAL; s->enabled = qemu_get_be32(f); for (i = 0; i < NUM_CPU(s); i++) { s->cpu_enabled[i] = qemu_get_be32(f); -#ifndef NVIC - s->irq_target[i] = qemu_get_be32(f); -#endif for (j = 0; j < 32; j++) s->priority1[j][i] = qemu_get_be32(f); for (j = 0; j < GIC_NIRQ; j++) @@ -715,6 +713,9 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id) s->priority2[i] = qemu_get_be32(f); } for (i = 0; i < GIC_NIRQ; i++) { +#ifndef NVIC + s->irq_target[i] = qemu_get_be32(f); +#endif s->irq_state[i].enabled = qemu_get_byte(f); s->irq_state[i].pending = qemu_get_byte(f); s->irq_state[i].active = qemu_get_byte(f); @@ -741,9 +742,7 @@ static void gic_init(gic_state *s) for (i = 0; i < NUM_CPU(s); i++) { sysbus_init_irq(&s->busdev, &s->parent_irq[i]); } - s->iomemtype = cpu_register_io_memory(gic_dist_readfn, - gic_dist_writefn, s, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000); gic_reset(s); - register_savevm(NULL, "arm_gic", -1, 1, gic_save, gic_load, s); + register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s); } diff --git a/hw/arm_pic.c b/hw/arm_pic.c index f44568c..a2e8a73 100644 --- a/hw/arm_pic.c +++ b/hw/arm_pic.c @@ -4,23 +4,12 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the LGPL + * This code is licensed under the LGPL */ #include "hw.h" -#include "pc.h" #include "arm-misc.h" -/* Stub functions for hardware that doesn't exist. */ -void pic_info(Monitor *mon) -{ -} - -void irq_info(Monitor *mon) -{ -} - - /* Input 0 is IRQ and input 1 is FIQ. */ static void arm_pic_cpu_handler(void *opaque, int irq, int level) { @@ -39,7 +28,7 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level) cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ); break; default: - hw_error("arm_pic_cpu_handler: Bad interrput line %d\n", irq); + hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq); } } diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c index d8b062c..477fc6f 100644 --- a/hw/arm_sysctl.c +++ b/hw/arm_sysctl.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "hw.h" @@ -17,6 +17,9 @@ typedef struct { SysBusDevice busdev; + MemoryRegion iomem; + qemu_irq pl110_mux_ctrl; + uint32_t sys_id; uint32_t leds; uint16_t lockval; @@ -26,11 +29,16 @@ typedef struct { uint32_t nvflags; uint32_t resetlevel; uint32_t proc_id; + uint32_t sys_mci; + uint32_t sys_cfgdata; + uint32_t sys_cfgctrl; + uint32_t sys_cfgstat; + uint32_t sys_clcd; } arm_sysctl_state; static const VMStateDescription vmstate_arm_sysctl = { .name = "realview_sysctl", - .version_id = 1, + .version_id = 3, .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_UINT32(leds, arm_sysctl_state), @@ -40,10 +48,31 @@ static const VMStateDescription vmstate_arm_sysctl = { VMSTATE_UINT32(flags, arm_sysctl_state), VMSTATE_UINT32(nvflags, arm_sysctl_state), VMSTATE_UINT32(resetlevel, arm_sysctl_state), + VMSTATE_UINT32_V(sys_mci, arm_sysctl_state, 2), + VMSTATE_UINT32_V(sys_cfgdata, arm_sysctl_state, 2), + VMSTATE_UINT32_V(sys_cfgctrl, arm_sysctl_state, 2), + VMSTATE_UINT32_V(sys_cfgstat, arm_sysctl_state, 2), + VMSTATE_UINT32_V(sys_clcd, arm_sysctl_state, 3), VMSTATE_END_OF_LIST() } }; +/* The PB926 actually uses a different format for + * its SYS_ID register. Fortunately the bits which are + * board type on later boards are distinct. + */ +#define BOARD_ID_PB926 0x100 +#define BOARD_ID_EB 0x140 +#define BOARD_ID_PBA8 0x178 +#define BOARD_ID_PBX 0x182 +#define BOARD_ID_VEXPRESS 0x190 + +static int board_id(arm_sysctl_state *s) +{ + /* Extract the board ID field from the SYS_ID register value */ + return (s->sys_id >> 16) & 0xfff; +} + static void arm_sysctl_reset(DeviceState *d) { arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, sysbus_from_qdev(d)); @@ -54,9 +83,17 @@ static void arm_sysctl_reset(DeviceState *d) s->cfgdata2 = 0; s->flags = 0; s->resetlevel = 0; + if (board_id(s) == BOARD_ID_VEXPRESS) { + /* On VExpress this register will RAZ/WI */ + s->sys_clcd = 0; + } else { + /* All others: CLCDID 0x1f, indicating VGA */ + s->sys_clcd = 0x1f00; + } } -static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) +static uint64_t arm_sysctl_read(void *opaque, target_phys_addr_t offset, + unsigned size) { arm_sysctl_state *s = (arm_sysctl_state *)opaque; @@ -88,21 +125,25 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) case 0x38: /* NVFLAGS */ return s->nvflags; case 0x40: /* RESETCTL */ + if (board_id(s) == BOARD_ID_VEXPRESS) { + /* reserved: RAZ/WI */ + return 0; + } return s->resetlevel; case 0x44: /* PCICTL */ return 1; case 0x48: /* MCI */ - return 0; + return s->sys_mci; case 0x4c: /* FLASH */ return 0; case 0x50: /* CLCD */ - return 0x1000; + return s->sys_clcd; case 0x54: /* CLCDSER */ return 0; case 0x58: /* BOOTCS */ return 0; case 0x5c: /* 24MHz */ - return muldiv64(qemu_get_clock(vm_clock), 24000000, get_ticks_per_sec()); + return muldiv64(qemu_get_clock_ns(vm_clock), 24000000, get_ticks_per_sec()); case 0x60: /* MISC */ return 0; case 0x84: /* PROCID0 */ @@ -126,14 +167,30 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) case 0xcc: /* SYS_TEST_OSC3 */ case 0xd0: /* SYS_TEST_OSC4 */ return 0; + case 0xa0: /* SYS_CFGDATA */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + return s->sys_cfgdata; + case 0xa4: /* SYS_CFGCTRL */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + return s->sys_cfgctrl; + case 0xa8: /* SYS_CFGSTAT */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + return s->sys_cfgstat; default: + bad_reg: printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset); return 0; } } static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, - uint32_t val) + uint64_t val, unsigned size) { arm_sysctl_state *s = (arm_sysctl_state *)opaque; @@ -174,17 +231,68 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, s->nvflags &= ~val; break; case 0x40: /* RESETCTL */ - if (s->lockval == LOCK_VALUE) { - s->resetlevel = val; - if (val & 0x100) - qemu_system_reset_request (); + switch (board_id(s)) { + case BOARD_ID_PB926: + if (s->lockval == LOCK_VALUE) { + s->resetlevel = val; + if (val & 0x100) { + qemu_system_reset_request(); + } + } + break; + case BOARD_ID_PBX: + case BOARD_ID_PBA8: + if (s->lockval == LOCK_VALUE) { + s->resetlevel = val; + if (val & 0x04) { + qemu_system_reset_request(); + } + } + break; + case BOARD_ID_VEXPRESS: + case BOARD_ID_EB: + default: + /* reserved: RAZ/WI */ + break; } break; case 0x44: /* PCICTL */ /* nothing to do. */ break; case 0x4c: /* FLASH */ + break; case 0x50: /* CLCD */ + switch (board_id(s)) { + case BOARD_ID_PB926: + /* On 926 bits 13:8 are R/O, bits 1:0 control + * the mux that defines how to interpret the PL110 + * graphics format, and other bits are r/w but we + * don't implement them to do anything. + */ + s->sys_clcd &= 0x3f00; + s->sys_clcd |= val & ~0x3f00; + qemu_set_irq(s->pl110_mux_ctrl, val & 3); + break; + case BOARD_ID_EB: + /* The EB is the same except that there is no mux since + * the EB has a PL111. + */ + s->sys_clcd &= 0x3f00; + s->sys_clcd |= val & ~0x3f00; + break; + case BOARD_ID_PBA8: + case BOARD_ID_PBX: + /* On PBA8 and PBX bit 7 is r/w and all other bits + * are either r/o or RAZ/WI. + */ + s->sys_clcd &= (1 << 7); + s->sys_clcd |= val & ~(1 << 7); + break; + case BOARD_ID_VEXPRESS: + default: + /* On VExpress this register is unimplemented and will RAZ/WI */ + break; + } case 0x54: /* CLCDSER */ case 0x64: /* DMAPSR0 */ case 0x68: /* DMAPSR1 */ @@ -200,34 +308,84 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, case 0x98: /* OSCRESET3 */ case 0x9c: /* OSCRESET4 */ break; + case 0xa0: /* SYS_CFGDATA */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + s->sys_cfgdata = val; + return; + case 0xa4: /* SYS_CFGCTRL */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + s->sys_cfgctrl = val & ~(3 << 18); + s->sys_cfgstat = 1; /* complete */ + switch (s->sys_cfgctrl) { + case 0xc0800000: /* SYS_CFG_SHUTDOWN to motherboard */ + qemu_system_shutdown_request(); + break; + case 0xc0900000: /* SYS_CFG_REBOOT to motherboard */ + qemu_system_reset_request(); + break; + default: + s->sys_cfgstat |= 2; /* error */ + } + return; + case 0xa8: /* SYS_CFGSTAT */ + if (board_id(s) != BOARD_ID_VEXPRESS) { + goto bad_reg; + } + s->sys_cfgstat = val & 3; + return; default: + bad_reg: printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset); return; } } -static CPUReadMemoryFunc * const arm_sysctl_readfn[] = { - arm_sysctl_read, - arm_sysctl_read, - arm_sysctl_read +static const MemoryRegionOps arm_sysctl_ops = { + .read = arm_sysctl_read, + .write = arm_sysctl_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const arm_sysctl_writefn[] = { - arm_sysctl_write, - arm_sysctl_write, - arm_sysctl_write -}; +static void arm_sysctl_gpio_set(void *opaque, int line, int level) +{ + arm_sysctl_state *s = (arm_sysctl_state *)opaque; + switch (line) { + case ARM_SYSCTL_GPIO_MMC_WPROT: + { + /* For PB926 and EB write-protect is bit 2 of SYS_MCI; + * for all later boards it is bit 1. + */ + int bit = 2; + if ((board_id(s) == BOARD_ID_PB926) || (board_id(s) == BOARD_ID_EB)) { + bit = 4; + } + s->sys_mci &= ~bit; + if (level) { + s->sys_mci |= bit; + } + break; + } + case ARM_SYSCTL_GPIO_MMC_CARDIN: + s->sys_mci &= ~1; + if (level) { + s->sys_mci |= 1; + } + break; + } +} static int arm_sysctl_init1(SysBusDevice *dev) { arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, dev); - int iomemtype; - iomemtype = cpu_register_io_memory(arm_sysctl_readfn, - arm_sysctl_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, iomemtype); - /* ??? Save/restore. */ + memory_region_init_io(&s->iomem, &arm_sysctl_ops, s, "arm-sysctl", 0x1000); + sysbus_init_mmio_region(dev, &s->iomem); + qdev_init_gpio_in(&s->busdev.qdev, arm_sysctl_gpio_set, 2); + qdev_init_gpio_out(&s->busdev.qdev, &s->pl110_mux_ctrl, 1); return 0; } diff --git a/hw/arm_timer.c b/hw/arm_timer.c index 82f05de..66db81d 100644 --- a/hw/arm_timer.c +++ b/hw/arm_timer.c @@ -4,7 +4,7 @@ * Copyright (c) 2005-2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -140,41 +140,32 @@ static void arm_timer_tick(void *opaque) arm_timer_update(s); } -static void arm_timer_save(QEMUFile *f, void *opaque) -{ - arm_timer_state *s = (arm_timer_state *)opaque; - qemu_put_be32(f, s->control); - qemu_put_be32(f, s->limit); - qemu_put_be32(f, s->int_level); - qemu_put_ptimer(f, s->timer); -} - -static int arm_timer_load(QEMUFile *f, void *opaque, int version_id) -{ - arm_timer_state *s = (arm_timer_state *)opaque; - - if (version_id != 1) - return -EINVAL; - - s->control = qemu_get_be32(f); - s->limit = qemu_get_be32(f); - s->int_level = qemu_get_be32(f); - qemu_get_ptimer(f, s->timer); - return 0; -} +static const VMStateDescription vmstate_arm_timer = { + .name = "arm_timer", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(control, arm_timer_state), + VMSTATE_UINT32(limit, arm_timer_state), + VMSTATE_INT32(int_level, arm_timer_state), + VMSTATE_PTIMER(timer, arm_timer_state), + VMSTATE_END_OF_LIST() + } +}; static arm_timer_state *arm_timer_init(uint32_t freq) { arm_timer_state *s; QEMUBH *bh; - s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state)); + s = (arm_timer_state *)g_malloc0(sizeof(arm_timer_state)); s->freq = freq; s->control = TIMER_CTRL_IE; bh = qemu_bh_new(arm_timer_tick, s); s->timer = ptimer_init(bh); - register_savevm(NULL, "arm_timer", -1, 1, arm_timer_save, arm_timer_load, s); + vmstate_register(NULL, -1, &vmstate_arm_timer, s); return s; } @@ -185,6 +176,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq) typedef struct { SysBusDevice busdev; + MemoryRegion iomem; arm_timer_state *timer[2]; int level[2]; qemu_irq irq; @@ -199,7 +191,8 @@ static void sp804_set_irq(void *opaque, int irq, int level) qemu_set_irq(s->irq, s->level[0] || s->level[1]); } -static uint32_t sp804_read(void *opaque, target_phys_addr_t offset) +static uint64_t sp804_read(void *opaque, target_phys_addr_t offset, + unsigned size) { sp804_state *s = (sp804_state *)opaque; @@ -212,7 +205,7 @@ static uint32_t sp804_read(void *opaque, target_phys_addr_t offset) } static void sp804_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { sp804_state *s = (sp804_state *)opaque; @@ -223,40 +216,25 @@ static void sp804_write(void *opaque, target_phys_addr_t offset, } } -static CPUReadMemoryFunc * const sp804_readfn[] = { - sp804_read, - sp804_read, - sp804_read +static const MemoryRegionOps sp804_ops = { + .read = sp804_read, + .write = sp804_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const sp804_writefn[] = { - sp804_write, - sp804_write, - sp804_write +static const VMStateDescription vmstate_sp804 = { + .name = "sp804", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32_ARRAY(level, sp804_state, 2), + VMSTATE_END_OF_LIST() + } }; -static void sp804_save(QEMUFile *f, void *opaque) -{ - sp804_state *s = (sp804_state *)opaque; - qemu_put_be32(f, s->level[0]); - qemu_put_be32(f, s->level[1]); -} - -static int sp804_load(QEMUFile *f, void *opaque, int version_id) -{ - sp804_state *s = (sp804_state *)opaque; - - if (version_id != 1) - return -EINVAL; - - s->level[0] = qemu_get_be32(f); - s->level[1] = qemu_get_be32(f); - return 0; -} - static int sp804_init(SysBusDevice *dev) { - int iomemtype; sp804_state *s = FROM_SYSBUS(sp804_state, dev); qemu_irq *qi; @@ -268,10 +246,9 @@ static int sp804_init(SysBusDevice *dev) s->timer[1] = arm_timer_init(1000000); s->timer[0]->irq = qi[0]; s->timer[1]->irq = qi[1]; - iomemtype = cpu_register_io_memory(sp804_readfn, - sp804_writefn, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, iomemtype); - register_savevm(&dev->qdev, "sp804", -1, 1, sp804_save, sp804_load, s); + memory_region_init_io(&s->iomem, &sp804_ops, s, "sp804", 0x1000); + sysbus_init_mmio_region(dev, &s->iomem); + vmstate_register(&dev->qdev, -1, &vmstate_sp804, s); return 0; } @@ -280,17 +257,19 @@ static int sp804_init(SysBusDevice *dev) typedef struct { SysBusDevice busdev; + MemoryRegion iomem; arm_timer_state *timer[3]; } icp_pit_state; -static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset) +static uint64_t icp_pit_read(void *opaque, target_phys_addr_t offset, + unsigned size) { icp_pit_state *s = (icp_pit_state *)opaque; int n; /* ??? Don't know the PrimeCell ID for this device. */ n = offset >> 8; - if (n > 3) { + if (n > 2) { hw_error("sp804_read: Bad timer %d\n", n); } @@ -298,35 +277,27 @@ static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset) } static void icp_pit_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { icp_pit_state *s = (icp_pit_state *)opaque; int n; n = offset >> 8; - if (n > 3) { + if (n > 2) { hw_error("sp804_write: Bad timer %d\n", n); } arm_timer_write(s->timer[n], offset & 0xff, value); } - -static CPUReadMemoryFunc * const icp_pit_readfn[] = { - icp_pit_read, - icp_pit_read, - icp_pit_read -}; - -static CPUWriteMemoryFunc * const icp_pit_writefn[] = { - icp_pit_write, - icp_pit_write, - icp_pit_write +static const MemoryRegionOps icp_pit_ops = { + .read = icp_pit_read, + .write = icp_pit_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int icp_pit_init(SysBusDevice *dev) { - int iomemtype; icp_pit_state *s = FROM_SYSBUS(icp_pit_state, dev); /* Timer 0 runs at the system clock speed (40MHz). */ @@ -339,10 +310,8 @@ static int icp_pit_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->timer[1]->irq); sysbus_init_irq(dev, &s->timer[2]->irq); - iomemtype = cpu_register_io_memory(icp_pit_readfn, - icp_pit_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, iomemtype); + memory_region_init_io(&s->iomem, &icp_pit_ops, s, "icp_pit", 0x1000); + sysbus_init_mmio_region(dev, &s->iomem); /* This device has no state to save/restore. The component timers will save themselves. */ return 0; diff --git a/hw/armv7m.c b/hw/armv7m.c index 304cd34..28d41b8 100644 --- a/hw/armv7m.c +++ b/hw/armv7m.c @@ -4,18 +4,17 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" #include "arm-misc.h" -#include "sysemu.h" #include "loader.h" #include "elf.h" /* Bitbanded IO. Each word corresponds to a single bit. */ -/* Get the byte address of the real memory for a bitband acess. */ +/* Get the byte address of the real memory for a bitband access. */ static inline uint32_t bitband_addr(void * opaque, uint32_t addr) { uint32_t res; @@ -107,31 +106,27 @@ static void bitband_writel(void *opaque, target_phys_addr_t offset, cpu_physical_memory_write(addr, (uint8_t *)&v, 4); } -static CPUReadMemoryFunc * const bitband_readfn[] = { - bitband_readb, - bitband_readw, - bitband_readl -}; - -static CPUWriteMemoryFunc * const bitband_writefn[] = { - bitband_writeb, - bitband_writew, - bitband_writel +static const MemoryRegionOps bitband_ops = { + .old_mmio = { + .read = { bitband_readb, bitband_readw, bitband_readl, }, + .write = { bitband_writeb, bitband_writew, bitband_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; typedef struct { SysBusDevice busdev; + MemoryRegion iomem; uint32_t base; } BitBandState; static int bitband_init(SysBusDevice *dev) { BitBandState *s = FROM_SYSBUS(BitBandState, dev); - int iomemtype; - iomemtype = cpu_register_io_memory(bitband_readfn, bitband_writefn, - &s->base, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x02000000, iomemtype); + memory_region_init_io(&s->iomem, &bitband_ops, &s->base, "bitband", + 0x02000000); + sysbus_init_mmio_region(dev, &s->iomem); return 0; } @@ -161,7 +156,8 @@ static void armv7m_reset(void *opaque) flash_size and sram_size are in kb. Returns the NVIC array. */ -qemu_irq *armv7m_init(int flash_size, int sram_size, +qemu_irq *armv7m_init(MemoryRegion *address_space_mem, + int flash_size, int sram_size, const char *kernel_filename, const char *cpu_model) { CPUState *env; @@ -174,6 +170,9 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, uint64_t lowaddr; int i; int big_endian; + MemoryRegion *sram = g_new(MemoryRegion, 1); + MemoryRegion *flash = g_new(MemoryRegion, 1); + MemoryRegion *hack = g_new(MemoryRegion, 1); flash_size *= 1024; sram_size *= 1024; @@ -199,12 +198,11 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, #endif /* Flash programming is done via the SCU, so pretend it is ROM. */ - cpu_register_physical_memory(0, flash_size, - qemu_ram_alloc(NULL, "armv7m.flash", - flash_size) | IO_MEM_ROM); - cpu_register_physical_memory(0x20000000, sram_size, - qemu_ram_alloc(NULL, "armv7m.sram", - sram_size) | IO_MEM_RAM); + memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size); + memory_region_set_readonly(flash, true); + memory_region_add_subregion(address_space_mem, 0, flash); + memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size); + memory_region_add_subregion(address_space_mem, 0x20000000, sram); armv7m_bitband_init(); nvic = qdev_create(NULL, "armv7m_nvic"); @@ -237,9 +235,8 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, /* Hack to map an additional page of ram at the top of the address space. This stops qemu complaining about executing code outside RAM when returning from an exception. */ - cpu_register_physical_memory(0xfffff000, 0x1000, - qemu_ram_alloc(NULL, "armv7m.hack", - 0x1000) | IO_MEM_RAM); + memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000); + memory_region_add_subregion(address_space_mem, 0xfffff000, hack); qemu_register_reset(armv7m_reset, env); return pic; diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c index 6c7ce01..bf8c3c5 100644 --- a/hw/armv7m_nvic.c +++ b/hw/armv7m_nvic.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. * * The ARMv7M System controller is fairly tightly tied in with the * NVIC. Much of that is also implemented here. @@ -13,6 +13,7 @@ #include "sysbus.h" #include "qemu-timer.h" #include "arm-misc.h" +#include "exec-memory.h" /* 32 internal lines (16 used for system exceptions) plus 64 external interrupt lines. */ @@ -64,7 +65,7 @@ static inline int64_t systick_scale(nvic_state *s) static void systick_reload(nvic_state *s, int reset) { if (reset) - s->systick.tick = qemu_get_clock(vm_clock); + s->systick.tick = qemu_get_clock_ns(vm_clock); s->systick.tick += (s->systick.reload + 1) * systick_scale(s); qemu_mod_timer(s->systick.timer, s->systick.tick); } @@ -136,7 +137,7 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) int64_t t; if ((s->systick.control & SYSTICK_ENABLE) == 0) return 0; - t = qemu_get_clock(vm_clock); + t = qemu_get_clock_ns(vm_clock); if (t >= s->systick.tick) return 0; val = ((s->systick.tick - (t + 1)) / systick_scale(s)) + 1; @@ -273,7 +274,7 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) s->systick.control &= 0xfffffff8; s->systick.control |= value & 7; if ((oldval ^ value) & SYSTICK_ENABLE) { - int64_t now = qemu_get_clock(vm_clock); + int64_t now = qemu_get_clock_ns(vm_clock); if (value & SYSTICK_ENABLE) { if (s->systick.tick) { s->systick.tick += now; @@ -365,39 +366,28 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) } } -static void nvic_save(QEMUFile *f, void *opaque) -{ - nvic_state *s = (nvic_state *)opaque; - - qemu_put_be32(f, s->systick.control); - qemu_put_be32(f, s->systick.reload); - qemu_put_be64(f, s->systick.tick); - qemu_put_timer(f, s->systick.timer); -} - -static int nvic_load(QEMUFile *f, void *opaque, int version_id) -{ - nvic_state *s = (nvic_state *)opaque; - - if (version_id != 1) - return -EINVAL; - - s->systick.control = qemu_get_be32(f); - s->systick.reload = qemu_get_be32(f); - s->systick.tick = qemu_get_be64(f); - qemu_get_timer(f, s->systick.timer); - - return 0; -} +static const VMStateDescription vmstate_nvic = { + .name = "armv7m_nvic", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(systick.control, nvic_state), + VMSTATE_UINT32(systick.reload, nvic_state), + VMSTATE_INT64(systick.tick, nvic_state), + VMSTATE_TIMER(systick.timer, nvic_state), + VMSTATE_END_OF_LIST() + } +}; static int armv7m_nvic_init(SysBusDevice *dev) { nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev); gic_init(&s->gic); - cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype); - s->systick.timer = qemu_new_timer(vm_clock, systick_timer_tick, s); - register_savevm(&dev->qdev, "armv7m_nvic", -1, 1, nvic_save, nvic_load, s); + memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem); + s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s); + vmstate_register(&dev->qdev, -1, &vmstate_nvic, s); return 0; } diff --git a/hw/audiodev.h b/hw/audiodev.h index 8e930b2..d60c349 100644 --- a/hw/audiodev.h +++ b/hw/audiodev.h @@ -11,7 +11,7 @@ int Adlib_init(qemu_irq *pic); int GUS_init(qemu_irq *pic); /* ac97.c */ -int ac97_init(PCIBus *buf); +int ac97_init(PCIBus *bus); /* cs4231a.c */ int cs4231a_init(qemu_irq *pic); diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c index 57b5e2f..73eb39d 100644 --- a/hw/axis_dev88.c +++ b/hw/axis_dev88.c @@ -26,18 +26,19 @@ #include "net.h" #include "flash.h" #include "boards.h" -#include "sysemu.h" #include "etraxfs.h" #include "loader.h" #include "elf.h" #include "cris-boot.h" +#include "blockdev.h" +#include "exec-memory.h" #define D(x) #define DNAND(x) struct nand_state_t { - NANDFlashState *nand; + DeviceState *nand; unsigned int rdy:1; unsigned int ale:1; unsigned int cle:1; @@ -252,14 +253,16 @@ void axisdev88_init (ram_addr_t ram_size, CPUState *env; DeviceState *dev; SysBusDevice *s; + DriveInfo *nand; qemu_irq irq[30], nmi[2], *cpu_irq; void *etraxfs_dmac; - struct etraxfs_dma_client *eth[2] = {NULL, NULL}; + struct etraxfs_dma_client *dma_eth; int i; int nand_regs; int gpio_regs; - ram_addr_t phys_ram; - ram_addr_t phys_intmem; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *phys_ram = g_new(MemoryRegion, 1); + MemoryRegion *phys_intmem = g_new(MemoryRegion, 1); /* init CPUs */ if (cpu_model == NULL) { @@ -268,18 +271,18 @@ void axisdev88_init (ram_addr_t ram_size, env = cpu_init(cpu_model); /* allocate RAM */ - phys_ram = qemu_ram_alloc(NULL, "axisdev88.ram", ram_size); - cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM); + memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size); + memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram); /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the internal memory. */ - phys_intmem = qemu_ram_alloc(NULL, "axisdev88.chipram", INTMEM_SIZE); - cpu_register_physical_memory(0x38000000, INTMEM_SIZE, - phys_intmem | IO_MEM_RAM); - + memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE); + memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem); /* Attach a NAND flash to CS1. */ - nand_state.nand = nand_init(NAND_MFR_STMICRO, 0x39); + nand = drive_get(IF_MTD, 0, 0); + nand_state.nand = nand_init(nand ? nand->bdrv : NULL, + NAND_MFR_STMICRO, 0x39); nand_regs = cpu_register_io_memory(nand_read, nand_write, &nand_state, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(0x10000000, 0x05000000, nand_regs); @@ -312,16 +315,18 @@ void axisdev88_init (ram_addr_t ram_size, } /* Add the two ethernet blocks. */ - eth[0] = etraxfs_eth_init(&nd_table[0], 0x30034000, 1); - if (nb_nics > 1) - eth[1] = etraxfs_eth_init(&nd_table[1], 0x30036000, 2); + dma_eth = g_malloc0(sizeof dma_eth[0] * 4); /* Allocate 4 channels. */ + etraxfs_eth_init(&nd_table[0], 0x30034000, 1, &dma_eth[0], &dma_eth[1]); + if (nb_nics > 1) { + etraxfs_eth_init(&nd_table[1], 0x30036000, 2, &dma_eth[2], &dma_eth[3]); + } /* The DMA Connector block is missing, hardwire things for now. */ - etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); - etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1); - if (eth[1]) { - etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]); - etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1); + etraxfs_dmac_connect_client(etraxfs_dmac, 0, &dma_eth[0]); + etraxfs_dmac_connect_client(etraxfs_dmac, 1, &dma_eth[1]); + if (nb_nics > 1) { + etraxfs_dmac_connect_client(etraxfs_dmac, 6, &dma_eth[2]); + etraxfs_dmac_connect_client(etraxfs_dmac, 7, &dma_eth[3]); } /* 2 timers. */ @@ -347,6 +352,7 @@ static QEMUMachine axisdev88_machine = { .name = "axis-dev88", .desc = "AXIS devboard 88", .init = axisdev88_init, + .is_default = 1, }; static void axisdev88_machine_init(void) diff --git a/hw/baum.c b/hw/baum.c index 21326ae..86d780a 100644 --- a/hw/baum.c +++ b/hw/baum.c @@ -223,7 +223,7 @@ static void baum_accept_input(struct CharDriverState *chr) if (!baum->out_buf_used) return; - room = qemu_chr_can_read(chr); + room = qemu_chr_be_can_write(chr); if (!room) return; if (room > baum->out_buf_used) @@ -231,12 +231,12 @@ static void baum_accept_input(struct CharDriverState *chr) first = BUF_SIZE - baum->out_buf_ptr; if (room > first) { - qemu_chr_read(chr, baum->out_buf + baum->out_buf_ptr, first); + qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, first); baum->out_buf_ptr = 0; baum->out_buf_used -= first; room -= first; } - qemu_chr_read(chr, baum->out_buf + baum->out_buf_ptr, room); + qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, room); baum->out_buf_ptr += room; baum->out_buf_used -= room; } @@ -250,16 +250,16 @@ static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len while (len--) if ((*cur++ = *buf++) == ESC) *cur++ = ESC; - room = qemu_chr_can_read(baum->chr); + room = qemu_chr_be_can_write(baum->chr); len = cur - io_buf; if (len <= room) { /* Fits */ - qemu_chr_read(baum->chr, io_buf, len); + qemu_chr_be_write(baum->chr, io_buf, len); } else { int first; uint8_t out; /* Can't fit all, send what can be, and store the rest. */ - qemu_chr_read(baum->chr, io_buf, room); + qemu_chr_be_write(baum->chr, io_buf, room); len -= room; cur = io_buf + room; if (len > BUF_SIZE - baum->out_buf_used) { @@ -335,7 +335,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len) int i; /* Allow 100ms to complete the DisplayData packet */ - qemu_mod_timer(baum->cellCount_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(baum->cellCount_timer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10); for (i = 0; i < baum->x * baum->y ; i++) { EAT(c); @@ -468,20 +468,6 @@ static int baum_write(CharDriverState *chr, const uint8_t *buf, int len) return orig_len; } -/* The other end sent us some event */ -static void baum_send_event(CharDriverState *chr, int event) -{ - BaumDriverState *baum = chr->opaque; - switch (event) { - case CHR_EVENT_BREAK: - break; - case CHR_EVENT_OPENED: - /* Reset state */ - baum->in_buf_used = 0; - break; - } -} - /* Send the key code to the other end */ static void baum_send_key(BaumDriverState *baum, uint8_t type, uint8_t value) { uint8_t packet[] = { type, value }; @@ -559,7 +545,7 @@ static void baum_chr_read(void *opaque) if (ret == -1 && (brlapi_errno != BRLAPI_ERROR_LIBCERR || errno != EINTR)) { brlapi_perror("baum: brlapi_readKey"); brlapi__closeConnection(baum->brlapi); - qemu_free(baum->brlapi); + g_free(baum->brlapi); baum->brlapi = NULL; } } @@ -571,12 +557,12 @@ static void baum_close(struct CharDriverState *chr) qemu_free_timer(baum->cellCount_timer); if (baum->brlapi) { brlapi__closeConnection(baum->brlapi); - qemu_free(baum->brlapi); + g_free(baum->brlapi); } - qemu_free(baum); + g_free(baum); } -CharDriverState *chr_baum_init(QemuOpts *opts) +int chr_baum_init(QemuOpts *opts, CharDriverState **_chr) { BaumDriverState *baum; CharDriverState *chr; @@ -586,16 +572,15 @@ CharDriverState *chr_baum_init(QemuOpts *opts) #endif int tty; - baum = qemu_mallocz(sizeof(BaumDriverState)); - baum->chr = chr = qemu_mallocz(sizeof(CharDriverState)); + baum = g_malloc0(sizeof(BaumDriverState)); + baum->chr = chr = g_malloc0(sizeof(CharDriverState)); chr->opaque = baum; chr->chr_write = baum_write; - chr->chr_send_event = baum_send_event; chr->chr_accept_input = baum_accept_input; chr->chr_close = baum_close; - handle = qemu_mallocz(brlapi_getHandleSize()); + handle = g_malloc0(brlapi_getHandleSize()); baum->brlapi = handle; baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL); @@ -604,7 +589,7 @@ CharDriverState *chr_baum_init(QemuOpts *opts) goto fail_handle; } - baum->cellCount_timer = qemu_new_timer(vm_clock, baum_cellCount_timer_cb, baum); + baum->cellCount_timer = qemu_new_timer_ns(vm_clock, baum_cellCount_timer_cb, baum); if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) { brlapi_perror("baum_init: brlapi_getDisplaySize"); @@ -629,14 +614,15 @@ CharDriverState *chr_baum_init(QemuOpts *opts) qemu_chr_generic_open(chr); - return chr; + *_chr = chr; + return 0; fail: qemu_free_timer(baum->cellCount_timer); brlapi__closeConnection(handle); fail_handle: - qemu_free(handle); - qemu_free(chr); - qemu_free(baum); - return NULL; + g_free(handle); + g_free(chr); + g_free(baum); + return -EIO; } diff --git a/hw/baum.h b/hw/baum.h index 8af710f..3f28cc3 100644 --- a/hw/baum.h +++ b/hw/baum.h @@ -23,4 +23,4 @@ */ /* char device */ -CharDriverState *chr_baum_init(QemuOpts *opts); +int chr_baum_init(QemuOpts *opts, CharDriverState **_chr); diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c index 4ee99a1..431359d 100644 --- a/hw/bitbang_i2c.c +++ b/hw/bitbang_i2c.c @@ -4,7 +4,7 @@ * * Copyright (c) 2008 Jan Kiszka * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #include "hw.h" #include "bitbang_i2c.h" @@ -38,7 +38,8 @@ typedef enum bitbang_i2c_state { RECEIVING_BIT2, RECEIVING_BIT1, RECEIVING_BIT0, - SENDING_ACK + SENDING_ACK, + SENT_NACK } bitbang_i2c_state; struct bitbang_i2c_interface { @@ -115,6 +116,7 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level) } switch (i2c->state) { case STOPPED: + case SENT_NACK: return bitbang_i2c_ret(i2c, 1); case SENDING_BIT7 ... SENDING_BIT0: @@ -155,6 +157,7 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level) i2c->state = RECEIVING_BIT7; if (data != 0) { DPRINTF("NACKED\n"); + i2c->state = SENT_NACK; i2c_nack(i2c->bus); } else { DPRINTF("ACKED\n"); @@ -168,7 +171,7 @@ bitbang_i2c_interface *bitbang_i2c_init(i2c_bus *bus) { bitbang_i2c_interface *s; - s = qemu_mallocz(sizeof(bitbang_i2c_interface)); + s = g_malloc0(sizeof(bitbang_i2c_interface)); s->bus = bus; s->last_data = 1; diff --git a/hw/blizzard.c b/hw/blizzard.c index 5f329ad..b2c1b22 100644 --- a/hw/blizzard.c +++ b/hw/blizzard.c @@ -19,7 +19,6 @@ */ #include "qemu-common.h" -#include "sysemu.h" #include "console.h" #include "devices.h" #include "vga_int.h" @@ -189,7 +188,7 @@ static int blizzard_transfer_setup(BlizzardState *s) s->data.len = s->bpp * s->data.dx * s->data.dy; s->data.pitch = s->data.dx; if (s->data.len > s->data.buflen) { - s->data.buf = qemu_realloc(s->data.buf, s->data.len); + s->data.buf = g_realloc(s->data.buf, s->data.len); s->data.buflen = s->data.len; } s->data.ptr = s->data.buf; @@ -954,9 +953,9 @@ static void blizzard_screen_dump(void *opaque, const char *filename) { void *s1d13745_init(qemu_irq gpio_int) { - BlizzardState *s = (BlizzardState *) qemu_mallocz(sizeof(*s)); + BlizzardState *s = (BlizzardState *) g_malloc0(sizeof(*s)); - s->fb = qemu_malloc(0x180000); + s->fb = g_malloc(0x180000); s->state = graphic_console_init(blizzard_update_display, blizzard_invalidate_display, @@ -965,7 +964,7 @@ void *s1d13745_init(qemu_irq gpio_int) switch (ds_get_bits_per_pixel(s->state)) { case 0: s->line_fn_tab[0] = s->line_fn_tab[1] = - qemu_mallocz(sizeof(blizzard_fn_t) * 0x10); + g_malloc0(sizeof(blizzard_fn_t) * 0x10); break; case 8: s->line_fn_tab[0] = blizzard_draw_fn_8; diff --git a/hw/boards.h b/hw/boards.h index 6f0f0d7..716fd7b 100644 --- a/hw/boards.h +++ b/hw/boards.h @@ -27,6 +27,7 @@ typedef struct QEMUMachine { no_cdrom:1, no_sdcard:1; int is_default; + const char *default_machine_opts; GlobalProperty *compat_props; struct QEMUMachine *next; } QEMUMachine; diff --git a/hw/bonito.c b/hw/bonito.c index 65a4a63..fdb8198 100644 --- a/hw/bonito.c +++ b/hw/bonito.c @@ -42,6 +42,7 @@ #include "mips.h" #include "pci_host.h" #include "sysemu.h" +#include "exec-memory.h" //#define DEBUG_BONITO @@ -240,7 +241,7 @@ static void bonito_writel(void *opaque, target_phys_addr_t addr, uint32_t val) saddr = (addr - BONITO_REGBASE) >> 2; - DPRINTF("bonito_writel "TARGET_FMT_plx" val %x saddr %x \n", addr, val, saddr); + DPRINTF("bonito_writel "TARGET_FMT_plx" val %x saddr %x\n", addr, val, saddr); switch (saddr) { case BONITO_BONPONCFG: case BONITO_IODEVCFG: @@ -286,10 +287,10 @@ static void bonito_writel(void *opaque, target_phys_addr_t addr, uint32_t val) break; case BONITO_INTEN: case BONITO_INTISR: - DPRINTF("write to readonly bonito register %x \n", saddr); + DPRINTF("write to readonly bonito register %x\n", saddr); break; default: - DPRINTF("write to unknown bonito register %x \n", saddr); + DPRINTF("write to unknown bonito register %x\n", saddr); break; } } @@ -301,7 +302,7 @@ static uint32_t bonito_readl(void *opaque, target_phys_addr_t addr) saddr = (addr - BONITO_REGBASE) >> 2; - DPRINTF("bonito_readl "TARGET_FMT_plx" \n", addr); + DPRINTF("bonito_readl "TARGET_FMT_plx"\n", addr); switch (saddr) { case BONITO_INTISR: return s->regs[saddr]; @@ -327,7 +328,7 @@ static void bonito_pciconf_writel(void *opaque, target_phys_addr_t addr, { PCIBonitoState *s = opaque; - DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %x \n", addr, val); + DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %x\n", addr, val); s->dev.config_write(&s->dev, addr, val, 4); } @@ -442,7 +443,7 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr) exit(1); } pciaddr = PCI_ADDR(pci_bus_num(s->pcihost->bus), devno, funno, regno); - DPRINTF("cfgaddr %x pciaddr %x busno %x devno %d funno %d regno %d \n", + DPRINTF("cfgaddr %x pciaddr %x busno %x devno %d funno %d regno %d\n", cfgaddr, pciaddr, pci_bus_num(s->pcihost->bus), devno, funno, regno); return pciaddr; @@ -455,7 +456,7 @@ static void bonito_spciconf_writeb(void *opaque, target_phys_addr_t addr, uint32_t pciaddr; uint16_t status; - DPRINTF("bonito_spciconf_writeb "TARGET_FMT_plx" val %x \n", addr, val); + DPRINTF("bonito_spciconf_writeb "TARGET_FMT_plx" val %x\n", addr, val); pciaddr = bonito_sbridge_pciaddr(s, addr); if (pciaddr == 0xffffffff) { @@ -479,7 +480,7 @@ static void bonito_spciconf_writew(void *opaque, target_phys_addr_t addr, uint32_t pciaddr; uint16_t status; - DPRINTF("bonito_spciconf_writew "TARGET_FMT_plx" val %x \n", addr, val); + DPRINTF("bonito_spciconf_writew "TARGET_FMT_plx" val %x\n", addr, val); assert((addr&0x1)==0); pciaddr = bonito_sbridge_pciaddr(s, addr); @@ -505,7 +506,7 @@ static void bonito_spciconf_writel(void *opaque, target_phys_addr_t addr, uint32_t pciaddr; uint16_t status; - DPRINTF("bonito_spciconf_writel "TARGET_FMT_plx" val %x \n", addr, val); + DPRINTF("bonito_spciconf_writel "TARGET_FMT_plx" val %x\n", addr, val); assert((addr&0x3)==0); pciaddr = bonito_sbridge_pciaddr(s, addr); @@ -530,7 +531,7 @@ static uint32_t bonito_spciconf_readb(void *opaque, target_phys_addr_t addr) uint32_t pciaddr; uint16_t status; - DPRINTF("bonito_spciconf_readb "TARGET_FMT_plx" \n", addr); + DPRINTF("bonito_spciconf_readb "TARGET_FMT_plx"\n", addr); pciaddr = bonito_sbridge_pciaddr(s, addr); if (pciaddr == 0xffffffff) { @@ -554,7 +555,7 @@ static uint32_t bonito_spciconf_readw(void *opaque, target_phys_addr_t addr) uint32_t pciaddr; uint16_t status; - DPRINTF("bonito_spciconf_readw "TARGET_FMT_plx" \n", addr); + DPRINTF("bonito_spciconf_readw "TARGET_FMT_plx"\n", addr); assert((addr&0x1)==0); pciaddr = bonito_sbridge_pciaddr(s, addr); @@ -580,7 +581,7 @@ static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr) uint32_t pciaddr; uint16_t status; - DPRINTF("bonito_spciconf_readl "TARGET_FMT_plx" \n", addr); + DPRINTF("bonito_spciconf_readl "TARGET_FMT_plx"\n", addr); assert((addr&0x3) == 0); pciaddr = bonito_sbridge_pciaddr(s, addr); @@ -691,11 +692,7 @@ static int bonito_initfn(PCIDevice *dev) PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev); /* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */ - pci_config_set_vendor_id(dev->config, 0xdf53); - pci_config_set_device_id(dev->config, 0x00d5); - pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST); pci_config_set_prog_interface(dev->config, 0x00); - pci_config_set_revision(dev->config, 0x01); /* set the north bridge register mapping */ s->bonito_reg_handle = cpu_register_io_memory(bonito_read, bonito_write, s, @@ -777,7 +774,9 @@ PCIBus *bonito_init(qemu_irq *pic) dev = qdev_create(NULL, "Bonito-pcihost"); pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev)); b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq, - pci_bonito_map_irq, pic, 0x28, 32); + pci_bonito_map_irq, pic, get_system_memory(), + get_system_io(), + 0x28, 32); pcihost->bus = b; qdev_init_nofail(dev); @@ -796,6 +795,11 @@ static PCIDeviceInfo bonito_info = { .qdev.vmsd = &vmstate_bonito, .qdev.no_user = 1, .init = bonito_initfn, + /*Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined"*/ + .vendor_id = 0xdf53, + .device_id = 0x00d5, + .revision = 0x01, + .class_id = PCI_CLASS_BRIDGE_HOST, }; static SysBusDeviceInfo bonito_pcihost_info = { diff --git a/hw/bt-hci-csr.c b/hw/bt-hci-csr.c index 982577d..0dcf897 100644 --- a/hw/bt-hci-csr.c +++ b/hw/bt-hci-csr.c @@ -22,7 +22,6 @@ #include "qemu-char.h" #include "qemu-timer.h" #include "irq.h" -#include "sysemu.h" #include "net.h" #include "bt.h" @@ -88,7 +87,7 @@ static inline void csrhci_fifo_wake(struct csrhci_s *s) } if (s->out_len) - qemu_mod_timer(s->out_tm, qemu_get_clock(vm_clock) + s->baud_delay); + qemu_mod_timer(s->out_tm, qemu_get_clock_ns(vm_clock) + s->baud_delay); } #define csrhci_out_packetz(s, len) memset(csrhci_out_packet(s, len), 0, len) @@ -435,7 +434,7 @@ qemu_irq *csrhci_pins_get(CharDriverState *chr) CharDriverState *uart_hci_init(qemu_irq wakeup) { struct csrhci_s *s = (struct csrhci_s *) - qemu_mallocz(sizeof(struct csrhci_s)); + g_malloc0(sizeof(struct csrhci_s)); s->chr.opaque = s; s->chr.chr_write = csrhci_write; @@ -446,7 +445,7 @@ CharDriverState *uart_hci_init(qemu_irq wakeup) s->hci->evt_recv = csrhci_out_hci_packet_event; s->hci->acl_recv = csrhci_out_hci_packet_acl; - s->out_tm = qemu_new_timer(vm_clock, csrhci_out_tick, s); + s->out_tm = qemu_new_timer_ns(vm_clock, csrhci_out_tick, s); s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins); csrhci_reset(s); diff --git a/hw/bt-hci.c b/hw/bt-hci.c index f1ee92c..a3a7fb4 100644 --- a/hw/bt-hci.c +++ b/hw/bt-hci.c @@ -576,7 +576,7 @@ static void bt_hci_inquiry_result(struct bt_hci_s *hci, static void bt_hci_mod_timer_1280ms(QEMUTimer *timer, int period) { - qemu_mod_timer(timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(timer, qemu_get_clock_ns(vm_clock) + muldiv64(period << 7, get_ticks_per_sec(), 100)); } @@ -657,7 +657,7 @@ static void bt_hci_lmp_link_establish(struct bt_hci_s *hci, if (master) { link->acl_mode = acl_active; hci->lm.handle[hci->lm.last_handle].acl_mode_timer = - qemu_new_timer(vm_clock, bt_hci_mode_tick, link); + qemu_new_timer_ns(vm_clock, bt_hci_mode_tick, link); } } @@ -721,7 +721,7 @@ static void bt_hci_connection_reject_event(struct bt_hci_s *hci, static void bt_hci_connection_accept(struct bt_hci_s *hci, struct bt_device_s *host) { - struct bt_hci_link_s *link = qemu_mallocz(sizeof(struct bt_hci_link_s)); + struct bt_hci_link_s *link = g_malloc0(sizeof(struct bt_hci_link_s)); evt_conn_complete params; uint16_t handle; uint8_t status = HCI_SUCCESS; @@ -736,7 +736,7 @@ static void bt_hci_connection_accept(struct bt_hci_s *hci, tries); if (!tries) { - qemu_free(link); + g_free(link); bt_hci_connection_reject(hci, host, HCI_REJECTED_LIMITED_RESOURCES); status = HCI_NO_CONNECTION; goto complete; @@ -893,7 +893,7 @@ static void bt_hci_disconnect(struct bt_hci_s *hci, /* We are the slave, we get to clean this burden */ link = (struct bt_hci_link_s *) btlink; - qemu_free(link); + g_free(link); complete: bt_hci_lmp_link_teardown(hci, handle); @@ -928,7 +928,7 @@ static void bt_hci_lmp_disconnect_slave(struct bt_link_s *btlink) uint16_t handle = link->handle; evt_disconn_complete params; - qemu_free(link); + g_free(link); bt_hci_lmp_link_teardown(hci, handle); @@ -1084,7 +1084,7 @@ static int bt_hci_mode_change(struct bt_hci_s *hci, uint16_t handle, bt_hci_event_status(hci, HCI_SUCCESS); - qemu_mod_timer(link->acl_mode_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(link->acl_mode_timer, qemu_get_clock_ns(vm_clock) + muldiv64(interval * 625, get_ticks_per_sec(), 1000000)); bt_hci_lmp_mode_change_master(hci, link->link, mode, interval); @@ -1138,7 +1138,7 @@ static void bt_hci_reset(struct bt_hci_s *hci) hci->device.inquiry_scan = 0; hci->device.page_scan = 0; if (hci->device.lmp_name) - qemu_free((void *) hci->device.lmp_name); + g_free((void *) hci->device.lmp_name); hci->device.lmp_name = NULL; hci->device.class[0] = 0x00; hci->device.class[1] = 0x00; @@ -1816,8 +1816,8 @@ static void bt_submit_hci(struct HCIInfo *info, LENGTH_CHECK(change_local_name); if (hci->device.lmp_name) - qemu_free((void *) hci->device.lmp_name); - hci->device.lmp_name = qemu_strndup(PARAM(change_local_name, name), + g_free((void *) hci->device.lmp_name); + hci->device.lmp_name = g_strndup(PARAM(change_local_name, name), sizeof(PARAM(change_local_name, name))); bt_hci_event_complete_status(hci, HCI_SUCCESS); break; @@ -2143,12 +2143,12 @@ static void bt_hci_destroy(struct bt_device_s *dev) struct HCIInfo *bt_new_hci(struct bt_scatternet_s *net) { - struct bt_hci_s *s = qemu_mallocz(sizeof(struct bt_hci_s)); + struct bt_hci_s *s = g_malloc0(sizeof(struct bt_hci_s)); - s->lm.inquiry_done = qemu_new_timer(vm_clock, bt_hci_inquiry_done, s); - s->lm.inquiry_next = qemu_new_timer(vm_clock, bt_hci_inquiry_next, s); + s->lm.inquiry_done = qemu_new_timer_ns(vm_clock, bt_hci_inquiry_done, s); + s->lm.inquiry_next = qemu_new_timer_ns(vm_clock, bt_hci_inquiry_next, s); s->conn_accept_timer = - qemu_new_timer(vm_clock, bt_hci_conn_accept_timeout, s); + qemu_new_timer_ns(vm_clock, bt_hci_conn_accept_timeout, s); s->evt_packet = bt_hci_evt_packet; s->evt_submit = bt_hci_evt_submit; @@ -2188,7 +2188,7 @@ static void bt_hci_done(struct HCIInfo *info) bt_device_done(&hci->device); if (hci->device.lmp_name) - qemu_free((void *) hci->device.lmp_name); + g_free((void *) hci->device.lmp_name); /* Be gentle and send DISCONNECT to all connected peers and those * currently waiting for us to accept or reject a connection request. @@ -2217,5 +2217,5 @@ static void bt_hci_done(struct HCIInfo *info) qemu_free_timer(hci->lm.inquiry_next); qemu_free_timer(hci->conn_accept_timer); - qemu_free(hci); + g_free(hci); } diff --git a/hw/bt-hid.c b/hw/bt-hid.c index abdfd35..8d7a3da 100644 --- a/hw/bt-hid.c +++ b/hw/bt-hid.c @@ -19,7 +19,9 @@ */ #include "qemu-common.h" -#include "usb.h" +#include "qemu-timer.h" +#include "console.h" +#include "hid.h" #include "bt.h" enum hid_transaction_req { @@ -86,7 +88,7 @@ struct bt_hid_device_s { struct bt_l2cap_device_s btdev; struct bt_l2cap_conn_params_s *control; struct bt_l2cap_conn_params_s *interrupt; - USBDevice *usbdev; + HIDState hid; int proto; int connected; @@ -111,7 +113,7 @@ static void bt_hid_reset(struct bt_hid_device_s *s) bt_l2cap_device_done(&s->btdev); bt_l2cap_device_init(&s->btdev, net); - s->usbdev->info->handle_reset(s->usbdev); + hid_reset(&s->hid); s->proto = BT_HID_PROTO_REPORT; s->state = bt_state_ready; s->dataother.len = 0; @@ -124,23 +126,16 @@ static void bt_hid_reset(struct bt_hid_device_s *s) static int bt_hid_out(struct bt_hid_device_s *s) { - USBPacket p; - if (s->data_type == BT_DATA_OUTPUT) { - p.pid = USB_TOKEN_OUT; - p.devep = 1; - p.data = s->dataout.buffer; - p.len = s->dataout.len; - s->dataout.len = s->usbdev->info->handle_data(s->usbdev, &p); - - return s->dataout.len; + /* nothing */ + ; } if (s->data_type == BT_DATA_FEATURE) { /* XXX: * does this send a USB_REQ_CLEAR_FEATURE/USB_REQ_SET_FEATURE * or a SET_REPORT? */ - p.devep = 0; + ; } return -1; @@ -148,14 +143,8 @@ static int bt_hid_out(struct bt_hid_device_s *s) static int bt_hid_in(struct bt_hid_device_s *s) { - USBPacket p; - - p.pid = USB_TOKEN_IN; - p.devep = 1; - p.data = s->datain.buffer; - p.len = sizeof(s->datain.buffer); - s->datain.len = s->usbdev->info->handle_data(s->usbdev, &p); - + s->datain.len = hid_keyboard_poll(&s->hid, s->datain.buffer, + sizeof(s->datain.buffer)); return s->datain.len; } @@ -323,8 +312,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s, break; } s->proto = parameter; - s->usbdev->info->handle_control(s->usbdev, SET_PROTOCOL, s->proto, 0, 0, - NULL); + s->hid.protocol = parameter; ret = BT_HS_SUCCESSFUL; break; @@ -333,8 +321,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s, ret = BT_HS_ERR_INVALID_PARAMETER; break; } - s->usbdev->info->handle_control(s->usbdev, GET_IDLE, 0, 0, 1, - s->control->sdu_out(s->control, 1)); + *s->control->sdu_out(s->control, 1) = s->hid.idle; s->control->sdu_submit(s->control); break; @@ -344,11 +331,7 @@ static void bt_hid_control_transaction(struct bt_hid_device_s *s, break; } - /* We don't need to know about the Idle Rate here really, - * so just pass it on to the device. */ - ret = s->usbdev->info->handle_control(s->usbdev, - SET_IDLE, data[1], 0, 0, NULL) ? - BT_HS_SUCCESSFUL : BT_HS_ERR_INVALID_PARAMETER; + s->hid.idle = data[1]; /* XXX: Does this generate a handshake? */ break; @@ -385,9 +368,10 @@ static void bt_hid_control_sdu(void *opaque, const uint8_t *data, int len) bt_hid_control_transaction(hid, data, len); } -static void bt_hid_datain(void *opaque) +static void bt_hid_datain(HIDState *hs) { - struct bt_hid_device_s *hid = opaque; + struct bt_hid_device_s *hid = + container_of(hs, struct bt_hid_device_s, hid); /* If suspended, wake-up and send a wake-up event first. We might * want to also inspect the input report and ignore event like @@ -450,7 +434,7 @@ static void bt_hid_connected_update(struct bt_hid_device_s *hid) hid->btdev.device.inquiry_scan = !hid->connected; if (hid->connected && !prev) { - hid->usbdev->info->handle_reset(hid->usbdev); + hid_reset(&hid->hid); hid->proto = BT_HID_PROTO_REPORT; } @@ -518,9 +502,9 @@ static void bt_hid_destroy(struct bt_device_s *dev) bt_hid_send_control(hid, BT_HC_VIRTUAL_CABLE_UNPLUG); bt_l2cap_device_done(&hid->btdev); - hid->usbdev->info->handle_destroy(hid->usbdev); + hid_free(&hid->hid); - qemu_free(hid); + g_free(hid); } enum peripheral_minor_class { @@ -531,9 +515,9 @@ enum peripheral_minor_class { }; static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net, - USBDevice *dev, enum peripheral_minor_class minor) + enum peripheral_minor_class minor) { - struct bt_hid_device_s *s = qemu_mallocz(sizeof(*s)); + struct bt_hid_device_s *s = g_malloc0(sizeof(*s)); uint32_t class = /* Format type */ (0 << 0) | @@ -551,9 +535,8 @@ static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net, bt_l2cap_psm_register(&s->btdev, BT_PSM_HID_INTR, BT_HID_MTU, bt_hid_new_interrupt_ch); - s->usbdev = dev; - s->btdev.device.lmp_name = s->usbdev->product_desc; - usb_hid_datain_cb(s->usbdev, s, bt_hid_datain); + hid_init(&s->hid, HID_KEYBOARD, bt_hid_datain); + s->btdev.device.lmp_name = "BT Keyboard"; s->btdev.device.handle_destroy = bt_hid_destroy; @@ -566,6 +549,5 @@ static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net, struct bt_device_s *bt_keyboard_init(struct bt_scatternet_s *net) { - USBDevice *dev = usb_create_simple(NULL /* FIXME */, "usb-kbd"); - return bt_hid_init(net, dev, class_keyboard); + return bt_hid_init(net, class_keyboard); } diff --git a/hw/bt-l2cap.c b/hw/bt-l2cap.c index 7e2f668..2ccba60 100644 --- a/hw/bt-l2cap.c +++ b/hw/bt-l2cap.c @@ -410,7 +410,7 @@ static struct l2cap_chan_s *l2cap_channel_open(struct l2cap_instance_s *l2cap, if (psm_info) { /* Device supports this use-case. */ - ch = qemu_mallocz(sizeof(*ch)); + ch = g_malloc0(sizeof(*ch)); ch->params.sdu_out = l2cap_bframe_out; ch->params.sdu_submit = l2cap_bframe_submit; ch->frame_in = l2cap_bframe_in; @@ -428,7 +428,7 @@ static struct l2cap_chan_s *l2cap_channel_open(struct l2cap_instance_s *l2cap, result = L2CAP_CR_SUCCESS; status = L2CAP_CS_NO_INFO; } else { - qemu_free(ch); + g_free(ch); result = L2CAP_CR_NO_MEM; status = L2CAP_CS_NO_INFO; @@ -473,7 +473,7 @@ static void l2cap_channel_close(struct l2cap_instance_s *l2cap, l2cap->cid[cid] = NULL; ch->params.close(ch->params.opaque); - qemu_free(ch); + g_free(ch); } l2cap_disconnection_response(l2cap, cid, source_cid); @@ -1218,13 +1218,13 @@ static void l2cap_teardown(struct l2cap_instance_s *l2cap, int send_disconnect) for (cid = L2CAP_CID_ALLOC; cid < L2CAP_CID_MAX; cid ++) if (l2cap->cid[cid]) { l2cap->cid[cid]->params.close(l2cap->cid[cid]->params.opaque); - qemu_free(l2cap->cid[cid]); + g_free(l2cap->cid[cid]); } if (l2cap->role) - qemu_free(l2cap); + g_free(l2cap); else - qemu_free(l2cap->link); + g_free(l2cap->link); } /* L2CAP glue to lower layers in bluetooth stack (LMP) */ @@ -1236,7 +1236,7 @@ static void l2cap_lmp_connection_request(struct bt_link_s *link) /* Always accept - we only get called if (dev->device->page_scan). */ - l2cap = qemu_mallocz(sizeof(struct slave_l2cap_instance_s)); + l2cap = g_malloc0(sizeof(struct slave_l2cap_instance_s)); l2cap->link.slave = &dev->device; l2cap->link.host = link->host; l2cap_init(&l2cap->l2cap, &l2cap->link, 0); @@ -1257,7 +1257,7 @@ static void l2cap_lmp_connection_complete(struct bt_link_s *link) return; } - l2cap = qemu_mallocz(sizeof(struct l2cap_instance_s)); + l2cap = g_malloc0(sizeof(struct l2cap_instance_s)); l2cap_init(l2cap, link, 1); link->acl_mode = acl_active; @@ -1353,7 +1353,7 @@ void bt_l2cap_psm_register(struct bt_l2cap_device_s *dev, int psm, int min_mtu, exit(-1); } - new_psm = qemu_mallocz(sizeof(*new_psm)); + new_psm = g_malloc0(sizeof(*new_psm)); new_psm->psm = psm; new_psm->min_mtu = min_mtu; new_psm->new_channel = new_channel; diff --git a/hw/bt-sdp.c b/hw/bt-sdp.c index cdf2d95..3e390ab 100644 --- a/hw/bt-sdp.c +++ b/hw/bt-sdp.c @@ -567,12 +567,12 @@ static void bt_l2cap_sdp_close_ch(void *opaque) int i; for (i = 0; i < sdp->services; i ++) { - qemu_free(sdp->service_list[i].attribute_list->pair); - qemu_free(sdp->service_list[i].attribute_list); - qemu_free(sdp->service_list[i].uuid); + g_free(sdp->service_list[i].attribute_list->pair); + g_free(sdp->service_list[i].attribute_list); + g_free(sdp->service_list[i].uuid); } - qemu_free(sdp->service_list); - qemu_free(sdp); + g_free(sdp->service_list); + g_free(sdp); } struct sdp_def_service_s { @@ -709,10 +709,10 @@ static void sdp_service_record_build(struct sdp_service_record_s *record, } record->uuids = 1 << ffs(record->uuids - 1); record->attribute_list = - qemu_mallocz(record->attributes * sizeof(*record->attribute_list)); + g_malloc0(record->attributes * sizeof(*record->attribute_list)); record->uuid = - qemu_mallocz(record->uuids * sizeof(*record->uuid)); - data = qemu_malloc(len); + g_malloc0(record->uuids * sizeof(*record->uuid)); + data = g_malloc(len); record->attributes = 0; uuid = record->uuid; @@ -753,7 +753,7 @@ static void sdp_service_db_build(struct bt_l2cap_sdp_state_s *sdp, while (service[sdp->services]) sdp->services ++; sdp->service_list = - qemu_mallocz(sdp->services * sizeof(*sdp->service_list)); + g_malloc0(sdp->services * sizeof(*sdp->service_list)); sdp->services = 0; while (*service) { @@ -942,7 +942,7 @@ SERVICE(pnp, static int bt_l2cap_sdp_new_ch(struct bt_l2cap_device_s *dev, struct bt_l2cap_conn_params_s *params) { - struct bt_l2cap_sdp_state_s *sdp = qemu_mallocz(sizeof(*sdp)); + struct bt_l2cap_sdp_state_s *sdp = g_malloc0(sizeof(*sdp)); struct sdp_def_service_s *services[] = { &sdp_service_sdp_s, &sdp_service_hid_s, diff --git a/hw/bt.c b/hw/bt.c index 34bf004..dc99fc2 100644 --- a/hw/bt.c +++ b/hw/bt.c @@ -54,7 +54,7 @@ static void bt_dummy_lmp_acl_resp(struct bt_link_s *link, /* Slaves that don't hold any additional per link state can use these */ static void bt_dummy_lmp_connection_request(struct bt_link_s *req) { - struct bt_link_s *link = qemu_mallocz(sizeof(struct bt_link_s)); + struct bt_link_s *link = g_malloc0(sizeof(struct bt_link_s)); link->slave = req->slave; link->host = req->host; @@ -65,13 +65,13 @@ static void bt_dummy_lmp_connection_request(struct bt_link_s *req) static void bt_dummy_lmp_disconnect_slave(struct bt_link_s *link) { - qemu_free(link); + g_free(link); } static void bt_dummy_destroy(struct bt_device_s *device) { bt_device_done(device); - qemu_free(device); + g_free(device); } static int bt_dev_idx = 0; diff --git a/hw/bt.h b/hw/bt.h index 4a702ad..a48b8d4 100644 --- a/hw/bt.h +++ b/hw/bt.h @@ -26,7 +26,7 @@ /* BD Address */ typedef struct { uint8_t b[6]; -} __attribute__((packed)) bdaddr_t; +} QEMU_PACKED bdaddr_t; #define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) #define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}) @@ -446,13 +446,13 @@ typedef struct { uint8_t lap[3]; uint8_t length; /* 1.28s units */ uint8_t num_rsp; -} __attribute__ ((packed)) inquiry_cp; +} QEMU_PACKED inquiry_cp; #define INQUIRY_CP_SIZE 5 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) status_bdaddr_rp; +} QEMU_PACKED status_bdaddr_rp; #define STATUS_BDADDR_RP_SIZE 7 #define OCF_INQUIRY_CANCEL 0x0002 @@ -464,7 +464,7 @@ typedef struct { uint8_t lap[3]; uint8_t length; /* 1.28s units */ uint8_t num_rsp; -} __attribute__ ((packed)) periodic_inquiry_cp; +} QEMU_PACKED periodic_inquiry_cp; #define PERIODIC_INQUIRY_CP_SIZE 9 #define OCF_EXIT_PERIODIC_INQUIRY 0x0004 @@ -477,55 +477,55 @@ typedef struct { uint8_t pscan_mode; uint16_t clock_offset; uint8_t role_switch; -} __attribute__ ((packed)) create_conn_cp; +} QEMU_PACKED create_conn_cp; #define CREATE_CONN_CP_SIZE 13 #define OCF_DISCONNECT 0x0006 typedef struct { uint16_t handle; uint8_t reason; -} __attribute__ ((packed)) disconnect_cp; +} QEMU_PACKED disconnect_cp; #define DISCONNECT_CP_SIZE 3 #define OCF_ADD_SCO 0x0007 typedef struct { uint16_t handle; uint16_t pkt_type; -} __attribute__ ((packed)) add_sco_cp; +} QEMU_PACKED add_sco_cp; #define ADD_SCO_CP_SIZE 4 #define OCF_CREATE_CONN_CANCEL 0x0008 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) create_conn_cancel_cp; +} QEMU_PACKED create_conn_cancel_cp; #define CREATE_CONN_CANCEL_CP_SIZE 6 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) create_conn_cancel_rp; +} QEMU_PACKED create_conn_cancel_rp; #define CREATE_CONN_CANCEL_RP_SIZE 7 #define OCF_ACCEPT_CONN_REQ 0x0009 typedef struct { bdaddr_t bdaddr; uint8_t role; -} __attribute__ ((packed)) accept_conn_req_cp; +} QEMU_PACKED accept_conn_req_cp; #define ACCEPT_CONN_REQ_CP_SIZE 7 #define OCF_REJECT_CONN_REQ 0x000A typedef struct { bdaddr_t bdaddr; uint8_t reason; -} __attribute__ ((packed)) reject_conn_req_cp; +} QEMU_PACKED reject_conn_req_cp; #define REJECT_CONN_REQ_CP_SIZE 7 #define OCF_LINK_KEY_REPLY 0x000B typedef struct { bdaddr_t bdaddr; uint8_t link_key[16]; -} __attribute__ ((packed)) link_key_reply_cp; +} QEMU_PACKED link_key_reply_cp; #define LINK_KEY_REPLY_CP_SIZE 22 #define OCF_LINK_KEY_NEG_REPLY 0x000C @@ -535,7 +535,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t pin_len; uint8_t pin_code[16]; -} __attribute__ ((packed)) pin_code_reply_cp; +} QEMU_PACKED pin_code_reply_cp; #define PIN_CODE_REPLY_CP_SIZE 23 #define OCF_PIN_CODE_NEG_REPLY 0x000E @@ -544,32 +544,32 @@ typedef struct { typedef struct { uint16_t handle; uint16_t pkt_type; -} __attribute__ ((packed)) set_conn_ptype_cp; +} QEMU_PACKED set_conn_ptype_cp; #define SET_CONN_PTYPE_CP_SIZE 4 #define OCF_AUTH_REQUESTED 0x0011 typedef struct { uint16_t handle; -} __attribute__ ((packed)) auth_requested_cp; +} QEMU_PACKED auth_requested_cp; #define AUTH_REQUESTED_CP_SIZE 2 #define OCF_SET_CONN_ENCRYPT 0x0013 typedef struct { uint16_t handle; uint8_t encrypt; -} __attribute__ ((packed)) set_conn_encrypt_cp; +} QEMU_PACKED set_conn_encrypt_cp; #define SET_CONN_ENCRYPT_CP_SIZE 3 #define OCF_CHANGE_CONN_LINK_KEY 0x0015 typedef struct { uint16_t handle; -} __attribute__ ((packed)) change_conn_link_key_cp; +} QEMU_PACKED change_conn_link_key_cp; #define CHANGE_CONN_LINK_KEY_CP_SIZE 2 #define OCF_MASTER_LINK_KEY 0x0017 typedef struct { uint8_t key_flag; -} __attribute__ ((packed)) master_link_key_cp; +} QEMU_PACKED master_link_key_cp; #define MASTER_LINK_KEY_CP_SIZE 1 #define OCF_REMOTE_NAME_REQ 0x0019 @@ -578,50 +578,50 @@ typedef struct { uint8_t pscan_rep_mode; uint8_t pscan_mode; uint16_t clock_offset; -} __attribute__ ((packed)) remote_name_req_cp; +} QEMU_PACKED remote_name_req_cp; #define REMOTE_NAME_REQ_CP_SIZE 10 #define OCF_REMOTE_NAME_REQ_CANCEL 0x001A typedef struct { bdaddr_t bdaddr; -} __attribute__ ((packed)) remote_name_req_cancel_cp; +} QEMU_PACKED remote_name_req_cancel_cp; #define REMOTE_NAME_REQ_CANCEL_CP_SIZE 6 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) remote_name_req_cancel_rp; +} QEMU_PACKED remote_name_req_cancel_rp; #define REMOTE_NAME_REQ_CANCEL_RP_SIZE 7 #define OCF_READ_REMOTE_FEATURES 0x001B typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_remote_features_cp; +} QEMU_PACKED read_remote_features_cp; #define READ_REMOTE_FEATURES_CP_SIZE 2 #define OCF_READ_REMOTE_EXT_FEATURES 0x001C typedef struct { uint16_t handle; uint8_t page_num; -} __attribute__ ((packed)) read_remote_ext_features_cp; +} QEMU_PACKED read_remote_ext_features_cp; #define READ_REMOTE_EXT_FEATURES_CP_SIZE 3 #define OCF_READ_REMOTE_VERSION 0x001D typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_remote_version_cp; +} QEMU_PACKED read_remote_version_cp; #define READ_REMOTE_VERSION_CP_SIZE 2 #define OCF_READ_CLOCK_OFFSET 0x001F typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_clock_offset_cp; +} QEMU_PACKED read_clock_offset_cp; #define READ_CLOCK_OFFSET_CP_SIZE 2 #define OCF_READ_LMP_HANDLE 0x0020 typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_lmp_handle_cp; +} QEMU_PACKED read_lmp_handle_cp; #define READ_LMP_HANDLE_CP_SIZE 2 typedef struct { @@ -629,7 +629,7 @@ typedef struct { uint16_t handle; uint8_t lmp_handle; uint32_t reserved; -} __attribute__ ((packed)) read_lmp_handle_rp; +} QEMU_PACKED read_lmp_handle_rp; #define READ_LMP_HANDLE_RP_SIZE 8 #define OCF_SETUP_SYNC_CONN 0x0028 @@ -641,7 +641,7 @@ typedef struct { uint16_t voice_setting; uint8_t retrans_effort; uint16_t pkt_type; -} __attribute__ ((packed)) setup_sync_conn_cp; +} QEMU_PACKED setup_sync_conn_cp; #define SETUP_SYNC_CONN_CP_SIZE 17 #define OCF_ACCEPT_SYNC_CONN_REQ 0x0029 @@ -653,14 +653,14 @@ typedef struct { uint16_t voice_setting; uint8_t retrans_effort; uint16_t pkt_type; -} __attribute__ ((packed)) accept_sync_conn_req_cp; +} QEMU_PACKED accept_sync_conn_req_cp; #define ACCEPT_SYNC_CONN_REQ_CP_SIZE 21 #define OCF_REJECT_SYNC_CONN_REQ 0x002A typedef struct { bdaddr_t bdaddr; uint8_t reason; -} __attribute__ ((packed)) reject_sync_conn_req_cp; +} QEMU_PACKED reject_sync_conn_req_cp; #define REJECT_SYNC_CONN_REQ_CP_SIZE 7 /* Link Policy */ @@ -671,7 +671,7 @@ typedef struct { uint16_t handle; uint16_t max_interval; uint16_t min_interval; -} __attribute__ ((packed)) hold_mode_cp; +} QEMU_PACKED hold_mode_cp; #define HOLD_MODE_CP_SIZE 6 #define OCF_SNIFF_MODE 0x0003 @@ -681,13 +681,13 @@ typedef struct { uint16_t min_interval; uint16_t attempt; uint16_t timeout; -} __attribute__ ((packed)) sniff_mode_cp; +} QEMU_PACKED sniff_mode_cp; #define SNIFF_MODE_CP_SIZE 10 #define OCF_EXIT_SNIFF_MODE 0x0004 typedef struct { uint16_t handle; -} __attribute__ ((packed)) exit_sniff_mode_cp; +} QEMU_PACKED exit_sniff_mode_cp; #define EXIT_SNIFF_MODE_CP_SIZE 2 #define OCF_PARK_MODE 0x0005 @@ -695,13 +695,13 @@ typedef struct { uint16_t handle; uint16_t max_interval; uint16_t min_interval; -} __attribute__ ((packed)) park_mode_cp; +} QEMU_PACKED park_mode_cp; #define PARK_MODE_CP_SIZE 6 #define OCF_EXIT_PARK_MODE 0x0006 typedef struct { uint16_t handle; -} __attribute__ ((packed)) exit_park_mode_cp; +} QEMU_PACKED exit_park_mode_cp; #define EXIT_PARK_MODE_CP_SIZE 2 #define OCF_QOS_SETUP 0x0007 @@ -711,56 +711,56 @@ typedef struct { uint32_t peak_bandwidth; /* Byte per seconds */ uint32_t latency; /* Microseconds */ uint32_t delay_variation; /* Microseconds */ -} __attribute__ ((packed)) hci_qos; +} QEMU_PACKED hci_qos; #define HCI_QOS_CP_SIZE 17 typedef struct { uint16_t handle; uint8_t flags; /* Reserved */ hci_qos qos; -} __attribute__ ((packed)) qos_setup_cp; +} QEMU_PACKED qos_setup_cp; #define QOS_SETUP_CP_SIZE (3 + HCI_QOS_CP_SIZE) #define OCF_ROLE_DISCOVERY 0x0009 typedef struct { uint16_t handle; -} __attribute__ ((packed)) role_discovery_cp; +} QEMU_PACKED role_discovery_cp; #define ROLE_DISCOVERY_CP_SIZE 2 typedef struct { uint8_t status; uint16_t handle; uint8_t role; -} __attribute__ ((packed)) role_discovery_rp; +} QEMU_PACKED role_discovery_rp; #define ROLE_DISCOVERY_RP_SIZE 4 #define OCF_SWITCH_ROLE 0x000B typedef struct { bdaddr_t bdaddr; uint8_t role; -} __attribute__ ((packed)) switch_role_cp; +} QEMU_PACKED switch_role_cp; #define SWITCH_ROLE_CP_SIZE 7 #define OCF_READ_LINK_POLICY 0x000C typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_link_policy_cp; +} QEMU_PACKED read_link_policy_cp; #define READ_LINK_POLICY_CP_SIZE 2 typedef struct { uint8_t status; uint16_t handle; uint16_t policy; -} __attribute__ ((packed)) read_link_policy_rp; +} QEMU_PACKED read_link_policy_rp; #define READ_LINK_POLICY_RP_SIZE 5 #define OCF_WRITE_LINK_POLICY 0x000D typedef struct { uint16_t handle; uint16_t policy; -} __attribute__ ((packed)) write_link_policy_cp; +} QEMU_PACKED write_link_policy_cp; #define WRITE_LINK_POLICY_CP_SIZE 4 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) write_link_policy_rp; +} QEMU_PACKED write_link_policy_rp; #define WRITE_LINK_POLICY_RP_SIZE 3 #define OCF_READ_DEFAULT_LINK_POLICY 0x000E @@ -776,7 +776,7 @@ typedef struct { uint16_t max_local_latency; uint16_t min_remote_timeout; uint16_t min_local_timeout; -} __attribute__ ((packed)) sniff_subrate_cp; +} QEMU_PACKED sniff_subrate_cp; #define SNIFF_SUBRATE_CP_SIZE 10 /* Host Controller and Baseband */ @@ -785,7 +785,7 @@ typedef struct { #define OCF_SET_EVENT_MASK 0x0001 typedef struct { uint8_t mask[8]; -} __attribute__ ((packed)) set_event_mask_cp; +} QEMU_PACKED set_event_mask_cp; #define SET_EVENT_MASK_CP_SIZE 8 #define OCF_RESET 0x0003 @@ -795,7 +795,7 @@ typedef struct { uint8_t flt_type; uint8_t cond_type; uint8_t condition[0]; -} __attribute__ ((packed)) set_event_flt_cp; +} QEMU_PACKED set_event_flt_cp; #define SET_EVENT_FLT_CP_SIZE 2 enum bt_filter_type { @@ -821,26 +821,26 @@ enum conn_setup_cond { #define OCF_FLUSH 0x0008 typedef struct { uint16_t handle; -} __attribute__ ((packed)) flush_cp; +} QEMU_PACKED flush_cp; #define FLUSH_CP_SIZE 2 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) flush_rp; +} QEMU_PACKED flush_rp; #define FLUSH_RP_SIZE 3 #define OCF_READ_PIN_TYPE 0x0009 typedef struct { uint8_t status; uint8_t pin_type; -} __attribute__ ((packed)) read_pin_type_rp; +} QEMU_PACKED read_pin_type_rp; #define READ_PIN_TYPE_RP_SIZE 2 #define OCF_WRITE_PIN_TYPE 0x000A typedef struct { uint8_t pin_type; -} __attribute__ ((packed)) write_pin_type_cp; +} QEMU_PACKED write_pin_type_cp; #define WRITE_PIN_TYPE_CP_SIZE 1 #define OCF_CREATE_NEW_UNIT_KEY 0x000B @@ -849,89 +849,89 @@ typedef struct { typedef struct { bdaddr_t bdaddr; uint8_t read_all; -} __attribute__ ((packed)) read_stored_link_key_cp; +} QEMU_PACKED read_stored_link_key_cp; #define READ_STORED_LINK_KEY_CP_SIZE 7 typedef struct { uint8_t status; uint16_t max_keys; uint16_t num_keys; -} __attribute__ ((packed)) read_stored_link_key_rp; +} QEMU_PACKED read_stored_link_key_rp; #define READ_STORED_LINK_KEY_RP_SIZE 5 #define OCF_WRITE_STORED_LINK_KEY 0x0011 typedef struct { uint8_t num_keys; /* variable length part */ -} __attribute__ ((packed)) write_stored_link_key_cp; +} QEMU_PACKED write_stored_link_key_cp; #define WRITE_STORED_LINK_KEY_CP_SIZE 1 typedef struct { uint8_t status; uint8_t num_keys; -} __attribute__ ((packed)) write_stored_link_key_rp; +} QEMU_PACKED write_stored_link_key_rp; #define READ_WRITE_LINK_KEY_RP_SIZE 2 #define OCF_DELETE_STORED_LINK_KEY 0x0012 typedef struct { bdaddr_t bdaddr; uint8_t delete_all; -} __attribute__ ((packed)) delete_stored_link_key_cp; +} QEMU_PACKED delete_stored_link_key_cp; #define DELETE_STORED_LINK_KEY_CP_SIZE 7 typedef struct { uint8_t status; uint16_t num_keys; -} __attribute__ ((packed)) delete_stored_link_key_rp; +} QEMU_PACKED delete_stored_link_key_rp; #define DELETE_STORED_LINK_KEY_RP_SIZE 3 #define OCF_CHANGE_LOCAL_NAME 0x0013 typedef struct { char name[248]; -} __attribute__ ((packed)) change_local_name_cp; +} QEMU_PACKED change_local_name_cp; #define CHANGE_LOCAL_NAME_CP_SIZE 248 #define OCF_READ_LOCAL_NAME 0x0014 typedef struct { uint8_t status; char name[248]; -} __attribute__ ((packed)) read_local_name_rp; +} QEMU_PACKED read_local_name_rp; #define READ_LOCAL_NAME_RP_SIZE 249 #define OCF_READ_CONN_ACCEPT_TIMEOUT 0x0015 typedef struct { uint8_t status; uint16_t timeout; -} __attribute__ ((packed)) read_conn_accept_timeout_rp; +} QEMU_PACKED read_conn_accept_timeout_rp; #define READ_CONN_ACCEPT_TIMEOUT_RP_SIZE 3 #define OCF_WRITE_CONN_ACCEPT_TIMEOUT 0x0016 typedef struct { uint16_t timeout; -} __attribute__ ((packed)) write_conn_accept_timeout_cp; +} QEMU_PACKED write_conn_accept_timeout_cp; #define WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE 2 #define OCF_READ_PAGE_TIMEOUT 0x0017 typedef struct { uint8_t status; uint16_t timeout; -} __attribute__ ((packed)) read_page_timeout_rp; +} QEMU_PACKED read_page_timeout_rp; #define READ_PAGE_TIMEOUT_RP_SIZE 3 #define OCF_WRITE_PAGE_TIMEOUT 0x0018 typedef struct { uint16_t timeout; -} __attribute__ ((packed)) write_page_timeout_cp; +} QEMU_PACKED write_page_timeout_cp; #define WRITE_PAGE_TIMEOUT_CP_SIZE 2 #define OCF_READ_SCAN_ENABLE 0x0019 typedef struct { uint8_t status; uint8_t enable; -} __attribute__ ((packed)) read_scan_enable_rp; +} QEMU_PACKED read_scan_enable_rp; #define READ_SCAN_ENABLE_RP_SIZE 2 #define OCF_WRITE_SCAN_ENABLE 0x001A typedef struct { uint8_t scan_enable; -} __attribute__ ((packed)) write_scan_enable_cp; +} QEMU_PACKED write_scan_enable_cp; #define WRITE_SCAN_ENABLE_CP_SIZE 1 enum scan_enable_bits { @@ -945,14 +945,14 @@ typedef struct { uint8_t status; uint16_t interval; uint16_t window; -} __attribute__ ((packed)) read_page_activity_rp; +} QEMU_PACKED read_page_activity_rp; #define READ_PAGE_ACTIVITY_RP_SIZE 5 #define OCF_WRITE_PAGE_ACTIVITY 0x001C typedef struct { uint16_t interval; uint16_t window; -} __attribute__ ((packed)) write_page_activity_cp; +} QEMU_PACKED write_page_activity_cp; #define WRITE_PAGE_ACTIVITY_CP_SIZE 4 #define OCF_READ_INQ_ACTIVITY 0x001D @@ -960,14 +960,14 @@ typedef struct { uint8_t status; uint16_t interval; uint16_t window; -} __attribute__ ((packed)) read_inq_activity_rp; +} QEMU_PACKED read_inq_activity_rp; #define READ_INQ_ACTIVITY_RP_SIZE 5 #define OCF_WRITE_INQ_ACTIVITY 0x001E typedef struct { uint16_t interval; uint16_t window; -} __attribute__ ((packed)) write_inq_activity_cp; +} QEMU_PACKED write_inq_activity_cp; #define WRITE_INQ_ACTIVITY_CP_SIZE 4 #define OCF_READ_AUTH_ENABLE 0x001F @@ -989,26 +989,26 @@ typedef struct { typedef struct { uint8_t status; uint8_t dev_class[3]; -} __attribute__ ((packed)) read_class_of_dev_rp; +} QEMU_PACKED read_class_of_dev_rp; #define READ_CLASS_OF_DEV_RP_SIZE 4 #define OCF_WRITE_CLASS_OF_DEV 0x0024 typedef struct { uint8_t dev_class[3]; -} __attribute__ ((packed)) write_class_of_dev_cp; +} QEMU_PACKED write_class_of_dev_cp; #define WRITE_CLASS_OF_DEV_CP_SIZE 3 #define OCF_READ_VOICE_SETTING 0x0025 typedef struct { uint8_t status; uint16_t voice_setting; -} __attribute__ ((packed)) read_voice_setting_rp; +} QEMU_PACKED read_voice_setting_rp; #define READ_VOICE_SETTING_RP_SIZE 3 #define OCF_WRITE_VOICE_SETTING 0x0026 typedef struct { uint16_t voice_setting; -} __attribute__ ((packed)) write_voice_setting_cp; +} QEMU_PACKED write_voice_setting_cp; #define WRITE_VOICE_SETTING_CP_SIZE 2 #define OCF_READ_AUTOMATIC_FLUSH_TIMEOUT 0x0027 @@ -1027,13 +1027,13 @@ typedef struct { typedef struct { uint16_t handle; uint8_t type; -} __attribute__ ((packed)) read_transmit_power_level_cp; +} QEMU_PACKED read_transmit_power_level_cp; #define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 typedef struct { uint8_t status; uint16_t handle; int8_t level; -} __attribute__ ((packed)) read_transmit_power_level_rp; +} QEMU_PACKED read_transmit_power_level_rp; #define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 #define OCF_HOST_BUFFER_SIZE 0x0033 @@ -1042,7 +1042,7 @@ typedef struct { uint8_t sco_mtu; uint16_t acl_max_pkt; uint16_t sco_max_pkt; -} __attribute__ ((packed)) host_buffer_size_cp; +} QEMU_PACKED host_buffer_size_cp; #define HOST_BUFFER_SIZE_CP_SIZE 7 #define OCF_HOST_NUMBER_OF_COMPLETED_PACKETS 0x0035 @@ -1052,19 +1052,19 @@ typedef struct { uint8_t status; uint16_t handle; uint16_t link_sup_to; -} __attribute__ ((packed)) read_link_supervision_timeout_rp; +} QEMU_PACKED read_link_supervision_timeout_rp; #define READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE 5 #define OCF_WRITE_LINK_SUPERVISION_TIMEOUT 0x0037 typedef struct { uint16_t handle; uint16_t link_sup_to; -} __attribute__ ((packed)) write_link_supervision_timeout_cp; +} QEMU_PACKED write_link_supervision_timeout_cp; #define WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE 4 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) write_link_supervision_timeout_rp; +} QEMU_PACKED write_link_supervision_timeout_rp; #define WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE 3 #define OCF_READ_NUM_SUPPORTED_IAC 0x0038 @@ -1075,14 +1075,14 @@ typedef struct { uint8_t status; uint8_t num_current_iac; uint8_t lap[MAX_IAC_LAP][3]; -} __attribute__ ((packed)) read_current_iac_lap_rp; +} QEMU_PACKED read_current_iac_lap_rp; #define READ_CURRENT_IAC_LAP_RP_SIZE 2+3*MAX_IAC_LAP #define OCF_WRITE_CURRENT_IAC_LAP 0x003A typedef struct { uint8_t num_current_iac; uint8_t lap[MAX_IAC_LAP][3]; -} __attribute__ ((packed)) write_current_iac_lap_cp; +} QEMU_PACKED write_current_iac_lap_cp; #define WRITE_CURRENT_IAC_LAP_CP_SIZE 1+3*MAX_IAC_LAP #define OCF_READ_PAGE_SCAN_PERIOD_MODE 0x003B @@ -1096,45 +1096,45 @@ typedef struct { #define OCF_SET_AFH_CLASSIFICATION 0x003F typedef struct { uint8_t map[10]; -} __attribute__ ((packed)) set_afh_classification_cp; +} QEMU_PACKED set_afh_classification_cp; #define SET_AFH_CLASSIFICATION_CP_SIZE 10 typedef struct { uint8_t status; -} __attribute__ ((packed)) set_afh_classification_rp; +} QEMU_PACKED set_afh_classification_rp; #define SET_AFH_CLASSIFICATION_RP_SIZE 1 #define OCF_READ_INQUIRY_SCAN_TYPE 0x0042 typedef struct { uint8_t status; uint8_t type; -} __attribute__ ((packed)) read_inquiry_scan_type_rp; +} QEMU_PACKED read_inquiry_scan_type_rp; #define READ_INQUIRY_SCAN_TYPE_RP_SIZE 2 #define OCF_WRITE_INQUIRY_SCAN_TYPE 0x0043 typedef struct { uint8_t type; -} __attribute__ ((packed)) write_inquiry_scan_type_cp; +} QEMU_PACKED write_inquiry_scan_type_cp; #define WRITE_INQUIRY_SCAN_TYPE_CP_SIZE 1 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_inquiry_scan_type_rp; +} QEMU_PACKED write_inquiry_scan_type_rp; #define WRITE_INQUIRY_SCAN_TYPE_RP_SIZE 1 #define OCF_READ_INQUIRY_MODE 0x0044 typedef struct { uint8_t status; uint8_t mode; -} __attribute__ ((packed)) read_inquiry_mode_rp; +} QEMU_PACKED read_inquiry_mode_rp; #define READ_INQUIRY_MODE_RP_SIZE 2 #define OCF_WRITE_INQUIRY_MODE 0x0045 typedef struct { uint8_t mode; -} __attribute__ ((packed)) write_inquiry_mode_cp; +} QEMU_PACKED write_inquiry_mode_cp; #define WRITE_INQUIRY_MODE_CP_SIZE 1 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_inquiry_mode_rp; +} QEMU_PACKED write_inquiry_mode_rp; #define WRITE_INQUIRY_MODE_RP_SIZE 1 #define OCF_READ_PAGE_SCAN_TYPE 0x0046 @@ -1145,17 +1145,17 @@ typedef struct { typedef struct { uint8_t status; uint8_t mode; -} __attribute__ ((packed)) read_afh_mode_rp; +} QEMU_PACKED read_afh_mode_rp; #define READ_AFH_MODE_RP_SIZE 2 #define OCF_WRITE_AFH_MODE 0x0049 typedef struct { uint8_t mode; -} __attribute__ ((packed)) write_afh_mode_cp; +} QEMU_PACKED write_afh_mode_cp; #define WRITE_AFH_MODE_CP_SIZE 1 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_afh_mode_rp; +} QEMU_PACKED write_afh_mode_rp; #define WRITE_AFH_MODE_RP_SIZE 1 #define OCF_READ_EXT_INQUIRY_RESPONSE 0x0051 @@ -1163,18 +1163,18 @@ typedef struct { uint8_t status; uint8_t fec; uint8_t data[240]; -} __attribute__ ((packed)) read_ext_inquiry_response_rp; +} QEMU_PACKED read_ext_inquiry_response_rp; #define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242 #define OCF_WRITE_EXT_INQUIRY_RESPONSE 0x0052 typedef struct { uint8_t fec; uint8_t data[240]; -} __attribute__ ((packed)) write_ext_inquiry_response_cp; +} QEMU_PACKED write_ext_inquiry_response_cp; #define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241 typedef struct { uint8_t status; -} __attribute__ ((packed)) write_ext_inquiry_response_rp; +} QEMU_PACKED write_ext_inquiry_response_rp; #define WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE 1 /* Informational Parameters */ @@ -1188,34 +1188,34 @@ typedef struct { uint8_t lmp_ver; uint16_t manufacturer; uint16_t lmp_subver; -} __attribute__ ((packed)) read_local_version_rp; +} QEMU_PACKED read_local_version_rp; #define READ_LOCAL_VERSION_RP_SIZE 9 #define OCF_READ_LOCAL_COMMANDS 0x0002 typedef struct { uint8_t status; uint8_t commands[64]; -} __attribute__ ((packed)) read_local_commands_rp; +} QEMU_PACKED read_local_commands_rp; #define READ_LOCAL_COMMANDS_RP_SIZE 65 #define OCF_READ_LOCAL_FEATURES 0x0003 typedef struct { uint8_t status; uint8_t features[8]; -} __attribute__ ((packed)) read_local_features_rp; +} QEMU_PACKED read_local_features_rp; #define READ_LOCAL_FEATURES_RP_SIZE 9 #define OCF_READ_LOCAL_EXT_FEATURES 0x0004 typedef struct { uint8_t page_num; -} __attribute__ ((packed)) read_local_ext_features_cp; +} QEMU_PACKED read_local_ext_features_cp; #define READ_LOCAL_EXT_FEATURES_CP_SIZE 1 typedef struct { uint8_t status; uint8_t page_num; uint8_t max_page_num; uint8_t features[8]; -} __attribute__ ((packed)) read_local_ext_features_rp; +} QEMU_PACKED read_local_ext_features_rp; #define READ_LOCAL_EXT_FEATURES_RP_SIZE 11 #define OCF_READ_BUFFER_SIZE 0x0005 @@ -1225,21 +1225,21 @@ typedef struct { uint8_t sco_mtu; uint16_t acl_max_pkt; uint16_t sco_max_pkt; -} __attribute__ ((packed)) read_buffer_size_rp; +} QEMU_PACKED read_buffer_size_rp; #define READ_BUFFER_SIZE_RP_SIZE 8 #define OCF_READ_COUNTRY_CODE 0x0007 typedef struct { uint8_t status; uint8_t country_code; -} __attribute__ ((packed)) read_country_code_rp; +} QEMU_PACKED read_country_code_rp; #define READ_COUNTRY_CODE_RP_SIZE 2 #define OCF_READ_BD_ADDR 0x0009 typedef struct { uint8_t status; bdaddr_t bdaddr; -} __attribute__ ((packed)) read_bd_addr_rp; +} QEMU_PACKED read_bd_addr_rp; #define READ_BD_ADDR_RP_SIZE 7 /* Status params */ @@ -1250,27 +1250,27 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t counter; -} __attribute__ ((packed)) read_failed_contact_counter_rp; +} QEMU_PACKED read_failed_contact_counter_rp; #define READ_FAILED_CONTACT_COUNTER_RP_SIZE 4 #define OCF_RESET_FAILED_CONTACT_COUNTER 0x0002 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) reset_failed_contact_counter_rp; +} QEMU_PACKED reset_failed_contact_counter_rp; #define RESET_FAILED_CONTACT_COUNTER_RP_SIZE 4 #define OCF_READ_LINK_QUALITY 0x0003 typedef struct { uint16_t handle; -} __attribute__ ((packed)) read_link_quality_cp; +} QEMU_PACKED read_link_quality_cp; #define READ_LINK_QUALITY_CP_SIZE 4 typedef struct { uint8_t status; uint16_t handle; uint8_t link_quality; -} __attribute__ ((packed)) read_link_quality_rp; +} QEMU_PACKED read_link_quality_rp; #define READ_LINK_QUALITY_RP_SIZE 4 #define OCF_READ_RSSI 0x0005 @@ -1278,7 +1278,7 @@ typedef struct { uint8_t status; uint16_t handle; int8_t rssi; -} __attribute__ ((packed)) read_rssi_rp; +} QEMU_PACKED read_rssi_rp; #define READ_RSSI_RP_SIZE 4 #define OCF_READ_AFH_MAP 0x0006 @@ -1287,21 +1287,21 @@ typedef struct { uint16_t handle; uint8_t mode; uint8_t map[10]; -} __attribute__ ((packed)) read_afh_map_rp; +} QEMU_PACKED read_afh_map_rp; #define READ_AFH_MAP_RP_SIZE 14 #define OCF_READ_CLOCK 0x0007 typedef struct { uint16_t handle; uint8_t which_clock; -} __attribute__ ((packed)) read_clock_cp; +} QEMU_PACKED read_clock_cp; #define READ_CLOCK_CP_SIZE 3 typedef struct { uint8_t status; uint16_t handle; uint32_t clock; uint16_t accuracy; -} __attribute__ ((packed)) read_clock_rp; +} QEMU_PACKED read_clock_rp; #define READ_CLOCK_RP_SIZE 9 /* Testing commands */ @@ -1323,7 +1323,7 @@ typedef struct { uint8_t pscan_mode; uint8_t dev_class[3]; uint16_t clock_offset; -} __attribute__ ((packed)) inquiry_info; +} QEMU_PACKED inquiry_info; #define INQUIRY_INFO_SIZE 14 #define EVT_CONN_COMPLETE 0x03 @@ -1333,7 +1333,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t link_type; uint8_t encr_mode; -} __attribute__ ((packed)) evt_conn_complete; +} QEMU_PACKED evt_conn_complete; #define EVT_CONN_COMPLETE_SIZE 11 #define EVT_CONN_REQUEST 0x04 @@ -1341,7 +1341,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t dev_class[3]; uint8_t link_type; -} __attribute__ ((packed)) evt_conn_request; +} QEMU_PACKED evt_conn_request; #define EVT_CONN_REQUEST_SIZE 10 #define EVT_DISCONN_COMPLETE 0x05 @@ -1349,14 +1349,14 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t reason; -} __attribute__ ((packed)) evt_disconn_complete; +} QEMU_PACKED evt_disconn_complete; #define EVT_DISCONN_COMPLETE_SIZE 4 #define EVT_AUTH_COMPLETE 0x06 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) evt_auth_complete; +} QEMU_PACKED evt_auth_complete; #define EVT_AUTH_COMPLETE_SIZE 3 #define EVT_REMOTE_NAME_REQ_COMPLETE 0x07 @@ -1364,7 +1364,7 @@ typedef struct { uint8_t status; bdaddr_t bdaddr; char name[248]; -} __attribute__ ((packed)) evt_remote_name_req_complete; +} QEMU_PACKED evt_remote_name_req_complete; #define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255 #define EVT_ENCRYPT_CHANGE 0x08 @@ -1372,14 +1372,14 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t encrypt; -} __attribute__ ((packed)) evt_encrypt_change; +} QEMU_PACKED evt_encrypt_change; #define EVT_ENCRYPT_CHANGE_SIZE 5 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE 0x09 typedef struct { uint8_t status; uint16_t handle; -} __attribute__ ((packed)) evt_change_conn_link_key_complete; +} QEMU_PACKED evt_change_conn_link_key_complete; #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE 3 #define EVT_MASTER_LINK_KEY_COMPLETE 0x0A @@ -1387,7 +1387,7 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t key_flag; -} __attribute__ ((packed)) evt_master_link_key_complete; +} QEMU_PACKED evt_master_link_key_complete; #define EVT_MASTER_LINK_KEY_COMPLETE_SIZE 4 #define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B @@ -1395,7 +1395,7 @@ typedef struct { uint8_t status; uint16_t handle; uint8_t features[8]; -} __attribute__ ((packed)) evt_read_remote_features_complete; +} QEMU_PACKED evt_read_remote_features_complete; #define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11 #define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C @@ -1405,7 +1405,7 @@ typedef struct { uint8_t lmp_ver; uint16_t manufacturer; uint16_t lmp_subver; -} __attribute__ ((packed)) evt_read_remote_version_complete; +} QEMU_PACKED evt_read_remote_version_complete; #define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8 #define EVT_QOS_SETUP_COMPLETE 0x0D @@ -1414,14 +1414,14 @@ typedef struct { uint16_t handle; uint8_t flags; /* Reserved */ hci_qos qos; -} __attribute__ ((packed)) evt_qos_setup_complete; +} QEMU_PACKED evt_qos_setup_complete; #define EVT_QOS_SETUP_COMPLETE_SIZE (4 + HCI_QOS_CP_SIZE) #define EVT_CMD_COMPLETE 0x0E typedef struct { uint8_t ncmd; uint16_t opcode; -} __attribute__ ((packed)) evt_cmd_complete; +} QEMU_PACKED evt_cmd_complete; #define EVT_CMD_COMPLETE_SIZE 3 #define EVT_CMD_STATUS 0x0F @@ -1429,19 +1429,19 @@ typedef struct { uint8_t status; uint8_t ncmd; uint16_t opcode; -} __attribute__ ((packed)) evt_cmd_status; +} QEMU_PACKED evt_cmd_status; #define EVT_CMD_STATUS_SIZE 4 #define EVT_HARDWARE_ERROR 0x10 typedef struct { uint8_t code; -} __attribute__ ((packed)) evt_hardware_error; +} QEMU_PACKED evt_hardware_error; #define EVT_HARDWARE_ERROR_SIZE 1 #define EVT_FLUSH_OCCURRED 0x11 typedef struct { uint16_t handle; -} __attribute__ ((packed)) evt_flush_occured; +} QEMU_PACKED evt_flush_occurred; #define EVT_FLUSH_OCCURRED_SIZE 2 #define EVT_ROLE_CHANGE 0x12 @@ -1449,7 +1449,7 @@ typedef struct { uint8_t status; bdaddr_t bdaddr; uint8_t role; -} __attribute__ ((packed)) evt_role_change; +} QEMU_PACKED evt_role_change; #define EVT_ROLE_CHANGE_SIZE 8 #define EVT_NUM_COMP_PKTS 0x13 @@ -1459,7 +1459,7 @@ typedef struct { uint16_t handle; uint16_t num_packets; } connection[0]; -} __attribute__ ((packed)) evt_num_comp_pkts; +} QEMU_PACKED evt_num_comp_pkts; #define EVT_NUM_COMP_PKTS_SIZE(num_hndl) (1 + 4 * (num_hndl)) #define EVT_MODE_CHANGE 0x14 @@ -1468,26 +1468,26 @@ typedef struct { uint16_t handle; uint8_t mode; uint16_t interval; -} __attribute__ ((packed)) evt_mode_change; +} QEMU_PACKED evt_mode_change; #define EVT_MODE_CHANGE_SIZE 6 #define EVT_RETURN_LINK_KEYS 0x15 typedef struct { uint8_t num_keys; /* variable length part */ -} __attribute__ ((packed)) evt_return_link_keys; +} QEMU_PACKED evt_return_link_keys; #define EVT_RETURN_LINK_KEYS_SIZE 1 #define EVT_PIN_CODE_REQ 0x16 typedef struct { bdaddr_t bdaddr; -} __attribute__ ((packed)) evt_pin_code_req; +} QEMU_PACKED evt_pin_code_req; #define EVT_PIN_CODE_REQ_SIZE 6 #define EVT_LINK_KEY_REQ 0x17 typedef struct { bdaddr_t bdaddr; -} __attribute__ ((packed)) evt_link_key_req; +} QEMU_PACKED evt_link_key_req; #define EVT_LINK_KEY_REQ_SIZE 6 #define EVT_LINK_KEY_NOTIFY 0x18 @@ -1495,7 +1495,7 @@ typedef struct { bdaddr_t bdaddr; uint8_t link_key[16]; uint8_t key_type; -} __attribute__ ((packed)) evt_link_key_notify; +} QEMU_PACKED evt_link_key_notify; #define EVT_LINK_KEY_NOTIFY_SIZE 23 #define EVT_LOOPBACK_COMMAND 0x19 @@ -1503,14 +1503,14 @@ typedef struct { #define EVT_DATA_BUFFER_OVERFLOW 0x1A typedef struct { uint8_t link_type; -} __attribute__ ((packed)) evt_data_buffer_overflow; +} QEMU_PACKED evt_data_buffer_overflow; #define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 #define EVT_MAX_SLOTS_CHANGE 0x1B typedef struct { uint16_t handle; uint8_t max_slots; -} __attribute__ ((packed)) evt_max_slots_change; +} QEMU_PACKED evt_max_slots_change; #define EVT_MAX_SLOTS_CHANGE_SIZE 3 #define EVT_READ_CLOCK_OFFSET_COMPLETE 0x1C @@ -1518,7 +1518,7 @@ typedef struct { uint8_t status; uint16_t handle; uint16_t clock_offset; -} __attribute__ ((packed)) evt_read_clock_offset_complete; +} QEMU_PACKED evt_read_clock_offset_complete; #define EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE 5 #define EVT_CONN_PTYPE_CHANGED 0x1D @@ -1526,20 +1526,20 @@ typedef struct { uint8_t status; uint16_t handle; uint16_t ptype; -} __attribute__ ((packed)) evt_conn_ptype_changed; +} QEMU_PACKED evt_conn_ptype_changed; #define EVT_CONN_PTYPE_CHANGED_SIZE 5 #define EVT_QOS_VIOLATION 0x1E typedef struct { uint16_t handle; -} __attribute__ ((packed)) evt_qos_violation; +} QEMU_PACKED evt_qos_violation; #define EVT_QOS_VIOLATION_SIZE 2 #define EVT_PSCAN_REP_MODE_CHANGE 0x20 typedef struct { bdaddr_t bdaddr; uint8_t pscan_rep_mode; -} __attribute__ ((packed)) evt_pscan_rep_mode_change; +} QEMU_PACKED evt_pscan_rep_mode_change; #define EVT_PSCAN_REP_MODE_CHANGE_SIZE 7 #define EVT_FLOW_SPEC_COMPLETE 0x21 @@ -1549,7 +1549,7 @@ typedef struct { uint8_t flags; uint8_t direction; hci_qos qos; -} __attribute__ ((packed)) evt_flow_spec_complete; +} QEMU_PACKED evt_flow_spec_complete; #define EVT_FLOW_SPEC_COMPLETE_SIZE (5 + HCI_QOS_CP_SIZE) #define EVT_INQUIRY_RESULT_WITH_RSSI 0x22 @@ -1561,7 +1561,7 @@ typedef struct { uint8_t dev_class[3]; uint16_t clock_offset; int8_t rssi; -} __attribute__ ((packed)) inquiry_info_with_rssi; +} QEMU_PACKED inquiry_info_with_rssi; #define INQUIRY_INFO_WITH_RSSI_SIZE 15 typedef struct { uint8_t num_responses; @@ -1572,7 +1572,7 @@ typedef struct { uint8_t dev_class[3]; uint16_t clock_offset; int8_t rssi; -} __attribute__ ((packed)) inquiry_info_with_rssi_and_pscan_mode; +} QEMU_PACKED inquiry_info_with_rssi_and_pscan_mode; #define INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE 16 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE 0x23 @@ -1582,7 +1582,7 @@ typedef struct { uint8_t page_num; uint8_t max_page_num; uint8_t features[8]; -} __attribute__ ((packed)) evt_read_remote_ext_features_complete; +} QEMU_PACKED evt_read_remote_ext_features_complete; #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE 13 #define EVT_SYNC_CONN_COMPLETE 0x2C @@ -1596,7 +1596,7 @@ typedef struct { uint16_t rx_pkt_len; uint16_t tx_pkt_len; uint8_t air_mode; -} __attribute__ ((packed)) evt_sync_conn_complete; +} QEMU_PACKED evt_sync_conn_complete; #define EVT_SYNC_CONN_COMPLETE_SIZE 17 #define EVT_SYNC_CONN_CHANGED 0x2D @@ -1607,7 +1607,7 @@ typedef struct { uint8_t retrans_window; uint16_t rx_pkt_len; uint16_t tx_pkt_len; -} __attribute__ ((packed)) evt_sync_conn_changed; +} QEMU_PACKED evt_sync_conn_changed; #define EVT_SYNC_CONN_CHANGED_SIZE 9 #define EVT_SNIFF_SUBRATE 0x2E @@ -1618,7 +1618,7 @@ typedef struct { uint16_t max_local_latency; uint16_t min_remote_timeout; uint16_t min_local_timeout; -} __attribute__ ((packed)) evt_sniff_subrate; +} QEMU_PACKED evt_sniff_subrate; #define EVT_SNIFF_SUBRATE_SIZE 11 #define EVT_EXTENDED_INQUIRY_RESULT 0x2F @@ -1630,7 +1630,7 @@ typedef struct { uint16_t clock_offset; int8_t rssi; uint8_t data[240]; -} __attribute__ ((packed)) extended_inquiry_info; +} QEMU_PACKED extended_inquiry_info; #define EXTENDED_INQUIRY_INFO_SIZE 254 #define EVT_TESTING 0xFE @@ -1656,22 +1656,22 @@ typedef struct { struct hci_command_hdr { uint16_t opcode; /* OCF & OGF */ uint8_t plen; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hci_event_hdr { uint8_t evt; uint8_t plen; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hci_acl_hdr { uint16_t handle; /* Handle & Flags(PB, BC) */ uint16_t dlen; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hci_sco_hdr { uint16_t handle; uint8_t dlen; -} __attribute__ ((packed)); +} QEMU_PACKED; /* L2CAP layer defines */ @@ -1718,25 +1718,25 @@ typedef struct { uint16_t len; uint16_t cid; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_hdr; +} QEMU_PACKED l2cap_hdr; #define L2CAP_HDR_SIZE 4 typedef struct { uint8_t code; uint8_t ident; uint16_t len; -} __attribute__ ((packed)) l2cap_cmd_hdr; +} QEMU_PACKED l2cap_cmd_hdr; #define L2CAP_CMD_HDR_SIZE 4 typedef struct { uint16_t reason; -} __attribute__ ((packed)) l2cap_cmd_rej; +} QEMU_PACKED l2cap_cmd_rej; #define L2CAP_CMD_REJ_SIZE 2 typedef struct { uint16_t dcid; uint16_t scid; -} __attribute__ ((packed)) l2cap_cmd_rej_cid; +} QEMU_PACKED l2cap_cmd_rej_cid; #define L2CAP_CMD_REJ_CID_SIZE 4 /* reject reason */ @@ -1749,7 +1749,7 @@ enum bt_l2cap_rej_reason { typedef struct { uint16_t psm; uint16_t scid; -} __attribute__ ((packed)) l2cap_conn_req; +} QEMU_PACKED l2cap_conn_req; #define L2CAP_CONN_REQ_SIZE 4 typedef struct { @@ -1757,7 +1757,7 @@ typedef struct { uint16_t scid; uint16_t result; uint16_t status; -} __attribute__ ((packed)) l2cap_conn_rsp; +} QEMU_PACKED l2cap_conn_rsp; #define L2CAP_CONN_RSP_SIZE 8 /* connect result */ @@ -1780,7 +1780,7 @@ typedef struct { uint16_t dcid; uint16_t flags; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_conf_req; +} QEMU_PACKED l2cap_conf_req; #define L2CAP_CONF_REQ_SIZE(datalen) (4 + (datalen)) typedef struct { @@ -1788,7 +1788,7 @@ typedef struct { uint16_t flags; uint16_t result; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_conf_rsp; +} QEMU_PACKED l2cap_conf_rsp; #define L2CAP_CONF_RSP_SIZE(datalen) (6 + datalen) enum bt_l2cap_conf_res { @@ -1802,7 +1802,7 @@ typedef struct { uint8_t type; uint8_t len; uint8_t val[0]; -} __attribute__ ((packed)) l2cap_conf_opt; +} QEMU_PACKED l2cap_conf_opt; #define L2CAP_CONF_OPT_SIZE 2 enum bt_l2cap_conf_val { @@ -1821,7 +1821,7 @@ typedef struct { uint32_t peak_bandwidth; uint32_t latency; uint32_t delay_variation; -} __attribute__ ((packed)) l2cap_conf_opt_qos; +} QEMU_PACKED l2cap_conf_opt_qos; #define L2CAP_CONF_OPT_QOS_SIZE 22 enum bt_l2cap_conf_opt_qos_st { @@ -1841,25 +1841,25 @@ enum bt_l2cap_mode { typedef struct { uint16_t dcid; uint16_t scid; -} __attribute__ ((packed)) l2cap_disconn_req; +} QEMU_PACKED l2cap_disconn_req; #define L2CAP_DISCONN_REQ_SIZE 4 typedef struct { uint16_t dcid; uint16_t scid; -} __attribute__ ((packed)) l2cap_disconn_rsp; +} QEMU_PACKED l2cap_disconn_rsp; #define L2CAP_DISCONN_RSP_SIZE 4 typedef struct { uint16_t type; -} __attribute__ ((packed)) l2cap_info_req; +} QEMU_PACKED l2cap_info_req; #define L2CAP_INFO_REQ_SIZE 2 typedef struct { uint16_t type; uint16_t result; uint8_t data[0]; -} __attribute__ ((packed)) l2cap_info_rsp; +} QEMU_PACKED l2cap_info_rsp; #define L2CAP_INFO_RSP_SIZE 4 /* info type */ diff --git a/hw/cbus.c b/hw/cbus.c index 8ae24e0..7216899 100644 --- a/hw/cbus.c +++ b/hw/cbus.c @@ -132,7 +132,7 @@ static void cbus_sel(void *opaque, int line, int level) CBus *cbus_init(qemu_irq dat) { - CBusPriv *s = (CBusPriv *) qemu_mallocz(sizeof(*s)); + CBusPriv *s = (CBusPriv *) g_malloc0(sizeof(*s)); s->dat_out = dat; s->cbus.clk = qemu_allocate_irqs(cbus_clk, s, 1)[0]; @@ -387,7 +387,7 @@ static void retu_io(void *opaque, int rw, int reg, uint16_t *val) void *retu_init(qemu_irq irq, int vilma) { - CBusRetu *s = (CBusRetu *) qemu_mallocz(sizeof(*s)); + CBusRetu *s = (CBusRetu *) g_malloc0(sizeof(*s)); s->irq = irq; s->irqen = 0xffff; @@ -603,7 +603,7 @@ static void tahvo_io(void *opaque, int rw, int reg, uint16_t *val) void *tahvo_init(qemu_irq irq, int betty) { - CBusTahvo *s = (CBusTahvo *) qemu_mallocz(sizeof(*s)); + CBusTahvo *s = (CBusTahvo *) g_malloc0(sizeof(*s)); s->irq = irq; s->irqen = 0xffff; diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 5f45b5d..c7e365b 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -31,7 +31,6 @@ #include "pci.h" #include "console.h" #include "vga_int.h" -#include "kvm.h" #include "loader.h" /* @@ -174,8 +173,6 @@ #define CIRRUS_PNPMMIO_SIZE 0x1000 -#define ABS(a) ((signed)(a) > 0 ? a : -a) - #define BLTUNSAFE(s) \ ( \ ( /* check dst is within bounds */ \ @@ -201,9 +198,14 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, typedef struct CirrusVGAState { VGACommonState vga; - int cirrus_linear_io_addr; - int cirrus_linear_bitblt_io_addr; - int cirrus_mmio_io_addr; + MemoryRegion cirrus_linear_io; + MemoryRegion cirrus_linear_bitblt_io; + MemoryRegion cirrus_mmio_io; + MemoryRegion pci_bar; + bool linear_vram; /* vga.vram mapped over cirrus_linear_io */ + MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */ + MemoryRegion low_mem; /* always mapped, overridden by: */ + MemoryRegion *cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */ uint32_t cirrus_addr_mask; uint32_t linear_mmio_mask; uint8_t cirrus_shadow_gr0; @@ -613,7 +615,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; off_cur &= TARGET_PAGE_MASK; while (off_cur < off_cur_end) { - cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur); + memory_region_set_dirty(&s->vga.vram, off_cur); off_cur += TARGET_PAGE_SIZE; } off_begin += off_pitch; @@ -1178,12 +1180,6 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index) } if (limit > 0) { - /* Thinking about changing bank base? First, drop the dirty bitmap information - * on the current location, otherwise we lose this pointer forever */ - if (s->vga.lfb_vram_mapped) { - target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000; - cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000); - } s->cirrus_bank_base[bank_index] = offset; s->cirrus_bank_limit[bank_index] = limit; } else { @@ -1922,8 +1918,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, val <<= 1; dst++; } - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset); - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7); + memory_region_set_dirty(&s->vga.vram, offset); + memory_region_set_dirty(&s->vga.vram, offset + 7); } static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, @@ -1947,8 +1943,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, val <<= 1; dst += 2; } - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset); - cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15); + memory_region_set_dirty(&s->vga.vram, offset); + memory_region_set_dirty(&s->vga.vram, offset + 15); } /*************************************** @@ -1957,7 +1953,9 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, * ***************************************/ -static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_vga_mem_read(void *opaque, + target_phys_addr_t addr, + uint32_t size) { CirrusVGAState *s = opaque; unsigned bank_index; @@ -1965,11 +1963,9 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) uint32_t val; if ((s->vga.sr[0x07] & 0x01) == 0) { - return vga_mem_readb(s, addr); + return vga_mem_readb(&s->vga, addr); } - addr &= 0x1ffff; - if (addr < 0x10000) { /* XXX handle bitblt */ /* video memory */ @@ -2001,28 +1997,10 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) return val; } -static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_vga_mem_readb(opaque, addr); - v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_vga_mem_readb(opaque, addr); - v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8; - v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16; - v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, - uint32_t mem_value) +static void cirrus_vga_mem_write(void *opaque, + target_phys_addr_t addr, + uint64_t mem_value, + uint32_t size) { CirrusVGAState *s = opaque; unsigned bank_index; @@ -2030,12 +2008,10 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, unsigned mode; if ((s->vga.sr[0x07] & 0x01) == 0) { - vga_mem_writeb(s, addr, mem_value); + vga_mem_writeb(&s->vga, addr, mem_value); return; } - addr &= 0x1ffff; - if (addr < 0x10000) { if (s->cirrus_srcptr != s->cirrus_srcptr_end) { /* bitblt */ @@ -2058,8 +2034,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, mode = s->vga.gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { *(s->vga.vram_ptr + bank_offset) = mem_value; - cpu_physical_memory_set_dirty(s->vga.vram_offset + - bank_offset); + memory_region_set_dirty(&s->vga.vram, bank_offset); } else { if ((s->vga.gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, @@ -2086,30 +2061,14 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - cirrus_vga_mem_writeb(opaque, addr, val & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - cirrus_vga_mem_writeb(opaque, addr, val & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - -static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = { - cirrus_vga_mem_readb, - cirrus_vga_mem_readw, - cirrus_vga_mem_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = { - cirrus_vga_mem_writeb, - cirrus_vga_mem_writew, - cirrus_vga_mem_writel, +static const MemoryRegionOps cirrus_vga_mem_ops = { + .read = cirrus_vga_mem_read, + .write = cirrus_vga_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; /*************************************** @@ -2288,7 +2247,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) * ***************************************/ -static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr, + unsigned size) { CirrusVGAState *s = opaque; uint32_t ret; @@ -2316,28 +2276,8 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_readb(opaque, addr); - v |= cirrus_linear_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_readb(opaque, addr); - v |= cirrus_linear_readb(opaque, addr + 1) << 8; - v |= cirrus_linear_readb(opaque, addr + 2) << 16; - v |= cirrus_linear_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void cirrus_linear_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { CirrusVGAState *s = opaque; unsigned mode; @@ -2366,7 +2306,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, mode = s->vga.gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { *(s->vga.vram_ptr + addr) = (uint8_t) val; - cpu_physical_memory_set_dirty(s->vga.vram_offset + addr); + memory_region_set_dirty(&s->vga.vram, addr); } else { if ((s->vga.gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val); @@ -2377,35 +2317,6 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_writeb(opaque, addr, val & 0xff); - cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_writeb(opaque, addr, val & 0xff); - cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static CPUReadMemoryFunc * const cirrus_linear_read[3] = { - cirrus_linear_readb, - cirrus_linear_readw, - cirrus_linear_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_linear_write[3] = { - cirrus_linear_writeb, - cirrus_linear_writew, - cirrus_linear_writel, -}; - /*************************************** * * system to screen memory access @@ -2413,37 +2324,23 @@ static CPUWriteMemoryFunc * const cirrus_linear_write[3] = { ***************************************/ -static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_linear_bitblt_read(void *opaque, + target_phys_addr_t addr, + unsigned size) { + CirrusVGAState *s = opaque; uint32_t ret; /* XXX handle bitblt */ + (void)s; ret = 0xff; return ret; } -static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_bitblt_readb(opaque, addr); - v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_linear_bitblt_readb(opaque, addr); - v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8; - v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16; - v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void cirrus_linear_bitblt_write(void *opaque, + target_phys_addr_t addr, + uint64_t val, + unsigned size) { CirrusVGAState *s = opaque; @@ -2456,77 +2353,70 @@ static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = { - cirrus_linear_bitblt_readb, - cirrus_linear_bitblt_readw, - cirrus_linear_bitblt_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = { - cirrus_linear_bitblt_writeb, - cirrus_linear_bitblt_writew, - cirrus_linear_bitblt_writel, +static const MemoryRegionOps cirrus_linear_bitblt_io_ops = { + .read = cirrus_linear_bitblt_read, + .write = cirrus_linear_bitblt_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; -static void map_linear_vram(CirrusVGAState *s) +static void unmap_bank(CirrusVGAState *s, unsigned bank) { - if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) { - s->vga.map_addr = s->vga.lfb_addr; - s->vga.map_end = s->vga.lfb_end; - cpu_register_physical_memory(s->vga.map_addr, s->vga.map_end - s->vga.map_addr, s->vga.vram_offset); + if (s->cirrus_bank[bank]) { + memory_region_del_subregion(&s->low_mem_container, + s->cirrus_bank[bank]); + memory_region_destroy(s->cirrus_bank[bank]); + g_free(s->cirrus_bank[bank]); + s->cirrus_bank[bank] = NULL; } +} - if (!s->vga.map_addr) - return; - - s->vga.lfb_vram_mapped = 0; +static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank) +{ + MemoryRegion *mr; + static const char *names[] = { "vga.bank0", "vga.bank1" }; if (!(s->cirrus_srcptr != s->cirrus_srcptr_end) && !((s->vga.sr[0x07] & 0x01) == 0) && !((s->vga.gr[0x0B] & 0x14) == 0x14) && !(s->vga.gr[0x0B] & 0x02)) { - cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000, - (s->vga.vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM); - cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000, - (s->vga.vram_offset + s->cirrus_bank_base[1]) | IO_MEM_RAM); - - s->vga.lfb_vram_mapped = 1; - } - else { - cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000, - s->vga.vga_io_memory); + mr = g_malloc(sizeof(*mr)); + memory_region_init_alias(mr, names[bank], &s->vga.vram, + s->cirrus_bank_base[bank], 0x8000); + memory_region_add_subregion_overlap( + &s->low_mem_container, + 0x8000 * bank, + mr, + 1); + unmap_bank(s, bank); + s->cirrus_bank[bank] = mr; + } else { + unmap_bank(s, bank); } +} - vga_dirty_log_start(&s->vga); +static void map_linear_vram(CirrusVGAState *s) +{ + if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) { + s->linear_vram = true; + memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1); + } + map_linear_vram_bank(s, 0); + map_linear_vram_bank(s, 1); } static void unmap_linear_vram(CirrusVGAState *s) { - if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) { - s->vga.map_addr = s->vga.map_end = 0; - cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size, - s->cirrus_linear_io_addr); + if (s->bustype == CIRRUS_BUSTYPE_PCI && s->linear_vram) { + s->linear_vram = false; + memory_region_del_subregion(&s->pci_bar, &s->vga.vram); } - cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000, - s->vga.vga_io_memory); + unmap_bank(s, 0); + unmap_bank(s, 1); } /* Compute the memory access functions */ @@ -2534,6 +2424,7 @@ static void cirrus_update_memory_access(CirrusVGAState *s) { unsigned mode; + memory_region_transaction_begin(); if ((s->vga.sr[0x17] & 0x44) == 0x44) { goto generic_io; } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { @@ -2553,6 +2444,7 @@ static void cirrus_update_memory_access(CirrusVGAState *s) unmap_linear_vram(s); } } + memory_region_transaction_commit(); } @@ -2760,12 +2652,11 @@ static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) * ***************************************/ -static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { CirrusVGAState *s = opaque; - addr &= CIRRUS_PNPMMIO_SIZE - 1; - if (addr >= 0x100) { return cirrus_mmio_blt_read(s, addr - 0x100); } else { @@ -2773,33 +2664,11 @@ static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr) } } -static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_mmio_readb(opaque, addr); - v |= cirrus_mmio_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - - v = cirrus_mmio_readb(opaque, addr); - v |= cirrus_mmio_readb(opaque, addr + 1) << 8; - v |= cirrus_mmio_readb(opaque, addr + 2) << 16; - v |= cirrus_mmio_readb(opaque, addr + 3) << 24; - return v; -} - -static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { CirrusVGAState *s = opaque; - addr &= CIRRUS_PNPMMIO_SIZE - 1; - if (addr >= 0x100) { cirrus_mmio_blt_write(s, addr - 0x100, val); } else { @@ -2807,33 +2676,14 @@ static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_mmio_writeb(opaque, addr, val & 0xff); - cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - cirrus_mmio_writeb(opaque, addr, val & 0xff); - cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff); - cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff); - cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static CPUReadMemoryFunc * const cirrus_mmio_read[3] = { - cirrus_mmio_readb, - cirrus_mmio_readw, - cirrus_mmio_readl, -}; - -static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = { - cirrus_mmio_writeb, - cirrus_mmio_writew, - cirrus_mmio_writel, +static const MemoryRegionOps cirrus_mmio_io_ops = { + .read = cirrus_mmio_read, + .write = cirrus_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; /* load/save state */ @@ -2942,7 +2792,18 @@ static void cirrus_reset(void *opaque) s->cirrus_hidden_dac_data = 0; } -static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) +static const MemoryRegionOps cirrus_linear_io_ops = { + .read = cirrus_linear_read, + .write = cirrus_linear_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, + MemoryRegion *system_memory) { int i; static int inited; @@ -2988,28 +2849,33 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s); register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s); - s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read, - cirrus_vga_mem_write, s, - DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, - s->vga.vga_io_memory); - qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); + memory_region_init(&s->low_mem_container, + "cirrus-lowmem-container", + 0x20000); + + memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s, + "cirrus-low-memory", 0x20000); + memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem); + memory_region_add_subregion_overlap(system_memory, + isa_mem_base + 0x000a0000, + &s->low_mem_container, + 1); + memory_region_set_coalescing(&s->low_mem); /* I/O handler for LFB */ - s->cirrus_linear_io_addr = - cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s, + "cirrus-linear-io", VGA_RAM_SIZE); /* I/O handler for LFB */ - s->cirrus_linear_bitblt_io_addr = - cpu_register_io_memory(cirrus_linear_bitblt_read, - cirrus_linear_bitblt_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->cirrus_linear_bitblt_io, + &cirrus_linear_bitblt_io_ops, + s, + "cirrus-bitblt-mmio", + 0x400000); /* I/O handler for memory-mapped I/O */ - s->cirrus_mmio_io_addr = - cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s, + "cirrus-mmio", CIRRUS_PNPMMIO_SIZE); s->real_vram_size = (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024; @@ -3025,7 +2891,6 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) s->vga.cursor_draw_line = cirrus_cursor_draw_line; qemu_register_reset(cirrus_reset, s); - cirrus_reset(s); } /*************************************** @@ -3034,14 +2899,14 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) * ***************************************/ -void isa_cirrus_vga_init(void) +void isa_cirrus_vga_init(MemoryRegion *system_memory) { CirrusVGAState *s; - s = qemu_mallocz(sizeof(CirrusVGAState)); + s = g_malloc0(sizeof(CirrusVGAState)); vga_common_init(&s->vga, VGA_RAM_SIZE); - cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0); + cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0, system_memory); s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate, s->vga.screen_dump, s->vga.text_update, &s->vga); @@ -3056,76 +2921,36 @@ void isa_cirrus_vga_init(void) * ***************************************/ -static void cirrus_pci_lfb_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga; - - /* XXX: add byte swapping apertures */ - cpu_register_physical_memory(addr, s->vga.vram_size, - s->cirrus_linear_io_addr); - cpu_register_physical_memory(addr + 0x1000000, 0x400000, - s->cirrus_linear_bitblt_io_addr); - - s->vga.map_addr = s->vga.map_end = 0; - s->vga.lfb_addr = addr & TARGET_PAGE_MASK; - s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; - /* account for overflow */ - if (s->vga.lfb_end < addr + VGA_RAM_SIZE) - s->vga.lfb_end = addr + VGA_RAM_SIZE; - - vga_dirty_log_start(&s->vga); -} - -static void cirrus_pci_mmio_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga; - - cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE, - s->cirrus_mmio_io_addr); -} - -static void pci_cirrus_write_config(PCIDevice *d, - uint32_t address, uint32_t val, int len) -{ - PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d); - CirrusVGAState *s = &pvs->cirrus_vga; - - pci_default_write_config(d, address, val, len); - if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) - s->vga.map_addr = 0; - cirrus_update_memory_access(s); -} - static int pci_cirrus_vga_initfn(PCIDevice *dev) { PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev); CirrusVGAState *s = &d->cirrus_vga; - uint8_t *pci_conf = d->dev.config; - int device_id = CIRRUS_ID_CLGD5446; + PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->qdev.info); + int16_t device_id = info->device_id; /* setup VGA */ vga_common_init(&s->vga, VGA_RAM_SIZE); - cirrus_init_common(s, device_id, 1); + cirrus_init_common(s, device_id, 1, pci_address_space(dev)); s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate, s->vga.screen_dump, s->vga.text_update, &s->vga); /* setup PCI */ - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS); - pci_config_set_device_id(pci_conf, device_id); - pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA); + + memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000); + + /* XXX: add byte swapping apertures */ + memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io); + memory_region_add_subregion(&s->pci_bar, 0x1000000, + &s->cirrus_linear_bitblt_io); /* setup memory space */ /* memory #0 LFB */ /* memory #1 memory-mapped I/O */ /* XXX: s->vga.vram_size must be a power of two */ - pci_register_bar(&d->dev, 0, 0x2000000, - PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar); if (device_id == CIRRUS_ID_CLGD5446) { - pci_register_bar(&d->dev, 1, CIRRUS_PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map); + pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io); } return 0; } @@ -3143,7 +2968,9 @@ static PCIDeviceInfo cirrus_vga_info = { .no_hotplug = 1, .init = pci_cirrus_vga_initfn, .romfile = VGABIOS_CIRRUS_FILENAME, - .config_write = pci_cirrus_write_config, + .vendor_id = PCI_VENDOR_ID_CIRRUS, + .device_id = CIRRUS_ID_CLGD5446, + .class_id = PCI_CLASS_DISPLAY_VGA, }; static void cirrus_vga_register(void) diff --git a/hw/cris-boot.c b/hw/cris-boot.c index 2ef17f6..37894f8 100644 --- a/hw/cris-boot.c +++ b/hw/cris-boot.c @@ -23,7 +23,6 @@ */ #include "hw.h" -#include "sysemu.h" #include "loader.h" #include "elf.h" #include "cris-boot.h" diff --git a/hw/cris_pic_cpu.c b/hw/cris_pic_cpu.c index a92d445..06ae484 100644 --- a/hw/cris_pic_cpu.c +++ b/hw/cris_pic_cpu.c @@ -22,17 +22,12 @@ * THE SOFTWARE. */ +#include "sysbus.h" #include "hw.h" -#include "pc.h" #include "etraxfs.h" #define D(x) -void pic_info(Monitor *mon) -{} -void irq_info(Monitor *mon) -{} - static void cris_pic_cpu_handler(void *opaque, int irq, int level) { CPUState *env = (CPUState *)opaque; diff --git a/hw/cs4231a.c b/hw/cs4231a.c index 598f032..a7e03a3 100644 --- a/hw/cs4231a.c +++ b/hw/cs4231a.c @@ -59,6 +59,7 @@ static struct { typedef struct CSState { ISADevice dev; QEMUSoundCard card; + MemoryRegion ioports; qemu_irq pic; uint32_t regs[CS_REGS]; uint8_t dregs[CS_DREGS]; @@ -74,14 +75,6 @@ typedef struct CSState { int16_t *tab; } CSState; -#define IO_READ_PROTO(name) \ - static uint32_t name (void *opaque, uint32_t addr) - -#define IO_WRITE_PROTO(name) \ - static void name (void *opaque, uint32_t addr, uint32_t val) - -#define GET_SADDR(addr) (addr & 3) - #define MODE2 (1 << 6) #define MCE (1 << 6) #define PMCE (1 << 4) @@ -353,12 +346,12 @@ static void cs_reset_voices (CSState *s, uint32_t val) } } -IO_READ_PROTO (cs_read) +static uint64_t cs_read (void *opaque, target_phys_addr_t addr, unsigned size) { CSState *s = opaque; uint32_t saddr, iaddr, ret; - saddr = GET_SADDR (addr); + saddr = addr; iaddr = ~0U; switch (saddr) { @@ -390,12 +383,14 @@ IO_READ_PROTO (cs_read) return ret; } -IO_WRITE_PROTO (cs_write) +static void cs_write (void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned size) { CSState *s = opaque; - uint32_t saddr, iaddr; + uint32_t saddr, iaddr, val; - saddr = GET_SADDR (addr); + saddr = addr; + val = val64; switch (saddr) { case Index_Address: @@ -637,18 +632,23 @@ static const VMStateDescription vmstate_cs4231a = { } }; +static const MemoryRegionOps cs_ioport_ops = { + .read = cs_read, + .write = cs_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + } +}; + static int cs4231a_initfn (ISADevice *dev) { CSState *s = DO_UPCAST (CSState, dev, dev); - int i; isa_init_irq (dev, &s->pic, s->irq); - for (i = 0; i < 4; i++) { - isa_init_ioport(dev, i); - register_ioport_write (s->port + i, 1, 1, cs_write, s); - register_ioport_read (s->port + i, 1, 1, cs_read, s); - } + memory_region_init_io (&s->ioports, &cs_ioport_ops, s, "cs4231a", 4); + isa_register_ioport (dev, &s->ioports, s->port); DMA_register_channel (s->dma, cs_dma_read, s); diff --git a/hw/cuda.c b/hw/cuda.c index e4c178d..4077436 100644 --- a/hw/cuda.c +++ b/hw/cuda.c @@ -24,6 +24,7 @@ */ #include "hw.h" #include "ppc_mac.h" +#include "adb.h" #include "qemu-timer.h" #include "sysemu.h" @@ -117,6 +118,7 @@ typedef struct CUDATimer { } CUDATimer; typedef struct CUDAState { + MemoryRegion mem; /* cuda registers */ uint8_t b; /* B-side data */ uint8_t a; /* A-side data */ @@ -170,7 +172,7 @@ static unsigned int get_counter(CUDATimer *s) int64_t d; unsigned int counter; - d = muldiv64(qemu_get_clock(vm_clock) - s->load_time, + d = muldiv64(qemu_get_clock_ns(vm_clock) - s->load_time, CUDA_TIMER_FREQ, get_ticks_per_sec()); if (s->index == 0) { /* the timer goes down from latch to -1 (period of latch + 2) */ @@ -189,7 +191,7 @@ static unsigned int get_counter(CUDATimer *s) static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val) { CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val); - ti->load_time = qemu_get_clock(vm_clock); + ti->load_time = qemu_get_clock_ns(vm_clock); ti->counter_value = val; cuda_timer_update(s, ti, ti->load_time); } @@ -346,7 +348,7 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) break; case 4: s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; - cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); + cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock)); break; case 5: s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); @@ -355,12 +357,12 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) break; case 6: s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; - cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); + cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock)); break; case 7: s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); s->ifr &= ~T1_INT; - cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); + cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock)); break; case 8: s->timers[1].latch = val; @@ -374,7 +376,7 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) break; case 11: s->acr = val; - cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); + cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock)); cuda_update(s); break; case 12: @@ -506,7 +508,7 @@ static void cuda_adb_poll(void *opaque) cuda_send_packet_to_host(s, obuf, olen + 2); } qemu_mod_timer(s->adb_poll_timer, - qemu_get_clock(vm_clock) + + qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ)); } @@ -524,7 +526,7 @@ static void cuda_receive_packet(CUDAState *s, s->autopoll = autopoll; if (autopoll) { qemu_mod_timer(s->adb_poll_timer, - qemu_get_clock(vm_clock) + + qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ)); } else { qemu_del_timer(s->adb_poll_timer); @@ -536,14 +538,14 @@ static void cuda_receive_packet(CUDAState *s, break; case CUDA_SET_TIME: ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4]; - s->tick_offset = ti - (qemu_get_clock(vm_clock) / get_ticks_per_sec()); + s->tick_offset = ti - (qemu_get_clock_ns(vm_clock) / get_ticks_per_sec()); obuf[0] = CUDA_PACKET; obuf[1] = 0; obuf[2] = 0; cuda_send_packet_to_host(s, obuf, 3); break; case CUDA_GET_TIME: - ti = s->tick_offset + (qemu_get_clock(vm_clock) / get_ticks_per_sec()); + ti = s->tick_offset + (qemu_get_clock_ns(vm_clock) / get_ticks_per_sec()); obuf[0] = CUDA_PACKET; obuf[1] = 0; obuf[2] = 0; @@ -632,92 +634,72 @@ static uint32_t cuda_readl (void *opaque, target_phys_addr_t addr) return 0; } -static CPUWriteMemoryFunc * const cuda_write[] = { - &cuda_writeb, - &cuda_writew, - &cuda_writel, +static MemoryRegionOps cuda_ops = { + .old_mmio = { + .write = { + cuda_writeb, + cuda_writew, + cuda_writel, + }, + .read = { + cuda_readb, + cuda_readw, + cuda_readl, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUReadMemoryFunc * const cuda_read[] = { - &cuda_readb, - &cuda_readw, - &cuda_readl, -}; - -static void cuda_save_timer(QEMUFile *f, CUDATimer *s) -{ - qemu_put_be16s(f, &s->latch); - qemu_put_be16s(f, &s->counter_value); - qemu_put_sbe64s(f, &s->load_time); - qemu_put_sbe64s(f, &s->next_irq_time); - if (s->timer) - qemu_put_timer(f, s->timer); -} - -static void cuda_save(QEMUFile *f, void *opaque) +static bool cuda_timer_exist(void *opaque, int version_id) { - CUDAState *s = (CUDAState *)opaque; - - qemu_put_ubyte(f, s->b); - qemu_put_ubyte(f, s->a); - qemu_put_ubyte(f, s->dirb); - qemu_put_ubyte(f, s->dira); - qemu_put_ubyte(f, s->sr); - qemu_put_ubyte(f, s->acr); - qemu_put_ubyte(f, s->pcr); - qemu_put_ubyte(f, s->ifr); - qemu_put_ubyte(f, s->ier); - qemu_put_ubyte(f, s->anh); - qemu_put_sbe32s(f, &s->data_in_size); - qemu_put_sbe32s(f, &s->data_in_index); - qemu_put_sbe32s(f, &s->data_out_index); - qemu_put_ubyte(f, s->autopoll); - qemu_put_buffer(f, s->data_in, sizeof(s->data_in)); - qemu_put_buffer(f, s->data_out, sizeof(s->data_out)); - qemu_put_be32s(f, &s->tick_offset); - cuda_save_timer(f, &s->timers[0]); - cuda_save_timer(f, &s->timers[1]); -} + CUDATimer *s = opaque; -static void cuda_load_timer(QEMUFile *f, CUDATimer *s) -{ - qemu_get_be16s(f, &s->latch); - qemu_get_be16s(f, &s->counter_value); - qemu_get_sbe64s(f, &s->load_time); - qemu_get_sbe64s(f, &s->next_irq_time); - if (s->timer) - qemu_get_timer(f, s->timer); + return s->timer != NULL; } -static int cuda_load(QEMUFile *f, void *opaque, int version_id) -{ - CUDAState *s = (CUDAState *)opaque; - - if (version_id != 1) - return -EINVAL; - - s->b = qemu_get_ubyte(f); - s->a = qemu_get_ubyte(f); - s->dirb = qemu_get_ubyte(f); - s->dira = qemu_get_ubyte(f); - s->sr = qemu_get_ubyte(f); - s->acr = qemu_get_ubyte(f); - s->pcr = qemu_get_ubyte(f); - s->ifr = qemu_get_ubyte(f); - s->ier = qemu_get_ubyte(f); - s->anh = qemu_get_ubyte(f); - qemu_get_sbe32s(f, &s->data_in_size); - qemu_get_sbe32s(f, &s->data_in_index); - qemu_get_sbe32s(f, &s->data_out_index); - s->autopoll = qemu_get_ubyte(f); - qemu_get_buffer(f, s->data_in, sizeof(s->data_in)); - qemu_get_buffer(f, s->data_out, sizeof(s->data_out)); - qemu_get_be32s(f, &s->tick_offset); - cuda_load_timer(f, &s->timers[0]); - cuda_load_timer(f, &s->timers[1]); +static const VMStateDescription vmstate_cuda_timer = { + .name = "cuda_timer", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT16(latch, CUDATimer), + VMSTATE_UINT16(counter_value, CUDATimer), + VMSTATE_INT64(load_time, CUDATimer), + VMSTATE_INT64(next_irq_time, CUDATimer), + VMSTATE_TIMER_TEST(timer, CUDATimer, cuda_timer_exist), + VMSTATE_END_OF_LIST() + } +}; - return 0; -} +static const VMStateDescription vmstate_cuda = { + .name = "cuda", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(a, CUDAState), + VMSTATE_UINT8(b, CUDAState), + VMSTATE_UINT8(dira, CUDAState), + VMSTATE_UINT8(dirb, CUDAState), + VMSTATE_UINT8(sr, CUDAState), + VMSTATE_UINT8(acr, CUDAState), + VMSTATE_UINT8(pcr, CUDAState), + VMSTATE_UINT8(ifr, CUDAState), + VMSTATE_UINT8(ier, CUDAState), + VMSTATE_UINT8(anh, CUDAState), + VMSTATE_INT32(data_in_size, CUDAState), + VMSTATE_INT32(data_in_index, CUDAState), + VMSTATE_INT32(data_out_index, CUDAState), + VMSTATE_UINT8(autopoll, CUDAState), + VMSTATE_BUFFER(data_in, CUDAState), + VMSTATE_BUFFER(data_out, CUDAState), + VMSTATE_UINT32(tick_offset, CUDAState), + VMSTATE_STRUCT_ARRAY(timers, CUDAState, 2, 1, + vmstate_cuda_timer, CUDATimer), + VMSTATE_END_OF_LIST() + } +}; static void cuda_reset(void *opaque) { @@ -746,7 +728,7 @@ static void cuda_reset(void *opaque) set_counter(s, &s->timers[1], 0xffff); } -void cuda_init (int *cuda_mem_index, qemu_irq irq) +void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq) { struct tm tm; CUDAState *s = &cuda_state; @@ -754,16 +736,17 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq) s->irq = irq; s->timers[0].index = 0; - s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s); + s->timers[0].timer = qemu_new_timer_ns(vm_clock, cuda_timer1, s); s->timers[1].index = 1; qemu_get_timedate(&tm, 0); s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET; - s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); - *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s, - DEVICE_NATIVE_ENDIAN); - register_savevm(NULL, "cuda", -1, 1, cuda_save, cuda_load, s); + s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s); + memory_region_init_io(&s->mem, &cuda_ops, s, "cuda", 0x2000); + + *cuda_mem = &s->mem; + vmstate_register(NULL, -1, &vmstate_cuda, s); qemu_register_reset(cuda_reset, s); } diff --git a/hw/debugcon.c b/hw/debugcon.c index 5ee6821..c9ee6d9 100644 --- a/hw/debugcon.c +++ b/hw/debugcon.c @@ -51,7 +51,7 @@ static void debugcon_ioport_write(void *opaque, uint32_t addr, uint32_t val) printf("debugcon: write addr=0x%04x val=0x%02x\n", addr, val); #endif - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); } diff --git a/hw/dec_pci.c b/hw/dec_pci.c index bf88f2a..1aec066 100644 --- a/hw/dec_pci.c +++ b/hw/dec_pci.c @@ -50,28 +50,16 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num) return irq_num; } -static int dec_21154_initfn(PCIDevice *dev) -{ - int rc; - - rc = pci_bridge_initfn(dev); - if (rc < 0) { - return rc; - } - - pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_DEC); - pci_config_set_device_id(dev->config, PCI_DEVICE_ID_DEC_21154); - return 0; -} - static PCIDeviceInfo dec_21154_pci_bridge_info = { .qdev.name = "dec-21154-p2p-bridge", .qdev.desc = "DEC 21154 PCI-PCI bridge", .qdev.size = sizeof(PCIBridge), .qdev.vmsd = &vmstate_pci_device, .qdev.reset = pci_bridge_reset, - .init = dec_21154_initfn, + .init = pci_bridge_initfn, .exit = pci_bridge_exitfn, + .vendor_id = PCI_VENDOR_ID_DEC, + .device_id = PCI_DEVICE_ID_DEC_21154, .config_write = pci_bridge_write_config, .is_bridge = 1, }; @@ -92,26 +80,21 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn) static int pci_dec_21154_init_device(SysBusDevice *dev) { DECState *s; - int pci_mem_config, pci_mem_data; s = FROM_SYSBUS(DECState, dev); - pci_mem_config = pci_host_conf_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - pci_mem_data = pci_host_data_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, pci_mem_config); - sysbus_init_mmio(dev, 0x1000, pci_mem_data); + memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, + &s->host_state, "pci-conf-idx", 0x1000); + memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, + &s->host_state, "pci-data-idx", 0x1000); + sysbus_init_mmio_region(dev, &s->host_state.conf_mem); + sysbus_init_mmio_region(dev, &s->host_state.data_mem); return 0; } static int dec_21154_pci_host_init(PCIDevice *d) { /* PCI2PCI bridge same values as PearPC - check this */ - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_DEC_21154); - pci_set_byte(d->config + PCI_REVISION_ID, 0x02); - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI); return 0; } @@ -119,6 +102,10 @@ static PCIDeviceInfo dec_21154_pci_host_info = { .qdev.name = "dec-21154", .qdev.size = sizeof(PCIDevice), .init = dec_21154_pci_host_init, + .vendor_id = PCI_VENDOR_ID_DEC, + .device_id = PCI_DEVICE_ID_DEC_21154, + .revision = 0x02, + .class_id = PCI_CLASS_BRIDGE_PCI, .is_bridge = 1, }; diff --git a/hw/devices.h b/hw/devices.h index c788373..1a55c1e 100644 --- a/hw/devices.h +++ b/hw/devices.h @@ -1,6 +1,9 @@ #ifndef QEMU_DEVICES_H #define QEMU_DEVICES_H +/* ??? Not all users of this file can include cpu-common.h. */ +struct MemoryRegion; + /* Devices that have nowhere better to go. */ /* smc91c111.c */ @@ -47,24 +50,19 @@ void *tahvo_init(qemu_irq irq, int betty); void retu_key_event(void *retu, int state); -/* tusb6010.c */ -typedef struct TUSBState TUSBState; -TUSBState *tusb6010_init(qemu_irq intr); -int tusb6010_sync_io(TUSBState *s); -int tusb6010_async_io(TUSBState *s); -void tusb6010_power(TUSBState *s, int on); - /* tc6393xb.c */ typedef struct TC6393xbState TC6393xbState; #define TC6393XB_RAM 0x110000 /* amount of ram for Video and USB */ -TC6393xbState *tc6393xb_init(uint32_t base, qemu_irq irq); +TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem, + uint32_t base, qemu_irq irq); void tc6393xb_gpio_out_set(TC6393xbState *s, int line, qemu_irq handler); qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s); qemu_irq tc6393xb_l3v_get(TC6393xbState *s); /* sm501.c */ -void sm501_init(uint32_t base, uint32_t local_mem_bytes, qemu_irq irq, +void sm501_init(struct MemoryRegion *address_space_mem, uint32_t base, + uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr); #endif diff --git a/hw/dma.c b/hw/dma.c index 8a7302a..0a9322d 100644 --- a/hw/dma.c +++ b/hw/dma.c @@ -358,6 +358,14 @@ static void DMA_run (void) struct dma_cont *d; int icont, ichan; int rearm = 0; + static int running = 0; + + if (running) { + rearm = 1; + goto out; + } else { + running = 1; + } d = dma_controllers; @@ -374,6 +382,8 @@ static void DMA_run (void) } } + running = 0; +out: if (rearm) qemu_bh_schedule_idle(dma_bh); } diff --git a/hw/dp8393x.c b/hw/dp8393x.c index 0ef8abe..f66844b 100644 --- a/hw/dp8393x.c +++ b/hw/dp8393x.c @@ -290,7 +290,7 @@ static void set_next_tick(dp8393xState *s) } ticks = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0]; - s->wt_last_update = qemu_get_clock(vm_clock); + s->wt_last_update = qemu_get_clock_ns(vm_clock); delay = get_ticks_per_sec() * ticks / 5000000; qemu_mod_timer(s->watchdog, s->wt_last_update + delay); } @@ -305,7 +305,7 @@ static void update_wt_regs(dp8393xState *s) return; } - elapsed = s->wt_last_update - qemu_get_clock(vm_clock); + elapsed = s->wt_last_update - qemu_get_clock_ns(vm_clock); val = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0]; val -= elapsed / 5000000; s->regs[SONIC_WT1] = (val >> 16) & 0xffff; @@ -870,7 +870,7 @@ static void nic_cleanup(VLANClientState *nc) qemu_del_timer(s->watchdog); qemu_free_timer(s->watchdog); - qemu_free(s); + g_free(s); } static NetClientInfo net_dp83932_info = { @@ -889,16 +889,16 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift, qemu_check_nic_model(nd, "dp83932"); - s = qemu_mallocz(sizeof(dp8393xState)); + s = g_malloc0(sizeof(dp8393xState)); s->mem_opaque = mem_opaque; s->memory_rw = memory_rw; s->it_shift = it_shift; s->irq = irq; - s->watchdog = qemu_new_timer(vm_clock, dp8393x_watchdog, s); + s->watchdog = qemu_new_timer_ns(vm_clock, dp8393x_watchdog, s); s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */ - memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(s->conf.macaddr)); + s->conf.macaddr = nd->macaddr; s->conf.vlan = nd->vlan; s->conf.peer = nd->netdev; diff --git a/hw/ds1225y.c b/hw/ds1225y.c index b1c5232..6852a61 100644 --- a/hw/ds1225y.c +++ b/hw/ds1225y.c @@ -22,31 +22,24 @@ * THE SOFTWARE. */ -#include "hw.h" -#include "mips.h" -#include "nvram.h" +#include "sysbus.h" +#include "trace.h" -//#define DEBUG_NVRAM - -typedef struct ds1225y_t -{ +typedef struct { + DeviceState qdev; uint32_t chip_size; - QEMUFile *file; + char *filename; + FILE *file; uint8_t *contents; - uint8_t protection; -} ds1225y_t; - +} NvRamState; static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr) { - ds1225y_t *s = opaque; + NvRamState *s = opaque; uint32_t val; val = s->contents[addr]; - -#ifdef DEBUG_NVRAM - printf("nvram: read 0x%x at " TARGET_FMT_lx "\n", val, addr); -#endif + trace_nvram_read(addr, val); return val; } @@ -70,17 +63,16 @@ static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr) static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t val) { - ds1225y_t *s = opaque; + NvRamState *s = opaque; -#ifdef DEBUG_NVRAM - printf("nvram: write 0x%x at " TARGET_FMT_lx "\n", val, addr); -#endif + val &= 0xff; + trace_nvram_write(addr, s->contents[addr], val); - s->contents[addr] = val & 0xff; + s->contents[addr] = val; if (s->file) { - qemu_fseek(s->file, addr, SEEK_SET); - qemu_put_byte(s->file, (int)val); - qemu_fflush(s->file); + fseek(s->file, addr, SEEK_SET); + fputc(val, s->file); + fflush(s->file); } } @@ -98,34 +90,6 @@ static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t val) nvram_writeb(opaque, addr + 3, (val >> 24) & 0xff); } -static void nvram_writeb_protected (void *opaque, target_phys_addr_t addr, uint32_t val) -{ - ds1225y_t *s = opaque; - - if (s->protection != 7) { -#ifdef DEBUG_NVRAM - printf("nvram: prevent write of 0x%x at " TARGET_FMT_lx "\n", val, addr); -#endif - return; - } - - nvram_writeb(opaque, addr, val); -} - -static void nvram_writew_protected (void *opaque, target_phys_addr_t addr, uint32_t val) -{ - nvram_writeb_protected(opaque, addr, val & 0xff); - nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void nvram_writel_protected (void *opaque, target_phys_addr_t addr, uint32_t val) -{ - nvram_writeb_protected(opaque, addr, val & 0xff); - nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff); - nvram_writeb_protected(opaque, addr + 2, (val >> 16) & 0xff); - nvram_writeb_protected(opaque, addr + 3, (val >> 24) & 0xff); -} - static CPUReadMemoryFunc * const nvram_read[] = { &nvram_readb, &nvram_readw, @@ -138,45 +102,87 @@ static CPUWriteMemoryFunc * const nvram_write[] = { &nvram_writel, }; -static CPUWriteMemoryFunc * const nvram_write_protected[] = { - &nvram_writeb_protected, - &nvram_writew_protected, - &nvram_writel_protected, +static int nvram_post_load(void *opaque, int version_id) +{ + NvRamState *s = opaque; + + /* Close file, as filename may has changed in load/store process */ + if (s->file) { + fclose(s->file); + } + + /* Write back nvram contents */ + s->file = fopen(s->filename, "wb"); + if (s->file) { + /* Write back contents, as 'wb' mode cleaned the file */ + if (fwrite(s->contents, s->chip_size, 1, s->file) != 1) { + printf("nvram_post_load: short write\n"); + } + fflush(s->file); + } + + return 0; +} + +static const VMStateDescription vmstate_nvram = { + .name = "nvram", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = nvram_post_load, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32(contents, NvRamState, chip_size, 0, + vmstate_info_uint8, uint8_t), + VMSTATE_END_OF_LIST() + } }; -/* Initialisation routine */ -void *ds1225y_init(target_phys_addr_t mem_base, const char *filename) +typedef struct { + SysBusDevice busdev; + NvRamState nvram; +} SysBusNvRamState; + +static int nvram_sysbus_initfn(SysBusDevice *dev) { - ds1225y_t *s; - int mem_indexRW, mem_indexRP; - QEMUFile *file; + NvRamState *s = &FROM_SYSBUS(SysBusNvRamState, dev)->nvram; + FILE *file; + int s_io; + + s->contents = g_malloc0(s->chip_size); - s = qemu_mallocz(sizeof(ds1225y_t)); - s->chip_size = 0x2000; /* Fixed for ds1225y chip: 8 KiB */ - s->contents = qemu_mallocz(s->chip_size); - s->protection = 7; + s_io = cpu_register_io_memory(nvram_read, nvram_write, s, + DEVICE_NATIVE_ENDIAN); + sysbus_init_mmio(dev, s->chip_size, s_io); /* Read current file */ - file = qemu_fopen(filename, "rb"); + file = fopen(s->filename, "rb"); if (file) { /* Read nvram contents */ - qemu_get_buffer(file, s->contents, s->chip_size); - qemu_fclose(file); - } - s->file = qemu_fopen(filename, "wb"); - if (s->file) { - /* Write back contents, as 'wb' mode cleaned the file */ - qemu_put_buffer(s->file, s->contents, s->chip_size); - qemu_fflush(s->file); + if (fread(s->contents, s->chip_size, 1, file) != 1) { + printf("nvram_sysbus_initfn: short read\n"); + } + fclose(file); } + nvram_post_load(s, 0); - /* Read/write memory */ - mem_indexRW = cpu_register_io_memory(nvram_read, nvram_write, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(mem_base, s->chip_size, mem_indexRW); - /* Read/write protected memory */ - mem_indexRP = cpu_register_io_memory(nvram_read, nvram_write_protected, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(mem_base + s->chip_size, s->chip_size, mem_indexRP); - return s; + return 0; } + +static SysBusDeviceInfo nvram_sysbus_info = { + .qdev.name = "ds1225y", + .qdev.size = sizeof(SysBusNvRamState), + .qdev.vmsd = &vmstate_nvram, + .init = nvram_sysbus_initfn, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("size", SysBusNvRamState, nvram.chip_size, 0x2000), + DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static void nvram_register(void) +{ + sysbus_register_withprop(&nvram_sysbus_info); +} + +device_init(nvram_register) diff --git a/hw/ds1338.c b/hw/ds1338.c index 6f5ae5e..3522af5 100644 --- a/hw/ds1338.c +++ b/hw/ds1338.c @@ -4,7 +4,7 @@ * Copyright (c) 2009 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #include "i2c.h" diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c index 61efb39..30146b9 100644 --- a/hw/dummy_m68k.c +++ b/hw/dummy_m68k.c @@ -3,14 +3,14 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "hw.h" -#include "sysemu.h" #include "boards.h" #include "loader.h" #include "elf.h" +#include "exec-memory.h" #define KERNEL_LOAD_ADDR 0x10000 @@ -22,6 +22,8 @@ static void dummy_m68k_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); int kernel_size; uint64_t elf_entry; target_phys_addr_t entry; @@ -38,8 +40,8 @@ static void dummy_m68k_init(ram_addr_t ram_size, env->vbr = 0; /* RAM at address zero */ - cpu_register_physical_memory(0, ram_size, - qemu_ram_alloc(NULL, "dummy_m68k.ram", ram_size) | IO_MEM_RAM); + memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size); + memory_region_add_subregion(address_space_mem, 0, ram); /* Load kernel. */ if (kernel_filename) { diff --git a/hw/e1000.c b/hw/e1000.c index af101bd..e164d79 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -31,6 +31,7 @@ #include "net/checksum.h" #include "loader.h" #include "sysemu.h" +#include "dma.h" #include "e1000_hw.h" @@ -82,7 +83,8 @@ typedef struct E1000State_st { PCIDevice dev; NICState *nic; NICConf conf; - int mmio_index; + MemoryRegion mmio; + MemoryRegion io; uint32_t mac_reg[0x8000]; uint16_t phy_reg[0x20]; @@ -151,14 +153,6 @@ static const char phy_regcap[0x20] = { }; static void -ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, - pcibus_t size, int type) -{ - DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS - " size=0x%08"FMT_PCIBUS"\n", addr, size); -} - -static void set_interrupt_cause(E1000State *s, int index, uint32_t val) { if (val) @@ -446,7 +440,9 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) return; } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) { // data descriptor - tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8; + if (tp->size == 0) { + tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8; + } tp->cptse = ( txd_lower & E1000_TXD_CMD_TSE ) ? 1 : 0; } else { // legacy descriptor @@ -470,7 +466,9 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) bytes = split_size; if (tp->size + bytes > msh) bytes = msh - tp->size; - cpu_physical_memory_read(addr, tp->data + tp->size, bytes); + + bytes = MIN(sizeof(tp->data) - tp->size, bytes); + pci_dma_read(&s->dev, addr, tp->data + tp->size, bytes); if ((sz = tp->size + bytes) >= hdr && tp->size < hdr) memmove(tp->header, tp->data, hdr); tp->size = sz; @@ -485,7 +483,8 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) // context descriptor TSE is not set, while data descriptor TSE is set DBGOUT(TXERR, "TCP segmentaion Error\n"); } else { - cpu_physical_memory_read(addr, tp->data + tp->size, split_size); + split_size = MIN(sizeof(tp->data) - tp->size, split_size); + pci_dma_read(&s->dev, addr, tp->data + tp->size, split_size); tp->size += split_size; } @@ -501,7 +500,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) } static uint32_t -txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) +txdesc_writeback(E1000State *s, dma_addr_t base, struct e1000_tx_desc *dp) { uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data); @@ -510,15 +509,23 @@ txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) & ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU); dp->upper.data = cpu_to_le32(txd_upper); - cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp), - (void *)&dp->upper, sizeof(dp->upper)); + pci_dma_write(&s->dev, base + ((char *)&dp->upper - (char *)dp), + (void *)&dp->upper, sizeof(dp->upper)); return E1000_ICR_TXDW; } +static uint64_t tx_desc_base(E1000State *s) +{ + uint64_t bah = s->mac_reg[TDBAH]; + uint64_t bal = s->mac_reg[TDBAL] & ~0xf; + + return (bah << 32) + bal; +} + static void start_xmit(E1000State *s) { - target_phys_addr_t base; + dma_addr_t base; struct e1000_tx_desc desc; uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE; @@ -528,16 +535,16 @@ start_xmit(E1000State *s) } while (s->mac_reg[TDH] != s->mac_reg[TDT]) { - base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] + + base = tx_desc_base(s) + sizeof(struct e1000_tx_desc) * s->mac_reg[TDH]; - cpu_physical_memory_read(base, (void *)&desc, sizeof(desc)); + pci_dma_read(&s->dev, base, (void *)&desc, sizeof(desc)); DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH], (void *)(intptr_t)desc.buffer_addr, desc.lower.data, desc.upper.data); process_tx_desc(s, &desc); - cause |= txdesc_writeback(base, &desc); + cause |= txdesc_writeback(s, base, &desc); if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN]) s->mac_reg[TDH] = 0; @@ -614,21 +621,50 @@ e1000_set_link_status(VLANClientState *nc) E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque; uint32_t old_status = s->mac_reg[STATUS]; - if (nc->link_down) + if (nc->link_down) { s->mac_reg[STATUS] &= ~E1000_STATUS_LU; - else + s->phy_reg[PHY_STATUS] &= ~MII_SR_LINK_STATUS; + } else { s->mac_reg[STATUS] |= E1000_STATUS_LU; + s->phy_reg[PHY_STATUS] |= MII_SR_LINK_STATUS; + } if (s->mac_reg[STATUS] != old_status) set_ics(s, 0, E1000_ICR_LSC); } +static bool e1000_has_rxbufs(E1000State *s, size_t total_size) +{ + int bufs; + /* Fast-path short packets */ + if (total_size <= s->rxbuf_size) { + return s->mac_reg[RDH] != s->mac_reg[RDT] || !s->check_rxov; + } + if (s->mac_reg[RDH] < s->mac_reg[RDT]) { + bufs = s->mac_reg[RDT] - s->mac_reg[RDH]; + } else if (s->mac_reg[RDH] > s->mac_reg[RDT] || !s->check_rxov) { + bufs = s->mac_reg[RDLEN] / sizeof(struct e1000_rx_desc) + + s->mac_reg[RDT] - s->mac_reg[RDH]; + } else { + return false; + } + return total_size <= bufs * s->rxbuf_size; +} + static int e1000_can_receive(VLANClientState *nc) { E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque; - return (s->mac_reg[RCTL] & E1000_RCTL_EN); + return (s->mac_reg[RCTL] & E1000_RCTL_EN) && e1000_has_rxbufs(s, 1); +} + +static uint64_t rx_desc_base(E1000State *s) +{ + uint64_t bah = s->mac_reg[RDBAH]; + uint64_t bal = s->mac_reg[RDBAL] & ~0xf; + + return (bah << 32) + bal; } static ssize_t @@ -636,12 +672,15 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) { E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque; struct e1000_rx_desc desc; - target_phys_addr_t base; + dma_addr_t base; unsigned int n, rdt; uint32_t rdh_start; uint16_t vlan_special = 0; uint8_t vlan_status = 0, vlan_offset = 0; uint8_t min_buf[MIN_BUF_SIZE]; + size_t desc_offset; + size_t desc_size; + size_t total_size; if (!(s->mac_reg[RCTL] & E1000_RCTL_EN)) return -1; @@ -654,12 +693,6 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) size = sizeof(min_buf); } - if (size > s->rxbuf_size) { - DBGOUT(RX, "packet too large for buffers (%lu > %d)\n", - (unsigned long)size, s->rxbuf_size); - return -1; - } - if (!receive_filter(s, buf, size)) return size; @@ -672,25 +705,44 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) } rdh_start = s->mac_reg[RDH]; - do { - if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) { + desc_offset = 0; + total_size = size + fcs_len(s); + if (!e1000_has_rxbufs(s, total_size)) { set_ics(s, 0, E1000_ICS_RXO); return -1; + } + do { + desc_size = total_size - desc_offset; + if (desc_size > s->rxbuf_size) { + desc_size = s->rxbuf_size; } - base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] + - sizeof(desc) * s->mac_reg[RDH]; - cpu_physical_memory_read(base, (void *)&desc, sizeof(desc)); + base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH]; + pci_dma_read(&s->dev, base, (void *)&desc, sizeof(desc)); desc.special = vlan_special; desc.status |= (vlan_status | E1000_RXD_STAT_DD); if (desc.buffer_addr) { - cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr), - (void *)(buf + vlan_offset), size); - desc.length = cpu_to_le16(size + fcs_len(s)); - desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM; + if (desc_offset < size) { + size_t copy_size = size - desc_offset; + if (copy_size > s->rxbuf_size) { + copy_size = s->rxbuf_size; + } + pci_dma_write(&s->dev, le64_to_cpu(desc.buffer_addr), + (void *)(buf + desc_offset + vlan_offset), + copy_size); + } + desc_offset += desc_size; + desc.length = cpu_to_le16(desc_size); + if (desc_offset >= total_size) { + desc.status |= E1000_RXD_STAT_EOP | E1000_RXD_STAT_IXSM; + } else { + /* Guest zeroing out status is not a hardware requirement. + Clear EOP in case guest didn't do it. */ + desc.status &= ~E1000_RXD_STAT_EOP; + } } else { // as per intel docs; skip descriptors with null buf addr DBGOUT(RX, "Null RX descriptor!!\n"); } - cpu_physical_memory_write(base, (void *)&desc, sizeof(desc)); + pci_dma_write(&s->dev, base, (void *)&desc, sizeof(desc)); if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) s->mac_reg[RDH] = 0; @@ -702,7 +754,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size) set_ics(s, 0, E1000_ICS_RXO); return -1; } - } while (desc.buffer_addr == 0); + } while (desc_offset < total_size); s->mac_reg[GPRC]++; s->mac_reg[TPR]++; @@ -853,7 +905,8 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = { enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) }; static void -e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) { E1000State *s = opaque; unsigned int index = (addr & 0x1ffff) >> 2; @@ -861,31 +914,15 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) if (index < NWRITEOPS && macreg_writeops[index]) { macreg_writeops[index](s, index, val); } else if (index < NREADOPS && macreg_readops[index]) { - DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val); + DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04"PRIx64"\n", index<<2, val); } else { - DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n", + DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n", index<<2, val); } } -static void -e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - // emulate hw without byte enables: no RMW - e1000_mmio_writel(opaque, addr & ~3, - (val & 0xffff) << (8*(addr & 3))); -} - -static void -e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - // emulate hw without byte enables: no RMW - e1000_mmio_writel(opaque, addr & ~3, - (val & 0xff) << (8*(addr & 3))); -} - -static uint32_t -e1000_mmio_readl(void *opaque, target_phys_addr_t addr) +static uint64_t +e1000_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size) { E1000State *s = opaque; unsigned int index = (addr & 0x1ffff) >> 2; @@ -898,20 +935,39 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr) return 0; } -static uint32_t -e1000_mmio_readb(void *opaque, target_phys_addr_t addr) +static const MemoryRegionOps e1000_mmio_ops = { + .read = e1000_mmio_read, + .write = e1000_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static uint64_t e1000_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - return ((e1000_mmio_readl(opaque, addr & ~3)) >> - (8 * (addr & 3))) & 0xff; + E1000State *s = opaque; + + (void)s; + return 0; } -static uint32_t -e1000_mmio_readw(void *opaque, target_phys_addr_t addr) +static void e1000_io_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - return ((e1000_mmio_readl(opaque, addr & ~3)) >> - (8 * (addr & 3))) & 0xffff; + E1000State *s = opaque; + + (void)s; } +static const MemoryRegionOps e1000_io_ops = { + .read = e1000_io_read, + .write = e1000_io_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static bool is_version_1(void *opaque, int version_id) { return version_id == 1; @@ -1031,36 +1087,22 @@ static const uint32_t mac_reg_init[] = { /* PCI interface */ -static CPUWriteMemoryFunc * const e1000_mmio_write[] = { - e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel -}; - -static CPUReadMemoryFunc * const e1000_mmio_read[] = { - e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl -}; - static void -e1000_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +e1000_mmio_setup(E1000State *d) { - E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); int i; const uint32_t excluded_regs[] = { E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS, E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE }; - - DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", - addr, size); - - cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index); - qemu_register_coalesced_mmio(addr, excluded_regs[0]); - + memory_region_init_io(&d->mmio, &e1000_mmio_ops, d, "e1000-mmio", + PNPMMIO_SIZE); + memory_region_add_coalescing(&d->mmio, 0, excluded_regs[0]); for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++) - qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4, - excluded_regs[i + 1] - - excluded_regs[i] - 4); + memory_region_add_coalescing(&d->mmio, excluded_regs[i] + 4, + excluded_regs[i+1] - excluded_regs[i] - 4); + memory_region_init_io(&d->io, &e1000_io_ops, d, "e1000-io", IOPORT_SIZE); } static void @@ -1076,7 +1118,8 @@ pci_e1000_uninit(PCIDevice *dev) { E1000State *d = DO_UPCAST(E1000State, dev, dev); - cpu_unregister_io_memory(d->mmio_index); + memory_region_destroy(&d->mmio); + memory_region_destroy(&d->io); qemu_del_vlan_client(&d->nic->nc); return 0; } @@ -1112,26 +1155,16 @@ static int pci_e1000_init(PCIDevice *pci_dev) pci_conf = d->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, E1000_DEVID); - /* TODO: we have no capabilities, so why is this bit set? */ - pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST); - pci_conf[PCI_REVISION_ID] = 0x03; - pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET); /* TODO: RST# value should be 0, PCI spec 6.2.4 */ pci_conf[PCI_CACHE_LINE_SIZE] = 0x10; - /* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */ - pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 + pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */ - d->mmio_index = cpu_register_io_memory(e1000_mmio_read, - e1000_mmio_write, d, DEVICE_LITTLE_ENDIAN); + e1000_mmio_setup(d); - pci_register_bar(&d->dev, 0, PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); - pci_register_bar(&d->dev, 1, IOPORT_SIZE, - PCI_BASE_ADDRESS_SPACE_IO, ioport_map); + pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io); memmove(d->eeprom_data, e1000_eeprom_template, sizeof e1000_eeprom_template); @@ -1168,7 +1201,11 @@ static PCIDeviceInfo e1000_info = { .qdev.vmsd = &vmstate_e1000, .init = pci_e1000_init, .exit = pci_e1000_uninit, - .romfile = "pxe-e1000.bin", + .romfile = "pxe-e1000.rom", + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = E1000_DEVID, + .revision = 0x03, + .class_id = PCI_CLASS_NETWORK_ETHERNET, .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(E1000State, conf), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/e1000_hw.h b/hw/e1000_hw.h index 9bd8a4b..2e341ac 100644 --- a/hw/e1000_hw.h +++ b/hw/e1000_hw.h @@ -349,6 +349,23 @@ #define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ #define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */ +/* PHY Status Register */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + /* Interrupt Cause Read */ #define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ #define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ diff --git a/hw/eepro100.c b/hw/eepro100.c index edf48f6..29ec5b4 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -1,7 +1,7 @@ /* * QEMU i8255x (PRO100) emulation * - * Copyright (C) 2006-2010 Stefan Weil + * Copyright (C) 2006-2011 Stefan Weil * * Portions of the code are copies from grub / etherboot eepro100.c * and linux e100.c. @@ -20,11 +20,10 @@ * along with this program. If not, see . * * Tested features (i82559): - * PXE boot (i386) ok + * PXE boot (i386 guest, i386 / mips / mipsel / ppc host) ok * Linux networking (i386) ok * * Untested: - * non-i386 platforms * Windows networking * * References: @@ -47,6 +46,16 @@ #include "net.h" #include "eeprom93xx.h" #include "sysemu.h" +#include "dma.h" + +/* QEMU sends frames smaller than 60 bytes to ethernet nics. + * Such frames are rejected by real nics and their emulations. + * To avoid this behaviour, other nic emulations pad received + * frames. The following definition enables this padding for + * eepro100, too. We keep the define around in case it might + * become useful the future if the core networking is ever + * changed to pad short packets itself. */ +#define CONFIG_PAD_RECEIVED_FRAMES #define KiB 1024 @@ -121,8 +130,6 @@ typedef struct { PCIDeviceInfo pci; uint32_t device; - uint16_t device_id; - uint8_t revision; uint8_t stats_size; bool has_extended_tcb_support; bool power_management; @@ -130,7 +137,7 @@ typedef struct { /* Offsets to the various registers. All accesses need not be longword aligned. */ -enum speedo_offsets { +typedef enum { SCBStatus = 0, /* Status Word. */ SCBAck = 1, SCBCmd = 2, /* Rx/Command Unit command and status. */ @@ -145,7 +152,7 @@ enum speedo_offsets { SCBpmdr = 27, /* Power Management Driver. */ SCBgctrl = 28, /* General Control. */ SCBgstat = 29, /* General Status. */ -}; +} E100RegisterOffset; /* A speedo3 transmit buffer descriptor with two buffers... */ typedef struct { @@ -173,7 +180,7 @@ typedef struct { uint32_t rx_buf_addr; /* void * */ uint16_t count; uint16_t size; - char packet[MAX_ETH_FRAME_SIZE + 4]; + /* Ethernet frame data follows. */ } eepro100_rx_t; typedef enum { @@ -222,17 +229,17 @@ typedef struct { PCIDevice dev; /* Hash register (multicast mask array, multiple individual addresses). */ uint8_t mult[8]; - int mmio_index; + MemoryRegion mmio_bar; + MemoryRegion io_bar; + MemoryRegion flash_bar; NICState *nic; NICConf conf; uint8_t scb_stat; /* SCB stat/ack byte */ uint8_t int_stat; /* PCI interrupt status */ /* region must not be saved by nic_save. */ - uint32_t region[3]; /* PCI region addresses */ uint16_t mdimem[32]; eeprom_t *eeprom; uint32_t device; /* device variant */ - uint32_t pointer; /* (cu_base + cu_offset) address the next command block in the command block list. */ uint32_t cu_base; /* CU base address */ uint32_t cu_offset; /* CU address offset */ @@ -249,11 +256,13 @@ typedef struct { /* Statistical counters. Also used for wake-up packet (i82559). */ eepro100_stats_t statistics; + /* Data in mem is always in the byte order of the controller (le). + * It must be dword aligned to allow direct access to 32 bit values. */ + uint8_t mem[PCI_MEM_SIZE] __attribute__((aligned(8)));; + /* Configuration bytes. */ uint8_t configuration[22]; - /* Data in mem is always in the byte order of the controller (le). */ - uint8_t mem[PCI_MEM_SIZE]; /* vmstate for each particular nic */ VMStateDescription *vmstate; @@ -307,13 +316,6 @@ static const uint16_t eepro100_mdi_mask[] = { 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; -/* XXX: optimize */ -static void stl_le_phys(target_phys_addr_t addr, uint32_t val) -{ - val = cpu_to_le32(val); - cpu_physical_memory_write(addr, (const uint8_t *)&val, sizeof(val)); -} - #define POLYNOMIAL 0x04c11db6 /* From FreeBSD */ @@ -339,6 +341,36 @@ static unsigned compute_mcast_idx(const uint8_t * ep) return (crc & BITS(7, 2)) >> 2; } +/* Read a 16 bit control/status (CSR) register. */ +static uint16_t e100_read_reg2(EEPRO100State *s, E100RegisterOffset addr) +{ + assert(!((uintptr_t)&s->mem[addr] & 1)); + return le16_to_cpup((uint16_t *)&s->mem[addr]); +} + +/* Read a 32 bit control/status (CSR) register. */ +static uint32_t e100_read_reg4(EEPRO100State *s, E100RegisterOffset addr) +{ + assert(!((uintptr_t)&s->mem[addr] & 3)); + return le32_to_cpup((uint32_t *)&s->mem[addr]); +} + +/* Write a 16 bit control/status (CSR) register. */ +static void e100_write_reg2(EEPRO100State *s, E100RegisterOffset addr, + uint16_t val) +{ + assert(!((uintptr_t)&s->mem[addr] & 1)); + cpu_to_le16w((uint16_t *)&s->mem[addr], val); +} + +/* Read a 32 bit control/status (CSR) register. */ +static void e100_write_reg4(EEPRO100State *s, E100RegisterOffset addr, + uint32_t val) +{ + assert(!((uintptr_t)&s->mem[addr] & 3)); + cpu_to_le32w((uint32_t *)&s->mem[addr], val); +} + #if defined(DEBUG_EEPRO100) static const char *nic_dump(const uint8_t * buf, unsigned size) { @@ -462,16 +494,9 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device) TRACE(OTHER, logout("%p\n", s)); - /* PCI Vendor ID */ - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - /* PCI Device ID */ - pci_config_set_device_id(pci_conf, e100_device->device_id); /* PCI Status */ pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM | PCI_STATUS_FAST_BACK); - /* PCI Revision ID */ - pci_config_set_revision(pci_conf, e100_device->revision); - pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET); /* PCI Latency Timer */ pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x20); /* latency timer = 32 clocks */ /* Capability Pointer is set by PCI framework. */ @@ -499,12 +524,7 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device) case i82559ER: case i82562: case i82801: - break; case i82559C: -#if EEPROM_SIZE > 0 - pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_INTEL); - pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0040); -#endif break; default: logout("Device %X is undefined!\n", device); @@ -590,8 +610,7 @@ static void nic_selective_reset(EEPRO100State * s) TRACE(EEPROM, logout("checksum=0x%04x\n", eeprom_contents[EEPROM_SIZE - 1])); memset(s->mem, 0, sizeof(s->mem)); - uint32_t val = BIT(21); - memcpy(&s->mem[SCBCtrlMDI], &val, sizeof(val)); + e100_write_reg4(s, SCBCtrlMDI, BIT(21)); assert(sizeof(s->mdimem) == sizeof(eepro100_mdi_default)); memcpy(&s->mdimem[0], &eepro100_mdi_default[0], sizeof(s->mdimem)); @@ -694,22 +713,26 @@ static void dump_statistics(EEPRO100State * s) * values which really matter. * Number of data should check configuration!!! */ - cpu_physical_memory_write(s->statsaddr, - (uint8_t *) & s->statistics, s->stats_size); - stl_le_phys(s->statsaddr + 0, s->statistics.tx_good_frames); - stl_le_phys(s->statsaddr + 36, s->statistics.rx_good_frames); - stl_le_phys(s->statsaddr + 48, s->statistics.rx_resource_errors); - stl_le_phys(s->statsaddr + 60, s->statistics.rx_short_frame_errors); + pci_dma_write(&s->dev, s->statsaddr, + (uint8_t *) &s->statistics, s->stats_size); + stl_le_pci_dma(&s->dev, s->statsaddr + 0, + s->statistics.tx_good_frames); + stl_le_pci_dma(&s->dev, s->statsaddr + 36, + s->statistics.rx_good_frames); + stl_le_pci_dma(&s->dev, s->statsaddr + 48, + s->statistics.rx_resource_errors); + stl_le_pci_dma(&s->dev, s->statsaddr + 60, + s->statistics.rx_short_frame_errors); #if 0 - stw_le_phys(s->statsaddr + 76, s->statistics.xmt_tco_frames); - stw_le_phys(s->statsaddr + 78, s->statistics.rcv_tco_frames); + stw_le_pci_dma(&s->dev, s->statsaddr + 76, s->statistics.xmt_tco_frames); + stw_le_pci_dma(&s->dev, s->statsaddr + 78, s->statistics.rcv_tco_frames); missing("CU dump statistical counters"); #endif } static void read_cb(EEPRO100State *s) { - cpu_physical_memory_read(s->cb_address, (uint8_t *) &s->tx, sizeof(s->tx)); + pci_dma_read(&s->dev, s->cb_address, (uint8_t *) &s->tx, sizeof(s->tx)); s->tx.status = le16_to_cpu(s->tx.status); s->tx.command = le16_to_cpu(s->tx.command); s->tx.link = le32_to_cpu(s->tx.link); @@ -739,18 +762,17 @@ static void tx_command(EEPRO100State *s) } assert(tcb_bytes <= sizeof(buf)); while (size < tcb_bytes) { - uint32_t tx_buffer_address = ldl_phys(tbd_address); - uint16_t tx_buffer_size = lduw_phys(tbd_address + 4); + uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address); + uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4); #if 0 - uint16_t tx_buffer_el = lduw_phys(tbd_address + 6); + uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6); #endif tbd_address += 8; TRACE(RXTX, logout ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n", tx_buffer_address, tx_buffer_size)); tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size); - cpu_physical_memory_read(tx_buffer_address, &buf[size], - tx_buffer_size); + pci_dma_read(&s->dev, tx_buffer_address, &buf[size], tx_buffer_size); size += tx_buffer_size; } if (tbd_array == 0xffffffff) { @@ -761,16 +783,19 @@ static void tx_command(EEPRO100State *s) if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) { /* Extended Flexible TCB. */ for (; tbd_count < 2; tbd_count++) { - uint32_t tx_buffer_address = ldl_phys(tbd_address); - uint16_t tx_buffer_size = lduw_phys(tbd_address + 4); - uint16_t tx_buffer_el = lduw_phys(tbd_address + 6); + uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, + tbd_address); + uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, + tbd_address + 4); + uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, + tbd_address + 6); tbd_address += 8; TRACE(RXTX, logout ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n", tx_buffer_address, tx_buffer_size)); tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size); - cpu_physical_memory_read(tx_buffer_address, &buf[size], - tx_buffer_size); + pci_dma_read(&s->dev, tx_buffer_address, + &buf[size], tx_buffer_size); size += tx_buffer_size; if (tx_buffer_el & 1) { break; @@ -779,16 +804,16 @@ static void tx_command(EEPRO100State *s) } tbd_address = tbd_array; for (; tbd_count < s->tx.tbd_count; tbd_count++) { - uint32_t tx_buffer_address = ldl_phys(tbd_address); - uint16_t tx_buffer_size = lduw_phys(tbd_address + 4); - uint16_t tx_buffer_el = lduw_phys(tbd_address + 6); + uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address); + uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4); + uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6); tbd_address += 8; TRACE(RXTX, logout ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n", tx_buffer_address, tx_buffer_size)); tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size); - cpu_physical_memory_read(tx_buffer_address, &buf[size], - tx_buffer_size); + pci_dma_read(&s->dev, tx_buffer_address, + &buf[size], tx_buffer_size); size += tx_buffer_size; if (tx_buffer_el & 1) { break; @@ -813,7 +838,7 @@ static void set_multicast_list(EEPRO100State *s) TRACE(OTHER, logout("multicast list, multicast count = %u\n", multicast_count)); for (i = 0; i < multicast_count; i += 6) { uint8_t multicast_addr[6]; - cpu_physical_memory_read(s->cb_address + 10 + i, multicast_addr, 6); + pci_dma_read(&s->dev, s->cb_address + 10 + i, multicast_addr, 6); TRACE(OTHER, logout("multicast entry %s\n", nic_dump(multicast_addr, 6))); unsigned mcast_idx = compute_mcast_idx(multicast_addr); assert(mcast_idx < 64); @@ -847,12 +872,12 @@ static void action_command(EEPRO100State *s) /* Do nothing. */ break; case CmdIASetup: - cpu_physical_memory_read(s->cb_address + 8, &s->conf.macaddr.a[0], 6); + pci_dma_read(&s->dev, s->cb_address + 8, &s->conf.macaddr.a[0], 6); TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6))); break; case CmdConfigure: - cpu_physical_memory_read(s->cb_address + 8, &s->configuration[0], - sizeof(s->configuration)); + pci_dma_read(&s->dev, s->cb_address + 8, + &s->configuration[0], sizeof(s->configuration)); TRACE(OTHER, logout("configuration: %s\n", nic_dump(&s->configuration[0], 16))); TRACE(OTHER, logout("configuration: %s\n", @@ -889,7 +914,8 @@ static void action_command(EEPRO100State *s) break; } /* Write new status. */ - stw_phys(s->cb_address, s->tx.status | ok_status | STATUS_C); + stw_le_pci_dma(&s->dev, s->cb_address, + s->tx.status | ok_status | STATUS_C); if (bit_i) { /* CU completed action. */ eepro100_cx_interrupt(s); @@ -928,7 +954,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val) logout("unexpected CU state is %u\n", cu_state); } set_cu_state(s, cu_active); - s->cu_offset = s->pointer; + s->cu_offset = e100_read_reg4(s, SCBPointer); action_command(s); break; case CU_RESUME: @@ -949,25 +975,33 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val) break; case CU_STATSADDR: /* Load dump counters address. */ - s->statsaddr = s->pointer; - TRACE(OTHER, logout("val=0x%02x (status address)\n", val)); + s->statsaddr = e100_read_reg4(s, SCBPointer); + TRACE(OTHER, logout("val=0x%02x (dump counters address)\n", val)); + if (s->statsaddr & 3) { + /* Memory must be Dword aligned. */ + logout("unaligned dump counters address\n"); + /* Handling of misaligned addresses is undefined. + * Here we align the address by ignoring the lower bits. */ + /* TODO: Test unaligned dump counter address on real hardware. */ + s->statsaddr &= ~3; + } break; case CU_SHOWSTATS: /* Dump statistical counters. */ TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val)); dump_statistics(s); - stl_le_phys(s->statsaddr + s->stats_size, 0xa005); + stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa005); break; case CU_CMD_BASE: /* Load CU base. */ TRACE(OTHER, logout("val=0x%02x (CU base address)\n", val)); - s->cu_base = s->pointer; + s->cu_base = e100_read_reg4(s, SCBPointer); break; case CU_DUMPSTATS: /* Dump and reset statistical counters. */ TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val)); dump_statistics(s); - stl_le_phys(s->statsaddr + s->stats_size, 0xa007); + stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa007); memset(&s->statistics, 0, sizeof(s->statistics)); break; case CU_SRESUME: @@ -994,7 +1028,7 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val) #endif } set_ru_state(s, ru_ready); - s->ru_offset = s->pointer; + s->ru_offset = e100_read_reg4(s, SCBPointer); TRACE(OTHER, logout("val=0x%02x (rx start)\n", val)); break; case RX_RESUME: @@ -1018,7 +1052,7 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val) case RX_ADDR_LOAD: /* Load RU base. */ TRACE(OTHER, logout("val=0x%02x (RU base address)\n", val)); - s->ru_base = s->pointer; + s->ru_base = e100_read_reg4(s, SCBPointer); break; default: logout("val=0x%02x (undefined RU command)\n", val); @@ -1050,8 +1084,7 @@ static void eepro100_write_command(EEPRO100State * s, uint8_t val) static uint16_t eepro100_read_eeprom(EEPRO100State * s) { - uint16_t val; - memcpy(&val, &s->mem[SCBeeprom], sizeof(val)); + uint16_t val = e100_read_reg2(s, SCBeeprom); if (eeprom93xx_read(s->eeprom)) { val |= EEPROM_DO; } else { @@ -1065,7 +1098,7 @@ static void eepro100_write_eeprom(eeprom_t * eeprom, uint8_t val) { TRACE(EEPROM, logout("val=0x%02x\n", val)); - /* mask unwriteable bits */ + /* mask unwritable bits */ #if 0 val = SET_MASKED(val, 0x31, eeprom->value); #endif @@ -1076,12 +1109,6 @@ static void eepro100_write_eeprom(eeprom_t * eeprom, uint8_t val) eeprom93xx_write(eeprom, eecs, eesk, eedi); } -static void eepro100_write_pointer(EEPRO100State * s, uint32_t val) -{ - s->pointer = le32_to_cpu(val); - TRACE(OTHER, logout("val=0x%08x\n", val)); -} - /***************************************************************************** * * MDI emulation. @@ -1121,8 +1148,7 @@ static const char *reg2name(uint8_t reg) static uint32_t eepro100_read_mdi(EEPRO100State * s) { - uint32_t val; - memcpy(&val, &s->mem[0x10], sizeof(val)); + uint32_t val = e100_read_reg4(s, SCBCtrlMDI); #ifdef DEBUG_EEPRO100 uint8_t raiseint = (val & BIT(29)) >> 29; @@ -1139,8 +1165,9 @@ static uint32_t eepro100_read_mdi(EEPRO100State * s) return val; } -static void eepro100_write_mdi(EEPRO100State * s, uint32_t val) +static void eepro100_write_mdi(EEPRO100State *s) { + uint32_t val = e100_read_reg4(s, SCBCtrlMDI); uint8_t raiseint = (val & BIT(29)) >> 29; uint8_t opcode = (val & BITS(27, 26)) >> 26; uint8_t phy = (val & BITS(25, 21)) >> 21; @@ -1231,7 +1258,7 @@ static void eepro100_write_mdi(EEPRO100State * s, uint32_t val) } } val = (val & 0xffff0000) + data; - memcpy(&s->mem[0x10], &val, sizeof(val)); + e100_write_reg4(s, SCBCtrlMDI, val); } /***************************************************************************** @@ -1256,9 +1283,9 @@ static uint32_t eepro100_read_port(EEPRO100State * s) return 0; } -static void eepro100_write_port(EEPRO100State * s, uint32_t val) +static void eepro100_write_port(EEPRO100State *s) { - val = le32_to_cpu(val); + uint32_t val = e100_read_reg4(s, SCBPort); uint32_t address = (val & ~PORT_SELECTION_MASK); uint8_t selection = (val & PORT_SELECTION_MASK); switch (selection) { @@ -1268,10 +1295,10 @@ static void eepro100_write_port(EEPRO100State * s, uint32_t val) case PORT_SELFTEST: TRACE(OTHER, logout("selftest address=0x%08x\n", address)); eepro100_selftest_t data; - cpu_physical_memory_read(address, (uint8_t *) & data, sizeof(data)); + pci_dma_read(&s->dev, address, (uint8_t *) &data, sizeof(data)); data.st_sign = 0xffffffff; data.st_result = 0; - cpu_physical_memory_write(address, (uint8_t *) & data, sizeof(data)); + pci_dma_write(&s->dev, address, (uint8_t *) &data, sizeof(data)); break; case PORT_SELECTIVE_RESET: TRACE(OTHER, logout("selective reset, selftest address=0x%08x\n", address)); @@ -1293,7 +1320,7 @@ static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr) { uint8_t val = 0; if (addr <= sizeof(s->mem) - sizeof(val)) { - memcpy(&val, &s->mem[addr], sizeof(val)); + val = s->mem[addr]; } switch (addr) { @@ -1316,10 +1343,20 @@ static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr) case SCBeeprom: val = eepro100_read_eeprom(s); break; + case SCBCtrlMDI: + case SCBCtrlMDI + 1: + case SCBCtrlMDI + 2: + case SCBCtrlMDI + 3: + val = (uint8_t)(eepro100_read_mdi(s) >> (8 * (addr & 3))); + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); + break; case SCBpmdr: /* Power Management Driver Register */ val = 0; TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); break; + case SCBgctrl: /* General Control Register */ + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); + break; case SCBgstat: /* General Status Register */ /* 100 Mbps full duplex, valid link */ val = 0x07; @@ -1336,7 +1373,7 @@ static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr) { uint16_t val = 0; if (addr <= sizeof(s->mem) - sizeof(val)) { - memcpy(&val, &s->mem[addr], sizeof(val)); + val = e100_read_reg2(s, addr); } switch (addr) { @@ -1348,6 +1385,11 @@ static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr) val = eepro100_read_eeprom(s); TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); break; + case SCBCtrlMDI: + case SCBCtrlMDI + 2: + val = (uint16_t)(eepro100_read_mdi(s) >> (8 * (addr & 3))); + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); + break; default: logout("addr=%s val=0x%04x\n", regname(addr), val); missing("unknown word read"); @@ -1359,7 +1401,7 @@ static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr) { uint32_t val = 0; if (addr <= sizeof(s->mem) - sizeof(val)) { - memcpy(&val, &s->mem[addr], sizeof(val)); + val = e100_read_reg4(s, addr); } switch (addr) { @@ -1367,15 +1409,16 @@ static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr) TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); break; case SCBPointer: -#if 0 - val = eepro100_read_pointer(s); -#endif TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); break; case SCBPort: val = eepro100_read_port(s); TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); break; + case SCBflash: + val = eepro100_read_eeprom(s); + TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); + break; case SCBCtrlMDI: val = eepro100_read_mdi(s); break; @@ -1390,27 +1433,43 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val) { /* SCBStatus is readonly. */ if (addr > SCBStatus && addr <= sizeof(s->mem) - sizeof(val)) { - memcpy(&s->mem[addr], &val, sizeof(val)); + s->mem[addr] = val; } - TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); - switch (addr) { case SCBStatus: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); break; case SCBAck: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); eepro100_acknowledge(s); break; case SCBCmd: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); eepro100_write_command(s, val); break; case SCBIntmask: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); if (val & BIT(1)) { eepro100_swi_interrupt(s); } eepro100_interrupt(s, 0); break; + case SCBPointer: + case SCBPointer + 1: + case SCBPointer + 2: + case SCBPointer + 3: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); + break; + case SCBPort: + case SCBPort + 1: + case SCBPort + 2: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); + break; case SCBPort + 3: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); + eepro100_write_port(s); + break; case SCBFlow: /* does not exist on 82557 */ case SCBFlow + 1: case SCBFlow + 2: @@ -1418,8 +1477,18 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val) TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); break; case SCBeeprom: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); eepro100_write_eeprom(s->eeprom, val); break; + case SCBCtrlMDI: + case SCBCtrlMDI + 1: + case SCBCtrlMDI + 2: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); + break; + case SCBCtrlMDI + 3: + TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val)); + eepro100_write_mdi(s); + break; default: logout("addr=%s val=0x%02x\n", regname(addr), val); missing("unknown byte write"); @@ -1430,23 +1499,42 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val) { /* SCBStatus is readonly. */ if (addr > SCBStatus && addr <= sizeof(s->mem) - sizeof(val)) { - memcpy(&s->mem[addr], &val, sizeof(val)); + e100_write_reg2(s, addr, val); } - TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); - switch (addr) { case SCBStatus: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); s->mem[SCBAck] = (val >> 8); eepro100_acknowledge(s); break; case SCBCmd: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); eepro100_write_command(s, val); eepro100_write1(s, SCBIntmask, val >> 8); break; + case SCBPointer: + case SCBPointer + 2: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); + break; + case SCBPort: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); + break; + case SCBPort + 2: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); + eepro100_write_port(s); + break; case SCBeeprom: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); eepro100_write_eeprom(s->eeprom, val); break; + case SCBCtrlMDI: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); + break; + case SCBCtrlMDI + 2: + TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val)); + eepro100_write_mdi(s); + break; default: logout("addr=%s val=0x%04x\n", regname(addr), val); missing("unknown word write"); @@ -1456,19 +1544,25 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val) static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val) { if (addr <= sizeof(s->mem) - sizeof(val)) { - memcpy(&s->mem[addr], &val, sizeof(val)); + e100_write_reg4(s, addr, val); } switch (addr) { case SCBPointer: - eepro100_write_pointer(s, val); + TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); break; case SCBPort: TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); - eepro100_write_port(s, val); + eepro100_write_port(s); + break; + case SCBflash: + TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); + val = val >> 16; + eepro100_write_eeprom(s->eeprom, val); break; case SCBCtrlMDI: - eepro100_write_mdi(s, val); + TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val)); + eepro100_write_mdi(s); break; default: logout("addr=%s val=0x%08x\n", regname(addr), val); @@ -1476,165 +1570,38 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val) } } -/***************************************************************************** - * - * Port mapped I/O. - * - ****************************************************************************/ - -static uint32_t ioport_read1(void *opaque, uint32_t addr) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read1(s, addr - s->region[1]); -} - -static uint32_t ioport_read2(void *opaque, uint32_t addr) -{ - EEPRO100State *s = opaque; - return eepro100_read2(s, addr - s->region[1]); -} - -static uint32_t ioport_read4(void *opaque, uint32_t addr) -{ - EEPRO100State *s = opaque; - return eepro100_read4(s, addr - s->region[1]); -} - -static void ioport_write1(void *opaque, uint32_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write1(s, addr - s->region[1], val); -} - -static void ioport_write2(void *opaque, uint32_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; - eepro100_write2(s, addr - s->region[1], val); -} - -static void ioport_write4(void *opaque, uint32_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; - eepro100_write4(s, addr - s->region[1], val); -} - -/***********************************************************/ -/* PCI EEPRO100 definitions */ - -static void pci_map(PCIDevice * pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); - - TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", " - "size=0x%08"FMT_PCIBUS", type=%d\n", - region_num, addr, size, type)); - - assert(region_num == 1); - register_ioport_write(addr, size, 1, ioport_write1, s); - register_ioport_read(addr, size, 1, ioport_read1, s); - register_ioport_write(addr, size, 2, ioport_write2, s); - register_ioport_read(addr, size, 2, ioport_read2, s); - register_ioport_write(addr, size, 4, ioport_write4, s); - register_ioport_read(addr, size, 4, ioport_read4, s); - - s->region[region_num] = addr; -} - -/***************************************************************************** - * - * Memory mapped I/O. - * - ****************************************************************************/ - -static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write1(s, addr, val); -} - -static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) +static uint64_t eepro100_read(void *opaque, target_phys_addr_t addr, + unsigned size) { EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write2(s, addr, val); -} - -static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s val=0x%02x\n", regname(addr), val); -#endif - eepro100_write4(s, addr, val); -} -static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read1(s, addr); + switch (size) { + case 1: return eepro100_read1(s, addr); + case 2: return eepro100_read2(s, addr); + case 4: return eepro100_read4(s, addr); + default: abort(); + } } -static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr) +static void eepro100_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read2(s, addr); -} -static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr) -{ - EEPRO100State *s = opaque; -#if 0 - logout("addr=%s\n", regname(addr)); -#endif - return eepro100_read4(s, addr); + switch (size) { + case 1: return eepro100_write1(s, addr, data); + case 2: return eepro100_write2(s, addr, data); + case 4: return eepro100_write4(s, addr, data); + default: abort(); + } } -static CPUWriteMemoryFunc * const pci_mmio_write[] = { - pci_mmio_writeb, - pci_mmio_writew, - pci_mmio_writel -}; - -static CPUReadMemoryFunc * const pci_mmio_read[] = { - pci_mmio_readb, - pci_mmio_readw, - pci_mmio_readl +static const MemoryRegionOps eepro100_ops = { + .read = eepro100_read, + .write = eepro100_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static void pci_mmio_map(PCIDevice * pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); - - TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", " - "size=0x%08"FMT_PCIBUS", type=%d\n", - region_num, addr, size, type)); - - assert(region_num == 0 || region_num == 2); - - /* Map control / status registers and flash. */ - cpu_register_physical_memory(addr, size, s->mmio_index); - s->region[region_num] = addr; -} - static int nic_can_receive(VLANClientState *nc) { EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque; @@ -1653,19 +1620,32 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size */ EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque; uint16_t rfd_status = 0xa000; +#if defined(CONFIG_PAD_RECEIVED_FRAMES) + uint8_t min_buf[60]; +#endif static const uint8_t broadcast_macaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +#if defined(CONFIG_PAD_RECEIVED_FRAMES) + /* Pad to minimum Ethernet frame length */ + if (size < sizeof(min_buf)) { + memcpy(min_buf, buf, size); + memset(&min_buf[size], 0, sizeof(min_buf) - size); + buf = min_buf; + size = sizeof(min_buf); + } +#endif + if (s->configuration[8] & 0x80) { /* CSMA is disabled. */ logout("%p received while CSMA is disabled\n", s); return -1; +#if !defined(CONFIG_PAD_RECEIVED_FRAMES) } else if (size < 64 && (s->configuration[7] & BIT(0))) { /* Short frame and configuration byte 7/0 (discard short receive) set: * Short frame is discarded */ logout("%p received short frame (%zu byte)\n", s, size); s->statistics.rx_short_frame_errors++; -#if 0 return -1; #endif } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & BIT(3))) { @@ -1734,8 +1714,8 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size } /* !!! */ eepro100_rx_t rx; - cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx, - offsetof(eepro100_rx_t, packet)); + pci_dma_read(&s->dev, s->ru_base + s->ru_offset, + (uint8_t *) &rx, sizeof(eepro100_rx_t)); uint16_t rfd_command = le16_to_cpu(rx.command); uint16_t rfd_size = le16_to_cpu(rx.size); @@ -1744,14 +1724,17 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size "(%zu bytes); data truncated\n", rfd_size, size); size = rfd_size; } +#if !defined(CONFIG_PAD_RECEIVED_FRAMES) if (size < 64) { rfd_status |= 0x0080; } +#endif TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n", rfd_command, rx.link, rx.rx_buf_addr, rfd_size)); - stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status), - rfd_status); - stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size); + stw_le_pci_dma(&s->dev, s->ru_base + s->ru_offset + + offsetof(eepro100_rx_t, status), rfd_status); + stw_le_pci_dma(&s->dev, s->ru_base + s->ru_offset + + offsetof(eepro100_rx_t, count), size); /* Early receive interrupt not supported. */ #if 0 eepro100_er_interrupt(s); @@ -1765,8 +1748,8 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size #if 0 assert(!(s->configuration[17] & BIT(0))); #endif - cpu_physical_memory_write(s->ru_base + s->ru_offset + - offsetof(eepro100_rx_t, packet), buf, size); + pci_dma_write(&s->dev, s->ru_base + s->ru_offset + + sizeof(eepro100_rx_t), buf, size); s->statistics.rx_good_frames++; eepro100_fr_interrupt(s); s->ru_offset = le32_to_cpu(rx.link); @@ -1801,7 +1784,6 @@ static const VMStateDescription vmstate_eepro100 = { /* The eeprom should be saved and restored by its own routines. */ VMSTATE_UINT32(device, EEPRO100State), /* TODO check device. */ - VMSTATE_UINT32(pointer, EEPRO100State), VMSTATE_UINT32(cu_base, EEPRO100State), VMSTATE_UINT32(cu_offset, EEPRO100State), VMSTATE_UINT32(ru_base, EEPRO100State), @@ -1846,7 +1828,9 @@ static int pci_nic_uninit(PCIDevice *pci_dev) { EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); - cpu_unregister_io_memory(s->mmio_index); + memory_region_destroy(&s->mmio_bar); + memory_region_destroy(&s->io_bar); + memory_region_destroy(&s->flash_bar); vmstate_unregister(&pci_dev->qdev, s->vmstate, s); eeprom93xx_free(&pci_dev->qdev, s->eeprom); qemu_del_vlan_client(&s->nic->nc); @@ -1878,21 +1862,19 @@ static int e100_nic_init(PCIDevice *pci_dev) s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE); /* Handler for memory-mapped I/O */ - s->mmio_index = - cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s, - DEVICE_NATIVE_ENDIAN); - - pci_register_bar(&s->dev, 0, PCI_MEM_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY | - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_mmio_map); - pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO, - pci_map); - pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY, - pci_mmio_map); + memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio", + PCI_MEM_SIZE); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio_bar); + memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io", + PCI_IO_SIZE); + pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); + /* FIXME: flash aliases to mmio?! */ + memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash", + PCI_FLASH_SIZE); + pci_register_bar(&s->dev, 2, 0, &s->flash_bar); qemu_macaddr_default_if_unset(&s->conf.macaddr); logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6)); - assert(s->region[1] == 0); nic_reset(s); @@ -1904,7 +1886,7 @@ static int e100_nic_init(PCIDevice *pci_dev) qemu_register_reset(nic_reset, s); - s->vmstate = qemu_malloc(sizeof(vmstate_eepro100)); + s->vmstate = g_malloc(sizeof(vmstate_eepro100)); memcpy(s->vmstate, &vmstate_eepro100, sizeof(vmstate_eepro100)); s->vmstate->name = s->nic->nc.model; vmstate_register(&pci_dev->qdev, -1, s->vmstate, s); @@ -1920,9 +1902,9 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.desc = "Intel i82550 Ethernet", .device = i82550, /* TODO: check device id. */ - .device_id = PCI_DEVICE_ID_INTEL_82551IT, + .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT, /* Revision ID: 0x0c, 0x0d, 0x0e. */ - .revision = 0x0e, + .pci.revision = 0x0e, /* TODO: check size of statistical counters. */ .stats_size = 80, /* TODO: check extended tcb support. */ @@ -1932,9 +1914,9 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82551", .pci.qdev.desc = "Intel i82551 Ethernet", .device = i82551, - .device_id = PCI_DEVICE_ID_INTEL_82551IT, + .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT, /* Revision ID: 0x0f, 0x10. */ - .revision = 0x0f, + .pci.revision = 0x0f, /* TODO: check size of statistical counters. */ .stats_size = 80, .has_extended_tcb_support = true, @@ -1943,29 +1925,29 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82557a", .pci.qdev.desc = "Intel i82557A Ethernet", .device = i82557A, - .device_id = PCI_DEVICE_ID_INTEL_82557, - .revision = 0x01, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.revision = 0x01, .power_management = false, },{ .pci.qdev.name = "i82557b", .pci.qdev.desc = "Intel i82557B Ethernet", .device = i82557B, - .device_id = PCI_DEVICE_ID_INTEL_82557, - .revision = 0x02, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.revision = 0x02, .power_management = false, },{ .pci.qdev.name = "i82557c", .pci.qdev.desc = "Intel i82557C Ethernet", .device = i82557C, - .device_id = PCI_DEVICE_ID_INTEL_82557, - .revision = 0x03, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.revision = 0x03, .power_management = false, },{ .pci.qdev.name = "i82558a", .pci.qdev.desc = "Intel i82558A Ethernet", .device = i82558A, - .device_id = PCI_DEVICE_ID_INTEL_82557, - .revision = 0x04, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.revision = 0x04, .stats_size = 76, .has_extended_tcb_support = true, .power_management = true, @@ -1973,8 +1955,8 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82558b", .pci.qdev.desc = "Intel i82558B Ethernet", .device = i82558B, - .device_id = PCI_DEVICE_ID_INTEL_82557, - .revision = 0x05, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.revision = 0x05, .stats_size = 76, .has_extended_tcb_support = true, .power_management = true, @@ -1982,8 +1964,8 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82559a", .pci.qdev.desc = "Intel i82559A Ethernet", .device = i82559A, - .device_id = PCI_DEVICE_ID_INTEL_82557, - .revision = 0x06, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.revision = 0x06, .stats_size = 80, .has_extended_tcb_support = true, .power_management = true, @@ -1991,8 +1973,8 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82559b", .pci.qdev.desc = "Intel i82559B Ethernet", .device = i82559B, - .device_id = PCI_DEVICE_ID_INTEL_82557, - .revision = 0x07, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.revision = 0x07, .stats_size = 80, .has_extended_tcb_support = true, .power_management = true, @@ -2000,12 +1982,16 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82559c", .pci.qdev.desc = "Intel i82559C Ethernet", .device = i82559C, - .device_id = PCI_DEVICE_ID_INTEL_82557, + .pci.device_id = PCI_DEVICE_ID_INTEL_82557, #if 0 - .revision = 0x08, + .pci.revision = 0x08, #endif /* TODO: Windows wants revision id 0x0c. */ - .revision = 0x0c, + .pci.revision = 0x0c, +#if EEPROM_SIZE > 0 + .pci.subsystem_vendor_id = PCI_VENDOR_ID_INTEL, + .pci.subsystem_id = 0x0040, +#endif .stats_size = 80, .has_extended_tcb_support = true, .power_management = true, @@ -2013,8 +1999,8 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82559er", .pci.qdev.desc = "Intel i82559ER Ethernet", .device = i82559ER, - .device_id = PCI_DEVICE_ID_INTEL_82551IT, - .revision = 0x09, + .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT, + .pci.revision = 0x09, .stats_size = 80, .has_extended_tcb_support = true, .power_management = true, @@ -2023,9 +2009,9 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.desc = "Intel i82562 Ethernet", .device = i82562, /* TODO: check device id. */ - .device_id = PCI_DEVICE_ID_INTEL_82551IT, + .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT, /* TODO: wrong revision id. */ - .revision = 0x0e, + .pci.revision = 0x0e, .stats_size = 80, .has_extended_tcb_support = true, .power_management = true, @@ -2034,8 +2020,8 @@ static E100PCIDeviceInfo e100_devices[] = { .pci.qdev.name = "i82801", .pci.qdev.desc = "Intel i82801 Ethernet", .device = i82801, - .device_id = 0x2449, - .revision = 0x03, + .pci.device_id = 0x2449, + .pci.revision = 0x03, .stats_size = 80, .has_extended_tcb_support = true, .power_management = true, @@ -2054,7 +2040,9 @@ static void eepro100_register_devices(void) PCIDeviceInfo *pci_dev = &e100_devices[i].pci; /* We use the same rom file for all device ids. QEMU fixes the device id during rom load. */ - pci_dev->romfile = "gpxe-eepro100-80861209.rom"; + pci_dev->vendor_id = PCI_VENDOR_ID_INTEL; + pci_dev->class_id = PCI_CLASS_NETWORK_ETHERNET; + pci_dev->romfile = "pxe-eepro100.rom"; pci_dev->init = e100_nic_init; pci_dev->exit = pci_nic_uninit; pci_dev->qdev.props = e100_properties; diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c index 660b28f..4c7158d 100644 --- a/hw/eeprom93xx.c +++ b/hw/eeprom93xx.c @@ -75,7 +75,7 @@ struct _eeprom_t { uint8_t tick; uint8_t address; uint8_t command; - uint8_t writeable; + uint8_t writable; uint8_t eecs; uint8_t eesk; @@ -130,7 +130,7 @@ static const VMStateDescription vmstate_eeprom = { VMSTATE_UINT8(tick, eeprom_t), VMSTATE_UINT8(address, eeprom_t), VMSTATE_UINT8(command, eeprom_t), - VMSTATE_UINT8(writeable, eeprom_t), + VMSTATE_UINT8(writable, eeprom_t), VMSTATE_UINT8(eecs, eeprom_t), VMSTATE_UINT8(eesk, eeprom_t), @@ -165,7 +165,7 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi) address = 0x0; } else if (eeprom->eecs && ! eecs) { /* End chip select cycle. This triggers write / erase. */ - if (eeprom->writeable) { + if (eeprom->writable) { uint8_t subcommand = address >> (eeprom->addrbits - 2); if (command == 0 && subcommand == 2) { /* Erase all. */ @@ -232,7 +232,7 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi) switch (address >> (eeprom->addrbits - 2)) { case 0: logout("write disable command\n"); - eeprom->writeable = 0; + eeprom->writable = 0; break; case 1: logout("write all command\n"); @@ -242,7 +242,7 @@ void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi) break; case 3: logout("write enable command\n"); - eeprom->writeable = 1; + eeprom->writable = 1; break; } } else { @@ -310,7 +310,7 @@ eeprom_t *eeprom93xx_new(DeviceState *dev, uint16_t nwords) addrbits = 6; } - eeprom = (eeprom_t *)qemu_mallocz(sizeof(*eeprom) + nwords * 2); + eeprom = (eeprom_t *)g_malloc0(sizeof(*eeprom) + nwords * 2); eeprom->size = nwords; eeprom->addrbits = addrbits; /* Output DO is tristate, read results in 1. */ @@ -325,7 +325,7 @@ void eeprom93xx_free(DeviceState *dev, eeprom_t *eeprom) /* Destroy EEPROM. */ logout("eeprom = 0x%p\n", eeprom); vmstate_unregister(dev, &vmstate_eeprom, eeprom); - qemu_free(eeprom); + g_free(eeprom); } uint16_t *eeprom93xx_data(eeprom_t *eeprom) diff --git a/hw/elf_ops.h b/hw/elf_ops.h index 0bd7235..6af357f 100644 --- a/hw/elf_ops.h +++ b/hw/elf_ops.h @@ -150,7 +150,7 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, i++; } if (nsyms) { - syms = qemu_realloc(syms, nsyms * sizeof(*syms)); + syms = g_realloc(syms, nsyms * sizeof(*syms)); qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ)); for (i = 0; i < nsyms - 1; i++) { @@ -159,7 +159,7 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, } } } else { - qemu_free(syms); + g_free(syms); syms = NULL; } @@ -173,19 +173,19 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, goto fail; /* Commit */ - s = qemu_mallocz(sizeof(*s)); + s = g_malloc0(sizeof(*s)); s->lookup_symbol = glue(lookup_symbol, SZ); glue(s->disas_symtab.elf, SZ) = syms; s->disas_num_syms = nsyms; s->disas_strtab = str; s->next = syminfos; syminfos = s; - qemu_free(shdr_table); + g_free(shdr_table); return 0; fail: - qemu_free(syms); - qemu_free(str); - qemu_free(shdr_table); + g_free(syms); + g_free(str); + g_free(shdr_table); return -1; } @@ -238,7 +238,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, size = ehdr.e_phnum * sizeof(phdr[0]); lseek(fd, ehdr.e_phoff, SEEK_SET); - phdr = qemu_mallocz(size); + phdr = g_malloc0(size); if (!phdr) goto fail; if (read(fd, phdr, size) != size) @@ -256,7 +256,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, if (ph->p_type == PT_LOAD) { mem_size = ph->p_memsz; /* XXX: avoid allocating */ - data = qemu_mallocz(mem_size); + data = g_malloc0(mem_size); if (ph->p_filesz > 0) { if (lseek(fd, ph->p_offset, SEEK_SET) < 0) goto fail; @@ -280,18 +280,18 @@ static int glue(load_elf, SZ)(const char *name, int fd, if ((addr + mem_size) > high) high = addr + mem_size; - qemu_free(data); + g_free(data); data = NULL; } } - qemu_free(phdr); + g_free(phdr); if (lowaddr) *lowaddr = (uint64_t)(elf_sword)low; if (highaddr) *highaddr = (uint64_t)(elf_sword)high; return total_size; fail: - qemu_free(data); - qemu_free(phdr); + g_free(data); + g_free(phdr); return -1; } diff --git a/hw/empty_slot.c b/hw/empty_slot.c index 664b8d9..da8adc4 100644 --- a/hw/empty_slot.c +++ b/hw/empty_slot.c @@ -53,18 +53,21 @@ static CPUWriteMemoryFunc * const empty_slot_write[3] = { void empty_slot_init(target_phys_addr_t addr, uint64_t slot_size) { - DeviceState *dev; - SysBusDevice *s; - EmptySlot *e; + if (slot_size > 0) { + /* Only empty slots larger than 0 byte need handling. */ + DeviceState *dev; + SysBusDevice *s; + EmptySlot *e; - dev = qdev_create(NULL, "empty_slot"); - s = sysbus_from_qdev(dev); - e = FROM_SYSBUS(EmptySlot, s); - e->size = slot_size; + dev = qdev_create(NULL, "empty_slot"); + s = sysbus_from_qdev(dev); + e = FROM_SYSBUS(EmptySlot, s); + e->size = slot_size; - qdev_init_nofail(dev); + qdev_init_nofail(dev); - sysbus_mmio_map(s, 0, addr); + sysbus_mmio_map(s, 0, addr); + } } static int empty_slot_init1(SysBusDevice *dev) diff --git a/hw/es1370.c b/hw/es1370.c index 40cb48c..c5c16b0 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -30,6 +30,7 @@ #include "audiodev.h" #include "audio/audio.h" #include "pci.h" +#include "dma.h" /* Missing stuff: SCTRL_P[12](END|ST)INC @@ -268,6 +269,7 @@ struct chan { typedef struct ES1370State { PCIDevice dev; QEMUSoundCard card; + MemoryRegion io; struct chan chan[NB_CHANNELS]; SWVoiceOut *dac_voice[2]; SWVoiceIn *adc_voice; @@ -775,7 +777,6 @@ IO_READ_PROTO (es1370_readl) return val; } - static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, int max, int *irq) { @@ -802,7 +803,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, if (!acquired) break; - cpu_physical_memory_write (addr, tmpbuf, acquired); + pci_dma_write (&s->dev, addr, tmpbuf, acquired); temp -= acquired; addr += acquired; @@ -816,7 +817,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, int copied, to_copy; to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf)); - cpu_physical_memory_read (addr, tmpbuf, to_copy); + pci_dma_read (&s->dev, addr, tmpbuf, to_copy); copied = AUD_write (voice, tmpbuf, to_copy); if (!copied) break; @@ -906,23 +907,20 @@ static void es1370_adc_callback (void *opaque, int avail) es1370_run_channel (s, ADC_CHANNEL, avail); } -static void es1370_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - ES1370State *s = DO_UPCAST (ES1370State, dev, pci_dev); - - (void) region_num; - (void) size; - (void) type; - - register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s); - register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s); - register_ioport_write (addr, 0x40, 4, es1370_writel, s); +static const MemoryRegionPortio es1370_portio[] = { + { 0, 0x40 * 4, 1, .write = es1370_writeb, }, + { 0, 0x40 * 2, 2, .write = es1370_writew, }, + { 0, 0x40, 4, .write = es1370_writel, }, + { 0, 0x40 * 4, 1, .read = es1370_readb, }, + { 0, 0x40 * 2, 2, .read = es1370_readw, }, + { 0, 0x40, 4, .read = es1370_readl, }, + PORTIO_END_OF_LIST() +}; - register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s); - register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s); - register_ioport_read (addr, 0x40, 4, es1370_readl, s); -} +static const MemoryRegionOps es1370_io_ops = { + .old_portio = es1370_portio, + .endianness = DEVICE_LITTLE_ENDIAN, +}; static const VMStateDescription vmstate_es1370_channel = { .name = "es1370_channel", @@ -998,32 +996,20 @@ static int es1370_initfn (PCIDevice *dev) ES1370State *s = DO_UPCAST (ES1370State, dev, dev); uint8_t *c = s->dev.config; - pci_config_set_vendor_id (c, PCI_VENDOR_ID_ENSONIQ); - pci_config_set_device_id (c, PCI_DEVICE_ID_ENSONIQ_ES1370); c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_SLOW >> 8; - pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO); -#if 1 - c[PCI_SUBSYSTEM_VENDOR_ID] = 0x42; - c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x49; - c[PCI_SUBSYSTEM_ID] = 0x4c; - c[PCI_SUBSYSTEM_ID + 1] = 0x4c; -#else - c[PCI_SUBSYSTEM_VENDOR_ID] = 0x74; - c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x12; - c[PCI_SUBSYSTEM_ID] = 0x71; - c[PCI_SUBSYSTEM_ID + 1] = 0x13; +#if 0 c[PCI_CAPABILITY_LIST] = 0xdc; c[PCI_INTERRUPT_LINE] = 10; c[0xdc] = 0x00; #endif - /* TODO: RST# value should be 0. */ c[PCI_INTERRUPT_PIN] = 1; c[PCI_MIN_GNT] = 0x0c; c[PCI_MAX_LAT] = 0x80; - pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map); + memory_region_init_io (&s->io, &es1370_io_ops, s, "es1370", 256); + pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); qemu_register_reset (es1370_on_reset, s); AUD_register_card ("es1370", &s->card); @@ -1031,6 +1017,14 @@ static int es1370_initfn (PCIDevice *dev) return 0; } +static int es1370_exitfn(PCIDevice *dev) +{ + ES1370State *s = DO_UPCAST (ES1370State, dev, dev); + + memory_region_destroy (&s->io); + return 0; +} + int es1370_init (PCIBus *bus) { pci_create_simple (bus, -1, "ES1370"); @@ -1043,6 +1037,17 @@ static PCIDeviceInfo es1370_info = { .qdev.size = sizeof (ES1370State), .qdev.vmsd = &vmstate_es1370, .init = es1370_initfn, + .exit = es1370_exitfn, + .vendor_id = PCI_VENDOR_ID_ENSONIQ, + .device_id = PCI_DEVICE_ID_ENSONIQ_ES1370, + .class_id = PCI_CLASS_MULTIMEDIA_AUDIO, +#if 1 + .subsystem_vendor_id = 0x4942, + .subsystem_id = 0x4c4c, +#else + .subsystem_vendor_id = 0x1274, + .subsystem_id = 0x1371, +#endif }; static void es1370_register (void) diff --git a/hw/escc.c b/hw/escc.c index f6fd919..13c7e66 100644 --- a/hw/escc.c +++ b/hw/escc.c @@ -27,15 +27,7 @@ #include "escc.h" #include "qemu-char.h" #include "console.h" - -/* debug serial */ -//#define DEBUG_SERIAL - -/* debug keyboard */ -//#define DEBUG_KBD - -/* debug mouse */ -//#define DEBUG_MOUSE +#include "trace.h" /* * Chipset docs: @@ -69,25 +61,6 @@ * 2010-May-23 Artyom Tarasenko: Reworked IUS logic */ -#ifdef DEBUG_SERIAL -#define SER_DPRINTF(fmt, ...) \ - do { printf("SER: " fmt , ## __VA_ARGS__); } while (0) -#else -#define SER_DPRINTF(fmt, ...) -#endif -#ifdef DEBUG_KBD -#define KBD_DPRINTF(fmt, ...) \ - do { printf("KBD: " fmt , ## __VA_ARGS__); } while (0) -#else -#define KBD_DPRINTF(fmt, ...) -#endif -#ifdef DEBUG_MOUSE -#define MS_DPRINTF(fmt, ...) \ - do { printf("MSC: " fmt , ## __VA_ARGS__); } while (0) -#else -#define MS_DPRINTF(fmt, ...) -#endif - typedef enum { chn_a, chn_b, } ChnID; @@ -108,25 +81,26 @@ typedef struct { #define SERIAL_REGS 16 typedef struct ChannelState { qemu_irq irq; - uint32_t reg; uint32_t rxint, txint, rxint_under_svc, txint_under_svc; - ChnID chn; // this channel, A (base+4) or B (base+0) - ChnType type; struct ChannelState *otherchn; - uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS]; + uint32_t reg; + uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS]; SERIOQueue queue; CharDriverState *chr; int e0_mode, led_mode, caps_lock_mode, num_lock_mode; int disabled; int clock; uint32_t vmstate_dummy; + ChnID chn; // this channel, A (base+4) or B (base+0) + ChnType type; + uint8_t rx, tx; } ChannelState; struct SerialState { SysBusDevice busdev; struct ChannelState chn[2]; uint32_t it_shift; - int mmio_index; + MemoryRegion mmio; uint32_t disabled; uint32_t frequency; }; @@ -249,7 +223,7 @@ static void put_queue(void *opaque, int b) ChannelState *s = opaque; SERIOQueue *q = &s->queue; - SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b); + trace_escc_put_queue(CHN_C(s), b); if (q->count >= SERIO_QUEUE_SIZE) return; q->data[q->wptr] = b; @@ -273,7 +247,7 @@ static uint32_t get_queue(void *opaque) q->rptr = 0; q->count--; } - SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val); + trace_escc_get_queue(CHN_C(s), val); if (q->count > 0) serial_receive_byte(s, 0); return val; @@ -300,7 +274,7 @@ static void escc_update_irq(ChannelState *s) irq = escc_update_irq_chn(s); irq |= escc_update_irq_chn(s->otherchn); - SER_DPRINTF("IRQ = %d\n", irq); + trace_escc_update_irq(irq); qemu_set_irq(s->irq, irq); } @@ -485,12 +459,12 @@ static void escc_update_parameters(ChannelState *s) ssp.parity = parity; ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; - SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s), - speed, parity, data_bits, stop_bits); - qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); + trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); } -static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void escc_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { SerialState *serial = opaque; ChannelState *s; @@ -503,8 +477,7 @@ static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) s = &serial->chn[channel]; switch (saddr) { case SERIAL_CTRL: - SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, - val & 0xff); + trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff); newreg = 0; switch (s->reg) { case W_CMD: @@ -574,11 +547,11 @@ static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) s->reg = 0; break; case SERIAL_DATA: - SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val); + trace_escc_mem_writeb_data(CHN_C(s), val); s->tx = val; if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled if (s->chr) - qemu_chr_write(s->chr, &s->tx, 1); + qemu_chr_fe_write(s->chr, &s->tx, 1); else if (s->type == kbd && !s->disabled) { handle_kbd_command(s, val); } @@ -592,7 +565,8 @@ static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) } } -static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr) +static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SerialState *serial = opaque; ChannelState *s; @@ -605,8 +579,7 @@ static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr) s = &serial->chn[channel]; switch (saddr) { case SERIAL_CTRL: - SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, - s->rregs[s->reg]); + trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]); ret = s->rregs[s->reg]; s->reg = 0; return ret; @@ -617,7 +590,7 @@ static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr) ret = get_queue(s); else ret = s->rx; - SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret); + trace_escc_mem_readb_data(CHN_C(s), ret); if (s->chr) qemu_chr_accept_input(s->chr); return ret; @@ -627,6 +600,16 @@ static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr) return 0; } +static const MemoryRegionOps escc_mem_ops = { + .read = escc_mem_read, + .write = escc_mem_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + static int serial_can_receive(void *opaque) { ChannelState *s = opaque; @@ -643,7 +626,7 @@ static int serial_can_receive(void *opaque) static void serial_receive_byte(ChannelState *s, int ch) { - SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch); + trace_escc_serial_receive_byte(CHN_C(s), ch); s->rregs[R_STATUS] |= STATUS_RXAV; s->rx = ch; set_rxint(s); @@ -668,18 +651,6 @@ static void serial_event(void *opaque, int event) serial_receive_break(s); } -static CPUReadMemoryFunc * const escc_mem_read[3] = { - escc_mem_readb, - NULL, - NULL, -}; - -static CPUWriteMemoryFunc * const escc_mem_write[3] = { - escc_mem_writeb, - NULL, - NULL, -}; - static const VMStateDescription vmstate_escc_chn = { .name ="escc_chn", .version_id = 2, @@ -712,7 +683,7 @@ static const VMStateDescription vmstate_escc = { } }; -int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, +MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, CharDriverState *chrA, CharDriverState *chrB, int clock, int it_shift) { @@ -737,7 +708,7 @@ int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, } d = FROM_SYSBUS(SerialState, s); - return d->mmio_index; + return &d->mmio; } static const uint8_t keycodes[128] = { @@ -767,8 +738,7 @@ static void sunkbd_event(void *opaque, int ch) ChannelState *s = opaque; int release = ch & 0x80; - KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : - "press"); + trace_escc_sunkbd_event_in(ch); switch (ch) { case 58: // Caps lock press s->caps_lock_mode ^= 1; @@ -802,13 +772,13 @@ static void sunkbd_event(void *opaque, int ch) } else { ch = keycodes[ch & 0x7f]; } - KBD_DPRINTF("Translated keycode %2.2x\n", ch); + trace_escc_sunkbd_event_out(ch); put_queue(s, ch | release); } static void handle_kbd_command(ChannelState *s, int val) { - KBD_DPRINTF("Command %d\n", val); + trace_escc_kbd_command(val); if (s->led_mode) { // Ignore led byte s->led_mode = 0; return; @@ -840,8 +810,7 @@ static void sunmouse_event(void *opaque, ChannelState *s = opaque; int ch; - MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state); - + trace_escc_sunmouse_event(dx, dy, buttons_state); ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */ if (buttons_state & MOUSE_EVENT_LBUTTON) @@ -901,7 +870,6 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, static int escc_init1(SysBusDevice *dev) { SerialState *s = FROM_SYSBUS(SerialState, dev); - int io; unsigned int i; s->chn[0].disabled = s->disabled; @@ -918,10 +886,9 @@ static int escc_init1(SysBusDevice *dev) s->chn[0].otherchn = &s->chn[1]; s->chn[1].otherchn = &s->chn[0]; - io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io); - s->mmio_index = io; + memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc", + ESCC_SIZE << s->it_shift); + sysbus_init_mmio_region(dev, &s->mmio); if (s->chn[0].type == mouse) { qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, diff --git a/hw/escc.h b/hw/escc.h index 015b9d0..d1da46f 100644 --- a/hw/escc.h +++ b/hw/escc.h @@ -1,6 +1,6 @@ /* escc.c */ #define ESCC_SIZE 4 -int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, +MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, CharDriverState *chrA, CharDriverState *chrB, int clock, int it_shift); diff --git a/hw/esp.c b/hw/esp.c index fa9d2a2..b698a43 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -25,9 +25,7 @@ #include "sysbus.h" #include "scsi.h" #include "esp.h" - -/* debug ESP card */ -//#define DEBUG_ESP +#include "trace.h" /* * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O), @@ -37,13 +35,6 @@ * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt */ -#ifdef DEBUG_ESP -#define DPRINTF(fmt, ...) \ - do { printf("ESP: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while (0) -#endif - #define ESP_ERROR(fmt, ...) \ do { printf("ESP ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0) @@ -54,17 +45,18 @@ typedef struct ESPState ESPState; struct ESPState { SysBusDevice busdev; - uint32_t it_shift; - qemu_irq irq; uint8_t rregs[ESP_REGS]; uint8_t wregs[ESP_REGS]; + qemu_irq irq; + uint32_t it_shift; int32_t ti_size; uint32_t ti_rptr, ti_wptr; - uint8_t ti_buf[TI_BUFSZ]; - uint32_t sense; + uint32_t status; uint32_t dma; + uint8_t ti_buf[TI_BUFSZ]; SCSIBus bus; SCSIDevice *current_dev; + SCSIRequest *current_req; uint8_t cmdbuf[TI_BUFSZ]; uint32_t cmdlen; uint32_t do_cmd; @@ -74,13 +66,14 @@ struct ESPState { /* The size of the current DMA transfer. Zero if no transfer is in progress. */ uint32_t dma_counter; - uint8_t *async_buf; + int dma_enabled; + uint32_t async_len; + uint8_t *async_buf; ESPDMAMemoryReadWriteFunc dma_memory_read; ESPDMAMemoryReadWriteFunc dma_memory_write; void *dma_opaque; - int dma_enabled; void (*dma_cb)(ESPState *s); }; @@ -156,7 +149,7 @@ static void esp_raise_irq(ESPState *s) if (!(s->rregs[ESP_RSTAT] & STAT_INT)) { s->rregs[ESP_RSTAT] |= STAT_INT; qemu_irq_raise(s->irq); - DPRINTF("Raise IRQ\n"); + trace_esp_raise_irq(); } } @@ -165,7 +158,7 @@ static void esp_lower_irq(ESPState *s) if (s->rregs[ESP_RSTAT] & STAT_INT) { s->rregs[ESP_RSTAT] &= ~STAT_INT; qemu_irq_lower(s->irq); - DPRINTF("Lower IRQ\n"); + trace_esp_lower_irq(); } } @@ -176,17 +169,28 @@ static void esp_dma_enable(void *opaque, int irq, int level) if (level) { s->dma_enabled = 1; - DPRINTF("Raise enable\n"); + trace_esp_dma_enable(); if (s->dma_cb) { s->dma_cb(s); s->dma_cb = NULL; } } else { - DPRINTF("Lower enable\n"); + trace_esp_dma_disable(); s->dma_enabled = 0; } } +static void esp_request_cancelled(SCSIRequest *req) +{ + ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); + + if (req == s->current_req) { + scsi_req_unref(s->current_req); + s->current_req = NULL; + s->current_dev = NULL; + } +} + static uint32_t get_cmd(ESPState *s, uint8_t *buf) { uint32_t dmalen; @@ -199,21 +203,22 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) } else { dmalen = s->ti_size; memcpy(buf, s->ti_buf, dmalen); - buf[0] = 0; + buf[0] = buf[2] >> 5; } - DPRINTF("get_cmd: len %d target %d\n", dmalen, target); + trace_esp_get_cmd(dmalen, target); s->ti_size = 0; s->ti_rptr = 0; s->ti_wptr = 0; - if (s->current_dev) { + if (s->current_req) { /* Started a new command before the old one finished. Cancel it. */ - s->current_dev->info->cancel_io(s->current_dev, 0); + scsi_req_cancel(s->current_req); s->async_len = 0; } - if (target >= ESP_MAX_DEVS || !s->bus.devs[target]) { + s->current_dev = scsi_device_find(&s->bus, 0, target, 0); + if (!s->current_dev) { // No such drive s->rregs[ESP_RSTAT] = 0; s->rregs[ESP_RINTR] = INTR_DC; @@ -221,7 +226,6 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) esp_raise_irq(s); return 0; } - s->current_dev = s->bus.devs[target]; return dmalen; } @@ -229,10 +233,13 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) { int32_t datalen; int lun; + SCSIDevice *current_lun; - DPRINTF("do_busid_cmd: busid 0x%x\n", busid); + trace_esp_do_busid_cmd(busid); lun = busid & 7; - datalen = s->current_dev->info->send_command(s->current_dev, 0, buf, lun); + current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun); + s->current_req = scsi_req_new(current_lun, 0, lun, buf, NULL); + datalen = scsi_req_enqueue(s->current_req); s->ti_size = datalen; if (datalen != 0) { s->rregs[ESP_RSTAT] = STAT_TC; @@ -240,11 +247,10 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid) s->dma_counter = 0; if (datalen > 0) { s->rregs[ESP_RSTAT] |= STAT_DI; - s->current_dev->info->read_data(s->current_dev, 0); } else { s->rregs[ESP_RSTAT] |= STAT_DO; - s->current_dev->info->write_data(s->current_dev, 0); } + scsi_req_continue(s->current_req); } s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; s->rregs[ESP_RSEQ] = SEQ_CD; @@ -295,7 +301,7 @@ static void handle_satn_stop(ESPState *s) } s->cmdlen = get_cmd(s, s->cmdbuf); if (s->cmdlen) { - DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen); + trace_esp_handle_satn_stop(s->cmdlen); s->do_cmd = 1; s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; @@ -306,8 +312,8 @@ static void handle_satn_stop(ESPState *s) static void write_response(ESPState *s) { - DPRINTF("Transfer status (sense=%d)\n", s->sense); - s->ti_buf[0] = s->sense; + trace_esp_write_response(s->status); + s->ti_buf[0] = s->status; s->ti_buf[1] = 0; if (s->dma) { s->dma_memory_write(s->dma_opaque, s->ti_buf, 2); @@ -342,7 +348,7 @@ static void esp_do_dma(ESPState *s) to_device = (s->ti_size < 0); len = s->dma_left; if (s->do_cmd) { - DPRINTF("command len %d + %d\n", s->cmdlen, len); + trace_esp_do_dma(s->cmdlen, len); s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); s->ti_size = 0; s->cmdlen = 0; @@ -370,53 +376,56 @@ static void esp_do_dma(ESPState *s) else s->ti_size -= len; if (s->async_len == 0) { - if (to_device) { - // ti_size is negative - s->current_dev->info->write_data(s->current_dev, 0); - } else { - s->current_dev->info->read_data(s->current_dev, 0); - /* If there is still data to be read from the device then - complete the DMA operation immediately. Otherwise defer - until the scsi layer has completed. */ - if (s->dma_left == 0 && s->ti_size > 0) { - esp_dma_done(s); - } + scsi_req_continue(s->current_req); + /* If there is still data to be read from the device then + complete the DMA operation immediately. Otherwise defer + until the scsi layer has completed. */ + if (to_device || s->dma_left != 0 || s->ti_size == 0) { + return; } - } else { - /* Partially filled a scsi buffer. Complete immediately. */ - esp_dma_done(s); } + + /* Partially filled a scsi buffer. Complete immediately. */ + esp_dma_done(s); } -static void esp_command_complete(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg) +static void esp_command_complete(SCSIRequest *req, uint32_t status) { - ESPState *s = DO_UPCAST(ESPState, busdev.qdev, bus->qbus.parent); + ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); - if (reason == SCSI_REASON_DONE) { - DPRINTF("SCSI Command complete\n"); - if (s->ti_size != 0) - DPRINTF("SCSI command completed unexpectedly\n"); - s->ti_size = 0; - s->dma_left = 0; - s->async_len = 0; - if (arg) - DPRINTF("Command failed\n"); - s->sense = arg; - s->rregs[ESP_RSTAT] = STAT_ST; - esp_dma_done(s); + trace_esp_command_complete(); + if (s->ti_size != 0) { + trace_esp_command_complete_unexpected(); + } + s->ti_size = 0; + s->dma_left = 0; + s->async_len = 0; + if (status) { + trace_esp_command_complete_fail(); + } + s->status = status; + s->rregs[ESP_RSTAT] = STAT_ST; + esp_dma_done(s); + if (s->current_req) { + scsi_req_unref(s->current_req); + s->current_req = NULL; s->current_dev = NULL; - } else { - DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); - s->async_len = arg; - s->async_buf = s->current_dev->info->get_buf(s->current_dev, 0); - if (s->dma_left) { - esp_do_dma(s); - } else if (s->dma_counter != 0 && s->ti_size <= 0) { - /* If this was the last part of a DMA transfer then the - completion interrupt is deferred to here. */ - esp_dma_done(s); - } + } +} + +static void esp_transfer_data(SCSIRequest *req, uint32_t len) +{ + ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); + + trace_esp_transfer_data(s->dma_left, s->ti_size); + s->async_len = len; + s->async_buf = scsi_req_get_buf(req); + if (s->dma_left) { + esp_do_dma(s); + } else if (s->dma_counter != 0 && s->ti_size <= 0) { + /* If this was the last part of a DMA transfer then the + completion interrupt is deferred to here. */ + esp_dma_done(s); } } @@ -436,13 +445,13 @@ static void handle_ti(ESPState *s) minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size; else minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size; - DPRINTF("Transfer Information len %d\n", minlen); + trace_esp_handle_ti(minlen); if (s->dma) { s->dma_left = minlen; s->rregs[ESP_RSTAT] &= ~STAT_TC; esp_do_dma(s); } else if (s->do_cmd) { - DPRINTF("command len %d\n", s->cmdlen); + trace_esp_handle_ti_cmd(s->cmdlen); s->ti_size = 0; s->cmdlen = 0; s->do_cmd = 0; @@ -501,7 +510,7 @@ static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr) uint32_t saddr, old_val; saddr = addr >> s->it_shift; - DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]); + trace_esp_mem_readb(saddr, s->rregs[saddr]); switch (saddr) { case ESP_FIFO: if (s->ti_size > 0) { @@ -542,8 +551,7 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) uint32_t saddr; saddr = addr >> s->it_shift; - DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], - val); + trace_esp_mem_writeb(saddr, s->wregs[saddr], val); switch (saddr) { case ESP_TCLO: case ESP_TCMID: @@ -571,21 +579,21 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) } switch(val & CMD_CMD) { case CMD_NOP: - DPRINTF("NOP (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_nop(val); break; case CMD_FLUSH: - DPRINTF("Flush FIFO (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_flush(val); //s->ti_size = 0; s->rregs[ESP_RINTR] = INTR_FC; s->rregs[ESP_RSEQ] = 0; s->rregs[ESP_RFLAGS] = 0; break; case CMD_RESET: - DPRINTF("Chip reset (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_reset(val); esp_soft_reset(&s->busdev.qdev); break; case CMD_BUSRESET: - DPRINTF("Bus reset (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_bus_reset(val); s->rregs[ESP_RINTR] = INTR_RST; if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) { esp_raise_irq(s); @@ -595,41 +603,41 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) handle_ti(s); break; case CMD_ICCS: - DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_iccs(val); write_response(s); s->rregs[ESP_RINTR] = INTR_FC; s->rregs[ESP_RSTAT] |= STAT_MI; break; case CMD_MSGACC: - DPRINTF("Message Accepted (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_msgacc(val); s->rregs[ESP_RINTR] = INTR_DC; s->rregs[ESP_RSEQ] = 0; s->rregs[ESP_RFLAGS] = 0; esp_raise_irq(s); break; case CMD_PAD: - DPRINTF("Transfer padding (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_pad(val); s->rregs[ESP_RSTAT] = STAT_TC; s->rregs[ESP_RINTR] = INTR_FC; s->rregs[ESP_RSEQ] = 0; break; case CMD_SATN: - DPRINTF("Set ATN (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_satn(val); break; case CMD_SEL: - DPRINTF("Select without ATN (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_sel(val); handle_s_without_atn(s); break; case CMD_SELATN: - DPRINTF("Select with ATN (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_selatn(val); handle_satn(s); break; case CMD_SELATNS: - DPRINTF("Select with ATN & stop (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_selatns(val); handle_satn_stop(s); break; case CMD_ENSEL: - DPRINTF("Enable selection (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_ensel(val); s->rregs[ESP_RINTR] = 0; break; default: @@ -678,7 +686,7 @@ static const VMStateDescription vmstate_esp = { VMSTATE_UINT32(ti_rptr, ESPState), VMSTATE_UINT32(ti_wptr, ESPState), VMSTATE_BUFFER(ti_buf, ESPState), - VMSTATE_UINT32(sense, ESPState), + VMSTATE_UINT32(status, ESPState), VMSTATE_UINT32(dma, ESPState), VMSTATE_BUFFER(cmdbuf, ESPState), VMSTATE_UINT32(cmdlen, ESPState), @@ -714,6 +722,16 @@ void esp_init(target_phys_addr_t espaddr, int it_shift, *dma_enable = qdev_get_gpio_in(dev, 1); } +static const struct SCSIBusInfo esp_scsi_info = { + .tcq = false, + .max_target = ESP_MAX_DEVS, + .max_lun = 7, + + .transfer_data = esp_transfer_data, + .complete = esp_command_complete, + .cancel = esp_request_cancelled +}; + static int esp_init1(SysBusDevice *dev) { ESPState *s = FROM_SYSBUS(ESPState, dev); @@ -728,7 +746,7 @@ static int esp_init1(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2); - scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete); + scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info); return scsi_bus_legacy_handle_cmdline(&s->bus); } diff --git a/hw/etraxfs.c b/hw/etraxfs.c deleted file mode 100644 index 5ee5f97..0000000 --- a/hw/etraxfs.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * QEMU ETRAX System Emulator - * - * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB. - * - * 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 AUTHORS OR 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. - */ - -#include "sysbus.h" -#include "boards.h" -#include "sysemu.h" -#include "net.h" -#include "flash.h" -#include "etraxfs.h" -#include "loader.h" -#include "elf.h" -#include "cris-boot.h" -#include "blockdev.h" - -#define FLASH_SIZE 0x2000000 -#define INTMEM_SIZE (128 * 1024) - -static struct cris_load_info li; - -static void flash_cpu_reset(void *opaque) -{ - CPUState *env = opaque; - cpu_reset(env); -} - -static -void bareetraxfs_init (ram_addr_t ram_size, - const char *boot_device, - const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename, const char *cpu_model) -{ - DeviceState *dev; - SysBusDevice *s; - CPUState *env; - qemu_irq irq[30], nmi[2], *cpu_irq; - void *etraxfs_dmac; - struct etraxfs_dma_client *eth[2] = {NULL, NULL}; - DriveInfo *dinfo; - int i; - ram_addr_t phys_ram; - ram_addr_t phys_flash; - ram_addr_t phys_intmem; - - /* init CPUs */ - if (cpu_model == NULL) { - cpu_model = "crisv32"; - } - env = cpu_init(cpu_model); - - /* allocate RAM */ - phys_ram = qemu_ram_alloc(NULL, "etraxfs.ram", ram_size); - cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM); - - /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the - internal memory. */ - phys_intmem = qemu_ram_alloc(NULL, "etraxfs.chipram", INTMEM_SIZE); - cpu_register_physical_memory(0x38000000, INTMEM_SIZE, - phys_intmem | IO_MEM_RAM); - - - phys_flash = qemu_ram_alloc(NULL, "etraxfs.flash", FLASH_SIZE); - dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi02_register(0x0, phys_flash, - dinfo ? dinfo->bdrv : NULL, (64 * 1024), - FLASH_SIZE >> 16, - 1, 2, 0x0000, 0x0000, 0x0000, 0x0000, - 0x555, 0x2aa, 0); - cpu_irq = cris_pic_init_cpu(env); - dev = qdev_create(NULL, "etraxfs,pic"); - /* FIXME: Is there a proper way to signal vectors to the CPU core? */ - qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector); - qdev_init_nofail(dev); - s = sysbus_from_qdev(dev); - sysbus_mmio_map(s, 0, 0x3001c000); - sysbus_connect_irq(s, 0, cpu_irq[0]); - sysbus_connect_irq(s, 1, cpu_irq[1]); - for (i = 0; i < 30; i++) { - irq[i] = qdev_get_gpio_in(dev, i); - } - nmi[0] = qdev_get_gpio_in(dev, 30); - nmi[1] = qdev_get_gpio_in(dev, 31); - - etraxfs_dmac = etraxfs_dmac_init(0x30000000, 10); - for (i = 0; i < 10; i++) { - /* On ETRAX, odd numbered channels are inputs. */ - etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1); - } - - /* Add the two ethernet blocks. */ - eth[0] = etraxfs_eth_init(&nd_table[0], 0x30034000, 1); - if (nb_nics > 1) - eth[1] = etraxfs_eth_init(&nd_table[1], 0x30036000, 2); - - /* The DMA Connector block is missing, hardwire things for now. */ - etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); - etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1); - if (eth[1]) { - etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]); - etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1); - } - - /* 2 timers. */ - sysbus_create_varargs("etraxfs,timer", 0x3001e000, irq[0x1b], nmi[1], NULL); - sysbus_create_varargs("etraxfs,timer", 0x3005e000, irq[0x1b], nmi[1], NULL); - - for (i = 0; i < 4; i++) { - sysbus_create_simple("etraxfs,serial", 0x30026000 + i * 0x2000, - irq[0x14 + i]); - } - - if (kernel_filename) { - li.image_filename = kernel_filename; - li.cmdline = kernel_cmdline; - cris_load_image(env, &li); - } else { - if (!dinfo) { - fprintf(stderr, - "Provide a kernel image or a flash image to boot from.\n"); - exit(1); - } - - /* Nothing more to do for flash images, those boot from addr 0. */ - qemu_register_reset(flash_cpu_reset, env); - } -} - -static QEMUMachine bareetraxfs_machine = { - .name = "bareetraxfs", - .desc = "Bare ETRAX FS board", - .init = bareetraxfs_init, - .is_default = 1, -}; - -static void bareetraxfs_machine_init(void) -{ - qemu_register_machine(&bareetraxfs_machine); -} - -machine_init(bareetraxfs_machine_init); diff --git a/hw/etraxfs.h b/hw/etraxfs.h index 01fb9d3..24e8fd8 100644 --- a/hw/etraxfs.h +++ b/hw/etraxfs.h @@ -22,7 +22,25 @@ * THE SOFTWARE. */ +#include "net.h" #include "etraxfs_dma.h" qemu_irq *cris_pic_init_cpu(CPUState *env); -void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr); + +/* Instantiate an ETRAXFS Ethernet MAC. */ +static inline DeviceState * +etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr, + void *dma_out, void *dma_in) +{ + DeviceState *dev; + qemu_check_nic_model(nd, "fseth"); + + dev = qdev_create(NULL, "etraxfs-eth"); + qdev_set_nic_properties(dev, nd); + qdev_prop_set_uint32(dev, "phyaddr", phyaddr); + qdev_prop_set_ptr(dev, "dma_out", dma_out); + qdev_prop_set_ptr(dev, "dma_in", dma_in); + qdev_init_nofail(dev); + sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); + return dev; +} diff --git a/hw/etraxfs_dma.c b/hw/etraxfs_dma.c index c205ec1..02d0183 100644 --- a/hw/etraxfs_dma.c +++ b/hw/etraxfs_dma.c @@ -24,6 +24,7 @@ #include #include #include "hw.h" +#include "exec-memory.h" #include "qemu-common.h" #include "sysemu.h" @@ -185,7 +186,7 @@ struct fs_dma_channel struct fs_dma_ctrl { - int map; + MemoryRegion mmio; int nr_channels; struct fs_dma_channel *channels; @@ -562,13 +563,17 @@ static uint32_t dma_rinvalid (void *opaque, target_phys_addr_t addr) return 0; } -static uint32_t -dma_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +dma_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct fs_dma_ctrl *ctrl = opaque; int c; uint32_t r = 0; + if (size != 4) { + dma_rinvalid(opaque, addr); + } + /* Make addr relative to this channel and bounded to nr regs. */ c = fs_channel(addr); addr &= 0xff; @@ -599,20 +604,24 @@ dma_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value) static void dma_update_state(struct fs_dma_ctrl *ctrl, int c) { - if ((ctrl->channels[c].regs[RW_CFG] & 1) != 3) { - if (ctrl->channels[c].regs[RW_CFG] & 2) - ctrl->channels[c].state = STOPPED; - if (!(ctrl->channels[c].regs[RW_CFG] & 1)) - ctrl->channels[c].state = RST; - } + if (ctrl->channels[c].regs[RW_CFG] & 2) + ctrl->channels[c].state = STOPPED; + if (!(ctrl->channels[c].regs[RW_CFG] & 1)) + ctrl->channels[c].state = RST; } static void -dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +dma_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct fs_dma_ctrl *ctrl = opaque; + uint32_t value = val64; int c; + if (size != 4) { + dma_winvalid(opaque, addr, value); + } + /* Make addr relative to this channel and bounded to nr regs. */ c = fs_channel(addr); addr &= 0xff; @@ -668,16 +677,14 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } } -static CPUReadMemoryFunc * const dma_read[] = { - &dma_rinvalid, - &dma_rinvalid, - &dma_readl, -}; - -static CPUWriteMemoryFunc * const dma_write[] = { - &dma_winvalid, - &dma_winvalid, - &dma_writel, +static const MemoryRegionOps dma_ops = { + .read = dma_read, + .write = dma_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4 + } }; static int etraxfs_dmac_run(void *opaque) @@ -732,7 +739,7 @@ static void DMA_run(void *opaque) struct fs_dma_ctrl *etraxfs_dmac = opaque; int p = 1; - if (vm_running) + if (runstate_is_running()) p = etraxfs_dmac_run(etraxfs_dmac); if (p) @@ -743,14 +750,16 @@ void *etraxfs_dmac_init(target_phys_addr_t base, int nr_channels) { struct fs_dma_ctrl *ctrl = NULL; - ctrl = qemu_mallocz(sizeof *ctrl); + ctrl = g_malloc0(sizeof *ctrl); ctrl->bh = qemu_bh_new(DMA_run, ctrl); ctrl->nr_channels = nr_channels; - ctrl->channels = qemu_mallocz(sizeof ctrl->channels[0] * nr_channels); + ctrl->channels = g_malloc0(sizeof ctrl->channels[0] * nr_channels); + + memory_region_init_io(&ctrl->mmio, &dma_ops, ctrl, "etraxfs-dma", + nr_channels * 0x2000); + memory_region_add_subregion(get_system_memory(), base, &ctrl->mmio); - ctrl->map = cpu_register_io_memory(dma_read, dma_write, ctrl, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, nr_channels * 0x2000, ctrl->map); return ctrl; } diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c index 6aa4007..246a279 100644 --- a/hw/etraxfs_eth.c +++ b/hw/etraxfs_eth.c @@ -23,7 +23,7 @@ */ #include -#include "hw.h" +#include "sysbus.h" #include "net.h" #include "etraxfs.h" @@ -319,6 +319,8 @@ static void mdio_cycle(struct qemu_mdio *bus) struct fs_eth { + SysBusDevice busdev; + MemoryRegion mmio; NICState *nic; NICConf conf; int ethregs; @@ -327,8 +329,14 @@ struct fs_eth uint8_t macaddr[2][6]; uint32_t regs[FS_ETH_MAX_REGS]; - struct etraxfs_dma_client *dma_out; - struct etraxfs_dma_client *dma_in; + union { + void *vdma_out; + struct etraxfs_dma_client *dma_out; + }; + union { + void *vdma_in; + struct etraxfs_dma_client *dma_in; + }; /* MDIO bus. */ struct qemu_mdio mdio_bus; @@ -366,7 +374,8 @@ static void eth_validate_duplex(struct fs_eth *eth) } } -static uint32_t eth_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +eth_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct fs_eth *eth = opaque; uint32_t r = 0; @@ -410,9 +419,11 @@ static void eth_update_ma(struct fs_eth *eth, int ma) } static void -eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +eth_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct fs_eth *eth = opaque; + uint32_t value = val64; addr >>= 2; switch (addr) @@ -546,14 +557,14 @@ static void eth_set_link(VLANClientState *nc) eth->phy.link = !nc->link_down; } -static CPUReadMemoryFunc * const eth_read[] = { - NULL, NULL, - ð_readl, -}; - -static CPUWriteMemoryFunc * const eth_write[] = { - NULL, NULL, - ð_writel, +static const MemoryRegionOps eth_ops = { + .read = eth_read, + .write = eth_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void eth_cleanup(VLANClientState *nc) @@ -562,8 +573,12 @@ static void eth_cleanup(VLANClientState *nc) cpu_unregister_io_memory(eth->ethregs); - qemu_free(eth->dma_out); - qemu_free(eth); + /* Disconnect the client. */ + eth->dma_out->client.push = NULL; + eth->dma_out->client.opaque = NULL; + eth->dma_in->client.opaque = NULL; + eth->dma_in->client.pull = NULL; + g_free(eth); } static NetClientInfo net_etraxfs_info = { @@ -575,39 +590,48 @@ static NetClientInfo net_etraxfs_info = { .link_status_changed = eth_set_link, }; -void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr) +static int fs_eth_init(SysBusDevice *dev) { - struct etraxfs_dma_client *dma = NULL; - struct fs_eth *eth = NULL; + struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev); - qemu_check_nic_model(nd, "fseth"); - - dma = qemu_mallocz(sizeof *dma * 2); - eth = qemu_mallocz(sizeof *eth); - - dma[0].client.push = eth_tx_push; - dma[0].client.opaque = eth; - dma[1].client.opaque = eth; - dma[1].client.pull = NULL; + if (!s->dma_out || !s->dma_in) { + hw_error("Unconnected ETRAX-FS Ethernet MAC.\n"); + } - eth->dma_out = dma; - eth->dma_in = dma + 1; + s->dma_out->client.push = eth_tx_push; + s->dma_out->client.opaque = s; + s->dma_in->client.opaque = s; + s->dma_in->client.pull = NULL; - /* Connect the phy. */ - eth->phyaddr = phyaddr & 0x1f; - tdk_init(ð->phy); - mdio_attach(ð->mdio_bus, ð->phy, eth->phyaddr); + memory_region_init_io(&s->mmio, ð_ops, s, "etraxfs-eth", 0x5c); + sysbus_init_mmio_region(dev, &s->mmio); - eth->ethregs = cpu_register_io_memory(eth_read, eth_write, eth, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory (base, 0x5c, eth->ethregs); + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, + dev->qdev.info->name, dev->qdev.id, s); + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); - memcpy(eth->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr)); - eth->conf.vlan = nd->vlan; - eth->conf.peer = nd->netdev; + tdk_init(&s->phy); + mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr); + return 0; +} - eth->nic = qemu_new_nic(&net_etraxfs_info, ð->conf, - nd->model, nd->name, eth); +static SysBusDeviceInfo etraxfs_eth_info = { + .init = fs_eth_init, + .qdev.name = "etraxfs-eth", + .qdev.size = sizeof(struct fs_eth), + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("phyaddr", struct fs_eth, phyaddr, 1), + DEFINE_PROP_PTR("dma_out", struct fs_eth, vdma_out), + DEFINE_PROP_PTR("dma_in", struct fs_eth, vdma_in), + DEFINE_NIC_PROPERTIES(struct fs_eth, conf), + DEFINE_PROP_END_OF_LIST(), + } +}; - return dma; +static void etraxfs_eth_register(void) +{ + sysbus_register_withprop(&etraxfs_eth_info); } + +device_init(etraxfs_eth_register) diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c index 4feffda..47a56d7 100644 --- a/hw/etraxfs_pic.c +++ b/hw/etraxfs_pic.c @@ -39,6 +39,7 @@ struct etrax_pic { SysBusDevice busdev; + MemoryRegion mmio; void *interrupt_vector; qemu_irq parent_irq; qemu_irq parent_nmi; @@ -77,7 +78,8 @@ static void pic_update(struct etrax_pic *fs) qemu_set_irq(fs->parent_irq, !!vector); } -static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +pic_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct etrax_pic *fs = opaque; uint32_t rval; @@ -87,8 +89,8 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) return rval; } -static void -pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +static void pic_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned int size) { struct etrax_pic *fs = opaque; D(printf("%s addr=%x val=%x\n", __func__, addr, value)); @@ -99,14 +101,14 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } } -static CPUReadMemoryFunc * const pic_read[] = { - NULL, NULL, - &pic_readl, -}; - -static CPUWriteMemoryFunc * const pic_write[] = { - NULL, NULL, - &pic_writel, +static const MemoryRegionOps pic_ops = { + .read = pic_read, + .write = pic_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void nmi_handler(void *opaque, int irq, int level) @@ -139,15 +141,13 @@ static void irq_handler(void *opaque, int irq, int level) static int etraxfs_pic_init(SysBusDevice *dev) { struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev); - int intr_vect_regs; qdev_init_gpio_in(&dev->qdev, irq_handler, 32); sysbus_init_irq(dev, &s->parent_irq); sysbus_init_irq(dev, &s->parent_nmi); - intr_vect_regs = cpu_register_io_memory(pic_read, pic_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, intr_vect_regs); + memory_region_init_io(&s->mmio, &pic_ops, s, "etraxfs-pic", R_MAX * 4); + sysbus_init_mmio_region(dev, &s->mmio); return 0; } diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c index 2787ebd..298b985 100644 --- a/hw/etraxfs_ser.c +++ b/hw/etraxfs_ser.c @@ -24,6 +24,7 @@ #include "sysbus.h" #include "qemu-char.h" +#include "qemu-log.h" #define D(x) @@ -46,6 +47,7 @@ struct etrax_serial { SysBusDevice busdev; + MemoryRegion mmio; CharDriverState *chr; qemu_irq irq; @@ -72,7 +74,8 @@ static void ser_update_irq(struct etrax_serial *s) qemu_set_irq(s->irq, !!s->regs[R_MASKED_INTR]); } -static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +ser_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct etrax_serial *s = opaque; D(CPUState *env = s->env); @@ -100,25 +103,27 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) break; default: r = s->regs[addr]; - D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r)); + D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r)); break; } return r; } static void -ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +ser_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct etrax_serial *s = opaque; - unsigned char ch = value; + uint32_t value = val64; + unsigned char ch = val64; D(CPUState *env = s->env); - D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, value)); + D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr, value)); addr >>= 2; switch (addr) { case RW_DOUT: - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); s->regs[R_INTR] |= 3; s->pending_tx = 1; s->regs[addr] = value; @@ -127,7 +132,8 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) if (s->pending_tx) { value &= ~1; s->pending_tx = 0; - D(printf("fixedup value=%x r_intr=%x\n", value, s->regs[R_INTR])); + D(qemu_log("fixedup value=%x r_intr=%x\n", + value, s->regs[R_INTR])); } s->regs[addr] = value; s->regs[R_INTR] &= ~value; @@ -140,14 +146,14 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) ser_update_irq(s); } -static CPUReadMemoryFunc * const ser_read[] = { - NULL, NULL, - &ser_readl, -}; - -static CPUWriteMemoryFunc * const ser_write[] = { - NULL, NULL, - &ser_writel, +static const MemoryRegionOps ser_ops = { + .read = ser_read, + .write = ser_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void serial_receive(void *opaque, const uint8_t *buf, int size) @@ -157,7 +163,7 @@ static void serial_receive(void *opaque, const uint8_t *buf, int size) /* Got a byte. */ if (s->rx_fifo_len >= 16) { - printf("WARNING: UART dropped char.\n"); + qemu_log("WARNING: UART dropped char.\n"); return; } @@ -190,19 +196,26 @@ static void serial_event(void *opaque, int event) } -static int etraxfs_ser_init(SysBusDevice *dev) +static void etraxfs_ser_reset(DeviceState *d) { - struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev); - int ser_regs; + struct etrax_serial *s = container_of(d, typeof(*s), busdev.qdev); /* transmitter begins ready and idle. */ s->regs[RS_STAT_DIN] |= (1 << STAT_TR_RDY); s->regs[RS_STAT_DIN] |= (1 << STAT_TR_IDLE); + s->regs[RW_REC_CTRL] = 0x10000; + +} + +static int etraxfs_ser_init(SysBusDevice *dev) +{ + struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev); + sysbus_init_irq(dev, &s->irq); - ser_regs = cpu_register_io_memory(ser_read, ser_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, ser_regs); + memory_region_init_io(&s->mmio, &ser_ops, s, "etraxfs-serial", R_MAX * 4); + sysbus_init_mmio_region(dev, &s->mmio); + s->chr = qdev_init_chardev(&dev->qdev); if (s->chr) qemu_chr_add_handlers(s->chr, @@ -211,10 +224,16 @@ static int etraxfs_ser_init(SysBusDevice *dev) return 0; } +static SysBusDeviceInfo etraxfs_ser_info = { + .init = etraxfs_ser_init, + .qdev.name = "etraxfs,serial", + .qdev.size = sizeof(struct etrax_serial), + .qdev.reset = etraxfs_ser_reset, +}; + static void etraxfs_serial_register(void) { - sysbus_register_dev("etraxfs,serial", sizeof (struct etrax_serial), - etraxfs_ser_init); + sysbus_register_withprop(&etraxfs_ser_info); } device_init(etraxfs_serial_register) diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c index 133741b..57dc739 100644 --- a/hw/etraxfs_timer.c +++ b/hw/etraxfs_timer.c @@ -43,6 +43,7 @@ struct etrax_timer { SysBusDevice busdev; + MemoryRegion mmio; qemu_irq irq; qemu_irq nmi; @@ -72,7 +73,8 @@ struct etrax_timer { uint32_t r_masked_intr; }; -static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +timer_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct etrax_timer *t = opaque; uint32_t r = 0; @@ -85,7 +87,7 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) r = ptimer_get_count(t->ptimer_t1); break; case R_TIME: - r = qemu_get_clock(vm_clock) / 10; + r = qemu_get_clock_ns(vm_clock) / 10; break; case RW_INTR_MASK: r = t->rw_intr_mask; @@ -239,9 +241,11 @@ static inline void timer_watchdog_update(struct etrax_timer *t, uint32_t value) } static void -timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +timer_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct etrax_timer *t = opaque; + uint32_t value = val64; switch (addr) { @@ -281,14 +285,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } } -static CPUReadMemoryFunc * const timer_read[] = { - NULL, NULL, - &timer_readl, -}; - -static CPUWriteMemoryFunc * const timer_write[] = { - NULL, NULL, - &timer_writel, +static const MemoryRegionOps timer_ops = { + .read = timer_read, + .write = timer_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void etraxfs_timer_reset(void *opaque) @@ -307,7 +311,6 @@ static void etraxfs_timer_reset(void *opaque) static int etraxfs_timer_init(SysBusDevice *dev) { struct etrax_timer *t = FROM_SYSBUS(typeof (*t), dev); - int timer_regs; t->bh_t0 = qemu_bh_new(timer0_hit, t); t->bh_t1 = qemu_bh_new(timer1_hit, t); @@ -319,10 +322,8 @@ static int etraxfs_timer_init(SysBusDevice *dev) sysbus_init_irq(dev, &t->irq); sysbus_init_irq(dev, &t->nmi); - timer_regs = cpu_register_io_memory(timer_read, timer_write, t, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x5c, timer_regs); - + memory_region_init_io(&t->mmio, &timer_ops, t, "etraxfs-timer", 0x5c); + sysbus_init_mmio_region(dev, &t->mmio); qemu_register_reset(etraxfs_timer_reset, t); return 0; } diff --git a/hw/event_notifier.c b/hw/event_notifier.c deleted file mode 100644 index 13f3656..0000000 --- a/hw/event_notifier.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * event notifier support - * - * Copyright Red Hat, Inc. 2010 - * - * Authors: - * Michael S. Tsirkin - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - */ - -#include "hw.h" -#include "event_notifier.h" -#ifdef CONFIG_EVENTFD -#include -#endif - -int event_notifier_init(EventNotifier *e, int active) -{ -#ifdef CONFIG_EVENTFD - int fd = eventfd(!!active, EFD_NONBLOCK | EFD_CLOEXEC); - if (fd < 0) - return -errno; - e->fd = fd; - return 0; -#else - return -ENOSYS; -#endif -} - -void event_notifier_cleanup(EventNotifier *e) -{ - close(e->fd); -} - -int event_notifier_get_fd(EventNotifier *e) -{ - return e->fd; -} - -int event_notifier_test_and_clear(EventNotifier *e) -{ - uint64_t value; - int r = read(e->fd, &value, sizeof(value)); - return r == sizeof(value); -} - -int event_notifier_test(EventNotifier *e) -{ - uint64_t value; - int r = read(e->fd, &value, sizeof(value)); - if (r == sizeof(value)) { - /* restore previous value. */ - int s = write(e->fd, &value, sizeof(value)); - /* never blocks because we use EFD_SEMAPHORE. - * If we didn't we'd get EAGAIN on overflow - * and we'd have to write code to ignore it. */ - assert(s == sizeof(value)); - } - return r == sizeof(value); -} diff --git a/hw/event_notifier.h b/hw/event_notifier.h deleted file mode 100644 index 24117ea..0000000 --- a/hw/event_notifier.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef QEMU_EVENT_NOTIFIER_H -#define QEMU_EVENT_NOTIFIER_H - -#include "qemu-common.h" - -struct EventNotifier { - int fd; -}; - -int event_notifier_init(EventNotifier *, int active); -void event_notifier_cleanup(EventNotifier *); -int event_notifier_get_fd(EventNotifier *); -int event_notifier_test_and_clear(EventNotifier *); -int event_notifier_test(EventNotifier *); - -#endif diff --git a/hw/fdc.c b/hw/fdc.c index 4bbcc47..ecaad09 100644 --- a/hw/fdc.c +++ b/hw/fdc.c @@ -63,21 +63,6 @@ #define FD_RESET_SENSEI_COUNT 4 /* Number of sense interrupts on RESET */ /* Floppy disk drive emulation */ -typedef enum FDiskType { - FDRIVE_DISK_288 = 0x01, /* 2.88 MB disk */ - FDRIVE_DISK_144 = 0x02, /* 1.44 MB disk */ - FDRIVE_DISK_720 = 0x03, /* 720 kB disk */ - FDRIVE_DISK_USER = 0x04, /* User defined geometry */ - FDRIVE_DISK_NONE = 0x05, /* No disk */ -} FDiskType; - -typedef enum FDriveType { - FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */ - FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */ - FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */ - FDRIVE_DRV_NONE = 0x03, /* No drive connected */ -} FDriveType; - typedef enum FDiskFlags { FDISK_DBL_SIDES = 0x01, } FDiskFlags; @@ -97,6 +82,7 @@ typedef struct FDrive { uint8_t max_track; /* Nb of tracks */ uint16_t bps; /* Bytes per sector */ uint8_t ro; /* Is read-only */ + uint8_t media_changed; /* Is media changed */ } FDrive; static void fd_init(FDrive *drv) @@ -178,111 +164,23 @@ static void fd_recalibrate(FDrive *drv) drv->sect = 1; } -/* Recognize floppy formats */ -typedef struct FDFormat { - FDriveType drive; - FDiskType disk; - uint8_t last_sect; - uint8_t max_track; - uint8_t max_head; - const char *str; -} FDFormat; - -static const FDFormat fd_formats[] = { - /* First entry is default format */ - /* 1.44 MB 3"1/2 floppy disks */ - { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, "1.6 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", }, - /* 2.88 MB 3"1/2 floppy disks */ - { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", }, - { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", }, - { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, "3.2 MB 3\"1/2", }, - { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", }, - { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", }, - /* 720 kB 3"1/2 floppy disks */ - { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 1, "720 kB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, "800 kB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, "820 kB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, "830 kB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", }, - { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", }, - /* 1.2 MB 5"1/4 floppy disks */ - { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1, "1.2 kB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1, "1.6 MB 5\"1/4", }, - /* 720 kB 5"1/4 floppy disks */ - { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 80, 1, "720 kB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1, "880 kB 5\"1/4", }, - /* 360 kB 5"1/4 floppy disks */ - { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 1, "360 kB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 0, "180 kB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, "410 kB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, "420 kB 5\"1/4", }, - /* 320 kB 5"1/4 floppy disks */ - { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 1, "320 kB 5\"1/4", }, - { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 0, "160 kB 5\"1/4", }, - /* 360 kB must match 5"1/4 better than 3"1/2... */ - { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 0, "360 kB 3\"1/2", }, - /* end */ - { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, }, -}; - /* Revalidate a disk drive after a disk change */ static void fd_revalidate(FDrive *drv) { - const FDFormat *parse; - uint64_t nb_sectors, size; - int i, first_match, match; int nb_heads, max_track, last_sect, ro; + FDriveType drive; FLOPPY_DPRINTF("revalidate\n"); if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) { ro = bdrv_is_read_only(drv->bs); - bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect); + bdrv_get_floppy_geometry_hint(drv->bs, &nb_heads, &max_track, + &last_sect, drv->drive, &drive); if (nb_heads != 0 && max_track != 0 && last_sect != 0) { FLOPPY_DPRINTF("User defined disk (%d %d %d)", nb_heads - 1, max_track, last_sect); } else { - bdrv_get_geometry(drv->bs, &nb_sectors); - match = -1; - first_match = -1; - for (i = 0;; i++) { - parse = &fd_formats[i]; - if (parse->drive == FDRIVE_DRV_NONE) - break; - if (drv->drive == parse->drive || - drv->drive == FDRIVE_DRV_NONE) { - size = (parse->max_head + 1) * parse->max_track * - parse->last_sect; - if (nb_sectors == size) { - match = i; - break; - } - if (first_match == -1) - first_match = i; - } - } - if (match == -1) { - if (first_match == -1) - match = 1; - else - match = first_match; - parse = &fd_formats[match]; - } - nb_heads = parse->max_head + 1; - max_track = parse->max_track; - last_sect = parse->last_sect; - drv->drive = parse->drive; - FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str, - nb_heads, max_track, last_sect, ro ? "ro" : "rw"); + FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads, + max_track, last_sect, ro ? "ro" : "rw"); } if (nb_heads == 1) { drv->flags &= ~FDISK_DBL_SIDES; @@ -292,6 +190,7 @@ static void fd_revalidate(FDrive *drv) drv->max_track = max_track; drv->last_sect = last_sect; drv->ro = ro; + drv->drive = drive; } else { FLOPPY_DPRINTF("No disk in drive\n"); drv->last_sect = 0; @@ -303,6 +202,8 @@ static void fd_revalidate(FDrive *drv) /********************************************************/ /* Intel 82078 floppy disk controller emulation */ +typedef struct FDCtrl FDCtrl; + static void fdctrl_reset(FDCtrl *fdctrl, int do_irq); static void fdctrl_reset_fifo(FDCtrl *fdctrl); static int fdctrl_transfer_handler (void *opaque, int nchan, @@ -472,13 +373,13 @@ enum { #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT) struct FDCtrl { - /* Controller's identification */ - uint8_t version; - /* HW */ qemu_irq irq; - int dma_chann; /* Controller state */ QEMUTimer *result_timer; + int dma_chann; + /* Controller's identification */ + uint8_t version; + /* HW */ uint8_t sra; uint8_t srb; uint8_t dor; @@ -499,21 +400,21 @@ struct FDCtrl { uint8_t data_dir; uint8_t eot; /* last wanted sector */ /* States kept only to be returned back */ - /* Timers state */ - uint8_t timer0; - uint8_t timer1; /* precompensation */ uint8_t precomp_trk; uint8_t config; uint8_t lock; /* Power down config (also with status regB access mode */ uint8_t pwrd; - /* Sun4m quirks? */ - int sun4m; /* Floppy drives */ uint8_t num_floppies; + /* Sun4m quirks? */ + int sun4m; FDrive drives[MAX_FD]; int reset_sensei; + /* Timers state */ + uint8_t timer0; + uint8_t timer1; }; typedef struct FDCtrlSysBus { @@ -533,6 +434,7 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg) FDCtrl *fdctrl = opaque; uint32_t retval; + reg &= 7; switch (reg) { case FD_REG_SRA: retval = fdctrl_read_statusA(fdctrl); @@ -570,6 +472,7 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value) FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value); + reg &= 7; switch (reg) { case FD_REG_DOR: fdctrl_write_dor(fdctrl, value); @@ -588,16 +491,6 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value) } } -static uint32_t fdctrl_read_port (void *opaque, uint32_t reg) -{ - return fdctrl_read(opaque, reg & 7); -} - -static void fdctrl_write_port (void *opaque, uint32_t reg, uint32_t value) -{ - fdctrl_write(opaque, reg & 7, value); -} - static uint32_t fdctrl_read_mem (void *opaque, target_phys_addr_t reg) { return fdctrl_read(opaque, (uint32_t)reg); @@ -633,16 +526,42 @@ static CPUWriteMemoryFunc * const fdctrl_mem_write_strict[3] = { NULL, }; +static bool fdrive_media_changed_needed(void *opaque) +{ + FDrive *drive = opaque; + + return (drive->bs != NULL && drive->media_changed != 1); +} + +static const VMStateDescription vmstate_fdrive_media_changed = { + .name = "fdrive/media_changed", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(media_changed, FDrive), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_fdrive = { .name = "fdrive", .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, - .fields = (VMStateField []) { + .fields = (VMStateField[]) { VMSTATE_UINT8(head, FDrive), VMSTATE_UINT8(track, FDrive), VMSTATE_UINT8(sect, FDrive), VMSTATE_END_OF_LIST() + }, + .subsections = (VMStateSubsection[]) { + { + .vmsd = &vmstate_fdrive_media_changed, + .needed = &fdrive_media_changed_needed, + } , { + /* empty */ + } } }; @@ -728,12 +647,6 @@ static void fdctrl_handle_tc(void *opaque, int irq, int level) } } -/* XXX: may change if moved to bdrv */ -int fdctrl_get_drive_type(FDCtrl *fdctrl, int drive_num) -{ - return fdctrl->drives[drive_num].drive; -} - /* Change IRQ state */ static void fdctrl_reset_irq(FDCtrl *fdctrl) { @@ -976,7 +889,15 @@ static int fdctrl_media_changed(FDrive *drv) if (!drv->bs) return 0; - ret = bdrv_media_changed(drv->bs); + if (drv->media_changed) { + drv->media_changed = 0; + ret = 1; + } else { + ret = bdrv_media_changed(drv->bs); + if (ret < 0) { + ret = 0; /* we don't know, assume no */ + } + } if (ret) { fd_revalidate(drv); } @@ -1529,7 +1450,7 @@ static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction) /* XXX: should set main status register to busy */ cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; qemu_mod_timer(fdctrl->result_timer, - qemu_get_clock(vm_clock) + (get_ticks_per_sec() / 50)); + qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 50)); } static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction) @@ -1848,6 +1769,17 @@ static void fdctrl_result_timer(void *opaque) fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); } +static void fdctrl_change_cb(void *opaque, bool load) +{ + FDrive *drive = opaque; + + drive->media_changed = 1; +} + +static const BlockDevOps fdctrl_block_ops = { + .change_media_cb = fdctrl_change_cb, +}; + /* Init functions */ static int fdctrl_connect_drives(FDCtrl *fdctrl) { @@ -1871,29 +1803,15 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl) fd_init(drive); fd_revalidate(drive); if (drive->bs) { - bdrv_set_removable(drive->bs, 1); + drive->media_changed = 1; + bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive); } } return 0; } -FDCtrl *fdctrl_init_isa(DriveInfo **fds) -{ - ISADevice *dev; - - dev = isa_create("isa-fdc"); - if (fds[0]) { - qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv); - } - if (fds[1]) { - qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv); - } - qdev_init_nofail(&dev->qdev); - return &(DO_UPCAST(FDCtrlISABus, busdev, dev)->state); -} - -FDCtrl *fdctrl_init_sysbus(qemu_irq irq, int dma_chann, - target_phys_addr_t mmio_base, DriveInfo **fds) +void fdctrl_init_sysbus(qemu_irq irq, int dma_chann, + target_phys_addr_t mmio_base, DriveInfo **fds) { FDCtrl *fdctrl; DeviceState *dev; @@ -1912,16 +1830,13 @@ FDCtrl *fdctrl_init_sysbus(qemu_irq irq, int dma_chann, qdev_init_nofail(dev); sysbus_connect_irq(&sys->busdev, 0, irq); sysbus_mmio_map(&sys->busdev, 0, mmio_base); - - return fdctrl; } -FDCtrl *sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base, - DriveInfo **fds, qemu_irq *fdc_tc) +void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base, + DriveInfo **fds, qemu_irq *fdc_tc) { DeviceState *dev; FDCtrlSysBus *sys; - FDCtrl *fdctrl; dev = qdev_create(NULL, "SUNW,fdtwo"); if (fds[0]) { @@ -1929,12 +1844,9 @@ FDCtrl *sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base, } qdev_init_nofail(dev); sys = DO_UPCAST(FDCtrlSysBus, busdev.qdev, dev); - fdctrl = &sys->state; sysbus_connect_irq(&sys->busdev, 0, irq); sysbus_mmio_map(&sys->busdev, 0, io_base); *fdc_tc = qdev_get_gpio_in(dev, 0); - - return fdctrl; } static int fdctrl_init_common(FDCtrl *fdctrl) @@ -1957,7 +1869,7 @@ static int fdctrl_init_common(FDCtrl *fdctrl) FLOPPY_DPRINTF("init controller\n"); fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); fdctrl->fifo_size = 512; - fdctrl->result_timer = qemu_new_timer(vm_clock, + fdctrl->result_timer = qemu_new_timer_ns(vm_clock, fdctrl_result_timer, fdctrl); fdctrl->version = 0x90; /* Intel 82078 controller */ @@ -1969,6 +1881,12 @@ static int fdctrl_init_common(FDCtrl *fdctrl) return fdctrl_connect_drives(fdctrl); } +static const MemoryRegionPortio fdc_portio_list[] = { + { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write }, + { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write }, + PORTIO_END_OF_LIST(), +}; + static int isabus_fdc_init1(ISADevice *dev) { FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev); @@ -1978,16 +1896,7 @@ static int isabus_fdc_init1(ISADevice *dev) int dma_chann = 2; int ret; - register_ioport_read(iobase + 0x01, 5, 1, - &fdctrl_read_port, fdctrl); - register_ioport_read(iobase + 0x07, 1, 1, - &fdctrl_read_port, fdctrl); - register_ioport_write(iobase + 0x01, 5, 1, - &fdctrl_write_port, fdctrl); - register_ioport_write(iobase + 0x07, 1, 1, - &fdctrl_write_port, fdctrl); - isa_init_ioport_range(dev, iobase, 6); - isa_init_ioport(dev, iobase + 7); + isa_register_portio_list(dev, iobase, fdc_portio_list, fdctrl, "fdc"); isa_init_irq(&isa->busdev, &fdctrl->irq, isairq); fdctrl->dma_chann = dma_chann; @@ -2038,6 +1947,18 @@ static int sun4m_fdc_init1(SysBusDevice *dev) return fdctrl_init_common(fdctrl); } +void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev) +{ + FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev); + FDCtrl *fdctrl = &isa->state; + int i; + + for (i = 0; i < MAX_FD; i++) { + bs[i] = fdctrl->drives[i].bs; + } +} + + static const VMStateDescription vmstate_isa_fdc ={ .name = "fdc", .version_id = 2, diff --git a/hw/fdc.h b/hw/fdc.h index 242730a..506feb6 100644 --- a/hw/fdc.h +++ b/hw/fdc.h @@ -1,16 +1,36 @@ #ifndef HW_FDC_H #define HW_FDC_H +#include "isa.h" +#include "blockdev.h" + /* fdc.c */ #define MAX_FD 2 -typedef struct FDCtrl FDCtrl; +static inline ISADevice *fdctrl_init_isa(DriveInfo **fds) +{ + ISADevice *dev; + + dev = isa_try_create("isa-fdc"); + if (!dev) { + return NULL; + } + + if (fds[0]) { + qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv); + } + if (fds[1]) { + qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv); + } + qdev_init_nofail(&dev->qdev); + + return dev; +} -FDCtrl *fdctrl_init_isa(DriveInfo **fds); -FDCtrl *fdctrl_init_sysbus(qemu_irq irq, int dma_chann, - target_phys_addr_t mmio_base, DriveInfo **fds); -FDCtrl *sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base, - DriveInfo **fds, qemu_irq *fdc_tc); -int fdctrl_get_drive_type(FDCtrl *fdctrl, int drive_num); +void fdctrl_init_sysbus(qemu_irq irq, int dma_chann, + target_phys_addr_t mmio_base, DriveInfo **fds); +void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base, + DriveInfo **fds, qemu_irq *fdc_tc); +void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev); #endif diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h deleted file mode 100644 index 126e60e..0000000 --- a/hw/file-op-9p.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Virtio 9p - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Aneesh Kumar K.V - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ -#ifndef _FILEOP_H -#define _FILEOP_H -#include -#include -#include -#include -#include -#include -#include -#define SM_LOCAL_MODE_BITS 0600 -#define SM_LOCAL_DIR_MODE_BITS 0700 - -typedef enum -{ - /* - * Server will try to set uid/gid. - * On failure ignore the error. - */ - SM_NONE = 0, - /* - * uid/gid set on fileserver files - */ - SM_PASSTHROUGH = 1, - /* - * uid/gid part of xattr - */ - SM_MAPPED, -} SecModel; - -typedef struct FsCred -{ - uid_t fc_uid; - gid_t fc_gid; - mode_t fc_mode; - dev_t fc_rdev; -} FsCred; - -struct xattr_operations; - -typedef struct FsContext -{ - char *fs_root; - SecModel fs_sm; - uid_t uid; - struct xattr_operations **xops; -} FsContext; - -void cred_init(FsCred *); - -typedef struct FileOperations -{ - int (*lstat)(FsContext *, const char *, struct stat *); - ssize_t (*readlink)(FsContext *, const char *, char *, size_t); - int (*chmod)(FsContext *, const char *, FsCred *); - int (*chown)(FsContext *, const char *, FsCred *); - int (*mknod)(FsContext *, const char *, FsCred *); - int (*utimensat)(FsContext *, const char *, const struct timespec *); - int (*remove)(FsContext *, const char *); - int (*symlink)(FsContext *, const char *, const char *, FsCred *); - int (*link)(FsContext *, const char *, const char *); - int (*setuid)(FsContext *, uid_t); - int (*close)(FsContext *, int); - int (*closedir)(FsContext *, DIR *); - DIR *(*opendir)(FsContext *, const char *); - int (*open)(FsContext *, const char *, int); - int (*open2)(FsContext *, const char *, int, FsCred *); - void (*rewinddir)(FsContext *, DIR *); - off_t (*telldir)(FsContext *, DIR *); - struct dirent *(*readdir)(FsContext *, DIR *); - void (*seekdir)(FsContext *, DIR *, off_t); - ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t); - ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t); - int (*mkdir)(FsContext *, const char *, FsCred *); - int (*fstat)(FsContext *, int, struct stat *); - int (*rename)(FsContext *, const char *, const char *); - int (*truncate)(FsContext *, const char *, off_t); - int (*fsync)(FsContext *, int, int); - int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf); - ssize_t (*lgetxattr)(FsContext *, const char *, - const char *, void *, size_t); - ssize_t (*llistxattr)(FsContext *, const char *, void *, size_t); - int (*lsetxattr)(FsContext *, const char *, - const char *, void *, size_t, int); - int (*lremovexattr)(FsContext *, const char *, const char *); - void *opaque; -} FileOperations; - -static inline const char *rpath(FsContext *ctx, const char *path) -{ - /* FIXME: so wrong... */ - static char buffer[4096]; - snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path); - return buffer; -} -#endif diff --git a/hw/flash.h b/hw/flash.h index d7d103e..9c9e526 100644 --- a/hw/flash.h +++ b/hw/flash.h @@ -1,15 +1,22 @@ /* NOR flash devices */ + +#include "memory.h" + typedef struct pflash_t pflash_t; /* pflash_cfi01.c */ -pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi01_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, uint16_t id2, uint16_t id3, int be); /* pflash_cfi02.c */ -pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi02_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, uint16_t id0, uint16_t id1, @@ -17,15 +24,16 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, uint16_t unlock_addr0, uint16_t unlock_addr1, int be); +MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl); + /* nand.c */ -typedef struct NANDFlashState NANDFlashState; -NANDFlashState *nand_init(int manf_id, int chip_id); -void nand_done(NANDFlashState *s); -void nand_setpins(NANDFlashState *s, - int cle, int ale, int ce, int wp, int gnd); -void nand_getpins(NANDFlashState *s, int *rb); -void nand_setio(NANDFlashState *s, uint8_t value); -uint8_t nand_getio(NANDFlashState *s); +DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id); +void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale, + uint8_t ce, uint8_t wp, uint8_t gnd); +void nand_getpins(DeviceState *dev, int *rb); +void nand_setio(DeviceState *dev, uint32_t value); +uint32_t nand_getio(DeviceState *dev); +uint32_t nand_getbuswidth(DeviceState *dev); #define NAND_MFR_TOSHIBA 0x98 #define NAND_MFR_SAMSUNG 0xec @@ -37,10 +45,7 @@ uint8_t nand_getio(NANDFlashState *s); #define NAND_MFR_MICRON 0x2c /* onenand.c */ -void onenand_base_update(void *opaque, target_phys_addr_t new); -void onenand_base_unmap(void *opaque); -void *onenand_init(uint32_t id, int regshift, qemu_irq irq); -void *onenand_raw_otp(void *opaque); +void *onenand_raw_otp(DeviceState *onenand_device); /* ecc.c */ typedef struct { diff --git a/hw/fmopl.c b/hw/fmopl.c index 3df1806..5ad52ab 100644 --- a/hw/fmopl.c +++ b/hw/fmopl.c @@ -45,6 +45,10 @@ #define PI 3.14159265358979323846 #endif +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + /* -------------------- for debug --------------------- */ /* #define OPL_OUTPUT_LOG */ #ifdef OPL_OUTPUT_LOG @@ -595,14 +599,14 @@ static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE ) OPL->AR_TABLE[i] = rate / ARRATE; OPL->DR_TABLE[i] = rate / DRRATE; } - for (i = 60;i < 76;i++) + for (i = 60; i < ARRAY_SIZE(OPL->AR_TABLE); i++) { OPL->AR_TABLE[i] = EG_AED-1; OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; } #if 0 for (i = 0;i < 64 ;i++){ /* make for overflow area */ - LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i, + LOG(LOG_WAR, ("rate %2d , ar %f ms , dr %f ms\n", i, ((double)(EG_ENT<AR_TABLE[i]) * (1000.0 / OPL->rate), ((double)(EG_ENT<DR_TABLE[i]) * (1000.0 / OPL->rate) )); } diff --git a/hw/framebuffer.c b/hw/framebuffer.c index 24cdf25..56cf16e 100644 --- a/hw/framebuffer.c +++ b/hw/framebuffer.c @@ -78,6 +78,9 @@ void framebuffer_update_display( dest = ds_get_data(ds); if (dest_col_pitch < 0) dest -= dest_col_pitch * (cols - 1); + if (dest_row_pitch < 0) { + dest -= dest_row_pitch * (rows - 1); + } first = -1; addr = pd; diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c index 85c8c3c..dbcb888 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -26,6 +26,7 @@ #include "isa.h" #include "fw_cfg.h" #include "sysbus.h" +#include "qemu-error.h" /* debug firmware config */ //#define DEBUG_FW_CFG @@ -56,6 +57,130 @@ struct FWCfgState { Notifier machine_ready; }; +#define JPG_FILE 0 +#define BMP_FILE 1 + +static char *read_splashfile(char *filename, int *file_sizep, int *file_typep) +{ + GError *err = NULL; + gboolean res; + gchar *content; + int file_type = -1; + unsigned int filehead = 0; + int bmp_bpp; + + res = g_file_get_contents(filename, &content, (gsize *)file_sizep, &err); + if (res == FALSE) { + error_report("failed to read splash file '%s'", filename); + g_error_free(err); + return NULL; + } + + /* check file size */ + if (*file_sizep < 30) { + goto error; + } + + /* check magic ID */ + filehead = ((content[0] & 0xff) + (content[1] << 8)) & 0xffff; + if (filehead == 0xd8ff) { + file_type = JPG_FILE; + } else if (filehead == 0x4d42) { + file_type = BMP_FILE; + } else { + goto error; + } + + /* check BMP bpp */ + if (file_type == BMP_FILE) { + bmp_bpp = (content[28] + (content[29] << 8)) & 0xffff; + if (bmp_bpp != 24) { + goto error; + } + } + + /* return values */ + *file_typep = file_type; + + return content; + +error: + error_report("splash file '%s' format not recognized; must be JPEG " + "or 24 bit BMP", filename); + g_free(content); + return NULL; +} + +static void fw_cfg_bootsplash(FWCfgState *s) +{ + int boot_splash_time = -1; + const char *boot_splash_filename = NULL; + char *p; + char *filename, *file_data; + int file_size; + int file_type = -1; + const char *temp; + + /* get user configuration */ + QemuOptsList *plist = qemu_find_opts("boot-opts"); + QemuOpts *opts = QTAILQ_FIRST(&plist->head); + if (opts != NULL) { + temp = qemu_opt_get(opts, "splash"); + if (temp != NULL) { + boot_splash_filename = temp; + } + temp = qemu_opt_get(opts, "splash-time"); + if (temp != NULL) { + p = (char *)temp; + boot_splash_time = strtol(p, (char **)&p, 10); + } + } + + /* insert splash time if user configurated */ + if (boot_splash_time >= 0) { + /* validate the input */ + if (boot_splash_time > 0xffff) { + error_report("splash time is big than 65535, force it to 65535."); + boot_splash_time = 0xffff; + } + /* use little endian format */ + qemu_extra_params_fw[0] = (uint8_t)(boot_splash_time & 0xff); + qemu_extra_params_fw[1] = (uint8_t)((boot_splash_time >> 8) & 0xff); + fw_cfg_add_file(s, "etc/boot-menu-wait", qemu_extra_params_fw, 2); + } + + /* insert splash file if user configurated */ + if (boot_splash_filename != NULL) { + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, boot_splash_filename); + if (filename == NULL) { + error_report("failed to find file '%s'.", boot_splash_filename); + return; + } + + /* loading file data */ + file_data = read_splashfile(filename, &file_size, &file_type); + if (file_data == NULL) { + g_free(filename); + return; + } + if (boot_splash_filedata != NULL) { + g_free(boot_splash_filedata); + } + boot_splash_filedata = (uint8_t *)file_data; + boot_splash_filedata_size = file_size; + + /* insert data */ + if (file_type == JPG_FILE) { + fw_cfg_add_file(s, "bootsplash.jpg", + boot_splash_filedata, boot_splash_filedata_size); + } else { + fw_cfg_add_file(s, "bootsplash.bmp", + boot_splash_filedata, boot_splash_filedata_size); + } + g_free(filename); + } +} + static void fw_cfg_write(FWCfgState *s, uint8_t value) { int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); @@ -63,7 +188,8 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value) FW_CFG_DPRINTF("write %d\n", value); - if (s->cur_entry & FW_CFG_WRITE_CHANNEL && s->cur_offset < e->len) { + if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback && + s->cur_offset < e->len) { e->data[s->cur_offset++] = value; if (s->cur_offset == e->len) { e->callback(e->callback_opaque, e->data); @@ -234,7 +360,7 @@ int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value) { uint16_t *copy; - copy = qemu_malloc(sizeof(value)); + copy = g_malloc(sizeof(value)); *copy = cpu_to_le16(value); return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value)); } @@ -243,7 +369,7 @@ int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value) { uint32_t *copy; - copy = qemu_malloc(sizeof(value)); + copy = g_malloc(sizeof(value)); *copy = cpu_to_le32(value); return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value)); } @@ -252,7 +378,7 @@ int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value) { uint64_t *copy; - copy = qemu_malloc(sizeof(value)); + copy = g_malloc(sizeof(value)); *copy = cpu_to_le64(value); return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value)); } @@ -285,7 +411,7 @@ int fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data, if (!s->files) { int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS; - s->files = qemu_mallocz(dsize); + s->files = g_malloc0(dsize); fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, (uint8_t*)s->files, dsize); } @@ -316,7 +442,7 @@ int fw_cfg_add_file(FWCfgState *s, const char *filename, uint8_t *data, return 1; } -static void fw_cfg_machine_ready(struct Notifier* n) +static void fw_cfg_machine_ready(struct Notifier *n, void *data) { uint32_t len; FWCfgState *s = container_of(n, FWCfgState, machine_ready); @@ -352,7 +478,7 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu); - + fw_cfg_bootsplash(s); s->machine_ready.notify = fw_cfg_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); diff --git a/hw/g364fb.c b/hw/g364fb.c index a41e988..f00ee27 100644 --- a/hw/g364fb.c +++ b/hw/g364fb.c @@ -1,7 +1,7 @@ /* * QEMU G364 framebuffer Emulator. * - * Copyright (c) 2007-2009 Herve Poussineau + * Copyright (c) 2007-2011 Herve Poussineau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -18,27 +18,18 @@ */ #include "hw.h" -#include "mips.h" #include "console.h" #include "pixel_ops.h" - -//#define DEBUG_G364 - -#ifdef DEBUG_G364 -#define DPRINTF(fmt, ...) \ -do { printf("g364: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while (0) -#endif -#define BADF(fmt, ...) \ -do { fprintf(stderr, "g364 ERROR: " fmt , ## __VA_ARGS__);} while (0) +#include "trace.h" +#include "sysbus.h" typedef struct G364State { /* hardware */ uint8_t *vram; - ram_addr_t vram_offset; - int vram_size; + uint32_t vram_size; qemu_irq irq; + MemoryRegion mem_vram; + MemoryRegion mem_ctrl; /* registers */ uint8_t color_palette[256][3]; uint8_t cursor_palette[3][3]; @@ -53,31 +44,34 @@ typedef struct G364State { int blanked; } G364State; -#define REG_ID 0x000000 -#define REG_BOOT 0x080000 -#define REG_DISPLAY 0x080118 -#define REG_VDISPLAY 0x080150 -#define REG_CTLA 0x080300 -#define REG_TOP 0x080400 -#define REG_CURS_PAL 0x080508 -#define REG_CURS_POS 0x080638 -#define REG_CLR_PAL 0x080800 -#define REG_CURS_PAT 0x081000 -#define REG_RESET 0x180000 +#define REG_BOOT 0x000000 +#define REG_DISPLAY 0x000118 +#define REG_VDISPLAY 0x000150 +#define REG_CTLA 0x000300 +#define REG_TOP 0x000400 +#define REG_CURS_PAL 0x000508 +#define REG_CURS_POS 0x000638 +#define REG_CLR_PAL 0x000800 +#define REG_CURS_PAT 0x001000 +#define REG_RESET 0x100000 #define CTLA_FORCE_BLANK 0x00000400 #define CTLA_NO_CURSOR 0x00800000 -static inline int check_dirty(ram_addr_t page) +#define G364_PAGE_SIZE 4096 + +static inline int check_dirty(G364State *s, ram_addr_t page) { - return cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG); + return memory_region_get_dirty(&s->mem_vram, page, DIRTY_MEMORY_VGA); } static inline void reset_dirty(G364State *s, ram_addr_t page_min, ram_addr_t page_max) { - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE - 1, - VGA_DIRTY_FLAG); + memory_region_reset_dirty(&s->mem_vram, + page_min, + page_max + G364_PAGE_SIZE - page_min - 1, + DIRTY_MEMORY_VGA); } static void g364fb_draw_graphic8(G364State *s) @@ -110,11 +104,12 @@ static void g364fb_draw_graphic8(G364State *s) w = 4; break; default: - BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds)); + hw_error("g364: unknown host depth %d", + ds_get_bits_per_pixel(s->ds)); return; } - page = s->vram_offset; + page = 0; page_min = (ram_addr_t)-1; page_max = 0; @@ -135,7 +130,7 @@ static void g364fb_draw_graphic8(G364State *s) /* XXX: out of range in vram? */ data_display = dd = ds_get_data(s->ds); while (y < s->height) { - if (check_dirty(page)) { + if (check_dirty(s, page)) { if (y < ymin) ymin = ymax = y; if (page_min == (ram_addr_t)-1) @@ -143,7 +138,7 @@ static void g364fb_draw_graphic8(G364State *s) page_max = page; if (x < xmin) xmin = x; - for (i = 0; i < TARGET_PAGE_SIZE; i++) { + for (i = 0; i < G364_PAGE_SIZE; i++) { uint8_t index; unsigned int color; if (unlikely((y >= ycursor && y < ycursor + 64) && @@ -207,15 +202,15 @@ static void g364fb_draw_graphic8(G364State *s) ymin = s->height; ymax = 0; } - x += TARGET_PAGE_SIZE; + x += G364_PAGE_SIZE; dy = x / s->width; x = x % s->width; y += dy; - vram += TARGET_PAGE_SIZE; + vram += G364_PAGE_SIZE; data_display += dy * ds_get_linesize(s->ds); dd = data_display + x * w; } - page += TARGET_PAGE_SIZE; + page += G364_PAGE_SIZE; } done: @@ -250,6 +245,8 @@ static void g364fb_update_display(void *opaque) { G364State *s = opaque; + qemu_flush_coalesced_mmio_buffer(); + if (s->width == 0 || s->height == 0) return; @@ -262,7 +259,7 @@ static void g364fb_update_display(void *opaque) } else if (s->depth == 8) { g364fb_draw_graphic8(s); } else { - BADF("unknown guest depth %d\n", s->depth); + error_report("g364: unknown guest depth %d", s->depth); } qemu_irq_raise(s->irq); @@ -274,14 +271,13 @@ static inline void g364fb_invalidate_display(void *opaque) int i; s->blanked = 0; - for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) { - cpu_physical_memory_set_dirty(s->vram_offset + i); + for (i = 0; i < s->vram_size; i += G364_PAGE_SIZE) { + memory_region_set_dirty(&s->mem_vram, i); } } -static void g364fb_reset(void *opaque) +static void g364fb_reset(G364State *s) { - G364State *s = opaque; qemu_irq_lower(s->irq); memset(s->color_palette, 0, sizeof(s->color_palette)); @@ -292,7 +288,7 @@ static void g364fb_reset(void *opaque) s->top_of_screen = 0; s->width = s->height = 0; memset(s->vram, 0, s->vram_size); - g364fb_invalidate_display(opaque); + g364fb_invalidate_display(s); } static void g364fb_screen_dump(void *opaque, const char *filename) @@ -303,8 +299,10 @@ static void g364fb_screen_dump(void *opaque, const char *filename) uint8_t *data_buffer; FILE *f; + qemu_flush_coalesced_mmio_buffer(); + if (s->depth != 8) { - BADF("unknown guest depth %d\n", s->depth); + error_report("g364: unknown guest depth %d", s->depth); return; } @@ -336,7 +334,9 @@ static void g364fb_screen_dump(void *opaque, const char *filename) } /* called for accesses to io ports */ -static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr) +static uint64_t g364fb_ctrl_read(void *opaque, + target_phys_addr_t addr, + unsigned int size) { G364State *s = opaque; uint32_t val; @@ -353,9 +353,6 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr) val |= ((uint32_t)s->cursor_palette[idx][2] << 0); } else { switch (addr) { - case REG_ID: - val = 0x10; /* Mips G364 */ - break; case REG_DISPLAY: val = s->width / 4; break; @@ -367,33 +364,19 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr) break; default: { - BADF("invalid read at [" TARGET_FMT_plx "]\n", addr); + error_report("g364: invalid read at [" TARGET_FMT_plx "]", + addr); val = 0; break; } } } - DPRINTF("read 0x%08x at [" TARGET_FMT_plx "]\n", val, addr); + trace_g364fb_read(addr, val); return val; } -static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3); - if (addr & 0x2) - return v >> 16; - else - return v & 0xffff; -} - -static uint32_t g364fb_ctrl_readb(void *opaque, target_phys_addr_t addr) -{ - uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3); - return (v >> (8 * (addr & 0x3))) & 0xff; -} - static void g364fb_update_depth(G364State *s) { static const int depths[8] = { 1, 2, 4, 8, 15, 16, 0 }; @@ -410,16 +393,19 @@ static void g364_invalidate_cursor_position(G364State *s) start = ymin * ds_get_linesize(s->ds); end = (ymax + 1) * ds_get_linesize(s->ds); - for (i = start; i < end; i += TARGET_PAGE_SIZE) { - cpu_physical_memory_set_dirty(s->vram_offset + i); + for (i = start; i < end; i += G364_PAGE_SIZE) { + memory_region_set_dirty(&s->mem_vram, i); } } -static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +static void g364fb_ctrl_write(void *opaque, + target_phys_addr_t addr, + uint64_t val, + unsigned int size) { G364State *s = opaque; - DPRINTF("write 0x%08x at [" TARGET_FMT_plx "]\n", val, addr); + trace_g364fb_write(addr, val); if (addr >= REG_CLR_PAL && addr < REG_CLR_PAL + 0x800) { /* color palette */ @@ -442,120 +428,65 @@ static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t v g364fb_invalidate_display(s); } else { switch (addr) { - case REG_ID: /* Card identifier; read-only */ - case REG_BOOT: /* Boot timing */ - case 0x80108: /* Line timing: half sync */ - case 0x80110: /* Line timing: back porch */ - case 0x80120: /* Line timing: short display */ - case 0x80128: /* Frame timing: broad pulse */ - case 0x80130: /* Frame timing: v sync */ - case 0x80138: /* Frame timing: v preequalise */ - case 0x80140: /* Frame timing: v postequalise */ - case 0x80148: /* Frame timing: v blank */ - case 0x80158: /* Line timing: line time */ - case 0x80160: /* Frame store: line start */ - case 0x80168: /* vram cycle: mem init */ - case 0x80170: /* vram cycle: transfer delay */ - case 0x80200: /* vram cycle: mask register */ - /* ignore */ - break; - case REG_TOP: - s->top_of_screen = val; - g364fb_invalidate_display(s); - break; - case REG_DISPLAY: - s->width = val * 4; - break; - case REG_VDISPLAY: - s->height = val / 2; - break; - case REG_CTLA: - s->ctla = val; - g364fb_update_depth(s); - g364fb_invalidate_display(s); - break; - case REG_CURS_POS: - g364_invalidate_cursor_position(s); - s->cursor_position = val; - g364_invalidate_cursor_position(s); - break; - case REG_RESET: - g364fb_reset(s); - break; - default: - BADF("invalid write of 0x%08x at [" TARGET_FMT_plx "]\n", val, addr); - break; + case REG_BOOT: /* Boot timing */ + case 0x00108: /* Line timing: half sync */ + case 0x00110: /* Line timing: back porch */ + case 0x00120: /* Line timing: short display */ + case 0x00128: /* Frame timing: broad pulse */ + case 0x00130: /* Frame timing: v sync */ + case 0x00138: /* Frame timing: v preequalise */ + case 0x00140: /* Frame timing: v postequalise */ + case 0x00148: /* Frame timing: v blank */ + case 0x00158: /* Line timing: line time */ + case 0x00160: /* Frame store: line start */ + case 0x00168: /* vram cycle: mem init */ + case 0x00170: /* vram cycle: transfer delay */ + case 0x00200: /* vram cycle: mask register */ + /* ignore */ + break; + case REG_TOP: + s->top_of_screen = val; + g364fb_invalidate_display(s); + break; + case REG_DISPLAY: + s->width = val * 4; + break; + case REG_VDISPLAY: + s->height = val / 2; + break; + case REG_CTLA: + s->ctla = val; + g364fb_update_depth(s); + g364fb_invalidate_display(s); + break; + case REG_CURS_POS: + g364_invalidate_cursor_position(s); + s->cursor_position = val; + g364_invalidate_cursor_position(s); + break; + case REG_RESET: + g364fb_reset(s); + break; + default: + error_report("g364: invalid write of 0x%" PRIx64 + " at [" TARGET_FMT_plx "]", val, addr); + break; } } qemu_irq_lower(s->irq); } -static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3); - - if (addr & 0x2) - val = (val << 16) | (old_val & 0x0000ffff); - else - val = val | (old_val & 0xffff0000); - g364fb_ctrl_writel(opaque, addr & ~0x3, val); -} - -static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3); - - switch (addr & 3) { - case 0: - val = val | (old_val & 0xffffff00); - break; - case 1: - val = (val << 8) | (old_val & 0xffff00ff); - break; - case 2: - val = (val << 16) | (old_val & 0xff00ffff); - break; - case 3: - val = (val << 24) | (old_val & 0x00ffffff); - break; - } - g364fb_ctrl_writel(opaque, addr & ~0x3, val); -} - -static CPUReadMemoryFunc * const g364fb_ctrl_read[3] = { - g364fb_ctrl_readb, - g364fb_ctrl_readw, - g364fb_ctrl_readl, +static const MemoryRegionOps g364fb_ctrl_ops = { + .read = g364fb_ctrl_read, + .write = g364fb_ctrl_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .impl.max_access_size = 4, }; -static CPUWriteMemoryFunc * const g364fb_ctrl_write[3] = { - g364fb_ctrl_writeb, - g364fb_ctrl_writew, - g364fb_ctrl_writel, -}; - -static int g364fb_load(QEMUFile *f, void *opaque, int version_id) +static int g364fb_post_load(void *opaque, int version_id) { G364State *s = opaque; - unsigned int i, vram_size; - - if (version_id != 1) - return -EINVAL; - - vram_size = qemu_get_be32(f); - if (vram_size < s->vram_size) - return -EINVAL; - qemu_get_buffer(f, s->vram, s->vram_size); - for (i = 0; i < 256; i++) - qemu_get_buffer(f, s->color_palette[i], 3); - for (i = 0; i < 3; i++) - qemu_get_buffer(f, s->cursor_palette[i], 3); - qemu_get_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor)); - s->cursor_position = qemu_get_be32(f); - s->ctla = qemu_get_be32(f); - s->top_of_screen = qemu_get_be32(f); - s->width = qemu_get_be32(f); - s->height = qemu_get_be32(f); /* force refresh */ g364fb_update_depth(s); @@ -564,52 +495,80 @@ static int g364fb_load(QEMUFile *f, void *opaque, int version_id) return 0; } -static void g364fb_save(QEMUFile *f, void *opaque) -{ - G364State *s = opaque; - int i; - - qemu_put_be32(f, s->vram_size); - qemu_put_buffer(f, s->vram, s->vram_size); - for (i = 0; i < 256; i++) - qemu_put_buffer(f, s->color_palette[i], 3); - for (i = 0; i < 3; i++) - qemu_put_buffer(f, s->cursor_palette[i], 3); - qemu_put_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor)); - qemu_put_be32(f, s->cursor_position); - qemu_put_be32(f, s->ctla); - qemu_put_be32(f, s->top_of_screen); - qemu_put_be32(f, s->width); - qemu_put_be32(f, s->height); -} +static const VMStateDescription vmstate_g364fb = { + .name = "g364fb", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = g364fb_post_load, + .fields = (VMStateField[]) { + VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, 0, vram_size), + VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3), + VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9), + VMSTATE_UINT16_ARRAY(cursor, G364State, 512), + VMSTATE_UINT32(cursor_position, G364State), + VMSTATE_UINT32(ctla, G364State), + VMSTATE_UINT32(top_of_screen, G364State), + VMSTATE_UINT32(width, G364State), + VMSTATE_UINT32(height, G364State), + VMSTATE_END_OF_LIST() + } +}; -int g364fb_mm_init(target_phys_addr_t vram_base, - target_phys_addr_t ctrl_base, int it_shift, - qemu_irq irq) +static void g364fb_init(DeviceState *dev, G364State *s) { - G364State *s; - int io_ctrl; - - s = qemu_mallocz(sizeof(G364State)); - - s->vram_size = 8 * 1024 * 1024; - s->vram_offset = qemu_ram_alloc(NULL, "g364fb.vram", s->vram_size); - s->vram = qemu_get_ram_ptr(s->vram_offset); - s->irq = irq; - - qemu_register_reset(g364fb_reset, s); - register_savevm(NULL, "g364fb", 0, 1, g364fb_save, g364fb_load, s); - g364fb_reset(s); + s->vram = g_malloc0(s->vram_size); s->ds = graphic_console_init(g364fb_update_display, g364fb_invalidate_display, g364fb_screen_dump, NULL, s); - cpu_register_physical_memory(vram_base, s->vram_size, s->vram_offset); + memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000); + memory_region_init_ram_ptr(&s->mem_vram, dev, "vram", + s->vram_size, s->vram); + memory_region_set_coalescing(&s->mem_vram); +} - io_ctrl = cpu_register_io_memory(g364fb_ctrl_read, g364fb_ctrl_write, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(ctrl_base, 0x200000, io_ctrl); +typedef struct { + SysBusDevice busdev; + G364State g364; +} G364SysBusState; + +static int g364fb_sysbus_init(SysBusDevice *dev) +{ + G364State *s = &FROM_SYSBUS(G364SysBusState, dev)->g364; + + g364fb_init(&dev->qdev, s); + sysbus_init_irq(dev, &s->irq); + sysbus_init_mmio_region(dev, &s->mem_ctrl); + sysbus_init_mmio_region(dev, &s->mem_vram); return 0; } + +static void g364fb_sysbus_reset(DeviceState *d) +{ + G364SysBusState *s = DO_UPCAST(G364SysBusState, busdev.qdev, d); + g364fb_reset(&s->g364); +} + +static SysBusDeviceInfo g364fb_sysbus_info = { + .init = g364fb_sysbus_init, + .qdev.name = "sysbus-g364", + .qdev.desc = "G364 framebuffer", + .qdev.size = sizeof(G364SysBusState), + .qdev.vmsd = &vmstate_g364fb, + .qdev.reset = g364fb_sysbus_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size, + 8 * 1024 * 1024), + DEFINE_PROP_END_OF_LIST(), + } +}; + +static void g364fb_register(void) +{ + sysbus_register_withprop(&g364fb_sysbus_info); +} + +device_init(g364fb_register); diff --git a/hw/gles1_calls.c b/hw/gles1_calls.c deleted file mode 100644 index 7bd2cd3..0000000 --- a/hw/gles1_calls.c +++ /dev/null @@ -1,1396 +0,0 @@ -/* GLES v1 implementation. - * - * Copyright (c) 2010 Samsung Electronics. - * - * 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 or - * (at your option) any later version of the License. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - */ - -#include "gles2.h" -#include "EGL/degl.h" -#include "GLES/gl.h" - -#include "gles2_types.h" - - -#define gles1_count_glClipPlanef 4 -#define gles1_count_glClipPlanex 4 -#define gles1_count_glLoadMatrixf 16 -#define gles1_count_glLoadMatrixx 16 -#define gles1_count_glMultMatrixf 16 -#define gles1_count_glMultMatrixx 16 - - -// Numbers from c->array's end -#define gles1_num_glColorPointer 1 -#define gles1_num_glNormalPointer 2 -#define gles1_num_glTexCoordPointer 3 -#define gles1_num_glVertexPointer 4 - -#define gles1_size_glNormalPointer 3 - -//for debug only -void checkGLESError(void) -{ - GLenum error; - if ((error = glGetError()) != 0) { - GLES2_PRINT("Error after call 0x%x!\n", error); - } - else { - GLES2_PRINT("Ok after call!\n"); - } -} - -static void gles1_apply_glColorPointer(gles2_Array *va) -{ - glColorPointer(va->size, va->type, - va->real_stride, va->ptr); - GLenum error; - - if ((error = glGetError()) != GL_NO_ERROR) { - GLES2_PRINT("glColorPointer(%d, 0x%x, %d, %p\n)" - " failed with 0x%x!\n", va->size, va->type, - va->stride, va->ptr, error); - } -} - -static void gles1_apply_glNormalPointer(gles2_Array *va) -{ - glNormalPointer(va->type, va->real_stride, va->ptr); - GLenum error; - - if ((error = glGetError()) != GL_NO_ERROR) { - GLES2_PRINT("glNormalPointer(0x%x, %d, %p\n)" - " failed with 0x%x!\n", va->type, - va->stride, va->ptr, error); - } -} - -static void gles1_apply_glTexCoordPointer(gles2_Array *va) -{ - glTexCoordPointer(va->size, va->type, - va->real_stride, va->ptr); - GLenum error; - - if ((error = glGetError()) != GL_NO_ERROR) { - GLES2_PRINT("glTexCoordPointer(%d, 0x%x, %d, %p\n)" - " failed with 0x%x!\n", va->size, va->type, - va->stride, va->ptr, error); - } -} - -static void gles1_apply_glVertexPointer(gles2_Array *va) -{ - glVertexPointer(va->size, va->type, - va->real_stride, va->ptr); - GLenum error; - - if ((error = glGetError()) != GL_NO_ERROR) { - GLES2_PRINT("glVertexPointer(%d, 0x%x, %d, %p\n)" - " failed with 0x%x!\n", va->size, va->type, - va->stride, va->ptr, error); - } -} - - -unsigned gles1_glGetCount(TGLenum pname) -{ - unsigned count; - switch(pname) { - case GL_MAX_TEXTURE_UNITS: - - case GL_ALPHA_BITS: - case GL_ALPHA_SCALE: - case GL_ALPHA_TEST: - case GL_ALPHA_TEST_FUNC: - case GL_ALPHA_TEST_REF: - case GL_BLEND: - case GL_BLEND_DST: - case GL_BLEND_SRC: - case GL_BLUE_BITS: - case GL_CLIP_PLANE0: - case GL_CLIP_PLANE1: - case GL_CLIP_PLANE2: - case GL_CLIP_PLANE3: - case GL_CLIP_PLANE4: - case GL_CLIP_PLANE5: - case GL_COLOR_MATERIAL: - case GL_CULL_FACE: - case GL_CULL_FACE_MODE: - case GL_DEPTH_BITS: - case GL_DEPTH_CLEAR_VALUE: - case GL_DEPTH_FUNC: - case GL_DEPTH_TEST: - case GL_DEPTH_WRITEMASK: - case GL_DITHER: - case GL_FOG: - case GL_FOG_DENSITY: - case GL_FOG_END: - case GL_FOG_HINT: - case GL_FOG_MODE: - case GL_FOG_START: - case GL_FRONT_FACE: - case GL_GREEN_BITS: - case GL_LIGHT0: - case GL_LIGHT1: - case GL_LIGHT2: - case GL_LIGHT3: - case GL_LIGHT4: - case GL_LIGHT5: - case GL_LIGHT6: - case GL_LIGHT7: - case GL_LIGHTING: - case GL_LIGHT_MODEL_TWO_SIDE: - case GL_LINE_SMOOTH: - case GL_LINE_SMOOTH_HINT: - case GL_LINE_WIDTH: - case GL_COLOR_LOGIC_OP: - case GL_LOGIC_OP_MODE: - case GL_MATRIX_MODE: - case GL_MAX_CLIP_PLANES: - case GL_MAX_LIGHTS: - case GL_MAX_MODELVIEW_STACK_DEPTH: - case GL_MAX_PROJECTION_STACK_DEPTH: - case GL_MAX_TEXTURE_SIZE: - case GL_MAX_TEXTURE_STACK_DEPTH: - case GL_MODELVIEW_STACK_DEPTH: - case GL_NORMALIZE: - case GL_PACK_ALIGNMENT: - case GL_PERSPECTIVE_CORRECTION_HINT: - case GL_POINT_SIZE: - case GL_POINT_SMOOTH: - case GL_POINT_SMOOTH_HINT: - case GL_POLYGON_OFFSET_FACTOR: - case GL_POLYGON_OFFSET_UNITS: - case GL_POLYGON_OFFSET_FILL: - case GL_PROJECTION_STACK_DEPTH: - case GL_RED_BITS: - case GL_RESCALE_NORMAL: - case GL_SCISSOR_TEST: - case GL_SHADE_MODEL: - case GL_STENCIL_BITS: - case GL_STENCIL_CLEAR_VALUE: - case GL_STENCIL_FAIL: - case GL_STENCIL_FUNC: - case GL_STENCIL_PASS_DEPTH_FAIL: - case GL_STENCIL_PASS_DEPTH_PASS: - case GL_STENCIL_REF: - case GL_STENCIL_TEST: - case GL_STENCIL_VALUE_MASK: - case GL_STENCIL_WRITEMASK: - case GL_SUBPIXEL_BITS: - case GL_TEXTURE_2D: - case GL_TEXTURE_BINDING_2D: - case GL_TEXTURE_STACK_DEPTH: - case GL_UNPACK_ALIGNMENT: - case GL_VERTEX_ARRAY: - case GL_VERTEX_ARRAY_SIZE: - case GL_VERTEX_ARRAY_TYPE: - case GL_VERTEX_ARRAY_STRIDE: - case GL_NORMAL_ARRAY: - case GL_NORMAL_ARRAY_TYPE: - case GL_NORMAL_ARRAY_STRIDE: - case GL_COLOR_ARRAY: - case GL_COLOR_ARRAY_SIZE: - case GL_COLOR_ARRAY_TYPE: - case GL_COLOR_ARRAY_STRIDE: - case GL_TEXTURE_COORD_ARRAY: - case GL_TEXTURE_COORD_ARRAY_SIZE: - case GL_TEXTURE_COORD_ARRAY_TYPE: - case GL_TEXTURE_COORD_ARRAY_STRIDE: - case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: - case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: - case GL_SPOT_EXPONENT: - case GL_SPOT_CUTOFF: - case GL_CONSTANT_ATTENUATION: - case GL_LINEAR_ATTENUATION: - case GL_QUADRATIC_ATTENUATION: - case GL_SHININESS: - case GL_TEXTURE_ENV_MODE: - case GL_COMBINE_RGB: - case GL_COMBINE_ALPHA: - case GL_SRC0_RGB: - case GL_SRC1_RGB: - case GL_SRC2_RGB: - case GL_SRC0_ALPHA: - case GL_SRC1_ALPHA: - case GL_SRC2_ALPHA: - case GL_OPERAND0_RGB: - case GL_OPERAND1_RGB: - case GL_OPERAND2_RGB: - case GL_OPERAND0_ALPHA: - case GL_OPERAND1_ALPHA: - case GL_OPERAND2_ALPHA: - case GL_RGB_SCALE: - case GL_POINT_SIZE_MIN: - case GL_POINT_SIZE_MAX: - case GL_POINT_FADE_THRESHOLD_SIZE: - count = 1; - break; - - case GL_DEPTH_RANGE: - case GL_ALIASED_LINE_WIDTH_RANGE: - case GL_MAX_VIEWPORT_DIMS: - case GL_ALIASED_POINT_SIZE_RANGE: - count = 2; - break; - - case GL_CURRENT_NORMAL: - case GL_SPOT_DIRECTION: - case GL_POINT_DISTANCE_ATTENUATION: - count = 3; - break; - - case GL_COLOR_CLEAR_VALUE: - case GL_COLOR_WRITEMASK: - case GL_CURRENT_COLOR: - case GL_CURRENT_TEXTURE_COORDS: - case GL_FOG_COLOR: - case GL_LIGHT_MODEL_AMBIENT: - case GL_SCISSOR_BOX: - case GL_VIEWPORT: - case GL_AMBIENT: - case GL_DIFFUSE: - case GL_SPECULAR: - case GL_EMISSION: - case GL_TEXTURE_ENV_COLOR: - case GL_POSITION: - case GL_AMBIENT_AND_DIFFUSE: - count = 4; - break; - - - case GL_MODELVIEW_MATRIX: - case GL_PROJECTION_MATRIX: - case GL_TEXTURE_MATRIX: - count = 16; - break; - - default: - GLES2_PRINT("ERROR: Unknown pname 0x%x in glGet!\n", pname); - //exit(0); - count = 1; - break; - } - - GLES2_PRINT("glGet(0x%x) -> %u!\n", pname, count); - - return count; -} - - -GLES2_CB(glGetPointerv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - - Tptr res = 0; - - switch (pname) - { - case GL_COLOR_ARRAY_POINTER: - res = c->arrays[c->narrays - gles1_num_glColorPointer].tptr; - break; - case GL_NORMAL_ARRAY_POINTER: - res = c->arrays[c->narrays - gles1_num_glNormalPointer].tptr; - break; - case GL_TEXTURE_COORD_ARRAY_POINTER: - res = c->arrays[c->narrays - gles1_num_glTexCoordPointer].tptr; - break; - case GL_VERTEX_ARRAY_POINTER: - res = c->arrays[c->narrays - gles1_num_glVertexPointer].tptr; - break; - - default: - GLES2_PRINT("ERROR: Unknown pname 0x%x in glGetPointerv!\n", pname); - //exit(0); - break; - } - - GLES2_BARRIER_RET; - gles2_put_Tptr(s, paramsp, res); -} - -GLES2_CB(glEnableClientState) -{ - GLES2_ARG(TGLenum, array); - GLES2_BARRIER_ARG_NORET; - - switch (array) - { - case GL_COLOR_ARRAY: - c->arrays[c->narrays - gles1_num_glColorPointer].enabled = 1; - break; - case GL_NORMAL_ARRAY: - c->arrays[c->narrays - gles1_num_glNormalPointer].enabled = 1; - break; - case GL_TEXTURE_COORD_ARRAY: - c->arrays[c->narrays - gles1_num_glTexCoordPointer].enabled = 1; - break; - case GL_VERTEX_ARRAY: - c->arrays[c->narrays - gles1_num_glVertexPointer].enabled = 1; - break; - - default: - GLES2_PRINT("ERROR: Unknown array 0x%x in glDisableClientState!\n", array); - exit(0); - break; - } - - glEnableClientState(array); -} - -GLES2_CB(glDisableClientState) -{ - GLES2_ARG(TGLenum, array); - GLES2_BARRIER_ARG_NORET; - - switch (array) - { - case GL_COLOR_ARRAY: - c->arrays[c->narrays - gles1_num_glColorPointer].enabled = 0; - break; - case GL_NORMAL_ARRAY: - c->arrays[c->narrays - gles1_num_glNormalPointer].enabled = 0; - break; - case GL_TEXTURE_COORD_ARRAY: - c->arrays[c->narrays - gles1_num_glTexCoordPointer].enabled = 0; - break; - case GL_VERTEX_ARRAY: - c->arrays[c->narrays - gles1_num_glVertexPointer].enabled = 0; - break; - - default: - GLES2_PRINT("ERROR: Unknown array 0x%x in glDisableClientState!\n", array); - exit(0); - break; - } - - glDisableClientState(array); -} - - -//***************** Has been generated! ******************* - -GLES2_CB(glAlphaFunc) -{ - GLES2_ARG(TGLenum, func); - GLES2_ARG(TGLclampf, ref); - GLES2_BARRIER_ARG_NORET; - - glAlphaFunc(func, ref); -} - -GLES2_CB(glClipPlanef) -{ - GLES2_ARG(TGLenum, plane); - GLES2_ARG(Tptr, equationp); - unsigned count = gles1_count_glClipPlanef; - GLfloat equation [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - equation[i] = gles2_get_TGLfloat(s, equationp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glClipPlanef(plane, equation); -} - -GLES2_CB(glColor4f) -{ - GLES2_ARG(TGLfloat, red); - GLES2_ARG(TGLfloat, green); - GLES2_ARG(TGLfloat, blue); - GLES2_ARG(TGLfloat, alpha); - GLES2_BARRIER_ARG_NORET; - - glColor4f(red, green, blue, alpha); -} - -GLES2_CB(glFogf) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfloat, param); - GLES2_BARRIER_ARG_NORET; - - glFogf(pname, param); -} - -GLES2_CB(glFogfv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfloat(s, paramsp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glFogfv(pname, params); -} - -GLES2_CB(glFrustumf) -{ - GLES2_ARG(TGLfloat, left); - GLES2_ARG(TGLfloat, right); - GLES2_ARG(TGLfloat, bottom); - GLES2_ARG(TGLfloat, top); - GLES2_ARG(TGLfloat, zNear); - GLES2_ARG(TGLfloat, zFar); - GLES2_BARRIER_ARG_NORET; - - glFrustumf(left, right, bottom, top, zNear, zFar); -} - -GLES2_CB(glGetClipPlanef) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, eqnp); - unsigned count = gles1_glGetCount(pname); - GLfloat eqn [16]; - - glGetClipPlanef(pname, eqn); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfloat(s, eqnp + i*sizeof(TGLfloat), eqn[i]); - } -} - -GLES2_CB(glGetLightfv) -{ - GLES2_ARG(TGLenum, light); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - - glGetLightfv(light, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfloat(s, paramsp + i*sizeof(TGLfloat), params[i]); - } -} - -GLES2_CB(glGetMaterialfv) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - - glGetMaterialfv(face, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfloat(s, paramsp + i*sizeof(TGLfloat), params[i]); - } -} - -GLES2_CB(glGetTexEnvfv) -{ - GLES2_ARG(TGLenum, env); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - - glGetTexEnvfv(env, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfloat(s, paramsp + i*sizeof(TGLfloat), params[i]); - } -} - -GLES2_CB(glLightModelf) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfloat, param); - GLES2_BARRIER_ARG_NORET; - - glLightModelf(pname, param); -} - -GLES2_CB(glLightModelfv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfloat(s, paramsp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glLightModelfv(pname, params); -} - -GLES2_CB(glLightf) -{ - GLES2_ARG(TGLenum, light); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfloat, param); - GLES2_BARRIER_ARG_NORET; - - glLightf(light, pname, param); -} - -GLES2_CB(glLightfv) -{ - GLES2_ARG(TGLenum, light); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfloat(s, paramsp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glLightfv(light, pname, params); -} - -GLES2_CB(glLoadMatrixf) -{ - GLES2_ARG(Tptr, mp); - unsigned count = gles1_count_glLoadMatrixf; - GLfloat m [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - m[i] = gles2_get_TGLfloat(s, mp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glLoadMatrixf(m); -} - -GLES2_CB(glMaterialf) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfloat, param); - GLES2_BARRIER_ARG_NORET; - - glMaterialf(face, pname, param); -} - -GLES2_CB(glMaterialfv) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfloat(s, paramsp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glMaterialfv(face, pname, params); -} - -GLES2_CB(glMultMatrixf) -{ - GLES2_ARG(Tptr, mp); - unsigned count = gles1_count_glMultMatrixf; - GLfloat m [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - m[i] = gles2_get_TGLfloat(s, mp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glMultMatrixf(m); -} - -GLES2_CB(glMultiTexCoord4f) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLfloat, ps); - GLES2_ARG(TGLfloat, t); - GLES2_ARG(TGLfloat, r); - GLES2_ARG(TGLfloat, q); - GLES2_BARRIER_ARG_NORET; - - glMultiTexCoord4f(target, ps, t, r, q); -} - -GLES2_CB(glNormal3f) -{ - GLES2_ARG(TGLfloat, nx); - GLES2_ARG(TGLfloat, ny); - GLES2_ARG(TGLfloat, nz); - GLES2_BARRIER_ARG_NORET; - - glNormal3f(nx, ny, nz); -} - -GLES2_CB(glOrthof) -{ - GLES2_ARG(TGLfloat, left); - GLES2_ARG(TGLfloat, right); - GLES2_ARG(TGLfloat, bottom); - GLES2_ARG(TGLfloat, top); - GLES2_ARG(TGLfloat, zNear); - GLES2_ARG(TGLfloat, zFar); - GLES2_BARRIER_ARG_NORET; - - glOrthof(left, right, bottom, top, zNear, zFar); -} - -GLES2_CB(glPointParameterf) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfloat, param); - GLES2_BARRIER_ARG_NORET; - - glPointParameterf(pname, param); -} - -GLES2_CB(glPointParameterfv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfloat(s, paramsp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glPointParameterfv(pname, params); -} - -GLES2_CB(glPointSize) -{ - GLES2_ARG(TGLfloat, size); - GLES2_BARRIER_ARG_NORET; - - glPointSize(size); -} - -GLES2_CB(glRotatef) -{ - GLES2_ARG(TGLfloat, angle); - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_ARG(TGLfloat, z); - GLES2_BARRIER_ARG_NORET; - - glRotatef(angle, x, y, z); -} - -GLES2_CB(glScalef) -{ - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_ARG(TGLfloat, z); - GLES2_BARRIER_ARG_NORET; - - glScalef(x, y, z); -} - -GLES2_CB(glTexEnvf) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfloat, param); - GLES2_BARRIER_ARG_NORET; - - glTexEnvf(target, pname, param); -} - -GLES2_CB(glTexEnvfv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfloat params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfloat(s, paramsp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glTexEnvfv(target, pname, params); -} - -GLES2_CB(glTranslatef) -{ - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_ARG(TGLfloat, z); - GLES2_BARRIER_ARG_NORET; - - glTranslatef(x, y, z); -} - -GLES2_CB(glAlphaFuncx) -{ - GLES2_ARG(TGLenum, func); - GLES2_ARG(TGLclampx, ref); - GLES2_BARRIER_ARG_NORET; - - glAlphaFuncx(func, ref); -} - -GLES2_CB(glClearColorx) -{ - GLES2_ARG(TGLclampx, red); - GLES2_ARG(TGLclampx, green); - GLES2_ARG(TGLclampx, blue); - GLES2_ARG(TGLclampx, alpha); - GLES2_BARRIER_ARG_NORET; - - glClearColorx(red, green, blue, alpha); -} - -GLES2_CB(glClearDepthx) -{ - GLES2_ARG(TGLclampx, depth); - GLES2_BARRIER_ARG_NORET; - - glClearDepthx(depth); -} - -GLES2_CB(glClientActiveTexture) -{ - GLES2_ARG(TGLenum, texture); - GLES2_BARRIER_ARG_NORET; - - glClientActiveTexture(texture); -} - -GLES2_CB(glClipPlanex) -{ - GLES2_ARG(TGLenum, plane); - GLES2_ARG(Tptr, equationp); - unsigned count = gles1_count_glClipPlanex; - GLfixed equation [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - equation[i] = gles2_get_TGLfixed(s, equationp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glClipPlanex(plane, equation); -} - -GLES2_CB(glColor4ub) -{ - GLES2_ARG(TGLubyte, red); - GLES2_ARG(TGLubyte, green); - GLES2_ARG(TGLubyte, blue); - GLES2_ARG(TGLubyte, alpha); - GLES2_BARRIER_ARG_NORET; - - glColor4ub(red, green, blue, alpha); -} - -GLES2_CB(glColor4x) -{ - GLES2_ARG(TGLfixed, red); - GLES2_ARG(TGLfixed, green); - GLES2_ARG(TGLfixed, blue); - GLES2_ARG(TGLfixed, alpha); - GLES2_BARRIER_ARG_NORET; - - glColor4x(red, green, blue, alpha); -} - -GLES2_CB(glColorPointer) -{ - GLES2_ARG(TGLint, size); - GLES2_ARG(TGLenum, type); - GLES2_ARG(TGLsizei, stride); - GLES2_ARG(Tptr, pointerp); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Array glColorPointer at 0x%x\n", pointerp); - - gles2_Array *va = c->arrays + (c->narrays - gles1_num_glColorPointer); - va->size = size; - va->type = type; - va->stride = stride; - va->tptr = pointerp; - va->apply = gles1_apply_glColorPointer; - va->enabled = 1; -} - -GLES2_CB(glDepthRangex) -{ - GLES2_ARG(TGLclampx, zNear); - GLES2_ARG(TGLclampx, zFar); - GLES2_BARRIER_ARG_NORET; - - glDepthRangex(zNear, zFar); -} - -GLES2_CB(glFogx) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfixed, param); - GLES2_BARRIER_ARG_NORET; - - glFogx(pname, param); -} - -GLES2_CB(glFogxv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfixed(s, paramsp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glFogxv(pname, params); -} - -GLES2_CB(glFrustumx) -{ - GLES2_ARG(TGLfixed, left); - GLES2_ARG(TGLfixed, right); - GLES2_ARG(TGLfixed, bottom); - GLES2_ARG(TGLfixed, top); - GLES2_ARG(TGLfixed, zNear); - GLES2_ARG(TGLfixed, zFar); - GLES2_BARRIER_ARG_NORET; - - glFrustumx(left, right, bottom, top, zNear, zFar); -} - -GLES2_CB(glGetClipPlanex) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, eqnp); - unsigned count = gles1_glGetCount(pname); - GLfixed eqn [16]; - - glGetClipPlanex(pname, eqn); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfixed(s, eqnp + i*sizeof(TGLfixed), eqn[i]); - } -} - -GLES2_CB(glGetFixedv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - - glGetFixedv(pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfixed(s, paramsp + i*sizeof(TGLfixed), params[i]); - } -} - -GLES2_CB(glGetLightxv) -{ - GLES2_ARG(TGLenum, light); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - - glGetLightxv(light, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfixed(s, paramsp + i*sizeof(TGLfixed), params[i]); - } -} - -GLES2_CB(glGetMaterialxv) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - - glGetMaterialxv(face, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfixed(s, paramsp + i*sizeof(TGLfixed), params[i]); - } -} - -GLES2_CB(glGetTexEnviv) -{ - GLES2_ARG(TGLenum, env); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLint params [16]; - - glGetTexEnviv(env, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLint(s, paramsp + i*sizeof(TGLint), params[i]); - } -} - -GLES2_CB(glGetTexEnvxv) -{ - GLES2_ARG(TGLenum, env); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - - glGetTexEnvxv(env, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfixed(s, paramsp + i*sizeof(TGLfixed), params[i]); - } -} - -GLES2_CB(glGetTexParameterxv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - - glGetTexParameterxv(target, pname, params); - GLES2_BARRIER_RET; - unsigned i = 0; - for (i = 0; i < count; ++i) { - gles2_put_TGLfixed(s, paramsp + i*sizeof(TGLfixed), params[i]); - } -} - -GLES2_CB(glLightModelx) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfixed, param); - GLES2_BARRIER_ARG_NORET; - - glLightModelx(pname, param); -} - -GLES2_CB(glLightModelxv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfixed(s, paramsp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glLightModelxv(pname, params); -} - -GLES2_CB(glLightx) -{ - GLES2_ARG(TGLenum, light); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfixed, param); - GLES2_BARRIER_ARG_NORET; - - glLightx(light, pname, param); -} - -GLES2_CB(glLightxv) -{ - GLES2_ARG(TGLenum, light); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfixed(s, paramsp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glLightxv(light, pname, params); -} - -GLES2_CB(glLineWidthx) -{ - GLES2_ARG(TGLfixed, width); - GLES2_BARRIER_ARG_NORET; - - glLineWidthx(width); -} - -GLES2_CB(glLoadIdentity) -{ - GLES2_BARRIER_ARG_NORET; - - glLoadIdentity(); -} - -GLES2_CB(glLoadMatrixx) -{ - GLES2_ARG(Tptr, mp); - unsigned count = gles1_count_glLoadMatrixx; - GLfixed m [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - m[i] = gles2_get_TGLfixed(s, mp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glLoadMatrixx(m); -} - -GLES2_CB(glLogicOp) -{ - GLES2_ARG(TGLenum, opcode); - GLES2_BARRIER_ARG_NORET; - - glLogicOp(opcode); -} - -GLES2_CB(glMaterialx) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfixed, param); - GLES2_BARRIER_ARG_NORET; - - glMaterialx(face, pname, param); -} - -GLES2_CB(glMaterialxv) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfixed(s, paramsp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glMaterialxv(face, pname, params); -} - -GLES2_CB(glMatrixMode) -{ - GLES2_ARG(TGLenum, mode); - GLES2_BARRIER_ARG_NORET; - - glMatrixMode(mode); -} - -GLES2_CB(glMultMatrixx) -{ - GLES2_ARG(Tptr, mp); - unsigned count = gles1_count_glMultMatrixx; - GLfixed m [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - m[i] = gles2_get_TGLfixed(s, mp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glMultMatrixx(m); -} - -GLES2_CB(glMultiTexCoord4x) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLfixed, ps); - GLES2_ARG(TGLfixed, t); - GLES2_ARG(TGLfixed, r); - GLES2_ARG(TGLfixed, q); - GLES2_BARRIER_ARG_NORET; - - glMultiTexCoord4x(target, ps, t, r, q); -} - -GLES2_CB(glNormal3x) -{ - GLES2_ARG(TGLfixed, nx); - GLES2_ARG(TGLfixed, ny); - GLES2_ARG(TGLfixed, nz); - GLES2_BARRIER_ARG_NORET; - - glNormal3x(nx, ny, nz); -} - -GLES2_CB(glNormalPointer) -{ - GLES2_ARG(TGLenum, type); - GLES2_ARG(TGLsizei, stride); - GLES2_ARG(Tptr, pointerp); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Array glNormalPointer at 0x%x\n", pointerp); - - gles2_Array *va = c->arrays + (c->narrays - gles1_num_glNormalPointer); - va->type = type; - va->stride = stride; - va->tptr = pointerp; - va->size = gles1_size_glNormalPointer; - va->apply = gles1_apply_glNormalPointer; - va->enabled = 1; -} - -GLES2_CB(glOrthox) -{ - GLES2_ARG(TGLfixed, left); - GLES2_ARG(TGLfixed, right); - GLES2_ARG(TGLfixed, bottom); - GLES2_ARG(TGLfixed, top); - GLES2_ARG(TGLfixed, zNear); - GLES2_ARG(TGLfixed, zFar); - GLES2_BARRIER_ARG_NORET; - - glOrthox(left, right, bottom, top, zNear, zFar); -} - -GLES2_CB(glPointParameterx) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfixed, param); - GLES2_BARRIER_ARG_NORET; - - glPointParameterx(pname, param); -} - -GLES2_CB(glPointParameterxv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfixed(s, paramsp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glPointParameterxv(pname, params); -} - -GLES2_CB(glPointSizex) -{ - GLES2_ARG(TGLfixed, size); - GLES2_BARRIER_ARG_NORET; - - glPointSizex(size); -} - -GLES2_CB(glPolygonOffsetx) -{ - GLES2_ARG(TGLfixed, factor); - GLES2_ARG(TGLfixed, units); - GLES2_BARRIER_ARG_NORET; - - glPolygonOffsetx(factor, units); -} - -GLES2_CB(glPopMatrix) -{ - GLES2_BARRIER_ARG_NORET; - - glPopMatrix(); -} - -GLES2_CB(glPushMatrix) -{ - GLES2_BARRIER_ARG_NORET; - - glPushMatrix(); -} - -GLES2_CB(glRotatex) -{ - GLES2_ARG(TGLfixed, angle); - GLES2_ARG(TGLfixed, x); - GLES2_ARG(TGLfixed, y); - GLES2_ARG(TGLfixed, z); - GLES2_BARRIER_ARG_NORET; - - glRotatex(angle, x, y, z); -} - -GLES2_CB(glSampleCoveragex) -{ - GLES2_ARG(TGLclampx, value); - GLES2_ARG(TGLboolean, invert); - GLES2_BARRIER_ARG_NORET; - - glSampleCoveragex(value, invert); -} - -GLES2_CB(glScalex) -{ - GLES2_ARG(TGLfixed, x); - GLES2_ARG(TGLfixed, y); - GLES2_ARG(TGLfixed, z); - GLES2_BARRIER_ARG_NORET; - - glScalex(x, y, z); -} - -GLES2_CB(glShadeModel) -{ - GLES2_ARG(TGLenum, mode); - GLES2_BARRIER_ARG_NORET; - - glShadeModel(mode); -} - -GLES2_CB(glTexCoordPointer) -{ - GLES2_ARG(TGLint, size); - GLES2_ARG(TGLenum, type); - GLES2_ARG(TGLsizei, stride); - GLES2_ARG(Tptr, pointerp); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Array glTexCoordPointer at 0x%x\n", pointerp); - - gles2_Array *va = c->arrays + (c->narrays - gles1_num_glTexCoordPointer); - va->size = size; - va->type = type; - va->stride = stride; - va->tptr = pointerp; - va->apply = gles1_apply_glTexCoordPointer; - va->enabled = 1; -} - -GLES2_CB(glTexEnvi) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLint, param); - GLES2_BARRIER_ARG_NORET; - - glTexEnvi(target, pname, param); -} - -GLES2_CB(glTexEnvx) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfixed, param); - GLES2_BARRIER_ARG_NORET; - - glTexEnvx(target, pname, param); -} - -GLES2_CB(glTexEnviv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLint params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLint(s, paramsp + i*sizeof(TGLint)); - } - GLES2_BARRIER_ARG_NORET; - - glTexEnviv(target, pname, params); -} - -GLES2_CB(glTexEnvxv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfixed(s, paramsp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glTexEnvxv(target, pname, params); -} - -GLES2_CB(glTexParameterx) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfixed, param); - GLES2_BARRIER_ARG_NORET; - - glTexParameterx(target, pname, param); -} - -GLES2_CB(glTexParameterxv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - unsigned count = gles1_glGetCount(pname); - GLfixed params [16]; - unsigned i = 0; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfixed(s, paramsp + i*sizeof(TGLfixed)); - } - GLES2_BARRIER_ARG_NORET; - - glTexParameterxv(target, pname, params); -} - -GLES2_CB(glTranslatex) -{ - GLES2_ARG(TGLfixed, x); - GLES2_ARG(TGLfixed, y); - GLES2_ARG(TGLfixed, z); - GLES2_BARRIER_ARG_NORET; - - glTranslatex(x, y, z); -} - -GLES2_CB(glVertexPointer) -{ - GLES2_ARG(TGLint, size); - GLES2_ARG(TGLenum, type); - GLES2_ARG(TGLsizei, stride); - GLES2_ARG(Tptr, pointerp); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Array glVertexPointer at 0x%x\n", pointerp); - - gles2_Array *va = c->arrays + (c->narrays - gles1_num_glVertexPointer); - va->size = size; - va->type = type; - va->stride = stride; - va->tptr = pointerp; - va->apply = gles1_apply_glVertexPointer; - va->enabled = 1; -} diff --git a/hw/gles2.c b/hw/gles2.c deleted file mode 100644 index ab4f822..0000000 --- a/hw/gles2.c +++ /dev/null @@ -1,754 +0,0 @@ -/* Copyright (c) 2009-2010 Nokia Corporation - * - * 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 or - * (at your option) any later version of the License. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - */ - -#include "gles2.h" -#include - -// From target-arm/helper.c. -extern int get_phys_addr(CPUState *env, uint32_t address, - int access_type, int is_user, - uint32_t *phys_ptr, int *prot, - target_ulong *page_size); - - -// List of calls to used by the kernel module (page 0). -static gles2_Call const gles2_kcalls[]; -// List of calls used by clients (page 1->15). -static gles2_Call const gles2_calls[]; - -// Translate a target virtual address to physical address. -static target_ulong gles2_pa(gles2_State *s, target_ulong va, - int access_type) -{ - target_ulong pa, ps; - int prot; - - if (get_phys_addr(s->env, va, access_type, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Page fault on guest!\n"); - return 0; - } - - return pa; -} - -int gles2_transfer_compile(gles2_CompiledTransfer* tfr, gles2_State *s, - target_ulong va, target_ulong len) -{ - tfr->nsections = 0; - tfr->sections = 0; - -#if (GLES2_DEBUG == 1) - target_ulong first_page = TARGET_PAGE(va); -#endif // GLES2_DEBUG == 1 - - target_ulong last_page = TARGET_PAGE(va + len - 1); - target_ulong start_addr = va; - - GLES2_PRINT("DEBUG: Compiling transfer of %d bytes at 0x%x (0x%x->0x%x).\n", - len, va, first_page, last_page); - - // Loop through the pages. - while (len) { - target_ulong start_page = TARGET_PAGE(start_addr); - target_ulong start_pa = gles2_pa(s, start_page, 0); - target_ulong end_pa = start_pa; - - // Solve length of continuous section. - target_ulong end_page = start_page; - while(end_page < last_page) { - target_ulong next_page = end_page + TARGET_PAGE_SIZE; - target_ulong next_pa = gles2_pa(s, next_page, 0); - - // If the target pages are not linearly spaced, stop.. - if((next_pa < start_pa) || - (next_pa - start_pa > next_page - start_page)) { - break; - } - - end_page = next_page; - end_pa = next_pa; - } - - unsigned id = tfr->nsections++; - - GLES2_PRINT("\tContinuous from 0x%x to 0x%x (0x%x to 0x%x) #%d.\n", - start_page, end_page, start_pa, end_pa, id); - tfr->sections = realloc(tfr->sections, - tfr->nsections*sizeof(*(tfr->sections))); - - target_phys_addr_t pages_len = end_page + TARGET_PAGE_SIZE - start_page; - void* target_pages = cpu_physical_memory_map(start_pa, &pages_len, 0); - - if (!target_pages || !pages_len) { - fprintf(stderr, "ERROR: Failed to map memory to host!\n"); - return 0; - } - - target_ulong section_len = end_page + TARGET_PAGE_SIZE - start_addr; - - if (section_len > len) { - section_len = len; - } - - target_ulong offset = TARGET_OFFSET(start_addr); - void* target_data = target_pages + offset; - - GLES2_PRINT("\tSlice of %d bytes at %p (offset = %x).\n", - section_len, target_data, offset); - - tfr->sections[id].base = target_data; - tfr->sections[id].len = section_len; - - cpu_physical_memory_unmap(target_pages, pages_len, 0, pages_len); - len -= section_len; - start_addr += section_len; - GLES2_PRINT("\t%d bytes remain...\n", len); - } - return 1; -} - -void gles2_transfer_exec(gles2_CompiledTransfer* tfr, gles2_State *s, - void* data, int access_type) -{ - unsigned i; - - for (i = 0; i < tfr->nsections; ++i) { - void* target_data = tfr->sections[i].base; - target_ulong len = tfr->sections[i].len; - if (access_type == 0) { - memcpy(data, target_data, len); - } else { - memcpy(target_data, data, len); - } - data += len; - } -} - -void gles2_transfer_free(gles2_CompiledTransfer* tfr) -{ - free(tfr->sections); - tfr->sections = 0; - tfr->nsections = 0; -} - -int gles2_transfer(gles2_State *s, target_ulong va, target_ulong len, - void* data, int access_type) -{ -#if (GLES2_DEBUG == 1) - target_ulong first_page = TARGET_PAGE(va); -#endif // GLES2_DEBUG == 1 - - target_ulong last_page = TARGET_PAGE(va + len - 1); - target_ulong start_addr = va; - - GLES2_PRINT("DEBUG: Request transfer of %d bytes at 0x%x (0x%x->0x%x) (access=%d).\n", - len, va, first_page, last_page, access_type); - - // Loop through the pages. - while (len) { - target_ulong start_page = TARGET_PAGE(start_addr); - target_ulong start_pa = gles2_pa(s, start_page, access_type); - target_ulong end_pa = start_pa; - - // Solve length of continuous section. - target_ulong end_page = start_page; - while(end_page < last_page) { - target_ulong next_page = end_page + TARGET_PAGE_SIZE; - target_ulong next_pa = gles2_pa(s, next_page, access_type); - - // If the target pages are not linearly spaced, stop.. - if ((next_pa < start_pa) || - (next_pa - start_pa > next_page - start_page)) { - break; - } - - end_page = next_page; - end_pa = next_pa; - } - - GLES2_PRINT("\tContinuous from 0x%x to 0x%x (0x%x to 0x%x).\n", - start_page, end_page, start_pa, end_pa); - - target_phys_addr_t pages_len = end_page + TARGET_PAGE_SIZE - start_page; - void* target_pages = cpu_physical_memory_map(start_pa, &pages_len, access_type); - if (!target_pages || !pages_len) { - GLES2_PRINT("ERROR: Failed to map memory to host!\n"); - return 0; - } - - target_ulong section_len = end_page + TARGET_PAGE_SIZE - start_addr; - target_ulong offset = TARGET_OFFSET(start_addr); - void* target_data = target_pages + offset; - - if (section_len > len) { - section_len = len; - } - - GLES2_PRINT("\tTransfering %d bytes at %p (offset = %x).\n", - section_len, target_data, offset); - - if (access_type == 0) { - memcpy(data, target_data, section_len); - } else { - memcpy(target_data, data, section_len); - } - - cpu_physical_memory_unmap(target_pages, pages_len, access_type, pages_len); - len -= section_len; - start_addr += section_len; - data += section_len; - - GLES2_PRINT("\t%d bytes remain...\n", len); - } - return 1; -} - -void gles2_put_byte(gles2_State *s, target_ulong va, uint8_t byte) -{ - int prot; - target_ulong pa, ps; - - if (get_phys_addr(s->env, va, 1, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return; - } - - GLES2_PRINT("DEBUG: Written 0x%x to 0x%x(0x%x)\n", byte, va, pa); - stb_phys(pa, byte); -} - -uint8_t gles2_get_byte(gles2_State *s, target_ulong va) -{ - uint8_t byte; - int prot; - target_ulong pa, ps; - - if (get_phys_addr(s->env, va, 0, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return 0xDE; - } - - byte = ldub_phys(pa); - - //GLES2_PRINT("DEBUG: Read 0x%x from 0x%x(0x%x)\n", byte, va, pa); - - return byte; -} - -void gles2_put_word(gles2_State *s, target_ulong va, uint16_t word) -{ - int prot; - target_ulong pa, ps; - - if (get_phys_addr(s->env, va, 1, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return; - } - - GLES2_PRINT("DEBUG: Written 0x%x to 0x%x(0x%x)\n", word, va, pa); - stw_phys(pa, word); -} - -uint16_t gles2_get_word(gles2_State *s, target_ulong va) -{ - uint16_t word; - - int prot; - target_ulong pa, ps; - if (get_phys_addr(s->env, va, 0, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return 0xDEAD; - } - - word = lduw_phys(pa); - - //GLES2_PRINT("DEBUG: Read 0x%x from 0x%x(0x%x)\n", word, va, pa); - - return word; -} - -uint32_t gles2_get_dword(gles2_State *s, target_ulong va) -{ - uint32_t dword; - int prot; - target_ulong pa, ps; - - if (get_phys_addr(s->env, va, 0, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return 0xDEAD000; - } - - dword = ldl_phys(pa); - - //GLES2_PRINT("DEBUG: Read 0x%x from 0x%x(0x%x)\n", dword, va, pa); - - return dword; -} - -void gles2_put_dword(gles2_State *s, target_ulong va, uint32_t dword) -{ - int prot; - target_ulong pa, ps; - - if (get_phys_addr(s->env, va, 1, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return; - } - - GLES2_PRINT("DEBUG: Written 0x%x to 0x%x(0x%x)\n", dword, va, pa); - stl_phys(pa, dword); -} - -float gles2_get_float(gles2_State *s, target_ulong va) -{ - float flt; - int prot; - target_ulong pa, ps; - - if (get_phys_addr(s->env, va, 0, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return -123456789.f; - } - - cpu_physical_memory_read(pa, (unsigned char*)&flt, 4); - //flt = ldfl_p(pa); - - //GLES2_PRINT("DEBUG: Read %f from 0x%x(0x%x)\n", flt, va, pa); - - return flt; -} - -void gles2_put_float(gles2_State *s, target_ulong va, float flt) -{ - int prot; - target_ulong pa, ps; - - if (get_phys_addr(s->env, va, 1, 1, &pa, &prot, &ps)) { - GLES2_PRINT("ERROR: Memory mapping failed for 0x%x!\n", va); - return; - } - - GLES2_PRINT("DEBUG: Written %f to 0x%x(0x%x)\n", flt, va, pa); - cpu_physical_memory_write(pa, (unsigned char*)&flt, 4); - //stfl_p(pa, flt); -} - -uint32_t gles2_handle_create(gles2_State *s, void* data) -{ - uint32_t i = 0; - - if (data) { - for (i = 0; i < GLES2_NHANDLES; ++i) { - if (!s->handles[i]) { - break; - } - } - - if (i == GLES2_NHANDLES) { - fprintf(stderr, "ERROR: No free handles!\n"); - return 0x0; - } - s->handles[i] = data; - i |= GLES2_HANDLE_BASE; - } - - GLES2_PRINT("Handle %x created for %p!\n", i, data); - return i; -} - -uint32_t gles2_handle_find(gles2_State *s, void* data) -{ - uint32_t i = 0; - - if (data) { - for(i = 0; i < GLES2_NHANDLES; ++i) { - if(s->handles[i] == data) { - break; - } - } - - if (i == GLES2_NHANDLES) { -// fprintf(stderr, "ERROR: Handle not found!\n"); - return 0x0; - } - i |= GLES2_HANDLE_BASE; - } - - GLES2_PRINT("Handle %x found for %p!\n", i, data); - return i; -} - -void* gles2_handle_get(gles2_State *s, uint32_t i) -{ -#if(GLES2_DEBUG == 1) - if (i && (i & ~GLES2_HANDLE_MASK) != GLES2_HANDLE_BASE) { - GLES2_PRINT("ERROR: Invalid handle %x!\n", i); - exit(1); - } -#endif // GLES2_DEBUG == 1 - - void* data = i ? s->handles[i & GLES2_HANDLE_MASK] : NULL; - - GLES2_PRINT("Reading handle %x => %p\n", i, data); - - return data; -} - -void* gles2_handle_free(gles2_State *s, uint32_t i) -{ - void* data = NULL; - if (i) { - data = s->handles[i & GLES2_HANDLE_MASK]; - s->handles[i & GLES2_HANDLE_MASK] = NULL; - } - - GLES2_PRINT("Freed handle %i => %p\n", i, data); - return data; -} - -// Virtual register area write operation handler. -static void gles2_write(void *opaque, target_phys_addr_t addr, uint32_t value) -{ - gles2_State *s = (gles2_State*)opaque; - - target_ulong page = addr/(4*TARGET_PAGE_SIZE); - target_ulong callnr = ((addr) & (4*TARGET_PAGE_SIZE - 1))/0x04; - - GLES2_PRINT("Page %d (0x%x) write (call nr. %d (0x%x)), addr = 0x%x, value = 0x%x.\n", page, page, callnr, callnr, (int32_t)addr, value); - - if (page) { - gles2_Call const *call = gles2_calls + callnr; - - if (page > 1) { - gles2_Client* client; - - // Client API calls without active context should be ignored. - if ((page - 2 > GLES2_NCLIENTS) || - !(client = s->clients[page - 2])) { - return; - } - - // Make sure nothing is running. - GLES2_PRINT("Syncing with worker...\n"); - pthread_mutex_lock(&client->mutex_wait); - while (client->state != gles2_ClientState_ready) { - pthread_cond_wait(&client->cond_state, &client->mutex_wait); - } - pthread_mutex_lock(&client->mutex_run); - pthread_mutex_lock(&client->mutex_xcode); - client->call = call; - client->state = gles2_ClientState_pending; - client->phase_xcode = 0; - GLES2_PRINT("Requesting call %s...\n", call->name); - pthread_cond_signal(&client->cond_start); - pthread_mutex_unlock(&client->mutex_wait); - - GLES2_PRINT("Releasing worker for decoding...\n"); - pthread_mutex_unlock(&client->mutex_run); - do { - pthread_cond_wait(&client->cond_xcode, &client->mutex_xcode); - } while (client->phase_xcode < 1); - - pthread_mutex_unlock(&client->mutex_xcode); - GLES2_PRINT("Decoding finished.\n"); - } else { - gles2_decode_t d = 0; - GLES2_PRINT("Calling clientless function %s...\n", call->name); - call->callback(s, &d, 0); - } - } else { - gles2_Call const *call = gles2_kcalls + callnr; - gles2_decode_t d = 0; - - GLES2_PRINT("Calling kernel function %s...\n", call->name); - - call->callback(s, &d, 0); - } -} - -// Virtual register area read operation handler. -static uint32_t gles2_read(void *opaque, target_phys_addr_t addr) -{ - gles2_State *s = (gles2_State*)opaque; - - target_ulong page = addr/(4*TARGET_PAGE_SIZE); - - if (page) { - gles2_Client* client; - - // Client API calls without active context should be ignored. - if ((page - 2 > GLES2_NCLIENTS) || - !(client = s->clients[page - 2])) { - return 0; - } - - if(pthread_mutex_trylock(&client->mutex_xcode)) { - return 1; - } - - if(client->phase_xcode == 2) { - while (client->phase_xcode < 4) { - client->phase_xcode = 3; - pthread_cond_signal(&client->cond_return); - pthread_cond_wait(&client->cond_xcode, &client->mutex_xcode); - } - pthread_mutex_unlock(&client->mutex_xcode); - return 0; - } - int ret = (client->phase_xcode == 4 ? 0 : 1); - pthread_mutex_unlock(&client->mutex_xcode); - return ret; - } - return 0; -} - -static CPUReadMemoryFunc *gles2_readfn[] = { - gles2_read, - gles2_read, - gles2_read, -}; - -static CPUWriteMemoryFunc *gles2_writefn[] = { - gles2_write, - gles2_write, - gles2_write, -}; - -// Initializes a new gles2 device. -void *gles2_init(CPUState *env) -{ - gles2_State *s = qemu_malloc(sizeof(*s)); - unsigned i; - - s->env = env; - s->quality = gles2_quality; - - GLES2_PRINT("GLES2 quality: %d\n", s->quality); - - cpu_register_physical_memory(GLES2_HWBASE, - GLES2_HWSIZE, - cpu_register_io_memory(gles2_readfn, - gles2_writefn, s, DEVICE_NATIVE_ENDIAN)); - - for (i = 0; i < GLES2_NCLIENTS; ++i) { - s->clients[i] = NULL; - } - - for (i = 0; i < GLES2_NHANDLES; ++i) { - s->handles[i] = NULL; - } - - GLES2_PRINT("Registered IO memory!\n"); - return s; -} - -/****************************************************************************** - * - * Kernel interface functions. - * - *****************************************************************************/ - -static void* gles2_client_worker(void *opaque) -{ - gles2_Client *client = opaque; - int run = 1; - - GLES2_PRINT("WORKER(%d): Starting!\n", client->nr); - - pthread_mutex_lock(&client->mutex_xcode); - do - { - gles2_decode_t d = 0; - GLES2_PRINT("WORKER(%d): Waiting for call...\n", client->nr); - pthread_mutex_lock(&client->mutex_wait); - - client->state = gles2_ClientState_ready; - pthread_cond_signal(&client->cond_state); - client->phase_xcode = 4; - pthread_cond_signal(&client->cond_xcode); - pthread_mutex_unlock(&client->mutex_xcode); - while (client->state != gles2_ClientState_pending) { - pthread_cond_wait(&client->cond_start, &client->mutex_wait); - } - - GLES2_PRINT("WORKER(%d): Got call, waiting permission to run...\n", client->nr); - - pthread_mutex_lock(&client->mutex_run); - GLES2_PRINT("WORKER(%d): Running!\n", client->nr); - client->state = gles2_ClientState_running; - pthread_mutex_unlock(&client->mutex_wait); - - if (client->call) { - GLES2_PRINT("WORKER(%d): Calling function %s (%p)...\n", - client->nr, client->call->name, client->call); - client->call->callback(client->s, &d, client); - - GLES2_PRINT("\tWORKER(%d): Done.\n", client->nr); - client->state = gles2_ClientState_done; - } else { - GLES2_PRINT("WORKER(%d): Exit requested!\n", client->nr); - run = 0; - client->state = gles2_ClientState_exit; - pthread_cond_signal(&client->cond_state); - } - pthread_mutex_unlock(&client->mutex_run); - } while (run); - - GLES2_PRINT("WORKER(%d): Exiting!\n", client->nr); - return opaque; -} - -// Called by kernel module when a new client connects. -static void gles2_init_cb(gles2_State *s, gles2_decode_t *d, gles2_Client *c) -{ - unsigned i; - gles2_Client *client; - pthread_attr_t attr; - - for (i = 0; i < GLES2_NCLIENTS; ++i) { - if (!s->clients[i]) { - break; - } - } - - if (i == GLES2_NCLIENTS) { - GLES2_PRINT("ERROR: No free slots!\n"); - gles2_ret_dword(s, 0); - return; - } - - GLES2_PRINT("Initialization!\n"); - - client = malloc(sizeof(*client)); - client->s = s; - client->nr = i + 1; - pthread_mutex_init(&client->mutex_wait, NULL); - pthread_mutex_init(&client->mutex_run, NULL); - pthread_mutex_init(&client->mutex_xcode, NULL); - pthread_cond_init(&client->cond_start, NULL); - pthread_cond_init(&client->cond_state, NULL); - pthread_cond_init(&client->cond_xcode, NULL); - pthread_cond_init(&client->cond_return, NULL); - client->state = gles2_ClientState_init; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - pthread_mutex_lock(&client->mutex_wait); - - GLES2_PRINT("Creating worker...\n"); - pthread_create(&client->thread, &attr, gles2_client_worker, client); - - do { - pthread_cond_wait(&client->cond_state, &client->mutex_wait); - } while(client->state != gles2_ClientState_ready); - pthread_mutex_unlock(&client->mutex_wait); - - GLES2_PRINT("Worker initialized\n"); - - s->clients[i] = client; - gles2_ret_dword(s, client->nr); -} - -// Called by kernel module when an existing client disconnects. -static void gles2_exit_cb(gles2_State *s, gles2_decode_t *d, gles2_Client *c) -{ - uint32_t nr = gles2_arg_dword(s, d); - gles2_Client *client; - - GLES2_PRINT("Exit called for client %d!\n", nr); - - if ((nr > GLES2_NCLIENTS + 1) || - (nr == 0)) { - GLES2_PRINT("Client number out of range!\n"); - return; - } else { - client = s->clients[nr - 1]; - } - - if (!client) { - GLES2_PRINT("Can't exit NULL client!\n"); - return; - } - - GLES2_PRINT("\tRequesting worker to exit.\n"); - - // Make sure nothing is running. - GLES2_PRINT("Syncing with worker...\n"); - pthread_mutex_lock(&client->mutex_wait); - while (client->state != gles2_ClientState_ready) { - pthread_cond_wait(&client->cond_state, &client->mutex_wait); - } - pthread_mutex_lock(&client->mutex_run); - client->call = NULL; - client->state = gles2_ClientState_pending; - GLES2_PRINT("Requesting exit...\n"); - pthread_cond_signal(&client->cond_start); - pthread_mutex_unlock(&client->mutex_wait); - - GLES2_PRINT("Waiting worker to exit...\n"); - do { - pthread_cond_wait(&client->cond_state, &client->mutex_run); - } while (client->state != gles2_ClientState_exit); - pthread_mutex_unlock(&client->mutex_run); - - GLES2_PRINT("\tJoining...\n"); - pthread_join(client->thread, NULL); - pthread_mutex_destroy(&client->mutex_wait); - pthread_mutex_destroy(&client->mutex_run); - pthread_cond_destroy(&client->cond_start); - pthread_cond_destroy(&client->cond_state); - - free(client); - s->clients[nr - 1] = NULL; - - GLES2_PRINT("\tDone!\n"); -} - -/****************************************************************************** - * - * Call tables - * - *****************************************************************************/ - -/* Make a weak stub for every dummy function. */ -#define CALL_DUMMY(func) \ - void gles2_##func##_cb(gles2_State *s, gles2_decode_t *d, struct gles2_Client *c); \ - void gles2_##func##_cb(gles2_State *s, gles2_decode_t *d, struct gles2_Client *c) \ - { \ - GLES2_BARRIER_ARG_NORET; \ - fprintf(stderr, "GLES2: DUMMY " #func "\n"); \ - } - -#define CALL_ENTRY(func) \ - void gles2_##func##_cb(gles2_State *s, gles2_decode_t *d, struct gles2_Client *c); - -#include "gles2_calls.h" - -#undef CALL_ENTRY -#undef CALL_DUMMY - -#define CALL_ENTRY(func) { #func, gles2_##func##_cb }, -#define CALL_DUMMY(func) { #func, gles2_##func##_cb }, - -static gles2_Call const gles2_kcalls[] = -{ - CALL_ENTRY(init) - CALL_ENTRY(exit) -}; - -static gles2_Call const gles2_calls[] = -{ - { "<>", 0 }, -#include "gles2_calls.h" -}; - -#undef CALL_ENTRY - diff --git a/hw/gles2.h b/hw/gles2.h deleted file mode 100644 index 21b2cbe..0000000 --- a/hw/gles2.h +++ /dev/null @@ -1,357 +0,0 @@ -/* Copyright (c) 2009-2010 Nokia Corporation - * - * 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 or - * (at your option) any later version of the License. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - */ - -#ifndef GLES2_H__ -#define GLES2_H__ - -#include "qemu-common.h" -#include "cpu.h" -#include - -#define GLES2_HWBASE 0x6f000000 -#define GLES2_HWSIZE 0x00100000 -#define GLES2_NCLIENTS (GLES2_HWSIZE/TARGET_PAGE_SIZE - 2) -#define GLES2_NHANDLES GLES2_NCLIENTS * 16 -// Address base for host to guest pointer handles. -#define GLES2_HANDLE_BASE 0xCAFE0000 -#define GLES2_HANDLE_MASK 0x0000FFFF // Handle to index bitmask. - -#define GLES2_BARRIER_ARG \ - if (c) { \ - pthread_mutex_lock(&c->mutex_xcode); \ - c->phase_xcode = 1; \ - pthread_cond_signal(&c->cond_xcode); \ - pthread_mutex_unlock(&c->mutex_xcode); \ - GLES2_PRINT("-- ARG BARRIER --\n"); \ - } -#define GLES2_BARRIER_ARG_NORET \ - if (c) { \ - pthread_mutex_lock(&c->mutex_xcode); \ - c->phase_xcode = 3; \ - GLES2_PRINT("-- ARG & RETURN BARRIER --\n"); \ - } -#define GLES2_BARRIER_RET \ - if (c) { \ - pthread_mutex_lock(&c->mutex_xcode); \ - c->phase_xcode = 2; \ - do { \ - pthread_cond_wait(&c->cond_return, &c->mutex_xcode); \ - } while (c->phase_xcode == 2); \ - GLES2_PRINT("-- RETURN BARRIER --\n"); \ - } - -// Round address to lower page boundary. -#define TARGET_PAGE(addr) ((addr) & ~(TARGET_PAGE_SIZE - 1)) -// Return the page offset part of address. -#define TARGET_OFFSET(addr) ((addr) & (TARGET_PAGE_SIZE - 1)) - -//#define GLES2_DEBUG 1 -#define GLES2_DEBUG 0 -#if(GLES2_DEBUG == 1) -# define GLES2_PRINT(format, args...) \ - fprintf(stderr, "GLES2: " format, ##args) -#else -# define GLES2_PRINT(format, args...) (void)0 -#endif // GLES_DEBUG != 1 - -struct gles2_Array; -typedef struct gles2_Array gles2_Array; -struct gles2_Call; -typedef struct gles2_Call gles2_Call; -struct gles2_State; -typedef struct gles2_State gles2_State; - -typedef enum gles2_ClientState -{ - gles2_ClientState_init, - gles2_ClientState_ready, - gles2_ClientState_pending, - gles2_ClientState_running, - gles2_ClientState_done, - gles2_ClientState_exit -} gles2_ClientState; - -// A connected GLES2 client. -typedef struct gles2_Client -{ - gles2_State *s; // Link to the device state the client was connected to. - target_ulong nr; // The client ID from kernel. - - gles2_Call const *call; // Next/current call to perform. - pthread_t thread; // The worker thread. - pthread_cond_t cond_start; // To wake worker for a call. - pthread_cond_t cond_state; // Worker signals when state changes. - volatile gles2_ClientState state;// Status of the client. - pthread_mutex_t mutex_run; // Locked when thread is running, or is - // prevented from doing so. - pthread_mutex_t mutex_wait; // For synchronization of worker and caller. - - pthread_mutex_t mutex_xcode; // For decode/encode synchronization. - volatile int phase_xcode; // Phase of call 0: pending 1: decode done - // 2: exec done 3: encode done - pthread_cond_t cond_xcode; // --''-- - pthread_cond_t cond_return; // --''-- - - gles2_Array *arrays; // Host side vertex pointer arrays. - int narrays; // Number of arrays (the maximum too). -} gles2_Client; - -// The GLES2 device state holder. -struct gles2_State -{ - CPUState *env; // The CPU the device is attached to. - gles2_Client *clients[GLES2_NCLIENTS]; // Array of clients. - void *handles[GLES2_NHANDLES]; // Handles passed from host to guest. - int quality; // Rendering quality. -}; - -typedef unsigned int gles2_decode_t; // Function call decoding state. -typedef uint32_t gles2_target_arg_t; // Target unit argument type. -// Callback for register area access. -typedef void gles2_Callback(gles2_State *s, gles2_decode_t *d, - gles2_Client *c); - -// Information holder for guest->host call. -struct gles2_Call -{ -#ifndef NDEBUG - char const* name; -#endif //!NDEBUG - gles2_Callback* callback; -}; - -// Create and initialize a GLES2 device and attach to CPU. -extern void *gles2_init(CPUState *env); -// Rendering quality option. -extern int gles2_quality; - -/****************************************************************************** - * - * Guest memory continuous access functions - * - *****************************************************************************/ - -// Holder for compiled transfer holder. -typedef struct gles2_CompiledTransfer -{ - unsigned nsections; // Number of physical memory sections in the transfer. - struct - { - char* base; // Base address of the section. - target_ulong len; // Length of the section. - } *sections; // Sections of the transfer. -} gles2_CompiledTransfer; - -// Pre-compile a transfer to or from virtual guest address. -// NOTE: An assumption is made that the mapping is equal for read and write, for -// complicated transfers, use gles2_transfer or Fix It! -extern int gles2_transfer_compile(gles2_CompiledTransfer *tfr, gles2_State *s, - target_ulong va, target_ulong len); -// Execute a pre-compiled transfer. -extern void gles2_transfer_exec(gles2_CompiledTransfer *tfr, gles2_State *s, - void* data, int access_type); -// Free a pre-compiled transfer. -extern void gles2_transfer_free(gles2_CompiledTransfer *tfr); -// Perform a non-compiled transfer between guest and host. -// access_type, read = 0, write = 1, execute = 2 -extern int gles2_transfer(gles2_State *s, target_ulong va, target_ulong len, - void* data, int access_type); - -/****************************************************************************** - * - * Guest memory random access functions - * - *****************************************************************************/ - -// Read an 8-bit byte from target system memory. -extern uint8_t gles2_get_byte(gles2_State *s, target_ulong va); -// Write an 8-bit byte to target system memory. -extern void gles2_put_byte(gles2_State *s, target_ulong va, uint8_t byte); -// Read a 16-bit word from target system memory. -extern uint16_t gles2_get_word(gles2_State *s, target_ulong va); -// Write a 16-bit word to target system memory. -extern void gles2_put_word(gles2_State *s, target_ulong va, uint16_t word); -// Read a 32-bit double word from target system memory. -extern uint32_t gles2_get_dword(gles2_State *s, target_ulong va); -// Write a 32-bit double word to target system memory. -extern void gles2_put_dword(gles2_State *s, target_ulong va, - uint32_t dword); -// Read a 32-bit float from target system memory. -extern float gles2_get_float(gles2_State *s, target_ulong va); -// Write a 32-bit float to target system memory. -extern void gles2_put_float(gles2_State *s, target_ulong va, float flt); - -#define gles2_put_handle(s, va, handle) gles2_put_dword(s, va, handle) -#define gles2_get_handle(s, va) gles2_get_dword(s, va) - -/****************************************************************************** - * - * Handle management functions - * - *****************************************************************************/ - -// Create a handle from host side pointer to be passed to guest. -extern uint32_t gles2_handle_create(gles2_State *s, void* data); -// Find if there is previously created handle for pointer. -extern uint32_t gles2_handle_find(gles2_State *s, void* data); -// Get the host pointer by guest handle. -extern void* gles2_handle_get(gles2_State *s, uint32_t i); -// Release a handle for reuse. -extern void* gles2_handle_free(gles2_State *s, uint32_t i); - -// Get the smallest function argument according to target CPU ABI. -static inline gles2_target_arg_t gles2_arg_raw(gles2_State *s, unsigned i); -static inline gles2_target_arg_t gles2_arg_raw(gles2_State *s, unsigned i) -{ - if (i < 4) { - return s->env->regs[i]; - } - - return gles2_get_dword(s, s->env->regs[13] + 2*0x04 + (i - 4)*0x04); -} - -/****************************************************************************** - * - * ABI function argument decoding functions - * - *****************************************************************************/ - -#define GLES2_DEBUG_ARGS 1 -static inline uint8_t gles2_arg_byte(gles2_State *s, gles2_decode_t *d); -static inline uint8_t gles2_arg_byte(gles2_State *s, gles2_decode_t *d) -{ - uint8_t byte = gles2_arg_raw(s, (*d)++) & 0xFF; -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("byte arg(%d) = %x\n", *d - 1, byte); -#endif - return byte; -} - -static inline uint16_t gles2_arg_word(gles2_State *s, gles2_decode_t *d); -static inline uint16_t gles2_arg_word(gles2_State *s, gles2_decode_t *d) -{ - uint16_t word = gles2_arg_raw(s, (*d)++) & 0xFFFF; -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("word arg(%d) = %x\n", *d - 1, word); -#endif - return word; -} - -static inline uint32_t gles2_arg_dword(gles2_State *s, gles2_decode_t *d); -static inline uint32_t gles2_arg_dword(gles2_State *s, gles2_decode_t *d) -{ - uint32_t dword = gles2_arg_raw(s, (*d)++); -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("dword arg(%d) = %x\n", *d - 1, dword); -#endif - return dword; -} - -static inline uint64_t gles2_arg_qword(gles2_State *s, gles2_decode_t *d); -static inline uint64_t gles2_arg_qword(gles2_State *s, gles2_decode_t *d) -{ - uint64_t qword = gles2_arg_raw(s, (*d)++) - | ((uint64_t)gles2_arg_raw(s, (*d)++) << 32); -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("qword arg(%d) = %"PRIu64"\n", *d - 2, qword); -#endif - return qword; -} - -static inline uint32_t gles2_arg_handle(gles2_State *s, gles2_decode_t *d); -static inline uint32_t gles2_arg_handle(gles2_State *s, gles2_decode_t *d) -{ - uint32_t handle = gles2_arg_raw(s, (*d)++); - -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("handle arg(%d) = %x\n", *d - 1, handle); -#endif - return handle; -} - -// This needs to be its own special function, because we must preserve the byteorder. -static inline float gles2_arg_float(gles2_State *s, gles2_decode_t *d); -static inline float gles2_arg_float(gles2_State *s, gles2_decode_t *d) -{ - unsigned i = (*d)++; - - if (i < 4) { - return *((float*)&s->env->regs[i]); - } - - return gles2_get_float(s, s->env->regs[13] + 2*0x04 + (i - 4)*0x04); -} - -/****************************************************************************** - * - * ABI return value encoding functions - * - *****************************************************************************/ - -static inline void gles2_ret_byte(gles2_State *s, uint8_t byte); -static inline void gles2_ret_byte(gles2_State *s, uint8_t byte) -{ - s->env->regs[0] = byte; -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("byte ret = %d\n", byte); -#endif -} - -static inline void gles2_ret_word(gles2_State *s, uint16_t word); -static inline void gles2_ret_word(gles2_State *s, uint16_t word) -{ - s->env->regs[0] = word; -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("word ret = %d\n", word); -#endif -} - -static inline void gles2_ret_dword(gles2_State *s, uint32_t dword); -static inline void gles2_ret_dword(gles2_State *s, uint32_t dword) -{ - s->env->regs[0] = dword; -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("dword ret = %d\n", dword); -#endif -} - -static inline void gles2_ret_qword(gles2_State *s, uint64_t qword); -static inline void gles2_ret_qword(gles2_State *s, uint64_t qword) -{ - s->env->regs[0] = qword & 0xFFFFFFFF; - s->env->regs[1] = qword >> 32; -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("qword ret = %"PRIu64"\n", qword); -#endif -} - -static inline void gles2_ret_handle(gles2_State *s, uint32_t handle); -static inline void gles2_ret_handle(gles2_State *s, uint32_t handle) -{ - s->env->regs[0] = handle; - -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("handle ret = %x\n", handle); -#endif -} - -static inline void gles2_ret_float(gles2_State *s, float flt); -static inline void gles2_ret_float(gles2_State *s, float flt) -{ - s->env->regs[0] = *(uint32_t*)&flt; - -#if (GLES2_DEBUG_ARGS == 1) - GLES2_PRINT("float ret = %f\n", flt); -#endif -} - -#endif // GLES2_H__ - diff --git a/hw/gles2_calls.c b/hw/gles2_calls.c deleted file mode 100644 index 1cdec75..0000000 --- a/hw/gles2_calls.c +++ /dev/null @@ -1,2796 +0,0 @@ -/* Copyright (c) 2009-2010 Nokia Corporation - * - * 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 or - * (at your option) any later version of the License. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - */ - -#include "gles2.h" -#include "EGL/degl.h" -#include "GLES2/gl2.h" - -#include "gles2_types.h" - -GLES2_CB(eglBindAPI) -{ - GLES2_ARG(TEGLenum, api); - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, eglBindAPI(api)); -} - -GLES2_CB(eglGetDisplay) -{ -// GLES2_ARG(TEGLDisplay, dpy); -// (void)dpy; - GLES2_BARRIER_ARG; - - GLES2_PRINT("Getting display...\n"); - - EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); - - GLES2_PRINT("\tGot host display %p...\n", dpy); - - GLES2_BARRIER_RET; - gles2_ret_TEGLDisplay(s, gles2_handle_create(s, dpy)); -} - -GLES2_CB(eglInitialize) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(Tptr, majorp); - GLES2_ARG(Tptr, minorp); - - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - - GLES2_PRINT("Request to initialize display %p...\n", dpy); - - EGLint major, minor; - if (eglInitialize(dpy, &major, &minor)) { - GLES2_PRINT("Display initialized (EGL %d.%d)!\n", major, minor); - GLES2_BARRIER_RET; - gles2_put_TEGLint(s, majorp, major); - gles2_put_TEGLint(s, minorp, minor); - gles2_ret_TEGLBoolean(s, EGL_TRUE); - return; - } - - GLES2_PRINT("Failed to initialize...\n"); - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, EGL_FALSE); -} - -GLES2_CB(eglTerminate) -{ - GLES2_ARG(TEGLDisplay, dpy_); - - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - - GLES2_PRINT("Request to close display %p...\n", dpy); - - EGLBoolean ret = eglTerminate(dpy); - - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, ret); -} - -GLES2_CB(eglGetConfigs) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(Tptr, configsp); - GLES2_ARG(TEGLint, config_size); - GLES2_ARG(Tptr, num_configp); - - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - - EGLConfig* configs = configsp ? malloc(sizeof(EGLConfig)*config_size) : NULL; - - EGLint num_config; - EGLBoolean ret = eglGetConfigs(dpy, configs, config_size, &num_config); - - GLES2_BARRIER_RET; - if (configs) { - EGLint i; - - for (i = 0; i < num_config; ++i) { - uint32_t handle; - if (!(handle = gles2_handle_find(s, configs[i]))) { - handle = gles2_handle_create(s, configs[i]); - } - gles2_put_TEGLConfig(s, configsp + i*sizeof(TEGLConfig), handle); - } - - free(configs); - } - gles2_put_TEGLint(s, num_configp, num_config); - - gles2_ret_TEGLBoolean(s, ret); -} - -GLES2_CB(eglChooseConfig) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(Tptr, attrib_listp); - GLES2_ARG(Tptr, configsp); - GLES2_ARG(TEGLint, config_size); - GLES2_ARG(Tptr, num_configp); - (void)config_size; - (void)attrib_listp; - - EGLint attrib_list_n = 0; - while (gles2_get_TEGLint(s, attrib_listp - + attrib_list_n*sizeof(EGLint)) != EGL_NONE) { - attrib_list_n += 2; - } - EGLint* attrib_list = malloc((attrib_list_n + 1)*sizeof(EGLint)); - EGLint i; - - for (i = 0; i < attrib_list_n; ++i) { - attrib_list[i] = gles2_get_TEGLint(s, attrib_listp - + i*sizeof(EGLint)); - } - attrib_list[attrib_list_n] = EGL_NONE; - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - - EGLConfig* configs = configsp ? malloc(sizeof(EGLConfig)*config_size) : NULL; - - EGLint num_config; - EGLBoolean ret = eglChooseConfig(dpy, attrib_list, configs, config_size, &num_config); - free(attrib_list); - GLES2_BARRIER_RET; - if (configs) { - EGLint i; - - for (i = 0; i < num_config; ++i) { - uint32_t handle; - if (!(handle = gles2_handle_find(s, configs[i]))) { - handle = gles2_handle_create(s, configs[i]); - } - gles2_put_TEGLConfig(s, configsp + i*sizeof(TEGLConfig), handle); - } - - free(configs); - } - gles2_put_TEGLint(s, num_configp, num_config); - - gles2_ret_TEGLBoolean(s, ret); -} - -GLES2_CB(eglGetConfigAttrib) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLConfig, config); - GLES2_ARG(TEGLint, attribute); - GLES2_ARG(Tptr, valuep); - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - - EGLint value; - EGLBoolean ret = eglGetConfigAttrib(dpy, gles2_handle_get(s, config), attribute, &value); - - GLES2_BARRIER_RET; - - gles2_put_TEGLint(s, valuep, value); - gles2_ret_TEGLBoolean(s, ret); -} - -typedef struct gles2_Surface -{ - uint32_t ddrawp; // Pointer to the offscreen drawable in guest memory. - DEGLDrawable ddraw; // Offscreen drawable, read from guest memory. - EGLSurface surf; // Pointer to the EGL surface. - uint32_t pixelsp; // Pointer to pixels in guest memory. - int pixmap; // True if surface is pixmap. - gles2_CompiledTransfer tfr; // Framebuffer transfer. - int valid; // If the surface is valid. - int id; // DEBUG! -} gles2_Surface; - -// See if guest offscreen drawable was changed and if so, update host copy. -static int gles2_surface_update(gles2_State *s, gles2_Surface *surf) -{ - int ret = 0; - - uint32_t width = gles2_get_dword(s, surf->ddrawp + 0*sizeof(uint32_t)); - uint32_t height = gles2_get_dword(s, surf->ddrawp + 1*sizeof(uint32_t)); - uint32_t depth = gles2_get_dword(s, surf->ddrawp + 2*sizeof(uint32_t)); - uint32_t bpp = gles2_get_dword(s, surf->ddrawp + 3*sizeof(uint32_t)); - uint32_t pixelsp = gles2_get_dword(s, surf->ddrawp + 4*sizeof(uint32_t)); - - if (width != surf->ddraw.width - || height != surf->ddraw.height - || depth != surf->ddraw.depth) { - surf->ddraw.width = width; - surf->ddraw.height = height; - surf->ddraw.depth = depth; - surf->ddraw.bpp = bpp; - ret = 1; - } - - surf->pixelsp = pixelsp; - - return ret; -} - -// TODO: Support swapping of offscreen surfaces. -static void gles2_eglSwapCallback(void* userdata) -{ - (void)userdata; - GLES2_PRINT("Swap called!\n"); -} - -static int surf_id = 1; - -GLES2_CB(eglCreateWindowSurface) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLConfig, config_); - GLES2_ARG(Tptr, winp); - GLES2_ARG(Tptr, attrib_listp); - - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - EGLConfig config = (EGLConfig)gles2_handle_get(s, config_); - (void)attrib_listp; - - gles2_Surface* fsurf; - - if (!(fsurf = malloc(sizeof(*fsurf)))) { - GLES2_PRINT("\tFake window creation failed!\n"); - GLES2_BARRIER_ARG; - GLES2_BARRIER_RET; - gles2_ret_TEGLSurface(s, 0); - return; - } - - fsurf->id = surf_id++; - - fsurf->ddrawp = winp; - fsurf->pixmap = 0; - gles2_surface_update(s, fsurf); - GLES2_BARRIER_ARG; - - GLES2_PRINT("Host window creation requested, %dx%d@%d(Bpp=%d) at 0x%x, ID = %d...\n", - fsurf->ddraw.width, fsurf->ddraw.height, - fsurf->ddraw.depth, fsurf->ddraw.bpp, fsurf->pixelsp, fsurf->id); - - unsigned nbytes = fsurf->ddraw.width*fsurf->ddraw.height*fsurf->ddraw.bpp; - fsurf->ddraw.pixels = malloc(nbytes); - fsurf->ddraw.userdata = fsurf; - fsurf->ddraw.swap = gles2_eglSwapCallback; - - if((fsurf->surf = eglCreateWindowSurface(dpy, config, - (EGLNativeWindowType)&fsurf->ddraw, NULL)) == EGL_NO_CONTEXT) - { - GLES2_PRINT("\tHost window creation failed!\n"); - free(fsurf->ddraw.pixels); - free(fsurf); - GLES2_BARRIER_RET; - gles2_ret_TEGLSurface(s, 0); - return; - } - - GLES2_PRINT("Created at %p!\n", fsurf); - GLES2_BARRIER_RET; - gles2_transfer_compile(&fsurf->tfr, s, fsurf->pixelsp, nbytes); - gles2_ret_TEGLSurface(s, gles2_handle_create(s, fsurf)); -} - -GLES2_CB(eglCreatePixmapSurface) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLConfig, config_); - GLES2_ARG(Tptr, pixmapp); - GLES2_ARG(Tptr, attrib_listp); - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - EGLConfig config = (EGLConfig)gles2_handle_get(s, config_); - (void)attrib_listp; - - gles2_Surface* fsurf; - - if (!(fsurf = malloc(sizeof(*fsurf)))) { - GLES2_PRINT("\tFake pixmap creation failed!\n"); - GLES2_BARRIER_ARG; - GLES2_BARRIER_RET; - gles2_ret_TEGLSurface(s, 0); - return; - } - - fsurf->id = surf_id++; - fsurf->ddrawp = pixmapp; - fsurf->pixmap = 1; - gles2_surface_update(s, fsurf); - GLES2_BARRIER_ARG; - - GLES2_PRINT("Host pixmap creation requested, %dx%d@%d(Bpp=%d) at 0x%x, ID = %d...\n", - fsurf->ddraw.width, fsurf->ddraw.height, - fsurf->ddraw.depth, fsurf->ddraw.bpp, fsurf->pixelsp, fsurf->id); - - unsigned nbytes = fsurf->ddraw.width*fsurf->ddraw.height*fsurf->ddraw.bpp; - fsurf->ddraw.pixels = malloc(nbytes); - fsurf->ddraw.userdata = fsurf; - fsurf->ddraw.swap = gles2_eglSwapCallback; - - if((fsurf->surf = eglCreatePixmapSurface(dpy, config, - (EGLNativeWindowType)&fsurf->ddraw, NULL)) == EGL_NO_CONTEXT) { - GLES2_PRINT("\tHost pixmap creation failed!\n"); - free(fsurf->ddraw.pixels); - free(fsurf); - GLES2_BARRIER_RET; - gles2_ret_TEGLSurface(s, 0); - return; - } - - GLES2_PRINT("Created at %p!\n", fsurf); - GLES2_BARRIER_RET; - gles2_transfer_compile(&fsurf->tfr, s, fsurf->pixelsp, nbytes); - gles2_ret_TEGLSurface(s, gles2_handle_create(s, fsurf)); -} - -GLES2_CB(eglDestroySurface) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLSurface, surface_); - GLES2_BARRIER_ARG_NORET; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - gles2_Surface* fsurf = (EGLSurface)gles2_handle_get(s, surface_); - gles2_handle_free(s, surface_); - - GLES2_PRINT("Destroyed surface ID = %d...\n", fsurf->id); - fsurf->id = -1; - - eglDestroySurface(dpy, fsurf->surf); - free(fsurf->ddraw.pixels); - -// if(fsurf->pixmap == 0) { - gles2_transfer_free(&fsurf->tfr); -// } - free(fsurf); -} - -GLES2_CB(eglBindTexImage) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLSurface, surface_); - GLES2_ARG(TEGLint, buffer); - gles2_CompiledTransfer tfr; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - gles2_Surface* fsurf = (gles2_Surface*)gles2_handle_get(s, surface_); - - // FIXME: Not a very clean way.. - uint32_t pixelsp = gles2_get_dword(s, fsurf->ddrawp + 4*sizeof(uint32_t)); - if (pixelsp) { - unsigned nbytes = fsurf->ddraw.width - * fsurf->ddraw.height*fsurf->ddraw.bpp; - gles2_transfer_compile(&tfr, s, pixelsp, nbytes); - } - GLES2_BARRIER_ARG; - - if (pixelsp) { -// gles2_transfer(s, pixelsp, nbytes, fsurf->ddraw.pixels, 0); - gles2_transfer_exec(&tfr, s, fsurf->ddraw.pixels, 0); - } - - GLES2_PRINT("Binding surface ID = %d!\n", fsurf->id); - - EGLBoolean ret = eglBindTexImage(dpy, &fsurf->ddraw, buffer); - if (pixelsp) { - gles2_transfer_free(&tfr); - } - - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, ret); -} - -GLES2_CB(eglReleaseTexImage) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLSurface, surface_); - GLES2_ARG(TEGLint, buffer); - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - gles2_Surface* fsurf = (gles2_Surface*)gles2_handle_get(s, surface_); - - GLES2_PRINT("Unbinding surface ID = %d!\n", fsurf->id); - - EGLBoolean ret = eglReleaseTexImage(dpy, &fsurf->ddraw, buffer); - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, ret); -} - -GLES2_CB(eglCreateContext) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLConfig, config_); - GLES2_ARG(TEGLContext, share_context_); - GLES2_ARG(Tptr, attrib_listp); - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - EGLConfig config = (EGLConfig)gles2_handle_get(s, config_); - EGLContext share_context = (EGLContext)gles2_handle_get(s, share_context_); - - GLES2_PRINT("TODO: Handle attribs...\n"); - (void)attrib_listp; - - GLES2_PRINT("Host context creation requested...\n"); - EGLContext ctx; - if ((ctx = eglCreateContext(dpy, config, - share_context, NULL)) == EGL_NO_CONTEXT) { - GLES2_PRINT("\tContext creation failed!\n"); - GLES2_BARRIER_RET; - gles2_ret_TEGLContext(s, 0); - return; - } - GLES2_PRINT("Created at %p!\n", ctx); - GLES2_BARRIER_RET; - gles2_ret_TEGLContext(s, gles2_handle_create(s, ctx)); -} - -GLES2_CB(eglDestroyContext) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLContext, ctx_); - GLES2_BARRIER_ARG; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - EGLContext ctx = (EGLContext)gles2_handle_get(s, ctx_); - gles2_handle_free(s, ctx_); - GLES2_PRINT("Destroyed %p!\n", ctx); - - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, eglDestroyContext(dpy, ctx)); -} - - -GLES2_CB(eglMakeCurrent) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLSurface, draw_); - GLES2_ARG(TEGLSurface, read_); - GLES2_ARG(TEGLContext, ctx_); - GLES2_BARRIER_ARG; - int i; - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - gles2_Surface* draw = (EGLSurface)gles2_handle_get(s, draw_); - gles2_Surface* read = (EGLSurface)gles2_handle_get(s, read_); - EGLContext ctx = (EGLContext)gles2_handle_get(s, ctx_); - - GLES2_PRINT("Making host context current...\n"); - - if (!eglMakeCurrent(dpy, - draw ? draw->surf : NULL, - read ? read->surf : NULL, - ctx)) { - GLES2_PRINT("\tMakeCurrent failed!\n"); - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, EGL_FALSE); - return; - } - - // Initialize client state. - if (ctx) { - c->narrays = 0; - int vattrib_num = 0; - - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &vattrib_num); - GLES2_PRINT("Maximum number of host vertex arrays: %d.\n", vattrib_num); - - c->narrays += vattrib_num; - - // for gles v1. - c->narrays += 4; //glVertexPointer, glNormalPointer, glColorPointer, glTexCoordPointer - - c->arrays = malloc(c->narrays * sizeof(*c->arrays)); - for (i = 0; i < c->narrays; ++i) { - c->arrays[i].type = GL_NONE; - c->arrays[i].enabled = 0; - c->arrays[i].ptr = 0; - c->arrays[i].apply = 0; - c->arrays[i].tptr = 0; - } - } - - GLES2_PRINT("Made %p current (DRAW = %d, READ = %d)!\n", ctx, draw ? draw->id : 0, read ? read->id : 0); - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, EGL_TRUE); -} - -GLES2_CB(eglSwapBuffers) -{ - GLES2_ARG(TEGLDisplay, dpy_); - GLES2_ARG(TEGLSurface, surface_); - - EGLDisplay dpy = (EGLDisplay)gles2_handle_get(s, dpy_); - gles2_Surface* fsurf = (EGLSurface)gles2_handle_get(s, surface_); - if (!fsurf) { - fprintf(stderr, "ERROR: Trying to swap NULL surface!\n"); - GLES2_BARRIER_ARG; - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, EGL_TRUE); - return; - } - - if (gles2_surface_update(s, fsurf)) { - GLES2_BARRIER_ARG; - GLES2_PRINT("DIMENSIONS CHANGED!\n"); - glFinish(); - free(fsurf->ddraw.pixels); - unsigned nbytes = fsurf->ddraw.width - * fsurf->ddraw.height*fsurf->ddraw.bpp; - fsurf->ddraw.pixels = malloc(nbytes); - - gles2_transfer_free(&fsurf->tfr); - GLES2_BARRIER_RET; - gles2_transfer_compile(&fsurf->tfr, s, fsurf->pixelsp, nbytes); - eglSwapBuffers(dpy, fsurf->surf); - gles2_ret_TEGLBoolean(s, EGL_TRUE); - return; - } - GLES2_BARRIER_ARG; - - GLES2_PRINT("Swapping DGLES2 surface ID = %d!\n", fsurf->id); - eglSwapBuffers(dpy, fsurf->surf); - - GLES2_PRINT("Transferring frame!\n"); - gles2_transfer_exec(&fsurf->tfr, s, fsurf->ddraw.pixels, 1); - GLES2_PRINT("\tDone!\n"); - GLES2_BARRIER_RET; - gles2_ret_TEGLBoolean(s, EGL_TRUE); -} - -GLES2_CB(glClearColor) -{ - GLES2_ARG(TGLclampf, red); - GLES2_ARG(TGLclampf, green); - GLES2_ARG(TGLclampf, blue); - GLES2_ARG(TGLclampf, alpha); - GLES2_BARRIER_ARG_NORET; - - glClearColor(red, green, blue, alpha); -} - - -GLES2_CB(glClear) -{ - GLES2_ARG(TGLbitfield, mask); - GLES2_BARRIER_ARG_NORET; - - glClear(mask); -} - -GLES2_CB(glDisableVertexAttribArray) -{ - GLES2_ARG(TGLuint, index); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Disabling array %d\n", index); - c->arrays[index].enabled = 0; - glDisableVertexAttribArray(index); -} - -static void fglTransferArrays(gles2_State *s, gles2_Client *c, - GLint first, GLsizei count) -{ - int i; - - for(i = 0; i < c->narrays; ++i) { - gles2_Array* va = c->arrays + i; - if(!va->enabled) { - continue; - } - unsigned esize = 1; - switch (va->type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: esize = 1; break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: esize = 2; break; - case GL_FIXED: - case GL_FLOAT: esize = 4; break; - - default: - GLES2_PRINT("ERROR: Unknown type 0x%x in fglTransferArrays!\n", va->type); - exit(0); - break; - - } - if (!va->stride) { - va->stride = va->size*esize; - } - va->real_stride = va->size*esize; - - if (va->ptr) { - free(va->ptr); - } - unsigned nbytes = esize*count*va->size; - va->ptr = malloc(nbytes); - - GLsizei j; - for (j = 0; j < count; ++j) { - signed k; - for (k = 0; k < va->size; ++k) { - switch (esize) { - case 1: - ((TGLubyte*)va->ptr)[j*va->size + k] = - gles2_get_byte(s, va->tptr + va->stride*(first + j) - + k*sizeof(TGLubyte)); - break; - case 2: - ((TGLushort*)va->ptr)[j*va->size + k] = - gles2_get_word(s, va->tptr + va->stride*(first + j) - + k*sizeof(TGLushort)); - break; - case 4: - if(va->type == GL_FLOAT) { - ((TGLfloat*)va->ptr)[j*va->size + k] = - gles2_get_float(s, va->tptr - + va->stride*(first + j) - + k*sizeof(TGLfloat)); - } else { - ((TGLuint*)va->ptr)[j*va->size + k] = - gles2_get_dword(s, va->tptr - + va->stride*(first + j) - + k*sizeof(TGLuint)); - } - break; - } - } - } - - va->apply(va); - } -} - -static void fglApplyVertexAttrib(gles2_Array *va) -{ - glVertexAttribPointer(va->indx, va->size, va->type, - va->normalized, 0, va->ptr); - GLenum error; - - if ((error = glGetError()) != GL_NO_ERROR) { - GLES2_PRINT("glVertexAttribPointer(%d, %d, 0x%x, 0, %d, %p\n)" - " failed with 0x%x!\n", va->indx, va->size, va->type, - va->normalized, va->ptr, error); - } -} - -GLES2_CB(glDrawArrays) -{ - GLES2_ARG(TGLenum, mode); - GLES2_ARG(TGLint, first); - GLES2_ARG(TGLsizei, count); - - fglTransferArrays(s, c, first, count); - GLES2_BARRIER_ARG_NORET; - - glDrawArrays(mode, 0, count); -} - -GLES2_CB(glDrawElements) -{ - GLES2_ARG(TGLenum, mode); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(TGLenum, type); - GLES2_ARG(Tptr, indicesp); - - (void)indicesp; - (void)count; - (void)mode; - - GLint indice_size; - switch (type) { - case GL_UNSIGNED_BYTE: indice_size = sizeof(TGLubyte); break; - case GL_UNSIGNED_SHORT: indice_size = sizeof(TGLushort); break; - default: - fprintf(stderr, "ERROR: Invalid type %d!\n", type); - return; - } - - int i, first = -1, last = -1; - void *copied_indices = malloc(indice_size * count); - for (i = 0; i < count; i++) { - TGLushort idx = 0; - switch (type) { - case GL_UNSIGNED_BYTE: - idx = gles2_get_byte(s, indicesp++); - ((TGLubyte *)copied_indices)[i] = (TGLubyte)idx; - break; - case GL_UNSIGNED_SHORT: - idx = gles2_get_word(s, indicesp); - ((TGLushort *)copied_indices)[i] = idx; - indicesp += 2; - break; - default: - break; - } - if (first < 0 || idx < first) { - first = idx; - } - if (last < 0 || idx > last) { - last = idx; - } - } - fglTransferArrays(s, c, first, last - first + 1); - GLES2_BARRIER_ARG_NORET; - - glDrawElements(mode, count, type, copied_indices); - free(copied_indices); -} - -GLES2_CB(glEnableVertexAttribArray) -{ - GLES2_ARG(TGLuint, index); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Enabling array %d\n", index); - c->arrays[index].enabled = 1; - c->arrays[index].apply = fglApplyVertexAttrib; - glEnableVertexAttribArray(index); -} - -#if 0 -GL_APICALL void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, - GLfloat* params) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, - GLint* params) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, - GLenum pname, void** pointer) -{ - DUMMY(); -} -#endif //0 - -GLES2_CB(glVertexAttrib1f) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(TGLfloat, x); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib1f(indx, x); -} - -GLES2_CB(glVertexAttrib1fv) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(Tptr, valuesp); - GLfloat x = gles2_get_float(s, valuesp); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib1f(indx, x); -} - -GLES2_CB(glVertexAttrib2f) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib2f(indx, x, y); -} - -GLES2_CB(glVertexAttrib2fv) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(Tptr, valuesp); - - GLfloat x = gles2_get_float(s, valuesp); - GLfloat y = gles2_get_float(s, valuesp + sizeof(TGLfloat)); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib2f(indx, x, y); -} - -GLES2_CB(glVertexAttrib3f) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_ARG(TGLfloat, z); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib3f(indx, x, y, z); -} - -GLES2_CB(glVertexAttrib3fv) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(Tptr, valuesp); - - GLfloat x = gles2_get_float(s, valuesp + 0*sizeof(TGLfloat)); - GLfloat y = gles2_get_float(s, valuesp + 1*sizeof(TGLfloat)); - GLfloat z = gles2_get_float(s, valuesp + 2*sizeof(TGLfloat)); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib3f(indx, x, y, z); -} - -GLES2_CB(glVertexAttrib4f) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_ARG(TGLfloat, z); - GLES2_ARG(TGLfloat, w); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib4f(indx, x, y, z, w); -} - -GLES2_CB(glVertexAttrib4fv) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(Tptr, valuesp); - - GLfloat x = gles2_get_float(s, valuesp + 0*sizeof(TGLfloat)); - GLfloat y = gles2_get_float(s, valuesp + 1*sizeof(TGLfloat)); - GLfloat z = gles2_get_float(s, valuesp + 2*sizeof(TGLfloat)); - GLfloat w = gles2_get_float(s, valuesp + 3*sizeof(TGLfloat)); - GLES2_BARRIER_ARG_NORET; - - glVertexAttrib4f(indx, x, y, z, w); -} - -GLES2_CB(glVertexAttribPointer) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(TGLint, size); - GLES2_ARG(TGLenum, type); - GLES2_ARG(TGLboolean, normalized); - GLES2_ARG(TGLsizei, stride); - GLES2_ARG(Tptr, tptr); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Array %d at 0x%x (%d elements every %d bytes)\n", - indx, tptr, size, stride); - - gles2_Array *va = c->arrays + indx; - va->type = type; - va->indx = indx; - va->size = size; - va->normalized = normalized; - va->stride = stride; - va->tptr = tptr; -} - -GLES2_CB(glGetVertexAttribPointerv) -{ - GLES2_ARG(TGLuint, indx); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, tptr); - - Tptr res = 0; - - if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) - GLES2_PRINT("ERROR: Unknown pname 0x%x in glGetVertexAttribPointerv!\n", pname); - - res = c->arrays[indx].tptr; - - GLES2_BARRIER_RET; - gles2_put_Tptr(s, tptr, res); -} - - -static unsigned gles2_glGetCount(TGLenum pname) -{ - unsigned count; - switch(pname) { - case GL_ACTIVE_TEXTURE: count = 1; break; - case GL_ALIASED_LINE_WIDTH_RANGE: count = 2; break; - case GL_ALIASED_POINT_SIZE_RANGE: count = 2; break; - case GL_ALPHA_BITS: count = 1; break; - case GL_ARRAY_BUFFER_BINDING: count = 1; break; - case GL_BLEND: count = 1; break; - case GL_BLEND_COLOR: count = 4; break; - case GL_BLEND_DST_ALPHA: count = 1; break; - case GL_BLEND_DST_RGB: count = 1; break; - case GL_BLEND_EQUATION_ALPHA: count = 1; break; - case GL_BLEND_EQUATION_RGB: count = 1; break; - case GL_BLEND_SRC_ALPHA: count = 1; break; - case GL_BLEND_SRC_RGB: count = 1; break; - case GL_BLUE_BITS: count = 1; break; - case GL_COLOR_CLEAR_VALUE: count = 4; break; - case GL_COLOR_WRITEMASK: count = 4; break; - case GL_COMPRESSED_TEXTURE_FORMATS: count = GL_NUM_COMPRESSED_TEXTURE_FORMATS; break; - case GL_CULL_FACE: count = 1; break; - case GL_CULL_FACE_MODE: count = 1; break; - case GL_CURRENT_PROGRAM: count = 1; break; - case GL_DEPTH_BITS: count = 1; break; - case GL_DEPTH_CLEAR_VALUE: count = 1; break; - case GL_DEPTH_FUNC: count = 1; break; - case GL_DEPTH_RANGE: count = 2; break; - case GL_DEPTH_TEST: count = 1; break; - case GL_DEPTH_WRITEMASK: count = 1; break; - case GL_DITHER: count = 1; break; - case GL_ELEMENT_ARRAY_BUFFER_BINDING: count = 1; break; - case GL_FRAMEBUFFER_BINDING: count = 1; break; - case GL_FRONT_FACE: count = 1; break; - case GL_GENERATE_MIPMAP_HINT: count = 1; break; - case GL_GREEN_BITS: count = 1; break; - case GL_IMPLEMENTATION_COLOR_READ_FORMAT: count = 1; break; - case GL_IMPLEMENTATION_COLOR_READ_TYPE: count = 1; break; - case GL_LINE_WIDTH: count = 1; break; - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: count = 1; break; - case GL_MAX_CUBE_MAP_TEXTURE_SIZE: count = 1; break; - case GL_MAX_FRAGMENT_UNIFORM_VECTORS: count = 1; break; - case GL_MAX_RENDERBUFFER_SIZE: count = 1; break; - case GL_MAX_TEXTURE_IMAGE_UNITS: count = 1; break; - case GL_MAX_TEXTURE_SIZE: count = 1; break; - case GL_MAX_VARYING_VECTORS: count = 1; break; - case GL_MAX_VERTEX_ATTRIBS: count = 1; break; - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: count = 1; break; - case GL_MAX_VERTEX_UNIFORM_VECTORS: count = 1; break; - case GL_MAX_VIEWPORT_DIMS: count = 2; break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS: count = 1; break; - case GL_NUM_SHADER_BINARY_FORMATS: count = 1; break; - case GL_PACK_ALIGNMENT: count = 1; break; - case GL_POLYGON_OFFSET_FACTOR: count = 1; break; - case GL_POLYGON_OFFSET_FILL: count = 1; break; - case GL_POLYGON_OFFSET_UNITS: count = 1; break; - case GL_RED_BITS: count = 1; break; - case GL_RENDERBUFFER_BINDING: count = 1; break; - case GL_SAMPLE_BUFFERS: count = 1; break; - case GL_SAMPLE_COVERAGE_INVERT: count = 1; break; - case GL_SAMPLE_COVERAGE_VALUE: count = 1; break; - case GL_SAMPLES: count = 1; break; - case GL_SCISSOR_BOX: count = 4; break; - case GL_SCISSOR_TEST: count = 1; break; - case GL_SHADER_BINARY_FORMATS: count = GL_NUM_SHADER_BINARY_FORMATS; break; - case GL_SHADER_COMPILER: count = 1; break; - case GL_STENCIL_BACK_FAIL: count = 1; break; - case GL_STENCIL_BACK_FUNC: count = 1; break; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: count = 1; break; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: count = 1; break; - case GL_STENCIL_BACK_REF: count = 1; break; - case GL_STENCIL_BACK_VALUE_MASK: count = 1; break; - case GL_STENCIL_BACK_WRITEMASK: count = 1; break; - case GL_STENCIL_BITS: count = 1; break; - case GL_STENCIL_CLEAR_VALUE: count = 1; break; - case GL_STENCIL_FAIL: count = 1; break; - case GL_STENCIL_FUNC: count = 1; break; - case GL_STENCIL_PASS_DEPTH_FAIL: count = 1; break; - case GL_STENCIL_PASS_DEPTH_PASS: count = 1; break; - case GL_STENCIL_REF: count = 1; break; - case GL_STENCIL_TEST: count = 1; break; - case GL_STENCIL_VALUE_MASK: count = 1; break; - case GL_STENCIL_WRITEMASK: count = 1; break; - case GL_SUBPIXEL_BITS: count = 1; break; - case GL_TEXTURE_BINDING_2D: count = 1; break; - case GL_TEXTURE_BINDING_CUBE_MAP: count = 1; break; - case GL_UNPACK_ALIGNMENT: count = 1; break; - case GL_VIEWPORT: count = 4; break; - default: - count = gles1_glGetCount(pname); - //GLES2_PRINT("ERROR: Unknown pname 0x%x in glGet!\n", pname); - //count = 1; - break; - } - - GLES2_PRINT("glGet(0x%x) -> %u!\n", pname, count); - - return count; -} - -GLES2_CB(glGetBooleanv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - GLboolean params[4]; - glGetBooleanv(pname, params); - unsigned const count = gles2_glGetCount(pname); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < count; ++i) { - gles2_put_TGLboolean(s, paramsp + i*sizeof(TGLboolean), params[i]); - } -} - -GLES2_CB(glGetError) -{ - GLES2_BARRIER_ARG; - GLES2_BARRIER_RET; - gles2_ret_TGLenum(s, glGetError()); -} - -GLES2_CB(eglGetError) -{ - GLES2_BARRIER_ARG; - GLES2_BARRIER_RET; - gles2_ret_TGLint(s, eglGetError()); -} - -GLES2_CB(glGetFloatv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - GLfloat params[4]; - glGetFloatv(pname, params); - unsigned const count = gles2_glGetCount(pname); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < count; ++i) { - gles2_put_TGLfloat(s, paramsp + i*sizeof(TGLfloat), params[i]); - } -} - -GLES2_CB(glGetIntegerv) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - GLint params[4]; - glGetIntegerv(pname, params); - unsigned const count = gles2_glGetCount(pname); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < count; ++i) { - gles2_put_TGLint(s, paramsp + i*sizeof(TGLint), params[i]); - } -} - -GLES2_CB(glColorMask) -{ - GLES2_ARG(TGLboolean, red); - GLES2_ARG(TGLboolean, green); - GLES2_ARG(TGLboolean, blue); - GLES2_ARG(TGLboolean, alpha); - GLES2_BARRIER_ARG_NORET; - - glColorMask(red, green, blue, alpha); -} - -GLES2_CB(glCullFace) -{ - GLES2_ARG(TGLenum, mode); - GLES2_BARRIER_ARG_NORET; - - glCullFace(mode); -} - -GLES2_CB(glDisable) -{ - GLES2_ARG(TGLenum, cap); - GLES2_BARRIER_ARG; - - glDisable(cap); - GLES2_BARRIER_RET; -} - -GLES2_CB(glEnable) -{ - GLES2_ARG(TGLenum, cap); - GLES2_BARRIER_ARG; - - glEnable(cap); - - GLES2_BARRIER_RET; -} - -GLES2_CB(glFinish) -{ - // Important to do this way, so that we don't return too early. - GLES2_BARRIER_ARG; - glFinish(); - GLES2_BARRIER_RET; -} - -GLES2_CB(glFlush) -{ - GLES2_BARRIER_ARG_NORET; - glFlush(); -} - -GLES2_CB(glFrontFace) -{ - GLES2_ARG(TGLenum, mode); - GLES2_BARRIER_ARG_NORET; - - glFrontFace(mode); -} - -GLES2_CB(glIsEnabled) -{ - GLES2_ARG(TGLenum, cap); - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TGLboolean(s, glIsEnabled(cap)); -} - -GLES2_CB(glHint) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, mode); - GLES2_BARRIER_ARG_NORET; - - if(s->quality <= 75) - { - switch(target) - { - default: mode = GL_FASTEST; break; - } - } - - glHint(target, mode); -} - -GLES2_CB(glLineWidth) -{ - GLES2_ARG(TGLfloat, width); - GLES2_BARRIER_ARG_NORET; - - glLineWidth(width); -} - -GLES2_CB(glPolygonOffset) -{ - GLES2_ARG(TGLfloat, factor); - GLES2_ARG(TGLfloat, units); - GLES2_BARRIER_ARG_NORET; - - glPolygonOffset(factor, units); -} - -GLES2_CB(glSampleCoverage) -{ - GLES2_ARG(TGLclampf, value); - GLES2_ARG(TGLboolean, invert); - GLES2_BARRIER_ARG_NORET; - - glSampleCoverage(value, invert); -} - -GLES2_CB(glScissor) -{ - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_BARRIER_ARG_NORET; - - glScissor(x, y, width, height); -} - -GLES2_CB(glViewport) -{ - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_BARRIER_ARG_NORET; - - glViewport(x, y, width, height); -} - -GLES2_CB(glActiveTexture) -{ - GLES2_ARG(TGLenum, texture); - GLES2_BARRIER_ARG_NORET; - - glActiveTexture(texture); -} - -GLES2_CB(glBindTexture) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLuint, texture); - GLES2_BARRIER_ARG_NORET; - - glBindTexture(target, texture); -} - -#if 0 -GL_APICALL void GL_APIENTRY glCompressedTexImage2D(GLenum target, - GLint level, GLenum internalformat, GLsizei width, GLsizei height, - GLint border, GLsizei imageSize, const void* data) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, - GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, const void* data) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, - GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, - GLint border) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint x, GLint y, - GLsizei width, GLsizei height) -{ - DUMMY(); -} -#endif // 0 - -GLES2_CB(glDeleteTextures) -{ - GLES2_ARG(TGLsizei, n); - GLES2_ARG(Tptr, texturesp); - - GLsizei i; - GLuint* textures = (GLuint*)malloc(sizeof(GLuint)*n); - for(i = 0; i < n; ++i) { - textures[i] = gles2_get_TGLuint(s, texturesp + i*sizeof(TGLuint)); - } - GLES2_BARRIER_ARG_NORET; - - glDeleteTextures(n, textures); - free(textures); -} - -GLES2_CB(glGenerateMipmap) -{ - GLES2_ARG(TGLenum, target); - GLES2_BARRIER_ARG_NORET; - - glGenerateMipmap(target); -} - -GLES2_CB(glGenTextures) -{ - GLES2_ARG(TGLsizei, n); - GLES2_ARG(Tptr, texturesp); - GLES2_BARRIER_ARG; - - GLsizei i; - GLuint* textures = (GLuint*)malloc(sizeof(GLuint)*n); - glGenTextures(n, textures); - GLES2_BARRIER_RET; - for(i = 0; i < n; ++i) { - gles2_put_TGLuint(s, texturesp + i*sizeof(TGLuint), textures[i]); - } - free(textures); -} - -static unsigned gles2_glTexParameterCount(GLenum pname) -{ - unsigned count; - - switch(pname) { - case GL_TEXTURE_MIN_FILTER: count = 1; break; - case GL_TEXTURE_MAG_FILTER: count = 1; break; - case GL_TEXTURE_WRAP_S: count = 1; break; - case GL_TEXTURE_WRAP_T: count = 1; break; - default: - GLES2_PRINT("ERROR: Unknown texture parameter 0x%x!\n", pname); - count = 1; - break; - } - - return count; -} - -GLES2_CB(glGetTexParameterfv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - GLfloat params[4]; - glGetTexParameterfv(target, pname, params); - unsigned const count = gles2_glTexParameterCount(pname); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < count; ++i) { - gles2_put_TGLfloat(s, paramsp + i*sizeof(TGLfloat), params[i]); - } -} - -GLES2_CB(glGetTexParameteriv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - GLint params[4]; - glGetTexParameteriv(target, pname, params); - unsigned const count = gles2_glTexParameterCount(pname); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < count; ++i) { - gles2_put_TGLint(s, paramsp + i*sizeof(TGLint), params[i]); - } -} - -GLES2_CB(glGetUniformfv) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLint, location); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - const int MAX_SIZE = 16; - GLfloat reserve[MAX_SIZE]; - GLfloat params[MAX_SIZE]; - gles2_transfer(s, paramsp, sizeof(GLfloat)*MAX_SIZE, params, 0); - - memcpy(reserve, params, sizeof(GLfloat)*MAX_SIZE); - - glGetUniformfv(program, location, params); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < MAX_SIZE; ++i) { - if (params[i] != reserve[i]) - gles2_put_TGLfloat(s, paramsp + i*sizeof(TGLfloat), params[i]); - } -} - -GLES2_CB(glGetUniformiv) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLint, location); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - const int MAX_SIZE = 16; - GLint reserve[MAX_SIZE]; - GLint params[MAX_SIZE]; - gles2_transfer(s, paramsp, sizeof(GLint)*MAX_SIZE, params, 0); - - memcpy(reserve, params, sizeof(GLint)*MAX_SIZE); - - glGetUniformiv(program, location, params); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < MAX_SIZE; ++i) { - if (params[i] != reserve[i]) - gles2_put_TGLint(s, paramsp + i*sizeof(TGLint), params[i]); - } -} - -static unsigned gles2_glGetVertexAttribCount(GLenum pname) -{ - unsigned count; - - switch(pname) { - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: count = 1; break; - case GL_VERTEX_ATTRIB_ARRAY_ENABLED: count = 1; break; - case GL_VERTEX_ATTRIB_ARRAY_SIZE: count = 1; break; - case GL_VERTEX_ATTRIB_ARRAY_STRIDE: count = 1; break; - case GL_VERTEX_ATTRIB_ARRAY_TYPE: count = 1; break; - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: count = 1; break; - case GL_CURRENT_VERTEX_ATTRIB: count = 4; break; - default: - GLES2_PRINT("ERROR: Unknown texture parameter 0x%x!\n", pname); - count = 1; - break; - } - - return count; -} - -GLES2_CB(glGetVertexAttribfv) -{ - GLES2_ARG(TGLuint, index); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - const int MAX_SIZE = 4; - GLfloat params[MAX_SIZE]; - - glGetVertexAttribfv(index, pname, params); - unsigned count = gles2_glGetVertexAttribCount(pname); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < count; ++i) { - gles2_put_TGLfloat(s, paramsp + i*sizeof(TGLfloat), params[i]); - } -} - -GLES2_CB(glGetVertexAttribiv) -{ - GLES2_ARG(TGLuint, index); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - const int MAX_SIZE = 4; - GLint params[MAX_SIZE]; - - glGetVertexAttribiv(index, pname, params); - unsigned count = gles2_glGetVertexAttribCount(pname); - unsigned i; - GLES2_BARRIER_RET; - for(i = 0; i < count; ++i) { - gles2_put_TGLint(s, paramsp + i*sizeof(TGLint), params[i]); - } -} - -GLES2_CB(glIsTexture) -{ - GLES2_ARG(TGLuint, texture); - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TGLboolean(s, glIsTexture(texture)); -} - - - -GLES2_CB(glReadPixels) -{ - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_ARG(TGLenum, format); - GLES2_ARG(TGLenum, type); - GLES2_ARG(Tptr, pixelsp); - GLES2_BARRIER_ARG; - - unsigned bpp; - switch (format) { - case GL_ALPHA: bpp = 1; break; - case GL_RGB: bpp = (type == GL_UNSIGNED_BYTE) ? 3 : 2; break; - case GL_RGBA: bpp = (type == GL_UNSIGNED_BYTE) ? 4 : 2; break; - case GL_LUMINANCE: bpp = 1; break; - case GL_LUMINANCE_ALPHA: bpp = 2; break; - default: - GLES2_PRINT("ERROR: Unknown format 0x%x...\n", format); - bpp = 1; - break; - } - - GLES2_PRINT("Reading %dx%dx%d image at %d,%d...\n", - width, height, bpp, x, y); - char* pixels = NULL; - unsigned nbytes = width*height*bpp; - pixels = malloc(nbytes); - - glReadPixels(x, y, width, height, format, type, pixels); - GLES2_BARRIER_RET; - gles2_transfer(s, pixelsp, nbytes, pixels, 1); - free(pixels); -} - -GLES2_CB(glReleaseShaderCompiler) -{ - GLES2_BARRIER_ARG_NORET; - - glReleaseShaderCompiler(); -} - -GLES2_CB(glTexImage2D) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLint, level); - GLES2_ARG(TGLint, internalformat); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_ARG(TGLint, border); - GLES2_ARG(TGLenum, format); - GLES2_ARG(TGLenum, type); - GLES2_ARG(Tptr, pixelsp); - - unsigned bpp; - - switch(format) { - case GL_ALPHA: bpp = 1; break; - case GL_RGB: bpp = (type == GL_UNSIGNED_BYTE) ? 3 : 2; break; - case GL_RGBA: bpp = (type == GL_UNSIGNED_BYTE) ? 4 : 2; break; - case GL_LUMINANCE: bpp = 1; break; - case GL_LUMINANCE_ALPHA: bpp = 2; break; - default: - GLES2_PRINT("ERROR: Unknown format 0x%x...\n", format); - bpp = 1; - break; - } - - GLES2_PRINT("Uploading %dx%dx%d image...\n", width, height, bpp); - char* pixels = NULL; - if (pixelsp) { - unsigned nbytes = width*height*bpp; - pixels = malloc(nbytes); - gles2_transfer(s, pixelsp, nbytes, pixels, 0); - } - GLES2_BARRIER_ARG_NORET; - - glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); - free(pixels); -} - -GLES2_CB(glTexParameterf) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLfloat, param); - GLES2_BARRIER_ARG_NORET; - - glTexParameterf(target, pname, param); -} - -GLES2_CB(glTexParameterfv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - - GLfloat params[4]; - unsigned const count = gles2_glTexParameterCount(pname); - unsigned i; - for (i = 0; i < count; ++i) { - params[i] = gles2_get_TGLfloat(s, paramsp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glTexParameterfv(target, pname, params); -} - -GLES2_CB(glTexParameteri) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLint, param); - GLES2_BARRIER_ARG_NORET; - - if(s->quality <= 50) - { - switch(pname) - { - case GL_TEXTURE_MIN_FILTER: param = GL_NEAREST; break; - case GL_TEXTURE_MAG_FILTER: param = GL_NEAREST; break; - default: break; - } - } - - glTexParameterf(target, pname, param); -} - -GLES2_CB(glTexParameteriv) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - - GLint params[4]; - unsigned const count = gles2_glTexParameterCount(pname); - unsigned i; - for(i = 0; i < count; ++i) { - params[i] = gles2_get_TGLint(s, paramsp + i*sizeof(GLint)); - } - GLES2_BARRIER_ARG_NORET; - - glTexParameteriv(target, pname, params); -} - -GLES2_CB(glTexSubImage2D) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLint, level); - GLES2_ARG(TGLint, xoffset); - GLES2_ARG(TGLint, yoffset); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_ARG(TGLenum, format); - GLES2_ARG(TGLenum, type); - GLES2_ARG(Tptr, pixelsp); - - unsigned bpp; - switch (format) { - case GL_ALPHA: bpp = 1; break; - case GL_RGB: bpp = (type == GL_UNSIGNED_BYTE) ? 3 : 2; break; - case GL_RGBA: bpp = (type == GL_UNSIGNED_BYTE) ? 4 : 2; break; - case GL_LUMINANCE: bpp = 1; break; - case GL_LUMINANCE_ALPHA: bpp = 2; break; - default: - GLES2_PRINT("ERROR: Unknown format 0x%x...\n", format); - bpp = 1; - break; - } - - GLES2_PRINT("Uploading partial %dx%dx%d image at %d,%d...\n", - width, height, bpp, xoffset, yoffset); - - unsigned nbytes = width*height*bpp; - char* pixels = malloc(nbytes); - gles2_transfer(s, pixelsp, nbytes, pixels, 0); - GLES2_BARRIER_ARG_NORET; - - glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - free(pixels); -} - - -GLES2_CB(glCompileShader) -{ - GLES2_ARG(TGLuint, shader); - GLES2_BARRIER_ARG_NORET; - - glCompileShader(shader); -} - -GLES2_CB(glCompressedTexImage2D) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLint, level); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_ARG(TGLenum, internalformat); - GLES2_ARG(TGLint, border); - GLES2_ARG(TGLsizei, imageSize); - GLES2_ARG(Tptr, data); - - GLES2_PRINT("Uploading compressed %dx%d image with size 0x%x and border %d...\n", - width, height, xoffset, yoffset, imageSize, border); - - char* pixels = malloc(imageSize); - gles2_transfer(s, data, imageSize, pixels, 0); - GLES2_BARRIER_ARG_NORET; - - glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels); - free(pixels); -} - -GLES2_CB(glCopyTexImage2D) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLint, level); - GLES2_ARG(TGLenum, internalformat); - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_ARG(TGLint, border); - - GLES2_BARRIER_ARG; - - glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); - - GLES2_BARRIER_RET; -} - - -GLES2_CB(glCompressedTexSubImage2D) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLint, level); - GLES2_ARG(TGLint, xoffset); - GLES2_ARG(TGLint, yoffset); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_ARG(TGLenum, format); - GLES2_ARG(TGLsizei, imageSize); - GLES2_ARG(Tptr, data); - - GLES2_PRINT("Uploading compressed partial %dx%d image at %d,%d with size 0x%x...\n", - width, height, xoffset, yoffset, imageSize); - - char* pixels = malloc(imageSize); - gles2_transfer(s, data, imageSize, pixels, 0); - GLES2_BARRIER_ARG_NORET; - - glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels); - free(pixels); -} - - -GLES2_CB(glCreateShader) -{ - GLES2_ARG(TGLenum, type); - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TGLuint(s, glCreateShader(type)); -} - -GLES2_CB(glDeleteShader) -{ - GLES2_ARG(TGLuint, shader); - GLES2_BARRIER_ARG_NORET; - - glDeleteShader(shader); -} - -GLES2_CB(glIsShader) -{ - GLES2_ARG(TGLuint, shader); - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TGLboolean(s, glIsShader(shader)); -} - -GLES2_CB(glGetShaderiv) -{ - GLES2_ARG(TGLuint, shader); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - GLint param; - glGetShaderiv(shader, pname, ¶m); - GLES2_BARRIER_RET; - gles2_put_TGLint(s, paramsp, param); -} - -GLES2_CB(glGetShaderInfoLog) -{ - GLES2_ARG(TGLuint, shader); - GLES2_ARG(TGLsizei, bufsize); - GLES2_ARG(Tptr, lengthp); - GLES2_ARG(Tptr, infologp); - - GLsizei length = gles2_get_TGLsizei(s, lengthp); - char* infolog = malloc(bufsize); - glGetShaderInfoLog(shader, bufsize, &length, infolog); - gles2_transfer(s, infologp, length, infolog, 1); - gles2_put_TGLsizei(s, lengthp, length); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("shader %d infolog:\n%.*s\n", shader, length, infolog); - free(infolog); -} - -GLES2_CB(glGetShaderPrecisionFormat) -{ - GLES2_ARG(TGLenum, shadertype); - GLES2_ARG(TGLenum, precisiontype); - GLES2_ARG(Tptr, rangep); - GLES2_ARG(Tptr, precisionp); - - GLint range[2] = {0}; - GLint precision = 0; - - glGetShaderPrecisionFormat(shadertype, precisiontype, range, &precision); - - gles2_put_TGLint(s, rangep, range[0]); - gles2_put_TGLint(s, rangep + sizeof(TGLint), range[1]); - gles2_put_TGLint(s, precisionp, precision); - - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("shadertype %d precisiontype %d: range = (%d, %d), " - "precision = %d\n", shadertype, precisiontype, range[0], - range[1], precision); -} - -GLES2_CB(glGetShaderSource) -{ - /* If host OpenGL driver doesn't support some of keywords, - * before call glShaderSource gles library cut these keywords. - * In this case host OpenGL driver returns changed source. - * May be it should be fixed. - * */ - GLES2_ARG(TGLuint, shader); - GLES2_ARG(TGLsizei, bufsize); - GLES2_ARG(Tptr, lengthp); - GLES2_ARG(Tptr, sourcep); - - GLsizei length = lengthp ? gles2_get_TGLsizei(s, lengthp) : 0; - char* source = malloc(bufsize); - glGetShaderSource(shader, bufsize, &length, source); - gles2_transfer(s, sourcep, length, source, 1); - gles2_put_TGLsizei(s, lengthp, length); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("shader %d source:\n%.*s\n", shader, length, source); - free(source); -} - -#if 0 -GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, - GLenum precisiontype, GLint* range, GLint* precision) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, - GLsizei* length, char* source) -{ - DUMMY(); -} - -GL_APICALL GLboolean GL_APIENTRY glIsShader(GLuint shader) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glReleaseShaderCompiler(void) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, - GLenum binaryformat, const void* binary, GLsizei length) -{ - DUMMY(); -} -#endif // 0 - -GLES2_CB(glShaderSource) -{ - GLES2_ARG(TGLuint, shader); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, stringp); - GLES2_ARG(Tptr, lengthp); - - char** string_fgl = malloc(sizeof(char*)*count); - GLint* length_fgl = malloc(sizeof(GLint)*count); - - unsigned i; - for (i = 0; i < count; ++i) { - length_fgl[i] = gles2_get_TGLint(s, lengthp + i*sizeof(TGLint)); - string_fgl[i] = malloc(length_fgl[i] + 1); - gles2_transfer(s, gles2_get_dword(s, stringp + i*sizeof(Tptr)), - length_fgl[i], string_fgl[i], 0); - string_fgl[i][length_fgl[i]] = 0; - } - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("shader %d source:\n", shader); - #if(GLES2_DEBUG == 1) - for(i = 0; i < count; ++i) { - fprintf(stderr, "%.*s", length_fgl[i], string_fgl[i]); - } - #endif // GLES2_DEBUG == 1 - GLES2_PRINT("\n--END--"); - - glShaderSource(shader, (GLsizei)count, - (const char**)string_fgl, length_fgl); - - for (i = 0; i < count; ++i) { - free(string_fgl[i]); - } - - free(string_fgl); - free(length_fgl); -} - -GLES2_CB(glAttachShader) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLuint, shader); - GLES2_BARRIER_ARG_NORET; - - glAttachShader(program, shader); -} - -GLES2_CB(glBindAttribLocation) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLuint, index); - GLES2_ARG(Tptr, namep); - - char name[120]; - Tptr i; - - for(i = 0; (name[i] = gles2_get_byte(s, namep + i)) ; ++i); - GLES2_BARRIER_ARG_NORET; - - GLES2_PRINT("Binding attribute %s at %d...\n", name, index); - glBindAttribLocation(program, index, name); -} - -GLES2_CB(glCreateProgram)//(void) -{ - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TGLuint(s, glCreateProgram()); -} - -GLES2_CB(glCopyTexSubImage2D) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLint, level); - GLES2_ARG(TGLint, xoffset); - GLES2_ARG(TGLint, yoffset); - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - - GLES2_BARRIER_ARG; - - glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); - - GLES2_BARRIER_RET; -} - -GLES2_CB(glDeleteProgram)//(GLuint program) -{ - GLES2_ARG(TGLuint, program); - GLES2_BARRIER_ARG_NORET; - - glDeleteProgram(program); -} - -#if 0 -GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, - GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) -{ - DUMMY(); -} -#endif // 0 - -GLES2_CB(glGetActiveAttrib) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLuint, index); - GLES2_ARG(TGLsizei, bufsize); - GLES2_ARG(Tptr, lengthp); // GLsizei* - GLES2_ARG(Tptr, sizep); // GLint* - GLES2_ARG(Tptr, typep); // GLenum* - GLES2_ARG(Tptr, namep); // char* - GLES2_BARRIER_ARG; - - char* name = malloc(bufsize); - GLsizei length = 0; - GLint size = 0; - GLenum type = 0; - Tptr i; - - glGetError(); - glGetActiveAttrib(program, index, bufsize, &length, &size, &type, name); - GLES2_PRINT("Active attrib: %s\n", name); - - GLES2_BARRIER_RET; - if(lengthp) - gles2_put_TGLsizei(s, lengthp, length); - gles2_put_TGLint(s, sizep, size); - gles2_put_TGLenum(s, typep, type); - (void) (namep + i); - - for (i = 0; i < length; ++i) { - gles2_put_byte(s, namep + i, name[i]); - } - if(i < bufsize) - gles2_put_byte(s, namep + i, 0); - - free(name); -} - -GLES2_CB(glGetActiveUniform) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLuint, index); - GLES2_ARG(TGLsizei, bufsize); - GLES2_ARG(Tptr, lengthp); // GLsizei* - GLES2_ARG(Tptr, sizep); // GLint* - GLES2_ARG(Tptr, typep); // GLenum* - GLES2_ARG(Tptr, namep); // char* - GLES2_BARRIER_ARG; - - char* name = malloc(bufsize); - GLsizei length = 0; - GLint size = 0; - GLenum type = 0; - Tptr i; - - glGetError(); - glGetActiveUniform(program, index, bufsize, &length, &size, &type, name); - GLES2_PRINT("Active uniform: %s\n", name); - - GLES2_BARRIER_RET; - if(lengthp) - gles2_put_TGLsizei(s, lengthp, length); - gles2_put_TGLint(s, sizep, size); - gles2_put_TGLenum(s, typep, type); - (void) (namep + i); - - for (i = 0; i < length; ++i) { - gles2_put_byte(s, namep + i, name[i]); - } - if(i < bufsize) - gles2_put_byte(s, namep + i, 0); - - free(name); -} - -GLES2_CB(glGetAttachedShaders) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLsizei, maxCount); - GLES2_ARG(Tptr, countp); // GLsizei* - GLES2_ARG(Tptr, shadersp); // GLuint* - GLES2_BARRIER_ARG; - - GLuint* shaders = malloc(maxCount); - GLsizei count = 0; - - glGetAttachedShaders(program, maxCount, &count, shaders); - - GLES2_BARRIER_RET; - gles2_put_TGLsizei(s, countp, count); - - unsigned i; - for (i = 0; i < count; ++i) { - gles2_put_TGLuint(s, shadersp + i*sizeof(TGLuint), shaders[i]); - } - - free(shaders); -} - - -#if 0 -GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, - GLsizei maxcount, GLsizei* count, GLuint* shaders) -{ - DUMMY(); -} -#endif // 0 - -GLES2_CB(glGetAttribLocation) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(Tptr, namep); - - char name[120]; - Tptr i; - - for (i = 0; (name[i] = gles2_get_byte(s, namep + i)) ; ++i); - - GLES2_PRINT("Getting attribute %s location...\n", name); - - gles2_ret_TGLint(s, glGetAttribLocation(program, name)); - GLES2_BARRIER_ARG_NORET; -} - -GLES2_CB(glGetProgramiv) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLenum, pname); - GLES2_ARG(Tptr, paramsp); - GLES2_BARRIER_ARG; - - GLint param; - - glGetProgramiv(program, pname, ¶m); - GLES2_BARRIER_RET; - gles2_put_TGLint(s, paramsp, param); -} - -GLES2_CB(glGetProgramInfoLog) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLsizei, bufsize); - GLES2_ARG(Tptr, lengthp); - GLES2_ARG(Tptr, infologp); - - GLsizei length = gles2_get_TGLsizei(s, lengthp); - char* infolog = malloc(bufsize); - glGetProgramInfoLog(program, bufsize, &length, infolog); - gles2_transfer(s, infologp, length, infolog, 1); - gles2_put_TGLsizei(s, lengthp, length); - GLES2_BARRIER_ARG_NORET; - GLES2_PRINT("program %d infolog:\n%.*s\n", program, length, infolog); - free(infolog); -} - -#if 0 -GL_APICALL void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params) -{ - DUMMY(); -} - -GL_APICALL void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params) -{ - DUMMY(); -} -#endif // 0 - -GLES2_CB(glGetUniformLocation) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(Tptr, namep); - - char name[120]; - Tptr i; - - for (i = 0; (name[i] = gles2_get_byte(s, namep + i)) ; ++i); - - GLES2_PRINT("Getting uniform %s location...\n", name); - - gles2_ret_TGLint(s, glGetUniformLocation(program, name)); - GLES2_BARRIER_ARG_NORET; -} - -GLES2_CB(glIsProgram) -{ - GLES2_ARG(TGLuint, program); - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TGLboolean(s, glIsProgram(program)); -} - -GLES2_CB(glLinkProgram) -{ - GLES2_ARG(TGLuint, program); - GLES2_BARRIER_ARG_NORET; - - glLinkProgram(program); -} - -GLES2_CB(glUniform1f) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLfloat, x); - GLES2_BARRIER_ARG_NORET; - - glUniform1f(location, x); -} - -GLES2_CB(glUniform1fv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*1; - GLfloat* v = malloc(nvs*sizeof(*v)); - unsigned i; - - for (i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLint(s, vp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glUniform1fv(location, count, v); - free(v); -} - -GLES2_CB(glUniform1i)//(GLint location, GLint x) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLint, x); - GLES2_BARRIER_ARG_NORET; - - glUniform1i(location, x); -} - -GLES2_CB(glUniform1iv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*1; - GLint* v = malloc(nvs*sizeof(*v)); - unsigned i; - for (i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLint(s, vp + i*sizeof(TGLint)); - } - GLES2_BARRIER_ARG_NORET; - - glUniform1iv(location, count, v); - free(v); -} - -GLES2_CB(glUniform2f) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_BARRIER_ARG_NORET; - - glUniform2f(location, x, y); -} - -GLES2_CB(glUniform2fv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*2; - GLfloat* v = malloc(nvs*sizeof(*v)); - unsigned i; - for (i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLfloat(s, vp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glUniform2fv(location, count, v); - free(v); -} - -GLES2_CB(glUniform2i) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_BARRIER_ARG_NORET; - - glUniform2i(location, x, y); -} - -GLES2_CB(glUniform2iv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*2; - GLint* v = malloc(nvs*sizeof(*v)); - unsigned i; - for (i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLint(s, vp + i*sizeof(TGLint)); - } - GLES2_BARRIER_ARG_NORET; - - glUniform2iv(location, count, v); - free(v); -} - -GLES2_CB(glUniform3f) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_ARG(TGLfloat, z); - GLES2_BARRIER_ARG_NORET; - - glUniform3f(location, x, y, z); -} - -GLES2_CB(glUniform3fv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*3; - GLfloat* v = malloc(nvs*sizeof(*v)); - unsigned i; - for(i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLfloat(s, vp + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glUniform3fv(location, count, v); - free(v); -} - -GLES2_CB(glUniform3i) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_ARG(TGLint, z); - GLES2_BARRIER_ARG_NORET; - - glUniform3i(location, x, y, z); -} - -GLES2_CB(glUniform3iv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*3; - GLint* v = malloc(nvs*sizeof(*v)); - unsigned i; - for(i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLint(s, vp + i*sizeof(TGLint)); - } - GLES2_BARRIER_ARG_NORET; - - glUniform3iv(location, count, v); - free(v); -} - -GLES2_CB(glUniform4f) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLfloat, x); - GLES2_ARG(TGLfloat, y); - GLES2_ARG(TGLfloat, z); - GLES2_ARG(TGLfloat, w); - GLES2_BARRIER_ARG_NORET; - - glUniform4f(location, x, y, z, w); -} - -GLES2_CB(glUniform4fv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*4; - GLfloat* v = malloc(nvs*sizeof(*v)); - unsigned i; - for(i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLfloat(s, vp + i*sizeof(TGLfloat)); - } - - GLES2_BARRIER_ARG_NORET; - glUniform4fv(location, count, v); - free(v); -} - -GLES2_CB(glUniform4i) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLint, x); - GLES2_ARG(TGLint, y); - GLES2_ARG(TGLint, z); - GLES2_ARG(TGLint, w); - GLES2_BARRIER_ARG_NORET; - - glUniform4i(location, x, y, z, w); -} - -GLES2_CB(glUniform4iv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLsizei, count); - GLES2_ARG(Tptr, vp); - - unsigned nvs = count*4; - GLint* v = malloc(nvs*sizeof(*v)); - unsigned i; - for(i = 0; i < nvs; ++i) { - v[i] = gles2_get_TGLint(s, vp + i*sizeof(TGLint)); - } - - GLES2_BARRIER_ARG_NORET; - glUniform4iv(location, count, v); - free(v); -} - -GLES2_CB(glUniformMatrix2fv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLint, count); - GLES2_ARG(TGLboolean, transpose); - GLES2_ARG(Tptr, valuep); - - unsigned nfloats = 2*2*count; - GLfloat* value = malloc(nfloats*sizeof(TGLfloat)); - unsigned i; - - for (i = 0; i < nfloats; ++i) { - value[i] = gles2_get_TGLfloat(s, valuep + i*sizeof(TGLfloat)); - } - - GLES2_BARRIER_ARG_NORET; - - glUniformMatrix2fv(location, count, transpose, value); - free(value); -} - -GLES2_CB(glUniformMatrix3fv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLint, count); - GLES2_ARG(TGLboolean, transpose); - GLES2_ARG(Tptr, valuep); - - unsigned nfloats = 3*3*count; - GLfloat* value = malloc(nfloats*sizeof(TGLfloat)); - unsigned i; - for(i = 0; i < nfloats; ++i) { - value[i] = gles2_get_TGLfloat(s, valuep + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glUniformMatrix3fv(location, count, transpose, value); - free(value); -} - -GLES2_CB(glUniformMatrix4fv) -{ - GLES2_ARG(TGLint, location); - GLES2_ARG(TGLint, count); - GLES2_ARG(TGLboolean, transpose); - GLES2_ARG(Tptr, valuep); - - unsigned nfloats = 4*4*count; - GLfloat* value = malloc(nfloats*sizeof(TGLfloat)); - unsigned i; - for(i = 0; i < nfloats; ++i) { - value[i] = gles2_get_TGLfloat(s, valuep + i*sizeof(TGLfloat)); - } - GLES2_BARRIER_ARG_NORET; - - glUniformMatrix4fv(location, count, transpose, value); - free(value); -} - -GLES2_CB(glUseProgram) -{ - GLES2_ARG(TGLuint, program); - GLES2_BARRIER_ARG_NORET; - - glUseProgram(program); -} - -GLES2_CB(glValidateProgram) -{ - GLES2_ARG(TGLuint, program); - GLES2_BARRIER_ARG_NORET; - - glValidateProgram(program); -} - -GLES2_CB(glBlendColor) -{ - GLES2_ARG(TGLclampf, red); - GLES2_ARG(TGLclampf, green); - GLES2_ARG(TGLclampf, blue); - GLES2_ARG(TGLclampf, alpha); - GLES2_BARRIER_ARG_NORET; - - glBlendColor(red, green, blue, alpha); -} - -GLES2_CB(glBlendEquation) -{ - GLES2_ARG(TGLenum, mode); - GLES2_BARRIER_ARG_NORET; - - glBlendEquation(mode); -} - -GLES2_CB(glBlendEquationSeparate) -{ - GLES2_ARG(TGLenum, modeRGB); - GLES2_ARG(TGLenum, modeAlpha); - GLES2_BARRIER_ARG_NORET; - - glBlendEquationSeparate(modeRGB, modeAlpha); -} - -GLES2_CB(glBlendFunc) -{ - GLES2_ARG(TGLenum, sfactor); - GLES2_ARG(TGLenum, dfactor); - GLES2_BARRIER_ARG_NORET; - - glBlendFunc(sfactor, dfactor); -} - -GLES2_CB(glBlendFuncSeparate) -{ - GLES2_ARG(TGLenum, srcRGB); - GLES2_ARG(TGLenum, dstRGB); - GLES2_ARG(TGLenum, srcAlpha); - GLES2_ARG(TGLenum, dstAlpha); - GLES2_BARRIER_ARG_NORET; - - glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); -} - -GLES2_CB(glPixelStorei) -{ - GLES2_ARG(TGLenum, pname); - GLES2_ARG(TGLint, param); - GLES2_BARRIER_ARG_NORET; - - glPixelStorei(pname, param); -} - -#if 0 -GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program) -{ - DUMMY(); -} -#endif // 0 - -GLES2_CB(glClearStencil) -{ - GLES2_ARG(TGLint, s_); - GLES2_BARRIER_ARG_NORET; - - glClearStencil(s_); -} - -GLES2_CB(glStencilFunc) -{ - GLES2_ARG(TGLenum, func); - GLES2_ARG(TGLint, ref); - GLES2_ARG(TGLuint, mask); - GLES2_BARRIER_ARG_NORET; - - glStencilFunc(func, ref, mask); -} - -GLES2_CB(glStencilFuncSeparate) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, func); - GLES2_ARG(TGLint, ref); - GLES2_ARG(TGLuint, mask); - GLES2_BARRIER_ARG_NORET; - - glStencilFuncSeparate(face, func, ref, mask); -} - -GLES2_CB(glStencilMask) -{ - GLES2_ARG(TGLuint, mask); - GLES2_BARRIER_ARG_NORET; - - glStencilMask(mask); -} - -GLES2_CB(glStencilMaskSeparate) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLuint, mask); - GLES2_BARRIER_ARG_NORET; - - glStencilMaskSeparate(face, mask); -} - -GLES2_CB(glStencilOp) -{ - GLES2_ARG(TGLenum, fail); - GLES2_ARG(TGLenum, zfail); - GLES2_ARG(TGLenum, zpass); - GLES2_BARRIER_ARG_NORET; - - glStencilOp(fail, zfail, zpass); -} - -GLES2_CB(glStencilOpSeparate) -{ - GLES2_ARG(TGLenum, face); - GLES2_ARG(TGLenum, fail); - GLES2_ARG(TGLenum, zfail); - GLES2_ARG(TGLenum, zpass); - GLES2_BARRIER_ARG_NORET; - - glStencilOpSeparate(face, fail, zfail, zpass); -} - -GLES2_CB(glBindFramebuffer) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLuint, framebuffer); - GLES2_BARRIER_ARG_NORET; - - glBindFramebuffer(target, framebuffer); -} - -GLES2_CB(glBindRenderbuffer) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLuint, renderbuffer); - GLES2_BARRIER_ARG_NORET; - - glBindRenderbuffer(target, renderbuffer); -} - -GLES2_CB(glCheckFramebufferStatus) -{ - GLES2_ARG(TGLenum, target); - GLES2_BARRIER_ARG; - - GLES2_BARRIER_RET; - gles2_ret_TGLenum(s, glCheckFramebufferStatus(target)); -} - -GLES2_CB(glDeleteFramebuffers) -{ - GLES2_ARG(TGLsizei, n); - GLES2_ARG(Tptr, framebuffersp); - - GLsizei i; - GLuint* framebuffers = (GLuint*)malloc(sizeof(GLuint)*n); - - for (i = 0; i < n; ++i) { - framebuffers[i] = gles2_get_TGLuint(s, - framebuffersp + i*sizeof(TGLuint)); - } - GLES2_BARRIER_ARG_NORET; - - glDeleteFramebuffers(n, framebuffers); - free(framebuffers); -} - -GLES2_CB(glDeleteRenderbuffers) -{ - GLES2_ARG(TGLsizei, n); - GLES2_ARG(Tptr, renderbuffersp); - - GLsizei i; - GLuint* renderbuffers = (GLuint*)malloc(sizeof(GLuint)*n); - - for (i = 0; i < n; ++i) { - renderbuffers[i] = gles2_get_TGLuint(s, - renderbuffersp + i*sizeof(TGLuint)); - } - GLES2_BARRIER_ARG_NORET; - - glDeleteRenderbuffers(n, renderbuffers); - free(renderbuffers); -} - -GLES2_CB(glFramebufferRenderbuffer) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, attachment); - GLES2_ARG(TGLenum, renderbuffertarget); - GLES2_ARG(TGLuint, renderbuffer); - GLES2_BARRIER_ARG_NORET; - - glFramebufferRenderbuffer(target, attachment, - renderbuffertarget, renderbuffer); -} - -GLES2_CB(glFramebufferTexture2D) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, attachment); - GLES2_ARG(TGLenum, textarget); - GLES2_ARG(TGLuint, texture); - GLES2_ARG(TGLint, level); - GLES2_BARRIER_ARG_NORET; - - glFramebufferTexture2D(target, attachment, textarget, texture, level); -} - -GLES2_CB(glGenFramebuffers) -{ - GLES2_ARG(TGLsizei, n); - GLES2_ARG(Tptr, framebuffersp); - - GLsizei i; - GLuint* framebuffers = (GLuint*)malloc(sizeof(GLuint)*n); - - glGenFramebuffers(n, framebuffers); - for(i = 0; i < n; ++i) { - gles2_put_TGLuint(s, framebuffersp + i*sizeof(TGLuint), - framebuffers[i]); - } - GLES2_BARRIER_ARG_NORET; - - free(framebuffers); -} - -GLES2_CB(glGenRenderbuffers)//(GLsizei n, GLuint* renderbuffers) -{ - GLES2_ARG(TGLsizei, n); - GLES2_ARG(Tptr, renderbuffersp); - - GLsizei i; - GLuint* renderbuffers = (GLuint*)malloc(sizeof(GLuint)*n); - - glGenRenderbuffers(n, renderbuffers); - for(i = 0; i < n; ++i) { - gles2_put_TGLuint(s, renderbuffersp + i*sizeof(TGLuint), - renderbuffers[i]); - } - GLES2_BARRIER_ARG_NORET; - - free(renderbuffers); -} - -#if 0 -GLES2_CB(glGetFramebufferAttachmentParameteriv)//(GLenum target, - GLenum attachment, GLenum pname, GLint* params) -{ - DUMMY(); -} - -GLES2_CB(glGetRenderbufferParameteriv)//(GLenum target, GLenum pname, - GLint* params) -{ - DUMMY(); -} - -GLES2_CB(glIsFramebuffer)//(GLuint framebuffer) -{ - DUMMY(); -} - -GLES2_CB(glIsRenderbuffer)//(GLuint renderbuffer) -{ - DUMMY(); -} -#endif // 0 - -GLES2_CB(glBindBuffer) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLuint, buffer); - GLES2_BARRIER_ARG_NORET; - - glBindTexture(target, buffer); -} - - -GLES2_CB(glRenderbufferStorage) -{ - GLES2_ARG(TGLenum, target); - GLES2_ARG(TGLenum, internalformat); - GLES2_ARG(TGLsizei, width); - GLES2_ARG(TGLsizei, height); - GLES2_BARRIER_ARG_NORET; - - glRenderbufferStorage(target, internalformat, width, height); -} - -GLES2_CB(glDepthFunc) -{ - GLES2_ARG(TGLenum, func); - GLES2_BARRIER_ARG_NORET; - - glDepthFunc(func); -} - -GLES2_CB(glDepthMask) -{ - GLES2_ARG(TGLboolean, flag); - GLES2_BARRIER_ARG_NORET; - - glDepthMask(flag); -} - -GLES2_CB(glDepthRangef) -{ - GLES2_ARG(TGLclampf, zNear); - GLES2_ARG(TGLclampf, zFar); - GLES2_BARRIER_ARG_NORET; - - glDepthRangef(zNear, zFar); -} - -GLES2_CB(glDetachShader) -{ - GLES2_ARG(TGLuint, program); - GLES2_ARG(TGLuint, shader); - GLES2_BARRIER_ARG_NORET; - - glDetachShader(program, shader); -} - -GLES2_CB(glClearDepthf) -{ - GLES2_ARG(TGLclampf, depth); - GLES2_BARRIER_ARG_NORET; - - glClearDepthf(depth); -} - diff --git a/hw/gles2_calls.h b/hw/gles2_calls.h deleted file mode 100644 index 446858f..0000000 --- a/hw/gles2_calls.h +++ /dev/null @@ -1,278 +0,0 @@ -/* Copyright (c) 2009-2010 Nokia Corporation - * - * 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 or - * (at your option) any later version of the License. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - */ - -/*egl*/ -CALL_ENTRY(eglGetError) -CALL_ENTRY(eglGetDisplay) -CALL_ENTRY(eglInitialize) -CALL_ENTRY(eglTerminate) -CALL_DUMMY(eglQueryString) -CALL_ENTRY(eglGetConfigs) -CALL_ENTRY(eglChooseConfig) -CALL_ENTRY(eglGetConfigAttrib) -CALL_ENTRY(eglCreateWindowSurface) -CALL_DUMMY(eglCreatePbufferSurface) -CALL_ENTRY(eglCreatePixmapSurface) -CALL_ENTRY(eglDestroySurface) -CALL_DUMMY(eglQuerySurface) -CALL_ENTRY(eglBindAPI) -CALL_DUMMY(eglQueryAPI) -CALL_DUMMY(eglWaitClient) -CALL_DUMMY(eglReleaseThread) -CALL_DUMMY(eglCreatePbufferFromClientBuffer) -CALL_DUMMY(eglSurfaceAttrib) -CALL_ENTRY(eglBindTexImage) -CALL_ENTRY(eglReleaseTexImage) -CALL_DUMMY(eglSwapInterval) -CALL_ENTRY(eglCreateContext) -CALL_ENTRY(eglDestroyContext) -CALL_ENTRY(eglMakeCurrent) -CALL_DUMMY(eglGetCurrentContext) -CALL_DUMMY(eglGetCurrentSurface) -CALL_DUMMY(eglGetCurrentDisplay) -CALL_DUMMY(eglQueryContext) -CALL_DUMMY(eglWaitGL) -CALL_DUMMY(eglWaitNative) -CALL_ENTRY(eglSwapBuffers) -CALL_DUMMY(eglCopyBuffers) -CALL_DUMMY(eglGetProcAddress) - -/* gles v2*/ -CALL_ENTRY(glActiveTexture) -CALL_ENTRY(glAttachShader) -CALL_ENTRY(glBindAttribLocation) -CALL_ENTRY(glBindBuffer) -CALL_ENTRY(glBindFramebuffer) -CALL_ENTRY(glBindRenderbuffer) -CALL_ENTRY(glBindTexture) -CALL_ENTRY(glBlendColor) -CALL_ENTRY(glBlendEquation) -CALL_ENTRY(glBlendEquationSeparate) -CALL_ENTRY(glBlendFunc) -CALL_ENTRY(glBlendFuncSeparate) -CALL_DUMMY(glBufferData) -CALL_DUMMY(glBufferSubData) -CALL_ENTRY(glCheckFramebufferStatus) -CALL_ENTRY(glClear) -CALL_ENTRY(glClearColor) -CALL_ENTRY(glClearDepthf) -CALL_ENTRY(glClearStencil) -CALL_ENTRY(glColorMask) -CALL_ENTRY(glCompileShader) -CALL_ENTRY(glCompressedTexImage2D) -CALL_ENTRY(glCompressedTexSubImage2D) -CALL_ENTRY(glCopyTexImage2D) -CALL_ENTRY(glCopyTexSubImage2D) -CALL_ENTRY(glCreateProgram) -CALL_ENTRY(glCreateShader) -CALL_ENTRY(glCullFace) -CALL_DUMMY(glDeleteBuffers) -CALL_ENTRY(glDeleteFramebuffers) -CALL_ENTRY(glDeleteProgram) -CALL_ENTRY(glDeleteRenderbuffers) -CALL_ENTRY(glDeleteShader) -CALL_ENTRY(glDeleteTextures) -CALL_ENTRY(glDepthFunc) -CALL_ENTRY(glDepthMask) -CALL_ENTRY(glDepthRangef) -CALL_ENTRY(glDetachShader) -CALL_ENTRY(glDisable) -CALL_ENTRY(glDisableVertexAttribArray) -CALL_ENTRY(glDrawArrays) -CALL_ENTRY(glDrawElements) -CALL_ENTRY(glEnable) -CALL_ENTRY(glEnableVertexAttribArray) -CALL_ENTRY(glFinish) -CALL_ENTRY(glFlush) -CALL_ENTRY(glFramebufferRenderbuffer) -CALL_ENTRY(glFramebufferTexture2D) -CALL_ENTRY(glFrontFace) -CALL_DUMMY(glGenBuffers) -CALL_ENTRY(glGenerateMipmap) -CALL_ENTRY(glGenFramebuffers) -CALL_ENTRY(glGenRenderbuffers) -CALL_ENTRY(glGenTextures) -CALL_ENTRY(glGetActiveAttrib) -CALL_ENTRY(glGetActiveUniform) -CALL_ENTRY(glGetAttachedShaders) -CALL_ENTRY(glGetAttribLocation) -CALL_ENTRY(glGetBooleanv) -CALL_DUMMY(glGetBufferParameteriv) -CALL_ENTRY(glGetError) -CALL_ENTRY(glGetFloatv) -CALL_DUMMY(glGetFramebufferAttachmentParameteriv) -CALL_ENTRY(glGetIntegerv) -CALL_ENTRY(glGetProgramiv) -CALL_ENTRY(glGetProgramInfoLog) -CALL_DUMMY(glGetRenderbufferParameteriv) -CALL_ENTRY(glGetShaderiv) -CALL_ENTRY(glGetShaderInfoLog) -CALL_ENTRY(glGetShaderPrecisionFormat) -CALL_ENTRY(glGetShaderSource) -CALL_DUMMY(glGetString) -CALL_ENTRY(glGetTexParameterfv) -CALL_ENTRY(glGetTexParameteriv) -CALL_ENTRY(glGetUniformfv) -CALL_ENTRY(glGetUniformiv) -CALL_ENTRY(glGetUniformLocation) -CALL_ENTRY(glGetVertexAttribfv) -CALL_ENTRY(glGetVertexAttribiv) -CALL_ENTRY(glGetVertexAttribPointerv) -CALL_ENTRY(glHint) -CALL_DUMMY(glIsBuffer) -CALL_ENTRY(glIsEnabled) -CALL_DUMMY(glIsFramebuffer) -CALL_ENTRY(glIsProgram) -CALL_DUMMY(glIsRenderbuffer) -CALL_ENTRY(glIsShader) -CALL_ENTRY(glIsTexture) -CALL_ENTRY(glLineWidth) -CALL_ENTRY(glLinkProgram) -CALL_ENTRY(glPixelStorei) -CALL_ENTRY(glPolygonOffset) -CALL_ENTRY(glReadPixels) -CALL_ENTRY(glReleaseShaderCompiler) -CALL_ENTRY(glRenderbufferStorage) -CALL_ENTRY(glSampleCoverage) -CALL_ENTRY(glScissor) -CALL_DUMMY(glShaderBinary) -CALL_ENTRY(glShaderSource) -CALL_ENTRY(glStencilFunc) -CALL_ENTRY(glStencilFuncSeparate) -CALL_ENTRY(glStencilMask) -CALL_ENTRY(glStencilMaskSeparate) -CALL_ENTRY(glStencilOp) -CALL_ENTRY(glStencilOpSeparate) -CALL_ENTRY(glTexImage2D) -CALL_ENTRY(glTexParameterf) -CALL_ENTRY(glTexParameterfv) -CALL_ENTRY(glTexParameteri) -CALL_ENTRY(glTexParameteriv) -CALL_ENTRY(glTexSubImage2D) -CALL_ENTRY(glUniform1f) -CALL_ENTRY(glUniform1fv) -CALL_ENTRY(glUniform1i) -CALL_ENTRY(glUniform1iv) -CALL_ENTRY(glUniform2f) -CALL_ENTRY(glUniform2fv) -CALL_ENTRY(glUniform2i) -CALL_ENTRY(glUniform2iv) -CALL_ENTRY(glUniform3f) -CALL_ENTRY(glUniform3fv) -CALL_ENTRY(glUniform3i) -CALL_ENTRY(glUniform3iv) -CALL_ENTRY(glUniform4f) -CALL_ENTRY(glUniform4fv) -CALL_ENTRY(glUniform4i) -CALL_ENTRY(glUniform4iv) -CALL_ENTRY(glUniformMatrix2fv) -CALL_ENTRY(glUniformMatrix3fv) -CALL_ENTRY(glUniformMatrix4fv) -CALL_ENTRY(glUseProgram) -CALL_ENTRY(glValidateProgram) -CALL_ENTRY(glVertexAttrib1f) -CALL_ENTRY(glVertexAttrib1fv) -CALL_ENTRY(glVertexAttrib2f) -CALL_ENTRY(glVertexAttrib2fv) -CALL_ENTRY(glVertexAttrib3f) -CALL_ENTRY(glVertexAttrib3fv) -CALL_ENTRY(glVertexAttrib4f) -CALL_ENTRY(glVertexAttrib4fv) -CALL_ENTRY(glVertexAttribPointer) -CALL_ENTRY(glViewport) - -/* gles v1 without gles v2*/ -CALL_ENTRY(glAlphaFunc) -CALL_ENTRY(glClipPlanef) -CALL_ENTRY(glColor4f) -CALL_ENTRY(glFogf) -CALL_ENTRY(glFogfv) -CALL_ENTRY(glFrustumf) -CALL_ENTRY(glGetClipPlanef) -CALL_ENTRY(glGetLightfv) -CALL_ENTRY(glGetMaterialfv) -CALL_ENTRY(glGetTexEnvfv) -CALL_ENTRY(glLightModelf) -CALL_ENTRY(glLightModelfv) -CALL_ENTRY(glLightf) -CALL_ENTRY(glLightfv) -CALL_ENTRY(glLoadMatrixf) -CALL_ENTRY(glMaterialf) -CALL_ENTRY(glMaterialfv) -CALL_ENTRY(glMultMatrixf) -CALL_ENTRY(glMultiTexCoord4f) -CALL_ENTRY(glNormal3f) -CALL_ENTRY(glOrthof) -CALL_ENTRY(glPointParameterf) -CALL_ENTRY(glPointParameterfv) -CALL_ENTRY(glPointSize) -CALL_ENTRY(glRotatef) -CALL_ENTRY(glScalef) -CALL_ENTRY(glTexEnvf) -CALL_ENTRY(glTexEnvfv) -CALL_ENTRY(glTranslatef) -CALL_ENTRY(glAlphaFuncx) -CALL_ENTRY(glClearColorx) -CALL_ENTRY(glClearDepthx) -CALL_ENTRY(glClientActiveTexture) -CALL_ENTRY(glClipPlanex) -CALL_ENTRY(glColor4ub) -CALL_ENTRY(glColor4x) -CALL_ENTRY(glColorPointer) -CALL_ENTRY(glDepthRangex) -CALL_ENTRY(glDisableClientState) -CALL_ENTRY(glEnableClientState) -CALL_ENTRY(glFogx) -CALL_ENTRY(glFogxv) -CALL_ENTRY(glFrustumx) -CALL_ENTRY(glGetClipPlanex) -CALL_ENTRY(glGetFixedv) -CALL_ENTRY(glGetLightxv) -CALL_ENTRY(glGetMaterialxv) -CALL_ENTRY(glGetPointerv) -CALL_ENTRY(glGetTexEnviv) -CALL_ENTRY(glGetTexEnvxv) -CALL_ENTRY(glGetTexParameterxv) -CALL_ENTRY(glLightModelx) -CALL_ENTRY(glLightModelxv) -CALL_ENTRY(glLightx) -CALL_ENTRY(glLightxv) -CALL_ENTRY(glLineWidthx) -CALL_ENTRY(glLoadIdentity) -CALL_ENTRY(glLoadMatrixx) -CALL_ENTRY(glLogicOp) -CALL_ENTRY(glMaterialx) -CALL_ENTRY(glMaterialxv) -CALL_ENTRY(glMatrixMode) -CALL_ENTRY(glMultMatrixx) -CALL_ENTRY(glMultiTexCoord4x) -CALL_ENTRY(glNormal3x) -CALL_ENTRY(glNormalPointer) -CALL_ENTRY(glOrthox) -CALL_ENTRY(glPointParameterx) -CALL_ENTRY(glPointParameterxv) -CALL_ENTRY(glPointSizex) -CALL_ENTRY(glPolygonOffsetx) -CALL_ENTRY(glPopMatrix) -CALL_ENTRY(glPushMatrix) -CALL_ENTRY(glRotatex) -CALL_ENTRY(glSampleCoveragex) -CALL_ENTRY(glScalex) -CALL_ENTRY(glShadeModel) -CALL_ENTRY(glTexCoordPointer) -CALL_ENTRY(glTexEnvi) -CALL_ENTRY(glTexEnvx) -CALL_ENTRY(glTexEnviv) -CALL_ENTRY(glTexEnvxv) -CALL_ENTRY(glTexParameterx) -CALL_ENTRY(glTexParameterxv) -CALL_ENTRY(glTranslatex) -CALL_ENTRY(glVertexPointer) diff --git a/hw/gles2_types.h b/hw/gles2_types.h deleted file mode 100644 index 5506509..0000000 --- a/hw/gles2_types.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2009-2010 Nokia Corporation - * - * 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 or - * (at your option) any later version of the License. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - */ - -#ifndef GLES2_TYPES_H_ -#define GLES2_TYPES_H_ - -// Automatically create the prototype and function definition. -#define GLES2_CB(FUNC) \ - void gles2_##FUNC##_cb(gles2_State *s, \ - gles2_decode_t *d, gles2_Client *c); \ - void gles2_##FUNC##_cb(gles2_State *s, \ - gles2_decode_t *d, gles2_Client *c) - -// Sizes of primitive types in the ABI. -#define GLES2_HTYPE_byte uint8_t -#define GLES2_HTYPE_word uint16_t -#define GLES2_HTYPE_dword uint32_t -#define GLES2_HTYPE_float float -#define GLES2_HTYPE_handle uint32_t - -// Defines shorthands for handling types. -#define GLES2_TYPE(TYPE, SIZE) \ - typedef GLES2_HTYPE_##SIZE TYPE; \ - static inline void gles2_ret_##TYPE(gles2_State *s, TYPE value) \ - { gles2_ret_##SIZE(s, value); } \ - static inline void gles2_put_##TYPE(gles2_State *s, target_ulong va, TYPE value) \ - { gles2_put_##SIZE(s, va, value); } \ - static inline TYPE gles2_get_##TYPE(gles2_State *s, target_ulong va) \ - { return (TYPE)gles2_get_##SIZE(s, va); } \ - static inline TYPE gles2_arg_##TYPE(gles2_State *s, gles2_decode_t *d) \ - { return (TYPE)gles2_arg_##SIZE(s, d); } - -// Bunch of expansions of previous macro to ease things up. -GLES2_TYPE(Tptr, dword) -GLES2_TYPE(TEGLBoolean, dword) -GLES2_TYPE(TEGLenum, dword) -GLES2_TYPE(TEGLint, dword) -GLES2_TYPE(TEGLDisplay, handle) -GLES2_TYPE(TEGLConfig, handle) -GLES2_TYPE(TEGLContext, handle) -GLES2_TYPE(TEGLSurface, handle) - -GLES2_TYPE(TGLclampf, float) -GLES2_TYPE(TGLbitfield, dword) -GLES2_TYPE(TGLboolean, byte) -GLES2_TYPE(TGLint, dword) -GLES2_TYPE(TGLuint, dword) -GLES2_TYPE(TGLushort, word) -GLES2_TYPE(TGLubyte, byte) -GLES2_TYPE(TGLenum, dword) -GLES2_TYPE(TGLsizei, dword) -GLES2_TYPE(TGLfloat, float) -GLES2_TYPE(TGLfixed, dword) -GLES2_TYPE(TGLclampx, dword) - - -// Just one more macro for even less typing. -#define GLES2_ARG(TYPE, NAME) \ - TYPE NAME = gles2_arg_##TYPE(s, d) - -// pthread_cond_signal(&s->cond_xcode); - - -// Host to guest vertex array copy. -struct gles2_Array -{ - GLuint indx; // Parameter of the call. - GLint size; // --''-- - GLenum type; // --''-- - GLboolean normalized; // --''-- - GLsizei stride; // --''-- - GLsizei real_stride; // --''-- - Tptr tptr; // Pointer in the guest memory. - void* ptr; // Pointer in the host memory. - - void (*apply) (struct gles2_Array *va); - - GLboolean enabled; // State. -}; - -unsigned gles1_glGetCount(TGLenum pname); -void checkGLESError(void); - -#endif /* GLES2_TYPES_H_ */ diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index bd3d6b0..94a608e 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -41,6 +41,8 @@ typedef struct GrackleState { SysBusDevice busdev; PCIHostState host_state; + MemoryRegion pci_mmio; + MemoryRegion pci_hole; } GrackleState; /* Don't know if this matches real hardware, but it agrees with OHW. */ @@ -57,28 +59,13 @@ static void pci_grackle_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num + 0x15], level); } -static void pci_grackle_save(QEMUFile* f, void *opaque) -{ - PCIDevice *d = opaque; - - pci_device_save(d, f); -} - -static int pci_grackle_load(QEMUFile* f, void *opaque, int version_id) -{ - PCIDevice *d = opaque; - - if (version_id != 1) - return -EINVAL; - - return pci_device_load(d, f); -} - static void pci_grackle_reset(void *opaque) { } -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) +PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -88,10 +75,20 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) qdev_init_nofail(dev); s = sysbus_from_qdev(dev); d = FROM_SYSBUS(GrackleState, s); + + memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL); + memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio, + 0x80000000ULL, 0x7e000000ULL); + memory_region_add_subregion(address_space_mem, 0x80000000ULL, + &d->pci_hole); + d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_grackle_set_irq, pci_grackle_map_irq, - pic, 0, 4); + pic, + &d->pci_mmio, + address_space_io, + 0, 4); pci_create_simple(d->host_state.bus, 0, "grackle"); @@ -104,30 +101,23 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) static int pci_grackle_init_device(SysBusDevice *dev) { GrackleState *s; - int pci_mem_config, pci_mem_data; s = FROM_SYSBUS(GrackleState, dev); - pci_mem_config = pci_host_conf_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - pci_mem_data = pci_host_data_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, pci_mem_config); - sysbus_init_mmio(dev, 0x1000, pci_mem_data); + memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, + &s->host_state, "pci-conf-idx", 0x1000); + memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, + &s->host_state, "pci-data-idx", 0x1000); + sysbus_init_mmio_region(dev, &s->host_state.conf_mem); + sysbus_init_mmio_region(dev, &s->host_state.data_mem); - register_savevm(&dev->qdev, "grackle", 0, 1, pci_grackle_save, - pci_grackle_load, &s->host_state); qemu_register_reset(pci_grackle_reset, &s->host_state); return 0; } static int grackle_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_MPC106); - d->config[0x08] = 0x00; // revision d->config[0x09] = 0x01; - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); return 0; } @@ -135,6 +125,10 @@ static PCIDeviceInfo grackle_pci_host_info = { .qdev.name = "grackle", .qdev.size = sizeof(PCIDevice), .init = grackle_pci_host_init, + .vendor_id = PCI_VENDOR_ID_MOTOROLA, + .device_id = PCI_DEVICE_ID_MOTOROLA_MPC106, + .revision = 0x00, + .class_id = PCI_CLASS_BRIDGE_HOST, }; static void grackle_register_devices(void) diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c index 101b150..c90b810 100644 --- a/hw/grlib_apbuart.c +++ b/hw/grlib_apbuart.c @@ -114,7 +114,7 @@ grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value) switch (addr) { case DATA_OFFSET: c = value & 0xFF; - qemu_chr_write(uart->chr, &c, 1); + qemu_chr_fe_write(uart->chr, &c, 1); return; case STATUS_OFFSET: @@ -133,7 +133,7 @@ grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value) break; } - trace_grlib_apbuart_unknown_register("write", addr); + trace_grlib_apbuart_writel_unknown(addr, value); } static CPUReadMemoryFunc * const grlib_apbuart_read[] = { diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c index 596a900..85869b9 100644 --- a/hw/grlib_gptimer.c +++ b/hw/grlib_gptimer.c @@ -165,15 +165,15 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr) /* Unit registers */ switch (addr) { case SCALER_OFFSET: - trace_grlib_gptimer_readl(-1, "scaler:", unit->scaler); + trace_grlib_gptimer_readl(-1, addr, unit->scaler); return unit->scaler; case SCALER_RELOAD_OFFSET: - trace_grlib_gptimer_readl(-1, "reload:", unit->reload); + trace_grlib_gptimer_readl(-1, addr, unit->reload); return unit->reload; case CONFIG_OFFSET: - trace_grlib_gptimer_readl(-1, "config:", unit->config); + trace_grlib_gptimer_readl(-1, addr, unit->config); return unit->config; default: @@ -189,17 +189,16 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr) switch (timer_addr) { case COUNTER_OFFSET: value = ptimer_get_count(unit->timers[id].ptimer); - trace_grlib_gptimer_readl(id, "counter value:", value); + trace_grlib_gptimer_readl(id, addr, value); return value; case COUNTER_RELOAD_OFFSET: value = unit->timers[id].reload; - trace_grlib_gptimer_readl(id, "reload value:", value); + trace_grlib_gptimer_readl(id, addr, value); return value; case CONFIG_OFFSET: - trace_grlib_gptimer_readl(id, "scaler value:", - unit->timers[id].config); + trace_grlib_gptimer_readl(id, addr, unit->timers[id].config); return unit->timers[id].config; default: @@ -208,7 +207,7 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr) } - trace_grlib_gptimer_unknown_register("read", addr); + trace_grlib_gptimer_readl(-1, addr, 0); return 0; } @@ -226,19 +225,19 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value) case SCALER_OFFSET: value &= 0xFFFF; /* clean up the value */ unit->scaler = value; - trace_grlib_gptimer_writel(-1, "scaler:", unit->scaler); + trace_grlib_gptimer_writel(-1, addr, unit->scaler); return; case SCALER_RELOAD_OFFSET: value &= 0xFFFF; /* clean up the value */ unit->reload = value; - trace_grlib_gptimer_writel(-1, "reload:", unit->reload); + trace_grlib_gptimer_writel(-1, addr, unit->reload); grlib_gptimer_set_scaler(unit, value); return; case CONFIG_OFFSET: /* Read Only (disable timer freeze not supported) */ - trace_grlib_gptimer_writel(-1, "config (Read Only):", 0); + trace_grlib_gptimer_writel(-1, addr, 0); return; default: @@ -253,18 +252,18 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value) /* GPTimer registers */ switch (timer_addr) { case COUNTER_OFFSET: - trace_grlib_gptimer_writel(id, "counter:", value); + trace_grlib_gptimer_writel(id, addr, value); unit->timers[id].counter = value; grlib_gptimer_enable(&unit->timers[id]); return; case COUNTER_RELOAD_OFFSET: - trace_grlib_gptimer_writel(id, "reload:", value); + trace_grlib_gptimer_writel(id, addr, value); unit->timers[id].reload = value; return; case CONFIG_OFFSET: - trace_grlib_gptimer_writel(id, "config:", value); + trace_grlib_gptimer_writel(id, addr, value); if (value & GPTIMER_INT_PENDING) { /* clear pending bit */ @@ -297,7 +296,7 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value) } - trace_grlib_gptimer_unknown_register("write", addr); + trace_grlib_gptimer_writel(-1, addr, value); } static CPUReadMemoryFunc * const grlib_gptimer_read[] = { @@ -346,7 +345,7 @@ static int grlib_gptimer_init(SysBusDevice *dev) assert(unit->nr_timers > 0); assert(unit->nr_timers <= GPTIMER_MAX_TIMERS); - unit->timers = qemu_mallocz(sizeof unit->timers[0] * unit->nr_timers); + unit->timers = g_malloc0(sizeof unit->timers[0] * unit->nr_timers); for (i = 0; i < unit->nr_timers; i++) { GPTimer *timer = &unit->timers[i]; diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c index f47c491..9490a78 100644 --- a/hw/grlib_irqmp.c +++ b/hw/grlib_irqmp.c @@ -220,7 +220,7 @@ static uint32_t grlib_irqmp_readl(void *opaque, target_phys_addr_t addr) return state->extended[cpu]; } - trace_grlib_irqmp_unknown_register("read", addr); + trace_grlib_irqmp_readl_unknown(addr); return 0; } @@ -308,7 +308,7 @@ grlib_irqmp_writel(void *opaque, target_phys_addr_t addr, uint32_t value) return; } - trace_grlib_irqmp_unknown_register("write", addr); + trace_grlib_irqmp_writel_unknown(addr, value); } static CPUReadMemoryFunc * const grlib_irqmp_read[] = { @@ -345,7 +345,7 @@ static int grlib_irqmp_init(SysBusDevice *dev) grlib_irqmp_write, irqmp, DEVICE_NATIVE_ENDIAN); - irqmp->state = qemu_mallocz(sizeof *irqmp->state); + irqmp->state = g_malloc0(sizeof *irqmp->state); if (irqmp_regs < 0) { return -1; diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index 923073b..432683a 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -27,6 +27,7 @@ #include "pci.h" #include "pci_host.h" #include "pc.h" +#include "exec-memory.h" //#define DEBUG @@ -226,7 +227,7 @@ #define PCI_MAPPING_ENTRY(regname) \ target_phys_addr_t regname ##_start; \ target_phys_addr_t regname ##_length; \ - int regname ##_handle + MemoryRegion regname ##_mem typedef struct GT64120State { SysBusDevice busdev; @@ -268,17 +269,18 @@ static void gt64120_isd_mapping(GT64120State *s) target_phys_addr_t start = s->regs[GT_ISD] << 21; target_phys_addr_t length = 0x1000; - if (s->ISD_length) - cpu_register_physical_memory(s->ISD_start, s->ISD_length, - IO_MEM_UNASSIGNED); + if (s->ISD_length) { + memory_region_del_subregion(get_system_memory(), &s->ISD_mem); + } check_reserved_space(&start, &length); length = 0x1000; /* Map new address */ - DPRINTF("ISD: "TARGET_FMT_plx"@"TARGET_FMT_plx" -> "TARGET_FMT_plx"@"TARGET_FMT_plx", %x\n", s->ISD_length, s->ISD_start, - length, start, s->ISD_handle); + DPRINTF("ISD: "TARGET_FMT_plx"@"TARGET_FMT_plx + " -> "TARGET_FMT_plx"@"TARGET_FMT_plx"\n", + s->ISD_length, s->ISD_start, length, start); s->ISD_start = start; s->ISD_length = length; - cpu_register_physical_memory(s->ISD_start, s->ISD_length, s->ISD_handle); + memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem); } static void gt64120_pci_mapping(GT64120State *s) @@ -289,18 +291,23 @@ static void gt64120_pci_mapping(GT64120State *s) /* Unmap old IO address */ if (s->PCI0IO_length) { - cpu_register_physical_memory(s->PCI0IO_start, s->PCI0IO_length, IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem); + memory_region_destroy(&s->PCI0IO_mem); } /* Map new IO address */ s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21; s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) - (s->regs[GT_PCI0IOLD] & 0x7f)) << 21; isa_mem_base = s->PCI0IO_start; - isa_mmio_init(s->PCI0IO_start, s->PCI0IO_length); + if (s->PCI0IO_length) { + isa_mmio_setup(&s->PCI0IO_mem, s->PCI0IO_length); + memory_region_add_subregion(get_system_memory(), s->PCI0IO_start, + &s->PCI0IO_mem); + } } } static void gt64120_writel (void *opaque, target_phys_addr_t addr, - uint32_t val) + uint64_t val, unsigned size) { GT64120State *s = opaque; uint32_t saddr; @@ -537,19 +544,19 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, /* not really implemented */ s->regs[saddr] = ~(~(s->regs[saddr]) | ~(val & 0xfffffffe)); s->regs[saddr] |= !!(s->regs[saddr] & 0xfffffffe); - DPRINTF("INTRCAUSE %x\n", val); + DPRINTF("INTRCAUSE %" PRIx64 "\n", val); break; case GT_INTRMASK: s->regs[saddr] = val & 0x3c3ffffe; - DPRINTF("INTRMASK %x\n", val); + DPRINTF("INTRMASK %" PRIx64 "\n", val); break; case GT_PCI0_ICMASK: s->regs[saddr] = val & 0x03fffffe; - DPRINTF("ICMASK %x\n", val); + DPRINTF("ICMASK %" PRIx64 "\n", val); break; case GT_PCI0_SERR0MASK: s->regs[saddr] = val & 0x0000003f; - DPRINTF("SERR0MASK %x\n", val); + DPRINTF("SERR0MASK %" PRIx64 "\n", val); break; /* Reserved when only PCI_0 is configured. */ @@ -578,8 +585,8 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, } } -static uint32_t gt64120_readl (void *opaque, - target_phys_addr_t addr) +static uint64_t gt64120_readl (void *opaque, + target_phys_addr_t addr, unsigned size) { GT64120State *s = opaque; uint32_t val; @@ -850,16 +857,10 @@ static uint32_t gt64120_readl (void *opaque, return val; } -static CPUWriteMemoryFunc * const gt64120_write[] = { - >64120_writel, - >64120_writel, - >64120_writel, -}; - -static CPUReadMemoryFunc * const gt64120_read[] = { - >64120_readl, - >64120_readl, - >64120_readl, +static const MemoryRegionOps isd_mem_ops = { + .read = gt64120_readl, + .write = gt64120_writel, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int gt64120_pci_map_irq(PCIDevice *pci_dev, int irq_num) @@ -1080,25 +1081,6 @@ static void gt64120_reset(void *opaque) gt64120_pci_mapping(s); } -static void gt64120_save(QEMUFile* f, void *opaque) -{ - PCIDevice *d = opaque; - pci_device_save(d, f); -} - -static int gt64120_load(QEMUFile* f, void *opaque, int version_id) -{ - PCIDevice *d = opaque; - int ret; - - if (version_id != 1) - return -EINVAL; - ret = pci_device_load(d, f); - if (ret < 0) - return ret; - return 0; -} - PCIBus *gt64120_register(qemu_irq *pic) { SysBusDevice *s; @@ -1111,9 +1093,11 @@ PCIBus *gt64120_register(qemu_irq *pic) d = FROM_SYSBUS(GT64120State, s); d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci", gt64120_pci_set_irq, gt64120_pci_map_irq, - pic, PCI_DEVFN(18, 0), 4); - d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d, - DEVICE_NATIVE_ENDIAN); + pic, + get_system_memory(), + get_system_io(), + PCI_DEVFN(18, 0), 4); + memory_region_init_io(&d->ISD_mem, &isd_mem_ops, d, "isd-mem", 0x1000); pci_create_simple(d->pci.bus, PCI_DEVFN(0, 0), "gt64120_pci"); return d->pci.bus; @@ -1131,22 +1115,16 @@ static int gt64120_init(SysBusDevice *dev) does not fully work. */ isa_mem_base = 0x10000000; qemu_register_reset(gt64120_reset, s); - register_savevm(&dev->qdev, "GT64120 PCI Bus", 0, 1, - gt64120_save, gt64120_load, &s->pci); return 0; } static int gt64120_pci_init(PCIDevice *d) { /* FIXME: Malta specific hw assumptions ahead */ - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MARVELL); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_MARVELL_GT6412X); pci_set_word(d->config + PCI_COMMAND, 0); pci_set_word(d->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); - pci_set_byte(d->config + PCI_CLASS_REVISION, 0x10); pci_config_set_prog_interface(d->config, 0); - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); pci_set_long(d->config + PCI_BASE_ADDRESS_0, 0x00000008); pci_set_long(d->config + PCI_BASE_ADDRESS_1, 0x01000008); pci_set_long(d->config + PCI_BASE_ADDRESS_2, 0x1c000000); @@ -1162,6 +1140,10 @@ static PCIDeviceInfo gt64120_pci_info = { .qdev.name = "gt64120_pci", .qdev.size = sizeof(PCIDevice), .init = gt64120_pci_init, + .vendor_id = PCI_VENDOR_ID_MARVELL, + .device_id = PCI_DEVICE_ID_MARVELL_GT6412X, + .revision = 0x10, + .class_id = PCI_CLASS_BRIDGE_HOST, }; static void gt64120_pci_register_devices(void) diff --git a/hw/gumstix.c b/hw/gumstix.c index ee63f63..686a5ed 100644 --- a/hw/gumstix.c +++ b/hw/gumstix.c @@ -35,10 +35,10 @@ #include "pxa.h" #include "net.h" #include "flash.h" -#include "sysemu.h" #include "devices.h" #include "boards.h" #include "blockdev.h" +#include "exec-memory.h" static const int sector_len = 128 * 1024; @@ -50,11 +50,12 @@ static void connex_init(ram_addr_t ram_size, PXA2xxState *cpu; DriveInfo *dinfo; int be; + MemoryRegion *address_space_mem = get_system_memory(); uint32_t connex_rom = 0x01000000; uint32_t connex_ram = 0x04000000; - cpu = pxa255_init(connex_ram); + cpu = pxa255_init(address_space_mem, connex_ram); dinfo = drive_get(IF_PFLASH, 0, 0); if (!dinfo) { @@ -68,8 +69,7 @@ static void connex_init(ram_addr_t ram_size, #else be = 0; #endif - if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom", - connex_rom), + if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom, dinfo->bdrv, sector_len, connex_rom / sector_len, 2, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); @@ -89,11 +89,12 @@ static void verdex_init(ram_addr_t ram_size, PXA2xxState *cpu; DriveInfo *dinfo; int be; + MemoryRegion *address_space_mem = get_system_memory(); uint32_t verdex_rom = 0x02000000; uint32_t verdex_ram = 0x10000000; - cpu = pxa270_init(verdex_ram, cpu_model ?: "pxa270-c0"); + cpu = pxa270_init(address_space_mem, verdex_ram, cpu_model ?: "pxa270-c0"); dinfo = drive_get(IF_PFLASH, 0, 0); if (!dinfo) { @@ -107,8 +108,7 @@ static void verdex_init(ram_addr_t ram_size, #else be = 0; #endif - if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom", - verdex_rom), + if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom, dinfo->bdrv, sector_len, verdex_rom / sector_len, 2, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); diff --git a/hw/gus.c b/hw/gus.c index ff9e7c7..b5eb548 100644 --- a/hw/gus.c +++ b/hw/gus.c @@ -232,9 +232,25 @@ static const VMStateDescription vmstate_gus = { } }; +static const MemoryRegionPortio gus_portio_list1[] = { + {0x000, 1, 1, .write = gus_writeb }, + {0x000, 1, 2, .write = gus_writew }, + {0x006, 10, 1, .read = gus_readb, .write = gus_writeb }, + {0x006, 10, 2, .read = gus_readw, .write = gus_writew }, + {0x100, 8, 1, .read = gus_readb, .write = gus_writeb }, + {0x100, 8, 2, .read = gus_readw, .write = gus_writew }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionPortio gus_portio_list2[] = { + {0, 1, 1, .read = gus_readb }, + {0, 1, 2, .read = gus_readw }, + PORTIO_END_OF_LIST(), +}; + static int gus_initfn (ISADevice *dev) { - GUSState *s = DO_UPCAST(GUSState, dev, dev); + GUSState *s = DO_UPCAST (GUSState, dev, dev); struct audsettings as; AUD_register_card ("gus", &s->card); @@ -260,28 +276,11 @@ static int gus_initfn (ISADevice *dev) s->shift = 2; s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift; - s->mixbuf = qemu_mallocz (s->samples << s->shift); - - register_ioport_write (s->port, 1, 1, gus_writeb, s); - register_ioport_write (s->port, 1, 2, gus_writew, s); - isa_init_ioport_range(dev, s->port, 2); - - register_ioport_read ((s->port + 0x100) & 0xf00, 1, 1, gus_readb, s); - register_ioport_read ((s->port + 0x100) & 0xf00, 1, 2, gus_readw, s); - isa_init_ioport_range(dev, (s->port + 0x100) & 0xf00, 2); - - register_ioport_write (s->port + 6, 10, 1, gus_writeb, s); - register_ioport_write (s->port + 6, 10, 2, gus_writew, s); - register_ioport_read (s->port + 6, 10, 1, gus_readb, s); - register_ioport_read (s->port + 6, 10, 2, gus_readw, s); - isa_init_ioport_range(dev, s->port + 6, 10); - + s->mixbuf = g_malloc0 (s->samples << s->shift); - register_ioport_write (s->port + 0x100, 8, 1, gus_writeb, s); - register_ioport_write (s->port + 0x100, 8, 2, gus_writew, s); - register_ioport_read (s->port + 0x100, 8, 1, gus_readb, s); - register_ioport_read (s->port + 0x100, 8, 2, gus_readw, s); - isa_init_ioport_range(dev, s->port + 0x100, 8); + isa_register_portio_list (dev, s->port, gus_portio_list1, s, "gus"); + isa_register_portio_list (dev, (s->port + 0x100) & 0xf00, + gus_portio_list2, s, "gus"); DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s); s->emu.himemaddr = s->himem; diff --git a/hw/hda-audio.c b/hw/hda-audio.c index c699d6f..9b089e6 100644 --- a/hw/hda-audio.c +++ b/hw/hda-audio.c @@ -466,7 +466,8 @@ struct HDAAudioState { QEMUSoundCard card; const desc_codec *desc; HDAAudioStream st[4]; - bool running[16]; + bool running_compat[16]; + bool running_real[2 * 16]; /* properties */ uint32_t debug; @@ -663,7 +664,7 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data) st->channel = payload & 0x0f; dprint(a, 2, "%s: stream %d, channel %d\n", st->node->name, st->stream, st->channel); - hda_audio_set_running(st, a->running[st->stream]); + hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]); hda_codec_response(hda, true, 0); break; case AC_VERB_GET_CONV: @@ -746,16 +747,20 @@ fail: hda_codec_response(hda, true, 0); } -static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running) +static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output) { HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda); int s; - a->running[stnr] = running; + a->running_compat[stnr] = running; + a->running_real[output * 16 + stnr] = running; for (s = 0; s < ARRAY_SIZE(a->st); s++) { if (a->st[s].node == NULL) { continue; } + if (a->st[s].output != output) { + continue; + } if (a->st[s].stream != stnr) { continue; } @@ -837,6 +842,12 @@ static int hda_audio_post_load(void *opaque, int version) int i; dprint(a, 1, "%s\n", __FUNCTION__); + if (version == 1) { + /* assume running_compat[] is for output streams */ + for (i = 0; i < ARRAY_SIZE(a->running_compat); i++) + a->running_real[16 + i] = a->running_compat[i]; + } + for (i = 0; i < ARRAY_SIZE(a->st); i++) { st = a->st + i; if (st->node == NULL) @@ -844,7 +855,7 @@ static int hda_audio_post_load(void *opaque, int version) hda_codec_parse_fmt(st->format, &st->as); hda_audio_setup(st); hda_audio_set_amp(st); - hda_audio_set_running(st, a->running[st->stream]); + hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]); } return 0; } @@ -868,13 +879,14 @@ static const VMStateDescription vmstate_hda_audio_stream = { static const VMStateDescription vmstate_hda_audio = { .name = "hda-audio", - .version_id = 1, + .version_id = 2, .post_load = hda_audio_post_load, .fields = (VMStateField []) { VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0, vmstate_hda_audio_stream, HDAAudioStream), - VMSTATE_BOOL_ARRAY(running, HDAAudioState, 16), + VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16), + VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2), VMSTATE_END_OF_LIST() } }; diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c index b19b754..16f48d1 100644 --- a/hw/heathrow_pic.c +++ b/hw/heathrow_pic.c @@ -43,6 +43,7 @@ typedef struct HeathrowPIC { } HeathrowPIC; typedef struct HeathrowPICS { + MemoryRegion mem; HeathrowPIC pics[2]; qemu_irq *irqs; } HeathrowPICS; @@ -62,7 +63,8 @@ static void heathrow_pic_update(HeathrowPICS *s) } } -static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +static void pic_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { HeathrowPICS *s = opaque; HeathrowPIC *pic; @@ -89,7 +91,8 @@ static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } } -static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) +static uint64_t pic_read(void *opaque, target_phys_addr_t addr, + unsigned size) { HeathrowPICS *s = opaque; HeathrowPIC *pic; @@ -120,19 +123,12 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) return value; } -static CPUWriteMemoryFunc * const pic_write[] = { - &pic_writel, - &pic_writel, - &pic_writel, +static const MemoryRegionOps heathrow_pic_ops = { + .read = pic_read, + .write = pic_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static CPUReadMemoryFunc * const pic_read[] = { - &pic_readl, - &pic_readl, - &pic_readl, -}; - - static void heathrow_pic_set_irq(void *opaque, int num, int level) { HeathrowPICS *s = opaque; @@ -159,42 +155,31 @@ static void heathrow_pic_set_irq(void *opaque, int num, int level) heathrow_pic_update(s); } -static void heathrow_pic_save_one(QEMUFile *f, HeathrowPIC *s) -{ - qemu_put_be32s(f, &s->events); - qemu_put_be32s(f, &s->mask); - qemu_put_be32s(f, &s->levels); - qemu_put_be32s(f, &s->level_triggered); -} - -static void heathrow_pic_save(QEMUFile *f, void *opaque) -{ - HeathrowPICS *s = (HeathrowPICS *)opaque; - - heathrow_pic_save_one(f, &s->pics[0]); - heathrow_pic_save_one(f, &s->pics[1]); -} - -static void heathrow_pic_load_one(QEMUFile *f, HeathrowPIC *s) -{ - qemu_get_be32s(f, &s->events); - qemu_get_be32s(f, &s->mask); - qemu_get_be32s(f, &s->levels); - qemu_get_be32s(f, &s->level_triggered); -} - -static int heathrow_pic_load(QEMUFile *f, void *opaque, int version_id) -{ - HeathrowPICS *s = (HeathrowPICS *)opaque; - - if (version_id != 1) - return -EINVAL; - - heathrow_pic_load_one(f, &s->pics[0]); - heathrow_pic_load_one(f, &s->pics[1]); +static const VMStateDescription vmstate_heathrow_pic_one = { + .name = "heathrow_pic_one", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(events, HeathrowPIC), + VMSTATE_UINT32(mask, HeathrowPIC), + VMSTATE_UINT32(levels, HeathrowPIC), + VMSTATE_UINT32(level_triggered, HeathrowPIC), + VMSTATE_END_OF_LIST() + } +}; - return 0; -} +static const VMStateDescription vmstate_heathrow_pic = { + .name = "heathrow_pic", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(pics, HeathrowPICS, 2, 1, + vmstate_heathrow_pic_one, HeathrowPIC), + VMSTATE_END_OF_LIST() + } +}; static void heathrow_pic_reset_one(HeathrowPIC *s) { @@ -212,19 +197,19 @@ static void heathrow_pic_reset(void *opaque) s->pics[1].level_triggered = 0x1ff00000; } -qemu_irq *heathrow_pic_init(int *pmem_index, +qemu_irq *heathrow_pic_init(MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs) { HeathrowPICS *s; - s = qemu_mallocz(sizeof(HeathrowPICS)); + s = g_malloc0(sizeof(HeathrowPICS)); /* only 1 CPU */ s->irqs = irqs[0]; - *pmem_index = cpu_register_io_memory(pic_read, pic_write, s, - DEVICE_LITTLE_ENDIAN); + memory_region_init_io(&s->mem, &heathrow_pic_ops, s, + "heathrow-pic", 0x1000); + *pmem = &s->mem; - register_savevm(NULL, "heathrow_pic", -1, 1, heathrow_pic_save, - heathrow_pic_load, s); + vmstate_register(NULL, -1, &vmstate_heathrow_pic, s); qemu_register_reset(heathrow_pic_reset, s); return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64); } diff --git a/hw/hpet.c b/hw/hpet.c index c12064d..6e6ea52 100644 --- a/hw/hpet.c +++ b/hw/hpet.c @@ -74,8 +74,6 @@ typedef struct HPETState { uint8_t hpet_id; /* instance id */ } HPETState; -struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; - static uint32_t hpet_in_legacy_mode(HPETState *s) { return s->config & HPET_CFG_LEGACY; @@ -145,7 +143,7 @@ static int deactivating_bit(uint64_t old, uint64_t new, uint64_t mask) static uint64_t hpet_get_ticks(HPETState *s) { - return ns_to_ticks(qemu_get_clock(vm_clock) + s->hpet_offset); + return ns_to_ticks(qemu_get_clock_ns(vm_clock) + s->hpet_offset); } /* @@ -159,14 +157,14 @@ static inline uint64_t hpet_calculate_diff(HPETTimer *t, uint64_t current) cmp = (uint32_t)t->cmp; diff = cmp - (uint32_t)current; - diff = (int32_t)diff > 0 ? diff : (uint32_t)0; + diff = (int32_t)diff > 0 ? diff : (uint32_t)1; return (uint64_t)diff; } else { uint64_t diff, cmp; cmp = t->cmp; diff = cmp - current; - diff = (int64_t)diff > 0 ? diff : (uint64_t)0; + diff = (int64_t)diff > 0 ? diff : (uint64_t)1; return diff; } } @@ -194,7 +192,7 @@ static void update_irq(struct HPETTimer *timer, int set) qemu_irq_lower(s->irqs[route]); } } else if (timer_fsb_route(timer)) { - stl_phys(timer->fsb >> 32, timer->fsb & 0xffffffff); + stl_le_phys(timer->fsb >> 32, timer->fsb & 0xffffffff); } else if (timer->config & HPET_TN_TYPE_LEVEL) { s->isr |= mask; qemu_irq_raise(s->irqs[route]); @@ -226,7 +224,7 @@ static int hpet_post_load(void *opaque, int version_id) HPETState *s = opaque; /* Recalculate the offset between the main counter and guest time */ - s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_get_clock(vm_clock); + s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_get_clock_ns(vm_clock); /* Push number of timers into capability returned via HPET_ID */ s->capability &= ~HPET_ID_NUM_TIM_MASK; @@ -300,11 +298,11 @@ static void hpet_timer(void *opaque) } diff = hpet_calculate_diff(t, cur_tick); qemu_mod_timer(t->qemu_timer, - qemu_get_clock(vm_clock) + (int64_t)ticks_to_ns(diff)); + qemu_get_clock_ns(vm_clock) + (int64_t)ticks_to_ns(diff)); } else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) { if (t->wrap_flag) { diff = hpet_calculate_diff(t, cur_tick); - qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(t->qemu_timer, qemu_get_clock_ns(vm_clock) + (int64_t)ticks_to_ns(diff)); t->wrap_flag = 0; } @@ -333,7 +331,7 @@ static void hpet_set_timer(HPETTimer *t) } } qemu_mod_timer(t->qemu_timer, - qemu_get_clock(vm_clock) + (int64_t)ticks_to_ns(diff)); + qemu_get_clock_ns(vm_clock) + (int64_t)ticks_to_ns(diff)); } static void hpet_del_timer(HPETTimer *t) @@ -399,7 +397,7 @@ static uint32_t hpet_ram_readl(void *opaque, target_phys_addr_t addr) case HPET_CFG: return s->config; case HPET_CFG + 4: - DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl \n"); + DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl\n"); return 0; case HPET_COUNTER: if (hpet_enabled(s)) { @@ -460,7 +458,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr, uint8_t timer_id = (addr - 0x100) / 0x20; HPETTimer *timer = &s->timer[timer_id]; - DPRINTF("qemu: hpet_ram_writel timer_id = %#x \n", timer_id); + DPRINTF("qemu: hpet_ram_writel timer_id = %#x\n", timer_id); if (timer_id > s->num_timers) { DPRINTF("qemu: timer id out of range\n"); return; @@ -487,7 +485,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr, DPRINTF("qemu: invalid HPET_TN_CFG+4 write\n"); break; case HPET_TN_CMP: // comparator register - DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP \n"); + DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP\n"); if (timer->config & HPET_TN_32BIT) { new_val = (uint32_t)new_val; } @@ -549,7 +547,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr, if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) { /* Enable main counter and interrupt generation. */ s->hpet_offset = - ticks_to_ns(s->hpet_counter) - qemu_get_clock(vm_clock); + ticks_to_ns(s->hpet_counter) - qemu_get_clock_ns(vm_clock); for (i = 0; i < s->num_timers; i++) { if ((&s->timer[i])->cmp != ~0ULL) { hpet_set_timer(&s->timer[i]); @@ -572,7 +570,7 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr, } break; case HPET_CFG + 4: - DPRINTF("qemu: invalid HPET_CFG+4 write \n"); + DPRINTF("qemu: invalid HPET_CFG+4 write\n"); break; case HPET_STATUS: val = new_val & s->isr; @@ -705,7 +703,7 @@ static int hpet_init(SysBusDevice *dev) } for (i = 0; i < HPET_MAX_TIMERS; i++) { timer = &s->timer[i]; - timer->qemu_timer = qemu_new_timer(vm_clock, hpet_timer, timer); + timer->qemu_timer = qemu_new_timer_ns(vm_clock, hpet_timer, timer); timer->tn = i; timer->state = s; } diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h index 8bf312a..6128702 100644 --- a/hw/hpet_emul.h +++ b/hw/hpet_emul.h @@ -59,13 +59,13 @@ struct hpet_fw_entry uint64_t address; uint16_t min_tick; uint8_t page_prot; -} __attribute__ ((packed)); +} QEMU_PACKED; struct hpet_fw_config { uint8_t count; struct hpet_fw_entry hpet[8]; -} __attribute__ ((packed)); +} QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; #endif diff --git a/hw/hw.h b/hw/hw.h index 5e24329..ed20f5a 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -85,8 +85,8 @@ uint64_t qemu_get_be64(QEMUFile *f); int qemu_file_rate_limit(QEMUFile *f); int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); int64_t qemu_file_get_rate_limit(QEMUFile *f); -int qemu_file_has_error(QEMUFile *f); -void qemu_file_set_error(QEMUFile *f); +int qemu_file_get_error(QEMUFile *f); +void qemu_file_set_error(QEMUFile *f, int error); /* Try to send any outstanding data. This function is useful when output is * halted due to rate limiting or EAGAIN errors occur as it can be used to @@ -298,6 +298,8 @@ enum VMStateFlags { VMS_VARRAY_UINT16 = 0x080, /* Array with size in uint16_t field */ VMS_VBUFFER = 0x100, /* Buffer with size in int32_t field */ VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */ + VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/ + VMS_VARRAY_UINT32 = 0x800, /* Array with size in uint32_t field*/ }; typedef struct { @@ -322,6 +324,7 @@ typedef struct VMStateSubsection { struct VMStateDescription { const char *name; + int unmigratable; int version_id; int minimum_version_id; int minimum_version_id_old; @@ -343,6 +346,7 @@ extern const VMStateInfo vmstate_info_int64; extern const VMStateInfo vmstate_info_uint8_equal; extern const VMStateInfo vmstate_info_uint16_equal; extern const VMStateInfo vmstate_info_int32_equal; +extern const VMStateInfo vmstate_info_uint32_equal; extern const VMStateInfo vmstate_info_int32_le; extern const VMStateInfo vmstate_info_uint8; @@ -396,6 +400,15 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_value(_state, _field, _type), \ } +#define VMSTATE_POINTER_TEST(_field, _state, _test, _info, _type) { \ + .name = (stringify(_field)), \ + .info = &(_info), \ + .field_exists = (_test), \ + .size = sizeof(_type), \ + .flags = VMS_SINGLE|VMS_POINTER, \ + .offset = vmstate_offset_value(_state, _field, _type), \ +} + #define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version), \ @@ -426,6 +439,15 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \ } +#define VMSTATE_ARRAY_INT32_UNSAFE(_field, _state, _field_num, _info, _type) {\ + .name = (stringify(_field)), \ + .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_VARRAY_INT32, \ + .offset = offsetof(_state, _field), \ +} + #define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version), \ @@ -436,6 +458,16 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_pointer(_state, _field, _type), \ } +#define VMSTATE_VARRAY_UINT32(_field, _state, _field_num, _version, _info, _type) {\ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_VARRAY_UINT32|VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ +} + #define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version), \ @@ -475,19 +507,50 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = vmstate_offset_array(_state, _field, _type, _num), \ } -#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) { \ +#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .num = (_num), \ + .field_exists = (_test), \ + .version_id = (_version), \ + .vmsd = &(_vmsd), \ + .size = sizeof(_type), \ + .flags = VMS_STRUCT|VMS_ARRAY, \ + .offset = vmstate_offset_array(_state, _field, _type, _num),\ +} + +#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \ .name = (stringify(_field)), \ - .num = (_num), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ .version_id = (_version), \ .vmsd = &(_vmsd), \ .size = sizeof(_type), \ - .flags = VMS_STRUCT|VMS_ARRAY, \ - .offset = vmstate_offset_array(_state, _field, _type, _num), \ + .flags = VMS_STRUCT|VMS_VARRAY_UINT8, \ + .offset = offsetof(_state, _field), \ } -#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \ +#define VMSTATE_STRUCT_VARRAY_POINTER_INT32(_field, _state, _field_num, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .version_id = 0, \ + .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ + .size = sizeof(_type), \ + .vmsd = &(_vmsd), \ + .flags = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ +} + +#define VMSTATE_STRUCT_VARRAY_POINTER_UINT16(_field, _state, _field_num, _vmsd, _type) { \ .name = (stringify(_field)), \ - .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ + .version_id = 0, \ + .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\ + .size = sizeof(_type), \ + .vmsd = &(_vmsd), \ + .flags = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ +} + +#define VMSTATE_STRUCT_VARRAY_INT32(_field, _state, _field_num, _version, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ .version_id = (_version), \ .vmsd = &(_vmsd), \ .size = sizeof(_type), \ @@ -495,6 +558,16 @@ extern const VMStateInfo vmstate_info_unused_buffer; .offset = offsetof(_state, _field), \ } +#define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \ + .version_id = (_version), \ + .vmsd = &(_vmsd), \ + .size = sizeof(_type), \ + .flags = VMS_STRUCT|VMS_VARRAY_UINT32, \ + .offset = offsetof(_state, _field), \ +} + #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ @@ -566,6 +639,14 @@ extern const VMStateDescription vmstate_pci_device; .offset = vmstate_offset_value(_state, _field, PCIDevice), \ } +#define VMSTATE_PCI_DEVICE_POINTER(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(PCIDevice), \ + .vmsd = &vmstate_pci_device, \ + .flags = VMS_STRUCT|VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, PCIDevice), \ +} + extern const VMStateDescription vmstate_pcie_device; #define VMSTATE_PCIE_DEVICE(_field, _state) { \ @@ -609,6 +690,37 @@ extern const VMStateDescription vmstate_usb_device; .offset = vmstate_offset_macaddr(_state, _field), \ } +extern const VMStateDescription vmstate_ptimer; + +#define VMSTATE_PTIMER(_field, _state) { \ + .name = (stringify(_field)), \ + .version_id = (1), \ + .vmsd = &vmstate_ptimer, \ + .size = sizeof(ptimer_state *), \ + .flags = VMS_STRUCT|VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, ptimer_state), \ +} + +extern const VMStateDescription vmstate_hid_keyboard_device; + +#define VMSTATE_HID_KEYBOARD_DEVICE(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(HIDState), \ + .vmsd = &vmstate_hid_keyboard_device, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, HIDState), \ +} + +extern const VMStateDescription vmstate_hid_ptr_device; + +#define VMSTATE_HID_POINTER_DEVICE(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(HIDState), \ + .vmsd = &vmstate_hid_ptr_device, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, HIDState), \ +} + /* _f : field name _f_n : num of elements field_name _n : num of elements @@ -625,6 +737,10 @@ extern const VMStateDescription vmstate_usb_device; #define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) \ VMSTATE_STRUCT_POINTER_TEST(_field, _state, NULL, _vmsd, _type) +#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \ + VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version, \ + _vmsd, _type) + #define VMSTATE_BOOL_V(_f, _s, _v) \ VMSTATE_SINGLE(_f, _s, _v, vmstate_info_bool, bool) @@ -679,30 +795,30 @@ extern const VMStateDescription vmstate_usb_device; #define VMSTATE_INT32_EQUAL(_f, _s) \ VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_equal, int32_t) +#define VMSTATE_UINT32_EQUAL(_f, _s) \ + VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint32_equal, uint32_t) + #define VMSTATE_INT32_LE(_f, _s) \ VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t) +#define VMSTATE_UINT8_TEST(_f, _s, _t) \ + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t) + #define VMSTATE_UINT16_TEST(_f, _s, _t) \ VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t) #define VMSTATE_UINT32_TEST(_f, _s, _t) \ VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t) -#define VMSTATE_TIMER_V(_f, _s, _v) \ - VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *) +#define VMSTATE_TIMER_TEST(_f, _s, _test) \ + VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *) #define VMSTATE_TIMER(_f, _s) \ - VMSTATE_TIMER_V(_f, _s, 0) + VMSTATE_TIMER_TEST(_f, _s, NULL) #define VMSTATE_TIMER_ARRAY(_f, _s, _n) \ VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *) -#define VMSTATE_PTIMER_V(_f, _s, _v) \ - VMSTATE_POINTER(_f, _s, _v, vmstate_info_ptimer, ptimer_state *) - -#define VMSTATE_PTIMER(_f, _s) \ - VMSTATE_PTIMER_V(_f, _s, 0) - #define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v) \ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool) @@ -751,6 +867,12 @@ extern const VMStateDescription vmstate_usb_device; #define VMSTATE_UINT32_ARRAY(_f, _s, _n) \ VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0) +#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \ + VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t) + +#define VMSTATE_INT64_ARRAY(_f, _s, _n) \ + VMSTATE_INT64_ARRAY_V(_f, _s, _n, 0) + #define VMSTATE_BUFFER_V(_f, _s, _v) \ VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f))) diff --git a/hw/i2c-addressable.c b/hw/i2c-addressable.c deleted file mode 100644 index eeb35a3..0000000 --- a/hw/i2c-addressable.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Interface to support I2C devices with control registers accessed by I2C - * - * Contributed by Alexey Merkulov - * Dmitry Zhurikhin - * Vladimir Monakhov - */ - -#include "i2c-addressable.h" - - -static int i2c_addressable_rx(i2c_slave *s) -{ - I2CAddressableDeviceInfo *t = - DO_UPCAST(I2CAddressableDeviceInfo, i2c, s->info); - I2CAddressableState *dev = FROM_I2C_SLAVE(I2CAddressableState, s); - - /* Get next byte of the value and transfer it */ - if (t->read) { - return t->read(dev, dev->addr, dev->num++); - } - return 0; -} - -static int i2c_addressable_tx(i2c_slave *s, uint8_t data) -{ - I2CAddressableDeviceInfo *t = - DO_UPCAST(I2CAddressableDeviceInfo, i2c, s->info); - I2CAddressableState *dev = FROM_I2C_SLAVE(I2CAddressableState, s); - - if (dev->num < t->size) { - /* First fully get control register address byte after byte */ - if (!t->rev) { - /* Less significant bytes come first */ - dev->addr |= data << (dev->num * 8); - } else { - /* More significant bytes come first */ - dev->addr |= data << ((t->size - dev->num - 1) * 8); - } - } else { - /* Then get corresponding data byte after byte */ - if (t->write) { - t->write(dev, dev->addr, dev->num - t->size, data); - } - } - - dev->num++; - return 1; -} - -static void i2c_addressable_event(i2c_slave *s, enum i2c_event event) -{ - I2CAddressableState *dev = FROM_I2C_SLAVE(I2CAddressableState, s); - - switch (event) { - case I2C_START_SEND: - dev->addr = 0; - /* fallthrough */ - case I2C_START_RECV: - /* Save address from the previous send */ - dev->num = 0; - break; - case I2C_FINISH: - default: - break; - } -} - -static int i2c_addressable_device_init(i2c_slave *s) -{ - I2CAddressableDeviceInfo *t = - DO_UPCAST(I2CAddressableDeviceInfo, i2c, s->info); - I2CAddressableState *dev = FROM_I2C_SLAVE(I2CAddressableState, s); - - return t->init(dev); -} - -void i2c_addressable_register_device(I2CAddressableDeviceInfo *info) -{ - assert(info->i2c.qdev.size >= sizeof(I2CAddressableState)); - info->i2c.init = i2c_addressable_device_init; - info->i2c.event = i2c_addressable_event; - info->i2c.recv = i2c_addressable_rx; - info->i2c.send = i2c_addressable_tx; - i2c_register_slave(&info->i2c); -} diff --git a/hw/i2c-addressable.h b/hw/i2c-addressable.h deleted file mode 100644 index 4a2a2f1..0000000 --- a/hw/i2c-addressable.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef QEMU_I2C_ADDRESSABLE_H -#define QEMU_I2C_ADDRESSABLE_H - -/* - * Interface to support I2C devices with control registers accessed by I2C - * - * Contributed by Alexey Merkulov - * Dmitry Zhurikhin - * Vladimir Monakhov - * - * Many I2C devices have common logic which closely corresponds to control - * registers. These devices are first passed with an ID of the needed command - * to be performed. This ID may be considered as control register address. - * Then the device is either passed with some data or is awaited to return - * some data. This may be considered as control register write and read - * respectively. This interface provides a generic way to implement such - * I2C devices emulation by writing two functions for reading and writing of - * control registers similar to iomem interface. One difference is that - * control registers may not have fixed sizes so along with the register - * address these functions get another parameter - offset inside this register - * data. - */ - -#include "i2c.h" - -#define I2CADDR_SLAVE_FROM_QDEV(dev) DO_UPCAST(I2CAddressableState, i2c.qdev, dev) -#define FROM_I2CADDR_SLAVE(type, dev) DO_UPCAST(type, i2c_addressable, dev) - -typedef struct I2CAddressableState { - /* I2C slave for the device */ - i2c_slave i2c; - /* Address of currently processing data */ - uint32_t addr; - /* Number of transferred bytes */ - uint8_t num; -} I2CAddressableState; - -typedef uint8_t (*i2c_addressable_read) (void *opaque, uint32_t address, - uint8_t offset); -typedef void (*i2c_addressable_write) (void *opaque, uint32_t address, - uint8_t offset, uint8_t val); -typedef int (*i2c_addressable_init) (I2CAddressableState *i2c); - -typedef struct I2CAddressableDeviceInfo { - I2CSlaveInfo i2c; - - /* Read, write and init handlers */ - i2c_addressable_read read; - i2c_addressable_write write; - i2c_addressable_init init; - - /* Size of passed addresses in bytes */ - int size; - /* Byte order: reversed is big-endian (more significant bytes come before - * less significant ones) */ - int rev; -} I2CAddressableDeviceInfo; - -void i2c_addressable_register_device(I2CAddressableDeviceInfo *info); - -#endif diff --git a/hw/i2c.c b/hw/i2c.c index f80d12d..9bcf3e1 100644 --- a/hw/i2c.c +++ b/hw/i2c.c @@ -4,7 +4,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. */ #include "i2c.h" @@ -84,7 +84,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv) DeviceState *qdev; i2c_slave *slave = NULL; - QLIST_FOREACH(qdev, &bus->qbus.children, sibling) { + QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) { i2c_slave *candidate = I2C_SLAVE_FROM_QDEV(qdev); if (candidate->address == address) { slave = candidate; diff --git a/hw/i2c.h b/hw/i2c.h index 83fd917..9381d01 100644 --- a/hw/i2c.h +++ b/hw/i2c.h @@ -59,11 +59,6 @@ void i2c_register_slave(I2CSlaveInfo *type); DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr); -/* max7310.c */ -void max7310_reset(i2c_slave *i2c); -qemu_irq *max7310_gpio_in_get(i2c_slave *i2c); -void max7310_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler); - /* wm8750.c */ void wm8750_data_req_set(DeviceState *dev, void (*data_req)(void *, int, int), void *opaque); @@ -77,6 +72,6 @@ void wm8750_set_bclk_in(void *opaque, int new_hz); void tmp105_set(i2c_slave *i2c, int temp); /* lm832x.c */ -void lm832x_key_event(i2c_slave *i2c, int key, int state); +void lm832x_key_event(DeviceState *dev, int key, int state); #endif diff --git a/hw/i8254.c b/hw/i8254.c index 06b225c..12571ef 100644 --- a/hw/i8254.c +++ b/hw/i8254.c @@ -53,9 +53,13 @@ typedef struct PITChannelState { qemu_irq irq; } PITChannelState; -struct PITState { +typedef struct PITState { + ISADevice dev; + MemoryRegion ioports; + uint32_t irq; + uint32_t iobase; PITChannelState channels[3]; -}; +} PITState; static PITState pit_state; @@ -66,7 +70,7 @@ static int pit_get_count(PITChannelState *s) uint64_t d; int counter; - d = muldiv64(qemu_get_clock(vm_clock) - s->count_load_time, PIT_FREQ, + d = muldiv64(qemu_get_clock_ns(vm_clock) - s->count_load_time, PIT_FREQ, get_ticks_per_sec()); switch(s->mode) { case 0: @@ -119,8 +123,9 @@ static int pit_get_out1(PITChannelState *s, int64_t current_time) return out; } -int pit_get_out(PITState *pit, int channel, int64_t current_time) +int pit_get_out(ISADevice *dev, int channel, int64_t current_time) { + PITState *pit = DO_UPCAST(PITState, dev, dev); PITChannelState *s = &pit->channels[channel]; return pit_get_out1(s, current_time); } @@ -179,8 +184,9 @@ static int64_t pit_get_next_transition_time(PITChannelState *s, } /* val must be 0 or 1 */ -void pit_set_gate(PITState *pit, int channel, int val) +void pit_set_gate(ISADevice *dev, int channel, int val) { + PITState *pit = DO_UPCAST(PITState, dev, dev); PITChannelState *s = &pit->channels[channel]; switch(s->mode) { @@ -193,7 +199,7 @@ void pit_set_gate(PITState *pit, int channel, int val) case 5: if (s->gate < val) { /* restart counting on rising edge */ - s->count_load_time = qemu_get_clock(vm_clock); + s->count_load_time = qemu_get_clock_ns(vm_clock); pit_irq_timer_update(s, s->count_load_time); } break; @@ -201,7 +207,7 @@ void pit_set_gate(PITState *pit, int channel, int val) case 3: if (s->gate < val) { /* restart counting on rising edge */ - s->count_load_time = qemu_get_clock(vm_clock); + s->count_load_time = qemu_get_clock_ns(vm_clock); pit_irq_timer_update(s, s->count_load_time); } /* XXX: disable/enable counting */ @@ -210,20 +216,23 @@ void pit_set_gate(PITState *pit, int channel, int val) s->gate = val; } -int pit_get_gate(PITState *pit, int channel) +int pit_get_gate(ISADevice *dev, int channel) { + PITState *pit = DO_UPCAST(PITState, dev, dev); PITChannelState *s = &pit->channels[channel]; return s->gate; } -int pit_get_initial_count(PITState *pit, int channel) +int pit_get_initial_count(ISADevice *dev, int channel) { + PITState *pit = DO_UPCAST(PITState, dev, dev); PITChannelState *s = &pit->channels[channel]; return s->count; } -int pit_get_mode(PITState *pit, int channel) +int pit_get_mode(ISADevice *dev, int channel) { + PITState *pit = DO_UPCAST(PITState, dev, dev); PITChannelState *s = &pit->channels[channel]; return s->mode; } @@ -232,7 +241,7 @@ static inline void pit_load_count(PITChannelState *s, int val) { if (val == 0) val = 0x10000; - s->count_load_time = qemu_get_clock(vm_clock); + s->count_load_time = qemu_get_clock_ns(vm_clock); s->count = val; pit_irq_timer_update(s, s->count_load_time); } @@ -266,7 +275,7 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) if (!(val & 0x10) && !s->status_latched) { /* status latch */ /* XXX: add BCD and null count */ - s->status = (pit_get_out1(s, qemu_get_clock(vm_clock)) << 7) | + s->status = (pit_get_out1(s, qemu_get_clock_ns(vm_clock)) << 7) | (s->rw_mode << 4) | (s->mode << 1) | s->bcd; @@ -462,9 +471,9 @@ static const VMStateDescription vmstate_pit = { } }; -static void pit_reset(void *opaque) +static void pit_reset(DeviceState *dev) { - PITState *pit = opaque; + PITState *pit = container_of(dev, PITState, dev.qdev); PITChannelState *s; int i; @@ -498,20 +507,50 @@ void hpet_pit_enable(void) pit_load_count(s, 0); } -PITState *pit_init(int base, qemu_irq irq) +static const MemoryRegionPortio pit_portio[] = { + { 0, 4, 1, .write = pit_ioport_write }, + { 0, 3, 1, .read = pit_ioport_read }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps pit_ioport_ops = { + .old_portio = pit_portio +}; + +static int pit_initfn(ISADevice *dev) { - PITState *pit = &pit_state; + PITState *pit = DO_UPCAST(PITState, dev, dev); PITChannelState *s; s = &pit->channels[0]; /* the timer 0 is connected to an IRQ */ - s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s); - s->irq = irq; + s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s); + s->irq = isa_get_irq(pit->irq); - vmstate_register(NULL, base, &vmstate_pit, pit); - qemu_register_reset(pit_reset, pit); - register_ioport_write(base, 4, 1, pit_ioport_write, pit); - register_ioport_read(base, 3, 1, pit_ioport_read, pit); + memory_region_init_io(&pit->ioports, &pit_ioport_ops, pit, "pit", 4); + isa_register_ioport(dev, &pit->ioports, pit->iobase); - return pit; + qdev_set_legacy_instance_id(&dev->qdev, pit->iobase, 2); + + return 0; +} + +static ISADeviceInfo pit_info = { + .qdev.name = "isa-pit", + .qdev.size = sizeof(PITState), + .qdev.vmsd = &vmstate_pit, + .qdev.reset = pit_reset, + .qdev.no_user = 1, + .init = pit_initfn, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("irq", PITState, irq, -1), + DEFINE_PROP_HEX32("iobase", PITState, iobase, -1), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static void pit_register(void) +{ + isa_qdev_register(&pit_info); } +device_init(pit_register) diff --git a/hw/i8259.c b/hw/i8259.c index a8dbee6..ab519de 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -40,7 +40,8 @@ //#define DEBUG_IRQ_LATENCY //#define DEBUG_IRQ_COUNT -typedef struct PicState { +struct PicState { + ISADevice dev; uint8_t last_irr; /* edge detection */ uint8_t irr; /* interrupt request register */ uint8_t imr; /* interrupt mask register */ @@ -58,61 +59,39 @@ typedef struct PicState { uint8_t single_mode; /* true if slave pic is not initialized */ uint8_t elcr; /* PIIX edge/trigger selection*/ uint8_t elcr_mask; - PicState2 *pics_state; -} PicState; - -struct PicState2 { - /* 0 is master pic, 1 is slave pic */ - /* XXX: better separation between the two pics */ - PicState pics[2]; - qemu_irq parent_irq; - void *irq_request_opaque; + qemu_irq int_out[1]; + uint32_t master; /* reflects /SP input pin */ + uint32_t iobase; + uint32_t elcr_addr; + MemoryRegion base_io; + MemoryRegion elcr_io; }; -#if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT) +#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) static int irq_level[16]; #endif #ifdef DEBUG_IRQ_COUNT static uint64_t irq_count[16]; #endif -PicState2 *isa_pic; - -/* set irq level. If an edge is detected, then the IRR is set to 1 */ -static inline void pic_set_irq1(PicState *s, int irq, int level) -{ - int mask; - mask = 1 << irq; - if (s->elcr & mask) { - /* level triggered */ - if (level) { - s->irr |= mask; - s->last_irr |= mask; - } else { - s->irr &= ~mask; - s->last_irr &= ~mask; - } - } else { - /* edge triggered */ - if (level) { - if ((s->last_irr & mask) == 0) - s->irr |= mask; - s->last_irr |= mask; - } else { - s->last_irr &= ~mask; - } - } -} +#ifdef DEBUG_IRQ_LATENCY +static int64_t irq_time[16]; +#endif +PicState *isa_pic; +static PicState *slave_pic; /* return the highest priority found in mask (highest = smallest number). Return 8 if no irq */ -static inline int get_priority(PicState *s, int mask) +static int get_priority(PicState *s, int mask) { int priority; - if (mask == 0) + + if (mask == 0) { return 8; + } priority = 0; - while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) + while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) { priority++; + } return priority; } @@ -123,16 +102,19 @@ static int pic_get_irq(PicState *s) mask = s->irr & ~s->imr; priority = get_priority(s, mask); - if (priority == 8) + if (priority == 8) { return -1; + } /* compute current priority. If special fully nested mode on the master, the IRQ coming from the slave is not taken into account for the priority computation. */ mask = s->isr; - if (s->special_mask) + if (s->special_mask) { mask &= ~s->imr; - if (s->special_fully_nested_mode && s == &s->pics_state->pics[0]) + } + if (s->special_fully_nested_mode && s->master) { mask &= ~(1 << 2); + } cur_priority = get_priority(s, mask); if (priority < cur_priority) { /* higher priority found: an irq should be generated */ @@ -142,130 +124,130 @@ static int pic_get_irq(PicState *s) } } -/* raise irq to CPU if necessary. must be called every time the active - irq may change */ -/* XXX: should not export it, but it is needed for an APIC kludge */ -void pic_update_irq(PicState2 *s) +/* Update INT output. Must be called every time the output may have changed. */ +static void pic_update_irq(PicState *s) { - int irq2, irq; - - /* first look at slave pic */ - irq2 = pic_get_irq(&s->pics[1]); - if (irq2 >= 0) { - /* if irq request by slave pic, signal master PIC */ - pic_set_irq1(&s->pics[0], 2, 1); - pic_set_irq1(&s->pics[0], 2, 0); - } - /* look at requested irq */ - irq = pic_get_irq(&s->pics[0]); - if (irq >= 0) { -#if defined(DEBUG_PIC) - { - int i; - for(i = 0; i < 2; i++) { - printf("pic%d: imr=%x irr=%x padd=%d\n", - i, s->pics[i].imr, s->pics[i].irr, - s->pics[i].priority_add); + int irq; - } - } - printf("pic: cpu_interrupt\n"); -#endif - qemu_irq_raise(s->parent_irq); - } - -/* all targets should do this rather than acking the IRQ in the cpu */ -#if defined(TARGET_MIPS) || defined(TARGET_PPC) || defined(TARGET_ALPHA) - else { - qemu_irq_lower(s->parent_irq); + irq = pic_get_irq(s); + if (irq >= 0) { + DPRINTF("pic%d: imr=%x irr=%x padd=%d\n", + s->master ? 0 : 1, s->imr, s->irr, s->priority_add); + qemu_irq_raise(s->int_out[0]); + } else { + qemu_irq_lower(s->int_out[0]); } -#endif } -#ifdef DEBUG_IRQ_LATENCY -int64_t irq_time[16]; -#endif - -static void i8259_set_irq(void *opaque, int irq, int level) +/* set irq level. If an edge is detected, then the IRR is set to 1 */ +static void pic_set_irq(void *opaque, int irq, int level) { - PicState2 *s = opaque; + PicState *s = opaque; + int mask = 1 << irq; +#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) || \ + defined(DEBUG_IRQ_LATENCY) + int irq_index = s->master ? irq : irq + 8; +#endif #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) - if (level != irq_level[irq]) { - DPRINTF("i8259_set_irq: irq=%d level=%d\n", irq, level); - irq_level[irq] = level; + if (level != irq_level[irq_index]) { + DPRINTF("pic_set_irq: irq=%d level=%d\n", irq_index, level); + irq_level[irq_index] = level; #ifdef DEBUG_IRQ_COUNT - if (level == 1) - irq_count[irq]++; + if (level == 1) { + irq_count[irq_index]++; + } #endif } #endif #ifdef DEBUG_IRQ_LATENCY if (level) { - irq_time[irq] = qemu_get_clock(vm_clock); + irq_time[irq_index] = qemu_get_clock_ns(vm_clock); } #endif - pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); + + if (s->elcr & mask) { + /* level triggered */ + if (level) { + s->irr |= mask; + s->last_irr |= mask; + } else { + s->irr &= ~mask; + s->last_irr &= ~mask; + } + } else { + /* edge triggered */ + if (level) { + if ((s->last_irr & mask) == 0) { + s->irr |= mask; + } + s->last_irr |= mask; + } else { + s->last_irr &= ~mask; + } + } pic_update_irq(s); } /* acknowledge interrupt 'irq' */ -static inline void pic_intack(PicState *s, int irq) +static void pic_intack(PicState *s, int irq) { if (s->auto_eoi) { - if (s->rotate_on_auto_eoi) + if (s->rotate_on_auto_eoi) { s->priority_add = (irq + 1) & 7; + } } else { s->isr |= (1 << irq); } /* We don't clear a level sensitive interrupt here */ - if (!(s->elcr & (1 << irq))) + if (!(s->elcr & (1 << irq))) { s->irr &= ~(1 << irq); + } + pic_update_irq(s); } -int pic_read_irq(PicState2 *s) +int pic_read_irq(PicState *s) { int irq, irq2, intno; - irq = pic_get_irq(&s->pics[0]); + irq = pic_get_irq(s); if (irq >= 0) { - pic_intack(&s->pics[0], irq); if (irq == 2) { - irq2 = pic_get_irq(&s->pics[1]); + irq2 = pic_get_irq(slave_pic); if (irq2 >= 0) { - pic_intack(&s->pics[1], irq2); + pic_intack(slave_pic, irq2); } else { /* spurious IRQ on slave controller */ irq2 = 7; } - intno = s->pics[1].irq_base + irq2; -#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY) - irq = irq2 + 8; -#endif + intno = slave_pic->irq_base + irq2; } else { - intno = s->pics[0].irq_base + irq; + intno = s->irq_base + irq; } + pic_intack(s, irq); } else { /* spurious IRQ on host controller */ irq = 7; - intno = s->pics[0].irq_base + irq; + intno = s->irq_base + irq; } - pic_update_irq(s); +#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY) + if (irq == 2) { + irq = irq2 + 8; + } +#endif #ifdef DEBUG_IRQ_LATENCY printf("IRQ%d latency=%0.3fus\n", irq, - (double)(qemu_get_clock(vm_clock) - + (double)(qemu_get_clock_ns(vm_clock) - irq_time[irq]) * 1000000.0 / get_ticks_per_sec()); #endif DPRINTF("pic_interrupt: irq=%d\n", irq); return intno; } -static void pic_reset(void *opaque) +static void pic_init_reset(PicState *s) { - PicState *s = opaque; - s->last_irr = 0; s->irr = 0; s->imr = 0; @@ -282,36 +264,48 @@ static void pic_reset(void *opaque) s->init4 = 0; s->single_mode = 0; /* Note: ELCR is not reset */ + pic_update_irq(s); +} + +static void pic_reset(DeviceState *dev) +{ + PicState *s = container_of(dev, PicState, dev.qdev); + + pic_init_reset(s); + s->elcr = 0; } -static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void pic_ioport_write(void *opaque, target_phys_addr_t addr64, + uint64_t val64, unsigned size) { PicState *s = opaque; + uint32_t addr = addr64; + uint32_t val = val64; int priority, cmd, irq; DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val); - addr &= 1; if (addr == 0) { if (val & 0x10) { - /* init */ - pic_reset(s); - /* deassert a pending interrupt */ - qemu_irq_lower(s->pics_state->parent_irq); + pic_init_reset(s); s->init_state = 1; s->init4 = val & 1; s->single_mode = val & 2; - if (val & 0x08) + if (val & 0x08) { hw_error("level sensitive irq not supported"); + } } else if (val & 0x08) { - if (val & 0x04) + if (val & 0x04) { s->poll = 1; - if (val & 0x02) + } + if (val & 0x02) { s->read_reg_select = val & 1; - if (val & 0x40) + } + if (val & 0x40) { s->special_mask = (val >> 5) & 1; + } } else { cmd = val >> 5; - switch(cmd) { + switch (cmd) { case 0: case 4: s->rotate_on_auto_eoi = cmd >> 2; @@ -322,25 +316,26 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) if (priority != 8) { irq = (priority + s->priority_add) & 7; s->isr &= ~(1 << irq); - if (cmd == 5) + if (cmd == 5) { s->priority_add = (irq + 1) & 7; - pic_update_irq(s->pics_state); + } + pic_update_irq(s); } break; case 3: irq = val & 7; s->isr &= ~(1 << irq); - pic_update_irq(s->pics_state); + pic_update_irq(s); break; case 6: s->priority_add = (val + 1) & 7; - pic_update_irq(s->pics_state); + pic_update_irq(s); break; case 7: irq = val & 7; s->isr &= ~(1 << irq); s->priority_add = (irq + 1) & 7; - pic_update_irq(s->pics_state); + pic_update_irq(s); break; default: /* no operation */ @@ -348,11 +343,11 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } } else { - switch(s->init_state) { + switch (s->init_state) { case 0: /* normal mode */ s->imr = val; - pic_update_irq(s->pics_state); + pic_update_irq(s); break; case 1: s->irq_base = val & 0xf8; @@ -374,75 +369,50 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -static uint32_t pic_poll_read (PicState *s, uint32_t addr1) -{ - int ret; - - ret = pic_get_irq(s); - if (ret >= 0) { - if (addr1 >> 7) { - s->pics_state->pics[0].isr &= ~(1 << 2); - s->pics_state->pics[0].irr &= ~(1 << 2); - } - s->irr &= ~(1 << ret); - s->isr &= ~(1 << ret); - if (addr1 >> 7 || ret != 2) - pic_update_irq(s->pics_state); - } else { - ret = 0x07; - pic_update_irq(s->pics_state); - } - - return ret; -} - -static uint32_t pic_ioport_read(void *opaque, uint32_t addr1) +static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PicState *s = opaque; - unsigned int addr; int ret; - addr = addr1; - addr &= 1; if (s->poll) { - ret = pic_poll_read(s, addr1); + ret = pic_get_irq(s); + if (ret >= 0) { + pic_intack(s, ret); + ret |= 0x80; + } else { + ret = 0; + } s->poll = 0; } else { if (addr == 0) { - if (s->read_reg_select) + if (s->read_reg_select) { ret = s->isr; - else + } else { ret = s->irr; + } } else { ret = s->imr; } } - DPRINTF("read: addr=0x%02x val=0x%02x\n", addr1, ret); + DPRINTF("read: addr=0x%02x val=0x%02x\n", addr, ret); return ret; } -/* memory mapped interrupt status */ -/* XXX: may be the same than pic_read_irq() */ -uint32_t pic_intack_read(PicState2 *s) +int pic_get_output(PicState *s) { - int ret; - - ret = pic_poll_read(&s->pics[0], 0x00); - if (ret == 2) - ret = pic_poll_read(&s->pics[1], 0x80) + 8; - /* Prepare for ISR read */ - s->pics[0].read_reg_select = 1; - - return ret; + return (pic_get_irq(s) >= 0); } -static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void elcr_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { PicState *s = opaque; s->elcr = val & s->elcr_mask; } -static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1) +static uint64_t elcr_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PicState *s = opaque; return s->elcr; @@ -453,7 +423,7 @@ static const VMStateDescription vmstate_pic = { .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, - .fields = (VMStateField []) { + .fields = (VMStateField[]) { VMSTATE_UINT8(last_irr, PicState), VMSTATE_UINT8(irr, PicState), VMSTATE_UINT8(imr, PicState), @@ -474,17 +444,42 @@ static const VMStateDescription vmstate_pic = { } }; -/* XXX: add generic master/slave system */ -static void pic_init1(int io_addr, int elcr_addr, PicState *s) +static const MemoryRegionOps pic_base_ioport_ops = { + .read = pic_ioport_read, + .write = pic_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +static const MemoryRegionOps pic_elcr_ioport_ops = { + .read = elcr_ioport_read, + .write = elcr_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +static int pic_initfn(ISADevice *dev) { - register_ioport_write(io_addr, 2, 1, pic_ioport_write, s); - register_ioport_read(io_addr, 2, 1, pic_ioport_read, s); - if (elcr_addr >= 0) { - register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s); - register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s); + PicState *s = DO_UPCAST(PicState, dev, dev); + + memory_region_init_io(&s->base_io, &pic_base_ioport_ops, s, "pic", 2); + memory_region_init_io(&s->elcr_io, &pic_elcr_ioport_ops, s, "elcr", 1); + + isa_register_ioport(NULL, &s->base_io, s->iobase); + if (s->elcr_addr != -1) { + isa_register_ioport(NULL, &s->elcr_io, s->elcr_addr); } - vmstate_register(NULL, io_addr, &vmstate_pic, s); - qemu_register_reset(pic_reset, s); + + qdev_init_gpio_out(&dev->qdev, s->int_out, ARRAY_SIZE(s->int_out)); + qdev_init_gpio_in(&dev->qdev, pic_set_irq, 8); + + qdev_set_legacy_instance_id(&dev->qdev, s->iobase, 1); + + return 0; } void pic_info(Monitor *mon) @@ -492,11 +487,11 @@ void pic_info(Monitor *mon) int i; PicState *s; - if (!isa_pic) + if (!isa_pic) { return; - - for(i=0;i<2;i++) { - s = &isa_pic->pics[i]; + } + for (i = 0; i < 2; i++) { + s = i == 0 ? isa_pic : slave_pic; monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d " "irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n", i, s->irr, s->imr, s->isr, s->priority_add, @@ -516,24 +511,69 @@ void irq_info(Monitor *mon) monitor_printf(mon, "IRQ statistics:\n"); for (i = 0; i < 16; i++) { count = irq_count[i]; - if (count > 0) + if (count > 0) { monitor_printf(mon, "%2d: %" PRId64 "\n", i, count); + } } #endif } qemu_irq *i8259_init(qemu_irq parent_irq) { - PicState2 *s; - - s = qemu_mallocz(sizeof(PicState2)); - pic_init1(0x20, 0x4d0, &s->pics[0]); - pic_init1(0xa0, 0x4d1, &s->pics[1]); - s->pics[0].elcr_mask = 0xf8; - s->pics[1].elcr_mask = 0xde; - s->parent_irq = parent_irq; - s->pics[0].pics_state = s; - s->pics[1].pics_state = s; - isa_pic = s; - return qemu_allocate_irqs(i8259_set_irq, s, 16); + qemu_irq *irq_set; + ISADevice *dev; + int i; + + irq_set = g_malloc(ISA_NUM_IRQS * sizeof(qemu_irq)); + + dev = isa_create("isa-i8259"); + qdev_prop_set_uint32(&dev->qdev, "iobase", 0x20); + qdev_prop_set_uint32(&dev->qdev, "elcr_addr", 0x4d0); + qdev_prop_set_uint8(&dev->qdev, "elcr_mask", 0xf8); + qdev_prop_set_bit(&dev->qdev, "master", true); + qdev_init_nofail(&dev->qdev); + + qdev_connect_gpio_out(&dev->qdev, 0, parent_irq); + for (i = 0 ; i < 8; i++) { + irq_set[i] = qdev_get_gpio_in(&dev->qdev, i); + } + + isa_pic = DO_UPCAST(PicState, dev, dev); + + dev = isa_create("isa-i8259"); + qdev_prop_set_uint32(&dev->qdev, "iobase", 0xa0); + qdev_prop_set_uint32(&dev->qdev, "elcr_addr", 0x4d1); + qdev_prop_set_uint8(&dev->qdev, "elcr_mask", 0xde); + qdev_init_nofail(&dev->qdev); + + qdev_connect_gpio_out(&dev->qdev, 0, irq_set[2]); + for (i = 0 ; i < 8; i++) { + irq_set[i + 8] = qdev_get_gpio_in(&dev->qdev, i); + } + + slave_pic = DO_UPCAST(PicState, dev, dev); + + return irq_set; +} + +static ISADeviceInfo i8259_info = { + .qdev.name = "isa-i8259", + .qdev.size = sizeof(PicState), + .qdev.vmsd = &vmstate_pic, + .qdev.reset = pic_reset, + .qdev.no_user = 1, + .init = pic_initfn, + .qdev.props = (Property[]) { + DEFINE_PROP_HEX32("iobase", PicState, iobase, -1), + DEFINE_PROP_HEX32("elcr_addr", PicState, elcr_addr, -1), + DEFINE_PROP_HEX8("elcr_mask", PicState, elcr_mask, -1), + DEFINE_PROP_BIT("master", PicState, master, 0, false), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static void pic_register(void) +{ + isa_qdev_register(&i8259_info); } +device_init(pic_register) diff --git a/hw/ide.h b/hw/ide.h index 73fb550..9059aae 100644 --- a/hw/ide.h +++ b/hw/ide.h @@ -13,12 +13,13 @@ ISADevice *isa_ide_init(int iobase, int iobase2, int isairq, /* ide-pci.c */ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, int secondary_ide_enabled); +PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); /* ide-macio.c */ -int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, +MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, void *dbdma, int channel, qemu_irq dma_irq); /* ide-mmio.c */ @@ -28,4 +29,7 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2, void ide_get_bs(BlockDriverState *bs[], BusState *qbus); +/* ide/core.c */ +void ide_drive_get(DriveInfo **hd, int max_bus); + #endif /* HW_IDE_H */ diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 98bdf70..0af201d 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -276,12 +276,12 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val) } } -static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr) +static uint64_t ahci_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - AHCIState *s = ptr; + AHCIState *s = opaque; uint32_t val = 0; - addr = addr & 0xfff; if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) { switch (addr) { case HOST_CAP: @@ -314,10 +314,10 @@ static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr) -static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) +static void ahci_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - AHCIState *s = ptr; - addr = addr & 0xfff; + AHCIState *s = opaque; /* Only aligned reads are allowed on AHCI */ if (addr & 3) { @@ -327,7 +327,7 @@ static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) } if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) { - DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val); + DPRINTF(-1, "(addr 0x%08X), val 0x%08"PRIX64"\n", (unsigned) addr, val); switch (addr) { case HOST_CAP: /* R/WO, RO */ @@ -364,18 +364,49 @@ static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) } -static CPUReadMemoryFunc * const ahci_readfn[3]={ - ahci_mem_readl, - ahci_mem_readl, - ahci_mem_readl +static MemoryRegionOps ahci_mem_ops = { + .read = ahci_mem_read, + .write = ahci_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static CPUWriteMemoryFunc * const ahci_writefn[3]={ - ahci_mem_writel, - ahci_mem_writel, - ahci_mem_writel +static uint64_t ahci_idp_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + AHCIState *s = opaque; + + if (addr == s->idp_offset) { + /* index register */ + return s->idp_index; + } else if (addr == s->idp_offset + 4) { + /* data register - do memory read at location selected by index */ + return ahci_mem_read(opaque, s->idp_index, size); + } else { + return 0; + } +} + +static void ahci_idp_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) +{ + AHCIState *s = opaque; + + if (addr == s->idp_offset) { + /* index register - mask off reserved bits */ + s->idp_index = (uint32_t)val & ((AHCI_MEM_BAR_SIZE - 1) & ~3); + } else if (addr == s->idp_offset + 4) { + /* data register - do memory write at location selected by index */ + ahci_mem_write(opaque, s->idp_index, val, size); + } +} + +static MemoryRegionOps ahci_idp_ops = { + .read = ahci_idp_read, + .write = ahci_idp_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; + static void ahci_reg_init(AHCIState *s) { int i; @@ -505,10 +536,7 @@ static void ahci_reset_port(AHCIState *s, int port) ide_bus_reset(&d->port); ide_state->ncq_queues = AHCI_MAX_CMDS; - pr->irq_stat = 0; - pr->irq_mask = 0; pr->scr_stat = 0; - pr->scr_ctl = 0; pr->scr_err = 0; pr->scr_act = 0; d->busy_slot = -1; @@ -716,6 +744,7 @@ static void ncq_cb(void *opaque, int ret) DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n", ncq_tfs->tag); + bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct); qemu_sglist_destroy(&ncq_tfs->sglist); ncq_tfs->used = 0; } @@ -748,7 +777,8 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis, ncq_tfs->sector_count = ((uint16_t)ncq_fis->sector_count_high << 8) | ncq_fis->sector_count_low; - DPRINTF(port, "NCQ transfer LBA from %ld to %ld, drive max %ld\n", + DPRINTF(port, "NCQ transfer LBA from %"PRId64" to %"PRId64", " + "drive max %"PRId64"\n", ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 2, s->dev[port].port.ifs[0].nb_sectors - 1); @@ -757,21 +787,30 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis, switch(ncq_fis->command) { case READ_FPDMA_QUEUED: - DPRINTF(port, "NCQ reading %d sectors from LBA %ld, tag %d\n", + DPRINTF(port, "NCQ reading %d sectors from LBA %"PRId64", " + "tag %d\n", ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag); - ncq_tfs->is_read = 1; - DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba); + DPRINTF(port, "tag %d aio read %"PRId64"\n", + ncq_tfs->tag, ncq_tfs->lba); + + bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct, + (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE, + BDRV_ACCT_READ); ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->sglist, ncq_tfs->lba, ncq_cb, ncq_tfs); break; case WRITE_FPDMA_QUEUED: - DPRINTF(port, "NCQ writing %d sectors to LBA %ld, tag %d\n", + DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n", ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag); - ncq_tfs->is_read = 0; - DPRINTF(port, "tag %d aio write %ld\n", ncq_tfs->tag, ncq_tfs->lba); + DPRINTF(port, "tag %d aio write %"PRId64"\n", + ncq_tfs->tag, ncq_tfs->lba); + + bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct, + (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE, + BDRV_ACCT_WRITE); ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->sglist, ncq_tfs->lba, ncq_cb, ncq_tfs); @@ -884,8 +923,31 @@ static int handle_cmd(AHCIState *s, int port, int slot) } if (ide_state->drive_kind != IDE_CD) { - ide_set_sector(ide_state, (cmd_fis[6] << 16) | (cmd_fis[5] << 8) | - cmd_fis[4]); + /* + * We set the sector depending on the sector defined in the FIS. + * Unfortunately, the spec isn't exactly obvious on this one. + * + * Apparently LBA48 commands set fis bytes 10,9,8,6,5,4 to the + * 48 bit sector number. ATA_CMD_READ_DMA_EXT is an example for + * such a command. + * + * Non-LBA48 commands however use 7[lower 4 bits],6,5,4 to define a + * 28-bit sector number. ATA_CMD_READ_DMA is an example for such + * a command. + * + * Since the spec doesn't explicitly state what each field should + * do, I simply assume non-used fields as reserved and OR everything + * together, independent of the command. + */ + ide_set_sector(ide_state, ((uint64_t)cmd_fis[10] << 40) + | ((uint64_t)cmd_fis[9] << 32) + /* This is used for LBA48 commands */ + | ((uint64_t)cmd_fis[8] << 24) + /* This is used for non-LBA48 commands */ + | ((uint64_t)(cmd_fis[7] & 0xf) << 24) + | ((uint64_t)cmd_fis[6] << 16) + | ((uint64_t)cmd_fis[5] << 8) + | cmd_fis[4]); } /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command @@ -1066,9 +1128,11 @@ static int ahci_dma_set_inactive(IDEDMA *dma) ad->dma_cb = NULL; - /* maybe we still have something to process, check later */ - ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad); - qemu_bh_schedule(ad->check_bh); + if (!ad->check_bh) { + /* maybe we still have something to process, check later */ + ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad); + qemu_bh_schedule(ad->check_bh); + } return 0; } @@ -1077,7 +1141,7 @@ static void ahci_irq_set(void *opaque, int n, int level) { } -static void ahci_dma_restart_cb(void *opaque, int running, int reason) +static void ahci_dma_restart_cb(void *opaque, int running, RunState state) { } @@ -1104,10 +1168,12 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports) int i; s->ports = ports; - s->dev = qemu_mallocz(sizeof(AHCIDevice) * ports); + s->dev = g_malloc0(sizeof(AHCIDevice) * ports); ahci_reg_init(s); - s->mem = cpu_register_io_memory(ahci_readfn, ahci_writefn, s, - DEVICE_LITTLE_ENDIAN); + /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */ + memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", AHCI_MEM_BAR_SIZE); + memory_region_init_io(&s->idp, &ahci_idp_ops, s, "ahci-idp", 32); + irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports); for (i = 0; i < s->ports; i++) { @@ -1126,27 +1192,25 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports) void ahci_uninit(AHCIState *s) { - qemu_free(s->dev); -} - -void ahci_pci_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - struct AHCIPCIState *d = (struct AHCIPCIState *)pci_dev; - AHCIState *s = &d->ahci; - - cpu_register_physical_memory(addr, size, s->mem); + memory_region_destroy(&s->mem); + memory_region_destroy(&s->idp); + g_free(s->dev); } void ahci_reset(void *opaque) { struct AHCIPCIState *d = opaque; + AHCIPortRegs *pr; int i; d->ahci.control_regs.irqstatus = 0; d->ahci.control_regs.ghc = 0; for (i = 0; i < d->ahci.ports; i++) { + pr = &d->ahci.dev[i].port_regs; + pr->irq_stat = 0; + pr->irq_mask = 0; + pr->scr_ctl = 0; ahci_reset_port(&d->ahci, i); } } diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h index a4560c4..b223d2c 100644 --- a/hw/ide/ahci.h +++ b/hw/ide/ahci.h @@ -24,7 +24,7 @@ #ifndef HW_IDE_AHCI_H #define HW_IDE_AHCI_H -#define AHCI_PCI_BAR 5 +#define AHCI_MEM_BAR_SIZE 0x1000 #define AHCI_MAX_PORTS 32 #define AHCI_MAX_SG 168 /* hardware max is 64K */ #define AHCI_DMA_BOUNDARY 0xffffffff @@ -212,6 +212,10 @@ #define RES_FIS_SDBFIS 0x58 #define RES_FIS_UFIS 0x60 +#define SATA_CAP_SIZE 0x8 +#define SATA_CAP_REV 0x2 +#define SATA_CAP_BAR 0x4 + typedef struct AHCIControlRegs { uint32_t cap; uint32_t ghc; @@ -244,13 +248,13 @@ typedef struct AHCICmdHdr { uint32_t status; uint64_t tbl_addr; uint32_t reserved[4]; -} __attribute__ ((packed)) AHCICmdHdr; +} QEMU_PACKED AHCICmdHdr; typedef struct AHCI_SG { uint64_t addr; uint32_t reserved; uint32_t flags_size; -} __attribute__ ((packed)) AHCI_SG; +} QEMU_PACKED AHCI_SG; typedef struct AHCIDevice AHCIDevice; @@ -258,7 +262,7 @@ typedef struct NCQTransferState { AHCIDevice *drive; BlockDriverAIOCB *aiocb; QEMUSGList sglist; - int is_read; + BlockAcctCookie acct; uint16_t sector_count; uint64_t lba; uint8_t tag; @@ -289,7 +293,10 @@ struct AHCIDevice { typedef struct AHCIState { AHCIDevice *dev; AHCIControlRegs control_regs; - int mem; + MemoryRegion mem; + MemoryRegion idp; /* Index-Data Pair I/O port space */ + unsigned idp_offset; /* Offset of index in I/O port space */ + uint32_t idp_index; /* Current IDP index */ int ports; qemu_irq irq; } AHCIState; @@ -320,14 +327,11 @@ typedef struct NCQFrame { uint8_t reserved8; uint8_t reserved9; uint8_t reserved10; -} __attribute__ ((packed)) NCQFrame; +} QEMU_PACKED NCQFrame; void ahci_init(AHCIState *s, DeviceState *qdev, int ports); void ahci_uninit(AHCIState *s); -void ahci_pci_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type); - void ahci_reset(void *opaque); #endif /* HW_IDE_AHCI_H */ diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 5d5464a..5fe98b1 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -27,7 +27,6 @@ #include #include #include "block.h" -#include "block_int.h" #include "sysemu.h" #include "dma.h" @@ -44,35 +43,95 @@ static void cmd646_update_irq(PCIIDEState *d); -static void ide_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); - IDEBus *bus; - - if (region_num <= 3) { - bus = &d->bus[(region_num >> 1)]; - if (region_num & 1) { - register_ioport_read(addr + 2, 1, 1, ide_status_read, bus); - register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus); + CMD646BAR *cmd646bar = opaque; + + if (addr != 2 || size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + return ide_status_read(cmd646bar->bus, addr + 2); +} + +static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + CMD646BAR *cmd646bar = opaque; + + if (addr != 2 || size != 1) { + return; + } + ide_cmd_write(cmd646bar->bus, addr + 2, data); +} + +static MemoryRegionOps cmd646_cmd_ops = { + .read = cmd646_cmd_read, + .write = cmd646_cmd_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + CMD646BAR *cmd646bar = opaque; + + if (size == 1) { + return ide_ioport_read(cmd646bar->bus, addr); + } else if (addr == 0) { + if (size == 2) { + return ide_data_readw(cmd646bar->bus, addr); + } else { + return ide_data_readl(cmd646bar->bus, addr); + } + } + return ((uint64_t)1 << (size * 8)) - 1; +} + +static void cmd646_data_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + CMD646BAR *cmd646bar = opaque; + + if (size == 1) { + return ide_ioport_write(cmd646bar->bus, addr, data); + } else if (addr == 0) { + if (size == 2) { + return ide_data_writew(cmd646bar->bus, addr, data); } else { - register_ioport_write(addr, 8, 1, ide_ioport_write, bus); - register_ioport_read(addr, 8, 1, ide_ioport_read, bus); - - /* data ports */ - register_ioport_write(addr, 2, 2, ide_data_writew, bus); - register_ioport_read(addr, 2, 2, ide_data_readw, bus); - register_ioport_write(addr, 4, 4, ide_data_writel, bus); - register_ioport_read(addr, 4, 4, ide_data_readl, bus); + return ide_data_writel(cmd646bar->bus, addr, data); } } } -static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm, - uint32_t addr) +static MemoryRegionOps cmd646_data_ops = { + .read = cmd646_data_read, + .write = cmd646_data_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void setup_cmd646_bar(PCIIDEState *d, int bus_num) +{ + IDEBus *bus = &d->bus[bus_num]; + CMD646BAR *bar = &d->cmd646_bar[bus_num]; + + bar->bus = bus; + bar->pci_dev = d; + memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4); + memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8); +} + +static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, + unsigned size) { + BMDMAState *bm = opaque; + PCIIDEState *pci_dev = bm->pci_dev; uint32_t val; + if (size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + switch(addr & 3) { case 0: val = bm->cmd; @@ -100,31 +159,22 @@ static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm, return val; } -static uint32_t bmdma_readb_0(void *opaque, uint32_t addr) +static void bmdma_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[0]; + BMDMAState *bm = opaque; + PCIIDEState *pci_dev = bm->pci_dev; - return bmdma_readb_common(pci_dev, bm, addr); -} - -static uint32_t bmdma_readb_1(void *opaque, uint32_t addr) -{ - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[1]; - - return bmdma_readb_common(pci_dev, bm, addr); -} + if (size != 1) { + return; + } -static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm, - uint32_t addr, uint32_t val) -{ #ifdef DEBUG_IDE printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch(addr & 3) { case 0: - bmdma_cmd_writeb(bm, addr, val); + bmdma_cmd_writeb(bm, val); break; case 1: pci_dev->dev.config[MRDMODE] = @@ -143,42 +193,25 @@ static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm, } } -static void bmdma_writeb_0(void *opaque, uint32_t addr, uint32_t val) -{ - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[0]; - - bmdma_writeb_common(pci_dev, bm, addr, val); -} - -static void bmdma_writeb_1(void *opaque, uint32_t addr, uint32_t val) -{ - PCIIDEState *pci_dev = opaque; - BMDMAState *bm = &pci_dev->bmdma[1]; - - bmdma_writeb_common(pci_dev, bm, addr, val); -} +static MemoryRegionOps cmd646_bmdma_ops = { + .read = bmdma_read, + .write = bmdma_write, +}; -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void bmdma_setup_bar(PCIIDEState *d) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); + BMDMAState *bm; int i; + memory_region_init(&d->bmdma_bar, "cmd646-bmdma", 16); for(i = 0;i < 2; i++) { - BMDMAState *bm = &d->bmdma[i]; - - if (i == 0) { - register_ioport_write(addr, 4, 1, bmdma_writeb_0, d); - register_ioport_read(addr, 4, 1, bmdma_readb_0, d); - } else { - register_ioport_write(addr, 4, 1, bmdma_writeb_1, d); - register_ioport_read(addr, 4, 1, bmdma_readb_1, d); - } - - iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4); - ioport_register(&bm->addr_ioport); - addr += 8; + bm = &d->bmdma[i]; + memory_region_init_io(&bm->extra_io, &cmd646_bmdma_ops, bm, + "cmd646-bmdma-bus", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); + memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, + "cmd646-bmdma-ioport", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } @@ -226,25 +259,22 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) qemu_irq *irq; int i; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646); - - pci_conf[PCI_REVISION_ID] = 0x07; // IDE controller revision pci_conf[PCI_CLASS_PROG] = 0x8f; - pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE); - pci_conf[0x51] = 0x04; // enable IDE0 if (d->secondary) { /* XXX: if not enabled, really disable the seconday IDE controller */ pci_conf[0x51] |= 0x08; /* enable IDE1 */ } - pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map); - pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + setup_cmd646_bar(d, 0); + setup_cmd646_bar(d, 1); + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data); + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd); + pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data); + pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].cmd); + bmdma_setup_bar(d); + pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); /* TODO: RST# value should be 0 */ pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1 @@ -254,7 +284,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) ide_bus_new(&d->bus[i], &d->dev.qdev, i); ide_init2(&d->bus[i], irq[i]); - bmdma_init(&d->bus[i], &d->bmdma[i]); + bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, &d->bmdma[i].dma); @@ -265,6 +295,24 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) return 0; } +static int pci_cmd646_ide_exitfn(PCIDevice *dev) +{ + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_destroy(&d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + memory_region_destroy(&d->bmdma[i].addr_ioport); + memory_region_destroy(&d->cmd646_bar[i].cmd); + memory_region_destroy(&d->cmd646_bar[i].data); + } + memory_region_destroy(&d->bmdma_bar); + + return 0; +} + void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, int secondary_ide_enabled) { @@ -282,6 +330,11 @@ static PCIDeviceInfo cmd646_ide_info[] = { .qdev.name = "cmd646-ide", .qdev.size = sizeof(PCIIDEState), .init = pci_cmd646_ide_initfn, + .exit = pci_cmd646_ide_exitfn, + .vendor_id = PCI_VENDOR_ID_CMD, + .device_id = PCI_DEVICE_ID_CMD_646, + .revision = 0x07, // IDE controller revision + .class_id = PCI_CLASS_STORAGE_IDE, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/ide/core.c b/hw/ide/core.c index dd63664..93a1a68 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -25,42 +25,40 @@ #include #include #include -#include +#include #include "qemu-error.h" #include "qemu-timer.h" #include "sysemu.h" #include "dma.h" #include "blockdev.h" +#include "block_int.h" #include -static const int smart_attributes[][5] = { - /* id, flags, val, wrst, thrsh */ - { 0x01, 0x03, 0x64, 0x64, 0x06}, /* raw read */ - { 0x03, 0x03, 0x64, 0x64, 0x46}, /* spin up */ - { 0x04, 0x02, 0x64, 0x64, 0x14}, /* start stop count */ - { 0x05, 0x03, 0x64, 0x64, 0x36}, /* remapped sectors */ - { 0x00, 0x00, 0x00, 0x00, 0x00} +/* These values were based on a Seagate ST3500418AS but have been modified + to make more sense in QEMU */ +static const int smart_attributes[][12] = { + /* id, flags, hflags, val, wrst, raw (6 bytes), threshold */ + /* raw read error rate*/ + { 0x01, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06}, + /* spin up */ + { 0x03, 0x03, 0x00, 0x64, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* start stop count */ + { 0x04, 0x02, 0x00, 0x64, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14}, + /* remapped sectors */ + { 0x05, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24}, + /* power on hours */ + { 0x09, 0x03, 0x00, 0x64, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* power cycle count */ + { 0x0c, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* airflow-temperature-celsius */ + { 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32}, + /* end of list */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -/* XXX: DVDs that could fit on a CD will be reported as a CD */ -static inline int media_present(IDEState *s) -{ - return (s->nb_sectors > 0); -} - -static inline int media_is_dvd(IDEState *s) -{ - return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS); -} - -static inline int media_is_cd(IDEState *s) -{ - return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS); -} - -static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret); static int ide_handle_rw_error(IDEState *s, int error, int op); +static void ide_dummy_transfer_stop(IDEState *s); static void padstr(char *str, const char *src, int len) { @@ -74,17 +72,6 @@ static void padstr(char *str, const char *src, int len) } } -static void padstr8(uint8_t *buf, int buf_size, const char *src) -{ - int i; - for(i = 0; i < buf_size; i++) { - if (*src) - buf[i] = *src++; - else - buf[i] = ' '; - } -} - static void put_le16(uint16_t *p, unsigned int v) { *p = cpu_to_le16(v); @@ -94,7 +81,7 @@ static void ide_identify(IDEState *s) { uint16_t *p; unsigned int oldsize; - IDEDevice *dev; + IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master; if (s->identify_set) { memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data)); @@ -140,6 +127,9 @@ static void ide_identify(IDEState *s) put_le16(p + 66, 120); put_le16(p + 67, 120); put_le16(p + 68, 120); + if (dev && dev->conf.discard_granularity) { + put_le16(p + 69, (1 << 14)); /* determinate TRIM behavior */ + } if (s->ncq_queues) { put_le16(p + 75, s->ncq_queues - 1); @@ -170,9 +160,12 @@ static void ide_identify(IDEState *s) put_le16(p + 101, s->nb_sectors >> 16); put_le16(p + 102, s->nb_sectors >> 32); put_le16(p + 103, s->nb_sectors >> 48); - dev = s->unit ? s->bus->slave : s->bus->master; + if (dev && dev->conf.physical_block_size) put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf)); + if (dev && dev->conf.discard_granularity) { + put_le16(p + 169, 1); /* TRIM support */ + } memcpy(s->identify_data, p, sizeof(s->identify_data)); s->identify_set = 1; @@ -315,6 +308,74 @@ static void ide_set_signature(IDEState *s) } } +typedef struct TrimAIOCB { + BlockDriverAIOCB common; + QEMUBH *bh; + int ret; +} TrimAIOCB; + +static void trim_aio_cancel(BlockDriverAIOCB *acb) +{ + TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common); + + qemu_bh_delete(iocb->bh); + iocb->bh = NULL; + qemu_aio_release(iocb); +} + +static AIOPool trim_aio_pool = { + .aiocb_size = sizeof(TrimAIOCB), + .cancel = trim_aio_cancel, +}; + +static void ide_trim_bh_cb(void *opaque) +{ + TrimAIOCB *iocb = opaque; + + iocb->common.cb(iocb->common.opaque, iocb->ret); + + qemu_bh_delete(iocb->bh); + iocb->bh = NULL; + + qemu_aio_release(iocb); +} + +BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + TrimAIOCB *iocb; + int i, j, ret; + + iocb = qemu_aio_get(&trim_aio_pool, bs, cb, opaque); + iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb); + iocb->ret = 0; + + for (j = 0; j < qiov->niov; j++) { + uint64_t *buffer = qiov->iov[j].iov_base; + + for (i = 0; i < qiov->iov[j].iov_len / 8; i++) { + /* 6-byte LBA + 2-byte range per entry */ + uint64_t entry = le64_to_cpu(buffer[i]); + uint64_t sector = entry & 0x0000ffffffffffffULL; + uint16_t count = entry >> 48; + + if (count == 0) { + break; + } + + ret = bdrv_discard(bs, sector, count); + if (!iocb->ret) { + iocb->ret = ret; + } + } + } + + qemu_bh_schedule(iocb->bh); + + return &iocb->common; +} + static inline void ide_abort_command(IDEState *s) { s->status = READY_STAT | ERR_STAT; @@ -322,8 +383,8 @@ static inline void ide_abort_command(IDEState *s) } /* prepare data transfer and tell what to do after */ -static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, - EndTransferFunc *end_transfer_func) +void ide_transfer_start(IDEState *s, uint8_t *buf, int size, + EndTransferFunc *end_transfer_func) { s->end_transfer_func = end_transfer_func; s->data_ptr = buf; @@ -334,7 +395,7 @@ static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, s->bus->dma->ops->start_transfer(s->bus->dma); } -static void ide_transfer_stop(IDEState *s) +void ide_transfer_stop(IDEState *s) { s->end_transfer_func = ide_transfer_stop; s->data_ptr = s->io_buffer; @@ -414,7 +475,10 @@ void ide_sector_read(IDEState *s) #endif if (n > s->req_nb_sectors) n = s->req_nb_sectors; + + bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); ret = bdrv_read(s->bs, sector_num, s->io_buffer, n); + bdrv_acct_done(s->bs, &s->acct); if (ret != 0) { if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ)) @@ -434,7 +498,7 @@ static void dma_buf_commit(IDEState *s, int is_write) qemu_sglist_destroy(&s->sg); } -static void ide_set_inactive(IDEState *s) +void ide_set_inactive(IDEState *s) { s->bus->dma->aiocb = NULL; s->bus->dma->ops->set_inactive(s->bus->dma); @@ -446,7 +510,6 @@ void ide_dma_error(IDEState *s) s->error = ABRT_ERR; s->status = READY_STAT | ERR_STAT; ide_set_inactive(s); - s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT); ide_set_irq(s->bus); } @@ -463,9 +526,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC) || action == BLOCK_ERR_STOP_ANY) { s->bus->dma->ops->set_unit(s->bus->dma, s->unit); - s->bus->dma->ops->add_status(s->bus->dma, op); + s->bus->error_status = op; bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); - vm_stop(0); + vm_stop(RUN_STATE_IO_ERROR); + bdrv_iostatus_set_err(s->bs, error); } else { if (op & BM_STATUS_DMA_RETRY) { dma_buf_commit(s, 0); @@ -489,8 +553,11 @@ handle_rw_error: if (ret < 0) { int op = BM_STATUS_DMA_RETRY; - if (s->is_read) + if (s->dma_cmd == IDE_DMA_READ) op |= BM_STATUS_RETRY_READ; + else if (s->dma_cmd == IDE_DMA_TRIM) + op |= BM_STATUS_RETRY_TRIM; + if (ide_handle_rw_error(s, -ret, op)) { return; } @@ -499,7 +566,7 @@ handle_rw_error: n = s->io_buffer_size >> 9; sector_num = ide_get_sector(s); if (n > 0) { - dma_buf_commit(s, s->is_read); + dma_buf_commit(s, ide_cmd_is_read(s)); sector_num += n; ide_set_sector(s, sector_num); s->nsector -= n; @@ -516,20 +583,30 @@ handle_rw_error: n = s->nsector; s->io_buffer_index = 0; s->io_buffer_size = n * 512; - if (s->bus->dma->ops->prepare_buf(s->bus->dma, s->is_read) == 0) + if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) { + /* The PRDs were too short. Reset the Active bit, but don't raise an + * interrupt. */ goto eot; + } #ifdef DEBUG_AIO - printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, is_read=%d\n", - sector_num, n, s->is_read); + printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n", + sector_num, n, s->dma_cmd); #endif - if (s->is_read) { + switch (s->dma_cmd) { + case IDE_DMA_READ: s->bus->dma->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, ide_dma_cb, s); - } else { + break; + case IDE_DMA_WRITE: s->bus->dma->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, ide_dma_cb, s); + break; + case IDE_DMA_TRIM: + s->bus->dma->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, + ide_issue_trim, ide_dma_cb, s, true); + break; } if (!s->bus->dma->aiocb) { @@ -539,16 +616,32 @@ handle_rw_error: return; eot: - s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT); - ide_set_inactive(s); + if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { + bdrv_acct_done(s->bs, &s->acct); + } + ide_set_inactive(s); } -static void ide_sector_start_dma(IDEState *s, int is_read) +static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd) { s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; s->io_buffer_index = 0; s->io_buffer_size = 0; - s->is_read = is_read; + s->dma_cmd = dma_cmd; + + switch (dma_cmd) { + case IDE_DMA_READ: + bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE, + BDRV_ACCT_READ); + break; + case IDE_DMA_WRITE: + bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE, + BDRV_ACCT_WRITE); + break; + default: + break; + } + s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb); } @@ -571,7 +664,10 @@ void ide_sector_write(IDEState *s) n = s->nsector; if (n > s->req_nb_sectors) n = s->req_nb_sectors; + + bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); + bdrv_acct_done(s->bs, &s->acct); if (ret != 0) { if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY)) @@ -598,44 +694,12 @@ void ide_sector_write(IDEState *s) option _only_ to install Windows 2000. You must disable it for normal use. */ qemu_mod_timer(s->sector_write_timer, - qemu_get_clock(vm_clock) + (get_ticks_per_sec() / 1000)); + qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 1000)); } else { ide_set_irq(s->bus); } } -void ide_atapi_cmd_ok(IDEState *s) -{ - s->error = 0; - s->status = READY_STAT | SEEK_STAT; - s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; - ide_set_irq(s->bus); -} - -void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc) -{ -#ifdef DEBUG_IDE_ATAPI - printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc); -#endif - s->error = sense_key << 4; - s->status = READY_STAT | ERR_STAT; - s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; - s->sense_key = sense_key; - s->asc = asc; - ide_set_irq(s->bus); -} - -static void ide_atapi_cmd_check_status(IDEState *s) -{ -#ifdef DEBUG_IDE_ATAPI - printf("atapi_cmd_check_status\n"); -#endif - s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4); - s->status = ERR_STAT; - s->nsector = 0; - ide_set_irq(s->bus); -} - static void ide_flush_cb(void *opaque, int ret) { IDEState *s = opaque; @@ -647,6 +711,7 @@ static void ide_flush_cb(void *opaque, int ret) } } + bdrv_acct_done(s->bs, &s->acct); s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); } @@ -660,876 +725,13 @@ void ide_flush_cache(IDEState *s) return; } + bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH); acb = bdrv_aio_flush(s->bs, ide_flush_cb, s); if (acb == NULL) { ide_flush_cb(s, -EIO); } } -static inline void cpu_to_ube16(uint8_t *buf, int val) -{ - buf[0] = val >> 8; - buf[1] = val & 0xff; -} - -static inline void cpu_to_ube32(uint8_t *buf, unsigned int val) -{ - buf[0] = val >> 24; - buf[1] = val >> 16; - buf[2] = val >> 8; - buf[3] = val & 0xff; -} - -static inline int ube16_to_cpu(const uint8_t *buf) -{ - return (buf[0] << 8) | buf[1]; -} - -static inline int ube32_to_cpu(const uint8_t *buf) -{ - return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; -} - -static void lba_to_msf(uint8_t *buf, int lba) -{ - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; -} - -static void cd_data_to_raw(uint8_t *buf, int lba) -{ - /* sync bytes */ - buf[0] = 0x00; - memset(buf + 1, 0xff, 10); - buf[11] = 0x00; - buf += 12; - /* MSF */ - lba_to_msf(buf, lba); - buf[3] = 0x01; /* mode 1 data */ - buf += 4; - /* data */ - buf += 2048; - /* XXX: ECC not computed */ - memset(buf, 0, 288); -} - -static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, - int sector_size) -{ - int ret; - - switch(sector_size) { - case 2048: - ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4); - break; - case 2352: - ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4); - if (ret < 0) - return ret; - cd_data_to_raw(buf, lba); - break; - default: - ret = -EIO; - break; - } - return ret; -} - -void ide_atapi_io_error(IDEState *s, int ret) -{ - /* XXX: handle more errors */ - if (ret == -ENOMEDIUM) { - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - } else { - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_LOGICAL_BLOCK_OOR); - } -} - -/* The whole ATAPI transfer logic is handled in this function */ -static void ide_atapi_cmd_reply_end(IDEState *s) -{ - int byte_count_limit, size, ret; -#ifdef DEBUG_IDE_ATAPI - printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", - s->packet_transfer_size, - s->elementary_transfer_size, - s->io_buffer_index); -#endif - if (s->packet_transfer_size <= 0) { - /* end of transfer */ - ide_transfer_stop(s); - s->status = READY_STAT | SEEK_STAT; - s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; - ide_set_irq(s->bus); -#ifdef DEBUG_IDE_ATAPI - printf("status=0x%x\n", s->status); -#endif - } else { - /* see if a new sector must be read */ - if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) { - ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size); - if (ret < 0) { - ide_transfer_stop(s); - ide_atapi_io_error(s, ret); - return; - } - s->lba++; - s->io_buffer_index = 0; - } - if (s->elementary_transfer_size > 0) { - /* there are some data left to transmit in this elementary - transfer */ - size = s->cd_sector_size - s->io_buffer_index; - if (size > s->elementary_transfer_size) - size = s->elementary_transfer_size; - s->packet_transfer_size -= size; - s->elementary_transfer_size -= size; - s->io_buffer_index += size; - ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size, - size, ide_atapi_cmd_reply_end); - } else { - /* a new transfer is needed */ - s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO; - byte_count_limit = s->lcyl | (s->hcyl << 8); -#ifdef DEBUG_IDE_ATAPI - printf("byte_count_limit=%d\n", byte_count_limit); -#endif - if (byte_count_limit == 0xffff) - byte_count_limit--; - size = s->packet_transfer_size; - if (size > byte_count_limit) { - /* byte count limit must be even if this case */ - if (byte_count_limit & 1) - byte_count_limit--; - size = byte_count_limit; - } - s->lcyl = size; - s->hcyl = size >> 8; - s->elementary_transfer_size = size; - /* we cannot transmit more than one sector at a time */ - if (s->lba != -1) { - if (size > (s->cd_sector_size - s->io_buffer_index)) - size = (s->cd_sector_size - s->io_buffer_index); - } - s->packet_transfer_size -= size; - s->elementary_transfer_size -= size; - s->io_buffer_index += size; - ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size, - size, ide_atapi_cmd_reply_end); - ide_set_irq(s->bus); -#ifdef DEBUG_IDE_ATAPI - printf("status=0x%x\n", s->status); -#endif - } - } -} - -/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */ -static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) -{ - if (size > max_size) - size = max_size; - s->lba = -1; /* no sector read */ - s->packet_transfer_size = size; - s->io_buffer_size = size; /* dma: send the reply data as one chunk */ - s->elementary_transfer_size = 0; - s->io_buffer_index = 0; - - if (s->atapi_dma) { - s->status = READY_STAT | SEEK_STAT | DRQ_STAT; - s->bus->dma->ops->start_dma(s->bus->dma, s, - ide_atapi_cmd_read_dma_cb); - } else { - s->status = READY_STAT | SEEK_STAT; - ide_atapi_cmd_reply_end(s); - } -} - -/* start a CD-CDROM read command */ -static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors, - int sector_size) -{ - s->lba = lba; - s->packet_transfer_size = nb_sectors * sector_size; - s->elementary_transfer_size = 0; - s->io_buffer_index = sector_size; - s->cd_sector_size = sector_size; - - s->status = READY_STAT | SEEK_STAT; - ide_atapi_cmd_reply_end(s); -} - -/* ATAPI DMA support */ - -/* XXX: handle read errors */ -static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) -{ - IDEState *s = opaque; - int data_offset, n; - - if (ret < 0) { - ide_atapi_io_error(s, ret); - goto eot; - } - - if (s->io_buffer_size > 0) { - /* - * For a cdrom read sector command (s->lba != -1), - * adjust the lba for the next s->io_buffer_size chunk - * and dma the current chunk. - * For a command != read (s->lba == -1), just transfer - * the reply data. - */ - if (s->lba != -1) { - if (s->cd_sector_size == 2352) { - n = 1; - cd_data_to_raw(s->io_buffer, s->lba); - } else { - n = s->io_buffer_size >> 11; - } - s->lba += n; - } - s->packet_transfer_size -= s->io_buffer_size; - if (s->bus->dma->ops->rw_buf(s->bus->dma, 1) == 0) - goto eot; - } - - if (s->packet_transfer_size <= 0) { - s->status = READY_STAT | SEEK_STAT; - s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; - ide_set_irq(s->bus); - eot: - s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT); - ide_set_inactive(s); - return; - } - - s->io_buffer_index = 0; - if (s->cd_sector_size == 2352) { - n = 1; - s->io_buffer_size = s->cd_sector_size; - data_offset = 16; - } else { - n = s->packet_transfer_size >> 11; - if (n > (IDE_DMA_BUF_SECTORS / 4)) - n = (IDE_DMA_BUF_SECTORS / 4); - s->io_buffer_size = n * 2048; - data_offset = 0; - } -#ifdef DEBUG_AIO - printf("aio_read_cd: lba=%u n=%d\n", s->lba, n); -#endif - s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset); - s->bus->dma->iov.iov_len = n * 4 * 512; - qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1); - s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2, - &s->bus->dma->qiov, n * 4, - ide_atapi_cmd_read_dma_cb, s); - if (!s->bus->dma->aiocb) { - /* Note: media not present is the most likely case */ - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - goto eot; - } -} - -/* start a CD-CDROM read command with DMA */ -/* XXX: test if DMA is available */ -static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors, - int sector_size) -{ - s->lba = lba; - s->packet_transfer_size = nb_sectors * sector_size; - s->io_buffer_index = 0; - s->io_buffer_size = 0; - s->cd_sector_size = sector_size; - - /* XXX: check if BUSY_STAT should be set */ - s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; - s->bus->dma->ops->start_dma(s->bus->dma, s, - ide_atapi_cmd_read_dma_cb); -} - -static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, - int sector_size) -{ -#ifdef DEBUG_IDE_ATAPI - printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio", - lba, nb_sectors); -#endif - if (s->atapi_dma) { - ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size); - } else { - ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size); - } -} - -static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index, - uint16_t profile) -{ - uint8_t *buf_profile = buf + 12; /* start of profiles */ - - buf_profile += ((*index) * 4); /* start of indexed profile */ - cpu_to_ube16 (buf_profile, profile); - buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7])); - - /* each profile adds 4 bytes to the response */ - (*index)++; - buf[11] += 4; /* Additional Length */ - - return 4; -} - -static int ide_dvd_read_structure(IDEState *s, int format, - const uint8_t *packet, uint8_t *buf) -{ - switch (format) { - case 0x0: /* Physical format information */ - { - int layer = packet[6]; - uint64_t total_sectors; - - if (layer != 0) - return -ASC_INV_FIELD_IN_CMD_PACKET; - - bdrv_get_geometry(s->bs, &total_sectors); - total_sectors >>= 2; - if (total_sectors == 0) - return -ASC_MEDIUM_NOT_PRESENT; - - buf[4] = 1; /* DVD-ROM, part version 1 */ - buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ - buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ - buf[7] = 0; /* default densities */ - - /* FIXME: 0x30000 per spec? */ - cpu_to_ube32(buf + 8, 0); /* start sector */ - cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */ - cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */ - - /* Size of buffer, not including 2 byte size field */ - cpu_to_be16wu((uint16_t *)buf, 2048 + 2); - - /* 2k data + 4 byte header */ - return (2048 + 4); - } - - case 0x01: /* DVD copyright information */ - buf[4] = 0; /* no copyright data */ - buf[5] = 0; /* no region restrictions */ - - /* Size of buffer, not including 2 byte size field */ - cpu_to_be16wu((uint16_t *)buf, 4 + 2); - - /* 4 byte header + 4 byte data */ - return (4 + 4); - - case 0x03: /* BCA information - invalid field for no BCA info */ - return -ASC_INV_FIELD_IN_CMD_PACKET; - - case 0x04: /* DVD disc manufacturing information */ - /* Size of buffer, not including 2 byte size field */ - cpu_to_be16wu((uint16_t *)buf, 2048 + 2); - - /* 2k data + 4 byte header */ - return (2048 + 4); - - case 0xff: - /* - * This lists all the command capabilities above. Add new ones - * in order and update the length and buffer return values. - */ - - buf[4] = 0x00; /* Physical format */ - buf[5] = 0x40; /* Not writable, is readable */ - cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4); - - buf[8] = 0x01; /* Copyright info */ - buf[9] = 0x40; /* Not writable, is readable */ - cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4); - - buf[12] = 0x03; /* BCA info */ - buf[13] = 0x40; /* Not writable, is readable */ - cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4); - - buf[16] = 0x04; /* Manufacturing info */ - buf[17] = 0x40; /* Not writable, is readable */ - cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4); - - /* Size of buffer, not including 2 byte size field */ - cpu_to_be16wu((uint16_t *)buf, 16 + 2); - - /* data written + 4 byte header */ - return (16 + 4); - - default: /* TODO: formats beyond DVD-ROM requires */ - return -ASC_INV_FIELD_IN_CMD_PACKET; - } -} - -static void ide_atapi_cmd(IDEState *s) -{ - const uint8_t *packet; - uint8_t *buf; - int max_len; - - packet = s->io_buffer; - buf = s->io_buffer; -#ifdef DEBUG_IDE_ATAPI - { - int i; - printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8)); - for(i = 0; i < ATAPI_PACKET_SIZE; i++) { - printf(" %02x", packet[i]); - } - printf("\n"); - } -#endif - /* If there's a UNIT_ATTENTION condition pending, only - REQUEST_SENSE and INQUIRY commands are allowed to complete. */ - if (s->sense_key == SENSE_UNIT_ATTENTION && - s->io_buffer[0] != GPCMD_REQUEST_SENSE && - s->io_buffer[0] != GPCMD_INQUIRY) { - ide_atapi_cmd_check_status(s); - return; - } - switch(s->io_buffer[0]) { - case GPCMD_TEST_UNIT_READY: - if (bdrv_is_inserted(s->bs) && !s->cdrom_changed) { - ide_atapi_cmd_ok(s); - } else { - s->cdrom_changed = 0; - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - } - break; - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - { - int action, code; - if (packet[0] == GPCMD_MODE_SENSE_10) - max_len = ube16_to_cpu(packet + 7); - else - max_len = packet[4]; - action = packet[2] >> 6; - code = packet[2] & 0x3f; - switch(action) { - case 0: /* current values */ - switch(code) { - case GPMODE_R_W_ERROR_PAGE: /* error recovery */ - cpu_to_ube16(&buf[0], 16 + 6); - buf[2] = 0x70; - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - - buf[8] = 0x01; - buf[9] = 0x06; - buf[10] = 0x00; - buf[11] = 0x05; - buf[12] = 0x00; - buf[13] = 0x00; - buf[14] = 0x00; - buf[15] = 0x00; - ide_atapi_cmd_reply(s, 16, max_len); - break; - case GPMODE_AUDIO_CTL_PAGE: - cpu_to_ube16(&buf[0], 24 + 6); - buf[2] = 0x70; - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - - /* Fill with CDROM audio volume */ - buf[17] = 0; - buf[19] = 0; - buf[21] = 0; - buf[23] = 0; - - ide_atapi_cmd_reply(s, 24, max_len); - break; - case GPMODE_CAPABILITIES_PAGE: - cpu_to_ube16(&buf[0], 28 + 6); - buf[2] = 0x70; - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - buf[6] = 0; - buf[7] = 0; - - buf[8] = 0x2a; - buf[9] = 0x12; - buf[10] = 0x00; - buf[11] = 0x00; - - /* Claim PLAY_AUDIO capability (0x01) since some Linux - code checks for this to automount media. */ - buf[12] = 0x71; - buf[13] = 3 << 5; - buf[14] = (1 << 0) | (1 << 3) | (1 << 5); - if (bdrv_is_locked(s->bs)) - buf[6] |= 1 << 1; - buf[15] = 0x00; - cpu_to_ube16(&buf[16], 706); - buf[18] = 0; - buf[19] = 2; - cpu_to_ube16(&buf[20], 512); - cpu_to_ube16(&buf[22], 706); - buf[24] = 0; - buf[25] = 0; - buf[26] = 0; - buf[27] = 0; - ide_atapi_cmd_reply(s, 28, max_len); - break; - default: - goto error_cmd; - } - break; - case 1: /* changeable values */ - goto error_cmd; - case 2: /* default values */ - goto error_cmd; - default: - case 3: /* saved values */ - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_SAVING_PARAMETERS_NOT_SUPPORTED); - break; - } - } - break; - case GPCMD_REQUEST_SENSE: - max_len = packet[4]; - memset(buf, 0, 18); - buf[0] = 0x70 | (1 << 7); - buf[2] = s->sense_key; - buf[7] = 10; - buf[12] = s->asc; - if (s->sense_key == SENSE_UNIT_ATTENTION) - s->sense_key = SENSE_NONE; - ide_atapi_cmd_reply(s, 18, max_len); - break; - case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - if (bdrv_is_inserted(s->bs)) { - bdrv_set_locked(s->bs, packet[4] & 1); - ide_atapi_cmd_ok(s); - } else { - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - } - break; - case GPCMD_READ_10: - case GPCMD_READ_12: - { - int nb_sectors, lba; - - if (packet[0] == GPCMD_READ_10) - nb_sectors = ube16_to_cpu(packet + 7); - else - nb_sectors = ube32_to_cpu(packet + 6); - lba = ube32_to_cpu(packet + 2); - if (nb_sectors == 0) { - ide_atapi_cmd_ok(s); - break; - } - ide_atapi_cmd_read(s, lba, nb_sectors, 2048); - } - break; - case GPCMD_READ_CD: - { - int nb_sectors, lba, transfer_request; - - nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8]; - lba = ube32_to_cpu(packet + 2); - if (nb_sectors == 0) { - ide_atapi_cmd_ok(s); - break; - } - transfer_request = packet[9]; - switch(transfer_request & 0xf8) { - case 0x00: - /* nothing */ - ide_atapi_cmd_ok(s); - break; - case 0x10: - /* normal read */ - ide_atapi_cmd_read(s, lba, nb_sectors, 2048); - break; - case 0xf8: - /* read all data */ - ide_atapi_cmd_read(s, lba, nb_sectors, 2352); - break; - default: - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - break; - } - } - break; - case GPCMD_SEEK: - { - unsigned int lba; - uint64_t total_sectors; - - bdrv_get_geometry(s->bs, &total_sectors); - total_sectors >>= 2; - if (total_sectors == 0) { - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - break; - } - lba = ube32_to_cpu(packet + 2); - if (lba >= total_sectors) { - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_LOGICAL_BLOCK_OOR); - break; - } - ide_atapi_cmd_ok(s); - } - break; - case GPCMD_START_STOP_UNIT: - { - int start, eject, err = 0; - start = packet[4] & 1; - eject = (packet[4] >> 1) & 1; - - if (eject) { - err = bdrv_eject(s->bs, !start); - } - - switch (err) { - case 0: - ide_atapi_cmd_ok(s); - break; - case -EBUSY: - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIA_REMOVAL_PREVENTED); - break; - default: - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - break; - } - } - break; - case GPCMD_MECHANISM_STATUS: - { - max_len = ube16_to_cpu(packet + 8); - cpu_to_ube16(buf, 0); - /* no current LBA */ - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = 1; - cpu_to_ube16(buf + 6, 0); - ide_atapi_cmd_reply(s, 8, max_len); - } - break; - case GPCMD_READ_TOC_PMA_ATIP: - { - int format, msf, start_track, len; - uint64_t total_sectors; - - bdrv_get_geometry(s->bs, &total_sectors); - total_sectors >>= 2; - if (total_sectors == 0) { - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - break; - } - max_len = ube16_to_cpu(packet + 7); - format = packet[9] >> 6; - msf = (packet[1] >> 1) & 1; - start_track = packet[6]; - switch(format) { - case 0: - len = cdrom_read_toc(total_sectors, buf, msf, start_track); - if (len < 0) - goto error_cmd; - ide_atapi_cmd_reply(s, len, max_len); - break; - case 1: - /* multi session : only a single session defined */ - memset(buf, 0, 12); - buf[1] = 0x0a; - buf[2] = 0x01; - buf[3] = 0x01; - ide_atapi_cmd_reply(s, 12, max_len); - break; - case 2: - len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track); - if (len < 0) - goto error_cmd; - ide_atapi_cmd_reply(s, len, max_len); - break; - default: - error_cmd: - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - break; - } - } - break; - case GPCMD_READ_CDVD_CAPACITY: - { - uint64_t total_sectors; - - bdrv_get_geometry(s->bs, &total_sectors); - total_sectors >>= 2; - if (total_sectors == 0) { - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - break; - } - /* NOTE: it is really the number of sectors minus 1 */ - cpu_to_ube32(buf, total_sectors - 1); - cpu_to_ube32(buf + 4, 2048); - ide_atapi_cmd_reply(s, 8, 8); - } - break; - case GPCMD_READ_DVD_STRUCTURE: - { - int media = packet[1]; - int format = packet[7]; - int ret; - - max_len = ube16_to_cpu(packet + 8); - - if (format < 0xff) { - if (media_is_cd(s)) { - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_INCOMPATIBLE_FORMAT); - break; - } else if (!media_present(s)) { - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - break; - } - } - - memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ? - IDE_DMA_BUF_SECTORS * 512 + 4 : max_len); - - switch (format) { - case 0x00 ... 0x7f: - case 0xff: - if (media == 0) { - ret = ide_dvd_read_structure(s, format, packet, buf); - - if (ret < 0) - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret); - else - ide_atapi_cmd_reply(s, ret, max_len); - - break; - } - /* TODO: BD support, fall through for now */ - - /* Generic disk structures */ - case 0x80: /* TODO: AACS volume identifier */ - case 0x81: /* TODO: AACS media serial number */ - case 0x82: /* TODO: AACS media identifier */ - case 0x83: /* TODO: AACS media key block */ - case 0x90: /* TODO: List of recognized format layers */ - case 0xc0: /* TODO: Write protection status */ - default: - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - break; - } - } - break; - case GPCMD_SET_SPEED: - ide_atapi_cmd_ok(s); - break; - case GPCMD_INQUIRY: - max_len = packet[4]; - buf[0] = 0x05; /* CD-ROM */ - buf[1] = 0x80; /* removable */ - buf[2] = 0x00; /* ISO */ - buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */ - buf[4] = 31; /* additional length */ - buf[5] = 0; /* reserved */ - buf[6] = 0; /* reserved */ - buf[7] = 0; /* reserved */ - padstr8(buf + 8, 8, "QEMU"); - padstr8(buf + 16, 16, "QEMU DVD-ROM"); - padstr8(buf + 32, 4, s->version); - ide_atapi_cmd_reply(s, 36, max_len); - break; - case GPCMD_GET_CONFIGURATION: - { - uint32_t len; - uint8_t index = 0; - - /* only feature 0 is supported */ - if (packet[2] != 0 || packet[3] != 0) { - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - break; - } - - /* XXX: could result in alignment problems in some architectures */ - max_len = ube16_to_cpu(packet + 7); - - /* - * XXX: avoid overflow for io_buffer if max_len is bigger than - * the size of that buffer (dimensioned to max number of - * sectors to transfer at once) - * - * Only a problem if the feature/profiles grow. - */ - if (max_len > 512) /* XXX: assume 1 sector */ - max_len = 512; - - memset(buf, 0, max_len); - /* - * the number of sectors from the media tells us which profile - * to use as current. 0 means there is no media - */ - if (media_is_dvd(s)) - cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM); - else if (media_is_cd(s)) - cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM); - - buf[10] = 0x02 | 0x01; /* persistent and current */ - len = 12; /* headers: 8 + 4 */ - len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM); - len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM); - cpu_to_ube32(buf, len - 4); /* data length */ - - ide_atapi_cmd_reply(s, len, max_len); - break; - } - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - max_len = ube16_to_cpu(packet + 7); - - if (packet[1] & 0x01) { /* polling */ - /* We don't support any event class (yet). */ - cpu_to_ube16(buf, 0x00); /* No event descriptor returned */ - buf[2] = 0x80; /* No Event Available (NEA) */ - buf[3] = 0x00; /* Empty supported event classes */ - ide_atapi_cmd_reply(s, 4, max_len); - } else { /* asynchronous mode */ - /* Only polling is supported, asynchronous mode is not. */ - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_INV_FIELD_IN_CMD_PACKET); - } - break; - default: - ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, - ASC_ILLEGAL_OPCODE); - break; - } -} - static void ide_cfata_metadata_inquiry(IDEState *s) { uint16_t *p; @@ -1584,21 +786,36 @@ static void ide_cfata_metadata_write(IDEState *s) } /* called when the inserted state of the media has changed */ -static void cdrom_change_cb(void *opaque, int reason) +static void ide_cd_change_cb(void *opaque, bool load) { IDEState *s = opaque; uint64_t nb_sectors; - if (!(reason & CHANGE_MEDIA)) { - return; - } - + s->tray_open = !load; bdrv_get_geometry(s->bs, &nb_sectors); s->nb_sectors = nb_sectors; - s->sense_key = SENSE_UNIT_ATTENTION; - s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED; + /* + * First indicate to the guest that a CD has been removed. That's + * done on the next command the guest sends us. + * + * Then we set UNIT_ATTENTION, by which the guest will + * detect a new CD in the drive. See ide_atapi_cmd() for details. + */ s->cdrom_changed = 1; + s->events.new_media = true; + s->events.eject_request = false; + ide_set_irq(s->bus); +} + +static void ide_cd_eject_request_cb(void *opaque, bool force) +{ + IDEState *s = opaque; + + s->events.eject_request = true; + if (force) { + s->tray_locked = false; + } ide_set_irq(s->bus); } @@ -1700,6 +917,78 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } +#define HD_OK (1u << IDE_HD) +#define CD_OK (1u << IDE_CD) +#define CFA_OK (1u << IDE_CFATA) +#define HD_CFA_OK (HD_OK | CFA_OK) +#define ALL_OK (HD_OK | CD_OK | CFA_OK) + +/* See ACS-2 T13/2015-D Table B.2 Command codes */ +static const uint8_t ide_cmd_table[0x100] = { + /* NOP not implemented, mandatory for CD */ + [CFA_REQ_EXT_ERROR_CODE] = CFA_OK, + [WIN_DSM] = ALL_OK, + [WIN_DEVICE_RESET] = CD_OK, + [WIN_RECAL] = HD_CFA_OK, + [WIN_READ] = ALL_OK, + [WIN_READ_ONCE] = ALL_OK, + [WIN_READ_EXT] = HD_CFA_OK, + [WIN_READDMA_EXT] = HD_CFA_OK, + [WIN_READ_NATIVE_MAX_EXT] = HD_CFA_OK, + [WIN_MULTREAD_EXT] = HD_CFA_OK, + [WIN_WRITE] = HD_CFA_OK, + [WIN_WRITE_ONCE] = HD_CFA_OK, + [WIN_WRITE_EXT] = HD_CFA_OK, + [WIN_WRITEDMA_EXT] = HD_CFA_OK, + [CFA_WRITE_SECT_WO_ERASE] = CFA_OK, + [WIN_MULTWRITE_EXT] = HD_CFA_OK, + [WIN_WRITE_VERIFY] = HD_CFA_OK, + [WIN_VERIFY] = HD_CFA_OK, + [WIN_VERIFY_ONCE] = HD_CFA_OK, + [WIN_VERIFY_EXT] = HD_CFA_OK, + [WIN_SEEK] = HD_CFA_OK, + [CFA_TRANSLATE_SECTOR] = CFA_OK, + [WIN_DIAGNOSE] = ALL_OK, + [WIN_SPECIFY] = HD_CFA_OK, + [WIN_STANDBYNOW2] = ALL_OK, + [WIN_IDLEIMMEDIATE2] = ALL_OK, + [WIN_STANDBY2] = ALL_OK, + [WIN_SETIDLE2] = ALL_OK, + [WIN_CHECKPOWERMODE2] = ALL_OK, + [WIN_SLEEPNOW2] = ALL_OK, + [WIN_PACKETCMD] = CD_OK, + [WIN_PIDENTIFY] = CD_OK, + [WIN_SMART] = HD_CFA_OK, + [CFA_ACCESS_METADATA_STORAGE] = CFA_OK, + [CFA_ERASE_SECTORS] = CFA_OK, + [WIN_MULTREAD] = HD_CFA_OK, + [WIN_MULTWRITE] = HD_CFA_OK, + [WIN_SETMULT] = HD_CFA_OK, + [WIN_READDMA] = HD_CFA_OK, + [WIN_READDMA_ONCE] = HD_CFA_OK, + [WIN_WRITEDMA] = HD_CFA_OK, + [WIN_WRITEDMA_ONCE] = HD_CFA_OK, + [CFA_WRITE_MULTI_WO_ERASE] = CFA_OK, + [WIN_STANDBYNOW1] = ALL_OK, + [WIN_IDLEIMMEDIATE] = ALL_OK, + [WIN_STANDBY] = ALL_OK, + [WIN_SETIDLE1] = ALL_OK, + [WIN_CHECKPOWERMODE1] = ALL_OK, + [WIN_SLEEPNOW1] = ALL_OK, + [WIN_FLUSH_CACHE] = ALL_OK, + [WIN_FLUSH_CACHE_EXT] = HD_CFA_OK, + [WIN_IDENTIFY] = ALL_OK, + [WIN_SETFEATURES] = ALL_OK, + [IBM_SENSE_CONDITION] = CFA_OK, + [CFA_WEAR_LEVEL] = CFA_OK, + [WIN_READ_NATIVE_MAX] = ALL_OK, +}; + +static bool ide_cmd_permitted(IDEState *s, uint32_t cmd) +{ + return cmd < ARRAY_SIZE(ide_cmd_table) + && (ide_cmd_table[cmd] & (1u << s->drive_kind)); +} void ide_exec_cmd(IDEBus *bus, uint32_t val) { @@ -1719,7 +1008,23 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET) return; + if (!ide_cmd_permitted(s, val)) { + goto abort_cmd; + } + switch(val) { + case WIN_DSM: + switch (s->feature) { + case DSM_TRIM: + if (!s->bs) { + goto abort_cmd; + } + ide_sector_start_dma(s, IDE_DMA_TRIM); + break; + default: + goto abort_cmd; + } + break; case WIN_IDENTIFY: if (s->bs && s->drive_kind != IDE_CD) { if (s->drive_kind != IDE_CFATA) @@ -1766,17 +1071,19 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); break; - case WIN_READ_EXT: + case WIN_READ_EXT: lba48 = 1; case WIN_READ: case WIN_READ_ONCE: - if (!s->bs) + if (s->drive_kind == IDE_CD) { + ide_set_signature(s); /* odd, but ATA4 8.27.5.2 requires it */ goto abort_cmd; + } ide_cmd_lba48_transform(s, lba48); s->req_nb_sectors = 1; ide_sector_read(s); break; - case WIN_WRITE_EXT: + case WIN_WRITE_EXT: lba48 = 1; case WIN_WRITE: case WIN_WRITE_ONCE: @@ -1789,7 +1096,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) ide_transfer_start(s, s->io_buffer, 512, ide_sector_write); s->media_changed = 1; break; - case WIN_MULTREAD_EXT: + case WIN_MULTREAD_EXT: lba48 = 1; case WIN_MULTREAD: if (!s->mult_sectors) @@ -1814,23 +1121,23 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write); s->media_changed = 1; break; - case WIN_READDMA_EXT: + case WIN_READDMA_EXT: lba48 = 1; case WIN_READDMA: case WIN_READDMA_ONCE: if (!s->bs) goto abort_cmd; ide_cmd_lba48_transform(s, lba48); - ide_sector_start_dma(s, 1); + ide_sector_start_dma(s, IDE_DMA_READ); break; - case WIN_WRITEDMA_EXT: + case WIN_WRITEDMA_EXT: lba48 = 1; case WIN_WRITEDMA: case WIN_WRITEDMA_ONCE: if (!s->bs) goto abort_cmd; ide_cmd_lba48_transform(s, lba48); - ide_sector_start_dma(s, 0); + ide_sector_start_dma(s, IDE_DMA_WRITE); s->media_changed = 1; break; case WIN_READ_NATIVE_MAX_EXT: @@ -1843,6 +1150,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) break; case WIN_CHECKPOWERMODE1: case WIN_CHECKPOWERMODE2: + s->error = 0; s->nsector = 0xff; /* device active or idle */ s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); @@ -1915,7 +1223,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) case WIN_STANDBYNOW1: case WIN_STANDBYNOW2: case WIN_IDLEIMMEDIATE: - case CFA_IDLEIMMEDIATE: + case WIN_IDLEIMMEDIATE2: case WIN_SETIDLE1: case WIN_SETIDLE2: case WIN_SLEEPNOW1: @@ -1924,21 +1232,15 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) ide_set_irq(s->bus); break; case WIN_SEEK: - if(s->drive_kind == IDE_CD) - goto abort_cmd; /* XXX: Check that seek is within bounds */ s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); break; /* ATAPI commands */ case WIN_PIDENTIFY: - if (s->drive_kind == IDE_CD) { - ide_atapi_identify(s); - s->status = READY_STAT | SEEK_STAT; - ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop); - } else { - ide_abort_command(s); - } + ide_atapi_identify(s); + s->status = READY_STAT | SEEK_STAT; + ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop); ide_set_irq(s->bus); break; case WIN_DIAGNOSE: @@ -1954,16 +1256,12 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) */ ide_set_irq(s->bus); break; - case WIN_SRST: - if (s->drive_kind != IDE_CD) - goto abort_cmd; + case WIN_DEVICE_RESET: ide_set_signature(s); s->status = 0x00; /* NOTE: READY is _not_ set */ s->error = 0x01; break; case WIN_PACKETCMD: - if (s->drive_kind != IDE_CD) - goto abort_cmd; /* overlapping commands not supported */ if (s->feature & 0x02) goto abort_cmd; @@ -1975,16 +1273,12 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) break; /* CF-ATA commands */ case CFA_REQ_EXT_ERROR_CODE: - if (s->drive_kind != IDE_CFATA) - goto abort_cmd; s->error = 0x09; /* miscellaneous error */ s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); break; case CFA_ERASE_SECTORS: case CFA_WEAR_LEVEL: - if (s->drive_kind != IDE_CFATA) - goto abort_cmd; if (val == CFA_WEAR_LEVEL) s->nsector = 0; if (val == CFA_ERASE_SECTORS) @@ -1994,8 +1288,6 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) ide_set_irq(s->bus); break; case CFA_TRANSLATE_SECTOR: - if (s->drive_kind != IDE_CFATA) - goto abort_cmd; s->error = 0x00; s->status = READY_STAT | SEEK_STAT; memset(s->io_buffer, 0, 0x200); @@ -2014,8 +1306,6 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) ide_set_irq(s->bus); break; case CFA_ACCESS_METADATA_STORAGE: - if (s->drive_kind != IDE_CFATA) - goto abort_cmd; switch (s->feature) { case 0x02: /* Inquiry Metadata Storage */ ide_cfata_metadata_inquiry(s); @@ -2034,8 +1324,6 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) ide_set_irq(s->bus); break; case IBM_SENSE_CONDITION: - if (s->drive_kind != IDE_CFATA) - goto abort_cmd; switch (s->feature) { case 0x01: /* sense temperature in device */ s->nsector = 0x50; /* +20 C */ @@ -2047,9 +1335,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) ide_set_irq(s->bus); break; - case WIN_SMART: - if (s->drive_kind == IDE_CD) - goto abort_cmd; + case WIN_SMART: if (s->hcyl != 0xc2 || s->lcyl != 0x4f) goto abort_cmd; if (!s->smart_enabled && s->feature != SMART_ENABLE) @@ -2097,7 +1383,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) if (smart_attributes[n][0] == 0) break; s->io_buffer[2+0+(n*12)] = smart_attributes[n][0]; - s->io_buffer[2+1+(n*12)] = smart_attributes[n][4]; + s->io_buffer[2+1+(n*12)] = smart_attributes[n][11]; } for (n=0; n<511; n++) /* checksum */ s->io_buffer[511] += s->io_buffer[n]; @@ -2110,12 +1396,13 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) memset(s->io_buffer, 0, 0x200); s->io_buffer[0] = 0x01; /* smart struct version */ for (n=0; n<30; n++) { - if (smart_attributes[n][0] == 0) + if (smart_attributes[n][0] == 0) { break; - s->io_buffer[2+0+(n*12)] = smart_attributes[n][0]; - s->io_buffer[2+1+(n*12)] = smart_attributes[n][1]; - s->io_buffer[2+3+(n*12)] = smart_attributes[n][2]; - s->io_buffer[2+4+(n*12)] = smart_attributes[n][3]; + } + int i; + for(i = 0; i < 11; i++) { + s->io_buffer[2+i+(n*12)] = smart_attributes[n][i]; + } } s->io_buffer[362] = 0x02 | (s->smart_autosave?0x80:0x00); if (s->smart_selftest_count == 0) { @@ -2203,6 +1490,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) } break; default: + /* should not be reachable */ abort_cmd: ide_abort_command(s); ide_set_irq(s->bus); @@ -2339,15 +1627,36 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val) bus->cmd = val; } +/* + * Returns true if the running PIO transfer is a PIO out (i.e. data is + * transferred from the device to the guest), false if it's a PIO in + */ +static bool ide_is_pio_out(IDEState *s) +{ + if (s->end_transfer_func == ide_sector_write || + s->end_transfer_func == ide_atapi_cmd) { + return false; + } else if (s->end_transfer_func == ide_sector_read || + s->end_transfer_func == ide_transfer_stop || + s->end_transfer_func == ide_atapi_cmd_reply_end || + s->end_transfer_func == ide_dummy_transfer_stop) { + return true; + } + + abort(); +} + void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) { IDEBus *bus = opaque; IDEState *s = idebus_active_if(bus); uint8_t *p; - /* PIO data access allowed only when DRQ bit is set */ - if (!(s->status & DRQ_STAT)) + /* PIO data access allowed only when DRQ bit is set. The result of a write + * during PIO out is indeterminate, just ignore it. */ + if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) { return; + } p = s->data_ptr; *(uint16_t *)p = le16_to_cpu(val); @@ -2364,9 +1673,11 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr) uint8_t *p; int ret; - /* PIO data access allowed only when DRQ bit is set */ - if (!(s->status & DRQ_STAT)) + /* PIO data access allowed only when DRQ bit is set. The result of a read + * during PIO in is indeterminate, return 0 and don't move forward. */ + if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) { return 0; + } p = s->data_ptr; ret = cpu_to_le16(*(uint16_t *)p); @@ -2383,9 +1694,11 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val) IDEState *s = idebus_active_if(bus); uint8_t *p; - /* PIO data access allowed only when DRQ bit is set */ - if (!(s->status & DRQ_STAT)) + /* PIO data access allowed only when DRQ bit is set. The result of a write + * during PIO out is indeterminate, just ignore it. */ + if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) { return; + } p = s->data_ptr; *(uint32_t *)p = le32_to_cpu(val); @@ -2402,9 +1715,11 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr) uint8_t *p; int ret; - /* PIO data access allowed only when DRQ bit is set */ - if (!(s->status & DRQ_STAT)) + /* PIO data access allowed only when DRQ bit is set. The result of a read + * during PIO in is indeterminate, return 0 and don't move forward. */ + if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) { return 0; + } p = s->data_ptr; ret = cpu_to_le32(*(uint32_t *)p); @@ -2496,13 +1811,32 @@ void ide_bus_reset(IDEBus *bus) bus->dma->ops->reset(bus->dma); } -int ide_init_drive(IDEState *s, BlockDriverState *bs, +static bool ide_cd_is_tray_open(void *opaque) +{ + return ((IDEState *)opaque)->tray_open; +} + +static bool ide_cd_is_medium_locked(void *opaque) +{ + return ((IDEState *)opaque)->tray_locked; +} + +static const BlockDevOps ide_cd_block_ops = { + .change_media_cb = ide_cd_change_cb, + .eject_request_cb = ide_cd_eject_request_cb, + .is_tray_open = ide_cd_is_tray_open, + .is_medium_locked = ide_cd_is_medium_locked, +}; + +int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, const char *version, const char *serial) { int cylinders, heads, secs; uint64_t nb_sectors; s->bs = bs; + s->drive_kind = kind; + bdrv_get_geometry(bs, &nb_sectors); bdrv_guess_geometry(bs, &cylinders, &heads, &secs); if (cylinders < 1 || cylinders > 16383) { @@ -2527,10 +1861,9 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, s->smart_autosave = 1; s->smart_errors = 0; s->smart_selftest_count = 0; - if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) { - s->drive_kind = IDE_CD; - bdrv_set_change_cb(bs, cdrom_change_cb, s); - bs->buffer_alignment = 2048; + if (kind == IDE_CD) { + bdrv_set_dev_ops(bs, &ide_cd_block_ops, s); + bdrv_set_buffer_alignment(bs, 2048); } else { if (!bdrv_is_inserted(s->bs)) { error_report("Device needs media, but drive is empty"); @@ -2554,7 +1887,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, } ide_reset(s); - bdrv_set_removable(bs, s->drive_kind == IDE_CD); + bdrv_iostatus_enable(bs); return 0; } @@ -2567,10 +1900,14 @@ static void ide_init1(IDEBus *bus, int unit) s->unit = unit; s->drive_serial = drive_serial++; /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */ - s->io_buffer = qemu_memalign(2048, IDE_DMA_BUF_SECTORS*512 + 4); s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4; + s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len); + memset(s->io_buffer, 0, s->io_buffer_total_len); + s->smart_selftest_data = qemu_blockalign(s->bs, 512); - s->sector_write_timer = qemu_new_timer(vm_clock, + memset(s->smart_selftest_data, 0, 512); + + s->sector_write_timer = qemu_new_timer_ns(vm_clock, ide_sector_write_timer_cb, s); } @@ -2589,7 +1926,7 @@ static int ide_nop_int(IDEDMA *dma, int x) return 0; } -static void ide_nop_restart(void *opaque, int x, int y) +static void ide_nop_restart(void *opaque, int x, RunState y) { } @@ -2633,11 +1970,13 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, dinfo = i == 0 ? hd0 : hd1; ide_init1(bus, i); if (dinfo) { - if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL, + if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, + dinfo->media_cd ? IDE_CD : IDE_HD, NULL, *dinfo->serial ? dinfo->serial : NULL) < 0) { error_report("Can't set up IDE drive %s", dinfo->id); exit(1); } + bdrv_attach_dev_nofail(dinfo->bdrv, &bus->ifs[i]); } else { ide_reset(&bus->ifs[i]); } @@ -2646,20 +1985,27 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, bus->dma = &ide_dma_nop; } -void ide_init_ioport(IDEBus *bus, int iobase, int iobase2) +static const MemoryRegionPortio ide_portio_list[] = { + { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write }, + { 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew }, + { 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionPortio ide_portio2_list[] = { + { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write }, + PORTIO_END_OF_LIST(), +}; + +void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2) { - register_ioport_write(iobase, 8, 1, ide_ioport_write, bus); - register_ioport_read(iobase, 8, 1, ide_ioport_read, bus); + /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA + bridge has been setup properly to always register with ISA. */ + isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide"); + if (iobase2) { - register_ioport_read(iobase2, 1, 1, ide_status_read, bus); - register_ioport_write(iobase2, 1, 1, ide_cmd_write, bus); + isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide"); } - - /* data ports */ - register_ioport_write(iobase, 2, 2, ide_data_writew, bus); - register_ioport_read(iobase, 2, 2, ide_data_readw, bus); - register_ioport_write(iobase, 4, 4, ide_data_writel, bus); - register_ioport_read(iobase, 4, 4, ide_data_readl, bus); } static bool is_identify_set(void *opaque, int version_id) @@ -2694,7 +2040,7 @@ static int ide_drive_post_load(void *opaque, int version_id) IDEState *s = opaque; if (version_id < 3) { - if (s->sense_key == SENSE_UNIT_ATTENTION && + if (s->sense_key == UNIT_ATTENTION && s->asc == ASC_MEDIUM_MAY_HAVE_CHANGED) { s->cdrom_changed = 1; } @@ -2706,7 +2052,7 @@ static int ide_drive_pio_post_load(void *opaque, int version_id) { IDEState *s = opaque; - if (s->end_transfer_fn_idx > ARRAY_SIZE(transfer_end_table)) { + if (s->end_transfer_fn_idx >= ARRAY_SIZE(transfer_end_table)) { return -EINVAL; } s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx]; @@ -2738,10 +2084,67 @@ static bool ide_drive_pio_state_needed(void *opaque) { IDEState *s = opaque; - return (s->status & DRQ_STAT) != 0; + return ((s->status & DRQ_STAT) != 0) + || (s->bus->error_status & BM_STATUS_PIO_RETRY); +} + +static int ide_tray_state_post_load(void *opaque, int version_id) +{ + IDEState *s = opaque; + + bdrv_eject(s->bs, s->tray_open); + bdrv_lock_medium(s->bs, s->tray_locked); + return 0; +} + +static bool ide_tray_state_needed(void *opaque) +{ + IDEState *s = opaque; + + return s->tray_open || s->tray_locked; +} + +static bool ide_atapi_gesn_needed(void *opaque) +{ + IDEState *s = opaque; + + return s->events.new_media || s->events.eject_request; } -const VMStateDescription vmstate_ide_drive_pio_state = { +static bool ide_error_needed(void *opaque) +{ + IDEBus *bus = opaque; + + return (bus->error_status != 0); +} + +/* Fields for GET_EVENT_STATUS_NOTIFICATION ATAPI command */ +static const VMStateDescription vmstate_ide_atapi_gesn_state = { + .name ="ide_drive/atapi/gesn_state", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_BOOL(events.new_media, IDEState), + VMSTATE_BOOL(events.eject_request, IDEState), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_ide_tray_state = { + .name = "ide_drive/tray_state", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = ide_tray_state_post_load, + .fields = (VMStateField[]) { + VMSTATE_BOOL(tray_open, IDEState), + VMSTATE_BOOL(tray_locked, IDEState), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_ide_drive_pio_state = { .name = "ide_drive/pio_state", .version_id = 1, .minimum_version_id = 1, @@ -2795,11 +2198,28 @@ const VMStateDescription vmstate_ide_drive = { .vmsd = &vmstate_ide_drive_pio_state, .needed = ide_drive_pio_state_needed, }, { + .vmsd = &vmstate_ide_tray_state, + .needed = ide_tray_state_needed, + }, { + .vmsd = &vmstate_ide_atapi_gesn_state, + .needed = ide_atapi_gesn_needed, + }, { /* empty */ } } }; +static const VMStateDescription vmstate_ide_error_status = { + .name ="ide_bus/error", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_INT32(error_status, IDEBus), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_ide_bus = { .name = "ide_bus", .version_id = 1, @@ -2809,5 +2229,27 @@ const VMStateDescription vmstate_ide_bus = { VMSTATE_UINT8(cmd, IDEBus), VMSTATE_UINT8(unit, IDEBus), VMSTATE_END_OF_LIST() + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_ide_error_status, + .needed = ide_error_needed, + }, { + /* empty */ + } } }; + +void ide_drive_get(DriveInfo **hd, int max_bus) +{ + int i; + + if (drive_get_max_bus(IF_IDE) >= max_bus) { + fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus); + exit(1); + } + + for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) { + hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); + } +} diff --git a/hw/ide/ich.c b/hw/ide/ich.c index f242d7a..3f7510f 100644 --- a/hw/ide/ich.c +++ b/hw/ide/ich.c @@ -66,23 +66,33 @@ #include #include #include "block.h" -#include "block_int.h" -#include "sysemu.h" #include "dma.h" #include #include +#define ICH9_SATA_CAP_OFFSET 0xA8 + +#define ICH9_IDP_BAR 4 +#define ICH9_MEM_BAR 5 + +#define ICH9_IDP_INDEX 0x10 +#define ICH9_IDP_INDEX_LOG2 0x04 + +static const VMStateDescription vmstate_ahci = { + .name = "ahci", + .unmigratable = 1, +}; + static int pci_ich9_ahci_init(PCIDevice *dev) { struct AHCIPCIState *d; + int sata_cap_offset; + uint8_t *sata_cap; d = DO_UPCAST(struct AHCIPCIState, card, dev); - pci_config_set_vendor_id(d->card.config, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(d->card.config, PCI_DEVICE_ID_INTEL_82801IR); + ahci_init(&d->ahci, &dev->qdev, 6); - pci_config_set_class(d->card.config, PCI_CLASS_STORAGE_SATA); - pci_config_set_revision(d->card.config, 0x02); pci_config_set_prog_interface(d->card.config, AHCI_PROGMODE_MAJOR_REV_1); d->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */ @@ -94,15 +104,26 @@ static int pci_ich9_ahci_init(PCIDevice *dev) qemu_register_reset(ahci_reset, d); - /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */ - pci_register_bar(&d->card, 5, 0x1000, PCI_BASE_ADDRESS_SPACE_MEMORY, - ahci_pci_map); - msi_init(dev, 0x50, 1, true, false); - - ahci_init(&d->ahci, &dev->qdev, 6); d->ahci.irq = d->card.irq[0]; + pci_register_bar(&d->card, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO, + &d->ahci.idp); + pci_register_bar(&d->card, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY, + &d->ahci.mem); + + sata_cap_offset = pci_add_capability(&d->card, PCI_CAP_ID_SATA, + ICH9_SATA_CAP_OFFSET, SATA_CAP_SIZE); + if (sata_cap_offset < 0) { + return sata_cap_offset; + } + + sata_cap = d->card.config + sata_cap_offset; + pci_set_word(sata_cap + SATA_CAP_REV, 0x10); + pci_set_long(sata_cap + SATA_CAP_BAR, + (ICH9_IDP_BAR + 0x4) | (ICH9_IDP_INDEX_LOG2 << 4)); + d->ahci.idp_offset = ICH9_IDP_INDEX; + return 0; } @@ -111,10 +132,7 @@ static int pci_ich9_uninit(PCIDevice *dev) struct AHCIPCIState *d; d = DO_UPCAST(struct AHCIPCIState, card, dev); - if (msi_enabled(dev)) { - msi_uninit(dev); - } - + msi_uninit(dev); qemu_unregister_reset(ahci_reset, d); ahci_uninit(&d->ahci); @@ -133,9 +151,14 @@ static PCIDeviceInfo ich_ahci_info[] = { .qdev.name = "ich9-ahci", .qdev.alias = "ahci", .qdev.size = sizeof(AHCIPCIState), + .qdev.vmsd = &vmstate_ahci, .init = pci_ich9_ahci_init, .exit = pci_ich9_uninit, .config_write = pci_ich9_write_config, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82801IR, + .revision = 0x02, + .class_id = PCI_CLASS_STORAGE_SATA, },{ /* end of list */ } diff --git a/hw/ide/internal.h b/hw/ide/internal.h index d533fb6..00b28df 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -7,8 +7,11 @@ * non-internal declarations are in hw/ide.h */ #include -#include "block_int.h" +#include #include "iorange.h" +#include "dma.h" +#include "sysemu.h" +#include "hw/scsi-defs.h" /* debug IDE devices */ //#define DEBUG_IDE @@ -54,107 +57,120 @@ typedef struct IDEDMAOps IDEDMAOps; #define IDE_CMD_RESET 0x04 #define IDE_CMD_DISABLE_IRQ 0x02 -/* ATA/ATAPI Commands pre T13 Spec */ +/* ACS-2 T13/2015-D Table B.2 Command codes */ #define WIN_NOP 0x00 -/* - * 0x01->0x02 Reserved - */ +/* reserved 0x01..0x02 */ #define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */ -/* - * 0x04->0x07 Reserved - */ -#define WIN_SRST 0x08 /* ATAPI soft reset command */ +/* reserved 0x04..0x05 */ +#define WIN_DSM 0x06 +/* reserved 0x07 */ #define WIN_DEVICE_RESET 0x08 -/* - * 0x09->0x0F Reserved - */ -#define WIN_RECAL 0x10 -#define WIN_RESTORE WIN_RECAL -/* - * 0x10->0x1F Reserved - */ +/* reserved 0x09..0x0a */ +/* REQUEST SENSE DATA EXT 0x0B */ +/* reserved 0x0C..0x0F */ +#define WIN_RECAL 0x10 /* obsolete since ATA4 */ +/* obsolete since ATA3, retired in ATA4 0x11..0x1F */ #define WIN_READ 0x20 /* 28-Bit */ -#define WIN_READ_ONCE 0x21 /* 28-Bit without retries */ -#define WIN_READ_LONG 0x22 /* 28-Bit */ -#define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */ +#define WIN_READ_ONCE 0x21 /* 28-Bit w/o retries, obsolete since ATA5 */ +/* obsolete since ATA4 0x22..0x23 */ #define WIN_READ_EXT 0x24 /* 48-Bit */ #define WIN_READDMA_EXT 0x25 /* 48-Bit */ -#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */ +#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit, obsolete since ACS2 */ #define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */ -/* - * 0x28 - */ +/* reserved 0x28 */ #define WIN_MULTREAD_EXT 0x29 /* 48-Bit */ -/* - * 0x2A->0x2F Reserved - */ +/* READ STREAM DMA EXT 0x2A */ +/* READ STREAM EXT 0x2B */ +/* reserved 0x2C..0x2E */ +/* READ LOG EXT 0x2F */ #define WIN_WRITE 0x30 /* 28-Bit */ -#define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */ -#define WIN_WRITE_LONG 0x32 /* 28-Bit */ -#define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */ +#define WIN_WRITE_ONCE 0x31 /* 28-Bit w/o retries, obsolete since ATA5 */ +/* obsolete since ATA4 0x32..0x33 */ #define WIN_WRITE_EXT 0x34 /* 48-Bit */ #define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */ #define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */ +#define WIN_SET_MAX_EXT 0x37 /* 48-Bit, obsolete since ACS2 */ #define WIN_SET_MAX_EXT 0x37 /* 48-Bit */ #define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */ #define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */ -/* - * 0x3A->0x3B Reserved - */ -#define WIN_WRITE_VERIFY 0x3C /* 28-Bit */ -/* - * 0x3D->0x3F Reserved - */ +/* WRITE STREAM DMA EXT 0x3A */ +/* WRITE STREAM EXT 0x3B */ +#define WIN_WRITE_VERIFY 0x3C /* 28-Bit, obsolete since ATA4 */ +/* WRITE DMA FUA EXT 0x3D */ +/* obsolete since ACS2 0x3E */ +/* WRITE LOG EXT 0x3F */ #define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */ -#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */ +#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - w/o retries, obsolete since ATA5 */ #define WIN_VERIFY_EXT 0x42 /* 48-Bit */ -/* - * 0x43->0x4F Reserved - */ -#define WIN_FORMAT 0x50 -/* - * 0x51->0x5F Reserved - */ -#define WIN_INIT 0x60 -/* - * 0x61->0x5F Reserved - */ -#define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */ +/* reserved 0x43..0x44 */ +/* WRITE UNCORRECTABLE EXT 0x45 */ +/* reserved 0x46 */ +/* READ LOG DMA EXT 0x47 */ +/* reserved 0x48..0x4F */ +/* obsolete since ATA4 0x50 */ +/* CONFIGURE STREAM 0x51 */ +/* reserved 0x52..0x56 */ +/* WRITE LOG DMA EXT 0x57 */ +/* reserved 0x58..0x5A */ +/* TRUSTED NON DATA 0x5B */ +/* TRUSTED RECEIVE 0x5C */ +/* TRUSTED RECEIVE DMA 0x5D */ +/* TRUSTED SEND 0x5E */ +/* TRUSTED SEND DMA 0x5F */ +/* READ FPDMA QUEUED 0x60 */ +/* WRITE FPDMA QUEUED 0x61 */ +/* reserved 0x62->0x6F */ +#define WIN_SEEK 0x70 /* obsolete since ATA7 */ +/* reserved 0x71-0x7F */ +/* vendor specific 0x80-0x86 */ #define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */ +/* vendor specific 0x88-0x8F */ #define WIN_DIAGNOSE 0x90 -#define WIN_SPECIFY 0x91 /* set drive geometry translation */ +#define WIN_SPECIFY 0x91 /* set drive geometry translation, obsolete since ATA6 */ #define WIN_DOWNLOAD_MICROCODE 0x92 -#define WIN_STANDBYNOW2 0x94 -#define CFA_IDLEIMMEDIATE 0x95 /* force drive to become "ready" */ -#define WIN_STANDBY2 0x96 -#define WIN_SETIDLE2 0x97 -#define WIN_CHECKPOWERMODE2 0x98 -#define WIN_SLEEPNOW2 0x99 -/* - * 0x9A VENDOR - */ +/* DOWNLOAD MICROCODE DMA 0x93 */ +#define WIN_STANDBYNOW2 0x94 /* retired in ATA4 */ +#define WIN_IDLEIMMEDIATE2 0x95 /* force drive to become "ready", retired in ATA4 */ +#define WIN_STANDBY2 0x96 /* retired in ATA4 */ +#define WIN_SETIDLE2 0x97 /* retired in ATA4 */ +#define WIN_CHECKPOWERMODE2 0x98 /* retired in ATA4 */ +#define WIN_SLEEPNOW2 0x99 /* retired in ATA4 */ +/* vendor specific 0x9A */ +/* reserved 0x9B..0x9F */ #define WIN_PACKETCMD 0xA0 /* Send a packet command. */ #define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ -#define WIN_QUEUED_SERVICE 0xA2 +#define WIN_QUEUED_SERVICE 0xA2 /* obsolete since ACS2 */ +/* reserved 0xA3..0xAF */ #define WIN_SMART 0xB0 /* self-monitoring and reporting */ +/* Device Configuration Overlay 0xB1 */ +/* reserved 0xB2..0xB3 */ +/* Sanitize Device 0xB4 */ +/* reserved 0xB5 */ +/* NV Cache 0xB6 */ +/* reserved for CFA 0xB7..0xBB */ #define CFA_ACCESS_METADATA_STORAGE 0xB8 +/* reserved 0xBC..0xBF */ #define CFA_ERASE_SECTORS 0xC0 /* microdrives implement as NOP */ +/* vendor specific 0xC1..0xC3 */ #define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/ #define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ #define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ -#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */ +#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers, obsolete since ACS2 */ #define WIN_READDMA 0xC8 /* read sectors using DMA transfers */ -#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */ +#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - w/o retries, obsolete since ATA5 */ #define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */ -#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */ -#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */ +#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - w/o retries, obsolete since ATA5 */ +#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers, obsolete since ACS2 */ #define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */ -#define WIN_GETMEDIASTATUS 0xDA -#define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */ -#define WIN_POSTBOOT 0xDC -#define WIN_PREBOOT 0xDD -#define WIN_DOORLOCK 0xDE /* lock door on removable drives */ -#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */ +/* WRITE MULTIPLE FUA EXT 0xCE */ +/* reserved 0xCF..0xDO */ +/* CHECK MEDIA CARD TYPE 0xD1 */ +/* reserved for media card pass through 0xD2..0xD4 */ +/* reserved 0xD5..0xD9 */ +#define WIN_GETMEDIASTATUS 0xDA /* obsolete since ATA8 */ +/* obsolete since ATA3, retired in ATA4 0xDB..0xDD */ +#define WIN_DOORLOCK 0xDE /* lock door on removable drives, obsolete since ATA8 */ +#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives, obsolete since ATA8 */ #define WIN_STANDBYNOW1 0xE0 #define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */ #define WIN_STANDBY 0xE2 /* Set device in Standby Mode */ @@ -164,31 +180,34 @@ typedef struct IDEDMAOps IDEDMAOps; #define WIN_SLEEPNOW1 0xE6 #define WIN_FLUSH_CACHE 0xE7 #define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */ -#define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */ - /* SET_FEATURES 0x22 or 0xDD */ +/* READ BUFFER DMA 0xE9 */ #define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */ +/* WRITE BUFFER DMA 0xEB */ #define WIN_IDENTIFY 0xEC /* ask drive to identify itself */ -#define WIN_MEDIAEJECT 0xED -#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */ +#define WIN_MEDIAEJECT 0xED /* obsolete since ATA8 */ +/* obsolete since ATA4 0xEE */ #define WIN_SETFEATURES 0xEF /* set special drive features */ -#define EXABYTE_ENABLE_NEST 0xF0 -#define IBM_SENSE_CONDITION 0xF0 /* measure disk temperature */ +#define IBM_SENSE_CONDITION 0xF0 /* measure disk temperature, vendor specific */ #define WIN_SECURITY_SET_PASS 0xF1 #define WIN_SECURITY_UNLOCK 0xF2 #define WIN_SECURITY_ERASE_PREPARE 0xF3 #define WIN_SECURITY_ERASE_UNIT 0xF4 #define WIN_SECURITY_FREEZE_LOCK 0xF5 -#define CFA_WEAR_LEVEL 0xF5 /* microdrives implement as NOP */ +#define CFA_WEAR_LEVEL 0xF5 /* microdrives implement as NOP; not specified in T13! */ #define WIN_SECURITY_DISABLE 0xF6 +/* vendor specific 0xF7 */ #define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */ #define WIN_SET_MAX 0xF9 -#define DISABLE_SEAGATE 0xFB +/* vendor specific 0xFA..0xFF */ /* set to 1 set disable mult support */ #define MAX_MULT_SECTORS 16 #define IDE_DMA_BUF_SECTORS 256 +/* feature values for Data Set Management */ +#define DSM_TRIM 0x01 + #if (IDE_DMA_BUF_SECTORS < MAX_MULT_SECTORS) #error "IDE_DMA_BUF_SECTORS must be bigger or equal to MAX_MULT_SECTORS" #endif @@ -262,71 +281,6 @@ typedef struct IDEDMAOps IDEDMAOps; #define GPCMD_GET_MEDIA_STATUS 0xda #define GPCMD_MODE_SENSE_6 0x1a -/* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_WRITE_PARMS_PAGE 0x05 -#define GPMODE_AUDIO_CTL_PAGE 0x0e -#define GPMODE_POWER_PAGE 0x1a -#define GPMODE_FAULT_FAIL_PAGE 0x1c -#define GPMODE_TO_PROTECT_PAGE 0x1d -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f -/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor - * of MODE_SENSE_POWER_PAGE */ -#define GPMODE_CDROM_PAGE 0x0d - -/* - * Based on values from but extending CD_MINS - * to the maximum common size allowed by the Orange's Book ATIP - * - * 90 and 99 min CDs are also available but using them as the - * upper limit reduces the effectiveness of the heuristic to - * detect DVDs burned to less than 25% of their maximum capacity - */ - -/* Some generally useful CD-ROM information */ -#define CD_MINS 80 /* max. minutes per CD */ -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ -#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ -#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) -#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) - -/* - * The MMC values are not IDE specific and might need to be moved - * to a common header if they are also needed for the SCSI emulation - */ - -/* Profile list from MMC-6 revision 1 table 91 */ -#define MMC_PROFILE_NONE 0x0000 -#define MMC_PROFILE_CD_ROM 0x0008 -#define MMC_PROFILE_CD_R 0x0009 -#define MMC_PROFILE_CD_RW 0x000A -#define MMC_PROFILE_DVD_ROM 0x0010 -#define MMC_PROFILE_DVD_R_SR 0x0011 -#define MMC_PROFILE_DVD_RAM 0x0012 -#define MMC_PROFILE_DVD_RW_RO 0x0013 -#define MMC_PROFILE_DVD_RW_SR 0x0014 -#define MMC_PROFILE_DVD_R_DL_SR 0x0015 -#define MMC_PROFILE_DVD_R_DL_JR 0x0016 -#define MMC_PROFILE_DVD_RW_DL 0x0017 -#define MMC_PROFILE_DVD_DDR 0x0018 -#define MMC_PROFILE_DVD_PLUS_RW 0x001A -#define MMC_PROFILE_DVD_PLUS_R 0x001B -#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A -#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B -#define MMC_PROFILE_BD_ROM 0x0040 -#define MMC_PROFILE_BD_R_SRM 0x0041 -#define MMC_PROFILE_BD_R_RRM 0x0042 -#define MMC_PROFILE_BD_RE 0x0043 -#define MMC_PROFILE_HDDVD_ROM 0x0050 -#define MMC_PROFILE_HDDVD_R 0x0051 -#define MMC_PROFILE_HDDVD_RAM 0x0052 -#define MMC_PROFILE_HDDVD_RW 0x0053 -#define MMC_PROFILE_HDDVD_R_DL 0x0058 -#define MMC_PROFILE_HDDVD_RW_DL 0x005A -#define MMC_PROFILE_INVALID 0xFFFF - #define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */ #define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */ #define ATAPI_INT_REASON_REL 0x04 @@ -348,11 +302,6 @@ typedef struct IDEDMAOps IDEDMAOps; #define CFA_INVALID_ADDRESS 0x21 #define CFA_ADDRESS_OVERFLOW 0x2f -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 - #define SMART_READ_DATA 0xd0 #define SMART_READ_THRESH 0xd1 #define SMART_ATTR_AUTOSAVE 0xd2 @@ -371,7 +320,21 @@ typedef void EndTransferFunc(IDEState *); typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *); typedef int DMAFunc(IDEDMA *); typedef int DMAIntFunc(IDEDMA *, int); -typedef void DMARestartFunc(void *, int, int); +typedef void DMARestartFunc(void *, int, RunState); + +struct unreported_events { + bool eject_request; + bool new_media; +}; + +enum ide_dma_cmd { + IDE_DMA_READ, + IDE_DMA_WRITE, + IDE_DMA_TRIM, +}; + +#define ide_cmd_is_read(s) \ + ((s)->dma_cmd == IDE_DMA_READ) /* NOTE: IDEState represents in fact one drive */ struct IDEState { @@ -408,8 +371,11 @@ struct IDEState { BlockDriverState *bs; char version[9]; /* ATAPI specific */ + struct unreported_events events; uint8_t sense_key; uint8_t asc; + bool tray_open; + bool tray_locked; uint8_t cdrom_changed; int packet_transfer_size; int elementary_transfer_size; @@ -417,6 +383,7 @@ struct IDEState { int lba; int cd_sector_size; int atapi_dma; /* true if dma is requested for the packet cmd */ + BlockAcctCookie acct; /* ATA DMA state */ int io_buffer_size; QEMUSGList sg; @@ -439,7 +406,7 @@ struct IDEState { uint32_t mdata_size; uint8_t *mdata_storage; int media_changed; - int is_read; + enum ide_dma_cmd dma_cmd; /* SMART */ uint8_t smart_enabled; uint8_t smart_autosave; @@ -479,6 +446,8 @@ struct IDEBus { uint8_t unit; uint8_t cmd; qemu_irq irq; + + int error_status; }; struct IDEDevice { @@ -498,10 +467,17 @@ struct IDEDeviceInfo { #define BM_STATUS_DMAING 0x01 #define BM_STATUS_ERROR 0x02 #define BM_STATUS_INT 0x04 + +/* FIXME These are not status register bits */ #define BM_STATUS_DMA_RETRY 0x08 #define BM_STATUS_PIO_RETRY 0x10 #define BM_STATUS_RETRY_READ 0x20 #define BM_STATUS_RETRY_FLUSH 0x40 +#define BM_STATUS_RETRY_TRIM 0x80 + +#define BM_MIGRATION_COMPAT_STATUS_BITS \ + (BM_STATUS_DMA_RETRY | BM_STATUS_PIO_RETRY | \ + BM_STATUS_RETRY_READ | BM_STATUS_RETRY_FLUSH) #define BM_CMD_START 0x01 #define BM_CMD_READ 0x08 @@ -551,12 +527,12 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr); void ide_data_writel(void *opaque, uint32_t addr, uint32_t val); uint32_t ide_data_readl(void *opaque, uint32_t addr); -int ide_init_drive(IDEState *s, BlockDriverState *bs, +int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, const char *version, const char *serial); void ide_init2(IDEBus *bus, qemu_irq irq); void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1, qemu_irq irq); -void ide_init_ioport(IDEBus *bus, int iobase, int iobase2); +void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2); void ide_exec_cmd(IDEBus *bus, uint32_t val); void ide_dma_cb(void *opaque, int ret); @@ -564,6 +540,18 @@ void ide_sector_write(IDEState *s); void ide_sector_read(IDEState *s); void ide_flush_cache(IDEState *s); +void ide_transfer_start(IDEState *s, uint8_t *buf, int size, + EndTransferFunc *end_transfer_func); +void ide_transfer_stop(IDEState *s); +void ide_set_inactive(IDEState *s); +BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque); + +/* hw/ide/atapi.c */ +void ide_atapi_cmd(IDEState *s); +void ide_atapi_cmd_reply_end(IDEState *s); + /* hw/ide/qdev.c */ void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id); IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive); diff --git a/hw/ide/isa.c b/hw/ide/isa.c index 8c59c5a..01a9e59 100644 --- a/hw/ide/isa.c +++ b/hw/ide/isa.c @@ -26,8 +26,6 @@ #include #include #include "block.h" -#include "block_int.h" -#include "sysemu.h" #include "dma.h" #include @@ -68,10 +66,8 @@ static int isa_ide_initfn(ISADevice *dev) ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev); ide_bus_new(&s->bus, &s->dev.qdev, 0); - ide_init_ioport(&s->bus, s->iobase, s->iobase2); + ide_init_ioport(&s->bus, dev, s->iobase, s->iobase2); isa_init_irq(dev, &s->irq, s->isairq); - isa_init_ioport_range(dev, s->iobase, 8); - isa_init_ioport(dev, s->iobase2); ide_init2(&s->bus, s->irq); vmstate_register(&dev->qdev, 0, &vmstate_ide_isa, s); return 0; diff --git a/hw/ide/macio.c b/hw/ide/macio.c index c1b4caa..70b3342 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -26,8 +26,6 @@ #include #include #include "block.h" -#include "block_int.h" -#include "sysemu.h" #include "dma.h" #include @@ -36,6 +34,7 @@ /* MacIO based PowerPC IDE */ typedef struct MACIOIDEState { + MemoryRegion mem; IDEBus bus; BlockDriverAIOCB *aiocb; } MACIOIDEState; @@ -52,8 +51,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_atapi_io_error(s, ret); - io->dma_end(opaque); - return; + goto done; } if (s->io_buffer_size > 0) { @@ -71,8 +69,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) ide_atapi_cmd_ok(s); if (io->len == 0) { - io->dma_end(opaque); - return; + goto done; } /* launch next transfer */ @@ -90,11 +87,16 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) if (!m->aiocb) { qemu_sglist_destroy(&s->sg); /* Note: media not present is the most likely case */ - ide_atapi_cmd_error(s, SENSE_NOT_READY, + ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT); - io->dma_end(opaque); - return; + goto done; } + return; + +done: + bdrv_acct_done(s->bs, &s->acct); + io->dma_end(opaque); + return; } static void pmac_ide_transfer_cb(void *opaque, int ret) @@ -109,8 +111,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_dma_error(s); - io->dma_end(io); - return; + goto done; } sector_num = ide_get_sector(s); @@ -130,10 +131,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) } /* end of DMA ? */ - if (io->len == 0) { - io->dma_end(io); - return; + goto done; } /* launch next transfer */ @@ -146,14 +145,29 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) io->addr += io->len; io->len = 0; - if (s->is_read) + switch (s->dma_cmd) { + case IDE_DMA_READ: m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, pmac_ide_transfer_cb, io); - else + break; + case IDE_DMA_WRITE: m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, pmac_ide_transfer_cb, io); + break; + case IDE_DMA_TRIM: + m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, + ide_issue_trim, pmac_ide_transfer_cb, s, true); + break; + } + if (!m->aiocb) pmac_ide_transfer_cb(io, -1); + return; +done: + if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { + bdrv_acct_done(s->bs, &s->acct); + } + io->dma_end(io); } static void pmac_ide_transfer(DBDMA_io *io) @@ -163,10 +177,22 @@ static void pmac_ide_transfer(DBDMA_io *io) s->io_buffer_size = 0; if (s->drive_kind == IDE_CD) { + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); pmac_ide_atapi_transfer_cb(io, 0); return; } + switch (s->dma_cmd) { + case IDE_DMA_READ: + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); + break; + case IDE_DMA_WRITE: + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); + break; + default: + break; + } + pmac_ide_transfer_cb(io, 0); } @@ -273,16 +299,20 @@ static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr) return retval; } -static CPUWriteMemoryFunc * const pmac_ide_write[] = { - pmac_ide_writeb, - pmac_ide_writew, - pmac_ide_writel, -}; - -static CPUReadMemoryFunc * const pmac_ide_read[] = { - pmac_ide_readb, - pmac_ide_readw, - pmac_ide_readl, +static MemoryRegionOps pmac_ide_ops = { + .old_mmio = { + .write = { + pmac_ide_writeb, + pmac_ide_writew, + pmac_ide_writel, + }, + .read = { + pmac_ide_readb, + pmac_ide_readw, + pmac_ide_readl, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static const VMStateDescription vmstate_pmac = { @@ -307,23 +337,20 @@ static void pmac_ide_reset(void *opaque) /* hd_table must contain 4 block drivers */ /* PowerMac uses memory mapped registers, not I/O. Return the memory I/O index to access the ide. */ -int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, - void *dbdma, int channel, qemu_irq dma_irq) +MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, + void *dbdma, int channel, qemu_irq dma_irq) { MACIOIDEState *d; - int pmac_ide_memory; - d = qemu_mallocz(sizeof(MACIOIDEState)); + d = g_malloc0(sizeof(MACIOIDEState)); ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq); if (dbdma) DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d); - pmac_ide_memory = cpu_register_io_memory(pmac_ide_read, - pmac_ide_write, d, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000); vmstate_register(NULL, 0, &vmstate_pmac, d); qemu_register_reset(pmac_ide_reset, d); - return pmac_ide_memory; + return &d->mem; } diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c index 2ceeb87..9eee5b5 100644 --- a/hw/ide/microdrive.c +++ b/hw/ide/microdrive.c @@ -26,8 +26,6 @@ #include #include #include "block.h" -#include "block_int.h" -#include "sysemu.h" #include "dma.h" #include @@ -532,7 +530,7 @@ static int dscm1xxxx_detach(void *opaque) PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv) { - MicroDriveState *md = (MicroDriveState *) qemu_mallocz(sizeof(MicroDriveState)); + MicroDriveState *md = (MicroDriveState *) g_malloc0(sizeof(MicroDriveState)); md->card.state = md; md->card.attach = dscm1xxxx_attach; md->card.detach = dscm1xxxx_detach; @@ -543,7 +541,7 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv) qemu_allocate_irqs(md_set_irq, md, 1)[0]); md->bus.ifs[0].drive_kind = IDE_CFATA; md->bus.ifs[0].mdata_size = METADATA_SIZE; - md->bus.ifs[0].mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE); + md->bus.ifs[0].mdata_storage = (uint8_t *) g_malloc0(METADATA_SIZE); vmstate_register(NULL, -1, &vmstate_microdrive, md); diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c index 82b24b6..2ec21b0 100644 --- a/hw/ide/mmio.c +++ b/hw/ide/mmio.c @@ -24,8 +24,6 @@ */ #include #include "block.h" -#include "block_int.h" -#include "sysemu.h" #include "dma.h" #include @@ -122,7 +120,7 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2, qemu_irq irq, int shift, DriveInfo *hd0, DriveInfo *hd1) { - MMIOState *s = qemu_mallocz(sizeof(MMIOState)); + MMIOState *s = g_malloc0(sizeof(MMIOState)); int mem1, mem2; ide_init2_with_non_qdev_drives(&s->bus, hd0, hd1, irq); diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 35168cb..49b823d 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -27,8 +27,6 @@ #include #include #include "block.h" -#include "block_int.h" -#include "sysemu.h" #include "dma.h" #include @@ -64,7 +62,8 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write) } prd; int l, len; - qemu_sglist_init(&s->sg, s->nsector / (BMDMA_PAGE_SIZE / 512) + 1); + pci_dma_sglist_init(&s->sg, &bm->pci_dev->dev, + s->nsector / (BMDMA_PAGE_SIZE / 512) + 1); s->io_buffer_size = 0; for(;;) { if (bm->cur_prd_len == 0) { @@ -72,7 +71,7 @@ static int bmdma_prepare_buf(IDEDMA *dma, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) return s->io_buffer_size != 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + pci_dma_read(&bm->pci_dev->dev, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -114,7 +113,7 @@ static int bmdma_rw_buf(IDEDMA *dma, int is_write) if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) return 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + pci_dma_read(&bm->pci_dev->dev, bm->cur_addr, (uint8_t *)&prd, 8); bm->cur_addr += 8; prd.addr = le32_to_cpu(prd.addr); prd.size = le32_to_cpu(prd.size); @@ -129,11 +128,11 @@ static int bmdma_rw_buf(IDEDMA *dma, int is_write) l = bm->cur_prd_len; if (l > 0) { if (is_write) { - cpu_physical_memory_write(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); + pci_dma_write(&bm->pci_dev->dev, bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); } else { - cpu_physical_memory_read(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); + pci_dma_read(&bm->pci_dev->dev, bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); } bm->cur_prd_addr += l; bm->cur_prd_len -= l; @@ -170,7 +169,7 @@ static int bmdma_set_inactive(IDEDMA *dma) return 0; } -static void bmdma_restart_dma(BMDMAState *bm, int is_read) +static void bmdma_restart_dma(BMDMAState *bm, enum ide_dma_cmd dma_cmd) { IDEState *s = bmdma_active_if(bm); @@ -178,38 +177,53 @@ static void bmdma_restart_dma(BMDMAState *bm, int is_read) s->io_buffer_index = 0; s->io_buffer_size = 0; s->nsector = bm->nsector; - s->is_read = is_read; + s->dma_cmd = dma_cmd; bm->cur_addr = bm->addr; bm->dma_cb = ide_dma_cb; bmdma_start_dma(&bm->dma, s, bm->dma_cb); } +/* TODO This should be common IDE code */ static void bmdma_restart_bh(void *opaque) { BMDMAState *bm = opaque; + IDEBus *bus = bm->bus; int is_read; + int error_status; qemu_bh_delete(bm->bh); bm->bh = NULL; - is_read = !!(bm->status & BM_STATUS_RETRY_READ); + if (bm->unit == (uint8_t) -1) { + return; + } + + is_read = !!(bus->error_status & BM_STATUS_RETRY_READ); - if (bm->status & BM_STATUS_DMA_RETRY) { - bm->status &= ~(BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ); - bmdma_restart_dma(bm, is_read); - } else if (bm->status & BM_STATUS_PIO_RETRY) { - bm->status &= ~(BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ); + /* The error status must be cleared before resubmitting the request: The + * request may fail again, and this case can only be distinguished if the + * called function can set a new error status. */ + error_status = bus->error_status; + bus->error_status = 0; + + if (error_status & BM_STATUS_DMA_RETRY) { + if (error_status & BM_STATUS_RETRY_TRIM) { + bmdma_restart_dma(bm, IDE_DMA_TRIM); + } else { + bmdma_restart_dma(bm, is_read ? IDE_DMA_READ : IDE_DMA_WRITE); + } + } else if (error_status & BM_STATUS_PIO_RETRY) { if (is_read) { ide_sector_read(bmdma_active_if(bm)); } else { ide_sector_write(bmdma_active_if(bm)); } - } else if (bm->status & BM_STATUS_RETRY_FLUSH) { + } else if (error_status & BM_STATUS_RETRY_FLUSH) { ide_flush_cache(bmdma_active_if(bm)); } } -static void bmdma_restart_cb(void *opaque, int running, int reason) +static void bmdma_restart_cb(void *opaque, int running, RunState state) { IDEDMA *dma = opaque; BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); @@ -273,9 +287,8 @@ static void bmdma_irq(void *opaque, int n, int level) qemu_set_irq(bm->irq, level); } -void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) +void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val) { - BMDMAState *bm = opaque; #ifdef DEBUG_IDE printf("%s: 0x%08x\n", __func__, val); #endif @@ -297,12 +310,8 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) */ if (bm->bus->dma->aiocb) { qemu_aio_flush(); -#ifdef DEBUG_IDE - if (bm->bus->dma->aiocb) - printf("ide_dma_cancel: aiocb still pending"); - if (bm->status & BM_STATUS_DMAING) - printf("ide_dma_cancel: BM_STATUS_DMAING still pending"); -#endif + assert(bm->bus->dma->aiocb == NULL); + assert((bm->status & BM_STATUS_DMAING) == 0); } } else { bm->cur_addr = bm->addr; @@ -318,22 +327,24 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) bm->cmd = val & 0x09; } -static void bmdma_addr_read(IORange *ioport, uint64_t addr, - unsigned width, uint64_t *data) +static uint64_t bmdma_addr_read(void *opaque, dma_addr_t addr, + unsigned width) { - BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport); + BMDMAState *bm = opaque; uint32_t mask = (1ULL << (width * 8)) - 1; + uint64_t data; - *data = (bm->addr >> (addr * 8)) & mask; + data = (bm->addr >> (addr * 8)) & mask; #ifdef DEBUG_IDE printf("%s: 0x%08x\n", __func__, (unsigned)*data); #endif + return data; } -static void bmdma_addr_write(IORange *ioport, uint64_t addr, - unsigned width, uint64_t data) +static void bmdma_addr_write(void *opaque, dma_addr_t addr, + uint64_t data, unsigned width) { - BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport); + BMDMAState *bm = opaque; int shift = addr * 8; uint32_t mask = (1ULL << (width * 8)) - 1; @@ -344,9 +355,10 @@ static void bmdma_addr_write(IORange *ioport, uint64_t addr, bm->addr |= ((data & mask) << shift) & ~3; } -const IORangeOps bmdma_addr_ioport_ops = { +MemoryRegionOps bmdma_addr_ioport_ops = { .read = bmdma_addr_read, .write = bmdma_addr_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static bool ide_bmdma_current_needed(void *opaque) @@ -356,6 +368,43 @@ static bool ide_bmdma_current_needed(void *opaque) return (bm->cur_prd_len != 0); } +static bool ide_bmdma_status_needed(void *opaque) +{ + BMDMAState *bm = opaque; + + /* Older versions abused some bits in the status register for internal + * error state. If any of these bits are set, we must add a subsection to + * transfer the real status register */ + uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS; + + return ((bm->status & abused_bits) != 0); +} + +static void ide_bmdma_pre_save(void *opaque) +{ + BMDMAState *bm = opaque; + uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS; + + bm->migration_compat_status = + (bm->status & ~abused_bits) | (bm->bus->error_status & abused_bits); +} + +/* This function accesses bm->bus->error_status which is loaded only after + * BMDMA itself. This is why the function is called from ide_pci_post_load + * instead of being registered with VMState where it would run too early. */ +static int ide_bmdma_post_load(void *opaque, int version_id) +{ + BMDMAState *bm = opaque; + uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS; + + if (bm->status == 0) { + bm->status = bm->migration_compat_status & ~abused_bits; + bm->bus->error_status |= bm->migration_compat_status & abused_bits; + } + + return 0; +} + static const VMStateDescription vmstate_bmdma_current = { .name = "ide bmdma_current", .version_id = 1, @@ -370,15 +419,26 @@ static const VMStateDescription vmstate_bmdma_current = { } }; +const VMStateDescription vmstate_bmdma_status = { + .name ="ide bmdma/status", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT8(status, BMDMAState), + VMSTATE_END_OF_LIST() + } +}; static const VMStateDescription vmstate_bmdma = { .name = "ide bmdma", .version_id = 3, .minimum_version_id = 0, .minimum_version_id_old = 0, + .pre_save = ide_bmdma_pre_save, .fields = (VMStateField []) { VMSTATE_UINT8(cmd, BMDMAState), - VMSTATE_UINT8(status, BMDMAState), + VMSTATE_UINT8(migration_compat_status, BMDMAState), VMSTATE_UINT32(addr, BMDMAState), VMSTATE_INT64(sector_num, BMDMAState), VMSTATE_UINT32(nsector, BMDMAState), @@ -390,6 +450,9 @@ static const VMStateDescription vmstate_bmdma = { .vmsd = &vmstate_bmdma_current, .needed = ide_bmdma_current_needed, }, { + .vmsd = &vmstate_bmdma_status, + .needed = ide_bmdma_status_needed, + }, { /* empty */ } } @@ -404,7 +467,9 @@ static int ide_pci_post_load(void *opaque, int version_id) /* current versions always store 0/1, but older version stored bigger values. We only need last bit */ d->bmdma[i].unit &= 1; + ide_bmdma_post_load(&d->bmdma[i], -1); } + return 0; } @@ -451,7 +516,7 @@ static const struct IDEDMAOps bmdma_ops = { .reset = bmdma_reset, }; -void bmdma_init(IDEBus *bus, BMDMAState *bm) +void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d) { qemu_irq *irq; @@ -464,4 +529,5 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm) bm->irq = bus->irq; irq = qemu_allocate_irqs(bmdma_irq, bm, 1); bus->irq = *irq; + bm->pci_dev = d; } diff --git a/hw/ide/pci.h b/hw/ide/pci.h index cd72cba..a694e54 100644 --- a/hw/ide/pci.h +++ b/hw/ide/pci.h @@ -19,16 +19,31 @@ typedef struct BMDMAState { BlockDriverCompletionFunc *dma_cb; int64_t sector_num; uint32_t nsector; - IORange addr_ioport; + MemoryRegion addr_ioport; + MemoryRegion extra_io; QEMUBH *bh; qemu_irq irq; + + /* Bit 0-2 and 7: BM status register + * Bit 3-6: bus->error_status */ + uint8_t migration_compat_status; + struct PCIIDEState *pci_dev; } BMDMAState; +typedef struct CMD646BAR { + MemoryRegion cmd; + MemoryRegion data; + IDEBus *bus; + struct PCIIDEState *pci_dev; +} CMD646BAR; + typedef struct PCIIDEState { PCIDevice dev; IDEBus bus[2]; BMDMAState bmdma[2]; uint32_t secondary; /* used only for cmd646 */ + MemoryRegion bmdma_bar; + CMD646BAR cmd646_bar[2]; /* used only for cmd646 */ } PCIIDEState; @@ -39,9 +54,9 @@ static inline IDEState *bmdma_active_if(BMDMAState *bmdma) } -void bmdma_init(IDEBus *bus, BMDMAState *bm); -void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val); -extern const IORangeOps bmdma_addr_ioport_ops; +void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d); +void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val); +extern MemoryRegionOps bmdma_addr_ioport_ops; void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table); extern const VMStateDescription vmstate_ide_pci; diff --git a/hw/ide/piix.c b/hw/ide/piix.c index c349644..08cbbe2 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -27,17 +27,20 @@ #include #include #include "block.h" -#include "block_int.h" #include "sysemu.h" #include "dma.h" #include -static uint32_t bmdma_readb(void *opaque, uint32_t addr) +static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, unsigned size) { BMDMAState *bm = opaque; uint32_t val; + if (size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + switch(addr & 3) { case 0: val = bm->cmd; @@ -55,36 +58,46 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr) return val; } -static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) +static void bmdma_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { BMDMAState *bm = opaque; + + if (size != 1) { + return; + } + #ifdef DEBUG_IDE printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch(addr & 3) { + case 0: + return bmdma_cmd_writeb(bm, val); case 2: bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); break; } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static MemoryRegionOps piix_bmdma_ops = { + .read = bmdma_read, + .write = bmdma_write, +}; + +static void bmdma_setup_bar(PCIIDEState *d) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); int i; + memory_region_init(&d->bmdma_bar, "piix-bmdma-container", 16); for(i = 0;i < 2; i++) { BMDMAState *bm = &d->bmdma[i]; - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); - - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); - register_ioport_read(addr, 4, 1, bmdma_readb, bm); - - iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4); - ioport_register(&bm->addr_ioport); - addr += 8; + memory_region_init_io(&bm->extra_io, &piix_bmdma_ops, bm, + "piix-bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); + memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, + "bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } @@ -109,8 +122,7 @@ static void piix3_reset(void *opaque) } static void pci_piix_init_ports(PCIIDEState *d) { - int i; - struct { + static const struct { int iobase; int iobase2; int isairq; @@ -118,29 +130,32 @@ static void pci_piix_init_ports(PCIIDEState *d) { {0x1f0, 0x3f6, 14}, {0x170, 0x376, 15}, }; + int i; for (i = 0; i < 2; i++) { ide_bus_new(&d->bus[i], &d->dev.qdev, i); - ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2); + ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, + port_info[i].iobase2); ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq)); - bmdma_init(&d->bus[i], &d->bmdma[i]); + bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, &d->bmdma[i].dma); } } -static int pci_piix_ide_initfn(PCIIDEState *d) +static int pci_piix_ide_initfn(PCIDevice *dev) { + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); uint8_t *pci_conf = d->dev.config; pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode - pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE); qemu_register_reset(piix3_reset, d); - pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + bmdma_setup_bar(d); + pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d); @@ -149,22 +164,56 @@ static int pci_piix_ide_initfn(PCIIDEState *d) return 0; } -static int pci_piix3_ide_initfn(PCIDevice *dev) +static int pci_piix3_xen_ide_unplug(DeviceState *dev) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + PCIDevice *pci_dev; + PCIIDEState *pci_ide; + DriveInfo *di; + int i = 0; + + pci_dev = DO_UPCAST(PCIDevice, qdev, dev); + pci_ide = DO_UPCAST(PCIIDEState, dev, pci_dev); + + for (; i < 3; i++) { + di = drive_get_by_index(IF_IDE, i); + if (di != NULL && !di->media_cd) { + DeviceState *ds = bdrv_get_attached_dev(di->bdrv); + if (ds) { + bdrv_detach_dev(di->bdrv, ds); + } + bdrv_close(di->bdrv); + pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; + drive_put_ref(di); + } + } + qdev_reset_all(&(pci_ide->dev.qdev)); + return 0; +} - pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371SB_1); - return pci_piix_ide_initfn(d); +PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) +{ + PCIDevice *dev; + + dev = pci_create_simple(bus, devfn, "piix3-ide-xen"); + dev->qdev.info->unplug = pci_piix3_xen_ide_unplug; + pci_ide_create_devs(dev, hd_table); + return dev; } -static int pci_piix4_ide_initfn(PCIDevice *dev) +static int pci_piix_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_destroy(&d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + memory_region_destroy(&d->bmdma[i].addr_ioport); + } + memory_region_destroy(&d->bmdma_bar); - pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371AB); - return pci_piix_ide_initfn(d); + return 0; } /* hd_table must contain 4 block drivers */ @@ -195,13 +244,29 @@ static PCIDeviceInfo piix_ide_info[] = { .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .no_hotplug = 1, - .init = pci_piix3_ide_initfn, + .init = pci_piix_ide_initfn, + .exit = pci_piix_ide_exitfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371SB_1, + .class_id = PCI_CLASS_STORAGE_IDE, + },{ + .qdev.name = "piix3-ide-xen", + .qdev.size = sizeof(PCIIDEState), + .qdev.no_user = 1, + .init = pci_piix_ide_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371SB_1, + .class_id = PCI_CLASS_STORAGE_IDE, },{ .qdev.name = "piix4-ide", .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .no_hotplug = 1, - .init = pci_piix4_ide_initfn, + .init = pci_piix_ide_initfn, + .exit = pci_piix_ide_exitfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371AB, + .class_id = PCI_CLASS_STORAGE_IDE, },{ /* end of list */ } diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 2bb5c27..4207127 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -31,6 +31,10 @@ static struct BusInfo ide_bus_info = { .name = "IDE", .size = sizeof(IDEBus), .get_fw_dev_path = idebus_get_fw_dev_path, + .props = (Property[]) { + DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1), + DEFINE_PROP_END_OF_LIST(), + }, }; void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id) @@ -98,7 +102,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive) { DeviceState *dev; - dev = qdev_create(&bus->qbus, "ide-drive"); + dev = qdev_create(&bus->qbus, drive->media_cd ? "ide-cd" : "ide-hd"); qdev_prop_set_uint32(dev, "unit", unit); qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv); qdev_init_nofail(dev); @@ -118,13 +122,18 @@ typedef struct IDEDrive { IDEDevice dev; } IDEDrive; -static int ide_drive_initfn(IDEDevice *dev) +static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind) { IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus); IDEState *s = bus->ifs + dev->unit; const char *serial; DriveInfo *dinfo; + if (dev->conf.discard_granularity && dev->conf.discard_granularity != 512) { + error_report("discard_granularity must be 512 for ide"); + return -1; + } + serial = dev->serial; if (!serial) { /* try to fall back to value set with legacy -drive serial=... */ @@ -134,15 +143,15 @@ static int ide_drive_initfn(IDEDevice *dev) } } - if (ide_init_drive(s, dev->conf.bs, dev->version, serial) < 0) { + if (ide_init_drive(s, dev->conf.bs, kind, dev->version, serial) < 0) { return -1; } if (!dev->version) { - dev->version = qemu_strdup(s->version); + dev->version = g_strdup(s->version); } if (!dev->serial) { - dev->serial = qemu_strdup(s->drive_serial_str); + dev->serial = g_strdup(s->drive_serial_str); } add_boot_device_path(dev->conf.bootindex, &dev->qdev, @@ -151,22 +160,68 @@ static int ide_drive_initfn(IDEDevice *dev) return 0; } -static IDEDeviceInfo ide_drive_info = { - .qdev.name = "ide-drive", - .qdev.fw_name = "drive", - .qdev.size = sizeof(IDEDrive), - .init = ide_drive_initfn, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1), - DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), - DEFINE_PROP_STRING("ver", IDEDrive, dev.version), - DEFINE_PROP_STRING("serial", IDEDrive, dev.serial), - DEFINE_PROP_END_OF_LIST(), +static int ide_hd_initfn(IDEDevice *dev) +{ + return ide_dev_initfn(dev, IDE_HD); +} + +static int ide_cd_initfn(IDEDevice *dev) +{ + return ide_dev_initfn(dev, IDE_CD); +} + +static int ide_drive_initfn(IDEDevice *dev) +{ + DriveInfo *dinfo = drive_get_by_blockdev(dev->conf.bs); + + return ide_dev_initfn(dev, dinfo->media_cd ? IDE_CD : IDE_HD); +} + +#define DEFINE_IDE_DEV_PROPERTIES() \ + DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \ + DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \ + DEFINE_PROP_STRING("serial", IDEDrive, dev.serial) + +static IDEDeviceInfo ide_dev_info[] = { + { + .qdev.name = "ide-hd", + .qdev.fw_name = "drive", + .qdev.desc = "virtual IDE disk", + .qdev.size = sizeof(IDEDrive), + .init = ide_hd_initfn, + .qdev.props = (Property[]) { + DEFINE_IDE_DEV_PROPERTIES(), + DEFINE_PROP_END_OF_LIST(), + } + },{ + .qdev.name = "ide-cd", + .qdev.fw_name = "drive", + .qdev.desc = "virtual IDE CD-ROM", + .qdev.size = sizeof(IDEDrive), + .init = ide_cd_initfn, + .qdev.props = (Property[]) { + DEFINE_IDE_DEV_PROPERTIES(), + DEFINE_PROP_END_OF_LIST(), + } + },{ + .qdev.name = "ide-drive", /* legacy -device ide-drive */ + .qdev.fw_name = "drive", + .qdev.desc = "virtual IDE disk or CD-ROM (legacy)", + .qdev.size = sizeof(IDEDrive), + .init = ide_drive_initfn, + .qdev.props = (Property[]) { + DEFINE_IDE_DEV_PROPERTIES(), + DEFINE_PROP_END_OF_LIST(), + } } }; -static void ide_drive_register(void) +static void ide_dev_register(void) { - ide_qdev_register(&ide_drive_info); + int i; + + for (i = 0; i < ARRAY_SIZE(ide_dev_info); i++) { + ide_qdev_register(&ide_dev_info[i]); + } } -device_init(ide_drive_register); +device_init(ide_dev_register); diff --git a/hw/ide/via.c b/hw/ide/via.c index 04f3290..098f150 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -28,17 +28,21 @@ #include #include #include "block.h" -#include "block_int.h" #include "sysemu.h" #include "dma.h" #include -static uint32_t bmdma_readb(void *opaque, uint32_t addr) +static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, + unsigned size) { BMDMAState *bm = opaque; uint32_t val; + if (size != 1) { + return ((uint64_t)1 << (size * 8)) - 1; + } + switch (addr & 3) { case 0: val = bm->cmd; @@ -56,13 +60,21 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr) return val; } -static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) +static void bmdma_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { BMDMAState *bm = opaque; + + if (size != 1) { + return; + } + #ifdef DEBUG_IDE printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); #endif switch (addr & 3) { + case 0: + return bmdma_cmd_writeb(bm, val); case 2: bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06); break; @@ -70,23 +82,25 @@ static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val) } } -static void bmdma_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static MemoryRegionOps via_bmdma_ops = { + .read = bmdma_read, + .write = bmdma_write, +}; + +static void bmdma_setup_bar(PCIIDEState *d) { - PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev); int i; + memory_region_init(&d->bmdma_bar, "via-bmdma-container", 16); for(i = 0;i < 2; i++) { BMDMAState *bm = &d->bmdma[i]; - register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm); - - register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm); - register_ioport_read(addr, 4, 1, bmdma_readb, bm); - - iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4); - ioport_register(&bm->addr_ioport); - addr += 8; + memory_region_init_io(&bm->extra_io, &via_bmdma_ops, bm, + "via-bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); + memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, + "bmdma", 4); + memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } @@ -132,8 +146,7 @@ static void via_reset(void *opaque) } static void vt82c686b_init_ports(PCIIDEState *d) { - int i; - struct { + static const struct { int iobase; int iobase2; int isairq; @@ -141,13 +154,15 @@ static void vt82c686b_init_ports(PCIIDEState *d) { {0x1f0, 0x3f6, 14}, {0x170, 0x376, 15}, }; + int i; for (i = 0; i < 2; i++) { ide_bus_new(&d->bus[i], &d->dev.qdev, i); - ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2); + ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase, + port_info[i].iobase2); ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq)); - bmdma_init(&d->bus[i], &d->bmdma[i]); + bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, &d->bmdma[i].dma); @@ -160,16 +175,12 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);; uint8_t *pci_conf = d->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_IDE); - pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE); pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */ - pci_config_set_revision(pci_conf,0x06); /* Revision 0.6 */ pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); qemu_register_reset(via_reset, d); - pci_register_bar(&d->dev, 4, 0x10, - PCI_BASE_ADDRESS_SPACE_IO, bmdma_map); + bmdma_setup_bar(d); + pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d); @@ -178,6 +189,22 @@ static int vt82c686b_ide_initfn(PCIDevice *dev) return 0; } +static int vt82c686b_ide_exitfn(PCIDevice *dev) +{ + PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); + unsigned i; + + for (i = 0; i < 2; ++i) { + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io); + memory_region_destroy(&d->bmdma[i].extra_io); + memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport); + memory_region_destroy(&d->bmdma[i].addr_ioport); + } + memory_region_destroy(&d->bmdma_bar); + + return 0; +} + void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) { PCIDevice *dev; @@ -191,6 +218,11 @@ static PCIDeviceInfo via_ide_info = { .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .init = vt82c686b_ide_initfn, + .exit = vt82c686b_ide_exitfn, + .vendor_id = PCI_VENDOR_ID_VIA, + .device_id = PCI_DEVICE_ID_VIA_IDE, + .revision = 0x06, + .class_id = PCI_CLASS_STORAGE_IDE, }; static void via_ide_register(void) diff --git a/hw/integratorcp.c b/hw/integratorcp.c index b049940..9a289b4 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -4,21 +4,23 @@ * Copyright (c) 2005-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "sysbus.h" #include "primecell.h" #include "devices.h" -#include "sysemu.h" #include "boards.h" #include "arm-misc.h" #include "net.h" +#include "exec-memory.h" +#include "sysemu.h" typedef struct { SysBusDevice busdev; uint32_t memsz; - uint32_t flash_offset; + MemoryRegion flash; + bool flash_mapped; uint32_t cm_osc; uint32_t cm_ctrl; uint32_t cm_lock; @@ -109,9 +111,15 @@ static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset) static void integratorcm_do_remap(integratorcm_state *s, int flash) { if (flash) { - cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM); + if (s->flash_mapped) { + sysbus_del_memory(&s->busdev, &s->flash); + s->flash_mapped = false; + } } else { - cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM); + if (!s->flash_mapped) { + sysbus_add_memory_overlap(&s->busdev, 0, &s->flash, 1); + s->flash_mapped = true; + } } //??? tlb_flush (cpu_single_env, 1); } @@ -119,15 +127,20 @@ static void integratorcm_do_remap(integratorcm_state *s, int flash) static void integratorcm_set_ctrl(integratorcm_state *s, uint32_t value) { if (value & 8) { - hw_error("Board reset\n"); + qemu_system_reset_request(); } - if ((s->cm_init ^ value) & 4) { + if ((s->cm_ctrl ^ value) & 4) { integratorcm_do_remap(s, (value & 4) == 0); } - if ((s->cm_init ^ value) & 1) { - printf("Green LED %s\n", (value & 1) ? "on" : "off"); + if ((s->cm_ctrl ^ value) & 1) { + /* (value & 1) != 0 means the green "MISC LED" is lit. + * We don't have any nice place to display LEDs. printf is a bad + * idea because Linux uses the LED as a heartbeat and the output + * will swamp anything else on the terminal. + */ } - s->cm_init = (s->cm_init & ~ 5) | (value ^ 5); + /* Note that the RESET bit [3] always reads as zero */ + s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5); } static void integratorcm_update(integratorcm_state *s) @@ -253,7 +266,8 @@ static int integratorcm_init(SysBusDevice *dev) } memcpy(integrator_spd + 73, "QEMU-MEMORY", 11); s->cm_init = 0x00000112; - s->flash_offset = qemu_ram_alloc(NULL, "integrator.flash", 0x100000); + memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000); + s->flash_mapped = false; iomemtype = cpu_register_io_memory(integratorcm_readfn, integratorcm_writefn, s, @@ -457,7 +471,9 @@ static void integratorcp_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; - ram_addr_t ram_offset; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *ram_alias = g_new(MemoryRegion, 1); qemu_irq pic[32]; qemu_irq *cpu_pic; DeviceState *dev; @@ -470,13 +486,14 @@ static void integratorcp_init(ram_addr_t ram_size, fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } - ram_offset = qemu_ram_alloc(NULL, "integrator.ram", ram_size); + memory_region_init_ram(ram, NULL, "integrator.ram", ram_size); /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */ /* ??? RAM should repeat to fill physical memory space. */ /* SDRAM at address zero*/ - cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); + memory_region_add_subregion(address_space_mem, 0, ram); /* And again at address 0x80000000 */ - cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM); + memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size); + memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias); dev = qdev_create(NULL, "integrator_core"); qdev_prop_set_uint32(dev, "memsz", ram_size >> 20); diff --git a/hw/intel-hda.c b/hw/intel-hda.c index b2b6708..10769e0 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -24,6 +24,7 @@ #include "audiodev.h" #include "intel-hda.h" #include "intel-hda-defs.h" +#include "dma.h" /* --------------------------------------------------------------------- */ /* hda bus */ @@ -86,7 +87,7 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad) DeviceState *qdev; HDACodecDevice *cdev; - QLIST_FOREACH(qdev, &bus->qbus.children, sibling) { + QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) { cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); if (cdev->cad == cad) { return cdev; @@ -177,7 +178,7 @@ struct IntelHDAState { IntelHDAStream st[8]; /* state */ - int mmio_addr; + MemoryRegion mmio; uint32_t rirb_count; int64_t wall_base_ns; @@ -224,19 +225,6 @@ static target_phys_addr_t intel_hda_addr(uint32_t lbase, uint32_t ubase) return addr; } -static void stl_phys_le(target_phys_addr_t addr, uint32_t value) -{ - uint32_t value_le = cpu_to_le32(value); - cpu_physical_memory_write(addr, (uint8_t*)(&value_le), sizeof(value_le)); -} - -static uint32_t ldl_phys_le(target_phys_addr_t addr) -{ - uint32_t value_le; - cpu_physical_memory_read(addr, (uint8_t*)(&value_le), sizeof(value_le)); - return le32_to_cpu(value_le); -} - static void intel_hda_update_int_sts(IntelHDAState *d) { uint32_t sts = 0; @@ -341,7 +329,7 @@ static void intel_hda_corb_run(IntelHDAState *d) rp = (d->corb_rp + 1) & 0xff; addr = intel_hda_addr(d->corb_lbase, d->corb_ubase); - verb = ldl_phys_le(addr + 4*rp); + verb = ldl_le_pci_dma(&d->pci, addr + 4*rp); d->corb_rp = rp; dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb); @@ -373,8 +361,8 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res ex = (solicited ? 0 : (1 << 4)) | dev->cad; wp = (d->rirb_wp + 1) & 0xff; addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase); - stl_phys_le(addr + 8*wp, response); - stl_phys_le(addr + 8*wp + 4, ex); + stl_le_pci_dma(&d->pci, addr + 8*wp, response); + stl_le_pci_dma(&d->pci, addr + 8*wp + 4, ex); d->rirb_wp = wp; dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n", @@ -402,18 +390,19 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, { HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus); IntelHDAState *d = container_of(bus, IntelHDAState, codecs); - IntelHDAStream *st = NULL; target_phys_addr_t addr; uint32_t s, copy, left; + IntelHDAStream *st; bool irq = false; - for (s = 0; s < ARRAY_SIZE(d->st); s++) { - if (stnr == ((d->st[s].ctl >> 20) & 0x0f)) { - st = d->st + s; + st = output ? d->st + 4 : d->st; + for (s = 0; s < 4; s++) { + if (stnr == ((st[s].ctl >> 20) & 0x0f)) { + st = st + s; break; } } - if (st == NULL) { + if (s == 4) { return false; } if (st->bpl == NULL) { @@ -438,8 +427,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, dprint(d, 3, "dma: entry %d, pos %d/%d, copy %d\n", st->be, st->bp, st->bpl[st->be].len, copy); - cpu_physical_memory_rw(st->bpl[st->be].addr + st->bp, - buf, copy, !output); + pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output); st->lpib += copy; st->bp += copy; buf += copy; @@ -461,7 +449,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, } if (d->dp_lbase & 0x01) { addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase); - stl_phys_le(addr + 8*s, st->lpib); + stl_le_pci_dma(&d->pci, addr + 8*s, st->lpib); } dprint(d, 3, "dma: --\n"); @@ -480,10 +468,10 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st) addr = intel_hda_addr(st->bdlp_lbase, st->bdlp_ubase); st->bentries = st->lvi +1; - qemu_free(st->bpl); - st->bpl = qemu_malloc(sizeof(bpl) * st->bentries); + g_free(st->bpl); + st->bpl = g_malloc(sizeof(bpl) * st->bentries); for (i = 0; i < st->bentries; i++, addr += 16) { - cpu_physical_memory_read(addr, buf, 16); + pci_dma_read(&d->pci, addr, buf, 16); st->bpl[i].addr = le64_to_cpu(*(uint64_t *)buf); st->bpl[i].len = le32_to_cpu(*(uint32_t *)(buf + 8)); st->bpl[i].flags = le32_to_cpu(*(uint32_t *)(buf + 12)); @@ -497,15 +485,15 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st) st->bp = 0; } -static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running) +static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output) { DeviceState *qdev; HDACodecDevice *cdev; - QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) { + QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) { cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); if (cdev->info->stream) { - cdev->info->stream(cdev, stream, running); + cdev->info->stream(cdev, stream, running, output); } } } @@ -579,6 +567,7 @@ static void intel_hda_set_ics(IntelHDAState *d, const IntelHDAReg *reg, uint32_t static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old) { + bool output = reg->stream >= 4; IntelHDAStream *st = d->st + reg->stream; if (st->ctl & 0x01) { @@ -594,11 +583,11 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint3 dprint(d, 1, "st #%d: start %d (ring buf %d bytes)\n", reg->stream, stnr, st->cbl); intel_hda_parse_bdl(d, st); - intel_hda_notify_codecs(d, stnr, true); + intel_hda_notify_codecs(d, stnr, true, output); } else { /* stop */ dprint(d, 1, "st #%d: stop %d\n", reg->stream, stnr); - intel_hda_notify_codecs(d, stnr, false); + intel_hda_notify_codecs(d, stnr, false, output); } } intel_hda_update_irq(d); @@ -1097,26 +1086,22 @@ static uint32_t intel_hda_mmio_readl(void *opaque, target_phys_addr_t addr) return intel_hda_reg_read(d, reg, 0xffffffff); } -static CPUReadMemoryFunc * const intel_hda_mmio_read[3] = { - intel_hda_mmio_readb, - intel_hda_mmio_readw, - intel_hda_mmio_readl, -}; - -static CPUWriteMemoryFunc * const intel_hda_mmio_write[3] = { - intel_hda_mmio_writeb, - intel_hda_mmio_writew, - intel_hda_mmio_writel, +static const MemoryRegionOps intel_hda_mmio_ops = { + .old_mmio = { + .read = { + intel_hda_mmio_readb, + intel_hda_mmio_readw, + intel_hda_mmio_readl, + }, + .write = { + intel_hda_mmio_writeb, + intel_hda_mmio_writew, + intel_hda_mmio_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static void intel_hda_map(PCIDevice *pci, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci); - - cpu_register_physical_memory(addr, 0x4000, d->mmio_addr); -} - /* --------------------------------------------------------------------- */ static void intel_hda_reset(DeviceState *dev) @@ -1126,10 +1111,10 @@ static void intel_hda_reset(DeviceState *dev) HDACodecDevice *cdev; intel_hda_regs_reset(d); - d->wall_base_ns = qemu_get_clock(vm_clock); + d->wall_base_ns = qemu_get_clock_ns(vm_clock); /* reset codecs */ - QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) { + QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) { cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); if (qdev->info->reset) { qdev->info->reset(qdev); @@ -1146,20 +1131,14 @@ static int intel_hda_init(PCIDevice *pci) d->name = d->pci.qdev.info->name; - pci_config_set_vendor_id(conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(conf, 0x2668); - pci_config_set_revision(conf, 1); - pci_config_set_class(conf, PCI_CLASS_MULTIMEDIA_HD_AUDIO); pci_config_set_interrupt_pin(conf, 1); /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */ conf[0x40] = 0x01; - d->mmio_addr = cpu_register_io_memory(intel_hda_mmio_read, - intel_hda_mmio_write, d, - DEVICE_NATIVE_ENDIAN); - pci_register_bar(&d->pci, 0, 0x4000, PCI_BASE_ADDRESS_SPACE_MEMORY, - intel_hda_map); + memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d, + "intel-hda", 0x4000); + pci_register_bar(&d->pci, 0, 0, &d->mmio); if (d->msi) { msi_init(&d->pci, 0x50, 1, true, false); } @@ -1174,10 +1153,8 @@ static int intel_hda_exit(PCIDevice *pci) { IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci); - if (d->msi) { - msi_uninit(&d->pci); - } - cpu_unregister_io_memory(d->mmio_addr); + msi_uninit(&d->pci); + memory_region_destroy(&d->mmio); return 0; } @@ -1276,6 +1253,10 @@ static PCIDeviceInfo intel_hda_info = { .init = intel_hda_init, .exit = intel_hda_exit, .config_write = intel_hda_write_config, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = 0x2668, + .revision = 1, + .class_id = PCI_CLASS_MULTIMEDIA_HD_AUDIO, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0), DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1), diff --git a/hw/intel-hda.h b/hw/intel-hda.h index 4e44e38..65fd2a8 100644 --- a/hw/intel-hda.h +++ b/hw/intel-hda.h @@ -34,7 +34,7 @@ struct HDACodecDeviceInfo { int (*init)(HDACodecDevice *dev); int (*exit)(HDACodecDevice *dev); void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data); - void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running); + void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, bool output); }; void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, diff --git a/hw/ioapic.c b/hw/ioapic.c index 569327d..61991d7 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -104,7 +104,6 @@ static void ioapic_service(IOAPICState *s) uint64_t entry; uint8_t dest; uint8_t dest_mode; - uint8_t polarity; for (i = 0; i < IOAPIC_NUM_PINS; i++) { mask = 1 << i; @@ -116,7 +115,6 @@ static void ioapic_service(IOAPICState *s) dest_mode = (entry >> IOAPIC_LVT_DEST_MODE_SHIFT) & 1; delivery_mode = (entry >> IOAPIC_LVT_DELIV_MODE_SHIFT) & IOAPIC_DM_MASK; - polarity = (entry >> IOAPIC_LVT_POLARITY_SHIFT) & 1; if (trig_mode == IOAPIC_TRIGGER_EDGE) { s->irr &= ~mask; } else { @@ -128,7 +126,7 @@ static void ioapic_service(IOAPICState *s) vector = entry & IOAPIC_VECTOR_MASK; } apic_deliver_irq(dest, dest_mode, delivery_mode, - vector, polarity, trig_mode); + vector, trig_mode); } } } @@ -150,6 +148,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level) uint32_t mask = 1 << vector; uint64_t entry = s->ioredtbl[vector]; + if (entry & (1 << IOAPIC_LVT_POLARITY_SHIFT)) { + level = !level; + } if (((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1) == IOAPIC_TRIGGER_LEVEL) { /* level triggered */ @@ -160,8 +161,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level) s->irr &= ~mask; } } else { - /* edge triggered */ - if (level) { + /* According to the 82093AA manual, we must ignore edge requests + * if the input pin is masked. */ + if (level && !(entry & IOAPIC_LVT_MASKED)) { s->irr |= mask; ioapic_service(s); } diff --git a/hw/ioapic.h b/hw/ioapic.h index cb2642a..86e63da 100644 --- a/hw/ioapic.h +++ b/hw/ioapic.h @@ -17,4 +17,11 @@ * License along with this library; if not, see . */ +#ifndef HW_IOAPIC_H +#define HW_IOAPIC_H + +#define IOAPIC_NUM_PINS 24 + void ioapic_eoi_broadcast(int vector); + +#endif /* !HW_IOAPIC_H */ diff --git a/hw/ioh3420.c b/hw/ioh3420.c index 95adf09..a6bfbb9 100644 --- a/hw/ioh3420.c +++ b/hw/ioh3420.c @@ -104,12 +104,8 @@ static int ioh3420_initfn(PCIDevice *d) return rc; } - d->config[PCI_REVISION_ID] = PCI_DEVICE_ID_IOH_REV; pcie_port_init_reg(d); - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_IOH_EPORT); - rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET, IOH_EP_SSVID_SVID, IOH_EP_SSVID_SSID); if (rc < 0) { @@ -217,6 +213,9 @@ static PCIDeviceInfo ioh3420_info = { .config_write = ioh3420_write_config, .init = ioh3420_initfn, .exit = ioh3420_exitfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_IOH_EPORT, + .revision = PCI_DEVICE_ID_IOH_REV, .qdev.props = (Property[]) { DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0), diff --git a/hw/iommu.c b/hw/iommu.c deleted file mode 100644 index 4151022..0000000 --- a/hw/iommu.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * QEMU SPARC iommu emulation - * - * Copyright (c) 2003-2005 Fabrice Bellard - * - * 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 AUTHORS OR 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. - */ - -#include "sun4m.h" -#include "sysbus.h" - -/* debug iommu */ -//#define DEBUG_IOMMU - -#ifdef DEBUG_IOMMU -#define DPRINTF(fmt, ...) \ - do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) -#endif - -#define IOMMU_NREGS (4*4096/4) -#define IOMMU_CTRL (0x0000 >> 2) -#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */ -#define IOMMU_CTRL_VERS 0x0f000000 /* Version */ -#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */ -#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */ -#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */ -#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */ -#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */ -#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */ -#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */ -#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */ -#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */ -#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */ -#define IOMMU_CTRL_MASK 0x0000001d - -#define IOMMU_BASE (0x0004 >> 2) -#define IOMMU_BASE_MASK 0x07fffc00 - -#define IOMMU_TLBFLUSH (0x0014 >> 2) -#define IOMMU_TLBFLUSH_MASK 0xffffffff - -#define IOMMU_PGFLUSH (0x0018 >> 2) -#define IOMMU_PGFLUSH_MASK 0xffffffff - -#define IOMMU_AFSR (0x1000 >> 2) -#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */ -#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after - transaction */ -#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than - 12.8 us. */ -#define IOMMU_AFSR_BE 0x10000000 /* Write access received error - acknowledge */ -#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */ -#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */ -#define IOMMU_AFSR_RESV 0x00800000 /* Reserved, forced to 0x8 by - hardware */ -#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */ -#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */ -#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */ -#define IOMMU_AFSR_MASK 0xff0fffff - -#define IOMMU_AFAR (0x1004 >> 2) - -#define IOMMU_AER (0x1008 >> 2) /* Arbiter Enable Register */ -#define IOMMU_AER_EN_P0_ARB 0x00000001 /* MBus master 0x8 (Always 1) */ -#define IOMMU_AER_EN_P1_ARB 0x00000002 /* MBus master 0x9 */ -#define IOMMU_AER_EN_P2_ARB 0x00000004 /* MBus master 0xa */ -#define IOMMU_AER_EN_P3_ARB 0x00000008 /* MBus master 0xb */ -#define IOMMU_AER_EN_0 0x00010000 /* SBus slot 0 */ -#define IOMMU_AER_EN_1 0x00020000 /* SBus slot 1 */ -#define IOMMU_AER_EN_2 0x00040000 /* SBus slot 2 */ -#define IOMMU_AER_EN_3 0x00080000 /* SBus slot 3 */ -#define IOMMU_AER_EN_F 0x00100000 /* SBus on-board */ -#define IOMMU_AER_SBW 0x80000000 /* S-to-M asynchronous writes */ -#define IOMMU_AER_MASK 0x801f000f - -#define IOMMU_SBCFG0 (0x1010 >> 2) /* SBUS configration per-slot */ -#define IOMMU_SBCFG1 (0x1014 >> 2) /* SBUS configration per-slot */ -#define IOMMU_SBCFG2 (0x1018 >> 2) /* SBUS configration per-slot */ -#define IOMMU_SBCFG3 (0x101c >> 2) /* SBUS configration per-slot */ -#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when - bypass enabled */ -#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */ -#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */ -#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses - produced by this device as pure - physical. */ -#define IOMMU_SBCFG_MASK 0x00010003 - -#define IOMMU_ARBEN (0x2000 >> 2) /* SBUS arbitration enable */ -#define IOMMU_ARBEN_MASK 0x001f0000 -#define IOMMU_MID 0x00000008 - -#define IOMMU_MASK_ID (0x3018 >> 2) /* Mask ID */ -#define IOMMU_MASK_ID_MASK 0x00ffffff - -#define IOMMU_MSII_MASK 0x26000000 /* microSPARC II mask number */ -#define IOMMU_TS_MASK 0x23000000 /* turboSPARC mask number */ - -/* The format of an iopte in the page tables */ -#define IOPTE_PAGE 0xffffff00 /* Physical page number (PA[35:12]) */ -#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or - Viking/MXCC) */ -#define IOPTE_WRITE 0x00000004 /* Writeable */ -#define IOPTE_VALID 0x00000002 /* IOPTE is valid */ -#define IOPTE_WAZ 0x00000001 /* Write as zeros */ - -#define IOMMU_PAGE_SHIFT 12 -#define IOMMU_PAGE_SIZE (1 << IOMMU_PAGE_SHIFT) -#define IOMMU_PAGE_MASK ~(IOMMU_PAGE_SIZE - 1) - -typedef struct IOMMUState { - SysBusDevice busdev; - uint32_t regs[IOMMU_NREGS]; - target_phys_addr_t iostart; - uint32_t version; - qemu_irq irq; -} IOMMUState; - -static uint32_t iommu_mem_readl(void *opaque, target_phys_addr_t addr) -{ - IOMMUState *s = opaque; - target_phys_addr_t saddr; - uint32_t ret; - - saddr = addr >> 2; - switch (saddr) { - default: - ret = s->regs[saddr]; - break; - case IOMMU_AFAR: - case IOMMU_AFSR: - ret = s->regs[saddr]; - qemu_irq_lower(s->irq); - break; - } - DPRINTF("read reg[%d] = %x\n", (int)saddr, ret); - return ret; -} - -static void iommu_mem_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - IOMMUState *s = opaque; - target_phys_addr_t saddr; - - saddr = addr >> 2; - DPRINTF("write reg[%d] = %x\n", (int)saddr, val); - switch (saddr) { - case IOMMU_CTRL: - switch (val & IOMMU_CTRL_RNGE) { - case IOMMU_RNGE_16MB: - s->iostart = 0xffffffffff000000ULL; - break; - case IOMMU_RNGE_32MB: - s->iostart = 0xfffffffffe000000ULL; - break; - case IOMMU_RNGE_64MB: - s->iostart = 0xfffffffffc000000ULL; - break; - case IOMMU_RNGE_128MB: - s->iostart = 0xfffffffff8000000ULL; - break; - case IOMMU_RNGE_256MB: - s->iostart = 0xfffffffff0000000ULL; - break; - case IOMMU_RNGE_512MB: - s->iostart = 0xffffffffe0000000ULL; - break; - case IOMMU_RNGE_1GB: - s->iostart = 0xffffffffc0000000ULL; - break; - default: - case IOMMU_RNGE_2GB: - s->iostart = 0xffffffff80000000ULL; - break; - } - DPRINTF("iostart = " TARGET_FMT_plx "\n", s->iostart); - s->regs[saddr] = ((val & IOMMU_CTRL_MASK) | s->version); - break; - case IOMMU_BASE: - s->regs[saddr] = val & IOMMU_BASE_MASK; - break; - case IOMMU_TLBFLUSH: - DPRINTF("tlb flush %x\n", val); - s->regs[saddr] = val & IOMMU_TLBFLUSH_MASK; - break; - case IOMMU_PGFLUSH: - DPRINTF("page flush %x\n", val); - s->regs[saddr] = val & IOMMU_PGFLUSH_MASK; - break; - case IOMMU_AFAR: - s->regs[saddr] = val; - qemu_irq_lower(s->irq); - break; - case IOMMU_AER: - s->regs[saddr] = (val & IOMMU_AER_MASK) | IOMMU_AER_EN_P0_ARB; - break; - case IOMMU_AFSR: - s->regs[saddr] = (val & IOMMU_AFSR_MASK) | IOMMU_AFSR_RESV; - qemu_irq_lower(s->irq); - break; - case IOMMU_SBCFG0: - case IOMMU_SBCFG1: - case IOMMU_SBCFG2: - case IOMMU_SBCFG3: - s->regs[saddr] = val & IOMMU_SBCFG_MASK; - break; - case IOMMU_ARBEN: - // XXX implement SBus probing: fault when reading unmapped - // addresses, fault cause and address stored to MMU/IOMMU - s->regs[saddr] = (val & IOMMU_ARBEN_MASK) | IOMMU_MID; - break; - case IOMMU_MASK_ID: - s->regs[saddr] |= val & IOMMU_MASK_ID_MASK; - break; - default: - s->regs[saddr] = val; - break; - } -} - -static CPUReadMemoryFunc * const iommu_mem_read[3] = { - NULL, - NULL, - iommu_mem_readl, -}; - -static CPUWriteMemoryFunc * const iommu_mem_write[3] = { - NULL, - NULL, - iommu_mem_writel, -}; - -static uint32_t iommu_page_get_flags(IOMMUState *s, target_phys_addr_t addr) -{ - uint32_t ret; - target_phys_addr_t iopte; -#ifdef DEBUG_IOMMU - target_phys_addr_t pa = addr; -#endif - - iopte = s->regs[IOMMU_BASE] << 4; - addr &= ~s->iostart; - iopte += (addr >> (IOMMU_PAGE_SHIFT - 2)) & ~3; - cpu_physical_memory_read(iopte, (uint8_t *)&ret, 4); - tswap32s(&ret); - DPRINTF("get flags addr " TARGET_FMT_plx " => pte " TARGET_FMT_plx - ", *pte = %x\n", pa, iopte, ret); - - return ret; -} - -static target_phys_addr_t iommu_translate_pa(target_phys_addr_t addr, - uint32_t pte) -{ - uint32_t tmppte; - target_phys_addr_t pa; - - tmppte = pte; - pa = ((pte & IOPTE_PAGE) << 4) + (addr & ~IOMMU_PAGE_MASK); - DPRINTF("xlate dva " TARGET_FMT_plx " => pa " TARGET_FMT_plx - " (iopte = %x)\n", addr, pa, tmppte); - - return pa; -} - -static void iommu_bad_addr(IOMMUState *s, target_phys_addr_t addr, - int is_write) -{ - DPRINTF("bad addr " TARGET_FMT_plx "\n", addr); - s->regs[IOMMU_AFSR] = IOMMU_AFSR_ERR | IOMMU_AFSR_LE | IOMMU_AFSR_RESV | - IOMMU_AFSR_FAV; - if (!is_write) - s->regs[IOMMU_AFSR] |= IOMMU_AFSR_RD; - s->regs[IOMMU_AFAR] = addr; - qemu_irq_raise(s->irq); -} - -void sparc_iommu_memory_rw(void *opaque, target_phys_addr_t addr, - uint8_t *buf, int len, int is_write) -{ - int l; - uint32_t flags; - target_phys_addr_t page, phys_addr; - - while (len > 0) { - page = addr & IOMMU_PAGE_MASK; - l = (page + IOMMU_PAGE_SIZE) - addr; - if (l > len) - l = len; - flags = iommu_page_get_flags(opaque, page); - if (!(flags & IOPTE_VALID)) { - iommu_bad_addr(opaque, page, is_write); - return; - } - phys_addr = iommu_translate_pa(addr, flags); - if (is_write) { - if (!(flags & IOPTE_WRITE)) { - iommu_bad_addr(opaque, page, is_write); - return; - } - cpu_physical_memory_write(phys_addr, buf, l); - } else { - cpu_physical_memory_read(phys_addr, buf, l); - } - len -= l; - buf += l; - addr += l; - } -} - -static const VMStateDescription vmstate_iommu = { - .name ="iommu", - .version_id = 2, - .minimum_version_id = 2, - .minimum_version_id_old = 2, - .fields = (VMStateField []) { - VMSTATE_UINT32_ARRAY(regs, IOMMUState, IOMMU_NREGS), - VMSTATE_UINT64(iostart, IOMMUState), - VMSTATE_END_OF_LIST() - } -}; - -static void iommu_reset(DeviceState *d) -{ - IOMMUState *s = container_of(d, IOMMUState, busdev.qdev); - - memset(s->regs, 0, IOMMU_NREGS * 4); - s->iostart = 0; - s->regs[IOMMU_CTRL] = s->version; - s->regs[IOMMU_ARBEN] = IOMMU_MID; - s->regs[IOMMU_AFSR] = IOMMU_AFSR_RESV; - s->regs[IOMMU_AER] = IOMMU_AER_EN_P0_ARB | IOMMU_AER_EN_P1_ARB; - s->regs[IOMMU_MASK_ID] = IOMMU_TS_MASK; -} - -static int iommu_init1(SysBusDevice *dev) -{ - IOMMUState *s = FROM_SYSBUS(IOMMUState, dev); - int io; - - sysbus_init_irq(dev, &s->irq); - - io = cpu_register_io_memory(iommu_mem_read, iommu_mem_write, s); - sysbus_init_mmio(dev, IOMMU_NREGS * sizeof(uint32_t), io); - - return 0; -} - -static SysBusDeviceInfo iommu_info = { - .init = iommu_init1, - .qdev.name = "iommu", - .qdev.size = sizeof(IOMMUState), - .qdev.vmsd = &vmstate_iommu, - .qdev.reset = iommu_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_HEX32("version", IOMMUState, version, 0), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void iommu_register_devices(void) -{ - sysbus_register_withprop(&iommu_info); -} - -device_init(iommu_register_devices) diff --git a/hw/irq.c b/hw/irq.c index 7703f62..62f766e 100644 --- a/hw/irq.c +++ b/hw/irq.c @@ -44,8 +44,8 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n) struct IRQState *p; int i; - s = (qemu_irq *)qemu_mallocz(sizeof(qemu_irq) * n); - p = (struct IRQState *)qemu_mallocz(sizeof(struct IRQState) * n); + s = (qemu_irq *)g_malloc0(sizeof(qemu_irq) * n); + p = (struct IRQState *)g_malloc0(sizeof(struct IRQState) * n); for (i = 0; i < n; i++) { p->handler = handler; p->opaque = opaque; @@ -58,8 +58,8 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n) void qemu_free_irqs(qemu_irq *s) { - qemu_free(s[0]); - qemu_free(s); + g_free(s[0]); + g_free(s); } static void qemu_notirq(void *opaque, int line, int level) @@ -75,3 +75,32 @@ qemu_irq qemu_irq_invert(qemu_irq irq) qemu_irq_raise(irq); return qemu_allocate_irqs(qemu_notirq, irq, 1)[0]; } + +static void qemu_splitirq(void *opaque, int line, int level) +{ + struct IRQState **irq = opaque; + irq[0]->handler(irq[0]->opaque, irq[0]->n, level); + irq[1]->handler(irq[1]->opaque, irq[1]->n, level); +} + +qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2) +{ + qemu_irq *s = g_malloc0(2 * sizeof(qemu_irq)); + s[0] = irq1; + s[1] = irq2; + return qemu_allocate_irqs(qemu_splitirq, s, 1)[0]; +} + +static void proxy_irq_handler(void *opaque, int n, int level) +{ + qemu_irq **target = opaque; + + if (*target) { + qemu_set_irq((*target)[n], level); + } +} + +qemu_irq *qemu_irq_proxy(qemu_irq **target, int n) +{ + return qemu_allocate_irqs(proxy_irq_handler, target, n); +} diff --git a/hw/irq.h b/hw/irq.h index 5daae44..64da2fd 100644 --- a/hw/irq.h +++ b/hw/irq.h @@ -3,9 +3,7 @@ /* Generic IRQ/GPIO pin infrastructure. */ -/* FIXME: Rmove one of these. */ typedef void (*qemu_irq_handler)(void *opaque, int n, int level); -typedef void SetIRQFunc(void *opaque, int irq_num, int level); void qemu_set_irq(qemu_irq irq, int level); @@ -32,4 +30,12 @@ void qemu_free_irqs(qemu_irq *s); /* Returns a new IRQ with opposite polarity. */ qemu_irq qemu_irq_invert(qemu_irq irq); +/* Returns a new IRQ which feeds into both the passed IRQs */ +qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2); + +/* Returns a new IRQ set which connects 1:1 to another IRQ set, which + * may be set later. + */ +qemu_irq *qemu_irq_proxy(qemu_irq **target, int n); + #endif diff --git a/hw/isa-bus.c b/hw/isa-bus.c index 9e33e71..7c2c261 100644 --- a/hw/isa-bus.c +++ b/hw/isa-bus.c @@ -17,13 +17,14 @@ * License along with this library; if not, see . */ #include "hw.h" -#include "sysemu.h" #include "monitor.h" #include "sysbus.h" #include "isa.h" +#include "exec-memory.h" struct ISABus { BusState qbus; + MemoryRegion *address_space_io; qemu_irq *irqs; }; static ISABus *isabus; @@ -39,7 +40,7 @@ static struct BusInfo isa_bus_info = { .get_fw_dev_path = isabus_get_fw_dev_path, }; -ISABus *isa_bus_new(DeviceState *dev) +ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io) { if (isabus) { fprintf(stderr, "Can't create a second ISA bus\n"); @@ -51,6 +52,7 @@ ISABus *isa_bus_new(DeviceState *dev) } isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL)); + isabus->address_space_io = address_space_io; return isabus; } @@ -81,29 +83,32 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq) dev->nirqs++; } -static void isa_init_ioport_one(ISADevice *dev, uint16_t ioport) +static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport) { - assert(dev->nioports < ARRAY_SIZE(dev->ioports)); - dev->ioports[dev->nioports++] = ioport; + if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) { + dev->ioport_id = ioport; + } } -static int isa_cmp_ports(const void *p1, const void *p2) +void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start) { - return *(uint16_t*)p1 - *(uint16_t*)p2; + memory_region_add_subregion(isabus->address_space_io, start, io); + isa_init_ioport(dev, start); } -void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length) +void isa_register_portio_list(ISADevice *dev, uint16_t start, + const MemoryRegionPortio *pio_start, + void *opaque, const char *name) { - int i; - for (i = start; i < start + length; i++) { - isa_init_ioport_one(dev, i); - } - qsort(dev->ioports, dev->nioports, sizeof(dev->ioports[0]), isa_cmp_ports); -} + PortioList *piolist = g_new(PortioList, 1); -void isa_init_ioport(ISADevice *dev, uint16_t ioport) -{ - isa_init_ioport_range(dev, ioport, 1); + /* START is how we should treat DEV, regardless of the actual + contents of the portio array. This is how the old code + actually handled e.g. the FDC device. */ + isa_init_ioport(dev, start); + + portio_list_init(piolist, pio_start, opaque, name); + portio_list_add(piolist, isabus->address_space_io, start); } static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base) @@ -136,6 +141,18 @@ ISADevice *isa_create(const char *name) return DO_UPCAST(ISADevice, qdev, dev); } +ISADevice *isa_try_create(const char *name) +{ + DeviceState *dev; + + if (!isabus) { + hw_error("Tried to create isa device %s with no isa bus present.", + name); + } + dev = qdev_try_create(&isabus->qbus, name); + return DO_UPCAST(ISADevice, qdev, dev); +} + ISADevice *isa_create_simple(const char *name) { ISADevice *dev; @@ -184,11 +201,16 @@ static char *isabus_get_fw_dev_path(DeviceState *dev) int off; off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev)); - if (d->nioports) { - snprintf(path + off, sizeof(path) - off, "@%04x", d->ioports[0]); + if (d->ioport_id) { + snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id); } return strdup(path); } +MemoryRegion *isa_address_space(ISADevice *dev) +{ + return get_system_memory(); +} + device_init(isabus_register_devices) diff --git a/hw/isa.h b/hw/isa.h index f1335ff..5eb9c78 100644 --- a/hw/isa.h +++ b/hw/isa.h @@ -4,8 +4,11 @@ /* ISA bus */ #include "ioport.h" +#include "memory.h" #include "qdev.h" +#define ISA_NUM_IRQS 16 + typedef struct ISABus ISABus; typedef struct ISADevice ISADevice; typedef struct ISADeviceInfo ISADeviceInfo; @@ -14,8 +17,7 @@ struct ISADevice { DeviceState qdev; uint32_t isairq[2]; int nirqs; - uint16_t ioports[32]; - int nioports; + int ioport_id; }; typedef int (*isa_qdev_initfn)(ISADevice *dev); @@ -24,18 +26,49 @@ struct ISADeviceInfo { isa_qdev_initfn init; }; -ISABus *isa_bus_new(DeviceState *dev); +ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io); void isa_bus_irqs(qemu_irq *irqs); qemu_irq isa_get_irq(int isairq); void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq); -void isa_init_ioport(ISADevice *dev, uint16_t ioport); -void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length); void isa_qdev_register(ISADeviceInfo *info); +MemoryRegion *isa_address_space(ISADevice *dev); ISADevice *isa_create(const char *name); +ISADevice *isa_try_create(const char *name); ISADevice *isa_create_simple(const char *name); +/** + * isa_register_ioport: Install an I/O port region on the ISA bus. + * + * Register an I/O port region via memory_region_add_subregion + * inside the ISA I/O address space. + * + * @dev: the ISADevice against which these are registered; may be NULL. + * @io: the #MemoryRegion being registered. + * @start: the base I/O port. + */ +void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start); + +/** + * isa_register_portio_list: Initialize a set of ISA io ports + * + * Several ISA devices have many dis-joint I/O ports. Worse, these I/O + * ports can be interleaved with I/O ports from other devices. This + * function makes it easy to create multiple MemoryRegions for a single + * device and use the legacy portio routines. + * + * @dev: the ISADevice against which these are registered; may be NULL. + * @start: the base I/O port against which the portio->offset is applied. + * @portio: the ports, sorted by offset. + * @opaque: passed into the old_portio callbacks. + * @name: passed into memory_region_init_io. + */ +void isa_register_portio_list(ISADevice *dev, uint16_t start, + const MemoryRegionPortio *portio, + void *opaque, const char *name); + extern target_phys_addr_t isa_mem_base; +void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size); void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size); /* dma.c */ diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c index ca957fb..fd755ab 100644 --- a/hw/isa_mmio.c +++ b/hw/isa_mmio.c @@ -24,6 +24,7 @@ #include "hw.h" #include "isa.h" +#include "exec-memory.h" static void isa_mmio_writeb (void *opaque, target_phys_addr_t addr, uint32_t val) @@ -58,25 +59,23 @@ static uint32_t isa_mmio_readl(void *opaque, target_phys_addr_t addr) return cpu_inl(addr & IOPORTS_MASK); } -static CPUWriteMemoryFunc * const isa_mmio_write[] = { - &isa_mmio_writeb, - &isa_mmio_writew, - &isa_mmio_writel, +static const MemoryRegionOps isa_mmio_ops = { + .old_mmio = { + .write = { isa_mmio_writeb, isa_mmio_writew, isa_mmio_writel }, + .read = { isa_mmio_readb, isa_mmio_readw, isa_mmio_readl, }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static CPUReadMemoryFunc * const isa_mmio_read[] = { - &isa_mmio_readb, - &isa_mmio_readw, - &isa_mmio_readl, -}; +void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size) +{ + memory_region_init_io(mr, &isa_mmio_ops, NULL, "isa-mmio", size); +} void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size) { - int isa_mmio_iomemtype; + MemoryRegion *mr = g_malloc(sizeof(*mr)); - isa_mmio_iomemtype = cpu_register_io_memory(isa_mmio_read, - isa_mmio_write, - NULL, - DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(base, size, isa_mmio_iomemtype); + isa_mmio_setup(mr, size); + memory_region_add_subregion(get_system_memory(), base, mr); } diff --git a/hw/ivshmem.c b/hw/ivshmem.c index 7b19a81..7b4dbf6 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -18,6 +18,8 @@ #include "pci.h" #include "msix.h" #include "kvm.h" +#include "migration.h" +#include "qerror.h" #include #include @@ -56,11 +58,16 @@ typedef struct IVShmemState { CharDriverState **eventfd_chr; CharDriverState *server_chr; - int ivshmem_mmio_io_addr; + MemoryRegion ivshmem_mmio; pcibus_t mmio_addr; - pcibus_t shm_pci_addr; - uint64_t ivshmem_offset; + /* We might need to register the BAR before we actually have the memory. + * So prepare a container MemoryRegion for the BAR immediately and + * add a subregion when we have the memory. + */ + MemoryRegion bar; + MemoryRegion ivshmem; + MemoryRegion msix_bar; uint64_t ivshmem_size; /* size of shared memory region */ int shm_fd; /* shared memory file descriptor */ @@ -73,6 +80,8 @@ typedef struct IVShmemState { uint32_t features; EventfdEntry *eventfd_table; + Error *migration_blocker; + char * shmobj; char * sizearg; char * role; @@ -96,23 +105,6 @@ static inline bool is_power_of_two(uint64_t x) { return (x & (x - 1)) == 0; } -static void ivshmem_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev); - - s->shm_pci_addr = addr; - - if (s->ivshmem_offset > 0) { - cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size, - s->ivshmem_offset); - } - - IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %" - PRIu64 ", size = %" FMT_PCIBUS "\n", addr, s->ivshmem_offset, size); - -} - /* accessing registers - based on rtl8139 */ static void ivshmem_update_irq(IVShmemState *s, int val) { @@ -168,15 +160,8 @@ static uint32_t ivshmem_IntrStatus_read(IVShmemState *s) return ret; } -static void ivshmem_io_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - - IVSHMEM_DPRINTF("We shouldn't be writing words\n"); -} - -static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void ivshmem_io_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { IVShmemState *s = opaque; @@ -219,20 +204,8 @@ static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr, } } -static void ivshmem_io_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - IVSHMEM_DPRINTF("We shouldn't be writing bytes\n"); -} - -static uint32_t ivshmem_io_readw(void *opaque, target_phys_addr_t addr) -{ - - IVSHMEM_DPRINTF("We shouldn't be reading words\n"); - return 0; -} - -static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr) +static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { IVShmemState *s = opaque; @@ -265,23 +238,14 @@ static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t ivshmem_io_readb(void *opaque, target_phys_addr_t addr) -{ - IVSHMEM_DPRINTF("We shouldn't be reading bytes\n"); - - return 0; -} - -static CPUReadMemoryFunc * const ivshmem_mmio_read[3] = { - ivshmem_io_readb, - ivshmem_io_readw, - ivshmem_io_readl, -}; - -static CPUWriteMemoryFunc * const ivshmem_mmio_write[3] = { - ivshmem_io_writeb, - ivshmem_io_writew, - ivshmem_io_writel, +static const MemoryRegionOps ivshmem_mmio_ops = { + .read = ivshmem_io_read, + .write = ivshmem_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, }; static void ivshmem_receive(void *opaque, const uint8_t *buf, int size) @@ -371,12 +335,12 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) { ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, "ivshmem.bar2", - s->ivshmem_size, ptr); + memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2", + s->ivshmem_size, ptr); + memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* region for shared memory */ - pci_register_bar(&s->dev, 2, s->ivshmem_size, - PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map); + pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); } static void close_guest_eventfds(IVShmemState *s, int posn) @@ -391,7 +355,7 @@ static void close_guest_eventfds(IVShmemState *s, int posn) close(s->peers[posn].eventfds[i]); } - qemu_free(s->peers[posn].eventfds); + g_free(s->peers[posn].eventfds); s->peers[posn].nb_eventfds = 0; } @@ -401,8 +365,12 @@ static void setup_ioeventfds(IVShmemState *s) { for (i = 0; i <= s->max_peer; i++) { for (j = 0; j < s->peers[i].nb_eventfds; j++) { - kvm_set_ioeventfd_mmio_long(s->peers[i].eventfds[j], - s->mmio_addr + DOORBELL, (i << 16) | j, 1); + memory_region_add_eventfd(&s->ivshmem_mmio, + DOORBELL, + 4, + true, + (i << 16) | j, + s->peers[i].eventfds[j]); } } } @@ -419,7 +387,7 @@ static void increase_dynamic_storage(IVShmemState *s, int new_min_size) { s->nb_peers = s->nb_peers * 2; IVSHMEM_DPRINTF("bumping storage to %d guests\n", s->nb_peers); - s->peers = qemu_realloc(s->peers, s->nb_peers * sizeof(Peer)); + s->peers = g_realloc(s->peers, s->nb_peers * sizeof(Peer)); /* zero out new pointers */ for (j = old_nb_alloc; j < s->nb_peers; j++) { @@ -437,7 +405,7 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) memcpy(&incoming_posn, buf, sizeof(long)); /* pick off s->server_chr->msgfd and store it, posn should accompany msg */ - tmp_fd = qemu_chr_get_msgfd(s->server_chr); + tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr); IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd); /* make sure we have enough space for this guest */ @@ -483,18 +451,13 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) /* mmap the region and map into the BAR2 */ map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, incoming_fd, 0); - s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, - "ivshmem.bar2", s->ivshmem_size, map_ptr); + memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, + "ivshmem.bar2", s->ivshmem_size, map_ptr); - IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %" - PRIu64 ", size = %" PRIu64 "\n", s->shm_pci_addr, + IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n", s->ivshmem_offset, s->ivshmem_size); - if (s->shm_pci_addr > 0) { - /* map memory into BAR2 */ - cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size, - s->ivshmem_offset); - } + memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* only store the fd if it is successfully mapped */ s->shm_fd = incoming_fd; @@ -508,7 +471,7 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) if (guest_max_eventfd == 0) { /* one eventfd per MSI vector */ - s->peers[incoming_posn].eventfds = (int *) qemu_malloc(s->vectors * + s->peers[incoming_posn].eventfds = (int *) g_malloc(s->vectors * sizeof(int)); } @@ -549,20 +512,6 @@ static void ivshmem_reset(DeviceState *d) return; } -static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev); - - s->mmio_addr = addr; - cpu_register_physical_memory(addr + 0, IVSHMEM_REG_BAR_SIZE, - s->ivshmem_mmio_io_addr); - - if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { - setup_ioeventfds(s); - } -} - static uint64_t ivshmem_get_size(IVShmemState * s) { uint64_t value; @@ -596,11 +545,10 @@ static void ivshmem_setup_msi(IVShmemState * s) { /* allocate the MSI-X vectors */ - if (!msix_init(&s->dev, s->vectors, 1, 0)) { - pci_register_bar(&s->dev, 1, - msix_bar_size(&s->dev), - PCI_BASE_ADDRESS_SPACE_MEMORY, - msix_mmio_map); + memory_region_init(&s->msix_bar, "ivshmem-msix", 4096); + if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) { + pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, + &s->msix_bar); IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors); } else { IVSHMEM_DPRINTF("msix initialization failed\n"); @@ -613,7 +561,7 @@ static void ivshmem_setup_msi(IVShmemState * s) { } /* allocate Qemu char devices for receiving interrupts */ - s->eventfd_table = qemu_mallocz(s->vectors * sizeof(EventfdEntry)); + s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry)); } static void ivshmem_save(QEMUFile* f, void *opaque) @@ -702,28 +650,29 @@ static int pci_ivshmem_init(PCIDevice *dev) } if (s->role_val == IVSHMEM_PEER) { - register_device_unmigratable(&s->dev.qdev, "ivshmem", s); + error_set(&s->migration_blocker, QERR_DEVICE_FEATURE_BLOCKS_MIGRATION, "ivshmem", "peer mode"); + migrate_add_blocker(s->migration_blocker); } pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REDHAT_QUMRANET); - pci_conf[0x02] = 0x10; - pci_conf[0x03] = 0x11; pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY; - pci_config_set_class(pci_conf, PCI_CLASS_MEMORY_RAM); - pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; pci_config_set_interrupt_pin(pci_conf, 1); - s->shm_pci_addr = 0; - s->ivshmem_offset = 0; s->shm_fd = 0; - s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read, - ivshmem_mmio_write, s, DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s, + "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE); + + if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { + setup_ioeventfds(s); + } + /* region for registers*/ - pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, + &s->ivshmem_mmio); + + memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size); if ((s->server_chr != NULL) && (strncmp(s->server_chr->filename, "unix:", 5) == 0)) { @@ -747,12 +696,12 @@ static int pci_ivshmem_init(PCIDevice *dev) s->vm_id = -1; /* allocate/initialize space for interrupt handling */ - s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer)); + s->peers = g_malloc0(s->nb_peers * sizeof(Peer)); - pci_register_bar(&s->dev, 2, s->ivshmem_size, - PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map); + pci_register_bar(&s->dev, 2, + PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar); - s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *)); + s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *)); qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read, ivshmem_event, s); @@ -797,7 +746,15 @@ static int pci_ivshmem_uninit(PCIDevice *dev) { IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); - cpu_unregister_io_memory(s->ivshmem_mmio_io_addr); + if (s->migration_blocker) { + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); + } + + memory_region_destroy(&s->ivshmem_mmio); + memory_region_del_subregion(&s->bar, &s->ivshmem); + memory_region_destroy(&s->ivshmem); + memory_region_destroy(&s->bar); unregister_savevm(&dev->qdev, "ivshmem", s); return 0; @@ -809,6 +766,9 @@ static PCIDeviceInfo ivshmem_info = { .qdev.reset = ivshmem_reset, .init = pci_ivshmem_init, .exit = pci_ivshmem_uninit, + .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = 0x1110, + .class_id = PCI_CLASS_MEMORY_RAM, .qdev.props = (Property[]) { DEFINE_PROP_CHR("chardev", IVShmemState, server_chr), DEFINE_PROP_STRING("size", IVShmemState, sizearg), diff --git a/hw/jazz_led.c b/hw/jazz_led.c index 1dc22cf..eb472a0 100644 --- a/hw/jazz_led.c +++ b/hw/jazz_led.c @@ -312,7 +312,7 @@ void jazz_led_init(target_phys_addr_t base) LedState *s; int io; - s = qemu_mallocz(sizeof(LedState)); + s = g_malloc0(sizeof(LedState)); s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND; diff --git a/hw/lan9118.c b/hw/lan9118.c index 4ce9eb3..f8149e6 100644 --- a/hw/lan9118.c +++ b/hw/lan9118.c @@ -4,7 +4,7 @@ * Copyright (c) 2009 CodeSourcery, LLC. * Written by Paul Brook * - * This code is licenced under the GNU GPL v2 + * This code is licensed under the GNU GPL v2 */ #include "sysbus.h" @@ -152,7 +152,7 @@ typedef struct { NICState *nic; NICConf conf; qemu_irq irq; - int mmio_index; + MemoryRegion mmio; ptimer_state *timer; uint32_t irq_cfg; @@ -228,6 +228,12 @@ static void lan9118_update(lan9118_state *s) if ((s->irq_cfg & IRQ_EN) == 0) { level = 0; } + if ((s->irq_cfg & (IRQ_TYPE | IRQ_POL)) != (IRQ_TYPE | IRQ_POL)) { + /* Interrupt is active low unless we're configured as + * active-high polarity, push-pull type. + */ + level = !level; + } qemu_set_irq(s->irq, level); } @@ -294,8 +300,7 @@ static void phy_reset(lan9118_state *s) static void lan9118_reset(DeviceState *d) { lan9118_state *s = FROM_SYSBUS(lan9118_state, sysbus_from_qdev(d)); - - s->irq_cfg &= ~(IRQ_TYPE | IRQ_POL); + s->irq_cfg &= (IRQ_TYPE | IRQ_POL); s->int_sts = 0; s->int_en = 0; s->fifo_int = 0x48000000; @@ -327,7 +332,7 @@ static void lan9118_reset(DeviceState *d) s->afc_cfg = 0; s->e2p_cmd = 0; s->e2p_data = 0; - s->free_timer_start = qemu_get_clock(vm_clock) / 40; + s->free_timer_start = qemu_get_clock_ns(vm_clock) / 40; ptimer_stop(s->timer); ptimer_set_count(s->timer, 0xffff); @@ -721,7 +726,7 @@ static void do_phy_write(lan9118_state *s, int reg, uint32_t val) break; } s->phy_control = val & 0x7980; - /* Complete autonegotiation imediately. */ + /* Complete autonegotiation immediately. */ if (val & 0x1000) { s->phy_status |= 0x0020; } @@ -858,6 +863,7 @@ static void lan9118_eeprom_cmd(lan9118_state *s, int cmd, int addr) } else { DPRINTF("EEPROM Write All (ignored)\n"); } + break; case 5: /* ERASE */ if (s->eeprom_writable) { s->eeprom[addr] = 0xff; @@ -890,7 +896,7 @@ static void lan9118_tick(void *opaque) } static void lan9118_writel(void *opaque, target_phys_addr_t offset, - uint32_t val) + uint64_t val, unsigned size) { lan9118_state *s = (lan9118_state *)opaque; offset &= 0xff; @@ -904,7 +910,8 @@ static void lan9118_writel(void *opaque, target_phys_addr_t offset, switch (offset) { case CSR_IRQ_CFG: /* TODO: Implement interrupt deassertion intervals. */ - s->irq_cfg = (s->irq_cfg & IRQ_INT) | (val & IRQ_EN); + val &= (IRQ_EN | IRQ_POL | IRQ_TYPE); + s->irq_cfg = (s->irq_cfg & IRQ_INT) | val; break; case CSR_INT_STS: s->int_sts &= ~val; @@ -1016,13 +1023,14 @@ static void lan9118_writel(void *opaque, target_phys_addr_t offset, break; default: - hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, val); + hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, (int)val); break; } lan9118_update(s); } -static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset) +static uint64_t lan9118_readl(void *opaque, target_phys_addr_t offset, + unsigned size) { lan9118_state *s = (lan9118_state *)opaque; @@ -1076,7 +1084,7 @@ static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset) case CSR_WORD_SWAP: return s->word_swap; case CSR_FREE_RUN: - return (qemu_get_clock(vm_clock) / 40) - s->free_timer_start; + return (qemu_get_clock_ns(vm_clock) / 40) - s->free_timer_start; case CSR_RX_DROP: /* TODO: Implement dropped frames counter. */ return 0; @@ -1095,16 +1103,10 @@ static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset) return 0; } -static CPUReadMemoryFunc * const lan9118_readfn[] = { - lan9118_readl, - lan9118_readl, - lan9118_readl -}; - -static CPUWriteMemoryFunc * const lan9118_writefn[] = { - lan9118_writel, - lan9118_writel, - lan9118_writel +static const MemoryRegionOps lan9118_mem_ops = { + .read = lan9118_readl, + .write = lan9118_writel, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void lan9118_cleanup(VLANClientState *nc) @@ -1129,10 +1131,8 @@ static int lan9118_init1(SysBusDevice *dev) QEMUBH *bh; int i; - s->mmio_index = cpu_register_io_memory(lan9118_readfn, - lan9118_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x100, s->mmio_index); + memory_region_init_io(&s->mmio, &lan9118_mem_ops, s, "lan9118-mmio", 0x100); + sysbus_init_mmio_region(dev, &s->mmio); sysbus_init_irq(dev, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); diff --git a/hw/lance.c b/hw/lance.c index ddb1cbb..93d5fda 100644 --- a/hw/lance.c +++ b/hw/lance.c @@ -55,8 +55,8 @@ static void parent_lance_reset(void *opaque, int irq, int level) pcnet_h_reset(&d->state); } -static void lance_mem_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void lance_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { SysBusPCNetState *d = opaque; @@ -64,7 +64,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, pcnet_ioport_writew(&d->state, addr, val & 0xffff); } -static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) +static uint64_t lance_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SysBusPCNetState *d = opaque; uint32_t val; @@ -74,16 +75,14 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) return val & 0xffff; } -static CPUReadMemoryFunc * const lance_mem_read[3] = { - NULL, - lance_mem_readw, - NULL, -}; - -static CPUWriteMemoryFunc * const lance_mem_write[3] = { - NULL, - lance_mem_writew, - NULL, +static const MemoryRegionOps lance_mem_ops = { + .read = lance_mem_read, + .write = lance_mem_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 2, + .max_access_size = 2, + }, }; static void lance_cleanup(VLANClientState *nc) @@ -98,6 +97,7 @@ static NetClientInfo net_lance_info = { .size = sizeof(NICState), .can_receive = pcnet_can_receive, .receive = pcnet_receive, + .link_status_changed = pcnet_set_link_status, .cleanup = lance_cleanup, }; @@ -117,13 +117,11 @@ static int lance_init(SysBusDevice *dev) SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev); PCNetState *s = &d->state; - s->mmio_index = - cpu_register_io_memory(lance_mem_read, lance_mem_write, d, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->mmio, &lance_mem_ops, d, "lance-mmio", 4); qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1); - sysbus_init_mmio(dev, 4, s->mmio_index); + sysbus_init_mmio_region(dev, &s->mmio); sysbus_init_irq(dev, &s->irq); diff --git a/hw/leon3.c b/hw/leon3.c index 919f49f..607ec85 100644 --- a/hw/leon3.c +++ b/hw/leon3.c @@ -29,6 +29,7 @@ #include "loader.h" #include "elf.h" #include "trace.h" +#include "exec-memory.h" #include "grlib.h" @@ -100,7 +101,9 @@ static void leon3_generic_hw_init(ram_addr_t ram_size, const char *cpu_model) { CPUState *env; - ram_addr_t ram_offset, prom_offset; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *prom = g_new(MemoryRegion, 1); int ret; char *filename; qemu_irq *cpu_irqs = NULL; @@ -122,7 +125,7 @@ static void leon3_generic_hw_init(ram_addr_t ram_size, cpu_sparc_set_id(env, 0); /* Reset data */ - reset_info = qemu_mallocz(sizeof(ResetData)); + reset_info = g_malloc0(sizeof(ResetData)); reset_info->env = env; qemu_register_reset(main_cpu_reset, reset_info); @@ -139,14 +142,14 @@ static void leon3_generic_hw_init(ram_addr_t ram_size, exit(1); } - ram_offset = qemu_ram_alloc(NULL, "leon3.ram", ram_size); - cpu_register_physical_memory(0x40000000, ram_size, ram_offset | IO_MEM_RAM); + memory_region_init_ram(ram, NULL, "leon3.ram", ram_size); + memory_region_add_subregion(address_space_mem, 0x40000000, ram); /* Allocate BIOS */ prom_size = 8 * 1024 * 1024; /* 8Mb */ - prom_offset = qemu_ram_alloc(NULL, "Leon3.bios", prom_size); - cpu_register_physical_memory(0x00000000, prom_size, - prom_offset | IO_MEM_ROM); + memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size); + memory_region_set_readonly(prom, true); + memory_region_add_subregion(address_space_mem, 0x00000000, prom); /* Load boot prom */ if (bios_name == NULL) { diff --git a/hw/lm832x.c b/hw/lm832x.c index ce7dcac..992ce49 100644 --- a/hw/lm832x.c +++ b/hw/lm832x.c @@ -463,9 +463,9 @@ static int lm8323_init(i2c_slave *i2c) LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c); s->model = 0x8323; - s->pwm.tm[0] = qemu_new_timer(vm_clock, lm_kbd_pwm0_tick, s); - s->pwm.tm[1] = qemu_new_timer(vm_clock, lm_kbd_pwm1_tick, s); - s->pwm.tm[2] = qemu_new_timer(vm_clock, lm_kbd_pwm2_tick, s); + s->pwm.tm[0] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm0_tick, s); + s->pwm.tm[1] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm1_tick, s); + s->pwm.tm[2] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm2_tick, s); qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1); lm_kbd_reset(s); @@ -474,9 +474,9 @@ static int lm8323_init(i2c_slave *i2c) return 0; } -void lm832x_key_event(struct i2c_slave *i2c, int key, int state) +void lm832x_key_event(DeviceState *dev, int key, int state) { - LM823KbdState *s = (LM823KbdState *) i2c; + LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, I2C_SLAVE_FROM_QDEV(dev)); if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR)) return; diff --git a/hw/loader.c b/hw/loader.c index 35d792e..9bbcddd 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -85,17 +85,17 @@ int load_image(const char *filename, uint8_t *addr) } /* read()-like version */ -int read_targphys(const char *name, - int fd, target_phys_addr_t dst_addr, size_t nbytes) +ssize_t read_targphys(const char *name, + int fd, target_phys_addr_t dst_addr, size_t nbytes) { uint8_t *buf; - size_t did; + ssize_t did; - buf = qemu_malloc(nbytes); + buf = g_malloc(nbytes); did = read(fd, buf, nbytes); if (did > 0) rom_add_blob_fixed("read", buf, did, dst_addr); - qemu_free(buf); + g_free(buf); return did; } @@ -176,7 +176,8 @@ static void bswap_ahdr(struct exec *e) int load_aout(const char *filename, target_phys_addr_t addr, int max_sz, int bswap_needed, target_phys_addr_t target_page_size) { - int fd, size, ret; + int fd; + ssize_t size, ret; struct exec e; uint32_t magic; @@ -234,9 +235,9 @@ static void *load_at(int fd, int offset, int size) void *ptr; if (lseek(fd, offset, SEEK_SET) < 0) return NULL; - ptr = qemu_malloc(size); + ptr = g_malloc(size); if (read(fd, ptr, size) != size) { - qemu_free(ptr); + g_free(ptr); return NULL; } return ptr; @@ -351,14 +352,14 @@ static void *zalloc(void *x, unsigned items, unsigned size) size *= items; size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); - p = qemu_malloc(size); + p = g_malloc(size); return (p); } static void zfree(void *x, void *addr) { - qemu_free(addr); + g_free(addr); } @@ -476,7 +477,7 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, } *ep = hdr->ih_ep; - data = qemu_malloc(hdr->ih_size); + data = g_malloc(hdr->ih_size); if (read(fd, data, hdr->ih_size) != hdr->ih_size) { fprintf(stderr, "Error reading file\n"); @@ -490,10 +491,10 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, compressed_data = data; max_bytes = UBOOT_MAX_GUNZIP_BYTES; - data = qemu_malloc(max_bytes); + data = g_malloc(max_bytes); bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size); - qemu_free(compressed_data); + g_free(compressed_data); if (bytes < 0) { fprintf(stderr, "Unable to decompress gzipped image!\n"); goto out; @@ -510,7 +511,7 @@ int load_uimage(const char *filename, target_phys_addr_t *ep, out: if (data) - qemu_free(data); + g_free(data); close(fd); return ret; } @@ -564,11 +565,11 @@ int rom_add_file(const char *file, const char *fw_dir, int rc, fd = -1; char devpath[100]; - rom = qemu_mallocz(sizeof(*rom)); - rom->name = qemu_strdup(file); + rom = g_malloc0(sizeof(*rom)); + rom->name = g_strdup(file); rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name); if (rom->path == NULL) { - rom->path = qemu_strdup(file); + rom->path = g_strdup(file); } fd = open(rom->path, O_RDONLY | O_BINARY); @@ -579,12 +580,12 @@ int rom_add_file(const char *file, const char *fw_dir, } if (fw_dir) { - rom->fw_dir = qemu_strdup(fw_dir); - rom->fw_file = qemu_strdup(file); + rom->fw_dir = g_strdup(fw_dir); + rom->fw_file = g_strdup(file); } rom->addr = addr; rom->romsize = lseek(fd, 0, SEEK_END); - rom->data = qemu_mallocz(rom->romsize); + rom->data = g_malloc0(rom->romsize); lseek(fd, 0, SEEK_SET); rc = read(fd, rom->data, rom->romsize); if (rc != rom->romsize) { @@ -618,10 +619,10 @@ int rom_add_file(const char *file, const char *fw_dir, err: if (fd != -1) close(fd); - qemu_free(rom->data); - qemu_free(rom->path); - qemu_free(rom->name); - qemu_free(rom); + g_free(rom->data); + g_free(rom->path); + g_free(rom->name); + g_free(rom); return -1; } @@ -630,11 +631,11 @@ int rom_add_blob(const char *name, const void *blob, size_t len, { Rom *rom; - rom = qemu_mallocz(sizeof(*rom)); - rom->name = qemu_strdup(name); + rom = g_malloc0(sizeof(*rom)); + rom->name = g_strdup(name); rom->addr = addr; rom->romsize = len; - rom->data = qemu_mallocz(rom->romsize); + rom->data = g_malloc0(rom->romsize); memcpy(rom->data, blob, len); rom_insert(rom); return 0; @@ -664,7 +665,7 @@ static void rom_reset(void *unused) cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize); if (rom->isrom) { /* rom needs to be written only once */ - qemu_free(rom->data); + g_free(rom->data); rom->data = NULL; } } @@ -779,13 +780,13 @@ void do_info_roms(Monitor *mon) QTAILQ_FOREACH(rom, &roms, next) { if (!rom->fw_file) { monitor_printf(mon, "addr=" TARGET_FMT_plx - " size=0x%06zx mem=%s name=\"%s\" \n", + " size=0x%06zx mem=%s name=\"%s\"\n", rom->addr, rom->romsize, rom->isrom ? "rom" : "ram", rom->name); } else { monitor_printf(mon, "fw=%s/%s" - " size=0x%06zx name=\"%s\" \n", + " size=0x%06zx name=\"%s\"\n", rom->fw_dir, rom->fw_file, rom->romsize, diff --git a/hw/loader.h b/hw/loader.h index fc6bdff..fbcaba9 100644 --- a/hw/loader.h +++ b/hw/loader.h @@ -14,8 +14,8 @@ int load_aout(const char *filename, target_phys_addr_t addr, int max_sz, int load_uimage(const char *filename, target_phys_addr_t *ep, target_phys_addr_t *loadaddr, int *is_linux); -int read_targphys(const char *name, - int fd, target_phys_addr_t dst_addr, size_t nbytes); +ssize_t read_targphys(const char *name, + int fd, target_phys_addr_t dst_addr, size_t nbytes); void pstrcpy_targphys(const char *name, target_phys_addr_t dest, int buf_size, const char *source); diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index e4b51a8..fcc27d7 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. */ /* ??? Need to check if the {read,write}[wl] routines work properly on @@ -16,6 +16,7 @@ #include "pci.h" #include "scsi.h" #include "block_int.h" +#include "dma.h" //#define DEBUG_LSI //#define DEBUG_LSI_REG @@ -174,6 +175,7 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0) #define LSI_TAG_VALID (1 << 16) typedef struct lsi_request { + SCSIRequest *req; uint32_t tag; uint32_t dma_len; uint8_t *dma_buf; @@ -184,12 +186,12 @@ typedef struct lsi_request { typedef struct { PCIDevice dev; - int mmio_io_addr; - int ram_io_addr; - uint32_t script_ram_base; + MemoryRegion mmio_io; + MemoryRegion ram_io; + MemoryRegion io_io; int carry; /* ??? Should this be an a visible register somewhere? */ - int sense; + int status; /* Action to take at the end of a MSG IN phase. 0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN. */ int msg_action; @@ -352,10 +354,10 @@ static void lsi_soft_reset(LSIState *s) while (!QTAILQ_EMPTY(&s->queue)) { p = QTAILQ_FIRST(&s->queue); QTAILQ_REMOVE(&s->queue, p, next); - qemu_free(p); + g_free(p); } if (s->current) { - qemu_free(s->current); + g_free(s->current); s->current = NULL; } } @@ -390,11 +392,7 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr) { uint32_t buf; - /* Optimize reading from SCRIPTS RAM. */ - if ((addr & 0xffffe000) == s->script_ram_base) { - return s->script_ram[(addr & 0x1fff) >> 2]; - } - cpu_physical_memory_read(addr, (uint8_t *)&buf, 4); + pci_dma_read(&s->dev, addr, (uint8_t *)&buf, 4); return cpu_to_le32(buf); } @@ -532,8 +530,8 @@ static void lsi_bad_selection(LSIState *s, uint32_t id) /* Initiate a SCSI layer data transfer. */ static void lsi_do_dma(LSIState *s, int out) { - uint32_t count, id; - target_phys_addr_t addr; + uint32_t count; + dma_addr_t addr; SCSIDevice *dev; assert(s->current); @@ -543,12 +541,8 @@ static void lsi_do_dma(LSIState *s, int out) return; } - id = (s->current->tag >> 8) & 0xf; - dev = s->bus.devs[id]; - if (!dev) { - lsi_bad_selection(s, id); - return; - } + dev = s->current->req->dev; + assert(dev); count = s->dbc; if (count > s->current->dma_len) @@ -563,31 +557,23 @@ static void lsi_do_dma(LSIState *s, int out) else if (s->sbms) addr |= ((uint64_t)s->sbms << 32); - DPRINTF("DMA addr=0x" TARGET_FMT_plx " len=%d\n", addr, count); + DPRINTF("DMA addr=0x" DMA_ADDR_FMT " len=%d\n", addr, count); s->csbc += count; s->dnad += count; s->dbc -= count; - - if (s->current->dma_buf == NULL) { - s->current->dma_buf = dev->info->get_buf(dev, s->current->tag); + if (s->current->dma_buf == NULL) { + s->current->dma_buf = scsi_req_get_buf(s->current->req); } - /* ??? Set SFBR to first data byte. */ if (out) { - cpu_physical_memory_read(addr, s->current->dma_buf, count); + pci_dma_read(&s->dev, addr, s->current->dma_buf, count); } else { - cpu_physical_memory_write(addr, s->current->dma_buf, count); + pci_dma_write(&s->dev, addr, s->current->dma_buf, count); } s->current->dma_len -= count; if (s->current->dma_len == 0) { s->current->dma_buf = NULL; - if (out) { - /* Write the data. */ - dev->info->write_data(dev, s->current->tag); - } else { - /* Request any remaining data. */ - dev->info->read_data(dev, s->current->tag); - } + scsi_req_continue(s->current->req); } else { s->current->dma_buf += count; lsi_resume_script(s); @@ -652,82 +638,116 @@ static void lsi_reselect(LSIState *s, lsi_request *p) } } -/* Record that data is available for a queued command. Returns zero if - the device was reselected, nonzero if the IO is deferred. */ -static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) +static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag) { lsi_request *p; QTAILQ_FOREACH(p, &s->queue, next) { if (p->tag == tag) { - if (p->pending) { - BADF("Multiple IO pending for tag %d\n", tag); - } - p->pending = arg; - /* Reselect if waiting for it, or if reselection triggers an IRQ - and the bus is free. - Since no interrupt stacking is implemented in the emulation, it - is also required that there are no pending interrupts waiting - for service from the device driver. */ - if (s->waiting == 1 || - (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && - !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) { - /* Reselect device. */ - lsi_reselect(s, p); - return 0; - } else { - DPRINTF("Queueing IO tag=0x%x\n", tag); - p->pending = arg; - return 1; - } + return p; } } - BADF("IO with unknown tag %d\n", tag); - return 1; + + return NULL; } -/* Callback to indicate that the SCSI layer has completed a transfer. */ -static void lsi_command_complete(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg) +static void lsi_request_cancelled(SCSIRequest *req) { - LSIState *s = DO_UPCAST(LSIState, dev.qdev, bus->qbus.parent); + LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); + lsi_request *p = req->hba_private; + + if (s->current && req == s->current->req) { + scsi_req_unref(req); + g_free(s->current); + s->current = NULL; + return; + } + + if (p) { + QTAILQ_REMOVE(&s->queue, p, next); + scsi_req_unref(req); + g_free(p); + } +} + +/* Record that data is available for a queued command. Returns zero if + the device was reselected, nonzero if the IO is deferred. */ +static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len) +{ + lsi_request *p = req->hba_private; + + if (p->pending) { + BADF("Multiple IO pending for request %p\n", p); + } + p->pending = len; + /* Reselect if waiting for it, or if reselection triggers an IRQ + and the bus is free. + Since no interrupt stacking is implemented in the emulation, it + is also required that there are no pending interrupts waiting + for service from the device driver. */ + if (s->waiting == 1 || + (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && + !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) { + /* Reselect device. */ + lsi_reselect(s, p); + return 0; + } else { + DPRINTF("Queueing IO tag=0x%x\n", p->tag); + p->pending = len; + return 1; + } +} + + /* Callback to indicate that the SCSI layer has completed a command. */ +static void lsi_command_complete(SCSIRequest *req, uint32_t status) +{ + LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); int out; out = (s->sstat1 & PHASE_MASK) == PHASE_DO; - if (reason == SCSI_REASON_DONE) { - DPRINTF("Command complete sense=%d\n", (int)arg); - s->sense = arg; - s->command_complete = 2; - if (s->waiting && s->dbc != 0) { - /* Raise phase mismatch for short transfers. */ - lsi_bad_phase(s, out, PHASE_ST); - } else { - lsi_set_phase(s, PHASE_ST); - } + DPRINTF("Command complete status=%d\n", (int)status); + s->status = status; + s->command_complete = 2; + if (s->waiting && s->dbc != 0) { + /* Raise phase mismatch for short transfers. */ + lsi_bad_phase(s, out, PHASE_ST); + } else { + lsi_set_phase(s, PHASE_ST); + } - qemu_free(s->current); + if (s->current && req == s->current->req) { + scsi_req_unref(s->current->req); + g_free(s->current); s->current = NULL; - - lsi_resume_script(s); - return; } + lsi_resume_script(s); +} + + /* Callback to indicate that the SCSI layer has completed a transfer. */ +static void lsi_transfer_data(SCSIRequest *req, uint32_t len) +{ + LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); + int out; - if (s->waiting == 1 || !s->current || tag != s->current->tag || + if (s->waiting == 1 || !s->current || req->hba_private != s->current || (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) { - if (lsi_queue_tag(s, tag, arg)) + if (lsi_queue_req(s, req, len)) { return; + } } + out = (s->sstat1 & PHASE_MASK) == PHASE_DO; + /* host adapter (re)connected */ - DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg); - s->current->dma_len = arg; + DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, len); + s->current->dma_len = len; s->command_complete = 1; - if (!s->waiting) - return; - if (s->waiting == 1 || s->dbc == 0) { - lsi_resume_script(s); - } else { - lsi_do_dma(s, out); + if (s->waiting) { + if (s->waiting == 1 || s->dbc == 0) { + lsi_resume_script(s); + } else { + lsi_do_dma(s, out); + } } } @@ -741,30 +761,32 @@ static void lsi_do_command(LSIState *s) DPRINTF("Send command len=%d\n", s->dbc); if (s->dbc > 16) s->dbc = 16; - cpu_physical_memory_read(s->dnad, buf, s->dbc); + pci_dma_read(&s->dev, s->dnad, buf, s->dbc); s->sfbr = buf[0]; s->command_complete = 0; id = (s->select_tag >> 8) & 0xf; - dev = s->bus.devs[id]; + dev = scsi_device_find(&s->bus, 0, id, s->current_lun); if (!dev) { lsi_bad_selection(s, id); return; } assert(s->current == NULL); - s->current = qemu_mallocz(sizeof(lsi_request)); + s->current = g_malloc0(sizeof(lsi_request)); s->current->tag = s->select_tag; + s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun, buf, + s->current); - n = dev->info->send_command(dev, s->current->tag, buf, s->current_lun); - if (n > 0) { - lsi_set_phase(s, PHASE_DI); - dev->info->read_data(dev, s->current->tag); - } else if (n < 0) { - lsi_set_phase(s, PHASE_DO); - dev->info->write_data(dev, s->current->tag); + n = scsi_req_enqueue(s->current->req); + if (n) { + if (n > 0) { + lsi_set_phase(s, PHASE_DI); + } else if (n < 0) { + lsi_set_phase(s, PHASE_DO); + } + scsi_req_continue(s->current->req); } - if (!s->command_complete) { if (n) { /* Command did not complete immediately so disconnect. */ @@ -783,14 +805,14 @@ static void lsi_do_command(LSIState *s) static void lsi_do_status(LSIState *s) { - uint8_t sense; - DPRINTF("Get status len=%d sense=%d\n", s->dbc, s->sense); + uint8_t status; + DPRINTF("Get status len=%d status=%d\n", s->dbc, s->status); if (s->dbc != 1) BADF("Bad Status move\n"); s->dbc = 1; - sense = s->sense; - s->sfbr = sense; - cpu_physical_memory_write(s->dnad, &sense, 1); + status = s->status; + s->sfbr = status; + pci_dma_write(&s->dev, s->dnad, &status, 1); lsi_set_phase(s, PHASE_MI); s->msg_action = 1; lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */ @@ -804,7 +826,7 @@ static void lsi_do_msgin(LSIState *s) len = s->msg_len; if (len > s->dbc) len = s->dbc; - cpu_physical_memory_write(s->dnad, s->msg, len); + pci_dma_write(&s->dev, s->dnad, s->msg, len); /* Linux drivers rely on the last byte being in the SIDL. */ s->sidl = s->msg[len - 1]; s->msg_len -= len; @@ -836,7 +858,7 @@ static void lsi_do_msgin(LSIState *s) static uint8_t lsi_get_msgbyte(LSIState *s) { uint8_t data; - cpu_physical_memory_read(s->dnad, &data, 1); + pci_dma_read(&s->dev, s->dnad, &data, 1); s->dnad++; s->dbc--; return data; @@ -854,17 +876,15 @@ static void lsi_do_msgout(LSIState *s) uint8_t msg; int len; uint32_t current_tag; - SCSIDevice *current_dev; - lsi_request *p, *p_next; - int id; + lsi_request *current_req, *p, *p_next; if (s->current) { current_tag = s->current->tag; + current_req = s->current; } else { current_tag = s->select_tag; + current_req = lsi_find_by_tag(s, current_tag); } - id = (current_tag >> 8) & 0xf; - current_dev = s->bus.devs[id]; DPRINTF("MSG out len=%d\n", s->dbc); while (s->dbc) { @@ -913,7 +933,9 @@ static void lsi_do_msgout(LSIState *s) case 0x0d: /* The ABORT TAG message clears the current I/O process only. */ DPRINTF("MSG: ABORT TAG tag=0x%x\n", current_tag); - current_dev->info->cancel_io(current_dev, current_tag); + if (current_req) { + scsi_req_cancel(current_req->req); + } lsi_disconnect(s); break; case 0x06: @@ -936,7 +958,9 @@ static void lsi_do_msgout(LSIState *s) } /* clear the current I/O process */ - current_dev->info->cancel_io(current_dev, current_tag); + if (s->current) { + scsi_req_cancel(s->current->req); + } /* As the current implemented devices scsi_disk and scsi_generic only support one LUN, we don't need to keep track of LUNs. @@ -945,11 +969,9 @@ static void lsi_do_msgout(LSIState *s) device, but this is currently not implemented (and seems not to be really necessary). So let's simply clear all queued commands for the current device: */ - id = current_tag & 0x0000ff00; QTAILQ_FOREACH_SAFE(p, &s->queue, next, p_next) { - if ((p->tag & 0x0000ff00) == id) { - current_dev->info->cancel_io(current_dev, p->tag); - QTAILQ_REMOVE(&s->queue, p, next); + if ((p->tag & 0x0000ff00) == (current_tag & 0x0000ff00)) { + scsi_req_cancel(p->req); } } @@ -988,8 +1010,8 @@ static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count) DPRINTF("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count); while (count) { n = (count > LSI_BUF_SIZE) ? LSI_BUF_SIZE : count; - cpu_physical_memory_read(src, buf, n); - cpu_physical_memory_write(dest, buf, n); + pci_dma_read(&s->dev, src, buf, n); + pci_dma_write(&s->dev, dest, buf, n); src += n; dest += n; count -= n; @@ -1057,7 +1079,7 @@ again: /* 32-bit Table indirect */ offset = sxt24(addr); - cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8); + pci_dma_read(&s->dev, s->dsa + offset, (uint8_t *)buf, 8); /* byte count is stored in bits 0:23 only */ s->dbc = cpu_to_le32(buf[0]) & 0xffffff; s->rbc = s->dbc; @@ -1175,7 +1197,7 @@ again: } s->sstat0 |= LSI_SSTAT0_WOA; s->scntl1 &= ~LSI_SCNTL1_IARB; - if (id >= LSI_MAX_DEVS || !s->bus.devs[id]) { + if (!scsi_device_find(&s->bus, 0, id, 0)) { lsi_bad_selection(s, id); break; } @@ -1416,7 +1438,7 @@ again: n = (insn & 7); reg = (insn >> 16) & 0xff; if (insn & (1 << 24)) { - cpu_physical_memory_read(addr, data, n); + pci_dma_read(&s->dev, addr, data, n); DPRINTF("Load reg 0x%x size %d addr 0x%08x = %08x\n", reg, n, addr, *(int *)data); for (i = 0; i < n; i++) { @@ -1427,7 +1449,7 @@ again: for (i = 0; i < n; i++) { data[i] = lsi_reg_readb(s, reg + i); } - cpu_physical_memory_write(addr, data, n); + pci_dma_write(&s->dev, addr, data, n); } } } @@ -1657,13 +1679,9 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) if (val & LSI_SCNTL1_RST) { if (!(s->sstat0 & LSI_SSTAT0_RST)) { DeviceState *dev; - int id; - for (id = 0; id < s->bus.ndev; id++) { - if (s->bus.devs[id]) { - dev = &s->bus.devs[id]->qdev; - dev->info->reset(dev); - } + QTAILQ_FOREACH(dev, &s->bus.qbus.children, sibling) { + dev->info->reset(dev); } s->sstat0 |= LSI_SSTAT0_RST; lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0); @@ -1867,241 +1885,90 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) #undef CASE_SET_REG32 } -static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void lsi_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { LSIState *s = opaque; lsi_reg_writeb(s, addr & 0xff, val); } -static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); -} - -static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); - lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff); - lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff); -} - -static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr) +static uint64_t lsi_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { LSIState *s = opaque; return lsi_reg_readb(s, addr & 0xff); } -static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - uint32_t val; - - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - return val; -} - -static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - uint32_t val; - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - val |= lsi_reg_readb(s, addr + 2) << 16; - val |= lsi_reg_readb(s, addr + 3) << 24; - return val; -} - -static CPUReadMemoryFunc * const lsi_mmio_readfn[3] = { - lsi_mmio_readb, - lsi_mmio_readw, - lsi_mmio_readl, +static const MemoryRegionOps lsi_mmio_ops = { + .read = lsi_mmio_read, + .write = lsi_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; -static CPUWriteMemoryFunc * const lsi_mmio_writefn[3] = { - lsi_mmio_writeb, - lsi_mmio_writew, - lsi_mmio_writel, -}; - -static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void lsi_ram_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { LSIState *s = opaque; uint32_t newval; + uint32_t mask; int shift; - addr &= 0x1fff; newval = s->script_ram[addr >> 2]; shift = (addr & 3) * 8; - newval &= ~(0xff << shift); + mask = ((uint64_t)1 << (size * 8)) - 1; + newval &= ~(mask << shift); newval |= val << shift; s->script_ram[addr >> 2] = newval; } -static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - uint32_t newval; - - addr &= 0x1fff; - newval = s->script_ram[addr >> 2]; - if (addr & 2) { - newval = (newval & 0xffff) | (val << 16); - } else { - newval = (newval & 0xffff0000) | val; - } - s->script_ram[addr >> 2] = newval; -} - - -static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - LSIState *s = opaque; - - addr &= 0x1fff; - s->script_ram[addr >> 2] = val; -} - -static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr) +static uint64_t lsi_ram_read(void *opaque, target_phys_addr_t addr, + unsigned size) { LSIState *s = opaque; uint32_t val; + uint32_t mask; - addr &= 0x1fff; val = s->script_ram[addr >> 2]; + mask = ((uint64_t)1 << (size * 8)) - 1; val >>= (addr & 3) * 8; - return val & 0xff; -} - -static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - uint32_t val; - - addr &= 0x1fff; - val = s->script_ram[addr >> 2]; - if (addr & 2) - val >>= 16; - return val; -} - -static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr) -{ - LSIState *s = opaque; - - addr &= 0x1fff; - return s->script_ram[addr >> 2]; + return val & mask; } -static CPUReadMemoryFunc * const lsi_ram_readfn[3] = { - lsi_ram_readb, - lsi_ram_readw, - lsi_ram_readl, -}; - -static CPUWriteMemoryFunc * const lsi_ram_writefn[3] = { - lsi_ram_writeb, - lsi_ram_writew, - lsi_ram_writel, +static const MemoryRegionOps lsi_ram_ops = { + .read = lsi_ram_read, + .write = lsi_ram_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static uint32_t lsi_io_readb(void *opaque, uint32_t addr) +static uint64_t lsi_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { LSIState *s = opaque; return lsi_reg_readb(s, addr & 0xff); } -static uint32_t lsi_io_readw(void *opaque, uint32_t addr) -{ - LSIState *s = opaque; - uint32_t val; - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - return val; -} - -static uint32_t lsi_io_readl(void *opaque, uint32_t addr) -{ - LSIState *s = opaque; - uint32_t val; - addr &= 0xff; - val = lsi_reg_readb(s, addr); - val |= lsi_reg_readb(s, addr + 1) << 8; - val |= lsi_reg_readb(s, addr + 2) << 16; - val |= lsi_reg_readb(s, addr + 3) << 24; - return val; -} - -static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val) +static void lsi_io_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { LSIState *s = opaque; lsi_reg_writeb(s, addr & 0xff, val); } -static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val) -{ - LSIState *s = opaque; - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); -} - -static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val) -{ - LSIState *s = opaque; - addr &= 0xff; - lsi_reg_writeb(s, addr, val & 0xff); - lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff); - lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff); - lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff); -} - -static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); - - DPRINTF("Mapping IO at %08"FMT_PCIBUS"\n", addr); - - register_ioport_write(addr, 256, 1, lsi_io_writeb, s); - register_ioport_read(addr, 256, 1, lsi_io_readb, s); - register_ioport_write(addr, 256, 2, lsi_io_writew, s); - register_ioport_read(addr, 256, 2, lsi_io_readw, s); - register_ioport_write(addr, 256, 4, lsi_io_writel, s); - register_ioport_read(addr, 256, 4, lsi_io_readl, s); -} - -static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); - - DPRINTF("Mapping ram at %08"FMT_PCIBUS"\n", addr); - s->script_ram_base = addr; - cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr); -} - -static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - LSIState *s = DO_UPCAST(LSIState, dev, pci_dev); - - DPRINTF("Mapping registers at %08"FMT_PCIBUS"\n", addr); - cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr); -} +static const MemoryRegionOps lsi_io_ops = { + .read = lsi_io_read, + .write = lsi_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; static void lsi_scsi_reset(DeviceState *dev) { @@ -2131,7 +1998,7 @@ static const VMStateDescription vmstate_lsi_scsi = { VMSTATE_PCI_DEVICE(dev, LSIState), VMSTATE_INT32(carry, LSIState), - VMSTATE_INT32(sense, LSIState), + VMSTATE_INT32(status, LSIState), VMSTATE_INT32(msg_action, LSIState), VMSTATE_INT32(msg_len, LSIState), VMSTATE_BUFFER(msg, LSIState), @@ -2208,12 +2075,23 @@ static int lsi_scsi_uninit(PCIDevice *d) { LSIState *s = DO_UPCAST(LSIState, dev, d); - cpu_unregister_io_memory(s->mmio_io_addr); - cpu_unregister_io_memory(s->ram_io_addr); + memory_region_destroy(&s->mmio_io); + memory_region_destroy(&s->ram_io); + memory_region_destroy(&s->io_io); return 0; } +static const struct SCSIBusInfo lsi_scsi_info = { + .tcq = true, + .max_target = LSI_MAX_DEVS, + .max_lun = 0, /* LUN support is buggy */ + + .transfer_data = lsi_transfer_data, + .complete = lsi_command_complete, + .cancel = lsi_request_cancelled +}; + static int lsi_scsi_init(PCIDevice *dev) { LSIState *s = DO_UPCAST(LSIState, dev, dev); @@ -2221,37 +2099,21 @@ static int lsi_scsi_init(PCIDevice *dev) pci_conf = s->dev.config; - /* PCI Vendor ID (word) */ - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_LSI_LOGIC); - /* PCI device ID (word) */ - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_LSI_53C895A); - /* PCI base class code */ - pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_SCSI); - /* PCI subsystem ID */ - pci_conf[PCI_SUBSYSTEM_ID] = 0x00; - pci_conf[PCI_SUBSYSTEM_ID + 1] = 0x10; /* PCI latency timer = 255 */ pci_conf[PCI_LATENCY_TIMER] = 0xff; - /* TODO: RST# value should be 0 */ - /* Interrupt pin 1 */ + /* Interrupt pin A */ pci_conf[PCI_INTERRUPT_PIN] = 0x01; - s->mmio_io_addr = cpu_register_io_memory(lsi_mmio_readfn, - lsi_mmio_writefn, s, - DEVICE_NATIVE_ENDIAN); - s->ram_io_addr = cpu_register_io_memory(lsi_ram_readfn, - lsi_ram_writefn, s, - DEVICE_NATIVE_ENDIAN); - - pci_register_bar(&s->dev, 0, 256, - PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc); - pci_register_bar(&s->dev, 1, 0x400, - PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_mmio_mapfunc); - pci_register_bar(&s->dev, 2, 0x2000, - PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc); + memory_region_init_io(&s->mmio_io, &lsi_mmio_ops, s, "lsi-mmio", 0x400); + memory_region_init_io(&s->ram_io, &lsi_ram_ops, s, "lsi-ram", 0x2000); + memory_region_init_io(&s->io_io, &lsi_io_ops, s, "lsi-io", 256); + + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io); + pci_register_bar(&s->dev, 1, 0, &s->mmio_io); + pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io); QTAILQ_INIT(&s->queue); - scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete); + scsi_bus_new(&s->bus, &dev->qdev, &lsi_scsi_info); if (!dev->qdev.hotplugged) { return scsi_bus_legacy_handle_cmdline(&s->bus); } @@ -2266,6 +2128,10 @@ static PCIDeviceInfo lsi_info = { .qdev.vmsd = &vmstate_lsi_scsi, .init = lsi_scsi_init, .exit = lsi_scsi_uninit, + .vendor_id = PCI_VENDOR_ID_LSI_LOGIC, + .device_id = PCI_DEVICE_ID_LSI_53C895A, + .class_id = PCI_CLASS_STORAGE_SCSI, + .subsystem_id = 0x1000, }; static void lsi53c895a_register_devices(void) diff --git a/hw/m48t59.c b/hw/m48t59.c index 2020487..a77937e 100644 --- a/hw/m48t59.c +++ b/hw/m48t59.c @@ -50,8 +50,6 @@ */ struct M48t59State { - /* Model parameters */ - uint32_t type; // 2 = m48t02, 8 = m48t08, 59 = m48t59 /* Hardware parameters */ qemu_irq IRQ; uint32_t io_base; @@ -64,14 +62,18 @@ struct M48t59State { struct QEMUTimer *alrm_timer; struct QEMUTimer *wd_timer; /* NVRAM storage */ - uint8_t lock; - uint16_t addr; uint8_t *buffer; + /* Model parameters */ + uint32_t type; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */ + /* NVRAM storage */ + uint16_t addr; + uint8_t lock; }; typedef struct M48t59ISAState { ISADevice busdev; M48t59State state; + MemoryRegion io; } M48t59ISAState; typedef struct M48t59SysBusState { @@ -123,7 +125,7 @@ static void alarm_cb (void *opaque) /* Repeat once a second */ next_time = 1; } - qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock_ns(vm_clock) + next_time * 1000); qemu_set_irq(NVRAM->IRQ, 0); } @@ -478,7 +480,6 @@ static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) { M48t59State *NVRAM = opaque; - addr -= NVRAM->io_base; NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val); switch (addr) { case 0: @@ -490,7 +491,7 @@ static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) NVRAM->addr |= val << 8; break; case 3: - m48t59_write(NVRAM, val, NVRAM->addr); + m48t59_write(NVRAM, NVRAM->addr, val); NVRAM->addr = 0x0000; break; default: @@ -503,7 +504,6 @@ static uint32_t NVRAM_readb (void *opaque, uint32_t addr) M48t59State *NVRAM = opaque; uint32_t retval; - addr -= NVRAM->io_base; switch (addr) { case 3: retval = m48t59_read(NVRAM, NVRAM->addr); @@ -585,28 +585,18 @@ static CPUReadMemoryFunc * const nvram_read[] = { &nvram_readl, }; -static void m48t59_save(QEMUFile *f, void *opaque) -{ - M48t59State *s = opaque; - - qemu_put_8s(f, &s->lock); - qemu_put_be16s(f, &s->addr); - qemu_put_buffer(f, s->buffer, s->size); -} - -static int m48t59_load(QEMUFile *f, void *opaque, int version_id) -{ - M48t59State *s = opaque; - - if (version_id != 1) - return -EINVAL; - - qemu_get_8s(f, &s->lock); - qemu_get_be16s(f, &s->addr); - qemu_get_buffer(f, s->buffer, s->size); - - return 0; -} +static const VMStateDescription vmstate_m48t59 = { + .name = "m48t59", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(lock, M48t59State), + VMSTATE_UINT16(addr, M48t59State), + VMSTATE_VBUFFER_UINT32(buffer, M48t59State, 0, NULL, 0, size), + VMSTATE_END_OF_LIST() + } +}; static void m48t59_reset_common(M48t59State *NVRAM) { @@ -635,6 +625,15 @@ static void m48t59_reset_sysbus(DeviceState *d) m48t59_reset_common(NVRAM); } +static const MemoryRegionPortio m48t59_portio[] = { + {0, 4, 1, .read = NVRAM_readb, .write = NVRAM_writeb }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionOps m48t59_io_ops = { + .old_portio = m48t59_portio, +}; + /* Initialisation routine */ M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base, uint32_t io_base, uint16_t size, int type) @@ -678,10 +677,9 @@ M48t59State *m48t59_init_isa(uint32_t io_base, uint16_t size, int type) d = DO_UPCAST(M48t59ISAState, busdev, dev); s = &d->state; + memory_region_init_io(&d->io, &m48t59_io_ops, s, "m48t59", 4); if (io_base != 0) { - register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s); - register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s); - isa_init_ioport_range(dev, io_base, 4); + isa_register_ioport(dev, &d->io, io_base); } return s; @@ -689,14 +687,14 @@ M48t59State *m48t59_init_isa(uint32_t io_base, uint16_t size, int type) static void m48t59_init_common(M48t59State *s) { - s->buffer = qemu_mallocz(s->size); + s->buffer = g_malloc0(s->size); if (s->type == 59) { - s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s); - s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s); + s->alrm_timer = qemu_new_timer_ns(vm_clock, &alarm_cb, s); + s->wd_timer = qemu_new_timer_ns(vm_clock, &watchdog_cb, s); } qemu_get_timedate(&s->alarm, 0); - register_savevm(NULL, "m48t59", -1, 1, m48t59_save, m48t59_load, s); + vmstate_register(NULL, -1, &vmstate_m48t59, s); } static int m48t59_init_isa1(ISADevice *dev) diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index 5680fa9..1791ec1 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -165,6 +165,11 @@ typedef struct DBDMA_channel { int processing; } DBDMA_channel; +typedef struct { + MemoryRegion mem; + DBDMA_channel channels[DBDMA_CHANNELS]; +} DBDMAState; + #ifdef DEBUG_DBDMA static void dump_dbdma_cmd(dbdma_cmd *cmd) { @@ -617,31 +622,34 @@ static void channel_run(DBDMA_channel *ch) } } -static void DBDMA_run (DBDMA_channel *ch) +static void DBDMA_run(DBDMAState *s) { int channel; - for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) { - uint32_t status = ch->regs[DBDMA_STATUS]; - if (!ch->processing && (status & RUN) && (status & ACTIVE)) - channel_run(ch); + for (channel = 0; channel < DBDMA_CHANNELS; channel++) { + DBDMA_channel *ch = &s->channels[channel]; + uint32_t status = ch->regs[DBDMA_STATUS]; + if (!ch->processing && (status & RUN) && (status & ACTIVE)) { + channel_run(ch); + } } } static void DBDMA_run_bh(void *opaque) { - DBDMA_channel *ch = opaque; + DBDMAState *s = opaque; DBDMA_DPRINTF("DBDMA_run_bh\n"); - DBDMA_run(ch); + DBDMA_run(s); } void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, DBDMA_rw rw, DBDMA_flush flush, void *opaque) { - DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan; + DBDMAState *s = dbdma; + DBDMA_channel *ch = &s->channels[nchan]; DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan); @@ -653,11 +661,6 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, ch->io.channel = ch; } -void DBDMA_schedule(void) -{ - qemu_notify_event(); -} - static void dbdma_control_write(DBDMA_channel *ch) { @@ -696,11 +699,12 @@ dbdma_control_write(DBDMA_channel *ch) ch->flush(&ch->io); } -static void dbdma_writel (void *opaque, - target_phys_addr_t addr, uint32_t value) +static void dbdma_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { int channel = addr >> DBDMA_CHANNEL_SHIFT; - DBDMA_channel *ch = (DBDMA_channel *)opaque + channel; + DBDMAState *s = opaque; + DBDMA_channel *ch = &s->channels[channel]; int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value); @@ -745,11 +749,13 @@ static void dbdma_writel (void *opaque, } } -static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr) +static uint64_t dbdma_read(void *opaque, target_phys_addr_t addr, + unsigned size) { uint32_t value; int channel = addr >> DBDMA_CHANNEL_SHIFT; - DBDMA_channel *ch = (DBDMA_channel *)opaque + channel; + DBDMAState *s = opaque; + DBDMA_channel *ch = &s->channels[channel]; int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; value = ch->regs[reg]; @@ -789,61 +795,57 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr) return value; } -static CPUWriteMemoryFunc * const dbdma_write[] = { - NULL, - NULL, - dbdma_writel, +static const MemoryRegionOps dbdma_ops = { + .read = dbdma_read, + .write = dbdma_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; -static CPUReadMemoryFunc * const dbdma_read[] = { - NULL, - NULL, - dbdma_readl, +static const VMStateDescription vmstate_dbdma_channel = { + .name = "dbdma_channel", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, struct DBDMA_channel, DBDMA_REGS), + VMSTATE_END_OF_LIST() + } }; -static void dbdma_save(QEMUFile *f, void *opaque) -{ - DBDMA_channel *s = opaque; - unsigned int i, j; - - for (i = 0; i < DBDMA_CHANNELS; i++) - for (j = 0; j < DBDMA_REGS; j++) - qemu_put_be32s(f, &s[i].regs[j]); -} - -static int dbdma_load(QEMUFile *f, void *opaque, int version_id) -{ - DBDMA_channel *s = opaque; - unsigned int i, j; - - if (version_id != 2) - return -EINVAL; - - for (i = 0; i < DBDMA_CHANNELS; i++) - for (j = 0; j < DBDMA_REGS; j++) - qemu_get_be32s(f, &s[i].regs[j]); - - return 0; -} +static const VMStateDescription vmstate_dbdma = { + .name = "dbdma", + .version_id = 2, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(channels, DBDMAState, DBDMA_CHANNELS, 1, + vmstate_dbdma_channel, DBDMA_channel), + VMSTATE_END_OF_LIST() + } +}; static void dbdma_reset(void *opaque) { - DBDMA_channel *s = opaque; + DBDMAState *s = opaque; int i; for (i = 0; i < DBDMA_CHANNELS; i++) - memset(s[i].regs, 0, DBDMA_SIZE); + memset(s->channels[i].regs, 0, DBDMA_SIZE); } -void* DBDMA_init (int *dbdma_mem_index) +void* DBDMA_init (MemoryRegion **dbdma_mem) { - DBDMA_channel *s; + DBDMAState *s; - s = qemu_mallocz(sizeof(DBDMA_channel) * DBDMA_CHANNELS); + s = g_malloc0(sizeof(DBDMAState)); - *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s, - DEVICE_LITTLE_ENDIAN); - register_savevm(NULL, "dbdma", -1, 1, dbdma_save, dbdma_load, s); + memory_region_init_io(&s->mem, &dbdma_ops, s, "dbdma", 0x1000); + *dbdma_mem = &s->mem; + vmstate_register(NULL, -1, &vmstate_dbdma, s); qemu_register_reset(dbdma_reset, s); dbdma_bh = qemu_bh_new(DBDMA_run_bh, s); diff --git a/hw/mac_dbdma.h b/hw/mac_dbdma.h index d236c5b..6d1abe6 100644 --- a/hw/mac_dbdma.h +++ b/hw/mac_dbdma.h @@ -20,6 +20,8 @@ * THE SOFTWARE. */ +#include "memory.h" + typedef struct DBDMA_io DBDMA_io; typedef void (*DBDMA_flush)(DBDMA_io *io); @@ -39,5 +41,4 @@ struct DBDMA_io { void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, DBDMA_rw rw, DBDMA_flush flush, void *opaque); -void DBDMA_schedule(void); -void* DBDMA_init (int *dbdma_mem_index); +void* DBDMA_init (MemoryRegion **dbdma_mem); diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c index c2a2fc2..ed0a2b7 100644 --- a/hw/mac_nvram.c +++ b/hw/mac_nvram.c @@ -38,8 +38,8 @@ #endif struct MacIONVRAMState { - target_phys_addr_t size; - int mem_index; + uint32_t size; + MemoryRegion mem; unsigned int it_shift; uint8_t *data; }; @@ -71,8 +71,8 @@ void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val) } /* macio style NVRAM device */ -static void macio_nvram_writeb (void *opaque, - target_phys_addr_t addr, uint32_t value) +static void macio_nvram_writeb(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { MacIONVRAMState *s = opaque; @@ -81,7 +81,8 @@ static void macio_nvram_writeb (void *opaque, NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value); } -static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr) +static uint64_t macio_nvram_readb(void *opaque, target_phys_addr_t addr, + unsigned size) { MacIONVRAMState *s = opaque; uint32_t value; @@ -93,68 +94,50 @@ static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr) return value; } -static CPUWriteMemoryFunc * const nvram_write[] = { - &macio_nvram_writeb, - &macio_nvram_writeb, - &macio_nvram_writeb, +static const MemoryRegionOps macio_nvram_ops = { + .read = macio_nvram_readb, + .write = macio_nvram_writeb, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUReadMemoryFunc * const nvram_read[] = { - &macio_nvram_readb, - &macio_nvram_readb, - &macio_nvram_readb, +static const VMStateDescription vmstate_macio_nvram = { + .name = "macio_nvram", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_VBUFFER_UINT32(data, MacIONVRAMState, 0, NULL, 0, size), + VMSTATE_END_OF_LIST() + } }; -static void macio_nvram_save(QEMUFile *f, void *opaque) -{ - MacIONVRAMState *s = (MacIONVRAMState *)opaque; - - qemu_put_buffer(f, s->data, s->size); -} - -static int macio_nvram_load(QEMUFile *f, void *opaque, int version_id) -{ - MacIONVRAMState *s = (MacIONVRAMState *)opaque; - - if (version_id != 1) - return -EINVAL; - - qemu_get_buffer(f, s->data, s->size); - - return 0; -} static void macio_nvram_reset(void *opaque) { } -MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size, +MacIONVRAMState *macio_nvram_init (target_phys_addr_t size, unsigned int it_shift) { MacIONVRAMState *s; - s = qemu_mallocz(sizeof(MacIONVRAMState)); - s->data = qemu_mallocz(size); + s = g_malloc0(sizeof(MacIONVRAMState)); + s->data = g_malloc0(size); s->size = size; s->it_shift = it_shift; - s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s, - DEVICE_NATIVE_ENDIAN); - *mem_index = s->mem_index; - register_savevm(NULL, "macio_nvram", -1, 1, macio_nvram_save, - macio_nvram_load, s); + memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram", + size << it_shift); + vmstate_register(NULL, -1, &vmstate_macio_nvram, s); qemu_register_reset(macio_nvram_reset, s); return s; } -void macio_nvram_map (void *opaque, target_phys_addr_t mem_base) +void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar, + target_phys_addr_t mem_base) { - MacIONVRAMState *s; - - s = opaque; - cpu_register_physical_memory(mem_base, s->size << s->it_shift, - s->mem_index); + memory_region_add_subregion(bar, mem_base, &s->mem); } /* Set up a system OpenBIOS NVRAM partition */ diff --git a/hw/macio.c b/hw/macio.c index 789ca55..cc6ae40 100644 --- a/hw/macio.c +++ b/hw/macio.c @@ -30,58 +30,55 @@ typedef struct macio_state_t macio_state_t; struct macio_state_t { int is_oldworld; - int pic_mem_index; - int dbdma_mem_index; - int cuda_mem_index; - int escc_mem_index; + MemoryRegion bar; + MemoryRegion *pic_mem; + MemoryRegion *dbdma_mem; + MemoryRegion *cuda_mem; + MemoryRegion *escc_mem; void *nvram; int nb_ide; - int ide_mem_index[4]; + MemoryRegion *ide_mem[4]; }; -static void macio_map (PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void macio_bar_setup(macio_state_t *macio_state) { - macio_state_t *macio_state; int i; + MemoryRegion *bar = &macio_state->bar; - macio_state = (macio_state_t *)(pci_dev + 1); - if (macio_state->pic_mem_index >= 0) { + memory_region_init(bar, "macio", 0x80000); + if (macio_state->pic_mem) { if (macio_state->is_oldworld) { /* Heathrow PIC */ - cpu_register_physical_memory(addr + 0x00000, 0x1000, - macio_state->pic_mem_index); + memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem); } else { /* OpenPIC */ - cpu_register_physical_memory(addr + 0x40000, 0x40000, - macio_state->pic_mem_index); + memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem); } } - if (macio_state->dbdma_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x08000, 0x1000, - macio_state->dbdma_mem_index); + if (macio_state->dbdma_mem) { + memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem); } - if (macio_state->escc_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE << 4, - macio_state->escc_mem_index); + if (macio_state->escc_mem) { + memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem); } - if (macio_state->cuda_mem_index >= 0) { - cpu_register_physical_memory(addr + 0x16000, 0x2000, - macio_state->cuda_mem_index); + if (macio_state->cuda_mem) { + memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem); } for (i = 0; i < macio_state->nb_ide; i++) { - if (macio_state->ide_mem_index[i] >= 0) { - cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000, - macio_state->ide_mem_index[i]); + if (macio_state->ide_mem[i]) { + memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000), + macio_state->ide_mem[i]); } } if (macio_state->nvram != NULL) - macio_nvram_map(macio_state->nvram, addr + 0x60000); + macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000); } -void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, - int dbdma_mem_index, int cuda_mem_index, void *nvram, - int nb_ide, int *ide_mem_index, int escc_mem_index) +void macio_init (PCIBus *bus, int device_id, int is_oldworld, + MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, + MemoryRegion *cuda_mem, void *nvram, + int nb_ide, MemoryRegion **ide_mem, + MemoryRegion *escc_mem) { PCIDevice *d; macio_state_t *macio_state; @@ -92,18 +89,18 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, -1, NULL, NULL); macio_state = (macio_state_t *)(d + 1); macio_state->is_oldworld = is_oldworld; - macio_state->pic_mem_index = pic_mem_index; - macio_state->dbdma_mem_index = dbdma_mem_index; - macio_state->cuda_mem_index = cuda_mem_index; - macio_state->escc_mem_index = escc_mem_index; + macio_state->pic_mem = pic_mem; + macio_state->dbdma_mem = dbdma_mem; + macio_state->cuda_mem = cuda_mem; + macio_state->escc_mem = escc_mem; macio_state->nvram = nvram; if (nb_ide > 4) nb_ide = 4; macio_state->nb_ide = nb_ide; for (i = 0; i < nb_ide; i++) - macio_state->ide_mem_index[i] = ide_mem_index[i]; + macio_state->ide_mem[i] = ide_mem[i]; for (; i < 4; i++) - macio_state->ide_mem_index[i] = -1; + macio_state->ide_mem[i] = NULL; /* Note: this code is strongly inspirated from the corresponding code in PearPC */ @@ -113,6 +110,6 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, d->config[0x3d] = 0x01; // interrupt on pin 1 - pci_register_bar(d, 0, 0x80000, - PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map); + macio_bar_setup(macio_state); + pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar); } diff --git a/hw/mainstone.c b/hw/mainstone.c index 58e3f86..3ed6649 100644 --- a/hw/mainstone.c +++ b/hw/mainstone.c @@ -14,10 +14,32 @@ #include "net.h" #include "devices.h" #include "boards.h" -#include "mainstone.h" -#include "sysemu.h" #include "flash.h" #include "blockdev.h" +#include "sysbus.h" +#include "exec-memory.h" + +/* Device addresses */ +#define MST_FPGA_PHYS 0x08000000 +#define MST_ETH_PHYS 0x10000300 +#define MST_FLASH_0 0x00000000 +#define MST_FLASH_1 0x04000000 + +/* IRQ definitions */ +#define MMC_IRQ 0 +#define USIM_IRQ 1 +#define USBC_IRQ 2 +#define ETHERNET_IRQ 3 +#define AC97_IRQ 4 +#define PEN_IRQ 5 +#define MSINS_IRQ 6 +#define EXBRD_IRQ 7 +#define S0_CD_IRQ 9 +#define S0_STSCHG_IRQ 10 +#define S0_IRQ 11 +#define S1_CD_IRQ 13 +#define S1_STSCHG_IRQ 14 +#define S1_IRQ 15 static struct keymap map[0xE0] = { [0 ... 0xDF] = { -1, -1 }, @@ -69,7 +91,8 @@ static struct arm_boot_info mainstone_binfo = { .ram_size = 0x04000000, }; -static void mainstone_common_init(ram_addr_t ram_size, +static void mainstone_common_init(MemoryRegion *address_space_mem, + ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum mainstone_model_e model, int arm_id) @@ -77,19 +100,20 @@ static void mainstone_common_init(ram_addr_t ram_size, uint32_t sector_len = 256 * 1024; target_phys_addr_t mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 }; PXA2xxState *cpu; - qemu_irq *mst_irq; + DeviceState *mst_irq; DriveInfo *dinfo; int i; int be; + MemoryRegion *rom = g_new(MemoryRegion, 1); if (!cpu_model) cpu_model = "pxa270-c5"; /* Setup CPU & memory */ - cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model); - cpu_register_physical_memory(0, MAINSTONE_ROM, - qemu_ram_alloc(NULL, "mainstone.rom", - MAINSTONE_ROM) | IO_MEM_ROM); + cpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, cpu_model); + memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM); + memory_region_set_readonly(rom, true); + memory_region_add_subregion(address_space_mem, 0, rom); #ifdef TARGET_WORDS_BIGENDIAN be = 1; @@ -105,10 +129,9 @@ static void mainstone_common_init(ram_addr_t ram_size, exit(1); } - if (!pflash_cfi01_register(mainstone_flash_base[i], - qemu_ram_alloc(NULL, i ? "mainstone.flash1" : - "mainstone.flash0", - MAINSTONE_FLASH), + if (!pflash_cfi01_register(mainstone_flash_base[i], NULL, + i ? "mainstone.flash1" : "mainstone.flash0", + MAINSTONE_FLASH, dinfo->bdrv, sector_len, MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0, be)) { @@ -117,16 +140,25 @@ static void mainstone_common_init(ram_addr_t ram_size, } } - mst_irq = mst_irq_init(cpu, MST_FPGA_PHYS, PXA2XX_PIC_GPIO_0); + mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS, + qdev_get_gpio_in(cpu->gpio, 0)); /* setup keypad */ printf("map addr %p\n", &map); pxa27x_register_keypad(cpu->kp, map, 0xe0); /* MMC/SD host */ - pxa2xx_mmci_handlers(cpu->mmc, NULL, mst_irq[MMC_IRQ]); + pxa2xx_mmci_handlers(cpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ)); - smc91c111_init(&nd_table[0], MST_ETH_PHYS, mst_irq[ETHERNET_IRQ]); + pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0], + qdev_get_gpio_in(mst_irq, S0_IRQ), + qdev_get_gpio_in(mst_irq, S0_CD_IRQ)); + pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1], + qdev_get_gpio_in(mst_irq, S1_IRQ), + qdev_get_gpio_in(mst_irq, S1_CD_IRQ)); + + smc91c111_init(&nd_table[0], MST_ETH_PHYS, + qdev_get_gpio_in(mst_irq, ETHERNET_IRQ)); mainstone_binfo.kernel_filename = kernel_filename; mainstone_binfo.kernel_cmdline = kernel_cmdline; @@ -140,7 +172,7 @@ static void mainstone_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - mainstone_common_init(ram_size, kernel_filename, + mainstone_common_init(get_system_memory(), ram_size, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196); } diff --git a/hw/mainstone.h b/hw/mainstone.h deleted file mode 100644 index 9618c06..0000000 --- a/hw/mainstone.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * PXA270-based Intel Mainstone platforms. - * - * Copyright (c) 2007 by Armin Kuster or - * - * - * This code is licensed under the GNU GPL v2. - */ - -#ifndef __MAINSTONE_H__ -#define __MAINSTONE_H__ - -/* Device addresses */ -#define MST_FPGA_PHYS 0x08000000 -#define MST_ETH_PHYS 0x10000300 -#define MST_FLASH_0 0x00000000 -#define MST_FLASH_1 0x04000000 - -/* IRQ definitions */ -#define MMC_IRQ 0 -#define USIM_IRQ 1 -#define USBC_IRQ 2 -#define ETHERNET_IRQ 3 -#define AC97_IRQ 4 -#define PEN_IRQ 5 -#define MSINS_IRQ 6 -#define EXBRD_IRQ 7 -#define S0_CD_IRQ 9 -#define S0_STSCHG_IRQ 10 -#define S0_IRQ 11 -#define S1_CD_IRQ 13 -#define S1_STSCHG_IRQ 14 -#define S1_IRQ 15 - -extern qemu_irq -*mst_irq_init(PXA2xxState *cpu, uint32_t base, int irq); - -#endif /* __MAINSTONE_H__ */ diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c index 3eff925..f8c5242 100644 --- a/hw/marvell_88w8618_audio.c +++ b/hw/marvell_88w8618_audio.c @@ -4,7 +4,7 @@ * * Copyright (c) 2008 Jan Kiszka * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #include "sysbus.h" #include "hw.h" diff --git a/hw/max111x.c b/hw/max111x.c index 2844665..70cd1af 100644 --- a/hw/max111x.c +++ b/hw/max111x.c @@ -15,7 +15,7 @@ typedef struct { uint8_t tb1, rb2, rb3; int cycle; - int input[8]; + uint8_t input[8]; int inputs, com; } MAX111xState; @@ -94,36 +94,22 @@ static uint32_t max111x_transfer(SSISlave *dev, uint32_t value) return max111x_read(s); } -static void max111x_save(QEMUFile *f, void *opaque) -{ - MAX111xState *s = (MAX111xState *) opaque; - int i; - - qemu_put_8s(f, &s->tb1); - qemu_put_8s(f, &s->rb2); - qemu_put_8s(f, &s->rb3); - qemu_put_be32(f, s->inputs); - qemu_put_be32(f, s->com); - for (i = 0; i < s->inputs; i ++) - qemu_put_byte(f, s->input[i]); -} - -static int max111x_load(QEMUFile *f, void *opaque, int version_id) -{ - MAX111xState *s = (MAX111xState *) opaque; - int i; - - qemu_get_8s(f, &s->tb1); - qemu_get_8s(f, &s->rb2); - qemu_get_8s(f, &s->rb3); - if (s->inputs != qemu_get_be32(f)) - return -EINVAL; - s->com = qemu_get_be32(f); - for (i = 0; i < s->inputs; i ++) - s->input[i] = qemu_get_byte(f); - - return 0; -} +static const VMStateDescription vmstate_max111x = { + .name = "max111x", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT8(tb1, MAX111xState), + VMSTATE_UINT8(rb2, MAX111xState), + VMSTATE_UINT8(rb3, MAX111xState), + VMSTATE_INT32_EQUAL(inputs, MAX111xState), + VMSTATE_INT32(com, MAX111xState), + VMSTATE_ARRAY_INT32_UNSAFE(input, MAX111xState, inputs, + vmstate_info_uint8, uint8_t), + VMSTATE_END_OF_LIST() + } +}; static int max111x_init(SSISlave *dev, int inputs) { @@ -143,8 +129,7 @@ static int max111x_init(SSISlave *dev, int inputs) s->input[7] = 0x80; s->com = 0; - register_savevm(&dev->qdev, "max111x", -1, 0, - max111x_save, max111x_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_max111x, s); return 0; } diff --git a/hw/max7310.c b/hw/max7310.c index c302eb6..c1bdb2e 100644 --- a/hw/max7310.c +++ b/hw/max7310.c @@ -23,9 +23,9 @@ typedef struct { qemu_irq *gpio_in; } MAX7310State; -void max7310_reset(i2c_slave *i2c) +static void max7310_reset(DeviceState *dev) { - MAX7310State *s = (MAX7310State *) i2c; + MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, I2C_SLAVE_FROM_QDEV(dev)); s->level &= s->direction; s->direction = 0xff; s->polarity = 0xf0; @@ -179,33 +179,17 @@ static int max7310_init(i2c_slave *i2c) { MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, i2c); - s->gpio_in = qemu_allocate_irqs(max7310_gpio_set, s, - ARRAY_SIZE(s->handler)); - - max7310_reset(&s->i2c); + qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8); + qdev_init_gpio_out(&i2c->qdev, s->handler, 8); return 0; } -qemu_irq *max7310_gpio_in_get(i2c_slave *i2c) -{ - MAX7310State *s = (MAX7310State *) i2c; - return s->gpio_in; -} - -void max7310_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler) -{ - MAX7310State *s = (MAX7310State *) i2c; - if (line >= ARRAY_SIZE(s->handler) || line < 0) - hw_error("bad GPIO line"); - - s->handler[line] = handler; -} - static I2CSlaveInfo max7310_info = { .qdev.name = "max7310", .qdev.size = sizeof(MAX7310State), .qdev.vmsd = &vmstate_max7310, + .qdev.reset = max7310_reset, .init = max7310_init, .event = max7310_event, .recv = max7310_rx, diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index a1b0e31..2aaca2f 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -81,6 +81,7 @@ typedef struct RTCState { ISADevice dev; + MemoryRegion io; uint8_t cmos_data[128]; uint8_t cmos_index; struct tm current_tm; @@ -99,6 +100,7 @@ typedef struct RTCState { QEMUTimer *coalesced_timer; QEMUTimer *second_timer; QEMUTimer *second_timer2; + Notifier clock_reset_notifier; } RTCState; static void rtc_set_time(RTCState *s); @@ -112,7 +114,7 @@ static void rtc_coalesced_timer_update(RTCState *s) } else { /* divide each RTC interval to 2 - 8 smaller intervals */ int c = MIN(s->irq_coalesced, 7) + 1; - int64_t next_clock = qemu_get_clock(rtc_clock) + + int64_t next_clock = qemu_get_clock_ns(rtc_clock) + muldiv64(s->period / c, get_ticks_per_sec(), 32768); qemu_mod_timer(s->coalesced_timer, next_clock); } @@ -234,7 +236,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data) /* UIP bit is read only */ s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) | (s->cmos_data[RTC_REG_A] & REG_A_UIP); - rtc_timer_update(s, qemu_get_clock(rtc_clock)); + rtc_timer_update(s, qemu_get_clock_ns(rtc_clock)); break; case RTC_REG_B: if (data & REG_B_SET) { @@ -256,7 +258,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data) } else { s->cmos_data[RTC_REG_B] = data; } - rtc_timer_update(s, qemu_get_clock(rtc_clock)); + rtc_timer_update(s, qemu_get_clock_ns(rtc_clock)); break; case RTC_REG_C: case RTC_REG_D: @@ -572,6 +574,22 @@ static const VMStateDescription vmstate_rtc = { } }; +static void rtc_notify_clock_reset(Notifier *notifier, void *data) +{ + RTCState *s = container_of(notifier, RTCState, clock_reset_notifier); + int64_t now = *(int64_t *)data; + + rtc_set_date_from_host(&s->dev); + s->next_second_time = now + (get_ticks_per_sec() * 99) / 100; + qemu_mod_timer(s->second_timer2, s->next_second_time); + rtc_timer_update(s, now); +#ifdef TARGET_I386 + if (rtc_td_hack) { + rtc_coalesced_timer_update(s); + } +#endif +} + static void rtc_reset(void *opaque) { RTCState *s = opaque; @@ -587,6 +605,15 @@ static void rtc_reset(void *opaque) #endif } +static const MemoryRegionPortio cmos_portio[] = { + {0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionOps cmos_ops = { + .old_portio = cmos_portio +}; + static int rtc_initfn(ISADevice *dev) { RTCState *s = DO_UPCAST(RTCState, dev, dev); @@ -599,22 +626,24 @@ static int rtc_initfn(ISADevice *dev) rtc_set_date_from_host(dev); - s->periodic_timer = qemu_new_timer(rtc_clock, rtc_periodic_timer, s); + s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s); #ifdef TARGET_I386 if (rtc_td_hack) s->coalesced_timer = - qemu_new_timer(rtc_clock, rtc_coalesced_timer, s); + qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s); #endif - s->second_timer = qemu_new_timer(rtc_clock, rtc_update_second, s); - s->second_timer2 = qemu_new_timer(rtc_clock, rtc_update_second2, s); + s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s); + s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s); + + s->clock_reset_notifier.notify = rtc_notify_clock_reset; + qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier); s->next_second_time = - qemu_get_clock(rtc_clock) + (get_ticks_per_sec() * 99) / 100; + qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100; qemu_mod_timer(s->second_timer2, s->next_second_time); - register_ioport_write(base, 2, 1, cmos_ioport_write, s); - register_ioport_read(base, 2, 1, cmos_ioport_read, s); - isa_init_ioport_range(dev, base, 2); + memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2); + isa_register_ioport(dev, &s->io, base); qdev_set_legacy_instance_id(&dev->qdev, base, 2); qemu_register_reset(rtc_reset, s); diff --git a/hw/mcf5206.c b/hw/mcf5206.c index 2a618d4..15d6f22 100644 --- a/hw/mcf5206.c +++ b/hw/mcf5206.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "hw.h" #include "mcf.h" @@ -132,7 +132,7 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq) m5206_timer_state *s; QEMUBH *bh; - s = (m5206_timer_state *)qemu_mallocz(sizeof(m5206_timer_state)); + s = (m5206_timer_state *)g_malloc0(sizeof(m5206_timer_state)); bh = qemu_bh_new(m5206_timer_trigger, s); s->timer = ptimer_init(bh); s->irq = irq; @@ -523,7 +523,7 @@ qemu_irq *mcf5206_init(uint32_t base, CPUState *env) qemu_irq *pic; int iomemtype; - s = (m5206_mbar_state *)qemu_mallocz(sizeof(m5206_mbar_state)); + s = (m5206_mbar_state *)g_malloc0(sizeof(m5206_mbar_state)); iomemtype = cpu_register_io_memory(m5206_mbar_readfn, m5206_mbar_writefn, s, DEVICE_NATIVE_ENDIAN); diff --git a/hw/mcf5208.c b/hw/mcf5208.c index 17a692d..1c2c0c4 100644 --- a/hw/mcf5208.c +++ b/hw/mcf5208.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "hw.h" #include "mcf.h" @@ -13,6 +13,7 @@ #include "boards.h" #include "loader.h" #include "elf.h" +#include "exec-memory.h" #define SYS_FREQ 66000000 @@ -27,6 +28,7 @@ #define PCSR_PRE_MASK 0x0f00 typedef struct { + MemoryRegion iomem; qemu_irq irq; ptimer_state *timer; uint16_t pcsr; @@ -43,7 +45,7 @@ static void m5208_timer_update(m5208_timer_state *s) } static void m5208_timer_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { m5208_timer_state *s = (m5208_timer_state *)opaque; int prescale; @@ -104,7 +106,8 @@ static void m5208_timer_trigger(void *opaque) m5208_timer_update(s); } -static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr) +static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr, + unsigned size) { m5208_timer_state *s = (m5208_timer_state *)opaque; switch (addr) { @@ -120,19 +123,14 @@ static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr) } } -static CPUReadMemoryFunc * const m5208_timer_readfn[] = { - m5208_timer_read, - m5208_timer_read, - m5208_timer_read +static const MemoryRegionOps m5208_timer_ops = { + .read = m5208_timer_read, + .write = m5208_timer_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const m5208_timer_writefn[] = { - m5208_timer_write, - m5208_timer_write, - m5208_timer_write -}; - -static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr) +static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr, + unsigned size) { switch (addr) { case 0x110: /* SDCS0 */ @@ -154,45 +152,36 @@ static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr) } static void m5208_sys_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { hw_error("m5208_sys_write: Bad offset 0x%x\n", (int)addr); } -static CPUReadMemoryFunc * const m5208_sys_readfn[] = { - m5208_sys_read, - m5208_sys_read, - m5208_sys_read -}; - -static CPUWriteMemoryFunc * const m5208_sys_writefn[] = { - m5208_sys_write, - m5208_sys_write, - m5208_sys_write +static const MemoryRegionOps m5208_sys_ops = { + .read = m5208_sys_read, + .write = m5208_sys_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static void mcf5208_sys_init(qemu_irq *pic) +static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic) { - int iomemtype; + MemoryRegion *iomem = g_new(MemoryRegion, 1); m5208_timer_state *s; QEMUBH *bh; int i; - iomemtype = cpu_register_io_memory(m5208_sys_readfn, - m5208_sys_writefn, NULL, - DEVICE_NATIVE_ENDIAN); /* SDRAMC. */ - cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype); + memory_region_init_io(iomem, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000); + memory_region_add_subregion(address_space, 0xfc0a8000, iomem); /* Timers. */ for (i = 0; i < 2; i++) { - s = (m5208_timer_state *)qemu_mallocz(sizeof(m5208_timer_state)); + s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state)); bh = qemu_bh_new(m5208_timer_trigger, s); s->timer = ptimer_init(bh); - iomemtype = cpu_register_io_memory(m5208_timer_readfn, - m5208_timer_writefn, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000, - iomemtype); + memory_region_init_io(&s->iomem, &m5208_timer_ops, s, + "m5208-timer", 0x00004000); + memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i, + &s->iomem); s->irq = pic[4 + i]; } } @@ -207,6 +196,9 @@ static void mcf5208evb_init(ram_addr_t ram_size, uint64_t elf_entry; target_phys_addr_t entry; qemu_irq *pic; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *sram = g_new(MemoryRegion, 1); if (!cpu_model) cpu_model = "m5208"; @@ -221,12 +213,12 @@ static void mcf5208evb_init(ram_addr_t ram_size, /* TODO: Configure BARs. */ /* DRAM at 0x40000000 */ - cpu_register_physical_memory(0x40000000, ram_size, - qemu_ram_alloc(NULL, "mcf5208.ram", ram_size) | IO_MEM_RAM); + memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size); + memory_region_add_subregion(address_space_mem, 0x40000000, ram); /* Internal SRAM. */ - cpu_register_physical_memory(0x80000000, 16384, - qemu_ram_alloc(NULL, "mcf5208.sram", 16384) | IO_MEM_RAM); + memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384); + memory_region_add_subregion(address_space_mem, 0x80000000, sram); /* Internal peripherals. */ pic = mcf_intc_init(0xfc048000, env); @@ -235,7 +227,7 @@ static void mcf5208evb_init(ram_addr_t ram_size, mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]); mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]); - mcf5208_sys_init(pic); + mcf5208_sys_init(address_space_mem, pic); if (nb_nics > 1) { fprintf(stderr, "Too many NICs\n"); diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c index 21035da..42a5d77 100644 --- a/hw/mcf_fec.c +++ b/hw/mcf_fec.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "hw.h" #include "net.h" @@ -447,7 +447,7 @@ static void mcf_fec_cleanup(VLANClientState *nc) cpu_unregister_io_memory(s->mmio_index); - qemu_free(s); + g_free(s); } static NetClientInfo net_mcf_fec_info = { @@ -464,14 +464,14 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq) qemu_check_nic_model(nd, "mcf_fec"); - s = (mcf_fec_state *)qemu_mallocz(sizeof(mcf_fec_state)); + s = (mcf_fec_state *)g_malloc0(sizeof(mcf_fec_state)); s->irq = irq; s->mmio_index = cpu_register_io_memory(mcf_fec_readfn, mcf_fec_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(base, 0x400, s->mmio_index); - memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr)); + s->conf.macaddr = nd->macaddr; s->conf.vlan = nd->vlan; s->conf.peer = nd->netdev; diff --git a/hw/mcf_intc.c b/hw/mcf_intc.c index ac04295..99092e7 100644 --- a/hw/mcf_intc.c +++ b/hw/mcf_intc.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "hw.h" #include "mcf.h" @@ -144,7 +144,7 @@ qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env) mcf_intc_state *s; int iomemtype; - s = qemu_mallocz(sizeof(mcf_intc_state)); + s = g_malloc0(sizeof(mcf_intc_state)); s->env = env; mcf_intc_reset(s); diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c index db57096..e6b2ab0 100644 --- a/hw/mcf_uart.c +++ b/hw/mcf_uart.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "hw.h" #include "mcf.h" @@ -110,7 +110,7 @@ static void mcf_uart_do_tx(mcf_uart_state *s) { if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) { if (s->chr) - qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1); + qemu_chr_fe_write(s->chr, (unsigned char *)&s->tb, 1); s->sr |= MCF_UART_TxEMP; } if (s->tx_enabled) { @@ -272,7 +272,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr) { mcf_uart_state *s; - s = qemu_mallocz(sizeof(mcf_uart_state)); + s = g_malloc0(sizeof(mcf_uart_state)); s->chr = chr; s->irq = irq; if (chr) { diff --git a/hw/mcs5000_tk.c b/hw/mcs5000_tk.c deleted file mode 100644 index c24f1a2..0000000 --- a/hw/mcs5000_tk.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Melfas MCS-5000 Touchkey - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Dmitry Zhurikhin - * Vladimir Monakhov - * - * NB: Only features used in the kernel driver is implemented currently. - * NB2: This device may also be used in touchscreen mode. Not supported now. - */ - -#include "console.h" -#include "i2c-addressable.h" - - -#define MCS5000_TK_LED_ONOFF 0x01 -#define MCS5000_TK_LED_DIMMING 0x02 -#define MCS5000_TK_RESERVED 0x03 -#define MCS5000_TK_VALUE_STATUS 0x04 -#define MCS5000_TK_RESERVED1 0x05 -#define MCS5000_TK_HW_VERSION 0x06 -#define MCS5000_TK_FW_VERSION 0x0A -#define MCS5000_TK_MI_VERSION 0x0B - -#define MCS5000_TK_FW_ADDR 0x7e - - -typedef struct MCS5000State { - - I2CAddressableState i2c_addressable; - - uint8_t hw_version; - uint8_t fw_version; - uint8_t mi_version; - - uint8_t status; - - int32_t download_fw_state; - int32_t download_fw_size; - qemu_irq irq; -} MCS5000State; - - -static int map[0x80]; - -static int universal_tk_keymap[0x80] = { - [0x61] = 100, /* 100 is KEY_PHONE / KEY_SEND */ - [0x62] = 101, /* 101 is KEY_FRONT / KEY_HOME */ - [0x63] = 102, /* 102 is KEY_EXIT / KEY_END */ -}; - - -static void mcs5000_reset(DeviceState *d) -{ - MCS5000State *s = - FROM_I2CADDR_SLAVE(MCS5000State, I2CADDR_SLAVE_FROM_QDEV(d)); - - s->hw_version = 0x9; - s->fw_version = 0x9; - s->mi_version = 0x0; - - s->status = 0; - - s->download_fw_state = 0; - s->download_fw_size = 0; -} - -static uint8_t mcs5000_read(void *opaque, uint32_t address, uint8_t offset) -{ - MCS5000State *s = (MCS5000State *)opaque; - - if (offset > 0) { - hw_error("mcs5000: bad read size\n"); - } - - switch (address) { - case MCS5000_TK_VALUE_STATUS: - return s->status; - case MCS5000_TK_HW_VERSION: - return s->hw_version; - case MCS5000_TK_FW_VERSION: - return s->fw_version; - case MCS5000_TK_MI_VERSION: - return s->mi_version; - case MCS5000_TK_FW_ADDR: - s->download_fw_state++; - switch (s->download_fw_state - 1) { - case 0: /* Request for firmware download */ - return 0x55; - case 1: /* Prepare erase done */ - return 0x8F; - case 2: /* Erase done */ - return 0x82; - case 3: /* Read flash */ - return 0x84; - case 4: /* Check firmware */ - if (s->download_fw_size > 0) { - s->download_fw_size--; - s->download_fw_state = 4; - } - return 0xFF; - case 5: /* Prepare program */ - return 0x8F; - case 6: /* Program flash */ - return 0x83; - case 7: /* Read flash */ - return 0x84; - case 8: /* Verify data */ - /* TODO */ - if (s->download_fw_size > 0) { - s->download_fw_size--; - s->download_fw_state = 8; - } - return 0xFF; - default: - s->download_fw_state = 0; - return 0; - } - default: - hw_error("mcs5000: bad read offset 0x%x\n", address); - } -} - - -static void mcs5000_write(void *opaque, uint32_t address, uint8_t offset, - uint8_t val) -{ - MCS5000State *s = (MCS5000State *)opaque; - - if (offset > 0) { - hw_error("mcs5000: bad write size\n"); - } - - switch (address) { - case MCS5000_TK_LED_ONOFF: - break; - case MCS5000_TK_LED_DIMMING: - break; - case MCS5000_TK_FW_ADDR: - if (s->download_fw_state == 3 || s->download_fw_state == 7) { - s->download_fw_size = val; - } else if (s->download_fw_state == 6) { - /* TODO */ - /* Get firmware image */ - } - break; - default: - hw_error("mcs5000: bad write offset 0x%x\n", address); - } -} - -static int mcs5000_tk_event(void *opaque, int keycode) -{ - MCS5000State *s = (MCS5000State *)opaque; - int k, push = 0; - - push = (keycode & 0x80) ? 0 : 1; /* Key push from qemu */ - keycode &= ~(0x80); /* Strip qemu key release bit */ - - k = map[keycode]; - - /* Don't report unknown keypress */ - if (k < 0) { - return -1; - } - - s->status = k | (push << 7); - qemu_irq_raise(s->irq); - return 0; -} - -static void mcs5000_init_keymap(int keycodes[]) -{ - int i; - - for (i = 0; i < 0x80; i++) { - map[i] = -1; - } - for (i = 0; i < 0x80; i++) { - map[keycodes[i]] = i; - } -} - -static void mcs5000_save(QEMUFile *f, void *opaque) -{ - MCS5000State *s = (MCS5000State *)opaque; - - qemu_put_8s(f, &s->status); - - qemu_put_sbe32s(f, &s->download_fw_state); - qemu_put_sbe32s(f, &s->download_fw_size); -} - -static int mcs5000_load(QEMUFile *f, void *opaque, int version_id) -{ - MCS5000State *s = (MCS5000State *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_8s(f, &s->status); - - qemu_get_sbe32s(f, &s->download_fw_state); - qemu_get_sbe32s(f, &s->download_fw_size); - - return 0; -} - -static int mcs5000_init(I2CAddressableState *s, int keycodes[]) -{ - MCS5000State *t = FROM_I2CADDR_SLAVE(MCS5000State, s); - - qdev_init_gpio_out(&s->i2c.qdev, &t->irq, 1); - qemu_add_kbd_event_handler(mcs5000_tk_event, t, "MCS5000 Touchkey"); - - mcs5000_reset(&s->i2c.qdev); - mcs5000_init_keymap(keycodes); - - register_savevm(&s->i2c.qdev, "mcs5000", -1, 1, - mcs5000_save, mcs5000_load, s); - - return 0; -} - -static int mcs5000_universal_init(I2CAddressableState *i2c) -{ - return mcs5000_init(i2c, universal_tk_keymap); -} - -static I2CAddressableDeviceInfo mcs5000_universal_info = { - .i2c.qdev.name = "mcs5000.universal", - .i2c.qdev.size = sizeof(MCS5000State), - .i2c.qdev.reset = mcs5000_reset, - .init = mcs5000_universal_init, - .read = mcs5000_read, - .write = mcs5000_write, - .size = 1, - .rev = 0 -}; - -static void mcs5000_register_devices(void) -{ - i2c_addressable_register_device(&mcs5000_universal_info); -} - -device_init(mcs5000_register_devices) diff --git a/hw/microblaze_pic_cpu.c b/hw/microblaze_pic_cpu.c index 7c59382..8b5623c 100644 --- a/hw/microblaze_pic_cpu.c +++ b/hw/microblaze_pic_cpu.c @@ -23,15 +23,10 @@ */ #include "hw.h" -#include "pc.h" +#include "microblaze_pic_cpu.h" #define D(x) -void pic_info(Monitor *mon) -{} -void irq_info(Monitor *mon) -{} - static void microblaze_pic_cpu_handler(void *opaque, int irq, int level) { CPUState *env = (CPUState *)opaque; @@ -43,7 +38,6 @@ static void microblaze_pic_cpu_handler(void *opaque, int irq, int level) cpu_reset_interrupt(env, type); } -qemu_irq *microblaze_pic_init_cpu(CPUState *env); qemu_irq *microblaze_pic_init_cpu(CPUState *env) { return qemu_allocate_irqs(microblaze_pic_cpu_handler, env, 2); diff --git a/hw/mips.h b/hw/mips.h index 73aa8f8..6fa9a3a 100644 --- a/hw/mips.h +++ b/hw/mips.h @@ -8,18 +8,6 @@ PCIBus *gt64120_register(qemu_irq *pic); /* bonito.c */ PCIBus *bonito_init(qemu_irq *pic); -/* ds1225y.c */ -void *ds1225y_init(target_phys_addr_t mem_base, const char *filename); -void ds1225y_set_protection(void *opaque, int protection); - -/* g364fb.c */ -int g364fb_mm_init(target_phys_addr_t vram_base, - target_phys_addr_t ctrl_base, int it_shift, - qemu_irq irq); - -/* mipsnet.c */ -void mipsnet_init(int base, qemu_irq irq, NICInfo *nd); - /* jazz_led.c */ void jazz_led_init(target_phys_addr_t base); diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c index 3b0abdb..04921c1 100644 --- a/hw/mips_fulong2e.c +++ b/hw/mips_fulong2e.c @@ -38,6 +38,7 @@ #include "vt82c686.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "exec-memory.h" #define DEBUG_FULONG2E_INIT @@ -67,7 +68,7 @@ #define FULONG2E_ATI_SLOT 6 #define FULONG2E_RTL8139_SLOT 7 -static PITState *pit; +static ISADevice *pit; static struct _loaderparams { int ram_size; @@ -140,7 +141,7 @@ static int64_t load_kernel (CPUState *env) /* Setup prom parameters. */ prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE); - prom_buf = qemu_malloc(prom_size); + prom_buf = g_malloc(prom_size); prom_set(prom_buf, index++, "%s", loaderparams.kernel_filename); if (initrd_size > 0) { @@ -256,18 +257,18 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device, const char *initrd_filename, const char *cpu_model) { char *filename; - unsigned long ram_offset, bios_offset; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *bios = g_new(MemoryRegion, 1); long bios_size; int64_t kernel_entry; qemu_irq *i8259; qemu_irq *cpu_exit_irq; int via_devfn; PCIBus *pci_bus; - uint8_t *eeprom_buf; i2c_bus *smbus; int i; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; - DeviceState *eeprom; CPUState *env; /* init CPUs */ @@ -290,12 +291,12 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device, bios_size = 1024 * 1024; /* allocate RAM */ - ram_offset = qemu_ram_alloc(NULL, "fulong2e.ram", ram_size); - bios_offset = qemu_ram_alloc(NULL, "fulong2e.bios", bios_size); + memory_region_init_ram(ram, NULL, "fulong2e.ram", ram_size); + memory_region_init_ram(bios, NULL, "fulong2e.bios", bios_size); + memory_region_set_readonly(bios, true); - cpu_register_physical_memory(0, ram_size, ram_offset); - cpu_register_physical_memory(0x1fc00000LL, - bios_size, bios_offset | IO_MEM_ROM); + memory_region_add_subregion(address_space_mem, 0, ram); + memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios); /* We do not support flash operation, just loading pmon.bin as raw BIOS. * Please use -L to set the BIOS path and -bios to set bios name. */ @@ -306,7 +307,7 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device, loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel (env); - write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry); + write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); } else { if (bios_name == NULL) { bios_name = FULONG_BIOSNAME; @@ -315,7 +316,7 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device, if (filename) { bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE); - qemu_free(filename); + g_free(filename); } else { bios_size = -1; } @@ -330,46 +331,34 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device, cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); - /* Interrupt controller */ - /* The 8259 -> IP5 */ - i8259 = i8259_init(env->irq[5]); - /* North bridge, Bonito --> IP2 */ pci_bus = bonito_init((qemu_irq *)&(env->irq[2])); /* South bridge */ - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } - - for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { - hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); - } + ide_drive_get(hd, MAX_IDE_BUS); via_devfn = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0)); if (via_devfn < 0) { - fprintf(stderr, "vt82c686b_init error \n"); + fprintf(stderr, "vt82c686b_init error\n"); exit(1); } + /* Interrupt controller */ + /* The 8259 -> IP5 */ + i8259 = i8259_init(env->irq[5]); isa_bus_irqs(i8259); + vt82c686b_ide_init(pci_bus, hd, PCI_DEVFN(FULONG2E_VIA_SLOT, 1)); usb_uhci_vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 2)); usb_uhci_vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 3)); smbus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 4), 0xeee1, NULL); - eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ - memcpy(eeprom_buf, eeprom_spd, sizeof(eeprom_spd)); /* TODO: Populate SPD eeprom data. */ - eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); - qdev_prop_set_uint8(eeprom, "address", 0x50); - qdev_prop_set_ptr(eeprom, "data", eeprom_buf); - qdev_init_nofail(eeprom); + smbus_eeprom_init(smbus, 1, eeprom_spd, sizeof(eeprom_spd)); /* init other devices */ - pit = pit_init(0x40, isa_get_irq(0)); + pit = pit_init(0x40, 0); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c index 85eba5a..14beea2 100644 --- a/hw/mips_jazz.c +++ b/hw/mips_jazz.c @@ -37,6 +37,8 @@ #include "loader.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "sysbus.h" +#include "exec-memory.h" enum jazz_model_e { @@ -50,44 +52,42 @@ static void main_cpu_reset(void *opaque) cpu_reset(env); } -static uint32_t rtc_readb(void *opaque, target_phys_addr_t addr) +static uint64_t rtc_read(void *opaque, target_phys_addr_t addr, unsigned size) { return cpu_inw(0x71); } -static void rtc_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void rtc_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { cpu_outw(0x71, val & 0xff); } -static CPUReadMemoryFunc * const rtc_read[3] = { - rtc_readb, - rtc_readb, - rtc_readb, +static const MemoryRegionOps rtc_ops = { + .read = rtc_read, + .write = rtc_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const rtc_write[3] = { - rtc_writeb, - rtc_writeb, - rtc_writeb, -}; - -static void dma_dummy_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static uint64_t dma_dummy_read(void *opaque, target_phys_addr_t addr, + unsigned size) { /* Nothing to do. That is only to ensure that * the current DMA acknowledge cycle is completed. */ + return 0xff; } -static CPUReadMemoryFunc * const dma_dummy_read[3] = { - NULL, - NULL, - NULL, -}; +static void dma_dummy_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) +{ + /* Nothing to do. That is only to ensure that + * the current DMA acknowledge cycle is completed. */ +} -static CPUWriteMemoryFunc * const dma_dummy_write[3] = { - dma_dummy_writeb, - dma_dummy_writeb, - dma_dummy_writeb, +static const MemoryRegionOps dma_dummy_ops = { + .read = dma_dummy_read, + .write = dma_dummy_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; #define MAGNUM_BIOS_SIZE_MAX 0x7e000 @@ -102,10 +102,11 @@ static void cpu_request_exit(void *opaque, int irq, int level) } } -static -void mips_jazz_init (ram_addr_t ram_size, - const char *cpu_model, - enum jazz_model_e jazz_model) +static void mips_jazz_init(MemoryRegion *address_space, + MemoryRegion *address_space_io, + ram_addr_t ram_size, + const char *cpu_model, + enum jazz_model_e jazz_model) { char *filename; int bios_size, n; @@ -113,14 +114,19 @@ void mips_jazz_init (ram_addr_t ram_size, qemu_irq *rc4030, *i8259; rc4030_dma *dmas; void* rc4030_opaque; - int s_rtc, s_dma_dummy; + MemoryRegion *rtc = g_new(MemoryRegion, 1); + MemoryRegion *i8042 = g_new(MemoryRegion, 1); + MemoryRegion *dma_dummy = g_new(MemoryRegion, 1); NICInfo *nd; - PITState *pit; + DeviceState *dev; + SysBusDevice *sysbus; + ISADevice *pit; DriveInfo *fds[MAX_FD]; qemu_irq esp_reset, dma_enable; qemu_irq *cpu_exit_irq; - ram_addr_t ram_offset; - ram_addr_t bios_offset; + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *bios = g_new(MemoryRegion, 1); + MemoryRegion *bios2 = g_new(MemoryRegion, 1); /* init CPUs */ if (cpu_model == NULL) { @@ -139,14 +145,15 @@ void mips_jazz_init (ram_addr_t ram_size, qemu_register_reset(main_cpu_reset, env); /* allocate RAM */ - ram_offset = qemu_ram_alloc(NULL, "mips_jazz.ram", ram_size); - cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); + memory_region_init_ram(ram, NULL, "mips_jazz.ram", ram_size); + memory_region_add_subregion(address_space, 0, ram); - bios_offset = qemu_ram_alloc(NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE); - cpu_register_physical_memory(0x1fc00000LL, - MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM); - cpu_register_physical_memory(0xfff00000LL, - MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM); + memory_region_init_ram(bios, NULL, "mips_jazz.bios", MAGNUM_BIOS_SIZE); + memory_region_set_readonly(bios, true); + memory_region_init_alias(bios2, "mips_jazz.bios", bios, + 0, MAGNUM_BIOS_SIZE); + memory_region_add_subregion(address_space, 0x1fc00000LL, bios); + memory_region_add_subregion(address_space, 0xfff00000LL, bios2); /* load the BIOS image. */ if (bios_name == NULL) @@ -155,7 +162,7 @@ void mips_jazz_init (ram_addr_t ram_size, if (filename) { bios_size = load_image_targphys(filename, 0xfff00000LL, MAGNUM_BIOS_SIZE); - qemu_free(filename); + g_free(filename); } else { bios_size = -1; } @@ -171,17 +178,16 @@ void mips_jazz_init (ram_addr_t ram_size, /* Chipset */ rc4030_opaque = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas); - s_dma_dummy = cpu_register_io_memory(dma_dummy_read, dma_dummy_write, NULL, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(0x8000d000, 0x00001000, s_dma_dummy); + memory_region_init_io(dma_dummy, &dma_dummy_ops, NULL, "dummy_dma", 0x1000); + memory_region_add_subregion(address_space, 0x8000d000, dma_dummy); /* ISA devices */ + isa_bus_new(NULL, address_space_io); i8259 = i8259_init(env->irq[4]); - isa_bus_new(NULL); isa_bus_irqs(i8259); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); - pit = pit_init(0x40, i8259[0]); + pit = pit_init(0x40, 0); pcspk_init(pit); /* ISA IO space at 0x90000000 */ @@ -191,10 +197,24 @@ void mips_jazz_init (ram_addr_t ram_size, /* Video card */ switch (jazz_model) { case JAZZ_MAGNUM: - g364fb_mm_init(0x40000000, 0x60000000, 0, rc4030[3]); + dev = qdev_create(NULL, "sysbus-g364"); + qdev_init_nofail(dev); + sysbus = sysbus_from_qdev(dev); + sysbus_mmio_map(sysbus, 0, 0x60080000); + sysbus_mmio_map(sysbus, 1, 0x40000000); + sysbus_connect_irq(sysbus, 0, rc4030[3]); + { + /* Simple ROM, so user doesn't have to provide one */ + MemoryRegion *rom_mr = g_new(MemoryRegion, 1); + memory_region_init_ram(rom_mr, NULL, "g364fb.rom", 0x80000); + memory_region_set_readonly(rom_mr, true); + uint8_t *rom = memory_region_get_ram_ptr(rom_mr); + memory_region_add_subregion(address_space, 0x60000000, rom_mr); + rom[0] = 0x10; /* Mips G364 */ + } break; case JAZZ_PICA61: - isa_vga_mm_init(0x40000000, 0x60000000, 0); + isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory()); break; default: break; @@ -204,7 +224,7 @@ void mips_jazz_init (ram_addr_t ram_size, for (n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (!nd->model) - nd->model = qemu_strdup("dp83932"); + nd->model = g_strdup("dp83932"); if (strcmp(nd->model, "dp83932") == 0) { dp83932_init(nd, 0x80001000, 2, rc4030[4], rc4030_opaque, rc4030_dma_memory_rw); @@ -235,27 +255,21 @@ void mips_jazz_init (ram_addr_t ram_size, /* Real time clock */ rtc_init(1980, NULL); - s_rtc = cpu_register_io_memory(rtc_read, rtc_write, NULL, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc); + memory_region_init_io(rtc, &rtc_ops, NULL, "rtc", 0x1000); + memory_region_add_subregion(address_space, 0x80004000, rtc); /* Keyboard (i8042) */ - i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0x1000, 0x1); + i8042_mm_init(rc4030[6], rc4030[7], i8042, 0x1000, 0x1); + memory_region_add_subregion(address_space, 0x80005000, i8042); /* Serial ports */ if (serial_hds[0]) { -#ifdef TARGET_WORDS_BIGENDIAN - serial_mm_init(0x80006000, 0, rc4030[8], 8000000/16, serial_hds[0], 1, 1); -#else - serial_mm_init(0x80006000, 0, rc4030[8], 8000000/16, serial_hds[0], 1, 0); -#endif + serial_mm_init(address_space, 0x80006000, 0, rc4030[8], 8000000/16, + serial_hds[0], DEVICE_NATIVE_ENDIAN); } if (serial_hds[1]) { -#ifdef TARGET_WORDS_BIGENDIAN - serial_mm_init(0x80007000, 0, rc4030[9], 8000000/16, serial_hds[1], 1, 1); -#else - serial_mm_init(0x80007000, 0, rc4030[9], 8000000/16, serial_hds[1], 1, 0); -#endif + serial_mm_init(address_space, 0x80007000, 0, rc4030[9], 8000000/16, + serial_hds[1], DEVICE_NATIVE_ENDIAN); } /* Parallel port */ @@ -266,8 +280,11 @@ void mips_jazz_init (ram_addr_t ram_size, /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */ audio_init(i8259, NULL); - /* NVRAM: Unprotected at 0x9000, Protected at 0xa000, Read only at 0xb000 */ - ds1225y_init(0x80009000, "nvram"); + /* NVRAM */ + dev = qdev_create(NULL, "ds1225y"); + qdev_init_nofail(dev); + sysbus = sysbus_from_qdev(dev); + sysbus_mmio_map(sysbus, 0, 0x80009000); /* LED indicator */ jazz_led_init(0x8000f000); @@ -279,7 +296,8 @@ void mips_magnum_init (ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - mips_jazz_init(ram_size, cpu_model, JAZZ_MAGNUM); + mips_jazz_init(get_system_memory(), get_system_io(), + ram_size, cpu_model, JAZZ_MAGNUM); } static @@ -288,7 +306,8 @@ void mips_pica61_init (ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - mips_jazz_init(ram_size, cpu_model, JAZZ_PICA61); + mips_jazz_init(get_system_memory(), get_system_io(), + ram_size, cpu_model, JAZZ_PICA61); } static QEMUMachine mips_magnum_machine = { diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 7211d98..941b9bd 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -46,6 +46,8 @@ #include "elf.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "exec-memory.h" +#include "sysbus.h" /* SysBusDevice */ //#define DEBUG_BOARD_INIT @@ -56,6 +58,9 @@ #define MAX_IDE_BUS 2 typedef struct { + MemoryRegion iomem; + MemoryRegion iomem_lo; /* 0 - 0x900 */ + MemoryRegion iomem_hi; /* 0xa00 - 0x100000 */ uint32_t leds; uint32_t brk; uint32_t gpout; @@ -68,7 +73,12 @@ typedef struct { SerialState *uart; } MaltaFPGAState; -static PITState *pit; +typedef struct { + SysBusDevice busdev; + qemu_irq *i8259; +} MaltaState; + +static ISADevice *pit; static struct _loaderparams { int ram_size; @@ -92,8 +102,8 @@ static void malta_fpga_update_display(void *opaque) } leds_text[8] = '\0'; - qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text); - qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text); + qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text); + qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text); } /* @@ -214,7 +224,8 @@ static void eeprom24c0x_write(int scl, int sda) eeprom.sda = sda; } -static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr) +static uint64_t malta_fpga_read(void *opaque, target_phys_addr_t addr, + unsigned size) { MaltaFPGAState *s = opaque; uint32_t val = 0; @@ -301,8 +312,8 @@ static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr) return val; } -static void malta_fpga_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void malta_fpga_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { MaltaFPGAState *s = opaque; uint32_t saddr; @@ -327,7 +338,7 @@ static void malta_fpga_writel(void *opaque, target_phys_addr_t addr, /* ASCIIWORD Register */ case 0x00410: - snprintf(s->display_text, 9, "%08X", val); + snprintf(s->display_text, 9, "%08X", (uint32_t)val); malta_fpga_update_display(s); break; @@ -387,16 +398,10 @@ static void malta_fpga_writel(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const malta_fpga_read[] = { - malta_fpga_readl, - malta_fpga_readl, - malta_fpga_readl -}; - -static CPUWriteMemoryFunc * const malta_fpga_write[] = { - malta_fpga_writel, - malta_fpga_writel, - malta_fpga_writel +static const MemoryRegionOps malta_fpga_ops = { + .read = malta_fpga_read, + .write = malta_fpga_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void malta_fpga_reset(void *opaque) @@ -417,39 +422,38 @@ static void malta_fpga_reset(void *opaque) static void malta_fpga_led_init(CharDriverState *chr) { - qemu_chr_printf(chr, "\e[HMalta LEDBAR\r\n"); - qemu_chr_printf(chr, "+--------+\r\n"); - qemu_chr_printf(chr, "+ +\r\n"); - qemu_chr_printf(chr, "+--------+\r\n"); - qemu_chr_printf(chr, "\n"); - qemu_chr_printf(chr, "Malta ASCII\r\n"); - qemu_chr_printf(chr, "+--------+\r\n"); - qemu_chr_printf(chr, "+ +\r\n"); - qemu_chr_printf(chr, "+--------+\r\n"); + qemu_chr_fe_printf(chr, "\e[HMalta LEDBAR\r\n"); + qemu_chr_fe_printf(chr, "+--------+\r\n"); + qemu_chr_fe_printf(chr, "+ +\r\n"); + qemu_chr_fe_printf(chr, "+--------+\r\n"); + qemu_chr_fe_printf(chr, "\n"); + qemu_chr_fe_printf(chr, "Malta ASCII\r\n"); + qemu_chr_fe_printf(chr, "+--------+\r\n"); + qemu_chr_fe_printf(chr, "+ +\r\n"); + qemu_chr_fe_printf(chr, "+--------+\r\n"); } -static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr) +static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space, + target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr) { MaltaFPGAState *s; - int malta; - s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState)); + s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState)); - malta = cpu_register_io_memory(malta_fpga_read, - malta_fpga_write, s, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->iomem, &malta_fpga_ops, s, + "malta-fpga", 0x100000); + memory_region_init_alias(&s->iomem_lo, "malta-fpga", + &s->iomem, 0, 0x900); + memory_region_init_alias(&s->iomem_hi, "malta-fpga", + &s->iomem, 0xa00, 0x10000-0xa00); - cpu_register_physical_memory(base, 0x900, malta); - /* 0xa00 is less than a page, so will still get the right offsets. */ - cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta); + memory_region_add_subregion(address_space, base, &s->iomem_lo); + memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi); - s->display = qemu_chr_open("fpga", "vc:320x200", malta_fpga_led_init); + s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init); -#ifdef TARGET_WORDS_BIGENDIAN - s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 1); -#else - s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 0); -#endif + s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq, + 230400, uart_chr, DEVICE_NATIVE_ENDIAN); malta_fpga_reset(s); qemu_register_reset(malta_fpga_reset, s); @@ -709,7 +713,7 @@ static int64_t load_kernel (void) /* Setup prom parameters. */ prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE); - prom_buf = qemu_malloc(prom_size); + prom_buf = g_malloc(prom_size); prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename); if (initrd_size > 0) { @@ -732,6 +736,12 @@ static int64_t load_kernel (void) return kernel_entry; } +static void malta_mips_config(CPUState *env) +{ + env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) | + ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC); +} + static void main_cpu_reset(void *opaque) { CPUState *env = opaque; @@ -743,6 +753,8 @@ static void main_cpu_reset(void *opaque) if (loaderparams.kernel_filename) { env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL)); } + + malta_mips_config(env); } static void cpu_request_exit(void *opaque, int irq, int level) @@ -761,16 +773,17 @@ void mips_malta_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { char *filename; - ram_addr_t ram_offset; - ram_addr_t bios_offset; + pflash_t *fl; + MemoryRegion *system_memory = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1); target_long bios_size; int64_t kernel_entry; PCIBus *pci_bus; CPUState *env; - qemu_irq *i8259; + qemu_irq *isa_irq; qemu_irq *cpu_exit_irq; int piix4_devfn; - uint8_t *eeprom_buf; i2c_bus *smbus; int i; DriveInfo *dinfo; @@ -780,12 +793,17 @@ void mips_malta_init (ram_addr_t ram_size, int fl_sectors = 0; int be; + DeviceState *dev = qdev_create(NULL, "mips-malta"); + MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev); + + qdev_init_nofail(dev); + /* Make sure the first 3 serial ports are associated with a device. */ for(i = 0; i < 3; i++) { if (!serial_hds[i]) { char label[32]; snprintf(label, sizeof(label), "serial%d", i); - serial_hds[i] = qemu_chr_open(label, "null", NULL); + serial_hds[i] = qemu_chr_new(label, "null", NULL); } } @@ -797,12 +815,19 @@ void mips_malta_init (ram_addr_t ram_size, cpu_model = "24Kf"; #endif } - env = cpu_init(cpu_model); - if (!env) { - fprintf(stderr, "Unable to find CPU definition\n"); - exit(1); + + for (i = 0; i < smp_cpus; i++) { + env = cpu_init(cpu_model); + if (!env) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } + /* Init internal devices */ + cpu_mips_irq_init_cpu(env); + cpu_mips_clock_init(env); + qemu_register_reset(main_cpu_reset, env); } - qemu_register_reset(main_cpu_reset, env); + env = first_cpu; /* allocate RAM */ if (ram_size > (256 << 20)) { @@ -811,17 +836,8 @@ void mips_malta_init (ram_addr_t ram_size, ((unsigned int)ram_size / (1 << 20))); exit(1); } - ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size); - bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE); - - - cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); - - /* Map the bios at two physical locations, as on the real board. */ - cpu_register_physical_memory(0x1e000000LL, - BIOS_SIZE, bios_offset | IO_MEM_ROM); - cpu_register_physical_memory(0x1fc00000LL, - BIOS_SIZE, bios_offset | IO_MEM_ROM); + memory_region_init_ram(ram, NULL, "mips_malta.ram", ram_size); + memory_region_add_subregion(system_memory, 0, ram); #ifdef TARGET_WORDS_BIGENDIAN be = 1; @@ -829,17 +845,24 @@ void mips_malta_init (ram_addr_t ram_size, be = 0; #endif /* FPGA */ - malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]); + malta_fpga_init(system_memory, 0x1f000000LL, env->irq[2], serial_hds[2]); /* Load firmware in flash / BIOS unless we boot directly into a kernel. */ if (kernel_filename) { /* Write a small bootloader to the flash location. */ + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE); + memory_region_set_readonly(bios, true); + memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE); + /* Map the bios at two physical locations, as on the real board. */ + memory_region_add_subregion(system_memory, 0x1e000000LL, bios); + memory_region_add_subregion(system_memory, 0x1fc00000LL, bios_alias); loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(); - write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry); + write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); } else { dinfo = drive_get(IF_PFLASH, 0, fl_idx); if (dinfo) { @@ -848,15 +871,31 @@ void mips_malta_init (ram_addr_t ram_size, fl_sectors = bios_size >> 16; #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size " TARGET_FMT_lx " at " - "offset %08lx addr %08llx '%s' %x\n", - fl_idx, bios_size, bios_offset, 0x1e000000LL, + "addr %08llx '%s' %x\n", + fl_idx, bios_size, 0x1e000000LL, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi01_register(0x1e000000LL, bios_offset, - dinfo->bdrv, 65536, fl_sectors, - 4, 0x0000, 0x0000, 0x0000, 0x0000, be); - fl_idx++; + fl = pflash_cfi01_register(0x1e000000LL, + NULL, "mips_malta.bios", BIOS_SIZE, + dinfo->bdrv, 65536, fl_sectors, + 4, 0x0000, 0x0000, 0x0000, 0x0000, be); + bios = pflash_cfi01_get_memory(fl); + /* Map the bios at two physical locations, as on the real board. */ + memory_region_init_alias(bios_alias, "bios.1fc", + bios, 0, BIOS_SIZE); + memory_region_add_subregion(system_memory, 0x1fc00000LL, + bios_alias); + fl_idx++; } else { + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE); + memory_region_set_readonly(bios, true); + memory_region_init_alias(bios_alias, "bios.1fc", + bios, 0, BIOS_SIZE); + /* Map the bios at two physical locations, as on the real board. */ + memory_region_add_subregion(system_memory, 0x1e000000LL, bios); + memory_region_add_subregion(system_memory, 0x1fc00000LL, + bios_alias); /* Load a BIOS image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; @@ -864,7 +903,7 @@ void mips_malta_init (ram_addr_t ram_size, if (filename) { bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE); - qemu_free(filename); + g_free(filename); } else { bios_size = -1; } @@ -879,7 +918,7 @@ void mips_malta_init (ram_addr_t ram_size, a neat trick which allows bi-endian firmware. */ #ifndef TARGET_WORDS_BIGENDIAN { - uint32_t *addr = qemu_get_ram_ptr(bios_offset);; + uint32_t *addr = memory_region_get_ram_ptr(bios); uint32_t *end = addr + bios_size; while (addr < end) { bswap32s(addr); @@ -891,46 +930,41 @@ void mips_malta_init (ram_addr_t ram_size, /* Board ID = 0x420 (Malta Board with CoreLV) XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should map to the board ID. */ - stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420); + stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420); /* Init internal devices */ cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); - /* Interrupt controller */ - /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */ - i8259 = i8259_init(env->irq[2]); + /* + * We have a circular dependency problem: pci_bus depends on isa_irq, + * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends + * on piix4, and piix4 depends on pci_bus. To stop the cycle we have + * qemu_irq_proxy() adds an extra bit of indirection, allowing us + * to resolve the isa_irq -> i8259 dependency after i8259 is initialized. + */ + isa_irq = qemu_irq_proxy(&s->i8259, 16); /* Northbridge */ - pci_bus = gt64120_register(i8259); + pci_bus = gt64120_register(isa_irq); /* Southbridge */ + ide_drive_get(hd, MAX_IDE_BUS); - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } + piix4_devfn = piix4_init(pci_bus, 80); - for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { - hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); - } + /* Interrupt controller */ + /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */ + s->i8259 = i8259_init(env->irq[2]); - piix4_devfn = piix4_init(pci_bus, 80); - isa_bus_irqs(i8259); + isa_bus_irqs(s->i8259); pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1); usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9), NULL, NULL, 0); - eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ - for (i = 0; i < 8; i++) { - /* TODO: Populate SPD eeprom data. */ - DeviceState *eeprom; - eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); - qdev_prop_set_uint8(eeprom, "address", 0x50 + i); - qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256)); - qdev_init_nofail(eeprom); - } - pit = pit_init(0x40, isa_get_irq(0)); + /* TODO: Populate SPD eeprom data. */ + smbus_eeprom_init(smbus, 8, NULL, 0); + pit = pit_init(0x40, 0); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); @@ -957,22 +991,47 @@ void mips_malta_init (ram_addr_t ram_size, if (cirrus_vga_enabled) { pci_cirrus_vga_init(pci_bus); } else if (vmsvga_enabled) { - pci_vmsvga_init(pci_bus); + if (!pci_vmsvga_init(pci_bus)) { + fprintf(stderr, "Warning: vmware_vga not available," + " using standard VGA instead\n"); + pci_vga_init(pci_bus); + } } else if (std_vga_enabled) { pci_vga_init(pci_bus); } } +static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev) +{ + return 0; +} + +static SysBusDeviceInfo mips_malta_device = { + .init = mips_malta_sysbus_device_init, + .qdev.name = "mips-malta", + .qdev.size = sizeof(MaltaState), + .qdev.props = (Property[]) { + DEFINE_PROP_END_OF_LIST(), + } +}; + static QEMUMachine mips_malta_machine = { .name = "malta", .desc = "MIPS Malta Core LV", .init = mips_malta_init, + .max_cpus = 16, .is_default = 1, }; +static void mips_malta_device_init(void) +{ + sysbus_register_withprop(&mips_malta_device); +} + static void mips_malta_machine_init(void) { qemu_register_machine(&mips_malta_machine); } +device_init(mips_malta_device_init); machine_init(mips_malta_machine_init); diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index 380a7eb..b56cba6 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -1,7 +1,7 @@ /* * QEMU/mipssim emulation * - * Emulates a very simple machine model similiar to the one use by the + * Emulates a very simple machine model similar to the one used by the * proprietary MIPS emulator. * * Copyright (c) 2007 Thiemo Seufer @@ -35,6 +35,8 @@ #include "mips-bios.h" #include "loader.h" #include "elf.h" +#include "sysbus.h" +#include "exec-memory.h" static struct _loaderparams { int ram_size; @@ -112,6 +114,22 @@ static void main_cpu_reset(void *opaque) } } +static void mipsnet_init(int base, qemu_irq irq, NICInfo *nd) +{ + DeviceState *dev; + SysBusDevice *s; + + dev = qdev_create(NULL, "mipsnet"); + qdev_set_nic_properties(dev, nd); + qdev_init_nofail(dev); + + s = sysbus_from_qdev(dev); + sysbus_connect_irq(s, 0, irq); + memory_region_add_subregion(get_system_io(), + base, + sysbus_mmio_get_region(s, 0)); +} + static void mips_mipssim_init (ram_addr_t ram_size, const char *boot_device, @@ -119,8 +137,9 @@ mips_mipssim_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { char *filename; - ram_addr_t ram_offset; - ram_addr_t bios_offset; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *bios = g_new(MemoryRegion, 1); CPUState *env; ResetData *reset_info; int bios_size; @@ -138,27 +157,27 @@ mips_mipssim_init (ram_addr_t ram_size, fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } - reset_info = qemu_mallocz(sizeof(ResetData)); + reset_info = g_malloc0(sizeof(ResetData)); reset_info->env = env; reset_info->vector = env->active_tc.PC; qemu_register_reset(main_cpu_reset, reset_info); /* Allocate RAM. */ - ram_offset = qemu_ram_alloc(NULL, "mips_mipssim.ram", ram_size); - bios_offset = qemu_ram_alloc(NULL, "mips_mipssim.bios", BIOS_SIZE); + memory_region_init_ram(ram, NULL, "mips_mipssim.ram", ram_size); + memory_region_init_ram(bios, NULL, "mips_mipssim.bios", BIOS_SIZE); + memory_region_set_readonly(bios, true); - cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); + memory_region_add_subregion(address_space_mem, 0, ram); /* Map the BIOS / boot exception handler. */ - cpu_register_physical_memory(0x1fc00000LL, - BIOS_SIZE, bios_offset | IO_MEM_ROM); + memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios); /* Load a BIOS / boot exception handler image. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE); - qemu_free(filename); + g_free(filename); } else { bios_size = -1; } diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c index fb34dcf..d0564d4 100644 --- a/hw/mips_r4k.c +++ b/hw/mips_r4k.c @@ -23,6 +23,7 @@ #include "elf.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "exec-memory.h" #define MAX_IDE_BUS 2 @@ -30,7 +31,7 @@ static const int ide_iobase[2] = { 0x1f0, 0x170 }; static const int ide_iobase2[2] = { 0x3f6, 0x376 }; static const int ide_irq[2] = { 14, 15 }; -static PITState *pit; /* PIT i8254 */ +static ISADevice *pit; /* PIT i8254 */ /* i8254 PIT is attached to the IRQ0 at PIC i8259 */ @@ -41,8 +42,8 @@ static struct _loaderparams { const char *initrd_filename; } loaderparams; -static void mips_qemu_writel (void *opaque, target_phys_addr_t addr, - uint32_t val) +static void mips_qemu_write (void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { if ((addr & 0xffff) == 0 && val == 42) qemu_system_reset_request (); @@ -50,25 +51,18 @@ static void mips_qemu_writel (void *opaque, target_phys_addr_t addr, qemu_system_shutdown_request (); } -static uint32_t mips_qemu_readl (void *opaque, target_phys_addr_t addr) +static uint64_t mips_qemu_read (void *opaque, target_phys_addr_t addr, + unsigned size) { return 0; } -static CPUWriteMemoryFunc * const mips_qemu_write[] = { - &mips_qemu_writel, - &mips_qemu_writel, - &mips_qemu_writel, +static const MemoryRegionOps mips_qemu_ops = { + .read = mips_qemu_read, + .write = mips_qemu_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUReadMemoryFunc * const mips_qemu_read[] = { - &mips_qemu_readl, - &mips_qemu_readl, - &mips_qemu_readl, -}; - -static int mips_qemu_iomemtype = 0; - typedef struct ResetData { CPUState *env; uint64_t vector; @@ -126,7 +120,7 @@ static int64_t load_kernel(void) /* Store command line. */ params_size = 264; - params_buf = qemu_malloc(params_size); + params_buf = g_malloc(params_size); params_buf[0] = tswap32(ram_size); params_buf[1] = tswap32(0x12345678); @@ -162,8 +156,10 @@ void mips_r4k_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { char *filename; - ram_addr_t ram_offset; - ram_addr_t bios_offset; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *bios; + MemoryRegion *iomem = g_new(MemoryRegion, 1); int bios_size; CPUState *env; ResetData *reset_info; @@ -186,7 +182,7 @@ void mips_r4k_init (ram_addr_t ram_size, fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } - reset_info = qemu_mallocz(sizeof(ResetData)); + reset_info = g_malloc0(sizeof(ResetData)); reset_info->env = env; reset_info->vector = env->active_tc.PC; qemu_register_reset(main_cpu_reset, reset_info); @@ -198,16 +194,12 @@ void mips_r4k_init (ram_addr_t ram_size, ((unsigned int)ram_size / (1 << 20))); exit(1); } - ram_offset = qemu_ram_alloc(NULL, "mips_r4k.ram", ram_size); + memory_region_init_ram(ram, NULL, "mips_r4k.ram", ram_size); - cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); + memory_region_add_subregion(address_space_mem, 0, ram); - if (!mips_qemu_iomemtype) { - mips_qemu_iomemtype = cpu_register_io_memory(mips_qemu_read, - mips_qemu_write, NULL, - DEVICE_NATIVE_ENDIAN); - } - cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype); + memory_region_init_io(iomem, &mips_qemu_ops, NULL, "mips-qemu", 0x10000); + memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem); /* Try to load a BIOS image. If this fails, we continue regardless, but initialize the hardware ourselves. When a kernel gets @@ -227,15 +219,15 @@ void mips_r4k_init (ram_addr_t ram_size, be = 0; #endif if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { - bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE); - cpu_register_physical_memory(0x1fc00000, BIOS_SIZE, - bios_offset | IO_MEM_ROM); + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios); load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { uint32_t mips_rom = 0x00400000; - bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom); - if (!pflash_cfi01_register(0x1fc00000, bios_offset, + if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom, dinfo->bdrv, sector_len, mips_rom / sector_len, 4, 0, 0, 0, 0, be)) { @@ -248,7 +240,7 @@ void mips_r4k_init (ram_addr_t ram_size, bios_name); } if (filename) { - qemu_free(filename); + g_free(filename); } if (kernel_filename) { @@ -264,8 +256,8 @@ void mips_r4k_init (ram_addr_t ram_size, cpu_mips_clock_init(env); /* The PIC is attached to the MIPS CPU INT0 pin */ + isa_bus_new(NULL, get_system_io()); i8259 = i8259_init(env->irq[2]); - isa_bus_new(NULL); isa_bus_irqs(i8259); rtc_init(2000, NULL); @@ -274,7 +266,7 @@ void mips_r4k_init (ram_addr_t ram_size, isa_mmio_init(0x14000000, 0x00010000); isa_mem_base = 0x10000000; - pit = pit_init(0x40, i8259[0]); + pit = pit_init(0x40, 0); for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { @@ -287,15 +279,7 @@ void mips_r4k_init (ram_addr_t ram_size, if (nd_table[0].vlan) isa_ne2000_init(0x300, 9, &nd_table[0]); - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } - - for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { - hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); - } - + ide_drive_get(hd, MAX_IDE_BUS); for(i = 0; i < MAX_IDE_BUS; i++) isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], diff --git a/hw/mips_timer.c b/hw/mips_timer.c index 9c95f28..cf6ac69 100644 --- a/hw/mips_timer.c +++ b/hw/mips_timer.c @@ -47,7 +47,7 @@ static void cpu_mips_timer_update(CPUState *env) uint64_t now, next; uint32_t wait; - now = qemu_get_clock(vm_clock); + now = qemu_get_clock_ns(vm_clock); wait = env->CP0_Compare - env->CP0_Count - (uint32_t)muldiv64(now, TIMER_FREQ, get_ticks_per_sec()); next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ); @@ -71,7 +71,7 @@ uint32_t cpu_mips_get_count (CPUState *env) } else { uint64_t now; - now = qemu_get_clock(vm_clock); + now = qemu_get_clock_ns(vm_clock); if (qemu_timer_pending(env->timer) && qemu_timer_expired(env->timer, now)) { /* The timer has already expired. */ @@ -90,7 +90,7 @@ void cpu_mips_store_count (CPUState *env, uint32_t count) else { /* Store new count register */ env->CP0_Count = - count - (uint32_t)muldiv64(qemu_get_clock(vm_clock), + count - (uint32_t)muldiv64(qemu_get_clock_ns(vm_clock), TIMER_FREQ, get_ticks_per_sec()); /* Update timer timer */ cpu_mips_timer_update(env); @@ -115,7 +115,7 @@ void cpu_mips_start_count(CPUState *env) void cpu_mips_stop_count(CPUState *env) { /* Store the current value */ - env->CP0_Count += (uint32_t)muldiv64(qemu_get_clock(vm_clock), + env->CP0_Count += (uint32_t)muldiv64(qemu_get_clock_ns(vm_clock), TIMER_FREQ, get_ticks_per_sec()); } @@ -141,7 +141,7 @@ static void mips_timer_cb (void *opaque) void cpu_mips_clock_init (CPUState *env) { - env->timer = qemu_new_timer(vm_clock, &mips_timer_cb, env); + env->timer = qemu_new_timer_ns(vm_clock, &mips_timer_cb, env); env->CP0_Compare = 0; cpu_mips_store_count(env, 1); } diff --git a/hw/mipsnet.c b/hw/mipsnet.c index c5e54ff..605367b 100644 --- a/hw/mipsnet.c +++ b/hw/mipsnet.c @@ -1,12 +1,7 @@ #include "hw.h" -#include "mips.h" #include "net.h" -#include "isa.h" - -//#define DEBUG_MIPSNET_SEND -//#define DEBUG_MIPSNET_RECEIVE -//#define DEBUG_MIPSNET_DATA -//#define DEBUG_MIPSNET_IRQ +#include "trace.h" +#include "sysbus.h" /* MIPSnet register offsets */ @@ -25,6 +20,8 @@ #define MAX_ETH_FRAME_SIZE 1514 typedef struct MIPSnetState { + SysBusDevice busdev; + uint32_t busy; uint32_t rx_count; uint32_t rx_read; @@ -33,7 +30,7 @@ typedef struct MIPSnetState { uint32_t intctl; uint8_t rx_buffer[MAX_ETH_FRAME_SIZE]; uint8_t tx_buffer[MAX_ETH_FRAME_SIZE]; - int io_base; + MemoryRegion io; qemu_irq irq; NICState *nic; NICConf conf; @@ -54,9 +51,7 @@ static void mipsnet_reset(MIPSnetState *s) static void mipsnet_update_irq(MIPSnetState *s) { int isr = !!s->intctl; -#ifdef DEBUG_MIPSNET_IRQ - printf("mipsnet: Set IRQ to %d (%02x)\n", isr, s->intctl); -#endif + trace_mipsnet_irq(isr, s->intctl); qemu_set_irq(s->irq, isr); } @@ -80,9 +75,7 @@ static ssize_t mipsnet_receive(VLANClientState *nc, const uint8_t *buf, size_t s { MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque; -#ifdef DEBUG_MIPSNET_RECEIVE - printf("mipsnet: receiving len=%zu\n", size); -#endif + trace_mipsnet_receive(size); if (!mipsnet_can_receive(nc)) return -1; @@ -103,7 +96,8 @@ static ssize_t mipsnet_receive(VLANClientState *nc, const uint8_t *buf, size_t s return size; } -static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr) +static uint64_t mipsnet_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned int size) { MIPSnetState *s = opaque; int ret = 0; @@ -144,20 +138,17 @@ static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr) default: break; } -#ifdef DEBUG_MIPSNET_DATA - printf("mipsnet: read addr=0x%02x val=0x%02x\n", addr, ret); -#endif + trace_mipsnet_read(addr, ret); return ret; } -static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void mipsnet_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned int size) { MIPSnetState *s = opaque; addr &= 0x3f; -#ifdef DEBUG_MIPSNET_DATA - printf("mipsnet: write addr=0x%02x val=0x%02x\n", addr, val); -#endif + trace_mipsnet_write(addr, val); switch (addr) { case MIPSNET_TX_DATA_COUNT: s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0; @@ -181,9 +172,7 @@ static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val) s->tx_buffer[s->tx_written++] = val; if (s->tx_written == s->tx_count) { /* Send buffer. */ -#ifdef DEBUG_MIPSNET_SEND - printf("mipsnet: sending len=%d\n", s->tx_count); -#endif + trace_mipsnet_send(s->tx_count); qemu_send_packet(&s->nic->nc, s->tx_buffer, s->tx_count); s->tx_count = s->tx_written = 0; s->intctl |= MIPSNET_INTCTL_TXDONE; @@ -202,48 +191,29 @@ static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -static void mipsnet_save(QEMUFile *f, void *opaque) -{ - MIPSnetState *s = opaque; - - qemu_put_be32s(f, &s->busy); - qemu_put_be32s(f, &s->rx_count); - qemu_put_be32s(f, &s->rx_read); - qemu_put_be32s(f, &s->tx_count); - qemu_put_be32s(f, &s->tx_written); - qemu_put_be32s(f, &s->intctl); - qemu_put_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE); - qemu_put_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE); -} - -static int mipsnet_load(QEMUFile *f, void *opaque, int version_id) -{ - MIPSnetState *s = opaque; - - if (version_id > 0) - return -EINVAL; - - qemu_get_be32s(f, &s->busy); - qemu_get_be32s(f, &s->rx_count); - qemu_get_be32s(f, &s->rx_read); - qemu_get_be32s(f, &s->tx_count); - qemu_get_be32s(f, &s->tx_written); - qemu_get_be32s(f, &s->intctl); - qemu_get_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE); - qemu_get_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE); - - return 0; -} +static const VMStateDescription vmstate_mipsnet = { + .name = "mipsnet", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(busy, MIPSnetState), + VMSTATE_UINT32(rx_count, MIPSnetState), + VMSTATE_UINT32(rx_read, MIPSnetState), + VMSTATE_UINT32(tx_count, MIPSnetState), + VMSTATE_UINT32(tx_written, MIPSnetState), + VMSTATE_UINT32(intctl, MIPSnetState), + VMSTATE_BUFFER(rx_buffer, MIPSnetState), + VMSTATE_BUFFER(tx_buffer, MIPSnetState), + VMSTATE_END_OF_LIST() + } +}; static void mipsnet_cleanup(VLANClientState *nc) { MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque; - unregister_savevm(NULL, "mipsnet", s); - - isa_unassign_ioport(s->io_base, 36); - - qemu_free(s); + s->nic = NULL; } static NetClientInfo net_mipsnet_info = { @@ -254,35 +224,50 @@ static NetClientInfo net_mipsnet_info = { .cleanup = mipsnet_cleanup, }; -void mipsnet_init (int base, qemu_irq irq, NICInfo *nd) -{ - MIPSnetState *s; - - qemu_check_nic_model(nd, "mipsnet"); +static MemoryRegionOps mipsnet_ioport_ops = { + .read = mipsnet_ioport_read, + .write = mipsnet_ioport_write, + .impl.min_access_size = 1, + .impl.max_access_size = 4, +}; - s = qemu_mallocz(sizeof(MIPSnetState)); +static int mipsnet_sysbus_init(SysBusDevice *dev) +{ + MIPSnetState *s = DO_UPCAST(MIPSnetState, busdev, dev); - register_ioport_write(base, 36, 1, mipsnet_ioport_write, s); - register_ioport_read(base, 36, 1, mipsnet_ioport_read, s); - register_ioport_write(base, 36, 2, mipsnet_ioport_write, s); - register_ioport_read(base, 36, 2, mipsnet_ioport_read, s); - register_ioport_write(base, 36, 4, mipsnet_ioport_write, s); - register_ioport_read(base, 36, 4, mipsnet_ioport_read, s); + memory_region_init_io(&s->io, &mipsnet_ioport_ops, s, "mipsnet-io", 36); + sysbus_init_mmio_region(dev, &s->io); + sysbus_init_irq(dev, &s->irq); - s->io_base = base; - s->irq = irq; + s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, + dev->qdev.info->name, dev->qdev.id, s); + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); - if (nd) { - memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr)); - s->conf.vlan = nd->vlan; - s->conf.peer = nd->netdev; + return 0; +} - s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, - nd->model, nd->name, s); +static void mipsnet_sysbus_reset(DeviceState *dev) +{ + MIPSnetState *s = DO_UPCAST(MIPSnetState, busdev.qdev, dev); + mipsnet_reset(s); +} - qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); +static SysBusDeviceInfo mipsnet_info = { + .init = mipsnet_sysbus_init, + .qdev.name = "mipsnet", + .qdev.desc = "MIPS Simulator network device", + .qdev.size = sizeof(MIPSnetState), + .qdev.vmsd = &vmstate_mipsnet, + .qdev.reset = mipsnet_sysbus_reset, + .qdev.props = (Property[]) { + DEFINE_NIC_PROPERTIES(MIPSnetState, conf), + DEFINE_PROP_END_OF_LIST(), } +}; - mipsnet_reset(s); - register_savevm(NULL, "mipsnet", 0, 0, mipsnet_save, mipsnet_load, s); +static void mipsnet_register_devices(void) +{ + sysbus_register_withprop(&mipsnet_info); } + +device_init(mipsnet_register_devices) diff --git a/hw/mpcore.c b/hw/mpcore.c index fc05215..d6175cf 100644 --- a/hw/mpcore.c +++ b/hw/mpcore.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -40,6 +40,8 @@ typedef struct mpcore_priv_state { int iomemtype; mpcore_timer_state timer[8]; uint32_t num_cpu; + MemoryRegion iomem; + MemoryRegion container; } mpcore_priv_state; /* Per-CPU Timers. */ @@ -63,7 +65,7 @@ static void mpcore_timer_reload(mpcore_timer_state *s, int restart) if (s->count == 0) return; if (restart) - s->tick = qemu_get_clock(vm_clock); + s->tick = qemu_get_clock_ns(vm_clock); s->tick += (int64_t)s->count * mpcore_timer_scale(s); qemu_mod_timer(s->timer, s->tick); } @@ -92,7 +94,7 @@ static uint32_t mpcore_timer_read(mpcore_timer_state *s, int offset) if (((s->control & 1) == 0) || (s->count == 0)) return 0; /* Slow and ugly, but hopefully won't happen too often. */ - val = s->tick - qemu_get_clock(vm_clock); + val = s->tick - qemu_get_clock_ns(vm_clock); val /= mpcore_timer_scale(s); if (val < 0) val = 0; @@ -145,13 +147,14 @@ static void mpcore_timer_init(mpcore_priv_state *mpcore, { s->id = id; s->mpcore = mpcore; - s->timer = qemu_new_timer(vm_clock, mpcore_timer_tick, s); + s->timer = qemu_new_timer_ns(vm_clock, mpcore_timer_tick, s); } /* Per-CPU private memory mapped IO. */ -static uint32_t mpcore_priv_read(void *opaque, target_phys_addr_t offset) +static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset, + unsigned size) { mpcore_priv_state *s = (mpcore_priv_state *)opaque; int id; @@ -203,7 +206,7 @@ bad_reg: } static void mpcore_priv_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { mpcore_priv_state *s = (mpcore_priv_state *)opaque; int id; @@ -250,23 +253,19 @@ bad_reg: hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset); } -static CPUReadMemoryFunc * const mpcore_priv_readfn[] = { - mpcore_priv_read, - mpcore_priv_read, - mpcore_priv_read +static const MemoryRegionOps mpcore_priv_ops = { + .read = mpcore_priv_read, + .write = mpcore_priv_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const mpcore_priv_writefn[] = { - mpcore_priv_write, - mpcore_priv_write, - mpcore_priv_write -}; - -static void mpcore_priv_map(SysBusDevice *dev, target_phys_addr_t base) +static void mpcore_priv_map_setup(mpcore_priv_state *s) { - mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev); - cpu_register_physical_memory(base, 0x1000, s->iomemtype); - cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype); + memory_region_init(&s->container, "mpcode-priv-container", 0x2000); + memory_region_init_io(&s->iomem, &mpcore_priv_ops, s, "mpcode-priv", + 0x1000); + memory_region_add_subregion(&s->container, 0, &s->iomem); + memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem); } static int mpcore_priv_init(SysBusDevice *dev) @@ -275,10 +274,8 @@ static int mpcore_priv_init(SysBusDevice *dev) int i; gic_init(&s->gic, s->num_cpu); - s->iomemtype = cpu_register_io_memory(mpcore_priv_readfn, - mpcore_priv_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio_cb(dev, 0x2000, mpcore_priv_map); + mpcore_priv_map_setup(s); + sysbus_init_mmio_region(dev, &s->container); for (i = 0; i < s->num_cpu * 2; i++) { mpcore_timer_init(s, &s->timer[i], i); } diff --git a/hw/msi.c b/hw/msi.c index 3dc3a24..f214fcf 100644 --- a/hw/msi.c +++ b/hw/msi.c @@ -155,7 +155,7 @@ int msi_init(struct PCIDevice *dev, uint8_t offset, pci_set_word(dev->wmask + msi_data_off(dev, msi64bit), 0xffff); if (msi_per_vector_mask) { - /* Make mask bits 0 to nr_vectors - 1 writeable. */ + /* Make mask bits 0 to nr_vectors - 1 writable. */ pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit), 0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors)); } @@ -164,9 +164,17 @@ int msi_init(struct PCIDevice *dev, uint8_t offset, void msi_uninit(struct PCIDevice *dev) { - uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); - uint8_t cap_size = msi_cap_sizeof(flags); - pci_del_capability(dev, PCI_CAP_ID_MSIX, cap_size); + uint16_t flags; + uint8_t cap_size; + + if (!(dev->cap_present & QEMU_PCI_CAP_MSI)) { + return; + } + flags = pci_get_word(dev->config + msi_flags_off(dev)); + cap_size = msi_cap_sizeof(flags); + pci_del_capability(dev, PCI_CAP_ID_MSI, cap_size); + dev->cap_present &= ~QEMU_PCI_CAP_MSI; + MSI_DEV_PRINTF(dev, "uninit\n"); } @@ -241,7 +249,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector) "notify vector 0x%x" " address: 0x%"PRIx64" data: 0x%"PRIx32"\n", vector, address, data); - stl_phys(address, data); + stl_le_phys(address, data); } /* call this function after updating configs by pci_default_write_config(). */ diff --git a/hw/msix.c b/hw/msix.c index daaf9b7..149eed2 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -16,9 +16,6 @@ #include "pci.h" #include "range.h" -/* MSI-X capability structure */ -#define MSIX_TABLE_OFFSET 4 -#define MSIX_PBA_OFFSET 8 #define MSIX_CAP_LENGTH 12 /* MSI enable bit and maskall bit are in byte 1 in FLAGS register */ @@ -26,14 +23,6 @@ #define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8) #define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8) -/* MSI-X table format */ -#define MSIX_MSG_ADDR 0 -#define MSIX_MSG_UPPER_ADDR 4 -#define MSIX_MSG_DATA 8 -#define MSIX_VECTOR_CTRL 12 -#define MSIX_ENTRY_SIZE 16 -#define MSIX_VECTOR_MASK 0x1 - /* How much space does an MSIX table need. */ /* The spec requires giving the table structure * a 4K aligned region all by itself. */ @@ -82,18 +71,20 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries, pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1); /* Table on top of BAR */ - pci_set_long(config + MSIX_TABLE_OFFSET, bar_size | bar_nr); + pci_set_long(config + PCI_MSIX_TABLE, bar_size | bar_nr); /* Pending bits on top of that */ - pci_set_long(config + MSIX_PBA_OFFSET, (bar_size + MSIX_PAGE_PENDING) | + pci_set_long(config + PCI_MSIX_PBA, (bar_size + MSIX_PAGE_PENDING) | bar_nr); pdev->msix_cap = config_offset; - /* Make flags bit writeable. */ + /* Make flags bit writable. */ pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK | MSIX_MASKALL_MASK; + pdev->msix_function_masked = true; return 0; } -static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr) +static uint64_t msix_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PCIDevice *dev = opaque; unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3; @@ -102,12 +93,6 @@ static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr) return pci_get_long(page + offset); } -static uint32_t msix_mmio_read_unallowed(void *opaque, target_phys_addr_t addr) -{ - fprintf(stderr, "MSI-X: only dword read is allowed!\n"); - return 0; -} - static uint8_t msix_pending_mask(int vector) { return 1 << (vector % 8); @@ -133,107 +118,120 @@ static void msix_clr_pending(PCIDevice *dev, int vector) *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector); } -static int msix_function_masked(PCIDevice *dev) +static bool msix_vector_masked(PCIDevice *dev, int vector, bool fmask) { - return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK; + unsigned offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL; + return fmask || dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT; } -static int msix_is_masked(PCIDevice *dev, int vector) +static bool msix_is_masked(PCIDevice *dev, int vector) { - unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL; - return msix_function_masked(dev) || - dev->msix_table_page[offset] & MSIX_VECTOR_MASK; + return msix_vector_masked(dev, vector, dev->msix_function_masked); } -static void msix_handle_mask_update(PCIDevice *dev, int vector) +static void msix_handle_mask_update(PCIDevice *dev, int vector, bool was_masked) { - if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) { + bool is_masked = msix_is_masked(dev, vector); + if (is_masked == was_masked) { + return; + } + + if (!is_masked && msix_is_pending(dev, vector)) { msix_clr_pending(dev, vector); msix_notify(dev, vector); } } +static void msix_update_function_masked(PCIDevice *dev) +{ + dev->msix_function_masked = !msix_enabled(dev) || + (dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK); +} + /* Handle MSI-X capability config write. */ void msix_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len) { unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET; int vector; + bool was_masked; if (!range_covers_byte(addr, len, enable_pos)) { return; } + was_masked = dev->msix_function_masked; + msix_update_function_masked(dev); + if (!msix_enabled(dev)) { return; } pci_device_deassert_intx(dev); - if (msix_function_masked(dev)) { + if (dev->msix_function_masked == was_masked) { return; } for (vector = 0; vector < dev->msix_entries_nr; ++vector) { - msix_handle_mask_update(dev, vector); + msix_handle_mask_update(dev, vector, + msix_vector_masked(dev, vector, was_masked)); } } -static void msix_mmio_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void msix_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { PCIDevice *dev = opaque; unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3; - int vector = offset / MSIX_ENTRY_SIZE; - pci_set_long(dev->msix_table_page + offset, val); - msix_handle_mask_update(dev, vector); -} + int vector = offset / PCI_MSIX_ENTRY_SIZE; + bool was_masked; -static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - fprintf(stderr, "MSI-X: only dword write is allowed!\n"); -} + /* MSI-X page includes a read-only PBA and a writeable Vector Control. */ + if (vector >= dev->msix_entries_nr) { + return; + } -static CPUWriteMemoryFunc * const msix_mmio_write[] = { - msix_mmio_write_unallowed, msix_mmio_write_unallowed, msix_mmio_writel -}; + was_masked = msix_is_masked(dev, vector); + pci_set_long(dev->msix_table_page + offset, val); + msix_handle_mask_update(dev, vector, was_masked); +} -static CPUReadMemoryFunc * const msix_mmio_read[] = { - msix_mmio_read_unallowed, msix_mmio_read_unallowed, msix_mmio_readl +static const MemoryRegionOps msix_mmio_ops = { + .read = msix_mmio_read, + .write = msix_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; -/* Should be called from device's map method. */ -void msix_mmio_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void msix_mmio_setup(PCIDevice *d, MemoryRegion *bar) { uint8_t *config = d->config + d->msix_cap; - uint32_t table = pci_get_long(config + MSIX_TABLE_OFFSET); + uint32_t table = pci_get_long(config + PCI_MSIX_TABLE); uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1); /* TODO: for assigned devices, we'll want to make it possible to map * pending bits separately in case they are in a separate bar. */ - int table_bir = table & PCI_MSIX_FLAGS_BIRMASK; - if (table_bir != region_num) - return; - if (size <= offset) - return; - cpu_register_physical_memory(addr + offset, size - offset, - d->msix_mmio_index); + memory_region_add_subregion(bar, offset, &d->msix_mmio); } static void msix_mask_all(struct PCIDevice *dev, unsigned nentries) { int vector; for (vector = 0; vector < nentries; ++vector) { - unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL; - dev->msix_table_page[offset] |= MSIX_VECTOR_MASK; + unsigned offset = + vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL; + dev->msix_table_page[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT; } } /* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is * modified, it should be retrieved with msix_bar_size. */ int msix_init(struct PCIDevice *dev, unsigned short nentries, + MemoryRegion *bar, unsigned bar_nr, unsigned bar_size) { int ret; @@ -244,19 +242,14 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, if (nentries > MSIX_MAX_ENTRIES) return -EINVAL; - dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES * + dev->msix_entry_used = g_malloc0(MSIX_MAX_ENTRIES * sizeof *dev->msix_entry_used); - dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE); + dev->msix_table_page = g_malloc0(MSIX_PAGE_SIZE); msix_mask_all(dev, nentries); - dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read, - msix_mmio_write, dev, - DEVICE_NATIVE_ENDIAN); - if (dev->msix_mmio_index == -1) { - ret = -EBUSY; - goto err_index; - } + memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev, + "msix", MSIX_PAGE_SIZE); dev->msix_entries_nr = nentries; ret = msix_add_config(dev, nentries, bar_nr, bar_size); @@ -264,15 +257,15 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, goto err_config; dev->cap_present |= QEMU_PCI_CAP_MSIX; + msix_mmio_setup(dev, bar); return 0; err_config: dev->msix_entries_nr = 0; - cpu_unregister_io_memory(dev->msix_mmio_index); -err_index: - qemu_free(dev->msix_table_page); + memory_region_destroy(&dev->msix_mmio); + g_free(dev->msix_table_page); dev->msix_table_page = NULL; - qemu_free(dev->msix_entry_used); + g_free(dev->msix_entry_used); dev->msix_entry_used = NULL; return ret; } @@ -288,7 +281,7 @@ static void msix_free_irq_entries(PCIDevice *dev) } /* Clean up resources for the device. */ -int msix_uninit(PCIDevice *dev) +int msix_uninit(PCIDevice *dev, MemoryRegion *bar) { if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) return 0; @@ -296,10 +289,11 @@ int msix_uninit(PCIDevice *dev) dev->msix_cap = 0; msix_free_irq_entries(dev); dev->msix_entries_nr = 0; - cpu_unregister_io_memory(dev->msix_mmio_index); - qemu_free(dev->msix_table_page); + memory_region_del_subregion(bar, &dev->msix_mmio); + memory_region_destroy(&dev->msix_mmio); + g_free(dev->msix_table_page); dev->msix_table_page = NULL; - qemu_free(dev->msix_entry_used); + g_free(dev->msix_entry_used); dev->msix_entry_used = NULL; dev->cap_present &= ~QEMU_PCI_CAP_MSIX; return 0; @@ -313,7 +307,7 @@ void msix_save(PCIDevice *dev, QEMUFile *f) return; } - qemu_put_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE); + qemu_put_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE); qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8); } @@ -327,8 +321,9 @@ void msix_load(PCIDevice *dev, QEMUFile *f) } msix_free_irq_entries(dev); - qemu_get_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE); + qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE); qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8); + msix_update_function_masked(dev); } /* Does device support MSI-X? */ @@ -355,7 +350,7 @@ uint32_t msix_bar_size(PCIDevice *dev) /* Send an MSI-X message */ void msix_notify(PCIDevice *dev, unsigned vector) { - uint8_t *table_entry = dev->msix_table_page + vector * MSIX_ENTRY_SIZE; + uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE; uint64_t address; uint32_t data; @@ -366,10 +361,9 @@ void msix_notify(PCIDevice *dev, unsigned vector) return; } - address = pci_get_long(table_entry + MSIX_MSG_UPPER_ADDR); - address = (address << 32) | pci_get_long(table_entry + MSIX_MSG_ADDR); - data = pci_get_long(table_entry + MSIX_MSG_DATA); - stl_phys(address, data); + address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR); + data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA); + stl_le_phys(address, data); } void msix_reset(PCIDevice *dev) diff --git a/hw/msix.h b/hw/msix.h index a9f7993..7e04336 100644 --- a/hw/msix.h +++ b/hw/msix.h @@ -5,15 +5,13 @@ #include "pci.h" int msix_init(PCIDevice *pdev, unsigned short nentries, + MemoryRegion *bar, unsigned bar_nr, unsigned bar_size); void msix_write_config(PCIDevice *pci_dev, uint32_t address, uint32_t val, int len); -void msix_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type); - -int msix_uninit(PCIDevice *d); +int msix_uninit(PCIDevice *d, MemoryRegion *bar); void msix_save(PCIDevice *dev, QEMUFile *f); void msix_load(PCIDevice *dev, QEMUFile *f); diff --git a/hw/msmouse.c b/hw/msmouse.c index 05f893c..c3b57ea 100644 --- a/hw/msmouse.c +++ b/hw/msmouse.c @@ -50,7 +50,7 @@ static void msmouse_event(void *opaque, /* We always send the packet of, so that we do not have to keep track of previous state of the middle button. This can potentially confuse some very old drivers for two button mice though. */ - qemu_chr_read(chr, bytes, 4); + qemu_chr_be_write(chr, bytes, 4); } static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len) @@ -61,18 +61,19 @@ static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int static void msmouse_chr_close (struct CharDriverState *chr) { - qemu_free (chr); + g_free (chr); } -CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts) +int qemu_chr_open_msmouse(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; - chr = qemu_mallocz(sizeof(CharDriverState)); + chr = g_malloc0(sizeof(CharDriverState)); chr->chr_write = msmouse_chr_write; chr->chr_close = msmouse_chr_close; qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse"); - return chr; + *_chr = chr; + return 0; } diff --git a/hw/msmouse.h b/hw/msmouse.h index 456cb21..8b853b3 100644 --- a/hw/msmouse.h +++ b/hw/msmouse.h @@ -1,2 +1,2 @@ /* msmouse.c */ -CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts); +int qemu_chr_open_msmouse(QemuOpts *opts, CharDriverState **_chr); diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c index 5252fc5..7bcd5d7 100644 --- a/hw/mst_fpga.c +++ b/hw/mst_fpga.c @@ -8,8 +8,7 @@ * This code is licensed under the GNU GPL v2. */ #include "hw.h" -#include "pxa.h" -#include "mainstone.h" +#include "sysbus.h" /* Mainstone FPGA for extern irqs */ #define FPGA_GPIO_PIN 0 @@ -27,9 +26,16 @@ #define MST_PCMCIA0 0xe0 #define MST_PCMCIA1 0xe4 +#define MST_PCMCIAx_READY (1 << 10) +#define MST_PCMCIAx_nCD (1 << 5) + +#define MST_PCMCIA_CD0_IRQ 9 +#define MST_PCMCIA_CD1_IRQ 13 + typedef struct mst_irq_state{ - qemu_irq *parent; - qemu_irq *pins; + SysBusDevice busdev; + + qemu_irq parent; uint32_t prev_level; uint32_t leddat1; @@ -47,33 +53,36 @@ typedef struct mst_irq_state{ }mst_irq_state; static void -mst_fpga_update_gpio(mst_irq_state *s) -{ - uint32_t level, diff; - int bit; - level = s->prev_level ^ s->intsetclr; - - for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ffs(diff) - 1; - qemu_set_irq(s->pins[bit], (level >> bit) & 1 ); - } - s->prev_level = level; -} - -static void mst_fpga_set_irq(void *opaque, int irq, int level) { mst_irq_state *s = (mst_irq_state *)opaque; + uint32_t oldint = s->intsetclr & s->intmskena; if (level) s->prev_level |= 1u << irq; else s->prev_level &= ~(1u << irq); - if(s->intmskena & (1u << irq)) { - s->intsetclr = 1u << irq; - qemu_set_irq(s->parent[0], level); + switch(irq) { + case MST_PCMCIA_CD0_IRQ: + if (level) + s->pcmcia0 &= ~MST_PCMCIAx_nCD; + else + s->pcmcia0 |= MST_PCMCIAx_nCD; + break; + case MST_PCMCIA_CD1_IRQ: + if (level) + s->pcmcia1 &= ~MST_PCMCIAx_nCD; + else + s->pcmcia1 |= MST_PCMCIAx_nCD; + break; } + + if ((s->intmskena & (1u << irq)) && level) + s->intsetclr |= 1u << irq; + + if (oldint != (s->intsetclr & s->intmskena)) + qemu_set_irq(s->parent, s->intsetclr & s->intmskena); } @@ -109,7 +118,7 @@ mst_fpga_readb(void *opaque, target_phys_addr_t addr) return s->pcmcia1; default: printf("Mainstone - mst_fpga_readb: Bad register offset " - REG_FMT " \n", addr); + "0x" TARGET_FMT_plx "\n", addr); } return 0; } @@ -145,22 +154,24 @@ mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) case MST_MSCRD: s->mscrd = value; break; - case MST_INTMSKENA: /* Mask interupt */ + case MST_INTMSKENA: /* Mask interrupt */ s->intmskena = (value & 0xFEEFF); - mst_fpga_update_gpio(s); + qemu_set_irq(s->parent, s->intsetclr & s->intmskena); break; case MST_INTSETCLR: /* clear or set interrupt */ s->intsetclr = (value & 0xFEEFF); + qemu_set_irq(s->parent, s->intsetclr & s->intmskena); break; + /* For PCMCIAx allow the to change only power and reset */ case MST_PCMCIA0: - s->pcmcia0 = value; + s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f); break; case MST_PCMCIA1: - s->pcmcia1 = value; + s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f); break; default: printf("Mainstone - mst_fpga_writeb: Bad register offset " - REG_FMT " \n", addr); + "0x" TARGET_FMT_plx "\n", addr); } } @@ -175,66 +186,70 @@ static CPUWriteMemoryFunc * const mst_fpga_writefn[] = { mst_fpga_writeb, }; -static void -mst_fpga_save(QEMUFile *f, void *opaque) -{ - struct mst_irq_state *s = (mst_irq_state *) opaque; - - qemu_put_be32s(f, &s->prev_level); - qemu_put_be32s(f, &s->leddat1); - qemu_put_be32s(f, &s->leddat2); - qemu_put_be32s(f, &s->ledctrl); - qemu_put_be32s(f, &s->gpswr); - qemu_put_be32s(f, &s->mscwr1); - qemu_put_be32s(f, &s->mscwr2); - qemu_put_be32s(f, &s->mscwr3); - qemu_put_be32s(f, &s->mscrd); - qemu_put_be32s(f, &s->intmskena); - qemu_put_be32s(f, &s->intsetclr); - qemu_put_be32s(f, &s->pcmcia0); - qemu_put_be32s(f, &s->pcmcia1); -} -static int -mst_fpga_load(QEMUFile *f, void *opaque, int version_id) +static int mst_fpga_post_load(void *opaque, int version_id) { mst_irq_state *s = (mst_irq_state *) opaque; - qemu_get_be32s(f, &s->prev_level); - qemu_get_be32s(f, &s->leddat1); - qemu_get_be32s(f, &s->leddat2); - qemu_get_be32s(f, &s->ledctrl); - qemu_get_be32s(f, &s->gpswr); - qemu_get_be32s(f, &s->mscwr1); - qemu_get_be32s(f, &s->mscwr2); - qemu_get_be32s(f, &s->mscwr3); - qemu_get_be32s(f, &s->mscrd); - qemu_get_be32s(f, &s->intmskena); - qemu_get_be32s(f, &s->intsetclr); - qemu_get_be32s(f, &s->pcmcia0); - qemu_get_be32s(f, &s->pcmcia1); + qemu_set_irq(s->parent, s->intsetclr & s->intmskena); return 0; } -qemu_irq *mst_irq_init(PXA2xxState *cpu, uint32_t base, int irq) +static int mst_fpga_init(SysBusDevice *dev) { mst_irq_state *s; int iomemtype; - qemu_irq *qi; - s = (mst_irq_state *) - qemu_mallocz(sizeof(mst_irq_state)); + s = FROM_SYSBUS(mst_irq_state, dev); - s->parent = &cpu->pic[irq]; + s->pcmcia0 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD; + s->pcmcia1 = MST_PCMCIAx_READY | MST_PCMCIAx_nCD; + + sysbus_init_irq(dev, &s->parent); /* alloc the external 16 irqs */ - qi = qemu_allocate_irqs(mst_fpga_set_irq, s, MST_NUM_IRQS); - s->pins = qi; + qdev_init_gpio_in(&dev->qdev, mst_fpga_set_irq, MST_NUM_IRQS); iomemtype = cpu_register_io_memory(mst_fpga_readfn, mst_fpga_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x00100000, iomemtype); - register_savevm(NULL, "mainstone_fpga", 0, 0, mst_fpga_save, - mst_fpga_load, s); - return qi; + sysbus_init_mmio(dev, 0x00100000, iomemtype); + return 0; +} + +static VMStateDescription vmstate_mst_fpga_regs = { + .name = "mainstone_fpga", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = mst_fpga_post_load, + .fields = (VMStateField []) { + VMSTATE_UINT32(prev_level, mst_irq_state), + VMSTATE_UINT32(leddat1, mst_irq_state), + VMSTATE_UINT32(leddat2, mst_irq_state), + VMSTATE_UINT32(ledctrl, mst_irq_state), + VMSTATE_UINT32(gpswr, mst_irq_state), + VMSTATE_UINT32(mscwr1, mst_irq_state), + VMSTATE_UINT32(mscwr2, mst_irq_state), + VMSTATE_UINT32(mscwr3, mst_irq_state), + VMSTATE_UINT32(mscrd, mst_irq_state), + VMSTATE_UINT32(intmskena, mst_irq_state), + VMSTATE_UINT32(intsetclr, mst_irq_state), + VMSTATE_UINT32(pcmcia0, mst_irq_state), + VMSTATE_UINT32(pcmcia1, mst_irq_state), + VMSTATE_END_OF_LIST(), + }, +}; + +static SysBusDeviceInfo mst_fpga_info = { + .init = mst_fpga_init, + .qdev.name = "mainstone-fpga", + .qdev.desc = "Mainstone II FPGA", + .qdev.size = sizeof(mst_irq_state), + .qdev.vmsd = &vmstate_mst_fpga_regs, +}; + +static void mst_fpga_register(void) +{ + sysbus_register_withprop(&mst_fpga_info); } +device_init(mst_fpga_register); diff --git a/hw/multiboot.c b/hw/multiboot.c index 0d2bfb4..b4484a3 100644 --- a/hw/multiboot.c +++ b/hw/multiboot.c @@ -97,11 +97,11 @@ typedef struct { static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline) { - int len = strlen(cmdline) + 1; target_phys_addr_t p = s->offset_cmdlines; + char *b = (char *)s->mb_buf + p; - pstrcpy((char *)s->mb_buf + p, len, cmdline); - s->offset_cmdlines += len; + get_opt_value(b, strlen(cmdline) + 1, cmdline); + s->offset_cmdlines += strlen(b) + 1; return s->mb_buf_phys + p; } @@ -187,7 +187,7 @@ int load_multiboot(void *fw_cfg, mb_kernel_size = elf_high - elf_low; mh_entry_addr = elf_entry; - mbs.mb_buf = qemu_malloc(mb_kernel_size); + mbs.mb_buf = g_malloc(mb_kernel_size); if (rom_copy(mbs.mb_buf, mh_load_addr, mb_kernel_size) != mb_kernel_size) { fprintf(stderr, "Error while fetching elf kernel from rom\n"); exit(1); @@ -198,11 +198,14 @@ int load_multiboot(void *fw_cfg, } else { /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */ uint32_t mh_header_addr = ldl_p(header+i+12); + uint32_t mh_load_end_addr = ldl_p(header+i+20); + uint32_t mh_bss_end_addr = ldl_p(header+i+24); mh_load_addr = ldl_p(header+i+16); uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr); + uint32_t mb_load_size = mh_load_end_addr - mh_load_addr; mh_entry_addr = ldl_p(header+i+28); - mb_kernel_size = kernel_file_size - mb_kernel_text_offset; + mb_kernel_size = mh_bss_end_addr - mh_load_addr; /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE. uint32_t mh_mode_type = ldl_p(header+i+32); @@ -212,17 +215,18 @@ int load_multiboot(void *fw_cfg, mb_debug("multiboot: mh_header_addr = %#x\n", mh_header_addr); mb_debug("multiboot: mh_load_addr = %#x\n", mh_load_addr); - mb_debug("multiboot: mh_load_end_addr = %#x\n", ldl_p(header+i+20)); - mb_debug("multiboot: mh_bss_end_addr = %#x\n", ldl_p(header+i+24)); + mb_debug("multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr); + mb_debug("multiboot: mh_bss_end_addr = %#x\n", mh_bss_end_addr); mb_debug("qemu: loading multiboot kernel (%#x bytes) at %#x\n", - mb_kernel_size, mh_load_addr); + mb_load_size, mh_load_addr); - mbs.mb_buf = qemu_malloc(mb_kernel_size); + mbs.mb_buf = g_malloc(mb_kernel_size); fseek(f, mb_kernel_text_offset, SEEK_SET); - if (fread(mbs.mb_buf, 1, mb_kernel_size, f) != mb_kernel_size) { + if (fread(mbs.mb_buf, 1, mb_load_size, f) != mb_load_size) { fprintf(stderr, "fread() failed\n"); exit(1); } + memset(mbs.mb_buf + mb_load_size, 0, mb_kernel_size - mb_load_size); fclose(f); } @@ -238,7 +242,7 @@ int load_multiboot(void *fw_cfg, const char *r = initrd_filename; mbs.mb_buf_size += strlen(r) + 1; mbs.mb_mods_avail = 1; - while ((r = strchr(r, ','))) { + while (*(r = get_opt_value(NULL, 0, r))) { mbs.mb_mods_avail++; r++; } @@ -248,11 +252,11 @@ int load_multiboot(void *fw_cfg, mbs.mb_buf_size = TARGET_PAGE_ALIGN(mbs.mb_buf_size); /* enlarge mb_buf to hold cmdlines and mb-info structs */ - mbs.mb_buf = qemu_realloc(mbs.mb_buf, mbs.mb_buf_size); + mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size); mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE; if (initrd_filename) { - char *next_initrd; + char *next_initrd, not_last; mbs.offset_mods = mbs.mb_buf_size; @@ -261,9 +265,9 @@ int load_multiboot(void *fw_cfg, int mb_mod_length; uint32_t offs = mbs.mb_buf_size; - next_initrd = strchr(initrd_filename, ','); - if (next_initrd) - *next_initrd = '\0'; + next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename); + not_last = *next_initrd; + *next_initrd = '\0'; /* if a space comes after the module filename, treat everything after that as parameters */ target_phys_addr_t c = mb_add_cmdline(&mbs, initrd_filename); @@ -272,12 +276,12 @@ int load_multiboot(void *fw_cfg, mb_debug("multiboot loading module: %s\n", initrd_filename); mb_mod_length = get_image_size(initrd_filename); if (mb_mod_length < 0) { - fprintf(stderr, "failed to get %s image size\n", initrd_filename); + fprintf(stderr, "Failed to open file '%s'\n", initrd_filename); exit(1); } mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size); - mbs.mb_buf = qemu_realloc(mbs.mb_buf, mbs.mb_buf_size); + mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size); load_image(initrd_filename, (unsigned char *)mbs.mb_buf + offs); mb_add_mod(&mbs, mbs.mb_buf_phys + offs, @@ -287,7 +291,7 @@ int load_multiboot(void *fw_cfg, (char *)mbs.mb_buf + offs, (char *)mbs.mb_buf + offs + mb_mod_length, c); initrd_filename = next_initrd+1; - } while (next_initrd); + } while (not_last); } /* Commandline support */ @@ -307,7 +311,7 @@ int load_multiboot(void *fw_cfg, | MULTIBOOT_FLAGS_MMAP); stl_p(bootinfo + MBI_MEM_LOWER, 640); stl_p(bootinfo + MBI_MEM_UPPER, (ram_size / 1024) - 1024); - stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8001ffff); /* XXX: use the -boot switch? */ + stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8000ffff); /* XXX: use the -boot switch? */ stl_p(bootinfo + MBI_MMAP_ADDR, ADDR_E820_MAP); mb_debug("multiboot: mh_entry_addr = %#x\n", mh_entry_addr); @@ -316,7 +320,7 @@ int load_multiboot(void *fw_cfg, mb_debug(" mb_mods_count = %d\n", mbs.mb_mods_count); /* save bootinfo off the stack */ - mb_bootinfo_data = qemu_malloc(sizeof(bootinfo)); + mb_bootinfo_data = g_malloc(sizeof(bootinfo)); memcpy(mb_bootinfo_data, bootinfo, sizeof(bootinfo)); /* Pass variables to option rom */ diff --git a/hw/musicpal.c b/hw/musicpal.c index d98aa8d..20553b5 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -3,7 +3,7 @@ * * Copyright (c) 2008 Jan Kiszka * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #include "sysbus.h" @@ -19,6 +19,7 @@ #include "console.h" #include "i2c.h" #include "blockdev.h" +#include "exec-memory.h" #define MP_MISC_BASE 0x80002000 #define MP_MISC_SIZE 0x00001000 @@ -142,6 +143,7 @@ typedef struct mv88w8618_rx_desc { typedef struct mv88w8618_eth_state { SysBusDevice busdev; + MemoryRegion iomem; qemu_irq irq; uint32_t smir; uint32_t icr; @@ -260,7 +262,8 @@ static void eth_send(mv88w8618_eth_state *s, int queue_index) } while (desc_addr != s->tx_queue[queue_index]); } -static uint32_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset) +static uint64_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset, + unsigned size) { mv88w8618_eth_state *s = opaque; @@ -302,7 +305,7 @@ static uint32_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset) } static void mv88w8618_eth_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { mv88w8618_eth_state *s = opaque; @@ -353,16 +356,10 @@ static void mv88w8618_eth_write(void *opaque, target_phys_addr_t offset, } } -static CPUReadMemoryFunc * const mv88w8618_eth_readfn[] = { - mv88w8618_eth_read, - mv88w8618_eth_read, - mv88w8618_eth_read -}; - -static CPUWriteMemoryFunc * const mv88w8618_eth_writefn[] = { - mv88w8618_eth_write, - mv88w8618_eth_write, - mv88w8618_eth_write +static const MemoryRegionOps mv88w8618_eth_ops = { + .read = mv88w8618_eth_read, + .write = mv88w8618_eth_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void eth_cleanup(VLANClientState *nc) @@ -387,10 +384,9 @@ static int mv88w8618_eth_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf, dev->qdev.info->name, dev->qdev.id, s); - s->mmio_index = cpu_register_io_memory(mv88w8618_eth_readfn, - mv88w8618_eth_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MP_ETH_SIZE, s->mmio_index); + memory_region_init_io(&s->iomem, &mv88w8618_eth_ops, s, "mv88w8618-eth", + MP_ETH_SIZE); + sysbus_init_mmio_region(dev, &s->iomem); return 0; } @@ -444,6 +440,7 @@ static SysBusDeviceInfo mv88w8618_eth_info = { typedef struct musicpal_lcd_state { SysBusDevice busdev; + MemoryRegion iomem; uint32_t brightness; uint32_t mode; uint32_t irqctrl; @@ -528,7 +525,8 @@ static void musicpal_lcd_gpio_brigthness_in(void *opaque, int irq, int level) s->brightness |= level << irq; } -static uint32_t musicpal_lcd_read(void *opaque, target_phys_addr_t offset) +static uint64_t musicpal_lcd_read(void *opaque, target_phys_addr_t offset, + unsigned size) { musicpal_lcd_state *s = opaque; @@ -542,7 +540,7 @@ static uint32_t musicpal_lcd_read(void *opaque, target_phys_addr_t offset) } static void musicpal_lcd_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { musicpal_lcd_state *s = opaque; @@ -581,29 +579,21 @@ static void musicpal_lcd_write(void *opaque, target_phys_addr_t offset, } } -static CPUReadMemoryFunc * const musicpal_lcd_readfn[] = { - musicpal_lcd_read, - musicpal_lcd_read, - musicpal_lcd_read -}; - -static CPUWriteMemoryFunc * const musicpal_lcd_writefn[] = { - musicpal_lcd_write, - musicpal_lcd_write, - musicpal_lcd_write +static const MemoryRegionOps musicpal_lcd_ops = { + .read = musicpal_lcd_read, + .write = musicpal_lcd_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int musicpal_lcd_init(SysBusDevice *dev) { musicpal_lcd_state *s = FROM_SYSBUS(musicpal_lcd_state, dev); - int iomemtype; s->brightness = 7; - iomemtype = cpu_register_io_memory(musicpal_lcd_readfn, - musicpal_lcd_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MP_LCD_SIZE, iomemtype); + memory_region_init_io(&s->iomem, &musicpal_lcd_ops, s, + "musicpal-lcd", MP_LCD_SIZE); + sysbus_init_mmio_region(dev, &s->iomem); s->ds = graphic_console_init(lcd_refresh, lcd_invalidate, NULL, NULL, s); @@ -645,6 +635,7 @@ static SysBusDeviceInfo musicpal_lcd_info = { typedef struct mv88w8618_pic_state { SysBusDevice busdev; + MemoryRegion iomem; uint32_t level; uint32_t enabled; qemu_irq parent_irq; @@ -667,7 +658,8 @@ static void mv88w8618_pic_set_irq(void *opaque, int irq, int level) mv88w8618_pic_update(s); } -static uint32_t mv88w8618_pic_read(void *opaque, target_phys_addr_t offset) +static uint64_t mv88w8618_pic_read(void *opaque, target_phys_addr_t offset, + unsigned size) { mv88w8618_pic_state *s = opaque; @@ -681,7 +673,7 @@ static uint32_t mv88w8618_pic_read(void *opaque, target_phys_addr_t offset) } static void mv88w8618_pic_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { mv88w8618_pic_state *s = opaque; @@ -707,29 +699,21 @@ static void mv88w8618_pic_reset(DeviceState *d) s->enabled = 0; } -static CPUReadMemoryFunc * const mv88w8618_pic_readfn[] = { - mv88w8618_pic_read, - mv88w8618_pic_read, - mv88w8618_pic_read -}; - -static CPUWriteMemoryFunc * const mv88w8618_pic_writefn[] = { - mv88w8618_pic_write, - mv88w8618_pic_write, - mv88w8618_pic_write +static const MemoryRegionOps mv88w8618_pic_ops = { + .read = mv88w8618_pic_read, + .write = mv88w8618_pic_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int mv88w8618_pic_init(SysBusDevice *dev) { mv88w8618_pic_state *s = FROM_SYSBUS(mv88w8618_pic_state, dev); - int iomemtype; qdev_init_gpio_in(&dev->qdev, mv88w8618_pic_set_irq, 32); sysbus_init_irq(dev, &s->parent_irq); - iomemtype = cpu_register_io_memory(mv88w8618_pic_readfn, - mv88w8618_pic_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MP_PIC_SIZE, iomemtype); + memory_region_init_io(&s->iomem, &mv88w8618_pic_ops, s, + "musicpal-pic", MP_PIC_SIZE); + sysbus_init_mmio_region(dev, &s->iomem); return 0; } @@ -775,6 +759,7 @@ typedef struct mv88w8618_timer_state { typedef struct mv88w8618_pit_state { SysBusDevice busdev; + MemoryRegion iomem; mv88w8618_timer_state timer[4]; } mv88w8618_pit_state; @@ -797,7 +782,8 @@ static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s, s->ptimer = ptimer_init(bh); } -static uint32_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset) +static uint64_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset, + unsigned size) { mv88w8618_pit_state *s = opaque; mv88w8618_timer_state *t; @@ -813,7 +799,7 @@ static uint32_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset) } static void mv88w8618_pit_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { mv88w8618_pit_state *s = opaque; mv88w8618_timer_state *t; @@ -864,21 +850,14 @@ static void mv88w8618_pit_reset(DeviceState *d) } } -static CPUReadMemoryFunc * const mv88w8618_pit_readfn[] = { - mv88w8618_pit_read, - mv88w8618_pit_read, - mv88w8618_pit_read -}; - -static CPUWriteMemoryFunc * const mv88w8618_pit_writefn[] = { - mv88w8618_pit_write, - mv88w8618_pit_write, - mv88w8618_pit_write +static const MemoryRegionOps mv88w8618_pit_ops = { + .read = mv88w8618_pit_read, + .write = mv88w8618_pit_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int mv88w8618_pit_init(SysBusDevice *dev) { - int iomemtype; mv88w8618_pit_state *s = FROM_SYSBUS(mv88w8618_pit_state, dev); int i; @@ -888,10 +867,9 @@ static int mv88w8618_pit_init(SysBusDevice *dev) mv88w8618_timer_init(dev, &s->timer[i], 1000000); } - iomemtype = cpu_register_io_memory(mv88w8618_pit_readfn, - mv88w8618_pit_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MP_PIT_SIZE, iomemtype); + memory_region_init_io(&s->iomem, &mv88w8618_pit_ops, s, + "musicpal-pit", MP_PIT_SIZE); + sysbus_init_mmio_region(dev, &s->iomem); return 0; } @@ -932,11 +910,13 @@ static SysBusDeviceInfo mv88w8618_pit_info = { typedef struct mv88w8618_flashcfg_state { SysBusDevice busdev; + MemoryRegion iomem; uint32_t cfgr0; } mv88w8618_flashcfg_state; -static uint32_t mv88w8618_flashcfg_read(void *opaque, - target_phys_addr_t offset) +static uint64_t mv88w8618_flashcfg_read(void *opaque, + target_phys_addr_t offset, + unsigned size) { mv88w8618_flashcfg_state *s = opaque; @@ -950,7 +930,7 @@ static uint32_t mv88w8618_flashcfg_read(void *opaque, } static void mv88w8618_flashcfg_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { mv88w8618_flashcfg_state *s = opaque; @@ -961,28 +941,20 @@ static void mv88w8618_flashcfg_write(void *opaque, target_phys_addr_t offset, } } -static CPUReadMemoryFunc * const mv88w8618_flashcfg_readfn[] = { - mv88w8618_flashcfg_read, - mv88w8618_flashcfg_read, - mv88w8618_flashcfg_read -}; - -static CPUWriteMemoryFunc * const mv88w8618_flashcfg_writefn[] = { - mv88w8618_flashcfg_write, - mv88w8618_flashcfg_write, - mv88w8618_flashcfg_write +static const MemoryRegionOps mv88w8618_flashcfg_ops = { + .read = mv88w8618_flashcfg_read, + .write = mv88w8618_flashcfg_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int mv88w8618_flashcfg_init(SysBusDevice *dev) { - int iomemtype; mv88w8618_flashcfg_state *s = FROM_SYSBUS(mv88w8618_flashcfg_state, dev); s->cfgr0 = 0xfffe4285; /* Default as set by U-Boot for 8 MB flash */ - iomemtype = cpu_register_io_memory(mv88w8618_flashcfg_readfn, - mv88w8618_flashcfg_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MP_FLASHCFG_SIZE, iomemtype); + memory_region_init_io(&s->iomem, &mv88w8618_flashcfg_ops, s, + "musicpal-flashcfg", MP_FLASHCFG_SIZE); + sysbus_init_mmio_region(dev, &s->iomem); return 0; } @@ -1009,7 +981,8 @@ static SysBusDeviceInfo mv88w8618_flashcfg_info = { #define MP_BOARD_REVISION 0x31 -static uint32_t musicpal_misc_read(void *opaque, target_phys_addr_t offset) +static uint64_t musicpal_misc_read(void *opaque, target_phys_addr_t offset, + unsigned size) { switch (offset) { case MP_MISC_BOARD_REVISION: @@ -1021,37 +994,31 @@ static uint32_t musicpal_misc_read(void *opaque, target_phys_addr_t offset) } static void musicpal_misc_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { } -static CPUReadMemoryFunc * const musicpal_misc_readfn[] = { - musicpal_misc_read, - musicpal_misc_read, - musicpal_misc_read, -}; - -static CPUWriteMemoryFunc * const musicpal_misc_writefn[] = { - musicpal_misc_write, - musicpal_misc_write, - musicpal_misc_write, +static const MemoryRegionOps musicpal_misc_ops = { + .read = musicpal_misc_read, + .write = musicpal_misc_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static void musicpal_misc_init(void) +static void musicpal_misc_init(SysBusDevice *dev) { - int iomemtype; + MemoryRegion *iomem = g_new(MemoryRegion, 1); - iomemtype = cpu_register_io_memory(musicpal_misc_readfn, - musicpal_misc_writefn, NULL, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(MP_MISC_BASE, MP_MISC_SIZE, iomemtype); + memory_region_init_io(iomem, &musicpal_misc_ops, NULL, + "musicpal-misc", MP_MISC_SIZE); + sysbus_add_memory(dev, MP_MISC_BASE, iomem); } /* WLAN register offsets */ #define MP_WLAN_MAGIC1 0x11c #define MP_WLAN_MAGIC2 0x124 -static uint32_t mv88w8618_wlan_read(void *opaque, target_phys_addr_t offset) +static uint64_t mv88w8618_wlan_read(void *opaque, target_phys_addr_t offset, + unsigned size) { switch (offset) { /* Workaround to allow loading the binary-only wlandrv.ko crap @@ -1067,30 +1034,23 @@ static uint32_t mv88w8618_wlan_read(void *opaque, target_phys_addr_t offset) } static void mv88w8618_wlan_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { } -static CPUReadMemoryFunc * const mv88w8618_wlan_readfn[] = { - mv88w8618_wlan_read, - mv88w8618_wlan_read, - mv88w8618_wlan_read, -}; - -static CPUWriteMemoryFunc * const mv88w8618_wlan_writefn[] = { - mv88w8618_wlan_write, - mv88w8618_wlan_write, - mv88w8618_wlan_write, +static const MemoryRegionOps mv88w8618_wlan_ops = { + .read = mv88w8618_wlan_read, + .write =mv88w8618_wlan_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int mv88w8618_wlan_init(SysBusDevice *dev) { - int iomemtype; + MemoryRegion *iomem = g_new(MemoryRegion, 1); - iomemtype = cpu_register_io_memory(mv88w8618_wlan_readfn, - mv88w8618_wlan_writefn, NULL, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MP_WLAN_SIZE, iomemtype); + memory_region_init_io(iomem, &mv88w8618_wlan_ops, NULL, + "musicpal-wlan", MP_WLAN_SIZE); + sysbus_init_mmio_region(dev, iomem); return 0; } @@ -1118,6 +1078,7 @@ static int mv88w8618_wlan_init(SysBusDevice *dev) typedef struct musicpal_gpio_state { SysBusDevice busdev; + MemoryRegion iomem; uint32_t lcd_brightness; uint32_t out_state; uint32_t in_state; @@ -1190,7 +1151,8 @@ static void musicpal_gpio_pin_event(void *opaque, int pin, int level) } } -static uint32_t musicpal_gpio_read(void *opaque, target_phys_addr_t offset) +static uint64_t musicpal_gpio_read(void *opaque, target_phys_addr_t offset, + unsigned size) { musicpal_gpio_state *s = opaque; @@ -1229,7 +1191,7 @@ static uint32_t musicpal_gpio_read(void *opaque, target_phys_addr_t offset) } static void musicpal_gpio_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { musicpal_gpio_state *s = opaque; switch (offset) { @@ -1267,16 +1229,10 @@ static void musicpal_gpio_write(void *opaque, target_phys_addr_t offset, } } -static CPUReadMemoryFunc * const musicpal_gpio_readfn[] = { - musicpal_gpio_read, - musicpal_gpio_read, - musicpal_gpio_read, -}; - -static CPUWriteMemoryFunc * const musicpal_gpio_writefn[] = { - musicpal_gpio_write, - musicpal_gpio_write, - musicpal_gpio_write, +static const MemoryRegionOps musicpal_gpio_ops = { + .read = musicpal_gpio_read, + .write = musicpal_gpio_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void musicpal_gpio_reset(DeviceState *d) @@ -1295,14 +1251,12 @@ static void musicpal_gpio_reset(DeviceState *d) static int musicpal_gpio_init(SysBusDevice *dev) { musicpal_gpio_state *s = FROM_SYSBUS(musicpal_gpio_state, dev); - int iomemtype; sysbus_init_irq(dev, &s->irq); - iomemtype = cpu_register_io_memory(musicpal_gpio_readfn, - musicpal_gpio_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, MP_GPIO_SIZE, iomemtype); + memory_region_init_io(&s->iomem, &musicpal_gpio_ops, s, + "musicpal-gpio", MP_GPIO_SIZE); + sysbus_init_mmio_region(dev, &s->iomem); qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out)); @@ -1501,7 +1455,9 @@ static void musicpal_init(ram_addr_t ram_size, int i; unsigned long flash_size; DriveInfo *dinfo; - ram_addr_t sram_off; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *sram = g_new(MemoryRegion, 1); if (!cpu_model) { cpu_model = "arm926"; @@ -1514,12 +1470,11 @@ static void musicpal_init(ram_addr_t ram_size, cpu_pic = arm_pic_init_cpu(env); /* For now we use a fixed - the original - RAM size */ - cpu_register_physical_memory(0, MP_RAM_DEFAULT_SIZE, - qemu_ram_alloc(NULL, "musicpal.ram", - MP_RAM_DEFAULT_SIZE)); + memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE); + memory_region_add_subregion(address_space_mem, 0, ram); - sram_off = qemu_ram_alloc(NULL, "musicpal.sram", MP_SRAM_SIZE); - cpu_register_physical_memory(MP_SRAM_BASE, MP_SRAM_SIZE, sram_off); + memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE); + memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram); dev = sysbus_create_simple("mv88w8618_pic", MP_PIC_BASE, cpu_pic[ARM_PIC_CPU_IRQ]); @@ -1531,22 +1486,12 @@ static void musicpal_init(ram_addr_t ram_size, pic[MP_TIMER4_IRQ], NULL); if (serial_hds[0]) { -#ifdef TARGET_WORDS_BIGENDIAN - serial_mm_init(MP_UART1_BASE, 2, pic[MP_UART1_IRQ], 1825000, - serial_hds[0], 1, 1); -#else - serial_mm_init(MP_UART1_BASE, 2, pic[MP_UART1_IRQ], 1825000, - serial_hds[0], 1, 0); -#endif + serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ], + 1825000, serial_hds[0], DEVICE_NATIVE_ENDIAN); } if (serial_hds[1]) { -#ifdef TARGET_WORDS_BIGENDIAN - serial_mm_init(MP_UART2_BASE, 2, pic[MP_UART2_IRQ], 1825000, - serial_hds[1], 1, 1); -#else - serial_mm_init(MP_UART2_BASE, 2, pic[MP_UART2_IRQ], 1825000, - serial_hds[1], 1, 0); -#endif + serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ], + 1825000, serial_hds[1], DEVICE_NATIVE_ENDIAN); } /* Register flash */ @@ -1565,16 +1510,16 @@ static void musicpal_init(ram_addr_t ram_size, * image is smaller than 32 MB. */ #ifdef TARGET_WORDS_BIGENDIAN - pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL, - "musicpal.flash", flash_size), + pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL, + "musicpal.flash", flash_size, dinfo->bdrv, 0x10000, (flash_size + 0xffff) >> 16, MP_FLASH_SIZE_MAX / flash_size, 2, 0x00BF, 0x236D, 0x0000, 0x0000, 0x5555, 0x2AAA, 1); #else - pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL, - "musicpal.flash", flash_size), + pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL, + "musicpal.flash", flash_size, dinfo->bdrv, 0x10000, (flash_size + 0xffff) >> 16, MP_FLASH_SIZE_MAX / flash_size, @@ -1594,14 +1539,14 @@ static void musicpal_init(ram_addr_t ram_size, sysbus_create_simple("mv88w8618_wlan", MP_WLAN_BASE, NULL); - musicpal_misc_init(); + musicpal_misc_init(sysbus_from_qdev(dev)); dev = sysbus_create_simple("musicpal_gpio", MP_GPIO_BASE, pic[MP_GPIO_IRQ]); - i2c_dev = sysbus_create_simple("gpio_i2c", 0, NULL); + i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL); i2c = (i2c_bus *)qdev_get_child_bus(i2c_dev, "i2c"); lcd_dev = sysbus_create_simple("musicpal_lcd", MP_LCD_BASE, NULL); - key_dev = sysbus_create_simple("musicpal_key", 0, NULL); + key_dev = sysbus_create_simple("musicpal_key", -1, NULL); /* I2C read data */ qdev_connect_gpio_out(i2c_dev, 0, diff --git a/hw/nand.c b/hw/nand.c index f414aa1..7f25814 100644 --- a/hw/nand.c +++ b/hw/nand.c @@ -6,6 +6,10 @@ * Copyright (c) 2006 Openedhand Ltd. * Written by Andrzej Zaborowski * + * Support for additional features based on "MT29F2G16ABCWP 2Gx16" + * datasheet from Micron Technology and "NAND02G-B2C" datasheet + * from ST Microelectronics. + * * This code is licensed under the GNU GPL v2. */ @@ -14,7 +18,8 @@ # include "hw.h" # include "flash.h" # include "blockdev.h" -/* FIXME: Pass block device as an argument. */ +# include "sysbus.h" +#include "qemu-error.h" # define NAND_CMD_READ0 0x00 # define NAND_CMD_READ1 0x01 @@ -44,30 +49,45 @@ # define MAX_PAGE 0x800 # define MAX_OOB 0x40 +typedef struct NANDFlashState NANDFlashState; struct NANDFlashState { + SysBusDevice busdev; uint8_t manf_id, chip_id; + uint8_t buswidth; /* in BYTES */ int size, pages; int page_shift, oob_shift, erase_shift, addr_shift; uint8_t *storage; BlockDriverState *bdrv; int mem_oob; - int cle, ale, ce, wp, gnd; + uint8_t cle, ale, ce, wp, gnd; uint8_t io[MAX_PAGE + MAX_OOB + 0x400]; uint8_t *ioaddr; int iolen; - uint32_t cmd, addr; + uint32_t cmd; + uint64_t addr; int addrlen; int status; int offset; void (*blk_write)(NANDFlashState *s); void (*blk_erase)(NANDFlashState *s); - void (*blk_load)(NANDFlashState *s, uint32_t addr, int offset); + void (*blk_load)(NANDFlashState *s, uint64_t addr, int offset); + + uint32_t ioaddr_vmstate; }; +static void mem_and(uint8_t *dest, const uint8_t *src, size_t n) +{ + /* Like memcpy() but we logical-AND the data into the destination */ + int i; + for (i = 0; i < n; i++) { + dest[i] &= src[i]; + } +} + # define NAND_NO_AUTOINCR 0x00000001 # define NAND_BUSWIDTH_16 0x00000002 # define NAND_NO_PADDING 0x00000004 @@ -199,8 +219,9 @@ static const struct { [0xc5] = { 2048, 16, 0, 0, LP_OPTIONS16 }, }; -static void nand_reset(NANDFlashState *s) +static void nand_reset(DeviceState *dev) { + NANDFlashState *s = FROM_SYSBUS(NANDFlashState, sysbus_from_qdev(dev)); s->cmd = NAND_CMD_READ0; s->addr = 0; s->addrlen = 0; @@ -209,6 +230,14 @@ static void nand_reset(NANDFlashState *s) s->status &= NAND_IOSTATUS_UNPROTCT; } +static inline void nand_pushio_byte(NANDFlashState *s, uint8_t value) +{ + s->ioaddr[s->iolen++] = value; + for (value = s->buswidth; --value;) { + s->ioaddr[s->iolen++] = 0; + } +} + static void nand_command(NANDFlashState *s) { unsigned int offset; @@ -218,15 +247,19 @@ static void nand_command(NANDFlashState *s) break; case NAND_CMD_READID: - s->io[0] = s->manf_id; - s->io[1] = s->chip_id; - s->io[2] = 'Q'; /* Don't-care byte (often 0xa5) */ - if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) - s->io[3] = 0x15; /* Page Size, Block Size, Spare Size.. */ - else - s->io[3] = 0xc0; /* Multi-plane */ s->ioaddr = s->io; - s->iolen = 4; + s->iolen = 0; + nand_pushio_byte(s, s->manf_id); + nand_pushio_byte(s, s->chip_id); + nand_pushio_byte(s, 'Q'); /* Don't-care byte (often 0xa5) */ + if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { + /* Page Size, Block Size, Spare Size; bit 6 indicates + * 8 vs 16 bit width NAND. + */ + nand_pushio_byte(s, (s->buswidth == 2) ? 0x55 : 0x15); + } else { + nand_pushio_byte(s, 0xc0); /* Multi-plane */ + } break; case NAND_CMD_RANDOMREAD2: @@ -242,7 +275,7 @@ static void nand_command(NANDFlashState *s) break; case NAND_CMD_RESET: - nand_reset(s); + nand_reset(&s->busdev.qdev); break; case NAND_CMD_PAGEPROGRAM1: @@ -271,9 +304,9 @@ static void nand_command(NANDFlashState *s) break; case NAND_CMD_READSTATUS: - s->io[0] = s->status; s->ioaddr = s->io; - s->iolen = 1; + s->iolen = 0; + nand_pushio_byte(s, s->status); break; default: @@ -281,57 +314,135 @@ static void nand_command(NANDFlashState *s) } } -static void nand_save(QEMUFile *f, void *opaque) +static void nand_pre_save(void *opaque) { - NANDFlashState *s = (NANDFlashState *) opaque; - qemu_put_byte(f, s->cle); - qemu_put_byte(f, s->ale); - qemu_put_byte(f, s->ce); - qemu_put_byte(f, s->wp); - qemu_put_byte(f, s->gnd); - qemu_put_buffer(f, s->io, sizeof(s->io)); - qemu_put_be32(f, s->ioaddr - s->io); - qemu_put_be32(f, s->iolen); - - qemu_put_be32s(f, &s->cmd); - qemu_put_be32s(f, &s->addr); - qemu_put_be32(f, s->addrlen); - qemu_put_be32(f, s->status); - qemu_put_be32(f, s->offset); - /* XXX: do we want to save s->storage too? */ + NANDFlashState *s = opaque; + + s->ioaddr_vmstate = s->ioaddr - s->io; } -static int nand_load(QEMUFile *f, void *opaque, int version_id) +static int nand_post_load(void *opaque, int version_id) { - NANDFlashState *s = (NANDFlashState *) opaque; - s->cle = qemu_get_byte(f); - s->ale = qemu_get_byte(f); - s->ce = qemu_get_byte(f); - s->wp = qemu_get_byte(f); - s->gnd = qemu_get_byte(f); - qemu_get_buffer(f, s->io, sizeof(s->io)); - s->ioaddr = s->io + qemu_get_be32(f); - s->iolen = qemu_get_be32(f); - if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io) + NANDFlashState *s = opaque; + + if (s->ioaddr_vmstate > sizeof(s->io)) { return -EINVAL; + } + s->ioaddr = s->io + s->ioaddr_vmstate; - qemu_get_be32s(f, &s->cmd); - qemu_get_be32s(f, &s->addr); - s->addrlen = qemu_get_be32(f); - s->status = qemu_get_be32(f); - s->offset = qemu_get_be32(f); return 0; } +static const VMStateDescription vmstate_nand = { + .name = "nand", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_save = nand_pre_save, + .post_load = nand_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT8(cle, NANDFlashState), + VMSTATE_UINT8(ale, NANDFlashState), + VMSTATE_UINT8(ce, NANDFlashState), + VMSTATE_UINT8(wp, NANDFlashState), + VMSTATE_UINT8(gnd, NANDFlashState), + VMSTATE_BUFFER(io, NANDFlashState), + VMSTATE_UINT32(ioaddr_vmstate, NANDFlashState), + VMSTATE_INT32(iolen, NANDFlashState), + VMSTATE_UINT32(cmd, NANDFlashState), + VMSTATE_UINT64(addr, NANDFlashState), + VMSTATE_INT32(addrlen, NANDFlashState), + VMSTATE_INT32(status, NANDFlashState), + VMSTATE_INT32(offset, NANDFlashState), + /* XXX: do we want to save s->storage too? */ + VMSTATE_END_OF_LIST() + } +}; + +static int nand_device_init(SysBusDevice *dev) +{ + int pagesize; + NANDFlashState *s = FROM_SYSBUS(NANDFlashState, dev); + + s->buswidth = nand_flash_ids[s->chip_id].width >> 3; + s->size = nand_flash_ids[s->chip_id].size << 20; + if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { + s->page_shift = 11; + s->erase_shift = 6; + } else { + s->page_shift = nand_flash_ids[s->chip_id].page_shift; + s->erase_shift = nand_flash_ids[s->chip_id].erase_shift; + } + + switch (1 << s->page_shift) { + case 256: + nand_init_256(s); + break; + case 512: + nand_init_512(s); + break; + case 2048: + nand_init_2048(s); + break; + default: + error_report("Unsupported NAND block size"); + return -1; + } + + pagesize = 1 << s->oob_shift; + s->mem_oob = 1; + if (s->bdrv) { + if (bdrv_is_read_only(s->bdrv)) { + error_report("Can't use a read-only drive"); + return -1; + } + if (bdrv_getlength(s->bdrv) >= + (s->pages << s->page_shift) + (s->pages << s->oob_shift)) { + pagesize = 0; + s->mem_oob = 0; + } + } else { + pagesize += 1 << s->page_shift; + } + if (pagesize) { + s->storage = (uint8_t *) memset(g_malloc(s->pages * pagesize), + 0xff, s->pages * pagesize); + } + /* Give s->ioaddr a sane value in case we save state before it is used. */ + s->ioaddr = s->io; + + return 0; +} + +static SysBusDeviceInfo nand_info = { + .init = nand_device_init, + .qdev.name = "nand", + .qdev.size = sizeof(NANDFlashState), + .qdev.reset = nand_reset, + .qdev.vmsd = &vmstate_nand, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT8("manufacturer_id", NANDFlashState, manf_id, 0), + DEFINE_PROP_UINT8("chip_id", NANDFlashState, chip_id, 0), + DEFINE_PROP_DRIVE("drive", NANDFlashState, bdrv), + DEFINE_PROP_END_OF_LIST() + } +}; + +static void nand_create_device(void) +{ + sysbus_register_withprop(&nand_info); +} + /* * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins. Chip * outputs are R/B and eight I/O pins. * * CE, WP and R/B are active low. */ -void nand_setpins(NANDFlashState *s, - int cle, int ale, int ce, int wp, int gnd) +void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale, + uint8_t ce, uint8_t wp, uint8_t gnd) { + NANDFlashState *s = (NANDFlashState *) dev; s->cle = cle; s->ale = ale; s->ce = ce; @@ -343,13 +454,15 @@ void nand_setpins(NANDFlashState *s, s->status &= ~NAND_IOSTATUS_UNPROTCT; } -void nand_getpins(NANDFlashState *s, int *rb) +void nand_getpins(DeviceState *dev, int *rb) { *rb = 1; } -void nand_setio(NANDFlashState *s, uint8_t value) +void nand_setio(DeviceState *dev, uint32_t value) { + int i; + NANDFlashState *s = (NANDFlashState *) dev; if (!s->ce && s->cle) { if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2) @@ -395,40 +508,69 @@ void nand_setio(NANDFlashState *s, uint8_t value) s->addr = (s->addr & mask) | v; s->addrlen ++; - if (s->addrlen == 1 && s->cmd == NAND_CMD_READID) - nand_command(s); - - if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && - s->addrlen == 3 && ( - s->cmd == NAND_CMD_READ0 || - s->cmd == NAND_CMD_PAGEPROGRAM1)) - nand_command(s); - if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && - s->addrlen == 4 && ( - s->cmd == NAND_CMD_READ0 || - s->cmd == NAND_CMD_PAGEPROGRAM1)) - nand_command(s); + switch (s->addrlen) { + case 1: + if (s->cmd == NAND_CMD_READID) { + nand_command(s); + } + break; + case 2: /* fix cache address as a byte address */ + s->addr <<= (s->buswidth - 1); + break; + case 3: + if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && + (s->cmd == NAND_CMD_READ0 || + s->cmd == NAND_CMD_PAGEPROGRAM1)) { + nand_command(s); + } + break; + case 4: + if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && + nand_flash_ids[s->chip_id].size < 256 && /* 1Gb or less */ + (s->cmd == NAND_CMD_READ0 || + s->cmd == NAND_CMD_PAGEPROGRAM1)) { + nand_command(s); + } + break; + case 5: + if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && + nand_flash_ids[s->chip_id].size >= 256 && /* 2Gb or more */ + (s->cmd == NAND_CMD_READ0 || + s->cmd == NAND_CMD_PAGEPROGRAM1)) { + nand_command(s); + } + break; + default: + break; + } } if (!s->cle && !s->ale && s->cmd == NAND_CMD_PAGEPROGRAM1) { - if (s->iolen < (1 << s->page_shift) + (1 << s->oob_shift)) - s->io[s->iolen ++] = value; + if (s->iolen < (1 << s->page_shift) + (1 << s->oob_shift)) { + for (i = s->buswidth; i--; value >>= 8) { + s->io[s->iolen ++] = (uint8_t) (value & 0xff); + } + } } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) { if ((s->addr & ((1 << s->addr_shift) - 1)) < (1 << s->page_shift) + (1 << s->oob_shift)) { - s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = value; - s->addr ++; + for (i = s->buswidth; i--; s->addr++, value >>= 8) { + s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = + (uint8_t) (value & 0xff); + } } } } -uint8_t nand_getio(NANDFlashState *s) +uint32_t nand_getio(DeviceState *dev) { int offset; + uint32_t x = 0; + NANDFlashState *s = (NANDFlashState *) dev; /* Allow sequential reading */ if (!s->iolen && s->cmd == NAND_CMD_READ0) { - offset = (s->addr & ((1 << s->addr_shift) - 1)) + s->offset; + offset = (int) (s->addr & ((1 << s->addr_shift) - 1)) + s->offset; s->offset = 0; s->blk_load(s, s->addr, offset); @@ -441,129 +583,90 @@ uint8_t nand_getio(NANDFlashState *s) if (s->ce || s->iolen <= 0) return 0; - s->iolen --; - s->addr++; - return *(s->ioaddr ++); + for (offset = s->buswidth; offset--;) { + x |= s->ioaddr[offset] << (offset << 3); + } + /* after receiving READ STATUS command all subsequent reads will + * return the status register value until another command is issued + */ + if (s->cmd != NAND_CMD_READSTATUS) { + s->addr += s->buswidth; + s->ioaddr += s->buswidth; + s->iolen -= s->buswidth; + } + return x; +} + +uint32_t nand_getbuswidth(DeviceState *dev) +{ + NANDFlashState *s = (NANDFlashState *) dev; + return s->buswidth << 3; } -NANDFlashState *nand_init(int manf_id, int chip_id) +DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id) { - int pagesize; - NANDFlashState *s; - DriveInfo *dinfo; + DeviceState *dev; if (nand_flash_ids[chip_id].size == 0) { hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__); } - - s = (NANDFlashState *) qemu_mallocz(sizeof(NANDFlashState)); - dinfo = drive_get(IF_MTD, 0, 0); - if (dinfo) - s->bdrv = dinfo->bdrv; - s->manf_id = manf_id; - s->chip_id = chip_id; - s->size = nand_flash_ids[s->chip_id].size << 20; - if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { - s->page_shift = 11; - s->erase_shift = 6; - } else { - s->page_shift = nand_flash_ids[s->chip_id].page_shift; - s->erase_shift = nand_flash_ids[s->chip_id].erase_shift; - } - - switch (1 << s->page_shift) { - case 256: - nand_init_256(s); - break; - case 512: - nand_init_512(s); - break; - case 2048: - nand_init_2048(s); - break; - default: - hw_error("%s: Unsupported NAND block size.\n", __FUNCTION__); - } - - pagesize = 1 << s->oob_shift; - s->mem_oob = 1; - if (s->bdrv && bdrv_getlength(s->bdrv) >= - (s->pages << s->page_shift) + (s->pages << s->oob_shift)) { - pagesize = 0; - s->mem_oob = 0; + dev = qdev_create(NULL, "nand"); + qdev_prop_set_uint8(dev, "manufacturer_id", manf_id); + qdev_prop_set_uint8(dev, "chip_id", chip_id); + if (bdrv) { + qdev_prop_set_drive_nofail(dev, "drive", bdrv); } - if (!s->bdrv) - pagesize += 1 << s->page_shift; - if (pagesize) - s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize), - 0xff, s->pages * pagesize); - /* Give s->ioaddr a sane value in case we save state before it - is used. */ - s->ioaddr = s->io; - - register_savevm(NULL, "nand", -1, 0, nand_save, nand_load, s); - - return s; + qdev_init_nofail(dev); + return dev; } -void nand_done(NANDFlashState *s) -{ - if (s->bdrv) { - bdrv_close(s->bdrv); - bdrv_delete(s->bdrv); - } - - if (!s->bdrv || s->mem_oob) - qemu_free(s->storage); - - qemu_free(s); -} +device_init(nand_create_device) #else /* Program a single page */ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) { - uint32_t off, page, sector, soff; + uint64_t off, page, sector, soff; uint8_t iobuf[(PAGE_SECTORS + 2) * 0x200]; if (PAGE(s->addr) >= s->pages) return; if (!s->bdrv) { - memcpy(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) + + mem_and(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset, s->io, s->iolen); } else if (s->mem_oob) { sector = SECTOR(s->addr); off = (s->addr & PAGE_MASK) + s->offset; soff = SECTOR_OFFSET(s->addr); if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) { - printf("%s: read error in sector %i\n", __FUNCTION__, sector); + printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); return; } - memcpy(iobuf + (soff | off), s->io, MIN(s->iolen, PAGE_SIZE - off)); + mem_and(iobuf + (soff | off), s->io, MIN(s->iolen, PAGE_SIZE - off)); if (off + s->iolen > PAGE_SIZE) { page = PAGE(s->addr); - memcpy(s->storage + (page << OOB_SHIFT), s->io + PAGE_SIZE - off, + mem_and(s->storage + (page << OOB_SHIFT), s->io + PAGE_SIZE - off, MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE)); } if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) - printf("%s: write error in sector %i\n", __FUNCTION__, sector); + printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); } else { off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset; sector = off >> 9; soff = off & 0x1ff; if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) { - printf("%s: read error in sector %i\n", __FUNCTION__, sector); + printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); return; } - memcpy(iobuf + soff, s->io, s->iolen); + mem_and(iobuf + soff, s->io, s->iolen); if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) - printf("%s: write error in sector %i\n", __FUNCTION__, sector); + printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); } s->offset = 0; } @@ -571,7 +674,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s) /* Erase a single block */ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s) { - uint32_t i, page, addr; + uint64_t i, page, addr; uint8_t iobuf[0x200] = { [0 ... 0x1ff] = 0xff, }; addr = s->addr & ~((1 << (ADDR_SHIFT + s->erase_shift)) - 1); @@ -588,34 +691,35 @@ static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s) page = SECTOR(addr + (ADDR_SHIFT + s->erase_shift)); for (; i < page; i ++) if (bdrv_write(s->bdrv, i, iobuf, 1) == -1) - printf("%s: write error in sector %i\n", __FUNCTION__, i); + printf("%s: write error in sector %" PRIu64 "\n", __func__, i); } else { addr = PAGE_START(addr); page = addr >> 9; if (bdrv_read(s->bdrv, page, iobuf, 1) == -1) - printf("%s: read error in sector %i\n", __FUNCTION__, page); + printf("%s: read error in sector %" PRIu64 "\n", __func__, page); memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1); if (bdrv_write(s->bdrv, page, iobuf, 1) == -1) - printf("%s: write error in sector %i\n", __FUNCTION__, page); + printf("%s: write error in sector %" PRIu64 "\n", __func__, page); memset(iobuf, 0xff, 0x200); i = (addr & ~0x1ff) + 0x200; for (addr += ((PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200; i < addr; i += 0x200) if (bdrv_write(s->bdrv, i >> 9, iobuf, 1) == -1) - printf("%s: write error in sector %i\n", __FUNCTION__, i >> 9); + printf("%s: write error in sector %" PRIu64 "\n", + __func__, i >> 9); page = i >> 9; if (bdrv_read(s->bdrv, page, iobuf, 1) == -1) - printf("%s: read error in sector %i\n", __FUNCTION__, page); + printf("%s: read error in sector %" PRIu64 "\n", __func__, page); memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1); if (bdrv_write(s->bdrv, page, iobuf, 1) == -1) - printf("%s: write error in sector %i\n", __FUNCTION__, page); + printf("%s: write error in sector %" PRIu64 "\n", __func__, page); } } static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, - uint32_t addr, int offset) + uint64_t addr, int offset) { if (PAGE(addr) >= s->pages) return; @@ -623,8 +727,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, if (s->bdrv) { if (s->mem_oob) { if (bdrv_read(s->bdrv, SECTOR(addr), s->io, PAGE_SECTORS) == -1) - printf("%s: read error in sector %i\n", - __FUNCTION__, SECTOR(addr)); + printf("%s: read error in sector %" PRIu64 "\n", + __func__, SECTOR(addr)); memcpy(s->io + SECTOR_OFFSET(s->addr) + PAGE_SIZE, s->storage + (PAGE(s->addr) << OOB_SHIFT), OOB_SIZE); @@ -632,8 +736,8 @@ static void glue(nand_blk_load_, PAGE_SIZE)(NANDFlashState *s, } else { if (bdrv_read(s->bdrv, PAGE_START(addr) >> 9, s->io, (PAGE_SECTORS + 2)) == -1) - printf("%s: read error in sector %i\n", - __FUNCTION__, PAGE_START(addr) >> 9); + printf("%s: read error in sector %" PRIu64 "\n", + __func__, PAGE_START(addr) >> 9); s->ioaddr = s->io + (PAGE_START(addr) & 0x1ff) + offset; } } else { diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c index 3ff0d89..11ffee7 100644 --- a/hw/ne2000-isa.c +++ b/hw/ne2000-isa.c @@ -27,6 +27,7 @@ #include "qdev.h" #include "net.h" #include "ne2000.h" +#include "exec-memory.h" typedef struct ISANE2000State { ISADevice dev; @@ -66,19 +67,8 @@ static int isa_ne2000_initfn(ISADevice *dev) ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev); NE2000State *s = &isa->ne2000; - register_ioport_write(isa->iobase, 16, 1, ne2000_ioport_write, s); - register_ioport_read(isa->iobase, 16, 1, ne2000_ioport_read, s); - isa_init_ioport_range(dev, isa->iobase, 16); - - register_ioport_write(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_write, s); - register_ioport_read(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_read, s); - register_ioport_write(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_write, s); - register_ioport_read(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_read, s); - isa_init_ioport_range(dev, isa->iobase + 0x10, 2); - - register_ioport_write(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_write, s); - register_ioport_read(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_read, s); - isa_init_ioport(dev, isa->iobase + 0x1f); + ne2000_setup_io(s, 0x20); + isa_register_ioport(dev, &s->io, isa->iobase); isa_init_irq(dev, &s->irq, isa->isairq); @@ -92,19 +82,6 @@ static int isa_ne2000_initfn(ISADevice *dev) return 0; } -void isa_ne2000_init(int base, int irq, NICInfo *nd) -{ - ISADevice *dev; - - qemu_check_nic_model(nd, "ne2k_isa"); - - dev = isa_create("ne2k_isa"); - qdev_prop_set_uint32(&dev->qdev, "iobase", base); - qdev_prop_set_uint32(&dev->qdev, "irq", irq); - qdev_set_nic_properties(&dev->qdev, nd); - qdev_init_nofail(&dev->qdev); -} - static ISADeviceInfo ne2000_isa_info = { .qdev.name = "ne2k_isa", .qdev.size = sizeof(ISANE2000State), diff --git a/hw/ne2000.c b/hw/ne2000.c index 5966359..62e082f 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -297,7 +297,7 @@ ssize_t ne2000_receive(VLANClientState *nc, const uint8_t *buf, size_t size_) return size_; } -void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) { NE2000State *s = opaque; int offset, page, index; @@ -394,7 +394,7 @@ void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) +static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) { NE2000State *s = opaque; int offset, page, ret; @@ -544,7 +544,7 @@ static inline void ne2000_dma_update(NE2000State *s, int len) } } -void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) { NE2000State *s = opaque; @@ -564,7 +564,7 @@ void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) +static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) { NE2000State *s = opaque; int ret; @@ -612,12 +612,12 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr) return ret; } -void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) { /* nothing to do (end of reset pulse) */ } -uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) +static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) { NE2000State *s = opaque; ne2000_reset(s); @@ -676,27 +676,55 @@ static const VMStateDescription vmstate_pci_ne2000 = { } }; -/***********************************************************/ -/* PCI NE2000 definitions */ +static uint64_t ne2000_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + NE2000State *s = opaque; -static void ne2000_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) + if (addr < 0x10 && size == 1) { + return ne2000_ioport_read(s, addr); + } else if (addr == 0x10) { + if (size <= 2) { + return ne2000_asic_ioport_read(s, addr); + } else { + return ne2000_asic_ioport_readl(s, addr); + } + } else if (addr == 0x1f && size == 1) { + return ne2000_reset_ioport_read(s, addr); + } + return ((uint64_t)1 << (size * 8)) - 1; +} + +static void ne2000_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { - PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); - NE2000State *s = &d->ne2000; + NE2000State *s = opaque; - register_ioport_write(addr, 16, 1, ne2000_ioport_write, s); - register_ioport_read(addr, 16, 1, ne2000_ioport_read, s); + if (addr < 0x10 && size == 1) { + return ne2000_ioport_write(s, addr, data); + } else if (addr == 0x10) { + if (size <= 2) { + return ne2000_asic_ioport_write(s, addr, data); + } else { + return ne2000_asic_ioport_writel(s, addr, data); + } + } else if (addr == 0x1f && size == 1) { + return ne2000_reset_ioport_write(s, addr, data); + } +} - register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s); - register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s); - register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s); - register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s); - register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s); - register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s); +static const MemoryRegionOps ne2000_ops = { + .read = ne2000_read, + .write = ne2000_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; - register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s); - register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s); +/***********************************************************/ +/* PCI NE2000 definitions */ + +void ne2000_setup_io(NE2000State *s, unsigned size) +{ + memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size); } static void ne2000_cleanup(VLANClientState *nc) @@ -721,15 +749,11 @@ static int pci_ne2000_init(PCIDevice *pci_dev) uint8_t *pci_conf; pci_conf = d->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8029); - pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET); - /* TODO: RST# value should be 0. PCI spec 6.2.4 */ - pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 - - pci_register_bar(&d->dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, ne2000_map); + pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */ + s = &d->ne2000; + ne2000_setup_io(s, 0x100); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); s->irq = d->dev.irq[0]; qemu_macaddr_default_if_unset(&s->c.macaddr); @@ -742,7 +766,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev) if (!pci_dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { - rom_add_option("pxe-ne2k_pci.bin", -1); + rom_add_option("pxe-ne2k_pci.rom", -1); loaded = 1; } } @@ -757,6 +781,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev) PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); NE2000State *s = &d->ne2000; + memory_region_destroy(&s->io); qemu_del_vlan_client(&s->nic->nc); return 0; } @@ -767,6 +792,9 @@ static PCIDeviceInfo ne2000_info = { .qdev.vmsd = &vmstate_pci_ne2000, .init = pci_ne2000_init, .exit = pci_ne2000_exit, + .vendor_id = PCI_VENDOR_ID_REALTEK, + .device_id = PCI_DEVICE_ID_REALTEK_8029, + .class_id = PCI_CLASS_NETWORK_ETHERNET, .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/ne2000.h b/hw/ne2000.h index 54fdfca..5fee052 100644 --- a/hw/ne2000.h +++ b/hw/ne2000.h @@ -4,6 +4,7 @@ #define NE2000_MEM_SIZE NE2000_PMEM_END typedef struct NE2000State { + MemoryRegion io; uint8_t cmd; uint32_t start; uint32_t stop; @@ -27,12 +28,7 @@ typedef struct NE2000State { uint8_t mem[NE2000_MEM_SIZE]; } NE2000State; -void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t ne2000_ioport_read(void *opaque, uint32_t addr); -void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr); -void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr); +void ne2000_setup_io(NE2000State *s, unsigned size); extern const VMStateDescription vmstate_ne2000; void ne2000_reset(NE2000State *s); int ne2000_can_receive(VLANClientState *vc); diff --git a/hw/nseries.c b/hw/nseries.c index 2f6f473..eb99143 100644 --- a/hw/nseries.c +++ b/hw/nseries.c @@ -31,6 +31,8 @@ #include "hw.h" #include "bt.h" #include "loader.h" +#include "blockdev.h" +#include "sysbus.h" /* Nokia N8x0 support */ struct n800_s { @@ -45,12 +47,12 @@ struct n800_s { i2c_bus *i2c; int keymap[0x80]; - i2c_slave *kbd; + DeviceState *kbd; - TUSBState *usb; + DeviceState *usb; void *retu; void *tahvo; - void *nand; + DeviceState *nand; }; /* GPIO pins */ @@ -134,9 +136,9 @@ static void n800_mmc_cs_cb(void *opaque, int line, int level) static void n8x0_gpio_setup(struct n800_s *s) { qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1); - omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]); + qdev_connect_gpio_out(s->cpu->gpio, N8X0_MMC_CS_GPIO, mmc_cs[0]); - qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]); + qemu_irq_lower(qdev_get_gpio_in(s->cpu->gpio, N800_BAT_COVER_GPIO)); } #define MAEMO_CAL_HEADER(...) \ @@ -163,13 +165,23 @@ static const uint8_t n8x0_cal_bt_id[] = { static void n8x0_nand_setup(struct n800_s *s) { char *otp_region; - - /* Either ec40xx or ec48xx are OK for the ID */ - omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update, - onenand_base_unmap, - (s->nand = onenand_init(0xec4800, 1, - omap2_gpio_in_get(s->cpu->gpif, - N8X0_ONENAND_GPIO)[0]))); + DriveInfo *dinfo; + + s->nand = qdev_create(NULL, "onenand"); + qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG); + /* Either 0x40 or 0x48 are OK for the device ID */ + qdev_prop_set_uint16(s->nand, "device_id", 0x48); + qdev_prop_set_uint16(s->nand, "version_id", 0); + qdev_prop_set_int32(s->nand, "shift", 1); + dinfo = drive_get(IF_MTD, 0, 0); + if (dinfo && dinfo->bdrv) { + qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv); + } + qdev_init_nofail(s->nand); + sysbus_connect_irq(sysbus_from_qdev(s->nand), 0, + qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO)); + omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, + sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0)); otp_region = onenand_raw_otp(s->nand); memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac)); @@ -180,14 +192,16 @@ static void n8x0_nand_setup(struct n800_s *s) static void n8x0_i2c_setup(struct n800_s *s) { DeviceState *dev; - qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0]; + qemu_irq tmp_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TMP105_GPIO); /* Attach the CPU on one end of our I2C bus. */ s->i2c = omap_i2c_bus(s->cpu->i2c[0]); /* Attach a menelaus PM chip */ dev = i2c_create_slave(s->i2c, "twl92230", N8X0_MENELAUS_ADDR); - qdev_connect_gpio_out(dev, 3, s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]); + qdev_connect_gpio_out(dev, 3, + qdev_get_gpio_in(s->cpu->ih[0], + OMAP_INT_24XX_SYS_NIRQ)); /* Attach a TMP105 PM chip (A0 wired to ground) */ dev = i2c_create_slave(s->i2c, "tmp105", N8X0_TMP105_ADDR); @@ -249,8 +263,8 @@ static void n800_tsc_kbd_setup(struct n800_s *s) /* XXX: are the three pins inverted inside the chip between the * tsc and the cpu (N4111)? */ qemu_irq penirq = NULL; /* NC */ - qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0]; - qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0]; + qemu_irq kbirq = qdev_get_gpio_in(s->cpu->gpio, N800_TSC_KP_IRQ_GPIO); + qemu_irq dav = qdev_get_gpio_in(s->cpu->gpio, N800_TSC_TS_GPIO); s->ts.chip = tsc2301_init(penirq, kbirq, dav); s->ts.opaque = s->ts.chip->opaque; @@ -269,7 +283,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s) static void n810_tsc_setup(struct n800_s *s) { - qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0]; + qemu_irq pintdav = qdev_get_gpio_in(s->cpu->gpio, N810_TSC_TS_GPIO); s->ts.opaque = tsc2005_init(pintdav); s->ts.txrx = tsc2005_txrx; @@ -361,8 +375,7 @@ static int n810_keys[0x80] = { static void n810_kbd_setup(struct n800_s *s) { - qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0]; - DeviceState *dev; + qemu_irq kbd_irq = qdev_get_gpio_in(s->cpu->gpio, N810_KEYBOARD_GPIO); int i; for (i = 0; i < 0x80; i ++) @@ -375,8 +388,8 @@ static void n810_kbd_setup(struct n800_s *s) /* Attach the LM8322 keyboard to the I2C bus, * should happen in n8x0_i2c_setup and s->kbd be initialised here. */ - dev = i2c_create_slave(s->i2c, "lm8323", N810_LM8323_ADDR); - qdev_connect_gpio_out(dev, 0, kbd_irq); + s->kbd = i2c_create_slave(s->i2c, "lm8323", N810_LM8323_ADDR); + qdev_connect_gpio_out(s->kbd, 0, kbd_irq); } /* LCD MIPI DBI-C controller (URAL) */ @@ -652,7 +665,7 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len) static void *mipid_init(void) { - struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s)); + struct mipid_s *s = (struct mipid_s *) g_malloc0(sizeof(*s)); s->id = 0x838f03; mipid_reset(s); @@ -708,10 +721,10 @@ static void n800_dss_init(struct rfbi_chip_s *chip) chip->write(chip->opaque, 1, 0x01); /* Input Data Format */ chip->write(chip->opaque, 1, 0x01); /* Data Source Select */ - fb_blank = memset(qemu_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2); + fb_blank = memset(g_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2); /* Display Memory Data Port */ chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800); - qemu_free(fb_blank); + g_free(fb_blank); } static void n8x0_dss_setup(struct n800_s *s) @@ -726,15 +739,15 @@ static void n8x0_dss_setup(struct n800_s *s) static void n8x0_cbus_setup(struct n800_s *s) { - qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0]; - qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0]; - qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0]; + qemu_irq dat_out = qdev_get_gpio_in(s->cpu->gpio, N8X0_CBUS_DAT_GPIO); + qemu_irq retu_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_RETU_GPIO); + qemu_irq tahvo_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TAHVO_GPIO); CBus *cbus = cbus_init(dat_out); - omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk); - omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat); - omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel); + qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk); + qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat); + qdev_connect_gpio_out(s->cpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel); cbus_attach(cbus, s->retu = retu_init(retu_irq, 1)); cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1)); @@ -743,38 +756,31 @@ static void n8x0_cbus_setup(struct n800_s *s) static void n8x0_uart_setup(struct n800_s *s) { CharDriverState *radio = uart_hci_init( - omap2_gpio_in_get(s->cpu->gpif, - N8X0_BT_HOST_WKUP_GPIO)[0]); + qdev_get_gpio_in(s->cpu->gpio, N8X0_BT_HOST_WKUP_GPIO)); - omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_RESET_GPIO, + qdev_connect_gpio_out(s->cpu->gpio, N8X0_BT_RESET_GPIO, csrhci_pins_get(radio)[csrhci_pin_reset]); - omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_WKUP_GPIO, + qdev_connect_gpio_out(s->cpu->gpio, N8X0_BT_WKUP_GPIO, csrhci_pins_get(radio)[csrhci_pin_wakeup]); omap_uart_attach(s->cpu->uart[BT_UART], radio); } -static void n8x0_usb_power_cb(void *opaque, int line, int level) -{ - struct n800_s *s = opaque; - - tusb6010_power(s->usb, level); -} - static void n8x0_usb_setup(struct n800_s *s) { - qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0]; - qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0]; - TUSBState *tusb = tusb6010_init(tusb_irq); - + SysBusDevice *dev; + s->usb = qdev_create(NULL, "tusb6010"); + dev = sysbus_from_qdev(s->usb); + qdev_init_nofail(s->usb); + sysbus_connect_irq(dev, 0, + qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO)); /* Using the NOR interface */ omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS, - tusb6010_async_io(tusb), NULL, NULL, tusb); + sysbus_mmio_get_region(dev, 0)); omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS, - tusb6010_sync_io(tusb), NULL, NULL, tusb); - - s->usb = tusb; - omap2_gpio_out_set(s->cpu->gpif, N8X0_TUSB_ENABLE_GPIO, tusb_pwr); + sysbus_mmio_get_region(dev, 1)); + qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, + qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */ } /* Setup done before the main bootloader starts by some early setup code @@ -1020,7 +1026,7 @@ static void n8x0_boot_init(void *opaque) /* If the machine has a slided keyboard, open it */ if (s->kbd) - qemu_irq_raise(omap2_gpio_in_get(s->cpu->gpif, N810_SLIDE_GPIO)[0]); + qemu_irq_raise(qdev_get_gpio_in(s->cpu->gpio, N810_SLIDE_GPIO)); } #define OMAP_TAG_NOKIA_BT 0x4e01 @@ -1254,12 +1260,12 @@ static int n8x0_atag_setup(void *p, int model) return (void *) w - p; } -static int n800_atag_setup(struct arm_boot_info *info, void *p) +static int n800_atag_setup(const struct arm_boot_info *info, void *p) { return n8x0_atag_setup(p, 800); } -static int n810_atag_setup(struct arm_boot_info *info, void *p) +static int n810_atag_setup(const struct arm_boot_info *info, void *p) { return n8x0_atag_setup(p, 810); } @@ -1269,7 +1275,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, struct arm_boot_info *binfo, int model) { - struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s)); + struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s)); int sdram_size = binfo->ram_size; DisplayState *ds; diff --git a/hw/omap.h b/hw/omap.h index c227a82..cc09a3c 100644 --- a/hw/omap.h +++ b/hw/omap.h @@ -17,6 +17,7 @@ * with this program; if not, see . */ #ifndef hw_omap_h +#include "memory.h" # define hw_omap_h "omap.h" # define OMAP_EMIFS_BASE 0x00000000 @@ -93,21 +94,11 @@ struct omap_target_agent_s *omap_l4ta_get( int cs); target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region, int iotype); +target_phys_addr_t omap_l4_region_base(struct omap_target_agent_s *ta, + int region); int l4_register_io_memory(CPUReadMemoryFunc * const *mem_read, CPUWriteMemoryFunc * const *mem_write, void *opaque); -/* OMAP interrupt controller */ -struct omap_intr_handler_s; -struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, - unsigned long size, unsigned char nbanks, qemu_irq **pins, - qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk); -struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base, - int size, int nbanks, qemu_irq **pins, - qemu_irq parent_irq, qemu_irq parent_fiq, - omap_clk fclk, omap_clk iclk); -void omap_inth_reset(struct omap_intr_handler_s *s); -qemu_irq omap_inth_get_pin(struct omap_intr_handler_s *s, int n); - /* OMAP2 SDRAM controller */ struct omap_sdrc_s; struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base); @@ -115,11 +106,12 @@ void omap_sdrc_reset(struct omap_sdrc_s *s); /* OMAP2 general purpose memory controller */ struct omap_gpmc_s; -struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq); +struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu, + target_phys_addr_t base, + qemu_irq irq, qemu_irq drq); void omap_gpmc_reset(struct omap_gpmc_s *s); -void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype, - void (*base_upd)(void *opaque, target_phys_addr_t new), - void (*unmap)(void *opaque), void *opaque); +void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem); +void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand); /* * Common IRQ numbers for level 1 interrupt handler @@ -674,37 +666,20 @@ void omap_uart_reset(struct omap_uart_s *s); void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr); struct omap_mpuio_s; -struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base, +struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *system_memory, + target_phys_addr_t base, qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup, omap_clk clk); qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s); void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler); void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down); -/* omap1 gpio module interface */ -struct omap_gpio_s; -struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base, - qemu_irq irq, omap_clk clk); -void omap_gpio_reset(struct omap_gpio_s *s); -qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s); -void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler); - -/* omap2 gpio interface */ -struct omap_gpif_s; -struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta, - qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules); -void omap_gpif_reset(struct omap_gpif_s *s); -qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start); -void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler); - struct uWireSlave { uint16_t (*receive)(void *opaque); void (*send)(void *opaque, uint16_t data); void *opaque; }; struct omap_uwire_s; -struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base, - qemu_irq *irq, qemu_irq dma, omap_clk clk); void omap_uwire_attach(struct omap_uwire_s *s, uWireSlave *slave, int chipselect); @@ -742,8 +717,6 @@ struct I2SCodec { } in, out; }; struct omap_mcbsp_s; -struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base, - qemu_irq *irq, qemu_irq *dma, omap_clk clk); void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave); void omap_tap_init(struct omap_target_agent_s *ta, @@ -753,8 +726,7 @@ void omap_tap_init(struct omap_target_agent_s *ta, struct omap_lcd_panel_s; void omap_lcdc_reset(struct omap_lcd_panel_s *s); struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq, - struct omap_dma_lcd_channel_s *dma, - ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk); + struct omap_dma_lcd_channel_s *dma, omap_clk clk); /* omap_dss.c */ struct rfbi_chip_s { @@ -801,6 +773,7 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s); # define cpu_is_omap2420(cpu) (cpu->mpu_model == omap2420) # define cpu_is_omap2430(cpu) (cpu->mpu_model == omap2430) # define cpu_is_omap3430(cpu) (cpu->mpu_model == omap3430) +# define cpu_is_omap3630(cpu) (cpu->mpu_model == omap3630) # define cpu_is_omap15xx(cpu) \ (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu)) @@ -812,7 +785,8 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s); # define cpu_class_omap1(cpu) \ (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu)) # define cpu_class_omap2(cpu) cpu_is_omap24xx(cpu) -# define cpu_class_omap3(cpu) cpu_is_omap3430(cpu) +# define cpu_class_omap3(cpu) \ + (cpu_is_omap3430(cpu) || cpu_is_omap3630(cpu)) struct omap_mpu_state_s { enum omap_mpu_model { @@ -826,15 +800,31 @@ struct omap_mpu_state_s { omap2423, omap2430, omap3430, + omap3630, } mpu_model; CPUState *env; - qemu_irq *irq[2]; qemu_irq *drq; qemu_irq wakeup; + MemoryRegion ulpd_pm_iomem; + MemoryRegion pin_cfg_iomem; + MemoryRegion id_iomem; + MemoryRegion id_iomem_e18; + MemoryRegion id_iomem_ed4; + MemoryRegion id_iomem_e20; + MemoryRegion mpui_iomem; + MemoryRegion tcmi_iomem; + MemoryRegion clkm_iomem; + MemoryRegion clkdsp_iomem; + MemoryRegion pwl_iomem; + MemoryRegion pwt_iomem; + MemoryRegion mpui_io_iomem; + MemoryRegion imif_ram; + MemoryRegion emiff_ram; + struct omap_dma_port_if_s { uint32_t (*read[3])(struct omap_mpu_state_s *s, target_phys_addr_t offset); @@ -850,7 +840,7 @@ struct omap_mpu_state_s { /* MPUI-TIPB peripherals */ struct omap_uart_s *uart[3]; - struct omap_gpio_s *gpio; + DeviceState *gpio; struct omap_mcbsp_s *mcbsp1; struct omap_mcbsp_s *mcbsp3; @@ -887,7 +877,7 @@ struct omap_mpu_state_s { struct omap_lpg_s *led[2]; /* MPU private TIPB peripherals */ - struct omap_intr_handler_s *ih[2]; + DeviceState *ih[2]; struct soc_dma_s *dma; @@ -916,6 +906,7 @@ struct omap_mpu_state_s { uint32_t tcmi_regs[17]; struct dpll_ctl_s { + MemoryRegion iomem; uint16_t mode; omap_clk dpll; } dpll[3]; @@ -948,8 +939,6 @@ struct omap_mpu_state_s { struct omap_gpmc_s *gpmc; struct omap_sysctl_s *sysc; - struct omap_gpif_s *gpif; - struct omap_mcspi_s *mcspi[2]; struct omap_dss_s *dss; @@ -958,7 +947,8 @@ struct omap_mpu_state_s { }; /* omap1.c */ -struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, +struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory, + unsigned long sdram_size, const char *core); /* omap2.c */ @@ -1123,7 +1113,7 @@ inline static int debug_register_io_memory(CPUReadMemoryFunc * const *mem_read, CPUWriteMemoryFunc * const *mem_write, void *opaque) { - struct io_fn *s = qemu_malloc(sizeof(struct io_fn)); + struct io_fn *s = g_malloc(sizeof(struct io_fn)); s->mem_read = mem_read; s->mem_write = mem_write; diff --git a/hw/omap1.c b/hw/omap1.c index d5e4dab..619812c 100644 --- a/hw/omap1.c +++ b/hw/omap1.c @@ -27,6 +27,7 @@ #include "pc.h" #include "blockdev.h" #include "range.h" +#include "sysbus.h" /* Should signal the TCMI/GPMC */ uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr) @@ -83,6 +84,7 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, /* MPU OS timers */ struct omap_mpu_timer_s { + MemoryRegion iomem; qemu_irq irq; omap_clk clk; uint32_t val; @@ -101,7 +103,7 @@ struct omap_mpu_timer_s { static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer) { - uint64_t distance = qemu_get_clock(vm_clock) - timer->time; + uint64_t distance = qemu_get_clock_ns(vm_clock) - timer->time; if (timer->st && timer->enable && timer->rate) return timer->val - muldiv64(distance >> (timer->ptv + 1), @@ -113,7 +115,7 @@ static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer) static inline void omap_timer_sync(struct omap_mpu_timer_s *timer) { timer->val = omap_timer_read(timer); - timer->time = qemu_get_clock(vm_clock); + timer->time = qemu_get_clock_ns(vm_clock); } static inline void omap_timer_update(struct omap_mpu_timer_s *timer) @@ -178,10 +180,15 @@ static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer) timer->rate = omap_clk_getrate(timer->clk); } -static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque; + if (size != 4) { + return omap_badwidth_read32(opaque, addr); + } + switch (addr) { case 0x00: /* CNTL_TIMER */ return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st; @@ -198,10 +205,14 @@ static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr) } static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque; + if (size != 4) { + return omap_badwidth_write32(opaque, addr, value); + } + switch (addr) { case 0x00: /* CNTL_TIMER */ omap_timer_sync(s); @@ -225,16 +236,10 @@ static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_mpu_timer_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap_mpu_timer_read, -}; - -static CPUWriteMemoryFunc * const omap_mpu_timer_writefn[] = { - omap_badwidth_write32, - omap_badwidth_write32, - omap_mpu_timer_write, +static const MemoryRegionOps omap_mpu_timer_ops = { + .read = omap_mpu_timer_read, + .write = omap_mpu_timer_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s) @@ -249,23 +254,24 @@ static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s) s->it_ena = 1; } -static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base, +static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory, + target_phys_addr_t base, qemu_irq irq, omap_clk clk) { - int iomemtype; struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) - qemu_mallocz(sizeof(struct omap_mpu_timer_s)); + g_malloc0(sizeof(struct omap_mpu_timer_s)); s->irq = irq; s->clk = clk; - s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s); + s->timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, s); s->tick = qemu_bh_new(omap_timer_fire, s); omap_mpu_timer_reset(s); omap_timer_clk_setup(s); - iomemtype = cpu_register_io_memory(omap_mpu_timer_readfn, - omap_mpu_timer_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x100, iomemtype); + memory_region_init_io(&s->iomem, &omap_mpu_timer_ops, s, + "omap-mpu-timer", 0x100); + + memory_region_add_subregion(system_memory, base, &s->iomem); return s; } @@ -273,16 +279,22 @@ static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base, /* Watchdog timer */ struct omap_watchdog_timer_s { struct omap_mpu_timer_s timer; + MemoryRegion iomem; uint8_t last_wr; int mode; int free; int reset; }; -static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (addr) { case 0x00: /* CNTL_TIMER */ return (s->timer.ptv << 9) | (s->timer.ar << 8) | @@ -300,10 +312,14 @@ static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr) } static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque; + if (size != 2) { + return omap_badwidth_write16(opaque, addr, value); + } + switch (addr) { case 0x00: /* CNTL_TIMER */ omap_timer_sync(&s->timer); @@ -343,16 +359,10 @@ static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_wd_timer_readfn[] = { - omap_badwidth_read16, - omap_wd_timer_read, - omap_badwidth_read16, -}; - -static CPUWriteMemoryFunc * const omap_wd_timer_writefn[] = { - omap_badwidth_write16, - omap_wd_timer_write, - omap_badwidth_write16, +static const MemoryRegionOps omap_wd_timer_ops = { + .read = omap_wd_timer_read, + .write = omap_wd_timer_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s) @@ -373,22 +383,22 @@ static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s) omap_timer_update(&s->timer); } -static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base, +static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory, + target_phys_addr_t base, qemu_irq irq, omap_clk clk) { - int iomemtype; struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) - qemu_mallocz(sizeof(struct omap_watchdog_timer_s)); + g_malloc0(sizeof(struct omap_watchdog_timer_s)); s->timer.irq = irq; s->timer.clk = clk; - s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer); + s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer); omap_wd_timer_reset(s); omap_timer_clk_setup(&s->timer); - iomemtype = cpu_register_io_memory(omap_wd_timer_readfn, - omap_wd_timer_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x100, iomemtype); + memory_region_init_io(&s->iomem, &omap_wd_timer_ops, s, + "omap-wd-timer", 0x100); + memory_region_add_subregion(memory, base, &s->iomem); return s; } @@ -396,13 +406,19 @@ static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base, /* 32-kHz timer */ struct omap_32khz_timer_s { struct omap_mpu_timer_s timer; + MemoryRegion iomem; }; -static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_os_timer_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 4) { + return omap_badwidth_read32(opaque, addr); + } + switch (offset) { case 0x00: /* TVR */ return s->timer.reset_val; @@ -421,11 +437,15 @@ static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr) } static void omap_os_timer_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 4) { + return omap_badwidth_write32(opaque, addr, value); + } + switch (offset) { case 0x00: /* TVR */ s->timer.reset_val = value & 0x00ffffff; @@ -451,16 +471,10 @@ static void omap_os_timer_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_os_timer_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap_os_timer_read, -}; - -static CPUWriteMemoryFunc * const omap_os_timer_writefn[] = { - omap_badwidth_write32, - omap_badwidth_write32, - omap_os_timer_write, +static const MemoryRegionOps omap_os_timer_ops = { + .read = omap_os_timer_read, + .write = omap_os_timer_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_os_timer_reset(struct omap_32khz_timer_s *s) @@ -475,37 +489,42 @@ static void omap_os_timer_reset(struct omap_32khz_timer_s *s) s->timer.ar = 1; } -static struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base, +static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory, + target_phys_addr_t base, qemu_irq irq, omap_clk clk) { - int iomemtype; struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) - qemu_mallocz(sizeof(struct omap_32khz_timer_s)); + g_malloc0(sizeof(struct omap_32khz_timer_s)); s->timer.irq = irq; s->timer.clk = clk; - s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer); + s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer); omap_os_timer_reset(s); omap_timer_clk_setup(&s->timer); - iomemtype = cpu_register_io_memory(omap_os_timer_readfn, - omap_os_timer_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->iomem, &omap_os_timer_ops, s, + "omap-os-timer", 0x800); + memory_region_add_subregion(memory, base, &s->iomem); return s; } /* Ultra Low-Power Device Module */ -static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; uint16_t ret; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (addr) { case 0x14: /* IT_STATUS */ ret = s->ulpd_pm_regs[addr >> 2]; s->ulpd_pm_regs[addr >> 2] = 0; - qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]); + qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K)); return ret; case 0x18: /* Reserved */ @@ -559,7 +578,7 @@ static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s, } static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; int64_t now, ticks; @@ -567,6 +586,10 @@ static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr, static const int bypass_div[4] = { 1, 2, 4, 4 }; uint16_t diff; + if (size != 2) { + return omap_badwidth_write16(opaque, addr, value); + } + switch (addr) { case 0x00: /* COUNTER_32_LSB */ case 0x04: /* COUNTER_32_MSB */ @@ -580,7 +603,7 @@ static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr, case 0x10: /* GAUGING_CTRL */ /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */ if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) { - now = qemu_get_clock(vm_clock); + now = qemu_get_clock_ns(vm_clock); if (value & 1) s->ulpd_gauge_start = now; @@ -602,7 +625,7 @@ static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr, s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1; s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */ - qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]); + qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K)); } } s->ulpd_pm_regs[addr >> 2] = value; @@ -673,16 +696,10 @@ static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_ulpd_pm_readfn[] = { - omap_badwidth_read16, - omap_ulpd_pm_read, - omap_badwidth_read16, -}; - -static CPUWriteMemoryFunc * const omap_ulpd_pm_writefn[] = { - omap_badwidth_write16, - omap_ulpd_pm_write, - omap_badwidth_write16, +static const MemoryRegionOps omap_ulpd_pm_ops = { + .read = omap_ulpd_pm_read, + .write = omap_ulpd_pm_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu) @@ -712,21 +729,26 @@ static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu) omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4")); } -static void omap_ulpd_pm_init(target_phys_addr_t base, +static void omap_ulpd_pm_init(MemoryRegion *system_memory, + target_phys_addr_t base, struct omap_mpu_state_s *mpu) { - int iomemtype = cpu_register_io_memory(omap_ulpd_pm_readfn, - omap_ulpd_pm_writefn, mpu, DEVICE_NATIVE_ENDIAN); - - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&mpu->ulpd_pm_iomem, &omap_ulpd_pm_ops, mpu, + "omap-ulpd-pm", 0x800); + memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem); omap_ulpd_pm_reset(mpu); } /* OMAP Pin Configuration */ -static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + if (size != 4) { + return omap_badwidth_read32(opaque, addr); + } + switch (addr) { case 0x00: /* FUNC_MUX_CTRL_0 */ case 0x04: /* FUNC_MUX_CTRL_1 */ @@ -826,11 +848,15 @@ static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s, } static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; uint32_t diff; + if (size != 4) { + return omap_badwidth_write32(opaque, addr, value); + } + switch (addr) { case 0x00: /* FUNC_MUX_CTRL_0 */ diff = s->func_mux_ctrl[addr >> 2] ^ value; @@ -899,16 +925,10 @@ static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_pin_cfg_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap_pin_cfg_read, -}; - -static CPUWriteMemoryFunc * const omap_pin_cfg_writefn[] = { - omap_badwidth_write32, - omap_badwidth_write32, - omap_pin_cfg_write, +static const MemoryRegionOps omap_pin_cfg_ops = { + .read = omap_pin_cfg_read, + .write = omap_pin_cfg_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu) @@ -927,21 +947,26 @@ static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu) memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl)); } -static void omap_pin_cfg_init(target_phys_addr_t base, +static void omap_pin_cfg_init(MemoryRegion *system_memory, + target_phys_addr_t base, struct omap_mpu_state_s *mpu) { - int iomemtype = cpu_register_io_memory(omap_pin_cfg_readfn, - omap_pin_cfg_writefn, mpu, DEVICE_NATIVE_ENDIAN); - - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&mpu->pin_cfg_iomem, &omap_pin_cfg_ops, mpu, + "omap-pin-cfg", 0x800); + memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem); omap_pin_cfg_reset(mpu); } /* Device Identification, Die Identification */ -static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_id_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + if (size != 4) { + return omap_badwidth_read32(opaque, addr); + } + switch (addr) { case 0xfffe1800: /* DIE_ID_LSB */ return 0xc9581f0e; @@ -981,38 +1006,48 @@ static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr) } static void omap_id_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { + if (size != 4) { + return omap_badwidth_write32(opaque, addr, value); + } + OMAP_BAD_REG(addr); } -static CPUReadMemoryFunc * const omap_id_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap_id_read, +static const MemoryRegionOps omap_id_ops = { + .read = omap_id_read, + .write = omap_id_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const omap_id_writefn[] = { - omap_badwidth_write32, - omap_badwidth_write32, - omap_id_write, -}; - -static void omap_id_init(struct omap_mpu_state_s *mpu) +static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu) { - int iomemtype = cpu_register_io_memory(omap_id_readfn, - omap_id_writefn, mpu, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory_offset(0xfffe1800, 0x800, iomemtype, 0xfffe1800); - cpu_register_physical_memory_offset(0xfffed400, 0x100, iomemtype, 0xfffed400); - if (!cpu_is_omap15xx(mpu)) - cpu_register_physical_memory_offset(0xfffe2000, 0x800, iomemtype, 0xfffe2000); + memory_region_init_io(&mpu->id_iomem, &omap_id_ops, mpu, + "omap-id", 0x100000000ULL); + memory_region_init_alias(&mpu->id_iomem_e18, "omap-id-e18", &mpu->id_iomem, + 0xfffe1800, 0x800); + memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18); + memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-ed4", &mpu->id_iomem, + 0xfffed400, 0x100); + memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4); + if (!cpu_is_omap15xx(mpu)) { + memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-e20", + &mpu->id_iomem, 0xfffe2000, 0x800); + memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20); + } } /* MPUI Control (Dummy) */ -static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_mpui_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + if (size != 4) { + return omap_badwidth_read32(opaque, addr); + } + switch (addr) { case 0x00: /* CTRL */ return s->mpui_ctrl; @@ -1038,10 +1073,14 @@ static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr) } static void omap_mpui_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + if (size != 4) { + return omap_badwidth_write32(opaque, addr, value); + } + switch (addr) { case 0x00: /* CTRL */ s->mpui_ctrl = value & 0x007fffff; @@ -1063,16 +1102,10 @@ static void omap_mpui_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_mpui_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap_mpui_read, -}; - -static CPUWriteMemoryFunc * const omap_mpui_writefn[] = { - omap_badwidth_write32, - omap_badwidth_write32, - omap_mpui_write, +static const MemoryRegionOps omap_mpui_ops = { + .read = omap_mpui_read, + .write = omap_mpui_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_mpui_reset(struct omap_mpu_state_s *s) @@ -1080,13 +1113,12 @@ static void omap_mpui_reset(struct omap_mpu_state_s *s) s->mpui_ctrl = 0x0003ff1b; } -static void omap_mpui_init(target_phys_addr_t base, +static void omap_mpui_init(MemoryRegion *memory, target_phys_addr_t base, struct omap_mpu_state_s *mpu) { - int iomemtype = cpu_register_io_memory(omap_mpui_readfn, - omap_mpui_writefn, mpu, DEVICE_NATIVE_ENDIAN); - - cpu_register_physical_memory(base, 0x100, iomemtype); + memory_region_init_io(&mpu->mpui_iomem, &omap_mpui_ops, mpu, + "omap-mpui", 0x100); + memory_region_add_subregion(memory, base, &mpu->mpui_iomem); omap_mpui_reset(mpu); } @@ -1094,6 +1126,7 @@ static void omap_mpui_init(target_phys_addr_t base, /* TIPB Bridges */ struct omap_tipb_bridge_s { qemu_irq abort; + MemoryRegion iomem; int width_intr; uint16_t control; @@ -1102,10 +1135,15 @@ struct omap_tipb_bridge_s { uint16_t enh_control; }; -static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque; + if (size < 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (addr) { case 0x00: /* TIPB_CNTL */ return s->control; @@ -1128,10 +1166,14 @@ static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr) } static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque; + if (size < 2) { + return omap_badwidth_write16(opaque, addr, value); + } + switch (addr) { case 0x00: /* TIPB_CNTL */ s->control = value & 0xffff; @@ -1162,16 +1204,10 @@ static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_tipb_bridge_readfn[] = { - omap_badwidth_read16, - omap_tipb_bridge_read, - omap_tipb_bridge_read, -}; - -static CPUWriteMemoryFunc * const omap_tipb_bridge_writefn[] = { - omap_badwidth_write16, - omap_tipb_bridge_write, - omap_tipb_bridge_write, +static const MemoryRegionOps omap_tipb_bridge_ops = { + .read = omap_tipb_bridge_read, + .write = omap_tipb_bridge_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s) @@ -1182,29 +1218,34 @@ static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s) s->enh_control = 0x000f; } -static struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base, - qemu_irq abort_irq, omap_clk clk) +static struct omap_tipb_bridge_s *omap_tipb_bridge_init( + MemoryRegion *memory, target_phys_addr_t base, + qemu_irq abort_irq, omap_clk clk) { - int iomemtype; struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) - qemu_mallocz(sizeof(struct omap_tipb_bridge_s)); + g_malloc0(sizeof(struct omap_tipb_bridge_s)); s->abort = abort_irq; omap_tipb_bridge_reset(s); - iomemtype = cpu_register_io_memory(omap_tipb_bridge_readfn, - omap_tipb_bridge_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x100, iomemtype); + memory_region_init_io(&s->iomem, &omap_tipb_bridge_ops, s, + "omap-tipb-bridge", 0x100); + memory_region_add_subregion(memory, base, &s->iomem); return s; } /* Dummy Traffic Controller's Memory Interface */ -static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_tcmi_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; uint32_t ret; + if (size != 4) { + return omap_badwidth_read32(opaque, addr); + } + switch (addr) { case 0x00: /* IMIF_PRIO */ case 0x04: /* EMIFS_PRIO */ @@ -1234,10 +1275,14 @@ static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr) } static void omap_tcmi_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + if (size != 4) { + return omap_badwidth_write32(opaque, addr, value); + } + switch (addr) { case 0x00: /* IMIF_PRIO */ case 0x04: /* EMIFS_PRIO */ @@ -1264,16 +1309,10 @@ static void omap_tcmi_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_tcmi_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap_tcmi_read, -}; - -static CPUWriteMemoryFunc * const omap_tcmi_writefn[] = { - omap_badwidth_write32, - omap_badwidth_write32, - omap_tcmi_write, +static const MemoryRegionOps omap_tcmi_ops = { + .read = omap_tcmi_read, + .write = omap_tcmi_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_tcmi_reset(struct omap_mpu_state_s *mpu) @@ -1295,21 +1334,25 @@ static void omap_tcmi_reset(struct omap_mpu_state_s *mpu) mpu->tcmi_regs[0x40 >> 2] = 0x00000000; } -static void omap_tcmi_init(target_phys_addr_t base, +static void omap_tcmi_init(MemoryRegion *memory, target_phys_addr_t base, struct omap_mpu_state_s *mpu) { - int iomemtype = cpu_register_io_memory(omap_tcmi_readfn, - omap_tcmi_writefn, mpu, DEVICE_NATIVE_ENDIAN); - - cpu_register_physical_memory(base, 0x100, iomemtype); + memory_region_init_io(&mpu->tcmi_iomem, &omap_tcmi_ops, mpu, + "omap-tcmi", 0x100); + memory_region_add_subregion(memory, base, &mpu->tcmi_iomem); omap_tcmi_reset(mpu); } /* Digital phase-locked loops control */ -static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_dpll_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + if (addr == 0x00) /* CTL_REG */ return s->mode; @@ -1318,13 +1361,17 @@ static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr) } static void omap_dpll_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque; uint16_t diff; static const int bypass_div[4] = { 1, 2, 4, 4 }; int div, mult; + if (size != 2) { + return omap_badwidth_write16(opaque, addr, value); + } + if (addr == 0x00) { /* CTL_REG */ /* See omap_ulpd_pm_write() too */ diff = s->mode & value; @@ -1350,16 +1397,10 @@ static void omap_dpll_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_dpll_readfn[] = { - omap_badwidth_read16, - omap_dpll_read, - omap_badwidth_read16, -}; - -static CPUWriteMemoryFunc * const omap_dpll_writefn[] = { - omap_badwidth_write16, - omap_dpll_write, - omap_badwidth_write16, +static const MemoryRegionOps omap_dpll_ops = { + .read = omap_dpll_read, + .write = omap_dpll_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_dpll_reset(struct dpll_ctl_s *s) @@ -1368,23 +1409,27 @@ static void omap_dpll_reset(struct dpll_ctl_s *s) omap_clk_setrate(s->dpll, 1, 1); } -static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base, - omap_clk clk) +static void omap_dpll_init(MemoryRegion *memory, struct dpll_ctl_s *s, + target_phys_addr_t base, omap_clk clk) { - int iomemtype = cpu_register_io_memory(omap_dpll_readfn, - omap_dpll_writefn, s, DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&s->iomem, &omap_dpll_ops, s, "omap-dpll", 0x100); s->dpll = clk; omap_dpll_reset(s); - cpu_register_physical_memory(base, 0x100, iomemtype); + memory_region_add_subregion(memory, base, &s->iomem); } /* MPU Clock/Reset/Power Mode Control */ -static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_clkm_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (addr) { case 0x00: /* ARM_CKCTL */ return s->clkm.arm_ckctl; @@ -1578,7 +1623,7 @@ static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s, } static void omap_clkm_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; uint16_t diff; @@ -1588,6 +1633,10 @@ static void omap_clkm_write(void *opaque, target_phys_addr_t addr, "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4", }; + if (size != 2) { + return omap_badwidth_write16(opaque, addr, value); + } + switch (addr) { case 0x00: /* ARM_CKCTL */ diff = s->clkm.arm_ckctl ^ value; @@ -1654,22 +1703,21 @@ static void omap_clkm_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_clkm_readfn[] = { - omap_badwidth_read16, - omap_clkm_read, - omap_badwidth_read16, -}; - -static CPUWriteMemoryFunc * const omap_clkm_writefn[] = { - omap_badwidth_write16, - omap_clkm_write, - omap_badwidth_write16, +static const MemoryRegionOps omap_clkm_ops = { + .read = omap_clkm_read, + .write = omap_clkm_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (addr) { case 0x04: /* DSP_IDLECT1 */ return s->clkm.dsp_idlect1; @@ -1706,11 +1754,15 @@ static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s, } static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; uint16_t diff; + if (size != 2) { + return omap_badwidth_write16(opaque, addr, value); + } + switch (addr) { case 0x04: /* DSP_IDLECT1 */ diff = s->clkm.dsp_idlect1 ^ value; @@ -1737,16 +1789,10 @@ static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_clkdsp_readfn[] = { - omap_badwidth_read16, - omap_clkdsp_read, - omap_badwidth_read16, -}; - -static CPUWriteMemoryFunc * const omap_clkdsp_writefn[] = { - omap_badwidth_write16, - omap_clkdsp_write, - omap_badwidth_write16, +static const MemoryRegionOps omap_clkdsp_ops = { + .read = omap_clkdsp_read, + .write = omap_clkdsp_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_clkm_reset(struct omap_mpu_state_s *s) @@ -1772,15 +1818,13 @@ static void omap_clkm_reset(struct omap_mpu_state_s *s) s->clkm.dsp_rstct2 = 0x0000; } -static void omap_clkm_init(target_phys_addr_t mpu_base, +static void omap_clkm_init(MemoryRegion *memory, target_phys_addr_t mpu_base, target_phys_addr_t dsp_base, struct omap_mpu_state_s *s) { - int iomemtype[2] = { - cpu_register_io_memory(omap_clkm_readfn, omap_clkm_writefn, s, - DEVICE_NATIVE_ENDIAN), - cpu_register_io_memory(omap_clkdsp_readfn, omap_clkdsp_writefn, s, - DEVICE_NATIVE_ENDIAN), - }; + memory_region_init_io(&s->clkm_iomem, &omap_clkm_ops, s, + "omap-clkm", 0x100); + memory_region_init_io(&s->clkdsp_iomem, &omap_clkdsp_ops, s, + "omap-clkdsp", 0x1000); s->clkm.arm_idlect1 = 0x03ff; s->clkm.arm_idlect2 = 0x0100; @@ -1788,8 +1832,8 @@ static void omap_clkm_init(target_phys_addr_t mpu_base, omap_clkm_reset(s); s->clkm.cold_start = 0x3a; - cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]); - cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]); + memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem); + memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem); } /* MPU I/O */ @@ -1799,6 +1843,7 @@ struct omap_mpuio_s { qemu_irq *in; qemu_irq handler[16]; qemu_irq wakeup; + MemoryRegion iomem; uint16_t inputs; uint16_t outputs; @@ -1853,12 +1898,17 @@ static void omap_mpuio_kbd_update(struct omap_mpuio_s *s) s->row_latch = ~rows; } -static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_mpuio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; uint16_t ret; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (offset) { case 0x00: /* INPUT_LATCH */ return s->inputs; @@ -1909,13 +1959,17 @@ static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr) } static void omap_mpuio_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; uint16_t diff; int ln; + if (size != 2) { + return omap_badwidth_write16(opaque, addr, value); + } + switch (offset) { case 0x04: /* OUTPUT_REG */ diff = (s->outputs ^ value) & ~s->dir; @@ -1981,16 +2035,10 @@ static void omap_mpuio_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_mpuio_readfn[] = { - omap_badwidth_read16, - omap_mpuio_read, - omap_badwidth_read16, -}; - -static CPUWriteMemoryFunc * const omap_mpuio_writefn[] = { - omap_badwidth_write16, - omap_mpuio_write, - omap_badwidth_write16, +static const MemoryRegionOps omap_mpuio_ops = { + .read = omap_mpuio_read, + .write = omap_mpuio_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_mpuio_reset(struct omap_mpuio_s *s) @@ -2018,13 +2066,13 @@ static void omap_mpuio_onoff(void *opaque, int line, int on) omap_mpuio_kbd_update(s); } -struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base, +struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory, + target_phys_addr_t base, qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup, omap_clk clk) { - int iomemtype; struct omap_mpuio_s *s = (struct omap_mpuio_s *) - qemu_mallocz(sizeof(struct omap_mpuio_s)); + g_malloc0(sizeof(struct omap_mpuio_s)); s->irq = gpio_int; s->kbd_irq = kbd_int; @@ -2032,9 +2080,9 @@ struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base, s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16); omap_mpuio_reset(s); - iomemtype = cpu_register_io_memory(omap_mpuio_readfn, - omap_mpuio_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->iomem, &omap_mpuio_ops, s, + "omap-mpuio", 0x800); + memory_region_add_subregion(memory, base, &s->iomem); omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]); @@ -2068,6 +2116,7 @@ void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down) /* MicroWire Interface */ struct omap_uwire_s { + MemoryRegion iomem; qemu_irq txirq; qemu_irq rxirq; qemu_irq txdrq; @@ -2105,11 +2154,16 @@ static void omap_uwire_transfer_start(struct omap_uwire_s *s) } } -static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_uwire_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_uwire_s *s = (struct omap_uwire_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (offset) { case 0x00: /* RDR */ s->control &= ~(1 << 15); /* RDRB */ @@ -2135,11 +2189,15 @@ static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr) } static void omap_uwire_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_uwire_s *s = (struct omap_uwire_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 2) { + return omap_badwidth_write16(opaque, addr, value); + } + switch (offset) { case 0x00: /* TDR */ s->txbuf = value; /* TD */ @@ -2183,16 +2241,10 @@ static void omap_uwire_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_uwire_readfn[] = { - omap_badwidth_read16, - omap_uwire_read, - omap_badwidth_read16, -}; - -static CPUWriteMemoryFunc * const omap_uwire_writefn[] = { - omap_badwidth_write16, - omap_uwire_write, - omap_badwidth_write16, +static const MemoryRegionOps omap_uwire_ops = { + .read = omap_uwire_read, + .write = omap_uwire_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_uwire_reset(struct omap_uwire_s *s) @@ -2205,21 +2257,22 @@ static void omap_uwire_reset(struct omap_uwire_s *s) s->setup[4] = 0; } -struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base, - qemu_irq *irq, qemu_irq dma, omap_clk clk) +static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory, + target_phys_addr_t base, + qemu_irq txirq, qemu_irq rxirq, + qemu_irq dma, + omap_clk clk) { - int iomemtype; struct omap_uwire_s *s = (struct omap_uwire_s *) - qemu_mallocz(sizeof(struct omap_uwire_s)); + g_malloc0(sizeof(struct omap_uwire_s)); - s->txirq = irq[0]; - s->rxirq = irq[1]; + s->txirq = txirq; + s->rxirq = rxirq; s->txdrq = dma; omap_uwire_reset(s); - iomemtype = cpu_register_io_memory(omap_uwire_readfn, - omap_uwire_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->iomem, &omap_uwire_ops, s, "omap-uwire", 0x800); + memory_region_add_subregion(system_memory, base, &s->iomem); return s; } @@ -2246,11 +2299,16 @@ static void omap_pwl_update(struct omap_mpu_state_s *s) } } -static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_pwl_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 1) { + return omap_badwidth_read8(opaque, addr); + } + switch (offset) { case 0x00: /* PWL_LEVEL */ return s->pwl.level; @@ -2262,11 +2320,15 @@ static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr) } static void omap_pwl_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 1) { + return omap_badwidth_write8(opaque, addr, value); + } + switch (offset) { case 0x00: /* PWL_LEVEL */ s->pwl.level = value; @@ -2282,16 +2344,10 @@ static void omap_pwl_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_pwl_readfn[] = { - omap_pwl_read, - omap_badwidth_read8, - omap_badwidth_read8, -}; - -static CPUWriteMemoryFunc * const omap_pwl_writefn[] = { - omap_pwl_write, - omap_badwidth_write8, - omap_badwidth_write8, +static const MemoryRegionOps omap_pwl_ops = { + .read = omap_pwl_read, + .write = omap_pwl_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_pwl_reset(struct omap_mpu_state_s *s) @@ -2311,26 +2367,30 @@ static void omap_pwl_clk_update(void *opaque, int line, int on) omap_pwl_update(s); } -static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s, +static void omap_pwl_init(MemoryRegion *system_memory, + target_phys_addr_t base, struct omap_mpu_state_s *s, omap_clk clk) { - int iomemtype; - omap_pwl_reset(s); - iomemtype = cpu_register_io_memory(omap_pwl_readfn, - omap_pwl_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->pwl_iomem, &omap_pwl_ops, s, + "omap-pwl", 0x800); + memory_region_add_subregion(system_memory, base, &s->pwl_iomem); omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]); } /* Pulse-Width Tone module */ -static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_pwt_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 1) { + return omap_badwidth_read8(opaque, addr); + } + switch (offset) { case 0x00: /* FRC */ return s->pwt.frc; @@ -2344,11 +2404,15 @@ static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr) } static void omap_pwt_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 1) { + return omap_badwidth_write8(opaque, addr, value); + } + switch (offset) { case 0x00: /* FRC */ s->pwt.frc = value & 0x3f; @@ -2386,16 +2450,10 @@ static void omap_pwt_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_pwt_readfn[] = { - omap_pwt_read, - omap_badwidth_read8, - omap_badwidth_read8, -}; - -static CPUWriteMemoryFunc * const omap_pwt_writefn[] = { - omap_pwt_write, - omap_badwidth_write8, - omap_badwidth_write8, +static const MemoryRegionOps omap_pwt_ops = { + .read =omap_pwt_read, + .write = omap_pwt_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_pwt_reset(struct omap_mpu_state_s *s) @@ -2405,21 +2463,21 @@ static void omap_pwt_reset(struct omap_mpu_state_s *s) s->pwt.gcr = 0; } -static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s, +static void omap_pwt_init(MemoryRegion *system_memory, + target_phys_addr_t base, struct omap_mpu_state_s *s, omap_clk clk) { - int iomemtype; - s->pwt.clk = clk; omap_pwt_reset(s); - iomemtype = cpu_register_io_memory(omap_pwt_readfn, - omap_pwt_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->pwt_iomem, &omap_pwt_ops, s, + "omap-pwt", 0x800); + memory_region_add_subregion(system_memory, base, &s->pwt_iomem); } /* Real-time Clock module */ struct omap_rtc_s { + MemoryRegion iomem; qemu_irq irq; qemu_irq alarm; QEMUTimer *clk; @@ -2452,12 +2510,17 @@ static void omap_rtc_alarm_update(struct omap_rtc_s *s) printf("%s: conversion failed\n", __FUNCTION__); } -static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_rtc_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_rtc_s *s = (struct omap_rtc_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; uint8_t i; + if (size != 1) { + return omap_badwidth_read8(opaque, addr); + } + switch (offset) { case 0x00: /* SECONDS_REG */ return to_bcd(s->current_tm.tm_sec); @@ -2530,13 +2593,17 @@ static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr) } static void omap_rtc_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_rtc_s *s = (struct omap_rtc_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; struct tm new_tm; time_t ti[2]; + if (size != 1) { + return omap_badwidth_write8(opaque, addr, value); + } + switch (offset) { case 0x00: /* SECONDS_REG */ #ifdef ALMDEBUG @@ -2717,16 +2784,10 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_rtc_readfn[] = { - omap_rtc_read, - omap_badwidth_read8, - omap_badwidth_read8, -}; - -static CPUWriteMemoryFunc * const omap_rtc_writefn[] = { - omap_rtc_write, - omap_badwidth_write8, - omap_badwidth_write8, +static const MemoryRegionOps omap_rtc_ops = { + .read = omap_rtc_read, + .write = omap_rtc_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_rtc_tick(void *opaque) @@ -2802,7 +2863,7 @@ static void omap_rtc_reset(struct omap_rtc_s *s) s->pm_am = 0; s->auto_comp = 0; s->round = 0; - s->tick = qemu_get_clock(rt_clock); + s->tick = qemu_get_clock_ms(rt_clock); memset(&s->alarm_tm, 0, sizeof(s->alarm_tm)); s->alarm_tm.tm_mday = 0x01; s->status = 1 << 7; @@ -2813,28 +2874,30 @@ static void omap_rtc_reset(struct omap_rtc_s *s) omap_rtc_tick(s); } -static struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base, - qemu_irq *irq, omap_clk clk) +static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory, + target_phys_addr_t base, + qemu_irq timerirq, qemu_irq alarmirq, + omap_clk clk) { - int iomemtype; struct omap_rtc_s *s = (struct omap_rtc_s *) - qemu_mallocz(sizeof(struct omap_rtc_s)); + g_malloc0(sizeof(struct omap_rtc_s)); - s->irq = irq[0]; - s->alarm = irq[1]; - s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s); + s->irq = timerirq; + s->alarm = alarmirq; + s->clk = qemu_new_timer_ms(rt_clock, omap_rtc_tick, s); omap_rtc_reset(s); - iomemtype = cpu_register_io_memory(omap_rtc_readfn, - omap_rtc_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->iomem, &omap_rtc_ops, s, + "omap-rtc", 0x800); + memory_region_add_subregion(system_memory, base, &s->iomem); return s; } /* Multi-channel Buffered Serial Port interfaces */ struct omap_mcbsp_s { + MemoryRegion iomem; qemu_irq txirq; qemu_irq rxirq; qemu_irq txdrq; @@ -2915,7 +2978,7 @@ static void omap_mcbsp_source_tick(void *opaque) s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7]; omap_mcbsp_rx_newdata(s); - qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(s->source_timer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec()); } @@ -2961,7 +3024,7 @@ static void omap_mcbsp_sink_tick(void *opaque) s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7]; omap_mcbsp_tx_newdata(s); - qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(s->sink_timer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec()); } @@ -3040,12 +3103,17 @@ static void omap_mcbsp_req_update(struct omap_mcbsp_s *s) omap_mcbsp_rx_stop(s); } -static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; uint16_t ret; + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + switch (offset) { case 0x00: /* DRR2 */ if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */ @@ -3302,16 +3370,20 @@ static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr, omap_badwidth_write16(opaque, addr, value); } -static CPUReadMemoryFunc * const omap_mcbsp_readfn[] = { - omap_badwidth_read16, - omap_mcbsp_read, - omap_badwidth_read16, -}; +static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) +{ + switch (size) { + case 2: return omap_mcbsp_writeh(opaque, addr, value); + case 4: return omap_mcbsp_writew(opaque, addr, value); + default: return omap_badwidth_write16(opaque, addr, value); + } +} -static CPUWriteMemoryFunc * const omap_mcbsp_writefn[] = { - omap_badwidth_write16, - omap_mcbsp_writeh, - omap_mcbsp_writew, +static const MemoryRegionOps omap_mcbsp_ops = { + .read = omap_mcbsp_read, + .write = omap_mcbsp_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_mcbsp_reset(struct omap_mcbsp_s *s) @@ -3333,24 +3405,24 @@ static void omap_mcbsp_reset(struct omap_mcbsp_s *s) qemu_del_timer(s->sink_timer); } -struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base, - qemu_irq *irq, qemu_irq *dma, omap_clk clk) +static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory, + target_phys_addr_t base, + qemu_irq txirq, qemu_irq rxirq, + qemu_irq *dma, omap_clk clk) { - int iomemtype; struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) - qemu_mallocz(sizeof(struct omap_mcbsp_s)); + g_malloc0(sizeof(struct omap_mcbsp_s)); - s->txirq = irq[0]; - s->rxirq = irq[1]; + s->txirq = txirq; + s->rxirq = rxirq; s->txdrq = dma[0]; s->rxdrq = dma[1]; - s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s); - s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s); + s->sink_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_sink_tick, s); + s->source_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_source_tick, s); omap_mcbsp_reset(s); - iomemtype = cpu_register_io_memory(omap_mcbsp_readfn, - omap_mcbsp_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->iomem, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800); + memory_region_add_subregion(system_memory, base, &s->iomem); return s; } @@ -3384,6 +3456,7 @@ void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave) /* LED Pulse Generators */ struct omap_lpg_s { + MemoryRegion iomem; QEMUTimer *tm; uint8_t control; @@ -3399,9 +3472,9 @@ static void omap_lpg_tick(void *opaque) struct omap_lpg_s *s = opaque; if (s->cycle) - qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on); + qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->period - s->on); else - qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on); + qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->on); s->cycle = !s->cycle; printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off"); @@ -3448,11 +3521,16 @@ static void omap_lpg_reset(struct omap_lpg_s *s) omap_lpg_update(s); } -static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_lpg_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_lpg_s *s = (struct omap_lpg_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 1) { + return omap_badwidth_read8(opaque, addr); + } + switch (offset) { case 0x00: /* LCR */ return s->control; @@ -3466,11 +3544,15 @@ static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr) } static void omap_lpg_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_lpg_s *s = (struct omap_lpg_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; + if (size != 1) { + return omap_badwidth_write8(opaque, addr, value); + } + switch (offset) { case 0x00: /* LCR */ if (~value & (1 << 6)) /* LPGRES */ @@ -3490,16 +3572,10 @@ static void omap_lpg_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_lpg_readfn[] = { - omap_lpg_read, - omap_badwidth_read8, - omap_badwidth_read8, -}; - -static CPUWriteMemoryFunc * const omap_lpg_writefn[] = { - omap_lpg_write, - omap_badwidth_write8, - omap_badwidth_write8, +static const MemoryRegionOps omap_lpg_ops = { + .read = omap_lpg_read, + .write = omap_lpg_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void omap_lpg_clk_update(void *opaque, int line, int on) @@ -3510,19 +3586,18 @@ static void omap_lpg_clk_update(void *opaque, int line, int on) omap_lpg_update(s); } -static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk) +static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory, + target_phys_addr_t base, omap_clk clk) { - int iomemtype; struct omap_lpg_s *s = (struct omap_lpg_s *) - qemu_mallocz(sizeof(struct omap_lpg_s)); + g_malloc0(sizeof(struct omap_lpg_s)); - s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s); + s->tm = qemu_new_timer_ms(rt_clock, omap_lpg_tick, s); omap_lpg_reset(s); - iomemtype = cpu_register_io_memory(omap_lpg_readfn, - omap_lpg_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x800, iomemtype); + memory_region_init_io(&s->iomem, &omap_lpg_ops, s, "omap-lpg", 0x800); + memory_region_add_subregion(system_memory, base, &s->iomem); omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]); @@ -3530,8 +3605,13 @@ static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk) } /* MPUI Peripheral Bridge configuration */ -static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { + if (size != 2) { + return omap_badwidth_read16(opaque, addr); + } + if (addr == OMAP_MPUI_BASE) /* CMR */ return 0xfe4d; @@ -3539,23 +3619,26 @@ static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr) return 0; } -static CPUReadMemoryFunc * const omap_mpui_io_readfn[] = { - omap_badwidth_read16, - omap_mpui_io_read, - omap_badwidth_read16, -}; +static void omap_mpui_io_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) +{ + /* FIXME: infinite loop */ + omap_badwidth_write16(opaque, addr, value); +} -static CPUWriteMemoryFunc * const omap_mpui_io_writefn[] = { - omap_badwidth_write16, - omap_badwidth_write16, - omap_badwidth_write16, +static const MemoryRegionOps omap_mpui_io_ops = { + .read = omap_mpui_io_read, + .write = omap_mpui_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu) +static void omap_setup_mpui_io(MemoryRegion *system_memory, + struct omap_mpu_state_s *mpu) { - int iomemtype = cpu_register_io_memory(omap_mpui_io_readfn, - omap_mpui_io_writefn, mpu, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype); + memory_region_init_io(&mpu->mpui_io_iomem, &omap_mpui_io_ops, mpu, + "omap-mpui-io", 0x7fff); + memory_region_add_subregion(system_memory, OMAP_MPUI_BASE, + &mpu->mpui_io_iomem); } /* General chip reset */ @@ -3563,8 +3646,6 @@ static void omap1_mpu_reset(void *opaque) { struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; - omap_inth_reset(mpu->ih[0]); - omap_inth_reset(mpu->ih[1]); omap_dma_reset(mpu->dma); omap_mpu_timer_reset(mpu->timer[0]); omap_mpu_timer_reset(mpu->timer[1]); @@ -3585,7 +3666,6 @@ static void omap1_mpu_reset(void *opaque) omap_uart_reset(mpu->uart[2]); omap_mmc_reset(mpu->mmc); omap_mpuio_reset(mpu->mpuio); - omap_gpio_reset(mpu->gpio); omap_uwire_reset(mpu->microwire); omap_pwl_reset(mpu); omap_pwt_reset(mpu); @@ -3630,14 +3710,16 @@ static const struct omap_map_s { { 0 } }; -static void omap_setup_dsp_mapping(const struct omap_map_s *map) +static void omap_setup_dsp_mapping(MemoryRegion *system_memory, + const struct omap_map_s *map) { - int io; + MemoryRegion *io; for (; map->phys_dsp; map ++) { - io = cpu_get_physical_page_desc(map->phys_mpu); - - cpu_register_physical_memory(map->phys_dsp, map->size, io); + io = g_new(MemoryRegion, 1); + memory_region_init_alias(io, map->name, + system_memory, map->phys_mpu, map->size); + memory_region_add_subregion(system_memory, map->phys_dsp, io); } } @@ -3706,16 +3788,17 @@ static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s, return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr); } -struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, +struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory, + unsigned long sdram_size, const char *core) { int i; struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) - qemu_mallocz(sizeof(struct omap_mpu_state_s)); - ram_addr_t imif_base, emiff_base; + g_malloc0(sizeof(struct omap_mpu_state_s)); qemu_irq *cpu_irq; qemu_irq dma_irqs[6]; DriveInfo *dinfo; + SysBusDevice *busdev; if (!core) core = "ti925t"; @@ -3736,27 +3819,38 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, omap_clk_init(s); /* Memory-mapped stuff */ - cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size, - (emiff_base = qemu_ram_alloc(NULL, "omap1.dram", - s->sdram_size)) | IO_MEM_RAM); - cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size, - (imif_base = qemu_ram_alloc(NULL, "omap1.sram", - s->sram_size)) | IO_MEM_RAM); + memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size); + memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram); + memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size); + memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram); - omap_clkm_init(0xfffece00, 0xe1008000, s); + omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s); cpu_irq = arm_pic_init_cpu(s->env); - s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0], - cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ], - omap_findclk(s, "arminth_ck")); - s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1], - omap_inth_get_pin(s->ih[0], OMAP_INT_15XX_IH2_IRQ), - NULL, omap_findclk(s, "arminth_ck")); - - for (i = 0; i < 6; i ++) - dma_irqs[i] = - s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr]; - s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD], + s->ih[0] = qdev_create(NULL, "omap-intc"); + qdev_prop_set_uint32(s->ih[0], "size", 0x100); + qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck")); + qdev_init_nofail(s->ih[0]); + busdev = sysbus_from_qdev(s->ih[0]); + sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]); + sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]); + sysbus_mmio_map(busdev, 0, 0xfffecb00); + s->ih[1] = qdev_create(NULL, "omap-intc"); + qdev_prop_set_uint32(s->ih[1], "size", 0x800); + qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck")); + qdev_init_nofail(s->ih[1]); + busdev = sysbus_from_qdev(s->ih[1]); + sysbus_connect_irq(busdev, 0, + qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ)); + /* The second interrupt controller's FIQ output is not wired up */ + sysbus_mmio_map(busdev, 0, 0xfffe0000); + + for (i = 0; i < 6; i++) { + dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih], + omap1_dma_irq_map[i].intr); + } + s->dma = omap_dma_init(0xfffed800, dma_irqs, + qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD), s, omap_findclk(s, "dma_ck"), omap_dma_3_1); s->port[emiff ].addr_valid = omap_validate_emiff_addr; @@ -3767,70 +3861,77 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr; /* Register SDRAM and SRAM DMA ports for fast transfers. */ - soc_dma_port_add_mem_ram(s->dma, - emiff_base, OMAP_EMIFF_BASE, s->sdram_size); - soc_dma_port_add_mem_ram(s->dma, - imif_base, OMAP_IMIF_BASE, s->sram_size); + soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram), + OMAP_EMIFF_BASE, s->sdram_size); + soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram), + OMAP_IMIF_BASE, s->sram_size); - s->timer[0] = omap_mpu_timer_init(0xfffec500, - s->irq[0][OMAP_INT_TIMER1], + s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500, + qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1), omap_findclk(s, "mputim_ck")); - s->timer[1] = omap_mpu_timer_init(0xfffec600, - s->irq[0][OMAP_INT_TIMER2], + s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600, + qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2), omap_findclk(s, "mputim_ck")); - s->timer[2] = omap_mpu_timer_init(0xfffec700, - s->irq[0][OMAP_INT_TIMER3], + s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700, + qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3), omap_findclk(s, "mputim_ck")); - s->wdt = omap_wd_timer_init(0xfffec800, - s->irq[0][OMAP_INT_WD_TIMER], + s->wdt = omap_wd_timer_init(system_memory, 0xfffec800, + qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER), omap_findclk(s, "armwdt_ck")); - s->os_timer = omap_os_timer_init(0xfffb9000, - s->irq[1][OMAP_INT_OS_TIMER], + s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000, + qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER), omap_findclk(s, "clk32-kHz")); - s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL], - omap_dma_get_lcdch(s->dma), imif_base, emiff_base, - omap_findclk(s, "lcd_ck")); + s->lcd = omap_lcdc_init(0xfffec000, + qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL), + omap_dma_get_lcdch(s->dma), + omap_findclk(s, "lcd_ck")); - omap_ulpd_pm_init(0xfffe0800, s); - omap_pin_cfg_init(0xfffe1000, s); - omap_id_init(s); + omap_ulpd_pm_init(system_memory, 0xfffe0800, s); + omap_pin_cfg_init(system_memory, 0xfffe1000, s); + omap_id_init(system_memory, s); - omap_mpui_init(0xfffec900, s); + omap_mpui_init(system_memory, 0xfffec900, s); - s->private_tipb = omap_tipb_bridge_init(0xfffeca00, - s->irq[0][OMAP_INT_BRIDGE_PRIV], + s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00, + qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV), omap_findclk(s, "tipb_ck")); - s->public_tipb = omap_tipb_bridge_init(0xfffed300, - s->irq[0][OMAP_INT_BRIDGE_PUB], + s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300, + qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB), omap_findclk(s, "tipb_ck")); - omap_tcmi_init(0xfffecc00, s); + omap_tcmi_init(system_memory, 0xfffecc00, s); - s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1], + s->uart[0] = omap_uart_init(0xfffb0000, + qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1), omap_findclk(s, "uart1_ck"), omap_findclk(s, "uart1_ck"), s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX], "uart1", serial_hds[0]); - s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2], + s->uart[1] = omap_uart_init(0xfffb0800, + qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2), omap_findclk(s, "uart2_ck"), omap_findclk(s, "uart2_ck"), s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX], "uart2", serial_hds[0] ? serial_hds[1] : NULL); - s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3], + s->uart[2] = omap_uart_init(0xfffb9800, + qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3), omap_findclk(s, "uart3_ck"), omap_findclk(s, "uart3_ck"), s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX], "uart3", serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL); - omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1")); - omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2")); - omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3")); + omap_dpll_init(system_memory, + &s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1")); + omap_dpll_init(system_memory, + &s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2")); + omap_dpll_init(system_memory, + &s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3")); dinfo = drive_get(IF_SD, 0, 0); if (!dinfo) { @@ -3838,37 +3939,59 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, exit(1); } s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv, - s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX], + qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN), + &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck")); - s->mpuio = omap_mpuio_init(0xfffb5000, - s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO], - s->wakeup, omap_findclk(s, "clk32-kHz")); - - s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1], - omap_findclk(s, "arm_gpio_ck")); - - s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX], + s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000, + qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD), + qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO), + s->wakeup, omap_findclk(s, "clk32-kHz")); + + s->gpio = qdev_create(NULL, "omap-gpio"); + qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model); + qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck")); + qdev_init_nofail(s->gpio); + sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0, + qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1)); + sysbus_mmio_map(sysbus_from_qdev(s->gpio), 0, 0xfffce000); + + s->microwire = omap_uwire_init(system_memory, 0xfffb3000, + qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX), + qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX), s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck")); - omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck")); - omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck")); + omap_pwl_init(system_memory, 0xfffb5800, s, omap_findclk(s, "armxor_ck")); + omap_pwt_init(system_memory, 0xfffb6000, s, omap_findclk(s, "armxor_ck")); - s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C], + s->i2c[0] = omap_i2c_init(0xfffb3800, + qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C), &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck")); - s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER], + s->rtc = omap_rtc_init(system_memory, 0xfffb4800, + qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER), + qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM), omap_findclk(s, "clk32-kHz")); - s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX], + s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800, + qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX), + qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX), &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck")); - s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX], + s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000, + qdev_get_gpio_in(s->ih[0], + OMAP_INT_310_McBSP2_TX), + qdev_get_gpio_in(s->ih[0], + OMAP_INT_310_McBSP2_RX), &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck")); - s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX], + s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000, + qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX), + qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX), &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck")); - s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz")); - s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz")); + s->led[0] = omap_lpg_init(system_memory, + 0xfffbd000, omap_findclk(s, "clk32-kHz")); + s->led[1] = omap_lpg_init(system_memory, + 0xfffbd800, omap_findclk(s, "clk32-kHz")); /* Register mappings not currenlty implemented: * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310) @@ -3885,8 +4008,8 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, * DSP MMU fffed200 - fffed2ff */ - omap_setup_dsp_mapping(omap15xx_dsp_mm); - omap_setup_mpui_io(s); + omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm); + omap_setup_mpui_io(system_memory, s); qemu_register_reset(omap1_mpu_reset, s); diff --git a/hw/omap2.c b/hw/omap2.c index 0f13272..5197fef 100644 --- a/hw/omap2.c +++ b/hw/omap2.c @@ -27,6 +27,7 @@ #include "qemu-char.h" #include "flash.h" #include "soc_dma.h" +#include "sysbus.h" #include "audio/audio.h" /* Enhanced Audio Controller (CODEC only) */ @@ -590,7 +591,7 @@ static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta, { int iomemtype; struct omap_eac_s *s = (struct omap_eac_s *) - qemu_mallocz(sizeof(struct omap_eac_s)); + g_malloc0(sizeof(struct omap_eac_s)); s->irq = irq; s->codec.rxdrq = *drq ++; @@ -747,14 +748,14 @@ static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr, if (ch == STI_TRACE_CONTROL_CHANNEL) { /* Flush channel value. */ - qemu_chr_write(s->chr, (const uint8_t *) "\r", 1); + qemu_chr_fe_write(s->chr, (const uint8_t *) "\r", 1); } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) { if (value == 0xc0 || value == 0xc3) { /* Open channel ch. */ } else if (value == 0x00) - qemu_chr_write(s->chr, (const uint8_t *) "\n", 1); + qemu_chr_fe_write(s->chr, (const uint8_t *) "\n", 1); else - qemu_chr_write(s->chr, &byte, 1); + qemu_chr_fe_write(s->chr, &byte, 1); } } @@ -776,12 +777,12 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta, { int iomemtype; struct omap_sti_s *s = (struct omap_sti_s *) - qemu_mallocz(sizeof(struct omap_sti_s)); + g_malloc0(sizeof(struct omap_sti_s)); s->irq = irq; omap_sti_reset(s); - s->chr = chr ?: qemu_chr_open("null", "null", NULL); + s->chr = chr ?: qemu_chr_new("null", "null", NULL); iomemtype = l4_register_io_memory(omap_sti_readfn, omap_sti_writefn, s); @@ -1789,7 +1790,7 @@ static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta, { int iomemtype; struct omap_prcm_s *s = (struct omap_prcm_s *) - qemu_mallocz(sizeof(struct omap_prcm_s)); + g_malloc0(sizeof(struct omap_prcm_s)); s->irq[0] = mpu_int; s->irq[1] = dsp_int; @@ -2162,7 +2163,7 @@ static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta, { int iomemtype; struct omap_sysctl_s *s = (struct omap_sysctl_s *) - qemu_mallocz(sizeof(struct omap_sysctl_s)); + g_malloc0(sizeof(struct omap_sysctl_s)); s->mpu = mpu; omap_sysctl_reset(s); @@ -2179,7 +2180,6 @@ static void omap2_mpu_reset(void *opaque) { struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; - omap_inth_reset(mpu->ih[0]); omap_dma_reset(mpu->dma); omap_prcm_reset(mpu->prcm); omap_sysctl_reset(mpu->sysc); @@ -2203,7 +2203,6 @@ static void omap2_mpu_reset(void *opaque) omap_uart_reset(mpu->uart[1]); omap_uart_reset(mpu->uart[2]); omap_mmc_reset(mpu->mmc); - omap_gpif_reset(mpu->gpif); omap_mcspi_reset(mpu->mcspi[0]); omap_mcspi_reset(mpu->mcspi[1]); omap_i2c_reset(mpu->i2c[0]); @@ -2228,13 +2227,14 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, const char *core) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) - qemu_mallocz(sizeof(struct omap_mpu_state_s)); + g_malloc0(sizeof(struct omap_mpu_state_s)); ram_addr_t sram_base, q2_base; qemu_irq *cpu_irq; qemu_irq dma_irqs[4]; - omap_clk gpio_clks[4]; DriveInfo *dinfo; int i; + SysBusDevice *busdev; + struct omap_target_agent_s *ta; /* Core */ s->mpu_model = omap2420; @@ -2263,31 +2263,41 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */ cpu_irq = arm_pic_init_cpu(s->env); - s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0], - cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ], - omap_findclk(s, "mpu_intc_fclk"), - omap_findclk(s, "mpu_intc_iclk")); - + s->ih[0] = qdev_create(NULL, "omap2-intc"); + qdev_prop_set_uint8(s->ih[0], "revision", 0x21); + qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk")); + qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk")); + qdev_init_nofail(s->ih[0]); + busdev = sysbus_from_qdev(s->ih[0]); + sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]); + sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]); + sysbus_mmio_map(busdev, 0, 0x480fe000); s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3), - s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s); + qdev_get_gpio_in(s->ih[0], + OMAP_INT_24XX_PRCM_MPU_IRQ), + NULL, NULL, s); s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1), omap_findclk(s, "omapctrl_iclk"), s); - for (i = 0; i < 4; i ++) - dma_irqs[i] = - s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr]; + for (i = 0; i < 4; i++) { + dma_irqs[i] = qdev_get_gpio_in(s->ih[omap2_dma_irq_map[i].ih], + omap2_dma_irq_map[i].intr); + } s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32, omap_findclk(s, "sdma_iclk"), omap_findclk(s, "sdma_fclk")); s->port->addr_valid = omap2_validate_addr; /* Register SDRAM and SRAM ports for fast DMA transfers. */ - soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size); - soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size); + soc_dma_port_add_mem(s->dma, qemu_get_ram_ptr(q2_base), + OMAP2_Q2_BASE, s->sdram_size); + soc_dma_port_add_mem(s->dma, qemu_get_ram_ptr(sram_base), + OMAP2_SRAM_BASE, s->sram_size); s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19), - s->irq[0][OMAP_INT_24XX_UART1_IRQ], + qdev_get_gpio_in(s->ih[0], + OMAP_INT_24XX_UART1_IRQ), omap_findclk(s, "uart1_fclk"), omap_findclk(s, "uart1_iclk"), s->drq[OMAP24XX_DMA_UART1_TX], @@ -2295,7 +2305,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, "uart1", serial_hds[0]); s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20), - s->irq[0][OMAP_INT_24XX_UART2_IRQ], + qdev_get_gpio_in(s->ih[0], + OMAP_INT_24XX_UART2_IRQ), omap_findclk(s, "uart2_fclk"), omap_findclk(s, "uart2_iclk"), s->drq[OMAP24XX_DMA_UART2_TX], @@ -2303,7 +2314,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, "uart2", serial_hds[0] ? serial_hds[1] : NULL); s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21), - s->irq[0][OMAP_INT_24XX_UART3_IRQ], + qdev_get_gpio_in(s->ih[0], + OMAP_INT_24XX_UART3_IRQ), omap_findclk(s, "uart3_fclk"), omap_findclk(s, "uart3_iclk"), s->drq[OMAP24XX_DMA_UART3_TX], @@ -2312,51 +2324,51 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL); s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7), - s->irq[0][OMAP_INT_24XX_GPTIMER1], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER1), omap_findclk(s, "wu_gpt1_clk"), omap_findclk(s, "wu_l4_iclk")); s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8), - s->irq[0][OMAP_INT_24XX_GPTIMER2], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER2), omap_findclk(s, "core_gpt2_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22), - s->irq[0][OMAP_INT_24XX_GPTIMER3], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER3), omap_findclk(s, "core_gpt3_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23), - s->irq[0][OMAP_INT_24XX_GPTIMER4], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER4), omap_findclk(s, "core_gpt4_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24), - s->irq[0][OMAP_INT_24XX_GPTIMER5], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER5), omap_findclk(s, "core_gpt5_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25), - s->irq[0][OMAP_INT_24XX_GPTIMER6], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER6), omap_findclk(s, "core_gpt6_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26), - s->irq[0][OMAP_INT_24XX_GPTIMER7], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER7), omap_findclk(s, "core_gpt7_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27), - s->irq[0][OMAP_INT_24XX_GPTIMER8], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER8), omap_findclk(s, "core_gpt8_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28), - s->irq[0][OMAP_INT_24XX_GPTIMER9], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER9), omap_findclk(s, "core_gpt9_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29), - s->irq[0][OMAP_INT_24XX_GPTIMER10], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER10), omap_findclk(s, "core_gpt10_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30), - s->irq[0][OMAP_INT_24XX_GPTIMER11], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER11), omap_findclk(s, "core_gpt11_clk"), omap_findclk(s, "core_l4_iclk")); s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31), - s->irq[0][OMAP_INT_24XX_GPTIMER12], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER12), omap_findclk(s, "core_gpt12_clk"), omap_findclk(s, "core_l4_iclk")); @@ -2367,26 +2379,52 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, omap_findclk(s, "core_l4_iclk")); s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5), - s->irq[0][OMAP_INT_24XX_I2C1_IRQ], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C1_IRQ), &s->drq[OMAP24XX_DMA_I2C1_TX], omap_findclk(s, "i2c1.fclk"), omap_findclk(s, "i2c1.iclk")); s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6), - s->irq[0][OMAP_INT_24XX_I2C2_IRQ], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C2_IRQ), &s->drq[OMAP24XX_DMA_I2C2_TX], omap_findclk(s, "i2c2.fclk"), omap_findclk(s, "i2c2.iclk")); - gpio_clks[0] = omap_findclk(s, "gpio1_dbclk"); - gpio_clks[1] = omap_findclk(s, "gpio2_dbclk"); - gpio_clks[2] = omap_findclk(s, "gpio3_dbclk"); - gpio_clks[3] = omap_findclk(s, "gpio4_dbclk"); - s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3), - &s->irq[0][OMAP_INT_24XX_GPIO_BANK1], - gpio_clks, omap_findclk(s, "gpio_iclk"), 4); + s->gpio = qdev_create(NULL, "omap2-gpio"); + qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model); + qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk")); + qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk")); + qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk")); + qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk")); + qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk")); + if (s->mpu_model == omap2430) { + qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk")); + } + qdev_init_nofail(s->gpio); + busdev = sysbus_from_qdev(s->gpio); + sysbus_connect_irq(busdev, 0, + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK1)); + sysbus_connect_irq(busdev, 3, + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK2)); + sysbus_connect_irq(busdev, 6, + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK3)); + sysbus_connect_irq(busdev, 9, + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK4)); + if (s->mpu_model == omap2430) { + sysbus_connect_irq(busdev, 12, + qdev_get_gpio_in(s->ih[0], + OMAP_INT_243X_GPIO_BANK5)); + } + ta = omap_l4ta(s->l4, 3); + sysbus_mmio_map(busdev, 0, omap_l4_region_base(ta, 1)); + sysbus_mmio_map(busdev, 1, omap_l4_region_base(ta, 0)); + sysbus_mmio_map(busdev, 2, omap_l4_region_base(ta, 2)); + sysbus_mmio_map(busdev, 3, omap_l4_region_base(ta, 4)); + sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5)); s->sdrc = omap_sdrc_init(0x68009000); - s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]); + s->gpmc = omap_gpmc_init(s, 0x6800a000, + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPMC_IRQ), + s->drq[OMAP24XX_DMA_GPMC]); dinfo = drive_get(IF_SD, 0, 0); if (!dinfo) { @@ -2394,36 +2432,38 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, exit(1); } s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv, - s->irq[0][OMAP_INT_24XX_MMC_IRQ], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ), &s->drq[OMAP24XX_DMA_MMC1_TX], omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk")); s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4, - s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI1_IRQ), &s->drq[OMAP24XX_DMA_SPI1_TX0], omap_findclk(s, "spi1_fclk"), omap_findclk(s, "spi1_iclk")); s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2, - s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI2_IRQ), &s->drq[OMAP24XX_DMA_SPI2_TX0], omap_findclk(s, "spi2_fclk"), omap_findclk(s, "spi2_iclk")); s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800, /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */ - s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_DSS_IRQ), + s->drq[OMAP24XX_DMA_DSS], omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"), omap_findclk(s, "dss_54m_clk"), omap_findclk(s, "dss_l3_iclk"), omap_findclk(s, "dss_l4_iclk")); omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000, - s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"), + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_STI), + omap_findclk(s, "emul_ck"), serial_hds[0] && serial_hds[1] && serial_hds[2] ? serial_hds[3] : NULL); s->eac = omap_eac_init(omap_l4ta(s->l4, 32), - s->irq[0][OMAP_INT_24XX_EAC_IRQ], + qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_EAC_IRQ), /* Ten consecutive lines */ &s->drq[OMAP24XX_DMA_EAC_AC_RD], omap_findclk(s, "func_96m_clk"), diff --git a/hw/omap_clk.c b/hw/omap_clk.c index 6bcabef..8448006 100644 --- a/hw/omap_clk.c +++ b/hw/omap_clk.c @@ -836,7 +836,7 @@ static struct clk i2c2_iclk = { .parent = &core_l4_iclk, }; -static struct clk gpio_dbclk[4] = { +static struct clk gpio_dbclk[5] = { { .name = "gpio1_dbclk", .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, @@ -853,6 +853,10 @@ static struct clk gpio_dbclk[4] = { .name = "gpio4_dbclk", .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .parent = &wu_32k_clk, + }, { + .name = "gpio5_dbclk", + .flags = CLOCK_IN_OMAP243X, + .parent = &wu_32k_clk, }, }; @@ -1235,7 +1239,7 @@ void omap_clk_init(struct omap_mpu_state_s *mpu) for (i = onchip_clks, count = 0; *i; i ++) if ((*i)->flags & flag) count ++; - mpu->clks = (struct clk *) qemu_mallocz(sizeof(struct clk) * (count + 1)); + mpu->clks = (struct clk *) g_malloc0(sizeof(struct clk) * (count + 1)); for (i = onchip_clks, j = mpu->clks; *i; i ++) if ((*i)->flags & flag) { memcpy(j, *i, sizeof(struct clk)); diff --git a/hw/omap_dma.c b/hw/omap_dma.c index 8e2dcc9..f943d4e 100644 --- a/hw/omap_dma.c +++ b/hw/omap_dma.c @@ -1620,7 +1620,7 @@ struct soc_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs, { int iomemtype, num_irqs, memsize, i; struct omap_dma_s *s = (struct omap_dma_s *) - qemu_mallocz(sizeof(struct omap_dma_s)); + g_malloc0(sizeof(struct omap_dma_s)); if (model <= omap_dma_3_1) { num_irqs = 6; @@ -2039,7 +2039,7 @@ struct soc_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs, { int iomemtype, i; struct omap_dma_s *s = (struct omap_dma_s *) - qemu_mallocz(sizeof(struct omap_dma_s)); + g_malloc0(sizeof(struct omap_dma_s)); s->model = omap_dma_4; s->chans = chans; diff --git a/hw/omap_dss.c b/hw/omap_dss.c index afe287a..b4a8b4c 100644 --- a/hw/omap_dss.c +++ b/hw/omap_dss.c @@ -389,10 +389,11 @@ static void omap_disc_write(void *opaque, target_phys_addr_t addr, s->dig.enable = (value >> 1) & 1; s->lcd.enable = (value >> 0) & 1; if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */ - if (~((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) - fprintf(stderr, "%s: Overlay Optimization when no overlay " - "region effectively exists leads to " - "unpredictable behaviour!\n", __FUNCTION__); + if (!((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) { + fprintf(stderr, "%s: Overlay Optimization when no overlay " + "region effectively exists leads to " + "unpredictable behaviour!\n", __func__); + } if (value & (1 << 6)) { /* GODIGITAL */ /* XXX: Shadowed fields are: * s->dispc.config @@ -627,7 +628,7 @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s) } if (!data) { if (len > bounce_len) { - bounce_buffer = qemu_realloc(bounce_buffer, len); + bounce_buffer = g_realloc(bounce_buffer, len); } data = bounce_buffer; cpu_physical_memory_read(data_addr, data, len); @@ -1030,7 +1031,7 @@ struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta, { int iomemtype[5]; struct omap_dss_s *s = (struct omap_dss_s *) - qemu_mallocz(sizeof(struct omap_dss_s)); + g_malloc0(sizeof(struct omap_dss_s)); s->irq = irq; s->drq = drq; diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c index 478f7d9..30630a8 100644 --- a/hw/omap_gpio.c +++ b/hw/omap_gpio.c @@ -20,10 +20,10 @@ #include "hw.h" #include "omap.h" -/* General-Purpose I/O */ +#include "sysbus.h" + struct omap_gpio_s { qemu_irq irq; - qemu_irq *in; qemu_irq handler[16]; uint16_t inputs; @@ -35,9 +35,17 @@ struct omap_gpio_s { uint16_t pins; }; +struct omap_gpif_s { + SysBusDevice busdev; + int mpu_model; + void *clk; + struct omap_gpio_s omap1; +}; + +/* General-Purpose I/O of OMAP1 */ static void omap_gpio_set(void *opaque, int line, int level) { - struct omap_gpio_s *s = (struct omap_gpio_s *) opaque; + struct omap_gpio_s *s = &((struct omap_gpif_s *) opaque)->omap1; uint16_t prev = s->inputs; if (level) @@ -160,7 +168,7 @@ static CPUWriteMemoryFunc * const omap_gpio_writefn[] = { omap_badwidth_write16, }; -void omap_gpio_reset(struct omap_gpio_s *s) +static void omap_gpio_reset(struct omap_gpio_s *s) { s->inputs = 0; s->outputs = ~0; @@ -171,43 +179,12 @@ void omap_gpio_reset(struct omap_gpio_s *s) s->pins = ~0; } -struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base, - qemu_irq irq, omap_clk clk) -{ - int iomemtype; - struct omap_gpio_s *s = (struct omap_gpio_s *) - qemu_mallocz(sizeof(struct omap_gpio_s)); - - s->irq = irq; - s->in = qemu_allocate_irqs(omap_gpio_set, s, 16); - omap_gpio_reset(s); - - iomemtype = cpu_register_io_memory(omap_gpio_readfn, - omap_gpio_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x1000, iomemtype); - - return s; -} - -qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s) -{ - return s->in; -} - -void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler) -{ - if (line >= 16 || line < 0) - hw_error("%s: No GPIO line %i\n", __FUNCTION__, line); - s->handler[line] = handler; -} - -/* General-Purpose Interface of OMAP2 */ struct omap2_gpio_s { qemu_irq irq[2]; qemu_irq wkup; - qemu_irq *in; - qemu_irq handler[32]; + qemu_irq *handler; + uint8_t revision; uint8_t config[2]; uint32_t inputs; uint32_t outputs; @@ -221,8 +198,21 @@ struct omap2_gpio_s { uint8_t delay; }; +struct omap2_gpif_s { + SysBusDevice busdev; + int mpu_model; + void *iclk; + void *fclk[6]; + int modulecount; + struct omap2_gpio_s *modules; + qemu_irq *handler; + int autoidle; + int gpo; +}; + +/* General-Purpose Interface of OMAP2/3 */ static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s, - int line) + int line) { qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]); } @@ -269,10 +259,12 @@ static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line) omap2_gpio_module_wake(s, line); } -static void omap2_gpio_module_set(void *opaque, int line, int level) +static void omap2_gpio_set(void *opaque, int line, int level) { - struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; + struct omap2_gpif_s *p = opaque; + struct omap2_gpio_s *s = &p->modules[line >> 5]; + line &= 31; if (level) { if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1])) omap2_gpio_module_int(s, line); @@ -308,7 +300,7 @@ static uint32_t omap2_gpio_module_read(void *opaque, target_phys_addr_t addr) switch (addr) { case 0x00: /* GPIO_REVISION */ - return 0x18; + return s->revision; case 0x10: /* GPIO_SYSCONFIG */ return s->config[0]; @@ -518,7 +510,7 @@ static void omap2_gpio_module_write(void *opaque, target_phys_addr_t addr, static uint32_t omap2_gpio_module_readp(void *opaque, target_phys_addr_t addr) { - return omap2_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3); + return omap2_gpio_module_read(opaque, addr & ~3) >> ((addr & 3) << 3); } static void omap2_gpio_module_writep(void *opaque, target_phys_addr_t addr, @@ -583,45 +575,28 @@ static CPUWriteMemoryFunc * const omap2_gpio_module_writefn[] = { omap2_gpio_module_write, }; -static void omap2_gpio_module_init(struct omap2_gpio_s *s, - struct omap_target_agent_s *ta, int region, - qemu_irq mpu, qemu_irq dsp, qemu_irq wkup, - omap_clk fclk, omap_clk iclk) +static void omap_gpif_reset(DeviceState *dev) { - int iomemtype; - - s->irq[0] = mpu; - s->irq[1] = dsp; - s->wkup = wkup; - s->in = qemu_allocate_irqs(omap2_gpio_module_set, s, 32); - - iomemtype = l4_register_io_memory(omap2_gpio_module_readfn, - omap2_gpio_module_writefn, s); - omap_l4_attach(ta, region, iomemtype); + struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s, + sysbus_from_qdev(dev)); + omap_gpio_reset(&s->omap1); } -struct omap_gpif_s { - struct omap2_gpio_s module[5]; - int modules; - - int autoidle; - int gpo; -}; - -void omap_gpif_reset(struct omap_gpif_s *s) +static void omap2_gpif_reset(DeviceState *dev) { int i; - - for (i = 0; i < s->modules; i ++) - omap2_gpio_module_reset(s->module + i); - + struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s, + sysbus_from_qdev(dev)); + for (i = 0; i < s->modulecount; i++) { + omap2_gpio_module_reset(&s->modules[i]); + } s->autoidle = 0; s->gpo = 0; } -static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr) +static uint32_t omap2_gpif_top_read(void *opaque, target_phys_addr_t addr) { - struct omap_gpif_s *s = (struct omap_gpif_s *) opaque; + struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque; switch (addr) { case 0x00: /* IPGENERICOCPSPL_REVISION */ @@ -647,10 +622,10 @@ static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr) return 0; } -static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr, +static void omap2_gpif_top_write(void *opaque, target_phys_addr_t addr, uint32_t value) { - struct omap_gpif_s *s = (struct omap_gpif_s *) opaque; + struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque; switch (addr) { case 0x00: /* IPGENERICOCPSPL_REVISION */ @@ -662,7 +637,7 @@ static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr, case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */ if (value & (1 << 1)) /* SOFTRESET */ - omap_gpif_reset(s); + omap2_gpif_reset(&s->busdev.qdev); s->autoidle = value & 1; break; @@ -676,50 +651,119 @@ static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = { - omap_gpif_top_read, - omap_gpif_top_read, - omap_gpif_top_read, +static CPUReadMemoryFunc * const omap2_gpif_top_readfn[] = { + omap2_gpif_top_read, + omap2_gpif_top_read, + omap2_gpif_top_read, }; -static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = { - omap_gpif_top_write, - omap_gpif_top_write, - omap_gpif_top_write, +static CPUWriteMemoryFunc * const omap2_gpif_top_writefn[] = { + omap2_gpif_top_write, + omap2_gpif_top_write, + omap2_gpif_top_write, }; -struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta, - qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules) +static int omap_gpio_init(SysBusDevice *dev) { - int iomemtype, i; - struct omap_gpif_s *s = (struct omap_gpif_s *) - qemu_mallocz(sizeof(struct omap_gpif_s)); - int region[4] = { 0, 2, 4, 5 }; + struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s, dev); + if (!s->clk) { + hw_error("omap-gpio: clk not connected\n"); + } + qdev_init_gpio_in(&dev->qdev, omap_gpio_set, 16); + qdev_init_gpio_out(&dev->qdev, s->omap1.handler, 16); + sysbus_init_irq(dev, &s->omap1.irq); + sysbus_init_mmio(dev, 0x1000, + cpu_register_io_memory(omap_gpio_readfn, + omap_gpio_writefn, + &s->omap1, + DEVICE_NATIVE_ENDIAN)); + return 0; +} - s->modules = modules; - for (i = 0; i < modules; i ++) - omap2_gpio_module_init(s->module + i, ta, region[i], - irq[i], NULL, NULL, fclk[i], iclk); +static int omap2_gpio_init(SysBusDevice *dev) +{ + int i; + struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s, dev); + if (!s->iclk) { + hw_error("omap2-gpio: iclk not connected\n"); + } + if (s->mpu_model < omap3430) { + s->modulecount = (s->mpu_model < omap2430) ? 4 : 5; + sysbus_init_mmio(dev, 0x1000, + cpu_register_io_memory(omap2_gpif_top_readfn, + omap2_gpif_top_writefn, s, + DEVICE_NATIVE_ENDIAN)); + } else { + s->modulecount = 6; + } + s->modules = g_malloc0(s->modulecount * sizeof(struct omap2_gpio_s)); + s->handler = g_malloc0(s->modulecount * 32 * sizeof(qemu_irq)); + qdev_init_gpio_in(&dev->qdev, omap2_gpio_set, s->modulecount * 32); + qdev_init_gpio_out(&dev->qdev, s->handler, s->modulecount * 32); + for (i = 0; i < s->modulecount; i++) { + struct omap2_gpio_s *m = &s->modules[i]; + if (!s->fclk[i]) { + hw_error("omap2-gpio: fclk%d not connected\n", i); + } + m->revision = (s->mpu_model < omap3430) ? 0x18 : 0x25; + m->handler = &s->handler[i * 32]; + sysbus_init_irq(dev, &m->irq[0]); /* mpu irq */ + sysbus_init_irq(dev, &m->irq[1]); /* dsp irq */ + sysbus_init_irq(dev, &m->wkup); + sysbus_init_mmio(dev, 0x1000, + cpu_register_io_memory(omap2_gpio_module_readfn, + omap2_gpio_module_writefn, + m, DEVICE_NATIVE_ENDIAN)); + } + return 0; +} - omap_gpif_reset(s); +/* Using qdev pointer properties for the clocks is not ideal. + * qdev should support a generic means of defining a 'port' with + * an arbitrary interface for connecting two devices. Then we + * could reframe the omap clock API in terms of clock ports, + * and get some type safety. For now the best qdev provides is + * passing an arbitrary pointer. + * (It's not possible to pass in the string which is the clock + * name, because this device does not have the necessary information + * (ie the struct omap_mpu_state_s*) to do the clockname to pointer + * translation.) + */ - iomemtype = l4_register_io_memory(omap_gpif_top_readfn, - omap_gpif_top_writefn, s); - omap_l4_attach(ta, 1, iomemtype); +static SysBusDeviceInfo omap_gpio_info = { + .init = omap_gpio_init, + .qdev.name = "omap-gpio", + .qdev.size = sizeof(struct omap_gpif_s), + .qdev.reset = omap_gpif_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0), + DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk), + DEFINE_PROP_END_OF_LIST() + } +}; - return s; -} +static SysBusDeviceInfo omap2_gpio_info = { + .init = omap2_gpio_init, + .qdev.name = "omap2-gpio", + .qdev.size = sizeof(struct omap2_gpif_s), + .qdev.reset = omap2_gpif_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0), + DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk), + DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]), + DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]), + DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]), + DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]), + DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]), + DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]), + DEFINE_PROP_END_OF_LIST() + } +}; -qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start) +static void omap_gpio_register_device(void) { - if (start >= s->modules * 32 || start < 0) - hw_error("%s: No GPIO line %i\n", __FUNCTION__, start); - return s->module[start >> 5].in + (start & 31); + sysbus_register_withprop(&omap_gpio_info); + sysbus_register_withprop(&omap2_gpio_info); } -void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler) -{ - if (line >= s->modules * 32 || line < 0) - hw_error("%s: No GPIO line %i\n", __FUNCTION__, line); - s->module[line >> 5].handler[line & 31] = handler; -} +device_init(omap_gpio_register_device) diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c index 8bf3343..414f9f5 100644 --- a/hw/omap_gpmc.c +++ b/hw/omap_gpmc.c @@ -21,77 +21,418 @@ #include "hw.h" #include "flash.h" #include "omap.h" +#include "memory.h" +#include "exec-memory.h" /* General-Purpose Memory Controller */ struct omap_gpmc_s { qemu_irq irq; + qemu_irq drq; + MemoryRegion iomem; + int accept_256; + uint8_t revision; uint8_t sysconfig; uint16_t irqst; uint16_t irqen; + uint16_t lastirq; uint16_t timeout; uint16_t config; - uint32_t prefconfig[2]; - int prefcontrol; - int preffifo; - int prefcount; struct omap_gpmc_cs_file_s { uint32_t config[7]; - target_phys_addr_t base; - size_t size; - int iomemtype; - void (*base_update)(void *opaque, target_phys_addr_t new); - void (*unmap)(void *opaque); - void *opaque; + MemoryRegion *iomem; + MemoryRegion container; + MemoryRegion nandiomem; + DeviceState *dev; } cs_file[8]; int ecc_cs; int ecc_ptr; uint32_t ecc_cfg; ECCState ecc[9]; + struct prefetch { + uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */ + uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */ + int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */ + int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */ + int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */ + MemoryRegion iomem; + uint8_t fifo[64]; + } prefetch; }; +#define OMAP_GPMC_8BIT 0 +#define OMAP_GPMC_16BIT 1 +#define OMAP_GPMC_NOR 0 +#define OMAP_GPMC_NAND 2 + +static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f) +{ + return (f->config[0] >> 10) & 3; +} + +static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f) +{ + /* devsize field is really 2 bits but we ignore the high + * bit to ensure consistent behaviour if the guest sets + * it (values 2 and 3 are reserved in the TRM) + */ + return (f->config[0] >> 12) & 1; +} + +/* Extract the chip-select value from the prefetch config1 register */ +static int prefetch_cs(uint32_t config1) +{ + return (config1 >> 24) & 7; +} + +static int prefetch_threshold(uint32_t config1) +{ + return (config1 >> 8) & 0x7f; +} + static void omap_gpmc_int_update(struct omap_gpmc_s *s) { - qemu_set_irq(s->irq, s->irqen & s->irqst); + /* The TRM is a bit unclear, but it seems to say that + * the TERMINALCOUNTSTATUS bit is set only on the + * transition when the prefetch engine goes from + * active to inactive, whereas the FIFOEVENTSTATUS + * bit is held high as long as the fifo has at + * least THRESHOLD bytes available. + * So we do the latter here, but TERMINALCOUNTSTATUS + * is set elsewhere. + */ + if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) { + s->irqst |= 1; + } + if ((s->irqen & s->irqst) != s->lastirq) { + s->lastirq = s->irqen & s->irqst; + qemu_set_irq(s->irq, s->lastirq); + } } -static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask) +static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value) { - /* TODO: check for overlapping regions and report access errors */ - if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) || - (base < 0 || base >= 0x40) || - (base & 0x0f & ~mask)) { - fprintf(stderr, "%s: wrong cs address mapping/decoding!\n", - __FUNCTION__); + if (s->prefetch.config1 & 4) { + qemu_set_irq(s->drq, value); + } +} + +/* Access functions for when a NAND-like device is mapped into memory: + * all addresses in the region behave like accesses to the relevant + * GPMC_NAND_DATA_i register (which is actually implemented to call these) + */ +static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque; + uint64_t v; + nand_setpins(f->dev, 0, 0, 0, 1, 0); + switch (omap_gpmc_devsize(f)) { + case OMAP_GPMC_8BIT: + v = nand_getio(f->dev); + if (size == 1) { + return v; + } + v |= (nand_getio(f->dev) << 8); + if (size == 2) { + return v; + } + v |= (nand_getio(f->dev) << 16); + v |= (nand_getio(f->dev) << 24); + return v; + case OMAP_GPMC_16BIT: + v = nand_getio(f->dev); + if (size == 1) { + /* 8 bit read from 16 bit device : probably a guest bug */ + return v & 0xff; + } + if (size == 2) { + return v; + } + v |= (nand_getio(f->dev) << 16); + return v; + default: + abort(); + } +} + +static void omap_nand_setio(DeviceState *dev, uint64_t value, + int nandsize, int size) +{ + /* Write the specified value to the NAND device, respecting + * both size of the NAND device and size of the write access. + */ + switch (nandsize) { + case OMAP_GPMC_8BIT: + switch (size) { + case 1: + nand_setio(dev, value & 0xff); + break; + case 2: + nand_setio(dev, value & 0xff); + nand_setio(dev, (value >> 8) & 0xff); + break; + case 4: + default: + nand_setio(dev, value & 0xff); + nand_setio(dev, (value >> 8) & 0xff); + nand_setio(dev, (value >> 16) & 0xff); + nand_setio(dev, (value >> 24) & 0xff); + break; + } + break; + case OMAP_GPMC_16BIT: + switch (size) { + case 1: + /* writing to a 16bit device with 8bit access is probably a guest + * bug; pass the value through anyway. + */ + case 2: + nand_setio(dev, value & 0xffff); + break; + case 4: + default: + nand_setio(dev, value & 0xffff); + nand_setio(dev, (value >> 16) & 0xffff); + break; + } + break; + } +} + +static void omap_nand_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) +{ + struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque; + nand_setpins(f->dev, 0, 0, 0, 1, 0); + omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size); +} + +static const MemoryRegionOps omap_nand_ops = { + .read = omap_nand_read, + .write = omap_nand_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void fill_prefetch_fifo(struct omap_gpmc_s *s) +{ + /* Fill the prefetch FIFO by reading data from NAND. + * We do this synchronously, unlike the hardware which + * will do this asynchronously. We refill when the + * FIFO has THRESHOLD bytes free, and we always refill + * as much data as possible starting at the top end + * of the FIFO. + * (We have to refill at THRESHOLD rather than waiting + * for the FIFO to empty to allow for the case where + * the FIFO size isn't an exact multiple of THRESHOLD + * and we're doing DMA transfers.) + * This means we never need to handle wrap-around in + * the fifo-reading code, and the next byte of data + * to read is always fifo[63 - fifopointer]. + */ + int fptr; + int cs = prefetch_cs(s->prefetch.config1); + int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0); + int bytes; + /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE + * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND. + * Instead believe the bit that says it is always a byte count. + */ + bytes = 64 - s->prefetch.fifopointer; + if (bytes > s->prefetch.count) { + bytes = s->prefetch.count; + } + s->prefetch.count -= bytes; + s->prefetch.fifopointer += bytes; + fptr = 64 - s->prefetch.fifopointer; + /* Move the existing data in the FIFO so it sits just + * before what we're about to read in + */ + while (fptr < (64 - bytes)) { + s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes]; + fptr++; + } + while (fptr < 64) { + if (is16bit) { + uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2); + s->prefetch.fifo[fptr++] = v & 0xff; + s->prefetch.fifo[fptr++] = (v >> 8) & 0xff; + } else { + s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1); + } + } + if (s->prefetch.startengine && (s->prefetch.count == 0)) { + /* This was the final transfer: raise TERMINALCOUNTSTATUS */ + s->irqst |= 2; + s->prefetch.startengine = 0; + } + /* If there are any bytes in the FIFO at this point then + * we must raise a DMA request (either this is a final part + * transfer, or we filled the FIFO in which case we certainly + * have THRESHOLD bytes available) + */ + if (s->prefetch.fifopointer != 0) { + omap_gpmc_dma_update(s, 1); + } + omap_gpmc_int_update(s); +} + +/* Access functions for a NAND-like device when the prefetch/postwrite + * engine is enabled -- all addresses in the region behave alike: + * data is read or written to the FIFO. + */ +static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; + uint32_t data; + if (s->prefetch.config1 & 1) { + /* The TRM doesn't define the behaviour if you read from the + * FIFO when the prefetch engine is in write mode. We choose + * to always return zero. + */ + return 0; + } + /* Note that trying to read an empty fifo repeats the last byte */ + if (s->prefetch.fifopointer) { + s->prefetch.fifopointer--; + } + data = s->prefetch.fifo[63 - s->prefetch.fifopointer]; + if (s->prefetch.fifopointer == + (64 - prefetch_threshold(s->prefetch.config1))) { + /* We've drained THRESHOLD bytes now. So deassert the + * DMA request, then refill the FIFO (which will probably + * assert it again.) + */ + omap_gpmc_dma_update(s, 0); + fill_prefetch_fifo(s); + } + omap_gpmc_int_update(s); + return data; +} + +static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) +{ + struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; + int cs = prefetch_cs(s->prefetch.config1); + if ((s->prefetch.config1 & 1) == 0) { + /* The TRM doesn't define the behaviour of writing to the + * FIFO when the prefetch engine is in read mode. We + * choose to ignore the write. + */ + return; + } + if (s->prefetch.count == 0) { + /* The TRM doesn't define the behaviour of writing to the + * FIFO if the transfer is complete. We choose to ignore. + */ return; } + /* The only reason we do any data buffering in postwrite + * mode is if we are talking to a 16 bit NAND device, in + * which case we need to buffer the first byte of the + * 16 bit word until the other byte arrives. + */ + int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0); + if (is16bit) { + /* fifopointer alternates between 64 (waiting for first + * byte of word) and 63 (waiting for second byte) + */ + if (s->prefetch.fifopointer == 64) { + s->prefetch.fifo[0] = value; + s->prefetch.fifopointer--; + } else { + value = (value << 8) | s->prefetch.fifo[0]; + omap_nand_write(&s->cs_file[cs], 0, value, 2); + s->prefetch.count--; + s->prefetch.fifopointer = 64; + } + } else { + /* Just write the byte : fifopointer remains 64 at all times */ + omap_nand_write(&s->cs_file[cs], 0, value, 1); + s->prefetch.count--; + } + if (s->prefetch.count == 0) { + /* Final transfer: raise TERMINALCOUNTSTATUS */ + s->irqst |= 2; + s->prefetch.startengine = 0; + } + omap_gpmc_int_update(s); +} + +static const MemoryRegionOps omap_prefetch_ops = { + .read = omap_gpmc_prefetch_read, + .write = omap_gpmc_prefetch_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl.min_access_size = 1, + .impl.max_access_size = 1, +}; + +static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs) +{ + /* Return the MemoryRegion* to map/unmap for this chipselect */ + struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; + if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) { + return f->iomem; + } + if ((s->prefetch.config1 & 0x80) && + (prefetch_cs(s->prefetch.config1) == cs)) { + /* The prefetch engine is enabled for this CS: map the FIFO */ + return &s->prefetch.iomem; + } + return &f->nandiomem; +} - if (!f->opaque) +static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs) +{ + struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; + uint32_t mask = (f->config[6] >> 8) & 0xf; + uint32_t base = f->config[6] & 0x3f; + uint32_t size; + + if (!f->iomem && !f->dev) { + return; + } + + if (!(f->config[6] & (1 << 6))) { + /* Do nothing unless CSVALID */ return; + } - f->base = base << 24; - f->size = (0x0fffffff & ~(mask << 24)) + 1; + /* TODO: check for overlapping regions and report access errors */ + if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf + && !(s->accept_256 && !mask)) { + fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n", + __func__, mask); + } + + base <<= 24; + size = (0x0fffffff & ~(mask << 24)) + 1; /* TODO: rather than setting the size of the mapping (which should be * constant), the mask should cause wrapping of the address space, so * that the same memory becomes accessible at every size bytes * starting from base. */ - if (f->iomemtype) - cpu_register_physical_memory(f->base, f->size, f->iomemtype); - - if (f->base_update) - f->base_update(f->opaque, f->base); + memory_region_init(&f->container, "omap-gpmc-file", size); + memory_region_add_subregion(&f->container, 0, + omap_gpmc_cs_memregion(s, cs)); + memory_region_add_subregion(get_system_memory(), base, + &f->container); } -static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f) +static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs) { - if (f->size) { - if (f->unmap) - f->unmap(f->opaque); - if (f->iomemtype) - cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED); - f->base = 0; - f->size = 0; + struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; + if (!(f->config[6] & (1 << 6))) { + /* Do nothing unless CSVALID */ + return; } + if (!f->iomem && !f->dev) { + return; + } + memory_region_del_subregion(get_system_memory(), &f->container); + memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs)); + memory_region_destroy(&f->container); } void omap_gpmc_reset(struct omap_gpmc_s *s) @@ -104,27 +445,33 @@ void omap_gpmc_reset(struct omap_gpmc_s *s) omap_gpmc_int_update(s); s->timeout = 0; s->config = 0xa00; - s->prefconfig[0] = 0x00004000; - s->prefconfig[1] = 0x00000000; - s->prefcontrol = 0; - s->preffifo = 0; - s->prefcount = 0; + s->prefetch.config1 = 0x00004000; + s->prefetch.transfercount = 0x00000000; + s->prefetch.startengine = 0; + s->prefetch.fifopointer = 0; + s->prefetch.count = 0; for (i = 0; i < 8; i ++) { - if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_unmap(s->cs_file + i); - s->cs_file[i].config[0] = i ? 1 << 12 : 0; + omap_gpmc_cs_unmap(s, i); s->cs_file[i].config[1] = 0x101001; s->cs_file[i].config[2] = 0x020201; s->cs_file[i].config[3] = 0x10031003; s->cs_file[i].config[4] = 0x10f1111; s->cs_file[i].config[5] = 0; s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6); - if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_map(&s->cs_file[i], - s->cs_file[i].config[6] & 0x1f, /* MASKADDR */ - (s->cs_file[i].config[6] >> 8 & 0xf)); /* BASEADDR */ + + s->cs_file[i].config[6] = 0xf00; + /* In theory we could probe attached devices for some CFG1 + * bits here, but we just retain them across resets as they + * were set initially by omap_gpmc_attach(). + */ + if (i == 0) { + s->cs_file[i].config[0] &= 0x00433e00; + s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */ + omap_gpmc_cs_map(s, i); + } else { + s->cs_file[i].config[0] &= 0x00403c00; + } } - omap_gpmc_cs_map(s->cs_file, 0, 0xf); s->ecc_cs = 0; s->ecc_ptr = 0; s->ecc_cfg = 0x3fcff000; @@ -132,15 +479,38 @@ void omap_gpmc_reset(struct omap_gpmc_s *s) ecc_reset(&s->ecc[i]); } -static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr) +static int gpmc_wordaccess_only(target_phys_addr_t addr) +{ + /* Return true if the register offset is to a register that + * only permits word width accesses. + * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND + * for any chipselect. + */ + if (addr >= 0x60 && addr <= 0x1d4) { + int cs = (addr - 0x60) / 0x30; + addr -= cs * 0x30; + if (addr >= 0x7c && addr < 0x88) { + /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */ + return 0; + } + } + return 1; +} + +static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; int cs; struct omap_gpmc_cs_file_s *f; + if (size != 4 && gpmc_wordaccess_only(addr)) { + return omap_badwidth_read32(opaque, addr); + } + switch (addr) { case 0x000: /* GPMC_REVISION */ - return 0x20; + return s->revision; case 0x010: /* GPMC_SYSCONFIG */ return s->sysconfig; @@ -172,36 +542,46 @@ static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr) addr -= cs * 0x30; f = s->cs_file + cs; switch (addr) { - case 0x60: /* GPMC_CONFIG1 */ - return f->config[0]; - case 0x64: /* GPMC_CONFIG2 */ - return f->config[1]; - case 0x68: /* GPMC_CONFIG3 */ - return f->config[2]; - case 0x6c: /* GPMC_CONFIG4 */ - return f->config[3]; - case 0x70: /* GPMC_CONFIG5 */ - return f->config[4]; - case 0x74: /* GPMC_CONFIG6 */ - return f->config[5]; - case 0x78: /* GPMC_CONFIG7 */ - return f->config[6]; - case 0x84: /* GPMC_NAND_DATA */ - return 0; + case 0x60: /* GPMC_CONFIG1 */ + return f->config[0]; + case 0x64: /* GPMC_CONFIG2 */ + return f->config[1]; + case 0x68: /* GPMC_CONFIG3 */ + return f->config[2]; + case 0x6c: /* GPMC_CONFIG4 */ + return f->config[3]; + case 0x70: /* GPMC_CONFIG5 */ + return f->config[4]; + case 0x74: /* GPMC_CONFIG6 */ + return f->config[5]; + case 0x78: /* GPMC_CONFIG7 */ + return f->config[6]; + case 0x84 ... 0x87: /* GPMC_NAND_DATA */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + return omap_nand_read(f, 0, size); + } + return 0; } break; case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */ - return s->prefconfig[0]; + return s->prefetch.config1; case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */ - return s->prefconfig[1]; + return s->prefetch.transfercount; case 0x1ec: /* GPMC_PREFETCH_CONTROL */ - return s->prefcontrol; + return s->prefetch.startengine; case 0x1f0: /* GPMC_PREFETCH_STATUS */ - return (s->preffifo << 24) | - ((s->preffifo > - ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) | - s->prefcount; + /* NB: The OMAP3 TRM is inconsistent about whether the GPMC + * FIFOTHRESHOLDSTATUS bit should be set when + * FIFOPOINTER > FIFOTHRESHOLD or when it is >= FIFOTHRESHOLD. + * Apparently the underlying functional spec from which the TRM was + * created states that the behaviour is ">=", and this also + * makes more conceptual sense. + */ + return (s->prefetch.fifopointer << 24) | + ((s->prefetch.fifopointer >= + ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) | + s->prefetch.count; case 0x1f4: /* GPMC_ECC_CONFIG */ return s->ecc_cs; @@ -230,12 +610,16 @@ static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr) } static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; int cs; struct omap_gpmc_cs_file_s *f; + if (size != 4 && gpmc_wordaccess_only(addr)) { + return omap_badwidth_write32(opaque, addr, value); + } + switch (addr) { case 0x000: /* GPMC_REVISION */ case 0x014: /* GPMC_SYSSTATUS */ @@ -249,7 +633,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, case 0x010: /* GPMC_SYSCONFIG */ if ((value >> 3) == 0x3) - fprintf(stderr, "%s: bad SDRAM idle mode %i\n", + fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n", __FUNCTION__, value >> 3); if (value & 2) omap_gpmc_reset(s); @@ -257,7 +641,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, break; case 0x018: /* GPMC_IRQSTATUS */ - s->irqen = ~value; + s->irqst &= ~value; omap_gpmc_int_update(s); break; @@ -283,62 +667,109 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, addr -= cs * 0x30; f = s->cs_file + cs; switch (addr) { - case 0x60: /* GPMC_CONFIG1 */ - f->config[0] = value & 0xffef3e13; - break; - case 0x64: /* GPMC_CONFIG2 */ - f->config[1] = value & 0x001f1f8f; - break; - case 0x68: /* GPMC_CONFIG3 */ - f->config[2] = value & 0x001f1f8f; - break; - case 0x6c: /* GPMC_CONFIG4 */ - f->config[3] = value & 0x1f8f1f8f; - break; - case 0x70: /* GPMC_CONFIG5 */ - f->config[4] = value & 0x0f1f1f1f; - break; - case 0x74: /* GPMC_CONFIG6 */ - f->config[5] = value & 0x00000fcf; - break; - case 0x78: /* GPMC_CONFIG7 */ - if ((f->config[6] ^ value) & 0xf7f) { - if (f->config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_unmap(f); - if (value & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_map(f, value & 0x1f, /* MASKADDR */ - (value >> 8 & 0xf)); /* BASEADDR */ - } + case 0x60: /* GPMC_CONFIG1 */ + f->config[0] = value & 0xffef3e13; + break; + case 0x64: /* GPMC_CONFIG2 */ + f->config[1] = value & 0x001f1f8f; + break; + case 0x68: /* GPMC_CONFIG3 */ + f->config[2] = value & 0x001f1f8f; + break; + case 0x6c: /* GPMC_CONFIG4 */ + f->config[3] = value & 0x1f8f1f8f; + break; + case 0x70: /* GPMC_CONFIG5 */ + f->config[4] = value & 0x0f1f1f1f; + break; + case 0x74: /* GPMC_CONFIG6 */ + f->config[5] = value & 0x00000fcf; + break; + case 0x78: /* GPMC_CONFIG7 */ + if ((f->config[6] ^ value) & 0xf7f) { + omap_gpmc_cs_unmap(s, cs); f->config[6] = value & 0x00000f7f; - break; - case 0x7c: /* GPMC_NAND_COMMAND */ - case 0x80: /* GPMC_NAND_ADDRESS */ - case 0x84: /* GPMC_NAND_DATA */ - break; - - default: - goto bad_reg; + omap_gpmc_cs_map(s, cs); + } + break; + case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */ + omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size); + } + break; + case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */ + omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size); + } + break; + case 0x84 ... 0x87: /* GPMC_NAND_DATA */ + if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) { + omap_nand_write(f, 0, value, size); + } + break; + default: + goto bad_reg; } break; case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */ - s->prefconfig[0] = value & 0x7f8f7fbf; - /* TODO: update interrupts, fifos, dmas */ + if (!s->prefetch.startengine) { + uint32_t oldconfig1 = s->prefetch.config1; + uint32_t changed; + s->prefetch.config1 = value & 0x7f8f7fbf; + changed = oldconfig1 ^ s->prefetch.config1; + if (changed & (0x80 | 0x7000000)) { + /* Turning the engine on or off, or mapping it somewhere else. + * cs_map() and cs_unmap() check the prefetch config and + * overall CSVALID bits, so it is sufficient to unmap-and-map + * both the old cs and the new one. + */ + int oldcs = prefetch_cs(oldconfig1); + int newcs = prefetch_cs(s->prefetch.config1); + omap_gpmc_cs_unmap(s, oldcs); + omap_gpmc_cs_map(s, oldcs); + if (newcs != oldcs) { + omap_gpmc_cs_unmap(s, newcs); + omap_gpmc_cs_map(s, newcs); + } + } + } break; case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */ - s->prefconfig[1] = value & 0x3fff; + if (!s->prefetch.startengine) { + s->prefetch.transfercount = value & 0x3fff; + } break; case 0x1ec: /* GPMC_PREFETCH_CONTROL */ - s->prefcontrol = value & 1; - if (s->prefcontrol) { - if (s->prefconfig[0] & 1) - s->preffifo = 0x40; - else - s->preffifo = 0x00; + if (s->prefetch.startengine != (value & 1)) { + s->prefetch.startengine = value & 1; + if (s->prefetch.startengine) { + /* Prefetch engine start */ + s->prefetch.count = s->prefetch.transfercount; + if (s->prefetch.config1 & 1) { + /* Write */ + s->prefetch.fifopointer = 64; + } else { + /* Read */ + s->prefetch.fifopointer = 0; + fill_prefetch_fifo(s); + } + } else { + /* Prefetch engine forcibly stopped. The TRM + * doesn't define the behaviour if you do this. + * We clear the prefetch count, which means that + * we permit no more writes, and don't read any + * more data from NAND. The CPU can still drain + * the FIFO of unread data. + */ + s->prefetch.count = 0; + } + omap_gpmc_int_update(s); } - /* TODO: start */ break; case 0x1f4: /* GPMC_ECC_CONFIG */ @@ -369,38 +800,53 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const omap_gpmc_readfn[] = { - omap_badwidth_read32, /* TODO */ - omap_badwidth_read32, /* TODO */ - omap_gpmc_read, +static const MemoryRegionOps omap_gpmc_ops = { + .read = omap_gpmc_read, + .write = omap_gpmc_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const omap_gpmc_writefn[] = { - omap_badwidth_write32, /* TODO */ - omap_badwidth_write32, /* TODO */ - omap_gpmc_write, -}; - -struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq) +struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu, + target_phys_addr_t base, + qemu_irq irq, qemu_irq drq) { - int iomemtype; + int cs; struct omap_gpmc_s *s = (struct omap_gpmc_s *) - qemu_mallocz(sizeof(struct omap_gpmc_s)); + g_malloc0(sizeof(struct omap_gpmc_s)); + + memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000); + memory_region_add_subregion(get_system_memory(), base, &s->iomem); + s->irq = irq; + s->drq = drq; + s->accept_256 = cpu_is_omap3630(mpu); + s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20; + s->lastirq = 0; omap_gpmc_reset(s); - iomemtype = cpu_register_io_memory(omap_gpmc_readfn, - omap_gpmc_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x1000, iomemtype); + /* We have to register a different IO memory handler for each + * chip select region in case a NAND device is mapped there. We + * make the region the worst-case size of 256MB and rely on the + * container memory region in cs_map to chop it down to the actual + * guest-requested size. + */ + for (cs = 0; cs < 8; cs++) { + memory_region_init_io(&s->cs_file[cs].nandiomem, + &omap_nand_ops, + &s->cs_file[cs], + "omap-nand", + 256 * 1024 * 1024); + } + memory_region_init_io(&s->prefetch.iomem, &omap_prefetch_ops, s, + "omap-gpmc-prefetch", 256 * 1024 * 1024); return s; } -void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype, - void (*base_upd)(void *opaque, target_phys_addr_t new), - void (*unmap)(void *opaque), void *opaque) +void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem) { struct omap_gpmc_cs_file_s *f; + assert(iomem); if (cs < 0 || cs >= 8) { fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs); @@ -408,12 +854,29 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype, } f = &s->cs_file[cs]; - f->iomemtype = iomemtype; - f->base_update = base_upd; - f->unmap = unmap; - f->opaque = opaque; + omap_gpmc_cs_unmap(s, cs); + f->config[0] &= ~(0xf << 10); + f->iomem = iomem; + omap_gpmc_cs_map(s, cs); +} - if (f->config[6] & (1 << 6)) /* CSVALID */ - omap_gpmc_cs_map(f, f->config[6] & 0x1f, /* MASKADDR */ - (f->config[6] >> 8 & 0xf)); /* BASEADDR */ +void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand) +{ + struct omap_gpmc_cs_file_s *f; + assert(nand); + + if (cs < 0 || cs >= 8) { + fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs); + exit(-1); + } + f = &s->cs_file[cs]; + + omap_gpmc_cs_unmap(s, cs); + f->config[0] &= ~(0xf << 10); + f->config[0] |= (OMAP_GPMC_NAND << 10); + f->dev = nand; + if (nand_getbuswidth(f->dev) == 16) { + f->config[0] |= OMAP_GPMC_16BIT << 12; + } + omap_gpmc_cs_map(s, cs); } diff --git a/hw/omap_gptimer.c b/hw/omap_gptimer.c index 9c0f9f2..704b000 100644 --- a/hw/omap_gptimer.c +++ b/hw/omap_gptimer.c @@ -102,7 +102,7 @@ static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer) uint64_t distance; if (timer->st && timer->rate) { - distance = qemu_get_clock(vm_clock) - timer->time; + distance = qemu_get_clock_ns(vm_clock) - timer->time; distance = muldiv64(distance, timer->rate, timer->ticks_per_sec); if (distance >= 0xffffffff - timer->val) @@ -117,7 +117,7 @@ static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer) { if (timer->st) { timer->val = omap_gp_timer_read(timer); - timer->time = qemu_get_clock(vm_clock); + timer->time = qemu_get_clock_ns(vm_clock); } } @@ -163,7 +163,7 @@ static void omap_gp_timer_tick(void *opaque) timer->val = 0; } else { timer->val = timer->load_val; - timer->time = qemu_get_clock(vm_clock); + timer->time = qemu_get_clock_ns(vm_clock); } if (timer->trigger == gpt_trigger_overflow || @@ -411,7 +411,7 @@ static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr, break; case 0x28: /* TCRR */ - s->time = qemu_get_clock(vm_clock); + s->time = qemu_get_clock_ns(vm_clock); s->val = value; omap_gp_timer_update(s); break; @@ -421,7 +421,7 @@ static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr, break; case 0x30: /* TTGR */ - s->time = qemu_get_clock(vm_clock); + s->time = qemu_get_clock_ns(vm_clock); s->val = s->load_val; omap_gp_timer_update(s); break; @@ -465,13 +465,13 @@ struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta, { int iomemtype; struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) - qemu_mallocz(sizeof(struct omap_gp_timer_s)); + g_malloc0(sizeof(struct omap_gp_timer_s)); s->ta = ta; s->irq = irq; s->clk = fclk; - s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s); - s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s); + s->timer = qemu_new_timer_ns(vm_clock, omap_gp_timer_tick, s); + s->match = qemu_new_timer_ns(vm_clock, omap_gp_timer_match, s); s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0]; omap_gp_timer_reset(s); omap_gp_timer_clk_setup(s); diff --git a/hw/omap_i2c.c b/hw/omap_i2c.c index 5cabb5a..11577b1 100644 --- a/hw/omap_i2c.c +++ b/hw/omap_i2c.c @@ -426,7 +426,7 @@ struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base, { int iomemtype; struct omap_i2c_s *s = (struct omap_i2c_s *) - qemu_mallocz(sizeof(struct omap_i2c_s)); + g_malloc0(sizeof(struct omap_i2c_s)); /* TODO: set a value greater or equal to real hardware */ s->revision = 0x11; @@ -448,7 +448,7 @@ struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta, { int iomemtype; struct omap_i2c_s *s = (struct omap_i2c_s *) - qemu_mallocz(sizeof(struct omap_i2c_s)); + g_malloc0(sizeof(struct omap_i2c_s)); s->revision = 0x34; s->irq = irq; diff --git a/hw/omap_intc.c b/hw/omap_intc.c index 001e20b..45efa25 100644 --- a/hw/omap_intc.c +++ b/hw/omap_intc.c @@ -19,6 +19,7 @@ */ #include "hw.h" #include "omap.h" +#include "sysbus.h" /* Interrupt Handlers */ struct omap_intr_handler_bank_s { @@ -32,24 +33,26 @@ struct omap_intr_handler_bank_s { }; struct omap_intr_handler_s { + SysBusDevice busdev; qemu_irq *pins; qemu_irq parent_intr[2]; + MemoryRegion mmio; + void *iclk; + void *fclk; unsigned char nbanks; int level_only; + uint32_t size; + + uint8_t revision; /* state */ uint32_t new_agr[2]; int sir_intr[2]; int autoidle; uint32_t mask; - struct omap_intr_handler_bank_s bank[]; + struct omap_intr_handler_bank_s bank[3]; }; -inline qemu_irq omap_inth_get_pin(struct omap_intr_handler_s *s, int n) -{ - return s->pins[n]; -} - static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq) { int i, j, sir_intr, p_intr, p, f; @@ -142,7 +145,8 @@ static void omap_set_intr_noedge(void *opaque, int irq, int req) bank->irqs = (bank->inputs &= ~(1 << n)) | bank->swi; } -static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) +static uint64_t omap_inth_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; int i, offset = addr; @@ -220,7 +224,7 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) } static void omap_inth_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; int i, offset = addr; @@ -312,20 +316,20 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, OMAP_BAD_REG(addr); } -static CPUReadMemoryFunc * const omap_inth_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap_inth_read, +static const MemoryRegionOps omap_inth_mem_ops = { + .read = omap_inth_read, + .write = omap_inth_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; -static CPUWriteMemoryFunc * const omap_inth_writefn[] = { - omap_inth_write, - omap_inth_write, - omap_inth_write, -}; - -void omap_inth_reset(struct omap_intr_handler_s *s) +static void omap_inth_reset(DeviceState *dev) { + struct omap_intr_handler_s *s = FROM_SYSBUS(struct omap_intr_handler_s, + sysbus_from_qdev(dev)); int i; for (i = 0; i < s->nbanks; ++i){ @@ -352,32 +356,37 @@ void omap_inth_reset(struct omap_intr_handler_s *s) qemu_set_irq(s->parent_intr[1], 0); } -struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, - unsigned long size, unsigned char nbanks, qemu_irq **pins, - qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk) +static int omap_intc_init(SysBusDevice *dev) { - int iomemtype; - struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) - qemu_mallocz(sizeof(struct omap_intr_handler_s) + - sizeof(struct omap_intr_handler_bank_s) * nbanks); - - s->parent_intr[0] = parent_irq; - s->parent_intr[1] = parent_fiq; - s->nbanks = nbanks; - s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32); - if (pins) - *pins = s->pins; - - omap_inth_reset(s); - - iomemtype = cpu_register_io_memory(omap_inth_readfn, - omap_inth_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, size, iomemtype); - - return s; + struct omap_intr_handler_s *s; + s = FROM_SYSBUS(struct omap_intr_handler_s, dev); + if (!s->iclk) { + hw_error("omap-intc: clk not connected\n"); + } + s->nbanks = 1; + sysbus_init_irq(dev, &s->parent_intr[0]); + sysbus_init_irq(dev, &s->parent_intr[1]); + qdev_init_gpio_in(&dev->qdev, omap_set_intr, s->nbanks * 32); + memory_region_init_io(&s->mmio, &omap_inth_mem_ops, s, + "omap-intc", s->size); + sysbus_init_mmio_region(dev, &s->mmio); + return 0; } -static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr) +static SysBusDeviceInfo omap_intc_info = { + .init = omap_intc_init, + .qdev.name = "omap-intc", + .qdev.size = sizeof(struct omap_intr_handler_s), + .qdev.reset = omap_inth_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100), + DEFINE_PROP_PTR("clk", struct omap_intr_handler_s, iclk), + DEFINE_PROP_END_OF_LIST() + } +}; + +static uint64_t omap2_inth_read(void *opaque, target_phys_addr_t addr, + unsigned size) { struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; int offset = addr; @@ -389,12 +398,15 @@ static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr) if (bank_no < s->nbanks) { offset &= ~0x60; bank = &s->bank[bank_no]; + } else { + OMAP_BAD_REG(addr); + return 0; } } switch (offset) { case 0x00: /* INTC_REVISION */ - return 0x21; + return s->revision; case 0x10: /* INTC_SYSCONFIG */ return (s->autoidle >> 2) & 1; @@ -455,7 +467,7 @@ static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr) } static void omap2_inth_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; int offset = addr; @@ -467,6 +479,9 @@ static void omap2_inth_write(void *opaque, target_phys_addr_t addr, if (bank_no < s->nbanks) { offset &= ~0x60; bank = &s->bank[bank_no]; + } else { + OMAP_BAD_REG(addr); + return; } } @@ -475,7 +490,7 @@ static void omap2_inth_write(void *opaque, target_phys_addr_t addr, s->autoidle &= 4; s->autoidle |= (value & 1) << 2; if (value & 2) /* SOFTRESET */ - omap_inth_reset(s); + omap_inth_reset(&s->busdev.qdev); return; case 0x48: /* INTC_CONTROL */ @@ -558,41 +573,55 @@ static void omap2_inth_write(void *opaque, target_phys_addr_t addr, OMAP_BAD_REG(addr); } -static CPUReadMemoryFunc * const omap2_inth_readfn[] = { - omap_badwidth_read32, - omap_badwidth_read32, - omap2_inth_read, -}; - -static CPUWriteMemoryFunc * const omap2_inth_writefn[] = { - omap2_inth_write, - omap2_inth_write, - omap2_inth_write, +static const MemoryRegionOps omap2_inth_mem_ops = { + .read = omap2_inth_read, + .write = omap2_inth_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; -struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base, - int size, int nbanks, qemu_irq **pins, - qemu_irq parent_irq, qemu_irq parent_fiq, - omap_clk fclk, omap_clk iclk) +static int omap2_intc_init(SysBusDevice *dev) { - int iomemtype; - struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) - qemu_mallocz(sizeof(struct omap_intr_handler_s) + - sizeof(struct omap_intr_handler_bank_s) * nbanks); - - s->parent_intr[0] = parent_irq; - s->parent_intr[1] = parent_fiq; - s->nbanks = nbanks; + struct omap_intr_handler_s *s; + s = FROM_SYSBUS(struct omap_intr_handler_s, dev); + if (!s->iclk) { + hw_error("omap2-intc: iclk not connected\n"); + } + if (!s->fclk) { + hw_error("omap2-intc: fclk not connected\n"); + } s->level_only = 1; - s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32); - if (pins) - *pins = s->pins; - - omap_inth_reset(s); + s->nbanks = 3; + sysbus_init_irq(dev, &s->parent_intr[0]); + sysbus_init_irq(dev, &s->parent_intr[1]); + qdev_init_gpio_in(&dev->qdev, omap_set_intr_noedge, s->nbanks * 32); + memory_region_init_io(&s->mmio, &omap2_inth_mem_ops, s, + "omap2-intc", 0x1000); + sysbus_init_mmio_region(dev, &s->mmio); + return 0; +} - iomemtype = cpu_register_io_memory(omap2_inth_readfn, - omap2_inth_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, size, iomemtype); +static SysBusDeviceInfo omap2_intc_info = { + .init = omap2_intc_init, + .qdev.name = "omap2-intc", + .qdev.size = sizeof(struct omap_intr_handler_s), + .qdev.reset = omap_inth_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s, + revision, 0x21), + DEFINE_PROP_PTR("iclk", struct omap_intr_handler_s, iclk), + DEFINE_PROP_PTR("fclk", struct omap_intr_handler_s, fclk), + DEFINE_PROP_END_OF_LIST() + } +}; - return s; +static void omap_intc_register_device(void) +{ + sysbus_register_withprop(&omap_intc_info); + sysbus_register_withprop(&omap2_intc_info); } + +device_init(omap_intc_register_device) diff --git a/hw/omap_l4.c b/hw/omap_l4.c index 4af0ca8..a4a8883 100644 --- a/hw/omap_l4.c +++ b/hw/omap_l4.c @@ -120,7 +120,7 @@ struct omap_l4_s { struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num) { - struct omap_l4_s *bus = qemu_mallocz( + struct omap_l4_s *bus = g_malloc0( sizeof(*bus) + ta_num * sizeof(*bus->ta)); bus->ta_num = ta_num; @@ -128,24 +128,30 @@ struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num) #ifdef L4_MUX_HACK omap_l4_io_entries = 1; - omap_l4_io_entry = qemu_mallocz(125 * sizeof(*omap_l4_io_entry)); + omap_l4_io_entry = g_malloc0(125 * sizeof(*omap_l4_io_entry)); omap_cpu_io_entry = cpu_register_io_memory(omap_l4_io_readfn, omap_l4_io_writefn, bus, DEVICE_NATIVE_ENDIAN); # define L4_PAGES (0xb4000 / TARGET_PAGE_SIZE) - omap_l4_io_readb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES); - omap_l4_io_readh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES); - omap_l4_io_readw_fn = qemu_mallocz(sizeof(void *) * L4_PAGES); - omap_l4_io_writeb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES); - omap_l4_io_writeh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES); - omap_l4_io_writew_fn = qemu_mallocz(sizeof(void *) * L4_PAGES); - omap_l4_io_opaque = qemu_mallocz(sizeof(void *) * L4_PAGES); + omap_l4_io_readb_fn = g_malloc0(sizeof(void *) * L4_PAGES); + omap_l4_io_readh_fn = g_malloc0(sizeof(void *) * L4_PAGES); + omap_l4_io_readw_fn = g_malloc0(sizeof(void *) * L4_PAGES); + omap_l4_io_writeb_fn = g_malloc0(sizeof(void *) * L4_PAGES); + omap_l4_io_writeh_fn = g_malloc0(sizeof(void *) * L4_PAGES); + omap_l4_io_writew_fn = g_malloc0(sizeof(void *) * L4_PAGES); + omap_l4_io_opaque = g_malloc0(sizeof(void *) * L4_PAGES); #endif return bus; } +target_phys_addr_t omap_l4_region_base(struct omap_target_agent_s *ta, + int region) +{ + return ta->bus->base + ta->start[region].offset; +} + static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr) { struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque; diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c index 0c2c550..29e6048 100644 --- a/hw/omap_lcdc.c +++ b/hw/omap_lcdc.c @@ -24,8 +24,6 @@ struct omap_lcd_panel_s { qemu_irq irq; DisplayState *state; - ram_addr_t imif_base; - ram_addr_t emiff_base; int plm; int tft; @@ -436,17 +434,14 @@ void omap_lcdc_reset(struct omap_lcd_panel_s *s) } struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq, - struct omap_dma_lcd_channel_s *dma, - ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk) + struct omap_dma_lcd_channel_s *dma, omap_clk clk) { int iomemtype; struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) - qemu_mallocz(sizeof(struct omap_lcd_panel_s)); + g_malloc0(sizeof(struct omap_lcd_panel_s)); s->irq = irq; s->dma = dma; - s->imif_base = imif_base; - s->emiff_base = emiff_base; omap_lcdc_reset(s); iomemtype = cpu_register_io_memory(omap_lcdc_readfn, diff --git a/hw/omap_mmc.c b/hw/omap_mmc.c index e9ec2f3..a1afeb5 100644 --- a/hw/omap_mmc.c +++ b/hw/omap_mmc.c @@ -576,7 +576,7 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, { int iomemtype; struct omap_mmc_s *s = (struct omap_mmc_s *) - qemu_mallocz(sizeof(struct omap_mmc_s)); + g_malloc0(sizeof(struct omap_mmc_s)); s->irq = irq; s->dma = dma; @@ -602,7 +602,7 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta, { int iomemtype; struct omap_mmc_s *s = (struct omap_mmc_s *) - qemu_mallocz(sizeof(struct omap_mmc_s)); + g_malloc0(sizeof(struct omap_mmc_s)); s->irq = irq; s->dma = dma; diff --git a/hw/omap_sdrc.c b/hw/omap_sdrc.c index e183762..1df2fd8 100644 --- a/hw/omap_sdrc.c +++ b/hw/omap_sdrc.c @@ -153,7 +153,7 @@ struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base) { int iomemtype; struct omap_sdrc_s *s = (struct omap_sdrc_s *) - qemu_mallocz(sizeof(struct omap_sdrc_s)); + g_malloc0(sizeof(struct omap_sdrc_s)); omap_sdrc_reset(s); diff --git a/hw/omap_spi.c b/hw/omap_spi.c index a6b0349..6030ad9 100644 --- a/hw/omap_spi.c +++ b/hw/omap_spi.c @@ -315,7 +315,7 @@ struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum, { int iomemtype; struct omap_mcspi_s *s = (struct omap_mcspi_s *) - qemu_mallocz(sizeof(struct omap_mcspi_s)); + g_malloc0(sizeof(struct omap_mcspi_s)); struct omap_mcspi_ch_s *ch = s->ch; s->irq = irq; diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c index 06bccbd..fe53545 100644 --- a/hw/omap_sx1.c +++ b/hw/omap_sx1.c @@ -26,13 +26,13 @@ * with this program; if not, see . */ #include "hw.h" -#include "sysemu.h" #include "console.h" #include "omap.h" #include "boards.h" #include "arm-misc.h" #include "flash.h" #include "blockdev.h" +#include "exec-memory.h" /*****************************************************************************/ /* Siemens SX1 Cellphone V1 */ @@ -122,6 +122,7 @@ static void sx1_init(ram_addr_t ram_size, const int version) { struct omap_mpu_state_s *cpu; + MemoryRegion *address_space = get_system_memory(); int io; static uint32_t cs0val = 0x00213090; static uint32_t cs1val = 0x00215070; @@ -136,7 +137,7 @@ static void sx1_init(ram_addr_t ram_size, flash_size = flash2_size; } - cpu = omap310_mpu_init(sx1_binfo.ram_size, cpu_model); + cpu = omap310_mpu_init(address_space, sx1_binfo.ram_size, cpu_model); /* External Flash (EMIFS) */ cpu_register_physical_memory(OMAP_CS0_BASE, flash_size, @@ -162,8 +163,8 @@ static void sx1_init(ram_addr_t ram_size, #endif if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) { - if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL, - "omap_sx1.flash0-1", flash_size), + if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL, + "omap_sx1.flash0-1", flash_size, dinfo->bdrv, sector_size, flash_size / sector_size, 4, 0, 0, 0, 0, be)) { @@ -183,8 +184,8 @@ static void sx1_init(ram_addr_t ram_size, cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size, OMAP_CS1_SIZE - flash1_size, io); - if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL, - "omap_sx1.flash1-1", flash1_size), + if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL, + "omap_sx1.flash1-1", flash1_size, dinfo->bdrv, sector_size, flash1_size / sector_size, 4, 0, 0, 0, 0, be)) { diff --git a/hw/omap_synctimer.c b/hw/omap_synctimer.c index 118668a..b47ca88 100644 --- a/hw/omap_synctimer.c +++ b/hw/omap_synctimer.c @@ -27,7 +27,7 @@ struct omap_synctimer_s { /* 32-kHz Sync Timer of the OMAP2 */ static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) { - return muldiv64(qemu_get_clock(vm_clock), 0x8000, get_ticks_per_sec()); + return muldiv64(qemu_get_clock_ns(vm_clock), 0x8000, get_ticks_per_sec()); } void omap_synctimer_reset(struct omap_synctimer_s *s) @@ -86,7 +86,7 @@ static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = { struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta, struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk) { - struct omap_synctimer_s *s = qemu_mallocz(sizeof(*s)); + struct omap_synctimer_s *s = g_malloc0(sizeof(*s)); omap_synctimer_reset(s); omap_l4_attach(ta, 0, l4_register_io_memory( diff --git a/hw/omap_uart.c b/hw/omap_uart.c index 9cee81d..19f8e6e 100644 --- a/hw/omap_uart.c +++ b/hw/omap_uart.c @@ -22,6 +22,7 @@ #include "omap.h" /* We use pc-style serial ports. */ #include "pc.h" +#include "exec-memory.h" /* UARTs */ struct omap_uart_s { @@ -55,20 +56,15 @@ struct omap_uart_s *omap_uart_init(target_phys_addr_t base, const char *label, CharDriverState *chr) { struct omap_uart_s *s = (struct omap_uart_s *) - qemu_mallocz(sizeof(struct omap_uart_s)); + g_malloc0(sizeof(struct omap_uart_s)); s->base = base; s->fclk = fclk; s->irq = irq; -#ifdef TARGET_WORDS_BIGENDIAN - s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16, - chr ?: qemu_chr_open(label, "null", NULL), 1, - 1); -#else - s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16, - chr ?: qemu_chr_open(label, "null", NULL), 1, - 0); -#endif + s->serial = serial_mm_init(get_system_memory(), base, 2, irq, + omap_clk_getrate(fclk)/16, + chr ?: qemu_chr_new(label, "null", NULL), + DEVICE_NATIVE_ENDIAN); return s; } @@ -182,15 +178,8 @@ struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta, void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr) { /* TODO: Should reuse or destroy current s->serial */ -#ifdef TARGET_WORDS_BIGENDIAN - s->serial = serial_mm_init(s->base, 2, s->irq, + s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq, omap_clk_getrate(s->fclk) / 16, - chr ?: qemu_chr_open("null", "null", NULL), 1, - 1); -#else - s->serial = serial_mm_init(s->base, 2, s->irq, - omap_clk_getrate(s->fclk) / 16, - chr ?: qemu_chr_open("null", "null", NULL), 1, - 0); -#endif + chr ?: qemu_chr_new("null", "null", NULL), + DEVICE_NATIVE_ENDIAN); } diff --git a/hw/onenand.c b/hw/onenand.c index 71c1ab4..7898da9 100644 --- a/hw/onenand.c +++ b/hw/onenand.c @@ -23,6 +23,10 @@ #include "flash.h" #include "irq.h" #include "blockdev.h" +#include "memory.h" +#include "exec-memory.h" +#include "sysbus.h" +#include "qemu-error.h" /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */ #define PAGE_SHIFT 11 @@ -31,7 +35,12 @@ #define BLOCK_SHIFT (PAGE_SHIFT + 6) typedef struct { - uint32_t id; + SysBusDevice busdev; + struct { + uint16_t man; + uint16_t dev; + uint16_t ver; + } id; int shift; target_phys_addr_t base; qemu_irq intr; @@ -41,10 +50,13 @@ typedef struct { uint8_t *image; uint8_t *otp; uint8_t *current; - ram_addr_t ram; + MemoryRegion ram; + MemoryRegion mapped_ram; + uint8_t current_direction; uint8_t *boot[2]; uint8_t *data[2][2]; - int iomemtype; + MemoryRegion iomem; + MemoryRegion container; int cycle; int otpmode; @@ -96,38 +108,88 @@ enum { ONEN_LOCK_UNLOCKED = 1 << 2, }; -void onenand_base_update(void *opaque, target_phys_addr_t new) +static void onenand_mem_setup(OneNANDState *s) { - OneNANDState *s = (OneNANDState *) opaque; - - s->base = new; - /* XXX: We should use IO_MEM_ROMD but we broke it earlier... * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to * write boot commands. Also take note of the BWPS bit. */ - cpu_register_physical_memory(s->base + (0x0000 << s->shift), - 0x0200 << s->shift, s->iomemtype); - cpu_register_physical_memory(s->base + (0x0200 << s->shift), - 0xbe00 << s->shift, - (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM); - if (s->iomemtype) - cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift), - 0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift)); + memory_region_init(&s->container, "onenand", 0x10000 << s->shift); + memory_region_add_subregion(&s->container, 0, &s->iomem); + memory_region_init_alias(&s->mapped_ram, "onenand-mapped-ram", + &s->ram, 0x0200 << s->shift, + 0xbe00 << s->shift); + memory_region_add_subregion_overlap(&s->container, + 0x0200 << s->shift, + &s->mapped_ram, + 1); } -void onenand_base_unmap(void *opaque) +static void onenand_intr_update(OneNANDState *s) { - OneNANDState *s = (OneNANDState *) opaque; + qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1); +} - cpu_register_physical_memory(s->base, - 0x10000 << s->shift, IO_MEM_UNASSIGNED); +static void onenand_pre_save(void *opaque) +{ + OneNANDState *s = opaque; + if (s->current == s->otp) { + s->current_direction = 1; + } else if (s->current == s->image) { + s->current_direction = 2; + } else { + s->current_direction = 0; + } } -static void onenand_intr_update(OneNANDState *s) +static int onenand_post_load(void *opaque, int version_id) { - qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1); + OneNANDState *s = opaque; + switch (s->current_direction) { + case 0: + break; + case 1: + s->current = s->otp; + break; + case 2: + s->current = s->image; + break; + default: + return -1; + } + onenand_intr_update(s); + return 0; } +static const VMStateDescription vmstate_onenand = { + .name = "onenand", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_save = onenand_pre_save, + .post_load = onenand_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT8(current_direction, OneNANDState), + VMSTATE_INT32(cycle, OneNANDState), + VMSTATE_INT32(otpmode, OneNANDState), + VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8), + VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8), + VMSTATE_INT32(bufaddr, OneNANDState), + VMSTATE_INT32(count, OneNANDState), + VMSTATE_UINT16(command, OneNANDState), + VMSTATE_UINT16_ARRAY(config, OneNANDState, 2), + VMSTATE_UINT16(status, OneNANDState), + VMSTATE_UINT16(intstatus, OneNANDState), + VMSTATE_UINT16(wpstatus, OneNANDState), + VMSTATE_INT32(secs_cur, OneNANDState), + VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks), + VMSTATE_UINT8(ecc.cp, OneNANDState), + VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2), + VMSTATE_UINT16(ecc.count, OneNANDState), + VMSTATE_BUFFER_UNSAFE(otp, OneNANDState, 0, ((64 + 2) << PAGE_SHIFT)), + VMSTATE_END_OF_LIST() + } +}; + /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */ static void onenand_reset(OneNANDState *s, int cold) { @@ -154,11 +216,17 @@ static void onenand_reset(OneNANDState *s, int cold) /* Lock the whole flash */ memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks); - if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0) - hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__); + if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) { + hw_error("%s: Loading the BootRAM failed.\n", __func__); + } } } +static void onenand_system_reset(DeviceState *dev) +{ + onenand_reset(FROM_SYSBUS(OneNANDState, sysbus_from_qdev(dev)), 1); +} + static inline int onenand_load_main(OneNANDState *s, int sec, int secn, void *dest) { @@ -175,14 +243,39 @@ static inline int onenand_load_main(OneNANDState *s, int sec, int secn, static inline int onenand_prog_main(OneNANDState *s, int sec, int secn, void *src) { - if (s->bdrv_cur) - return bdrv_write(s->bdrv_cur, sec, src, secn) < 0; - else if (sec + secn > s->secs_cur) - return 1; - - memcpy(s->current + (sec << 9), src, secn << 9); + int result = 0; + + if (secn > 0) { + uint32_t size = (uint32_t)secn * 512; + const uint8_t *sp = (const uint8_t *)src; + uint8_t *dp = 0; + if (s->bdrv_cur) { + dp = g_malloc(size); + if (!dp || bdrv_read(s->bdrv_cur, sec, dp, secn) < 0) { + result = 1; + } + } else { + if (sec + secn > s->secs_cur) { + result = 1; + } else { + dp = (uint8_t *)s->current + (sec << 9); + } + } + if (!result) { + uint32_t i; + for (i = 0; i < size; i++) { + dp[i] &= sp[i]; + } + if (s->bdrv_cur) { + result = bdrv_write(s->bdrv_cur, sec, dp, secn) < 0; + } + } + if (dp && s->bdrv_cur) { + g_free(dp); + } + } - return 0; + return result; } static inline int onenand_load_spare(OneNANDState *s, int sec, int secn, @@ -205,38 +298,90 @@ static inline int onenand_load_spare(OneNANDState *s, int sec, int secn, static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn, void *src) { - uint8_t buf[512]; - - if (s->bdrv_cur) { - if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) - return 1; - memcpy(buf + ((sec & 31) << 4), src, secn << 4); - return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0; - } else if (sec + secn > s->secs_cur) - return 1; - - memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4); - - return 0; + int result = 0; + if (secn > 0) { + const uint8_t *sp = (const uint8_t *)src; + uint8_t *dp = 0, *dpp = 0; + if (s->bdrv_cur) { + dp = g_malloc(512); + if (!dp || bdrv_read(s->bdrv_cur, + s->secs_cur + (sec >> 5), + dp, 1) < 0) { + result = 1; + } else { + dpp = dp + ((sec & 31) << 4); + } + } else { + if (sec + secn > s->secs_cur) { + result = 1; + } else { + dpp = s->current + (s->secs_cur << 9) + (sec << 4); + } + } + if (!result) { + uint32_t i; + for (i = 0; i < (secn << 4); i++) { + dpp[i] &= sp[i]; + } + if (s->bdrv_cur) { + result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), + dp, 1) < 0; + } + } + if (dp) { + g_free(dp); + } + } + return result; } static inline int onenand_erase(OneNANDState *s, int sec, int num) { - /* TODO: optimise */ - uint8_t buf[512]; - - memset(buf, 0xff, sizeof(buf)); - for (; num > 0; num --, sec ++) { - if (onenand_prog_main(s, sec, 1, buf)) - return 1; - if (onenand_prog_spare(s, sec, 1, buf)) - return 1; + uint8_t *blankbuf, *tmpbuf; + blankbuf = g_malloc(512); + if (!blankbuf) { + return 1; + } + tmpbuf = g_malloc(512); + if (!tmpbuf) { + g_free(blankbuf); + return 1; + } + memset(blankbuf, 0xff, 512); + for (; num > 0; num--, sec++) { + if (s->bdrv_cur) { + int erasesec = s->secs_cur + (sec >> 5); + if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1)) { + goto fail; + } + if (bdrv_read(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) { + goto fail; + } + memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4); + if (bdrv_write(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) { + goto fail; + } + } else { + if (sec + 1 > s->secs_cur) { + goto fail; + } + memcpy(s->current + (sec << 9), blankbuf, 512); + memcpy(s->current + (s->secs_cur << 9) + (sec << 4), + blankbuf, 1 << 4); + } } + g_free(tmpbuf); + g_free(blankbuf); return 0; + +fail: + g_free(tmpbuf); + g_free(blankbuf); + return 1; } -static void onenand_command(OneNANDState *s, int cmd) +static void onenand_command(OneNANDState *s) { int b; int sec; @@ -256,7 +401,7 @@ static void onenand_command(OneNANDState *s, int cmd) s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \ buf += (s->bufaddr & 3) << 4; - switch (cmd) { + switch (s->command) { case 0x00: /* Load single/multiple sector data unit into buffer */ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) @@ -437,13 +582,14 @@ static void onenand_command(OneNANDState *s, int cmd) s->status |= ONEN_ERR_CMD; s->intstatus |= ONEN_INT; fprintf(stderr, "%s: unknown OneNAND command %x\n", - __FUNCTION__, cmd); + __func__, s->command); } onenand_intr_update(s); } -static uint32_t onenand_read(void *opaque, target_phys_addr_t addr) +static uint64_t onenand_read(void *opaque, target_phys_addr_t addr, + unsigned size) { OneNANDState *s = (OneNANDState *) opaque; int offset = addr >> s->shift; @@ -453,12 +599,12 @@ static uint32_t onenand_read(void *opaque, target_phys_addr_t addr) return lduw_le_p(s->boot[0] + addr); case 0xf000: /* Manufacturer ID */ - return (s->id >> 16) & 0xff; + return s->id.man; case 0xf001: /* Device ID */ - return (s->id >> 8) & 0xff; - /* TODO: get the following values from a real chip! */ + return s->id.dev; case 0xf002: /* Version ID */ - return (s->id >> 0) & 0xff; + return s->id.ver; + /* TODO: get the following values from a real chip! */ case 0xf003: /* Data Buffer size */ return 1 << PAGE_SHIFT; case 0xf004: /* Boot Buffer size */ @@ -508,7 +654,7 @@ static uint32_t onenand_read(void *opaque, target_phys_addr_t addr) } static void onenand_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { OneNANDState *s = (OneNANDState *) opaque; int offset = addr >> s->shift; @@ -541,13 +687,13 @@ static void onenand_write(void *opaque, target_phys_addr_t addr, case 0x0090: /* Read Identification Data */ memset(s->boot[0], 0, 3 << s->shift); - s->boot[0][0 << s->shift] = (s->id >> 16) & 0xff; - s->boot[0][1 << s->shift] = (s->id >> 8) & 0xff; + s->boot[0][0 << s->shift] = s->id.man & 0xff; + s->boot[0][1 << s->shift] = s->id.dev & 0xff; s->boot[0][2 << s->shift] = s->wpstatus & 0xff; break; default: - fprintf(stderr, "%s: unknown OneNAND boot command %x\n", + fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n", __FUNCTION__, value); } break; @@ -568,7 +714,7 @@ static void onenand_write(void *opaque, target_phys_addr_t addr, if (s->intstatus & (1 << 15)) break; s->command = value; - onenand_command(s, s->command); + onenand_command(s); break; case 0xf221: /* System Configuration 1 */ s->config[0] = value; @@ -603,59 +749,81 @@ static void onenand_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const onenand_readfn[] = { - onenand_read, /* TODO */ - onenand_read, - onenand_read, -}; - -static CPUWriteMemoryFunc * const onenand_writefn[] = { - onenand_write, /* TODO */ - onenand_write, - onenand_write, +static const MemoryRegionOps onenand_ops = { + .read = onenand_read, + .write = onenand_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -void *onenand_init(uint32_t id, int regshift, qemu_irq irq) +static int onenand_initfn(SysBusDevice *dev) { - OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s)); - DriveInfo *dinfo = drive_get(IF_MTD, 0, 0); - uint32_t size = 1 << (24 + ((id >> 12) & 7)); + OneNANDState *s = (OneNANDState *)dev; + uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7)); void *ram; - - s->shift = regshift; - s->intr = irq; + s->base = (target_phys_addr_t)-1; s->rdy = NULL; - s->id = id; s->blocks = size >> BLOCK_SHIFT; s->secs = size >> 9; - s->blockwp = qemu_malloc(s->blocks); - s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0; - s->iomemtype = cpu_register_io_memory(onenand_readfn, - onenand_writefn, s, DEVICE_NATIVE_ENDIAN); - if (!dinfo) - s->image = memset(qemu_malloc(size + (size >> 5)), - 0xff, size + (size >> 5)); - else - s->bdrv = dinfo->bdrv; - s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT), + s->blockwp = g_malloc(s->blocks); + s->density_mask = (s->id.dev & 0x08) + ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0; + memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand", + 0x10000 << s->shift); + if (!s->bdrv) { + s->image = memset(g_malloc(size + (size >> 5)), + 0xff, size + (size >> 5)); + } else { + if (bdrv_is_read_only(s->bdrv)) { + error_report("Can't use a read-only drive"); + return -1; + } + s->bdrv_cur = s->bdrv; + } + s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT), 0xff, (64 + 2) << PAGE_SHIFT); - s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift); - ram = qemu_get_ram_ptr(s->ram); + memory_region_init_ram(&s->ram, NULL, "onenand.ram", 0xc000 << s->shift); + ram = memory_region_get_ram_ptr(&s->ram); s->boot[0] = ram + (0x0000 << s->shift); s->boot[1] = ram + (0x8000 << s->shift); s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift); s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift); s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift); s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift); + onenand_mem_setup(s); + sysbus_init_irq(dev, &s->intr); + sysbus_init_mmio_region(dev, &s->container); + vmstate_register(&dev->qdev, + ((s->shift & 0x7f) << 24) + | ((s->id.man & 0xff) << 16) + | ((s->id.dev & 0xff) << 8) + | (s->id.ver & 0xff), + &vmstate_onenand, s); + return 0; +} - onenand_reset(s, 1); +static SysBusDeviceInfo onenand_info = { + .init = onenand_initfn, + .qdev.name = "onenand", + .qdev.size = sizeof(OneNANDState), + .qdev.reset = onenand_system_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0), + DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0), + DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0), + DEFINE_PROP_INT32("shift", OneNANDState, shift, 0), + DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv), + DEFINE_PROP_END_OF_LIST() + } +}; - return s; +static void onenand_register_device(void) +{ + sysbus_register_withprop(&onenand_info); } -void *onenand_raw_otp(void *opaque) +void *onenand_raw_otp(DeviceState *onenand_device) { - OneNANDState *s = (OneNANDState *) opaque; - - return s->otp; + return FROM_SYSBUS(OneNANDState, sysbus_from_qdev(onenand_device))->otp; } + +device_init(onenand_register_device) diff --git a/hw/openpic.c b/hw/openpic.c index 6d2cf99..22fc275 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -2,6 +2,7 @@ * OpenPIC emulation * * Copyright (c) 2004 Jocelyn Mayer + * 2011 Alexander Graf * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -56,13 +57,13 @@ #define MAX_MBX 4 #define MAX_TMR 4 #define VECTOR_BITS 8 -#define MAX_IPI 0 +#define MAX_IPI 4 #define VID (0x00000000) #elif defined(USE_MPCxxx) -#define MAX_CPU 2 +#define MAX_CPU 15 #define MAX_IRQ 128 #define MAX_DBL 0 #define MAX_MBX 0 @@ -127,14 +128,14 @@ enum { #define MPIC_MSI_REG_START 0x11C00 #define MPIC_MSI_REG_SIZE 0x100 #define MPIC_CPU_REG_START 0x20000 -#define MPIC_CPU_REG_SIZE 0x100 +#define MPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) enum mpic_ide_bits { - IDR_EP = 0, - IDR_CI0 = 1, - IDR_CI1 = 2, - IDR_P1 = 30, - IDR_P0 = 31, + IDR_EP = 31, + IDR_CI0 = 30, + IDR_CI1 = 29, + IDR_P1 = 1, + IDR_P0 = 0, }; #else @@ -161,6 +162,16 @@ static inline int test_bit (uint32_t *field, int bit) return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0; } +static int get_current_cpu(void) +{ + return cpu_single_env->cpu_index; +} + +static uint32_t openpic_cpu_read_internal(void *opaque, target_phys_addr_t addr, + int idx); +static void openpic_cpu_write_internal(void *opaque, target_phys_addr_t addr, + uint32_t val, int idx); + enum { IRQ_EXTERNAL = 0x01, IRQ_INTERNAL = 0x02, @@ -205,7 +216,11 @@ typedef struct IRQ_dst_t { typedef struct openpic_t { PCIDevice pci_dev; - int mem_index; + MemoryRegion mem; + + /* Sub-regions */ + MemoryRegion sub_io_mem[7]; + /* Global registers */ uint32_t frep; /* Feature reporting register */ uint32_t glbc; /* Global configuration register */ @@ -461,46 +476,35 @@ static void openpic_reset (void *opaque) opp->glbc = 0x00000000; } -static inline uint32_t read_IRQreg (openpic_t *opp, int n_IRQ, uint32_t reg) +static inline uint32_t read_IRQreg_ide(openpic_t *opp, int n_IRQ) { - uint32_t retval; - - switch (reg) { - case IRQ_IPVP: - retval = opp->src[n_IRQ].ipvp; - break; - case IRQ_IDE: - retval = opp->src[n_IRQ].ide; - break; - } + return opp->src[n_IRQ].ide; +} - return retval; +static inline uint32_t read_IRQreg_ipvp(openpic_t *opp, int n_IRQ) +{ + return opp->src[n_IRQ].ipvp; } -static inline void write_IRQreg (openpic_t *opp, int n_IRQ, - uint32_t reg, uint32_t val) +static inline void write_IRQreg_ide(openpic_t *opp, int n_IRQ, uint32_t val) { uint32_t tmp; - switch (reg) { - case IRQ_IPVP: - /* NOTE: not fully accurate for special IRQs, but simple and - sufficient */ - /* ACTIVITY bit is read-only */ - opp->src[n_IRQ].ipvp = - (opp->src[n_IRQ].ipvp & 0x40000000) | - (val & 0x800F00FF); - openpic_update_irq(opp, n_IRQ); - DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", - n_IRQ, val, opp->src[n_IRQ].ipvp); - break; - case IRQ_IDE: - tmp = val & 0xC0000000; - tmp |= val & ((1 << MAX_CPU) - 1); - opp->src[n_IRQ].ide = tmp; - DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide); - break; - } + tmp = val & 0xC0000000; + tmp |= val & ((1ULL << MAX_CPU) - 1); + opp->src[n_IRQ].ide = tmp; + DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide); +} + +static inline void write_IRQreg_ipvp(openpic_t *opp, int n_IRQ, uint32_t val) +{ + /* NOTE: not fully accurate for special IRQs, but simple and sufficient */ + /* ACTIVITY bit is read-only */ + opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp & 0x40000000) + | (val & 0x800F00FF); + openpic_update_irq(opp, n_IRQ); + DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", n_IRQ, val, + opp->src[n_IRQ].ipvp); } #if 0 // Code provision for Intel model @@ -512,10 +516,10 @@ static uint32_t read_doorbell_register (openpic_t *opp, switch (offset) { case DBL_IPVP_OFFSET: - retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP); + retval = read_IRQreg_ipvp(opp, IRQ_DBL0 + n_dbl); break; case DBL_IDE_OFFSET: - retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE); + retval = read_IRQreg_ide(opp, IRQ_DBL0 + n_dbl); break; case DBL_DMR_OFFSET: retval = opp->doorbells[n_dbl].dmr; @@ -530,10 +534,10 @@ static void write_doorbell_register (penpic_t *opp, int n_dbl, { switch (offset) { case DBL_IVPR_OFFSET: - write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP, value); + write_IRQreg_ipvp(opp, IRQ_DBL0 + n_dbl, value); break; case DBL_IDE_OFFSET: - write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE, value); + write_IRQreg_ide(opp, IRQ_DBL0 + n_dbl, value); break; case DBL_DMR_OFFSET: opp->doorbells[n_dbl].dmr = value; @@ -553,10 +557,10 @@ static uint32_t read_mailbox_register (openpic_t *opp, retval = opp->mailboxes[n_mbx].mbr; break; case MBX_IVPR_OFFSET: - retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP); + retval = read_IRQreg_ipvp(opp, IRQ_MBX0 + n_mbx); break; case MBX_DMR_OFFSET: - retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE); + retval = read_IRQreg_ide(opp, IRQ_MBX0 + n_mbx); break; } @@ -571,10 +575,10 @@ static void write_mailbox_register (openpic_t *opp, int n_mbx, opp->mailboxes[n_mbx].mbr = value; break; case MBX_IVPR_OFFSET: - write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP, value); + write_IRQreg_ipvp(opp, IRQ_MBX0 + n_mbx, value); break; case MBX_DMR_OFFSET: - write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE, value); + write_IRQreg_ide(opp, IRQ_MBX0 + n_mbx, value); break; } } @@ -590,18 +594,27 @@ static void openpic_gbl_write (void *opaque, target_phys_addr_t addr, uint32_t v DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val); if (addr & 0xF) return; - addr &= 0xFF; switch (addr) { - case 0x00: /* FREP */ + case 0x40: + case 0x50: + case 0x60: + case 0x70: + case 0x80: + case 0x90: + case 0xA0: + case 0xB0: + openpic_cpu_write_internal(opp, addr, val, get_current_cpu()); break; - case 0x20: /* GLBC */ + case 0x1000: /* FREP */ + break; + case 0x1020: /* GLBC */ if (val & 0x80000000 && opp->reset) opp->reset(opp); opp->glbc = val & ~0x80000000; break; - case 0x80: /* VENI */ + case 0x1080: /* VENI */ break; - case 0x90: /* PINT */ + case 0x1090: /* PINT */ for (idx = 0; idx < opp->nb_cpus; idx++) { if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) { DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx); @@ -615,22 +628,20 @@ static void openpic_gbl_write (void *opaque, target_phys_addr_t addr, uint32_t v } opp->pint = val; break; -#if MAX_IPI > 0 - case 0xA0: /* IPI_IPVP */ - case 0xB0: - case 0xC0: - case 0xD0: + case 0x10A0: /* IPI_IPVP */ + case 0x10B0: + case 0x10C0: + case 0x10D0: { int idx; - idx = (addr - 0xA0) >> 4; - write_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP, val); + idx = (addr - 0x10A0) >> 4; + write_IRQreg_ipvp(opp, opp->irq_ipi0 + idx, val); } break; -#endif - case 0xE0: /* SPVE */ + case 0x10E0: /* SPVE */ opp->spve = val & 0x000000FF; break; - case 0xF0: /* TIFR */ + case 0x10F0: /* TIFR */ opp->tifr = val; break; default: @@ -647,36 +658,43 @@ static uint32_t openpic_gbl_read (void *opaque, target_phys_addr_t addr) retval = 0xFFFFFFFF; if (addr & 0xF) return retval; - addr &= 0xFF; switch (addr) { - case 0x00: /* FREP */ + case 0x1000: /* FREP */ retval = opp->frep; break; - case 0x20: /* GLBC */ + case 0x1020: /* GLBC */ retval = opp->glbc; break; - case 0x80: /* VENI */ + case 0x1080: /* VENI */ retval = opp->veni; break; - case 0x90: /* PINT */ + case 0x1090: /* PINT */ retval = 0x00000000; break; -#if MAX_IPI > 0 - case 0xA0: /* IPI_IPVP */ + case 0x40: + case 0x50: + case 0x60: + case 0x70: + case 0x80: + case 0x90: + case 0xA0: case 0xB0: - case 0xC0: - case 0xD0: + retval = openpic_cpu_read_internal(opp, addr, get_current_cpu()); + break; + case 0x10A0: /* IPI_IPVP */ + case 0x10B0: + case 0x10C0: + case 0x10D0: { int idx; - idx = (addr - 0xA0) >> 4; - retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP); + idx = (addr - 0x10A0) >> 4; + retval = read_IRQreg_ipvp(opp, opp->irq_ipi0 + idx); } break; -#endif - case 0xE0: /* SPVE */ + case 0x10E0: /* SPVE */ retval = opp->spve; break; - case 0xF0: /* TIFR */ + case 0x10F0: /* TIFR */ retval = opp->tifr; break; default: @@ -710,10 +728,10 @@ static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val) opp->timers[idx].tibc = val; break; case 0x20: /* TIVP */ - write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP, val); + write_IRQreg_ipvp(opp, opp->irq_tim0 + idx, val); break; case 0x30: /* TIDE */ - write_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE, val); + write_IRQreg_ide(opp, opp->irq_tim0 + idx, val); break; } } @@ -740,10 +758,10 @@ static uint32_t openpic_timer_read (void *opaque, uint32_t addr) retval = opp->timers[idx].tibc; break; case 0x20: /* TIPV */ - retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IPVP); + retval = read_IRQreg_ipvp(opp, opp->irq_tim0 + idx); break; case 0x30: /* TIDE */ - retval = read_IRQreg(opp, opp->irq_tim0 + idx, IRQ_IDE); + retval = read_IRQreg_ide(opp, opp->irq_tim0 + idx); break; } DPRINTF("%s: => %08x\n", __func__, retval); @@ -763,10 +781,10 @@ static void openpic_src_write (void *opaque, uint32_t addr, uint32_t val) idx = addr >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - write_IRQreg(opp, idx, IRQ_IDE, val); + write_IRQreg_ide(opp, idx, val); } else { /* EXVP / IFEVP / IEEVP */ - write_IRQreg(opp, idx, IRQ_IPVP, val); + write_IRQreg_ipvp(opp, idx, val); } } @@ -784,38 +802,40 @@ static uint32_t openpic_src_read (void *opaque, uint32_t addr) idx = addr >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - retval = read_IRQreg(opp, idx, IRQ_IDE); + retval = read_IRQreg_ide(opp, idx); } else { /* EXVP / IFEVP / IEEVP */ - retval = read_IRQreg(opp, idx, IRQ_IPVP); + retval = read_IRQreg_ipvp(opp, idx); } DPRINTF("%s: => %08x\n", __func__, retval); return retval; } -static void openpic_cpu_write (void *opaque, target_phys_addr_t addr, uint32_t val) +static void openpic_cpu_write_internal(void *opaque, target_phys_addr_t addr, + uint32_t val, int idx) { openpic_t *opp = opaque; IRQ_src_t *src; IRQ_dst_t *dst; - int idx, s_IRQ, n_IRQ; + int s_IRQ, n_IRQ; - DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val); + DPRINTF("%s: cpu %d addr " TARGET_FMT_plx " <= %08x\n", __func__, idx, + addr, val); if (addr & 0xF) return; - addr &= 0x1FFF0; - idx = addr / 0x1000; dst = &opp->dst[idx]; addr &= 0xFF0; switch (addr) { #if MAX_IPI > 0 - case 0x40: /* PIPD */ + case 0x40: /* IPIDR */ case 0x50: case 0x60: case 0x70: idx = (addr - 0x40) >> 4; - write_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IDE, val); + /* we use IDE as mask which CPUs to deliver the IPI to still. */ + write_IRQreg_ide(opp, opp->irq_ipi0 + idx, + opp->src[opp->irq_ipi0 + idx].ide | val); openpic_set_irq(opp, opp->irq_ipi0 + idx, 1); openpic_set_irq(opp, opp->irq_ipi0 + idx, 0); break; @@ -852,20 +872,24 @@ static void openpic_cpu_write (void *opaque, target_phys_addr_t addr, uint32_t v } } -static uint32_t openpic_cpu_read (void *opaque, target_phys_addr_t addr) +static void openpic_cpu_write(void *opaque, target_phys_addr_t addr, uint32_t val) +{ + openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12); +} + +static uint32_t openpic_cpu_read_internal(void *opaque, target_phys_addr_t addr, + int idx) { openpic_t *opp = opaque; IRQ_src_t *src; IRQ_dst_t *dst; uint32_t retval; - int idx, n_IRQ; + int n_IRQ; - DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr); + DPRINTF("%s: cpu %d addr " TARGET_FMT_plx "\n", __func__, idx, addr); retval = 0xFFFFFFFF; if (addr & 0xF) return retval; - addr &= 0x1FFF0; - idx = addr / 0x1000; dst = &opp->dst[idx]; addr &= 0xFF0; switch (addr) { @@ -905,18 +929,22 @@ static uint32_t openpic_cpu_read (void *opaque, target_phys_addr_t addr) reset_bit(&src->ipvp, IPVP_ACTIVITY); src->pending = 0; } + + if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) { + src->ide &= ~(1 << idx); + if (src->ide && !test_bit(&src->ipvp, IPVP_SENSE)) { + /* trigger on CPUs that didn't know about it yet */ + openpic_set_irq(opp, n_IRQ, 1); + openpic_set_irq(opp, n_IRQ, 0); + /* if all CPUs knew about it, set active bit again */ + set_bit(&src->ipvp, IPVP_ACTIVITY); + } + } } break; case 0xB0: /* PEOI */ retval = 0; break; -#if MAX_IPI > 0 - case 0x40: /* IDE */ - case 0x50: - idx = (addr - 0x40) >> 4; - retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IDE); - break; -#endif default: break; } @@ -925,6 +953,11 @@ static uint32_t openpic_cpu_read (void *opaque, target_phys_addr_t addr) return retval; } +static uint32_t openpic_cpu_read(void *opaque, target_phys_addr_t addr) +{ + return openpic_cpu_read_internal(opaque, addr, (addr & 0x1f000) >> 12); +} + static void openpic_buggy_write (void *opaque, target_phys_addr_t addr, uint32_t val) { @@ -984,47 +1017,34 @@ static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr) return retval; } -static CPUWriteMemoryFunc * const openpic_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &openpic_writel, -}; +static uint64_t openpic_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + openpic_t *opp = opaque; -static CPUReadMemoryFunc * const openpic_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &openpic_readl, -}; + switch (size) { + case 4: return openpic_readl(opp, addr); + default: return openpic_buggy_read(opp, addr); + } +} -static void openpic_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void openpic_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { - openpic_t *opp; + openpic_t *opp = opaque; - DPRINTF("Map OpenPIC\n"); - opp = (openpic_t *)pci_dev; - /* Global registers */ - DPRINTF("Register OPENPIC gbl %08x => %08x\n", - addr + 0x1000, addr + 0x1000 + 0x100); - /* Timer registers */ - DPRINTF("Register OPENPIC timer %08x => %08x\n", - addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR); - /* Interrupt source registers */ - DPRINTF("Register OPENPIC src %08x => %08x\n", - addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2)); - /* Per CPU registers */ - DPRINTF("Register OPENPIC dst %08x => %08x\n", - addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU); - cpu_register_physical_memory(addr, 0x40000, opp->mem_index); -#if 0 // Don't implement ISU for now - opp_io_memory = cpu_register_io_memory(openpic_src_read, - openpic_src_write, NULL - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2), - opp_io_memory); -#endif + switch (size) { + case 4: return openpic_writel(opp, addr, data); + default: return openpic_buggy_write(opp, addr, data); + } } +static const MemoryRegionOps openpic_ops = { + .read = openpic_read, + .write = openpic_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) { unsigned int i; @@ -1161,7 +1181,7 @@ static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src) qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); } -qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, +qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs, qemu_irq irq_out) { openpic_t *opp; @@ -1180,14 +1200,22 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME? pci_conf[0x3d] = 0x00; // no interrupt pin + memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000); +#if 0 // Don't implement ISU for now + opp_io_memory = cpu_register_io_memory(openpic_src_read, + openpic_src_write, NULL + DEVICE_NATIVE_ENDIAN); + cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2), + opp_io_memory); +#endif + /* Register I/O spaces */ - pci_register_bar(&opp->pci_dev, 0, 0x40000, - PCI_BASE_ADDRESS_SPACE_MEMORY, &openpic_map); + pci_register_bar(&opp->pci_dev, 0, + PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem); } else { - opp = qemu_mallocz(sizeof(openpic_t)); + opp = g_malloc0(sizeof(openpic_t)); + memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000); } - opp->mem_index = cpu_register_io_memory(openpic_read, openpic_write, opp, - DEVICE_LITTLE_ENDIAN); // isu_base &= 0xFFFC0000; opp->nb_cpus = nb_cpus; @@ -1223,8 +1251,8 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, opp->irq_raise = openpic_irq_raise; opp->reset = openpic_reset; - if (pmem_index) - *pmem_index = opp->mem_index; + if (pmem) + *pmem = &opp->mem; return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq); } @@ -1248,7 +1276,7 @@ static void mpic_reset (void *opaque) mpp->glbc = 0x80000000; /* Initialise controller registers */ - mpp->frep = 0x004f0002; + mpp->frep = 0x004f0002 | ((mpp->nb_cpus - 1) << 8); mpp->veni = VENI; mpp->pint = 0x00000000; mpp->spve = 0x0000FFFF; @@ -1257,6 +1285,10 @@ static void mpic_reset (void *opaque) mpp->src[i].ipvp = 0x80800000; mpp->src[i].ide = 0x00000001; } + /* Set IDE for IPIs to 0 so we don't get spurious interrupts */ + for (i = mpp->irq_ipi0; i < (mpp->irq_ipi0 + MAX_IPI); i++) { + mpp->src[i].ide = 0; + } /* Initialise IRQ destinations */ for (i = 0; i < MAX_CPU; i++) { mpp->dst[i].pctp = 0x0000000F; @@ -1297,13 +1329,13 @@ static void mpic_timer_write (void *opaque, target_phys_addr_t addr, uint32_t va mpp->timers[idx].tibc = val; break; case 0x20: /* GTIVPR */ - write_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IPVP, val); + write_IRQreg_ipvp(mpp, MPIC_TMR_IRQ + idx, val); break; case 0x30: /* GTIDR & TFRR */ if ((addr & 0xF0) == 0xF0) mpp->dst[cpu].tfrr = val; else - write_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IDE, val); + write_IRQreg_ide(mpp, MPIC_TMR_IRQ + idx, val); break; } } @@ -1329,13 +1361,13 @@ static uint32_t mpic_timer_read (void *opaque, target_phys_addr_t addr) retval = mpp->timers[idx].tibc; break; case 0x20: /* TIPV */ - retval = read_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IPVP); + retval = read_IRQreg_ipvp(mpp, MPIC_TMR_IRQ + idx); break; case 0x30: /* TIDR */ if ((addr &0xF0) == 0XF0) retval = mpp->dst[cpu].tfrr; else - retval = read_IRQreg(mpp, MPIC_TMR_IRQ + idx, IRQ_IDE); + retval = read_IRQreg_ide(mpp, MPIC_TMR_IRQ + idx); break; } DPRINTF("%s: => %08x\n", __func__, retval); @@ -1358,10 +1390,10 @@ static void mpic_src_ext_write (void *opaque, target_phys_addr_t addr, idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - write_IRQreg(mpp, idx, IRQ_IDE, val); + write_IRQreg_ide(mpp, idx, val); } else { /* EXVP / IFEVP / IEEVP */ - write_IRQreg(mpp, idx, IRQ_IPVP, val); + write_IRQreg_ipvp(mpp, idx, val); } } } @@ -1382,10 +1414,10 @@ static uint32_t mpic_src_ext_read (void *opaque, target_phys_addr_t addr) idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - retval = read_IRQreg(mpp, idx, IRQ_IDE); + retval = read_IRQreg_ide(mpp, idx); } else { /* EXVP / IFEVP / IEEVP */ - retval = read_IRQreg(mpp, idx, IRQ_IPVP); + retval = read_IRQreg_ipvp(mpp, idx); } DPRINTF("%s: => %08x\n", __func__, retval); } @@ -1408,10 +1440,10 @@ static void mpic_src_int_write (void *opaque, target_phys_addr_t addr, idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - write_IRQreg(mpp, idx, IRQ_IDE, val); + write_IRQreg_ide(mpp, idx, val); } else { /* EXVP / IFEVP / IEEVP */ - write_IRQreg(mpp, idx, IRQ_IPVP, val); + write_IRQreg_ipvp(mpp, idx, val); } } } @@ -1432,10 +1464,10 @@ static uint32_t mpic_src_int_read (void *opaque, target_phys_addr_t addr) idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - retval = read_IRQreg(mpp, idx, IRQ_IDE); + retval = read_IRQreg_ide(mpp, idx); } else { /* EXVP / IFEVP / IEEVP */ - retval = read_IRQreg(mpp, idx, IRQ_IPVP); + retval = read_IRQreg_ipvp(mpp, idx); } DPRINTF("%s: => %08x\n", __func__, retval); } @@ -1458,10 +1490,10 @@ static void mpic_src_msg_write (void *opaque, target_phys_addr_t addr, idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - write_IRQreg(mpp, idx, IRQ_IDE, val); + write_IRQreg_ide(mpp, idx, val); } else { /* EXVP / IFEVP / IEEVP */ - write_IRQreg(mpp, idx, IRQ_IPVP, val); + write_IRQreg_ipvp(mpp, idx, val); } } } @@ -1482,10 +1514,10 @@ static uint32_t mpic_src_msg_read (void *opaque, target_phys_addr_t addr) idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - retval = read_IRQreg(mpp, idx, IRQ_IDE); + retval = read_IRQreg_ide(mpp, idx); } else { /* EXVP / IFEVP / IEEVP */ - retval = read_IRQreg(mpp, idx, IRQ_IPVP); + retval = read_IRQreg_ipvp(mpp, idx); } DPRINTF("%s: => %08x\n", __func__, retval); } @@ -1508,10 +1540,10 @@ static void mpic_src_msi_write (void *opaque, target_phys_addr_t addr, idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - write_IRQreg(mpp, idx, IRQ_IDE, val); + write_IRQreg_ide(mpp, idx, val); } else { /* EXVP / IFEVP / IEEVP */ - write_IRQreg(mpp, idx, IRQ_IPVP, val); + write_IRQreg_ipvp(mpp, idx, val); } } } @@ -1531,10 +1563,10 @@ static uint32_t mpic_src_msi_read (void *opaque, target_phys_addr_t addr) idx += (addr & 0xFFF0) >> 5; if (addr & 0x10) { /* EXDE / IFEDE / IEEDE */ - retval = read_IRQreg(mpp, idx, IRQ_IDE); + retval = read_IRQreg_ide(mpp, idx); } else { /* EXVP / IFEVP / IEEVP */ - retval = read_IRQreg(mpp, idx, IRQ_IPVP); + retval = read_IRQreg_ipvp(mpp, idx); } DPRINTF("%s: => %08x\n", __func__, retval); } @@ -1542,125 +1574,136 @@ static uint32_t mpic_src_msi_read (void *opaque, target_phys_addr_t addr) return retval; } -static CPUWriteMemoryFunc * const mpic_glb_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &openpic_gbl_write, -}; - -static CPUReadMemoryFunc * const mpic_glb_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &openpic_gbl_read, -}; - -static CPUWriteMemoryFunc * const mpic_tmr_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &mpic_timer_write, -}; - -static CPUReadMemoryFunc * const mpic_tmr_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &mpic_timer_read, -}; - -static CPUWriteMemoryFunc * const mpic_cpu_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &openpic_cpu_write, -}; - -static CPUReadMemoryFunc * const mpic_cpu_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &openpic_cpu_read, +static const MemoryRegionOps mpic_glb_ops = { + .old_mmio = { + .write = { openpic_buggy_write, + openpic_buggy_write, + openpic_gbl_write, + }, + .read = { openpic_buggy_read, + openpic_buggy_read, + openpic_gbl_read, + }, + }, + .endianness = DEVICE_BIG_ENDIAN, }; -static CPUWriteMemoryFunc * const mpic_ext_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &mpic_src_ext_write, +static const MemoryRegionOps mpic_tmr_ops = { + .old_mmio = { + .write = { openpic_buggy_write, + openpic_buggy_write, + mpic_timer_write, + }, + .read = { openpic_buggy_read, + openpic_buggy_read, + mpic_timer_read, + }, + }, + .endianness = DEVICE_BIG_ENDIAN, }; -static CPUReadMemoryFunc * const mpic_ext_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &mpic_src_ext_read, +static const MemoryRegionOps mpic_cpu_ops = { + .old_mmio = { + .write = { openpic_buggy_write, + openpic_buggy_write, + openpic_cpu_write, + }, + .read = { openpic_buggy_read, + openpic_buggy_read, + openpic_cpu_read, + }, + }, + .endianness = DEVICE_BIG_ENDIAN, }; -static CPUWriteMemoryFunc * const mpic_int_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &mpic_src_int_write, +static const MemoryRegionOps mpic_ext_ops = { + .old_mmio = { + .write = { openpic_buggy_write, + openpic_buggy_write, + mpic_src_ext_write, + }, + .read = { openpic_buggy_read, + openpic_buggy_read, + mpic_src_ext_read, + }, + }, + .endianness = DEVICE_BIG_ENDIAN, }; -static CPUReadMemoryFunc * const mpic_int_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &mpic_src_int_read, +static const MemoryRegionOps mpic_int_ops = { + .old_mmio = { + .write = { openpic_buggy_write, + openpic_buggy_write, + mpic_src_int_write, + }, + .read = { openpic_buggy_read, + openpic_buggy_read, + mpic_src_int_read, + }, + }, + .endianness = DEVICE_BIG_ENDIAN, }; -static CPUWriteMemoryFunc * const mpic_msg_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &mpic_src_msg_write, +static const MemoryRegionOps mpic_msg_ops = { + .old_mmio = { + .write = { openpic_buggy_write, + openpic_buggy_write, + mpic_src_msg_write, + }, + .read = { openpic_buggy_read, + openpic_buggy_read, + mpic_src_msg_read, + }, + }, + .endianness = DEVICE_BIG_ENDIAN, }; -static CPUReadMemoryFunc * const mpic_msg_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &mpic_src_msg_read, -}; -static CPUWriteMemoryFunc * const mpic_msi_write[] = { - &openpic_buggy_write, - &openpic_buggy_write, - &mpic_src_msi_write, -}; - -static CPUReadMemoryFunc * const mpic_msi_read[] = { - &openpic_buggy_read, - &openpic_buggy_read, - &mpic_src_msi_read, +static const MemoryRegionOps mpic_msi_ops = { + .old_mmio = { + .write = { openpic_buggy_write, + openpic_buggy_write, + mpic_src_msi_write, + }, + .read = { openpic_buggy_read, + openpic_buggy_read, + mpic_src_msi_read, + }, + }, + .endianness = DEVICE_BIG_ENDIAN, }; -qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus, - qemu_irq **irqs, qemu_irq irq_out) +qemu_irq *mpic_init (MemoryRegion *address_space, target_phys_addr_t base, + int nb_cpus, qemu_irq **irqs, qemu_irq irq_out) { - openpic_t *mpp; - int i; + openpic_t *mpp; + int i; struct { - CPUReadMemoryFunc * const *read; - CPUWriteMemoryFunc * const *write; - target_phys_addr_t start_addr; - ram_addr_t size; + const char *name; + MemoryRegionOps const *ops; + target_phys_addr_t start_addr; + ram_addr_t size; } const list[] = { - {mpic_glb_read, mpic_glb_write, MPIC_GLB_REG_START, MPIC_GLB_REG_SIZE}, - {mpic_tmr_read, mpic_tmr_write, MPIC_TMR_REG_START, MPIC_TMR_REG_SIZE}, - {mpic_ext_read, mpic_ext_write, MPIC_EXT_REG_START, MPIC_EXT_REG_SIZE}, - {mpic_int_read, mpic_int_write, MPIC_INT_REG_START, MPIC_INT_REG_SIZE}, - {mpic_msg_read, mpic_msg_write, MPIC_MSG_REG_START, MPIC_MSG_REG_SIZE}, - {mpic_msi_read, mpic_msi_write, MPIC_MSI_REG_START, MPIC_MSI_REG_SIZE}, - {mpic_cpu_read, mpic_cpu_write, MPIC_CPU_REG_START, MPIC_CPU_REG_SIZE}, + {"glb", &mpic_glb_ops, MPIC_GLB_REG_START, MPIC_GLB_REG_SIZE}, + {"tmr", &mpic_tmr_ops, MPIC_TMR_REG_START, MPIC_TMR_REG_SIZE}, + {"ext", &mpic_ext_ops, MPIC_EXT_REG_START, MPIC_EXT_REG_SIZE}, + {"int", &mpic_int_ops, MPIC_INT_REG_START, MPIC_INT_REG_SIZE}, + {"msg", &mpic_msg_ops, MPIC_MSG_REG_START, MPIC_MSG_REG_SIZE}, + {"msi", &mpic_msi_ops, MPIC_MSI_REG_START, MPIC_MSI_REG_SIZE}, + {"cpu", &mpic_cpu_ops, MPIC_CPU_REG_START, MPIC_CPU_REG_SIZE}, }; - /* XXX: for now, only one CPU is supported */ - if (nb_cpus != 1) - return NULL; + mpp = g_malloc0(sizeof(openpic_t)); - mpp = qemu_mallocz(sizeof(openpic_t)); + memory_region_init(&mpp->mem, "mpic", 0x40000); + memory_region_add_subregion(address_space, base, &mpp->mem); for (i = 0; i < sizeof(list)/sizeof(list[0]); i++) { - int mem_index; - mem_index = cpu_register_io_memory(list[i].read, list[i].write, mpp, - DEVICE_BIG_ENDIAN); - if (mem_index < 0) { - goto free; - } - cpu_register_physical_memory(base + list[i].start_addr, - list[i].size, mem_index); + memory_region_init_io(&mpp->sub_io_mem[i], list[i].ops, mpp, + list[i].name, list[i].size); + + memory_region_add_subregion(&mpp->mem, list[i].start_addr, + &mpp->sub_io_mem[i]); } mpp->nb_cpus = nb_cpus; @@ -1679,8 +1722,4 @@ qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus, qemu_register_reset(mpic_reset, mpp); return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq); - -free: - qemu_free(mpp); - return NULL; } diff --git a/hw/openpic.h b/hw/openpic.h index 0957c1f..715f084 100644 --- a/hw/openpic.h +++ b/hw/openpic.h @@ -11,8 +11,8 @@ enum { OPENPIC_OUTPUT_NB, }; -qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, - qemu_irq **irqs, qemu_irq irq_out); -qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus, +qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs, qemu_irq irq_out); +qemu_irq *mpic_init (MemoryRegion *address_space, target_phys_addr_t base, + int nb_cpus, qemu_irq **irqs, qemu_irq irq_out); #endif /* __OPENPIC_H__ */ diff --git a/hw/palm.c b/hw/palm.c index f22d777..094bfde 100644 --- a/hw/palm.c +++ b/hw/palm.c @@ -25,6 +25,7 @@ #include "arm-misc.h" #include "devices.h" #include "loader.h" +#include "exec-memory.h" static uint32_t static_readb(void *opaque, target_phys_addr_t offset) { @@ -53,16 +54,12 @@ static void static_write(void *opaque, target_phys_addr_t offset, #endif } -static CPUReadMemoryFunc * const static_readfn[] = { - static_readb, - static_readh, - static_readw, -}; - -static CPUWriteMemoryFunc * const static_writefn[] = { - static_write, - static_write, - static_write, +static const MemoryRegionOps static_ops = { + .old_mmio = { + .read = { static_readb, static_readh, static_readw, }, + .write = { static_write, static_write, static_write, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; /* Palm Tunsgten|E support */ @@ -94,7 +91,7 @@ static void palmte_microwire_setup(struct omap_mpu_state_s *cpu) { uWireSlave *tsc; - tsc = tsc2102_init(omap_gpio_in_get(cpu->gpio)[PALMTE_PINTDAV_GPIO]); + tsc = tsc2102_init(qdev_get_gpio_in(cpu->gpio, PALMTE_PINTDAV_GPIO)); omap_uwire_attach(cpu->microwire, tsc, 0); omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc)); @@ -163,24 +160,24 @@ static void palmte_gpio_setup(struct omap_mpu_state_s *cpu) qemu_irq *misc_gpio; omap_mmc_handlers(cpu->mmc, - omap_gpio_in_get(cpu->gpio)[PALMTE_MMC_WP_GPIO], + qdev_get_gpio_in(cpu->gpio, PALMTE_MMC_WP_GPIO), qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio) [PALMTE_MMC_SWITCH_GPIO])); misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7); - omap_gpio_out_set(cpu->gpio, PALMTE_MMC_POWER_GPIO, misc_gpio[0]); - omap_gpio_out_set(cpu->gpio, PALMTE_SPEAKER_GPIO, misc_gpio[1]); - omap_gpio_out_set(cpu->gpio, 11, misc_gpio[2]); - omap_gpio_out_set(cpu->gpio, 12, misc_gpio[3]); - omap_gpio_out_set(cpu->gpio, 13, misc_gpio[4]); - omap_mpuio_out_set(cpu->mpuio, 1, misc_gpio[5]); - omap_mpuio_out_set(cpu->mpuio, 3, misc_gpio[6]); + qdev_connect_gpio_out(cpu->gpio, PALMTE_MMC_POWER_GPIO, misc_gpio[0]); + qdev_connect_gpio_out(cpu->gpio, PALMTE_SPEAKER_GPIO, misc_gpio[1]); + qdev_connect_gpio_out(cpu->gpio, 11, misc_gpio[2]); + qdev_connect_gpio_out(cpu->gpio, 12, misc_gpio[3]); + qdev_connect_gpio_out(cpu->gpio, 13, misc_gpio[4]); + omap_mpuio_out_set(cpu->mpuio, 1, misc_gpio[5]); + omap_mpuio_out_set(cpu->mpuio, 3, misc_gpio[6]); /* Reset some inputs to initial state. */ - qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USBDETECT_GPIO]); - qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_USB_OR_DC_GPIO]); - qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[4]); - qemu_irq_lower(omap_gpio_in_get(cpu->gpio)[PALMTE_HEADPHONES_GPIO]); + qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USBDETECT_GPIO)); + qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USB_OR_DC_GPIO)); + qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, 4)); + qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_HEADPHONES_GPIO)); qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]); qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]); qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]); @@ -198,37 +195,39 @@ static void palmte_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { + MemoryRegion *address_space_mem = get_system_memory(); struct omap_mpu_state_s *cpu; int flash_size = 0x00800000; int sdram_size = palmte_binfo.ram_size; - int io; static uint32_t cs0val = 0xffffffff; static uint32_t cs1val = 0x0000e1a0; static uint32_t cs2val = 0x0000e1a0; static uint32_t cs3val = 0xe1a0e1a0; int rom_size, rom_loaded = 0; DisplayState *ds = get_displaystate(); + MemoryRegion *flash = g_new(MemoryRegion, 1); + MemoryRegion *cs = g_new(MemoryRegion, 4); - cpu = omap310_mpu_init(sdram_size, cpu_model); + cpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model); /* External Flash (EMIFS) */ - cpu_register_physical_memory(OMAP_CS0_BASE, flash_size, - qemu_ram_alloc(NULL, "palmte.flash", - flash_size) | IO_MEM_ROM); - - io = cpu_register_io_memory(static_readfn, static_writefn, &cs0val, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(OMAP_CS0_BASE + flash_size, - OMAP_CS0_SIZE - flash_size, io); - io = cpu_register_io_memory(static_readfn, static_writefn, &cs1val, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(OMAP_CS1_BASE, OMAP_CS1_SIZE, io); - io = cpu_register_io_memory(static_readfn, static_writefn, &cs2val, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(OMAP_CS2_BASE, OMAP_CS2_SIZE, io); - io = cpu_register_io_memory(static_readfn, static_writefn, &cs3val, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(OMAP_CS3_BASE, OMAP_CS3_SIZE, io); + memory_region_init_ram(flash, NULL, "palmte.flash", flash_size); + memory_region_set_readonly(flash, true); + memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash); + + memory_region_init_io(&cs[0], &static_ops, &cs0val, "palmte-cs0", + OMAP_CS0_SIZE - flash_size); + memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size, + &cs[0]); + memory_region_init_io(&cs[1], &static_ops, &cs1val, "palmte-cs1", + OMAP_CS1_SIZE); + memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]); + memory_region_init_io(&cs[2], &static_ops, &cs2val, "palmte-cs2", + OMAP_CS2_SIZE); + memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]); + memory_region_init_io(&cs[3], &static_ops, &cs3val, "palmte-cs3", + OMAP_CS3_SIZE); + memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]); palmte_microwire_setup(cpu); diff --git a/hw/parallel.c b/hw/parallel.c index ce311aa..8494d94 100644 --- a/hw/parallel.c +++ b/hw/parallel.c @@ -64,7 +64,7 @@ #define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE) -struct ParallelState { +typedef struct ParallelState { uint8_t dataw; uint8_t datar; uint8_t status; @@ -77,7 +77,7 @@ struct ParallelState { uint32_t last_read_offset; /* For debugging */ /* Memory-mapped interface */ int it_shift; -}; +} ParallelState; typedef struct ISAParallelState { ISADevice dev; @@ -120,7 +120,7 @@ parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val) if (val & PARA_CTR_STROBE) { s->status &= ~PARA_STS_BUSY; if ((s->control & PARA_CTR_STROBE) == 0) - qemu_chr_write(s->chr, &s->dataw, 1); + qemu_chr_fe_write(s->chr, &s->dataw, 1); } else { if (s->control & PARA_CTR_INTEN) { s->irq_pending = 1; @@ -150,7 +150,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) if (s->dataw == val) return; pdebug("wd%02x\n", val); - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm); s->dataw = val; break; case PARA_REG_STS: @@ -170,11 +170,11 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) } else { dir = 0; } - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir); parm &= ~PARA_CTR_DIR; } - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm); s->control = val; break; case PARA_REG_EPP_ADDR: @@ -183,7 +183,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) pdebug("wa%02x s\n", val); else { struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 }; - if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) { s->epp_timeout = 1; pdebug("wa%02x t\n", val); } @@ -197,7 +197,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val) pdebug("we%02x s\n", val); else { struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 }; - if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) { s->epp_timeout = 1; pdebug("we%02x t\n", val); } @@ -222,7 +222,7 @@ parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val) pdebug("we%04x s\n", val); return; } - err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); + err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); if (err) { s->epp_timeout = 1; pdebug("we%04x t\n", val); @@ -245,7 +245,7 @@ parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val) pdebug("we%08x s\n", val); return; } - err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); + err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg); if (err) { s->epp_timeout = 1; pdebug("we%08x t\n", val); @@ -297,13 +297,13 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) addr &= 7; switch(addr) { case PARA_REG_DATA: - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret); if (s->last_read_offset != addr || s->datar != ret) pdebug("rd%02x\n", ret); s->datar = ret; break; case PARA_REG_STS: - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret); ret &= ~PARA_STS_TMOUT; if (s->epp_timeout) ret |= PARA_STS_TMOUT; @@ -315,7 +315,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) /* s->control has some bits fixed to 1. It is zero only when it has not been yet written to. */ if (s->control == 0) { - qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret); if (s->last_read_offset != addr) pdebug("rc%02x\n", ret); s->control = ret; @@ -332,7 +332,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) pdebug("ra%02x s\n", ret); else { struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 }; - if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) { s->epp_timeout = 1; pdebug("ra%02x t\n", ret); } @@ -346,7 +346,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr) pdebug("re%02x s\n", ret); else { struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 }; - if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) { + if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) { s->epp_timeout = 1; pdebug("re%02x t\n", ret); } @@ -374,7 +374,7 @@ parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr) pdebug("re%04x s\n", eppdata); return eppdata; } - err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg); + err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg); ret = le16_to_cpu(eppdata); if (err) { @@ -401,7 +401,7 @@ parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr) pdebug("re%08x s\n", eppdata); return eppdata; } - err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg); + err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg); ret = le32_to_cpu(eppdata); if (err) { @@ -448,6 +448,29 @@ static void parallel_reset(void *opaque) static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; +static const MemoryRegionPortio isa_parallel_portio_hw_list[] = { + { 0, 8, 1, + .read = parallel_ioport_read_hw, + .write = parallel_ioport_write_hw }, + { 4, 1, 2, + .read = parallel_ioport_eppdata_read_hw2, + .write = parallel_ioport_eppdata_write_hw2 }, + { 4, 1, 4, + .read = parallel_ioport_eppdata_read_hw4, + .write = parallel_ioport_eppdata_write_hw4 }, + { 0x400, 8, 1, + .read = parallel_ioport_ecp_read, + .write = parallel_ioport_ecp_write }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionPortio isa_parallel_portio_sw_list[] = { + { 0, 8, 1, + .read = parallel_ioport_read_sw, + .write = parallel_ioport_write_sw }, + PORTIO_END_OF_LIST(), +}; + static int parallel_isa_initfn(ISADevice *dev) { static int index; @@ -473,45 +496,19 @@ static int parallel_isa_initfn(ISADevice *dev) isa_init_irq(dev, &s->irq, isa->isairq); qemu_register_reset(parallel_reset, s); - if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) { + if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) { s->hw_driver = 1; s->status = dummy; } - if (s->hw_driver) { - register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s); - register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s); - isa_init_ioport_range(dev, base, 8); - - register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s); - register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s); - register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s); - register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s); - isa_init_ioport(dev, base+4); - register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s); - register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s); - isa_init_ioport_range(dev, base+0x400, 8); - } - else { - register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s); - register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s); - isa_init_ioport_range(dev, base, 8); - } + isa_register_portio_list(dev, base, + (s->hw_driver + ? &isa_parallel_portio_hw_list[0] + : &isa_parallel_portio_sw_list[0]), + s, "parallel"); return 0; } -ParallelState *parallel_init(int index, CharDriverState *chr) -{ - ISADevice *dev; - - dev = isa_create("isa-parallel"); - qdev_prop_set_uint32(&dev->qdev, "index", index); - qdev_prop_set_chr(&dev->qdev, "chardev", chr); - if (qdev_init(&dev->qdev) < 0) - return NULL; - return &DO_UPCAST(ISAParallelState, dev, dev)->state; -} - /* Memory mapped interface */ static uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr) { @@ -571,12 +568,13 @@ static CPUWriteMemoryFunc * const parallel_mm_write_sw[] = { }; /* If fd is zero, it means that the parallel device uses the console */ -ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr) +bool parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, + CharDriverState *chr) { ParallelState *s; int io_sw; - s = qemu_mallocz(sizeof(ParallelState)); + s = g_malloc0(sizeof(ParallelState)); s->irq = irq; s->chr = chr; s->it_shift = it_shift; @@ -585,7 +583,7 @@ ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq io_sw = cpu_register_io_memory(parallel_mm_read_sw, parallel_mm_write_sw, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(base, 8 << it_shift, io_sw); - return s; + return true; } static ISADeviceInfo parallel_isa_info = { diff --git a/hw/pc.c b/hw/pc.c index 07b4c51..ca468c7 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -41,6 +41,14 @@ #include "sysemu.h" #include "blockdev.h" #include "ui/qemu-spice.h" +#include "memory.h" +#include "exec-memory.h" + +#ifdef CONFIG_MARU +#include "../tizen/src/hw/maru_overlay.h" +#include "../tizen/src/hw/maru_brightness.h" +#include "../tizen/src/maru_err_table.h" +#endif /* output Bochs bios info messages */ //#define DEBUG_BIOS @@ -76,26 +84,26 @@ struct e820_entry { uint64_t address; uint64_t length; uint32_t type; -} __attribute((__packed__, __aligned__(4))); +} QEMU_PACKED __attribute((__aligned__(4))); struct e820_table { uint32_t count; struct e820_entry entry[E820_NR_ENTRIES]; -} __attribute((__packed__, __aligned__(4))); +} QEMU_PACKED __attribute((__aligned__(4))); static struct e820_table e820_table; +struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; -void isa_irq_handler(void *opaque, int n, int level) +void gsi_handler(void *opaque, int n, int level) { - IsaIrqState *isa = (IsaIrqState *)opaque; + GSIState *s = opaque; - DPRINTF("isa_irqs: %s irq %d\n", level? "raise" : "lower", n); - if (n < 16) { - qemu_set_irq(isa->i8259[n], level); + DPRINTF("pc: %s GSI %d\n", level ? "raising" : "lowering", n); + if (n < ISA_NUM_IRQS) { + qemu_set_irq(s->i8259_irq[n], level); } - if (isa->ioapic) - qemu_set_irq(isa->ioapic[n], level); -}; + qemu_set_irq(s->ioapic_irq[n], level); +} static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { @@ -153,9 +161,6 @@ int cpu_get_pic_interrupt(CPUState *env) intno = apic_get_interrupt(env->apic_state); if (intno >= 0) { - /* set irq request if a PIC irq is still pending */ - /* XXX: improve that */ - pic_update_irq(isa_pic); return intno; } /* read the irq from the PIC */ @@ -191,23 +196,24 @@ static void pic_irq_request(void *opaque, int irq, int level) #define REG_EQUIPMENT_BYTE 0x14 -static int cmos_get_fd_drive_type(int fd0) +static int cmos_get_fd_drive_type(FDriveType fd0) { int val; switch (fd0) { - case 0: + case FDRIVE_DRV_144: /* 1.44 Mb 3"5 drive */ val = 4; break; - case 1: + case FDRIVE_DRV_288: /* 2.88 Mb 3"5 drive */ val = 5; break; - case 2: + case FDRIVE_DRV_120: /* 1.2 Mb 5"5 drive */ val = 2; break; + case FDRIVE_DRV_NONE: default: val = 0; break; @@ -331,11 +337,12 @@ static void pc_cmos_init_late(void *opaque) void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, const char *boot_device, - BusState *idebus0, BusState *idebus1, - FDCtrl *floppy_controller, ISADevice *s) + ISADevice *floppy, BusState *idebus0, BusState *idebus1, + ISADevice *s) { - int val; - int fd0, fd1, nb; + int val, nb, nb_heads, max_track, last_sect, i; + FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE }; + BlockDriverState *fd[MAX_FD]; static pc_cmos_init_late_arg arg; /* various important CMOS locations needed by PC/Bochs bios */ @@ -377,19 +384,28 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, } /* floppy type */ - - fd0 = fdctrl_get_drive_type(floppy_controller, 0); - fd1 = fdctrl_get_drive_type(floppy_controller, 1); - - val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1); + if (floppy) { + fdc_get_bs(fd, floppy); + for (i = 0; i < 2; i++) { + if (fd[i] && bdrv_is_inserted(fd[i])) { + bdrv_get_floppy_geometry_hint(fd[i], &nb_heads, &max_track, + &last_sect, FDRIVE_DRV_NONE, + &fd_type[i]); + } + } + } + val = (cmos_get_fd_drive_type(fd_type[0]) << 4) | + cmos_get_fd_drive_type(fd_type[1]); rtc_set_memory(s, 0x10, val); val = 0; nb = 0; - if (fd0 < 3) + if (fd_type[0] < FDRIVE_DRV_NONE) { nb++; - if (fd1 < 3) + } + if (fd_type[1] < FDRIVE_DRV_NONE) { nb++; + } switch (nb) { case 0: break; @@ -414,6 +430,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, /* port 92 stuff: could be split off */ typedef struct Port92State { ISADevice dev; + MemoryRegion io; uint8_t outport; qemu_irq *a20_out; } Port92State; @@ -465,13 +482,22 @@ static void port92_reset(DeviceState *d) s->outport &= ~1; } +static const MemoryRegionPortio port92_portio[] = { + { 0, 1, 1, .read = port92_read, .write = port92_write }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionOps port92_ops = { + .old_portio = port92_portio +}; + static int port92_initfn(ISADevice *dev) { Port92State *s = DO_UPCAST(Port92State, dev, dev); - register_ioport_read(0x92, 1, 1, port92_read, s); - register_ioport_write(0x92, 1, 1, port92_write, s); - isa_init_ioport(dev, 0x92); + memory_region_init_io(&s->io, &port92_ops, s, "port92", 1); + isa_register_ioport(dev, &s->io, 0x92); + s->outport = 0; return 0; } @@ -536,8 +562,7 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val) /* LGPL'ed VGA BIOS messages */ case 0x501: case 0x502: - fprintf(stderr, "VGA BIOS panic, line %d\n", val); - exit(1); + exit((val << 1) | 1); case 0x500: case 0x503: #ifdef DEBUG_BIOS @@ -578,6 +603,7 @@ static void *bochs_bios_init(void) register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL); register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL); + register_ioport_write(0x501, 1, 1, bochs_bios_write, NULL); register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL); register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL); register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL); @@ -604,7 +630,7 @@ static void *bochs_bios_init(void) * of nodes, one word for each VCPU->node and one word for each node to * hold the amount of memory. */ - numa_fw_cfg = qemu_mallocz((1 + smp_cpus + nb_numa_nodes) * 8); + numa_fw_cfg = g_malloc0((1 + smp_cpus + nb_numa_nodes) * 8); numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); for (i = 0; i < smp_cpus; i++) { for (j = 0; j < nb_numa_nodes; j++) { @@ -661,6 +687,17 @@ static void load_linux(void *fw_cfg, MIN(ARRAY_SIZE(header), kernel_size)) { fprintf(stderr, "qemu: could not load kernel '%s': %s\n", kernel_filename, strerror(errno)); + +#ifdef CONFIG_MARU + char *error_msg = NULL; + + error_msg = maru_convert_path(error_msg, kernel_filename); + maru_register_exit_msg(MARU_EXIT_KERNEL_FILE_EXCEPTION, error_msg); + if (error_msg) { + g_free(error_msg); + } +#endif + exit(1); } @@ -775,7 +812,7 @@ static void load_linux(void *fw_cfg, initrd_addr = (initrd_max-initrd_size) & ~4095; - initrd_data = qemu_malloc(initrd_size); + initrd_data = g_malloc(initrd_size); load_image(initrd_filename, initrd_data); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); @@ -793,8 +830,8 @@ static void load_linux(void *fw_cfg, setup_size = (setup_size+1)*512; kernel_size -= setup_size; - setup = qemu_malloc(setup_size); - kernel = qemu_malloc(kernel_size); + setup = g_malloc(setup_size); + kernel = g_malloc(kernel_size); fseek(f, 0, SEEK_SET); if (fread(setup, 1, setup_size, f) != setup_size) { fprintf(stderr, "fread() failed\n"); @@ -919,7 +956,6 @@ static CPUState *pc_new_cpu(const char *cpu_model) exit(1); } if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) { - env->cpuid_apic_id = env->cpu_index; env->apic_state = apic_init(env, env->cpuid_apic_id); } qemu_register_reset(pc_cpu_reset, env); @@ -945,49 +981,47 @@ void pc_cpus_init(const char *cpu_model) } } -void pc_memory_init(ram_addr_t ram_size, +#ifdef CONFIG_MARU +extern char* qemu_get_data_dir(void); +#endif + +void pc_memory_init(MemoryRegion *system_memory, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, - ram_addr_t *below_4g_mem_size_p, - ram_addr_t *above_4g_mem_size_p) + ram_addr_t below_4g_mem_size, + ram_addr_t above_4g_mem_size, + MemoryRegion *rom_memory, + MemoryRegion **ram_memory) { char *filename; int ret, linux_boot, i; - ram_addr_t ram_addr, bios_offset, option_rom_offset; - ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; + MemoryRegion *ram, *bios, *isa_bios, *option_rom_mr; + MemoryRegion *ram_below_4g, *ram_above_4g; int bios_size, isa_bios_size; void *fw_cfg; - if (ram_size >= 0xe0000000 ) { - above_4g_mem_size = ram_size - 0xe0000000; - below_4g_mem_size = 0xe0000000; - } else { - below_4g_mem_size = ram_size; - } - *above_4g_mem_size_p = above_4g_mem_size; - *below_4g_mem_size_p = below_4g_mem_size; - -#if TARGET_PHYS_ADDR_BITS == 32 - if (above_4g_mem_size > 0) { - hw_error("To much RAM for 32-bit physical address"); - } -#endif linux_boot = (kernel_filename != NULL); - /* allocate RAM */ - ram_addr = qemu_ram_alloc(NULL, "pc.ram", - below_4g_mem_size + above_4g_mem_size); - cpu_register_physical_memory(0, 0xa0000, ram_addr); - cpu_register_physical_memory(0x100000, - below_4g_mem_size - 0x100000, - ram_addr + 0x100000); -#if TARGET_PHYS_ADDR_BITS > 32 + /* Allocate RAM. We allocate it as a single memory region and use + * aliases to address portions of it, mostly for backwards compatiblity + * with older qemus that used qemu_ram_alloc(). + */ + ram = g_malloc(sizeof(*ram)); + memory_region_init_ram(ram, NULL, "pc.ram", + below_4g_mem_size + above_4g_mem_size); + *ram_memory = ram; + ram_below_4g = g_malloc(sizeof(*ram_below_4g)); + memory_region_init_alias(ram_below_4g, "ram-below-4g", ram, + 0, below_4g_mem_size); + memory_region_add_subregion(system_memory, 0, ram_below_4g); if (above_4g_mem_size > 0) { - cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size, - ram_addr + below_4g_mem_size); + ram_above_4g = g_malloc(sizeof(*ram_above_4g)); + memory_region_init_alias(ram_above_4g, "ram-above-4g", ram, + below_4g_mem_size, above_4g_mem_size); + memory_region_add_subregion(system_memory, 0x100000000ULL, + ram_above_4g); } -#endif /* BIOS load */ if (bios_name == NULL) @@ -1002,30 +1036,66 @@ void pc_memory_init(ram_addr_t ram_size, (bios_size % 65536) != 0) { goto bios_error; } - bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size); + bios = g_malloc(sizeof(*bios)); + memory_region_init_ram(bios, NULL, "pc.bios", bios_size); + memory_region_set_readonly(bios, true); ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); if (ret != 0) { bios_error: fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name); + +#ifdef CONFIG_MARU + char *error_msg = NULL; + const char *path = qemu_get_data_dir(); + char *bios_path = NULL; + int bios_len = 0; + + bios_len = strlen(path) + strlen("/") + strlen(bios_name) + 1; + bios_path = g_malloc(bios_len * sizeof(char)); + if (!bios_path) { + fprintf(stderr, "qemu: failed to allocate memory\n"); + } + snprintf(bios_path, bios_len, "%s/%s", path, bios_name); + error_msg = maru_convert_path(error_msg, bios_path); + maru_register_exit_msg(MARU_EXIT_BIOS_FILE_EXCEPTION, error_msg); + + if (bios_path) { + g_free(bios_path); + } + if (error_msg) { + g_free(error_msg); + } +#endif + exit(1); } if (filename) { - qemu_free(filename); + g_free(filename); } /* map the last 128KB of the BIOS in ISA space */ isa_bios_size = bios_size; if (isa_bios_size > (128 * 1024)) isa_bios_size = 128 * 1024; - cpu_register_physical_memory(0x100000 - isa_bios_size, - isa_bios_size, - (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); - - option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE); - cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset); + isa_bios = g_malloc(sizeof(*isa_bios)); + memory_region_init_alias(isa_bios, "isa-bios", bios, + bios_size - isa_bios_size, isa_bios_size); + memory_region_add_subregion_overlap(rom_memory, + 0x100000 - isa_bios_size, + isa_bios, + 1); + memory_region_set_readonly(isa_bios, true); + + option_rom_mr = g_malloc(sizeof(*option_rom_mr)); + memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE); + memory_region_add_subregion_overlap(rom_memory, + PC_ROM_MIN_VGA, + option_rom_mr, + 1); /* map all the bios at the top of memory */ - cpu_register_physical_memory((uint32_t)(-bios_size), - bios_size, bios_offset | IO_MEM_ROM); + memory_region_add_subregion(rom_memory, + (uint32_t)(-bios_size), + bios); fw_cfg = bochs_bios_init(); rom_set_fw(fw_cfg); @@ -1050,13 +1120,18 @@ void pc_vga_init(PCIBus *pci_bus) if (pci_bus) { pci_cirrus_vga_init(pci_bus); } else { - isa_cirrus_vga_init(); + isa_cirrus_vga_init(get_system_memory()); } } else if (vmsvga_enabled) { - if (pci_bus) - pci_vmsvga_init(pci_bus); - else + if (pci_bus) { + if (!pci_vmsvga_init(pci_bus)) { + fprintf(stderr, "Warning: vmware_vga not available," + " using standard VGA instead\n"); + pci_vga_init(pci_bus); + } + } else { fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__); + } #ifdef CONFIG_SPICE } else if (qxl_enabled) { if (pci_bus) @@ -1067,20 +1142,22 @@ void pc_vga_init(PCIBus *pci_bus) } else if (std_vga_enabled) { if (pci_bus) { pci_vga_init(pci_bus); - pci_overlay_init(pci_bus); - pci_brightness_init(pci_bus); } else { isa_vga_init(); } - } else if (tizen_vga_enabled) { +#ifdef CONFIG_MARU + } else if (maru_vga_enabled) { if (pci_bus) { - pci_tizen_vga_init(pci_bus); - pci_overlay_init(pci_bus); - pci_brightness_init(pci_bus); + pci_maru_vga_init(pci_bus); + pci_maru_overlay_init(pci_bus); + pci_maru_brightness_init(pci_bus); } else { isa_vga_init(); } } +#else + } +#endif } static void cpu_request_exit(void *opaque, int irq, int level) @@ -1092,16 +1169,16 @@ static void cpu_request_exit(void *opaque, int irq, int level) } } -void pc_basic_device_init(qemu_irq *isa_irq, - FDCtrl **floppy_controller, - ISADevice **rtc_state) +void pc_basic_device_init(qemu_irq *gsi, + ISADevice **rtc_state, + ISADevice **floppy, + bool no_vmport) { int i; DriveInfo *fd[MAX_FD]; - PITState *pit; qemu_irq rtc_irq = NULL; qemu_irq *a20_line; - ISADevice *i8042, *port92; + ISADevice *i8042, *port92, *vmmouse, *pit; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); @@ -1109,18 +1186,20 @@ void pc_basic_device_init(qemu_irq *isa_irq, register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); if (!no_hpet) { - DeviceState *hpet = sysbus_create_simple("hpet", HPET_BASE, NULL); + DeviceState *hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL); - for (i = 0; i < 24; i++) { - sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]); + if (hpet) { + for (i = 0; i < GSI_NUM_PINS; i++) { + sysbus_connect_irq(sysbus_from_qdev(hpet), i, gsi[i]); + } + rtc_irq = qdev_get_gpio_in(hpet, 0); } - rtc_irq = qdev_get_gpio_in(hpet, 0); } *rtc_state = rtc_init(2000, rtc_irq); qemu_register_boot_set(pc_boot_set, *rtc_state); - pit = pit_init(0x40, isa_get_irq(0)); + pit = pit_init(0x40, 0); pcspk_init(pit); for(i = 0; i < MAX_SERIAL_PORTS; i++) { @@ -1138,7 +1217,16 @@ void pc_basic_device_init(qemu_irq *isa_irq, a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2); i8042 = isa_create_simple("i8042"); i8042_setup_a20_line(i8042, &a20_line[0]); - vmmouse_init(i8042); + if (!no_vmport) { + vmport_init(); + vmmouse = isa_try_create("vmmouse"); + } else { + vmmouse = NULL; + } + if (vmmouse) { + qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042); + qdev_init_nofail(&vmmouse->qdev); + } port92 = isa_create_simple("port92"); port92_init(port92, &a20_line[1]); @@ -1148,7 +1236,7 @@ void pc_basic_device_init(qemu_irq *isa_irq, for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } - *floppy_controller = fdctrl_init_isa(fd); + *floppy = fdctrl_init_isa(fd); } void pc_pci_device_init(PCIBus *pci_bus) diff --git a/hw/pc.h b/hw/pc.h old mode 100755 new mode 100644 index 2358bce..b22ad39 --- a/hw/pc.h +++ b/hw/pc.h @@ -2,9 +2,13 @@ #define HW_PC_H #include "qemu-common.h" +#include "memory.h" #include "ioport.h" #include "isa.h" #include "fdc.h" +#include "net.h" +#include "memory.h" +#include "ioapic.h" /* PC-style peripherals (also used by other machines). */ @@ -12,70 +16,108 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase, CharDriverState *chr); -SerialState *serial_mm_init (target_phys_addr_t base, int it_shift, - qemu_irq irq, int baudbase, - CharDriverState *chr, int ioregister, - int be); -SerialState *serial_isa_init(int index, CharDriverState *chr); +SerialState *serial_mm_init(MemoryRegion *address_space, + target_phys_addr_t base, int it_shift, + qemu_irq irq, int baudbase, + CharDriverState *chr, enum device_endian); +static inline bool serial_isa_init(int index, CharDriverState *chr) +{ + ISADevice *dev; + + dev = isa_try_create("isa-serial"); + if (!dev) { + return false; + } + qdev_prop_set_uint32(&dev->qdev, "index", index); + qdev_prop_set_chr(&dev->qdev, "chardev", chr); + if (qdev_init(&dev->qdev) < 0) { + return false; + } + return true; +} + void serial_set_frequency(SerialState *s, uint32_t frequency); /* parallel.c */ - -typedef struct ParallelState ParallelState; -ParallelState *parallel_init(int index, CharDriverState *chr); -ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr); +static inline bool parallel_init(int index, CharDriverState *chr) +{ + ISADevice *dev; + + dev = isa_try_create("isa-parallel"); + if (!dev) { + return false; + } + qdev_prop_set_uint32(&dev->qdev, "index", index); + qdev_prop_set_chr(&dev->qdev, "chardev", chr); + if (qdev_init(&dev->qdev) < 0) { + return false; + } + return true; +} + +bool parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, + CharDriverState *chr); /* i8259.c */ -typedef struct PicState2 PicState2; -extern PicState2 *isa_pic; -void pic_set_irq(int irq, int level); -void pic_set_irq_new(void *opaque, int irq, int level); +typedef struct PicState PicState; +extern PicState *isa_pic; qemu_irq *i8259_init(qemu_irq parent_irq); -int pic_read_irq(PicState2 *s); -void pic_update_irq(PicState2 *s); -uint32_t pic_intack_read(PicState2 *s); +int pic_read_irq(PicState *s); +int pic_get_output(PicState *s); void pic_info(Monitor *mon); void irq_info(Monitor *mon); -/* ISA */ -#define IOAPIC_NUM_PINS 0x18 +/* Global System Interrupts */ + +#define GSI_NUM_PINS IOAPIC_NUM_PINS -typedef struct isa_irq_state { - qemu_irq *i8259; - qemu_irq ioapic[IOAPIC_NUM_PINS]; -} IsaIrqState; +typedef struct GSIState { + qemu_irq i8259_irq[ISA_NUM_IRQS]; + qemu_irq ioapic_irq[IOAPIC_NUM_PINS]; +} GSIState; -void isa_irq_handler(void *opaque, int n, int level); +void gsi_handler(void *opaque, int n, int level); /* i8254.c */ #define PIT_FREQ 1193182 -typedef struct PITState PITState; +static inline ISADevice *pit_init(int base, int irq) +{ + ISADevice *dev; -PITState *pit_init(int base, qemu_irq irq); -void pit_set_gate(PITState *pit, int channel, int val); -int pit_get_gate(PITState *pit, int channel); -int pit_get_initial_count(PITState *pit, int channel); -int pit_get_mode(PITState *pit, int channel); -int pit_get_out(PITState *pit, int channel, int64_t current_time); + dev = isa_create("isa-pit"); + qdev_prop_set_uint32(&dev->qdev, "iobase", base); + qdev_prop_set_uint32(&dev->qdev, "irq", irq); + qdev_init_nofail(&dev->qdev); + + return dev; +} + +void pit_set_gate(ISADevice *dev, int channel, int val); +int pit_get_gate(ISADevice *dev, int channel); +int pit_get_initial_count(ISADevice *dev, int channel); +int pit_get_mode(ISADevice *dev, int channel); +int pit_get_out(ISADevice *dev, int channel, int64_t current_time); void hpet_pit_disable(void); void hpet_pit_enable(void); /* vmport.c */ -void vmport_init(void); +static inline void vmport_init(void) +{ + isa_create_simple("vmport"); +} void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque); - -/* vmmouse.c */ -void *vmmouse_init(void *m); +void vmmouse_get_data(uint32_t *data); +void vmmouse_set_data(const uint32_t *data); /* pckbd.c */ void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base); void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, - target_phys_addr_t base, ram_addr_t size, + MemoryRegion *region, ram_addr_t size, target_phys_addr_t mask); void i8042_isa_mouse_fake_event(void *opaque); void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out); @@ -88,22 +130,25 @@ void pc_cmos_set_s3_resume(void *opaque, int irq, int level); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); void pc_cpus_init(const char *cpu_model); -void pc_memory_init(ram_addr_t ram_size, +void pc_memory_init(MemoryRegion *system_memory, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, - ram_addr_t *below_4g_mem_size_p, - ram_addr_t *above_4g_mem_size_p); + ram_addr_t below_4g_mem_size, + ram_addr_t above_4g_mem_size, + MemoryRegion *rom_memory, + MemoryRegion **ram_memory); qemu_irq *pc_allocate_cpu_irq(void); void pc_vga_init(PCIBus *pci_bus); -void pc_basic_device_init(qemu_irq *isa_irq, - FDCtrl **floppy_controller, - ISADevice **rtc_state); +void pc_basic_device_init(qemu_irq *gsi, + ISADevice **rtc_state, + ISADevice **floppy, + bool no_vmport); void pc_init_ne2k_isa(NICInfo *nd); void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, const char *boot_device, - BusState *ide0, BusState *ide1, - FDCtrl *floppy_controller, ISADevice *s); + ISADevice *floppy, BusState *ide0, BusState *ide1, + ISADevice *s); void pc_pci_device_init(PCIBus *pci_bus); typedef void (*cpu_set_smm_t)(int smm, void *arg); @@ -128,15 +173,24 @@ void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); extern int no_hpet; /* pcspk.c */ -void pcspk_init(PITState *); +void pcspk_init(ISADevice *pit); int pcspk_audio_init(qemu_irq *pic); /* piix_pci.c */ struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size); -void i440fx_init_memory_mappings(PCII440FXState *d); +PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, + qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + ram_addr_t ram_size, + target_phys_addr_t pci_hole_start, + target_phys_addr_t pci_hole_size, + target_phys_addr_t pci_hole64_start, + target_phys_addr_t pci_hole64_size, + MemoryRegion *pci_memory, + MemoryRegion *ram_memory); /* piix4.c */ extern PCIDevice *piix4_dev; @@ -150,26 +204,49 @@ enum vga_retrace_method { extern enum vga_retrace_method vga_retrace_method; -int isa_vga_init(void); -int pci_vga_init(PCIBus *bus); -int pci_tizen_vga_init(PCIBus *bus); -int pci_overlay_init(PCIBus *bus); -int pci_brightness_init(PCIBus *bus); -int pci_get_brightness(void); +static inline int isa_vga_init(void) +{ + ISADevice *dev; + + dev = isa_try_create("isa-vga"); + if (!dev) { + fprintf(stderr, "Warning: isa-vga not available\n"); + return 0; + } + qdev_init_nofail(&dev->qdev); + return 1; +} -/* codec_accel.c */ -int pci_codec_init(PCIBus *bus); +int pci_vga_init(PCIBus *bus); +#ifdef CONFIG_MARU +int pci_maru_vga_init(PCIBus *bus); +#endif int isa_vga_mm_init(target_phys_addr_t vram_base, - target_phys_addr_t ctrl_base, int it_shift); + target_phys_addr_t ctrl_base, int it_shift, + MemoryRegion *address_space); /* cirrus_vga.c */ void pci_cirrus_vga_init(PCIBus *bus); -void isa_cirrus_vga_init(void); +void isa_cirrus_vga_init(MemoryRegion *address_space); /* ne2000.c */ - -void isa_ne2000_init(int base, int irq, NICInfo *nd); +static inline bool isa_ne2000_init(int base, int irq, NICInfo *nd) +{ + ISADevice *dev; + + qemu_check_nic_model(nd, "ne2k_isa"); + + dev = isa_try_create("ne2k_isa"); + if (!dev) { + return false; + } + qdev_prop_set_uint32(&dev->qdev, "iobase", base); + qdev_prop_set_uint32(&dev->qdev, "irq", irq); + qdev_set_nic_properties(&dev->qdev, nd); + qdev_init_nofail(&dev->qdev); + return true; +} /* e820 types */ #define E820_RAM 1 @@ -179,5 +256,5 @@ void isa_ne2000_init(int base, int irq, NICInfo *nd); #define E820_UNUSABLE 5 int e820_add_entry(uint64_t, uint64_t, uint32_t); -int svcamera_pci_init(PCIBus *bus); + #endif diff --git a/hw/pc_piix.c b/hw/pc_piix.c index ca0ed9e..05000e3 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -22,6 +22,8 @@ * THE SOFTWARE. */ +#include + #include "hw.h" #include "pc.h" #include "apic.h" @@ -32,10 +34,18 @@ #include "boards.h" #include "ide.h" #include "kvm.h" +#include "kvmclock.h" #include "sysemu.h" #include "sysbus.h" #include "arch_init.h" #include "blockdev.h" +#include "smbus.h" +#include "xen.h" +#include "memory.h" +#include "exec-memory.h" +#ifdef CONFIG_XEN +# include +#endif #define MAX_IDE_BUS 2 @@ -43,7 +53,7 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; -static void ioapic_init(IsaIrqState *isa_irq_state) +static void ioapic_init(GSIState *gsi_state) { DeviceState *dev; SysBusDevice *d; @@ -55,18 +65,21 @@ static void ioapic_init(IsaIrqState *isa_irq_state) sysbus_mmio_map(d, 0, 0xfec00000); for (i = 0; i < IOAPIC_NUM_PINS; i++) { - isa_irq_state->ioapic[i] = qdev_get_gpio_in(dev, i); + gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); } } /* PC hardware initialisation */ -static void pc_init1(ram_addr_t ram_size, +static void pc_init1(MemoryRegion *system_memory, + MemoryRegion *system_io, + ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, - int pci_enabled) + int pci_enabled, + int kvmclock_enabled) { int i; ram_addr_t below_4g_mem_size, above_4g_mem_size; @@ -74,48 +87,95 @@ static void pc_init1(ram_addr_t ram_size, PCII440FXState *i440fx_state; int piix3_devfn = -1; qemu_irq *cpu_irq; - qemu_irq *isa_irq; + qemu_irq *gsi; qemu_irq *i8259; qemu_irq *cmos_s3; qemu_irq *smi_irq; - IsaIrqState *isa_irq_state; + GSIState *gsi_state; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; - FDCtrl *floppy_controller; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; + ISADevice *floppy; + MemoryRegion *ram_memory; + MemoryRegion *pci_memory; + MemoryRegion *rom_memory; pc_cpus_init(cpu_model); - vmport_init(); + if (kvmclock_enabled) { + kvmclock_create(); + } - /* allocate ram and load rom/bios */ - pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename, - &below_4g_mem_size, &above_4g_mem_size); + if (ram_size >= 0xe0000000 ) { + above_4g_mem_size = ram_size - 0xe0000000; + below_4g_mem_size = 0xe0000000; + } else { + above_4g_mem_size = 0; + below_4g_mem_size = ram_size; + } - cpu_irq = pc_allocate_cpu_irq(); - i8259 = i8259_init(cpu_irq[0]); - isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state)); - isa_irq_state->i8259 = i8259; if (pci_enabled) { - ioapic_init(isa_irq_state); + pci_memory = g_new(MemoryRegion, 1); + memory_region_init(pci_memory, "pci", INT64_MAX); + rom_memory = pci_memory; + } else { + pci_memory = NULL; + rom_memory = system_memory; } - isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); + + /* allocate ram and load rom/bios */ + if (!xen_enabled()) { + pc_memory_init(system_memory, + kernel_filename, kernel_cmdline, initrd_filename, + below_4g_mem_size, above_4g_mem_size, + pci_enabled ? rom_memory : system_memory, &ram_memory); + } + + gsi_state = g_malloc0(sizeof(*gsi_state)); + gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS); if (pci_enabled) { - pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); + pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, gsi, + system_memory, system_io, ram_size, + below_4g_mem_size, + 0x100000000ULL - below_4g_mem_size, + 0x100000000ULL + above_4g_mem_size, + (sizeof(target_phys_addr_t) == 4 + ? 0 + : ((uint64_t)1 << 62)), + pci_memory, ram_memory); } else { pci_bus = NULL; i440fx_state = NULL; - isa_bus_new(NULL); + isa_bus_new(NULL, system_io); + no_hpet = 1; + } + isa_bus_irqs(gsi); + + if (!xen_enabled()) { + cpu_irq = pc_allocate_cpu_irq(); + i8259 = i8259_init(cpu_irq[0]); + } else { + i8259 = xen_interrupt_controller_init(); + } + + for (i = 0; i < ISA_NUM_IRQS; i++) { + gsi_state->i8259_irq[i] = i8259[i]; + } + if (pci_enabled) { + ioapic_init(gsi_state); } - isa_bus_irqs(isa_irq); - pc_register_ferr_irq(isa_get_irq(13)); + pc_register_ferr_irq(gsi[13]); pc_vga_init(pci_enabled? pci_bus: NULL); + if (xen_enabled()) { + pci_create_simple(pci_bus, -1, "xen-platform"); + } + /* init basic PC hardware */ - pc_basic_device_init(isa_irq, &floppy_controller, &rtc_state); + pc_basic_device_init(gsi, &rtc_state, &floppy, xen_enabled()); for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; @@ -126,18 +186,14 @@ static void pc_init1(ram_addr_t ram_size, pci_nic_init_nofail(nd, "e1000", NULL); } - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } - - for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { - hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); - } - + ide_drive_get(hd, MAX_IDE_BUS); if (pci_enabled) { PCIDevice *dev; - dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); + if (xen_enabled()) { + dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); + } else { + dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); + } idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); } else { @@ -149,51 +205,34 @@ static void pc_init1(ram_addr_t ram_size, } } - audio_init(isa_irq, pci_enabled ? pci_bus : NULL); + audio_init(gsi, pci_enabled ? pci_bus : NULL); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, - idebus[0], idebus[1], floppy_controller, rtc_state); + floppy, idebus[0], idebus[1], rtc_state); if (pci_enabled && usb_enabled) { usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); } if (pci_enabled && acpi_enabled) { - uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ i2c_bus *smbus; - cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); + if (!xen_enabled()) { + cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); + } else { + cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1); + } smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, - isa_get_irq(9), *cmos_s3, *smi_irq, + gsi[9], *cmos_s3, *smi_irq, kvm_enabled()); - for (i = 0; i < 8; i++) { - DeviceState *eeprom; - eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); - qdev_prop_set_uint8(eeprom, "address", 0x50 + i); - qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256)); - qdev_init_nofail(eeprom); - } - } - - if (i440fx_state) { - i440fx_init_memory_mappings(i440fx_state); + smbus_eeprom_init(smbus, 8, NULL, 0); } if (pci_enabled) { pc_pci_device_init(pci_bus); } - - if (pci_enabled) { - svcamera_pci_init(pci_bus); - } - -#ifdef CONFIG_FFMPEG - if (pci_enabled) { - pci_codec_init(pci_bus); - } -#endif } static void pc_init_pci(ram_addr_t ram_size, @@ -203,9 +242,25 @@ static void pc_init_pci(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { - pc_init1(ram_size, boot_device, + pc_init1(get_system_memory(), + get_system_io(), + ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 1); + initrd_filename, cpu_model, 1, 1); +} + +static void pc_init_pci_no_kvmclock(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ + pc_init1(get_system_memory(), + get_system_io(), + ram_size, boot_device, + kernel_filename, kernel_cmdline, + initrd_filename, cpu_model, 1, 0); } static void pc_init_isa(ram_addr_t ram_size, @@ -217,13 +272,33 @@ static void pc_init_isa(ram_addr_t ram_size, { if (cpu_model == NULL) cpu_model = "486"; - pc_init1(ram_size, boot_device, + pc_init1(get_system_memory(), + get_system_io(), + ram_size, boot_device, kernel_filename, kernel_cmdline, - initrd_filename, cpu_model, 0); + initrd_filename, cpu_model, 0, 1); } -static QEMUMachine pc_machine = { - .name = "pc-0.14", +#ifdef CONFIG_XEN +static void pc_xen_hvm_init(ram_addr_t ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ + if (xen_hvm_init() != 0) { + hw_error("xen hardware virtual machine initialisation failed"); + } + pc_init_pci_no_kvmclock(ram_size, boot_device, + kernel_filename, kernel_cmdline, + initrd_filename, cpu_model); + xen_vcpu_init(); +} +#endif + +static QEMUMachine pc_machine_v1_0 = { + .name = "pc-1.0", .alias = "pc", .desc = "Standard PC", .init = pc_init_pci, @@ -231,10 +306,53 @@ static QEMUMachine pc_machine = { .is_default = 1, }; +static QEMUMachine pc_machine_v0_15 = { + .name = "pc-0.15", + .desc = "Standard PC", + .init = pc_init_pci, + .max_cpus = 255, + .is_default = 1, +}; + +static QEMUMachine pc_machine_v0_14 = { + .name = "pc-0.14", + .desc = "Standard PC", + .init = pc_init_pci, + .max_cpus = 255, + .compat_props = (GlobalProperty[]) { + { + .driver = "qxl", + .property = "revision", + .value = stringify(2), + },{ + .driver = "qxl-vga", + .property = "revision", + .value = stringify(2), + },{ + .driver = "virtio-blk-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-serial-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-net-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + }, + { /* end of list */ } + }, +}; + static QEMUMachine pc_machine_v0_13 = { .name = "pc-0.13", .desc = "Standard PC", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { @@ -253,6 +371,26 @@ static QEMUMachine pc_machine_v0_13 = { .driver = "PCI", .property = "command_serr_enable", .value = "off", + },{ + .driver = "virtio-blk-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-serial-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-net-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "AC97", + .property = "use_broken_id", + .value = stringify(1), }, { /* end of list */ } }, @@ -261,7 +399,7 @@ static QEMUMachine pc_machine_v0_13 = { static QEMUMachine pc_machine_v0_12 = { .name = "pc-0.12", .desc = "Standard PC", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { @@ -284,6 +422,26 @@ static QEMUMachine pc_machine_v0_12 = { .driver = "PCI", .property = "command_serr_enable", .value = "off", + },{ + .driver = "virtio-blk-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-serial-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-net-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "AC97", + .property = "use_broken_id", + .value = stringify(1), }, { /* end of list */ } } @@ -292,7 +450,7 @@ static QEMUMachine pc_machine_v0_12 = { static QEMUMachine pc_machine_v0_11 = { .name = "pc-0.11", .desc = "Standard PC, qemu 0.11", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { @@ -323,6 +481,26 @@ static QEMUMachine pc_machine_v0_11 = { .driver = "PCI", .property = "command_serr_enable", .value = "off", + },{ + .driver = "virtio-blk-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-serial-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-net-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "AC97", + .property = "use_broken_id", + .value = stringify(1), }, { /* end of list */ } } @@ -331,7 +509,7 @@ static QEMUMachine pc_machine_v0_11 = { static QEMUMachine pc_machine_v0_10 = { .name = "pc-0.10", .desc = "Standard PC, qemu 0.10", - .init = pc_init_pci, + .init = pc_init_pci_no_kvmclock, .max_cpus = 255, .compat_props = (GlobalProperty[]) { { @@ -374,6 +552,26 @@ static QEMUMachine pc_machine_v0_10 = { .driver = "PCI", .property = "command_serr_enable", .value = "off", + },{ + .driver = "virtio-blk-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-serial-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-net-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "AC97", + .property = "use_broken_id", + .value = stringify(1), }, { /* end of list */ } }, @@ -386,14 +584,29 @@ static QEMUMachine isapc_machine = { .max_cpus = 1, }; +#ifdef CONFIG_XEN +static QEMUMachine xenfv_machine = { + .name = "xenfv", + .desc = "Xen Fully-virtualized PC", + .init = pc_xen_hvm_init, + .max_cpus = HVM_MAX_VCPUS, + .default_machine_opts = "accel=xen", +}; +#endif + static void pc_machine_init(void) { - qemu_register_machine(&pc_machine); + qemu_register_machine(&pc_machine_v1_0); + qemu_register_machine(&pc_machine_v0_15); + qemu_register_machine(&pc_machine_v0_14); qemu_register_machine(&pc_machine_v0_13); qemu_register_machine(&pc_machine_v0_12); qemu_register_machine(&pc_machine_v0_11); qemu_register_machine(&pc_machine_v0_10); qemu_register_machine(&isapc_machine); +#ifdef CONFIG_XEN + qemu_register_machine(&xenfv_machine); +#endif } machine_init(pc_machine_init); diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 478fe9b..12f61fe 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -91,7 +91,8 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, */ dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); dinfo->bus = scsibus->busnr; - scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit, false); + scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit, + false, -1); if (!scsidev) { return -1; } @@ -127,7 +128,8 @@ void drive_hot_add(Monitor *mon, const QDict *qdict) if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) { goto err; } - dev = pci_find_device(pci_find_root_bus(dom), pci_bus, slot, 0); + dev = pci_find_device(pci_find_root_bus(dom), pci_bus, + PCI_DEVFN(slot, 0)); if (!dev) { monitor_printf(mon, "no pci device with address %s\n", pci_addr); goto err; @@ -277,7 +279,7 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr) return -1; } - d = pci_find_device(pci_find_root_bus(dom), bus, slot, 0); + d = pci_find_device(pci_find_root_bus(dom), bus, PCI_DEVFN(slot, 0)); if (!d) { monitor_printf(mon, "slot %d empty\n", slot); return -1; diff --git a/hw/pci-stub.c b/hw/pci-stub.c index c5a0aa8..636171c 100644 --- a/hw/pci-stub.c +++ b/hw/pci-stub.c @@ -1,5 +1,5 @@ /* - * PCI stubs for plathome that doesn't support pci bus. + * PCI stubs for platforms that don't support pci bus. * * Copyright (c) 2010 Isaku Yamahata * VA Linux Systems Japan K.K. @@ -21,20 +21,17 @@ #include "sysemu.h" #include "monitor.h" #include "pci.h" +#include "qmp-commands.h" -static void pci_error_message(Monitor *mon) +PciInfoList *qmp_query_pci(Error **errp) { - monitor_printf(mon, "PCI devices not supported\n"); + error_set(errp, QERR_UNSUPPORTED); + return NULL; } -void do_pci_info(Monitor *mon, QObject **ret_data) -{ - pci_error_message(mon); -} - -void do_pci_info_print(Monitor *mon, const QObject *data) +static void pci_error_message(Monitor *mon) { - pci_error_message(mon); + monitor_printf(mon, "PCI devices not supported\n"); } int do_pcie_aer_inejct_error(Monitor *mon, diff --git a/hw/pci.c b/hw/pci.c index d5bbba9..399227f 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -29,8 +29,8 @@ #include "net.h" #include "sysemu.h" #include "loader.h" -#include "qemu-objects.h" #include "range.h" +#include "qmp-commands.h" //#define DEBUG_PCI #ifdef DEBUG_PCI @@ -126,6 +126,13 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); } +int pci_bus_get_irq_level(PCIBus *bus, int irq_num) +{ + assert(irq_num >= 0); + assert(irq_num < bus->nirq); + return !!bus->irq_count[irq_num]; +} + /* Update interrupt status bit in config space on interrupt * state change. */ static void pci_update_irq_status(PCIDevice *dev) @@ -161,7 +168,7 @@ void pci_device_reset(PCIDevice *dev) dev->irq_state = 0; pci_update_irq_status(dev); pci_device_deassert_intx(dev); - /* Clear all writeable bits */ + /* Clear all writable bits */ pci_word_test_and_clear_mask(dev->config + PCI_COMMAND, pci_get_word(dev->wmask + PCI_COMMAND) | pci_get_word(dev->w1cmask + PCI_COMMAND)); @@ -216,7 +223,7 @@ static int pcibus_reset(BusState *qbus) static void pci_host_bus_register(int domain, PCIBus *bus) { struct PCIHostBus *host; - host = qemu_mallocz(sizeof(*host)); + host = g_malloc0(sizeof(*host)); host->domain = domain; host->bus = bus; QLIST_INSERT_HEAD(&host_buses, host, next); @@ -256,11 +263,16 @@ int pci_find_domain(const PCIBus *bus) } void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, - const char *name, int devfn_min) + const char *name, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min) { qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name); assert(PCI_FUNC(devfn_min) == 0); bus->devfn_min = devfn_min; + bus->address_space_mem = address_space_mem; + bus->address_space_io = address_space_io; /* host bridge */ QLIST_INIT(&bus->child); @@ -269,13 +281,17 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, vmstate_register(NULL, -1, &vmstate_pcibus, bus); } -PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min) +PCIBus *pci_bus_new(DeviceState *parent, const char *name, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min) { PCIBus *bus; - bus = qemu_mallocz(sizeof(*bus)); + bus = g_malloc0(sizeof(*bus)); bus->qbus.qdev_allocated = 1; - pci_bus_new_inplace(bus, parent, name, devfn_min); + pci_bus_new_inplace(bus, parent, name, address_space_mem, + address_space_io, devfn_min); return bus; } @@ -286,7 +302,7 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, bus->map_irq = map_irq; bus->irq_opaque = irq_opaque; bus->nirq = nirq; - bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0])); + bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0])); } void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev) @@ -296,18 +312,17 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev) bus->hotplug_qdev = qdev; } -void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base) -{ - bus->mem_base = base; -} - PCIBus *pci_register_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, - void *irq_opaque, int devfn_min, int nirq) + void *irq_opaque, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min, int nirq) { PCIBus *bus; - bus = pci_bus_new(parent, name, devfn_min); + bus = pci_bus_new(parent, name, address_space_mem, + address_space_io, devfn_min); pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq); return bus; } @@ -326,13 +341,13 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size) int i; assert(size == pci_config_size(s)); - config = qemu_malloc(size); + config = g_malloc(size); qemu_get_buffer(f, config, size); for (i = 0; i < size; ++i) { if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i] & ~s->w1cmask[i]) { - qemu_free(config); + g_free(config); return -EINVAL; } } @@ -340,7 +355,7 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size) pci_update_mappings(s); - qemu_free(config); + g_free(config); return 0; } @@ -558,7 +573,7 @@ PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr) return NULL; } - *devfnp = slot << 3; + *devfnp = PCI_DEVFN(slot, 0); return pci_find_bus(pci_find_root_bus(dom), bus); } @@ -700,29 +715,30 @@ static void pci_config_alloc(PCIDevice *pci_dev) { int config_size = pci_config_size(pci_dev); - pci_dev->config = qemu_mallocz(config_size); - pci_dev->cmask = qemu_mallocz(config_size); - pci_dev->wmask = qemu_mallocz(config_size); - pci_dev->w1cmask = qemu_mallocz(config_size); - pci_dev->used = qemu_mallocz(config_size); + pci_dev->config = g_malloc0(config_size); + pci_dev->cmask = g_malloc0(config_size); + pci_dev->wmask = g_malloc0(config_size); + pci_dev->w1cmask = g_malloc0(config_size); + pci_dev->used = g_malloc0(config_size); } static void pci_config_free(PCIDevice *pci_dev) { - qemu_free(pci_dev->config); - qemu_free(pci_dev->cmask); - qemu_free(pci_dev->wmask); - qemu_free(pci_dev->w1cmask); - qemu_free(pci_dev->used); + g_free(pci_dev->config); + g_free(pci_dev->cmask); + g_free(pci_dev->wmask); + g_free(pci_dev->w1cmask); + g_free(pci_dev->used); } /* -1 for devfn means auto assign */ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, const char *name, int devfn, - PCIConfigReadFunc *config_read, - PCIConfigWriteFunc *config_write, - bool is_bridge) + const PCIDeviceInfo *info) { + PCIConfigReadFunc *config_read = info->config_read; + PCIConfigWriteFunc *config_write = info->config_write; + if (devfn < 0) { for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices); devfn += PCI_FUNC_MAX) { @@ -743,13 +759,29 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, pci_dev->irq_state = 0; pci_config_alloc(pci_dev); - if (!is_bridge) { - pci_set_default_subsystem_id(pci_dev); + pci_config_set_vendor_id(pci_dev->config, info->vendor_id); + pci_config_set_device_id(pci_dev->config, info->device_id); + pci_config_set_revision(pci_dev->config, info->revision); + pci_config_set_class(pci_dev->config, info->class_id); + + if (!info->is_bridge) { + if (info->subsystem_vendor_id || info->subsystem_id) { + pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, + info->subsystem_vendor_id); + pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, + info->subsystem_id); + } else { + pci_set_default_subsystem_id(pci_dev); + } + } else { + /* subsystem_vendor_id/subsystem_id are only for header type 0 */ + assert(!info->subsystem_vendor_id); + assert(!info->subsystem_id); } pci_init_cmask(pci_dev); pci_init_wmask(pci_dev); pci_init_w1cmask(pci_dev); - if (is_bridge) { + if (info->is_bridge) { pci_init_wmask_bridge(pci_dev); } if (pci_init_multifunction(bus, pci_dev)) { @@ -776,29 +808,26 @@ static void do_pci_unregister_device(PCIDevice *pci_dev) pci_config_free(pci_dev); } +/* TODO: obsolete. eliminate this once all pci devices are qdevifed. */ PCIDevice *pci_register_device(PCIBus *bus, const char *name, int instance_size, int devfn, PCIConfigReadFunc *config_read, PCIConfigWriteFunc *config_write) { PCIDevice *pci_dev; + PCIDeviceInfo info = { + .config_read = config_read, + .config_write = config_write, + }; - pci_dev = qemu_mallocz(instance_size); - pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, - config_read, config_write, - PCI_HEADER_TYPE_NORMAL); + pci_dev = g_malloc0(instance_size); + pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info); if (pci_dev == NULL) { hw_error("PCI: can't register device\n"); } return pci_dev; } -static target_phys_addr_t pci_to_cpu_addr(PCIBus *bus, - target_phys_addr_t addr) -{ - return addr + bus->mem_base; -} - static void pci_unregister_io_regions(PCIDevice *pci_dev) { PCIIORegion *r; @@ -808,14 +837,7 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev) r = &pci_dev->io_regions[i]; if (!r->size || r->addr == PCI_BAR_UNMAPPED) continue; - if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { - isa_unassign_ioport(r->addr, r->filtered_size); - } else { - cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, - r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); - } + memory_region_del_subregion(r->address_space, r->memory); } } @@ -832,18 +854,18 @@ static int pci_unregister_device(DeviceState *dev) pci_unregister_io_regions(pci_dev); pci_del_option_rom(pci_dev); - qemu_free(pci_dev->romfile); + g_free(pci_dev->romfile); do_pci_unregister_device(pci_dev); return 0; } void pci_register_bar(PCIDevice *pci_dev, int region_num, - pcibus_t size, uint8_t type, - PCIMapIORegionFunc *map_func) + uint8_t type, MemoryRegion *memory) { PCIIORegion *r; uint32_t addr; uint64_t wmask; + pcibus_t size = memory_region_size(memory); assert(region_num >= 0); assert(region_num < PCI_NUM_REGIONS); @@ -856,14 +878,13 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, r = &pci_dev->io_regions[region_num]; r->addr = PCI_BAR_UNMAPPED; r->size = size; - r->filtered_size = size; r->type = type; - r->map_func = map_func; + r->memory = NULL; wmask = ~(size - 1); addr = pci_bar(pci_dev, region_num); if (region_num == PCI_ROM_SLOT) { - /* ROM enable bit is writeable */ + /* ROM enable bit is writable */ wmask |= PCI_ROM_ADDRESS_ENABLE; } pci_set_long(pci_dev->config + addr, type); @@ -875,41 +896,16 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff); pci_set_long(pci_dev->cmask + addr, 0xffffffff); } + pci_dev->io_regions[region_num].memory = memory; + pci_dev->io_regions[region_num].address_space + = type & PCI_BASE_ADDRESS_SPACE_IO + ? pci_dev->bus->address_space_io + : pci_dev->bus->address_space_mem; } -static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size, - uint8_t type) +pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num) { - pcibus_t base = *addr; - pcibus_t limit = *addr + *size - 1; - PCIDevice *br; - - for (br = d->bus->parent_dev; br; br = br->bus->parent_dev) { - uint16_t cmd = pci_get_word(d->config + PCI_COMMAND); - - if (type & PCI_BASE_ADDRESS_SPACE_IO) { - if (!(cmd & PCI_COMMAND_IO)) { - goto no_map; - } - } else { - if (!(cmd & PCI_COMMAND_MEMORY)) { - goto no_map; - } - } - - base = MAX(base, pci_bridge_get_base(br, type)); - limit = MIN(limit, pci_bridge_get_limit(br, type)); - } - - if (base > limit) { - goto no_map; - } - *addr = base; - *size = limit - base + 1; - return; -no_map: - *addr = PCI_BAR_UNMAPPED; - *size = 0; + return pci_dev->io_regions[region_num].addr; } static pcibus_t pci_bar_address(PCIDevice *d, @@ -981,7 +977,7 @@ static void pci_update_mappings(PCIDevice *d) { PCIIORegion *r; int i; - pcibus_t new_addr, filtered_size; + pcibus_t new_addr; for(i = 0; i < PCI_NUM_REGIONS; i++) { r = &d->io_regions[i]; @@ -992,51 +988,18 @@ static void pci_update_mappings(PCIDevice *d) new_addr = pci_bar_address(d, i, r->type, r->size); - /* bridge filtering */ - filtered_size = r->size; - if (new_addr != PCI_BAR_UNMAPPED) { - pci_bridge_filter(d, &new_addr, &filtered_size, r->type); - } - /* This bar isn't changed */ - if (new_addr == r->addr && filtered_size == r->filtered_size) + if (new_addr == r->addr) continue; /* now do the real mapping */ if (r->addr != PCI_BAR_UNMAPPED) { - if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - int class; - /* NOTE: specific hack for IDE in PC case: - only one byte must be mapped. */ - class = pci_get_word(d->config + PCI_CLASS_DEVICE); - if (class == 0x0101 && r->size == 4) { - isa_unassign_ioport(r->addr + 2, 1); - } else { - isa_unassign_ioport(r->addr, r->filtered_size); - } - } else { - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); - qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); - } + memory_region_del_subregion(r->address_space, r->memory); } r->addr = new_addr; - r->filtered_size = filtered_size; if (r->addr != PCI_BAR_UNMAPPED) { - /* - * TODO: currently almost all the map funcions assumes - * filtered_size == size and addr & ~(size - 1) == addr. - * However with bridge filtering, they aren't always true. - * Teach them such cases, such that filtered_size < size and - * addr & (size - 1) != 0. - */ - if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - r->map_func(d, i, r->addr, r->filtered_size, r->type); - } else { - r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr), - r->filtered_size, r->type); - } + memory_region_add_subregion_overlap(r->address_space, + r->addr, r->memory, 1); } } } @@ -1064,8 +1027,7 @@ uint32_t pci_default_read_config(PCIDevice *d, uint32_t address, int len) { uint32_t val = 0; - assert(len == 1 || len == 2 || len == 4); - len = MIN(len, pci_config_size(d) - address); + memcpy(&val, d->config + address, len); return le32_to_cpu(val); } @@ -1073,9 +1035,8 @@ uint32_t pci_default_read_config(PCIDevice *d, void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) { int i, was_irq_disabled = pci_irq_disabled(d); - uint32_t config_size = pci_config_size(d); - for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) { + for (i = 0; i < l; val >>= 8, ++i) { uint8_t wmask = d->wmask[addr + i]; uint8_t w1cmask = d->w1cmask[addr + i]; assert(!(wmask & w1cmask)); @@ -1145,6 +1106,7 @@ static const pci_class_desc pci_class_descriptions[] = { 0x0400, "Video controller", "video"}, { 0x0401, "Audio controller", "sound"}, { 0x0402, "Phone"}, + { 0x0403, "Audio controller", "sound"}, { 0x0480, "Multimedia controller"}, { 0x0500, "RAM controller", "memory"}, { 0x0501, "Flash controller", "flash"}, @@ -1202,276 +1164,194 @@ void pci_for_each_device(PCIBus *bus, int bus_num, } } -static void pci_device_print(Monitor *mon, QDict *device) +static const pci_class_desc *get_class_desc(int class) { - QDict *qdict; - QListEntry *entry; - uint64_t addr, size; - - monitor_printf(mon, " Bus %2" PRId64 ", ", qdict_get_int(device, "bus")); - monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n", - qdict_get_int(device, "slot"), - qdict_get_int(device, "function")); - monitor_printf(mon, " "); - - qdict = qdict_get_qdict(device, "class_info"); - if (qdict_haskey(qdict, "desc")) { - monitor_printf(mon, "%s", qdict_get_str(qdict, "desc")); - } else { - monitor_printf(mon, "Class %04" PRId64, qdict_get_int(qdict, "class")); - } - - qdict = qdict_get_qdict(device, "id"); - monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n", - qdict_get_int(qdict, "device"), - qdict_get_int(qdict, "vendor")); + const pci_class_desc *desc; - if (qdict_haskey(device, "irq")) { - monitor_printf(mon, " IRQ %" PRId64 ".\n", - qdict_get_int(device, "irq")); + desc = pci_class_descriptions; + while (desc->desc && class != desc->class) { + desc++; } - if (qdict_haskey(device, "pci_bridge")) { - QDict *info; - - qdict = qdict_get_qdict(device, "pci_bridge"); - - info = qdict_get_qdict(qdict, "bus"); - monitor_printf(mon, " BUS %" PRId64 ".\n", - qdict_get_int(info, "number")); - monitor_printf(mon, " secondary bus %" PRId64 ".\n", - qdict_get_int(info, "secondary")); - monitor_printf(mon, " subordinate bus %" PRId64 ".\n", - qdict_get_int(info, "subordinate")); + return desc; +} - info = qdict_get_qdict(qdict, "io_range"); - monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n", - qdict_get_int(info, "base"), - qdict_get_int(info, "limit")); +static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num); - info = qdict_get_qdict(qdict, "memory_range"); - monitor_printf(mon, - " memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n", - qdict_get_int(info, "base"), - qdict_get_int(info, "limit")); +static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev) +{ + PciMemoryRegionList *head = NULL, *cur_item = NULL; + int i; - info = qdict_get_qdict(qdict, "prefetchable_range"); - monitor_printf(mon, " prefetchable memory range " - "[0x%08"PRIx64", 0x%08"PRIx64"]\n", - qdict_get_int(info, "base"), - qdict_get_int(info, "limit")); - } + for (i = 0; i < PCI_NUM_REGIONS; i++) { + const PCIIORegion *r = &dev->io_regions[i]; + PciMemoryRegionList *region; - QLIST_FOREACH_ENTRY(qdict_get_qlist(device, "regions"), entry) { - qdict = qobject_to_qdict(qlist_entry_obj(entry)); - monitor_printf(mon, " BAR%d: ", (int) qdict_get_int(qdict, "bar")); + if (!r->size) { + continue; + } - addr = qdict_get_int(qdict, "address"); - size = qdict_get_int(qdict, "size"); + region = g_malloc0(sizeof(*region)); + region->value = g_malloc0(sizeof(*region->value)); - if (!strcmp(qdict_get_str(qdict, "type"), "io")) { - monitor_printf(mon, "I/O at 0x%04"FMT_PCIBUS - " [0x%04"FMT_PCIBUS"].\n", - addr, addr + size - 1); + if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { + region->value->type = g_strdup("io"); } else { - monitor_printf(mon, "%d bit%s memory at 0x%08"FMT_PCIBUS - " [0x%08"FMT_PCIBUS"].\n", - qdict_get_bool(qdict, "mem_type_64") ? 64 : 32, - qdict_get_bool(qdict, "prefetch") ? - " prefetchable" : "", addr, addr + size - 1); + region->value->type = g_strdup("memory"); + region->value->has_prefetch = true; + region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH); + region->value->has_mem_type_64 = true; + region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64); } - } - monitor_printf(mon, " id \"%s\"\n", qdict_get_str(device, "qdev_id")); + region->value->bar = i; + region->value->address = r->addr; + region->value->size = r->size; - if (qdict_haskey(device, "pci_bridge")) { - qdict = qdict_get_qdict(device, "pci_bridge"); - if (qdict_haskey(qdict, "devices")) { - QListEntry *dev; - QLIST_FOREACH_ENTRY(qdict_get_qlist(qdict, "devices"), dev) { - pci_device_print(mon, qobject_to_qdict(qlist_entry_obj(dev))); - } + /* XXX: waiting for the qapi to support GSList */ + if (!cur_item) { + head = cur_item = region; + } else { + cur_item->next = region; + cur_item = region; } } -} - -void do_pci_info_print(Monitor *mon, const QObject *data) -{ - QListEntry *bus, *dev; - QLIST_FOREACH_ENTRY(qobject_to_qlist(data), bus) { - QDict *qdict = qobject_to_qdict(qlist_entry_obj(bus)); - QLIST_FOREACH_ENTRY(qdict_get_qlist(qdict, "devices"), dev) { - pci_device_print(mon, qobject_to_qdict(qlist_entry_obj(dev))); - } - } + return head; } -static QObject *pci_get_dev_class(const PCIDevice *dev) +static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus, + int bus_num) { - int class; - const pci_class_desc *desc; + PciBridgeInfo *info; - class = pci_get_word(dev->config + PCI_CLASS_DEVICE); - desc = pci_class_descriptions; - while (desc->desc && class != desc->class) - desc++; + info = g_malloc0(sizeof(*info)); - if (desc->desc) { - return qobject_from_jsonf("{ 'desc': %s, 'class': %d }", - desc->desc, class); - } else { - return qobject_from_jsonf("{ 'class': %d }", class); - } -} + info->bus.number = dev->config[PCI_PRIMARY_BUS]; + info->bus.secondary = dev->config[PCI_SECONDARY_BUS]; + info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS]; -static QObject *pci_get_dev_id(const PCIDevice *dev) -{ - return qobject_from_jsonf("{ 'device': %d, 'vendor': %d }", - pci_get_word(dev->config + PCI_VENDOR_ID), - pci_get_word(dev->config + PCI_DEVICE_ID)); -} + info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range)); + info->bus.io_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO); + info->bus.io_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO); -static QObject *pci_get_regions_list(const PCIDevice *dev) -{ - int i; - QList *regions_list; - - regions_list = qlist_new(); - - for (i = 0; i < PCI_NUM_REGIONS; i++) { - QObject *obj; - const PCIIORegion *r = &dev->io_regions[i]; + info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range)); + info->bus.memory_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY); + info->bus.memory_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY); - if (!r->size) { - continue; - } + info->bus.prefetchable_range = g_malloc0(sizeof(*info->bus.prefetchable_range)); + info->bus.prefetchable_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); + info->bus.prefetchable_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); - if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - obj = qobject_from_jsonf("{ 'bar': %d, 'type': 'io', " - "'address': %" PRId64 ", " - "'size': %" PRId64 " }", - i, r->addr, r->size); - } else { - int mem_type_64 = r->type & PCI_BASE_ADDRESS_MEM_TYPE_64; - - obj = qobject_from_jsonf("{ 'bar': %d, 'type': 'memory', " - "'mem_type_64': %i, 'prefetch': %i, " - "'address': %" PRId64 ", " - "'size': %" PRId64 " }", - i, mem_type_64, - r->type & PCI_BASE_ADDRESS_MEM_PREFETCH, - r->addr, r->size); + if (dev->config[PCI_SECONDARY_BUS] != 0) { + PCIBus *child_bus = pci_find_bus(bus, dev->config[PCI_SECONDARY_BUS]); + if (child_bus) { + info->has_devices = true; + info->devices = qmp_query_pci_devices(child_bus, dev->config[PCI_SECONDARY_BUS]); } - - qlist_append_obj(regions_list, obj); } - return QOBJECT(regions_list); + return info; } -static QObject *pci_get_devices_list(PCIBus *bus, int bus_num); - -static QObject *pci_get_dev_dict(PCIDevice *dev, PCIBus *bus, int bus_num) +static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus, + int bus_num) { + const pci_class_desc *desc; + PciDeviceInfo *info; uint8_t type; - QObject *obj; + int class; - obj = qobject_from_jsonf("{ 'bus': %d, 'slot': %d, 'function': %d," "'class_info': %p, 'id': %p, 'regions': %p," - " 'qdev_id': %s }", - bus_num, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), - pci_get_dev_class(dev), pci_get_dev_id(dev), - pci_get_regions_list(dev), - dev->qdev.id ? dev->qdev.id : ""); + info = g_malloc0(sizeof(*info)); + info->bus = bus_num; + info->slot = PCI_SLOT(dev->devfn); + info->function = PCI_FUNC(dev->devfn); + + class = pci_get_word(dev->config + PCI_CLASS_DEVICE); + info->class_info.class = class; + desc = get_class_desc(class); + if (desc->desc) { + info->class_info.has_desc = true; + info->class_info.desc = g_strdup(desc->desc); + } + + info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID); + info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID); + info->regions = qmp_query_pci_regions(dev); + info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : ""); if (dev->config[PCI_INTERRUPT_PIN] != 0) { - QDict *qdict = qobject_to_qdict(obj); - qdict_put(qdict, "irq", qint_from_int(dev->config[PCI_INTERRUPT_LINE])); + info->has_irq = true; + info->irq = dev->config[PCI_INTERRUPT_LINE]; } type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION; if (type == PCI_HEADER_TYPE_BRIDGE) { - QDict *qdict; - QObject *pci_bridge; - - pci_bridge = qobject_from_jsonf("{ 'bus': " - "{ 'number': %d, 'secondary': %d, 'subordinate': %d }, " - "'io_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "}, " - "'memory_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "}, " - "'prefetchable_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "} }", - dev->config[PCI_PRIMARY_BUS], dev->config[PCI_SECONDARY_BUS], - dev->config[PCI_SUBORDINATE_BUS], - pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO), - pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO), - pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY), - pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY), - pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY | - PCI_BASE_ADDRESS_MEM_PREFETCH), - pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY | - PCI_BASE_ADDRESS_MEM_PREFETCH)); - - if (dev->config[PCI_SECONDARY_BUS] != 0) { - PCIBus *child_bus = pci_find_bus(bus, dev->config[PCI_SECONDARY_BUS]); - - if (child_bus) { - qdict = qobject_to_qdict(pci_bridge); - qdict_put_obj(qdict, "devices", - pci_get_devices_list(child_bus, - dev->config[PCI_SECONDARY_BUS])); - } - } - qdict = qobject_to_qdict(obj); - qdict_put_obj(qdict, "pci_bridge", pci_bridge); + info->has_pci_bridge = true; + info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num); } - return obj; + return info; } -static QObject *pci_get_devices_list(PCIBus *bus, int bus_num) +static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num) { - int devfn; + PciDeviceInfoList *info, *head = NULL, *cur_item = NULL; PCIDevice *dev; - QList *dev_list; - - dev_list = qlist_new(); + int devfn; for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { dev = bus->devices[devfn]; if (dev) { - qlist_append_obj(dev_list, pci_get_dev_dict(dev, bus, bus_num)); + info = g_malloc0(sizeof(*info)); + info->value = qmp_query_pci_device(dev, bus, bus_num); + + /* XXX: waiting for the qapi to support GSList */ + if (!cur_item) { + head = cur_item = info; + } else { + cur_item->next = info; + cur_item = info; + } } } - return QOBJECT(dev_list); + return head; } -static QObject *pci_get_bus_dict(PCIBus *bus, int bus_num) +static PciInfo *qmp_query_pci_bus(PCIBus *bus, int bus_num) { + PciInfo *info = NULL; + bus = pci_find_bus(bus, bus_num); if (bus) { - return qobject_from_jsonf("{ 'bus': %d, 'devices': %p }", - bus_num, pci_get_devices_list(bus, bus_num)); + info = g_malloc0(sizeof(*info)); + info->bus = bus_num; + info->devices = qmp_query_pci_devices(bus, bus_num); } - return NULL; + return info; } -void do_pci_info(Monitor *mon, QObject **ret_data) +PciInfoList *qmp_query_pci(Error **errp) { - QList *bus_list; + PciInfoList *info, *head = NULL, *cur_item = NULL; struct PCIHostBus *host; - bus_list = qlist_new(); - QLIST_FOREACH(host, &host_buses, next) { - QObject *obj = pci_get_bus_dict(host->bus, 0); - if (obj) { - qlist_append_obj(bus_list, obj); + info = g_malloc0(sizeof(*info)); + info->value = qmp_query_pci_bus(host->bus, 0); + + /* XXX: waiting for the qapi to support GSList */ + if (!cur_item) { + head = cur_item = info; + } else { + cur_item->next = info; + cur_item = info; } } - *ret_data = QOBJECT(bus_list); + return head; } static const char * const pci_nic_models[] = { @@ -1543,22 +1423,6 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model, return res; } -static void pci_bridge_update_mappings_fn(PCIBus *b, PCIDevice *d) -{ - pci_update_mappings(d); -} - -void pci_bridge_update_mappings(PCIBus *b) -{ - PCIBus *child; - - pci_for_each_device_under_bus(b, pci_bridge_update_mappings_fn); - - QLIST_FOREACH(child, &b->child, sibling) { - pci_bridge_update_mappings(child); - } -} - /* Whether a given bus number is in range of the secondary * bus of the given bridge device. */ static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num) @@ -1603,14 +1467,14 @@ PCIBus *pci_find_bus(PCIBus *bus, int bus_num) return NULL; } -PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function) +PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn) { bus = pci_find_bus(bus, bus_num); if (!bus) return NULL; - return bus->devices[PCI_DEVFN(slot, function)]; + return bus->devices[devfn]; } static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) @@ -1618,7 +1482,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) PCIDevice *pci_dev = (PCIDevice *)qdev; PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev); PCIBus *bus; - int devfn, rc; + int rc; bool is_default_rom; /* initialize cap_present for pci_is_express() and pci_config_size() */ @@ -1627,10 +1491,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) } bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev)); - devfn = pci_dev->devfn; - pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn, - info->config_read, info->config_write, - info->is_bridge); + pci_dev = do_pci_register_device(pci_dev, bus, base->name, + pci_dev->devfn, info); if (pci_dev == NULL) return -1; if (qdev->hotplugged && info->no_hotplug) { @@ -1638,16 +1500,18 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) do_pci_unregister_device(pci_dev); return -1; } - rc = info->init(pci_dev); - if (rc != 0) { - do_pci_unregister_device(pci_dev); - return rc; + if (info->init) { + rc = info->init(pci_dev); + if (rc != 0) { + do_pci_unregister_device(pci_dev); + return rc; + } } /* rom loading */ is_default_rom = false; if (pci_dev->romfile == NULL && info->romfile != NULL) { - pci_dev->romfile = qemu_strdup(info->romfile); + pci_dev->romfile = g_strdup(info->romfile); is_default_rom = true; } pci_add_option_rom(pci_dev, is_default_rom); @@ -1708,6 +1572,21 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, return DO_UPCAST(PCIDevice, qdev, dev); } +PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, + bool multifunction, + const char *name) +{ + DeviceState *dev; + + dev = qdev_try_create(&bus->qbus, name); + if (!dev) { + return NULL; + } + qdev_prop_set_uint32(dev, "addr", devfn); + qdev_prop_set_bit(dev, "multifunction", multifunction); + return DO_UPCAST(PCIDevice, qdev, dev); +} + PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name) @@ -1727,6 +1606,11 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name) return pci_create_simple_multifunction(bus, devfn, false, name); } +PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name) +{ + return pci_try_create_multifunction(bus, devfn, false, name); +} + static int pci_find_space(PCIDevice *pdev, uint8_t size) { int config_size = pci_config_size(pdev); @@ -1758,9 +1642,23 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id, return next; } -static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type) +static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset) { - cpu_register_physical_memory(addr, size, pdev->rom_offset); + uint8_t next, prev, found = 0; + + if (!(pdev->used[offset])) { + return 0; + } + + assert(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST); + + for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]); + prev = next + PCI_CAP_LIST_NEXT) { + if (next <= offset && next > found) { + found = next; + } + } + return found; } /* Patch the PCI vendor and device ids in a PCI rom image if necessary. @@ -1848,13 +1746,14 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom) path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile); if (path == NULL) { - path = qemu_strdup(pdev->romfile); + path = g_strdup(pdev->romfile); } size = get_image_size(path); if (size < 0) { error_report("%s: failed to find romfile \"%s\"", __FUNCTION__, pdev->romfile); + g_free(path); return -1; } if (size & (size - 1)) { @@ -1865,30 +1764,31 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom) snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name); else snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name); - pdev->rom_offset = qemu_ram_alloc(&pdev->qdev, name, size); - - ptr = qemu_get_ram_ptr(pdev->rom_offset); + pdev->has_rom = true; + memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size); + ptr = memory_region_get_ram_ptr(&pdev->rom); load_image(path, ptr); - qemu_free(path); + g_free(path); if (is_default_rom) { /* Only the default rom images will be patched (if needed). */ pci_patch_ids(pdev, ptr, size); } - pci_register_bar(pdev, PCI_ROM_SLOT, size, - 0, pci_map_option_rom); + qemu_put_ram_ptr(ptr); + + pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom); return 0; } static void pci_del_option_rom(PCIDevice *pdev) { - if (!pdev->rom_offset) + if (!pdev->has_rom) return; - qemu_ram_free(pdev->rom_offset); - pdev->rom_offset = 0; + memory_region_destroy(&pdev->rom); + pdev->has_rom = false; } /* @@ -1902,11 +1802,30 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size) { uint8_t *config; + int i, overlapping_cap; + if (!offset) { offset = pci_find_space(pdev, size); if (!offset) { return -ENOSPC; } + } else { + /* Verify that capabilities don't overlap. Note: device assignment + * depends on this check to verify that the device is not broken. + * Should never trigger for emulated devices, but it's helpful + * for debugging these. */ + for (i = offset; i < offset + size; i++) { + overlapping_cap = pci_find_capability_at_offset(pdev, i); + if (overlapping_cap) { + fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " + "Attempt to add PCI capability %x at offset " + "%x overlaps existing capability %x at offset %x\n", + pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + cap_id, offset, overlapping_cap, i); + return -EINVAL; + } + } } config = pdev->config + offset; @@ -1929,7 +1848,7 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) if (!offset) return; pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT]; - /* Make capability writeable again */ + /* Make capability writable again */ memset(pdev->wmask + offset, 0xff, size); memset(pdev->w1cmask + offset, 0, size); /* Clear cmask as device-specific registers can't be checked */ @@ -1940,12 +1859,6 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST; } -/* Reserve space for capability at a known offset (to call after load). */ -void pci_reserve_capability(PCIDevice *pdev, uint8_t offset, uint8_t size) -{ - memset(pdev->used + offset, 0xff, size); -} - uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id) { return pci_find_capability_list(pdev, cap_id, NULL); @@ -2058,7 +1971,7 @@ static char *pcibus_get_dev_path(DeviceState *dev) path_len = domain_len + slot_len * slot_depth; /* Allocate memory, fill in the terminating null byte. */ - path = qemu_malloc(path_len + 1 /* For '\0' */); + path = g_malloc(path_len + 1 /* For '\0' */); path[path_len] = '\0'; /* First field is the domain. */ @@ -2115,3 +2028,13 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev) return rc; } + +MemoryRegion *pci_address_space(PCIDevice *dev) +{ + return dev->bus->address_space_mem; +} + +MemoryRegion *pci_address_space_io(PCIDevice *dev) +{ + return dev->bus->address_space_io; +} diff --git a/hw/pci.h b/hw/pci.h index e086064..b0473b0 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -2,9 +2,10 @@ #define QEMU_PCI_H #include "qemu-common.h" -#include "qobject.h" #include "qdev.h" +#include "memory.h" +#include "dma.h" /* PCI includes legacy ISA access. */ #include "isa.h" @@ -16,6 +17,7 @@ #define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) #define PCI_FUNC(devfn) ((devfn) & 0x07) +#define PCI_SLOT_MAX 32 #define PCI_FUNC_MAX 8 /* Class, Vendor and Device IDs from Linux's pci_ids.h */ @@ -73,7 +75,8 @@ #define PCI_DEVICE_ID_VIRTIO_BLOCK 0x1001 #define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002 #define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003 -#define PCI_DEVICE_ID_VIRTIO_EXAMPLE 0x1010 + +#define PCI_DEVICE_ID_VIRTIO_GL 0x1006 #define FMT_PCIBUS PRIx64 @@ -89,9 +92,9 @@ typedef struct PCIIORegion { pcibus_t addr; /* current PCI mapping address. -1 means not mapped */ #define PCI_BAR_UNMAPPED (~(pcibus_t)0) pcibus_t size; - pcibus_t filtered_size; uint8_t type; - PCIMapIORegionFunc *map_func; + MemoryRegion *memory; + MemoryRegion *address_space; } PCIIORegion; #define PCI_ROM_SLOT 6 @@ -131,7 +134,7 @@ struct PCIDevice { /* PCI config space */ uint8_t *config; - /* Used to enable config checks on load. Note that writeable bits are + /* Used to enable config checks on load. Note that writable bits are * never checked even if set in cmask. */ uint8_t *cmask; @@ -172,11 +175,13 @@ struct PCIDevice { /* Space to store MSIX table */ uint8_t *msix_table_page; /* MMIO index used to map MSIX table and pending bit entries. */ - int msix_mmio_index; + MemoryRegion msix_mmio; /* Reference-count for entries actually in use by driver. */ unsigned *msix_entry_used; /* Region including the MSI-X table */ uint32_t msix_bar_size; + /* MSIX function mask set or MSIX disabled */ + bool msix_function_masked; /* Version id needed for VMState */ int32_t version_id; @@ -188,7 +193,8 @@ struct PCIDevice { /* Location of option rom */ char *romfile; - ram_addr_t rom_offset; + bool has_rom; + MemoryRegion rom; uint32_t rom_bar; }; @@ -198,16 +204,14 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, PCIConfigWriteFunc *config_write); void pci_register_bar(PCIDevice *pci_dev, int region_num, - pcibus_t size, uint8_t type, - PCIMapIORegionFunc *map_func); + uint8_t attr, MemoryRegion *memory); +pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num); int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size); void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); -void pci_reserve_capability(PCIDevice *pci_dev, uint8_t offset, uint8_t size); - uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id); @@ -217,6 +221,8 @@ void pci_default_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len); void pci_device_save(PCIDevice *s, QEMUFile *f); int pci_device_load(PCIDevice *s, QEMUFile *f); +MemoryRegion *pci_address_space(PCIDevice *dev); +MemoryRegion *pci_address_space_io(PCIDevice *dev); typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); @@ -230,19 +236,27 @@ typedef enum { typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev, PCIHotplugState state); void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, - const char *name, int devfn_min); -PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min); + const char *name, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min); +PCIBus *pci_bus_new(DeviceState *parent, const char *name, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min); void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, void *irq_opaque, int nirq); +int pci_bus_get_irq_level(PCIBus *bus, int irq_num); void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev); PCIBus *pci_register_bus(DeviceState *parent, const char *name, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, - void *irq_opaque, int devfn_min, int nirq); + void *irq_opaque, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + uint8_t devfn_min, int nirq); void pci_device_reset(PCIDevice *dev); void pci_bus_reset(PCIBus *bus); -void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base); - PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, const char *default_devaddr); PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model, @@ -252,7 +266,7 @@ void pci_for_each_device(PCIBus *bus, int bus_num, void (*fn)(PCIBus *bus, PCIDe PCIBus *pci_find_root_bus(int domain); int pci_find_domain(const PCIBus *bus); PCIBus *pci_find_bus(PCIBus *bus, int bus_num); -PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function); +PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn); int pci_qdev_find_device(const char *id, PCIDevice **pdev); PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr); @@ -261,10 +275,6 @@ int pci_parse_devaddr(const char *addr, int *domp, int *busp, int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp, unsigned *slotp); -void do_pci_info_print(Monitor *mon, const QObject *data); -void do_pci_info(Monitor *mon, QObject **ret_data); -void pci_bridge_update_mappings(PCIBus *b); - void pci_device_deassert_intx(PCIDevice *dev); static inline void @@ -429,6 +439,13 @@ typedef struct { PCIConfigReadFunc *config_read; PCIConfigWriteFunc *config_write; + uint16_t vendor_id; + uint16_t device_id; + uint8_t revision; + uint16_t class_id; + uint16_t subsystem_vendor_id; /* only for header type = 0 */ + uint16_t subsystem_id; /* only for header type = 0 */ + /* * pci-to-pci bridge or normal device. * This doesn't mean pci host switch. @@ -454,8 +471,12 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, bool multifunction, const char *name); +PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn, + bool multifunction, + const char *name); PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); +PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name); static inline int pci_is_express(const PCIDevice *d) { @@ -467,4 +488,70 @@ static inline uint32_t pci_config_size(const PCIDevice *d) return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE; } +/* DMA access functions */ +static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr, + void *buf, dma_addr_t len, DMADirection dir) +{ + cpu_physical_memory_rw(addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE); + return 0; +} + +static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr, + void *buf, dma_addr_t len) +{ + return pci_dma_rw(dev, addr, buf, len, DMA_DIRECTION_TO_DEVICE); +} + +static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr, + const void *buf, dma_addr_t len) +{ + return pci_dma_rw(dev, addr, (void *) buf, len, DMA_DIRECTION_FROM_DEVICE); +} + +#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ + static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \ + dma_addr_t addr) \ + { \ + return ld##_l##_phys(addr); \ + } \ + static inline void st##_s##_pci_dma(PCIDevice *dev, \ + dma_addr_t addr, uint##_bits##_t val) \ + { \ + st##_s##_phys(addr, val); \ + } + +PCI_DMA_DEFINE_LDST(ub, b, 8); +PCI_DMA_DEFINE_LDST(uw_le, w_le, 16) +PCI_DMA_DEFINE_LDST(l_le, l_le, 32); +PCI_DMA_DEFINE_LDST(q_le, q_le, 64); +PCI_DMA_DEFINE_LDST(uw_be, w_be, 16) +PCI_DMA_DEFINE_LDST(l_be, l_be, 32); +PCI_DMA_DEFINE_LDST(q_be, q_be, 64); + +#undef PCI_DMA_DEFINE_LDST + +static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr, + dma_addr_t *plen, DMADirection dir) +{ + target_phys_addr_t len = *plen; + void *buf; + + buf = cpu_physical_memory_map(addr, &len, dir == DMA_DIRECTION_FROM_DEVICE); + *plen = len; + return buf; +} + +static inline void pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len, + DMADirection dir, dma_addr_t access_len) +{ + cpu_physical_memory_unmap(buffer, len, dir == DMA_DIRECTION_FROM_DEVICE, + access_len); +} + +static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev, + int alloc_hint) +{ + qemu_sglist_init(qsg, alloc_hint); +} + #endif diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c index 464d897..650d165 100644 --- a/hw/pci_bridge.c +++ b/hw/pci_bridge.c @@ -135,6 +135,76 @@ pcibus_t pci_bridge_get_limit(const PCIDevice *bridge, uint8_t type) return limit; } +static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias, + uint8_t type, const char *name, + MemoryRegion *space, + MemoryRegion *parent_space, + bool enabled) +{ + pcibus_t base = pci_bridge_get_base(&bridge->dev, type); + pcibus_t limit = pci_bridge_get_limit(&bridge->dev, type); + /* TODO: this doesn't handle base = 0 limit = 2^64 - 1 correctly. + * Apparently no way to do this with existing memory APIs. */ + pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0; + + memory_region_init_alias(alias, name, space, base, size); + memory_region_add_subregion_overlap(parent_space, base, alias, 1); +} + +static void pci_bridge_cleanup_alias(MemoryRegion *alias, + MemoryRegion *parent_space) +{ + memory_region_del_subregion(parent_space, alias); + memory_region_destroy(alias); +} + +static void pci_bridge_region_init(PCIBridge *br) +{ + PCIBus *parent = br->dev.bus; + uint16_t cmd = pci_get_word(br->dev.config + PCI_COMMAND); + + pci_bridge_init_alias(br, &br->alias_pref_mem, + PCI_BASE_ADDRESS_MEM_PREFETCH, + "pci_bridge_pref_mem", + &br->address_space_mem, + parent->address_space_mem, + cmd & PCI_COMMAND_MEMORY); + pci_bridge_init_alias(br, &br->alias_mem, + PCI_BASE_ADDRESS_SPACE_MEMORY, + "pci_bridge_mem", + &br->address_space_mem, + parent->address_space_mem, + cmd & PCI_COMMAND_MEMORY); + pci_bridge_init_alias(br, &br->alias_io, + PCI_BASE_ADDRESS_SPACE_IO, + "pci_bridge_io", + &br->address_space_io, + parent->address_space_io, + cmd & PCI_COMMAND_IO); + /* TODO: optinal VGA and VGA palette snooping support. */ +} + +static void pci_bridge_region_cleanup(PCIBridge *br) +{ + PCIBus *parent = br->dev.bus; + pci_bridge_cleanup_alias(&br->alias_io, + parent->address_space_io); + pci_bridge_cleanup_alias(&br->alias_mem, + parent->address_space_mem); + pci_bridge_cleanup_alias(&br->alias_pref_mem, + parent->address_space_mem); +} + +static void pci_bridge_update_mappings(PCIBridge *br) +{ + /* Make updates atomic to: handle the case of one VCPU updating the bridge + * while another accesses an unaffected region. */ + memory_region_transaction_begin(); + pci_bridge_region_cleanup(br); + pci_bridge_region_init(br); + memory_region_transaction_commit(); +} + /* default write_config function for PCI-to-PCI bridge */ void pci_bridge_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) @@ -145,13 +215,15 @@ void pci_bridge_write_config(PCIDevice *d, pci_default_write_config(d, address, val, len); - if (/* io base/limit */ + if (ranges_overlap(address, len, PCI_COMMAND, 2) || + + /* io base/limit */ ranges_overlap(address, len, PCI_IO_BASE, 2) || /* memory base/limit, prefetchable base/limit and io base/limit upper 16 */ ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) { - pci_bridge_update_mappings(&s->sec_bus); + pci_bridge_update_mappings(s); } newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL); @@ -246,7 +318,11 @@ int pci_bridge_initfn(PCIDevice *dev) br->bus_name); sec_bus->parent_dev = dev; sec_bus->map_irq = br->map_irq; - + sec_bus->address_space_mem = &br->address_space_mem; + memory_region_init(&br->address_space_mem, "pci_bridge_pci", INT64_MAX); + sec_bus->address_space_io = &br->address_space_io; + memory_region_init(&br->address_space_io, "pci_bridge_io", 65536); + pci_bridge_region_init(br); QLIST_INIT(&sec_bus->child); QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling); return 0; @@ -258,6 +334,9 @@ int pci_bridge_exitfn(PCIDevice *pci_dev) PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev); assert(QLIST_EMPTY(&s->sec_bus.child)); QLIST_REMOVE(&s->sec_bus, sibling); + pci_bridge_region_cleanup(s); + memory_region_destroy(&s->address_space_mem); + memory_region_destroy(&s->address_space_io); /* qbus_free() is called automatically by qdev_free() */ return 0; } diff --git a/hw/pci_host.c b/hw/pci_host.c index 7c40155..44c6c20 100644 --- a/hw/pci_host.c +++ b/hw/pci_host.c @@ -44,7 +44,21 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr) uint8_t bus_num = addr >> 16; uint8_t devfn = addr >> 8; - return pci_find_device(bus, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); + return pci_find_device(bus, bus_num, devfn); +} + +void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr, + uint32_t limit, uint32_t val, uint32_t len) +{ + assert(len <= 4); + pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr)); +} + +uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr, + uint32_t limit, uint32_t len) +{ + assert(len <= 4); + return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr)); } void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len) @@ -52,12 +66,14 @@ void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len) PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr); uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1); - if (!pci_dev) + if (!pci_dev) { return; + } PCI_DPRINTF("%s: %s: addr=%02" PRIx32 " val=%08" PRIx32 " len=%d\n", __func__, pci_dev->name, config_addr, val, len); - pci_dev->config_write(pci_dev, config_addr, val, len); + pci_host_config_write_common(pci_dev, config_addr, PCI_CONFIG_SPACE_SIZE, + val, len); } uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len) @@ -66,94 +82,84 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len) uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1); uint32_t val; - assert(len == 1 || len == 2 || len == 4); if (!pci_dev) { return ~0x0; } - val = pci_dev->config_read(pci_dev, config_addr, len); + val = pci_host_config_read_common(pci_dev, config_addr, + PCI_CONFIG_SPACE_SIZE, len); PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n", __func__, pci_dev->name, config_addr, val, len); return val; } -static void pci_host_config_write(ReadWriteHandler *handler, - pcibus_t addr, uint32_t val, int len) +static void pci_host_config_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned len) { - PCIHostState *s = container_of(handler, PCIHostState, conf_handler); + PCIHostState *s = opaque; - PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n", + PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n", __func__, addr, len, val); s->config_reg = val; } -static uint32_t pci_host_config_read(ReadWriteHandler *handler, - pcibus_t addr, int len) +static uint64_t pci_host_config_read(void *opaque, target_phys_addr_t addr, + unsigned len) { - PCIHostState *s = container_of(handler, PCIHostState, conf_handler); + PCIHostState *s = opaque; uint32_t val = s->config_reg; - PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n", + PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx32"\n", __func__, addr, len, val); return val; } -static void pci_host_data_write(ReadWriteHandler *handler, - pcibus_t addr, uint32_t val, int len) +static void pci_host_data_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned len) { - PCIHostState *s = container_of(handler, PCIHostState, data_handler); - PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", - addr, len, val); + PCIHostState *s = opaque; + PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n", + addr, len, (unsigned)val); if (s->config_reg & (1u << 31)) pci_data_write(s->bus, s->config_reg | (addr & 3), val, len); } -static uint32_t pci_host_data_read(ReadWriteHandler *handler, - pcibus_t addr, int len) +static uint64_t pci_host_data_read(void *opaque, + target_phys_addr_t addr, unsigned len) { - PCIHostState *s = container_of(handler, PCIHostState, data_handler); + PCIHostState *s = opaque; uint32_t val; if (!(s->config_reg & (1 << 31))) return 0xffffffff; val = pci_data_read(s->bus, s->config_reg | (addr & 3), len); - PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", + PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n", addr, len, val); return val; } -static void pci_host_init(PCIHostState *s) -{ - s->conf_handler.write = pci_host_config_write; - s->conf_handler.read = pci_host_config_read; - s->data_handler.write = pci_host_data_write; - s->data_handler.read = pci_host_data_read; -} +const MemoryRegionOps pci_host_conf_le_ops = { + .read = pci_host_config_read, + .write = pci_host_config_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; -int pci_host_conf_register_mmio(PCIHostState *s, int endian) -{ - pci_host_init(s); - return cpu_register_io_memory_simple(&s->conf_handler, endian); -} +const MemoryRegionOps pci_host_conf_be_ops = { + .read = pci_host_config_read, + .write = pci_host_config_write, + .endianness = DEVICE_BIG_ENDIAN, +}; -void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s) -{ - pci_host_init(s); - register_ioport_simple(&s->conf_handler, ioport, 4, 4); - sysbus_init_ioports(&s->busdev, ioport, 4); -} +const MemoryRegionOps pci_host_data_le_ops = { + .read = pci_host_data_read, + .write = pci_host_data_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +const MemoryRegionOps pci_host_data_be_ops = { + .read = pci_host_data_read, + .write = pci_host_data_write, + .endianness = DEVICE_BIG_ENDIAN, +}; -int pci_host_data_register_mmio(PCIHostState *s, int endian) -{ - pci_host_init(s); - return cpu_register_io_memory_simple(&s->data_handler, endian); -} -void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s) -{ - pci_host_init(s); - register_ioport_simple(&s->data_handler, ioport, 4, 1); - register_ioport_simple(&s->data_handler, ioport, 4, 2); - register_ioport_simple(&s->data_handler, ioport, 4, 4); - sysbus_init_ioports(&s->busdev, ioport, 4); -} diff --git a/hw/pci_host.h b/hw/pci_host.h index 0a58595..0211086 100644 --- a/hw/pci_host.h +++ b/hw/pci_host.h @@ -29,25 +29,28 @@ #define PCI_HOST_H #include "sysbus.h" -#include "rwhandler.h" struct PCIHostState { SysBusDevice busdev; - ReadWriteHandler conf_handler; - ReadWriteHandler data_handler; + MemoryRegion conf_mem; + MemoryRegion data_mem; + MemoryRegion *address_space; uint32_t config_reg; PCIBus *bus; }; +/* common internal helpers for PCI/PCIe hosts, cut off overflows */ +void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr, + uint32_t limit, uint32_t val, uint32_t len); +uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr, + uint32_t limit, uint32_t len); + void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len); uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len); -/* for mmio */ -int pci_host_conf_register_mmio(PCIHostState *s, int endian); -int pci_host_data_register_mmio(PCIHostState *s, int endian); - -/* for ioio */ -void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s); -void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s); +extern const MemoryRegionOps pci_host_conf_le_ops; +extern const MemoryRegionOps pci_host_conf_be_ops; +extern const MemoryRegionOps pci_host_data_le_ops; +extern const MemoryRegionOps pci_host_data_be_ops; #endif /* PCI_HOST_H */ diff --git a/hw/pci_host_template.h b/hw/pci_host_template.h deleted file mode 100644 index 11e6c88..0000000 --- a/hw/pci_host_template.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * QEMU Common PCI Host bridge configuration data space access routines. - * - * Copyright (c) 2006 Fabrice Bellard - * - * 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 AUTHORS OR 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. - */ - -/* Worker routines for a PCI host controller that uses an {address,data} - register pair to access PCI configuration space. */ - -static void glue(pci_host_data_writeb, PCI_HOST_SUFFIX)( - void* opaque, PCI_ADDR_T addr, uint32_t val) -{ - PCIHostState *s = opaque; - - PCI_DPRINTF("writeb addr " TARGET_FMT_plx " val %x\n", - (target_phys_addr_t)addr, val); - if (s->config_reg & (1u << 31)) - pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1); -} - -static void glue(pci_host_data_writew, PCI_HOST_SUFFIX)( - void* opaque, PCI_ADDR_T addr, uint32_t val) -{ - PCIHostState *s = opaque; -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap16(val); -#endif - PCI_DPRINTF("writew addr " TARGET_FMT_plx " val %x\n", - (target_phys_addr_t)addr, val); - if (s->config_reg & (1u << 31)) - pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2); -} - -static void glue(pci_host_data_writel, PCI_HOST_SUFFIX)( - void* opaque, PCI_ADDR_T addr, uint32_t val) -{ - PCIHostState *s = opaque; -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif - PCI_DPRINTF("writel addr " TARGET_FMT_plx " val %x\n", - (target_phys_addr_t)addr, val); - if (s->config_reg & (1u << 31)) - pci_data_write(s->bus, s->config_reg, val, 4); -} - -static uint32_t glue(pci_host_data_readb, PCI_HOST_SUFFIX)( - void* opaque, PCI_ADDR_T addr) -{ - PCIHostState *s = opaque; - uint32_t val; - - if (!(s->config_reg & (1 << 31))) - return 0xff; - val = pci_data_read(s->bus, s->config_reg | (addr & 3), 1); - PCI_DPRINTF("readb addr " TARGET_FMT_plx " val %x\n", - (target_phys_addr_t)addr, val); - return val; -} - -static uint32_t glue(pci_host_data_readw, PCI_HOST_SUFFIX)( - void* opaque, PCI_ADDR_T addr) -{ - PCIHostState *s = opaque; - uint32_t val; - if (!(s->config_reg & (1 << 31))) - return 0xffff; - val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2); - PCI_DPRINTF("readw addr " TARGET_FMT_plx " val %x\n", - (target_phys_addr_t)addr, val); -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap16(val); -#endif - return val; -} - -static uint32_t glue(pci_host_data_readl, PCI_HOST_SUFFIX)( - void* opaque, PCI_ADDR_T addr) -{ - PCIHostState *s = opaque; - uint32_t val; - if (!(s->config_reg & (1 << 31))) - return 0xffffffff; - val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4); - PCI_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n", - (target_phys_addr_t)addr, val); -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif - return val; -} diff --git a/hw/pci_ids.h b/hw/pci_ids.h index 97b819d..83f3893 100644 --- a/hw/pci_ids.h +++ b/hw/pci_ids.h @@ -24,7 +24,6 @@ #define PCI_CLASS_DISPLAY_OTHER 0x0380 #define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 -#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 #define PCI_CLASS_MEMORY_RAM 0x0500 @@ -69,14 +68,6 @@ #define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020 #define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b -#define PCI_VENDOR_ID_SAMSUNG 0x144d - -#define PCI_VENDOR_ID_TIZEN 0xC9B5 -#define PCI_DEVICE_ID_VIRTUAL_OVERLAY 0x1010 -#define PCI_DEVICE_ID_VIRTUAL_BRIGHTNESS 0x1014 -#define PCI_DEVICE_ID_VIRTUAL_CAMERA 0x1018 -#define PCI_DEVICE_ID_VIRTUAL_CODEC 0x101C - #define PCI_VENDOR_ID_SUN 0x108e #define PCI_DEVICE_ID_SUN_EBUS 0x1000 #define PCI_DEVICE_ID_SUN_SIMBA 0x5000 @@ -109,6 +100,7 @@ #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82441 0x1237 #define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415 +#define PCI_DEVICE_ID_INTEL_82801D 0x24CD #define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 @@ -117,3 +109,14 @@ #define PCI_DEVICE_ID_INTEL_82371AB 0x7111 #define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 +#define PCI_DEVICE_ID_INTEL_82801I_UHCI1 0x2934 +#define PCI_DEVICE_ID_INTEL_82801I_UHCI2 0x2935 +#define PCI_DEVICE_ID_INTEL_82801I_UHCI3 0x2936 +#define PCI_DEVICE_ID_INTEL_82801I_UHCI4 0x2937 +#define PCI_DEVICE_ID_INTEL_82801I_UHCI5 0x2938 +#define PCI_DEVICE_ID_INTEL_82801I_UHCI6 0x2939 +#define PCI_DEVICE_ID_INTEL_82801I_EHCI1 0x293a +#define PCI_DEVICE_ID_INTEL_82801I_EHCI2 0x293c + +#define PCI_VENDOR_ID_XEN 0x5853 +#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001 diff --git a/hw/pci_internals.h b/hw/pci_internals.h index e3c93a3..96690b7 100644 --- a/hw/pci_internals.h +++ b/hw/pci_internals.h @@ -16,15 +16,16 @@ extern struct BusInfo pci_bus_info; struct PCIBus { BusState qbus; - int devfn_min; + uint8_t devfn_min; pci_set_irq_fn set_irq; pci_map_irq_fn map_irq; pci_hotplug_fn hotplug; DeviceState *hotplug_qdev; void *irq_opaque; - PCIDevice *devices[256]; + PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX]; PCIDevice *parent_dev; - target_phys_addr_t mem_base; + MemoryRegion *address_space_mem; + MemoryRegion *address_space_io; QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */ QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */ @@ -40,6 +41,24 @@ struct PCIBridge { /* private member */ PCIBus sec_bus; + /* + * Memory regions for the bridge's address spaces. These regions are not + * directly added to system_memory/system_io or its descendants. + * Bridge's secondary bus points to these, so that devices + * under the bridge see these regions as its address spaces. + * The regions are as large as the entire address space - + * they don't take into account any windows. + */ + MemoryRegion address_space_mem; + MemoryRegion address_space_io; + /* + * Aliases for each of the address space windows that the bridge + * can forward. Mapped into the bridge's parent's address space, + * as subregions. + */ + MemoryRegion alias_pref_mem; + MemoryRegion alias_mem; + MemoryRegion alias_io; pci_map_irq_fn map_irq; const char *bus_name; }; diff --git a/hw/pci_regs.h b/hw/pci_regs.h index dd0bed4..e8357c3 100644 --- a/hw/pci_regs.h +++ b/hw/pci_regs.h @@ -211,6 +211,7 @@ #define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */ #define PCI_CAP_ID_EXP 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ +#define PCI_CAP_ID_SATA 0x12 /* Serial ATA */ #define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */ #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ @@ -223,7 +224,7 @@ #define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */ #define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */ #define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */ -#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */ +#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxiliary power support mask */ #define PCI_PM_CAP_D1 0x0200 /* D1 power state support */ #define PCI_PM_CAP_D2 0x0400 /* D2 power state support */ #define PCI_PM_CAP_PME 0x0800 /* PME pin supported */ @@ -300,12 +301,22 @@ #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ #define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */ -/* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */ +/* MSI-X registers */ #define PCI_MSIX_FLAGS 2 #define PCI_MSIX_FLAGS_QSIZE 0x7FF #define PCI_MSIX_FLAGS_ENABLE (1 << 15) #define PCI_MSIX_FLAGS_MASKALL (1 << 14) -#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) +#define PCI_MSIX_TABLE 4 +#define PCI_MSIX_PBA 8 +#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) + +/* MSI-X entry's format */ +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 /* CompactPCI Hotswap Register */ @@ -365,6 +376,11 @@ #define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ #define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ +/* PCI Bridge Subsystem ID registers */ + +#define PCI_SSVID_VENDOR_ID 4 /* PCI-Bridge subsystem vendor id register */ +#define PCI_SSVID_DEVICE_ID 6 /* PCI-Bridge subsystem device id register */ + /* PCI Express capability registers */ #define PCI_EXP_FLAGS 2 /* Capabilities register */ @@ -420,7 +436,7 @@ #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ #define PCI_EXP_LNKCAP_L1EL 0x00038000 /* L1 Exit Latency */ #define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* L1 Clock Power Management */ -#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Suprise Down Error Reporting Capable */ +#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Surprise Down Error Reporting Capable */ #define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */ #define PCI_EXP_LNKCAP_LBNC 0x00200000 /* Link Bandwidth Notification Capability */ #define PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */ @@ -437,7 +453,10 @@ #define PCI_EXP_LNKCTL_LABIE 0x0800 /* Lnk Autonomous Bandwidth Interrupt Enable */ #define PCI_EXP_LNKSTA 18 /* Link Status */ #define PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */ +#define PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */ +#define PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */ #define PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */ +#define PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */ #define PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */ #define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */ #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ @@ -486,10 +505,22 @@ #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ #define PCI_EXP_RTCAP 30 /* Root Capabilities */ #define PCI_EXP_RTSTA 32 /* Root Status */ +#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ +#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCAP2_LTR 0x800 /* Latency tolerance reporting */ +#define PCI_EXP_OBFF_MASK 0xc0000 /* OBFF support mechanism */ +#define PCI_EXP_OBFF_MSG 0x40000 /* New message signaling */ +#define PCI_EXP_OBFF_WAKE 0x80000 /* Re-use WAKE# for OBFF */ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ #define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ +#define PCI_EXP_IDO_REQ_EN 0x100 /* ID-based ordering request enable */ +#define PCI_EXP_IDO_CMP_EN 0x200 /* ID-based ordering completion enable */ +#define PCI_EXP_LTR_EN 0x400 /* Latency tolerance reporting */ +#define PCI_EXP_OBFF_MSGA_EN 0x2000 /* OBFF enable with Message type A */ +#define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */ +#define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ @@ -502,9 +533,12 @@ #define PCI_EXT_CAP_ID_VC 2 #define PCI_EXT_CAP_ID_DSN 3 #define PCI_EXT_CAP_ID_PWR 4 +#define PCI_EXT_CAP_ID_VNDR 11 +#define PCI_EXT_CAP_ID_ACS 13 #define PCI_EXT_CAP_ID_ARI 14 #define PCI_EXT_CAP_ID_ATS 15 #define PCI_EXT_CAP_ID_SRIOV 16 +#define PCI_EXT_CAP_ID_LTR 24 /* Advanced Error Reporting */ #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ @@ -556,8 +590,7 @@ #define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */ #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ #define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ -#define PCI_ERR_ROOT_COR_SRC 52 -#define PCI_ERR_ROOT_SRC 54 +#define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */ /* Virtual Channel */ #define PCI_VC_PORT_REG1 4 @@ -662,4 +695,22 @@ #define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ +#define PCI_LTR_MAX_SNOOP_LAT 0x4 +#define PCI_LTR_MAX_NOSNOOP_LAT 0x6 +#define PCI_LTR_VALUE_MASK 0x000003ff +#define PCI_LTR_SCALE_MASK 0x00001c00 +#define PCI_LTR_SCALE_SHIFT 10 + +/* Access Control Service */ +#define PCI_ACS_CAP 0x04 /* ACS Capability Register */ +#define PCI_ACS_SV 0x01 /* Source Validation */ +#define PCI_ACS_TB 0x02 /* Translation Blocking */ +#define PCI_ACS_RR 0x04 /* P2P Request Redirect */ +#define PCI_ACS_CR 0x08 /* P2P Completion Redirect */ +#define PCI_ACS_UF 0x10 /* Upstream Forwarding */ +#define PCI_ACS_EC 0x20 /* P2P Egress Control */ +#define PCI_ACS_DT 0x40 /* Direct Translated P2P */ +#define PCI_ACS_CTRL 0x06 /* ACS Control Register */ +#define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */ + #endif /* LINUX_PCI_REGS_H */ diff --git a/hw/pcie.c b/hw/pcie.c index 6a113a9..5c9eb2f 100644 --- a/hw/pcie.c +++ b/hw/pcie.c @@ -18,8 +18,7 @@ * with this program; if not, see . */ -#include "sysemu.h" -#include "range.h" +#include "qemu-common.h" #include "pci_bridge.h" #include "pcie.h" #include "msix.h" @@ -176,8 +175,16 @@ static void hotplug_event_notify(PCIDevice *dev) } } +static void hotplug_event_clear(PCIDevice *dev) +{ + hotplug_event_update_event_status(dev); + if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) { + qemu_set_irq(dev->irq[dev->exp.hpev_intx], 0); + } +} + /* - * A PCI Express Hot-Plug Event has occured, so update slot status register + * A PCI Express Hot-Plug Event has occurred, so update slot status register * and notify OS of the event if necessary. * * 6.7.3 PCI Express Hot-Plug Events @@ -321,6 +328,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev, uint8_t *exp_cap = dev->config + pos; uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA); + if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) { + hotplug_event_clear(dev); + } + if (!ranges_overlap(addr, len, pos + PCI_EXP_SLTCTL, 2)) { return; } diff --git a/hw/pcie.h b/hw/pcie.h index bc909e2..a213fba 100644 --- a/hw/pcie.h +++ b/hw/pcie.h @@ -40,7 +40,7 @@ typedef enum { * * Not all the bits of slot control register match with the ones of * slot status. Not some bits of slot status register is used to - * show status, not to report event occurence. + * show status, not to report event occurrence. * So such bits must be masked out when checking the software * notification condition. */ diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c index 6e653dd..62c06ea 100644 --- a/hw/pcie_aer.c +++ b/hw/pcie_aer.c @@ -38,6 +38,9 @@ #define PCIE_DEV_PRINTF(dev, fmt, ...) \ PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__) +#define PCI_ERR_SRC_COR_OFFS 0 +#define PCI_ERR_SRC_UNCOR_OFFS 2 + /* From 6.2.7 Error Listing and Rules. Table 6-2, 6-3 and 6-4 */ static uint32_t pcie_aer_uncor_default_severity(uint32_t status) { @@ -108,7 +111,7 @@ int pcie_aer_init(PCIDevice *dev, uint16_t offset) if (dev->exp.aer_log.log_max > PCIE_AER_LOG_MAX_LIMIT) { return -EINVAL; } - dev->exp.aer_log.log = qemu_mallocz(sizeof dev->exp.aer_log.log[0] * + dev->exp.aer_log.log = g_malloc0(sizeof dev->exp.aer_log.log[0] * dev->exp.aer_log.log_max); pci_set_long(dev->w1cmask + offset + PCI_ERR_UNCOR_STATUS, @@ -162,7 +165,7 @@ int pcie_aer_init(PCIDevice *dev, uint16_t offset) void pcie_aer_exit(PCIDevice *dev) { - qemu_free(dev->exp.aer_log.log); + g_free(dev->exp.aer_log.log); } static void pcie_aer_update_uncor_status(PCIDevice *dev) @@ -320,7 +323,8 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const PCIEAERMsg *msg) if (root_status & PCI_ERR_ROOT_COR_RCV) { root_status |= PCI_ERR_ROOT_MULTI_COR_RCV; } else { - pci_set_word(aer_cap + PCI_ERR_ROOT_COR_SRC, msg->source_id); + pci_set_word(aer_cap + PCI_ERR_ROOT_ERR_SRC + PCI_ERR_SRC_COR_OFFS, + msg->source_id); } root_status |= PCI_ERR_ROOT_COR_RCV; break; @@ -341,7 +345,8 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const PCIEAERMsg *msg) if (root_status & PCI_ERR_ROOT_UNCOR_RCV) { root_status |= PCI_ERR_ROOT_MULTI_UNCOR_RCV; } else { - pci_set_word(aer_cap + PCI_ERR_ROOT_SRC, msg->source_id); + pci_set_word(aer_cap + PCI_ERR_ROOT_ERR_SRC + + PCI_ERR_SRC_UNCOR_OFFS, msg->source_id); } root_status |= PCI_ERR_ROOT_UNCOR_RCV; } @@ -410,7 +415,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err) int i; assert(err->status); - assert(err->status & (err->status - 1)); + assert(!(err->status & (err->status - 1))); errcap &= ~(PCI_ERR_CAP_FEP_MASK | PCI_ERR_CAP_TLP); errcap |= PCI_ERR_CAP_FEP(first_bit); @@ -490,7 +495,7 @@ static int pcie_aer_record_error(PCIDevice *dev, int fep = PCI_ERR_CAP_FEP(errcap); assert(err->status); - assert(err->status & (err->status - 1)); + assert(!(err->status & (err->status - 1))); if (errcap & PCI_ERR_CAP_MHRE && (pci_get_long(aer_cap + PCI_ERR_UNCOR_STATUS) & (1U << fep))) { @@ -612,7 +617,7 @@ static bool pcie_aer_inject_uncor_error(PCIEAERInject *inj, bool is_fatal) /* * non-Function specific error must be recorded in all functions. * It is the responsibility of the caller of this function. - * It is also caller's responsiblity to determine which function should + * It is also caller's responsibility to determine which function should * report the rerror. * * 6.2.4 Error Logging @@ -785,16 +790,6 @@ static const VMStateDescription vmstate_pcie_aer_err = { } }; -#define VMSTATE_PCIE_AER_ERRS(_field, _state, _field_num, _vmsd, _type) { \ - .name = (stringify(_field)), \ - .version_id = 0, \ - .num_offset = vmstate_offset_value(_state, _field_num, uint16_t), \ - .size = sizeof(_type), \ - .vmsd = &(_vmsd), \ - .flags = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT, \ - .offset = vmstate_offset_pointer(_state, _field, _type), \ -} - const VMStateDescription vmstate_pcie_aer_log = { .name = "PCIE_AER_ERROR_LOG", .version_id = 1, @@ -803,7 +798,7 @@ const VMStateDescription vmstate_pcie_aer_log = { .fields = (VMStateField[]) { VMSTATE_UINT16(log_num, PCIEAERLog), VMSTATE_UINT16(log_max, PCIEAERLog), - VMSTATE_PCIE_AER_ERRS(log, PCIEAERLog, log_num, + VMSTATE_STRUCT_VARRAY_POINTER_UINT16(log, PCIEAERLog, log_num, vmstate_pcie_aer_err, PCIEAERErr), VMSTATE_END_OF_LIST() } @@ -984,20 +979,21 @@ int do_pcie_aer_inejct_error(Monitor *mon, if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) { char *e = NULL; error_status = strtoul(error_name, &e, 0); - correctable = !!qdict_get_int(qdict, "correctable"); + correctable = qdict_get_try_bool(qdict, "correctable", 0); if (!e || *e != '\0') { monitor_printf(mon, "invalid error status value. \"%s\"", error_name); return -EINVAL; } } + err.status = error_status; err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn; err.flags = 0; if (correctable) { err.flags |= PCIE_AER_ERR_IS_CORRECTABLE; } - if (qdict_get_int(qdict, "advisory_non_fatal")) { + if (qdict_get_try_bool(qdict, "advisory_non_fatal", 0)) { err.flags |= PCIE_AER_ERR_MAYBE_ADVISORY; } if (qdict_haskey(qdict, "header0")) { diff --git a/hw/pcie_host.c b/hw/pcie_host.c index 21069ee..28bbe72 100644 --- a/hw/pcie_host.c +++ b/hw/pcie_host.c @@ -22,6 +22,7 @@ #include "hw.h" #include "pci.h" #include "pcie_host.h" +#include "exec-memory.h" /* * PCI express mmcfig address @@ -49,99 +50,71 @@ static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus *s, uint32_t mmcfg_addr) { return pci_find_device(s, PCIE_MMCFG_BUS(mmcfg_addr), - PCI_SLOT(PCIE_MMCFG_DEVFN(mmcfg_addr)), - PCI_FUNC(PCIE_MMCFG_DEVFN(mmcfg_addr))); + PCIE_MMCFG_DEVFN(mmcfg_addr)); } -static void pcie_mmcfg_data_write(PCIBus *s, - uint32_t mmcfg_addr, uint32_t val, int len) +static void pcie_mmcfg_data_write(void *opaque, target_phys_addr_t mmcfg_addr, + uint64_t val, unsigned len) { + PCIExpressHost *e = opaque; + PCIBus *s = e->pci.bus; PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr); + uint32_t addr; + uint32_t limit; - if (!pci_dev) + if (!pci_dev) { return; - - pci_dev->config_write(pci_dev, - PCIE_MMCFG_CONFOFFSET(mmcfg_addr), val, len); + } + addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr); + limit = pci_config_size(pci_dev); + if (limit <= addr) { + /* conventional pci device can be behind pcie-to-pci bridge. + 256 <= addr < 4K has no effects. */ + return; + } + pci_host_config_write_common(pci_dev, addr, limit, val, len); } -static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t addr, int len) +static uint64_t pcie_mmcfg_data_read(void *opaque, + target_phys_addr_t mmcfg_addr, + unsigned len) { - PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, addr); + PCIExpressHost *e = opaque; + PCIBus *s = e->pci.bus; + PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr); + uint32_t addr; + uint32_t limit; - assert(len == 1 || len == 2 || len == 4); if (!pci_dev) { return ~0x0; } - return pci_dev->config_read(pci_dev, PCIE_MMCFG_CONFOFFSET(addr), len); -} - -static void pcie_mmcfg_data_writeb(void *opaque, - target_phys_addr_t addr, uint32_t value) -{ - PCIExpressHost *e = opaque; - pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 1); -} - -static void pcie_mmcfg_data_writew(void *opaque, - target_phys_addr_t addr, uint32_t value) -{ - PCIExpressHost *e = opaque; - pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 2); -} - -static void pcie_mmcfg_data_writel(void *opaque, - target_phys_addr_t addr, uint32_t value) -{ - PCIExpressHost *e = opaque; - pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 4); -} - -static uint32_t pcie_mmcfg_data_readb(void *opaque, target_phys_addr_t addr) -{ - PCIExpressHost *e = opaque; - return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 1); -} - -static uint32_t pcie_mmcfg_data_readw(void *opaque, target_phys_addr_t addr) -{ - PCIExpressHost *e = opaque; - return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 2); -} - -static uint32_t pcie_mmcfg_data_readl(void *opaque, target_phys_addr_t addr) -{ - PCIExpressHost *e = opaque; - return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 4); + addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr); + limit = pci_config_size(pci_dev); + if (limit <= addr) { + /* conventional pci device can be behind pcie-to-pci bridge. + 256 <= addr < 4K has no effects. */ + return ~0x0; + } + return pci_host_config_read_common(pci_dev, addr, limit, len); } - -static CPUWriteMemoryFunc * const pcie_mmcfg_write[] = -{ - pcie_mmcfg_data_writeb, - pcie_mmcfg_data_writew, - pcie_mmcfg_data_writel, -}; - -static CPUReadMemoryFunc * const pcie_mmcfg_read[] = -{ - pcie_mmcfg_data_readb, - pcie_mmcfg_data_readw, - pcie_mmcfg_data_readl, +static const MemoryRegionOps pcie_mmcfg_ops = { + .read = pcie_mmcfg_data_read, + .write = pcie_mmcfg_data_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; /* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ #define PCIE_BASE_ADDR_UNMAPPED ((target_phys_addr_t)-1ULL) -int pcie_host_init(PCIExpressHost *e) +int pcie_host_init(PCIExpressHost *e, uint32_t size) { + assert(!(size & (size - 1))); /* power of 2 */ + assert(size >= PCIE_MMCFG_SIZE_MIN); + assert(size <= PCIE_MMCFG_SIZE_MAX); e->base_addr = PCIE_BASE_ADDR_UNMAPPED; - e->mmio_index = - cpu_register_io_memory(pcie_mmcfg_read, pcie_mmcfg_write, e, - DEVICE_NATIVE_ENDIAN); - if (e->mmio_index < 0) { - return -1; - } + e->size = size; + memory_region_init_io(&e->mmio, &pcie_mmcfg_ops, e, "pcie-mmcfg", e->size); return 0; } @@ -149,29 +122,23 @@ int pcie_host_init(PCIExpressHost *e) void pcie_host_mmcfg_unmap(PCIExpressHost *e) { if (e->base_addr != PCIE_BASE_ADDR_UNMAPPED) { - cpu_register_physical_memory(e->base_addr, e->size, IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), &e->mmio); e->base_addr = PCIE_BASE_ADDR_UNMAPPED; } } -void pcie_host_mmcfg_map(PCIExpressHost *e, - target_phys_addr_t addr, uint32_t size) +void pcie_host_mmcfg_map(PCIExpressHost *e, target_phys_addr_t addr) { - assert(!(size & (size - 1))); /* power of 2 */ - assert(size >= PCIE_MMCFG_SIZE_MIN); - assert(size <= PCIE_MMCFG_SIZE_MAX); - e->base_addr = addr; - e->size = size; - cpu_register_physical_memory(e->base_addr, e->size, e->mmio_index); + memory_region_add_subregion(get_system_memory(), e->base_addr, &e->mmio); } void pcie_host_mmcfg_update(PCIExpressHost *e, int enable, - target_phys_addr_t addr, uint32_t size) + target_phys_addr_t addr) { pcie_host_mmcfg_unmap(e); if (enable) { - pcie_host_mmcfg_map(e, addr, size); + pcie_host_mmcfg_map(e, addr); } } diff --git a/hw/pcie_host.h b/hw/pcie_host.h index a202661..0074508 100644 --- a/hw/pcie_host.h +++ b/hw/pcie_host.h @@ -22,6 +22,7 @@ #define PCIE_HOST_H #include "pci_host.h" +#include "memory.h" struct PCIExpressHost { PCIHostState pci; @@ -34,16 +35,15 @@ struct PCIExpressHost { /* the size of MMCONFIG area. It's host bridge dependent */ target_phys_addr_t size; - /* result of cpu_register_io_memory() to map MMCONFIG area */ - int mmio_index; + /* MMCONFIG mmio area */ + MemoryRegion mmio; }; -int pcie_host_init(PCIExpressHost *e); +int pcie_host_init(PCIExpressHost *e, uint32_t size); void pcie_host_mmcfg_unmap(PCIExpressHost *e); -void pcie_host_mmcfg_map(PCIExpressHost *e, - target_phys_addr_t addr, uint32_t size); +void pcie_host_mmcfg_map(PCIExpressHost *e, target_phys_addr_t addr); void pcie_host_mmcfg_update(PCIExpressHost *e, int enable, - target_phys_addr_t addr, uint32_t size); + target_phys_addr_t addr); #endif /* PCIE_HOST_H */ diff --git a/hw/pcie_port.c b/hw/pcie_port.c index 340dcdb..8a36f5c 100644 --- a/hw/pcie_port.c +++ b/hw/pcie_port.c @@ -76,7 +76,7 @@ void pcie_chassis_create(uint8_t chassis_number) if (c) { return; } - c = qemu_mallocz(sizeof(*c)); + c = g_malloc0(sizeof(*c)); c->number = chassis_number; QLIST_INIT(&c->slots); QLIST_INSERT_HEAD(&chassis, c, next); diff --git a/hw/pckbd.c b/hw/pckbd.c index ae65c04..06b40c5 100644 --- a/hw/pckbd.c +++ b/hw/pckbd.c @@ -400,33 +400,27 @@ static void kbd_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value kbd_write_data(s, 0, value & 0xff); } -static CPUReadMemoryFunc * const kbd_mm_read[] = { - &kbd_mm_readb, - &kbd_mm_readb, - &kbd_mm_readb, -}; - -static CPUWriteMemoryFunc * const kbd_mm_write[] = { - &kbd_mm_writeb, - &kbd_mm_writeb, - &kbd_mm_writeb, +static const MemoryRegionOps i8042_mmio_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + .old_mmio = { + .read = { kbd_mm_readb, kbd_mm_readb, kbd_mm_readb }, + .write = { kbd_mm_writeb, kbd_mm_writeb, kbd_mm_writeb }, + }, }; void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, - target_phys_addr_t base, ram_addr_t size, + MemoryRegion *region, ram_addr_t size, target_phys_addr_t mask) { - KBDState *s = qemu_mallocz(sizeof(KBDState)); - int s_io_memory; + KBDState *s = g_malloc0(sizeof(KBDState)); s->irq_kbd = kbd_irq; s->irq_mouse = mouse_irq; s->mask = mask; vmstate_register(NULL, 0, &vmstate_kbd, s); - s_io_memory = cpu_register_io_memory(kbd_mm_read, kbd_mm_write, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, size, s_io_memory); + + memory_region_init_io(region, &i8042_mmio_ops, s, "i8042", size); s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); @@ -435,7 +429,8 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, typedef struct ISAKBDState { ISADevice dev; - KBDState kbd; + KBDState kbd; + MemoryRegion io[2]; } ISAKBDState; void i8042_isa_mouse_fake_event(void *opaque) @@ -464,19 +459,37 @@ static const VMStateDescription vmstate_kbd_isa = { } }; +static const MemoryRegionPortio i8042_data_portio[] = { + { 0, 1, 1, .read = kbd_read_data, .write = kbd_write_data }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionPortio i8042_cmd_portio[] = { + { 0, 1, 1, .read = kbd_read_status, .write = kbd_write_command }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps i8042_data_ops = { + .old_portio = i8042_data_portio +}; + +static const MemoryRegionOps i8042_cmd_ops = { + .old_portio = i8042_cmd_portio +}; + static int i8042_initfn(ISADevice *dev) { - KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd); + ISAKBDState *isa_s = DO_UPCAST(ISAKBDState, dev, dev); + KBDState *s = &isa_s->kbd; isa_init_irq(dev, &s->irq_kbd, 1); isa_init_irq(dev, &s->irq_mouse, 12); - register_ioport_read(0x60, 1, 1, kbd_read_data, s); - register_ioport_write(0x60, 1, 1, kbd_write_data, s); - isa_init_ioport(dev, 0x60); - register_ioport_read(0x64, 1, 1, kbd_read_status, s); - register_ioport_write(0x64, 1, 1, kbd_write_command, s); - isa_init_ioport(dev, 0x64); + memory_region_init_io(isa_s->io + 0, &i8042_data_ops, s, "i8042-data", 1); + isa_register_ioport(dev, isa_s->io + 0, 0x60); + + memory_region_init_io(isa_s->io + 1, &i8042_cmd_ops, s, "i8042-cmd", 1); + isa_register_ioport(dev, isa_s->io + 1, 0x64); s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c index 339a401..4e164da 100644 --- a/hw/pcnet-pci.c +++ b/hw/pcnet-pci.c @@ -31,6 +31,7 @@ #include "net.h" #include "loader.h" #include "qemu-timer.h" +#include "dma.h" #include "pcnet.h" @@ -46,6 +47,7 @@ typedef struct { PCIDevice pci_dev; PCNetState state; + MemoryRegion io_bar; } PCIPCNetState; static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val) @@ -54,9 +56,9 @@ static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val) #ifdef PCNET_DEBUG printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val); #endif - /* Check APROMWE bit to enable write access */ - if (pcnet_bcr_readw(s,2) & 0x100) + if (BCR_APROMWE(s)) { s->prom[addr & 15] = val; + } } static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr) @@ -69,25 +71,65 @@ static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr) return val; } -static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state; + PCNetState *d = opaque; -#ifdef PCNET_DEBUG_IO - printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n", - addr, size); -#endif + if (addr < 0x10) { + if (!BCR_DWIO(d) && size == 1) { + return pcnet_aprom_readb(d, addr); + } else if (!BCR_DWIO(d) && (addr & 1) == 0 && size == 2) { + return pcnet_aprom_readb(d, addr) | + (pcnet_aprom_readb(d, addr + 1) << 8); + } else if (BCR_DWIO(d) && (addr & 3) == 0 && size == 4) { + return pcnet_aprom_readb(d, addr) | + (pcnet_aprom_readb(d, addr + 1) << 8) | + (pcnet_aprom_readb(d, addr + 2) << 16) | + (pcnet_aprom_readb(d, addr + 3) << 24); + } + } else { + if (size == 2) { + return pcnet_ioport_readw(d, addr); + } else if (size == 4) { + return pcnet_ioport_readl(d, addr); + } + } + return ((uint64_t)1 << (size * 8)) - 1; +} - register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d); - register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d); +static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + PCNetState *d = opaque; - register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d); - register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d); - register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d); - register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d); + if (addr < 0x10) { + if (!BCR_DWIO(d) && size == 1) { + pcnet_aprom_writeb(d, addr, data); + } else if (!BCR_DWIO(d) && (addr & 1) == 0 && size == 2) { + pcnet_aprom_writeb(d, addr, data & 0xff); + pcnet_aprom_writeb(d, addr + 1, data >> 8); + } else if (BCR_DWIO(d) && (addr & 3) == 0 && size == 4) { + pcnet_aprom_writeb(d, addr, data & 0xff); + pcnet_aprom_writeb(d, addr + 1, (data >> 8) & 0xff); + pcnet_aprom_writeb(d, addr + 2, (data >> 16) & 0xff); + pcnet_aprom_writeb(d, addr + 3, data >> 24); + } + } else { + if (size == 2) { + pcnet_ioport_writew(d, addr, data); + } else if (size == 4) { + pcnet_ioport_writel(d, addr, data); + } + } } +static const MemoryRegionOps pcnet_io_ops = { + .read = pcnet_ioport_read, + .write = pcnet_ioport_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { PCNetState *d = opaque; @@ -202,41 +244,24 @@ static const VMStateDescription vmstate_pci_pcnet = { /* PCI interface */ -static CPUWriteMemoryFunc * const pcnet_mmio_write[] = { - &pcnet_mmio_writeb, - &pcnet_mmio_writew, - &pcnet_mmio_writel -}; - -static CPUReadMemoryFunc * const pcnet_mmio_read[] = { - &pcnet_mmio_readb, - &pcnet_mmio_readw, - &pcnet_mmio_readl +static const MemoryRegionOps pcnet_mmio_ops = { + .old_mmio = { + .read = { pcnet_mmio_readb, pcnet_mmio_readw, pcnet_mmio_readl }, + .write = { pcnet_mmio_writeb, pcnet_mmio_writew, pcnet_mmio_writel }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev); - -#ifdef PCNET_DEBUG_IO - printf("pcnet_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n", - addr, size); -#endif - - cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index); -} - static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap) { - cpu_physical_memory_write(addr, buf, len); + pci_dma_write(dma_opaque, addr, buf, len); } static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap) { - cpu_physical_memory_read(addr, buf, len); + pci_dma_read(dma_opaque, addr, buf, len); } static void pci_pcnet_cleanup(VLANClientState *nc) @@ -250,7 +275,8 @@ static int pci_pcnet_uninit(PCIDevice *dev) { PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev); - cpu_unregister_io_memory(d->state.mmio_index); + memory_region_destroy(&d->state.mmio); + memory_region_destroy(&d->io_bar); qemu_del_timer(d->state.poll_timer); qemu_free_timer(d->state.poll_timer); qemu_del_vlan_client(&d->state.nic->nc); @@ -262,6 +288,7 @@ static NetClientInfo net_pci_pcnet_info = { .size = sizeof(NICState), .can_receive = pcnet_can_receive, .receive = pcnet_receive, + .link_status_changed = pcnet_set_link_status, .cleanup = pci_pcnet_cleanup, }; @@ -278,39 +305,35 @@ static int pci_pcnet_init(PCIDevice *pci_dev) pci_conf = pci_dev->config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE); pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); - pci_conf[PCI_REVISION_ID] = 0x10; - pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET); pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0); pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0); - pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0 + pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */ pci_conf[PCI_MIN_GNT] = 0x06; pci_conf[PCI_MAX_LAT] = 0xff; /* Handler for memory-mapped I/O */ - s->mmio_index = - cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, s, "pcnet-mmio", + PCNET_PNPMMIO_SIZE); - pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE, - PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map); + memory_region_init_io(&d->io_bar, &pcnet_io_ops, s, "pcnet-io", + PCNET_IOPORT_SIZE); + pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar); - pci_register_bar(pci_dev, 1, PCNET_PNPMMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, pcnet_mmio_map); + pci_register_bar(pci_dev, 1, 0, &s->mmio); s->irq = pci_dev->irq[0]; s->phys_mem_read = pci_physical_memory_read; s->phys_mem_write = pci_physical_memory_write; + s->dma_opaque = pci_dev; if (!pci_dev->qdev.hotplugged) { static int loaded = 0; if (!loaded) { - rom_add_option("pxe-pcnet.bin", -1); + rom_add_option("pxe-pcnet.rom", -1); loaded = 1; } } @@ -332,6 +355,10 @@ static PCIDeviceInfo pcnet_info = { .qdev.vmsd = &vmstate_pci_pcnet, .init = pci_pcnet_init, .exit = pci_pcnet_uninit, + .vendor_id = PCI_VENDOR_ID_AMD, + .device_id = PCI_DEVICE_ID_AMD_LANCE, + .revision = 0x10, + .class_id = PCI_CLASS_NETWORK_ETHERNET, .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/pcnet.c b/hw/pcnet.c index db52dc5..cba253b 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -58,24 +58,6 @@ struct qemu_ether_header { uint16_t ether_type; }; -/* BUS CONFIGURATION REGISTERS */ -#define BCR_MSRDA 0 -#define BCR_MSWRA 1 -#define BCR_MC 2 -#define BCR_LNKST 4 -#define BCR_LED1 5 -#define BCR_LED2 6 -#define BCR_LED3 7 -#define BCR_FDC 9 -#define BCR_BSBC 18 -#define BCR_EECAS 19 -#define BCR_SWS 20 -#define BCR_PLAT 22 - -#define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080) -#define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100) -#define BCR_SWSTYLE(S) ((S)->bcr[BCR_SWS ] & 0x00FF) - #define CSR_INIT(S) !!(((S)->csr[0])&0x0001) #define CSR_STRT(S) !!(((S)->csr[0])&0x0002) #define CSR_STOP(S) !!(((S)->csr[0])&0x0004) @@ -113,23 +95,23 @@ struct qemu_ether_header { #define CSR_XMTRL(S) ((S)->csr[78]) #define CSR_MISSC(S) ((S)->csr[112]) -#define CSR_IADR(S) ((S)->csr[ 1] | ((S)->csr[ 2] << 16)) -#define CSR_CRBA(S) ((S)->csr[18] | ((S)->csr[19] << 16)) -#define CSR_CXBA(S) ((S)->csr[20] | ((S)->csr[21] << 16)) -#define CSR_NRBA(S) ((S)->csr[22] | ((S)->csr[23] << 16)) -#define CSR_BADR(S) ((S)->csr[24] | ((S)->csr[25] << 16)) -#define CSR_NRDA(S) ((S)->csr[26] | ((S)->csr[27] << 16)) -#define CSR_CRDA(S) ((S)->csr[28] | ((S)->csr[29] << 16)) -#define CSR_BADX(S) ((S)->csr[30] | ((S)->csr[31] << 16)) -#define CSR_NXDA(S) ((S)->csr[32] | ((S)->csr[33] << 16)) -#define CSR_CXDA(S) ((S)->csr[34] | ((S)->csr[35] << 16)) -#define CSR_NNRD(S) ((S)->csr[36] | ((S)->csr[37] << 16)) -#define CSR_NNXD(S) ((S)->csr[38] | ((S)->csr[39] << 16)) -#define CSR_PXDA(S) ((S)->csr[60] | ((S)->csr[61] << 16)) -#define CSR_NXBA(S) ((S)->csr[64] | ((S)->csr[65] << 16)) +#define CSR_IADR(S) ((S)->csr[ 1] | ((uint32_t)(S)->csr[ 2] << 16)) +#define CSR_CRBA(S) ((S)->csr[18] | ((uint32_t)(S)->csr[19] << 16)) +#define CSR_CXBA(S) ((S)->csr[20] | ((uint32_t)(S)->csr[21] << 16)) +#define CSR_NRBA(S) ((S)->csr[22] | ((uint32_t)(S)->csr[23] << 16)) +#define CSR_BADR(S) ((S)->csr[24] | ((uint32_t)(S)->csr[25] << 16)) +#define CSR_NRDA(S) ((S)->csr[26] | ((uint32_t)(S)->csr[27] << 16)) +#define CSR_CRDA(S) ((S)->csr[28] | ((uint32_t)(S)->csr[29] << 16)) +#define CSR_BADX(S) ((S)->csr[30] | ((uint32_t)(S)->csr[31] << 16)) +#define CSR_NXDA(S) ((S)->csr[32] | ((uint32_t)(S)->csr[33] << 16)) +#define CSR_CXDA(S) ((S)->csr[34] | ((uint32_t)(S)->csr[35] << 16)) +#define CSR_NNRD(S) ((S)->csr[36] | ((uint32_t)(S)->csr[37] << 16)) +#define CSR_NNXD(S) ((S)->csr[38] | ((uint32_t)(S)->csr[39] << 16)) +#define CSR_PXDA(S) ((S)->csr[60] | ((uint32_t)(S)->csr[61] << 16)) +#define CSR_NXBA(S) ((S)->csr[64] | ((uint32_t)(S)->csr[65] << 16)) #define PHYSADDR(S,A) \ - (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16)) + (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16)) struct pcnet_initblk16 { uint16_t mode; @@ -1215,6 +1197,13 @@ ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_) return size_; } +void pcnet_set_link_status(VLANClientState *nc) +{ + PCNetState *d = DO_UPCAST(NICState, nc, nc)->opaque; + + d->lnkst = nc->link_down ? 0 : 0x40; +} + static void pcnet_transmit(PCNetState *s) { target_phys_addr_t xmit_cxda = 0; @@ -1336,7 +1325,7 @@ static void pcnet_poll_timer(void *opaque) pcnet_update_irq(s); if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) { - uint64_t now = qemu_get_clock(vm_clock) * 33; + uint64_t now = qemu_get_clock_ns(vm_clock) * 33; if (!s->timer || !now) s->timer = now; else { @@ -1348,7 +1337,7 @@ static void pcnet_poll_timer(void *opaque) CSR_POLL(s) = t; } qemu_mod_timer(s->poll_timer, - pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock))); + pcnet_get_next_poll_time(s,qemu_get_clock_ns(vm_clock))); } } @@ -1557,19 +1546,6 @@ uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap) void pcnet_h_reset(void *opaque) { PCNetState *s = opaque; - int i; - uint16_t checksum; - - /* Initialize the PROM */ - - memcpy(s->prom, s->conf.macaddr.a, 6); - s->prom[12] = s->prom[13] = 0x00; - s->prom[14] = s->prom[15] = 0x57; - - for (i = 0,checksum = 0; i < 16; i++) - checksum += s->prom[i]; - *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum); - s->bcr[BCR_MSRDA] = 0x0005; s->bcr[BCR_MSWRA] = 0x0005; @@ -1736,7 +1712,10 @@ void pcnet_common_cleanup(PCNetState *d) int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info) { - s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s); + int i; + uint16_t checksum; + + s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(info, &s->conf, dev->info->name, dev->id, s); @@ -1744,5 +1723,32 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info) add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0"); + /* Initialize the PROM */ + + /* + Datasheet: http://pdfdata.datasheetsite.com/web/24528/AM79C970A.pdf + page 95 + */ + memcpy(s->prom, s->conf.macaddr.a, 6); + /* Reserved Location: must be 00h */ + s->prom[6] = s->prom[7] = 0x00; + /* Reserved Location: must be 00h */ + s->prom[8] = 0x00; + /* Hardware ID: must be 11h if compatibility to AMD drivers is desired */ + s->prom[9] = 0x11; + /* User programmable space, init with 0 */ + s->prom[10] = s->prom[11] = 0x00; + /* LSByte of two-byte checksum, which is the sum of bytes 00h-0Bh + and bytes 0Eh and 0Fh, must therefore be initialized with 0! */ + s->prom[12] = s->prom[13] = 0x00; + /* Must be ASCII W (57h) if compatibility to AMD + driver software is desired */ + s->prom[14] = s->prom[15] = 0x57; + + for (i = 0, checksum = 0; i < 16; i++) { + checksum += s->prom[i]; + } + *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum); + return 0; } diff --git a/hw/pcnet.h b/hw/pcnet.h index 534bdf9..edc81c9 100644 --- a/hw/pcnet.h +++ b/hw/pcnet.h @@ -4,6 +4,26 @@ #define PCNET_LOOPTEST_CRC 1 #define PCNET_LOOPTEST_NOCRC 2 +#include "memory.h" + +/* BUS CONFIGURATION REGISTERS */ +#define BCR_MSRDA 0 +#define BCR_MSWRA 1 +#define BCR_MC 2 +#define BCR_LNKST 4 +#define BCR_LED1 5 +#define BCR_LED2 6 +#define BCR_LED3 7 +#define BCR_FDC 9 +#define BCR_BSBC 18 +#define BCR_EECAS 19 +#define BCR_SWS 20 +#define BCR_PLAT 22 + +#define BCR_APROMWE(S) !!((S)->bcr[BCR_MC ] & 0x0100) +#define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080) +#define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100) +#define BCR_SWSTYLE(S) ((S)->bcr[BCR_SWS ] & 0x00FF) typedef struct PCNetState_st PCNetState; @@ -16,16 +36,17 @@ struct PCNetState_st { uint8_t prom[16]; uint16_t csr[128]; uint16_t bcr[32]; + int xmit_pos; uint64_t timer; - int mmio_index, xmit_pos; + MemoryRegion mmio; uint8_t buffer[4096]; - int tx_busy; qemu_irq irq; void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap); void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr, uint8_t *buf, int len, int do_bswap); void *dma_opaque; + int tx_busy; int looptest; }; @@ -37,6 +58,7 @@ uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr); uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap); int pcnet_can_receive(VLANClientState *nc); ssize_t pcnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size_); +void pcnet_set_link_status(VLANClientState *nc); void pcnet_common_cleanup(PCNetState *d); int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info); extern const VMStateDescription vmstate_pcnet; diff --git a/hw/pcspk.c b/hw/pcspk.c index 26a0ecb..7fa2d36 100644 --- a/hw/pcspk.c +++ b/hw/pcspk.c @@ -37,7 +37,7 @@ typedef struct { uint8_t sample_buf[PCSPK_BUF_LEN]; QEMUSoundCard card; SWVoiceOut *voice; - PITState *pit; + ISADevice *pit; unsigned int pit_count; unsigned int samples; unsigned int play_pos; @@ -118,7 +118,7 @@ static uint32_t pcspk_ioport_read(void *opaque, uint32_t addr) int out; s->dummy_refresh_clock ^= (1 << 4); - out = pit_get_out(s->pit, 2, qemu_get_clock(vm_clock)) << 5; + out = pit_get_out(s->pit, 2, qemu_get_clock_ns(vm_clock)) << 5; return pit_get_gate(s->pit, 2) | (s->data_on << 1) | s->dummy_refresh_clock | out; } @@ -137,7 +137,7 @@ static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -void pcspk_init(PITState *pit) +void pcspk_init(ISADevice *pit) { PCSpkState *s = &pcspk_state; diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c index 42de459..17da2fd 100644 --- a/hw/petalogix_s3adsp1800_mmu.c +++ b/hw/petalogix_s3adsp1800_mmu.c @@ -35,6 +35,9 @@ #include "loader.h" #include "elf.h" #include "blockdev.h" +#include "exec-memory.h" + +#include "microblaze_pic_cpu.h" #define LMB_BRAM_SIZE (128 * 1024) #define FLASH_SIZE (16 * 1024 * 1024) @@ -75,7 +78,7 @@ static int petalogix_load_device_tree(target_phys_addr_t addr, path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); if (path) { fdt = load_device_tree(path, &fdt_size); - qemu_free(path); + g_free(path); } if (!fdt) return 0; @@ -93,7 +96,7 @@ static int petalogix_load_device_tree(target_phys_addr_t addr, path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); if (path) { fdt_size = load_image_targphys(path, addr, 0x10000); - qemu_free(path); + g_free(path); } } @@ -123,10 +126,10 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size, DriveInfo *dinfo; int i; target_phys_addr_t ddr_base = 0x90000000; - ram_addr_t phys_lmb_bram; - ram_addr_t phys_ram; - ram_addr_t phys_flash; + MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1); + MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq irq[32], *cpu_irq; + MemoryRegion *sysmem = get_system_memory(); /* init CPUs */ if (cpu_model == NULL) { @@ -138,17 +141,17 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size, qemu_register_reset(main_cpu_reset, env); /* Attach emulated BRAM through the LMB. */ - phys_lmb_bram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.lmb_bram", - LMB_BRAM_SIZE); - cpu_register_physical_memory(0x00000000, LMB_BRAM_SIZE, - phys_lmb_bram | IO_MEM_RAM); + memory_region_init_ram(phys_lmb_bram, NULL, + "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE); + memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram); - phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size); - cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM); + memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram", + ram_size); + memory_region_add_subregion(sysmem, ddr_base, phys_ram); - phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi01_register(0xa0000000, phys_flash, + pflash_cfi01_register(0xa0000000, + NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 1, 0x89, 0x18, 0x0000, 0x0, 1); @@ -167,16 +170,21 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size, if (kernel_filename) { uint64_t entry, low, high; uint32_t base32; + int big_endian = 0; + +#ifdef TARGET_WORDS_BIGENDIAN + big_endian = 1; +#endif /* Boots a kernel elf binary. */ kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, &low, &high, - 1, ELF_MACHINE, 0); + big_endian, ELF_MACHINE, 0); base32 = entry; if (base32 == 0xc0000000) { kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, &entry, NULL, NULL, - 1, ELF_MACHINE, 0); + big_endian, ELF_MACHINE, 0); } /* Always boot into physical ram. */ boot_info.bootstrap_pc = ddr_base + (entry & 0x0fffffff); @@ -212,7 +220,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size, static QEMUMachine petalogix_s3adsp1800_machine = { .name = "petalogix-s3adsp1800", - .desc = "Petalogix linux refdesign for xilinx Spartan 3ADSP1800", + .desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800", .init = petalogix_s3adsp1800_init, .is_default = 1 }; diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index fb20dfb..69b8e3d 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -40,6 +40,7 @@ #include "flash.h" #include "block.h" #include "qemu-timer.h" +#include "exec-memory.h" #define PFLASH_BUG(fmt, ...) \ do { \ @@ -74,8 +75,7 @@ struct pflash_t { target_phys_addr_t counter; unsigned int writeblock_size; QEMUTimer *timer; - ram_addr_t off; - int fl_mem; + MemoryRegion mem; void *storage; }; @@ -89,8 +89,7 @@ static void pflash_timer (void *opaque) if (pfl->bypass) { pfl->wcycle = 2; } else { - cpu_register_physical_memory(pfl->base, pfl->total_len, - pfl->off | IO_MEM_ROMD | pfl->fl_mem); + memory_region_rom_device_set_readable(&pfl->mem, true); pfl->wcycle = 0; } pfl->cmd = 0; @@ -263,7 +262,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, if (!pfl->wcycle) { /* Set the device in I/O access mode */ - cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem); + memory_region_rom_device_set_readable(&pfl->mem, false); } switch (pfl->wcycle) { @@ -422,8 +421,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset, __func__, offset, pfl->wcycle, pfl->cmd, value); reset_flash: - cpu_register_physical_memory(pfl->base, pfl->total_len, - pfl->off | IO_MEM_ROMD | pfl->fl_mem); + memory_region_rom_device_set_readable(&pfl->mem, true); pfl->bypass = 0; pfl->wcycle = 0; @@ -514,28 +512,20 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr, pflash_write(pfl, addr, value, 4, 0); } -static CPUWriteMemoryFunc * const pflash_write_ops_be[] = { - &pflash_writeb_be, - &pflash_writew_be, - &pflash_writel_be, +static const MemoryRegionOps pflash_cfi01_ops_be = { + .old_mmio = { + .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, }, + .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUReadMemoryFunc * const pflash_read_ops_be[] = { - &pflash_readb_be, - &pflash_readw_be, - &pflash_readl_be, -}; - -static CPUWriteMemoryFunc * const pflash_write_ops_le[] = { - &pflash_writeb_le, - &pflash_writew_le, - &pflash_writel_le, -}; - -static CPUReadMemoryFunc * const pflash_read_ops_le[] = { - &pflash_readb_le, - &pflash_readw_le, - &pflash_readl_le, +static const MemoryRegionOps pflash_cfi01_ops_le = { + .old_mmio = { + .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, }, + .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; /* Count trailing zeroes of a 32 bits quantity */ @@ -574,12 +564,13 @@ static int ctz32 (uint32_t n) return ret; } -pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi01_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3, - int be) + uint16_t id2, uint16_t id3, int be) { pflash_t *pfl; target_phys_addr_t total_len; @@ -594,32 +585,25 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, return NULL; #endif - pfl = qemu_mallocz(sizeof(pflash_t)); + pfl = g_malloc0(sizeof(pflash_t)); - /* FIXME: Allocate ram ourselves. */ - pfl->storage = qemu_get_ram_ptr(off); - if (be) { - pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be, - pflash_write_ops_be, pfl, - DEVICE_NATIVE_ENDIAN); - } else { - pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le, - pflash_write_ops_le, pfl, - DEVICE_NATIVE_ENDIAN); - } - pfl->off = off; - cpu_register_physical_memory(base, total_len, - off | pfl->fl_mem | IO_MEM_ROMD); + memory_region_init_rom_device( + &pfl->mem, be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl, + qdev, name, size); + pfl->storage = memory_region_get_ram_ptr(&pfl->mem); + memory_region_add_subregion(get_system_memory(), base, &pfl->mem); pfl->bs = bs; if (pfl->bs) { /* read the initial flash content */ ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9); if (ret < 0) { - cpu_unregister_io_memory(pfl->fl_mem); - qemu_free(pfl); + memory_region_del_subregion(get_system_memory(), &pfl->mem); + memory_region_destroy(&pfl->mem); + g_free(pfl); return NULL; } + bdrv_attach_dev_nofail(pfl->bs, pfl); } #if 0 /* XXX: there should be a bit to set up read-only, * the same way the hardware does (with WP pin). @@ -628,7 +612,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, #else pfl->ro = 0; #endif - pfl->timer = qemu_new_timer(vm_clock, pflash_timer, pfl); + pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl); pfl->base = base; pfl->sector_len = sector_len; pfl->total_len = total_len; @@ -724,3 +708,8 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, return pfl; } + +MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl) +{ + return &fl->mem; +} diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index 3594a36..e5a63da 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -39,6 +39,7 @@ #include "flash.h" #include "qemu-timer.h" #include "block.h" +#include "exec-memory.h" //#define PFLASH_DEBUG #ifdef PFLASH_DEBUG @@ -50,6 +51,8 @@ do { \ #define DPRINTF(fmt, ...) do { } while (0) #endif +#define PFLASH_LAZY_ROMD_THRESHOLD 42 + struct pflash_t { BlockDriverState *bs; target_phys_addr_t base; @@ -67,24 +70,38 @@ struct pflash_t { uint8_t cfi_len; uint8_t cfi_table[0x52]; QEMUTimer *timer; - ram_addr_t off; - int fl_mem; + /* The device replicates the flash memory across its memory space. Emulate + * that by having a container (.mem) filled with an array of aliases + * (.mem_mappings) pointing to the flash memory (.orig_mem). + */ + MemoryRegion mem; + MemoryRegion *mem_mappings; /* array; one per mapping */ + MemoryRegion orig_mem; int rom_mode; + int read_counter; /* used for lazy switch-back to rom mode */ void *storage; }; -static void pflash_register_memory(pflash_t *pfl, int rom_mode) +/* + * Set up replicated mappings of the same region. + */ +static void pflash_setup_mappings(pflash_t *pfl) { - unsigned long phys_offset = pfl->fl_mem; - int i; - - if (rom_mode) - phys_offset |= pfl->off | IO_MEM_ROMD; - pfl->rom_mode = rom_mode; + unsigned i; + target_phys_addr_t size = memory_region_size(&pfl->orig_mem); + + memory_region_init(&pfl->mem, "pflash", pfl->mappings * size); + pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings); + for (i = 0; i < pfl->mappings; ++i) { + memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias", + &pfl->orig_mem, 0, size); + memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]); + } +} - for (i = 0; i < pfl->mappings; i++) - cpu_register_physical_memory(pfl->base + i * pfl->chip_len, - pfl->chip_len, phys_offset); +static void pflash_register_memory(pflash_t *pfl, int rom_mode) +{ + memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode); } static void pflash_timer (void *opaque) @@ -112,10 +129,10 @@ static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset, DPRINTF("%s: offset " TARGET_FMT_plx "\n", __func__, offset); ret = -1; - if (pfl->rom_mode) { - /* Lazy reset of to ROMD mode */ - if (pfl->wcycle == 0) - pflash_register_memory(pfl, 1); + /* Lazy reset to ROMD mode after a certain amount of read accesses */ + if (!pfl->rom_mode && pfl->wcycle == 0 && + ++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) { + pflash_register_memory(pfl, 1); } offset &= pfl->chip_len - 1; boff = offset & 0xFF; @@ -185,7 +202,7 @@ static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset, default: goto flash_read; } - DPRINTF("%s: ID " TARGET_FMT_pld " %x\n", __func__, boff, ret); + DPRINTF("%s: ID " TARGET_FMT_plx " %x\n", __func__, boff, ret); break; case 0xA0: case 0x10: @@ -254,6 +271,7 @@ static void pflash_write (pflash_t *pfl, target_phys_addr_t offset, /* Set the device in I/O access mode if required */ if (pfl->rom_mode) pflash_register_memory(pfl, 0); + pfl->read_counter = 0; /* We're in read mode */ check_unlock0: if (boff == 0x55 && cmd == 0x98) { @@ -363,7 +381,7 @@ static void pflash_write (pflash_t *pfl, target_phys_addr_t offset, case 4: switch (pfl->cmd) { case 0xA0: - /* Ignore writes while flash data write is occuring */ + /* Ignore writes while flash data write is occurring */ /* As we suppose write is immediate, this should never happen */ return; case 0x80: @@ -390,7 +408,7 @@ static void pflash_write (pflash_t *pfl, target_phys_addr_t offset, pflash_update(pfl, 0, pfl->chip_len); /* Let's wait 5 seconds before chip erase is done */ qemu_mod_timer(pfl->timer, - qemu_get_clock(vm_clock) + (get_ticks_per_sec() * 5)); + qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() * 5)); break; case 0x30: /* Sector erase */ @@ -403,7 +421,7 @@ static void pflash_write (pflash_t *pfl, target_phys_addr_t offset, pfl->status = 0x00; /* Let's wait 1/2 second before sector erase is done */ qemu_mod_timer(pfl->timer, - qemu_get_clock(vm_clock) + (get_ticks_per_sec() / 2)); + qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 2)); break; default: DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd); @@ -534,28 +552,20 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr, pflash_write(pfl, addr, value, 4, 0); } -static CPUWriteMemoryFunc * const pflash_write_ops_be[] = { - &pflash_writeb_be, - &pflash_writew_be, - &pflash_writel_be, -}; - -static CPUReadMemoryFunc * const pflash_read_ops_be[] = { - &pflash_readb_be, - &pflash_readw_be, - &pflash_readl_be, +static const MemoryRegionOps pflash_cfi02_ops_be = { + .old_mmio = { + .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, }, + .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const pflash_write_ops_le[] = { - &pflash_writeb_le, - &pflash_writew_le, - &pflash_writel_le, -}; - -static CPUReadMemoryFunc * const pflash_read_ops_le[] = { - &pflash_readb_le, - &pflash_readw_le, - &pflash_readl_le, +static const MemoryRegionOps pflash_cfi02_ops_le = { + .old_mmio = { + .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, }, + .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; /* Count trailing zeroes of a 32 bits quantity */ @@ -594,7 +604,9 @@ static int ctz32 (uint32_t n) return ret; } -pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, +pflash_t *pflash_cfi02_register(target_phys_addr_t base, + DeviceState *qdev, const char *name, + target_phys_addr_t size, BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int nb_mappings, int width, uint16_t id0, uint16_t id1, @@ -613,33 +625,27 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024)) return NULL; #endif - pfl = qemu_mallocz(sizeof(pflash_t)); - /* FIXME: Allocate ram ourselves. */ - pfl->storage = qemu_get_ram_ptr(off); - if (be) { - pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be, - pflash_write_ops_be, - pfl, DEVICE_NATIVE_ENDIAN); - } else { - pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le, - pflash_write_ops_le, - pfl, DEVICE_NATIVE_ENDIAN); - } - pfl->off = off; + pfl = g_malloc0(sizeof(pflash_t)); + memory_region_init_rom_device( + &pfl->orig_mem, be ? &pflash_cfi02_ops_be : &pflash_cfi02_ops_le, pfl, + qdev, name, size); + pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem); pfl->base = base; pfl->chip_len = chip_len; pfl->mappings = nb_mappings; - pflash_register_memory(pfl, 1); pfl->bs = bs; if (pfl->bs) { /* read the initial flash content */ ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9); if (ret < 0) { - cpu_unregister_io_memory(pfl->fl_mem); - qemu_free(pfl); + g_free(pfl); return NULL; } + bdrv_attach_dev_nofail(pfl->bs, pfl); } + pflash_setup_mappings(pfl); + pfl->rom_mode = 1; + memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem); #if 0 /* XXX: there should be a bit to set up read-only, * the same way the hardware does (with WP pin). */ @@ -647,7 +653,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, #else pfl->ro = 0; #endif - pfl->timer = qemu_new_timer(vm_clock, pflash_timer, pfl); + pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl); pfl->sector_len = sector_len; pfl->width = width; pfl->wcycle = 0; diff --git a/hw/piix4.c b/hw/piix4.c index 72073cd..2fd1171 100644 --- a/hw/piix4.c +++ b/hw/piix4.c @@ -30,10 +30,14 @@ PCIDevice *piix4_dev; +typedef struct PIIX4State { + PCIDevice dev; +} PIIX4State; + static void piix4_reset(void *opaque) { - PCIDevice *d = opaque; - uint8_t *pci_conf = d->config; + PIIX4State *d = opaque; + uint8_t *pci_conf = d->dev.config; pci_conf[0x04] = 0x07; // master, memory and I/O pci_conf[0x05] = 0x00; @@ -68,33 +72,23 @@ static void piix4_reset(void *opaque) pci_conf[0xae] = 0x00; } -static void piix_save(QEMUFile* f, void *opaque) -{ - PCIDevice *d = opaque; - pci_device_save(d, f); -} - -static int piix_load(QEMUFile* f, void *opaque, int version_id) -{ - PCIDevice *d = opaque; - if (version_id != 2) - return -EINVAL; - return pci_device_load(d, f); -} +static const VMStateDescription vmstate_piix4 = { + .name = "PIIX4", + .version_id = 2, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, PIIX4State), + VMSTATE_END_OF_LIST() + } +}; -static int piix4_initfn(PCIDevice *d) +static int piix4_initfn(PCIDevice *dev) { - uint8_t *pci_conf; - - isa_bus_new(&d->qdev); - register_savevm(&d->qdev, "PIIX4", 0, 2, piix_save, piix_load, d); - - pci_conf = d->config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge - pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); + PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev); - piix4_dev = d; + isa_bus_new(&d->dev.qdev, pci_address_space_io(dev)); + piix4_dev = &d->dev; qemu_register_reset(piix4_reset, d); return 0; } @@ -111,10 +105,14 @@ static PCIDeviceInfo piix4_info[] = { { .qdev.name = "PIIX4", .qdev.desc = "ISA bridge", - .qdev.size = sizeof(PCIDevice), + .qdev.size = sizeof(PIIX4State), + .qdev.vmsd = &vmstate_piix4, .qdev.no_user = 1, .no_hotplug = 1, .init = piix4_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371AB_0, // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge + .class_id = PCI_CLASS_BRIDGE_ISA, },{ /* end of list */ } diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 358da58..d183443 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -29,6 +29,7 @@ #include "isa.h" #include "sysbus.h" #include "range.h" +#include "xen.h" /* * I440FX chipset data sheet. @@ -37,16 +38,50 @@ typedef PCIHostState I440FXState; +#define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ +#define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */ +#define XEN_PIIX_NUM_PIRQS 128ULL +#define PIIX_PIRQC 0x60 + typedef struct PIIX3State { PCIDevice dev; - int pci_irq_levels[4]; + + /* + * bitmap to track pic levels. + * The pic level is the logical OR of all the PCI irqs mapped to it + * So one PIC level is tracked by PIIX_NUM_PIRQS bits. + * + * PIRQ is mapped to PIC pins, we track it by + * PIIX_NUM_PIRQS * PIIX_NUM_PIC_IRQS = 64 bits with + * pic_irq * PIIX_NUM_PIRQS + pirq + */ +#if PIIX_NUM_PIC_IRQS * PIIX_NUM_PIRQS > 64 +#error "unable to encode pic state in 64bit in pic_levels." +#endif + uint64_t pic_levels; + qemu_irq *pic; + + /* This member isn't used. Just for save/load compatibility */ + int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS]; } PIIX3State; +typedef struct PAMMemoryRegion { + MemoryRegion mem; + bool initialized; +} PAMMemoryRegion; + struct PCII440FXState { PCIDevice dev; - target_phys_addr_t isa_page_descs[384 / 4]; + MemoryRegion *system_memory; + MemoryRegion *pci_address_space; + MemoryRegion *ram_memory; + MemoryRegion pci_hole; + MemoryRegion pci_hole_64bit; + PAMMemoryRegion pam_regions[13]; + MemoryRegion smram_region; uint8_t smm_enabled; + bool smram_enabled; PIIX3State *piix3; }; @@ -55,64 +90,80 @@ struct PCII440FXState { #define I440FX_PAM_SIZE 7 #define I440FX_SMRAM 0x72 -static void piix3_set_irq(void *opaque, int irq_num, int level); +static void piix3_set_irq(void *opaque, int pirq, int level); +static void piix3_write_config_xen(PCIDevice *dev, + uint32_t address, uint32_t val, int len); /* return the global irq number corresponding to a given device irq pin. We could also use the bus number to have a more precise mapping. */ -static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) +static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx) { int slot_addend; slot_addend = (pci_dev->devfn >> 3) - 1; - return (irq_num + slot_addend) & 3; + return (pci_intx + slot_addend) & 3; } -static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r) +static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r, + PAMMemoryRegion *mem) { - uint32_t addr; + if (mem->initialized) { + memory_region_del_subregion(d->system_memory, &mem->mem); + memory_region_destroy(&mem->mem); + } // printf("ISA mapping %08x-0x%08x: %d\n", start, end, r); switch(r) { case 3: /* RAM */ - cpu_register_physical_memory(start, end - start, - start); + memory_region_init_alias(&mem->mem, "pam-ram", d->ram_memory, + start, end - start); break; case 1: /* ROM (XXX: not quite correct) */ - cpu_register_physical_memory(start, end - start, - start | IO_MEM_ROM); + memory_region_init_alias(&mem->mem, "pam-rom", d->ram_memory, + start, end - start); + memory_region_set_readonly(&mem->mem, true); break; case 2: case 0: /* XXX: should distinguish read/write cases */ - for(addr = start; addr < end; addr += 4096) { - cpu_register_physical_memory(addr, 4096, - d->isa_page_descs[(addr - 0xa0000) >> 12]); - } + memory_region_init_alias(&mem->mem, "pam-pci", d->pci_address_space, + start, end - start); break; } + memory_region_add_subregion_overlap(d->system_memory, + start, &mem->mem, 1); + mem->initialized = true; } static void i440fx_update_memory_mappings(PCII440FXState *d) { int i, r; - uint32_t smram, addr; + uint32_t smram; - update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3); + memory_region_transaction_begin(); + update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3, + &d->pam_regions[0]); for(i = 0; i < 12; i++) { r = (d->dev.config[(i >> 1) + (I440FX_PAM + 1)] >> ((i & 1) * 4)) & 3; - update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r); + update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r, + &d->pam_regions[i+1]); } smram = d->dev.config[I440FX_SMRAM]; if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) { - cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000); + if (!d->smram_enabled) { + memory_region_del_subregion(d->system_memory, &d->smram_region); + d->smram_enabled = true; + } } else { - for(addr = 0xa0000; addr < 0xc0000; addr += 4096) { - cpu_register_physical_memory(addr, 4096, - d->isa_page_descs[(addr - 0xa0000) >> 12]); + if (d->smram_enabled) { + memory_region_add_subregion_overlap(d->system_memory, 0xa0000, + &d->smram_region, 1); + d->smram_enabled = false; } } + memory_region_transaction_commit(); } static void i440fx_set_smm(int val, void *arg) @@ -127,17 +178,6 @@ static void i440fx_set_smm(int val, void *arg) } -/* XXX: suppress when better memory API. We make the assumption that - no device (in particular the VGA) changes the memory mappings in - the 0xa0000-0x100000 range */ -void i440fx_init_memory_mappings(PCII440FXState *d) -{ - int i; - for(i = 0; i < 96; i++) { - d->isa_page_descs[i] = cpu_get_physical_page_desc(0xa0000 + i * 0x1000); - } -} - static void i440fx_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len) { @@ -162,9 +202,11 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id) i440fx_update_memory_mappings(d); qemu_get_8s(f, &d->smm_enabled); - if (version_id == 2) - for (i = 0; i < 4; i++) - d->piix3->pci_irq_levels[i] = qemu_get_be32(f); + if (version_id == 2) { + for (i = 0; i < PIIX_NUM_PIRQS; i++) { + qemu_get_be32(f); /* dummy load for compatibility */ + } + } return 0; } @@ -195,9 +237,16 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev) { I440FXState *s = FROM_SYSBUS(I440FXState, dev); - pci_host_conf_register_ioport(0xcf8, s); + memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s, + "pci-conf-idx", 4); + sysbus_add_io(dev, 0xcf8, &s->conf_mem); + sysbus_init_ioports(&s->busdev, 0xcf8, 4); + + memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s, + "pci-conf-data", 4); + sysbus_add_io(dev, 0xcfc, &s->data_mem); + sysbus_init_ioports(&s->busdev, 0xcfc, 4); - pci_host_data_register_ioport(0xcfc, s); return 0; } @@ -205,38 +254,78 @@ static int i440fx_initfn(PCIDevice *dev) { PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev); - pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82441); - d->dev.config[0x08] = 0x02; // revision - pci_config_set_class(d->dev.config, PCI_CLASS_BRIDGE_HOST); - d->dev.config[I440FX_SMRAM] = 0x02; cpu_smm_register(&i440fx_set_smm, d); return 0; } -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size) +static PCIBus *i440fx_common_init(const char *device_name, + PCII440FXState **pi440fx_state, + int *piix3_devfn, + qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + ram_addr_t ram_size, + target_phys_addr_t pci_hole_start, + target_phys_addr_t pci_hole_size, + target_phys_addr_t pci_hole64_start, + target_phys_addr_t pci_hole64_size, + MemoryRegion *pci_address_space, + MemoryRegion *ram_memory) { DeviceState *dev; PCIBus *b; PCIDevice *d; I440FXState *s; PIIX3State *piix3; + PCII440FXState *f; dev = qdev_create(NULL, "i440FX-pcihost"); s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev)); - b = pci_bus_new(&s->busdev.qdev, NULL, 0); + s->address_space = address_space_mem; + b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space, + address_space_io, 0); s->bus = b; qdev_init_nofail(dev); - d = pci_create_simple(b, 0, "i440FX"); + d = pci_create_simple(b, 0, device_name); *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); - - piix3 = DO_UPCAST(PIIX3State, dev, - pci_create_simple_multifunction(b, -1, true, "PIIX3")); + f = *pi440fx_state; + f->system_memory = address_space_mem; + f->pci_address_space = pci_address_space; + f->ram_memory = ram_memory; + memory_region_init_alias(&f->pci_hole, "pci-hole", f->pci_address_space, + pci_hole_start, pci_hole_size); + memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole); + memory_region_init_alias(&f->pci_hole_64bit, "pci-hole64", + f->pci_address_space, + pci_hole64_start, pci_hole64_size); + if (pci_hole64_size) { + memory_region_add_subregion(f->system_memory, pci_hole64_start, + &f->pci_hole_64bit); + } + memory_region_init_alias(&f->smram_region, "smram-region", + f->pci_address_space, 0xa0000, 0x20000); + f->smram_enabled = true; + + /* Xen supports additional interrupt routes from the PCI devices to + * the IOAPIC: the four pins of each PCI device on the bus are also + * connected to the IOAPIC directly. + * These additional routes can be discovered through ACPI. */ + if (xen_enabled()) { + piix3 = DO_UPCAST(PIIX3State, dev, + pci_create_simple_multifunction(b, -1, true, "PIIX3-xen")); + pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, + piix3, XEN_PIIX_NUM_PIRQS); + } else { + piix3 = DO_UPCAST(PIIX3State, dev, + pci_create_simple_multifunction(b, -1, true, "PIIX3")); + pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, + PIIX_NUM_PIRQS); + } piix3->pic = pic; - pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); + (*pi440fx_state)->piix3 = piix3; *piix3_devfn = piix3->dev.devfn; @@ -246,33 +335,98 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * ram_size = 255; (*pi440fx_state)->dev.config[0x57]=ram_size; + i440fx_update_memory_mappings(f); + + return b; +} + +PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, + qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io, + ram_addr_t ram_size, + target_phys_addr_t pci_hole_start, + target_phys_addr_t pci_hole_size, + target_phys_addr_t pci_hole64_start, + target_phys_addr_t pci_hole64_size, + MemoryRegion *pci_memory, MemoryRegion *ram_memory) + +{ + PCIBus *b; + + b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, + address_space_mem, address_space_io, ram_size, + pci_hole_start, pci_hole_size, + pci_hole64_size, pci_hole64_size, + pci_memory, ram_memory); return b; } /* PIIX3 PCI to ISA bridge */ +static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq) +{ + qemu_set_irq(piix3->pic[pic_irq], + !!(piix3->pic_levels & + (((1ULL << PIIX_NUM_PIRQS) - 1) << + (pic_irq * PIIX_NUM_PIRQS)))); +} -static void piix3_set_irq(void *opaque, int irq_num, int level) +static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level) +{ + int pic_irq; + uint64_t mask; + + pic_irq = piix3->dev.config[PIIX_PIRQC + pirq]; + if (pic_irq >= PIIX_NUM_PIC_IRQS) { + return; + } + + mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + pirq); + piix3->pic_levels &= ~mask; + piix3->pic_levels |= mask * !!level; + + piix3_set_irq_pic(piix3, pic_irq); +} + +static void piix3_set_irq(void *opaque, int pirq, int level) { - int i, pic_irq, pic_level; PIIX3State *piix3 = opaque; + piix3_set_irq_level(piix3, pirq, level); +} + +/* irq routing is changed. so rebuild bitmap */ +static void piix3_update_irq_levels(PIIX3State *piix3) +{ + int pirq; + + piix3->pic_levels = 0; + for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) { + piix3_set_irq_level(piix3, pirq, + pci_bus_get_irq_level(piix3->dev.bus, pirq)); + } +} - piix3->pci_irq_levels[irq_num] = level; - - /* now we change the pic irq level according to the piix irq mappings */ - /* XXX: optimize */ - pic_irq = piix3->dev.config[0x60 + irq_num]; - if (pic_irq < 16) { - /* The pic level is the logical OR of all the PCI irqs mapped - to it */ - pic_level = 0; - for (i = 0; i < 4; i++) { - if (pic_irq == piix3->dev.config[0x60 + i]) - pic_level |= piix3->pci_irq_levels[i]; +static void piix3_write_config(PCIDevice *dev, + uint32_t address, uint32_t val, int len) +{ + pci_default_write_config(dev, address, val, len); + if (ranges_overlap(address, len, PIIX_PIRQC, 4)) { + PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev); + int pic_irq; + piix3_update_irq_levels(piix3); + for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) { + piix3_set_irq_pic(piix3, pic_irq); } - qemu_set_irq(piix3->pic[pic_irq], pic_level); } } +static void piix3_write_config_xen(PCIDevice *dev, + uint32_t address, uint32_t val, int len) +{ + xen_piix_pci_write_config_client(address, val, len); + piix3_write_config(dev, address, val, len); +} + static void piix3_reset(void *opaque) { PIIX3State *d = opaque; @@ -310,7 +464,25 @@ static void piix3_reset(void *opaque) pci_conf[0xac] = 0x00; pci_conf[0xae] = 0x00; - memset(d->pci_irq_levels, 0, sizeof(d->pci_irq_levels)); + d->pic_levels = 0; +} + +static int piix3_post_load(void *opaque, int version_id) +{ + PIIX3State *piix3 = opaque; + piix3_update_irq_levels(piix3); + return 0; +} + +static void piix3_pre_save(void *opaque) +{ + int i; + PIIX3State *piix3 = opaque; + + for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) { + piix3->pci_irq_levels_vmstate[i] = + pci_bus_get_irq_level(piix3->dev.bus, i); + } } static const VMStateDescription vmstate_piix3 = { @@ -318,9 +490,12 @@ static const VMStateDescription vmstate_piix3 = { .version_id = 3, .minimum_version_id = 2, .minimum_version_id_old = 2, + .post_load = piix3_post_load, + .pre_save = piix3_pre_save, .fields = (VMStateField []) { VMSTATE_PCI_DEVICE(dev, PIIX3State), - VMSTATE_INT32_ARRAY_V(pci_irq_levels, PIIX3State, 4, 3), + VMSTATE_INT32_ARRAY_V(pci_irq_levels_vmstate, PIIX3State, + PIIX_NUM_PIRQS, 3), VMSTATE_END_OF_LIST() } }; @@ -328,15 +503,8 @@ static const VMStateDescription vmstate_piix3 = { static int piix3_initfn(PCIDevice *dev) { PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev); - uint8_t *pci_conf; - - isa_bus_new(&d->dev.qdev); - - pci_conf = d->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1) - pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); + isa_bus_new(&d->dev.qdev, pci_address_space_io(dev)); qemu_register_reset(piix3_reset, d); return 0; } @@ -351,6 +519,10 @@ static PCIDeviceInfo i440fx_info[] = { .no_hotplug = 1, .init = i440fx_initfn, .config_write = i440fx_write_config, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82441, + .revision = 0x02, + .class_id = PCI_CLASS_BRIDGE_HOST, },{ .qdev.name = "PIIX3", .qdev.desc = "ISA bridge", @@ -359,6 +531,22 @@ static PCIDeviceInfo i440fx_info[] = { .qdev.no_user = 1, .no_hotplug = 1, .init = piix3_initfn, + .config_write = piix3_write_config, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1) + .class_id = PCI_CLASS_BRIDGE_ISA, + },{ + .qdev.name = "PIIX3-xen", + .qdev.desc = "ISA bridge", + .qdev.size = sizeof(PIIX3State), + .qdev.vmsd = &vmstate_piix3, + .qdev.no_user = 1, + .no_hotplug = 1, + .init = piix3_initfn, + .config_write = piix3_write_config_xen, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1) + .class_id = PCI_CLASS_BRIDGE_ISA, },{ /* end of list */ } diff --git a/hw/pl011.c b/hw/pl011.c index 77f0dbf..707a161 100644 --- a/hw/pl011.c +++ b/hw/pl011.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -133,7 +133,7 @@ static void pl011_write(void *opaque, target_phys_addr_t offset, /* ??? Check if transmitter is enabled. */ ch = value; if (s->chr) - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); s->int_level |= PL011_INT_TX; pl011_update(s); break; @@ -235,56 +235,30 @@ static CPUWriteMemoryFunc * const pl011_writefn[] = { pl011_write }; -static void pl011_save(QEMUFile *f, void *opaque) -{ - pl011_state *s = (pl011_state *)opaque; - int i; - - qemu_put_be32(f, s->readbuff); - qemu_put_be32(f, s->flags); - qemu_put_be32(f, s->lcr); - qemu_put_be32(f, s->cr); - qemu_put_be32(f, s->dmacr); - qemu_put_be32(f, s->int_enabled); - qemu_put_be32(f, s->int_level); - for (i = 0; i < 16; i++) - qemu_put_be32(f, s->read_fifo[i]); - qemu_put_be32(f, s->ilpr); - qemu_put_be32(f, s->ibrd); - qemu_put_be32(f, s->fbrd); - qemu_put_be32(f, s->ifl); - qemu_put_be32(f, s->read_pos); - qemu_put_be32(f, s->read_count); - qemu_put_be32(f, s->read_trigger); -} - -static int pl011_load(QEMUFile *f, void *opaque, int version_id) -{ - pl011_state *s = (pl011_state *)opaque; - int i; - - if (version_id != 1) - return -EINVAL; - - s->readbuff = qemu_get_be32(f); - s->flags = qemu_get_be32(f); - s->lcr = qemu_get_be32(f); - s->cr = qemu_get_be32(f); - s->dmacr = qemu_get_be32(f); - s->int_enabled = qemu_get_be32(f); - s->int_level = qemu_get_be32(f); - for (i = 0; i < 16; i++) - s->read_fifo[i] = qemu_get_be32(f); - s->ilpr = qemu_get_be32(f); - s->ibrd = qemu_get_be32(f); - s->fbrd = qemu_get_be32(f); - s->ifl = qemu_get_be32(f); - s->read_pos = qemu_get_be32(f); - s->read_count = qemu_get_be32(f); - s->read_trigger = qemu_get_be32(f); - - return 0; -} +static const VMStateDescription vmstate_pl011 = { + .name = "pl011", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(readbuff, pl011_state), + VMSTATE_UINT32(flags, pl011_state), + VMSTATE_UINT32(lcr, pl011_state), + VMSTATE_UINT32(cr, pl011_state), + VMSTATE_UINT32(dmacr, pl011_state), + VMSTATE_UINT32(int_enabled, pl011_state), + VMSTATE_UINT32(int_level, pl011_state), + VMSTATE_UINT32_ARRAY(read_fifo, pl011_state, 16), + VMSTATE_UINT32(ilpr, pl011_state), + VMSTATE_UINT32(ibrd, pl011_state), + VMSTATE_UINT32(fbrd, pl011_state), + VMSTATE_UINT32(ifl, pl011_state), + VMSTATE_INT32(read_pos, pl011_state), + VMSTATE_INT32(read_count, pl011_state), + VMSTATE_INT32(read_trigger, pl011_state), + VMSTATE_END_OF_LIST() + } +}; static int pl011_init(SysBusDevice *dev, const unsigned char *id) { @@ -307,7 +281,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id) qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, pl011_event, s); } - register_savevm(&dev->qdev, "pl011_uart", -1, 1, pl011_save, pl011_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_pl011, s); return 0; } diff --git a/hw/pl022.c b/hw/pl022.c index ffe05ab..9a1cb71 100644 --- a/hw/pl022.c +++ b/hw/pl022.c @@ -4,7 +4,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -239,54 +239,42 @@ static CPUWriteMemoryFunc * const pl022_writefn[] = { pl022_write }; -static void pl022_save(QEMUFile *f, void *opaque) -{ - pl022_state *s = (pl022_state *)opaque; - int i; - - qemu_put_be32(f, s->cr0); - qemu_put_be32(f, s->cr1); - qemu_put_be32(f, s->bitmask); - qemu_put_be32(f, s->sr); - qemu_put_be32(f, s->cpsr); - qemu_put_be32(f, s->is); - qemu_put_be32(f, s->im); - qemu_put_be32(f, s->tx_fifo_head); - qemu_put_be32(f, s->rx_fifo_head); - qemu_put_be32(f, s->tx_fifo_len); - qemu_put_be32(f, s->rx_fifo_len); - for (i = 0; i < 8; i++) { - qemu_put_be16(f, s->tx_fifo[i]); - qemu_put_be16(f, s->rx_fifo[i]); - } -} - -static int pl022_load(QEMUFile *f, void *opaque, int version_id) -{ - pl022_state *s = (pl022_state *)opaque; - int i; - - if (version_id != 1) - return -EINVAL; - - s->cr0 = qemu_get_be32(f); - s->cr1 = qemu_get_be32(f); - s->bitmask = qemu_get_be32(f); - s->sr = qemu_get_be32(f); - s->cpsr = qemu_get_be32(f); - s->is = qemu_get_be32(f); - s->im = qemu_get_be32(f); - s->tx_fifo_head = qemu_get_be32(f); - s->rx_fifo_head = qemu_get_be32(f); - s->tx_fifo_len = qemu_get_be32(f); - s->rx_fifo_len = qemu_get_be32(f); - for (i = 0; i < 8; i++) { - s->tx_fifo[i] = qemu_get_be16(f); - s->rx_fifo[i] = qemu_get_be16(f); +static const VMStateDescription vmstate_pl022 = { + .name = "pl022_ssp", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(cr0, pl022_state), + VMSTATE_UINT32(cr1, pl022_state), + VMSTATE_UINT32(bitmask, pl022_state), + VMSTATE_UINT32(sr, pl022_state), + VMSTATE_UINT32(cpsr, pl022_state), + VMSTATE_UINT32(is, pl022_state), + VMSTATE_UINT32(im, pl022_state), + VMSTATE_INT32(tx_fifo_head, pl022_state), + VMSTATE_INT32(rx_fifo_head, pl022_state), + VMSTATE_INT32(tx_fifo_len, pl022_state), + VMSTATE_INT32(rx_fifo_len, pl022_state), + VMSTATE_UINT16(tx_fifo[0], pl022_state), + VMSTATE_UINT16(rx_fifo[0], pl022_state), + VMSTATE_UINT16(tx_fifo[1], pl022_state), + VMSTATE_UINT16(rx_fifo[1], pl022_state), + VMSTATE_UINT16(tx_fifo[2], pl022_state), + VMSTATE_UINT16(rx_fifo[2], pl022_state), + VMSTATE_UINT16(tx_fifo[3], pl022_state), + VMSTATE_UINT16(rx_fifo[3], pl022_state), + VMSTATE_UINT16(tx_fifo[4], pl022_state), + VMSTATE_UINT16(rx_fifo[4], pl022_state), + VMSTATE_UINT16(tx_fifo[5], pl022_state), + VMSTATE_UINT16(rx_fifo[5], pl022_state), + VMSTATE_UINT16(tx_fifo[6], pl022_state), + VMSTATE_UINT16(rx_fifo[6], pl022_state), + VMSTATE_UINT16(tx_fifo[7], pl022_state), + VMSTATE_UINT16(rx_fifo[7], pl022_state), + VMSTATE_END_OF_LIST() } - - return 0; -} +}; static int pl022_init(SysBusDevice *dev) { @@ -300,7 +288,7 @@ static int pl022_init(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); s->ssi = ssi_create_bus(&dev->qdev, "ssi"); pl022_reset(s); - register_savevm(&dev->qdev, "pl022_ssp", -1, 1, pl022_save, pl022_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_pl022, s); return 0; } diff --git a/hw/pl031.c b/hw/pl031.c index c488f69..017a313 100644 --- a/hw/pl031.c +++ b/hw/pl031.c @@ -80,9 +80,9 @@ static void pl031_interrupt(void * opaque) static uint32_t pl031_get_count(pl031_state *s) { - /* This assumes qemu_get_clock returns the time since the machine was + /* This assumes qemu_get_clock_ns returns the time since the machine was created. */ - return s->tick_offset + qemu_get_clock(vm_clock) / get_ticks_per_sec(); + return s->tick_offset + qemu_get_clock_ns(vm_clock) / get_ticks_per_sec(); } static void pl031_set_alarm(pl031_state *s) @@ -90,7 +90,7 @@ static void pl031_set_alarm(pl031_state *s) int64_t now; uint32_t ticks; - now = qemu_get_clock(vm_clock); + now = qemu_get_clock_ns(vm_clock); ticks = s->tick_offset + now / get_ticks_per_sec(); /* The timer wraps around. This subtraction also wraps in the same way, @@ -161,7 +161,7 @@ static void pl031_write(void * opaque, target_phys_addr_t offset, pl031_update(s); break; case RTC_ICR: - /* The PL031 documentation (DDI0224B) states that the interupt is + /* The PL031 documentation (DDI0224B) states that the interrupt is cleared when bit 0 of the written value is set. However the arm926e documentation (DDI0287B) states that the interrupt is cleared when any value is written. */ @@ -217,7 +217,7 @@ static int pl031_init(SysBusDevice *dev) qemu_get_timedate(&tm, 0); s->tick_offset = mktimegm(&tm); - s->timer = qemu_new_timer(vm_clock, pl031_interrupt, s); + s->timer = qemu_new_timer_ns(vm_clock, pl031_interrupt, s); return 0; } diff --git a/hw/pl050.c b/hw/pl050.c index b155cc0..f7fa2e2 100644 --- a/hw/pl050.c +++ b/hw/pl050.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" diff --git a/hw/pl061.c b/hw/pl061.c index 1997b7c..cf5adbe 100644 --- a/hw/pl061.c +++ b/hw/pl061.c @@ -5,7 +5,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -24,34 +24,68 @@ do { fprintf(stderr, "pl061: error: " fmt , ## __VA_ARGS__);} while (0) #endif static const uint8_t pl061_id[12] = + { 0x00, 0x00, 0x00, 0x00, 0x61, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; +static const uint8_t pl061_id_luminary[12] = { 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 }; typedef struct { SysBusDevice busdev; - int locked; - uint8_t data; - uint8_t old_data; - uint8_t dir; - uint8_t isense; - uint8_t ibe; - uint8_t iev; - uint8_t im; - uint8_t istate; - uint8_t afsel; - uint8_t dr2r; - uint8_t dr4r; - uint8_t dr8r; - uint8_t odr; - uint8_t pur; - uint8_t pdr; - uint8_t slr; - uint8_t den; - uint8_t cr; - uint8_t float_high; + uint32_t locked; + uint32_t data; + uint32_t old_data; + uint32_t dir; + uint32_t isense; + uint32_t ibe; + uint32_t iev; + uint32_t im; + uint32_t istate; + uint32_t afsel; + uint32_t dr2r; + uint32_t dr4r; + uint32_t dr8r; + uint32_t odr; + uint32_t pur; + uint32_t pdr; + uint32_t slr; + uint32_t den; + uint32_t cr; + uint32_t float_high; + uint32_t amsel; qemu_irq irq; qemu_irq out[8]; + const unsigned char *id; } pl061_state; +static const VMStateDescription vmstate_pl061 = { + .name = "pl061", + .version_id = 2, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(locked, pl061_state), + VMSTATE_UINT32(data, pl061_state), + VMSTATE_UINT32(old_data, pl061_state), + VMSTATE_UINT32(dir, pl061_state), + VMSTATE_UINT32(isense, pl061_state), + VMSTATE_UINT32(ibe, pl061_state), + VMSTATE_UINT32(iev, pl061_state), + VMSTATE_UINT32(im, pl061_state), + VMSTATE_UINT32(istate, pl061_state), + VMSTATE_UINT32(afsel, pl061_state), + VMSTATE_UINT32(dr2r, pl061_state), + VMSTATE_UINT32(dr4r, pl061_state), + VMSTATE_UINT32(dr8r, pl061_state), + VMSTATE_UINT32(odr, pl061_state), + VMSTATE_UINT32(pur, pl061_state), + VMSTATE_UINT32(pdr, pl061_state), + VMSTATE_UINT32(slr, pl061_state), + VMSTATE_UINT32(den, pl061_state), + VMSTATE_UINT32(cr, pl061_state), + VMSTATE_UINT32(float_high, pl061_state), + VMSTATE_UINT32_V(amsel, pl061_state, 2), + VMSTATE_END_OF_LIST() + } +}; + static void pl061_update(pl061_state *s) { uint8_t changed; @@ -69,7 +103,7 @@ static void pl061_update(pl061_state *s) s->old_data = out; for (i = 0; i < 8; i++) { mask = 1 << i; - if ((changed & mask) && s->out) { + if (changed & mask) { DPRINTF("Set output %d = %d\n", i, (out & mask) != 0); qemu_set_irq(s->out[i], (out & mask) != 0); } @@ -83,7 +117,7 @@ static uint32_t pl061_read(void *opaque, target_phys_addr_t offset) pl061_state *s = (pl061_state *)opaque; if (offset >= 0xfd0 && offset < 0x1000) { - return pl061_id[(offset - 0xfd0) >> 2]; + return s->id[(offset - 0xfd0) >> 2]; } if (offset < 0x400) { return s->data & (offset >> 2); @@ -95,7 +129,7 @@ static uint32_t pl061_read(void *opaque, target_phys_addr_t offset) return s->isense; case 0x408: /* Interrupt both edges */ return s->ibe; - case 0x40c: /* Interupt event */ + case 0x40c: /* Interrupt event */ return s->iev; case 0x410: /* Interrupt mask */ return s->im; @@ -125,6 +159,8 @@ static uint32_t pl061_read(void *opaque, target_phys_addr_t offset) return s->locked; case 0x524: /* Commit */ return s->cr; + case 0x528: /* Analog mode select */ + return s->amsel; default: hw_error("pl061_read: Bad offset %x\n", (int)offset); return 0; @@ -145,19 +181,19 @@ static void pl061_write(void *opaque, target_phys_addr_t offset, } switch (offset) { case 0x400: /* Direction */ - s->dir = value; + s->dir = value & 0xff; break; case 0x404: /* Interrupt sense */ - s->isense = value; + s->isense = value & 0xff; break; case 0x408: /* Interrupt both edges */ - s->ibe = value; + s->ibe = value & 0xff; break; - case 0x40c: /* Interupt event */ - s->iev = value; + case 0x40c: /* Interrupt event */ + s->iev = value & 0xff; break; case 0x410: /* Interrupt mask */ - s->im = value; + s->im = value & 0xff; break; case 0x41c: /* Interrupt clear */ s->istate &= ~value; @@ -167,35 +203,38 @@ static void pl061_write(void *opaque, target_phys_addr_t offset, s->afsel = (s->afsel & ~mask) | (value & mask); break; case 0x500: /* 2mA drive */ - s->dr2r = value; + s->dr2r = value & 0xff; break; case 0x504: /* 4mA drive */ - s->dr4r = value; + s->dr4r = value & 0xff; break; case 0x508: /* 8mA drive */ - s->dr8r = value; + s->dr8r = value & 0xff; break; case 0x50c: /* Open drain */ - s->odr = value; + s->odr = value & 0xff; break; case 0x510: /* Pull-up */ - s->pur = value; + s->pur = value & 0xff; break; case 0x514: /* Pull-down */ - s->pdr = value; + s->pdr = value & 0xff; break; case 0x518: /* Slew rate control */ - s->slr = value; + s->slr = value & 0xff; break; case 0x51c: /* Digital enable */ - s->den = value; + s->den = value & 0xff; break; case 0x520: /* Lock */ s->locked = (value != 0xacce551); break; case 0x524: /* Commit */ if (!s->locked) - s->cr = value; + s->cr = value & 0xff; + break; + case 0x528: + s->amsel = value & 0xff; break; default: hw_error("pl061_write: Bad offset %x\n", (int)offset); @@ -235,67 +274,11 @@ static CPUWriteMemoryFunc * const pl061_writefn[] = { pl061_write }; -static void pl061_save(QEMUFile *f, void *opaque) -{ - pl061_state *s = (pl061_state *)opaque; - - qemu_put_be32(f, s->locked); - qemu_put_be32(f, s->data); - qemu_put_be32(f, s->old_data); - qemu_put_be32(f, s->dir); - qemu_put_be32(f, s->isense); - qemu_put_be32(f, s->ibe); - qemu_put_be32(f, s->iev); - qemu_put_be32(f, s->im); - qemu_put_be32(f, s->istate); - qemu_put_be32(f, s->afsel); - qemu_put_be32(f, s->dr2r); - qemu_put_be32(f, s->dr4r); - qemu_put_be32(f, s->dr8r); - qemu_put_be32(f, s->odr); - qemu_put_be32(f, s->pur); - qemu_put_be32(f, s->pdr); - qemu_put_be32(f, s->slr); - qemu_put_be32(f, s->den); - qemu_put_be32(f, s->cr); - qemu_put_be32(f, s->float_high); -} - -static int pl061_load(QEMUFile *f, void *opaque, int version_id) -{ - pl061_state *s = (pl061_state *)opaque; - if (version_id != 1) - return -EINVAL; - - s->locked = qemu_get_be32(f); - s->data = qemu_get_be32(f); - s->old_data = qemu_get_be32(f); - s->dir = qemu_get_be32(f); - s->isense = qemu_get_be32(f); - s->ibe = qemu_get_be32(f); - s->iev = qemu_get_be32(f); - s->im = qemu_get_be32(f); - s->istate = qemu_get_be32(f); - s->afsel = qemu_get_be32(f); - s->dr2r = qemu_get_be32(f); - s->dr4r = qemu_get_be32(f); - s->dr8r = qemu_get_be32(f); - s->odr = qemu_get_be32(f); - s->pur = qemu_get_be32(f); - s->pdr = qemu_get_be32(f); - s->slr = qemu_get_be32(f); - s->den = qemu_get_be32(f); - s->cr = qemu_get_be32(f); - s->float_high = qemu_get_be32(f); - - return 0; -} - -static int pl061_init(SysBusDevice *dev) +static int pl061_init(SysBusDevice *dev, const unsigned char *id) { int iomemtype; pl061_state *s = FROM_SYSBUS(pl061_state, dev); - + s->id = id; iomemtype = cpu_register_io_memory(pl061_readfn, pl061_writefn, s, DEVICE_NATIVE_ENDIAN); @@ -304,14 +287,37 @@ static int pl061_init(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8); qdev_init_gpio_out(&dev->qdev, s->out, 8); pl061_reset(s); - register_savevm(&dev->qdev, "pl061_gpio", -1, 1, pl061_save, pl061_load, s); return 0; } +static int pl061_init_luminary(SysBusDevice *dev) +{ + return pl061_init(dev, pl061_id_luminary); +} + +static int pl061_init_arm(SysBusDevice *dev) +{ + return pl061_init(dev, pl061_id); +} + +static SysBusDeviceInfo pl061_info = { + .init = pl061_init_arm, + .qdev.name = "pl061", + .qdev.size = sizeof(pl061_state), + .qdev.vmsd = &vmstate_pl061, +}; + +static SysBusDeviceInfo pl061_luminary_info = { + .init = pl061_init_luminary, + .qdev.name = "pl061_luminary", + .qdev.size = sizeof(pl061_state), + .qdev.vmsd = &vmstate_pl061, +}; + static void pl061_register_devices(void) { - sysbus_register_dev("pl061", sizeof(pl061_state), - pl061_init); + sysbus_register_withprop(&pl061_info); + sysbus_register_withprop(&pl061_luminary_info); } device_init(pl061_register_devices) diff --git a/hw/pl080.c b/hw/pl080.c index 901f04a..5ba3b08 100644 --- a/hw/pl080.c +++ b/hw/pl080.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -199,10 +199,10 @@ again: if (size == 0) { /* Transfer complete. */ if (ch->lli) { - ch->src = ldl_phys(ch->lli); - ch->dest = ldl_phys(ch->lli + 4); - ch->ctrl = ldl_phys(ch->lli + 12); - ch->lli = ldl_phys(ch->lli + 8); + ch->src = ldl_le_phys(ch->lli); + ch->dest = ldl_le_phys(ch->lli + 4); + ch->ctrl = ldl_le_phys(ch->lli + 12); + ch->lli = ldl_le_phys(ch->lli + 8); } else { ch->conf &= ~PL080_CCONF_E; } diff --git a/hw/pl110.c b/hw/pl110.c index 06d2dfa..4ac710a 100644 --- a/hw/pl110.c +++ b/hw/pl110.c @@ -4,7 +4,7 @@ * Copyright (c) 2005-2009 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GNU LGPL + * This code is licensed under the GNU LGPL */ #include "sysbus.h" @@ -24,15 +24,25 @@ enum pl110_bppmode BPP_4, BPP_8, BPP_16, - BPP_32 + BPP_32, + BPP_16_565, /* PL111 only */ + BPP_12 /* PL111 only */ +}; + + +/* The Versatile/PB uses a slightly modified PL110 controller. */ +enum pl110_version +{ + PL110, + PL110_VERSATILE, + PL111 }; typedef struct { SysBusDevice busdev; DisplayState *ds; - /* The Versatile/PB uses a slightly modified PL110 controller. */ - int versatile; + int version; uint32_t timing[4]; uint32_t cr; uint32_t upbase; @@ -43,6 +53,7 @@ typedef struct { int rows; enum pl110_bppmode bpp; int invalidate; + uint32_t mux_ctrl; uint32_t pallette[256]; uint32_t raw_pallette[128]; qemu_irq irq; @@ -50,10 +61,10 @@ typedef struct { static const VMStateDescription vmstate_pl110 = { .name = "pl110", - .version_id = 1, + .version_id = 2, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_INT32(versatile, pl110_state), + VMSTATE_INT32(version, pl110_state), VMSTATE_UINT32_ARRAY(timing, pl110_state, 4), VMSTATE_UINT32(cr, pl110_state), VMSTATE_UINT32(upbase, pl110_state), @@ -66,6 +77,7 @@ static const VMStateDescription vmstate_pl110 = { VMSTATE_INT32(invalidate, pl110_state), VMSTATE_UINT32_ARRAY(pallette, pl110_state, 256), VMSTATE_UINT32_ARRAY(raw_pallette, pl110_state, 128), + VMSTATE_UINT32_V(mux_ctrl, pl110_state, 2), VMSTATE_END_OF_LIST() } }; @@ -82,6 +94,17 @@ static const unsigned char pl110_versatile_id[] = #define pl110_versatile_id pl110_id #endif +static const unsigned char pl111_id[] = { + 0x11, 0x11, 0x24, 0x00, 0x0d, 0xf0, 0x05, 0xb1 +}; + +/* Indexed by pl110_version */ +static const unsigned char *idregs[] = { + pl110_id, + pl110_versatile_id, + pl111_id +}; + #include "pixel_ops.h" #define BITS 8 @@ -144,12 +167,40 @@ static void pl110_update_display(void *opaque) if (s->cr & PL110_CR_BGR) bpp_offset = 0; else - bpp_offset = 18; + bpp_offset = 24; + + if ((s->version != PL111) && (s->bpp == BPP_16)) { + /* The PL110's native 16 bit mode is 5551; however + * most boards with a PL110 implement an external + * mux which allows bits to be reshuffled to give + * 565 format. The mux is typically controlled by + * an external system register. + * This is controlled by a GPIO input pin + * so boards can wire it up to their register. + * + * The PL111 straightforwardly implements both + * 5551 and 565 under control of the bpp field + * in the LCDControl register. + */ + switch (s->mux_ctrl) { + case 3: /* 565 BGR */ + bpp_offset = (BPP_16_565 - BPP_16); + break; + case 1: /* 5551 */ + break; + case 0: /* 888; also if we have loaded vmstate from an old version */ + case 2: /* 565 RGB */ + default: + /* treat as 565 but honour BGR bit */ + bpp_offset += (BPP_16_565 - BPP_16); + break; + } + } if (s->cr & PL110_CR_BEBO) - fn = fntable[s->bpp + 6 + bpp_offset]; + fn = fntable[s->bpp + 8 + bpp_offset]; else if (s->cr & PL110_CR_BEPO) - fn = fntable[s->bpp + 12 + bpp_offset]; + fn = fntable[s->bpp + 16 + bpp_offset]; else fn = fntable[s->bpp + bpp_offset]; @@ -167,6 +218,8 @@ static void pl110_update_display(void *opaque) case BPP_8: break; case BPP_16: + case BPP_16_565: + case BPP_12: src_width <<= 1; break; case BPP_32: @@ -253,10 +306,7 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset) pl110_state *s = (pl110_state *)opaque; if (offset >= 0xfe0 && offset < 0x1000) { - if (s->versatile) - return pl110_versatile_id[(offset - 0xfe0) >> 2]; - else - return pl110_id[(offset - 0xfe0) >> 2]; + return idregs[s->version][(offset - 0xfe0) >> 2]; } if (offset >= 0x200 && offset < 0x400) { return s->raw_pallette[(offset - 0x200) >> 2]; @@ -275,12 +325,14 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset) case 5: /* LCDLPBASE */ return s->lpbase; case 6: /* LCDIMSC */ - if (s->versatile) - return s->cr; + if (s->version != PL110) { + return s->cr; + } return s->int_mask; case 7: /* LCDControl */ - if (s->versatile) - return s->int_mask; + if (s->version != PL110) { + return s->int_mask; + } return s->cr; case 8: /* LCDRIS */ return s->int_status; @@ -337,15 +389,17 @@ static void pl110_write(void *opaque, target_phys_addr_t offset, s->lpbase = val; break; case 6: /* LCDIMSC */ - if (s->versatile) + if (s->version != PL110) { goto control; + } imsc: s->int_mask = val; pl110_update(s); break; case 7: /* LCDControl */ - if (s->versatile) + if (s->version != PL110) { goto imsc; + } control: s->cr = val; s->bpp = (val >> 1) & 7; @@ -374,6 +428,12 @@ static CPUWriteMemoryFunc * const pl110_writefn[] = { pl110_write }; +static void pl110_mux_ctrl_set(void *opaque, int line, int level) +{ + pl110_state *s = (pl110_state *)opaque; + s->mux_ctrl = level; +} + static int pl110_init(SysBusDevice *dev) { pl110_state *s = FROM_SYSBUS(pl110_state, dev); @@ -384,6 +444,7 @@ static int pl110_init(SysBusDevice *dev) DEVICE_NATIVE_ENDIAN); sysbus_init_mmio(dev, 0x1000, iomemtype); sysbus_init_irq(dev, &s->irq); + qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1); s->ds = graphic_console_init(pl110_update_display, pl110_invalidate_display, NULL, NULL, s); @@ -393,7 +454,14 @@ static int pl110_init(SysBusDevice *dev) static int pl110_versatile_init(SysBusDevice *dev) { pl110_state *s = FROM_SYSBUS(pl110_state, dev); - s->versatile = 1; + s->version = PL110_VERSATILE; + return pl110_init(dev); +} + +static int pl111_init(SysBusDevice *dev) +{ + pl110_state *s = FROM_SYSBUS(pl110_state, dev); + s->version = PL111; return pl110_init(dev); } @@ -413,10 +481,19 @@ static SysBusDeviceInfo pl110_versatile_info = { .qdev.no_user = 1, }; +static SysBusDeviceInfo pl111_info = { + .init = pl111_init, + .qdev.name = "pl111", + .qdev.size = sizeof(pl110_state), + .qdev.vmsd = &vmstate_pl110, + .qdev.no_user = 1, +}; + static void pl110_register_devices(void) { sysbus_register_withprop(&pl110_info); sysbus_register_withprop(&pl110_versatile_info); + sysbus_register_withprop(&pl111_info); } device_init(pl110_register_devices) diff --git a/hw/pl110_template.h b/hw/pl110_template.h index b3c9077..1dce32a 100644 --- a/hw/pl110_template.h +++ b/hw/pl110_template.h @@ -4,7 +4,7 @@ * Copyright (c) 2005 CodeSourcery, LLC. * Written by Paul Brook * - * This code is licenced under the GNU LGPL + * This code is licensed under the GNU LGPL * * Framebuffer format conversion routines. */ @@ -43,49 +43,61 @@ #include "pl110_template.h" #undef BORDER -static drawfn glue(pl110_draw_fn_,BITS)[36] = +static drawfn glue(pl110_draw_fn_,BITS)[48] = { glue(pl110_draw_line1_lblp_bgr,BITS), glue(pl110_draw_line2_lblp_bgr,BITS), glue(pl110_draw_line4_lblp_bgr,BITS), glue(pl110_draw_line8_lblp_bgr,BITS), - glue(pl110_draw_line16_lblp_bgr,BITS), + glue(pl110_draw_line16_555_lblp_bgr,BITS), glue(pl110_draw_line32_lblp_bgr,BITS), + glue(pl110_draw_line16_lblp_bgr,BITS), + glue(pl110_draw_line12_lblp_bgr,BITS), glue(pl110_draw_line1_bbbp_bgr,BITS), glue(pl110_draw_line2_bbbp_bgr,BITS), glue(pl110_draw_line4_bbbp_bgr,BITS), glue(pl110_draw_line8_bbbp_bgr,BITS), - glue(pl110_draw_line16_bbbp_bgr,BITS), + glue(pl110_draw_line16_555_bbbp_bgr,BITS), glue(pl110_draw_line32_bbbp_bgr,BITS), + glue(pl110_draw_line16_bbbp_bgr,BITS), + glue(pl110_draw_line12_bbbp_bgr,BITS), glue(pl110_draw_line1_lbbp_bgr,BITS), glue(pl110_draw_line2_lbbp_bgr,BITS), glue(pl110_draw_line4_lbbp_bgr,BITS), glue(pl110_draw_line8_lbbp_bgr,BITS), - glue(pl110_draw_line16_lbbp_bgr,BITS), + glue(pl110_draw_line16_555_lbbp_bgr,BITS), glue(pl110_draw_line32_lbbp_bgr,BITS), + glue(pl110_draw_line16_lbbp_bgr,BITS), + glue(pl110_draw_line12_lbbp_bgr,BITS), glue(pl110_draw_line1_lblp_rgb,BITS), glue(pl110_draw_line2_lblp_rgb,BITS), glue(pl110_draw_line4_lblp_rgb,BITS), glue(pl110_draw_line8_lblp_rgb,BITS), - glue(pl110_draw_line16_lblp_rgb,BITS), + glue(pl110_draw_line16_555_lblp_rgb,BITS), glue(pl110_draw_line32_lblp_rgb,BITS), + glue(pl110_draw_line16_lblp_rgb,BITS), + glue(pl110_draw_line12_lblp_rgb,BITS), glue(pl110_draw_line1_bbbp_rgb,BITS), glue(pl110_draw_line2_bbbp_rgb,BITS), glue(pl110_draw_line4_bbbp_rgb,BITS), glue(pl110_draw_line8_bbbp_rgb,BITS), - glue(pl110_draw_line16_bbbp_rgb,BITS), + glue(pl110_draw_line16_555_bbbp_rgb,BITS), glue(pl110_draw_line32_bbbp_rgb,BITS), + glue(pl110_draw_line16_bbbp_rgb,BITS), + glue(pl110_draw_line12_bbbp_rgb,BITS), glue(pl110_draw_line1_lbbp_rgb,BITS), glue(pl110_draw_line2_lbbp_rgb,BITS), glue(pl110_draw_line4_lbbp_rgb,BITS), glue(pl110_draw_line8_lbbp_rgb,BITS), - glue(pl110_draw_line16_lbbp_rgb,BITS), + glue(pl110_draw_line16_555_lbbp_rgb,BITS), glue(pl110_draw_line32_lbbp_rgb,BITS), + glue(pl110_draw_line16_lbbp_rgb,BITS), + glue(pl110_draw_line12_lbbp_rgb,BITS), }; #undef BITS @@ -299,6 +311,82 @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_ } } +static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) +{ + /* RGB 555 plus an intensity bit (which we ignore) */ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *)src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif +#ifdef RGB +#define LSB r +#define MSB b +#else +#define LSB b +#define MSB r +#endif + LSB = (data & 0x1f) << 3; + data >>= 5; + g = (data & 0x1f) << 3; + data >>= 5; + MSB = (data & 0x1f) << 3; + data >>= 5; + COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + LSB = (data & 0x1f) << 3; + data >>= 5; + g = (data & 0x1f) << 3; + data >>= 5; + MSB = (data & 0x1f) << 3; + data >>= 6; + COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); +#undef MSB +#undef LSB + width -= 2; + src += 4; + } +} + +static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) +{ + /* RGB 444 with 4 bits of zeroes at the top of each halfword */ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *)src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif +#ifdef RGB +#define LSB r +#define MSB b +#else +#define LSB b +#define MSB r +#endif + LSB = (data & 0xf) << 4; + data >>= 4; + g = (data & 0xf) << 4; + data >>= 4; + MSB = (data & 0xf) << 4; + data >>= 8; + COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + LSB = (data & 0xf) << 4; + data >>= 4; + g = (data & 0xf) << 4; + data >>= 4; + MSB = (data & 0xf) << 4; + data >>= 8; + COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); +#undef MSB +#undef LSB + width -= 2; + src += 4; + } +} + #undef SWAP_PIXELS #undef NAME #undef SWAP_WORDS diff --git a/hw/pl181.c b/hw/pl181.c index 36d9d02..0943c09 100644 --- a/hw/pl181.c +++ b/hw/pl181.c @@ -4,7 +4,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "blockdev.h" @@ -47,6 +47,8 @@ typedef struct { int linux_hack; uint32_t fifo[PL181_FIFO_LEN]; qemu_irq irq[2]; + /* GPIO outputs for 'card is readonly' and 'card inserted' */ + qemu_irq cardstatus[2]; } pl181_state; #define PL181_CMD_INDEX 0x3f @@ -444,6 +446,9 @@ static void pl181_reset(void *opaque) s->linux_hack = 0; s->mask[0] = 0; s->mask[1] = 0; + + /* We can assume our GPIO outputs have been wired up now */ + sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]); } static int pl181_init(SysBusDevice *dev) @@ -457,6 +462,7 @@ static int pl181_init(SysBusDevice *dev) sysbus_init_mmio(dev, 0x1000, iomemtype); sysbus_init_irq(dev, &s->irq[0]); sysbus_init_irq(dev, &s->irq[1]); + qdev_init_gpio_out(&s->busdev.qdev, s->cardstatus, 2); dinfo = drive_get_next(IF_SD); s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0); qemu_register_reset(pl181_reset, s); diff --git a/hw/pl190.c b/hw/pl190.c index 75f2ba1..8dc7e42 100644 --- a/hw/pl190.c +++ b/hw/pl190.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" diff --git a/hw/pl192.c b/hw/pl192.c deleted file mode 100644 index 8a3c51d..0000000 --- a/hw/pl192.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * ARM PrimeCell PL192 Vector Interrupt Controller - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - */ - -#include "sysbus.h" -#include "primecell.h" - - -#define PL192_INT_SOURCES 32 -#define PL192_DAISY_IRQ PL192_INT_SOURCES -#define PL192_NO_IRQ PL192_INT_SOURCES+1 -#define PL192_PRIO_LEVELS 16 - -#define PL192_IRQSTATUS 0x00 -#define PL192_FIQSTATUS 0x04 -#define PL192_RAWINTR 0x08 -#define PL192_INTSELECT 0x0C -#define PL192_INTENABLE 0x10 -#define PL192_INTENCLEAR 0x14 -#define PL192_SOFTINT 0x18 -#define PL192_SOFTINTCLEAR 0x1C -#define PL192_PROTECTION 0x20 -#define PL192_SWPRIORITYMASK 0x24 -#define PL192_PRIORITYDAISY 0x28 -#define PL192_VECTADDR 0xF00 -#define PL192_IOMEM_SIZE 0x1000 - -#define PL190_ITCR 0x300 -#define PL190_VECTADDR 0x30 -#define PL190_DEFVECTADDR 0x34 - -#define PL192_IOMEM_SIZE 0x1000 - - -typedef struct pl192_state_s { - SysBusDevice busdev; - uint32_t instance; - - /* Control registers */ - uint32_t irq_status; - uint32_t fiq_status; - uint32_t rawintr; - uint32_t intselect; - uint32_t intenable; - uint32_t softint; - uint32_t protection; - uint32_t sw_priority_mask; - uint32_t vect_addr[PL192_INT_SOURCES]; - uint32_t vect_priority[PL192_INT_SOURCES]; - uint32_t address; - - /* Currently processed interrupt and - highest priority interrupt */ - uint32_t current; - uint32_t current_highest; - - /* Priority masking logic */ - int32_t stack_i; - uint32_t priority_stack[PL192_PRIO_LEVELS+1]; - uint8_t irq_stack[PL192_PRIO_LEVELS+1]; - uint32_t priority; - - /* Daisy-chain interface */ - uint32_t daisy_vectaddr; - uint32_t daisy_priority; - struct pl192_state_s *daisy_callback; - uint8_t daisy_input; - - /* Parent interrupts */ - qemu_irq irq; - qemu_irq fiq; - - /* Next controller in chain */ - struct pl192_state_s *daisy; -} pl192_state; - -const unsigned char pl192_id[] = -{ 0x92, 0x11, 0x04, 0x00, 0x0D, 0xF0, 0x05, 0xB1 }; - - -static void pl192_update(pl192_state *); - -static void pl192_raise(pl192_state *s, int is_fiq) -{ - if (is_fiq) { - if (s->fiq) { - /* Raise parent FIQ */ - qemu_irq_raise(s->fiq); - } else { - if (s->daisy) { - /* FIQ is directly propagated through daisy chain */ - pl192_raise(s->daisy, is_fiq); - } else { - hw_error("pl192: cannot raise FIQ. This usually means that " - "initialization was done incorrectly.\n"); - } - } - } else { - if (s->irq) { - /* Raise parent IRQ */ - qemu_irq_raise(s->irq); - } else { - if (s->daisy) { - /* Setup daisy input of the next chained contorller and force - it to update it's state */ - s->daisy->daisy_vectaddr = s->address; - s->daisy->daisy_callback = s; - s->daisy->daisy_input = 1; - pl192_update(s->daisy); - } else { - hw_error("pl192: cannot raise IRQ. This usually means that " - "initialization was done incorrectly.\n"); - } - } - } -} - -static void pl192_lower(pl192_state *s, int is_fiq) -{ - /* Lower parrent interrupt if there is one */ - if (is_fiq && s->fiq) { - qemu_irq_lower(s->fiq); - } - if (!is_fiq && s->irq) { - qemu_irq_lower(s->irq); - } - /* Propagate to the previous controller in chain if needed */ - if (s->daisy) { - if (!is_fiq) { - s->daisy->daisy_input = 0; - pl192_update(s->daisy); - } else { - pl192_lower(s->daisy, is_fiq); - } - } -} - -/* Find interrupt of the highest priority */ -static uint32_t pl192_priority_sorter(pl192_state *s) -{ - int i; - uint32_t prio_irq[PL192_PRIO_LEVELS]; - - for (i = 0; i < PL192_PRIO_LEVELS; i++) { - prio_irq[i] = PL192_NO_IRQ; - } - if (s->daisy_input) { - prio_irq[s->daisy_priority] = PL192_DAISY_IRQ; - } - for (i = PL192_INT_SOURCES - 1; i >= 0; i--) { - if (s->irq_status & (1 << i)) { - prio_irq[s->vect_priority[i]] = i; - } - } - for (i = 0; i < PL192_PRIO_LEVELS; i++) { - if ((s->sw_priority_mask & (1 << i)) && - prio_irq[i] <= PL192_DAISY_IRQ) { - return prio_irq[i]; - } - } - return PL192_NO_IRQ; -} - -static void pl192_update(pl192_state *s) -{ - /* TODO: does SOFTINT affects IRQ_STATUS??? */ - s->irq_status = (s->rawintr | s->softint) & s->intenable & ~s->intselect; - s->fiq_status = (s->rawintr | s->softint) & s->intenable & s->intselect; - if (s->fiq_status) { - pl192_raise(s, 1); - } else { - pl192_lower(s, 1); - } - if (s->irq_status || s->daisy_input) { - s->current_highest = pl192_priority_sorter(s); - if (s->current_highest < PL192_INT_SOURCES) { - s->address = s->vect_addr[s->current_highest]; - } else { - s->address = s->daisy_vectaddr; - } - if (s->current_highest != s->current) { - if (s->current_highest < PL192_INT_SOURCES) { - if (s->vect_priority[s->current_highest] >= s->priority) { - return ; - } - } - if (s->current_highest == PL192_DAISY_IRQ) { - if (s->daisy_priority >= s->priority) { - return ; - } - } - if (s->current_highest <= PL192_DAISY_IRQ) { - pl192_raise(s, 0); - } else { - pl192_lower(s, 0); - } - } - } else { - s->current_highest = PL192_NO_IRQ; - pl192_lower(s, 0); - } -} - -/* Set priority level when an interrupt have been acknoledged by CPU. - Also save interrupt id and priority to stack so it can be restored - lately. */ -static inline void pl192_mask_priority(pl192_state *s) -{ - if (s->stack_i >= PL192_INT_SOURCES) { - hw_error("pl192: internal error\n"); - } - s->stack_i++; - if (s->current == PL192_DAISY_IRQ) { - s->priority = s->daisy_priority; - } else { - s->priority = s->vect_priority[s->current]; - } - s->priority_stack[s->stack_i] = s->priority; - s->irq_stack[s->stack_i] = s->current; -} - -/* Set priority level when interrupt have been successfully processed by CPU. - Also restore previous interrupt id and priority level. */ -static inline void pl192_unmask_priority(pl192_state *s) -{ - if (s->stack_i < 1) { - hw_error("pl192: internal error\n"); - } - s->stack_i--; - s->priority = s->priority_stack[s->stack_i]; - s->current = s->irq_stack[s->stack_i]; -} - -/* IRQ was acknoledged by CPU. Update controller state accordingly */ -static uint32_t pl192_irq_ack(pl192_state *s) -{ - int is_daisy = (s->current_highest == PL192_DAISY_IRQ); - uint32_t res = s->address; - - s->current = s->current_highest; - pl192_mask_priority(s); - if (is_daisy) { - pl192_mask_priority(s->daisy_callback); - } - pl192_update(s); - return res; -} - -/* IRQ was processed by CPU. Update controller state accrodingly */ -static void pl192_irq_fin(pl192_state *s) -{ - int is_daisy = (s->current == PL192_DAISY_IRQ); - - pl192_unmask_priority(s); - if (is_daisy) { - pl192_unmask_priority(s->daisy_callback); - } - pl192_update(s); - if (s->current == PL192_NO_IRQ) { - pl192_lower(s, 0); - } -} - -static uint32_t pl192_read(void *opaque, target_phys_addr_t offset) -{ - pl192_state *s = (pl192_state *) opaque; - - if (offset & 3) { - hw_error("pl192: bad read offset " TARGET_FMT_plx "\n", offset); - return 0; - } - - if (offset >= 0xfe0 && offset < 0x1000) { - return pl192_id[(offset - 0xfe0) >> 2]; - } - if (offset >= 0x100 && offset < 0x180) { - return s->vect_addr[(offset - 0x100) >> 2]; - } - if (offset >= 0x200 && offset < 0x280) { - return s->vect_priority[(offset - 0x200) >> 2]; - } - - switch (offset) { - case PL192_IRQSTATUS: - return s->irq_status; - case PL192_FIQSTATUS: - return s->fiq_status; - case PL192_RAWINTR: - return s->rawintr; - case PL192_INTSELECT: - return s->intselect; - case PL192_INTENABLE: - return s->intenable; - case PL192_SOFTINT: - return s->softint; - case PL192_PROTECTION: - return s->protection; - case PL192_SWPRIORITYMASK: - return s->sw_priority_mask; - case PL192_PRIORITYDAISY: - return s->daisy_priority; - case PL192_INTENCLEAR: - case PL192_SOFTINTCLEAR: - hw_error("pl192: attempt to read write-only register (offset = " - TARGET_FMT_plx ")\n", offset); - case PL192_VECTADDR: - return pl192_irq_ack(s); - /* Workaround for kernel code using PL190 */ - case PL190_ITCR: - case PL190_VECTADDR: - case PL190_DEFVECTADDR: - return 0; - default: - hw_error("pl192: bad read offset " TARGET_FMT_plx "\n", offset); - return 0; - } -} - -static void pl192_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - pl192_state *s = (pl192_state *) opaque; - - if (offset & 3) { - hw_error("pl192: bad write offset " TARGET_FMT_plx "\n", offset); - } - - if (offset >= 0xfe0 && offset < 0x1000) { - hw_error("pl192: attempt to write to a read-only register (offset = " - TARGET_FMT_plx ")\n", offset); - } - if (offset >= 0x100 && offset < 0x180) { - s->vect_addr[(offset - 0x100) >> 2] = value; - pl192_update(s); - return; - } - if (offset >= 0x200 && offset < 0x280) { - s->vect_priority[(offset - 0x200) >> 2] = value & 0xf; - pl192_update(s); - return; - } - - switch (offset) { - case PL192_IRQSTATUS: - /* This is a readonly register, but linux tries to write to it - anyway. Ignore the write. */ - return; - case PL192_FIQSTATUS: - case PL192_RAWINTR: - hw_error("pl192: attempt to write to a read-only register (offset = " - TARGET_FMT_plx ")\n", offset); - break; - case PL192_INTSELECT: - s->intselect = value; - break; - case PL192_INTENABLE: - s->intenable |= value; - break; - case PL192_INTENCLEAR: - s->intenable &= ~value; - break; - case PL192_SOFTINT: - s->softint |= value; - break; - case PL192_SOFTINTCLEAR: - s->softint &= ~value; - break; - case PL192_PROTECTION: - /* TODO: implement protection */ - s->protection = value & 1; - break; - case PL192_SWPRIORITYMASK: - s->sw_priority_mask = value & 0xffff; - break; - case PL192_PRIORITYDAISY: - s->daisy_priority = value & 0xf; - break; - case PL192_VECTADDR: - pl192_irq_fin(s); - return; - case PL190_ITCR: - case PL190_VECTADDR: - case PL190_DEFVECTADDR: - /* NB: This thing is not present here, but linux wants to write it */ - /* Ignore written value */ - return; - default: - hw_error("pl192: bad write offset " TARGET_FMT_plx "\n", offset); - return; - } - - pl192_update(s); -} - -static void pl192_irq_handler(void *opaque, int irq, int level) -{ - pl192_state *s = (pl192_state *) opaque; - - if (level) { - s->rawintr |= 1 << irq; - } else { - s->rawintr &= ~(1 << irq); - } - pl192_update(opaque); -} - -static void pl192_reset(DeviceState *d) -{ - pl192_state *s = FROM_SYSBUS(pl192_state, sysbus_from_qdev(d)); - int i; - - for (i = 0; i < PL192_INT_SOURCES; i++) { - s->vect_priority[i] = 0xf; - } - s->sw_priority_mask = 0xffff; - s->daisy_priority = 0xf; - s->current = PL192_NO_IRQ; - s->current_highest = PL192_NO_IRQ; - s->stack_i = 0; - s->priority_stack[0] = 0x10; - s->irq_stack[0] = PL192_NO_IRQ; - s->priority = 0x10; -} - -static CPUReadMemoryFunc * const pl192_readfn[] = { - pl192_read, - pl192_read, - pl192_read -}; - -static CPUWriteMemoryFunc * const pl192_writefn[] = { - pl192_write, - pl192_write, - pl192_write -}; - -static void pl192_save(QEMUFile *f, void *opaque) -{ - pl192_state *s = (pl192_state *) opaque; - int i; - - qemu_put_be32s(f, &s->irq_status); - qemu_put_be32s(f, &s->fiq_status); - qemu_put_be32s(f, &s->rawintr); - qemu_put_be32s(f, &s->intselect); - qemu_put_be32s(f, &s->intenable); - qemu_put_be32s(f, &s->softint); - qemu_put_be32s(f, &s->protection); - qemu_put_be32s(f, &s->sw_priority_mask); - - for (i = 0; i < PL192_INT_SOURCES; i++) { - qemu_put_be32s(f, &s->vect_addr[i]); - qemu_put_be32s(f, &s->vect_priority[i]); - } - - qemu_put_be32s(f, &s->address); - qemu_put_be32s(f, &s->current); - qemu_put_be32s(f, &s->current_highest); - qemu_put_sbe32s(f, &s->stack_i); - - for (i = 0; i <= PL192_PRIO_LEVELS; i++) { - qemu_put_be32s(f, &s->priority_stack[i]); - qemu_put_8s (f, &s->irq_stack[i]); - } - - qemu_put_be32s(f, &s->priority); - qemu_put_be32s(f, &s->daisy_vectaddr); - qemu_put_be32s(f, &s->daisy_priority); - qemu_put_8s (f, &s->daisy_input); -} - -static int pl192_load(QEMUFile *f, void *opaque, int version_id) -{ - pl192_state *s = (pl192_state *) opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->irq_status); - qemu_get_be32s(f, &s->fiq_status); - qemu_get_be32s(f, &s->rawintr); - qemu_get_be32s(f, &s->intselect); - qemu_get_be32s(f, &s->intenable); - qemu_get_be32s(f, &s->softint); - qemu_get_be32s(f, &s->protection); - qemu_get_be32s(f, &s->sw_priority_mask); - - for (i = 0; i < PL192_INT_SOURCES; i++) { - qemu_get_be32s(f, &s->vect_addr[i]); - qemu_get_be32s(f, &s->vect_priority[i]); - } - - qemu_get_be32s(f, &s->address); - qemu_get_be32s(f, &s->current); - qemu_get_be32s(f, &s->current_highest); - qemu_get_sbe32s(f, &s->stack_i); - - for (i = 0; i <= PL192_PRIO_LEVELS; i++) { - qemu_get_be32s(f, &s->priority_stack[i]); - qemu_get_8s (f, &s->irq_stack[i]); - } - - qemu_get_be32s(f, &s->priority); - qemu_get_be32s(f, &s->daisy_vectaddr); - qemu_get_be32s(f, &s->daisy_priority); - qemu_get_8s (f, &s->daisy_input); - - return 0; -} - -DeviceState *pl192_init(target_phys_addr_t base, int instance, ...) -{ - va_list va; - qemu_irq irq; - int n; - - DeviceState *dev = qdev_create(NULL, "pl192"); - SysBusDevice *s = sysbus_from_qdev(dev); - qdev_prop_set_uint32(dev, "instance", instance); - qdev_init_nofail(dev); - sysbus_mmio_map(s, 0, base); - - va_start(va, instance); - n = 0; - while (1) { - irq = va_arg(va, qemu_irq); - if (!irq) - break; - sysbus_connect_irq(s, n, irq); - n++; - } - return dev; -} - -static int pl192_init1(SysBusDevice *dev) -{ - pl192_state *s = FROM_SYSBUS(pl192_state, dev); - int iomemtype; - - sysbus_init_irq(dev, &s->irq); - sysbus_init_irq(dev, &s->fiq); - - /* Allocate IRQs */ - qdev_init_gpio_in(&dev->qdev, pl192_irq_handler, PL192_INT_SOURCES); - - /* Map Interrupt Controller registers to memory */ - iomemtype = cpu_register_io_memory(pl192_readfn, pl192_writefn, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, PL192_IOMEM_SIZE, iomemtype); - - /* TODO: Interrupt Controller coprocessor??? */ - pl192_reset(&s->busdev.qdev); - - register_savevm(&dev->qdev, "pl192", s->instance, 1, - pl192_save, pl192_load, s); - - return 0; -} - -static SysBusDeviceInfo pl192_info = { - .init = pl192_init1, - .qdev.name = "pl192", - .qdev.size = sizeof(pl192_state), - .qdev.reset = pl192_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("instance", pl192_state, instance, 0), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void pl192_register_devices(void) -{ - sysbus_register_withprop(&pl192_info); -} - -void pl192_chain(void *first, void *next) -{ - pl192_state *s1 = FROM_SYSBUS(pl192_state, (SysBusDevice *)first); - pl192_state *s2 = FROM_SYSBUS(pl192_state, (SysBusDevice *)next); - - s2->daisy = s1; -} - -device_init(pl192_register_devices) diff --git a/hw/pl330.c b/hw/pl330.c deleted file mode 100644 index b72d2c4..0000000 --- a/hw/pl330.c +++ /dev/null @@ -1,1571 +0,0 @@ -/* - * ARM PrimeCell PL330 DMA Controller - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - */ - -#include "sysbus.h" -#include "primecell.h" -#include "qemu-timer.h" - - -#define PL330_CHAN_NUM 8 -#define PL330_PERIPH_NUM 32 -#define PL330_MAX_BURST_LEN 128 -#define PL330_INSN_MAXSIZE 6 - -#define PL330_FIFO_OK 0 -#define PL330_FIFO_STALL 1 -#define PL330_FIFO_ERR (-1) - -#define PL330_FAULT_UNDEF_INSTR (1 << 0) -#define PL330_FAULT_OPERAND_INVALID (1 << 1) -#define PL330_FAULT_DMAGO_ER (1 << 4) -#define PL330_FAULT_EVENT_ER (1 << 5) -#define PL330_FAULT_CH_PERIPH_ER (1 << 6) -#define PL330_FAULT_CH_RDWR_ER (1 << 7) -#define PL330_FAULT_MFIFO_ER (1 << 12) -#define PL330_FAULT_INSTR_FETCH_ER (1 << 16) -#define PL330_FAULT_DATA_WRITE_ER (1 << 17) -#define PL330_FAULT_DATA_READ_ER (1 << 18) -#define PL330_FAULT_DBG_INSTR (1 << 30) -#define PL330_FAULT_LOCKUP_ER (1 << 31) - -#define PL330_UNTAGGED 0xff - -#define PL330_SINGLE 0x0 -#define PL330_BURST 0x1 - -#define PL330_WATCHDOG_LIMIT 1024 - -/* IOMEM mapped registers */ -#define PL330_REG_DS 0x000 -#define PL330_REG_DPC 0x004 -#define PL330_REG_INTEN 0x020 -#define PL330_REG_ES 0x024 -#define PL330_REG_INTSTATUS 0x028 -#define PL330_REG_INTCLR 0x02C -#define PL330_REG_FSM 0x030 -#define PL330_REG_FSC 0x034 -#define PL330_REG_FTM 0x038 -#define PL330_REG_FTC_BASE 0x040 -#define PL330_REG_CS_BASE 0x100 -#define PL330_REG_CPC_BASE 0x104 -#define PL330_REG_CHANCTRL 0x400 -#define PL330_REG_DBGSTATUS 0xD00 -#define PL330_REG_DBGCMD 0xD04 -#define PL330_REG_DBGINST0 0xD08 -#define PL330_REG_DBGINST1 0xD0C -#define PL330_REG_CONFIG 0xE00 -#define PL330_REG_ID 0xFE0 - -#define PL330_IOMEM_SIZE 0x1000 - - -static const uint32_t pl330_id[] = -{ 0x30, 0x13, 0x04, 0x00, 0xB1, 0x05, 0xF0, 0x0D }; - - -/* DMA chanel states as they are described in PL330 Technical Reference Manual - Most of them will not be used in emulation. */ -enum pl330_chan_enum { - pl330_chan_stopped = 0, - pl330_chan_executing = 1, - pl330_chan_completing, - pl330_chan_waiting_periph, - pl330_chan_at_barrier, - pl330_chan_waiting_event = 4, - pl330_chan_updating_pc = 3, - pl330_chan_cache_miss, - pl330_chan_fault_completing, - pl330_chan_fault = 15, - pl330_chan_killing -}; - -struct pl330_chan_state; -struct pl330_fifo; -struct pl330_queue_entry; -struct pl330_queue; -struct pl330_state; -struct pl330_insn_desc; - -typedef struct pl330_chan_state pl330_chan_state; -typedef struct pl330_fifo pl330_fifo; -typedef struct pl330_queue_entry pl330_queue_entry; -typedef struct pl330_queue pl330_queue; -typedef struct pl330_state pl330_state; -typedef struct pl330_insn_desc pl330_insn_desc; - - -struct pl330_chan_state { - uint32_t src; - uint32_t dst; - uint32_t pc; - uint32_t control; - uint32_t status; - uint32_t lc[2]; - uint32_t fault_type; - - uint8_t ns; - uint8_t is_manager; - uint8_t request_flag; - uint8_t wakeup; - uint8_t wfp_sbp; - - enum pl330_chan_enum state; - uint8_t stall; - - pl330_state *parent; - uint8_t tag; - uint32_t watchdog_timer; -}; - -struct pl330_fifo { - uint8_t *buf; - uint8_t *tag; - int32_t s, t; - int32_t buf_size; -}; - -struct pl330_queue_entry { - uint32_t addr; - int32_t len; - int32_t n; - int32_t inc; - int32_t z; - uint8_t tag; - uint8_t seqn; -}; - -struct pl330_queue { - pl330_queue_entry *queue; - int32_t queue_size; - uint8_t *lo_seqn; - uint8_t *hi_seqn; -}; - -struct pl330_state { - SysBusDevice busdev; - uint32_t instance; - - pl330_chan_state manager; - pl330_chan_state *chan; - pl330_fifo fifo; - pl330_queue read_queue; - pl330_queue write_queue; - - /* Config registers. cfg[5] = CfgDn. */ - uint32_t inten; - uint32_t int_status; - uint32_t ev_status; - uint32_t cfg[6]; - uint32_t dbg[2]; - uint8_t debug_status; - - qemu_irq irq_abort; - qemu_irq *irq; - - uint8_t num_faulting; - - int32_t chan_num; - int32_t periph_num; - uint32_t event_num; - - QEMUTimer *timer; /* is used for restore dma. */ - int8_t periph_busy[PL330_PERIPH_NUM]; -}; - -struct pl330_insn_desc { - /* OPCODE of the instruction */ - uint8_t opcode; - /* Mask so we can select several sibling instructions, such as - DMALD, DMALDS and DMALDB */ - uint8_t opmask; - /* Size of instruction in bytes */ - uint8_t size; - /* Interpreter */ - void (*exec)(pl330_chan_state *, uint8_t opcode, uint8_t *args, int len); -}; - - -/* MFIFO Implementation */ - -/* - * MFIFO is implemented as a cyclic buffer of BUF_SIZE size. Tagged bytes are - * stored in this buffer. Data is stored in BUF field, tags - in the - * corresponding array elemnets of TAG field. - */ - -/* Initialize queue. */ -static void pl330_fifo_init(pl330_fifo *s, uint32_t size) -{ - s->buf = qemu_mallocz(size * sizeof(uint8_t)); - s->tag = qemu_mallocz(size * sizeof(uint8_t)); - s->buf_size = size; -} - -/* Cyclic increment */ -static inline int pl330_fifo_inc(int x, int size) -{ - return (x + 1) % size; -} - -/* Number of empty bytes in MFIFO */ -static inline int pl330_fifo_num_free(pl330_fifo *s) -{ - if (s->t < s->s) { - return s->s - s->t; - } else { - return s->buf_size - s->t + s->s; - } -} - -/* Number of bytes in MFIFO */ -static inline int pl330_fifo_num_used(pl330_fifo *s) -{ - if (s->t >= s->s) { - return s->t - s->s; - } else { - return s->buf_size - s->s + s->t; - } -} - -/* Push LEN bytes of data stored in BUF to MFIFO and tag it with TAG. - Zero returned on success, PL330_FIFO_STALL if there is no enough free - space in MFIFO to store requested amount of data. If push was unsaccessful - no data is stored to MFIFO. */ -static int pl330_fifo_push(pl330_fifo *s, uint8_t *buf, int len, uint8_t tag) -{ - int i; - int old_s, old_t; - - old_s = s->s; - old_t = s->t; - for (i = 0; i < len; i++) { - if (pl330_fifo_inc(s->t, s->buf_size) != s->s) { - s->buf[s->t] = buf[i]; - s->tag[s->t] = tag; - s->t = pl330_fifo_inc(s->t, s->buf_size); - } else { - /* Rollback transaction */ - s->s = old_s; - s->t = old_t; - return PL330_FIFO_STALL; - } - } - return PL330_FIFO_OK; -} - -/* Get LEN bytes of data from MFIFO and store it to BUF. Tag value of each - byte is veryfied. Zero returned on success, PL330_FIFO_ERR on tag missmatch - and PL330_FIFO_STALL if there is no enough data in MFIFO. If get was - unsaccessful no data is removed from MFIFO. */ -static int pl330_fifo_get(pl330_fifo *s, uint8_t *buf, int len, uint8_t tag) -{ - int i, ret; - int old_s, old_t; - - old_s = s->s; - old_t = s->t; - for (i = 0; i < len; i++) { - if (s->t != s->s && s->tag[s->s] == tag) { - buf[i] = s->buf[s->s]; - s->s = pl330_fifo_inc(s->s, s->buf_size); - } else { - /* Rollback transaction */ - if (s->t == s->s) - ret = PL330_FIFO_STALL; - else - ret = PL330_FIFO_ERR; - s->s = old_s; - s->t = old_t; - return ret; - } - } - return PL330_FIFO_OK; -} - -/* Reset MFIFO. This completely erases all data in it. */ -static inline void pl330_fifo_reset(pl330_fifo *s) -{ - s->s = 0; - s->t = 0; -} - -/* Return tag of the first byte stored in MFIFO. If MFIFO is empty - PL330_UNTAGGED is returned. */ -static inline uint8_t pl330_fifo_tag(pl330_fifo *s) -{ - if (s->t == s->s) - return PL330_UNTAGGED; - return s->tag[s->s]; -} - -/* Returns non-zero if tag TAG is present in fifo or zero otherwise */ -static int pl330_fifo_has_tag(pl330_fifo *s, uint8_t tag) -{ - int i; - - for (i = s->s; i != s->t; i = pl330_fifo_inc(i, s->buf_size)) { - if (s->tag[i] == tag) - return 1; - } - return 0; -} - -/* Remove all entry tagged with TAG from MFIFO */ -static void pl330_fifo_tagged_remove(pl330_fifo *s, uint8_t tag) -{ - int i, t; - - t = s->s; - for (i = s->s; i != s->t; i = pl330_fifo_inc(i, s->buf_size)) { - if (s->tag[i] != tag) { - s->buf[t] = s->buf[i]; - s->tag[t] = s->tag[i]; - t++; - } - } - s->t = t; -} - - -/* Read-Write Queue implementation */ - -/* - * Read-Write Queue stores up to QUEUE_SIZE instructions (loads or stores). - * Each instructions is described by source (for loads) or destination (for - * stores) address ADDR, width of data to be loaded/stored LEN, number of - * stores/loads to be performed N, INC bit, Z bit and TAG to identify channel - * this instruction belongs to. Queue does not store any information about - * nature of the instruction: is it load or store. PL330 has different queues - * for loads and stores so this is already known at the top level where it matters. - * - * Queue works as FIFO for instructions with equivalent tags, but can issue - * instructions with different tags in arbitrary order. SEQN field attached to - * each instruction helps to achieve this. For each TAG queue contains - * instructions with consecutive SEQN values ranged from LO_SEQN[TAG] to - * HI_SEQN[TAG]-1 inclusive. SEQN is 8-bit unsigned integer, so SEQN=255 is - * followed by SEQN=0. - * - * Z bit indicates that zeroes should be stored. Thus no MFIFO fetches - * are performed in this case. - */ - -static void pl330_queue_reset(pl330_queue *s) -{ - int i; - - for (i = 0; i < s->queue_size; i++) - s->queue[i].tag = PL330_UNTAGGED; -} - -/* Initialize queue */ -static void pl330_queue_init(pl330_queue *s, int size, int channum) -{ - s->queue = (pl330_queue_entry *) - qemu_mallocz(size * sizeof(pl330_queue_entry)); - s->lo_seqn = (uint8_t *)qemu_mallocz(channum * sizeof(uint8_t)); - s->hi_seqn = (uint8_t *)qemu_mallocz(channum * sizeof(uint8_t)); - s->queue_size = size; -} - -/* Returns pointer to an empty slot or NULL if queue is full */ -static pl330_queue_entry *pl330_queue_find_empty(pl330_queue *s) -{ - int i; - - for (i = 0; i < s->queue_size; i++) - if (s->queue[i].tag == PL330_UNTAGGED) - return &s->queue[i]; - return NULL; -} - -/* Puts instruction to queue. - Return value: - - zero - OK - - non-zero - queue is full */ -static int pl330_insn_to_queue(pl330_queue *s, uint32_t addr, - int len, int n, int inc, int z, uint8_t tag) -{ - pl330_queue_entry *entry = pl330_queue_find_empty(s); - - if (! entry) - return 1; - entry->tag = tag; - entry->addr = addr; - entry->len = len; - entry->n = n; - entry->z = z; - entry->inc = inc; - entry->seqn = s->hi_seqn[tag]; - s->hi_seqn[tag]++; - return 0; -} - -/* Returns a pointer to queue slot containing instruction which satisfies - following conditions: - - it has valid tag value (not PL330_UNTAGGED) - - it can be issued without violating queue logic (see above) - - if TAG argument is not PL330_UNTAGGED this instruction has tag value - equivalent to the argument TAG value. - If such instruction cannot be found NULL is returned. */ -static pl330_queue_entry *pl330_queue_find_insn(pl330_queue *s, - uint8_t tag) -{ - int i; - - for (i = 0; i < s->queue_size; i++) { - if (s->queue[i].tag != PL330_UNTAGGED) { - if (s->queue[i].seqn == s->lo_seqn[s->queue[i].tag] && - (s->queue[i].tag == tag || - tag == PL330_UNTAGGED || - s->queue[i].z)) - return &s->queue[i]; - } - } - return NULL; -} - -/* Removes instruction from queue. */ -static inline void pl330_insn_from_queue(pl330_queue *s, - pl330_queue_entry *e) -{ - s->lo_seqn[e->tag]++; - e->tag = PL330_UNTAGGED; -} - -/* Removes all instructions tagged with TAG from queue. */ -static inline void pl330_tag_from_queue(pl330_queue *s, uint8_t tag) -{ - int i; - - for (i = 0; i < s->queue_size; i++) { - if (s->queue[i].tag == tag) - s->queue[i].tag = PL330_UNTAGGED; - } -} - - -/* DMA instruction execution engine */ - -/* Moves DMA channel to the FAULT state and updates it's status. */ -static inline void pl330_fault(pl330_chan_state *ch, uint32_t flags) -{ - ch->fault_type |= flags; - ch->state = pl330_chan_fault; - ch->parent->num_faulting++; - if (ch->parent->num_faulting == 1) { - qemu_irq_raise(ch->parent->irq_abort); - } -} - -/* - * For information about instructions see PL330 Technical Reference Manual. - * - * Arguments: - * CH - chanel executing the instruction - * OPCODE - opcode - * ARGS - array of 8-bit arguments - * LEN - number of elements in ARGS array - */ -static void pl330_dmaaddh(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint16_t im = (((uint16_t)args[0]) << 8) | ((uint16_t)args[1]); - uint8_t ra = (opcode >> 1) & 1; - - if (ra) { - ch->dst += im; - } else { - ch->src += im; - } -} - -static void pl330_dmaend(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - if (ch->state == pl330_chan_executing && !ch->is_manager) { - /* Wait for all transfers to complete */ - if (pl330_fifo_has_tag(&ch->parent->fifo, ch->tag) || - pl330_queue_find_insn(&ch->parent->read_queue, ch->tag) != NULL || - pl330_queue_find_insn(&ch->parent->write_queue, ch->tag) != NULL) { - - ch->stall = 1; - return; - } - } - pl330_fifo_tagged_remove(&ch->parent->fifo, ch->tag); - pl330_tag_from_queue(&ch->parent->read_queue, ch->tag); - pl330_tag_from_queue(&ch->parent->write_queue, ch->tag); - ch->state = pl330_chan_stopped; -} - -static void pl330_dmaflushp(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t periph_id; - - if (args[0] & 7) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - periph_id = (args[0] >> 3) & 0x1f; - if (periph_id >= ch->parent->periph_num) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (ch->ns > ((ch->parent->cfg[4] & (1 << periph_id)) >> periph_id)) { - pl330_fault(ch, PL330_FAULT_CH_PERIPH_ER); - return; - } - /* Do nothing */ -} - -static void pl330_dmago(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t chan_id; - uint8_t ns; - uint32_t pc; - pl330_chan_state *s; - - if (! ch->is_manager) { - /* TODO: what error actually is it? */ - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - ns = (opcode >> 1) & 1; - chan_id = args[0] & 7; - if ((args[0] >> 3)) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (chan_id >= ch->parent->chan_num) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - pc = (((uint32_t)args[4]) << 24) | (((uint32_t)args[3]) << 16) | - (((uint32_t)args[2]) << 8) | (((uint32_t)args[1])); - if (ch->parent->chan[chan_id].state != pl330_chan_stopped) { - /* TODO: what error actually is it? */ - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (ch->ns > ns) { - pl330_fault(ch, PL330_FAULT_DMAGO_ER); - return; - } - s = &ch->parent->chan[chan_id]; - s->ns = ns; - s->pc = pc; - s->state = pl330_chan_executing; -} - -static void pl330_dmald(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t bs = opcode & 3; - uint32_t size, num, inc; - - if (bs == 2) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if ((bs == 1 && ch->request_flag == PL330_BURST) || - (bs == 3 && ch->request_flag == PL330_SINGLE)) { - /* Perform NOP */ - return; - } - num = ((ch->control >> 4) & 0xf) + 1; - size = (uint32_t)1 << ((ch->control >> 1) & 0x7); - inc = ch->control & 1; - ch->stall = pl330_insn_to_queue(&ch->parent->read_queue, ch->src, - size, num, inc, 0, ch->tag); - if (inc) { - ch->src += size * num; - } -} - -static void pl330_dmaldp(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t periph_id; - - if (args[0] & 7) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - periph_id = (args[0] >> 3) & 0x1f; - if (periph_id >= ch->parent->periph_num) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (ch->ns > ((ch->parent->cfg[4] & (1 << periph_id)) >> periph_id)) { - pl330_fault(ch, PL330_FAULT_CH_PERIPH_ER); - return; - } - pl330_dmald(ch, opcode, args, len); -} - -static void pl330_dmalp(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t lc = (opcode & 2) >> 1; - - ch->lc[lc] = args[0]; -} - -static void pl330_dmalpend(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t nf = (opcode & 0x10) >> 4; - uint8_t bs = opcode & 3; - uint8_t lc = (opcode & 4) >> 2; - - if (bs == 2) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if ((bs == 1 && ch->request_flag == PL330_BURST) || - (bs == 3 && ch->request_flag == PL330_SINGLE)) { - /* Perform NOP */ - return; - } - if (!nf || ch->lc[lc]) { - if (nf) { - ch->lc[lc]--; - } - ch->pc -= args[0]; - ch->pc -= len + 1; - /* "ch->pc -= args[0] + len + 1" is incorrect when args[0] == 256 */ - } -} - -static void pl330_dmakill(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - if (ch->state == pl330_chan_fault || - ch->state == pl330_chan_fault_completing) { - /* This is the only way for chanel from faulting state */ - ch->fault_type = 0; - ch->parent->num_faulting--; - if (ch->parent->num_faulting == 0) { - qemu_irq_lower(ch->parent->irq_abort); - } - } - ch->state = pl330_chan_killing; - pl330_fifo_tagged_remove(&ch->parent->fifo, ch->tag); - pl330_tag_from_queue(&ch->parent->read_queue, ch->tag); - pl330_tag_from_queue(&ch->parent->write_queue, ch->tag); - ch->state = pl330_chan_stopped; -} - -static void pl330_dmamov(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t rd = args[0] & 7; - uint32_t im; - - if ((args[0] >> 3)) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - im = (((uint32_t)args[4]) << 24) | (((uint32_t)args[3]) << 16) | - (((uint32_t)args[2]) << 8) | (((uint32_t)args[1])); - switch (rd) { - case 0: - ch->src = im; - break; - case 1: - ch->control = im; - break; - case 2: - ch->dst = im; - break; - default: - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } -} - -static void pl330_dmanop(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - /* NOP is NOP. */ -} - -static void pl330_dmarmb(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - /* Do nothing. Since we do not emulate AXI Bus transactions there is no - stalls. So we are allways on barrier. */ -} - -static void pl330_dmasev(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t ev_id; - - if (args[0] & 7) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - ev_id = (args[0] >> 3) & 0x1f; - if (ev_id >= ch->parent->event_num) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (ch->ns > ((ch->parent->cfg[3] & (1 << ev_id)) >> ev_id)) { - pl330_fault(ch, PL330_FAULT_EVENT_ER); - return; - } - if (ch->parent->inten & (1 << ev_id)) { - ch->parent->int_status |= (1 << ev_id); - qemu_irq_raise(ch->parent->irq[ev_id]); - } else { - ch->parent->ev_status |= (1 << ev_id); - } -} - -static void pl330_dmast(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t bs = opcode & 3; - uint32_t size, num, inc; - - if (bs == 2) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if ((bs == 1 && ch->request_flag == PL330_BURST) || - (bs == 3 && ch->request_flag == PL330_SINGLE)) { - /* Perform NOP */ - return; - } - num = ((ch->control >> 18) & 0xf) + 1; - size = (uint32_t)1 << ((ch->control >> 15) & 0x7); - inc = (ch->control >> 14) & 1; - ch->stall = pl330_insn_to_queue(&ch->parent->write_queue, ch->dst, - size, num, inc, 0, ch->tag); - if (inc) { - ch->dst += size * num; - } -} - -static void pl330_dmastp(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t periph_id; - - if (args[0] & 7) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - periph_id = (args[0] >> 3) & 0x1f; - if (periph_id >= ch->parent->periph_num) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (ch->ns > ((ch->parent->cfg[4] & (1 << periph_id)) >> periph_id)) { - pl330_fault(ch, PL330_FAULT_CH_PERIPH_ER); - return; - } - pl330_dmast(ch, opcode, args, len); -} - -static void pl330_dmastz(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint32_t size, num, inc; - - num = ((ch->control >> 18) & 0xf) + 1; - size = (uint32_t)1 << ((ch->control >> 15) & 0x7); - inc = (ch->control >> 14) & 1; - ch->stall = pl330_insn_to_queue(&ch->parent->write_queue, ch->dst, - size, num, inc, 1, ch->tag); - if (inc) { - ch->dst += size * num; - } -} - -static void pl330_dmawfe(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t ev_id; - - if (args[0] & 5) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - ev_id = (args[0] >> 3) & 0x1f; - if (ev_id >= ch->parent->event_num) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (ch->ns > ((ch->parent->cfg[3] & (1 << ev_id)) >> ev_id)) { - pl330_fault(ch, PL330_FAULT_EVENT_ER); - return; - } - ch->wakeup = ev_id; -} - -static void pl330_dmawfp(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - uint8_t bs = opcode & 3; - uint8_t periph_id; - - if (args[0] & 7) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - periph_id = (args[0] >> 3) & 0x1f; - if (periph_id >= ch->parent->periph_num) { - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - if (ch->ns > ((ch->parent->cfg[4] & (1 << periph_id)) >> periph_id)) { - pl330_fault(ch, PL330_FAULT_CH_PERIPH_ER); - return; - } - switch (bs) { - case 0: /* S */ - ch->request_flag = PL330_SINGLE; - ch->wfp_sbp = 0; - break; - case 1: /* P */ - ch->request_flag = PL330_BURST; - ch->wfp_sbp = 2; - break; - case 2: /* B */ - ch->request_flag = PL330_BURST; - ch->wfp_sbp = 1; - break; - default: - pl330_fault(ch, PL330_FAULT_OPERAND_INVALID); - return; - } - - if (ch->parent->periph_busy[periph_id]) { - ch->state = pl330_chan_waiting_periph; - } else if (ch->state == pl330_chan_waiting_periph) { - ch->state = pl330_chan_executing; - } -} - -static void pl330_dmawmb(pl330_chan_state *ch, uint8_t opcode, - uint8_t *args, int len) -{ - /* Do nothing. Since we do not emulate AXI Bus transactions there is no - stalls. So we are allways on barrier. */ -} - -/* "NULL" terminated array of the instruction descriptions. */ -static const pl330_insn_desc insn_desc[] = { - { .opcode = 0x54, .opmask = 0xFD, .size = 3, .exec = pl330_dmaaddh }, - { .opcode = 0x00, .opmask = 0xFF, .size = 1, .exec = pl330_dmaend }, - { .opcode = 0x35, .opmask = 0xFF, .size = 2, .exec = pl330_dmaflushp }, - { .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago }, - { .opcode = 0x04, .opmask = 0xFC, .size = 1, .exec = pl330_dmald }, - { .opcode = 0x25, .opmask = 0xFD, .size = 2, .exec = pl330_dmaldp }, - { .opcode = 0x20, .opmask = 0xFD, .size = 2, .exec = pl330_dmalp }, - /* dmastp must be before dmalpend in tis map, because thay maps - * are overrided */ - { .opcode = 0x29, .opmask = 0xFD, .size = 2, .exec = pl330_dmastp }, - { .opcode = 0x28, .opmask = 0xE8, .size = 2, .exec = pl330_dmalpend }, - { .opcode = 0x01, .opmask = 0xFF, .size = 1, .exec = pl330_dmakill }, - { .opcode = 0xBC, .opmask = 0xFF, .size = 6, .exec = pl330_dmamov }, - { .opcode = 0x18, .opmask = 0xFF, .size = 1, .exec = pl330_dmanop }, - { .opcode = 0x12, .opmask = 0xFF, .size = 1, .exec = pl330_dmarmb }, - { .opcode = 0x34, .opmask = 0xFF, .size = 2, .exec = pl330_dmasev }, - { .opcode = 0x08, .opmask = 0xFC, .size = 1, .exec = pl330_dmast }, - { .opcode = 0x0C, .opmask = 0xFF, .size = 1, .exec = pl330_dmastz }, - { .opcode = 0x36, .opmask = 0xFF, .size = 2, .exec = pl330_dmawfe }, - { .opcode = 0x30, .opmask = 0xFC, .size = 2, .exec = pl330_dmawfp }, - { .opcode = 0x13, .opmask = 0xFF, .size = 1, .exec = pl330_dmawmb }, - { .opcode = 0x00, .opmask = 0x00, .size = 0, .exec = NULL } -}; - -/* Instructions which can be issued via debug registers. */ -static const pl330_insn_desc debug_insn_desc[] = { - { .opcode = 0xA0, .opmask = 0xFD, .size = 6, .exec = pl330_dmago }, - { .opcode = 0x01, .opmask = 0xFF, .size = 1, .exec = pl330_dmakill }, - { .opcode = 0x34, .opmask = 0xFF, .size = 2, .exec = pl330_dmasev }, - { .opcode = 0x00, .opmask = 0x00, .size = 0, .exec = NULL } -}; - -static inline const pl330_insn_desc * - pl330_fetch_insn(pl330_chan_state *ch) -{ - uint8_t opcode; - int i; - - cpu_physical_memory_read(ch->pc, &opcode, 1); - for (i = 0; insn_desc[i].size; i++) - if ((opcode & insn_desc[i].opmask) == insn_desc[i].opcode) - return &insn_desc[i]; - return NULL; -} - -static inline void pl330_exec_insn(pl330_chan_state *ch, - const pl330_insn_desc *insn) -{ - uint8_t buf[PL330_INSN_MAXSIZE]; - - cpu_physical_memory_read(ch->pc, buf, insn->size); - insn->exec(ch, buf[0], &buf[1], insn->size - 1); -} - -static inline void pl330_update_pc(pl330_chan_state *ch, - const pl330_insn_desc *insn) -{ - ch->pc += insn->size; -} - -/* Try to execute current instruction in channel CH. Number of executed - instructions is returned (0 or 1). */ -static int pl330_chan_exec(pl330_chan_state *ch) -{ - const pl330_insn_desc *insn; - - if (ch->state != pl330_chan_executing && ch->state != pl330_chan_waiting_periph) { - return 0; - } - ch->stall = 0; - insn = pl330_fetch_insn(ch); - if (! insn) { - pl330_fault(ch, PL330_FAULT_UNDEF_INSTR); - return 0; - } - pl330_exec_insn(ch, insn); - if (ch->state == pl330_chan_executing && !ch->stall) { - pl330_update_pc(ch, insn); - ch->watchdog_timer = 0; - return 1; - } else { - if (ch->stall) { - ch->watchdog_timer++; - if (ch->watchdog_timer >= PL330_WATCHDOG_LIMIT) { - pl330_fault(ch, PL330_FAULT_LOCKUP_ER); - } - } - } - return 0; -} - -/* Try to execute 1 instruction in each channel, one instruction from read - queue and one instruction from write queue. Number of successfully executed - instructions is returned. */ -static int pl330_exec_cycle(pl330_chan_state *channel) -{ - pl330_state *s = channel->parent; - pl330_queue_entry *q; - int i; - int num_exec = 0; - int fifo_res = 0; - uint8_t buf[PL330_MAX_BURST_LEN]; - - /* Execute one instruction in each channel */ - num_exec += pl330_chan_exec(channel); - - /* Execute one instruction from read queue */ - q = pl330_queue_find_insn(&s->read_queue, PL330_UNTAGGED); - if (q != NULL && q->len <= pl330_fifo_num_free(&s->fifo)) { - cpu_physical_memory_read(q->addr, buf, q->len); - fifo_res = pl330_fifo_push(&s->fifo, buf, q->len, q->tag); - if (fifo_res == PL330_FIFO_OK) { - if (q->inc) { - q->addr += q->len; - } - q->n--; - if (! q->n) { - pl330_insn_from_queue(&s->read_queue, q); - } - num_exec++; - } - } - - /* Execute one instruction from write queue. */ - q = pl330_queue_find_insn(&s->write_queue, pl330_fifo_tag(&s->fifo)); - if (q != NULL && (q->z || q->len <= pl330_fifo_num_used(&s->fifo))) { - if (q->z) { - for (i = 0; i < q->len; i++) { - buf[i] = 0; - } - } else { - fifo_res = pl330_fifo_get(&s->fifo, buf, q->len, q->tag); - } - if (fifo_res == PL330_FIFO_OK || q->z) { - cpu_physical_memory_write(q->addr, buf, q->len); - if (q->inc) { - q->addr += q->len; - } - q->n--; - if (! q->n) { - pl330_insn_from_queue(&s->write_queue, q); - } - num_exec++; - } - } - - return num_exec; -} - -static int pl330_exec_channel(pl330_chan_state *channel) -{ - int insr_exec = 0; - - /* TODO: Is it all right to execute everything or should we do per-cycle - simulation? */ - while (pl330_exec_cycle(channel)) { - insr_exec++; - } - - /* Detect deadlock */ - if (channel->state == pl330_chan_executing) { - pl330_fault(channel, PL330_FAULT_LOCKUP_ER); - } - /* Situation when one of the queues has deadlocked but all channels - has finished their programs should be impossible. */ - - return insr_exec; -} - - -static inline void pl330_exec(pl330_state *s) -{ - int i, insr_exec; - do { - insr_exec = pl330_exec_channel(&s->manager); - - for (i = 0; i < s->chan_num; i++) { - insr_exec += pl330_exec_channel(&s->chan[i]); - } - } while (insr_exec); -} - -static void pl330_exec_cycle_timer(void *opaque) -{ - struct pl330_state *s = (struct pl330_state *)opaque; - pl330_exec(s); -} - -/* Stop or restore dma operations */ -static void pl330_dma_stop_irq(void *opaque, int irq, int level) -{ - struct pl330_state *s = (struct pl330_state *)opaque; - - if (s->periph_busy[irq] != level) { - s->periph_busy[irq] = level; - qemu_mod_timer(s->timer, qemu_get_clock(vm_clock)); - } -} - -static void pl330_debug_exec(pl330_state *s) -{ - uint8_t args[5]; - uint8_t opcode; - uint8_t chan_id; - int i; - pl330_chan_state *ch; - const pl330_insn_desc *insn; - - s->debug_status = 1; - chan_id = (s->dbg[0] >> 8) & 0x07; - opcode = (s->dbg[0] >> 16) & 0xff; - args[0] = (s->dbg[0] >> 24) & 0xff; - args[1] = (s->dbg[1] >> 0) & 0xff; - args[2] = (s->dbg[1] >> 8) & 0xff; - args[3] = (s->dbg[1] >> 16) & 0xff; - args[4] = (s->dbg[1] >> 24) & 0xff; - if (s->dbg[0] & 1) { - ch = &s->chan[chan_id]; - } else { - ch = &s->manager; - } - insn = NULL; - for (i = 0; debug_insn_desc[i].size; i++) - if ((opcode & debug_insn_desc[i].opmask) == debug_insn_desc[i].opcode) - insn = &debug_insn_desc[i]; - if (!insn) { - pl330_fault(ch, PL330_FAULT_UNDEF_INSTR); - return ; - } - ch->stall = 0; - insn->exec(ch, opcode, args, insn->size - 1); - if (ch->stall) { - hw_error("pl330: stall of debug instruction not implemented\n"); - } - s->debug_status = 0; -} - - -/* IOMEM mapped registers */ - -static void pl330_iomem_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - pl330_state *s = (pl330_state *) opaque; - uint32_t i; - - if (offset & 3) { - hw_error("pl330: bad write offset " TARGET_FMT_plx "\n", offset); - } - switch (offset) { - case PL330_REG_INTEN: - s->inten = value; - break; - case PL330_REG_INTCLR: - for (i = 0; i < s->event_num; i++) { - if (s->int_status & s->inten & value & (1 << i)) { - qemu_irq_lower(s->irq[i]); - } - } - s->int_status &= ~value; - break; - case PL330_REG_DBGCMD: - if ((value & 3) == 0) { - pl330_debug_exec(s); - pl330_exec(s); - } else { - hw_error("pl330: write of illegal value %u for offset " - TARGET_FMT_plx "\n", value, offset); - } - break; - case PL330_REG_DBGINST0: - s->dbg[0] = value; - break; - case PL330_REG_DBGINST1: - s->dbg[1] = value; - break; - default: - hw_error("pl330: bad write offset " TARGET_FMT_plx "\n", offset); - break; - } -} - -static uint32_t pl330_iomem_read(void *opaque, target_phys_addr_t offset) -{ - pl330_state *s = (pl330_state *) opaque; - int chan_id; - int i; - uint32_t res; - - if (offset & 3) { - hw_error("pl330: bad read offset " TARGET_FMT_plx "\n", offset); - } - - if (offset >= PL330_REG_ID && offset < PL330_REG_ID + 32) { - return pl330_id[(offset - PL330_REG_ID) >> 2]; - } - if (offset >= PL330_REG_CONFIG && offset < PL330_REG_CONFIG + 24) { - return s->cfg[(offset - PL330_REG_CONFIG) >> 2]; - } - if (offset >= PL330_REG_CHANCTRL && offset < 0xD00) { - offset -= PL330_REG_CHANCTRL; - chan_id = offset >> 5; - if (chan_id >= s->chan_num) { - hw_error("pl330: bad read offset " TARGET_FMT_plx "\n", offset); - } - switch (offset & 0x1f) { - case 0x00: - return s->chan[chan_id].src; - case 0x04: - return s->chan[chan_id].dst; - case 0x08: - return s->chan[chan_id].control; - case 0x0C: - return s->chan[chan_id].lc[0]; - case 0x10: - return s->chan[chan_id].lc[1]; - default: - hw_error("pl330: bad read offset " TARGET_FMT_plx "\n", offset); - } - } - if (offset >= PL330_REG_CS_BASE && offset < 0x400) { - offset -= PL330_REG_CS_BASE; - chan_id = offset >> 3; - if (chan_id >= s->chan_num) { - hw_error("pl330: bad read offset " TARGET_FMT_plx "\n", offset); - } - switch ((offset >> 2) & 1) { - case 0x0: - return (s->chan[chan_id].ns << 20) | (s->chan[chan_id].wakeup << 4) | - (s->chan[chan_id].state & 0xf) | - (s->chan[chan_id].wfp_sbp << 13); - case 0x1: - return s->chan[chan_id].pc; - default: - hw_error("pl330: read error\n"); - } - } - if (offset >= PL330_REG_FTC_BASE && offset < 0x100) { - offset -= PL330_REG_FTC_BASE; - chan_id = offset >> 2; - if (chan_id >= s->chan_num) { - hw_error("pl330: bad read offset " TARGET_FMT_plx "\n", offset); - } - return s->chan[chan_id].fault_type; - } - switch (offset) { - case PL330_REG_DS: - return (s->manager.ns << 8) | (s->manager.wakeup << 4) | - (s->manager.state & 0xf); - case PL330_REG_DPC: - return s->manager.pc; - case PL330_REG_INTEN: - return s->inten; - case PL330_REG_ES: - return s->ev_status; - case PL330_REG_INTSTATUS: - return s->int_status; - case PL330_REG_INTCLR: - /* Documentation says that we can't read this register - * but linux kernel does it */ - return 0; - case PL330_REG_FSM: - return s->manager.fault_type ? 1 : 0; - case PL330_REG_FSC: - res = 0; - for (i = 0; i < s->chan_num; i++) { - if (s->chan[i].state == pl330_chan_fault || - s->chan[i].state == pl330_chan_fault_completing) { - res |= 1 << i; - } - } - return res; - case PL330_REG_FTM: - return s->manager.fault_type; - case PL330_REG_DBGSTATUS: - return s->debug_status; - default: - hw_error("pl330: bad read offset " TARGET_FMT_plx "\n", offset); - } -} - -static CPUReadMemoryFunc * const pl330_readfn[] = { - pl330_iomem_read, - pl330_iomem_read, - pl330_iomem_read -}; - -static CPUWriteMemoryFunc * const pl330_writefn[] = { - pl330_iomem_write, - pl330_iomem_write, - pl330_iomem_write -}; - -static void pl330_save(QEMUFile *f, void *opaque) -{ - pl330_state *s = (pl330_state *) opaque; - int i; - /* manager */ - qemu_put_be32s(f, &s->manager.src); - qemu_put_be32s(f, &s->manager.dst); - qemu_put_be32s(f, &s->manager.pc); - qemu_put_be32s(f, &s->manager.control); - qemu_put_be32s(f, &s->manager.status); - qemu_put_be32s(f, &s->manager.lc[0]); - qemu_put_be32s(f, &s->manager.lc[1]); - qemu_put_be32s(f, &s->manager.fault_type); - qemu_put_8s (f, &s->manager.request_flag); - qemu_put_8s (f, &s->manager.wakeup); - qemu_put_8s (f, &s->manager.wfp_sbp); - qemu_put_byte (f, (uint8_t) s->manager.state); - qemu_put_8s (f, &s->manager.stall); - qemu_put_be32s(f, &s->manager.watchdog_timer); - /* chan[chan_num] */ - for (i = 0; i < s->chan_num; i++) { - qemu_put_be32s(f, &s->chan[i].src); - qemu_put_be32s(f, &s->chan[i].dst); - qemu_put_be32s(f, &s->chan[i].pc); - qemu_put_be32s(f, &s->chan[i].control); - qemu_put_be32s(f, &s->chan[i].status); - qemu_put_be32s(f, &s->chan[i].lc[0]); - qemu_put_be32s(f, &s->chan[i].lc[1]); - qemu_put_be32s(f, &s->chan[i].fault_type); - qemu_put_8s (f, &s->chan[i].ns); - qemu_put_8s (f, &s->chan[i].request_flag); - qemu_put_8s (f, &s->chan[i].wakeup); - qemu_put_8s (f, &s->chan[i].wfp_sbp); - qemu_put_byte (f, (uint8_t) s->chan[i].state); - qemu_put_8s (f, &s->chan[i].stall); - qemu_put_be32s(f, &s->chan[i].watchdog_timer); - } - /* fifo */ - qemu_put_buffer(f, s->fifo.buf, s->fifo.buf_size); - qemu_put_buffer(f, s->fifo.tag, s->fifo.buf_size); - qemu_put_sbe32s(f, &s->fifo.s); - qemu_put_sbe32s(f, &s->fifo.t); - /* read_queue */ - for (i = 0; i < s->read_queue.queue_size; i++) { - qemu_put_be32s (f, &s->read_queue.queue->addr); - qemu_put_sbe32s(f, &s->read_queue.queue->len); - qemu_put_sbe32s(f, &s->read_queue.queue->n); - qemu_put_sbe32s(f, &s->read_queue.queue->inc); - qemu_put_sbe32s(f, &s->read_queue.queue->z); - qemu_put_8s (f, &s->read_queue.queue->tag); - qemu_put_8s (f, &s->read_queue.queue->seqn); - } - qemu_put_buffer(f, s->read_queue.lo_seqn, s->chan_num); - qemu_put_buffer(f, s->read_queue.hi_seqn, s->chan_num); - /* write_queue */ - for (i = 0; i < s->write_queue.queue_size; i++) { - qemu_put_be32s (f, &s->write_queue.queue->addr); - qemu_put_sbe32s(f, &s->write_queue.queue->len); - qemu_put_sbe32s(f, &s->write_queue.queue->n); - qemu_put_sbe32s(f, &s->write_queue.queue->inc); - qemu_put_sbe32s(f, &s->write_queue.queue->z); - qemu_put_8s (f, &s->write_queue.queue->tag); - qemu_put_8s (f, &s->write_queue.queue->seqn); - } - qemu_put_buffer(f, s->write_queue.lo_seqn, s->chan_num); - qemu_put_buffer(f, s->write_queue.hi_seqn, s->chan_num); - /* config registers */ - qemu_put_be32s(f, &s->inten); - qemu_put_be32s(f, &s->int_status); - qemu_put_be32s(f, &s->ev_status); - for (i = 0; i < 6; i++) { - qemu_put_be32s(f, s->cfg + i); - if (i > 1) - continue; - qemu_put_be32s(f, s->dbg + i); - } - qemu_put_8s (f, &s->debug_status); - /* other */ - qemu_put_8s (f, &s->num_faulting); - qemu_put_sbuffer(f, s->periph_busy, PL330_PERIPH_NUM); - qemu_put_timer (f, s->timer); -} - -static int pl330_load(QEMUFile *f, void *opaque, int version_id) -{ - pl330_state *s = (pl330_state *) opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - /* manager */ - qemu_get_be32s(f, &s->manager.src); - qemu_get_be32s(f, &s->manager.dst); - qemu_get_be32s(f, &s->manager.pc); - qemu_get_be32s(f, &s->manager.control); - qemu_get_be32s(f, &s->manager.status); - qemu_get_be32s(f, &s->manager.lc[0]); - qemu_get_be32s(f, &s->manager.lc[1]); - qemu_get_be32s(f, &s->manager.fault_type); - qemu_get_8s (f, &s->manager.request_flag); - qemu_get_8s (f, &s->manager.wakeup); - qemu_get_8s (f, &s->manager.wfp_sbp); - s->manager.state = qemu_get_byte(f); - qemu_get_8s (f, &s->manager.stall); - qemu_get_be32s(f, &s->manager.watchdog_timer); - /* chan[chan_num] */ - for (i = 0; i < s->chan_num; i++) { - qemu_get_be32s(f, &s->chan[i].src); - qemu_get_be32s(f, &s->chan[i].dst); - qemu_get_be32s(f, &s->chan[i].pc); - qemu_get_be32s(f, &s->chan[i].control); - qemu_get_be32s(f, &s->chan[i].status); - qemu_get_be32s(f, &s->chan[i].lc[0]); - qemu_get_be32s(f, &s->chan[i].lc[1]); - qemu_get_be32s(f, &s->chan[i].fault_type); - qemu_get_8s (f, &s->chan[i].ns); - qemu_get_8s (f, &s->chan[i].request_flag); - qemu_get_8s (f, &s->chan[i].wakeup); - qemu_get_8s (f, &s->chan[i].wfp_sbp); - s->chan[i].state = qemu_get_byte(f); - qemu_get_8s (f, &s->chan[i].stall); - qemu_get_be32s(f, &s->chan[i].watchdog_timer); - } - /* fifo */ - qemu_get_buffer(f, s->fifo.buf, s->fifo.buf_size); - qemu_get_buffer(f, s->fifo.tag, s->fifo.buf_size); - qemu_get_sbe32s(f, &s->fifo.s); - qemu_get_sbe32s(f, &s->fifo.t); - /* read_queue */ - for (i = 0; i < s->read_queue.queue_size; i++) { - qemu_get_be32s (f, &s->read_queue.queue->addr); - qemu_get_sbe32s(f, &s->read_queue.queue->len); - qemu_get_sbe32s(f, &s->read_queue.queue->n); - qemu_get_sbe32s(f, &s->read_queue.queue->inc); - qemu_get_sbe32s(f, &s->read_queue.queue->z); - qemu_get_8s (f, &s->read_queue.queue->tag); - qemu_get_8s (f, &s->read_queue.queue->seqn); - } - qemu_get_buffer(f, s->read_queue.lo_seqn, s->chan_num); - qemu_get_buffer(f, s->read_queue.hi_seqn, s->chan_num); - /* write_queue */ - for (i = 0; i < s->write_queue.queue_size; i++) { - qemu_get_be32s (f, &s->write_queue.queue->addr); - qemu_get_sbe32s(f, &s->write_queue.queue->len); - qemu_get_sbe32s(f, &s->write_queue.queue->n); - qemu_get_sbe32s(f, &s->write_queue.queue->inc); - qemu_get_sbe32s(f, &s->write_queue.queue->z); - qemu_get_8s (f, &s->write_queue.queue->tag); - qemu_get_8s (f, &s->write_queue.queue->seqn); - } - qemu_get_buffer(f, s->write_queue.lo_seqn, s->chan_num); - qemu_get_buffer(f, s->write_queue.hi_seqn, s->chan_num); - /* config registers */ - qemu_get_be32s(f, &s->inten); - qemu_get_be32s(f, &s->int_status); - qemu_get_be32s(f, &s->ev_status); - for (i = 0; i < 6; i++) { - qemu_get_be32s(f, &s->cfg[i]); - if (i > 1) - continue; - qemu_get_be32s(f, &s->dbg[i]); - } - qemu_get_8s (f, &s->debug_status); - /* other */ - qemu_get_8s (f, &s->num_faulting); - qemu_get_sbuffer(f, s->periph_busy, PL330_PERIPH_NUM); - qemu_get_timer (f, s->timer); - - return 0; -} - -/* Controller logic and initialization */ - -static void pl330_chan_reset(pl330_chan_state *ch) -{ - ch->src = 0; - ch->dst = 0; - ch->pc = 0; - ch->state = pl330_chan_stopped; - ch->watchdog_timer = 0; - ch->stall = 0; - ch->control = 0; - ch->status = 0; - ch->fault_type = 0; -} - -static void pl330_reset(DeviceState *d) -{ - int i; - pl330_state *s = FROM_SYSBUS(pl330_state, sysbus_from_qdev(d)); - - s->inten = 0; - s->int_status = 0; - s->ev_status = 0; - s->debug_status = 0; - s->num_faulting = 0; - pl330_fifo_reset(&s->fifo); - pl330_queue_reset(&s->read_queue); - pl330_queue_reset(&s->write_queue); - - for (i = 0; i < s->chan_num; i++) { - pl330_chan_reset(&s->chan[i]); - } - for (i = 0; i < s->periph_num; i++) { - s->periph_busy[i] = 0; - } -} - -/* PrimeCell PL330 Initialization. CFG is a 6-element array of 32-bit integers. - CFG[0] is Config Register 0, CFG[1] - Config Register 1, ..., CFG[4] - - Config Register 4 and CFG[5] - Config Register Dn. IRQS is an array of - interrupts. Required number of elements in this array is discribed by - bits [21:17] of CFG[0]. */ -DeviceState *pl330_init(target_phys_addr_t base, - uint32_t instance, const uint32_t *cfg, - qemu_irq *irqs, qemu_irq irq_abort) -{ - DeviceState *dev; - SysBusDevice *s; - int i; - - dev = qdev_create(NULL, "pl330"); - qdev_prop_set_uint32(dev, "instance", instance); - qdev_prop_set_uint32(dev, "cfg0", cfg[0]); - qdev_prop_set_uint32(dev, "cfg1", cfg[1]); - qdev_prop_set_uint32(dev, "cfg2", cfg[2]); - qdev_prop_set_uint32(dev, "cfg3", cfg[3]); - qdev_prop_set_uint32(dev, "cfg4", cfg[4]); - qdev_prop_set_uint32(dev, "cfg5", cfg[5]); - - qdev_init_nofail(dev); - s = sysbus_from_qdev(dev); - sysbus_connect_irq(s, 0, irq_abort); - for (i = 0; i < ((cfg[0] >> 17) & 0x1f) + 1; i++) { - sysbus_connect_irq(s, i + 1, irqs[i]); - } - sysbus_mmio_map(s, 0, base); - - return dev; -} - -static int pl330_init1(SysBusDevice *dev) -{ - int i; - int iomem; - pl330_state *s = FROM_SYSBUS(pl330_state, dev); - - sysbus_init_irq(dev, &s->irq_abort); - iomem = cpu_register_io_memory(pl330_readfn, pl330_writefn, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, PL330_IOMEM_SIZE, iomem); - s->timer = qemu_new_timer(vm_clock, pl330_exec_cycle_timer, s); - - s->chan_num = ((s->cfg[0] >> 4) & 7) + 1; - s->chan = qemu_mallocz(sizeof(pl330_chan_state) * s->chan_num); - for (i = 0; i < s->chan_num; i++) { - s->chan[i].parent = s; - s->chan[i].tag = (uint8_t)i; - } - s->manager.parent = s; - s->manager.tag = s->chan_num; - s->manager.ns = (s->cfg[0] >> 2) & 1; - s->manager.is_manager = 1; - if (s->cfg[0] & 1) { - s->periph_num = ((s->cfg[0] >> 12) & 0x1f) + 1; - } else { - s->periph_num = 0; - } - s->event_num = ((s->cfg[0] >> 17) & 0x1f) + 1; - - s->irq = qemu_mallocz(sizeof(qemu_irq) * s->event_num); - for (i = 0; i < s->event_num; i++) { - sysbus_init_irq(dev, &s->irq[i]); - } - - qdev_init_gpio_in(&dev->qdev, pl330_dma_stop_irq, PL330_PERIPH_NUM); - - pl330_queue_init(&s->read_queue, ((s->cfg[5] >> 16) & 0xf) + 1, s->chan_num); - pl330_queue_init(&s->write_queue, ((s->cfg[5] >> 8) & 0xf) + 1, s->chan_num); - pl330_fifo_init(&s->fifo, ((s->cfg[5] >> 20) & 0x1ff) + 1); - pl330_reset(&s->busdev.qdev); - - register_savevm(&dev->qdev, "pl330", s->instance, 1, - pl330_save, pl330_load, s); - - return 0; -} - -static SysBusDeviceInfo pl330_info = { - .init = pl330_init1, - .qdev.name = "pl330", - .qdev.size = sizeof(pl330_state), - .qdev.reset = pl330_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("instance", pl330_state, instance, 0), - DEFINE_PROP_HEX32 ("cfg0", pl330_state, cfg[0], 0), - DEFINE_PROP_HEX32 ("cfg1", pl330_state, cfg[1], 0), - DEFINE_PROP_HEX32 ("cfg2", pl330_state, cfg[2], 0), - DEFINE_PROP_HEX32 ("cfg3", pl330_state, cfg[3], 0), - DEFINE_PROP_HEX32 ("cfg4", pl330_state, cfg[4], 0), - DEFINE_PROP_HEX32 ("cfg5", pl330_state, cfg[5], 0), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void pl330_register_devices(void) -{ - sysbus_register_withprop(&pl330_info); -} - -device_init(pl330_register_devices) diff --git a/hw/ppc.c b/hw/ppc.c index 968aec1..d29af0b 100644 --- a/hw/ppc.c +++ b/hw/ppc.c @@ -50,7 +50,7 @@ static void cpu_ppc_tb_stop (CPUState *env); static void cpu_ppc_tb_start (CPUState *env); -static void ppc_set_irq (CPUState *env, int n_IRQ, int level) +void ppc_set_irq(CPUState *env, int n_IRQ, int level) { unsigned int old_pending = env->pending_interrupts; @@ -208,6 +208,7 @@ static void ppc970_set_irq (void *opaque, int pin, int level) } else { LOG_IRQ("%s: restart the CPU\n", __func__); env->halted = 0; + qemu_cpu_kick(env); } break; case PPC970_INPUT_HRESET: @@ -246,6 +247,39 @@ void ppc970_irq_init (CPUState *env) env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env, PPC970_INPUT_NB); } + +/* POWER7 internal IRQ controller */ +static void power7_set_irq (void *opaque, int pin, int level) +{ + CPUState *env = opaque; + + LOG_IRQ("%s: env %p pin %d level %d\n", __func__, + env, pin, level); + + switch (pin) { + case POWER7_INPUT_INT: + /* Level sensitive - active high */ + LOG_IRQ("%s: set the external IRQ state to %d\n", + __func__, level); + ppc_set_irq(env, PPC_INTERRUPT_EXT, level); + break; + default: + /* Unknown pin - do nothing */ + LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); + return; + } + if (level) { + env->irq_input_state |= 1 << pin; + } else { + env->irq_input_state &= ~(1 << pin); + } +} + +void ppcPOWER7_irq_init (CPUState *env) +{ + env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, env, + POWER7_INPUT_NB); +} #endif /* defined(TARGET_PPC64) */ /* PowerPC 40x internal IRQ controller */ @@ -300,6 +334,7 @@ static void ppc40x_set_irq (void *opaque, int pin, int level) } else { LOG_IRQ("%s: restart the CPU\n", __func__); env->halted = 0; + qemu_cpu_kick(env); } break; case PPC40x_INPUT_DEBUG: @@ -388,25 +423,8 @@ void ppce500_irq_init (CPUState *env) } /*****************************************************************************/ /* PowerPC time base and decrementer emulation */ -struct ppc_tb_t { - /* Time base management */ - int64_t tb_offset; /* Compensation */ - int64_t atb_offset; /* Compensation */ - uint32_t tb_freq; /* TB frequency */ - /* Decrementer management */ - uint64_t decr_next; /* Tick for next decr interrupt */ - uint32_t decr_freq; /* decrementer frequency */ - struct QEMUTimer *decr_timer; - /* Hypervisor decrementer management */ - uint64_t hdecr_next; /* Tick for next hdecr interrupt */ - struct QEMUTimer *hdecr_timer; - uint64_t purr_load; - uint64_t purr_start; - void *opaque; -}; -static inline uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, - int64_t tb_offset) +uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset) { /* TB time in tb periods */ return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset; @@ -417,7 +435,11 @@ uint64_t cpu_ppc_load_tbl (CPUState *env) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset); + if (kvm_enabled()) { + return env->spr[SPR_TBL]; + } + + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset); LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); return tb; @@ -428,7 +450,7 @@ static inline uint32_t _cpu_ppc_load_tbu(CPUState *env) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset); + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset); LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); return tb >> 32; @@ -436,6 +458,10 @@ static inline uint32_t _cpu_ppc_load_tbu(CPUState *env) uint32_t cpu_ppc_load_tbu (CPUState *env) { + if (kvm_enabled()) { + return env->spr[SPR_TBU]; + } + return _cpu_ppc_load_tbu(env); } @@ -452,9 +478,9 @@ void cpu_ppc_store_tbl (CPUState *env, uint32_t value) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset); + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset); tb &= 0xFFFFFFFF00000000ULL; - cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock), + cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock), &tb_env->tb_offset, tb | (uint64_t)value); } @@ -463,9 +489,9 @@ static inline void _cpu_ppc_store_tbu(CPUState *env, uint32_t value) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->tb_offset); + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset); tb &= 0x00000000FFFFFFFFULL; - cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock), + cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock), &tb_env->tb_offset, ((uint64_t)value << 32) | tb); } @@ -479,7 +505,7 @@ uint64_t cpu_ppc_load_atbl (CPUState *env) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset); + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset); LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); return tb; @@ -490,7 +516,7 @@ uint32_t cpu_ppc_load_atbu (CPUState *env) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset); + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset); LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); return tb >> 32; @@ -501,9 +527,9 @@ void cpu_ppc_store_atbl (CPUState *env, uint32_t value) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset); + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset); tb &= 0xFFFFFFFF00000000ULL; - cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock), + cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock), &tb_env->atb_offset, tb | (uint64_t)value); } @@ -512,9 +538,9 @@ void cpu_ppc_store_atbu (CPUState *env, uint32_t value) ppc_tb_t *tb_env = env->tb_env; uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_get_clock(vm_clock), tb_env->atb_offset); + tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset); tb &= 0x00000000FFFFFFFFULL; - cpu_ppc_store_tb(tb_env, qemu_get_clock(vm_clock), + cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock), &tb_env->atb_offset, ((uint64_t)value << 32) | tb); } @@ -525,7 +551,7 @@ static void cpu_ppc_tb_stop (CPUState *env) /* If the time base is already frozen, do nothing */ if (tb_env->tb_freq != 0) { - vmclk = qemu_get_clock(vm_clock); + vmclk = qemu_get_clock_ns(vm_clock); /* Get the time base */ tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset); /* Get the alternate time base */ @@ -547,7 +573,7 @@ static void cpu_ppc_tb_start (CPUState *env) /* If the time base is not frozen, do nothing */ if (tb_env->tb_freq == 0) { - vmclk = qemu_get_clock(vm_clock); + vmclk = qemu_get_clock_ns(vm_clock); /* Get the time base from tb_offset */ tb = tb_env->tb_offset; /* Get the alternate time base from atb_offset */ @@ -567,11 +593,14 @@ static inline uint32_t _cpu_ppc_load_decr(CPUState *env, uint64_t next) uint32_t decr; int64_t diff; - diff = next - qemu_get_clock(vm_clock); - if (diff >= 0) + diff = next - qemu_get_clock_ns(vm_clock); + if (diff >= 0) { decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec()); - else + } else if (tb_env->flags & PPC_TIMER_BOOKE) { + decr = 0; + } else { decr = -muldiv64(-diff, tb_env->decr_freq, get_ticks_per_sec()); + } LOG_TB("%s: %08" PRIx32 "\n", __func__, decr); return decr; @@ -581,6 +610,10 @@ uint32_t cpu_ppc_load_decr (CPUState *env) { ppc_tb_t *tb_env = env->tb_env; + if (kvm_enabled()) { + return env->spr[SPR_DECR]; + } + return _cpu_ppc_load_decr(env, tb_env->decr_next); } @@ -596,7 +629,7 @@ uint64_t cpu_ppc_load_purr (CPUState *env) ppc_tb_t *tb_env = env->tb_env; uint64_t diff; - diff = qemu_get_clock(vm_clock) - tb_env->purr_start; + diff = qemu_get_clock_ns(vm_clock) - tb_env->purr_start; return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec()); } @@ -629,20 +662,32 @@ static void __cpu_ppc_store_decr (CPUState *env, uint64_t *nextp, LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__, decr, value); - now = qemu_get_clock(vm_clock); + + if (kvm_enabled()) { + /* KVM handles decrementer exceptions, we don't need our own timer */ + return; + } + + now = qemu_get_clock_ns(vm_clock); next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq); - if (is_excp) + if (is_excp) { next += *nextp - now; - if (next == now) + } + if (next == now) { next++; + } *nextp = next; /* Adjust timer */ qemu_mod_timer(timer, next); - /* If we set a negative value and the decrementer was positive, - * raise an exception. + + /* If we set a negative value and the decrementer was positive, raise an + * exception. */ - if ((value & 0x80000000) && !(decr & 0x80000000)) + if ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) + && (value & 0x80000000) + && !(decr & 0x80000000)) { (*raise_excp)(env); + } } static inline void _cpu_ppc_store_decr(CPUState *env, uint32_t decr, @@ -690,7 +735,7 @@ void cpu_ppc_store_purr (CPUState *env, uint64_t value) ppc_tb_t *tb_env = env->tb_env; tb_env->purr_load = value; - tb_env->purr_start = qemu_get_clock(vm_clock); + tb_env->purr_start = qemu_get_clock_ns(vm_clock); } static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq) @@ -714,14 +759,15 @@ clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq) { ppc_tb_t *tb_env; - tb_env = qemu_mallocz(sizeof(ppc_tb_t)); + tb_env = g_malloc0(sizeof(ppc_tb_t)); env->tb_env = tb_env; + tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED; /* Create new timer */ - tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env); + tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_decr_cb, env); if (0) { /* XXX: find a suitable condition to enable the hypervisor decrementer */ - tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env); + tb_env->hdecr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_hdecr_cb, env); } else { tb_env->hdecr_timer = NULL; } @@ -759,11 +805,11 @@ uint32_t cpu_ppc601_load_rtcl (CPUState *env) } /*****************************************************************************/ -/* Embedded PowerPC timers */ +/* PowerPC 40x timers */ /* PIT, FIT & WDT */ -typedef struct ppcemb_timer_t ppcemb_timer_t; -struct ppcemb_timer_t { +typedef struct ppc40x_timer_t ppc40x_timer_t; +struct ppc40x_timer_t { uint64_t pit_reload; /* PIT auto-reload value */ uint64_t fit_next; /* Tick for next FIT interrupt */ struct QEMUTimer *fit_timer; @@ -779,13 +825,13 @@ static void cpu_4xx_fit_cb (void *opaque) { CPUState *env; ppc_tb_t *tb_env; - ppcemb_timer_t *ppcemb_timer; + ppc40x_timer_t *ppc40x_timer; uint64_t now, next; env = opaque; tb_env = env->tb_env; - ppcemb_timer = tb_env->opaque; - now = qemu_get_clock(vm_clock); + ppc40x_timer = tb_env->opaque; + now = qemu_get_clock_ns(vm_clock); switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) { case 0: next = 1 << 9; @@ -806,7 +852,7 @@ static void cpu_4xx_fit_cb (void *opaque) next = now + muldiv64(next, get_ticks_per_sec(), tb_env->tb_freq); if (next == now) next++; - qemu_mod_timer(ppcemb_timer->fit_timer, next); + qemu_mod_timer(ppc40x_timer->fit_timer, next); env->spr[SPR_40x_TSR] |= 1 << 26; if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) ppc_set_irq(env, PPC_INTERRUPT_FIT, 1); @@ -818,11 +864,11 @@ static void cpu_4xx_fit_cb (void *opaque) /* Programmable interval timer */ static void start_stop_pit (CPUState *env, ppc_tb_t *tb_env, int is_excp) { - ppcemb_timer_t *ppcemb_timer; + ppc40x_timer_t *ppc40x_timer; uint64_t now, next; - ppcemb_timer = tb_env->opaque; - if (ppcemb_timer->pit_reload <= 1 || + ppc40x_timer = tb_env->opaque; + if (ppc40x_timer->pit_reload <= 1 || !((env->spr[SPR_40x_TCR] >> 26) & 0x1) || (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) { /* Stop PIT */ @@ -830,9 +876,9 @@ static void start_stop_pit (CPUState *env, ppc_tb_t *tb_env, int is_excp) qemu_del_timer(tb_env->decr_timer); } else { LOG_TB("%s: start PIT %016" PRIx64 "\n", - __func__, ppcemb_timer->pit_reload); - now = qemu_get_clock(vm_clock); - next = now + muldiv64(ppcemb_timer->pit_reload, + __func__, ppc40x_timer->pit_reload); + now = qemu_get_clock_ns(vm_clock); + next = now + muldiv64(ppc40x_timer->pit_reload, get_ticks_per_sec(), tb_env->decr_freq); if (is_excp) next += tb_env->decr_next - now; @@ -847,21 +893,21 @@ static void cpu_4xx_pit_cb (void *opaque) { CPUState *env; ppc_tb_t *tb_env; - ppcemb_timer_t *ppcemb_timer; + ppc40x_timer_t *ppc40x_timer; env = opaque; tb_env = env->tb_env; - ppcemb_timer = tb_env->opaque; + ppc40x_timer = tb_env->opaque; env->spr[SPR_40x_TSR] |= 1 << 27; if ((env->spr[SPR_40x_TCR] >> 26) & 0x1) - ppc_set_irq(env, ppcemb_timer->decr_excp, 1); + ppc_set_irq(env, ppc40x_timer->decr_excp, 1); start_stop_pit(env, tb_env, 1); LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " " "%016" PRIx64 "\n", __func__, (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1), (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1), env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR], - ppcemb_timer->pit_reload); + ppc40x_timer->pit_reload); } /* Watchdog timer */ @@ -869,13 +915,13 @@ static void cpu_4xx_wdt_cb (void *opaque) { CPUState *env; ppc_tb_t *tb_env; - ppcemb_timer_t *ppcemb_timer; + ppc40x_timer_t *ppc40x_timer; uint64_t now, next; env = opaque; tb_env = env->tb_env; - ppcemb_timer = tb_env->opaque; - now = qemu_get_clock(vm_clock); + ppc40x_timer = tb_env->opaque; + now = qemu_get_clock_ns(vm_clock); switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) { case 0: next = 1 << 17; @@ -901,13 +947,13 @@ static void cpu_4xx_wdt_cb (void *opaque) switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) { case 0x0: case 0x1: - qemu_mod_timer(ppcemb_timer->wdt_timer, next); - ppcemb_timer->wdt_next = next; + qemu_mod_timer(ppc40x_timer->wdt_timer, next); + ppc40x_timer->wdt_next = next; env->spr[SPR_40x_TSR] |= 1 << 31; break; case 0x2: - qemu_mod_timer(ppcemb_timer->wdt_timer, next); - ppcemb_timer->wdt_next = next; + qemu_mod_timer(ppc40x_timer->wdt_timer, next); + ppc40x_timer->wdt_next = next; env->spr[SPR_40x_TSR] |= 1 << 30; if ((env->spr[SPR_40x_TCR] >> 27) & 0x1) ppc_set_irq(env, PPC_INTERRUPT_WDT, 1); @@ -935,12 +981,12 @@ static void cpu_4xx_wdt_cb (void *opaque) void store_40x_pit (CPUState *env, target_ulong val) { ppc_tb_t *tb_env; - ppcemb_timer_t *ppcemb_timer; + ppc40x_timer_t *ppc40x_timer; tb_env = env->tb_env; - ppcemb_timer = tb_env->opaque; + ppc40x_timer = tb_env->opaque; LOG_TB("%s val" TARGET_FMT_lx "\n", __func__, val); - ppcemb_timer->pit_reload = val; + ppc40x_timer->pit_reload = val; start_stop_pit(env, tb_env, 0); } @@ -949,31 +995,7 @@ target_ulong load_40x_pit (CPUState *env) return cpu_ppc_load_decr(env); } -void store_booke_tsr (CPUState *env, target_ulong val) -{ - ppc_tb_t *tb_env = env->tb_env; - ppcemb_timer_t *ppcemb_timer; - - ppcemb_timer = tb_env->opaque; - - LOG_TB("%s: val " TARGET_FMT_lx "\n", __func__, val); - env->spr[SPR_40x_TSR] &= ~(val & 0xFC000000); - if (val & 0x80000000) - ppc_set_irq(env, ppcemb_timer->decr_excp, 0); -} - -void store_booke_tcr (CPUState *env, target_ulong val) -{ - ppc_tb_t *tb_env; - - tb_env = env->tb_env; - LOG_TB("%s: val " TARGET_FMT_lx "\n", __func__, val); - env->spr[SPR_40x_TCR] = val & 0xFFC00000; - start_stop_pit(env, tb_env, 1); - cpu_4xx_wdt_cb(env); -} - -static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq) +static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq) { CPUState *env = opaque; ppc_tb_t *tb_env = env->tb_env; @@ -985,30 +1007,31 @@ static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq) /* XXX: we should also update all timers */ } -clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq, +clk_setup_cb ppc_40x_timers_init (CPUState *env, uint32_t freq, unsigned int decr_excp) { ppc_tb_t *tb_env; - ppcemb_timer_t *ppcemb_timer; + ppc40x_timer_t *ppc40x_timer; - tb_env = qemu_mallocz(sizeof(ppc_tb_t)); + tb_env = g_malloc0(sizeof(ppc_tb_t)); env->tb_env = tb_env; - ppcemb_timer = qemu_mallocz(sizeof(ppcemb_timer_t)); + tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED; + ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t)); tb_env->tb_freq = freq; tb_env->decr_freq = freq; - tb_env->opaque = ppcemb_timer; + tb_env->opaque = ppc40x_timer; LOG_TB("%s freq %" PRIu32 "\n", __func__, freq); - if (ppcemb_timer != NULL) { + if (ppc40x_timer != NULL) { /* We use decr timer for PIT */ - tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_4xx_pit_cb, env); - ppcemb_timer->fit_timer = - qemu_new_timer(vm_clock, &cpu_4xx_fit_cb, env); - ppcemb_timer->wdt_timer = - qemu_new_timer(vm_clock, &cpu_4xx_wdt_cb, env); - ppcemb_timer->decr_excp = decr_excp; + tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_4xx_pit_cb, env); + ppc40x_timer->fit_timer = + qemu_new_timer_ns(vm_clock, &cpu_4xx_fit_cb, env); + ppc40x_timer->wdt_timer = + qemu_new_timer_ns(vm_clock, &cpu_4xx_wdt_cb, env); + ppc40x_timer->decr_excp = decr_excp; } - return &ppc_emb_set_tb_clk; + return &ppc_40x_set_tb_clk; } /*****************************************************************************/ @@ -1098,7 +1121,7 @@ int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn), { ppc_dcr_t *dcr_env; - dcr_env = qemu_mallocz(sizeof(ppc_dcr_t)); + dcr_env = g_malloc0(sizeof(ppc_dcr_t)); dcr_env->read_error = read_error; dcr_env->write_error = write_error; env->dcr_env = dcr_env; diff --git a/hw/ppc.h b/hw/ppc.h index 34f54cf..9f91170 100644 --- a/hw/ppc.h +++ b/hw/ppc.h @@ -1,3 +1,5 @@ +void ppc_set_irq (CPUState *env, int n_IRQ, int level); + /* PowerPC hardware exceptions management helpers */ typedef void (*clk_setup_cb)(void *opaque, uint32_t freq); typedef struct clk_setup_t clk_setup_t; @@ -11,6 +13,36 @@ static inline void clk_setup (clk_setup_t *clk, uint32_t freq) (*clk->cb)(clk->opaque, freq); } +struct ppc_tb_t { + /* Time base management */ + int64_t tb_offset; /* Compensation */ + int64_t atb_offset; /* Compensation */ + uint32_t tb_freq; /* TB frequency */ + /* Decrementer management */ + uint64_t decr_next; /* Tick for next decr interrupt */ + uint32_t decr_freq; /* decrementer frequency */ + struct QEMUTimer *decr_timer; + /* Hypervisor decrementer management */ + uint64_t hdecr_next; /* Tick for next hdecr interrupt */ + struct QEMUTimer *hdecr_timer; + uint64_t purr_load; + uint64_t purr_start; + void *opaque; + uint32_t flags; +}; + +/* PPC Timers flags */ +#define PPC_TIMER_BOOKE (1 << 0) /* Enable Booke support */ +#define PPC_TIMER_E500 (1 << 1) /* Enable e500 support */ +#define PPC_DECR_UNDERFLOW_TRIGGERED (1 << 2) /* Decr interrupt triggered when + * the most significant bit + * changes from 0 to 1. + */ +#define PPC_DECR_ZERO_TRIGGERED (1 << 3) /* Decr interrupt triggered when + * the decrementer reaches zero. + */ + +uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset); clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq); /* Embedded PowerPC DCR management */ typedef uint32_t (*dcr_read_cb)(void *opaque, int dcrn); @@ -19,7 +51,7 @@ int ppc_dcr_init (CPUState *env, int (*dcr_read_error)(int dcrn), int (*dcr_write_error)(int dcrn)); int ppc_dcr_register (CPUState *env, int dcrn, void *opaque, dcr_read_cb drc_read, dcr_write_cb dcr_write); -clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq, +clk_setup_cb ppc_40x_timers_init (CPUState *env, uint32_t freq, unsigned int decr_excp); /* Embedded PowerPC reset */ @@ -36,6 +68,7 @@ void ppc40x_irq_init (CPUState *env); void ppce500_irq_init (CPUState *env); void ppc6xx_irq_init (CPUState *env); void ppc970_irq_init (CPUState *env); +void ppcPOWER7_irq_init (CPUState *env); /* PPC machines for OpenBIOS */ enum { @@ -54,3 +87,6 @@ enum { #define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07) #define PPC_SERIAL_MM_BAUDBASE 399193 + +/* ppc_booke.c */ +void ppc_booke_timers_init(CPUState *env, uint32_t freq, uint32_t flags); diff --git a/hw/ppc405.h b/hw/ppc405.h index e042a05..d8fdf09 100644 --- a/hw/ppc405.h +++ b/hw/ppc405.h @@ -59,16 +59,21 @@ struct ppc4xx_bd_info_t { ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd, uint32_t flags); -CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], - target_phys_addr_t ram_sizes[4], - uint32_t sysclk, qemu_irq **picp, - int do_init); -CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], - target_phys_addr_t ram_sizes[2], - uint32_t sysclk, qemu_irq **picp, - int do_init); +CPUState *ppc405cr_init(MemoryRegion *address_space_mem, + MemoryRegion ram_memories[4], + target_phys_addr_t ram_bases[4], + target_phys_addr_t ram_sizes[4], + uint32_t sysclk, qemu_irq **picp, + int do_init); +CPUState *ppc405ep_init(MemoryRegion *address_space_mem, + MemoryRegion ram_memories[2], + target_phys_addr_t ram_bases[2], + target_phys_addr_t ram_sizes[2], + uint32_t sysclk, qemu_irq **picp, + int do_init); /* IBM STBxxx microcontrollers */ -CPUState *ppc_stb025_init (target_phys_addr_t ram_bases[2], +CPUState *ppc_stb025_init (MemoryRegion ram_memories[2], + target_phys_addr_t ram_bases[2], target_phys_addr_t ram_sizes[2], uint32_t sysclk, qemu_irq **picp, ram_addr_t *offsetp); diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c index 9abede7..672e934 100644 --- a/hw/ppc405_boards.c +++ b/hw/ppc405_boards.c @@ -32,6 +32,7 @@ #include "qemu-log.h" #include "loader.h" #include "blockdev.h" +#include "exec-memory.h" #define BIOS_FILENAME "ppc405_rom.bin" #define BIOS_SIZE (2048 * 1024) @@ -136,16 +137,16 @@ static void ref405ep_fpga_writel (void *opaque, ref405ep_fpga_writeb(opaque, addr + 3, value & 0xFF); } -static CPUReadMemoryFunc * const ref405ep_fpga_read[] = { - &ref405ep_fpga_readb, - &ref405ep_fpga_readw, - &ref405ep_fpga_readl, -}; - -static CPUWriteMemoryFunc * const ref405ep_fpga_write[] = { - &ref405ep_fpga_writeb, - &ref405ep_fpga_writew, - &ref405ep_fpga_writel, +static const MemoryRegionOps ref405ep_fpga_ops = { + .old_mmio = { + .read = { + ref405ep_fpga_readb, ref405ep_fpga_readw, ref405ep_fpga_readl, + }, + .write = { + ref405ep_fpga_writeb, ref405ep_fpga_writew, ref405ep_fpga_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void ref405ep_fpga_reset (void *opaque) @@ -157,16 +158,15 @@ static void ref405ep_fpga_reset (void *opaque) fpga->reg1 = 0x0F; } -static void ref405ep_fpga_init (uint32_t base) +static void ref405ep_fpga_init (MemoryRegion *sysmem, uint32_t base) { ref405ep_fpga_t *fpga; - int fpga_memory; + MemoryRegion *fpga_memory = g_new(MemoryRegion, 1); - fpga = qemu_mallocz(sizeof(ref405ep_fpga_t)); - fpga_memory = cpu_register_io_memory(ref405ep_fpga_read, - ref405ep_fpga_write, fpga, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x00000100, fpga_memory); + fpga = g_malloc0(sizeof(ref405ep_fpga_t)); + memory_region_init_io(fpga_memory, &ref405ep_fpga_ops, fpga, + "fpga", 0x00000100); + memory_region_add_subregion(sysmem, base, fpga_memory); qemu_register_reset(&ref405ep_fpga_reset, fpga); } @@ -181,7 +181,10 @@ static void ref405ep_init (ram_addr_t ram_size, ppc4xx_bd_info_t bd; CPUPPCState *env; qemu_irq *pic; - ram_addr_t sram_offset, bios_offset, bdloc; + MemoryRegion *bios; + MemoryRegion *sram = g_new(MemoryRegion, 1); + ram_addr_t bdloc; + MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories)); target_phys_addr_t ram_bases[2], ram_sizes[2]; target_ulong sram_size; long bios_size; @@ -192,26 +195,25 @@ static void ref405ep_init (ram_addr_t ram_size, int linux_boot; int fl_idx, fl_sectors, len; DriveInfo *dinfo; + MemoryRegion *sysmem = get_system_memory(); /* XXX: fix this */ - ram_bases[0] = qemu_ram_alloc(NULL, "ef405ep.ram", 0x08000000); + memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000); + ram_bases[0] = 0; ram_sizes[0] = 0x08000000; + memory_region_init(&ram_memories[1], "ef405ep.ram1", 0); ram_bases[1] = 0x00000000; ram_sizes[1] = 0x00000000; ram_size = 128 * 1024 * 1024; #ifdef DEBUG_BOARD_INIT printf("%s: register cpu\n", __func__); #endif - env = ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic, - kernel_filename == NULL ? 0 : 1); + env = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes, + 33333333, &pic, kernel_filename == NULL ? 0 : 1); /* allocate SRAM */ sram_size = 512 * 1024; - sram_offset = qemu_ram_alloc(NULL, "ef405ep.sram", sram_size); -#ifdef DEBUG_BOARD_INIT - printf("%s: register SRAM at offset %08lx\n", __func__, sram_offset); -#endif - cpu_register_physical_memory(0xFFF00000, sram_size, - sram_offset | IO_MEM_RAM); + memory_region_init_ram(sram, NULL, "ef405ep.sram", sram_size); + memory_region_add_subregion(sysmem, 0xFFF00000, sram); /* allocate and load BIOS */ #ifdef DEBUG_BOARD_INIT printf("%s: register BIOS\n", __func__); @@ -221,15 +223,15 @@ static void ref405ep_init (ram_addr_t ram_size, dinfo = drive_get(IF_PFLASH, 0, fl_idx); if (dinfo) { bios_size = bdrv_getlength(dinfo->bdrv); - bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size); fl_sectors = (bios_size + 65535) >> 16; #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size %lx" - " at offset %08lx addr %lx '%s' %d\n", - fl_idx, bios_size, bios_offset, -bios_size, + " at addr %lx '%s' %d\n", + fl_idx, bios_size, -bios_size, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi02_register((uint32_t)(-bios_size), bios_offset, + pflash_cfi02_register((uint32_t)(-bios_size), + NULL, "ef405ep.bios", bios_size, dinfo->bdrv, 65536, fl_sectors, 1, 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 1); @@ -240,13 +242,14 @@ static void ref405ep_init (ram_addr_t ram_size, #ifdef DEBUG_BOARD_INIT printf("Load BIOS from file\n"); #endif - bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE); + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset)); - qemu_free(filename); + bios_size = load_image(filename, memory_region_get_ram_ptr(bios)); + g_free(filename); } else { bios_size = -1; } @@ -256,14 +259,14 @@ static void ref405ep_init (ram_addr_t ram_size, exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; - cpu_register_physical_memory((uint32_t)(-bios_size), - bios_size, bios_offset | IO_MEM_ROM); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios); } /* Register FPGA */ #ifdef DEBUG_BOARD_INIT printf("%s: register FPGA\n", __func__); #endif - ref405ep_fpga_init(0xF0300000); + ref405ep_fpga_init(sysmem, 0xF0300000); /* Register NVRAM */ #ifdef DEBUG_BOARD_INIT printf("%s: register NVRAM\n", __func__); @@ -350,7 +353,7 @@ static void ref405ep_init (ram_addr_t ram_size, #ifdef DEBUG_BOARD_INIT printf("%s: Done\n", __func__); #endif - printf("bdloc %016lx\n", (unsigned long)bdloc); + printf("bdloc " RAM_ADDR_FMT "\n", bdloc); } static QEMUMachine ref405ep_machine = { @@ -461,16 +464,12 @@ static void taihu_cpld_writel (void *opaque, taihu_cpld_writeb(opaque, addr + 3, value & 0xFF); } -static CPUReadMemoryFunc * const taihu_cpld_read[] = { - &taihu_cpld_readb, - &taihu_cpld_readw, - &taihu_cpld_readl, -}; - -static CPUWriteMemoryFunc * const taihu_cpld_write[] = { - &taihu_cpld_writeb, - &taihu_cpld_writew, - &taihu_cpld_writel, +static const MemoryRegionOps taihu_cpld_ops = { + .old_mmio = { + .read = { taihu_cpld_readb, taihu_cpld_readw, taihu_cpld_readl, }, + .write = { taihu_cpld_writeb, taihu_cpld_writew, taihu_cpld_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void taihu_cpld_reset (void *opaque) @@ -482,16 +481,14 @@ static void taihu_cpld_reset (void *opaque) cpld->reg1 = 0x80; } -static void taihu_cpld_init (uint32_t base) +static void taihu_cpld_init (MemoryRegion *sysmem, uint32_t base) { taihu_cpld_t *cpld; - int cpld_memory; + MemoryRegion *cpld_memory = g_new(MemoryRegion, 1); - cpld = qemu_mallocz(sizeof(taihu_cpld_t)); - cpld_memory = cpu_register_io_memory(taihu_cpld_read, - taihu_cpld_write, cpld, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x00000100, cpld_memory); + cpld = g_malloc0(sizeof(taihu_cpld_t)); + memory_region_init_io(cpld_memory, &taihu_cpld_ops, cpld, "cpld", 0x100); + memory_region_add_subregion(sysmem, base, cpld_memory); qemu_register_reset(&taihu_cpld_reset, cpld); } @@ -504,7 +501,9 @@ static void taihu_405ep_init(ram_addr_t ram_size, { char *filename; qemu_irq *pic; - ram_addr_t bios_offset; + MemoryRegion *sysmem = get_system_memory(); + MemoryRegion *bios; + MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories)); target_phys_addr_t ram_bases[2], ram_sizes[2]; long bios_size; target_ulong kernel_base, initrd_base; @@ -514,16 +513,20 @@ static void taihu_405ep_init(ram_addr_t ram_size, DriveInfo *dinfo; /* RAM is soldered to the board so the size cannot be changed */ - ram_bases[0] = qemu_ram_alloc(NULL, "taihu_405ep.ram-0", 0x04000000); + memory_region_init_ram(&ram_memories[0], NULL, + "taihu_405ep.ram-0", 0x04000000); + ram_bases[0] = 0; ram_sizes[0] = 0x04000000; - ram_bases[1] = qemu_ram_alloc(NULL, "taihu_405ep.ram-1", 0x04000000); + memory_region_init_ram(&ram_memories[1], NULL, + "taihu_405ep.ram-1", 0x04000000); + ram_bases[1] = 0x04000000; ram_sizes[1] = 0x04000000; ram_size = 0x08000000; #ifdef DEBUG_BOARD_INIT printf("%s: register cpu\n", __func__); #endif - ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic, - kernel_filename == NULL ? 0 : 1); + ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes, + 33333333, &pic, kernel_filename == NULL ? 0 : 1); /* allocate and load BIOS */ #ifdef DEBUG_BOARD_INIT printf("%s: register BIOS\n", __func__); @@ -536,14 +539,14 @@ static void taihu_405ep_init(ram_addr_t ram_size, /* XXX: should check that size is 2MB */ // bios_size = 2 * 1024 * 1024; fl_sectors = (bios_size + 65535) >> 16; - bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size); #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size %lx" - " at offset %08lx addr %lx '%s' %d\n", - fl_idx, bios_size, bios_offset, -bios_size, + " at addr %lx '%s' %d\n", + fl_idx, bios_size, -bios_size, bdrv_get_device_name(dinfo->bdrv), fl_sectors); #endif - pflash_cfi02_register((uint32_t)(-bios_size), bios_offset, + pflash_cfi02_register((uint32_t)(-bios_size), + NULL, "taihu_405ep.bios", bios_size, dinfo->bdrv, 65536, fl_sectors, 1, 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 1); @@ -556,10 +559,12 @@ static void taihu_405ep_init(ram_addr_t ram_size, #endif if (bios_name == NULL) bios_name = BIOS_FILENAME; - bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE); + bios = g_new(MemoryRegion, 1); + memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset)); + bios_size = load_image(filename, memory_region_get_ram_ptr(bios)); + g_free(filename); } else { bios_size = -1; } @@ -569,8 +574,8 @@ static void taihu_405ep_init(ram_addr_t ram_size, exit(1); } bios_size = (bios_size + 0xfff) & ~0xfff; - cpu_register_physical_memory((uint32_t)(-bios_size), - bios_size, bios_offset | IO_MEM_ROM); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios); } /* Register Linux flash */ dinfo = drive_get(IF_PFLASH, 0, fl_idx); @@ -581,12 +586,11 @@ static void taihu_405ep_init(ram_addr_t ram_size, fl_sectors = (bios_size + 65535) >> 16; #ifdef DEBUG_BOARD_INIT printf("Register parallel flash %d size %lx" - " at offset %08lx addr " TARGET_FMT_lx " '%s'\n", - fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000, + " at addr " TARGET_FMT_lx " '%s'\n", + fl_idx, bios_size, (target_ulong)0xfc000000, bdrv_get_device_name(dinfo->bdrv)); #endif - bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size); - pflash_cfi02_register(0xfc000000, bios_offset, + pflash_cfi02_register(0xfc000000, NULL, "taihu_405ep.flash", bios_size, dinfo->bdrv, 65536, fl_sectors, 1, 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 1); @@ -596,7 +600,7 @@ static void taihu_405ep_init(ram_addr_t ram_size, #ifdef DEBUG_BOARD_INIT printf("%s: register CPLD\n", __func__); #endif - taihu_cpld_init(0x50100000); + taihu_cpld_init(sysmem, 0x50100000); /* Load kernel */ linux_boot = (kernel_filename != NULL); if (linux_boot) { diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c index 334187e..a6e7431 100644 --- a/hw/ppc405_uc.c +++ b/hw/ppc405_uc.c @@ -28,6 +28,7 @@ #include "qemu-timer.h" #include "sysemu.h" #include "qemu-log.h" +#include "exec-memory.h" #define DEBUG_OPBA #define DEBUG_SDRAM @@ -51,39 +52,42 @@ ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd, bdloc = 0x01000000UL - sizeof(struct ppc4xx_bd_info_t); else bdloc = bd->bi_memsize - sizeof(struct ppc4xx_bd_info_t); - stl_phys(bdloc + 0x00, bd->bi_memstart); - stl_phys(bdloc + 0x04, bd->bi_memsize); - stl_phys(bdloc + 0x08, bd->bi_flashstart); - stl_phys(bdloc + 0x0C, bd->bi_flashsize); - stl_phys(bdloc + 0x10, bd->bi_flashoffset); - stl_phys(bdloc + 0x14, bd->bi_sramstart); - stl_phys(bdloc + 0x18, bd->bi_sramsize); - stl_phys(bdloc + 0x1C, bd->bi_bootflags); - stl_phys(bdloc + 0x20, bd->bi_ipaddr); - for (i = 0; i < 6; i++) + stl_be_phys(bdloc + 0x00, bd->bi_memstart); + stl_be_phys(bdloc + 0x04, bd->bi_memsize); + stl_be_phys(bdloc + 0x08, bd->bi_flashstart); + stl_be_phys(bdloc + 0x0C, bd->bi_flashsize); + stl_be_phys(bdloc + 0x10, bd->bi_flashoffset); + stl_be_phys(bdloc + 0x14, bd->bi_sramstart); + stl_be_phys(bdloc + 0x18, bd->bi_sramsize); + stl_be_phys(bdloc + 0x1C, bd->bi_bootflags); + stl_be_phys(bdloc + 0x20, bd->bi_ipaddr); + for (i = 0; i < 6; i++) { stb_phys(bdloc + 0x24 + i, bd->bi_enetaddr[i]); - stw_phys(bdloc + 0x2A, bd->bi_ethspeed); - stl_phys(bdloc + 0x2C, bd->bi_intfreq); - stl_phys(bdloc + 0x30, bd->bi_busfreq); - stl_phys(bdloc + 0x34, bd->bi_baudrate); - for (i = 0; i < 4; i++) + } + stw_be_phys(bdloc + 0x2A, bd->bi_ethspeed); + stl_be_phys(bdloc + 0x2C, bd->bi_intfreq); + stl_be_phys(bdloc + 0x30, bd->bi_busfreq); + stl_be_phys(bdloc + 0x34, bd->bi_baudrate); + for (i = 0; i < 4; i++) { stb_phys(bdloc + 0x38 + i, bd->bi_s_version[i]); + } for (i = 0; i < 32; i++) { stb_phys(bdloc + 0x3C + i, bd->bi_r_version[i]); } - stl_phys(bdloc + 0x5C, bd->bi_plb_busfreq); - stl_phys(bdloc + 0x60, bd->bi_pci_busfreq); - for (i = 0; i < 6; i++) + stl_be_phys(bdloc + 0x5C, bd->bi_plb_busfreq); + stl_be_phys(bdloc + 0x60, bd->bi_pci_busfreq); + for (i = 0; i < 6; i++) { stb_phys(bdloc + 0x64 + i, bd->bi_pci_enetaddr[i]); + } n = 0x6A; if (flags & 0x00000001) { for (i = 0; i < 6; i++) stb_phys(bdloc + n++, bd->bi_pci_enetaddr2[i]); } - stl_phys(bdloc + n, bd->bi_opbfreq); + stl_be_phys(bdloc + n, bd->bi_opbfreq); n += 4; for (i = 0; i < 2; i++) { - stl_phys(bdloc + n, bd->bi_iic_fast[i]); + stl_be_phys(bdloc + n, bd->bi_iic_fast[i]); n += 4; } @@ -169,7 +173,7 @@ static void ppc4xx_plb_init(CPUState *env) { ppc4xx_plb_t *plb; - plb = qemu_mallocz(sizeof(ppc4xx_plb_t)); + plb = g_malloc0(sizeof(ppc4xx_plb_t)); ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb); ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb); ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb); @@ -245,7 +249,7 @@ static void ppc4xx_pob_init(CPUState *env) { ppc4xx_pob_t *pob; - pob = qemu_mallocz(sizeof(ppc4xx_pob_t)); + pob = g_malloc0(sizeof(ppc4xx_pob_t)); ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob); ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob); ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob); @@ -256,6 +260,7 @@ static void ppc4xx_pob_init(CPUState *env) /* OPB arbitrer */ typedef struct ppc4xx_opba_t ppc4xx_opba_t; struct ppc4xx_opba_t { + MemoryRegion io; uint8_t cr; uint8_t pr; }; @@ -354,16 +359,12 @@ static void opba_writel (void *opaque, opba_writeb(opaque, addr + 1, value >> 16); } -static CPUReadMemoryFunc * const opba_read[] = { - &opba_readb, - &opba_readw, - &opba_readl, -}; - -static CPUWriteMemoryFunc * const opba_write[] = { - &opba_writeb, - &opba_writew, - &opba_writel, +static const MemoryRegionOps opba_ops = { + .old_mmio = { + .read = { opba_readb, opba_readw, opba_readl, }, + .write = { opba_writeb, opba_writew, opba_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void ppc4xx_opba_reset (void *opaque) @@ -378,15 +379,13 @@ static void ppc4xx_opba_reset (void *opaque) static void ppc4xx_opba_init(target_phys_addr_t base) { ppc4xx_opba_t *opba; - int io; - opba = qemu_mallocz(sizeof(ppc4xx_opba_t)); + opba = g_malloc0(sizeof(ppc4xx_opba_t)); #ifdef DEBUG_OPBA printf("%s: offset " TARGET_FMT_plx "\n", __func__, base); #endif - io = cpu_register_io_memory(opba_read, opba_write, opba, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x002, io); + memory_region_init_io(&opba->io, &opba_ops, opba, "opba", 0x002); + memory_region_add_subregion(get_system_memory(), base, &opba->io); qemu_register_reset(ppc4xx_opba_reset, opba); } @@ -579,7 +578,7 @@ static void ppc405_ebc_init(CPUState *env) { ppc4xx_ebc_t *ebc; - ebc = qemu_mallocz(sizeof(ppc4xx_ebc_t)); + ebc = g_malloc0(sizeof(ppc4xx_ebc_t)); qemu_register_reset(&ebc_reset, ebc); ppc_dcr_register(env, EBC0_CFGADDR, ebc, &dcr_read_ebc, &dcr_write_ebc); @@ -662,7 +661,7 @@ static void ppc405_dma_init(CPUState *env, qemu_irq irqs[4]) { ppc405_dma_t *dma; - dma = qemu_mallocz(sizeof(ppc405_dma_t)); + dma = g_malloc0(sizeof(ppc405_dma_t)); memcpy(dma->irqs, irqs, 4 * sizeof(qemu_irq)); qemu_register_reset(&ppc405_dma_reset, dma); ppc_dcr_register(env, DMA0_CR0, @@ -719,6 +718,7 @@ static void ppc405_dma_init(CPUState *env, qemu_irq irqs[4]) /* GPIO */ typedef struct ppc405_gpio_t ppc405_gpio_t; struct ppc405_gpio_t { + MemoryRegion io; uint32_t or; uint32_t tcr; uint32_t osrh; @@ -786,16 +786,12 @@ static void ppc405_gpio_writel (void *opaque, #endif } -static CPUReadMemoryFunc * const ppc405_gpio_read[] = { - &ppc405_gpio_readb, - &ppc405_gpio_readw, - &ppc405_gpio_readl, -}; - -static CPUWriteMemoryFunc * const ppc405_gpio_write[] = { - &ppc405_gpio_writeb, - &ppc405_gpio_writew, - &ppc405_gpio_writel, +static const MemoryRegionOps ppc405_gpio_ops = { + .old_mmio = { + .read = { ppc405_gpio_readb, ppc405_gpio_readw, ppc405_gpio_readl, }, + .write = { ppc405_gpio_writeb, ppc405_gpio_writew, ppc405_gpio_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void ppc405_gpio_reset (void *opaque) @@ -805,15 +801,13 @@ static void ppc405_gpio_reset (void *opaque) static void ppc405_gpio_init(target_phys_addr_t base) { ppc405_gpio_t *gpio; - int io; - gpio = qemu_mallocz(sizeof(ppc405_gpio_t)); + gpio = g_malloc0(sizeof(ppc405_gpio_t)); #ifdef DEBUG_GPIO printf("%s: offset " TARGET_FMT_plx "\n", __func__, base); #endif - io = cpu_register_io_memory(ppc405_gpio_read, ppc405_gpio_write, gpio, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x038, io); + memory_region_init_io(&gpio->io, &ppc405_gpio_ops, gpio, "pgio", 0x038); + memory_region_add_subregion(get_system_memory(), base, &gpio->io); qemu_register_reset(&ppc405_gpio_reset, gpio); } @@ -828,7 +822,9 @@ enum { typedef struct ppc405_ocm_t ppc405_ocm_t; struct ppc405_ocm_t { - target_ulong offset; + MemoryRegion ram; + MemoryRegion isarc_ram; + MemoryRegion dsarc_ram; uint32_t isarc; uint32_t isacntl; uint32_t dsarc; @@ -851,16 +847,15 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm, if (ocm->isacntl & 0x80000000) { /* Unmap previously assigned memory region */ printf("OCM unmap ISA %08" PRIx32 "\n", ocm->isarc); - cpu_register_physical_memory(ocm->isarc, 0x04000000, - IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), &ocm->isarc_ram); } if (isacntl & 0x80000000) { /* Map new instruction memory region */ #ifdef DEBUG_OCM printf("OCM map ISA %08" PRIx32 "\n", isarc); #endif - cpu_register_physical_memory(isarc, 0x04000000, - ocm->offset | IO_MEM_RAM); + memory_region_add_subregion(get_system_memory(), isarc, + &ocm->isarc_ram); } } if (ocm->dsarc != dsarc || @@ -872,8 +867,8 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm, #ifdef DEBUG_OCM printf("OCM unmap DSA %08" PRIx32 "\n", ocm->dsarc); #endif - cpu_register_physical_memory(ocm->dsarc, 0x04000000, - IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), + &ocm->dsarc_ram); } } if (dsacntl & 0x80000000) { @@ -883,8 +878,8 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm, #ifdef DEBUG_OCM printf("OCM map DSA %08" PRIx32 "\n", dsarc); #endif - cpu_register_physical_memory(dsarc, 0x04000000, - ocm->offset | IO_MEM_RAM); + memory_region_add_subregion(get_system_memory(), dsarc, + &ocm->dsarc_ram); } } } @@ -969,8 +964,11 @@ static void ppc405_ocm_init(CPUState *env) { ppc405_ocm_t *ocm; - ocm = qemu_mallocz(sizeof(ppc405_ocm_t)); - ocm->offset = qemu_ram_alloc(NULL, "ppc405.ocm", 4096); + ocm = g_malloc0(sizeof(ppc405_ocm_t)); + /* XXX: Size is 4096 or 0x04000000 */ + memory_region_init_ram(&ocm->isarc_ram, NULL, "ppc405.ocm", 4096); + memory_region_init_alias(&ocm->dsarc_ram, "ppc405.dsarc", &ocm->isarc_ram, + 0, 4096); qemu_register_reset(&ocm_reset, ocm); ppc_dcr_register(env, OCM0_ISARC, ocm, &dcr_read_ocm, &dcr_write_ocm); @@ -987,6 +985,7 @@ static void ppc405_ocm_init(CPUState *env) typedef struct ppc4xx_i2c_t ppc4xx_i2c_t; struct ppc4xx_i2c_t { qemu_irq irq; + MemoryRegion iomem; uint8_t mdata; uint8_t lmadr; uint8_t hmadr; @@ -1183,16 +1182,12 @@ static void ppc4xx_i2c_writel (void *opaque, ppc4xx_i2c_writeb(opaque, addr + 3, value); } -static CPUReadMemoryFunc * const i2c_read[] = { - &ppc4xx_i2c_readb, - &ppc4xx_i2c_readw, - &ppc4xx_i2c_readl, -}; - -static CPUWriteMemoryFunc * const i2c_write[] = { - &ppc4xx_i2c_writeb, - &ppc4xx_i2c_writew, - &ppc4xx_i2c_writel, +static const MemoryRegionOps i2c_ops = { + .old_mmio = { + .read = { ppc4xx_i2c_readb, ppc4xx_i2c_readw, ppc4xx_i2c_readl, }, + .write = { ppc4xx_i2c_writeb, ppc4xx_i2c_writew, ppc4xx_i2c_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void ppc4xx_i2c_reset (void *opaque) @@ -1214,16 +1209,14 @@ static void ppc4xx_i2c_reset (void *opaque) static void ppc405_i2c_init(target_phys_addr_t base, qemu_irq irq) { ppc4xx_i2c_t *i2c; - int io; - i2c = qemu_mallocz(sizeof(ppc4xx_i2c_t)); + i2c = g_malloc0(sizeof(ppc4xx_i2c_t)); i2c->irq = irq; #ifdef DEBUG_I2C printf("%s: offset " TARGET_FMT_plx "\n", __func__, base); #endif - io = cpu_register_io_memory(i2c_read, i2c_write, i2c, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x011, io); + memory_region_init_io(&i2c->iomem, &i2c_ops, i2c, "i2c", 0x011); + memory_region_add_subregion(get_system_memory(), base, &i2c->iomem); qemu_register_reset(ppc4xx_i2c_reset, i2c); } @@ -1231,6 +1224,7 @@ static void ppc405_i2c_init(target_phys_addr_t base, qemu_irq irq) /* General purpose timers */ typedef struct ppc4xx_gpt_t ppc4xx_gpt_t; struct ppc4xx_gpt_t { + MemoryRegion iomem; int64_t tb_offset; uint32_t tb_freq; struct QEMUTimer *timer; @@ -1347,7 +1341,7 @@ static uint32_t ppc4xx_gpt_readl (void *opaque, target_phys_addr_t addr) switch (addr) { case 0x00: /* Time base counter */ - ret = muldiv64(qemu_get_clock(vm_clock) + gpt->tb_offset, + ret = muldiv64(qemu_get_clock_ns(vm_clock) + gpt->tb_offset, gpt->tb_freq, get_ticks_per_sec()); break; case 0x10: @@ -1404,7 +1398,7 @@ static void ppc4xx_gpt_writel (void *opaque, case 0x00: /* Time base counter */ gpt->tb_offset = muldiv64(value, get_ticks_per_sec(), gpt->tb_freq) - - qemu_get_clock(vm_clock); + - qemu_get_clock_ns(vm_clock); ppc4xx_gpt_compute_timer(gpt); break; case 0x10: @@ -1451,16 +1445,12 @@ static void ppc4xx_gpt_writel (void *opaque, } } -static CPUReadMemoryFunc * const gpt_read[] = { - &ppc4xx_gpt_readb, - &ppc4xx_gpt_readw, - &ppc4xx_gpt_readl, -}; - -static CPUWriteMemoryFunc * const gpt_write[] = { - &ppc4xx_gpt_writeb, - &ppc4xx_gpt_writew, - &ppc4xx_gpt_writel, +static const MemoryRegionOps gpt_ops = { + .old_mmio = { + .read = { ppc4xx_gpt_readb, ppc4xx_gpt_readw, ppc4xx_gpt_readl, }, + .write = { ppc4xx_gpt_writeb, ppc4xx_gpt_writew, ppc4xx_gpt_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void ppc4xx_gpt_cb (void *opaque) @@ -1495,18 +1485,17 @@ static void ppc4xx_gpt_init(target_phys_addr_t base, qemu_irq irqs[5]) { ppc4xx_gpt_t *gpt; int i; - int io; - gpt = qemu_mallocz(sizeof(ppc4xx_gpt_t)); + gpt = g_malloc0(sizeof(ppc4xx_gpt_t)); for (i = 0; i < 5; i++) { gpt->irqs[i] = irqs[i]; } - gpt->timer = qemu_new_timer(vm_clock, &ppc4xx_gpt_cb, gpt); + gpt->timer = qemu_new_timer_ns(vm_clock, &ppc4xx_gpt_cb, gpt); #ifdef DEBUG_GPT printf("%s: offset " TARGET_FMT_plx "\n", __func__, base); #endif - io = cpu_register_io_memory(gpt_read, gpt_write, gpt, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x0d4, io); + memory_region_init_io(&gpt->iomem, &gpt_ops, gpt, "gpt", 0x0d4); + memory_region_add_subregion(get_system_memory(), base, &gpt->iomem); qemu_register_reset(ppc4xx_gpt_reset, gpt); } @@ -1728,7 +1717,7 @@ static void ppc405_mal_init(CPUState *env, qemu_irq irqs[4]) ppc40x_mal_t *mal; int i; - mal = qemu_mallocz(sizeof(ppc40x_mal_t)); + mal = g_malloc0(sizeof(ppc40x_mal_t)); for (i = 0; i < 4; i++) mal->irqs[i] = irqs[i]; qemu_register_reset(&ppc40x_mal_reset, mal); @@ -2093,7 +2082,7 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7], { ppc405cr_cpc_t *cpc; - cpc = qemu_mallocz(sizeof(ppc405cr_cpc_t)); + cpc = g_malloc0(sizeof(ppc405cr_cpc_t)); memcpy(cpc->clk_setup, clk_setup, PPC405CR_CLK_NB * sizeof(clk_setup_t)); cpc->sysclk = sysclk; @@ -2118,10 +2107,12 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7], qemu_register_reset(ppc405cr_cpc_reset, cpc); } -CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], - target_phys_addr_t ram_sizes[4], - uint32_t sysclk, qemu_irq **picp, - int do_init) +CPUState *ppc405cr_init(MemoryRegion *address_space_mem, + MemoryRegion ram_memories[4], + target_phys_addr_t ram_bases[4], + target_phys_addr_t ram_sizes[4], + uint32_t sysclk, qemu_irq **picp, + int do_init) { clk_setup_t clk_setup[PPC405CR_CLK_NB]; qemu_irq dma_irqs[4]; @@ -2139,7 +2130,7 @@ CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], /* OBP arbitrer */ ppc4xx_opba_init(0xef600600); /* Universal interrupt controller */ - irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); + irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; irqs[PPCUIC_OUTPUT_CINT] = @@ -2147,7 +2138,8 @@ CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); *picp = pic; /* SDRAM controller */ - ppc4xx_sdram_init(env, pic[14], 1, ram_bases, ram_sizes, do_init); + ppc4xx_sdram_init(env, pic[14], 1, ram_memories, + ram_bases, ram_sizes, do_init); /* External bus controller */ ppc405_ebc_init(env); /* DMA controller */ @@ -2158,12 +2150,14 @@ CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4], ppc405_dma_init(env, dma_irqs); /* Serial ports */ if (serial_hds[0] != NULL) { - serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE, - serial_hds[0], 1, 1); + serial_mm_init(address_space_mem, 0xef600300, 0, pic[0], + PPC_SERIAL_MM_BAUDBASE, serial_hds[0], + DEVICE_BIG_ENDIAN); } if (serial_hds[1] != NULL) { - serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE, - serial_hds[1], 1, 1); + serial_mm_init(address_space_mem, 0xef600400, 0, pic[1], + PPC_SERIAL_MM_BAUDBASE, serial_hds[1], + DEVICE_BIG_ENDIAN); } /* IIC controller */ ppc405_i2c_init(0xef600500, pic[2]); @@ -2430,7 +2424,7 @@ static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8], { ppc405ep_cpc_t *cpc; - cpc = qemu_mallocz(sizeof(ppc405ep_cpc_t)); + cpc = g_malloc0(sizeof(ppc405ep_cpc_t)); memcpy(cpc->clk_setup, clk_setup, PPC405EP_CLK_NB * sizeof(clk_setup_t)); cpc->jtagid = 0x20267049; @@ -2462,10 +2456,12 @@ static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8], #endif } -CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], - target_phys_addr_t ram_sizes[2], - uint32_t sysclk, qemu_irq **picp, - int do_init) +CPUState *ppc405ep_init(MemoryRegion *address_space_mem, + MemoryRegion ram_memories[2], + target_phys_addr_t ram_bases[2], + target_phys_addr_t ram_sizes[2], + uint32_t sysclk, qemu_irq **picp, + int do_init) { clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup; qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4]; @@ -2487,7 +2483,7 @@ CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], /* OBP arbitrer */ ppc4xx_opba_init(0xef600600); /* Universal interrupt controller */ - irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); + irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; irqs[PPCUIC_OUTPUT_CINT] = @@ -2496,7 +2492,8 @@ CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], *picp = pic; /* SDRAM controller */ /* XXX 405EP has no ECC interrupt */ - ppc4xx_sdram_init(env, pic[17], 2, ram_bases, ram_sizes, do_init); + ppc4xx_sdram_init(env, pic[17], 2, ram_memories, + ram_bases, ram_sizes, do_init); /* External bus controller */ ppc405_ebc_init(env); /* DMA controller */ @@ -2511,12 +2508,14 @@ CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2], ppc405_gpio_init(0xef600700); /* Serial ports */ if (serial_hds[0] != NULL) { - serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE, - serial_hds[0], 1, 1); + serial_mm_init(address_space_mem, 0xef600300, 0, pic[0], + PPC_SERIAL_MM_BAUDBASE, serial_hds[0], + DEVICE_BIG_ENDIAN); } if (serial_hds[1] != NULL) { - serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE, - serial_hds[1], 1, 1); + serial_mm_init(address_space_mem, 0xef600400, 0, pic[1], + PPC_SERIAL_MM_BAUDBASE, serial_hds[1], + DEVICE_BIG_ENDIAN); } /* OCM */ ppc405_ocm_init(env); diff --git a/hw/ppc440.c b/hw/ppc440.c index 1ed001a..cd8a95d 100644 --- a/hw/ppc440.c +++ b/hw/ppc440.c @@ -34,10 +34,12 @@ static const unsigned int ppc440ep_sdram_bank_sizes[] = { 256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0 }; -CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, - const unsigned int pci_irq_nrs[4], int do_init, - const char *cpu_model) +CPUState *ppc440ep_init(MemoryRegion *address_space_mem, ram_addr_t *ram_size, + PCIBus **pcip, const unsigned int pci_irq_nrs[4], + int do_init, const char *cpu_model) { + MemoryRegion *ram_memories + = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories)); target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS]; target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS]; CPUState *env; @@ -45,8 +47,9 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, qemu_irq *irqs; qemu_irq *pci_irqs; - if (cpu_model == NULL) - cpu_model = "405"; // XXX: should be 440EP + if (cpu_model == NULL) { + cpu_model = "440-Xilinx"; // XXX: should be 440EP + } env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to initialize CPU!\n"); @@ -56,7 +59,7 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, ppc_dcr_init(env, NULL, NULL); /* interrupt controller */ - irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); + irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; pic = ppcuic_init(env, irqs, 0x0C0, 0, 1); @@ -65,14 +68,15 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, memset(ram_bases, 0, sizeof(ram_bases)); memset(ram_sizes, 0, sizeof(ram_sizes)); *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS, + ram_memories, ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes); /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */ - ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases, - ram_sizes, do_init); + ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories, + ram_bases, ram_sizes, do_init); /* PCI */ - pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4); + pci_irqs = g_malloc(sizeof(qemu_irq) * 4); pci_irqs[0] = pic[pci_irq_nrs[0]]; pci_irqs[1] = pic[pci_irq_nrs[1]]; pci_irqs[2] = pic[pci_irq_nrs[2]]; @@ -88,12 +92,14 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN); if (serial_hds[0] != NULL) { - serial_mm_init(0xef600300, 0, pic[0], PPC_SERIAL_MM_BAUDBASE, - serial_hds[0], 1, 1); + serial_mm_init(address_space_mem, 0xef600300, 0, pic[0], + PPC_SERIAL_MM_BAUDBASE, serial_hds[0], + DEVICE_BIG_ENDIAN); } if (serial_hds[1] != NULL) { - serial_mm_init(0xef600400, 0, pic[1], PPC_SERIAL_MM_BAUDBASE, - serial_hds[1], 1, 1); + serial_mm_init(address_space_mem, 0xef600400, 0, pic[1], + PPC_SERIAL_MM_BAUDBASE, serial_hds[1], + DEVICE_BIG_ENDIAN); } return env; diff --git a/hw/ppc440.h b/hw/ppc440.h index a40f917..9c27c36 100644 --- a/hw/ppc440.h +++ b/hw/ppc440.h @@ -14,8 +14,8 @@ #include "hw.h" -CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip, - const unsigned int pci_irq_nrs[4], int do_init, - const char *cpu_model); +CPUState *ppc440ep_init(MemoryRegion *address_space, ram_addr_t *ram_size, + PCIBus **pcip, const unsigned int pci_irq_nrs[4], + int do_init, const char *cpu_model); #endif diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index 34ddf45..b734e3a 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -17,13 +17,13 @@ #include "hw.h" #include "pci.h" #include "boards.h" -#include "sysemu.h" #include "ppc440.h" #include "kvm.h" #include "kvm_ppc.h" #include "device_tree.h" #include "loader.h" #include "elf.h" +#include "exec-memory.h" #define BINARY_DEVICE_TREE_FILE "bamboo.dtb" @@ -44,13 +44,15 @@ static int bamboo_load_device_tree(target_phys_addr_t addr, char *filename; int fdt_size; void *fdt; + uint32_t tb_freq = 400000000; + uint32_t clock_freq = 400000000; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); if (!filename) { goto out; } fdt = load_device_tree(filename, &fdt_size); - qemu_free(filename); + g_free(filename); if (fdt == NULL) { goto out; } @@ -77,11 +79,21 @@ static int bamboo_load_device_tree(target_phys_addr_t addr, if (ret < 0) fprintf(stderr, "couldn't set /chosen/bootargs\n"); - if (kvm_enabled()) - kvmppc_fdt_update(fdt); + /* Copy data from the host device tree into the guest. Since the guest can + * directly access the timebase without host involvement, we must expose + * the correct frequencies. */ + if (kvm_enabled()) { + tb_freq = kvmppc_get_tbfreq(); + clock_freq = kvmppc_get_clockfreq(); + } + + qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency", + clock_freq); + qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency", + tb_freq); ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr); - qemu_free(fdt); + g_free(fdt); out: #endif @@ -97,6 +109,7 @@ static void bamboo_init(ram_addr_t ram_size, const char *cpu_model) { unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 }; + MemoryRegion *address_space_mem = get_system_memory(); PCIBus *pcibus; CPUState *env; uint64_t elf_entry; @@ -108,7 +121,8 @@ static void bamboo_init(ram_addr_t ram_size, int i; /* Setup CPU. */ - env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model); + env = ppc440ep_init(address_space_mem, &ram_size, &pcibus, + pci_irq_nrs, 1, cpu_model); if (pcibus) { /* Register network interfaces. */ @@ -156,8 +170,6 @@ static void bamboo_init(ram_addr_t ram_size, exit(1); } - cpu_synchronize_state(env); - /* Set initial guest state. */ env->gpr[1] = (16<<20) - 8; env->gpr[3] = FDT_ADDR; diff --git a/hw/ppc4xx.h b/hw/ppc4xx.h index bc4ee01..f969e44 100644 --- a/hw/ppc4xx.h +++ b/hw/ppc4xx.h @@ -42,11 +42,13 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs, uint32_t dcr_base, int has_ssr, int has_vr); ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks, + MemoryRegion ram_memories[], target_phys_addr_t ram_bases[], target_phys_addr_t ram_sizes[], const unsigned int sdram_bank_sizes[]); void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, + MemoryRegion ram_memories[], target_phys_addr_t *ram_bases, target_phys_addr_t *ram_sizes, int do_init); diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c index 5f581fe..d18caa4 100644 --- a/hw/ppc4xx_devs.c +++ b/hw/ppc4xx_devs.c @@ -24,8 +24,8 @@ #include "hw.h" #include "ppc.h" #include "ppc4xx.h" -#include "sysemu.h" #include "qemu-log.h" +#include "exec-memory.h" //#define DEBUG_MMIO //#define DEBUG_UNASSIGNED @@ -39,7 +39,7 @@ #endif /*****************************************************************************/ -/* Generic PowerPC 4xx processor instanciation */ +/* Generic PowerPC 4xx processor instantiation */ CPUState *ppc4xx_init (const char *cpu_model, clk_setup_t *cpu_clk, clk_setup_t *tb_clk, uint32_t sysclk) @@ -56,7 +56,7 @@ CPUState *ppc4xx_init (const char *cpu_model, cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */ cpu_clk->opaque = env; /* Set time-base frequency to sysclk */ - tb_clk->cb = ppc_emb_timers_init(env, sysclk, PPC_INTERRUPT_PIT); + tb_clk->cb = ppc_40x_timers_init(env, sysclk, PPC_INTERRUPT_PIT); tb_clk->opaque = env; ppc_dcr_init(env, NULL, NULL); /* Register qemu callbacks */ @@ -294,7 +294,7 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs, ppcuic_t *uic; int i; - uic = qemu_mallocz(sizeof(ppcuic_t)); + uic = g_malloc0(sizeof(ppcuic_t)); uic->dcr_base = dcr_base; uic->irqs = irqs; if (has_vr) @@ -314,6 +314,8 @@ typedef struct ppc4xx_sdram_t ppc4xx_sdram_t; struct ppc4xx_sdram_t { uint32_t addr; int nbanks; + MemoryRegion containers[4]; /* used for clipping */ + MemoryRegion *ram_memories; target_phys_addr_t ram_bases[4]; target_phys_addr_t ram_sizes[4]; uint32_t besr0; @@ -396,16 +398,22 @@ static target_ulong sdram_size (uint32_t bcr) return size; } -static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled) +static void sdram_set_bcr(ppc4xx_sdram_t *sdram, + uint32_t *bcrp, uint32_t bcr, int enabled) { + unsigned n = bcrp - sdram->bcr; + if (*bcrp & 0x00000001) { /* Unmap RAM */ #ifdef DEBUG_SDRAM printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n", __func__, sdram_base(*bcrp), sdram_size(*bcrp)); #endif - cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp), - IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), + &sdram->containers[n]); + memory_region_del_subregion(&sdram->containers[n], + &sdram->ram_memories[n]); + memory_region_destroy(&sdram->containers[n]); } *bcrp = bcr & 0xFFDEE001; if (enabled && (bcr & 0x00000001)) { @@ -413,8 +421,13 @@ static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled) printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n", __func__, sdram_base(bcr), sdram_size(bcr)); #endif - cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr), - sdram_base(bcr) | IO_MEM_RAM); + memory_region_init(&sdram->containers[n], "sdram-containers", + sdram_size(bcr)); + memory_region_add_subregion(&sdram->containers[n], 0, + &sdram->ram_memories[n]); + memory_region_add_subregion(get_system_memory(), + sdram_base(bcr), + &sdram->containers[n]); } } @@ -424,11 +437,12 @@ static void sdram_map_bcr (ppc4xx_sdram_t *sdram) for (i = 0; i < sdram->nbanks; i++) { if (sdram->ram_sizes[i] != 0) { - sdram_set_bcr(&sdram->bcr[i], + sdram_set_bcr(sdram, + &sdram->bcr[i], sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]), 1); } else { - sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0); + sdram_set_bcr(sdram, &sdram->bcr[i], 0x00000000, 0); } } } @@ -442,9 +456,8 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram) printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n", __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i])); #endif - cpu_register_physical_memory(sdram_base(sdram->bcr[i]), - sdram_size(sdram->bcr[i]), - IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), + &sdram->ram_memories[i]); } } @@ -569,16 +582,16 @@ static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val) sdram->pmit = (val & 0xF8000000) | 0x07C00000; break; case 0x40: /* SDRAM_B0CR */ - sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[0], val, sdram->cfg & 0x80000000); break; case 0x44: /* SDRAM_B1CR */ - sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[1], val, sdram->cfg & 0x80000000); break; case 0x48: /* SDRAM_B2CR */ - sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[2], val, sdram->cfg & 0x80000000); break; case 0x4C: /* SDRAM_B3CR */ - sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000); + sdram_set_bcr(sdram, &sdram->bcr[3], val, sdram->cfg & 0x80000000); break; case 0x80: /* SDRAM_TR */ sdram->tr = val & 0x018FC01F; @@ -622,15 +635,17 @@ static void sdram_reset (void *opaque) } void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, + MemoryRegion *ram_memories, target_phys_addr_t *ram_bases, target_phys_addr_t *ram_sizes, int do_init) { ppc4xx_sdram_t *sdram; - sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t)); + sdram = g_malloc0(sizeof(ppc4xx_sdram_t)); sdram->irq = irq; sdram->nbanks = nbanks; + sdram->ram_memories = ram_memories; memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t)); memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(target_phys_addr_t)); @@ -654,11 +669,13 @@ void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks, * must be one of a small set of sizes. The number of banks and the supported * sizes varies by SoC. */ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks, + MemoryRegion ram_memories[], target_phys_addr_t ram_bases[], target_phys_addr_t ram_sizes[], const unsigned int sdram_bank_sizes[]) { ram_addr_t size_left = ram_size; + ram_addr_t base = 0; int i; int j; @@ -669,8 +686,10 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks, if (bank_size <= size_left) { char name[32]; snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); - ram_bases[i] = qemu_ram_alloc(NULL, name, bank_size); + memory_region_init_ram(&ram_memories[i], NULL, name, bank_size); + ram_bases[i] = base; ram_sizes[i] = bank_size; + base += ram_size; size_left -= bank_size; break; } diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c index f62f1f9..339b38e 100644 --- a/hw/ppc4xx_pci.c +++ b/hw/ppc4xx_pci.c @@ -24,6 +24,7 @@ #include "ppc4xx.h" #include "pci.h" #include "pci_host.h" +#include "exec-memory.h" #undef DEBUG #ifdef DEBUG @@ -285,50 +286,48 @@ static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pci_irqs[irq_num], level); } -static void ppc4xx_pci_save(QEMUFile *f, void *opaque) -{ - PPC4xxPCIState *controller = opaque; - int i; - - pci_device_save(controller->pci_dev, f); - - for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) { - qemu_put_be32s(f, &controller->pmm[i].la); - qemu_put_be32s(f, &controller->pmm[i].ma); - qemu_put_be32s(f, &controller->pmm[i].pcila); - qemu_put_be32s(f, &controller->pmm[i].pciha); - } - - for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) { - qemu_put_be32s(f, &controller->ptm[i].ms); - qemu_put_be32s(f, &controller->ptm[i].la); +static const VMStateDescription vmstate_pci_master_map = { + .name = "pci_master_map", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(la, struct PCIMasterMap), + VMSTATE_UINT32(ma, struct PCIMasterMap), + VMSTATE_UINT32(pcila, struct PCIMasterMap), + VMSTATE_UINT32(pciha, struct PCIMasterMap), + VMSTATE_END_OF_LIST() } -} - -static int ppc4xx_pci_load(QEMUFile *f, void *opaque, int version_id) -{ - PPC4xxPCIState *controller = opaque; - int i; - - if (version_id != 1) - return -EINVAL; - - pci_device_load(controller->pci_dev, f); +}; - for (i = 0; i < PPC4xx_PCI_NR_PMMS; i++) { - qemu_get_be32s(f, &controller->pmm[i].la); - qemu_get_be32s(f, &controller->pmm[i].ma); - qemu_get_be32s(f, &controller->pmm[i].pcila); - qemu_get_be32s(f, &controller->pmm[i].pciha); +static const VMStateDescription vmstate_pci_target_map = { + .name = "pci_target_map", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(ms, struct PCITargetMap), + VMSTATE_UINT32(la, struct PCITargetMap), + VMSTATE_END_OF_LIST() } +}; - for (i = 0; i < PPC4xx_PCI_NR_PTMS; i++) { - qemu_get_be32s(f, &controller->ptm[i].ms); - qemu_get_be32s(f, &controller->ptm[i].la); +static const VMStateDescription vmstate_ppc4xx_pci = { + .name = "ppc4xx_pci", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState), + VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1, + vmstate_pci_master_map, + struct PCIMasterMap), + VMSTATE_STRUCT_ARRAY(ptm, PPC4xxPCIState, PPC4xx_PCI_NR_PTMS, 1, + vmstate_pci_target_map, + struct PCITargetMap), + VMSTATE_END_OF_LIST() } - - return 0; -} +}; /* XXX Interrupt acknowledge cycles not supported. */ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], @@ -342,12 +341,15 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], static int ppc4xx_pci_id; uint8_t *pci_conf; - controller = qemu_mallocz(sizeof(PPC4xxPCIState)); + controller = g_malloc0(sizeof(PPC4xxPCIState)); controller->pci_state.bus = pci_register_bus(NULL, "pci", ppc4xx_pci_set_irq, ppc4xx_pci_map_irq, - pci_irqs, 0, 4); + pci_irqs, + get_system_memory(), + get_system_io(), + 0, 4); controller->pci_dev = pci_register_device(controller->pci_state.bus, "host bridge", sizeof(PCIDevice), @@ -366,10 +368,12 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index); /* CFGDATA */ - index = pci_host_data_register_mmio(&controller->pci_state, 1); - if (index < 0) - goto free; - cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index); + memory_region_init_io(&controller->pci_state.data_mem, + &pci_host_data_be_ops, + &controller->pci_state, "pci-conf-data", 4); + memory_region_add_subregion(get_system_memory(), + config_space + PCIC0_CFGDATA, + &controller->pci_state.data_mem); /* Internal registers */ index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller, @@ -381,13 +385,13 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4], qemu_register_reset(ppc4xx_pci_reset, controller); /* XXX load/save code not tested. */ - register_savevm(&controller->pci_dev->qdev, "ppc4xx_pci", ppc4xx_pci_id++, - 1, ppc4xx_pci_save, ppc4xx_pci_load, controller); + vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++, + &vmstate_ppc4xx_pci, controller); return controller->pci_state.bus; free: printf("%s error\n", __func__); - qemu_free(controller); + g_free(controller); return NULL; } diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h index ea87593..af75e45 100644 --- a/hw/ppc_mac.h +++ b/hw/ppc_mac.h @@ -25,6 +25,8 @@ #if !defined(__PPC_MAC_H__) #define __PPC_MAC_H__ +#include "memory.h" + /* SMP is not enabled, for now */ #define MAX_CPUS 1 @@ -35,79 +37,44 @@ #define PROM_ADDR 0xfff00000 #define KERNEL_LOAD_ADDR 0x01000000 -#define CMDLINE_ADDR 0x027ff000 -#define INITRD_LOAD_ADDR 0x02800000 +#define KERNEL_GAP 0x00100000 #define ESCC_CLOCK 3686400 /* Cuda */ -void cuda_init (int *cuda_mem_index, qemu_irq irq); +void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq); /* MacIO */ -void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index, - int dbdma_mem_index, int cuda_mem_index, void *nvram, - int nb_ide, int *ide_mem_index, int escc_mem_index); +void macio_init (PCIBus *bus, int device_id, int is_oldworld, + MemoryRegion *pic_mem, MemoryRegion *dbdma_mem, + MemoryRegion *cuda_mem, void *nvram, + int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem); /* Heathrow PIC */ -qemu_irq *heathrow_pic_init(int *pmem_index, +qemu_irq *heathrow_pic_init(MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs); /* Grackle PCI */ -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic); +PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); /* UniNorth PCI */ -PCIBus *pci_pmac_init(qemu_irq *pic); -PCIBus *pci_pmac_u3_init(qemu_irq *pic); +PCIBus *pci_pmac_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); +PCIBus *pci_pmac_u3_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); /* Mac NVRAM */ typedef struct MacIONVRAMState MacIONVRAMState; -MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size, +MacIONVRAMState *macio_nvram_init (target_phys_addr_t size, unsigned int it_shift); -void macio_nvram_map (void *opaque, target_phys_addr_t mem_base); +void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar, + target_phys_addr_t mem_base); void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len); uint32_t macio_nvram_read (void *opaque, uint32_t addr); void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val); - -/* adb.c */ - -#define MAX_ADB_DEVICES 16 - -#define ADB_MAX_OUT_LEN 16 - -typedef struct ADBDevice ADBDevice; - -/* buf = NULL means polling */ -typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out, - const uint8_t *buf, int len); -typedef int ADBDeviceReset(ADBDevice *d); - -struct ADBDevice { - struct ADBBusState *bus; - int devaddr; - int handler; - ADBDeviceRequest *devreq; - ADBDeviceReset *devreset; - void *opaque; -}; - -typedef struct ADBBusState { - ADBDevice devices[MAX_ADB_DEVICES]; - int nb_devices; - int poll_index; -} ADBBusState; - -int adb_request(ADBBusState *s, uint8_t *buf_out, - const uint8_t *buf, int len); -int adb_poll(ADBBusState *s, uint8_t *buf_out); - -ADBDevice *adb_register_device(ADBBusState *s, int devaddr, - ADBDeviceRequest *devreq, - ADBDeviceReset *devreset, - void *opaque); -void adb_kbd_init(ADBBusState *bus); -void adb_mouse_init(ADBBusState *bus); - -extern ADBBusState adb_bus; - #endif /* !defined(__PPC_MAC_H__) */ diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index b9245f0..8c84f9e 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -49,6 +49,7 @@ #include "hw.h" #include "ppc.h" #include "ppc_mac.h" +#include "adb.h" #include "mac_dbdma.h" #include "nvram.h" #include "pc.h" @@ -67,6 +68,7 @@ #include "kvm_ppc.h" #include "hw/usb.h" #include "blockdev.h" +#include "exec-memory.h" #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf0000510 @@ -82,12 +84,13 @@ #endif /* UniN device */ -static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +static void unin_write(void *opaque, target_phys_addr_t addr, uint64_t value, + unsigned size) { - UNIN_DPRINTF("writel addr " TARGET_FMT_plx " val %x\n", addr, value); + UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value); } -static uint32_t unin_readl (void *opaque, target_phys_addr_t addr) +static uint64_t unin_read(void *opaque, target_phys_addr_t addr, unsigned size) { uint32_t value; @@ -97,16 +100,10 @@ static uint32_t unin_readl (void *opaque, target_phys_addr_t addr) return value; } -static CPUWriteMemoryFunc * const unin_write[] = { - &unin_writel, - &unin_writel, - &unin_writel, -}; - -static CPUReadMemoryFunc * const unin_read[] = { - &unin_readl, - &unin_readl, - &unin_readl, +static const MemoryRegionOps unin_ops = { + .read = unin_read, + .write = unin_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int fw_cfg_boot_set(void *opaque, const char *boot_device) @@ -120,6 +117,11 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr) return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR; } +static target_phys_addr_t round_page(target_phys_addr_t addr) +{ + return (addr + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; +} + /* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init (ram_addr_t ram_size, const char *boot_device, @@ -131,17 +133,17 @@ static void ppc_core99_init (ram_addr_t ram_size, CPUState *env = NULL; char *filename; qemu_irq *pic, **openpic_irqs; - int unin_memory; + MemoryRegion *unin_memory = g_new(MemoryRegion, 1); int linux_boot, i; - ram_addr_t ram_offset, bios_offset; - uint32_t kernel_base, initrd_base; + MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); + target_phys_addr_t kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; - int nvram_mem_index; int bios_size; - int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index; - int ide_mem_index[3]; + MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem; + MemoryRegion *escc_bar = g_new(MemoryRegion, 1); + MemoryRegion *ide_mem[3]; int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; @@ -169,22 +171,23 @@ static void ppc_core99_init (ram_addr_t ram_size, } /* allocate RAM */ - ram_offset = qemu_ram_alloc(NULL, "ppc_core99.ram", ram_size); - cpu_register_physical_memory(0, ram_size, ram_offset); + memory_region_init_ram(ram, NULL, "ppc_core99.ram", ram_size); + memory_region_add_subregion(get_system_memory(), 0, ram); /* allocate and load BIOS */ - bios_offset = qemu_ram_alloc(NULL, "ppc_core99.bios", BIOS_SIZE); + memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); - qemu_free(filename); + g_free(filename); } else { bios_size = -1; } @@ -220,7 +223,7 @@ static void ppc_core99_init (ram_addr_t ram_size, } /* load initrd */ if (initrd_filename) { - initrd_base = INITRD_LOAD_ADDR; + initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { @@ -228,9 +231,11 @@ static void ppc_core99_init (ram_addr_t ram_size, initrd_filename); exit(1); } + cmdline_base = round_page(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; + cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { @@ -254,19 +259,16 @@ static void ppc_core99_init (ram_addr_t ram_size, } } - isa_mem_base = 0x80000000; - /* Register 8 MB of ISA IO space */ isa_mmio_init(0xf2000000, 0x00800000); /* UniN init */ - unin_memory = cpu_register_io_memory(unin_read, unin_write, NULL, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory); + memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000); + memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory); - openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *)); + openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); openpic_irqs[0] = - qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); + g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); for (i = 0; i < smp_cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins * and PowerPC input pins @@ -307,51 +309,45 @@ static void ppc_core99_init (ram_addr_t ram_size, exit(1); } } - pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL); + pic = openpic_init(NULL, &pic_mem, smp_cpus, openpic_irqs, NULL); if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ - pci_bus = pci_pmac_u3_init(pic); + pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99_U3; } else { - pci_bus = pci_pmac_init(pic); + pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99; } /* init basic PC hardware */ pci_vga_init(pci_bus); - escc_mem_index = escc_init(0x80013000, pic[0x25], pic[0x24], - serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); + escc_mem = escc_init(0, pic[0x25], pic[0x24], + serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); + memory_region_init_alias(escc_bar, "escc-bar", + escc_mem, 0, memory_region_size(escc_mem)); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } - dbdma = DBDMA_init(&dbdma_mem_index); + ide_drive_get(hd, MAX_IDE_BUS); + dbdma = DBDMA_init(&dbdma_mem); /* We only emulate 2 out of 3 IDE controllers for now */ - ide_mem_index[0] = -1; - hd[0] = drive_get(IF_IDE, 0, 0); - hd[1] = drive_get(IF_IDE, 0, 1); - ide_mem_index[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]); - hd[0] = drive_get(IF_IDE, 1, 0); - hd[1] = drive_get(IF_IDE, 1, 1); - ide_mem_index[2] = pmac_ide_init(hd, pic[0x0e], dbdma, 0x1a, pic[0x02]); + ide_mem[0] = NULL; + ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]); + ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]); /* cuda also initialize ADB */ if (machine_arch == ARCH_MAC99_U3) { usb_enabled = 1; } - cuda_init(&cuda_mem_index, pic[0x19]); + cuda_init(&cuda_mem, pic[0x19]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); - macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index, - dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index, - escc_mem_index); + macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem, + dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); @@ -368,9 +364,9 @@ static void ppc_core99_init (ram_addr_t ram_size, graphic_depth = 15; /* The NewWorld NVRAM is not located in the MacIO device */ - nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 1); + nvr = macio_nvram_init(0x2000, 1); pmac_format_nvram_partition(nvr, 0x2000); - macio_nvram_map(nvr, 0xFFF04000); + macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000); /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); @@ -380,8 +376,8 @@ static void ppc_core99_init (ram_addr_t ram_size, fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { - fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR); - pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); + pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } @@ -399,7 +395,7 @@ static void ppc_core99_init (ram_addr_t ram_size, uint8_t *hypercall; fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); - hypercall = qemu_malloc(16); + hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 8a4e088..aac3526 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -26,6 +26,7 @@ #include "hw.h" #include "ppc.h" #include "ppc_mac.h" +#include "adb.h" #include "mac_dbdma.h" #include "nvram.h" #include "pc.h" @@ -43,6 +44,7 @@ #include "kvm.h" #include "kvm_ppc.h" #include "blockdev.h" +#include "exec-memory.h" #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf0000510 @@ -59,6 +61,11 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr) return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR; } +static target_phys_addr_t round_page(target_phys_addr_t addr) +{ + return (addr + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; +} + static void ppc_heathrow_init (ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, @@ -66,18 +73,20 @@ static void ppc_heathrow_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { + MemoryRegion *sysmem = get_system_memory(); CPUState *env = NULL; char *filename; qemu_irq *pic, **heathrow_irqs; int linux_boot, i; - ram_addr_t ram_offset, bios_offset; - uint32_t kernel_base, initrd_base; + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *bios = g_new(MemoryRegion, 1); + uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; int bios_size; - int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index; - int escc_mem_index, ide_mem_index[2]; + MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem; + MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2]; uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; @@ -107,21 +116,22 @@ static void ppc_heathrow_init (ram_addr_t ram_size, exit(1); } - ram_offset = qemu_ram_alloc(NULL, "ppc_heathrow.ram", ram_size); - cpu_register_physical_memory(0, ram_size, ram_offset); + memory_region_init_ram(ram, NULL, "ppc_heathrow.ram", ram_size); + memory_region_add_subregion(sysmem, 0, ram); /* allocate and load BIOS */ - bios_offset = qemu_ram_alloc(NULL, "ppc_heathrow.bios", BIOS_SIZE); + memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(sysmem, PROM_ADDR, bios); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); - qemu_free(filename); + g_free(filename); } else { bios_size = -1; } @@ -157,7 +167,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size, } /* load initrd */ if (initrd_filename) { - initrd_base = INITRD_LOAD_ADDR; + initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { @@ -165,9 +175,11 @@ static void ppc_heathrow_init (ram_addr_t ram_size, initrd_filename); exit(1); } + cmdline_base = round_page(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; + cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { @@ -199,15 +211,13 @@ static void ppc_heathrow_init (ram_addr_t ram_size, } } - isa_mem_base = 0x80000000; - /* Register 2 MB of ISA IO space */ isa_mmio_init(0xfe000000, 0x00200000); /* XXX: we register only 1 output pin for heathrow PIC */ - heathrow_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *)); + heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); heathrow_irqs[0] = - qemu_mallocz(smp_cpus * sizeof(qemu_irq) * 1); + g_malloc0(smp_cpus * sizeof(qemu_irq) * 1); /* Connect the heathrow PIC outputs to the 6xx bus */ for (i = 0; i < smp_cpus; i++) { switch (PPC_INPUT(env)) { @@ -225,47 +235,45 @@ static void ppc_heathrow_init (ram_addr_t ram_size, if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { hw_error("Only 6xx bus is supported on heathrow machine\n"); } - pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs); - pci_bus = pci_grackle_init(0xfec00000, pic); + pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs); + pci_bus = pci_grackle_init(0xfec00000, pic, + get_system_memory(), + get_system_io()); pci_vga_init(pci_bus); - escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0], + escc_mem = escc_init(0, pic[0x0f], pic[0x10], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); + memory_region_init_alias(escc_bar, "escc-bar", + escc_mem, 0, memory_region_size(escc_mem)); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } + ide_drive_get(hd, MAX_IDE_BUS); /* First IDE channel is a MAC IDE on the MacIO bus */ - hd[0] = drive_get(IF_IDE, 0, 0); - hd[1] = drive_get(IF_IDE, 0, 1); - dbdma = DBDMA_init(&dbdma_mem_index); - ide_mem_index[0] = -1; - ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]); + dbdma = DBDMA_init(&dbdma_mem); + ide_mem[0] = NULL; + ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]); /* Second IDE channel is a CMD646 on the PCI bus */ - hd[0] = drive_get(IF_IDE, 1, 0); - hd[1] = drive_get(IF_IDE, 1, 1); + hd[0] = hd[MAX_IDE_DEVS]; + hd[1] = hd[MAX_IDE_DEVS + 1]; hd[3] = hd[2] = NULL; pci_cmd646_ide_init(pci_bus, hd, 0); /* cuda also initialize ADB */ - cuda_init(&cuda_mem_index, pic[0x12]); + cuda_init(&cuda_mem, pic[0x12]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); - nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 4); + nvr = macio_nvram_init(0x2000, 4); pmac_format_nvram_partition(nvr, 0x2000); - macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index, - dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index, - escc_mem_index); + macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem, + dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); @@ -283,8 +291,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size, fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { - fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR); - pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); + pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } @@ -302,7 +310,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size, uint8_t *hypercall; fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); - hypercall = qemu_malloc(16); + hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index 6b22122..f22d5b9 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -38,6 +38,7 @@ #include "loader.h" #include "mc146818rtc.h" #include "blockdev.h" +#include "exec-memory.h" //#define HARD_DEBUG_PPC_IO //#define DEBUG_PPC_IO @@ -82,7 +83,7 @@ static const int ide_irq[2] = { 13, 13 }; static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 }; static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; -//static PITState *pit; +//static ISADevice *pit; /* ISA IO ports bridge */ #define PPC_IO_BASE 0x80000000 @@ -105,7 +106,7 @@ static uint32_t speaker_ioport_read (void *opaque, uint32_t addr) { #if 0 int out; - out = pit_get_out(pit, 2, qemu_get_clock(vm_clock)); + out = pit_get_out(pit, 2, qemu_get_clock_ns(vm_clock)); dummy_refresh_clock ^= 1; return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) | (dummy_refresh_clock << 4); @@ -115,21 +116,22 @@ static uint32_t speaker_ioport_read (void *opaque, uint32_t addr) /* PCI intack register */ /* Read-only register (?) */ -static void _PPC_intack_write (void *opaque, - target_phys_addr_t addr, uint32_t value) +static void PPC_intack_write (void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { #if 0 - printf("%s: 0x" TARGET_FMT_plx " => 0x%08" PRIx32 "\n", __func__, addr, + printf("%s: 0x" TARGET_FMT_plx " => 0x%08" PRIx64 "\n", __func__, addr, value); #endif } -static inline uint32_t _PPC_intack_read(target_phys_addr_t addr) +static uint64_t PPC_intack_read(void *opaque, target_phys_addr_t addr, + unsigned size) { uint32_t retval = 0; if ((addr & 0xf) == 0) - retval = pic_intack_read(isa_pic); + retval = pic_read_irq(isa_pic); #if 0 printf("%s: 0x" TARGET_FMT_plx " <= %08" PRIx32 "\n", __func__, addr, retval); @@ -138,31 +140,10 @@ static inline uint32_t _PPC_intack_read(target_phys_addr_t addr) return retval; } -static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr) -{ - return _PPC_intack_read(addr); -} - -static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr) -{ - return _PPC_intack_read(addr); -} - -static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr) -{ - return _PPC_intack_read(addr); -} - -static CPUWriteMemoryFunc * const PPC_intack_write[] = { - &_PPC_intack_write, - &_PPC_intack_write, - &_PPC_intack_write, -}; - -static CPUReadMemoryFunc * const PPC_intack_read[] = { - &PPC_intack_readb, - &PPC_intack_readw, - &PPC_intack_readl, +static const MemoryRegionOps PPC_intack_ops = { + .read = PPC_intack_read, + .write = PPC_intack_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; /* PowerPC control and status registers */ @@ -243,17 +224,14 @@ static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr) return retval; } -static CPUWriteMemoryFunc * const PPC_XCSR_write[] = { - &PPC_XCSR_writeb, - &PPC_XCSR_writew, - &PPC_XCSR_writel, +static const MemoryRegionOps PPC_XCSR_ops = { + .old_mmio = { + .read = { PPC_XCSR_readb, PPC_XCSR_readw, PPC_XCSR_readl, }, + .write = { PPC_XCSR_writeb, PPC_XCSR_writew, PPC_XCSR_writel, }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static CPUReadMemoryFunc * const PPC_XCSR_read[] = { - &PPC_XCSR_readb, - &PPC_XCSR_readw, - &PPC_XCSR_readl, -}; #endif /* Fake super-io ports for PREP platform (Intel 82378ZB) */ @@ -502,16 +480,12 @@ static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr) return ret; } -static CPUWriteMemoryFunc * const PPC_prep_io_write[] = { - &PPC_prep_io_writeb, - &PPC_prep_io_writew, - &PPC_prep_io_writel, -}; - -static CPUReadMemoryFunc * const PPC_prep_io_read[] = { - &PPC_prep_io_readb, - &PPC_prep_io_readw, - &PPC_prep_io_readl, +static const MemoryRegionOps PPC_prep_io_ops = { + .old_mmio = { + .read = { PPC_prep_io_readb, PPC_prep_io_readw, PPC_prep_io_readl }, + .write = { PPC_prep_io_writeb, PPC_prep_io_writew, PPC_prep_io_writel }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; #define NVRAM_SIZE 0x2000 @@ -533,13 +507,19 @@ static void ppc_prep_init (ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { + MemoryRegion *sysmem = get_system_memory(); CPUState *env = NULL; char *filename; nvram_t nvram; M48t59State *m48t59; - int PPC_io_memory; + MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1); + MemoryRegion *intack = g_new(MemoryRegion, 1); +#if 0 + MemoryRegion *xcsr = g_new(MemoryRegion, 1); +#endif int linux_boot, i, nb_nics1, bios_size; - ram_addr_t ram_offset, bios_offset; + MemoryRegion *ram = g_new(MemoryRegion, 1); + MemoryRegion *bios = g_new(MemoryRegion, 1); uint32_t kernel_base, initrd_base; long kernel_size, initrd_size; PCIBus *pci_bus; @@ -549,7 +529,7 @@ static void ppc_prep_init (ram_addr_t ram_size, DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; - sysctrl = qemu_mallocz(sizeof(sysctrl_t)); + sysctrl = g_malloc0(sizeof(sysctrl_t)); linux_boot = (kernel_filename != NULL); @@ -573,11 +553,11 @@ static void ppc_prep_init (ram_addr_t ram_size, } /* allocate RAM */ - ram_offset = qemu_ram_alloc(NULL, "ppc_prep.ram", ram_size); - cpu_register_physical_memory(0, ram_size, ram_offset); + memory_region_init_ram(ram, NULL, "ppc_prep.ram", ram_size); + memory_region_add_subregion(sysmem, 0, ram); /* allocate and load BIOS */ - bios_offset = qemu_ram_alloc(NULL, "ppc_prep.bios", BIOS_SIZE); + memory_region_init_ram(bios, NULL, "ppc_prep.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); @@ -590,15 +570,15 @@ static void ppc_prep_init (ram_addr_t ram_size, target_phys_addr_t bios_addr; bios_size = (bios_size + 0xfff) & ~0xfff; bios_addr = (uint32_t)(-bios_size); - cpu_register_physical_memory(bios_addr, bios_size, - bios_offset | IO_MEM_ROM); + memory_region_set_readonly(bios, true); + memory_region_add_subregion(sysmem, bios_addr, bios); bios_size = load_image_targphys(filename, bios_addr, bios_size); } if (bios_size < 0 || bios_size > BIOS_SIZE) { hw_error("qemu: could not load PPC PREP bios '%s'\n", bios_name); } if (filename) { - qemu_free(filename); + g_free(filename); } if (linux_boot) { @@ -647,22 +627,21 @@ static void ppc_prep_init (ram_addr_t ram_size, if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { hw_error("Only 6xx bus is supported on PREP machine\n"); } - i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]); - pci_bus = pci_prep_init(i8259); /* Hmm, prep has no pci-isa bridge ??? */ - isa_bus_new(NULL); + isa_bus_new(NULL, get_system_io()); + i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]); + pci_bus = pci_prep_init(i8259, get_system_memory(), get_system_io()); isa_bus_irqs(i8259); // pci_bus = i440fx_init(); /* Register 8 MB of ISA IO space (needed for non-contiguous map) */ - PPC_io_memory = cpu_register_io_memory(PPC_prep_io_read, - PPC_prep_io_write, sysctrl, - DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory); + memory_region_init_io(PPC_io_memory, &PPC_prep_io_ops, sysctrl, + "ppc-io", 0x00800000); + memory_region_add_subregion(sysmem, 0x80000000, PPC_io_memory); /* init basic PC hardware */ pci_vga_init(pci_bus); // openpic = openpic_init(0x00000000, 0xF0000000, 1); - // pit = pit_init(0x40, i8259[0]); + // pit = pit_init(0x40, 0); rtc_init(2000, NULL); if (serial_hds[0]) @@ -672,7 +651,7 @@ static void ppc_prep_init (ram_addr_t ram_size, nb_nics1 = NE2000_NB_MAX; for(i = 0; i < nb_nics1; i++) { if (nd_table[i].model == NULL) { - nd_table[i].model = qemu_strdup("ne2k_isa"); + nd_table[i].model = g_strdup("ne2k_isa"); } if (strcmp(nd_table[i].model, "ne2k_isa") == 0) { isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]); @@ -681,15 +660,7 @@ static void ppc_prep_init (ram_addr_t ram_size, } } - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } - - for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { - hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); - } - + ide_drive_get(hd, MAX_IDE_BUS); for(i = 0; i < MAX_IDE_BUS; i++) { isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[2 * i], @@ -720,15 +691,12 @@ static void ppc_prep_init (ram_addr_t ram_size, register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl); register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl); /* PCI intack location */ - PPC_io_memory = cpu_register_io_memory(PPC_intack_read, - PPC_intack_write, NULL, - DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory); + memory_region_init_io(intack, &PPC_intack_ops, NULL, "ppc-intack", 4); + memory_region_add_subregion(sysmem, 0xBFFFFFF0, intack); /* PowerPC control and status register group */ #if 0 - PPC_io_memory = cpu_register_io_memory(PPC_XCSR_read, PPC_XCSR_write, - NULL, DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory); + memory_region_init_io(xcsr, &PPC_XCSR_ops, NULL, "ppc-xcsr", 0x1000); + memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr); #endif if (usb_enabled) { diff --git a/hw/ppce500.h b/hw/ppce500.h deleted file mode 100644 index 24d49bb..0000000 --- a/hw/ppce500.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * QEMU PowerPC E500 emulation shared definitions - * - * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved. - * - * Author: Yu Liu, - * - * This file is derived from hw/ppc440.h - * the copyright for that material belongs to the original owners. - * - * This 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. - */ - -#if !defined(PPC_E500_H) -#define PPC_E500_H - -PCIBus *ppce500_pci_init(qemu_irq *pic, target_phys_addr_t registers); - -#endif /* !defined(PPC_E500_H) */ diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c index b7670ae..51b6abd 100644 --- a/hw/ppce500_mpc8544ds.c +++ b/hw/ppce500_mpc8544ds.c @@ -14,8 +14,6 @@ * (at your option) any later version. */ -#include - #include "config.h" #include "qemu-common.h" #include "net.h" @@ -28,9 +26,11 @@ #include "kvm_ppc.h" #include "device_tree.h" #include "openpic.h" -#include "ppce500.h" +#include "ppc.h" #include "loader.h" #include "elf.h" +#include "sysbus.h" +#include "exec-memory.h" #define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb" #define UIMAGE_LOAD_BASE 0 @@ -49,50 +49,39 @@ #define MPC8544_PCI_REGS_SIZE 0x1000 #define MPC8544_PCI_IO 0xE1000000 #define MPC8544_PCI_IOLEN 0x10000 +#define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + 0xe0000) +#define MPC8544_SPIN_BASE 0xEF000000 -#ifdef CONFIG_FDT -static int mpc8544_copy_soc_cell(void *fdt, const char *node, const char *prop) +struct boot_info { - uint32_t cell; - int ret; - - ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell)); - if (ret < 0) { - fprintf(stderr, "couldn't read host %s/%s\n", node, prop); - goto out; - } - - ret = qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0", - prop, cell); - if (ret < 0) { - fprintf(stderr, "couldn't set guest /cpus/PowerPC,8544@0/%s\n", prop); - goto out; - } - -out: - return ret; -} -#endif + uint32_t dt_base; + uint32_t entry; +}; -static int mpc8544_load_device_tree(target_phys_addr_t addr, - uint32_t ramsize, - target_phys_addr_t initrd_base, - target_phys_addr_t initrd_size, - const char *kernel_cmdline) +static int mpc8544_load_device_tree(CPUState *env, + target_phys_addr_t addr, + uint32_t ramsize, + target_phys_addr_t initrd_base, + target_phys_addr_t initrd_size, + const char *kernel_cmdline) { int ret = -1; #ifdef CONFIG_FDT - uint32_t mem_reg_property[] = {0, ramsize}; + uint32_t mem_reg_property[] = {0, cpu_to_be32(ramsize)}; char *filename; int fdt_size; void *fdt; + uint8_t hypercall[16]; + uint32_t clock_freq = 400000000; + uint32_t tb_freq = 400000000; + int i; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); if (!filename) { goto out; } fdt = load_device_tree(filename, &fdt_size); - qemu_free(filename); + g_free(filename); if (fdt == NULL) { goto out; } @@ -103,15 +92,19 @@ static int mpc8544_load_device_tree(target_phys_addr_t addr, if (ret < 0) fprintf(stderr, "couldn't set /memory/reg\n"); - ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", - initrd_base); - if (ret < 0) - fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); + if (initrd_size) { + ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", + initrd_base); + if (ret < 0) { + fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); + } - ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", - (initrd_base + initrd_size)); - if (ret < 0) - fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); + ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", + (initrd_base + initrd_size)); + if (ret < 0) { + fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); + } + } ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline); @@ -119,36 +112,59 @@ static int mpc8544_load_device_tree(target_phys_addr_t addr, fprintf(stderr, "couldn't set /chosen/bootargs\n"); if (kvm_enabled()) { - struct dirent *dirp; - DIR *dp; - char buf[128]; - - if ((dp = opendir("/proc/device-tree/cpus/")) == NULL) { - printf("Can't open directory /proc/device-tree/cpus/\n"); - ret = -1; - goto out; - } + /* Read out host's frequencies */ + clock_freq = kvmppc_get_clockfreq(); + tb_freq = kvmppc_get_tbfreq(); + + /* indicate KVM hypercall interface */ + qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible", + "linux,kvm"); + kvmppc_get_hypercall(env, hypercall, sizeof(hypercall)); + qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions", + hypercall, sizeof(hypercall)); + } + + /* We need to generate the cpu nodes in reverse order, so Linux can pick + the first node as boot node and be happy */ + for (i = smp_cpus - 1; i >= 0; i--) { + char cpu_name[128]; + uint64_t cpu_release_addr = cpu_to_be64(MPC8544_SPIN_BASE + (i * 0x20)); - buf[0] = '\0'; - while ((dirp = readdir(dp)) != NULL) { - if (strncmp(dirp->d_name, "PowerPC", 7) == 0) { - snprintf(buf, 128, "/cpus/%s", dirp->d_name); + for (env = first_cpu; env != NULL; env = env->next_cpu) { + if (env->cpu_index == i) { break; } } - closedir(dp); - if (buf[0] == '\0') { - printf("Unknow host!\n"); - ret = -1; - goto out; + + if (!env) { + continue; } - mpc8544_copy_soc_cell(fdt, buf, "clock-frequency"); - mpc8544_copy_soc_cell(fdt, buf, "timebase-frequency"); + snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", env->cpu_index); + qemu_devtree_add_subnode(fdt, cpu_name); + qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq); + qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq); + qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu"); + qemu_devtree_setprop_cell(fdt, cpu_name, "reg", env->cpu_index); + qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size", + env->dcache_line_size); + qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size", + env->icache_line_size); + qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000); + qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000); + qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0); + if (env->cpu_index) { + qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled"); + qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table"); + qemu_devtree_setprop(fdt, cpu_name, "cpu-release-addr", + &cpu_release_addr, sizeof(cpu_release_addr)); + } else { + qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay"); + } } ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr); - qemu_free(fdt); + g_free(fdt); out: #endif @@ -156,6 +172,55 @@ out: return ret; } +/* Create -kernel TLB entries for BookE, linearly spanning 256MB. */ +static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size) +{ + return ffs(size >> 10) - 1; +} + +static void mmubooke_create_initial_mapping(CPUState *env, + target_ulong va, + target_phys_addr_t pa) +{ + ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0); + target_phys_addr_t size; + + size = (booke206_page_size_to_tlb(256 * 1024 * 1024) << MAS1_TSIZE_SHIFT); + tlb->mas1 = MAS1_VALID | size; + tlb->mas2 = va & TARGET_PAGE_MASK; + tlb->mas7_3 = pa & TARGET_PAGE_MASK; + tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX; + + env->tlb_dirty = true; +} + +static void mpc8544ds_cpu_reset_sec(void *opaque) +{ + CPUState *env = opaque; + + cpu_reset(env); + + /* Secondary CPU starts in halted state for now. Needs to change when + implementing non-kernel boot. */ + env->halted = 1; + env->exception_index = EXCP_HLT; +} + +static void mpc8544ds_cpu_reset(void *opaque) +{ + CPUState *env = opaque; + struct boot_info *bi = env->load_info; + + cpu_reset(env); + + /* Set initial guest state. */ + env->halted = 0; + env->gpr[1] = (16<<20) - 8; + env->gpr[3] = bi->dt_base; + env->nip = bi->entry; + mmubooke_create_initial_mapping(env, 0, 0); +} + static void mpc8544ds_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, @@ -163,8 +228,10 @@ static void mpc8544ds_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); PCIBus *pci_bus; - CPUState *env; + CPUState *env = NULL; uint64_t elf_entry; uint64_t elf_lowaddr; target_phys_addr_t entry=0; @@ -175,48 +242,89 @@ static void mpc8544ds_init(ram_addr_t ram_size, target_long initrd_size=0; int i=0; unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; - qemu_irq *irqs, *mpic, *pci_irqs; + qemu_irq **irqs, *mpic; + DeviceState *dev; + CPUState *firstenv = NULL; + + /* Setup CPUs */ + if (cpu_model == NULL) { + cpu_model = "e500v2_v30"; + } + + irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); + irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); + for (i = 0; i < smp_cpus; i++) { + qemu_irq *input; + env = cpu_ppc_init(cpu_model); + if (!env) { + fprintf(stderr, "Unable to initialize CPU!\n"); + exit(1); + } + + if (!firstenv) { + firstenv = env; + } - /* Setup CPU */ - env = cpu_ppc_init("e500v2_v30"); - if (!env) { - fprintf(stderr, "Unable to initialize CPU!\n"); - exit(1); + irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB); + input = (qemu_irq *)env->irq_inputs; + irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; + irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; + env->spr[SPR_BOOKE_PIR] = env->cpu_index = i; + + ppc_booke_timers_init(env, 400000000, PPC_TIMER_E500); + + /* Register reset handler */ + if (!i) { + /* Primary CPU */ + struct boot_info *boot_info; + boot_info = g_malloc0(sizeof(struct boot_info)); + qemu_register_reset(mpc8544ds_cpu_reset, env); + env->load_info = boot_info; + } else { + /* Secondary CPUs */ + qemu_register_reset(mpc8544ds_cpu_reset_sec, env); + } } + env = firstenv; + /* Fixup Memory size on a alignment boundary */ ram_size &= ~(RAM_SIZES_ALIGN - 1); /* Register Memory */ - cpu_register_physical_memory(0, ram_size, qemu_ram_alloc(NULL, - "mpc8544ds.ram", ram_size)); + memory_region_init_ram(ram, NULL, "mpc8544ds.ram", ram_size); + memory_region_add_subregion(address_space_mem, 0, ram); /* MPIC */ - irqs = qemu_mallocz(sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); - irqs[OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_INT]; - irqs[OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_CINT]; - mpic = mpic_init(MPC8544_MPIC_REGS_BASE, 1, &irqs, NULL); + mpic = mpic_init(address_space_mem, MPC8544_MPIC_REGS_BASE, + smp_cpus, irqs, NULL); + + if (!mpic) { + cpu_abort(env, "MPIC failed to initialize\n"); + } /* Serial */ if (serial_hds[0]) { - serial_mm_init(MPC8544_SERIAL0_REGS_BASE, + serial_mm_init(address_space_mem, MPC8544_SERIAL0_REGS_BASE, 0, mpic[12+26], 399193, - serial_hds[0], 1, 1); + serial_hds[0], DEVICE_BIG_ENDIAN); } if (serial_hds[1]) { - serial_mm_init(MPC8544_SERIAL1_REGS_BASE, + serial_mm_init(address_space_mem, MPC8544_SERIAL1_REGS_BASE, 0, mpic[12+26], 399193, - serial_hds[0], 1, 1); + serial_hds[0], DEVICE_BIG_ENDIAN); } + /* General Utility device */ + sysbus_create_simple("mpc8544-guts", MPC8544_UTIL_BASE, NULL); + /* PCI */ - pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4); - pci_irqs[0] = mpic[pci_irq_nrs[0]]; - pci_irqs[1] = mpic[pci_irq_nrs[1]]; - pci_irqs[2] = mpic[pci_irq_nrs[2]]; - pci_irqs[3] = mpic[pci_irq_nrs[3]]; - pci_bus = ppce500_pci_init(pci_irqs, MPC8544_PCI_REGS_BASE); + dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE, + mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]], + mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]], + NULL); + pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (!pci_bus) printf("couldn't create PCI controller!\n"); @@ -229,6 +337,9 @@ static void mpc8544ds_init(ram_addr_t ram_size, } } + /* Register spinning region */ + sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL); + /* Load kernel. */ if (kernel_filename) { kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL); @@ -261,32 +372,33 @@ static void mpc8544ds_init(ram_addr_t ram_size, /* If we're loading a kernel directly, we must load the device tree too. */ if (kernel_filename) { + struct boot_info *boot_info; + +#ifndef CONFIG_FDT + cpu_abort(env, "Compiled without FDT support - can't load kernel\n"); +#endif dt_base = (kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK; - if (mpc8544_load_device_tree(dt_base, ram_size, + if (mpc8544_load_device_tree(env, dt_base, ram_size, initrd_base, initrd_size, kernel_cmdline) < 0) { fprintf(stderr, "couldn't load device tree\n"); exit(1); } - cpu_synchronize_state(env); - - /* Set initial guest state. */ - env->gpr[1] = (16<<20) - 8; - env->gpr[3] = dt_base; - env->nip = entry; - /* XXX we currently depend on KVM to create some initial TLB entries. */ + boot_info = env->load_info; + boot_info->entry = entry; + boot_info->dt_base = dt_base; } - if (kvm_enabled()) + if (kvm_enabled()) { kvmppc_init(); - - return; + } } static QEMUMachine mpc8544ds_machine = { .name = "mpc8544ds", .desc = "mpc8544ds", .init = mpc8544ds_init, + .max_cpus = 15, }; static void mpc8544ds_machine_init(void) diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index 11edd03..960a5d0 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -15,7 +15,6 @@ */ #include "hw.h" -#include "ppce500.h" #include "pci.h" #include "pci_host.h" #include "bswap.h" @@ -29,7 +28,8 @@ #define PCIE500_CFGADDR 0x0 #define PCIE500_CFGDATA 0x4 #define PCIE500_REG_BASE 0xC00 -#define PCIE500_REG_SIZE (0x1000 - PCIE500_REG_BASE) +#define PCIE500_ALL_SIZE 0x1000 +#define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE) #define PPCE500_PCI_CONFIG_ADDR 0x0 #define PPCE500_PCI_CONFIG_DATA 0x4 @@ -73,11 +73,13 @@ struct pci_inbound { }; struct PPCE500PCIState { + PCIHostState pci_state; struct pci_outbound pob[PPCE500_PCI_NR_POBS]; struct pci_inbound pib[PPCE500_PCI_NR_PIBS]; uint32_t gasket_time; - PCIHostState pci_state; - PCIDevice *pci_dev; + qemu_irq irq[4]; + /* mmio maps */ + int reg; }; typedef struct PPCE500PCIState PPCE500PCIState; @@ -87,6 +89,7 @@ static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr) PPCE500PCIState *pci = opaque; unsigned long win; uint32_t value = 0; + int idx; win = addr & 0xfe0; @@ -95,24 +98,44 @@ static uint32_t pci_reg_read4(void *opaque, target_phys_addr_t addr) case PPCE500_PCI_OW2: case PPCE500_PCI_OW3: case PPCE500_PCI_OW4: + idx = (addr >> 5) & 0x7; switch (addr & 0xC) { - case PCI_POTAR: value = pci->pob[(addr >> 5) & 0x7].potar; break; - case PCI_POTEAR: value = pci->pob[(addr >> 5) & 0x7].potear; break; - case PCI_POWBAR: value = pci->pob[(addr >> 5) & 0x7].powbar; break; - case PCI_POWAR: value = pci->pob[(addr >> 5) & 0x7].powar; break; - default: break; + case PCI_POTAR: + value = pci->pob[idx].potar; + break; + case PCI_POTEAR: + value = pci->pob[idx].potear; + break; + case PCI_POWBAR: + value = pci->pob[idx].powbar; + break; + case PCI_POWAR: + value = pci->pob[idx].powar; + break; + default: + break; } break; case PPCE500_PCI_IW3: case PPCE500_PCI_IW2: case PPCE500_PCI_IW1: + idx = ((addr >> 5) & 0x3) - 1; switch (addr & 0xC) { - case PCI_PITAR: value = pci->pib[(addr >> 5) & 0x3].pitar; break; - case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 0x3].piwbar; break; - case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 0x3].piwbear; break; - case PCI_PIWAR: value = pci->pib[(addr >> 5) & 0x3].piwar; break; - default: break; + case PCI_PITAR: + value = pci->pib[idx].pitar; + break; + case PCI_PIWBAR: + value = pci->pib[idx].piwbar; + break; + case PCI_PIWBEAR: + value = pci->pib[idx].piwbear; + break; + case PCI_PIWAR: + value = pci->pib[idx].piwar; + break; + default: + break; }; break; @@ -140,6 +163,7 @@ static void pci_reg_write4(void *opaque, target_phys_addr_t addr, { PPCE500PCIState *pci = opaque; unsigned long win; + int idx; win = addr & 0xfe0; @@ -151,24 +175,44 @@ static void pci_reg_write4(void *opaque, target_phys_addr_t addr, case PPCE500_PCI_OW2: case PPCE500_PCI_OW3: case PPCE500_PCI_OW4: + idx = (addr >> 5) & 0x7; switch (addr & 0xC) { - case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = value; break; - case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = value; break; - case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = value; break; - case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = value; break; - default: break; + case PCI_POTAR: + pci->pob[idx].potar = value; + break; + case PCI_POTEAR: + pci->pob[idx].potear = value; + break; + case PCI_POWBAR: + pci->pob[idx].powbar = value; + break; + case PCI_POWAR: + pci->pob[idx].powar = value; + break; + default: + break; }; break; case PPCE500_PCI_IW3: case PPCE500_PCI_IW2: case PPCE500_PCI_IW1: + idx = ((addr >> 5) & 0x3) - 1; switch (addr & 0xC) { - case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = value; break; - case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = value; break; - case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = value; break; - case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = value; break; - default: break; + case PCI_PITAR: + pci->pib[idx].pitar = value; + break; + case PCI_PIWBAR: + pci->pib[idx].piwbar = value; + break; + case PCI_PIWBEAR: + pci->pib[idx].piwbear = value; + break; + case PCI_PIWAR: + pci->pib[idx].piwar = value; + break; + default: + break; }; break; @@ -198,7 +242,7 @@ static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num) ret = (irq_num + devno - 0x10) % 4; break; default: - printf("Error:%s:unknow dev number\n", __func__); + printf("Error:%s:unknown dev number\n", __func__); } pci_debug("%s: devfn %x irq %d -> %d devno:%x\n", __func__, @@ -216,111 +260,125 @@ static void mpc85xx_pci_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } -static void ppce500_pci_save(QEMUFile *f, void *opaque) -{ - PPCE500PCIState *controller = opaque; - int i; - - pci_device_save(controller->pci_dev, f); +static const VMStateDescription vmstate_pci_outbound = { + .name = "pci_outbound", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(potar, struct pci_outbound), + VMSTATE_UINT32(potear, struct pci_outbound), + VMSTATE_UINT32(powbar, struct pci_outbound), + VMSTATE_UINT32(powar, struct pci_outbound), + VMSTATE_END_OF_LIST() + } +}; - for (i = 0; i < PPCE500_PCI_NR_POBS; i++) { - qemu_put_be32s(f, &controller->pob[i].potar); - qemu_put_be32s(f, &controller->pob[i].potear); - qemu_put_be32s(f, &controller->pob[i].powbar); - qemu_put_be32s(f, &controller->pob[i].powar); +static const VMStateDescription vmstate_pci_inbound = { + .name = "pci_inbound", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(pitar, struct pci_inbound), + VMSTATE_UINT32(piwbar, struct pci_inbound), + VMSTATE_UINT32(piwbear, struct pci_inbound), + VMSTATE_UINT32(piwar, struct pci_inbound), + VMSTATE_END_OF_LIST() } +}; - for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) { - qemu_put_be32s(f, &controller->pib[i].pitar); - qemu_put_be32s(f, &controller->pib[i].piwbar); - qemu_put_be32s(f, &controller->pib[i].piwbear); - qemu_put_be32s(f, &controller->pib[i].piwar); +static const VMStateDescription vmstate_ppce500_pci = { + .name = "ppce500_pci", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(pob, PPCE500PCIState, PPCE500_PCI_NR_POBS, 1, + vmstate_pci_outbound, struct pci_outbound), + VMSTATE_STRUCT_ARRAY(pib, PPCE500PCIState, PPCE500_PCI_NR_PIBS, 1, + vmstate_pci_outbound, struct pci_inbound), + VMSTATE_UINT32(gasket_time, PPCE500PCIState), + VMSTATE_END_OF_LIST() } - qemu_put_be32s(f, &controller->gasket_time); +}; + +static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base) +{ + PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); + PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h); + + sysbus_add_memory(dev, base + PCIE500_CFGADDR, &h->conf_mem); + sysbus_add_memory(dev, base + PCIE500_CFGDATA, &h->data_mem); + cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE, + s->reg); } -static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id) +static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base) { - PPCE500PCIState *controller = opaque; - int i; + PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); - if (version_id != 1) - return -EINVAL; + sysbus_del_memory(dev, &h->conf_mem); + sysbus_del_memory(dev, &h->data_mem); + cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE, + IO_MEM_UNASSIGNED); +} - pci_device_load(controller->pci_dev, f); +#include "exec-memory.h" - for (i = 0; i < PPCE500_PCI_NR_POBS; i++) { - qemu_get_be32s(f, &controller->pob[i].potar); - qemu_get_be32s(f, &controller->pob[i].potear); - qemu_get_be32s(f, &controller->pob[i].powbar); - qemu_get_be32s(f, &controller->pob[i].powar); - } +static int e500_pcihost_initfn(SysBusDevice *dev) +{ + PCIHostState *h; + PPCE500PCIState *s; + PCIBus *b; + int i; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *address_space_io = get_system_io(); + + h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); + s = DO_UPCAST(PPCE500PCIState, pci_state, h); - for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) { - qemu_get_be32s(f, &controller->pib[i].pitar); - qemu_get_be32s(f, &controller->pib[i].piwbar); - qemu_get_be32s(f, &controller->pib[i].piwbear); - qemu_get_be32s(f, &controller->pib[i].piwar); + for (i = 0; i < ARRAY_SIZE(s->irq); i++) { + sysbus_init_irq(dev, &s->irq[i]); } - qemu_get_be32s(f, &controller->gasket_time); + + b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq, + mpc85xx_pci_map_irq, s->irq, address_space_mem, + address_space_io, PCI_DEVFN(0x11, 0), 4); + s->pci_state.bus = b; + + pci_create_simple(b, 0, "e500-host-bridge"); + + memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h, + "pci-conf-idx", 4); + memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h, + "pci-conf-data", 4); + s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s, + DEVICE_BIG_ENDIAN); + sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap); return 0; } -PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers) +static PCIDeviceInfo e500_host_bridge_info = { + .qdev.name = "e500-host-bridge", + .qdev.desc = "Host bridge", + .qdev.size = sizeof(PCIDevice), + .vendor_id = PCI_VENDOR_ID_FREESCALE, + .device_id = PCI_DEVICE_ID_MPC8533E, + .class_id = PCI_CLASS_PROCESSOR_POWERPC, +}; + +static SysBusDeviceInfo e500_pcihost_info = { + .init = e500_pcihost_initfn, + .qdev.name = "e500-pcihost", + .qdev.size = sizeof(PPCE500PCIState), + .qdev.vmsd = &vmstate_ppce500_pci, +}; + +static void e500_pci_register(void) { - PPCE500PCIState *controller; - PCIDevice *d; - int index; - static int ppce500_pci_id; - - controller = qemu_mallocz(sizeof(PPCE500PCIState)); - - controller->pci_state.bus = pci_register_bus(NULL, "pci", - mpc85xx_pci_set_irq, - mpc85xx_pci_map_irq, - pci_irqs, PCI_DEVFN(0x11, 0), - 4); - d = pci_register_device(controller->pci_state.bus, - "host bridge", sizeof(PCIDevice), - 0, NULL, NULL); - - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_FREESCALE); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_MPC8533E); - pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_POWERPC); - - controller->pci_dev = d; - - /* CFGADDR */ - index = pci_host_conf_register_mmio(&controller->pci_state, - DEVICE_BIG_ENDIAN); - if (index < 0) - goto free; - cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index); - - /* CFGDATA */ - index = pci_host_data_register_mmio(&controller->pci_state, - DEVICE_BIG_ENDIAN); - if (index < 0) - goto free; - cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index); - - index = cpu_register_io_memory(e500_pci_reg_read, - e500_pci_reg_write, controller, - DEVICE_NATIVE_ENDIAN); - if (index < 0) - goto free; - cpu_register_physical_memory(registers + PCIE500_REG_BASE, - PCIE500_REG_SIZE, index); - - /* XXX load/save code not tested. */ - register_savevm(&d->qdev, "ppce500_pci", ppce500_pci_id++, - 1, ppce500_pci_save, ppce500_pci_load, controller); - - return controller->pci_state.bus; - -free: - printf("%s error\n", __func__); - qemu_free(controller); - return NULL; + sysbus_register_withprop(&e500_pcihost_info); + pci_qdev_register(&e500_host_bridge_info); } +device_init(e500_pci_register); diff --git a/hw/prep_pci.c b/hw/prep_pci.c index f88b825..149807a 100644 --- a/hw/prep_pci.c +++ b/hw/prep_pci.c @@ -110,19 +110,30 @@ static void prep_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level); } -PCIBus *pci_prep_init(qemu_irq *pic) +PCIBus *pci_prep_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { PREPPCIState *s; PCIDevice *d; int PPC_io_memory; - s = qemu_mallocz(sizeof(PREPPCIState)); + s = g_malloc0(sizeof(PREPPCIState)); s->bus = pci_register_bus(NULL, "pci", - prep_set_irq, prep_map_irq, pic, 0, 4); - - pci_host_conf_register_ioport(0xcf8, s); - - pci_host_data_register_ioport(0xcfc, s); + prep_set_irq, prep_map_irq, pic, + address_space_mem, + address_space_io, + 0, 4); + + memory_region_init_io(&s->conf_mem, &pci_host_conf_be_ops, s, + "pci-conf-idx", 1); + memory_region_add_subregion(address_space_io, 0xcf8, &s->conf_mem); + sysbus_init_ioports(&s->busdev, 0xcf8, 1); + + memory_region_init_io(&s->data_mem, &pci_host_data_be_ops, s, + "pci-conf-data", 1); + memory_region_add_subregion(address_space_io, 0xcfc, &s->data_mem); + sysbus_init_ioports(&s->busdev, 0xcfc, 1); PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read, PPC_PCIIO_write, s, diff --git a/hw/prep_pci.h b/hw/prep_pci.h index cd68512..b6b481a 100644 --- a/hw/prep_pci.h +++ b/hw/prep_pci.h @@ -2,7 +2,10 @@ #define QEMU_PREP_PCI_H #include "qemu-common.h" +#include "memory.h" -PCIBus *pci_prep_init(qemu_irq *pic); +PCIBus *pci_prep_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); #endif diff --git a/hw/primecell.h b/hw/primecell.h index fb456ad..de7d6f2 100644 --- a/hw/primecell.h +++ b/hw/primecell.h @@ -11,4 +11,8 @@ void *pl080_init(uint32_t base, qemu_irq irq, int nchannels); /* arm_sysctl.c */ void arm_sysctl_init(uint32_t base, uint32_t sys_id, uint32_t proc_id); +/* arm_sysctl GPIO lines */ +#define ARM_SYSCTL_GPIO_MMC_WPROT 0 +#define ARM_SYSCTL_GPIO_MMC_CARDIN 1 + #endif diff --git a/hw/ps2.c b/hw/ps2.c index 9ccf8cb..beb2292 100644 --- a/hw/ps2.c +++ b/hw/ps2.c @@ -92,6 +92,7 @@ typedef struct { not the keyboard controller. */ int translate; int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */ + int ledstate; } PS2KbdState; typedef struct { @@ -110,14 +111,24 @@ typedef struct { /* Table to convert from PC scancodes to raw scancodes. */ static const unsigned char ps2_raw_keycode[128] = { - 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, - 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, - 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, - 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3, - 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105, - 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63, - 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111, - 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110 + 0, 118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13, + 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, + 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, + 50, 49, 58, 65, 73, 74, 89, 124, 17, 41, 88, 5, 6, 4, 12, 3, + 11, 2, 10, 1, 9, 119, 126, 108, 117, 125, 123, 107, 115, 116, 121, 105, +114, 122, 112, 113, 127, 96, 97, 120, 7, 15, 23, 31, 39, 47, 55, 63, + 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111, + 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110 +}; +static const unsigned char ps2_raw_keycode_set3[128] = { + 0, 8, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13, + 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27, + 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42, + 50, 49, 58, 65, 73, 74, 89, 126, 25, 41, 20, 7, 15, 23, 31, 39, + 47, 2, 63, 71, 79, 118, 95, 108, 117, 125, 132, 107, 115, 116, 124, 105, +114, 122, 112, 113, 127, 96, 97, 86, 94, 15, 23, 31, 39, 47, 55, 63, + 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111, + 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110 }; void ps2_queue(void *opaque, int b) @@ -143,12 +154,16 @@ static void ps2_put_keycode(void *opaque, int keycode) { PS2KbdState *s = opaque; - /* XXX: add support for scancode sets 1 and 3 */ - if (!s->translate && keycode < 0xe0 && s->scancode_set == 2) - { - if (keycode & 0x80) + /* XXX: add support for scancode set 1 */ + if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) { + if (keycode & 0x80) { ps2_queue(&s->common, 0xf0); - keycode = ps2_raw_keycode[keycode & 0x7f]; + } + if (s->scancode_set == 2) { + keycode = ps2_raw_keycode[keycode & 0x7f]; + } else if (s->scancode_set == 3) { + keycode = ps2_raw_keycode_set3[keycode & 0x7f]; + } } ps2_queue(&s->common, keycode); } @@ -181,11 +196,17 @@ uint32_t ps2_read_data(void *opaque) return val; } +static void ps2_set_ledstate(PS2KbdState *s, int ledstate) +{ + s->ledstate = ledstate; + kbd_put_ledstate(ledstate); +} + static void ps2_reset_keyboard(PS2KbdState *s) { s->scan_enabled = 1; s->scancode_set = 2; - kbd_put_ledstate(0); + ps2_set_ledstate(s, 0); } void ps2_write_keyboard(void *opaque, int val) @@ -260,7 +281,7 @@ void ps2_write_keyboard(void *opaque, int val) s->common.write_cmd = -1; break; case KBD_CMD_SET_LEDS: - kbd_put_ledstate(val); + ps2_set_ledstate(s, val); ps2_queue(&s->common, KBD_REPLY_ACK); s->common.write_cmd = -1; break; @@ -543,6 +564,33 @@ static const VMStateDescription vmstate_ps2_common = { } }; +static bool ps2_keyboard_ledstate_needed(void *opaque) +{ + PS2KbdState *s = opaque; + + return s->ledstate != 0; /* 0 is default state */ +} + +static int ps2_kbd_ledstate_post_load(void *opaque, int version_id) +{ + PS2KbdState *s = opaque; + + kbd_put_ledstate(s->ledstate); + return 0; +} + +static const VMStateDescription vmstate_ps2_keyboard_ledstate = { + .name = "ps2kbd/ledstate", + .version_id = 3, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .post_load = ps2_kbd_ledstate_post_load, + .fields = (VMStateField []) { + VMSTATE_INT32(ledstate, PS2KbdState), + VMSTATE_END_OF_LIST() + } +}; + static int ps2_kbd_post_load(void* opaque, int version_id) { PS2KbdState *s = (PS2KbdState*)opaque; @@ -564,6 +612,14 @@ static const VMStateDescription vmstate_ps2_keyboard = { VMSTATE_INT32(translate, PS2KbdState), VMSTATE_INT32_V(scancode_set, PS2KbdState,3), VMSTATE_END_OF_LIST() + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_ps2_keyboard_ledstate, + .needed = ps2_keyboard_ledstate_needed, + }, { + /* empty */ + } } }; @@ -590,20 +646,24 @@ static const VMStateDescription vmstate_ps2_mouse = { void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) { - PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState)); + PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState)); s->common.update_irq = update_irq; s->common.update_arg = update_arg; s->scancode_set = 2; vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); +#ifdef CONFIG_MARU qemu_add_ps2kbd_event_handler(ps2_put_keycode, s); +#else + qemu_add_kbd_event_handler(ps2_put_keycode, s); +#endif qemu_register_reset(ps2_kbd_reset, s); return s; } void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) { - PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState)); + PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState)); s->common.update_irq = update_irq; s->common.update_arg = update_arg; diff --git a/hw/ptimer.c b/hw/ptimer.c index 4ddbc59..b6cabd5 100644 --- a/hw/ptimer.c +++ b/hw/ptimer.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GNU LGPL. + * This code is licensed under the GNU LGPL. */ #include "hw.h" #include "qemu-timer.h" @@ -11,7 +11,7 @@ struct ptimer_state { - int enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */ + uint8_t enabled; /* 0 = disabled, 1 = periodic, 2 = oneshot. */ uint64_t limit; uint64_t delta; uint32_t period_frac; @@ -68,7 +68,7 @@ uint64_t ptimer_get_count(ptimer_state *s) uint64_t counter; if (s->enabled) { - now = qemu_get_clock(vm_clock); + now = qemu_get_clock_ns(vm_clock); /* Figure out the current counter value. */ if (now - s->next_event > 0 || s->period == 0) { @@ -122,7 +122,7 @@ void ptimer_set_count(ptimer_state *s, uint64_t count) { s->delta = count; if (s->enabled) { - s->next_event = qemu_get_clock(vm_clock); + s->next_event = qemu_get_clock_ns(vm_clock); ptimer_reload(s); } } @@ -137,7 +137,7 @@ void ptimer_run(ptimer_state *s, int oneshot) return; } s->enabled = oneshot ? 2 : 1; - s->next_event = qemu_get_clock(vm_clock); + s->next_event = qemu_get_clock_ns(vm_clock); ptimer_reload(s); } @@ -159,7 +159,7 @@ void ptimer_set_period(ptimer_state *s, int64_t period) s->period = period; s->period_frac = 0; if (s->enabled) { - s->next_event = qemu_get_clock(vm_clock); + s->next_event = qemu_get_clock_ns(vm_clock); ptimer_reload(s); } } @@ -170,7 +170,7 @@ void ptimer_set_freq(ptimer_state *s, uint32_t freq) s->period = 1000000000ll / freq; s->period_frac = (1000000000ll << 32) / freq; if (s->enabled) { - s->next_event = qemu_get_clock(vm_clock); + s->next_event = qemu_get_clock_ns(vm_clock); ptimer_reload(s); } } @@ -183,62 +183,35 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload) if (reload) s->delta = limit; if (s->enabled && reload) { - s->next_event = qemu_get_clock(vm_clock); + s->next_event = qemu_get_clock_ns(vm_clock); ptimer_reload(s); } } -void qemu_put_ptimer(QEMUFile *f, ptimer_state *s) -{ - qemu_put_byte(f, s->enabled); - qemu_put_be64s(f, &s->limit); - qemu_put_be64s(f, &s->delta); - qemu_put_be32s(f, &s->period_frac); - qemu_put_sbe64s(f, &s->period); - qemu_put_sbe64s(f, &s->last_event); - qemu_put_sbe64s(f, &s->next_event); - qemu_put_timer(f, s->timer); -} - -void qemu_get_ptimer(QEMUFile *f, ptimer_state *s) -{ - s->enabled = qemu_get_byte(f); - qemu_get_be64s(f, &s->limit); - qemu_get_be64s(f, &s->delta); - qemu_get_be32s(f, &s->period_frac); - qemu_get_sbe64s(f, &s->period); - qemu_get_sbe64s(f, &s->last_event); - qemu_get_sbe64s(f, &s->next_event); - qemu_get_timer(f, s->timer); -} - -static int get_ptimer(QEMUFile *f, void *pv, size_t size) -{ - ptimer_state *v = pv; - - qemu_get_ptimer(f, v); - return 0; -} - -static void put_ptimer(QEMUFile *f, void *pv, size_t size) -{ - ptimer_state *v = pv; - - qemu_put_ptimer(f, v); -} - -const VMStateInfo vmstate_info_ptimer = { +const VMStateDescription vmstate_ptimer = { .name = "ptimer", - .get = get_ptimer, - .put = put_ptimer, + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(enabled, ptimer_state), + VMSTATE_UINT64(limit, ptimer_state), + VMSTATE_UINT64(delta, ptimer_state), + VMSTATE_UINT32(period_frac, ptimer_state), + VMSTATE_INT64(period, ptimer_state), + VMSTATE_INT64(last_event, ptimer_state), + VMSTATE_INT64(next_event, ptimer_state), + VMSTATE_TIMER(timer, ptimer_state), + VMSTATE_END_OF_LIST() + } }; ptimer_state *ptimer_init(QEMUBH *bh) { ptimer_state *s; - s = (ptimer_state *)qemu_mallocz(sizeof(ptimer_state)); + s = (ptimer_state *)g_malloc0(sizeof(ptimer_state)); s->bh = bh; - s->timer = qemu_new_timer(vm_clock, ptimer_tick, s); + s->timer = qemu_new_timer_ns(vm_clock, ptimer_tick, s); return s; } diff --git a/hw/pxa.h b/hw/pxa.h index f73d33b..7e98384 100644 --- a/hw/pxa.h +++ b/hw/pxa.h @@ -4,11 +4,13 @@ * Copyright (c) 2006 Openedhand Ltd. * Written by Andrzej Zaborowski * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #ifndef PXA_H # define PXA_H "pxa.h" +#include "memory.h" + /* Interrupt numbers */ # define PXA2XX_PIC_SSP3 0 # define PXA2XX_PIC_USBH2 2 @@ -63,24 +65,16 @@ # define PXA2XX_INTERNAL_SIZE 0x40000 /* pxa2xx_pic.c */ -qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env); - -/* pxa2xx_timer.c */ -void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs); -void pxa27x_timer_init(target_phys_addr_t base, qemu_irq *irqs, qemu_irq irq4); +DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env); /* pxa2xx_gpio.c */ DeviceState *pxa2xx_gpio_init(target_phys_addr_t base, - CPUState *env, qemu_irq *pic, int lines); + CPUState *env, DeviceState *pic, int lines); void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler); /* pxa2xx_dma.c */ -typedef struct PXA2xxDMAState PXA2xxDMAState; -PXA2xxDMAState *pxa255_dma_init(target_phys_addr_t base, - qemu_irq irq); -PXA2xxDMAState *pxa27x_dma_init(target_phys_addr_t base, - qemu_irq irq); -void pxa2xx_dma_request(PXA2xxDMAState *s, int req_num, int on); +DeviceState *pxa255_dma_init(target_phys_addr_t base, qemu_irq irq); +DeviceState *pxa27x_dma_init(target_phys_addr_t base, qemu_irq irq); /* pxa2xx_lcd.c */ typedef struct PXA2xxLCDState PXA2xxLCDState; @@ -92,7 +86,8 @@ void pxa2xx_lcdc_oritentation(void *opaque, int angle); /* pxa2xx_mmci.c */ typedef struct PXA2xxMMCIState PXA2xxMMCIState; PXA2xxMMCIState *pxa2xx_mmci_init(target_phys_addr_t base, - BlockDriverState *bd, qemu_irq irq, void *dma); + BlockDriverState *bd, qemu_irq irq, + qemu_irq rx_dma, qemu_irq tx_dma); void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly, qemu_irq coverswitch); @@ -125,9 +120,14 @@ typedef struct PXA2xxFIrState PXA2xxFIrState; typedef struct { CPUState *env; - qemu_irq *pic; + DeviceState *pic; qemu_irq reset; - PXA2xxDMAState *dma; + MemoryRegion sdram; + MemoryRegion internal; + MemoryRegion cm_iomem; + MemoryRegion mm_iomem; + MemoryRegion pm_iomem; + DeviceState *dma; DeviceState *gpio; PXA2xxLCDState *lcd; SSIBus **ssp; @@ -153,38 +153,13 @@ typedef struct { /* Performance monitoring */ uint32_t pmnc; - - /* Real-Time clock */ - target_phys_addr_t rtc_base; - uint32_t rttr; - uint32_t rtsr; - uint32_t rtar; - uint32_t rdar1; - uint32_t rdar2; - uint32_t ryar1; - uint32_t ryar2; - uint32_t swar1; - uint32_t swar2; - uint32_t piar; - uint32_t last_rcnr; - uint32_t last_rdcr; - uint32_t last_rycr; - uint32_t last_swcr; - uint32_t last_rtcpicr; - int64_t last_hz; - int64_t last_sw; - int64_t last_pi; - QEMUTimer *rtc_hz; - QEMUTimer *rtc_rdal1; - QEMUTimer *rtc_rdal2; - QEMUTimer *rtc_swal1; - QEMUTimer *rtc_swal2; - QEMUTimer *rtc_pi; } PXA2xxState; struct PXA2xxI2SState { + MemoryRegion iomem; qemu_irq irq; - PXA2xxDMAState *dma; + qemu_irq rx_dma; + qemu_irq tx_dma; void (*data_req)(void *, int, int); uint32_t control[2]; @@ -206,7 +181,8 @@ struct PXA2xxI2SState { # define PA_FMT "0x%08lx" # define REG_FMT "0x" TARGET_FMT_plx -PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision); -PXA2xxState *pxa255_init(unsigned int sdram_size); +PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size, + const char *revision); +PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size); #endif /* PXA_H */ diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index d966846..e9a507e 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 Openedhand Ltd. * Written by Andrzej Zaborowski * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -13,7 +13,6 @@ #include "pc.h" #include "i2c.h" #include "ssi.h" -#include "qemu-timer.h" #include "qemu-char.h" #include "blockdev.h" @@ -89,7 +88,8 @@ static PXASSPDef pxa27x_ssp[] = { #define PCMD0 0x80 /* Power Manager I2C Command register File 0 */ #define PCMD31 0xfc /* Power Manager I2C Command register File 31 */ -static uint32_t pxa2xx_pm_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_pm_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PXA2xxState *s = (PXA2xxState *) opaque; @@ -108,13 +108,16 @@ static uint32_t pxa2xx_pm_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_pm_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { PXA2xxState *s = (PXA2xxState *) opaque; switch (addr) { case PMCR: - s->pm_regs[addr >> 2] &= 0x15 & ~(value & 0x2a); + /* Clear the write-one-to-clear bits... */ + s->pm_regs[addr >> 2] &= ~(value & 0x2a); + /* ...and set the plain r/w bits */ + s->pm_regs[addr >> 2] &= ~0x15; s->pm_regs[addr >> 2] |= value & 0x15; break; @@ -135,44 +138,30 @@ static void pxa2xx_pm_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_pm_readfn[] = { - pxa2xx_pm_read, - pxa2xx_pm_read, - pxa2xx_pm_read, +static const MemoryRegionOps pxa2xx_pm_ops = { + .read = pxa2xx_pm_read, + .write = pxa2xx_pm_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const pxa2xx_pm_writefn[] = { - pxa2xx_pm_write, - pxa2xx_pm_write, - pxa2xx_pm_write, +static const VMStateDescription vmstate_pxa2xx_pm = { + .name = "pxa2xx_pm", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40), + VMSTATE_END_OF_LIST() + } }; -static void pxa2xx_pm_save(QEMUFile *f, void *opaque) -{ - PXA2xxState *s = (PXA2xxState *) opaque; - int i; - - for (i = 0; i < 0x40; i ++) - qemu_put_be32s(f, &s->pm_regs[i]); -} - -static int pxa2xx_pm_load(QEMUFile *f, void *opaque, int version_id) -{ - PXA2xxState *s = (PXA2xxState *) opaque; - int i; - - for (i = 0; i < 0x40; i ++) - qemu_get_be32s(f, &s->pm_regs[i]); - - return 0; -} - #define CCCR 0x00 /* Core Clock Configuration register */ #define CKEN 0x04 /* Clock Enable register */ #define OSCC 0x08 /* Oscillator Configuration register */ #define CCSR 0x0c /* Core Clock Status register */ -static uint32_t pxa2xx_cm_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_cm_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PXA2xxState *s = (PXA2xxState *) opaque; @@ -193,7 +182,7 @@ static uint32_t pxa2xx_cm_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_cm_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { PXA2xxState *s = (PXA2xxState *) opaque; @@ -216,42 +205,25 @@ static void pxa2xx_cm_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_cm_readfn[] = { - pxa2xx_cm_read, - pxa2xx_cm_read, - pxa2xx_cm_read, +static const MemoryRegionOps pxa2xx_cm_ops = { + .read = pxa2xx_cm_read, + .write = pxa2xx_cm_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const pxa2xx_cm_writefn[] = { - pxa2xx_cm_write, - pxa2xx_cm_write, - pxa2xx_cm_write, +static const VMStateDescription vmstate_pxa2xx_cm = { + .name = "pxa2xx_cm", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4), + VMSTATE_UINT32(clkcfg, PXA2xxState), + VMSTATE_UINT32(pmnc, PXA2xxState), + VMSTATE_END_OF_LIST() + } }; -static void pxa2xx_cm_save(QEMUFile *f, void *opaque) -{ - PXA2xxState *s = (PXA2xxState *) opaque; - int i; - - for (i = 0; i < 4; i ++) - qemu_put_be32s(f, &s->cm_regs[i]); - qemu_put_be32s(f, &s->clkcfg); - qemu_put_be32s(f, &s->pmnc); -} - -static int pxa2xx_cm_load(QEMUFile *f, void *opaque, int version_id) -{ - PXA2xxState *s = (PXA2xxState *) opaque; - int i; - - for (i = 0; i < 4; i ++) - qemu_get_be32s(f, &s->cm_regs[i]); - qemu_get_be32s(f, &s->clkcfg); - qemu_get_be32s(f, &s->pmnc); - - return 0; -} - static uint32_t pxa2xx_clkpwr_read(void *opaque, int op2, int reg, int crm) { PXA2xxState *s = (PXA2xxState *) opaque; @@ -373,7 +345,7 @@ static uint32_t pxa2xx_perf_read(void *opaque, int op2, int reg, int crm) return s->pmnc; case CPCCNT: if (s->pmnc & 1) - return qemu_get_clock(vm_clock); + return qemu_get_clock_ns(vm_clock); else return 0; case CPINTEN: @@ -482,7 +454,8 @@ static void pxa2xx_cp14_write(void *opaque, int op2, int reg, int crm, #define BSCNTR3 0x60 /* Memory Buffer Strength Control register 3 */ #define SA1110 0x64 /* SA-1110 Memory Compatibility register */ -static uint32_t pxa2xx_mm_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_mm_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PXA2xxState *s = (PXA2xxState *) opaque; @@ -499,7 +472,7 @@ static uint32_t pxa2xx_mm_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_mm_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { PXA2xxState *s = (PXA2xxState *) opaque; @@ -516,41 +489,27 @@ static void pxa2xx_mm_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_mm_readfn[] = { - pxa2xx_mm_read, - pxa2xx_mm_read, - pxa2xx_mm_read, +static const MemoryRegionOps pxa2xx_mm_ops = { + .read = pxa2xx_mm_read, + .write = pxa2xx_mm_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const pxa2xx_mm_writefn[] = { - pxa2xx_mm_write, - pxa2xx_mm_write, - pxa2xx_mm_write, +static const VMStateDescription vmstate_pxa2xx_mm = { + .name = "pxa2xx_mm", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a), + VMSTATE_END_OF_LIST() + } }; -static void pxa2xx_mm_save(QEMUFile *f, void *opaque) -{ - PXA2xxState *s = (PXA2xxState *) opaque; - int i; - - for (i = 0; i < 0x1a; i ++) - qemu_put_be32s(f, &s->mm_regs[i]); -} - -static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id) -{ - PXA2xxState *s = (PXA2xxState *) opaque; - int i; - - for (i = 0; i < 0x1a; i ++) - qemu_get_be32s(f, &s->mm_regs[i]); - - return 0; -} - /* Synchronous Serial Ports */ typedef struct { SysBusDevice busdev; + MemoryRegion iomem; qemu_irq irq; int enable; SSIBus *bus; @@ -657,7 +616,8 @@ static void pxa2xx_ssp_fifo_update(PXA2xxSSPState *s) pxa2xx_ssp_int_update(s); } -static uint32_t pxa2xx_ssp_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_ssp_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PXA2xxSSPState *s = (PXA2xxSSPState *) opaque; uint32_t retval; @@ -703,9 +663,10 @@ static uint32_t pxa2xx_ssp_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_ssp_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value64, unsigned size) { PXA2xxSSPState *s = (PXA2xxSSPState *) opaque; + uint32_t value = value64; switch (addr) { case SSCR0: @@ -792,16 +753,10 @@ static void pxa2xx_ssp_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_ssp_readfn[] = { - pxa2xx_ssp_read, - pxa2xx_ssp_read, - pxa2xx_ssp_read, -}; - -static CPUWriteMemoryFunc * const pxa2xx_ssp_writefn[] = { - pxa2xx_ssp_write, - pxa2xx_ssp_write, - pxa2xx_ssp_write, +static const MemoryRegionOps pxa2xx_ssp_ops = { + .read = pxa2xx_ssp_read, + .write = pxa2xx_ssp_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void pxa2xx_ssp_save(QEMUFile *f, void *opaque) @@ -853,15 +808,12 @@ static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id) static int pxa2xx_ssp_init(SysBusDevice *dev) { - int iomemtype; PXA2xxSSPState *s = FROM_SYSBUS(PXA2xxSSPState, dev); sysbus_init_irq(dev, &s->irq); - iomemtype = cpu_register_io_memory(pxa2xx_ssp_readfn, - pxa2xx_ssp_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, iomemtype); + memory_region_init_io(&s->iomem, &pxa2xx_ssp_ops, s, "pxa2xx-ssp", 0x1000); + sysbus_init_mmio_region(dev, &s->iomem); register_savevm(&dev->qdev, "pxa2xx_ssp", -1, 0, pxa2xx_ssp_save, pxa2xx_ssp_load, s); @@ -886,14 +838,44 @@ static int pxa2xx_ssp_init(SysBusDevice *dev) #define RTCPICR 0x34 /* RTC Periodic Interrupt Counter register */ #define PIAR 0x38 /* RTC Periodic Interrupt Alarm register */ -static inline void pxa2xx_rtc_int_update(PXA2xxState *s) -{ - qemu_set_irq(s->pic[PXA2XX_PIC_RTCALARM], !!(s->rtsr & 0x2553)); -} - -static void pxa2xx_rtc_hzupdate(PXA2xxState *s) -{ - int64_t rt = qemu_get_clock(rt_clock); +typedef struct { + SysBusDevice busdev; + MemoryRegion iomem; + uint32_t rttr; + uint32_t rtsr; + uint32_t rtar; + uint32_t rdar1; + uint32_t rdar2; + uint32_t ryar1; + uint32_t ryar2; + uint32_t swar1; + uint32_t swar2; + uint32_t piar; + uint32_t last_rcnr; + uint32_t last_rdcr; + uint32_t last_rycr; + uint32_t last_swcr; + uint32_t last_rtcpicr; + int64_t last_hz; + int64_t last_sw; + int64_t last_pi; + QEMUTimer *rtc_hz; + QEMUTimer *rtc_rdal1; + QEMUTimer *rtc_rdal2; + QEMUTimer *rtc_swal1; + QEMUTimer *rtc_swal2; + QEMUTimer *rtc_pi; + qemu_irq rtc_irq; +} PXA2xxRTCState; + +static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s) +{ + qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553)); +} + +static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s) +{ + int64_t rt = qemu_get_clock_ms(rt_clock); s->last_rcnr += ((rt - s->last_hz) << 15) / (1000 * ((s->rttr & 0xffff) + 1)); s->last_rdcr += ((rt - s->last_hz) << 15) / @@ -901,23 +883,23 @@ static void pxa2xx_rtc_hzupdate(PXA2xxState *s) s->last_hz = rt; } -static void pxa2xx_rtc_swupdate(PXA2xxState *s) +static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s) { - int64_t rt = qemu_get_clock(rt_clock); + int64_t rt = qemu_get_clock_ms(rt_clock); if (s->rtsr & (1 << 12)) s->last_swcr += (rt - s->last_sw) / 10; s->last_sw = rt; } -static void pxa2xx_rtc_piupdate(PXA2xxState *s) +static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s) { - int64_t rt = qemu_get_clock(rt_clock); + int64_t rt = qemu_get_clock_ms(rt_clock); if (s->rtsr & (1 << 15)) s->last_swcr += rt - s->last_pi; s->last_pi = rt; } -static inline void pxa2xx_rtc_alarm_update(PXA2xxState *s, +static inline void pxa2xx_rtc_alarm_update(PXA2xxRTCState *s, uint32_t rtsr) { if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0))) @@ -962,7 +944,7 @@ static inline void pxa2xx_rtc_alarm_update(PXA2xxState *s, static inline void pxa2xx_rtc_hz_tick(void *opaque) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; s->rtsr |= (1 << 0); pxa2xx_rtc_alarm_update(s, s->rtsr); pxa2xx_rtc_int_update(s); @@ -970,7 +952,7 @@ static inline void pxa2xx_rtc_hz_tick(void *opaque) static inline void pxa2xx_rtc_rdal1_tick(void *opaque) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; s->rtsr |= (1 << 4); pxa2xx_rtc_alarm_update(s, s->rtsr); pxa2xx_rtc_int_update(s); @@ -978,7 +960,7 @@ static inline void pxa2xx_rtc_rdal1_tick(void *opaque) static inline void pxa2xx_rtc_rdal2_tick(void *opaque) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; s->rtsr |= (1 << 6); pxa2xx_rtc_alarm_update(s, s->rtsr); pxa2xx_rtc_int_update(s); @@ -986,7 +968,7 @@ static inline void pxa2xx_rtc_rdal2_tick(void *opaque) static inline void pxa2xx_rtc_swal1_tick(void *opaque) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; s->rtsr |= (1 << 8); pxa2xx_rtc_alarm_update(s, s->rtsr); pxa2xx_rtc_int_update(s); @@ -994,7 +976,7 @@ static inline void pxa2xx_rtc_swal1_tick(void *opaque) static inline void pxa2xx_rtc_swal2_tick(void *opaque) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; s->rtsr |= (1 << 10); pxa2xx_rtc_alarm_update(s, s->rtsr); pxa2xx_rtc_int_update(s); @@ -1002,7 +984,7 @@ static inline void pxa2xx_rtc_swal2_tick(void *opaque) static inline void pxa2xx_rtc_pi_tick(void *opaque) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; s->rtsr |= (1 << 13); pxa2xx_rtc_piupdate(s); s->last_rtcpicr = 0; @@ -1010,9 +992,10 @@ static inline void pxa2xx_rtc_pi_tick(void *opaque) pxa2xx_rtc_int_update(s); } -static uint32_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; switch (addr) { case RTTR: @@ -1036,16 +1019,16 @@ static uint32_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr) case PIAR: return s->piar; case RCNR: - return s->last_rcnr + ((qemu_get_clock(rt_clock) - s->last_hz) << 15) / + return s->last_rcnr + ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) / (1000 * ((s->rttr & 0xffff) + 1)); case RDCR: - return s->last_rdcr + ((qemu_get_clock(rt_clock) - s->last_hz) << 15) / + return s->last_rdcr + ((qemu_get_clock_ms(rt_clock) - s->last_hz) << 15) / (1000 * ((s->rttr & 0xffff) + 1)); case RYCR: return s->last_rycr; case SWCR: if (s->rtsr & (1 << 12)) - return s->last_swcr + (qemu_get_clock(rt_clock) - s->last_sw) / 10; + return s->last_swcr + (qemu_get_clock_ms(rt_clock) - s->last_sw) / 10; else return s->last_swcr; default: @@ -1056,9 +1039,10 @@ static uint32_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_rtc_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value64, unsigned size) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; + uint32_t value = value64; switch (addr) { case RTTR: @@ -1158,20 +1142,15 @@ static void pxa2xx_rtc_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_rtc_readfn[] = { - pxa2xx_rtc_read, - pxa2xx_rtc_read, - pxa2xx_rtc_read, +static const MemoryRegionOps pxa2xx_rtc_ops = { + .read = pxa2xx_rtc_read, + .write = pxa2xx_rtc_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const pxa2xx_rtc_writefn[] = { - pxa2xx_rtc_write, - pxa2xx_rtc_write, - pxa2xx_rtc_write, -}; - -static void pxa2xx_rtc_init(PXA2xxState *s) +static int pxa2xx_rtc_init(SysBusDevice *dev) { + PXA2xxRTCState *s = FROM_SYSBUS(PXA2xxRTCState, dev); struct tm tm; int wom; @@ -1189,72 +1168,79 @@ static void pxa2xx_rtc_init(PXA2xxState *s) s->last_swcr = (tm.tm_hour << 19) | (tm.tm_min << 13) | (tm.tm_sec << 7); s->last_rtcpicr = 0; - s->last_hz = s->last_sw = s->last_pi = qemu_get_clock(rt_clock); + s->last_hz = s->last_sw = s->last_pi = qemu_get_clock_ms(rt_clock); + + s->rtc_hz = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_hz_tick, s); + s->rtc_rdal1 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_rdal1_tick, s); + s->rtc_rdal2 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_rdal2_tick, s); + s->rtc_swal1 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_swal1_tick, s); + s->rtc_swal2 = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_swal2_tick, s); + s->rtc_pi = qemu_new_timer_ms(rt_clock, pxa2xx_rtc_pi_tick, s); - s->rtc_hz = qemu_new_timer(rt_clock, pxa2xx_rtc_hz_tick, s); - s->rtc_rdal1 = qemu_new_timer(rt_clock, pxa2xx_rtc_rdal1_tick, s); - s->rtc_rdal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_rdal2_tick, s); - s->rtc_swal1 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal1_tick, s); - s->rtc_swal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal2_tick, s); - s->rtc_pi = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick, s); + sysbus_init_irq(dev, &s->rtc_irq); + + memory_region_init_io(&s->iomem, &pxa2xx_rtc_ops, s, "pxa2xx-rtc", 0x10000); + sysbus_init_mmio_region(dev, &s->iomem); + + return 0; } -static void pxa2xx_rtc_save(QEMUFile *f, void *opaque) +static void pxa2xx_rtc_pre_save(void *opaque) { - PXA2xxState *s = (PXA2xxState *) opaque; + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; pxa2xx_rtc_hzupdate(s); pxa2xx_rtc_piupdate(s); pxa2xx_rtc_swupdate(s); +} - qemu_put_be32s(f, &s->rttr); - qemu_put_be32s(f, &s->rtsr); - qemu_put_be32s(f, &s->rtar); - qemu_put_be32s(f, &s->rdar1); - qemu_put_be32s(f, &s->rdar2); - qemu_put_be32s(f, &s->ryar1); - qemu_put_be32s(f, &s->ryar2); - qemu_put_be32s(f, &s->swar1); - qemu_put_be32s(f, &s->swar2); - qemu_put_be32s(f, &s->piar); - qemu_put_be32s(f, &s->last_rcnr); - qemu_put_be32s(f, &s->last_rdcr); - qemu_put_be32s(f, &s->last_rycr); - qemu_put_be32s(f, &s->last_swcr); - qemu_put_be32s(f, &s->last_rtcpicr); - qemu_put_sbe64s(f, &s->last_hz); - qemu_put_sbe64s(f, &s->last_sw); - qemu_put_sbe64s(f, &s->last_pi); -} - -static int pxa2xx_rtc_load(QEMUFile *f, void *opaque, int version_id) +static int pxa2xx_rtc_post_load(void *opaque, int version_id) { - PXA2xxState *s = (PXA2xxState *) opaque; - - qemu_get_be32s(f, &s->rttr); - qemu_get_be32s(f, &s->rtsr); - qemu_get_be32s(f, &s->rtar); - qemu_get_be32s(f, &s->rdar1); - qemu_get_be32s(f, &s->rdar2); - qemu_get_be32s(f, &s->ryar1); - qemu_get_be32s(f, &s->ryar2); - qemu_get_be32s(f, &s->swar1); - qemu_get_be32s(f, &s->swar2); - qemu_get_be32s(f, &s->piar); - qemu_get_be32s(f, &s->last_rcnr); - qemu_get_be32s(f, &s->last_rdcr); - qemu_get_be32s(f, &s->last_rycr); - qemu_get_be32s(f, &s->last_swcr); - qemu_get_be32s(f, &s->last_rtcpicr); - qemu_get_sbe64s(f, &s->last_hz); - qemu_get_sbe64s(f, &s->last_sw); - qemu_get_sbe64s(f, &s->last_pi); + PXA2xxRTCState *s = (PXA2xxRTCState *) opaque; pxa2xx_rtc_alarm_update(s, s->rtsr); return 0; } +static const VMStateDescription vmstate_pxa2xx_rtc_regs = { + .name = "pxa2xx_rtc", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .pre_save = pxa2xx_rtc_pre_save, + .post_load = pxa2xx_rtc_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32(rttr, PXA2xxRTCState), + VMSTATE_UINT32(rtsr, PXA2xxRTCState), + VMSTATE_UINT32(rtar, PXA2xxRTCState), + VMSTATE_UINT32(rdar1, PXA2xxRTCState), + VMSTATE_UINT32(rdar2, PXA2xxRTCState), + VMSTATE_UINT32(ryar1, PXA2xxRTCState), + VMSTATE_UINT32(ryar2, PXA2xxRTCState), + VMSTATE_UINT32(swar1, PXA2xxRTCState), + VMSTATE_UINT32(swar2, PXA2xxRTCState), + VMSTATE_UINT32(piar, PXA2xxRTCState), + VMSTATE_UINT32(last_rcnr, PXA2xxRTCState), + VMSTATE_UINT32(last_rdcr, PXA2xxRTCState), + VMSTATE_UINT32(last_rycr, PXA2xxRTCState), + VMSTATE_UINT32(last_swcr, PXA2xxRTCState), + VMSTATE_UINT32(last_rtcpicr, PXA2xxRTCState), + VMSTATE_INT64(last_hz, PXA2xxRTCState), + VMSTATE_INT64(last_sw, PXA2xxRTCState), + VMSTATE_INT64(last_pi, PXA2xxRTCState), + VMSTATE_END_OF_LIST(), + }, +}; + +static SysBusDeviceInfo pxa2xx_rtc_sysbus_info = { + .init = pxa2xx_rtc_init, + .qdev.name = "pxa2xx_rtc", + .qdev.desc = "PXA2xx RTC Controller", + .qdev.size = sizeof(PXA2xxRTCState), + .qdev.vmsd = &vmstate_pxa2xx_rtc_regs, +}; + /* I2C Interface */ typedef struct { i2c_slave i2c; @@ -1262,10 +1248,13 @@ typedef struct { } PXA2xxI2CSlaveState; struct PXA2xxI2CState { + SysBusDevice busdev; + MemoryRegion iomem; PXA2xxI2CSlaveState *slave; i2c_bus *bus; qemu_irq irq; - target_phys_addr_t offset; + uint32_t offset; + uint32_t region_size; uint16_t control; uint16_t status; @@ -1345,7 +1334,8 @@ static int pxa2xx_i2c_tx(i2c_slave *i2c, uint8_t data) return 1; } -static uint32_t pxa2xx_i2c_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_i2c_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PXA2xxI2CState *s = (PXA2xxI2CState *) opaque; @@ -1373,9 +1363,10 @@ static uint32_t pxa2xx_i2c_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_i2c_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value64, unsigned size) { PXA2xxI2CState *s = (PXA2xxI2CState *) opaque; + uint32_t value = value64; int ack; addr -= s->offset; @@ -1442,16 +1433,10 @@ static void pxa2xx_i2c_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_i2c_readfn[] = { - pxa2xx_i2c_read, - pxa2xx_i2c_read, - pxa2xx_i2c_read, -}; - -static CPUWriteMemoryFunc * const pxa2xx_i2c_writefn[] = { - pxa2xx_i2c_write, - pxa2xx_i2c_write, - pxa2xx_i2c_write, +static const MemoryRegionOps pxa2xx_i2c_ops = { + .read = pxa2xx_i2c_read, + .write = pxa2xx_i2c_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static const VMStateDescription vmstate_pxa2xx_i2c_slave = { @@ -1499,27 +1484,41 @@ static I2CSlaveInfo pxa2xx_i2c_slave_info = { PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base, qemu_irq irq, uint32_t region_size) { - int iomemtype; DeviceState *dev; - PXA2xxI2CState *s = qemu_mallocz(sizeof(PXA2xxI2CState)); + SysBusDevice *i2c_dev; + PXA2xxI2CState *s; + + i2c_dev = sysbus_from_qdev(qdev_create(NULL, "pxa2xx_i2c")); + qdev_prop_set_uint32(&i2c_dev->qdev, "size", region_size + 1); + qdev_prop_set_uint32(&i2c_dev->qdev, "offset", + base - (base & (~region_size) & TARGET_PAGE_MASK)); + qdev_init_nofail(&i2c_dev->qdev); + + sysbus_mmio_map(i2c_dev, 0, base & ~region_size); + sysbus_connect_irq(i2c_dev, 0, irq); + + s = FROM_SYSBUS(PXA2xxI2CState, i2c_dev); /* FIXME: Should the slave device really be on a separate bus? */ dev = i2c_create_slave(i2c_init_bus(NULL, "dummy"), "pxa2xx-i2c-slave", 0); s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE_FROM_QDEV(dev)); s->slave->host = s; - s->irq = irq; - s->bus = i2c_init_bus(NULL, "i2c"); - s->offset = base - (base & (~region_size) & TARGET_PAGE_MASK); + return s; +} - iomemtype = cpu_register_io_memory(pxa2xx_i2c_readfn, - pxa2xx_i2c_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base & ~region_size, - region_size + 1, iomemtype); +static int pxa2xx_i2c_initfn(SysBusDevice *dev) +{ + PXA2xxI2CState *s = FROM_SYSBUS(PXA2xxI2CState, dev); - vmstate_register(NULL, base, &vmstate_pxa2xx_i2c, s); + s->bus = i2c_init_bus(&dev->qdev, "i2c"); - return s; + memory_region_init_io(&s->iomem, &pxa2xx_i2c_ops, s, + "pxa2xx-i2x", s->region_size); + sysbus_init_mmio_region(dev, &s->iomem); + sysbus_init_irq(dev, &s->irq); + + return 0; } i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s) @@ -1527,6 +1526,19 @@ i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s) return s->bus; } +static SysBusDeviceInfo pxa2xx_i2c_info = { + .init = pxa2xx_i2c_initfn, + .qdev.name = "pxa2xx_i2c", + .qdev.desc = "PXA2xx I2C Bus Controller", + .qdev.size = sizeof(PXA2xxI2CState), + .qdev.vmsd = &vmstate_pxa2xx_i2c, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("size", PXA2xxI2CState, region_size, 0x10000), + DEFINE_PROP_UINT32("offset", PXA2xxI2CState, offset, 0), + DEFINE_PROP_END_OF_LIST(), + }, +}; + /* PXA Inter-IC Sound Controller */ static void pxa2xx_i2s_reset(PXA2xxI2SState *i2s) { @@ -1553,8 +1565,8 @@ static inline void pxa2xx_i2s_update(PXA2xxI2SState *i2s) tfs = (i2s->tx_len || i2s->fifo_len < SACR_TFTH(i2s->control[0])) && i2s->enable && !SACR_DPRL(i2s->control[1]); - pxa2xx_dma_request(i2s->dma, PXA2XX_RX_RQ_I2S, rfs); - pxa2xx_dma_request(i2s->dma, PXA2XX_TX_RQ_I2S, tfs); + qemu_set_irq(i2s->rx_dma, rfs); + qemu_set_irq(i2s->tx_dma, tfs); i2s->status &= 0xe0; if (i2s->fifo_len < 16 || !i2s->enable) @@ -1582,7 +1594,8 @@ static inline void pxa2xx_i2s_update(PXA2xxI2SState *i2s) #define SADIV 0x60 /* Serial Audio Clock Divider register */ #define SADR 0x80 /* Serial Audio Data register */ -static uint32_t pxa2xx_i2s_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_i2s_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; @@ -1614,7 +1627,7 @@ static uint32_t pxa2xx_i2s_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_i2s_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value, unsigned size) { PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; uint32_t *sample; @@ -1631,7 +1644,7 @@ static void pxa2xx_i2s_write(void *opaque, target_phys_addr_t addr, } if (value & (1 << 4)) /* EFWR */ printf("%s: Attempt to use special function\n", __FUNCTION__); - s->enable = ((value ^ 4) & 5) == 5; /* ENB && !RST*/ + s->enable = (value & 9) == 1; /* ENB && !RST*/ pxa2xx_i2s_update(s); break; case SACR1: @@ -1668,52 +1681,30 @@ static void pxa2xx_i2s_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_i2s_readfn[] = { - pxa2xx_i2s_read, - pxa2xx_i2s_read, - pxa2xx_i2s_read, +static const MemoryRegionOps pxa2xx_i2s_ops = { + .read = pxa2xx_i2s_read, + .write = pxa2xx_i2s_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const pxa2xx_i2s_writefn[] = { - pxa2xx_i2s_write, - pxa2xx_i2s_write, - pxa2xx_i2s_write, +static const VMStateDescription vmstate_pxa2xx_i2s = { + .name = "pxa2xx_i2s", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2), + VMSTATE_UINT32(status, PXA2xxI2SState), + VMSTATE_UINT32(mask, PXA2xxI2SState), + VMSTATE_UINT32(clk, PXA2xxI2SState), + VMSTATE_INT32(enable, PXA2xxI2SState), + VMSTATE_INT32(rx_len, PXA2xxI2SState), + VMSTATE_INT32(tx_len, PXA2xxI2SState), + VMSTATE_INT32(fifo_len, PXA2xxI2SState), + VMSTATE_END_OF_LIST() + } }; -static void pxa2xx_i2s_save(QEMUFile *f, void *opaque) -{ - PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; - - qemu_put_be32s(f, &s->control[0]); - qemu_put_be32s(f, &s->control[1]); - qemu_put_be32s(f, &s->status); - qemu_put_be32s(f, &s->mask); - qemu_put_be32s(f, &s->clk); - - qemu_put_be32(f, s->enable); - qemu_put_be32(f, s->rx_len); - qemu_put_be32(f, s->tx_len); - qemu_put_be32(f, s->fifo_len); -} - -static int pxa2xx_i2s_load(QEMUFile *f, void *opaque, int version_id) -{ - PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; - - qemu_get_be32s(f, &s->control[0]); - qemu_get_be32s(f, &s->control[1]); - qemu_get_be32s(f, &s->status); - qemu_get_be32s(f, &s->mask); - qemu_get_be32s(f, &s->clk); - - s->enable = qemu_get_be32(f); - s->rx_len = qemu_get_be32(f); - s->tx_len = qemu_get_be32(f); - s->fifo_len = qemu_get_be32(f); - - return 0; -} - static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx) { PXA2xxI2SState *s = (PXA2xxI2SState *) opaque; @@ -1736,33 +1727,35 @@ static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx) pxa2xx_i2s_update(s); } -static PXA2xxI2SState *pxa2xx_i2s_init(target_phys_addr_t base, - qemu_irq irq, PXA2xxDMAState *dma) +static PXA2xxI2SState *pxa2xx_i2s_init(MemoryRegion *sysmem, + target_phys_addr_t base, + qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma) { - int iomemtype; PXA2xxI2SState *s = (PXA2xxI2SState *) - qemu_mallocz(sizeof(PXA2xxI2SState)); + g_malloc0(sizeof(PXA2xxI2SState)); s->irq = irq; - s->dma = dma; + s->rx_dma = rx_dma; + s->tx_dma = tx_dma; s->data_req = pxa2xx_i2s_data_req; pxa2xx_i2s_reset(s); - iomemtype = cpu_register_io_memory(pxa2xx_i2s_readfn, - pxa2xx_i2s_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x100000, iomemtype); + memory_region_init_io(&s->iomem, &pxa2xx_i2s_ops, s, + "pxa2xx-i2s", 0x100000); + memory_region_add_subregion(sysmem, base, &s->iomem); - register_savevm(NULL, "pxa2xx_i2s", base, 0, - pxa2xx_i2s_save, pxa2xx_i2s_load, s); + vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s); return s; } /* PXA Fast Infra-red Communications Port */ struct PXA2xxFIrState { + MemoryRegion iomem; qemu_irq irq; - PXA2xxDMAState *dma; + qemu_irq rx_dma; + qemu_irq tx_dma; int enable; CharDriverState *chr; @@ -1816,8 +1809,8 @@ static inline void pxa2xx_fir_update(PXA2xxFIrState *s) (s->status[0] & (1 << 1)); /* TUR */ intr |= s->status[0] & 0x25; /* FRE, RAB, EIF */ - pxa2xx_dma_request(s->dma, PXA2XX_RX_RQ_ICP, (s->status[0] >> 4) & 1); - pxa2xx_dma_request(s->dma, PXA2XX_TX_RQ_ICP, (s->status[0] >> 3) & 1); + qemu_set_irq(s->rx_dma, (s->status[0] >> 4) & 1); + qemu_set_irq(s->tx_dma, (s->status[0] >> 3) & 1); qemu_set_irq(s->irq, intr && s->enable); } @@ -1830,7 +1823,8 @@ static inline void pxa2xx_fir_update(PXA2xxFIrState *s) #define ICSR1 0x18 /* FICP Status register 1 */ #define ICFOR 0x1c /* FICP FIFO Occupancy Status register */ -static uint32_t pxa2xx_fir_read(void *opaque, target_phys_addr_t addr) +static uint64_t pxa2xx_fir_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PXA2xxFIrState *s = (PXA2xxFIrState *) opaque; uint8_t ret; @@ -1868,9 +1862,10 @@ static uint32_t pxa2xx_fir_read(void *opaque, target_phys_addr_t addr) } static void pxa2xx_fir_write(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint64_t value64, unsigned size) { PXA2xxFIrState *s = (PXA2xxFIrState *) opaque; + uint32_t value = value64; uint8_t ch; switch (addr) { @@ -1899,7 +1894,7 @@ static void pxa2xx_fir_write(void *opaque, target_phys_addr_t addr, else ch = ~value; if (s->chr && s->enable && (s->control[0] & (1 << 3))) /* TXE */ - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); break; case ICSR0: s->status[0] &= ~(value & 0x66); @@ -1912,16 +1907,10 @@ static void pxa2xx_fir_write(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const pxa2xx_fir_readfn[] = { - pxa2xx_fir_read, - pxa2xx_fir_read, - pxa2xx_fir_read, -}; - -static CPUWriteMemoryFunc * const pxa2xx_fir_writefn[] = { - pxa2xx_fir_write, - pxa2xx_fir_write, - pxa2xx_fir_write, +static const MemoryRegionOps pxa2xx_fir_ops = { + .read = pxa2xx_fir_read, + .write = pxa2xx_fir_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int pxa2xx_fir_is_empty(void *opaque) @@ -1995,23 +1984,23 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id) return 0; } -static PXA2xxFIrState *pxa2xx_fir_init(target_phys_addr_t base, - qemu_irq irq, PXA2xxDMAState *dma, +static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem, + target_phys_addr_t base, + qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma, CharDriverState *chr) { - int iomemtype; PXA2xxFIrState *s = (PXA2xxFIrState *) - qemu_mallocz(sizeof(PXA2xxFIrState)); + g_malloc0(sizeof(PXA2xxFIrState)); s->irq = irq; - s->dma = dma; + s->rx_dma = rx_dma; + s->tx_dma = tx_dma; s->chr = chr; pxa2xx_fir_reset(s); - iomemtype = cpu_register_io_memory(pxa2xx_fir_readfn, - pxa2xx_fir_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x1000, iomemtype); + memory_region_init_io(&s->iomem, &pxa2xx_fir_ops, s, "pxa2xx-fir", 0x1000); + memory_region_add_subregion(sysmem, base, &s->iomem); if (chr) qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty, @@ -2034,12 +2023,13 @@ static void pxa2xx_reset(void *opaque, int line, int level) } /* Initialise a PXA270 integrated chip (ARM based core). */ -PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) +PXA2xxState *pxa270_init(MemoryRegion *address_space, + unsigned int sdram_size, const char *revision) { PXA2xxState *s; - int iomemtype, i; + int i; DriveInfo *dinfo; - s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState)); + s = (PXA2xxState *) g_malloc0(sizeof(PXA2xxState)); if (revision && strncmp(revision, "pxa27", 5)) { fprintf(stderr, "Machine requires a PXA27x processor.\n"); @@ -2056,19 +2046,24 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0]; /* SDRAM & Internal Memory Storage */ - cpu_register_physical_memory(PXA2XX_SDRAM_BASE, - sdram_size, qemu_ram_alloc(NULL, "pxa270.sdram", - sdram_size) | IO_MEM_RAM); - cpu_register_physical_memory(PXA2XX_INTERNAL_BASE, - 0x40000, qemu_ram_alloc(NULL, "pxa270.internal", - 0x40000) | IO_MEM_RAM); + memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size); + memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram); + memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000); + memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE, + &s->internal); s->pic = pxa2xx_pic_init(0x40d00000, s->env); - s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); + s->dma = pxa27x_dma_init(0x40000000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA)); - pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0], - s->pic[PXA27X_PIC_OST_4_11]); + sysbus_create_varargs("pxa27x-timer", 0x40a00000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0), + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1), + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2), + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3), + qdev_get_gpio_in(s->pic, PXA27X_PIC_OST_4_11), + NULL); s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121); @@ -2078,34 +2073,36 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) exit(1); } s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv, - s->pic[PXA2XX_PIC_MMC], s->dma); - - for (i = 0; pxa270_serial[i].io_base; i ++) - if (serial_hds[i]) -#ifdef TARGET_WORDS_BIGENDIAN - serial_mm_init(pxa270_serial[i].io_base, 2, - s->pic[pxa270_serial[i].irqn], 14857000/16, - serial_hds[i], 1, 1); -#else - serial_mm_init(pxa270_serial[i].io_base, 2, - s->pic[pxa270_serial[i].irqn], 14857000/16, - serial_hds[i], 1, 0); -#endif - else + qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), + qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI), + qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI)); + + for (i = 0; pxa270_serial[i].io_base; i++) { + if (serial_hds[i]) { + serial_mm_init(address_space, pxa270_serial[i].io_base, 2, + qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn), + 14857000 / 16, serial_hds[i], + DEVICE_NATIVE_ENDIAN); + } else { break; + } + } if (serial_hds[i]) - s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP], - s->dma, serial_hds[i]); + s->fir = pxa2xx_fir_init(address_space, 0x40800000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP), + qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP), + qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP), + serial_hds[i]); - s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD]); + s->lcd = pxa2xx_lcdc_init(0x44000000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD)); s->cm_base = 0x41300000; s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */ s->clkcfg = 0x00000009; /* Turbo mode active */ - iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn, - pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype); - register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); + memory_region_init_io(&s->cm_iomem, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000); + memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem); + vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); @@ -2113,48 +2110,47 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) s->mm_regs[MDMRS >> 2] = 0x00020002; s->mm_regs[MDREFR >> 2] = 0x03ca4000; s->mm_regs[MECR >> 2] = 0x00000001; /* Two PC Card sockets */ - iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn, - pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype); - register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); + memory_region_init_io(&s->mm_iomem, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000); + memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem); + vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s); s->pm_base = 0x40f00000; - iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn, - pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->pm_base, 0x100, iomemtype); - register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); + memory_region_init_io(&s->pm_iomem, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100); + memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem); + vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s); for (i = 0; pxa27x_ssp[i].io_base; i ++); - s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i); + s->ssp = (SSIBus **)g_malloc0(sizeof(SSIBus *) * i); for (i = 0; pxa27x_ssp[i].io_base; i ++) { DeviceState *dev; dev = sysbus_create_simple("pxa2xx-ssp", pxa27x_ssp[i].io_base, - s->pic[pxa27x_ssp[i].irqn]); + qdev_get_gpio_in(s->pic, pxa27x_ssp[i].irqn)); s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi"); } if (usb_enabled) { sysbus_create_simple("sysbus-ohci", 0x4c000000, - s->pic[PXA2XX_PIC_USBH1]); + qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1)); } s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000); s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000); - s->rtc_base = 0x40900000; - iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn, - pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype); - pxa2xx_rtc_init(s); - register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, - pxa2xx_rtc_load, s); + sysbus_create_simple("pxa2xx_rtc", 0x40900000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM)); - s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff); - s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff); + s->i2c[0] = pxa2xx_i2c_init(0x40301600, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff); + s->i2c[1] = pxa2xx_i2c_init(0x40f00100, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff); - s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma); + s->i2s = pxa2xx_i2s_init(address_space, 0x40400000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S), + qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S), + qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S)); - s->kp = pxa27x_keypad_init(0x41500000, s->pic[PXA2XX_PIC_KEYPAD]); + s->kp = pxa27x_keypad_init(0x41500000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD)); /* GPIO1 resets the processor */ /* The handler can be overridden by board-specific code */ @@ -2163,13 +2159,13 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision) } /* Initialise a PXA255 integrated chip (ARM based core). */ -PXA2xxState *pxa255_init(unsigned int sdram_size) +PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size) { PXA2xxState *s; - int iomemtype, i; + int i; DriveInfo *dinfo; - s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState)); + s = (PXA2xxState *) g_malloc0(sizeof(PXA2xxState)); s->env = cpu_init("pxa255"); if (!s->env) { @@ -2179,18 +2175,24 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) s->reset = qemu_allocate_irqs(pxa2xx_reset, s, 1)[0]; /* SDRAM & Internal Memory Storage */ - cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size, - qemu_ram_alloc(NULL, "pxa255.sdram", - sdram_size) | IO_MEM_RAM); - cpu_register_physical_memory(PXA2XX_INTERNAL_BASE, PXA2XX_INTERNAL_SIZE, - qemu_ram_alloc(NULL, "pxa255.internal", - PXA2XX_INTERNAL_SIZE) | IO_MEM_RAM); + memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size); + memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram); + memory_region_init_ram(&s->internal, NULL, "pxa255.internal", + PXA2XX_INTERNAL_SIZE); + memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE, + &s->internal); s->pic = pxa2xx_pic_init(0x40d00000, s->env); - s->dma = pxa255_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]); + s->dma = pxa255_dma_init(0x40000000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA)); - pxa25x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0]); + sysbus_create_varargs("pxa25x-timer", 0x40a00000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0), + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1), + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2), + qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3), + NULL); s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85); @@ -2200,35 +2202,36 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) exit(1); } s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv, - s->pic[PXA2XX_PIC_MMC], s->dma); + qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), + qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI), + qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI)); - for (i = 0; pxa255_serial[i].io_base; i ++) + for (i = 0; pxa255_serial[i].io_base; i++) { if (serial_hds[i]) { -#ifdef TARGET_WORDS_BIGENDIAN - serial_mm_init(pxa255_serial[i].io_base, 2, - s->pic[pxa255_serial[i].irqn], 14745600/16, - serial_hds[i], 1, 1); -#else - serial_mm_init(pxa255_serial[i].io_base, 2, - s->pic[pxa255_serial[i].irqn], 14745600/16, - serial_hds[i], 1, 0); -#endif + serial_mm_init(address_space, pxa255_serial[i].io_base, 2, + qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn), + 14745600 / 16, serial_hds[i], + DEVICE_NATIVE_ENDIAN); } else { break; } + } if (serial_hds[i]) - s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP], - s->dma, serial_hds[i]); + s->fir = pxa2xx_fir_init(address_space, 0x40800000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP), + qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP), + qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP), + serial_hds[i]); - s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD]); + s->lcd = pxa2xx_lcdc_init(0x44000000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD)); s->cm_base = 0x41300000; s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */ s->clkcfg = 0x00000009; /* Turbo mode active */ - iomemtype = cpu_register_io_memory(pxa2xx_cm_readfn, - pxa2xx_cm_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->cm_base, 0x1000, iomemtype); - register_savevm(NULL, "pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); + memory_region_init_io(&s->cm_iomem, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000); + memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem); + vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); @@ -2236,46 +2239,44 @@ PXA2xxState *pxa255_init(unsigned int sdram_size) s->mm_regs[MDMRS >> 2] = 0x00020002; s->mm_regs[MDREFR >> 2] = 0x03ca4000; s->mm_regs[MECR >> 2] = 0x00000001; /* Two PC Card sockets */ - iomemtype = cpu_register_io_memory(pxa2xx_mm_readfn, - pxa2xx_mm_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->mm_base, 0x1000, iomemtype); - register_savevm(NULL, "pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); + memory_region_init_io(&s->mm_iomem, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000); + memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem); + vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s); s->pm_base = 0x40f00000; - iomemtype = cpu_register_io_memory(pxa2xx_pm_readfn, - pxa2xx_pm_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->pm_base, 0x100, iomemtype); - register_savevm(NULL, "pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); + memory_region_init_io(&s->pm_iomem, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100); + memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem); + vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s); for (i = 0; pxa255_ssp[i].io_base; i ++); - s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i); + s->ssp = (SSIBus **)g_malloc0(sizeof(SSIBus *) * i); for (i = 0; pxa255_ssp[i].io_base; i ++) { DeviceState *dev; dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base, - s->pic[pxa255_ssp[i].irqn]); + qdev_get_gpio_in(s->pic, pxa255_ssp[i].irqn)); s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi"); } if (usb_enabled) { sysbus_create_simple("sysbus-ohci", 0x4c000000, - s->pic[PXA2XX_PIC_USBH1]); + qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1)); } s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000); s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000); - s->rtc_base = 0x40900000; - iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn, - pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype); - pxa2xx_rtc_init(s); - register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, - pxa2xx_rtc_load, s); + sysbus_create_simple("pxa2xx_rtc", 0x40900000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM)); - s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff); - s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff); + s->i2c[0] = pxa2xx_i2c_init(0x40301600, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff); + s->i2c[1] = pxa2xx_i2c_init(0x40f00100, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff); - s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma); + s->i2s = pxa2xx_i2s_init(address_space, 0x40400000, + qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S), + qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S), + qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S)); /* GPIO1 resets the processor */ /* The handler can be overridden by board-specific code */ @@ -2287,6 +2288,8 @@ static void pxa2xx_register_devices(void) { i2c_register_slave(&pxa2xx_i2c_slave_info); sysbus_register_dev("pxa2xx-ssp", sizeof(PXA2xxSSPState), pxa2xx_ssp_init); + sysbus_register_withprop(&pxa2xx_i2c_info); + sysbus_register_withprop(&pxa2xx_rtc_sysbus_info); } device_init(pxa2xx_register_devices) diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c index b512d34..07ec2db 100644 --- a/hw/pxa2xx_dma.c +++ b/hw/pxa2xx_dma.c @@ -5,11 +5,17 @@ * Copyright (c) 2006 Thorsten Zitterell * Written by Andrzej Zaborowski * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "hw.h" #include "pxa.h" +#include "sysbus.h" + +#define PXA255_DMA_NUM_CHANNELS 16 +#define PXA27X_DMA_NUM_CHANNELS 32 + +#define PXA2XX_DMA_NUM_REQUESTS 75 typedef struct { target_phys_addr_t descr; @@ -20,11 +26,8 @@ typedef struct { int request; } PXA2xxDMAChannel; -/* Allow the DMA to be used as a PIC. */ -typedef void (*pxa2xx_dma_handler_t)(void *opaque, int irq, int level); - -struct PXA2xxDMAState { - pxa2xx_dma_handler_t handler; +typedef struct PXA2xxDMAState { + SysBusDevice busdev; qemu_irq irq; uint32_t stopintr; @@ -39,16 +42,11 @@ struct PXA2xxDMAState { int channels; PXA2xxDMAChannel *chan; - uint8_t *req; + uint8_t req[PXA2XX_DMA_NUM_REQUESTS]; /* Flag to avoid recursive DMA invocations. */ int running; -}; - -#define PXA255_DMA_NUM_CHANNELS 16 -#define PXA27X_DMA_NUM_CHANNELS 32 - -#define PXA2XX_DMA_NUM_REQUESTS 75 +} PXA2xxDMAState; #define DCSR0 0x0000 /* DMA Control / Status register for Channel 0 */ #define DCSR31 0x007c /* DMA Control / Status register for Channel 31 */ @@ -428,74 +426,42 @@ static CPUWriteMemoryFunc * const pxa2xx_dma_writefn[] = { pxa2xx_dma_write }; -static void pxa2xx_dma_save(QEMUFile *f, void *opaque) +static void pxa2xx_dma_request(void *opaque, int req_num, int on) { - PXA2xxDMAState *s = (PXA2xxDMAState *) opaque; - int i; - - qemu_put_be32(f, s->channels); - - qemu_put_be32s(f, &s->stopintr); - qemu_put_be32s(f, &s->eorintr); - qemu_put_be32s(f, &s->rasintr); - qemu_put_be32s(f, &s->startintr); - qemu_put_be32s(f, &s->endintr); - qemu_put_be32s(f, &s->align); - qemu_put_be32s(f, &s->pio); - - qemu_put_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS); - for (i = 0; i < s->channels; i ++) { - qemu_put_betl(f, s->chan[i].descr); - qemu_put_betl(f, s->chan[i].src); - qemu_put_betl(f, s->chan[i].dest); - qemu_put_be32s(f, &s->chan[i].cmd); - qemu_put_be32s(f, &s->chan[i].state); - qemu_put_be32(f, s->chan[i].request); - }; -} + PXA2xxDMAState *s = opaque; + int ch; + if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS) + hw_error("%s: Bad DMA request %i\n", __FUNCTION__, req_num); -static int pxa2xx_dma_load(QEMUFile *f, void *opaque, int version_id) -{ - PXA2xxDMAState *s = (PXA2xxDMAState *) opaque; - int i; - - if (qemu_get_be32(f) != s->channels) - return -EINVAL; - - qemu_get_be32s(f, &s->stopintr); - qemu_get_be32s(f, &s->eorintr); - qemu_get_be32s(f, &s->rasintr); - qemu_get_be32s(f, &s->startintr); - qemu_get_be32s(f, &s->endintr); - qemu_get_be32s(f, &s->align); - qemu_get_be32s(f, &s->pio); - - qemu_get_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS); - for (i = 0; i < s->channels; i ++) { - s->chan[i].descr = qemu_get_betl(f); - s->chan[i].src = qemu_get_betl(f); - s->chan[i].dest = qemu_get_betl(f); - qemu_get_be32s(f, &s->chan[i].cmd); - qemu_get_be32s(f, &s->chan[i].state); - s->chan[i].request = qemu_get_be32(f); - }; + if (!(s->req[req_num] & DRCMR_MAPVLD)) + return; + ch = s->req[req_num] & DRCMR_CHLNUM; - return 0; + if (!s->chan[ch].request && on) + s->chan[ch].state |= DCSR_RASINTR; + else + s->chan[ch].state &= ~DCSR_RASINTR; + if (s->chan[ch].request && !on) + s->chan[ch].state |= DCSR_EORINT; + + s->chan[ch].request = on; + if (on) { + pxa2xx_dma_run(s); + pxa2xx_dma_update(s, ch); + } } -static PXA2xxDMAState *pxa2xx_dma_init(target_phys_addr_t base, - qemu_irq irq, int channels) +static int pxa2xx_dma_init(SysBusDevice *dev) { int i, iomemtype; PXA2xxDMAState *s; - s = (PXA2xxDMAState *) - qemu_mallocz(sizeof(PXA2xxDMAState)); + s = FROM_SYSBUS(PXA2xxDMAState, dev); + + if (s->channels <= 0) { + return -1; + } - s->channels = channels; - s->chan = qemu_mallocz(sizeof(PXA2xxDMAChannel) * s->channels); - s->irq = irq; - s->handler = (pxa2xx_dma_handler_t) pxa2xx_dma_request; - s->req = qemu_mallocz(sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS); + s->chan = g_malloc0(sizeof(PXA2xxDMAChannel) * s->channels); memset(s->chan, 0, sizeof(PXA2xxDMAChannel) * s->channels); for (i = 0; i < s->channels; i ++) @@ -503,47 +469,100 @@ static PXA2xxDMAState *pxa2xx_dma_init(target_phys_addr_t base, memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS); + qdev_init_gpio_in(&dev->qdev, pxa2xx_dma_request, PXA2XX_DMA_NUM_REQUESTS); + iomemtype = cpu_register_io_memory(pxa2xx_dma_readfn, pxa2xx_dma_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x00010000, iomemtype); + sysbus_init_mmio(dev, 0x00010000, iomemtype); + sysbus_init_irq(dev, &s->irq); - register_savevm(NULL, "pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s); - - return s; + return 0; } -PXA2xxDMAState *pxa27x_dma_init(target_phys_addr_t base, - qemu_irq irq) +DeviceState *pxa27x_dma_init(target_phys_addr_t base, qemu_irq irq) { - return pxa2xx_dma_init(base, irq, PXA27X_DMA_NUM_CHANNELS); + DeviceState *dev; + + dev = qdev_create(NULL, "pxa2xx-dma"); + qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS); + qdev_init_nofail(dev); + + sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); + sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); + + return dev; } -PXA2xxDMAState *pxa255_dma_init(target_phys_addr_t base, - qemu_irq irq) +DeviceState *pxa255_dma_init(target_phys_addr_t base, qemu_irq irq) { - return pxa2xx_dma_init(base, irq, PXA255_DMA_NUM_CHANNELS); + DeviceState *dev; + + dev = qdev_create(NULL, "pxa2xx-dma"); + qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS); + qdev_init_nofail(dev); + + sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); + sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); + + return dev; } -void pxa2xx_dma_request(PXA2xxDMAState *s, int req_num, int on) +static bool is_version_0(void *opaque, int version_id) { - int ch; - if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS) - hw_error("%s: Bad DMA request %i\n", __FUNCTION__, req_num); + return version_id == 0; +} - if (!(s->req[req_num] & DRCMR_MAPVLD)) - return; - ch = s->req[req_num] & DRCMR_CHLNUM; +static VMStateDescription vmstate_pxa2xx_dma_chan = { + .name = "pxa2xx_dma_chan", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINTTL(descr, PXA2xxDMAChannel), + VMSTATE_UINTTL(src, PXA2xxDMAChannel), + VMSTATE_UINTTL(dest, PXA2xxDMAChannel), + VMSTATE_UINT32(cmd, PXA2xxDMAChannel), + VMSTATE_UINT32(state, PXA2xxDMAChannel), + VMSTATE_INT32(request, PXA2xxDMAChannel), + VMSTATE_END_OF_LIST(), + }, +}; - if (!s->chan[ch].request && on) - s->chan[ch].state |= DCSR_RASINTR; - else - s->chan[ch].state &= ~DCSR_RASINTR; - if (s->chan[ch].request && !on) - s->chan[ch].state |= DCSR_EORINT; +static VMStateDescription vmstate_pxa2xx_dma = { + .name = "pxa2xx_dma", + .version_id = 1, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UNUSED_TEST(is_version_0, 4), + VMSTATE_UINT32(stopintr, PXA2xxDMAState), + VMSTATE_UINT32(eorintr, PXA2xxDMAState), + VMSTATE_UINT32(rasintr, PXA2xxDMAState), + VMSTATE_UINT32(startintr, PXA2xxDMAState), + VMSTATE_UINT32(endintr, PXA2xxDMAState), + VMSTATE_UINT32(align, PXA2xxDMAState), + VMSTATE_UINT32(pio, PXA2xxDMAState), + VMSTATE_BUFFER(req, PXA2xxDMAState), + VMSTATE_STRUCT_VARRAY_POINTER_INT32(chan, PXA2xxDMAState, channels, + vmstate_pxa2xx_dma_chan, PXA2xxDMAChannel), + VMSTATE_END_OF_LIST(), + }, +}; - s->chan[ch].request = on; - if (on) { - pxa2xx_dma_run(s); - pxa2xx_dma_update(s, ch); - } +static SysBusDeviceInfo pxa2xx_dma_info = { + .init = pxa2xx_dma_init, + .qdev.name = "pxa2xx-dma", + .qdev.desc = "PXA2xx DMA controller", + .qdev.size = sizeof(PXA2xxDMAState), + .qdev.vmsd = &vmstate_pxa2xx_dma, + .qdev.props = (Property[]) { + DEFINE_PROP_INT32("channels", PXA2xxDMAState, channels, -1), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static void pxa2xx_dma_register(void) +{ + sysbus_register_withprop(&pxa2xx_dma_info); } +device_init(pxa2xx_dma_register); diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c index 789965d..200b0cf 100644 --- a/hw/pxa2xx_gpio.c +++ b/hw/pxa2xx_gpio.c @@ -253,7 +253,7 @@ static CPUWriteMemoryFunc * const pxa2xx_gpio_writefn[] = { }; DeviceState *pxa2xx_gpio_init(target_phys_addr_t base, - CPUState *env, qemu_irq *pic, int lines) + CPUState *env, DeviceState *pic, int lines) { DeviceState *dev; @@ -263,9 +263,12 @@ DeviceState *pxa2xx_gpio_init(target_phys_addr_t base, qdev_init_nofail(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); - sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[PXA2XX_PIC_GPIO_0]); - sysbus_connect_irq(sysbus_from_qdev(dev), 1, pic[PXA2XX_PIC_GPIO_1]); - sysbus_connect_irq(sysbus_from_qdev(dev), 2, pic[PXA2XX_PIC_GPIO_X]); + sysbus_connect_irq(sysbus_from_qdev(dev), 0, + qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_0)); + sysbus_connect_irq(sysbus_from_qdev(dev), 1, + qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_1)); + sysbus_connect_irq(sysbus_from_qdev(dev), 2, + qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_X)); return dev; } diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c index 4c99917..e33959d 100644 --- a/hw/pxa2xx_keypad.c +++ b/hw/pxa2xx_keypad.c @@ -82,22 +82,45 @@ struct PXA2xxKeyPadState { qemu_irq irq; struct keymap *map; + int pressed_cnt; + int alt_code; uint32_t kpc; uint32_t kpdk; uint32_t kprec; uint32_t kpmk; uint32_t kpas; - uint32_t kpasmkp0; - uint32_t kpasmkp1; - uint32_t kpasmkp2; - uint32_t kpasmkp3; + uint32_t kpasmkp[4]; uint32_t kpkdi; }; +static void pxa27x_keypad_find_pressed_key(PXA2xxKeyPadState *kp, int *row, int *col) +{ + int i; + for (i = 0; i < 4; i++) + { + *col = i * 2; + for (*row = 0; *row < 8; (*row)++) { + if (kp->kpasmkp[i] & (1 << *row)) + return; + } + *col = i * 2 + 1; + for (*row = 0; *row < 8; (*row)++) { + if (kp->kpasmkp[i] & (1 << (*row + 16))) + return; + } + } +} + static void pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode) { - int row, col,rel; + int row, col, rel, assert_irq = 0; + uint32_t val; + + if (keycode == 0xe0) { + kp->alt_code = 1; + return; + } if(!(kp->kpc & KPC_ME)) /* skip if not enabled */ return; @@ -108,46 +131,43 @@ static void pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode) rel = (keycode & 0x80) ? 1 : 0; /* key release from qemu */ keycode &= ~(0x80); /* strip qemu key release bit */ + if (kp->alt_code) { + keycode |= 0x80; + kp->alt_code = 0; + } + row = kp->map[keycode].row; col = kp->map[keycode].column; if(row == -1 || col == -1) return; - switch (col) { - case 0: - case 1: - if(rel) - kp->kpasmkp0 = ~(0xffffffff); - else - kp->kpasmkp0 |= KPASMKPx_MKC(row,col); - break; - case 2: - case 3: - if(rel) - kp->kpasmkp1 = ~(0xffffffff); - else - kp->kpasmkp1 |= KPASMKPx_MKC(row,col); - break; - case 4: - case 5: - if(rel) - kp->kpasmkp2 = ~(0xffffffff); - else - kp->kpasmkp2 |= KPASMKPx_MKC(row,col); - break; - case 6: - case 7: - if(rel) - kp->kpasmkp3 = ~(0xffffffff); - else - kp->kpasmkp3 |= KPASMKPx_MKC(row,col); - break; - } /* switch */ + + val = KPASMKPx_MKC(row, col); + if (rel) { + if (kp->kpasmkp[col / 2] & val) { + kp->kpasmkp[col / 2] &= ~val; + kp->pressed_cnt--; + assert_irq = 1; + } + } else { + if (!(kp->kpasmkp[col / 2] & val)) { + kp->kpasmkp[col / 2] |= val; + kp->pressed_cnt++; + assert_irq = 1; + } + } + kp->kpas = ((kp->pressed_cnt & 0x1f) << 26) | (0xf << 4) | 0xf; + if (kp->pressed_cnt == 1) { + kp->kpas &= ~((0xf << 4) | 0xf); + if (rel) + pxa27x_keypad_find_pressed_key(kp, &row, &col); + kp->kpas |= ((row & 0xf) << 4) | (col & 0xf); + } goto out; } return; out: - if(kp->kpc & KPC_MIE) { + if (assert_irq && (kp->kpc & KPC_MIE)) { kp->kpc |= KPC_MI; qemu_irq_raise(kp->irq); } @@ -194,16 +214,16 @@ static uint32_t pxa2xx_keypad_read(void *opaque, target_phys_addr_t offset) return s->kpas; break; case KPASMKP0: - return s->kpasmkp0; + return s->kpasmkp[0]; break; case KPASMKP1: - return s->kpasmkp1; + return s->kpasmkp[1]; break; case KPASMKP2: - return s->kpasmkp2; + return s->kpasmkp[2]; break; case KPASMKP3: - return s->kpasmkp3; + return s->kpasmkp[3]; break; case KPKDI: return s->kpkdi; @@ -237,16 +257,16 @@ static void pxa2xx_keypad_write(void *opaque, s->kpas = value; break; case KPASMKP0: - s->kpasmkp0 = value; + s->kpasmkp[0] = value; break; case KPASMKP1: - s->kpasmkp1 = value; + s->kpasmkp[1] = value; break; case KPASMKP2: - s->kpasmkp2 = value; + s->kpasmkp[2] = value; break; case KPASMKP3: - s->kpasmkp3 = value; + s->kpasmkp[3] = value; break; case KPKDI: s->kpkdi = value; @@ -269,40 +289,22 @@ static CPUWriteMemoryFunc * const pxa2xx_keypad_writefn[] = { pxa2xx_keypad_write }; -static void pxa2xx_keypad_save(QEMUFile *f, void *opaque) -{ - PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque; - - qemu_put_be32s(f, &s->kpc); - qemu_put_be32s(f, &s->kpdk); - qemu_put_be32s(f, &s->kprec); - qemu_put_be32s(f, &s->kpmk); - qemu_put_be32s(f, &s->kpas); - qemu_put_be32s(f, &s->kpasmkp0); - qemu_put_be32s(f, &s->kpasmkp1); - qemu_put_be32s(f, &s->kpasmkp2); - qemu_put_be32s(f, &s->kpasmkp3); - qemu_put_be32s(f, &s->kpkdi); - -} - -static int pxa2xx_keypad_load(QEMUFile *f, void *opaque, int version_id) -{ - PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque; - - qemu_get_be32s(f, &s->kpc); - qemu_get_be32s(f, &s->kpdk); - qemu_get_be32s(f, &s->kprec); - qemu_get_be32s(f, &s->kpmk); - qemu_get_be32s(f, &s->kpas); - qemu_get_be32s(f, &s->kpasmkp0); - qemu_get_be32s(f, &s->kpasmkp1); - qemu_get_be32s(f, &s->kpasmkp2); - qemu_get_be32s(f, &s->kpasmkp3); - qemu_get_be32s(f, &s->kpkdi); - - return 0; -} +static const VMStateDescription vmstate_pxa2xx_keypad = { + .name = "pxa2xx_keypad", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(kpc, PXA2xxKeyPadState), + VMSTATE_UINT32(kpdk, PXA2xxKeyPadState), + VMSTATE_UINT32(kprec, PXA2xxKeyPadState), + VMSTATE_UINT32(kpmk, PXA2xxKeyPadState), + VMSTATE_UINT32(kpas, PXA2xxKeyPadState), + VMSTATE_UINT32_ARRAY(kpasmkp, PXA2xxKeyPadState, 4), + VMSTATE_UINT32(kpkdi, PXA2xxKeyPadState), + VMSTATE_END_OF_LIST() + } +}; PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base, qemu_irq irq) @@ -310,15 +312,14 @@ PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base, int iomemtype; PXA2xxKeyPadState *s; - s = (PXA2xxKeyPadState *) qemu_mallocz(sizeof(PXA2xxKeyPadState)); + s = (PXA2xxKeyPadState *) g_malloc0(sizeof(PXA2xxKeyPadState)); s->irq = irq; iomemtype = cpu_register_io_memory(pxa2xx_keypad_readfn, pxa2xx_keypad_writefn, s, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(base, 0x00100000, iomemtype); - register_savevm(NULL, "pxa2xx_keypad", 0, 0, - pxa2xx_keypad_save, pxa2xx_keypad_load, s); + vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s); return s; } diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c index 5b2b07e..b73290c 100644 --- a/hw/pxa2xx_lcd.c +++ b/hw/pxa2xx_lcd.c @@ -15,6 +15,20 @@ #include "sysemu.h" #include "framebuffer.h" +struct DMAChannel { + target_phys_addr_t branch; + uint8_t up; + uint8_t palette[1024]; + uint8_t pbuffer[1024]; + void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr, + int *miny, int *maxy); + + target_phys_addr_t descriptor; + target_phys_addr_t source; + uint32_t id; + uint32_t command; +}; + struct PXA2xxLCDState { qemu_irq irq; int irqlevel; @@ -50,25 +64,13 @@ struct PXA2xxLCDState { uint32_t liidr; uint8_t bscntr; - struct { - target_phys_addr_t branch; - int up; - uint8_t palette[1024]; - uint8_t pbuffer[1024]; - void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr, - int *miny, int *maxy); - - target_phys_addr_t descriptor; - target_phys_addr_t source; - uint32_t id; - uint32_t command; - } dma_ch[7]; + struct DMAChannel dma_ch[7]; qemu_irq vsync_cb; int orientation; }; -typedef struct __attribute__ ((__packed__)) { +typedef struct QEMU_PACKED { uint32_t fdaddr; uint32_t fsaddr; uint32_t fidr; @@ -663,7 +665,7 @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp) } } -static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s, +static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s, target_phys_addr_t addr, int *miny, int *maxy) { int src_width, dest_width; @@ -690,7 +692,7 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s, fn, s->dma_ch[0].palette, miny, maxy); } -static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s, +static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s, target_phys_addr_t addr, int *miny, int *maxy) { int src_width, dest_width; @@ -718,6 +720,67 @@ static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s, miny, maxy); } +static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s, + target_phys_addr_t addr, int *miny, int *maxy) +{ + int src_width, dest_width; + drawfn fn = NULL; + if (s->dest_width) { + fn = s->line_fn[s->transp][s->bpp]; + } + if (!fn) { + return; + } + + src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ + if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) { + src_width *= 3; + } else if (s->bpp > pxa_lcdc_16bpp) { + src_width *= 4; + } else if (s->bpp > pxa_lcdc_8bpp) { + src_width *= 2; + } + + dest_width = s->xres * s->dest_width; + *miny = 0; + framebuffer_update_display(s->ds, + addr, s->xres, s->yres, + src_width, -dest_width, -s->dest_width, + s->invalidated, + fn, s->dma_ch[0].palette, miny, maxy); +} + +static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, + target_phys_addr_t addr, int *miny, int *maxy) +{ + int src_width, dest_width; + drawfn fn = NULL; + if (s->dest_width) { + fn = s->line_fn[s->transp][s->bpp]; + } + if (!fn) { + return; + } + + src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ + if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) { + src_width *= 3; + } else if (s->bpp > pxa_lcdc_16bpp) { + src_width *= 4; + } else if (s->bpp > pxa_lcdc_8bpp) { + src_width *= 2; + } + + dest_width = s->yres * s->dest_width; + *miny = 0; + framebuffer_update_display(s->ds, + addr, s->xres, s->yres, + src_width, -s->dest_width, dest_width, + s->invalidated, + fn, s->dma_ch[0].palette, + miny, maxy); +} + static void pxa2xx_lcdc_resize(PXA2xxLCDState *s) { int width, height; @@ -728,10 +791,11 @@ static void pxa2xx_lcdc_resize(PXA2xxLCDState *s) height = LCCR2_LPP(s->control[2]) + 1; if (width != s->xres || height != s->yres) { - if (s->orientation) + if (s->orientation == 90 || s->orientation == 270) { qemu_console_resize(s->ds, height, width); - else + } else { qemu_console_resize(s->ds, width, height); + } s->invalidated = 1; s->xres = width; s->yres = height; @@ -795,10 +859,24 @@ static void pxa2xx_update_display(void *opaque) } if (miny >= 0) { - if (s->orientation) - dpy_update(s->ds, miny, 0, maxy - miny, s->xres); - else - dpy_update(s->ds, 0, miny, s->xres, maxy - miny); + switch (s->orientation) { + case 0: + dpy_update(s->ds, 0, miny, s->xres, maxy - miny + 1); + break; + case 90: + dpy_update(s->ds, miny, 0, maxy - miny + 1, s->xres); + break; + case 180: + maxy = s->yres - maxy - 1; + miny = s->yres - miny - 1; + dpy_update(s->ds, 0, maxy, s->xres, miny - maxy + 1); + break; + case 270: + maxy = s->yres - maxy - 1; + miny = s->yres - miny - 1; + dpy_update(s->ds, maxy, 0, miny - maxy + 1, s->xres); + break; + } } pxa2xx_lcdc_int_update(s); @@ -820,10 +898,19 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle) { PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; - if (angle) { - s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_vert; - } else { - s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_horiz; + switch (angle) { + case 0: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0; + break; + case 90: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90; + break; + case 180: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180; + break; + case 270: + s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270; + break; } s->orientation = angle; @@ -831,74 +918,26 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle) pxa2xx_lcdc_resize(s); } -static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque) -{ - PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; - int i; - - qemu_put_be32(f, s->irqlevel); - qemu_put_be32(f, s->transp); - - for (i = 0; i < 6; i ++) - qemu_put_be32s(f, &s->control[i]); - for (i = 0; i < 2; i ++) - qemu_put_be32s(f, &s->status[i]); - for (i = 0; i < 2; i ++) - qemu_put_be32s(f, &s->ovl1c[i]); - for (i = 0; i < 2; i ++) - qemu_put_be32s(f, &s->ovl2c[i]); - qemu_put_be32s(f, &s->ccr); - qemu_put_be32s(f, &s->cmdcr); - qemu_put_be32s(f, &s->trgbr); - qemu_put_be32s(f, &s->tcr); - qemu_put_be32s(f, &s->liidr); - qemu_put_8s(f, &s->bscntr); - - for (i = 0; i < 7; i ++) { - qemu_put_betl(f, s->dma_ch[i].branch); - qemu_put_byte(f, s->dma_ch[i].up); - qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); - - qemu_put_betl(f, s->dma_ch[i].descriptor); - qemu_put_betl(f, s->dma_ch[i].source); - qemu_put_be32s(f, &s->dma_ch[i].id); - qemu_put_be32s(f, &s->dma_ch[i].command); +static const VMStateDescription vmstate_dma_channel = { + .name = "dma_channel", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINTTL(branch, struct DMAChannel), + VMSTATE_UINT8(up, struct DMAChannel), + VMSTATE_BUFFER(pbuffer, struct DMAChannel), + VMSTATE_UINTTL(descriptor, struct DMAChannel), + VMSTATE_UINTTL(source, struct DMAChannel), + VMSTATE_UINT32(id, struct DMAChannel), + VMSTATE_UINT32(command, struct DMAChannel), + VMSTATE_END_OF_LIST() } -} +}; -static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id) +static int pxa2xx_lcdc_post_load(void *opaque, int version_id) { - PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; - int i; - - s->irqlevel = qemu_get_be32(f); - s->transp = qemu_get_be32(f); - - for (i = 0; i < 6; i ++) - qemu_get_be32s(f, &s->control[i]); - for (i = 0; i < 2; i ++) - qemu_get_be32s(f, &s->status[i]); - for (i = 0; i < 2; i ++) - qemu_get_be32s(f, &s->ovl1c[i]); - for (i = 0; i < 2; i ++) - qemu_get_be32s(f, &s->ovl2c[i]); - qemu_get_be32s(f, &s->ccr); - qemu_get_be32s(f, &s->cmdcr); - qemu_get_be32s(f, &s->trgbr); - qemu_get_be32s(f, &s->tcr); - qemu_get_be32s(f, &s->liidr); - qemu_get_8s(f, &s->bscntr); - - for (i = 0; i < 7; i ++) { - s->dma_ch[i].branch = qemu_get_betl(f); - s->dma_ch[i].up = qemu_get_byte(f); - qemu_get_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); - - s->dma_ch[i].descriptor = qemu_get_betl(f); - s->dma_ch[i].source = qemu_get_betl(f); - qemu_get_be32s(f, &s->dma_ch[i].id); - qemu_get_be32s(f, &s->dma_ch[i].command); - } + PXA2xxLCDState *s = opaque; s->bpp = LCCR3_BPP(s->control[3]); s->xres = s->yres = s->pal_for = -1; @@ -906,6 +945,31 @@ static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id) return 0; } +static const VMStateDescription vmstate_pxa2xx_lcdc = { + .name = "pxa2xx_lcdc", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = pxa2xx_lcdc_post_load, + .fields = (VMStateField[]) { + VMSTATE_INT32(irqlevel, PXA2xxLCDState), + VMSTATE_INT32(transp, PXA2xxLCDState), + VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6), + VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2), + VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2), + VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2), + VMSTATE_UINT32(ccr, PXA2xxLCDState), + VMSTATE_UINT32(cmdcr, PXA2xxLCDState), + VMSTATE_UINT32(trgbr, PXA2xxLCDState), + VMSTATE_UINT32(tcr, PXA2xxLCDState), + VMSTATE_UINT32(liidr, PXA2xxLCDState), + VMSTATE_UINT8(bscntr, PXA2xxLCDState), + VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0, + vmstate_dma_channel, struct DMAChannel), + VMSTATE_END_OF_LIST() + } +}; + #define BITS 8 #include "pxa2xx_template.h" #define BITS 15 @@ -922,7 +986,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq) int iomemtype; PXA2xxLCDState *s; - s = (PXA2xxLCDState *) qemu_mallocz(sizeof(PXA2xxLCDState)); + s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState)); s->invalidated = 1; s->irq = irq; @@ -970,8 +1034,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq) exit(1); } - register_savevm(NULL, "pxa2xx_lcdc", 0, 0, - pxa2xx_lcdc_save, pxa2xx_lcdc_load, s); + vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s); return s; } diff --git a/hw/pxa2xx_mmci.c b/hw/pxa2xx_mmci.c index 24d409d..1de4979 100644 --- a/hw/pxa2xx_mmci.c +++ b/hw/pxa2xx_mmci.c @@ -10,10 +10,12 @@ #include "hw.h" #include "pxa.h" #include "sd.h" +#include "qdev.h" struct PXA2xxMMCIState { qemu_irq irq; - void *dma; + qemu_irq rx_dma; + qemu_irq tx_dma; SDState *card; @@ -102,10 +104,8 @@ static void pxa2xx_mmci_int_update(PXA2xxMMCIState *s) if (s->cmdat & CMDAT_DMA_EN) { mask |= INT_RXFIFO_REQ | INT_TXFIFO_REQ; - pxa2xx_dma_request(s->dma, - PXA2XX_RX_RQ_MMCI, !!(s->intreq & INT_RXFIFO_REQ)); - pxa2xx_dma_request(s->dma, - PXA2XX_TX_RQ_MMCI, !!(s->intreq & INT_TXFIFO_REQ)); + qemu_set_irq(s->rx_dma, !!(s->intreq & INT_RXFIFO_REQ)); + qemu_set_irq(s->tx_dma, !!(s->intreq & INT_TXFIFO_REQ)); } qemu_set_irq(s->irq, !!(s->intreq & ~mask)); @@ -518,14 +518,16 @@ static int pxa2xx_mmci_load(QEMUFile *f, void *opaque, int version_id) } PXA2xxMMCIState *pxa2xx_mmci_init(target_phys_addr_t base, - BlockDriverState *bd, qemu_irq irq, void *dma) + BlockDriverState *bd, qemu_irq irq, + qemu_irq rx_dma, qemu_irq tx_dma) { int iomemtype; PXA2xxMMCIState *s; - s = (PXA2xxMMCIState *) qemu_mallocz(sizeof(PXA2xxMMCIState)); + s = (PXA2xxMMCIState *) g_malloc0(sizeof(PXA2xxMMCIState)); s->irq = irq; - s->dma = dma; + s->rx_dma = rx_dma; + s->tx_dma = tx_dma; iomemtype = cpu_register_io_memory(pxa2xx_mmci_readfn, pxa2xx_mmci_writefn, s, DEVICE_NATIVE_ENDIAN); diff --git a/hw/pxa2xx_pcmcia.c b/hw/pxa2xx_pcmcia.c index 50d4649..74c6817 100644 --- a/hw/pxa2xx_pcmcia.c +++ b/hw/pxa2xx_pcmcia.c @@ -136,7 +136,7 @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(target_phys_addr_t base) PXA2xxPCMCIAState *s; s = (PXA2xxPCMCIAState *) - qemu_mallocz(sizeof(PXA2xxPCMCIAState)); + g_malloc0(sizeof(PXA2xxPCMCIAState)); /* Socket I/O Memory Space */ iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn, diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c index a36da23..bdd82e6 100644 --- a/hw/pxa2xx_pic.c +++ b/hw/pxa2xx_pic.c @@ -5,11 +5,12 @@ * Copyright (c) 2006 Thorsten Zitterell * Written by Andrzej Zaborowski * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "hw.h" #include "pxa.h" +#include "sysbus.h" #define ICIP 0x00 /* Interrupt Controller IRQ Pending register */ #define ICMR 0x04 /* Interrupt Controller Mask register */ @@ -31,6 +32,7 @@ #define PXA2XX_PIC_SRCS 40 typedef struct { + SysBusDevice busdev; CPUState *cpu_env; uint32_t int_enabled[2]; uint32_t int_pending[2]; @@ -241,51 +243,17 @@ static CPUWriteMemoryFunc * const pxa2xx_pic_writefn[] = { pxa2xx_pic_mem_write, }; -static void pxa2xx_pic_save(QEMUFile *f, void *opaque) +static int pxa2xx_pic_post_load(void *opaque, int version_id) { - PXA2xxPICState *s = (PXA2xxPICState *) opaque; - int i; - - for (i = 0; i < 2; i ++) - qemu_put_be32s(f, &s->int_enabled[i]); - for (i = 0; i < 2; i ++) - qemu_put_be32s(f, &s->int_pending[i]); - for (i = 0; i < 2; i ++) - qemu_put_be32s(f, &s->is_fiq[i]); - qemu_put_be32s(f, &s->int_idle); - for (i = 0; i < PXA2XX_PIC_SRCS; i ++) - qemu_put_be32s(f, &s->priority[i]); -} - -static int pxa2xx_pic_load(QEMUFile *f, void *opaque, int version_id) -{ - PXA2xxPICState *s = (PXA2xxPICState *) opaque; - int i; - - for (i = 0; i < 2; i ++) - qemu_get_be32s(f, &s->int_enabled[i]); - for (i = 0; i < 2; i ++) - qemu_get_be32s(f, &s->int_pending[i]); - for (i = 0; i < 2; i ++) - qemu_get_be32s(f, &s->is_fiq[i]); - qemu_get_be32s(f, &s->int_idle); - for (i = 0; i < PXA2XX_PIC_SRCS; i ++) - qemu_get_be32s(f, &s->priority[i]); - pxa2xx_pic_update(opaque); return 0; } -qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env) +DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env) { - PXA2xxPICState *s; + DeviceState *dev = qdev_create(NULL, "pxa2xx_pic"); int iomemtype; - qemu_irq *qi; - - s = (PXA2xxPICState *) - qemu_mallocz(sizeof(PXA2xxPICState)); - if (!s) - return NULL; + PXA2xxPICState *s = FROM_SYSBUS(PXA2xxPICState, sysbus_from_qdev(dev)); s->cpu_env = env; @@ -296,18 +264,53 @@ qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env) s->is_fiq[0] = 0; s->is_fiq[1] = 0; - qi = qemu_allocate_irqs(pxa2xx_pic_set_irq, s, PXA2XX_PIC_SRCS); + qdev_init_nofail(dev); + + qdev_init_gpio_in(dev, pxa2xx_pic_set_irq, PXA2XX_PIC_SRCS); /* Enable IC memory-mapped registers access. */ iomemtype = cpu_register_io_memory(pxa2xx_pic_readfn, pxa2xx_pic_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x00100000, iomemtype); + sysbus_init_mmio(sysbus_from_qdev(dev), 0x00100000, iomemtype); + sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); /* Enable IC coprocessor access. */ cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, s); - register_savevm(NULL, "pxa2xx_pic", 0, 0, pxa2xx_pic_save, - pxa2xx_pic_load, s); + return dev; +} + +static VMStateDescription vmstate_pxa2xx_pic_regs = { + .name = "pxa2xx_pic", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = pxa2xx_pic_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(int_enabled, PXA2xxPICState, 2), + VMSTATE_UINT32_ARRAY(int_pending, PXA2xxPICState, 2), + VMSTATE_UINT32_ARRAY(is_fiq, PXA2xxPICState, 2), + VMSTATE_UINT32(int_idle, PXA2xxPICState), + VMSTATE_UINT32_ARRAY(priority, PXA2xxPICState, PXA2XX_PIC_SRCS), + VMSTATE_END_OF_LIST(), + }, +}; - return qi; +static int pxa2xx_pic_initfn(SysBusDevice *dev) +{ + return 0; +} + +static SysBusDeviceInfo pxa2xx_pic_info = { + .init = pxa2xx_pic_initfn, + .qdev.name = "pxa2xx_pic", + .qdev.desc = "PXA2xx PIC", + .qdev.size = sizeof(PXA2xxPICState), + .qdev.vmsd = &vmstate_pxa2xx_pic_regs, +}; + +static void pxa2xx_pic_register(void) +{ + sysbus_register_withprop(&pxa2xx_pic_info); } +device_init(pxa2xx_pic_register); diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c index b556d11..4235e42 100644 --- a/hw/pxa2xx_timer.c +++ b/hw/pxa2xx_timer.c @@ -4,13 +4,14 @@ * Copyright (c) 2006 Openedhand Ltd. * Copyright (c) 2006 Thorsten Zitterell * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "hw.h" #include "qemu-timer.h" #include "sysemu.h" #include "pxa.h" +#include "sysbus.h" #define OSMR0 0x00 #define OSMR1 0x04 @@ -59,13 +60,14 @@ static int pxa2xx_timer4_freq[8] = { [5 ... 7] = 0, }; +typedef struct PXA2xxTimerInfo PXA2xxTimerInfo; + typedef struct { uint32_t value; - int level; qemu_irq irq; QEMUTimer *qtimer; int num; - void *info; + PXA2xxTimerInfo *info; } PXA2xxTimer0; typedef struct { @@ -77,22 +79,34 @@ typedef struct { uint32_t control; } PXA2xxTimer4; -typedef struct { +struct PXA2xxTimerInfo { + SysBusDevice busdev; + uint32_t flags; + int32_t clock; int32_t oldclock; uint64_t lastload; uint32_t freq; PXA2xxTimer0 timer[4]; - PXA2xxTimer4 *tm4; uint32_t events; uint32_t irq_enabled; uint32_t reset3; uint32_t snapshot; -} pxa2xx_timer_info; + + qemu_irq irq4; + PXA2xxTimer4 tm4[8]; +}; + +#define PXA2XX_TIMER_HAVE_TM4 0 + +static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s) +{ + return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4); +} static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu) { - pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; + PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; int i; uint32_t now_vm; uint64_t new_qemu; @@ -109,7 +123,7 @@ static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu) static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) { - pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; + PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; uint32_t now_vm; uint64_t new_qemu; static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 }; @@ -136,7 +150,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) { - pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; + PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; int tm = 0; switch (offset) { @@ -153,11 +167,11 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) case OSMR6: tm ++; case OSMR5: tm ++; case OSMR4: - if (!s->tm4) + if (!pxa2xx_timer_has_tm4(s)) goto badreg; return s->tm4[tm].tm.value; case OSCR: - return s->clock + muldiv64(qemu_get_clock(vm_clock) - + return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) - s->lastload, s->freq, get_ticks_per_sec()); case OSCR11: tm ++; case OSCR10: tm ++; @@ -167,13 +181,13 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) case OSCR6: tm ++; case OSCR5: tm ++; case OSCR4: - if (!s->tm4) + if (!pxa2xx_timer_has_tm4(s)) goto badreg; if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) { if (s->tm4[tm - 1].freq) s->snapshot = s->tm4[tm - 1].clock + muldiv64( - qemu_get_clock(vm_clock) - + qemu_get_clock_ns(vm_clock) - s->tm4[tm - 1].lastload, s->tm4[tm - 1].freq, get_ticks_per_sec()); else @@ -182,7 +196,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) if (!s->tm4[tm].freq) return s->tm4[tm].clock; - return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) - + return s->tm4[tm].clock + muldiv64(qemu_get_clock_ns(vm_clock) - s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec()); case OIER: return s->irq_enabled; @@ -198,7 +212,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset) case OMCR6: tm ++; case OMCR5: tm ++; case OMCR4: - if (!s->tm4) + if (!pxa2xx_timer_has_tm4(s)) goto badreg; return s->tm4[tm].control; case OSNR: @@ -215,7 +229,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, uint32_t value) { int i, tm = 0; - pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; + PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; switch (offset) { case OSMR3: tm ++; @@ -223,7 +237,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, case OSMR1: tm ++; case OSMR0: s->timer[tm].value = value; - pxa2xx_timer_update(s, qemu_get_clock(vm_clock)); + pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock)); break; case OSMR11: tm ++; case OSMR10: tm ++; @@ -233,14 +247,14 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, case OSMR6: tm ++; case OSMR5: tm ++; case OSMR4: - if (!s->tm4) + if (!pxa2xx_timer_has_tm4(s)) goto badreg; s->tm4[tm].tm.value = value; - pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm); + pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm); break; case OSCR: s->oldclock = s->clock; - s->lastload = qemu_get_clock(vm_clock); + s->lastload = qemu_get_clock_ns(vm_clock); s->clock = value; pxa2xx_timer_update(s, s->lastload); break; @@ -252,10 +266,10 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, case OSCR6: tm ++; case OSCR5: tm ++; case OSCR4: - if (!s->tm4) + if (!pxa2xx_timer_has_tm4(s)) goto badreg; s->tm4[tm].oldclock = s->tm4[tm].clock; - s->tm4[tm].lastload = qemu_get_clock(vm_clock); + s->tm4[tm].lastload = qemu_get_clock_ns(vm_clock); s->tm4[tm].clock = value; pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm); break; @@ -263,20 +277,13 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, s->irq_enabled = value & 0xfff; break; case OSSR: /* Status register */ + value &= s->events; s->events &= ~value; - for (i = 0; i < 4; i ++, value >>= 1) { - if (s->timer[i].level && (value & 1)) { - s->timer[i].level = 0; + for (i = 0; i < 4; i ++, value >>= 1) + if (value & 1) qemu_irq_lower(s->timer[i].irq); - } - } - if (s->tm4) { - for (i = 0; i < 8; i ++, value >>= 1) - if (s->tm4[i].tm.level && (value & 1)) - s->tm4[i].tm.level = 0; - if (!(s->events & 0xff0)) - qemu_irq_lower(s->tm4->tm.irq); - } + if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value) + qemu_irq_lower(s->irq4); break; case OWER: /* XXX: Reset on OSMR3 match? */ s->reset3 = value; @@ -285,7 +292,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, case OMCR6: tm ++; case OMCR5: tm ++; case OMCR4: - if (!s->tm4) + if (!pxa2xx_timer_has_tm4(s)) goto badreg; s->tm4[tm].control = value & 0x0ff; /* XXX Stop if running (shouldn't happen) */ @@ -293,14 +300,14 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7]; else { s->tm4[tm].freq = 0; - pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm); + pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm); } break; case OMCR11: tm ++; case OMCR10: tm ++; case OMCR9: tm ++; case OMCR8: tm += 4; - if (!s->tm4) + if (!pxa2xx_timer_has_tm4(s)) goto badreg; s->tm4[tm].control = value & 0x3ff; /* XXX Stop if running (shouldn't happen) */ @@ -309,7 +316,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset, pxa2xx_timer4_freq[(value & (1 << 8)) ? 0 : (value & 7)]; else { s->tm4[tm].freq = 0; - pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm); + pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm); } break; default: @@ -333,10 +340,9 @@ static CPUWriteMemoryFunc * const pxa2xx_timer_writefn[] = { static void pxa2xx_timer_tick(void *opaque) { PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque; - pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info; + PXA2xxTimerInfo *i = t->info; if (i->irq_enabled & (1 << t->num)) { - t->level = 1; i->events |= 1 << t->num; qemu_irq_raise(t->irq); } @@ -351,140 +357,162 @@ static void pxa2xx_timer_tick(void *opaque) static void pxa2xx_timer_tick4(void *opaque) { PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque; - pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->tm.info; + PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info; pxa2xx_timer_tick(&t->tm); if (t->control & (1 << 3)) t->clock = 0; if (t->control & (1 << 6)) - pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4); -} - -static void pxa2xx_timer_save(QEMUFile *f, void *opaque) -{ - pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; - int i; - - qemu_put_be32s(f, (uint32_t *) &s->clock); - qemu_put_be32s(f, (uint32_t *) &s->oldclock); - qemu_put_be64s(f, &s->lastload); - - for (i = 0; i < 4; i ++) { - qemu_put_be32s(f, &s->timer[i].value); - qemu_put_be32(f, s->timer[i].level); - } - if (s->tm4) - for (i = 0; i < 8; i ++) { - qemu_put_be32s(f, &s->tm4[i].tm.value); - qemu_put_be32(f, s->tm4[i].tm.level); - qemu_put_sbe32s(f, &s->tm4[i].oldclock); - qemu_put_sbe32s(f, &s->tm4[i].clock); - qemu_put_be64s(f, &s->tm4[i].lastload); - qemu_put_be32s(f, &s->tm4[i].freq); - qemu_put_be32s(f, &s->tm4[i].control); - } - - qemu_put_be32s(f, &s->events); - qemu_put_be32s(f, &s->irq_enabled); - qemu_put_be32s(f, &s->reset3); - qemu_put_be32s(f, &s->snapshot); + pxa2xx_timer_update4(i, qemu_get_clock_ns(vm_clock), t->tm.num - 4); + if (i->events & 0xff0) + qemu_irq_raise(i->irq4); } -static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id) +static int pxa25x_timer_post_load(void *opaque, int version_id) { - pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; + PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; int64_t now; int i; - qemu_get_be32s(f, (uint32_t *) &s->clock); - qemu_get_be32s(f, (uint32_t *) &s->oldclock); - qemu_get_be64s(f, &s->lastload); - - now = qemu_get_clock(vm_clock); - for (i = 0; i < 4; i ++) { - qemu_get_be32s(f, &s->timer[i].value); - s->timer[i].level = qemu_get_be32(f); - } + now = qemu_get_clock_ns(vm_clock); pxa2xx_timer_update(s, now); - if (s->tm4) - for (i = 0; i < 8; i ++) { - qemu_get_be32s(f, &s->tm4[i].tm.value); - s->tm4[i].tm.level = qemu_get_be32(f); - qemu_get_sbe32s(f, &s->tm4[i].oldclock); - qemu_get_sbe32s(f, &s->tm4[i].clock); - qemu_get_be64s(f, &s->tm4[i].lastload); - qemu_get_be32s(f, &s->tm4[i].freq); - qemu_get_be32s(f, &s->tm4[i].control); + if (pxa2xx_timer_has_tm4(s)) + for (i = 0; i < 8; i ++) pxa2xx_timer_update4(s, now, i); - } - - qemu_get_be32s(f, &s->events); - qemu_get_be32s(f, &s->irq_enabled); - qemu_get_be32s(f, &s->reset3); - qemu_get_be32s(f, &s->snapshot); return 0; } -static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, - qemu_irq *irqs) +static int pxa2xx_timer_init(SysBusDevice *dev) { int i; int iomemtype; - pxa2xx_timer_info *s; + PXA2xxTimerInfo *s; - s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info)); + s = FROM_SYSBUS(PXA2xxTimerInfo, dev); s->irq_enabled = 0; s->oldclock = 0; s->clock = 0; - s->lastload = qemu_get_clock(vm_clock); + s->lastload = qemu_get_clock_ns(vm_clock); s->reset3 = 0; for (i = 0; i < 4; i ++) { s->timer[i].value = 0; - s->timer[i].irq = irqs[i]; + sysbus_init_irq(dev, &s->timer[i].irq); s->timer[i].info = s; s->timer[i].num = i; - s->timer[i].level = 0; - s->timer[i].qtimer = qemu_new_timer(vm_clock, + s->timer[i].qtimer = qemu_new_timer_ns(vm_clock, pxa2xx_timer_tick, &s->timer[i]); } + if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) { + sysbus_init_irq(dev, &s->irq4); + + for (i = 0; i < 8; i ++) { + s->tm4[i].tm.value = 0; + s->tm4[i].tm.info = s; + s->tm4[i].tm.num = i + 4; + s->tm4[i].freq = 0; + s->tm4[i].control = 0x0; + s->tm4[i].tm.qtimer = qemu_new_timer_ns(vm_clock, + pxa2xx_timer_tick4, &s->tm4[i]); + } + } iomemtype = cpu_register_io_memory(pxa2xx_timer_readfn, pxa2xx_timer_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x00001000, iomemtype); + sysbus_init_mmio(dev, 0x00001000, iomemtype); - register_savevm(NULL, "pxa2xx_timer", 0, 0, - pxa2xx_timer_save, pxa2xx_timer_load, s); - - return s; + return 0; } -void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs) +static const VMStateDescription vmstate_pxa2xx_timer0_regs = { + .name = "pxa2xx_timer0", + .version_id = 2, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .fields = (VMStateField[]) { + VMSTATE_UINT32(value, PXA2xxTimer0), + VMSTATE_END_OF_LIST(), + }, +}; + +static const VMStateDescription vmstate_pxa2xx_timer4_regs = { + .name = "pxa2xx_timer4", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(tm, PXA2xxTimer4, 1, + vmstate_pxa2xx_timer0_regs, PXA2xxTimer0), + VMSTATE_INT32(oldclock, PXA2xxTimer4), + VMSTATE_INT32(clock, PXA2xxTimer4), + VMSTATE_UINT64(lastload, PXA2xxTimer4), + VMSTATE_UINT32(freq, PXA2xxTimer4), + VMSTATE_UINT32(control, PXA2xxTimer4), + VMSTATE_END_OF_LIST(), + }, +}; + +static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id) { - pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs); - s->freq = PXA25X_FREQ; - s->tm4 = NULL; + return pxa2xx_timer_has_tm4(opaque); } -void pxa27x_timer_init(target_phys_addr_t base, - qemu_irq *irqs, qemu_irq irq4) -{ - pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs); - int i; - s->freq = PXA27X_FREQ; - s->tm4 = (PXA2xxTimer4 *) qemu_mallocz(8 * - sizeof(PXA2xxTimer4)); - for (i = 0; i < 8; i ++) { - s->tm4[i].tm.value = 0; - s->tm4[i].tm.irq = irq4; - s->tm4[i].tm.info = s; - s->tm4[i].tm.num = i + 4; - s->tm4[i].tm.level = 0; - s->tm4[i].freq = 0; - s->tm4[i].control = 0x0; - s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock, - pxa2xx_timer_tick4, &s->tm4[i]); +static const VMStateDescription vmstate_pxa2xx_timer_regs = { + .name = "pxa2xx_timer", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = pxa25x_timer_post_load, + .fields = (VMStateField[]) { + VMSTATE_INT32(clock, PXA2xxTimerInfo), + VMSTATE_INT32(oldclock, PXA2xxTimerInfo), + VMSTATE_UINT64(lastload, PXA2xxTimerInfo), + VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1, + vmstate_pxa2xx_timer0_regs, PXA2xxTimer0), + VMSTATE_UINT32(events, PXA2xxTimerInfo), + VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo), + VMSTATE_UINT32(reset3, PXA2xxTimerInfo), + VMSTATE_UINT32(snapshot, PXA2xxTimerInfo), + VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8, + pxa2xx_timer_has_tm4_test, 0, + vmstate_pxa2xx_timer4_regs, PXA2xxTimer4), + VMSTATE_END_OF_LIST(), } -} +}; + +static SysBusDeviceInfo pxa25x_timer_dev_info = { + .init = pxa2xx_timer_init, + .qdev.name = "pxa25x-timer", + .qdev.desc = "PXA25x timer", + .qdev.size = sizeof(PXA2xxTimerInfo), + .qdev.vmsd = &vmstate_pxa2xx_timer_regs, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ), + DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags, + PXA2XX_TIMER_HAVE_TM4, false), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static SysBusDeviceInfo pxa27x_timer_dev_info = { + .init = pxa2xx_timer_init, + .qdev.name = "pxa27x-timer", + .qdev.desc = "PXA27x timer", + .qdev.size = sizeof(PXA2xxTimerInfo), + .qdev.vmsd = &vmstate_pxa2xx_timer_regs, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ), + DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags, + PXA2XX_TIMER_HAVE_TM4, true), + DEFINE_PROP_END_OF_LIST(), + }, +}; + +static void pxa2xx_timer_register(void) +{ + sysbus_register_withprop(&pxa25x_timer_dev_info); + sysbus_register_withprop(&pxa27x_timer_dev_info); +}; +device_init(pxa2xx_timer_register); diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index a493087..f0b811c 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -51,7 +51,7 @@ static int parse_bit(DeviceState *dev, Property *prop, const char *str) static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len) { - uint8_t *p = qdev_get_prop_ptr(dev, prop); + uint32_t *p = qdev_get_prop_ptr(dev, prop); return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off"); } @@ -93,6 +93,35 @@ PropertyInfo qdev_prop_uint8 = { .print = print_uint8, }; +/* --- 8bit hex value --- */ + +static int parse_hex8(DeviceState *dev, Property *prop, const char *str) +{ + uint8_t *ptr = qdev_get_prop_ptr(dev, prop); + char *end; + + *ptr = strtoul(str, &end, 16); + if ((*end != '\0') || (end == str)) { + return -EINVAL; + } + + return 0; +} + +static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + uint8_t *ptr = qdev_get_prop_ptr(dev, prop); + return snprintf(dest, len, "0x%" PRIx8, *ptr); +} + +PropertyInfo qdev_prop_hex8 = { + .name = "hex8", + .type = PROP_TYPE_UINT8, + .size = sizeof(uint8_t), + .parse = parse_hex8, + .print = print_hex8, +}; + /* --- 16bit integer --- */ static int parse_uint16(DeviceState *dev, Property *prop, const char *str) @@ -275,14 +304,14 @@ static int parse_string(DeviceState *dev, Property *prop, const char *str) char **ptr = qdev_get_prop_ptr(dev, prop); if (*ptr) - qemu_free(*ptr); - *ptr = qemu_strdup(str); + g_free(*ptr); + *ptr = g_strdup(str); return 0; } static void free_string(DeviceState *dev, Property *prop) { - qemu_free(*(char **)qdev_get_prop_ptr(dev, prop)); + g_free(*(char **)qdev_get_prop_ptr(dev, prop)); } static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len) @@ -312,7 +341,7 @@ static int parse_drive(DeviceState *dev, Property *prop, const char *str) bs = bdrv_find(str); if (bs == NULL) return -ENOENT; - if (bdrv_attach(bs, dev) < 0) + if (bdrv_attach_dev(bs, dev) < 0) return -EEXIST; *ptr = bs; return 0; @@ -323,7 +352,7 @@ static void free_drive(DeviceState *dev, Property *prop) BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); if (*ptr) { - bdrv_detach(*ptr, dev); + bdrv_detach_dev(*ptr, dev); blockdev_auto_del(*ptr); } } @@ -351,8 +380,13 @@ static int parse_chr(DeviceState *dev, Property *prop, const char *str) CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); *ptr = qemu_chr_find(str); - if (*ptr == NULL) + if (*ptr == NULL) { return -ENOENT; + } + if ((*ptr)->avail_connections < 1) { + return -EEXIST; + } + --(*ptr)->avail_connections; return 0; } @@ -519,6 +553,8 @@ static int parse_pci_devfn(DeviceState *dev, Property *prop, const char *str) return -EINVAL; if (fn > 7) return -EINVAL; + if (slot > 31) + return -EINVAL; *ptr = slot << 3 | fn; return 0; } @@ -673,7 +709,7 @@ int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *va { int res; - res = bdrv_attach(value, dev); + res = bdrv_attach_dev(value, dev); if (res < 0) { error_report("Can't attach drive %s to %s.%s: %s", bdrv_get_device_name(value), @@ -763,7 +799,7 @@ static int qdev_add_one_global(QemuOpts *opts, void *opaque) { GlobalProperty *g; - g = qemu_mallocz(sizeof(*g)); + g = g_malloc0(sizeof(*g)); g->driver = qemu_opt_get(opts, "driver"); g->property = qemu_opt_get(opts, "property"); g->value = qemu_opt_get(opts, "value"); diff --git a/hw/qdev.c b/hw/qdev.c index c7fec44..106407f 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -36,6 +36,7 @@ static bool qdev_hot_removed = false; /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ static BusState *main_system_bus; +static void main_system_bus_create(void); DeviceInfo *device_info_list; @@ -84,13 +85,13 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info) DeviceState *dev; assert(bus->info == info->bus_info); - dev = qemu_mallocz(info->size); + dev = g_malloc0(info->size); dev->info = info; dev->parent_bus = bus; qdev_prop_set_defaults(dev, dev->info->props); qdev_prop_set_defaults(dev, dev->parent_bus->info->props); qdev_prop_set_globals(dev); - QLIST_INSERT_HEAD(&bus->children, dev, sibling); + QTAILQ_INSERT_HEAD(&bus->children, dev, sibling); if (qdev_hotplug) { assert(bus->allow_hotplug); dev->hotplugged = 1; @@ -106,6 +107,23 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info) initialize the actual device emulation. */ DeviceState *qdev_create(BusState *bus, const char *name) { + DeviceState *dev; + + dev = qdev_try_create(bus, name); + if (!dev) { + if (bus) { + hw_error("Unknown device '%s' for bus '%s'\n", name, + bus->info->name); + } else { + hw_error("Unknown device '%s' for default sysbus\n", name); + } + } + + return dev; +} + +DeviceState *qdev_try_create(BusState *bus, const char *name) +{ DeviceInfo *info; if (!bus) { @@ -114,7 +132,7 @@ DeviceState *qdev_create(BusState *bus, const char *name) info = qdev_find_info(bus->info, name); if (!info) { - hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name); + return NULL; } return qdev_create_from_info(bus, info); @@ -168,7 +186,7 @@ int qdev_device_help(QemuOpts *opts) return 1; } - if (!qemu_opt_get(opts, "?")) { + if (!driver || !qemu_opt_get(opts, "?")) { return 0; } @@ -189,6 +207,12 @@ int qdev_device_help(QemuOpts *opts) } error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name); } + for (prop = info->bus_info->props; prop && prop->name; prop++) { + if (!prop->info->parse) { + continue; /* no way to set it, don't show */ + } + error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name); + } return 1; } @@ -277,6 +301,9 @@ int qdev_init(DeviceState *dev) dev->alias_required_for_version); } dev->state = DEV_STATE_INITIALIZED; + if (dev->hotplugged && dev->info->reset) { + dev->info->reset(dev); + } return 0; } @@ -313,8 +340,7 @@ static int qdev_reset_one(DeviceState *dev, void *opaque) BusState *sysbus_get_default(void) { if (!main_system_bus) { - main_system_bus = qbus_create(&system_bus_info, NULL, - "main-system-bus"); + main_system_bus_create(); } return main_system_bus; } @@ -346,7 +372,8 @@ int qdev_simple_unplug_cb(DeviceState *dev) return 0; } -/* Like qdev_init(), but terminate program via hw_error() instead of + +/* Like qdev_init(), but terminate program via error_report() instead of returning an error value. This is okay during machine creation. Don't use for hotplug, because there callers need to recover from failure. Exception: if you know the device's init() callback can't @@ -358,7 +385,7 @@ void qdev_init_nofail(DeviceState *dev) DeviceInfo *info = dev->info; if (qdev_init(dev) < 0) { - error_report("Initialization of device %s failed\n", info->name); + error_report("Initialization of device %s failed", info->name); exit(1); } } @@ -381,13 +408,13 @@ void qdev_free(DeviceState *dev) if (dev->opts) qemu_opts_del(dev->opts); } - QLIST_REMOVE(dev, sibling); + QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling); for (prop = dev->info->props; prop && prop->name; prop++) { if (prop->info->free) { prop->info->free(dev, prop); } } - qemu_free(dev); + g_free(dev); } void qdev_machine_creation_done(void) @@ -446,7 +473,7 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) { - qdev_prop_set_macaddr(dev, "mac", nd->macaddr); + qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a); if (nd->vlan) qdev_prop_set_vlan(dev, "vlan", nd->vlan); if (nd->netdev) @@ -455,6 +482,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) qdev_prop_exists(dev, "vectors")) { qdev_prop_set_uint32(dev, "vectors", nd->nvectors); } + nd->instantiated = 1; } BusState *qdev_get_child_bus(DeviceState *dev, const char *name) @@ -482,7 +510,7 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, } } - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { err = qdev_walk_children(dev, devfn, busfn, opaque); if (err < 0) { return err; @@ -532,7 +560,7 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, return bus; } - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { QLIST_FOREACH(child, &dev->child_bus, sibling) { ret = qbus_find_recursive(child, name, info); if (ret) { @@ -548,7 +576,7 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id) DeviceState *dev, *ret; BusState *child; - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { if (dev->id && strcmp(dev->id, id) == 0) return dev; QLIST_FOREACH(child, &dev->child_bus, sibling) { @@ -581,7 +609,7 @@ static void qbus_list_dev(BusState *bus) const char *sep = " "; error_printf("devices at \"%s\":", bus->name); - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { error_printf("%s\"%s\"", sep, dev->info->name); if (dev->id) error_printf("/\"%s\"", dev->id); @@ -612,17 +640,17 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem) * (2) driver name * (3) driver alias, if present */ - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { if (dev->id && strcmp(dev->id, elem) == 0) { return dev; } } - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { if (strcmp(dev->info->name, elem) == 0) { return dev; } } - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) { return dev; } @@ -728,17 +756,17 @@ void qbus_create_inplace(BusState *bus, BusInfo *info, if (name) { /* use supplied name */ - bus->name = qemu_strdup(name); + bus->name = g_strdup(name); } else if (parent && parent->id) { /* parent device has id -> use it for bus name */ len = strlen(parent->id) + 16; - buf = qemu_malloc(len); + buf = g_malloc(len); snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus); bus->name = buf; } else { /* no id -> use lowercase bus type for bus name */ len = strlen(info->name) + 16; - buf = qemu_malloc(len); + buf = g_malloc(len); len = snprintf(buf, len, "%s.%d", info->name, parent ? parent->num_child_bus : 0); for (i = 0; i < len; i++) @@ -746,7 +774,7 @@ void qbus_create_inplace(BusState *bus, BusInfo *info, bus->name = buf; } - QLIST_INIT(&bus->children); + QTAILQ_INIT(&bus->children); if (parent) { QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling); parent->num_child_bus++; @@ -761,17 +789,27 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name) { BusState *bus; - bus = qemu_mallocz(info->size); + bus = g_malloc0(info->size); bus->qdev_allocated = 1; qbus_create_inplace(bus, info, parent, name); return bus; } +static void main_system_bus_create(void) +{ + /* assign main_system_bus before qbus_create_inplace() + * in order to make "if (bus != main_system_bus)" work */ + main_system_bus = g_malloc0(system_bus_info.size); + main_system_bus->qdev_allocated = 1; + qbus_create_inplace(main_system_bus, &system_bus_info, NULL, + "main-system-bus"); +} + void qbus_free(BusState *bus) { DeviceState *dev; - while ((dev = QLIST_FIRST(&bus->children)) != NULL) { + while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) { qdev_free(dev); } if (bus->parent) { @@ -781,9 +819,9 @@ void qbus_free(BusState *bus) assert(bus != main_system_bus); /* main_system_bus is never freed */ qemu_unregister_reset(qbus_reset_all_fn, bus); } - qemu_free((void*)bus->name); + g_free((void*)bus->name); if (bus->qdev_allocated) { - qemu_free(bus); + g_free(bus); } } @@ -840,7 +878,7 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent) qdev_printf("bus: %s\n", bus->name); indent += 2; qdev_printf("type %s\n", bus->info->name); - QLIST_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(dev, &bus->children, sibling) { qdev_print(mon, dev, indent); } } @@ -903,7 +941,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) if (dev->parent_bus->info->get_fw_dev_path) { d = dev->parent_bus->info->get_fw_dev_path(dev); l += snprintf(p + l, size - l, "%s", d); - qemu_free(d); + g_free(d); } else { l += snprintf(p + l, size - l, "%s", dev->info->name); } diff --git a/hw/qdev.h b/hw/qdev.h index 9808f85..36a4198 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -42,7 +42,7 @@ struct DeviceState { qemu_irq *gpio_in; QLIST_HEAD(, BusState) child_bus; int num_child_bus; - QLIST_ENTRY(DeviceState) sibling; + QTAILQ_ENTRY(DeviceState) sibling; int instance_id_alias; int alias_required_for_version; }; @@ -73,7 +73,7 @@ struct BusState { const char *name; int allow_hotplug; int qdev_allocated; - QLIST_HEAD(, DeviceState) children; + QTAILQ_HEAD(ChildrenHead, DeviceState) children; QLIST_ENTRY(BusState) sibling; }; @@ -122,6 +122,7 @@ typedef struct GlobalProperty { /*** Board API. This should go away once we have a machine config file. ***/ DeviceState *qdev_create(BusState *bus, const char *name); +DeviceState *qdev_try_create(BusState *bus, const char *name); int qdev_device_help(QemuOpts *opts); DeviceState *qdev_device_add(QemuOpts *opts); int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT; @@ -223,6 +224,7 @@ extern PropertyInfo qdev_prop_uint16; extern PropertyInfo qdev_prop_uint32; extern PropertyInfo qdev_prop_int32; extern PropertyInfo qdev_prop_uint64; +extern PropertyInfo qdev_prop_hex8; extern PropertyInfo qdev_prop_hex32; extern PropertyInfo qdev_prop_hex64; extern PropertyInfo qdev_prop_string; @@ -266,6 +268,8 @@ extern PropertyInfo qdev_prop_pci_devfn; DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t) #define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) +#define DEFINE_PROP_HEX8(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t) #define DEFINE_PROP_HEX32(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t) #define DEFINE_PROP_HEX64(_n, _s, _f, _d) \ diff --git a/hw/qt602240_ts.c b/hw/qt602240_ts.c deleted file mode 100644 index 8530d21..0000000 --- a/hw/qt602240_ts.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * AT42QT602240 Touchscreen - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Alexey Merkulov - * Dmitry Zhurikhin - * Vladimir Monakhov - * - * NB: Only features used in the kernel driver is implemented currently. - */ - -#include "console.h" -#include "i2c-addressable.h" - -/* Object types */ -#define QT602240_DEBUG_DELTAS 2 -#define QT602240_DEBUG_REFERENCES 3 -#define QT602240_DEBUG_CTERANGE 26 -#define QT602240_GEN_MESSAGE 5 -#define QT602240_GEN_COMMAND 6 -#define QT602240_GEN_POWER 7 -#define QT602240_GEN_ACQUIRE 8 -#define QT602240_TOUCH_MULTI 9 -#define QT602240_TOUCH_KEYARRAY 15 -#define QT602240_PROCI_GRIPFACE 20 -#define QT602240_PROCG_NOISE 22 -#define QT602240_PROCI_ONETOUCH 24 -#define QT602240_PROCI_TWOTOUCH 27 -#define QT602240_SPT_GPIOPWM 19 -#define QT602240_SPT_SELFTEST 25 -#define QT602240_SPT_CTECONFIG 28 - -/* Orient */ -#define QT602240_NORMAL 0x0 -#define QT602240_DIAGONAL 0x1 -#define QT602240_HORIZONTAL_FLIP 0x2 -#define QT602240_ROTATED_90_COUNTER 0x3 -#define QT602240_VERTICAL_FLIP 0x4 -#define QT602240_ROTATED_90 0x5 -#define QT602240_ROTATED_180 0x6 -#define QT602240_DIAGONAL_COUNTER 0x7 - -/* Touch status */ -#define QT602240_SUPPRESS (1 << 1) -#define QT602240_AMP (1 << 2) -#define QT602240_VECTOR (1 << 3) -#define QT602240_MOVE (1 << 4) -#define QT602240_RELEASE (1 << 5) -#define QT602240_PRESS (1 << 6) -#define QT602240_DETECT (1 << 7) - -/* Message */ -#define QT602240_REPORTID 0 -#define QT602240_MSG_STATUS 1 -#define QT602240_MSG_XPOSMSB 2 -#define QT602240_MSG_YPOSMSB 3 -#define QT602240_MSG_XYPOSLSB 4 -#define QT602240_MSG_TCHAREA 5 -#define QT602240_MSG_TCHAMPLITUDE 6 -#define QT602240_MSG_TCHVECTOR 7 -#define QT602240_CHECKSUM 8 - -/* Message format */ -#define OBJECT_TABLE_MAX_SIZE 16 - -#define OBJ_ADDR_TYPE 0 -#define OBJ_ADDR_START 1 -#define OBJ_ADDR_SIZE 3 -#define OBJ_ADDR_INSTANCES 4 -#define OBJ_ADDR_REPORT_IDS 5 -#define OBJ_SIZE 6 - -/* Size of message queue */ -#define QT602240_MAX_MESSAGE 10 - -#define QEMUMAXX 0x7FFF -#define QEMUMAXY 0x7FFF - -#define FAMILY_ID_SIZE 1 -#define VARIANT_ID_SIZE 1 -#define VERSION_SIZE 1 -#define BUILD_SIZE 1 -#define MATRIX_X_SIZE_SIZE 1 -#define MATRIX_Y_SIZE_SIZE 1 -#define OBJECTS_NUM_SIZE 1 -#define OBJECT_TABLE_SIZE (OBJECT_TABLE_MAX_SIZE * OBJ_SIZE) -#define CHECKSUM_SIZE 1 -#define MESSAGE_SIZE 9 -#define MULTITOUCH_SIZE 30 -#define GENCOMMAND_SIZE 5 -#define SPT_CTECONFIG_SIZE 5 - -#define FAMILY_ID 0 -#define VARIANT_ID (FAMILY_ID + FAMILY_ID_SIZE) -#define VERSION (VARIANT_ID + VARIANT_ID_SIZE) -#define BUILD (VERSION + VERSION_SIZE) -#define MATRIX_X_SIZE (BUILD + BUILD_SIZE) -#define MATRIX_Y_SIZE (MATRIX_X_SIZE + MATRIX_X_SIZE_SIZE) -#define OBJECTS_NUM (MATRIX_Y_SIZE + MATRIX_Y_SIZE_SIZE) -#define OBJECT_TABLE (OBJECTS_NUM + OBJECTS_NUM_SIZE) -#define CHECKSUM (OBJECT_TABLE + OBJECT_TABLE_SIZE) -#define MESSAGE (CHECKSUM + CHECKSUM_SIZE) -#define MULTITOUCH (MESSAGE + MESSAGE_SIZE) -#define GENCOMMAND (MULTITOUCH + MULTITOUCH_SIZE) -#define SPT_CTECONFIG (GENCOMMAND + GENCOMMAND_SIZE) -#define TOTAL_SIZE (SPT_CTECONFIG + SPT_CTECONFIG_SIZE) - -#define MULTITOUCH_CTRL 0 -#define MULTITOUCH_ORIENT 9 -#define MULTITOUCH_XRANGE_LSB 18 -#define MULTITOUCH_XRANGE_MSB 19 -#define MULTITOUCH_YRANGE_LSB 20 -#define MULTITOUCH_YRANGE_MSB 21 - -/* This structure closely correspond to the memory map of the real device. - * We use this property in read\write functions by directly reading\writing - * data at the offsets provided by the driver. It is possible due to proper - * filling of ADDR_START field of each object with this object's structure - * offset in the next structure and byte-to-byte equivalence of each object - * structure to that of the real device. */ -typedef struct QT602240State { - - I2CAddressableState i2c_addressable; - - uint8_t regs[TOTAL_SIZE]; - - /* Supported objects are MESSAGE, MULTITOUCH, SPT_CTECONFIG, GENCOMMAND. */ - - int32_t prev_x, prev_y; - int32_t pressure; - qemu_irq irq; - - /* Messages are stored in a cyclic buffer */ - int32_t queue_start, queue_end; - uint8_t queue[QT602240_MAX_MESSAGE][MESSAGE_SIZE]; - - /* Boundary reported coordinates */ - uint32_t minx, maxx, miny, maxy, orient; -} QT602240State; - -typedef struct QT602240MultitouchMessage { - uint8_t status; - uint8_t xposmsb; - uint8_t yposmsb; - uint8_t xyposlsb; - uint8_t tcharea; - uint8_t tchamplitude; - uint8_t tchvector; -} QT602240MultitouchMessage; - - -/* Add one object to the table */ -static void qt602240_add_object(QT602240State *s, uint16_t offset, - uint8_t size, int type, uint8_t report_ids) -{ - int i; - - for (i = 0; i < OBJECT_TABLE_MAX_SIZE; i++) { - if (s->regs[OBJECT_TABLE + i * OBJ_SIZE + OBJ_ADDR_TYPE] == 0) { - - s->regs[OBJECT_TABLE + i * OBJ_SIZE + OBJ_ADDR_TYPE] = type; - - s->regs[OBJECT_TABLE + i * OBJ_SIZE + OBJ_ADDR_START] = - offset & 0xFF; - - s->regs[OBJECT_TABLE + i * OBJ_SIZE + OBJ_ADDR_START + 1] = - (offset >> 8) & 0xFF; - - s->regs[OBJECT_TABLE + i * OBJ_SIZE + OBJ_ADDR_SIZE] = size - 1; - - s->regs[OBJECT_TABLE + i * OBJ_SIZE + OBJ_ADDR_INSTANCES] = 0; - - s->regs[OBJECT_TABLE + i * OBJ_SIZE + OBJ_ADDR_REPORT_IDS] = report_ids; - - s->regs[OBJECTS_NUM]++; - break; - } - } -} - -/* Reset to default values */ -static void qt602240_reset(DeviceState *d) -{ - QT602240State *s = - FROM_I2CADDR_SLAVE(QT602240State, I2CADDR_SLAVE_FROM_QDEV(d)); - - s->regs[FAMILY_ID] = 0x80; - s->regs[VARIANT_ID] = 0x00; - s->regs[VERSION] = 20; - s->regs[BUILD] = 0x00; - s->regs[MATRIX_X_SIZE] = 16; - s->regs[MATRIX_Y_SIZE] = 14; - s->regs[OBJECTS_NUM] = 0; - - s->minx = 0; - s->maxx = 1; - s->miny = 0; - s->maxy = 1; - - qt602240_add_object(s, MESSAGE, MESSAGE_SIZE, - QT602240_GEN_MESSAGE, 0); - qt602240_add_object(s, MULTITOUCH, MULTITOUCH_SIZE, - QT602240_TOUCH_MULTI, 10); - qt602240_add_object(s, SPT_CTECONFIG, SPT_CTECONFIG_SIZE, - QT602240_SPT_CTECONFIG, 0); - qt602240_add_object(s, GENCOMMAND, GENCOMMAND_SIZE, - QT602240_GEN_COMMAND, 0); - - s->regs[MESSAGE + QT602240_REPORTID] = 0xFF; - - s->queue_start = 0; - s->queue_end = 0; -} - -#define OFFESETOF_MEM(s, mem) ((void *)(&(mem)) - (void *)(s)) - -static uint8_t qt602240_read(void *opaque, uint32_t address, uint8_t offset) -{ - QT602240State *s = (QT602240State *)opaque; - uint8_t retval; - uint32_t reg = address + offset; - - if (reg > TOTAL_SIZE) { - hw_error("qt602240: bad read offset 0x%x\n", reg); - } - - retval = s->regs[reg]; - if (reg >= MESSAGE + QT602240_REPORTID && - reg <= MESSAGE + QT602240_CHECKSUM) { - /* Get message from the queue */ - if (s->queue_start == s->queue_end) { - /* No messages */ - return 0xFF; - } - retval = s->queue[s->queue_start][reg - MESSAGE]; - /* Here is an assumption that message is read till the end */ - if (reg == MESSAGE + QT602240_CHECKSUM) { - /* Move to the next message from the queue */ - s->queue_start = (s->queue_start + 1) % QT602240_MAX_MESSAGE; - if (s->queue_start != s->queue_end) { - qemu_irq_raise(s->irq); // GRS : # of interrupt & # of message does not match - } - } - } - - if(reg == 127){ - return 3; // GRS : Temporary code. Unimplemented reg - } - return retval; -} - -static void qt602240_write(void *opaque, uint32_t address, uint8_t offset, - uint8_t val) -{ - QT602240State *s = (QT602240State *)opaque; - uint32_t reg = address + offset; - - if (reg >= MULTITOUCH && - reg < MULTITOUCH + MULTITOUCH_SIZE) { - s->regs[reg] = val; - - if (reg == MULTITOUCH + MULTITOUCH_ORIENT) { - s->orient = s->regs[reg] & 1; - } - - if (reg == MULTITOUCH + MULTITOUCH_XRANGE_LSB || - reg == MULTITOUCH + MULTITOUCH_XRANGE_MSB) { - int res = s->regs[MULTITOUCH + MULTITOUCH_XRANGE_LSB] + - (s->regs[MULTITOUCH + MULTITOUCH_XRANGE_MSB] << 8) + 1; - - if (s->orient == 0) { - s->maxx = res; - } else { - s->maxy = res; - } - } - - if (reg == MULTITOUCH + MULTITOUCH_YRANGE_LSB || - reg == MULTITOUCH + MULTITOUCH_YRANGE_MSB) { - int res = s->regs[MULTITOUCH + MULTITOUCH_YRANGE_LSB] + - (s->regs[MULTITOUCH + MULTITOUCH_YRANGE_MSB] << 8) + 1; - - if (s->orient == 0) { - s->maxy = res; - } else { - s->maxx = res; - } - } - - } else if (reg >= GENCOMMAND && - reg < GENCOMMAND + GENCOMMAND_SIZE) { - s->regs[reg] = val; - } else if (reg >= SPT_CTECONFIG && - reg < SPT_CTECONFIG + SPT_CTECONFIG_SIZE) { - s->regs[reg] = val; - } else { - hw_error("qt602240: bad write offset 0x%x\n", reg); - } -} - -static int qt602240_enabled(QT602240State *s) -{ - /* Check for ENABLE and RPTEN bits */ - return ((s->regs[MULTITOUCH + MULTITOUCH_CTRL] & 0x3) == 0x3); -} - -/* Modify the message read by the driver */ -static void qt602240_msg(QT602240State *s, int x, int y, int status) -{ - /* Check if queue is full */ - if ((s->queue_end + 1) % QT602240_MAX_MESSAGE == s->queue_start) { - if(status != QT602240_RELEASE){ - return; // GRS : Heuristic - Drag does not finish, by dropping release msg - } - } - - memset(s->queue[s->queue_end], 0, MESSAGE_SIZE); - s->queue[s->queue_end][QT602240_REPORTID] = 2; - s->queue[s->queue_end][QT602240_MSG_XPOSMSB] = x >> 2; - s->queue[s->queue_end][QT602240_MSG_YPOSMSB] = y >> 2; - s->queue[s->queue_end][QT602240_MSG_XYPOSLSB] = - ((x & 3) << 6) | ((y & 3) << 2); - s->queue[s->queue_end][QT602240_MSG_STATUS] = status; - s->queue[s->queue_end][QT602240_MSG_TCHAREA] = 1; - - if ((s->queue_end + 1) % QT602240_MAX_MESSAGE != s->queue_start) { - s->queue_end = (s->queue_end + 1) % QT602240_MAX_MESSAGE; - // GRS : In case of queue full & release msg - drop the last msg instead of release - } - -} - -static void qt602240_ts_event(void *opaque, - int x, int y, int z, int buttons_state) -{ - QT602240State *s = (QT602240State *)opaque; - - if (!qt602240_enabled(s)) { - return; - } - - /* Convert QEMU mouse coordinates to the touchscreen */ - /* FIXME: should we use configuration data provided by the driver? */ - y = (s->miny + y * (s->maxy - s->miny) / QEMUMAXY); - x = (s->minx + x * (s->maxx - s->minx) / QEMUMAXX); - - if (s->pressure == !buttons_state) { - if (buttons_state) { - qt602240_msg(s, x, y, QT602240_PRESS | QT602240_DETECT); - } else { - qt602240_msg(s, x, y, QT602240_RELEASE); - } - qemu_irq_raise(s->irq); - } else if (s->pressure && (x != s->prev_x || y != s->prev_y)) { - static int drop_move = 1; - if(drop_move){ - qt602240_msg(s, x, y, QT602240_MOVE | QT602240_DETECT); - qemu_irq_raise(s->irq); - drop_move = 0; - }else{ - drop_move = 1; - } - } - - s->pressure = !!buttons_state; - s->prev_x = x; - s->prev_y = y; -} - -static void qt602240_save(QEMUFile *f, void *opaque) -{ - QT602240State *s = (QT602240State *)opaque; - int i; - - qemu_put_buffer(f, s->regs, TOTAL_SIZE); - qemu_put_sbe32s(f, &s->prev_x); - qemu_put_sbe32s(f, &s->prev_y); - qemu_put_sbe32s(f, &s->pressure); - qemu_put_sbe32s(f, &s->queue_start); - qemu_put_sbe32s(f, &s->queue_end); - - for (i = 0; i < QT602240_MAX_MESSAGE; i++) { - qemu_put_buffer(f, s->queue[i], MESSAGE_SIZE); - } - - qemu_put_be32s(f, &s->minx); - qemu_put_be32s(f, &s->miny); - qemu_put_be32s(f, &s->maxx); - qemu_put_be32s(f, &s->maxy); - qemu_put_be32s(f, &s->orient); -} - -static int qt602240_load(QEMUFile *f, void *opaque, int version_id) -{ - QT602240State *s = (QT602240State *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_buffer(f, s->regs, TOTAL_SIZE); - qemu_get_sbe32s(f, &s->prev_x); - qemu_get_sbe32s(f, &s->prev_y); - qemu_get_sbe32s(f, &s->pressure); - qemu_get_sbe32s(f, &s->queue_start); - qemu_get_sbe32s(f, &s->queue_end); - - for (i = 0; i < QT602240_MAX_MESSAGE; i++) { - qemu_get_buffer(f, s->queue[i], MESSAGE_SIZE); - } - - qemu_get_be32s(f, &s->minx); - qemu_get_be32s(f, &s->miny); - qemu_get_be32s(f, &s->maxx); - qemu_get_be32s(f, &s->maxy); - qemu_get_be32s(f, &s->orient); - - return 0; -} - -static int qt602240_init(I2CAddressableState *s) -{ - QT602240State *t = FROM_I2CADDR_SLAVE(QT602240State, s); - - qdev_init_gpio_out(&s->i2c.qdev, &t->irq, 1); - - qemu_add_mouse_event_handler(qt602240_ts_event, t, 1, - "AT42QT602240 Touchscreen"); - qt602240_reset(&s->i2c.qdev); - - register_savevm(&s->i2c.qdev, "qt602240", -1, 1, - qt602240_save, qt602240_load, s); - - return 0; -} - -static I2CAddressableDeviceInfo qt602240_info = { - .i2c.qdev.name = "qt602240", - .i2c.qdev.size = sizeof(QT602240State), - .i2c.qdev.reset = qt602240_reset, - .init = qt602240_init, - .read = qt602240_read, - .write = qt602240_write, - .size = 2, - .rev = 0 -}; - -static void qt602240_register_devices(void) -{ - i2c_addressable_register_device(&qt602240_info); -} - -device_init(qt602240_register_devices) diff --git a/hw/qxl-logger.c b/hw/qxl-logger.c index 76f43e6..367aad1 100644 --- a/hw/qxl-logger.c +++ b/hw/qxl-logger.c @@ -19,6 +19,7 @@ * along with this program; if not, see . */ +#include "qemu-timer.h" #include "qxl.h" static const char *qxl_type[] = { @@ -223,7 +224,8 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) if (!qxl->cmdlog) { return; } - fprintf(stderr, "qxl-%d/%s:", qxl->id, ring); + fprintf(stderr, "%" PRId64 " qxl-%d/%s:", qemu_get_clock_ns(vm_clock), + qxl->id, ring); fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data, qxl_name(qxl_type, ext->cmd.type), compat ? "(compat)" : ""); diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 58965e0..2c51ba9 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -28,16 +28,16 @@ static void qxl_flip(PCIQXLDevice *qxl, QXLRect *rect) int len, i; src += (qxl->guest_primary.surface.height - rect->top - 1) * - qxl->guest_primary.stride; - dst += rect->top * qxl->guest_primary.stride; + qxl->guest_primary.abs_stride; + dst += rect->top * qxl->guest_primary.abs_stride; src += rect->left * qxl->guest_primary.bytes_pp; dst += rect->left * qxl->guest_primary.bytes_pp; len = (rect->right - rect->left) * qxl->guest_primary.bytes_pp; for (i = rect->top; i < rect->bottom; i++) { memcpy(dst, src, len); - dst += qxl->guest_primary.stride; - src -= qxl->guest_primary.stride; + dst += qxl->guest_primary.abs_stride; + src -= qxl->guest_primary.abs_stride; } } @@ -45,7 +45,8 @@ void qxl_render_resize(PCIQXLDevice *qxl) { QXLSurfaceCreate *sc = &qxl->guest_primary.surface; - qxl->guest_primary.stride = sc->stride; + qxl->guest_primary.qxl_stride = sc->stride; + qxl->guest_primary.abs_stride = abs(sc->stride); qxl->guest_primary.resized++; switch (sc->format) { case SPICE_SURFACE_FMT_16_555: @@ -75,23 +76,30 @@ void qxl_render_update(PCIQXLDevice *qxl) VGACommonState *vga = &qxl->vga; QXLRect dirty[32], update; void *ptr; - int i; + int i, redraw = 0; + + if (!is_buffer_shared(vga->ds->surface)) { + dprint(qxl, 1, "%s: restoring shared displaysurface\n", __func__); + qxl->guest_primary.resized++; + qxl->guest_primary.commands++; + redraw = 1; + } if (qxl->guest_primary.resized) { qxl->guest_primary.resized = 0; if (qxl->guest_primary.flipped) { - qemu_free(qxl->guest_primary.flipped); + g_free(qxl->guest_primary.flipped); qxl->guest_primary.flipped = NULL; } qemu_free_displaysurface(vga->ds); - qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset); - if (qxl->guest_primary.stride < 0) { + qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram); + if (qxl->guest_primary.qxl_stride < 0) { /* spice surface is upside down -> need extra buffer to flip */ - qxl->guest_primary.stride = -qxl->guest_primary.stride; - qxl->guest_primary.flipped = qemu_malloc(qxl->guest_primary.surface.width * - qxl->guest_primary.stride); + qxl->guest_primary.flipped = + g_malloc(qxl->guest_primary.surface.width * + qxl->guest_primary.abs_stride); ptr = qxl->guest_primary.flipped; } else { ptr = qxl->guest_primary.data; @@ -100,7 +108,7 @@ void qxl_render_update(PCIQXLDevice *qxl) __FUNCTION__, qxl->guest_primary.surface.width, qxl->guest_primary.surface.height, - qxl->guest_primary.stride, + qxl->guest_primary.qxl_stride, qxl->guest_primary.bytes_pp, qxl->guest_primary.bits_pp, qxl->guest_primary.flipped ? "yes" : "no"); @@ -108,7 +116,7 @@ void qxl_render_update(PCIQXLDevice *qxl) qemu_create_displaysurface_from(qxl->guest_primary.surface.width, qxl->guest_primary.surface.height, qxl->guest_primary.bits_pp, - qxl->guest_primary.stride, + qxl->guest_primary.abs_stride, ptr); dpy_resize(vga->ds); } @@ -124,8 +132,12 @@ void qxl_render_update(PCIQXLDevice *qxl) update.bottom = qxl->guest_primary.surface.height; memset(dirty, 0, sizeof(dirty)); - qxl->ssd.worker->update_area(qxl->ssd.worker, 0, &update, - dirty, ARRAY_SIZE(dirty), 1); + qxl_spice_update_area(qxl, 0, &update, + dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC); + if (redraw) { + memset(dirty, 0, sizeof(dirty)); + dirty[0] = update; + } for (i = 0; i < ARRAY_SIZE(dirty); i++) { if (qemu_spice_rect_is_empty(dirty+i)) { @@ -185,7 +197,6 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); QXLCursor *cursor; QEMUCursor *c; - int x = -1, y = -1; if (!qxl->ssd.ds->mouse_set || !qxl->ssd.ds->cursor_define) { return; @@ -198,8 +209,6 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) } switch (cmd->type) { case QXL_CURSOR_SET: - x = cmd->u.set.position.x; - y = cmd->u.set.position.y; cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id); if (cursor->chunk.data_size != cursor->data_size) { fprintf(stderr, "%s: multiple chunks\n", __FUNCTION__); @@ -209,18 +218,20 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) if (c == NULL) { c = cursor_builtin_left_ptr(); } - qemu_mutex_lock_iothread(); - qxl->ssd.ds->cursor_define(c); - qxl->ssd.ds->mouse_set(x, y, 1); - qemu_mutex_unlock_iothread(); - cursor_put(c); + qemu_mutex_lock(&qxl->ssd.lock); + if (qxl->ssd.cursor) { + cursor_put(qxl->ssd.cursor); + } + qxl->ssd.cursor = c; + qxl->ssd.mouse_x = cmd->u.set.position.x; + qxl->ssd.mouse_y = cmd->u.set.position.y; + qemu_mutex_unlock(&qxl->ssd.lock); break; case QXL_CURSOR_MOVE: - x = cmd->u.position.x; - y = cmd->u.position.y; - qemu_mutex_lock_iothread(); - qxl->ssd.ds->mouse_set(x, y, 1); - qemu_mutex_unlock_iothread(); + qemu_mutex_lock(&qxl->ssd.lock); + qxl->ssd.mouse_x = cmd->u.position.x; + qxl->ssd.mouse_y = cmd->u.position.y; + qemu_mutex_unlock(&qxl->ssd.lock); break; } } diff --git a/hw/qxl.c b/hw/qxl.c index fe4212b..41500e9 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -18,8 +18,6 @@ * along with this program; if not, see . */ -#include - #include "qemu-common.h" #include "qemu-timer.h" #include "qemu-queue.h" @@ -120,11 +118,130 @@ static QXLMode qxl_modes[] = { static PCIQXLDevice *qxl0; static void qxl_send_events(PCIQXLDevice *d, uint32_t events); -static void qxl_destroy_primary(PCIQXLDevice *d); +static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async); static void qxl_reset_memslots(PCIQXLDevice *d); static void qxl_reset_surfaces(PCIQXLDevice *d); static void qxl_ring_set_dirty(PCIQXLDevice *qxl); +void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) +{ +#if SPICE_INTERFACE_QXL_MINOR >= 1 + qxl_send_events(qxl, QXL_INTERRUPT_ERROR); +#endif + if (qxl->guestdebug) { + va_list ap; + va_start(ap, msg); + fprintf(stderr, "qxl-%d: guest bug: ", qxl->id); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end(ap); + } +} + + +void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, + struct QXLRect *area, struct QXLRect *dirty_rects, + uint32_t num_dirty_rects, + uint32_t clear_dirty_region, + qxl_async_io async) +{ + if (async == QXL_SYNC) { + qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, + dirty_rects, num_dirty_rects, clear_dirty_region); + } else { +#if SPICE_INTERFACE_QXL_MINOR >= 1 + spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area, + clear_dirty_region, 0); +#else + abort(); +#endif + } +} + +static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl, + uint32_t id) +{ + qemu_mutex_lock(&qxl->track_lock); + qxl->guest_surfaces.cmds[id] = 0; + qxl->guest_surfaces.count--; + qemu_mutex_unlock(&qxl->track_lock); +} + +static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id, + qxl_async_io async) +{ + if (async) { +#if SPICE_INTERFACE_QXL_MINOR < 1 + abort(); +#else + spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, + (uint64_t)id); +#endif + } else { + qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id); + qxl_spice_destroy_surface_wait_complete(qxl, id); + } +} + +#if SPICE_INTERFACE_QXL_MINOR >= 1 +static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl) +{ + spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, 0); +} +#endif + +void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, + uint32_t count) +{ + qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count); +} + +void qxl_spice_oom(PCIQXLDevice *qxl) +{ + qxl->ssd.worker->oom(qxl->ssd.worker); +} + +void qxl_spice_reset_memslots(PCIQXLDevice *qxl) +{ + qxl->ssd.worker->reset_memslots(qxl->ssd.worker); +} + +static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl) +{ + qemu_mutex_lock(&qxl->track_lock); + memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds)); + qxl->guest_surfaces.count = 0; + qemu_mutex_unlock(&qxl->track_lock); +} + +static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async) +{ + if (async) { +#if SPICE_INTERFACE_QXL_MINOR < 1 + abort(); +#else + spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0); +#endif + } else { + qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker); + qxl_spice_destroy_surfaces_complete(qxl); + } +} + +void qxl_spice_reset_image_cache(PCIQXLDevice *qxl) +{ + qxl->ssd.worker->reset_image_cache(qxl->ssd.worker); +} + +void qxl_spice_reset_cursor(PCIQXLDevice *qxl) +{ + qxl->ssd.worker->reset_cursor(qxl->ssd.worker); + qemu_mutex_lock(&qxl->track_lock); + qxl->guest_cursor = 0; + qemu_mutex_unlock(&qxl->track_lock); +} + + static inline uint32_t msb_mask(uint32_t val) { uint32_t mask; @@ -147,7 +264,7 @@ static ram_addr_t qxl_rom_size(void) static void init_qxl_rom(PCIQXLDevice *d) { - QXLRom *rom = qemu_get_ram_ptr(d->rom_offset); + QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar); QXLModes *modes = (QXLModes *)(rom + 1); uint32_t ram_header_size; uint32_t surface0_area_size; @@ -214,6 +331,7 @@ static void init_qxl_ram(PCIQXLDevice *d) d->ram->magic = cpu_to_le32(QXL_RAM_MAGIC); d->ram->int_pending = cpu_to_le32(0); d->ram->int_mask = cpu_to_le32(0); + d->ram->update_surface = 0; SPICE_RING_INIT(&d->ram->cmd_ring); SPICE_RING_INIT(&d->ram->cursor_ring); SPICE_RING_INIT(&d->ram->release_ring); @@ -223,39 +341,37 @@ static void init_qxl_ram(PCIQXLDevice *d) } /* can be called from spice server thread context */ -static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end) +static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end) { while (addr < end) { - cpu_physical_memory_set_dirty(addr); + memory_region_set_dirty(mr, addr); addr += TARGET_PAGE_SIZE; } } static void qxl_rom_set_dirty(PCIQXLDevice *qxl) { - ram_addr_t addr = qxl->rom_offset; - qxl_set_dirty(addr, addr + qxl->rom_size); + qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size); } /* called from spice server thread context only */ static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr) { - ram_addr_t addr = qxl->vga.vram_offset; void *base = qxl->vga.vram_ptr; intptr_t offset; offset = ptr - base; offset &= ~(TARGET_PAGE_SIZE-1); assert(offset < qxl->vga.vram_size); - qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE); + qxl_set_dirty(&qxl->vga.vram, offset, offset + TARGET_PAGE_SIZE); } /* can be called from spice server thread context */ static void qxl_ring_set_dirty(PCIQXLDevice *qxl) { - ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset; - ram_addr_t end = qxl->vga.vram_offset + qxl->vga.vram_size; - qxl_set_dirty(addr, end); + ram_addr_t addr = qxl->shadow_rom.ram_header_offset; + ram_addr_t end = qxl->vga.vram_size; + qxl_set_dirty(&qxl->vga.vram, addr, end); } /* @@ -270,6 +386,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); uint32_t id = le32_to_cpu(cmd->surface_id); PANIC_ON(id >= NUM_SURFACES); + qemu_mutex_lock(&qxl->track_lock); if (cmd->type == QXL_SURFACE_CMD_CREATE) { qxl->guest_surfaces.cmds[id] = ext->cmd.data; qxl->guest_surfaces.count++; @@ -280,13 +397,16 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) qxl->guest_surfaces.cmds[id] = 0; qxl->guest_surfaces.count--; } + qemu_mutex_unlock(&qxl->track_lock); break; } case QXL_CMD_CURSOR: { QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); if (cmd->type == QXL_CURSOR_SET) { + qemu_mutex_lock(&qxl->track_lock); qxl->guest_cursor = ext->cmd.data; + qemu_mutex_unlock(&qxl->track_lock); } break; } @@ -336,6 +456,58 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) info->n_surfaces = NUM_SURFACES; } +static const char *qxl_mode_to_string(int mode) +{ + switch (mode) { + case QXL_MODE_COMPAT: + return "compat"; + case QXL_MODE_NATIVE: + return "native"; + case QXL_MODE_UNDEFINED: + return "undefined"; + case QXL_MODE_VGA: + return "vga"; + } + return "INVALID"; +} + +static const char *io_port_to_string(uint32_t io_port) +{ + if (io_port >= QXL_IO_RANGE_SIZE) { + return "out of range"; + } + static const char *io_port_to_string[QXL_IO_RANGE_SIZE + 1] = { + [QXL_IO_NOTIFY_CMD] = "QXL_IO_NOTIFY_CMD", + [QXL_IO_NOTIFY_CURSOR] = "QXL_IO_NOTIFY_CURSOR", + [QXL_IO_UPDATE_AREA] = "QXL_IO_UPDATE_AREA", + [QXL_IO_UPDATE_IRQ] = "QXL_IO_UPDATE_IRQ", + [QXL_IO_NOTIFY_OOM] = "QXL_IO_NOTIFY_OOM", + [QXL_IO_RESET] = "QXL_IO_RESET", + [QXL_IO_SET_MODE] = "QXL_IO_SET_MODE", + [QXL_IO_LOG] = "QXL_IO_LOG", + [QXL_IO_MEMSLOT_ADD] = "QXL_IO_MEMSLOT_ADD", + [QXL_IO_MEMSLOT_DEL] = "QXL_IO_MEMSLOT_DEL", + [QXL_IO_DETACH_PRIMARY] = "QXL_IO_DETACH_PRIMARY", + [QXL_IO_ATTACH_PRIMARY] = "QXL_IO_ATTACH_PRIMARY", + [QXL_IO_CREATE_PRIMARY] = "QXL_IO_CREATE_PRIMARY", + [QXL_IO_DESTROY_PRIMARY] = "QXL_IO_DESTROY_PRIMARY", + [QXL_IO_DESTROY_SURFACE_WAIT] = "QXL_IO_DESTROY_SURFACE_WAIT", + [QXL_IO_DESTROY_ALL_SURFACES] = "QXL_IO_DESTROY_ALL_SURFACES", +#if SPICE_INTERFACE_QXL_MINOR >= 1 + [QXL_IO_UPDATE_AREA_ASYNC] = "QXL_IO_UPDATE_AREA_ASYNC", + [QXL_IO_MEMSLOT_ADD_ASYNC] = "QXL_IO_MEMSLOT_ADD_ASYNC", + [QXL_IO_CREATE_PRIMARY_ASYNC] = "QXL_IO_CREATE_PRIMARY_ASYNC", + [QXL_IO_DESTROY_PRIMARY_ASYNC] = "QXL_IO_DESTROY_PRIMARY_ASYNC", + [QXL_IO_DESTROY_SURFACE_ASYNC] = "QXL_IO_DESTROY_SURFACE_ASYNC", + [QXL_IO_DESTROY_ALL_SURFACES_ASYNC] + = "QXL_IO_DESTROY_ALL_SURFACES_ASYNC", + [QXL_IO_FLUSH_SURFACES_ASYNC] = "QXL_IO_FLUSH_SURFACES_ASYNC", + [QXL_IO_FLUSH_RELEASE] = "QXL_IO_FLUSH_RELEASE", +#endif + }; + return io_port_to_string[io_port]; +} + /* called from spice server thread context only */ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) { @@ -343,27 +515,34 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) SimpleSpiceUpdate *update; QXLCommandRing *ring; QXLCommand *cmd; - int notify; + int notify, ret; switch (qxl->mode) { case QXL_MODE_VGA: dprint(qxl, 2, "%s: vga\n", __FUNCTION__); - update = qemu_spice_create_update(&qxl->ssd); - if (update == NULL) { - return false; + ret = false; + qemu_mutex_lock(&qxl->ssd.lock); + if (qxl->ssd.update != NULL) { + update = qxl->ssd.update; + qxl->ssd.update = NULL; + *ext = update->ext; + ret = true; } - *ext = update->ext; - qxl_log_command(qxl, "vga", ext); - return true; + qemu_mutex_unlock(&qxl->ssd.lock); + if (ret) { + dprint(qxl, 2, "%s %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode)); + qxl_log_command(qxl, "vga", ext); + } + return ret; case QXL_MODE_COMPAT: case QXL_MODE_NATIVE: case QXL_MODE_UNDEFINED: - dprint(qxl, 2, "%s: %s\n", __FUNCTION__, - qxl->cmdflags ? "compat" : "native"); + dprint(qxl, 4, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode)); ring = &qxl->ram->cmd_ring; if (SPICE_RING_IS_EMPTY(ring)) { return false; } + dprint(qxl, 2, "%s: %s\n", __FUNCTION__, qxl_mode_to_string(qxl->mode)); SPICE_RING_CONS_ITEM(ring, cmd); ext->cmd = *cmd; ext->group_id = MEMSLOT_GROUP_GUEST; @@ -557,6 +736,38 @@ static int interface_flush_resources(QXLInstance *sin) return ret; } +static void qxl_create_guest_primary_complete(PCIQXLDevice *d); + +#if SPICE_INTERFACE_QXL_MINOR >= 1 + +/* called from spice server thread context only */ +static void interface_async_complete(QXLInstance *sin, uint64_t cookie) +{ + PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); + uint32_t current_async; + + qemu_mutex_lock(&qxl->async_lock); + current_async = qxl->current_async; + qxl->current_async = QXL_UNDEFINED_IO; + qemu_mutex_unlock(&qxl->async_lock); + + dprint(qxl, 2, "async_complete: %d (%ld) done\n", current_async, cookie); + switch (current_async) { + case QXL_IO_CREATE_PRIMARY_ASYNC: + qxl_create_guest_primary_complete(qxl); + break; + case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: + qxl_spice_destroy_surfaces_complete(qxl); + break; + case QXL_IO_DESTROY_SURFACE_ASYNC: + qxl_spice_destroy_surface_wait_complete(qxl, (uint32_t)cookie); + break; + } + qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD); +} + +#endif + static const QXLInterface qxl_interface = { .base.type = SPICE_INTERFACE_QXL, .base.description = "qxl gpu", @@ -576,6 +787,9 @@ static const QXLInterface qxl_interface = { .req_cursor_notification = interface_req_cursor_notification, .notify_update = interface_notify_update, .flush_resources = interface_flush_resources, +#if SPICE_INTERFACE_QXL_MINOR >= 1 + .async_complete = interface_async_complete, +#endif }; static void qxl_enter_vga_mode(PCIQXLDevice *d) @@ -595,10 +809,10 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d) return; } dprint(d, 1, "%s\n", __FUNCTION__); - qxl_destroy_primary(d); + qxl_destroy_primary(d, QXL_SYNC); } -static void qxl_set_irq(PCIQXLDevice *d) +static void qxl_update_irq(PCIQXLDevice *d) { uint32_t pending = le32_to_cpu(d->ram->int_pending); uint32_t mask = le32_to_cpu(d->ram->int_mask); @@ -607,35 +821,19 @@ static void qxl_set_irq(PCIQXLDevice *d) qxl_ring_set_dirty(d); } -static void qxl_write_config(PCIDevice *d, uint32_t address, - uint32_t val, int len) -{ - PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d); - VGACommonState *vga = &qxl->vga; - - vga_dirty_log_stop(vga); - pci_default_write_config(d, address, val, len); - if (vga->map_addr && qxl->pci.io_regions[0].addr == -1) { - vga->map_addr = 0; - } - vga_dirty_log_start(vga); -} - static void qxl_check_state(PCIQXLDevice *d) { QXLRam *ram = d->ram; - assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring)); - assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring)); + assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring)); + assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring)); } static void qxl_reset_state(PCIQXLDevice *d) { - QXLRam *ram = d->ram; QXLRom *rom = d->rom; - assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring)); - assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring)); + qxl_check_state(d); d->shadow_rom.update_id = cpu_to_le32(0); *rom = d->shadow_rom; qxl_rom_set_dirty(d); @@ -662,10 +860,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm) dprint(d, 1, "%s: start%s\n", __FUNCTION__, loadvm ? " (loadvm)" : ""); - qemu_mutex_unlock_iothread(); - d->ssd.worker->reset_cursor(d->ssd.worker); - d->ssd.worker->reset_image_cache(d->ssd.worker); - qemu_mutex_lock_iothread(); + qxl_spice_reset_cursor(d); + qxl_spice_reset_image_cache(d); qxl_reset_surfaces(d); qxl_reset_memslots(d); @@ -694,13 +890,28 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) if (qxl->mode != QXL_MODE_VGA) { dprint(qxl, 1, "%s\n", __FUNCTION__); - qxl_destroy_primary(qxl); + qxl_destroy_primary(qxl, QXL_SYNC); qxl_soft_reset(qxl); } vga_ioport_write(opaque, addr, val); } -static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) +static const MemoryRegionPortio qxl_vga_portio_list[] = { + { 0x04, 2, 1, .read = vga_ioport_read, + .write = qxl_vga_ioport_write }, /* 3b4 */ + { 0x0a, 1, 1, .read = vga_ioport_read, + .write = qxl_vga_ioport_write }, /* 3ba */ + { 0x10, 16, 1, .read = vga_ioport_read, + .write = qxl_vga_ioport_write }, /* 3c0 */ + { 0x24, 2, 1, .read = vga_ioport_read, + .write = qxl_vga_ioport_write }, /* 3d4 */ + { 0x2a, 1, 1, .read = vga_ioport_read, + .write = qxl_vga_ioport_write }, /* 3da */ + PORTIO_END_OF_LIST(), +}; + +static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, + qxl_async_io async) { static const int regions[] = { QXL_RAM_RANGE_INDEX, @@ -748,10 +959,10 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) switch (pci_region) { case QXL_RAM_RANGE_INDEX: - virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset); + virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram); break; case QXL_VRAM_RANGE_INDEX: - virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset); + virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar); break; default: /* should not happen */ @@ -766,11 +977,11 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) memslot.generation = d->rom->slot_generation = 0; qxl_rom_set_dirty(d); - dprint(d, 1, "%s: slot %d: host virt 0x%" PRIx64 " - 0x%" PRIx64 "\n", + dprint(d, 1, "%s: slot %d: host virt 0x%lx - 0x%lx\n", __FUNCTION__, memslot.slot_id, memslot.virt_start, memslot.virt_end); - d->ssd.worker->add_memslot(d->ssd.worker, &memslot); + qemu_spice_add_memslot(&d->ssd, &memslot, async); d->guest_slots[slot_id].ptr = (void*)memslot.virt_start; d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start; d->guest_slots[slot_id].delta = delta; @@ -780,14 +991,14 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id) { dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id); - d->ssd.worker->del_memslot(d->ssd.worker, MEMSLOT_GROUP_HOST, slot_id); + qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id); d->guest_slots[slot_id].active = 0; } static void qxl_reset_memslots(PCIQXLDevice *d) { dprint(d, 1, "%s:\n", __FUNCTION__); - d->ssd.worker->reset_memslots(d->ssd.worker); + qxl_spice_reset_memslots(d); memset(&d->guest_slots, 0, sizeof(d->guest_slots)); } @@ -795,10 +1006,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d) { dprint(d, 1, "%s:\n", __FUNCTION__); d->mode = QXL_MODE_UNDEFINED; - qemu_mutex_unlock_iothread(); - d->ssd.worker->destroy_surfaces(d->ssd.worker); - qemu_mutex_lock_iothread(); - memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds)); + qxl_spice_destroy_surfaces(d, QXL_SYNC); } /* called from spice server thread context only */ @@ -823,7 +1031,14 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id) } } -static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm) +static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl) +{ + /* for local rendering */ + qxl_render_resize(qxl); +} + +static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm, + qxl_async_io async) { QXLDevSurfaceCreate surface; QXLSurfaceCreate *sc = &qxl->guest_primary.surface; @@ -851,24 +1066,27 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm) qxl->mode = QXL_MODE_NATIVE; qxl->cmdflags = 0; - qxl->ssd.worker->create_primary_surface(qxl->ssd.worker, 0, &surface); + qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface, async); - /* for local rendering */ - qxl_render_resize(qxl); + if (async == QXL_SYNC) { + qxl_create_guest_primary_complete(qxl); + } } -static void qxl_destroy_primary(PCIQXLDevice *d) +/* return 1 if surface destoy was initiated (in QXL_ASYNC case) or + * done (in QXL_SYNC case), 0 otherwise. */ +static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async) { if (d->mode == QXL_MODE_UNDEFINED) { - return; + return 0; } dprint(d, 1, "%s\n", __FUNCTION__); d->mode = QXL_MODE_UNDEFINED; - qemu_mutex_unlock_iothread(); - d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0); - qemu_mutex_lock_iothread(); + qemu_spice_destroy_primary_surface(&d->ssd, 0, async); + qxl_spice_reset_cursor(d); + return 1; } static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) @@ -891,17 +1109,17 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) .mem = devmem + d->shadow_rom.draw_area_offset, }; - dprint(d, 1, "%s: mode %d [ %d x %d @ %d bpp devmem 0x%lx ]\n", __FUNCTION__, - modenr, mode->x_res, mode->y_res, mode->bits, devmem); + dprint(d, 1, "%s: mode %d [ %d x %d @ %d bpp devmem 0x%" PRIx64 " ]\n", + __func__, modenr, mode->x_res, mode->y_res, mode->bits, devmem); if (!loadvm) { qxl_hard_reset(d, 0); } d->guest_slots[0].slot = slot; - qxl_add_memslot(d, 0, devmem); + qxl_add_memslot(d, 0, devmem, QXL_SYNC); d->guest_primary.surface = surface; - qxl_create_guest_primary(d, 0); + qxl_create_guest_primary(d, 0, QXL_SYNC); d->mode = QXL_MODE_COMPAT; d->cmdflags = QXL_COMMAND_FLAG_COMPAT; @@ -915,10 +1133,15 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) qxl_rom_set_dirty(d); } -static void ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { PCIQXLDevice *d = opaque; - uint32_t io_port = addr - d->io_base; + uint32_t io_port = addr; + qxl_async_io async = QXL_SYNC; +#if SPICE_INTERFACE_QXL_MINOR >= 1 + uint32_t orig_io_port = io_port; +#endif switch (io_port) { case QXL_IO_RESET: @@ -926,52 +1149,103 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) case QXL_IO_MEMSLOT_ADD: case QXL_IO_MEMSLOT_DEL: case QXL_IO_CREATE_PRIMARY: + case QXL_IO_UPDATE_IRQ: + case QXL_IO_LOG: +#if SPICE_INTERFACE_QXL_MINOR >= 1 + case QXL_IO_MEMSLOT_ADD_ASYNC: + case QXL_IO_CREATE_PRIMARY_ASYNC: +#endif break; default: - if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT) + if (d->mode != QXL_MODE_VGA) { break; - dprint(d, 1, "%s: unexpected port 0x%x in vga mode\n", __FUNCTION__, io_port); + } + dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n", + __func__, io_port, io_port_to_string(io_port)); +#if SPICE_INTERFACE_QXL_MINOR >= 1 + /* be nice to buggy guest drivers */ + if (io_port >= QXL_IO_UPDATE_AREA_ASYNC && + io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) { + qxl_send_events(d, QXL_INTERRUPT_IO_CMD); + } +#endif return; } +#if SPICE_INTERFACE_QXL_MINOR >= 1 + /* we change the io_port to avoid ifdeffery in the main switch */ + orig_io_port = io_port; + switch (io_port) { + case QXL_IO_UPDATE_AREA_ASYNC: + io_port = QXL_IO_UPDATE_AREA; + goto async_common; + case QXL_IO_MEMSLOT_ADD_ASYNC: + io_port = QXL_IO_MEMSLOT_ADD; + goto async_common; + case QXL_IO_CREATE_PRIMARY_ASYNC: + io_port = QXL_IO_CREATE_PRIMARY; + goto async_common; + case QXL_IO_DESTROY_PRIMARY_ASYNC: + io_port = QXL_IO_DESTROY_PRIMARY; + goto async_common; + case QXL_IO_DESTROY_SURFACE_ASYNC: + io_port = QXL_IO_DESTROY_SURFACE_WAIT; + goto async_common; + case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: + io_port = QXL_IO_DESTROY_ALL_SURFACES; + goto async_common; + case QXL_IO_FLUSH_SURFACES_ASYNC: +async_common: + async = QXL_ASYNC; + qemu_mutex_lock(&d->async_lock); + if (d->current_async != QXL_UNDEFINED_IO) { + qxl_guest_bug(d, "%d async started before last (%d) complete", + io_port, d->current_async); + qemu_mutex_unlock(&d->async_lock); + return; + } + d->current_async = orig_io_port; + qemu_mutex_unlock(&d->async_lock); + dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val); + break; + default: + break; + } +#endif + switch (io_port) { case QXL_IO_UPDATE_AREA: { QXLRect update = d->ram->update_area; - qemu_mutex_unlock_iothread(); - d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface, - &update, NULL, 0, 0); - qemu_mutex_lock_iothread(); + qxl_spice_update_area(d, d->ram->update_surface, + &update, NULL, 0, 0, async); break; } case QXL_IO_NOTIFY_CMD: - d->ssd.worker->wakeup(d->ssd.worker); + qemu_spice_wakeup(&d->ssd); break; case QXL_IO_NOTIFY_CURSOR: - d->ssd.worker->wakeup(d->ssd.worker); + qemu_spice_wakeup(&d->ssd); break; case QXL_IO_UPDATE_IRQ: - qxl_set_irq(d); + qxl_update_irq(d); break; case QXL_IO_NOTIFY_OOM: if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) { break; } - pthread_yield(); - if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) { - break; - } d->oom_running = 1; - d->ssd.worker->oom(d->ssd.worker); + qxl_spice_oom(d); d->oom_running = 0; break; case QXL_IO_SET_MODE: - dprint(d, 1, "QXL_SET_MODE %d\n", val); + dprint(d, 1, "QXL_SET_MODE %d\n", (int)val); qxl_set_mode(d, val, 0); break; case QXL_IO_LOG: if (d->guestdebug) { - fprintf(stderr, "qxl/guest: %s", d->ram->log_buf); + fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id, + qemu_get_clock_ns(vm_clock), d->ram->log_buf); } break; case QXL_IO_RESET: @@ -979,38 +1253,102 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) qxl_hard_reset(d, 0); break; case QXL_IO_MEMSLOT_ADD: - PANIC_ON(val >= NUM_MEMSLOTS); - PANIC_ON(d->guest_slots[val].active); + if (val >= NUM_MEMSLOTS) { + qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range"); + break; + } + if (d->guest_slots[val].active) { + qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active"); + break; + } d->guest_slots[val].slot = d->ram->mem_slot; - qxl_add_memslot(d, val, 0); + qxl_add_memslot(d, val, 0, async); break; case QXL_IO_MEMSLOT_DEL: + if (val >= NUM_MEMSLOTS) { + qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range"); + break; + } qxl_del_memslot(d, val); break; case QXL_IO_CREATE_PRIMARY: - PANIC_ON(val != 0); - dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n"); + if (val != 0) { + qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY (async=%d): val != 0", + async); + goto cancel_async; + } + dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async); d->guest_primary.surface = d->ram->create_surface; - qxl_create_guest_primary(d, 0); + qxl_create_guest_primary(d, 0, async); break; case QXL_IO_DESTROY_PRIMARY: - PANIC_ON(val != 0); - dprint(d, 1, "QXL_IO_DESTROY_PRIMARY\n"); - qxl_destroy_primary(d); + if (val != 0) { + qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0", + async); + goto cancel_async; + } + dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async, + qxl_mode_to_string(d->mode)); + if (!qxl_destroy_primary(d, async)) { + dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n", + qxl_mode_to_string(d->mode)); + goto cancel_async; + } break; case QXL_IO_DESTROY_SURFACE_WAIT: - d->ssd.worker->destroy_surface_wait(d->ssd.worker, val); + if (val >= NUM_SURFACES) { + qxl_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):" + "%d >= NUM_SURFACES", async, val); + goto cancel_async; + } + qxl_spice_destroy_surface_wait(d, val, async); break; +#if SPICE_INTERFACE_QXL_MINOR >= 1 + case QXL_IO_FLUSH_RELEASE: { + QXLReleaseRing *ring = &d->ram->release_ring; + if (ring->prod - ring->cons + 1 == ring->num_items) { + fprintf(stderr, + "ERROR: no flush, full release ring [p%d,%dc]\n", + ring->prod, ring->cons); + } + qxl_push_free_res(d, 1 /* flush */); + dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n", + qxl_mode_to_string(d->mode), d->guest_surfaces.count, + d->num_free_res, d->last_release); + break; + } + case QXL_IO_FLUSH_SURFACES_ASYNC: + dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC" + " (%"PRId64") (%s, s#=%d, res#=%d)\n", + val, qxl_mode_to_string(d->mode), d->guest_surfaces.count, + d->num_free_res); + qxl_spice_flush_surfaces_async(d); + break; +#endif case QXL_IO_DESTROY_ALL_SURFACES: - d->ssd.worker->destroy_surfaces(d->ssd.worker); + d->mode = QXL_MODE_UNDEFINED; + qxl_spice_destroy_surfaces(d, async); break; default: fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port); abort(); } + return; +cancel_async: +#if SPICE_INTERFACE_QXL_MINOR >= 1 + if (async) { + qxl_send_events(d, QXL_INTERRUPT_IO_CMD); + qemu_mutex_lock(&d->async_lock); + d->current_async = QXL_UNDEFINED_IO; + qemu_mutex_unlock(&d->async_lock); + } +#else + return; +#endif } -static uint32_t ioport_read(void *opaque, uint32_t addr) +static uint64_t ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PCIQXLDevice *d = opaque; @@ -1018,42 +1356,14 @@ static uint32_t ioport_read(void *opaque, uint32_t addr) return 0xff; } -static void qxl_map(PCIDevice *pci, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - static const char *names[] = { - [ QXL_IO_RANGE_INDEX ] = "ioports", - [ QXL_RAM_RANGE_INDEX ] = "devram", - [ QXL_ROM_RANGE_INDEX ] = "rom", - [ QXL_VRAM_RANGE_INDEX ] = "vram", - }; - PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci); - - dprint(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__, - region_num, names[region_num], addr, size); - - switch (region_num) { - case QXL_IO_RANGE_INDEX: - register_ioport_write(addr, size, 1, ioport_write, pci); - register_ioport_read(addr, size, 1, ioport_read, pci); - qxl->io_base = addr; - break; - case QXL_RAM_RANGE_INDEX: - cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM); - qxl->vga.map_addr = addr; - qxl->vga.map_end = addr + size; - if (qxl->id == 0) { - vga_dirty_log_start(&qxl->vga); - } - break; - case QXL_ROM_RANGE_INDEX: - cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM); - break; - case QXL_VRAM_RANGE_INDEX: - cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM); - break; - } -} +static const MemoryRegionOps qxl_io_ops = { + .read = ioport_read, + .write = ioport_write, + .valid = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; static void pipe_read(void *opaque) { @@ -1064,10 +1374,9 @@ static void pipe_read(void *opaque) do { len = read(d->pipe[0], &dummy, sizeof(dummy)); } while (len == sizeof(dummy)); - qxl_set_irq(d); + qxl_update_irq(d); } -/* called from spice server thread context only */ static void qxl_send_events(PCIQXLDevice *d, uint32_t events) { uint32_t old_pending; @@ -1078,8 +1387,8 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events) if ((old_pending & le_events) == le_events) { return; } - if (pthread_self() == d->main) { - qxl_set_irq(d); + if (qemu_thread_is_self(&d->main)) { + qxl_update_irq(d); } else { if (write(d->pipe[1], d, 1) != 1) { dprint(d, 1, "%s: write to pipe failed\n", __FUNCTION__); @@ -1093,15 +1402,11 @@ static void init_pipe_signaling(PCIQXLDevice *d) dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__); return; } -#ifdef CONFIG_IOTHREAD fcntl(d->pipe[0], F_SETFL, O_NONBLOCK); -#else - fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */); -#endif fcntl(d->pipe[1], F_SETFL, O_NONBLOCK); fcntl(d->pipe[0], F_SETOWN, getpid()); - d->main = pthread_self(); + qemu_thread_get_self(&d->main); qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d); } @@ -1163,17 +1468,27 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata) } } -static void qxl_vm_change_state_handler(void *opaque, int running, int reason) +static void qxl_vm_change_state_handler(void *opaque, int running, + RunState state) { PCIQXLDevice *qxl = opaque; - qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason); - - if (!running && qxl->mode == QXL_MODE_NATIVE) { - /* dirty all vram (which holds surfaces) to make sure it is saved */ + qemu_spice_vm_change_state_handler(&qxl->ssd, running, state); + + if (running) { + /* + * if qxl_send_events was called from spice server context before + * migration ended, qxl_update_irq for these events might not have been + * called + */ + qxl_update_irq(qxl); + } else if (qxl->mode == QXL_MODE_NATIVE) { + /* dirty all vram (which holds surfaces) and devram (primary surface) + * to make sure they are saved */ /* FIXME #1: should go out during "live" stage */ /* FIXME #2: we only need to save the areas which are actually used */ - ram_addr_t addr = qxl->vram_offset; - qxl_set_dirty(addr, addr + qxl->vram_size); + qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size); + qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset, + qxl->shadow_rom.surface0_area_size); } } @@ -1209,7 +1524,6 @@ static DisplayChangeListener display_listener = { static int qxl_init_common(PCIQXLDevice *qxl) { uint8_t* config = qxl->pci.config; - uint32_t pci_device_id; uint32_t pci_device_rev; uint32_t io_size; @@ -1217,29 +1531,31 @@ static int qxl_init_common(PCIQXLDevice *qxl) qxl->generation = 1; qxl->num_memslots = NUM_MEMSLOTS; qxl->num_surfaces = NUM_SURFACES; + qemu_mutex_init(&qxl->track_lock); + qemu_mutex_init(&qxl->async_lock); + qxl->current_async = QXL_UNDEFINED_IO; switch (qxl->revision) { case 1: /* spice 0.4 -- qxl-1 */ - pci_device_id = QXL_DEVICE_ID_STABLE; pci_device_rev = QXL_REVISION_STABLE_V04; break; case 2: /* spice 0.6 -- qxl-2 */ - pci_device_id = QXL_DEVICE_ID_STABLE; pci_device_rev = QXL_REVISION_STABLE_V06; break; - default: /* experimental */ - pci_device_id = QXL_DEVICE_ID_DEVEL; - pci_device_rev = 1; +#if SPICE_INTERFACE_QXL_MINOR >= 1 + case 3: /* qxl-3 */ +#endif + default: + pci_device_rev = QXL_DEFAULT_REVISION; break; } - pci_config_set_vendor_id(config, REDHAT_PCI_VENDOR_ID); - pci_config_set_device_id(config, pci_device_id); pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev); pci_set_byte(&config[PCI_INTERRUPT_PIN], 1); qxl->rom_size = qxl_rom_size(); - qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size); + memory_region_init_ram(&qxl->rom_bar, &qxl->pci.qdev, "qxl.vrom", + qxl->rom_size); init_qxl_rom(qxl); init_qxl_ram(qxl); @@ -1250,26 +1566,32 @@ static int qxl_init_common(PCIQXLDevice *qxl) qxl->vram_size = 4096; } qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1); - qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size); + memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram", + qxl->vram_size); io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); if (qxl->revision == 1) { io_size = 8; } + memory_region_init_io(&qxl->io_bar, &qxl_io_ops, qxl, + "qxl-ioports", io_size); + if (qxl->id == 0) { + vga_dirty_log_start(&qxl->vga); + } + + pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX, - io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map); + PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar); pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX, - qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY, - qxl_map); + PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar); pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX, - qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY, - qxl_map); + PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram); - pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size, - PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map); + pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, + PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar); qxl->ssd.qxl.base.sif = &qxl_interface.base; qxl->ssd.qxl.id = qxl->id; @@ -1287,6 +1609,7 @@ static int qxl_init_primary(PCIDevice *dev) PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev); VGACommonState *vga = &qxl->vga; ram_addr_t ram_size = msb_mask(qxl->vga.vram_size * 2 - 1); + PortioList *qxl_vga_port_list = g_new(PortioList, 1); qxl->id = 0; @@ -1294,23 +1617,17 @@ static int qxl_init_primary(PCIDevice *dev) ram_size = 32 * 1024 * 1024; } vga_common_init(vga, ram_size); - vga_init(vga); - register_ioport_write(0x3c0, 16, 1, qxl_vga_ioport_write, vga); - register_ioport_write(0x3b4, 2, 1, qxl_vga_ioport_write, vga); - register_ioport_write(0x3d4, 2, 1, qxl_vga_ioport_write, vga); - register_ioport_write(0x3ba, 1, 1, qxl_vga_ioport_write, vga); - register_ioport_write(0x3da, 1, 1, qxl_vga_ioport_write, vga); + vga_init(vga, pci_address_space(dev), pci_address_space_io(dev), false); + portio_list_init(qxl_vga_port_list, qxl_vga_portio_list, vga, "vga"); + portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0); vga->ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate, qxl_hw_screen_dump, qxl_hw_text_update, qxl); - qxl->ssd.ds = vga->ds; - qxl->ssd.bufsize = (16 * 1024 * 1024); - qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize); + qemu_spice_display_init_common(&qxl->ssd, vga->ds); qxl0 = qxl; register_displaychangelistener(vga->ds, &display_listener); - pci_config_set_class(dev->config, PCI_CLASS_DISPLAY_VGA); return qxl_init_common(qxl); } @@ -1326,11 +1643,10 @@ static int qxl_init_secondary(PCIDevice *dev) ram_size = 16 * 1024 * 1024; } qxl->vga.vram_size = ram_size; - qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram", - qxl->vga.vram_size); - qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset); + memory_region_init_ram(&qxl->vga.vram, &qxl->pci.qdev, "qxl.vgavram", + qxl->vga.vram_size); + qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram); - pci_config_set_class(dev->config, PCI_CLASS_DISPLAY_OTHER); return qxl_init_common(qxl); } @@ -1359,12 +1675,25 @@ static int qxl_pre_load(void *opaque) return 0; } +static void qxl_create_memslots(PCIQXLDevice *d) +{ + int i; + + for (i = 0; i < NUM_MEMSLOTS; i++) { + if (!d->guest_slots[i].active) { + continue; + } + dprint(d, 1, "%s: restoring guest slot %d\n", __func__, i); + qxl_add_memslot(d, i, 0, QXL_SYNC); + } +} + static int qxl_post_load(void *opaque, int version) { PCIQXLDevice* d = opaque; uint8_t *ram_start = d->vga.vram_ptr; QXLCommandExt *cmds; - int in, out, i, newmode; + int in, out, newmode; dprint(d, 1, "%s: start\n", __FUNCTION__); @@ -1377,26 +1706,24 @@ static int qxl_post_load(void *opaque, int version) d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset); - dprint(d, 1, "%s: restore mode\n", __FUNCTION__); + dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__, + qxl_mode_to_string(d->mode)); newmode = d->mode; d->mode = QXL_MODE_UNDEFINED; + switch (newmode) { case QXL_MODE_UNDEFINED: break; case QXL_MODE_VGA: + qxl_create_memslots(d); qxl_enter_vga_mode(d); break; case QXL_MODE_NATIVE: - for (i = 0; i < NUM_MEMSLOTS; i++) { - if (!d->guest_slots[i].active) { - continue; - } - qxl_add_memslot(d, i, 0); - } - qxl_create_guest_primary(d, 1); + qxl_create_memslots(d); + qxl_create_guest_primary(d, 1, QXL_SYNC); /* replay surface-create and cursor-set commands */ - cmds = qemu_mallocz(sizeof(QXLCommandExt) * (NUM_SURFACES + 1)); + cmds = g_malloc0(sizeof(QXLCommandExt) * (NUM_SURFACES + 1)); for (in = 0, out = 0; in < NUM_SURFACES; in++) { if (d->guest_surfaces.cmds[in] == 0) { continue; @@ -1406,15 +1733,19 @@ static int qxl_post_load(void *opaque, int version) cmds[out].group_id = MEMSLOT_GROUP_GUEST; out++; } - cmds[out].cmd.data = d->guest_cursor; - cmds[out].cmd.type = QXL_CMD_CURSOR; - cmds[out].group_id = MEMSLOT_GROUP_GUEST; - out++; - d->ssd.worker->loadvm_commands(d->ssd.worker, cmds, out); - qemu_free(cmds); + if (d->guest_cursor) { + cmds[out].cmd.data = d->guest_cursor; + cmds[out].cmd.type = QXL_CMD_CURSOR; + cmds[out].group_id = MEMSLOT_GROUP_GUEST; + out++; + } + qxl_spice_loadvm_commands(d, cmds, out); + g_free(cmds); break; case QXL_MODE_COMPAT: + /* note: no need to call qxl_create_memslots, qxl_set_mode + * creates the mem slot. */ qxl_set_mode(d, d->shadow_rom.mode, 1); break; } @@ -1483,6 +1814,19 @@ static VMStateDescription qxl_vmstate = { }, }; +static Property qxl_properties[] = { + DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, + 64 * 1024 * 1024), + DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, + 64 * 1024 * 1024), + DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, + QXL_DEFAULT_REVISION), + DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0), + DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0), + DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0), + DEFINE_PROP_END_OF_LIST(), +}; + static PCIDeviceInfo qxl_info_primary = { .qdev.name = "qxl-vga", .qdev.desc = "Spice QXL GPU (primary, vga compatible)", @@ -1491,17 +1835,11 @@ static PCIDeviceInfo qxl_info_primary = { .qdev.vmsd = &qxl_vmstate, .no_hotplug = 1, .init = qxl_init_primary, - .config_write = qxl_write_config, .romfile = "vgabios-qxl.bin", - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024), - DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024), - DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2), - DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0), - DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0), - DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0), - DEFINE_PROP_END_OF_LIST(), - } + .vendor_id = REDHAT_PCI_VENDOR_ID, + .device_id = QXL_DEVICE_ID_STABLE, + .class_id = PCI_CLASS_DISPLAY_VGA, + .qdev.props = qxl_properties, }; static PCIDeviceInfo qxl_info_secondary = { @@ -1511,15 +1849,10 @@ static PCIDeviceInfo qxl_info_secondary = { .qdev.reset = qxl_reset_handler, .qdev.vmsd = &qxl_vmstate, .init = qxl_init_secondary, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024), - DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024), - DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2), - DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0), - DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0), - DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0), - DEFINE_PROP_END_OF_LIST(), - } + .vendor_id = REDHAT_PCI_VENDOR_ID, + .device_id = QXL_DEVICE_ID_STABLE, + .class_id = PCI_CLASS_DISPLAY_OTHER, + .qdev.props = qxl_properties, }; static void qxl_register(void) diff --git a/hw/qxl.h b/hw/qxl.h index f6c450d..766aa6d 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -4,6 +4,7 @@ #include "hw.h" #include "pci.h" #include "vga_int.h" +#include "qemu-thread.h" #include "ui/qemu-spice.h" #include "ui/spice-display.h" @@ -15,6 +16,8 @@ enum qxl_mode { QXL_MODE_NATIVE, }; +#define QXL_UNDEFINED_IO UINT32_MAX + typedef struct PCIQXLDevice { PCIDevice pci; SimpleSpiceDisplay ssd; @@ -30,6 +33,9 @@ typedef struct PCIQXLDevice { int32_t num_memslots; int32_t num_surfaces; + uint32_t current_async; + QemuMutex async_lock; + struct guest_slots { QXLMemSlot slot; void *ptr; @@ -42,7 +48,8 @@ typedef struct PCIQXLDevice { QXLSurfaceCreate surface; uint32_t commands; uint32_t resized; - int32_t stride; + int32_t qxl_stride; + uint32_t abs_stride; uint32_t bits_pp; uint32_t bytes_pp; uint8_t *data, *flipped; @@ -55,8 +62,10 @@ typedef struct PCIQXLDevice { } guest_surfaces; QXLPHYSICAL guest_cursor; + QemuMutex track_lock; + /* thread signaling */ - pthread_t main; + QemuThread main; int pipe[2]; /* ram pci bar */ @@ -72,19 +81,19 @@ typedef struct PCIQXLDevice { QXLRom *rom; QXLModes *modes; uint32_t rom_size; - uint64_t rom_offset; + MemoryRegion rom_bar; /* vram pci bar */ uint32_t vram_size; - uint64_t vram_offset; + MemoryRegion vram_bar; /* io bar */ - uint32_t io_base; + MemoryRegion io_bar; } PCIQXLDevice; #define PANIC_ON(x) if ((x)) { \ printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \ - exit(-1); \ + abort(); \ } #define dprint(_qxl, _level, _fmt, ...) \ @@ -95,8 +104,27 @@ typedef struct PCIQXLDevice { } \ } while (0) +#if SPICE_INTERFACE_QXL_MINOR >= 1 +#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10 +#else +#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V06 +#endif + /* qxl.c */ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); +void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...); + +void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, + struct QXLRect *area, struct QXLRect *dirty_rects, + uint32_t num_dirty_rects, + uint32_t clear_dirty_region, + qxl_async_io async); +void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, + uint32_t count); +void qxl_spice_oom(PCIQXLDevice *qxl); +void qxl_spice_reset_memslots(PCIQXLDevice *qxl); +void qxl_spice_reset_image_cache(PCIQXLDevice *qxl); +void qxl_spice_reset_cursor(PCIQXLDevice *qxl); /* qxl-logger.c */ void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id); @@ -106,3 +134,9 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext); void qxl_render_resize(PCIQXLDevice *qxl); void qxl_render_update(PCIQXLDevice *qxl); void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext); +#if SPICE_INTERFACE_QXL_MINOR >= 1 +void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id, + struct QXLRect *area, + uint32_t clear_dirty_region, + int is_vga); +#endif diff --git a/hw/r2d.c b/hw/r2d.c index a0f8c1f..b65fd42 100644 --- a/hw/r2d.c +++ b/hw/r2d.c @@ -37,6 +37,7 @@ #include "usb.h" #include "flash.h" #include "blockdev.h" +#include "exec-memory.h" #define FLASH_BASE 0x00000000 #define FLASH_SIZE 0x02000000 @@ -81,6 +82,7 @@ typedef struct { /* output pin */ qemu_irq irl; + MemoryRegion iomem; } r2d_fpga_t; enum r2d_fpga_irq { @@ -167,31 +169,25 @@ r2d_fpga_write(void *opaque, target_phys_addr_t addr, uint32_t value) } } -static CPUReadMemoryFunc * const r2d_fpga_readfn[] = { - r2d_fpga_read, - r2d_fpga_read, - NULL, +static const MemoryRegionOps r2d_fpga_ops = { + .old_mmio = { + .read = { r2d_fpga_read, r2d_fpga_read, NULL, }, + .write = { r2d_fpga_write, r2d_fpga_write, NULL, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const r2d_fpga_writefn[] = { - r2d_fpga_write, - r2d_fpga_write, - NULL, -}; - -static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl) +static qemu_irq *r2d_fpga_init(MemoryRegion *sysmem, + target_phys_addr_t base, qemu_irq irl) { - int iomemtype; r2d_fpga_t *s; - s = qemu_mallocz(sizeof(r2d_fpga_t)); + s = g_malloc0(sizeof(r2d_fpga_t)); s->irl = irl; - iomemtype = cpu_register_io_memory(r2d_fpga_readfn, - r2d_fpga_writefn, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x40, iomemtype); + memory_region_init_io(&s->iomem, &r2d_fpga_ops, s, "r2d-fpga", 0x40); + memory_region_add_subregion(sysmem, base, &s->iomem); return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS); } @@ -209,7 +205,7 @@ static void main_cpu_reset(void *opaque) env->pc = s->vector; } -static struct __attribute__((__packed__)) +static struct QEMU_PACKED { int mount_root_rdonly; int ramdisk_flags; @@ -231,10 +227,11 @@ static void r2d_init(ram_addr_t ram_size, CPUState *env; ResetData *reset_info; struct SH7750State *s; - ram_addr_t sdram_addr; + MemoryRegion *sdram = g_new(MemoryRegion, 1); qemu_irq *irq; DriveInfo *dinfo; int i; + MemoryRegion *address_space_mem = get_system_memory(); if (!cpu_model) cpu_model = "SH7751R"; @@ -244,21 +241,22 @@ static void r2d_init(ram_addr_t ram_size, fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } - reset_info = qemu_mallocz(sizeof(ResetData)); + reset_info = g_malloc0(sizeof(ResetData)); reset_info->env = env; reset_info->vector = env->pc; qemu_register_reset(main_cpu_reset, reset_info); /* Allocate memory space */ - sdram_addr = qemu_ram_alloc(NULL, "r2d.sdram", SDRAM_SIZE); - cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr); + memory_region_init_ram(sdram, NULL, "r2d.sdram", SDRAM_SIZE); + memory_region_add_subregion(address_space_mem, SDRAM_BASE, sdram); /* Register peripherals */ s = sh7750_init(env); - irq = r2d_fpga_init(0x04000000, sh7750_irl(s)); + irq = r2d_fpga_init(address_space_mem, 0x04000000, sh7750_irl(s)); sysbus_create_varargs("sh_pci", 0x1e200000, irq[PCI_INTA], irq[PCI_INTB], irq[PCI_INTC], irq[PCI_INTD], NULL); - sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]); + sm501_init(address_space_mem, 0x10000000, SM501_VRAM_SIZE, + irq[SM501], serial_hds[2]); /* onboard CF (True IDE mode, Master only). */ dinfo = drive_get(IF_IDE, 0, 0); @@ -267,7 +265,7 @@ static void r2d_init(ram_addr_t ram_size, /* onboard flash memory */ dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE), + pflash_cfi02_register(0x0, NULL, "r2d.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (16 * 1024), FLASH_SIZE >> 16, 1, 4, 0x0000, 0x0000, 0x0000, 0x0000, diff --git a/hw/rc4030.c b/hw/rc4030.c index 0a9d98d..33e1070 100644 --- a/hw/rc4030.c +++ b/hw/rc4030.c @@ -50,7 +50,7 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } whi typedef struct dma_pagetable_entry { int32_t frame; int32_t owner; -} __attribute__((packed)) dma_pagetable_entry; +} QEMU_PACKED dma_pagetable_entry; #define DMA_PAGESIZE 4096 #define DMA_REG_ENABLE 1 @@ -104,7 +104,7 @@ static void set_next_tick(rc4030State *s) tm_hz = 1000 / (s->itr + 1); - qemu_mod_timer(s->periodic_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(s->periodic_timer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / tm_hz); } @@ -307,7 +307,7 @@ static void rc4030_writel(void *opaque, target_phys_addr_t addr, uint32_t val) if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) { target_phys_addr_t dest = s->cache_ptag & ~0x1; dest += (s->cache_maint & 0x3) << 3; - cpu_physical_memory_rw(dest, (uint8_t*)&val, 4, 1); + cpu_physical_memory_write(dest, &val, 4); } break; /* Remote Speed Registers */ @@ -704,7 +704,7 @@ void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, i entry_addr = s->dma_tl_base + index * sizeof(dma_pagetable_entry); /* XXX: not sure. should we really use only lowest bits? */ entry_addr &= 0x7fffffff; - cpu_physical_memory_rw(entry_addr, (uint8_t *)&entry, sizeof(entry), 0); + cpu_physical_memory_read(entry_addr, &entry, sizeof(entry)); /* Read/write data at right place */ phys_addr = entry.frame + (addr & (DMA_PAGESIZE - 1)); @@ -789,8 +789,8 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n) struct rc4030DMAState *p; int i; - s = (rc4030_dma *)qemu_mallocz(sizeof(rc4030_dma) * n); - p = (struct rc4030DMAState *)qemu_mallocz(sizeof(struct rc4030DMAState) * n); + s = (rc4030_dma *)g_malloc0(sizeof(rc4030_dma) * n); + p = (struct rc4030DMAState *)g_malloc0(sizeof(struct rc4030DMAState) * n); for (i = 0; i < n; i++) { p->opaque = opaque; p->n = i; @@ -806,12 +806,12 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, rc4030State *s; int s_chipset, s_jazzio; - s = qemu_mallocz(sizeof(rc4030State)); + s = g_malloc0(sizeof(rc4030State)); *irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16); *dmas = rc4030_allocate_dmas(s, 4); - s->periodic_timer = qemu_new_timer(vm_clock, rc4030_periodic_timer, s); + s->periodic_timer = qemu_new_timer_ns(vm_clock, rc4030_periodic_timer, s); s->timer_irq = timer; s->jazz_bus_irq = jazz_bus; diff --git a/hw/realview.c b/hw/realview.c index 6eb6c6a..9a8e63c 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -17,19 +17,21 @@ #include "sysemu.h" #include "boards.h" #include "bitbang_i2c.h" -#include "sysbus.h" #include "blockdev.h" +#include "exec-memory.h" #define SMP_BOOT_ADDR 0xe0000000 typedef struct { SysBusDevice busdev; + MemoryRegion iomem; bitbang_i2c_interface *bitbang; int out; int in; } RealViewI2CState; -static uint32_t realview_i2c_read(void *opaque, target_phys_addr_t offset) +static uint64_t realview_i2c_read(void *opaque, target_phys_addr_t offset, + unsigned size) { RealViewI2CState *s = (RealViewI2CState *)opaque; @@ -42,7 +44,7 @@ static uint32_t realview_i2c_read(void *opaque, target_phys_addr_t offset) } static void realview_i2c_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { RealViewI2CState *s = (RealViewI2CState *)opaque; @@ -60,30 +62,22 @@ static void realview_i2c_write(void *opaque, target_phys_addr_t offset, s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0); } -static CPUReadMemoryFunc * const realview_i2c_readfn[] = { - realview_i2c_read, - realview_i2c_read, - realview_i2c_read -}; - -static CPUWriteMemoryFunc * const realview_i2c_writefn[] = { - realview_i2c_write, - realview_i2c_write, - realview_i2c_write +static const MemoryRegionOps realview_i2c_ops = { + .read = realview_i2c_read, + .write = realview_i2c_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int realview_i2c_init(SysBusDevice *dev) { RealViewI2CState *s = FROM_SYSBUS(RealViewI2CState, dev); i2c_bus *bus; - int iomemtype; bus = i2c_init_bus(&dev->qdev, "i2c"); s->bitbang = bitbang_i2c_init(bus); - iomemtype = cpu_register_io_memory(realview_i2c_readfn, - realview_i2c_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, iomemtype); + memory_region_init_io(&s->iomem, &realview_i2c_ops, s, + "realview-i2c", 0x1000); + sysbus_init_mmio_region(dev, &s->iomem); return 0; } @@ -104,17 +98,6 @@ static struct arm_boot_info realview_binfo = { .smp_loader_start = SMP_BOOT_ADDR, }; -static void secondary_cpu_reset(void *opaque) -{ - CPUState *env = opaque; - - cpu_reset(env); - /* Set entry point for secondary CPUs. This assumes we're using - the init code from arm_boot.c. Real hardware resets all CPUs - the same. */ - env->regs[15] = SMP_BOOT_ADDR; -} - /* The following two lists must be consistent. */ enum realview_board_type { BOARD_EB, @@ -137,11 +120,16 @@ static void realview_init(ram_addr_t ram_size, enum realview_board_type board_type) { CPUState *env = NULL; - ram_addr_t ram_offset; - DeviceState *dev; + MemoryRegion *sysmem = get_system_memory(); + MemoryRegion *ram_lo = g_new(MemoryRegion, 1); + MemoryRegion *ram_hi = g_new(MemoryRegion, 1); + MemoryRegion *ram_alias = g_new(MemoryRegion, 1); + MemoryRegion *ram_hack = g_new(MemoryRegion, 1); + DeviceState *dev, *sysctl, *gpio2, *pl041; SysBusDevice *busdev; qemu_irq *irqp; qemu_irq pic[64]; + qemu_irq mmc_irq[2]; PCIBus *pci_bus; NICInfo *nd; i2c_bus *i2c; @@ -176,9 +164,6 @@ static void realview_init(ram_addr_t ram_size, } irqp = arm_pic_init_cpu(env); cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; - if (n > 0) { - qemu_register_reset(secondary_cpu_reset, env); - } } if (arm_feature(env, ARM_FEATURE_V7)) { if (is_mpcore) { @@ -198,27 +183,31 @@ static void realview_init(ram_addr_t ram_size, /* Core tile RAM. */ low_ram_size = ram_size - 0x20000000; ram_size = 0x20000000; - ram_offset = qemu_ram_alloc(NULL, "realview.lowmem", low_ram_size); - cpu_register_physical_memory(0x20000000, low_ram_size, - ram_offset | IO_MEM_RAM); + memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size); + memory_region_add_subregion(sysmem, 0x20000000, ram_lo); } - ram_offset = qemu_ram_alloc(NULL, "realview.highmem", ram_size); + memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size); low_ram_size = ram_size; if (low_ram_size > 0x10000000) low_ram_size = 0x10000000; /* SDRAM at address zero. */ - cpu_register_physical_memory(0, low_ram_size, ram_offset | IO_MEM_RAM); + memory_region_init_alias(ram_alias, "realview.alias", + ram_hi, 0, low_ram_size); + memory_region_add_subregion(sysmem, 0, ram_alias); if (is_pb) { /* And again at a high address. */ - cpu_register_physical_memory(0x70000000, ram_size, - ram_offset | IO_MEM_RAM); + memory_region_add_subregion(sysmem, 0x70000000, ram_hi); } else { ram_size = low_ram_size; } sys_id = is_pb ? 0x01780500 : 0xc1400400; - arm_sysctl_init(0x10000000, sys_id, proc_id); + sysctl = qdev_create(NULL, "realview_sysctl"); + qdev_prop_set_uint32(sysctl, "sys_id", sys_id); + qdev_init_nofail(sysctl); + qdev_prop_set_uint32(sysctl, "proc_id", proc_id); + sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); if (is_mpcore) { dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); @@ -243,6 +232,12 @@ static void realview_init(ram_addr_t ram_size, pic[n] = qdev_get_gpio_in(dev, n); } + pl041 = qdev_create(NULL, "pl041"); + qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); + qdev_init_nofail(pl041); + sysbus_mmio_map(sysbus_from_qdev(pl041), 0, 0x10004000); + sysbus_connect_irq(sysbus_from_qdev(pl041), 0, pic[19]); + sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); @@ -257,15 +252,41 @@ static void realview_init(ram_addr_t ram_size, sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); - sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]); - - sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); + sysbus_create_simple("pl061", 0x10013000, pic[6]); + sysbus_create_simple("pl061", 0x10014000, pic[7]); + gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]); + + sysbus_create_simple("pl111", 0x10020000, pic[23]); + + dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); + /* Wire up MMC card detect and read-only signals. These have + * to go to both the PL061 GPIO and the sysctl register. + * Note that the PL181 orders these lines (readonly,inserted) + * and the PL061 has them the other way about. Also the card + * detect line is inverted. + */ + mmc_irq[0] = qemu_irq_split( + qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT), + qdev_get_gpio_in(gpio2, 1)); + mmc_irq[1] = qemu_irq_split( + qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN), + qemu_irq_invert(qdev_get_gpio_in(gpio2, 0))); + qdev_connect_gpio_out(dev, 0, mmc_irq[0]); + qdev_connect_gpio_out(dev, 1, mmc_irq[1]); sysbus_create_simple("pl031", 0x10017000, pic[10]); if (!is_pb) { - dev = sysbus_create_varargs("realview_pci", 0x60000000, - pic[48], pic[49], pic[50], pic[51], NULL); + dev = qdev_create(NULL, "realview_pci"); + busdev = sysbus_from_qdev(dev); + qdev_init_nofail(dev); + sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */ + sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */ + sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */ + sysbus_connect_irq(busdev, 0, pic[48]); + sysbus_connect_irq(busdev, 1, pic[49]); + sysbus_connect_irq(busdev, 2, pic[50]); + sysbus_connect_irq(busdev, 3, pic[51]); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); @@ -279,8 +300,8 @@ static void realview_init(ram_addr_t ram_size, for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; - if ((!nd->model && !done_nic) - || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0) { + if (!done_nic && (!nd->model || + strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) { if (is_pb) { lan9118_init(nd, 0x4e000000, pic[28]); } else { @@ -356,9 +377,8 @@ static void realview_init(ram_addr_t ram_size, startup code. I guess this works on real hardware because the BootROM happens to be in ROM/flash or in memory that isn't clobbered until after Linux boots the secondary CPUs. */ - ram_offset = qemu_ram_alloc(NULL, "realview.hack", 0x1000); - cpu_register_physical_memory(SMP_BOOT_ADDR, 0x1000, - ram_offset | IO_MEM_RAM); + memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000); + memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); realview_binfo.ram_size = ram_size; realview_binfo.kernel_filename = kernel_filename; diff --git a/hw/realview_gic.c b/hw/realview_gic.c index db908b6..cd6a44d 100644 --- a/hw/realview_gic.c +++ b/hw/realview_gic.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -23,39 +23,37 @@ gic_get_current_cpu(void) typedef struct { gic_state gic; - int iomemtype; + MemoryRegion iomem; + MemoryRegion container; } RealViewGICState; -static uint32_t realview_gic_cpu_read(void *opaque, target_phys_addr_t offset) +static uint64_t realview_gic_cpu_read(void *opaque, target_phys_addr_t offset, + unsigned size) { gic_state *s = (gic_state *)opaque; return gic_cpu_read(s, gic_get_current_cpu(), offset); } static void realview_gic_cpu_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { gic_state *s = (gic_state *)opaque; gic_cpu_write(s, gic_get_current_cpu(), offset, value); } -static CPUReadMemoryFunc * const realview_gic_cpu_readfn[] = { - realview_gic_cpu_read, - realview_gic_cpu_read, - realview_gic_cpu_read +static const MemoryRegionOps realview_gic_cpu_ops = { + .read = realview_gic_cpu_read, + .write = realview_gic_cpu_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const realview_gic_cpu_writefn[] = { - realview_gic_cpu_write, - realview_gic_cpu_write, - realview_gic_cpu_write -}; - -static void realview_gic_map(SysBusDevice *dev, target_phys_addr_t base) +static void realview_gic_map_setup(RealViewGICState *s) { - RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev); - cpu_register_physical_memory(base, 0x1000, s->iomemtype); - cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype); + memory_region_init(&s->container, "realview-gic-container", 0x2000); + memory_region_init_io(&s->iomem, &realview_gic_cpu_ops, &s->gic, + "realview-gic", 0x1000); + memory_region_add_subregion(&s->container, 0, &s->iomem); + memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem); } static int realview_gic_init(SysBusDevice *dev) @@ -63,10 +61,8 @@ static int realview_gic_init(SysBusDevice *dev) RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev); gic_init(&s->gic); - s->iomemtype = cpu_register_io_memory(realview_gic_cpu_readfn, - realview_gic_cpu_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio_cb(dev, 0x2000, realview_gic_map); + realview_gic_map_setup(s); + sysbus_init_mmio_region(dev, &s->container); return 0; } diff --git a/hw/rtl8139.c b/hw/rtl8139.c index a22530c..aa8ed0a 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -45,14 +45,20 @@ * 2010-Feb-04 Frediano Ziglio: Rewrote timer support using QEMU timer only * when strictly needed (required for for * Darwin) + * 2011-Mar-22 Benjamin Poirier: Implemented VLAN offloading */ +/* For crc32 */ +#include + #include "hw.h" #include "pci.h" +#include "dma.h" #include "qemu-timer.h" #include "net.h" #include "loader.h" #include "sysemu.h" +#include "iov.h" /* debug RTL8139 card */ //#define DEBUG_RTL8139 1 @@ -62,14 +68,6 @@ /* debug RTL8139 card C+ mode only */ //#define DEBUG_RTL8139CP 1 -/* Calculate CRCs properly on Rx packets */ -#define RTL8139_CALCULATE_RXCRC 1 - -#if defined(RTL8139_CALCULATE_RXCRC) -/* For crc32 */ -#include -#endif - #define SET_MASKED(input, mask, curr) \ ( ( (input) & ~(mask) ) | ( (curr) & (mask) ) ) @@ -77,10 +75,24 @@ #define MOD2(input, size) \ ( ( input ) & ( size - 1 ) ) +#define ETHER_ADDR_LEN 6 +#define ETHER_TYPE_LEN 2 +#define ETH_HLEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ +#define ETH_MTU 1500 + +#define VLAN_TCI_LEN 2 +#define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN) + #if defined (DEBUG_RTL8139) -# define DEBUG_PRINT(x) do { printf x ; } while (0) +# define DPRINTF(fmt, ...) \ + do { fprintf(stderr, "RTL8139: " fmt, ## __VA_ARGS__); } while (0) #else -# define DEBUG_PRINT(x) +static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...) +{ + return 0; +} #endif /* Symbolic offsets to registers. */ @@ -416,9 +428,6 @@ typedef struct RTL8139TallyCounters /* Clears all tally counters */ static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters); -/* Writes tally counters to specified physical memory address */ -static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters); - typedef struct RTL8139State { PCIDevice dev; uint8_t phys[8]; /* mac address */ @@ -463,7 +472,6 @@ typedef struct RTL8139State { NICState *nic; NICConf conf; - int rtl8139_mmio_io_addr; /* C ring mode */ uint32_t currTxDesc; @@ -495,15 +503,21 @@ typedef struct RTL8139State { QEMUTimer *timer; int64_t TimerExpire; + MemoryRegion bar_io; + MemoryRegion bar_mem; + /* Support migration to/from old versions */ int rtl8139_mmio_io_addr_dummy; } RTL8139State; +/* Writes tally counters to memory via DMA */ +static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr); + static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time); static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) { - DEBUG_PRINT(("RTL8139: eeprom command 0x%02x\n", command)); + DPRINTF("eeprom command 0x%02x\n", command); switch (command & Chip9346_op_mask) { @@ -514,8 +528,8 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) eeprom->eedo = 0; eeprom->tick = 0; eeprom->mode = Chip9346_data_read; - DEBUG_PRINT(("RTL8139: eeprom read from address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->output)); + DPRINTF("eeprom read from address 0x%02x data=0x%04x\n", + eeprom->address, eeprom->output); } break; @@ -525,8 +539,8 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) eeprom->input = 0; eeprom->tick = 0; eeprom->mode = Chip9346_none; /* Chip9346_data_write */ - DEBUG_PRINT(("RTL8139: eeprom begin write to address 0x%02x\n", - eeprom->address)); + DPRINTF("eeprom begin write to address 0x%02x\n", + eeprom->address); } break; default: @@ -534,13 +548,13 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) switch (command & Chip9346_op_ext_mask) { case Chip9346_op_write_enable: - DEBUG_PRINT(("RTL8139: eeprom write enabled\n")); + DPRINTF("eeprom write enabled\n"); break; case Chip9346_op_write_all: - DEBUG_PRINT(("RTL8139: eeprom begin write all\n")); + DPRINTF("eeprom begin write all\n"); break; case Chip9346_op_write_disable: - DEBUG_PRINT(("RTL8139: eeprom write disabled\n")); + DPRINTF("eeprom write disabled\n"); break; } break; @@ -553,7 +567,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom) ++ eeprom->tick; - DEBUG_PRINT(("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, eeprom->eedo)); + DPRINTF("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, + eeprom->eedo); switch (eeprom->mode) { @@ -563,7 +578,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom) eeprom->mode = Chip9346_read_command; eeprom->tick = 0; eeprom->input = 0; - DEBUG_PRINT(("eeprom: +++ synchronized, begin command read\n")); + DPRINTF("eeprom: +++ synchronized, begin command read\n"); } break; @@ -588,7 +603,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom) eeprom->input = 0; eeprom->tick = 0; - DEBUG_PRINT(("eeprom: +++ end of read, awaiting next command\n")); + DPRINTF("eeprom: +++ end of read, awaiting next command\n"); #else // original behaviour ++eeprom->address; @@ -596,8 +611,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom) eeprom->output = eeprom->contents[eeprom->address]; eeprom->tick = 0; - DEBUG_PRINT(("eeprom: +++ read next address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->output)); + DPRINTF("eeprom: +++ read next address 0x%02x data=0x%04x\n", + eeprom->address, eeprom->output); #endif } break; @@ -606,8 +621,8 @@ static void prom9346_shift_clock(EEprom9346 *eeprom) eeprom->input = (eeprom->input << 1) | (bit & 1); if (eeprom->tick == 16) { - DEBUG_PRINT(("RTL8139: eeprom write to address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->input)); + DPRINTF("eeprom write to address 0x%02x data=0x%04x\n", + eeprom->address, eeprom->input); eeprom->contents[eeprom->address] = eeprom->input; eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */ @@ -625,8 +640,7 @@ static void prom9346_shift_clock(EEprom9346 *eeprom) { eeprom->contents[i] = eeprom->input; } - DEBUG_PRINT(("RTL8139: eeprom filled with data=0x%04x\n", - eeprom->input)); + DPRINTF("eeprom filled with data=0x%04x\n", eeprom->input); eeprom->mode = Chip9346_enter_command_mode; eeprom->tick = 0; @@ -659,8 +673,8 @@ static void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi) eeprom->eesk = eesk; eeprom->eedi = eedi; - DEBUG_PRINT(("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n", - eeprom->eecs, eeprom->eesk, eeprom->eedi, eeprom->eedo)); + DPRINTF("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n", eeprom->eecs, + eeprom->eesk, eeprom->eedi, eeprom->eedo); if (!old_eecs && eecs) { @@ -670,12 +684,12 @@ static void prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi) eeprom->output = 0; eeprom->mode = Chip9346_enter_command_mode; - DEBUG_PRINT(("=== eeprom: begin access, enter command mode\n")); + DPRINTF("=== eeprom: begin access, enter command mode\n"); } if (!eecs) { - DEBUG_PRINT(("=== eeprom: end access\n")); + DPRINTF("=== eeprom: end access\n"); return; } @@ -691,8 +705,8 @@ static void rtl8139_update_irq(RTL8139State *s) int isr; isr = (s->IntrStatus & s->IntrMask) & 0xffff; - DEBUG_PRINT(("RTL8139: Set IRQ to %d (%04x %04x)\n", - isr ? 1 : 0, s->IntrStatus, s->IntrMask)); + DPRINTF("Set IRQ to %d (%04x %04x)\n", isr ? 1 : 0, s->IntrStatus, + s->IntrMask); qemu_set_irq(s->dev.irq[0], (isr != 0)); } @@ -756,19 +770,19 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) /* write packet data */ if (wrapped && !(s->RxBufferSize < 65536 && rtl8139_RxWrap(s))) { - DEBUG_PRINT((">>> RTL8139: rx packet wrapped in buffer at %d\n", size-wrapped)); + DPRINTF(">>> rx packet wrapped in buffer at %d\n", size - wrapped); if (size > wrapped) { - cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, - buf, size-wrapped ); + pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, + buf, size-wrapped); } /* reset buffer pointer */ s->RxBufAddr = 0; - cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, - buf + (size-wrapped), wrapped ); + pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, + buf + (size-wrapped), wrapped); s->RxBufAddr = wrapped; @@ -777,13 +791,13 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) } /* non-wrapping path or overwrapping enabled */ - cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size ); + pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, buf, size); s->RxBufAddr += size; } #define MIN_BUF_SIZE 60 -static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high) +static inline dma_addr_t rtl8139_addr64(uint32_t low, uint32_t high) { #if TARGET_PHYS_ADDR_BITS > 32 return low | ((target_phys_addr_t)high << 32); @@ -817,20 +831,22 @@ static int rtl8139_can_receive(VLANClientState *nc) static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt) { RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque; + /* size is the length of the buffer passed to the driver */ int size = size_; + const uint8_t *dot1q_buf = NULL; uint32_t packet_header = 0; - uint8_t buf1[60]; + uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN]; static const uint8_t broadcast_macaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - DEBUG_PRINT((">>> RTL8139: received len=%d\n", size)); + DPRINTF(">>> received len=%d\n", size); /* test if board clock is stopped */ if (!s->clock_enabled) { - DEBUG_PRINT(("RTL8139: stopped ==========================\n")); + DPRINTF("stopped ==========================\n"); return -1; } @@ -838,21 +854,21 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ if (!rtl8139_receiver_enabled(s)) { - DEBUG_PRINT(("RTL8139: receiver disabled ================\n")); + DPRINTF("receiver disabled ================\n"); return -1; } /* XXX: check this */ if (s->RxConfig & AcceptAllPhys) { /* promiscuous: receive all */ - DEBUG_PRINT((">>> RTL8139: packet received in promiscuous mode\n")); + DPRINTF(">>> packet received in promiscuous mode\n"); } else { if (!memcmp(buf, broadcast_macaddr, 6)) { /* broadcast address */ if (!(s->RxConfig & AcceptBroadcast)) { - DEBUG_PRINT((">>> RTL8139: broadcast packet rejected\n")); + DPRINTF(">>> broadcast packet rejected\n"); /* update tally counter */ ++s->tally_counters.RxERR; @@ -862,7 +878,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ packet_header |= RxBroadcast; - DEBUG_PRINT((">>> RTL8139: broadcast packet received\n")); + DPRINTF(">>> broadcast packet received\n"); /* update tally counter */ ++s->tally_counters.RxOkBrd; @@ -871,7 +887,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ /* multicast */ if (!(s->RxConfig & AcceptMulticast)) { - DEBUG_PRINT((">>> RTL8139: multicast packet rejected\n")); + DPRINTF(">>> multicast packet rejected\n"); /* update tally counter */ ++s->tally_counters.RxERR; @@ -883,7 +899,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) { - DEBUG_PRINT((">>> RTL8139: multicast address mismatch\n")); + DPRINTF(">>> multicast address mismatch\n"); /* update tally counter */ ++s->tally_counters.RxERR; @@ -893,7 +909,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ packet_header |= RxMulticast; - DEBUG_PRINT((">>> RTL8139: multicast packet received\n")); + DPRINTF(">>> multicast packet received\n"); /* update tally counter */ ++s->tally_counters.RxOkMul; @@ -907,7 +923,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ /* match */ if (!(s->RxConfig & AcceptMyPhys)) { - DEBUG_PRINT((">>> RTL8139: rejecting physical address matching packet\n")); + DPRINTF(">>> rejecting physical address matching packet\n"); /* update tally counter */ ++s->tally_counters.RxERR; @@ -917,14 +933,14 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ packet_header |= RxPhysical; - DEBUG_PRINT((">>> RTL8139: physical address matching packet received\n")); + DPRINTF(">>> physical address matching packet received\n"); /* update tally counter */ ++s->tally_counters.RxOkPhy; } else { - DEBUG_PRINT((">>> RTL8139: unknown packet\n")); + DPRINTF(">>> unknown packet\n"); /* update tally counter */ ++s->tally_counters.RxERR; @@ -933,17 +949,20 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ } } - /* if too small buffer, then expand it */ - if (size < MIN_BUF_SIZE) { + /* if too small buffer, then expand it + * Include some tailroom in case a vlan tag is later removed. */ + if (size < MIN_BUF_SIZE + VLAN_HLEN) { memcpy(buf1, buf, size); - memset(buf1 + size, 0, MIN_BUF_SIZE - size); + memset(buf1 + size, 0, MIN_BUF_SIZE + VLAN_HLEN - size); buf = buf1; - size = MIN_BUF_SIZE; + if (size < MIN_BUF_SIZE) { + size = MIN_BUF_SIZE; + } } if (rtl8139_cp_receiver_enabled(s)) { - DEBUG_PRINT(("RTL8139: in C+ Rx mode ================\n")); + DPRINTF("in C+ Rx mode ================\n"); /* begin C+ receiver mode */ @@ -961,32 +980,33 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ /* w3 high 32bit of Rx buffer ptr */ int descriptor = s->currCPlusRxDesc; - target_phys_addr_t cplus_rx_ring_desc; + dma_addr_t cplus_rx_ring_desc; cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI); cplus_rx_ring_desc += 16 * descriptor; - DEBUG_PRINT(("RTL8139: +++ C+ mode reading RX descriptor %d from host memory at %08x %08x = %016" PRIx64 "\n", - descriptor, s->RxRingAddrHI, s->RxRingAddrLO, (uint64_t)cplus_rx_ring_desc)); + DPRINTF("+++ C+ mode reading RX descriptor %d from host memory at " + "%08x %08x = "DMA_ADDR_FMT"\n", descriptor, s->RxRingAddrHI, + s->RxRingAddrLO, cplus_rx_ring_desc); uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI; - cpu_physical_memory_read(cplus_rx_ring_desc, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_rx_ring_desc, (uint8_t *)&val, 4); rxdw0 = le32_to_cpu(val); - cpu_physical_memory_read(cplus_rx_ring_desc+4, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_rx_ring_desc+4, (uint8_t *)&val, 4); rxdw1 = le32_to_cpu(val); - cpu_physical_memory_read(cplus_rx_ring_desc+8, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_rx_ring_desc+8, (uint8_t *)&val, 4); rxbufLO = le32_to_cpu(val); - cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_rx_ring_desc+12, (uint8_t *)&val, 4); rxbufHI = le32_to_cpu(val); - DEBUG_PRINT(("RTL8139: +++ C+ mode RX descriptor %d %08x %08x %08x %08x\n", - descriptor, - rxdw0, rxdw1, rxbufLO, rxbufHI)); + DPRINTF("+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n", + descriptor, rxdw0, rxdw1, rxbufLO, rxbufHI); if (!(rxdw0 & CP_RX_OWN)) { - DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d is owned by host\n", descriptor)); + DPRINTF("C+ Rx mode : descriptor %d is owned by host\n", + descriptor); s->IntrStatus |= RxOverflow; ++s->RxMissed; @@ -1001,12 +1021,34 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ uint32_t rx_space = rxdw0 & CP_RX_BUFFER_SIZE_MASK; + /* write VLAN info to descriptor variables. */ + if (s->CpCmd & CPlusRxVLAN && be16_to_cpup((uint16_t *) + &buf[ETHER_ADDR_LEN * 2]) == ETH_P_8021Q) { + dot1q_buf = &buf[ETHER_ADDR_LEN * 2]; + size -= VLAN_HLEN; + /* if too small buffer, use the tailroom added duing expansion */ + if (size < MIN_BUF_SIZE) { + size = MIN_BUF_SIZE; + } + + rxdw1 &= ~CP_RX_VLAN_TAG_MASK; + /* BE + ~le_to_cpu()~ + cpu_to_le() = BE */ + rxdw1 |= CP_RX_TAVA | le16_to_cpup((uint16_t *) + &dot1q_buf[ETHER_TYPE_LEN]); + + DPRINTF("C+ Rx mode : extracted vlan tag with tci: ""%u\n", + be16_to_cpup((uint16_t *)&dot1q_buf[ETHER_TYPE_LEN])); + } else { + /* reset VLAN tag flag */ + rxdw1 &= ~CP_RX_TAVA; + } + /* TODO: scatter the packet over available receive ring descriptors space */ if (size+4 > rx_space) { - DEBUG_PRINT(("RTL8139: C+ Rx mode : descriptor %d size %d received %d + 4\n", - descriptor, rx_space, size)); + DPRINTF("C+ Rx mode : descriptor %d size %d received %d + 4\n", + descriptor, rx_space, size); s->IntrStatus |= RxOverflow; ++s->RxMissed; @@ -1019,10 +1061,17 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ return size_; } - target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI); + dma_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI); /* receive/copy to target memory */ - cpu_physical_memory_write( rx_addr, buf, size ); + if (dot1q_buf) { + pci_dma_write(&s->dev, rx_addr, buf, 2 * ETHER_ADDR_LEN); + pci_dma_write(&s->dev, rx_addr + 2 * ETHER_ADDR_LEN, + buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN, + size - 2 * ETHER_ADDR_LEN); + } else { + pci_dma_write(&s->dev, rx_addr, buf, size); + } if (s->CpCmd & CPlusRxChkSum) { @@ -1030,12 +1079,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ } /* write checksum */ -#if defined (RTL8139_CALCULATE_RXCRC) - val = cpu_to_le32(crc32(0, buf, size)); -#else - val = 0; -#endif - cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4); + val = cpu_to_le32(crc32(0, buf, size_)); + pci_dma_write(&s->dev, rx_addr+size, (uint8_t *)&val, 4); /* first segment of received packet flag */ #define CP_RX_STATUS_FS (1<<29) @@ -1079,14 +1124,11 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ rxdw0 &= ~CP_RX_BUFFER_SIZE_MASK; rxdw0 |= (size+4); - /* reset VLAN tag flag */ - rxdw1 &= ~CP_RX_TAVA; - /* update ring data */ val = cpu_to_le32(rxdw0); - cpu_physical_memory_write(cplus_rx_ring_desc, (uint8_t *)&val, 4); + pci_dma_write(&s->dev, cplus_rx_ring_desc, (uint8_t *)&val, 4); val = cpu_to_le32(rxdw1); - cpu_physical_memory_write(cplus_rx_ring_desc+4, (uint8_t *)&val, 4); + pci_dma_write(&s->dev, cplus_rx_ring_desc+4, (uint8_t *)&val, 4); /* update tally counter */ ++s->tally_counters.RxOk; @@ -1101,12 +1143,12 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ ++s->currCPlusRxDesc; } - DEBUG_PRINT(("RTL8139: done C+ Rx mode ----------------\n")); + DPRINTF("done C+ Rx mode ----------------\n"); } else { - DEBUG_PRINT(("RTL8139: in ring Rx mode ================\n")); + DPRINTF("in ring Rx mode ================\n"); /* begin ring receiver mode */ int avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize); @@ -1115,8 +1157,9 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ if (avail != 0 && size + 8 >= avail) { - DEBUG_PRINT(("rx overflow: rx buffer length %d head 0x%04x read 0x%04x === available 0x%04x need 0x%04x\n", - s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8)); + DPRINTF("rx overflow: rx buffer length %d head 0x%04x " + "read 0x%04x === available 0x%04x need 0x%04x\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8); s->IntrStatus |= RxOverflow; ++s->RxMissed; @@ -1136,12 +1179,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ rtl8139_write_buffer(s, buf, size); /* write checksum */ -#if defined (RTL8139_CALCULATE_RXCRC) val = cpu_to_le32(crc32(0, buf, size)); -#else - val = 0; -#endif - rtl8139_write_buffer(s, (uint8_t *)&val, 4); /* correct buffer write pointer */ @@ -1149,8 +1187,8 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ /* now we can signal we have received something */ - DEBUG_PRINT((" received: rx buffer length %d head 0x%04x read 0x%04x\n", - s->RxBufferSize, s->RxBufAddr, s->RxBufPtr)); + DPRINTF("received: rx buffer length %d head 0x%04x read 0x%04x\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr); } s->IntrStatus |= RxOK; @@ -1189,18 +1227,6 @@ static void rtl8139_reset(DeviceState *d) rtl8139_update_irq(s); - /* prepare eeprom */ - s->eeprom.contents[0] = 0x8129; -#if 1 - // PCI vendor and device ID should be mirrored here - s->eeprom.contents[1] = PCI_VENDOR_ID_REALTEK; - s->eeprom.contents[2] = PCI_DEVICE_ID_REALTEK_8139; -#endif - - s->eeprom.contents[7] = s->conf.macaddr.a[0] | s->conf.macaddr.a[1] << 8; - s->eeprom.contents[8] = s->conf.macaddr.a[2] | s->conf.macaddr.a[3] << 8; - s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8; - /* mark all status registers as owned by host */ for (i = 0; i < 4; ++i) { @@ -1282,50 +1308,51 @@ static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters) counters->TxUndrn = 0; } -static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters) +static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr) { + RTL8139TallyCounters *tally_counters = &s->tally_counters; uint16_t val16; uint32_t val32; uint64_t val64; val64 = cpu_to_le64(tally_counters->TxOk); - cpu_physical_memory_write(tc_addr + 0, (uint8_t *)&val64, 8); + pci_dma_write(&s->dev, tc_addr + 0, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->RxOk); - cpu_physical_memory_write(tc_addr + 8, (uint8_t *)&val64, 8); + pci_dma_write(&s->dev, tc_addr + 8, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->TxERR); - cpu_physical_memory_write(tc_addr + 16, (uint8_t *)&val64, 8); + pci_dma_write(&s->dev, tc_addr + 16, (uint8_t *)&val64, 8); val32 = cpu_to_le32(tally_counters->RxERR); - cpu_physical_memory_write(tc_addr + 24, (uint8_t *)&val32, 4); + pci_dma_write(&s->dev, tc_addr + 24, (uint8_t *)&val32, 4); val16 = cpu_to_le16(tally_counters->MissPkt); - cpu_physical_memory_write(tc_addr + 28, (uint8_t *)&val16, 2); + pci_dma_write(&s->dev, tc_addr + 28, (uint8_t *)&val16, 2); val16 = cpu_to_le16(tally_counters->FAE); - cpu_physical_memory_write(tc_addr + 30, (uint8_t *)&val16, 2); + pci_dma_write(&s->dev, tc_addr + 30, (uint8_t *)&val16, 2); val32 = cpu_to_le32(tally_counters->Tx1Col); - cpu_physical_memory_write(tc_addr + 32, (uint8_t *)&val32, 4); + pci_dma_write(&s->dev, tc_addr + 32, (uint8_t *)&val32, 4); val32 = cpu_to_le32(tally_counters->TxMCol); - cpu_physical_memory_write(tc_addr + 36, (uint8_t *)&val32, 4); + pci_dma_write(&s->dev, tc_addr + 36, (uint8_t *)&val32, 4); val64 = cpu_to_le64(tally_counters->RxOkPhy); - cpu_physical_memory_write(tc_addr + 40, (uint8_t *)&val64, 8); + pci_dma_write(&s->dev, tc_addr + 40, (uint8_t *)&val64, 8); val64 = cpu_to_le64(tally_counters->RxOkBrd); - cpu_physical_memory_write(tc_addr + 48, (uint8_t *)&val64, 8); + pci_dma_write(&s->dev, tc_addr + 48, (uint8_t *)&val64, 8); val32 = cpu_to_le32(tally_counters->RxOkMul); - cpu_physical_memory_write(tc_addr + 56, (uint8_t *)&val32, 4); + pci_dma_write(&s->dev, tc_addr + 56, (uint8_t *)&val32, 4); val16 = cpu_to_le16(tally_counters->TxAbt); - cpu_physical_memory_write(tc_addr + 60, (uint8_t *)&val16, 2); + pci_dma_write(&s->dev, tc_addr + 60, (uint8_t *)&val16, 2); val16 = cpu_to_le16(tally_counters->TxUndrn); - cpu_physical_memory_write(tc_addr + 62, (uint8_t *)&val16, 2); + pci_dma_write(&s->dev, tc_addr + 62, (uint8_t *)&val16, 2); } /* Loads values of tally counters from VM state file */ @@ -1356,27 +1383,27 @@ static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val) { val &= 0xff; - DEBUG_PRINT(("RTL8139: ChipCmd write val=0x%08x\n", val)); + DPRINTF("ChipCmd write val=0x%08x\n", val); if (val & CmdReset) { - DEBUG_PRINT(("RTL8139: ChipCmd reset\n")); + DPRINTF("ChipCmd reset\n"); rtl8139_reset(&s->dev.qdev); } if (val & CmdRxEnb) { - DEBUG_PRINT(("RTL8139: ChipCmd enable receiver\n")); + DPRINTF("ChipCmd enable receiver\n"); s->currCPlusRxDesc = 0; } if (val & CmdTxEnb) { - DEBUG_PRINT(("RTL8139: ChipCmd enable transmitter\n")); + DPRINTF("ChipCmd enable transmitter\n"); s->currCPlusTxDesc = 0; } - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0xe3, s->bChipCmdState); /* Deassert reset pin before next read */ @@ -1391,11 +1418,11 @@ static int rtl8139_RxBufferEmpty(RTL8139State *s) if (unread != 0) { - DEBUG_PRINT(("RTL8139: receiver buffer data available 0x%04x\n", unread)); + DPRINTF("receiver buffer data available 0x%04x\n", unread); return 0; } - DEBUG_PRINT(("RTL8139: receiver buffer is empty\n")); + DPRINTF("receiver buffer is empty\n"); return 1; } @@ -1407,7 +1434,7 @@ static uint32_t rtl8139_ChipCmd_read(RTL8139State *s) if (rtl8139_RxBufferEmpty(s)) ret |= RxBufEmpty; - DEBUG_PRINT(("RTL8139: ChipCmd read val=0x%04x\n", ret)); + DPRINTF("ChipCmd read val=0x%04x\n", ret); return ret; } @@ -1416,11 +1443,11 @@ static void rtl8139_CpCmd_write(RTL8139State *s, uint32_t val) { val &= 0xffff; - DEBUG_PRINT(("RTL8139C+ command register write(w) val=0x%04x\n", val)); + DPRINTF("C+ command register write(w) val=0x%04x\n", val); s->cplus_enabled = 1; - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0xff84, s->CpCmd); s->CpCmd = val; @@ -1430,33 +1457,33 @@ static uint32_t rtl8139_CpCmd_read(RTL8139State *s) { uint32_t ret = s->CpCmd; - DEBUG_PRINT(("RTL8139C+ command register read(w) val=0x%04x\n", ret)); + DPRINTF("C+ command register read(w) val=0x%04x\n", ret); return ret; } static void rtl8139_IntrMitigate_write(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139C+ IntrMitigate register write(w) val=0x%04x\n", val)); + DPRINTF("C+ IntrMitigate register write(w) val=0x%04x\n", val); } static uint32_t rtl8139_IntrMitigate_read(RTL8139State *s) { uint32_t ret = 0; - DEBUG_PRINT(("RTL8139C+ IntrMitigate register read(w) val=0x%04x\n", ret)); + DPRINTF("C+ IntrMitigate register read(w) val=0x%04x\n", ret); return ret; } -static int rtl8139_config_writeable(RTL8139State *s) +static int rtl8139_config_writable(RTL8139State *s) { if (s->Cfg9346 & Cfg9346_Unlock) { return 1; } - DEBUG_PRINT(("RTL8139: Configuration registers are write-protected\n")); + DPRINTF("Configuration registers are write-protected\n"); return 0; } @@ -1465,12 +1492,12 @@ static void rtl8139_BasicModeCtrl_write(RTL8139State *s, uint32_t val) { val &= 0xffff; - DEBUG_PRINT(("RTL8139: BasicModeCtrl register write(w) val=0x%04x\n", val)); + DPRINTF("BasicModeCtrl register write(w) val=0x%04x\n", val); - /* mask unwriteable bits */ + /* mask unwritable bits */ uint32_t mask = 0x4cff; - if (1 || !rtl8139_config_writeable(s)) + if (1 || !rtl8139_config_writable(s)) { /* Speed setting and autonegotiation enable bits are read-only */ mask |= 0x3000; @@ -1487,7 +1514,7 @@ static uint32_t rtl8139_BasicModeCtrl_read(RTL8139State *s) { uint32_t ret = s->BasicModeCtrl; - DEBUG_PRINT(("RTL8139: BasicModeCtrl register read(w) val=0x%04x\n", ret)); + DPRINTF("BasicModeCtrl register read(w) val=0x%04x\n", ret); return ret; } @@ -1496,9 +1523,9 @@ static void rtl8139_BasicModeStatus_write(RTL8139State *s, uint32_t val) { val &= 0xffff; - DEBUG_PRINT(("RTL8139: BasicModeStatus register write(w) val=0x%04x\n", val)); + DPRINTF("BasicModeStatus register write(w) val=0x%04x\n", val); - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0xff3f, s->BasicModeStatus); s->BasicModeStatus = val; @@ -1508,7 +1535,7 @@ static uint32_t rtl8139_BasicModeStatus_read(RTL8139State *s) { uint32_t ret = s->BasicModeStatus; - DEBUG_PRINT(("RTL8139: BasicModeStatus register read(w) val=0x%04x\n", ret)); + DPRINTF("BasicModeStatus register read(w) val=0x%04x\n", ret); return ret; } @@ -1517,9 +1544,9 @@ static void rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val) { val &= 0xff; - DEBUG_PRINT(("RTL8139: Cfg9346 write val=0x%02x\n", val)); + DPRINTF("Cfg9346 write val=0x%02x\n", val); - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0x31, s->Cfg9346); uint32_t opmode = val & 0xc0; @@ -1560,7 +1587,7 @@ static uint32_t rtl8139_Cfg9346_read(RTL8139State *s) } } - DEBUG_PRINT(("RTL8139: Cfg9346 read val=0x%02x\n", ret)); + DPRINTF("Cfg9346 read val=0x%02x\n", ret); return ret; } @@ -1569,12 +1596,13 @@ static void rtl8139_Config0_write(RTL8139State *s, uint32_t val) { val &= 0xff; - DEBUG_PRINT(("RTL8139: Config0 write val=0x%02x\n", val)); + DPRINTF("Config0 write val=0x%02x\n", val); - if (!rtl8139_config_writeable(s)) + if (!rtl8139_config_writable(s)) { return; + } - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0xf8, s->Config0); s->Config0 = val; @@ -1584,7 +1612,7 @@ static uint32_t rtl8139_Config0_read(RTL8139State *s) { uint32_t ret = s->Config0; - DEBUG_PRINT(("RTL8139: Config0 read val=0x%02x\n", ret)); + DPRINTF("Config0 read val=0x%02x\n", ret); return ret; } @@ -1593,12 +1621,13 @@ static void rtl8139_Config1_write(RTL8139State *s, uint32_t val) { val &= 0xff; - DEBUG_PRINT(("RTL8139: Config1 write val=0x%02x\n", val)); + DPRINTF("Config1 write val=0x%02x\n", val); - if (!rtl8139_config_writeable(s)) + if (!rtl8139_config_writable(s)) { return; + } - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0xC, s->Config1); s->Config1 = val; @@ -1608,7 +1637,7 @@ static uint32_t rtl8139_Config1_read(RTL8139State *s) { uint32_t ret = s->Config1; - DEBUG_PRINT(("RTL8139: Config1 read val=0x%02x\n", ret)); + DPRINTF("Config1 read val=0x%02x\n", ret); return ret; } @@ -1617,12 +1646,13 @@ static void rtl8139_Config3_write(RTL8139State *s, uint32_t val) { val &= 0xff; - DEBUG_PRINT(("RTL8139: Config3 write val=0x%02x\n", val)); + DPRINTF("Config3 write val=0x%02x\n", val); - if (!rtl8139_config_writeable(s)) + if (!rtl8139_config_writable(s)) { return; + } - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0x8F, s->Config3); s->Config3 = val; @@ -1632,7 +1662,7 @@ static uint32_t rtl8139_Config3_read(RTL8139State *s) { uint32_t ret = s->Config3; - DEBUG_PRINT(("RTL8139: Config3 read val=0x%02x\n", ret)); + DPRINTF("Config3 read val=0x%02x\n", ret); return ret; } @@ -1641,12 +1671,13 @@ static void rtl8139_Config4_write(RTL8139State *s, uint32_t val) { val &= 0xff; - DEBUG_PRINT(("RTL8139: Config4 write val=0x%02x\n", val)); + DPRINTF("Config4 write val=0x%02x\n", val); - if (!rtl8139_config_writeable(s)) + if (!rtl8139_config_writable(s)) { return; + } - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0x0a, s->Config4); s->Config4 = val; @@ -1656,7 +1687,7 @@ static uint32_t rtl8139_Config4_read(RTL8139State *s) { uint32_t ret = s->Config4; - DEBUG_PRINT(("RTL8139: Config4 read val=0x%02x\n", ret)); + DPRINTF("Config4 read val=0x%02x\n", ret); return ret; } @@ -1665,9 +1696,9 @@ static void rtl8139_Config5_write(RTL8139State *s, uint32_t val) { val &= 0xff; - DEBUG_PRINT(("RTL8139: Config5 write val=0x%02x\n", val)); + DPRINTF("Config5 write val=0x%02x\n", val); - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0x80, s->Config5); s->Config5 = val; @@ -1677,7 +1708,7 @@ static uint32_t rtl8139_Config5_read(RTL8139State *s) { uint32_t ret = s->Config5; - DEBUG_PRINT(("RTL8139: Config5 read val=0x%02x\n", ret)); + DPRINTF("Config5 read val=0x%02x\n", ret); return ret; } @@ -1686,11 +1717,11 @@ static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val) { if (!rtl8139_transmitter_enabled(s)) { - DEBUG_PRINT(("RTL8139: transmitter disabled; no TxConfig write val=0x%08x\n", val)); + DPRINTF("transmitter disabled; no TxConfig write val=0x%08x\n", val); return; } - DEBUG_PRINT(("RTL8139: TxConfig write val=0x%08x\n", val)); + DPRINTF("TxConfig write val=0x%08x\n", val); val = SET_MASKED(val, TxVersionMask | 0x8070f80f, s->TxConfig); @@ -1699,7 +1730,7 @@ static void rtl8139_TxConfig_write(RTL8139State *s, uint32_t val) static void rtl8139_TxConfig_writeb(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139C TxConfig via write(b) val=0x%02x\n", val)); + DPRINTF("RTL8139C TxConfig via write(b) val=0x%02x\n", val); uint32_t tc = s->TxConfig; tc &= 0xFFFFFF00; @@ -1711,16 +1742,16 @@ static uint32_t rtl8139_TxConfig_read(RTL8139State *s) { uint32_t ret = s->TxConfig; - DEBUG_PRINT(("RTL8139: TxConfig read val=0x%04x\n", ret)); + DPRINTF("TxConfig read val=0x%04x\n", ret); return ret; } static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139: RxConfig write val=0x%08x\n", val)); + DPRINTF("RxConfig write val=0x%08x\n", val); - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0xf0fc0040, s->RxConfig); s->RxConfig = val; @@ -1728,34 +1759,64 @@ static void rtl8139_RxConfig_write(RTL8139State *s, uint32_t val) /* reset buffer size and read/write pointers */ rtl8139_reset_rxring(s, 8192 << ((s->RxConfig >> 11) & 0x3)); - DEBUG_PRINT(("RTL8139: RxConfig write reset buffer size to %d\n", s->RxBufferSize)); + DPRINTF("RxConfig write reset buffer size to %d\n", s->RxBufferSize); } static uint32_t rtl8139_RxConfig_read(RTL8139State *s) { uint32_t ret = s->RxConfig; - DEBUG_PRINT(("RTL8139: RxConfig read val=0x%08x\n", ret)); + DPRINTF("RxConfig read val=0x%08x\n", ret); return ret; } -static void rtl8139_transfer_frame(RTL8139State *s, const uint8_t *buf, int size, int do_interrupt) +static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size, + int do_interrupt, const uint8_t *dot1q_buf) { + struct iovec *iov = NULL; + if (!size) { - DEBUG_PRINT(("RTL8139: +++ empty ethernet frame\n")); + DPRINTF("+++ empty ethernet frame\n"); return; } + if (dot1q_buf && size >= ETHER_ADDR_LEN * 2) { + iov = (struct iovec[3]) { + { .iov_base = buf, .iov_len = ETHER_ADDR_LEN * 2 }, + { .iov_base = (void *) dot1q_buf, .iov_len = VLAN_HLEN }, + { .iov_base = buf + ETHER_ADDR_LEN * 2, + .iov_len = size - ETHER_ADDR_LEN * 2 }, + }; + } + if (TxLoopBack == (s->TxConfig & TxLoopBack)) { - DEBUG_PRINT(("RTL8139: +++ transmit loopback mode\n")); + size_t buf2_size; + uint8_t *buf2; + + if (iov) { + buf2_size = iov_size(iov, 3); + buf2 = g_malloc(buf2_size); + iov_to_buf(iov, 3, buf2, 0, buf2_size); + buf = buf2; + } + + DPRINTF("+++ transmit loopback mode\n"); rtl8139_do_receive(&s->nic->nc, buf, size, do_interrupt); + + if (iov) { + g_free(buf2); + } } else { - qemu_send_packet(&s->nic->nc, buf, size); + if (iov) { + qemu_sendv_packet(&s->nic->nc, iov, 3); + } else { + qemu_send_packet(&s->nic->nc, buf, size); + } } } @@ -1763,35 +1824,36 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor) { if (!rtl8139_transmitter_enabled(s)) { - DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: transmitter disabled\n", - descriptor)); + DPRINTF("+++ cannot transmit from descriptor %d: transmitter " + "disabled\n", descriptor); return 0; } if (s->TxStatus[descriptor] & TxHostOwns) { - DEBUG_PRINT(("RTL8139: +++ cannot transmit from descriptor %d: owned by host (%08x)\n", - descriptor, s->TxStatus[descriptor])); + DPRINTF("+++ cannot transmit from descriptor %d: owned by host " + "(%08x)\n", descriptor, s->TxStatus[descriptor]); return 0; } - DEBUG_PRINT(("RTL8139: +++ transmitting from descriptor %d\n", descriptor)); + DPRINTF("+++ transmitting from descriptor %d\n", descriptor); int txsize = s->TxStatus[descriptor] & 0x1fff; uint8_t txbuffer[0x2000]; - DEBUG_PRINT(("RTL8139: +++ transmit reading %d bytes from host memory at 0x%08x\n", - txsize, s->TxAddr[descriptor])); + DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n", + txsize, s->TxAddr[descriptor]); - cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize); + pci_dma_read(&s->dev, s->TxAddr[descriptor], txbuffer, txsize); /* Mark descriptor as transferred */ s->TxStatus[descriptor] |= TxHostOwns; s->TxStatus[descriptor] |= TxStatOK; - rtl8139_transfer_frame(s, txbuffer, txsize, 0); + rtl8139_transfer_frame(s, txbuffer, txsize, 0, NULL); - DEBUG_PRINT(("RTL8139: +++ transmitted %d bytes from descriptor %d\n", txsize, descriptor)); + DPRINTF("+++ transmitted %d bytes from descriptor %d\n", txsize, + descriptor); /* update interrupt */ s->IntrStatus |= TxOK; @@ -1891,45 +1953,40 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) { if (!rtl8139_transmitter_enabled(s)) { - DEBUG_PRINT(("RTL8139: +++ C+ mode: transmitter disabled\n")); + DPRINTF("+++ C+ mode: transmitter disabled\n"); return 0; } if (!rtl8139_cp_transmitter_enabled(s)) { - DEBUG_PRINT(("RTL8139: +++ C+ mode: C+ transmitter disabled\n")); + DPRINTF("+++ C+ mode: C+ transmitter disabled\n"); return 0 ; } int descriptor = s->currCPlusTxDesc; - target_phys_addr_t cplus_tx_ring_desc = - rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]); + dma_addr_t cplus_tx_ring_desc = rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]); /* Normal priority ring */ cplus_tx_ring_desc += 16 * descriptor; - DEBUG_PRINT(("RTL8139: +++ C+ mode reading TX descriptor %d from host memory at %08x0x%08x = 0x%8lx\n", - descriptor, s->TxAddr[1], s->TxAddr[0], cplus_tx_ring_desc)); + DPRINTF("+++ C+ mode reading TX descriptor %d from host memory at " + "%08x %08x = 0x"DMA_ADDR_FMT"\n", descriptor, s->TxAddr[1], + s->TxAddr[0], cplus_tx_ring_desc); uint32_t val, txdw0,txdw1,txbufLO,txbufHI; - cpu_physical_memory_read(cplus_tx_ring_desc, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4); txdw0 = le32_to_cpu(val); - /* TODO: implement VLAN tagging support, VLAN tag data is read to txdw1 */ - cpu_physical_memory_read(cplus_tx_ring_desc+4, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_tx_ring_desc+4, (uint8_t *)&val, 4); txdw1 = le32_to_cpu(val); - cpu_physical_memory_read(cplus_tx_ring_desc+8, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_tx_ring_desc+8, (uint8_t *)&val, 4); txbufLO = le32_to_cpu(val); - cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4); + pci_dma_read(&s->dev, cplus_tx_ring_desc+12, (uint8_t *)&val, 4); txbufHI = le32_to_cpu(val); - DEBUG_PRINT(("RTL8139: +++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", - descriptor, - txdw0, txdw1, txbufLO, txbufHI)); - - /* TODO: the following discard cast should clean clang analyzer output */ - (void)txdw1; + DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor, + txdw0, txdw1, txbufLO, txbufHI); /* w0 ownership flag */ #define CP_TX_OWN (1<<31) @@ -1954,9 +2011,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) /* w0 bits 0...15 : buffer size */ #define CP_TX_BUFFER_SIZE (1<<16) #define CP_TX_BUFFER_SIZE_MASK (CP_TX_BUFFER_SIZE - 1) -/* w1 tag available flag */ -#define CP_RX_TAGC (1<<17) -/* w1 bits 0...15 : VLAN tag */ +/* w1 add tag flag */ +#define CP_TX_TAGC (1<<17) +/* w1 bits 0...15 : VLAN tag (big endian) */ #define CP_TX_VLAN_TAG_MASK ((1<<16) - 1) /* w2 low 32bit of Rx buffer ptr */ /* w3 high 32bit of Rx buffer ptr */ @@ -1975,46 +2032,50 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) if (!(txdw0 & CP_TX_OWN)) { - DEBUG_PRINT(("RTL8139: C+ Tx mode : descriptor %d is owned by host\n", descriptor)); + DPRINTF("C+ Tx mode : descriptor %d is owned by host\n", descriptor); return 0 ; } - DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : transmitting from descriptor %d\n", descriptor)); + DPRINTF("+++ C+ Tx mode : transmitting from descriptor %d\n", descriptor); if (txdw0 & CP_TX_FS) { - DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is first segment descriptor\n", descriptor)); + DPRINTF("+++ C+ Tx mode : descriptor %d is first segment " + "descriptor\n", descriptor); /* reset internal buffer offset */ s->cplus_txbuffer_offset = 0; } int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK; - target_phys_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI); + dma_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI); /* make sure we have enough space to assemble the packet */ if (!s->cplus_txbuffer) { s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE; - s->cplus_txbuffer = qemu_malloc(s->cplus_txbuffer_len); + s->cplus_txbuffer = g_malloc(s->cplus_txbuffer_len); s->cplus_txbuffer_offset = 0; - DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len)); + DPRINTF("+++ C+ mode transmission buffer allocated space %d\n", + s->cplus_txbuffer_len); } while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len) { s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE; - s->cplus_txbuffer = qemu_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len); + s->cplus_txbuffer = g_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len); - DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len)); + DPRINTF("+++ C+ mode transmission buffer space changed to %d\n", + s->cplus_txbuffer_len); } if (!s->cplus_txbuffer) { /* out of memory */ - DEBUG_PRINT(("RTL8139: +++ C+ mode transmiter failed to reallocate %d bytes\n", s->cplus_txbuffer_len)); + DPRINTF("+++ C+ mode transmiter failed to reallocate %d bytes\n", + s->cplus_txbuffer_len); /* update tally counter */ ++s->tally_counters.TxERR; @@ -2025,10 +2086,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) /* append more data to the packet */ - DEBUG_PRINT(("RTL8139: +++ C+ mode transmit reading %d bytes from host memory at %016" PRIx64 " to offset %d\n", - txsize, (uint64_t)tx_addr, s->cplus_txbuffer_offset)); + DPRINTF("+++ C+ mode transmit reading %d bytes from host memory at " + DMA_ADDR_FMT" to offset %d\n", txsize, tx_addr, + s->cplus_txbuffer_offset); - cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize); + pci_dma_read(&s->dev, tx_addr, + s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize); s->cplus_txbuffer_offset += txsize; /* seek to next Rx descriptor */ @@ -2055,15 +2118,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) /* update ring data */ val = cpu_to_le32(txdw0); - cpu_physical_memory_write(cplus_tx_ring_desc, (uint8_t *)&val, 4); - /* TODO: implement VLAN tagging support, VLAN tag data is read to txdw1 */ -// val = cpu_to_le32(txdw1); -// cpu_physical_memory_write(cplus_tx_ring_desc+4, &val, 4); + pci_dma_write(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4); /* Now decide if descriptor being processed is holding the last segment of packet */ if (txdw0 & CP_TX_LS) { - DEBUG_PRINT(("RTL8139: +++ C+ Tx mode : descriptor %d is last segment descriptor\n", descriptor)); + uint8_t dot1q_buffer_space[VLAN_HLEN]; + uint16_t *dot1q_buffer; + + DPRINTF("+++ C+ Tx mode : descriptor %d is last segment descriptor\n", + descriptor); /* can transfer fully assembled packet */ @@ -2071,6 +2135,21 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) int saved_size = s->cplus_txbuffer_offset; int saved_buffer_len = s->cplus_txbuffer_len; + /* create vlan tag */ + if (txdw1 & CP_TX_TAGC) { + /* the vlan tag is in BE byte order in the descriptor + * BE + le_to_cpu() + ~swap()~ = cpu */ + DPRINTF("+++ C+ Tx mode : inserting vlan tag with ""tci: %u\n", + bswap16(txdw1 & CP_TX_VLAN_TAG_MASK)); + + dot1q_buffer = (uint16_t *) dot1q_buffer_space; + dot1q_buffer[0] = cpu_to_be16(ETH_P_8021Q); + /* BE + le_to_cpu() + ~cpu_to_le()~ = BE */ + dot1q_buffer[1] = cpu_to_le16(txdw1 & CP_TX_VLAN_TAG_MASK); + } else { + dot1q_buffer = NULL; + } + /* reset the card space to protect from recursive call */ s->cplus_txbuffer = NULL; s->cplus_txbuffer_offset = 0; @@ -2078,11 +2157,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN)) { - DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task checksum\n")); - - #define ETH_P_IP 0x0800 /* Internet Protocol packet */ - #define ETH_HLEN 14 - #define ETH_MTU 1500 + DPRINTF("+++ C+ mode offloaded task checksum\n"); /* ip packet header */ ip_header *ip = NULL; @@ -2096,7 +2171,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); if (proto == ETH_P_IP) { - DEBUG_PRINT(("RTL8139: +++ C+ mode has IP packet\n")); + DPRINTF("+++ C+ mode has IP packet\n"); /* not aligned */ eth_payload_data = saved_buffer + ETH_HLEN; @@ -2105,7 +2180,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) ip = (ip_header*)eth_payload_data; if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { - DEBUG_PRINT(("RTL8139: +++ C+ mode packet has bad IP version %d expected %d\n", IP_HEADER_VERSION(ip), IP_HEADER_VERSION_4)); + DPRINTF("+++ C+ mode packet has bad IP version %d " + "expected %d\n", IP_HEADER_VERSION(ip), + IP_HEADER_VERSION_4); ip = NULL; } else { hlen = IP_HEADER_LENGTH(ip); @@ -2118,7 +2195,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) { if (txdw0 & CP_TX_IPCS) { - DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n")); + DPRINTF("+++ C+ mode need IP checksum\n"); if (hleneth_payload_len) {/* min header length */ /* bad packet header len */ @@ -2128,17 +2205,18 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) { ip->ip_sum = 0; ip->ip_sum = ip_checksum(ip, hlen); - DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum)); + DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", + hlen, ip->ip_sum); } } if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) { -#if defined (DEBUG_RTL8139) int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; -#endif - DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n", - ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss)); + + DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " + "frame data %d specified MSS=%d\n", ETH_MTU, + ip_data_len, saved_size - ETH_HLEN, large_send_mss); int tcp_send_offset = 0; int send_count = 0; @@ -2162,8 +2240,9 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) int tcp_data_len = ip_data_len - tcp_hlen; int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n", - ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size)); + DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " + "data len %d TCP chunk size %d\n", ip_data_len, + tcp_hlen, tcp_data_len, tcp_chunk_size); /* note the cycle below overwrites IP header data, but restores it from saved_ip_header before sending packet */ @@ -2181,13 +2260,16 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) chunk_size = tcp_data_len - tcp_send_offset; } - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq))); + DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", + be32_to_cpu(p_tcp_hdr->th_seq)); /* add 4 TCP pseudoheader fields */ /* copy IP source and destination fields */ memcpy(data_to_checksum, saved_ip_header + 12, 8); - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size)); + DPRINTF("+++ C+ mode TSO calculating TCP checksum for " + "packet with %d bytes data\n", tcp_hlen + + chunk_size); if (tcp_send_offset) { @@ -2209,7 +2291,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) p_tcp_hdr->th_sum = 0; int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum)); + DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", + tcp_checksum); p_tcp_hdr->th_sum = tcp_checksum; @@ -2224,11 +2307,14 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) ip->ip_sum = 0; ip->ip_sum = ip_checksum(eth_payload_data, hlen); - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum)); + DPRINTF("+++ C+ mode TSO IP header len=%d " + "checksum=%04x\n", hlen, ip->ip_sum); int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; - DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size)); - rtl8139_transfer_frame(s, saved_buffer, tso_send_size, 0); + DPRINTF("+++ C+ mode TSO transferring packet size " + "%d\n", tso_send_size); + rtl8139_transfer_frame(s, saved_buffer, tso_send_size, + 0, (uint8_t *) dot1q_buffer); /* add transferred count to TCP sequence number */ p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); @@ -2240,7 +2326,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) } else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) { - DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n")); + DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); /* maximum IP header length is 60 bytes */ uint8_t saved_ip_header[60]; @@ -2255,7 +2341,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) { - DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len)); + DPRINTF("+++ C+ mode calculating TCP checksum for " + "packet with %d bytes data\n", ip_data_len); ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; p_tcpip_hdr->zeros = 0; @@ -2267,13 +2354,15 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) p_tcp_hdr->th_sum = 0; int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); - DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum)); + DPRINTF("+++ C+ mode TCP checksum %04x\n", + tcp_checksum); p_tcp_hdr->th_sum = tcp_checksum; } else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) { - DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len)); + DPRINTF("+++ C+ mode calculating UDP checksum for " + "packet with %d bytes data\n", ip_data_len); ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; p_udpip_hdr->zeros = 0; @@ -2285,7 +2374,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) p_udp_hdr->uh_sum = 0; int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); - DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum)); + DPRINTF("+++ C+ mode UDP checksum %04x\n", + udp_checksum); p_udp_hdr->uh_sum = udp_checksum; } @@ -2299,9 +2389,10 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) /* update tally counter */ ++s->tally_counters.TxOk; - DEBUG_PRINT(("RTL8139: +++ C+ mode transmitting %d bytes packet\n", saved_size)); + DPRINTF("+++ C+ mode transmitting %d bytes packet\n", saved_size); - rtl8139_transfer_frame(s, saved_buffer, saved_size, 1); + rtl8139_transfer_frame(s, saved_buffer, saved_size, 1, + (uint8_t *) dot1q_buffer); /* restore card space if there was no recursion and reset offset */ if (!s->cplus_txbuffer) @@ -2312,12 +2403,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) } else { - qemu_free(saved_buffer); + g_free(saved_buffer); } } else { - DEBUG_PRINT(("RTL8139: +++ C+ mode transmission continue to next descriptor\n")); + DPRINTF("+++ C+ mode transmission continue to next descriptor\n"); } return 1; @@ -2335,8 +2426,8 @@ static void rtl8139_cplus_transmit(RTL8139State *s) /* Mark transfer completed */ if (!txcount) { - DEBUG_PRINT(("RTL8139: C+ mode : transmitter queue stalled, current TxDesc = %d\n", - s->currCPlusTxDesc)); + DPRINTF("C+ mode : transmitter queue stalled, current TxDesc = %d\n", + s->currCPlusTxDesc); } else { @@ -2361,7 +2452,8 @@ static void rtl8139_transmit(RTL8139State *s) /* Mark transfer completed */ if (!txcount) { - DEBUG_PRINT(("RTL8139: transmitter queue stalled, current TxDesc = %d\n", s->currTxDesc)); + DPRINTF("transmitter queue stalled, current TxDesc = %d\n", + s->currTxDesc); } } @@ -2374,7 +2466,8 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32 if (s->cplus_enabled) { - DEBUG_PRINT(("RTL8139C+ DTCCR write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor)); + DPRINTF("RTL8139C+ DTCCR write offset=0x%x val=0x%08x " + "descriptor=%d\n", txRegOffset, val, descriptor); /* handle Dump Tally Counters command */ s->TxStatus[descriptor] = val; @@ -2384,7 +2477,7 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32 target_phys_addr_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]); /* dump tally counters to specified memory location */ - RTL8139TallyCounters_physical_memory_write( tc_addr, &s->tally_counters); + RTL8139TallyCounters_dma_write(s, tc_addr); /* mark dump completed */ s->TxStatus[0] &= ~0x8; @@ -2393,7 +2486,8 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32 return; } - DEBUG_PRINT(("RTL8139: TxStatus write offset=0x%x val=0x%08x descriptor=%d\n", txRegOffset, val, descriptor)); + DPRINTF("TxStatus write offset=0x%x val=0x%08x descriptor=%d\n", + txRegOffset, val, descriptor); /* mask only reserved bits */ val &= ~0xff00c000; /* these bits are reset on write */ @@ -2409,7 +2503,7 @@ static uint32_t rtl8139_TxStatus_read(RTL8139State *s, uint32_t txRegOffset) { uint32_t ret = s->TxStatus[txRegOffset/4]; - DEBUG_PRINT(("RTL8139: TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret)); + DPRINTF("TxStatus read offset=0x%x val=0x%08x\n", txRegOffset, ret); return ret; } @@ -2441,7 +2535,7 @@ static uint16_t rtl8139_TSAD_read(RTL8139State *s) |((s->TxStatus[0] & TxHostOwns )?TSAD_OWN0:0) ; - DEBUG_PRINT(("RTL8139: TSAD read val=0x%04x\n", ret)); + DPRINTF("TSAD read val=0x%04x\n", ret); return ret; } @@ -2450,14 +2544,14 @@ static uint16_t rtl8139_CSCR_read(RTL8139State *s) { uint16_t ret = s->CSCR; - DEBUG_PRINT(("RTL8139: CSCR read val=0x%04x\n", ret)); + DPRINTF("CSCR read val=0x%04x\n", ret); return ret; } static void rtl8139_TxAddr_write(RTL8139State *s, uint32_t txAddrOffset, uint32_t val) { - DEBUG_PRINT(("RTL8139: TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val)); + DPRINTF("TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val); s->TxAddr[txAddrOffset/4] = val; } @@ -2466,20 +2560,20 @@ static uint32_t rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset) { uint32_t ret = s->TxAddr[txAddrOffset/4]; - DEBUG_PRINT(("RTL8139: TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret)); + DPRINTF("TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret); return ret; } static void rtl8139_RxBufPtr_write(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139: RxBufPtr write val=0x%04x\n", val)); + DPRINTF("RxBufPtr write val=0x%04x\n", val); /* this value is off by 16 */ s->RxBufPtr = MOD2(val + 0x10, s->RxBufferSize); - DEBUG_PRINT((" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n", - s->RxBufferSize, s->RxBufAddr, s->RxBufPtr)); + DPRINTF(" CAPR write: rx buffer length %d head 0x%04x read 0x%04x\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr); } static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s) @@ -2487,7 +2581,7 @@ static uint32_t rtl8139_RxBufPtr_read(RTL8139State *s) /* this value is off by 16 */ uint32_t ret = s->RxBufPtr - 0x10; - DEBUG_PRINT(("RTL8139: RxBufPtr read val=0x%04x\n", ret)); + DPRINTF("RxBufPtr read val=0x%04x\n", ret); return ret; } @@ -2497,14 +2591,14 @@ static uint32_t rtl8139_RxBufAddr_read(RTL8139State *s) /* this value is NOT off by 16 */ uint32_t ret = s->RxBufAddr; - DEBUG_PRINT(("RTL8139: RxBufAddr read val=0x%04x\n", ret)); + DPRINTF("RxBufAddr read val=0x%04x\n", ret); return ret; } static void rtl8139_RxBuf_write(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139: RxBuf write val=0x%08x\n", val)); + DPRINTF("RxBuf write val=0x%08x\n", val); s->RxBuf = val; @@ -2515,21 +2609,21 @@ static uint32_t rtl8139_RxBuf_read(RTL8139State *s) { uint32_t ret = s->RxBuf; - DEBUG_PRINT(("RTL8139: RxBuf read val=0x%08x\n", ret)); + DPRINTF("RxBuf read val=0x%08x\n", ret); return ret; } static void rtl8139_IntrMask_write(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139: IntrMask write(w) val=0x%04x\n", val)); + DPRINTF("IntrMask write(w) val=0x%04x\n", val); - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0x1e00, s->IntrMask); s->IntrMask = val; - rtl8139_set_next_tctr_time(s, qemu_get_clock(vm_clock)); + rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); rtl8139_update_irq(s); } @@ -2538,14 +2632,14 @@ static uint32_t rtl8139_IntrMask_read(RTL8139State *s) { uint32_t ret = s->IntrMask; - DEBUG_PRINT(("RTL8139: IntrMask read(w) val=0x%04x\n", ret)); + DPRINTF("IntrMask read(w) val=0x%04x\n", ret); return ret; } static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139: IntrStatus write(w) val=0x%04x\n", val)); + DPRINTF("IntrStatus write(w) val=0x%04x\n", val); #if 0 @@ -2556,7 +2650,7 @@ static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val) #else uint16_t newStatus = s->IntrStatus & ~val; - /* mask unwriteable bits */ + /* mask unwritable bits */ newStatus = SET_MASKED(newStatus, 0x1e00, s->IntrStatus); /* writing 1 to interrupt status register bit clears it */ @@ -2570,7 +2664,7 @@ static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val) * and probably emulated is slower is better to assume this resetting was * done before testing on previous rtl8139_update_irq lead to IRQ loosing */ - rtl8139_set_next_tctr_time(s, qemu_get_clock(vm_clock)); + rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); rtl8139_update_irq(s); #endif @@ -2578,11 +2672,11 @@ static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val) static uint32_t rtl8139_IntrStatus_read(RTL8139State *s) { - rtl8139_set_next_tctr_time(s, qemu_get_clock(vm_clock)); + rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); uint32_t ret = s->IntrStatus; - DEBUG_PRINT(("RTL8139: IntrStatus read(w) val=0x%04x\n", ret)); + DPRINTF("IntrStatus read(w) val=0x%04x\n", ret); #if 0 @@ -2598,9 +2692,9 @@ static uint32_t rtl8139_IntrStatus_read(RTL8139State *s) static void rtl8139_MultiIntr_write(RTL8139State *s, uint32_t val) { - DEBUG_PRINT(("RTL8139: MultiIntr write(w) val=0x%04x\n", val)); + DPRINTF("MultiIntr write(w) val=0x%04x\n", val); - /* mask unwriteable bits */ + /* mask unwritable bits */ val = SET_MASKED(val, 0xf000, s->MultiIntr); s->MultiIntr = val; @@ -2610,7 +2704,7 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s) { uint32_t ret = s->MultiIntr; - DEBUG_PRINT(("RTL8139: MultiIntr read(w) val=0x%04x\n", ret)); + DPRINTF("MultiIntr read(w) val=0x%04x\n", ret); return ret; } @@ -2619,8 +2713,6 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val) { RTL8139State *s = opaque; - addr &= 0xff; - switch (addr) { case MAC0 ... MAC0+5: @@ -2658,11 +2750,12 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val) break; case MediaStatus: /* ignore */ - DEBUG_PRINT(("RTL8139: not implemented write(b) to MediaStatus val=0x%02x\n", val)); + DPRINTF("not implemented write(b) to MediaStatus val=0x%02x\n", + val); break; case HltClk: - DEBUG_PRINT(("RTL8139: HltClk write val=0x%08x\n", val)); + DPRINTF("HltClk write val=0x%08x\n", val); if (val == 'R') { s->clock_enabled = 1; @@ -2674,27 +2767,29 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val) break; case TxThresh: - DEBUG_PRINT(("RTL8139C+ TxThresh write(b) val=0x%02x\n", val)); + DPRINTF("C+ TxThresh write(b) val=0x%02x\n", val); s->TxThresh = val; break; case TxPoll: - DEBUG_PRINT(("RTL8139C+ TxPoll write(b) val=0x%02x\n", val)); + DPRINTF("C+ TxPoll write(b) val=0x%02x\n", val); if (val & (1 << 7)) { - DEBUG_PRINT(("RTL8139C+ TxPoll high priority transmission (not implemented)\n")); + DPRINTF("C+ TxPoll high priority transmission (not " + "implemented)\n"); //rtl8139_cplus_transmit(s); } if (val & (1 << 6)) { - DEBUG_PRINT(("RTL8139C+ TxPoll normal priority transmission\n")); + DPRINTF("C+ TxPoll normal priority transmission\n"); rtl8139_cplus_transmit(s); } break; default: - DEBUG_PRINT(("RTL8139: not implemented write(b) addr=0x%x val=0x%02x\n", addr, val)); + DPRINTF("not implemented write(b) addr=0x%x val=0x%02x\n", addr, + val); break; } } @@ -2703,8 +2798,6 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val) { RTL8139State *s = opaque; - addr &= 0xfe; - switch (addr) { case IntrMask: @@ -2730,14 +2823,14 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val) rtl8139_BasicModeStatus_write(s, val); break; case NWayAdvert: - DEBUG_PRINT(("RTL8139: NWayAdvert write(w) val=0x%04x\n", val)); + DPRINTF("NWayAdvert write(w) val=0x%04x\n", val); s->NWayAdvert = val; break; case NWayLPAR: - DEBUG_PRINT(("RTL8139: forbidden NWayLPAR write(w) val=0x%04x\n", val)); + DPRINTF("forbidden NWayLPAR write(w) val=0x%04x\n", val); break; case NWayExpansion: - DEBUG_PRINT(("RTL8139: NWayExpansion write(w) val=0x%04x\n", val)); + DPRINTF("NWayExpansion write(w) val=0x%04x\n", val); s->NWayExpansion = val; break; @@ -2750,7 +2843,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val) break; default: - DEBUG_PRINT(("RTL8139: ioport write(w) addr=0x%x val=0x%04x via write(b)\n", addr, val)); + DPRINTF("ioport write(w) addr=0x%x val=0x%04x via write(b)\n", + addr, val); rtl8139_io_writeb(opaque, addr, val & 0xff); rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff); @@ -2763,7 +2857,7 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time) int64_t pci_time, next_time; uint32_t low_pci; - DEBUG_PRINT(("RTL8139: entered rtl8139_set_next_tctr_time\n")); + DPRINTF("entered rtl8139_set_next_tctr_time\n"); if (s->TimerExpire && current_time >= s->TimerExpire) { s->IntrStatus |= PCSTimeout; @@ -2802,12 +2896,10 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val) { RTL8139State *s = opaque; - addr &= 0xfc; - switch (addr) { case RxMissed: - DEBUG_PRINT(("RTL8139: RxMissed clearing on write\n")); + DPRINTF("RxMissed clearing on write\n"); s->RxMissed = 0; break; @@ -2832,31 +2924,32 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val) break; case RxRingAddrLO: - DEBUG_PRINT(("RTL8139: C+ RxRing low bits write val=0x%08x\n", val)); + DPRINTF("C+ RxRing low bits write val=0x%08x\n", val); s->RxRingAddrLO = val; break; case RxRingAddrHI: - DEBUG_PRINT(("RTL8139: C+ RxRing high bits write val=0x%08x\n", val)); + DPRINTF("C+ RxRing high bits write val=0x%08x\n", val); s->RxRingAddrHI = val; break; case Timer: - DEBUG_PRINT(("RTL8139: TCTR Timer reset on write\n")); - s->TCTR_base = qemu_get_clock(vm_clock); + DPRINTF("TCTR Timer reset on write\n"); + s->TCTR_base = qemu_get_clock_ns(vm_clock); rtl8139_set_next_tctr_time(s, s->TCTR_base); break; case FlashReg: - DEBUG_PRINT(("RTL8139: FlashReg TimerInt write val=0x%08x\n", val)); + DPRINTF("FlashReg TimerInt write val=0x%08x\n", val); if (s->TimerInt != val) { s->TimerInt = val; - rtl8139_set_next_tctr_time(s, qemu_get_clock(vm_clock)); + rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); } break; default: - DEBUG_PRINT(("RTL8139: ioport write(l) addr=0x%x val=0x%08x via write(b)\n", addr, val)); + DPRINTF("ioport write(l) addr=0x%x val=0x%08x via write(b)\n", + addr, val); rtl8139_io_writeb(opaque, addr, val & 0xff); rtl8139_io_writeb(opaque, addr + 1, (val >> 8) & 0xff); rtl8139_io_writeb(opaque, addr + 2, (val >> 16) & 0xff); @@ -2870,8 +2963,6 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr) RTL8139State *s = opaque; int ret; - addr &= 0xff; - switch (addr) { case MAC0 ... MAC0+5: @@ -2907,31 +2998,31 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr) case MediaStatus: ret = 0xd0; - DEBUG_PRINT(("RTL8139: MediaStatus read 0x%x\n", ret)); + DPRINTF("MediaStatus read 0x%x\n", ret); break; case HltClk: ret = s->clock_enabled; - DEBUG_PRINT(("RTL8139: HltClk read 0x%x\n", ret)); + DPRINTF("HltClk read 0x%x\n", ret); break; case PCIRevisionID: ret = RTL8139_PCI_REVID; - DEBUG_PRINT(("RTL8139: PCI Revision ID read 0x%x\n", ret)); + DPRINTF("PCI Revision ID read 0x%x\n", ret); break; case TxThresh: ret = s->TxThresh; - DEBUG_PRINT(("RTL8139C+ TxThresh read(b) val=0x%02x\n", ret)); + DPRINTF("C+ TxThresh read(b) val=0x%02x\n", ret); break; case 0x43: /* Part of TxConfig register. Windows driver tries to read it */ ret = s->TxConfig >> 24; - DEBUG_PRINT(("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret)); + DPRINTF("RTL8139C TxConfig at 0x43 read(b) val=0x%02x\n", ret); break; default: - DEBUG_PRINT(("RTL8139: not implemented read(b) addr=0x%x\n", addr)); + DPRINTF("not implemented read(b) addr=0x%x\n", addr); ret = 0; break; } @@ -2944,8 +3035,6 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr) RTL8139State *s = opaque; uint32_t ret; - addr &= 0xfe; /* mask lower bit */ - switch (addr) { case IntrMask: @@ -2976,15 +3065,15 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr) break; case NWayAdvert: ret = s->NWayAdvert; - DEBUG_PRINT(("RTL8139: NWayAdvert read(w) val=0x%04x\n", ret)); + DPRINTF("NWayAdvert read(w) val=0x%04x\n", ret); break; case NWayLPAR: ret = s->NWayLPAR; - DEBUG_PRINT(("RTL8139: NWayLPAR read(w) val=0x%04x\n", ret)); + DPRINTF("NWayLPAR read(w) val=0x%04x\n", ret); break; case NWayExpansion: ret = s->NWayExpansion; - DEBUG_PRINT(("RTL8139: NWayExpansion read(w) val=0x%04x\n", ret)); + DPRINTF("NWayExpansion read(w) val=0x%04x\n", ret); break; case CpCmd: @@ -3004,12 +3093,12 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr) break; default: - DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x via read(b)\n", addr)); + DPRINTF("ioport read(w) addr=0x%x via read(b)\n", addr); ret = rtl8139_io_readb(opaque, addr); ret |= rtl8139_io_readb(opaque, addr + 1) << 8; - DEBUG_PRINT(("RTL8139: ioport read(w) addr=0x%x val=0x%04x\n", addr, ret)); + DPRINTF("ioport read(w) addr=0x%x val=0x%04x\n", addr, ret); break; } @@ -3021,14 +3110,12 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr) RTL8139State *s = opaque; uint32_t ret; - addr &= 0xfc; /* also mask low 2 bits */ - switch (addr) { case RxMissed: ret = s->RxMissed; - DEBUG_PRINT(("RTL8139: RxMissed read val=0x%08x\n", ret)); + DPRINTF("RxMissed read val=0x%08x\n", ret); break; case TxConfig: @@ -3053,34 +3140,34 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr) case RxRingAddrLO: ret = s->RxRingAddrLO; - DEBUG_PRINT(("RTL8139: C+ RxRing low bits read val=0x%08x\n", ret)); + DPRINTF("C+ RxRing low bits read val=0x%08x\n", ret); break; case RxRingAddrHI: ret = s->RxRingAddrHI; - DEBUG_PRINT(("RTL8139: C+ RxRing high bits read val=0x%08x\n", ret)); + DPRINTF("C+ RxRing high bits read val=0x%08x\n", ret); break; case Timer: - ret = muldiv64(qemu_get_clock(vm_clock) - s->TCTR_base, + ret = muldiv64(qemu_get_clock_ns(vm_clock) - s->TCTR_base, PCI_FREQUENCY, get_ticks_per_sec()); - DEBUG_PRINT(("RTL8139: TCTR Timer read val=0x%08x\n", ret)); + DPRINTF("TCTR Timer read val=0x%08x\n", ret); break; case FlashReg: ret = s->TimerInt; - DEBUG_PRINT(("RTL8139: FlashReg TimerInt read val=0x%08x\n", ret)); + DPRINTF("FlashReg TimerInt read val=0x%08x\n", ret); break; default: - DEBUG_PRINT(("RTL8139: ioport read(l) addr=0x%x via read(b)\n", addr)); + DPRINTF("ioport read(l) addr=0x%x via read(b)\n", addr); ret = rtl8139_io_readb(opaque, addr); ret |= rtl8139_io_readb(opaque, addr + 1) << 8; ret |= rtl8139_io_readb(opaque, addr + 2) << 16; ret |= rtl8139_io_readb(opaque, addr + 3) << 24; - DEBUG_PRINT(("RTL8139: read(l) addr=0x%x val=%08x\n", addr, ret)); + DPRINTF("read(l) addr=0x%x val=%08x\n", addr, ret); break; } @@ -3156,7 +3243,7 @@ static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr) static int rtl8139_post_load(void *opaque, int version_id) { RTL8139State* s = opaque; - rtl8139_set_next_tctr_time(s, qemu_get_clock(vm_clock)); + rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); if (version_id < 4) { s->cplus_enabled = s->CpCmd != 0; } @@ -3182,13 +3269,13 @@ static const VMStateDescription vmstate_rtl8139_hotplug_ready ={ static void rtl8139_pre_save(void *opaque) { RTL8139State* s = opaque; - int64_t current_time = qemu_get_clock(vm_clock); + int64_t current_time = qemu_get_clock_ns(vm_clock); /* set IntrStatus correctly */ rtl8139_set_next_tctr_time(s, current_time); s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY, get_ticks_per_sec()); - s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr; + s->rtl8139_mmio_io_addr_dummy = 0; } static const VMStateDescription vmstate_rtl8139 = { @@ -3284,39 +3371,35 @@ static const VMStateDescription vmstate_rtl8139 = { /***********************************************************/ /* PCI RTL8139 definitions */ -static void rtl8139_mmio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev); - - cpu_register_physical_memory(addr + 0, 0x100, s->rtl8139_mmio_io_addr); -} - -static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev); - - register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s); - register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb, s); - - register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s); - register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw, s); - - register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s); - register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl, s); -} +static const MemoryRegionPortio rtl8139_portio[] = { + { 0, 0x100, 1, .read = rtl8139_ioport_readb, }, + { 0, 0x100, 1, .write = rtl8139_ioport_writeb, }, + { 0, 0x100, 2, .read = rtl8139_ioport_readw, }, + { 0, 0x100, 2, .write = rtl8139_ioport_writew, }, + { 0, 0x100, 4, .read = rtl8139_ioport_readl, }, + { 0, 0x100, 4, .write = rtl8139_ioport_writel, }, + PORTIO_END_OF_LIST() +}; -static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = { - rtl8139_mmio_readb, - rtl8139_mmio_readw, - rtl8139_mmio_readl, +static const MemoryRegionOps rtl8139_io_ops = { + .old_portio = rtl8139_portio, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = { - rtl8139_mmio_writeb, - rtl8139_mmio_writew, - rtl8139_mmio_writel, +static const MemoryRegionOps rtl8139_mmio_ops = { + .old_mmio = { + .read = { + rtl8139_mmio_readb, + rtl8139_mmio_readw, + rtl8139_mmio_readl, + }, + .write = { + rtl8139_mmio_writeb, + rtl8139_mmio_writew, + rtl8139_mmio_writel, + }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void rtl8139_timer(void *opaque) @@ -3325,13 +3408,13 @@ static void rtl8139_timer(void *opaque) if (!s->clock_enabled) { - DEBUG_PRINT(("RTL8139: >>> timer: clock is not running\n")); + DPRINTF(">>> timer: clock is not running\n"); return; } s->IntrStatus |= PCSTimeout; rtl8139_update_irq(s); - rtl8139_set_next_tctr_time(s, qemu_get_clock(vm_clock)); + rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); } static void rtl8139_cleanup(VLANClientState *nc) @@ -3345,9 +3428,10 @@ static int pci_rtl8139_uninit(PCIDevice *dev) { RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev); - cpu_unregister_io_memory(s->rtl8139_mmio_io_addr); + memory_region_destroy(&s->bar_io); + memory_region_destroy(&s->bar_mem); if (s->cplus_txbuffer) { - qemu_free(s->cplus_txbuffer); + g_free(s->cplus_txbuffer); s->cplus_txbuffer = NULL; } qemu_del_timer(s->timer); @@ -3370,28 +3454,29 @@ static int pci_rtl8139_init(PCIDevice *dev) uint8_t *pci_conf; pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139); - pci_conf[PCI_REVISION_ID] = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */ - pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET); - pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin 0 */ + pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */ /* TODO: start of capability list, but no capability * list bit in status register, and offset 0xdc seems unused. */ pci_conf[PCI_CAPABILITY_LIST] = 0xdc; - /* I/O handler for memory-mapped I/O */ - s->rtl8139_mmio_io_addr = - cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s, - DEVICE_LITTLE_ENDIAN); - - pci_register_bar(&s->dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, rtl8139_ioport_map); - - pci_register_bar(&s->dev, 1, 0x100, - PCI_BASE_ADDRESS_SPACE_MEMORY, rtl8139_mmio_map); + memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100); + memory_region_init_io(&s->bar_mem, &rtl8139_mmio_ops, s, "rtl8139", 0x100); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io); + pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem); qemu_macaddr_default_if_unset(&s->conf.macaddr); + /* prepare eeprom */ + s->eeprom.contents[0] = 0x8129; +#if 1 + /* PCI vendor and device ID should be mirrored here */ + s->eeprom.contents[1] = PCI_VENDOR_ID_REALTEK; + s->eeprom.contents[2] = PCI_DEVICE_ID_REALTEK_8139; +#endif + s->eeprom.contents[7] = s->conf.macaddr.a[0] | s->conf.macaddr.a[1] << 8; + s->eeprom.contents[8] = s->conf.macaddr.a[2] | s->conf.macaddr.a[3] << 8; + s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8; + s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf, dev->qdev.info->name, dev->qdev.id, s); qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); @@ -3401,8 +3486,8 @@ static int pci_rtl8139_init(PCIDevice *dev) s->cplus_txbuffer_offset = 0; s->TimerExpire = 0; - s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s); - rtl8139_set_next_tctr_time(s, qemu_get_clock(vm_clock)); + s->timer = qemu_new_timer_ns(vm_clock, rtl8139_timer, s); + rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock)); add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet-phy@0"); @@ -3416,7 +3501,11 @@ static PCIDeviceInfo rtl8139_info = { .qdev.vmsd = &vmstate_rtl8139, .init = pci_rtl8139_init, .exit = pci_rtl8139_uninit, - .romfile = "pxe-rtl8139.bin", + .romfile = "pxe-rtl8139.rom", + .vendor_id = PCI_VENDOR_ID_REALTEK, + .device_id = PCI_DEVICE_ID_REALTEK_8139, + .revision = RTL8139_PCI_REVID, /* >=0x20 is for 8139C+ */ + .class_id = PCI_CLASS_NETWORK_ETHERNET, .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(RTL8139State, conf), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c index 784dc01..c4b9a99 100644 --- a/hw/s390-virtio-bus.c +++ b/hw/s390-virtio-bus.c @@ -43,6 +43,8 @@ do { } while (0) #endif +#define VIRTIO_EXT_CODE 0x2603 + struct BusInfo s390_virtio_bus_info = { .name = "s390-virtio", .size = sizeof(VirtIOS390Bus), @@ -58,6 +60,9 @@ static const VirtIOBindings virtio_s390_bindings; static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev); +/* length of VirtIO device pages */ +const target_phys_addr_t virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE; + VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size) { VirtIOS390Bus *bus; @@ -123,7 +128,8 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev) { VirtIODevice *vdev; - vdev = virtio_blk_init((DeviceState *)dev, &dev->block); + vdev = virtio_blk_init((DeviceState *)dev, &dev->block, + &dev->block_serial); if (!vdev) { return -1; } @@ -139,7 +145,7 @@ static int s390_virtio_serial_init(VirtIOS390Device *dev) bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus); - vdev = virtio_serial_init((DeviceState *)dev, dev->max_virtserial_ports); + vdev = virtio_serial_init((DeviceState *)dev, &dev->serial); if (!vdev) { return -1; } @@ -160,7 +166,7 @@ static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq) (vq * VIRTIO_VQCONFIG_LEN) + VIRTIO_VQCONFIG_OFFS_TOKEN; - return ldq_phys(token_off); + return ldq_be_phys(token_off); } static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev) @@ -214,8 +220,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev) vring = s390_virtio_next_ring(bus); virtio_queue_set_addr(dev->vdev, i, vring); virtio_queue_set_vector(dev->vdev, i, i); - stq_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring); - stw_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i)); + stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring); + stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i)); } cur_offs = dev->dev_offs; @@ -223,7 +229,7 @@ void s390_virtio_device_sync(VirtIOS390Device *dev) cur_offs += num_vq * VIRTIO_VQCONFIG_LEN; /* Sync feature bitmap */ - stl_phys(cur_offs, dev->host_features); + stl_le_phys(cur_offs, dev->host_features); dev->feat_offs = cur_offs + dev->feat_len; cur_offs += dev->feat_len * 2; @@ -233,7 +239,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev) dev->vdev->get_config(dev->vdev, dev->vdev->config); } - cpu_physical_memory_rw(cur_offs, dev->vdev->config, dev->vdev->config_len, 1); + cpu_physical_memory_write(cur_offs, + dev->vdev->config, dev->vdev->config_len); cur_offs += dev->vdev->config_len; } @@ -246,11 +253,8 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev) /* Update guest supported feature bitmap */ - features = ldl_phys(dev->feat_offs); - if (vdev->set_features) { - vdev->set_features(vdev, features); - } - vdev->guest_features = features; + features = bswap32(ldl_be_phys(dev->feat_offs)); + virtio_set_features(vdev, features); } VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus) @@ -267,7 +271,7 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus, DeviceState *dev; int i; - QLIST_FOREACH(dev, &bus->bus.children, sibling) { + QTAILQ_FOREACH(dev, &bus->bus.children, sibling) { _dev = (VirtIOS390Device *)dev; for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { if (!virtio_queue_get_addr(_dev->vdev, i)) @@ -290,7 +294,7 @@ VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem) VirtIOS390Device *_dev; DeviceState *dev; - QLIST_FOREACH(dev, &bus->bus.children, sibling) { + QTAILQ_FOREACH(dev, &bus->bus.children, sibling) { _dev = (VirtIOS390Device *)dev; if (_dev->dev_offs == mem) { return _dev; @@ -304,9 +308,13 @@ static void virtio_s390_notify(void *opaque, uint16_t vector) { VirtIOS390Device *dev = (VirtIOS390Device*)opaque; uint64_t token = s390_virtio_device_vq_token(dev, vector); + CPUState *env = s390_cpu_addr2state(0); - /* XXX kvm dependency! */ - kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token); + if (kvm_enabled()) { + kvm_s390_virtio_irq(env, 0, token); + } else { + cpu_inject_ext(env, VIRTIO_EXT_CODE, 0, token); + } } static unsigned virtio_s390_get_features(void *opaque) @@ -325,6 +333,7 @@ static const VirtIOBindings virtio_s390_bindings = { static VirtIOS390DeviceInfo s390_virtio_net = { .init = s390_virtio_net_init, .qdev.name = "virtio-net-s390", + .qdev.alias = "virtio-net", .qdev.size = sizeof(VirtIOS390Device), .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic), @@ -340,9 +349,11 @@ static VirtIOS390DeviceInfo s390_virtio_net = { static VirtIOS390DeviceInfo s390_virtio_blk = { .init = s390_virtio_blk_init, .qdev.name = "virtio-blk-s390", + .qdev.alias = "virtio-blk", .qdev.size = sizeof(VirtIOS390Device), .qdev.props = (Property[]) { DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block), + DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial), DEFINE_PROP_END_OF_LIST(), }, }; @@ -353,8 +364,8 @@ static VirtIOS390DeviceInfo s390_virtio_serial = { .qdev.alias = "virtio-serial", .qdev.size = sizeof(VirtIOS390Device), .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("max_ports", VirtIOS390Device, max_virtserial_ports, - 31), + DEFINE_PROP_UINT32("max_ports", VirtIOS390Device, + serial.max_virtserial_ports, 31), DEFINE_PROP_END_OF_LIST(), }, }; diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h index 33379a3..f1bece7 100644 --- a/hw/s390-virtio-bus.h +++ b/hw/s390-virtio-bus.h @@ -18,6 +18,7 @@ */ #include "virtio-net.h" +#include "virtio-serial.h" #define VIRTIO_DEV_OFFS_TYPE 0 /* 8 bits */ #define VIRTIO_DEV_OFFS_NUM_VQ 1 /* 8 bits */ @@ -32,7 +33,7 @@ #define VIRTIO_VQCONFIG_LEN 24 #define VIRTIO_RING_LEN (TARGET_PAGE_SIZE * 3) -#define S390_DEVICE_PAGES 256 +#define S390_DEVICE_PAGES 512 typedef struct VirtIOS390Device { DeviceState qdev; @@ -41,10 +42,10 @@ typedef struct VirtIOS390Device { uint8_t feat_len; VirtIODevice *vdev; BlockConf block; + char *block_serial; NICConf nic; uint32_t host_features; - /* Max. number of ports we can have for a the virtio-serial device */ - uint32_t max_virtserial_ports; + virtio_serial_conf serial; virtio_net_conf net; } VirtIOS390Device; diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index f29b624..61b67e8 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -29,6 +29,7 @@ #include "hw/virtio.h" #include "hw/sysbus.h" #include "kvm.h" +#include "exec-memory.h" #include "hw/s390-virtio-bus.h" @@ -62,17 +63,6 @@ static VirtIOS390Bus *s390_bus; static CPUState **ipi_states; -void irq_info(Monitor *mon); -void pic_info(Monitor *mon); - -void irq_info(Monitor *mon) -{ -} - -void pic_info(Monitor *mon) -{ -} - CPUState *s390_cpu_addr2state(uint16_t cpu_addr) { if (cpu_addr >= smp_cpus) { @@ -82,13 +72,12 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr) return ipi_states[cpu_addr]; } -int s390_virtio_hypercall(CPUState *env) +int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall) { int r = 0, i; - target_ulong mem = env->regs[2]; - dprintf("KVM hypercall: %ld\n", env->regs[1]); - switch (env->regs[1]) { + dprintf("KVM hypercall: %ld\n", hypercall); + switch (hypercall) { case KVM_S390_VIRTIO_NOTIFY: if (mem > ram_size) { VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, @@ -108,6 +97,7 @@ int s390_virtio_hypercall(CPUState *env) dev = s390_virtio_bus_find_mem(s390_bus, mem); virtio_reset(dev->vdev); + stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); s390_virtio_device_sync(dev); break; } @@ -128,12 +118,39 @@ int s390_virtio_hypercall(CPUState *env) break; } - env->regs[2] = r; - return 0; + return r; +} + +/* + * The number of running CPUs. On s390 a shutdown is the state of all CPUs + * being either stopped or disabled (for interrupts) waiting. We have to + * track this number to call the shutdown sequence accordingly. This + * number is modified either on startup or while holding the big qemu lock. + */ +static unsigned s390_running_cpus; + +void s390_add_running_cpu(CPUState *env) +{ + if (env->halted) { + s390_running_cpus++; + env->halted = 0; + env->exception_index = -1; + } +} + +unsigned s390_del_running_cpu(CPUState *env) +{ + if (env->halted == 0) { + assert(s390_running_cpus >= 1); + s390_running_cpus--; + env->halted = 1; + env->exception_index = EXCP_HLT; + } + return s390_running_cpus; } /* PC hardware initialisation */ -static void s390_init(ram_addr_t ram_size, +static void s390_init(ram_addr_t my_ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, @@ -141,32 +158,53 @@ static void s390_init(ram_addr_t ram_size, const char *cpu_model) { CPUState *env = NULL; - ram_addr_t ram_addr; + MemoryRegion *sysmem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); ram_addr_t kernel_size = 0; ram_addr_t initrd_offset; ram_addr_t initrd_size = 0; + int shift = 0; + uint8_t *storage_keys; + void *virtio_region; + target_phys_addr_t virtio_region_len; + target_phys_addr_t virtio_region_start; int i; - /* XXX we only work on KVM for now */ - - if (!kvm_enabled()) { - fprintf(stderr, "The S390 target only works with KVM enabled\n"); - exit(1); + /* s390x ram size detection needs a 16bit multiplier + an increment. So + guests > 64GB can be specified in 2MB steps etc. */ + while ((my_ram_size >> (20 + shift)) > 65535) { + shift++; } + my_ram_size = my_ram_size >> (20 + shift) << (20 + shift); + + /* lets propagate the changed ram size into the global variable. */ + ram_size = my_ram_size; /* get a BUS */ - s390_bus = s390_virtio_bus_init(&ram_size); + s390_bus = s390_virtio_bus_init(&my_ram_size); /* allocate RAM */ - ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size); - cpu_register_physical_memory(0, ram_size, ram_addr); + memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size); + memory_region_add_subregion(sysmem, 0, ram); + + /* clear virtio region */ + virtio_region_len = my_ram_size - ram_size; + virtio_region_start = ram_size; + virtio_region = cpu_physical_memory_map(virtio_region_start, + &virtio_region_len, true); + memset(virtio_region, 0, virtio_region_len); + cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1, + virtio_region_len); + + /* allocate storage keys */ + storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE); /* init CPUs */ if (cpu_model == NULL) { cpu_model = "host"; } - ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus); + ipi_states = g_malloc(sizeof(CPUState *) * smp_cpus); for (i = 0; i < smp_cpus; i++) { CPUState *tmp_env; @@ -178,15 +216,16 @@ static void s390_init(ram_addr_t ram_size, ipi_states[i] = tmp_env; tmp_env->halted = 1; tmp_env->exception_index = EXCP_HLT; + tmp_env->storage_keys = storage_keys; } - env->halted = 0; - env->exception_index = 0; + /* One CPU has to run */ + s390_add_running_cpu(env); if (kernel_filename) { kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0)); - if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) { + if (lduw_be_phys(KERN_IMAGE_START) != 0x0dd0) { fprintf(stderr, "Specified image is not an s390 boot image\n"); exit(1); } @@ -204,6 +243,7 @@ static void s390_init(ram_addr_t ram_size, bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR)); + g_free(bios_filename); if ((long)bios_size < 0) { hw_error("could not load bootloader '%s'\n", bios_name); @@ -224,13 +264,13 @@ static void s390_init(ram_addr_t ram_size, } initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset)); - stq_phys(INITRD_PARM_START, initrd_offset); - stq_phys(INITRD_PARM_SIZE, initrd_size); + stq_be_phys(INITRD_PARM_START, initrd_offset); + stq_be_phys(INITRD_PARM_SIZE, initrd_size); } if (kernel_cmdline) { - cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline, - strlen(kernel_cmdline), 1); + cpu_physical_memory_write(KERN_PARM_AREA, kernel_cmdline, + strlen(kernel_cmdline) + 1); } /* Create VirtIO network adapters */ @@ -239,7 +279,7 @@ static void s390_init(ram_addr_t ram_size, DeviceState *dev; if (!nd->model) { - nd->model = qemu_strdup("virtio"); + nd->model = g_strdup("virtio"); } if (strcmp(nd->model, "virtio")) { diff --git a/hw/s5pc1xx.c b/hw/s5pc1xx.c deleted file mode 100644 index 9036c87..0000000 --- a/hw/s5pc1xx.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * S5PC1XX-based board emulation. - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - * Vladimir Monakhov - * Alexey Merkulov - * Dmitry Zhurikhin - */ - - -/* turn off some memory-hungry but useless (yet) devices */ -#define LOWMEMORY - - -#include "s5pc1xx.h" -#include "boards.h" -#include "arm-misc.h" -#include "primecell.h" -#include "qemu-timer.h" -#include "net.h" -#include "i2c.h" -#include "sysbus.h" -#include "s5pc1xx_gpio_regs.h" -#include "sysemu.h" -#include "ide.h" -#include "ak8973.h" - - -#ifdef CONFIG_GLES2 -#include "gles2.h" -#endif - - -/* Memory map */ -#define S5PC1XX_BOOT_BASE 0x00000000 -#define S5PC1XX_DRAM0_BASE 0x20000000 -#define S5PC1XX_ONEDRAM_BASE 0x30000000 -#define S5PC1XX_DRAM1_BASE 0x40000000 -#define S5PC1XX_SROMC_B0_BASE 0x80000000 -#define S5PC1XX_SROMC_B1_BASE 0x88000000 -#define S5PC1XX_SROMC_B2_BASE 0x90000000 -#define S5PC1XX_SROMC_B3_BASE 0x98000000 -#define S5PC1XX_SROMC_B4_BASE 0xA0000000 -#define S5PC1XX_SROMC_B5_BASE 0xA8000000 -#define S5PC1XX_ONENAND_BASE 0xB0000000 -#define S5PC1XX_NAND_BASE 0xB0E00000 -#define S5PC1XX_MP3_SRAM_BASE 0xC0000000 -#define S5PC1XX_IROM_BASE 0xD0000000 /* Internal SROM */ -#define S5PC1XX_IRAM_BASE 0xD0020000 /* Internal SRAM */ -#define S5PC1XX_DMZ_ROM 0xD8000000 -#define S5PC1XX_SFRS 0xE0000000 - -#define S5PC1XX_JPEG_BASE 0xFB600000 -#define S5PC1XX_USB_OTG_BASE 0xEC000000 - -/* Memory size */ -#define S5PC1XX_BOOT_SIZE (1 << 29) /* 512 MB */ -#define S5PC1XX_ISROM_SIZE (1 << 16) /* 64 KB */ -#define S5PC1XX_ISRAM_SIZE (1 << 17) /* 128 KB */ -#define S5PC1XX_DRAM_MAX_SIZE (1 << 29) /* 512 MB */ - -#ifndef LOWMEMORY -#define S5PC1XX_SFRS_SIZE (1 << 29) /* 512 MB */ -#else -#define S5PC1XX_SFRS_SIZE (1 << 27) /* 128 MB */ -#endif - -/* Interrputs Handling */ - -/* Number of interrupts */ -#define S5PC1XX_IRQ_COUNT 128 -/* Number of Vector Interrupt Controllers */ -#define S5PC1XX_VIC_N 4 -/* Number of vectors in each Vector Interrupt Controller */ -#define S5PC1XX_VIC_SIZE 32 -#define S5PC1XX_VIC_BASE 0xF2000000 -#define S5PC1XX_VIC_SHIFT 0x00100000 - -#define S5PC1XX_LCD_BASE 0xF8000000 -#define S5PC1XX_AC97_BASE 0xE2200000 - -#define S5PC1XX_SPI_BASE 0xE1300000 -#define S5PC1XX_SPI_SHIFT 0x00100000 - -#define S5PC1XX_IRQ_EXTEND 16 -#define S5PC1XX_IRQ_DMAMEM 18 -#define S5PC1XX_IRQ_DMA0 19 -#define S5PC1XX_IRQ_DMA1 20 -#define S5PC1XX_IRQ_TIMER0 21 -#define S5PC1XX_IRQ_TIMER1 22 -#define S5PC1XX_IRQ_TIMER2 23 -#define S5PC1XX_IRQ_TIMER3 24 -#define S5PC1XX_IRQ_TIMER4 25 -#define S5PC1XX_IRQ_SYS_TIMER 26 -#define S5PC1XX_IRQ_WDT 27 -#define S5PC1XX_IRQ_RTC_ALARM 28 -#define S5PC1XX_IRQ_RTC_TICK 29 -#define S5PC1XX_IRQ_GPIOINT 30 - -#define S5PC1XX_IRQ_CFCON 41 -#define S5PC1XX_IRQ_UART0 42 -#define S5PC1XX_IRQ_UART1 43 -#define S5PC1XX_IRQ_UART2 44 -#define S5PC1XX_IRQ_UART3 45 -#define S5PC1XX_IRQ_SPI0 47 -#define S5PC1XX_IRQ_SPI1 48 -#define S5PC1XX_IRQ_SPI2 49 - -#define S5PC1XX_IRQ_UHOST 55 -#define S5PC1XX_IRQ_OTG 56 - -#define S5PC1XX_IRQ_MMC0 58 -#define S5PC1XX_IRQ_MMC1 59 -#define S5PC1XX_IRQ_MMC2 60 -#define S5PC1XX_IRQ_MMC3 98 - -#define S5PC1XX_IRQ_I2C_0 46 -#define S5PC1XX_IRQ_I2C_2 51 -#define S5PC1XX_IRQ_I2C_PHY 52 -#define S5PC1XX_IRQ_I2C_DDC 77 - -#define S5PC1XX_IRQ_JPEG 72 - -#define S5PC1XX_IRQ_I2S0 80 -#define S5PC1XX_IRQ_I2S1 81 -#define S5PC1XX_IRQ_I2S_V5 S5PC1XX_IRQ_I2S0 - -#define S5PC1XX_IRQ_AC97 83 -#define S5PC1XX_IRQ_PCM0 84 -#define S5PC1XX_IRQ_PCM1 85 -#define S5PC1XX_IRQ_SPDIF 86 -#define S5PC1XX_IRQ_ADC0 87 -#define S5PC1XX_IRQ_PENDN0 88 -#define S5PC1XX_IRQ_KEYPAD 89 -#define S5PC1XX_IRQ_PCM2 93 - -#define S5PC1XX_IRQ_LCD0 64 -#define S5PC1XX_IRQ_LCD1 65 -#define S5PC1XX_IRQ_LCD2 66 - -#define S5PC1XX_IRQ_ADC1 105 -#define S5PC1XX_IRQ_PENDN1 106 - -#define S5PC1XX_DMAMEM_BASE 0xFA200000 -#define S5PC1XX_DMA0_BASE 0xE0900000 -#define S5PC1XX_DMA1_BASE 0xE0A00000 - -#define S5PC1XX_GPIO_BASE 0xE0200000 -#define S5PC1XX_PWM_BASE 0xE2500000 -#define S5PC1XX_ST_BASE 0xE2600000 -#define S5PC1XX_WDT_BASE 0xE2700000 -#define S5PC1XX_RTC_BASE 0xE2800000 - -#define S5PC1XX_UART_BASE 0xE2900000 -#define S5PC1XX_UART_SHIFT 0x00000400 - -#define S5PC1XX_PCM0_BASE 0xE2300000 -#define S5PC1XX_PCM1_BASE 0xE1200000 -#define S5PC1XX_PCM2_BASE 0xE2B00000 - -#define S5PC1XX_SPDIF_BASE 0xE1100000 - -#define S5PC1XX_SROMC_BASE 0xE8000000 - -#define S5PC1XX_I2S1_BASE 0xE2100000 -#define S5PC1XX_I2S2_BASE 0xE2A00000 - -#define S5PC1XX_I2C_0_BASE 0xE1800000 -#define S5PC1XX_I2C_2_BASE 0xE1A00000 -#define S5PC1XX_I2C_PHY_BASE 0xFA900000 -#define S5PC1XX_I2C_DDC_BASE 0xFAB00000 - -#define S5PC1XX_USB_EHCI_BASE 0xEC200000 -#define S5PC1XX_USB_OHCI_BASE 0xEC300000 - -#define S5PC1XX_SROMC_MAX_BANK_SIZE 0x08000000 - -#define S5PC1XX_SWRST_BASE 0xE0102000 -#define S5PC1XX_PMU_BASE 0xE0108000 -#define S5PC1XX_CMU_BASE 0xE0100000 - -#define S5PC1XX_KEYPAD_BASE 0xE1600000 -#define S5PC1XX_TSADC0_BASE 0xE1700000 -#define S5PC1XX_TSADC1_BASE 0xE1701000 - -#define S5PC1XX_I2S2_V5_BASE 0xEEE30000 - -#define S5PC1XX_CFCON_ATAPI1 0xE8200054 -#define S5PC1XX_CFCON_ATAPI2 0xE8200074 - -#define S5PC1XX_HSMMC0_BASE 0xEB000000 -#define S5PC1XX_HSMMC1_BASE 0xEB100000 -#define S5PC1XX_HSMMC2_BASE 0xEB200000 -#define S5PC1XX_HSMMC3_BASE 0xEB300000 - -#define S5PC1XX_IRQ_ONEDRAM_INT_AP 11 - -#define S5PC1XX_USB_NUM_PORTS 1 -#define S5PC1XX_SROMC_NUM_BANKS 6 - -#define S5PC1XX_QT602240_ADDR 0x4A -#define S5PC1XX_QT602240_IRQ GPIOINT_IRQ(GPJ0, 5) - -#define S5PC1XX_WM8994_ADDR 0x1A - -#define S5PC1XX_MCS5000_ADDR 0x20 -#define S5PC1XX_MCS5000_IRQ GPIOINT_IRQ(GPJ2, 7) - -#define S5PC1XX_MAX17040_ADDR 0x36 -#define S5PC1XX_MAX8998_ADDR 0x66 -#define S5PC1XX_MAX8998_RTC_ADDR 0x06 - -#define S5PC1XX_AK8973_ADDR 0x1C -#define S5PC1XX_AK8973_IRQ GPIOEXT_IRQ(29) - -/* pl330 peripheral numbers */ -#define PL330_PERIPH_NUM_I2S1 10 -#define PL330_PERIPH_NUM_I2S2 11 - - -static const uint32_t dmamem_cfg[] = -{ 0x003E1071, 0x00000075, 0x0, 0xFFFFFFFF, 0x00000003, 0x01F73733 }; - -static const uint32_t dma0_cfg[] = -{ 0x003FF075, 0x00000074, 0x0, 0xFFFFFFFF, 0xFFFFFFFF, 0x00773732 }; - -static const uint32_t dma1_cfg[] = -{ 0x003FF075, 0x00000074, 0x0, 0xFFFFFFFF, 0xFFFFFFFF, 0x00773732 }; - -static const uint8_t chipid_and_omr[] = -{ 0x00, 0x02, 0x11, 0x43, 0x09, 0x00, 0x00, 0x00 }; /* Little-endian */ - -/* FIXME: this should be considered a hack, but is there any other way? - now at least this may be easily changed if another compass device - is used */ -static DeviceState *compass_device = NULL; -static DeviceState *sensor_device = NULL; - - -int compass_update(int8_t x, int8_t y, int8_t z, int8_t temp) -{ - if (compass_device) { - ak8973_update(compass_device, x, y, z, temp); - } - return 0; -} - -#if 0 -/* smb380 module has this function */ -int sensor_update(int16_t x, int16_t y, int16_t z) -{ - if (sensor_device) { - /* TODO: implement proper emulation for SMB380 */ - /* smb380_update(sensor_device, x, y, z); */ - } - return 0; -} -#endif - -/* Find IRQ by it's number */ -static inline qemu_irq s5pc1xx_get_irq(struct s5pc1xx_state_s *s, int n) -{ - return s->irq[n / S5PC1XX_VIC_SIZE][n % S5PC1XX_VIC_SIZE]; -} - -//#include "s5pc1xx_debug.c" - -struct i2c -{ - i2c_bus *intrf0; - i2c_bus *intrf2; - i2c_bus *intrfDDC; - i2c_bus *intrfPHY; - - i2c_bus *gpio3; - i2c_bus *gpio4; - i2c_bus *gpio5; - i2c_bus *gpio10; -}; - -/* Helper structure and two functions. Allow you to connect several irq - sources to one irq input using logical OR. */ -struct irq_multiplexer_s { - qemu_irq parent; - int count; - uint8_t mask[]; -}; - -static void irq_mult_handler(void *opaque, int irq, int level) -{ - uint8_t old_level; - struct irq_multiplexer_s *s = (struct irq_multiplexer_s *)opaque; - - old_level = (s->mask[irq >> 3] >> (irq & 7)) & 1; - if (!old_level && level) { - s->count++; - s->mask[irq >> 3] |= (1 << (irq & 7)); - if (s->count == 1) { - qemu_irq_raise(s->parent); - } - } - if (old_level && !level) { - s->count--; - s->mask[irq >> 3] &= ~(1 << (irq & 7)); - if (s->count == 0) { - qemu_irq_lower(s->parent); - } - } -} - -static qemu_irq *irq_multiplexer(qemu_irq irq, int n) -{ - struct irq_multiplexer_s *s = - qemu_mallocz(sizeof(struct irq_multiplexer_s) + - ((n + 7) << 3) * sizeof(uint8_t)); - s->parent = irq; - return qemu_allocate_irqs(irq_mult_handler, s, n); -} - -static void s5pc110_rst_mm_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - if (val & 1) { - qemu_system_reset_request(); - } -} - -static CPUReadMemoryFunc * const s5pc110_rst_readfn[] = { - NULL, - NULL, - NULL -}; - -static CPUWriteMemoryFunc * const s5pc110_rst_writefn[] = { - s5pc110_rst_mm_write, - s5pc110_rst_mm_write, - s5pc110_rst_mm_write -}; - -static struct arm_boot_info s5pc110x_binfo = { - .loader_start = 0x0, - //.board_id = 0xA74, /* Aquila */ - .board_id = 0xb2e, /* Aquila */ - .revision = 0x803, /* Aquila LiMo Universal */ -}; - -static void s5pc110_reset(void *opaque) -{ - struct s5pc1xx_state_s *s = (struct s5pc1xx_state_s *)opaque; - - s->env->regs[15] = 0x30000000; -} - -/* Initialize and start system */ -static void s5pc110_init(ram_addr_t ram_size, const char *boot_device, - const char *kernel_fname, const char *kernel_cmdline, - const char *initrd_name, const char *cpu_model) -{ - ram_addr_t sdram_off, isrom_off, isram_off, chipid_off; - qemu_irq *cpu_irq; - DeviceState *dev, *dev_prev, *gpio, *dmamem, *dma0, *dma1; - CharDriverState *chr2, *chr3; - qemu_irq *dma_irqs, dma_stop_irq1, dma_stop_irq2; - struct i2c *i2c = (struct i2c *)qemu_mallocz(sizeof(*i2c)); - struct s5pc1xx_state_s *s = - (struct s5pc1xx_state_s *)qemu_mallocz(sizeof(*s)); - int i, j, iomemtype; - DriveInfo *dinfo; - - /* Core */ - s->mpu_model = s5pc110; - s->env = cpu_init("cortex-a8"); - if (!s->env) - hw_error("Unable to find CPU definition (%s)\n", "cortex-a8"); - - /* Chip-ID and OMR */ - chipid_off = qemu_ram_alloc(NULL, "s5pc100.chipid", sizeof(chipid_and_omr)); - cpu_register_physical_memory(S5PC1XX_SFRS, sizeof(chipid_and_omr), - chipid_off | IO_MEM_ROM); - cpu_physical_memory_write_rom(S5PC1XX_SFRS, chipid_and_omr, - sizeof(chipid_and_omr)); - - /* Software reset */ - iomemtype = - cpu_register_io_memory(s5pc110_rst_readfn, s5pc110_rst_writefn, NULL, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(S5PC1XX_SWRST_BASE, 0x4, iomemtype); - - /* Memory */ - /* Main RAM */ - if (ram_size > S5PC1XX_DRAM_MAX_SIZE) { - hw_error("Too much memory was requested for this board " - "(requested: %lu MB, max: %u MB)\n", - ram_size / (1024 * 1024), - S5PC1XX_DRAM_MAX_SIZE / (1024 * 1024)); - } - s->sdram_size = ram_size; - sdram_off = qemu_ram_alloc(NULL, "s5pc100.ram", ram_size); - cpu_register_physical_memory(S5PC1XX_DRAM1_BASE, ram_size, - sdram_off | IO_MEM_RAM); - /* Also map the same memory to boot area. */ - cpu_register_physical_memory(S5PC1XX_BOOT_BASE, ram_size, - sdram_off | IO_MEM_RAM); - - /* Internal SROM */ - s->isrom_size = S5PC1XX_ISROM_SIZE; - isrom_off = qemu_ram_alloc(NULL, "s5pc100.srom", s->isrom_size); - cpu_register_physical_memory(S5PC1XX_IROM_BASE, s->isrom_size, - isrom_off | IO_MEM_ROM); - - /* Internal SRAM */ - s->isram_size = S5PC1XX_ISRAM_SIZE; - isram_off = qemu_ram_alloc(NULL, "s5pc100.sram", s->isram_size); - cpu_register_physical_memory(S5PC1XX_IRAM_BASE, s->isram_size, - isram_off | IO_MEM_RAM); - -#ifndef LOWMEMORY - /* SROMC banks */ - ram_addr_t srom_bank_off = qemu_ram_alloc(NULL, "s5pc100.srombanks", - S5PC1XX_SROMC_MAX_BANK_SIZE); - cpu_register_physical_memory(S5PC1XX_SROMC_B0_BASE, - S5PC1XX_SROMC_NUM_BANKS * S5PC1XX_SROMC_MAX_BANK_SIZE, - srom_bank_off | IO_MEM_ROM); -#endif - - /* System devices */ - /* Interrupts */ - cpu_irq = arm_pic_init_cpu(s->env); - s->irq = - qemu_mallocz(S5PC1XX_VIC_N * sizeof(qemu_irq *)); - dev = pl192_init(S5PC1XX_VIC_BASE, 0, - cpu_irq[ARM_PIC_CPU_IRQ], - cpu_irq[ARM_PIC_CPU_FIQ], NULL); - s->irq[0] = qemu_mallocz(S5PC1XX_VIC_SIZE * sizeof(qemu_irq)); - for (i = 0; i < S5PC1XX_VIC_SIZE; i++) - s->irq[0][i] = qdev_get_gpio_in(dev, i); - for (j = 1; j < S5PC1XX_VIC_N; j++) { - dev_prev = dev; - dev = - pl192_init(S5PC1XX_VIC_BASE + S5PC1XX_VIC_SHIFT * j, j, NULL); - - s->irq[j] = qemu_mallocz(S5PC1XX_VIC_SIZE * sizeof(qemu_irq)); - for (i = 0; i < S5PC1XX_VIC_SIZE; i++) - s->irq[j][i] = qdev_get_gpio_in(dev, i); - pl192_chain(sysbus_from_qdev(dev_prev), sysbus_from_qdev(dev)); - } - - /* GPIO */ - gpio = sysbus_create_varargs("s5pc1xx.gpio", S5PC1XX_GPIO_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_GPIOINT), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_EXTEND), - NULL); - - /* DMA Controller */ - dma_irqs = irq_multiplexer(s5pc1xx_get_irq(s, S5PC1XX_IRQ_DMAMEM), - ((dmamem_cfg[0] >> 17) & 0x1f) + 2); - dmamem = - pl330_init(S5PC1XX_DMAMEM_BASE, 0, dmamem_cfg, dma_irqs + 1, *dma_irqs); - dma_irqs = irq_multiplexer(s5pc1xx_get_irq(s, S5PC1XX_IRQ_DMA0), - ((dma0_cfg[0] >> 17) & 0x1f) + 2); - dma0 = pl330_init(S5PC1XX_DMA0_BASE, 1, dma0_cfg, dma_irqs + 1, *dma_irqs); - dma_irqs = irq_multiplexer(s5pc1xx_get_irq(s, S5PC1XX_IRQ_DMA1), - ((dma1_cfg[0] >> 17) & 0x1f) + 2); - dma1 = pl330_init(S5PC1XX_DMA1_BASE, 2, dma1_cfg, dma_irqs + 1, *dma_irqs); - - /* I2C */ - dev = sysbus_create_simple("s5pc1xx.i2c", S5PC1XX_I2C_0_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_I2C_0)); - i2c->intrf0 = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - dev = sysbus_create_simple("s5pc1xx.i2c", S5PC1XX_I2C_2_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_I2C_2)); - i2c->intrf2 = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - dev = sysbus_create_simple("s5pc1xx.i2c", S5PC1XX_I2C_PHY_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_I2C_PHY)); - i2c->intrfPHY = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - dev = sysbus_create_simple("s5pc1xx.i2c", S5PC1XX_I2C_DDC_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_I2C_DDC)); - i2c->intrfDDC = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - - /* GPIO I2C */ - dev = s5pc1xx_i2c_gpio_init(3); - i2c->gpio3 = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - dev = s5pc1xx_i2c_gpio_init(4); - i2c->gpio4 = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - dev = s5pc1xx_i2c_gpio_init(5); - i2c->gpio5 = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - dev = s5pc1xx_i2c_gpio_init(10); - i2c->gpio10 = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); - - /* SPI */ - sysbus_create_simple("s5pc1xx.spi", - S5PC1XX_SPI_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_SPI0)); - sysbus_create_simple("s5pc1xx.spi", - S5PC1XX_SPI_BASE + S5PC1XX_SPI_SHIFT, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_SPI1)); - sysbus_create_simple("s5pc1xx.spi", - S5PC1XX_SPI_BASE + S5PC1XX_SPI_SHIFT * 2, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_SPI2)); - - /* PMU */ - sysbus_create_simple("s5pc1xx.pmu", S5PC1XX_PMU_BASE, NULL); - - /* MAX17040 */ - max17040_init(i2c->gpio3, S5PC1XX_MAX17040_ADDR); - - /* MAX8998 */ - max8998_init(i2c->gpio4, S5PC1XX_MAX8998_ADDR); - - /* MAX8998 RTC */ - max8998_rtc_init(i2c->gpio4, S5PC1XX_MAX8998_RTC_ADDR); - - /* USB */ - if (usb_enabled) { - sysbus_create_simple("sysbus-ohci", S5PC1XX_USB_OHCI_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_UHOST)); - sysbus_create_simple("usb-ehci", S5PC1XX_USB_EHCI_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_UHOST)); - } - - /* Clock devices */ - /* CMU */ - sysbus_create_simple("s5pc1xx.clk", S5PC1XX_CMU_BASE, NULL); - - /* RTC */ - sysbus_create_varargs("s5pc1xx.rtc", S5PC1XX_RTC_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_RTC_ALARM), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_RTC_TICK), NULL); - - /* PWM */ - sysbus_create_varargs("s5pc1xx.pwm", S5PC1XX_PWM_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_TIMER0), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_TIMER1), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_TIMER2), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_TIMER3), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_TIMER4), NULL); - - /* WDT */ - sysbus_create_simple("s5pc1xx.wdt", S5PC1XX_WDT_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_WDT)); - - /* ST */ - sysbus_create_simple("s5pc1xx.st", S5PC1XX_ST_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_SYS_TIMER)); - - /* Storage devices */ - /* NAND */ - sysbus_create_simple("s5pc1xx.nand", S5PC1XX_NAND_BASE, NULL); - - /* OneNAND */ - s5pc1xx_onenand_init(S5PC1XX_ONENAND_BASE); - - /* SROMC */ - s5pc1xx_srom_init(S5PC1XX_SROMC_BASE, S5PC1XX_SROMC_NUM_BANKS); - - /* SD/MMC */ - sysbus_create_simple("s5pc1xx.mmc", S5PC1XX_HSMMC0_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_MMC0)); - - sysbus_create_simple("s5pc1xx.mmc", S5PC1XX_HSMMC1_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_MMC1)); - - sysbus_create_simple("s5pc1xx.mmc", S5PC1XX_HSMMC2_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_MMC2)); - - sysbus_create_simple("s5pc1xx.mmc", S5PC1XX_HSMMC3_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_MMC3)); - - dinfo = drive_get(IF_IDE, 0, 0); - mmio_ide_init(S5PC1XX_CFCON_ATAPI1, S5PC1XX_CFCON_ATAPI2, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_CFCON), 2, dinfo, NULL); - - /* Input/Output devices */ - /* UART */ - if (serial_hds[0]) { - chr2 = serial_hds[0]; - } else { - chr2 = qemu_chr_open("s5pc1xx.uart", "vc:800x600", NULL); - } - chr3 = - qemu_chr_open("AT_socket", "tcp:localhost:7776,server,nowait", NULL); - s5pc1xx_uart_init(S5PC1XX_UART_BASE, 0, 256, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_UART0), NULL); - s5pc1xx_uart_init(S5PC1XX_UART_BASE + S5PC1XX_UART_SHIFT, 1, 64, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_UART1), NULL); - s5pc1xx_uart_init(S5PC1XX_UART_BASE + S5PC1XX_UART_SHIFT * 2, 2, 16, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_UART2), chr2); - s5pc1xx_uart_init(S5PC1XX_UART_BASE + S5PC1XX_UART_SHIFT * 3, 3, 16, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_UART3), chr3); - - /* QT602240 Touchscreen */ - dev = i2c_create_slave(i2c->intrf2, "qt602240", S5PC1XX_QT602240_ADDR); - qdev_connect_gpio_out(dev, 0, - s5pc1xx_gpoint_irq(gpio, S5PC1XX_QT602240_IRQ)); - - /* S3C Touchscreen */ - s5pc1xx_tsadc_init(S5PC1XX_TSADC0_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_ADC0), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_PENDN0), - 1, 12, 0, 120, 0, 200); - s5pc1xx_tsadc_init(S5PC1XX_TSADC1_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_ADC1), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_PENDN1), - 1, 12, 0, 120, 0, 200); - - /* Keypad */ - s5pc1xx_keyif_init(S5PC1XX_KEYPAD_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_KEYPAD), - "aquila", 8); - - /* MSC5000 Touchkeys */ - dev = i2c_create_slave(i2c->gpio10, "mcs5000.universal", - S5PC1XX_MCS5000_ADDR); - qdev_connect_gpio_out(dev, 0, - s5pc1xx_gpoint_irq(gpio, S5PC1XX_MCS5000_IRQ)); - - /* USB-OTG */ - s5pc1xx_usb_otg_init(&nd_table[0], - S5PC1XX_USB_OTG_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_OTG)); - - /* OneDRAM */ - s5pc1xx_onedram_init("s5pc1xx.onedram.aquila.xmm", S5PC1XX_ONEDRAM_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_ONEDRAM_INT_AP)); - - /* AK8973 Compass Emulation */ - dev = i2c_create_slave(i2c->intrfDDC, "ak8973", S5PC1XX_AK8973_ADDR); - compass_device = dev; - qdev_connect_gpio_out(dev, 0, s5pc1xx_gpoint_irq(gpio, S5PC1XX_AK8973_IRQ)); - - /* Audio devices and interfaces */ - /* SPDIF */ - sysbus_create_simple("s5pc1xx.spdif", S5PC1XX_SPDIF_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_SPDIF)); - - /* AC97 */ - sysbus_create_simple("s5pc1xx.ac97", S5PC1XX_AC97_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_AC97)); - - /* PCM */ - s5pc1xx_pcm_init(S5PC1XX_PCM0_BASE, 0, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_PCM0)); - s5pc1xx_pcm_init(S5PC1XX_PCM1_BASE, 1, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_PCM1)); - s5pc1xx_pcm_init(S5PC1XX_PCM2_BASE, 2, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_PCM2)); - - /* WM8994 */ - dev = i2c_create_slave(i2c->gpio5, "wm8994", S5PC1XX_WM8994_ADDR); - - /* I2S */ - dma_stop_irq1 = qdev_get_gpio_in(dma0, PL330_PERIPH_NUM_I2S1); - dma_stop_irq2 = qdev_get_gpio_in(dma1, PL330_PERIPH_NUM_I2S2); - s5pc1xx_i2s_init(S5PC1XX_I2S2_V5_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_I2S_V5), dev /* WM8994 */, - dma_stop_irq1, dma_stop_irq2); - - /* Video devices */ - /* LCD */ - sysbus_create_varargs("s5pc1xx.lcd", S5PC1XX_LCD_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_LCD0), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_LCD1), - s5pc1xx_get_irq(s, S5PC1XX_IRQ_LCD2), NULL); - - /* JPEG */ - sysbus_create_simple("s5pc1xx.jpeg", S5PC1XX_JPEG_BASE, - s5pc1xx_get_irq(s, S5PC1XX_IRQ_JPEG)); - -#ifdef CONFIG_GLES2 - gles2_init(s->env); -#endif - - /* Load the kernel */ - s5pc110x_binfo.ram_size = ram_size; - s5pc110x_binfo.kernel_filename = kernel_fname; - s5pc110x_binfo.initrd_filename = initrd_name; - s5pc110x_binfo.loader_start = 0x30000000; - if (kernel_cmdline) { - if (strstr(kernel_cmdline,"duallcd")) { - /* Board is 'media' for enabling duallcd */ - s5pc110x_binfo.revision = 0x1003; - } - s5pc110x_binfo.kernel_cmdline = kernel_cmdline; - } else { - s5pc110x_binfo.kernel_cmdline = - "root=/dev/mtdblock2 rootfstype=cramfs init=/linuxrc " - "console=ttySAC2,115200 mem=128M debug"; - } - - arm_load_kernel(s->env, &s5pc110x_binfo); - - qemu_register_reset(s5pc110_reset, s); - s5pc110_reset(s); - - /* Don't hide cursor since we are using touchscreen */ - cursor_hide = 0; -} - -static QEMUMachine s5pc110_machine = { - .name = "s5pc110", - .desc = "S5PC110-base board", - .init = s5pc110_init, -}; - -static void s5pc1xx_machine_init(void) -{ - qemu_register_machine(&s5pc110_machine); -} - -machine_init(s5pc1xx_machine_init); diff --git a/hw/s5pc1xx.h b/hw/s5pc1xx.h deleted file mode 100644 index 88d6306..0000000 --- a/hw/s5pc1xx.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * S5PC1XX-based board emulation. - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - * Vladimir Monakhov - * Alexey Merkulov - * Dmitry Zhurikhin - */ - -#ifndef hw_s5pc1xx_h -#define hw_s5pc1xx_h "s5pc1xx.h" - -#include "qemu-common.h" - - -typedef struct Clk *S5pc1xxClk; -typedef void GPIOWriteMemoryFunc(void *opaque, int io_index, uint32_t value); -typedef uint32_t GPIOReadMemoryFunc(void *opaque, int io_index); - -struct s5pc1xx_state_s { - /* Model */ - enum s5pc1xx_model { - s5pc110 - } mpu_model; - - /* CPU Core */ - CPUState *env; - - /* Interrupts */ - qemu_irq **irq; - - /* Amount of different memory types */ - ram_addr_t sdram_size; - ram_addr_t isrom_size; - ram_addr_t isram_size; -}; - - -int compass_update(int8_t x, int8_t y, int8_t z, int8_t temp); - -/* s5pc1xx_gpio.c */ -void s5pc1xx_gpio_register_io_memory(int io_index, int instance, - GPIOReadMemoryFunc *mem_read, - GPIOWriteMemoryFunc *mem_write, - GPIOWriteMemoryFunc *mem_conf, - void *opaque); - -uint32_t s5pc1xx_empty_gpio_read(void *opaque, int io_index); -void s5pc1xx_empty_gpio_write(void *opaque, int io_index, uint32_t value); - -/* s5pc1xx_i2c_gpio.c */ -DeviceState *s5pc1xx_i2c_gpio_init(int instance); - -/* s5pc1xx_clk.c */ -S5pc1xxClk s5pc1xx_findclk(const char *name); -int64_t s5pc1xx_clk_getrate(S5pc1xxClk clk); - -/* s5pc1xx_pmu.c */ -DeviceState *max17040_init(i2c_bus *bus, int addr); -DeviceState *max8998_init(i2c_bus *bus, int addr); -DeviceState *max8998_rtc_init(i2c_bus *bus, int addr); - -/* s5pc1xx_srom.c */ -DeviceState *s5pc1xx_srom_init(target_phys_addr_t base, int num_banks); - -/* s5pc1xx_gpio.c */ -qemu_irq s5pc1xx_gpoint_irq(DeviceState *d, int irq_num); - -/* s5pc1xx_uart.c */ -DeviceState *s5pc1xx_uart_init(target_phys_addr_t base, int instance, - int queue_size, qemu_irq irq, - CharDriverState *chr); - -/* s5pc1xx_onenand.c */ -DeviceState *s5pc1xx_onenand_init(target_phys_addr_t base); - -/* s5pc1xx_tsadc.c */ -DeviceState *s5pc1xx_tsadc_init(target_phys_addr_t base, qemu_irq irq_adc, - qemu_irq irq_pennd, int new, int resolution, - int minx, int maxx, int miny, int maxy); - -/* s5pc1xx_keyif.c */ -DeviceState *s5pc1xx_keyif_init(target_phys_addr_t base, qemu_irq irq, - const char *keymapname, uint32_t shift); - -/* s5pc1xx_i2s.c */ -DeviceState *s5pc1xx_i2s_init(target_phys_addr_t base, qemu_irq irq, - DeviceState *wm8994_dev, qemu_irq dma_irq1, - qemu_irq dma_irq2); - -/* s5pc1xx_pcm.c */ -DeviceState *s5pc1xx_pcm_init(target_phys_addr_t base, - int instance, - qemu_irq irq); - -/* s5pc1xx_onedram.c */ -DeviceState *s5pc1xx_onedram_init(const char *name, target_phys_addr_t base, - qemu_irq irq_ap); - -/* usb-ohci.c */ -void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn, - qemu_irq irq); - -void s5pc1xx_usb_otg_init(NICInfo *nd, target_phys_addr_t base, qemu_irq irq); - -#endif /* hw_s5pc1xx_h */ diff --git a/hw/s5pc1xx_ac97.c b/hw/s5pc1xx_ac97.c deleted file mode 100644 index f1268a6..0000000 --- a/hw/s5pc1xx_ac97.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * AC97 controller for S5PC110-based board emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "s5pc1xx.h" -#include "qemu-timer.h" -#include "s5pc1xx_gpio_regs.h" -#include "sysbus.h" - -#define ALL_BITS(b,a) (((1 << (b - a + 1)) - 1) << a) - -/* R/W Specifies the AC97 Global Control Register 0x00000000 */ -#define AC_GLBCTRL 0x00 - #define ALL_CLEAR ALL_BITS(30, 24) - #define INT_EN(stat) (stat) - #define TRANSFER_EN (1 << 3) - #define AC_LINK_ON (1 << 2) - #define WARM_RESET (1 << 1) - #define COLD_RESET (1 << 0) - -/* R Specifies the AC97 Global Status Register 0x00000001 */ -#define AC_GLBSTAT 0x04 - #define CODEC_READY_INT (1 << 22) - #define PCM_OUT_UNDER_INT (1 << 21) - #define PCM_IN_OVER_INT (1 << 20) - #define MIC_IN_OVER_INT (1 << 19) - #define PCM_OUT_TH_INT (1 << 18) - #define PCM_IN_TH_INT (1 << 17) - #define MIC_IN_TH_INT (1 << 16) - #define ALL_STAT ALL_BITS(22, 16) - -/* R/W Specifies the AC97 Codec Command Register 0x00000000 */ -#define AC_CODEC_CMD 0x08 -/* R Specifies the AC97 Codec Status Register 0x00000000 */ -#define AC_CODEC_STAT 0x0C -/* R Specifies the AC97 PCM Out/In Channel FIFO Address Register 0x00000000 */ -#define AC_PCMADDR 0x10 -/* R Specifies the AC97 MIC In Channel FIFO Address Register 0x00000000 */ -#define AC_MICADDR 0x14 -/* R/W Specifies the AC97 PCM Out/In Channel FIFO Data Register 0x00000000 */ -#define AC_PCMDATA 0x18 -/* R/W Specifies the AC97 MIC In Channel FIFO Data Register 0x00000000 */ -#define AC_MICDATA 0x1C - -#define S5PC1XX_AC97_REG_MEM_SIZE 0x20 - - -typedef struct S5pc1xxAC97State { - SysBusDevice busdev; - - uint32_t glbctrl; - uint32_t glbstat; - uint32_t codec_cmd; - uint32_t codec_stat; - uint32_t pcmaddr; - uint32_t micaddr; - uint32_t pcmdata; - uint32_t micdata; - - struct FrameIn { - uint16_t pcm_left_fifo[16]; - uint16_t pcm_right_fifo[16]; - - uint64_t pcm_write_idx; - uint64_t pcm_read_idx; - - uint16_t mic_fifo[16]; - - uint64_t mic_write_idx; - uint64_t mic_read_idx; - - uint16_t tag_phase; - uint32_t data_phase[12]; - } in; - - struct FrameOut { - uint16_t pcm_left_fifo[16]; - uint16_t pcm_right_fifo[16]; - - uint64_t pcm_write_idx; - uint64_t pcm_read_idx; - - uint16_t tag_phase; - uint32_t data_phase[12]; - } out; - - uint8_t delay; - uint8_t cur_pos; - uint8_t stream; - uint8_t sync_en; - uint8_t reset; - - qemu_irq irq; - QEMUTimer *ac97_timer; - uint64_t last_ac97_time; -} S5pc1xxAC97State; - - -/* Function for initialization and cold reset */ -static void s5pc1xx_ac97_reset(void *opaque) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - int i; - - s->delay = 2; - s->stream = 0; - s->sync_en = 0; - - s->glbctrl = 0; - s->glbstat = 0; - s->codec_cmd = 0; - s->codec_stat = 0; - s->pcmaddr = 0; - s->micaddr = 0; - s->pcmdata = 0; - s->micdata = 0; - - s->in.tag_phase = 0; - s->out.tag_phase = 0; - - for (i = 0; i < 12; i++) { - s->in.data_phase[i] = 0; - s->out.data_phase[i] = 0; - } -} - -/* Interrupts handler */ -static void s5pc1xx_ac97_irq(S5pc1xxAC97State *s, - uint32_t stat, uint32_t clear) -{ - if (stat) { - s->glbstat |= stat; - if (s->glbctrl & INT_EN(stat)) /* if enabled */ - qemu_irq_raise(s->irq); - } - if (clear) { - s->glbstat &= ~(clear >> 8); - if (!(s->glbstat & ALL_STAT)) /* if all clear */ - qemu_irq_lower(s->irq); - } -} - -/* Controls input fifo stage */ -static void s5pc1xx_ac97_infifo_control(S5pc1xxAC97State *s) -{ - uint8_t pcm_depth, mic_depth; - - pcm_depth = (s->in.pcm_write_idx - s->in.pcm_read_idx) % 17; - mic_depth = (s->in.mic_write_idx - s->in.mic_read_idx) % 17; - - if (pcm_depth == 16) - s5pc1xx_ac97_irq(s, PCM_IN_OVER_INT, 0); - - if (pcm_depth > 7) - s5pc1xx_ac97_irq(s, PCM_IN_TH_INT, 0); - - if (mic_depth == 16) - s5pc1xx_ac97_irq(s, MIC_IN_OVER_INT, 0); - - if (mic_depth > 7) - s5pc1xx_ac97_irq(s, MIC_IN_TH_INT, 0); -} - -/* Controls output fifo stage */ -static void s5pc1xx_ac97_outfifo_control(S5pc1xxAC97State *s) -{ - uint8_t pcm_depth; - - pcm_depth = (s->out.pcm_write_idx - s->out.pcm_read_idx) % 17; - - if (pcm_depth == 0) - s5pc1xx_ac97_irq(s, PCM_OUT_UNDER_INT, 0); - - if (pcm_depth < 9) - s5pc1xx_ac97_irq(s, PCM_OUT_TH_INT, 0); -} - -/* Sync timer */ -static void s5pc1xx_ac97_sync(void *opaque) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - uint64_t next_ac97_time; - - if (s->sync_en) { - s->delay = 0; /* used for 1/12MHz delay */ - s->last_ac97_time = qemu_get_clock(vm_clock); - next_ac97_time = s->last_ac97_time + - muldiv64(1, get_ticks_per_sec(), 48000); /* 48 KHz cycle */ - qemu_mod_timer(s->ac97_timer, next_ac97_time); - } else { - qemu_del_timer(s->ac97_timer); - } -} - -/* Bitclk cycles counter */ -static uint8_t s5pc1xx_ac97_spent_cycles(S5pc1xxAC97State *s) -{ - uint64_t spent_1G, spent_12M; - - spent_1G = qemu_get_clock(vm_clock) - s->last_ac97_time; - spent_12M = muldiv64(spent_1G, 12288000, get_ticks_per_sec()); - - return (spent_12M % 256); -} - -/* Get current input frame and prepare next output frame */ -static void s5pc1xx_ac97_next_frame(S5pc1xxAC97State *s) -{ - short i; - - /* Get input frame */ - - /* check if codec_ready */ - if (s->in.tag_phase & (1 << 15)) { - /* check tag bits and check if the received address - * is equal to the most recent sent address */ - if ((s->in.tag_phase & (1 << 14)) && - (s->in.tag_phase & (1 << 13)) && - (s->in.data_phase[0] & ALL_BITS(18, 12)) == - (s->out.data_phase[0] & ALL_BITS(18, 12))) - s->codec_stat = (s->in.data_phase[0] << 4 & ALL_BITS(22, 16)) | - (s->in.data_phase[1] >> 4); - - if (s->in.pcm_write_idx < s->in.pcm_read_idx + 16) { - - if (s->in.tag_phase & (1 << 12)) - s->in.pcm_left_fifo[s->in.pcm_write_idx % 16] = - (s->in.data_phase[2] >> 4); - - if (s->in.tag_phase & (1 << 11)) - s->in.pcm_right_fifo[s->in.pcm_write_idx % 16] = - (s->in.data_phase[3] >> 4); - - s->in.pcm_write_idx++; - } - - if (s->in.mic_write_idx < s->in.mic_read_idx + 16) { - - if (s->in.tag_phase & (1 << 9)) - s->in.mic_fifo[s->in.mic_write_idx % 16] = - (s->in.data_phase[5] >> 4); - - s->in.mic_write_idx++; - } - - s5pc1xx_ac97_infifo_control(s); - } - - /* Set output frame */ - - s->out.tag_phase = 0; - for (i = 0; i < 4; i++) - s->out.data_phase[i] = 0; - - if (s->codec_cmd) { - /* enable slots 1 and 2 */ - s->out.tag_phase |= ALL_BITS(14, 13); - s->out.data_phase[0] = s->codec_cmd >> 4 & ALL_BITS(19, 12); - s->out.data_phase[1] = s->codec_cmd << 4 & ALL_BITS(19, 4); - s->codec_cmd = 0; - } else { - s->out.tag_phase &= ~ALL_BITS(14, 13); - } - - /* check if fifo is not empty */ - if (s->out.pcm_read_idx < s->out.pcm_write_idx) { - /* enable slots 3 and 4 */ - s->out.tag_phase |= ALL_BITS(12, 11); - s->out.data_phase[2] = - s->out.pcm_left_fifo[s->out.pcm_read_idx % 16] << 4; - s->out.data_phase[3] = - s->out.pcm_right_fifo[s->out.pcm_read_idx % 16] << 4; - s->out.pcm_read_idx++; - } else { - s->out.tag_phase &= ~ALL_BITS(12, 11); - } - - /* set bit 15 if any of bits 14~11 is high */ - if (s->out.tag_phase & ALL_BITS(14, 11)) - s->out.tag_phase |= (1 << 15); - - s5pc1xx_ac97_outfifo_control(s); -} - -/* Read AC97 by GPIO */ -static uint32_t s5pc1xx_ac97_gpio_read(void *opaque, int io_index) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - uint8_t ret_val; - - switch (io_index) { - case GPIO_AC97RESETn: - return s->reset; - - case GPIO_AC97SYNC: - return ((s->sync_en) && (s5pc1xx_ac97_spent_cycles(s) < 16)); - - case GPIO_AC97SDO: - if (!s->stream) - break; - - /* Note: '-1' is a delay just after start */ - s->cur_pos = s5pc1xx_ac97_spent_cycles(s) - 1; - - if (s->cur_pos < 16) - ret_val = s->out.tag_phase >> (15 - s->cur_pos) & 0x1; - else - ret_val = - s->out.data_phase[(s->cur_pos - 16) / 20] >> - (19 - (s->cur_pos - 16) % 20) & 0x1; - return ret_val; - } - return 0; -} - -/* Write AC97 by GPIO */ -static void s5pc1xx_ac97_gpio_write(void *opaque, int io_index, uint32_t value) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - - switch (io_index) { - case GPIO_AC97BITCLK: - if (value) { - if (s->delay == 1) - s5pc1xx_ac97_next_frame(s); - if (s->delay < 2) - s->delay++; - } - break; - - case GPIO_AC97SDI: - if (!(s->stream)) - break; - - /* Note: '-1' is a delay just after start */ - s->cur_pos = s5pc1xx_ac97_spent_cycles(s) - 1; - - if (s->cur_pos < 16) - s->in.tag_phase |= value << (15 - s->cur_pos); - else - s->in.data_phase[(s->cur_pos - 16) / 20] |= - value << (19 - (s->cur_pos - 16) % 20); - break; - } -} - -static GPIOReadMemoryFunc *s5pc1xx_ac97_gpio_readfn = s5pc1xx_ac97_gpio_read; -static GPIOWriteMemoryFunc *s5pc1xx_ac97_gpio_writefn = s5pc1xx_ac97_gpio_write; - -/* Read AC97 by OS */ -static uint32_t s5pc1xx_ac97_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - - switch(offset) { - case AC_GLBCTRL: - return s->glbctrl; - case AC_GLBSTAT: - return s->glbstat; - case AC_CODEC_CMD: - return s->codec_cmd; - case AC_CODEC_STAT: - return s->codec_stat; - case AC_PCMADDR: - s->pcmaddr = ((s->in.pcm_write_idx % 16) << 0) | - ((s->out.pcm_write_idx % 16) << 8) | - ((s->in.pcm_read_idx % 16) << 16) | - ((s->out.pcm_read_idx % 16) << 24); - return s->pcmaddr; - case AC_MICADDR: - s->micaddr = ((s->in.mic_write_idx % 16) << 0) | - ((s->in.mic_read_idx % 16) << 16); - return s->micaddr; - case AC_PCMDATA: - /* check if fifo is not empty */ - if (s->in.pcm_read_idx < s->in.pcm_write_idx) { - s->pcmdata = s->in.pcm_left_fifo[s->in.pcm_read_idx % 16] | - (s->in.pcm_right_fifo[s->in.pcm_read_idx % 16] << 16); - s->in.pcm_read_idx++; - } else { - return 0; - } - return s->pcmdata; - case AC_MICDATA: - /* check if fifo is not empty */ - if (s->in.mic_read_idx < s->in.mic_write_idx) { - s->micdata = s->in.mic_fifo[s->in.mic_read_idx % 16]; - s->in.mic_read_idx++; - } else { - return 0; - } - return s->micdata; - default: - hw_error("s5pc1xx.ac97: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -/* Write AC97 by OS */ -static void s5pc1xx_ac97_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - - switch(offset) { - case AC_GLBCTRL: - if (value & COLD_RESET) { - s->reset = 1; - s5pc1xx_ac97_reset(s); - } - - if (value & WARM_RESET) { - s->reset = 0; - s5pc1xx_ac97_irq(s, CODEC_READY_INT, 0); - } - - if (s->reset) - break; - - if ((value & AC_LINK_ON) > (s->glbctrl & AC_LINK_ON)) { - s->sync_en = 1; - s5pc1xx_ac97_sync(s); - } - - /* the value is set high above */ - s->sync_en = (value & AC_LINK_ON) ? : 0; - s->stream = (value & TRANSFER_EN) ? 1 : 0; - - if (value & ALL_CLEAR) - s5pc1xx_ac97_irq(s, 0, value & ALL_CLEAR); - - s->glbctrl = value & ~ALL_CLEAR; - break; - case AC_CODEC_CMD: - if (!s->reset) - s->codec_cmd = value; - break; - case AC_PCMDATA: - if (s->reset) - break; - - /* check if fifo is full */ - if (s->out.pcm_write_idx == s->out.pcm_read_idx + 16) - break; - - s->out.pcm_left_fifo[s->out.pcm_write_idx % 16] = - value & ALL_BITS(15, 0); - s->out.pcm_right_fifo[s->out.pcm_write_idx % 16] = - value >> 16 & ALL_BITS(15, 0); - - s->out.pcm_write_idx++; - break; - case AC_MICDATA: - /* mic data can't be written */ - break; - default: - hw_error("s5pc1xx.ac97: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_ac97_readfn[] = { - s5pc1xx_ac97_read, - s5pc1xx_ac97_read, - s5pc1xx_ac97_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_ac97_writefn[] = { - s5pc1xx_ac97_write, - s5pc1xx_ac97_write, - s5pc1xx_ac97_write -}; - -static void s5pc1xx_ac97_save(QEMUFile *f, void *opaque) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - uint64_t last; - int i; - - qemu_put_be32s(f, &s->glbctrl); - qemu_put_be32s(f, &s->glbstat); - qemu_put_be32s(f, &s->codec_cmd); - qemu_put_be32s(f, &s->codec_stat); - qemu_put_be32s(f, &s->pcmaddr); - qemu_put_be32s(f, &s->micaddr); - qemu_put_be32s(f, &s->pcmdata); - qemu_put_be32s(f, &s->micdata); - - for (i = 0; i < 16; i++) { - qemu_put_be16s(f, &s->in.pcm_left_fifo[i]); - qemu_put_be16s(f, &s->in.pcm_right_fifo[i]); - qemu_put_be16s(f, &s->in.mic_fifo[i]); - } - - for (i = 0; i < 12; i++) { - qemu_put_be32s(f, &s->in.data_phase[i]); - } - - qemu_put_be64s(f, &s->in.pcm_write_idx); - qemu_put_be64s(f, &s->in.pcm_read_idx); - - qemu_put_be64s(f, &s->in.mic_write_idx); - qemu_put_be64s(f, &s->in.mic_read_idx); - - qemu_put_be16s(f, &s->in.tag_phase); - - for (i = 0; i < 16; i++) { - qemu_put_be16s(f, &s->out.pcm_left_fifo[i]); - qemu_put_be16s(f, &s->out.pcm_right_fifo[i]); - } - - for (i = 0; i < 12; i++) { - qemu_put_be32s(f, &s->out.data_phase[i]); - } - - qemu_put_be64s(f, &s->out.pcm_write_idx); - qemu_put_be64s(f, &s->out.pcm_read_idx); - qemu_put_be16s(f, &s->out.tag_phase); - - qemu_put_8s(f, &s->delay); - qemu_put_8s(f, &s->cur_pos); - qemu_put_8s(f, &s->stream); - qemu_put_8s(f, &s->sync_en); - qemu_put_8s(f, &s->reset); - - last = qemu_get_clock(vm_clock) - s->last_ac97_time; - qemu_put_be64s(f, &last); - - qemu_put_timer(f, s->ac97_timer); -} - -static int s5pc1xx_ac97_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxAC97State *s = (S5pc1xxAC97State *)opaque; - uint64_t last; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->glbctrl); - qemu_get_be32s(f, &s->glbstat); - qemu_get_be32s(f, &s->codec_cmd); - qemu_get_be32s(f, &s->codec_stat); - qemu_get_be32s(f, &s->pcmaddr); - qemu_get_be32s(f, &s->micaddr); - qemu_get_be32s(f, &s->pcmdata); - qemu_get_be32s(f, &s->micdata); - - for (i = 0; i < 16; i++) { - qemu_get_be16s(f, &s->in.pcm_left_fifo[i]); - qemu_get_be16s(f, &s->in.pcm_right_fifo[i]); - qemu_get_be16s(f, &s->in.mic_fifo[i]); - } - - for (i = 0; i < 12; i++) { - qemu_get_be32s(f, &s->in.data_phase[i]); - } - - qemu_get_be64s(f, &s->in.pcm_write_idx); - qemu_get_be64s(f, &s->in.pcm_read_idx); - - qemu_get_be64s(f, &s->in.mic_write_idx); - qemu_get_be64s(f, &s->in.mic_read_idx); - - qemu_get_be16s(f, &s->in.tag_phase); - - for (i = 0; i < 16; i++) { - qemu_get_be16s(f, &s->out.pcm_left_fifo[i]); - qemu_get_be16s(f, &s->out.pcm_right_fifo[i]); - } - - for (i = 0; i < 12; i++) { - qemu_get_be32s(f, &s->out.data_phase[i]); - } - - qemu_get_be64s(f, &s->out.pcm_write_idx); - qemu_get_be64s(f, &s->out.pcm_read_idx); - qemu_get_be16s(f, &s->out.tag_phase); - - qemu_get_8s(f, &s->delay); - qemu_get_8s(f, &s->cur_pos); - qemu_get_8s(f, &s->stream); - qemu_get_8s(f, &s->sync_en); - qemu_get_8s(f, &s->reset); - - qemu_get_be64s(f, &last); - s->last_ac97_time = qemu_get_clock(vm_clock) - last; - - qemu_get_timer(f, s->ac97_timer); - - return 0; -} - -/* AC97 initialization */ -static int s5pc1xx_ac97_init(SysBusDevice *dev) -{ - S5pc1xxAC97State *s = FROM_SYSBUS(S5pc1xxAC97State, dev); - int iomemtype; - - sysbus_init_irq(dev, &s->irq); - iomemtype = - cpu_register_io_memory(s5pc1xx_ac97_readfn, s5pc1xx_ac97_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_AC97_REG_MEM_SIZE, iomemtype); - - s5pc1xx_gpio_register_io_memory(GPIO_IDX_AC97, 0, s5pc1xx_ac97_gpio_readfn, - s5pc1xx_ac97_gpio_writefn, NULL, s); - s->ac97_timer = qemu_new_timer(vm_clock, s5pc1xx_ac97_sync, s); - - qemu_register_reset(s5pc1xx_ac97_reset, s); - s5pc1xx_ac97_reset(s); - - register_savevm(&dev->qdev, "s5pc1xx.ac97", -1, 1, - s5pc1xx_ac97_save, s5pc1xx_ac97_load, s); - - return 0; -} - -static void s5pc1xx_ac97_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.ac97", sizeof(S5pc1xxAC97State), - s5pc1xx_ac97_init); -} - -device_init(s5pc1xx_ac97_register_devices) diff --git a/hw/s5pc1xx_clk.c b/hw/s5pc1xx_clk.c deleted file mode 100644 index 6acdd97..0000000 --- a/hw/s5pc1xx_clk.c +++ /dev/null @@ -1,827 +0,0 @@ -/* - * Clock controller for S5PC1XX-based board emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - * - * Based on OMAP CMU (hw/omap_clk.c) - */ - -#include "sysbus.h" -#include "s5pc1xx.h" - - -/* PLL lock */ -#define APLL_LOCK 0x000 /* R/W Control PLL locking period for APLL 0x0000_0FFF */ -#define MPLL_LOCK 0x008 /* R/W Control PLL locking period for MPLL 0x0000_0FFF */ -#define EPLL_LOCK 0x010 /* R/W Control PLL locking period for EPLL 0x0000_0FFF */ -#define VPLL_LOCK 0x020 /* R/W Control PLL locking period for VPLL 0x0000_0FFF */ - -/* PLL control */ -#define APLL_CON 0x100 /* R/W Control PLL output frequency for APLL 0x0C80_0301 */ -#define MPLL_CON 0x108 /* R/W Control PLL output frequency for MPLL 0x014D_0301 */ -#define EPLL_CON 0x110 /* R/W Control PLL output frequency for EPLL 0x0085_0302 */ -#define VPLL_CON 0x120 /* R/W Control PLL output frequency for VPLL 0x006C_0303 */ - -/* Clock source */ -#define CLK_SRC0 0x200 /* R/W Select clock source 0 (Main) 0x0000_0000 */ - - #define ONENAND_SHIFT 28 - #define MUX133_SHIFT 24 - #define MUX166_SHIFT 20 - #define MUX200_SHIFT 16 - #define VPLL_SHIFT 12 - #define EPLL_SHIFT 8 - #define MPLL_SHIFT 4 - #define APLL_SHIFT 0 - -#define CLK_SRC1 0x204 /* R/W Select clock source 1 (Multimedia) 0x0000_0000 */ -#define CLK_SRC2 0x208 /* R/W Select clock source 2 (Multimedia) 0x0000_0000 */ - - #define MFC_SHIFT 4 - #define G3D_SHIFT 0 - -#define CLK_SRC3 0x20C /* R/W Select clock source 3 (Multimedia) 0x0000_0000 */ -#define CLK_SRC4 0x210 /* R/W Select clock source 4 (Connectivity) 0x0000_0000 */ -#define CLK_SRC5 0x214 /* R/W Select clock source 5 (Connectivity) 0x0000_0000 */ - - #define MUX_PWM_SHIFT 12 - -#define CLK_SRC6 0x218 /* R/W Select clock source 6 (Audio) 0x0000_0000 */ - - #define MUX_ONEDRAM_SHIFT 24 - #define MUX_HPM_SHIFT 16 - #define MUX_SPDIF_SHIFT 12 - #define MUX_AUDIO_2_SHIFT 8 - #define MUX_AUDIO_1_SHIFT 4 - #define MUX_AUDIO_0_SHIFT 0 - -#define CLK_SRC_MASK0 0x280 /* R/W Clock source mask0 0xFFFF_FFFF */ -#define CLK_SRC_MASK1 0x284 /* R/W Clock source mask1 0xFFFF_FFFF */ - -/* Clock divider */ -#define CLK_DIV0 0x300 /* R/W Set clock divider ratio 0 (System clocks) 0x0000_0000 */ - -#define PCLK66_SHIFT 28 -#define HCLK133_SHIFT 24 -#define PCLK83_SHIFT 20 -#define HCLK166_SHIFT 16 -#define PCLK100_SHIFT 12 -#define HCLK200_SHIFT 8 -#define A2M_SHIFT 4 -#define APLL_SHIFT 0 - -#define CLK_DIV1 0x304 /* R/W Set clock divider ratio 1 (Multimedia) 0x0000_0000 */ -#define CLK_DIV2 0x308 /* R/W Set clock divider ratio 2 (Multimedia) 0x0000_0000 */ -#define CLK_DIV3 0x30C /* R/W Set clock divider ratio 3 (Multimedia) 0x0000_0000 */ -#define CLK_DIV4 0x310 /* R/W Set clock divider ratio 4 (Connectivity) 0x0000_0000 */ -#define CLK_DIV5 0x314 /* R/W Set clock divider ratio 5 (Connectivity) 0x0000_0000 */ - - #define DIV_PWM_SHIFT 12 - -#define CLK_DIV6 0x318 /* R/W Set clock divider ratio 6 (Audio & Others) 0x0000_0000 */ - - #define DIV_AUDIO_2_SHIFT 8 - #define DIV_AUDIO_1_SHIFT 4 - #define DIV_AUDIO_0_SHIFT 0 - -#define CLK_DIV7 0x31C /* R/W Set clock divider ratio 7 (IEM_IEC) 0x0000_0000 */ - -/* Clock gating */ -#define CLK_GATE_MAIN0 0x400 /* R/W Control AXI/AHB clock gating 0 0xFFFF_FFFF */ -#define CLK_GATE_MAIN1 0x404 /* R/W Control AXI/AHB clock gating 1 0xFFFF_FFFF */ -#define CLK_GATE_MAIN2 0x408 /* R/W Control AXI/AHB clock gating 2 0xFFFF_FFFF */ -#define CLK_GATE_PERI0 0x420 /* R/W Control APB clock gating 0 0xFFFF_FFFF */ -#define CLK_GATE_PERI1 0x424 /* R/W Control APB clock gating 1 0xFFFF_FFFF */ -#define CLK_GATE_SCLK0 0x440 /* R/W Control SCLK clock gating0 0xFFFF_FFFF */ -#define CLK_GATE_SCLK1 0x444 /* R/W Control SCLK clock gating1 0xFFFF_FFFF */ -#define CLK_GATE_IP0 0x460 /* R/W Control IP clock gating0 0xFFFF_FFFF */ -#define CLK_GATE_IP1 0x464 /* R/W Control IP clock gating1 0xFFFF_FFFF */ -#define CLK_GATE_IP2 0x468 /* R/W Control IP clock gating2 0xFFFF_FFFF */ -#define CLK_GATE_IP3 0x46C /* R/W Control IP clock gating3 0xFFFF_FFFF */ -#define CLK_GATE_IP4 0x470 /* R/W Control IP clock gating4 0xFFFF_FFFF */ -#define CLK_GATE_BLOCK 0x480 /* R/W Control block clock gating 0xFFFF_FFFF */ -#define CLK_GATE_BUS0 0x484 /* R/W Control AXI/AHB bus clock gating 0 0xFFFF_FFFF */ -#define CLK_GATE_BUS1 0x488 /* R/W Control AXI/AHB bus clock gating 1 0xFFFF_FFFF */ - -/* Clock output */ -#define CLK_OUT 0x500 /* R/W Select clock output 0x0000_0000 */ - -/* Clock divider status */ -#define CLK_DIV_STAT0 0x1000 /* R Clock divider status 0 (CLK_DIV0~3) 0x1111_1111 */ -#define CLK_DIV_STAT1 0x1004 /* R Clock divider status 1 (CLK_DIV4~5) 0x0001_0000 */ - -/* Clock MUX status */ -#define CLK_MUX_STAT0 0x1100 /* R Clock MUX status 0 0x0000_0000 */ -#define CLK_MUX_STAT1 0x1104 /* R Clock MUX status 1 0x0000_0000 */ - -/* Control bits */ -#define XOM_0 0 -#define VPLLSRC_SEL 1 -#define ALL_MUX_BITS_0 (1 << ONENAND_SHIFT) | (1 << MUX133_SHIFT) | \ - (1 << MUX166_SHIFT) | (1 << MUX200_SHIFT) | \ - (1 << VPLL_SHIFT) | (1 << EPLL_SHIFT) | \ - (1 << MPLL_SHIFT) | (1 << APLL_SHIFT) -#define ALL_DIV_BITS_0 (7 << PCLK66_SHIFT) | (0xf << HCLK133_SHIFT) | \ - (7 << PCLK83_SHIFT) | (0xf << HCLK166_SHIFT) | \ - (7 << PCLK100_SHIFT)| (7 << HCLK200_SHIFT) | \ - (7 << A2M_SHIFT) | (7 << APLL_SHIFT) - -#define ALL_MUX_BITS_5 0xffff /* all the [15:0] bits are used */ -#define ALL_DIV_BITS_5 0xffff /* all the [15:0] bits are used */ - -#define NONE -1 - -#define S5PC1XX_CLK_REG_MEM_SIZE 0x1110 - - -typedef struct { - SysBusDevice busdev; - - uint32_t lock_data[5]; /* PLL lock */ - uint32_t conf_data[5]; /* PLL control */ - uint32_t clk_src[7]; /* Clock source */ - uint32_t src_mask[2]; /* Clock source mask */ - uint32_t clk_div[8]; /* Clock divider */ - uint32_t clk_gate[23]; /* Clock gating */ - uint32_t clk_out; /* Clock output */ - uint32_t div_stat[2]; /* Clock divider status */ - uint32_t mux_stat[2]; /* Clock MUX status */ -} CmuStat; - -typedef struct Clk { - const char *name; /* Clock name */ - const char *alias; /* Clock notes */ - struct Clk *parent; /* Parent clock */ - - struct Clk *parents[9]; /* Parent cases */ - - unsigned short enabled; /* Is enabled, regardless of its input clk */ - unsigned long rate; /* Current rate */ - - unsigned int div_val; /* Rate relative to input (if .enabled) */ - unsigned int mult_val; /* Rate relative to input (if .enabled) */ - - short mux_shift; /* MANDATORY FIELD - Shift for mux value in CLK_SRC */ - short div_shift; /* MANDATORY FIELD - Shift for divisor value in CLK_DIV */ - - unsigned short src_reg_num; /* See above (default value = 0) */ - unsigned short div_reg_num; /* See above (default value = 0) */ -} Clk; - - -/* Clocks */ - -/* oscillators */ -static Clk xtal_osc12m = { - .name = "XXTI", - .rate = 24000000, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk xtal_osc27m = { - .name = "XXTI27", - .rate = 27000000, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk xtal_usb_osc48m = { - .name = "XusbXTI", - .rate = 24000000, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk xtal_rtc_osc32k = { - .name = "XrtcXTI", - .rate = 32768, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk sclk_hdmi27m = { - .name = "SCLK_HDMI27M", - .alias = "clkin", - .parents = {&xtal_osc27m}, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk fin_pll = { - .name = "fin_pll", - .alias = "clkin", - .parents = {XOM_0 ? &xtal_usb_osc48m : &xtal_osc12m}, - .mux_shift = NONE, - .div_shift = NONE, -}; - -/* PLLs */ -static Clk apll = { - .name = "apll", - .parents = {&fin_pll}, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk mpll = { - .name = "mpll", - .parents = {&fin_pll}, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk epll = { - .name = "epll", - .parents = {&fin_pll}, - .mux_shift = NONE, - .div_shift = NONE, -}; - -static Clk vpll = { - .name = "vpll", - .parents = {VPLLSRC_SEL ? &sclk_hdmi27m : &fin_pll}, - .mux_shift = NONE, - .div_shift = NONE, -}; - -/* reference clocks */ -static Clk sclk_apll = { - .name = "sclk_apll", - .parents = {&fin_pll, &apll}, - .mux_shift = APLL_SHIFT, /* MUXapll */ - .div_shift = NONE, -}; - -static Clk sclk_mpll = { - .name = "sclk_mpll", - .parents = {&fin_pll, &mpll}, - .mux_shift = MPLL_SHIFT, /* MUXmpll */ - .div_shift = NONE, -}; - -static Clk sclk_epll = { - .name = "sclk_epll", - .parents = {&fin_pll, &epll}, - .mux_shift = EPLL_SHIFT, /* MUXepll */ - .div_shift = NONE, -}; - -static Clk sclk_vpll = { - .name = "sclk_vpll", - .parents = {&fin_pll, &vpll}, - .mux_shift = VPLL_SHIFT, /* MUXvpll */ - .div_shift = NONE, -}; - -static Clk sclk_a2m = { - .name = "sclk_a2m", - .parents = {&sclk_apll}, - .mux_shift = NONE, - .div_shift = A2M_SHIFT, /* DIVa2m (1~8) */ -}; - -/* 133MHz domain clocks */ -static Clk hclk133 = { - .name = "hclk_133", - .parents = {&sclk_mpll, &sclk_a2m}, - .mux_shift = MUX133_SHIFT, /* MUX133 */ - .div_shift = HCLK133_SHIFT, /* DIVck133 (1~16) */ -}; - -static Clk pclk66 = { - .name = "pclk_66", - .parents = {&hclk133}, - .mux_shift = NONE, - .div_shift = PCLK66_SHIFT, /* DIVck66 (1~8) */ -}; - -/* 166MHz domain clocks */ -static Clk hclk166 = { - .name = "hclk_166", - .parents = {&sclk_mpll, &sclk_a2m}, - .mux_shift = MUX166_SHIFT, /* MUX166 */ - .div_shift = HCLK166_SHIFT, /* DIVck166 (1~16) */ -}; - -static Clk pclk83 = { - .name = "pclk_83", - .parents = {&hclk166}, - .mux_shift = NONE, - .div_shift = PCLK83_SHIFT, /* DIVck83 (1~8) */ -}; - -/* 200MHz domain clocks */ -static Clk armclk = { - .name = "armclk", - .parents = {&sclk_apll, &sclk_mpll}, - .mux_shift = MUX200_SHIFT, /* MUX200 */ - .div_shift = APLL_SHIFT, /* DIVapll (1~8) */ -}; - -static Clk hclk200 = { - .name = "hclk_200", - .parents = {&armclk}, - .mux_shift = NONE, - .div_shift = HCLK200_SHIFT, /* DIVck200 (1~8) */ -}; - -static Clk pclk100 = { - .name = "pclk_100", - .parents = {&hclk200}, - .mux_shift = NONE, - .div_shift = PCLK100_SHIFT, /* DIVck100 (1~8) */ -}; - -static Clk hclk100 = { - .name = "hclk_100", - .parents = {&hclk200}, - .div_val = 2, /* DIVimem (2) */ - .mux_shift = NONE, - .div_shift = NONE, -}; - -/* Special clocks */ - -static Clk sclk_pwm = { - .name = "sclk_pwm", - .parents = {&xtal_osc12m, &xtal_usb_osc48m, &sclk_hdmi27m, - - /* TODO: should be SCLK_USBPHY0, SCLK_USBPHY1, SCLK_HDMIPHY below */ - &sclk_hdmi27m, &sclk_hdmi27m, &sclk_hdmi27m, - - &sclk_mpll, &sclk_epll, &sclk_vpll}, - .src_reg_num = 5, /* CLK_SRC5 register */ - .mux_shift = MUX_PWM_SHIFT, /* MUXpwm */ - .div_reg_num = 5, /* CLK_DIV5 register */ - .div_shift = DIV_PWM_SHIFT, /* DIVpwm (1~16) */ -}; - -static Clk sclk_audio_0 = { - .name = "sclk_audio_0", - .parents = {&xtal_osc12m, - - /* TODO: should be PCMCDCLK0 below */ - &xtal_usb_osc48m, - - &sclk_hdmi27m, - - /* TODO: should be SCLK_USBPHY0, SCLK_USBPHY1, SCLK_HDMIPHY below */ - &sclk_hdmi27m, &sclk_hdmi27m, &sclk_hdmi27m, - - &sclk_mpll, &sclk_epll, &sclk_vpll}, - .src_reg_num = 6, /* CLK_SRC6 register */ - .mux_shift = MUX_AUDIO_0_SHIFT, /* MUXaudio0 */ - .div_reg_num = 6, /* CLK_DIV6 register */ - .div_shift = DIV_AUDIO_0_SHIFT, /* DIVaudio0 (1~16) */ -}; - -static Clk sclk_audio_1 = { - .name = "sclk_audio_1", - .parents = { - /* TODO should be I2SCDCLK1, PCMCDCLK1 below */ - &xtal_osc12m, &xtal_usb_osc48m, - - &sclk_hdmi27m, - - /* TODO: should be SCLK_USBPHY0, SCLK_USBPHY1, SCLK_HDMIPHY below */ - &sclk_hdmi27m, &sclk_hdmi27m, &sclk_hdmi27m, - - &sclk_mpll, &sclk_epll, &sclk_vpll}, - .src_reg_num = 6, /* CLK_SRC6 register */ - .mux_shift = MUX_AUDIO_1_SHIFT, /* MUXaudio1 */ - .div_reg_num = 6, /* CLK_DIV6 register */ - .div_shift = DIV_AUDIO_1_SHIFT, /* DIVaudio1 (1~16) */ -}; - -static Clk sclk_audio_2 = { - .name = "sclk_audio_2", - .parents = { - /* TODO: should be I2SCDCLK2, PCMCDCLK2 below */ - &xtal_osc12m, &xtal_usb_osc48m, - - &sclk_hdmi27m, - - /* TODO: should be SCLK_USBPHY0, SCLK_USBPHY1, SCLK_HDMIPHY below */ - &sclk_hdmi27m, &sclk_hdmi27m, &sclk_hdmi27m, - - &sclk_mpll, &sclk_epll, &sclk_vpll}, - .src_reg_num = 6, /* CLK_SRC6 register */ - .mux_shift = MUX_AUDIO_2_SHIFT, /* MUXaudio2 */ - .div_reg_num = 6, /* CLK_DIV6 register */ - .div_shift = DIV_AUDIO_2_SHIFT, /* DIVaudio2 (1~16) */ -}; - -static Clk sclk_spdif = { - .name = "sclk_spdif", - .parents = {&sclk_audio_0, &sclk_audio_1, &sclk_audio_2}, - .src_reg_num = 6, /* CLK_SRC6 register */ - .mux_shift = MUX_SPDIF_SHIFT, /* MUXspdif */ - .div_shift = NONE, -}; - -static Clk *onchip_clks[] = { - - /* non-ULPD clocks */ - &xtal_osc12m, - &xtal_osc27m, - &xtal_usb_osc48m, - &xtal_rtc_osc32k, - &sclk_hdmi27m, - &fin_pll, - - /* CLOCKS FROM CMU */ - &apll, - &mpll, - &epll, - &vpll, - &sclk_apll, - &sclk_mpll, - &sclk_epll, - &sclk_vpll, - &sclk_a2m, - &hclk133, - &pclk66, - &hclk166, - &pclk83, - &armclk, - &hclk200, - &pclk100, - &hclk100, - &sclk_pwm, - &sclk_audio_0, - &sclk_audio_1, - &sclk_audio_2, - &sclk_spdif, - - 0 -}; - -static void s5pc1xx_clk_reset(void *opaque) -{ - CmuStat *s = (CmuStat *)opaque; - - /* Set default values for registers */ - /* TODO: Add all the rest */ - s->clk_div[0] = 0x14131330; - s->clk_src[0] = 0x10001111; - s->clk_src[4] = 0x66666666; - s->clk_src[5] = 0x777; - s->clk_src[6] = 0x1000000; - - /* LOCKED bit is always set */ - s->conf_data[0] = 0xA0C80601 | (1 << 29); - s->conf_data[1] = 0xA29B0C01 | (1 << 29); - s->conf_data[2] = 0xA0600602 | (1 << 29); - s->conf_data[4] = 0xA06C0603 | (1 << 29); -} - -/* Find a clock by its name and return the clk structure */ -Clk *s5pc1xx_findclk(const char *name) -{ - Clk **i, *cur; - - for (i = onchip_clks; *i; i++) { - cur = *i; - if (!strcmp(cur->name, name) || - (cur->alias && !strcmp(cur->alias, name))) - return cur; - } - hw_error("%s: clock %s not found\n", __FUNCTION__, name); -} - -/* Get a frequency */ -int64_t s5pc1xx_clk_getrate(Clk *clk) -{ - return clk->rate; -} - -/* Update parents flow */ -static void s5pc1xx_clk_reparent(CmuStat *cmu_stat) -{ - Clk **i, *cur; - unsigned short parent_num; - - for (i = onchip_clks; *i; i++) { - cur = *i; - parent_num = 0; - - if (cur->mux_shift > NONE) - parent_num = - cmu_stat->clk_src[cur->src_reg_num] >> cur->mux_shift & 0xf; - cur->parent = cur->parents[parent_num]; - } -} - -/* Update clocks rates */ -static void s5pc1xx_clk_rate_update(CmuStat *cmu_stat) -{ - Clk **i, *cur; - - for (i = onchip_clks; *i; i++) { - cur = *i; - - cur->div_val = cur->div_val ?: 1; - cur->mult_val = cur->mult_val ?: 1; - - /* update all divisors using div_shift if any, - * divisors for (A,E,M,V)PLL are not updated here */ - if (cur->div_shift > NONE) - cur->div_val = - (cmu_stat->clk_div[cur->div_reg_num] >> cur->div_shift & 0xf) + 1; - - /* update frequencies for all the clocks except the oscillators */ - if (cur->parent) - cur->rate = muldiv64(cur->parent->rate, cur->mult_val, cur->div_val); - } -} - -/* Set a frequency */ -static void s5pc1xx_clk_setrate(CmuStat *cmu_stat, Clk *clk, - int divide, int multiply) -{ - clk->div_val = divide; - clk->mult_val = multiply; -} - -/* Set (A,M,E,V)PLL params after write operation */ -static void set_pll_conf(void *opaque, target_phys_addr_t offset, uint32_t val) -{ - CmuStat *s = (CmuStat *)opaque; - - /* Calculate control values depending on clock kind */ - switch ((offset - 0x100) >> 3) { - - case 0: - apll.enabled = (val >> 31) & 0x1; - /* include/exclude clock depending on .enabled value */ - if (apll.enabled) - s->clk_src[0] |= (1 << sclk_apll.mux_shift); - else - s->clk_src[0] &= ~(1 << sclk_apll.mux_shift); - - s5pc1xx_clk_setrate(s, &apll, - ((val >> 8) & 0x3F) << ((val & 0x7) - 1), - (val >> 16) & 0x3FF); - break; - - case 1: - mpll.enabled = (val >> 31) & 0x1; - if (mpll.enabled) - s->clk_src[0] |= (1 << sclk_mpll.mux_shift); - else - s->clk_src[0] &= ~(1 << sclk_mpll.mux_shift); - - s5pc1xx_clk_setrate(s, &mpll, - ((val >> 8) & 0x3F) << (val & 0x7), - (val >> 16) & 0x3FF); - break; - - case 2: - epll.enabled = (val >> 31) & 0x1; - if (epll.enabled) - s->clk_src[0] |= (1 << sclk_epll.mux_shift); - else - s->clk_src[0] &= ~(1 << sclk_epll.mux_shift); - - s5pc1xx_clk_setrate(s, &epll, - ((val >> 8) & 0x3F) << (val & 0x7), - (val >> 16) & 0x3FF); - break; - - case 4: - vpll.enabled = (val >> 31) & 0x1; - if (vpll.enabled) - s->clk_src[0] |= (1 << sclk_vpll.mux_shift); - else - s->clk_src[0] &= ~(1 << sclk_vpll.mux_shift); - - s5pc1xx_clk_setrate(s, &vpll, - ((val >> 8) & 0x3F) << (val & 0x7), - (val >> 16) & 0x3FF); - break; - - default: - hw_error("s5pc1xx.clk: bad pll offset 0x" TARGET_FMT_plx "\n", offset); - } -} - -static void s5pc1xx_clk_config(CmuStat *s) -{ - set_pll_conf(s, APLL_CON, s->conf_data[0]); - set_pll_conf(s, MPLL_CON, s->conf_data[1]); - set_pll_conf(s, EPLL_CON, s->conf_data[2]); - set_pll_conf(s, VPLL_CON, s->conf_data[4]); - - s5pc1xx_clk_reparent(s); - s5pc1xx_clk_rate_update(s); -} - -static uint32_t register_read(void *opaque, target_phys_addr_t offset) -{ - CmuStat *s = (CmuStat *)opaque; - - switch (offset) { - case 0x000 ... 0x020: - return s->lock_data[offset >> 3]; - case 0x100 ... 0x120: - return s->conf_data[(offset - 0x100) >> 3]; - case 0x200 ... 0x218: - return s->clk_src[(offset - 0x200) >> 2]; - case 0x280 ... 0x284: - return s->src_mask[(offset - 0x280) >> 2]; - case 0x300 ... 0x31C: - return s->clk_div[(offset - 0x300) >> 2]; - case 0x400 ... 0x488: - return s->clk_gate[(offset - 0x400) >> 2]; - case 0x500: - return s->clk_out; - case 0x1000: - case 0x1004: - return 0; - case 0x1100: - return - (1 << ((s->clk_src[0] >> ONENAND_SHIFT) & 0x1)) << ONENAND_SHIFT | - (1 << ((s->clk_src[0] >> MUX133_SHIFT) & 0x1)) << MUX133_SHIFT | - (1 << ((s->clk_src[0] >> MUX166_SHIFT) & 0x1)) << MUX166_SHIFT | - (1 << ((s->clk_src[0] >> MUX200_SHIFT) & 0x1)) << MUX200_SHIFT | - (1 << ((s->clk_src[0] >> VPLL_SHIFT) & 0x1)) << VPLL_SHIFT | - (1 << ((s->clk_src[0] >> EPLL_SHIFT) & 0x1)) << EPLL_SHIFT | - (1 << ((s->clk_src[0] >> MPLL_SHIFT) & 0x1)) << MPLL_SHIFT | - (1 << ((s->clk_src[0] >> APLL_SHIFT) & 0x1)) << APLL_SHIFT; - case 0x1104: - return - (1 << ((s->clk_src[6] >> MUX_HPM_SHIFT) & 0x1)) << MUX_HPM_SHIFT | - ((((s->clk_src[6] >> MUX_ONEDRAM_SHIFT) << 1) & 0x6) | - ((s->clk_src[6] >> MUX_ONEDRAM_SHIFT) & 0x1)) << 8 | - ((((s->clk_src[2] >> MFC_SHIFT) << 1) & 0x6) | - ((s->clk_src[2] >> MFC_SHIFT) & 0x1)) << MFC_SHIFT | - ((((s->clk_src[2] >> G3D_SHIFT) << 1) & 0x6) | - ((s->clk_src[2] >> G3D_SHIFT) & 0x1)) << G3D_SHIFT; - default: - hw_error("s5pc1xx.clk: bad read offset 0x" TARGET_FMT_plx "\n", offset); - return 0; - } -} - -static void register_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - CmuStat *s = (CmuStat *)opaque; - - switch (offset) { - case 0x000 ... 0x020: - s->lock_data[offset >> 3] = val; - break; - case 0x100 ... 0x120: - /* LOCKED bit is always set */ - s->conf_data[(offset - 0x100) >> 3] = val | (1 << 29); - - set_pll_conf(s, offset, val); - s5pc1xx_clk_reparent(s); - s5pc1xx_clk_rate_update(s); - - break; - case 0x200 ... 0x218: - s->clk_src[(offset - 0x200) >> 2] = val; - - /* clear reserved bits for security */ - s->clk_src[0] &= ALL_MUX_BITS_0; - s->clk_src[5] &= ALL_MUX_BITS_5; - - s5pc1xx_clk_reparent(s); - - break; - case 0x280 ... 0x284: - s->src_mask[(offset - 0x280) >> 2] = val; - break; - case 0x300 ... 0x31C: - s->clk_div[(offset - 0x300) >> 2] = val; - - /* clear reserved bits for security */ - s->clk_div[0] &= ALL_DIV_BITS_0; - s->clk_div[5] &= ALL_DIV_BITS_5; - - s5pc1xx_clk_rate_update(s); - - break; - case 0x400 ... 0x488: - s->clk_gate[(offset - 0x400) >> 2] = val; - break; - case 0x500: - s->clk_out = val; - break; - case 0x1000 ... 0x1004: - case 0x1100 ... 0x1104: - default: - hw_error("s5pc1xx.clk: bad write offset 0x" TARGET_FMT_plx "\n", offset); - } -} - -static CPUReadMemoryFunc * const register_readfn[] = { - register_read, - register_read, - register_read -}; - -static CPUWriteMemoryFunc * const register_writefn[] = { - register_write, - register_write, - register_write -}; - -static void s5pc1xx_clk_save(QEMUFile *f, void *opaque) -{ - CmuStat *s = (CmuStat *)opaque; - int i; - - qemu_put_be32s(f, &s->clk_out); - - for (i = 0; i < 23; i++) { - qemu_put_be32s(f, s->clk_gate + i); - if (i > 7) { - continue; - } - qemu_put_be32s(f, s->clk_div + i); - if (i > 6) { - continue; - } - qemu_put_be32s(f, s->clk_src + i); - if (i > 4) { - continue; - } - qemu_put_be32s(f, s->lock_data + i); - qemu_put_be32s(f, s->conf_data + i); - if (i > 1) { - continue; - } - qemu_put_be32s(f, s->src_mask + i); - qemu_put_be32s(f, s->div_stat + i); - qemu_put_be32s(f, s->mux_stat + i); - } -} - -static int s5pc1xx_clk_load(QEMUFile *f, void *opaque, int version_id) -{ - CmuStat *s = (CmuStat *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->clk_out); - - for (i = 0; i < 23; i++) { - qemu_get_be32s(f, s->clk_gate + i); - if (i > 7) { - continue; - } - qemu_get_be32s(f, s->clk_div + i); - if (i > 6) { - continue; - } - qemu_get_be32s(f, s->clk_src + i); - if (i > 4) { - continue; - } - qemu_get_be32s(f, s->lock_data + i); - qemu_get_be32s(f, s->conf_data + i); - if (i > 1) { - continue; - } - qemu_get_be32s(f, s->src_mask + i); - qemu_get_be32s(f, s->div_stat + i); - qemu_get_be32s(f, s->mux_stat + i); - } - s5pc1xx_clk_config(s); - return 0; -} - -/* Initialize clock */ -static int s5pc1xx_clk_init(SysBusDevice *dev) -{ - CmuStat *s = FROM_SYSBUS(CmuStat, dev); - int iomemtype; - - s5pc1xx_clk_reset(s); - s5pc1xx_clk_config(s); - - /* memory mapping */ - iomemtype = cpu_register_io_memory(register_readfn, register_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_CLK_REG_MEM_SIZE, iomemtype); - - qemu_register_reset(s5pc1xx_clk_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.clk", -1, 1, - s5pc1xx_clk_save, s5pc1xx_clk_load, s); - return 0; -} - -static void s5pc1xx_clk_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.clk", sizeof(CmuStat), s5pc1xx_clk_init); -} - -device_init(s5pc1xx_clk_register_devices) diff --git a/hw/s5pc1xx_debug.c b/hw/s5pc1xx_debug.c deleted file mode 100644 index 334f1fb..0000000 --- a/hw/s5pc1xx_debug.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * S5PC110 Test & Debug - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - */ - -/* Print all system information to stderr */ -static __attribute__((unused)) void debug_sysinfo(const struct s5pc1xx_state_s *s) -{ - fprintf(stderr, "CPU: %s\n", s->env->cpu_model_str); - fprintf(stderr, "SDRAM: %lu MB\n", s->sdram_size / (1024 * 1024)); - fprintf(stderr, "SRAM: %lu KB\n", s->isram_size / 1024); - fprintf(stderr, "SROM: %lu KB\n", s->isrom_size / 1024); -} - - -/* Interrupt Controller */ - -#define ADDR 0xF2000F00 - - -target_phys_addr_t vic_base[] = { - S5PC1XX_VIC0_BASE, S5PC1XX_VIC1_BASE, S5PC1XX_VIC2_BASE, S5PC1XX_VIC3_BASE -}; - -typedef enum { - enable, disable, swint, swclear, select_irq, selclear, priomask, daisyprio -} irq_op; - - -static __attribute__((unused)) void test_irq_handler(void *opaque, int irq, - int level) -{ - const char *name; - - if (irq) - name = "FIQ"; - else - name = "IRQ"; - - if (level) - fprintf(stderr, "%s was raised\n", name); -} - -static __attribute__((unused)) qemu_irq *test_irq_init(void) -{ - return qemu_allocate_irqs(test_irq_handler, NULL, 2); -} - -static __attribute__((unused)) uint32_t test_irq_op(irq_op op, int irq, - int is_wr, uint32_t val) -{ - int vic_id = irq / S5PC1XX_VIC_SIZE; - uint32_t res; - target_phys_addr_t base = vic_base[vic_id]; - target_phys_addr_t off; - - switch (op) { - case enable: - off = 0x10; - break; - case disable: - off = 0x14; - break; - case swint: - off = 0x18; - break; - case swclear: - off = 0x1C; - break; - case select_irq: - case selclear: - off = 0xC; - break; - case priomask: - off = 0x24; - break; - case daisyprio: - off = 0x28; - break; - default: - off = 0x0; - break; - } - if (op == priomask || op == daisyprio || !is_wr) { - if (is_wr) { - cpu_physical_memory_write(base + off, (uint8_t *)&val, 4); - } else { - cpu_physical_memory_read(base + off, (uint8_t *)&res, 4); - } - return res; - } - if (op == select_irq || op == selclear) - cpu_physical_memory_read(base + off, (uint8_t *)&res, 4); - if (op == select_irq) - res |= 1 << (irq % S5PC1XX_VIC_SIZE); - else if (op == selclear) - res &= ~(1 << (irq % S5PC1XX_VIC_SIZE)); - else - res = 1 << (irq % S5PC1XX_VIC_SIZE); - cpu_physical_memory_write(base + off, (uint8_t *)&res, 4); - return 0; -} - -static __attribute__((unused)) void test_irq_script(struct s5pc1xx_state_s *s) -{ - uint32_t res; - - fprintf(stderr,"Step 1: Interrupts disabled. Raising and lowering them.\n"); - qemu_irq_raise(s5pc1xx_get_irq(s, 14)); - qemu_irq_raise(s5pc1xx_get_irq(s, 33)); - qemu_irq_lower(s5pc1xx_get_irq(s, 14)); - qemu_irq_lower(s5pc1xx_get_irq(s, 33)); - qemu_irq_raise(s5pc1xx_get_irq(s, 69)); - qemu_irq_lower(s5pc1xx_get_irq(s, 69)); - qemu_irq_raise(s5pc1xx_get_irq(s, 101)); - - fprintf(stderr, "Step 2: Interrupt 101 is raised. Enable some other.\n"); - test_irq_op(enable, 4, 1, 0); - test_irq_op(enable, 34, 1, 0); - test_irq_op(enable, 5, 1, 0); - - fprintf(stderr, "Step 3: Interrupt 101 is raised. Enable it.\n"); - res = 0xDDEEAABB; - cpu_physical_memory_write(0xF2300114, (const uint8_t *)&res, 4); - test_irq_op(enable, 101, 1, 0); - cpu_physical_memory_read(ADDR, (uint8_t *)&res, 4); - fprintf(stderr, "Interrupt 101 vector is %x\n", res); - qemu_irq_raise(s5pc1xx_get_irq(s, 5)); - fprintf(stderr, "Step 4: Interrupt 101 has been acknoledged. " - "Interrupt 5 has been raised.\n"); - - fprintf(stderr, "Step 5: Generate IRQ 4 with higher priority.\n"); - res = 0xa; - cpu_physical_memory_write(0xF2000210, (const uint8_t *)&res, 4); - res = 0xDDEEBBAA; - cpu_physical_memory_write(0xF2000110, (const uint8_t *)&res, 4); - qemu_irq_raise(s5pc1xx_get_irq(s, 4)); - - fprintf(stderr, "Step 6: Acknoledge IRQ 4. Then lower it.\n"); - cpu_physical_memory_read(ADDR, (uint8_t *)&res, 4); - fprintf(stderr, "Interrupt 4 vector is %x\n", res); - qemu_irq_lower(s5pc1xx_get_irq(s, 4)); - - fprintf(stderr, "Step 7: Finalize IRQ 4 processing. No new interrupts " - "should appear as IRQ 101 is in progress.\n"); - cpu_physical_memory_write(ADDR, (const uint8_t *)&res, 4); - - fprintf(stderr, "Step 8: Mask IRQ 4's priority, then raise it again.\n"); - test_irq_op(priomask, 0, 1, 0xffff & ~(1 << 0xa)); - qemu_irq_raise(s5pc1xx_get_irq(s, 4)); - - fprintf(stderr, "Step 9: Finalize IRQ 101 processing. " - "We should recive IRQ 5.\n"); - res = 0xDDEEBBCC; - cpu_physical_memory_write(0xF2000114, (const uint8_t *)&res, 4); - qemu_irq_lower(s5pc1xx_get_irq(s, 101)); - cpu_physical_memory_write(ADDR, (const uint8_t *)&res, 4); - cpu_physical_memory_read(ADDR, (uint8_t *)&res, 4); - fprintf(stderr, "Interrupt 5 vector is %x\n", res); - - fprintf(stderr, "Step 10: Finalize IRQs. Clear them all.\n"); - qemu_irq_lower(s5pc1xx_get_irq(s, 5)); - qemu_irq_lower(s5pc1xx_get_irq(s, 4)); - cpu_physical_memory_write(ADDR, (const uint8_t *)&res, 4); -} - - -/* DMA */ - -#define DATA_ADDR 0x20010000 -#define RESULT_ADDR 0x20020000 -#define PROG_ADDR 0x20030000 - -#define DBGGO_ADDR 0xFA200D04 -#define DBG0_ADDR 0xFA200D08 -#define DBG1_ADDR 0xFA200D0C - -#define FSC_ADDR 0xFA200034 -#define FTC1_ADDR 0xFA200044 -#define CPC1_ADDR 0xFA20010C - - -uint32_t dbg0 = 0x01A00000; -uint32_t dbg1 = PROG_ADDR; -uint32_t dbggo = 0x0; -uint32_t dbgkill = 0x00010101; - -static const uint8_t dma_data[] = { - 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 -}; - -static const uint8_t dma_stz[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x35, 0x40, 0x0D, 0x00, /* DMAMOV CCR SAI SS4 SB4 DAI DS4 DB4 */ - 0x0C, /* DMASTZ */ - 0x00 /* DMAEND */ -}; - -static const uint8_t dma_stzlp[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x35, 0x40, 0x0D, 0x00, /* DMAMOV CCR SAI SS4 SB4 DAI DS4 DB4 */ - 0x20, 0x01, /* DMALP 2 */ - 0x0C, /* DMASTZ */ - 0x38, 0x01, /* DMALPEND */ - 0x00 /* DMAEND */ -}; - -static const uint8_t dma_copy[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x35, 0x40, 0x0D, 0x00, /* DMAMOV CCR SAI SS4 SB4 DAI DS4 DB4 */ - 0x20, 0x01, /* DMALP 2 */ - 0x04, /* DMALD */ - 0x08, /* DMAST */ - 0x38, 0x02, /* DMALPEND */ - 0x00 /* DMAEND */ -}; - -/* Paradoxically but this should work correctly too. */ -static const uint8_t dma_copy_2[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x35, 0x40, 0x0D, 0x00, /* DMAMOV CCR SAI SS4 SB4 DAI DS4 DB4 */ - 0x20, 0x01, /* DMALP 2 */ - 0x08, /* DMAST */ - 0x04, /* DMALD */ - 0x38, 0x02, /* DMALPEND */ - 0x00 /* DMAEND */ -}; - -static const uint8_t dma_scatter[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x34, 0x40, 0x0D, 0x00, /* DMAMOV CCR SAF SS4 SB4 DAI DS4 DB4 */ - 0x20, 0x01, /* DMALP 2 */ - 0x04, /* DMALD */ - 0x08, /* DMAST */ - 0x38, 0x02, /* DMALPEND */ - 0x00 /* DMAEND */ -}; - -static const uint8_t dma_gather[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x35, 0x00, 0x0D, 0x00, /* DMAMOV CCR SAI SS4 SB4 DAF DS4 DB4 */ - 0x20, 0x01, /* DMALP 2 */ - 0x04, /* DMALD */ - 0x08, /* DMAST */ - 0x38, 0x02, /* DMALPEND */ - 0x00 /* DMAEND */ -}; - -/* Watchdog abort at DMAEND */ -static const uint8_t dma_nold[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x34, 0x00, 0x0D, 0x00, /* DMAMOV CCR SAF SS4 SB4 DAF DS4 DB4 */ - 0x08, /* DMAST */ - 0x18, /* DMANOP */ - 0x00 /* DMAEND */ -}; - -/* Watchdog abort at DMAEND */ -static const uint8_t dma_nost[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x34, 0x00, 0x0D, 0x00, /* DMAMOV CCR SAF SS4 SB4 DAF DS4 DB4 */ - 0x04, /* DMALD */ - 0x18, /* DMANOP */ - 0x00 /* DMAEND */ -}; - -/* Watchdog abort at DMALD */ -static const uint8_t dma_ldfe[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x34, 0x00, 0x0D, 0x00, /* DMAMOV CCR SAF SS4 SB4 DAF DS4 DB4 */ - /* DMALPFE */ - 0x04, /* DMALD */ - 0x28, 0x01, /* DMALPEND */ - 0x00 /* DMAEND */ -}; - -/* Watchdog abort at DMAST */ -static const uint8_t dma_stfe[] = { - 0xBC, 0x00, 0x00, 0x00, 0x01, 0x20, /* DMAMOV SAR 0x20010000 */ - 0xBC, 0x02, 0x00, 0x00, 0x02, 0x20, /* DMAMOV DAR 0x20020000 */ - 0xBC, 0x01, 0x34, 0x00, 0x0D, 0x00, /* DMAMOV CCR SAF SS4 SB4 DAF DS4 DB4 */ - /* DMALPFE */ - 0x08, /* DMAST */ - 0x28, 0x01, /* DMALPEND */ - 0x00 /* DMAEND */ -}; - - -static inline void dma_exec_dbg(const uint8_t *prog, int size) -{ - cpu_physical_memory_write(PROG_ADDR, prog, size); - cpu_physical_memory_write(DBG0_ADDR, (uint8_t *)&dbg0, 4); - cpu_physical_memory_write(DBG1_ADDR, (uint8_t *)&dbg1, 4); - cpu_physical_memory_write(DBGGO_ADDR, (uint8_t *)&dbggo, 4); -} - -static inline void dma_kill_dbg(void) -{ - uint32_t zeroval = 0x0; - - cpu_physical_memory_write(DBG0_ADDR, (uint8_t *)&dbgkill, 4); - cpu_physical_memory_write(DBG1_ADDR, (uint8_t *)&zeroval, 4); - cpu_physical_memory_write(DBGGO_ADDR, (uint8_t *)&dbggo, 4); -} - -static __attribute__((unused)) void test_dma_script(struct s5pc1xx_state_s *s) -{ - uint8_t res[32]; - uint32_t reg; - int outcome; - int i; - - cpu_physical_memory_write(DATA_ADDR, dma_data, 32); - - /* TEST 1 */ - cpu_physical_memory_write(RESULT_ADDR, dma_data, 32); - dma_exec_dbg(dma_stz, 20); - outcome = 0; - cpu_physical_memory_read(RESULT_ADDR, res, 16); - for (i = 0; i < 16; i++) { - if (res[i] != 0) { - outcome = 1; - } - } - if (outcome) { - fprintf(stderr, "DMA test 1: DMASTZ. FAILED\n"); - } else { - fprintf(stderr, "DMA test 1: DMASTZ. OK\n"); - } - - /* TEST 2 */ - cpu_physical_memory_write(RESULT_ADDR, dma_data, 32); - dma_exec_dbg(dma_stzlp, 24); - outcome = 0; - cpu_physical_memory_read(RESULT_ADDR, res, 32); - for (i = 0; i < 32; i++) { - if (res[i] != 0) { - outcome = 1; - } - } - if (outcome) { - fprintf(stderr, "DMA test 2: DMASTZ in loop. FAILED\n"); - } else { - fprintf(stderr, "DMA test 2: DMASTZ in loop. OK\n"); - } - - /* TEST 3 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_copy, 25); - outcome = 0; - cpu_physical_memory_read(RESULT_ADDR, res, 32); - for (i = 0; i < 32; i++) { - if (res[i] != dma_data[i]) { - outcome = 1; - } - } - if (outcome) { - fprintf(stderr, "DMA test 3: DMA copy of 32 bytes of data. FAILED\n"); - } else { - fprintf(stderr, "DMA test 3: DMA copy of 32 bytes of data. OK\n"); - } - - /* TEST 4 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_copy_2, 25); - outcome = 0; - cpu_physical_memory_read(RESULT_ADDR, res, 32); - for (i = 0; i < 32; i++) { - if (res[i] != dma_data[i]) { - outcome = 1; - } - } - if (outcome) { - fprintf(stderr, "DMA test 4: DMA copy of 32 bytes of data (store before load). FAILED\n"); - } else { - fprintf(stderr, "DMA test 4: DMA copy of 32 bytes of data (store before load). OK\n"); - } - - /* TEST 5 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_scatter, 25); - outcome = 0; - cpu_physical_memory_read(RESULT_ADDR, res, 32); - for (i = 0; i < 32; i++) { - if (res[i] != dma_data[i % 4]) { - outcome = 1; - } - } - if (outcome) { - fprintf(stderr, "DMA test 5: DMA scatter. FAILED\n"); - } else { - fprintf(stderr, "DMA test 5: DMA scatter. OK\n"); - } - - /* TEST 6 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_gather, 25); - outcome = 0; - cpu_physical_memory_read(RESULT_ADDR, res, 32); - for (i = 0; i < 32; i++) { - if (res[i] != ((i > 3) ? 0 : dma_data[28 + i])) { - outcome = 1; - } - } - if (outcome) { - fprintf(stderr, "DMA test 6: DMA gather. FAILED\n"); - } else { - fprintf(stderr, "DMA test 6: DMA gather. OK\n"); - } - - /* TEST 7 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_nost, 21); - outcome = 0; - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (! (reg & 2)) { - outcome = 1; - } - cpu_physical_memory_read(FTC1_ADDR, (uint8_t *)®, 4); - if (reg != ((unsigned)1 << 31)) { - outcome = 1; - } - cpu_physical_memory_read(CPC1_ADDR, (uint8_t *)®, 4); - if (reg != PROG_ADDR + 20) { - outcome = 1; - } - dma_kill_dbg(); - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (reg & 2) { - outcome = 1; - } - if (outcome) { - fprintf(stderr, "DMA test 7: DMALD without DMAST. FAILED\n"); - } else { - fprintf(stderr, "DMA test 7: DMALD without DMAST. OK\n"); - } - - /* TEST 8 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_nold, 21); - outcome = 0; - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (! (reg & 2)) { - outcome = 1; - } - cpu_physical_memory_read(FTC1_ADDR, (uint8_t *)®, 4); - if (reg != ((unsigned)1 << 31)) { - outcome = 1; - } - cpu_physical_memory_read(CPC1_ADDR, (uint8_t *)®, 4); - if (reg != PROG_ADDR + 20) { - outcome = 1; - } - dma_kill_dbg(); - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (reg & 2) { - outcome = 1; - } - if (outcome) { - fprintf(stderr, "DMA test 8: DMAST without DMALD. FAILED\n"); - } else { - fprintf(stderr, "DMA test 8: DMAST without DMALD. OK\n"); - } - - /* TEST 9 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_ldfe, 22); - outcome = 0; - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (! (reg & 2)) { - outcome = 1; - } - cpu_physical_memory_read(FTC1_ADDR, (uint8_t *)®, 4); - if (reg != ((unsigned)1 << 31)) { - outcome = 1; - } - cpu_physical_memory_read(CPC1_ADDR, (uint8_t *)®, 4); - if (reg != PROG_ADDR + 18) { - outcome = 1; - } - dma_kill_dbg(); - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (reg & 2) { - outcome = 1; - } - if (outcome) { - fprintf(stderr, "DMA test 9: DMALD in infinite loop. FAILED\n"); - } else { - fprintf(stderr, "DMA test 9: DMALD in infinite loop. OK\n"); - } - - /* TEST 10 */ - dma_exec_dbg(dma_stzlp, 24); - dma_exec_dbg(dma_stfe, 22); - outcome = 0; - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (! (reg & 2)) { - outcome = 1; - } - cpu_physical_memory_read(FTC1_ADDR, (uint8_t *)®, 4); - if (reg != ((unsigned)1 << 31)) { - outcome = 1; - } - cpu_physical_memory_read(CPC1_ADDR, (uint8_t *)®, 4); - if (reg != PROG_ADDR + 18) { - outcome = 1; - } - dma_kill_dbg(); - cpu_physical_memory_read(FSC_ADDR, (uint8_t *)®, 4); - if (reg & 2) { - outcome = 1; - } - if (outcome) { - fprintf(stderr, "DMA test 10: DMAST in infinite loop. FAILED\n"); - } else { - fprintf(stderr, "DMA test 10: DMAST in infinite loop. OK\n"); - } -} - - -/* UART */ - -#define TRSTATUS_ADDR 0xE2900810 -#define FIFOCTL_ADDR 0xE2900808 -#define TRANSMIT_ADDR 0xE2900820 -#define RECIVE_ADDR 0xE2900824 - - -static const char *hello = "Hello world!\n"; -static char buf[256]; - - -static __attribute__((unused)) void test_uart_script(void) -{ - uint32_t res; - char *s; - int i; - - res = 1; - cpu_physical_memory_write(FIFOCTL_ADDR, (uint8_t *)&res, 4); - cpu_physical_memory_read(TRSTATUS_ADDR, (uint8_t *)&res, 4); - if (! (res & 4)) { - fprintf(stderr, "Error: UART2 transmitter is not ready!\n"); - } - s = (char *)hello; - while (*s) { - cpu_physical_memory_write(TRANSMIT_ADDR, (uint8_t *)s, 1); - s++; - } - sleep(10); - s = buf; - i = 0; - while (1) { - cpu_physical_memory_read(TRSTATUS_ADDR, (uint8_t *)&res, 4); - if (! (res & 1)) { - break; - } - if (i >= 255) { - fprintf(stderr, "Error: UART2 too many input data!\n"); - break; - } - cpu_physical_memory_read(RECIVE_ADDR, (uint8_t *)s, 1); - s++; - } - *s = '\0'; - fprintf (stderr, "Read data: %s\n", s); -} - diff --git a/hw/s5pc1xx_gpio.c b/hw/s5pc1xx_gpio.c deleted file mode 100644 index 6748024..0000000 --- a/hw/s5pc1xx_gpio.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * GPIO controller for S5PC110-based board emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "s5pc1xx.h" -#include "sysbus.h" -#include "s5pc1xx_gpio_regs.h" - - -#define GPIO_CONF_CASE 6 -#define GPIO_PIN_CONF(s, group, pin) (((s)->con[(group)] >> ((pin) * 4)) & 0xF) -#define S5PC1XX_GPIO_REG_MEM_SIZE 0xF84 - - -typedef struct S5pc1xxGPIOState { - SysBusDevice busdev; - - /* Port Registers */ - uint32_t con[GPH3 + 1]; - - /* Interrupt GPIO Registers - * GPI has no interrupts so corresponding field is not used */ - uint32_t int_con[GPJ4 + 1]; - uint32_t int_fltcon[GPJ4 + 1][2]; - uint32_t int_mask[GPJ4 + 1]; - uint32_t int_pend[GPJ4 + 1]; - uint32_t int_fixpri[GPJ4 + 1]; - - uint32_t int_grppri; - uint32_t int_priority; - uint32_t int_ser; - uint32_t int_ser_pend; - uint32_t int_grpfixpri; - - /* Extended Interrupt Registers */ - uint32_t ext_int_mask[4]; - uint32_t ext_int_pend[4]; - - /* Parent Interrupt for GPIO interrupts */ - qemu_irq gpioint; - /* Parent Extended Interrupt */ - qemu_irq extend; -} S5pc1xxGPIOState; - - -int s5pc1xx_gpio_case[GPH3 + 1][8][7] = { - -/* GPA0 */ {{GPIO_UART_RXD(0)}, {GPIO_UART_TXD(0)}, {GPIO_UART_CTS(0)}, {GPIO_UART_RTS(0)}, - {GPIO_UART_RXD(1)}, {GPIO_UART_TXD(1)}, {GPIO_UART_CTS(1)}, {GPIO_UART_RTS(1)}}, - -/* GPA1 */ {{GPIO_UART_RXD(2), 0, GPIO_UART_AUDIO_RXD}, {GPIO_UART_TXD(2), 0, GPIO_UART_AUDIO_TXD}, - {GPIO_UART_RXD(3), 0, GPIO_UART_CTS(2)}, {GPIO_UART_TXD(3), 0, GPIO_UART_RTS(2)}}, -/* not - * covered */ {}, - -/* GPC0 */ {{0, PCM_SCLK(1), GPIO_AC97BITCLK}, {0, PCM_EXTCLK(1), GPIO_AC97RESETn}, {0, PCM_FSYNC(1), GPIO_AC97SYNC}, - {0, PCM_SIN(1), GPIO_AC97SDI}, {0, PCM_SOUT(1), GPIO_AC97SDO}}, - -/* GPC1 */ {{PCM_SCLK(0), SPDIF_0_OUT}, {PCM_EXTCLK(0), SPDIF_EXTCLK}, - {PCM_FSYNC(0), LCD_FRM}, {PCM_SIN(0)}, {PCM_SOUT(0)}}, - -/* GPD0 */ {{GPIO_PWM_TOUT(0)}, {GPIO_PWM_TOUT(1)}, {GPIO_PWM_TOUT(2)}, {GPIO_PWM_TOUT(3), PWM_MIE_MDNI}}, - -/* not - * covered */ {}, {}, {}, - -/* GPF0 */ {{LCD_HSYNC}, {LCD_VSYNC}, {LCD_VDEN}, {LCD_VCLK}, - {LCD_VD(0)}, {LCD_VD(1)}, {LCD_VD(2)}, {LCD_VD(3)}}, - -/* GPF1 */ {{LCD_VD(4)}, {LCD_VD(5)}, {LCD_VD(6)}, {LCD_VD(7)}, - {LCD_VD(8)}, {LCD_VD(9)}, {LCD_VD(10)}, {LCD_VD(11)}}, - -/* GPF2 */ {{LCD_VD(12)}, {LCD_VD(13)}, {LCD_VD(14)}, {LCD_VD(15)}, - {LCD_VD(16)}, {LCD_VD(17)}, {LCD_VD(18)}, {LCD_VD(19)}}, - -/* GPF3 */ {{LCD_VD(20)}, {LCD_VD(21)}, {LCD_VD(22)}, {LCD_VD(23)}}, - -/* not - * covered */ {}, {}, {}, {}, - -/* GPI */ {{0, PCM_SCLK(2)}, {0, PCM_EXTCLK(2)}, {0, PCM_FSYNC(2)}, {0, PCM_SIN(2)}, {0, PCM_SOUT(2)}}, - -/* not - * covered */ {}, - -/* GPJ1 */ {{}, {}, {}, {}, {0, GPIO_KP_COL(0)}}, - -/* GPJ2 */ {{0, GPIO_KP_COL(1)}, {0, GPIO_KP_COL(2)}, {0, GPIO_KP_COL(3)}, {0, GPIO_KP_COL(4)}, - {0, GPIO_KP_COL(5)}, {0, GPIO_KP_COL(6)}, {0, GPIO_KP_COL(7)}, {0, GPIO_KP_ROW(0)}}, - -/* GPJ3 */ {{0, GPIO_KP_ROW(1), 0, 0, GPIO_I2C_SDA(10), 0, GPIO_I2C_SDA(10)}, - {0, GPIO_KP_ROW(2), 0, 0, GPIO_I2C_SCL(10), 0, GPIO_I2C_SCL(10)}, - {0, GPIO_KP_ROW(3)}, - {0, GPIO_KP_ROW(4)}, {0, GPIO_KP_ROW(5)}, {0, GPIO_KP_ROW(6)}, - {0, GPIO_KP_ROW(7), 0, 0, GPIO_I2C_SDA(3), 0, GPIO_I2C_SDA(3)}, - {0, GPIO_KP_ROW(8), 0, 0, GPIO_I2C_SCL(3), 0, GPIO_I2C_SCL(3)}}, - -/* GPJ4 */ {{0, GPIO_KP_ROW(9), 0, 0, GPIO_I2C_SDA(4), 0, GPIO_I2C_SDA(4)}, - {0, GPIO_KP_ROW(10)}, {0, GPIO_KP_ROW(11)}, - {0, GPIO_KP_ROW(12), 0, 0, GPIO_I2C_SCL(4), 0, GPIO_I2C_SCL(4)}, - {0, GPIO_KP_ROW(13)}}, -/* not - * covered */ {}, {}, {}, {}, - -/* MP0_5 */ {{}, {}, {0, 0, 0, 0, GPIO_I2C_SCL(5), 0, GPIO_I2C_SCL(5)}, {0, 0, 0, 0, GPIO_I2C_SDA(5), 0, GPIO_I2C_SDA(5)}, - {}, {}, {}, {}}, -/* not -* covered */ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - -/* GPH2 */ {{0, GPIO_KP_COL(0)}, {0, GPIO_KP_COL(1)}, {0, GPIO_KP_COL(2)}, {0, GPIO_KP_COL(3)}, - {0, GPIO_KP_COL(4)}, {0, GPIO_KP_COL(5)}, {0, GPIO_KP_COL(6)}, {0, GPIO_KP_COL(7)}}, - -/* GPH3 */ {{0, GPIO_KP_ROW(0)}, {0, GPIO_KP_ROW(1)}, {0, GPIO_KP_ROW(2)}, {0, GPIO_KP_ROW(3)}, - {0, GPIO_KP_ROW(4)}, {0, GPIO_KP_ROW(5)}, {0, GPIO_KP_ROW(6)}, {0, GPIO_KP_ROW(7)}}, -}; - - -/* IO Memory Support */ - -GPIOWriteMemoryFunc *gpio_io_mem_write[GPIO_IDX_MAX]; -GPIOReadMemoryFunc *gpio_io_mem_read[GPIO_IDX_MAX]; -GPIOWriteMemoryFunc *gpio_io_mem_conf[GPIO_IDX_MAX] = {NULL}; -void *gpio_io_mem_opaque[GPIO_IDX_MAX][8]; - - -void s5pc1xx_gpio_register_io_memory(int io_index, int instance, - GPIOReadMemoryFunc *mem_read, - GPIOWriteMemoryFunc *mem_write, - GPIOWriteMemoryFunc *mem_conf, - void *opaque) -{ - gpio_io_mem_read[io_index] = mem_read; - gpio_io_mem_write[io_index] = mem_write; - gpio_io_mem_conf[io_index] = mem_conf; - gpio_io_mem_opaque[io_index][instance] = opaque; -} - -uint32_t s5pc1xx_empty_gpio_read(void *opaque, int io_index) -{ - return 0; -} - -void s5pc1xx_empty_gpio_write(void *opaque, int io_index, uint32_t value) -{ -} - -/* Empty read and write functions references are used as plugs - * for the elements gpio_io_mem_read[0] and gpio_io_mem_write[0] */ -static GPIOReadMemoryFunc *s5pc1xx_empty_gpio_readfn = s5pc1xx_empty_gpio_read; -static GPIOWriteMemoryFunc *s5pc1xx_empty_gpio_writefn = s5pc1xx_empty_gpio_write; - - -/* GPIO General Logic */ - -/* GPIO Reset Function */ -static void s5pc1xx_gpio_reset(void *opaque) -{ - S5pc1xxGPIOState *s = (S5pc1xxGPIOState *)opaque; - unsigned int group; - - /* Note: no groups from ETC2 (50) till GPH0 (96) */ - for (group = GPA0; - group <= GPH3; - group = (group == ETC2) ? GPH0 : group + 1) { - s->con[group] = 0x0; - } - - for (group = 0; group < 4; group++) { - s->ext_int_mask[group] = 0xFF; - s->ext_int_pend[group] = 0x0; - } - - for (group = GPA0; group <= GPJ4; group++) { - s->int_con[group] = 0x0; - s->int_fltcon[group][0] = 0x0; - s->int_fltcon[group][1] = 0x0; - s->int_mask[group] = 0xFF; /* other values in documentation */ - s->int_pend[group] = 0x0; - s->int_fixpri[group] = 0x0; - } - - s->int_grppri = 0x0; - s->int_priority = 0x0; - s->int_ser = 0x0; - s->int_ser_pend = 0x0; - s->int_grpfixpri = 0x0; -} - -static void s5pc1xx_gpio_irq_lower(S5pc1xxGPIOState *s, - unsigned int group, uint32_t pinmask) -{ - unsigned int i = 0; - s->int_pend[group] &= ~pinmask; - for (i = GPA0; i <= GPJ4; i++) { - if (s->int_pend[i]) { - return; - } - } - - qemu_irq_lower(s->gpioint); -} - -static void s5pc1xx_gpio_extended_irq_lower(S5pc1xxGPIOState *s, - unsigned int group, uint32_t pinmask) -{ - unsigned int i = 0; - s->ext_int_pend[group] &= ~pinmask; - for (i = 0; i < 4; i++) - if (s->ext_int_pend[i]) - return; - - qemu_irq_lower(s->extend); -} - -static void s5pc1xx_gpio_irq_handler(void *opaque, int irq, int level) -{ - S5pc1xxGPIOState *s = (S5pc1xxGPIOState *)opaque; - unsigned int group = GPIOINT_GROUP(irq); - unsigned int pin = GPIOINT_PIN (irq); - - /* Special case of extended IRQs */ - if (irq < IRQ_EXTEND_NUM) { - group = irq >> 3; - pin = irq & 0x7; - - /* FIXME: IRQs 0~15 are not supported */ - if (irq < 16) - hw_error("s5pc1xx.gpio: " - "extended IRQs 0-15 through GPIO are not supported"); - - if (s->ext_int_mask[group] & (1 << pin)) - return; - - if (s->ext_int_pend[group] & (1 << pin)) - return; - - if (level) { - s->ext_int_pend[group] |= (1 << pin); - qemu_irq_raise(s->extend); - } else { - s5pc1xx_gpio_extended_irq_lower(s, group, (1 << pin)); - } - - return; - } - - if (GPIO_PIN_CONF(s, group, pin) != GIPIO_CONF_INT) - return; - - if (s->int_mask[group] & (1 << pin)) - return; - - /* if the interrupt has already happened */ - if (s->int_pend[group] & (1 << pin)) - return; - - if (level) { - s->int_pend[group] |= (1 << pin); - qemu_irq_raise(s->gpioint); - } else { - s5pc1xx_gpio_irq_lower(s, group, (1 << pin)); - } -} - -/* GPIO Read Function */ -static uint32_t s5pc1xx_gpio_read(void *opaque, - target_phys_addr_t offset) -{ - S5pc1xxGPIOState *s = (S5pc1xxGPIOState *)opaque; - uint32_t value = 0, ret_val; - int index, device, instance, io_index; - unsigned int group, pin, n; - int gpio_case; - - group = offset / STEP; - - if ((group <= ETC2) || ((group >= GPH0) && (group <= GPH3))) { - - if (offset % STEP == 0x00) - return s->con[group]; - - if (offset % STEP == 0x04) { - ret_val = 0; - - for (pin = 0; pin < 8; pin++) { - index = (s->con[group] >> pin * 4) & 0xF; - switch (index) { - case 0x1: - /* Input port can't be read */ - break; - case 0x0: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - gpio_case = s5pc1xx_gpio_case[group][pin][CASE(index)]; - if (gpio_case) { - device = gpio_case >> 11 & 0x1F; - instance = gpio_case >> 6 & 0x1F; - io_index = gpio_case >> 0 & 0x3F; - - if (!(gpio_io_mem_read[device])) - device = 0; - - value = (gpio_io_mem_read[device]) - (gpio_io_mem_opaque[device][instance], - io_index); - } - break; - case 0xF: - /* TODO: implement this case */ - break; - default: - hw_error("s5pc1xx.gpio: " - "bad pin configuration index 0x%X\n", index); - } - ret_val |= (value & 0x1) << pin; - } - return ret_val; - } - } - - if (offset >= INT_CON_BASE && offset < INT_CON_BASE + INT_REGS_SIZE) - return s->int_con[GET_GROUP_INT_CON(offset)]; - - if (offset >= INT_FLTCON_BASE && - offset < INT_FLTCON_BASE + INT_REGS_SIZE * 2) - return s->int_fltcon[GET_GROUP_INT_FLTCON(offset)] - [(offset & 0x4) >> 2]; - - if (offset >= INT_MASK_BASE && offset < INT_MASK_BASE + INT_REGS_SIZE) - return s->int_mask[GET_GROUP_INT_MASK(offset)]; - - if (offset >= INT_PEND_BASE && offset < INT_PEND_BASE + INT_REGS_SIZE) - return s->int_pend[GET_GROUP_INT_PEND(offset)]; - - if (offset >= INT_FIXPRI_BASE && offset < INT_FIXPRI_BASE + INT_REGS_SIZE) - return s->int_fixpri[GET_GROUP_INT_FIXPRI(offset)]; - - switch (offset) { - case GPIO_INT_GRPPRI: - return s->int_grppri; - case GPIO_INT_PRIORITY: - return s->int_priority; - case GPIO_INT_SER: - return s->int_ser; - case GPIO_INT_SER_PEND: - return s->int_ser_pend; - case GPIO_INT_GRPFIXPRI: - return s->int_grpfixpri; - } - - for (n = 0; n < 4; n++) { - /* EINT Mask Register */ - if (offset == EXT_INT_MASK(n)) - return s->ext_int_mask[n]; - /* EINT Pend Register */ - if (offset == EXT_INT_PEND(n)) - return s->ext_int_pend[n]; - } - - return 0; -} - -/* GPIO Write Function */ -static void s5pc1xx_gpio_write(void *opaque, - target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxGPIOState *s = (S5pc1xxGPIOState *)opaque; - int index, device, instance, io_index; - unsigned int group, pin, n; - int gpio_case; - - group = offset / STEP; - - if ((group <= ETC2) || ((group >= GPH0) && (group <= GPH3))) { - - if (offset % STEP == 0x00) { - for (pin = 0; pin < 8; pin++) { - int new_con = (value >> pin * 4) & 0xF; - - gpio_case = s5pc1xx_gpio_case[group][pin][GPIO_CONF_CASE]; - if (gpio_case) { - device = gpio_case >> 11 & 0x1F; - instance = gpio_case >> 6 & 0x1F; - io_index = gpio_case >> 0 & 0x3F; - - if (!(gpio_io_mem_conf[device])) - device = 0; - - gpio_io_mem_conf[device](gpio_io_mem_opaque[device][instance], - io_index, new_con); - } - } - s->con[group] = value; - return; - } - - if (offset % STEP == 0x04) { - for (pin = 0; pin < 8; pin++) { - index = (s->con[group] >> pin * 4) & 0xF; - switch (index) { - case 0x0: - /* Output port can't be written */ - break; - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - gpio_case = s5pc1xx_gpio_case[group][pin][CASE(index)]; - if (gpio_case) { - device = gpio_case >> 11 & 0x1F; - instance = gpio_case >> 6 & 0x1F; - io_index = gpio_case >> 0 & 0x3F; - - if (!(gpio_io_mem_write[device])) - device = 0; - - gpio_io_mem_write[device] - (gpio_io_mem_opaque[device][instance], - io_index, (value >> pin) & 0x1); - } - break; - case 0xF: - /* TODO: implement this case */ - break; - default: - hw_error("s5pc1xx.gpio: " - "bad pin configuration index 0x%X\n", index); - } - } - return; - } - } - - if (offset >= INT_CON_BASE && offset < INT_CON_BASE + INT_REGS_SIZE) { - s->int_con[GET_GROUP_INT_CON(offset)] = value; - return; - } - - if (offset >= INT_FLTCON_BASE && - offset < INT_FLTCON_BASE + INT_REGS_SIZE * 2) { - s->int_fltcon[GET_GROUP_INT_FLTCON(offset)][(offset & 0x4) >> 2] = - value; - return; - } - - if (offset >= INT_MASK_BASE && offset < INT_MASK_BASE + INT_REGS_SIZE) { - s->int_mask[GET_GROUP_INT_MASK(offset)] = value; - return; - } - - if (offset >= INT_PEND_BASE && offset < INT_PEND_BASE + INT_REGS_SIZE) { - group = GET_GROUP_INT_PEND(offset); - s5pc1xx_gpio_irq_lower(s, group, value); - return; - } - - if (offset >= INT_FIXPRI_BASE && offset < INT_FIXPRI_BASE + INT_REGS_SIZE) { - s->int_fixpri[GET_GROUP_INT_FIXPRI(offset)] = value; - return; - } - - switch (offset) { - case GPIO_INT_GRPPRI: - s->int_grppri = value; - return; - case GPIO_INT_PRIORITY: - s->int_priority = value; - return; - case GPIO_INT_SER: - s->int_ser = value; - return; - case GPIO_INT_SER_PEND: - s->int_ser_pend = value; - return; - case GPIO_INT_GRPFIXPRI: - s->int_grpfixpri = value; - return; - } - - for (n = 0; n < 4; n++) { - /* EINT Mask Register */ - if (offset == EXT_INT_MASK(n)) { - s->ext_int_mask[n] = value; - return; - } - /* EINT Pend Register */ - if (offset == EXT_INT_PEND(n)) { - s5pc1xx_gpio_extended_irq_lower(s, group, value); - return; - } - } -} - -static CPUReadMemoryFunc * const s5pc1xx_gpio_readfn[] = { - s5pc1xx_gpio_read, - s5pc1xx_gpio_read, - s5pc1xx_gpio_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_gpio_writefn[] = { - s5pc1xx_gpio_write, - s5pc1xx_gpio_write, - s5pc1xx_gpio_write -}; - -static void s5pc1xx_gpio_save(QEMUFile *f, void *opaque) -{ - S5pc1xxGPIOState *s = (S5pc1xxGPIOState *)opaque; - int i; - - for (i = GPA0; i <= GPH3; i = (i == ETC2) ? GPH0 : i + 1) { - qemu_put_be32s(f, s->con + i); - if (i <= GPJ4) { - qemu_put_be32s(f, s->int_con + i); - qemu_put_be32s(f, &s->int_fltcon[i][0]); - qemu_put_be32s(f, &s->int_fltcon[i][1]); - - qemu_put_be32s(f, s->int_mask + i); - qemu_put_be32s(f, s->int_pend + i); - qemu_put_be32s(f, s->int_fixpri + i); - } - } - - for (i = 0; i < 4; i++) { - qemu_put_be32s(f, s->ext_int_mask + i); - qemu_put_be32s(f, s->ext_int_pend + i); - } - - qemu_put_be32s(f, &s->int_grppri); - qemu_put_be32s(f, &s->int_priority); - qemu_put_be32s(f, &s->int_ser); - qemu_put_be32s(f, &s->int_ser_pend); - qemu_put_be32s(f, &s->int_grpfixpri); -} - -static int s5pc1xx_gpio_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxGPIOState *s = (S5pc1xxGPIOState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - for (i = GPA0; i <= GPH3; i = (i == ETC2) ? GPH0 : i + 1) { - qemu_get_be32s(f, s->con + i); - if (i <= GPJ4) { - qemu_get_be32s(f, s->int_con + i); - qemu_get_be32s(f, &s->int_fltcon[i][0]); - qemu_get_be32s(f, &s->int_fltcon[i][1]); - - qemu_get_be32s(f, s->int_mask + i); - qemu_get_be32s(f, s->int_pend + i); - qemu_get_be32s(f, s->int_fixpri + i); - } - } - - for (i = 0; i < 4; i++) { - qemu_get_be32s(f, s->ext_int_mask + i); - qemu_get_be32s(f, s->ext_int_pend + i); - } - - qemu_get_be32s(f, &s->int_grppri); - qemu_get_be32s(f, &s->int_priority); - qemu_get_be32s(f, &s->int_ser); - qemu_get_be32s(f, &s->int_ser_pend); - qemu_get_be32s(f, &s->int_grpfixpri); - - return 0; -} - -qemu_irq s5pc1xx_gpoint_irq(DeviceState *d, int irq_num) -{ - return qdev_get_gpio_in(d, irq_num); -} - -/* GPIO Init Function */ -static int s5pc1xx_gpio_init(SysBusDevice *dev) -{ - S5pc1xxGPIOState *s = FROM_SYSBUS(S5pc1xxGPIOState, dev); - int iomemtype; - - sysbus_init_irq(dev, &s->gpioint); - sysbus_init_irq(dev, &s->extend); - iomemtype = - cpu_register_io_memory(s5pc1xx_gpio_readfn, s5pc1xx_gpio_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_GPIO_REG_MEM_SIZE, iomemtype); - - /* First IRQ_EXTEND_NUM interrupts are for extended interrupts */ - qdev_init_gpio_in(&dev->qdev, s5pc1xx_gpio_irq_handler, - IRQ_EXTEND_NUM + MAX_PIN_IN_GROUP * (GPJ4 + 1)); - - s5pc1xx_gpio_register_io_memory(0, 0, s5pc1xx_empty_gpio_readfn, - s5pc1xx_empty_gpio_writefn, - s5pc1xx_empty_gpio_writefn, NULL); - s5pc1xx_gpio_reset(s); - qemu_register_reset(s5pc1xx_gpio_reset, s); - - register_savevm(&dev->qdev, "s5pc1xx.gpio", -1, 1, - s5pc1xx_gpio_save, s5pc1xx_gpio_load, s); - - return 0; -} - -static void s5pc1xx_gpio_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.gpio", sizeof(S5pc1xxGPIOState), - s5pc1xx_gpio_init); -} - -device_init(s5pc1xx_gpio_register_devices) diff --git a/hw/s5pc1xx_gpio_regs.h b/hw/s5pc1xx_gpio_regs.h deleted file mode 100644 index 93b43fb..0000000 --- a/hw/s5pc1xx_gpio_regs.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * S5C GPIO Controller Constants - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - - -/* Registers */ - -#define STEP 0x20 - -#define CON(group) (0x000 + STEP * group) /* R/W Configuration Register */ -#define DAT(group) (0x004 + STEP * group) /* R/W Data Register */ -#define PUD(group) (0x008 + STEP * group) /* R/W Pull-up/down Register */ -#define DRV(group) (0x00C + STEP * group) /* R/W Drive Strength Control Register */ -#define CONPDN(group) (0x010 + STEP * group) /* R/W Power Down Mode Configuration Register */ -#define PUDPDN(group) (0x014 + STEP * group) /* R/W Power Down Mode Pullup/down Register */ - -/* General PIN configurations */ -#define GIPIO_CONF_INPUT 0x0 -#define GIPIO_CONF_OUTPUT 0x1 -#define GIPIO_CONF_INT 0xF - -/* Warning: the group GPI is absent in the registers below */ - -/* inter - group without GPI */ -#define GROUP_TO_INT_NUM(group) ((group) - ((group) < 17 ? 0:1)) -#define INT_TO_GROUP_NUM(inter) ((inter) + ((inter) < 17 ? 0:1)) - -#define INT_REGS_SIZE 0x58 - -#define INT_CON_BASE 0x700 -/* FLTCON has double set of regesters. So its' size is 2*INT_REGS_SIZE */ -#define INT_FLTCON_BASE 0x800 - -#define INT_MASK_BASE 0x900 - -#define INT_PEND_BASE 0xA00 -#define INT_FIXPRI_BASE 0xB14 - -/* R/W GPIO Interrupt Configuration Register */ -#define INT_CON(group) (INT_CON_BASE + 4 * GROUP_TO_INT_NUM(group)) -#define GET_GROUP_INT_CON(addr) INT_TO_GROUP_NUM(((addr) - INT_CON_BASE) / 4) - -/* R/W GPIO Interrupt Filter Configuration Register 0 and 1 */ -#define INT_FLTCON(group) (INT_FLTCON_BASE + 4 * GROUP_TO_INT_NUM(group)) -#define GET_GROUP_INT_FLTCON(addr) INT_TO_GROUP_NUM(((addr) - INT_FLTCON_BASE) / 8) - - -/* R/W GPIO Interrupt Mask Register */ -#define INT_MASK(group) (INT_MASK_BASE + 4 * GROUP_TO_INT_NUM(group)) -#define GET_GROUP_INT_MASK(addr) INT_TO_GROUP_NUM(((addr) - INT_MASK_BASE) / 4) - -/* R/W GPIO Interrupt Pending Register */ -#define INT_PEND(group) (INT_PEND_BASE + 4 * GROUP_TO_INT_NUM(group)) -#define GET_GROUP_INT_PEND(addr) INT_TO_GROUP_NUM(((addr) - INT_PEND_BASE) / 4) - - -#define GPIO_INT_GRPPRI 0xB00 /* R/W GPIO Interrupt Group Priority Control Register 0x0 */ -#define GPIO_INT_PRIORITY 0xB04 /* R/W GPIO Interrupt Priority Control Register 0x00 */ -#define GPIO_INT_SER 0xB08 /* R Current Service Register 0x00 */ -#define GPIO_INT_SER_PEND 0xB0C /* R Current Service Pending Register 0x00 */ -#define GPIO_INT_GRPFIXPRI 0xB10 /* R/W GPIO Interrupt Group Fixed Priority Control Register 0x00 */ - -/* R/W GPIO Interrupt Fixed Priority Control Register */ -#define INT_FIXPRI(group) (INT_PEND_FIXPRI + 4 * GROUP_TO_INT_NUM(group)) -#define GET_GROUP_INT_FIXPRI(addr) INT_TO_GROUP_NUM(((addr)-INT_FIXPRI_BASE) / 4) - -/* R/W External Interrupt Configuration Register */ -#define EXT_INT_CON(n) (0xE00 + 0x04 * n) - -/* R/W External Interrupt Filter Configuration Register 0 */ -#define EXT_INT_FLTCON0(n) (0xE80 + 0x08 * n) - -/* R/W External Interrupt Filter Configuration Register 1 */ -#define EXT_INT_FLTCON1(n) (0xE84 + 0x08 * n) - -/* R/W External Interrupt Mask Register */ -#define EXT_INT_MASK(n) (0xF00 + 0x04 * n) - -/* R/W External Interrupt Pending Register */ -#define EXT_INT_PEND(n) (0xF40 + 0x04 * n) - -/* R/W Power down mode Pad Configure Register */ -#define PDNEN 0xF80 - - -/* Groups */ - -#define GPA0 0 -#define GPA1 1 -#define GPB 2 -#define GPC0 3 -#define GPC1 4 -#define GPD0 5 -#define GPD1 6 -#define GPE0 7 -#define GPE1 8 -#define GPF0 9 -#define GPF1 10 -#define GPF2 11 -#define GPF3 12 -#define GPG0 13 -#define GPG1 14 -#define GPG2 15 -#define GPG3 16 -#define GPI 17 -#define GPJ0 18 -#define GPJ1 19 -#define GPJ2 20 -#define GPJ3 21 -#define GPJ4 22 - -#define MP0_1 23 -#define MP0_2 24 -#define MP0_3 25 -#define MP0_4 26 -#define MP0_5 27 -#define MP0_6 28 -#define MP0_7 29 - -#define MP1_0 30 -#define MP1_1 31 -#define MP1_2 32 -#define MP1_3 33 -#define MP1_4 34 -#define MP1_5 35 -#define MP1_6 36 -#define MP1_7 37 -#define MP1_8 38 - -#define MP2_0 39 -#define MP2_1 40 -#define MP2_2 41 -#define MP2_3 42 -#define MP2_4 43 -#define MP2_5 44 -#define MP2_6 45 -#define MP2_7 46 -#define MP2_8 47 - -#define ETC0 48 -#define ETC1 49 -#define ETC2 50 - -#define GPH0 96 -#define GPH1 97 -#define GPH2 98 -#define GPH3 99 - - -#define MAX_PIN_IN_GROUP 8 -#define IRQ_EXTEND_NUM 32 - -/* GPIOINT IRQs */ -#define GPIOEXT_IRQ(irq) (irq % 32) -#define GPIOINT_IRQ(group, pin) \ - ((group) * MAX_PIN_IN_GROUP + (pin) + IRQ_EXTEND_NUM) -#define GPIOINT_GROUP(irq) ((irq - IRQ_EXTEND_NUM) / MAX_PIN_IN_GROUP) -#define GPIOINT_PIN(irq) ((irq - IRQ_EXTEND_NUM) % MAX_PIN_IN_GROUP) - - -/* GPIO device indexes and io_cases */ - -/* CASE_ID has the structure: device_num [15:11]; - * instance_num [10:6]; - * event_num [5:0] - */ -#define CASE_ID(device, instance, event) ((device << 11) | \ - (instance << 6) | \ - (event << 0)) - -#define GPIO_IDX_PWM 1 - #define GPIO_PWM_TOUT(n) CASE_ID(GPIO_IDX_PWM, 0, n) /* n = 0~3 */ - #define PWM_MIE_MDNI CASE_ID(GPIO_IDX_PWM, 0, 4) - -#define GPIO_IDX_UART 2 - #define GPIO_UART_RXD(n) CASE_ID(GPIO_IDX_UART, n, 1) /* n = 0~3 */ - #define GPIO_UART_TXD(n) CASE_ID(GPIO_IDX_UART, n, 2) /* n = 0~3 */ - #define GPIO_UART_CTS(n) CASE_ID(GPIO_IDX_UART, n, 3) /* n = 0~2 */ - #define GPIO_UART_RTS(n) CASE_ID(GPIO_IDX_UART, n, 4) /* n = 0~2 */ - #define GPIO_UART_AUDIO_RXD CASE_ID(GPIO_IDX_UART, 0, 5) - #define GPIO_UART_AUDIO_TXD CASE_ID(GPIO_IDX_UART, 0, 6) - -#define GPIO_IDX_KEYIF 3 - #define GPIO_KP_COL(n) CASE_ID(GPIO_IDX_KEYIF, n, 1) /* n = 0~7 */ - #define GPIO_KP_ROW(n) CASE_ID(GPIO_IDX_KEYIF, n, 2) /* n = 0~13 */ - -#define GPIO_IDX_LCD 4 - #define LCD_FRM CASE_ID(GPIO_IDX_LCD, 0, 1) - #define LCD_HSYNC CASE_ID(GPIO_IDX_LCD, 0, 2) - #define LCD_VSYNC CASE_ID(GPIO_IDX_LCD, 0, 3) - #define LCD_VDEN CASE_ID(GPIO_IDX_LCD, 0, 4) - #define LCD_VCLK CASE_ID(GPIO_IDX_LCD, 0, 5) - #define LCD_VD(n) CASE_ID(GPIO_IDX_LCD, n, 6) /* n = 0~23 */ - -#define GPIO_IDX_I2C 5 - #define GPIO_IDX_I2C_SCL 1 - #define GPIO_IDX_I2C_SDA 2 - #define GPIO_I2C_SDA(n) CASE_ID(GPIO_IDX_I2C, n, GPIO_IDX_I2C_SDA) - #define GPIO_I2C_SCL(n) CASE_ID(GPIO_IDX_I2C, n, GPIO_IDX_I2C_SCL) - -#define GPIO_IDX_AC97 6 - #define GPIO_AC97BITCLK CASE_ID(GPIO_IDX_AC97, 0, 1) - #define GPIO_AC97RESETn CASE_ID(GPIO_IDX_AC97, 0, 2) - #define GPIO_AC97SYNC CASE_ID(GPIO_IDX_AC97, 0, 3) - #define GPIO_AC97SDI CASE_ID(GPIO_IDX_AC97, 0, 4) - #define GPIO_AC97SDO CASE_ID(GPIO_IDX_AC97, 0, 5) - -#define GPIO_IDX_PCM 7 - #define PCM_SCLK(n) CASE_ID(GPIO_IDX_PCM, n, 1) /* n = 0~2 */ - #define PCM_EXTCLK(n) CASE_ID(GPIO_IDX_PCM, n, 2) /* n = 0~2 */ - #define PCM_FSYNC(n) CASE_ID(GPIO_IDX_PCM, n, 3) /* n = 0~2 */ - #define PCM_SIN(n) CASE_ID(GPIO_IDX_PCM, n, 4) /* n = 0~2 */ - #define PCM_SOUT(n) CASE_ID(GPIO_IDX_PCM, n, 5) /* n = 0~2 */ - -#define GPIO_IDX_SPDIF 8 - #define SPDIF_0_OUT CASE_ID(GPIO_IDX_SPDIF, 0, 1) - #define SPDIF_EXTCLK CASE_ID(GPIO_IDX_SPDIF, 0, 2) - -#define GPIO_IDX_MAX 9 - - -/* GPIO io_cases storage */ - -/* Note: cases with indexes = 2~5 are stored in the array first */ -#define CASE(index) (index > 1 ? index - 2 : 4 + index) diff --git a/hw/s5pc1xx_hsmmc_regs.h b/hw/s5pc1xx_hsmmc_regs.h deleted file mode 100644 index 85c3a5e..0000000 --- a/hw/s5pc1xx_hsmmc_regs.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * S5C HS-MMC Controller Constants - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - * - * Based on SMDK6400 MMC (hw/regs-hsmmc.h) - */ - -#ifndef __ASM_ARCH_REGS_HSMMC_H -#define __ASM_ARCH_REGS_HSMMC_H __FILE__ - -/* - * HS MMC Interface - */ - -#define S5C_HSMMC_REG(x) (x) - -/* R/W SDMA System Address register 0x0 */ -#define S5C_HSMMC_SYSAD 0x00 - -/* R/W Host DMA Buffer Boundary and Transfer Block Size Register 0x0 */ -#define S5C_HSMMC_BLKSIZE 0x04 -#define S5C_HSMMC_MAKE_BLKSZ(dma, bblksz) (((dma & 0x7) << 12) | (blksz & 0xFFF)) - -/* R/W Blocks count for current transfer 0x0 */ -#define S5C_HSMMC_BLKCNT 0x06 -/* R/W Command Argument Register 0x0 */ -#define S5C_HSMMC_ARGUMENT 0x08 - -/* R/W Transfer Mode Setting Register 0x0 */ -#define S5C_HSMMC_TRNMOD 0x0C -#define S5C_HSMMC_TRNS_DMA 0x01 -#define S5C_HSMMC_TRNS_BLK_CNT_EN 0x02 -#define S5C_HSMMC_TRNS_ACMD12 0x04 -#define S5C_HSMMC_TRNS_READ 0x10 -#define S5C_HSMMC_TRNS_MULTI 0x20 - -#define S5C_HSMMC_TRNS_BOOTCMD 0x1000 -#define S5C_HSMMC_TRNS_BOOTACK 0x2000 - -/* R/W Command Register 0x0 */ -#define S5C_HSMMC_CMDREG 0x0E -/* ROC Response Register 0 0x0 */ -#define S5C_HSMMC_RSPREG0 0x10 -/* ROC Response Register 1 0x0 */ -#define S5C_HSMMC_RSPREG1 0x14 -/* ROC Response Register 2 0x0 */ -#define S5C_HSMMC_RSPREG2 0x18 -/* ROC Response Register 3 0x0 */ -#define S5C_HSMMC_RSPREG3 0x1C -#define S5C_HSMMC_CMD_RESP_MASK 0x03 -#define S5C_HSMMC_CMD_CRC 0x08 -#define S5C_HSMMC_CMD_INDEX 0x10 -#define S5C_HSMMC_CMD_DATA 0x20 -#define S5C_HSMMC_CMD_RESP_NONE 0x00 -#define S5C_HSMMC_CMD_RESP_LONG 0x01 -#define S5C_HSMMC_CMD_RESP_SHORT 0x02 -#define S5C_HSMMC_CMD_RESP_SHORT_BUSY 0x03 -#define S5C_HSMMC_MAKE_CMD(c, f) (((c & 0xFF) << 8) | (f & 0xFF)) - -/* R/W Buffer Data Register 0x0 */ -#define S5C_HSMMC_BDATA 0x20 -/* R/ROC Present State Register 0x000A0000 */ -#define S5C_HSMMC_PRNSTS 0x24 -#define S5C_HSMMC_CMD_INHIBIT 0x00000001 -#define S5C_HSMMC_DATA_INHIBIT 0x00000002 -#define S5C_HSMMC_DOING_WRITE 0x00000100 -#define S5C_HSMMC_DOING_READ 0x00000200 -#define S5C_HSMMC_SPACE_AVAILABLE 0x00000400 -#define S5C_HSMMC_DATA_AVAILABLE 0x00000800 -#define S5C_HSMMC_CARD_PRESENT 0x00010000 -#define S5C_HSMMC_WRITE_PROTECT 0x00080000 - -/* R/W Present State Register 0x0 */ -#define S5C_HSMMC_HOSTCTL 0x28 -#define S5C_HSMMC_CTRL_LED 0x01 -#define S5C_HSMMC_CTRL_4BITBUS 0x02 -#define S5C_HSMMC_CTRL_HIGHSPEED 0x04 -#define S5C_HSMMC_CTRL_1BIT 0x00 -#define S5C_HSMMC_CTRL_4BIT 0x02 -#define S5C_HSMMC_CTRL_8BIT 0x20 -#define S5C_HSMMC_CTRL_SDMA 0x00 -#define S5C_HSMMC_CTRL_ADMA2_32 0x10 - -/* R/W Present State Register 0x0 */ -#define S5C_HSMMC_PWRCON 0x29 -#define S5C_HSMMC_POWER_OFF 0x00 -#define S5C_HSMMC_POWER_ON 0x01 -#define S5C_HSMMC_POWER_180 0x0A -#define S5C_HSMMC_POWER_300 0x0C -#define S5C_HSMMC_POWER_330 0x0E -#define S5C_HSMMC_POWER_ON_ALL 0xFF - -/* R/W Block Gap Control Register 0x0 */ -#define S5C_HSMMC_BLKGAP 0x2A -/* R/W Wakeup Control Register 0x0 */ -#define S5C_HSMMC_WAKCON 0x2B - -#define S5C_HSMMC_STAWAKEUP 0x8 - -/* R/W Command Register 0x0 */ -#define S5C_HSMMC_CLKCON 0x2C -#define S5C_HSMMC_DIVIDER_SHIFT 0x8 -#define S5C_HSMMC_CLOCK_EXT_STABLE 0x8 -#define S5C_HSMMC_CLOCK_CARD_EN 0x4 -#define S5C_HSMMC_CLOCK_INT_STABLE 0x2 -#define S5C_HSMMC_CLOCK_INT_EN 0x1 - -/* R/W Timeout Control Register 0x0 */ -#define S5C_HSMMC_TIMEOUTCON 0x2E -#define S5C_HSMMC_TIMEOUT_MAX 0x0E - -/* R/W Software Reset Register 0x0 */ -#define S5C_HSMMC_SWRST 0x2F -#define S5C_HSMMC_RESET_ALL 0x01 -#define S5C_HSMMC_RESET_CMD 0x02 -#define S5C_HSMMC_RESET_DATA 0x04 - -/* ROC/RW1C Normal Interrupt Status Register 0x0 */ -#define S5C_HSMMC_NORINTSTS 0x30 -#define S5C_HSMMC_NIS_ERR 0x00008000 -#define S5C_HSMMC_NIS_CMDCMP 0x00000001 -#define S5C_HSMMC_NIS_TRSCMP 0x00000002 -#define S5C_HSMMC_NIS_DMA 0x00000008 -#define S5C_HSMMC_NIS_INSERT 0x00000040 -#define S5C_HSMMC_NIS_REMOVE 0x00000080 - -/* ROC/RW1C Error Interrupt Status Register 0x0 */ -#define S5C_HSMMC_ERRINTSTS 0x32 -#define S5C_HSMMC_EIS_CMDTIMEOUT 0x00000001 -#define S5C_HSMMC_EIS_CMDERR 0x0000000E -#define S5C_HSMMC_EIS_DATATIMEOUT 0x00000010 -#define S5C_HSMMC_EIS_DATAERR 0x00000060 -#define S5C_HSMMC_EIS_CMD12ERR 0x00000100 -#define S5C_HSMMC_EIS_ADMAERR 0x00000200 -#define S5C_HSMMC_EIS_STABOOTACKERR 0x00000400 - -/* R/W Normal Interrupt Status Enable Register 0x0 */ -#define S5C_HSMMC_NORINTSTSEN 0x34 -/* R/W Error Interrupt Status Enable Register 0x0 */ -#define S5C_HSMMC_ERRINTSTSEN 0x36 -#define S5C_HSMMC_ENSTABOOTACKERR 0x400 - -/* R/W Normal Interrupt Signal Enable Register 0x0 */ -#define S5C_HSMMC_NORINTSIGEN 0x38 -#define S5C_HSMMC_INT_MASK_ALL 0x00 -#define S5C_HSMMC_INT_RESPONSE 0x00000001 -#define S5C_HSMMC_INT_DATA_END 0x00000002 -#define S5C_HSMMC_INT_DMA_END 0x00000008 -#define S5C_HSMMC_INT_SPACE_AVAIL 0x00000010 -#define S5C_HSMMC_INT_DATA_AVAIL 0x00000020 -#define S5C_HSMMC_INT_CARD_INSERT 0x00000040 -#define S5C_HSMMC_INT_CARD_REMOVE 0x00000080 -#define S5C_HSMMC_INT_CARD_CHANGE 0x000000C0 -#define S5C_HSMMC_INT_CARD_INT 0x00000100 -#define S5C_HSMMC_INT_TIMEOUT 0x00010000 -#define S5C_HSMMC_INT_CRC 0x00020000 -#define S5C_HSMMC_INT_END_BIT 0x00040000 -#define S5C_HSMMC_INT_INDEX 0x00080000 -#define S5C_HSMMC_INT_DATA_TIMEOUT 0x00100000 -#define S5C_HSMMC_INT_DATA_CRC 0x00200000 -#define S5C_HSMMC_INT_DATA_END_BIT 0x00400000 -#define S5C_HSMMC_INT_BUS_POWER 0x00800000 -#define S5C_HSMMC_INT_ACMD12ERR 0x01000000 -#define S5C_HSMMC_INT_ADMAERR 0x02000000 - -#define S5C_HSMMC_INT_NORMAL_MASK 0x00007FFF -#define S5C_HSMMC_INT_ERROR_MASK 0xFFFF8000 - -#define S5C_HSMMC_INT_CMD_MASK (S5C_HSMMC_INT_RESPONSE | \ - S5C_HSMMC_INT_TIMEOUT | \ - S5C_HSMMC_INT_CRC | \ - S5C_HSMMC_INT_END_BIT | \ - S5C_HSMMC_INT_INDEX | \ - S5C_HSMMC_NIS_ERR) -#define S5C_HSMMC_INT_DATA_MASK (S5C_HSMMC_INT_DATA_END | \ - S5C_HSMMC_INT_DMA_END | \ - S5C_HSMMC_INT_DATA_AVAIL | \ - S5C_HSMMC_INT_SPACE_AVAIL | \ - S5C_HSMMC_INT_DATA_TIMEOUT | \ - S5C_HSMMC_INT_DATA_CRC | \ - S5C_HSMMC_INT_DATA_END_BIT) - -/* R/W Error Interrupt Signal Enable Register 0x0 */ -#define S5C_HSMMC_ERRINTSIGEN 0x3A -#define S5C_HSMMC_ENSIGBOOTACKERR 0x400 - -/* ROC Auto CMD12 error status register 0x0 */ -#define S5C_HSMMC_ACMD12ERRSTS 0x3C - -/* HWInit Capabilities Register 0x05E80080 */ -#define S5C_HSMMC_CAPAREG 0x40 -#define S5C_HSMMC_TIMEOUT_CLK_MASK 0x0000003F -#define S5C_HSMMC_TIMEOUT_CLK_SHIFT 0x0 -#define S5C_HSMMC_TIMEOUT_CLK_UNIT 0x00000080 -#define S5C_HSMMC_CLOCK_BASE_MASK 0x00003F00 -#define S5C_HSMMC_CLOCK_BASE_SHIFT 0x8 -#define S5C_HSMMC_MAX_BLOCK_MASK 0x00030000 -#define S5C_HSMMC_MAX_BLOCK_SHIFT 0x10 -#define S5C_HSMMC_CAN_DO_DMA 0x00400000 -#define S5C_HSMMC_CAN_DO_ADMA2 0x00080000 -#define S5C_HSMMC_CAN_VDD_330 0x01000000 -#define S5C_HSMMC_CAN_VDD_300 0x02000000 -#define S5C_HSMMC_CAN_VDD_180 0x04000000 - -/* HWInit Maximum Current Capabilities Register 0x0 */ -#define S5C_HSMMC_MAXCURR 0x48 - -/* For ADMA2 */ - -/* W Force Event Auto CMD12 Error Interrupt Register 0x0000 */ -#define S5C_HSMMC_FEAER 0x50 -/* W Force Event Error Interrupt Register Error Interrupt 0x0000 */ -#define S5C_HSMMC_FEERR 0x52 - -/* R/W ADMA Error Status Register 0x00 */ -#define S5C_HSMMC_ADMAERR 0x54 -#define S5C_HSMMC_ADMAERR_CONTINUE_REQUEST (1 << 9) -#define S5C_HSMMC_ADMAERR_INTRRUPT_STATUS (1 << 8) -#define S5C_HSMMC_ADMAERR_LENGTH_MISMATCH (1 << 2) -#define S5C_HSMMC_ADMAERR_STATE_ST_STOP (0 << 0) -#define S5C_HSMMC_ADMAERR_STATE_ST_FDS (1 << 0) -#define S5C_HSMMC_ADMAERR_STATE_ST_TFR (3 << 0) - -/* R/W ADMA System Address Register 0x00 */ -#define S5C_HSMMC_ADMASYSADDR 0x58 -#define S5C_HSMMC_ADMA_ATTR_MSK 0x3F -#define S5C_HSMMC_ADMA_ATTR_ACT_NOP (0 << 4) -#define S5C_HSMMC_ADMA_ATTR_ACT_RSV (1 << 4) -#define S5C_HSMMC_ADMA_ATTR_ACT_TRAN (2 << 4) -#define S5C_HSMMC_ADMA_ATTR_ACT_LINK (3 << 4) -#define S5C_HSMMC_ADMA_ATTR_INT (1 << 2) -#define S5C_HSMMC_ADMA_ATTR_END (1 << 1) -#define S5C_HSMMC_ADMA_ATTR_VALID (1 << 0) - -/* R/W Control register 2 0x0 */ -#define S5C_HSMMC_CONTROL2 0x80 -/* R/W FIFO Interrupt Control (Control Register 3) 0x7F5F3F1F */ -#define S5C_HSMMC_CONTROL3 0x84 -/* R/W Control register 4 0x0 */ -#define S5C_HSMMC_CONTROL4 0x8C - - -/* Magic register which is used from kernel! */ -#define S5C_HSMMC_SLOT_INT_STATUS 0xFC - - -/* HWInit Host Controller Version Register 0x0401 */ -#define S5C_HSMMC_HCVER 0xFE -#define S5C_HSMMC_VENDOR_VER_MASK 0xFF00 -#define S5C_HSMMC_VENDOR_VER_SHIFT 0x8 -#define S5C_HSMMC_SPEC_VER_MASK 0x00FF -#define S5C_HSMMC_SPEC_VER_SHIFT 0x0 - -#define S5C_HSMMC_REG_SIZE 0x100 - -#endif /* __ASM_ARCH_REGS_HSMMC_H */ diff --git a/hw/s5pc1xx_i2c.c b/hw/s5pc1xx_i2c.c deleted file mode 100644 index 2fb757b..0000000 --- a/hw/s5pc1xx_i2c.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * I2C controller for S5PC1XX-based board emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - * Alexey Merkulov - * - * Based on SMDK6400 I2C (hw/smdk6400/smdk_i2c.c) - */ - -#include "i2c.h" -#include "sysbus.h" - - -#define I2CCON 0x00 /* I2C Control register */ -#define I2CSTAT 0x04 /* I2C Status register */ -#define I2CADD 0x08 /* I2C Slave Address register */ -#define I2CDS 0x0c /* I2C Data Shift register */ -#define I2CLC 0x10 /* I2C Line Control register */ - -#define SR_MODE 0x0 /* Slave Receive Mode */ -#define ST_MODE 0x1 /* Slave Transmit Mode */ -#define MR_MODE 0x2 /* Master Receive Mode */ -#define MT_MODE 0x3 /* Master Transmit Mode */ - - -#define S5PC1XX_IICCON_ACKEN (1<<7) -#define S5PC1XX_IICCON_TXDIV_16 (0<<6) -#define S5PC1XX_IICCON_TXDIV_512 (1<<6) -#define S5PC1XX_IICCON_IRQEN (1<<5) -#define S5PC1XX_IICCON_IRQPEND (1<<4) - -#define S5PC1XX_IICSTAT_START (1<<5) -#define S5PC1XX_IICSTAT_BUSBUSY (1<<5) -#define S5PC1XX_IICSTAT_TXRXEN (1<<4) -#define S5PC1XX_IICSTAT_ARBITR (1<<3) -#define S5PC1XX_IICSTAT_ASSLAVE (1<<2) -#define S5PC1XX_IICSTAT_ADDR0 (1<<1) -#define S5PC1XX_IICSTAT_LASTBIT (1<<0) - -#define S5PC1XX_I2C_REG_MEM_SIZE 0x1000 - - -/* I2C Interface */ -typedef struct S5pc1xxI2CState { - SysBusDevice busdev; - - i2c_bus *bus; - qemu_irq irq; - - uint8_t control; - uint8_t status; - uint8_t address; - uint8_t datashift; - uint8_t line_ctrl; - - uint8_t ibmr; - uint8_t data; -} S5pc1xxI2CState; - - -static void s5pc1xx_i2c_update(S5pc1xxI2CState *s) -{ - uint16_t level; - level = (s->status & S5PC1XX_IICSTAT_START) && - (s->control & S5PC1XX_IICCON_IRQEN); - - if (s->control & S5PC1XX_IICCON_IRQPEND) - level = 0; - qemu_set_irq(s->irq, !!level); -} - -static int s5pc1xx_i2c_receive(S5pc1xxI2CState *s) -{ - int r; - - r = i2c_recv(s->bus); - s5pc1xx_i2c_update(s); - return r; -} - -static int s5pc1xx_i2c_send(S5pc1xxI2CState *s, uint8_t data) -{ - if (!(s->status & S5PC1XX_IICSTAT_LASTBIT)) { - /*s->status |= 1 << 7;*/ - s->data = data; - i2c_send(s->bus, s->data); - } - s5pc1xx_i2c_update(s); - return 1; -} - -/* I2C read function */ -static uint32_t s5pc1xx_i2c_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxI2CState *s = (S5pc1xxI2CState *)opaque; - - switch (offset) { - case I2CCON: - return s->control; - case I2CSTAT: - return s->status; - case I2CADD: - return s->address; - case I2CDS: - s->data = s5pc1xx_i2c_receive(s); - return s->data; - case I2CLC: - return s->line_ctrl; - default: - hw_error("s5pc1xx.i2c: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } - return 0; -} - -/* I2C write function */ -static void s5pc1xx_i2c_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxI2CState *s = (S5pc1xxI2CState *)opaque; - int mode; - - qemu_irq_lower(s->irq); - - switch (offset) { - case I2CCON: - s->control = value & 0xff; - - if (value & S5PC1XX_IICCON_IRQEN) - s5pc1xx_i2c_update(s); - break; - - case I2CSTAT: - s->status = value & 0xff; - mode = (s->status >> 6) & 0x3; - if (value & S5PC1XX_IICSTAT_TXRXEN) { - /* IIC-bus data output enable/disable bit */ - switch(mode) { - case SR_MODE: - s->data = s5pc1xx_i2c_receive(s); - break; - case ST_MODE: - s->data = s5pc1xx_i2c_receive(s); - break; - case MR_MODE: - if (value & (1 << 5)) { - /* START condition */ - s->status &= ~S5PC1XX_IICSTAT_LASTBIT; - - i2c_start_transfer(s->bus, s->data >> 1, s->data & 1); - } else { - i2c_end_transfer(s->bus); - s->status |= S5PC1XX_IICSTAT_TXRXEN; - } - break; - case MT_MODE: - if (value & (1 << 5)) { - /* START condition */ - s->status &= ~S5PC1XX_IICSTAT_LASTBIT; - - i2c_start_transfer(s->bus, s->data >> 1, s->data & 1); - } else { - i2c_end_transfer(s->bus); - s->status |= S5PC1XX_IICSTAT_TXRXEN; - } - break; - default: - break; - } - } - s5pc1xx_i2c_update(s); - break; - - case I2CADD: - s->address = value & 0xff; - break; - - case I2CDS: - s5pc1xx_i2c_send(s, value & 0xff); - break; - - case I2CLC: - s->line_ctrl = value & 0xff; - break; - - default: - hw_error("s5pc1xx.i2c: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_i2c_readfn[] = { - s5pc1xx_i2c_read, - s5pc1xx_i2c_read, - s5pc1xx_i2c_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_i2c_writefn[] = { - s5pc1xx_i2c_write, - s5pc1xx_i2c_write, - s5pc1xx_i2c_write -}; - -static void s5pc1xx_i2c_save(QEMUFile *f, void *opaque) -{ - S5pc1xxI2CState *s = (S5pc1xxI2CState *)opaque; - - qemu_put_8s(f, &s->control); - qemu_put_8s(f, &s->status); - qemu_put_8s(f, &s->address); - qemu_put_8s(f, &s->datashift); - qemu_put_8s(f, &s->line_ctrl); - qemu_put_8s(f, &s->ibmr); - qemu_put_8s(f, &s->data); -} - -static int s5pc1xx_i2c_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxI2CState *s = (S5pc1xxI2CState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_8s(f, &s->control); - qemu_get_8s(f, &s->status); - qemu_get_8s(f, &s->address); - qemu_get_8s(f, &s->datashift); - qemu_get_8s(f, &s->line_ctrl); - qemu_get_8s(f, &s->ibmr); - qemu_get_8s(f, &s->data); - - return 0; -} - -/* I2C init */ -static int s5pc1xx_i2c_init(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxI2CState *s = FROM_SYSBUS(S5pc1xxI2CState, dev); - - sysbus_init_irq(dev, &s->irq); - s->bus = i2c_init_bus(&dev->qdev, "i2c"); - - iomemtype = - cpu_register_io_memory(s5pc1xx_i2c_readfn, s5pc1xx_i2c_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_I2C_REG_MEM_SIZE, iomemtype); - - register_savevm(&dev->qdev, "s5pc1xx.i2c", -1, 1, - s5pc1xx_i2c_save, s5pc1xx_i2c_load, s); - - return 0; -} - -static void s5pc1xx_i2c_register(void) -{ - sysbus_register_dev("s5pc1xx.i2c", sizeof(S5pc1xxI2CState), - s5pc1xx_i2c_init); -} - -device_init(s5pc1xx_i2c_register) diff --git a/hw/s5pc1xx_i2c_gpio.c b/hw/s5pc1xx_i2c_gpio.c deleted file mode 100644 index 36e8529..0000000 --- a/hw/s5pc1xx_i2c_gpio.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * I2C bus through GPIO pins - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Alexey Merkulov - */ - -#include "i2c.h" -#include "sysbus.h" -#include "s5pc1xx.h" -#include "s5pc1xx_gpio_regs.h" -#include "bitbang_i2c.h" - - -//#define DEBUG -#define SDA_PIN_NUM GPIO_IDX_I2C_SDA - - -typedef struct S5pc1xxI2CGPIOState { - SysBusDevice busdev; - - bitbang_i2c_interface *bitbang; - i2c_bus *bus; - - int32_t sda; - int32_t scl; - uint32_t instance; -} S5pc1xxI2CGPIOState; - - -static void s5pc1xx_i2c_gpio_reset(void *opaque) -{ - S5pc1xxI2CGPIOState *s = (S5pc1xxI2CGPIOState *)opaque; - s->sda = 1; - s->scl = 1; -} - -static void s5pc1xx_i2c_bitbang_set_conf(void *opaque, int io_index, - uint32_t conf) -{ - S5pc1xxI2CGPIOState *s = (S5pc1xxI2CGPIOState *)opaque; - -#ifdef DEBUG - fprintf(stderr, "QEMU BITBANG I2C set configuration: io_index = %s, " - "conf = 0x%02X\n", - io_index == SDA_PIN_NUM ? "sda" : "scl", conf == GIPIO_CONF_INPUT); -#endif - - if (io_index == SDA_PIN_NUM) { - s->sda = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, conf == GIPIO_CONF_INPUT); - } else { - s->sda = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, conf == GIPIO_CONF_INPUT); - s->scl = (conf == GIPIO_CONF_INPUT); - } -} - -static uint32_t s5pc1xx_i2c_bitbang_read(void *opaque, int io_index) -{ - S5pc1xxI2CGPIOState *s = (S5pc1xxI2CGPIOState *)opaque; - - uint32_t ret = io_index == SDA_PIN_NUM ? s->sda : s->scl; - -#ifdef DEBUG - fprintf(stderr, "QEMU BITBANG I2C read: io_index = %s, value = %d\n", - io_index == SDA_PIN_NUM ? "sda" : "scl", ret); -#endif - - return ret; -} - -static void s5pc1xx_i2c_bitbang_write(void *opaque, int io_index, uint32_t value) -{ -#ifdef DEBUG - fprintf(stderr, "QEMU BITBANG I2C write: io_index = %s, value = %u\n", - io_index == SDA_PIN_NUM ? "sda" : "scl", value); -#endif -} - -static void s5pc1xx_i2c_gpio_save(QEMUFile *f, void *opaque) -{ - S5pc1xxI2CGPIOState *s = (S5pc1xxI2CGPIOState *)opaque; - - /* FIXME: save bitbang? */ - qemu_put_sbe32s(f, &s->sda); - qemu_put_sbe32s(f, &s->scl); -} - -static int s5pc1xx_i2c_gpio_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxI2CGPIOState *s = (S5pc1xxI2CGPIOState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_sbe32s(f, &s->sda); - qemu_get_sbe32s(f, &s->scl); - - return 0; -} - -DeviceState *s5pc1xx_i2c_gpio_init(int instance) -{ - DeviceState *dev = qdev_create(NULL, "s5pc1xx.i2c.gpio"); - qdev_prop_set_uint32(dev, "instance", instance); - qdev_init_nofail(dev); - return dev; -} - -/* I2C init */ -static int s5pc1xx_i2c_gpio_init1(SysBusDevice *dev) -{ - S5pc1xxI2CGPIOState *s = FROM_SYSBUS(S5pc1xxI2CGPIOState, dev); - - s->bus = i2c_init_bus(&dev->qdev, "i2c"); - s->bitbang = bitbang_i2c_init(s->bus); - - s5pc1xx_gpio_register_io_memory(GPIO_IDX_I2C, s->instance, - s5pc1xx_i2c_bitbang_read, - s5pc1xx_i2c_bitbang_write, - s5pc1xx_i2c_bitbang_set_conf, s); - - s5pc1xx_i2c_gpio_reset(s); - qemu_register_reset(s5pc1xx_i2c_gpio_reset, s); - - register_savevm(&dev->qdev, "s5pc1xx.i2c.gpio", s->instance, 1, - s5pc1xx_i2c_gpio_save, s5pc1xx_i2c_gpio_load, s); - - return 0; -} - -static SysBusDeviceInfo s5pc1xx_i2c_gpio_info = { - .init = s5pc1xx_i2c_gpio_init1, - .qdev.name = "s5pc1xx.i2c.gpio", - .qdev.size = sizeof(S5pc1xxI2CGPIOState), - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("instance", S5pc1xxI2CGPIOState, instance, 0), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_i2c_gpio_register(void) -{ - sysbus_register_withprop(&s5pc1xx_i2c_gpio_info); -} - -device_init(s5pc1xx_i2c_gpio_register) diff --git a/hw/s5pc1xx_i2s.c b/hw/s5pc1xx_i2s.c deleted file mode 100644 index 1f1c049..0000000 --- a/hw/s5pc1xx_i2s.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * IIS Multi Audio Interface for S5PC1XX-based board emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Alexey Merkulov - * - * TODO: make support of second channel! - */ - -#include "sysbus.h" -#include "i2c.h" -#include "s5pc1xx.h" - - -#define AUDIO_WORDS_SEND 0x800 - -/*Magic size*/ -#define AUDIO_BUFFER_SIZE 0x100000 - -#define S5PC1XX_I2S_IISCON 0x00 -#define S5PC1XX_I2S_IISMOD 0x04 -#define S5PC1XX_I2S_IISFIC 0x08 -#define S5PC1XX_I2S_IISPSR 0x0C -#define S5PC1XX_I2S_IISTXD 0x10 -#define S5PC1XX_I2S_IISRXD 0x14 -#define S5PC1XX_I2S_IISFICS 0x18 -#define S5PC1XX_I2S_IISTXDS 0x1C -#define S5PC1XX_I2S_IISAHB 0x20 -#define S5PC1XX_I2S_IISSTR 0x24 -#define S5PC1XX_I2S_IISSIZE 0x28 -#define S5PC1XX_I2S_IISTRNCNT 0x2C -#define S5PC1XX_I2S_IISADDR0 0x30 -#define S5PC1XX_I2S_IISADDR1 0x34 -#define S5PC1XX_I2S_IISADDR2 0x38 -#define S5PC1XX_I2S_IISADDR3 0x3C -#define S5PC1XX_I2S_IISSTR1 0x40 - -#define S5PC1XX_I2S_REG_MEM_SIZE 0x44 - -#define S5PC1XX_IISCON_I2SACTIVE (0x1<< 0) -#define S5PC1XX_IISCON_RXDMACTIVE (0x1<< 1) -#define S5PC1XX_IISCON_TXDMACTIVE (0x1<< 2) -#define S5PC1XX_IISCON_RXCHPAUSE (0x1<< 3) -#define S5PC1XX_IISCON_TXCHPAUSE (0x1<< 4) -#define S5PC1XX_IISCON_RXDMAPAUSE (0x1<< 5) -#define S5PC1XX_IISCON_TXDMAPAUSE (0x1<< 6) -#define S5PC1XX_IISCON_FRXFULL (0x1<< 7) /*Read only*/ -#define S5PC1XX_IISCON_FTX0FULL (0x1<< 8) /*Read only*/ -#define S5PC1XX_IISCON_FRXEMPT (0x1<< 9) /*Read only*/ -#define S5PC1XX_IISCON_FTX0EMPT (0x1<<10) /*Read only*/ -#define S5PC1XX_IISCON_LRI (0x1<<11) /*Read only*/ -#define S5PC1XX_IISCON_FTX1FULL (0x1<<12) /*Read only*/ -#define S5PC1XX_IISCON_FTX2FULL (0x1<<13) /*Read only*/ -#define S5PC1XX_IISCON_FTX1EMPT (0x1<<14) /*Read only*/ -#define S5PC1XX_IISCON_FTX2EMPT (0x1<<15) /*Read only*/ -#define S5PC1XX_IISCON_FTXURINTEN (0x1<<16) -#define S5PC1XX_IISCON_FTXURSTATUS (0x1<<17) /*Write to clear*/ -#define S5PC1XX_IISCON_TXSDMACTIVE (0x1<<18) -#define S5PC1XX_IISCON_TXSDMAPAUSE (0x1<<20) -#define S5PC1XX_IISCON_FTXSFULL (0x1<<21) /*Read only*/ -#define S5PC1XX_IISCON_FTXSEMPT (0x1<<22) /*Read only*/ -#define S5PC1XX_IISCON_FTXSURINTEN (0x1<<23) -#define S5PC1XX_IISCON_FTXSURSTAT (0x1<<24) /*Write to clear*/ -#define S5PC1XX_IISCON_FRXOFINTEN (0x1<<25) -#define S5PC1XX_IISCON_FRXOFSTAT (0x1<<26) /*Write to clear*/ -#define S5PC1XX_IISCON_SWRESET (0x1<<31) - -#define S5PC1XX_IISCON_WRITE_MASK (0x8295007F) -#define S5PC1XX_IISCON_READ_MASK (0x0060FF80) -#define S5PC1XX_IISCON_WRITE_TO_CLEAR_MASK (0x05020000) - - -#define S5PC1XX_IISMOD_BFSMASK (3<<1) -#define S5PC1XX_IISMOD_32FS (0<<1) -#define S5PC1XX_IISMOD_48FS (1<<1) -#define S5PC1XX_IISMOD_16FS (2<<1) -#define S5PC1XX_IISMOD_24FS (3<<1) - -#define S5PC1XX_IISMOD_RFSMASK (3<<3) -#define S5PC1XX_IISMOD_256FS (0<<3) -#define S5PC1XX_IISMOD_512FS (1<<3) -#define S5PC1XX_IISMOD_384FS (2<<3) -#define S5PC1XX_IISMOD_768FS (3<<3) - -#define S5PC1XX_IISMOD_SDFMASK (3<<5) -#define S5PC1XX_IISMOD_IIS (0<<5) -#define S5PC1XX_IISMOD_MSB (1<<5) -#define S5PC1XX_IISMOD_LSB (2<<5) - -#define S5PC1XX_IISMOD_LRP (1<<7) - -#define S5PC1XX_IISMOD_TXRMASK (3<<8) -#define S5PC1XX_IISMOD_TX (0<<8) -#define S5PC1XX_IISMOD_RX (1<<8) -#define S5PC1XX_IISMOD_TXRX (2<<8) - -#define S5PC1XX_IISMOD_TX_SET(r) (!((1<<8)&(r))) -#define S5PC1XX_IISMOD_RX_SET(r) (((3<<8)&(r)) != 0) - - -#define S5PC1XX_IISMOD_IMSMASK (3<<10) -#define S5PC1XX_IISMOD_MSTPCLK (0<<10) -#define S5PC1XX_IISMOD_MSTCLKAUDIO (1<<10) -#define S5PC1XX_IISMOD_SLVPCLK (2<<10) -#define S5PC1XX_IISMOD_SLVI2SCLK (3<<10) - -#define S5PC1XX_IISMOD_CDCLKCON (1<<12) - -#define S5PC1XX_IISMOD_BLCMASK (3<<13) -#define S5PC1XX_IISMOD_16BIT (0<<13) -#define S5PC1XX_IISMOD_8BIT (1<<13) -#define S5PC1XX_IISMOD_24BIT (2<<13) - -#define S5PC1XX_IISMOD_SD1EN (1<<16) -#define S5PC1XX_IISMOD_SD2EN (1<<17) - -#define S5PC1XX_IISMOD_CCD1MASK (3<<18) -#define S5PC1XX_IISMOD_CCD1ND (0<<18) -#define S5PC1XX_IISMOD_CCD11STD (1<<18) -#define S5PC1XX_IISMOD_CCD12NDD (2<<18) - -#define S5PC1XX_IISMOD_CCD2MASK (3<<20) -#define S5PC1XX_IISMOD_CCD2ND (0<<20) -#define S5PC1XX_IISMOD_CCD21STD (1<<20) -#define S5PC1XX_IISMOD_CCD22NDD (2<<20) - -#define S5PC1XX_IISMOD_BLCPMASK (3<<24) -#define S5PC1XX_IISMOD_P16BIT (0<<24) -#define S5PC1XX_IISMOD_P8BIT (1<<24) -#define S5PC1XX_IISMOD_P24BIT (2<<24) -#define S5PC1XX_IISMOD_BLCSMASK (3<<26) -#define S5PC1XX_IISMOD_S16BIT (0<<26) -#define S5PC1XX_IISMOD_S8BIT (1<<26) -#define S5PC1XX_IISMOD_S24BIT (2<<26) -#define S5PC1XX_IISMOD_TXSLP (1<<28) -#define S5PC1XX_IISMOD_OPMSK (3<<30) -#define S5PC1XX_IISMOD_OPCCO (0<<30) -#define S5PC1XX_IISMOD_OPCCI (1<<30) -#define S5PC1XX_IISMOD_OPBCO (2<<30) -#define S5PC1XX_IISMOD_OPPCLK (3<<30) - -#define I2S_TOGGLE_BIT(old, new, bit) (((old) & (bit)) != ((new) & (bit))) - - -/* I2C Interface */ -typedef struct S5pc1xxI2SState { - SysBusDevice busdev; - - uint32_t iiscon; - uint32_t iismod; - uint32_t iisfic; - uint32_t iispsr; - uint32_t iisfics; - uint32_t iisahb; - uint32_t iisstr0; - uint32_t iissize; - uint32_t iistrncnt; - uint32_t iislvl0addr; - uint32_t iislvl1addr; - uint32_t iislvl2addr; - uint32_t iislvl3addr; - uint32_t iisstr1; - - uint8_t *buffer; - uint32_t buf_size; - uint32_t play_pos; - uint32_t last_free; - - qemu_irq irq; - qemu_irq dma_irq_stop1; - qemu_irq dma_irq_stop2; - DeviceState *wm8994; -} S5pc1xxI2SState; - - -static void s5pc1xx_i2s_stop(S5pc1xxI2SState *s) -{ - qemu_irq_raise(s->dma_irq_stop1); - qemu_irq_raise(s->dma_irq_stop2); -} - -static void s5pc1xx_i2s_resume(S5pc1xxI2SState *s) -{ - qemu_irq_lower(s->dma_irq_stop1); - qemu_irq_lower(s->dma_irq_stop2); -} - - -static void s5pc1xx_i2s_reset(void *opaque) -{ - S5pc1xxI2SState *s = (S5pc1xxI2SState *)opaque; - - s->iiscon = 0; - s->iismod = 0; - s->iisfic = 0; - s->iispsr = 0; - s->iisfics = 0; - s->iisahb = 0; - s->iisstr0 = 0; - s->iissize = 0x7FFF0000; - s->iistrncnt = 0; - s->iislvl0addr = 0; - s->iislvl1addr = 0; - s->iislvl2addr = 0; - s->iislvl3addr = 0; - s->iisstr1 = 0; - - s->play_pos = 0; - s->last_free = 0; -} - -static int s5pc1xx_i2s_pause(S5pc1xxI2SState *s) { - return s->iiscon & S5PC1XX_IISCON_TXCHPAUSE; -} - -static int s5pc1xx_i2s_transmit(S5pc1xxI2SState *s) { - return S5PC1XX_IISMOD_TX_SET(s->iismod); -} - -static void s5pc1xx_i2s_audio_callback(void *opaque, int free_out) -{ - S5pc1xxI2SState *s = (S5pc1xxI2SState *)opaque; - int8_t *codec_buffer = NULL; - int block_size = 0; - - - if (free_out <= 0) { - return; - } - if (free_out > AUDIO_WORDS_SEND) { - free_out = AUDIO_WORDS_SEND; - } - - block_size = 4 * free_out; - - if (s5pc1xx_i2s_pause(s)) { - return; - } - - if (s->play_pos > s->last_free && - s->play_pos + block_size > s->buf_size && - s->play_pos + block_size - s->buf_size > s->last_free) { - s5pc1xx_i2s_resume(s); - return; - } - - if (s->play_pos <= s->last_free && - s->play_pos + block_size > s->last_free) { - s5pc1xx_i2s_resume(s); - return; - } - - codec_buffer = wm8994_dac_buffer(s->wm8994, block_size); - memcpy(codec_buffer, s->buffer + s->play_pos, block_size); - s->play_pos = (s->play_pos + block_size) % s->buf_size; - - s5pc1xx_i2s_resume(s); - - wm8994_dac_commit(s->wm8994); -} - -/* I2S write function */ -static void s5pc1xx_i2s_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxI2SState *s = (S5pc1xxI2SState *)opaque; - int use_buf = 0; - - switch (offset) { - case S5PC1XX_I2S_IISCON: - if ((value & S5PC1XX_IISCON_SWRESET) && - !(s->iiscon & S5PC1XX_IISCON_SWRESET)) { - s5pc1xx_i2s_reset(s); - } - if (I2S_TOGGLE_BIT(s->iiscon, value, S5PC1XX_IISCON_TXCHPAUSE)) { - if (value & S5PC1XX_IISCON_TXCHPAUSE) { - s5pc1xx_i2s_stop(s); - } else { - s5pc1xx_i2s_resume(s); - } - } - - if (I2S_TOGGLE_BIT(s->iiscon, value, S5PC1XX_IISCON_TXSDMACTIVE)) { - /*TODO: stop dma if (value & S5PC1XX_IISCON_TXSDMACTIVE) is 0*/ - } - - s->iiscon = (s->iiscon & ~S5PC1XX_IISCON_WRITE_MASK) | - (value & S5PC1XX_IISCON_WRITE_MASK); - - - if (!(s->iiscon & S5PC1XX_IISCON_I2SACTIVE)) { - s->play_pos = 0; - s->last_free = 0; - s5pc1xx_i2s_resume(s); - } - - /* FIXME: Kernel wants this bit for synchronization. Fix this line */ - s->iiscon |= S5PC1XX_IISCON_LRI; - break; - case S5PC1XX_I2S_IISMOD: - s->iismod = value; - break; - case S5PC1XX_I2S_IISFIC: - s->iisfic = value; - break; - case S5PC1XX_I2S_IISPSR: - s->iispsr = value; - break; - case S5PC1XX_I2S_IISTXDS: - case S5PC1XX_I2S_IISTXD: - if (!s5pc1xx_i2s_transmit(s)) - break; - - if ( (s->iismod & S5PC1XX_IISMOD_LRP) && - ((s->iismod & S5PC1XX_IISMOD_BLCMASK) == S5PC1XX_IISMOD_16BIT || - (s->iismod & S5PC1XX_IISMOD_BLCMASK) == S5PC1XX_IISMOD_8BIT)) { - *(uint32_t *)(s->buffer + s->last_free) = - (value << 16) | (value >> 16); - } else { - *(uint32_t *)(s->buffer + s->last_free) = value; - } - - s->last_free = (s->last_free + sizeof(value)) % s->buf_size; - - use_buf = s->last_free - s->play_pos; - if (use_buf < 0) { - use_buf = s->buf_size + use_buf; - } - - if (use_buf >= AUDIO_WORDS_SEND*4) { - s5pc1xx_i2s_stop(s); - } - break; - case S5PC1XX_I2S_IISFICS: - s->iisfics = value; - break; - case S5PC1XX_I2S_IISAHB: - s->iisahb = value; - break; - case S5PC1XX_I2S_IISSTR: - s->iisstr0 = value; - break; - case S5PC1XX_I2S_IISSIZE: - s->iissize = value; - break; - case S5PC1XX_I2S_IISTRNCNT: - s->iistrncnt = value; - break; - case S5PC1XX_I2S_IISADDR0: - s->iislvl0addr = value; - break; - case S5PC1XX_I2S_IISADDR1: - s->iislvl1addr = value; - break; - case S5PC1XX_I2S_IISADDR2: - s->iislvl2addr = value; - break; - case S5PC1XX_I2S_IISADDR3: - s->iislvl3addr = value; - break; - case S5PC1XX_I2S_IISSTR1: - s->iisstr1 = value; - break; - default: - /* FIXME: all registers are accessible by byte */ - hw_error("s5pc1xx.i2s: bad write offset " TARGET_FMT_plx "\n", offset); - } -} - -/* I2S read function */ -static uint32_t s5pc1xx_i2s_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxI2SState *s = (S5pc1xxI2SState *)opaque; - - - switch (offset) { - case S5PC1XX_I2S_IISCON: - return s->iiscon; - case S5PC1XX_I2S_IISMOD: - return s->iismod; - case S5PC1XX_I2S_IISFIC: - return s->iisfic; - case S5PC1XX_I2S_IISPSR: - return s->iispsr; - case S5PC1XX_I2S_IISRXD: - /* TODO: Support receive data register */ - return 0; - case S5PC1XX_I2S_IISFICS: - return s->iisfics; - case S5PC1XX_I2S_IISAHB: - return s->iisahb; - case S5PC1XX_I2S_IISSTR: - return s->iisstr0; - case S5PC1XX_I2S_IISSIZE: - return s->iissize; - case S5PC1XX_I2S_IISTRNCNT: - return s->iistrncnt; - case S5PC1XX_I2S_IISADDR0: - return s->iislvl0addr; - case S5PC1XX_I2S_IISADDR1: - return s->iislvl1addr; - case S5PC1XX_I2S_IISADDR2: - return s->iislvl2addr; - case S5PC1XX_I2S_IISADDR3: - return s->iislvl3addr; - case S5PC1XX_I2S_IISSTR1: - return s->iisstr1; - default: - /* FIXME: all registers are accessible by byte */ - hw_error("s5pc1xx.i2s: bad write offset " TARGET_FMT_plx "\n", offset); - return 0; - } -} - -static CPUReadMemoryFunc * const s5pc1xx_i2s_readfn[] = { - s5pc1xx_i2s_read, - s5pc1xx_i2s_read, - s5pc1xx_i2s_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_i2s_writefn[] = { - s5pc1xx_i2s_write, - s5pc1xx_i2s_write, - s5pc1xx_i2s_write -}; - -static void s5pc1xx_i2s_save(QEMUFile *f, void *opaque) -{ - S5pc1xxI2SState *s = (S5pc1xxI2SState *)opaque; - - qemu_put_be32s(f, &s->iiscon); - qemu_put_be32s(f, &s->iismod); - qemu_put_be32s(f, &s->iisfic); - qemu_put_be32s(f, &s->iispsr); - qemu_put_be32s(f, &s->iisfics); - qemu_put_be32s(f, &s->iisahb); - qemu_put_be32s(f, &s->iisstr0); - qemu_put_be32s(f, &s->iissize); - qemu_put_be32s(f, &s->iistrncnt); - qemu_put_be32s(f, &s->iislvl0addr); - qemu_put_be32s(f, &s->iislvl1addr); - qemu_put_be32s(f, &s->iislvl2addr); - qemu_put_be32s(f, &s->iislvl3addr); - qemu_put_be32s(f, &s->iisstr1); - - qemu_put_buffer(f, s->buffer, s->buf_size); - - qemu_put_be32s(f, &s->buf_size); - qemu_put_be32s(f, &s->play_pos); - qemu_put_be32s(f, &s->last_free); -} - -static int s5pc1xx_i2s_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxI2SState *s = (S5pc1xxI2SState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->iiscon); - qemu_get_be32s(f, &s->iismod); - qemu_get_be32s(f, &s->iisfic); - qemu_get_be32s(f, &s->iispsr); - qemu_get_be32s(f, &s->iisfics); - qemu_get_be32s(f, &s->iisahb); - qemu_get_be32s(f, &s->iisstr0); - qemu_get_be32s(f, &s->iissize); - qemu_get_be32s(f, &s->iistrncnt); - qemu_get_be32s(f, &s->iislvl0addr); - qemu_get_be32s(f, &s->iislvl1addr); - qemu_get_be32s(f, &s->iislvl2addr); - qemu_get_be32s(f, &s->iislvl3addr); - qemu_get_be32s(f, &s->iisstr1); - - qemu_get_buffer(f, s->buffer, s->buf_size); - - qemu_get_be32s(f, &s->buf_size); - qemu_get_be32s(f, &s->play_pos); - qemu_get_be32s(f, &s->last_free); - - return 0; -} - -/* I2S init */ -DeviceState *s5pc1xx_i2s_init(target_phys_addr_t base, qemu_irq irq, - DeviceState *wm8994_dev, qemu_irq dma_irq1, - qemu_irq dma_irq2) -{ - DeviceState *dev = qdev_create(NULL, "s5pc1xx.i2s"); - - qdev_prop_set_ptr(dev, "wm8994", wm8994_dev); - qdev_init_nofail(dev); - sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); - sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); - sysbus_connect_irq(sysbus_from_qdev(dev), 1, dma_irq1); - sysbus_connect_irq(sysbus_from_qdev(dev), 2, dma_irq2); - return dev; -} - -static int s5pc1xx_i2s_init1(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxI2SState *s = FROM_SYSBUS(S5pc1xxI2SState, dev); - - sysbus_init_irq(dev, &s->irq); - sysbus_init_irq(dev, &s->dma_irq_stop1); - sysbus_init_irq(dev, &s->dma_irq_stop2); - - iomemtype = - cpu_register_io_memory(s5pc1xx_i2s_readfn, s5pc1xx_i2s_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_I2S_REG_MEM_SIZE, iomemtype); - s->buf_size = AUDIO_BUFFER_SIZE; - s->buffer = qemu_malloc(s->buf_size); - - s5pc1xx_i2s_reset(s); - qemu_register_reset(s5pc1xx_i2s_reset, s); - wm8994_data_req_set(s->wm8994, s5pc1xx_i2s_audio_callback, s); - - register_savevm(&dev->qdev, "s5pc1xx.i2s", -1, 1, - s5pc1xx_i2s_save, s5pc1xx_i2s_load, s); - - return 0; -} - -static SysBusDeviceInfo s5pc1xx_i2s_info = { - .init = s5pc1xx_i2s_init1, - .qdev.name = "s5pc1xx.i2s", - .qdev.size = sizeof(S5pc1xxI2SState), - .qdev.props = (Property[]) { - { - .name = "wm8994", - .info = &qdev_prop_ptr, - .offset = offsetof(S5pc1xxI2SState, wm8994), - }, - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_i2s_register_devices(void) -{ - sysbus_register_withprop(&s5pc1xx_i2s_info); -} - -device_init(s5pc1xx_i2s_register_devices) diff --git a/hw/s5pc1xx_jpeg.c b/hw/s5pc1xx_jpeg.c deleted file mode 100644 index d0d9495..0000000 --- a/hw/s5pc1xx_jpeg.c +++ /dev/null @@ -1,1034 +0,0 @@ -/* - * JPEG codec for S5PC110-based board emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "qemu-common.h" -#include "sysbus.h" - -#ifdef CONFIG_JPEG -#include -#include -#endif - -/* Control registers */ -#define JPGMOD 0x000 /* R/W Specifies the Sub-sampling Mode Register 0x0000_0000 */ - #define PROC_MODE (1 << 3) - -#define JPGOPR 0x004 /* R Specifies the Operation Status Register 0x0000_0000 */ -#define QTBL 0x008 /* R/W Specifies the Quantization Table Number Register 0x0000_0000 */ -#define HTBL 0x00C /* R/W Specifies the Huffman Table Number Register 0x0000_0000 */ -#define JPGDRI_U 0x010 /* R/W Specifies the MCU, which inserts RST marker(upper 8-bit) 0x0000_0000 */ -#define JPGDRI_L 0x014 /* R/W Specifies the MCU, which inserts RST marker (lower 8-bit) 0x0000_0000 */ -#define JPGY_U 0x018 /* R/W Specifies the Vertical Resolution (upper 8-bit) 0x0000_0000 */ -#define JPGY_L 0x01C /* R/W Specifies the Vertical Resolution (lower 8-bit) 0x0000_0000 */ -#define JPGX_U 0x020 /* R/W Specifies the Horizontal Resolution (upper 8-bit) 0x0000_0000 */ -#define JPGX_L 0x024 /* R/W Specifies the Horizontal Resolution (lower 8-bit) 0x0000_0000 */ -#define JPGCNT_U 0x028 /* R Specifies the amount of the compressed data in bytes (upper 8- bit) 0x0000_0000 */ -#define JPGCNT_M 0x02C /* R Specifies the amount of the compressed data in bytes (middle 8-bit) 0x0000_0000 */ -#define JPGCNT_L 0x030 /* R Specifies the amount of the compressed data in bytes (lower 8-bit) 0x0000_0000 */ -#define JPGINTSE 0x034 /* R/W Specifies the Interrupt Setting Register 0x0000_0000 */ -#define JPGINTST 0x038 /* R Specifies the Interrupt Status Register 0x0000_0000 */ - #define RESULT_STAT (1 << 6) - #define STREAM_STAT (1 << 5) - -#define JPGCOM 0x04C /* W Specifies the Command register 0x0000_0000 */ - #define INT_RELEASE (1 << 2) - -#define IMGADR 0x050 /* R/W Specifies the Source or Destination Image Address 0x0000_0000 */ -#define JPGADR 0x058 /* R/W Specifies the Source or Destination JPEG File Address 0x0000_0000 */ -#define COEF1 0x05C /* R/W Specifies the Coefficient Values for RGB <-> YCbCr Converter 0x0000_0000 */ -#define COEF2 0x060 /* R/W Specifies the Coefficient Values for RGB <-> YCbCr Converter 0x0000_0000 */ -#define COEF3 0x064 /* R/W Specifies the Coefficient Values for RGB <-> YCbCr Converter 0x0000_0000 */ -#define JPGCMOD 0x068 /* R/W Specifies the Mode Selection and Core Clock Setting 0x0000_0020 */ -#define JPGCLKCON 0x06C /* R/W Specifies the Power On/ Off and Clock Down Control 0x0000_0002 */ -#define JSTART 0x070 /* W Specifies the Start Compression or Decompression 0x0000_0000 */ -#define SW_RESET 0x078 /* R/W Specifies the S/W Reset 0x0000_0000 */ -#define TIMER_SE 0x07C /* R/W Specifies the Internal Timer Setting Register 0x7FFF_FFFF */ - #define TIMER_INT_EN (1 << 31) - -#define TIMER_ST 0x080 /* R/W Specifies the Internal Timer Status Register 0x7FFF_FFFF */ - #define TIMER_INT_STAT (1 << 31) - -#define COMSTAT 0x084 /* R Specifies the Command Status Register 0x0000_0000 */ -#define OUTFORM 0x088 /* R/W Specifies the Output Color Format of Decompression 0x0000_0000 */ -#define VERSION 0x08C /* R Specifies the Version Register 0x0000_0003 */ -#define ENC_STREAM_INTSE 0x098 /* R/W Specifies the Compressed Stream Size Interrupt Setting Register 0x00FF_FFE0 */ - #define ENC_STREAM_INT_EN (1 << 24) - -#define ENC_STREAM_INTST 0x09C /* R Specifies the Compressed Stream Size Interrupt Status Register 0x0000_0000 */ - #define ENC_STREAM_INT_STAT (1 << 0) - -#define QTBL0(n) (0x400 + (n << 2)) /* R/W Specifies the Quantization table 0 0x0000_0000 */ -#define QTBL1(n) (0x500 + (n << 2)) /* R/W Specifies the Quantization table 1 0x0000_0000 */ -#define QTBL2(n) (0x600 + (n << 2)) /* R/W Specifies the Quantization table 2 0x0000_0000 */ -#define QTBL3(n) (0x700 + (n << 2)) /* R/W Specifies the Quantization table 3 0x0000_0000 */ -#define HDCTBL0(n) (0x800 + (n << 2)) /* W Specifies the Huffman DC Table 0 - the number of code per code length 0x0000_0000 */ -#define HDCTBLG0(n) (0x840 + (n << 2)) /* W Specifies the Huffman DC Table 0 - Group number of the order for occurrence 0x0000_0000 */ -#define HACTBL0(n) (0x880 + (n << 2)) /* W Specifies the Huffman AC Table 0 - the number of code per code length 0x0000_0000 */ -#define HACTBLG0(n) (0x8C0 + (n << 2)) /* W Specifies the Huffman AC Table 0 - Group number of the order for occurrence 0x0000_0000 */ -#define HDCTBL1(n) (0xC00 + (n << 2)) /* W Specifies the Huffman DC Table 1 - the number of code per code length 0x0000_0000 */ -#define HDCTBLG1(n) (0xC40 + (n << 2)) /* W Specifies the Huffman DC Table 1 - Group number of the order for occurrence 0x0000_0000 */ -#define HACTBL1(n) (0xC80 + (n << 2)) /* W Specifies the Huffman AC Table 1 - the number of code per code length 0x0000_0000 */ -#define HACTBLG1(n) (0xCC0 + (n << 2)) /* W Specifies the Huffman AC Table 1 - Group number of the order for occurrence 0x0000_0000 */ - -#define S5PC1XX_JPEG_REG_MEM_SIZE 0xF48 - -/* FIXME: jpeg header size (8192 bytes) is an experimental value */ -#define JPEG_HDR_SIZE 8192 -#define MAX_IMG_SIZE (8192 * 8192 * 3) - -/* Control values */ -#define COMPR 0 -#define DECOMPR 1 - -#define YCbCr_422 (((4 + 2 + 2) * 2) | (16 << 5) | (8 << 10)) /* YCbCr4:2:2, x2 bits a sample, MCU block size = 16x8 */ -#define RGB_565 (5 + 6 + 5) /* RGB565, x1 bits a sample */ - -#define YCbCr_444 (((4 + 4 + 4) * 2) | (8 << 5) | (8 << 10)) -#define YCbCr_420 (((4 + 2 + 0) * 2) | (16 << 5) | (16 << 10)) -#define GRAY (((4 + 0 + 0) * 2) | (8 << 5) | (8 << 10)) - -#define JUST_RAISE_IRQ 0 -#define RESULT_INT (1 << 0) -#define STREAM_INT (1 << 1) -#define TIMER_INT (1 << 2) -#define ENC_STREAM_INT (1 << 3) - -#define LOW 1 -#define HIGH 0 -#define NONE 0 - -/* Arithmetical macroses */ -#define SIZE_OUT(value, min) ((((value) + (min) - 1) / (min)) * (min)) /* evaluate a length in 'min' units */ -#define ALL_BITS(b,a) (((1 << ((b) - (a) + 1)) - 1) << (a)) /* all bits from 'b' to 'a' are high */ - - -#ifdef CONFIG_JPEG -typedef struct jpeg_compress_struct CInfo; -typedef struct jpeg_decompress_struct DInfo; - -typedef struct Dummy_CInfo { - JDIMENSION image_width; - JDIMENSION image_height; - J_COLOR_SPACE in_color_space; - J_COLOR_SPACE jpeg_color_space; - struct comp_info { - int h_samp_factor; - int v_samp_factor; - } comp_info[3]; -} Dummy_CInfo; - -typedef struct Dummy_DInfo { - JDIMENSION image_width; - JDIMENSION image_height; - J_COLOR_SPACE out_color_space; -} Dummy_DInfo; -#endif - -typedef struct S5pc1xxJpegState { - SysBusDevice busdev; - qemu_irq irq; - uint8_t proc_mode, c1; - uint32_t byte_cnt, src_len, dst_len; - uint32_t mode_in, mode_out; - target_phys_addr_t src_addr, dst_addr; - char *src_base, *dst_base; - - /* Control registers */ - uint32_t jpgmod; - uint32_t jpgopr; - uint32_t qtbl; - uint32_t htbl; - uint32_t jpgdri_u; - uint32_t jpgdri_l; - uint32_t jpgy_u; - uint32_t jpgy_l; - uint32_t jpgx_u; - uint32_t jpgx_l; - uint32_t jpgintse; - uint32_t jpgintst; - uint32_t imgadr; - uint32_t jpgadr; - uint32_t coef1; - uint32_t coef2; - uint32_t coef3; - uint32_t jpgcmod; - uint32_t jpgclkcon; - uint32_t sw_reset; - uint32_t timer_se; - uint32_t timer_st; - uint32_t comstat; - uint32_t outform; - uint32_t version; - uint32_t enc_stream_intse; - uint32_t enc_stream_intst; - uint8_t qtbl0[64]; - uint8_t qtbl1[64]; - uint8_t qtbl2[64]; - uint8_t qtbl3[64]; - uint8_t hdctbl0[28]; - uint8_t hactbl0[178]; - uint8_t hdctbl1[28]; - uint8_t hactbl1[178]; - -#ifdef CONFIG_JPEG - /* Two structures below are used to protect corresponding values - * in CInfo and DInfo from overwriting */ - Dummy_CInfo *dummy_cinfo; - Dummy_DInfo *dummy_dinfo; - - CInfo *cinfo; - DInfo *dinfo; -#endif -} S5pc1xxJpegState; - -static void s5pc1xx_jpeg_irq(S5pc1xxJpegState *s, - uint8_t irq_stat, short to_clear); - -////////// Special code (only when configured with libjpeg support) ////////// - -#ifdef CONFIG_JPEG -/* Combine image properties before compression */ -static void s5pc1xx_jpeg_pre_coding(S5pc1xxJpegState *s) -{ - uint8_t src_color_mode, dst_color_mode; - uint16_t cols_out, rows_out; - - Dummy_CInfo *dummy_cinfo = s->dummy_cinfo; - - /* Input and output images addresses */ - s->src_addr = s->imgadr; - s->dst_addr = s->jpgadr; - - /* Input image area */ - dummy_cinfo->image_width = (s->jpgx_u << 8) | s->jpgx_l; - dummy_cinfo->image_height = (s->jpgy_u << 8) | s->jpgy_l; - - /* Coeff for color mode converting */ - s->c1 = (s->jpgcmod & 0x2) << 3; /* 0 or 16 */ - - /* Input image color mode */ - src_color_mode = (s->jpgcmod & ALL_BITS(7, 5)) >> 5; - switch (src_color_mode) { - case 0x1: - s->mode_in = YCbCr_422; - dummy_cinfo->in_color_space = JCS_YCbCr; - break; - case 0x2: - s->mode_in = RGB_565; - dummy_cinfo->in_color_space = JCS_RGB; - break; - default: - hw_error("s5pc1xx.jpeg: bad input color space (num = %u)\n", - src_color_mode); - } - - /* Input image size */ - s->src_len = (dummy_cinfo->image_width * (s->mode_in & ALL_BITS(4, 0)) * - dummy_cinfo->image_height) >> 3; - - /* Output image color mode */ - dst_color_mode = (s->jpgmod & ALL_BITS(2, 0)); - dummy_cinfo->comp_info[0].h_samp_factor = 2; - dummy_cinfo->comp_info[0].v_samp_factor = 2; - switch (dst_color_mode) { - case 0x1: - s->mode_out = YCbCr_422; - dummy_cinfo->jpeg_color_space = JCS_YCbCr; - dummy_cinfo->comp_info[1].h_samp_factor = 1; - dummy_cinfo->comp_info[1].v_samp_factor = 2; - dummy_cinfo->comp_info[2].h_samp_factor = 1; - dummy_cinfo->comp_info[2].v_samp_factor = 2; - break; - case 0x2: - s->mode_out = YCbCr_420; - dummy_cinfo->jpeg_color_space = JCS_YCbCr; - dummy_cinfo->comp_info[1].h_samp_factor = 1; - dummy_cinfo->comp_info[1].v_samp_factor = 1; - dummy_cinfo->comp_info[2].h_samp_factor = 1; - dummy_cinfo->comp_info[2].v_samp_factor = 1; - break; - default: - hw_error("s5pc1xx.jpeg: bad output color space (num = %u)\n", - dst_color_mode); - } - - /* Output image area */ - cols_out = SIZE_OUT(dummy_cinfo->image_width, - (s->mode_out >> 5) & ALL_BITS(4, 0)); - rows_out = SIZE_OUT(dummy_cinfo->image_height, - (s->mode_out >> 10) & ALL_BITS(4, 0)); - - /* Output image size */ - s->dst_len = JPEG_HDR_SIZE + - ((cols_out * (s->mode_out & ALL_BITS(4, 0)) * rows_out) >> 3); -} - -/* Calculate JPEG data size */ -static uint32_t s5pc1xx_jpeg_data_size(S5pc1xxJpegState *s) -{ - target_phys_addr_t page_size = TARGET_PAGE_SIZE; - uint8_t *jpg_Buf = NULL; - int i, j; - - s->dummy_dinfo->image_height = - s->dummy_dinfo->image_width = 0; - - /* Travel over all memory pages occupied by the image */ - for (i = 0, j = 1; i < (MAX_IMG_SIZE + JPEG_HDR_SIZE); i++) { - /* Map the first memory page or map the next memory page if less - * than 9 bytes till the end of the current one remains */ - if (!i || ((i % TARGET_PAGE_SIZE) > (TARGET_PAGE_SIZE - 9))) { - jpg_Buf = cpu_physical_memory_map(s->jpgadr, &page_size, 0); - if (!jpg_Buf || (page_size != TARGET_PAGE_SIZE * j)) { - fprintf(stderr, - "s5pc1xx.jpeg: input memory can't be accessed\n"); - /* Raise result interrupt as NOT OK */ - s5pc1xx_jpeg_irq(s, STREAM_INT, HIGH); - return 0; - } - j++; - page_size = TARGET_PAGE_SIZE * j; - } - - if (jpg_Buf[i] == 0xFF) { - if (jpg_Buf[i + 1] == 0xC0) { - s->dummy_dinfo->image_height = - (jpg_Buf[i + 5] << 8) | jpg_Buf[i + 6]; - s->dummy_dinfo->image_width = - (jpg_Buf[i + 7] << 8) | jpg_Buf[i + 8]; - } - if (jpg_Buf[i + 1] == 0xD9) - return (i + 2); /* Resulting size of the image */ - } - } - - fprintf(stderr, "s5pc1xx.jpeg: input image end can't be reached\n"); - /* Raise result interrupt as NOT OK */ - s5pc1xx_jpeg_irq(s, STREAM_INT, HIGH); - return 0; -} - -/* Combine image properties before decompression */ -static void s5pc1xx_jpeg_pre_decoding(S5pc1xxJpegState *s) -{ - uint8_t dst_color_mode; - uint16_t cols_out, rows_out; - - Dummy_DInfo *dummy_dinfo = s->dummy_dinfo; - - /* Input and output image addresses */ - s->src_addr = s->jpgadr; - s->dst_addr = s->imgadr; - - s->src_len = s5pc1xx_jpeg_data_size(s); - - /* Output image color mode */ - dst_color_mode = (s->outform & 0x1); - switch (dst_color_mode) { - case 0x0: - s->mode_out = YCbCr_422; - dummy_dinfo->out_color_space = JCS_YCbCr; - break; - case 0x1: - s->mode_out = YCbCr_420; - dummy_dinfo->out_color_space = JCS_YCbCr; - break; - default: - hw_error("s5pc1xx.jpeg: bad output color space (num = %u)\n", - dst_color_mode); - } - - /* Output image area */ - cols_out = SIZE_OUT(dummy_dinfo->image_width, - s->mode_out >> 5 & ALL_BITS(4, 0)); - rows_out = SIZE_OUT(dummy_dinfo->image_height, - s->mode_out >> 10 & ALL_BITS(4, 0)); - - /* Output image size */ - s->dst_len = (cols_out * (s->mode_out & ALL_BITS(4, 0)) * rows_out) >> 3; -} - -/* Get references to input and output data */ -static int s5pc1xx_jpeg_mem_map(S5pc1xxJpegState *s) -{ - target_phys_addr_t src_len, dst_len; - - src_len = s->src_len; - dst_len = s->dst_len; - - s->src_base = cpu_physical_memory_map(s->src_addr, &src_len, 0); - s->dst_base = cpu_physical_memory_map(s->dst_addr, &dst_len, 0); - - if (!s->src_base || !s->dst_base) { - fprintf(stderr, "s5pc1xx.jpeg: bad image address\n"); - /* Raise result interrupt as NOT OK */ - s5pc1xx_jpeg_irq(s, JUST_RAISE_IRQ, NONE); - return 1; - } - - if ((src_len == s->src_len) && (dst_len == s->dst_len)) - return 0; - - cpu_physical_memory_unmap(s->src_base, src_len, 0, 0); - cpu_physical_memory_unmap(s->dst_base, dst_len, 0, 0); - fprintf(stderr, "s5pc1xx.jpeg: not enough memory for image\n"); - /* Raise result interrupt as NOT OK */ - s5pc1xx_jpeg_irq(s, JUST_RAISE_IRQ, NONE); - return 1; -} - -/* JPEG compression */ -static void s5pc1xx_jpeg_coding(S5pc1xxJpegState *s) -{ - int row_stride, i; - struct jpeg_error_mgr jerr; - JSAMPROW row_pointer[1]; - - CInfo *cinfo = s->cinfo; - Dummy_CInfo *dummy_cinfo = s->dummy_cinfo; - - /* Allocate and initialize JPEG compression object */ - cinfo->err = jpeg_std_error(&jerr); - jpeg_create_compress(cinfo); - - cinfo->dest->next_output_byte = (JSAMPLE *) s->dst_base; - cinfo->dest->free_in_buffer = s->dst_len; - - /* RGB or YCbCr (3 components) can be used as compressor input color space - * according to s5pc1xx specification */ - cinfo->input_components = 3; - cinfo->image_width = dummy_cinfo->image_width; - cinfo->image_height = dummy_cinfo->image_height; - cinfo->in_color_space = dummy_cinfo->in_color_space; - - jpeg_set_defaults(cinfo); - - /* Note: using dummy_cinfo->jpeg_color_space instead of - * cinfo->jpeg_color_space because the second one is set by - * jpeg_set_defaults() and may be incorrect */ - jpeg_set_colorspace(cinfo, dummy_cinfo->jpeg_color_space); - -#if JPEG_LIB_VERSION >= 61 - - for (i = 0; i < 4; i++) { - cinfo->comp_info[i].quant_tbl_no = (s->qtbl >> (i * 2)) & 0x3; - cinfo->comp_info[i].dc_tbl_no = (s->htbl >> (i * 2)) & 0x1; - cinfo->comp_info[i].ac_tbl_no = (s->htbl >> (i * 2 + 1)) & 0x1; - } - - /* FIXME: force_baseline may be 'false' in the next four instructions */ - jpeg_add_quant_table (cinfo, 0, - (const unsigned int *) s->qtbl0, - 100, true); - jpeg_add_quant_table (cinfo, 1, - (const unsigned int *) s->qtbl1, - 100, true); - jpeg_add_quant_table (cinfo, 2, - (const unsigned int *) s->qtbl2, - 100, true); - jpeg_add_quant_table (cinfo, 3, - (const unsigned int *) s->qtbl3, - 100, true); - - cinfo->dc_huff_tbl_ptrs[0] = (JHUFF_TBL *) s->hdctbl0; - cinfo->ac_huff_tbl_ptrs[0] = (JHUFF_TBL *) s->hactbl0; - - cinfo->dc_huff_tbl_ptrs[1] = (JHUFF_TBL *) s->hdctbl1; - cinfo->ac_huff_tbl_ptrs[1] = (JHUFF_TBL *) s->hactbl1; - - jpeg_alloc_huff_table((j_common_ptr) cinfo); - -#endif - - for (i = 0; i < 3; i++) { - cinfo->comp_info[i].h_samp_factor = - dummy_cinfo->comp_info[i].h_samp_factor; - cinfo->comp_info[i].v_samp_factor = - dummy_cinfo->comp_info[i].v_samp_factor; - } - - jpeg_start_compress(cinfo, FALSE); - - /* JSAMPLEs per row in input_buffer */ - row_stride = cinfo->image_width * cinfo->input_components; - - while (cinfo->next_scanline < cinfo->image_height) { - row_pointer[0] = - (JSAMPROW) &s->src_base[cinfo->next_scanline * row_stride]; - (void) jpeg_write_scanlines(cinfo, row_pointer, 1); - } - - /* Finish compression */ - jpeg_finish_compress(cinfo); - jpeg_destroy_compress(cinfo); -} - -/* JPEG decompression */ -static void s5pc1xx_jpeg_decoding(S5pc1xxJpegState *s) -{ - struct jpeg_error_mgr jerr; - JSAMPARRAY buffer; /* Output row buffer */ - int row_stride; /* Physical row width in output buffer */ - int i, count; - - DInfo *dinfo = s->dinfo; - Dummy_DInfo *dummy_dinfo = s->dummy_dinfo; - - /* Allocate and initialize JPEG decompression object */ - dinfo->err = jpeg_std_error(&jerr); - jpeg_create_decompress(dinfo); - - dinfo->src->next_input_byte = (JSAMPLE *) s->src_base; - dinfo->src->bytes_in_buffer = s->src_len; - - (void) jpeg_read_header(dinfo, TRUE); - - dinfo->out_color_space = dummy_dinfo->out_color_space; - - (void) jpeg_start_decompress(dinfo); - - /* JSAMPLEs per row in output buffer */ - row_stride = dinfo->output_width * dinfo->output_components; - - /* Make a one-row-high sample array - * that will go away when done with image */ - buffer = (*(dinfo->mem->alloc_sarray)) - ((j_common_ptr) dinfo, JPOOL_IMAGE, row_stride, 1); - - count = 0; - while (dinfo->output_scanline < dinfo->output_height) { - (void) jpeg_read_scanlines(dinfo, buffer, 1); - - for (i = 0; i < row_stride; i++, count++) - s->dst_base[count] = (char) buffer[0][i]; - } - - /* Finish decompression */ - (void) jpeg_finish_decompress(dinfo); - jpeg_destroy_decompress(dinfo); -} -#endif - -//////////////////////////// Common code ////////////////////////////////////// - -/* Reset JPEG controller */ -static void s5pc1xx_jpeg_reset(void *opaque) -{ - S5pc1xxJpegState *s = (S5pc1xxJpegState *)opaque; - int i; - - s->jpgmod = 0x1; - s->jpgopr = 0x0; - s->qtbl = 0x0; - s->htbl = 0x0; - s->jpgdri_u = 0x0; - s->jpgdri_l = 0x0; - s->jpgy_u = 0x0; - s->jpgy_l = 0x0; - s->jpgx_u = 0x0; - s->jpgx_l = 0x0; - s->jpgintse = 0x0; - s->jpgintst = 0x0; - s->imgadr = 0x0; - s->jpgadr = 0x0; - s->coef1 = 0x0; - s->coef2 = 0x0; - s->coef3 = 0x0; - s->jpgcmod = 0x00000020; - s->jpgclkcon = 0x00000002; - s->sw_reset = 0x0; - s->timer_se = 0x7FFFFFFF; - s->timer_st = 0x7FFFFFFF; - s->comstat = 0x0; - s->outform = 0x0; - s->version = 0x00000003; - s->enc_stream_intse = 0x00FFFFE0; - s->enc_stream_intst = 0x0; - - for(i = 0; i < 178; i++) { - s->hactbl0[i] = 0x0; - s->hactbl1[i] = 0x0; - - if (i > 63) - continue; - - s->qtbl0[i] = 0x0; - s->qtbl1[i] = 0x0; - s->qtbl2[i] = 0x0; - s->qtbl3[i] = 0x0; - - if (i > 28) - continue; - - s->hdctbl0[i] = 0x0; - s->hdctbl1[i] = 0x0; - } -} - -/* Interrupts handler */ -static void s5pc1xx_jpeg_irq(S5pc1xxJpegState *s, - uint8_t irq_stat, short to_clear) -{ - switch(irq_stat) { - case JUST_RAISE_IRQ: - qemu_irq_raise(s->irq); - return; - case RESULT_INT: - if (to_clear) { - s->jpgintst &= ~RESULT_STAT; - break; - } - s->jpgintst |= RESULT_STAT; - qemu_irq_raise(s->irq); - return; - case STREAM_INT: - if (to_clear) { - s->jpgintst &= ~STREAM_STAT; - break; - } - s->jpgintst |= STREAM_STAT; - qemu_irq_raise(s->irq); - return; - case TIMER_INT: - if (to_clear) { - s->timer_st &= ~TIMER_INT_STAT; - break; - } - s->timer_st |= TIMER_INT_STAT; - if (s->timer_se & TIMER_INT_EN) - qemu_irq_raise(s->irq); - return; - case ENC_STREAM_INT: - if (to_clear) { - s->enc_stream_intst &= ~ENC_STREAM_INT_STAT; - break; - } - s->enc_stream_intst |= ENC_STREAM_INT_STAT; - if (s->enc_stream_intse & ENC_STREAM_INT_EN) - qemu_irq_raise(s->irq); - return; - default: - return; - } - - /* Lower irq if all states are clear */ - if (!((s->jpgintst & RESULT_STAT) | - (s->jpgintst & STREAM_STAT) | - (s->timer_st & TIMER_INT_STAT) | - (s->enc_stream_intst & ENC_STREAM_INT_STAT))) - qemu_irq_lower(s->irq); -} - -/* JPEG controller registers read */ -static uint32_t s5pc1xx_jpeg_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxJpegState *s = (S5pc1xxJpegState *)opaque; - - switch(offset) { - case JPGMOD: -#ifdef CONFIG_JPEG - if ((s->proc_mode == DECOMPR) && !s->jpgopr) { - if (s->dinfo->jpeg_color_space == JCS_GRAYSCALE) { - s->jpgmod = (s->jpgmod & ALL_BITS(31, 3)) | 0x3; - } else { - /* FIXME: the value below must be different - * depending on downsampling coefs */ - s->jpgmod = (s->jpgmod & ALL_BITS(31, 3)) | 0x0; - } - } -#endif - return s->jpgmod; - case JPGOPR: - return s->jpgopr; - case QTBL: - return s->qtbl; - case HTBL: - return s->htbl; - case JPGDRI_U: - return s->jpgdri_u; - case JPGDRI_L: - return s->jpgdri_l; - case JPGY_U: - return s->jpgy_u; - case JPGY_L: - return s->jpgy_l; - case JPGX_U: - return s->jpgx_u; - case JPGX_L: - return s->jpgx_l; - case JPGCNT_U: - if ((s->proc_mode & COMPR) && !s->jpgopr) - return (s->byte_cnt >> 16) & ALL_BITS(7, 0); - return 0; - case JPGCNT_M: - if ((s->proc_mode & COMPR) && !s->jpgopr) - return (s->byte_cnt >> 8) & ALL_BITS(7, 0); - return 0; - case JPGCNT_L: - if ((s->proc_mode & COMPR) && !s->jpgopr) - return (s->byte_cnt >> 0) & ALL_BITS(7, 0); - return 0; - case JPGINTSE: - return s->jpgintse; - case JPGINTST: - /* Set successful status if no operation is going on */ - if (!s->jpgopr) - s->jpgintst = 0x40; - return s->jpgintst; - case IMGADR: - return s->imgadr; - case JPGADR: - return s->jpgadr; - case COEF1: - return s->coef1; - case COEF2: - return s->coef2; - case COEF3: - return s->coef3; - case JPGCMOD: - return s->jpgcmod; - case JPGCLKCON: - return s->jpgclkcon; - case SW_RESET: - return s->sw_reset; - case TIMER_SE: - return s->timer_se; - case TIMER_ST: - return s->timer_st; - case COMSTAT: - return s->comstat; - case OUTFORM: - return s->outform; - case VERSION: - return s->version; - case ENC_STREAM_INTSE: - return s->enc_stream_intse; - case ENC_STREAM_INTST: - return s->enc_stream_intst; - case QTBL0(0) ... QTBL0(63): - return s->qtbl0[(offset - QTBL0(0)) >> 2]; - case QTBL1(0) ... QTBL1(63): - return s->qtbl1[(offset - QTBL1(0)) >> 2]; - case QTBL2(0) ... QTBL2(63): - return s->qtbl2[(offset - QTBL2(0)) >> 2]; - case QTBL3(0) ... QTBL3(63): - return s->qtbl3[(offset - QTBL3(0)) >> 2]; - default: - hw_error("s5pc1xx.jpeg: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -/* JPEG controller register write */ -static void s5pc1xx_jpeg_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - uint32_t old_val; - S5pc1xxJpegState *s = (S5pc1xxJpegState *)opaque; - - switch(offset) { - case JPGMOD: - old_val = s->jpgmod; - s->proc_mode = (value & PROC_MODE) ? DECOMPR : COMPR; - s->jpgmod = (s->proc_mode == COMPR) ? - value : - ((value & ALL_BITS(31, 3)) | (old_val & ALL_BITS(2, 0))); - break; - case QTBL: - s->qtbl = value; - break; - case HTBL: - s->htbl = value; - break; - case JPGDRI_U: - s->jpgdri_u = value; - break; - case JPGDRI_L: - s->jpgdri_l = value; - break; - case JPGY_U: - s->jpgy_u = value; - break; - case JPGY_L: - s->jpgy_l = value; - break; - case JPGX_U: - s->jpgx_u = value; - break; - case JPGX_L: - s->jpgx_l = value; - break; - case JPGINTSE: - s->jpgintse = value; - break; - case JPGCOM: - if (value & INT_RELEASE) { - s5pc1xx_jpeg_irq(s, RESULT_INT, LOW); - s5pc1xx_jpeg_irq(s, STREAM_INT, LOW); - } - break; - case IMGADR: - s->imgadr = value; - break; - case JPGADR: - s->jpgadr = value; - break; - case COEF1: - s->coef1 = value; - break; - case COEF2: - s->coef2 = value; - break; - case COEF3: - s->coef3 = value; - break; - case JPGCMOD: - s->jpgcmod = value; - break; - case JPGCLKCON: - s->jpgclkcon = value; - break; - case JSTART: - if (!value) - break; - s->jpgopr = 0x1; -#ifdef CONFIG_JPEG - switch(s->proc_mode) { - case COMPR: - s5pc1xx_jpeg_pre_coding(s); - if (s5pc1xx_jpeg_mem_map(s)) - break; - s5pc1xx_jpeg_coding(s); - s->byte_cnt = s5pc1xx_jpeg_data_size(s); - /* Raise result interrupt as OK */ - s5pc1xx_jpeg_irq(s, RESULT_INT, HIGH); - break; - case DECOMPR: - s5pc1xx_jpeg_pre_decoding(s); - if (!s->src_len) - break; - if (s5pc1xx_jpeg_mem_map(s)) - break; - s5pc1xx_jpeg_decoding(s); - /* Raise result interrupt as OK */ - s5pc1xx_jpeg_irq(s, RESULT_INT, HIGH); - break; - } -#endif - s->jpgopr = 0x0; - break; - case SW_RESET: - if (value) { - s->sw_reset = 0x1; - s5pc1xx_jpeg_reset(s); - } - s->sw_reset = 0x0; - break; - case TIMER_SE: - s->timer_se = value; - break; - case TIMER_ST: - s->timer_st = value; - if (value & TIMER_INT_STAT) - s5pc1xx_jpeg_irq(s, TIMER_INT, LOW); - break; - case OUTFORM: - s->outform = value; - break; - case ENC_STREAM_INTSE: - s->enc_stream_intse = value; - break; - case ENC_STREAM_INTST: - s->enc_stream_intst = value; - if (value & ENC_STREAM_INT_STAT) - s5pc1xx_jpeg_irq(s, ENC_STREAM_INT, LOW); - break; - case QTBL0(0) ... QTBL0(63): - s->qtbl0[(offset - QTBL0(0)) >> 2] = value & 0xFF; - break; - case QTBL1(0) ... QTBL1(63): - s->qtbl1[(offset - QTBL1(0)) >> 2] = value & 0xFF; - break; - case QTBL2(0) ... QTBL2(63): - s->qtbl2[(offset - QTBL2(0)) >> 2] = value & 0xFF; - break; - case QTBL3(0) ... QTBL3(63): - s->qtbl3[(offset - QTBL3(0)) >> 2] = value & 0xFF; - break; - case HDCTBL0(0) ... HDCTBL0(15): - s->hdctbl0[(offset - HDCTBL0(0)) >> 2] = value & 0xFF; - break; - case HDCTBLG0(0) ... HDCTBLG0(11): - s->hdctbl0[((offset - HDCTBLG0(0)) >> 2) + 16] = value & 0xFF; - break; - case HACTBL0(0) ... HACTBL0(15): - s->hactbl0[(offset - HACTBL0(0)) >> 2] = value & 0xFF; - break; - case HACTBLG0(0) ... HACTBLG0(161): - s->hactbl0[((offset - HACTBLG0(0)) >> 2) + 16] = value & 0xFF; - break; - case HDCTBL1(0) ... HDCTBL1(15): - s->hdctbl1[(offset - HDCTBL1(0)) >> 2] = value & 0xFF; - break; - case HDCTBLG1(0) ... HDCTBLG1(11): - s->hdctbl1[((offset - HDCTBLG1(0)) >> 2) + 16] = value & 0xFF; - break; - case HACTBL1(0) ... HACTBL1(15): - s->hactbl1[(offset - HACTBL1(0)) >> 2] = value & 0xFF; - break; - case HACTBLG1(0) ... HACTBLG1(161): - s->hactbl1[((offset - HACTBLG1(0)) >> 2) + 16] = value & 0xFF; - break; - default: - hw_error("s5pc1xx.jpeg: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_jpeg_readfn[] = { - s5pc1xx_jpeg_read, - s5pc1xx_jpeg_read, - s5pc1xx_jpeg_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_jpeg_writefn[] = { - s5pc1xx_jpeg_write, - s5pc1xx_jpeg_write, - s5pc1xx_jpeg_write -}; - -static void s5pc1xx_jpeg_save(QEMUFile *f, void *opaque) -{ - S5pc1xxJpegState *s = (S5pc1xxJpegState *)opaque; - - if (s->jpgopr) - hw_error("s5pc1xx.jpeg: JPEG process is going on, " - "saving snapshot is not possible\n"); - - qemu_put_8s(f, &s->proc_mode); - - qemu_put_be32s(f, &s->jpgmod); - qemu_put_be32s(f, &s->jpgopr); - qemu_put_be32s(f, &s->qtbl); - qemu_put_be32s(f, &s->htbl); - qemu_put_be32s(f, &s->jpgdri_u); - qemu_put_be32s(f, &s->jpgdri_l); - qemu_put_be32s(f, &s->jpgy_u); - qemu_put_be32s(f, &s->jpgy_l); - qemu_put_be32s(f, &s->jpgx_u); - qemu_put_be32s(f, &s->jpgx_l); - qemu_put_be32s(f, &s->jpgintse); - qemu_put_be32s(f, &s->jpgintst); - qemu_put_be32s(f, &s->imgadr); - qemu_put_be32s(f, &s->jpgadr); - qemu_put_be32s(f, &s->coef1); - qemu_put_be32s(f, &s->coef2); - qemu_put_be32s(f, &s->coef3); - qemu_put_be32s(f, &s->jpgcmod); - qemu_put_be32s(f, &s->jpgclkcon); - qemu_put_be32s(f, &s->sw_reset); - qemu_put_be32s(f, &s->timer_se); - qemu_put_be32s(f, &s->timer_st); - qemu_put_be32s(f, &s->comstat); - qemu_put_be32s(f, &s->outform); - qemu_put_be32s(f, &s->version); - qemu_put_be32s(f, &s->enc_stream_intse); - qemu_put_be32s(f, &s->enc_stream_intst); - - qemu_put_buffer(f, s->qtbl0, sizeof(s->qtbl0)); - qemu_put_buffer(f, s->qtbl1, sizeof(s->qtbl1)); - qemu_put_buffer(f, s->qtbl2, sizeof(s->qtbl2)); - qemu_put_buffer(f, s->qtbl3, sizeof(s->qtbl3)); - qemu_put_buffer(f, s->hdctbl0, sizeof(s->hdctbl0)); - qemu_put_buffer(f, s->hactbl0, sizeof(s->hactbl0)); - qemu_put_buffer(f, s->hdctbl1, sizeof(s->hdctbl1)); - qemu_put_buffer(f, s->hactbl1, sizeof(s->hactbl1)); -} - -static int s5pc1xx_jpeg_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxJpegState *s = (S5pc1xxJpegState *)opaque; - - if (version_id != 1) - return -EINVAL; - - qemu_get_8s(f, &s->proc_mode); - - qemu_get_be32s(f, &s->jpgmod); - qemu_get_be32s(f, &s->jpgopr); - qemu_get_be32s(f, &s->qtbl); - qemu_get_be32s(f, &s->htbl); - qemu_get_be32s(f, &s->jpgdri_u); - qemu_get_be32s(f, &s->jpgdri_l); - qemu_get_be32s(f, &s->jpgy_u); - qemu_get_be32s(f, &s->jpgy_l); - qemu_get_be32s(f, &s->jpgx_u); - qemu_get_be32s(f, &s->jpgx_l); - qemu_get_be32s(f, &s->jpgintse); - qemu_get_be32s(f, &s->jpgintst); - qemu_get_be32s(f, &s->imgadr); - qemu_get_be32s(f, &s->jpgadr); - qemu_get_be32s(f, &s->coef1); - qemu_get_be32s(f, &s->coef2); - qemu_get_be32s(f, &s->coef3); - qemu_get_be32s(f, &s->jpgcmod); - qemu_get_be32s(f, &s->jpgclkcon); - qemu_get_be32s(f, &s->sw_reset); - qemu_get_be32s(f, &s->timer_se); - qemu_get_be32s(f, &s->timer_st); - qemu_get_be32s(f, &s->comstat); - qemu_get_be32s(f, &s->outform); - qemu_get_be32s(f, &s->version); - qemu_get_be32s(f, &s->enc_stream_intse); - qemu_get_be32s(f, &s->enc_stream_intst); - - qemu_get_buffer(f, s->qtbl0, sizeof(s->qtbl0)); - qemu_get_buffer(f, s->qtbl1, sizeof(s->qtbl1)); - qemu_get_buffer(f, s->qtbl2, sizeof(s->qtbl2)); - qemu_get_buffer(f, s->qtbl3, sizeof(s->qtbl3)); - qemu_get_buffer(f, s->hdctbl0, sizeof(s->hdctbl0)); - qemu_get_buffer(f, s->hactbl0, sizeof(s->hactbl0)); - qemu_get_buffer(f, s->hdctbl1, sizeof(s->hdctbl1)); - qemu_get_buffer(f, s->hactbl1, sizeof(s->hactbl1)); - - return 0; -} - -/* JPEG initialization */ -static int s5pc1xx_jpeg_init(SysBusDevice *dev) -{ - int iomemtype; - - S5pc1xxJpegState *s = FROM_SYSBUS(S5pc1xxJpegState, dev); - s5pc1xx_jpeg_reset(s); - -#ifdef CONFIG_JPEG - s->cinfo = (CInfo *) qemu_mallocz(sizeof(CInfo)); - s->dinfo = (DInfo *) qemu_mallocz(sizeof(DInfo)); - s->dummy_cinfo = (Dummy_CInfo *) qemu_mallocz(sizeof(Dummy_CInfo)); - s->dummy_dinfo = (Dummy_DInfo *) qemu_mallocz(sizeof(Dummy_DInfo)); -#endif - - sysbus_init_irq(dev, &s->irq); - iomemtype = - cpu_register_io_memory(s5pc1xx_jpeg_readfn, s5pc1xx_jpeg_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_JPEG_REG_MEM_SIZE, iomemtype); - - qemu_register_reset(s5pc1xx_jpeg_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.jpeg", -1, 1, - s5pc1xx_jpeg_save, s5pc1xx_jpeg_load, s); - return 0; -} - -static void s5pc1xx_jpeg_register(void) -{ - sysbus_register_dev("s5pc1xx.jpeg", sizeof(S5pc1xxJpegState), - s5pc1xx_jpeg_init); -} - -device_init(s5pc1xx_jpeg_register) diff --git a/hw/s5pc1xx_keyif.c b/hw/s5pc1xx_keyif.c deleted file mode 100644 index e46a874..0000000 --- a/hw/s5pc1xx_keyif.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * S5PC1XX Keypad Interface - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Alexey Merkulov - */ - -#include "console.h" -#include "s5pc1xx.h" -#include "s5pc1xx_gpio_regs.h" -#include "sysbus.h" - - -#define KEY_RESERVED 0 -#define KEY_ESC 1 -#define KEY_1 2 -#define KEY_2 3 -#define KEY_3 4 -#define KEY_4 5 -#define KEY_5 6 -#define KEY_6 7 -#define KEY_7 8 -#define KEY_8 9 -#define KEY_9 10 -#define KEY_0 11 -#define KEY_MINUS 12 -#define KEY_EQUAL 13 -#define KEY_BACKSPACE 14 -#define KEY_TAB 15 -#define KEY_Q 16 -#define KEY_W 17 -#define KEY_E 18 -#define KEY_R 19 -#define KEY_T 20 -#define KEY_Y 21 -#define KEY_U 22 -#define KEY_I 23 -#define KEY_O 24 -#define KEY_P 25 -#define KEY_LEFTBRACE 26 -#define KEY_RIGHTBRACE 27 -#define KEY_ENTER 28 -#define KEY_LEFTCTRL 29 -#define KEY_A 30 -#define KEY_S 31 -#define KEY_D 32 -#define KEY_F 33 -#define KEY_G 34 -#define KEY_H 35 -#define KEY_J 36 -#define KEY_K 37 -#define KEY_L 38 -#define KEY_SEMICOLON 39 -#define KEY_APOSTROPHE 40 -#define KEY_GRAVE 41 -#define KEY_LEFTSHIFT 42 -#define KEY_BACKSLASH 43 -#define KEY_Z 44 -#define KEY_X 45 -#define KEY_C 46 -#define KEY_V 47 -#define KEY_B 48 -#define KEY_N 49 -#define KEY_M 50 -#define KEY_COMMA 51 -#define KEY_DOT 52 -#define KEY_SLASH 53 -#define KEY_RIGHTSHIFT 54 -#define KEY_KPASTERISK 55 -#define KEY_LEFTALT 56 -#define KEY_SPACE 57 -#define KEY_CAPSLOCK 58 -#define KEY_F1 59 -#define KEY_F2 60 -#define KEY_F3 61 -#define KEY_F4 62 -#define KEY_F5 63 -#define KEY_F6 64 -#define KEY_F7 65 -#define KEY_F8 66 -#define KEY_F9 67 -#define KEY_F10 68 -#define KEY_NUMLOCK 69 -#define KEY_SCROLLLOCK 70 -#define KEY_KP7 71 -#define KEY_KP8 72 -#define KEY_KP9 73 -#define KEY_KPMINUS 74 -#define KEY_KP4 75 -#define KEY_KP5 76 -#define KEY_KP6 77 -#define KEY_KPPLUS 78 -#define KEY_KP1 79 -#define KEY_KP2 80 -#define KEY_KP3 81 -#define KEY_KP0 82 -#define KEY_KPDOT 83 - -#define KEY_ZENKAKUHANKAKU 85 -#define KEY_102ND 86 -#define KEY_F11 87 -#define KEY_F12 88 -#define KEY_RO 89 -#define KEY_KATAKANA 90 -#define KEY_HIRAGANA 91 -#define KEY_HENKAN 92 -#define KEY_KATAKANAHIRAGANA 93 -#define KEY_MUHENKAN 94 -#define KEY_KPJPCOMMA 95 -#define KEY_KPENTER 96 -#define KEY_RIGHTCTRL 97 -#define KEY_KPSLASH 98 -#define KEY_SYSRQ 99 -#define KEY_RIGHTALT 100 -#define KEY_LINEFEED 101 -#define KEY_HOME 102 -#define KEY_UP 103 -#define KEY_PAGEUP 104 -#define KEY_LEFT 105 -#define KEY_RIGHT 106 -#define KEY_END 107 -#define KEY_DOWN 108 -#define KEY_PAGEDOWN 109 -#define KEY_INSERT 110 -#define KEY_DELETE 111 -#define KEY_MACRO 112 -#define KEY_MUTE 113 -#define KEY_VOLUMEDOWN 114 -#define KEY_VOLUMEUP 115 -#define KEY_POWER 116 /* SC System Power Down */ -#define KEY_KPEQUAL 117 -#define KEY_KPPLUSMINUS 118 -#define KEY_PAUSE 119 -#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */ - -#define KEY_KPCOMMA 121 -#define KEY_HANGEUL 122 -#define KEY_HANGUEL KEY_HANGEUL -#define KEY_HANJA 123 -#define KEY_YEN 124 -#define KEY_LEFTMETA 125 -#define KEY_RIGHTMETA 126 -#define KEY_COMPOSE 127 - -#define ROW_NUM 14 -#define COLUMN_NUM 8 -#define ROW_INIT 0x3FFF -#define KEY_MAX_NUMBER 128 -#define S5PC1XX_KEYIF_REG_MEM_SIZE 0x14 - -struct keymap { - int column; - int row; -}; - -typedef struct S5pc1xxKeyIFState { - SysBusDevice busdev; - - /* Specifies the KEYPAD interface control register */ - union { - /* raw register data */ - uint32_t v; - - /* register bits */ - struct keyifcon_bits { - unsigned int_f_en : 1; - unsigned int_r_en : 1; - unsigned df_en : 1; - unsigned fc_en : 1; - unsigned wakeupen : 1; - } b; - } keyifcon; - - /* Specifies the KEYPAD interface status and clear register */ - union { - /* raw register data */ - uint32_t v; - - /* register bits */ - struct keyifstsclr_bits { - unsigned p_int : 14; - unsigned reserved14_15 : 2; - unsigned r_int : 14; - } b; - } keyifstsclr; - - /* Specifies the KEYPAD interface column data output register */ - union { - /* raw register data */ - uint32_t v; - - /* register bits */ - struct keyifcol_bits { - unsigned keyifcol : 8; - unsigned keyifcolen : 8; - } b; - } keyifcol; - - /* Specifies the KEYPAD interface row data input register */ - uint32_t keyifrow; - - /* Specifies the KEYPAD interface debouncing filter clock - * division register */ - uint32_t keyiffc; - - qemu_irq irq_keypad; - - /* The keypad supports 14 rows and 8 columns */ - uint16_t keypad[COLUMN_NUM]; - - /* S5PC110 may have a shift of KEYIFCOL register values */ - uint32_t shift; - - /* Name of the keymap used */ - char *keymapname; - - /* Mapping from QEMU keycodes to keypad row-column; filled at device init */ - struct keymap map[KEY_MAX_NUMBER]; -} S5pc1xxKeyIFState; - - -/* Mapping variants for QEMU keycodes */ -static int msm_keycode[COLUMN_NUM][ROW_NUM] = { - {1, 2, KEY_1, KEY_Q, KEY_A, 6, 7, KEY_KP4 /*KEY_LEFT*/, 64, 65, 66, 67, 68, 69}, - {9, 10, KEY_2, KEY_W, KEY_S, KEY_Z, KEY_KP6 /*KEY_RIGHT*/, 16, 70, 71, 72, 73, 74, 75}, - {17, 18, KEY_3, KEY_E, KEY_D, KEY_X, 23, KEY_KP8 /*KEY_UP*/, 76, 77, 78, 79, 80, 81}, - {25, 26, KEY_4, KEY_R, KEY_F, KEY_C, 31, 32, 82, 83, 84, 85, 86, 87}, - {33, KEY_O, KEY_5, KEY_T, KEY_G, KEY_V, KEY_KP2 /*KEY_DOWN*/, KEY_BACKSPACE, 88, 89, 90, 91, 92, 93}, - {KEY_P, KEY_0, KEY_6, KEY_Y, KEY_H, KEY_SPACE, 47, 48, 94, 95, 96, 97, 98, 99}, - {KEY_M, KEY_L, KEY_7, KEY_U, KEY_J, KEY_N, 55, KEY_ENTER, 100, 101, 102, 103, 104, 105}, - {KEY_LEFTSHIFT, KEY_9, KEY_8, KEY_I, KEY_K, KEY_B, 63, KEY_COMMA, 106, 107, 108, 109, 110, 111} -}; - -static int int_keycode[COLUMN_NUM][ROW_NUM] = { - {1, 2, KEY_1, KEY_Q, KEY_A, 6, 7, KEY_KP4 /*KEY_LEFT*/}, - {9, 10, KEY_2, KEY_W, KEY_S, KEY_Z, KEY_KP6 /*KEY_RIGHT*/, 16}, - {17, 18, KEY_3, KEY_E, KEY_D, KEY_X, 23, KEY_KP8 /*KEY_UP*/}, - {25, 26, KEY_4, KEY_R, KEY_F, KEY_C, 31, 32}, - {33, KEY_O, KEY_5, KEY_T, KEY_G, KEY_V, KEY_KP2 /*KEY_DOWN*/, KEY_BACKSPACE}, - {KEY_P, KEY_0, KEY_6, KEY_Y, KEY_H, KEY_SPACE, 47, 48}, - {KEY_M, KEY_L, KEY_7, KEY_U, KEY_J, KEY_N, 55, KEY_ENTER}, - {KEY_LEFTSHIFT, KEY_9, KEY_8, KEY_I, KEY_K, KEY_B, 63, KEY_COMMA} -}; - -static int aquila_keycode[COLUMN_NUM][ROW_NUM] = { - {KEY_TAB /*KEY_CAMERA*/, KEY_ESC /*KEY_CONFIG*/}, - {KEY_EQUAL /*KEY_VOLUMEUP*/, KEY_MINUS /*KEY_VOLUMEDOWN*/} -}; - - -static void s5pc1xx_keyif_reset(DeviceState *d) -{ - S5pc1xxKeyIFState *s = - FROM_SYSBUS(S5pc1xxKeyIFState, sysbus_from_qdev(d)); - int i = 0; - - s->keyifcon.v = 0x00000000; - s->keyifstsclr.v = 0x00000000; - s->keyifcol.v = 0x00000000; - s->keyifrow = 0x00000000; - s->keyiffc = 0x00000000; - - for (i = 0; i < COLUMN_NUM; i++) { - s->keypad[i] = ROW_INIT; - } -} - -static int s5pc1xx_keypad_event(void *opaque, int keycode) -{ - S5pc1xxKeyIFState *s = (S5pc1xxKeyIFState *)opaque; - struct keymap k = {0, 0}; - int rel = 0; - - rel = (keycode & 0x80) ? 1 : 0; /* key release from qemu */ - keycode &= ~(0x80); /* strip qemu key release bit */ - - assert(keycode < KEY_MAX_NUMBER); - - k = s->map[keycode]; - - /* don't report unknown keypress */ - if (k.column < 0 || k.row < 0) { - return -1; - } - - if (rel) { - s->keypad[k.column] |= 1 << k.row; - } else { - s->keypad[k.column] &= ~(1 << k.row); - } - - if (rel && s->keyifcon.b.int_r_en) { - qemu_irq_raise(s->irq_keypad); - s->keyifstsclr.b.r_int = 1; - } - - if (!rel && s->keyifcon.b.int_f_en) { - qemu_irq_raise(s->irq_keypad); - s->keyifstsclr.b.p_int = 1; - } - - return 0; -} - -/* Read KEYIF by GPIO */ -static uint32_t s5pc1xx_keyif_gpio_read(void *opaque, - int io_index) -{ - S5pc1xxKeyIFState *s = (S5pc1xxKeyIFState *)opaque; - int i; - - for (i = 0; i < COLUMN_NUM; i++) { - if (io_index == GPIO_KP_COL(i)) { - return s->keyifcol.v >> i; - } - } - - for (i = 0; i < ROW_NUM; i++) { - if (io_index == GPIO_KP_ROW(i)) { - return s->keyifrow >> i; - } - } - - return 0; -} - -/* Write KEYIF by GPIO */ -static void s5pc1xx_keyif_gpio_write(void *opaque, - int io_index, - uint32_t value) -{ - S5pc1xxKeyIFState *s = (S5pc1xxKeyIFState *)opaque; - int i; - - for (i = 0; i < COLUMN_NUM; i++) { - if (io_index == GPIO_KP_COL(i)) { - s->keyifcol.v |= value << i; - } - } -} - -static GPIOReadMemoryFunc *s5pc1xx_keyif_gpio_readfn = s5pc1xx_keyif_gpio_read; -static GPIOWriteMemoryFunc *s5pc1xx_keyif_gpio_writefn = s5pc1xx_keyif_gpio_write; - -static uint32_t s5pc1xx_keyif_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxKeyIFState *s = (S5pc1xxKeyIFState *)opaque; - - switch (offset) { - case 0x00: /* KEYIFCON */ - return s->keyifcon.v; - case 0x04: /* KEYIFSTSCLR */ - return s->keyifstsclr.v; - case 0x08: /* KEYIFCOL */ - return s->keyifcol.v << s->shift; - case 0x0C: /* KEYIFROW */ - return s->keyifrow; - case 0x10: /* KEYIFFC */ - return s->keyiffc; - default: - hw_error("s5pc1xx.keyif: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static void s5pc1xx_keyif_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxKeyIFState *s = (S5pc1xxKeyIFState *)opaque; - struct keyifstsclr_bits* v = NULL; - int i = 0; - - switch (offset) { - case 0x00: /* KEYIFCON */ - s->keyifcon.v = val; - break; - case 0x04: /* KEYIFSTSCLR */ - v = (struct keyifstsclr_bits*)&val; - if (v->p_int) { - s->keyifstsclr.b.p_int = 0; - qemu_irq_lower(s->irq_keypad); - } - if (v->r_int) { - s->keyifstsclr.b.r_int = 0; - qemu_irq_lower(s->irq_keypad); - } - break; - case 0x08: /* KEYIFCOL */ - s->keyifcol.v = (val >> s->shift) & ~0xFF00; - s->keyifrow = ROW_INIT; /* 14 bit */ - /* FIXME: implement keyifcolen handling */ - for (i = 0; i < COLUMN_NUM; i++) { - if (!(s->keyifcol.b.keyifcol & (1 << i))) { - s->keyifrow &= s->keypad[i]; - } - } - break; - case 0x0C: /* KEYIFROW */ - /* Read-only */ - break; - case 0x10: /* KEYIFFC */ - s->keyiffc = val; - break; - default: - hw_error("s5pc1xx.keyif: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_keyif_mm_read[] = { - s5pc1xx_keyif_read, - s5pc1xx_keyif_read, - s5pc1xx_keyif_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_keyif_mm_write[] = { - s5pc1xx_keyif_write, - s5pc1xx_keyif_write, - s5pc1xx_keyif_write -}; - -static void s5pc1xx_keyif_save(QEMUFile *f, void *opaque) -{ - S5pc1xxKeyIFState *s = (S5pc1xxKeyIFState *)opaque; - int i; - - qemu_put_be32s(f, &s->keyifcon.v); - qemu_put_be32s(f, &s->keyifstsclr.v); - qemu_put_be32s(f, &s->keyifcol.v); - - qemu_put_be32s(f, &s->keyifrow); - qemu_put_be32s(f, &s->keyiffc); - - for (i = 0; i < COLUMN_NUM; i++) { - qemu_put_be16s(f, &s->keypad[i]); - } -} - -static int s5pc1xx_keyif_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxKeyIFState *s = (S5pc1xxKeyIFState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->keyifcon.v); - qemu_get_be32s(f, &s->keyifstsclr.v); - qemu_get_be32s(f, &s->keyifcol.v); - - qemu_get_be32s(f, &s->keyifrow); - qemu_get_be32s(f, &s->keyiffc); - - for (i = 0; i < COLUMN_NUM; i++) { - qemu_get_be16s(f, &s->keypad[i]); - } - - return 0; -} - -static void s5pc1xx_init_keymap(S5pc1xxKeyIFState *s) -{ - int i, j; - struct keymap init = {-1, -1}; - int (*keypad_keycode)[COLUMN_NUM][ROW_NUM]; - - for (i = 0; i < KEY_MAX_NUMBER; i++) { - s->map[i] = init; - } - - /* Look for the keymap with corresponding name */ - if (s->keymapname == NULL || !strcmp(s->keymapname, "msm")) { - /* Default one */ - keypad_keycode = &msm_keycode; - } else if (!strcmp(s->keymapname, "int")) { - keypad_keycode = &int_keycode; - } else if (!strcmp(s->keymapname, "aquila")) { - keypad_keycode = &aquila_keycode; - } else { - hw_error("s5pc1xx.keyif: unknown keymap '%s'", s->keymapname); - } - - for (i = 0; i < COLUMN_NUM; i++) { - for (j = 0; j < ROW_NUM; j++) { - struct keymap k = {i, j}; - s->map[(*keypad_keycode)[i][j]] = k; - } - } -} - -DeviceState *s5pc1xx_keyif_init(target_phys_addr_t base, qemu_irq irq, - const char *keymapname, uint32_t shift) -{ - DeviceState *dev = qdev_create(NULL, "s5pc1xx.keyif"); - - qdev_prop_set_uint32(dev, "shift", shift); - qdev_prop_set_string(dev, "keymap", (char *)keymapname); - qdev_init_nofail(dev); - sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); - sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); - return dev; -} - -static int s5pc1xx_keyif_init1(SysBusDevice *dev) -{ - S5pc1xxKeyIFState *s = FROM_SYSBUS(S5pc1xxKeyIFState, dev); - int iomemtype; - - sysbus_init_irq(dev, &s->irq_keypad); - iomemtype = cpu_register_io_memory(s5pc1xx_keyif_mm_read, - s5pc1xx_keyif_mm_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_KEYIF_REG_MEM_SIZE, iomemtype); - - s5pc1xx_gpio_register_io_memory(GPIO_IDX_KEYIF, 0, - s5pc1xx_keyif_gpio_readfn, - s5pc1xx_keyif_gpio_writefn, NULL, s); - s5pc1xx_init_keymap(s); - qemu_add_kbd_event_handler(s5pc1xx_keypad_event, s, "Keypad"); - - s5pc1xx_keyif_reset(&s->busdev.qdev); - - register_savevm(&dev->qdev, "s5pc1xx.keyif", -1, 1, - s5pc1xx_keyif_save, s5pc1xx_keyif_load, s); - - return 0; -} - -static SysBusDeviceInfo s5pc1xx_keyif_info = { - .init = s5pc1xx_keyif_init1, - .qdev.name = "s5pc1xx.keyif", - .qdev.size = sizeof(S5pc1xxKeyIFState), - .qdev.reset = s5pc1xx_keyif_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_STRING("keymap", S5pc1xxKeyIFState, keymapname), - DEFINE_PROP_UINT32("shift", S5pc1xxKeyIFState, shift, 0), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_keyif_register(void) -{ - sysbus_register_withprop(&s5pc1xx_keyif_info); -} - -device_init(s5pc1xx_keyif_register) diff --git a/hw/s5pc1xx_lcd.c b/hw/s5pc1xx_lcd.c deleted file mode 100644 index 3428901..0000000 --- a/hw/s5pc1xx_lcd.c +++ /dev/null @@ -1,1505 +0,0 @@ -/* - * S5PC1XX LCD Controller - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Kirill Batuzov - */ - -/* - * Known issues: - * multiple windows blending - implemented but not tested - * shadow registers - not implemented - * i80 indirect interface - not implemented - * dithering - not implemented - * RTQoS - not implemented - */ - -#include "console.h" -#include "pixel_ops.h" -#include "s5pc1xx.h" -#include "sysbus.h" - - -#define BISWP 0x8 -#define BYSWP 0x4 -#define HWSWP 0x2 -#define WSWP 0x1 - - -typedef struct { - uint8_t r, g, b; - uint32_t a; -} rgba; - -struct DrawConfig; - -typedef void pixel_to_rgb_func(uint32_t pixel, rgba *p); -typedef void draw_line_func(struct DrawConfig *cfg, uint8_t *src, - uint8_t *dst, uint8_t *ifb); -typedef uint32_t coef_func(const struct DrawConfig *cfg, rgba pa, rgba pb); - -typedef struct DrawConfig { - pixel_to_rgb_func *pixel_to_rgb; - draw_line_func *draw_line; - int (*put_pixel)(rgba p, uint8_t *pixel); - int (*get_pixel)(uint8_t *src, rgba *p); - void (*blend)(struct DrawConfig *cfg, rgba p_old, rgba p_new, rgba *p); - coef_func *coef_p, *coef_q, *coef_a, *coef_b; - uint8_t is_palletized; - uint32_t bg_alpha[2], fg_alpha[2]; - uint32_t color_key, color_mask, color_ctl; - uint8_t fg_alpha_pix, bg_alpha_pix; - int width; - int bpp; - uint32_t *palette; - uint8_t swap; - uint8_t fg_pixel_blending, bg_pixel_blending; - uint8_t fg_alpha_sel, bg_alpha_sel; -} DrawConfig; - -typedef struct S5pc1xxLcdWindow { - uint32_t wincon; - uint32_t vidosd[4]; - uint32_t buf_start[2]; - uint32_t buf_end[2]; - uint32_t buf_size; - uint32_t keycon[2]; - uint32_t winmap; - uint32_t vidw_alpha[2]; - uint32_t blendeq; - uint32_t palette[256]; -} S5pc1xxLcdWindow; - -typedef struct { - SysBusDevice busdev; - - uint32_t shadowcon; - uint32_t vidcon[3]; - uint32_t prtcon; - uint32_t vidtcon[3]; - uint32_t vp1tcon[2]; - uint32_t vidintcon[2]; - uint32_t dithcon; - uint32_t wpalcon[2]; - uint32_t trigcon; - uint32_t ituifcon; - uint32_t i80ifcon[4]; - uint32_t ldi_cmdcon[2]; - uint32_t sifccon[3]; - uint32_t blendcon; - uint32_t ldi_cmd[12]; - uint32_t dualrgb; - - S5pc1xxLcdWindow window[5]; - uint8_t *ifb; - uint8_t *valid_line; - uint8_t *valid_line_prev; - DisplayState *console; - uint8_t invalidate; - qemu_irq irq[3]; -} S5pc1xxLcdState; - - -/* Palette/pixel to RGB conversion */ - -#define DEF_PIXEL_TO_RGB(N,R,G,B,A) \ -static void N(uint32_t pixel, rgba *p) \ -{ \ - p->b = (pixel & ((1 << (B)) - 1)) << (8 - (B)); \ - pixel >>= (B); \ - p->g = (pixel & ((1 << (G)) - 1)) << (8 - (G)); \ - pixel >>= (G); \ - p->r = (pixel & ((1 << (R)) - 1)) << (8 - (R)); \ - pixel >>= (R); \ - if (1 == (A)) { \ - p->a = pixel & 1; \ - } else if (8 == (A)) { \ - p->a = pixel & 0xFF; \ - p->a = (p->a << 16) | (p->a << 8) | p->a; \ - } else { \ - p->a = (pixel & ((1 << (A)) - 1)) << (8 - (A)); \ - } \ -} - -DEF_PIXEL_TO_RGB(pixel_a232_to_rgb, 2, 3, 2, 1) -DEF_PIXEL_TO_RGB(pixel_a444_to_rgb, 4, 4, 4, 1) -DEF_PIXEL_TO_RGB(pixel_4444_to_rgb, 4, 4, 4, 4) -DEF_PIXEL_TO_RGB(pixel_565_to_rgb, 5, 6, 5, 0) -DEF_PIXEL_TO_RGB(pixel_a555_to_rgb, 5, 5, 5, 1) -DEF_PIXEL_TO_RGB(pixel_555_to_rgb, 5, 5, 5, 0) -DEF_PIXEL_TO_RGB(pixel_666_to_rgb, 6, 6, 6, 0) -DEF_PIXEL_TO_RGB(pixel_a666_to_rgb, 6, 6, 6, 1) -DEF_PIXEL_TO_RGB(pixel_a665_to_rgb, 6, 6, 5, 1) -DEF_PIXEL_TO_RGB(pixel_888_to_rgb, 8, 8, 8, 0) -DEF_PIXEL_TO_RGB(pixel_a888_to_rgb, 8, 8, 8, 1) -DEF_PIXEL_TO_RGB(pixel_a887_to_rgb, 8, 8, 7, 1) -DEF_PIXEL_TO_RGB(pixel_8888_to_rgb, 8, 8, 8, 8) - -/* Special case for (5+1,5+1,5+1) mode */ -static void pixel_1555_to_rgb(uint32_t pixel, rgba *p) -{ - uint8_t u = (pixel >> 15) & 1; - p->b = (((pixel & 0x1F) << 1) | u) << 2; - pixel >>= 5; - p->g = (((pixel & 0x3F) << 1) | u) << 2; - pixel >>= 6; - p->r = (((pixel & 0x1F) << 1) | u) << 2; -} - - -/* Write RGB to QEMU's GraphicConsole framebuffer */ - -static int put_pixel8(rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel8(p.r, p.g, p.b); - *(uint8_t *)d = pixel; - return 1; -} - -static int put_pixel15(rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel15(p.r, p.g, p.b); - *(uint16_t *)d = pixel; - return 2; -} - -static int put_pixel16(rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel16(p.r, p.g, p.b); - *(uint16_t *)d = pixel; - return 2; -} - -static int put_pixel24(rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel24(p.r, p.g, p.b); - *(uint8_t *)d++ = (pixel >> 0) & 0xFF; - *(uint8_t *)d++ = (pixel >> 8) & 0xFF; - *(uint8_t *)d++ = (pixel >> 16) & 0xFF; - return 3; -} - -static int put_pixel32(rgba p, uint8_t *d) -{ - uint32_t pixel = rgb_to_pixel24(p.r, p.g, p.b); - *(uint32_t *)d = pixel; - return 4; -} - - -/* Put/get pixel to/from internal LCD Controller framebuffer */ - -static int put_rgba(rgba p, uint8_t *d) -{ - *(uint8_t *)d++ = p.r; - *(uint8_t *)d++ = p.g; - *(uint8_t *)d++ = p.b; - *(uint32_t *)d = p.a; - return 7; -} - -static int get_rgba(uint8_t *s, rgba *p) -{ - p->r = *(uint8_t *)s++; - p->g = *(uint8_t *)s++; - p->b = *(uint8_t *)s++; - p->a = *(uint32_t *)s; - return 7; -} - - -/* Perform byte/halfword/word swap of data accrding to config */ - -static inline uint64_t swap_data(const DrawConfig *cfg, uint64_t x) -{ - int i; - uint64_t res; - - return x; - - if (cfg->swap & BISWP) { - res = 0; - for (i = 0; i < 64; i++) { - if (x & (1ULL << (64 - i))) { - res |= (1ULL << i); - } - } - x = res; - } - if (cfg->swap & BYSWP) { - x = ((x & 0x00000000000000FFULL) << 56) | - ((x & 0x000000000000FF00ULL) << 40) | - ((x & 0x0000000000FF0000ULL) << 24) | - ((x & 0x00000000FF000000ULL) << 8) | - ((x & 0x000000FF00000000ULL) >> 8) | - ((x & 0x0000FF0000000000ULL) >> 24) | - ((x & 0x00FF000000000000ULL) >> 40) | - ((x & 0xFF00000000000000ULL) >> 56); - } - if (cfg->swap & HWSWP) { - x = ((x & 0x000000000000FFFFULL) << 48) | - ((x & 0x00000000FFFF0000ULL) << 16) | - ((x & 0x0000FFFF00000000ULL) >> 16) | - ((x & 0xFFFF000000000000ULL) >> 48); - } - if (cfg->swap & WSWP) { - x = ((x & 0x00000000FFFFFFFFULL) << 32) | - ((x & 0xFFFFFFFF00000000ULL) >> 32); - } - return x; -} - - -/* Coefficient extraction functions */ - -static uint32_t coef_zero(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - return 0; -} - -static uint32_t coef_one(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - return 0xFFFFFF; -} - -static uint32_t coef_alphaa(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - if (!cfg->fg_pixel_blending) { - pa.a = cfg->fg_alpha_sel; - } - if (cfg->fg_alpha_pix) { - return pa.a; - } else { - return cfg->fg_alpha[pa.a]; - } -} - -static uint32_t coef_one_minus_alphaa(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - if (!cfg->fg_pixel_blending) { - pa.a = cfg->fg_alpha_sel; - } - if (cfg->fg_alpha_pix) { - return 0xFFFFFF - pa.a; - } else { - return 0xFFFFFF - cfg->fg_alpha[pa.a]; - } -} - -static uint32_t coef_alphab(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - if (!cfg->bg_pixel_blending) { - pb.a = cfg->bg_alpha_sel; - } - if (cfg->bg_alpha_pix) { - return pb.a; - } else { - return cfg->bg_alpha[pb.a]; - } -} - -static uint32_t coef_one_minus_alphab(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - if (!cfg->bg_pixel_blending) { - pb.a = cfg->bg_alpha_sel; - } - if (cfg->bg_alpha_pix) { - return 0xFFFFFF - pb.a; - } else { - return 0xFFFFFF - cfg->bg_alpha[pb.a]; - } -} - -static uint32_t coef_a(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - return (pa.r << 16) | (pa.g << 8) | pa.b; -} - -static uint32_t coef_one_minus_a(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - return 0xFFFFFF - ((pa.r << 16) | (pa.g << 8) | pa.b); -} - -static uint32_t coef_b(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - return (pb.r << 16) | (pb.g << 8) | pb.b; -} - -static uint32_t coef_one_minus_b(const DrawConfig *cfg, - rgba pa, rgba pb) -{ - return 0xFFFFFF - ((pb.r << 16) | (pb.g << 8) | pb.b); -} - - -/* Blending functions */ - -static void blend_alpha(const DrawConfig *cfg, - rgba p_bg, rgba p_fg, rgba *res) -{ - uint32_t pl, ql, al, bl; - uint32_t p, q, a, b, fg, bg, fga, bga; - - pl = cfg->coef_p(cfg, p_fg, p_bg); - ql = cfg->coef_q(cfg, p_fg, p_bg); - al = cfg->coef_a(cfg, p_fg, p_bg); - bl = cfg->coef_b(cfg, p_fg, p_bg); - res->a = 0; - /* B */ - p = pl & 0xFF; - pl >>= 8; - q = ql & 0xFF; - ql >>= 8; - a = al & 0xFF; - al >>= 8; - b = bl & 0xFF; - bl >>= 8; - fg = p_fg.b; - bg = p_bg.b; - if (cfg->fg_pixel_blending) { - if (cfg->fg_alpha_pix) { - fga = p_fg.a & 0xFF; - } else { - fga = cfg->fg_alpha[p_fg.a] & 0xFF; - } - } else { - fga = cfg->fg_alpha[cfg->fg_alpha_sel] & 0xFF; - } - if (cfg->bg_pixel_blending) { - if (cfg->bg_alpha_pix) { - bga = p_bg.a & 0xFF; - } else { - bga = cfg->bg_alpha[p_bg.a] & 0xFF; - } - } else { - bga = cfg->bg_alpha[cfg->bg_alpha_sel] & 0xFF; - } - bg = (bg * b + fg * a) / 0xFF; - if (bg > 0xFF) { - res->b = 0xFF; - } else { - res->b = bg; - } - bga = (bga * p + fga * q) / 0xFF; - if (bga > 0xFF) { - res->a |= 0xFF; - } else { - res->a |= bga; - } - /* G */ - p = pl & 0xFF; - pl >>= 8; - q = ql & 0xFF; - ql >>= 8; - a = al & 0xFF; - al >>= 8; - b = bl & 0xFF; - bl >>= 8; - fg = p_fg.g; - bg = p_bg.g; - if (cfg->fg_pixel_blending) { - if (cfg->fg_alpha_pix) { - fga = (p_fg.a >> 8) & 0xFF; - } else { - fga = (cfg->fg_alpha[p_fg.a] >> 8) & 0xFF; - } - } else { - fga = (cfg->fg_alpha[cfg->fg_alpha_sel] >> 8) & 0xFF; - } - if (cfg->bg_pixel_blending) { - if (cfg->bg_alpha_pix) { - bga = (p_bg.a >> 8) & 0xFF; - } else { - bga = (cfg->bg_alpha[p_bg.a] >> 8) & 0xFF; - } - } else { - bga = (cfg->bg_alpha[cfg->bg_alpha_sel] >> 8) & 0xFF; - } - bg = (bg * b + fg * a) / 0xFF; - if (bg > 0xFF) { - res->g = 0xFF; - } else { - res->g = bg; - } - bga = (bga * p + fga * q) / 0xFF; - if (bga > 0xFF) { - res->a |= 0xFF << 8; - } else { - res->a |= bga << 8; - } - /* R */ - p = pl & 0xFF; - pl >>= 8; - q = ql & 0xFF; - ql >>= 8; - a = al & 0xFF; - al >>= 8; - b = bl & 0xFF; - bl >>= 8; - fg = p_fg.r; - bg = p_bg.r; - if (cfg->fg_pixel_blending) { - if (cfg->fg_alpha_pix) { - fga = (p_fg.a >> 16) & 0xFF; - } else { - fga = (cfg->fg_alpha[p_fg.a] >> 16) & 0xFF; - } - } else { - fga = (cfg->fg_alpha[cfg->fg_alpha_sel] >> 16) & 0xFF; - } - if (cfg->bg_pixel_blending) { - if (cfg->bg_alpha_pix) { - bga = (p_bg.a >> 16) & 0xFF; - } else { - bga = (cfg->bg_alpha[p_bg.a] >> 16) & 0xFF; - } - } else { - bga = (cfg->bg_alpha[cfg->bg_alpha_sel] >> 16) & 0xFF; - } - bg = (bg * b + fg * a) / 0xFF; - if (bg > 0xFF) { - res->r = 0xFF; - } else { - res->r = bg; - } - bga = (bga * p + fga * q) / 0xFF; - if (bga > 0xFF) { - res->a |= 0xFF << 16; - } else { - res->a |= bga << 16; - } -} - -static void blend_colorkey(DrawConfig *cfg, - rgba p_bg, rgba p_fg, rgba *p) -{ - uint8_t r, g, b; - - if (cfg->color_ctl & 2) { - blend_alpha(cfg, p_bg, p_fg, p); - return ; - } - r = ((cfg->color_key & ~cfg->color_mask) >> 16) & 0xFF; - g = ((cfg->color_key & ~cfg->color_mask) >> 8) & 0xFF; - b = ((cfg->color_key & ~cfg->color_mask) >> 0) & 0xFF; - if (cfg->color_ctl & 1) { - if ((p_fg.r & ~((cfg->color_mask >> 16) & 0xFF)) == r && - (p_fg.g & ~((cfg->color_mask >> 8) & 0xFF)) == g && - (p_fg.b & ~((cfg->color_mask >> 0) & 0xFF)) == b) { - if (cfg->color_ctl & 4) { - p_fg.a = 1; - cfg->fg_pixel_blending = 0; - blend_alpha(cfg, p_bg, p_fg, p); - } else { - *p = p_bg; - } - } else { - if (cfg->color_ctl & 4) { - p_fg.a = 0; - cfg->fg_pixel_blending = 0; - blend_alpha(cfg, p_bg, p_fg, p); - } else { - *p = p_fg; - } - } - } else { - if ((p_bg.r & ~((cfg->color_mask >> 16) & 0xFF)) == r && - (p_bg.g & ~((cfg->color_mask >> 8) & 0xFF)) == g && - (p_bg.b & ~((cfg->color_mask >> 0) & 0xFF)) == b) { - if (cfg->color_ctl & 4) { - p_fg.a = 1; - cfg->fg_pixel_blending = 0; - blend_alpha(cfg, p_bg, p_fg, p); - } else { - *p = p_fg; - } - } else { - if (cfg->color_ctl & 4) { - p_fg.a = 0; - cfg->fg_pixel_blending = 0; - blend_alpha(cfg, p_bg, p_fg, p); - } else { - *p = p_bg; - } - } - } -} - - -/* Draw line functions */ - -#define DEF_DRAW_LINE(N) \ -static void glue(draw_line, N)(DrawConfig *cfg, uint8_t *src, \ - uint8_t *dst, uint8_t *ifb) \ -{ \ - rgba p, p_old; \ - uint64_t data; \ - int width = cfg->width; \ - int i; \ - do { \ - data = ldq_raw((void *)src); \ - src += 8; \ - data = swap_data(cfg, data); \ - for (i = 0; i < (64 / (N)); i++) { \ - cfg->pixel_to_rgb(cfg->is_palletized ? \ - cfg->palette[data & ((1ULL << (N)) - 1)] : \ - data & ((1ULL << (N)) - 1), &p); \ - if (cfg->blend) { \ - ifb += cfg->get_pixel(ifb, &p_old); \ - cfg->blend(cfg, p_old, p, &p); \ - } \ - dst += cfg->put_pixel(p, dst); \ - data >>= (N); \ - } \ - width -= (64 / (N)); \ - } while (width > 0); \ -} - -DEF_DRAW_LINE(1) -DEF_DRAW_LINE(2) -DEF_DRAW_LINE(4) -DEF_DRAW_LINE(8) -DEF_DRAW_LINE(16) -DEF_DRAW_LINE(32) - -static void draw_line_copy(DrawConfig *cfg, uint8_t *src, uint8_t *dst, - uint8_t *ifb) -{ - rgba p; - int width = cfg->width; - - do { - src += cfg->get_pixel(src, &p); - dst += cfg->put_pixel(p, dst); - width--; - } while (width > 0); -} - - -/* LCD Functions */ - -static void s5pc1xx_lcd_update_irq(S5pc1xxLcdState *s) -{ - if (!(s->vidintcon[0] & 1)) { - qemu_irq_lower(s->irq[0]); - qemu_irq_lower(s->irq[1]); - qemu_irq_lower(s->irq[2]); - return; - } - if ((s->vidintcon[0] & 2) && (s->vidintcon[1] & 1)) { - qemu_irq_raise(s->irq[0]); - } else { - qemu_irq_lower(s->irq[0]); - } - if ((s->vidintcon[0] & (1 << 12)) && (s->vidintcon[1] & 2)) { - qemu_irq_raise(s->irq[1]); - } else { - qemu_irq_lower(s->irq[1]); - } - if ((s->vidintcon[0] & (1 << 17)) && (s->vidintcon[1] & 4)) { - qemu_irq_raise(s->irq[2]); - } else { - qemu_irq_lower(s->irq[2]); - } -} - -static void s5pc1xx_lcd_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxLcdState *s = (S5pc1xxLcdState *)opaque; - int w, i; - - if (offset & 3) { - hw_error("s5pc1xx.lcd: bad write offset " TARGET_FMT_plx "\n", offset); - } - - switch (offset) { - case 0x000 ... 0x008: - s->vidcon[(offset - 0x000) >> 2] = val; - break; - case 0x00C: - s->prtcon = val; - break; - case 0x010 ... 0x018: - s->vidtcon[(offset - 0x010) >> 2] = val; - break; - case 0x020 ... 0x030: - s->window[(offset - 0x020) >> 2].wincon = val; - break; - case 0x034: - s->shadowcon = val; - break; - case 0x040 ... 0x088: - w = (offset - 0x040) >> 4; - i = ((offset - 0x040) & 0xF) >> 2; - if (i < 2) { - s->window[w].vidosd[i] = val; - } else if (i == 3) { - if (w != 1 && w != 2) { - hw_error("s5pc1xx.lcd: bad write offset " TARGET_FMT_plx "\n", - offset); - } else { - s->window[w].vidosd[i] = val; - } - } else { - if (w == 0) { - i++; - } - s->window[w].vidosd[i] = val; - } - break; - case 0x0A0 ... 0x0C0: - w = (offset - 0x0A0) >> 3; - i = ((offset - 0x0A0) >> 2) & 1; - if (i == 1 && w >= 2) { - hw_error("s5pc1xx.lcd: bad write offset " TARGET_FMT_plx "\n", - offset); - } - s->window[w].buf_start[i] = val; - break; - case 0x0D0 ... 0x0F0: - w = (offset - 0x0D0) >> 3; - i = ((offset - 0x0D0) >> 2) & 1; - if (i == 1 && w >= 2) { - hw_error("s5pc1xx.lcd: bad write offset " TARGET_FMT_plx "\n", - offset); - } - s->window[w].buf_end[i] = val; - break; - case 0x100 ... 0x110: - s->window[(offset - 0x100) >> 2].buf_size = val; - break; - case 0x118 ... 0x11C: - s->vp1tcon[(offset - 0x118)] = val; - break; - case 0x130: - s->vidintcon[0] = val; - case 0x134: - s->vidintcon[1] &= ~(val & 7); - s5pc1xx_lcd_update_irq(s); - break; - case 0x140 ... 0x15C: - w = ((offset - 0x140) >> 3) + 1; - i = ((offset - 0x140) >> 2) & 1; - s->window[w].keycon[i] = val; - break; - case 0x170: - s->dithcon = val; - break; - case 0x180 ... 0x190: - s->window[(offset - 0x180) >> 2].winmap = val; - break; - case 0x19C ... 0x1A0: - s->wpalcon[(offset - 0x19C) >> 2] = val; - break; - case 0x1A4: - s->trigcon = val; - break; - case 0x1A8: - s->ituifcon = val; - break; - case 0x1B0 ... 0x1BC: - s->i80ifcon[(offset - 0x1B0) >> 2] = val; - break; - case 0x1D0 ... 0x1D4: - s->ldi_cmdcon[(offset - 0x1D0) >> 2] = val; - break; - case 0x1E0 ... 0x1E8: - i = (offset - 0x1E0) >> 2; - if (i == 2) { - hw_error("s5pc1xx.lcd: bad write offset " TARGET_FMT_plx "\n", - offset); - } - s->sifccon[i] = val; - break; - case 0x200 ... 0x224: - w = ((offset - 0x200) >> 3); - i = ((offset - 0x200) >> 2) & 1; - s->window[w].vidw_alpha[i] = val; - break; - case 0x244 ... 0x250: - s->window[(offset - 0x244) >> 2].blendeq = val; - break; - case 0x260: - s->blendcon = val; - break; - case 0x27C: - s->dualrgb = val; - break; - case 0x280 ... 0x2AC: - s->ldi_cmd[(offset - 0x280) >> 2] = val; - break; - case 0x2400 ... 0x37FC: /* TODO: verify offset!!! */ - w = (offset - 0x2400) >> 10; - i = ((offset - 0x2400) >> 2) & 0xFF; - s->window[w].palette[i] = val; - break; - default: - hw_error("s5pc1xx.lcd: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -static uint32_t s5pc1xx_lcd_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxLcdState *s = (S5pc1xxLcdState *)opaque; - int w, i; - - if (offset & 3) { - hw_error("s5pc1xx.lcd: bad read offset " TARGET_FMT_plx "\n", offset); - } - - switch (offset) { - case 0x000 ... 0x008: - return s->vidcon[(offset - 0x000) >> 2]; - case 0x00C: - return s->prtcon; - case 0x010 ... 0x018: - return s->vidtcon[(offset - 0x010) >> 2]; - case 0x020 ... 0x030: - return s->window[(offset - 0x020) >> 2].wincon; - case 0x034: - return s->shadowcon; - case 0x040 ... 0x088: - w = (offset - 0x040) >> 4; - i = ((offset - 0x040) & 0xF) >> 2; - if (i < 2) { - return s->window[w].vidosd[i]; - } else if (i == 3) { - if (w != 1 && w != 2) { - hw_error("s5pc1xx.lcd: bad read offset " TARGET_FMT_plx "\n", - offset); - } else { - return s->window[w].vidosd[i]; - } - } else { - if (w == 0) { - i++; - } - return s->window[w].vidosd[i]; - } - case 0x0A0 ... 0x0C0: - w = (offset - 0x0A0) >> 3; - i = ((offset - 0x0A0) >> 2) & 1; - if (i == 1 && w >= 2) { - hw_error("s5pc1xx.lcd: bad read offset " TARGET_FMT_plx "\n", - offset); - } - return s->window[w].buf_start[i]; - case 0x0D0 ... 0x0F0: - w = (offset - 0x0D0) >> 3; - i = ((offset - 0x0D0) >> 2) & 1; - if (i == 1 && w >= 2) { - hw_error("s5pc1xx.lcd: bad read offset " TARGET_FMT_plx "\n", - offset); - } - return s->window[w].buf_end[i]; - case 0x100 ... 0x110: - return s->window[(offset - 0x100) >> 2].buf_size; - case 0x118 ... 0x11C: - return s->vp1tcon[(offset - 0x118)]; - case 0x130 ... 0x134: - return s->vidintcon[(offset - 0x130) >> 2]; - case 0x140 ... 0x15C: - w = ((offset - 0x140) >> 3) + 1; - i = ((offset - 0x140) >> 2) & 1; - return s->window[w].keycon[i]; - case 0x170: - return s->dithcon; - case 0x180 ... 0x190: - return s->window[(offset - 0x180) >> 2].winmap; - case 0x19C ... 0x1A0: - return s->wpalcon[(offset - 0x19C) >> 2]; - case 0x1A4: - return s->trigcon; - case 0x1A8: - return s->ituifcon; - case 0x1B0 ... 0x1BC: - return s->i80ifcon[(offset - 0x1B0) >> 2]; - case 0x1D0 ... 0x1D4: - return s->ldi_cmdcon[(offset - 0x1D0) >> 2]; - case 0x1E0 ... 0x1E8: - i = (offset - 0x1E0) >> 2; - return s->sifccon[i]; - case 0x200 ... 0x224: - w = ((offset - 0x200) >> 3); - i = ((offset - 0x200) >> 2) & 1; - return s->window[w].vidw_alpha[i]; - case 0x244 ... 0x250: - return s->window[(offset - 0x244) >> 2].blendeq; - case 0x260: - return s->blendcon; - case 0x27C: - return s->dualrgb; - case 0x280 ... 0x2AC: - return s->ldi_cmd[(offset - 0x280) >> 2]; - case 0x2400 ... 0x37FC: /* TODO: verify offset!!! */ - w = (offset - 0x2400) >> 10; - i = ((offset - 0x2400) >> 2) & 0xFF; - return s->window[w].palette[i]; - default: - hw_error("s5pc1xx.lcd: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc *s5pc1xx_lcd_readfn[] = { - s5pc1xx_lcd_read, - s5pc1xx_lcd_read, - s5pc1xx_lcd_read -}; - -static CPUWriteMemoryFunc *s5pc1xx_lcd_writefn[] = { - s5pc1xx_lcd_write, - s5pc1xx_lcd_write, - s5pc1xx_lcd_write -}; - -static void s5pc1xx_update_resolution(S5pc1xxLcdState *s) -{ - uint32_t width, height; - /* LCD resolution is stored in VIDEO TIME CONTROL REGISTER 2 */ - width = (s->vidtcon[2] & 0x7FF) + 1; - height = ((s->vidtcon[2] >> 11) & 0x7FF) + 1; - if (s->ifb == NULL || ds_get_width(s->console) != width || - ds_get_height(s->console) != height) { - - qemu_console_resize(s->console, width, height); - s->ifb = qemu_realloc(s->ifb, width * height * 7); - s->valid_line = - qemu_realloc(s->valid_line, (height >> 3) * sizeof(uint8_t)); - s->valid_line_prev = - qemu_realloc(s->valid_line_prev, (height >> 3) * sizeof(uint8_t)); - memset(s->ifb, 0, width * height * 7); - s->invalidate = 1; - } -} - -/* Returns WxPAL for given window number WINDOW */ -static uint32_t s5pc1xx_wxpal(S5pc1xxLcdState *s, int window) -{ - switch (window) { - case 0: - return s->wpalcon[1] & 0x7; - case 1: - return (s->wpalcon[1] >> 3) & 0x7; - case 2: - return ((s->wpalcon[0] >> 8) & 0x6) | ((s->wpalcon[1] >> 6) & 0x1); - case 3: - return ((s->wpalcon[0] >> 12) & 0x6) | ((s->wpalcon[1] >> 7) & 0x1); - case 4: - return ((s->wpalcon[0] >> 16) & 0x6) | ((s->wpalcon[1] >> 8) & 0x1); - default: - hw_error("s5pc1xx.lcd: incorrect window number %d\n", window); - } -} - -/* Parse BPPMODE_F bits and setup known DRAW_CONFIG fields accordingly. - BPPMODE_F = WINCON1[5:2] */ -static void s5pc1xx_parse_win_bppmode(S5pc1xxLcdState *s, - DrawConfig *cfg, int window) -{ - switch ((s->window[window].wincon >> 2) & 0xF) { - case 0: - cfg->draw_line = draw_line1; - cfg->is_palletized = 1; - cfg->bpp = 1; - break; - case 1: - cfg->draw_line = draw_line2; - cfg->is_palletized = 1; - cfg->bpp = 2; - break; - case 2: - cfg->draw_line = draw_line4; - cfg->is_palletized = 1; - cfg->bpp = 4; - break; - case 3: - cfg->draw_line = draw_line8; - cfg->is_palletized = 1; - cfg->bpp = 8; - break; - case 4: - cfg->draw_line = draw_line8; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_a232_to_rgb; - cfg->bpp = 8; - break; - case 5: - cfg->draw_line = draw_line16; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_565_to_rgb; - cfg->bpp = 16; - break; - case 6: - cfg->draw_line = draw_line16; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_a555_to_rgb; - cfg->bpp = 16; - break; - case 7: - cfg->draw_line = draw_line16; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_1555_to_rgb; - cfg->bpp = 16; - break; - case 8: - cfg->draw_line = draw_line32; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_666_to_rgb; - cfg->bpp = 32; - break; - case 9: - cfg->draw_line = draw_line32; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_a665_to_rgb; - cfg->bpp = 32; - break; - case 10: - cfg->draw_line = draw_line32; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_a666_to_rgb; - cfg->bpp = 32; - break; - case 11: - cfg->draw_line = draw_line32; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_888_to_rgb; - cfg->bpp = 32; - break; - case 12: - cfg->draw_line = draw_line32; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_a887_to_rgb; - cfg->bpp = 32; - break; - case 13: - cfg->draw_line = draw_line32; - cfg->is_palletized = 0; - if ((s->window[window].wincon & (1 << 6)) && - (s->window[window].wincon & 2)) { - cfg->pixel_to_rgb = pixel_8888_to_rgb; - cfg->fg_alpha_pix = 1; - } else { - cfg->pixel_to_rgb = pixel_a888_to_rgb; - } - cfg->bpp = 32; - break; - case 14: - cfg->draw_line = draw_line16; - cfg->is_palletized = 0; - if ((s->window[window].wincon & (1 << 6)) && - (s->window[window].wincon & 2)) { - cfg->pixel_to_rgb = pixel_4444_to_rgb; - cfg->fg_alpha_pix = 1; - } else { - cfg->pixel_to_rgb = pixel_a444_to_rgb; - } - cfg->bpp = 16; - break; - case 15: - cfg->draw_line = draw_line16; - cfg->is_palletized = 0; - cfg->pixel_to_rgb = pixel_555_to_rgb; - cfg->bpp = 16; - break; - } -} - -pixel_to_rgb_func *wxpal_to_rgb[8] = { - [0] = pixel_565_to_rgb, - [1] = pixel_a555_to_rgb, - [2] = pixel_666_to_rgb, - [3] = pixel_a665_to_rgb, - [4] = pixel_a666_to_rgb, - [5] = pixel_888_to_rgb, - [6] = pixel_a888_to_rgb, - [7] = pixel_8888_to_rgb -}; - -static inline uint32_t unpack_by_4(uint32_t x) -{ - return ((x & 0xF00) << 12) | ((x & 0xF0) << 8) | ((x & 0xF) << 4); -} - -static coef_func *coef_decode(uint32_t x) -{ - switch (x) { - case 0: - return coef_zero; - case 1: - return coef_one; - case 2: - return coef_alphaa; - case 3: - return coef_one_minus_alphaa; - case 4: - return coef_alphab; - case 5: - return coef_one_minus_alphab; - case 10: - return coef_a; - case 11: - return coef_one_minus_a; - case 12: - return coef_b; - case 13: - return coef_one_minus_b; - default: - hw_error("s5pc1xx.lcd: illegal value\n"); - } -} - -static inline void putpixel_by_bpp(DrawConfig *cfg, int bpp) -{ - switch (bpp) { - case 8: - cfg->put_pixel = put_pixel8; - break; - case 15: - cfg->put_pixel = put_pixel15; - break; - case 16: - cfg->put_pixel = put_pixel16; - break; - case 24: - cfg->put_pixel = put_pixel24; - break; - case 32: - cfg->put_pixel = put_pixel32; - break; - default: - hw_error("s5pc1xx.lcd: unsupported BPP (%d)", bpp); - } -} - -static void s5pc1xx_lcd_update(void *opaque) -{ - S5pc1xxLcdState *s = (S5pc1xxLcdState *)opaque; - DrawConfig cfg; - int i, dirty[2], x; - int line; - target_phys_addr_t scanline, newline, map_len, pd, inc_size; - uint8_t *mapline, *startline, *valid_line_tmp; - int lefttop_x, lefttop_y, rightbottom_x, rightbottom_y; - int ext_line_size; - int width, height; - uint32_t tmp; - int buf_id; - int need_redraw; - int global_width, global_height; - int bpp; - uint8_t *d; - uint8_t is_first_window; - - if (!s || !s->console || !ds_get_bits_per_pixel(s->console)) { - return; - } - - if (! (s->vidcon[0] & 2)) { - return; - } - - memset(&cfg, 0, sizeof(cfg)); - - s5pc1xx_update_resolution(s); - - /* First we will mark lines of the display which need to be redrawn */ - memset(s->valid_line, 0xFF, - ((((s->vidtcon[2] >> 11) & 0x7FF) + 1 + 7) >> 3) * sizeof(uint8_t)); - for (i = 0; i < 5; i++) { - if (s->window[i].wincon & 1) { - lefttop_x = (s->window[i].vidosd[0] >> 11) & 0x7FF; - lefttop_y = (s->window[i].vidosd[0] >> 0) & 0x7FF; - rightbottom_x = (s->window[i].vidosd[1] >> 11) & 0x7FF; - rightbottom_y = (s->window[i].vidosd[1] >> 0) & 0x7FF; - height = rightbottom_y - lefttop_y + 1; - width = rightbottom_x - lefttop_x + 1; - ext_line_size = s->window[i].buf_size & 0x1FFF; - buf_id = 0; - if (i <= 1) { - buf_id = (s->window[i].wincon >> 20) & 1; - } - /* According to documentation framebuffer is always located in - single bank of DRAM. Bits [31:24] of BUF_START encode bank - number, and [23:0] - address of the buffer in bank. We will - assume that DRAM Controller uses linear memory mapping so - BUF_START will be just address of the framebuffer. In the - other case framebuffer will be dispersed all over the system - memory so it is unclear how such system will work. - - Moreover, we will ignore absence of carry bit bitween bits 23 - and 24 while incrementing address in the hope that no - programmer will use such hack. */ - scanline = s->window[i].buf_start[buf_id]; - inc_size = (s->window[i].buf_size & 0x1FFF) + - ((s->window[i].buf_size >> 13) & 0x1FFF); - cpu_physical_sync_dirty_bitmap(scanline, - scanline + height * inc_size); - pd = (cpu_get_physical_page_desc(scanline) & TARGET_PAGE_MASK) + - (scanline & ~TARGET_PAGE_MASK); - dirty[0] = dirty[1] = - cpu_physical_memory_get_dirty(scanline, VGA_DIRTY_FLAG); - cpu_physical_memory_reset_dirty(scanline, scanline, VGA_DIRTY_FLAG); - for (line = 0; line < height; line++) { - newline = scanline + ext_line_size; - for (x = scanline; - x < newline; - x += TARGET_PAGE_SIZE) { - pd = (cpu_get_physical_page_desc(x) & TARGET_PAGE_MASK) + - (x & ~TARGET_PAGE_MASK); - dirty[1] = cpu_physical_memory_get_dirty(pd, VGA_DIRTY_FLAG); - dirty[0] |= dirty[1]; - } - if (dirty[0]) { - tmp = line + lefttop_y; - s->valid_line[tmp >> 3] &= ~(1 << (tmp & 0x7)); - } - dirty[0] = dirty[1] = 0; - scanline += (s->window[i].buf_size & 0x1FFF) + - ((s->window[i].buf_size >> 13) & 0x1FFF); - } - scanline = s->window[i].buf_start[buf_id]; - pd = (cpu_get_physical_page_desc(scanline) & TARGET_PAGE_MASK) + - (scanline & ~TARGET_PAGE_MASK); - cpu_physical_memory_reset_dirty(pd, pd + inc_size * height, - VGA_DIRTY_FLAG); - } - } - - need_redraw = 0; - is_first_window = 1; - for (i = 0; i < 5; i++) { - if (s->window[i].wincon & 1) { - cfg.fg_alpha_pix = 0; - s5pc1xx_parse_win_bppmode(s, &cfg, i); - /* If we have mode with palletized color then we need to parse - palette color mode and set pixel-to-rgb conversion function - accordingly. */ - if (cfg.is_palletized) { - tmp = s5pc1xx_wxpal(s, i); - /* Different windows have different mapping WxPAL to palette - pixel format. This transform happens to unify them all. */ - if (i < 2 && tmp < 7) { - tmp = 6 - tmp; - } - cfg.pixel_to_rgb = wxpal_to_rgb[tmp]; - if (tmp == 7) { - cfg.fg_alpha_pix = 1; - } - } - cfg.put_pixel = put_rgba; - cfg.get_pixel = get_rgba; - cfg.bg_alpha_pix = 1; - cfg.color_mask = s->window[i].keycon[0] & 0xFFFFFF; - cfg.color_key = s->window[i].keycon[1]; - cfg.color_ctl = (s->window[i].keycon[0] >> 24) & 7; - if (i == 0) { - cfg.fg_alpha[0] = s->window[i].vidw_alpha[0]; - cfg.fg_alpha[1] = s->window[i].vidw_alpha[1]; - } else { - cfg.fg_alpha[0] = - unpack_by_4((s->window[i].vidosd[3] & 0xFFF000) >> 12) | - (s->window[i].vidw_alpha[0] & 0xF0F0F); - cfg.fg_alpha[1] = - unpack_by_4(s->window[i].vidosd[3] & 0xFFF) | - (s->window[i].vidw_alpha[0] & 0xF0F0F); - } - cfg.bg_pixel_blending = 1; - cfg.fg_pixel_blending = s->window[i].wincon & (1 << 6); - cfg.fg_alpha_sel = (s->window[i].wincon >> 1) & 1; - cfg.palette = s->window[i].palette; - cfg.swap = (s->window[i].wincon >> 15) & 0xF; - cfg.coef_q = coef_decode((s->window[i].blendeq >> 18) & 0xF); - cfg.coef_p = coef_decode((s->window[i].blendeq >> 12) & 0xF); - cfg.coef_b = coef_decode((s->window[i].blendeq >> 6) & 0xF); - cfg.coef_a = coef_decode((s->window[i].blendeq >> 0) & 0xF); - if (is_first_window) { - cfg.blend = NULL; - } else { - cfg.blend = blend_colorkey; - } - is_first_window = 0; - /* At this point CFG is fully set up except WIDTH. We can proceed - with drawing. */ - lefttop_x = (s->window[i].vidosd[0] >> 11) & 0x7FF; - lefttop_y = (s->window[i].vidosd[0] >> 0) & 0x7FF; - rightbottom_x = (s->window[i].vidosd[1] >> 11) & 0x7FF; - rightbottom_y = (s->window[i].vidosd[1] >> 0) & 0x7FF; - height = rightbottom_y - lefttop_y + 1; - width = rightbottom_x - lefttop_x + 1; - cfg.width = width; - ext_line_size = (width * cfg.bpp) >> 3; - buf_id = 0; - if (i <= 1) { - buf_id = (s->window[i].wincon >> 20) & 1; - } - scanline = s->window[i].buf_start[buf_id]; - global_width = (s->vidtcon[2] & 0x7FF) + 1; - global_height = ((s->vidtcon[2] >> 11) & 0x7FF) + 1; - /* See comment above about DRAM Controller memory mapping. */ - map_len = ((s->window[i].buf_size & 0x1FFF) + - ((s->window[i].buf_size >> 13) & 0x1FFF)) * height; - mapline = cpu_physical_memory_map(scanline, &map_len, 0); - if (!mapline) { - return; - } - startline = mapline; - for (line = 0; line < height; line++) { - tmp = line + lefttop_y; - if (s->invalidate || - !(s->valid_line[tmp >> 3] & (1 << (tmp & 7))) || - !(s->valid_line_prev[tmp >> 3] & (1 << (tmp & 7)))) { - need_redraw = 1; - cfg.draw_line(&cfg, mapline, - s->ifb + lefttop_x * 7 + - (lefttop_y + line) * global_width * 7, - s->ifb + lefttop_x * 7 + - (lefttop_y + line) * global_width * 7); - } - mapline += (s->window[i].buf_size & 0x1FFF) + - ((s->window[i].buf_size >> 13) & 0x1FFF); - } - cpu_physical_memory_unmap(startline, map_len, 0, 0); - } - } - /* Last pass: copy resulting image to QEMU_CONSOLE. */ - if (need_redraw) { - width = (s->vidtcon[2] & 0x7FF) + 1; - height = ((s->vidtcon[2] >> 11) & 0x7FF) + 1; - cfg.get_pixel = get_rgba; - bpp = ds_get_bits_per_pixel(s->console); - putpixel_by_bpp(&cfg, bpp); - bpp = (bpp + 1) >> 3; - d = ds_get_data(s->console); - for (line = 0; line < height; line++) { - draw_line_copy(&cfg, s->ifb + width * line * 7, - d + width * line * bpp, NULL); - } - dpy_update(s->console, 0, 0, width, height); - } - valid_line_tmp = s->valid_line; - s->valid_line = s->valid_line_prev; - s->valid_line_prev = valid_line_tmp; - s->invalidate = 0; - s->vidintcon[1] |= 2; - s5pc1xx_lcd_update_irq(s); -} - -static void s5pc1xx_lcd_save(QEMUFile *f, void *opaque) -{ - S5pc1xxLcdState *s = (S5pc1xxLcdState *)opaque; - int i, j, width, height; - - width = (s->vidtcon[2] & 0x7FF) + 1; - height = ((s->vidtcon[2] >> 11) & 0x7FF) + 1; - - qemu_put_be32s(f, &s->shadowcon); - qemu_put_be32s(f, &s->prtcon); - qemu_put_be32s(f, &s->dithcon); - qemu_put_be32s(f, &s->trigcon); - qemu_put_be32s(f, &s->ituifcon); - qemu_put_be32s(f, &s->blendcon); - qemu_put_be32s(f, &s->dualrgb); - - for (i = 0; i < 2; i++) { - qemu_put_be32s(f, &s->vp1tcon[i]); - qemu_put_be32s(f, &s->vidintcon[i]); - qemu_put_be32s(f, &s->wpalcon[i]); - qemu_put_be32s(f, &s->ldi_cmdcon[i]); - } - - for (i = 0; i < 3; i++) { - qemu_put_be32s(f, &s->vidcon[i]); - qemu_put_be32s(f, &s->vidtcon[i]); - qemu_put_be32s(f, &s->sifccon[i]); - } - - for (i = 0; i < 4; i++) { - qemu_put_be32s(f, &s->i80ifcon[i]); - } - - for (i = 0; i < 12; i++) { - qemu_put_be32s(f, &s->ldi_cmd[i]); - } - - //qemu_put_buffer(f, s->ifb, width * height * 7); - - /* Not saving valid_line because the whole screen will be redrawn anyway */ - - for (i = 0; i < 5; i++) { - qemu_put_be32s(f, &s->window[i].wincon); - qemu_put_be32s(f, &s->window[i].buf_size); - qemu_put_be32s(f, &s->window[i].winmap); - qemu_put_be32s(f, &s->window[i].blendeq); - - for (j = 0; j < 2; j++) { - qemu_put_be32s(f, &s->window[i].buf_start[j]); - qemu_put_be32s(f, &s->window[i].buf_end[j]); - qemu_put_be32s(f, &s->window[i].keycon[j]); - qemu_put_be32s(f, &s->window[i].vidw_alpha[j]); - } - - for (j = 0; j < 4; j++) { - qemu_put_be32s(f, &s->window[i].vidosd[j]); - } - - for (j = 0; j < 256; j++) { - qemu_put_be32s(f, &s->window[i].palette[j]); - } - } -} - -static int s5pc1xx_lcd_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxLcdState *s = (S5pc1xxLcdState *)opaque; - int i, j, width, height; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->shadowcon); - qemu_get_be32s(f, &s->prtcon); - qemu_get_be32s(f, &s->dithcon); - qemu_get_be32s(f, &s->trigcon); - qemu_get_be32s(f, &s->ituifcon); - qemu_get_be32s(f, &s->blendcon); - qemu_get_be32s(f, &s->dualrgb); - - for (i = 0; i < 2; i++) { - qemu_get_be32s(f, &s->vp1tcon[i]); - qemu_get_be32s(f, &s->vidintcon[i]); - qemu_get_be32s(f, &s->wpalcon[i]); - qemu_get_be32s(f, &s->ldi_cmdcon[i]); - } - - for (i = 0; i < 3; i++) { - qemu_get_be32s(f, &s->vidcon[i]); - qemu_get_be32s(f, &s->vidtcon[i]); - qemu_get_be32s(f, &s->sifccon[i]); - } - - width = (s->vidtcon[2] & 0x7FF) + 1; - height = ((s->vidtcon[2] >> 11) & 0x7FF) + 1; - - for (i = 0; i < 4; i++) { - qemu_get_be32s(f, &s->i80ifcon[i]); - } - - for (i = 0; i < 12; i++) { - qemu_get_be32s(f, &s->ldi_cmd[i]); - } - - //qemu_get_buffer(f, s->ifb, width * height * 7); - - for (i = 0; i < 5; i++) { - qemu_get_be32s(f, &s->window[i].wincon); - qemu_get_be32s(f, &s->window[i].buf_size); - qemu_get_be32s(f, &s->window[i].winmap); - qemu_get_be32s(f, &s->window[i].blendeq); - - for (j = 0; j < 2; j++) { - qemu_get_be32s(f, &s->window[i].buf_start[j]); - qemu_get_be32s(f, &s->window[i].buf_end[j]); - qemu_get_be32s(f, &s->window[i].keycon[j]); - qemu_get_be32s(f, &s->window[i].vidw_alpha[j]); - } - - for (j = 0; j < 4; j++) { - qemu_get_be32s(f, &s->window[i].vidosd[j]); - } - - for (j = 0; j < 256; j++) { - qemu_get_be32s(f, &s->window[i].palette[j]); - } - } - - s5pc1xx_update_resolution(s); - /* Redraw the whole screen */ - s->invalidate = 1; - return 0; -} - -static void s5pc1xx_lcd_invalidate(void *opaque) -{ - S5pc1xxLcdState *s = (S5pc1xxLcdState *)opaque; - s->invalidate = 1; -} - -static void s5pc1xx_window_reset(S5pc1xxLcdWindow *s) -{ - memset(s, 0, sizeof(*s)); - s->blendeq = 0xC2; -} - -static void s5pc1xx_lcd_reset(void *opaque) -{ - S5pc1xxLcdState *s = (S5pc1xxLcdState *)opaque; - int i; - - memset((uint8_t *)s + sizeof(SysBusDevice), - 0, offsetof(S5pc1xxLcdState, window)); - for (i = 0; i < 5; i++) { - s5pc1xx_window_reset(&s->window[i]); - } - if (s->ifb != NULL) { - qemu_free(s->ifb); - } - s->ifb = NULL; - if (s->valid_line != NULL) { - qemu_free(s->valid_line); - } - s->valid_line = NULL; - if (s->valid_line_prev != NULL) { - qemu_free(s->valid_line_prev); - } - s->valid_line_prev = NULL; -} - -static int s5pc1xx_lcd_init(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxLcdState *s = FROM_SYSBUS(S5pc1xxLcdState, dev); - - s->ifb = NULL; - s->valid_line = NULL; - s->valid_line_prev = NULL; - s5pc1xx_lcd_reset(s); - - sysbus_init_irq(dev, &s->irq[0]); - sysbus_init_irq(dev, &s->irq[1]); - sysbus_init_irq(dev, &s->irq[2]); - - iomemtype = - cpu_register_io_memory(s5pc1xx_lcd_readfn, s5pc1xx_lcd_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x3800, iomemtype); - - s->console = graphic_console_init(s5pc1xx_lcd_update, - s5pc1xx_lcd_invalidate, NULL, NULL, s); - - qemu_register_reset(s5pc1xx_lcd_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.lcd", -1, 1, - s5pc1xx_lcd_save, s5pc1xx_lcd_load, s); - - return 0; -} - -static void s5pc1xx_lcd_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.lcd", sizeof(S5pc1xxLcdState), - s5pc1xx_lcd_init); -} - -device_init(s5pc1xx_lcd_register_devices) diff --git a/hw/s5pc1xx_mmc.c b/hw/s5pc1xx_mmc.c deleted file mode 100644 index bc73230..0000000 --- a/hw/s5pc1xx_mmc.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * MMC controller for S5PC1XX-based board emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Alexey Merkulov - * Vladimir Monakhov - * - * Based on SMDK6400 MMC (hw/smdk6400/smdk_mmc.c) - */ - -#include "hw.h" -#include "sd.h" -#include "s5pc1xx.h" -#include "s5pc1xx_hsmmc_regs.h" -#include "block_int.h" -#include "sysbus.h" - -#include "qemu-timer.h" - -/*#define DEBUG_MMC*/ - -#ifdef DEBUG_MMC -#define DPRINTF(fmt, args...) \ -do { fprintf(stderr, "QEMU SD/MMC: " fmt , ##args); } while (0) -#else -#define DPRINTF(fmt, args...) do {} while(0) -#endif - -#define CMD_RESPONSE (3 << 0) - -#define INSERTION_DELAY (get_ticks_per_sec()) - -typedef struct S5pc1xxMMCState { - SysBusDevice busdev; - - SDState *card; - uint8_t dma_transcpt; - uint32_t cmdarg; - uint32_t respcmd; - uint32_t response[4]; - qemu_irq irq; - - uint32_t sysad; - uint16_t blksize; - uint16_t blkcnt; - uint32_t argument; - uint16_t trnmod; - uint16_t cmdreg; - uint32_t prnsts; - uint8_t hostctl; - uint8_t pwrcon; - uint16_t clkcon; - uint8_t timeoutcon; - uint8_t swrst; - uint16_t norintsts; - uint16_t errintsts; - uint16_t norintstsen; - uint16_t errintstsen; - uint16_t norintsigen; - uint16_t errintsigen; - uint32_t control2; - uint32_t control3; - - QEMUTimer *response_timer; /* command response. */ - QEMUTimer *insert_timer; /* timer for 'changing' sd card. */ - - qemu_irq eject; -} S5pc1xxMMCState; - - -static void mmc_dmaInt(S5pc1xxMMCState *s) -{ - if (s->dma_transcpt == 1) - s->norintsts |= S5C_HSMMC_NIS_TRSCMP; - else - s->norintsts |= S5C_HSMMC_NIS_DMA; - qemu_set_irq(s->irq, 1); -} - -static void mmc_fifo_push(S5pc1xxMMCState *s, uint32_t pos, uint32_t value) -{ - cpu_physical_memory_write(s->sysad + pos, (uint8_t *)(&value), 4); -} - -static uint32_t mmc_fifo_pop(S5pc1xxMMCState *s, uint32_t pos) -{ - uint32_t value = 0; - - cpu_physical_memory_read(s->sysad + pos, (uint8_t *)(&value), 4); - return value; -} - -static void s5pc1xx_mmc_raise_end_command_irq(void *opaque) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - DPRINTF("raise IRQ response\n"); - qemu_irq_raise(s->irq); - s->norintsts |= S5C_HSMMC_NIS_CMDCMP; -} - -static void mmc_send_command(S5pc1xxMMCState *s) -{ - SDRequest request; - uint8_t response[16]; - int rlen; - - s->errintsts = 0; - qemu_mod_timer(s->response_timer, qemu_get_clock(vm_clock)); - if (!s->card) - return; - - request.cmd = s->cmdreg >> 8; - request.arg = s->cmdarg; - DPRINTF("Command %d %08x\n", request.cmd, request.arg); - rlen = sd_do_command(s->card, &request, response); - if (rlen < 0) - goto error; - if ((s->cmdreg & CMD_RESPONSE) != 0) { -#define RWORD(n) ((n >= 0 ? (response[n] << 24) : 0) \ - | (response[n + 1] << 16) \ - | (response[n + 2] << 8) \ - | response[n + 3]) - - if (rlen == 0) - goto error; - if (rlen != 4 && rlen != 16) - goto error; - s->response[0] = RWORD(0); - if (rlen == 4) { - s->response[1] = s->response[2] = s->response[3] = 0; - } else { - s->response[0] = RWORD(11); - s->response[1] = RWORD(7); - s->response[2] = RWORD(3); - s->response[3] = RWORD(-1); - } - DPRINTF("Response received\n"); -#undef RWORD - } else { - DPRINTF("Command sent\n"); - } - return; - -error: - DPRINTF("Timeout\n"); - s->errintsts |= S5C_HSMMC_EIS_CMDTIMEOUT; -} - -/* Transfer data between the card and the FIFO. This is complicated by - the FIFO holding 32-bit words and the card taking data in single byte - chunks. FIFO bytes are transferred in little-endian order. */ -static void mmc_fifo_run(S5pc1xxMMCState *s) -{ - uint32_t value; - int n; - uint32_t pos; - int is_read; - uint32_t datacnt, boundary_chk, boundary_count; - uint8_t dma_buf_boundary, dma_mask_flag; - - is_read = (s->trnmod & S5C_HSMMC_TRNS_READ) != 0; - - if (s->blkcnt != 0 && (!is_read || sd_data_ready(s->card))) { - n = 0; - value = 0; - - if (s->blkcnt > 1) { - /* multi block */ - if (s->norintstsen & 0x8) - dma_mask_flag = 1; /* DMA enable */ - else - dma_mask_flag = 0; /* DMA disable */ - - dma_buf_boundary = (s->blksize & 0xf000) >> 12; - boundary_chk = 1 << (dma_buf_boundary+12); - boundary_count = boundary_chk - (s->sysad % boundary_chk); - while (s->blkcnt) { - datacnt = s->blksize & 0x0fff; - pos = 0; - while (datacnt) { - if (is_read) { - value |= (uint32_t)sd_read_data(s->card) << (n * 8); - n++; - if (n == 4) { - mmc_fifo_push(s, pos, value); - value = 0; - n = 0; - pos += 4; - } - } else { - if (n == 0) { - value = mmc_fifo_pop(s, pos); - n = 4; - pos += 4; - } - sd_write_data(s->card, value & 0xff); - value >>= 8; - n--; - } - datacnt--; - } - s->sysad += s->blksize & 0x0fff; - boundary_count -= s->blksize & 0x0fff; - s->blkcnt--; - - if ((boundary_count == 0) && dma_mask_flag) - break; - } - if (s->blkcnt == 0) - s->norintsts |= S5C_HSMMC_NIS_TRSCMP; - else - s->norintsts |= S5C_HSMMC_NIS_DMA; - } else { - /* single block */ - datacnt = s->blksize & 0x0fff; - pos = 0; - while (datacnt) { - if (is_read) { - value |= - (uint32_t)sd_read_data(s->card) << (n * 8); - n++; - if (n == 4) { - mmc_fifo_push(s, pos, value); - value = 0; - n = 0; - pos += 4; - } - } else { - if (n == 0) { - value = mmc_fifo_pop(s, pos); - n = 4; - pos += 4; - } - sd_write_data(s->card, value & 0xff); - value >>= 8; - n--; - } - datacnt--; - } - s->blkcnt--; - s->norintsts |= S5C_HSMMC_NIS_TRSCMP; - } - } -} - -/* MMC read (byte) function */ -static uint32_t mmc_readb(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - - switch (offset) { - case (S5C_HSMMC_RSPREG0 + 0x3): - return (uint8_t)(s->response[0] >> 24); - case (S5C_HSMMC_RSPREG1 + 0x3): - return (uint8_t)(s->response[1] >> 24); - case (S5C_HSMMC_RSPREG2 + 0x3): - return (uint8_t)(s->response[2] >> 24); - case S5C_HSMMC_HOSTCTL: - return s->hostctl; - case S5C_HSMMC_PWRCON: - return s->pwrcon; - case S5C_HSMMC_BLKGAP: - return 0; - case S5C_HSMMC_WAKCON: - return 0; - case S5C_HSMMC_TIMEOUTCON: - return s->timeoutcon; - case S5C_HSMMC_SWRST: - return 0; - default: - hw_error("s5pc1xx.mmc: bad read offset " TARGET_FMT_plx "\n", offset); - } -} - -/* MMC read (word) function */ -static uint32_t mmc_readw(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - - switch (offset) { - case S5C_HSMMC_BLKSIZE: - return s->blksize; - case S5C_HSMMC_BLKCNT: - return s->blkcnt; - case S5C_HSMMC_TRNMOD: - return s->trnmod; - case S5C_HSMMC_CLKCON: - return s->clkcon; - case S5C_HSMMC_SWRST: - return s->swrst; - case S5C_HSMMC_NORINTSTS: - qemu_set_irq(s->irq, 0); - return s->norintsts; - case S5C_HSMMC_NORINTSTSEN: - return s->norintstsen; - case S5C_HSMMC_ACMD12ERRSTS: - return 0; - case S5C_HSMMC_SLOT_INT_STATUS: - return 0; - case S5C_HSMMC_HCVER: - return 0x2401; - default: - hw_error("s5pc1xx.mmc: bad read offset " TARGET_FMT_plx "\n", offset); - } -} - -/* MMC read (doubleword) function */ -static uint32_t mmc_readl(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - - switch (offset) { - case S5C_HSMMC_SYSAD: - return s->sysad; - case S5C_HSMMC_ARGUMENT: - return s->cmdarg; - case S5C_HSMMC_RSPREG0: - return s->response[0]; - case S5C_HSMMC_RSPREG1: - return s->response[1]; - case S5C_HSMMC_RSPREG2: - return s->response[2]; - case S5C_HSMMC_RSPREG3: - return s->response[3]; - case S5C_HSMMC_PRNSTS: - return s->prnsts; - case S5C_HSMMC_NORINTSTS: - qemu_set_irq(s->irq, 0); - return (s->errintsts << 16) | (s->norintsts); - case S5C_HSMMC_NORINTSTSEN: - return (s->errintstsen << 16) | s->norintstsen; - case S5C_HSMMC_NORINTSIGEN: - return (s->errintsigen << 16) | s->norintsigen; - case S5C_HSMMC_CAPAREG: - return 0x05E80080; - case S5C_HSMMC_MAXCURR: - return 0; - case S5C_HSMMC_CONTROL2: - return s->control2; - case S5C_HSMMC_CONTROL3: - return s->control3; - default: - hw_error("s5pc1xx.mmc: bad read offset " TARGET_FMT_plx "\n", offset); - } -} - -/* MMC write (byte) function */ -static void mmc_writeb(void *opaque, target_phys_addr_t offset, uint32_t value) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - - switch (offset) { - case S5C_HSMMC_HOSTCTL: - s->hostctl = value; - break; - case S5C_HSMMC_PWRCON: - s->pwrcon = value; - break; - case S5C_HSMMC_TIMEOUTCON: - s->timeoutcon = value; - break; - case S5C_HSMMC_SWRST: - s->swrst = value; - break; - default: - hw_error("s5pc1xx.mmc: bad write offset " TARGET_FMT_plx "\n", offset); - } -} - -/* MMC write (word) function */ -static void mmc_writew(void *opaque, target_phys_addr_t offset, uint32_t value) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - - switch (offset) { - case S5C_HSMMC_BLKSIZE: - s->blksize = value; - break; - case S5C_HSMMC_BLKCNT: - s->blkcnt = value; - break; - case S5C_HSMMC_TRNMOD: - s->trnmod = value; - break; - case S5C_HSMMC_CMDREG: /* Command */ - s->cmdreg = value; - mmc_send_command(s); - mmc_fifo_run(s); - if (s->errintsts) - s->norintsts |= S5C_HSMMC_NIS_ERR; - s->norintsts |= S5C_HSMMC_NIS_CMDCMP; - if (s->norintsts & S5C_HSMMC_NIS_TRSCMP) - s->norintsts &= ~S5C_HSMMC_NIS_CMDCMP; - if (s->norintsts & S5C_HSMMC_NIS_DMA) - s->norintsts &= ~S5C_HSMMC_NIS_CMDCMP; - break; - case S5C_HSMMC_CLKCON: - s->clkcon = value; - if (S5C_HSMMC_CLOCK_INT_EN & s->clkcon) - s->clkcon |= S5C_HSMMC_CLOCK_INT_STABLE; - else - s->clkcon &= ~S5C_HSMMC_CLOCK_INT_STABLE; - if (S5C_HSMMC_CLOCK_CARD_EN & s->clkcon) - s->clkcon |= S5C_HSMMC_CLOCK_EXT_STABLE; - else - s->clkcon &= ~S5C_HSMMC_CLOCK_EXT_STABLE; - break; - case S5C_HSMMC_NORINTSTS: - s->norintsts &= ~value; - s->norintsts &= ~0x8100; - s->norintsts |= value & 0x8100; - break; - case S5C_HSMMC_NORINTSTSEN: - s->norintstsen = value; - break; - case S5C_HSMMC_NORINTSIGEN: - s->norintsigen = value; - break; - default: - hw_error("s5pc1xx.mmc: bad write offset " TARGET_FMT_plx "\n", offset); - } -} - -/* MMC write (doubleword) function */ -static void mmc_writel(void *opaque, target_phys_addr_t offset, uint32_t value) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - int datacnt; - int is_read; - int value1, n; - uint32_t pos; - uint32_t boundary_chk, boundary_count; - uint32_t dma_buf_boundary; - uint8_t dma_mask_flag; - - switch (offset) { - case S5C_HSMMC_SYSAD: - s->sysad = value; - if (s->blkcnt != 0) { - n = 0; - value1 = 0; - is_read = (s->trnmod & S5C_HSMMC_TRNS_READ) != 0; - dma_buf_boundary = (s->blksize & 0xf000) >> 12; - boundary_chk = 1 << (dma_buf_boundary + 12); - - if (s->norintstsen & 0x8) - dma_mask_flag = 1; /* DMA enable */ - else - dma_mask_flag = 0; /* DMA disable */ - - boundary_count = boundary_chk - (s->sysad % boundary_chk); - while (s->blkcnt) { - pos = 0; - datacnt = s->blksize & 0x0fff; - while (datacnt) { - if (is_read) { - value1 |= (uint32_t)sd_read_data(s->card) << (n * 8); - n++; - if (n == 4) { - mmc_fifo_push(s, pos, value1); - value1 = 0; - n = 0; - pos += 4; - } - } else { - if (n == 0) { - value1 = mmc_fifo_pop(s, pos); - n = 4; - pos += 4; - } - sd_write_data(s->card, value1 & 0xff); - value1 >>= 8; - n--; - } - datacnt--; - } - s->sysad += s->blksize & 0x0fff; - boundary_count -= s->blksize & 0x0fff; - s->blkcnt--; - if ((boundary_count == 0) && dma_mask_flag) - break; - } - if (s->blkcnt == 0) { - s->dma_transcpt = 1; - mmc_dmaInt(s); - } else { - s->dma_transcpt = 0; - mmc_dmaInt(s); - } - } - break; - case S5C_HSMMC_ARGUMENT: - s->argument = value; - s->cmdarg = value; - break; - case S5C_HSMMC_NORINTSTS: - s->norintsts &= ~value; - s->norintsts &= ~0x8100; - s->norintsts |= value & 0x8100; - s->errintsts &= ~(value >> 16); - - if (s->errintsts == 0) { - s->norintsts &= ~S5C_HSMMC_NIS_ERR; /* Error Interrupt clear */ - } - break; - case S5C_HSMMC_NORINTSTSEN: - s->norintstsen = (uint16_t)value; - s->errintstsen = (uint16_t)(value >> 16); - break; - case S5C_HSMMC_NORINTSIGEN: - s->norintsigen = (uint16_t)value; - s->errintsigen = (uint16_t)(value >> 16); - break; - case S5C_HSMMC_CONTROL2: - s->control2 = value; - break; - case S5C_HSMMC_CONTROL3: - s->control3 = value; - break; - case S5C_HSMMC_CONTROL4: - /* Nothing for QENU emulation */ - break; - default: - hw_error("s5pc1xx.mmc: bad write offset " TARGET_FMT_plx "\n", offset); - } -} - -static CPUReadMemoryFunc *mmc_readfn[] = { - mmc_readb, - mmc_readw, - mmc_readl -}; - -static CPUWriteMemoryFunc *mmc_writefn[] = { - mmc_writeb, - mmc_writew, - mmc_writel -}; - -static void s5pc1xx_mmc_save(QEMUFile *f, void *opaque) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - int i; - - /* FIXME: must the structure below be saved? - * SDState *card; */ - - qemu_put_8s (f, &s->dma_transcpt); - qemu_put_be32s(f, &s->cmdarg); - qemu_put_be32s(f, &s->respcmd); - - for(i = 0; i < 4; i++) { - qemu_put_be32s(f, &s->response[i]); - } - - qemu_put_be32s(f, &s->sysad); - qemu_put_be16s(f, &s->blksize); - qemu_put_be16s(f, &s->blkcnt); - qemu_put_be32s(f, &s->argument); - qemu_put_be16s(f, &s->trnmod); - qemu_put_be16s(f, &s->cmdreg); - qemu_put_be32s(f, &s->prnsts); - qemu_put_8s (f, &s->hostctl); - qemu_put_8s (f, &s->pwrcon); - qemu_put_be16s(f, &s->clkcon); - qemu_put_8s (f, &s->timeoutcon); - qemu_put_8s (f, &s->swrst); - qemu_put_be16s(f, &s->norintsts); - qemu_put_be16s(f, &s->errintsts); - qemu_put_be16s(f, &s->norintstsen); - qemu_put_be16s(f, &s->errintstsen); - qemu_put_be16s(f, &s->norintsigen); - qemu_put_be16s(f, &s->errintsigen); - qemu_put_be32s(f, &s->control2); - qemu_put_be32s(f, &s->control3); - - qemu_put_timer(f, s->response_timer); - qemu_put_timer(f, s->insert_timer); -} - -static int s5pc1xx_mmc_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - /* FIXME: SDState *card; */ - qemu_get_8s (f, &s->dma_transcpt); - qemu_get_be32s(f, &s->cmdarg); - qemu_get_be32s(f, &s->respcmd); - - for(i = 0; i < 4; i++) { - qemu_get_be32s(f, &s->response[i]); - } - - qemu_get_be32s(f, &s->sysad); - qemu_get_be16s(f, &s->blksize); - qemu_get_be16s(f, &s->blkcnt); - qemu_get_be32s(f, &s->argument); - qemu_get_be16s(f, &s->trnmod); - qemu_get_be16s(f, &s->cmdreg); - qemu_get_be32s(f, &s->prnsts); - qemu_get_8s (f, &s->hostctl); - qemu_get_8s (f, &s->pwrcon); - qemu_get_be16s(f, &s->clkcon); - qemu_get_8s (f, &s->timeoutcon); - qemu_get_8s (f, &s->swrst); - qemu_get_be16s(f, &s->norintsts); - qemu_get_be16s(f, &s->errintsts); - qemu_get_be16s(f, &s->norintstsen); - qemu_get_be16s(f, &s->errintstsen); - qemu_get_be16s(f, &s->norintsigen); - qemu_get_be16s(f, &s->errintsigen); - qemu_get_be32s(f, &s->control2); - qemu_get_be32s(f, &s->control3); - - qemu_get_timer(f, s->response_timer); - qemu_get_timer(f, s->insert_timer); - - return 0; -} - -static void mmc_reset(void *opaque) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - - if (s->card) { - s->prnsts = 0x1ff0000; - s->norintsts |= 0x0040; - } else { - s->prnsts = 0x1fa0000; - s->norintsts = 0; - } - s->cmdarg = 0; - s->respcmd = 0; - s->response[0] = 0; - s->response[1] = 0; - s->response[2] = 0; - s->response[3] = 0; -} - -static void s5pc1xx_mmc_raise_insertion_irq(void *opaque) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - DPRINTF("raise IRQ response\n"); - - if (s->norintsts & S5C_HSMMC_NIS_REMOVE) { - DPRINTF("s5pc1xx.mmc: raise_insertion_irq - set timer!\n"); - qemu_mod_timer(s->insert_timer, - qemu_get_clock(vm_clock) + INSERTION_DELAY); - } else { - DPRINTF("s5pc1xx.mmc: raise_insertion_irq - raise irq!\n"); - s->norintsts |= S5C_HSMMC_NIS_INSERT; - qemu_irq_raise(s->irq); - } -} - -static void s5pc1xx_mmc_insert_eject(void *opaque, int irq, int level) -{ - S5pc1xxMMCState *s = (S5pc1xxMMCState *)opaque; - DPRINTF("change card state: %s!\n", level ? "insert" : "eject"); - - if (s->norintsts & S5C_HSMMC_NIS_REMOVE) { - if (level) { - DPRINTF("change card state: timer set!\n"); - qemu_mod_timer(s->insert_timer, - qemu_get_clock(vm_clock) + INSERTION_DELAY); - } - } else { - s->norintsts |= level ? S5C_HSMMC_NIS_INSERT : S5C_HSMMC_NIS_REMOVE; - qemu_irq_raise(s->irq); - } -} - -static int s5pc1xx_mmc_init(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxMMCState *s = FROM_SYSBUS(S5pc1xxMMCState, dev); - BlockDriverState *bd; - - sysbus_init_irq(dev, &s->irq); - iomemtype = cpu_register_io_memory(mmc_readfn, mmc_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5C_HSMMC_REG_SIZE, iomemtype); - - bd = qdev_init_bdrv(&dev->qdev, IF_SD); - - if ((bd == NULL)) { - s->card = NULL; - DPRINTF("s->card = NULL\n"); - } else { - s->eject = qemu_allocate_irqs(s5pc1xx_mmc_insert_eject, s, 1)[0]; - - DPRINTF("name = %s, sectors = %ld\n", - bd->device_name, bd->total_sectors); - - s->card = sd_init(bd, 0); - sd_set_cb(s->card, NULL, s->eject); - } - - qemu_register_reset(mmc_reset, s); - mmc_reset(s); - - s->response_timer = - qemu_new_timer(vm_clock, s5pc1xx_mmc_raise_end_command_irq, s); - - s->insert_timer = - qemu_new_timer(vm_clock, s5pc1xx_mmc_raise_insertion_irq, s); - - register_savevm(&dev->qdev, "s5pc1xx.mmc", -1, 1, - s5pc1xx_mmc_save, s5pc1xx_mmc_load, s); - - return 0; -} - -static void s5pc1xx_mmc_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.mmc", sizeof(S5pc1xxMMCState), - s5pc1xx_mmc_init); -} - -device_init(s5pc1xx_mmc_register_devices) diff --git a/hw/s5pc1xx_nand.c b/hw/s5pc1xx_nand.c deleted file mode 100644 index 242c2bd..0000000 --- a/hw/s5pc1xx_nand.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * S5PC1XX NAND controller. - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - */ - -#include "hw.h" -#include "flash.h" -#include "sysbus.h" - - -#define S5PC1XX_NAND_REG_MEM_SIZE 0x44 - - -typedef struct S5pc1xxNFConState { - SysBusDevice busdev; - - uint32_t config; - uint32_t control; - /* TODO: how does this status and nand chip status corellate? */ - uint32_t status; - - NANDFlashState *flash; -} S5pc1xxNFConState; - - -static uint32_t nfcon_read32(void *opaque, target_phys_addr_t offset) -{ - uint32_t x, res, i; - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - switch (offset) { - case 0x00: /* NFCONF */ - return s->config; - case 0x04: /* NFCONT */ - return s->control; - case 0x08: /* NFCMMD */ - case 0x0C: /* NFADDR */ - return 0x0; - case 0x10: /* NFDATA */ - res = 0; - nand_setpins(s->flash, 0, 0, 0, 1, 0); - for (i = 0; i < 4; i++) { - x = nand_getio(s->flash); - res = res | (x << (8 * i)); - } - return res; - case 0x14: /* NFMECCD0 */ - case 0x18: /* NFMECCD1 */ - case 0x1C: /* NFSECCD */ - return 0; - case 0x20: /* NFSBLK */ - case 0x24: /* NFEBLK */ - /* TODO: implement this */ - return 0; - case 0x28: /* NFSTAT */ - return s->status; - case 0x2C: /* NFECCERR0 */ - case 0x30: /* NFECCERR1 */ - case 0x34: /* NFMECC0 */ - case 0x38: /* NFMECC1 */ - case 0x3C: /* NFSECC */ - case 0x40: /* NFMLCBITPT */ - return 0; - default: - hw_error("s5pc1xx.nand: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static uint32_t nfcon_read16(void *opaque, target_phys_addr_t offset) -{ - uint32_t x, res, i; - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - if (offset == 0x10) { - nand_setpins(s->flash, 0, 0, 0, 1, 0); - res = 0; - for (i = 0; i < 2; i++) { - x = nand_getio(s->flash); - res = res | (x << (8 * i)); - } - return res; - } else { - hw_error("s5pc1xx.nand: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static uint32_t nfcon_read8(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - if (offset == 0x10) { - nand_setpins(s->flash, 0, 0, 0, 1, 0); - return nand_getio(s->flash); - } else { - hw_error("s5pc1xx.nand: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static void nfcon_write32(void *opaque, target_phys_addr_t offset, uint32_t val) -{ - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - switch (offset) { - case 0x00: /* NFCONF */ - s->config = val; - break; - case 0x04: /* NFCONT */ - s->control = val; - break; - case 0x08: /* NFCMMD */ - case 0x0C: /* NFADDR */ - case 0x10: /* NFDATA */ - switch (offset) { - case 0x08: - nand_setpins(s->flash, 1, 0, 0, 1, 0); - break; - case 0x0C: - nand_setpins(s->flash, 0, 1, 0, 1, 0); - break; - case 0x10: - nand_setpins(s->flash, 0, 0, 0, 1, 0); - break; - } - nand_setio(s->flash, (val >> 0) & 0xff); - nand_setio(s->flash, (val >> 8) & 0xff); - nand_setio(s->flash, (val >> 16) & 0xff); - nand_setio(s->flash, (val >> 24) & 0xff); - break; - case 0x14: /* NFMECCD0 */ - case 0x18: /* NFMECCD1 */ - case 0x1C: /* NFSECCD */ - break; - case 0x20: /* NFSBLK */ - case 0x24: /* NFEBLK */ - /* TODO: implement this */ - break; - case 0x28: /* NFSTAT */ - /* Ignore written value. Documentation states that this register is - R/W, but it describes states of the input pins. So what does write - to it suppose to do? */ - break; - case 0x2C: /* NFECCERR0 */ - case 0x30: /* NFECCERR1 */ - case 0x34: /* NFMECC0 */ - case 0x38: /* NFMECC1 */ - case 0x3C: /* NFSECC */ - case 0x40: /* NFMLCBITPT */ - break; - default: - hw_error("s5pc1xx.nand: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -static void nfcon_write16(void *opaque, target_phys_addr_t offset, uint32_t val) -{ - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - switch (offset) { - case 0x08: - nand_setpins(s->flash, 1, 0, 0, 1, 0); - break; - case 0x0C: - nand_setpins(s->flash, 0, 1, 0, 1, 0); - break; - case 0x10: - nand_setpins(s->flash, 0, 0, 0, 1, 0); - break; - default: - hw_error("s5pc1xx.nand: bad write offset " TARGET_FMT_plx "\n", - offset); - } - nand_setio(s->flash, (val >> 0) & 0xff); - nand_setio(s->flash, (val >> 8) & 0xff); -} - -static void nfcon_write8(void *opaque, target_phys_addr_t offset, uint32_t val) -{ - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - switch (offset) { - case 0x08: - nand_setpins(s->flash, 1, 0, 0, 1, 0); - break; - case 0x0C: - nand_setpins(s->flash, 0, 1, 0, 1, 0); - break; - case 0x10: - nand_setpins(s->flash, 0, 0, 0, 1, 0); - break; - default: - hw_error("s5pc1xx.nand: bad write offset " TARGET_FMT_plx "\n", - offset); - } - nand_setio(s->flash, (val >> 0) & 0xff); -} - -static CPUReadMemoryFunc * const nfcon_readfn[] = { - nfcon_read8, - nfcon_read16, - nfcon_read32 -}; - -static CPUWriteMemoryFunc * const nfcon_writefn[] = { - nfcon_write8, - nfcon_write16, - nfcon_write32 -}; - -static void s5pc1xx_nand_save(QEMUFile *f, void *opaque) -{ - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - qemu_put_be32s(f, &s->config); - qemu_put_be32s(f, &s->control); - qemu_put_be32s(f, &s->status); -} - -static int s5pc1xx_nand_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->config); - qemu_get_be32s(f, &s->control); - qemu_get_be32s(f, &s->status); - - return 0; -} - -static void s5pc1xx_nand_reset(void *opaque) -{ - S5pc1xxNFConState *s = (S5pc1xxNFConState *)opaque; - - s->config = 0x00001000; - s->control = 0x000100C6; - s->status = 0xF0800F0D; -} - -static int s5pc1xx_nand_init(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxNFConState *s = FROM_SYSBUS(S5pc1xxNFConState, dev); - - s->flash = nand_init(NAND_MFR_SAMSUNG, 0xA2); - s5pc1xx_nand_reset(s); - - iomemtype = cpu_register_io_memory(nfcon_readfn, nfcon_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_NAND_REG_MEM_SIZE, iomemtype); - - qemu_register_reset(s5pc1xx_nand_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.nand", -1, 1, - s5pc1xx_nand_save, s5pc1xx_nand_load, s); - - return 0; -} - -static void s5pc1xx_nand_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.nand", sizeof(S5pc1xxNFConState), - s5pc1xx_nand_init); -} - -device_init(s5pc1xx_nand_register_devices) diff --git a/hw/s5pc1xx_onedram.c b/hw/s5pc1xx_onedram.c deleted file mode 100644 index 2ca0faf..0000000 --- a/hw/s5pc1xx_onedram.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * S5PC1XX OneDRAM controller. - * - * Contributed by Kefeng Li - */ - -#include "s5pc1xx_onedram.h" - -#define TICK_COUNTDOWN 50 - -uint32_t sem_retry = 50; - - -/* Command handler */ -static int onedram_req_active_handler(S5pc1xxOneDRAMState *s) -{ - uint16_t cmd = INT_COMMAND(INT_MASK_CMD_RES_ACTIVE); - - onedram_send_cmd_to_pda(s, cmd); - return COMMAND_SUCCESS; -} - -static int onedram_smp_req_handler(S5pc1xxOneDRAMState *s) -{ - uint16_t cmd; - - onedram_put_authority(s); - - cmd = INT_COMMAND(INT_MASK_CMD_SMP_REP); - onedram_send_cmd_to_pda(s, cmd); - - return COMMAND_SUCCESS; -} - - -/* timer for waiting the semaphore for sem_retry times try */ -static void onedram_wait_semaphore(void *opaque) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - int64_t timeout; - - if(sem_retry <= 0) { - fprintf(stderr, "time out to wait semaphore from AP\n"); - qemu_del_timer(s->sem_timer); - sem_retry = 100; - } else if(onedram_read_sem(s)) { - sem_retry--; - timeout = get_ticks_per_sec(); - qemu_mod_timer(s->sem_timer, qemu_get_clock(vm_clock) + TICK_COUNTDOWN); - } else { - sem_retry = 100; - qemu_del_timer(s->sem_timer); - onedram_fmt_send_cmd(s); - } -} - -/* try to see if we have semaphore for sending, if not, request it from AP */ -static int onedram_fmt_try_send_cmd(S5pc1xxOneDRAMState *s) -{ - if(onedram_read_sem(s)) { - fprintf(stderr, "onedram_fmt_try_send_cmd - can't get anthority\n"); - qemu_mod_timer(s->sem_timer, qemu_get_clock(vm_clock) + TICK_COUNTDOWN); - } else { - onedram_fmt_send_cmd(s); - } - return 1; -} - -/* the real sending function of fmt */ -static int onedram_fmt_send_cmd(S5pc1xxOneDRAMState *s) -{ - int psrc = -1; - uint32_t len; - int ret = 0; - - onedram_disable_interrupt(s); - onedram_disable_write(s); - - do { - psrc = onedram_read_fmt(s, &len); - - if (psrc < 0) { - ret = -1; - break; - } - if (len == 0) { /* read done */ - ret = 0; - break; - } - if (!onedram_insert_socket(s, psrc, len)) - break; - } while (1); - - onedram_socket_push(s); - - onedram_enable_interrupt(s); - onedram_enable_write(s); - return ret; -} - - -static void onedram_data_handler_fmt_autonomous(S5pc1xxOneDRAMState *s) -{ - uint16_t non_cmd = 0; - uint32_t in_head = 0, in_tail = 0; - - if (onedram_can_access_shm(s)) { - in_head = onedram_read_inhead(s); - in_tail = onedram_read_intail(s); - - if (in_head != in_tail) { - non_cmd |= INT_MASK_SEND_FMT; - fprintf(stderr, "formated partition has head-tail mis-match\n"); - } - } else { - fprintf(stderr, - "onedram_data_handler_fmt_autonomous - can't access shm\n"); - } - - if (non_cmd & INT_MASK_SEND_FMT) - onedram_fmt_try_send_cmd(s); -} - -/*static*/ void onedram_command_handler(S5pc1xxOneDRAMState *s, - uint32_t data) -{ - uint8_t cmd = (uint8_t) (data & 0xff); - - onedram_data_handler_fmt_autonomous(s); - - switch (cmd) { - case INT_MASK_CMD_NONE: - return; - case INT_MASK_CMD_REQ_ACTIVE: - onedram_req_active_handler(s); - return; - case INT_MASK_CMD_RES_ACTIVE: - return; - case INT_MASK_CMD_INIT_START: - return; - case INT_MASK_CMD_INIT_END: - return; - case INT_MASK_CMD_ERR_DISPLAY: - return; - case INT_MASK_CMD_PHONE_START: - return; - case INT_MASK_CMD_REQ_TIME_SYNC: - return; - case INT_MASK_CMD_PHONE_DEEP_SLEEP: - return; - case INT_MASK_CMD_NV_REBUILDING: - return; - case INT_MASK_CMD_EMER_DOWN: - return; - case INT_MASK_CMD_SMP_REQ: - onedram_smp_req_handler(s); - return; - case INT_MASK_CMD_SMP_REP: - return; - default: - fprintf(stderr, "command_handler: Unknown command.. %x\n", cmd); - return; - } -} - -/*static*/ void onedram_data_handler(S5pc1xxOneDRAMState *s, - uint16_t non_cmd) -{ - if (non_cmd & INT_MASK_SEND_FMT) - onedram_fmt_try_send_cmd(s); -} - -/* Shared Memory R/W */ -static uint32_t onedram_can_access_shm(S5pc1xxOneDRAMState *s) -{ - return !(onedram_io_readl(s, ONEDRAM_SEM)); -} - -static int onedram_read_shm(S5pc1xxOneDRAMState *s, uint8_t *buf, - uint32_t offset, uint32_t size) -{ - uint8_t *src_base; - target_phys_addr_t phy_base, src_len; - phy_base = ONEDRAM_SHARED_BASE + offset; - src_len = size; - - if (!onedram_can_access_shm(s)) { - fprintf(stderr, - "onedram_read_shm : can't access to shm\n"); - return 0; - } - - if (size > (ONEDRAM_SHARED_SIZE - offset)){ - fprintf(stderr, - "onedram_read_shm : size exceed the maximum\n"); - return 0; - } - - src_base = cpu_physical_memory_map(phy_base, &src_len, 0); - - if (!src_base) { - fprintf(stderr, - "onedram_read_shm : src_base is NULL\n"); - return 0; - } - - memcpy(buf, src_base, src_len); - - cpu_physical_memory_unmap(src_base, src_len, 0, src_len); - - return 1; -} - -static int onedram_write_shm(S5pc1xxOneDRAMState *s, - const uint8_t *buf, uint32_t offset, - uint32_t size) -{ - uint8_t *src_base; - target_phys_addr_t phy_base, src_len; - phy_base = ONEDRAM_SHARED_BASE + offset; - src_len = size; - - if (!onedram_can_access_shm(s)) { - fprintf(stderr, - "onedram_write_shm : can't access to fmt\n"); - return 0; - } - - if (size > ONEDRAM_IN_FMT_SIZE){ - fprintf(stderr, - "onedram_write_shm : size exceeds the maximum\n"); - return 0; - } - - src_base = cpu_physical_memory_map(phy_base, &src_len, 1); - - if (!src_base) { - fprintf(stderr, - "onedram_write_shm : src_base is NULL\n"); - return 0; - } - - memcpy(src_base, buf, size); - - cpu_physical_memory_unmap(src_base, src_len, 1, src_len); - - return 1; -} - -/* Formatted Shared Memory Operation */ -/*static*/ uint32_t onedram_read_outhead(S5pc1xxOneDRAMState *s) -{ - uint32_t head = 0; - - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_read_shm(s, (uint8_t *)&head, - s->fmt_info->out_head_addr, - s->fmt_info->ptr_size); - } - return head; -} - -/*static*/ uint32_t onedram_read_inhead(S5pc1xxOneDRAMState *s) -{ - uint32_t head = 0; - - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_read_shm(s, (uint8_t *)&head, - s->fmt_info->in_head_addr, - s->fmt_info->ptr_size); - } - return head; -} - -/*static*/ uint32_t onedram_read_outtail(S5pc1xxOneDRAMState *s) -{ - uint32_t tail = 0; - - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_read_shm(s, (uint8_t *)&tail, - s->fmt_info->out_tail_addr, - s->fmt_info->ptr_size); - } - return tail; -} - -/*static*/ uint32_t onedram_read_intail(S5pc1xxOneDRAMState *s) -{ - uint32_t tail = 0; - - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_read_shm(s, (uint8_t *)&tail, - s->fmt_info->in_tail_addr, - s->fmt_info->ptr_size); - } - return tail; -} - -/*static*/ uint32_t onedram_write_outhead(S5pc1xxOneDRAMState *s, - uint32_t head) -{ - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_write_shm(s, (uint8_t *)&head, - s->fmt_info->out_head_addr, - s->fmt_info->ptr_size); - } - return head; -} - -/*static*/ uint32_t onedram_write_inhead(S5pc1xxOneDRAMState *s, - uint32_t head) -{ - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_write_shm(s, (uint8_t *)&head, - s->fmt_info->in_head_addr, - s->fmt_info->ptr_size); - } - return head; -} - -/*static*/ uint32_t onedram_write_outtail(S5pc1xxOneDRAMState *s, - uint32_t tail) -{ - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_write_shm(s, (uint8_t *)&tail, - s->fmt_info->out_tail_addr, - s->fmt_info->ptr_size); - } - return tail; -} - -/*static*/ uint32_t onedram_write_intail(S5pc1xxOneDRAMState *s, - uint32_t tail) -{ - if (!s->fmt_info) { - fprintf(stderr, "err\n"); - } else { - onedram_write_shm(s, (uint8_t *)&tail, - s->fmt_info->in_tail_addr, - s->fmt_info->ptr_size); - } - return tail; -} - -/*static*/ int onedram_read_fmt(S5pc1xxOneDRAMState *s, - uint32_t *len) -{ - int psrc = -1; - uint32_t head = 0, tail = 0; - uint32_t new_tail = 0; - - head = onedram_read_outhead(s); - tail = onedram_read_outtail(s); - - if (head >= s->fmt_info->out_buff_size || - tail >= s->fmt_info->out_buff_size) { - fprintf(stderr, "head(%d) or tail(%d) is out of bound\n", head, tail); - goto done_onedram_read_fmt; - } - - if (head == tail) { - psrc = /*(uint8_t *)*/(s->fmt_info->out_buff_addr + tail); - *len = 0; - goto done_onedram_read_fmt; - } - - if (head > tail) { - /* ------- tail ++++++++++++ head -------- */ - psrc = /*(uint8_t *)*/(s->fmt_info->out_buff_addr + tail); - *len = (head - tail); - } else { - /* +++++++ head ------------ tail ++++++++ */ - psrc = /*(uint8_t *)*/(s->fmt_info->out_buff_addr + tail); - *len = (s->fmt_info->out_buff_size - tail); - } - - /* new tail */ - new_tail = (uint32_t)((tail + *len) % s->fmt_info->out_buff_size); - onedram_write_outtail(s, new_tail); - -done_onedram_read_fmt: - return psrc; -} - -static int onedram_insert_socket(S5pc1xxOneDRAMState *s, - uint32_t psrc, uint16_t size) -{ - uint8_t *buf; - - if ((s->socket_len + size) >= SOCKET_BUFFER_MAX_SIZE) { - fprintf(stderr, "the socket buffer is overflow!\n"); - - onedram_read_shm(s, (s->socket_buffer + s->socket_len), psrc, - SOCKET_BUFFER_MAX_SIZE - s->socket_len); - s->socket_len = SOCKET_BUFFER_MAX_SIZE; - return 0; - } else { - buf = s->socket_buffer + s->socket_len; - onedram_read_shm(s, buf, psrc, size); - s->socket_len += size; - return 1; - } -} - -void onedram_socket_push(S5pc1xxOneDRAMState *s) -{ - onedram_tcp_write(s, s->socket_buffer, s->socket_len); - s->socket_len = 0; -} - -int onedram_write_fmt(S5pc1xxOneDRAMState *s, const uint8_t *buf, - uint32_t len) -{ - int ret = FAIL; - uint32_t size = 0; - uint32_t head = 0, tail = 0; - uint16_t irq_mask = 0; - - if (!s->fmt_info || !buf) - return FAIL; - - onedram_disable_interrupt(s); - onedram_disable_write(s); - - head = onedram_read_inhead(s); - tail = onedram_read_intail(s); - - if (head < tail) { - /* +++++++++ head ---------- tail ++++++++++ */ - size = tail - head - 1; - size = (len > size) ? size : len; - - onedram_write_shm(s, (uint8_t *)buf, - s->fmt_info->in_buff_addr + head, size); - ret = size; - } else if (tail == 0) { - /* tail +++++++++++++++ head --------------- */ - size = s->fmt_info->in_buff_size - head - 1; - size = (len > size) ? size : len; - - onedram_write_shm(s, (uint8_t *)buf, - s->fmt_info->in_buff_addr + head, size); - ret = size; - } else { - /* ------ tail +++++++++++ head ------------ */ - size = s->fmt_info->in_buff_size - head; - size = (len > size) ? size : len; - - onedram_write_shm(s, (uint8_t *)buf, - s->fmt_info->in_buff_addr + head, size); - ret = (int)size; - - if ((int)len > ret) { - size = (len - ret > tail - 1) ? tail - 1 : len - ret; - buf += ret; - onedram_write_shm(s, (uint8_t *)buf, - s->fmt_info->in_buff_addr, size); - ret += (int)size; - } - } - - /* calculate new head */ - head = (uint32_t)((head + ret) % s->fmt_info->in_buff_size); - onedram_write_inhead(s, head); - - if (head >= s->fmt_info->in_buff_size || - tail >= s->fmt_info->in_buff_size) { - fprintf(stderr, "head(%d) or tail(%d) is out of bound\n", head, tail); - goto err_onedram_write_fmt; - } - - /* send interrupt to the phone, if.. */ - irq_mask = INT_MASK_VALID; - - if (ret > 0) - irq_mask |= s->fmt_info->mask_send; - - if ((int)len > ret) - irq_mask |= s->fmt_info->mask_req_ack; - - onedram_put_authority(s); - onedram_enable_interrupt(s); - onedram_send_cmd_to_pda(s, irq_mask); - onedram_enable_write(s); - - return ret; - -err_onedram_write_fmt: - onedram_put_authority(s); - onedram_enable_interrupt(s); - onedram_enable_write(s); - - return ret; -} - -/* Interrupt Operation */ -static uint32_t onedram_irq_cp_raise_32(S5pc1xxOneDRAMState *s) -{ - uint32_t irq_mask; - int64_t timeout; - - s->irq_onedram_int_cp_pending = 1; - irq_mask = onedram_io_readl(s, ONEDRAM_MBX_BA); - - switch (irq_mask) { - case IPC_CP_IMG_LOADED: - onedram_io_writel(s, ONEDRAM_MBX_AB, IPC_CP_READY); - timeout = get_ticks_per_sec(); - qemu_mod_timer(s->bootup_timer, qemu_get_clock(vm_clock) + timeout); - return IRQ_HANDLED; - case IPC_CP_READY_FOR_LOADING: - return IRQ_HANDLED; - default: - fprintf(stderr, "onedram_irq_cp_raise_32: unknown command\n"); - break; - } - - return IRQ_HANDLED; -} - -static uint32_t onedram_irq_cp_raise_16(S5pc1xxOneDRAMState *s) -{ - uint16_t irq_mask; - s->irq_onedram_int_cp_pending = 1; - - irq_mask = (uint16_t)onedram_io_readl(s, ONEDRAM_MBX_BA); - - if (!(irq_mask & INT_MASK_VALID)) { - fprintf(stderr, "Invalid interrupt mask: 0x%04x\n", irq_mask); - return IRQ_NONE; - } - - if (irq_mask & INT_MASK_COMMAND) { - irq_mask &= ~(INT_MASK_VALID | INT_MASK_COMMAND); - onedram_command_handler(s, irq_mask); - } else { - irq_mask &= ~INT_MASK_VALID; - onedram_data_handler(s, irq_mask); - } - - return IRQ_HANDLED; -} - -void onedram_disable_interrupt(S5pc1xxOneDRAMState *s) -{ - s->onedram_state.interruptable = 0; -} - -void onedram_enable_interrupt(S5pc1xxOneDRAMState *s) -{ - s->onedram_state.interruptable = 1; -} - -uint16_t onedram_interruptable(S5pc1xxOneDRAMState *s) -{ - return s->onedram_state.interruptable; -} - -static void onedram_irq_cp_lower(S5pc1xxOneDRAMState *s) -{ - s->irq_onedram_int_cp_pending = 0; -} - -static uint32_t onedram_irq_cp_pending(S5pc1xxOneDRAMState *s) -{ - return s->irq_onedram_int_cp_pending; -} - -static void onedram_irq_ap_raise(S5pc1xxOneDRAMState *s) -{ - s->irq_onedram_int_ap_pending = 1; - qemu_irq_raise(s->irq_onedram_int_ap); -} - -static void onedram_irq_ap_lower(S5pc1xxOneDRAMState *s) -{ - s->irq_onedram_int_ap_pending = 0; - qemu_irq_lower(s->irq_onedram_int_ap); -} - -static uint32_t onedram_irq_ap_pending(S5pc1xxOneDRAMState *s) -{ - return s->irq_onedram_int_ap_pending; -} - -/* Authority Operation */ -unsigned int onedram_read_sem(S5pc1xxOneDRAMState *s) -{ - unsigned int sem; - - sem = onedram_io_readl(s, ONEDRAM_SEM); - - return sem; -} - -static void onedram_put_authority(S5pc1xxOneDRAMState *s) -{ - uint32_t sem; - sem = 0x1; - onedram_io_writel(s, ONEDRAM_SEM, sem); -} - -int onedram_try_get_authority(S5pc1xxOneDRAMState *s) -{ - uint16_t cmd = 0; - - if(!onedram_read_sem(s)) - return TRUE; - - cmd = INT_COMMAND(INT_MASK_CMD_SMP_REQ); - onedram_send_cmd_to_pda(s, cmd); - - return FALSE; -} - -void onedram_disable_write(S5pc1xxOneDRAMState *s) -{ - s->onedram_state.writable = 0; -} - -void onedram_enable_write(S5pc1xxOneDRAMState *s) -{ - s->onedram_state.writable = 1; -} - -uint16_t onedram_writable(S5pc1xxOneDRAMState *s) -{ - return s->onedram_state.writable; -} - -void onedram_send_cmd_to_pda(S5pc1xxOneDRAMState *s, uint16_t val) -{ - uint16_t check_ab; - - check_ab = (uint16_t)onedram_io_readl(s, ONEDRAM_CHECK_AB); - check_ab &= 0x1; - if (!check_ab) { - onedram_io_writel(s, ONEDRAM_MBX_AB, (uint32_t)val); - } else { - fprintf(stderr, "mailbox_ab has not been read by AP yet!\n"); - } -} - -/* Boot up timer */ -static void onedram_bootup(void *opaque) -{ - uint16_t cmd; - - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - if(!s->vmodem_bootup) { - onedram_io_writel(s, ONEDRAM_MBX_AB, IPC_CP_READY_FOR_LOADING); - s->vmodem_bootup = 1; - - } else { - /* Init the in/out head/tail */ - onedram_write_inhead(s, 0); - onedram_write_intail(s, 0); - onedram_write_outhead(s, 0); - onedram_write_outtail(s, 0); - /* put the authority to AP to let it access to shared memory */ - onedram_put_authority(s); - cmd = INT_COMMAND(INT_MASK_CMD_PHONE_START|CP_CHIP_INFINEON); - onedram_send_cmd_to_pda(s, cmd); - qemu_del_timer(s->bootup_timer); - } -} - -/* Register Modem */ -static void onedram_register_modem(S5pc1xxOneDRAMState *s, - ModemPlatformData *mp) -{ - /* fmt info */ - s->fmt_info->in_head_addr = mp->in_fmt_base; - s->fmt_info->in_tail_addr = mp->in_fmt_base + mp->ptr_fmt_size; - s->fmt_info->in_buff_addr = - FMT_IN_BUF_PTR/*mp->in_fmt_base + (mp->ptr_fmt_size << 1)*/; - s->fmt_info->in_buff_size = mp->in_fmt_size; - s->fmt_info->out_head_addr = mp->out_fmt_base; - s->fmt_info->out_tail_addr = mp->out_fmt_base + mp->ptr_fmt_size; - s->fmt_info->out_buff_addr = - FMT_OUT_BUF_PTR/*mp->out_fmt_base + (mp->ptr_fmt_size << 1)*/; - s->fmt_info->out_buff_size = mp->out_fmt_size; - s->fmt_info->mask_req_ack = INT_MASK_REQ_ACK_FMT; - s->fmt_info->mask_res_ack = INT_MASK_RES_ACK_FMT; - s->fmt_info->mask_send = INT_MASK_SEND_FMT; - s->fmt_info->ptr_size = mp->ptr_fmt_size; -} - -/* onedram IO R/W */ -static uint32_t onedram_io_readb(void *opaque, - target_phys_addr_t offset) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - switch (offset) { - case 0x00: - return (s->sem) & 0x000000FF; - case 0x01: - return ((s->sem >> 8 ) & 0x000000FF); - case 0x20: - return (s->mbx_ab) & 0x000000FF; - case 0x21: - /* If interrupt is pending, once after AP reads the mailbox_ab, - * we should clear the pending */ - if (onedram_irq_ap_pending(s)) - onedram_irq_ap_lower(s); - /* set check_ab to 0 means the mailbox_ab has been read by AP */ - s->check_ab = 0; - return ((s->mbx_ab >> 8) & 0x000000FF); - /* when modem is booting, the AP will read the high two bytes of mail_box - * (only for new onedram driver) */ - case 0x22: - return ((s->mbx_ab >> 16) & 0x000000FF); - case 0x23: - /* If interrupt is pending, once after AP reads the mailbox_ab, - * we should clear the pending */ - if (onedram_irq_ap_pending(s)) - onedram_irq_ap_lower(s); - /* set check_ab to 0 means the mailbox_ab has been read by AP */ - s->check_ab = 0; - return ((s->mbx_ab >> 24) & 0x000000FF); - case 0x40: - return (s->mbx_ba) & 0x000000FF; - case 0x41: - if (onedram_irq_cp_pending(s)) - onedram_irq_cp_lower(s); - /* set check_ba to 0 means the mailbox_ab has been read by CP */ - s->check_ba = 0; - return ((s->mbx_ba >> 8 ) & 0x000000FF); - case 0xA0: - return (s->check_ab) & 0x000000FF; - case 0xA1: - return ((s->check_ab >> 8 ) & 0x000000FF); - case 0xC0: - return ((s->check_ba) & 0x000000FF); - case 0xC1: - return ((s->check_ba >> 8 ) & 0x000000FF); - default: - hw_error("onedram: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static uint32_t onedram_io_readl(void *opaque, - target_phys_addr_t offset) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - switch (offset) { - case 0x00: - return s->sem; - case 0x20: - /* If interrupt is pending, once AP reads the mailbox_ab, - * we should clear the pending */ - if (onedram_irq_ap_pending(s)) - onedram_irq_ap_lower(s); - /* set check_ab to 0 means the mailbox_ab has been read by AP */ - s->check_ab = 0; - return s->mbx_ab; - case 0x40: - if (onedram_irq_cp_pending(s)) - onedram_irq_cp_lower(s); - /* set check_ba to 0 means the mailbox_ab has been read by CP */ - s->check_ba = 0; - return s->mbx_ba; - case 0xA0: - return s->check_ab; - case 0xC0: - return s->check_ba; - default: - hw_error("onedram: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static void onedram_io_writeb(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - switch (offset) { - case 0x00: - s->sem = val; - break; - case 0x20: - (s->mbx_ab) = (val & 0x000000FF); - break; - case 0x21: - (s->mbx_ab) |= ((val << 8) & 0x0000FF00) ; - /* set check_ab to 1 means the mailbox_ab is waiting for AP to read */ - s->check_ab = 1; - /* If interrupt is not pending, raise the interrupt to AP */ - if (!onedram_irq_ap_pending(s)) - onedram_irq_ap_raise(s); - break; - case 0x40: - (s->mbx_ba) = (val & 0x000000FF); - break; - case 0x41: - (s->mbx_ba) |= ((val << 8) & 0x0000FF00); - /* set check_ab to 1 means the mailbox_ba is waiting for CP to read */ - s->check_ba = 1; - /* raise an interrupt to inform CP that there is a message has come */ - if (onedram_interruptable(s)) - onedram_irq_cp_raise_16(s); - break; - case 0xA0: - (s->check_ab) = (val & 0x000000FF); - break; - case 0xA1: - (s->check_ab) |= ((val << 8) & 0x0000FF00); - break; - case 0xC0: - (s->check_ba) = (val & 0x000000FF); - break; - case 0xC1: - (s->check_ba) |= ((val << 8) & 0x0000FF00) ; - break; - default: - hw_error("onedram: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -static void onedram_io_writel(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - switch (offset) { - case 0x00: - s->sem = val; - break; - case 0x20: - s->mbx_ab = val; - s->check_ab = 1; - if (!onedram_irq_ap_pending(s)) - onedram_irq_ap_raise(s); - break; - case 0x40: - s->mbx_ba = val; - s->check_ba = 1; - if (onedram_interruptable(s)) - onedram_irq_cp_raise_32(s); - break; - case 0xA0: - s->check_ab = val; - break; - case 0xC0: - s->check_ba = val; - break; - default: - hw_error("onedram: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -/* - * In mailbox there are 2 bytes CMD and 4 bytes message, - * but 4 bytes only for booting the phone. - * in other cases, only use 2 bytes read - */ -static CPUReadMemoryFunc * const onedram_mm_read[] = { - onedram_io_readb, - onedram_io_readl, - onedram_io_readl -}; - -static CPUWriteMemoryFunc * const onedram_mm_write[] = { - onedram_io_writeb, - onedram_io_writel, - onedram_io_writel -}; - -static void s5pc1xx_onedram_save(QEMUFile *f, void *opaque) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - qemu_put_be32s(f, &s->magic_code); - qemu_put_be32s(f, &s->sem); - qemu_put_be32s(f, &s->mbx_ab); - qemu_put_be32s(f, &s->mbx_ba); - qemu_put_be32s(f, &s->check_ab); - qemu_put_be32s(f, &s->check_ba); - qemu_put_be32s(f, &s->irq_onedram_int_ap_pending); - qemu_put_be32s(f, &s->irq_onedram_int_cp_pending); - - /* FIXME: must the structure below be saved? - * CharDriverState *socket; */ - qemu_put_be32s(f, &s->vmodem_connected); - qemu_put_be32s(f, &s->vmodem_bootup); - - qemu_put_be32s (f, &s->socket_len); - qemu_put_buffer(f, s->socket_buffer, s->socket_len); - - qemu_put_be16s(f, &s->onedram_state.waiting_authority); - qemu_put_be16s(f, &s->onedram_state.waiting_sem_rep); - qemu_put_be16s(f, &s->onedram_state.waiting_check); - qemu_put_be16s(f, &s->onedram_state.non_cmd); - qemu_put_be16s(f, &s->onedram_state.send_cmd); - qemu_put_be16s(f, &s->onedram_state.interruptable); - qemu_put_be16s(f, &s->onedram_state.writable); - - qemu_put_8s (f, &s->onedram_state.send_size); - qemu_put_buffer(f, s->onedram_state.send_buf, s->onedram_state.send_size); - - qemu_put_timer(f, s->bootup_timer); - qemu_put_timer(f, s->sem_timer); -} - -static int s5pc1xx_onedram_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->magic_code); - qemu_get_be32s(f, &s->sem); - qemu_get_be32s(f, &s->mbx_ab); - qemu_get_be32s(f, &s->mbx_ba); - qemu_get_be32s(f, &s->check_ab); - qemu_get_be32s(f, &s->check_ba); - qemu_get_be32s(f, &s->irq_onedram_int_ap_pending); - qemu_get_be32s(f, &s->irq_onedram_int_cp_pending); - - /* FIXME: CharDriverState *socket; */ - qemu_get_be32s(f, &s->vmodem_connected); - qemu_get_be32s(f, &s->vmodem_bootup); - - qemu_get_be32s(f, &s->socket_len); - qemu_get_buffer(f, s->socket_buffer, s->socket_len); - - qemu_get_be16s(f, &s->onedram_state.waiting_authority); - qemu_get_be16s(f, &s->onedram_state.waiting_sem_rep); - qemu_get_be16s(f, &s->onedram_state.waiting_check); - qemu_get_be16s(f, &s->onedram_state.non_cmd); - qemu_get_be16s(f, &s->onedram_state.send_cmd); - qemu_get_be16s(f, &s->onedram_state.interruptable); - qemu_get_be16s(f, &s->onedram_state.writable); - - qemu_get_8s(f, &s->onedram_state.send_size); - qemu_get_buffer(f, s->onedram_state.send_buf, s->onedram_state.send_size); - - qemu_get_timer(f, s->bootup_timer); - qemu_get_timer(f, s->sem_timer); - - return 0; -} - -/* Socket for Vmodem operation*/ -static int onedram_tcp_can_read(void *opaque) -{ - return MAX_BUFFER; -} - -static void onedram_tcp_read(void *opaque, const uint8_t *buf, - int size) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - uint32_t send_cmd; - int64_t timeout; - /* In booting stage, we need to set up the connection to - * Vmodem thru Socket */ - if (!s->vmodem_connected) { - if (((uint32_t *)buf)[0] == IPC_CP_CONNECT_APP) { - send_cmd = IPC_AP_CONNECT_ACK; - onedram_tcp_write(s, (uint8_t *)&send_cmd, CONNECT_LENGTH); - s->vmodem_connected = 1; - /* put the anthority to AP, - * because AP will try to load the modem image for CP */ - onedram_put_authority(s); - /* before here, the PSI has been loaded by CP already, - * in the new onedram driver, - * we have to send IPC_CP_READY_FOR_LOADING to AP - * rather than waiting for to be read from AP */ - timeout = get_ticks_per_sec(); - qemu_mod_timer(s->bootup_timer, - qemu_get_clock(vm_clock) + timeout/10); - } - } else { - /* The connection to Vmodem has been set up, - * so now we only exchange IPC */ - if (onedram_writable(s)) { - //onedram_prepare_write_fmt(s, buf, size); - onedram_write_fmt(s, buf, size); - } else { - return; - } - } -} - -void onedram_tcp_write(void *opaque, const uint8_t *buf, uint32_t size) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - s->socket->chr_write(s->socket, buf, size); -} - -static void onedram_tcp_event(void *opaque, int event) -{ - /* not implemented yet */ -} - -static void onedram_tcp_init(void *opaque) -{ - S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque; - - /* open a socket to communicate with vmodem */ - const char *p = "tcp:localhost:7777,server,nowait"; - s->socket= qemu_chr_open("onedram_socket", p, NULL); - - if (!s->socket) - hw_error("onedram: could not open onedram socket\n"); - - qemu_chr_add_handlers(s->socket, onedram_tcp_can_read, - onedram_tcp_read, onedram_tcp_event, - s); -} - -DeviceState *s5pc1xx_onedram_init(const char *name, target_phys_addr_t base, - qemu_irq irq_ap) -{ - DeviceState *dev = qdev_create(NULL, name); - ram_addr_t onedram_shared, onedram_ap; - - qdev_init_nofail(dev); - onedram_ap = qemu_ram_alloc(dev, "s5pc1xx.onedram.ap", ONEDRAM_AP_SIZE); - cpu_register_physical_memory(base, ONEDRAM_AP_SIZE, - onedram_ap | IO_MEM_RAM); - onedram_shared = - qemu_ram_alloc(dev, "s5pc1xx.onedram.shared", ONEDRAM_SHARED_SIZE); - cpu_register_physical_memory(base + ONEDRAM_AP_SIZE, ONEDRAM_SHARED_SIZE, - onedram_shared | IO_MEM_RAM); - sysbus_mmio_map(sysbus_from_qdev(dev), 0, - base + ONEDRAM_AP_SIZE + ONEDRAM_SFR); - sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq_ap); - return dev; -} - -static int s5pc1xx_onedram_init1(SysBusDevice *dev, ModemPlatformData *mp) -{ - S5pc1xxOneDRAMState *s = FROM_SYSBUS(S5pc1xxOneDRAMState, dev); - int onedram_io; - - sysbus_init_irq(dev, &s->irq_onedram_int_ap); - onedram_io = cpu_register_io_memory(onedram_mm_read, - onedram_mm_write, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, ONEDRAM_REGISTER_SIZE, onedram_io); - - s->sem = 0; - s->mbx_ab = 0; - s->mbx_ba = 0; - s->check_ab = 0; - s->check_ba = 0; - - s->irq_onedram_int_ap_pending = 0; - s->irq_onedram_int_cp_pending = 0; - - s->vmodem_connected = 0; - s->vmodem_bootup = 0; - s->fmt_info = (ModemInfo *)qemu_mallocz(sizeof(ModemInfo)); - - s->socket_buffer = (uint8_t *)qemu_mallocz(SOCKET_BUFFER_MAX_SIZE); - s->socket_len = 0; - - s->onedram_state.waiting_authority = FALSE; - s->onedram_state.non_cmd = INT_MASK_CMD_NONE; - s->onedram_state.send_size = 0; - s->onedram_state.waiting_sem_rep = 0; - s->onedram_state.send_buf = NULL; - s->onedram_state.interruptable = 1; - s->onedram_state.writable = 1; - - onedram_register_modem(s, mp); - onedram_tcp_init(s); - - s->bootup_timer = qemu_new_timer(vm_clock, onedram_bootup, s); - s->sem_timer = qemu_new_timer(vm_clock, onedram_wait_semaphore, s); - register_savevm(&dev->qdev, "s5pc1xx.onedram", -1, 1, - s5pc1xx_onedram_save, s5pc1xx_onedram_load, s); - - return 0; -} - -static int s5pc1xx_onedram_aquila_xmm_init(SysBusDevice *dev) -{ - return s5pc1xx_onedram_init1(dev, &aquila_xmm_modem_data); -} -static void s5pc1xx_onedram_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.onedram.aquila.xmm", - sizeof(S5pc1xxOneDRAMState), - s5pc1xx_onedram_aquila_xmm_init); -} - -device_init(s5pc1xx_onedram_register_devices) diff --git a/hw/s5pc1xx_onedram.h b/hw/s5pc1xx_onedram.h deleted file mode 100644 index cd2fb6b..0000000 --- a/hw/s5pc1xx_onedram.h +++ /dev/null @@ -1,397 +0,0 @@ -#ifndef __S5PC1XX_ONEDRAM_H__ -#define __S5PC1XX_ONEDRAM_H__ - -#include "sysbus.h" -#include "console.h" -#include "s5pc1xx.h" -#include "qemu-timer.h" - -#define TRUE 1 -#define FALSE 0 - -#define SUCCESS 1 -#define FAIL -1 - -#define SZ_4K 0x00001000 -#define SZ_1K 0x00000400 -#define SZ_16M 0x01000000 - -/* SDRAM */ -#define S5PC11X_PA_SDRAM (0x30000000) - -/* - * OneDRAM memory map specific definitions - */ -#define ONEDRAM_BASE 0x30000000 -#define ONEDRAM_AP_BASE (ONEDRAM_BASE) -#define ONEDRAM_AP_SIZE 0x05000000 /* 80MB */ -#define ONEDRAM_SHARED_BASE (ONEDRAM_BASE + ONEDRAM_AP_SIZE) -#define ONEDRAM_SHARED_SIZE 0x00500000 /* 0x400000*/ - /* 0xFFF800*/ - /* 16382KB */ -#define ONEDRAM_REGISTER_SIZE 0x800 - -/* - * OneDRAM Interrupt related definitions - */ -#define ONEDRAM_SFR 0xFFF800 -#define ONEDRAM_IO_BASE (ONEDRAM_SHARED_BASE + ONEDRAM_SFR) - -/* A is Modem, B is Application Processor */ -#define ONEDRAM_SEM 0x00 /* semaphore */ -#define ONEDRAM_MBX_AB 0x20 /* mailbox AtoB */ -#define ONEDRAM_MBX_BA 0x40 /* mailbox BtoA */ -#define ONEDRAM_CHECK_AB 0xa0 /* check AtoB */ -#define ONEDRAM_CHECK_BA 0xc0 /* check BtoA */ - -#define IPC_MAGIC_PTR 0x0 -#define IPC_ACCESS_PTR 0x4 - -#define ONEDRAM_START_ADDRESS 0 -#define ONEDRAM_MAGIC_CODE_ADDRESS (ONEDRAM_START_ADDRESS + IPC_MAGIC_PTR) -#define ONEDRAM_ACCESS_ENABLE_ADDRESS (ONEDRAM_START_ADDRESS + IPC_ACCESS_PTR) - -#define IPC_PART_PTR_SIZE 0x4 - -/* formatted region */ -#define FMT_OUT_HEAD_PTR 0x10 -#define FMT_OUT_TAIL_PTR (FMT_OUT_HEAD_PTR + IPC_PART_PTR_SIZE) -#define FMT_IN_HEAD_PTR 0x18 -#define FMT_IN_TAIL_PTR (FMT_IN_HEAD_PTR + IPC_PART_PTR_SIZE) - -/*raw region */ -#define RAW_OUT_HEAD_PTR 0x20 -#define RAW_OUT_TAIL_PTR (RAW_OUT_HEAD_PTR + IPC_PART_PTR_SIZE) -#define RAW_IN_HEAD_PTR 0x28 -#define RAW_IN_TAIL_PTR (RAW_IN_HEAD_PTR + IPC_PART_PTR_SIZE) - -/* remote file system region */ -#define RFS_OUT_HEAD_PTR 0x30 -#define RFS_OUT_TAIL_PTR (RFS_OUT_HEAD_PTR + IPC_PART_PTR_SIZE) -#define RFS_IN_HEAD_PTR 0x38 -#define RFS_IN_TAIL_PTR (RFS_IN_HEAD_PTR + IPC_PART_PTR_SIZE) - -#define CP_FATAL_DISP_SIZE 0xA0 -#define CP_FATAL_DISP_PTR 0x1000 - -#define FMT_BUF_SIZE 0x1000 -#define FMT_OUT_BUF_PTR 0xFE000 -#define FMT_IN_BUF_PTR 0xFF000 - -#define RAW_BUF_SIZE 0x100000 -#define RAW_OUT_BUF_PTR 0x100000 -#define RAW_IN_BUF_PTR 0x200000 - -#define RFS_BUF_SIZE 0x100000 -#define RFS_OUT_BUF_PTR 0x300000 -#define RFS_IN_BUF_PTR 0x400000 - -#define IPC_PART_SIZE 0x500000 - -#define ONEDRAM_OUT_FMT_BASE FMT_OUT_BUF_PTR -#define ONEDRAM_OUT_FMT_SIZE FMT_BUF_SIZE - -#define ONEDRAM_OUT_RAW_BASE RAW_OUT_BUF_PTR -#define ONEDRAM_OUT_RAW_SIZE RAW_BUF_SIZE - -#define ONEDRAM_OUT_RFS_BASE RFS_OUT_BUF_PTR -#define ONEDRAM_OUT_RFS_SIZE RFS_BUF_SIZE - -#define ONEDRAM_IN_FMT_BASE FMT_IN_BUF_PTR -#define ONEDRAM_IN_FMT_SIZE FMT_BUF_SIZE - -#define ONEDRAM_IN_RAW_BASE RAW_IN_BUF_PTR -#define ONEDRAM_IN_RAW_SIZE RAW_BUF_SIZE - -#define ONEDRAM_IN_RFS_BASE RFS_IN_BUF_PTR -#define ONEDRAM_IN_RFS_SIZE RFS_BUF_SIZE - - -#define MAGIC_CODE 0x00aa -#define ACCESS_ENABLE 0x0001 - -#define IRQ_ONEDRAM_INT_AP 11 -#define IRQ_PHONE_ACTIVE 15 - -#define MAX_BUFFER 1024 - -#define CONNECT_LENGTH 4 - -#define TCP_CMD_LENGTH 2 - - -/* AP IPC define */ -#define IPC_AP_CONNECT_ACK 0xABCD1234 -#define IPC_AP_SEND_FMT_ACK 0xCDAB1234 - - -/* CP IPC define */ -#define IPC_CP_CONNECT_APP 0x1234ABCD -#define IPC_CP_READY_FOR_LOADING 0x12341234 -#define IPC_CP_IMG_LOADED 0x45674567 -#define IPC_CP_READY 0xABCDABCD - -/* - * IPC 4.0 specific definitions - */ -#define INT_MASK_VALID 0x0080 -#define INT_MASK_COMMAND 0x0040 - /* If not command */ - #define INT_MASK_REQ_ACK_RFS 0x0400 - #define INT_MASK_RES_ACK_RFS 0x0200 - #define INT_MASK_SEND_RFS 0x0100 - #define INT_MASK_REQ_ACK_FMT 0x0020 - #define INT_MASK_REQ_ACK_RAW 0x0010 - #define INT_MASK_RES_ACK_FMT 0x0008 - #define INT_MASK_RES_ACK_RAW 0x0004 - #define INT_MASK_SEND_FMT 0x0002 - #define INT_MASK_SEND_RAW 0x0001 - -#define INT_MASK_CMD_NONE 0x0000 -#define INT_MASK_CMD_INIT_START 0x0001 -#define INT_MASK_CMD_INIT_END 0x0002 - /* CMD_INIT_END extended bit */ - /* CP boot state */ - #define REQ_ONLINE_BOOT 0x0000 - #define REQ_AIRPLANE_BOOT 0x1000 - /* AP OS type */ - #define AP_OS_ANDROID 0x0100 - #define AP_OS_WINMOBILE 0x0200 - #define AP_OS_LINUX 0x0300 - #define AP_OS_SYMBIAN 0x0400 -#define INT_MASK_CMD_REQ_ACTIVE 0x0003 -#define INT_MASK_CMD_RES_ACTIVE 0x0004 -#define INT_MASK_CMD_REQ_TIME_SYNC 0x0005 -#define INT_MASK_CMD_PHONE_START 0x0008 - /* CMD_PHONE_START extended bit */ - /* CP chip type */ - #define CP_CHIP_QUALCOMM 0x0100 - #define CP_CHIP_INFINEON 0x0200 - #define CP_CHIP_BROADCOM 0x0300 -#define INT_MASK_CMD_ERR_DISPLAY 0x0009 -#define INT_MASK_CMD_PHONE_DEEP_SLEEP 0x000A -#define INT_MASK_CMD_NV_REBUILDING 0x000B -#define INT_MASK_CMD_EMER_DOWN 0x000C -#define INT_MASK_CMD_SMP_REQ 0x000D -#define INT_MASK_CMD_SMP_REP 0x000E -#define INT_MASK_CMD_MAX 0x000F - -#define INT_COMMAND(x) (INT_MASK_VALID | INT_MASK_COMMAND | x) -#define INT_NON_COMMAND(x) (INT_MASK_VALID | x) - -#define BIT_INT_MASK_CMD_REQ_ACTIVE 0x001 -#define BIT_INT_MASK_CMD_ERR_DISPLAY 0x002 -#define BIT_INT_MASK_CMD_PHONE_START 0x004 -#define BIT_INT_MASK_CMD_REQ_TIME_SYNC 0x008 -#define BIT_INT_MASK_CMD_PHONE_DEEP_SLEEP 0x010 -#define BIT_INT_MASK_CMD_NV_REBUILDING 0x020 -#define BIT_INT_MASK_CMD_EMER_DOWN 0x040 -#define BIT_INT_MASK_CMD_SMP_REQ 0x080 -#define BIT_INT_MASK_CMD_SMP_REP 0x100 -#define BIT_MAX 0x200 - -#define FMT_SERVICE 0 -#define RAW_SERVICE 1 -#define RFS_SERVICE 2 - -/* IRQ definition */ -#define IRQ_NONE (0) -#define IRQ_HANDLED (1) -#define IRQ_RETVAL(x) ((x) != 0) - -/* - * Modem deivce partitions. - */ -#define FMT_INDEX 0 -#define RAW_INDEX 1 -#define RFS_INDEX 2 -#define MAX_INDEX 3 - -#define MESG_PHONE_OFF 1 -#define MESG_PHONE_RESET 2 - -#define RETRY 50 -#define TIME_RESOLUTION 10 - -#define COMMAND_SUCCESS 0x00 -#define COMMAND_GET_AUTHORITY_FAIL 0x01 -#define COMMAND_FAIL 0x02 - -#define CONFIG_MODEM_CORE_FMT_SERVICE - -typedef struct ModemServiceOps { - int (*send_cmd_handler)(uint16_t); - void (*resp_cmd_handler)(void); -} ModemServiceOps; - -typedef struct ModemInfo { - /* DPRAM memory addresses */ - uint32_t in_head_addr; - uint32_t in_tail_addr; - uint32_t in_buff_addr; - uint32_t in_buff_size; - - uint32_t out_head_addr; - uint32_t out_tail_addr; - uint32_t out_buff_addr; - uint32_t out_buff_size; - - int ptr_size; - - uint16_t mask_req_ack; - uint16_t mask_res_ack; - uint16_t mask_send; -} ModemInfo; - -typedef struct ModemPlatformData { - const char *name; - uint32_t booting_type; - uint32_t irq_onedram_int_ap; - uint32_t out_fmt_base; - uint32_t out_fmt_size; - - uint32_t in_fmt_base; - uint32_t in_fmt_size; - - int ptr_fmt_size; -} ModemPlatformData; - -/* Booting type definitions */ -#define XMM 1 -#define MSM 2 -#define QSC 3 - -#define QEMU_MODEM XMM - -#define SOCKET_BUFFER_MAX_SIZE SZ_1K - -typedef struct OneDRAMState { - uint16_t waiting_authority; - uint16_t waiting_sem_rep; - uint16_t waiting_check; - uint16_t non_cmd; - uint16_t send_cmd; - uint16_t interruptable; - uint16_t writable; - - uint8_t *send_buf; - uint8_t send_size; -} OneDRAMState; - -typedef struct S5pc1xxOneDRAMState { - SysBusDevice busdev; - - uint32_t magic_code; - uint32_t sem; - uint32_t mbx_ab; - uint32_t mbx_ba; - uint32_t check_ab; - uint32_t check_ba; - - qemu_irq irq_onedram_int_ap; - uint32_t irq_onedram_int_ap_pending; - uint32_t irq_onedram_int_cp_pending; - - CharDriverState *socket; - uint32_t vmodem_connected; - uint32_t vmodem_bootup; - QEMUTimer *bootup_timer; - QEMUTimer *sem_timer; - - /* OneDRAM memory addresses */ - ModemInfo* fmt_info; - - uint8_t *socket_buffer; - uint32_t socket_len; - - OneDRAMState onedram_state; -} S5pc1xxOneDRAMState; - -/* OneDRAM */ -static struct ModemPlatformData aquila_xmm_modem_data = { - .name = "aquila-XMM6160", - .booting_type = XMM, - .irq_onedram_int_ap = 11, - - /* Memory map */ - .out_fmt_base = FMT_OUT_HEAD_PTR, - .out_fmt_size = FMT_BUF_SIZE, - .in_fmt_base = FMT_IN_HEAD_PTR, - .in_fmt_size = FMT_BUF_SIZE, - .ptr_fmt_size = IPC_PART_PTR_SIZE, - -}; - -/* Command handler */ -static int onedram_req_active_handler(S5pc1xxOneDRAMState *s); -static int onedram_smp_req_handler(S5pc1xxOneDRAMState *s); -static int onedram_fmt_try_send_cmd(S5pc1xxOneDRAMState *s); -static int onedram_fmt_send_cmd(S5pc1xxOneDRAMState *s); -static void onedram_data_handler_fmt_autonomous(S5pc1xxOneDRAMState *s); -/*static*/ void onedram_command_handler(S5pc1xxOneDRAMState *s, - uint32_t data); -/*static*/ void onedram_data_handler(S5pc1xxOneDRAMState *s, - uint16_t non_cmd); -static uint32_t onedram_can_access_shm(S5pc1xxOneDRAMState *s); -static int onedram_read_shm(S5pc1xxOneDRAMState *s, uint8_t *buf, - uint32_t offset, uint32_t size); -static int onedram_write_shm(S5pc1xxOneDRAMState *s, - const uint8_t *buf, uint32_t offset, - uint32_t size); -/*static*/ uint32_t onedram_read_outhead(S5pc1xxOneDRAMState *s); -/*static*/ uint32_t onedram_read_inhead(S5pc1xxOneDRAMState *s); -/*static*/ uint32_t onedram_read_outtail(S5pc1xxOneDRAMState *s); -/*static*/ uint32_t onedram_read_intail(S5pc1xxOneDRAMState *s); -/*static*/ uint32_t onedram_write_outhead(S5pc1xxOneDRAMState *s, - uint32_t head); -/*static*/ uint32_t onedram_write_inhead(S5pc1xxOneDRAMState *s, - uint32_t head); -/*static*/ uint32_t onedram_write_outtail(S5pc1xxOneDRAMState *s, - uint32_t tail); -/*static*/ uint32_t onedram_write_intail(S5pc1xxOneDRAMState *s, - uint32_t tail); -/*static*/ int onedram_read_fmt(S5pc1xxOneDRAMState *s, - uint32_t *len); -/*static*/ void onedram_read_fmt_wrapup(S5pc1xxOneDRAMState *s, - const uint16_t non_cmd); -static int onedram_insert_socket(S5pc1xxOneDRAMState *s, - uint32_t psrc, uint16_t size); -void onedram_socket_push(S5pc1xxOneDRAMState *s); -int onedram_write_fmt(S5pc1xxOneDRAMState *s, const uint8_t *buf, - uint32_t len); -static uint32_t onedram_irq_cp_raise_32(S5pc1xxOneDRAMState *s); -static uint32_t onedram_irq_cp_raise_16(S5pc1xxOneDRAMState *s); -void onedram_disable_interrupt(S5pc1xxOneDRAMState *s); -void onedram_enable_interrupt(S5pc1xxOneDRAMState *s); -uint16_t onedram_interruptable(S5pc1xxOneDRAMState *s); -static void onedram_irq_cp_lower(S5pc1xxOneDRAMState *s); -static uint32_t onedram_irq_cp_pending(S5pc1xxOneDRAMState *s); -static void onedram_irq_ap_raise(S5pc1xxOneDRAMState *s); -static void onedram_irq_ap_lower(S5pc1xxOneDRAMState *s); -static uint32_t onedram_irq_ap_pending(S5pc1xxOneDRAMState *s); -unsigned int onedram_read_sem(S5pc1xxOneDRAMState *s); -static void onedram_put_authority(S5pc1xxOneDRAMState *s); -int onedram_try_get_authority(S5pc1xxOneDRAMState *s); -void onedram_disable_write(S5pc1xxOneDRAMState *s); -void onedram_enable_write(S5pc1xxOneDRAMState *s); -uint16_t onedram_writable(S5pc1xxOneDRAMState *s); -void onedram_send_cmd_to_pda(S5pc1xxOneDRAMState *s, uint16_t val); -static void onedram_bootup(void *opaque); -static void onedram_register_modem(S5pc1xxOneDRAMState *s, - ModemPlatformData *mp); -static uint32_t onedram_io_readb(void *opaque, - target_phys_addr_t offset); -static uint32_t onedram_io_readl(void *opaque, - target_phys_addr_t offset); -static void onedram_io_writeb(void *opaque, target_phys_addr_t offset, - uint32_t val); -static void onedram_io_writel(void *opaque, target_phys_addr_t offset, - uint32_t val); -static int onedram_tcp_can_read(void *opaque); -static void onedram_tcp_read(void *opaque, const uint8_t *buf, - int size); -void onedram_tcp_write(void *opaque, const uint8_t *buf, uint32_t size); -static void onedram_tcp_event(void *opaque, int event); -static void onedram_tcp_init(void *opaque); - -#endif diff --git a/hw/s5pc1xx_onenand.c b/hw/s5pc1xx_onenand.c deleted file mode 100644 index 5fe0296..0000000 --- a/hw/s5pc1xx_onenand.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * S5PC1XX OneNAND controller. - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Alexey Merkulov - */ - -#include "sysbus.h" -#include "hw.h" -#include "flash.h" -#include "s5pc1xx.h" - - -/* OneNAND Device Description: - EC - , 50 - device properties, 2E - version */ -#define ONENAND_DEVICE_ID 0xEC502E - -/* Device is mux */ -#define IS_MUX_TYPE 1 - -#define ONENAND_CONTR_REG_BASE 0x00600000 -#define ONENAND_CONTR_REGS_SIZE 0x0000106C - -#define ONENAND_BUFFRES_SIZE 0x00012000 - -#define S5PC110_DMA_TRANS_STATUS_TD (0x1 << 18) -#define S5PC110_DMA_TRANS_STATUS_TB (0x1 << 17) -#define S5PC110_DMA_TRANS_STATUS_TE (0x1 << 16) - - -typedef struct S5pc1xxOneNANDState { - SysBusDevice busdev; - target_phys_addr_t base; - - /* OneNAND Interface Control register */ - uint32_t onenand_if_clrt; - /* OneNAND Interface Async. Timing Control register */ - uint32_t onenand_async_timing; - /* DMA Source Address Register */ - uint32_t dma_src_addr; - /* DMA Source Configuration Register */ - uint32_t dma_src_cfg; - /* DMA Destination Address Register */ - uint32_t dma_dst_addr; - /* DMA Destination Configuration Register */ - uint32_t dma_dst_cfg; - /* DMA Transfer Size Register */ - uint32_t dma_trans_size; - /* DMA Transfer Direction Register */ - uint32_t dma_trans_dir; - /* Sequencer Start Address Offset Register */ - uint32_t sqc_sao; - /* Sequencer Register Control Register */ - uint32_t sqc_reg_ctrl; - /* Sequencer Breakpoint Address Offset#0 Register */ - uint32_t sqc_brpao0; - /* Sequencer Breakpoint Address Offset#1 Register */ - uint32_t sqc_brpao1; - /* Interrupt Controller Sequencer Mask Register */ - uint32_t intc_sqc_mask; - /* Interrupt Controller DMA Mask Register */ - uint32_t intc_dma_mask; - /* Interrupt Controller OneNAND Mask Register */ - uint32_t intc_onenand_mask; -} S5pc1xxOneNANDState; - - -static uint32_t s5pc1xx_onenand_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxOneNANDState *s = (S5pc1xxOneNANDState *)opaque; - /* for compatibility with documentation */ - int test_offset = offset + ONENAND_CONTR_REG_BASE; - - switch (test_offset) { - case 0x00600100: /*RW OneNAND Interface Control register*/ - return s->onenand_if_clrt; - - case 0x00600400: /*RW DMA Source Address Register*/ - return s->dma_src_addr; - case 0x00600404: /*RW DMA Source Configuration Register*/ - return s->dma_src_cfg; - case 0x00600408: /*RW DMA Destination Address Register*/ - return s->dma_dst_addr; - case 0x0060040C: /*RW DMA Destination Configuration Register*/ - return s->dma_dst_cfg; - case 0x00600414: /*RW DMA Transfer Size Register*/ - return s->dma_trans_size; - case 0x00600418: /*WO DMA Transfer Command Register*/ - return 0; - case 0x0060041C: /*RO DMA Transfer Status Register*/ - return S5PC110_DMA_TRANS_STATUS_TD; - case 0x00600420: /*RW DMA Transfer Direction Register*/ - return s->dma_trans_dir; -#if 0 /*TODO: implement support for all of these registers*/ - case 0x00600104: /*WO OneNAND Interface Command register*/ - return 0; - case 0x00600108: /*RW OneNAND Interface Async. Timing*/ - return s->onenand_async_timing; - case 0x0060010C: /*RO OneNAND Interface Status Register*/ - return 0x00FC0000; - case 0x00600600: /*RW Sequencer Start Address Offset Register*/ - return s->sqc_sao; - case 0x00600608: /*WO Sequencer Command Register*/ - return 0; - case 0x0060060C: /*RO Sequencer Status Register*/ - case 0x00600610: /*RO Sequencer Current Address Offset*/ - case 0x00600614: /*RW Sequencer Register Control Register*/ - return s->sqc_reg_ctrl; - case 0x00600618: /*RO Sequencer Register Value Register*/ - case 0x00600620: /*RW Sequencer Breakpoint Address Offset#0*/ - return s->sqc_brpao0; - case 0x00600624: /*RW Sequencer Breakpoint Address Offset#1*/ - return s->sqc_brpao1; - case 0x00601000: /*WO Interrupt Controller Sequencer Clear*/ - return 0; - case 0x00601004: /*WO Interrupt Controller DMA Clear Register*/ - return 0; - case 0x00601008: /*WO Interrupt Controller OneNAND Clear*/ - return 0; - case 0x00601020: /*RW Interrupt Controller Sequencer Mask*/ - return s->intc_sqc_mask; - case 0x00601024: /*RW Interrupt Controller DMA Mask Register*/ - return s->intc_dma_mask; - case 0x00601028: /*RW Interrupt Controller OneNAND Mask*/ - return s->intc_onenand_mask; - case 0x00601040: /*RO Interrupt Controller Sequencer Pending*/ - case 0x00601044: /*RO Interrupt Controller DMA Pending*/ - case 0x00601048: /*RO Interrupt Controller OneNAND Pending*/ - case 0x00601060: /*RO Interrupt Controller Sequencer Status*/ - case 0x00601064: /*RO Interrupt Controller DMA Status Register*/ - case 0x00601068: /*RO Interrupt Controller OneNAND Status*/ -#endif - default: - hw_error("s5pc1xx.onenand: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static int is_inside_onenand(uint32_t offset, target_phys_addr_t base, uint32_t size) -{ - return offset >= base && - offset < base + ONENAND_BUFFRES_SIZE && - offset + size < base + ONENAND_BUFFRES_SIZE; -} - -static void s5pc1xx_onenand_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxOneNANDState *s = (S5pc1xxOneNANDState *)opaque; - uint8_t *buf = NULL; - /* for compatibility with documentation */ - int test_offset = offset + ONENAND_CONTR_REG_BASE; - - switch (test_offset) { - case 0x00600100: /*RW OneNAND Interface Control register*/ - s->onenand_if_clrt = val; - break; - case 0x00600400: /*RW DMA Source Address Register*/ - s->dma_src_addr = val; - break; - case 0x00600404: /*RW DMA Source Configuration Register*/ - s->dma_src_cfg = val; - break; - case 0x00600408: /*RW DMA Destination Address Register*/ - s->dma_dst_addr = val; - break; - case 0x0060040C: /*RW DMA Destination Configuration Register*/ - s->dma_dst_cfg = val; - break; - case 0x00600414: /*RW DMA Transfer Size Register*/ - s->dma_trans_size = val; - break; - case 0x00600418: /*WO DMA Transfer Command Register*/ - if (!is_inside_onenand(s->dma_src_addr, s->base, s->dma_trans_size) && - !is_inside_onenand(s->dma_dst_addr, s->base, s->dma_trans_size)) { - hw_error("s5pc1xx.onenand: invalide memory transfer: src = " - TARGET_FMT_plx ", dst = " TARGET_FMT_plx ", size = 0x%X\n", - (target_phys_addr_t)s->dma_src_addr, - (target_phys_addr_t)s->dma_dst_addr, - s->dma_trans_size); - } - - buf = qemu_malloc(s->dma_trans_size); - cpu_physical_memory_read (s->dma_src_addr, buf, s->dma_trans_size); - cpu_physical_memory_write(s->dma_dst_addr, buf, s->dma_trans_size); - qemu_free(buf); - break; - case 0x0060041C: /*RO DMA Transfer Status Register*/ - break; - case 0x00600420: /*RW DMA Transfer Direction Register*/ - s->dma_trans_dir = val; - break; -#if 0 /*TODO: implement support for all of these registers*/ - case 0x00600104: /*WO OneNAND Interface Command register*/ - /* TODO see WR bits */ - break; - case 0x00600108: /*RW OneNAND Interface Async. Timing*/ - s->onenand_async_timing = val; - break; - case 0x0060010C: /*RO OneNAND Interface Status Register*/ - break; - case 0x00600600: /*RW Sequencer Start Address Offset Register*/ - s->sqc_sao = val; - break; - case 0x00600608: /*WO Sequencer Command Register*/ - break; - case 0x0060060C: /*RO Sequencer Status Register*/ - break; - case 0x00600610: /*RO Sequencer Current Address Offset*/ - break; - case 0x00600614: /*RW Sequencer Register Control Register*/ - s->sqc_reg_ctrl = val; - break; - case 0x00600618: /*RO Sequencer Register Value Register*/ - break; - case 0x00600620: /*RW Sequencer Breakpoint Address Offset#0*/ - s->sqc_brpao0 = val; - break; - case 0x00600624: /*RW Sequencer Breakpoint Address Offset#1*/ - s->sqc_brpao1 = val; - break; - case 0x00601000: /*WO Interrupt Controller Sequencer Clear*/ - break; - case 0x00601004: /*WO Interrupt Controller DMA Clear Register*/ - break; - case 0x00601008: /*WO Interrupt Controller OneNAND Clear*/ - break; - case 0x00601020: /*RW Interrupt Controller Sequencer Mask*/ - s->intc_sqc_mask = val; - break; - case 0x00601024: /*RW Interrupt Controller DMA Mask Register*/ - s->intc_dma_mask = val; - break; - case 0x00601028: /*RW Interrupt Controller OneNAND Mask*/ - s->intc_onenand_mask = val; - break; - case 0x00601040: /*RO Interrupt Controller Sequencer Pending*/ - break; - case 0x00601044: /*RO Interrupt Controller DMA Pending*/ - break; - case 0x00601048: /*RO Interrupt Controller OneNAND Pending*/ - break; - case 0x00601060: /*RO Interrupt Controller Sequencer Status*/ - break; - case 0x00601064: /*RO Interrupt Controller DMA Status Register*/ - break; - case 0x00601068: /*RO Interrupt Controller OneNAND Status*/ - break; -#endif - default: - hw_error("s5pc1xx.onenand: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const onenand_config_reg_mm_read[] = { - s5pc1xx_onenand_read, - s5pc1xx_onenand_read, - s5pc1xx_onenand_read -}; - -static CPUWriteMemoryFunc * const onenand_config_reg_mm_write[] = { - s5pc1xx_onenand_write, - s5pc1xx_onenand_write, - s5pc1xx_onenand_write -}; - -static void s5pc1xx_onenand_save(QEMUFile *f, void *opaque) -{ - S5pc1xxOneNANDState *s = (S5pc1xxOneNANDState *)opaque; - - qemu_put_be32s(f, &s->onenand_if_clrt); - qemu_put_be32s(f, &s->onenand_async_timing); - qemu_put_be32s(f, &s->dma_src_addr); - qemu_put_be32s(f, &s->dma_src_cfg); - qemu_put_be32s(f, &s->dma_dst_addr); - qemu_put_be32s(f, &s->dma_dst_cfg); - qemu_put_be32s(f, &s->dma_trans_size); - qemu_put_be32s(f, &s->dma_trans_dir); - qemu_put_be32s(f, &s->sqc_sao); - qemu_put_be32s(f, &s->sqc_reg_ctrl); - qemu_put_be32s(f, &s->sqc_brpao0); - qemu_put_be32s(f, &s->sqc_brpao1); - qemu_put_be32s(f, &s->intc_sqc_mask); - qemu_put_be32s(f, &s->intc_dma_mask); - qemu_put_be32s(f, &s->intc_onenand_mask); -} - -static int s5pc1xx_onenand_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxOneNANDState *s = (S5pc1xxOneNANDState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->onenand_if_clrt); - qemu_get_be32s(f, &s->onenand_async_timing); - qemu_get_be32s(f, &s->dma_src_addr); - qemu_get_be32s(f, &s->dma_src_cfg); - qemu_get_be32s(f, &s->dma_dst_addr); - qemu_get_be32s(f, &s->dma_dst_cfg); - qemu_get_be32s(f, &s->dma_trans_size); - qemu_get_be32s(f, &s->dma_trans_dir); - qemu_get_be32s(f, &s->sqc_sao); - qemu_get_be32s(f, &s->sqc_reg_ctrl); - qemu_get_be32s(f, &s->sqc_brpao0); - qemu_get_be32s(f, &s->sqc_brpao1); - qemu_get_be32s(f, &s->intc_sqc_mask); - qemu_get_be32s(f, &s->intc_dma_mask); - qemu_get_be32s(f, &s->intc_onenand_mask); - - return 0; -} - -static void onenand_config_reg_reset(void *opaque) -{ - S5pc1xxOneNANDState *s = (S5pc1xxOneNANDState *)opaque; - - s->onenand_if_clrt = 0x00004000 | (IS_MUX_TYPE << 31); - s->onenand_async_timing = 0x00003415; - s->dma_src_addr = 0x00000000; - s->dma_src_cfg = 0x00040002; - s->dma_dst_addr = 0x00000000; - s->dma_dst_cfg = 0x00040002; - s->dma_trans_size = 0x00000000; - s->dma_trans_dir = 0x00000000; - s->sqc_sao = 0x00000000; - s->sqc_reg_ctrl = 0x00000000; - s->sqc_brpao0 = 0x00000000; - s->sqc_brpao1 = 0x00000000; - s->intc_sqc_mask = 0x01010000; - s->intc_dma_mask = 0x01010000; - s->intc_onenand_mask = 0x000000FF; -} - -DeviceState *s5pc1xx_onenand_init(target_phys_addr_t base) -{ - DeviceState *dev; - SysBusDevice *s; - void *onenand_dev; - - dev = qdev_create(NULL, "s5pc1xx.onenand"); - qdev_init_nofail(dev); - s = sysbus_from_qdev(dev); - - sysbus_mmio_map(s, 0, base + ONENAND_CONTR_REG_BASE); - - FROM_SYSBUS(S5pc1xxOneNANDState, s)->base = base; - - onenand_dev = - onenand_init(ONENAND_DEVICE_ID, 1, NULL, ONENAND_4KB_PAGE, 1); - onenand_base_update(onenand_dev, base); - - return dev; -} - -static int s5pc1xx_onenand_init1(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxOneNANDState *s = FROM_SYSBUS(S5pc1xxOneNANDState, dev); - - iomemtype = cpu_register_io_memory(onenand_config_reg_mm_read, - onenand_config_reg_mm_write, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, ONENAND_CONTR_REGS_SIZE, iomemtype); - - onenand_config_reg_reset(s); - - qemu_register_reset(onenand_config_reg_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.onenand", -1, 1, - s5pc1xx_onenand_save, s5pc1xx_onenand_load, s); - - return 0; -} - -static void s5pc1xx_onenand_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.onenand", sizeof(S5pc1xxOneNANDState), - s5pc1xx_onenand_init1); -} - -device_init(s5pc1xx_onenand_register_devices) diff --git a/hw/s5pc1xx_pcm.c b/hw/s5pc1xx_pcm.c deleted file mode 100644 index 8f58a18..0000000 --- a/hw/s5pc1xx_pcm.c +++ /dev/null @@ -1,717 +0,0 @@ -/* - * PCM audio interface for S5PC110-based board emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "s5pc1xx.h" -#include "qemu-timer.h" -#include "s5pc1xx_gpio_regs.h" -#include "sysbus.h" - - -#define ALL_BITS(b,a) (((1 << (b - a + 1)) - 1) << a) - -/* R/W Specifies the PCM Main Control 0x00000000 */ -#define PCM_CTL 0x00 - #define TXFIFO_DIPSTICK_SHIFT 13 /* 6 bits */ - #define RXFIFO_DIPSTICK_SHIFT 7 /* 6 bits */ - #define PCM_TX_DMA_EN (1 << 6) - #define PCM_RX_DMA_EN (1 << 5) - #define TX_MSB_POS (1 << 4) - #define RX_MSB_POS (1 << 3) - #define PCM_TXFIFO_EN (1 << 2) - #define PCM_RXFIFO_EN (1 << 1) - #define PCM_PCM_ENABLE (1 << 0) - -/* R/W Specifies the PCM Clock and Shift control 0x00000000 */ -#define PCM_CLKCTL 0x04 - #define CTL_SERCLK_EN (1 << 19) - #define CTL_SERCLK_SEL (1 << 18) /* TODO: now is set high as default */ - #define SCLK_DIV_SHIFT 9 - #define SYNC_DIV_SHIFT 0 - -/* R/W Specifies the PCM TxFIFO write port 0x00010000 */ -#define PCM_TXFIFO 0x08 - #define TXFIFO_DVALID (1 << 16) - -/* R/W Specifies the PCM RxFIFO read port 0x00010000 */ -#define PCM_RXFIFO 0x0C - #define RXFIFO_DVALID (1 << 16) - -/* R/W Specifies the PCM Interrupt Control 0x00000000 */ -#define PCM_IRQ_CTL 0x10 - #define INT_EN(stat) (stat) - #define EN_IRQ_TO_ARM (1 << 14) - -/* R Specifies the PCM Interrupt Status 0x00000000 */ -#define PCM_IRQ_STAT 0x14 - #define IRQ_PENDING (1 << 13) - #define TRANSFER_DONE (1 << 12) - #define TXFIFO_EMPTY (1 << 11) - #define TXFIFO_ALMOST_EMPTY (1 << 10) - #define TXFIFO_FULL (1 << 9) - #define TXFIFO_ALMOST_FULL (1 << 8) - #define TXFIFO_ERROR_STARVE (1 << 7) - #define TXFIFO_ERROR_OVERFLOW (1 << 6) - #define RXFIFO_EMPTY (1 << 5) - #define RXFIFO_ALMOST_EMPTY (1 << 4) - #define RXFIFO_FULL (1 << 3) - #define RXFIFO_ALMOST_FULL (1 << 2) - #define RXFIFO_ERROR_STARVE (1 << 1) - #define RXFIFO_ERROR_OVERFLOW (1 << 0) - #define ALL_STAT ALL_BITS(13,0) - -/* R Specifies the PCM FIFO Status 0x00000000 */ -#define PCM_FIFO_STAT 0x18 - #define TXFIFO_COUNT_SHIFT 14 /* 6 bits */ - #define TXFIFO_EMPTY_FLAG (1 << 13) - #define TXFIFO_ALMOST_EMPTY_FLAG (1 << 12) - #define TXFIFO_FULL_FLAG (1 << 11) - #define TXFIFO_ALMOST_FULL_FLAG (1 << 10) - #define RXFIFO_COUNT_SHIFT 4 /* 6 bits */ - #define RXFIFO_EMPTY_FLAG (1 << 3) - #define RXFIFO_ALMOST_EMPTY_FLAG (1 << 2) - #define RXFIFO_FULL_FLAG (1 << 1) - #define RXFIFO_ALMOST_FULL_FLAG (1 << 0) - -/* W Specifies the PCM Interrupt Clear - */ -#define PCM_CLRINT 0x20 - -#define S5PC1XX_PCM_REG_MEM_SIZE 0x24 - - -typedef struct S5pc1xxPCMState { - - SysBusDevice busdev; - qemu_irq irq; - uint32_t instance; - - uint32_t ctl; - uint32_t clk_ctl; - uint32_t irq_ctl; - uint32_t irq_stat; - uint32_t fifo_stat; - - struct FrameIn { - uint16_t fifo[32]; - - uint64_t write_idx; - uint64_t read_idx; - - uint8_t fifo_dipstick; - uint8_t delay; - } rx; - - struct FrameOut { - uint16_t fifo[32]; - - uint64_t write_idx; - uint64_t read_idx; - - uint8_t fifo_dipstick; - uint8_t delay; - } tx; - - QEMUTimer *pcm_timer; - uint16_t sync_div; - uint32_t sync_freq; - uint32_t sclk_freq; - uint64_t last_pcm_time; - - uint8_t sclk_en; - uint8_t pcm_io_en; - -} S5pc1xxPCMState; - - -/* Function for initialization and reset */ -static void s5pc1xx_pcm_reset(DeviceState *d) -{ - S5pc1xxPCMState *s = - FROM_SYSBUS(S5pc1xxPCMState, sysbus_from_qdev(d)); - - s->ctl = 0; - s->clk_ctl = 0x40000; - s->irq_ctl = 0; - s->irq_stat = 0; - s->fifo_stat = 0; - - s->rx.read_idx = 0; - s->rx.write_idx = 0; - s->rx.delay = 0; - - s->tx.read_idx = 0; - s->tx.write_idx = 0; - s->tx.delay = 0; - - s->sync_div = 0; - s->sync_freq = 0; - s->sclk_freq = 0; - s->last_pcm_time = 0; - - s->sclk_en = 0; - s->pcm_io_en = 0; -} - -/* Interrupts handler */ -static void s5pc1xx_pcm_irq(S5pc1xxPCMState *s, - uint32_t stat, uint8_t clear) -{ - if (stat) { - s->irq_stat |= (IRQ_PENDING | stat); - if ((s->irq_ctl & EN_IRQ_TO_ARM) && - (s->irq_ctl & INT_EN(stat))) /* if enabled */ - qemu_irq_raise(s->irq); - } - if (clear) { - s->irq_stat &= ~(ALL_STAT); /* clear all at once */ - qemu_irq_lower(s->irq); - } -} - -/* Controls RXFIFO stage */ -static void s5pc1xx_pcm_rx_control(S5pc1xxPCMState *s) -{ - uint8_t rx_depth; - - rx_depth = (s->rx.write_idx - s->rx.read_idx) % 33; - - if (rx_depth == 0) { - s5pc1xx_pcm_irq(s, RXFIFO_EMPTY, 0); - s->fifo_stat |= RXFIFO_EMPTY_FLAG; - } else { - s->fifo_stat &= ~(RXFIFO_EMPTY_FLAG); - } - - if (rx_depth == 32) { - s5pc1xx_pcm_irq(s, RXFIFO_FULL, 0); - s->fifo_stat |= RXFIFO_FULL_FLAG; - } else { - s->fifo_stat &= ~(RXFIFO_FULL_FLAG); - } - - if (rx_depth < s->rx.fifo_dipstick) { - s5pc1xx_pcm_irq(s, RXFIFO_ALMOST_EMPTY, 0); - s->fifo_stat |= RXFIFO_ALMOST_EMPTY_FLAG; - } else { - s->fifo_stat &= ~(RXFIFO_ALMOST_EMPTY_FLAG); - } - - if (rx_depth > (32 - s->rx.fifo_dipstick)) { - s5pc1xx_pcm_irq(s, RXFIFO_ALMOST_FULL, 0); - s->fifo_stat |= RXFIFO_ALMOST_FULL_FLAG; - } else { - s->fifo_stat &= ~(RXFIFO_ALMOST_FULL_FLAG); - } -} - -/* Controls TXFIFO stage */ -static void s5pc1xx_pcm_tx_control(S5pc1xxPCMState *s) -{ - uint8_t tx_depth; - - tx_depth = (s->tx.write_idx - s->tx.read_idx) % 33; - - if (tx_depth == 0) { - s5pc1xx_pcm_irq(s, TXFIFO_EMPTY, 0); - s->fifo_stat |= TXFIFO_EMPTY_FLAG; - } else { - s->fifo_stat &= ~(TXFIFO_EMPTY_FLAG); - } - - if (tx_depth == 32) { - s5pc1xx_pcm_irq(s, TXFIFO_FULL, 0); - s->fifo_stat |= TXFIFO_FULL_FLAG; - } else { - s->fifo_stat &= ~(TXFIFO_FULL_FLAG); - } - - if (tx_depth < s->tx.fifo_dipstick) { - s5pc1xx_pcm_irq(s, TXFIFO_ALMOST_EMPTY, 0); - s->fifo_stat |= TXFIFO_ALMOST_EMPTY_FLAG; - } else { - s->fifo_stat &= ~(TXFIFO_ALMOST_EMPTY_FLAG); - } - - if (tx_depth > (32 - s->tx.fifo_dipstick)) { - s5pc1xx_pcm_irq(s, TXFIFO_ALMOST_FULL, 0); - s->fifo_stat |= TXFIFO_ALMOST_FULL_FLAG; - } else { - s->fifo_stat &= ~(TXFIFO_ALMOST_FULL_FLAG); - } -} - -/* Increase fifo indexes */ -static void s5pc1xx_pcm_next_frame(S5pc1xxPCMState *s) -{ - if (s->ctl & PCM_RXFIFO_EN) { - if (s->rx.write_idx < s->rx.read_idx + 32) - s->rx.write_idx++; - s5pc1xx_pcm_rx_control(s); - } - - if (s->ctl & PCM_TXFIFO_EN) { - if (s->tx.read_idx < s->tx.write_idx) - s->tx.read_idx++; - s5pc1xx_pcm_tx_control(s); - } -} - -/* Determine sclk/sync_freq and sync_div */ -static void s5pc1xx_pcm_sclk_update(S5pc1xxPCMState *s) -{ - S5pc1xxClk clk; - uint16_t sclk_div; - - clk = s5pc1xx_findclk("pclk_66"); - - if (!(s->pcm_io_en)) - s->clk_ctl = 0x40000; - - sclk_div = 2 * ((s->clk_ctl >> SCLK_DIV_SHIFT & ALL_BITS(8, 0)) + 1); - s->sclk_freq = s5pc1xx_clk_getrate(clk) / sclk_div; - - if (!(s->sclk_freq)) - hw_error("s5pc1xx.pcm: timer frequency is zero\n"); - - s->sync_div = (s->clk_ctl >> SYNC_DIV_SHIFT & ALL_BITS(8, 0)) + 1; - s->sync_freq = s->sclk_freq / s->sync_div; -} - -/* Sync timer */ -static void s5pc1xx_pcm_sync(void *opaque) -{ - S5pc1xxPCMState *s = (S5pc1xxPCMState *)opaque; - uint64_t next_pcm_time; - - if (s->sclk_en) { - if (!(s->sync_freq)) - s5pc1xx_pcm_sclk_update(s); - - s5pc1xx_pcm_next_frame(s); - - s->last_pcm_time = qemu_get_clock(vm_clock); - next_pcm_time = - s->last_pcm_time + muldiv64(1, get_ticks_per_sec(), s->sync_freq); - qemu_mod_timer(s->pcm_timer, next_pcm_time); - } else { - qemu_del_timer(s->pcm_timer); - } -} - -/* SCLK x2 cycles counter */ -static uint16_t s5pc1xx_pcm_2sclk(S5pc1xxPCMState *s) -{ - uint32_t spent_1G; - uint16_t spent_2sclk; - - if (s->last_pcm_time) { - spent_1G = qemu_get_clock(vm_clock) - s->last_pcm_time; - spent_2sclk = - muldiv64(spent_1G, (s->sclk_freq * 2), get_ticks_per_sec()); - return spent_2sclk; - } else { - return 0; - } -} - -/* SCLK state */ -static uint8_t s5pc1xx_pcm_sclk_s(S5pc1xxPCMState *s) -{ - if (s->sclk_en) - return ((s5pc1xx_pcm_2sclk(s) % 2) ? 0 : 1); - else - return 0; -} - -/* SYNC signal state */ -static uint8_t s5pc1xx_pcm_sync_s(S5pc1xxPCMState *s) -{ - if (s->sclk_en) - return (s5pc1xx_pcm_2sclk(s) < 2); - else - return 0; -} - -/* Put PCM_SIN bit */ -static void s5pc1xx_write_rxfifo(S5pc1xxPCMState *s, uint32_t sdata) -{ - uint16_t cur_pos; - - if (!(s->sclk_en) || !(s->ctl & PCM_RXFIFO_EN)) - return; - - if (s->rx.write_idx == s->rx.read_idx + 32) { - s5pc1xx_pcm_irq(s, RXFIFO_ERROR_OVERFLOW, 0); - return; - } - - cur_pos = (s5pc1xx_pcm_2sclk(s) / 2) % s->sync_div - s->rx.delay; - - if (cur_pos < 16) - s->rx.fifo[s->rx.write_idx % 32] |= (sdata & 0x1) << (15 - cur_pos); -} - -/* Return PCM_SOUT bit */ -static uint8_t s5pc1xx_read_txfifo(S5pc1xxPCMState *s) -{ - uint16_t word, cur_pos; - - if (!(s->sclk_en) || !(s->ctl & PCM_TXFIFO_EN)) - return 0; - - if (s->tx.read_idx == s->tx.write_idx) { - s5pc1xx_pcm_irq(s, TXFIFO_ERROR_STARVE, 0); - return 0; - } - - cur_pos = (s5pc1xx_pcm_2sclk(s) / 2) % s->sync_div - s->tx.delay; - - if (cur_pos > 15) { - s5pc1xx_pcm_irq(s, TRANSFER_DONE, 0); - return 0; - } - - word = s->tx.fifo[s->tx.read_idx % 32]; - return (word >> (15 - cur_pos) & 0x1); -} - -/* Read PCM by GPIO */ -static uint32_t s5pc1xx_pcm_gpio_read(void *opaque, int io_index) -{ - S5pc1xxPCMState *s = (S5pc1xxPCMState *)opaque; - - if (!(s->pcm_io_en)) - return 0; - - if (io_index == PCM_SCLK(s->instance)) - return s5pc1xx_pcm_sclk_s(s); - - if (io_index == PCM_FSYNC(s->instance)) - return s5pc1xx_pcm_sync_s(s); - - if (io_index == PCM_SOUT(s->instance)) - return s5pc1xx_read_txfifo(s); - - return 0; -} - -/* Write PCM by GPIO */ -static void s5pc1xx_pcm_gpio_write(void *opaque, int io_index, uint32_t value) -{ - S5pc1xxPCMState *s = (S5pc1xxPCMState *)opaque; - - /* TODO: not implemented for now */ - if (io_index == PCM_EXTCLK(s->instance)) - return; - - if (io_index == PCM_SIN(s->instance)) { - s5pc1xx_write_rxfifo(s, value); - } -} - -static GPIOReadMemoryFunc *s5pc1xx_pcm_gpio_readfn = s5pc1xx_pcm_gpio_read; -static GPIOWriteMemoryFunc *s5pc1xx_pcm_gpio_writefn = s5pc1xx_pcm_gpio_write; - -/* Read PCM by OS */ -static uint32_t s5pc1xx_pcm_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxPCMState *s = (S5pc1xxPCMState *)opaque; - uint8_t rx_depth, tx_depth; - uint32_t ret_val; - - switch(offset) { - case PCM_CTL: - return s->ctl; - case PCM_CLKCTL: - return s->clk_ctl; - - case PCM_TXFIFO: - if (!(s->ctl & PCM_TX_DMA_EN) || !(s->ctl & PCM_TXFIFO_EN)) - return 0; - - return (s->tx.fifo[s->tx.read_idx % 32] | TXFIFO_DVALID); - - case PCM_RXFIFO: - if (!(s->ctl & PCM_RX_DMA_EN) || !(s->ctl & PCM_RXFIFO_EN)) - return 0; - - if (s->rx.read_idx == s->rx.write_idx) { - s5pc1xx_pcm_irq(s, RXFIFO_ERROR_STARVE, 0); - return 0; - } - - ret_val = s->rx.fifo[s->rx.read_idx % 32] | RXFIFO_DVALID; - - if (s->rx.read_idx < s->rx.write_idx) - s->rx.read_idx++; - - s5pc1xx_pcm_rx_control(s); - - return ret_val; - - case PCM_IRQ_CTL: - return s->irq_ctl; - case PCM_IRQ_STAT: - return s->irq_stat; - - case PCM_FIFO_STAT: - rx_depth = (s->rx.write_idx - s->rx.read_idx) % 33; - tx_depth = (s->tx.write_idx - s->tx.read_idx) % 33; - ret_val = (s->fifo_stat & ALL_BITS(3, 0)) | (rx_depth << 4) | - (s->fifo_stat & ALL_BITS(13, 10)) | (tx_depth << 14); - return ret_val; - - default: - hw_error("s5pc1xx.pcm: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -/* Write PCM by OS */ -static void s5pc1xx_pcm_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxPCMState *s = (S5pc1xxPCMState *)opaque; - - switch(offset) { - case PCM_CTL: - if ((value & PCM_PCM_ENABLE) < (s->ctl & PCM_PCM_ENABLE)) { - s->pcm_io_en = 0; - s5pc1xx_pcm_sclk_update(s); - } - /* the value is set low above */ - s->pcm_io_en = (!(value & PCM_PCM_ENABLE)) ? : 1; - - if ((value & PCM_RXFIFO_EN) < (s->ctl & PCM_RXFIFO_EN)) { - s->rx.read_idx = 0; - s->rx.write_idx = 0; - } - if ((value & PCM_TXFIFO_EN) < (s->ctl & PCM_TXFIFO_EN)) { - s->tx.read_idx = 0; - s->tx.write_idx = 0; - } - - s->rx.delay = (value & RX_MSB_POS) ? 1 : 0; - s->rx.fifo_dipstick = value >> RXFIFO_DIPSTICK_SHIFT & ALL_BITS(6, 0); - - s->tx.delay = (value & TX_MSB_POS) ? 1 : 0; - s->tx.fifo_dipstick = value >> TXFIFO_DIPSTICK_SHIFT & ALL_BITS(6, 0); - - s->ctl = value; - break; - - case PCM_CLKCTL: - if ((value & CTL_SERCLK_EN) > (s->clk_ctl & CTL_SERCLK_EN)) { - s->sclk_en = 1; - s5pc1xx_pcm_sync(s); - } - /* the value is set high above */ - s->sclk_en = (value & CTL_SERCLK_EN) ? : 0; - - if (value != s->clk_ctl) - s5pc1xx_pcm_sclk_update(s); - - s->clk_ctl = value; - break; - - case PCM_TXFIFO: - if (!(s->ctl & PCM_TX_DMA_EN) || !(s->ctl & PCM_TXFIFO_EN)) - break; - - if (s->tx.write_idx == s->tx.read_idx + 32) { - s5pc1xx_pcm_irq(s, TXFIFO_ERROR_OVERFLOW, 0); - break; - } - - s->tx.fifo[s->tx.write_idx % 32] = value; - - if (s->tx.write_idx < s->tx.read_idx + 32) - s->tx.write_idx++; - - s5pc1xx_pcm_tx_control(s); - - break; - - case PCM_RXFIFO: - if (!(s->ctl & PCM_RX_DMA_EN) || !(s->ctl & PCM_RXFIFO_EN)) - break; - - s->rx.fifo[s->rx.write_idx % 32] = value; - break; - - case PCM_IRQ_CTL: - s->irq_ctl = value; - break; - - case PCM_CLRINT: - /* clear all irq stats and lower the interrupt */ - s5pc1xx_pcm_irq(s, 0, 1); - break; - - default: - hw_error("s5pc1xx.pcm: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_pcm_readfn[] = { - s5pc1xx_pcm_read, - s5pc1xx_pcm_read, - s5pc1xx_pcm_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_pcm_writefn[] = { - s5pc1xx_pcm_write, - s5pc1xx_pcm_write, - s5pc1xx_pcm_write -}; - -static void s5pc1xx_pcm_save(QEMUFile *f, void *opaque) -{ - S5pc1xxPCMState *s = (S5pc1xxPCMState *)opaque; - uint64_t last; - int i; - - qemu_put_be32s(f, &s->ctl); - qemu_put_be32s(f, &s->clk_ctl); - qemu_put_be32s(f, &s->irq_ctl); - qemu_put_be32s(f, &s->irq_stat); - qemu_put_be32s(f, &s->fifo_stat); - - for (i = 0; i < 32; i++) { - qemu_put_be16s(f, &s->rx.fifo[i]); - } - - qemu_put_be64s(f, &s->rx.write_idx); - qemu_put_be64s(f, &s->rx.read_idx); - qemu_put_8s (f, &s->rx.fifo_dipstick); - qemu_put_8s (f, &s->rx.delay); - - for (i = 0; i < 32; i++) { - qemu_put_be16s(f, &s->tx.fifo[i]); - } - - qemu_put_be64s(f, &s->tx.write_idx); - qemu_put_be64s(f, &s->tx.read_idx); - qemu_put_8s (f, &s->tx.fifo_dipstick); - qemu_put_8s (f, &s->tx.delay); - - qemu_put_be16s(f, &s->sync_div); - qemu_put_be32s(f, &s->sync_freq); - qemu_put_be32s(f, &s->sclk_freq); - - last = qemu_get_clock(vm_clock) - s->last_pcm_time; - qemu_put_be64s(f, &last); - - qemu_put_8s(f, &s->sclk_en); - qemu_put_8s(f, &s->pcm_io_en); - - qemu_put_timer(f, s->pcm_timer); -} - -static int s5pc1xx_pcm_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxPCMState *s = (S5pc1xxPCMState *)opaque; - uint64_t last; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->ctl); - qemu_get_be32s(f, &s->clk_ctl); - qemu_get_be32s(f, &s->irq_ctl); - qemu_get_be32s(f, &s->irq_stat); - qemu_get_be32s(f, &s->fifo_stat); - - for (i = 0; i < 32; i++) { - qemu_get_be16s(f, &s->rx.fifo[i]); - } - - qemu_get_be64s(f, &s->rx.write_idx); - qemu_get_be64s(f, &s->rx.read_idx); - qemu_get_8s (f, &s->rx.fifo_dipstick); - qemu_get_8s (f, &s->rx.delay); - - for (i = 0; i < 32; i++) { - qemu_get_be16s(f, &s->tx.fifo[i]); - } - - qemu_get_be64s(f, &s->tx.write_idx); - qemu_get_be64s(f, &s->tx.read_idx); - qemu_get_8s (f, &s->tx.fifo_dipstick); - qemu_get_8s (f, &s->tx.delay); - - qemu_get_be16s(f, &s->sync_div); - qemu_get_be32s(f, &s->sync_freq); - qemu_get_be32s(f, &s->sclk_freq); - - qemu_get_be64s(f, &last); - s->last_pcm_time = qemu_get_clock(vm_clock) - last; - - qemu_get_8s(f, &s->sclk_en); - qemu_get_8s(f, &s->pcm_io_en); - - qemu_get_timer(f, s->pcm_timer); - - return 0; -} - -DeviceState *s5pc1xx_pcm_init(target_phys_addr_t base, int instance, - qemu_irq irq) -{ - DeviceState *dev = qdev_create(NULL, "s5pc1xx.pcm"); - qdev_prop_set_uint32(dev, "instance", instance); - qdev_init_nofail(dev); - sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); - sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); - return dev; -} - -/* PCM initialization */ -static int s5pc1xx_pcm_init1(SysBusDevice *dev) -{ - S5pc1xxPCMState *s = FROM_SYSBUS(S5pc1xxPCMState, dev); - int iomemtype; - - sysbus_init_irq(dev, &s->irq); - - iomemtype = - cpu_register_io_memory(s5pc1xx_pcm_readfn, s5pc1xx_pcm_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_PCM_REG_MEM_SIZE, iomemtype); - - s5pc1xx_gpio_register_io_memory(GPIO_IDX_PCM, s->instance, - s5pc1xx_pcm_gpio_readfn, - s5pc1xx_pcm_gpio_writefn, NULL, s); - s->pcm_timer = qemu_new_timer(vm_clock, s5pc1xx_pcm_sync, s); - - s5pc1xx_pcm_reset(&s->busdev.qdev); - - register_savevm(&dev->qdev, "s5pc1xx.pcm", s->instance, 1, - s5pc1xx_pcm_save, s5pc1xx_pcm_load, s); - - return 0; -} - -static SysBusDeviceInfo s5pc1xx_pcm_info = { - .init = s5pc1xx_pcm_init1, - .qdev.name = "s5pc1xx.pcm", - .qdev.size = sizeof(S5pc1xxPCMState), - .qdev.reset = s5pc1xx_pcm_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("instance", S5pc1xxPCMState, instance, 0), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_pcm_register(void) -{ - sysbus_register_withprop(&s5pc1xx_pcm_info); -} - -device_init(s5pc1xx_pcm_register) diff --git a/hw/s5pc1xx_pmu.c b/hw/s5pc1xx_pmu.c deleted file mode 100644 index d6428fe..0000000 --- a/hw/s5pc1xx_pmu.c +++ /dev/null @@ -1,1295 +0,0 @@ -/* - * S5PC1XX Power Management Unit controller, - * Maxim MAX17040 Fuel Gauge, - * Maxim MAX8998 Battery Charger and Real Time Clock. - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Dmitry Zhurikhin - * Vladimir Monakhov - */ - -#include "sysemu.h" -#include "sysbus.h" -#include "smbus.h" -#include "s5pc1xx.h" -#include "qemu-timer.h" - - -#define S5PC110_PMU_SFR_SIZE 0x8000 - - -typedef struct S5pc1xxPMUState { - SysBusDevice busdev; - - uint32_t osc_con; - uint32_t rst_stat; - uint32_t pwr_cfg; - uint32_t eint_wakeup_mask; - uint32_t wakeup_mask; - uint32_t pwr_mode; - uint32_t normal_cfg; - uint32_t idle_cfg; - uint32_t stop_cfg; - uint32_t stop_mem_cfg; - uint32_t sleep_cfg; - uint32_t osc_freq; - uint32_t osc_stable; - uint32_t pwr_stable; - uint32_t mtc_stable; - uint32_t clamp_stable; - uint32_t wakeup_stat; - uint32_t blk_pwr_stat; - uint32_t body_bias_con; - uint32_t ion_skew_con; - uint32_t ion_skew_mon; - uint32_t ioff_skew_con; - uint32_t ioff_skew_mon; - uint32_t others; - uint32_t om_stat; - uint32_t mie_control; - uint32_t hdmi_control; - uint32_t usb_phy_control; - uint32_t dac_control; - uint32_t mipi_dphy_control; - uint32_t adc_control; - uint32_t ps_hold_control; - uint32_t inform0; - uint32_t inform1; - uint32_t inform2; - uint32_t inform3; - uint32_t inform4; - uint32_t inform5; - uint32_t inform6; - uint32_t inform7; -} S5pc1xxPMUState; - - -static uint32_t s5pc1xx_pmu_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxPMUState *s = (S5pc1xxPMUState *)opaque; - target_phys_addr_t test_offset = offset + 0x8000; - - if (offset & 3) { - hw_error("s5pc1xx.pmu: bad read offset " TARGET_FMT_plx "\n", offset); - } - - switch (test_offset) { - case 0x8000: - return s->osc_con; - case 0xA000: - return s->rst_stat; - case 0xC000: - return s->pwr_cfg; - case 0xC004: - return s->eint_wakeup_mask; - case 0xC008: - return s->wakeup_mask; - case 0xC00C: - return s->pwr_mode; - case 0xC010: - return s->normal_cfg; - case 0xC020: - return s->idle_cfg; - case 0xC030: - return s->stop_cfg; - case 0xC034: - return s->stop_mem_cfg; - case 0xC040: - return s->sleep_cfg; - case 0xC100: - return s->osc_freq; - case 0xC104: - return s->osc_stable; - case 0xC108: - return s->pwr_stable; - case 0xC110: - return s->mtc_stable; - case 0xC114: - return s->clamp_stable; - case 0xC200: - return s->wakeup_stat; - case 0xC204: - return s->blk_pwr_stat; - case 0xC300: - return s->body_bias_con; - case 0xC310: - return s->ion_skew_con; - case 0xC314: - return s->ion_skew_mon; - case 0xC320: - return s->ioff_skew_con; - case 0xC324: - return s->ioff_skew_mon; - case 0xE000: - return s->others; - case 0xE100: - return s->om_stat; - case 0xE800: - return s->mie_control; - case 0xE804: - return s->hdmi_control; - case 0xE80C: - return s->usb_phy_control; - case 0xE810: - return s->dac_control; - case 0xE814: - return s->mipi_dphy_control; - case 0xE818: - return s->adc_control; - case 0xE81C: - return s->ps_hold_control; - case 0xF000: - return s->inform0; - case 0xF004: - return s->inform1; - case 0xF008: - return s->inform2; - case 0xF00C: - return s->inform3; - case 0xF010: - return s->inform4; - case 0xF014: - return s->inform5; - case 0xF018: - return s->inform6; - case 0xF01C: - return s->inform7; - default: - hw_error("s5pc1xx.pmu: bad read offset " TARGET_FMT_plx "\n", offset); - } -} - -static void s5pc1xx_pmu_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxPMUState *s = (S5pc1xxPMUState *)opaque; - target_phys_addr_t test_offset = offset + 0x8000; - - /* TODO: Check if writing any values should change emulation flow */ - - if (offset & 3) { - hw_error("s5pc1xx.pmu: bad write offset " TARGET_FMT_plx "\n", offset); - } - - switch (test_offset) { - case 0x8000: - s->osc_con = val; - break; - case 0xC000: - s->pwr_cfg = val; - break; - case 0xC004: - s->eint_wakeup_mask = val; - break; - case 0xC008: - s->wakeup_mask = val; - break; - case 0xC00C: - s->pwr_mode = val; - break; - case 0xC010: - s->normal_cfg = val; - break; - case 0xC020: - s->idle_cfg = val; - break; - case 0xC030: - s->stop_cfg = val; - break; - case 0xC034: - s->stop_mem_cfg = val; - break; - case 0xC040: - s->sleep_cfg = val; - break; - case 0xC100: - s->osc_freq = val; - break; - case 0xC104: - s->osc_stable = val; - break; - case 0xC108: - s->pwr_stable = val; - break; - case 0xC110: - s->mtc_stable = val; - break; - case 0xC114: - s->clamp_stable = val; - break; - case 0xC200: - s->wakeup_stat = val; - break; - case 0xC300: - s->body_bias_con = val; - break; - case 0xC310: - s->ion_skew_con = val; - break; - case 0xC320: - s->ioff_skew_con = val; - break; - case 0xE000: - s->others = val; - break; - case 0xE800: - s->mie_control = val; - break; - case 0xE804: - s->hdmi_control = val; - break; - case 0xE80C: - s->usb_phy_control = val; - break; - case 0xE810: - s->dac_control = val; - break; - case 0xE814: - s->mipi_dphy_control = val; - break; - case 0xE818: - s->adc_control = val; - break; - case 0xE81C: - s->ps_hold_control = val; - if ((val & (1 << 8)) == 0) { - qemu_system_shutdown_request(); - } - break; - case 0xF000: - s->inform0 = val; - break; - case 0xF004: - s->inform1 = val; - break; - case 0xF008: - s->inform2 = val; - break; - case 0xF00C: - s->inform3 = val; - break; - case 0xF010: - s->inform4 = val; - break; - case 0xF014: - s->inform5 = val; - break; - case 0xF018: - s->inform6 = val; - break; - case 0xF01C: - s->inform7 = val; - break; - case 0xA000: /* rst_stat */ - case 0xC204: /* blk_pwr_stat */ - case 0xC314: /* ion_skew_mon */ - case 0xC324: /* ioff_skew_mon */ - case 0xE100: /* om_stat */ - hw_error("s5pc1xx.pmu: bad write offset " TARGET_FMT_plx "\n", offset); - break; - default: - hw_error("s5pc1xx.pmu: bad write offset " TARGET_FMT_plx "\n", offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_pmu_readfn[] = { - s5pc1xx_pmu_read, - s5pc1xx_pmu_read, - s5pc1xx_pmu_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_pmu_writefn[] = { - s5pc1xx_pmu_write, - s5pc1xx_pmu_write, - s5pc1xx_pmu_write -}; - -static void s5pc1xx_pmu_save(QEMUFile *f, void *opaque) -{ - S5pc1xxPMUState *s = (S5pc1xxPMUState *)opaque; - - qemu_put_be32s(f, &s->osc_con); - qemu_put_be32s(f, &s->rst_stat); - qemu_put_be32s(f, &s->pwr_cfg); - qemu_put_be32s(f, &s->eint_wakeup_mask); - qemu_put_be32s(f, &s->wakeup_mask); - qemu_put_be32s(f, &s->pwr_mode); - qemu_put_be32s(f, &s->normal_cfg); - qemu_put_be32s(f, &s->idle_cfg); - qemu_put_be32s(f, &s->stop_cfg); - qemu_put_be32s(f, &s->stop_mem_cfg); - qemu_put_be32s(f, &s->sleep_cfg); - qemu_put_be32s(f, &s->osc_freq); - qemu_put_be32s(f, &s->osc_stable); - qemu_put_be32s(f, &s->pwr_stable); - qemu_put_be32s(f, &s->mtc_stable); - qemu_put_be32s(f, &s->clamp_stable); - qemu_put_be32s(f, &s->wakeup_stat); - qemu_put_be32s(f, &s->blk_pwr_stat); - qemu_put_be32s(f, &s->body_bias_con); - qemu_put_be32s(f, &s->ion_skew_con); - qemu_put_be32s(f, &s->ion_skew_mon); - qemu_put_be32s(f, &s->ioff_skew_con); - qemu_put_be32s(f, &s->ioff_skew_mon); - qemu_put_be32s(f, &s->others); - qemu_put_be32s(f, &s->om_stat); - qemu_put_be32s(f, &s->mie_control); - qemu_put_be32s(f, &s->hdmi_control); - qemu_put_be32s(f, &s->usb_phy_control); - qemu_put_be32s(f, &s->dac_control); - qemu_put_be32s(f, &s->mipi_dphy_control); - qemu_put_be32s(f, &s->adc_control); - qemu_put_be32s(f, &s->ps_hold_control); - qemu_put_be32s(f, &s->inform0); - qemu_put_be32s(f, &s->inform1); - qemu_put_be32s(f, &s->inform2); - qemu_put_be32s(f, &s->inform3); - qemu_put_be32s(f, &s->inform4); - qemu_put_be32s(f, &s->inform5); - qemu_put_be32s(f, &s->inform6); - qemu_put_be32s(f, &s->inform7); -} - -static int s5pc1xx_pmu_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxPMUState *s = (S5pc1xxPMUState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->osc_con); - qemu_get_be32s(f, &s->rst_stat); - qemu_get_be32s(f, &s->pwr_cfg); - qemu_get_be32s(f, &s->eint_wakeup_mask); - qemu_get_be32s(f, &s->wakeup_mask); - qemu_get_be32s(f, &s->pwr_mode); - qemu_get_be32s(f, &s->normal_cfg); - qemu_get_be32s(f, &s->idle_cfg); - qemu_get_be32s(f, &s->stop_cfg); - qemu_get_be32s(f, &s->stop_mem_cfg); - qemu_get_be32s(f, &s->sleep_cfg); - qemu_get_be32s(f, &s->osc_freq); - qemu_get_be32s(f, &s->osc_stable); - qemu_get_be32s(f, &s->pwr_stable); - qemu_get_be32s(f, &s->mtc_stable); - qemu_get_be32s(f, &s->clamp_stable); - qemu_get_be32s(f, &s->wakeup_stat); - qemu_get_be32s(f, &s->blk_pwr_stat); - qemu_get_be32s(f, &s->body_bias_con); - qemu_get_be32s(f, &s->ion_skew_con); - qemu_get_be32s(f, &s->ion_skew_mon); - qemu_get_be32s(f, &s->ioff_skew_con); - qemu_get_be32s(f, &s->ioff_skew_mon); - qemu_get_be32s(f, &s->others); - qemu_get_be32s(f, &s->om_stat); - qemu_get_be32s(f, &s->mie_control); - qemu_get_be32s(f, &s->hdmi_control); - qemu_get_be32s(f, &s->usb_phy_control); - qemu_get_be32s(f, &s->dac_control); - qemu_get_be32s(f, &s->mipi_dphy_control); - qemu_get_be32s(f, &s->adc_control); - qemu_get_be32s(f, &s->ps_hold_control); - qemu_get_be32s(f, &s->inform0); - qemu_get_be32s(f, &s->inform1); - qemu_get_be32s(f, &s->inform2); - qemu_get_be32s(f, &s->inform3); - qemu_get_be32s(f, &s->inform4); - qemu_get_be32s(f, &s->inform5); - qemu_get_be32s(f, &s->inform6); - qemu_get_be32s(f, &s->inform7); - - return 0; -} - -static void s5pc1xx_pmu_reset(void *opaque) -{ - S5pc1xxPMUState *s = (S5pc1xxPMUState *)opaque; - - s->osc_con = 0x00000003; - s->rst_stat = 0x00000001; - s->normal_cfg = 0xFFFFFFBF; - s->idle_cfg = 0x60000000; - s->stop_cfg = 0x96000000; - s->stop_mem_cfg = 0x000000FF; - s->osc_freq = 0x0000000F; - s->osc_stable = 0x000FFFFF; - s->mtc_stable = 0xFFFFFFFF; - s->clamp_stable = 0x03FF03FF; - s->blk_pwr_stat = 0x000000BF; - s->body_bias_con = 0x00000606; - s->mie_control = 0x00000001; - s->hdmi_control = 0x00960000; - s->dac_control = 0x00000001; - s->ps_hold_control = 0x00005301; -} - -static int s5pc1xx_pmu_init(SysBusDevice *dev) -{ - S5pc1xxPMUState *s = FROM_SYSBUS(S5pc1xxPMUState, dev); - int iomemtype; - - iomemtype = - cpu_register_io_memory(s5pc1xx_pmu_readfn, s5pc1xx_pmu_writefn, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC110_PMU_SFR_SIZE, iomemtype); - - s5pc1xx_pmu_reset(s); - - qemu_register_reset(s5pc1xx_pmu_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.pmu", -1, 1, - s5pc1xx_pmu_save, s5pc1xx_pmu_load, s); - - return 0; -} - - -/* Maxim MAX17040 Fuel Gauge */ - -#define MAX17040_VCELL_MSB 0x02 -#define MAX17040_VCELL_LSB 0x03 -#define MAX17040_SOC_MSB 0x04 -#define MAX17040_SOC_LSB 0x05 -#define MAX17040_MODE_MSB 0x06 -#define MAX17040_MODE_LSB 0x07 -#define MAX17040_VER_MSB 0x08 -#define MAX17040_VER_LSB 0x09 -#define MAX17040_RCOMP_MSB 0x0C -#define MAX17040_RCOMP_LSB 0x0D -#define MAX17040_CMD_MSB 0xFE -#define MAX17040_CMD_LSB 0xFF - -#define MAX17040_DELAY 1000 -#define MAX17040_BATTERY_FULL 95 -#define MAX17040_BATTERY_CHARGE 40 - - -typedef struct MAX17040State { - SMBusDevice smbusdev; - - uint16_t charge; - uint16_t vcell; - uint16_t mode; - uint16_t ver; - uint16_t rcomp; - uint16_t cmd; -} MAX17040State; - -static void max17040_reset(void *opaque) -{ - MAX17040State *s = (MAX17040State *)opaque; - - s->charge = MAX17040_BATTERY_CHARGE << 8; - s->vcell = 4200; - s->mode = 0; - s->ver = 0xAA28; - s->rcomp = 0; - s->cmd = 0; -} - -static void max17040_write_data(SMBusDevice *dev, uint8_t cmd, - uint8_t *buf, int len) -{ - MAX17040State *s = (MAX17040State *)dev; - int shift = 0, i; - uint16_t *reg = NULL; - - switch (cmd) { - case MAX17040_VCELL_LSB: - shift = 1; - case MAX17040_VCELL_MSB: - reg = &s->vcell; - break; - case MAX17040_SOC_LSB: - shift = 1; - case MAX17040_SOC_MSB: - reg = &s->charge; - break; - case MAX17040_MODE_LSB: - shift = 1; - case MAX17040_MODE_MSB: - reg = &s->mode; - break; - case MAX17040_VER_LSB: - shift = 1; - case MAX17040_VER_MSB: - reg = &s->ver; - break; - case MAX17040_RCOMP_LSB: - shift = 1; - case MAX17040_RCOMP_MSB: - reg = &s->rcomp; - break; - case MAX17040_CMD_LSB: - shift = 1; - case MAX17040_CMD_MSB: - reg = &s->cmd; - break; - default: - hw_error("max17040: bad write offset 0x%x\n", cmd); - } - - if (len > 2 - shift) { - hw_error("max17040: bad write length %d\n", len); - } - - for (i = 0; i < len; i++) { - *((uint8_t *)reg + i + shift) = buf[i]; - } -} - -static uint8_t max17040_read_data(SMBusDevice *dev, uint8_t cmd, int n) -{ - MAX17040State *s = (MAX17040State *)dev; - int shift = 0; - uint16_t val; - - if (n > 0) { - //bypass => todo check!! - //hw_error("max17040: bad read length %d\n", n); - } - - switch (cmd) { - case MAX17040_VCELL_MSB: - shift = 1; - case MAX17040_VCELL_LSB: - val = s->vcell; - break; - case MAX17040_SOC_MSB: - shift = 1; - case MAX17040_SOC_LSB: - val = s->charge; - break; - case MAX17040_MODE_MSB: - shift = 1; - case MAX17040_MODE_LSB: - val = s->mode; - break; - case MAX17040_VER_MSB: - shift = 1; - case MAX17040_VER_LSB: - val = s->ver; - break; - case MAX17040_RCOMP_MSB: - shift = 1; - case MAX17040_RCOMP_LSB: - val = s->rcomp; - break; - case MAX17040_CMD_MSB: - shift = 1; - case MAX17040_CMD_LSB: - val = s->cmd; - break; - default: - hw_error("max17040: bad read offset 0x%x\n", cmd); - } - - return ((val >> (shift * 8)) & 0xFF); -} - -static void max17040_save(QEMUFile *f, void *opaque) -{ - MAX17040State *s = (MAX17040State *)opaque; - - qemu_put_be16s(f, &s->charge); - qemu_put_be16s(f, &s->vcell); - qemu_put_be16s(f, &s->mode); - qemu_put_be16s(f, &s->ver); - qemu_put_be16s(f, &s->rcomp); - qemu_put_be16s(f, &s->cmd); -} - -static int max17040_load(QEMUFile *f, void *opaque, int version_id) -{ - MAX17040State *s = (MAX17040State *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be16s(f, &s->charge); - qemu_get_be16s(f, &s->vcell); - qemu_get_be16s(f, &s->mode); - qemu_get_be16s(f, &s->ver); - qemu_get_be16s(f, &s->rcomp); - qemu_get_be16s(f, &s->cmd); - - return 0; -} - -DeviceState *max17040_init(i2c_bus *bus, int addr) -{ - DeviceState *dev = qdev_create((BusState *)bus, "max17040"); - qdev_init_nofail(dev); - i2c_set_slave_address((i2c_slave *)dev, addr); - return dev; -} - -static int max17040_init1(SMBusDevice *dev) -{ - MAX17040State *s = (MAX17040State *) dev; - max17040_reset(s); - qemu_register_reset(max17040_reset, s); - register_savevm(&dev->i2c.qdev, "max17040", -1, 1, - max17040_save, max17040_load, s); - return 0; -} - -static SMBusDeviceInfo max17040_info = { - .i2c.qdev.name = "max17040", - .i2c.qdev.size = sizeof(MAX17040State), - .init = max17040_init1, - .write_data = max17040_write_data, - .read_data = max17040_read_data -}; - - -/* Maxim MAX8998 Battery Charger */ - -#define MAX8998_REG_IRQ1 0 -#define MAX8998_REG_IRQ2 1 -#define MAX8998_REG_IRQ3 2 -#define MAX8998_REG_IRQ4 3 -#define MAX8998_REG_IRQM1 4 -#define MAX8998_REG_IRQM2 5 -#define MAX8998_REG_IRQM3 6 -#define MAX8998_REG_IRQM4 7 -#define MAX8998_REG_STATUS1 8 -#define MAX8998_REG_STATUS2 9 -#define MAX8998_REG_STATUSM1 10 -#define MAX8998_REG_STATUSM2 11 -#define MAX8998_REG_CHGR1 12 -#define MAX8998_REG_CHGR2 13 -#define MAX8998_REG_LDO_ACTIVE_DISCHARGE1 14 -#define MAX8998_REG_LDO_ACTIVE_DISCHARGE2 15 -#define MAX8998_REG_BUCK_ACTIVE_DISCHARGE3 16 -#define MAX8998_REG_ONOFF1 17 -#define MAX8998_REG_ONOFF2 18 -#define MAX8998_REG_ONOFF3 19 -#define MAX8998_REG_ONOFF4 20 -#define MAX8998_REG_BUCK1_DVSARM1 21 -#define MAX8998_REG_BUCK1_DVSARM2 22 -#define MAX8998_REG_BUCK1_DVSARM3 23 -#define MAX8998_REG_BUCK1_DVSARM4 24 -#define MAX8998_REG_BUCK2_DVSINT1 25 -#define MAX8998_REG_BUCK2_DVSINT2 26 -#define MAX8998_REG_BUCK3 27 -#define MAX8998_REG_BUCK4 28 -#define MAX8998_REG_LDO2_LDO3 29 -#define MAX8998_REG_LDO4 30 -#define MAX8998_REG_LDO5 31 -#define MAX8998_REG_LDO6 32 -#define MAX8998_REG_LDO7 33 -#define MAX8998_REG_LDO8_LDO9 34 -#define MAX8998_REG_LDO10_LDO11 35 -#define MAX8998_REG_LDO12 36 -#define MAX8998_REG_LDO13 37 -#define MAX8998_REG_LDO14 38 -#define MAX8998_REG_LDO15 39 -#define MAX8998_REG_LDO16 40 -#define MAX8998_REG_LDO17 41 -#define MAX8998_REG_BKCHR 42 -#define MAX8998_REG_LBCNFG1 43 -#define MAX8998_REG_LBCNFG2 44 - - -typedef struct MAX8998State { - SMBusDevice smbusdev; - - uint32_t irq; - uint32_t irqm; - uint16_t status; - uint16_t statusm; - uint16_t chgr; - uint16_t ldo_active_discharge; - uint8_t buck_active_discharge; - uint32_t onoff; - uint32_t buck1_dvsarm; - uint16_t buck2_dvsint; - uint8_t buck3; - uint8_t buck4; - uint32_t ldo23_4_5_6; - uint32_t ldo7_89_1011_12; - uint32_t ldo13_14_15_16; - uint8_t ldo17; - uint8_t bkchr; - uint16_t lbcnfg; -} MAX8998State; - -static void max8998_reset(void *opaque) -{ - MAX8998State *s = (MAX8998State *)opaque; - - s->irq = 0; - s->irqm = 0; - s->status = 0; - s->statusm = 0xEFFF; - s->chgr = 0xA80; - s->ldo_active_discharge = 0; - s->buck_active_discharge = 0; - s->onoff = 0; - s->buck1_dvsarm = 0; - s->buck2_dvsint = 0; - s->buck3 = 0; - s->buck4 = 0; - s->ldo23_4_5_6 = 0; - s->ldo7_89_1011_12 = 0; - s->ldo13_14_15_16 = 0; - s->ldo17 = 0; - s->bkchr = 0; - s->lbcnfg = 0; -} - -static uint8_t *max8998_get_reg_addr(MAX8998State *s, uint8_t cmd) -{ - int shift = 0; - uint8_t *reg = NULL; - - switch (cmd) { - case MAX8998_REG_IRQ4: - case MAX8998_REG_IRQM4: - case MAX8998_REG_STATUS2: - case MAX8998_REG_STATUSM2: - case MAX8998_REG_CHGR2: - case MAX8998_REG_LDO_ACTIVE_DISCHARGE2: - case MAX8998_REG_BUCK_ACTIVE_DISCHARGE3: - case MAX8998_REG_ONOFF4: - case MAX8998_REG_BUCK1_DVSARM4: - case MAX8998_REG_BUCK2_DVSINT2: - case MAX8998_REG_BUCK3: - case MAX8998_REG_BUCK4: - case MAX8998_REG_LDO6: - case MAX8998_REG_LDO12: - case MAX8998_REG_LDO16: - case MAX8998_REG_LDO17: - case MAX8998_REG_BKCHR: - case MAX8998_REG_LBCNFG2: - break; - case MAX8998_REG_IRQ3: - case MAX8998_REG_IRQM3: - case MAX8998_REG_STATUS1: - case MAX8998_REG_STATUSM1: - case MAX8998_REG_CHGR1: - case MAX8998_REG_LDO_ACTIVE_DISCHARGE1: - case MAX8998_REG_ONOFF3: - case MAX8998_REG_BUCK1_DVSARM3: - case MAX8998_REG_BUCK2_DVSINT1: - case MAX8998_REG_LDO5: - case MAX8998_REG_LDO10_LDO11: - case MAX8998_REG_LDO15: - case MAX8998_REG_LBCNFG1: - shift = 1; - break; - case MAX8998_REG_IRQ2: - case MAX8998_REG_IRQM2: - case MAX8998_REG_ONOFF2: - case MAX8998_REG_BUCK1_DVSARM2: - case MAX8998_REG_LDO4: - case MAX8998_REG_LDO8_LDO9: - case MAX8998_REG_LDO14: - shift = 2; - break; - case MAX8998_REG_IRQ1: - case MAX8998_REG_IRQM1: - case MAX8998_REG_ONOFF1: - case MAX8998_REG_BUCK1_DVSARM1: - case MAX8998_REG_LDO2_LDO3: - case MAX8998_REG_LDO7: - case MAX8998_REG_LDO13: - shift = 3; - break; - default: - hw_error("max8998: bad write offset 0x%x\n", cmd); - } - - switch (cmd) { - case MAX8998_REG_IRQ1: - case MAX8998_REG_IRQ2: - case MAX8998_REG_IRQ3: - case MAX8998_REG_IRQ4: - reg = (uint8_t *)&s->irq; - break; - case MAX8998_REG_IRQM1: - case MAX8998_REG_IRQM2: - case MAX8998_REG_IRQM3: - case MAX8998_REG_IRQM4: - reg = (uint8_t *)&s->irqm; - break; - case MAX8998_REG_STATUS1: - case MAX8998_REG_STATUS2: - reg = (uint8_t *)&s->status; - break; - case MAX8998_REG_STATUSM1: - case MAX8998_REG_STATUSM2: - reg = (uint8_t *)&s->statusm; - break; - case MAX8998_REG_CHGR1: - case MAX8998_REG_CHGR2: - reg = (uint8_t *)&s->chgr; - break; - case MAX8998_REG_LDO_ACTIVE_DISCHARGE1: - case MAX8998_REG_LDO_ACTIVE_DISCHARGE2: - reg = (uint8_t *)&s->ldo_active_discharge; - break; - case MAX8998_REG_BUCK_ACTIVE_DISCHARGE3: - reg = (uint8_t *)&s->buck_active_discharge; - break; - case MAX8998_REG_ONOFF1: - case MAX8998_REG_ONOFF2: - case MAX8998_REG_ONOFF3: - case MAX8998_REG_ONOFF4: - reg = (uint8_t *)&s->onoff; - break; - case MAX8998_REG_BUCK1_DVSARM1: - case MAX8998_REG_BUCK1_DVSARM2: - case MAX8998_REG_BUCK1_DVSARM3: - case MAX8998_REG_BUCK1_DVSARM4: - reg = (uint8_t *)&s->buck1_dvsarm; - break; - case MAX8998_REG_BUCK2_DVSINT1: - case MAX8998_REG_BUCK2_DVSINT2: - reg = (uint8_t *)&s->buck2_dvsint; - break; - case MAX8998_REG_BUCK3: - reg = (uint8_t *)&s->buck3; - break; - case MAX8998_REG_BUCK4: - reg = (uint8_t *)&s->buck4; - break; - case MAX8998_REG_LDO2_LDO3: - case MAX8998_REG_LDO4: - case MAX8998_REG_LDO5: - case MAX8998_REG_LDO6: - reg = (uint8_t *)&s->ldo23_4_5_6; - break; - case MAX8998_REG_LDO7: - case MAX8998_REG_LDO8_LDO9: - case MAX8998_REG_LDO10_LDO11: - case MAX8998_REG_LDO12: - reg = (uint8_t *)&s->ldo7_89_1011_12; - break; - case MAX8998_REG_LDO13: - case MAX8998_REG_LDO14: - case MAX8998_REG_LDO15: - case MAX8998_REG_LDO16: - reg = (uint8_t *)&s->ldo13_14_15_16; - break; - case MAX8998_REG_LDO17: - reg = (uint8_t *)&s->ldo17; - break; - case MAX8998_REG_BKCHR: - reg = (uint8_t *)&s->bkchr; - break; - case MAX8998_REG_LBCNFG1: - case MAX8998_REG_LBCNFG2: - reg = (uint8_t *)&s->lbcnfg; - break; - default: - hw_error("max8998: bad write offset 0x%x\n", cmd); - } - - return (reg + shift); -} - -static void max8998_write_data(SMBusDevice *dev, uint8_t cmd, - uint8_t *buf, int len) -{ - MAX8998State *s = (MAX8998State *)dev; - - if (len > 1) { - hw_error("max8998: bad write length %d\n", len); - } - - *(max8998_get_reg_addr(s, cmd)) = buf[0]; -} - -static uint8_t max8998_read_data(SMBusDevice *dev, uint8_t cmd, int n) -{ - MAX8998State *s = (MAX8998State *)dev; - - if (n > 0 && cmd != MAX8998_REG_IRQ1) { - hw_error("max8998: bad read length %d\n", n); - } - - return *(max8998_get_reg_addr(s, cmd) + n); -} - -static void max8998_save(QEMUFile *f, void *opaque) -{ - MAX8998State *s = (MAX8998State *)opaque; - - qemu_put_be32s(f, &s->irq); - qemu_put_be32s(f, &s->irqm); - qemu_put_be16s(f, &s->status); - qemu_put_be16s(f, &s->statusm); - qemu_put_be16s(f, &s->chgr); - qemu_put_be16s(f, &s->ldo_active_discharge); - qemu_put_8s (f, &s->buck_active_discharge); - qemu_put_be32s(f, &s->onoff); - qemu_put_be32s(f, &s->buck1_dvsarm); - qemu_put_be16s(f, &s->buck2_dvsint); - qemu_put_8s (f, &s->buck3); - qemu_put_8s (f, &s->buck4); - qemu_put_be32s(f, &s->ldo23_4_5_6); - qemu_put_be32s(f, &s->ldo7_89_1011_12); - qemu_put_be32s(f, &s->ldo13_14_15_16); - qemu_put_8s (f, &s->ldo17); - qemu_put_8s (f, &s->bkchr); - qemu_put_be16s(f, &s->lbcnfg); -} - -static int max8998_load(QEMUFile *f, void *opaque, int version_id) -{ - MAX8998State *s = (MAX8998State *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->irq); - qemu_get_be32s(f, &s->irqm); - qemu_get_be16s(f, &s->status); - qemu_get_be16s(f, &s->statusm); - qemu_get_be16s(f, &s->chgr); - qemu_get_be16s(f, &s->ldo_active_discharge); - qemu_get_8s (f, &s->buck_active_discharge); - qemu_get_be32s(f, &s->onoff); - qemu_get_be32s(f, &s->buck1_dvsarm); - qemu_get_be16s(f, &s->buck2_dvsint); - qemu_get_8s (f, &s->buck3); - qemu_get_8s (f, &s->buck4); - qemu_get_be32s(f, &s->ldo23_4_5_6); - qemu_get_be32s(f, &s->ldo7_89_1011_12); - qemu_get_be32s(f, &s->ldo13_14_15_16); - qemu_get_8s (f, &s->ldo17); - qemu_get_8s (f, &s->bkchr); - qemu_get_be16s(f, &s->lbcnfg); - - return 0; -} - -DeviceState *max8998_init(i2c_bus *bus, int addr) -{ - DeviceState *dev = qdev_create((BusState *)bus, "max8998"); - qdev_init_nofail(dev); - i2c_set_slave_address((i2c_slave *)dev, addr); - return dev; -} - -static int max8998_init1(SMBusDevice *dev) -{ - MAX8998State *s = (MAX8998State *) dev; - max8998_reset(s); - qemu_register_reset(max8998_reset, s); - register_savevm(&dev->i2c.qdev, "max8998", -1, 1, - max8998_save, max8998_load, s); - return 0; -} - -static SMBusDeviceInfo max8998_info = { - .i2c.qdev.name = "max8998", - .i2c.qdev.size = sizeof(MAX8998State), - .init = max8998_init1, - .write_data = max8998_write_data, - .read_data = max8998_read_data -}; - - -/* Maxim MAX8998 Real Time Clock */ - -/* MX8998 RTC I2C MAP */ -#define RTC_SEC 0x0 /* second 00-59 */ -#define RTC_MIN 0x1 /* minute 00-59 */ -#define RTC_HR 0x2 /* hour AM/PM 1-12 or 00-23 */ -#define RTC_DAY 0x3 /* weekday 1-7 */ -#define RTC_DATE 0x4 /* date 01-31 */ -#define RTC_MT 0x5 /* month 01-12 */ -#define RTC_YEAR 0x6 /* year 00-99 */ -#define RTC_CEN 0x7 /* century 00-99 */ - -#define RTC_CON 0x1A - #define RTC_EN 0x01 /* RTC control enable */ - -#define MAX8998_REG(x, y) (0x8 * y + x) - -/* Time Keeper */ -#define MAX8998_RTC 0 -/* Alarm0 */ -#define MAX8998_ALRM0 1 -/* Alarm1 */ -#define MAX8998_ALRM1 2 -/* Conf */ -#define MAX8998_ALRM0_CONF 0x18 -#define MAX8998_ALRM1_CONF 0x19 - -#define MAX8998_ALRM_ON 0x77 -#define MAX8998_ALRM_OFF 0x0 - - -typedef struct MAX8998RTCState { - SMBusDevice smbusdev; - - uint8_t regs[RTC_CON + 1]; - - /* seconds update */ - QEMUTimer *seconds_timer; - struct tm current_tm; -} MAX8998RTCState; - -static void max8998_rtc_seconds_update(void *opaque); - -/* Set default values for all fields */ -static void max8998_rtc_reset(void *opaque) -{ - MAX8998RTCState *s = (MAX8998RTCState *)opaque; - short i; - - /* stop seconds timer */ - s->regs[RTC_CON] = 0x0; - max8998_rtc_seconds_update(s); - - for (i = RTC_SEC; i <= RTC_CEN; i++) { - s->regs[MAX8998_REG(i, MAX8998_RTC)] = 0; - } - /* get time from host */ - qemu_get_timedate(&s->current_tm, 0); - - /* start seconds timer */ - s->regs[RTC_CON] |= RTC_EN; - max8998_rtc_seconds_update(s); -} - -/* Get days in month. Month is between 0 and 11 */ -static int get_days_in_month(int month, int year) -{ - short d; - static const int days_tab[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - - if ((unsigned)month >= 12) { - return 31; - } - d = days_tab[month]; - if (month == 1) { - if ((year % 4) == 0) { - d++; - } - } - return d; -} - -/* Update 'struct tm' to the next second */ -static void max8998_rtc_next_second(struct tm *tm) -{ - int days_in_month; - - tm->tm_sec++; - if ((unsigned)tm->tm_sec >= 60) { - tm->tm_sec = 0; - tm->tm_min++; - if ((unsigned)tm->tm_min >= 60) { - tm->tm_min = 0; - tm->tm_hour++; - if ((unsigned)tm->tm_hour >= 24) { - tm->tm_hour = 0; - /* next day */ - tm->tm_wday++; - if ((unsigned)tm->tm_wday >= 8) { - tm->tm_wday = 1; - } - days_in_month = get_days_in_month(tm->tm_mon, tm->tm_year); - tm->tm_mday++; - if (tm->tm_mday < 1) { - tm->tm_mday = 1; - } else if (tm->tm_mday > days_in_month) { - tm->tm_mday = 1; - tm->tm_mon++; - if (tm->tm_mon >= 12) { - tm->tm_mon = 0; - tm->tm_year++; - } - } - } - } - } -} - -/* Using of qemu_timer to increase seconds */ -static void max8998_rtc_seconds_update(void *opaque) -{ - MAX8998RTCState *s = (MAX8998RTCState *)opaque; - uint64_t next_seconds_time; - - if (s->regs[RTC_CON] & RTC_EN) { - max8998_rtc_next_second(&(s->current_tm)); - next_seconds_time = qemu_get_clock(vm_clock) + get_ticks_per_sec(); - qemu_mod_timer(s->seconds_timer, next_seconds_time); - } else { - qemu_del_timer(s->seconds_timer); - } -} - -/* Convert time from bcd */ -static void max8998_rtc_set_time(MAX8998RTCState *s) -{ - struct tm *tm = &(s->current_tm); - - tm->tm_sec = from_bcd(s->regs[RTC_SEC]); - tm->tm_min = from_bcd(s->regs[RTC_MIN]); - tm->tm_hour = from_bcd(s->regs[RTC_HR] & 0x3f); - tm->tm_mday = from_bcd(s->regs[RTC_DATE]); - tm->tm_mon = from_bcd(s->regs[RTC_MT]); - tm->tm_year = from_bcd(s->regs[RTC_YEAR]) + - from_bcd(s->regs[RTC_CEN]) * 100 - 1900; - tm->tm_wday = s->regs[RTC_DAY]; /* one decimal digit */ -} - -/* Convert time to bcd */ -static void max8998_rtc_read_time(MAX8998RTCState *s) -{ - const struct tm *tm = &(s->current_tm); - - s->regs[RTC_SEC] = to_bcd(tm->tm_sec); - s->regs[RTC_MIN] = to_bcd(tm->tm_min); - s->regs[RTC_HR] = to_bcd(tm->tm_hour); - s->regs[RTC_DATE] = to_bcd(tm->tm_mday); - s->regs[RTC_MT] = to_bcd(tm->tm_mon); - s->regs[RTC_YEAR] = to_bcd(tm->tm_year % 100); - s->regs[RTC_CEN] = to_bcd((tm->tm_year + 1900) / 100); - s->regs[RTC_DAY] = tm->tm_wday; /* one decimal digit */ -} - -/* Write RTC MAX8998 by I2C through SMBus */ -static void max8998_rtc_write(SMBusDevice *dev, uint8_t cmd, - uint8_t *buf, int len) -{ - MAX8998RTCState *s = (MAX8998RTCState *)dev; - uint8_t *reg = NULL; - int i; - - switch (cmd) { - case MAX8998_REG(RTC_SEC, MAX8998_RTC) ... - MAX8998_REG(RTC_CEN, MAX8998_RTC): - case MAX8998_ALRM0_CONF: - case MAX8998_ALRM1_CONF: - reg = &s->regs[cmd]; - break; - - /* TODO: Implement alarm support */ - case MAX8998_REG(RTC_SEC, MAX8998_ALRM0) ... - MAX8998_REG(RTC_CEN, MAX8998_ALRM1): - return; - - default: - hw_error("max8998-rtc: bad write offset 0x%x\n", cmd); - } - - for (i = 0; i < len; i++) { - *((uint8_t *)reg + i) = buf[i]; - } - - if (cmd <= MAX8998_REG(RTC_CEN, MAX8998_RTC)) { - max8998_rtc_set_time(s); - } -} - -/* Read RTC MAX8998 by I2C through SMBus */ -static uint8_t max8998_rtc_read(SMBusDevice *dev, uint8_t cmd, int n) -{ - MAX8998RTCState *s = (MAX8998RTCState *)dev; - uint16_t val; - - if (n > 0) { - hw_error("max8998-rtc: bad read length %d\n", n); - } - - switch (cmd) { - case MAX8998_REG(RTC_SEC, MAX8998_RTC) ... - MAX8998_REG(RTC_CEN, MAX8998_RTC): - max8998_rtc_read_time(s); - case MAX8998_ALRM0_CONF: - case MAX8998_ALRM1_CONF: - val = s->regs[cmd]; - break; - - /* TODO: Implement alarm support */ - case MAX8998_REG(RTC_SEC, MAX8998_ALRM0) ... - MAX8998_REG(RTC_CEN, MAX8998_ALRM1): - return 0; - - default: - hw_error("max8998-rtc: bad read offset 0x%x\n", cmd); - } - - return (val & 0xFF); -} - -static void max8998_rtc_save(QEMUFile *f, void *opaque) -{ - MAX8998RTCState *s = (MAX8998RTCState *)opaque; - - max8998_rtc_read_time(s); - - qemu_put_buffer(f, s->regs, sizeof(s->regs)); - qemu_put_timer(f, s->seconds_timer); -} - -static int max8998_rtc_load(QEMUFile *f, void *opaque, int version_id) -{ - MAX8998RTCState *s = (MAX8998RTCState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_buffer(f, s->regs, sizeof(s->regs)); - - qemu_get_timedate(&s->current_tm, 0); - max8998_rtc_read_time(s); - - qemu_get_timer(f, s->seconds_timer); - - return 0; -} - -DeviceState *max8998_rtc_init(i2c_bus *bus, int addr) -{ - DeviceState *dev = qdev_create((BusState *)bus, "max8998-rtc"); - qdev_init_nofail(dev); - i2c_set_slave_address((i2c_slave *)dev, addr); - return dev; -} - -static int max8998_rtc_init1(SMBusDevice *dev) -{ - MAX8998RTCState *s = (MAX8998RTCState *) dev; - - s->seconds_timer = qemu_new_timer(vm_clock, max8998_rtc_seconds_update, s); - - /* initialize values */ - max8998_rtc_reset(s); - - qemu_register_reset(max8998_rtc_reset, s); - register_savevm(&dev->i2c.qdev, "max8998-rtc", -1, 1, - max8998_rtc_save, max8998_rtc_load, s); - - return 0; -} - -static SMBusDeviceInfo max8998_rtc_info = { - .i2c.qdev.name = "max8998-rtc", - .i2c.qdev.size = sizeof(MAX8998RTCState), - .init = max8998_rtc_init1, - .write_data = max8998_rtc_write, - .read_data = max8998_rtc_read -}; - -static void s5pc1xx_pmu_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.pmu", sizeof(S5pc1xxPMUState), s5pc1xx_pmu_init); - smbus_register_device(&max17040_info); - smbus_register_device(&max8998_info); - smbus_register_device(&max8998_rtc_info); -} - -device_init(s5pc1xx_pmu_register_devices) diff --git a/hw/s5pc1xx_pwm.c b/hw/s5pc1xx_pwm.c deleted file mode 100644 index cf7ea7a..0000000 --- a/hw/s5pc1xx_pwm.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * PWM Timer for S5PC110-based board emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "s5pc1xx.h" -#include "qemu-timer.h" -#include "sysbus.h" -#include "s5pc1xx_gpio_regs.h" - - -#define S5C_TCFG0 (0x00) /* R/W Timer Configuration - * Register 0 that configures two - * 8-bit Prescaler and DeadZone - * Length */ -#define S5C_TCFG1 (0x04) /* R/W Timer Configuration - * Register 1 that controls - * 5 MUX Select Bit */ -#define S5C_TCON (0x08) /* R/W Timer Control Register */ -#define S5C_TINT_CSTAT (0x44) /* R/W Timer Interrupt Control and - * Status Register */ -/* TCFG0 */ -#define S5C_TCFG0_PRESCALER0_SHIFT (0) -#define S5C_TCFG0_PRESCALER1_SHIFT (8) - -/* TCFG1 */ -#define S5C_TCFG1_DIV_SHIFT(tmr) (tmr * 0x04) -#define TCLK 0x5 - -/* TINT_CSTAT */ -#define INT_EN(tmr) (1 << tmr) -#define INT_STAT(tmr) (1 << (tmr+5)) - -#define S5C_TIMERREG(tmr,reg) (0x0c + reg + (0x0c * tmr)) - -/* R/W Timer 0..4 Count Buffer Register */ -#define S5C_TCNTB(tmr) S5C_TIMERREG(tmr, 0x00) - -/* R/W Timer 0..4 Compare Buffer Register */ -#define S5C_TCMPB(tmr) S5C_TIMERREG(tmr, 0x04) - -/* R Timer 0..4 Count Observation Register */ -#define S5C_TCNTO(tmr) S5C_TIMERREG(tmr, ((tmr == 4) ? 0x04 : 0x08)) -#define ALL_STAT (INT_STAT(0) | INT_STAT(1) | INT_STAT(2) | \ - INT_STAT(3) | INT_STAT(4)) - -#define S5PC1XX_PWM_REG_MEM_SIZE 0x50 - -static const uint32_t S5C_TCON_RELOAD[5] = {(1 << 3), (1 << 11), (1 << 15), (1 << 19), (1 << 22)}; -static const uint32_t S5C_TCON_INVERT[5] = {(1 << 2), (1 << 10), (1 << 14), (1 << 18), (0) }; -static const uint32_t S5C_TCON_MANUALUPD[5] = {(1 << 1), (1 << 9), (1 << 13), (1 << 17), (1 << 21)}; -static const uint32_t S5C_TCON_START[5] = {(1 << 0), (1 << 8), (1 << 12), (1 << 16), (1 << 20)}; - - -struct S5pc1xxPWMState; - -typedef struct S5pc1xxPWMTimerState { - qemu_irq irq_inst; /* irq instance */ - uint8_t tag; /* control tag and timer number */ - - QEMUTimer *pwm_timer; - uint32_t freq_out; - uint64_t last_pwm_time; - - uint32_t tcntb; /* count buffer value */ - uint64_t tcntb_in_qemu; /* tcntb measured in 1/(9GHz) units */ - uint32_t tcnt; /* count initial value */ - uint64_t tcnt_in_qemu; /* tcnt measured in 1/(9GHz) units */ - uint32_t tcmpb; /* comparison buffer value */ - uint32_t tcmp; /* comparison current value */ - - struct S5pc1xxPWMState *regs; -} S5pc1xxPWMTimerState; - -typedef struct S5pc1xxPWMState { - SysBusDevice busdev; - uint8_t tag; /* control tag */ - /* control regs */ - uint32_t tcfg0; - uint32_t tcfg1; - uint32_t tcon; - uint32_t tint_cstat; - S5pc1xxPWMTimerState tmr[5]; /* timers settings */ -} S5pc1xxPWMState; - - -/* Convert term to be measured in (1/pwm_timer_freq) units */ -static uint32_t s5pc1xx_pwm_convert_term(uint64_t term, uint32_t timer_freq) -{ - return muldiv64(term, timer_freq, get_ticks_per_sec()); -} - -/* Get buffer values */ -static void s5pc1xx_pwm_timer_renew(S5pc1xxPWMTimerState *t) -{ - t->tcmp = t->tcmpb; - t->tcnt = t->tcntb; - t->tcnt_in_qemu = t->tcntb_in_qemu; -} - -/* Set timer */ -static void s5pc1xx_pwm_timer_start(S5pc1xxPWMTimerState *t) -{ - t->last_pwm_time = qemu_get_clock(vm_clock); - qemu_mod_timer(t->pwm_timer, t->last_pwm_time + t->tcnt_in_qemu); -} - -/* Stop timer */ -static void s5pc1xx_pwm_timer_stop(S5pc1xxPWMTimerState *t) -{ - qemu_del_timer(t->pwm_timer); -} - -/* Events when timer riches zero */ -static void s5pc1xx_pwm_timer_expiry(void *opaque) -{ - S5pc1xxPWMTimerState *t = (S5pc1xxPWMTimerState *)opaque; - uint8_t num = t->tag; - - if (t->tag > 4) - hw_error("s5pc1xx.pwm: timer_expiry - wrong param (tag = %u)\n", - t->tag); - - /* Interrupt raising */ - t->regs->tint_cstat |= INT_STAT(num); - if (t->regs->tint_cstat & INT_EN(num)) - qemu_irq_raise(t->irq_inst); - - if (t->regs->tcon & S5C_TCON_RELOAD[num]) { - s5pc1xx_pwm_timer_renew(t); - s5pc1xx_pwm_timer_start(t); - } -} - -/* Update timer frequency */ -static void s5pc1xx_pwm_timer_freq(S5pc1xxPWMTimerState *t) -{ - S5pc1xxClk clk; - uint8_t divisor; - uint8_t prescaler = 0; - - if (t->tag > 4) - hw_error("s5pc1xx.pwm: timer_freq - wrong param (tag = %u)\n", - t->tag); - - switch (t->regs->tcfg1 >> S5C_TCFG1_DIV_SHIFT(t->tag) & 0xf) { - case TCLK: - clk = s5pc1xx_findclk("sclk_pwm"); - prescaler = 0; - divisor = 1; - break; - default: - clk = s5pc1xx_findclk("pclk_66"); - switch (t->tag) { - case 0 ... 1: - prescaler = - t->regs->tcfg0 >> S5C_TCFG0_PRESCALER0_SHIFT & 0xFF; - break; - case 2 ... 4: - prescaler = - t->regs->tcfg0 >> S5C_TCFG0_PRESCALER1_SHIFT & 0xFF; - break; - } - divisor = 1 << (t->regs->tcfg1 >> S5C_TCFG1_DIV_SHIFT(t->tag) & 0xF); - } - t->freq_out = s5pc1xx_clk_getrate(clk) / (prescaler + 1) / divisor; -} - -/* Read PWM by GPIO */ -static uint32_t s5pc1xx_pwm_gpio_read(void *opaque, - int io_index) -{ - S5pc1xxPWMState *s = (S5pc1xxPWMState *)opaque; - uint8_t i, tout = 0; - - if (s->tag < 255) - hw_error("s5pc1xx.pwm: gpio_read - wrong param (tag = %u)\n", - s->tag); - - for (i = 0; i < 4; i++) - if (io_index == GPIO_PWM_TOUT(i)) { - tout = (s->tcon & S5C_TCON_INVERT[i]) ? 0 : 1; - - if (s5pc1xx_pwm_convert_term(qemu_get_clock(vm_clock) - s->tmr[i].last_pwm_time, - s->tmr[i].freq_out) < s->tmr[i].tcmp) - tout = (s->tcon & S5C_TCON_INVERT[i]) ? 1 : 0; - } - return tout; -} - -static GPIOReadMemoryFunc *s5pc1xx_pwm_gpio_readfn = s5pc1xx_pwm_gpio_read; -static GPIOWriteMemoryFunc *s5pc1xx_pwm_gpio_writefn = s5pc1xx_empty_gpio_write; /* a plug */ - -/* Read PWM by OS */ -static uint32_t s5pc1xx_pwm_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxPWMState *s = (S5pc1xxPWMState *)opaque; - S5pc1xxPWMTimerState *tmr = s->tmr; - uint32_t tcnto; - uint8_t num; - - if (s->tag < 255) - hw_error("s5pc1xx.pwm: read - wrong param (tag = %u)\n", - s->tag); - - switch (offset) { - case S5C_TCFG0: - return s->tcfg0; - - case S5C_TCFG1: - return s->tcfg1; - - case S5C_TCON: - return s->tcon; - - case S5C_TINT_CSTAT: - return s->tint_cstat; - - case S5C_TCNTB(0): - case S5C_TCNTB(1): - case S5C_TCNTB(2): - case S5C_TCNTB(3): - case S5C_TCNTB(4): - return tmr[(offset - S5C_TCNTB(0)) / 0x0C].tcntb; - - case S5C_TCMPB(0): - case S5C_TCMPB(1): - case S5C_TCMPB(2): - case S5C_TCMPB(3): - return tmr[(offset - S5C_TCMPB(0)) / 0x0C].tcmpb; - - case S5C_TCNTO(0): - case S5C_TCNTO(1): - case S5C_TCNTO(2): - case S5C_TCNTO(3): - case S5C_TCNTO(4): - num = - (offset == S5C_TCNTO(4)) ? 4 : ((offset - S5C_TCNTO(0)) / 0x0C); - - if (!(s->tcon & S5C_TCON_START[num])) - return tmr[num].tcnt; - - if (qemu_get_clock(vm_clock) - tmr[num].last_pwm_time > tmr[num].tcnt_in_qemu) - return 0; - - tcnto = - tmr[num].tcnt - - s5pc1xx_pwm_convert_term(qemu_get_clock(vm_clock) - - tmr[num].last_pwm_time, - tmr[num].freq_out); - return tcnto; - - default: - hw_error("s5pc1xx.pwm: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -/* Write PWM by OS */ -static void s5pc1xx_pwm_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxPWMState *s = (S5pc1xxPWMState *)opaque; - S5pc1xxPWMTimerState *tmr = s->tmr; - uint8_t num; - - if (s->tag < 255) - hw_error("s5pc1xx.pwm: write - wrong param (tag = %u)\n", - s->tag); - - switch (offset) { - case S5C_TCFG0: - s->tcfg0 = value; - for (num = 0; num < 5; num++) - s5pc1xx_pwm_timer_freq(&tmr[num]); - break; - - case S5C_TCFG1: - s->tcfg1 = value; - for (num = 0; num < 5; num++) - s5pc1xx_pwm_timer_freq(&tmr[num]); - break; - - case S5C_TCON: - /* start timer if it was stopped */ - for (num = 0; num < 5; num++) { - if ((value & S5C_TCON_START[num]) > - (s->tcon & S5C_TCON_START[num])) - s5pc1xx_pwm_timer_start(&tmr[num]); - - if ((value & S5C_TCON_START[num]) < - (s->tcon & S5C_TCON_START[num])) - s5pc1xx_pwm_timer_stop(&tmr[num]); - - if (value & S5C_TCON_MANUALUPD[num]) { - s5pc1xx_pwm_timer_stop(&tmr[num]); - s5pc1xx_pwm_timer_renew(&tmr[num]); - } - } - s->tcon = value; - break; - - case S5C_TINT_CSTAT: - for (num = 0; num < 5; num++) - if (value & INT_STAT(num)) - qemu_irq_lower(tmr[num].irq_inst); - /* set TINT_CSTAT as value except *_STAT bits */ - s->tint_cstat = - (s->tint_cstat & ALL_STAT) | (value & ~ALL_STAT); - /* clear *_STAT bits if they are set in value */ - s->tint_cstat &= ~(value & ALL_STAT); - break; - - case S5C_TCNTB(0): - case S5C_TCNTB(1): - case S5C_TCNTB(2): - case S5C_TCNTB(3): - case S5C_TCNTB(4): - num = (offset - S5C_TCNTB(0)) / 0x0C; - /* count buffer */ - tmr[num].tcntb = value; - tmr[num].tcntb_in_qemu = - muldiv64(value, get_ticks_per_sec(), tmr[num].freq_out); - break; - - case S5C_TCMPB(0): - case S5C_TCMPB(1): - case S5C_TCMPB(2): - case S5C_TCMPB(3): - /* comparison buffer */ - tmr[(offset - S5C_TCMPB(0)) / 0x0C].tcmpb = value; - break; - - default: - hw_error("s5pc1xx.pwm: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_pwm_readfn[] = { - s5pc1xx_pwm_read, - s5pc1xx_pwm_read, - s5pc1xx_pwm_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_pwm_writefn[] = { - s5pc1xx_pwm_write, - s5pc1xx_pwm_write, - s5pc1xx_pwm_write -}; - -static void s5pc1xx_pwm_save(QEMUFile *f, void *opaque) -{ - S5pc1xxPWMState *s = (S5pc1xxPWMState *)opaque; - S5pc1xxPWMTimerState *tmr = s->tmr; - uint64_t last; - int num; - - qemu_put_8s (f, &s->tag); - qemu_put_be32s(f, &s->tcfg0); - qemu_put_be32s(f, &s->tcfg1); - qemu_put_be32s(f, &s->tcon); - qemu_put_be32s(f, &s->tint_cstat); - - for (num = 0; num < 5; num++) { - last = qemu_get_clock(vm_clock) - tmr[num].last_pwm_time; - - qemu_put_8s (f, &tmr[num].tag); - qemu_put_be32s(f, &tmr[num].freq_out); - qemu_put_be32s(f, &tmr[num].tcntb); - qemu_put_be64s(f, &tmr[num].tcntb_in_qemu); - qemu_put_be32s(f, &tmr[num].tcnt); - qemu_put_be64s(f, &tmr[num].tcnt_in_qemu); - qemu_put_be32s(f, &tmr[num].tcmpb); - qemu_put_be32s(f, &tmr[num].tcmp); - qemu_put_be64s(f, &last); - - qemu_put_timer(f, tmr[num].pwm_timer); - } -} - -static int s5pc1xx_pwm_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxPWMState *s = (S5pc1xxPWMState *)opaque; - S5pc1xxPWMTimerState *tmr = s->tmr; - uint64_t last; - int num; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_8s (f, &s->tag); - qemu_get_be32s(f, &s->tcfg0); - qemu_get_be32s(f, &s->tcfg1); - qemu_get_be32s(f, &s->tcon); - qemu_get_be32s(f, &s->tint_cstat); - - for (num = 0; num < 5; num++) { - qemu_get_8s (f, &tmr[num].tag); - qemu_get_be32s(f, &tmr[num].freq_out); - qemu_get_be32s(f, &tmr[num].tcntb); - qemu_get_be64s(f, &tmr[num].tcntb_in_qemu); - qemu_get_be32s(f, &tmr[num].tcnt); - qemu_get_be64s(f, &tmr[num].tcnt_in_qemu); - qemu_get_be32s(f, &tmr[num].tcmpb); - qemu_get_be32s(f, &tmr[num].tcmp); - qemu_get_be64s(f, &last); - - tmr[num].last_pwm_time = qemu_get_clock(vm_clock) - last; - - qemu_get_timer(f, tmr[num].pwm_timer); - } - - return 0; -} - -/* PWM Init */ -static int s5pc1xx_pwm_init(SysBusDevice *dev) -{ - int i, iomemtype; - S5pc1xxPWMState *s = FROM_SYSBUS(S5pc1xxPWMState, dev); - S5pc1xxPWMTimerState *tmr = s->tmr; - - s->tag = 255; - - for (i = 0; i < 5; i++) { - tmr[i].tag = i; - tmr[i].regs = s; - sysbus_init_irq(dev, &tmr[i].irq_inst); - tmr[i].pwm_timer = - qemu_new_timer(vm_clock, s5pc1xx_pwm_timer_expiry, &tmr[i]); - } - - s5pc1xx_pwm_write(s, S5C_TCFG0, 0x00000101); - - iomemtype = - cpu_register_io_memory(s5pc1xx_pwm_readfn, s5pc1xx_pwm_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_PWM_REG_MEM_SIZE, iomemtype); - - s5pc1xx_gpio_register_io_memory(GPIO_IDX_PWM, 0, s5pc1xx_pwm_gpio_readfn, - s5pc1xx_pwm_gpio_writefn, NULL, s); - - register_savevm(&dev->qdev, "s5pc1xx.pwm", -1, 1, - s5pc1xx_pwm_save, s5pc1xx_pwm_load, s); - return 0; -} - -static void s5pc1xx_pwm_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.pwm", sizeof(S5pc1xxPWMState), - s5pc1xx_pwm_init); -} - -device_init(s5pc1xx_pwm_register_devices) diff --git a/hw/s5pc1xx_rtc.c b/hw/s5pc1xx_rtc.c deleted file mode 100644 index 23353cc..0000000 --- a/hw/s5pc1xx_rtc.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Real Time Clock for S5C110-based board emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "qemu-common.h" -#include "qemu-timer.h" -#include "sysbus.h" - -/* Registers addresses */ - -#define INT_PEND 0x30 /* R/W Interrupt Pending Register */ -#define RTC_CON 0x40 /* R/W RTC Control Register */ -#define TIC_CNT 0x44 /* R/W Tick Time Count Register */ -#define RTC_ALM 0x50 /* R/W RTC Alarm Control Register */ -#define ALM_SEC 0x54 /* R/W Alarm Second Data Register */ -#define ALM_MIN 0x58 /* R/W Alarm Minute Data Register */ -#define ALM_HOUR 0x5C /* R/W Alarm Hour Data Register */ -#define ALM_DAY 0x60 /* R/W Alarm Day of the month Data Register */ -#define ALM_MON 0x64 /* R/W Alarm Month Data Register */ -#define ALM_YEAR 0x68 /* R/W Alarm Year Data Register */ -#define BCD_SEC 0x70 /* R/W BCD Second Register */ -#define BCD_MIN 0x74 /* R/W BCD Minute Register */ -#define BCD_HOUR 0x78 /* R/W BCD Hour Register */ -#define BCD_DAY 0x7C /* R/W BCD value for a day of the month (1-31) */ -#define BCD_WEEKDAY 0x80 /* R/W BCD value for a day of the week (1-7) */ -#define BCD_MON 0x84 /* R/W BCD Month Register */ -#define BCD_YEAR 0x88 /* R/W BCD Year Register */ -#define CUR_TIC_CNT 0x90 /* R Current Tick Time Counter Register */ - -/* Bit mapping for INT_PEND register */ - -#define INT_ALM 0x02 /* Alarm interrupt pending bit */ -#define INT_TIC 0x01 /* Time TIC interrupt pending bit */ - -/* Bit mapping for RTC_CON register */ - -#define TIC_EN 0x100 /* Tick timer enable */ -#define TIC_CK_SEL_SHIFT (4)/* Tick timer sub clock selection */ -#define CLK_RST 0x08 /* RTC clock count reset */ -#define CNT_SEL 0x04 /* BCD count select */ -#define CLK_SEL 0x02 /* BCD clock select */ -#define RTC_EN 0x01 /* RTC control enable */ - -/* Bit mapping for RTC_ALM register */ - -#define ALM_EN 0x40 /* Alarm global enable */ -#define YEAR_EN 0x20 /* Year alarm enable */ -#define MON_EN 0x10 /* Month alarm enable */ -#define DAY_EN 0x08 /* Day of the month alarm enable */ -#define HOUR_EN 0x04 /* Hour alarm enable */ -#define MIN_EN 0x02 /* Minute alarm enable */ -#define SEC_EN 0x01 /* Second alarm enable */ - -#define S5PC1XX_RTC_REG_MEM_SIZE 0x94 - - -typedef struct S5pc1xxRTCState { - SysBusDevice busdev; - - uint32_t regs[BCD_YEAR + 1]; - - /* periodic timer */ - QEMUTimer *periodic_timer; - uint32_t freq_out; - uint64_t last_tick; - uint64_t cur_tic_cnt; - qemu_irq tick_irq; - - /* second update */ - QEMUTimer *second_timer; - struct tm current_tm; - qemu_irq alm_irq; - -} S5pc1xxRTCState; - - -static void s5pc1xx_rtc_periodic_tick(void *opaque); -static void s5pc1xx_rtc_second_update(void *opaque); - -static void s5pc1xx_rtc_set_time(S5pc1xxRTCState *s) -{ - struct tm *tm = &(s->current_tm); - - tm->tm_sec = from_bcd(s->regs[BCD_SEC] & 0x7F); - tm->tm_min = from_bcd(s->regs[BCD_MIN] & 0x7F); - tm->tm_hour = from_bcd(s->regs[BCD_HOUR] & 0x3F); - tm->tm_wday = from_bcd(s->regs[BCD_WEEKDAY] & 0x07); - tm->tm_mday = from_bcd(s->regs[BCD_DAY] & 0x3F); - /* month value in qemu is between 0 and 11 */ - tm->tm_mon = from_bcd(s->regs[BCD_MON] & 0x1F) - 1; - /* year value is with base_year = 2000 (not 1900 as in qemu) */ - tm->tm_year = 100 + from_bcd(s->regs[BCD_YEAR] & 0xFF) + - from_bcd((s->regs[BCD_YEAR] >> 8) & 0xF) * 100; -} - -static void s5pc1xx_rtc_read_time(S5pc1xxRTCState *s) -{ - const struct tm *tm = &(s->current_tm); - - s->regs[BCD_SEC] = to_bcd(tm->tm_sec); - s->regs[BCD_MIN] = to_bcd(tm->tm_min); - s->regs[BCD_HOUR] = to_bcd(tm->tm_hour); - s->regs[BCD_WEEKDAY] = to_bcd(tm->tm_wday); - s->regs[BCD_DAY] = to_bcd(tm->tm_mday); - /* month value in qemu is between 0 and 11 */ - s->regs[BCD_MON] = to_bcd(tm->tm_mon + 1); - /* year value is with base_year = 2000 (not 1900 as in qemu) */ - s->regs[BCD_YEAR] = to_bcd((tm->tm_year - 100) % 100) | - (to_bcd((tm->tm_year - 100) % 1000 / 100) << 8); -} - -/* set default values for all fields */ -static void s5pc1xx_rtc_reset(S5pc1xxRTCState *s) -{ - short i; - - /* stop tick timer */ - s->regs[RTC_CON] &= ~TIC_EN; - s5pc1xx_rtc_periodic_tick(s); - - /* stop second timer */ - s->regs[RTC_CON] &= ~RTC_EN; - s5pc1xx_rtc_second_update(s); - - for (i = 0x30; i < 0x90; i += 0x4) { - s->regs[i] = 0; - } - - s->last_tick = 0; - s->freq_out = 0; -} - -/* Setup next timer tick */ -static void s5pc1xx_rtc_periodic_update(S5pc1xxRTCState *s) -{ - uint64_t next_periodic_time, last = qemu_get_clock(vm_clock); - s->last_tick = last; - next_periodic_time = - last + muldiv64(s->regs[TIC_CNT], get_ticks_per_sec(), s->freq_out); - qemu_mod_timer(s->periodic_timer, next_periodic_time); -} - -/* Send periodic interrupt */ -static void s5pc1xx_rtc_periodic_tick(void *opaque) -{ - S5pc1xxRTCState *s = (S5pc1xxRTCState *)opaque; - - /* tick actually happens not every CUR_TIC_CNT but rather at irq time; - * if current ticnto value is needed it is calculated in s5pc1xx_rtc_read */ - if (s->regs[RTC_CON] & TIC_EN) { - qemu_irq_raise(s->tick_irq); - s->regs[INT_PEND] |= INT_TIC; - s5pc1xx_rtc_periodic_update(s); - } else { - s->last_tick = 0; - qemu_del_timer(s->periodic_timer); - } -} - -/* Update tick timer frequency */ -static void s5pc1xx_rtc_periodic_rate(S5pc1xxRTCState *s) -{ - short freq_code; - - /* get four binary digits to determine the frequency */ - freq_code = (s->regs[RTC_CON] >> TIC_CK_SEL_SHIFT) & 0xF; - - /* tick timer frequency */ - s->freq_out = 32768 / (1 << freq_code); -} - -/* Month is between 0 and 11 */ -static int get_days_in_month(int month, int year) -{ - short d; - static const int days_tab[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - - if ((unsigned) month >= 12) { - return 31; - } - d = days_tab[month]; - if (month == 1) { - if ((year % 4) == 0) { - d++; - } - } - return d; -} - -/* Update 'tm' to the next second */ -static void s5pc1xx_rtc_next_second(struct tm *tm) -{ - int days_in_month; - - tm->tm_sec++; - if ((unsigned) tm->tm_sec >= 60) { - tm->tm_sec = 0; - tm->tm_min++; - if ((unsigned) tm->tm_min >= 60) { - tm->tm_min = 0; - tm->tm_hour++; - if ((unsigned) tm->tm_hour >= 24) { - tm->tm_hour = 0; - /* next day */ - tm->tm_wday++; - /* TODO: check if wday value in qemu is between 1 and 7 */ - if ((unsigned) tm->tm_wday >= 8) { - tm->tm_wday = 1; - } - days_in_month = get_days_in_month(tm->tm_mon, tm->tm_year); - tm->tm_mday++; - if (tm->tm_mday < 1) { - tm->tm_mday = 1; - } else if (tm->tm_mday > days_in_month) { - tm->tm_mday = 1; - tm->tm_mon++; - if (tm->tm_mon >= 12) { - tm->tm_mon = 0; - tm->tm_year++; - } - } - } - } - } -} - -/* Working with up-to-date time and check alarm */ -static void s5pc1xx_rtc_second_update(void *opaque) -{ - S5pc1xxRTCState *s = (S5pc1xxRTCState *)opaque; - uint64_t next_second_time; - - if (s->regs[RTC_CON] & RTC_EN) { - /* check if the alarm is generally enabled */ - /* then check if an alarm of at least one kind is enabled */ - if (s->regs[RTC_ALM] & ALM_EN && - (s->regs[RTC_ALM] & SEC_EN || - s->regs[RTC_ALM] & MIN_EN || - s->regs[RTC_ALM] & HOUR_EN || - s->regs[RTC_ALM] & DAY_EN || - s->regs[RTC_ALM] & MON_EN || - s->regs[RTC_ALM] & YEAR_EN)) { - - /* check alarm values together with corresponding permissive bits */ - if (((s->regs[ALM_SEC] & 0x7F) == - to_bcd(s->current_tm.tm_sec) || - !(s->regs[RTC_ALM] & SEC_EN)) && - - ((s->regs[ALM_MIN] & 0x7F) == - to_bcd(s->current_tm.tm_min) || - !(s->regs[RTC_ALM] & MIN_EN)) && - - ((s->regs[ALM_HOUR] & 0x3F) == - to_bcd(s->current_tm.tm_hour) || - !(s->regs[RTC_ALM] & HOUR_EN)) && - - ((s->regs[ALM_DAY] & 0x3F) == - to_bcd(s->current_tm.tm_mday) || - !(s->regs[RTC_ALM] & DAY_EN)) && - - ((s->regs[ALM_MON] & 0x1F) == - to_bcd(s->current_tm.tm_mon) || - !(s->regs[RTC_ALM] & MON_EN)) && - - (((s->regs[ALM_YEAR] & 0xFF) == - to_bcd((s->current_tm.tm_year - 100) % 100) && - ((s->regs[ALM_YEAR] >> 8) & 0xF) == - to_bcd((s->current_tm.tm_year - 100) % 1000 / 100)) || - !(s->regs[RTC_ALM] & YEAR_EN))) { - - qemu_irq_raise(s->alm_irq); - s->regs[INT_PEND] |= INT_ALM; - } - } - - s5pc1xx_rtc_next_second(&s->current_tm); - next_second_time = qemu_get_clock(vm_clock) + get_ticks_per_sec(); - qemu_mod_timer(s->second_timer, next_second_time); - } else { - qemu_del_timer(s->second_timer); - } -} - -static uint32_t s5pc1xx_rtc_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxRTCState *s = (S5pc1xxRTCState *)opaque; - - switch (offset) { - case BCD_SEC: - case BCD_MIN: - case BCD_HOUR: - case BCD_WEEKDAY: - case BCD_DAY: - case BCD_MON: - case BCD_YEAR: - s5pc1xx_rtc_read_time(s); - /* fallthrough */ - case INT_PEND: - case RTC_CON: - case TIC_CNT: - case RTC_ALM: - case ALM_SEC: - case ALM_MIN: - case ALM_HOUR: - case ALM_DAY: - case ALM_MON: - case ALM_YEAR: - return s->regs[offset]; - case CUR_TIC_CNT: - if (s->freq_out && s->last_tick && s->regs[TIC_CNT]) { - s->cur_tic_cnt = s->regs[TIC_CNT] - - muldiv64(qemu_get_clock(vm_clock) - s->last_tick, - s->freq_out, get_ticks_per_sec()) % - s->regs[TIC_CNT]; - } else { - s->cur_tic_cnt = 0; - } - - return s->cur_tic_cnt; - default: - hw_error("s5pc1xx.rtc: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static void s5pc1xx_rtc_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxRTCState *s = (S5pc1xxRTCState *)opaque; - - switch (offset) { - case INT_PEND: - /* lower interrupts if any */ - if (value & INT_TIC) { - qemu_irq_lower(s->tick_irq); - } - if (value & INT_ALM) { - qemu_irq_lower(s->alm_irq); - } - - /* clear INT_* bits if they are set in value */ - s->regs[INT_PEND] &= ~(value & (INT_TIC | INT_ALM)); - break; - case RTC_CON: - /* reset tick counter */ - if (value & CLK_RST) { - s5pc1xx_rtc_reset(s); - value &= ~CLK_RST; - } - /* start second timer */ - if ((value & RTC_EN) > (s->regs[RTC_CON] & RTC_EN)) { - s->regs[RTC_CON] |= RTC_EN; - qemu_get_timedate(&s->current_tm, 0); - s5pc1xx_rtc_second_update(s); - } - /* start tick timer */ - if ((value & TIC_EN) > (s->regs[RTC_CON] & TIC_EN)) { - s->regs[RTC_CON] = value; - s5pc1xx_rtc_periodic_rate(s); - s5pc1xx_rtc_periodic_update(s); - break; - } else if ((value & TIC_EN) < (s->regs[RTC_CON] & TIC_EN)) { - qemu_del_timer(s->periodic_timer); - } - s->regs[RTC_CON] = value; - s5pc1xx_rtc_periodic_rate(s); - break; - case TIC_CNT: - case RTC_ALM: - case ALM_SEC: - case ALM_MIN: - case ALM_HOUR: - case ALM_DAY: - case ALM_MON: - case ALM_YEAR: - s->regs[offset] = value; - break; - case BCD_SEC: - case BCD_MIN: - case BCD_HOUR: - case BCD_WEEKDAY: - case BCD_DAY: - case BCD_MON: - case BCD_YEAR: - s->regs[offset] = value; - /* if in disabled mode, do not update the time */ - if (s->regs[RTC_CON] & RTC_EN) { - s5pc1xx_rtc_set_time(s); - } - break; - default: - hw_error("s5pc1xx.rtc: bad write offset " TARGET_FMT_plx "\n", - offset); - } -} - -/* Memory mapped interface */ -static CPUReadMemoryFunc * const s5pc1xx_rtc_mm_read[] = { - s5pc1xx_rtc_read, - s5pc1xx_rtc_read, - s5pc1xx_rtc_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_rtc_mm_write[] = { - s5pc1xx_rtc_write, - s5pc1xx_rtc_write, - s5pc1xx_rtc_write -}; - -static void s5pc1xx_rtc_save(QEMUFile *f, void *opaque) -{ - S5pc1xxRTCState *s = (S5pc1xxRTCState *)opaque; - int i; - - s5pc1xx_rtc_read_time(s); - for (i = INT_PEND; i <= BCD_YEAR; i++) { - qemu_put_be32s(f, &s->regs[i]); - } - qemu_put_timer(f, s->second_timer); - - qemu_put_be64s(f, &s->last_tick); - qemu_put_be32s(f, &s->freq_out); - qemu_put_timer(f, s->periodic_timer); -} - -static int s5pc1xx_rtc_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxRTCState *s = (S5pc1xxRTCState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - for (i = INT_PEND; i <= BCD_YEAR; i++) { - qemu_get_be32s(f, &s->regs[i]); - } - - //s5pc1xx_rtc_set_time(s); - qemu_get_timedate(&s->current_tm, 0); - s5pc1xx_rtc_read_time(s); - qemu_get_timer(f, s->second_timer); - - qemu_get_be64s(f, &s->last_tick); - qemu_get_be32s(f, &s->freq_out); - qemu_get_timer(f, s->periodic_timer); - - return 0; -} - -/* initialize and start timers */ -static int s5pc1xx_rtc_init(SysBusDevice *dev) -{ - int iomemory; - S5pc1xxRTCState *s = FROM_SYSBUS(S5pc1xxRTCState, dev); - - sysbus_init_irq(dev, &s->alm_irq); - sysbus_init_irq(dev, &s->tick_irq); - - s->periodic_timer = - qemu_new_timer(vm_clock, s5pc1xx_rtc_periodic_tick, s); - s->second_timer = - qemu_new_timer(vm_clock, s5pc1xx_rtc_second_update, s); - - iomemory = - cpu_register_io_memory(s5pc1xx_rtc_mm_read, s5pc1xx_rtc_mm_write, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_RTC_REG_MEM_SIZE, iomemory); - - s5pc1xx_rtc_reset(s); - - register_savevm(&dev->qdev, "s5pc1xx.rtc", -1, 1, - s5pc1xx_rtc_save, s5pc1xx_rtc_load, s); - - return 0; -} - -static void s5pc1xx_rtc_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.rtc", sizeof(S5pc1xxRTCState), - s5pc1xx_rtc_init); -} - -device_init(s5pc1xx_rtc_register_devices) diff --git a/hw/s5pc1xx_spdif.c b/hw/s5pc1xx_spdif.c deleted file mode 100644 index 24cfb97..0000000 --- a/hw/s5pc1xx_spdif.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * SPDIF transmitter for S5PC110-based board emulation - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "s5pc1xx.h" -#include "qemu-timer.h" -#include "s5pc1xx_gpio_regs.h" -#include "sysbus.h" - -#define ALL_BITS(b,a) (((1 << (b - a + 1)) - 1) << a) - -/* R/W Specifies the Clock control register 0x0000_0002 */ -#define SPDCLKCON 0x00 - - #define MAIN_CLK_SEL (1 << 2) - #define CLK_DWN_READY (1 << 1) - #define POWER_ON (1 << 0) - -/* R/W Specifies the Control register 0x0000_0000 */ -#define SPDCON 0x04 - - #define FIFO_LEVEL_SHIFT 22 /* 5 bits */ - #define FIFO_LEVEL_THR_SHIFT 19 /* 3 bits */ - #define FIFO_TRANSFER_MODE_SHIFT 17 /* 2 bits */ - #define FIFO_LEVEL_INT_ST (1 << 16) - #define FIFO_LEVEL_INT_EN (1 << 15) - #define ENDIAN_FORMAT_SHIFT 13 /* 2 bits */ - #define USER_DATA_ATTACH (1 << 12) - #define USER_DATA_INT_ST (1 << 11) - #define USER_DATA_INT_EN (1 << 10) - #define BUF_EMPTY_INT_ST (1 << 9) - #define BUF_EMPTY_INT_EN (1 << 8) - #define STREAM_END_INT_ST (1 << 7) - #define STREAM_END_INT_EN (1 << 6) - #define SOFTWARE_RESET (1 << 5) - #define MAIN_CLK_FREQ_SHIFT 3 /* 2 bits */ - #define PCM_DATA_SIZE_SHIFT 1 /* 2 bits */ - /* TODO: Stream data coding is not described in the documentation. - * So, this is not implemented so far. */ - #define PCM_OR_STREAM (1 << 0) - -/* R/W Specifies the Burst status register 0x0000_0000 */ -#define SPDBSTAS 0x08 - - #define BURST_DATA_L_BIT_SHIFT 16 /* 16 bits */ - #define BITSTREAM_NUMBER_SHIFT 13 /* 3 bits */ - #define DATA_TYPE_DEP_INFO_SHIFT 8 /* 5 bits */ - #define ERROR_FLAG (1 << 7) - #define COMPR_DATA_TYPE_SHIFT 0 /* 5 bits */ - -/* R/W Specifies the Channel status register 0x0000_0000 */ -#define SPDCSTAS 0x0C - - #define CLK_ACCURACY_SHIFT 28 /* 2 bits */ - #define SAMP_FREQ_SHIFT 24 /* 4 bits */ - #define CH_NUM_SHIFT 20 /* 4 bits */ - #define SRC_NUM_SHIFT 16 /* 4 bits */ - #define CAT_CODE_SHIFT 8 /* 8 bits */ - #define CH_STAT_MODE_SHIFT 6 /* 2 bits */ - #define EMPHASIS_SHIFT 3 /* 3 bits */ - #define COPYRIGHT_ASSERTION (1 << 2) - #define AUDIO_WORD (1 << 1) - #define CH_STAT_BLOCK (1 << 0) - -/* W Specifies the SPDIFOUT data buffer 0x0000_0000 */ -#define SPDDAT 0x10 - -/* R/W Specifies the Repetition count register 0x0000_0000 */ -#define SPDCNT 0x14 - -/* R Specifies the Shadowed Burst Status Register 0x0000_0000 */ -#define SPDBSTAS_SHD 0x18 - -/* R Specifies the Shadowed Repetition Count Register 0x0000_0000 */ -#define SPDCNT_SHD 0x1C - -/* R/W Specifies the Subcode Q1 ~ Q32 0x0000_0000 */ -#define USERBIT1 0x20 - -/* R/W Specifies the Subcode Q33 ~ Q64 0x0000_0000 */ -#define USERBIT2 0x24 - -/* R/W Specifies the Subcode Q65 ~ Q96 0x0000_0000 */ -#define USERBIT3 0x28 - -/* R Specifies the Shadowed Register Userbit1 0x0000_0000 */ -#define USERBIT1_SHD 0x2C - -/* R Specifies the Shadowed Register Userbit2 0x0000_0000 */ -#define USERBIT2_SHD 0x30 - -/* R Specifies the Shadowed Register Userbit3 0x0000_0000 */ -#define USERBIT3_SHD 0x34 - -/* R Specifies the RTL Version Information 0x0000_000C */ -#define VERSION_INFO 0x38 - -#define S5PC1XX_SPDIF_REG_MEM_SIZE 0x3C - -#define M_PREAMBLE 1 -#define B_PREAMBLE 2 -#define W_PREAMBLE 3 - -#define FIFO_DEPTH (s->write_idx - s->read_idx) -#define INT_EN(stat) (stat >> 1) -#define ALL_STAT (STREAM_END_INT_ST | BUF_EMPTY_INT_ST | \ - USER_DATA_INT_ST | FIFO_LEVEL_INT_ST) - - -typedef struct S5pc1xxSpdifState { - SysBusDevice busdev; - qemu_irq irq; - - uint32_t spdclkcon; - uint32_t spdcon; - uint32_t spdbstas; - uint32_t spdcstas; - uint32_t spdcnt; - uint32_t userbit[3]; - uint32_t version_info; - - struct shadowed_regs { - uint32_t spdbstas; - uint32_t spdcnt; - uint32_t userbit[3]; - } shd; - - QEMUTimer *spdif_timer; - uint32_t sclk_freq; - int64_t count; /* has signed type */ - uint8_t updated; - - uint32_t fifo[2][16]; - uint64_t read_idx, write_idx; - uint8_t read_ch, write_ch; - - uint32_t sub_frame; - int8_t fifo_thr, endian_f; /* have signed type */ - int16_t Pa, Pb, Pc, Pd; /* have signed type */ - uint8_t lsb_pos, non_linear_pcm, stat_bit[16]; - uint8_t first_state, second_state; - uint16_t rep_period, data_sframe_num; -} S5pc1xxSpdifState; - - -/* Reset SPDIF */ -static void s5pc1xx_spdif_reset(void *opaque) -{ - S5pc1xxSpdifState *s = (S5pc1xxSpdifState *)opaque; - uint8_t i; - - s->spdclkcon = 0x2; - s->spdcon = 0x1; - s->spdbstas = 0; - s->spdcstas = 0; - s->spdcnt = 0; - s->shd.spdbstas = 0; - s->shd.spdcnt = 0; - s->version_info = 0xC; - - for (i = 0; i < 3; i++) { - s->userbit[i] = 0; - s->shd.userbit[i] = 0; - } - - s->sclk_freq = 0; - s->count = -1; - - s->read_idx = 0; - s->write_idx = 0; - s->read_ch = 0; - s->write_ch = 0; - - s->fifo_thr = -1; - s->endian_f = -1; - s->lsb_pos = 0; - s->first_state = 0; - s->second_state = 0; - - s->Pa = 0xF872; - s->Pb = 0x4E1F; - s->Pc = -1; - s->Pd = -1; - s->data_sframe_num = 0; /* used for non-linear PCM */ -} - -/* Interrupts handler */ -static void s5pc1xx_spdif_irq(S5pc1xxSpdifState *s, - uint32_t stat, uint8_t to_clear) -{ - if (to_clear) { - s->spdcon &= ~(stat); - if (!(s->spdcon & ALL_STAT)) /* if all clear */ - qemu_irq_lower(s->irq); - } else { - s->spdcon |= stat; - if (s->spdcon & INT_EN(stat)) /* if enabled */ - qemu_irq_raise(s->irq); - } -} - -/* -=FIFO HANDLING=- */ - -/* Determine threshold FIFO depth */ -static void s5pc1xx_spdif_fifo_thr(S5pc1xxSpdifState *s) -{ - uint8_t thr[8] = {0, 1, 4, 6, 10, 12, 14, 15}; - uint8_t thr_idx = (s->spdcon >> FIFO_LEVEL_THR_SHIFT) & 0x7; - - s->fifo_thr = thr[thr_idx]; -} - -/* Control FIFO level */ -static void s5pc1xx_spdif_fifo_control(S5pc1xxSpdifState *s) -{ - if (s->fifo_thr < 0) - s5pc1xx_spdif_fifo_thr(s); - - if (FIFO_DEPTH > s->fifo_thr) - s5pc1xx_spdif_irq(s, FIFO_LEVEL_INT_ST, 0); - - if (FIFO_DEPTH == 0) - s5pc1xx_spdif_irq(s, BUF_EMPTY_INT_ST, 0); -} - -/* Determine endian format index */ -static void s5pc1xx_spdif_endian_idx(S5pc1xxSpdifState *s) -{ - s->endian_f = (s->spdcon >> ENDIAN_FORMAT_SHIFT) & 0x3; -} - -/* Convert value according to current endian format */ -static uint32_t s5pc1xx_spdif_endian_format(S5pc1xxSpdifState *s, - uint32_t value) -{ - uint32_t ret_val = 0; - - if (s->endian_f < 0) - s5pc1xx_spdif_endian_idx(s); - - switch(s->endian_f) { - case 0: - ret_val = value & ALL_BITS(23, 0); - break; - case 1: - ret_val = (((value & ALL_BITS(15, 8)) << 8) | - ((value & ALL_BITS(23, 16)) >> 8) | - ((value & ALL_BITS(31, 24)) >> 24)); - break; - case 2: - ret_val = (((value & ALL_BITS( 7, 0)) << 16) | - ((value & ALL_BITS(15, 8)) >> 0) | - ((value & ALL_BITS(23, 16)) >> 16)); - break; - case 3: - ret_val = (((value & ALL_BITS( 7, 0)) << 8) | - ((value & ALL_BITS(15, 8)) >> 8)); - break; - } - return ret_val; -} - -/* Get value from FIFO */ -static uint32_t s5pc1xx_spdif_fifo_read(S5pc1xxSpdifState *s) -{ - uint32_t ret_val = 0; - - if (FIFO_DEPTH > 0) { - ret_val = s->fifo[s->read_ch][s->read_idx % 16]; - - if (s->read_ch == 1) - s->read_idx++; - } - s->read_ch = (s->read_ch + 1) % 2; - s5pc1xx_spdif_fifo_control(s); - - return ret_val; -} - -/* Put value into FIFO */ -static void s5pc1xx_spdif_fifo_write(S5pc1xxSpdifState *s, uint32_t value) -{ - value = s5pc1xx_spdif_endian_format(s, value); - - if (FIFO_DEPTH < 16) { - s->fifo[s->write_ch][s->write_idx % 16] = value; - - if (s->write_ch == 1) - s->write_idx++; - } - s->write_ch = (s->write_ch + 1) % 2; - s5pc1xx_spdif_fifo_control(s); -} - -/* -=SPDIF MAIN LOGIC=- */ - -/* Update burst params (for non-linear PCM) */ -static void s5pc1xx_spdif_stream_end(S5pc1xxSpdifState *s) -{ - s->shd.spdbstas = s->spdbstas; - s->shd.spdcnt = s->spdcnt; - - s->Pc = (s->shd.spdbstas >> 0) & ALL_BITS(15, 0); - s->Pd = (s->shd.spdbstas >> 16) & ALL_BITS(15, 0); - s->rep_period = (s->shd.spdcnt) & ALL_BITS(12, 0); - - s5pc1xx_spdif_irq(s, STREAM_END_INT_ST, 0); -} - -/* Spdif_tx block */ -static uint32_t s5pc1xx_spdif_tx_block(S5pc1xxSpdifState *s) -{ - uint32_t value; - uint16_t next_payload_size; - - /* check for beginning of new payload frame */ - if ((s->data_sframe_num > 3) && !(s->data_sframe_num % 2)) { - /* check if bit stream size will be past s->rep_period - * value after next write routine and avoid this */ - if ((s->data_sframe_num + 2) * 16 > s->rep_period) { - s5pc1xx_spdif_stream_end(s); - s->data_sframe_num = 0; - } - } - - next_payload_size = - (s->data_sframe_num > 3) ? (s->data_sframe_num - 4 + 2) * 16 : 0; - - switch(s->data_sframe_num) { - case 0: - value = s->Pa; - break; - case 1: - value = s->Pb; - break; - case 2: - value = s->Pc; - break; - case 3: - value = s->Pd; - break; - default: - if (next_payload_size > s->Pd) { - value = 0; - } else { - value = s5pc1xx_spdif_fifo_read(s); - } - } - s->data_sframe_num++; - - return value; -} - -/* Determine LSB position within sub-frame */ -static void s5pc1xx_spdif_lsb(S5pc1xxSpdifState *s) -{ - uint8_t data_size; - - if (s->non_linear_pcm) { - s->lsb_pos = 12; - return; - } - data_size = (((s->spdcon >> PCM_DATA_SIZE_SHIFT) & 0x3) + 4) << 2; - s->lsb_pos = 28 - data_size; -} - -/* Convert audio data to SPDIF format - * (compose 0~31 time slots into s->sub_frame) */ -static void s5pc1xx_spdif_sub_frame(S5pc1xxSpdifState *s) -{ - uint32_t value; - uint8_t ballast, preamble, v_flag, user_bit, parity_bit; - uint8_t i, ones; - uint16_t carrier_sframe_num = (s->count / 64) % 384; - - ballast = (s->second_state) ? 0 : 0x3; /* 2b'00 or 2b'11 */ - - /* Determine preamble */ - if (carrier_sframe_num % 2) { - /* channel 2 has odd sub-frames numbers and always has W-preamble */ - preamble = W_PREAMBLE; - } else { - /* channel 1 has even sub-frames numbers and has M-preamble except - * the first sub-frame */ - if (carrier_sframe_num) { - preamble = M_PREAMBLE; - } else { - preamble = B_PREAMBLE; - } - } - - /* Determine audio sample word */ - if (s->non_linear_pcm) { - value = s5pc1xx_spdif_tx_block(s); - } else { - value = s5pc1xx_spdif_fifo_read(s); - } - - /* Validity flag, user bit and channel status */ - v_flag = (value) ? 0 : 1; - /* TODO: User bit is always 0 for linear-PCM, but PCM user data is set - * for non-linear PCM in the registers USERBIT1~3(_SHD). The allocation - * of user data between two channels is unclear in the documentation. - * So, user data transmission is not inplemented so far. */ - user_bit = 0; - - /* Compose sub_frame without parity_bit */ - if (!(s->lsb_pos)) - s5pc1xx_spdif_lsb(s); - - s->sub_frame = ballast | (preamble << 2) | - (value << s->lsb_pos & ALL_BITS(27, s->lsb_pos)) | - (v_flag << 28) | (user_bit << 29) | - (s->stat_bit[carrier_sframe_num % 2] << 30); - - /* Determine parity_bit */ - ones = parity_bit = 0; - for (i = 4; i < 31; i++) { - if (s->sub_frame >> i & 0x1) - ones++; - } - if (ones % 2) - parity_bit = 1; - - s->sub_frame |= (parity_bit << 31); -} - -/* Channel coding of source signal */ -static void s5pc1xx_spdif_channel_coding(S5pc1xxSpdifState *s) -{ - uint8_t cur_pos = (s->count % 64) / 2; - uint8_t source_coding = s->sub_frame >> cur_pos & 0x1; - - /* Ballast handling (ballast ensures one deference - * from bi-phase scheme in channel coded preamble) */ - if (cur_pos < 2) { - s->first_state = s->second_state = source_coding; - return; - } - - /* Preamble and data handling */ - if (cur_pos < 3) { - /* the line below ensures one more deference - * from bi-phase scheme in channel coded preamble */ - s->first_state = s->second_state; - } else { - s->first_state = !(s->second_state); - } - - if (source_coding) { - s->second_state = !(s->first_state); - } else { - s->second_state = s->first_state; - } -} - -/* -=TIMER HANDLING=- */ - -/* Update timer frequency */ -static void s5pc1xx_spdif_sclk_update(S5pc1xxSpdifState *s) -{ - uint8_t freq_id = s->spdcstas >> SAMP_FREQ_SHIFT & 0xF; - - switch (freq_id) { - case 0: - /* samplling_freq x 32 time slots x 2 channels x bi-phase mark */ - s->sclk_freq = 44100 * 32 * 2 * 2; - break; - case 2: - s->sclk_freq = 48000 * 32 * 2 * 2; - break; - case 3: - s->sclk_freq = 32000 * 32 * 2 * 2; - break; - case 10: - s->sclk_freq = 96000 * 32 * 2 * 2; - break; - default: - hw_error("s5pc1xx.spdif: frequency id %u is not supported\n", freq_id); - } -} - -/* Sync timer engine */ -static void s5pc1xx_spdif_sync(void *opaque) -{ - S5pc1xxSpdifState *s = (S5pc1xxSpdifState *)opaque; - uint64_t next_spdif_time; - - if (s->spdclkcon & POWER_ON) { - if (!(s->sclk_freq)) - s5pc1xx_spdif_sclk_update(s); - - /* s->updated is used to avoid conflict between two functions - * in case of synchronous runs */ - s->updated = 0; - - s->count++; - - if (!(s->count % 64)) - s5pc1xx_spdif_sub_frame(s); - - if (!(s->count % 2)) - s5pc1xx_spdif_channel_coding(s); - - s->updated = 1; - - next_spdif_time = qemu_get_clock(vm_clock) + - muldiv64(1, get_ticks_per_sec(), s->sclk_freq); - qemu_mod_timer(s->spdif_timer, next_spdif_time); - } else { - s->spdclkcon |= CLK_DWN_READY; - qemu_del_timer(s->spdif_timer); - } -} - -/* -=RELATION WITH GPIO AND OS=- */ - -/* Read SPDIF by GPIO */ -static uint32_t s5pc1xx_spdif_gpio_read(void *opaque, int io_index) -{ - S5pc1xxSpdifState *s = (S5pc1xxSpdifState *)opaque; - - if (io_index == SPDIF_0_OUT) { - if (s->count % 2) { - return s->second_state; - } else { - if (s->updated) { - return s->first_state; - } else { - return s->second_state; - } - } - } - return 0; -} - -static GPIOReadMemoryFunc *s5pc1xx_spdif_gpio_readfn = s5pc1xx_spdif_gpio_read; -static GPIOWriteMemoryFunc *s5pc1xx_spdif_gpio_writefn = s5pc1xx_empty_gpio_write; - -/* Read SPDIF by OS */ -static uint32_t s5pc1xx_spdif_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxSpdifState *s = (S5pc1xxSpdifState *)opaque; - - switch(offset) { - case SPDCLKCON: - return s->spdclkcon; - case SPDCON: - s->spdcon = ((FIFO_DEPTH << FIFO_LEVEL_SHIFT) & ALL_BITS(26, 22)) | - (s->spdcon & ALL_BITS(21 ,0)); - return s->spdcon; - case SPDBSTAS: - return s->spdbstas; - case SPDCSTAS: - return s->spdcstas; - case SPDCNT: - return s->spdcnt; - case SPDBSTAS_SHD: - return s->shd.spdbstas; - case SPDCNT_SHD: - return s->shd.spdcnt; - case USERBIT1 ... USERBIT3: - return s->userbit[(offset - USERBIT1) / (USERBIT2 - USERBIT1)]; - case USERBIT1_SHD ... USERBIT3_SHD: - return s->shd.userbit[(offset - USERBIT1_SHD) / - (USERBIT2_SHD - USERBIT1_SHD)]; - case VERSION_INFO: - return s->version_info; - default: - hw_error("s5pc1xx.spdif: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -/* Write SPDIF by OS */ -static void s5pc1xx_spdif_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - uint32_t old_val; - S5pc1xxSpdifState *s = (S5pc1xxSpdifState *)opaque; - - switch(offset) { - case SPDCLKCON: - old_val = s->spdclkcon; - - /* Note: the CLK_DWN_READY field is read-only */ - s->spdclkcon = - (value & (POWER_ON | MAIN_CLK_SEL)) | (old_val & CLK_DWN_READY); - - if ((value & POWER_ON) > (old_val & POWER_ON)) { - s5pc1xx_spdif_stream_end(s); - s5pc1xx_spdif_sync(s); - s->spdclkcon &= ~CLK_DWN_READY; - } - break; - case SPDCON: - old_val = s->spdcon; - - /* Note: the 'FIFO level' field is read-only */ - s->spdcon = (old_val & ALL_BITS(26, 22)) | (value & ALL_BITS(21, 0)); - - /* Check 'FIFO level threshold' field for update */ - if ((value & ALL_BITS(21, 19)) != (old_val & ALL_BITS(21, 19))) - s5pc1xx_spdif_fifo_thr(s); - - /* Check 'Endian format' field for update */ - if ((value & ALL_BITS(14, 13)) != (old_val & ALL_BITS(14, 13))) - s5pc1xx_spdif_endian_idx(s); - - /* Check 'PCM data size' field for update */ - if ((value & ALL_BITS(2, 1)) != (old_val & ALL_BITS(2, 1))) - s5pc1xx_spdif_lsb(s); - - /* Clear irq states if any */ - if (value & ALL_STAT) - s5pc1xx_spdif_irq(s, (value & ALL_STAT), 1); - - break; - case SPDBSTAS: - s->spdbstas = value; - break; - case SPDCSTAS: - old_val = s->spdcstas; - s->spdcstas = value; - - /* Check 'Sampling frequency' field for update */ - if ((value & ALL_BITS(27, 24)) != (old_val & ALL_BITS(27, 24))) - s5pc1xx_spdif_sclk_update(s); - - s->stat_bit[(value >> CH_NUM_SHIFT) & ALL_BITS(3, 0)] = value & 0x1; - - s->non_linear_pcm = (value & AUDIO_WORD) ? 1 : 0; - - break; - case SPDCNT: - s->spdcnt = value; - break; - case SPDDAT: - s5pc1xx_spdif_fifo_write(s, value); - break; - case USERBIT1 ... USERBIT3: - s->userbit[(offset - USERBIT1) / (USERBIT2 - USERBIT1)] = value; - break; - default: - hw_error("s5pc1xx.spdif: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_spdif_readfn[] = { - s5pc1xx_spdif_read, - s5pc1xx_spdif_read, - s5pc1xx_spdif_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_spdif_writefn[] = { - s5pc1xx_spdif_write, - s5pc1xx_spdif_write, - s5pc1xx_spdif_write -}; - -static void s5pc1xx_spdif_save(QEMUFile *f, void *opaque) -{ - S5pc1xxSpdifState *s = (S5pc1xxSpdifState *)opaque; - int i; - - qemu_put_be32s(f, &s->spdclkcon); - qemu_put_be32s(f, &s->spdcon); - qemu_put_be32s(f, &s->spdbstas); - qemu_put_be32s(f, &s->spdcstas); - qemu_put_be32s(f, &s->spdcnt); - qemu_put_be32s(f, &s->version_info); - - for (i = 0; i < 3; i++) { - qemu_put_be32s(f, &s->userbit[i]); - qemu_put_be32s(f, &s->shd.userbit[i]); - } - - qemu_put_be32s(f, &s->shd.spdbstas); - qemu_put_be32s(f, &s->shd.spdcnt); - - qemu_put_be32s (f, &s->sclk_freq); - qemu_put_sbe64s(f, &s->count); - qemu_put_8s (f, &s->updated); - qemu_put_be64s (f, &s->read_idx); - qemu_put_be64s (f, &s->write_idx); - qemu_put_8s (f, &s->read_ch); - qemu_put_8s (f, &s->write_ch); - qemu_put_be32s (f, &s->sub_frame); - qemu_put_s8s (f, &s->fifo_thr); - qemu_put_s8s (f, &s->endian_f); - qemu_put_sbe16s(f, &s->Pa); - qemu_put_sbe16s(f, &s->Pb); - qemu_put_sbe16s(f, &s->Pc); - qemu_put_sbe16s(f, &s->Pd); - - for (i = 0; i < 16; i++) { - qemu_put_be32s(f, &s->fifo[0][i]); - qemu_put_be32s(f, &s->fifo[1][i]); - qemu_put_8s (f, &s->stat_bit[i]); - } - - qemu_put_8s (f, &s->lsb_pos); - qemu_put_8s (f, &s->non_linear_pcm); - qemu_put_8s (f, &s->first_state); - qemu_put_8s (f, &s->second_state); - qemu_put_be16s(f, &s->rep_period); - qemu_put_be16s(f, &s->data_sframe_num); - - qemu_put_timer(f, s->spdif_timer); -} - -static int s5pc1xx_spdif_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxSpdifState *s = (S5pc1xxSpdifState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->spdclkcon); - qemu_get_be32s(f, &s->spdcon); - qemu_get_be32s(f, &s->spdbstas); - qemu_get_be32s(f, &s->spdcstas); - qemu_get_be32s(f, &s->spdcnt); - qemu_get_be32s(f, &s->version_info); - - for (i = 0; i < 3; i++) { - qemu_get_be32s(f, &s->userbit[i]); - qemu_get_be32s(f, &s->shd.userbit[i]); - } - - qemu_get_be32s(f, &s->shd.spdbstas); - qemu_get_be32s(f, &s->shd.spdcnt); - - qemu_get_be32s (f, &s->sclk_freq); - qemu_get_sbe64s(f, &s->count); - qemu_get_8s (f, &s->updated); - qemu_get_be64s (f, &s->read_idx); - qemu_get_be64s (f, &s->write_idx); - qemu_get_8s (f, &s->read_ch); - qemu_get_8s (f, &s->write_ch); - qemu_get_be32s (f, &s->sub_frame); - qemu_get_s8s (f, &s->fifo_thr); - qemu_get_s8s (f, &s->endian_f); - qemu_get_sbe16s(f, &s->Pa); - qemu_get_sbe16s(f, &s->Pb); - qemu_get_sbe16s(f, &s->Pc); - qemu_get_sbe16s(f, &s->Pd); - - for (i = 0; i < 16; i++) { - qemu_get_be32s(f, &s->fifo[0][i]); - qemu_get_be32s(f, &s->fifo[1][i]); - qemu_get_8s (f, &s->stat_bit[i]); - } - - qemu_get_8s (f, &s->lsb_pos); - qemu_get_8s (f, &s->non_linear_pcm); - qemu_get_8s (f, &s->first_state); - qemu_get_8s (f, &s->second_state); - qemu_get_be16s(f, &s->rep_period); - qemu_get_be16s(f, &s->data_sframe_num); - - qemu_get_timer(f, s->spdif_timer); - - return 0; -} - -/* SPDIF initialization */ -static int s5pc1xx_spdif_init(SysBusDevice *dev) -{ - S5pc1xxSpdifState *s = FROM_SYSBUS(S5pc1xxSpdifState, dev); - int iomemtype; - - sysbus_init_irq(dev, &s->irq); - - iomemtype = - cpu_register_io_memory(s5pc1xx_spdif_readfn, s5pc1xx_spdif_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_SPDIF_REG_MEM_SIZE, iomemtype); - - s5pc1xx_gpio_register_io_memory(GPIO_IDX_SPDIF, 0, - s5pc1xx_spdif_gpio_readfn, - s5pc1xx_spdif_gpio_writefn, NULL, s); - - s->spdif_timer = qemu_new_timer(vm_clock, s5pc1xx_spdif_sync, s); - - s5pc1xx_spdif_reset(s); - - qemu_register_reset(s5pc1xx_spdif_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.spdif", -1, 1, - s5pc1xx_spdif_save, s5pc1xx_spdif_load, s); - - return 0; -} - -static void s5pc1xx_spdif_register(void) -{ - sysbus_register_dev("s5pc1xx.spdif", sizeof(S5pc1xxSpdifState), - s5pc1xx_spdif_init); -} - -device_init(s5pc1xx_spdif_register) diff --git a/hw/s5pc1xx_spi.c b/hw/s5pc1xx_spi.c deleted file mode 100644 index 13dfa9e..0000000 --- a/hw/s5pc1xx_spi.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * S5PC1XX SPI Emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Dmitry Zhurikhin - */ - -#include "sysbus.h" - - -#define S5PC1XX_WDT_REG_MEM_SIZE 0x30 - - -typedef struct S5pc1xxSPIState { - SysBusDevice busdev; - - uint32_t ch_cfg; - uint32_t clk_cfg; - uint32_t mode_cfg; - uint32_t cs_reg; - uint32_t spi_int_en; - uint32_t spi_status; - uint32_t spi_tx_dat; - uint32_t spi_rx_dat; - uint32_t packet_cnt_reg; - uint32_t pending_clr_reg; - uint32_t swap_cfg; - uint32_t fb_clk_sel; - - qemu_irq irq; -} S5pc1xxSPIState; - - -static uint32_t s5pc1xx_spi_mm_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxSPIState *s = (S5pc1xxSPIState *)opaque; - - switch (offset) { - case 0x00: - return s->ch_cfg; - case 0x04: - return s->clk_cfg; - case 0x08: - return s->mode_cfg; - case 0x0C: - return s->cs_reg; - case 0x10: - return s->spi_int_en; - case 0x14: - return s->spi_status; - case 0x18: - return s->spi_tx_dat; - case 0x1C: - return s->spi_rx_dat; - case 0x20: - return s->packet_cnt_reg; - case 0x24: - return s->pending_clr_reg; - case 0x28: - return s->swap_cfg; - case 0x2C: - return s->fb_clk_sel; - default: - hw_error("s5pc1x_spi: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static void s5pc1xx_spi_mm_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxSPIState *s = (S5pc1xxSPIState *)opaque; - - switch (offset) { - case 0x00: - s->ch_cfg = val; - break; - case 0x04: - s->clk_cfg = val; - break; - case 0x08: - s->mode_cfg = val; - break; - case 0x0C: - s->cs_reg = val; - break; - case 0x10: - s->spi_int_en = val; - break; - case 0x14: - s->spi_status = val; - break; - case 0x18: - s->spi_tx_dat = val; - break; - case 0x1C: - s->spi_rx_dat = val; - break; - case 0x20: - s->packet_cnt_reg = val; - break; - case 0x24: - s->pending_clr_reg = val; - break; - case 0x28: - s->swap_cfg = val; - break; - case 0x2C: - s->fb_clk_sel = val; - break; - default: - hw_error("s5pc1x_spi: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -CPUReadMemoryFunc * const s5pc1xx_spi_readfn[] = { - s5pc1xx_spi_mm_read, - s5pc1xx_spi_mm_read, - s5pc1xx_spi_mm_read -}; - -CPUWriteMemoryFunc * const s5pc1xx_spi_writefn[] = { - s5pc1xx_spi_mm_write, - s5pc1xx_spi_mm_write, - s5pc1xx_spi_mm_write -}; - -static void s5pc1xx_spi_save(QEMUFile *f, void *opaque) -{ - S5pc1xxSPIState *s = (S5pc1xxSPIState *)opaque; - - qemu_put_be32s(f, &s->ch_cfg); - qemu_put_be32s(f, &s->clk_cfg); - qemu_put_be32s(f, &s->mode_cfg); - qemu_put_be32s(f, &s->cs_reg); - qemu_put_be32s(f, &s->spi_int_en); - qemu_put_be32s(f, &s->spi_status); - qemu_put_be32s(f, &s->spi_tx_dat); - qemu_put_be32s(f, &s->spi_rx_dat); - qemu_put_be32s(f, &s->packet_cnt_reg); - qemu_put_be32s(f, &s->pending_clr_reg); - qemu_put_be32s(f, &s->swap_cfg); - qemu_put_be32s(f, &s->fb_clk_sel); -} - -static int s5pc1xx_spi_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxSPIState *s = (S5pc1xxSPIState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->ch_cfg); - qemu_get_be32s(f, &s->clk_cfg); - qemu_get_be32s(f, &s->mode_cfg); - qemu_get_be32s(f, &s->cs_reg); - qemu_get_be32s(f, &s->spi_int_en); - qemu_get_be32s(f, &s->spi_status); - qemu_get_be32s(f, &s->spi_tx_dat); - qemu_get_be32s(f, &s->spi_rx_dat); - qemu_get_be32s(f, &s->packet_cnt_reg); - qemu_get_be32s(f, &s->pending_clr_reg); - qemu_get_be32s(f, &s->swap_cfg); - qemu_get_be32s(f, &s->fb_clk_sel); - - return 0; -} - -static void s5pc1xx_spi_reset(void *opaque) -{ - S5pc1xxSPIState *s = (S5pc1xxSPIState *)opaque; - - s->ch_cfg = 0; - s->clk_cfg = 0; - s->mode_cfg = 0; - s->cs_reg = 1; - s->spi_int_en = 0; - s->spi_status = 0; - s->spi_tx_dat = 0; - s->spi_rx_dat = 0; - s->packet_cnt_reg = 0; - s->pending_clr_reg = 0; - s->swap_cfg = 0; - s->fb_clk_sel = 0; -} - -static int s5pc1xx_spi_init(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxSPIState *s = FROM_SYSBUS(S5pc1xxSPIState, dev); - - sysbus_init_irq(dev, &s->irq); - iomemtype = - cpu_register_io_memory(s5pc1xx_spi_readfn, s5pc1xx_spi_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_WDT_REG_MEM_SIZE, iomemtype); - - s5pc1xx_spi_reset(s); - - qemu_register_reset(s5pc1xx_spi_reset, s); - register_savevm(&dev->qdev, "s5pc1xx.spi", -1, 1, - s5pc1xx_spi_save, s5pc1xx_spi_load, s); - - return 0; -} - -static void s5pc1xx_spi_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.spi", sizeof(S5pc1xxSPIState), - s5pc1xx_spi_init); -} - -device_init(s5pc1xx_spi_register_devices) diff --git a/hw/s5pc1xx_srom.c b/hw/s5pc1xx_srom.c deleted file mode 100644 index 058b996..0000000 --- a/hw/s5pc1xx_srom.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * S5PC1XX SROM controller. - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Alexey Merkulov - */ - -#include "sysbus.h" -#include "s5pc1xx.h" - - -typedef struct S5pc1xxSROMState { - SysBusDevice busdev; - - /* SROM_BW - SROM Bus width & wait control */ - uint32_t control; - /* SROM_BCn - SROM Bank n control register */ - uint32_t *bank_control; - uint32_t num_banks; -} S5pc1xxSROMState; - - -static uint32_t s5pc1xx_srom_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxSROMState *s = (S5pc1xxSROMState *)opaque; - - if ((offset > (s->num_banks + 1) * 4) || (offset & 3)) { - hw_error("s5pc1xx.srom: bad read offset " TARGET_FMT_plx "\n", - offset); - } - - switch (offset) { - case 0x00: - return s->control; - default: - return s->bank_control[offset / 4 - 1]; - } -} - -static void s5pc1xx_srom_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxSROMState *s = (S5pc1xxSROMState *)opaque; - - if ((offset > (s->num_banks + 1) * 4) || (offset & 3)) { - hw_error("s5pc1xx.srom: bad write offset " TARGET_FMT_plx "\n", - offset); - } - - switch (offset) { - case 0x00: - s->control = val; - break; - default: - s->bank_control[offset / 4 - 1] = val; - break; - } -} - -static CPUReadMemoryFunc * const s5pc1xx_srom_mm_read[] = { - s5pc1xx_srom_read, - s5pc1xx_srom_read, - s5pc1xx_srom_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_srom_mm_write[] = { - s5pc1xx_srom_write, - s5pc1xx_srom_write, - s5pc1xx_srom_write -}; - -static void s5pc1xx_srom_save(QEMUFile *f, void *opaque) -{ - S5pc1xxSROMState *s = (S5pc1xxSROMState *)opaque; - int i; - - qemu_put_be32s(f, &s->control); - qemu_put_be32s(f, &s->num_banks); - - for (i = 0; i < s->num_banks; i++) { - qemu_put_be32s(f, s->bank_control + i); - } - -} - -static int s5pc1xx_srom_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxSROMState *s = (S5pc1xxSROMState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->control); - qemu_get_be32s(f, &s->num_banks); - - for (i = 0; i < s->num_banks; i++) { - qemu_get_be32s(f, s->bank_control + i); - } - - return 0; -} - -static void s5pc1xx_srom_reset(DeviceState *d) -{ - S5pc1xxSROMState *s = - FROM_SYSBUS(S5pc1xxSROMState, sysbus_from_qdev(d)); - int i = 0; - - s->control = 0x00000008; - for (i = 0; i < s->num_banks; i++) { - s->bank_control[i] = 0x000F0000; - } -} - -DeviceState *s5pc1xx_srom_init(target_phys_addr_t base, int num_banks) -{ - DeviceState *dev = qdev_create(NULL, "s5pc1xx.srom"); - - qdev_prop_set_uint32(dev, "num-banks", num_banks); - qdev_init_nofail(dev); - sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); - return dev; -} - -static int s5pc1xx_srom_init1(SysBusDevice *dev) -{ - S5pc1xxSROMState *s = FROM_SYSBUS(S5pc1xxSROMState, dev); - int iomemtype; - - iomemtype = - cpu_register_io_memory(s5pc1xx_srom_mm_read, s5pc1xx_srom_mm_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, (s->num_banks + 1) * 4, iomemtype); - s->bank_control = qemu_mallocz(s->num_banks * sizeof(uint32_t)); - - s5pc1xx_srom_reset(&s->busdev.qdev); - - register_savevm(&dev->qdev, "s5pc1xx.srom", -1, 1, - s5pc1xx_srom_save, s5pc1xx_srom_load, s); - - return 0; -} - -static SysBusDeviceInfo s5pc1xx_srom_info = { - .init = s5pc1xx_srom_init1, - .qdev.name = "s5pc1xx.srom", - .qdev.size = sizeof(S5pc1xxSROMState), - .qdev.reset = s5pc1xx_srom_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("num-banks", S5pc1xxSROMState, num_banks, 6), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_srom_register(void) -{ - sysbus_register_withprop(&s5pc1xx_srom_info); -} - -device_init(s5pc1xx_srom_register) diff --git a/hw/s5pc1xx_st.c b/hw/s5pc1xx_st.c deleted file mode 100644 index a4dbe37..0000000 --- a/hw/s5pc1xx_st.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * System Timer for S5C110-based board emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - * Dmitry Zhurikhin - */ - -#include "sysbus.h" -#include "qemu-timer.h" -#include "s5pc1xx.h" - - -#define TCFG 0x00 /* R/W Configures 8-bit-Prescaler and Clock MUX 0x0000_0000 */ -#define TCON 0x04 /* R/W Timer Control Register 0x0000_0000 */ -#define TICNTB 0x08 /* R/W Tick Integer Count Buffer Register 0x0000_0000 */ -#define TICNTO 0x0C /* R Tick Integer Count Observation Register 0x0000_0000 */ -#define TFCNTB 0x10 /* R/W Tick Fractional Count Buffer Register 0x0000_0000 */ -#define ICNTB 0x18 /* R/W Interrupt Count Buffer Register 0x0000_0000 */ -#define ICNTO 0x1C /* R Interrupt Count Observation Register 0x0000_0000 */ -#define INT_CSTAT 0x20 /* R/W Interrupt Control and Status Register 0x0000_0000 */ - -/* TCFG */ -#define TICK_SWRST (1 << 16) /* SW reset of TICK generation logic */ -#define FDIV_SEL (1 << 15) /* Fractional divider select */ -#define TICKGEN_SEL (1 << 14) /* 0 = Integer divider 1 = Fractional divider */ -#define TCLKB_MUX (3 << 12) /* Selects clock input for TCLKB */ -#define DIV_MUX (7 << 8) /* Selects Mux input for Timer */ -#define PRESCALER (0xFF << 0) /* Prescaler value for timer 0x00 */ - -/* TCON */ -#define INT_AUTO_RELOAD (1 << 5) /* 0 = No operation 1 = Interval mode(auto-reload) */ -#define INT_MAN_UPD (1 << 4) /* 0 = No operation 1 = Update ICNTB and One-shot mode */ -#define INT_RUN (1 << 3) /* 0 = Stop 1 = Start timer */ -#define TIMER_RUN (1 << 0) /* 0 = Stop 1 = Start timer */ - -/* INT_CSTAT */ -#define TWIE (1 << 10) /* TCON Write Interrupt Enable / 0: Disable, 1: Enable 0x0 */ -#define IWIE (1 << 9) /* ICNTB write Interrupt Enable / 0: Disable, 1: Enable 0x0 */ -#define TFWIE (1 << 8) /* TFCNTB write Interrupt Enable / 0: Disable, 1: Enable 0x0 */ -#define TIWIE (1 << 7) /* TICNTB write Interrupt Enable / 0: Disable, 1: Enable 0x0 */ -#define ICNTEIE (1 << 6) /* Interrupt counter expired (INTCNT=0) Interrupt Enable */ -#define TCON_W_STAT (1 << 5) /* TCON Write Interrupt Status Bit */ -#define ICNTB_W_STAT (1 << 4) /* ICNTB Write Interrupt Status Bit */ -#define TFCNTB_W_STAT (1 << 3) /* TFCTNB Write Interrupt Status Bit */ -#define TICNTB_W_STAT (1 << 2) /* TICTNB Write Interrupt Status Bit */ -#define INTCNT_EXP_STAT (1 << 1) /* Interrupt counter expired (INTCNT=0) Interrupt Status Bit */ -#define INT_ENABLE (1 << 0) /* Enables Interrupt */ -#define ALL_STAT (TCON_W_STAT | ICNTB_W_STAT | TFCNTB_W_STAT | \ - TICNTB_W_STAT | INTCNT_EXP_STAT) - -#define S5PC1XX_ST_REG_MEM_SIZE 0x24 - - -typedef struct { - SysBusDevice busdev; - - uint32_t tcfg; - uint32_t tcon; - uint32_t ticntb; - uint32_t ticnto; - uint32_t tfcntb; - uint32_t icntb; - int32_t icnto; /* has signed type */ - uint32_t int_cstat; - - qemu_irq irq; - - uint8_t divider; - uint8_t prescaler; - - QEMUTimer *st_timer; - uint32_t freq_out; - uint64_t tick_interval; - uint64_t last_tick; - uint64_t next_planned_tick; - uint64_t base_time; -} S5pc1xxSTState; - - -const char *st_clks[] = { "XXTI", "XrtcXTI", "XusbXTI", "pclk_66" }; - -static void s5pc1xx_st_tick(void *opaque); - -/* work with interrupts depending on permissive bits */ -static void s5pc1xx_st_irq(S5pc1xxSTState *s, uint32_t enab_mask, - uint32_t stat_mask) -{ - /* stop tick timer */ - if ((stat_mask == TICNTB_W_STAT) || (stat_mask == TFCNTB_W_STAT)) { - s->tcon &= ~TIMER_RUN; - s5pc1xx_st_tick(s); - } - - /* reload ICNT after manual update */ - if ((stat_mask == ICNTB_W_STAT) && (s->tcon & INT_MAN_UPD)) - s->icnto = s->icntb; - - /* raise irq */ - if ((s->int_cstat & INT_ENABLE) && (s->int_cstat & enab_mask)) { - qemu_irq_raise(s->irq); - } - - s->int_cstat |= stat_mask; -} - -static void s5pc1xx_st_set_timer(S5pc1xxSTState *s) -{ - uint64_t last = qemu_get_clock(vm_clock) - s->base_time; - /* make a tick each tick_interval'th QEMU timer cycle - this way - * system timer is working consistently (1 second for emulated machine - * corresponds to 1 second for host); otherwise due to QEMU timer interrupt - * handling overhead it will slowly drift towards the past */ - s->next_planned_tick = last + (s->tick_interval - last % s->tick_interval); - qemu_mod_timer(s->st_timer, s->next_planned_tick + s->base_time); - s->last_tick = last; -} - -/* counter step */ -static void s5pc1xx_st_tick(void *opaque) -{ - S5pc1xxSTState *s = (S5pc1xxSTState *)opaque; - - /* tick actually happens not every ticnto but rather at icnto update; - * if current ticnto value is needed it is calculated in s5pc1xx_st_read */ - if (s->tcon & TIMER_RUN) { - if (s->tcon & INT_RUN) { - /* reload count */ - if (s->icnto == 0 && s->tcon & INT_AUTO_RELOAD) - s->icnto = s->icntb; - - s->icnto--; - - /* time for interrupt */ - if (s->icnto <= 0) { - s->icnto = 0; - s5pc1xx_st_irq(s, ICNTEIE, INTCNT_EXP_STAT); - } - } - - /* schedule next interrupt */ - s5pc1xx_st_set_timer(s); - } else { - s->next_planned_tick = 0; - s->last_tick = 0; - qemu_del_timer(s->st_timer); - } -} - -/* set default values for all fields */ -static void s5pc1xx_st_reset(S5pc1xxSTState *s) -{ - /* TODO: Check if reseting all counters is needed */ - s->tcfg = 0; - s->tcon = 0; - s->ticntb = 0; - s->ticnto = 0; - s->tfcntb = 0; - s->icntb = 1; - s->icnto = 0; - s->int_cstat = 0; - - s->last_tick = 0; - s->next_planned_tick = 0; - s->freq_out = 0; - s->tick_interval = 0; - s->divider = 1; - s->prescaler = 0; - s->base_time = qemu_get_clock(vm_clock); - - qemu_del_timer(s->st_timer); -} - -/* update timer frequency */ -static void s5pc1xx_st_update(S5pc1xxSTState *s) -{ - S5pc1xxClk clk; - - s->divider = 1 << ((s->tcfg & DIV_MUX) >> 8); - s->prescaler = s->tcfg & PRESCALER; - - clk = s5pc1xx_findclk(st_clks[(s->tcfg & TCLKB_MUX) >> 12]); - s->freq_out = s5pc1xx_clk_getrate(clk) / (s->prescaler + 1) / s->divider; - s->tick_interval = - muldiv64(s->ticntb, get_ticks_per_sec(), s->freq_out) + - (muldiv64(s->tfcntb, get_ticks_per_sec(), s->freq_out) >> 16); - s->next_planned_tick = 0; - - if (!s->freq_out) - hw_error("s5pc1xx.st: timer update input frequency is zero\n"); -} - -/* System Timer read */ -static uint32_t s5pc1xx_st_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxSTState *s = (S5pc1xxSTState *)opaque; - uint64_t cur_clock, tps; - - switch (offset) { - case TCFG: - return s->tcfg; - case TCON: - return s->tcon; - case TICNTB: - return s->ticntb; - case TICNTO: - if (s->freq_out && s->last_tick && s->ticntb && s->next_planned_tick) { - cur_clock = qemu_get_clock(vm_clock) - s->base_time; - if (cur_clock < s->next_planned_tick) { - if (s->tick_interval > 0xFFFFFFFF) { - /* very large tick interval; muldiv64 can't be used - * in this case directly; avoid 64-bit difference by - * knowing the fact that next_planned_tick and last_tick - * may be represented as "next_planned_tick = - * K * tick_interval" and "last_tick = N * tick_interval" - * assuming that last_tick happened in time */ - tps = get_ticks_per_sec(); - s->ticnto = muldiv64(s->next_planned_tick - cur_clock, - s->ticntb, - (s->next_planned_tick - s->last_tick + - tps / 2) / tps) / tps; - } else { - /* tick interval is 32-bit so both differences - * should be 32-bit too */ - s->ticnto = muldiv64(s->next_planned_tick - cur_clock, s->ticntb, - s->next_planned_tick - s->last_tick); - } - } else { - s->ticnto = 0; - } - } else { - s->ticnto = 0; - } - return s->ticnto; - case TFCNTB: - return s->tfcntb; - case ICNTB: - return s->icntb - 1; - case ICNTO: - return s->icnto; - case INT_CSTAT: - return s->int_cstat; - default: - hw_error("s5pc1xx.st: bad read offset " TARGET_FMT_plx "\n", offset); - } -} - -/* System Timer write */ -static void s5pc1xx_st_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxSTState *s = (S5pc1xxSTState *)opaque; - - switch (offset) { - case TCFG: - if (value & TICK_SWRST) { - s5pc1xx_st_reset(s); - break; - } - s->tcfg = value; - s5pc1xx_st_update(s); - break; - - case TCON: - s5pc1xx_st_irq(s, TWIE, TCON_W_STAT); - - if ((value & TIMER_RUN) > (s->tcon & TIMER_RUN)) { - s->base_time = qemu_get_clock(vm_clock); - s5pc1xx_st_set_timer(s); - } else if ((value & TIMER_RUN) < (s->tcon & TIMER_RUN)) { - qemu_del_timer(s->st_timer); - } - s->tcon = value; - break; - - case TICNTB: - /* in this case s->ticntb is updated after interrupt raise - * since the timer must be stopped first */ - s5pc1xx_st_irq(s, TIWIE, TICNTB_W_STAT); - s->ticntb = value; - s5pc1xx_st_update(s); - break; - - case TFCNTB: - s5pc1xx_st_irq(s, TFWIE, TFCNTB_W_STAT); - s->tfcntb = value; - s5pc1xx_st_update(s); - break; - - case ICNTB: - /* in this case s->icntb is updated before interrupt raise - * since the value is needed for manual update */ - s->icntb = value + 1; - s5pc1xx_st_irq(s, IWIE, ICNTB_W_STAT); - break; - - case INT_CSTAT: - /* set INT_CSTAT as value except *_STAT bits */ - s->int_cstat = (s->int_cstat & ALL_STAT) | (value & ~ALL_STAT); - /* clear *_STAT bits if they are set in value */ - s->int_cstat &= ~(value & ALL_STAT); - - /* lower interrupt */ - /* TODO: check if IRQ should be lowered for all cases or - * only when there are no more stat bits left */ - if (!(s->int_cstat & ALL_STAT)) - qemu_irq_lower(s->irq); - break; - - default: - hw_error("s5pc1xx.st: bad write offset " TARGET_FMT_plx "\n", offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_st_readfn[] = { - s5pc1xx_st_read, - s5pc1xx_st_read, - s5pc1xx_st_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_st_writefn[] = { - s5pc1xx_st_write, - s5pc1xx_st_write, - s5pc1xx_st_write -}; - -static void s5pc1xx_st_save(QEMUFile *f, void *opaque) -{ - S5pc1xxSTState *s = (S5pc1xxSTState *)opaque; - - qemu_put_be32s (f, &s->tcfg); - qemu_put_be32s (f, &s->tcon); - qemu_put_be32s (f, &s->ticntb); - qemu_put_be32s (f, &s->ticnto); - qemu_put_be32s (f, &s->tfcntb); - qemu_put_be32s (f, &s->icntb); - qemu_put_sbe32s(f, &s->icnto); - qemu_put_be32s (f, &s->int_cstat); - - qemu_put_8s (f, &s->divider); - qemu_put_8s (f, &s->prescaler); - qemu_put_be32s (f, &s->freq_out); - - qemu_put_be64s (f, &s->tick_interval); - qemu_put_be64s (f, &s->last_tick); - qemu_put_be64s (f, &s->next_planned_tick); - qemu_put_be64s (f, &s->base_time); - - qemu_put_timer (f, s->st_timer); -} - -static int s5pc1xx_st_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxSTState *s = (S5pc1xxSTState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s (f, &s->tcfg); - qemu_get_be32s (f, &s->tcon); - qemu_get_be32s (f, &s->ticntb); - qemu_get_be32s (f, &s->ticnto); - qemu_get_be32s (f, &s->tfcntb); - qemu_get_be32s (f, &s->icntb); - qemu_get_sbe32s(f, &s->icnto); - qemu_get_be32s (f, &s->int_cstat); - - qemu_get_8s (f, &s->divider); - qemu_get_8s (f, &s->prescaler); - qemu_get_be32s (f, &s->freq_out); - - qemu_get_be64s (f, &s->tick_interval); - qemu_get_be64s (f, &s->last_tick); - qemu_get_be64s (f, &s->next_planned_tick); - qemu_get_be64s (f, &s->base_time); - - qemu_get_timer (f, s->st_timer); - - return 0; -} - -/* System Timer init */ -static int s5pc1xx_st_init(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxSTState *s = FROM_SYSBUS(S5pc1xxSTState, dev); - - s->st_timer = qemu_new_timer(vm_clock, s5pc1xx_st_tick, s); - sysbus_init_irq(dev, &s->irq); - iomemtype = - cpu_register_io_memory(s5pc1xx_st_readfn, s5pc1xx_st_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_ST_REG_MEM_SIZE, iomemtype); - - s5pc1xx_st_reset(s); - - register_savevm(&dev->qdev, "s5pc1xx.st", -1, 1, - s5pc1xx_st_save, s5pc1xx_st_load, s); - return 0; -} - -static void s5pc1xx_st_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.st", sizeof(S5pc1xxSTState), s5pc1xx_st_init); -} - -device_init(s5pc1xx_st_register_devices) diff --git a/hw/s5pc1xx_tsadc.c b/hw/s5pc1xx_tsadc.c deleted file mode 100644 index 737bf02..0000000 --- a/hw/s5pc1xx_tsadc.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * S5PC1XX ADC & TOUCH SCREEN INTERFACE - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Alexey Merkulov - * Dmitry Zhurikhin - */ - -#include "s5pc1xx.h" -#include "qemu-timer.h" -#include "sysbus.h" -#include "console.h" - - -#define QEMUMAXX 0x7FFF -#define QEMUMAXY 0x7FFF - -#define WAIT_FOR_INT 3 - -#define S5PC1XX_TSADC_REG_MEM_SIZE 0x24 - - -typedef union { - /* raw register data */ - uint32_t v; - - /* register bits */ - struct tsadccon_bits { - unsigned enable_start : 1; - unsigned read_start : 1; - unsigned standby : 1; - unsigned reserved3_5 : 3; - unsigned prscvl : 8; - unsigned prscen : 1; - unsigned ecflg : 1; /* (Read only) */ - unsigned res : 1; - unsigned tssel : 1; - } b; -} tsadccon_s; - -typedef union { - /* raw register data */ - uint32_t v; - - /* register bits */ - struct tsdat_bits { - /*XPDATA or YPDATA*/ - unsigned pdata : 12; - unsigned xy_pst_val : 2; - unsigned auto_pst_val : 1; - unsigned updown : 1; - } b; -} tsdat_s; - -typedef union { - /* raw register data */ - uint32_t v; - - /* register bits */ - struct tscon_bits { - unsigned xy_pst : 2; - unsigned auto_pst : 1; - unsigned pull_up : 1; - unsigned xp_sen : 1; - unsigned xm_sen : 1; - unsigned yp_sen : 1; - unsigned ym_sen : 1; - unsigned ud_sen : 1; - } b; -} tscon_s; - -typedef union { - /* raw register data */ - uint32_t v; - - /* register bits */ - struct tspenstat_bits { - unsigned tsc_dn : 1; - unsigned tsc_up : 1; - } b; -} tspenstat_s; - -typedef struct S5pc1xxTSADCState { - SysBusDevice busdev; - - /* R/W Specifies the TSn - ADC Control Register */ - tsadccon_s tsadccon; - - /* R/W Specifies the TSn - Touch Screen Control Register */ - tscon_s tscon; - - /* R/W Specifies the TSn - ADC Start or Interval Delay Register */ - uint32_t tsdly; - - /* R Specifies the TSn - ADC Conversion Data X Register */ - tsdat_s tsdat0; - - /* R Specifies the TSn - ADC Conversion Data Y Register */ - tsdat_s tsdat1; - - /* R/W Specifies the TSn - Penn Up or Down Status Register */ - tspenstat_s tspenstat; - - /* R/W Specifies the Analog input channel selection */ - uint32_t adcmux; - - /* Internal data */ - - /* ID of this device instance */ - uint32_t id; - /* Current pointer coordinates ({0,0} < {x,y} < {QEMUMAXX,QEMUMAXY}) */ - uint32_t x, y; - /* Boundary reported coordinates */ - uint32_t minx, maxx, miny, maxy; - /* Is it a 'new' touchscreen version? */ - int32_t new; - /* Touchscreen resolution, max 12 bit */ - uint32_t resolution; - /* Current mouse buttons state */ - int32_t pressure; - /* Currently reported touchscreen touch state */ - int32_t report_pressure; - - /* Interrupts */ - qemu_irq irq_adc; - qemu_irq irq_pennd; - - /* Timer to report conversion data periodically */ - QEMUTimer *timer; - uint32_t conversion_time; -} S5pc1xxTSADCState; - - -static void s5pc1xx_tsadc_reset(DeviceState *d) -{ - S5pc1xxTSADCState *s = - FROM_SYSBUS(S5pc1xxTSADCState, sysbus_from_qdev(d)); - - s->tsadccon.v = 0x00003FC4; - s->tscon.v = 0x00000058; - s->tsdly = 0x000000FF; - s->tsdat0.v = 0x00000000; - s->tsdat1.v = 0x00000000; - s->tspenstat.v = 0x00000000; - s->adcmux = 0x00000000; - - s->x = s->y = 0; - s->pressure = 0; - s->report_pressure = 0; - s->conversion_time = 0; -} - -static void s5pc1xx_tsadc_conversion_start(S5pc1xxTSADCState *s, - unsigned int time) -{ - /* Do not do anything in standby mode */ - if (!s->tsadccon.b.standby) { - /* Conversion is going... */ - s->tsadccon.b.ecflg = 0; - /* ... and will finish in 'time' QEMU vm_clock ticks */ - qemu_mod_timer(s->timer, - qemu_get_clock(vm_clock) + time); - } -} - -static void s5pc1xx_tsadc_conversion(void *opaque) -{ - S5pc1xxTSADCState *s = opaque; - - s->tsadccon.b.ecflg = 1; - - /* Generate IRQ_ADC for any mode except 'Waiting for interrupt' */ - if (s->tscon.b.xy_pst != WAIT_FOR_INT) { - qemu_irq_raise(s->irq_adc); - } else { - /* If mouse buttons state changed recently - report it */ - if (s->report_pressure != s->pressure && - ((s->pressure == 1 && s->tscon.b.ud_sen == 0) || - (s->pressure == 0 && s->tscon.b.ud_sen == 1))) { - qemu_irq_raise(s->irq_pennd); - s->tspenstat.b.tsc_dn |= s->pressure; - s->tspenstat.b.tsc_up |= !s->pressure; - } - s->report_pressure = s->pressure; - } -} - -static uint32_t s5pc1xx_tsadc_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxTSADCState *s = (S5pc1xxTSADCState *)opaque; - - switch (offset) { - case 0x00: - return s->tsadccon.v; - case 0x04: - return s->tscon.v; - case 0x08: - return s->tsdly; - case 0x0C: - if (s->new) { - s->tsdat0.b.pdata = - ((1 << s->resolution) - 1) - - (s->miny + s->y * (s->maxy - s->miny) / QEMUMAXY); - } else { - s->tsdat0.b.pdata = s->minx + s->x * (s->maxx - s->minx) / QEMUMAXX; - } - s->tsdat0.b.updown = s->report_pressure == 0; - s->tsdat0.b.auto_pst_val = s->tscon.b.auto_pst; - s->tsdat0.b.xy_pst_val = s->tscon.b.xy_pst; - if (s->tsadccon.b.read_start) - s5pc1xx_tsadc_conversion_start(s, s->conversion_time); - return s->tsdat0.v; - case 0x10: - if (s->new) { - s->tsdat1.b.pdata = - ((1 << s->resolution) - 1) - - (s->minx + s->x * (s->maxx - s->minx) / QEMUMAXX); - } else { - s->tsdat1.b.pdata = s->miny + s->y * (s->maxy - s->miny) / QEMUMAXY; - } - s->tsdat1.b.updown = s->report_pressure == 0; - s->tsdat1.b.auto_pst_val = s->tscon.b.auto_pst; - s->tsdat1.b.xy_pst_val = s->tscon.b.xy_pst; - if (s->tsadccon.b.read_start) - s5pc1xx_tsadc_conversion_start(s, s->conversion_time); - return s->tsdat1.v; - case 0x14: - return s->tspenstat.v; - case 0x18: - return 0x0; - case 0x1C: - return s->adcmux; - case 0x20: - return 0x0; - default: - hw_error("s5pc1xx.tsadc: bad read offset " TARGET_FMT_plx "\n", - offset); - } -} - -static void s5pc1xx_tsadc_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxTSADCState *s = (S5pc1xxTSADCState *)opaque; - - switch (offset) { - case 0x00: - s->tsadccon.v = val; - if (!s->tsadccon.b.read_start && s->tsadccon.b.enable_start) - s5pc1xx_tsadc_conversion_start(s, s->conversion_time); - s->tsadccon.b.enable_start = 0; - /* FIXME: choose the correct clock depending on a register value */ - s->conversion_time = - muldiv64(s->tsdly & 0xFFFF, get_ticks_per_sec(), - s5pc1xx_clk_getrate(s5pc1xx_findclk("pclk_66")) / - (s->tsadccon.b.prscen ? s->tsadccon.b.prscvl + 1: 1)); - break; - case 0x04: - s->tscon.v = val; - if (s->report_pressure != s->pressure && - s->tscon.b.xy_pst == WAIT_FOR_INT) { - /* Raise next IRQ for touch-up in one ms */ - s5pc1xx_tsadc_conversion_start(s, get_ticks_per_sec() / 1000); - } - break; - case 0x08: - s->tsdly = val; - /* FIXME: choose the correct clock depending on a register value */ - s->conversion_time = - muldiv64(s->tsdly & 0xFFFF, get_ticks_per_sec(), - s5pc1xx_clk_getrate(s5pc1xx_findclk("pclk_66")) / - (s->tsadccon.b.prscen ? s->tsadccon.b.prscvl + 1: 1)); - break; - case 0x14: - s->tspenstat.v = val; - break; - case 0x18: - qemu_irq_lower(s->irq_adc); - break; - case 0x1C: - s->adcmux = val; - break; - case 0x20: - qemu_irq_lower(s->irq_pennd); - break; - default: - hw_error("s5pc1xx.tsadc: bad write offset " TARGET_FMT_plx "\n", - offset); - break; - } -} - -static void s5pc1xx_touchscreen_event(void *opaque, - int x, int y, int z, int buttons_state) -{ - S5pc1xxTSADCState *s = opaque; - - if (buttons_state) { - s->x = x; - s->y = y; - } - - if (s->pressure == !buttons_state) { - s->pressure = !!buttons_state; - - /* Report button state change momentarily if it happens in - * 'Waiting for interrupt' mode */ - if (s->tscon.b.xy_pst == WAIT_FOR_INT && !s->tsadccon.b.standby) { - s5pc1xx_tsadc_conversion(s); - } - } -} - -static CPUReadMemoryFunc * const s5pc1xx_tsadc_mm_read[] = { - s5pc1xx_tsadc_read, - s5pc1xx_tsadc_read, - s5pc1xx_tsadc_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_tsadc_mm_write[] = { - s5pc1xx_tsadc_write, - s5pc1xx_tsadc_write, - s5pc1xx_tsadc_write -}; - -static void s5pc1xx_tsadc_save(QEMUFile *f, void *opaque) -{ - S5pc1xxTSADCState *s = opaque; - - qemu_put_be32s (f, &s->tsadccon.v); - qemu_put_be32s (f, &s->tscon.v); - qemu_put_be32s (f, &s->tsdat0.v); - qemu_put_be32s (f, &s->tsdat1.v); - qemu_put_be32s (f, &s->tspenstat.v); - - qemu_put_be32s (f, &s->tsdly); - qemu_put_be32s (f, &s->adcmux); - qemu_put_be32s (f, &s->x); - qemu_put_be32s (f, &s->y); - qemu_put_sbe32s(f, &s->pressure); - qemu_put_sbe32s(f, &s->report_pressure); - qemu_put_be32s (f, &s->conversion_time); - qemu_put_timer (f, s->timer); -} - -static int s5pc1xx_tsadc_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxTSADCState *s = opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s (f, &s->tsadccon.v); - qemu_get_be32s (f, &s->tscon.v); - qemu_get_be32s (f, &s->tsdat0.v); - qemu_get_be32s (f, &s->tsdat1.v); - qemu_get_be32s (f, &s->tspenstat.v); - - qemu_get_be32s (f, &s->tsdly); - qemu_get_be32s (f, &s->adcmux); - qemu_get_be32s (f, &s->x); - qemu_get_be32s (f, &s->y); - qemu_get_sbe32s(f, &s->pressure); - qemu_get_sbe32s(f, &s->report_pressure); - qemu_get_be32s (f, &s->conversion_time); - qemu_get_timer (f, s->timer); - - return 0; -} - -DeviceState *s5pc1xx_tsadc_init(target_phys_addr_t base, qemu_irq irq_adc, - qemu_irq irq_pennd, int new, int resolution, - int minx, int maxx, int miny, int maxy) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_create(NULL, new ? "s5pc1xx.tsadc.new" : "s5pc1xx.tsadc"); - qdev_prop_set_uint32(dev, "resolution", resolution); - qdev_prop_set_uint32(dev, "minx", minx); - qdev_prop_set_uint32(dev, "miny", miny); - qdev_prop_set_uint32(dev, "maxx", maxx); - qdev_prop_set_uint32(dev, "maxy", maxy); - - qdev_init_nofail(dev); - s = sysbus_from_qdev(dev); - sysbus_connect_irq(s, 0, irq_adc); - sysbus_connect_irq(s, 1, irq_pennd); - sysbus_mmio_map(s, 0, base); - - return dev; -} - -static int s5pc1xx_tsadc_init1(SysBusDevice *dev) -{ - S5pc1xxTSADCState *s = FROM_SYSBUS(S5pc1xxTSADCState, dev); - int iomemtype; - /* Current number of S3C Touchscreen controllers */ - static int s5pc1xx_tsadc_number = 0; - char name[30]; - - s->id = s5pc1xx_tsadc_number++; - snprintf(name, 30, "QEMU s5pc1xx Touchscreen %d", s->id); - iomemtype = cpu_register_io_memory(s5pc1xx_tsadc_mm_read, - s5pc1xx_tsadc_mm_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_TSADC_REG_MEM_SIZE, iomemtype); - - s5pc1xx_tsadc_reset(&s->busdev.qdev); - - sysbus_init_irq(dev, &s->irq_adc); - sysbus_init_irq(dev, &s->irq_pennd); - s->timer = qemu_new_timer(vm_clock, s5pc1xx_tsadc_conversion, s); - - qemu_add_mouse_event_handler(s5pc1xx_touchscreen_event, s, 1, name); - register_savevm(&dev->qdev, "s5pc1xx.tsadc", s->id, 1, - s5pc1xx_tsadc_save, s5pc1xx_tsadc_load, s); - - return 0; -} - -static int s5pc1xx_tsadc_new_init1(SysBusDevice *dev) -{ - S5pc1xxTSADCState *s = FROM_SYSBUS(S5pc1xxTSADCState, dev); - - s->new = 1; - return s5pc1xx_tsadc_init1(dev); -} - -static SysBusDeviceInfo s5pc1xx_tsadc_info = { - .init = s5pc1xx_tsadc_init1, - .qdev.name = "s5pc1xx.tsadc", - .qdev.size = sizeof(S5pc1xxTSADCState), - .qdev.reset = s5pc1xx_tsadc_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("resolution", S5pc1xxTSADCState, resolution, 12), - DEFINE_PROP_UINT32("minx", S5pc1xxTSADCState, minx, 0), - DEFINE_PROP_UINT32("miny", S5pc1xxTSADCState, miny, 0), - DEFINE_PROP_UINT32("maxx", S5pc1xxTSADCState, maxx, 480), - DEFINE_PROP_UINT32("maxy", S5pc1xxTSADCState, maxy, 800), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static SysBusDeviceInfo s5pc1xx_tsadc_new_info = { - .init = s5pc1xx_tsadc_new_init1, - .qdev.name = "s5pc1xx.tsadc.new", - .qdev.size = sizeof(S5pc1xxTSADCState), - .qdev.reset = s5pc1xx_tsadc_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("resolution", S5pc1xxTSADCState, resolution, 12), - DEFINE_PROP_UINT32("minx", S5pc1xxTSADCState, minx, 0), - DEFINE_PROP_UINT32("miny", S5pc1xxTSADCState, miny, 0), - DEFINE_PROP_UINT32("maxx", S5pc1xxTSADCState, maxx, 480), - DEFINE_PROP_UINT32("maxy", S5pc1xxTSADCState, maxy, 800), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_tsadc_register_devices(void) -{ - sysbus_register_withprop(&s5pc1xx_tsadc_info); - sysbus_register_withprop(&s5pc1xx_tsadc_new_info); -} - -device_init(s5pc1xx_tsadc_register_devices) diff --git a/hw/s5pc1xx_uart.c b/hw/s5pc1xx_uart.c deleted file mode 100644 index b36cf5c..0000000 --- a/hw/s5pc1xx_uart.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * S5PC1XX UART Emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - */ - -#include "sysbus.h" -#include "qemu-char.h" -#include "s5pc1xx.h" -#include "s5pc1xx_gpio_regs.h" - - -#define QUEUE_SIZE 257 - -#define INT_RXD (1 << 0) -#define INT_ERROR (1 << 1) -#define INT_TXD (1 << 2) -#define INT_MODEM (1 << 3) - -#define TRSTATUS_TRANSMITTER_READY (1 << 2) -#define TRSTATUS_BUFFER_EMPTY (1 << 1) -#define TRSTATUS_DATA_READY (1 << 0) - -#define UFSTAT_RX_FIFO_FULL (1 << 8) - -#define UFCON_FIFO_ENABLED (1 << 0) -#define UFCON_TX_LEVEL_SHIFT 8 -#define UFCON_TX_LEVEL (7 << UFCON_TX_LEVEL_SHIFT) - -#define UFSTAT_TX_COUNT_SHIT 16 -#define UFSTAT_TX_COUNT (0xFF << UFSTAT_TX_COUNT_SHIT) - -#define QI(x) ((x + 1) % QUEUE_SIZE) -#define QD(x) ((x - 1 + QUEUE_SIZE) % QUEUE_SIZE) - -#define S5PC1XX_UART_REG_MEM_SIZE 0x3C - -typedef struct UartQueue { - uint8_t queue[QUEUE_SIZE]; - uint32_t s, t; - uint32_t size; -} UartQueue; - -typedef struct S5pc1xxUartState { - SysBusDevice busdev; - - UartQueue rx; - - uint32_t ulcon; - uint32_t ucon; - uint32_t ufcon; - uint32_t umcon; - uint32_t utrstat; - uint32_t uerstat; - uint32_t ufstat; - uint32_t umstat; - uint32_t utxh; - uint32_t urxh; - uint32_t ubrdiv; - uint32_t udivslot; - uint32_t uintp; - uint32_t uintsp; - uint32_t uintm; - - CharDriverState *chr; - qemu_irq irq; - uint32_t instance; -} S5pc1xxUartState; - - -static inline int queue_elem_count(const UartQueue *s) -{ - if (s->t >= s->s) { - return s->t - s->s; - } else { - return QUEUE_SIZE - s->s + s->t; - } -} - -static inline int queue_empty_count(const UartQueue *s) -{ - return s->size - queue_elem_count(s) - 1; -} - -static inline int queue_empty(const UartQueue *s) -{ - return (queue_elem_count(s) == 0); -} - -static inline void queue_push(UartQueue *s, uint8_t x) -{ - s->queue[s->t] = x; - s->t = QI(s->t); -} - -static inline uint8_t queue_get(UartQueue *s) -{ - uint8_t ret; - - ret = s->queue[s->s]; - s->s = QI(s->s); - return ret; -} - -static inline void queue_reset(UartQueue *s) -{ - s->s = 0; - s->t = 0; -} - -static void s5pc1xx_uart_update(S5pc1xxUartState *s) -{ - if (s->ufcon && UFCON_FIFO_ENABLED) { - if (((s->ufstat && UFSTAT_TX_COUNT) >> UFSTAT_TX_COUNT_SHIT) <= - ((s->ufcon && UFCON_TX_LEVEL) >> UFCON_TX_LEVEL_SHIFT) * 2 ) { - s->uintsp |= INT_TXD; - } - } - - s->uintp = s->uintsp & ~s->uintm; - if (s->uintp) { - qemu_irq_raise(s->irq); - } else { - qemu_irq_lower(s->irq); - } -} - -/* Read UART by GPIO */ -static uint32_t s5pc1xx_uart_gpio_read(void *opaque, - int io_index) -{ - S5pc1xxUartState *s = (S5pc1xxUartState *)opaque; - - /* TODO: check if s->uintp should be used instead of s->uintsp */ - if (io_index == GPIO_UART_RXD(s->instance)) { - return (s->uintsp & INT_RXD); - } - if (io_index == GPIO_UART_TXD(s->instance)) { - return (s->uintsp & INT_TXD); - } - - /* TODO: check if this is correct */ - if (io_index == GPIO_UART_CTS(s->instance)) { - return ~(s->umstat & 0x1); - } - if (io_index == GPIO_UART_RTS(s->instance)) { - return ~(s->umcon & 0x1); - } - - /* TODO: return correct values */ - if (io_index == GPIO_UART_AUDIO_RXD) { - return 0; - } - if (io_index == GPIO_UART_AUDIO_TXD) { - return 0; - } - - return 0; -} - -static GPIOReadMemoryFunc *s5pc1xx_uart_gpio_readfn = s5pc1xx_uart_gpio_read; -static GPIOWriteMemoryFunc *s5pc1xx_uart_gpio_writefn = s5pc1xx_empty_gpio_write; /* a gag */ - -static uint32_t s5pc1xx_uart_mm_read(void *opaque, target_phys_addr_t offset) -{ - uint32_t res; - S5pc1xxUartState *s = (S5pc1xxUartState *)opaque; - - switch (offset) { - case 0x00: - return s->ulcon; - case 0x04: - return s->ucon; - case 0x08: - return s->ufcon; - case 0x0C: - return s->umcon; - case 0x10: - return s->utrstat; - case 0x14: - res = s->uerstat; - s->uerstat = 0; - return res; - case 0x18: - s->ufstat = queue_elem_count(&s->rx) & 0xff; - if (queue_empty_count(&s->rx) == 0) { - s->ufstat |= UFSTAT_RX_FIFO_FULL; - } - return s->ufstat; - case 0x1C: - return s->umstat; - case 0x24: - if (s->ufcon & 1) { - if (! queue_empty(&s->rx)) { - res = queue_get(&s->rx); - if (queue_empty(&s->rx)) { - s->utrstat &= ~TRSTATUS_DATA_READY; - } else { - s->utrstat |= TRSTATUS_DATA_READY; - } - } else { - s->uintsp |= INT_ERROR; - s5pc1xx_uart_update(s); - res = 0; - } - } else { - s->utrstat &= ~TRSTATUS_DATA_READY; - res = s->urxh; - } - return res; - case 0x28: - return s->ubrdiv; - case 0x2C: - return s->udivslot; - case 0x30: - return s->uintp; - case 0x34: - return s->uintsp; - case 0x38: - return s->uintm; - default: - hw_error("s5pc1xx.uart: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static void s5pc1xx_uart_mm_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - uint8_t ch; - S5pc1xxUartState *s = (S5pc1xxUartState *)opaque; - - switch (offset) { - case 0x00: - s->ulcon = val; - break; - case 0x04: - s->ucon = val; - break; - case 0x08: - s->ufcon = val; - if (val & 2) { - queue_reset(&s->rx); - } - s->ufcon &= ~6; - break; - case 0x0C: - s->umcon = val; - break; - case 0x20: - if (s->chr) { - s->utrstat &= ~(TRSTATUS_TRANSMITTER_READY | TRSTATUS_BUFFER_EMPTY); - ch = (uint8_t)val; - qemu_chr_write(s->chr, &ch, 1); - s->utrstat |= TRSTATUS_TRANSMITTER_READY | TRSTATUS_BUFFER_EMPTY; - s->uintsp |= INT_TXD; - } - break; - case 0x28: - s->ubrdiv = val; - break; - case 0x2C: - s->udivslot = val; - break; - case 0x30: - s->uintp &= ~val; - s->uintsp &= ~val; /* TODO: does this really work in this way??? */ - break; - case 0x34: - s->uintsp = val; - break; - case 0x38: - s->uintm = val; - break; - default: - hw_error("s5pc1xx.uart: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } - s5pc1xx_uart_update(s); -} - -CPUReadMemoryFunc * const s5pc1xx_uart_readfn[] = { - s5pc1xx_uart_mm_read, - s5pc1xx_uart_mm_read, - s5pc1xx_uart_mm_read -}; - -CPUWriteMemoryFunc * const s5pc1xx_uart_writefn[] = { - s5pc1xx_uart_mm_write, - s5pc1xx_uart_mm_write, - s5pc1xx_uart_mm_write -}; - -static void s5pc1xx_uart_save(QEMUFile *f, void *opaque) -{ - S5pc1xxUartState *s = (S5pc1xxUartState *)opaque; - - qemu_put_buffer(f, s->rx.queue, QUEUE_SIZE); - qemu_put_be32s(f, &s->rx.s); - qemu_put_be32s(f, &s->rx.t); - qemu_put_be32s(f, &s->rx.size); - - qemu_put_be32s(f, &s->ulcon); - qemu_put_be32s(f, &s->ucon); - qemu_put_be32s(f, &s->ufcon); - qemu_put_be32s(f, &s->umcon); - qemu_put_be32s(f, &s->utrstat); - qemu_put_be32s(f, &s->uerstat); - qemu_put_be32s(f, &s->ufstat); - qemu_put_be32s(f, &s->umstat); - qemu_put_be32s(f, &s->utxh); - qemu_put_be32s(f, &s->urxh); - qemu_put_be32s(f, &s->ubrdiv); - qemu_put_be32s(f, &s->udivslot); - qemu_put_be32s(f, &s->uintp); - qemu_put_be32s(f, &s->uintsp); - qemu_put_be32s(f, &s->uintm); -} - -static int s5pc1xx_uart_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxUartState *s = (S5pc1xxUartState *)opaque; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_buffer(f, s->rx.queue, QUEUE_SIZE); - qemu_get_be32s(f, &s->rx.s); - qemu_get_be32s(f, &s->rx.t); - qemu_get_be32s(f, &s->rx.size); - - qemu_get_be32s(f, &s->ulcon); - qemu_get_be32s(f, &s->ucon); - qemu_get_be32s(f, &s->ufcon); - qemu_get_be32s(f, &s->umcon); - qemu_get_be32s(f, &s->utrstat); - qemu_get_be32s(f, &s->uerstat); - qemu_get_be32s(f, &s->ufstat); - qemu_get_be32s(f, &s->umstat); - qemu_get_be32s(f, &s->utxh); - qemu_get_be32s(f, &s->urxh); - qemu_get_be32s(f, &s->ubrdiv); - qemu_get_be32s(f, &s->udivslot); - qemu_get_be32s(f, &s->uintp); - qemu_get_be32s(f, &s->uintsp); - qemu_get_be32s(f, &s->uintm); - - return 0; -} - -static int s5pc1xx_uart_can_receive(void *opaque) -{ - S5pc1xxUartState *s = (S5pc1xxUartState *)opaque; - - return queue_empty_count(&s->rx); -} - -static void s5pc1xx_uart_trigger_level(S5pc1xxUartState *s) -{ - /* TODO: fix this */ - if (! queue_empty(&s->rx)) { - s->uintsp |= INT_RXD; - } -} - -static void s5pc1xx_uart_receive(void *opaque, const uint8_t *buf, int size) -{ - int i; - S5pc1xxUartState *s = (S5pc1xxUartState *)opaque; - if (s->ufcon & 1) { - if (queue_empty_count(&s->rx) < size) { - for (i = 0; i < queue_empty_count(&s->rx); i++) { - queue_push(&s->rx, buf[i]); - } - s->uintp |= INT_ERROR; - s->utrstat |= TRSTATUS_DATA_READY; - } else { - for (i = 0; i < size; i++) { - queue_push(&s->rx, buf[i]); - } - s->utrstat |= TRSTATUS_DATA_READY; - } - s5pc1xx_uart_trigger_level(s); - } else { - s->urxh = buf[0]; - s->uintsp |= INT_RXD; - s->utrstat |= TRSTATUS_DATA_READY; - } - s5pc1xx_uart_update(s); -} - -static void s5pc1xx_uart_event(void *opaque, int event) -{ - /* TODO: implement this */ -} - -static void s5pc1xx_uart_reset(DeviceState *d) -{ - S5pc1xxUartState *s = - FROM_SYSBUS(S5pc1xxUartState, sysbus_from_qdev(d)); - - s->ulcon = 0; - s->ucon = 0; - s->ufcon = 0; - s->umcon = 0; - s->utrstat = 0x6; - s->uerstat = 0; - s->ufstat = 0; - s->umstat = 0; - s->ubrdiv = 0; - s->udivslot = 0; - s->uintp = 0; - s->uintsp = 0; - s->uintm = 0; - queue_reset(&s->rx); -} - -DeviceState *s5pc1xx_uart_init(target_phys_addr_t base, int instance, - int queue_size, qemu_irq irq, - CharDriverState *chr) -{ - DeviceState *dev = qdev_create(NULL, "s5pc1xx.uart"); - char str[] = "s5pc1xx.uart.00"; - - if (!chr) { - snprintf(str, strlen(str) + 1, "s5pc1xx.uart.%02d", instance % 100); - chr = qemu_chr_open(str, "null", NULL); - } - qdev_prop_set_chr(dev, "chr", chr); - qdev_prop_set_uint32(dev, "queue-size", queue_size); - qdev_prop_set_uint32(dev, "instance", instance); - qdev_init_nofail(dev); - sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); - sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); - return dev; -} - -static int s5pc1xx_uart_init1(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxUartState *s = FROM_SYSBUS(S5pc1xxUartState, dev); - - s5pc1xx_uart_reset(&s->busdev.qdev); - - sysbus_init_irq(dev, &s->irq); - - qemu_chr_add_handlers(s->chr, s5pc1xx_uart_can_receive, - s5pc1xx_uart_receive, s5pc1xx_uart_event, s); - - iomemtype = - cpu_register_io_memory(s5pc1xx_uart_readfn, s5pc1xx_uart_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_UART_REG_MEM_SIZE, iomemtype); - - s5pc1xx_gpio_register_io_memory(GPIO_IDX_UART, s->instance, - s5pc1xx_uart_gpio_readfn, - s5pc1xx_uart_gpio_writefn, NULL, s); - - register_savevm(&dev->qdev, "s5pc1xx.uart", s->instance, 1, - s5pc1xx_uart_save, s5pc1xx_uart_load, s); - - return 0; -} - -static SysBusDeviceInfo s5pc1xx_uart_info = { - .init = s5pc1xx_uart_init1, - .qdev.name = "s5pc1xx.uart", - .qdev.size = sizeof(S5pc1xxUartState), - .qdev.reset = s5pc1xx_uart_reset, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("instance", S5pc1xxUartState, instance, 0), - DEFINE_PROP_UINT32("queue-size", S5pc1xxUartState, rx.size, 16), - DEFINE_PROP_CHR("chr", S5pc1xxUartState, chr), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_uart_register(void) -{ - sysbus_register_withprop(&s5pc1xx_uart_info); -} - -device_init(s5pc1xx_uart_register) diff --git a/hw/s5pc1xx_usb_otg.c b/hw/s5pc1xx_usb_otg.c deleted file mode 100644 index d699933..0000000 --- a/hw/s5pc1xx_usb_otg.c +++ /dev/null @@ -1,812 +0,0 @@ -/* - * S5PC1XX UART Emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Kirill Batuzov - */ - -#include "sysbus.h" -#include "qemu-common.h" -#include "qemu-timer.h" -#include "usb.h" -#include "net.h" -#include "irq.h" -#include "hw.h" -#include "s5pc1xx.h" - - -/* Interrupts */ -#define USB_INT_MODEMIS (1 << 1) /* Mode Mismatch Interrupt */ -#define USB_INT_OTGINT (1 << 2) /* OTG Interrupt */ -#define USB_INT_SOF (1 << 3) /* Start of (micro) Frame */ -#define USB_INT_RXFLVL (1 << 4) /* RxFIFO Non-Empty */ -#define USB_INT_NPTXFEMP (1 << 5) /* Non-periodic TxFIFO Empty */ -#define USB_INT_GINNAKEFF (1 << 6) /* Global IN Non-periodic NAK Effective */ -#define USB_INT_GOUTNAKEFF (1 << 7) /* Global OUT NAK Effective */ -#define USB_INT_ERLYSUSP (1 << 10) /* Early Suspend */ -#define USB_INT_USBSUSP (1 << 11) /* USB Suspend */ -#define USB_INT_USBRST (1 << 12) /* USB Reset */ -#define USB_INT_ENUMDONE (1 << 13) /* Enumeration Done */ -#define USB_INT_ISOUTDROP (1 << 14) /* Isochronous OUT Packet Dropped */ -#define USB_INT_EOPF (1 << 15) /* End of Periodic Frame */ -#define USB_INT_IEPINT (1 << 18) /* IN Endpoints Interrupt */ -#define USB_INT_OEPINT (1 << 19) /* OUT Endpoints Interrupt */ -#define USB_INT_INCOMPLISOIN \ - (1 << 20) /* Incomplete Isochronous IN Transfer */ -#define USB_INT_INCOMPLISOOUT \ - (1 << 21) /* Incomplete Isochronous OUT Transfer */ -#define USB_INT_FETSUSP (1 << 22) /* Data Fetch Suspended */ -//#define USB_INT_PRTINT (1 << 24) /* Host Port Interrupt */ -//#define USB_INT_HCHINT (1 << 25) /* Host Channels Interrupt */ -#define USB_INT_PTXFEMP (1 << 26) /* Periodic TxFIFO Empty */ -#define USB_INT_CONIDSTSCHNG \ - (1 << 28) /* Connector ID Status Change */ -#define USB_INT_DISCONINT (1 << 29) /* Disconnect Detected Interrupt */ -#define USB_INT_SESSREQINT (1 << 30) /* New Session Detected Interrupt */ -#define USB_INT_WKUPINT (1 << 31) /* Resume Interrupt */ - -#define EP_INT_XFERCOMPL (1 << 0) /* Transfer complete */ -#define EP_INT_EPDISABLED (1 << 1) /* Endpoint disabled */ -#define EP_INT_AHBERR (1 << 2) /* AHB error */ -#define EP_INT_SETUP (1 << 3) /* [OUT] Setup phase done */ -#define EP_INT_TIMEOUT (1 << 3) /* [IN] Timeout */ -#define EP_INT_OUTTKNEPDIS (1 << 4) /* [OUT] Token Received When EP Disabled */ -#define EP_INT_INTKNFIFOEMP (1 << 4) /* [IN] Token Received When FIFO is Empty */ -#define EP_INT_STSPHSERCVD (1 << 5) /* [OUT] Status Phase Received For Control Write */ -#define EP_INT_INTTKNEPMIS (1 << 5) /* [IN] Token Received With EP Missmatch */ -#define EP_INT_BACK2BACK (1 << 6) /* [OUT] Back-to-Back SETUP Packets Receive */ -#define EP_INT_INEPNAKEFF (1 << 6) /* [IN] Endpoint NAK Effective */ -#define EP_INT_TXFEMP (1 << 7) /* Transmit FIFO Empty */ -#define EP_INT_OUTPKTERR (1 << 8) /* [OUT] Packet Error */ -#define EP_INT_TXFIFOUNDRN (1 << 8) /* [IN] FIFO Underrun */ -#define EP_INT_BNAINTR (1 << 9) /* Buffer not Available */ - - -#define OTG_EP_DIR_IN 0x80 -#define OTG_EP_DIR_OUT 0 - -#define OTG_EP_ENABLE (1U << 31) -#define OTG_EP_DISABLE (1 << 30) - -#define OTG_EP_COUNT 16 - - -typedef enum { - OTG_STATE_START = 0, - OTG_STATE_RESET, - OTG_STATE_SPEEDDETECT, - OTG_STATE_SETCONFIG_S, - OTG_STATE_SETCONFIG_W, - OTG_STATE_SETCONFIG_D, - OTG_STATE_SETIFACE_S, - OTG_STATE_SETIFACE_W, - OTG_STATE_SETIFACE_D, - OTG_STATE_OPERATIONAL -} OtgLogicalState; - -typedef struct S5pc1xxUsbOtgEndPoint { - uint32_t n; - uint32_t ctrl; - uint32_t interrupt; - uint32_t transfer_size; - uint32_t dma_addr; - uint32_t dma_buf; - uint32_t in_fifo_size; - - uint8_t dir; - - struct S5pc1xxUsbOtgState *parent; -} S5pc1xxUsbOtgEndPoint; - -typedef struct S5pc1xxUsbOtgState { - SysBusDevice busdev; - - struct S5pc1xxPhyState { - uint32_t power; - uint32_t clock; - uint32_t reset; - uint32_t tune0; - uint32_t tune1; - } phy; - - uint32_t gotg_ctl; - uint32_t gotg_int; - uint32_t gahb_cfg; - uint32_t gusb_cfg; - uint32_t grst_ctl; - uint32_t gint_sts; - uint32_t gint_msk; - uint32_t grx_stsr; - uint32_t grx_stsp; - uint32_t grx_fsiz; - uint32_t gnptx_fsiz; - uint32_t gnptx_sts; - uint32_t hnptx_fsiz; - uint32_t daint_sts; - uint32_t daint_msk; - uint32_t diep_msk; - uint32_t doep_msk; - - S5pc1xxUsbOtgEndPoint ep_in[OTG_EP_COUNT]; - S5pc1xxUsbOtgEndPoint ep_out[OTG_EP_COUNT]; - - OtgLogicalState state; - - NICState *nic; - NICConf conf; - qemu_irq irq; - uint8_t buf[1600]; - uint32_t buf_size; - uint8_t buf_full; -} S5pc1xxUsbOtgState; - - -static const uint8_t otg_setup_packet[] = { - 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00 -}; -static const uint8_t otg_setup_iface[] = { - 0x01, 0x0B, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00 -}; -static const uint8_t otg_setup_config[] = { - 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static void s5pc1xx_usb_otg_update_irq(S5pc1xxUsbOtgState *s) -{ - if (s->gint_sts & s->gint_msk) { - qemu_irq_raise(s->irq); - } else { - qemu_irq_lower(s->irq); - } -} - -static void s5pc1xx_usb_otg_initial_reset(DeviceState *d) -{ - S5pc1xxUsbOtgState *s = - FROM_SYSBUS(S5pc1xxUsbOtgState, sysbus_from_qdev(d)); - int i; - - s->phy.power = 0x000001F9; - s->phy.clock = 0x00000000; - s->phy.reset = 0x00000009; /* TODO: I believe it should be 0 */ - s->phy.tune0 = 0x000919B3; - s->phy.tune1 = 0x000919B3; - - s->gotg_ctl = 0x00010000; - s->gotg_int = 0x00000000; - s->gahb_cfg = 0x00000000; - s->gusb_cfg = 0x00001408; - s->grst_ctl = 0x80000000; - s->gint_sts = 0x04000020; - s->gint_msk = 0x00000000; - - for (i = 0; i < OTG_EP_COUNT; i++) { - s->ep_in[i].parent = s; - s->ep_in[i].dir = OTG_EP_DIR_IN; - s->ep_in[i].n = i; - s->ep_out[i].parent = s; - s->ep_out[i].dir = OTG_EP_DIR_OUT; - s->ep_out[i].n = i; - } - - s->state = OTG_STATE_START; - s->buf_full = 0; -} - -static void s5pc1xx_usb_otg_reset(S5pc1xxUsbOtgState *s) -{ - s5pc1xx_usb_otg_initial_reset(&s->busdev.qdev); - s->state = OTG_STATE_RESET; - s->gotg_ctl += 0x000C0000; - s->gint_sts |= USB_INT_USBRST; -} - -static uint32_t s5pc1xx_usb_otg_phy_mm_read(void *opaque, - target_phys_addr_t offset) -{ - S5pc1xxUsbOtgState *s = (S5pc1xxUsbOtgState *)opaque; - - switch (offset) { - case 0x00: - return s->phy.power; - case 0x04: - return s->phy.clock; - case 0x08: - return s->phy.reset; - case 0x20: - return s->phy.tune0; - case 0x24: - return s->phy.tune1; - default: - hw_error("s5pc1xx.usb_otg: bad read offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static void s5pc1xx_usb_otg_phy_mm_write(void *opaque, target_phys_addr_t offset, - uint32_t val) -{ - S5pc1xxUsbOtgState *s = (S5pc1xxUsbOtgState *)opaque; - - switch (offset) { - case 0x00: - s->phy.power = val; - break; - case 0x04: - s->phy.clock = val; - break; - case 0x08: - /* TODO: actually reset USB OTG */ - if (val & 0x1f) { - s5pc1xx_usb_otg_reset(s); - s->gint_sts |= USB_INT_USBRST; - s5pc1xx_usb_otg_update_irq(s); - } - break; - case 0x20: - s->phy.tune0 = val; - break; - case 0x24: - s->phy.tune1 = val; - break; - default: - hw_error("s5pc1xx.usb_otg: bad write offset 0x" TARGET_FMT_plx "\n", - offset); - } -} - -static void s5pc1xx_usb_otg_ep_update_irq(S5pc1xxUsbOtgEndPoint *s) -{ - if (s->interrupt) { - if (s->dir == OTG_EP_DIR_IN) { - s->parent->daint_sts |= (1 << s->n); - if (s->parent->daint_sts & s->parent->daint_msk & 0xffff) { - s->parent->gint_sts |= USB_INT_IEPINT; - } else { - s->parent->gint_sts &= ~USB_INT_IEPINT; - } - } else { - s->parent->daint_sts |= (1 << (s->n + 16)); - if (s->parent->daint_sts & s->parent->daint_msk & 0xffff0000) { - s->parent->gint_sts |= USB_INT_OEPINT; - } else { - s->parent->gint_sts &= ~USB_INT_OEPINT; - } - } - } else { - if (s->dir == OTG_EP_DIR_IN) { - s->parent->daint_sts &= ~(1 << s->n); - if (s->parent->daint_sts & s->parent->daint_msk & 0xffff) { - s->parent->gint_sts |= USB_INT_IEPINT; - } else { - s->parent->gint_sts &= ~USB_INT_IEPINT; - } - } else { - s->parent->daint_sts &= ~(1 << (s->n + 16)); - if (s->parent->daint_sts & s->parent->daint_msk & 0xffff0000) { - s->parent->gint_sts |= USB_INT_OEPINT; - } else { - s->parent->gint_sts &= ~USB_INT_OEPINT; - } - } - } - s5pc1xx_usb_otg_update_irq(s->parent); -} - -static void s5pc1xx_usb_otg_act(S5pc1xxUsbOtgState *s) -{ - switch (s->state) { - case OTG_STATE_START: - case OTG_STATE_RESET: - case OTG_STATE_SPEEDDETECT: - break; - case OTG_STATE_SETCONFIG_S: - if (s->ep_out[0].ctrl & OTG_EP_ENABLE) { - s->state = OTG_STATE_SETCONFIG_W; - cpu_physical_memory_write(s->ep_out[0].dma_addr, - otg_setup_config, 8); - s->ep_out[0].ctrl &= ~OTG_EP_ENABLE; - s->ep_out[0].interrupt |= EP_INT_SETUP|EP_INT_XFERCOMPL; - s5pc1xx_usb_otg_ep_update_irq(&s->ep_out[0]); - } - break; - case OTG_STATE_SETIFACE_S: - if (s->ep_out[0].ctrl & OTG_EP_ENABLE) { - s->state = OTG_STATE_SETIFACE_W; - cpu_physical_memory_write(s->ep_out[0].dma_addr, - otg_setup_iface, 8); - s->ep_out[0].ctrl &= ~OTG_EP_ENABLE; - s->ep_out[0].interrupt |= EP_INT_SETUP|EP_INT_XFERCOMPL; - s5pc1xx_usb_otg_ep_update_irq(&s->ep_out[0]); - } - break; - default: - break; - } -} - -static void s5pc1xx_usb_otg_data_tx(S5pc1xxUsbOtgEndPoint *s) -{ - uint8_t buf[1600]; - uint32_t size = s->transfer_size & 0x7ffff; - - cpu_physical_memory_read(s->dma_addr, buf, size); - qemu_send_packet(&s->parent->nic->nc, buf, size); - s->interrupt |= EP_INT_XFERCOMPL|EP_INT_TXFEMP; - s5pc1xx_usb_otg_ep_update_irq(s); -} - -static void s5pc1xx_usb_otg_data_rx(S5pc1xxUsbOtgEndPoint *s) -{ - uint32_t size = s->parent->buf_size; - - if (s->parent->buf_size > (s->transfer_size & 0x7ffff)) { - s->parent->buf_full = 0; - /* Packet dropped */ - return ; - } - cpu_physical_memory_write(s->dma_addr, s->parent->buf, size); - s->dma_buf = s->dma_addr + size; - s->transfer_size -= size; - s->ctrl &= ~OTG_EP_ENABLE; - s->interrupt |= EP_INT_XFERCOMPL; - s->parent->buf_full = 0; - s5pc1xx_usb_otg_ep_update_irq(s); -} - -static uint32_t s5pc1xx_usb_otg_ep_read(S5pc1xxUsbOtgEndPoint *s, - target_phys_addr_t addr) -{ - switch (addr) { - case 0x00: - return s->ctrl; - case 0x08: - return s->interrupt; - case 0x10: - return s->transfer_size; - case 0x14: - return s->dma_addr; - case 0x1C: - return s->dma_buf; - default: - hw_error("s5pc1xx.usb_otg: bad write offset 0x" TARGET_FMT_plx "\n", - addr); - } -} - -static uint32_t s5pc1xx_usb_otg_ep_write(S5pc1xxUsbOtgEndPoint *s, - target_phys_addr_t addr, uint32_t val) -{ - switch (addr) { - case 0x00: - if ((val & OTG_EP_DISABLE) && (s->ctrl & OTG_EP_ENABLE)) { - s->ctrl &= ~OTG_EP_ENABLE; - val &= ~OTG_EP_DISABLE; - s->interrupt |= EP_INT_EPDISABLED; - s5pc1xx_usb_otg_ep_update_irq(s); - } - val &= ~OTG_EP_DISABLE; - if (val & OTG_EP_ENABLE) { - s5pc1xx_usb_otg_act(s->parent); - if (s->n == 0 && s->dir == OTG_EP_DIR_IN) { - s->interrupt |= EP_INT_XFERCOMPL|EP_INT_TXFEMP; - if (s->parent->state == OTG_STATE_SETCONFIG_W) { - s->parent->state = OTG_STATE_SETIFACE_S; - } else if (s->parent->state == OTG_STATE_SETIFACE_W) { - s->parent->state = OTG_STATE_OPERATIONAL; - } - s5pc1xx_usb_otg_ep_update_irq(s); - } - if (s->n != 0 && s->dir == OTG_EP_DIR_IN) { - s5pc1xx_usb_otg_data_tx(s); - val &= ~OTG_EP_ENABLE; - } - if (s->n != 0 && s->dir == OTG_EP_DIR_OUT && - s->parent->buf_full == 1) { - s5pc1xx_usb_otg_data_rx(s); - val &= ~OTG_EP_ENABLE; - } - } - val &= ~(0xC << 24); /* TODO: handle NAK? */ - s->ctrl = val; - /* TODO: handle control */ - break; - case 0x08: - s->interrupt &= ~val; - s5pc1xx_usb_otg_ep_update_irq(s); - break; - case 0x10: - s->transfer_size = val; - break; - case 0x14: - s->dma_addr = val; - break; - default: - hw_error("s5pc1xx.usb_otg: bad write offset 0x" TARGET_FMT_plx "\n", - addr); - } - return 0; -} - -static uint32_t s5pc1xx_usb_otg_read(void *opaque, target_phys_addr_t addr) -{ - S5pc1xxUsbOtgState *s = (S5pc1xxUsbOtgState *)opaque; - - if (addr >= 0x100000 && addr < 0x100028) { - return s5pc1xx_usb_otg_phy_mm_read(opaque, addr - 0x100000); - } - - switch (addr) { - case 0x00: - return s->gotg_ctl; - case 0x04: - return s->gotg_int; - case 0x08: - return s->gahb_cfg; - case 0x0C: - return s->gusb_cfg; - case 0x10: - return s->grst_ctl; - case 0x14: - return s->gint_sts; - case 0x18: - return s->gint_msk; - case 0x1C: - return s->grx_stsr; - case 0x20: - return s->grx_stsp; - case 0x24: - return s->grx_fsiz; - case 0x28: - return s->gnptx_fsiz; - case 0x2C: - return s->gnptx_sts; - case 0x30: - return s->hnptx_fsiz; - case 0x100 ... 0x13C: - return s->ep_in[(addr - 0x100) >> 2].in_fifo_size; - case 0x810: - return s->diep_msk; - case 0x814: - return s->doep_msk; - case 0x818: - return s->daint_sts; - case 0x81C: - return s->daint_msk; - case 0x900 ... 0xAFC: - addr -= 0x900; - return s5pc1xx_usb_otg_ep_read(&s->ep_in[addr >> 5], addr & 0x1f); - case 0xB00 ... 0xCFC: - addr -= 0xB00; - return s5pc1xx_usb_otg_ep_read(&s->ep_out[addr >> 5], addr & 0x1f); - } - return 0; -} - -static void s5pc1xx_usb_otg_write(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - int i; - S5pc1xxUsbOtgState *s = (S5pc1xxUsbOtgState *)opaque; - - if (addr >= 0x100000 && addr < 0x100028) { - s5pc1xx_usb_otg_phy_mm_write(opaque, addr - 0x100000, val); - return; - } - - switch (addr) { - case 0x00: - s->gotg_ctl = val; - break; - case 0x04: - s->gotg_int &= ~val; - s5pc1xx_usb_otg_update_irq(s); - break; - case 0x08: - s->gahb_cfg = val; - break; - case 0x0C: - s->gusb_cfg = val; - break; - case 0x10: - if (val & 1) { - s5pc1xx_usb_otg_reset(s); - s->gint_sts |= USB_INT_USBRST; - s->state = OTG_STATE_RESET; - s5pc1xx_usb_otg_update_irq(s); - } else if (val & 0x0f) { - s->gint_sts |= USB_INT_USBRST; - s->state = OTG_STATE_RESET; - s5pc1xx_usb_otg_update_irq(s); - } - s->grst_ctl = val & (~0x3f); - s5pc1xx_usb_otg_update_irq(s); - break; - case 0x14: - val &= ~(7 << 24); - val &= ~(3 << 18); - val &= ~(0xf << 4); - val &= ~0x5; - s->gint_sts &= ~val; - if (val == 0x1000) { - s->gint_sts |= USB_INT_ENUMDONE; - s->state = OTG_STATE_SPEEDDETECT; - s5pc1xx_usb_otg_act(s); - } - if (val == USB_INT_ENUMDONE) { - s->state = OTG_STATE_SETCONFIG_S; - s5pc1xx_usb_otg_act(s); - } - s5pc1xx_usb_otg_update_irq(s); - break; - case 0x18: - s->gint_msk = val; - break; - case 0x24: - s->grx_fsiz = val; - break; - case 0x28: - s->gnptx_fsiz = val; - break; - case 0x30: - s->hnptx_fsiz = val; - break; - case 0x100 ... 0x13C: - s->ep_in[(addr - 0x100 ) >> 2].in_fifo_size = val; - break; - case 0x810: - s->diep_msk = val; - for (i = 0; i < OTG_EP_COUNT; i++) { - s5pc1xx_usb_otg_ep_update_irq(&s->ep_in[i]); - } - break; - case 0x814: - s->doep_msk = val; - for (i = 0; i < OTG_EP_COUNT; i++) { - s5pc1xx_usb_otg_ep_update_irq(&s->ep_out[i]); - } - break; - case 0x81C: - s->daint_msk = val; - if (s->daint_sts & 0xffff & s->daint_msk) { - s->gint_sts |= USB_INT_IEPINT; - } else { - s->gint_sts &= ~USB_INT_IEPINT; - } - if ((s->daint_sts & s->daint_msk) >> 16) { - s->gint_sts |= USB_INT_OEPINT; - } else { - s->gint_sts &= ~USB_INT_OEPINT; - } - s5pc1xx_usb_otg_update_irq(s); - break; - case 0x900 ... 0xAFC: - addr -= 0x900; - s5pc1xx_usb_otg_ep_write(&s->ep_in[addr >> 5], addr & 0x1f, val); - break; - case 0xB00 ... 0xCFC: - addr -= 0xB00; - s5pc1xx_usb_otg_ep_write(&s->ep_out[addr >> 5], addr & 0x1f, val); - break; - } -} - -static CPUReadMemoryFunc * const s5pc1xx_usb_otg_readfn[] = { - s5pc1xx_usb_otg_read, - s5pc1xx_usb_otg_read, - s5pc1xx_usb_otg_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_usb_otg_writefn[] = { - s5pc1xx_usb_otg_write, - s5pc1xx_usb_otg_write, - s5pc1xx_usb_otg_write -}; - -static void s5pc1xx_usb_otg_save(QEMUFile *f, void *opaque) -{ - S5pc1xxUsbOtgState *s = (S5pc1xxUsbOtgState *)opaque; - int i; - - qemu_put_be32s(f, &s->phy.power); - qemu_put_be32s(f, &s->phy.clock); - qemu_put_be32s(f, &s->phy.reset); - qemu_put_be32s(f, &s->phy.tune0); - qemu_put_be32s(f, &s->phy.tune1); - - qemu_put_be32s(f, &s->gotg_ctl); - qemu_put_be32s(f, &s->gotg_int); - qemu_put_be32s(f, &s->gahb_cfg); - qemu_put_be32s(f, &s->gusb_cfg); - qemu_put_be32s(f, &s->grst_ctl); - qemu_put_be32s(f, &s->gint_sts); - qemu_put_be32s(f, &s->gint_msk); - qemu_put_be32s(f, &s->grx_stsr); - qemu_put_be32s(f, &s->grx_stsp); - qemu_put_be32s(f, &s->grx_fsiz); - qemu_put_be32s(f, &s->gnptx_fsiz); - qemu_put_be32s(f, &s->gnptx_sts); - qemu_put_be32s(f, &s->hnptx_fsiz); - qemu_put_be32s(f, &s->daint_sts); - qemu_put_be32s(f, &s->daint_msk); - qemu_put_be32s(f, &s->diep_msk); - qemu_put_be32s(f, &s->doep_msk); - qemu_put_byte (f, (uint8_t) s->state); - - for (i = 0; i < OTG_EP_COUNT; i++) { - qemu_put_be32s(f, &s->ep_in[i].ctrl); - qemu_put_be32s(f, &s->ep_in[i].interrupt); - qemu_put_be32s(f, &s->ep_in[i].transfer_size); - qemu_put_be32s(f, &s->ep_in[i].dma_addr); - qemu_put_be32s(f, &s->ep_in[i].dma_buf); - qemu_put_be32s(f, &s->ep_in[i].in_fifo_size); - - qemu_put_be32s(f, &s->ep_out[i].ctrl); - qemu_put_be32s(f, &s->ep_out[i].interrupt); - qemu_put_be32s(f, &s->ep_out[i].transfer_size); - qemu_put_be32s(f, &s->ep_out[i].dma_addr); - qemu_put_be32s(f, &s->ep_out[i].dma_buf); - qemu_put_be32s(f, &s->ep_out[i].in_fifo_size); - } - /* FIXME: must the structure below be saved? - * NICState *nic; */ - qemu_put_be32s (f, &s->buf_size); - qemu_put_buffer(f, s->buf, s->buf_size); - qemu_put_8s (f, &s->buf_full); -} - -static int s5pc1xx_usb_otg_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxUsbOtgState *s = (S5pc1xxUsbOtgState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - qemu_get_be32s(f, &s->phy.power); - qemu_get_be32s(f, &s->phy.clock); - qemu_get_be32s(f, &s->phy.reset); - qemu_get_be32s(f, &s->phy.tune0); - qemu_get_be32s(f, &s->phy.tune1); - - qemu_get_be32s(f, &s->gotg_ctl); - qemu_get_be32s(f, &s->gotg_int); - qemu_get_be32s(f, &s->gahb_cfg); - qemu_get_be32s(f, &s->gusb_cfg); - qemu_get_be32s(f, &s->grst_ctl); - qemu_get_be32s(f, &s->gint_sts); - qemu_get_be32s(f, &s->gint_msk); - qemu_get_be32s(f, &s->grx_stsr); - qemu_get_be32s(f, &s->grx_stsp); - qemu_get_be32s(f, &s->grx_fsiz); - qemu_get_be32s(f, &s->gnptx_fsiz); - qemu_get_be32s(f, &s->gnptx_sts); - qemu_get_be32s(f, &s->hnptx_fsiz); - qemu_get_be32s(f, &s->daint_sts); - qemu_get_be32s(f, &s->daint_msk); - qemu_get_be32s(f, &s->diep_msk); - qemu_get_be32s(f, &s->doep_msk); - s->state = qemu_get_byte(f); - - for (i = 0; i < OTG_EP_COUNT; i++) { - qemu_get_be32s(f, &s->ep_in[i].ctrl); - qemu_get_be32s(f, &s->ep_in[i].interrupt); - qemu_get_be32s(f, &s->ep_in[i].transfer_size); - qemu_get_be32s(f, &s->ep_in[i].dma_addr); - qemu_get_be32s(f, &s->ep_in[i].dma_buf); - qemu_get_be32s(f, &s->ep_in[i].in_fifo_size); - - qemu_get_be32s(f, &s->ep_out[i].ctrl); - qemu_get_be32s(f, &s->ep_out[i].interrupt); - qemu_get_be32s(f, &s->ep_out[i].transfer_size); - qemu_get_be32s(f, &s->ep_out[i].dma_addr); - qemu_get_be32s(f, &s->ep_out[i].dma_buf); - qemu_get_be32s(f, &s->ep_out[i].in_fifo_size); - } - /* FIXME: NICState *nic; */ - qemu_get_be32s (f, &s->buf_size); - qemu_get_buffer(f, s->buf, s->buf_size); - qemu_get_8s (f, &s->buf_full); - - return 0; -} - -static int s5pc1xx_usb_otg_can_receive(VLANClientState *nc) -{ - S5pc1xxUsbOtgState *s = (DO_UPCAST(NICState, nc, nc))->opaque; - - return !s->buf_full; -} - -static ssize_t s5pc1xx_usb_otg_receive(VLANClientState *nc, const uint8_t *buf, - size_t size) -{ - S5pc1xxUsbOtgState *s = (DO_UPCAST(NICState, nc, nc))->opaque; - int i; - - s->buf_full = 1; - s->buf_size = size; - memcpy(s->buf, buf, size); - for (i = 0; i < OTG_EP_COUNT; i++) { - if (s->ep_out[i].ctrl & OTG_EP_ENABLE) { - s5pc1xx_usb_otg_data_rx(&s->ep_out[i]); - break; - } - } - return size; -} - -static void s5pc1xx_usb_otg_cleanup(VLANClientState *nc) -{ - S5pc1xxUsbOtgState *s = (DO_UPCAST(NICState, nc, nc))->opaque; - - s->nic = NULL; -} - -static NetClientInfo net_s5pc1xx_usb_otg_info = { - .type = NET_CLIENT_TYPE_NIC, - .size = sizeof(NICState), - .can_receive = s5pc1xx_usb_otg_can_receive, - .receive = s5pc1xx_usb_otg_receive, - .cleanup = s5pc1xx_usb_otg_cleanup, -}; - -static int s5pc1xx_usb_otg_init1(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxUsbOtgState *s = FROM_SYSBUS(S5pc1xxUsbOtgState, dev); - - iomemtype = - cpu_register_io_memory(s5pc1xx_usb_otg_readfn, - s5pc1xx_usb_otg_writefn, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x100030, iomemtype); - sysbus_init_irq(dev, &s->irq); - - qemu_macaddr_default_if_unset(&s->conf.macaddr); - - s5pc1xx_usb_otg_initial_reset(&s->busdev.qdev); - - s->nic = qemu_new_nic(&net_s5pc1xx_usb_otg_info, &s->conf, - dev->qdev.info->name, dev->qdev.id, s); - qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); - - register_savevm(&dev->qdev, "s5pc1xx.usb.otg", -1, 1, - s5pc1xx_usb_otg_save, s5pc1xx_usb_otg_load, s); - - return 0; -} - -static SysBusDeviceInfo s5pc1xx_usb_otg_info = { - .init = s5pc1xx_usb_otg_init1, - .qdev.name = "s5pc1xx.usb.otg", - .qdev.size = sizeof(S5pc1xxUsbOtgState), - .qdev.reset = s5pc1xx_usb_otg_initial_reset, - .qdev.props = (Property[]) { - DEFINE_NIC_PROPERTIES(S5pc1xxUsbOtgState, conf), - DEFINE_PROP_END_OF_LIST(), - } -}; - -static void s5pc1xx_usb_otg_register_devices(void) -{ - sysbus_register_withprop(&s5pc1xx_usb_otg_info); -} - -/* Legacy helper function. Should go away when machine config files are - implemented. */ -void s5pc1xx_usb_otg_init(NICInfo *nd, target_phys_addr_t base, qemu_irq irq) -{ - DeviceState *dev; - SysBusDevice *s; - - qemu_check_nic_model(nd, "s5pc1xx-usb-otg"); - dev = qdev_create(NULL, "s5pc1xx.usb.otg"); - qdev_set_nic_properties(dev, nd); - qdev_init_nofail(dev); - s = sysbus_from_qdev(dev); - sysbus_mmio_map(s, 0, base); - sysbus_connect_irq(s, 0, irq); -} - -device_init(s5pc1xx_usb_otg_register_devices) diff --git a/hw/s5pc1xx_wdt.c b/hw/s5pc1xx_wdt.c deleted file mode 100644 index 8052960..0000000 --- a/hw/s5pc1xx_wdt.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Watchdog Timer for S5C110-based board emulation - * - * Copyright (c) 2009 Samsung Electronics. - * Contributed by Vladimir Monakhov - */ - -#include "s5pc1xx.h" -#include "qemu-timer.h" -#include "sysbus.h" -#include "sysemu.h" - - -#define WTCON 0x00 /* R/W Watchdog Timer Control Register */ -#define WTDAT 0x04 /* R/W Watchdog Timer Data Register */ -#define WTCNT 0x08 /* R/W Watchdog Timer Count Register */ -#define WTCLRINT 0x0C /* W Watchdog Timer Interrupt Clear Register */ - -#define PRESCALER_SHIFT (8) -#define WDT_EN (1 << 5) -#define CLK_SEL_SHIFT (3) -#define INT_EN (1 << 2) -#define RESET_EN (1 << 0) - -#define S5PC1XX_WDT_REG_MEM_SIZE 0x14 - - -typedef struct S5pc1xxWDTState { - SysBusDevice busdev; - - qemu_irq irq; - uint32_t regs[WTCNT + 1]; - - QEMUTimer *wdt_timer; - uint32_t freq_out; - uint64_t ticnto_last_tick; -} S5pc1xxWDTState; - - -/* Timer step */ -static void s5pc1xx_wdt_tick(void *opaque) -{ - S5pc1xxWDTState *s = (S5pc1xxWDTState *)opaque; - uint64_t next_wdt_time; - - if (s->regs[WTCON] & WDT_EN) { - if (s->regs[WTCON] & INT_EN) - qemu_irq_raise(s->irq); - - if (s->regs[WTCON] & RESET_EN) { - qemu_system_reset_request(); - } - - s->ticnto_last_tick = qemu_get_clock(vm_clock); - next_wdt_time = s->ticnto_last_tick + - muldiv64(s->regs[WTDAT], get_ticks_per_sec(), s->freq_out); - qemu_mod_timer(s->wdt_timer, next_wdt_time); - } else { - s->ticnto_last_tick = 0; - qemu_del_timer(s->wdt_timer); - } -} - -/* Perform timer step, update frequency and compute next time for update */ -static void s5pc1xx_wdt_update(S5pc1xxWDTState *s) -{ - short div_fac; - short prescaler; - S5pc1xxClk clk; - - clk = s5pc1xx_findclk("pclk_66"); - div_fac = 16 << (s->regs[WTCON] >> CLK_SEL_SHIFT & 0x3); - prescaler = s->regs[WTCON] >> PRESCALER_SHIFT & 0xff; - - s->freq_out = s5pc1xx_clk_getrate(clk) / (prescaler + 1) / div_fac; - - if (!s->freq_out) - hw_error("s5pc1xx.wdt: timer update input frequency is zero\n"); -} - -/* WDT read */ -static uint32_t s5pc1xx_wdt_read(void *opaque, target_phys_addr_t offset) -{ - S5pc1xxWDTState *s = (S5pc1xxWDTState *)opaque; - - /* check if offset is correct, WTCLRINT is not for read */ - if (offset <= WTCNT) { - if (offset == WTCNT) { - if (s->freq_out && s->ticnto_last_tick && s->regs[WTDAT]) { - s->regs[WTCNT] = s->regs[WTDAT] - - muldiv64(qemu_get_clock(vm_clock) - s->ticnto_last_tick, - s->freq_out, get_ticks_per_sec()) % - s->regs[WTDAT]; - } else - s->regs[WTCNT] = 0; - } - return s->regs[offset]; - } else { - hw_error("s5pc1xx.wdt: bad read offset " TARGET_FMT_plx "\n", offset); - } -} - -/* WDT write */ -static void s5pc1xx_wdt_write(void *opaque, target_phys_addr_t offset, - uint32_t value) -{ - S5pc1xxWDTState *s = (S5pc1xxWDTState *)opaque; - - switch (offset) { - case WTCON: - if ((value & WDT_EN) > (s->regs[WTCON] & WDT_EN)) { - s->regs[WTCON] = value; - s5pc1xx_wdt_update(s); - s5pc1xx_wdt_tick(s); - } - s->regs[WTCON] = value; - s5pc1xx_wdt_update(s); - break; - case WTDAT: - case WTCNT: - s->regs[offset] = value; - break; - case WTCLRINT: - qemu_irq_lower(s->irq); - break; - default: - hw_error("s5pc1xx.wdt: bad write offset " TARGET_FMT_plx "\n", offset); - } -} - -static CPUReadMemoryFunc * const s5pc1xx_wdt_readfn[] = { - s5pc1xx_wdt_read, - s5pc1xx_wdt_read, - s5pc1xx_wdt_read -}; - -static CPUWriteMemoryFunc * const s5pc1xx_wdt_writefn[] = { - s5pc1xx_wdt_write, - s5pc1xx_wdt_write, - s5pc1xx_wdt_write -}; - -static void s5pc1xx_wdt_save(QEMUFile *f, void *opaque) -{ - S5pc1xxWDTState *s = (S5pc1xxWDTState *)opaque; - int i; - - for (i = 0; i <= WTCNT; i++) { - qemu_put_be32s(f, &s->regs[i]); - } - - qemu_put_be64s(f, &s->ticnto_last_tick); - qemu_put_be32s(f, &s->freq_out); - qemu_put_timer(f, s->wdt_timer); -} - -static int s5pc1xx_wdt_load(QEMUFile *f, void *opaque, int version_id) -{ - S5pc1xxWDTState *s = (S5pc1xxWDTState *)opaque; - int i; - - if (version_id != 1) { - return -EINVAL; - } - - for (i = 0; i <= WTCNT; i++) { - qemu_get_be32s(f, &s->regs[i]); - } - - qemu_get_be64s(f, &s->ticnto_last_tick); - qemu_get_be32s(f, &s->freq_out); - qemu_get_timer(f, s->wdt_timer); - - return 0; -} - -/* WDT init */ -static int s5pc1xx_wdt_init(SysBusDevice *dev) -{ - int iomemtype; - S5pc1xxWDTState *s = FROM_SYSBUS(S5pc1xxWDTState, dev); - - sysbus_init_irq(dev, &s->irq); - iomemtype = - cpu_register_io_memory(s5pc1xx_wdt_readfn, s5pc1xx_wdt_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, S5PC1XX_WDT_REG_MEM_SIZE, iomemtype); - - s->wdt_timer = qemu_new_timer(vm_clock, s5pc1xx_wdt_tick, s); - - s->regs[WTDAT] = 0x00008000; - s->regs[WTCNT] = 0x00008000; - /* initially WDT is stopped */ - s5pc1xx_wdt_write(s, WTCON, 0x00008001); - - register_savevm(&dev->qdev, "s5pc1xx.wdt", -1, 1, - s5pc1xx_wdt_save, s5pc1xx_wdt_load, s); - - return 0; -} - -static void s5pc1xx_wdt_register_devices(void) -{ - sysbus_register_dev("s5pc1xx.wdt", sizeof(S5pc1xxWDTState), - s5pc1xx_wdt_init); -} - -device_init(s5pc1xx_wdt_register_devices) diff --git a/hw/sb16.c b/hw/sb16.c index c9d37ad..f0658ac 100644 --- a/hw/sb16.c +++ b/hw/sb16.c @@ -766,7 +766,7 @@ static void complete (SB16State *s) if (s->aux_ts) { qemu_mod_timer ( s->aux_ts, - qemu_get_clock (vm_clock) + ticks + qemu_get_clock_ns (vm_clock) + ticks ); } } @@ -1341,12 +1341,21 @@ static const VMStateDescription vmstate_sb16 = { } }; +static const MemoryRegionPortio sb16_ioport_list[] = { + { 4, 1, 1, .write = mixer_write_indexb }, + { 4, 1, 2, .write = mixer_write_indexw }, + { 5, 1, 1, .read = mixer_read, .write = mixer_write_datab }, + { 6, 1, 1, .read = dsp_read, .write = dsp_write }, + { 10, 1, 1, .read = dsp_read }, + { 12, 1, 1, .write = dsp_write }, + { 12, 4, 1, .read = dsp_read }, + PORTIO_END_OF_LIST(), +}; + + static int sb16_initfn (ISADevice *dev) { - static const uint8_t dsp_write_ports[] = {0x6, 0xc}; - static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf}; SB16State *s; - int i; s = DO_UPCAST (SB16State, dev, dev); @@ -1361,27 +1370,12 @@ static int sb16_initfn (ISADevice *dev) s->csp_regs[9] = 0xf8; reset_mixer (s); - s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s); + s->aux_ts = qemu_new_timer_ns (vm_clock, aux_timer, s); if (!s->aux_ts) { dolog ("warning: Could not create auxiliary timer\n"); } - for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) { - register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s); - isa_init_ioport(dev, s->port + dsp_write_ports[i]); - } - - for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) { - register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s); - isa_init_ioport(dev, s->port + dsp_read_ports[i]); - } - - register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s); - register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s); - isa_init_ioport(dev, s->port + 0x4); - register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s); - register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s); - isa_init_ioport(dev, s->port + 0x5); + isa_register_portio_list (dev, s->port, sb16_ioport_list, s, "sb16"); DMA_register_channel (s->hdma, SB_read_DMA, s); DMA_register_channel (s->dma, SB_read_DMA, s); diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index ceeb4ec..64e709e 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -4,60 +4,134 @@ #include "scsi-defs.h" #include "qdev.h" #include "blockdev.h" +#include "trace.h" static char *scsibus_get_fw_dev_path(DeviceState *dev); +static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf); +static void scsi_req_dequeue(SCSIRequest *req); static struct BusInfo scsi_bus_info = { .name = "SCSI", .size = sizeof(SCSIBus), .get_fw_dev_path = scsibus_get_fw_dev_path, .props = (Property[]) { + DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1), + DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1), DEFINE_PROP_END_OF_LIST(), }, }; static int next_scsi_bus; /* Create a scsi bus, and attach devices to it. */ -void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev, - scsi_completionfn complete) +void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info) { qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL); bus->busnr = next_scsi_bus++; - bus->tcq = tcq; - bus->ndev = ndev; - bus->complete = complete; + bus->info = info; bus->qbus.allow_hotplug = 1; } +static void scsi_dma_restart_bh(void *opaque) +{ + SCSIDevice *s = opaque; + SCSIRequest *req, *next; + + qemu_bh_delete(s->bh); + s->bh = NULL; + + QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { + scsi_req_ref(req); + if (req->retry) { + req->retry = false; + switch (req->cmd.mode) { + case SCSI_XFER_FROM_DEV: + case SCSI_XFER_TO_DEV: + scsi_req_continue(req); + break; + case SCSI_XFER_NONE: + scsi_req_dequeue(req); + scsi_req_enqueue(req); + break; + } + } + scsi_req_unref(req); + } +} + +void scsi_req_retry(SCSIRequest *req) +{ + /* No need to save a reference, because scsi_dma_restart_bh just + * looks at the request list. */ + req->retry = true; +} + +static void scsi_dma_restart_cb(void *opaque, int running, RunState state) +{ + SCSIDevice *s = opaque; + + if (!running) { + return; + } + if (!s->bh) { + s->bh = qemu_bh_new(scsi_dma_restart_bh, s); + qemu_bh_schedule(s->bh); + } +} + static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); + SCSIDevice *d; int rc = -1; - if (dev->id == -1) { - for (dev->id = 0; dev->id < bus->ndev; dev->id++) { - if (bus->devs[dev->id] == NULL) - break; - } + if (dev->channel > bus->info->max_channel) { + error_report("bad scsi channel id: %d", dev->channel); + goto err; } - if (dev->id >= bus->ndev) { + if (dev->id != -1 && dev->id > bus->info->max_target) { error_report("bad scsi device id: %d", dev->id); goto err; } - if (bus->devs[dev->id]) { - qdev_free(&bus->devs[dev->id]->qdev); + if (dev->id == -1) { + int id = -1; + if (dev->lun == -1) { + dev->lun = 0; + } + do { + d = scsi_device_find(bus, dev->channel, ++id, dev->lun); + } while (d && d->lun == dev->lun && id <= bus->info->max_target); + if (id > bus->info->max_target) { + error_report("no free target"); + goto err; + } + dev->id = id; + } else if (dev->lun == -1) { + int lun = -1; + do { + d = scsi_device_find(bus, dev->channel, dev->id, ++lun); + } while (d && d->lun == lun && lun < bus->info->max_lun); + if (lun > bus->info->max_lun) { + error_report("no free lun"); + goto err; + } + dev->lun = lun; + } else { + d = scsi_device_find(bus, dev->channel, dev->id, dev->lun); + if (dev->lun == d->lun && dev != d) { + qdev_free(&d->qdev); + } } - bus->devs[dev->id] = dev; dev->info = info; QTAILQ_INIT(&dev->requests); rc = dev->info->init(dev); - if (rc != 0) { - bus->devs[dev->id] = NULL; + if (rc == 0) { + dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb, + dev); } err: @@ -67,13 +141,13 @@ err: static int scsi_qdev_exit(DeviceState *qdev) { SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); - SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); - assert(bus->devs[dev->id] != NULL); - if (bus->devs[dev->id]->info->destroy) { - bus->devs[dev->id]->info->destroy(bus->devs[dev->id]); + if (dev->vmsentry) { + qemu_del_vm_change_state_handler(dev->vmsentry); + } + if (dev->info->destroy) { + dev->info->destroy(dev); } - bus->devs[dev->id] = NULL; return 0; } @@ -88,7 +162,7 @@ void scsi_qdev_register(SCSIDeviceInfo *info) /* handle legacy '-drive if=scsi,...' cmd line args */ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, - int unit, bool removable) + int unit, bool removable, int bootindex) { const char *driver; DeviceState *dev; @@ -96,6 +170,9 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk"; dev = qdev_create(&bus->qbus, driver); qdev_prop_set_uint32(dev, "scsi-id", unit); + if (bootindex >= 0) { + qdev_prop_set_int32(dev, "bootindex", bootindex); + } if (qdev_prop_exists(dev, "removable")) { qdev_prop_set_bit(dev, "removable", removable); } @@ -115,13 +192,13 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus) int res = 0, unit; loc_push_none(&loc); - for (unit = 0; unit < bus->ndev; unit++) { + for (unit = 0; unit < bus->info->max_target; unit++) { dinfo = drive_get(IF_SCSI, bus->busnr, unit); if (dinfo == NULL) { continue; } qemu_opts_loc_restore(dinfo->opts); - if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false)) { + if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1)) { res = -1; break; } @@ -130,125 +207,560 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus) return res; } -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun) +/* SCSIReqOps implementation for invalid commands. */ + +static int32_t scsi_invalid_command(SCSIRequest *req, uint8_t *buf) +{ + scsi_req_build_sense(req, SENSE_CODE(INVALID_OPCODE)); + scsi_req_complete(req, CHECK_CONDITION); + return 0; +} + +static const struct SCSIReqOps reqops_invalid_opcode = { + .size = sizeof(SCSIRequest), + .send_command = scsi_invalid_command +}; + +/* SCSIReqOps implementation for unit attention conditions. */ + +static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf) +{ + if (req->dev && req->dev->unit_attention.key == UNIT_ATTENTION) { + scsi_req_build_sense(req, req->dev->unit_attention); + } else if (req->bus->unit_attention.key == UNIT_ATTENTION) { + scsi_req_build_sense(req, req->bus->unit_attention); + } + scsi_req_complete(req, CHECK_CONDITION); + return 0; +} + +static const struct SCSIReqOps reqops_unit_attention = { + .size = sizeof(SCSIRequest), + .send_command = scsi_unit_attention +}; + +/* SCSIReqOps implementation for REPORT LUNS and for commands sent to + an invalid LUN. */ + +typedef struct SCSITargetReq SCSITargetReq; + +struct SCSITargetReq { + SCSIRequest req; + int len; + uint8_t buf[2056]; +}; + +static void store_lun(uint8_t *outbuf, int lun) +{ + if (lun < 256) { + outbuf[1] = lun; + return; + } + outbuf[1] = (lun & 255); + outbuf[0] = (lun >> 8) | 0x40; +} + +static bool scsi_target_emulate_report_luns(SCSITargetReq *r) +{ + DeviceState *qdev; + int i, len, n; + int channel, id; + bool found_lun0; + + if (r->req.cmd.xfer < 16) { + return false; + } + if (r->req.cmd.buf[2] > 2) { + return false; + } + channel = r->req.dev->channel; + id = r->req.dev->id; + found_lun0 = false; + n = 0; + QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { + SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); + + if (dev->channel == channel && dev->id == id) { + if (dev->lun == 0) { + found_lun0 = true; + } + n += 8; + } + } + if (!found_lun0) { + n += 8; + } + len = MIN(n + 8, r->req.cmd.xfer & ~7); + if (len > sizeof(r->buf)) { + /* TODO: > 256 LUNs? */ + return false; + } + + memset(r->buf, 0, len); + stl_be_p(&r->buf, n); + i = found_lun0 ? 8 : 16; + QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { + SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); + + if (dev->channel == channel && dev->id == id) { + store_lun(&r->buf[i], dev->lun); + i += 8; + } + } + assert(i == n + 8); + r->len = len; + return true; +} + +static bool scsi_target_emulate_inquiry(SCSITargetReq *r) +{ + assert(r->req.dev->lun != r->req.lun); + if (r->req.cmd.buf[1] & 0x2) { + /* Command support data - optional, not implemented */ + return false; + } + + if (r->req.cmd.buf[1] & 0x1) { + /* Vital product data */ + uint8_t page_code = r->req.cmd.buf[2]; + if (r->req.cmd.xfer < 4) { + return false; + } + + r->buf[r->len++] = page_code ; /* this page */ + r->buf[r->len++] = 0x00; + + switch (page_code) { + case 0x00: /* Supported page codes, mandatory */ + { + int pages; + pages = r->len++; + r->buf[r->len++] = 0x00; /* list of supported pages (this page) */ + r->buf[pages] = r->len - pages - 1; /* number of pages */ + break; + } + default: + return false; + } + /* done with EVPD */ + assert(r->len < sizeof(r->buf)); + r->len = MIN(r->req.cmd.xfer, r->len); + return true; + } + + /* Standard INQUIRY data */ + if (r->req.cmd.buf[2] != 0) { + return false; + } + + /* PAGE CODE == 0 */ + if (r->req.cmd.xfer < 5) { + return -1; + } + + r->len = MIN(r->req.cmd.xfer, 36); + memset(r->buf, 0, r->len); + if (r->req.lun != 0) { + r->buf[0] = TYPE_NO_LUN; + } else { + r->buf[0] = TYPE_NOT_PRESENT | TYPE_INACTIVE; + r->buf[2] = 5; /* Version */ + r->buf[3] = 2 | 0x10; /* HiSup, response data format */ + r->buf[4] = r->len - 5; /* Additional Length = (Len - 1) - 4 */ + r->buf[7] = 0x10 | (r->req.bus->info->tcq ? 0x02 : 0); /* Sync, TCQ. */ + memcpy(&r->buf[8], "QEMU ", 8); + memcpy(&r->buf[16], "QEMU TARGET ", 16); + strncpy((char *) &r->buf[32], QEMU_VERSION, 4); + } + return true; +} + +static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf) +{ + SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req); + + switch (buf[0]) { + case REPORT_LUNS: + if (!scsi_target_emulate_report_luns(r)) { + goto illegal_request; + } + break; + case INQUIRY: + if (!scsi_target_emulate_inquiry(r)) { + goto illegal_request; + } + break; + case REQUEST_SENSE: + if (req->cmd.xfer < 4) { + goto illegal_request; + } + r->len = scsi_device_get_sense(r->req.dev, r->buf, + MIN(req->cmd.xfer, sizeof r->buf), + (req->cmd.buf[1] & 1) == 0); + if (r->req.dev->sense_is_ua) { + if (r->req.dev->info->unit_attention_reported) { + r->req.dev->info->unit_attention_reported(req->dev); + } + r->req.dev->sense_len = 0; + r->req.dev->sense_is_ua = false; + } + break; + default: + scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED)); + scsi_req_complete(req, CHECK_CONDITION); + return 0; + illegal_request: + scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD)); + scsi_req_complete(req, CHECK_CONDITION); + return 0; + } + + if (!r->len) { + scsi_req_complete(req, GOOD); + } + return r->len; +} + +static void scsi_target_read_data(SCSIRequest *req) +{ + SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req); + uint32_t n; + + n = r->len; + if (n > 0) { + r->len = 0; + scsi_req_data(&r->req, n); + } else { + scsi_req_complete(&r->req, GOOD); + } +} + +static uint8_t *scsi_target_get_buf(SCSIRequest *req) +{ + SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req); + + return r->buf; +} + +static const struct SCSIReqOps reqops_target_command = { + .size = sizeof(SCSITargetReq), + .send_command = scsi_target_send_command, + .read_data = scsi_target_read_data, + .get_buf = scsi_target_get_buf, +}; + + +SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, + uint32_t tag, uint32_t lun, void *hba_private) { SCSIRequest *req; - req = qemu_mallocz(size); + req = g_malloc0(reqops->size); + req->refcount = 1; req->bus = scsi_bus_from_device(d); req->dev = d; req->tag = tag; req->lun = lun; + req->hba_private = hba_private; req->status = -1; - req->enqueued = true; - QTAILQ_INSERT_TAIL(&d->requests, req, next); + req->sense_len = 0; + req->ops = reqops; + trace_scsi_req_alloc(req->dev->id, req->lun, req->tag); return req; } -SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag) +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, + uint8_t *buf, void *hba_private) { + SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); SCSIRequest *req; + SCSICommand cmd; + + if (scsi_req_parse(&cmd, d, buf) != 0) { + trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]); + req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private); + } else { + trace_scsi_req_parsed(d->id, lun, tag, buf[0], + cmd.mode, cmd.xfer); + if (cmd.lba != -1) { + trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0], + cmd.lba); + } + + if ((d->unit_attention.key == UNIT_ATTENTION || + bus->unit_attention.key == UNIT_ATTENTION) && + (buf[0] != INQUIRY && + buf[0] != REPORT_LUNS && + buf[0] != GET_CONFIGURATION && + buf[0] != GET_EVENT_STATUS_NOTIFICATION && + + /* + * If we already have a pending unit attention condition, + * report this one before triggering another one. + */ + !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) { + req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun, + hba_private); + } else if (lun != d->lun || + buf[0] == REPORT_LUNS || + (buf[0] == REQUEST_SENSE && (d->sense_len || cmd.xfer < 4))) { + req = scsi_req_alloc(&reqops_target_command, d, tag, lun, + hba_private); + } else { + req = d->info->alloc_req(d, tag, lun, buf, hba_private); + } + } + + req->cmd = cmd; + switch (buf[0]) { + case INQUIRY: + trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]); + break; + case TEST_UNIT_READY: + trace_scsi_test_unit_ready(d->id, lun, tag); + break; + case REPORT_LUNS: + trace_scsi_report_luns(d->id, lun, tag); + break; + case REQUEST_SENSE: + trace_scsi_request_sense(d->id, lun, tag); + break; + default: + break; + } + + return req; +} + +uint8_t *scsi_req_get_buf(SCSIRequest *req) +{ + return req->ops->get_buf(req); +} + +static void scsi_clear_unit_attention(SCSIRequest *req) +{ + SCSISense *ua; + if (req->dev->unit_attention.key != UNIT_ATTENTION && + req->bus->unit_attention.key != UNIT_ATTENTION) { + return; + } + + /* + * If an INQUIRY command enters the enabled command state, + * the device server shall [not] clear any unit attention condition; + * See also MMC-6, paragraphs 6.5 and 6.6.2. + */ + if (req->cmd.buf[0] == INQUIRY || + req->cmd.buf[0] == GET_CONFIGURATION || + req->cmd.buf[0] == GET_EVENT_STATUS_NOTIFICATION) { + return; + } + + if (req->dev->unit_attention.key == UNIT_ATTENTION) { + ua = &req->dev->unit_attention; + } else { + ua = &req->bus->unit_attention; + } + + /* + * If a REPORT LUNS command enters the enabled command state, [...] + * the device server shall clear any pending unit attention condition + * with an additional sense code of REPORTED LUNS DATA HAS CHANGED. + */ + if (req->cmd.buf[0] == REPORT_LUNS && + !(ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc && + ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq)) { + return; + } + + *ua = SENSE_CODE(NO_SENSE); +} + +int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len) +{ + int ret; + + assert(len >= 14); + if (!req->sense_len) { + return 0; + } + + ret = scsi_build_sense(req->sense, req->sense_len, buf, len, true); - QTAILQ_FOREACH(req, &d->requests, next) { - if (req->tag == tag) { - return req; + /* + * FIXME: clearing unit attention conditions upon autosense should be done + * only if the UA_INTLCK_CTRL field in the Control mode page is set to 00b + * (SAM-5, 5.14). + * + * We assume UA_INTLCK_CTRL to be 00b for HBAs that support autosense, and + * 10b for HBAs that do not support it (do not call scsi_req_get_sense). + * Here we handle unit attention clearing for UA_INTLCK_CTRL == 00b. + */ + if (req->dev->sense_is_ua) { + if (req->dev->info->unit_attention_reported) { + req->dev->info->unit_attention_reported(req->dev); } + req->dev->sense_len = 0; + req->dev->sense_is_ua = false; } - return NULL; + return ret; +} + +int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed) +{ + return scsi_build_sense(dev->sense, dev->sense_len, buf, len, fixed); +} + +void scsi_req_build_sense(SCSIRequest *req, SCSISense sense) +{ + trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag, + sense.key, sense.asc, sense.ascq); + memset(req->sense, 0, 18); + req->sense[0] = 0xf0; + req->sense[2] = sense.key; + req->sense[7] = 10; + req->sense[12] = sense.asc; + req->sense[13] = sense.ascq; + req->sense_len = 18; +} + +int32_t scsi_req_enqueue(SCSIRequest *req) +{ + int32_t rc; + + assert(!req->enqueued); + scsi_req_ref(req); + req->enqueued = true; + QTAILQ_INSERT_TAIL(&req->dev->requests, req, next); + + scsi_req_ref(req); + rc = req->ops->send_command(req, req->cmd.buf); + scsi_req_unref(req); + return rc; } static void scsi_req_dequeue(SCSIRequest *req) { + trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); + req->retry = false; if (req->enqueued) { QTAILQ_REMOVE(&req->dev->requests, req, next); req->enqueued = false; + scsi_req_unref(req); } } -void scsi_req_free(SCSIRequest *req) +static int scsi_get_performance_length(int num_desc, int type, int data_type) { - scsi_req_dequeue(req); - qemu_free(req); + /* MMC-6, paragraph 6.7. */ + switch (type) { + case 0: + if ((data_type & 3) == 0) { + /* Each descriptor is as in Table 295 - Nominal performance. */ + return 16 * num_desc + 8; + } else { + /* Each descriptor is as in Table 296 - Exceptions. */ + return 6 * num_desc + 8; + } + case 1: + case 4: + case 5: + return 8 * num_desc + 8; + case 2: + return 2048 * num_desc + 8; + case 3: + return 16 * num_desc + 8; + default: + return 8; + } } -static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) +static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) { - switch (cmd[0] >> 5) { + switch (buf[0] >> 5) { case 0: - req->cmd.xfer = cmd[4]; - req->cmd.len = 6; + cmd->xfer = buf[4]; + cmd->len = 6; /* length 0 means 256 blocks */ - if (req->cmd.xfer == 0) - req->cmd.xfer = 256; + if (cmd->xfer == 0) { + cmd->xfer = 256; + } break; case 1: case 2: - req->cmd.xfer = cmd[8] | (cmd[7] << 8); - req->cmd.len = 10; + cmd->xfer = lduw_be_p(&buf[7]); + cmd->len = 10; break; case 4: - req->cmd.xfer = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24); - req->cmd.len = 16; + cmd->xfer = ldl_be_p(&buf[10]) & 0xffffffffULL; + cmd->len = 16; break; case 5: - req->cmd.xfer = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24); - req->cmd.len = 12; + cmd->xfer = ldl_be_p(&buf[6]) & 0xffffffffULL; + cmd->len = 12; break; default: return -1; } - switch(cmd[0]) { + switch (buf[0]) { case TEST_UNIT_READY: - case REZERO_UNIT: + case REWIND: case START_STOP: - case SEEK_6: + case SET_CAPACITY: case WRITE_FILEMARKS: + case WRITE_FILEMARKS_16: case SPACE: case RESERVE: case RELEASE: case ERASE: case ALLOW_MEDIUM_REMOVAL: - case VERIFY: + case VERIFY_10: case SEEK_10: case SYNCHRONIZE_CACHE: + case SYNCHRONIZE_CACHE_16: + case LOCATE_16: case LOCK_UNLOCK_CACHE: case LOAD_UNLOAD: case SET_CD_SPEED: case SET_LIMITS: - case WRITE_LONG: + case WRITE_LONG_10: case MOVE_MEDIUM: case UPDATE_BLOCK: - req->cmd.xfer = 0; + case RESERVE_TRACK: + case SET_READ_AHEAD: + case PRE_FETCH: + case PRE_FETCH_16: + case ALLOW_OVERWRITE: + cmd->xfer = 0; break; case MODE_SENSE: break; - case WRITE_SAME: - req->cmd.xfer = 1; + case WRITE_SAME_10: + cmd->xfer = 1; break; - case READ_CAPACITY: - req->cmd.xfer = 8; + case READ_CAPACITY_10: + cmd->xfer = 8; break; case READ_BLOCK_LIMITS: - req->cmd.xfer = 6; - break; - case READ_POSITION: - req->cmd.xfer = 20; + cmd->xfer = 6; break; case SEND_VOLUME_TAG: - req->cmd.xfer *= 40; - break; - case MEDIUM_SCAN: - req->cmd.xfer *= 8; + /* GPCMD_SET_STREAMING from multimedia commands. */ + if (dev->type == TYPE_ROM) { + cmd->xfer = buf[10] | (buf[9] << 8); + } else { + cmd->xfer = buf[9] | (buf[8] << 8); + } break; case WRITE_10: - case WRITE_VERIFY: + case WRITE_VERIFY_10: case WRITE_6: case WRITE_12: case WRITE_VERIFY_12: case WRITE_16: case WRITE_VERIFY_16: - req->cmd.xfer *= req->dev->blocksize; + cmd->xfer *= dev->blocksize; break; case READ_10: case READ_6: @@ -256,53 +768,97 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) case RECOVER_BUFFERED_DATA: case READ_12: case READ_16: - req->cmd.xfer *= req->dev->blocksize; + cmd->xfer *= dev->blocksize; + break; + case FORMAT_UNIT: + /* MMC mandates the parameter list to be 12-bytes long. Parameters + * for block devices are restricted to the header right now. */ + if (dev->type == TYPE_ROM && (buf[1] & 16)) { + cmd->xfer = 12; + } else { + cmd->xfer = (buf[1] & 16) == 0 ? 0 : (buf[1] & 32 ? 8 : 4); + } break; case INQUIRY: - req->cmd.xfer = cmd[4] | (cmd[3] << 8); + case RECEIVE_DIAGNOSTIC: + case SEND_DIAGNOSTIC: + cmd->xfer = buf[4] | (buf[3] << 8); + break; + case READ_CD: + case READ_BUFFER: + case WRITE_BUFFER: + case SEND_CUE_SHEET: + cmd->xfer = buf[8] | (buf[7] << 8) | (buf[6] << 16); + break; + case PERSISTENT_RESERVE_OUT: + cmd->xfer = ldl_be_p(&buf[5]) & 0xffffffffULL; break; + case ERASE_12: + if (dev->type == TYPE_ROM) { + /* MMC command GET PERFORMANCE. */ + cmd->xfer = scsi_get_performance_length(buf[9] | (buf[8] << 8), + buf[10], buf[1] & 0x1f); + } + break; + case MECHANISM_STATUS: + case READ_DVD_STRUCTURE: + case SEND_DVD_STRUCTURE: case MAINTENANCE_OUT: case MAINTENANCE_IN: - if (req->dev->type == TYPE_ROM) { + if (dev->type == TYPE_ROM) { /* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */ - req->cmd.xfer = cmd[9] | (cmd[8] << 8); + cmd->xfer = buf[9] | (buf[8] << 8); } break; } return 0; } -static int scsi_req_stream_length(SCSIRequest *req, uint8_t *cmd) +static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) { - switch(cmd[0]) { + switch (buf[0]) { /* stream commands */ + case ERASE_12: + case ERASE_16: + cmd->xfer = 0; + break; case READ_6: case READ_REVERSE: case RECOVER_BUFFERED_DATA: case WRITE_6: - req->cmd.len = 6; - req->cmd.xfer = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16); - if (cmd[1] & 0x01) /* fixed */ - req->cmd.xfer *= req->dev->blocksize; + cmd->len = 6; + cmd->xfer = buf[4] | (buf[3] << 8) | (buf[2] << 16); + if (buf[1] & 0x01) { /* fixed */ + cmd->xfer *= dev->blocksize; + } break; case REWIND: case START_STOP: - req->cmd.len = 6; - req->cmd.xfer = 0; + cmd->len = 6; + cmd->xfer = 0; + break; + case SPACE_16: + cmd->xfer = buf[13] | (buf[12] << 8); + break; + case READ_POSITION: + cmd->xfer = buf[8] | (buf[7] << 8); + break; + case FORMAT_UNIT: + cmd->xfer = buf[4] | (buf[3] << 8); break; /* generic commands */ default: - return scsi_req_length(req, cmd); + return scsi_req_length(cmd, dev, buf); } return 0; } -static void scsi_req_xfer_mode(SCSIRequest *req) +static void scsi_cmd_xfer_mode(SCSICommand *cmd) { - switch (req->cmd.buf[0]) { + switch (cmd->buf[0]) { case WRITE_6: case WRITE_10: - case WRITE_VERIFY: + case WRITE_VERIFY_10: case WRITE_12: case WRITE_VERIFY_12: case WRITE_16: @@ -322,53 +878,45 @@ static void scsi_req_xfer_mode(SCSIRequest *req) case SEARCH_HIGH: case SEARCH_LOW: case UPDATE_BLOCK: - case WRITE_LONG: - case WRITE_SAME: + case WRITE_LONG_10: + case WRITE_SAME_10: case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12: - case SET_WINDOW: case MEDIUM_SCAN: case SEND_VOLUME_TAG: - case WRITE_LONG_2: + case SEND_CUE_SHEET: + case SEND_DVD_STRUCTURE: case PERSISTENT_RESERVE_OUT: case MAINTENANCE_OUT: - req->cmd.mode = SCSI_XFER_TO_DEV; + cmd->mode = SCSI_XFER_TO_DEV; break; default: - if (req->cmd.xfer) - req->cmd.mode = SCSI_XFER_FROM_DEV; + if (cmd->xfer) + cmd->mode = SCSI_XFER_FROM_DEV; else { - req->cmd.mode = SCSI_XFER_NONE; + cmd->mode = SCSI_XFER_NONE; } break; } } -static uint64_t scsi_req_lba(SCSIRequest *req) +static uint64_t scsi_cmd_lba(SCSICommand *cmd) { - uint8_t *buf = req->cmd.buf; + uint8_t *buf = cmd->buf; uint64_t lba; switch (buf[0] >> 5) { case 0: - lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) | - (((uint64_t) buf[1] & 0x1f) << 16); + lba = ldl_be_p(&buf[0]) & 0x1fffff; break; case 1: case 2: - lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) | - ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24); + case 5: + lba = ldl_be_p(&buf[2]) & 0xffffffffULL; break; case 4: - lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) | - ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) | - ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) | - ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56); - break; - case 5: - lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) | - ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24); + lba = ldq_be_p(&buf[2]); break; default: lba = -1; @@ -377,37 +925,196 @@ static uint64_t scsi_req_lba(SCSIRequest *req) return lba; } -int scsi_req_parse(SCSIRequest *req, uint8_t *buf) +int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) { int rc; - if (req->dev->type == TYPE_TAPE) { - rc = scsi_req_stream_length(req, buf); + if (dev->type == TYPE_TAPE) { + rc = scsi_req_stream_length(cmd, dev, buf); } else { - rc = scsi_req_length(req, buf); + rc = scsi_req_length(cmd, dev, buf); } if (rc != 0) return rc; - memcpy(req->cmd.buf, buf, req->cmd.len); - scsi_req_xfer_mode(req); - req->cmd.lba = scsi_req_lba(req); + memcpy(cmd->buf, buf, cmd->len); + scsi_cmd_xfer_mode(cmd); + cmd->lba = scsi_cmd_lba(cmd); return 0; } +/* + * Predefined sense codes + */ + +/* No sense data available */ +const struct SCSISense sense_code_NO_SENSE = { + .key = NO_SENSE , .asc = 0x00 , .ascq = 0x00 +}; + +/* LUN not ready, Manual intervention required */ +const struct SCSISense sense_code_LUN_NOT_READY = { + .key = NOT_READY, .asc = 0x04, .ascq = 0x03 +}; + +/* LUN not ready, Medium not present */ +const struct SCSISense sense_code_NO_MEDIUM = { + .key = NOT_READY, .asc = 0x3a, .ascq = 0x00 +}; + +/* LUN not ready, medium removal prevented */ +const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED = { + .key = NOT_READY, .asc = 0x53, .ascq = 0x00 +}; + +/* Hardware error, internal target failure */ +const struct SCSISense sense_code_TARGET_FAILURE = { + .key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00 +}; + +/* Illegal request, invalid command operation code */ +const struct SCSISense sense_code_INVALID_OPCODE = { + .key = ILLEGAL_REQUEST, .asc = 0x20, .ascq = 0x00 +}; + +/* Illegal request, LBA out of range */ +const struct SCSISense sense_code_LBA_OUT_OF_RANGE = { + .key = ILLEGAL_REQUEST, .asc = 0x21, .ascq = 0x00 +}; + +/* Illegal request, Invalid field in CDB */ +const struct SCSISense sense_code_INVALID_FIELD = { + .key = ILLEGAL_REQUEST, .asc = 0x24, .ascq = 0x00 +}; + +/* Illegal request, LUN not supported */ +const struct SCSISense sense_code_LUN_NOT_SUPPORTED = { + .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00 +}; + +/* Illegal request, Saving parameters not supported */ +const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED = { + .key = ILLEGAL_REQUEST, .asc = 0x39, .ascq = 0x00 +}; + +/* Illegal request, Incompatible medium installed */ +const struct SCSISense sense_code_INCOMPATIBLE_FORMAT = { + .key = ILLEGAL_REQUEST, .asc = 0x30, .ascq = 0x00 +}; + +/* Illegal request, medium removal prevented */ +const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED = { + .key = ILLEGAL_REQUEST, .asc = 0x53, .ascq = 0x00 +}; + +/* Command aborted, I/O process terminated */ +const struct SCSISense sense_code_IO_ERROR = { + .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06 +}; + +/* Command aborted, I_T Nexus loss occurred */ +const struct SCSISense sense_code_I_T_NEXUS_LOSS = { + .key = ABORTED_COMMAND, .asc = 0x29, .ascq = 0x07 +}; + +/* Command aborted, Logical Unit failure */ +const struct SCSISense sense_code_LUN_FAILURE = { + .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01 +}; + +/* Unit attention, Power on, reset or bus device reset occurred */ +const struct SCSISense sense_code_RESET = { + .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00 +}; + +/* Unit attention, No medium */ +const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM = { + .key = UNIT_ATTENTION, .asc = 0x3a, .ascq = 0x00 +}; + +/* Unit attention, Medium may have changed */ +const struct SCSISense sense_code_MEDIUM_CHANGED = { + .key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00 +}; + +/* Unit attention, Reported LUNs data has changed */ +const struct SCSISense sense_code_REPORTED_LUNS_CHANGED = { + .key = UNIT_ATTENTION, .asc = 0x3f, .ascq = 0x0e +}; + +/* Unit attention, Device internal reset */ +const struct SCSISense sense_code_DEVICE_INTERNAL_RESET = { + .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x04 +}; + +/* + * scsi_build_sense + * + * Convert between fixed and descriptor sense buffers + */ +int scsi_build_sense(uint8_t *in_buf, int in_len, + uint8_t *buf, int len, bool fixed) +{ + bool fixed_in; + SCSISense sense; + if (!fixed && len < 8) { + return 0; + } + + if (in_len == 0) { + sense.key = NO_SENSE; + sense.asc = 0; + sense.ascq = 0; + } else { + fixed_in = (in_buf[0] & 2) == 0; + + if (fixed == fixed_in) { + memcpy(buf, in_buf, MIN(len, in_len)); + return MIN(len, in_len); + } + + if (fixed_in) { + sense.key = in_buf[2]; + sense.asc = in_buf[12]; + sense.ascq = in_buf[13]; + } else { + sense.key = in_buf[1]; + sense.asc = in_buf[2]; + sense.ascq = in_buf[3]; + } + } + + memset(buf, 0, len); + if (fixed) { + /* Return fixed format sense buffer */ + buf[0] = 0xf0; + buf[2] = sense.key; + buf[7] = 10; + buf[12] = sense.asc; + buf[13] = sense.ascq; + return MIN(len, 18); + } else { + /* Return descriptor format sense buffer */ + buf[0] = 0x72; + buf[1] = sense.key; + buf[2] = sense.asc; + buf[3] = sense.ascq; + return 8; + } +} + static const char *scsi_command_name(uint8_t cmd) { static const char *names[] = { [ TEST_UNIT_READY ] = "TEST_UNIT_READY", - [ REZERO_UNIT ] = "REZERO_UNIT", - /* REWIND and REZERO_UNIT use the same operation code */ + [ REWIND ] = "REWIND", [ REQUEST_SENSE ] = "REQUEST_SENSE", [ FORMAT_UNIT ] = "FORMAT_UNIT", [ READ_BLOCK_LIMITS ] = "READ_BLOCK_LIMITS", [ REASSIGN_BLOCKS ] = "REASSIGN_BLOCKS", [ READ_6 ] = "READ_6", [ WRITE_6 ] = "WRITE_6", - [ SEEK_6 ] = "SEEK_6", + [ SET_CAPACITY ] = "SET_CAPACITY", [ READ_REVERSE ] = "READ_REVERSE", [ WRITE_FILEMARKS ] = "WRITE_FILEMARKS", [ SPACE ] = "SPACE", @@ -425,19 +1132,17 @@ static const char *scsi_command_name(uint8_t cmd) [ RECEIVE_DIAGNOSTIC ] = "RECEIVE_DIAGNOSTIC", [ SEND_DIAGNOSTIC ] = "SEND_DIAGNOSTIC", [ ALLOW_MEDIUM_REMOVAL ] = "ALLOW_MEDIUM_REMOVAL", - - [ SET_WINDOW ] = "SET_WINDOW", - [ READ_CAPACITY ] = "READ_CAPACITY", + [ READ_CAPACITY_10 ] = "READ_CAPACITY_10", [ READ_10 ] = "READ_10", [ WRITE_10 ] = "WRITE_10", [ SEEK_10 ] = "SEEK_10", - [ WRITE_VERIFY ] = "WRITE_VERIFY", - [ VERIFY ] = "VERIFY", + [ WRITE_VERIFY_10 ] = "WRITE_VERIFY_10", + [ VERIFY_10 ] = "VERIFY_10", [ SEARCH_HIGH ] = "SEARCH_HIGH", [ SEARCH_EQUAL ] = "SEARCH_EQUAL", [ SEARCH_LOW ] = "SEARCH_LOW", [ SET_LIMITS ] = "SET_LIMITS", - [ PRE_FETCH ] = "PRE_FETCH", + [ PRE_FETCH ] = "PRE_FETCH/READ_POSITION", /* READ_POSITION and PRE_FETCH use the same operation code */ [ SYNCHRONIZE_CACHE ] = "SYNCHRONIZE_CACHE", [ LOCK_UNLOCK_CACHE ] = "LOCK_UNLOCK_CACHE", @@ -448,11 +1153,14 @@ static const char *scsi_command_name(uint8_t cmd) [ WRITE_BUFFER ] = "WRITE_BUFFER", [ READ_BUFFER ] = "READ_BUFFER", [ UPDATE_BLOCK ] = "UPDATE_BLOCK", - [ READ_LONG ] = "READ_LONG", - [ WRITE_LONG ] = "WRITE_LONG", + [ READ_LONG_10 ] = "READ_LONG_10", + [ WRITE_LONG_10 ] = "WRITE_LONG_10", [ CHANGE_DEFINITION ] = "CHANGE_DEFINITION", - [ WRITE_SAME ] = "WRITE_SAME", + [ WRITE_SAME_10 ] = "WRITE_SAME_10", + [ UNMAP ] = "UNMAP", [ READ_TOC ] = "READ_TOC", + [ REPORT_DENSITY_SUPPORT ] = "REPORT_DENSITY_SUPPORT", + [ GET_CONFIGURATION ] = "GET_CONFIGURATION", [ LOG_SELECT ] = "LOG_SELECT", [ LOG_SENSE ] = "LOG_SENSE", [ MODE_SELECT_10 ] = "MODE_SELECT_10", @@ -461,27 +1169,51 @@ static const char *scsi_command_name(uint8_t cmd) [ MODE_SENSE_10 ] = "MODE_SENSE_10", [ PERSISTENT_RESERVE_IN ] = "PERSISTENT_RESERVE_IN", [ PERSISTENT_RESERVE_OUT ] = "PERSISTENT_RESERVE_OUT", + [ WRITE_FILEMARKS_16 ] = "WRITE_FILEMARKS_16", + [ EXTENDED_COPY ] = "EXTENDED_COPY", + [ ATA_PASSTHROUGH ] = "ATA_PASSTHROUGH", + [ ACCESS_CONTROL_IN ] = "ACCESS_CONTROL_IN", + [ ACCESS_CONTROL_OUT ] = "ACCESS_CONTROL_OUT", + [ READ_16 ] = "READ_16", + [ COMPARE_AND_WRITE ] = "COMPARE_AND_WRITE", + [ WRITE_16 ] = "WRITE_16", + [ WRITE_VERIFY_16 ] = "WRITE_VERIFY_16", + [ VERIFY_16 ] = "VERIFY_16", + [ PRE_FETCH_16 ] = "PRE_FETCH_16", + [ SYNCHRONIZE_CACHE_16 ] = "SPACE_16/SYNCHRONIZE_CACHE_16", + /* SPACE_16 and SYNCHRONIZE_CACHE_16 use the same operation code */ + [ LOCATE_16 ] = "LOCATE_16", + [ WRITE_SAME_16 ] = "ERASE_16/WRITE_SAME_16", + /* ERASE_16 and WRITE_SAME_16 use the same operation code */ + [ SERVICE_ACTION_IN_16 ] = "SERVICE_ACTION_IN_16", + [ WRITE_LONG_16 ] = "WRITE_LONG_16", + [ REPORT_LUNS ] = "REPORT_LUNS", + [ BLANK ] = "BLANK", [ MOVE_MEDIUM ] = "MOVE_MEDIUM", + [ LOAD_UNLOAD ] = "LOAD_UNLOAD", [ READ_12 ] = "READ_12", [ WRITE_12 ] = "WRITE_12", + [ ERASE_12 ] = "ERASE_12/GET_PERFORMANCE", + /* ERASE_12 and GET_PERFORMANCE use the same operation code */ + [ SERVICE_ACTION_IN_12 ] = "SERVICE_ACTION_IN_12", [ WRITE_VERIFY_12 ] = "WRITE_VERIFY_12", + [ VERIFY_12 ] = "VERIFY_12", [ SEARCH_HIGH_12 ] = "SEARCH_HIGH_12", [ SEARCH_EQUAL_12 ] = "SEARCH_EQUAL_12", [ SEARCH_LOW_12 ] = "SEARCH_LOW_12", [ READ_ELEMENT_STATUS ] = "READ_ELEMENT_STATUS", - [ SEND_VOLUME_TAG ] = "SEND_VOLUME_TAG", - [ WRITE_LONG_2 ] = "WRITE_LONG_2", - - [ REPORT_DENSITY_SUPPORT ] = "REPORT_DENSITY_SUPPORT", - [ GET_CONFIGURATION ] = "GET_CONFIGURATION", - [ READ_16 ] = "READ_16", - [ WRITE_16 ] = "WRITE_16", - [ WRITE_VERIFY_16 ] = "WRITE_VERIFY_16", - [ SERVICE_ACTION_IN ] = "SERVICE_ACTION_IN", - [ REPORT_LUNS ] = "REPORT_LUNS", - [ LOAD_UNLOAD ] = "LOAD_UNLOAD", + [ SEND_VOLUME_TAG ] = "SEND_VOLUME_TAG/SET_STREAMING", + /* SEND_VOLUME_TAG and SET_STREAMING use the same operation code */ + [ READ_CD ] = "READ_CD", + [ READ_DEFECT_DATA_12 ] = "READ_DEFECT_DATA_12", + [ READ_DVD_STRUCTURE ] = "READ_DVD_STRUCTURE", + [ RESERVE_TRACK ] = "RESERVE_TRACK", + [ SEND_CUE_SHEET ] = "SEND_CUE_SHEET", + [ SEND_DVD_STRUCTURE ] = "SEND_DVD_STRUCTURE", [ SET_CD_SPEED ] = "SET_CD_SPEED", - [ BLANK ] = "BLANK", + [ SET_READ_AHEAD ] = "SET_READ_AHEAD", + [ ALLOW_OVERWRITE ] = "ALLOW_OVERWRITE", + [ MECHANISM_STATUS ] = "MECHANISM_STATUS", }; if (cmd >= ARRAY_SIZE(names) || names[cmd] == NULL) @@ -489,6 +1221,47 @@ static const char *scsi_command_name(uint8_t cmd) return names[cmd]; } +SCSIRequest *scsi_req_ref(SCSIRequest *req) +{ + req->refcount++; + return req; +} + +void scsi_req_unref(SCSIRequest *req) +{ + if (--req->refcount == 0) { + if (req->ops->free_req) { + req->ops->free_req(req); + } + g_free(req); + } +} + +/* Tell the device that we finished processing this chunk of I/O. It + will start the next chunk or complete the command. */ +void scsi_req_continue(SCSIRequest *req) +{ + trace_scsi_req_continue(req->dev->id, req->lun, req->tag); + if (req->cmd.mode == SCSI_XFER_TO_DEV) { + req->ops->write_data(req); + } else { + req->ops->read_data(req); + } +} + +/* Called by the devices when data is ready for the HBA. The HBA should + start a DMA operation to read or fill the device's data buffer. + Once it completes, calling scsi_req_continue will restart I/O. */ +void scsi_req_data(SCSIRequest *req, int len) +{ + if (req->io_canceled) { + trace_scsi_req_data_canceled(req->dev->id, req->lun, req->tag, len); + } else { + trace_scsi_req_data(req->dev->id, req->lun, req->tag, len); + req->bus->info->transfer_data(req, len); + } +} + void scsi_req_print(SCSIRequest *req) { FILE *fp = stderr; @@ -517,31 +1290,106 @@ void scsi_req_print(SCSIRequest *req) } } -void scsi_req_complete(SCSIRequest *req) +void scsi_req_complete(SCSIRequest *req, int status) { - assert(req->status != -1); + assert(req->status == -1); + req->status = status; + + assert(req->sense_len < sizeof(req->sense)); + if (status == GOOD) { + req->sense_len = 0; + } + + if (req->sense_len) { + memcpy(req->dev->sense, req->sense, req->sense_len); + req->dev->sense_len = req->sense_len; + req->dev->sense_is_ua = (req->ops == &reqops_unit_attention); + } else { + req->dev->sense_len = 0; + req->dev->sense_is_ua = false; + } + + /* + * Unit attention state is now stored in the device's sense buffer + * if the HBA didn't do autosense. Clear the pending unit attention + * flags. + */ + scsi_clear_unit_attention(req); + + scsi_req_ref(req); scsi_req_dequeue(req); - req->bus->complete(req->bus, SCSI_REASON_DONE, - req->tag, - req->status); + req->bus->info->complete(req, req->status); + scsi_req_unref(req); } -static char *scsibus_get_fw_dev_path(DeviceState *dev) +void scsi_req_cancel(SCSIRequest *req) { - SCSIDevice *d = (SCSIDevice*)dev; - SCSIBus *bus = scsi_bus_from_device(d); - char path[100]; - int i; + if (!req->enqueued) { + return; + } + scsi_req_ref(req); + scsi_req_dequeue(req); + req->io_canceled = true; + if (req->ops->cancel_io) { + req->ops->cancel_io(req); + } + if (req->bus->info->cancel) { + req->bus->info->cancel(req); + } + scsi_req_unref(req); +} - for (i = 0; i < bus->ndev; i++) { - if (bus->devs[i] == d) { - break; - } +void scsi_req_abort(SCSIRequest *req, int status) +{ + if (!req->enqueued) { + return; + } + scsi_req_ref(req); + scsi_req_dequeue(req); + req->io_canceled = true; + if (req->ops->cancel_io) { + req->ops->cancel_io(req); } + scsi_req_complete(req, status); + scsi_req_unref(req); +} - assert(i != bus->ndev); +void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) +{ + SCSIRequest *req; - snprintf(path, sizeof(path), "%s@%x", qdev_fw_name(dev), i); + while (!QTAILQ_EMPTY(&sdev->requests)) { + req = QTAILQ_FIRST(&sdev->requests); + scsi_req_cancel(req); + } + sdev->unit_attention = sense; +} + +static char *scsibus_get_fw_dev_path(DeviceState *dev) +{ + SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev); + char path[100]; + + snprintf(path, sizeof(path), "channel@%x/%s@%x,%x", d->channel, + qdev_fw_name(dev), d->id, d->lun); return strdup(path); } + +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) +{ + DeviceState *qdev; + SCSIDevice *target_dev = NULL; + + QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) { + SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev); + + if (dev->channel == channel && dev->id == id) { + if (dev->lun == lun) { + return dev; + } + target_dev = dev; + } + } + return target_dev; +} diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h index 413cce0..354ed7b 100644 --- a/hw/scsi-defs.h +++ b/hw/scsi-defs.h @@ -25,14 +25,14 @@ */ #define TEST_UNIT_READY 0x00 -#define REZERO_UNIT 0x01 +#define REWIND 0x01 #define REQUEST_SENSE 0x03 #define FORMAT_UNIT 0x04 #define READ_BLOCK_LIMITS 0x05 #define REASSIGN_BLOCKS 0x07 #define READ_6 0x08 #define WRITE_6 0x0a -#define SEEK_6 0x0b +#define SET_CAPACITY 0x0b #define READ_REVERSE 0x0f #define WRITE_FILEMARKS 0x10 #define SPACE 0x11 @@ -48,14 +48,13 @@ #define RECEIVE_DIAGNOSTIC 0x1c #define SEND_DIAGNOSTIC 0x1d #define ALLOW_MEDIUM_REMOVAL 0x1e - -#define SET_WINDOW 0x24 -#define READ_CAPACITY 0x25 +#define READ_CAPACITY_10 0x25 #define READ_10 0x28 #define WRITE_10 0x2a #define SEEK_10 0x2b -#define WRITE_VERIFY 0x2e -#define VERIFY 0x2f +#define LOCATE_10 0x2b +#define WRITE_VERIFY_10 0x2e +#define VERIFY_10 0x2f #define SEARCH_HIGH 0x30 #define SEARCH_EQUAL 0x31 #define SEARCH_LOW 0x32 @@ -71,45 +70,74 @@ #define WRITE_BUFFER 0x3b #define READ_BUFFER 0x3c #define UPDATE_BLOCK 0x3d -#define READ_LONG 0x3e -#define WRITE_LONG 0x3f +#define READ_LONG_10 0x3e +#define WRITE_LONG_10 0x3f #define CHANGE_DEFINITION 0x40 -#define WRITE_SAME 0x41 +#define WRITE_SAME_10 0x41 +#define UNMAP 0x42 #define READ_TOC 0x43 +#define REPORT_DENSITY_SUPPORT 0x44 +#define GET_CONFIGURATION 0x46 +#define GET_EVENT_STATUS_NOTIFICATION 0x4a #define LOG_SELECT 0x4c #define LOG_SENSE 0x4d +#define RESERVE_TRACK 0x53 #define MODE_SELECT_10 0x55 #define RESERVE_10 0x56 #define RELEASE_10 0x57 #define MODE_SENSE_10 0x5a +#define SEND_CUE_SHEET 0x5d #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f +#define VARLENGTH_CDB 0x7f +#define WRITE_FILEMARKS_16 0x80 +#define ALLOW_OVERWRITE 0x82 +#define EXTENDED_COPY 0x83 +#define ATA_PASSTHROUGH 0x85 +#define ACCESS_CONTROL_IN 0x86 +#define ACCESS_CONTROL_OUT 0x87 +#define READ_16 0x88 +#define COMPARE_AND_WRITE 0x89 +#define WRITE_16 0x8a +#define WRITE_VERIFY_16 0x8e +#define VERIFY_16 0x8f +#define PRE_FETCH_16 0x90 +#define SPACE_16 0x91 +#define SYNCHRONIZE_CACHE_16 0x91 +#define LOCATE_16 0x92 #define WRITE_SAME_16 0x93 +#define ERASE_16 0x93 +#define SERVICE_ACTION_IN_16 0x9e +#define WRITE_LONG_16 0x9f +#define REPORT_LUNS 0xa0 +#define BLANK 0xa1 #define MAINTENANCE_IN 0xa3 #define MAINTENANCE_OUT 0xa4 #define MOVE_MEDIUM 0xa5 +#define LOAD_UNLOAD 0xa6 +#define SET_READ_AHEAD 0xa7 #define READ_12 0xa8 #define WRITE_12 0xaa +#define SERVICE_ACTION_IN_12 0xab +#define ERASE_12 0xac +#define READ_DVD_STRUCTURE 0xad #define WRITE_VERIFY_12 0xae +#define VERIFY_12 0xaf #define SEARCH_HIGH_12 0xb0 #define SEARCH_EQUAL_12 0xb1 #define SEARCH_LOW_12 0xb2 #define READ_ELEMENT_STATUS 0xb8 #define SEND_VOLUME_TAG 0xb6 -#define WRITE_LONG_2 0xea +#define READ_DEFECT_DATA_12 0xb7 +#define SET_CD_SPEED 0xbb +#define MECHANISM_STATUS 0xbd +#define READ_CD 0xbe +#define SEND_DVD_STRUCTURE 0xbf -/* from hw/scsi-generic.c */ -#define REWIND 0x01 -#define REPORT_DENSITY_SUPPORT 0x44 -#define GET_CONFIGURATION 0x46 -#define READ_16 0x88 -#define WRITE_16 0x8a -#define WRITE_VERIFY_16 0x8e -#define SERVICE_ACTION_IN 0x9e -#define REPORT_LUNS 0xa0 -#define LOAD_UNLOAD 0xa6 -#define SET_CD_SPEED 0xbb -#define BLANK 0xa1 +/* + * SERVICE ACTION IN subcodes + */ +#define SAI_READ_CAPACITY_16 0x10 /* * SAM Status codes @@ -154,6 +182,7 @@ #define TYPE_DISK 0x00 #define TYPE_TAPE 0x01 +#define TYPE_PRINTER 0x02 #define TYPE_PROCESSOR 0x03 /* HP scanners use this */ #define TYPE_WORM 0x04 /* Treated as ROM by our system */ #define TYPE_ROM 0x05 @@ -161,6 +190,99 @@ #define TYPE_MOD 0x07 /* Magneto-optical disk - * - treated as TYPE_DISK */ #define TYPE_MEDIUM_CHANGER 0x08 -#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ +#define TYPE_STORAGE_ARRAY 0x0c /* Storage array device */ +#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ +#define TYPE_RBC 0x0e /* Simplified Direct-Access Device */ +#define TYPE_OSD 0x11 /* Object-storage Device */ +#define TYPE_WLUN 0x1e /* Well known LUN */ +#define TYPE_NOT_PRESENT 0x1f +#define TYPE_INACTIVE 0x20 #define TYPE_NO_LUN 0x7f +/* Mode page codes for mode sense/set */ +#define MODE_PAGE_R_W_ERROR 0x01 +#define MODE_PAGE_HD_GEOMETRY 0x04 +#define MODE_PAGE_FLEXIBLE_DISK_GEOMETRY 0x05 +#define MODE_PAGE_CACHING 0x08 +#define MODE_PAGE_AUDIO_CTL 0x0e +#define MODE_PAGE_POWER 0x1a +#define MODE_PAGE_FAULT_FAIL 0x1c +#define MODE_PAGE_TO_PROTECT 0x1d +#define MODE_PAGE_CAPABILITIES 0x2a +#define MODE_PAGE_ALLS 0x3f +/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor + * of MODE_PAGE_SENSE_POWER */ +#define MODE_PAGE_CDROM 0x0d + +/* Event notification classes for GET EVENT STATUS NOTIFICATION */ +#define GESN_NO_EVENTS 0 +#define GESN_OPERATIONAL_CHANGE 1 +#define GESN_POWER_MANAGEMENT 2 +#define GESN_EXTERNAL_REQUEST 3 +#define GESN_MEDIA 4 +#define GESN_MULTIPLE_HOSTS 5 +#define GESN_DEVICE_BUSY 6 + +/* Event codes for MEDIA event status notification */ +#define MEC_NO_CHANGE 0 +#define MEC_EJECT_REQUESTED 1 +#define MEC_NEW_MEDIA 2 +#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ +#define MEC_MEDIA_CHANGED 4 /* only for media changers */ +#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ +#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ + +#define MS_TRAY_OPEN 1 +#define MS_MEDIA_PRESENT 2 + +/* + * Based on values from but extending CD_MINS + * to the maximum common size allowed by the Orange's Book ATIP + * + * 90 and 99 min CDs are also available but using them as the + * upper limit reduces the effectiveness of the heuristic to + * detect DVDs burned to less than 25% of their maximum capacity + */ + +/* Some generally useful CD-ROM information */ +#define CD_MINS 80 /* max. minutes per CD */ +#define CD_SECS 60 /* seconds per minute */ +#define CD_FRAMES 75 /* frames per second */ +#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ +#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) +#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) + +/* + * The MMC values are not IDE specific and might need to be moved + * to a common header if they are also needed for the SCSI emulation + */ + +/* Profile list from MMC-6 revision 1 table 91 */ +#define MMC_PROFILE_NONE 0x0000 +#define MMC_PROFILE_CD_ROM 0x0008 +#define MMC_PROFILE_CD_R 0x0009 +#define MMC_PROFILE_CD_RW 0x000A +#define MMC_PROFILE_DVD_ROM 0x0010 +#define MMC_PROFILE_DVD_R_SR 0x0011 +#define MMC_PROFILE_DVD_RAM 0x0012 +#define MMC_PROFILE_DVD_RW_RO 0x0013 +#define MMC_PROFILE_DVD_RW_SR 0x0014 +#define MMC_PROFILE_DVD_R_DL_SR 0x0015 +#define MMC_PROFILE_DVD_R_DL_JR 0x0016 +#define MMC_PROFILE_DVD_RW_DL 0x0017 +#define MMC_PROFILE_DVD_DDR 0x0018 +#define MMC_PROFILE_DVD_PLUS_RW 0x001A +#define MMC_PROFILE_DVD_PLUS_R 0x001B +#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A +#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B +#define MMC_PROFILE_BD_ROM 0x0040 +#define MMC_PROFILE_BD_R_SRM 0x0041 +#define MMC_PROFILE_BD_R_RRM 0x0042 +#define MMC_PROFILE_BD_RE 0x0043 +#define MMC_PROFILE_HDDVD_ROM 0x0050 +#define MMC_PROFILE_HDDVD_R 0x0051 +#define MMC_PROFILE_HDDVD_RAM 0x0052 +#define MMC_PROFILE_HDDVD_RW 0x0053 +#define MMC_PROFILE_HDDVD_R_DL 0x0058 +#define MMC_PROFILE_HDDVD_RW_DL 0x005A +#define MMC_PROFILE_INVALID 0xFFFF diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 488eedd..673948c 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -12,7 +12,7 @@ * 2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the * MODE SENSE response. * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. * * Note that this file only handles the SCSI architecture model and device * commands. Emulation of interface/link layer protocols is handled by @@ -37,352 +37,310 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0) #include "scsi-defs.h" #include "sysemu.h" #include "blockdev.h" +#include "block_int.h" + +#ifdef __linux +#include +#endif #define SCSI_DMA_BUF_SIZE 131072 #define SCSI_MAX_INQUIRY_LEN 256 -#define SCSI_REQ_STATUS_RETRY 0x01 -#define SCSI_REQ_STATUS_RETRY_TYPE_MASK 0x06 -#define SCSI_REQ_STATUS_RETRY_READ 0x00 -#define SCSI_REQ_STATUS_RETRY_WRITE 0x02 -#define SCSI_REQ_STATUS_RETRY_FLUSH 0x04 - typedef struct SCSIDiskState SCSIDiskState; -typedef struct SCSISense { - uint8_t key; -} SCSISense; - typedef struct SCSIDiskReq { SCSIRequest req; - /* ??? We should probably keep track of whether the data transfer is - a read or a write. Currently we rely on the host getting it right. */ /* Both sector and sector_count are in terms of qemu 512 byte blocks. */ uint64_t sector; uint32_t sector_count; + uint32_t buflen; struct iovec iov; QEMUIOVector qiov; - uint32_t status; + BlockAcctCookie acct; } SCSIDiskReq; struct SCSIDiskState { SCSIDevice qdev; - BlockDriverState *bs; - /* The qemu block layer uses a fixed 512 byte sector size. - This is the number of 512 byte blocks in a single scsi sector. */ - int cluster_size; uint32_t removable; - uint64_t max_lba; + bool media_changed; + bool media_event; + bool eject_request; QEMUBH *bh; char *version; char *serial; - SCSISense sense; + bool tray_open; + bool tray_locked; }; -static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type); -static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf); +static int scsi_handle_rw_error(SCSIDiskReq *r, int error); -static SCSIDiskReq *scsi_new_request(SCSIDiskState *s, uint32_t tag, - uint32_t lun) +static void scsi_free_request(SCSIRequest *req) { - SCSIRequest *req; - SCSIDiskReq *r; + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); - req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun); - r = DO_UPCAST(SCSIDiskReq, req, req); - r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE); - return r; + if (r->iov.iov_base) { + qemu_vfree(r->iov.iov_base); + } } -static void scsi_remove_request(SCSIDiskReq *r) +/* Helper function for command completion with sense. */ +static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense) { - qemu_vfree(r->iov.iov_base); - scsi_req_free(&r->req); + DPRINTF("Command complete tag=0x%x sense=%d/%d/%d\n", + r->req.tag, sense.key, sense.asc, sense.ascq); + scsi_req_build_sense(&r->req, sense); + scsi_req_complete(&r->req, CHECK_CONDITION); } -static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag) +/* Cancel a pending data transfer. */ +static void scsi_cancel_io(SCSIRequest *req) { - return DO_UPCAST(SCSIDiskReq, req, scsi_req_find(&s->qdev, tag)); -} + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); -static void scsi_disk_clear_sense(SCSIDiskState *s) -{ - memset(&s->sense, 0, sizeof(s->sense)); -} + DPRINTF("Cancel tag=0x%x\n", req->tag); + if (r->req.aiocb) { + bdrv_aio_cancel(r->req.aiocb); -static void scsi_disk_set_sense(SCSIDiskState *s, uint8_t key) -{ - s->sense.key = key; + /* This reference was left in by scsi_*_data. We take ownership of + * it the moment scsi_req_cancel is called, independent of whether + * bdrv_aio_cancel completes the request or not. */ + scsi_req_unref(&r->req); + } + r->req.aiocb = NULL; } -static void scsi_req_set_status(SCSIDiskReq *r, int status, int sense_code) +static uint32_t scsi_init_iovec(SCSIDiskReq *r) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - r->req.status = status; - scsi_disk_set_sense(s, sense_code); -} - -/* Helper function for command completion. */ -static void scsi_command_complete(SCSIDiskReq *r, int status, int sense) -{ - DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", - r->req.tag, status, sense); - scsi_req_set_status(r, status, sense); - scsi_req_complete(&r->req); - scsi_remove_request(r); -} - -/* Cancel a pending data transfer. */ -static void scsi_cancel_io(SCSIDevice *d, uint32_t tag) -{ - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); - SCSIDiskReq *r; - DPRINTF("Cancel tag=0x%x\n", tag); - r = scsi_find_request(s, tag); - if (r) { - if (r->req.aiocb) - bdrv_aio_cancel(r->req.aiocb); - r->req.aiocb = NULL; - scsi_remove_request(r); + if (!r->iov.iov_base) { + r->buflen = SCSI_DMA_BUF_SIZE; + r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen); } + r->iov.iov_len = MIN(r->sector_count * 512, r->buflen); + qemu_iovec_init_external(&r->qiov, &r->iov, 1); + return r->qiov.size / 512; } static void scsi_read_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); int n; - r->req.aiocb = NULL; + if (r->req.aiocb != NULL) { + r->req.aiocb = NULL; + bdrv_acct_done(s->qdev.conf.bs, &r->acct); + } if (ret) { - if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) { - return; + if (scsi_handle_rw_error(r, -ret)) { + goto done; } } - DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len); + DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size); - n = r->iov.iov_len / 512; + n = r->qiov.size / 512; r->sector += n; r->sector_count -= n; - r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len); + scsi_req_data(&r->req, r->qiov.size); + +done: + if (!r->req.io_canceled) { + scsi_req_unref(&r->req); + } } +static void scsi_flush_complete(void * opaque, int ret) +{ + SCSIDiskReq *r = (SCSIDiskReq *)opaque; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + + if (r->req.aiocb != NULL) { + r->req.aiocb = NULL; + bdrv_acct_done(s->qdev.conf.bs, &r->acct); + } + + if (ret < 0) { + if (scsi_handle_rw_error(r, -ret)) { + goto done; + } + } + + scsi_req_complete(&r->req, GOOD); + +done: + if (!r->req.io_canceled) { + scsi_req_unref(&r->req); + } +} -static void scsi_read_request(SCSIDiskReq *r) +/* Read more data from scsi device into buffer. */ +static void scsi_read_data(SCSIRequest *req) { + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint32_t n; if (r->sector_count == (uint32_t)-1) { DPRINTF("Read buf_len=%zd\n", r->iov.iov_len); r->sector_count = 0; - r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len); + scsi_req_data(&r->req, r->iov.iov_len); return; } DPRINTF("Read sector_count=%d\n", r->sector_count); if (r->sector_count == 0) { - scsi_command_complete(r, GOOD, NO_SENSE); + /* This also clears the sense buffer for REQUEST SENSE. */ + scsi_req_complete(&r->req, GOOD); return; } /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); - n = r->sector_count; - if (n > SCSI_DMA_BUF_SIZE / 512) - n = SCSI_DMA_BUF_SIZE / 512; - - r->iov.iov_len = n * 512; - qemu_iovec_init_external(&r->qiov, &r->iov, 1); - r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n, - scsi_read_complete, r); - if (r->req.aiocb == NULL) { - scsi_read_complete(r, -EIO); + /* The request is used as the AIO opaque value, so add a ref. */ + scsi_req_ref(&r->req); + if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { + DPRINTF("Data transfer direction invalid\n"); + scsi_read_complete(r, -EINVAL); + return; } -} -/* Read more data from scsi device into buffer. */ -static void scsi_read_data(SCSIDevice *d, uint32_t tag) -{ - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); - SCSIDiskReq *r; - - r = scsi_find_request(s, tag); - if (!r) { - BADF("Bad read tag 0x%x\n", tag); - /* ??? This is the wrong error. */ - scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); + if (s->tray_open) { + scsi_read_complete(r, -ENOMEDIUM); return; } - scsi_read_request(r); + n = scsi_init_iovec(r); + bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); + r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n, + scsi_read_complete, r); + if (r->req.aiocb == NULL) { + scsi_read_complete(r, -EIO); + } } -static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) +/* + * scsi_handle_rw_error has two return values. 0 means that the error + * must be ignored, 1 means that the error has been processed and the + * caller should not do anything else for this request. Note that + * scsi_handle_rw_error always manages its reference counts, independent + * of the return value. + */ +static int scsi_handle_rw_error(SCSIDiskReq *r, int error) { - int is_read = (type == SCSI_REQ_STATUS_RETRY_READ); + int is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - BlockErrorAction action = bdrv_get_on_error(s->bs, is_read); + BlockErrorAction action = bdrv_get_on_error(s->qdev.conf.bs, is_read); if (action == BLOCK_ERR_IGNORE) { - bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read); + bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read); return 0; } if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC) || action == BLOCK_ERR_STOP_ANY) { - type &= SCSI_REQ_STATUS_RETRY_TYPE_MASK; - r->status |= SCSI_REQ_STATUS_RETRY | type; - - bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); - vm_stop(0); + bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read); + vm_stop(RUN_STATE_IO_ERROR); + bdrv_iostatus_set_err(s->qdev.conf.bs, error); + scsi_req_retry(&r->req); } else { - if (type == SCSI_REQ_STATUS_RETRY_READ) { - r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0); + switch (error) { + case ENOMEDIUM: + scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); + break; + case ENOMEM: + scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE)); + break; + case EINVAL: + scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); + break; + default: + scsi_check_condition(r, SENSE_CODE(IO_ERROR)); + break; } - scsi_command_complete(r, CHECK_CONDITION, - HARDWARE_ERROR); - bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read); + bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_REPORT, is_read); } - return 1; } static void scsi_write_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; - uint32_t len; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint32_t n; - r->req.aiocb = NULL; + if (r->req.aiocb != NULL) { + r->req.aiocb = NULL; + bdrv_acct_done(s->qdev.conf.bs, &r->acct); + } if (ret) { - if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) { - return; + if (scsi_handle_rw_error(r, -ret)) { + goto done; } } - n = r->iov.iov_len / 512; + n = r->qiov.size / 512; r->sector += n; r->sector_count -= n; if (r->sector_count == 0) { - scsi_command_complete(r, GOOD, NO_SENSE); + scsi_req_complete(&r->req, GOOD); } else { - len = r->sector_count * 512; - if (len > SCSI_DMA_BUF_SIZE) { - len = SCSI_DMA_BUF_SIZE; - } - r->iov.iov_len = len; - DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len); - r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len); + scsi_init_iovec(r); + DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size); + scsi_req_data(&r->req, r->qiov.size); + } + +done: + if (!r->req.io_canceled) { + scsi_req_unref(&r->req); } } -static void scsi_write_request(SCSIDiskReq *r) +static void scsi_write_data(SCSIRequest *req) { + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint32_t n; /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); - n = r->iov.iov_len / 512; + /* The request is used as the AIO opaque value, so add a ref. */ + scsi_req_ref(&r->req); + if (r->req.cmd.mode != SCSI_XFER_TO_DEV) { + DPRINTF("Data transfer direction invalid\n"); + scsi_write_complete(r, -EINVAL); + return; + } + + n = r->qiov.size / 512; if (n) { - qemu_iovec_init_external(&r->qiov, &r->iov, 1); - r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n, - scsi_write_complete, r); + if (s->tray_open) { + scsi_write_complete(r, -ENOMEDIUM); + return; + } + bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); + r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n, + scsi_write_complete, r); if (r->req.aiocb == NULL) { - scsi_write_complete(r, -EIO); + scsi_write_complete(r, -ENOMEM); } } else { - /* Invoke completion routine to fetch data from host. */ + /* Called for the first time. Ask the driver to send us more data. */ scsi_write_complete(r, 0); } } -/* Write data to a scsi device. Returns nonzero on failure. - The transfer may complete asynchronously. */ -static int scsi_write_data(SCSIDevice *d, uint32_t tag) -{ - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); - SCSIDiskReq *r; - - DPRINTF("Write data tag=0x%x\n", tag); - r = scsi_find_request(s, tag); - if (!r) { - BADF("Bad write tag 0x%x\n", tag); - scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); - return 1; - } - - scsi_write_request(r); - - return 0; -} - -static void scsi_dma_restart_bh(void *opaque) -{ - SCSIDiskState *s = opaque; - SCSIRequest *req; - SCSIDiskReq *r; - - qemu_bh_delete(s->bh); - s->bh = NULL; - - QTAILQ_FOREACH(req, &s->qdev.requests, next) { - r = DO_UPCAST(SCSIDiskReq, req, req); - if (r->status & SCSI_REQ_STATUS_RETRY) { - int status = r->status; - int ret; - - r->status &= - ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK); - - switch (status & SCSI_REQ_STATUS_RETRY_TYPE_MASK) { - case SCSI_REQ_STATUS_RETRY_READ: - scsi_read_request(r); - break; - case SCSI_REQ_STATUS_RETRY_WRITE: - scsi_write_request(r); - break; - case SCSI_REQ_STATUS_RETRY_FLUSH: - ret = scsi_disk_emulate_command(r, r->iov.iov_base); - if (ret == 0) { - scsi_command_complete(r, GOOD, NO_SENSE); - } - } - } - } -} - -static void scsi_dma_restart_cb(void *opaque, int running, int reason) -{ - SCSIDiskState *s = opaque; - - if (!running) - return; - - if (!s->bh) { - s->bh = qemu_bh_new(scsi_dma_restart_bh, s); - qemu_bh_schedule(s->bh); - } -} - /* Return a pointer to the data buffer. */ -static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag) +static uint8_t *scsi_get_buf(SCSIRequest *req) { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); - SCSIDiskReq *r; + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); - r = scsi_find_request(s, tag); - if (!r) { - BADF("Bad buffer tag 0x%x\n", tag); - return NULL; - } return (uint8_t *)r->iov.iov_base; } @@ -406,11 +364,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) return -1; } - if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) { - outbuf[buflen++] = 5; - } else { - outbuf[buflen++] = 0; - } + outbuf[buflen++] = s->qdev.type & 0x1f; outbuf[buflen++] = page_code ; // this page outbuf[buflen++] = 0x00; @@ -422,9 +376,11 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) "buffer size %zd\n", req->cmd.xfer); pages = buflen++; outbuf[buflen++] = 0x00; // list of supported pages (this page) - outbuf[buflen++] = 0x80; // unit serial number + if (s->serial) { + outbuf[buflen++] = 0x80; // unit serial number + } outbuf[buflen++] = 0x83; // device identification - if (bdrv_get_type_hint(s->bs) != BDRV_TYPE_CDROM) { + if (s->qdev.type == TYPE_DISK) { outbuf[buflen++] = 0xb0; // block limits outbuf[buflen++] = 0xb2; // thin provisioning } @@ -433,12 +389,20 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) } case 0x80: /* Device serial number, optional */ { - int l = strlen(s->serial); + int l; - if (l > req->cmd.xfer) + if (!s->serial) { + DPRINTF("Inquiry (EVPD[Serial number] not supported\n"); + return -1; + } + + l = strlen(s->serial); + if (l > req->cmd.xfer) { l = req->cmd.xfer; - if (l > 20) + } + if (l > 20) { l = 20; + } DPRINTF("Inquiry EVPD[Serial number] " "buffer size %zd\n", req->cmd.xfer); @@ -451,10 +415,11 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) case 0x83: /* Device identification page, mandatory */ { int max_len = 255 - 8; - int id_len = strlen(bdrv_get_device_name(s->bs)); + int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs)); - if (id_len > max_len) + if (id_len > max_len) { id_len = max_len; + } DPRINTF("Inquiry EVPD[Device identification] " "buffer size %zd\n", req->cmd.xfer); @@ -464,7 +429,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[buflen++] = 0; // reserved outbuf[buflen++] = id_len; // length of data following - memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len); + memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len); buflen += id_len; break; } @@ -477,7 +442,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) unsigned int opt_io_size = s->qdev.conf.opt_io_size / s->qdev.blocksize; - if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) { + if (s->qdev.type == TYPE_ROM) { DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n", page_code); return -1; @@ -537,23 +502,16 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) } buflen = req->cmd.xfer; - if (buflen > SCSI_MAX_INQUIRY_LEN) + if (buflen > SCSI_MAX_INQUIRY_LEN) { buflen = SCSI_MAX_INQUIRY_LEN; - - memset(outbuf, 0, buflen); - - if (req->lun || req->cmd.buf[1] >> 5) { - outbuf[0] = 0x7f; /* LUN not supported */ - return buflen; } + memset(outbuf, 0, buflen); - if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) { - outbuf[0] = 5; - outbuf[1] = 0x80; + outbuf[0] = s->qdev.type & 0x1f; + outbuf[1] = s->removable ? 0x80 : 0; + if (s->qdev.type == TYPE_ROM) { memcpy(&outbuf[16], "QEMU CD-ROM ", 16); } else { - outbuf[0] = 0; - outbuf[1] = s->removable ? 0x80 : 0; memcpy(&outbuf[16], "QEMU HARDDISK ", 16); } memcpy(&outbuf[8], "QEMU ", 8); @@ -577,16 +535,254 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) } /* Sync data transfer and TCQ. */ - outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0); + outbuf[7] = 0x10 | (req->bus->info->tcq ? 0x02 : 0); return buflen; } -static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p, +static inline bool media_is_dvd(SCSIDiskState *s) +{ + uint64_t nb_sectors; + if (s->qdev.type != TYPE_ROM) { + return false; + } + if (!bdrv_is_inserted(s->qdev.conf.bs)) { + return false; + } + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + return nb_sectors > CD_MAX_SECTORS; +} + +static inline bool media_is_cd(SCSIDiskState *s) +{ + uint64_t nb_sectors; + if (s->qdev.type != TYPE_ROM) { + return false; + } + if (!bdrv_is_inserted(s->qdev.conf.bs)) { + return false; + } + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + return nb_sectors <= CD_MAX_SECTORS; +} + +static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r, + uint8_t *outbuf) +{ + static const int rds_caps_size[5] = { + [0] = 2048 + 4, + [1] = 4 + 4, + [3] = 188 + 4, + [4] = 2048 + 4, + }; + + uint8_t media = r->req.cmd.buf[1]; + uint8_t layer = r->req.cmd.buf[6]; + uint8_t format = r->req.cmd.buf[7]; + int size = -1; + + if (s->qdev.type != TYPE_ROM) { + return -1; + } + if (media != 0) { + scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); + return -1; + } + + if (format != 0xff) { + if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) { + scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); + return -1; + } + if (media_is_cd(s)) { + scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT)); + return -1; + } + if (format >= ARRAY_SIZE(rds_caps_size)) { + return -1; + } + size = rds_caps_size[format]; + memset(outbuf, 0, size); + } + + switch (format) { + case 0x00: { + /* Physical format information */ + uint64_t nb_sectors; + if (layer != 0) { + goto fail; + } + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + + outbuf[4] = 1; /* DVD-ROM, part version 1 */ + outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ + outbuf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ + outbuf[7] = 0; /* default densities */ + + stl_be_p(&outbuf[12], (nb_sectors >> 2) - 1); /* end sector */ + stl_be_p(&outbuf[16], (nb_sectors >> 2) - 1); /* l0 end sector */ + break; + } + + case 0x01: /* DVD copyright information, all zeros */ + break; + + case 0x03: /* BCA information - invalid field for no BCA info */ + return -1; + + case 0x04: /* DVD disc manufacturing information, all zeros */ + break; + + case 0xff: { /* List capabilities */ + int i; + size = 4; + for (i = 0; i < ARRAY_SIZE(rds_caps_size); i++) { + if (!rds_caps_size[i]) { + continue; + } + outbuf[size] = i; + outbuf[size + 1] = 0x40; /* Not writable, readable */ + stw_be_p(&outbuf[size + 2], rds_caps_size[i]); + size += 4; + } + break; + } + + default: + return -1; + } + + /* Size of buffer, not including 2 byte size field */ + stw_be_p(outbuf, size - 2); + return size; + +fail: + return -1; +} + +static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf) +{ + uint8_t event_code, media_status; + + media_status = 0; + if (s->tray_open) { + media_status = MS_TRAY_OPEN; + } else if (bdrv_is_inserted(s->qdev.conf.bs)) { + media_status = MS_MEDIA_PRESENT; + } + + /* Event notification descriptor */ + event_code = MEC_NO_CHANGE; + if (media_status != MS_TRAY_OPEN) { + if (s->media_event) { + event_code = MEC_NEW_MEDIA; + s->media_event = false; + } else if (s->eject_request) { + event_code = MEC_EJECT_REQUESTED; + s->eject_request = false; + } + } + + outbuf[0] = event_code; + outbuf[1] = media_status; + + /* These fields are reserved, just clear them. */ + outbuf[2] = 0; + outbuf[3] = 0; + return 4; +} + +static int scsi_get_event_status_notification(SCSIDiskState *s, SCSIDiskReq *r, + uint8_t *outbuf) +{ + int size; + uint8_t *buf = r->req.cmd.buf; + uint8_t notification_class_request = buf[4]; + if (s->qdev.type != TYPE_ROM) { + return -1; + } + if ((buf[1] & 1) == 0) { + /* asynchronous */ + return -1; + } + + size = 4; + outbuf[0] = outbuf[1] = 0; + outbuf[3] = 1 << GESN_MEDIA; /* supported events */ + if (notification_class_request & (1 << GESN_MEDIA)) { + outbuf[2] = GESN_MEDIA; + size += scsi_event_status_media(s, &outbuf[size]); + } else { + outbuf[2] = 0x80; + } + stw_be_p(outbuf, size - 4); + return size; +} + +static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf) +{ + int current; + + if (s->qdev.type != TYPE_ROM) { + return -1; + } + current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM; + memset(outbuf, 0, 40); + stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */ + stw_be_p(&outbuf[6], current); + /* outbuf[8] - outbuf[19]: Feature 0 - Profile list */ + outbuf[10] = 0x03; /* persistent, current */ + outbuf[11] = 8; /* two profiles */ + stw_be_p(&outbuf[12], MMC_PROFILE_DVD_ROM); + outbuf[14] = (current == MMC_PROFILE_DVD_ROM); + stw_be_p(&outbuf[16], MMC_PROFILE_CD_ROM); + outbuf[18] = (current == MMC_PROFILE_CD_ROM); + /* outbuf[20] - outbuf[31]: Feature 1 - Core feature */ + stw_be_p(&outbuf[20], 1); + outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */ + outbuf[23] = 8; + stl_be_p(&outbuf[24], 1); /* SCSI */ + outbuf[28] = 1; /* DBE = 1, mandatory */ + /* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */ + stw_be_p(&outbuf[32], 3); + outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */ + outbuf[35] = 4; + outbuf[36] = 0x39; /* tray, load=1, eject=1, unlocked at powerup, lock=1 */ + /* TODO: Random readable, CD read, DVD read, drive serial number, + power management */ + return 40; +} + +static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf) +{ + if (s->qdev.type != TYPE_ROM) { + return -1; + } + memset(outbuf, 0, 8); + outbuf[5] = 1; /* CD-ROM */ + return 8; +} + +static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, int page_control) { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); - BlockDriverState *bdrv = s->bs; + static const int mode_sense_valid[0x3f] = { + [MODE_PAGE_HD_GEOMETRY] = (1 << TYPE_DISK), + [MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1 << TYPE_DISK), + [MODE_PAGE_CACHING] = (1 << TYPE_DISK) | (1 << TYPE_ROM), + [MODE_PAGE_R_W_ERROR] = (1 << TYPE_DISK) | (1 << TYPE_ROM), + [MODE_PAGE_AUDIO_CTL] = (1 << TYPE_ROM), + [MODE_PAGE_CAPABILITIES] = (1 << TYPE_ROM), + }; + + BlockDriverState *bdrv = s->qdev.conf.bs; int cylinders, heads, secs; + uint8_t *p = *p_outbuf; + + if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) { + return -1; + } + + p[0] = page; /* * If Changeable Values are requested, a mask denoting those mode parameters @@ -595,14 +791,13 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p, * The buffer was already menset to zero by the caller of this function. */ switch (page) { - case 4: /* Rigid disk device geometry page. */ - p[0] = 4; + case MODE_PAGE_HD_GEOMETRY: p[1] = 0x16; if (page_control == 1) { /* Changeable Values */ - return p[1] + 2; + break; } /* if a geometry hint is available, use it */ - bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs); + bdrv_guess_geometry(bdrv, &cylinders, &heads, &secs); p[2] = (cylinders >> 16) & 0xff; p[3] = (cylinders >> 8) & 0xff; p[4] = cylinders & 0xff; @@ -625,22 +820,21 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p, /* Medium rotation rate [rpm], 5400 rpm */ p[20] = (5400 >> 8) & 0xff; p[21] = 5400 & 0xff; - return p[1] + 2; + break; - case 5: /* Flexible disk device geometry page. */ - p[0] = 5; + case MODE_PAGE_FLEXIBLE_DISK_GEOMETRY: p[1] = 0x1e; if (page_control == 1) { /* Changeable Values */ - return p[1] + 2; + break; } /* Transfer rate [kbit/s], 5Mbit/s */ p[2] = 5000 >> 8; p[3] = 5000 & 0xff; /* if a geometry hint is available, use it */ - bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs); + bdrv_guess_geometry(bdrv, &cylinders, &heads, &secs); p[4] = heads & 0xff; p[5] = secs & 0xff; - p[6] = s->cluster_size * 2; + p[6] = s->qdev.blocksize >> 8; p[8] = (cylinders >> 8) & 0xff; p[9] = cylinders & 0xff; /* Write precomp start cylinder, disabled */ @@ -664,80 +858,93 @@ static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p, /* Medium rotation rate [rpm], 5400 rpm */ p[28] = (5400 >> 8) & 0xff; p[29] = 5400 & 0xff; - return p[1] + 2; + break; - case 8: /* Caching page. */ + case MODE_PAGE_CACHING: p[0] = 8; p[1] = 0x12; if (page_control == 1) { /* Changeable Values */ - return p[1] + 2; + break; } - if (bdrv_enable_write_cache(s->bs)) { + if (bdrv_enable_write_cache(s->qdev.conf.bs)) { p[2] = 4; /* WCE */ } - return p[1] + 2; + break; - case 0x2a: /* CD Capabilities and Mechanical Status page. */ - if (bdrv_get_type_hint(bdrv) != BDRV_TYPE_CDROM) - return 0; - p[0] = 0x2a; + case MODE_PAGE_R_W_ERROR: + p[1] = 10; + p[2] = 0x80; /* Automatic Write Reallocation Enabled */ + if (s->qdev.type == TYPE_ROM) { + p[3] = 0x20; /* Read Retry Count */ + } + break; + + case MODE_PAGE_AUDIO_CTL: + p[1] = 14; + break; + + case MODE_PAGE_CAPABILITIES: p[1] = 0x14; if (page_control == 1) { /* Changeable Values */ - return p[1] + 2; + break; } - p[2] = 3; // CD-R & CD-RW read - p[3] = 0; // Writing not supported + + p[2] = 0x3b; /* CD-R & CD-RW read */ + p[3] = 0; /* Writing not supported */ p[4] = 0x7f; /* Audio, composite, digital out, mode 2 form 1&2, multi session */ p[5] = 0xff; /* CD DA, DA accurate, RW supported, RW corrected, C2 errors, ISRC, UPC, Bar code */ - p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0); + p[6] = 0x2d | (s->tray_locked ? 2 : 0); /* Locking supported, jumper present, eject, tray */ p[7] = 0; /* no volume & mute control, no changer */ - p[8] = (50 * 176) >> 8; // 50x read speed + p[8] = (50 * 176) >> 8; /* 50x read speed */ p[9] = (50 * 176) & 0xff; - p[10] = 0 >> 8; // No volume - p[11] = 0 & 0xff; - p[12] = 2048 >> 8; // 2M buffer + p[10] = 2 >> 8; /* Two volume levels */ + p[11] = 2 & 0xff; + p[12] = 2048 >> 8; /* 2M buffer */ p[13] = 2048 & 0xff; - p[14] = (16 * 176) >> 8; // 16x read speed current + p[14] = (16 * 176) >> 8; /* 16x read speed current */ p[15] = (16 * 176) & 0xff; - p[18] = (16 * 176) >> 8; // 16x write speed + p[18] = (16 * 176) >> 8; /* 16x write speed */ p[19] = (16 * 176) & 0xff; - p[20] = (16 * 176) >> 8; // 16x write speed current + p[20] = (16 * 176) >> 8; /* 16x write speed current */ p[21] = (16 * 176) & 0xff; - return p[1] + 2; + break; default: - return 0; + return -1; } + + *p_outbuf += p[1] + 2; + return p[1] + 2; } -static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf) +static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf) { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint64_t nb_sectors; - int page, dbd, buflen, page_control; + int page, dbd, buflen, ret, page_control; uint8_t *p; uint8_t dev_specific_param; - dbd = req->cmd.buf[1] & 0x8; - page = req->cmd.buf[2] & 0x3f; - page_control = (req->cmd.buf[2] & 0xc0) >> 6; + dbd = r->req.cmd.buf[1] & 0x8; + page = r->req.cmd.buf[2] & 0x3f; + page_control = (r->req.cmd.buf[2] & 0xc0) >> 6; DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n", - (req->cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, req->cmd.xfer, page_control); - memset(outbuf, 0, req->cmd.xfer); + (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control); + memset(outbuf, 0, r->req.cmd.xfer); p = outbuf; - if (bdrv_is_read_only(s->bs)) { + if (bdrv_is_read_only(s->qdev.conf.bs)) { dev_specific_param = 0x80; /* Readonly. */ } else { dev_specific_param = 0x00; } - if (req->cmd.buf[0] == MODE_SENSE) { + if (r->req.cmd.buf[0] == MODE_SENSE) { p[1] = 0; /* Default media type. */ p[2] = dev_specific_param; p[3] = 0; /* Block descriptor length. */ @@ -749,44 +956,44 @@ static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf) p += 8; } - bdrv_get_geometry(s->bs, &nb_sectors); - if (!dbd && nb_sectors) { - if (req->cmd.buf[0] == MODE_SENSE) { + /* MMC prescribes that CD/DVD drives have no block descriptors. */ + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + if (!dbd && s->qdev.type == TYPE_DISK && nb_sectors) { + if (r->req.cmd.buf[0] == MODE_SENSE) { outbuf[3] = 8; /* Block descriptor length */ } else { /* MODE_SENSE_10 */ outbuf[7] = 8; /* Block descriptor length */ } - nb_sectors /= s->cluster_size; - if (nb_sectors > 0xffffff) + nb_sectors /= (s->qdev.blocksize / 512); + if (nb_sectors > 0xffffff) { nb_sectors = 0; + } p[0] = 0; /* media density code */ p[1] = (nb_sectors >> 16) & 0xff; p[2] = (nb_sectors >> 8) & 0xff; p[3] = nb_sectors & 0xff; p[4] = 0; /* reserved */ p[5] = 0; /* bytes 5-7 are the sector size in bytes */ - p[6] = s->cluster_size * 2; + p[6] = s->qdev.blocksize >> 8; p[7] = 0; p += 8; } - if (page_control == 3) { /* Saved Values */ - return -1; /* ILLEGAL_REQUEST */ + if (page_control == 3) { + /* Saved Values */ + scsi_check_condition(r, SENSE_CODE(SAVING_PARAMS_NOT_SUPPORTED)); + return -1; } - switch (page) { - case 0x04: - case 0x05: - case 0x08: - case 0x2a: - p += mode_sense_page(req, page, p, page_control); - break; - case 0x3f: - p += mode_sense_page(req, 0x08, p, page_control); - p += mode_sense_page(req, 0x2a, p, page_control); - break; - default: - return -1; /* ILLEGAL_REQUEST */ + if (page == 0x3f) { + for (page = 0; page <= 0x3e; page++) { + mode_sense_page(s, page, &p, page_control); + } + } else { + ret = mode_sense_page(s, page, &p, page_control); + if (ret == -1) { + return -1; + } } buflen = p - outbuf; @@ -795,14 +1002,15 @@ static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf) * following data that is available to be transferred. The mode data * length does not include itself. */ - if (req->cmd.buf[0] == MODE_SENSE) { + if (r->req.cmd.buf[0] == MODE_SENSE) { outbuf[0] = buflen - 1; } else { /* MODE_SENSE_10 */ outbuf[0] = ((buflen - 2) >> 8) & 0xff; outbuf[1] = (buflen - 2) & 0xff; } - if (buflen > req->cmd.xfer) - buflen = req->cmd.xfer; + if (buflen > r->req.cmd.xfer) { + buflen = r->req.cmd.xfer; + } return buflen; } @@ -815,9 +1023,9 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) msf = req->cmd.buf[1] & 2; format = req->cmd.buf[2] & 0xf; start_track = req->cmd.buf[6]; - bdrv_get_geometry(s->bs, &nb_sectors); + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); - nb_sectors /= s->cluster_size; + nb_sectors /= s->qdev.blocksize / 512; switch (format) { case 0: toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track); @@ -836,135 +1044,187 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) default: return -1; } - if (toclen > req->cmd.xfer) + if (toclen > req->cmd.xfer) { toclen = req->cmd.xfer; + } return toclen; } -static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) +static int scsi_disk_emulate_start_stop(SCSIDiskReq *r) +{ + SCSIRequest *req = &r->req; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); + bool start = req->cmd.buf[4] & 1; + bool loej = req->cmd.buf[4] & 2; /* load on start, eject on !start */ + + if (s->qdev.type == TYPE_ROM && loej) { + if (!start && !s->tray_open && s->tray_locked) { + scsi_check_condition(r, + bdrv_is_inserted(s->qdev.conf.bs) + ? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED) + : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED)); + return -1; + } + bdrv_eject(s->qdev.conf.bs, !start); + s->tray_open = !start; + } + return 0; +} + +static int scsi_disk_emulate_command(SCSIDiskReq *r) { SCSIRequest *req = &r->req; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); uint64_t nb_sectors; + uint8_t *outbuf; int buflen = 0; - int ret; + if (!r->iov.iov_base) { + /* + * FIXME: we shouldn't return anything bigger than 4k, but the code + * requires the buffer to be as big as req->cmd.xfer in several + * places. So, do not allow CDBs with a very large ALLOCATION + * LENGTH. The real fix would be to modify scsi_read_data and + * dma_buf_read, so that they return data beyond the buflen + * as all zeros. + */ + if (req->cmd.xfer > 65536) { + goto illegal_request; + } + r->buflen = MAX(4096, req->cmd.xfer); + r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen); + } + + outbuf = r->iov.iov_base; switch (req->cmd.buf[0]) { case TEST_UNIT_READY: - if (!bdrv_is_inserted(s->bs)) + if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) { goto not_ready; - break; - case REQUEST_SENSE: - if (req->cmd.xfer < 4) - goto illegal_request; - memset(outbuf, 0, 4); - buflen = 4; - if (s->sense.key == NOT_READY && req->cmd.xfer >= 18) { - memset(outbuf, 0, 18); - buflen = 18; - outbuf[7] = 10; - /* asc 0x3a, ascq 0: Medium not present */ - outbuf[12] = 0x3a; - outbuf[13] = 0; - } - outbuf[0] = 0xf0; - outbuf[1] = 0; - outbuf[2] = s->sense.key; - scsi_disk_clear_sense(s); + } break; case INQUIRY: buflen = scsi_disk_emulate_inquiry(req, outbuf); - if (buflen < 0) + if (buflen < 0) { goto illegal_request; - break; + } + break; case MODE_SENSE: case MODE_SENSE_10: - buflen = scsi_disk_emulate_mode_sense(req, outbuf); - if (buflen < 0) + buflen = scsi_disk_emulate_mode_sense(r, outbuf); + if (buflen < 0) { goto illegal_request; + } break; case READ_TOC: buflen = scsi_disk_emulate_read_toc(req, outbuf); - if (buflen < 0) + if (buflen < 0) { goto illegal_request; + } break; case RESERVE: - if (req->cmd.buf[1] & 1) + if (req->cmd.buf[1] & 1) { goto illegal_request; + } break; case RESERVE_10: - if (req->cmd.buf[1] & 3) + if (req->cmd.buf[1] & 3) { goto illegal_request; + } break; case RELEASE: - if (req->cmd.buf[1] & 1) + if (req->cmd.buf[1] & 1) { goto illegal_request; + } break; case RELEASE_10: - if (req->cmd.buf[1] & 3) + if (req->cmd.buf[1] & 3) { goto illegal_request; + } break; case START_STOP: - if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) { - /* load/eject medium */ - bdrv_eject(s->bs, !(req->cmd.buf[4] & 1)); + if (scsi_disk_emulate_start_stop(r) < 0) { + return -1; } - break; + break; case ALLOW_MEDIUM_REMOVAL: - bdrv_set_locked(s->bs, req->cmd.buf[4] & 1); - break; - case READ_CAPACITY: + s->tray_locked = req->cmd.buf[4] & 1; + bdrv_lock_medium(s->qdev.conf.bs, req->cmd.buf[4] & 1); + break; + case READ_CAPACITY_10: /* The normal LEN field for this command is zero. */ - memset(outbuf, 0, 8); - bdrv_get_geometry(s->bs, &nb_sectors); - if (!nb_sectors) + memset(outbuf, 0, 8); + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + if (!nb_sectors) { goto not_ready; - nb_sectors /= s->cluster_size; + } + if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) { + goto illegal_request; + } + nb_sectors /= s->qdev.blocksize / 512; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ - s->max_lba = nb_sectors; + s->qdev.max_lba = nb_sectors; /* Clip to 2TB, instead of returning capacity modulo 2TB. */ - if (nb_sectors > UINT32_MAX) + if (nb_sectors > UINT32_MAX) { nb_sectors = UINT32_MAX; + } outbuf[0] = (nb_sectors >> 24) & 0xff; outbuf[1] = (nb_sectors >> 16) & 0xff; outbuf[2] = (nb_sectors >> 8) & 0xff; outbuf[3] = nb_sectors & 0xff; outbuf[4] = 0; outbuf[5] = 0; - outbuf[6] = s->cluster_size * 2; + outbuf[6] = s->qdev.blocksize >> 8; outbuf[7] = 0; buflen = 8; - break; - case SYNCHRONIZE_CACHE: - ret = bdrv_flush(s->bs); - if (ret < 0) { - if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) { - return -1; - } + break; + case REQUEST_SENSE: + /* Just return "NO SENSE". */ + buflen = scsi_build_sense(NULL, 0, outbuf, r->buflen, + (req->cmd.buf[1] & 1) == 0); + break; + case MECHANISM_STATUS: + buflen = scsi_emulate_mechanism_status(s, outbuf); + if (buflen < 0) { + goto illegal_request; } break; case GET_CONFIGURATION: - memset(outbuf, 0, 8); - /* ??? This should probably return much more information. For now - just return the basic header indicating the CD-ROM profile. */ - outbuf[7] = 8; // CD-ROM - buflen = 8; + buflen = scsi_get_configuration(s, outbuf); + if (buflen < 0) { + goto illegal_request; + } + break; + case GET_EVENT_STATUS_NOTIFICATION: + buflen = scsi_get_event_status_notification(s, r, outbuf); + if (buflen < 0) { + goto illegal_request; + } + break; + case READ_DVD_STRUCTURE: + buflen = scsi_read_dvd_structure(s, r, outbuf); + if (buflen < 0) { + goto illegal_request; + } break; - case SERVICE_ACTION_IN: + case SERVICE_ACTION_IN_16: /* Service Action In subcommands. */ - if ((req->cmd.buf[1] & 31) == 0x10) { + if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { DPRINTF("SAI READ CAPACITY(16)\n"); memset(outbuf, 0, req->cmd.xfer); - bdrv_get_geometry(s->bs, &nb_sectors); - if (!nb_sectors) + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + if (!nb_sectors) { goto not_ready; - nb_sectors /= s->cluster_size; + } + if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) { + goto illegal_request; + } + nb_sectors /= s->qdev.blocksize / 512; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ - s->max_lba = nb_sectors; + s->qdev.max_lba = nb_sectors; outbuf[0] = (nb_sectors >> 56) & 0xff; outbuf[1] = (nb_sectors >> 48) & 0xff; outbuf[2] = (nb_sectors >> 40) & 0xff; @@ -975,7 +1235,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) outbuf[7] = nb_sectors & 0xff; outbuf[8] = 0; outbuf[9] = 0; - outbuf[10] = s->cluster_size * 2; + outbuf[10] = s->qdev.blocksize >> 8; outbuf[11] = 0; outbuf[12] = 0; outbuf[13] = get_physical_block_exp(&s->qdev.conf); @@ -991,33 +1251,26 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) } DPRINTF("Unsupported Service Action In\n"); goto illegal_request; - case REPORT_LUNS: - if (req->cmd.xfer < 16) - goto illegal_request; - memset(outbuf, 0, 16); - outbuf[3] = 8; - buflen = 16; - break; - case VERIFY: - break; - case REZERO_UNIT: - DPRINTF("Rezero Unit\n"); - if (!bdrv_is_inserted(s->bs)) { - goto not_ready; - } + case VERIFY_10: break; default: - goto illegal_request; + scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); + return -1; } - scsi_req_set_status(r, GOOD, NO_SENSE); return buflen; not_ready: - scsi_command_complete(r, CHECK_CONDITION, NOT_READY); + if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) { + scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); + } else { + scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); + } return -1; illegal_request: - scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST); + if (r->req.status == -1) { + scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); + } return -1; } @@ -1026,34 +1279,17 @@ illegal_request: (eg. disk reads), negative for transfers to the device (eg. disk writes), and zero if the command does not transfer any data. */ -static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, - uint8_t *buf, int lun) +static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); - uint32_t len; - int is_write; + SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); + int32_t len; uint8_t command; - uint8_t *outbuf; - SCSIDiskReq *r; int rc; command = buf[0]; - r = scsi_find_request(s, tag); - if (r) { - BADF("Tag 0x%x already in use\n", tag); - scsi_cancel_io(d, tag); - } - /* ??? Tags are not unique for different luns. We only implement a - single lun, so this should not matter. */ - r = scsi_new_request(s, tag, lun); - outbuf = (uint8_t *)r->iov.iov_base; - is_write = 0; - DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); - - if (scsi_req_parse(&r->req, buf) != 0) { - BADF("Unsupported command length, command %x\n", command); - goto fail; - } + DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]); + #ifdef DEBUG_SCSI { int i; @@ -1064,15 +1300,8 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, } #endif - if (lun || buf[1] >> 5) { - /* Only LUN 0 supported. */ - DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5); - if (command != REQUEST_SENSE && command != INQUIRY) - goto fail; - } switch (command) { case TEST_UNIT_READY: - case REQUEST_SENSE: case INQUIRY: case MODE_SENSE: case MODE_SENSE_10: @@ -1082,48 +1311,59 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, case RELEASE_10: case START_STOP: case ALLOW_MEDIUM_REMOVAL: - case READ_CAPACITY: - case SYNCHRONIZE_CACHE: + case READ_CAPACITY_10: case READ_TOC: + case READ_DVD_STRUCTURE: case GET_CONFIGURATION: - case SERVICE_ACTION_IN: - case REPORT_LUNS: - case VERIFY: - case REZERO_UNIT: - rc = scsi_disk_emulate_command(r, outbuf); + case GET_EVENT_STATUS_NOTIFICATION: + case MECHANISM_STATUS: + case SERVICE_ACTION_IN_16: + case REQUEST_SENSE: + case VERIFY_10: + rc = scsi_disk_emulate_command(r); if (rc < 0) { return 0; } r->iov.iov_len = rc; break; + case SYNCHRONIZE_CACHE: + /* The request is used as the AIO opaque value, so add a ref. */ + scsi_req_ref(&r->req); + bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH); + r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_flush_complete, r); + if (r->req.aiocb == NULL) { + scsi_flush_complete(r, -EIO); + } + return 0; case READ_6: case READ_10: case READ_12: case READ_16: - len = r->req.cmd.xfer / d->blocksize; + len = r->req.cmd.xfer / s->qdev.blocksize; DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len); - if (r->req.cmd.lba > s->max_lba) + if (r->req.cmd.lba > s->qdev.max_lba) { goto illegal_lba; - r->sector = r->req.cmd.lba * s->cluster_size; - r->sector_count = len * s->cluster_size; + } + r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512); + r->sector_count = len * (s->qdev.blocksize / 512); break; case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: - case WRITE_VERIFY: + case WRITE_VERIFY_10: case WRITE_VERIFY_12: case WRITE_VERIFY_16: - len = r->req.cmd.xfer / d->blocksize; + len = r->req.cmd.xfer / s->qdev.blocksize; DPRINTF("Write %s(sector %" PRId64 ", count %d)\n", (command & 0xe) == 0xe ? "And Verify " : "", r->req.cmd.lba, len); - if (r->req.cmd.lba > s->max_lba) + if (r->req.cmd.lba > s->qdev.max_lba) { goto illegal_lba; - r->sector = r->req.cmd.lba * s->cluster_size; - r->sector_count = len * s->cluster_size; - is_write = 1; + } + r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512); + r->sector_count = len * (s->qdev.blocksize / 512); break; case MODE_SELECT: DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer); @@ -1141,21 +1381,19 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, goto fail; } break; - case SEEK_6: case SEEK_10: - DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, - r->req.cmd.lba); - if (r->req.cmd.lba > s->max_lba) { + DPRINTF("Seek(10) (sector %" PRId64 ")\n", r->req.cmd.lba); + if (r->req.cmd.lba > s->qdev.max_lba) { goto illegal_lba; } break; case WRITE_SAME_16: - len = r->req.cmd.xfer / d->blocksize; + len = r->req.cmd.xfer / s->qdev.blocksize; DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len); - if (r->req.cmd.lba > s->max_lba) { + if (r->req.cmd.lba > s->qdev.max_lba) { goto illegal_lba; } @@ -1166,8 +1404,9 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, goto fail; } - rc = bdrv_discard(s->bs, r->req.cmd.lba * s->cluster_size, - len * s->cluster_size); + rc = bdrv_discard(s->qdev.conf.bs, + r->req.cmd.lba * (s->qdev.blocksize / 512), + len * (s->qdev.blocksize / 512)); if (rc < 0) { /* XXX: better error code ?*/ goto fail; @@ -1176,36 +1415,26 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, break; default: DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]); + scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); + return 0; fail: - scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST); + scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); return 0; illegal_lba: - scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR); + scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE)); return 0; } if (r->sector_count == 0 && r->iov.iov_len == 0) { - scsi_command_complete(r, GOOD, NO_SENSE); + scsi_req_complete(&r->req, GOOD); } len = r->sector_count * 512 + r->iov.iov_len; - if (is_write) { + if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { return -len; } else { - if (!r->sector_count) + if (!r->sector_count) { r->sector_count = -1; - return len; - } -} - -static void scsi_disk_purge_requests(SCSIDiskState *s) -{ - SCSIDiskReq *r; - - while (!QTAILQ_EMPTY(&s->qdev.requests)) { - r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests)); - if (r->req.aiocb) { - bdrv_aio_cancel(r->req.aiocb); } - scsi_remove_request(r); + return len; } } @@ -1214,96 +1443,361 @@ static void scsi_disk_reset(DeviceState *dev) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev); uint64_t nb_sectors; - scsi_disk_purge_requests(s); + scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET)); - bdrv_get_geometry(s->bs, &nb_sectors); - nb_sectors /= s->cluster_size; + bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); + nb_sectors /= s->qdev.blocksize / 512; if (nb_sectors) { nb_sectors--; } - s->max_lba = nb_sectors; + s->qdev.max_lba = nb_sectors; } static void scsi_destroy(SCSIDevice *dev) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); - scsi_disk_purge_requests(s); + scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE)); blockdev_mark_auto_del(s->qdev.conf.bs); } -static int scsi_disk_initfn(SCSIDevice *dev) +static void scsi_cd_change_media_cb(void *opaque, bool load) +{ + SCSIDiskState *s = opaque; + + /* + * When a CD gets changed, we have to report an ejected state and + * then a loaded state to guests so that they detect tray + * open/close and media change events. Guests that do not use + * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close + * states rely on this behavior. + * + * media_changed governs the state machine used for unit attention + * report. media_event is used by GET EVENT STATUS NOTIFICATION. + */ + s->media_changed = load; + s->tray_open = !load; + s->qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM); + s->media_event = true; + s->eject_request = false; +} + +static void scsi_cd_eject_request_cb(void *opaque, bool force) +{ + SCSIDiskState *s = opaque; + + s->eject_request = true; + if (force) { + s->tray_locked = false; + } +} + +static bool scsi_cd_is_tray_open(void *opaque) +{ + return ((SCSIDiskState *)opaque)->tray_open; +} + +static bool scsi_cd_is_medium_locked(void *opaque) +{ + return ((SCSIDiskState *)opaque)->tray_locked; +} + +static const BlockDevOps scsi_cd_block_ops = { + .change_media_cb = scsi_cd_change_media_cb, + .eject_request_cb = scsi_cd_eject_request_cb, + .is_tray_open = scsi_cd_is_tray_open, + .is_medium_locked = scsi_cd_is_medium_locked, +}; + +static void scsi_disk_unit_attention_reported(SCSIDevice *dev) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + if (s->media_changed) { + s->media_changed = false; + s->qdev.unit_attention = SENSE_CODE(MEDIUM_CHANGED); + } +} + +static int scsi_initfn(SCSIDevice *dev) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); - int is_cd; DriveInfo *dinfo; if (!s->qdev.conf.bs) { error_report("scsi-disk: drive property not set"); return -1; } - s->bs = s->qdev.conf.bs; - is_cd = bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM; - if (!is_cd && !bdrv_is_inserted(s->bs)) { + if (!s->removable && !bdrv_is_inserted(s->qdev.conf.bs)) { error_report("Device needs media, but drive is empty"); return -1; } if (!s->serial) { /* try to fall back to value set with legacy -drive serial=... */ - dinfo = drive_get_by_blockdev(s->bs); - s->serial = qemu_strdup(*dinfo->serial ? dinfo->serial : "0"); + dinfo = drive_get_by_blockdev(s->qdev.conf.bs); + if (*dinfo->serial) { + s->serial = g_strdup(dinfo->serial); + } } if (!s->version) { - s->version = qemu_strdup(QEMU_VERSION); + s->version = g_strdup(QEMU_VERSION); } - if (bdrv_is_sg(s->bs)) { + if (bdrv_is_sg(s->qdev.conf.bs)) { error_report("scsi-disk: unwanted /dev/sg*"); return -1; } - if (is_cd) { - s->qdev.blocksize = 2048; - } else { - s->qdev.blocksize = s->qdev.conf.logical_block_size; + if (s->removable) { + bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_cd_block_ops, s); } - s->cluster_size = s->qdev.blocksize / 512; - s->bs->buffer_alignment = s->qdev.blocksize; + bdrv_set_buffer_alignment(s->qdev.conf.bs, s->qdev.blocksize); - s->qdev.type = TYPE_DISK; - qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s); - bdrv_set_removable(s->bs, is_cd); - add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0"); + bdrv_iostatus_enable(s->qdev.conf.bs); + add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL); return 0; } -static SCSIDeviceInfo scsi_disk_info = { - .qdev.name = "scsi-disk", - .qdev.fw_name = "disk", - .qdev.desc = "virtual scsi disk or cdrom", - .qdev.size = sizeof(SCSIDiskState), - .qdev.reset = scsi_disk_reset, - .init = scsi_disk_initfn, - .destroy = scsi_destroy, +static int scsi_hd_initfn(SCSIDevice *dev) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + s->qdev.blocksize = s->qdev.conf.logical_block_size; + s->qdev.type = TYPE_DISK; + return scsi_initfn(&s->qdev); +} + +static int scsi_cd_initfn(SCSIDevice *dev) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + s->qdev.blocksize = 2048; + s->qdev.type = TYPE_ROM; + s->removable = true; + return scsi_initfn(&s->qdev); +} + +static int scsi_disk_initfn(SCSIDevice *dev) +{ + DriveInfo *dinfo; + + if (!dev->conf.bs) { + return scsi_initfn(dev); /* ... and die there */ + } + + dinfo = drive_get_by_blockdev(dev->conf.bs); + if (dinfo->media_cd) { + return scsi_cd_initfn(dev); + } else { + return scsi_hd_initfn(dev); + } +} + +static const SCSIReqOps scsi_disk_reqops = { + .size = sizeof(SCSIDiskReq), + .free_req = scsi_free_request, .send_command = scsi_send_command, .read_data = scsi_read_data, .write_data = scsi_write_data, .cancel_io = scsi_cancel_io, .get_buf = scsi_get_buf, - .qdev.props = (Property[]) { - DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), - DEFINE_PROP_STRING("ver", SCSIDiskState, version), - DEFINE_PROP_STRING("serial", SCSIDiskState, serial), - DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false), - DEFINE_PROP_END_OF_LIST(), - }, +}; + +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, + uint8_t *buf, void *hba_private) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); + SCSIRequest *req; + + req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private); + return req; +} + +#ifdef __linux__ +static int get_device_type(SCSIDiskState *s) +{ + BlockDriverState *bdrv = s->qdev.conf.bs; + uint8_t cmd[16]; + uint8_t buf[36]; + uint8_t sensebuf[8]; + sg_io_hdr_t io_header; + int ret; + + memset(cmd, 0, sizeof(cmd)); + memset(buf, 0, sizeof(buf)); + cmd[0] = INQUIRY; + cmd[4] = sizeof(buf); + + memset(&io_header, 0, sizeof(io_header)); + io_header.interface_id = 'S'; + io_header.dxfer_direction = SG_DXFER_FROM_DEV; + io_header.dxfer_len = sizeof(buf); + io_header.dxferp = buf; + io_header.cmdp = cmd; + io_header.cmd_len = sizeof(cmd); + io_header.mx_sb_len = sizeof(sensebuf); + io_header.sbp = sensebuf; + io_header.timeout = 6000; /* XXX */ + + ret = bdrv_ioctl(bdrv, SG_IO, &io_header); + if (ret < 0 || io_header.driver_status || io_header.host_status) { + return -1; + } + s->qdev.type = buf[0]; + s->removable = (buf[1] & 0x80) != 0; + return 0; +} + +static int scsi_block_initfn(SCSIDevice *dev) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + int sg_version; + int rc; + + if (!s->qdev.conf.bs) { + error_report("scsi-block: drive property not set"); + return -1; + } + + /* check we are using a driver managing SG_IO (version 3 and after) */ + if (bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 || + sg_version < 30000) { + error_report("scsi-block: scsi generic interface too old"); + return -1; + } + + /* get device type from INQUIRY data */ + rc = get_device_type(s); + if (rc < 0) { + error_report("scsi-block: INQUIRY failed"); + return -1; + } + + /* Make a guess for the block size, we'll fix it when the guest sends. + * READ CAPACITY. If they don't, they likely would assume these sizes + * anyway. (TODO: check in /sys). + */ + if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM) { + s->qdev.blocksize = 2048; + } else { + s->qdev.blocksize = 512; + } + return scsi_initfn(&s->qdev); +} + +static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag, + uint32_t lun, uint8_t *buf, + void *hba_private) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); + + switch (buf[0]) { + case READ_6: + case READ_10: + case READ_12: + case READ_16: + case WRITE_6: + case WRITE_10: + case WRITE_12: + case WRITE_16: + case WRITE_VERIFY_10: + case WRITE_VERIFY_12: + case WRITE_VERIFY_16: + /* MMC writing cannot be done via pread/pwrite, because it sometimes + * involves writing beyond the maximum LBA or to negative LBA (lead-in). + * And once you do these writes, reading from the block device is + * unreliable, too. It is even possible that reads deliver random data + * from the host page cache (this is probably a Linux bug). + * + * We might use scsi_disk_reqops as long as no writing commands are + * seen, but performance usually isn't paramount on optical media. So, + * just make scsi-block operate the same as scsi-generic for them. + */ + if (s->qdev.type != TYPE_ROM) { + return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, + hba_private); + } + } + + return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun, + hba_private); +} +#endif + +#define DEFINE_SCSI_DISK_PROPERTIES() \ + DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \ + DEFINE_PROP_STRING("ver", SCSIDiskState, version), \ + DEFINE_PROP_STRING("serial", SCSIDiskState, serial) + +static SCSIDeviceInfo scsi_disk_info[] = { + { + .qdev.name = "scsi-hd", + .qdev.fw_name = "disk", + .qdev.desc = "virtual SCSI disk", + .qdev.size = sizeof(SCSIDiskState), + .qdev.reset = scsi_disk_reset, + .init = scsi_hd_initfn, + .destroy = scsi_destroy, + .alloc_req = scsi_new_request, + .unit_attention_reported = scsi_disk_unit_attention_reported, + .qdev.props = (Property[]) { + DEFINE_SCSI_DISK_PROPERTIES(), + DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false), + DEFINE_PROP_END_OF_LIST(), + } + },{ + .qdev.name = "scsi-cd", + .qdev.fw_name = "disk", + .qdev.desc = "virtual SCSI CD-ROM", + .qdev.size = sizeof(SCSIDiskState), + .qdev.reset = scsi_disk_reset, + .init = scsi_cd_initfn, + .destroy = scsi_destroy, + .alloc_req = scsi_new_request, + .unit_attention_reported = scsi_disk_unit_attention_reported, + .qdev.props = (Property[]) { + DEFINE_SCSI_DISK_PROPERTIES(), + DEFINE_PROP_END_OF_LIST(), + }, +#ifdef __linux__ + },{ + .qdev.name = "scsi-block", + .qdev.fw_name = "disk", + .qdev.desc = "SCSI block device passthrough", + .qdev.size = sizeof(SCSIDiskState), + .qdev.reset = scsi_disk_reset, + .init = scsi_block_initfn, + .destroy = scsi_destroy, + .alloc_req = scsi_block_new_request, + .qdev.props = (Property[]) { + DEFINE_SCSI_DISK_PROPERTIES(), + DEFINE_PROP_END_OF_LIST(), + }, +#endif + },{ + .qdev.name = "scsi-disk", /* legacy -device scsi-disk */ + .qdev.fw_name = "disk", + .qdev.desc = "virtual SCSI disk or CD-ROM (legacy)", + .qdev.size = sizeof(SCSIDiskState), + .qdev.reset = scsi_disk_reset, + .init = scsi_disk_initfn, + .destroy = scsi_destroy, + .alloc_req = scsi_new_request, + .unit_attention_reported = scsi_disk_unit_attention_reported, + .qdev.props = (Property[]) { + DEFINE_SCSI_DISK_PROPERTIES(), + DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false), + DEFINE_PROP_END_OF_LIST(), + } + } }; static void scsi_disk_register_devices(void) { - scsi_qdev_register(&scsi_disk_info); + int i; + + for (i = 0; i < ARRAY_SIZE(scsi_disk_info); i++) { + scsi_qdev_register(&scsi_disk_info[i]); + } } device_init(scsi_disk_register_devices) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 9be1cca..e62044f 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -7,7 +7,7 @@ * * Written by Laurent Vivier * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. * */ @@ -39,15 +39,18 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0) #define SCSI_SENSE_BUF_SIZE 96 -#define SG_ERR_DRIVER_TIMEOUT 0x06 -#define SG_ERR_DRIVER_SENSE 0x08 +#define SG_ERR_DRIVER_TIMEOUT 0x06 +#define SG_ERR_DRIVER_SENSE 0x08 + +#define SG_ERR_DID_OK 0x00 +#define SG_ERR_DID_NO_CONNECT 0x01 +#define SG_ERR_DID_BUS_BUSY 0x02 +#define SG_ERR_DID_TIME_OUT 0x03 #ifndef MAX_UINT #define MAX_UINT ((unsigned int)-1) #endif -typedef struct SCSIGenericState SCSIGenericState; - typedef struct SCSIGenericReq { SCSIRequest req; uint8_t *buf; @@ -56,95 +59,94 @@ typedef struct SCSIGenericReq { sg_io_hdr_t io_header; } SCSIGenericReq; -struct SCSIGenericState -{ - SCSIDevice qdev; - BlockDriverState *bs; - int lun; - int driver_status; - uint8_t sensebuf[SCSI_SENSE_BUF_SIZE]; - uint8_t senselen; -}; - -static SCSIGenericReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun) +static void scsi_free_request(SCSIRequest *req) { - SCSIRequest *req; + SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); - req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun); - return DO_UPCAST(SCSIGenericReq, req, req); -} - -static void scsi_remove_request(SCSIGenericReq *r) -{ - qemu_free(r->buf); - scsi_req_free(&r->req); -} - -static SCSIGenericReq *scsi_find_request(SCSIGenericState *s, uint32_t tag) -{ - return DO_UPCAST(SCSIGenericReq, req, scsi_req_find(&s->qdev, tag)); + g_free(r->buf); } /* Helper function for command completion. */ static void scsi_command_complete(void *opaque, int ret) { + int status; SCSIGenericReq *r = (SCSIGenericReq *)opaque; - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); - s->driver_status = r->io_header.driver_status; - if (s->driver_status & SG_ERR_DRIVER_SENSE) - s->senselen = r->io_header.sb_len_wr; + r->req.aiocb = NULL; + if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) { + r->req.sense_len = r->io_header.sb_len_wr; + } - if (ret != 0) - r->req.status = BUSY; - else { - if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) { - r->req.status = BUSY; + if (ret != 0) { + switch (ret) { + case -EDOM: + status = TASK_SET_FULL; + break; + case -ENOMEM: + status = CHECK_CONDITION; + scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE)); + break; + default: + status = CHECK_CONDITION; + scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR)); + break; + } + } else { + if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT || + r->io_header.host_status == SG_ERR_DID_BUS_BUSY || + r->io_header.host_status == SG_ERR_DID_TIME_OUT || + (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) { + status = BUSY; BADF("Driver Timeout\n"); - } else if (r->io_header.status) - r->req.status = r->io_header.status; - else if (s->driver_status & SG_ERR_DRIVER_SENSE) - r->req.status = CHECK_CONDITION; - else - r->req.status = GOOD; + } else if (r->io_header.host_status) { + status = CHECK_CONDITION; + scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS)); + } else if (r->io_header.status) { + status = r->io_header.status; + } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) { + status = CHECK_CONDITION; + } else { + status = GOOD; + } } DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", - r, r->req.tag, r->req.status); + r, r->req.tag, status); - scsi_req_complete(&r->req); - scsi_remove_request(r); + scsi_req_complete(&r->req, status); + if (!r->req.io_canceled) { + scsi_req_unref(&r->req); + } } /* Cancel a pending data transfer. */ -static void scsi_cancel_io(SCSIDevice *d, uint32_t tag) +static void scsi_cancel_io(SCSIRequest *req) { - DPRINTF("scsi_cancel_io 0x%x\n", tag); - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); - SCSIGenericReq *r; - DPRINTF("Cancel tag=0x%x\n", tag); - r = scsi_find_request(s, tag); - if (r) { - if (r->req.aiocb) - bdrv_aio_cancel(r->req.aiocb); - r->req.aiocb = NULL; - scsi_remove_request(r); + SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); + + DPRINTF("Cancel tag=0x%x\n", req->tag); + if (r->req.aiocb) { + bdrv_aio_cancel(r->req.aiocb); + + /* This reference was left in by scsi_*_data. We take ownership of + * it independent of whether bdrv_aio_cancel completes the request + * or not. */ + scsi_req_unref(&r->req); } + r->req.aiocb = NULL; } static int execute_command(BlockDriverState *bdrv, SCSIGenericReq *r, int direction, BlockDriverCompletionFunc *complete) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); - r->io_header.interface_id = 'S'; r->io_header.dxfer_direction = direction; r->io_header.dxferp = r->buf; r->io_header.dxfer_len = r->buflen; r->io_header.cmdp = r->req.cmd.buf; r->io_header.cmd_len = r->req.cmd.len; - r->io_header.mx_sb_len = sizeof(s->sensebuf); - r->io_header.sbp = s->sensebuf; + r->io_header.mx_sb_len = sizeof(r->req.sense); + r->io_header.sbp = r->req.sense; r->io_header.timeout = MAX_UINT; r->io_header.usr_ptr = r; r->io_header.flags |= SG_FLAG_DIRECT_IO; @@ -152,7 +154,7 @@ static int execute_command(BlockDriverState *bdrv, r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r); if (r->req.aiocb == NULL) { BADF("execute_command: read failed !\n"); - return -1; + return -ENOMEM; } return 0; @@ -161,8 +163,10 @@ static int execute_command(BlockDriverState *bdrv, static void scsi_read_complete(void * opaque, int ret) { SCSIGenericReq *r = (SCSIGenericReq *)opaque; + SCSIDevice *s = r->req.dev; int len; + r->req.aiocb = NULL; if (ret) { DPRINTF("IO error ret %d\n", ret); scsi_command_complete(r, ret); @@ -172,61 +176,56 @@ static void scsi_read_complete(void * opaque, int ret) DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len); r->len = -1; - r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len); - if (len == 0) + if (len == 0) { scsi_command_complete(r, 0); + } else { + /* Snoop READ CAPACITY output to set the blocksize. */ + if (r->req.cmd.buf[0] == READ_CAPACITY_10) { + s->blocksize = ldl_be_p(&r->buf[4]); + s->max_lba = ldl_be_p(&r->buf[0]); + } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 && + (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { + s->blocksize = ldl_be_p(&r->buf[8]); + s->max_lba = ldq_be_p(&r->buf[0]); + } + bdrv_set_buffer_alignment(s->conf.bs, s->blocksize); + + scsi_req_data(&r->req, len); + if (!r->req.io_canceled) { + scsi_req_unref(&r->req); + } + } } /* Read more data from scsi device into buffer. */ -static void scsi_read_data(SCSIDevice *d, uint32_t tag) +static void scsi_read_data(SCSIRequest *req) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); - SCSIGenericReq *r; + SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); + SCSIDevice *s = r->req.dev; int ret; - DPRINTF("scsi_read_data 0x%x\n", tag); - r = scsi_find_request(s, tag); - if (!r) { - BADF("Bad read tag 0x%x\n", tag); - /* ??? This is the wrong error. */ - scsi_command_complete(r, -EINVAL); - return; - } + DPRINTF("scsi_read_data 0x%x\n", req->tag); + /* The request is used as the AIO opaque value, so add a ref. */ + scsi_req_ref(&r->req); if (r->len == -1) { scsi_command_complete(r, 0); return; } - if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE) - { - s->senselen = MIN(r->len, s->senselen); - memcpy(r->buf, s->sensebuf, s->senselen); - r->io_header.driver_status = 0; - r->io_header.status = 0; - r->io_header.dxfer_len = s->senselen; - r->len = -1; - DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen); - DPRINTF("Sense: %d %d %d %d %d %d %d %d\n", - r->buf[0], r->buf[1], r->buf[2], r->buf[3], - r->buf[4], r->buf[5], r->buf[6], r->buf[7]); - r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, s->senselen); - return; - } - - ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete); - if (ret == -1) { - scsi_command_complete(r, -EINVAL); - return; + ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete); + if (ret < 0) { + scsi_command_complete(r, ret); } } static void scsi_write_complete(void * opaque, int ret) { SCSIGenericReq *r = (SCSIGenericReq *)opaque; - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); + SCSIDevice *s = r->req.dev; DPRINTF("scsi_write_complete() ret = %d\n", ret); + r->req.aiocb = NULL; if (ret) { DPRINTF("IO error\n"); scsi_command_complete(r, ret); @@ -234,9 +233,9 @@ static void scsi_write_complete(void * opaque, int ret) } if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 && - s->qdev.type == TYPE_TAPE) { - s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11]; - DPRINTF("block size %d\n", s->qdev.blocksize); + s->type == TYPE_TAPE) { + s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11]; + DPRINTF("block size %d\n", s->blocksize); } scsi_command_complete(r, ret); @@ -244,66 +243,33 @@ static void scsi_write_complete(void * opaque, int ret) /* Write data to a scsi device. Returns nonzero on failure. The transfer may complete asynchronously. */ -static int scsi_write_data(SCSIDevice *d, uint32_t tag) +static void scsi_write_data(SCSIRequest *req) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); - SCSIGenericReq *r; + SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); + SCSIDevice *s = r->req.dev; int ret; - DPRINTF("scsi_write_data 0x%x\n", tag); - r = scsi_find_request(s, tag); - if (!r) { - BADF("Bad write tag 0x%x\n", tag); - /* ??? This is the wrong error. */ - scsi_command_complete(r, -EINVAL); - return 0; - } - + DPRINTF("scsi_write_data 0x%x\n", req->tag); if (r->len == 0) { r->len = r->buflen; - r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->len); - return 0; + scsi_req_data(&r->req, r->len); + return; } - ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete); - if (ret == -1) { - scsi_command_complete(r, -EINVAL); - return 1; + /* The request is used as the AIO opaque value, so add a ref. */ + scsi_req_ref(&r->req); + ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete); + if (ret < 0) { + scsi_command_complete(r, ret); } - - return 0; } /* Return a pointer to the data buffer. */ -static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag) +static uint8_t *scsi_get_buf(SCSIRequest *req) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); - SCSIGenericReq *r; - r = scsi_find_request(s, tag); - if (!r) { - BADF("Bad buffer tag 0x%x\n", tag); - return NULL; - } - return r->buf; -} + SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); -static void scsi_req_fixup(SCSIRequest *req) -{ - switch(req->cmd.buf[0]) { - case WRITE_10: - req->cmd.buf[1] &= ~0x08; /* disable FUA */ - break; - case READ_10: - req->cmd.buf[1] &= ~0x08; /* disable FUA */ - break; - case REWIND: - case START_STOP: - if (req->dev->type == TYPE_TAPE) { - /* force IMMED, otherwise qemu waits end of command */ - req->cmd.buf[1] = 0x01; - } - break; - } + return r->buf; } /* Execute a scsi command. Returns the length of the data expected by the @@ -311,46 +277,12 @@ static void scsi_req_fixup(SCSIRequest *req) (eg. disk reads), negative for transfers to the device (eg. disk writes), and zero if the command does not transfer any data. */ -static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, - uint8_t *cmd, int lun) +static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); - SCSIGenericReq *r; - SCSIBus *bus; + SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); + SCSIDevice *s = r->req.dev; int ret; - if (cmd[0] != REQUEST_SENSE && - (lun != s->lun || (cmd[1] >> 5) != s->lun)) { - DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5); - - s->sensebuf[0] = 0x70; - s->sensebuf[1] = 0x00; - s->sensebuf[2] = ILLEGAL_REQUEST; - s->sensebuf[3] = 0x00; - s->sensebuf[4] = 0x00; - s->sensebuf[5] = 0x00; - s->sensebuf[6] = 0x00; - s->senselen = 7; - s->driver_status = SG_ERR_DRIVER_SENSE; - bus = scsi_bus_from_device(d); - bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION); - return 0; - } - - r = scsi_find_request(s, tag); - if (r) { - BADF("Tag 0x%x already in use %p\n", tag, r); - scsi_cancel_io(d, tag); - } - r = scsi_new_request(d, tag, lun); - - if (-1 == scsi_req_parse(&r->req, cmd)) { - BADF("Unsupported command length, command %x\n", cmd[0]); - scsi_remove_request(r); - return 0; - } - scsi_req_fixup(&r->req); - DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag, r->req.cmd.xfer, cmd[0]); @@ -366,12 +298,14 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, if (r->req.cmd.xfer == 0) { if (r->buf != NULL) - qemu_free(r->buf); + g_free(r->buf); r->buflen = 0; r->buf = NULL; - ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete); - if (ret == -1) { - scsi_command_complete(r, -EINVAL); + /* The request is used as the AIO opaque value, so add a ref. */ + scsi_req_ref(&r->req); + ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete); + if (ret < 0) { + scsi_command_complete(r, ret); return 0; } return 0; @@ -379,8 +313,8 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, if (r->buflen != r->req.cmd.xfer) { if (r->buf != NULL) - qemu_free(r->buf); - r->buf = qemu_malloc(r->req.cmd.xfer); + g_free(r->buf); + r->buf = g_malloc(r->req.cmd.xfer); r->buflen = r->req.cmd.xfer; } @@ -389,39 +323,9 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { r->len = 0; return -r->req.cmd.xfer; + } else { + return r->req.cmd.xfer; } - - return r->req.cmd.xfer; -} - -static int get_blocksize(BlockDriverState *bdrv) -{ - uint8_t cmd[10]; - uint8_t buf[8]; - uint8_t sensebuf[8]; - sg_io_hdr_t io_header; - int ret; - - memset(cmd, 0, sizeof(cmd)); - memset(buf, 0, sizeof(buf)); - cmd[0] = READ_CAPACITY; - - memset(&io_header, 0, sizeof(io_header)); - io_header.interface_id = 'S'; - io_header.dxfer_direction = SG_DXFER_FROM_DEV; - io_header.dxfer_len = sizeof(buf); - io_header.dxferp = buf; - io_header.cmdp = cmd; - io_header.cmd_len = sizeof(cmd); - io_header.mx_sb_len = sizeof(sensebuf); - io_header.sbp = sensebuf; - io_header.timeout = 6000; /* XXX */ - - ret = bdrv_ioctl(bdrv, SG_IO, &io_header); - if (ret < 0) - return -1; - - return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; } static int get_stream_blocksize(BlockDriverState *bdrv) @@ -449,120 +353,125 @@ static int get_stream_blocksize(BlockDriverState *bdrv) io_header.timeout = 6000; /* XXX */ ret = bdrv_ioctl(bdrv, SG_IO, &io_header); - if (ret < 0) + if (ret < 0 || io_header.driver_status || io_header.host_status) { return -1; - - return (buf[9] << 16) | (buf[10] << 8) | buf[11]; -} - -static void scsi_generic_purge_requests(SCSIGenericState *s) -{ - SCSIGenericReq *r; - - while (!QTAILQ_EMPTY(&s->qdev.requests)) { - r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests)); - if (r->req.aiocb) { - bdrv_aio_cancel(r->req.aiocb); - } - scsi_remove_request(r); } + return (buf[9] << 16) | (buf[10] << 8) | buf[11]; } static void scsi_generic_reset(DeviceState *dev) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev); + SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev); - scsi_generic_purge_requests(s); + scsi_device_purge_requests(s, SENSE_CODE(RESET)); } -static void scsi_destroy(SCSIDevice *d) +static void scsi_destroy(SCSIDevice *s) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d); - - scsi_generic_purge_requests(s); - blockdev_mark_auto_del(s->qdev.conf.bs); + scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE)); + blockdev_mark_auto_del(s->conf.bs); } -static int scsi_generic_initfn(SCSIDevice *dev) +static int scsi_generic_initfn(SCSIDevice *s) { - SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev); int sg_version; struct sg_scsi_id scsiid; - if (!s->qdev.conf.bs) { + if (!s->conf.bs) { error_report("scsi-generic: drive property not set"); return -1; } - s->bs = s->qdev.conf.bs; /* check we are really using a /dev/sg* file */ - if (!bdrv_is_sg(s->bs)) { + if (!bdrv_is_sg(s->conf.bs)) { error_report("scsi-generic: not /dev/sg*"); return -1; } - if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) { + if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) { error_report("Device doesn't support drive option werror"); return -1; } - if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) { + if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) { error_report("Device doesn't support drive option rerror"); return -1; } /* check we are using a driver managing SG_IO (version 3 and after */ - if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 || + if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 || sg_version < 30000) { error_report("scsi-generic: scsi generic interface too old"); return -1; } /* get LUN of the /dev/sg? */ - if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) { + if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) { error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed"); return -1; } /* define device state */ - s->lun = scsiid.lun; - DPRINTF("LUN %d\n", s->lun); - s->qdev.type = scsiid.scsi_type; - DPRINTF("device type %d\n", s->qdev.type); - if (s->qdev.type == TYPE_TAPE) { - s->qdev.blocksize = get_stream_blocksize(s->bs); - if (s->qdev.blocksize == -1) - s->qdev.blocksize = 0; - } else { - s->qdev.blocksize = get_blocksize(s->bs); - /* removable media returns 0 if not present */ - if (s->qdev.blocksize <= 0) { - if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM) - s->qdev.blocksize = 2048; - else - s->qdev.blocksize = 512; + s->type = scsiid.scsi_type; + DPRINTF("device type %d\n", s->type); + if (s->type == TYPE_DISK || s->type == TYPE_ROM) { + add_boot_device_path(s->conf.bootindex, &s->qdev, NULL); + } + + switch (s->type) { + case TYPE_TAPE: + s->blocksize = get_stream_blocksize(s->conf.bs); + if (s->blocksize == -1) { + s->blocksize = 0; } + break; + + /* Make a guess for block devices, we'll fix it when the guest sends. + * READ CAPACITY. If they don't, they likely would assume these sizes + * anyway. (TODO: they could also send MODE SENSE). + */ + case TYPE_ROM: + case TYPE_WORM: + s->blocksize = 2048; + break; + default: + s->blocksize = 512; + break; } - DPRINTF("block size %d\n", s->qdev.blocksize); - s->driver_status = 0; - memset(s->sensebuf, 0, sizeof(s->sensebuf)); - bdrv_set_removable(s->bs, 0); + + DPRINTF("block size %d\n", s->blocksize); return 0; } +const SCSIReqOps scsi_generic_req_ops = { + .size = sizeof(SCSIGenericReq), + .free_req = scsi_free_request, + .send_command = scsi_send_command, + .read_data = scsi_read_data, + .write_data = scsi_write_data, + .cancel_io = scsi_cancel_io, + .get_buf = scsi_get_buf, +}; + +static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, + uint8_t *buf, void *hba_private) +{ + SCSIRequest *req; + + req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private); + return req; +} + static SCSIDeviceInfo scsi_generic_info = { .qdev.name = "scsi-generic", + .qdev.fw_name = "disk", .qdev.desc = "pass through generic scsi device (/dev/sg*)", - .qdev.size = sizeof(SCSIGenericState), + .qdev.size = sizeof(SCSIDevice), .qdev.reset = scsi_generic_reset, .init = scsi_generic_initfn, .destroy = scsi_destroy, - .send_command = scsi_send_command, - .read_data = scsi_read_data, - .write_data = scsi_write_data, - .cancel_io = scsi_cancel_io, - .get_buf = scsi_get_buf, + .alloc_req = scsi_new_request, .qdev.props = (Property[]) { - DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf), + DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf), DEFINE_PROP_END_OF_LIST(), }, }; diff --git a/hw/scsi.h b/hw/scsi.h index d3b5d56..ab6e952 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -3,23 +3,19 @@ #include "qdev.h" #include "block.h" -#include "block_int.h" +#include "sysemu.h" #define MAX_SCSI_DEVS 255 #define SCSI_CMD_BUF_SIZE 16 -/* scsi-disk.c */ -enum scsi_reason { - SCSI_REASON_DONE, /* Command complete. */ - SCSI_REASON_DATA /* Transfer complete, more data required. */ -}; - typedef struct SCSIBus SCSIBus; +typedef struct SCSIBusInfo SCSIBusInfo; +typedef struct SCSICommand SCSICommand; typedef struct SCSIDevice SCSIDevice; typedef struct SCSIDeviceInfo SCSIDeviceInfo; -typedef void (*scsi_completionfn)(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg); +typedef struct SCSIRequest SCSIRequest; +typedef struct SCSIReqOps SCSIReqOps; enum SCSIXferMode { SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */ @@ -27,33 +23,59 @@ enum SCSIXferMode { SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */ }; -typedef struct SCSIRequest { +typedef struct SCSISense { + uint8_t key; + uint8_t asc; + uint8_t ascq; +} SCSISense; + +#define SCSI_SENSE_BUF_SIZE 96 + +struct SCSICommand { + uint8_t buf[SCSI_CMD_BUF_SIZE]; + int len; + size_t xfer; + uint64_t lba; + enum SCSIXferMode mode; +}; + +struct SCSIRequest { SCSIBus *bus; SCSIDevice *dev; + const SCSIReqOps *ops; + uint32_t refcount; uint32_t tag; uint32_t lun; uint32_t status; - struct { - uint8_t buf[SCSI_CMD_BUF_SIZE]; - int len; - size_t xfer; - uint64_t lba; - enum SCSIXferMode mode; - } cmd; + SCSICommand cmd; BlockDriverAIOCB *aiocb; + uint8_t sense[SCSI_SENSE_BUF_SIZE]; + uint32_t sense_len; bool enqueued; + bool io_canceled; + bool retry; + void *hba_private; QTAILQ_ENTRY(SCSIRequest) next; -} SCSIRequest; +}; struct SCSIDevice { DeviceState qdev; + VMChangeStateEntry *vmsentry; + QEMUBH *bh; uint32_t id; BlockConf conf; SCSIDeviceInfo *info; + SCSISense unit_attention; + bool sense_is_ua; + uint8_t sense[SCSI_SENSE_BUF_SIZE]; + uint32_t sense_len; QTAILQ_HEAD(, SCSIRequest) requests; + uint32_t channel; + uint32_t lun; int blocksize; int type; + uint64_t max_lba; }; /* cdrom.c */ @@ -61,33 +83,43 @@ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track); int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num); /* scsi-bus.c */ +struct SCSIReqOps { + size_t size; + void (*free_req)(SCSIRequest *req); + int32_t (*send_command)(SCSIRequest *req, uint8_t *buf); + void (*read_data)(SCSIRequest *req); + void (*write_data)(SCSIRequest *req); + void (*cancel_io)(SCSIRequest *req); + uint8_t *(*get_buf)(SCSIRequest *req); +}; + typedef int (*scsi_qdev_initfn)(SCSIDevice *dev); struct SCSIDeviceInfo { DeviceInfo qdev; scsi_qdev_initfn init; void (*destroy)(SCSIDevice *s); - int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf, - int lun); - void (*read_data)(SCSIDevice *s, uint32_t tag); - int (*write_data)(SCSIDevice *s, uint32_t tag); - void (*cancel_io)(SCSIDevice *s, uint32_t tag); - uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag); + SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun, + uint8_t *buf, void *hba_private); + void (*unit_attention_reported)(SCSIDevice *s); +}; + +struct SCSIBusInfo { + int tcq; + int max_channel, max_target, max_lun; + void (*transfer_data)(SCSIRequest *req, uint32_t arg); + void (*complete)(SCSIRequest *req, uint32_t arg); + void (*cancel)(SCSIRequest *req); }; -typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, - int unit); struct SCSIBus { BusState qbus; int busnr; - int tcq, ndev; - scsi_completionfn complete; - - SCSIDevice *devs[MAX_SCSI_DEVS]; + SCSISense unit_attention; + const SCSIBusInfo *info; }; -void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev, - scsi_completionfn complete); +void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info); void scsi_qdev_register(SCSIDeviceInfo *info); static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) @@ -96,15 +128,84 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) } SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, - int unit, bool removable); + int unit, bool removable, int bootindex); int scsi_bus_legacy_handle_cmdline(SCSIBus *bus); -SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun); -SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag); +/* + * Predefined sense codes + */ + +/* No sense data available */ +extern const struct SCSISense sense_code_NO_SENSE; +/* LUN not ready, Manual intervention required */ +extern const struct SCSISense sense_code_LUN_NOT_READY; +/* LUN not ready, Medium not present */ +extern const struct SCSISense sense_code_NO_MEDIUM; +/* LUN not ready, medium removal prevented */ +extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED; +/* Hardware error, internal target failure */ +extern const struct SCSISense sense_code_TARGET_FAILURE; +/* Illegal request, invalid command operation code */ +extern const struct SCSISense sense_code_INVALID_OPCODE; +/* Illegal request, LBA out of range */ +extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE; +/* Illegal request, Invalid field in CDB */ +extern const struct SCSISense sense_code_INVALID_FIELD; +/* Illegal request, LUN not supported */ +extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED; +/* Illegal request, Saving parameters not supported */ +extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED; +/* Illegal request, Incompatible format */ +extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT; +/* Illegal request, medium removal prevented */ +extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED; +/* Command aborted, I/O process terminated */ +extern const struct SCSISense sense_code_IO_ERROR; +/* Command aborted, I_T Nexus loss occurred */ +extern const struct SCSISense sense_code_I_T_NEXUS_LOSS; +/* Command aborted, Logical Unit failure */ +extern const struct SCSISense sense_code_LUN_FAILURE; +/* LUN not ready, Medium not present */ +extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM; +/* Unit attention, Power on, reset or bus device reset occurred */ +extern const struct SCSISense sense_code_RESET; +/* Unit attention, Medium may have changed*/ +extern const struct SCSISense sense_code_MEDIUM_CHANGED; +/* Unit attention, Reported LUNs data has changed */ +extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED; +/* Unit attention, Device internal reset */ +extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET; + +#define SENSE_CODE(x) sense_code_ ## x + +int scsi_sense_valid(SCSISense sense); +int scsi_build_sense(uint8_t *in_buf, int in_len, + uint8_t *buf, int len, bool fixed); + +SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, + uint32_t tag, uint32_t lun, void *hba_private); +SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, + uint8_t *buf, void *hba_private); +int32_t scsi_req_enqueue(SCSIRequest *req); void scsi_req_free(SCSIRequest *req); +SCSIRequest *scsi_req_ref(SCSIRequest *req); +void scsi_req_unref(SCSIRequest *req); -int scsi_req_parse(SCSIRequest *req, uint8_t *buf); +void scsi_req_build_sense(SCSIRequest *req, SCSISense sense); void scsi_req_print(SCSIRequest *req); -void scsi_req_complete(SCSIRequest *req); +void scsi_req_continue(SCSIRequest *req); +void scsi_req_data(SCSIRequest *req, int len); +void scsi_req_complete(SCSIRequest *req, int status); +uint8_t *scsi_req_get_buf(SCSIRequest *req); +int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len); +void scsi_req_abort(SCSIRequest *req, int status); +void scsi_req_cancel(SCSIRequest *req); +void scsi_req_retry(SCSIRequest *req); +void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); +int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); + +/* scsi-generic.c. */ +extern const SCSIReqOps scsi_generic_req_ops; #endif diff --git a/hw/sd.c b/hw/sd.c index 0b90232..10e26ad 100644 --- a/hw/sd.c +++ b/hw/sd.c @@ -31,7 +31,6 @@ #include "hw.h" #include "block.h" -#include "block_int.h" #include "sd.h" //#define DEBUG_SD 1 @@ -393,9 +392,7 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv) } else { sect = 0; } - sect <<= 9; - - size = sect + 1; + size = sect << 9; sect = (size >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)) + 1; @@ -411,9 +408,9 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv) sd->bdrv = bdrv; if (sd->wp_groups) - qemu_free(sd->wp_groups); + g_free(sd->wp_groups); sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : 0; - sd->wp_groups = (int *) qemu_mallocz(sizeof(int) * sect); + sd->wp_groups = (int *) g_malloc0(sizeof(int) * sect); memset(sd->function_group, 0, sizeof(int) * 6); sd->erase_start = 0; sd->erase_end = 0; @@ -422,14 +419,10 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv) sd->pwd_len = 0; } -static void sd_cardchange(void *opaque, int reason) +static void sd_cardchange(void *opaque, bool load) { SDState *sd = opaque; - if (!(reason & CHANGE_MEDIA)) { - return; - } - qemu_set_irq(sd->inserted_cb, bdrv_is_inserted(sd->bdrv)); if (bdrv_is_inserted(sd->bdrv)) { sd_reset(sd, sd->bdrv); @@ -437,6 +430,10 @@ static void sd_cardchange(void *opaque, int reason) } } +static const BlockDevOps sd_block_ops = { + .change_media_cb = sd_cardchange, +}; + /* We do not model the chip select pin, so allow the board to select whether card should be in SSI or MMC/SD mode. It is also up to the board to ensure that ssi transfers only occur when the chip select @@ -445,13 +442,14 @@ SDState *sd_init(BlockDriverState *bs, int is_spi) { SDState *sd; - sd = (SDState *) qemu_mallocz(sizeof(SDState)); + sd = (SDState *) g_malloc0(sizeof(SDState)); sd->buf = qemu_blockalign(bs, 512); sd->spi = is_spi; sd->enable = 1; sd_reset(sd, bs); if (sd->bdrv) { - bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); + bdrv_attach_dev_nofail(sd->bdrv, sd); + bdrv_set_dev_ops(sd->bdrv, &sd_block_ops, sd); } return sd; } @@ -460,8 +458,8 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert) { sd->readonly_cb = readonly; sd->inserted_cb = insert; - qemu_set_irq(readonly, bdrv_is_read_only(sd->bdrv)); - qemu_set_irq(insert, bdrv_is_inserted(sd->bdrv)); + qemu_set_irq(readonly, sd->bdrv ? bdrv_is_read_only(sd->bdrv) : 0); + qemu_set_irq(insert, sd->bdrv ? bdrv_is_inserted(sd->bdrv) : 0); } static void sd_erase(SDState *sd) @@ -1103,8 +1101,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, break; } break; - - case 52: + + case 52: case 53: /* CMD52, CMD53: reserved for SDIO cards * (see the SDIO Simplified Specification V2.0) @@ -1115,7 +1113,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, sd->card_status |= ILLEGAL_COMMAND; return sd_r0; - /* Application specific commands (Class 8) */ case 55: /* CMD55: APP_CMD */ if (sd->rca != rca) @@ -1451,14 +1448,8 @@ void sd_write_data(SDState *sd, uint8_t value) break; case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ - sd->data[sd->data_offset ++] = value; - if (sd->data_offset >= sd->blk_len) { - /* TODO: Check CRC before committing */ - sd->state = sd_programming_state; - BLK_WRITE_BLOCK(sd->data_start, sd->data_offset); - sd->blk_written ++; - sd->data_start += sd->blk_len; - sd->data_offset = 0; + if (sd->data_offset == 0) { + /* Start of the block - lets check the address is valid */ if (sd->data_start + sd->blk_len > sd->size) { sd->card_status |= ADDRESS_ERROR; break; @@ -1467,6 +1458,15 @@ void sd_write_data(SDState *sd, uint8_t value) sd->card_status |= WP_VIOLATION; break; } + } + sd->data[sd->data_offset++] = value; + if (sd->data_offset >= sd->blk_len) { + /* TODO: Check CRC before committing */ + sd->state = sd_programming_state; + BLK_WRITE_BLOCK(sd->data_start, sd->data_offset); + sd->blk_written++; + sd->data_start += sd->blk_len; + sd->data_offset = 0; sd->csd[14] |= 0x40; /* Bzzzzzzztt .... Operation complete. */ diff --git a/hw/serial.c b/hw/serial.c index 2c4af61..d35c7a9 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -153,6 +153,7 @@ struct SerialState { int poll_msl; struct QEMUTimer *modem_status_poll; + MemoryRegion io; }; typedef struct ISASerialState { @@ -274,7 +275,7 @@ static void serial_update_parameters(SerialState *s) ssp.data_bits = data_bits; ssp.stop_bits = stop_bits; s->char_transmit_time = (get_ticks_per_sec() / speed) * frame_size; - qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); DPRINTF("speed=%d parity=%c data=%d stop=%d\n", speed, parity, data_bits, stop_bits); @@ -287,7 +288,7 @@ static void serial_update_msl(SerialState *s) qemu_del_timer(s->modem_status_poll); - if (qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) { + if (qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) { s->poll_msl = -1; return; } @@ -312,13 +313,13 @@ static void serial_update_msl(SerialState *s) We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */ if (s->poll_msl) - qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + get_ticks_per_sec() / 100); + qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 100); } static void serial_xmit(void *opaque) { SerialState *s = opaque; - uint64_t new_xmit_ts = qemu_get_clock(vm_clock); + uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock); if (s->tsr_retry <= 0) { if (s->fcr & UART_FCR_FE) { @@ -334,7 +335,7 @@ static void serial_xmit(void *opaque) if (s->mcr & UART_MCR_LOOP) { /* in loopback mode, say that we just received a char */ serial_receive1(s, &s->tsr, 1); - } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) { + } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) { if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) { s->tsr_retry++; qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time); @@ -350,7 +351,7 @@ static void serial_xmit(void *opaque) s->tsr_retry = 0; } - s->last_xmit_ts = qemu_get_clock(vm_clock); + s->last_xmit_ts = qemu_get_clock_ns(vm_clock); if (!(s->lsr & UART_LSR_THRE)) qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time); @@ -467,7 +468,7 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) break_enable = (val >> 6) & 1; if (break_enable != s->last_break_enable) { s->last_break_enable = break_enable; - qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK, + qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK, &break_enable); } } @@ -482,7 +483,7 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) if (s->poll_msl >= 0 && old_mcr != s->mcr) { - qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags); flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR); @@ -491,10 +492,10 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) if (val & UART_MCR_DTR) flags |= CHR_TIOCM_DTR; - qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags); /* Update the modem status after a one-character-send wait-time, since there may be a response from the device/computer at the other end of the serial line */ - qemu_mod_timer(s->modem_status_poll, qemu_get_clock(vm_clock) + s->char_transmit_time); + qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + s->char_transmit_time); } } break; @@ -525,7 +526,7 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr) if (s->recv_fifo.count == 0) s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); else - qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4); + qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4); s->timeout_ipending = 0; } else { ret = s->rbr; @@ -641,7 +642,7 @@ static void serial_receive1(void *opaque, const uint8_t *buf, int size) } s->lsr |= UART_LSR_DR; /* call the timeout receive callback in 4 char transmit time */ - qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4); + qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4); } else { if (s->lsr & UART_LSR_DR) s->lsr |= UART_LSR_OE; @@ -720,7 +721,7 @@ static void serial_reset(void *opaque) fifo_clear(s,RECV_FIFO); fifo_clear(s,XMIT_FIFO); - s->last_xmit_ts = qemu_get_clock(vm_clock); + s->last_xmit_ts = qemu_get_clock_ns(vm_clock); s->thr_ipending = 0; s->last_break_enable = 0; @@ -734,10 +735,10 @@ static void serial_init_core(SerialState *s) exit(1); } - s->modem_status_poll = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_update_msl, s); + s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s); - s->fifo_timeout_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s); - s->transmit_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *) serial_xmit, s); + s->fifo_timeout_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s); + s->transmit_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_xmit, s); qemu_register_reset(serial_reset, s); @@ -755,6 +756,15 @@ void serial_set_frequency(SerialState *s, uint32_t frequency) static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; +static const MemoryRegionPortio serial_portio[] = { + { 0, 8, 1, .read = serial_ioport_read, .write = serial_ioport_write }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps serial_io_ops = { + .old_portio = serial_portio +}; + static int serial_isa_initfn(ISADevice *dev) { static int index; @@ -776,24 +786,11 @@ static int serial_isa_initfn(ISADevice *dev) serial_init_core(s); qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3); - register_ioport_write(isa->iobase, 8, 1, serial_ioport_write, s); - register_ioport_read(isa->iobase, 8, 1, serial_ioport_read, s); - isa_init_ioport_range(dev, isa->iobase, 8); + memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); + isa_register_ioport(dev, &s->io, isa->iobase); return 0; } -SerialState *serial_isa_init(int index, CharDriverState *chr) -{ - ISADevice *dev; - - dev = isa_create("isa-serial"); - qdev_prop_set_uint32(&dev->qdev, "index", index); - qdev_prop_set_chr(&dev->qdev, "chardev", chr); - if (qdev_init(&dev->qdev) < 0) - return NULL; - return &DO_UPCAST(ISASerialState, dev, dev)->state; -} - static const VMStateDescription vmstate_isa_serial = { .name = "serial", .version_id = 3, @@ -809,7 +806,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase, { SerialState *s; - s = qemu_mallocz(sizeof(SerialState)); + s = g_malloc0(sizeof(SerialState)); s->irq = irq; s->baudbase = baudbase; @@ -824,126 +821,47 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase, } /* Memory mapped interface */ -static uint32_t serial_mm_readb(void *opaque, target_phys_addr_t addr) -{ - SerialState *s = opaque; - - return serial_ioport_read(s, addr >> s->it_shift) & 0xFF; -} - -static void serial_mm_writeb(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - SerialState *s = opaque; - - serial_ioport_write(s, addr >> s->it_shift, value & 0xFF); -} - -static uint32_t serial_mm_readw_be(void *opaque, target_phys_addr_t addr) -{ - SerialState *s = opaque; - uint32_t val; - - val = serial_ioport_read(s, addr >> s->it_shift) & 0xFFFF; - val = bswap16(val); - return val; -} - -static uint32_t serial_mm_readw_le(void *opaque, target_phys_addr_t addr) -{ - SerialState *s = opaque; - uint32_t val; - - val = serial_ioport_read(s, addr >> s->it_shift) & 0xFFFF; - return val; -} - -static void serial_mm_writew_be(void *opaque, target_phys_addr_t addr, - uint32_t value) +static uint64_t serial_mm_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SerialState *s = opaque; - - value = bswap16(value); - serial_ioport_write(s, addr >> s->it_shift, value & 0xFFFF); + return serial_ioport_read(s, addr >> s->it_shift); } -static void serial_mm_writew_le(void *opaque, target_phys_addr_t addr, - uint32_t value) +static void serial_mm_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { SerialState *s = opaque; - - serial_ioport_write(s, addr >> s->it_shift, value & 0xFFFF); -} - -static uint32_t serial_mm_readl_be(void *opaque, target_phys_addr_t addr) -{ - SerialState *s = opaque; - uint32_t val; - - val = serial_ioport_read(s, addr >> s->it_shift); - val = bswap32(val); - return val; -} - -static uint32_t serial_mm_readl_le(void *opaque, target_phys_addr_t addr) -{ - SerialState *s = opaque; - uint32_t val; - - val = serial_ioport_read(s, addr >> s->it_shift); - return val; -} - -static void serial_mm_writel_be(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - SerialState *s = opaque; - - value = bswap32(value); + value &= ~0u >> (32 - (size * 8)); serial_ioport_write(s, addr >> s->it_shift, value); } -static void serial_mm_writel_le(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - SerialState *s = opaque; - - serial_ioport_write(s, addr >> s->it_shift, value); -} - -static CPUReadMemoryFunc * const serial_mm_read_be[] = { - &serial_mm_readb, - &serial_mm_readw_be, - &serial_mm_readl_be, -}; - -static CPUWriteMemoryFunc * const serial_mm_write_be[] = { - &serial_mm_writeb, - &serial_mm_writew_be, - &serial_mm_writel_be, -}; - -static CPUReadMemoryFunc * const serial_mm_read_le[] = { - &serial_mm_readb, - &serial_mm_readw_le, - &serial_mm_readl_le, -}; - -static CPUWriteMemoryFunc * const serial_mm_write_le[] = { - &serial_mm_writeb, - &serial_mm_writew_le, - &serial_mm_writel_le, +static const MemoryRegionOps serial_mm_ops[3] = { + [DEVICE_NATIVE_ENDIAN] = { + .read = serial_mm_read, + .write = serial_mm_write, + .endianness = DEVICE_NATIVE_ENDIAN, + }, + [DEVICE_LITTLE_ENDIAN] = { + .read = serial_mm_read, + .write = serial_mm_write, + .endianness = DEVICE_LITTLE_ENDIAN, + }, + [DEVICE_BIG_ENDIAN] = { + .read = serial_mm_read, + .write = serial_mm_write, + .endianness = DEVICE_BIG_ENDIAN, + }, }; -SerialState *serial_mm_init (target_phys_addr_t base, int it_shift, - qemu_irq irq, int baudbase, - CharDriverState *chr, int ioregister, - int be) +SerialState *serial_mm_init(MemoryRegion *address_space, + target_phys_addr_t base, int it_shift, + qemu_irq irq, int baudbase, + CharDriverState *chr, enum device_endian end) { SerialState *s; - int s_io_memory; - s = qemu_mallocz(sizeof(SerialState)); + s = g_malloc0(sizeof(SerialState)); s->it_shift = it_shift; s->irq = irq; @@ -953,18 +871,10 @@ SerialState *serial_mm_init (target_phys_addr_t base, int it_shift, serial_init_core(s); vmstate_register(NULL, base, &vmstate_serial, s); - if (ioregister) { - if (be) { - s_io_memory = cpu_register_io_memory(serial_mm_read_be, - serial_mm_write_be, s, - DEVICE_NATIVE_ENDIAN); - } else { - s_io_memory = cpu_register_io_memory(serial_mm_read_le, - serial_mm_write_le, s, - DEVICE_NATIVE_ENDIAN); - } - cpu_register_physical_memory(base, 8 << it_shift, s_io_memory); - } + memory_region_init_io(&s->io, &serial_mm_ops[end], s, + "serial", 8 << it_shift); + memory_region_add_subregion(address_space, base, &s->io); + serial_update_msl(s); return s; } diff --git a/hw/sh7750.c b/hw/sh7750.c index 19d5bf8..9f3ea92 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -29,7 +29,6 @@ #include "sh7750_regs.h" #include "sh7750_regnames.h" #include "sh_intc.h" -#include "exec-all.h" #include "cpu.h" #define NB_DEVICES 4 @@ -713,7 +712,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu) int sh7750_io_memory; int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */ - s = qemu_mallocz(sizeof(SH7750State)); + s = g_malloc0(sizeof(SH7750State)); s->cpu = cpu; s->periph_freq = 60000000; /* 60MHz */ sh7750_io_memory = cpu_register_io_memory(sh7750_mem_read, diff --git a/hw/sh7750_regs.h b/hw/sh7750_regs.h index 5a23a2c..6ec13ab 100644 --- a/hw/sh7750_regs.h +++ b/hw/sh7750_regs.h @@ -23,9 +23,9 @@ * All register has 2 addresses: in 0xff000000 - 0xffffffff (P4 address) and * in 0x1f000000 - 0x1fffffff (area 7 address) */ -#define SH7750_P4_BASE 0xff000000 /* Accessable only in - priveleged mode */ -#define SH7750_A7_BASE 0x1f000000 /* Accessable only using TLB */ +#define SH7750_P4_BASE 0xff000000 /* Accessible only in + privileged mode */ +#define SH7750_A7_BASE 0x1f000000 /* Accessible only using TLB */ #define SH7750_P4_REG32(ofs) (SH7750_P4_BASE + (ofs)) #define SH7750_A7_REG32(ofs) (SH7750_A7_BASE + (ofs)) diff --git a/hw/sh_intc.c b/hw/sh_intc.c index 0734da9..e07424f 100644 --- a/hw/sh_intc.c +++ b/hw/sh_intc.c @@ -5,7 +5,7 @@ * Based on sh_timer.c and arm_timer.c by Paul Brook * Copyright (c) 2005-2006 CodeSourcery. * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sh_intc.h" @@ -382,13 +382,14 @@ void sh_intc_register_sources(struct intc_desc *desc, sh_intc_register_source(desc, vect->enum_id, groups, nr_groups); s = sh_intc_source(desc, vect->enum_id); - if (s) - s->vect = vect->vect; + if (s) { + s->vect = vect->vect; #ifdef DEBUG_INTC_SOURCES - printf("sh_intc: registered source %d -> 0x%04x (%d/%d)\n", - vect->enum_id, s->vect, s->enable_count, s->enable_max); + printf("sh_intc: registered source %d -> 0x%04x (%d/%d)\n", + vect->enum_id, s->vect, s->enable_count, s->enable_max); #endif + } } if (groups) { @@ -431,7 +432,7 @@ int sh_intc_init(struct intc_desc *desc, desc->nr_prio_regs = nr_prio_regs; i = sizeof(struct intc_source) * nr_sources; - desc->sources = qemu_mallocz(i); + desc->sources = g_malloc0(i); for (i = 0; i < desc->nr_sources; i++) { struct intc_source *source = desc->sources + i; diff --git a/hw/sh_pci.c b/hw/sh_pci.c index e99d8db..36f3930 100644 --- a/hw/sh_pci.c +++ b/hw/sh_pci.c @@ -26,19 +26,23 @@ #include "pci.h" #include "pci_host.h" #include "bswap.h" +#include "exec-memory.h" typedef struct SHPCIState { SysBusDevice busdev; PCIBus *bus; PCIDevice *dev; qemu_irq irq[4]; - int memconfig; + MemoryRegion memconfig_p4; + MemoryRegion memconfig_a7; + MemoryRegion isa; uint32_t par; uint32_t mbr; uint32_t iobr; } SHPCIState; -static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val) +static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint64_t val, + unsigned size) { SHPCIState *pcic = p; switch(addr) { @@ -53,10 +57,10 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val) break; case 0x1c8: if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) { - cpu_register_physical_memory(pcic->iobr & 0xfffc0000, 0x40000, - IO_MEM_UNASSIGNED); + memory_region_del_subregion(get_system_memory(), &pcic->isa); pcic->iobr = val & 0xfffc0001; - isa_mmio_init(pcic->iobr & 0xfffc0000, 0x40000); + memory_region_add_subregion(get_system_memory(), + pcic->iobr & 0xfffc0000, &pcic->isa); } break; case 0x220: @@ -65,7 +69,8 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val) } } -static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr) +static uint64_t sh_pci_reg_read (void *p, target_phys_addr_t addr, + unsigned size) { SHPCIState *pcic = p; switch(addr) { @@ -83,14 +88,14 @@ static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr) return 0; } -typedef struct { - CPUReadMemoryFunc * const r[3]; - CPUWriteMemoryFunc * const w[3]; -} MemOp; - -static MemOp sh_pci_reg = { - { NULL, NULL, sh_pci_reg_read }, - { NULL, NULL, sh_pci_reg_write }, +static const MemoryRegionOps sh_pci_reg_ops = { + .read = sh_pci_reg_read, + .write = sh_pci_reg_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; static int sh_pci_map_irq(PCIDevice *d, int irq_num) @@ -109,11 +114,23 @@ static void sh_pci_map(SysBusDevice *dev, target_phys_addr_t base) { SHPCIState *s = FROM_SYSBUS(SHPCIState, dev); - cpu_register_physical_memory(P4ADDR(base), 0x224, s->memconfig); - cpu_register_physical_memory(A7ADDR(base), 0x224, s->memconfig); - + memory_region_add_subregion(get_system_memory(), + P4ADDR(base), + &s->memconfig_p4); + memory_region_add_subregion(get_system_memory(), + A7ADDR(base), + &s->memconfig_a7); s->iobr = 0xfe240000; - isa_mmio_init(s->iobr, 0x40000); + memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa); +} + +static void sh_pci_unmap(SysBusDevice *dev, target_phys_addr_t base) +{ + SHPCIState *s = FROM_SYSBUS(SHPCIState, dev); + + memory_region_del_subregion(get_system_memory(), &s->memconfig_p4); + memory_region_del_subregion(get_system_memory(), &s->memconfig_a7); + memory_region_del_subregion(get_system_memory(), &s->isa); } static int sh_pci_init_device(SysBusDevice *dev) @@ -127,18 +144,24 @@ static int sh_pci_init_device(SysBusDevice *dev) } s->bus = pci_register_bus(&s->busdev.qdev, "pci", sh_pci_set_irq, sh_pci_map_irq, - s->irq, PCI_DEVFN(0, 0), 4); - s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w, - s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio_cb(dev, 0x224, sh_pci_map); + s->irq, + get_system_memory(), + get_system_io(), + PCI_DEVFN(0, 0), 4); + memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s, + "sh_pci", 0x224); + memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_p4, + 0, 0x224); + isa_mmio_setup(&s->isa, 0x40000); + sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap); + sysbus_init_mmio_region(dev, &s->memconfig_a7); + sysbus_init_mmio_region(dev, &s->isa); s->dev = pci_create_simple(s->bus, PCI_DEVFN(0, 0), "sh_pci_host"); return 0; } static int sh_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_HITACHI); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_HITACHI_SH7751R); pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT); pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST | PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); @@ -149,6 +172,8 @@ static PCIDeviceInfo sh_pci_host_info = { .qdev.name = "sh_pci_host", .qdev.size = sizeof(PCIDevice), .init = sh_pci_host_init, + .vendor_id = PCI_VENDOR_ID_HITACHI, + .device_id = PCI_DEVICE_ID_HITACHI_SH7751R, }; static void sh_pci_register_devices(void) diff --git a/hw/sh_serial.c b/hw/sh_serial.c index 191f4a6..a20c59e 100644 --- a/hw/sh_serial.c +++ b/hw/sh_serial.c @@ -105,7 +105,7 @@ static void sh_serial_write(void *opaque, uint32_t offs, uint32_t val) case 0x0c: /* FTDR / TDR */ if (s->chr) { ch = val; - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); } s->dr = val; s->flags &= ~SH_SERIAL_FLAG_TDE; @@ -361,7 +361,7 @@ void sh_serial_init (target_phys_addr_t base, int feat, sh_serial_state *s; int s_io_memory; - s = qemu_mallocz(sizeof(sh_serial_state)); + s = g_malloc0(sizeof(sh_serial_state)); s->feat = feat; s->flags = SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE; diff --git a/hw/sh_timer.c b/hw/sh_timer.c index 5eec6b7..dca3c94 100644 --- a/hw/sh_timer.c +++ b/hw/sh_timer.c @@ -5,7 +5,7 @@ * Based on arm_timer.c by Paul Brook * Copyright (c) 2005-2006 CodeSourcery. * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "hw.h" @@ -188,7 +188,7 @@ static void *sh_timer_init(uint32_t freq, int feat, qemu_irq irq) sh_timer_state *s; QEMUBH *bh; - s = (sh_timer_state *)qemu_mallocz(sizeof(sh_timer_state)); + s = (sh_timer_state *)g_malloc0(sizeof(sh_timer_state)); s->freq = freq; s->feat = feat; s->tcor = 0xffffffff; @@ -311,7 +311,7 @@ void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq, tmu012_state *s; int timer_feat = (feat & TMU012_FEAT_EXTCLK) ? TIMER_FEAT_EXTCLK : 0; - s = (tmu012_state *)qemu_mallocz(sizeof(tmu012_state)); + s = (tmu012_state *)g_malloc0(sizeof(tmu012_state)); s->feat = feat; s->timer[0] = sh_timer_init(freq, timer_feat, ch0_irq); s->timer[1] = sh_timer_init(freq, timer_feat, ch1_irq); diff --git a/hw/shix.c b/hw/shix.c index 638bf16..dbf4764 100644 --- a/hw/shix.c +++ b/hw/shix.c @@ -28,7 +28,6 @@ More information in target-sh4/README.sh4 */ #include "hw.h" -#include "pc.h" #include "sh.h" #include "sysemu.h" #include "boards.h" @@ -37,16 +36,6 @@ #define BIOS_FILENAME "shix_bios.bin" #define BIOS_ADDRESS 0xA0000000 -void irq_info(Monitor *mon) -{ - /* XXXXX */ -} - -void pic_info(Monitor *mon) -{ - /* XXXXX */ -} - static void shix_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c index a83e5b8..329c251 100644 --- a/hw/slavio_intctl.c +++ b/hw/slavio_intctl.c @@ -46,22 +46,22 @@ struct SLAVIO_INTCTLState; typedef struct SLAVIO_CPUINTCTLState { - uint32_t intreg_pending; struct SLAVIO_INTCTLState *master; + uint32_t intreg_pending; uint32_t cpu; uint32_t irl_out; } SLAVIO_CPUINTCTLState; typedef struct SLAVIO_INTCTLState { SysBusDevice busdev; - uint32_t intregm_pending; - uint32_t intregm_disabled; - uint32_t target_cpu; #ifdef DEBUG_IRQ_COUNT uint64_t irq_count[32]; #endif qemu_irq cpu_irqs[MAX_CPUS][MAX_PILS]; SLAVIO_CPUINTCTLState slaves[MAX_CPUS]; + uint32_t intregm_pending; + uint32_t intregm_disabled; + uint32_t target_cpu; } SLAVIO_INTCTLState; #define INTCTL_MAXADDR 0xf diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c index 198360d..1f5a2d7 100644 --- a/hw/slavio_misc.c +++ b/hw/slavio_misc.c @@ -37,13 +37,13 @@ typedef struct MiscState { SysBusDevice busdev; qemu_irq irq; + qemu_irq fdc_tc; uint32_t dummy; uint8_t config; uint8_t aux1, aux2; uint8_t diag, mctrl; uint8_t sysctrl; uint16_t leds; - qemu_irq fdc_tc; } MiscState; typedef struct APCState { diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c index 5511313..84449ba 100644 --- a/hw/slavio_timer.c +++ b/hw/slavio_timer.c @@ -48,16 +48,16 @@ typedef struct CPUTimerState { qemu_irq irq; ptimer_state *timer; uint32_t count, counthigh, reached; - uint64_t limit; - // processor only + /* processor only */ uint32_t running; + uint64_t limit; } CPUTimerState; typedef struct SLAVIO_TIMERState { SysBusDevice busdev; uint32_t num_cpus; - CPUTimerState cputimer[MAX_CPUS + 1]; uint32_t cputimer_mode; + CPUTimerState cputimer[MAX_CPUS + 1]; } SLAVIO_TIMERState; typedef struct TimerContext { @@ -381,7 +381,7 @@ static int slavio_timer_init1(SysBusDevice *dev) TimerContext *tc; for (i = 0; i <= MAX_CPUS; i++) { - tc = qemu_mallocz(sizeof(TimerContext)); + tc = g_malloc0(sizeof(TimerContext)); tc->s = s; tc->timer_index = i; diff --git a/hw/sm501.c b/hw/sm501.c index 0f0bf96..297bc9c 100644 --- a/hw/sm501.c +++ b/hw/sm501.c @@ -459,7 +459,7 @@ typedef struct SM501State { target_phys_addr_t base; uint32_t local_mem_size_index; uint8_t * local_mem; - ram_addr_t local_mem_offset; + MemoryRegion local_mem_region; uint32_t last_width; uint32_t last_height; @@ -726,7 +726,8 @@ static void sm501_2d_operation(SM501State * s) } } -static uint32_t sm501_system_config_read(void *opaque, target_phys_addr_t addr) +static uint64_t sm501_system_config_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SM501State * s = (SM501State *)opaque; uint32_t ret = 0; @@ -778,12 +779,12 @@ static uint32_t sm501_system_config_read(void *opaque, target_phys_addr_t addr) return ret; } -static void sm501_system_config_write(void *opaque, - target_phys_addr_t addr, uint32_t value) +static void sm501_system_config_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { SM501State * s = (SM501State *)opaque; SM501_DPRINTF("sm501 system config regs : write addr=%x, val=%x\n", - addr, value); + (uint32_t)addr, (uint32_t)value); switch(addr) { case SM501_SYSTEM_CONTROL: @@ -821,21 +822,19 @@ static void sm501_system_config_write(void *opaque, default: printf("sm501 system config : not implemented register write." - " addr=%x, val=%x\n", (int)addr, value); + " addr=%x, val=%x\n", (int)addr, (uint32_t)value); abort(); } } -static CPUReadMemoryFunc * const sm501_system_config_readfn[] = { - NULL, - NULL, - &sm501_system_config_read, -}; - -static CPUWriteMemoryFunc * const sm501_system_config_writefn[] = { - NULL, - NULL, - &sm501_system_config_write, +static const MemoryRegionOps sm501_system_config_ops = { + .read = sm501_system_config_read, + .write = sm501_system_config_write, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static uint32_t sm501_palette_read(void *opaque, target_phys_addr_t addr) @@ -864,7 +863,8 @@ static void sm501_palette_write(void *opaque, *(uint32_t*)&s->dc_palette[addr] = value; } -static uint32_t sm501_disp_ctrl_read(void *opaque, target_phys_addr_t addr) +static uint64_t sm501_disp_ctrl_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SM501State * s = (SM501State *)opaque; uint32_t ret = 0; @@ -958,13 +958,12 @@ static uint32_t sm501_disp_ctrl_read(void *opaque, target_phys_addr_t addr) return ret; } -static void sm501_disp_ctrl_write(void *opaque, - target_phys_addr_t addr, - uint32_t value) +static void sm501_disp_ctrl_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { SM501State * s = (SM501State *)opaque; SM501_DPRINTF("sm501 disp ctrl regs : write addr=%x, val=%x\n", - addr, value); + (unsigned)addr, (unsigned)value); switch(addr) { case SM501_DC_PANEL_CONTROL: @@ -1059,24 +1058,23 @@ static void sm501_disp_ctrl_write(void *opaque, default: printf("sm501 disp ctrl : not implemented register write." - " addr=%x, val=%x\n", (int)addr, value); + " addr=%x, val=%x\n", (int)addr, (unsigned)value); abort(); } } -static CPUReadMemoryFunc * const sm501_disp_ctrl_readfn[] = { - NULL, - NULL, - &sm501_disp_ctrl_read, +static const MemoryRegionOps sm501_disp_ctrl_ops = { + .read = sm501_disp_ctrl_read, + .write = sm501_disp_ctrl_write, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const sm501_disp_ctrl_writefn[] = { - NULL, - NULL, - &sm501_disp_ctrl_write, -}; - -static uint32_t sm501_2d_engine_read(void *opaque, target_phys_addr_t addr) +static uint64_t sm501_2d_engine_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SM501State * s = (SM501State *)opaque; uint32_t ret = 0; @@ -1095,12 +1093,12 @@ static uint32_t sm501_2d_engine_read(void *opaque, target_phys_addr_t addr) return ret; } -static void sm501_2d_engine_write(void *opaque, - target_phys_addr_t addr, uint32_t value) +static void sm501_2d_engine_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { SM501State * s = (SM501State *)opaque; SM501_DPRINTF("sm501 2d engine regs : write addr=%x, val=%x\n", - addr, value); + (unsigned)addr, (unsigned)value); switch(addr) { case SM501_2D_SOURCE: @@ -1148,21 +1146,19 @@ static void sm501_2d_engine_write(void *opaque, break; default: printf("sm501 2d engine : not implemented register write." - " addr=%x, val=%x\n", (int)addr, value); + " addr=%x, val=%x\n", (int)addr, (unsigned)value); abort(); } } -static CPUReadMemoryFunc * const sm501_2d_engine_readfn[] = { - NULL, - NULL, - &sm501_2d_engine_read, -}; - -static CPUWriteMemoryFunc * const sm501_2d_engine_writefn[] = { - NULL, - NULL, - &sm501_2d_engine_write, +static const MemoryRegionOps sm501_2d_engine_ops = { + .read = sm501_2d_engine_read, + .write = sm501_2d_engine_write, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; /* draw line functions for all console modes */ @@ -1276,7 +1272,7 @@ static void sm501_draw_crt(SM501State * s) int y_start = -1; ram_addr_t page_min = ~0l; ram_addr_t page_max = 0l; - ram_addr_t offset = s->local_mem_offset; + ram_addr_t offset = 0; /* choose draw_line function */ switch (s->dc_crt_control & 3) { @@ -1333,7 +1329,8 @@ static void sm501_draw_crt(SM501State * s) /* check dirty flags for each line */ for (page = page0; page <= page1; page += TARGET_PAGE_SIZE) - if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) + if (memory_region_get_dirty(&s->local_mem_region, page, + DIRTY_MEMORY_VGA)) update = 1; /* draw line and change status */ @@ -1372,8 +1369,9 @@ static void sm501_draw_crt(SM501State * s) /* clear dirty flags */ if (page_min != ~0l) { - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); + memory_region_reset_dirty(&s->local_mem_region, + page_min, page_max + TARGET_PAGE_SIZE, + DIRTY_MEMORY_VGA); } } @@ -1385,17 +1383,17 @@ static void sm501_update_display(void *opaque) sm501_draw_crt(s); } -void sm501_init(uint32_t base, uint32_t local_mem_bytes, qemu_irq irq, - CharDriverState *chr) +void sm501_init(MemoryRegion *address_space_mem, uint32_t base, + uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr) { SM501State * s; DeviceState *dev; - int sm501_system_config_index; - int sm501_disp_ctrl_index; - int sm501_2d_engine_index; + MemoryRegion *sm501_system_config = g_new(MemoryRegion, 1); + MemoryRegion *sm501_disp_ctrl = g_new(MemoryRegion, 1); + MemoryRegion *sm501_2d_engine = g_new(MemoryRegion, 1); /* allocate management data region */ - s = (SM501State *)qemu_mallocz(sizeof(SM501State)); + s = (SM501State *)g_malloc0(sizeof(SM501State)); s->base = base; s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes); @@ -1407,27 +1405,26 @@ void sm501_init(uint32_t base, uint32_t local_mem_bytes, qemu_irq irq, s->dc_crt_control = 0x00010000; /* allocate local memory */ - s->local_mem_offset = qemu_ram_alloc(NULL, "sm501.local", local_mem_bytes); - s->local_mem = qemu_get_ram_ptr(s->local_mem_offset); - cpu_register_physical_memory(base, local_mem_bytes, s->local_mem_offset); + memory_region_init_ram(&s->local_mem_region, NULL, "sm501.local", + local_mem_bytes); + s->local_mem = memory_region_get_ram_ptr(&s->local_mem_region); + memory_region_add_subregion(address_space_mem, base, &s->local_mem_region); /* map mmio */ - sm501_system_config_index - = cpu_register_io_memory(sm501_system_config_readfn, - sm501_system_config_writefn, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base + MMIO_BASE_OFFSET, - 0x6c, sm501_system_config_index); - sm501_disp_ctrl_index = cpu_register_io_memory(sm501_disp_ctrl_readfn, - sm501_disp_ctrl_writefn, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base + MMIO_BASE_OFFSET + SM501_DC, - 0x1000, sm501_disp_ctrl_index); - sm501_2d_engine_index = cpu_register_io_memory(sm501_2d_engine_readfn, - sm501_2d_engine_writefn, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base + MMIO_BASE_OFFSET + SM501_2D_ENGINE, - 0x54, sm501_2d_engine_index); + memory_region_init_io(sm501_system_config, &sm501_system_config_ops, s, + "sm501-system-config", 0x6c); + memory_region_add_subregion(address_space_mem, base + MMIO_BASE_OFFSET, + sm501_system_config); + memory_region_init_io(sm501_disp_ctrl, &sm501_disp_ctrl_ops, s, + "sm501-disp-ctrl", 0x1000); + memory_region_add_subregion(address_space_mem, + base + MMIO_BASE_OFFSET + SM501_DC, + sm501_disp_ctrl); + memory_region_init_io(sm501_2d_engine, &sm501_2d_engine_ops, s, + "sm501-2d-engine", 0x54); + memory_region_add_subregion(address_space_mem, + base + MMIO_BASE_OFFSET + SM501_2D_ENGINE, + sm501_2d_engine); /* bridge to usb host emulation module */ dev = qdev_create(NULL, "sysbus-ohci"); @@ -1440,15 +1437,10 @@ void sm501_init(uint32_t base, uint32_t local_mem_bytes, qemu_irq irq, /* bridge to serial emulation module */ if (chr) { -#ifdef TARGET_WORDS_BIGENDIAN - serial_mm_init(base + MMIO_BASE_OFFSET + SM501_UART0, 2, - NULL, /* TODO : chain irq to IRL */ - 115200, chr, 1, 1); -#else - serial_mm_init(base + MMIO_BASE_OFFSET + SM501_UART0, 2, + serial_mm_init(address_space_mem, + base + MMIO_BASE_OFFSET + SM501_UART0, 2, NULL, /* TODO : chain irq to IRL */ - 115200, chr, 1, 0); -#endif + 115200, chr, DEVICE_NATIVE_ENDIAN); } /* create qemu graphic console */ diff --git a/hw/sm501_template.h b/hw/sm501_template.h index d1ceef9..2d4a3d8 100644 --- a/hw/sm501_template.h +++ b/hw/sm501_template.h @@ -120,7 +120,7 @@ static void glue(draw_hwc_line_, PIXEL_NAME)(SM501State * s, int crt, /* get pixel value */ if (i % 4 == 0) { - cpu_physical_memory_rw(cursor_addr, &bitset, 1, 0); + bitset = ldub_phys(cursor_addr); cursor_addr++; } v = bitset & 3; diff --git a/hw/smb380.c b/hw/smb380.c deleted file mode 100644 index 067f335..0000000 --- a/hw/smb380.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * SMB380 Sensor Emulation - * - * Contributed by Junsik.Park - */ - -#ifndef _WIN32 -#include -#include -#include -#else -#include -#include -#include -#endif - -#include "i2c-addressable.h" - -//#define DEBUG - -typedef struct SensorState { - I2CAddressableState i2c_addressable; - char data[7]; - - int16_t x; - int16_t y; - int16_t z; - int idx_out, req_out; -}SensorState; - -SensorState glob_accel_state; - -#define BITS_PER_BYTE 8 -#define SMB380_ACCEL_BITS 10 - -int sensor_update(uint16_t x, uint16_t y, uint16_t z) -{ - glob_accel_state.x = x; - glob_accel_state.y = y; - glob_accel_state.z = z; - - return 0; -} - -static int sensor_xyz_set(struct SensorState *s, uint16_t x, uint16_t y, uint16_t z) -{ - /* remains right 10bit */ - - x <<= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - x >>= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - - /* data[1] : 2 ~ 10 (bit) - * data[0] : 0 ~ 1 (bit) */ - - s->data[0] = (0x3 & x) << 6; - s->data[1] = x >> 2; - s->data[2] = (0x3 & y) << 6; - s->data[3] = y >> 2; - s->data[4] = (0x3 & z) << 6; - s->data[5] = z >> 2; - - return 0; -} - -static void smb380_reset(struct SensorState *s) -{ - s->idx_out = 0; - - glob_accel_state.x = 0; - glob_accel_state.y = -256; - glob_accel_state.z = 0; - - s->data[0] = 0; - s->data[1] = 0; - s->data[2] = 0; - s->data[3] = 0; - s->data[4] = 0; - s->data[5] = 0; - s->idx_out = 0; - - return ; -} - -static uint8_t smb380_read(void *opaque, uint32_t address, uint8_t offset) -{ - SensorState *s = (SensorState *)opaque; - int index = 0; - - index = s->idx_out; - -#ifdef DEBUG - printf("smb380_read IDX = %d, Data=%d\n", index, s->data[index]); -#endif - - s->idx_out ++; - - return s->data[index]; -} - -#ifdef DEBUG -static int print_hex(char *data, int len) -{ - return 0; -} -#endif - -static int parse_val(char *buff, unsigned char find_data, char *parsebuff) -{ - - int vvvi = 0; - while (1) { - if (vvvi > 40) { - return -1; - } - if (buff[vvvi] == find_data) { - - vvvi++; - strncpy(parsebuff, buff, vvvi); - return vvvi; - } - vvvi++; - } - - return 0; -} - -#define SENSOR_BUF 16 -#define SENSOR_VALUE_BUF 56 -static int get_from_ide(struct SensorState *accel_state) -{ - int client_socket; - struct sockaddr_in server_addr; - char buff[SENSOR_VALUE_BUF + 1]; - char buff2[SENSOR_VALUE_BUF + 1]; - char tmpbuf[SENSOR_VALUE_BUF + 1]; - int len = 0, len1 = 0; - int result = 0; - const char *command0 = "readSensor()\n"; - const char *command1 = "accelerometer\n"; - -#ifdef _WIN32 - WSADATA wsaData; - if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) - return -1; - - client_socket = socket(AF_INET, SOCK_STREAM, 0); -#else - client_socket = socket(PF_INET, SOCK_STREAM, 0); -#endif - if (client_socket == -1) { - return -1; - } - - memset(&server_addr, 0, sizeof( server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(8010); - server_addr.sin_addr.s_addr= inet_addr("127.0.0.1"); - if( -1 == connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))) { - close( client_socket); - return -1; - } - - if(read (client_socket, buff, SENSOR_BUF) < 0) { - close(client_socket); - return -1; - } - - if(1) { - if(write(client_socket, command0, strlen(command0)) < 0) { - close(client_socket); - return -1; - } - if(write(client_socket, command1, strlen(command1)) < 0) { - close(client_socket); - return -1; - } - - memset(buff, '\0', sizeof(buff)); - memset(buff2, '\0', sizeof(buff2)); - - result = read(client_socket, buff2, SENSOR_VALUE_BUF); - if (result <= (SENSOR_VALUE_BUF)/2) { - close( client_socket); - return -1; - } - memcpy(buff, buff2, result); - } - -#ifdef DEBUG - print_hex(buff2, 90); -#endif - - /* start */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len = parse_val(buff2, 0x33, tmpbuf); - - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len += parse_val(buff2+len, 0x0a, tmpbuf); - - /* first data */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len1 = parse_val(buff2+len, 0x0a, tmpbuf); - len += len1; -#ifdef DEBUG - print_hex(tmpbuf, len1); -#endif - //accel.read_accelx = atof(tmpbuf); - accel_state->x = (int)(atof(tmpbuf) * (-26.2)); // 26 ~= 256 / 9.8 - if (accel_state->x > 512) - accel_state->x = 512; - if (accel_state->x < -512) - accel_state->x = -512; - - /* second data */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len1 = parse_val(buff2+len, 0x0a, tmpbuf); - len += len1; -#ifdef DEBUG - print_hex(tmpbuf, len1); -#endif - accel_state->y = (int)(atof(tmpbuf) * 26.2); - if (accel_state->y > 512) - accel_state->y = 512; - if (accel_state->y < -512) - accel_state->y = -512; - - /* third data */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len1 = parse_val(buff2+len, 0x0a, tmpbuf); - len += len1; -#ifdef DEBUG - print_hex(tmpbuf, len1); -#endif - accel_state->z = (int)(atof(tmpbuf) * 26); - - if (accel_state->z > 512) - accel_state->z = 512; - if (accel_state->z < -512) - accel_state->z = -512; - -#ifdef DEBUG - printf("accel_state->x=%d %d %d\n", accel_state->x, accel_state->y, accel_state->z); -#endif - - close( client_socket); - - return 0; -} - -static void smb380_write(void *opaque, uint32_t address, uint8_t offset, uint8_t val) -{ - SensorState *s = (SensorState *)opaque; - -#ifdef DEBUG - printf("smb380_write\n"); -#endif - - get_from_ide (&glob_accel_state); - - sensor_xyz_set (s, glob_accel_state.x, glob_accel_state.y, glob_accel_state.z); - s->idx_out = 0; - - return; -} - -static int smb380_init(I2CAddressableState *s) -{ - SensorState *t = FROM_I2CADDR_SLAVE(SensorState, s); - - smb380_reset(s); - - return 0; -} - -#if 0 -#define DEFAULT_TIME 500000000 -/* get sensor info from IDE when performance problem occurs */ - -static void sensor_timer (void *opaque) -{ - SensorState *s = opaque; - int64_t expire_time = DEFAULT_TIME; - -#ifdef DEBUG - //printf("sensor timer\n"); -#endif - - /* 1 sec : 500000000 */ - - qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + expire_time); -} - - -/* set timer for getting sensor info */ - -SensorState* sensor_init() -{ - SensorState *s = &glob_accel_state; - - s->ts = qemu_new_timer (vm_clock, sensor_timer, s); - qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + DEFAULT_TIME); - - return s; - - //s->ts = qemu_new_timer (vm_clock, accel_timer, s); -} -#endif - - -static I2CAddressableDeviceInfo smb380_info = { - .i2c.qdev.name = "smb380", - .i2c.qdev.size = sizeof(SensorState), - .init = smb380_init, - .read = smb380_read, - .write = smb380_write, - .size = 1, - .rev = 0 -}; - -static void smb380_register_devices(void) -{ - i2c_addressable_register_device(&smb380_info); -} - - -device_init(smb380_register_devices) diff --git a/hw/smbios.c b/hw/smbios.c index a3ae1de..c9ba43e 100644 --- a/hw/smbios.c +++ b/hw/smbios.c @@ -21,19 +21,19 @@ struct smbios_header { uint16_t length; uint8_t type; -} __attribute__((__packed__)); +} QEMU_PACKED; struct smbios_field { struct smbios_header header; uint8_t type; uint16_t offset; uint8_t data[]; -} __attribute__((__packed__)); +} QEMU_PACKED; struct smbios_table { struct smbios_header header; uint8_t data[]; -} __attribute__((__packed__)); +} QEMU_PACKED; #define SMBIOS_FIELD_ENTRY 0 #define SMBIOS_TABLE_ENTRY 1 @@ -105,9 +105,9 @@ void smbios_add_field(int type, int offset, int len, void *data) if (!smbios_entries) { smbios_entries_len = sizeof(uint16_t); - smbios_entries = qemu_mallocz(smbios_entries_len); + smbios_entries = g_malloc0(smbios_entries_len); } - smbios_entries = qemu_realloc(smbios_entries, smbios_entries_len + + smbios_entries = g_realloc(smbios_entries, smbios_entries_len + sizeof(*field) + len); field = (struct smbios_field *)(smbios_entries + smbios_entries_len); field->header.type = SMBIOS_FIELD_ENTRY; @@ -192,10 +192,10 @@ int smbios_entry_add(const char *t) if (!smbios_entries) { smbios_entries_len = sizeof(uint16_t); - smbios_entries = qemu_mallocz(smbios_entries_len); + smbios_entries = g_malloc0(smbios_entries_len); } - smbios_entries = qemu_realloc(smbios_entries, smbios_entries_len + + smbios_entries = g_realloc(smbios_entries, smbios_entries_len + sizeof(*table) + size); table = (struct smbios_table *)(smbios_entries + smbios_entries_len); table->header.type = SMBIOS_TABLE_ENTRY; diff --git a/hw/smbios.h b/hw/smbios.h index 3a5169d..94e3641 100644 --- a/hw/smbios.h +++ b/hw/smbios.h @@ -26,7 +26,7 @@ struct smbios_structure_header { uint8_t type; uint8_t length; uint16_t handle; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 0 - BIOS Information */ struct smbios_type_0 { @@ -42,7 +42,7 @@ struct smbios_type_0 { uint8_t system_bios_minor_release; uint8_t embedded_controller_major_release; uint8_t embedded_controller_minor_release; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 1 - System Information */ struct smbios_type_1 { @@ -55,7 +55,7 @@ struct smbios_type_1 { uint8_t wake_up_type; uint8_t sku_number_str; uint8_t family_str; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 3 - System Enclosure (v2.3) */ struct smbios_type_3 { @@ -74,7 +74,7 @@ struct smbios_type_3 { uint8_t number_of_power_cords; uint8_t contained_element_count; // contained elements follow -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 4 - Processor Information (v2.0) */ struct smbios_type_4 { @@ -94,7 +94,7 @@ struct smbios_type_4 { uint16_t l1_cache_handle; uint16_t l2_cache_handle; uint16_t l3_cache_handle; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 16 - Physical Memory Array * Associated with one type 17 (Memory Device). @@ -107,7 +107,7 @@ struct smbios_type_16 { uint32_t maximum_capacity; uint16_t memory_error_information_handle; uint16_t number_of_memory_devices; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 17 - Memory Device * Associated with one type 19 */ @@ -124,7 +124,7 @@ struct smbios_type_17 { uint8_t bank_locator_str; uint8_t memory_type; uint16_t type_detail; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 19 - Memory Array Mapped Address */ struct smbios_type_19 { @@ -133,7 +133,7 @@ struct smbios_type_19 { uint32_t ending_address; uint16_t memory_array_handle; uint8_t partition_width; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 20 - Memory Device Mapped Address */ struct smbios_type_20 { @@ -145,18 +145,18 @@ struct smbios_type_20 { uint8_t partition_row_position; uint8_t interleave_position; uint8_t interleaved_data_depth; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 32 - System Boot Information */ struct smbios_type_32 { struct smbios_structure_header header; uint8_t reserved[6]; uint8_t boot_status; -} __attribute__((__packed__)); +} QEMU_PACKED; /* SMBIOS type 127 -- End-of-table */ struct smbios_type_127 { struct smbios_structure_header header; -} __attribute__((__packed__)); +} QEMU_PACKED; #endif /*QEMU_SMBIOS_H */ diff --git a/hw/smbus.c b/hw/smbus.c index e464539..ff027c8 100644 --- a/hw/smbus.c +++ b/hw/smbus.c @@ -4,7 +4,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. */ /* TODO: Implement PEC. */ diff --git a/hw/smbus.h b/hw/smbus.h index 571c52d..a398715 100644 --- a/hw/smbus.h +++ b/hw/smbus.h @@ -66,3 +66,6 @@ void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data); void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data, int len); + +void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom, + const uint8_t *eeprom_spd, int size); diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c index 52463e0..5d080ab 100644 --- a/hw/smbus_eeprom.c +++ b/hw/smbus_eeprom.c @@ -96,7 +96,7 @@ static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n) return eeprom_receive_byte(dev); } -static int smbus_eeprom_init(SMBusDevice *dev) +static int smbus_eeprom_initfn(SMBusDevice *dev) { SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev; @@ -111,7 +111,7 @@ static SMBusDeviceInfo smbus_eeprom_info = { DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data), DEFINE_PROP_END_OF_LIST(), }, - .init = smbus_eeprom_init, + .init = smbus_eeprom_initfn, .quick_cmd = eeprom_quick_cmd, .send_byte = eeprom_send_byte, .receive_byte = eeprom_receive_byte, @@ -125,3 +125,21 @@ static void smbus_eeprom_register_devices(void) } device_init(smbus_eeprom_register_devices) + +void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom, + const uint8_t *eeprom_spd, int eeprom_spd_size) +{ + int i; + uint8_t *eeprom_buf = g_malloc0(8 * 256); /* XXX: make this persistent */ + if (eeprom_spd_size > 0) { + memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size); + } + + for (i = 0; i < nb_eeprom; i++) { + DeviceState *eeprom; + eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); + qdev_prop_set_uint8(eeprom, "address", 0x50 + i); + qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256)); + qdev_init_nofail(eeprom); + } +} diff --git a/hw/smbus_smb380.c b/hw/smbus_smb380.c deleted file mode 100644 index b73b3f5..0000000 --- a/hw/smbus_smb380.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * SMB380 Sensor Emulation - * - * Contributed by Junsik.Park - */ - -#ifndef _WIN32 -#include -#include -#include -#else -#include -#include -#include -#endif - -#include "hw.h" -#include "i2c.h" -#include "smbus.h" - -//#define DEBUG - -typedef struct SMBusSENSORDevice { - SMBusDevice smbusedev; - uint8_t data[7]; - - int16_t x; - int16_t y; - int16_t z; - int idx_out, req_out; -}SMBusSENSORDevice; - -SMBusSENSORDevice glob_accel_state; - -static int sensor_xyz_set(struct SMBusSENSORDevice *s, uint16_t x, uint16_t y, uint16_t z); - -#define BITS_PER_BYTE 8 -#define SMB380_ACCEL_BITS 10 - -static void smb380_quick_cmd(SMBusDevice *dev, uint8_t read) -{ -#ifdef DEBUG - printf("sensor quick cmd : addr=0x%02x read%d\n", dev->i2c.address, read); -#endif -} - -static void smb380_send_byte(SMBusDevice *dev, uint8_t val) -{ -#ifdef DEBUG - SMBusSENSORDevice *s = (SMBusSENSORDevice *) dev; - printf("smb380_send_byte: addr=0x%02x val=0x%02x index=%d\n",dev->i2c.address, val, s->idx_out); -#endif - -} - -static uint8_t smb380_receive_byte(SMBusDevice *dev, uint8_t address) -{ - SMBusSENSORDevice *s = (SMBusSENSORDevice *) dev; - int index = (int) address; - if (index != 0) - return s->data[index-2]; - else - return sensor_xyz_set(s, glob_accel_state.x, glob_accel_state.y, glob_accel_state.z); -} - -void sensor_update(uint16_t x, uint16_t y, uint16_t z) -{ - glob_accel_state.x = x; - glob_accel_state.y = y; - glob_accel_state.z = z; -} - -static int sensor_xyz_set(struct SMBusSENSORDevice *s, uint16_t x, uint16_t y, uint16_t z) -{ - /* remains right 10bit */ - - x <<= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - x >>= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - - y <<= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - y >>= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - - z <<= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - z >>= (sizeof(uint16_t) * BITS_PER_BYTE - SMB380_ACCEL_BITS); - - /* data[1] : 2 ~ 10 (bit) - * data[0] : 0 ~ 1 (bit) */ - - s->data[0] = (0x3 & x) << 6; - s->data[1] = x >> 2; - s->data[2] = (0x3 & y) << 6; - s->data[3] = y >> 2; - s->data[4] = (0x3 & z) << 6; - s->data[5] = z >> 2; - - return 0; -} - -static void smb380_reset(struct SMBusSENSORDevice *s) -{ - s->idx_out = 0; - - glob_accel_state.x = 0; - glob_accel_state.y = -256; - glob_accel_state.z = 0; - - s->data[0] = 0; - s->data[1] = 0; - s->data[2] = 0; - s->data[3] = 0; - s->data[4] = 0; - s->data[5] = 0; - s->idx_out = 0; - - return ; -} - -static uint8_t smb380_read_data(SMBusDevice *opaque, uint8_t address, uint8_t offset) -{ - return smb380_receive_byte(opaque, address); -} - -#ifdef DEBUG -static int print_hex(char *data, int len) -{ - return 0; -} -#endif - -static int parse_val(char *buff, unsigned char find_data, char *parsebuff) -{ - int vvvi = 0; - while (1) { - if (vvvi > 40) { - return -1; - } - if (buff[vvvi] == find_data) { - - vvvi++; - strncpy(parsebuff, buff, vvvi); - return vvvi; - } - vvvi++; - } - - return 0; -} - -#define SENSOR_BUF 16 -#define SENSOR_VALUE_BUF 56 -static int get_from_ide(struct SMBusSENSORDevice *accel_state) -{ - int client_socket; - struct sockaddr_in server_addr; - char buff[SENSOR_VALUE_BUF + 1]; - char buff2[SENSOR_VALUE_BUF + 1]; - char tmpbuf[SENSOR_VALUE_BUF + 1]; - int len = 0, len1 = 0; - int result = 0; - const char *command0 = "readSensor()\n"; - const char *command1 = "accelerometer\n"; - -#ifdef _WIN32 - WSADATA wsaData; - if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) - return -1; - - client_socket = socket(AF_INET, SOCK_STREAM, 0); -#else - client_socket = socket(PF_INET, SOCK_STREAM, 0); -#endif - if (client_socket == -1) { - return -1; - } - - memset(&server_addr, 0, sizeof( server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(8010); - server_addr.sin_addr.s_addr= inet_addr("127.0.0.1"); - if( -1 == connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))) { - close( client_socket); - return -1; - } - - if(read (client_socket, buff, SENSOR_BUF) < 0) { - close(client_socket); - return -1; - } - - if(1) { - if(write(client_socket, command0, strlen(command0)) < 0) { - close(client_socket); - return -1; - } - if(write(client_socket, command1, strlen(command1)) < 0) { - close(client_socket); - return -1; - } - - memset(buff, '\0', sizeof(buff)); - memset(buff2, '\0', sizeof(buff2)); - - result = read(client_socket, buff2, SENSOR_VALUE_BUF); - if (result <= (SENSOR_VALUE_BUF)/2) { - close( client_socket); - return -1; - } - memcpy(buff, buff2, result); - } - -#ifdef DEBUG - print_hex(buff2, 90); -#endif - - /* start */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len = parse_val(buff2, 0x33, tmpbuf); - - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len += parse_val(buff2+len, 0x0a, tmpbuf); - - /* first data */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len1 = parse_val(buff2+len, 0x0a, tmpbuf); - len += len1; -#ifdef DEBUG - print_hex(tmpbuf, len1); -#endif - //accel.read_accelx = atof(tmpbuf); - accel_state->x = (int)(atof(tmpbuf) * (-26.2)); // 26 ~= 256 / 9.8 - if (accel_state->x > 512) - accel_state->x = 512; - if (accel_state->x < -512) - accel_state->x = -512; - - /* second data */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len1 = parse_val(buff2+len, 0x0a, tmpbuf); - len += len1; -#ifdef DEBUG - print_hex(tmpbuf, len1); -#endif - accel_state->y = (int)(atof(tmpbuf) * 26.2); - if (accel_state->y > 512) - accel_state->y = 512; - if (accel_state->y < -512) - accel_state->y = -512; - - /* third data */ - memset(tmpbuf, '\0', sizeof(tmpbuf)); - len1 = parse_val(buff2+len, 0x0a, tmpbuf); - len += len1; -#ifdef DEBUG - print_hex(tmpbuf, len1); -#endif - accel_state->z = (int)(atof(tmpbuf) * 26); - - if (accel_state->z > 512) - accel_state->z = 512; - if (accel_state->z < -512) - accel_state->z = -512; - -#ifdef DEBUG - printf("accel_state->x=%d %d %d\n", accel_state->x, accel_state->y, accel_state->z); -#endif - - close( client_socket); - - return 0; -} - -static void smb380_write_data(SMBusDevice *dev, uint8_t address, uint8_t offset, uint8_t val) -{ - SMBusSENSORDevice *s = (SMBusSENSORDevice *)dev; - -#ifdef DEBUG - printf("smb380_write\n"); -#endif - get_from_ide (&glob_accel_state); - - sensor_xyz_set (s, glob_accel_state.x, glob_accel_state.y, glob_accel_state.z); - - -#ifdef DEBUG - printf("smb380_send_byte: addr=0x%02x val=0x%02x\n",address, val); -#endif - smb380_send_byte(dev,val); - -} - -static int smb380_init(SMBusDevice *s) -{ - SMBusSENSORDevice *t = (SMBusSENSORDevice *)s; - - smb380_reset(t); - return 0; -} - -#if 0 -#define DEFAULT_TIME 500000000 -/* get sensor info from IDE when performance problem occurs */ - -static void sensor_timer (void *opaque) -{ - SensorState *s = opaque; - int64_t expire_time = DEFAULT_TIME; - -#ifdef DEBUG - //printf("sensor timer\n"); -#endif - - /* 1 sec : 500000000 */ - - qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + expire_time); -} - - -/* set timer for getting sensor info */ - -SensorState* sensor_init() -{ - SensorState *s = &glob_accel_state; - - s->ts = qemu_new_timer (vm_clock, sensor_timer, s); - qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + DEFAULT_TIME); - - return s; - - //s->ts = qemu_new_timer (vm_clock, accel_timer, s); -} -#endif - - -static SMBusDeviceInfo smb380_info = { - .i2c.qdev.name = "smb380", - .i2c.qdev.size = sizeof(SMBusSENSORDevice), - .init = smb380_init, - .quick_cmd = smb380_quick_cmd, - .send_byte = smb380_send_byte, - .receive_byte = smb380_receive_byte, - .read_data = smb380_read_data, - .write_data = smb380_write_data -}; - -static void smb380_register_devices(void) -{ - smbus_register_device(&smb380_info); -} - -device_init(smb380_register_devices) diff --git a/hw/smc91c111.c b/hw/smc91c111.c index dafea5c..fc8c498 100644 --- a/hw/smc91c111.c +++ b/hw/smc91c111.c @@ -4,7 +4,7 @@ * Copyright (c) 2005 CodeSourcery, LLC. * Written by Paul Brook * - * This code is licenced under the GPL + * This code is licensed under the GPL */ #include "sysbus.h" @@ -43,7 +43,7 @@ typedef struct { uint8_t data[NUM_PACKETS][2048]; uint8_t int_level; uint8_t int_mask; - int mmio_index; + MemoryRegion mmio; } smc91c111_state; static const VMStateDescription vmstate_smc91c111 = { @@ -252,8 +252,9 @@ static void smc91c111_queue_tx(smc91c111_state *s, int packet) smc91c111_do_tx(s); } -static void smc91c111_reset(smc91c111_state *s) +static void smc91c111_reset(DeviceState *dev) { + smc91c111_state *s = FROM_SYSBUS(smc91c111_state, sysbus_from_qdev(dev)); s->bank = 0; s->tx_fifo_len = 0; s->tx_fifo_done_len = 0; @@ -302,7 +303,7 @@ static void smc91c111_writeb(void *opaque, target_phys_addr_t offset, case 5: SET_HIGH(rcr, value); if (s->rcr & RCR_SOFT_RST) - smc91c111_reset(s); + smc91c111_reset(&s->busdev.qdev); return; case 10: case 11: /* RPCR */ /* Ignored */ @@ -716,16 +717,15 @@ static ssize_t smc91c111_receive(VLANClientState *nc, const uint8_t *buf, size_t return size; } -static CPUReadMemoryFunc * const smc91c111_readfn[] = { - smc91c111_readb, - smc91c111_readw, - smc91c111_readl -}; - -static CPUWriteMemoryFunc * const smc91c111_writefn[] = { - smc91c111_writeb, - smc91c111_writew, - smc91c111_writel +static const MemoryRegionOps smc91c111_mem_ops = { + /* The special case for 32 bit writes to 0xc means we can't just + * set .impl.min/max_access_size to 1, unfortunately + */ + .old_mmio = { + .read = { smc91c111_readb, smc91c111_readw, smc91c111_readl, }, + .write = { smc91c111_writeb, smc91c111_writew, smc91c111_writel, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void smc91c111_cleanup(VLANClientState *nc) @@ -746,16 +746,11 @@ static NetClientInfo net_smc91c111_info = { static int smc91c111_init1(SysBusDevice *dev) { smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev); - - s->mmio_index = cpu_register_io_memory(smc91c111_readfn, - smc91c111_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 16, s->mmio_index); + memory_region_init_io(&s->mmio, &smc91c111_mem_ops, s, + "smc91c111-mmio", 16); + sysbus_init_mmio_region(dev, &s->mmio); sysbus_init_irq(dev, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); - - smc91c111_reset(s); - s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf, dev->qdev.info->name, dev->qdev.id, s); qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); @@ -768,6 +763,7 @@ static SysBusDeviceInfo smc91c111_info = { .qdev.name = "smc91c111", .qdev.size = sizeof(smc91c111_state), .qdev.vmsd = &vmstate_smc91c111, + .qdev.reset = smc91c111_reset, .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(smc91c111_state, conf), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/soc_dma.c b/hw/soc_dma.c index 23ec516..03bc846 100644 --- a/hw/soc_dma.c +++ b/hw/soc_dma.c @@ -48,7 +48,7 @@ static int fifo_size; static void transfer_fifo2fifo(struct soc_dma_ch_s *ch) { if (ch->bytes > fifo_size) - fifo_buf = qemu_realloc(fifo_buf, fifo_size = ch->bytes); + fifo_buf = g_realloc(fifo_buf, fifo_size = ch->bytes); /* Implement as transfer_fifo2linear + transfer_linear2fifo. */ ch->io_fn[0](ch->io_opaque[0], fifo_buf, ch->bytes); @@ -84,7 +84,7 @@ struct dma_s { static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes) { - int64_t now = qemu_get_clock(vm_clock); + int64_t now = qemu_get_clock_ns(vm_clock); struct dma_s *dma = (struct dma_s *) ch->dma; qemu_mod_timer(ch->timer, now + delay_bytes / dma->channel_freq); @@ -239,14 +239,14 @@ void soc_dma_reset(struct soc_dma_s *soc) struct soc_dma_s *soc_dma_init(int n) { int i; - struct dma_s *s = qemu_mallocz(sizeof(*s) + n * sizeof(*s->ch)); + struct dma_s *s = g_malloc0(sizeof(*s) + n * sizeof(*s->ch)); s->chnum = n; s->soc.ch = s->ch; for (i = 0; i < n; i ++) { s->ch[i].dma = &s->soc; s->ch[i].num = i; - s->ch[i].timer = qemu_new_timer(vm_clock, soc_dma_ch_run, &s->ch[i]); + s->ch[i].timer = qemu_new_timer_ns(vm_clock, soc_dma_ch_run, &s->ch[i]); } soc_dma_reset(&s->soc); @@ -261,7 +261,7 @@ void soc_dma_port_add_fifo(struct soc_dma_s *soc, target_phys_addr_t virt_base, struct memmap_entry_s *entry; struct dma_s *dma = (struct dma_s *) soc; - dma->memmap = qemu_realloc(dma->memmap, sizeof(*entry) * + dma->memmap = g_realloc(dma->memmap, sizeof(*entry) * (dma->memmap_size + 1)); entry = soc_dma_lookup(dma, virt_base); @@ -313,7 +313,7 @@ void soc_dma_port_add_mem(struct soc_dma_s *soc, uint8_t *phys_base, struct memmap_entry_s *entry; struct dma_s *dma = (struct dma_s *) soc; - dma->memmap = qemu_realloc(dma->memmap, sizeof(*entry) * + dma->memmap = g_realloc(dma->memmap, sizeof(*entry) * (dma->memmap_size + 1)); entry = soc_dma_lookup(dma, virt_base); diff --git a/hw/soc_dma.h b/hw/soc_dma.h index c0ebb8d..904b26c 100644 --- a/hw/soc_dma.h +++ b/hw/soc_dma.h @@ -18,6 +18,8 @@ * with this program; if not, see . */ +#include "memory.h" + struct soc_dma_s; struct soc_dma_ch_s; typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len); @@ -105,9 +107,3 @@ static inline void soc_dma_port_add_fifo_out(struct soc_dma_s *dma, { return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 1); } - -static inline void soc_dma_port_add_mem_ram(struct soc_dma_s *dma, - ram_addr_t offset, target_phys_addr_t virt_base, size_t size) -{ - return soc_dma_port_add_mem(dma, qemu_get_ram_ptr(offset), virt_base, size); -} diff --git a/hw/spitz.c b/hw/spitz.c index 5b1e42d..23f9d41 100644 --- a/hw/spitz.c +++ b/hw/spitz.c @@ -24,6 +24,7 @@ #include "boards.h" #include "blockdev.h" #include "sysbus.h" +#include "exec-memory.h" #undef REG_FMT #define REG_FMT "0x%02lx" @@ -48,14 +49,15 @@ typedef struct { SysBusDevice busdev; - NANDFlashState *nand; + MemoryRegion iomem; + DeviceState *nand; uint8_t ctl; uint8_t manf_id; uint8_t chip_id; ECCState ecc; } SLNANDState; -static uint32_t sl_readb(void *opaque, target_phys_addr_t addr) +static uint64_t sl_read(void *opaque, target_phys_addr_t addr, unsigned size) { SLNANDState *s = (SLNANDState *) opaque; int ryby; @@ -85,6 +87,10 @@ static uint32_t sl_readb(void *opaque, target_phys_addr_t addr) return s->ctl; case FLASH_FLASHIO: + if (size == 4) { + return ecc_digest(&s->ecc, nand_getio(s->nand)) | + (ecc_digest(&s->ecc, nand_getio(s->nand)) << 16); + } return ecc_digest(&s->ecc, nand_getio(s->nand)); default: @@ -93,19 +99,8 @@ static uint32_t sl_readb(void *opaque, target_phys_addr_t addr) return 0; } -static uint32_t sl_readl(void *opaque, target_phys_addr_t addr) -{ - SLNANDState *s = (SLNANDState *) opaque; - - if (addr == FLASH_FLASHIO) - return ecc_digest(&s->ecc, nand_getio(s->nand)) | - (ecc_digest(&s->ecc, nand_getio(s->nand)) << 16); - - return sl_readb(opaque, addr); -} - -static void sl_writeb(void *opaque, target_phys_addr_t addr, - uint32_t value) +static void sl_write(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { SLNANDState *s = (SLNANDState *) opaque; @@ -139,15 +134,10 @@ enum { FLASH_1024M, }; -static CPUReadMemoryFunc * const sl_readfn[] = { - sl_readb, - sl_readb, - sl_readl, -}; -static CPUWriteMemoryFunc * const sl_writefn[] = { - sl_writeb, - sl_writeb, - sl_writeb, +static const MemoryRegionOps sl_ops = { + .read = sl_read, + .write = sl_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void sl_flash_register(PXA2xxState *cpu, int size) @@ -167,18 +157,17 @@ static void sl_flash_register(PXA2xxState *cpu, int size) } static int sl_nand_init(SysBusDevice *dev) { - int iomemtype; SLNANDState *s; + DriveInfo *nand; s = FROM_SYSBUS(SLNANDState, dev); s->ctl = 0; - s->nand = nand_init(s->manf_id, s->chip_id); - - iomemtype = cpu_register_io_memory(sl_readfn, - sl_writefn, s, DEVICE_NATIVE_ENDIAN); + nand = drive_get(IF_MTD, 0, 0); + s->nand = nand_init(nand ? nand->bdrv : NULL, s->manf_id, s->chip_id); - sysbus_init_mmio(dev, 0x40, iomemtype); + memory_region_init_io(&s->iomem, &sl_ops, s, "sl", 0x40); + sysbus_init_mmio_region(dev, &s->iomem); return 0; } @@ -393,7 +382,7 @@ static void spitz_keyboard_tick(void *opaque) s->fifopos = 0; } - qemu_mod_timer(s->kbdtimer, qemu_get_clock(vm_clock) + + qemu_mod_timer(s->kbdtimer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 32); } @@ -485,7 +474,7 @@ static void spitz_keyboard_register(PXA2xxState *cpu) qdev_connect_gpio_out(cpu->gpio, spitz_gpio_key_strobe[i], qdev_get_gpio_in(dev, i)); - qemu_mod_timer(s->kbdtimer, qemu_get_clock(vm_clock)); + qemu_mod_timer(s->kbdtimer, qemu_get_clock_ns(vm_clock)); qemu_add_kbd_event_handler(spitz_keyboard_handler, s); } @@ -506,7 +495,7 @@ static int spitz_keyboard_init(SysBusDevice *dev) spitz_keyboard_pre_map(s); - s->kbdtimer = qemu_new_timer(vm_clock, spitz_keyboard_tick, s); + s->kbdtimer = qemu_new_timer_ns(vm_clock, spitz_keyboard_tick, s); qdev_init_gpio_in(&dev->qdev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM); qdev_init_gpio_out(&dev->qdev, s->sense, SPITZ_KEY_SENSE_NUM); @@ -706,17 +695,13 @@ static void spitz_ssp_attach(PXA2xxState *cpu) static void spitz_microdrive_attach(PXA2xxState *cpu, int slot) { PCMCIACardState *md; - BlockDriverState *bs; DriveInfo *dinfo; dinfo = drive_get(IF_IDE, 0, 0); - if (!dinfo) + if (!dinfo || dinfo->media_cd) return; - bs = dinfo->bdrv; - if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) { - md = dscm1xxxx_init(dinfo); - pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md); - } + md = dscm1xxxx_init(dinfo); + pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md); } /* Wm8750 and Max7310 on I2C */ @@ -898,17 +883,20 @@ static void spitz_common_init(ram_addr_t ram_size, { PXA2xxState *cpu; DeviceState *scp0, *scp1 = NULL; + MemoryRegion *address_space_mem = get_system_memory(); + MemoryRegion *rom = g_new(MemoryRegion, 1); if (!cpu_model) cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0"; /* Setup CPU & memory */ - cpu = pxa270_init(spitz_binfo.ram_size, cpu_model); + cpu = pxa270_init(address_space_mem, spitz_binfo.ram_size, cpu_model); sl_flash_register(cpu, (model == spitz) ? FLASH_128M : FLASH_1024M); - cpu_register_physical_memory(0, SPITZ_ROM, - qemu_ram_alloc(NULL, "spitz.rom", SPITZ_ROM) | IO_MEM_ROM); + memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM); + memory_region_set_readonly(rom, true); + memory_region_add_subregion(address_space_mem, 0, rom); /* Setup peripherals */ spitz_keyboard_register(cpu); diff --git a/hw/ssd0303.c b/hw/ssd0303.c index 108c068..401fdf5 100644 --- a/hw/ssd0303.c +++ b/hw/ssd0303.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ /* The controller can support a variety of different displays, but we only @@ -93,7 +93,7 @@ static int ssd0303_send(i2c_slave *i2c, uint8_t data) DPRINTF("cmd 0x%02x\n", data); s->mode = SSD0303_IDLE; switch (data) { - case 0x00 ... 0x0f: /* Set lower colum address. */ + case 0x00 ... 0x0f: /* Set lower column address. */ s->col = (s->col & 0xf0) | (data & 0xf); break; case 0x10 ... 0x20: /* Set higher column address. */ diff --git a/hw/ssd0323.c b/hw/ssd0323.c index 8643961..1eb3823 100644 --- a/hw/ssd0323.c +++ b/hw/ssd0323.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ /* The controller can support a variety of different displays, but we only diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c index fb4b649..18dabd6 100644 --- a/hw/ssi-sd.c +++ b/hw/ssi-sd.c @@ -4,7 +4,7 @@ * Copyright (c) 2007-2009 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #include "blockdev.h" diff --git a/hw/ssi.c b/hw/ssi.c index cfe7c07..9842fe7 100644 --- a/hw/ssi.c +++ b/hw/ssi.c @@ -4,7 +4,7 @@ * Copyright (c) 2009 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #include "ssi.h" @@ -25,8 +25,8 @@ static int ssi_slave_init(DeviceState *dev, DeviceInfo *base_info) SSIBus *bus; bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); - if (QLIST_FIRST(&bus->qbus.children) != dev - || QLIST_NEXT(dev, sibling) != NULL) { + if (QTAILQ_FIRST(&bus->qbus.children) != dev + || QTAILQ_NEXT(dev, sibling) != NULL) { hw_error("Too many devices on SSI bus"); } @@ -61,7 +61,7 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val) { DeviceState *dev; SSISlave *slave; - dev = QLIST_FIRST(&bus->qbus.children); + dev = QTAILQ_FIRST(&bus->qbus.children); if (!dev) { return 0; } diff --git a/hw/stellaris.c b/hw/stellaris.c index b903273..2bf1c23 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -14,8 +14,8 @@ #include "qemu-timer.h" #include "i2c.h" #include "net.h" -#include "sysemu.h" #include "boards.h" +#include "exec-memory.h" #define GPIO_A 0 #define GPIO_B 1 @@ -79,7 +79,7 @@ static void gptm_reload(gptm_state *s, int n, int reset) { int64_t tick; if (reset) - tick = qemu_get_clock(vm_clock); + tick = qemu_get_clock_ns(vm_clock); else tick = s->tick[n]; @@ -280,64 +280,28 @@ static CPUWriteMemoryFunc * const gptm_writefn[] = { gptm_write }; -static void gptm_save(QEMUFile *f, void *opaque) -{ - gptm_state *s = (gptm_state *)opaque; - - qemu_put_be32(f, s->config); - qemu_put_be32(f, s->mode[0]); - qemu_put_be32(f, s->mode[1]); - qemu_put_be32(f, s->control); - qemu_put_be32(f, s->state); - qemu_put_be32(f, s->mask); - qemu_put_be32(f, s->mode[0]); - qemu_put_be32(f, s->mode[0]); - qemu_put_be32(f, s->load[0]); - qemu_put_be32(f, s->load[1]); - qemu_put_be32(f, s->match[0]); - qemu_put_be32(f, s->match[1]); - qemu_put_be32(f, s->prescale[0]); - qemu_put_be32(f, s->prescale[1]); - qemu_put_be32(f, s->match_prescale[0]); - qemu_put_be32(f, s->match_prescale[1]); - qemu_put_be32(f, s->rtc); - qemu_put_be64(f, s->tick[0]); - qemu_put_be64(f, s->tick[1]); - qemu_put_timer(f, s->timer[0]); - qemu_put_timer(f, s->timer[1]); -} - -static int gptm_load(QEMUFile *f, void *opaque, int version_id) -{ - gptm_state *s = (gptm_state *)opaque; - - if (version_id != 1) - return -EINVAL; - - s->config = qemu_get_be32(f); - s->mode[0] = qemu_get_be32(f); - s->mode[1] = qemu_get_be32(f); - s->control = qemu_get_be32(f); - s->state = qemu_get_be32(f); - s->mask = qemu_get_be32(f); - s->mode[0] = qemu_get_be32(f); - s->mode[0] = qemu_get_be32(f); - s->load[0] = qemu_get_be32(f); - s->load[1] = qemu_get_be32(f); - s->match[0] = qemu_get_be32(f); - s->match[1] = qemu_get_be32(f); - s->prescale[0] = qemu_get_be32(f); - s->prescale[1] = qemu_get_be32(f); - s->match_prescale[0] = qemu_get_be32(f); - s->match_prescale[1] = qemu_get_be32(f); - s->rtc = qemu_get_be32(f); - s->tick[0] = qemu_get_be64(f); - s->tick[1] = qemu_get_be64(f); - qemu_get_timer(f, s->timer[0]); - qemu_get_timer(f, s->timer[1]); - - return 0; -} +static const VMStateDescription vmstate_stellaris_gptm = { + .name = "stellaris_gptm", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(config, gptm_state), + VMSTATE_UINT32_ARRAY(mode, gptm_state, 2), + VMSTATE_UINT32(control, gptm_state), + VMSTATE_UINT32(state, gptm_state), + VMSTATE_UINT32(mask, gptm_state), + VMSTATE_UNUSED(8), + VMSTATE_UINT32_ARRAY(load, gptm_state, 2), + VMSTATE_UINT32_ARRAY(match, gptm_state, 2), + VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2), + VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2), + VMSTATE_UINT32(rtc, gptm_state), + VMSTATE_INT64_ARRAY(tick, gptm_state, 2), + VMSTATE_TIMER_ARRAY(timer, gptm_state, 2), + VMSTATE_END_OF_LIST() + } +}; static int stellaris_gptm_init(SysBusDevice *dev) { @@ -353,10 +317,9 @@ static int stellaris_gptm_init(SysBusDevice *dev) sysbus_init_mmio(dev, 0x1000, iomemtype); s->opaque[0] = s->opaque[1] = s; - s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); - s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); - register_savevm(&dev->qdev, "stellaris_gptm", -1, 1, - gptm_save, gptm_load, s); + s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]); + s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]); + vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s); return 0; } @@ -370,6 +333,7 @@ typedef struct { uint32_t int_mask; uint32_t resc; uint32_t rcc; + uint32_t rcc2; uint32_t rcgc[3]; uint32_t scgc[3]; uint32_t dcgc[3]; @@ -424,6 +388,32 @@ static uint32_t pllcfg_fury[16] = { 0xb11c /* 8.192 Mhz */ }; +#define DID0_VER_MASK 0x70000000 +#define DID0_VER_0 0x00000000 +#define DID0_VER_1 0x10000000 + +#define DID0_CLASS_MASK 0x00FF0000 +#define DID0_CLASS_SANDSTORM 0x00000000 +#define DID0_CLASS_FURY 0x00010000 + +static int ssys_board_class(const ssys_state *s) +{ + uint32_t did0 = s->board->did0; + switch (did0 & DID0_VER_MASK) { + case DID0_VER_0: + return DID0_CLASS_SANDSTORM; + case DID0_VER_1: + switch (did0 & DID0_CLASS_MASK) { + case DID0_CLASS_SANDSTORM: + case DID0_CLASS_FURY: + return did0 & DID0_CLASS_MASK; + } + /* for unknown classes, fall through */ + default: + hw_error("ssys_board_class: Unknown class 0x%08x\n", did0); + } +} + static uint32_t ssys_read(void *opaque, target_phys_addr_t offset) { ssys_state *s = (ssys_state *)opaque; @@ -467,12 +457,18 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset) { int xtal; xtal = (s->rcc >> 6) & 0xf; - if (s->board->did0 & (1 << 16)) { + switch (ssys_board_class(s)) { + case DID0_CLASS_FURY: return pllcfg_fury[xtal]; - } else { + case DID0_CLASS_SANDSTORM: return pllcfg_sandstorm[xtal]; + default: + hw_error("ssys_read: Unhandled class for PLLCFG read.\n"); + return 0; } } + case 0x070: /* RCC2 */ + return s->rcc2; case 0x100: /* RCGC0 */ return s->rcgc[0]; case 0x104: /* RCGC1 */ @@ -505,9 +501,21 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset) } } +static bool ssys_use_rcc2(ssys_state *s) +{ + return (s->rcc2 >> 31) & 0x1; +} + +/* + * Caculate the sys. clock period in ms. + */ static void ssys_calculate_system_clock(ssys_state *s) { - system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1); + if (ssys_use_rcc2(s)) { + system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1); + } else { + system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1); + } } static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value) @@ -543,6 +551,18 @@ static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value) s->rcc = value; ssys_calculate_system_clock(s); break; + case 0x070: /* RCC2 */ + if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) { + break; + } + + if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) { + /* PLL enable. */ + s->int_status |= (1 << 6); + } + s->rcc2 = value; + ssys_calculate_system_clock(s); + break; case 0x100: /* RCGC0 */ s->rcgc[0] = value; break; @@ -600,63 +620,49 @@ static void ssys_reset(void *opaque) s->pborctl = 0x7ffd; s->rcc = 0x078e3ac0; + + if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) { + s->rcc2 = 0; + } else { + s->rcc2 = 0x07802810; + } s->rcgc[0] = 1; s->scgc[0] = 1; s->dcgc[0] = 1; } -static void ssys_save(QEMUFile *f, void *opaque) -{ - ssys_state *s = (ssys_state *)opaque; - - qemu_put_be32(f, s->pborctl); - qemu_put_be32(f, s->ldopctl); - qemu_put_be32(f, s->int_mask); - qemu_put_be32(f, s->int_status); - qemu_put_be32(f, s->resc); - qemu_put_be32(f, s->rcc); - qemu_put_be32(f, s->rcgc[0]); - qemu_put_be32(f, s->rcgc[1]); - qemu_put_be32(f, s->rcgc[2]); - qemu_put_be32(f, s->scgc[0]); - qemu_put_be32(f, s->scgc[1]); - qemu_put_be32(f, s->scgc[2]); - qemu_put_be32(f, s->dcgc[0]); - qemu_put_be32(f, s->dcgc[1]); - qemu_put_be32(f, s->dcgc[2]); - qemu_put_be32(f, s->clkvclr); - qemu_put_be32(f, s->ldoarst); -} - -static int ssys_load(QEMUFile *f, void *opaque, int version_id) +static int stellaris_sys_post_load(void *opaque, int version_id) { - ssys_state *s = (ssys_state *)opaque; + ssys_state *s = opaque; - if (version_id != 1) - return -EINVAL; - - s->pborctl = qemu_get_be32(f); - s->ldopctl = qemu_get_be32(f); - s->int_mask = qemu_get_be32(f); - s->int_status = qemu_get_be32(f); - s->resc = qemu_get_be32(f); - s->rcc = qemu_get_be32(f); - s->rcgc[0] = qemu_get_be32(f); - s->rcgc[1] = qemu_get_be32(f); - s->rcgc[2] = qemu_get_be32(f); - s->scgc[0] = qemu_get_be32(f); - s->scgc[1] = qemu_get_be32(f); - s->scgc[2] = qemu_get_be32(f); - s->dcgc[0] = qemu_get_be32(f); - s->dcgc[1] = qemu_get_be32(f); - s->dcgc[2] = qemu_get_be32(f); - s->clkvclr = qemu_get_be32(f); - s->ldoarst = qemu_get_be32(f); ssys_calculate_system_clock(s); return 0; } +static const VMStateDescription vmstate_stellaris_sys = { + .name = "stellaris_sys", + .version_id = 2, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = stellaris_sys_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32(pborctl, ssys_state), + VMSTATE_UINT32(ldopctl, ssys_state), + VMSTATE_UINT32(int_mask, ssys_state), + VMSTATE_UINT32(int_status, ssys_state), + VMSTATE_UINT32(resc, ssys_state), + VMSTATE_UINT32(rcc, ssys_state), + VMSTATE_UINT32_V(rcc2, ssys_state, 2), + VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3), + VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3), + VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3), + VMSTATE_UINT32(clkvclr, ssys_state), + VMSTATE_UINT32(ldoarst, ssys_state), + VMSTATE_END_OF_LIST() + } +}; + static int stellaris_sys_init(uint32_t base, qemu_irq irq, stellaris_board_info * board, uint8_t *macaddr) @@ -664,7 +670,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq, int iomemtype; ssys_state *s; - s = (ssys_state *)qemu_mallocz(sizeof(ssys_state)); + s = (ssys_state *)g_malloc0(sizeof(ssys_state)); s->irq = irq; s->board = board; /* Most devices come preprogrammed with a MAC address in the user data. */ @@ -676,7 +682,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq, DEVICE_NATIVE_ENDIAN); cpu_register_physical_memory(base, 0x00001000, iomemtype); ssys_reset(s); - register_savevm(NULL, "stellaris_sys", -1, 1, ssys_save, ssys_load, s); + vmstate_register(NULL, -1, &vmstate_stellaris_sys, s); return 0; } @@ -844,36 +850,22 @@ static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = { stellaris_i2c_write }; -static void stellaris_i2c_save(QEMUFile *f, void *opaque) -{ - stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; - - qemu_put_be32(f, s->msa); - qemu_put_be32(f, s->mcs); - qemu_put_be32(f, s->mdr); - qemu_put_be32(f, s->mtpr); - qemu_put_be32(f, s->mimr); - qemu_put_be32(f, s->mris); - qemu_put_be32(f, s->mcr); -} - -static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id) -{ - stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; - - if (version_id != 1) - return -EINVAL; - - s->msa = qemu_get_be32(f); - s->mcs = qemu_get_be32(f); - s->mdr = qemu_get_be32(f); - s->mtpr = qemu_get_be32(f); - s->mimr = qemu_get_be32(f); - s->mris = qemu_get_be32(f); - s->mcr = qemu_get_be32(f); - - return 0; -} +static const VMStateDescription vmstate_stellaris_i2c = { + .name = "stellaris_i2c", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(msa, stellaris_i2c_state), + VMSTATE_UINT32(mcs, stellaris_i2c_state), + VMSTATE_UINT32(mdr, stellaris_i2c_state), + VMSTATE_UINT32(mtpr, stellaris_i2c_state), + VMSTATE_UINT32(mimr, stellaris_i2c_state), + VMSTATE_UINT32(mris, stellaris_i2c_state), + VMSTATE_UINT32(mcr, stellaris_i2c_state), + VMSTATE_END_OF_LIST() + } +}; static int stellaris_i2c_init(SysBusDevice * dev) { @@ -891,8 +883,7 @@ static int stellaris_i2c_init(SysBusDevice * dev) sysbus_init_mmio(dev, 0x1000, iomemtype); /* ??? For now we only implement the master interface. */ stellaris_i2c_reset(s); - register_savevm(&dev->qdev, "stellaris_i2c", -1, 1, - stellaris_i2c_save, stellaris_i2c_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s); return 0; } @@ -1130,60 +1121,40 @@ static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = { stellaris_adc_write }; -static void stellaris_adc_save(QEMUFile *f, void *opaque) -{ - stellaris_adc_state *s = (stellaris_adc_state *)opaque; - int i; - int j; - - qemu_put_be32(f, s->actss); - qemu_put_be32(f, s->ris); - qemu_put_be32(f, s->im); - qemu_put_be32(f, s->emux); - qemu_put_be32(f, s->ostat); - qemu_put_be32(f, s->ustat); - qemu_put_be32(f, s->sspri); - qemu_put_be32(f, s->sac); - for (i = 0; i < 4; i++) { - qemu_put_be32(f, s->fifo[i].state); - for (j = 0; j < 16; j++) { - qemu_put_be32(f, s->fifo[i].data[j]); - } - qemu_put_be32(f, s->ssmux[i]); - qemu_put_be32(f, s->ssctl[i]); +static const VMStateDescription vmstate_stellaris_adc = { + .name = "stellaris_adc", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(actss, stellaris_adc_state), + VMSTATE_UINT32(ris, stellaris_adc_state), + VMSTATE_UINT32(im, stellaris_adc_state), + VMSTATE_UINT32(emux, stellaris_adc_state), + VMSTATE_UINT32(ostat, stellaris_adc_state), + VMSTATE_UINT32(ustat, stellaris_adc_state), + VMSTATE_UINT32(sspri, stellaris_adc_state), + VMSTATE_UINT32(sac, stellaris_adc_state), + VMSTATE_UINT32(fifo[0].state, stellaris_adc_state), + VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16), + VMSTATE_UINT32(ssmux[0], stellaris_adc_state), + VMSTATE_UINT32(ssctl[0], stellaris_adc_state), + VMSTATE_UINT32(fifo[1].state, stellaris_adc_state), + VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16), + VMSTATE_UINT32(ssmux[1], stellaris_adc_state), + VMSTATE_UINT32(ssctl[1], stellaris_adc_state), + VMSTATE_UINT32(fifo[2].state, stellaris_adc_state), + VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16), + VMSTATE_UINT32(ssmux[2], stellaris_adc_state), + VMSTATE_UINT32(ssctl[2], stellaris_adc_state), + VMSTATE_UINT32(fifo[3].state, stellaris_adc_state), + VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16), + VMSTATE_UINT32(ssmux[3], stellaris_adc_state), + VMSTATE_UINT32(ssctl[3], stellaris_adc_state), + VMSTATE_UINT32(noise, stellaris_adc_state), + VMSTATE_END_OF_LIST() } - qemu_put_be32(f, s->noise); -} - -static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) -{ - stellaris_adc_state *s = (stellaris_adc_state *)opaque; - int i; - int j; - - if (version_id != 1) - return -EINVAL; - - s->actss = qemu_get_be32(f); - s->ris = qemu_get_be32(f); - s->im = qemu_get_be32(f); - s->emux = qemu_get_be32(f); - s->ostat = qemu_get_be32(f); - s->ustat = qemu_get_be32(f); - s->sspri = qemu_get_be32(f); - s->sac = qemu_get_be32(f); - for (i = 0; i < 4; i++) { - s->fifo[i].state = qemu_get_be32(f); - for (j = 0; j < 16; j++) { - s->fifo[i].data[j] = qemu_get_be32(f); - } - s->ssmux[i] = qemu_get_be32(f); - s->ssctl[i] = qemu_get_be32(f); - } - s->noise = qemu_get_be32(f); - - return 0; -} +}; static int stellaris_adc_init(SysBusDevice *dev) { @@ -1201,8 +1172,7 @@ static int stellaris_adc_init(SysBusDevice *dev) sysbus_init_mmio(dev, 0x1000, iomemtype); stellaris_adc_reset(s); qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1); - register_savevm(&dev->qdev, "stellaris_adc", -1, 1, - stellaris_adc_save, stellaris_adc_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s); return 0; } @@ -1234,24 +1204,16 @@ static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val) return ssi_transfer(s->bus[s->current_dev], val); } -static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque) -{ - stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; - - qemu_put_be32(f, s->current_dev); -} - -static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id) -{ - stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; - - if (version_id != 1) - return -EINVAL; - - s->current_dev = qemu_get_be32(f); - - return 0; -} +static const VMStateDescription vmstate_stellaris_ssi_bus = { + .name = "stellaris_ssi_bus", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(current_dev, stellaris_ssi_bus_state), + VMSTATE_END_OF_LIST() + } +}; static int stellaris_ssi_bus_init(SSISlave *dev) { @@ -1261,8 +1223,7 @@ static int stellaris_ssi_bus_init(SSISlave *dev) s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1"); qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1); - register_savevm(&dev->qdev, "stellaris_ssi_bus", -1, 1, - stellaris_ssi_bus_save, stellaris_ssi_bus_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s); return 0; } @@ -1300,6 +1261,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, 0x40024000, 0x40025000, 0x40026000}; static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; + MemoryRegion *address_space_mem = get_system_memory(); qemu_irq *pic; DeviceState *gpio_dev[7]; qemu_irq gpio_in[7][8]; @@ -1314,7 +1276,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, flash_size = ((board->dc0 & 0xffff) + 1) << 1; sram_size = (board->dc0 >> 18) + 1; - pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); + pic = armv7m_init(address_space_mem, + flash_size, sram_size, kernel_filename, cpu_model); if (board->dc1 & (1 << 16)) { dev = sysbus_create_varargs("stellaris-adc", 0x40038000, @@ -1334,11 +1297,11 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, } } - stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr); + stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a); for (i = 0; i < 7; i++) { if (board->dc4 & (1 << i)) { - gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i], + gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i], pic[gpio_irq[i]]); for (j = 0; j < 8; j++) { gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j); diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c index 6a0583a..d5613ff 100644 --- a/hw/stellaris_enet.c +++ b/hw/stellaris_enet.c @@ -4,7 +4,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" #include "net.h" @@ -69,7 +69,7 @@ typedef struct { NICState *nic; NICConf conf; qemu_irq irq; - int mmio_index; + MemoryRegion mmio; } stellaris_enet_state; static void stellaris_enet_update(stellaris_enet_state *s) @@ -130,7 +130,8 @@ static int stellaris_enet_can_receive(VLANClientState *nc) return (s->np < 31); } -static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset) +static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset, + unsigned size) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; uint32_t val; @@ -198,7 +199,7 @@ static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset) } static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { stellaris_enet_state *s = (stellaris_enet_state *)opaque; @@ -303,17 +304,12 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset, } } -static CPUReadMemoryFunc * const stellaris_enet_readfn[] = { - stellaris_enet_read, - stellaris_enet_read, - stellaris_enet_read +static const MemoryRegionOps stellaris_enet_ops = { + .read = stellaris_enet_read, + .write = stellaris_enet_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static CPUWriteMemoryFunc * const stellaris_enet_writefn[] = { - stellaris_enet_write, - stellaris_enet_write, - stellaris_enet_write -}; static void stellaris_enet_reset(stellaris_enet_state *s) { s->mdv = 0x80; @@ -391,9 +387,9 @@ static void stellaris_enet_cleanup(VLANClientState *nc) unregister_savevm(&s->busdev.qdev, "stellaris_enet", s); - cpu_unregister_io_memory(s->mmio_index); + memory_region_destroy(&s->mmio); - qemu_free(s); + g_free(s); } static NetClientInfo net_stellaris_enet_info = { @@ -408,10 +404,9 @@ static int stellaris_enet_init(SysBusDevice *dev) { stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev); - s->mmio_index = cpu_register_io_memory(stellaris_enet_readfn, - stellaris_enet_writefn, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, s->mmio_index); + memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet", + 0x1000); + sysbus_init_mmio_region(dev, &s->mmio); sysbus_init_irq(dev, &s->irq); qemu_macaddr_default_if_unset(&s->conf.macaddr); diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c index 16aae96..68c600c 100644 --- a/hw/stellaris_input.c +++ b/hw/stellaris_input.c @@ -4,7 +4,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "hw.h" #include "devices.h" @@ -13,7 +13,7 @@ typedef struct { qemu_irq irq; int keycode; - int pressed; + uint8_t pressed; } gamepad_button; typedef struct { @@ -47,30 +47,29 @@ static void stellaris_gamepad_put_key(void * opaque, int keycode) s->extension = 0; } -static void stellaris_gamepad_save(QEMUFile *f, void *opaque) -{ - gamepad_state *s = (gamepad_state *)opaque; - int i; - - qemu_put_be32(f, s->extension); - for (i = 0; i < s->num_buttons; i++) - qemu_put_byte(f, s->buttons[i].pressed); -} - -static int stellaris_gamepad_load(QEMUFile *f, void *opaque, int version_id) -{ - gamepad_state *s = (gamepad_state *)opaque; - int i; - - if (version_id != 1) - return -EINVAL; - - s->extension = qemu_get_be32(f); - for (i = 0; i < s->num_buttons; i++) - s->buttons[i].pressed = qemu_get_byte(f); +static const VMStateDescription vmstate_stellaris_button = { + .name = "stellaris_button", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT8(pressed, gamepad_button), + VMSTATE_END_OF_LIST() + } +}; - return 0; -} +static const VMStateDescription vmstate_stellaris_gamepad = { + .name = "stellaris_gamepad", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(extension, gamepad_state), + VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0, + vmstate_stellaris_button, gamepad_button), + VMSTATE_END_OF_LIST() + } +}; /* Returns an array 5 ouput slots. */ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) @@ -78,14 +77,13 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) gamepad_state *s; int i; - s = (gamepad_state *)qemu_mallocz(sizeof (gamepad_state)); - s->buttons = (gamepad_button *)qemu_mallocz(n * sizeof (gamepad_button)); + s = (gamepad_state *)g_malloc0(sizeof (gamepad_state)); + s->buttons = (gamepad_button *)g_malloc0(n * sizeof (gamepad_button)); for (i = 0; i < n; i++) { s->buttons[i].irq = irq[i]; s->buttons[i].keycode = keycode[i]; } s->num_buttons = n; qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s); - register_savevm(NULL, "stellaris_gamepad", -1, 1, - stellaris_gamepad_save, stellaris_gamepad_load, s); + vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s); } diff --git a/hw/sun4m.c b/hw/sun4m.c index 30e8a21..314edc4 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -97,12 +97,12 @@ struct sun4m_hwdef { target_phys_addr_t reg_base, vram_base; } vsimm[MAX_VSIMMS]; target_phys_addr_t ecc_base; - uint32_t ecc_version; - uint8_t nvram_machine_id; - uint16_t machine_id; - uint32_t iommu_version; uint64_t max_mem; const char * const default_cpu_model; + uint32_t ecc_version; + uint32_t iommu_version; + uint16_t machine_id; + uint8_t nvram_machine_id; }; #define MAX_IOUNITS 5 @@ -115,11 +115,11 @@ struct sun4d_hwdef { target_phys_addr_t ledma_base, le_base; target_phys_addr_t tcx_base; target_phys_addr_t sbi_base; - uint8_t nvram_machine_id; - uint16_t machine_id; - uint32_t iounit_version; uint64_t max_mem; const char * const default_cpu_model; + uint32_t iounit_version; + uint16_t machine_id; + uint8_t nvram_machine_id; }; struct sun4c_hwdef { @@ -128,11 +128,11 @@ struct sun4c_hwdef { target_phys_addr_t serial_base, fd_base; target_phys_addr_t idreg_base, dma_base, esp_base, le_base; target_phys_addr_t tcx_base, aux1_base; - uint8_t nvram_machine_id; - uint16_t machine_id; - uint32_t iommu_version; uint64_t max_mem; const char * const default_cpu_model; + uint32_t iommu_version; + uint16_t machine_id; + uint8_t nvram_machine_id; }; int DMA_get_channel_mode (int nchan) @@ -216,13 +216,13 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr, static DeviceState *slavio_intctl; -void pic_info(Monitor *mon) +void sun4m_pic_info(Monitor *mon) { if (slavio_intctl) slavio_pic_info(mon, slavio_intctl); } -void irq_info(Monitor *mon) +void sun4m_irq_info(Monitor *mon) { if (slavio_intctl) slavio_irq_info(mon, slavio_intctl); @@ -253,15 +253,21 @@ void cpu_check_irqs(CPUState *env) } } +static void cpu_kick_irq(CPUState *env) +{ + env->halted = 0; + cpu_check_irqs(env); + qemu_cpu_kick(env); +} + static void cpu_set_irq(void *opaque, int irq, int level) { CPUState *env = opaque; if (level) { trace_sun4m_cpu_set_irq_raise(irq); - env->halted = 0; env->pil_in |= 1 << irq; - cpu_check_irqs(env); + cpu_kick_irq(env); } else { trace_sun4m_cpu_set_irq_lower(irq); env->pil_in &= ~(1 << irq); @@ -587,19 +593,25 @@ static void idreg_init(target_phys_addr_t addr) cpu_physical_memory_write_rom(addr, idreg_data, sizeof(idreg_data)); } +typedef struct IDRegState { + SysBusDevice busdev; + MemoryRegion mem; +} IDRegState; + static int idreg_init1(SysBusDevice *dev) { - ram_addr_t idreg_offset; + IDRegState *s = FROM_SYSBUS(IDRegState, dev); - idreg_offset = qemu_ram_alloc(NULL, "sun4m.idreg", sizeof(idreg_data)); - sysbus_init_mmio(dev, sizeof(idreg_data), idreg_offset | IO_MEM_ROM); + memory_region_init_ram(&s->mem, NULL, "sun4m.idreg", sizeof(idreg_data)); + memory_region_set_readonly(&s->mem, true); + sysbus_init_mmio_region(dev, &s->mem); return 0; } static SysBusDeviceInfo idreg_info = { .init = idreg_init1, .qdev.name = "macio_idreg", - .qdev.size = sizeof(SysBusDevice), + .qdev.size = sizeof(IDRegState), }; static void idreg_register_devices(void) @@ -609,6 +621,11 @@ static void idreg_register_devices(void) device_init(idreg_register_devices); +typedef struct AFXState { + SysBusDevice busdev; + MemoryRegion mem; +} AFXState; + /* SS-5 TCX AFX register */ static void afx_init(target_phys_addr_t addr) { @@ -624,17 +641,17 @@ static void afx_init(target_phys_addr_t addr) static int afx_init1(SysBusDevice *dev) { - ram_addr_t afx_offset; + AFXState *s = FROM_SYSBUS(AFXState, dev); - afx_offset = qemu_ram_alloc(NULL, "sun4m.afx", 4); - sysbus_init_mmio(dev, 4, afx_offset | IO_MEM_RAM); + memory_region_init_ram(&s->mem, NULL, "sun4m.afx", 4); + sysbus_init_mmio_region(dev, &s->mem); return 0; } static SysBusDeviceInfo afx_info = { .init = afx_init1, .qdev.name = "tcx_afx", - .qdev.size = sizeof(SysBusDevice), + .qdev.size = sizeof(AFXState), }; static void afx_register_devices(void) @@ -644,6 +661,11 @@ static void afx_register_devices(void) device_init(afx_register_devices); +typedef struct PROMState { + SysBusDevice busdev; + MemoryRegion prom; +} PROMState; + /* Boot PROM (OpenBIOS) */ static uint64_t translate_prom_address(void *opaque, uint64_t addr) { @@ -675,7 +697,7 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name) if (ret < 0 || ret > PROM_SIZE_MAX) { ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); } - qemu_free(filename); + g_free(filename); } else { ret = -1; } @@ -687,17 +709,18 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name) static int prom_init1(SysBusDevice *dev) { - ram_addr_t prom_offset; + PROMState *s = FROM_SYSBUS(PROMState, dev); - prom_offset = qemu_ram_alloc(NULL, "sun4m.prom", PROM_SIZE_MAX); - sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM); + memory_region_init_ram(&s->prom, NULL, "sun4m.prom", PROM_SIZE_MAX); + memory_region_set_readonly(&s->prom, true); + sysbus_init_mmio_region(dev, &s->prom); return 0; } static SysBusDeviceInfo prom_info = { .init = prom_init1, .qdev.name = "openprom", - .qdev.size = sizeof(SysBusDevice), + .qdev.size = sizeof(PROMState), .qdev.props = (Property[]) { {/* end of property list */} } @@ -713,19 +736,17 @@ device_init(prom_register_devices); typedef struct RamDevice { SysBusDevice busdev; + MemoryRegion ram; uint64_t size; } RamDevice; /* System RAM */ static int ram_init1(SysBusDevice *dev) { - ram_addr_t RAM_size, ram_offset; RamDevice *d = FROM_SYSBUS(RamDevice, dev); - RAM_size = d->size; - - ram_offset = qemu_ram_alloc(NULL, "sun4m.ram", RAM_size); - sysbus_init_mmio(dev, RAM_size, ram_offset); + memory_region_init_ram(&d->ram, NULL, "sun4m.ram", d->size); + sysbus_init_mmio_region(dev, &d->ram); return 0; } diff --git a/hw/sun4m.h b/hw/sun4m.h index ce97ee5..504c3af 100644 --- a/hw/sun4m.h +++ b/hw/sun4m.h @@ -30,6 +30,10 @@ void slavio_irq_info(Monitor *mon, DeviceState *dev); void sun4c_pic_info(Monitor *mon, void *opaque); void sun4c_irq_info(Monitor *mon, void *opaque); +/* sun4m.c */ +void sun4m_pic_info(Monitor *mon); +void sun4m_irq_info(Monitor *mon); + /* sparc32_dma.c */ #include "sparc32_dma.h" diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c index bba69ee..6eeadfa 100644 --- a/hw/sun4m_iommu.c +++ b/hw/sun4m_iommu.c @@ -118,7 +118,7 @@ #define IOPTE_PAGE 0xffffff00 /* Physical page number (PA[35:12]) */ #define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */ -#define IOPTE_WRITE 0x00000004 /* Writeable */ +#define IOPTE_WRITE 0x00000004 /* Writable */ #define IOPTE_VALID 0x00000002 /* IOPTE is valid */ #define IOPTE_WAZ 0x00000001 /* Write as zeros */ @@ -130,8 +130,8 @@ typedef struct IOMMUState { SysBusDevice busdev; uint32_t regs[IOMMU_NREGS]; target_phys_addr_t iostart; - uint32_t version; qemu_irq irq; + uint32_t version; } IOMMUState; static uint32_t iommu_mem_readl(void *opaque, target_phys_addr_t addr) diff --git a/hw/sun4u.c b/hw/sun4u.c index 90b1ce2..eaaefe3 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -38,6 +38,7 @@ #include "loader.h" #include "elf.h" #include "blockdev.h" +#include "exec-memory.h" //#define DEBUG_IRQ //#define DEBUG_EBUS @@ -91,6 +92,12 @@ struct hwdef { uint64_t console_serial_base; }; +typedef struct EbusState { + PCIDevice pci_dev; + MemoryRegion bar0; + MemoryRegion bar1; +} EbusState; + int DMA_get_channel_mode (int nchan) { return 0; @@ -236,14 +243,6 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename, return kernel_size; } -void pic_info(Monitor *mon) -{ -} - -void irq_info(Monitor *mon) -{ -} - void cpu_check_irqs(CPUState *env) { uint32_t pil = env->pil_in | @@ -255,7 +254,9 @@ void cpu_check_irqs(CPUState *env) pil |= 1 << 14; } - if (!pil) { + /* The bit corresponding to psrpil is (1<< psrpil), the next bit + is (2 << psrpil). */ + if (pil < (2 << env->psrpil)){ if (env->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n", env->interrupt_index); @@ -287,10 +288,12 @@ void cpu_check_irqs(CPUState *env) break; } } - } else { + } else if (env->interrupt_request & CPU_INTERRUPT_HARD) { CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x " "current interrupt %x\n", pil, env->pil_in, env->softint, env->interrupt_index); + env->interrupt_index = 0; + cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); } } @@ -298,6 +301,7 @@ static void cpu_kick_irq(CPUState *env) { env->halted = 0; cpu_check_irqs(env); + qemu_cpu_kick(env); } static void cpu_set_irq(void *opaque, int irq, int level) @@ -306,9 +310,8 @@ static void cpu_set_irq(void *opaque, int irq, int level) if (level) { CPUIRQ_DPRINTF("Raise CPU IRQ %d\n", irq); - env->halted = 0; env->pil_in |= 1 << irq; - cpu_check_irqs(env); + cpu_kick_irq(env); } else { CPUIRQ_DPRINTF("Lower CPU IRQ %d\n", irq); env->pil_in &= ~(1 << irq); @@ -345,16 +348,16 @@ static CPUTimer* cpu_timer_create(const char* name, CPUState *env, QEMUBHFunc *cb, uint32_t frequency, uint64_t disabled_mask) { - CPUTimer *timer = qemu_mallocz(sizeof (CPUTimer)); + CPUTimer *timer = g_malloc0(sizeof (CPUTimer)); timer->name = name; timer->frequency = frequency; timer->disabled_mask = disabled_mask; timer->disabled = 1; - timer->clock_offset = qemu_get_clock(vm_clock); + timer->clock_offset = qemu_get_clock_ns(vm_clock); - timer->qtimer = qemu_new_timer(vm_clock, cb, env); + timer->qtimer = qemu_new_timer_ns(vm_clock, cb, env); return timer; } @@ -362,7 +365,7 @@ static CPUTimer* cpu_timer_create(const char* name, CPUState *env, static void cpu_timer_reset(CPUTimer *timer) { timer->disabled = 1; - timer->clock_offset = qemu_get_clock(vm_clock); + timer->clock_offset = qemu_get_clock_ns(vm_clock); qemu_del_timer(timer->qtimer); } @@ -457,7 +460,7 @@ void cpu_tick_set_count(CPUTimer *timer, uint64_t count) uint64_t real_count = count & ~timer->disabled_mask; uint64_t disabled_bit = count & timer->disabled_mask; - int64_t vm_clock_offset = qemu_get_clock(vm_clock) - + int64_t vm_clock_offset = qemu_get_clock_ns(vm_clock) - cpu_to_timer_ticks(real_count, timer->frequency); TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n", @@ -471,7 +474,7 @@ void cpu_tick_set_count(CPUTimer *timer, uint64_t count) uint64_t cpu_tick_get_count(CPUTimer *timer) { uint64_t real_count = timer_to_cpu_ticks( - qemu_get_clock(vm_clock) - timer->clock_offset, + qemu_get_clock_ns(vm_clock) - timer->clock_offset, timer->frequency); TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n", @@ -486,7 +489,7 @@ uint64_t cpu_tick_get_count(CPUTimer *timer) void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit) { - int64_t now = qemu_get_clock(vm_clock); + int64_t now = qemu_get_clock_ns(vm_clock); uint64_t real_limit = limit & ~timer->disabled_mask; timer->disabled = (limit & timer->disabled_mask) ? 1 : 0; @@ -518,21 +521,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit) } } -static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n", - region_num, addr); - switch (region_num) { - case 0: - isa_mmio_init(addr, 0x1000000); - break; - case 1: - isa_mmio_init(addr, 0x800000); - break; - } -} - static void dummy_isa_irq_handler(void *opaque, int n, int level) { } @@ -549,32 +537,34 @@ pci_ebus_init(PCIBus *bus, int devfn) } static int -pci_ebus_init1(PCIDevice *s) -{ - isa_bus_new(&s->qdev); - - pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN); - pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS); - s->config[0x04] = 0x06; // command = bus master, pci mem - s->config[0x05] = 0x00; - s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error - s->config[0x07] = 0x03; // status = medium devsel - s->config[0x08] = 0x01; // revision - s->config[0x09] = 0x00; // programming i/f - pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER); - s->config[0x0D] = 0x0a; // latency_timer - - pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY, - ebus_mmio_mapfunc); - pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY, - ebus_mmio_mapfunc); +pci_ebus_init1(PCIDevice *pci_dev) +{ + EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev); + + isa_bus_new(&pci_dev->qdev, pci_address_space_io(pci_dev)); + + pci_dev->config[0x04] = 0x06; // command = bus master, pci mem + pci_dev->config[0x05] = 0x00; + pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error + pci_dev->config[0x07] = 0x03; // status = medium devsel + pci_dev->config[0x09] = 0x00; // programming i/f + pci_dev->config[0x0D] = 0x0a; // latency_timer + + isa_mmio_setup(&s->bar0, 0x1000000); + pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0); + isa_mmio_setup(&s->bar1, 0x800000); + pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1); return 0; } static PCIDeviceInfo ebus_info = { .qdev.name = "ebus", - .qdev.size = sizeof(PCIDevice), + .qdev.size = sizeof(EbusState), .init = pci_ebus_init1, + .vendor_id = PCI_VENDOR_ID_SUN, + .device_id = PCI_DEVICE_ID_SUN_EBUS, + .revision = 0x01, + .class_id = PCI_CLASS_BRIDGE_OTHER, }; static void pci_ebus_register(void) @@ -584,6 +574,11 @@ static void pci_ebus_register(void) device_init(pci_ebus_register); +typedef struct PROMState { + SysBusDevice busdev; + MemoryRegion prom; +} PROMState; + static uint64_t translate_prom_address(void *opaque, uint64_t addr) { target_phys_addr_t *base_addr = (target_phys_addr_t *)opaque; @@ -615,7 +610,7 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name) if (ret < 0 || ret > PROM_SIZE_MAX) { ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); } - qemu_free(filename); + g_free(filename); } else { ret = -1; } @@ -627,17 +622,18 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name) static int prom_init1(SysBusDevice *dev) { - ram_addr_t prom_offset; + PROMState *s = FROM_SYSBUS(PROMState, dev); - prom_offset = qemu_ram_alloc(NULL, "sun4u.prom", PROM_SIZE_MAX); - sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM); + memory_region_init_ram(&s->prom, NULL, "sun4u.prom", PROM_SIZE_MAX); + memory_region_set_readonly(&s->prom, true); + sysbus_init_mmio_region(dev, &s->prom); return 0; } static SysBusDeviceInfo prom_info = { .init = prom_init1, .qdev.name = "openprom", - .qdev.size = sizeof(SysBusDevice), + .qdev.size = sizeof(PROMState), .qdev.props = (Property[]) { {/* end of property list */} } @@ -654,19 +650,17 @@ device_init(prom_register_devices); typedef struct RamDevice { SysBusDevice busdev; + MemoryRegion ram; uint64_t size; } RamDevice; /* System RAM */ static int ram_init1(SysBusDevice *dev) { - ram_addr_t RAM_size, ram_offset; RamDevice *d = FROM_SYSBUS(RamDevice, dev); - RAM_size = d->size; - - ram_offset = qemu_ram_alloc(NULL, "sun4u.ram", RAM_size); - sysbus_init_mmio(dev, RAM_size, ram_offset); + memory_region_init_ram(&d->ram, NULL, "sun4u.ram", d->size); + sysbus_init_mmio_region(dev, &d->ram); return 0; } @@ -730,7 +724,7 @@ static CPUState *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef) env->hstick = cpu_timer_create("hstick", env, hstick_irq, hstick_frequency, TICK_INT_DIS); - reset_info = qemu_mallocz(sizeof(ResetData)); + reset_info = g_malloc0(sizeof(ResetData)); reset_info->env = env; reset_info->prom_addr = hwdef->prom_addr; qemu_register_reset(main_cpu_reset, reset_info); @@ -738,7 +732,8 @@ static CPUState *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef) return env; } -static void sun4uv_init(ram_addr_t RAM_size, +static void sun4uv_init(MemoryRegion *address_space_mem, + ram_addr_t RAM_size, const char *boot_devices, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, @@ -766,7 +761,6 @@ static void sun4uv_init(ram_addr_t RAM_size, irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2, &pci_bus3); - isa_mem_base = APB_PCI_IO_BASE; pci_vga_init(pci_bus); // XXX Should be pci_bus3 @@ -774,8 +768,8 @@ static void sun4uv_init(ram_addr_t RAM_size, i = 0; if (hwdef->console_serial_base) { - serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200, - serial_hds[i], 1, 1); + serial_mm_init(address_space_mem, hwdef->console_serial_base, 0, + NULL, 115200, serial_hds[i], DEVICE_BIG_ENDIAN); i++; } for(; i < MAX_SERIAL_PORTS; i++) { @@ -793,14 +787,7 @@ static void sun4uv_init(ram_addr_t RAM_size, for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); - if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { - fprintf(stderr, "qemu: too many IDE bus\n"); - exit(1); - } - for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { - hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, - i % MAX_IDE_DEVS); - } + ide_drive_get(hd, MAX_IDE_BUS); pci_cmd646_ide_init(pci_bus, hd, 1); @@ -886,7 +873,7 @@ static void sun4u_init(ram_addr_t RAM_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - sun4uv_init(RAM_size, boot_devices, kernel_filename, + sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]); } @@ -896,7 +883,7 @@ static void sun4v_init(ram_addr_t RAM_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - sun4uv_init(RAM_size, boot_devices, kernel_filename, + sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]); } @@ -906,7 +893,7 @@ static void niagara_init(ram_addr_t RAM_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { - sun4uv_init(RAM_size, boot_devices, kernel_filename, + sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]); } diff --git a/hw/syborg.c b/hw/syborg.c index 758c69a..248de54 100644 --- a/hw/syborg.c +++ b/hw/syborg.c @@ -25,8 +25,8 @@ #include "sysbus.h" #include "boards.h" #include "arm-misc.h" -#include "sysemu.h" #include "net.h" +#include "exec-memory.h" static struct arm_boot_info syborg_binfo; @@ -36,9 +36,10 @@ static void syborg_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; + MemoryRegion *sysmem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); qemu_irq *cpu_pic; qemu_irq pic[64]; - ram_addr_t ram_addr; DeviceState *dev; int i; @@ -51,8 +52,8 @@ static void syborg_init(ram_addr_t ram_size, } /* RAM at address zero. */ - ram_addr = qemu_ram_alloc(NULL, "syborg.ram", ram_size); - cpu_register_physical_memory(0, ram_size, ram_addr | IO_MEM_RAM); + memory_region_init_ram(ram, NULL, "syborg.ram", ram_size); + memory_region_add_subregion(sysmem, 0, ram); cpu_pic = arm_pic_init_cpu(env); dev = sysbus_create_simple("syborg,interrupt", 0xC0000000, diff --git a/hw/syborg_fb.c b/hw/syborg_fb.c index 7e37364..ae3e0eb 100644 --- a/hw/syborg_fb.c +++ b/hw/syborg_fb.c @@ -217,15 +217,24 @@ static void syborg_fb_update_display(void *opaque) } if (s->rgb) { - bpp_offset = 18; + bpp_offset = 24; } else { bpp_offset = 0; } if (s->endian) { + bpp_offset += 8; + } + /* Our bpp constants mostly match the PL110/PL111 but + * not for the 16 bit case + */ + switch (s->bpp) { + case BPP_SRC_16: bpp_offset += 6; + break; + default: + bpp_offset += s->bpp; } - - fn = fntable[s->bpp + bpp_offset]; + fn = fntable[bpp_offset]; if (s->pitch) { src_width = s->pitch; diff --git a/hw/syborg_interrupt.c b/hw/syborg_interrupt.c index 5217983..1b0f3bb 100644 --- a/hw/syborg_interrupt.c +++ b/hw/syborg_interrupt.c @@ -213,7 +213,7 @@ static int syborg_int_init(SysBusDevice *dev) syborg_int_writefn, s, DEVICE_NATIVE_ENDIAN); sysbus_init_mmio(dev, 0x1000, iomemtype); - s->flags = qemu_mallocz(s->num_irqs * sizeof(syborg_int_flags)); + s->flags = g_malloc0(s->num_irqs * sizeof(syborg_int_flags)); register_savevm(&dev->qdev, "syborg_int", -1, 1, syborg_int_save, syborg_int_load, s); diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c index d295e99..82b9dc0 100644 --- a/hw/syborg_keyboard.c +++ b/hw/syborg_keyboard.c @@ -51,11 +51,11 @@ enum { typedef struct { SysBusDevice busdev; - int int_enabled; + uint32_t int_enabled; int extension_bit; uint32_t fifo_size; uint32_t *key_fifo; - int read_pos, read_count; + uint32_t read_pos, read_count; qemu_irq irq; } SyborgKeyboardState; @@ -165,43 +165,21 @@ static void syborg_keyboard_event(void *opaque, int keycode) syborg_keyboard_update(s); } -static void syborg_keyboard_save(QEMUFile *f, void *opaque) -{ - SyborgKeyboardState *s = (SyborgKeyboardState *)opaque; - int i; - - qemu_put_be32(f, s->fifo_size); - qemu_put_be32(f, s->int_enabled); - qemu_put_be32(f, s->extension_bit); - qemu_put_be32(f, s->read_pos); - qemu_put_be32(f, s->read_count); - for (i = 0; i < s->fifo_size; i++) { - qemu_put_be32(f, s->key_fifo[i]); - } -} - -static int syborg_keyboard_load(QEMUFile *f, void *opaque, int version_id) -{ - SyborgKeyboardState *s = (SyborgKeyboardState *)opaque; - uint32_t val; - int i; - - if (version_id != 1) - return -EINVAL; - - val = qemu_get_be32(f); - if (val != s->fifo_size) - return -EINVAL; - - s->int_enabled = qemu_get_be32(f); - s->extension_bit = qemu_get_be32(f); - s->read_pos = qemu_get_be32(f); - s->read_count = qemu_get_be32(f); - for (i = 0; i < s->fifo_size; i++) { - s->key_fifo[i] = qemu_get_be32(f); +static const VMStateDescription vmstate_syborg_keyboard = { + .name = "syborg_keyboard", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_EQUAL(fifo_size, SyborgKeyboardState), + VMSTATE_UINT32(int_enabled, SyborgKeyboardState), + VMSTATE_UINT32(read_pos, SyborgKeyboardState), + VMSTATE_UINT32(read_count, SyborgKeyboardState), + VMSTATE_VARRAY_UINT32(key_fifo, SyborgKeyboardState, fifo_size, 1, + vmstate_info_uint32, uint32), + VMSTATE_END_OF_LIST() } - return 0; -} +}; static int syborg_keyboard_init(SysBusDevice *dev) { @@ -217,12 +195,11 @@ static int syborg_keyboard_init(SysBusDevice *dev) fprintf(stderr, "syborg_keyboard: fifo too small\n"); s->fifo_size = 16; } - s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0])); + s->key_fifo = g_malloc0(s->fifo_size * sizeof(s->key_fifo[0])); qemu_add_kbd_event_handler(syborg_keyboard_event, s); - register_savevm(&dev->qdev, "syborg_keyboard", -1, 1, - syborg_keyboard_save, syborg_keyboard_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_syborg_keyboard, s); return 0; } diff --git a/hw/syborg_pointer.c b/hw/syborg_pointer.c index a886888..b91214d 100644 --- a/hw/syborg_pointer.c +++ b/hw/syborg_pointer.c @@ -152,52 +152,36 @@ static void syborg_pointer_event(void *opaque, int dx, int dy, int dz, syborg_pointer_update(s); } -static void syborg_pointer_save(QEMUFile *f, void *opaque) -{ - SyborgPointerState *s = (SyborgPointerState *)opaque; - int i; - - qemu_put_be32(f, s->fifo_size); - qemu_put_be32(f, s->absolute); - qemu_put_be32(f, s->int_enabled); - qemu_put_be32(f, s->read_pos); - qemu_put_be32(f, s->read_count); - for (i = 0; i < s->fifo_size; i++) { - qemu_put_be32(f, s->event_fifo[i].x); - qemu_put_be32(f, s->event_fifo[i].y); - qemu_put_be32(f, s->event_fifo[i].z); - qemu_put_be32(f, s->event_fifo[i].pointer_buttons); +static const VMStateDescription vmstate_event_data = { + .name = "dbma_channel", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_INT32(x, event_data), + VMSTATE_INT32(y, event_data), + VMSTATE_INT32(z, event_data), + VMSTATE_INT32(pointer_buttons, event_data), + VMSTATE_END_OF_LIST() } -} +}; -static int syborg_pointer_load(QEMUFile *f, void *opaque, int version_id) -{ - SyborgPointerState *s = (SyborgPointerState *)opaque; - uint32_t val; - int i; - - if (version_id != 1) - return -EINVAL; - - val = qemu_get_be32(f); - if (val != s->fifo_size) - return -EINVAL; - - val = qemu_get_be32(f); - if (val != s->absolute) - return -EINVAL; - - s->int_enabled = qemu_get_be32(f); - s->read_pos = qemu_get_be32(f); - s->read_count = qemu_get_be32(f); - for (i = 0; i < s->fifo_size; i++) { - s->event_fifo[i].x = qemu_get_be32(f); - s->event_fifo[i].y = qemu_get_be32(f); - s->event_fifo[i].z = qemu_get_be32(f); - s->event_fifo[i].pointer_buttons = qemu_get_be32(f); +static const VMStateDescription vmstate_syborg_pointer = { + .name = "syborg_pointer", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_EQUAL(fifo_size, SyborgPointerState), + VMSTATE_UINT32_EQUAL(absolute, SyborgPointerState), + VMSTATE_INT32(int_enabled, SyborgPointerState), + VMSTATE_INT32(read_pos, SyborgPointerState), + VMSTATE_INT32(read_count, SyborgPointerState), + VMSTATE_STRUCT_VARRAY_UINT32(event_fifo, SyborgPointerState, fifo_size, + 1, vmstate_event_data, event_data), + VMSTATE_END_OF_LIST() } - return 0; -} +}; static int syborg_pointer_init(SysBusDevice *dev) { @@ -214,13 +198,12 @@ static int syborg_pointer_init(SysBusDevice *dev) fprintf(stderr, "syborg_pointer: fifo too small\n"); s->fifo_size = 16; } - s->event_fifo = qemu_mallocz(s->fifo_size * sizeof(s->event_fifo[0])); + s->event_fifo = g_malloc0(s->fifo_size * sizeof(s->event_fifo[0])); qemu_add_mouse_event_handler(syborg_pointer_event, s, s->absolute, "Syborg Pointer"); - register_savevm(&dev->qdev, "syborg_pointer", -1, 1, - syborg_pointer_save, syborg_pointer_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_syborg_pointer, s); return 0; } diff --git a/hw/syborg_rtc.c b/hw/syborg_rtc.c index 329aa42..69f6ccf 100644 --- a/hw/syborg_rtc.c +++ b/hw/syborg_rtc.c @@ -66,7 +66,7 @@ static void syborg_rtc_write(void *opaque, target_phys_addr_t offset, uint32_t v offset &= 0xfff; switch (offset >> 2) { case RTC_LATCH: - now = qemu_get_clock(vm_clock); + now = qemu_get_clock_ns(vm_clock); if (value >= 4) { s->offset = s->data - now; } else { @@ -102,26 +102,17 @@ static CPUWriteMemoryFunc * const syborg_rtc_writefn[] = { syborg_rtc_write }; -static void syborg_rtc_save(QEMUFile *f, void *opaque) -{ - SyborgRTCState *s = opaque; - - qemu_put_be64(f, s->offset); - qemu_put_be64(f, s->data); -} - -static int syborg_rtc_load(QEMUFile *f, void *opaque, int version_id) -{ - SyborgRTCState *s = opaque; - - if (version_id != 1) - return -EINVAL; - - s->offset = qemu_get_be64(f); - s->data = qemu_get_be64(f); - - return 0; -} +static const VMStateDescription vmstate_syborg_rtc = { + .name = "syborg_keyboard", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT64(offset, SyborgRTCState), + VMSTATE_INT64(data, SyborgRTCState), + VMSTATE_END_OF_LIST() + } +}; static int syborg_rtc_init(SysBusDevice *dev) { @@ -137,8 +128,7 @@ static int syborg_rtc_init(SysBusDevice *dev) qemu_get_timedate(&tm, 0); s->offset = (uint64_t)mktime(&tm) * 1000000000; - register_savevm(&dev->qdev, "syborg_rtc", -1, 1, - syborg_rtc_save, syborg_rtc_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_syborg_rtc, s); return 0; } diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c index 34ce076..c83f82c 100644 --- a/hw/syborg_serial.c +++ b/hw/syborg_serial.c @@ -119,14 +119,14 @@ static void do_dma_tx(SyborgSerialState *s, uint32_t count) /* optimize later. Now, 1 byte per iteration */ while (count--) { cpu_physical_memory_read(s->dma_tx_ptr, &ch, 1); - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); s->dma_tx_ptr++; } } else { s->dma_tx_ptr += count; } /* QEMU char backends do not have a nonblocking mode, so we transmit all - the data imediately and the interrupt status will be unchanged. */ + the data immediately and the interrupt status will be unchanged. */ } /* Initiate RX DMA, and transfer data from the FIFO. */ @@ -203,7 +203,7 @@ static void syborg_serial_write(void *opaque, target_phys_addr_t offset, case SERIAL_DATA: ch = value; if (s->chr) - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); break; case SERIAL_INT_ENABLE: s->int_enable = value; @@ -273,47 +273,24 @@ static CPUWriteMemoryFunc * const syborg_serial_writefn[] = { syborg_serial_write }; -static void syborg_serial_save(QEMUFile *f, void *opaque) -{ - SyborgSerialState *s = opaque; - int i; - - qemu_put_be32(f, s->fifo_size); - qemu_put_be32(f, s->int_enable); - qemu_put_be32(f, s->read_pos); - qemu_put_be32(f, s->read_count); - qemu_put_be32(f, s->dma_tx_ptr); - qemu_put_be32(f, s->dma_rx_ptr); - qemu_put_be32(f, s->dma_rx_size); - for (i = 0; i < s->fifo_size; i++) { - qemu_put_be32(f, s->read_fifo[i]); - } -} - -static int syborg_serial_load(QEMUFile *f, void *opaque, int version_id) -{ - SyborgSerialState *s = opaque; - int i; - - if (version_id != 1) - return -EINVAL; - - i = qemu_get_be32(f); - if (s->fifo_size != i) - return -EINVAL; - - s->int_enable = qemu_get_be32(f); - s->read_pos = qemu_get_be32(f); - s->read_count = qemu_get_be32(f); - s->dma_tx_ptr = qemu_get_be32(f); - s->dma_rx_ptr = qemu_get_be32(f); - s->dma_rx_size = qemu_get_be32(f); - for (i = 0; i < s->fifo_size; i++) { - s->read_fifo[i] = qemu_get_be32(f); +static const VMStateDescription vmstate_syborg_serial = { + .name = "syborg_serial", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_EQUAL(fifo_size, SyborgSerialState), + VMSTATE_UINT32(int_enable, SyborgSerialState), + VMSTATE_INT32(read_pos, SyborgSerialState), + VMSTATE_INT32(read_count, SyborgSerialState), + VMSTATE_UINT32(dma_tx_ptr, SyborgSerialState), + VMSTATE_UINT32(dma_rx_ptr, SyborgSerialState), + VMSTATE_UINT32(dma_rx_size, SyborgSerialState), + VMSTATE_VARRAY_UINT32(read_fifo, SyborgSerialState, fifo_size, 1, + vmstate_info_uint32, uint32), + VMSTATE_END_OF_LIST() } - - return 0; -} +}; static int syborg_serial_init(SysBusDevice *dev) { @@ -334,10 +311,8 @@ static int syborg_serial_init(SysBusDevice *dev) fprintf(stderr, "syborg_serial: fifo too small\n"); s->fifo_size = 16; } - s->read_fifo = qemu_mallocz(s->fifo_size * sizeof(s->read_fifo[0])); + s->read_fifo = g_malloc0(s->fifo_size * sizeof(s->read_fifo[0])); - register_savevm(&dev->qdev, "syborg_serial", -1, 1, - syborg_serial_save, syborg_serial_load, s); return 0; } @@ -345,6 +320,7 @@ static SysBusDeviceInfo syborg_serial_info = { .init = syborg_serial_init, .qdev.name = "syborg,serial", .qdev.size = sizeof(SyborgSerialState), + .qdev.vmsd = &vmstate_syborg_serial, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("fifo-size", SyborgSerialState, fifo_size, 16), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/syborg_timer.c b/hw/syborg_timer.c index cedcd8e..50c813e 100644 --- a/hw/syborg_timer.c +++ b/hw/syborg_timer.c @@ -174,34 +174,21 @@ static CPUWriteMemoryFunc * const syborg_timer_writefn[] = { syborg_timer_write }; -static void syborg_timer_save(QEMUFile *f, void *opaque) -{ - SyborgTimerState *s = opaque; - - qemu_put_be32(f, s->running); - qemu_put_be32(f, s->oneshot); - qemu_put_be32(f, s->limit); - qemu_put_be32(f, s->int_level); - qemu_put_be32(f, s->int_enabled); - qemu_put_ptimer(f, s->timer); -} - -static int syborg_timer_load(QEMUFile *f, void *opaque, int version_id) -{ - SyborgTimerState *s = opaque; - - if (version_id != 1) - return -EINVAL; - - s->running = qemu_get_be32(f); - s->oneshot = qemu_get_be32(f); - s->limit = qemu_get_be32(f); - s->int_level = qemu_get_be32(f); - s->int_enabled = qemu_get_be32(f); - qemu_get_ptimer(f, s->timer); - - return 0; -} +static const VMStateDescription vmstate_syborg_timer = { + .name = "syborg_timer", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(running, SyborgTimerState), + VMSTATE_INT32(oneshot, SyborgTimerState), + VMSTATE_UINT32(limit, SyborgTimerState), + VMSTATE_UINT32(int_level, SyborgTimerState), + VMSTATE_UINT32(int_enabled, SyborgTimerState), + VMSTATE_PTIMER(timer, SyborgTimerState), + VMSTATE_END_OF_LIST() + } +}; static int syborg_timer_init(SysBusDevice *dev) { @@ -222,8 +209,7 @@ static int syborg_timer_init(SysBusDevice *dev) bh = qemu_bh_new(syborg_timer_tick, s); s->timer = ptimer_init(bh); ptimer_set_freq(s->timer, s->freq); - register_savevm(&dev->qdev, "syborg_timer", -1, 1, - syborg_timer_save, syborg_timer_load, s); + vmstate_register(&dev->qdev, -1, &vmstate_syborg_timer, s); return 0; } diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c index ee08c49..6de952c 100644 --- a/hw/syborg_virtio.c +++ b/hw/syborg_virtio.c @@ -26,7 +26,6 @@ #include "sysbus.h" #include "virtio.h" #include "virtio-net.h" -#include "sysemu.h" //#define DEBUG_SYBORG_VIRTIO @@ -132,9 +131,7 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset, } switch (offset >> 2) { case SYBORG_VIRTIO_GUEST_FEATURES: - if (vdev->set_features) - vdev->set_features(vdev, value); - vdev->guest_features = value; + virtio_set_features(vdev, value); break; case SYBORG_VIRTIO_QUEUE_BASE: if (value == 0) @@ -147,7 +144,9 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset, vdev->queue_sel = value; break; case SYBORG_VIRTIO_QUEUE_NOTIFY: - virtio_queue_notify(vdev, value); + if (value < VIRTIO_PCI_QUEUE_MAX) { + virtio_queue_notify(vdev, value); + } break; case SYBORG_VIRTIO_STATUS: virtio_set_status(vdev, value & 0xFF); diff --git a/hw/sysbus.c b/hw/sysbus.c index 1583bd8..fd2fc6a 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -18,8 +18,8 @@ */ #include "sysbus.h" -#include "sysemu.h" #include "monitor.h" +#include "exec-memory.h" static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *sysbus_get_fw_dev_path(DeviceState *dev); @@ -50,11 +50,22 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) } if (dev->mmio[n].addr != (target_phys_addr_t)-1) { /* Unregister previous mapping. */ - cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size, - IO_MEM_UNASSIGNED); + if (dev->mmio[n].memory) { + memory_region_del_subregion(get_system_memory(), + dev->mmio[n].memory); + } else if (dev->mmio[n].unmap) { + dev->mmio[n].unmap(dev, dev->mmio[n].addr); + } else { + cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size, + IO_MEM_UNASSIGNED); + } } dev->mmio[n].addr = addr; - if (dev->mmio[n].cb) { + if (dev->mmio[n].memory) { + memory_region_add_subregion(get_system_memory(), + addr, + dev->mmio[n].memory); + } else if (dev->mmio[n].cb) { dev->mmio[n].cb(dev, addr); } else { cpu_register_physical_memory(addr, dev->mmio[n].size, @@ -96,16 +107,33 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, dev->mmio[n].iofunc = iofunc; } -void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, - mmio_mapfunc cb) +void sysbus_init_mmio_cb2(SysBusDevice *dev, + mmio_mapfunc cb, mmio_mapfunc unmap) { int n; assert(dev->num_mmio < QDEV_MAX_MMIO); n = dev->num_mmio++; dev->mmio[n].addr = -1; - dev->mmio[n].size = size; + dev->mmio[n].size = 0; dev->mmio[n].cb = cb; + dev->mmio[n].unmap = unmap; +} + +void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory) +{ + int n; + + assert(dev->num_mmio < QDEV_MAX_MMIO); + n = dev->num_mmio++; + dev->mmio[n].addr = -1; + dev->mmio[n].size = memory_region_size(memory); + dev->mmio[n].memory = memory; +} + +MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n) +{ + return dev->mmio[n].memory; } void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) @@ -138,8 +166,8 @@ void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init) { SysBusDeviceInfo *info; - info = qemu_mallocz(sizeof(*info)); - info->qdev.name = qemu_strdup(name); + info = g_malloc0(sizeof(*info)); + info->qdev.name = g_strdup(name); info->qdev.size = size; info->init = init; sysbus_register_withprop(info); @@ -170,6 +198,39 @@ DeviceState *sysbus_create_varargs(const char *name, sysbus_connect_irq(s, n, irq); n++; } + va_end(va); + return dev; +} + +DeviceState *sysbus_try_create_varargs(const char *name, + target_phys_addr_t addr, ...) +{ + DeviceState *dev; + SysBusDevice *s; + va_list va; + qemu_irq irq; + int n; + + dev = qdev_try_create(NULL, name); + if (!dev) { + return NULL; + } + s = sysbus_from_qdev(dev); + qdev_init_nofail(dev); + if (addr != (target_phys_addr_t)-1) { + sysbus_mmio_map(s, 0, addr); + } + va_start(va, addr); + n = 0; + while (1) { + irq = va_arg(va, qemu_irq); + if (!irq) { + break; + } + sysbus_connect_irq(s, n, irq); + n++; + } + va_end(va); return dev; } @@ -178,6 +239,7 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent) SysBusDevice *s = sysbus_from_qdev(dev); int i; + monitor_printf(mon, "%*sirq %d\n", indent, "", s->num_irq); for (i = 0; i < s->num_mmio; i++) { monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", indent, "", s->mmio[i].addr, s->mmio[i].size); @@ -201,3 +263,32 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) return strdup(path); } + +void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr, + MemoryRegion *mem) +{ + memory_region_add_subregion(get_system_memory(), addr, mem); +} + +void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr, + MemoryRegion *mem, unsigned priority) +{ + memory_region_add_subregion_overlap(get_system_memory(), addr, mem, + priority); +} + +void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem) +{ + memory_region_del_subregion(get_system_memory(), mem); +} + +void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr, + MemoryRegion *mem) +{ + memory_region_add_subregion(get_system_io(), addr, mem); +} + +void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem) +{ + memory_region_del_subregion(get_system_io(), mem); +} diff --git a/hw/sysbus.h b/hw/sysbus.h index e9eb618..6c36537 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -4,6 +4,7 @@ /* Devices attached directly to the main system bus. */ #include "qdev.h" +#include "memory.h" #define QDEV_MAX_MMIO 32 #define QDEV_MAX_PIO 32 @@ -22,7 +23,9 @@ struct SysBusDevice { target_phys_addr_t addr; target_phys_addr_t size; mmio_mapfunc cb; + mmio_mapfunc unmap; ram_addr_t iofunc; + MemoryRegion *memory; } mmio[QDEV_MAX_MMIO]; int num_pio; pio_addr_t pio[QDEV_MAX_PIO]; @@ -44,8 +47,10 @@ void sysbus_register_withprop(SysBusDeviceInfo *info); void *sysbus_new(void); void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, ram_addr_t iofunc); -void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, - mmio_mapfunc cb); +void sysbus_init_mmio_cb2(SysBusDevice *dev, + mmio_mapfunc cb, mmio_mapfunc unmap); +void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory); +MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n); void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p); void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target); void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); @@ -53,10 +58,20 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq); void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr); +void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr, + MemoryRegion *mem); +void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr, + MemoryRegion *mem, unsigned priority); +void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem); +void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr, + MemoryRegion *mem); +void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem); /* Legacy helper function for creating devices. */ DeviceState *sysbus_create_varargs(const char *name, target_phys_addr_t addr, ...); +DeviceState *sysbus_try_create_varargs(const char *name, + target_phys_addr_t addr, ...); static inline DeviceState *sysbus_create_simple(const char *name, target_phys_addr_t addr, qemu_irq irq) @@ -64,4 +79,11 @@ static inline DeviceState *sysbus_create_simple(const char *name, return sysbus_create_varargs(name, addr, irq, NULL); } +static inline DeviceState *sysbus_try_create_simple(const char *name, + target_phys_addr_t addr, + qemu_irq irq) +{ + return sysbus_try_create_varargs(name, addr, irq, NULL); +} + #endif /* !HW_SYSBUS_H */ diff --git a/hw/tc58128.c b/hw/tc58128.c index 672a01c..4ce80b1 100644 --- a/hw/tc58128.c +++ b/hw/tc58128.c @@ -1,6 +1,5 @@ #include "hw.h" #include "sh.h" -#include "sysemu.h" #include "loader.h" #define CE1 0x0100 @@ -31,12 +30,8 @@ static void init_dev(tc58128_dev * dev, const char *filename) int ret, blocks; dev->state = WAIT; - dev->flash_contents = qemu_mallocz(FLASH_SIZE); + dev->flash_contents = g_malloc(FLASH_SIZE); memset(dev->flash_contents, 0xff, FLASH_SIZE); - if (!dev->flash_contents) { - fprintf(stderr, "could not alloc memory for flash\n"); - exit(1); - } if (filename) { /* Load flash image skipping the first block */ ret = load_image(filename, dev->flash_contents + 528 * 32); diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c index c3fbe4e..c144dcf 100644 --- a/hw/tc6393xb.c +++ b/hw/tc6393xb.c @@ -8,11 +8,11 @@ * This code is licensed under the GNU GPL v2. */ #include "hw.h" -#include "pxa.h" #include "devices.h" #include "flash.h" #include "console.h" #include "pixel_ops.h" +#include "blockdev.h" #define IRQ_TC6393_NAND 0 #define IRQ_TC6393_MMC 1 @@ -79,6 +79,7 @@ #define NAND_MODE_ECC_RST 0x60 struct TC6393xbState { + MemoryRegion iomem; qemu_irq irq; qemu_irq *sub_irqs; struct { @@ -118,11 +119,11 @@ struct TC6393xbState { } nand; int nand_enable; uint32_t nand_phys; - NANDFlashState *flash; + DeviceState *flash; ECCState ecc; DisplayState *ds; - ram_addr_t vram_addr; + MemoryRegion vram; uint16_t *vram_ptr; uint32_t scr_width, scr_height; /* in pixels */ qemu_irq l3v; @@ -381,7 +382,7 @@ static void tc6393xb_nand_writeb(TC6393xbState *s, target_phys_addr_t addr, uint case NAND_DATA + 2: case NAND_DATA + 3: nand_setio(s->flash, value); - s->nand.isr &= 1; + s->nand.isr |= 1; tc6393xb_nand_irq(s); return; case NAND_MODE: @@ -495,7 +496,9 @@ static void tc6393xb_update_display(void *opaque) } -static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { +static uint64_t tc6393xb_readb(void *opaque, target_phys_addr_t addr, + unsigned size) +{ TC6393xbState *s = opaque; switch (addr >> 8) { @@ -516,7 +519,8 @@ static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { return 0; } -static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) { +static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, + uint64_t value, unsigned size) { TC6393xbState *s = opaque; switch (addr >> 8) { @@ -532,53 +536,24 @@ static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t valu tc6393xb_nand_writeb(s, addr & 0xff, value); else fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n", - (uint32_t) addr, value & 0xff); -} - -static uint32_t tc6393xb_readw(void *opaque, target_phys_addr_t addr) -{ - return (tc6393xb_readb(opaque, addr) & 0xff) | - (tc6393xb_readb(opaque, addr + 1) << 8); -} - -static uint32_t tc6393xb_readl(void *opaque, target_phys_addr_t addr) -{ - return (tc6393xb_readb(opaque, addr) & 0xff) | - ((tc6393xb_readb(opaque, addr + 1) & 0xff) << 8) | - ((tc6393xb_readb(opaque, addr + 2) & 0xff) << 16) | - ((tc6393xb_readb(opaque, addr + 3) & 0xff) << 24); + (uint32_t) addr, (int)value & 0xff); } -static void tc6393xb_writew(void *opaque, target_phys_addr_t addr, uint32_t value) +TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq) { - tc6393xb_writeb(opaque, addr, value); - tc6393xb_writeb(opaque, addr + 1, value >> 8); -} - -static void tc6393xb_writel(void *opaque, target_phys_addr_t addr, uint32_t value) -{ - tc6393xb_writeb(opaque, addr, value); - tc6393xb_writeb(opaque, addr + 1, value >> 8); - tc6393xb_writeb(opaque, addr + 2, value >> 16); - tc6393xb_writeb(opaque, addr + 3, value >> 24); -} - -TC6393xbState *tc6393xb_init(uint32_t base, qemu_irq irq) -{ - int iomemtype; TC6393xbState *s; - CPUReadMemoryFunc * const tc6393xb_readfn[] = { - tc6393xb_readb, - tc6393xb_readw, - tc6393xb_readl, - }; - CPUWriteMemoryFunc * const tc6393xb_writefn[] = { - tc6393xb_writeb, - tc6393xb_writew, - tc6393xb_writel, + DriveInfo *nand; + static const MemoryRegionOps tc6393xb_ops = { + .read = tc6393xb_readb, + .write = tc6393xb_writeb, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; - s = (TC6393xbState *) qemu_mallocz(sizeof(TC6393xbState)); + s = (TC6393xbState *) g_malloc0(sizeof(TC6393xbState)); s->irq = irq; s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS); @@ -587,15 +562,15 @@ TC6393xbState *tc6393xb_init(uint32_t base, qemu_irq irq) s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS); - s->flash = nand_init(NAND_MFR_TOSHIBA, 0x76); + nand = drive_get(IF_MTD, 0, 0); + s->flash = nand_init(nand ? nand->bdrv : NULL, NAND_MFR_TOSHIBA, 0x76); - iomemtype = cpu_register_io_memory(tc6393xb_readfn, - tc6393xb_writefn, s, DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(base, 0x10000, iomemtype); + memory_region_init_io(&s->iomem, &tc6393xb_ops, s, "tc6393xb", 0x10000); + memory_region_add_subregion(sysmem, base, &s->iomem); - s->vram_addr = qemu_ram_alloc(NULL, "tc6393xb.vram", 0x100000); - s->vram_ptr = qemu_get_ram_ptr(s->vram_addr); - cpu_register_physical_memory(base + 0x100000, 0x100000, s->vram_addr); + memory_region_init_ram(&s->vram, NULL, "tc6393xb.vram", 0x100000); + s->vram_ptr = memory_region_get_ram_ptr(&s->vram); + memory_region_add_subregion(sysmem, base + 0x100000, &s->vram); s->scr_width = 480; s->scr_height = 640; s->ds = graphic_console_init(tc6393xb_update_display, diff --git a/hw/tcx.c b/hw/tcx.c index 0e32830..cd24100 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -40,11 +40,19 @@ typedef struct TCXState { DisplayState *ds; uint8_t *vram; uint32_t *vram24, *cplane; - ram_addr_t vram_offset, vram24_offset, cplane_offset; + MemoryRegion vram_mem; + MemoryRegion vram_8bit; + MemoryRegion vram_24bit; + MemoryRegion vram_cplane; + MemoryRegion dac; + MemoryRegion tec; + MemoryRegion thc24; + MemoryRegion thc8; + ram_addr_t vram24_offset, cplane_offset; uint32_t vram_size; - uint16_t width, height, depth; - uint8_t r[256], g[256], b[256]; uint32_t palette[256]; + uint8_t r[256], g[256], b[256]; + uint16_t width, height, depth; uint8_t dac_index, dac_state; } TCXState; @@ -56,7 +64,7 @@ static void tcx_set_dirty(TCXState *s) unsigned int i; for (i = 0; i < MAXX * MAXY; i += TARGET_PAGE_SIZE) { - cpu_physical_memory_set_dirty(s->vram_offset + i); + memory_region_set_dirty(&s->vram_mem, i); } } @@ -65,8 +73,8 @@ static void tcx24_set_dirty(TCXState *s) unsigned int i; for (i = 0; i < MAXX * MAXY * 4; i += TARGET_PAGE_SIZE) { - cpu_physical_memory_set_dirty(s->vram24_offset + i); - cpu_physical_memory_set_dirty(s->cplane_offset + i); + memory_region_set_dirty(&s->vram_mem, s->vram24_offset + i); + memory_region_set_dirty(&s->vram_mem, s->cplane_offset + i); } } @@ -174,16 +182,18 @@ static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d, } } -static inline int check_dirty(ram_addr_t page, ram_addr_t page24, +static inline int check_dirty(TCXState *s, ram_addr_t page, ram_addr_t page24, ram_addr_t cpage) { int ret; unsigned int off; - ret = cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG); + ret = memory_region_get_dirty(&s->vram_mem, page, DIRTY_MEMORY_VGA); for (off = 0; off < TARGET_PAGE_SIZE * 4; off += TARGET_PAGE_SIZE) { - ret |= cpu_physical_memory_get_dirty(page24 + off, VGA_DIRTY_FLAG); - ret |= cpu_physical_memory_get_dirty(cpage + off, VGA_DIRTY_FLAG); + ret |= memory_region_get_dirty(&s->vram_mem, page24 + off, + DIRTY_MEMORY_VGA); + ret |= memory_region_get_dirty(&s->vram_mem, cpage + off, + DIRTY_MEMORY_VGA); } return ret; } @@ -192,16 +202,17 @@ static inline void reset_dirty(TCXState *ts, ram_addr_t page_min, ram_addr_t page_max, ram_addr_t page24, ram_addr_t cpage) { - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); - page_min -= ts->vram_offset; - page_max -= ts->vram_offset; - cpu_physical_memory_reset_dirty(page24 + page_min * 4, - page24 + page_max * 4 + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); - cpu_physical_memory_reset_dirty(cpage + page_min * 4, - cpage + page_max * 4 + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); + memory_region_reset_dirty(&ts->vram_mem, + page_min, page_max + TARGET_PAGE_SIZE, + DIRTY_MEMORY_VGA); + memory_region_reset_dirty(&ts->vram_mem, + page24 + page_min * 4, + page24 + page_max * 4 + TARGET_PAGE_SIZE, + DIRTY_MEMORY_VGA); + memory_region_reset_dirty(&ts->vram_mem, + cpage + page_min * 4, + cpage + page_max * 4 + TARGET_PAGE_SIZE, + DIRTY_MEMORY_VGA); } /* Fixed line length 1024 allows us to do nice tricks not possible on @@ -216,7 +227,7 @@ static void tcx_update_display(void *opaque) if (ds_get_bits_per_pixel(ts->ds) == 0) return; - page = ts->vram_offset; + page = 0; y_start = -1; page_min = -1; page_max = 0; @@ -242,7 +253,7 @@ static void tcx_update_display(void *opaque) } for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) { - if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) { + if (memory_region_get_dirty(&ts->vram_mem, page, DIRTY_MEMORY_VGA)) { if (y_start < 0) y_start = y; if (page < page_min) @@ -279,8 +290,9 @@ static void tcx_update_display(void *opaque) } /* reset modified pages */ if (page_max >= page_min) { - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); + memory_region_reset_dirty(&ts->vram_mem, + page_min, page_max + TARGET_PAGE_SIZE, + DIRTY_MEMORY_VGA); } } @@ -294,7 +306,7 @@ static void tcx24_update_display(void *opaque) if (ds_get_bits_per_pixel(ts->ds) != 32) return; - page = ts->vram_offset; + page = 0; page24 = ts->vram24_offset; cpage = ts->cplane_offset; y_start = -1; @@ -309,7 +321,7 @@ static void tcx24_update_display(void *opaque) for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE, page24 += TARGET_PAGE_SIZE, cpage += TARGET_PAGE_SIZE) { - if (check_dirty(page, page24, cpage)) { + if (check_dirty(ts, page, page24, cpage)) { if (y_start < 0) y_start = y; if (page < page_min) @@ -421,18 +433,20 @@ static void tcx_reset(DeviceState *d) s->r[255] = s->g[255] = s->b[255] = 255; update_palette_entries(s, 0, 256); memset(s->vram, 0, MAXX*MAXY); - cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + - MAXX * MAXY * (1 + 4 + 4), VGA_DIRTY_FLAG); + memory_region_reset_dirty(&s->vram_mem, 0, MAXX * MAXY * (1 + 4 + 4), + DIRTY_MEMORY_VGA); s->dac_index = 0; s->dac_state = 0; } -static uint32_t tcx_dac_readl(void *opaque, target_phys_addr_t addr) +static uint64_t tcx_dac_readl(void *opaque, target_phys_addr_t addr, + unsigned size) { return 0; } -static void tcx_dac_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +static void tcx_dac_writel(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) { TCXState *s = opaque; @@ -468,77 +482,77 @@ static void tcx_dac_writel(void *opaque, target_phys_addr_t addr, uint32_t val) return; } -static CPUReadMemoryFunc * const tcx_dac_read[3] = { - NULL, - NULL, - tcx_dac_readl, +static const MemoryRegionOps tcx_dac_ops = { + .read = tcx_dac_readl, + .write = tcx_dac_writel, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; -static CPUWriteMemoryFunc * const tcx_dac_write[3] = { - NULL, - NULL, - tcx_dac_writel, -}; - -static uint32_t tcx_dummy_readl(void *opaque, target_phys_addr_t addr) +static uint64_t dummy_readl(void *opaque, target_phys_addr_t addr, + unsigned size) { return 0; } -static void tcx_dummy_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void dummy_writel(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { } -static CPUReadMemoryFunc * const tcx_dummy_read[3] = { - NULL, - NULL, - tcx_dummy_readl, -}; - -static CPUWriteMemoryFunc * const tcx_dummy_write[3] = { - NULL, - NULL, - tcx_dummy_writel, +static const MemoryRegionOps dummy_ops = { + .read = dummy_readl, + .write = dummy_writel, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, }; static int tcx_init1(SysBusDevice *dev) { TCXState *s = FROM_SYSBUS(TCXState, dev); - int io_memory, dummy_memory; - ram_addr_t vram_offset; + ram_addr_t vram_offset = 0; int size; uint8_t *vram_base; - vram_offset = qemu_ram_alloc(NULL, "tcx.vram", s->vram_size * (1 + 4 + 4)); - vram_base = qemu_get_ram_ptr(vram_offset); - s->vram_offset = vram_offset; + memory_region_init_ram(&s->vram_mem, NULL, "tcx.vram", + s->vram_size * (1 + 4 + 4)); + vram_base = memory_region_get_ram_ptr(&s->vram_mem); /* 8-bit plane */ s->vram = vram_base; size = s->vram_size; - sysbus_init_mmio(dev, size, s->vram_offset); + memory_region_init_alias(&s->vram_8bit, "tcx.vram.8bit", + &s->vram_mem, vram_offset, size); + sysbus_init_mmio_region(dev, &s->vram_8bit); vram_offset += size; vram_base += size; /* DAC */ - io_memory = cpu_register_io_memory(tcx_dac_read, tcx_dac_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, TCX_DAC_NREGS, io_memory); + memory_region_init_io(&s->dac, &tcx_dac_ops, s, "tcx.dac", TCX_DAC_NREGS); + sysbus_init_mmio_region(dev, &s->dac); /* TEC (dummy) */ - dummy_memory = cpu_register_io_memory(tcx_dummy_read, tcx_dummy_write, - s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, TCX_TEC_NREGS, dummy_memory); + memory_region_init_io(&s->tec, &dummy_ops, s, "tcx.tec", TCX_TEC_NREGS); + sysbus_init_mmio_region(dev, &s->tec); /* THC: NetBSD writes here even with 8-bit display: dummy */ - sysbus_init_mmio(dev, TCX_THC_NREGS_24, dummy_memory); + memory_region_init_io(&s->thc24, &dummy_ops, s, "tcx.thc24", + TCX_THC_NREGS_24); + sysbus_init_mmio_region(dev, &s->thc24); if (s->depth == 24) { /* 24-bit plane */ size = s->vram_size * 4; s->vram24 = (uint32_t *)vram_base; s->vram24_offset = vram_offset; - sysbus_init_mmio(dev, size, vram_offset); + memory_region_init_alias(&s->vram_24bit, "tcx.vram.24bit", + &s->vram_mem, vram_offset, size); + sysbus_init_mmio_region(dev, &s->vram_24bit); vram_offset += size; vram_base += size; @@ -546,14 +560,18 @@ static int tcx_init1(SysBusDevice *dev) size = s->vram_size * 4; s->cplane = (uint32_t *)vram_base; s->cplane_offset = vram_offset; - sysbus_init_mmio(dev, size, vram_offset); + memory_region_init_alias(&s->vram_cplane, "tcx.vram.cplane", + &s->vram_mem, vram_offset, size); + sysbus_init_mmio_region(dev, &s->vram_cplane); s->ds = graphic_console_init(tcx24_update_display, tcx24_invalidate_display, tcx24_screen_dump, NULL, s); } else { /* THC 8 bit (dummy) */ - sysbus_init_mmio(dev, TCX_THC_NREGS_8, dummy_memory); + memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8", + TCX_THC_NREGS_8); + sysbus_init_mmio_region(dev, &s->thc8); s->ds = graphic_console_init(tcx_update_display, tcx_invalidate_display, diff --git a/hw/tosa.c b/hw/tosa.c index 0bfab16..b992b99 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -11,7 +11,6 @@ #include "hw.h" #include "pxa.h" #include "arm-misc.h" -#include "sysemu.h" #include "devices.h" #include "sharpsl.h" #include "pcmcia.h" @@ -21,10 +20,12 @@ #include "ssi.h" #include "blockdev.h" #include "sysbus.h" +#include "exec-memory.h" #define TOSA_RAM 0x04000000 #define TOSA_ROM 0x00800000 +#define TOSA_GPIO_USB_IN (5) #define TOSA_GPIO_nSD_DETECT (9) #define TOSA_GPIO_ON_RESET (19) #define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */ @@ -51,17 +52,13 @@ static void tosa_microdrive_attach(PXA2xxState *cpu) { PCMCIACardState *md; - BlockDriverState *bs; DriveInfo *dinfo; dinfo = drive_get(IF_IDE, 0, 0); - if (!dinfo) + if (!dinfo || dinfo->media_cd) return; - bs = dinfo->bdrv; - if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) { - md = dscm1xxxx_init(dinfo); - pxa2xx_pcmcia_attach(cpu->pcmcia[0], md); - } + md = dscm1xxxx_init(dinfo); + pxa2xx_pcmcia_attach(cpu->pcmcia[0], md); } static void tosa_out_switch(void *opaque, int line, int level) @@ -115,6 +112,9 @@ static void tosa_gpio_setup(PXA2xxState *cpu, qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]); qdev_connect_gpio_out(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio)); + + /* UDC Vbus */ + qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_USB_IN)); } static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value) @@ -207,6 +207,7 @@ static void tosa_init(ram_addr_t ram_size, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { + MemoryRegion *address_space_mem = get_system_memory(); PXA2xxState *cpu; TC6393xbState *tmio; DeviceState *scp0, *scp1; @@ -214,12 +215,12 @@ static void tosa_init(ram_addr_t ram_size, if (!cpu_model) cpu_model = "pxa255"; - cpu = pxa255_init(tosa_binfo.ram_size); + cpu = pxa255_init(address_space_mem, tosa_binfo.ram_size); cpu_register_physical_memory(0, TOSA_ROM, qemu_ram_alloc(NULL, "tosa.rom", TOSA_ROM) | IO_MEM_ROM); - tmio = tc6393xb_init(0x10000000, + tmio = tc6393xb_init(address_space_mem, 0x10000000, qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_TC6393XB_INT)); scp0 = sysbus_create_simple("scoop", 0x08800000, NULL); diff --git a/hw/tsc2005.c b/hw/tsc2005.c index a55853c..9a500eb 100644 --- a/hw/tsc2005.c +++ b/hw/tsc2005.c @@ -290,7 +290,7 @@ static void tsc2005_pin_update(TSC2005State *s) s->precision = s->nextprecision; s->function = s->nextfunction; s->pdst = !s->pnd0; /* Synchronised on internal clock */ - expires = qemu_get_clock(vm_clock) + (get_ticks_per_sec() >> 7); + expires = qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() >> 7); qemu_mod_timer(s->timer, expires); } @@ -524,12 +524,12 @@ void *tsc2005_init(qemu_irq pintdav) TSC2005State *s; s = (TSC2005State *) - qemu_mallocz(sizeof(TSC2005State)); + g_malloc0(sizeof(TSC2005State)); s->x = 400; s->y = 240; s->pressure = 0; s->precision = s->nextprecision = 0; - s->timer = qemu_new_timer(vm_clock, tsc2005_timer_tick, s); + s->timer = qemu_new_timer_ns(vm_clock, tsc2005_timer_tick, s); s->pint = pintdav; s->model = 0x2005; diff --git a/hw/tsc210x.c b/hw/tsc210x.c index fca73f1..3c448a6 100644 --- a/hw/tsc210x.c +++ b/hw/tsc210x.c @@ -503,9 +503,9 @@ static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg) l_ch = 1; r_ch = 1; if (s->softstep && !(s->dac_power & (1 << 10))) { - l_ch = (qemu_get_clock(vm_clock) > + l_ch = (qemu_get_clock_ns(vm_clock) > s->volume_change + TSC_SOFTSTEP_DELAY); - r_ch = (qemu_get_clock(vm_clock) > + r_ch = (qemu_get_clock_ns(vm_clock) > s->volume_change + TSC_SOFTSTEP_DELAY); } @@ -514,7 +514,7 @@ static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg) case 0x05: /* Stereo DAC Power Control */ return 0x2aa0 | s->dac_power | (((s->dac_power & (1 << 10)) && - (qemu_get_clock(vm_clock) > + (qemu_get_clock_ns(vm_clock) > s->powerdown + TSC_POWEROFF_DELAY)) << 6); case 0x06: /* Audio Control 3 */ @@ -695,7 +695,7 @@ static void tsc2102_audio_register_write( case 0x02: /* DAC Volume Control */ s->volume = value; - s->volume_change = qemu_get_clock(vm_clock); + s->volume_change = qemu_get_clock_ns(vm_clock); return; case 0x03: @@ -717,7 +717,7 @@ static void tsc2102_audio_register_write( case 0x05: /* Stereo DAC Power Control */ if ((value & ~s->dac_power) & (1 << 10)) - s->powerdown = qemu_get_clock(vm_clock); + s->powerdown = qemu_get_clock_ns(vm_clock); s->dac_power = value & 0x9543; #ifdef TSC_VERBOSE @@ -864,7 +864,7 @@ static void tsc210x_pin_update(TSC210xState *s) s->busy = 1; s->precision = s->nextprecision; s->function = s->nextfunction; - expires = qemu_get_clock(vm_clock) + (get_ticks_per_sec() >> 10); + expires = qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() >> 10); qemu_mod_timer(s->timer, expires); } @@ -1005,7 +1005,7 @@ static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out) static void tsc210x_save(QEMUFile *f, void *opaque) { TSC210xState *s = (TSC210xState *) opaque; - int64_t now = qemu_get_clock(vm_clock); + int64_t now = qemu_get_clock_ns(vm_clock); int i; qemu_put_be16(f, s->x); @@ -1051,7 +1051,7 @@ static void tsc210x_save(QEMUFile *f, void *opaque) static int tsc210x_load(QEMUFile *f, void *opaque, int version_id) { TSC210xState *s = (TSC210xState *) opaque; - int64_t now = qemu_get_clock(vm_clock); + int64_t now = qemu_get_clock_ns(vm_clock); int i; s->x = qemu_get_be16(f); @@ -1105,13 +1105,13 @@ uWireSlave *tsc2102_init(qemu_irq pint) TSC210xState *s; s = (TSC210xState *) - qemu_mallocz(sizeof(TSC210xState)); + g_malloc0(sizeof(TSC210xState)); memset(s, 0, sizeof(TSC210xState)); s->x = 160; s->y = 160; s->pressure = 0; s->precision = s->nextprecision = 0; - s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s); + s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s); s->pint = pint; s->model = 0x2102; s->name = "tsc2102"; @@ -1154,13 +1154,13 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav) TSC210xState *s; s = (TSC210xState *) - qemu_mallocz(sizeof(TSC210xState)); + g_malloc0(sizeof(TSC210xState)); memset(s, 0, sizeof(TSC210xState)); s->x = 400; s->y = 240; s->pressure = 0; s->precision = s->nextprecision = 0; - s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s); + s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s); s->pint = penirq; s->kbint = kbirq; s->davint = dav; diff --git a/hw/tusb6010.c b/hw/tusb6010.c index 0005e1c..ce7c81f 100644 --- a/hw/tusb6010.c +++ b/hw/tusb6010.c @@ -24,9 +24,11 @@ #include "omap.h" #include "irq.h" #include "devices.h" +#include "sysbus.h" -struct TUSBState { - int iomemtype[2]; +typedef struct TUSBState { + SysBusDevice busdev; + MemoryRegion iomem[2]; qemu_irq irq; MUSBState *musb; QEMUTimer *otg_timer; @@ -59,7 +61,7 @@ struct TUSBState { uint32_t pullup[2]; uint32_t control_config; uint32_t otg_timer_val; -}; +} TUSBState; #define TUSB_DEVCLOCK 60000000 /* 60 MHz */ @@ -234,16 +236,6 @@ struct TUSBState { #define TUSB_EP_CONFIG_XFR_SIZE(v) ((v) & 0x7fffffff) #define TUSB_PROD_TEST_RESET_VAL 0xa596 -int tusb6010_sync_io(TUSBState *s) -{ - return s->iomemtype[0]; -} - -int tusb6010_async_io(TUSBState *s) -{ - return s->iomemtype[1]; -} - static void tusb_intr_update(TUSBState *s) { if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY) @@ -520,7 +512,7 @@ static void tusb_async_writew(void *opaque, target_phys_addr_t addr, case TUSB_DEV_OTG_TIMER: s->otg_timer_val = value; if (value & TUSB_DEV_OTG_TIMER_ENABLE) - qemu_mod_timer(s->otg_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(s->otg_timer, qemu_get_clock_ns(vm_clock) + muldiv64(TUSB_DEV_OTG_TIMER_VAL(value), get_ticks_per_sec(), TUSB_DEVCLOCK)); else @@ -647,16 +639,12 @@ static void tusb_async_writew(void *opaque, target_phys_addr_t addr, } } -static CPUReadMemoryFunc * const tusb_async_readfn[] = { - tusb_async_readb, - tusb_async_readh, - tusb_async_readw, -}; - -static CPUWriteMemoryFunc * const tusb_async_writefn[] = { - tusb_async_writeb, - tusb_async_writeh, - tusb_async_writew, +static const MemoryRegionOps tusb_async_ops = { + .old_mmio = { + .read = { tusb_async_readb, tusb_async_readh, tusb_async_readw, }, + .write = { tusb_async_writeb, tusb_async_writeh, tusb_async_writew, }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void tusb_otg_tick(void *opaque) @@ -727,9 +715,33 @@ static void tusb_musb_core_intr(void *opaque, int source, int level) } } -TUSBState *tusb6010_init(qemu_irq intr) +static void tusb6010_power(TUSBState *s, int on) { - TUSBState *s = qemu_mallocz(sizeof(*s)); + if (!on) { + s->power = 0; + } else if (!s->power && on) { + s->power = 1; + /* Pull the interrupt down after TUSB6010 comes up. */ + s->intr_ok = 0; + tusb_intr_update(s); + qemu_mod_timer(s->pwr_timer, + qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2); + } +} + +static void tusb6010_irq(void *opaque, int source, int level) +{ + if (source) { + tusb_musb_core_intr(opaque, source - 1, level); + } else { + tusb6010_power(opaque, level); + } +} + +static void tusb6010_reset(DeviceState *dev) +{ + TUSBState *s = FROM_SYSBUS(TUSBState, sysbus_from_qdev(dev)); + int i; s->test_reset = TUSB_PROD_TEST_RESET_VAL; s->host_mode = 0; @@ -739,28 +751,54 @@ TUSBState *tusb6010_init(qemu_irq intr) s->mask = 0xffffffff; s->intr = 0x00000000; s->otg_timer_val = 0; - s->iomemtype[1] = cpu_register_io_memory(tusb_async_readfn, - tusb_async_writefn, s, DEVICE_NATIVE_ENDIAN); - s->irq = intr; - s->otg_timer = qemu_new_timer(vm_clock, tusb_otg_tick, s); - s->pwr_timer = qemu_new_timer(vm_clock, tusb_power_tick, s); - s->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s, - __musb_irq_max)); - - return s; + s->scratch = 0; + s->prcm_config = 0; + s->prcm_mngmt = 0; + s->intr_ok = 0; + s->usbip_intr = 0; + s->usbip_mask = 0; + s->gpio_intr = 0; + s->gpio_mask = 0; + s->gpio_config = 0; + s->dma_intr = 0; + s->dma_mask = 0; + s->dma_map = 0; + s->dma_config = 0; + s->ep0_config = 0; + s->wkup_mask = 0; + s->pullup[0] = s->pullup[1] = 0; + s->control_config = 0; + for (i = 0; i < 15; i++) { + s->rx_config[i] = s->tx_config[i] = 0; + } + musb_reset(s->musb); } -void tusb6010_power(TUSBState *s, int on) +static int tusb6010_init(SysBusDevice *dev) { - if (!on) - s->power = 0; - else if (!s->power && on) { - s->power = 1; + TUSBState *s = FROM_SYSBUS(TUSBState, dev); + s->otg_timer = qemu_new_timer_ns(vm_clock, tusb_otg_tick, s); + s->pwr_timer = qemu_new_timer_ns(vm_clock, tusb_power_tick, s); + memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async", + UINT32_MAX); + sysbus_init_mmio_region(dev, &s->iomem[0]); + sysbus_init_mmio_region(dev, &s->iomem[1]); + sysbus_init_irq(dev, &s->irq); + qdev_init_gpio_in(&dev->qdev, tusb6010_irq, musb_irq_max + 1); + s->musb = musb_init(&dev->qdev, 1); + return 0; +} - /* Pull the interrupt down after TUSB6010 comes up. */ - s->intr_ok = 0; - tusb_intr_update(s); - qemu_mod_timer(s->pwr_timer, - qemu_get_clock(vm_clock) + get_ticks_per_sec() / 2); - } +static SysBusDeviceInfo tusb6010_info = { + .init = tusb6010_init, + .qdev.name = "tusb6010", + .qdev.size = sizeof(TUSBState), + .qdev.reset = tusb6010_reset, +}; + +static void tusb6010_register_device(void) +{ + sysbus_register_withprop(&tusb6010_info); } + +device_init(tusb6010_register_device) diff --git a/hw/twl92230.c b/hw/twl92230.c index e61f17f..a75448f 100644 --- a/hw/twl92230.c +++ b/hw/twl92230.c @@ -22,7 +22,6 @@ #include "hw.h" #include "qemu-timer.h" #include "i2c.h" -#include "sysemu.h" #include "console.h" #define VERBOSE 1 @@ -74,14 +73,14 @@ static inline void menelaus_update(MenelausState *s) static inline void menelaus_rtc_start(MenelausState *s) { - s->rtc.next += qemu_get_clock(rt_clock); + s->rtc.next += qemu_get_clock_ms(rt_clock); qemu_mod_timer(s->rtc.hz_tm, s->rtc.next); } static inline void menelaus_rtc_stop(MenelausState *s) { qemu_del_timer(s->rtc.hz_tm); - s->rtc.next -= qemu_get_clock(rt_clock); + s->rtc.next -= qemu_get_clock_ms(rt_clock); if (s->rtc.next < 1) s->rtc.next = 1; } @@ -786,7 +785,7 @@ static void menelaus_pre_save(void *opaque) { MenelausState *s = opaque; /* Should be <= 1000 */ - s->rtc_next_vmstate = s->rtc.next - qemu_get_clock(rt_clock); + s->rtc_next_vmstate = s->rtc.next - qemu_get_clock_ms(rt_clock); } static int menelaus_post_load(void *opaque, int version_id) @@ -847,7 +846,7 @@ static int twl92230_init(i2c_slave *i2c) { MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c); - s->rtc.hz_tm = qemu_new_timer(rt_clock, menelaus_rtc_hz, s); + s->rtc.hz_tm = qemu_new_timer_ms(rt_clock, menelaus_rtc_hz, s); /* Three output pins plus one interrupt pin. */ qdev_init_gpio_out(&i2c->qdev, s->out, 4); qdev_init_gpio_in(&i2c->qdev, menelaus_gpio_set, 3); diff --git a/hw/unin_pci.c b/hw/unin_pci.c index 5f15058..4299052 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -41,7 +41,8 @@ static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e }; typedef struct UNINState { SysBusDevice busdev; PCIHostState host_state; - ReadWriteHandler data_handler; + MemoryRegion pci_mmio; + MemoryRegion pci_hole; } UNINState; static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) @@ -63,23 +64,6 @@ static void pci_unin_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[unin_irq_line[irq_num]], level); } -static void pci_unin_save(QEMUFile* f, void *opaque) -{ - PCIDevice *d = opaque; - - pci_device_save(d, f); -} - -static int pci_unin_load(QEMUFile* f, void *opaque, int version_id) -{ - PCIDevice *d = opaque; - - if (version_id != 1) - return -EINVAL; - - return pci_device_load(d, f); -} - static void pci_unin_reset(void *opaque) { } @@ -117,72 +101,71 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) return retval; } -static void unin_data_write(ReadWriteHandler *handler, - pcibus_t addr, uint32_t val, int len) +static void unin_data_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned len) { - UNINState *s = container_of(handler, UNINState, data_handler); - UNIN_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val); + UNINState *s = opaque; + UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n", + addr, len, val); pci_data_write(s->host_state.bus, unin_get_config_reg(s->host_state.config_reg, addr), val, len); } -static uint32_t unin_data_read(ReadWriteHandler *handler, - pcibus_t addr, int len) +static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr, + unsigned len) { - UNINState *s = container_of(handler, UNINState, data_handler); + UNINState *s = opaque; uint32_t val; val = pci_data_read(s->host_state.bus, unin_get_config_reg(s->host_state.config_reg, addr), len); - UNIN_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val); + UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n", + addr, len, val); return val; } +static const MemoryRegionOps unin_data_ops = { + .read = unin_data_read, + .write = unin_data_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + static int pci_unin_main_init_device(SysBusDevice *dev) { UNINState *s; - int pci_mem_config, pci_mem_data; /* Use values found on a real PowerMac */ /* Uninorth main bus */ s = FROM_SYSBUS(UNINState, dev); - pci_mem_config = pci_host_conf_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - s->data_handler.read = unin_data_read; - s->data_handler.write = unin_data_write; - pci_mem_data = cpu_register_io_memory_simple(&s->data_handler, - DEVICE_LITTLE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, pci_mem_config); - sysbus_init_mmio(dev, 0x1000, pci_mem_data); - - register_savevm(&dev->qdev, "uninorth", 0, 1, - pci_unin_save, pci_unin_load, &s->host_state); + memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, + &s->host_state, "pci-conf-idx", 0x1000); + memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s, + "pci-conf-data", 0x1000); + sysbus_init_mmio_region(dev, &s->host_state.conf_mem); + sysbus_init_mmio_region(dev, &s->host_state.data_mem); + qemu_register_reset(pci_unin_reset, &s->host_state); return 0; } + static int pci_u3_agp_init_device(SysBusDevice *dev) { UNINState *s; - int pci_mem_config, pci_mem_data; /* Uninorth U3 AGP bus */ s = FROM_SYSBUS(UNINState, dev); - pci_mem_config = pci_host_conf_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - s->data_handler.read = unin_data_read; - s->data_handler.write = unin_data_write; - pci_mem_data = cpu_register_io_memory_simple(&s->data_handler, - DEVICE_LITTLE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, pci_mem_config); - sysbus_init_mmio(dev, 0x1000, pci_mem_data); - - register_savevm(&dev->qdev, "uninorth", 0, 1, - pci_unin_save, pci_unin_load, &s->host_state); + memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, + &s->host_state, "pci-conf-idx", 0x1000); + memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s, + "pci-conf-data", 0x1000); + sysbus_init_mmio_region(dev, &s->host_state.conf_mem); + sysbus_init_mmio_region(dev, &s->host_state.data_mem); + qemu_register_reset(pci_unin_reset, &s->host_state); return 0; @@ -191,38 +174,38 @@ static int pci_u3_agp_init_device(SysBusDevice *dev) static int pci_unin_agp_init_device(SysBusDevice *dev) { UNINState *s; - int pci_mem_config, pci_mem_data; /* Uninorth AGP bus */ s = FROM_SYSBUS(UNINState, dev); - pci_mem_config = pci_host_conf_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - pci_mem_data = pci_host_data_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, pci_mem_config); - sysbus_init_mmio(dev, 0x1000, pci_mem_data); + memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, + &s->host_state, "pci-conf-idx", 0x1000); + memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, + &s->host_state, "pci-conf-data", 0x1000); + sysbus_init_mmio_region(dev, &s->host_state.conf_mem); + sysbus_init_mmio_region(dev, &s->host_state.data_mem); return 0; } static int pci_unin_internal_init_device(SysBusDevice *dev) { UNINState *s; - int pci_mem_config, pci_mem_data; /* Uninorth internal bus */ s = FROM_SYSBUS(UNINState, dev); - pci_mem_config = pci_host_conf_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - pci_mem_data = pci_host_data_register_mmio(&s->host_state, - DEVICE_LITTLE_ENDIAN); - sysbus_init_mmio(dev, 0x1000, pci_mem_config); - sysbus_init_mmio(dev, 0x1000, pci_mem_data); + memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops, + &s->host_state, "pci-conf-idx", 0x1000); + memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops, + &s->host_state, "pci-conf-data", 0x1000); + sysbus_init_mmio_region(dev, &s->host_state.conf_mem); + sysbus_init_mmio_region(dev, &s->host_state.data_mem); return 0; } -PCIBus *pci_pmac_init(qemu_irq *pic) +PCIBus *pci_pmac_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -234,9 +217,18 @@ PCIBus *pci_pmac_init(qemu_irq *pic) qdev_init_nofail(dev); s = sysbus_from_qdev(dev); d = FROM_SYSBUS(UNINState, s); + memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL); + memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio, + 0x80000000ULL, 0x70000000ULL); + memory_region_add_subregion(address_space_mem, 0x80000000ULL, + &d->pci_hole); + d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_unin_set_irq, pci_unin_map_irq, - pic, PCI_DEVFN(11, 0), 4); + pic, + &d->pci_mmio, + address_space_io, + PCI_DEVFN(11, 0), 4); #if 0 pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north"); @@ -273,7 +265,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic) return d->host_state.bus; } -PCIBus *pci_pmac_u3_init(qemu_irq *pic) +PCIBus *pci_pmac_u3_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -286,9 +280,18 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic) s = sysbus_from_qdev(dev); d = FROM_SYSBUS(UNINState, s); + memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL); + memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio, + 0x80000000ULL, 0x70000000ULL); + memory_region_add_subregion(address_space_mem, 0x80000000ULL, + &d->pci_hole); + d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_unin_set_irq, pci_unin_map_irq, - pic, PCI_DEVFN(11, 0), 4); + pic, + &d->pci_mmio, + address_space_io, + PCI_DEVFN(11, 0), 4); sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); @@ -300,10 +303,6 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic) static int unin_main_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_PCI); - d->config[0x08] = 0x00; // revision - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer d->config[0x34] = 0x00; // capabilities_pointer @@ -312,10 +311,6 @@ static int unin_main_pci_host_init(PCIDevice *d) static int unin_agp_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP); - d->config[0x08] = 0x00; // revision - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer // d->config[0x34] = 0x80; // capabilities_pointer @@ -324,11 +319,6 @@ static int unin_agp_pci_host_init(PCIDevice *d) static int u3_agp_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_U3_AGP); - /* revision */ - d->config[0x08] = 0x00; - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); /* cache line size */ d->config[0x0C] = 0x08; /* latency timer */ @@ -338,10 +328,6 @@ static int u3_agp_pci_host_init(PCIDevice *d) static int unin_internal_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI); - d->config[0x08] = 0x00; // revision - pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST); d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer d->config[0x34] = 0x00; // capabilities_pointer @@ -352,24 +338,40 @@ static PCIDeviceInfo unin_main_pci_host_info = { .qdev.name = "uni-north", .qdev.size = sizeof(PCIDevice), .init = unin_main_pci_host_init, + .vendor_id = PCI_VENDOR_ID_APPLE, + .device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI, + .revision = 0x00, + .class_id = PCI_CLASS_BRIDGE_HOST, }; static PCIDeviceInfo u3_agp_pci_host_info = { .qdev.name = "u3-agp", .qdev.size = sizeof(PCIDevice), .init = u3_agp_pci_host_init, + .vendor_id = PCI_VENDOR_ID_APPLE, + .device_id = PCI_DEVICE_ID_APPLE_U3_AGP, + .revision = 0x00, + .class_id = PCI_CLASS_BRIDGE_HOST, }; static PCIDeviceInfo unin_agp_pci_host_info = { .qdev.name = "uni-north-agp", .qdev.size = sizeof(PCIDevice), .init = unin_agp_pci_host_init, + .vendor_id = PCI_VENDOR_ID_APPLE, + .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP, + .revision = 0x00, + .class_id = PCI_CLASS_BRIDGE_HOST, }; static PCIDeviceInfo unin_internal_pci_host_info = { .qdev.name = "uni-north-pci", .qdev.size = sizeof(PCIDevice), .init = unin_internal_pci_host_init, + .vendor_id = PCI_VENDOR_ID_APPLE, + .device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI, + .revision = 0x00, + .class_id = PCI_CLASS_BRIDGE_HOST, }; static void unin_register_devices(void) diff --git a/hw/usb-bt.c b/hw/usb-bt.c index 22e6845..f30eec1 100644 --- a/hw/usb-bt.c +++ b/hw/usb-bt.c @@ -99,13 +99,13 @@ static const USBDescIface desc_iface_bluetooth[] = { .eps = (USBDescEndpoint[]) { { .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0, .bInterval = 0x01, }, { .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0, .bInterval = 0x01, }, @@ -120,13 +120,13 @@ static const USBDescIface desc_iface_bluetooth[] = { .eps = (USBDescEndpoint[]) { { .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x09, .bInterval = 0x01, }, { .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x09, .bInterval = 0x01, }, @@ -141,13 +141,13 @@ static const USBDescIface desc_iface_bluetooth[] = { .eps = (USBDescEndpoint[]) { { .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x11, .bInterval = 0x01, }, { .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x11, .bInterval = 0x01, }, @@ -162,13 +162,13 @@ static const USBDescIface desc_iface_bluetooth[] = { .eps = (USBDescEndpoint[]) { { .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x19, .bInterval = 0x01, }, { .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x19, .bInterval = 0x01, }, @@ -183,13 +183,13 @@ static const USBDescIface desc_iface_bluetooth[] = { .eps = (USBDescEndpoint[]) { { .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x21, .bInterval = 0x01, }, { .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x21, .bInterval = 0x01, }, @@ -204,13 +204,13 @@ static const USBDescIface desc_iface_bluetooth[] = { .eps = (USBDescEndpoint[]) { { .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x31, .bInterval = 0x01, }, { .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, .wMaxPacketSize = 0x31, .bInterval = 0x01, }, @@ -294,9 +294,9 @@ static inline int usb_bt_fifo_dequeue(struct usb_hci_in_fifo_s *fifo, if (likely(!fifo->len)) return USB_RET_STALL; - len = MIN(p->len, fifo->fifo[fifo->start].len); - memcpy(p->data, fifo->fifo[fifo->start].data, len); - if (len == p->len) { + len = MIN(p->iov.size, fifo->fifo[fifo->start].len); + usb_packet_copy(p, fifo->fifo[fifo->start].data, len); + if (len == p->iov.size) { fifo->fifo[fifo->start].len -= len; fifo->fifo[fifo->start].data += len; } else { @@ -319,20 +319,13 @@ static inline void usb_bt_fifo_out_enqueue(struct USBBtState *s, struct usb_hci_out_fifo_s *fifo, void (*send)(struct HCIInfo *, const uint8_t *, int), int (*complete)(const uint8_t *, int), - const uint8_t *data, int len) + USBPacket *p) { - if (fifo->len) { - memcpy(fifo->data + fifo->len, data, len); - fifo->len += len; - if (complete(fifo->data, fifo->len)) { - send(s->hci, fifo->data, fifo->len); - fifo->len = 0; - } - } else if (complete(data, len)) - send(s->hci, data, len); - else { - memcpy(fifo->data, data, len); - fifo->len = len; + usb_packet_copy(p, fifo->data + fifo->len, p->iov.size); + fifo->len += p->iov.size; + if (complete(fifo->data, fifo->len)) { + send(s->hci, fifo->data, fifo->len); + fifo->len = 0; } /* TODO: do we need to loop? */ @@ -372,13 +365,13 @@ static void usb_bt_handle_reset(USBDevice *dev) s->altsetting = 0; } -static int usb_bt_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_bt_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { struct USBBtState *s = (struct USBBtState *) dev->opaque; int ret; - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { switch (request) { case DeviceRequest | USB_REQ_GET_CONFIGURATION: @@ -432,7 +425,7 @@ static int usb_bt_handle_control(USBDevice *dev, int request, int value, case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE) << 8): if (s->config) usb_bt_fifo_out_enqueue(s, &s->outcmd, s->hci->cmd_send, - usb_bt_hci_cmd_complete, data, length); + usb_bt_hci_cmd_complete, p); break; default: fail: @@ -474,12 +467,12 @@ static int usb_bt_handle_data(USBDevice *dev, USBPacket *p) switch (p->devep & 0xf) { case USB_ACL_EP: usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send, - usb_bt_hci_acl_complete, p->data, p->len); + usb_bt_hci_acl_complete, p); break; case USB_SCO_EP: usb_bt_fifo_out_enqueue(s, &s->outsco, s->hci->sco_send, - usb_bt_hci_sco_complete, p->data, p->len); + usb_bt_hci_sco_complete, p); break; default: @@ -535,6 +528,9 @@ USBDevice *usb_bt_init(HCIInfo *hci) if (!hci) return NULL; dev = usb_create_simple(NULL /* FIXME */, "usb-bt-dongle"); + if (!dev) { + return NULL; + } s = DO_UPCAST(struct USBBtState, dev, dev); s->dev.opaque = s; @@ -548,10 +544,16 @@ USBDevice *usb_bt_init(HCIInfo *hci) return dev; } +static const VMStateDescription vmstate_usb_bt = { + .name = "usb-bt", + .unmigratable = 1, +}; + static struct USBDeviceInfo bt_info = { .product_desc = "QEMU BT dongle", .qdev.name = "usb-bt-dongle", .qdev.size = sizeof(struct USBBtState), + .qdev.vmsd = &vmstate_usb_bt, .usb_desc = &desc_bluetooth, .init = usb_bt_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-bus.c b/hw/usb-bus.c index abc7e61..8cafb76 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -3,11 +3,13 @@ #include "qdev.h" #include "sysemu.h" #include "monitor.h" +#include "trace.h" static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent); static char *usb_get_dev_path(DeviceState *dev); static char *usb_get_fw_dev_path(DeviceState *qdev); +static int usb_qdev_exit(DeviceState *qdev); static struct BusInfo usb_bus_info = { .name = "USB", @@ -39,9 +41,10 @@ const VMStateDescription vmstate_usb_device = { } }; -void usb_bus_new(USBBus *bus, DeviceState *host) +void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host) { qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL); + bus->ops = ops; bus->busnr = next_usb_bus++; bus->qbus.allow_hotplug = 1; /* Yes, we can */ QTAILQ_INIT(&bus->free); @@ -72,9 +75,24 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) dev->info = info; dev->auto_attach = 1; QLIST_INIT(&dev->strings); + rc = usb_claim_port(dev); + if (rc != 0) { + goto err; + } rc = dev->info->init(dev); - if (rc == 0 && dev->auto_attach) - usb_device_attach(dev); + if (rc != 0) { + goto err; + } + if (dev->auto_attach) { + rc = usb_device_attach(dev); + if (rc != 0) { + goto err; + } + } + return 0; + +err: + usb_qdev_exit(qdev); return rc; } @@ -82,10 +100,15 @@ static int usb_qdev_exit(DeviceState *qdev) { USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev); - usb_device_detach(dev); + if (dev->attached) { + usb_device_detach(dev); + } if (dev->info->handle_destroy) { dev->info->handle_destroy(dev); } + if (dev->port) { + usb_release_port(dev); + } return 0; } @@ -116,7 +139,7 @@ USBDevice *usb_create(USBBus *bus, const char *name) bus = usb_bus_find(-1); if (!bus) return NULL; - fprintf(stderr, "%s: no bus specified, using \"%s\" for \"%s\"\n", + error_report("%s: no bus specified, using \"%s\" for \"%s\"\n", __FUNCTION__, bus->qbus.name, name); } #endif @@ -128,26 +151,69 @@ USBDevice *usb_create(USBBus *bus, const char *name) USBDevice *usb_create_simple(USBBus *bus, const char *name) { USBDevice *dev = usb_create(bus, name); + int rc; + if (!dev) { - hw_error("Failed to create USB device '%s'\n", name); + error_report("Failed to create USB device '%s'\n", name); + return NULL; + } + rc = qdev_init(&dev->qdev); + if (rc < 0) { + error_report("Failed to initialize USB device '%s'\n", name); + return NULL; } - qdev_init_nofail(&dev->qdev); return dev; } -void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, - USBPortOps *ops, int speedmask) +static void usb_fill_port(USBPort *port, void *opaque, int index, + USBPortOps *ops, int speedmask) { port->opaque = opaque; port->index = index; - port->opaque = opaque; - port->index = index; port->ops = ops; port->speedmask = speedmask; + usb_port_location(port, NULL, index + 1); +} + +void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, + USBPortOps *ops, int speedmask) +{ + usb_fill_port(port, opaque, index, ops, speedmask); QTAILQ_INSERT_TAIL(&bus->free, port, next); bus->nfree++; } +int usb_register_companion(const char *masterbus, USBPort *ports[], + uint32_t portcount, uint32_t firstport, + void *opaque, USBPortOps *ops, int speedmask) +{ + USBBus *bus; + int i; + + QTAILQ_FOREACH(bus, &busses, next) { + if (strcmp(bus->qbus.name, masterbus) == 0) { + break; + } + } + + if (!bus || !bus->ops->register_companion) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus", + "an USB masterbus"); + if (bus) { + error_printf_unless_qmp( + "USB bus '%s' does not allow companion controllers\n", + masterbus); + } + return -1; + } + + for (i = 0; i < portcount; i++) { + usb_fill_port(ports[i], opaque, i, ops, speedmask); + } + + return bus->ops->register_companion(bus, ports, portcount, firstport); +} + void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr) { if (upstream) { @@ -166,16 +232,13 @@ void usb_unregister_port(USBBus *bus, USBPort *port) bus->nfree--; } -static void do_attach(USBDevice *dev) +int usb_claim_port(USBDevice *dev) { USBBus *bus = usb_bus_from_device(dev); USBPort *port; - if (dev->attached) { - fprintf(stderr, "Warning: tried to attach usb device %s twice\n", - dev->product_desc); - return; - } + assert(dev->port == NULL); + if (dev->port_path) { QTAILQ_FOREACH(port, &bus->free, next) { if (strcmp(port->path, dev->port_path) == 0) { @@ -183,62 +246,86 @@ static void do_attach(USBDevice *dev) } } if (port == NULL) { - fprintf(stderr, "Warning: usb port %s (bus %s) not found\n", - dev->port_path, bus->qbus.name); - return; + error_report("Error: usb port %s (bus %s) not found (in use?)\n", + dev->port_path, bus->qbus.name); + return -1; } } else { + if (bus->nfree == 1 && strcmp(dev->qdev.info->name, "usb-hub") != 0) { + /* Create a new hub and chain it on */ + usb_create_simple(bus, "usb-hub"); + } + if (bus->nfree == 0) { + error_report("Error: tried to attach usb device %s to a bus " + "with no free ports\n", dev->product_desc); + return -1; + } port = QTAILQ_FIRST(&bus->free); } + trace_usb_port_claim(bus->busnr, port->path); - dev->attached++; QTAILQ_REMOVE(&bus->free, port, next); bus->nfree--; - usb_attach(port, dev); + dev->port = port; + port->dev = dev; QTAILQ_INSERT_TAIL(&bus->used, port, next); bus->nused++; + return 0; } -int usb_device_attach(USBDevice *dev) +void usb_release_port(USBDevice *dev) { USBBus *bus = usb_bus_from_device(dev); + USBPort *port = dev->port; - if (bus->nfree == 1 && dev->port_path == NULL) { - /* Create a new hub and chain it on - (unless a physical port location is specified). */ - usb_create_simple(bus, "usb-hub"); - } - do_attach(dev); - return 0; + assert(port != NULL); + trace_usb_port_release(bus->busnr, port->path); + + QTAILQ_REMOVE(&bus->used, port, next); + bus->nused--; + + dev->port = NULL; + port->dev = NULL; + + QTAILQ_INSERT_TAIL(&bus->free, port, next); + bus->nfree++; } -int usb_device_detach(USBDevice *dev) +int usb_device_attach(USBDevice *dev) { USBBus *bus = usb_bus_from_device(dev); - USBPort *port; + USBPort *port = dev->port; - if (!dev->attached) { - fprintf(stderr, "Warning: tried to detach unattached usb device %s\n", - dev->product_desc); + assert(port != NULL); + assert(!dev->attached); + trace_usb_port_attach(bus->busnr, port->path); + + if (!(port->speedmask & dev->speedmask)) { + error_report("Warning: speed mismatch trying to attach " + "usb device %s to bus %s\n", + dev->product_desc, bus->qbus.name); return -1; } - dev->attached--; - QTAILQ_FOREACH(port, &bus->used, next) { - if (port->dev == dev) - break; - } - assert(port != NULL); + dev->attached++; + usb_attach(port); - QTAILQ_REMOVE(&bus->used, port, next); - bus->nused--; + return 0; +} + +int usb_device_detach(USBDevice *dev) +{ + USBBus *bus = usb_bus_from_device(dev); + USBPort *port = dev->port; - usb_attach(port, NULL); + assert(port != NULL); + assert(dev->attached); + trace_usb_port_detach(bus->busnr, port->path); - QTAILQ_INSERT_TAIL(&bus->free, port, next); - bus->nfree++; + usb_detach(port); + dev->attached--; return 0; } @@ -270,6 +357,7 @@ static const char *usb_speed(unsigned int speed) [ USB_SPEED_LOW ] = "1.5", [ USB_SPEED_FULL ] = "12", [ USB_SPEED_HIGH ] = "480", + [ USB_SPEED_SUPER ] = "5000", }; if (speed >= ARRAY_SIZE(txt)) return "?"; @@ -291,7 +379,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) static char *usb_get_dev_path(DeviceState *qdev) { USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev); - return qemu_strdup(dev->port->path); + return g_strdup(dev->port->path); } static char *usb_get_fw_dev_path(DeviceState *qdev) @@ -302,7 +390,7 @@ static char *usb_get_fw_dev_path(DeviceState *qdev) long nr; fw_len = 32 + strlen(dev->port->path) * 6; - fw_path = qemu_malloc(fw_len); + fw_path = g_malloc(fw_len); in = dev->port->path; while (fw_len - pos > 0) { nr = strtol(in, &in, 10); diff --git a/hw/usb-desc.c b/hw/usb-desc.c index 62591f2..ae2d384 100644 --- a/hw/usb-desc.c +++ b/hw/usb-desc.c @@ -76,7 +76,7 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) { uint8_t bLength = 0x09; uint16_t wTotalLength = 0; - int i, rc, count; + int i, rc; if (len < bLength) { return -1; @@ -91,8 +91,19 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) dest[0x08] = conf->bMaxPower; wTotalLength += bLength; - count = conf->nif ? conf->nif : conf->bNumInterfaces; - for (i = 0; i < count; i++) { + /* handle grouped interfaces if any*/ + for (i = 0; i < conf->nif_groups; i++) { + rc = usb_desc_iface_group(&(conf->if_groups[i]), + dest + wTotalLength, + len - wTotalLength); + if (rc < 0) { + return rc; + } + wTotalLength += rc; + } + + /* handle normal (ungrouped / no IAD) interfaces if any */ + for (i = 0; i < conf->nif; i++) { rc = usb_desc_iface(conf->ifs + i, dest + wTotalLength, len - wTotalLength); if (rc < 0) { return rc; @@ -105,6 +116,41 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) return wTotalLength; } +int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, + size_t len) +{ + int pos = 0; + int i = 0; + + /* handle interface association descriptor */ + uint8_t bLength = 0x08; + + if (len < bLength) { + return -1; + } + + dest[0x00] = bLength; + dest[0x01] = USB_DT_INTERFACE_ASSOC; + dest[0x02] = iad->bFirstInterface; + dest[0x03] = iad->bInterfaceCount; + dest[0x04] = iad->bFunctionClass; + dest[0x05] = iad->bFunctionSubClass; + dest[0x06] = iad->bFunctionProtocol; + dest[0x07] = iad->iFunction; + pos += bLength; + + /* handle associated interfaces in this group */ + for (i = 0; i < iad->nif; i++) { + int rc = usb_desc_iface(&(iad->ifs[i]), dest + pos, len - pos); + if (rc < 0) { + return rc; + } + pos += rc; + } + + return pos; +} + int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) { uint8_t bLength = 0x09; @@ -196,7 +242,17 @@ static void usb_desc_setdefaults(USBDevice *dev) void usb_desc_init(USBDevice *dev) { + const USBDesc *desc = dev->info->usb_desc; + + assert(desc != NULL); dev->speed = USB_SPEED_FULL; + dev->speedmask = 0; + if (desc->full) { + dev->speedmask |= USB_SPEED_MASK_FULL; + } + if (desc->high) { + dev->speedmask |= USB_SPEED_MASK_HIGH; + } usb_desc_setdefaults(dev); } @@ -227,12 +283,12 @@ void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str) } } if (s == NULL) { - s = qemu_mallocz(sizeof(*s)); + s = g_malloc0(sizeof(*s)); s->index = index; QLIST_INSERT_HEAD(&dev->strings, s, next); } - qemu_free(s->str); - s->str = qemu_strdup(str); + g_free(s->str); + s->str = g_strdup(str); } const char *usb_desc_get_string(USBDevice *dev, uint8_t index) @@ -329,6 +385,10 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len trace_usb_desc_other_speed_config(dev->addr, index, len, ret); break; + case USB_DT_DEBUG: + /* ignore silently */ + break; + default: fprintf(stderr, "%s: %d unknown type %d (len %zd)\n", __FUNCTION__, dev->addr, type, len); @@ -344,8 +404,8 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len return ret; } -int usb_desc_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +int usb_desc_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { const USBDesc *desc = dev->info->usb_desc; int i, ret = -1; diff --git a/hw/usb-desc.h b/hw/usb-desc.h index ac734ab..5c14e4a 100644 --- a/hw/usb-desc.h +++ b/hw/usb-desc.h @@ -30,6 +30,24 @@ struct USBDescConfig { uint8_t bmAttributes; uint8_t bMaxPower; + /* grouped interfaces */ + uint8_t nif_groups; + const USBDescIfaceAssoc *if_groups; + + /* "normal" interfaces */ + uint8_t nif; + const USBDescIface *ifs; +}; + +/* conceptually an Interface Association Descriptor, and releated interfaces */ +struct USBDescIfaceAssoc { + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; + uint8_t nif; const USBDescIface *ifs; }; @@ -57,7 +75,7 @@ struct USBDescEndpoint { struct USBDescOther { uint8_t length; - uint8_t *data; + const uint8_t *data; }; typedef const char *USBDescStrings[256]; @@ -75,6 +93,8 @@ int usb_desc_device(const USBDescID *id, const USBDescDevice *dev, int usb_desc_device_qualifier(const USBDescDevice *dev, uint8_t *dest, size_t len); int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len); +int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, + size_t len); int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len); int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len); int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len); @@ -86,7 +106,7 @@ void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str); const char *usb_desc_get_string(USBDevice *dev, uint8_t index); int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len); int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len); -int usb_desc_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data); +int usb_desc_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data); #endif /* QEMU_HW_USB_DESC_H */ diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index a58ba0d..a946e1d 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -3,6 +3,11 @@ * * Copyright(c) 2008 Emutex Ltd. (address@hidden) * + * EHCI project was started by Mark Burkley, with contributions by + * Niels de Vos. David S. Ahern continued working on it. Kevin Wolf, + * Jan Kiszka and Vincent Palatin contributed bugfixes. + * + * * 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 @@ -13,47 +18,36 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * TODO: - * o Downstream port handoff + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . */ #include "hw.h" #include "qemu-timer.h" #include "usb.h" #include "pci.h" -#include "sysbus.h" -#include "usb-ehci.h" #include "monitor.h" +#include "trace.h" +#include "dma.h" #define EHCI_DEBUG 0 -#define STATE_DEBUG 0 /* state transitions */ -#if EHCI_DEBUG || STATE_DEBUG +#if EHCI_DEBUG #define DPRINTF printf #else #define DPRINTF(...) #endif -#if STATE_DEBUG -#define DPRINTF_ST DPRINTF -#else -#define DPRINTF_ST(...) -#endif - /* internal processing - reset HC to try and recover */ #define USB_RET_PROCERR (-99) #define MMIO_SIZE 0x1000 /* Capability Registers Base Address - section 2.2 */ -#define CAPREGBASE 0x0000 +#define CAPREGBASE 0x0000 #define CAPLENGTH CAPREGBASE + 0x0000 // 1-byte, 0x0001 reserved #define HCIVERSION CAPREGBASE + 0x0002 // 2-bytes, i/f version # -#define HCSPARAMS CAPREGBASE + 0x0004 // 4-bytes, structural params +#define HCSPARAMS CAPREGBASE + 0x0004 // 4-bytes, structural params #define HCCPARAMS CAPREGBASE + 0x0008 // 4-bytes, capability params #define EECP HCCPARAMS + 1 #define HCSPPORTROUTE1 CAPREGBASE + 0x000c @@ -107,10 +101,10 @@ #define PORTSC_BEGIN PORTSC #define PORTSC_END (PORTSC + 4 * NB_PORTS) /* - * Bits that are reserverd or are read-only are masked out of values + * Bits that are reserved or are read-only are masked out of values * written to us by software */ -#define PORTSC_RO_MASK 0x007021c5 +#define PORTSC_RO_MASK 0x007001c0 #define PORTSC_RWC_MASK 0x0000002a #define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable #define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable @@ -133,17 +127,11 @@ #define PORTSC_CSC (1 << 1) // Connect Status Change #define PORTSC_CONNECT (1 << 0) // Current Connect Status -//#define EHCI_NOMICROFRAMES - -#ifdef EHCI_NOMICROFRAMES #define FRAME_TIMER_FREQ 1000 -#else -#define FRAME_TIMER_FREQ 8000 -#endif -#define FRAME_TIMER_USEC (1000000 / FRAME_TIMER_FREQ) +#define FRAME_TIMER_NS (1000000000 / FRAME_TIMER_FREQ) #define NB_MAXINTRATE 8 // Max rate at which controller issues ints -#define NB_PORTS 4 // Number of downstream ports +#define NB_PORTS 6 // Number of downstream ports #define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction #define MAX_ITERATIONS 20 // Max number of QH before we break the loop #define MAX_QH 100 // Max allowable queue heads in a chain @@ -161,6 +149,7 @@ typedef enum { EST_FETCHENTRY, EST_FETCHQH, EST_FETCHITD, + EST_FETCHSITD, EST_ADVANCEQUEUE, EST_FETCHQTD, EST_EXECUTE, @@ -208,6 +197,7 @@ typedef struct EHCIitd { #define ITD_BUFPTR_MAXPKT_MASK 0x000007ff #define ITD_BUFPTR_MAXPKT_SH 0 #define ITD_BUFPTR_MULT_MASK 0x00000003 +#define ITD_BUFPTR_MULT_SH 0 } EHCIitd; /* EHCI spec version 1.0 Section 3.4 @@ -281,6 +271,7 @@ typedef struct EHCIqtd { uint32_t bufptr[5]; // Standard buffer pointer #define QTD_BUFPTR_MASK 0xfffff000 +#define QTD_BUFPTR_SH 12 } EHCIqtd; /* EHCI spec version 1.0 Section 3.6 @@ -344,11 +335,49 @@ typedef struct EHCIfstn { uint32_t backptr; // Standard next link pointer } EHCIfstn; -typedef struct { +typedef struct EHCIQueue EHCIQueue; +typedef struct EHCIState EHCIState; + +enum async_state { + EHCI_ASYNC_NONE = 0, + EHCI_ASYNC_INFLIGHT, + EHCI_ASYNC_FINISHED, +}; + +struct EHCIQueue { + EHCIState *ehci; + QTAILQ_ENTRY(EHCIQueue) next; + bool async_schedule; + uint32_t seen; + uint64_t ts; + + /* cached data from guest - needs to be flushed + * when guest removes an entry (doorbell, handshake sequence) + */ + EHCIqh qh; // copy of current QH (being worked on) + uint32_t qhaddr; // address QH read from + EHCIqtd qtd; // copy of current QTD (being worked on) + uint32_t qtdaddr; // address QTD read from + + USBPacket packet; + QEMUSGList sgl; + int pid; + uint32_t tbytes; + enum async_state async; + int usb_status; +}; + +struct EHCIState { + PCIDevice dev; + USBBus bus; qemu_irq irq; - target_phys_addr_t mem_base; - int mem; - int num_ports; + MemoryRegion mem; + int companion_count; + + /* properties */ + uint32_t freq; + uint32_t maxframes; + /* * EHCI spec version 1.0 Section 2.3 * Host Controller Operational Registers @@ -369,6 +398,7 @@ typedef struct { uint32_t portsc[NB_PORTS]; }; }; + /* * Internal states, shadow registers, etc */ @@ -378,35 +408,22 @@ typedef struct { int astate; // Current state in asynchronous schedule int pstate; // Current state in periodic schedule USBPort ports[NB_PORTS]; - uint8_t buffer[BUFF_SIZE]; - - /* cached data from guest - needs to be flushed - * when guest removes an entry (doorbell, handshake sequence) - */ - EHCIqh qh; // copy of current QH (being worked on) - uint32_t qhaddr; // address QH read from - - EHCIqtd qtd; // copy of current QTD (being worked on) - uint32_t qtdaddr; // address QTD read from + USBPort *companion_ports[NB_PORTS]; + uint32_t usbsts_pending; + QTAILQ_HEAD(, EHCIQueue) queues; - uint32_t itdaddr; // current ITD + uint32_t a_fetch_addr; // which address to look at next + uint32_t p_fetch_addr; // which address to look at next - uint32_t fetch_addr; // which address to look at next - - USBBus bus; - USBPacket usb_packet; - int async_port_in_progress; - int async_complete; - uint32_t tbytes; - int pid; - int exec_status; + USBPacket ipacket; + QEMUSGList isgl; int isoch_pause; - uint32_t last_run_usec; - uint32_t frame_end_usec; -} EHCIState; + + uint64_t last_run_ns; +}; #define SET_LAST_RUN_CLOCK(s) \ - (s)->last_run_usec = qemu_get_clock(vm_clock) / 1000; + (s)->last_run_ns = qemu_get_clock_ns(vm_clock); /* nifty macros from Arnon's EHCI version */ #define get_field(data, field) \ @@ -419,121 +436,412 @@ typedef struct { *data = val; \ } while(0) +static const char *ehci_state_names[] = { + [EST_INACTIVE] = "INACTIVE", + [EST_ACTIVE] = "ACTIVE", + [EST_EXECUTING] = "EXECUTING", + [EST_SLEEPING] = "SLEEPING", + [EST_WAITLISTHEAD] = "WAITLISTHEAD", + [EST_FETCHENTRY] = "FETCH ENTRY", + [EST_FETCHQH] = "FETCH QH", + [EST_FETCHITD] = "FETCH ITD", + [EST_ADVANCEQUEUE] = "ADVANCEQUEUE", + [EST_FETCHQTD] = "FETCH QTD", + [EST_EXECUTE] = "EXECUTE", + [EST_WRITEBACK] = "WRITEBACK", + [EST_HORIZONTALQH] = "HORIZONTALQH", +}; -#if EHCI_DEBUG -static const char *addr2str(unsigned addr) +static const char *ehci_mmio_names[] = { + [CAPLENGTH] = "CAPLENGTH", + [HCIVERSION] = "HCIVERSION", + [HCSPARAMS] = "HCSPARAMS", + [HCCPARAMS] = "HCCPARAMS", + [USBCMD] = "USBCMD", + [USBSTS] = "USBSTS", + [USBINTR] = "USBINTR", + [FRINDEX] = "FRINDEX", + [PERIODICLISTBASE] = "P-LIST BASE", + [ASYNCLISTADDR] = "A-LIST ADDR", + [PORTSC_BEGIN] = "PORTSC #0", + [PORTSC_BEGIN + 4] = "PORTSC #1", + [PORTSC_BEGIN + 8] = "PORTSC #2", + [PORTSC_BEGIN + 12] = "PORTSC #3", + [PORTSC_BEGIN + 16] = "PORTSC #4", + [PORTSC_BEGIN + 20] = "PORTSC #5", + [CONFIGFLAG] = "CONFIGFLAG", +}; + +static const char *nr2str(const char **n, size_t len, uint32_t nr) { - const char *r = " unknown"; + if (nr < len && n[nr] != NULL) { + return n[nr]; + } else { + return "unknown"; + } +} - switch(addr) { - case CAPLENGTH: - r = " CAPLENGTH"; - break; +static const char *state2str(uint32_t state) +{ + return nr2str(ehci_state_names, ARRAY_SIZE(ehci_state_names), state); +} - case HCIVERSION: - r = "HCIVERSION"; - break; +static const char *addr2str(target_phys_addr_t addr) +{ + return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr); +} - case HCSPARAMS: - r = " HCSPARAMS"; - break; +static void ehci_trace_usbsts(uint32_t mask, int state) +{ + /* interrupts */ + if (mask & USBSTS_INT) { + trace_usb_ehci_usbsts("INT", state); + } + if (mask & USBSTS_ERRINT) { + trace_usb_ehci_usbsts("ERRINT", state); + } + if (mask & USBSTS_PCD) { + trace_usb_ehci_usbsts("PCD", state); + } + if (mask & USBSTS_FLR) { + trace_usb_ehci_usbsts("FLR", state); + } + if (mask & USBSTS_HSE) { + trace_usb_ehci_usbsts("HSE", state); + } + if (mask & USBSTS_IAA) { + trace_usb_ehci_usbsts("IAA", state); + } - case HCCPARAMS: - r = " HCCPARAMS"; - break; + /* status */ + if (mask & USBSTS_HALT) { + trace_usb_ehci_usbsts("HALT", state); + } + if (mask & USBSTS_REC) { + trace_usb_ehci_usbsts("REC", state); + } + if (mask & USBSTS_PSS) { + trace_usb_ehci_usbsts("PSS", state); + } + if (mask & USBSTS_ASS) { + trace_usb_ehci_usbsts("ASS", state); + } +} - case USBCMD: - r = " COMMAND"; - break; +static inline void ehci_set_usbsts(EHCIState *s, int mask) +{ + if ((s->usbsts & mask) == mask) { + return; + } + ehci_trace_usbsts(mask, 1); + s->usbsts |= mask; +} - case USBSTS: - r = " STATUS"; - break; +static inline void ehci_clear_usbsts(EHCIState *s, int mask) +{ + if ((s->usbsts & mask) == 0) { + return; + } + ehci_trace_usbsts(mask, 0); + s->usbsts &= ~mask; +} - case USBINTR: - r = " INTERRUPT"; - break; +static inline void ehci_set_interrupt(EHCIState *s, int intr) +{ + int level = 0; - case FRINDEX: - r = " FRAME IDX"; - break; - - case PERIODICLISTBASE: - r = "P-LIST BASE"; - break; - - case ASYNCLISTADDR: - r = "A-LIST ADDR"; - break; + // TODO honour interrupt threshold requests - case PORTSC_BEGIN ... PORTSC_END: - r = "PORT STATUS"; - break; + ehci_set_usbsts(s, intr); - case CONFIGFLAG: - r = "CONFIG FLAG"; - break; + if ((s->usbsts & USBINTR_MASK) & s->usbintr) { + level = 1; } - return r; + qemu_set_irq(s->irq, level); } -#endif +static inline void ehci_record_interrupt(EHCIState *s, int intr) +{ + s->usbsts_pending |= intr; +} -static inline void ehci_set_interrupt(EHCIState *s, int intr) +static inline void ehci_commit_interrupt(EHCIState *s) { - int level = 0; + if (!s->usbsts_pending) { + return; + } + ehci_set_interrupt(s, s->usbsts_pending); + s->usbsts_pending = 0; +} - // TODO honour interrupt threshold requests +static void ehci_set_state(EHCIState *s, int async, int state) +{ + if (async) { + trace_usb_ehci_state("async", state2str(state)); + s->astate = state; + } else { + trace_usb_ehci_state("periodic", state2str(state)); + s->pstate = state; + } +} - s->usbsts |= intr; +static int ehci_get_state(EHCIState *s, int async) +{ + return async ? s->astate : s->pstate; +} - if ((s->usbsts & USBINTR_MASK) & s->usbintr) - level = 1; +static void ehci_set_fetch_addr(EHCIState *s, int async, uint32_t addr) +{ + if (async) { + s->a_fetch_addr = addr; + } else { + s->p_fetch_addr = addr; + } +} - qemu_set_irq(s->irq, level); +static int ehci_get_fetch_addr(EHCIState *s, int async) +{ + return async ? s->a_fetch_addr : s->p_fetch_addr; +} + +static void ehci_trace_qh(EHCIQueue *q, target_phys_addr_t addr, EHCIqh *qh) +{ + /* need three here due to argument count limits */ + trace_usb_ehci_qh_ptrs(q, addr, qh->next, + qh->current_qtd, qh->next_qtd, qh->altnext_qtd); + trace_usb_ehci_qh_fields(addr, + get_field(qh->epchar, QH_EPCHAR_RL), + get_field(qh->epchar, QH_EPCHAR_MPLEN), + get_field(qh->epchar, QH_EPCHAR_EPS), + get_field(qh->epchar, QH_EPCHAR_EP), + get_field(qh->epchar, QH_EPCHAR_DEVADDR)); + trace_usb_ehci_qh_bits(addr, + (bool)(qh->epchar & QH_EPCHAR_C), + (bool)(qh->epchar & QH_EPCHAR_H), + (bool)(qh->epchar & QH_EPCHAR_DTC), + (bool)(qh->epchar & QH_EPCHAR_I)); +} + +static void ehci_trace_qtd(EHCIQueue *q, target_phys_addr_t addr, EHCIqtd *qtd) +{ + /* need three here due to argument count limits */ + trace_usb_ehci_qtd_ptrs(q, addr, qtd->next, qtd->altnext); + trace_usb_ehci_qtd_fields(addr, + get_field(qtd->token, QTD_TOKEN_TBYTES), + get_field(qtd->token, QTD_TOKEN_CPAGE), + get_field(qtd->token, QTD_TOKEN_CERR), + get_field(qtd->token, QTD_TOKEN_PID)); + trace_usb_ehci_qtd_bits(addr, + (bool)(qtd->token & QTD_TOKEN_IOC), + (bool)(qtd->token & QTD_TOKEN_ACTIVE), + (bool)(qtd->token & QTD_TOKEN_HALT), + (bool)(qtd->token & QTD_TOKEN_BABBLE), + (bool)(qtd->token & QTD_TOKEN_XACTERR)); +} + +static void ehci_trace_itd(EHCIState *s, target_phys_addr_t addr, EHCIitd *itd) +{ + trace_usb_ehci_itd(addr, itd->next, + get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT), + get_field(itd->bufptr[2], ITD_BUFPTR_MULT), + get_field(itd->bufptr[0], ITD_BUFPTR_EP), + get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR)); +} + +static void ehci_trace_sitd(EHCIState *s, target_phys_addr_t addr, + EHCIsitd *sitd) +{ + trace_usb_ehci_sitd(addr, sitd->next, + (bool)(sitd->results & SITD_RESULTS_ACTIVE)); +} + +/* queue management */ + +static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, int async) +{ + EHCIQueue *q; + + q = g_malloc0(sizeof(*q)); + q->ehci = ehci; + q->async_schedule = async; + QTAILQ_INSERT_HEAD(&ehci->queues, q, next); + trace_usb_ehci_queue_action(q, "alloc"); + return q; +} + +static void ehci_free_queue(EHCIQueue *q) +{ + trace_usb_ehci_queue_action(q, "free"); + if (q->async == EHCI_ASYNC_INFLIGHT) { + usb_cancel_packet(&q->packet); + } + QTAILQ_REMOVE(&q->ehci->queues, q, next); + g_free(q); +} + +static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr) +{ + EHCIQueue *q; + + QTAILQ_FOREACH(q, &ehci->queues, next) { + if (addr == q->qhaddr) { + return q; + } + } + return NULL; +} + +static void ehci_queues_rip_unused(EHCIState *ehci) +{ + EHCIQueue *q, *tmp; + + QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) { + if (q->seen) { + q->seen = 0; + q->ts = ehci->last_run_ns; + continue; + } + if (ehci->last_run_ns < q->ts + 250000000) { + /* allow 0.25 sec idle */ + continue; + } + ehci_free_queue(q); + } +} + +static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev) +{ + EHCIQueue *q, *tmp; + + QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) { + if (q->packet.owner != dev) { + continue; + } + ehci_free_queue(q); + } +} + +static void ehci_queues_rip_all(EHCIState *ehci) +{ + EHCIQueue *q, *tmp; + + QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) { + ehci_free_queue(q); + } } /* Attach or detach a device on root hub */ -static void ehci_attach(USBPort *port, USBDevice *dev) +static void ehci_attach(USBPort *port) { EHCIState *s = port->opaque; uint32_t *portsc = &s->portsc[port->index]; - DPRINTF("ehci_attach invoked for index %d, portsc 0x%x, desc %s\n", - port->index, *portsc, dev ? dev->product_desc : "undefined"); + trace_usb_ehci_port_attach(port->index, port->dev->product_desc); - if (dev) { - if (port->dev) { - usb_attach(port, NULL); - } + if (*portsc & PORTSC_POWNER) { + USBPort *companion = s->companion_ports[port->index]; + companion->dev = port->dev; + companion->ops->attach(companion); + return; + } - *portsc |= PORTSC_CONNECT; + *portsc |= PORTSC_CONNECT; + *portsc |= PORTSC_CSC; - usb_send_msg(dev, USB_MSG_ATTACH); - port->dev = dev; - } else { - *portsc &= ~PORTSC_CONNECT; + ehci_set_interrupt(s, USBSTS_PCD); +} - if (port->dev) { - dev = port->dev; - usb_send_msg(dev, USB_MSG_DETACH); - } +static void ehci_detach(USBPort *port) +{ + EHCIState *s = port->opaque; + uint32_t *portsc = &s->portsc[port->index]; - port->dev = NULL; + trace_usb_ehci_port_detach(port->index); + + if (*portsc & PORTSC_POWNER) { + USBPort *companion = s->companion_ports[port->index]; + companion->ops->detach(companion); + companion->dev = NULL; + return; } + ehci_queues_rip_device(s, port->dev); + + *portsc &= ~(PORTSC_CONNECT|PORTSC_PED); *portsc |= PORTSC_CSC; - /* - * If a high speed device is attached then we own this port(indicated - * by zero in the PORTSC_POWNER bit field) so set the status bit - * and set an interrupt if enabled. - */ - if ( !(*portsc & PORTSC_POWNER)) { - ehci_set_interrupt(s, USBSTS_PCD); + ehci_set_interrupt(s, USBSTS_PCD); +} + +static void ehci_child_detach(USBPort *port, USBDevice *child) +{ + EHCIState *s = port->opaque; + uint32_t portsc = s->portsc[port->index]; + + if (portsc & PORTSC_POWNER) { + USBPort *companion = s->companion_ports[port->index]; + companion->ops->child_detach(companion, child); + companion->dev = NULL; + return; + } + + ehci_queues_rip_device(s, child); +} + +static void ehci_wakeup(USBPort *port) +{ + EHCIState *s = port->opaque; + uint32_t portsc = s->portsc[port->index]; + + if (portsc & PORTSC_POWNER) { + USBPort *companion = s->companion_ports[port->index]; + if (companion->ops->wakeup) { + companion->ops->wakeup(companion); + } + } +} + +static int ehci_register_companion(USBBus *bus, USBPort *ports[], + uint32_t portcount, uint32_t firstport) +{ + EHCIState *s = container_of(bus, EHCIState, bus); + uint32_t i; + + if (firstport + portcount > NB_PORTS) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "firstport", + "firstport on masterbus"); + error_printf_unless_qmp( + "firstport value of %u makes companion take ports %u - %u, which " + "is outside of the valid range of 0 - %u\n", firstport, firstport, + firstport + portcount - 1, NB_PORTS - 1); + return -1; + } + + for (i = 0; i < portcount; i++) { + if (s->companion_ports[firstport + i]) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus", + "an USB masterbus"); + error_printf_unless_qmp( + "port %u on masterbus %s already has a companion assigned\n", + firstport + i, bus->qbus.name); + return -1; + } } + + for (i = 0; i < portcount; i++) { + s->companion_ports[firstport + i] = ports[i]; + s->ports[firstport + i].speedmask |= + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL; + /* Ensure devs attached before the initial reset go to the companion */ + s->portsc[firstport + i] = PORTSC_POWNER; + } + + s->companion_count++; + s->mmio[0x05] = (s->companion_count << 4) | portcount; + + return 0; } /* 4.1 host controller initialization */ @@ -541,6 +849,20 @@ static void ehci_reset(void *opaque) { EHCIState *s = opaque; int i; + USBDevice *devs[NB_PORTS]; + + trace_usb_ehci_reset(); + + /* + * Do the detach before touching portsc, so that it correctly gets send to + * us or to our companion based on PORTSC_POWNER before the reset. + */ + for(i = 0; i < NB_PORTS; i++) { + devs[i] = s->ports[i].dev; + if (devs[i] && devs[i]->attached) { + usb_detach(&s->ports[i]); + } + } memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE); @@ -549,17 +871,21 @@ static void ehci_reset(void *opaque) s->astate = EST_INACTIVE; s->pstate = EST_INACTIVE; - s->async_port_in_progress = -1; - s->async_complete = 0; s->isoch_pause = -1; s->attach_poll_counter = 0; - for (i = 0; i < NB_PORTS; i++) { - s->portsc[i] = PORTSC_POWNER | PORTSC_PPOWER; - - if (s->ports[i].dev) - ehci_attach(&s->ports[i], s->ports[i].dev); + for(i = 0; i < NB_PORTS; i++) { + if (s->companion_ports[i]) { + s->portsc[i] = PORTSC_POWNER | PORTSC_PPOWER; + } else { + s->portsc[i] = PORTSC_PPOWER; + } + if (devs[i] && devs[i]->attached) { + usb_attach(&s->ports[i]); + usb_send_msg(devs[i], USB_MSG_RESET); + } } + ehci_queues_rip_all(s); } static uint32_t ehci_mem_readb(void *ptr, target_phys_addr_t addr) @@ -590,6 +916,7 @@ static uint32_t ehci_mem_readl(void *ptr, target_phys_addr_t addr) val = s->mmio[addr] | (s->mmio[addr+1] << 8) | (s->mmio[addr+2] << 16) | (s->mmio[addr+3] << 24); + trace_usb_ehci_mmio_readl(addr, addr2str(addr), val); return val; } @@ -605,108 +932,117 @@ static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val) exit(1); } -static void handle_port_status_write(EHCIState *s, int port, uint32_t val) +static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner) { - uint32_t *portsc = &s->portsc[port]; - int rwc; USBDevice *dev = s->ports[port].dev; + uint32_t *portsc = &s->portsc[port]; + uint32_t orig; - DPRINTF("port_status_write: " - "PORTSC (port %d) curr %08X new %08X rw-clear %08X rw %08X\n", - port, *portsc, val, (val & PORTSC_RWC_MASK), val & PORTSC_RO_MASK); + if (s->companion_ports[port] == NULL) + return; - rwc = val & PORTSC_RWC_MASK; - val &= PORTSC_RO_MASK; + owner = owner & PORTSC_POWNER; + orig = *portsc & PORTSC_POWNER; - // handle_read_write_clear(&val, portsc, PORTSC_PEDC | PORTSC_CSC); + if (!(owner ^ orig)) { + return; + } - *portsc &= ~rwc; + if (dev && dev->attached) { + usb_detach(&s->ports[port]); + } - if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) { - DPRINTF("port_status_write: USBTRAN Port %d reset begin\n", port); + *portsc &= ~PORTSC_POWNER; + *portsc |= owner; + + if (dev && dev->attached) { + usb_attach(&s->ports[port]); } +} - if (!(val & PORTSC_PRESET) &&(*portsc & PORTSC_PRESET)) { - DPRINTF("port_status_write: USBTRAN Port %d reset done\n", port); - ehci_attach(&s->ports[port], dev); +static void handle_port_status_write(EHCIState *s, int port, uint32_t val) +{ + uint32_t *portsc = &s->portsc[port]; + USBDevice *dev = s->ports[port].dev; + + /* Clear rwc bits */ + *portsc &= ~(val & PORTSC_RWC_MASK); + /* The guest may clear, but not set the PED bit */ + *portsc &= val | ~PORTSC_PED; + /* POWNER is masked out by RO_MASK as it is RO when we've no companion */ + handle_port_owner_write(s, port, val); + /* And finally apply RO_MASK */ + val &= PORTSC_RO_MASK; - // TODO how to handle reset of ports with no device - if (dev) - usb_send_msg(dev, USB_MSG_RESET); + if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) { + trace_usb_ehci_port_reset(port, 1); + } - if (s->ports[port].dev) { - DPRINTF("port_status_write: " - "Device was connected before reset, clearing CSC bit\n"); + if (!(val & PORTSC_PRESET) &&(*portsc & PORTSC_PRESET)) { + trace_usb_ehci_port_reset(port, 0); + if (dev && dev->attached) { + usb_reset(&s->ports[port]); *portsc &= ~PORTSC_CSC; } - /* Table 2.16 Set the enable bit(and enable bit change) to indicate + /* + * Table 2.16 Set the enable bit(and enable bit change) to indicate * to SW that this port has a high speed device attached - * - * TODO - when to disable? */ - val |= PORTSC_PED; - val |= PORTSC_PEDC; + if (dev && dev->attached && (dev->speedmask & USB_SPEED_MASK_HIGH)) { + val |= PORTSC_PED; + } } *portsc &= ~PORTSC_RO_MASK; *portsc |= val; - DPRINTF("port_status_write: Port %d status set to 0x%08x\n", port, *portsc); } static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) { EHCIState *s = ptr; + uint32_t *mmio = (uint32_t *)(&s->mmio[addr]); + uint32_t old = *mmio; int i; -#if EHCI_DEBUG - const char *str; -#endif + + trace_usb_ehci_mmio_writel(addr, addr2str(addr), val); /* Only aligned reads are allowed on OHCI */ if (addr & 3) { fprintf(stderr, "usb-ehci: Mis-aligned write to addr 0x" - TARGET_FMT_plx "\n", addr); + TARGET_FMT_plx "\n", addr); return; } if (addr >= PORTSC && addr < PORTSC + 4 * NB_PORTS) { handle_port_status_write(s, (addr-PORTSC)/4, val); + trace_usb_ehci_mmio_change(addr, addr2str(addr), *mmio, old); return; } if (addr < OPREGBASE) { fprintf(stderr, "usb-ehci: write attempt to read-only register" - TARGET_FMT_plx "\n", addr); + TARGET_FMT_plx "\n", addr); return; } /* Do any register specific pre-write processing here. */ -#if EHCI_DEBUG - str = addr2str((unsigned) addr); -#endif - switch(addr) - { + switch(addr) { case USBCMD: - DPRINTF("ehci_mem_writel: USBCMD val=0x%08X, current cmd=0x%08X\n", - val, s->usbcmd); - if ((val & USBCMD_RUNSTOP) && !(s->usbcmd & USBCMD_RUNSTOP)) { - DPRINTF("ehci_mem_writel: %s run, clear halt\n", str); - qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock)); + qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock)); SET_LAST_RUN_CLOCK(s); - s->usbsts &= ~USBSTS_HALT; + ehci_clear_usbsts(s, USBSTS_HALT); } if (!(val & USBCMD_RUNSTOP) && (s->usbcmd & USBCMD_RUNSTOP)) { - DPRINTF(" ** STOP **\n"); qemu_del_timer(s->frame_timer); // TODO - should finish out some stuff before setting halt - s->usbsts |= USBSTS_HALT; + ehci_set_usbsts(s, USBSTS_HALT); } if (val & USBCMD_HCRESET) { - DPRINTF("ehci_mem_writel: %s run, resetting\n", str); ehci_reset(s); val &= ~USBCMD_HCRESET; } @@ -717,60 +1053,28 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) val & USBCMD_FLS); val &= ~USBCMD_FLS; } -#if EHCI_DEBUG - if ((val & USBCMD_PSE) && !(s->usbcmd & USBCMD_PSE)) { - DPRINTF("periodic scheduling enabled\n"); - } - if (!(val & USBCMD_PSE) && (s->usbcmd & USBCMD_PSE)) { - DPRINTF("periodic scheduling disabled\n"); - } - if ((val & USBCMD_ASE) && !(s->usbcmd & USBCMD_ASE)) { - DPRINTF("asynchronous scheduling enabled\n"); - } - if (!(val & USBCMD_ASE) && (s->usbcmd & USBCMD_ASE)) { - DPRINTF("asynchronous scheduling disabled\n"); - } - if ((val & USBCMD_IAAD) && !(s->usbcmd & USBCMD_IAAD)) { - DPRINTF("doorbell request received\n"); - } - if ((val & USBCMD_LHCR) && !(s->usbcmd & USBCMD_LHCR)) { - DPRINTF("light host controller reset received\n"); - } - if ((val & USBCMD_ITC) != (s->usbcmd & USBCMD_ITC)) { - DPRINTF("interrupt threshold control set to %x\n", - (val & USBCMD_ITC)>>USBCMD_ITC_SH); - } -#endif break; - case USBSTS: val &= USBSTS_RO_MASK; // bits 6 thru 31 are RO - DPRINTF("ehci_mem_writel: %s RWC set to 0x%08X\n", str, val); - - val = (s->usbsts &= ~val); // bits 0 thru 5 are R/WC - - DPRINTF("ehci_mem_writel: %s updating interrupt condition\n", str); + ehci_clear_usbsts(s, val); // bits 0 thru 5 are R/WC + val = s->usbsts; ehci_set_interrupt(s, 0); break; - case USBINTR: val &= USBINTR_MASK; - DPRINTF("ehci_mem_writel: %s set to 0x%08X\n", str, val); break; case FRINDEX: s->sofv = val >> 3; - DPRINTF("ehci_mem_writel: %s set to 0x%08X\n", str, val); break; case CONFIGFLAG: - DPRINTF("ehci_mem_writel: %s set to 0x%08X\n", str, val); val &= 0x1; if (val) { - for (i = 0; i < NB_PORTS; i++) - s->portsc[i] &= ~PORTSC_POWNER; + for(i = 0; i < NB_PORTS; i++) + handle_port_owner_write(s, i, 0); } break; @@ -780,7 +1084,6 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) "ehci: PERIODIC list base register set while periodic schedule\n" " is enabled and HC is enabled\n"); } - DPRINTF("ehci_mem_writel: P-LIST BASE set to 0x%08X\n", val); break; case ASYNCLISTADDR: @@ -789,23 +1092,24 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) "ehci: ASYNC list address register set while async schedule\n" " is enabled and HC is enabled\n"); } - DPRINTF("ehci_mem_writel: A-LIST ADDR set to 0x%08X\n", val); break; } - *(uint32_t *)(&s->mmio[addr]) = val; + *mmio = val; + trace_usb_ehci_mmio_change(addr, addr2str(addr), *mmio, old); } // TODO : Put in common header file, duplication from usb-ohci.c /* Get an array of dwords from main memory */ -static inline int get_dwords(uint32_t addr, uint32_t *buf, int num) +static inline int get_dwords(EHCIState *ehci, uint32_t addr, + uint32_t *buf, int num) { int i; for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - cpu_physical_memory_rw(addr,(uint8_t *)buf, sizeof(*buf), 0); + pci_dma_read(&ehci->dev, addr, (uint8_t *)buf, sizeof(*buf)); *buf = le32_to_cpu(*buf); } @@ -813,13 +1117,14 @@ static inline int get_dwords(uint32_t addr, uint32_t *buf, int num) } /* Put an array of dwords in to main memory */ -static inline int put_dwords(uint32_t addr, uint32_t *buf, int num) +static inline int put_dwords(EHCIState *ehci, uint32_t addr, + uint32_t *buf, int num) { int i; for(i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { uint32_t tmp = cpu_to_le32(*buf); - cpu_physical_memory_rw(addr,(uint8_t *)&tmp, sizeof(tmp), 1); + pci_dma_write(&ehci->dev, addr, (uint8_t *)&tmp, sizeof(tmp)); } return 1; @@ -827,7 +1132,7 @@ static inline int put_dwords(uint32_t addr, uint32_t *buf, int num) // 4.10.2 -static int ehci_qh_do_overlay(EHCIState *ehci, EHCIqh *qh, EHCIqtd *qtd) +static int ehci_qh_do_overlay(EHCIQueue *q) { int i; int dtoggle; @@ -837,200 +1142,193 @@ static int ehci_qh_do_overlay(EHCIState *ehci, EHCIqh *qh, EHCIqtd *qtd) // remember values in fields to preserve in qh after overlay - dtoggle = qh->token & QTD_TOKEN_DTOGGLE; - ping = qh->token & QTD_TOKEN_PING; + dtoggle = q->qh.token & QTD_TOKEN_DTOGGLE; + ping = q->qh.token & QTD_TOKEN_PING; - DPRINTF("setting qh.current from %08X to 0x%08X\n", qh->current_qtd, - ehci->qtdaddr); - qh->current_qtd = ehci->qtdaddr; - qh->next_qtd = qtd->next; - qh->altnext_qtd = qtd->altnext; - qh->token = qtd->token; + q->qh.current_qtd = q->qtdaddr; + q->qh.next_qtd = q->qtd.next; + q->qh.altnext_qtd = q->qtd.altnext; + q->qh.token = q->qtd.token; - eps = get_field(qh->epchar, QH_EPCHAR_EPS); + eps = get_field(q->qh.epchar, QH_EPCHAR_EPS); if (eps == EHCI_QH_EPS_HIGH) { - qh->token &= ~QTD_TOKEN_PING; - qh->token |= ping; + q->qh.token &= ~QTD_TOKEN_PING; + q->qh.token |= ping; } - reload = get_field(qh->epchar, QH_EPCHAR_RL); - set_field(&qh->altnext_qtd, reload, QH_ALTNEXT_NAKCNT); + reload = get_field(q->qh.epchar, QH_EPCHAR_RL); + set_field(&q->qh.altnext_qtd, reload, QH_ALTNEXT_NAKCNT); for (i = 0; i < 5; i++) { - qh->bufptr[i] = qtd->bufptr[i]; + q->qh.bufptr[i] = q->qtd.bufptr[i]; } - if (!(qh->epchar & QH_EPCHAR_DTC)) { + if (!(q->qh.epchar & QH_EPCHAR_DTC)) { // preserve QH DT bit - qh->token &= ~QTD_TOKEN_DTOGGLE; - qh->token |= dtoggle; + q->qh.token &= ~QTD_TOKEN_DTOGGLE; + q->qh.token |= dtoggle; } - qh->bufptr[1] &= ~BUFPTR_CPROGMASK_MASK; - qh->bufptr[2] &= ~BUFPTR_FRAMETAG_MASK; + q->qh.bufptr[1] &= ~BUFPTR_CPROGMASK_MASK; + q->qh.bufptr[2] &= ~BUFPTR_FRAMETAG_MASK; - put_dwords(NLPTR_GET(ehci->qhaddr), (uint32_t *) qh, sizeof(EHCIqh) >> 2); + put_dwords(q->ehci, NLPTR_GET(q->qhaddr), (uint32_t *) &q->qh, + sizeof(EHCIqh) >> 2); return 0; } -static int ehci_buffer_rw(uint8_t *buffer, EHCIqh *qh, int bytes, int rw) +static int ehci_init_transfer(EHCIQueue *q) { - int bufpos = 0; - int cpage, offset; - uint32_t head; - uint32_t tail; - + uint32_t cpage, offset, bytes, plen; + dma_addr_t page; - if (!bytes) - return 0; + cpage = get_field(q->qh.token, QTD_TOKEN_CPAGE); + bytes = get_field(q->qh.token, QTD_TOKEN_TBYTES); + offset = q->qh.bufptr[0] & ~QTD_BUFPTR_MASK; + pci_dma_sglist_init(&q->sgl, &q->ehci->dev, 5); - cpage = get_field(qh->token, QTD_TOKEN_CPAGE); - if (cpage > 4) { - fprintf(stderr, "cpage out of range (%d)\n", cpage); - return USB_RET_PROCERR; - } - - offset = qh->bufptr[0] & ~QTD_BUFPTR_MASK; - DPRINTF("ehci_buffer_rw: %sing %d bytes %08x cpage %d offset %d\n", - rw ? "writ" : "read", bytes, qh->bufptr[0], cpage, offset); - - do { - /* start and end of this page */ - head = qh->bufptr[cpage] & QTD_BUFPTR_MASK; - tail = head + ~QTD_BUFPTR_MASK + 1; - /* add offset into page */ - head |= offset; - - if (bytes <= (tail - head)) { - tail = head + bytes; + while (bytes > 0) { + if (cpage > 4) { + fprintf(stderr, "cpage out of range (%d)\n", cpage); + return USB_RET_PROCERR; } - DPRINTF("DATA %s cpage:%d head:%08X tail:%08X target:%08X\n", - rw ? "WRITE" : "READ ", cpage, head, tail, bufpos); - - cpu_physical_memory_rw(head, &buffer[bufpos], tail - head, rw); - - bufpos += (tail - head); - bytes -= (tail - head); - - if (bytes > 0) { - cpage++; + page = q->qh.bufptr[cpage] & QTD_BUFPTR_MASK; + page += offset; + plen = bytes; + if (plen > 4096 - offset) { + plen = 4096 - offset; offset = 0; + cpage++; } - } while (bytes > 0); - - /* save cpage */ - set_field(&qh->token, cpage, QTD_TOKEN_CPAGE); - - /* save offset into cpage */ - offset = tail - head; - qh->bufptr[0] &= ~QTD_BUFPTR_MASK; - qh->bufptr[0] |= offset; + qemu_sglist_add(&q->sgl, page, plen); + bytes -= plen; + } return 0; } -static void ehci_async_complete_packet(USBPacket *packet, void *opaque) +static void ehci_finish_transfer(EHCIQueue *q, int status) { - EHCIState *ehci = opaque; + uint32_t cpage, offset; + + qemu_sglist_destroy(&q->sgl); - DPRINTF("Async packet complete\n"); - ehci->async_complete = 1; - ehci->exec_status = packet->len; + if (status > 0) { + /* update cpage & offset */ + cpage = get_field(q->qh.token, QTD_TOKEN_CPAGE); + offset = q->qh.bufptr[0] & ~QTD_BUFPTR_MASK; + + offset += status; + cpage += offset >> QTD_BUFPTR_SH; + offset &= ~QTD_BUFPTR_MASK; + + set_field(&q->qh.token, cpage, QTD_TOKEN_CPAGE); + q->qh.bufptr[0] &= QTD_BUFPTR_MASK; + q->qh.bufptr[0] |= offset; + } } -static int ehci_execute_complete(EHCIState *ehci, - EHCIqh *qh, - int ret) +static void ehci_async_complete_packet(USBPort *port, USBPacket *packet) { - int i, c_err, reload; + EHCIQueue *q; + EHCIState *s = port->opaque; + uint32_t portsc = s->portsc[port->index]; - if (ret == USB_RET_ASYNC && !ehci->async_complete) { - DPRINTF("not done yet\n"); - return ret; + if (portsc & PORTSC_POWNER) { + USBPort *companion = s->companion_ports[port->index]; + companion->ops->complete(companion, packet); + return; } - ehci->async_complete = 0; - i = ehci->async_port_in_progress; - ehci->async_port_in_progress = -1; + q = container_of(packet, EHCIQueue, packet); + trace_usb_ehci_queue_action(q, "wakeup"); + assert(q->async == EHCI_ASYNC_INFLIGHT); + q->async = EHCI_ASYNC_FINISHED; + q->usb_status = packet->result; +} + +static void ehci_execute_complete(EHCIQueue *q) +{ + int c_err, reload; + + assert(q->async != EHCI_ASYNC_INFLIGHT); + q->async = EHCI_ASYNC_NONE; DPRINTF("execute_complete: qhaddr 0x%x, next %x, qtdaddr 0x%x, status %d\n", - ehci->qhaddr, qh->next, ehci->qtdaddr, ret); + q->qhaddr, q->qh.next, q->qtdaddr, q->usb_status); - if (ret < 0) { + if (q->usb_status < 0) { err: /* TO-DO: put this is in a function that can be invoked below as well */ - c_err = get_field(qh->token, QTD_TOKEN_CERR); + c_err = get_field(q->qh.token, QTD_TOKEN_CERR); c_err--; - set_field(&qh->token, c_err, QTD_TOKEN_CERR); + set_field(&q->qh.token, c_err, QTD_TOKEN_CERR); - switch(ret) { + switch(q->usb_status) { case USB_RET_NODEV: - fprintf(stderr, "USB no device\n"); + q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_XACTERR); + ehci_record_interrupt(q->ehci, USBSTS_ERRINT); break; case USB_RET_STALL: - fprintf(stderr, "USB stall\n"); - qh->token |= QTD_TOKEN_HALT; + q->qh.token |= QTD_TOKEN_HALT; + ehci_record_interrupt(q->ehci, USBSTS_ERRINT); break; case USB_RET_NAK: /* 4.10.3 */ - reload = get_field(qh->epchar, QH_EPCHAR_RL); - if ((ehci->pid == USB_TOKEN_IN) && reload) { - int nakcnt = get_field(qh->altnext_qtd, QH_ALTNEXT_NAKCNT); + reload = get_field(q->qh.epchar, QH_EPCHAR_RL); + if ((q->pid == USB_TOKEN_IN) && reload) { + int nakcnt = get_field(q->qh.altnext_qtd, QH_ALTNEXT_NAKCNT); nakcnt--; - set_field(&qh->altnext_qtd, nakcnt, QH_ALTNEXT_NAKCNT); + set_field(&q->qh.altnext_qtd, nakcnt, QH_ALTNEXT_NAKCNT); } else if (!reload) { - return USB_RET_NAK; + return; } break; case USB_RET_BABBLE: - fprintf(stderr, "USB babble TODO\n"); - qh->token |= QTD_TOKEN_BABBLE; + q->qh.token |= (QTD_TOKEN_HALT | QTD_TOKEN_BABBLE); + ehci_record_interrupt(q->ehci, USBSTS_ERRINT); break; default: - fprintf(stderr, "USB invalid response %d to handle\n", ret); - /* TO-DO: transaction error */ - ret = USB_RET_PROCERR; + /* should not be triggerable */ + fprintf(stderr, "USB invalid response %d to handle\n", q->usb_status); + assert(0); break; } } else { // DPRINTF("Short packet condition\n"); // TODO check 4.12 for splits - if ((ret > ehci->tbytes) && (ehci->pid == USB_TOKEN_IN)) { - ret = USB_RET_BABBLE; + if ((q->usb_status > q->tbytes) && (q->pid == USB_TOKEN_IN)) { + q->usb_status = USB_RET_BABBLE; goto err; } - if (ehci->tbytes && ehci->pid == USB_TOKEN_IN) { - if (ehci_buffer_rw(ehci->buffer, qh, ret, 1) != 0) { - return USB_RET_PROCERR; - } - ehci->tbytes -= ret; + if (q->tbytes && q->pid == USB_TOKEN_IN) { + q->tbytes -= q->usb_status; } else { - ehci->tbytes = 0; + q->tbytes = 0; } - DPRINTF("updating tbytes to %d\n", ehci->tbytes); - set_field(&qh->token, ehci->tbytes, QTD_TOKEN_TBYTES); + DPRINTF("updating tbytes to %d\n", q->tbytes); + set_field(&q->qh.token, q->tbytes, QTD_TOKEN_TBYTES); } + ehci_finish_transfer(q, q->usb_status); + usb_packet_unmap(&q->packet); - qh->token ^= QTD_TOKEN_DTOGGLE; - qh->token &= ~QTD_TOKEN_ACTIVE; + q->qh.token ^= QTD_TOKEN_DTOGGLE; + q->qh.token &= ~QTD_TOKEN_ACTIVE; - if ((ret >= 0) && (qh->token & QTD_TOKEN_IOC)) { - // TODO should do this after writeback to memory - ehci_set_interrupt(ehci, USBSTS_INT); + if ((q->usb_status >= 0) && (q->qh.token & QTD_TOKEN_IOC)) { + ehci_record_interrupt(q->ehci, USBSTS_INT); } - - return ret; } // 4.10.3 -static int ehci_execute(EHCIState *ehci, EHCIqh *qh) +static int ehci_execute(EHCIQueue *q) { USBPort *port; USBDevice *dev; @@ -1039,76 +1337,65 @@ static int ehci_execute(EHCIState *ehci, EHCIqh *qh) int endp; int devadr; - if ( !(qh->token & QTD_TOKEN_ACTIVE)) { + if ( !(q->qh.token & QTD_TOKEN_ACTIVE)) { fprintf(stderr, "Attempting to execute inactive QH\n"); return USB_RET_PROCERR; } - ehci->tbytes = (qh->token & QTD_TOKEN_TBYTES_MASK) >> QTD_TOKEN_TBYTES_SH; - if (ehci->tbytes > BUFF_SIZE) { + q->tbytes = (q->qh.token & QTD_TOKEN_TBYTES_MASK) >> QTD_TOKEN_TBYTES_SH; + if (q->tbytes > BUFF_SIZE) { fprintf(stderr, "Request for more bytes than allowed\n"); return USB_RET_PROCERR; } - ehci->pid = (qh->token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH; - switch(ehci->pid) { - case 0: ehci->pid = USB_TOKEN_OUT; break; - case 1: ehci->pid = USB_TOKEN_IN; break; - case 2: ehci->pid = USB_TOKEN_SETUP; break; + q->pid = (q->qh.token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH; + switch(q->pid) { + case 0: q->pid = USB_TOKEN_OUT; break; + case 1: q->pid = USB_TOKEN_IN; break; + case 2: q->pid = USB_TOKEN_SETUP; break; default: fprintf(stderr, "bad token\n"); break; } - if ((ehci->tbytes && ehci->pid != USB_TOKEN_IN) && - (ehci_buffer_rw(ehci->buffer, qh, ehci->tbytes, 0) != 0)) { + if (ehci_init_transfer(q) != 0) { return USB_RET_PROCERR; } - endp = get_field(qh->epchar, QH_EPCHAR_EP); - devadr = get_field(qh->epchar, QH_EPCHAR_DEVADDR); + endp = get_field(q->qh.epchar, QH_EPCHAR_EP); + devadr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR); ret = USB_RET_NODEV; + usb_packet_setup(&q->packet, q->pid, devadr, endp); + usb_packet_map(&q->packet, &q->sgl); + // TO-DO: associating device with ehci port - for (i = 0; i < NB_PORTS; i++) { - port = &ehci->ports[i]; + for(i = 0; i < NB_PORTS; i++) { + port = &q->ehci->ports[i]; dev = port->dev; - // TODO sometime we will also need to check if we are the port owner - - if (!(ehci->portsc[i] &(PORTSC_CONNECT))) { + if (!(q->ehci->portsc[i] &(PORTSC_CONNECT))) { DPRINTF("Port %d, no exec, not connected(%08X)\n", - i, ehci->portsc[i]); + i, q->ehci->portsc[i]); continue; } - ehci->usb_packet.pid = ehci->pid; - ehci->usb_packet.devaddr = devadr; - ehci->usb_packet.devep = endp; - ehci->usb_packet.data = ehci->buffer; - ehci->usb_packet.len = ehci->tbytes; - ehci->usb_packet.complete_cb = ehci_async_complete_packet; - ehci->usb_packet.complete_opaque = ehci; - - ret = dev->info->handle_packet(dev, &ehci->usb_packet); + ret = usb_handle_packet(dev, &q->packet); - DPRINTF("submit: qh %x next %x qtd %x pid %x len %d (total %d) endp %x ret %d\n", - ehci->qhaddr, qh->next, ehci->qtdaddr, ehci->pid, - ehci->usb_packet.len, ehci->tbytes, endp, ret); + DPRINTF("submit: qh %x next %x qtd %x pid %x len %zd " + "(total %d) endp %x ret %d\n", + q->qhaddr, q->qh.next, q->qtdaddr, q->pid, + q->packet.iov.size, q->tbytes, endp, ret); - if (ret != USB_RET_NODEV) + if (ret != USB_RET_NODEV) { break; + } } if (ret > BUFF_SIZE) { - fprintf(stderr, "ret from handle packet > BUFF_SIZE\n"); + fprintf(stderr, "ret from usb_handle_packet > BUFF_SIZE\n"); return USB_RET_PROCERR; } - if (ret == USB_RET_ASYNC) { - ehci->async_port_in_progress = i; - ehci->async_complete = 0; - } - return ret; } @@ -1116,204 +1403,181 @@ static int ehci_execute(EHCIState *ehci, EHCIqh *qh) */ static int ehci_process_itd(EHCIState *ehci, - EHCIitd *itd) + EHCIitd *itd) { USBPort *port; USBDevice *dev; int ret; - int i, j; - int ptr; - int pid; - int pg; - int len; - int dir; - int devadr; - int endp; - int maxpkt; + uint32_t i, j, len, pid, dir, devaddr, endp; + uint32_t pg, off, ptr1, ptr2, max, mult; dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION); - devadr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR); + devaddr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR); endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP); - maxpkt = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT); + max = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT); + mult = get_field(itd->bufptr[2], ITD_BUFPTR_MULT); -#ifdef EHCI_NOMICROFRAMES for(i = 0; i < 8; i++) { -#else - i =(ehci->frindex & 7); -#endif - - if (itd->transact[i] & ITD_XACT_ACTIVE) { - DPRINTF("ISOCHRONOUS active for frame %d, interval %d\n", - ehci->frindex >> 3, i); + if (itd->transact[i] & ITD_XACT_ACTIVE) { + pg = get_field(itd->transact[i], ITD_XACT_PGSEL); + off = itd->transact[i] & ITD_XACT_OFFSET_MASK; + ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK); + ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK); + len = get_field(itd->transact[i], ITD_XACT_LENGTH); + + if (len > max * mult) { + len = max * mult; + } - pg = get_field(itd->transact[i], ITD_XACT_PGSEL); - ptr = (itd->bufptr[pg] & ITD_BUFPTR_MASK) | - (itd->transact[i] & ITD_XACT_OFFSET_MASK); - len = get_field(itd->transact[i], ITD_XACT_LENGTH); + if (len > BUFF_SIZE) { + return USB_RET_PROCERR; + } - if (len > BUFF_SIZE) { - return USB_RET_PROCERR; - } + pci_dma_sglist_init(&ehci->isgl, &ehci->dev, 2); + if (off + len > 4096) { + /* transfer crosses page border */ + uint32_t len2 = off + len - 4096; + uint32_t len1 = len - len2; + qemu_sglist_add(&ehci->isgl, ptr1 + off, len1); + qemu_sglist_add(&ehci->isgl, ptr2, len2); + } else { + qemu_sglist_add(&ehci->isgl, ptr1 + off, len); + } - DPRINTF("ISOCH: buffer %08X len %d\n", ptr, len); + pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT; - if (!dir) { - cpu_physical_memory_rw(ptr, &ehci->buffer[0], len, 0); - pid = USB_TOKEN_OUT; - } else - pid = USB_TOKEN_IN; + usb_packet_setup(&ehci->ipacket, pid, devaddr, endp); + usb_packet_map(&ehci->ipacket, &ehci->isgl); - ret = USB_RET_NODEV; + ret = USB_RET_NODEV; + for (j = 0; j < NB_PORTS; j++) { + port = &ehci->ports[j]; + dev = port->dev; - for(j = 0; j < NB_PORTS; j++) { - port = &ehci->ports[j]; - dev = port->dev; + if (!(ehci->portsc[j] &(PORTSC_CONNECT))) { + continue; + } - // TODO sometime we will also need to check if we are the port owner + ret = usb_handle_packet(dev, &ehci->ipacket); - if (!(ehci->portsc[j] &(PORTSC_CONNECT))) { - DPRINTF("Port %d, no exec, not connected(%08X)\n", - j, ehci->portsc[j]); - continue; + if (ret != USB_RET_NODEV) { + break; + } } - ehci->usb_packet.pid = ehci->pid; - ehci->usb_packet.devaddr = devadr; - ehci->usb_packet.devep = endp; - ehci->usb_packet.data = ehci->buffer; - ehci->usb_packet.len = len; - ehci->usb_packet.complete_cb = ehci_async_complete_packet; - ehci->usb_packet.complete_opaque = ehci; - - DPRINTF("calling dev->info->handle_packet\n"); - ret = dev->info->handle_packet(dev, &ehci->usb_packet); - - if (ret != USB_RET_NODEV) - break; - } + usb_packet_unmap(&ehci->ipacket); + qemu_sglist_destroy(&ehci->isgl); - /* In isoch, there is no facility to indicate a NAK so let's - * instead just complete a zero-byte transaction. Setting - * DBERR seems too draconian. - */ +#if 0 + /* In isoch, there is no facility to indicate a NAK so let's + * instead just complete a zero-byte transaction. Setting + * DBERR seems too draconian. + */ - if (ret == USB_RET_NAK) { - if (ehci->isoch_pause > 0) { - DPRINTF("ISOCH: received a NAK but paused so returning\n"); - ehci->isoch_pause--; - return 0; - } else if (ehci->isoch_pause == -1) { - DPRINTF("ISOCH: recv NAK & isoch pause inactive, setting\n"); - // Pause frindex for up to 50 msec waiting for data from - // remote - ehci->isoch_pause = 50; - return 0; + if (ret == USB_RET_NAK) { + if (ehci->isoch_pause > 0) { + DPRINTF("ISOCH: received a NAK but paused so returning\n"); + ehci->isoch_pause--; + return 0; + } else if (ehci->isoch_pause == -1) { + DPRINTF("ISOCH: recv NAK & isoch pause inactive, setting\n"); + // Pause frindex for up to 50 msec waiting for data from + // remote + ehci->isoch_pause = 50; + return 0; + } else { + DPRINTF("ISOCH: isoch pause timeout! return 0\n"); + ret = 0; + } } else { - DPRINTF("ISOCH: isoch pause timeout! return 0\n"); - ret = 0; + DPRINTF("ISOCH: received ACK, clearing pause\n"); + ehci->isoch_pause = -1; } - } else { - DPRINTF("ISOCH: received ACK, clearing pause\n"); - ehci->isoch_pause = -1; - } - - if (ret >= 0) { - itd->transact[i] &= ~ITD_XACT_ACTIVE; - - if (itd->transact[i] & ITD_XACT_IOC) { - // TODO should do this after writeback to memory - ehci_set_interrupt(ehci, USBSTS_INT); +#else + if (ret == USB_RET_NAK) { + ret = 0; } - } - - if (ret >= 0 && dir) { - cpu_physical_memory_rw(ptr, &ehci->buffer[0], len, 1); +#endif - if (ret != len) { - DPRINTF("ISOCH IN expected %d, got %d\n", - len, ret); - set_field(&itd->transact[i], ret, ITD_XACT_LENGTH); + if (ret >= 0) { + if (!dir) { + /* OUT */ + set_field(&itd->transact[i], len - ret, ITD_XACT_LENGTH); + } else { + /* IN */ + set_field(&itd->transact[i], ret, ITD_XACT_LENGTH); + } + + if (itd->transact[i] & ITD_XACT_IOC) { + ehci_record_interrupt(ehci, USBSTS_INT); + } } + itd->transact[i] &= ~ITD_XACT_ACTIVE; } } - -#ifdef EHCI_NOMICROFRAMES - } -#endif return 0; } /* This state is the entry point for asynchronous schedule * processing. Entry here consitutes a EHCI start event state (4.8.5) */ -static int ehci_state_waitlisthead(EHCIState *ehci, int async, int *state) +static int ehci_state_waitlisthead(EHCIState *ehci, int async) { - EHCIqh *qh = &ehci->qh; + EHCIqh qh; int i = 0; int again = 0; uint32_t entry = ehci->asynclistaddr; /* set reclamation flag at start event (4.8.6) */ if (async) { - ehci->usbsts |= USBSTS_REC; + ehci_set_usbsts(ehci, USBSTS_REC); } + ehci_queues_rip_unused(ehci); + /* Find the head of the list (4.9.1.1) */ for(i = 0; i < MAX_QH; i++) { - get_dwords(NLPTR_GET(entry), (uint32_t *) qh, sizeof(EHCIqh) >> 2); + get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &qh, + sizeof(EHCIqh) >> 2); + ehci_trace_qh(NULL, NLPTR_GET(entry), &qh); - if (qh->epchar & QH_EPCHAR_H) { - DPRINTF_ST("WAITLISTHEAD: QH %08X is the HEAD of the list\n", - entry); - if (async) + if (qh.epchar & QH_EPCHAR_H) { + if (async) { entry |= (NLPTR_TYPE_QH << 1); + } - ehci->fetch_addr = entry; - *state = EST_FETCHENTRY; + ehci_set_fetch_addr(ehci, async, entry); + ehci_set_state(ehci, async, EST_FETCHENTRY); again = 1; goto out; } - DPRINTF_ST("WAITLISTHEAD: QH %08X is NOT the HEAD of the list\n", - entry); - entry = qh->next; + entry = qh.next; if (entry == ehci->asynclistaddr) { - DPRINTF("WAITLISTHEAD: reached beginning of QH list\n"); break; } } /* no head found for list. */ - *state = EST_ACTIVE; + ehci_set_state(ehci, async, EST_ACTIVE); out: return again; } -/* This state is the entry point for periodic schedule processing as +/* This state is the entry point for periodic schedule processing as * well as being a continuation state for async processing. */ -static int ehci_state_fetchentry(EHCIState *ehci, int async, int *state) +static int ehci_state_fetchentry(EHCIState *ehci, int async) { int again = 0; - uint32_t entry = ehci->fetch_addr; + uint32_t entry = ehci_get_fetch_addr(ehci, async); -#if EHCI_DEBUG == 0 - if (qemu_get_clock(vm_clock) / 1000 >= ehci->frame_end_usec) { - if (async) { - DPRINTF("FETCHENTRY: FRAME timer elapsed, exit state machine\n"); - goto out; - } else { - DPRINTF("FETCHENTRY: WARNING " - "- frame timer elapsed during periodic\n"); - } - } -#endif if (entry < 0x1000) { DPRINTF("fetchentry: entry invalid (0x%08x)\n", entry); - *state = EST_ACTIVE; + ehci_set_state(ehci, async, EST_ACTIVE); goto out; } @@ -1325,21 +1589,22 @@ static int ehci_state_fetchentry(EHCIState *ehci, int async, int *state) switch (NLPTR_TYPE_GET(entry)) { case NLPTR_TYPE_QH: - DPRINTF_ST("FETCHENTRY: entry %X is a Queue Head\n", entry); - *state = EST_FETCHQH; - ehci->qhaddr = entry; + ehci_set_state(ehci, async, EST_FETCHQH); again = 1; break; case NLPTR_TYPE_ITD: - DPRINTF_ST("FETCHENTRY: entry %X is an ITD\n", entry); - *state = EST_FETCHITD; - ehci->itdaddr = entry; + ehci_set_state(ehci, async, EST_FETCHITD); + again = 1; + break; + + case NLPTR_TYPE_STITD: + ehci_set_state(ehci, async, EST_FETCHSITD); again = 1; break; default: - // TODO: handle siTD and FSTN types + /* TODO: handle FSTN type */ fprintf(stderr, "FETCHENTRY: entry at %X is of type %d " "which is not supported yet\n", entry, NLPTR_TYPE_GET(entry)); return -1; @@ -1349,88 +1614,139 @@ out: return again; } -static int ehci_state_fetchqh(EHCIState *ehci, int async, int *state) +static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async) { - EHCIqh *qh = &ehci->qh; + uint32_t entry; + EHCIQueue *q; int reload; - int again = 0; - get_dwords(NLPTR_GET(ehci->qhaddr), (uint32_t *) qh, sizeof(EHCIqh) >> 2); + entry = ehci_get_fetch_addr(ehci, async); + q = ehci_find_queue_by_qh(ehci, entry); + if (NULL == q) { + q = ehci_alloc_queue(ehci, async); + } + q->qhaddr = entry; + q->seen++; - if (async && (qh->epchar & QH_EPCHAR_H)) { + if (q->seen > 1) { + /* we are going in circles -- stop processing */ + ehci_set_state(ehci, async, EST_ACTIVE); + q = NULL; + goto out; + } + + get_dwords(ehci, NLPTR_GET(q->qhaddr), + (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2); + ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh); + + if (q->async == EHCI_ASYNC_INFLIGHT) { + /* I/O still in progress -- skip queue */ + ehci_set_state(ehci, async, EST_HORIZONTALQH); + goto out; + } + if (q->async == EHCI_ASYNC_FINISHED) { + /* I/O finished -- continue processing queue */ + trace_usb_ehci_queue_action(q, "resume"); + ehci_set_state(ehci, async, EST_EXECUTING); + goto out; + } + + if (async && (q->qh.epchar & QH_EPCHAR_H)) { /* EHCI spec version 1.0 Section 4.8.3 & 4.10.1 */ if (ehci->usbsts & USBSTS_REC) { - ehci->usbsts &= ~USBSTS_REC; + ehci_clear_usbsts(ehci, USBSTS_REC); } else { DPRINTF("FETCHQH: QH 0x%08x. H-bit set, reclamation status reset" - " - done processing\n", ehci->qhaddr); - *state = EST_ACTIVE; + " - done processing\n", q->qhaddr); + ehci_set_state(ehci, async, EST_ACTIVE); + q = NULL; goto out; } } #if EHCI_DEBUG - if (ehci->qhaddr != qh->next) { + if (q->qhaddr != q->qh.next) { DPRINTF("FETCHQH: QH 0x%08x (h %x halt %x active %x) next 0x%08x\n", - ehci->qhaddr, - qh->epchar & QH_EPCHAR_H, - qh->token & QTD_TOKEN_HALT, - qh->token & QTD_TOKEN_ACTIVE, - qh->next); + q->qhaddr, + q->qh.epchar & QH_EPCHAR_H, + q->qh.token & QTD_TOKEN_HALT, + q->qh.token & QTD_TOKEN_ACTIVE, + q->qh.next); } #endif - reload = get_field(qh->epchar, QH_EPCHAR_RL); + reload = get_field(q->qh.epchar, QH_EPCHAR_RL); if (reload) { - DPRINTF_ST("FETCHQH: reloading nakcnt to %d\n", reload); - set_field(&qh->altnext_qtd, reload, QH_ALTNEXT_NAKCNT); + set_field(&q->qh.altnext_qtd, reload, QH_ALTNEXT_NAKCNT); } - if (qh->token & QTD_TOKEN_HALT) { - DPRINTF_ST("FETCHQH: QH Halted, go horizontal\n"); - *state = EST_HORIZONTALQH; - again = 1; + if (q->qh.token & QTD_TOKEN_HALT) { + ehci_set_state(ehci, async, EST_HORIZONTALQH); - } else if ((qh->token & QTD_TOKEN_ACTIVE) && (qh->current_qtd > 0x1000)) { - DPRINTF_ST("FETCHQH: Active, !Halt, execute - fetch qTD\n"); - ehci->qtdaddr = qh->current_qtd; - *state = EST_FETCHQTD; - again = 1; + } else if ((q->qh.token & QTD_TOKEN_ACTIVE) && (q->qh.current_qtd > 0x1000)) { + q->qtdaddr = q->qh.current_qtd; + ehci_set_state(ehci, async, EST_FETCHQTD); } else { /* EHCI spec version 1.0 Section 4.10.2 */ - DPRINTF_ST("FETCHQH: !Active, !Halt, advance queue\n"); - *state = EST_ADVANCEQUEUE; - again = 1; + ehci_set_state(ehci, async, EST_ADVANCEQUEUE); } out: - return again; + return q; } -static int ehci_state_fetchitd(EHCIState *ehci, int async, int *state) +static int ehci_state_fetchitd(EHCIState *ehci, int async) { + uint32_t entry; EHCIitd itd; - get_dwords(NLPTR_GET(ehci->itdaddr),(uint32_t *) &itd, + assert(!async); + entry = ehci_get_fetch_addr(ehci, async); + + get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd, sizeof(EHCIitd) >> 2); - DPRINTF_ST("FETCHITD: Fetched ITD at address %08X " "(next is %08X)\n", - ehci->itdaddr, itd.next); + ehci_trace_itd(ehci, entry, &itd); - if (ehci_process_itd(ehci, &itd) != 0) + if (ehci_process_itd(ehci, &itd) != 0) { return -1; + } - put_dwords(NLPTR_GET(ehci->itdaddr), (uint32_t *) &itd, - sizeof(EHCIitd) >> 2); - ehci->itdaddr = itd.next; - *state = EST_FETCHITD; + put_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &itd, + sizeof(EHCIitd) >> 2); + ehci_set_fetch_addr(ehci, async, itd.next); + ehci_set_state(ehci, async, EST_FETCHENTRY); return 1; } +static int ehci_state_fetchsitd(EHCIState *ehci, int async) +{ + uint32_t entry; + EHCIsitd sitd; + + assert(!async); + entry = ehci_get_fetch_addr(ehci, async); + + get_dwords(ehci, NLPTR_GET(entry), (uint32_t *)&sitd, + sizeof(EHCIsitd) >> 2); + ehci_trace_sitd(ehci, entry, &sitd); + + if (!(sitd.results & SITD_RESULTS_ACTIVE)) { + /* siTD is not active, nothing to do */; + } else { + /* TODO: split transfers are not implemented */ + fprintf(stderr, "WARNING: Skipping active siTD\n"); + } + + ehci_set_fetch_addr(ehci, async, sitd.next); + ehci_set_state(ehci, async, EST_FETCHENTRY); + return 1; +} + /* Section 4.10.2 - paragraph 3 */ -static int ehci_state_advqueue(EHCIState *ehci, int async, int *state) +static int ehci_state_advqueue(EHCIQueue *q, int async) { #if 0 /* TO-DO: 4.10.2 - paragraph 2 @@ -1438,315 +1754,308 @@ static int ehci_state_advqueue(EHCIState *ehci, int async, int *state) * go to horizontal QH */ if (I-bit set) { - *state = EST_HORIZONTALQH; + ehci_set_state(ehci, async, EST_HORIZONTALQH); goto out; } #endif - /* + /* * want data and alt-next qTD is valid */ - if (((ehci->qh.token & QTD_TOKEN_TBYTES_MASK) != 0) && - (ehci->qh.altnext_qtd > 0x1000) && - (NLPTR_TBIT(ehci->qh.altnext_qtd) == 0)) { - DPRINTF_ST("ADVQUEUE: goto alt next qTD. " - "curr 0x%08x next 0x%08x alt 0x%08x (next qh %x)\n", - ehci->qh.current_qtd, ehci->qh.altnext_qtd, - ehci->qh.next_qtd, ehci->qh.next); - ehci->qtdaddr = ehci->qh.altnext_qtd; - *state = EST_FETCHQTD; + if (((q->qh.token & QTD_TOKEN_TBYTES_MASK) != 0) && + (q->qh.altnext_qtd > 0x1000) && + (NLPTR_TBIT(q->qh.altnext_qtd) == 0)) { + q->qtdaddr = q->qh.altnext_qtd; + ehci_set_state(q->ehci, async, EST_FETCHQTD); /* * next qTD is valid */ - } else if ((ehci->qh.next_qtd > 0x1000) && - (NLPTR_TBIT(ehci->qh.next_qtd) == 0)) { - DPRINTF_ST("ADVQUEUE: next qTD. " - "curr 0x%08x next 0x%08x alt 0x%08x (next qh %x)\n", - ehci->qh.current_qtd, ehci->qh.altnext_qtd, - ehci->qh.next_qtd, ehci->qh.next); - ehci->qtdaddr = ehci->qh.next_qtd; - *state = EST_FETCHQTD; + } else if ((q->qh.next_qtd > 0x1000) && + (NLPTR_TBIT(q->qh.next_qtd) == 0)) { + q->qtdaddr = q->qh.next_qtd; + ehci_set_state(q->ehci, async, EST_FETCHQTD); /* * no valid qTD, try next QH */ } else { - DPRINTF_ST("ADVQUEUE: go to horizontal QH\n"); - *state = EST_HORIZONTALQH; + ehci_set_state(q->ehci, async, EST_HORIZONTALQH); } return 1; } /* Section 4.10.2 - paragraph 4 */ -static int ehci_state_fetchqtd(EHCIState *ehci, int async, int *state) +static int ehci_state_fetchqtd(EHCIQueue *q, int async) { - EHCIqtd *qtd = &ehci->qtd; int again = 0; - get_dwords(NLPTR_GET(ehci->qtdaddr),(uint32_t *) qtd, sizeof(EHCIqtd) >> 2); + get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &q->qtd, + sizeof(EHCIqtd) >> 2); + ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &q->qtd); - if (qtd->token & QTD_TOKEN_ACTIVE) { - *state = EST_EXECUTE; + if (q->qtd.token & QTD_TOKEN_ACTIVE) { + ehci_set_state(q->ehci, async, EST_EXECUTE); again = 1; } else { - *state = EST_HORIZONTALQH; + ehci_set_state(q->ehci, async, EST_HORIZONTALQH); again = 1; } return again; } -static int ehci_state_horizqh(EHCIState *ehci, int async, int *state) +static int ehci_state_horizqh(EHCIQueue *q, int async) { int again = 0; - if (ehci->fetch_addr != ehci->qh.next) { - ehci->fetch_addr = ehci->qh.next; - *state = EST_FETCHENTRY; + if (ehci_get_fetch_addr(q->ehci, async) != q->qh.next) { + ehci_set_fetch_addr(q->ehci, async, q->qh.next); + ehci_set_state(q->ehci, async, EST_FETCHENTRY); again = 1; } else { - *state = EST_ACTIVE; + ehci_set_state(q->ehci, async, EST_ACTIVE); } return again; } -static int ehci_state_execute(EHCIState *ehci, int async, int *state) +/* + * Write the qh back to guest physical memory. This step isn't + * in the EHCI spec but we need to do it since we don't share + * physical memory with our guest VM. + * + * The first three dwords are read-only for the EHCI, so skip them + * when writing back the qh. + */ +static void ehci_flush_qh(EHCIQueue *q) +{ + uint32_t *qh = (uint32_t *) &q->qh; + uint32_t dwords = sizeof(EHCIqh) >> 2; + uint32_t addr = NLPTR_GET(q->qhaddr); + + put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3); +} + +static int ehci_state_execute(EHCIQueue *q, int async) { - EHCIqh *qh = &ehci->qh; - EHCIqtd *qtd = &ehci->qtd; int again = 0; int reload, nakcnt; int smask; - if (async) { - DPRINTF_ST(">>>>> ASYNC STATE MACHINE execute QH 0x%08x, QTD 0x%08x\n", - ehci->qhaddr, ehci->qtdaddr); - } else { - DPRINTF_ST(">>>>> PERIODIC STATE MACHINE execute\n"); - } - - if (ehci_qh_do_overlay(ehci, qh, qtd) != 0) + if (ehci_qh_do_overlay(q) != 0) { return -1; - - smask = get_field(qh->epcap, QH_EPCAP_SMASK); -#ifndef EHCI_NOMICROFRAMES - if (smask && (smask & (1 << (ehci->frindex & 7))) == 0) { - DPRINTF_ST("PERIODIC active not interval: mask %x, frindex %d,%d\n", - smask, (ehci->frindex >> 3),(ehci->frindex & 7)); - - *state = EST_HORIZONTALQH; - again = 1; - goto out; } -#endif + + smask = get_field(q->qh.epcap, QH_EPCAP_SMASK); if (!smask) { - reload = get_field(qh->epchar, QH_EPCHAR_RL); - nakcnt = get_field(qh->altnext_qtd, QH_ALTNEXT_NAKCNT); + reload = get_field(q->qh.epchar, QH_EPCHAR_RL); + nakcnt = get_field(q->qh.altnext_qtd, QH_ALTNEXT_NAKCNT); if (reload && !nakcnt) { - DPRINTF_ST("EXECUTE: RL != 0 but NakCnt == 0 -- no execute\n"); - *state = EST_HORIZONTALQH; + ehci_set_state(q->ehci, async, EST_HORIZONTALQH); again = 1; goto out; } } // TODO verify enough time remains in the uframe as in 4.4.1.1 - // TODO write back ptr to async list when done or out of time - // TODO Windows does not seem to ever set the MULT field - - if (!async) - { - int transactCtr = get_field(qh->epcap, QH_EPCAP_MULT); + if (!async) { + int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); if (!transactCtr) { - DPRINTF("ZERO transactctr for int qh, go HORIZ\n"); - *state = EST_HORIZONTALQH; + ehci_set_state(q->ehci, async, EST_HORIZONTALQH); again = 1; goto out; } } + if (async) { + ehci_set_usbsts(q->ehci, USBSTS_REC); + } - if (async) - ehci->usbsts |= USBSTS_REC; - - ehci->exec_status = ehci_execute(ehci, qh); - if (ehci->exec_status == USB_RET_PROCERR) { + q->usb_status = ehci_execute(q); + if (q->usb_status == USB_RET_PROCERR) { again = -1; goto out; } - *state = EST_EXECUTING; - - if (ehci->exec_status != USB_RET_ASYNC) + if (q->usb_status == USB_RET_ASYNC) { + ehci_flush_qh(q); + trace_usb_ehci_queue_action(q, "suspend"); + q->async = EHCI_ASYNC_INFLIGHT; + ehci_set_state(q->ehci, async, EST_HORIZONTALQH); again = 1; + goto out; + } + + ehci_set_state(q->ehci, async, EST_EXECUTING); + again = 1; out: return again; } -static int ehci_state_executing(EHCIState *ehci, int async, int *state) +static int ehci_state_executing(EHCIQueue *q, int async) { - EHCIqh *qh = &ehci->qh; int again = 0; int reload, nakcnt; - ehci->exec_status = ehci_execute_complete(ehci, qh, ehci->exec_status); - if (ehci->exec_status == USB_RET_ASYNC) { + ehci_execute_complete(q); + if (q->usb_status == USB_RET_ASYNC) { goto out; } - if (ehci->exec_status == USB_RET_PROCERR) { + if (q->usb_status == USB_RET_PROCERR) { again = -1; goto out; } // 4.10.3 if (!async) { - int transactCtr = get_field(qh->epcap, QH_EPCAP_MULT); + int transactCtr = get_field(q->qh.epcap, QH_EPCAP_MULT); transactCtr--; - set_field(&qh->epcap, transactCtr, QH_EPCAP_MULT); + set_field(&q->qh.epcap, transactCtr, QH_EPCAP_MULT); // 4.10.3, bottom of page 82, should exit this state when transaction // counter decrements to 0 } - - reload = get_field(qh->epchar, QH_EPCHAR_RL); + reload = get_field(q->qh.epchar, QH_EPCHAR_RL); if (reload) { - nakcnt = get_field(qh->altnext_qtd, QH_ALTNEXT_NAKCNT); - if (ehci->exec_status == USB_RET_NAK) { + nakcnt = get_field(q->qh.altnext_qtd, QH_ALTNEXT_NAKCNT); + if (q->usb_status == USB_RET_NAK) { if (nakcnt) { nakcnt--; } - DPRINTF_ST("EXECUTING: Nak occured and RL != 0, dec NakCnt to %d\n", - nakcnt); } else { nakcnt = reload; - DPRINTF_ST("EXECUTING: Nak didn't occur, reloading to %d\n", - nakcnt); } - set_field(&qh->altnext_qtd, nakcnt, QH_ALTNEXT_NAKCNT); + set_field(&q->qh.altnext_qtd, nakcnt, QH_ALTNEXT_NAKCNT); } - /* - * Write the qh back to guest physical memory. This step isn't - * in the EHCI spec but we need to do it since we don't share - * physical memory with our guest VM. - */ - - DPRINTF("EXECUTING: write QH to VM memory: qhaddr 0x%x, next 0x%x\n", - ehci->qhaddr, qh->next); - put_dwords(NLPTR_GET(ehci->qhaddr), (uint32_t *) qh, sizeof(EHCIqh) >> 2); - /* 4.10.5 */ - if ((ehci->exec_status == USB_RET_NAK) || (qh->token & QTD_TOKEN_ACTIVE)) { - *state = EST_HORIZONTALQH; + if ((q->usb_status == USB_RET_NAK) || (q->qh.token & QTD_TOKEN_ACTIVE)) { + ehci_set_state(q->ehci, async, EST_HORIZONTALQH); } else { - *state = EST_WRITEBACK; + ehci_set_state(q->ehci, async, EST_WRITEBACK); } again = 1; out: + ehci_flush_qh(q); return again; } -static int ehci_state_writeback(EHCIState *ehci, int async, int *state) +static int ehci_state_writeback(EHCIQueue *q, int async) { - EHCIqh *qh = &ehci->qh; int again = 0; /* Write back the QTD from the QH area */ - DPRINTF_ST("WRITEBACK: write QTD to VM memory\n"); - put_dwords(NLPTR_GET(ehci->qtdaddr),(uint32_t *) &qh->next_qtd, - sizeof(EHCIqtd) >> 2); + ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), (EHCIqtd*) &q->qh.next_qtd); + put_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &q->qh.next_qtd, + sizeof(EHCIqtd) >> 2); - /* TODO confirm next state. For now, keep going if async - * but stop after one qtd if periodic + /* + * EHCI specs say go horizontal here. + * + * We can also advance the queue here for performance reasons. We + * need to take care to only take that shortcut in case we've + * processed the qtd just written back without errors, i.e. halt + * bit is clear. */ - //if (async) { - *state = EST_ADVANCEQUEUE; + if (q->qh.token & QTD_TOKEN_HALT) { + ehci_set_state(q->ehci, async, EST_HORIZONTALQH); again = 1; - //} else { - // *state = EST_ACTIVE; - //} + } else { + ehci_set_state(q->ehci, async, EST_ADVANCEQUEUE); + again = 1; + } return again; } -/* - * This is the state machine that is common to both async and periodic +/* + * This is the state machine that is common to both async and periodic */ -static int ehci_advance_state(EHCIState *ehci, - int async, - int state) +static void ehci_advance_state(EHCIState *ehci, + int async) { + EHCIQueue *q = NULL; int again; int iter = 0; do { - if (state == EST_FETCHQH) { + if (ehci_get_state(ehci, async) == EST_FETCHQH) { iter++; /* if we are roaming a lot of QH without executing a qTD * something is wrong with the linked list. TO-DO: why is * this hack needed? */ + assert(iter < MAX_ITERATIONS); +#if 0 if (iter > MAX_ITERATIONS) { DPRINTF("\n*** advance_state: bailing on MAX ITERATIONS***\n"); - state = EST_ACTIVE; + ehci_set_state(ehci, async, EST_ACTIVE); break; } +#endif } - switch(state) { + switch(ehci_get_state(ehci, async)) { case EST_WAITLISTHEAD: - again = ehci_state_waitlisthead(ehci, async, &state); + again = ehci_state_waitlisthead(ehci, async); break; case EST_FETCHENTRY: - again = ehci_state_fetchentry(ehci, async, &state); + again = ehci_state_fetchentry(ehci, async); break; case EST_FETCHQH: - again = ehci_state_fetchqh(ehci, async, &state); + q = ehci_state_fetchqh(ehci, async); + again = q ? 1 : 0; break; case EST_FETCHITD: - again = ehci_state_fetchitd(ehci, async, &state); + again = ehci_state_fetchitd(ehci, async); + break; + + case EST_FETCHSITD: + again = ehci_state_fetchsitd(ehci, async); break; case EST_ADVANCEQUEUE: - again = ehci_state_advqueue(ehci, async, &state); + again = ehci_state_advqueue(q, async); break; case EST_FETCHQTD: - again = ehci_state_fetchqtd(ehci, async, &state); + again = ehci_state_fetchqtd(q, async); break; case EST_HORIZONTALQH: - again = ehci_state_horizqh(ehci, async, &state); + again = ehci_state_horizqh(q, async); break; case EST_EXECUTE: iter = 0; - again = ehci_state_execute(ehci, async, &state); + again = ehci_state_execute(q, async); break; case EST_EXECUTING: - again = ehci_state_executing(ehci, async, &state); + assert(q != NULL); + again = ehci_state_executing(q, async); break; case EST_WRITEBACK: - again = ehci_state_writeback(ehci, async, &state); + assert(q != NULL); + again = ehci_state_writeback(q, async); break; default: fprintf(stderr, "Bad state!\n"); again = -1; + assert(0); break; } @@ -1754,31 +2063,31 @@ static int ehci_advance_state(EHCIState *ehci, fprintf(stderr, "processing error - resetting ehci HC\n"); ehci_reset(ehci); again = 0; + assert(0); } } while (again); - return state; + ehci_commit_interrupt(ehci); } static void ehci_advance_async_state(EHCIState *ehci) { - EHCIqh qh; - int state = ehci->astate; + int async = 1; - switch(state) { + switch(ehci_get_state(ehci, async)) { case EST_INACTIVE: if (!(ehci->usbcmd & USBCMD_ASE)) { break; } - ehci->usbsts |= USBSTS_ASS; - ehci->astate = EST_ACTIVE; + ehci_set_usbsts(ehci, USBSTS_ASS); + ehci_set_state(ehci, async, EST_ACTIVE); // No break, fall through to ACTIVE case EST_ACTIVE: if ( !(ehci->usbcmd & USBCMD_ASE)) { - ehci->usbsts &= ~USBSTS_ASS; - ehci->astate = EST_INACTIVE; + ehci_clear_usbsts(ehci, USBSTS_ASS); + ehci_set_state(ehci, async, EST_INACTIVE); break; } @@ -1800,30 +2109,20 @@ static void ehci_advance_async_state(EHCIState *ehci) break; } - DPRINTF_ST("ASYNC: waiting for listhead, starting at %08x\n", - ehci->asynclistaddr); /* check that address register has been set */ if (ehci->asynclistaddr == 0) { break; } - state = EST_WAITLISTHEAD; - /* fall through */ - - case EST_FETCHENTRY: - /* fall through */ - - case EST_EXECUTING: - get_dwords(NLPTR_GET(ehci->qhaddr), (uint32_t *) &qh, - sizeof(EHCIqh) >> 2); - ehci->astate = ehci_advance_state(ehci, 1, state); + ehci_set_state(ehci, async, EST_WAITLISTHEAD); + ehci_advance_state(ehci, async); break; default: /* this should only be due to a developer mistake */ fprintf(stderr, "ehci: Bad asynchronous state %d. " "Resetting to active\n", ehci->astate); - ehci->astate = EST_ACTIVE; + assert(0); } } @@ -1831,24 +2130,23 @@ static void ehci_advance_periodic_state(EHCIState *ehci) { uint32_t entry; uint32_t list; + int async = 0; // 4.6 - switch(ehci->pstate) { + switch(ehci_get_state(ehci, async)) { case EST_INACTIVE: if ( !(ehci->frindex & 7) && (ehci->usbcmd & USBCMD_PSE)) { - DPRINTF("PERIODIC going active\n"); - ehci->usbsts |= USBSTS_PSS; - ehci->pstate = EST_ACTIVE; + ehci_set_usbsts(ehci, USBSTS_PSS); + ehci_set_state(ehci, async, EST_ACTIVE); // No break, fall through to ACTIVE } else break; case EST_ACTIVE: if ( !(ehci->frindex & 7) && !(ehci->usbcmd & USBCMD_PSE)) { - DPRINTF("PERIODIC going inactive\n"); - ehci->usbsts &= ~USBSTS_PSS; - ehci->pstate = EST_INACTIVE; + ehci_clear_usbsts(ehci, USBSTS_PSS); + ehci_set_state(ehci, async, EST_INACTIVE); break; } @@ -1859,25 +2157,21 @@ static void ehci_advance_periodic_state(EHCIState *ehci) } list |= ((ehci->frindex & 0x1ff8) >> 1); - cpu_physical_memory_rw(list, (uint8_t *) &entry, sizeof entry, 0); + pci_dma_read(&ehci->dev, list, (uint8_t *) &entry, sizeof entry); entry = le32_to_cpu(entry); DPRINTF("PERIODIC state adv fr=%d. [%08X] -> %08X\n", ehci->frindex / 8, list, entry); - ehci->fetch_addr = entry; - ehci->pstate = ehci_advance_state(ehci, 0, EST_FETCHENTRY); - break; - - case EST_EXECUTING: - DPRINTF("PERIODIC state adv for executing\n"); - ehci->pstate = ehci_advance_state(ehci, 0, EST_EXECUTING); + ehci_set_fetch_addr(ehci, async,entry); + ehci_set_state(ehci, async, EST_FETCHENTRY); + ehci_advance_state(ehci, async); break; default: /* this should only be due to a developer mistake */ fprintf(stderr, "ehci: Bad periodic state %d. " "Resetting to active\n", ehci->pstate); - ehci->pstate = EST_ACTIVE; + assert(0); } } @@ -1885,31 +2179,21 @@ static void ehci_frame_timer(void *opaque) { EHCIState *ehci = opaque; int64_t expire_time, t_now; - int usec_elapsed; + uint64_t ns_elapsed; int frames; - int usec_now; int i; int skipped_frames = 0; + t_now = qemu_get_clock_ns(vm_clock); + expire_time = t_now + (get_ticks_per_sec() / ehci->freq); - t_now = qemu_get_clock(vm_clock); - expire_time = t_now + (get_ticks_per_sec() / FRAME_TIMER_FREQ); - if (expire_time == t_now) - expire_time++; + ns_elapsed = t_now - ehci->last_run_ns; + frames = ns_elapsed / FRAME_TIMER_NS; - usec_now = t_now / 1000; - usec_elapsed = usec_now - ehci->last_run_usec; - frames = usec_elapsed / FRAME_TIMER_USEC; - ehci->frame_end_usec = usec_now + FRAME_TIMER_USEC - 10; - - for(i = 0; i < frames; i++) { + for (i = 0; i < frames; i++) { if ( !(ehci->usbsts & USBSTS_HALT)) { if (ehci->isoch_pause <= 0) { -#ifdef EHCI_NOMICROFRAMES ehci->frindex += 8; -#else - ehci->frindex++; -#endif } if (ehci->frindex > 0x00001fff) { @@ -1921,170 +2205,108 @@ static void ehci_frame_timer(void *opaque) ehci->sofv &= 0x000003ff; } - if (frames - i > 10) + if (frames - i > ehci->maxframes) { skipped_frames++; - else { - // TODO could this cause periodic frames to get skipped if async - // active? - if (ehci->astate != EST_EXECUTING) - ehci_advance_periodic_state(ehci); + } else { + ehci_advance_periodic_state(ehci); } - ehci->last_run_usec += FRAME_TIMER_USEC; + ehci->last_run_ns += FRAME_TIMER_NS; } #if 0 - if (skipped_frames) + if (skipped_frames) { DPRINTF("WARNING - EHCI skipped %d frames\n", skipped_frames); + } #endif /* Async is not inside loop since it executes everything it can once * called */ - if (ehci->pstate != EST_EXECUTING) - ehci_advance_async_state(ehci); + ehci_advance_async_state(ehci); qemu_mod_timer(ehci->frame_timer, expire_time); } -static CPUReadMemoryFunc *ehci_readfn[3]={ - ehci_mem_readb, - ehci_mem_readw, - ehci_mem_readl -}; -static CPUWriteMemoryFunc *ehci_writefn[3]={ - ehci_mem_writeb, - ehci_mem_writew, - ehci_mem_writel +static const MemoryRegionOps ehci_mem_ops = { + .old_mmio = { + .read = { ehci_mem_readb, ehci_mem_readw, ehci_mem_readl }, + .write = { ehci_mem_writeb, ehci_mem_writew, ehci_mem_writel }, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static void usb_ehci_save(QEMUFile *f, void *opaque) -{ - USBPort *ports = (USBPort *)opaque; - EHCIState *port_info; - uint32_t portsc; - int i; - - for (i = 0; i < NB_PORTS; i++) { - port_info = ports[i].opaque; - portsc = port_info->portsc[ports[i].index]; - if (portsc & PORTSC_CONNECT) { - hw_error("usb-ehci: some device is attached to usb-port. " - "SaveVM is not possible\n"); - } - } -} - -static int usb_ehci_load(QEMUFile *f, void *opaque, int version_id) -{ - if (version_id != 1) { - return -EINVAL; - } - - return 0; -} - -static void usb_ehci_init(EHCIState *s, DeviceState *dev, qemu_irq irq) -{ - int i; - - fprintf(stderr, "\n\n*** EHCI support is under development *** \n\n"); - s->irq = irq; - - // 2.2 host controller interface version - s->mmio[0x00] = (uint8_t) OPREGBASE; - s->mmio[0x01] = 0x00; - s->mmio[0x02] = 0x00; - s->mmio[0x03] = 0x01; // HC version - s->mmio[0x04] = NB_PORTS; // Number of downstream ports - s->mmio[0x05] = 0x00; // No companion ports at present - s->mmio[0x06] = 0x00; - s->mmio[0x07] = 0x00; - s->mmio[0x08] = 0x80; // We can cache whole frame, not 64-bit capable - s->mmio[0x09] = 0x68; // EECP - s->mmio[0x0a] = 0x00; - s->mmio[0x0b] = 0x00; - - // TODO - port registration is going to need an overhaul since ports - // can be low, full or high speed and are not tied to UHCI or EHCI. - // This works for now since we register last so are top of the free - // list but really all ports need to be owned by EHCI and it should - // hand off to companion controllers if device is full or low speed. - - DPRINTF("ehci_init : registering USB ports with no device attached\n"); - - // TODO come up with a better port allocation scheme - // added ehci->bus, need to find ehci->DeviceState - usb_bus_new(&s->bus, dev); - for (i = 0; i < NB_PORTS; i++) { - usb_register_port(&s->bus, &s->ports[i], s, i, ehci_attach, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - s->ports[i].dev = 0; - } - - s->frame_timer = qemu_new_timer(vm_clock, ehci_frame_timer, s); - - DPRINTF("ehci_init: calling ehci_reset\n"); - qemu_register_reset(ehci_reset, s); - - s->mem = cpu_register_io_memory(ehci_readfn, ehci_writefn, s, DEVICE_NATIVE_ENDIAN); +static int usb_ehci_initfn(PCIDevice *dev); - register_savevm(dev, "usb-ehci", -1, 1, - usb_ehci_save, usb_ehci_load, s->ports); -} - -typedef struct { - PCIDevice dev; - EHCIState state; -} EHCIPCIState; +static USBPortOps ehci_port_ops = { + .attach = ehci_attach, + .detach = ehci_detach, + .child_detach = ehci_child_detach, + .wakeup = ehci_wakeup, + .complete = ehci_async_complete_packet, +}; -static void ehci_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - EHCIPCIState *s = (EHCIPCIState *)pci_dev; +static USBBusOps ehci_bus_ops = { + .register_companion = ehci_register_companion, +}; - DPRINTF("ehci_map: region %d, addr %08llX, size %lld, s->mem %08X\n", - region_num, addr, size, s->state.mem); - s->state.mem_base = addr; - cpu_register_physical_memory(addr, size, s->state.mem); -} +static const VMStateDescription vmstate_ehci = { + .name = "ehci", + .unmigratable = 1, +}; -static int usb_ehci_initfn_pci(PCIDevice *dev); +static Property ehci_properties[] = { + DEFINE_PROP_UINT32("freq", EHCIState, freq, FRAME_TIMER_FREQ), + DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128), + DEFINE_PROP_END_OF_LIST(), +}; static PCIDeviceInfo ehci_info[] = { { - .qdev.name = "pci-ehci", - .qdev.size = sizeof(EHCIPCIState), - .init = usb_ehci_initfn_pci, + .qdev.name = "usb-ehci", + .qdev.size = sizeof(EHCIState), + .qdev.vmsd = &vmstate_ehci, + .init = usb_ehci_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */ + .revision = 0x10, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = ehci_properties, + },{ + .qdev.name = "ich9-usb-ehci1", + .qdev.size = sizeof(EHCIState), + .qdev.vmsd = &vmstate_ehci, + .init = usb_ehci_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1, + .revision = 0x03, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = ehci_properties, },{ /* end of list */ } }; -static int usb_ehci_initfn_pci(PCIDevice *dev) +static int usb_ehci_initfn(PCIDevice *dev) { - EHCIPCIState *s = DO_UPCAST(EHCIPCIState, dev, dev); + EHCIState *s = DO_UPCAST(EHCIState, dev, dev); uint8_t *pci_conf = s->dev.config; + int i; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82801D); - pci_set_byte(&pci_conf[PCI_REVISION_ID], 0x10); pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20); - pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB); - pci_set_byte(&pci_conf[PCI_HEADER_TYPE], PCI_HEADER_TYPE_NORMAL); /* capabilities pointer */ pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00); //pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50); - pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); // interrupt pin 3 + pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); /* interrupt pin D */ pci_set_byte(&pci_conf[PCI_MIN_GNT], 0); pci_set_byte(&pci_conf[PCI_MAX_LAT], 0); // pci_conf[0x50] = 0x01; // power management caps - pci_set_byte(&pci_conf[0x60], 0x20); // spec release number (2.1.4) + pci_set_byte(&pci_conf[USB_SBRN], USB_RELEASE_2); // release number (2.1.4) pci_set_byte(&pci_conf[0x61], 0x20); // frame length adjustment (2.1.5) pci_set_word(&pci_conf[0x62], 0x00); // port wake up capability (2.1.6) @@ -2101,26 +2323,38 @@ static int usb_ehci_initfn_pci(PCIDevice *dev) pci_conf[0x6e] = 0x00; pci_conf[0x6f] = 0xc0; // USBLEFCTLSTS - usb_ehci_init(&s->state, &dev->qdev, s->dev.irq[3]); + // 2.2 host controller interface version + s->mmio[0x00] = (uint8_t) OPREGBASE; + s->mmio[0x01] = 0x00; + s->mmio[0x02] = 0x00; + s->mmio[0x03] = 0x01; // HC version + s->mmio[0x04] = NB_PORTS; // Number of downstream ports + s->mmio[0x05] = 0x00; // No companion ports at present + s->mmio[0x06] = 0x00; + s->mmio[0x07] = 0x00; + s->mmio[0x08] = 0x80; // We can cache whole frame, not 64-bit capable + s->mmio[0x09] = 0x68; // EECP + s->mmio[0x0a] = 0x00; + s->mmio[0x0b] = 0x00; - DPRINTF("ehci_init: registering MMIO size %d\n", MMIO_SIZE); - pci_register_bar(&s->dev, 0, MMIO_SIZE, - PCI_BASE_ADDRESS_SPACE_MEMORY, ehci_map); - return 0; -} + s->irq = s->dev.irq[3]; -typedef struct { - SysBusDevice busdev; - EHCIState state; -} EHCISysBusState; + usb_bus_new(&s->bus, &ehci_bus_ops, &s->dev.qdev); + for(i = 0; i < NB_PORTS; i++) { + usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops, + USB_SPEED_MASK_HIGH); + s->ports[i].dev = 0; + } -static int usb_ehci_initfn_sysbus(SysBusDevice *dev) -{ - EHCISysBusState *s = FROM_SYSBUS(EHCISysBusState, dev); + s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s); + QTAILQ_INIT(&s->queues); + + qemu_register_reset(ehci_reset, s); + + memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE); + pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem); - sysbus_init_irq(dev, &s->state.irq); - usb_ehci_init(&s->state, &dev->qdev, s->state.irq); - sysbus_init_mmio(dev, 0x1000, s->state.mem); + fprintf(stderr, "*** EHCI support is under development ***\n"); return 0; } @@ -2128,16 +2362,9 @@ static int usb_ehci_initfn_sysbus(SysBusDevice *dev) static void ehci_register(void) { pci_qdev_register_many(ehci_info); - sysbus_register_dev("usb-ehci", sizeof(EHCISysBusState), - usb_ehci_initfn_sysbus); } device_init(ehci_register); -void usb_ehci_init_pci(PCIBus *bus, int devfn) -{ - pci_create_simple(bus, devfn, "pci-ehci"); -} - /* * vim: expandtab ts=4 */ diff --git a/hw/usb-ehci.h b/hw/usb-ehci.h deleted file mode 100644 index d3ade36..0000000 --- a/hw/usb-ehci.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef QEMU_USB_EHCI_H -#define QEMU_USB_EHCI_H - -#include "qemu-common.h" - -void usb_ehci_init_pci(PCIBus *bus, int devfn); - -#endif diff --git a/hw/usb-hid.c b/hw/usb-hid.c index b559c50..4d1a5d6 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -26,7 +26,12 @@ #include "console.h" #include "usb.h" #include "usb-desc.h" -#include "sysemu.h" +#include "qemu-timer.h" +#include "hid.h" + +#ifdef CONFIG_MARU +#include "../tizen/src/mloop_event.h" +#endif /* HID interface requests */ #define GET_REPORT 0xa101 @@ -41,48 +46,9 @@ #define USB_DT_REPORT 0x22 #define USB_DT_PHY 0x23 -#define USB_MOUSE 1 -#define USB_TABLET 2 -#define USB_KEYBOARD 3 - -typedef struct USBPointerEvent { - int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */ - int32_t dz, buttons_state; -} USBPointerEvent; - -#define QUEUE_LENGTH 16 /* should be enough for a triple-click */ -#define QUEUE_MASK (QUEUE_LENGTH-1u) -#define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK) - -typedef struct USBMouseState { - USBPointerEvent queue[QUEUE_LENGTH]; - int mouse_grabbed; - QEMUPutMouseEntry *eh_entry; -} USBMouseState; - -typedef struct USBKeyboardState { - uint32_t keycodes[QUEUE_LENGTH]; - uint16_t modifiers; - uint8_t leds; - uint8_t key[16]; - int32_t keys; -} USBKeyboardState; - typedef struct USBHIDState { USBDevice dev; - union { - USBMouseState ptr; - USBKeyboardState kbd; - }; - uint32_t head; /* index into circular queue */ - uint32_t n; - int kind; - int32_t protocol; - uint8_t idle; - int64_t next_idle_clock; - int changed; - void *datain_opaque; - void (*datain)(void *); + HIDState hid; } USBHIDState; enum { @@ -142,7 +108,6 @@ static const USBDescIface desc_iface_tablet = { .bInterfaceNumber = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CLASS_HID, - .bInterfaceSubClass = 0x01, /* boot */ .bInterfaceProtocol = 0x02, .ndesc = 1, .descs = (USBDescOther[]) { @@ -211,6 +176,7 @@ static const USBDescDevice desc_device_mouse = { .iConfiguration = STR_CONFIG_MOUSE, .bmAttributes = 0xa0, .bMaxPower = 50, + .nif = 1, .ifs = &desc_iface_mouse, }, }, @@ -227,6 +193,7 @@ static const USBDescDevice desc_device_tablet = { .iConfiguration = STR_CONFIG_TABLET, .bmAttributes = 0xa0, .bMaxPower = 50, + .nif = 1, .ifs = &desc_iface_tablet, }, }, @@ -243,6 +210,7 @@ static const USBDescDevice desc_device_keyboard = { .iConfiguration = STR_CONFIG_KEYBOARD, .bmAttributes = 0xa0, .bMaxPower = 50, + .nif = 1, .ifs = &desc_iface_keyboard, }, }, @@ -392,351 +360,34 @@ static const uint8_t qemu_keyboard_hid_report_descriptor[] = { 0xc0, /* End Collection */ }; -#define USB_HID_USAGE_ERROR_ROLLOVER 0x01 -#define USB_HID_USAGE_POSTFAIL 0x02 -#define USB_HID_USAGE_ERROR_UNDEFINED 0x03 - -/* Indices are QEMU keycodes, values are from HID Usage Table. Indices - * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */ -static const uint8_t usb_hid_usage_keys[0x100] = { - 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b, - 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c, - 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16, - 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33, - 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19, - 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55, - 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f, - 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59, - 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44, - 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, - 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46, - 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a, - 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d, - 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x91, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static void usb_hid_changed(USBHIDState *hs) -{ - hs->changed = 1; - - if (hs->datain) - hs->datain(hs->datain_opaque); - - usb_wakeup(&hs->dev); -} - -static void usb_pointer_event_clear(USBPointerEvent *e, int buttons) { - e->xdx = e->ydy = e->dz = 0; - e->buttons_state = buttons; -} - -static void usb_pointer_event_combine(USBPointerEvent *e, int xyrel, - int x1, int y1, int z1) { - if (xyrel) { - e->xdx += x1; - e->ydy += y1; - } else { - e->xdx = x1; - e->ydy = y1; - } - e->dz += z1; -} - -static void usb_pointer_event(void *opaque, - int x1, int y1, int z1, int buttons_state) +static void usb_hid_changed(HIDState *hs) { - USBHIDState *hs = opaque; - USBMouseState *s = &hs->ptr; - unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK; - unsigned previous_slot = (use_slot - 1) & QUEUE_MASK; - - /* We combine events where feasible to keep the queue small. We shouldn't - * combine anything with the first event of a particular button state, as - * that would change the location of the button state change. When the - * queue is empty, a second event is needed because we don't know if - * the first event changed the button state. */ - if (hs->n == QUEUE_LENGTH) { - /* Queue full. Discard old button state, combine motion normally. */ - s->queue[use_slot].buttons_state = buttons_state; - } else if (hs->n < 2 || - s->queue[use_slot].buttons_state != buttons_state || - s->queue[previous_slot].buttons_state != s->queue[use_slot].buttons_state) { - /* Cannot or should not combine, so add an empty item to the queue. */ - QUEUE_INCR(use_slot); - hs->n++; - usb_pointer_event_clear(&s->queue[use_slot], buttons_state); - } - usb_pointer_event_combine(&s->queue[use_slot], - hs->kind == USB_MOUSE, - x1, y1, z1); - usb_hid_changed(hs); -} + USBHIDState *us = container_of(hs, USBHIDState, hid); -static void usb_keyboard_event(void *opaque, int keycode) -{ - USBHIDState *hs = opaque; - USBKeyboardState *s = &hs->kbd; - int slot; - - if (hs->n == QUEUE_LENGTH) { - fprintf(stderr, "usb-kbd: warning: key event queue full\n"); - return; - } - slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++; - s->keycodes[slot] = keycode; - usb_hid_changed(hs); + usb_wakeup(&us->dev); } -static void usb_keyboard_process_keycode(USBHIDState *hs) +static void usb_hid_handle_reset(USBDevice *dev) { - USBKeyboardState *s = &hs->kbd; - uint8_t hid_code, key; - int i, keycode, slot; - - if (hs->n == 0) { - return; - } - slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--; - keycode = s->keycodes[slot]; - - key = keycode & 0x7f; - hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))]; - s->modifiers &= ~(1 << 8); - - switch (hid_code) { - case 0x00: - return; - - case 0xe0: - if (s->modifiers & (1 << 9)) { - s->modifiers ^= 3 << 8; - usb_hid_changed(hs); - return; - } - case 0xe1 ... 0xe7: - if (keycode & (1 << 7)) { - s->modifiers &= ~(1 << (hid_code & 0x0f)); - usb_hid_changed(hs); - return; - } - case 0xe8 ... 0xef: - s->modifiers |= 1 << (hid_code & 0x0f); - usb_hid_changed(hs); - return; - } + USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); - if (keycode & (1 << 7)) { - for (i = s->keys - 1; i >= 0; i --) - if (s->key[i] == hid_code) { - s->key[i] = s->key[-- s->keys]; - s->key[s->keys] = 0x00; - break; - } - if (i < 0) - return; - } else { - for (i = s->keys - 1; i >= 0; i --) - if (s->key[i] == hid_code) - break; - if (i < 0) { - if (s->keys < sizeof(s->key)) - s->key[s->keys ++] = hid_code; - } else - return; - } + hid_reset(&us->hid); } -static inline int int_clamp(int val, int vmin, int vmax) +static int usb_hid_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { - if (val < vmin) - return vmin; - else if (val > vmax) - return vmax; - else - return val; -} - -static int usb_pointer_poll(USBHIDState *hs, uint8_t *buf, int len) -{ - int dx, dy, dz, b, l; - int index; - USBMouseState *s = &hs->ptr; - USBPointerEvent *e; - - if (!s->mouse_grabbed) { - qemu_activate_mouse_event_handler(s->eh_entry); - s->mouse_grabbed = 1; - } - - /* When the buffer is empty, return the last event. Relative - movements will all be zero. */ - index = (hs->n ? hs->head : hs->head - 1); - e = &s->queue[index & QUEUE_MASK]; - - if (hs->kind == USB_MOUSE) { - dx = int_clamp(e->xdx, -127, 127); - dy = int_clamp(e->ydy, -127, 127); - e->xdx -= dx; - e->ydy -= dy; - } else { - dx = e->xdx; - dy = e->ydy; - } - dz = int_clamp(e->dz, -127, 127); - e->dz -= dz; - - b = 0; - if (e->buttons_state & MOUSE_EVENT_LBUTTON) - b |= 0x01; - if (e->buttons_state & MOUSE_EVENT_RBUTTON) - b |= 0x02; - if (e->buttons_state & MOUSE_EVENT_MBUTTON) - b |= 0x04; - - if (hs->n && - !e->dz && - (hs->kind == USB_TABLET || (!e->xdx && !e->ydy))) { - /* that deals with this event */ - QUEUE_INCR(hs->head); - hs->n--; - } - - /* Appears we have to invert the wheel direction */ - dz = 0 - dz; - l = 0; - switch (hs->kind) { - case USB_MOUSE: - if (len > l) - buf[l++] = b; - if (len > l) - buf[l++] = dx; - if (len > l) - buf[l++] = dy; - if (len > l) - buf[l++] = dz; - break; - - case USB_TABLET: - if (len > l) - buf[l++] = b; - if (len > l) - buf[l++] = dx & 0xff; - if (len > l) - buf[l++] = dx >> 8; - if (len > l) - buf[l++] = dy & 0xff; - if (len > l) - buf[l++] = dy >> 8; - if (len > l) - buf[l++] = dz; - break; - - default: - abort(); - } - - return l; -} - -static int usb_keyboard_poll(USBHIDState *hs, uint8_t *buf, int len) -{ - USBKeyboardState *s = &hs->kbd; - if (len < 2) - return 0; - - usb_keyboard_process_keycode(hs); - - buf[0] = s->modifiers & 0xff; - buf[1] = 0; - if (s->keys > 6) - memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2); - else - memcpy(buf + 2, s->key, MIN(8, len) - 2); - - return MIN(8, len); -} - -static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len) -{ - if (len > 0) { - int ledstate = 0; - /* 0x01: Num Lock LED - * 0x02: Caps Lock LED - * 0x04: Scroll Lock LED - * 0x08: Compose LED - * 0x10: Kana LED */ - s->leds = buf[0]; - if (s->leds & 0x04) - ledstate |= QEMU_SCROLL_LOCK_LED; - if (s->leds & 0x01) - ledstate |= QEMU_NUM_LOCK_LED; - if (s->leds & 0x02) - ledstate |= QEMU_CAPS_LOCK_LED; - kbd_put_ledstate(ledstate); - } - return 0; -} - -static void usb_mouse_handle_reset(USBDevice *dev) -{ - USBHIDState *s = (USBHIDState *)dev; - - memset(s->ptr.queue, 0, sizeof (s->ptr.queue)); - s->head = 0; - s->n = 0; - s->protocol = 1; -} - -static void usb_keyboard_handle_reset(USBDevice *dev) -{ - USBHIDState *s = (USBHIDState *)dev; - - qemu_add_kbd_event_handler(usb_keyboard_event, s); - memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes)); - s->head = 0; - s->n = 0; - memset(s->kbd.key, 0, sizeof (s->kbd.key)); - s->kbd.keys = 0; - s->protocol = 1; -} - -static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime) -{ - s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000; -} - -static int usb_hid_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) -{ - USBHIDState *s = (USBHIDState *)dev; + USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + HIDState *hs = &us->hid; int ret; - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { return ret; } ret = 0; - switch(request) { + switch (request) { case DeviceRequest | USB_REQ_GET_INTERFACE: data[0] = 0; ret = 1; @@ -746,17 +397,17 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value, break; /* hid specific requests */ case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { + switch (value >> 8) { case 0x22: - if (s->kind == USB_MOUSE) { + if (hs->kind == HID_MOUSE) { memcpy(data, qemu_mouse_hid_report_descriptor, sizeof(qemu_mouse_hid_report_descriptor)); ret = sizeof(qemu_mouse_hid_report_descriptor); - } else if (s->kind == USB_TABLET) { - memcpy(data, qemu_tablet_hid_report_descriptor, + } else if (hs->kind == HID_TABLET) { + memcpy(data, qemu_tablet_hid_report_descriptor, sizeof(qemu_tablet_hid_report_descriptor)); ret = sizeof(qemu_tablet_hid_report_descriptor); - } else if (s->kind == USB_KEYBOARD) { + } else if (hs->kind == HID_KEYBOARD) { memcpy(data, qemu_keyboard_hid_report_descriptor, sizeof(qemu_keyboard_hid_report_descriptor)); ret = sizeof(qemu_keyboard_hid_report_descriptor); @@ -767,36 +418,43 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value, } break; case GET_REPORT: - if (s->kind == USB_MOUSE || s->kind == USB_TABLET) - ret = usb_pointer_poll(s, data, length); - else if (s->kind == USB_KEYBOARD) - ret = usb_keyboard_poll(s, data, length); + if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { + ret = hid_pointer_poll(hs, data, length); + } else if (hs->kind == HID_KEYBOARD) { + ret = hid_keyboard_poll(hs, data, length); + } break; case SET_REPORT: - if (s->kind == USB_KEYBOARD) - ret = usb_keyboard_write(&s->kbd, data, length); - else + if (hs->kind == HID_KEYBOARD) { + ret = hid_keyboard_write(hs, data, length); + } else { goto fail; + } break; case GET_PROTOCOL: - if (s->kind != USB_KEYBOARD) + if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) { goto fail; + } ret = 1; - data[0] = s->protocol; + data[0] = hs->protocol; break; case SET_PROTOCOL: - if (s->kind != USB_KEYBOARD) + if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) { goto fail; + } ret = 0; - s->protocol = value; + hs->protocol = value; break; case GET_IDLE: ret = 1; - data[0] = s->idle; + data[0] = hs->idle; break; case SET_IDLE: - s->idle = (uint8_t) (value >> 8); - usb_hid_set_next_idle(s, qemu_get_clock(vm_clock)); + hs->idle = (uint8_t) (value >> 8); + hid_set_next_idle(hs, qemu_get_clock_ns(vm_clock)); + if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { + hid_pointer_activate(hs); + } ret = 0; break; default: @@ -809,23 +467,26 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value, static int usb_hid_handle_data(USBDevice *dev, USBPacket *p) { - USBHIDState *s = (USBHIDState *)dev; + USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); + HIDState *hs = &us->hid; + uint8_t buf[p->iov.size]; int ret = 0; - switch(p->pid) { + switch (p->pid) { case USB_TOKEN_IN: if (p->devep == 1) { - int64_t curtime = qemu_get_clock(vm_clock); - if (!s->changed && (!s->idle || s->next_idle_clock - curtime > 0)) + int64_t curtime = qemu_get_clock_ns(vm_clock); + if (!hid_has_events(hs) && + (!hs->idle || hs->next_idle_clock - curtime > 0)) { return USB_RET_NAK; - usb_hid_set_next_idle(s, curtime); - if (s->kind == USB_MOUSE || s->kind == USB_TABLET) { - ret = usb_pointer_poll(s, p->data, p->len); } - else if (s->kind == USB_KEYBOARD) { - ret = usb_keyboard_poll(s, p->data, p->len); + hid_set_next_idle(hs, curtime); + if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) { + ret = hid_pointer_poll(hs, buf, p->iov.size); + } else if (hs->kind == HID_KEYBOARD) { + ret = hid_keyboard_poll(hs, buf, p->iov.size); } - s->changed = s->n > 0; + usb_packet_copy(p, buf, ret); } else { goto fail; } @@ -841,95 +502,62 @@ static int usb_hid_handle_data(USBDevice *dev, USBPacket *p) static void usb_hid_handle_destroy(USBDevice *dev) { - USBHIDState *s = (USBHIDState *)dev; + USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); - switch(s->kind) { - case USB_KEYBOARD: - qemu_remove_kbd_event_handler(); - break; - default: - qemu_remove_mouse_event_handler(s->ptr.eh_entry); +#ifdef CONFIG_MARU + if (us->hid.kind == HID_KEYBOARD) { + mloop_evcmd_set_usbkbd(NULL); } +#endif + + hid_free(&us->hid); } static int usb_hid_initfn(USBDevice *dev, int kind) { - USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev); + USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev); usb_desc_init(dev); - s->kind = kind; - - if (s->kind == USB_MOUSE) { - s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, - 0, "QEMU USB Mouse"); - } else if (s->kind == USB_TABLET) { - s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, - 1, "QEMU USB Tablet"); - } - - /* Force poll routine to be run and grab input the first time. */ - s->changed = 1; + hid_init(&us->hid, kind, usb_hid_changed); return 0; } static int usb_tablet_initfn(USBDevice *dev) { - return usb_hid_initfn(dev, USB_TABLET); + return usb_hid_initfn(dev, HID_TABLET); } static int usb_mouse_initfn(USBDevice *dev) { - return usb_hid_initfn(dev, USB_MOUSE); + return usb_hid_initfn(dev, HID_MOUSE); } static int usb_keyboard_initfn(USBDevice *dev) { - return usb_hid_initfn(dev, USB_KEYBOARD); +#ifdef CONFIG_MARU + mloop_evcmd_set_usbkbd(dev); +#endif + return usb_hid_initfn(dev, HID_KEYBOARD); } -void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)) -{ - USBHIDState *s = (USBHIDState *)dev; - - s->datain_opaque = opaque; - s->datain = datain; -} - -static int usb_hid_post_load(void *opaque, int version_id) +static int usb_ptr_post_load(void *opaque, int version_id) { USBHIDState *s = opaque; - if (s->idle) { - usb_hid_set_next_idle(s, qemu_get_clock(vm_clock)); + if (s->dev.remote_wakeup) { + hid_pointer_activate(&s->hid); } return 0; } -static const VMStateDescription vmstate_usb_ptr_queue = { - .name = "usb-ptr-queue", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField []) { - VMSTATE_INT32(xdx, USBPointerEvent), - VMSTATE_INT32(ydy, USBPointerEvent), - VMSTATE_INT32(dz, USBPointerEvent), - VMSTATE_INT32(buttons_state, USBPointerEvent), - VMSTATE_END_OF_LIST() - } -}; static const VMStateDescription vmstate_usb_ptr = { .name = "usb-ptr", .version_id = 1, .minimum_version_id = 1, - .post_load = usb_hid_post_load, + .post_load = usb_ptr_post_load, .fields = (VMStateField []) { VMSTATE_USB_DEVICE(dev, USBHIDState), - VMSTATE_STRUCT_ARRAY(ptr.queue, USBHIDState, QUEUE_LENGTH, 0, - vmstate_usb_ptr_queue, USBPointerEvent), - VMSTATE_UINT32(head, USBHIDState), - VMSTATE_UINT32(n, USBHIDState), - VMSTATE_INT32(protocol, USBHIDState), - VMSTATE_UINT8(idle, USBHIDState), + VMSTATE_HID_POINTER_DEVICE(hid, USBHIDState), VMSTATE_END_OF_LIST() } }; @@ -938,18 +566,9 @@ static const VMStateDescription vmstate_usb_kbd = { .name = "usb-kbd", .version_id = 1, .minimum_version_id = 1, - .post_load = usb_hid_post_load, .fields = (VMStateField []) { VMSTATE_USB_DEVICE(dev, USBHIDState), - VMSTATE_UINT32_ARRAY(kbd.keycodes, USBHIDState, QUEUE_LENGTH), - VMSTATE_UINT32(head, USBHIDState), - VMSTATE_UINT32(n, USBHIDState), - VMSTATE_UINT16(kbd.modifiers, USBHIDState), - VMSTATE_UINT8(kbd.leds, USBHIDState), - VMSTATE_UINT8_ARRAY(kbd.key, USBHIDState, 16), - VMSTATE_INT32(kbd.keys, USBHIDState), - VMSTATE_INT32(protocol, USBHIDState), - VMSTATE_UINT8(idle, USBHIDState), + VMSTATE_HID_KEYBOARD_DEVICE(hid, USBHIDState), VMSTATE_END_OF_LIST() } }; @@ -964,7 +583,7 @@ static struct USBDeviceInfo hid_info[] = { .usb_desc = &desc_tablet, .init = usb_tablet_initfn, .handle_packet = usb_generic_handle_packet, - .handle_reset = usb_mouse_handle_reset, + .handle_reset = usb_hid_handle_reset, .handle_control = usb_hid_handle_control, .handle_data = usb_hid_handle_data, .handle_destroy = usb_hid_handle_destroy, @@ -977,7 +596,7 @@ static struct USBDeviceInfo hid_info[] = { .usb_desc = &desc_mouse, .init = usb_mouse_initfn, .handle_packet = usb_generic_handle_packet, - .handle_reset = usb_mouse_handle_reset, + .handle_reset = usb_hid_handle_reset, .handle_control = usb_hid_handle_control, .handle_data = usb_hid_handle_data, .handle_destroy = usb_hid_handle_destroy, @@ -990,7 +609,7 @@ static struct USBDeviceInfo hid_info[] = { .usb_desc = &desc_keyboard, .init = usb_keyboard_initfn, .handle_packet = usb_generic_handle_packet, - .handle_reset = usb_keyboard_handle_reset, + .handle_reset = usb_hid_handle_reset, .handle_control = usb_hid_handle_control, .handle_data = usb_hid_handle_data, .handle_destroy = usb_hid_handle_destroy, diff --git a/hw/usb-hub.c b/hw/usb-hub.c index 3dd31ba..e195937 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -119,6 +119,7 @@ static const USBDescDevice desc_device_hub = { .bNumInterfaces = 1, .bConfigurationValue = 1, .bmAttributes = 0xe0, + .nif = 1, .ifs = &desc_iface_hub, }, }, @@ -126,8 +127,8 @@ static const USBDescDevice desc_device_hub = { static const USBDesc desc_hub = { .id = { - .idVendor = 0, - .idProduct = 0, + .idVendor = 0x0409, + .idProduct = 0x55aa, .bcdDevice = 0x0101, .iManufacturer = STR_MANUFACTURER, .iProduct = STR_PRODUCT, @@ -137,74 +138,6 @@ static const USBDesc desc_hub = { .str = desc_strings, }; -static const uint8_t qemu_hub_dev_descriptor[] = { - 0x12, /* u8 bLength; */ - 0x01, /* u8 bDescriptorType; Device */ - 0x10, 0x01, /* u16 bcdUSB; v1.1 */ - - 0x09, /* u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* u8 bDeviceSubClass; */ - 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */ - 0x08, /* u8 bMaxPacketSize0; 8 Bytes */ - - 0x00, 0x00, /* u16 idVendor; */ - 0x00, 0x00, /* u16 idProduct; */ - 0x01, 0x01, /* u16 bcdDevice */ - - 0x03, /* u8 iManufacturer; */ - 0x02, /* u8 iProduct; */ - 0x01, /* u8 iSerialNumber; */ - 0x01 /* u8 bNumConfigurations; */ -}; - -/* XXX: patch interrupt size */ -static const uint8_t qemu_hub_config_descriptor[] = { - - /* one configuration */ - 0x09, /* u8 bLength; */ - 0x02, /* u8 bDescriptorType; Configuration */ - 0x19, 0x00, /* u16 wTotalLength; */ - 0x01, /* u8 bNumInterfaces; (1) */ - 0x01, /* u8 bConfigurationValue; */ - 0x00, /* u8 iConfiguration; */ - 0xe0, /* u8 bmAttributes; - Bit 7: must be set, - 6: Self-powered, - 5: Remote wakeup, - 4..0: resvd */ - 0x00, /* u8 MaxPower; */ - - /* USB 1.1: - * USB 2.0, single TT organization (mandatory): - * one interface, protocol 0 - * - * USB 2.0, multiple TT organization (optional): - * two interfaces, protocols 1 (like single TT) - * and 2 (multiple TT mode) ... config is - * sometimes settable - * NOT IMPLEMENTED - */ - - /* one interface */ - 0x09, /* u8 if_bLength; */ - 0x04, /* u8 if_bDescriptorType; Interface */ - 0x00, /* u8 if_bInterfaceNumber; */ - 0x00, /* u8 if_bAlternateSetting; */ - 0x01, /* u8 if_bNumEndpoints; */ - 0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */ - 0x00, /* u8 if_bInterfaceSubClass; */ - 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ - 0x00, /* u8 if_iInterface; */ - - /* one endpoint (status change endpoint) */ - 0x07, /* u8 ep_bLength; */ - 0x05, /* u8 ep_bDescriptorType; Endpoint */ - 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* u8 ep_bmAttributes; Interrupt */ - 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ - 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ -}; - static const uint8_t qemu_hub_hub_descriptor[] = { 0x00, /* u8 bLength; patched in later */ @@ -230,6 +163,7 @@ static void usb_hub_attach(USBPort *port1) } else { port->wPortStatus &= ~PORT_STAT_LOW_SPEED; } + usb_wakeup(&s->dev); } static void usb_hub_detach(USBPort *port1) @@ -237,6 +171,11 @@ static void usb_hub_detach(USBPort *port1) USBHubState *s = port1->opaque; USBHubPort *port = &s->ports[port1->index]; + usb_wakeup(&s->dev); + + /* Let upstream know the device on this port is gone */ + s->dev.port->ops->child_detach(s->dev.port, port1->dev); + port->wPortStatus &= ~PORT_STAT_CONNECTION; port->wPortChange |= PORT_STAT_C_CONNECTION; if (port->wPortStatus & PORT_STAT_ENABLE) { @@ -245,10 +184,18 @@ static void usb_hub_detach(USBPort *port1) } } -static void usb_hub_wakeup(USBDevice *dev) +static void usb_hub_child_detach(USBPort *port1, USBDevice *child) +{ + USBHubState *s = port1->opaque; + + /* Pass along upstream */ + s->dev.port->ops->child_detach(s->dev.port, child); +} + +static void usb_hub_wakeup(USBPort *port1) { - USBHubState *s = dev->port->opaque; - USBHubPort *port = &s->ports[dev->port->index]; + USBHubState *s = port1->opaque; + USBHubPort *port = &s->ports[port1->index]; if (port->wPortStatus & PORT_STAT_SUSPEND) { port->wPortChange |= PORT_STAT_C_SUSPEND; @@ -256,28 +203,50 @@ static void usb_hub_wakeup(USBDevice *dev) } } -static void usb_hub_handle_attach(USBDevice *dev) +static void usb_hub_complete(USBPort *port, USBPacket *packet) +{ + USBHubState *s = port->opaque; + + /* + * Just pass it along upstream for now. + * + * If we ever implement usb 2.0 split transactions this will + * become a little more complicated ... + * + * Can't use usb_packet_complete() here because packet->owner is + * cleared already, go call the ->complete() callback directly + * instead. + */ + s->dev.port->ops->complete(s->dev.port, packet); +} + +static void usb_hub_handle_reset(USBDevice *dev) { USBHubState *s = DO_UPCAST(USBHubState, dev, dev); + USBHubPort *port; int i; for (i = 0; i < NUM_PORTS; i++) { - usb_port_location(&s->ports[i].port, dev->port, i+1); + port = s->ports + i; + port->wPortStatus = PORT_STAT_POWER; + port->wPortChange = 0; + if (port->port.dev && port->port.dev->attached) { + port->wPortStatus |= PORT_STAT_CONNECTION; + port->wPortChange |= PORT_STAT_C_CONNECTION; + if (port->port.dev->speed == USB_SPEED_LOW) { + port->wPortStatus |= PORT_STAT_LOW_SPEED; + } + } } } -static void usb_hub_handle_reset(USBDevice *dev) -{ - /* XXX: do it */ -} - -static int usb_hub_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_hub_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { USBHubState *s = (USBHubState *)dev; int ret; - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { return ret; } @@ -342,7 +311,7 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value, port->wPortStatus |= PORT_STAT_SUSPEND; break; case PORT_RESET: - if (dev) { + if (dev && dev->attached) { usb_send_msg(dev, USB_MSG_RESET); port->wPortChange |= PORT_STAT_C_RESET; /* set enable bit */ @@ -437,11 +406,12 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p) if (p->devep == 1) { USBHubPort *port; unsigned int status; + uint8_t buf[4]; int i, n; n = (NUM_PORTS + 1 + 7) / 8; - if (p->len == 1) { /* FreeBSD workaround */ + if (p->iov.size == 1) { /* FreeBSD workaround */ n = 1; - } else if (n > p->len) { + } else if (n > p->iov.size) { return USB_RET_BABBLE; } status = 0; @@ -452,8 +422,9 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p) } if (status != 0) { for(i = 0; i < n; i++) { - p->data[i] = status >> (8 * i); + buf[i] = status >> (8 * i); } + usb_packet_copy(p, buf, n); ret = n; } else { ret = USB_RET_NAK; /* usb11 11.13.1 */ @@ -480,8 +451,8 @@ static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p) for(i = 0; i < NUM_PORTS; i++) { port = &s->ports[i]; dev = port->port.dev; - if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) { - ret = dev->info->handle_packet(dev, p); + if (dev && dev->attached && (port->wPortStatus & PORT_STAT_ENABLE)) { + ret = usb_handle_packet(dev, p); if (ret != USB_RET_NODEV) { return ret; } @@ -523,7 +494,9 @@ static void usb_hub_handle_destroy(USBDevice *dev) static USBPortOps usb_hub_port_ops = { .attach = usb_hub_attach, .detach = usb_hub_detach, + .child_detach = usb_hub_child_detach, .wakeup = usb_hub_wakeup, + .complete = usb_hub_complete, }; static int usb_hub_initfn(USBDevice *dev) @@ -538,9 +511,9 @@ static int usb_hub_initfn(USBDevice *dev) usb_register_port(usb_bus_from_device(dev), &port->port, s, i, &usb_hub_port_ops, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - port->wPortStatus = PORT_STAT_POWER; - port->wPortChange = 0; + usb_port_location(&port->port, dev->port, i+1); } + usb_hub_handle_reset(dev); return 0; } @@ -576,7 +549,6 @@ static struct USBDeviceInfo hub_info = { .usb_desc = &desc_hub, .init = usb_hub_initfn, .handle_packet = usb_hub_handle_packet, - .handle_attach = usb_hub_handle_attach, .handle_reset = usb_hub_handle_reset, .handle_control = usb_hub_handle_control, .handle_data = usb_hub_handle_data, diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 76f5b02..bb48c3b 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -4,7 +4,7 @@ * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. */ #include "qemu-common.h" @@ -18,6 +18,10 @@ #include "sysemu.h" #include "blockdev.h" +#ifdef CONFIG_MARU +#include "../tizen/src/mloop_event.h" +#endif + //#define DEBUG_MSD #ifdef DEBUG_MSD @@ -33,26 +37,32 @@ do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0) enum USBMSDMode { USB_MSDM_CBW, /* Command Block. */ - USB_MSDM_DATAOUT, /* Tranfer data to device. */ + USB_MSDM_DATAOUT, /* Transfer data to device. */ USB_MSDM_DATAIN, /* Transfer data from device. */ USB_MSDM_CSW /* Command Status. */ }; +struct usb_msd_csw { + uint32_t sig; + uint32_t tag; + uint32_t residue; + uint8_t status; +}; + typedef struct { USBDevice dev; enum USBMSDMode mode; uint32_t scsi_len; uint8_t *scsi_buf; - uint32_t usb_len; - uint8_t *usb_buf; uint32_t data_len; uint32_t residue; - uint32_t tag; + struct usb_msd_csw csw; + SCSIRequest *req; SCSIBus bus; BlockConf conf; + char *serial; SCSIDevice *scsi_dev; uint32_t removable; - int result; /* For async completion. */ USBPacket *packet; } MSDState; @@ -67,13 +77,6 @@ struct usb_msd_cbw { uint8_t cmd[16]; }; -struct usb_msd_csw { - uint32_t sig; - uint32_t tag; - uint32_t residue; - uint8_t status; -}; - enum { STR_MANUFACTURER = 1, STR_PRODUCT, @@ -119,6 +122,7 @@ static const USBDescDevice desc_device_full = { .bConfigurationValue = 1, .iConfiguration = STR_CONFIG_FULL, .bmAttributes = 0xc0, + .nif = 1, .ifs = &desc_iface_full, }, }, @@ -153,6 +157,7 @@ static const USBDescDevice desc_device_high = { .bConfigurationValue = 1, .iConfiguration = STR_CONFIG_HIGH, .bmAttributes = 0xc0, + .nif = 1, .ifs = &desc_iface_high, }, }, @@ -160,8 +165,8 @@ static const USBDescDevice desc_device_high = { static const USBDesc desc = { .id = { - .idVendor = 0, - .idProduct = 0, + .idVendor = 0x46f4, /* CRC16() of "QEMU" */ + .idProduct = 0x0001, .bcdDevice = 0, .iManufacturer = STR_MANUFACTURER, .iProduct = STR_PRODUCT, @@ -172,93 +177,103 @@ static const USBDesc desc = { .str = desc_strings, }; -static void usb_msd_copy_data(MSDState *s) +static void usb_msd_copy_data(MSDState *s, USBPacket *p) { uint32_t len; - len = s->usb_len; + len = p->iov.size - p->result; if (len > s->scsi_len) len = s->scsi_len; - if (s->mode == USB_MSDM_DATAIN) { - memcpy(s->usb_buf, s->scsi_buf, len); - } else { - memcpy(s->scsi_buf, s->usb_buf, len); - } - s->usb_len -= len; + usb_packet_copy(p, s->scsi_buf, len); s->scsi_len -= len; - s->usb_buf += len; s->scsi_buf += len; s->data_len -= len; if (s->scsi_len == 0 || s->data_len == 0) { - if (s->mode == USB_MSDM_DATAIN) { - s->scsi_dev->info->read_data(s->scsi_dev, s->tag); - } else if (s->mode == USB_MSDM_DATAOUT) { - s->scsi_dev->info->write_data(s->scsi_dev, s->tag); - } + scsi_req_continue(s->req); } } static void usb_msd_send_status(MSDState *s, USBPacket *p) { - struct usb_msd_csw csw; int len; - csw.sig = cpu_to_le32(0x53425355); - csw.tag = cpu_to_le32(s->tag); - csw.residue = s->residue; - csw.status = s->result; + DPRINTF("Command status %d tag 0x%x, len %zd\n", + s->csw.status, s->csw.tag, p->iov.size); - len = MIN(sizeof(csw), p->len); - memcpy(p->data, &csw, len); + assert(s->csw.sig == 0x53425355); + len = MIN(sizeof(s->csw), p->iov.size); + usb_packet_copy(p, &s->csw, len); + memset(&s->csw, 0, sizeof(s->csw)); } -static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag, - uint32_t arg) +static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) { - MSDState *s = DO_UPCAST(MSDState, dev.qdev, bus->qbus.parent); + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); USBPacket *p = s->packet; - if (tag != s->tag) { - fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", tag); - } - if (reason == SCSI_REASON_DONE) { - DPRINTF("Command complete %d\n", arg); - s->residue = s->data_len; - s->result = arg != 0; - if (s->packet) { - if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { - /* A deferred packet with no write data remaining must be - the status read packet. */ - usb_msd_send_status(s, p); - s->mode = USB_MSDM_CBW; - } else { - if (s->data_len) { - s->data_len -= s->usb_len; - if (s->mode == USB_MSDM_DATAIN) - memset(s->usb_buf, 0, s->usb_len); - s->usb_len = 0; - } - if (s->data_len == 0) - s->mode = USB_MSDM_CSW; - } - s->packet = NULL; - usb_packet_complete(p); - } else if (s->data_len == 0) { - s->mode = USB_MSDM_CSW; - } - return; - } - s->scsi_len = arg; - s->scsi_buf = s->scsi_dev->info->get_buf(s->scsi_dev, tag); + assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); + s->scsi_len = len; + s->scsi_buf = scsi_req_get_buf(req); if (p) { - usb_msd_copy_data(s); - if (s->usb_len == 0) { + usb_msd_copy_data(s, p); + p = s->packet; + if (p && p->result == p->iov.size) { /* Set s->packet to NULL before calling usb_packet_complete - because annother request may be issued before + because another request may be issued before usb_packet_complete returns. */ DPRINTF("Packet complete %p\n", p); s->packet = NULL; - usb_packet_complete(p); + usb_packet_complete(&s->dev, p); + } + } +} + +static void usb_msd_command_complete(SCSIRequest *req, uint32_t status) +{ + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); + USBPacket *p = s->packet; + + DPRINTF("Command complete %d tag 0x%x\n", status, req->tag); + s->residue = s->data_len; + + s->csw.sig = cpu_to_le32(0x53425355); + s->csw.tag = cpu_to_le32(req->tag); + s->csw.residue = s->residue; + s->csw.status = status != 0; + + if (s->packet) { + if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { + /* A deferred packet with no write data remaining must be + the status read packet. */ + usb_msd_send_status(s, p); + s->mode = USB_MSDM_CBW; + } else { + if (s->data_len) { + int len = (p->iov.size - p->result); + usb_packet_skip(p, len); + s->data_len -= len; + } + if (s->data_len == 0) { + s->mode = USB_MSDM_CSW; + } } + s->packet = NULL; + usb_packet_complete(&s->dev, p); + } else if (s->data_len == 0) { + s->mode = USB_MSDM_CSW; + } + scsi_req_unref(req); + s->req = NULL; +} + +static void usb_msd_request_cancelled(SCSIRequest *req) +{ + MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); + + if (req == s->req) { + scsi_req_unref(s->req); + s->req = NULL; + s->packet = NULL; + s->scsi_len = 0; } } @@ -267,16 +282,28 @@ static void usb_msd_handle_reset(USBDevice *dev) MSDState *s = (MSDState *)dev; DPRINTF("Reset\n"); + if (s->req) { + scsi_req_cancel(s->req); + } + assert(s->req == NULL); + + if (s->packet) { + USBPacket *p = s->packet; + s->packet = NULL; + p->result = USB_RET_STALL; + usb_packet_complete(dev, p); + } + s->mode = USB_MSDM_CBW; } -static int usb_msd_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_msd_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { MSDState *s = (MSDState *)dev; int ret; - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { return ret; } @@ -313,22 +340,22 @@ static int usb_msd_handle_control(USBDevice *dev, int request, int value, return ret; } -static void usb_msd_cancel_io(USBPacket *p, void *opaque) +static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p) { - MSDState *s = opaque; - s->scsi_dev->info->cancel_io(s->scsi_dev, s->tag); - s->packet = NULL; - s->scsi_len = 0; + MSDState *s = DO_UPCAST(MSDState, dev, dev); + + if (s->req) { + scsi_req_cancel(s->req); + } } static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) { MSDState *s = (MSDState *)dev; + uint32_t tag; int ret = 0; struct usb_msd_cbw cbw; uint8_t devep = p->devep; - uint8_t *data = p->data; - int len = p->len; switch (p->pid) { case USB_TOKEN_OUT: @@ -337,11 +364,11 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) switch (s->mode) { case USB_MSDM_CBW: - if (len != 31) { + if (p->iov.size != 31) { fprintf(stderr, "usb-msd: Bad CBW size"); goto fail; } - memcpy(&cbw, data, 31); + usb_packet_copy(p, &cbw, 31); if (le32_to_cpu(cbw.sig) != 0x43425355) { fprintf(stderr, "usb-msd: Bad signature %08x\n", le32_to_cpu(cbw.sig)); @@ -352,7 +379,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun); goto fail; } - s->tag = le32_to_cpu(cbw.tag); + tag = le32_to_cpu(cbw.tag); s->data_len = le32_to_cpu(cbw.data_len); if (s->data_len == 0) { s->mode = USB_MSDM_CSW; @@ -362,49 +389,47 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) s->mode = USB_MSDM_DATAOUT; } DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", - s->tag, cbw.flags, cbw.cmd_len, s->data_len); + tag, cbw.flags, cbw.cmd_len, s->data_len); s->residue = 0; - s->scsi_dev->info->send_command(s->scsi_dev, s->tag, cbw.cmd, 0); - /* ??? Should check that USB and SCSI data transfer - directions match. */ - if (s->residue == 0) { - if (s->mode == USB_MSDM_DATAIN) { - s->scsi_dev->info->read_data(s->scsi_dev, s->tag); - } else if (s->mode == USB_MSDM_DATAOUT) { - s->scsi_dev->info->write_data(s->scsi_dev, s->tag); - } + s->scsi_len = 0; + s->req = scsi_req_new(s->scsi_dev, tag, 0, cbw.cmd, NULL); + scsi_req_enqueue(s->req); + if (s->req && s->req->cmd.xfer != SCSI_XFER_NONE) { + scsi_req_continue(s->req); } - ret = len; + ret = p->result; break; case USB_MSDM_DATAOUT: - DPRINTF("Data out %d/%d\n", len, s->data_len); - if (len > s->data_len) + DPRINTF("Data out %zd/%d\n", p->iov.size, s->data_len); + if (p->iov.size > s->data_len) { goto fail; + } - s->usb_buf = data; - s->usb_len = len; if (s->scsi_len) { - usb_msd_copy_data(s); + usb_msd_copy_data(s, p); } - if (s->residue && s->usb_len) { - s->data_len -= s->usb_len; - if (s->data_len == 0) - s->mode = USB_MSDM_CSW; - s->usb_len = 0; + if (s->residue) { + int len = p->iov.size - p->result; + if (len) { + usb_packet_skip(p, len); + s->data_len -= len; + if (s->data_len == 0) { + s->mode = USB_MSDM_CSW; + } + } } - if (s->usb_len) { + if (p->result < p->iov.size) { DPRINTF("Deferring packet %p\n", p); - usb_defer_packet(p, usb_msd_cancel_io, s); s->packet = p; ret = USB_RET_ASYNC; } else { - ret = len; + ret = p->result; } break; default: - DPRINTF("Unexpected write (len %d)\n", len); + DPRINTF("Unexpected write (len %zd)\n", p->iov.size); goto fail; } break; @@ -415,53 +440,57 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) switch (s->mode) { case USB_MSDM_DATAOUT: - if (s->data_len != 0 || len < 13) + if (s->data_len != 0 || p->iov.size < 13) { goto fail; + } /* Waiting for SCSI write to complete. */ - usb_defer_packet(p, usb_msd_cancel_io, s); s->packet = p; ret = USB_RET_ASYNC; break; case USB_MSDM_CSW: - DPRINTF("Command status %d tag 0x%x, len %d\n", - s->result, s->tag, len); - if (len < 13) + if (p->iov.size < 13) { goto fail; + } - usb_msd_send_status(s, p); - s->mode = USB_MSDM_CBW; - ret = 13; + if (s->req) { + /* still in flight */ + s->packet = p; + ret = USB_RET_ASYNC; + } else { + usb_msd_send_status(s, p); + s->mode = USB_MSDM_CBW; + ret = 13; + } break; case USB_MSDM_DATAIN: - DPRINTF("Data in %d/%d, scsi_len %d\n", len, s->data_len, s->scsi_len); - if (len > s->data_len) - len = s->data_len; - s->usb_buf = data; - s->usb_len = len; + DPRINTF("Data in %zd/%d, scsi_len %d\n", + p->iov.size, s->data_len, s->scsi_len); if (s->scsi_len) { - usb_msd_copy_data(s); + usb_msd_copy_data(s, p); } - if (s->residue && s->usb_len) { - s->data_len -= s->usb_len; - memset(s->usb_buf, 0, s->usb_len); - if (s->data_len == 0) - s->mode = USB_MSDM_CSW; - s->usb_len = 0; + if (s->residue) { + int len = p->iov.size - p->result; + if (len) { + usb_packet_skip(p, len); + s->data_len -= len; + if (s->data_len == 0) { + s->mode = USB_MSDM_CSW; + } + } } - if (s->usb_len) { + if (p->result < p->iov.size) { DPRINTF("Deferring packet %p\n", p); - usb_defer_packet(p, usb_msd_cancel_io, s); s->packet = p; ret = USB_RET_ASYNC; } else { - ret = len; + ret = p->result; } break; default: - DPRINTF("Unexpected read (len %d)\n", len); + DPRINTF("Unexpected read (len %zd)\n", p->iov.size); goto fail; } break; @@ -476,16 +505,34 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) return ret; } +#ifdef CONFIG_MARU +static void usb_msd_handle_destroy(USBDevice *dev) +{ + mloop_evcmd_set_usbdisk(NULL); +} +#endif + static void usb_msd_password_cb(void *opaque, int err) { MSDState *s = opaque; if (!err) - usb_device_attach(&s->dev); - else + err = usb_device_attach(&s->dev); + + if (err) qdev_unplug(&s->dev.qdev); } +static const struct SCSIBusInfo usb_msd_scsi_info = { + .tcq = false, + .max_target = 0, + .max_lun = 0, + + .transfer_data = usb_msd_transfer_data, + .complete = usb_msd_command_complete, + .cancel = usb_msd_request_cancelled +}; + static int usb_msd_initfn(USBDevice *dev) { MSDState *s = DO_UPCAST(MSDState, dev, dev); @@ -506,17 +553,24 @@ static int usb_msd_initfn(USBDevice *dev) * * The hack is probably a bad idea. */ - bdrv_detach(bs, &s->dev.qdev); + bdrv_detach_dev(bs, &s->dev.qdev); s->conf.bs = NULL; - dinfo = drive_get_by_blockdev(bs); - if (dinfo && dinfo->serial) { - usb_desc_set_string(dev, STR_SERIALNUMBER, dinfo->serial); + if (!s->serial) { + /* try to fall back to value set with legacy -drive serial=... */ + dinfo = drive_get_by_blockdev(bs); + if (*dinfo->serial) { + s->serial = strdup(dinfo->serial); + } + } + if (s->serial) { + usb_desc_set_string(dev, STR_SERIALNUMBER, s->serial); } usb_desc_init(dev); - scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete); - s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable); + scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info); + s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable, + s->conf.bootindex); if (!s->scsi_dev) { return -1; } @@ -532,7 +586,6 @@ static int usb_msd_initfn(USBDevice *dev) } } - add_boot_device_path(s->conf.bootindex, &dev->qdev, "/disk@0,0"); return 0; } @@ -549,7 +602,7 @@ static USBDevice *usb_msd_init(const char *filename) /* parse -usbdevice disk: syntax into drive opts */ snprintf(id, sizeof(id), "usb%d", nr++); opts = qemu_opts_create(qemu_find_opts("drive"), id, 0); - +#ifndef CONFIG_MARU p1 = strchr(filename, ':'); if (p1++) { const char *p2; @@ -564,6 +617,7 @@ static USBDevice *usb_msd_init(const char *filename) } filename = p1; } +#endif if (!*filename) { printf("block device specification needed\n"); return NULL; @@ -590,25 +644,46 @@ static USBDevice *usb_msd_init(const char *filename) if (qdev_init(&dev->qdev) < 0) return NULL; +#ifdef CONFIG_MARU + mloop_evcmd_set_usbdisk(dev); +#endif + return dev; } +static const VMStateDescription vmstate_usb_msd = { + .name = "usb-storage", + .unmigratable = 1, /* FIXME: handle transactions which are in flight */ + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField []) { + VMSTATE_USB_DEVICE(dev, MSDState), + VMSTATE_END_OF_LIST() + } +}; + static struct USBDeviceInfo msd_info = { .product_desc = "QEMU USB MSD", .qdev.name = "usb-storage", .qdev.fw_name = "storage", .qdev.size = sizeof(MSDState), + .qdev.vmsd = &vmstate_usb_msd, .usb_desc = &desc, .init = usb_msd_initfn, .handle_packet = usb_generic_handle_packet, + .cancel_packet = usb_msd_cancel_io, .handle_attach = usb_desc_attach, .handle_reset = usb_msd_handle_reset, .handle_control = usb_msd_handle_control, .handle_data = usb_msd_handle_data, +#ifdef CONFIG_MARU + .handle_destroy = usb_msd_handle_destroy, +#endif .usbdevice_name = "disk", .usbdevice_init = usb_msd_init, .qdev.props = (Property[]) { DEFINE_BLOCK_PROPERTIES(MSDState, conf), + DEFINE_PROP_STRING("serial", MSDState, serial), DEFINE_PROP_BIT("removable", MSDState, removable, 0, false), DEFINE_PROP_END_OF_LIST(), }, diff --git a/hw/usb-musb.c b/hw/usb-musb.c index 782cfa2..01e2e7c 100644 --- a/hw/usb-musb.c +++ b/hw/usb-musb.c @@ -261,13 +261,30 @@ static void musb_attach(USBPort *port); static void musb_detach(USBPort *port); +static void musb_child_detach(USBPort *port, USBDevice *child); +static void musb_schedule_cb(USBPort *port, USBPacket *p); +static void musb_async_cancel_device(MUSBState *s, USBDevice *dev); static USBPortOps musb_port_ops = { .attach = musb_attach, .detach = musb_detach, + .child_detach = musb_child_detach, + .complete = musb_schedule_cb, }; -typedef struct { +static USBBusOps musb_bus_ops = { +}; + +typedef struct MUSBPacket MUSBPacket; +typedef struct MUSBEndPoint MUSBEndPoint; + +struct MUSBPacket { + USBPacket p; + MUSBEndPoint *ep; + int dir; +}; + +struct MUSBEndPoint { uint16_t faddr[2]; uint8_t haddr[2]; uint8_t hport[2]; @@ -284,7 +301,7 @@ typedef struct { int fifolen[2]; int fifostart[2]; int fifoaddr[2]; - USBPacket packey[2]; + MUSBPacket packey[2]; int status[2]; int ext_size[2]; @@ -294,10 +311,10 @@ typedef struct { MUSBState *musb; USBCallback *delayed_cb[2]; QEMUTimer *intv_timer[2]; -} MUSBEndPoint; +}; struct MUSBState { - qemu_irq *irqs; + qemu_irq irqs[musb_irq_max]; USBBus bus; USBPort port; @@ -321,14 +338,14 @@ struct MUSBState { /* Duplicating the world since 2008!... probably we should have 32 * logical, single endpoints instead. */ MUSBEndPoint ep[16]; -} *musb_init(qemu_irq *irqs) +}; + +void musb_reset(MUSBState *s) { - MUSBState *s = qemu_mallocz(sizeof(*s)); int i; - s->irqs = irqs; - s->faddr = 0x00; + s->devctl = 0; s->power = MGC_M_POWER_HSENAB; s->tx_intr = 0x0000; s->rx_intr = 0x0000; @@ -338,6 +355,10 @@ struct MUSBState { s->mask = 0x06; s->idx = 0; + s->setup_len = 0; + s->session = 0; + memset(s->buf, 0, sizeof(s->buf)); + /* TODO: _DW */ s->ep[0].config = MGC_M_CONFIGDATA_SOFTCONE | MGC_M_CONFIGDATA_DYNFIFO; for (i = 0; i < 16; i ++) { @@ -346,12 +367,25 @@ struct MUSBState { s->ep[i].maxp[1] = 0x40; s->ep[i].musb = s; s->ep[i].epnum = i; + usb_packet_init(&s->ep[i].packey[0].p); + usb_packet_init(&s->ep[i].packey[1].p); } +} - usb_bus_new(&s->bus, NULL /* FIXME */); +struct MUSBState *musb_init(DeviceState *parent_device, int gpio_base) +{ + MUSBState *s = g_malloc0(sizeof(*s)); + int i; + + for (i = 0; i < musb_irq_max; i++) { + s->irqs[i] = qdev_get_gpio_in(parent_device, gpio_base + i); + } + + musb_reset(s); + + usb_bus_new(&s->bus, &musb_bus_ops, parent_device); usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - usb_port_location(&s->port, NULL, 1); return s; } @@ -480,29 +514,40 @@ static void musb_detach(USBPort *port) { MUSBState *s = (MUSBState *) port->opaque; + musb_async_cancel_device(s, port->dev); + musb_intr_set(s, musb_irq_disconnect, 1); musb_session_update(s, 1, s->session); } -static inline void musb_cb_tick0(void *opaque) +static void musb_child_detach(USBPort *port, USBDevice *child) +{ + MUSBState *s = (MUSBState *) port->opaque; + + musb_async_cancel_device(s, child); +} + +static void musb_cb_tick0(void *opaque) { MUSBEndPoint *ep = (MUSBEndPoint *) opaque; - ep->delayed_cb[0](&ep->packey[0], opaque); + ep->delayed_cb[0](&ep->packey[0].p, opaque); } -static inline void musb_cb_tick1(void *opaque) +static void musb_cb_tick1(void *opaque) { MUSBEndPoint *ep = (MUSBEndPoint *) opaque; - ep->delayed_cb[1](&ep->packey[1], opaque); + ep->delayed_cb[1](&ep->packey[1].p, opaque); } #define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0) -static inline void musb_schedule_cb(USBPacket *packey, void *opaque, int dir) +static void musb_schedule_cb(USBPort *port, USBPacket *packey) { - MUSBEndPoint *ep = (MUSBEndPoint *) opaque; + MUSBPacket *p = container_of(packey, MUSBPacket, p); + MUSBEndPoint *ep = p->ep; + int dir = p->dir; int timeout = 0; if (ep->status[dir] == USB_RET_NAK) @@ -510,25 +555,15 @@ static inline void musb_schedule_cb(USBPacket *packey, void *opaque, int dir) else if (ep->interrupt[dir]) timeout = 8; else - return musb_cb_tick(opaque); + return musb_cb_tick(ep); if (!ep->intv_timer[dir]) - ep->intv_timer[dir] = qemu_new_timer(vm_clock, musb_cb_tick, opaque); + ep->intv_timer[dir] = qemu_new_timer_ns(vm_clock, musb_cb_tick, ep); - qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock(vm_clock) + + qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock_ns(vm_clock) + muldiv64(timeout, get_ticks_per_sec(), 8000)); } -static void musb_schedule0_cb(USBPacket *packey, void *opaque) -{ - return musb_schedule_cb(packey, opaque, 0); -} - -static void musb_schedule1_cb(USBPacket *packey, void *opaque) -{ - return musb_schedule_cb(packey, opaque, 1); -} - static int musb_timeout(int ttype, int speed, int val) { #if 1 @@ -567,7 +602,7 @@ static int musb_timeout(int ttype, int speed, int val) hw_error("bad interval\n"); } -static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep, +static void musb_packet(MUSBState *s, MUSBEndPoint *ep, int epnum, int pid, int len, USBCallback cb, int dir) { int ret; @@ -585,19 +620,16 @@ static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep, ep->type[idx] >> 6, ep->interval[idx]); ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT; ep->delayed_cb[dir] = cb; - cb = dir ? musb_schedule1_cb : musb_schedule0_cb; - ep->packey[dir].pid = pid; /* A wild guess on the FADDR semantics... */ - ep->packey[dir].devaddr = ep->faddr[idx]; - ep->packey[dir].devep = ep->type[idx] & 0xf; - ep->packey[dir].data = (void *) ep->buf[idx]; - ep->packey[dir].len = len; - ep->packey[dir].complete_cb = cb; - ep->packey[dir].complete_opaque = ep; + usb_packet_setup(&ep->packey[dir].p, pid, ep->faddr[idx], + ep->type[idx] & 0xf); + usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len); + ep->packey[dir].ep = ep; + ep->packey[dir].dir = dir; if (s->port.dev) - ret = s->port.dev->info->handle_packet(s->port.dev, &ep->packey[dir]); + ret = usb_handle_packet(s->port.dev, &ep->packey[dir].p); else ret = USB_RET_NODEV; @@ -607,7 +639,7 @@ static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep, } ep->status[dir] = ret; - usb_packet_complete(&ep->packey[dir]); + musb_schedule_cb(&s->port, &ep->packey[dir].p); } static void musb_tx_packet_complete(USBPacket *packey, void *opaque) @@ -720,7 +752,7 @@ static void musb_rx_packet_complete(USBPacket *packey, void *opaque) if (ep->status[1] == USB_RET_STALL) { ep->status[1] = 0; - packey->len = 0; + packey->result = 0; ep->csr[1] |= MGC_M_RXCSR_H_RXSTALL; if (!epnum) @@ -734,7 +766,7 @@ static void musb_rx_packet_complete(USBPacket *packey, void *opaque) * Data-errors in Isochronous. */ if (ep->interrupt[1]) return musb_packet(s, ep, epnum, USB_TOKEN_IN, - packey->len, musb_rx_packet_complete, 1); + packey->iov.size, musb_rx_packet_complete, 1); ep->csr[1] |= MGC_M_RXCSR_DATAERROR; if (!epnum) @@ -759,14 +791,14 @@ static void musb_rx_packet_complete(USBPacket *packey, void *opaque) /* TODO: check len for over/underruns of an OUT packet? */ /* TODO: perhaps make use of e->ext_size[1] here. */ - packey->len = ep->status[1]; + packey->result = ep->status[1]; if (!(ep->csr[1] & (MGC_M_RXCSR_H_RXSTALL | MGC_M_RXCSR_DATAERROR))) { ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY; if (!epnum) ep->csr[0] |= MGC_M_CSR0_RXPKTRDY; - ep->rxcount = packey->len; /* XXX: MIN(packey->len, ep->maxp[1]); */ + ep->rxcount = packey->result; /* XXX: MIN(packey->len, ep->maxp[1]); */ /* In DMA mode: assert DMA request for this EP */ } @@ -774,6 +806,21 @@ static void musb_rx_packet_complete(USBPacket *packey, void *opaque) musb_rx_intr_set(s, epnum, 1); } +static void musb_async_cancel_device(MUSBState *s, USBDevice *dev) +{ + int ep, dir; + + for (ep = 0; ep < 16; ep++) { + for (dir = 0; dir < 2; dir++) { + if (s->ep[ep].packey[dir].p.owner != dev) { + continue; + } + usb_cancel_packet(&s->ep[ep].packey[dir].p); + /* status updates needed here? */ + } + } +} + static void musb_tx_rdy(MUSBState *s, int epnum) { MUSBEndPoint *ep = s->ep + epnum; @@ -821,14 +868,14 @@ static void musb_rx_req(MUSBState *s, int epnum) /* If we already have a packet, which didn't fit into the * 64 bytes of the FIFO, only move the FIFO start and return. (Obsolete) */ - if (ep->packey[1].pid == USB_TOKEN_IN && ep->status[1] >= 0 && + if (ep->packey[1].p.pid == USB_TOKEN_IN && ep->status[1] >= 0 && (ep->fifostart[1]) + ep->rxcount < - ep->packey[1].len) { + ep->packey[1].p.iov.size) { TRACE("0x%08x, %d", ep->fifostart[1], ep->rxcount ); ep->fifostart[1] += ep->rxcount; ep->fifolen[1] = 0; - ep->rxcount = MIN(ep->packey[0].len - (ep->fifostart[1]), + ep->rxcount = MIN(ep->packey[0].p.iov.size - (ep->fifostart[1]), ep->maxp[1]); ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT; @@ -866,10 +913,11 @@ static void musb_rx_req(MUSBState *s, int epnum) #ifdef SETUPLEN_HACK /* Why should *we* do that instead of Linux? */ if (!epnum) { - if (ep->packey[0].devaddr == 2) + if (ep->packey[0].p.devaddr == 2) { total = MIN(s->setup_len, 8); - else + } else { total = MIN(s->setup_len, 64); + } s->setup_len -= total; } #endif diff --git a/hw/usb-net.c b/hw/usb-net.c index bf51bb3..a8b7c8d 100644 --- a/hw/usb-net.c +++ b/hw/usb-net.c @@ -29,6 +29,7 @@ #include "net.h" #include "qemu-queue.h" #include "sysemu.h" +#include "iov.h" /*#define TRAFFIC_DEBUG*/ /* Thanks to NetChip Technologies for donating this product ID. @@ -843,7 +844,7 @@ static int rndis_get_response(USBNetState *s, uint8_t *buf) QTAILQ_REMOVE(&s->rndis_resp, r, entries); ret = r->length; memcpy(buf, r->buf, r->length); - qemu_free(r); + g_free(r); return ret; } @@ -851,7 +852,7 @@ static int rndis_get_response(USBNetState *s, uint8_t *buf) static void *rndis_queue_response(USBNetState *s, unsigned int length) { struct rndis_response *r = - qemu_mallocz(sizeof(struct rndis_response) + length); + g_malloc0(sizeof(struct rndis_response) + length); QTAILQ_INSERT_TAIL(&s->rndis_resp, r, entries); r->length = length; @@ -865,7 +866,7 @@ static void rndis_clear_responsequeue(USBNetState *s) while ((r = s->rndis_resp.tqh_first)) { QTAILQ_REMOVE(&s->rndis_resp, r, entries); - qemu_free(r); + g_free(r); } } @@ -1042,13 +1043,13 @@ static void usb_net_handle_reset(USBDevice *dev) { } -static int usb_net_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_net_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { USBNetState *s = (USBNetState *) dev; int ret; - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { return ret; } @@ -1121,28 +1122,23 @@ static int usb_net_handle_control(USBDevice *dev, int request, int value, static int usb_net_handle_statusin(USBNetState *s, USBPacket *p) { + le32 buf[2]; int ret = 8; - if (p->len < 8) + if (p->iov.size < 8) { return USB_RET_STALL; + } - ((le32 *) p->data)[0] = cpu_to_le32(1); - ((le32 *) p->data)[1] = cpu_to_le32(0); + buf[0] = cpu_to_le32(1); + buf[1] = cpu_to_le32(0); + usb_packet_copy(p, buf, 8); if (!s->rndis_resp.tqh_first) ret = USB_RET_NAK; #ifdef TRAFFIC_DEBUG - fprintf(stderr, "usbnet: interrupt poll len %u return %d", p->len, ret); - { - int i; - fprintf(stderr, ":"); - for (i = 0; i < ret; i++) { - if (!(i & 15)) - fprintf(stderr, "\n%04x:", i); - fprintf(stderr, " %02x", p->data[i]); - } - fprintf(stderr, "\n\n"); - } + fprintf(stderr, "usbnet: interrupt poll len %zu return %d", + p->iov.size, ret); + iov_hexdump(p->iov.iov, p->iov.niov, stderr, "usbnet", ret); #endif return ret; @@ -1162,9 +1158,10 @@ static int usb_net_handle_datain(USBNetState *s, USBPacket *p) return ret; } ret = s->in_len - s->in_ptr; - if (ret > p->len) - ret = p->len; - memcpy(p->data, &s->in_buf[s->in_ptr], ret); + if (ret > p->iov.size) { + ret = p->iov.size; + } + usb_packet_copy(p, &s->in_buf[s->in_ptr], ret); s->in_ptr += ret; if (s->in_ptr >= s->in_len && (is_rndis(s) || (s->in_len & (64 - 1)) || !ret)) { @@ -1173,17 +1170,8 @@ static int usb_net_handle_datain(USBNetState *s, USBPacket *p) } #ifdef TRAFFIC_DEBUG - fprintf(stderr, "usbnet: data in len %u return %d", p->len, ret); - { - int i; - fprintf(stderr, ":"); - for (i = 0; i < ret; i++) { - if (!(i & 15)) - fprintf(stderr, "\n%04x:", i); - fprintf(stderr, " %02x", p->data[i]); - } - fprintf(stderr, "\n\n"); - } + fprintf(stderr, "usbnet: data in len %zu return %d", p->iov.size, ret); + iov_hexdump(p->iov.iov, p->iov.niov, stderr, "usbnet", ret); #endif return ret; @@ -1191,29 +1179,20 @@ static int usb_net_handle_datain(USBNetState *s, USBPacket *p) static int usb_net_handle_dataout(USBNetState *s, USBPacket *p) { - int ret = p->len; + int ret = p->iov.size; int sz = sizeof(s->out_buf) - s->out_ptr; struct rndis_packet_msg_type *msg = (struct rndis_packet_msg_type *) s->out_buf; uint32_t len; #ifdef TRAFFIC_DEBUG - fprintf(stderr, "usbnet: data out len %u\n", p->len); - { - int i; - fprintf(stderr, ":"); - for (i = 0; i < p->len; i++) { - if (!(i & 15)) - fprintf(stderr, "\n%04x:", i); - fprintf(stderr, " %02x", p->data[i]); - } - fprintf(stderr, "\n\n"); - } + fprintf(stderr, "usbnet: data out len %zu\n", p->iov.size); + iov_hexdump(p->iov.iov, p->iov.niov, stderr, "usbnet", p->iov.size); #endif if (sz > ret) sz = ret; - memcpy(&s->out_buf[s->out_ptr], p->data, sz); + usb_packet_copy(p, &s->out_buf[s->out_ptr], sz); s->out_ptr += sz; if (!is_rndis(s)) { @@ -1277,8 +1256,8 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p) } if (ret == USB_RET_STALL) fprintf(stderr, "usbnet: failed data transaction: " - "pid 0x%x ep 0x%x len 0x%x\n", - p->pid, p->devep, p->len); + "pid 0x%x ep 0x%x len 0x%zx\n", + p->pid, p->devep, p->iov.size); return ret; } @@ -1414,11 +1393,17 @@ static USBDevice *usb_net_init(const char *cmdline) return dev; } +static const VMStateDescription vmstate_usb_net = { + .name = "usb-net", + .unmigratable = 1, +}; + static struct USBDeviceInfo net_info = { .product_desc = "QEMU USB Network Interface", .qdev.name = "usb-net", .qdev.fw_name = "network", .qdev.size = sizeof(USBNetState), + .qdev.vmsd = &vmstate_usb_net, .usb_desc = &desc_net, .init = usb_net_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 09ea0b6..c27014a 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -62,7 +62,7 @@ typedef struct OHCIPort { typedef struct { USBBus bus; qemu_irq irq; - int mem; + MemoryRegion mem; int num_ports; const char *name; @@ -124,6 +124,7 @@ struct ohci_hcca { }; static void ohci_bus_stop(OHCIState *ohci); +static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev); /* Bitfields for the first word of an Endpoint Desciptor. */ #define OHCI_ED_FA_SHIFT 0 @@ -149,7 +150,7 @@ static void ohci_bus_stop(OHCIState *ohci); #define OHCI_TD_DI_SHIFT 21 #define OHCI_TD_DI_MASK (7<opaque; OHCIPort *port = &s->rhport[port1->index]; + uint32_t old_state = port->ctrl; /* set connect status */ port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC; @@ -343,6 +345,10 @@ static void ohci_attach(USBPort *port1) } DPRINTF("usb-ohci: Attached port %d\n", port1->index); + + if (old_state != port->ctrl) { + ohci_set_interrupt(s, OHCI_INTR_RHSC); + } } static void ohci_detach(USBPort *port1) @@ -351,6 +357,8 @@ static void ohci_detach(USBPort *port1) OHCIPort *port = &s->rhport[port1->index]; uint32_t old_state = port->ctrl; + ohci_async_cancel_device(s, port1->dev); + /* set connect status */ if (port->ctrl & OHCI_PORT_CCS) { port->ctrl &= ~OHCI_PORT_CCS; @@ -363,8 +371,41 @@ static void ohci_detach(USBPort *port1) } DPRINTF("usb-ohci: Detached port %d\n", port1->index); - if (old_state != port->ctrl) + if (old_state != port->ctrl) { ohci_set_interrupt(s, OHCI_INTR_RHSC); + } +} + +static void ohci_wakeup(USBPort *port1) +{ + OHCIState *s = port1->opaque; + OHCIPort *port = &s->rhport[port1->index]; + uint32_t intr = 0; + if (port->ctrl & OHCI_PORT_PSS) { + DPRINTF("usb-ohci: port %d: wakeup\n", port1->index); + port->ctrl |= OHCI_PORT_PSSC; + port->ctrl &= ~OHCI_PORT_PSS; + intr = OHCI_INTR_RHSC; + } + /* Note that the controller can be suspended even if this port is not */ + if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) { + DPRINTF("usb-ohci: remote-wakeup: SUSPEND->RESUME\n"); + /* This is the one state transition the controller can do by itself */ + s->ctl &= ~OHCI_CTL_HCFS; + s->ctl |= OHCI_USB_RESUME; + /* In suspend mode only ResumeDetected is possible, not RHSC: + * see the OHCI spec 5.1.2.3. + */ + intr = OHCI_INTR_RD; + } + ohci_set_interrupt(s, intr); +} + +static void ohci_child_detach(USBPort *port1, USBDevice *child) +{ + OHCIState *s = port1->opaque; + + ohci_async_cancel_device(s, child); } /* Reset the controller */ @@ -407,8 +448,8 @@ static void ohci_reset(void *opaque) { port = &ohci->rhport[i]; port->ctrl = 0; - if (port->port.dev) { - usb_attach(&port->port, port->port.dev); + if (port->port.dev && port->port.dev->attached) { + usb_reset(&port->port); } } if (ohci->async_td) { @@ -427,7 +468,7 @@ static inline int get_dwords(OHCIState *ohci, addr += ohci->localmem_base; for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0); + cpu_physical_memory_read(addr, buf, sizeof(*buf)); *buf = le32_to_cpu(*buf); } @@ -444,7 +485,7 @@ static inline int put_dwords(OHCIState *ohci, for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { uint32_t tmp = cpu_to_le32(*buf); - cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1); + cpu_physical_memory_write(addr, &tmp, sizeof(tmp)); } return 1; @@ -459,7 +500,7 @@ static inline int get_words(OHCIState *ohci, addr += ohci->localmem_base; for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0); + cpu_physical_memory_read(addr, buf, sizeof(*buf)); *buf = le16_to_cpu(*buf); } @@ -476,7 +517,7 @@ static inline int put_words(OHCIState *ohci, for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { uint16_t tmp = cpu_to_le16(*buf); - cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1); + cpu_physical_memory_write(addr, &tmp, sizeof(tmp)); } return 1; @@ -504,8 +545,7 @@ static inline int ohci_read_iso_td(OHCIState *ohci, static inline int ohci_read_hcca(OHCIState *ohci, uint32_t addr, struct ohci_hcca *hcca) { - cpu_physical_memory_rw(addr + ohci->localmem_base, - (uint8_t *)hcca, sizeof(*hcca), 0); + cpu_physical_memory_read(addr + ohci->localmem_base, hcca, sizeof(*hcca)); return 1; } @@ -531,8 +571,7 @@ static inline int ohci_put_iso_td(OHCIState *ohci, static inline int ohci_put_hcca(OHCIState *ohci, uint32_t addr, struct ohci_hcca *hcca) { - cpu_physical_memory_rw(addr + ohci->localmem_base, - (uint8_t *)hcca, sizeof(*hcca), 1); + cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca)); return 1; } @@ -577,9 +616,9 @@ static void ohci_copy_iso_td(OHCIState *ohci, static void ohci_process_lists(OHCIState *ohci, int completion); -static void ohci_async_complete_packet(USBPacket *packet, void *opaque) +static void ohci_async_complete_packet(USBPort *port, USBPacket *packet) { - OHCIState *ohci = opaque; + OHCIState *ohci = container_of(packet, OHCIState, usb_packet); #ifdef DEBUG_PACKET DPRINTF("Async packet complete\n"); #endif @@ -738,21 +777,18 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, } if (completion) { - ret = ohci->usb_packet.len; + ret = ohci->usb_packet.result; } else { ret = USB_RET_NODEV; for (i = 0; i < ohci->num_ports; i++) { dev = ohci->rhport[i].port.dev; if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) continue; - ohci->usb_packet.pid = pid; - ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA); - ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN); - ohci->usb_packet.data = ohci->usb_buf; - ohci->usb_packet.len = len; - ohci->usb_packet.complete_cb = ohci_async_complete_packet; - ohci->usb_packet.complete_opaque = ohci; - ret = dev->info->handle_packet(dev, &ohci->usb_packet); + usb_packet_setup(&ohci->usb_packet, pid, + OHCI_BM(ed->flags, ED_FA), + OHCI_BM(ed->flags, ED_EN)); + usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len); + ret = usb_handle_packet(dev, &ohci->usb_packet); if (ret != USB_RET_NODEV) break; } @@ -836,7 +872,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) { int dir; - size_t len = 0; + size_t len = 0, pktlen = 0; #ifdef DEBUG_PACKET const char *str = NULL; #endif @@ -904,25 +940,35 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) len = (td.be - td.cbp) + 1; } - if (len && dir != OHCI_TD_DIR_IN && !completion) { - ohci_copy_td(ohci, &td, ohci->usb_buf, len, 0); + pktlen = len; + if (len && dir != OHCI_TD_DIR_IN) { + /* The endpoint may not allow us to transfer it all now */ + pktlen = (ed->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT; + if (pktlen > len) { + pktlen = len; + } + if (!completion) { + ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen, 0); + } } } flag_r = (td.flags & OHCI_TD_R) != 0; #ifdef DEBUG_PACKET - DPRINTF(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n", - addr, (int64_t)len, str, flag_r, td.cbp, td.be); + DPRINTF(" TD @ 0x%.8x %" PRId64 " of %" PRId64 + " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n", + addr, (int64_t)pktlen, (int64_t)len, str, flag_r, td.cbp, td.be); - if (len > 0 && dir != OHCI_TD_DIR_IN) { + if (pktlen > 0 && dir != OHCI_TD_DIR_IN) { DPRINTF(" data:"); - for (i = 0; i < len; i++) + for (i = 0; i < pktlen; i++) { printf(" %.2x", ohci->usb_buf[i]); + } DPRINTF("\n"); } #endif if (completion) { - ret = ohci->usb_packet.len; + ret = ohci->usb_packet.result; ohci->async_td = 0; ohci->async_complete = 0; } else { @@ -943,14 +989,11 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) #endif return 1; } - ohci->usb_packet.pid = pid; - ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA); - ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN); - ohci->usb_packet.data = ohci->usb_buf; - ohci->usb_packet.len = len; - ohci->usb_packet.complete_cb = ohci_async_complete_packet; - ohci->usb_packet.complete_opaque = ohci; - ret = dev->info->handle_packet(dev, &ohci->usb_packet); + usb_packet_setup(&ohci->usb_packet, pid, + OHCI_BM(ed->flags, ED_FA), + OHCI_BM(ed->flags, ED_EN)); + usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen); + ret = usb_handle_packet(dev, &ohci->usb_packet); if (ret != USB_RET_NODEV) break; } @@ -972,20 +1015,20 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) DPRINTF("\n"); #endif } else { - ret = len; + ret = pktlen; } } /* Writeback */ - if (ret == len || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) { + if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) { /* Transmission succeeded. */ if (ret == len) { td.cbp = 0; } else { - td.cbp += ret; if ((td.cbp & 0xfff) + ret > 0xfff) { - td.cbp &= 0xfff; - td.cbp |= td.be & ~0xfff; + td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff); + } else { + td.cbp += ret; } } td.flags |= OHCI_TD_T1; @@ -993,6 +1036,12 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR); OHCI_SET_BM(td.flags, TD_EC, 0); + if ((dir != OHCI_TD_DIR_IN) && (ret != len)) { + /* Partial packet transfer: TD not ready to retire yet */ + goto exit_no_retire; + } + + /* Setting ED_C is part of the TD retirement process */ ed->head &= ~OHCI_ED_C; if (td.flags & OHCI_TD_T0) ed->head |= OHCI_ED_C; @@ -1033,6 +1082,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) i = OHCI_BM(td.flags, TD_DI); if (i < ohci->done_count) ohci->done_count = i; +exit_no_retire: ohci_put_td(ohci, addr, &td); return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR; } @@ -1101,7 +1151,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) /* Generate a SOF event, and set a timer for EOF */ static void ohci_sof(OHCIState *ohci) { - ohci->sof_time = qemu_get_clock(vm_clock); + ohci->sof_time = qemu_get_clock_ns(vm_clock); qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time); ohci_set_interrupt(ohci, OHCI_INTR_SF); } @@ -1186,12 +1236,12 @@ static void ohci_frame_boundary(void *opaque) */ static int ohci_bus_start(OHCIState *ohci) { - ohci->eof_timer = qemu_new_timer(vm_clock, + ohci->eof_timer = qemu_new_timer_ns(vm_clock, ohci_frame_boundary, ohci); if (ohci->eof_timer == NULL) { - fprintf(stderr, "usb-ohci: %s: qemu_new_timer failed\n", ohci->name); + fprintf(stderr, "usb-ohci: %s: qemu_new_timer_ns failed\n", ohci->name); /* TODO: Signal unrecoverable error */ return 0; } @@ -1311,7 +1361,7 @@ static uint32_t ohci_get_frame_remaining(OHCIState *ohci) /* Being in USB operational state guarnatees sof_time was * set already. */ - tks = qemu_get_clock(vm_clock) - ohci->sof_time; + tks = qemu_get_clock_ns(vm_clock) - ohci->sof_time; /* avoid muldiv if possible */ if (tks >= usb_frame_time) @@ -1405,13 +1455,13 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) return; } -static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) +static uint64_t ohci_mem_read(void *opaque, + target_phys_addr_t addr, + unsigned size) { - OHCIState *ohci = ptr; + OHCIState *ohci = opaque; uint32_t retval; - addr &= 0xff; - /* Only aligned reads are allowed on OHCI */ if (addr & 3) { fprintf(stderr, "usb-ohci: Mis-aligned read\n"); @@ -1528,11 +1578,12 @@ static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) return retval; } -static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) +static void ohci_mem_write(void *opaque, + target_phys_addr_t addr, + uint64_t val, + unsigned size) { - OHCIState *ohci = ptr; - - addr &= 0xff; + OHCIState *ohci = opaque; /* Only aligned reads are allowed on OHCI */ if (addr & 3) { @@ -1581,6 +1632,10 @@ static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) ohci->hcca = val & OHCI_HCCA_MASK; break; + case 7: /* HcPeriodCurrentED */ + /* Ignore writes to this read-only register, Linux does them */ + break; + case 8: /* HcControlHeadED */ ohci->ctrl_head = val & OHCI_EDPTR_MASK; break; @@ -1650,27 +1705,34 @@ static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) } } -/* Only dword reads are defined on OHCI register space */ -static CPUReadMemoryFunc * const ohci_readfn[3]={ - ohci_mem_read, - ohci_mem_read, - ohci_mem_read -}; +static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev) +{ + if (ohci->async_td && ohci->usb_packet.owner == dev) { + usb_cancel_packet(&ohci->usb_packet); + ohci->async_td = 0; + } +} -/* Only dword writes are defined on OHCI register space */ -static CPUWriteMemoryFunc * const ohci_writefn[3]={ - ohci_mem_write, - ohci_mem_write, - ohci_mem_write +static const MemoryRegionOps ohci_mem_ops = { + .read = ohci_mem_read, + .write = ohci_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, }; static USBPortOps ohci_port_ops = { .attach = ohci_attach, .detach = ohci_detach, + .child_detach = ohci_child_detach, + .wakeup = ohci_wakeup, + .complete = ohci_async_complete_packet, +}; + +static USBBusOps ohci_bus_ops = { }; -static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, - int num_ports, uint32_t localmem_base) +static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, + int num_ports, uint32_t localmem_base, + char *masterbus, uint32_t firstport) { int i; @@ -1690,55 +1752,61 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, usb_frame_time, usb_bit_time); } - ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci, - DEVICE_LITTLE_ENDIAN); + ohci->num_ports = num_ports; + if (masterbus) { + USBPort *ports[OHCI_MAX_PORTS]; + for(i = 0; i < num_ports; i++) { + ports[i] = &ohci->rhport[i].port; + } + if (usb_register_companion(masterbus, ports, num_ports, + firstport, ohci, &ohci_port_ops, + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) { + return -1; + } + } else { + usb_bus_new(&ohci->bus, &ohci_bus_ops, dev); + for (i = 0; i < num_ports; i++) { + usb_register_port(&ohci->bus, &ohci->rhport[i].port, + ohci, i, &ohci_port_ops, + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); + } + } + + memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256); ohci->localmem_base = localmem_base; ohci->name = dev->info->name; - - usb_bus_new(&ohci->bus, dev); - ohci->num_ports = num_ports; - for (i = 0; i < num_ports; i++) { - usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - usb_port_location(&ohci->rhport[i].port, NULL, i+1); - } + usb_packet_init(&ohci->usb_packet); ohci->async_td = 0; qemu_register_reset(ohci_reset, ohci); + + return 0; } typedef struct { PCIDevice pci_dev; OHCIState state; + char *masterbus; + uint32_t num_ports; + uint32_t firstport; } OHCIPCIState; -static void ohci_mapfunc(PCIDevice *pci_dev, int i, - pcibus_t addr, pcibus_t size, int type) -{ - OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, pci_dev); - cpu_register_physical_memory(addr, size, ohci->state.mem); -} - static int usb_ohci_initfn_pci(struct PCIDevice *dev) { OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev); - int num_ports = 3; - pci_config_set_vendor_id(ohci->pci_dev.config, PCI_VENDOR_ID_APPLE); - pci_config_set_device_id(ohci->pci_dev.config, - PCI_DEVICE_ID_APPLE_IPID_USB); ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */ - pci_config_set_class(ohci->pci_dev.config, PCI_CLASS_SERIAL_USB); - /* TODO: RST# value should be 0. */ - ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */ + ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */ - usb_ohci_init(&ohci->state, &dev->qdev, num_ports, 0); + if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0, + ohci->masterbus, ohci->firstport) != 0) { + return -1; + } ohci->state.irq = ohci->pci_dev.irq[0]; /* TODO: avoid cast below by using dev */ - pci_register_bar(&ohci->pci_dev, 0, 256, - PCI_BASE_ADDRESS_SPACE_MEMORY, ohci_mapfunc); + pci_register_bar(&ohci->pci_dev, 0, 0, &ohci->state.mem); return 0; } @@ -1758,9 +1826,10 @@ static int ohci_init_pxa(SysBusDevice *dev) { OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev); - usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset); + /* Cannot fail as we pass NULL for masterbus */ + usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0); sysbus_init_irq(dev, &s->ohci.irq); - sysbus_init_mmio(dev, 0x1000, s->ohci.mem); + sysbus_init_mmio_region(dev, &s->ohci.mem); return 0; } @@ -1770,6 +1839,15 @@ static PCIDeviceInfo ohci_pci_info = { .qdev.desc = "Apple USB Controller", .qdev.size = sizeof(OHCIPCIState), .init = usb_ohci_initfn_pci, + .vendor_id = PCI_VENDOR_ID_APPLE, + .device_id = PCI_DEVICE_ID_APPLE_IPID_USB, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = (Property[]) { + DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus), + DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3), + DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0), + DEFINE_PROP_END_OF_LIST(), + }, }; static SysBusDeviceInfo ohci_sysbus_info = { diff --git a/hw/usb-serial.c b/hw/usb-serial.c index 6763d52..7dbf6df 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -5,7 +5,7 @@ * Copyright (c) 2008 Samuel Thibault * Written by Paul Brook, reused for FTDI by Samuel Thibault * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. */ #include "qemu-common.h" @@ -146,6 +146,7 @@ static const USBDescDevice desc_device = { .bConfigurationValue = 1, .bmAttributes = 0x80, .bMaxPower = 50, + .nif = 1, .ifs = &desc_iface0, }, }, @@ -202,7 +203,7 @@ static uint8_t usb_get_modem_lines(USBSerialState *s) int flags; uint8_t ret; - if (qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) + if (qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) return FTDI_CTS|FTDI_DSR|FTDI_RLSD; ret = 0; @@ -218,14 +219,14 @@ static uint8_t usb_get_modem_lines(USBSerialState *s) return ret; } -static int usb_serial_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_serial_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { USBSerialState *s = (USBSerialState *)dev; int ret; DPRINTF("got control %x, value %x\n",request, value); - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { return ret; } @@ -262,7 +263,7 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value, case DeviceOutVendor | FTDI_SET_MDM_CTRL: { static int flags; - qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags); if (value & FTDI_SET_RTS) { if (value & FTDI_RTS) flags |= CHR_TIOCM_RTS; @@ -275,7 +276,7 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value, else flags &= ~CHR_TIOCM_DTR; } - qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags); + qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags); break; } case DeviceOutVendor | FTDI_SET_FLOW_CTRL: @@ -294,7 +295,7 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value, divisor = 1; s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8); - qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); + qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); break; } case DeviceOutVendor | FTDI_SET_DATA: @@ -323,7 +324,7 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value, DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP); goto fail; } - qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); + qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); /* TODO: TX ON/OFF */ break; case DeviceInVendor | FTDI_GET_MDM_ST: @@ -358,37 +359,42 @@ static int usb_serial_handle_control(USBDevice *dev, int request, int value, static int usb_serial_handle_data(USBDevice *dev, USBPacket *p) { USBSerialState *s = (USBSerialState *)dev; - int ret = 0; + int i, ret = 0; uint8_t devep = p->devep; - uint8_t *data = p->data; - int len = p->len; - int first_len; + struct iovec *iov; + uint8_t header[2]; + int first_len, len; switch (p->pid) { case USB_TOKEN_OUT: if (devep != 2) goto fail; - qemu_chr_write(s->cs, data, len); + for (i = 0; i < p->iov.niov; i++) { + iov = p->iov.iov + i; + qemu_chr_fe_write(s->cs, iov->iov_base, iov->iov_len); + } break; case USB_TOKEN_IN: if (devep != 1) goto fail; first_len = RECV_BUF - s->recv_ptr; + len = p->iov.size; if (len <= 2) { ret = USB_RET_NAK; break; } - *data++ = usb_get_modem_lines(s) | 1; + header[0] = usb_get_modem_lines(s) | 1; /* We do not have the uart details */ /* handle serial break */ if (s->event_trigger && s->event_trigger & FTDI_BI) { s->event_trigger &= ~FTDI_BI; - *data = FTDI_BI; + header[1] = FTDI_BI; + usb_packet_copy(p, header, 2); ret = 2; break; } else { - *data++ = 0; + header[1] = 0; } len -= 2; if (len > s->recv_used) @@ -399,9 +405,10 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p) } if (first_len > len) first_len = len; - memcpy(data, s->recv_buf + s->recv_ptr, first_len); + usb_packet_copy(p, header, 2); + usb_packet_copy(p, s->recv_buf + s->recv_ptr, first_len); if (len > first_len) - memcpy(data + first_len, s->recv_buf, len - first_len); + usb_packet_copy(p, s->recv_buf, len - first_len); s->recv_used -= len; s->recv_ptr = (s->recv_ptr + len) % RECV_BUF; ret = len + 2; @@ -421,7 +428,7 @@ static void usb_serial_handle_destroy(USBDevice *dev) { USBSerialState *s = (USBSerialState *)dev; - qemu_chr_close(s->cs); + qemu_chr_delete(s->cs); } static int usb_serial_can_read(void *opaque) @@ -531,7 +538,7 @@ static USBDevice *usb_serial_init(const char *filename) filename++; snprintf(label, sizeof(label), "usbserial%d", index++); - cdrv = qemu_chr_open(label, filename, NULL); + cdrv = qemu_chr_new(label, filename, NULL); if (!cdrv) return NULL; @@ -554,7 +561,7 @@ static USBDevice *usb_braille_init(const char *unused) USBDevice *dev; CharDriverState *cdrv; - cdrv = qemu_chr_open("braille", "braille", NULL); + cdrv = qemu_chr_new("braille", "braille", NULL); if (!cdrv) return NULL; @@ -565,10 +572,16 @@ static USBDevice *usb_braille_init(const char *unused) return dev; } +static const VMStateDescription vmstate_usb_serial = { + .name = "usb-serial", + .unmigratable = 1, +}; + static struct USBDeviceInfo serial_info = { .product_desc = "QEMU USB Serial", .qdev.name = "usb-serial", .qdev.size = sizeof(USBSerialState), + .qdev.vmsd = &vmstate_usb_serial, .usb_desc = &desc_serial, .init = usb_serial_initfn, .handle_packet = usb_generic_handle_packet, @@ -588,6 +601,7 @@ static struct USBDeviceInfo braille_info = { .product_desc = "QEMU USB Braille", .qdev.name = "usb-braille", .qdev.size = sizeof(USBSerialState), + .qdev.vmsd = &vmstate_usb_serial, .usb_desc = &desc_braille, .init = usb_serial_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index b384e1d..660c733 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -30,6 +30,13 @@ #include "pci.h" #include "qemu-timer.h" #include "usb-uhci.h" +#include "iov.h" +#include "dma.h" + +#ifdef CONFIG_MARU +#include "kvm.h" +#include "hax.h" +#endif //#define DEBUG //#define DEBUG_DUMP_DATA @@ -70,7 +77,6 @@ #define UHCI_PORT_WRITE_CLEAR (UHCI_PORT_CSC | UHCI_PORT_ENC) #define FRAME_TIMER_FREQ 1000 - #define FRAME_MAX_LOOPS 100 #define NB_PORTS 2 @@ -93,19 +99,16 @@ static const char *pid2str(int pid) #endif #ifdef DEBUG_DUMP_DATA -static void dump_data(const uint8_t *data, int len) +static void dump_data(USBPacket *p, int ret) { - int i; - - printf("uhci: data: "); - for(i = 0; i < len; i++) - printf(" %02x", data[i]); - printf("\n"); + iov_hexdump(p->iov.iov, p->iov.niov, stderr, "uhci", ret); } #else -static void dump_data(const uint8_t *data, int len) {} +static void dump_data(USBPacket *p, int ret) {} #endif +typedef struct UHCIState UHCIState; + /* * Pending async transaction. * 'packet' must be the first field because completion @@ -113,13 +116,14 @@ static void dump_data(const uint8_t *data, int len) {} */ typedef struct UHCIAsync { USBPacket packet; - struct UHCIAsync *next; + QEMUSGList sgl; + UHCIState *uhci; + QTAILQ_ENTRY(UHCIAsync) next; uint32_t td; uint32_t token; int8_t valid; uint8_t isoc; uint8_t done; - uint8_t buffer[2048]; } UHCIAsync; typedef struct UHCIPort { @@ -127,9 +131,10 @@ typedef struct UHCIPort { uint16_t ctrl; } UHCIPort; -typedef struct UHCIState { +struct UHCIState { PCIDevice dev; - USBBus bus; + MemoryRegion io_bar; + USBBus bus; /* Note unused when we're a companion controller */ uint16_t cmd; /* cmd register */ uint16_t status; uint16_t intr; /* interrupt enable register */ @@ -145,10 +150,13 @@ typedef struct UHCIState { uint32_t pending_int_mask; /* Active packets */ - UHCIAsync *async_pending; - UHCIAsync *async_pool; + QTAILQ_HEAD(,UHCIAsync) async_pending; uint8_t num_ports_vmstate; -} UHCIState; + + /* Properties */ + char *masterbus; + uint32_t firstport; +}; typedef struct UHCI_TD { uint32_t link; @@ -164,44 +172,36 @@ typedef struct UHCI_QH { static UHCIAsync *uhci_async_alloc(UHCIState *s) { - UHCIAsync *async = qemu_malloc(sizeof(UHCIAsync)); + UHCIAsync *async = g_malloc(sizeof(UHCIAsync)); memset(&async->packet, 0, sizeof(async->packet)); + async->uhci = s; async->valid = 0; async->td = 0; async->token = 0; async->done = 0; async->isoc = 0; - async->next = NULL; + usb_packet_init(&async->packet); + pci_dma_sglist_init(&async->sgl, &s->dev, 1); return async; } static void uhci_async_free(UHCIState *s, UHCIAsync *async) { - qemu_free(async); + usb_packet_cleanup(&async->packet); + qemu_sglist_destroy(&async->sgl); + g_free(async); } static void uhci_async_link(UHCIState *s, UHCIAsync *async) { - async->next = s->async_pending; - s->async_pending = async; + QTAILQ_INSERT_HEAD(&s->async_pending, async, next); } static void uhci_async_unlink(UHCIState *s, UHCIAsync *async) { - UHCIAsync *curr = s->async_pending; - UHCIAsync **prev = &s->async_pending; - - while (curr) { - if (curr == async) { - *prev = curr->next; - return; - } - - prev = &curr->next; - curr = curr->next; - } + QTAILQ_REMOVE(&s->async_pending, async, next); } static void uhci_async_cancel(UHCIState *s, UHCIAsync *async) @@ -220,11 +220,10 @@ static void uhci_async_cancel(UHCIState *s, UHCIAsync *async) */ static UHCIAsync *uhci_async_validate_begin(UHCIState *s) { - UHCIAsync *async = s->async_pending; + UHCIAsync *async; - while (async) { + QTAILQ_FOREACH(async, &s->async_pending, next) { async->valid--; - async = async->next; } return NULL; } @@ -234,47 +233,43 @@ static UHCIAsync *uhci_async_validate_begin(UHCIState *s) */ static void uhci_async_validate_end(UHCIState *s) { - UHCIAsync *curr = s->async_pending; - UHCIAsync **prev = &s->async_pending; - UHCIAsync *next; + UHCIAsync *curr, *n; - while (curr) { + QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) { if (curr->valid > 0) { - prev = &curr->next; - curr = curr->next; continue; } + uhci_async_unlink(s, curr); + uhci_async_cancel(s, curr); + } +} - next = curr->next; - - /* Unlink */ - *prev = next; +static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev) +{ + UHCIAsync *curr, *n; + QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) { + if (curr->packet.owner != dev) { + continue; + } + uhci_async_unlink(s, curr); uhci_async_cancel(s, curr); - - curr = next; } } static void uhci_async_cancel_all(UHCIState *s) { - UHCIAsync *curr = s->async_pending; - UHCIAsync *next; - - while (curr) { - next = curr->next; + UHCIAsync *curr, *n; + QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) { + uhci_async_unlink(s, curr); uhci_async_cancel(s, curr); - - curr = next; } - - s->async_pending = NULL; } static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token) { - UHCIAsync *async = s->async_pending; + UHCIAsync *async; UHCIAsync *match = NULL; int count = 0; @@ -291,7 +286,7 @@ static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token * If we ever do we'd want to optimize this algorithm. */ - while (async) { + QTAILQ_FOREACH(async, &s->async_pending, next) { if (async->token == token) { /* Good match */ match = async; @@ -301,8 +296,6 @@ static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token break; } } - - async = async->next; count++; } @@ -351,8 +344,8 @@ static void uhci_reset(void *opaque) for(i = 0; i < NB_PORTS; i++) { port = &s->ports[i]; port->ctrl = 0x0080; - if (port->port.dev) { - usb_attach(&port->port, port->port.dev); + if (port->port.dev && port->port.dev->attached) { + usb_reset(&port->port); } } @@ -441,7 +434,19 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val) case 0x00: if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) { /* start frame processing */ - qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock)); +#ifdef CONFIG_MARU + if (kvm_enabled() || hax_enabled()) { //kvm or haxm machine + s->expire_time = qemu_get_clock_ns(vm_clock) + + (get_ticks_per_sec() / FRAME_TIMER_FREQ); + } else { + s->expire_time = qemu_get_clock_ns(vm_clock) + + (get_ticks_per_sec() / (FRAME_TIMER_FREQ / 2)); + } +#else + s->expire_time = qemu_get_clock_ns(vm_clock) + + (get_ticks_per_sec() / FRAME_TIMER_FREQ); +#endif + qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock)); s->status &= ~UHCI_STS_HCHALTED; } else if (!(val & UHCI_CMD_RS)) { s->status |= UHCI_STS_HCHALTED; @@ -455,7 +460,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val) for(i = 0; i < NB_PORTS; i++) { port = &s->ports[i]; dev = port->port.dev; - if (dev) { + if (dev && dev->attached) { usb_send_msg(dev, USB_MSG_RESET); } } @@ -495,7 +500,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val) return; port = &s->ports[n]; dev = port->port.dev; - if (dev) { + if (dev && dev->attached) { /* port reset */ if ( (val & UHCI_PORT_RESET) && !(port->ctrl & UHCI_PORT_RESET) ) { @@ -621,6 +626,8 @@ static void uhci_detach(USBPort *port1) UHCIState *s = port1->opaque; UHCIPort *port = &s->ports[port1->index]; + uhci_async_cancel_device(s, port1->dev); + /* set connect status */ if (port->ctrl & UHCI_PORT_CCS) { port->ctrl &= ~UHCI_PORT_CCS; @@ -635,11 +642,17 @@ static void uhci_detach(USBPort *port1) uhci_resume(s); } -static void uhci_wakeup(USBDevice *dev) +static void uhci_child_detach(USBPort *port1, USBDevice *child) { - USBBus *bus = usb_bus_from_device(dev); - UHCIState *s = container_of(bus, UHCIState, bus); - UHCIPort *port = s->ports + dev->port->index; + UHCIState *s = port1->opaque; + + uhci_async_cancel_device(s, child); +} + +static void uhci_wakeup(USBPort *port1) +{ + UHCIState *s = port1->opaque; + UHCIPort *port = &s->ports[port1->index]; if (port->ctrl & UHCI_PORT_SUSPEND && !(port->ctrl & UHCI_PORT_RD)) { port->ctrl |= UHCI_PORT_RD; @@ -651,28 +664,29 @@ static int uhci_broadcast_packet(UHCIState *s, USBPacket *p) { int i, ret; - DPRINTF("uhci: packet enter. pid %s addr 0x%02x ep %d len %d\n", - pid2str(p->pid), p->devaddr, p->devep, p->len); + DPRINTF("uhci: packet enter. pid %s addr 0x%02x ep %d len %zd\n", + pid2str(p->pid), p->devaddr, p->devep, p->iov.size); if (p->pid == USB_TOKEN_OUT || p->pid == USB_TOKEN_SETUP) - dump_data(p->data, p->len); + dump_data(p, 0); ret = USB_RET_NODEV; for (i = 0; i < NB_PORTS && ret == USB_RET_NODEV; i++) { UHCIPort *port = &s->ports[i]; USBDevice *dev = port->port.dev; - if (dev && (port->ctrl & UHCI_PORT_EN)) - ret = dev->info->handle_packet(dev, p); + if (dev && dev->attached && (port->ctrl & UHCI_PORT_EN)) { + ret = usb_handle_packet(dev, p); + } } - DPRINTF("uhci: packet exit. ret %d len %d\n", ret, p->len); + DPRINTF("uhci: packet exit. ret %d len %zd\n", ret, p->iov.size); if (p->pid == USB_TOKEN_IN && ret > 0) - dump_data(p->data, ret); + dump_data(p, ret); return ret; } -static void uhci_async_complete(USBPacket * packet, void *opaque); +static void uhci_async_complete(USBPort *port, USBPacket *packet); static void uhci_process_frame(UHCIState *s); /* return -1 if fatal error (frame must be stopped) @@ -687,7 +701,7 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_ max_len = ((td->token >> 21) + 1) & 0x7ff; pid = td->token & 0xff; - ret = async->packet.len; + ret = async->packet.result; if (td->ctrl & TD_CTRL_IOS) td->ctrl &= ~TD_CTRL_ACTIVE; @@ -695,7 +709,7 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_ if (ret < 0) goto out; - len = async->packet.len; + len = async->packet.result; td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff); /* The NAK bit may have been set by a previous frame, so clear it @@ -711,11 +725,6 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_ goto out; } - if (len > 0) { - /* write the data back */ - cpu_physical_memory_write(td->buffer, async->buffer, len); - } - if ((td->ctrl & TD_CTRL_SPD) && len < max_len) { *int_mask |= 0x02; /* short packet: do not update QH */ @@ -732,11 +741,21 @@ out: case USB_RET_STALL: td->ctrl |= TD_CTRL_STALL; td->ctrl &= ~TD_CTRL_ACTIVE; + s->status |= UHCI_STS_USBERR; + if (td->ctrl & TD_CTRL_IOC) { + *int_mask |= 0x01; + } + uhci_update_irq(s); return 1; case USB_RET_BABBLE: td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL; td->ctrl &= ~TD_CTRL_ACTIVE; + s->status |= UHCI_STS_USBERR; + if (td->ctrl & TD_CTRL_IOC) { + *int_mask |= 0x01; + } + uhci_update_irq(s); /* frame interrupted */ return -1; @@ -820,18 +839,14 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in max_len = ((td->token >> 21) + 1) & 0x7ff; pid = td->token & 0xff; - async->packet.pid = pid; - async->packet.devaddr = (td->token >> 8) & 0x7f; - async->packet.devep = (td->token >> 15) & 0xf; - async->packet.data = async->buffer; - async->packet.len = max_len; - async->packet.complete_cb = uhci_async_complete; - async->packet.complete_opaque = s; + usb_packet_setup(&async->packet, pid, (td->token >> 8) & 0x7f, + (td->token >> 15) & 0xf); + qemu_sglist_add(&async->sgl, td->buffer, max_len); + usb_packet_map(&async->packet, &async->sgl); switch(pid) { case USB_TOKEN_OUT: case USB_TOKEN_SETUP: - cpu_physical_memory_read(td->buffer, async->buffer, max_len); len = uhci_broadcast_packet(s, &async->packet); if (len >= 0) len = max_len; @@ -854,18 +869,19 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in return 2; } - async->packet.len = len; + async->packet.result = len; done: len = uhci_complete_td(s, td, async, int_mask); + usb_packet_unmap(&async->packet); uhci_async_free(s, async); return len; } -static void uhci_async_complete(USBPacket *packet, void *opaque) +static void uhci_async_complete(USBPort *port, USBPacket *packet) { - UHCIState *s = opaque; - UHCIAsync *async = (UHCIAsync *) packet; + UHCIAsync *async = container_of(packet, UHCIAsync, packet); + UHCIState *s = async->uhci; DPRINTF("uhci: async complete. td 0x%x token 0x%x\n", async->td, async->token); @@ -874,7 +890,7 @@ static void uhci_async_complete(USBPacket *packet, void *opaque) uint32_t link = async->td; uint32_t int_mask = 0, val; - cpu_physical_memory_read(link & ~0xf, (uint8_t *) &td, sizeof(td)); + pci_dma_read(&s->dev, link & ~0xf, (uint8_t *) &td, sizeof(td)); le32_to_cpus(&td.link); le32_to_cpus(&td.ctrl); le32_to_cpus(&td.token); @@ -886,8 +902,8 @@ static void uhci_async_complete(USBPacket *packet, void *opaque) /* update the status bits of the TD */ val = cpu_to_le32(td.ctrl); - cpu_physical_memory_write((link & ~0xf) + 4, - (const uint8_t *)&val, sizeof(val)); + pci_dma_write(&s->dev, (link & ~0xf) + 4, + (const uint8_t *)&val, sizeof(val)); uhci_async_free(s, async); } else { async->done = 1; @@ -950,7 +966,7 @@ static void uhci_process_frame(UHCIState *s) DPRINTF("uhci: processing frame %d addr 0x%x\n" , s->frnum, frame_addr); - cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4); + pci_dma_read(&s->dev, frame_addr, (uint8_t *)&link, 4); le32_to_cpus(&link); int_mask = 0; @@ -974,7 +990,7 @@ static void uhci_process_frame(UHCIState *s) break; } - cpu_physical_memory_read(link & ~0xf, (uint8_t *) &qh, sizeof(qh)); + pci_dma_read(&s->dev, link & ~0xf, (uint8_t *) &qh, sizeof(qh)); le32_to_cpus(&qh.link); le32_to_cpus(&qh.el_link); @@ -994,7 +1010,7 @@ static void uhci_process_frame(UHCIState *s) } /* TD */ - cpu_physical_memory_read(link & ~0xf, (uint8_t *) &td, sizeof(td)); + pci_dma_read(&s->dev, link & ~0xf, (uint8_t *) &td, sizeof(td)); le32_to_cpus(&td.link); le32_to_cpus(&td.ctrl); le32_to_cpus(&td.token); @@ -1008,8 +1024,8 @@ static void uhci_process_frame(UHCIState *s) if (old_td_ctrl != td.ctrl) { /* update the status bits of the TD */ val = cpu_to_le32(td.ctrl); - cpu_physical_memory_write((link & ~0xf) + 4, - (const uint8_t *)&val, sizeof(val)); + pci_dma_write(&s->dev, (link & ~0xf) + 4, + (const uint8_t *)&val, sizeof(val)); } if (ret < 0) { @@ -1037,8 +1053,8 @@ static void uhci_process_frame(UHCIState *s) /* update QH element link */ qh.el_link = link; val = cpu_to_le32(qh.el_link); - cpu_physical_memory_write((curr_qh & ~0xf) + 4, - (const uint8_t *)&val, sizeof(val)); + pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4, + (const uint8_t *)&val, sizeof(val)); if (!depth_first(link)) { /* done with this QH */ @@ -1062,7 +1078,15 @@ static void uhci_frame_timer(void *opaque) UHCIState *s = opaque; /* prepare the timer for the next frame */ +#ifdef CONFIG_MARU + if (kvm_enabled() || hax_enabled()) { //kvm or haxm machine + s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ); + } else { + s->expire_time += (get_ticks_per_sec() / (FRAME_TIMER_FREQ / 2)); + } +#else s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ); +#endif if (!(s->cmd & UHCI_CMD_RS)) { /* Full stop */ @@ -1096,86 +1120,78 @@ static void uhci_frame_timer(void *opaque) qemu_mod_timer(s->frame_timer, s->expire_time); } -static void uhci_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - UHCIState *s = (UHCIState *)pci_dev; - - register_ioport_write(addr, 32, 2, uhci_ioport_writew, s); - register_ioport_read(addr, 32, 2, uhci_ioport_readw, s); - register_ioport_write(addr, 32, 4, uhci_ioport_writel, s); - register_ioport_read(addr, 32, 4, uhci_ioport_readl, s); - register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s); - register_ioport_read(addr, 32, 1, uhci_ioport_readb, s); -} +static const MemoryRegionPortio uhci_portio[] = { + { 0, 32, 2, .write = uhci_ioport_writew, }, + { 0, 32, 2, .read = uhci_ioport_readw, }, + { 0, 32, 4, .write = uhci_ioport_writel, }, + { 0, 32, 4, .read = uhci_ioport_readl, }, + { 0, 32, 1, .write = uhci_ioport_writeb, }, + { 0, 32, 1, .read = uhci_ioport_readb, }, + PORTIO_END_OF_LIST() +}; + +static const MemoryRegionOps uhci_ioport_ops = { + .old_portio = uhci_portio, +}; static USBPortOps uhci_port_ops = { .attach = uhci_attach, .detach = uhci_detach, + .child_detach = uhci_child_detach, .wakeup = uhci_wakeup, + .complete = uhci_async_complete, }; -static int usb_uhci_common_initfn(UHCIState *s) +static USBBusOps uhci_bus_ops = { +}; + +static int usb_uhci_common_initfn(PCIDevice *dev) { + UHCIState *s = DO_UPCAST(UHCIState, dev, dev); uint8_t *pci_conf = s->dev.config; int i; - pci_conf[PCI_REVISION_ID] = 0x01; // revision number pci_conf[PCI_CLASS_PROG] = 0x00; - pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB); /* TODO: reset value should be 0. */ - pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3 - pci_conf[0x60] = 0x10; // release number + pci_conf[PCI_INTERRUPT_PIN] = 4; /* interrupt pin D */ + pci_conf[USB_SBRN] = USB_RELEASE_1; // release number - usb_bus_new(&s->bus, &s->dev.qdev); - for(i = 0; i < NB_PORTS; i++) { - usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - usb_port_location(&s->ports[i].port, NULL, i+1); + if (s->masterbus) { + USBPort *ports[NB_PORTS]; + for(i = 0; i < NB_PORTS; i++) { + ports[i] = &s->ports[i].port; + } + if (usb_register_companion(s->masterbus, ports, NB_PORTS, + s->firstport, s, &uhci_port_ops, + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) { + return -1; + } + } else { + usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev); + for (i = 0; i < NB_PORTS; i++) { + usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops, + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); + } } - s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s); - s->expire_time = qemu_get_clock(vm_clock) + - (get_ticks_per_sec() / FRAME_TIMER_FREQ); + s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s); s->num_ports_vmstate = NB_PORTS; + QTAILQ_INIT(&s->async_pending); qemu_register_reset(uhci_reset, s); + memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20); /* Use region 4 for consistency with real hardware. BSD guests seem to rely on this. */ - pci_register_bar(&s->dev, 4, 0x20, - PCI_BASE_ADDRESS_SPACE_IO, uhci_map); + pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); return 0; } -static int usb_uhci_piix3_initfn(PCIDevice *dev) -{ - UHCIState *s = DO_UPCAST(UHCIState, dev, dev); - uint8_t *pci_conf = s->dev.config; - - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_2); - return usb_uhci_common_initfn(s); -} - -static int usb_uhci_piix4_initfn(PCIDevice *dev) -{ - UHCIState *s = DO_UPCAST(UHCIState, dev, dev); - uint8_t *pci_conf = s->dev.config; - - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_2); - return usb_uhci_common_initfn(s); -} - static int usb_uhci_vt82c686b_initfn(PCIDevice *dev) { UHCIState *s = DO_UPCAST(UHCIState, dev, dev); uint8_t *pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI); - /* USB misc control 1/2 */ pci_set_long(pci_conf + 0x40,0x00001000); /* PM capability */ @@ -1183,25 +1199,87 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev) /* USB legacy support */ pci_set_long(pci_conf + 0xc0,0x00002000); - return usb_uhci_common_initfn(s); + return usb_uhci_common_initfn(dev); +} + +static int usb_uhci_exit(PCIDevice *dev) +{ + UHCIState *s = DO_UPCAST(UHCIState, dev, dev); + + memory_region_destroy(&s->io_bar); + return 0; } +static Property uhci_properties[] = { + DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), + DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), + DEFINE_PROP_END_OF_LIST(), +}; + static PCIDeviceInfo uhci_info[] = { { .qdev.name = "piix3-usb-uhci", .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, - .init = usb_uhci_piix3_initfn, + .init = usb_uhci_common_initfn, + .exit = usb_uhci_exit, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371SB_2, + .revision = 0x01, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = uhci_properties, },{ .qdev.name = "piix4-usb-uhci", .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, - .init = usb_uhci_piix4_initfn, + .init = usb_uhci_common_initfn, + .exit = usb_uhci_exit, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82371AB_2, + .revision = 0x01, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = uhci_properties, },{ .qdev.name = "vt82c686b-usb-uhci", .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, .init = usb_uhci_vt82c686b_initfn, + .exit = usb_uhci_exit, + .vendor_id = PCI_VENDOR_ID_VIA, + .device_id = PCI_DEVICE_ID_VIA_UHCI, + .revision = 0x01, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = uhci_properties, + },{ + .qdev.name = "ich9-usb-uhci1", + .qdev.size = sizeof(UHCIState), + .qdev.vmsd = &vmstate_uhci, + .init = usb_uhci_common_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1, + .revision = 0x03, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = uhci_properties, + },{ + .qdev.name = "ich9-usb-uhci2", + .qdev.size = sizeof(UHCIState), + .qdev.vmsd = &vmstate_uhci, + .init = usb_uhci_common_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2, + .revision = 0x03, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = uhci_properties, + },{ + .qdev.name = "ich9-usb-uhci3", + .qdev.size = sizeof(UHCIState), + .qdev.vmsd = &vmstate_uhci, + .init = usb_uhci_common_initfn, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3, + .revision = 0x03, + .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = uhci_properties, },{ /* end of list */ } diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c index 5397894..2558006 100644 --- a/hw/usb-wacom.c +++ b/hw/usb-wacom.c @@ -41,20 +41,18 @@ #define HID_SET_IDLE 0x210a #define HID_SET_PROTOCOL 0x210b -enum { - WACOM_MODE_HID = 1, - WACOM_MODE_WACOM = 2, -} ; - typedef struct USBWacomState { USBDevice dev; QEMUPutMouseEntry *eh_entry; - int32_t dx, dy, dz, buttons_state; - int32_t x, y; - int32_t mouse_grabbed; - uint8_t mode; + int dx, dy, dz, buttons_state; + int x, y; + int mouse_grabbed; + enum { + WACOM_MODE_HID = 1, + WACOM_MODE_WACOM = 2, + } mode; uint8_t idle; - int32_t changed; + int changed; } USBWacomState; enum { @@ -110,6 +108,7 @@ static const USBDescDevice desc_device_wacom = { .bConfigurationValue = 1, .bmAttributes = 0x80, .bMaxPower = 40, + .nif = 1, .ifs = &desc_iface_wacom, }, }, @@ -251,13 +250,13 @@ static void usb_wacom_handle_reset(USBDevice *dev) s->mode = WACOM_MODE_HID; } -static int usb_wacom_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) +static int usb_wacom_handle_control(USBDevice *dev, USBPacket *p, + int request, int value, int index, int length, uint8_t *data) { USBWacomState *s = (USBWacomState *) dev; int ret; - ret = usb_desc_handle_control(dev, request, value, index, length, data); + ret = usb_desc_handle_control(dev, p, request, value, index, length, data); if (ret >= 0) { return ret; } @@ -275,8 +274,6 @@ static int usb_wacom_handle_control(USBDevice *dev, int request, int value, if (s->mouse_grabbed) { qemu_remove_mouse_event_handler(s->eh_entry); s->mouse_grabbed = 0; - s->changed = 1; - dev->setup_index=0; } s->mode = data[0]; ret = 0; @@ -311,6 +308,7 @@ static int usb_wacom_handle_control(USBDevice *dev, int request, int value, static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p) { USBWacomState *s = (USBWacomState *) dev; + uint8_t buf[p->iov.size]; int ret = 0; switch (p->pid) { @@ -320,9 +318,10 @@ static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p) return USB_RET_NAK; s->changed = 0; if (s->mode == WACOM_MODE_HID) - ret = usb_mouse_poll(s, p->data, p->len); + ret = usb_mouse_poll(s, buf, p->iov.size); else if (s->mode == WACOM_MODE_WACOM) - ret = usb_wacom_poll(s, p->data, p->len); + ret = usb_wacom_poll(s, buf, p->iov.size); + usb_packet_copy(p, buf, ret); break; } /* Fall through. */ @@ -352,70 +351,9 @@ static int usb_wacom_initfn(USBDevice *dev) return 0; } -/* Remove mouse handlers before loading. */ -static int wacom_pre_load(void *opaque) -{ - USBWacomState *s = (USBWacomState *)opaque; - - if (s->eh_entry) { - qemu_remove_mouse_event_handler(s->eh_entry); - } - - return 0; -} - -static int wacom_post_load(void *opaque, int version_id) -{ - USBWacomState *s = (USBWacomState *)opaque; - - s->changed = 1; - if (s->mouse_grabbed && s->mode == WACOM_MODE_WACOM) { - s->eh_entry = qemu_add_mouse_event_handler(usb_wacom_event, s, 1, - "QEMU PenPartner tablet"); - } else if (s->mouse_grabbed && s->mode == WACOM_MODE_HID) { - s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, 0, - "QEMU PenPartner tablet"); - } - if (s->mouse_grabbed) { - qemu_activate_mouse_event_handler(s->eh_entry); - } - - return 0; -} - -static VMStateDescription vmsd_usbdevice = { - .name = "wacom-tablet_usbdevice", - .version_id = 1, - .minimum_version_id = 1, - .minimum_version_id_old = 1, - .fields = (VMStateField []) { - VMSTATE_UINT8(addr, USBDevice), - VMSTATE_INT32(state, USBDevice), - VMSTATE_END_OF_LIST() - } -}; - -static VMStateDescription vmsd = { - .name = "wacom-tablet", - .version_id = 2, - .minimum_version_id = 1, - .minimum_version_id_old = 1, - .pre_load = wacom_pre_load, - .post_load = wacom_post_load, - .fields = (VMStateField []) { - VMSTATE_STRUCT(dev, USBWacomState, 1, vmsd_usbdevice, USBDevice), - VMSTATE_INT32(dx, USBWacomState), - VMSTATE_INT32(dy, USBWacomState), - VMSTATE_INT32(dz, USBWacomState), - VMSTATE_INT32(buttons_state, USBWacomState), - VMSTATE_INT32(x, USBWacomState), - VMSTATE_INT32(y, USBWacomState), - VMSTATE_INT32(mouse_grabbed, USBWacomState), - VMSTATE_UINT8(mode, USBWacomState), - VMSTATE_UINT8(idle, USBWacomState), - VMSTATE_INT32(changed, USBWacomState), - VMSTATE_END_OF_LIST() - } +static const VMStateDescription vmstate_usb_wacom = { + .name = "usb-wacom", + .unmigratable = 1, }; static struct USBDeviceInfo wacom_info = { @@ -425,7 +363,7 @@ static struct USBDeviceInfo wacom_info = { .usbdevice_name = "wacom-tablet", .usb_desc = &desc_wacom, .qdev.size = sizeof(USBWacomState), - .qdev.vmsd = &vmsd, + .qdev.vmsd = &vmstate_usb_wacom, .init = usb_wacom_initfn, .handle_packet = usb_generic_handle_packet, .handle_reset = usb_wacom_handle_reset, diff --git a/hw/usb.c b/hw/usb.c index 82a6217..2216efe 100644 --- a/hw/usb.c +++ b/hw/usb.c @@ -25,34 +25,43 @@ */ #include "qemu-common.h" #include "usb.h" +#include "iov.h" -void usb_attach(USBPort *port, USBDevice *dev) +void usb_attach(USBPort *port) { - if (dev != NULL) { - /* attach */ - if (port->dev) { - usb_attach(port, NULL); - } - dev->port = port; - port->dev = dev; - port->ops->attach(port); - usb_send_msg(dev, USB_MSG_ATTACH); - } else { - /* detach */ - dev = port->dev; - port->ops->detach(port); - if (dev) { - usb_send_msg(dev, USB_MSG_DETACH); - dev->port = NULL; - port->dev = NULL; - } - } + USBDevice *dev = port->dev; + + assert(dev != NULL); + assert(dev->attached); + assert(dev->state == USB_STATE_NOTATTACHED); + port->ops->attach(port); + usb_send_msg(dev, USB_MSG_ATTACH); +} + +void usb_detach(USBPort *port) +{ + USBDevice *dev = port->dev; + + assert(dev != NULL); + assert(dev->state != USB_STATE_NOTATTACHED); + port->ops->detach(port); + usb_send_msg(dev, USB_MSG_DETACH); +} + +void usb_reset(USBPort *port) +{ + USBDevice *dev = port->dev; + + assert(dev != NULL); + usb_detach(port); + usb_attach(port); + usb_send_msg(dev, USB_MSG_RESET); } void usb_wakeup(USBDevice *dev) { if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) { - dev->port->ops->wakeup(dev); + dev->port->ops->wakeup(dev->port); } } @@ -63,29 +72,35 @@ void usb_wakeup(USBDevice *dev) protocol) */ -#define SETUP_STATE_IDLE 0 -#define SETUP_STATE_DATA 1 -#define SETUP_STATE_ACK 2 +#define SETUP_STATE_IDLE 0 +#define SETUP_STATE_SETUP 1 +#define SETUP_STATE_DATA 2 +#define SETUP_STATE_ACK 3 static int do_token_setup(USBDevice *s, USBPacket *p) { int request, value, index; int ret = 0; - if (p->len != 8) + if (p->iov.size != 8) { return USB_RET_STALL; - - memcpy(s->setup_buf, p->data, 8); + } + + usb_packet_copy(p, s->setup_buf, p->iov.size); s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6]; s->setup_index = 0; request = (s->setup_buf[0] << 8) | s->setup_buf[1]; value = (s->setup_buf[3] << 8) | s->setup_buf[2]; index = (s->setup_buf[5] << 8) | s->setup_buf[4]; - + if (s->setup_buf[0] & USB_DIR_IN) { - ret = s->info->handle_control(s, request, value, index, + ret = s->info->handle_control(s, p, request, value, index, s->setup_len, s->data_buf); + if (ret == USB_RET_ASYNC) { + s->setup_state = SETUP_STATE_SETUP; + return USB_RET_ASYNC; + } if (ret < 0) return ret; @@ -93,6 +108,12 @@ static int do_token_setup(USBDevice *s, USBPacket *p) s->setup_len = ret; s->setup_state = SETUP_STATE_DATA; } else { + if (s->setup_len > sizeof(s->data_buf)) { + fprintf(stderr, + "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n", + s->setup_len, sizeof(s->data_buf)); + return USB_RET_STALL; + } if (s->setup_len == 0) s->setup_state = SETUP_STATE_ACK; else @@ -117,9 +138,12 @@ static int do_token_in(USBDevice *s, USBPacket *p) switch(s->setup_state) { case SETUP_STATE_ACK: if (!(s->setup_buf[0] & USB_DIR_IN)) { - s->setup_state = SETUP_STATE_IDLE; - ret = s->info->handle_control(s, request, value, index, + ret = s->info->handle_control(s, p, request, value, index, s->setup_len, s->data_buf); + if (ret == USB_RET_ASYNC) { + return USB_RET_ASYNC; + } + s->setup_state = SETUP_STATE_IDLE; if (ret > 0) return 0; return ret; @@ -131,9 +155,10 @@ static int do_token_in(USBDevice *s, USBPacket *p) case SETUP_STATE_DATA: if (s->setup_buf[0] & USB_DIR_IN) { int len = s->setup_len - s->setup_index; - if (len > p->len) - len = p->len; - memcpy(p->data, s->data_buf + s->setup_index, len); + if (len > p->iov.size) { + len = p->iov.size; + } + usb_packet_copy(p, s->data_buf + s->setup_index, len); s->setup_index += len; if (s->setup_index >= s->setup_len) s->setup_state = SETUP_STATE_ACK; @@ -166,9 +191,10 @@ static int do_token_out(USBDevice *s, USBPacket *p) case SETUP_STATE_DATA: if (!(s->setup_buf[0] & USB_DIR_IN)) { int len = s->setup_len - s->setup_index; - if (len > p->len) - len = p->len; - memcpy(s->data_buf + s->setup_index, p->data, len); + if (len > p->iov.size) { + len = p->iov.size; + } + usb_packet_copy(p, s->data_buf + s->setup_index, len); s->setup_index += len; if (s->setup_index >= s->setup_len) s->setup_state = SETUP_STATE_ACK; @@ -232,6 +258,36 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p) } } +/* ctrl complete function for devices which use usb_generic_handle_packet and + may return USB_RET_ASYNC from their handle_control callback. Device code + which does this *must* call this function instead of the normal + usb_packet_complete to complete their async control packets. */ +void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p) +{ + if (p->result < 0) { + s->setup_state = SETUP_STATE_IDLE; + } + + switch (s->setup_state) { + case SETUP_STATE_SETUP: + if (p->result < s->setup_len) { + s->setup_len = p->result; + } + s->setup_state = SETUP_STATE_DATA; + p->result = 8; + break; + + case SETUP_STATE_ACK: + s->setup_state = SETUP_STATE_IDLE; + p->result = 0; + break; + + default: + break; + } + usb_packet_complete(s, p); +} + /* XXX: fix overflow */ int set_usb_string(uint8_t *buf, const char *str) { @@ -253,9 +309,108 @@ int set_usb_string(uint8_t *buf, const char *str) void usb_send_msg(USBDevice *dev, int msg) { USBPacket p; + int ret; + memset(&p, 0, sizeof(p)); p.pid = msg; - dev->info->handle_packet(dev, &p); - + ret = usb_handle_packet(dev, &p); /* This _must_ be synchronous */ + assert(ret != USB_RET_ASYNC); +} + +/* Hand over a packet to a device for processing. Return value + USB_RET_ASYNC indicates the processing isn't finished yet, the + driver will call usb_packet_complete() when done processing it. */ +int usb_handle_packet(USBDevice *dev, USBPacket *p) +{ + int ret; + + assert(p->owner == NULL); + ret = dev->info->handle_packet(dev, p); + if (ret == USB_RET_ASYNC) { + if (p->owner == NULL) { + p->owner = dev; + } else { + /* We'll end up here when usb_handle_packet is called + * recursively due to a hub being in the chain. Nothing + * to do. Leave p->owner pointing to the device, not the + * hub. */; + } + } + return ret; +} + +/* Notify the controller that an async packet is complete. This should only + be called for packets previously deferred by returning USB_RET_ASYNC from + handle_packet. */ +void usb_packet_complete(USBDevice *dev, USBPacket *p) +{ + /* Note: p->owner != dev is possible in case dev is a hub */ + assert(p->owner != NULL); + p->owner = NULL; + dev->port->ops->complete(dev->port, p); +} + +/* Cancel an active packet. The packed must have been deferred by + returning USB_RET_ASYNC from handle_packet, and not yet + completed. */ +void usb_cancel_packet(USBPacket * p) +{ + assert(p->owner != NULL); + p->owner->info->cancel_packet(p->owner, p); + p->owner = NULL; +} + + +void usb_packet_init(USBPacket *p) +{ + qemu_iovec_init(&p->iov, 1); +} + +void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep) +{ + p->pid = pid; + p->devaddr = addr; + p->devep = ep; + p->result = 0; + qemu_iovec_reset(&p->iov); +} + +void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len) +{ + qemu_iovec_add(&p->iov, ptr, len); +} + +void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes) +{ + assert(p->result >= 0); + assert(p->result + bytes <= p->iov.size); + switch (p->pid) { + case USB_TOKEN_SETUP: + case USB_TOKEN_OUT: + iov_to_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes); + break; + case USB_TOKEN_IN: + iov_from_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes); + break; + default: + fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid); + abort(); + } + p->result += bytes; +} + +void usb_packet_skip(USBPacket *p, size_t bytes) +{ + assert(p->result >= 0); + assert(p->result + bytes <= p->iov.size); + if (p->pid == USB_TOKEN_IN) { + iov_clear(p->iov.iov, p->iov.niov, p->result, bytes); + } + p->result += bytes; +} + +void usb_packet_cleanup(USBPacket *p) +{ + qemu_iovec_destroy(&p->iov); } diff --git a/hw/usb.h b/hw/usb.h index d3d755d..c6e1870 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -26,6 +26,12 @@ #include "qdev.h" #include "qemu-queue.h" +/* Constants related to the USB / PCI interaction */ +#define USB_SBRN 0x60 /* Serial Bus Release Number Register */ +#define USB_RELEASE_1 0x10 /* USB 1.0 */ +#define USB_RELEASE_2 0x20 /* USB 2.0 */ +#define USB_RELEASE_3 0x30 /* USB 3.0 */ + #define USB_TOKEN_SETUP 0x2d #define USB_TOKEN_IN 0x69 /* device -> host */ #define USB_TOKEN_OUT 0xe1 /* host -> device */ @@ -124,6 +130,8 @@ #define USB_DT_ENDPOINT 0x05 #define USB_DT_DEVICE_QUALIFIER 0x06 #define USB_DT_OTHER_SPEED_CONFIG 0x07 +#define USB_DT_DEBUG 0x0A +#define USB_DT_INTERFACE_ASSOC 0x0B #define USB_ENDPOINT_XFER_CONTROL 0 #define USB_ENDPOINT_XFER_ISOC 1 @@ -131,6 +139,7 @@ #define USB_ENDPOINT_XFER_INT 3 typedef struct USBBus USBBus; +typedef struct USBBusOps USBBusOps; typedef struct USBPort USBPort; typedef struct USBDevice USBDevice; typedef struct USBDeviceInfo USBDeviceInfo; @@ -140,6 +149,7 @@ typedef struct USBDesc USBDesc; typedef struct USBDescID USBDescID; typedef struct USBDescDevice USBDescDevice; typedef struct USBDescConfig USBDescConfig; +typedef struct USBDescIfaceAssoc USBDescIfaceAssoc; typedef struct USBDescIface USBDescIface; typedef struct USBDescEndpoint USBDescEndpoint; typedef struct USBDescOther USBDescOther; @@ -159,7 +169,10 @@ struct USBDevice { char *port_path; void *opaque; + /* Actual connected speed */ int speed; + /* Supported speeds, not in info because it may be variable (hostdevs) */ + int speedmask; uint8_t addr; char product_desc[32]; int auto_attach; @@ -167,7 +180,7 @@ struct USBDevice { int32_t state; uint8_t setup_buf[8]; - uint8_t data_buf[1024]; + uint8_t data_buf[4096]; int32_t remote_wakeup; int32_t setup_state; int32_t setup_len; @@ -192,6 +205,11 @@ struct USBDeviceInfo { int (*handle_packet)(USBDevice *dev, USBPacket *p); /* + * Called when a packet is canceled. + */ + void (*cancel_packet)(USBDevice *dev, USBPacket *p); + + /* * Called when device is destroyed. */ void (*handle_destroy)(USBDevice *dev); @@ -212,7 +230,7 @@ struct USBDeviceInfo { * * Returns length or one of the USB_RET_ codes. */ - int (*handle_control)(USBDevice *dev, int request, int value, + int (*handle_control)(USBDevice *dev, USBPacket *p, int request, int value, int index, int length, uint8_t *data); /* @@ -234,7 +252,18 @@ struct USBDeviceInfo { typedef struct USBPortOps { void (*attach)(USBPort *port); void (*detach)(USBPort *port); - void (*wakeup)(USBDevice *dev); + /* + * This gets called when a device downstream from the device attached to + * the port (iow attached through a hub) gets detached. + */ + void (*child_detach)(USBPort *port, USBDevice *child); + void (*wakeup)(USBPort *port); + /* + * Note that port->dev will be different then the device from which + * the packet originated when a hub is involved, if you want the orginating + * device use p->owner + */ + void (*complete)(USBPort *port, USBPacket *p); } USBPortOps; /* USB port on which a device can be connected */ @@ -256,43 +285,31 @@ struct USBPacket { int pid; uint8_t devaddr; uint8_t devep; - uint8_t *data; - int len; + QEMUIOVector iov; + int result; /* transfer length or USB_RET_* status code */ /* Internal use by the USB layer. */ - USBCallback *complete_cb; - void *complete_opaque; - USBCallback *cancel_cb; - void *cancel_opaque; + USBDevice *owner; }; -/* Defer completion of a USB packet. The hadle_packet routine should then - return USB_RET_ASYNC. Packets that complete immediately (before - handle_packet returns) should not call this method. */ -static inline void usb_defer_packet(USBPacket *p, USBCallback *cancel, - void * opaque) -{ - p->cancel_cb = cancel; - p->cancel_opaque = opaque; -} - -/* Notify the controller that an async packet is complete. This should only - be called for packets previously deferred with usb_defer_packet, and - should never be called from within handle_packet. */ -static inline void usb_packet_complete(USBPacket *p) -{ - p->complete_cb(p, p->complete_opaque); -} - -/* Cancel an active packet. The packed must have been deferred with - usb_defer_packet, and not yet completed. */ -static inline void usb_cancel_packet(USBPacket * p) -{ - p->cancel_cb(p, p->cancel_opaque); -} - -void usb_attach(USBPort *port, USBDevice *dev); +void usb_packet_init(USBPacket *p); +void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep); +void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len); +int usb_packet_map(USBPacket *p, QEMUSGList *sgl); +void usb_packet_unmap(USBPacket *p); +void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes); +void usb_packet_skip(USBPacket *p, size_t bytes); +void usb_packet_cleanup(USBPacket *p); + +int usb_handle_packet(USBDevice *dev, USBPacket *p); +void usb_packet_complete(USBDevice *dev, USBPacket *p); +void usb_cancel_packet(USBPacket * p); + +void usb_attach(USBPort *port); +void usb_detach(USBPort *port); +void usb_reset(USBPort *port); void usb_wakeup(USBDevice *dev); int usb_generic_handle_packet(USBDevice *s, USBPacket *p); +void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p); int set_usb_string(uint8_t *buf, const char *str); void usb_send_msg(USBDevice *dev, int msg); @@ -301,9 +318,6 @@ USBDevice *usb_host_device_open(const char *devname); int usb_host_device_close(const char *devname); void usb_host_info(Monitor *mon); -/* usb-hid.c */ -void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); - /* usb-bt.c */ USBDevice *usb_bt_init(HCIInfo *hci); @@ -325,11 +339,13 @@ enum musb_irq_source_e { musb_irq_tx, musb_set_vbus, musb_set_session, - __musb_irq_max, + /* Add new interrupts here */ + musb_irq_max, /* total number of interrupts defined */ }; typedef struct MUSBState MUSBState; -MUSBState *musb_init(qemu_irq *irqs); +MUSBState *musb_init(DeviceState *parent_device, int gpio_base); +void musb_reset(MUSBState *s); uint32_t musb_core_intr_get(MUSBState *s); void musb_core_intr_clear(MUSBState *s, uint32_t mask); void musb_set_size(MUSBState *s, int epnum, int size, int is_tx); @@ -338,6 +354,7 @@ void musb_set_size(MUSBState *s, int epnum, int size, int is_tx); struct USBBus { BusState qbus; + USBBusOps *ops; int busnr; int nfree; int nused; @@ -346,7 +363,12 @@ struct USBBus { QTAILQ_ENTRY(USBBus) next; }; -void usb_bus_new(USBBus *bus, DeviceState *host); +struct USBBusOps { + int (*register_companion)(USBBus *bus, USBPort *ports[], + uint32_t portcount, uint32_t firstport); +}; + +void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host); USBBus *usb_bus_find(int busnr); void usb_qdev_register(USBDeviceInfo *info); void usb_qdev_register_many(USBDeviceInfo *info); @@ -355,8 +377,13 @@ USBDevice *usb_create_simple(USBBus *bus, const char *name); USBDevice *usbdevice_create(const char *cmdline); void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, USBPortOps *ops, int speedmask); +int usb_register_companion(const char *masterbus, USBPort *ports[], + uint32_t portcount, uint32_t firstport, + void *opaque, USBPortOps *ops, int speedmask); void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr); void usb_unregister_port(USBBus *bus, USBPort *port); +int usb_claim_port(USBDevice *dev); +void usb_release_port(USBDevice *dev); int usb_device_attach(USBDevice *dev); int usb_device_detach(USBDevice *dev); int usb_device_delete_addr(int busnr, int addr); diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 2fed8a0..8a88696 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -4,18 +4,21 @@ * Copyright (c) 2006-2009 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the LGPL. + * This code is licensed under the LGPL. */ #include "sysbus.h" #include "pci.h" #include "pci_host.h" +#include "exec-memory.h" typedef struct { SysBusDevice busdev; qemu_irq irq[4]; int realview; - int mem_config; + MemoryRegion mem_config; + MemoryRegion mem_config2; + MemoryRegion isa; } PCIVPBState; static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr) @@ -23,55 +26,24 @@ static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr) return addr & 0xffffff; } -static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr, - uint32_t val) +static void pci_vpb_config_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1); + pci_data_write(opaque, vpb_pci_config_addr(addr), val, size); } -static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2); -} - -static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr, - uint32_t val) -{ - pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4); -} - -static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr) -{ - uint32_t val; - val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1); - return val; -} - -static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr) -{ - uint32_t val; - val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2); - return val; -} - -static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr) +static uint64_t pci_vpb_config_read(void *opaque, target_phys_addr_t addr, + unsigned size) { uint32_t val; - val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4); + val = pci_data_read(opaque, vpb_pci_config_addr(addr), size); return val; } -static CPUWriteMemoryFunc * const pci_vpb_config_write[] = { - &pci_vpb_config_writeb, - &pci_vpb_config_writew, - &pci_vpb_config_writel, -}; - -static CPUReadMemoryFunc * const pci_vpb_config_read[] = { - &pci_vpb_config_readb, - &pci_vpb_config_readw, - &pci_vpb_config_readl, +static const MemoryRegionOps pci_vpb_config_ops = { + .read = pci_vpb_config_read, + .write = pci_vpb_config_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; static int pci_vpb_map_irq(PCIDevice *d, int irq_num) @@ -86,20 +58,6 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } -static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base) -{ - PCIVPBState *s = (PCIVPBState *)dev; - /* Selfconfig area. */ - cpu_register_physical_memory(base + 0x01000000, 0x1000000, s->mem_config); - /* Normal config area. */ - cpu_register_physical_memory(base + 0x02000000, 0x1000000, s->mem_config); - - if (s->realview) { - /* IO memory area. */ - isa_mmio_init(base + 0x03000000, 0x00100000); - } -} - static int pci_vpb_init(SysBusDevice *dev) { PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); @@ -111,14 +69,26 @@ static int pci_vpb_init(SysBusDevice *dev) } bus = pci_register_bus(&dev->qdev, "pci", pci_vpb_set_irq, pci_vpb_map_irq, s->irq, + get_system_memory(), get_system_io(), PCI_DEVFN(11, 0), 4); /* ??? Register memory space. */ - s->mem_config = cpu_register_io_memory(pci_vpb_config_read, - pci_vpb_config_write, bus, - DEVICE_LITTLE_ENDIAN); - sysbus_init_mmio_cb(dev, 0x04000000, pci_vpb_map); + /* Our memory regions are: + * 0 : PCI self config window + * 1 : PCI config window + * 2 : PCI IO window (realview_pci only) + */ + memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus, + "pci-vpb-selfconfig", 0x1000000); + sysbus_init_mmio_region(dev, &s->mem_config); + memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus, + "pci-vpb-config", 0x1000000); + sysbus_init_mmio_region(dev, &s->mem_config2); + if (s->realview) { + isa_mmio_setup(&s->isa, 0x0100000); + sysbus_init_mmio_region(dev, &s->isa); + } pci_create_simple(bus, -1, "versatile_pci_host"); return 0; @@ -133,12 +103,8 @@ static int pci_realview_init(SysBusDevice *dev) static int versatile_pci_host_init(PCIDevice *d) { - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX); - /* Both boards have the same device ID. Oh well. */ - pci_config_set_device_id(d->config, PCI_DEVICE_ID_XILINX_XC2VP30); pci_set_word(d->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); - pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO); pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10); return 0; } @@ -147,6 +113,10 @@ static PCIDeviceInfo versatile_pci_host_info = { .qdev.name = "versatile_pci_host", .qdev.size = sizeof(PCIDevice), .init = versatile_pci_host_init, + .vendor_id = PCI_VENDOR_ID_XILINX, + /* Both boards have the same device ID. Oh well. */ + .device_id = PCI_DEVICE_ID_XILINX_XC2VP30, + .class_id = PCI_CLASS_PROCESSOR_CO, }; static void versatile_pci_register_devices(void) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 9f1bfcf..6370600 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -4,7 +4,7 @@ * Copyright (c) 2005-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -180,7 +180,9 @@ static void versatile_init(ram_addr_t ram_size, qemu_irq *cpu_pic; qemu_irq pic[32]; qemu_irq sic[32]; - DeviceState *dev; + DeviceState *dev, *sysctl; + SysBusDevice *busdev; + DeviceState *pl041; PCIBus *pci_bus; NICInfo *nd; int n; @@ -198,7 +200,12 @@ static void versatile_init(ram_addr_t ram_size, /* SDRAM at address zero. */ cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); - arm_sysctl_init(0x10000000, 0x41007004, 0x02000000); + sysctl = qdev_create(NULL, "realview_sysctl"); + qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004); + qdev_init_nofail(sysctl); + qdev_prop_set_uint32(sysctl, "proc_id", 0x02000000); + sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); + cpu_pic = arm_pic_init_cpu(env); dev = sysbus_create_varargs("pl190", 0x10140000, cpu_pic[0], cpu_pic[1], NULL); @@ -214,8 +221,15 @@ static void versatile_init(ram_addr_t ram_size, sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]); sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]); - dev = sysbus_create_varargs("versatile_pci", 0x40000000, - sic[27], sic[28], sic[29], sic[30], NULL); + dev = qdev_create(NULL, "versatile_pci"); + busdev = sysbus_from_qdev(dev); + qdev_init_nofail(dev); + sysbus_mmio_map(busdev, 0, 0x41000000); /* PCI self-config */ + sysbus_mmio_map(busdev, 1, 0x42000000); /* PCI config */ + sysbus_connect_irq(busdev, 0, sic[27]); + sysbus_connect_irq(busdev, 1, sic[28]); + sysbus_connect_irq(busdev, 2, sic[29]); + sysbus_connect_irq(busdev, 3, sic[30]); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); /* The Versatile PCI bridge does not provide access to PCI IO space, @@ -223,7 +237,7 @@ static void versatile_init(ram_addr_t ram_size, for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; - if ((!nd->model && !done_smc) || strcmp(nd->model, "smc91c111") == 0) { + if (!done_smc && (!nd->model || strcmp(nd->model, "smc91c111") == 0)) { smc91c111_init(nd, 0x10010000, sic[25]); done_smc = 1; } else { @@ -250,7 +264,9 @@ static void versatile_init(ram_addr_t ram_size, /* The versatile/PB actually has a modified Color LCD controller that includes hardware cursor support from the PL111. */ - sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]); + dev = sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]); + /* Wire up the mux control signals from the SYS_CLCD register */ + qdev_connect_gpio_out(sysctl, 0, qdev_get_gpio_in(dev, 0)); sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL); sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL); @@ -258,6 +274,13 @@ static void versatile_init(ram_addr_t ram_size, /* Add PL031 Real Time Clock. */ sysbus_create_simple("pl031", 0x101e8000, pic[10]); + /* Add PL041 AACI Interface to the LM4549 codec */ + pl041 = qdev_create(NULL, "pl041"); + qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); + qdev_init_nofail(pl041); + sysbus_mmio_map(sysbus_from_qdev(pl041), 0, 0x10004000); + sysbus_connect_irq(sysbus_from_qdev(pl041), 0, sic[24]); + /* Memory map for Versatile/PB: */ /* 0x10000000 System registers. */ /* 0x10001000 PCI controller config registers. */ diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c index 4954bb1..f8984c6 100644 --- a/hw/vga-isa-mm.c +++ b/hw/vga-isa-mm.c @@ -79,50 +79,61 @@ static void vga_mm_writel (void *opaque, vga_ioport_write(&s->vga, addr >> s->it_shift, value); } -static CPUReadMemoryFunc * const vga_mm_read_ctrl[] = { - &vga_mm_readb, - &vga_mm_readw, - &vga_mm_readl, -}; - -static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = { - &vga_mm_writeb, - &vga_mm_writew, - &vga_mm_writel, +static const MemoryRegionOps vga_mm_ctrl_ops = { + .old_mmio = { + .read = { + vga_mm_readb, + vga_mm_readw, + vga_mm_readl, + }, + .write = { + vga_mm_writeb, + vga_mm_writew, + vga_mm_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base, - target_phys_addr_t ctrl_base, int it_shift) + target_phys_addr_t ctrl_base, int it_shift, + MemoryRegion *address_space) { - int s_ioport_ctrl, vga_io_memory; + MemoryRegion *s_ioport_ctrl, *vga_io_memory; s->it_shift = it_shift; - s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s, - DEVICE_NATIVE_ENDIAN); - vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s, - DEVICE_NATIVE_ENDIAN); + s_ioport_ctrl = g_malloc(sizeof(*s_ioport_ctrl)); + memory_region_init_io(s_ioport_ctrl, &vga_mm_ctrl_ops, s, + "vga-mm-ctrl", 0x100000); + + vga_io_memory = g_malloc(sizeof(*vga_io_memory)); + /* XXX: endianness? */ + memory_region_init_io(vga_io_memory, &vga_mem_ops, &s->vga, + "vga-mem", 0x20000); vmstate_register(NULL, 0, &vmstate_vga_common, s); - cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl); + memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl); s->vga.bank_offset = 0; - cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory); - qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000); + memory_region_add_subregion(address_space, + vram_base + 0x000a0000, vga_io_memory); + memory_region_set_coalescing(vga_io_memory); } int isa_vga_mm_init(target_phys_addr_t vram_base, - target_phys_addr_t ctrl_base, int it_shift) + target_phys_addr_t ctrl_base, int it_shift, + MemoryRegion *address_space) { ISAVGAMMState *s; - s = qemu_mallocz(sizeof(*s)); + s = g_malloc0(sizeof(*s)); vga_common_init(&s->vga, VGA_RAM_SIZE); - vga_mm_init(s, vram_base, ctrl_base, it_shift); + vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space); s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate, s->vga.screen_dump, s->vga.text_update, s); - vga_init_vbe(&s->vga); + vga_init_vbe(&s->vga, address_space); return 0; } diff --git a/hw/vga-isa.c b/hw/vga-isa.c index 3046054..4825313 100644 --- a/hw/vga-isa.c +++ b/hw/vga-isa.c @@ -29,21 +29,56 @@ #include "qemu-timer.h" #include "loader.h" -int isa_vga_init(void) +typedef struct ISAVGAState { + ISADevice dev; + struct VGACommonState state; +} ISAVGAState; + +static void vga_reset_isa(DeviceState *dev) { - VGACommonState *s; + ISAVGAState *d = container_of(dev, ISAVGAState, dev.qdev); + VGACommonState *s = &d->state; - s = qemu_mallocz(sizeof(*s)); + vga_common_reset(s); +} - vga_common_init(s, VGA_RAM_SIZE); - vga_init(s); - vmstate_register(NULL, 0, &vmstate_vga_common, s); +static int vga_initfn(ISADevice *dev) +{ + ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev); + VGACommonState *s = &d->state; + MemoryRegion *vga_io_memory; + const MemoryRegionPortio *vga_ports, *vbe_ports; + vga_common_init(s, VGA_RAM_SIZE); + s->legacy_address_space = isa_address_space(dev); + vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports); + isa_register_portio_list(dev, 0x3b0, vga_ports, s, "vga"); + if (vbe_ports) { + isa_register_portio_list(dev, 0x1ce, vbe_ports, s, "vbe"); + } + memory_region_add_subregion_overlap(isa_address_space(dev), + isa_mem_base + 0x000a0000, + vga_io_memory, 1); + memory_region_set_coalescing(vga_io_memory); s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s); - vga_init_vbe(s); + vga_init_vbe(s, isa_address_space(dev)); /* ROM BIOS */ rom_add_vga(VGABIOS_FILENAME); return 0; } + +static ISADeviceInfo vga_info = { + .qdev.name = "isa-vga", + .qdev.size = sizeof(ISAVGAState), + .qdev.vmsd = &vmstate_vga_common, + .qdev.reset = vga_reset_isa, + .init = vga_initfn, +}; + +static void vga_register(void) +{ + isa_qdev_register(&vga_info); +} +device_init(vga_register) diff --git a/hw/vga-pci.c b/hw/vga-pci.c index 098733c..0e509ff 100644 --- a/hw/vga-pci.c +++ b/hw/vga-pci.c @@ -29,12 +29,22 @@ #include "pixel_ops.h" #include "qemu-timer.h" #include "loader.h" +#ifdef CONFIG_MARU +#include "../tizen/src/hw/maru_device_ids.h" +#include "../tizen/src/hw/maru_vga_int.h" +#endif typedef struct PCIVGAState { PCIDevice dev; VGACommonState vga; } PCIVGAState; +int pci_vga_init(PCIBus *bus) +{ + pci_create_simple(bus, -1, "VGA"); + return 0; +} + static const VMStateDescription vmstate_vga_pci = { .name = "vga", .version_id = 2, @@ -47,95 +57,95 @@ static const VMStateDescription vmstate_vga_pci = { } }; -static void vga_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - PCIVGAState *d = (PCIVGAState *)pci_dev; - VGACommonState *s = &d->vga; - - cpu_register_physical_memory(addr, s->vram_size, s->vram_offset); - s->map_addr = addr; - s->map_end = addr + s->vram_size; - vga_dirty_log_start(s); -} - -static void pci_vga_write_config(PCIDevice *d, - uint32_t address, uint32_t val, int len) -{ - PCIVGAState *pvs = container_of(d, PCIVGAState, dev); - VGACommonState *s = &pvs->vga; - - pci_default_write_config(d, address, val, len); - if (s->map_addr && pvs->dev.io_regions[0].addr == -1) - s->map_addr = 0; -} - static int pci_vga_initfn(PCIDevice *dev) { PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev); VGACommonState *s = &d->vga; - uint8_t *pci_conf = d->dev.config; // vga + console init vga_common_init(s, VGA_RAM_SIZE); - vga_init(s); + vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true); s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s); - // dummy VGA (same as Bochs ID) - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_QEMU); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_QEMU_VGA); - pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA); - /* XXX: VGA_RAM_SIZE must be a power of two */ - pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); if (!dev->rom_bar) { /* compatibility with pc-0.13 and older */ - vga_init_vbe(s); + vga_init_vbe(s, pci_address_space(dev)); } return 0; } -int pci_vga_init(PCIBus *bus) -{ - pci_create_simple(bus, -1, "VGA"); - return 0; -} - static PCIDeviceInfo vga_info = { .qdev.name = "VGA", .qdev.size = sizeof(PCIVGAState), .qdev.vmsd = &vmstate_vga_pci, .no_hotplug = 1, .init = pci_vga_initfn, - .config_write = pci_vga_write_config, .romfile = "vgabios-stdvga.bin", + + /* dummy VGA (same as Bochs ID) */ + .vendor_id = PCI_VENDOR_ID_QEMU, + .device_id = PCI_DEVICE_ID_QEMU_VGA, + .class_id = PCI_CLASS_DISPLAY_VGA, }; -int pci_tizen_vga_init(PCIBus *bus) +#ifdef CONFIG_MARU + +int pci_maru_vga_init(PCIBus *bus) { - pci_create_simple(bus, -1, "TIZEN_VGA"); + pci_create_simple(bus, -1, "MARU_VGA"); return 0; } -static PCIDeviceInfo tizen_vga_info = { - .qdev.name = "TIZEN_VGA", +static int maru_pci_vga_initfn(PCIDevice *dev) +{ + PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev); + VGACommonState *s = &d->vga; + + // vga + console init + maru_vga_common_init(s, VGA_RAM_SIZE); + vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true); + + s->ds = graphic_console_init(s->update, s->invalidate, + s->screen_dump, s->text_update, s); + + /* XXX: VGA_RAM_SIZE must be a power of two */ + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); + + if (!dev->rom_bar) { + /* compatibility with pc-0.13 and older */ + vga_init_vbe(s, pci_address_space(dev)); + } + + return 0; +} + +static PCIDeviceInfo maru_vga_info = { + .qdev.name = "MARU_VGA", .qdev.size = sizeof(PCIVGAState), .qdev.vmsd = &vmstate_vga_pci, .no_hotplug = 1, - .init = pci_vga_initfn, - .config_write = pci_vga_write_config, - .romfile = "vgabios-tizenvga.bin", + .init = maru_pci_vga_initfn, + .romfile = "vgabios-maruvga.bin", + + /* dummy VGA (same as Bochs ID) */ + .vendor_id = PCI_VENDOR_ID_QEMU, + .device_id = PCI_DEVICE_ID_QEMU_VGA, + .class_id = PCI_CLASS_DISPLAY_VGA, }; +#endif // CONFIG_MARU + static void vga_register(void) { pci_qdev_register(&vga_info); -// by caramis... - pci_qdev_register(&tizen_vga_info); +#ifdef CONFIG_MARU + pci_qdev_register(&maru_vga_info); +#endif } device_init(vga_register); diff --git a/hw/vga.c b/hw/vga.c old mode 100755 new mode 100644 index a7649ec..ca79aa1 --- a/hw/vga.c +++ b/hw/vga.c @@ -28,7 +28,6 @@ #include "vga_int.h" #include "pixel_ops.h" #include "qemu-timer.h" -#include "kvm.h" //#define DEBUG_VGA //#define DEBUG_VGA_MEM @@ -150,9 +149,53 @@ static uint16_t expand2[256]; static uint8_t expand4to8[16]; static void vga_screen_dump(void *opaque, const char *filename); -static char *screen_dump_filename; +static const char *screen_dump_filename; static DisplayChangeListener *screen_dump_dcl; +static void vga_update_memory_access(VGACommonState *s) +{ + MemoryRegion *region, *old_region = s->chain4_alias; + target_phys_addr_t base, offset, size; + + s->chain4_alias = NULL; + + if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) { + offset = 0; + switch ((s->gr[6] >> 2) & 3) { + case 0: + base = 0xa0000; + size = 0x20000; + break; + case 1: + base = 0xa0000; + size = 0x10000; + offset = s->bank_offset; + break; + case 2: + base = 0xb0000; + size = 0x8000; + break; + case 3: + default: + base = 0xb8000; + size = 0x8000; + break; + } + base += isa_mem_base; + region = g_malloc(sizeof(*region)); + memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size); + memory_region_add_subregion_overlap(s->legacy_address_space, base, + region, 2); + s->chain4_alias = region; + } + if (old_region) { + memory_region_del_subregion(s->legacy_address_space, old_region); + memory_region_destroy(old_region); + g_free(old_region); + s->plane_updated = 0xf; + } +} + static void vga_dumb_update_retrace_info(VGACommonState *s) { (void) s; @@ -261,7 +304,7 @@ static uint8_t vga_precise_retrace(VGACommonState *s) int cur_line, cur_line_char, cur_char; int64_t cur_tick; - cur_tick = qemu_get_clock(vm_clock); + cur_tick = qemu_get_clock_ns(vm_clock); cur_char = (cur_tick / r->ticks_per_char) % r->total_chars; cur_line = cur_char / r->htotal; @@ -446,6 +489,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) #endif s->sr[s->sr_index] = val & sr_mask[s->sr_index]; if (s->sr_index == 1) s->update_retrace_info(s); + vga_update_memory_access(s); break; case 0x3c7: s->dac_read_index = val; @@ -473,6 +517,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) printf("vga: write GR%x = 0x%02x\n", s->gr_index, val); #endif s->gr[s->gr_index] = val & gr_mask[s->gr_index]; + vga_update_memory_access(s); break; case 0x3b4: case 0x3d4: @@ -606,6 +651,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) } s->vbe_regs[s->vbe_index] = val; s->bank_offset = (val << 16); + vga_update_memory_access(s); break; case VBE_DISPI_INDEX_ENABLE: if ((val & VBE_DISPI_ENABLED) && @@ -665,6 +711,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) } s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0; s->vbe_regs[s->vbe_index] = val; + vga_update_memory_access(s); break; case VBE_DISPI_INDEX_VIRT_WIDTH: { @@ -708,9 +755,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) #endif /* called for accesses between 0xa0000 and 0xc0000 */ -uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr) +uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr) { - VGACommonState *s = opaque; int memory_map_mode, plane; uint32_t ret; @@ -764,28 +810,9 @@ uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - v = vga_mem_readb(opaque, addr); - v |= vga_mem_readb(opaque, addr + 1) << 8; - return v; -} - -static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr) -{ - uint32_t v; - v = vga_mem_readb(opaque, addr); - v |= vga_mem_readb(opaque, addr + 1) << 8; - v |= vga_mem_readb(opaque, addr + 2) << 16; - v |= vga_mem_readb(opaque, addr + 3) << 24; - return v; -} - /* called for accesses between 0xa0000 and 0xc0000 */ -void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val) { - VGACommonState *s = opaque; int memory_map_mode, plane, write_mode, b, func_select, mask; uint32_t write_mask, bit_mask, set_mask; @@ -826,7 +853,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr); #endif s->plane_updated |= mask; /* only used to detect font change */ - cpu_physical_memory_set_dirty(s->vram_offset + addr); + memory_region_set_dirty(&s->vram, addr); } } else if (s->gr[5] & 0x10) { /* odd/even mode (aka text mode mapping) */ @@ -839,7 +866,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr); #endif s->plane_updated |= mask; /* only used to detect font change */ - cpu_physical_memory_set_dirty(s->vram_offset + addr); + memory_region_set_dirty(&s->vram, addr); } } else { /* standard VGA latched access */ @@ -913,24 +940,10 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n", addr * 4, write_mask, val); #endif - cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2)); + memory_region_set_dirty(&s->vram, addr << 2); } } -static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - vga_mem_writeb(opaque, addr, val & 0xff); - vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - vga_mem_writeb(opaque, addr, val & 0xff); - vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); - vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff); - vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, const uint8_t *font_ptr, int h, uint32_t fgcol, uint32_t bgcol); @@ -1273,7 +1286,7 @@ static void vga_draw_text(VGACommonState *s, int full_update) s->font_offsets[1] = offset; full_update = 1; } - if (s->plane_updated & (1 << 2)) { + if (s->plane_updated & (1 << 2) || s->chain4_alias) { /* if the plane 2 was modified since the last display, it indicates the font may have been modified */ s->plane_updated = 0; @@ -1554,89 +1567,22 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2) static void vga_sync_dirty_bitmap(VGACommonState *s) { - if (s->map_addr) - cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end); - - if (s->lfb_vram_mapped) { - cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000); - cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000); - } - -#ifdef CONFIG_BOCHS_VBE - if (s->vbe_mapped) { - cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size); - } -#endif - + memory_region_sync_dirty_bitmap(&s->vram); } void vga_dirty_log_start(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_start(s->map_addr, s->map_end - s->map_addr); - - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_start(isa_mem_base + 0xa0000, 0x8000); - kvm_log_start(isa_mem_base + 0xa8000, 0x8000); - } - -#ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); - } -#endif + memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA); } void vga_dirty_log_stop(VGACommonState *s) { - if (kvm_enabled() && s->map_addr) - kvm_log_stop(s->map_addr, s->map_end - s->map_addr); - - if (kvm_enabled() && s->lfb_vram_mapped) { - kvm_log_stop(isa_mem_base + 0xa0000, 0x8000); - kvm_log_stop(isa_mem_base + 0xa8000, 0x8000); - } - -#ifdef CONFIG_BOCHS_VBE - if (kvm_enabled() && s->vbe_mapped) { - kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); - } -#endif -} - -void vga_dirty_log_restart(VGACommonState *s) -{ - vga_dirty_log_stop(s); - vga_dirty_log_start(s); + memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA); } /* -* graphic modes -*/ -#if defined (TARGET_I386) -extern uint8_t overlay0_power; -extern uint16_t overlay0_left; -extern uint16_t overlay0_top; -extern uint16_t overlay0_width; -extern uint16_t overlay0_height; - -extern uint8_t overlay1_power; -extern uint16_t overlay1_left; -extern uint16_t overlay1_top; -extern uint16_t overlay1_width; -extern uint16_t overlay1_height; - -extern uint8_t* overlay_ptr; // pointer in qemu space - -/* brightness level : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 */ -//static const uint8_t brightness_tbl[] = {20, 100, 120, 140, 160, 180, 200, 220, 230, 240}; -static const uint8_t brightness_tbl[] = {20, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, - 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240}; -extern uint32_t brightness_level; -extern uint32_t brightness_off; -#endif - + * graphic modes + */ static void vga_draw_graphic(VGACommonState *s, int full_update) { int y1, y, update, linesize, y_start, double_scan, mask, depth; @@ -1693,7 +1639,9 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) if (depth == 32) { #endif qemu_free_displaysurface(s->ds); - s->ds->surface = qemu_create_displaysurface(s->ds, disp_width, height); + s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth, + s->line_offset, + s->vram_ptr + (s->start_addr * 4)); #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) s->ds->surface->pf = qemu_different_endianness_pixelformat(depth); #endif @@ -1793,21 +1741,19 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) if (!(s->cr[0x17] & 2)) { addr = (addr & ~0x8000) | ((y1 & 2) << 14); } - page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); - page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); + page0 = addr & TARGET_PAGE_MASK; + page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK; update = full_update | - cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | - cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); + memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) | + memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA); if ((page1 - page0) > TARGET_PAGE_SIZE) { /* if wide line, can use another page */ - update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); + update |= memory_region_get_dirty(&s->vram, + page0 + TARGET_PAGE_SIZE, + DIRTY_MEMORY_VGA); } /* explicit invalidation for the hardware cursor */ update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; -#if defined (TARGET_I386) - update |= 1; // sucking architecture causes low performance. sorry. -#endif if (update) { if (y_start < 0) y_start = y; @@ -1817,76 +1763,9 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) page_max = page1; if (!(is_buffer_shared(s->ds->surface))) { vga_draw_line(s, d, s->vram_ptr + addr, width); - } -#if defined (TARGET_I386) - int i; - uint8_t *fb_sub; - uint8_t *over_sub; - uint8_t *dst_sub; - uint8_t alpha, c_alpha; - uint32_t *dst; - uint16_t overlay_bottom; - - if (overlay0_power) { - overlay_bottom = overlay0_top + overlay0_height; - - if (overlay0_top <= y && y < overlay_bottom) { - fb_sub = s->vram_ptr + addr + overlay0_left * 4; - over_sub = overlay_ptr + (y - overlay0_top) * overlay0_width * 4; - dst = (uint32_t*)(s->ds->surface->data + addr + overlay0_left * 4); - - for (i = 0; i < overlay0_width; i++, fb_sub += 4, over_sub += 4, dst++) { - //alpha = 0x80; - alpha = fb_sub[3]; - c_alpha = 0xff - alpha; - //fprintf(stderr, "alpha = %d\n", alpha); - - *dst = ((c_alpha * over_sub[0] + alpha * fb_sub[0]) >> 8) | - ((c_alpha * over_sub[1] + alpha * fb_sub[1]) & 0xFF00) | - (((c_alpha * over_sub[2] + alpha * fb_sub[2]) & 0xFF00) << 8); - } - } + if (s->cursor_draw_line) + s->cursor_draw_line(s, d, y); } - - if (overlay1_power) { - overlay_bottom = overlay1_top + overlay1_height; - - if (overlay1_top <= y && y < overlay_bottom) { - fb_sub = s->vram_ptr + addr + overlay1_left * 4; - over_sub = overlay_ptr + (y - overlay1_top) * overlay1_width * 4 + 0x00400000; - dst = (uint32_t*)(s->ds->surface->data + addr + overlay1_left * 4); - - for (i = 0; i < overlay1_width; i++, fb_sub += 4, over_sub += 4, dst++) { - //alpha = 0x80; - alpha = fb_sub[3]; - c_alpha = 0xff - alpha; - //fprintf(stderr, "alpha = %d\n", alpha); - - *dst = ((c_alpha * over_sub[0] + alpha * fb_sub[0]) >> 8) | - ((c_alpha * over_sub[1] + alpha * fb_sub[1]) & 0xFF00) | - (((c_alpha * over_sub[2] + alpha * fb_sub[2]) & 0xFF00) << 8); - } - } - } - - if( brightness_off ) { - alpha = 0x00; - }else if (brightness_level < 24) { - alpha = brightness_tbl[brightness_level]; - } - - if ( brightness_off || brightness_level < 24 ) { - dst_sub = s->ds->surface->data + addr; - dst = (uint32_t*)(s->ds->surface->data + addr); - - for (i=0; i < disp_width; i++, dst_sub += 4, dst++) { - *dst = ((alpha * dst_sub[0]) >> 8) | - ((alpha * dst_sub[1]) & 0xFF00) | - (((alpha * dst_sub[2]) & 0xFF00) << 8); - } - } -#endif /* TARGET_I386 */ - } else { if (y_start >= 0) { /* flush to display */ @@ -1916,8 +1795,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) } /* reset modified pages */ if (page_max >= page_min) { - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, - VGA_DIRTY_FLAG); + memory_region_reset_dirty(&s->vram, + page_min, + page_max + TARGET_PAGE_SIZE - page_min, + DIRTY_MEMORY_VGA); } memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); } @@ -1957,6 +1838,8 @@ static void vga_update_display(void *opaque) VGACommonState *s = opaque; int full_update, graphic_mode; + qemu_flush_coalesced_mmio_buffer(); + if (ds_get_bits_per_pixel(s->ds) == 0) { /* nothing to do */ } else { @@ -1996,11 +1879,6 @@ static void vga_invalidate_display(void *opaque) void vga_common_reset(VGACommonState *s) { - s->lfb_addr = 0; - s->lfb_end = 0; - s->map_addr = 0; - s->map_end = 0; - s->lfb_vram_mapped = 0; s->sr_index = 0; memset(s->sr, '\0', sizeof(s->sr)); s->gr_index = 0; @@ -2057,6 +1935,7 @@ void vga_common_reset(VGACommonState *s) memset(&s->retrace_info, 0, sizeof (s->retrace_info)); break; } + vga_update_memory_access(s); } static void vga_reset(void *opaque) @@ -2081,6 +1960,8 @@ static void vga_update_text(void *opaque, console_ch_t *chardata) char msg_buffer[80]; int full_update = 0; + qemu_flush_coalesced_mmio_buffer(); + if (!(s->ar_index & 0x20)) { graphic_mode = GMODE_BLANK; } else { @@ -2231,16 +2112,30 @@ static void vga_update_text(void *opaque, console_ch_t *chardata) dpy_update(s->ds, 0, 0, s->last_width, height); } -CPUReadMemoryFunc * const vga_mem_read[3] = { - vga_mem_readb, - vga_mem_readw, - vga_mem_readl, -}; +static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + VGACommonState *s = opaque; + + return vga_mem_readb(s, addr); +} -CPUWriteMemoryFunc * const vga_mem_write[3] = { - vga_mem_writeb, - vga_mem_writew, - vga_mem_writel, +static void vga_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ + VGACommonState *s = opaque; + + return vga_mem_writeb(s, addr, data); +} + +const MemoryRegionOps vga_mem_ops = { + .read = vga_mem_read, + .write = vga_mem_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; static int vga_common_post_load(void *opaque, int version_id) @@ -2326,8 +2221,8 @@ void vga_common_init(VGACommonState *s, int vga_ram_size) #else s->is_vbe_vmstate = 0; #endif - s->vram_offset = qemu_ram_alloc(NULL, "vga.vram", vga_ram_size); - s->vram_ptr = qemu_get_ram_ptr(s->vram_offset); + memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size); + s->vram_ptr = memory_region_get_ram_ptr(&s->vram); s->vram_size = vga_ram_size; s->get_bpp = vga_get_bpp; s->get_offsets = vga_get_offsets; @@ -2347,59 +2242,87 @@ void vga_common_init(VGACommonState *s, int vga_ram_size) s->update_retrace_info = vga_precise_update_retrace_info; break; } + vga_dirty_log_start(s); } -/* used by both ISA and PCI */ -void vga_init(VGACommonState *s) -{ - int vga_io_memory; +static const MemoryRegionPortio vga_portio_list[] = { + { 0x04, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */ + { 0x0a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */ + { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */ + { 0x24, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */ + { 0x2a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */ + PORTIO_END_OF_LIST(), +}; - qemu_register_reset(vga_reset, s); +#ifdef CONFIG_BOCHS_VBE +static const MemoryRegionPortio vbe_portio_list[] = { + { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index }, +# ifdef TARGET_I386 + { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, +# else + { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, +# endif + PORTIO_END_OF_LIST(), +}; +#endif /* CONFIG_BOCHS_VBE */ - register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s); +/* Used by both ISA and PCI */ +MemoryRegion *vga_init_io(VGACommonState *s, + const MemoryRegionPortio **vga_ports, + const MemoryRegionPortio **vbe_ports) +{ + MemoryRegion *vga_mem; - register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s); - register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s); - register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s); - register_ioport_write(0x3da, 1, 1, vga_ioport_write, s); + *vga_ports = vga_portio_list; + *vbe_ports = NULL; +#ifdef CONFIG_BOCHS_VBE + *vbe_ports = vbe_portio_list; +#endif - register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s); + vga_mem = g_malloc(sizeof(*vga_mem)); + memory_region_init_io(vga_mem, &vga_mem_ops, s, + "vga-lowmem", 0x20000); - register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s); - register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s); - register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s); - register_ioport_read(0x3da, 1, 1, vga_ioport_read, s); - s->bank_offset = 0; + return vga_mem; +} -#ifdef CONFIG_BOCHS_VBE -#if defined (TARGET_I386) - register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s); - register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s); +void vga_init(VGACommonState *s, MemoryRegion *address_space, + MemoryRegion *address_space_io, bool init_vga_ports) +{ + MemoryRegion *vga_io_memory; + const MemoryRegionPortio *vga_ports, *vbe_ports; + PortioList *vga_port_list = g_new(PortioList, 1); + PortioList *vbe_port_list = g_new(PortioList, 1); - register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s); - register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s); -#else - register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s); - register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s); + qemu_register_reset(vga_reset, s); - register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s); - register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s); -#endif -#endif /* CONFIG_BOCHS_VBE */ + s->bank_offset = 0; - vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s, - DEVICE_LITTLE_ENDIAN); - cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, - vga_io_memory); - qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); + s->legacy_address_space = address_space; + + vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports); + memory_region_add_subregion_overlap(address_space, + isa_mem_base + 0x000a0000, + vga_io_memory, + 1); + memory_region_set_coalescing(vga_io_memory); + if (init_vga_ports) { + portio_list_init(vga_port_list, vga_ports, s, "vga"); + portio_list_add(vga_port_list, address_space_io, 0x3b0); + } + if (vbe_ports) { + portio_list_init(vbe_port_list, vbe_ports, s, "vbe"); + portio_list_add(vbe_port_list, address_space_io, 0x1ce); + } } -void vga_init_vbe(VGACommonState *s) +void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory) { #ifdef CONFIG_BOCHS_VBE /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VGA_RAM_SIZE, s->vram_offset); + memory_region_add_subregion(system_memory, + VBE_DISPI_LFB_PHYSICAL_ADDRESS, + &s->vram); s->vbe_mapped = 1; #endif } @@ -2411,7 +2334,6 @@ static void vga_save_dpy_update(DisplayState *ds, { if (screen_dump_filename) { ppm_save(screen_dump_filename, ds->surface); - screen_dump_filename = NULL; } } @@ -2430,15 +2352,19 @@ int ppm_save(const char *filename, struct DisplaySurface *ds) uint32_t v; int y, x; uint8_t r, g, b; + int ret; + char *linebuf, *pbuf; f = fopen(filename, "wb"); if (!f) return -1; fprintf(f, "P6\n%d %d\n%d\n", ds->width, ds->height, 255); + linebuf = g_malloc(ds->width * 3); d1 = ds->data; for(y = 0; y < ds->height; y++) { d = d1; + pbuf = linebuf; for(x = 0; x < ds->width; x++) { if (ds->pf.bits_per_pixel == 32) v = *(uint32_t *)d; @@ -2450,13 +2376,16 @@ int ppm_save(const char *filename, struct DisplaySurface *ds) (ds->pf.gmax + 1); b = ((v >> ds->pf.bshift) & ds->pf.bmax) * 256 / (ds->pf.bmax + 1); - fputc(r, f); - fputc(g, f); - fputc(b, f); + *pbuf++ = r; + *pbuf++ = g; + *pbuf++ = b; d += ds->pf.bytes_per_pixel; } d1 += ds->linesize; + ret = fwrite(linebuf, 1, pbuf - linebuf, f); + (void)ret; } + g_free(linebuf); fclose(f); return 0; } @@ -2465,7 +2394,7 @@ static DisplayChangeListener* vga_screen_dump_init(DisplayState *ds) { DisplayChangeListener *dcl; - dcl = qemu_mallocz(sizeof(DisplayChangeListener)); + dcl = g_malloc0(sizeof(DisplayChangeListener)); dcl->dpy_update = vga_save_dpy_update; dcl->dpy_resize = vga_save_dpy_resize; dcl->dpy_refresh = vga_save_dpy_refresh; @@ -2482,8 +2411,8 @@ static void vga_screen_dump(void *opaque, const char *filename) if (!screen_dump_dcl) screen_dump_dcl = vga_screen_dump_init(s->ds); - screen_dump_filename = (char *)filename; + screen_dump_filename = filename; vga_invalidate_display(s); vga_hw_update(); + screen_dump_filename = NULL; } - diff --git a/hw/vga_int.h b/hw/vga_int.h index 9d91ba6..4e8568d 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -23,6 +23,7 @@ */ #include +#include "memory.h" #define MSR_COLOR_EMULATION 0x01 #define MSR_PAGE_SELECT 0x20 @@ -34,7 +35,11 @@ #define CONFIG_BOCHS_VBE #define VBE_DISPI_MAX_XRES 1600 +#if CONFIG_MARU #define VBE_DISPI_MAX_YRES 1600 +#else +#define VBE_DISPI_MAX_YRES 1200 +#endif #define VBE_DISPI_MAX_BPP 32 #define VBE_DISPI_INDEX_ID 0x0 @@ -104,15 +109,12 @@ typedef uint8_t (* vga_retrace_fn)(struct VGACommonState *s); typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s); typedef struct VGACommonState { + MemoryRegion *legacy_address_space; uint8_t *vram_ptr; - ram_addr_t vram_offset; + MemoryRegion vram; uint32_t vram_size; - uint32_t lfb_addr; - uint32_t lfb_end; - uint32_t map_addr; - uint32_t map_end; - uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */ uint32_t latch; + MemoryRegion *chain4_alias; uint8_t sr_index; uint8_t sr[256]; uint8_t gr_index; @@ -134,7 +136,6 @@ typedef struct VGACommonState { int dac_8bit; uint8_t palette[768]; int32_t bank_offset; - int vga_io_memory; int (*get_bpp)(struct VGACommonState *s); void (*get_offsets)(struct VGACommonState *s, uint32_t *pline_offset, @@ -190,18 +191,21 @@ static inline int c6_to_8(int v) } void vga_common_init(VGACommonState *s, int vga_ram_size); -void vga_init(VGACommonState *s); +void vga_init(VGACommonState *s, MemoryRegion *address_space, + MemoryRegion *address_space_io, bool init_vga_ports); +MemoryRegion *vga_init_io(VGACommonState *s, + const MemoryRegionPortio **vga_ports, + const MemoryRegionPortio **vbe_ports); void vga_common_reset(VGACommonState *s); void vga_dirty_log_start(VGACommonState *s); void vga_dirty_log_stop(VGACommonState *s); -void vga_dirty_log_restart(VGACommonState *s); extern const VMStateDescription vmstate_vga_common; uint32_t vga_ioport_read(void *opaque, uint32_t addr); void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); -void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val); +uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr); +void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val); void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2); int ppm_save(const char *filename, struct DisplaySurface *ds); @@ -219,7 +223,7 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, unsigned int color_xor); int vga_ioport_invalid(VGACommonState *s, uint32_t addr); -void vga_init_vbe(VGACommonState *s); +void vga_init_vbe(VGACommonState *s, MemoryRegion *address_space); extern const uint8_t sr_mask[8]; extern const uint8_t gr_mask[16]; @@ -228,5 +232,4 @@ extern const uint8_t gr_mask[16]; #define VGABIOS_FILENAME "vgabios.bin" #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin" -extern CPUReadMemoryFunc * const vga_mem_read[3]; -extern CPUWriteMemoryFunc * const vga_mem_write[3]; +extern const MemoryRegionOps vga_mem_ops; diff --git a/hw/vhost.c b/hw/vhost.c index 6c194f0..0870cb7 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -120,7 +120,6 @@ static void vhost_dev_unassign_memory(struct vhost_dev *dev, if (start_addr <= reg->guest_phys_addr && memlast >= reglast) { --dev->mem->nregions; --to; - assert(to >= 0); ++overlap_middle; continue; } @@ -253,7 +252,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size) uint64_t log_base; int r; if (size) { - log = qemu_mallocz(size * sizeof *log); + log = g_malloc0(size * sizeof *log); } else { log = NULL; } @@ -263,7 +262,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size) vhost_client_sync_dirty_bitmap(&dev->client, 0, (target_phys_addr_t)~0x0ull); if (dev->log) { - qemu_free(dev->log); + g_free(dev->log); } dev->log = log; dev->log_size = size; @@ -297,10 +296,50 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev, return 0; } +static struct vhost_memory_region *vhost_dev_find_reg(struct vhost_dev *dev, + uint64_t start_addr, + uint64_t size) +{ + int i, n = dev->mem->nregions; + for (i = 0; i < n; ++i) { + struct vhost_memory_region *reg = dev->mem->regions + i; + if (ranges_overlap(reg->guest_phys_addr, reg->memory_size, + start_addr, size)) { + return reg; + } + } + return NULL; +} + +static bool vhost_dev_cmp_memory(struct vhost_dev *dev, + uint64_t start_addr, + uint64_t size, + uint64_t uaddr) +{ + struct vhost_memory_region *reg = vhost_dev_find_reg(dev, start_addr, size); + uint64_t reglast; + uint64_t memlast; + + if (!reg) { + return true; + } + + reglast = range_get_last(reg->guest_phys_addr, reg->memory_size); + memlast = range_get_last(start_addr, size); + + /* Need to extend region? */ + if (start_addr < reg->guest_phys_addr || memlast > reglast) { + return true; + } + /* userspace_addr changed? */ + return uaddr != reg->userspace_addr + start_addr - reg->guest_phys_addr; +} + static void vhost_client_set_memory(CPUPhysMemoryClient *client, target_phys_addr_t start_addr, ram_addr_t size, - ram_addr_t phys_offset) + ram_addr_t phys_offset, + bool log_dirty) { struct vhost_dev *dev = container_of(client, struct vhost_dev, client); ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; @@ -308,10 +347,29 @@ static void vhost_client_set_memory(CPUPhysMemoryClient *client, (dev->mem->nregions + 1) * sizeof dev->mem->regions[0]; uint64_t log_size; int r; - dev->mem = qemu_realloc(dev->mem, s); + + dev->mem = g_realloc(dev->mem, s); + + if (log_dirty) { + flags = IO_MEM_UNASSIGNED; + } assert(size); + /* Optimize no-change case. At least cirrus_vga does this a lot at this time. */ + if (flags == IO_MEM_RAM) { + if (!vhost_dev_cmp_memory(dev, start_addr, size, + (uintptr_t)qemu_get_ram_ptr(phys_offset))) { + /* Region exists with same address. Nothing to do. */ + return; + } + } else { + if (!vhost_dev_find_reg(dev, start_addr, size)) { + /* Removing region that we don't access. Nothing to do. */ + return; + } + } + vhost_dev_unassign_memory(dev, start_addr, size); if (flags == IO_MEM_RAM) { /* Add given mapping, merging adjacent regions if any */ @@ -427,7 +485,7 @@ static int vhost_client_migration_log(CPUPhysMemoryClient *client, return r; } if (dev->log) { - qemu_free(dev->log); + g_free(dev->log); } dev->log = NULL; dev->log_size = 0; @@ -457,11 +515,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, }; struct VirtQueue *vvq = virtio_get_queue(vdev, idx); - if (!vdev->binding->set_host_notifier) { - fprintf(stderr, "binding does not support host notifiers\n"); - return -ENOSYS; - } - vq->num = state.num = virtio_queue_get_num(vdev, idx); r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state); if (r) { @@ -509,12 +562,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, r = -errno; goto fail_alloc; } - r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, true); - if (r < 0) { - fprintf(stderr, "Error binding host notifier: %d\n", -r); - goto fail_host_notifier; - } - file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq)); r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file); if (r) { @@ -533,8 +580,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, fail_call: fail_kick: - vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false); -fail_host_notifier: fail_alloc: cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx), 0, 0); @@ -560,12 +605,6 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev, .index = idx, }; int r; - r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false); - if (r < 0) { - fprintf(stderr, "vhost VQ %d host cleanup failed: %d\n", idx, r); - fflush(stderr); - } - assert (r >= 0); r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state); if (r < 0) { fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r); @@ -609,7 +648,9 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force) hdev->client.set_memory = vhost_client_set_memory; hdev->client.sync_dirty_bitmap = vhost_client_sync_dirty_bitmap; hdev->client.migration_log = vhost_client_migration_log; - hdev->mem = qemu_mallocz(offsetof(struct vhost_memory, regions)); + hdev->client.log_start = NULL; + hdev->client.log_stop = NULL; + hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions)); hdev->log = NULL; hdev->log_size = 0; hdev->log_enabled = false; @@ -626,7 +667,7 @@ fail: void vhost_dev_cleanup(struct vhost_dev *hdev) { cpu_unregister_phys_memory_client(&hdev->client); - qemu_free(hdev->mem); + g_free(hdev->mem); close(hdev->control); } @@ -637,6 +678,60 @@ bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev) hdev->force; } +/* Stop processing guest IO notifications in qemu. + * Start processing them in vhost in kernel. + */ +int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) +{ + int i, r; + if (!vdev->binding->set_host_notifier) { + fprintf(stderr, "binding does not support host notifiers\n"); + r = -ENOSYS; + goto fail; + } + + for (i = 0; i < hdev->nvqs; ++i) { + r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, true); + if (r < 0) { + fprintf(stderr, "vhost VQ %d notifier binding failed: %d\n", i, -r); + goto fail_vq; + } + } + + return 0; +fail_vq: + while (--i >= 0) { + r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false); + if (r < 0) { + fprintf(stderr, "vhost VQ %d notifier cleanup error: %d\n", i, -r); + fflush(stderr); + } + assert (r >= 0); + } +fail: + return r; +} + +/* Stop processing guest IO notifications in vhost. + * Start processing them in qemu. + * This might actually run the qemu handlers right away, + * so virtio in qemu must be completely setup when this is called. + */ +void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) +{ + int i, r; + + for (i = 0; i < hdev->nvqs; ++i) { + r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false); + if (r < 0) { + fprintf(stderr, "vhost VQ %d notifier cleanup failed: %d\n", i, -r); + fflush(stderr); + } + assert (r >= 0); + } +} + +/* Host notifiers must be enabled at this point. */ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; @@ -674,7 +769,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) if (hdev->log_enabled) { hdev->log_size = vhost_get_log_size(hdev); hdev->log = hdev->log_size ? - qemu_mallocz(hdev->log_size * sizeof *hdev->log) : NULL; + g_malloc0(hdev->log_size * sizeof *hdev->log) : NULL; r = ioctl(hdev->control, VHOST_SET_LOG_BASE, (uint64_t)(unsigned long)hdev->log); if (r < 0) { @@ -702,6 +797,7 @@ fail: return r; } +/* Host notifiers must be enabled at this point. */ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) { int i, r; @@ -722,6 +818,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) assert (r >= 0); hdev->started = false; - qemu_free(hdev->log); + g_free(hdev->log); + hdev->log = NULL; hdev->log_size = 0; } diff --git a/hw/vhost.h b/hw/vhost.h index c8c595a..c9452f0 100644 --- a/hw/vhost.h +++ b/hw/vhost.h @@ -46,5 +46,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev); bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev); int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); +int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); +void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); #endif diff --git a/hw/vhost_net.c b/hw/vhost_net.c index 420e05f..950a6b8 100644 --- a/hw/vhost_net.c +++ b/hw/vhost_net.c @@ -15,6 +15,7 @@ #include "virtio-net.h" #include "vhost_net.h" +#include "qemu-error.h" #include "config.h" @@ -50,6 +51,9 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features) if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) { features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC); } + if (!(net->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) { + features &= ~(1 << VIRTIO_RING_F_EVENT_IDX); + } if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) { features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF); } @@ -65,6 +69,9 @@ void vhost_net_ack_features(struct vhost_net *net, unsigned features) if (features & (1 << VIRTIO_RING_F_INDIRECT_DESC)) { net->dev.acked_features |= (1 << VIRTIO_RING_F_INDIRECT_DESC); } + if (features & (1 << VIRTIO_RING_F_EVENT_IDX)) { + net->dev.acked_features |= (1 << VIRTIO_RING_F_EVENT_IDX); + } if (features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { net->dev.acked_features |= (1 << VIRTIO_NET_F_MRG_RXBUF); } @@ -85,7 +92,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd, bool force) { int r; - struct vhost_net *net = qemu_malloc(sizeof *net); + struct vhost_net *net = g_malloc(sizeof *net); if (!backend) { fprintf(stderr, "vhost-net requires backend to be setup\n"); goto fail; @@ -118,7 +125,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd, vhost_net_ack_features(net, 0); return net; fail: - qemu_free(net); + g_free(net); return NULL; } @@ -132,16 +139,22 @@ int vhost_net_start(struct vhost_net *net, { struct vhost_vring_file file = { }; int r; + + net->dev.nvqs = 2; + net->dev.vqs = net->vqs; + + r = vhost_dev_enable_notifiers(&net->dev, dev); + if (r < 0) { + goto fail_notifiers; + } if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr_mrg_rxbuf)); } - net->dev.nvqs = 2; - net->dev.vqs = net->vqs; r = vhost_dev_start(&net->dev, dev); if (r < 0) { - return r; + goto fail_start; } net->vc->info->poll(net->vc, false); @@ -166,6 +179,9 @@ fail: if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } +fail_start: + vhost_dev_disable_notifiers(&net->dev, dev); +fail_notifiers: return r; } @@ -183,6 +199,7 @@ void vhost_net_stop(struct vhost_net *net, if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } + vhost_dev_disable_notifiers(&net->dev, dev); } void vhost_net_cleanup(struct vhost_net *net) @@ -191,12 +208,13 @@ void vhost_net_cleanup(struct vhost_net *net) if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) { tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr)); } - qemu_free(net); + g_free(net); } #else struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd, bool force) { + error_report("vhost-net support is not compiled in"); return NULL; } diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c index fa60515..5ea0e60 100644 --- a/hw/virtex_ml507.c +++ b/hw/virtex_ml507.c @@ -34,6 +34,7 @@ #include "loader.h" #include "elf.h" #include "qemu-log.h" +#include "exec-memory.h" #include "ppc.h" #include "ppc4xx.h" @@ -60,7 +61,7 @@ static void mmubooke_create_initial_mapping(CPUState *env, target_ulong va, target_phys_addr_t pa) { - ppcemb_tlb_t *tlb = &env->tlb[0].tlbe; + ppcemb_tlb_t *tlb = &env->tlb.tlbe[0]; tlb->attr = 0; tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4); @@ -69,7 +70,7 @@ static void mmubooke_create_initial_mapping(CPUState *env, tlb->RPN = pa & TARGET_PAGE_MASK; tlb->PID = 0; - tlb = &env->tlb[1].tlbe; + tlb = &env->tlb.tlbe[1]; tlb->attr = 0; tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4); tlb->size = 1 << 31; /* up to 0xffffffff */ @@ -81,7 +82,6 @@ static void mmubooke_create_initial_mapping(CPUState *env, static CPUState *ppc440_init_xilinx(ram_addr_t *ram_size, int do_init, const char *cpu_model, - clk_setup_t *cpu_clk, clk_setup_t *tb_clk, uint32_t sysclk) { CPUState *env; @@ -93,16 +93,12 @@ static CPUState *ppc440_init_xilinx(ram_addr_t *ram_size, exit(1); } - cpu_clk->cb = NULL; /* We don't care about CPU clock frequency changes */ - cpu_clk->opaque = env; - /* Set time-base frequency to sysclk */ - tb_clk->cb = ppc_emb_timers_init(env, sysclk, PPC_INTERRUPT_DECR); - tb_clk->opaque = env; + ppc_booke_timers_init(env, sysclk, 0/* no flags */); ppc_dcr_init(env, NULL, NULL); /* interrupt controller */ - irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); + irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB); irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]; irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]; ppcuic_init(env, irqs, 0x0C0, 0, 1); @@ -154,7 +150,7 @@ static int xilinx_load_device_tree(target_phys_addr_t addr, path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); if (path) { fdt = load_device_tree(path, &fdt_size); - qemu_free(path); + g_free(path); } if (!fdt) { return 0; @@ -173,7 +169,7 @@ static int xilinx_load_device_tree(target_phys_addr_t addr, path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); if (path) { fdt_size = load_image_targphys(path, addr, 0x10000); - qemu_free(path); + g_free(path); } } @@ -191,14 +187,13 @@ static void virtex_init(ram_addr_t ram_size, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { + MemoryRegion *address_space_mem = get_system_memory(); DeviceState *dev; CPUState *env; target_phys_addr_t ram_base = 0; DriveInfo *dinfo; ram_addr_t phys_ram; - ram_addr_t phys_flash; qemu_irq irq[32], *cpu_irq; - clk_setup_t clk_setup[7]; int kernel_size; int i; @@ -207,17 +202,14 @@ static void virtex_init(ram_addr_t ram_size, cpu_model = "440-Xilinx"; } - memset(clk_setup, 0, sizeof(clk_setup)); - env = ppc440_init_xilinx(&ram_size, 1, cpu_model, &clk_setup[0], - &clk_setup[1], 400000000); + env = ppc440_init_xilinx(&ram_size, 1, cpu_model, 400000000); qemu_register_reset(main_cpu_reset, env); phys_ram = qemu_ram_alloc(NULL, "ram", ram_size); cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM); - phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE); dinfo = drive_get(IF_PFLASH, 0, 0); - pflash_cfi01_register(0xfc000000, phys_flash, + pflash_cfi01_register(0xfc000000, NULL, "virtex.flash", FLASH_SIZE, dinfo ? dinfo->bdrv : NULL, (64 * 1024), FLASH_SIZE >> 16, 1, 0x89, 0x18, 0x0000, 0x0, 1); @@ -228,7 +220,8 @@ static void virtex_init(ram_addr_t ram_size, irq[i] = qdev_get_gpio_in(dev, i); } - serial_mm_init(0x83e01003ULL, 2, irq[9], 115200, serial_hds[0], 1, 0); + serial_mm_init(address_space_mem, 0x83e01003ULL, 2, irq[9], 115200, + serial_hds[0], DEVICE_LITTLE_ENDIAN); /* 2 timers at irq 2 @ 62 Mhz. */ xilinx_timer_create(0x83c00000, irq[3], 2, 62 * 1000000); diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c deleted file mode 100644 index 6b18842..0000000 --- a/hw/virtio-9p-debug.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * Virtio 9p PDU debug - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Anthony Liguori - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ -#include "virtio.h" -#include "pc.h" -#include "virtio-9p.h" -#include "virtio-9p-debug.h" - -#define BUG_ON(cond) assert(!(cond)) - -static FILE *llogfile; - -static struct iovec *get_sg(V9fsPDU *pdu, int rx) -{ - if (rx) { - return pdu->elem.in_sg; - } - return pdu->elem.out_sg; -} - -static int get_sg_count(V9fsPDU *pdu, int rx) -{ - if (rx) { - return pdu->elem.in_num; - } - return pdu->elem.out_num; - -} - -static void pprint_int8(V9fsPDU *pdu, int rx, size_t *offsetp, - const char *name) -{ - size_t copied; - int count = get_sg_count(pdu, rx); - size_t offset = *offsetp; - struct iovec *sg = get_sg(pdu, rx); - int8_t value; - - copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value)); - - BUG_ON(copied != sizeof(value)); - offset += sizeof(value); - fprintf(llogfile, "%s=0x%x", name, value); - *offsetp = offset; -} - -static void pprint_int16(V9fsPDU *pdu, int rx, size_t *offsetp, - const char *name) -{ - size_t copied; - int count = get_sg_count(pdu, rx); - struct iovec *sg = get_sg(pdu, rx); - size_t offset = *offsetp; - int16_t value; - - - copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value)); - - BUG_ON(copied != sizeof(value)); - offset += sizeof(value); - fprintf(llogfile, "%s=0x%x", name, value); - *offsetp = offset; -} - -static void pprint_int32(V9fsPDU *pdu, int rx, size_t *offsetp, - const char *name) -{ - size_t copied; - int count = get_sg_count(pdu, rx); - struct iovec *sg = get_sg(pdu, rx); - size_t offset = *offsetp; - int32_t value; - - - copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value)); - - BUG_ON(copied != sizeof(value)); - offset += sizeof(value); - fprintf(llogfile, "%s=0x%x", name, value); - *offsetp = offset; -} - -static void pprint_int64(V9fsPDU *pdu, int rx, size_t *offsetp, - const char *name) -{ - size_t copied; - int count = get_sg_count(pdu, rx); - struct iovec *sg = get_sg(pdu, rx); - size_t offset = *offsetp; - int64_t value; - - - copied = do_pdu_unpack(&value, sg, count, offset, sizeof(value)); - - BUG_ON(copied != sizeof(value)); - offset += sizeof(value); - fprintf(llogfile, "%s=0x%" PRIx64, name, value); - *offsetp = offset; -} - -static void pprint_str(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name) -{ - int sg_count = get_sg_count(pdu, rx); - struct iovec *sg = get_sg(pdu, rx); - size_t offset = *offsetp; - uint16_t tmp_size, size; - size_t result; - size_t copied = 0; - int i = 0; - - /* get the size */ - copied = do_pdu_unpack(&tmp_size, sg, sg_count, offset, sizeof(tmp_size)); - BUG_ON(copied != sizeof(tmp_size)); - size = le16_to_cpupu(&tmp_size); - offset += copied; - - fprintf(llogfile, "%s=", name); - for (i = 0; size && i < sg_count; i++) { - size_t len; - if (offset >= sg[i].iov_len) { - /* skip this sg */ - offset -= sg[i].iov_len; - continue; - } else { - len = MIN(sg[i].iov_len - offset, size); - result = fwrite(sg[i].iov_base + offset, 1, len, llogfile); - BUG_ON(result != len); - size -= len; - copied += len; - if (size) { - offset = 0; - continue; - } - } - } - *offsetp += copied; -} - -static void pprint_qid(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name) -{ - fprintf(llogfile, "%s={", name); - pprint_int8(pdu, rx, offsetp, "type"); - pprint_int32(pdu, rx, offsetp, ", version"); - pprint_int64(pdu, rx, offsetp, ", path"); - fprintf(llogfile, "}"); -} - -static void pprint_stat(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name) -{ - fprintf(llogfile, "%s={", name); - pprint_int16(pdu, rx, offsetp, "size"); - pprint_int16(pdu, rx, offsetp, ", type"); - pprint_int32(pdu, rx, offsetp, ", dev"); - pprint_qid(pdu, rx, offsetp, ", qid"); - pprint_int32(pdu, rx, offsetp, ", mode"); - pprint_int32(pdu, rx, offsetp, ", atime"); - pprint_int32(pdu, rx, offsetp, ", mtime"); - pprint_int64(pdu, rx, offsetp, ", length"); - pprint_str(pdu, rx, offsetp, ", name"); - pprint_str(pdu, rx, offsetp, ", uid"); - pprint_str(pdu, rx, offsetp, ", gid"); - pprint_str(pdu, rx, offsetp, ", muid"); - pprint_str(pdu, rx, offsetp, ", extension"); - pprint_int32(pdu, rx, offsetp, ", uid"); - pprint_int32(pdu, rx, offsetp, ", gid"); - pprint_int32(pdu, rx, offsetp, ", muid"); - fprintf(llogfile, "}"); -} - -static void pprint_stat_dotl(V9fsPDU *pdu, int rx, size_t *offsetp, - const char *name) -{ - fprintf(llogfile, "%s={", name); - pprint_qid(pdu, rx, offsetp, "qid"); - pprint_int32(pdu, rx, offsetp, ", st_mode"); - pprint_int64(pdu, rx, offsetp, ", st_nlink"); - pprint_int32(pdu, rx, offsetp, ", st_uid"); - pprint_int32(pdu, rx, offsetp, ", st_gid"); - pprint_int64(pdu, rx, offsetp, ", st_rdev"); - pprint_int64(pdu, rx, offsetp, ", st_size"); - pprint_int64(pdu, rx, offsetp, ", st_blksize"); - pprint_int64(pdu, rx, offsetp, ", st_blocks"); - pprint_int64(pdu, rx, offsetp, ", atime"); - pprint_int64(pdu, rx, offsetp, ", atime_nsec"); - pprint_int64(pdu, rx, offsetp, ", mtime"); - pprint_int64(pdu, rx, offsetp, ", mtime_nsec"); - pprint_int64(pdu, rx, offsetp, ", ctime"); - pprint_int64(pdu, rx, offsetp, ", ctime_nsec"); - fprintf(llogfile, "}"); -} - - - -static void pprint_strs(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name) -{ - int sg_count = get_sg_count(pdu, rx); - struct iovec *sg = get_sg(pdu, rx); - size_t offset = *offsetp; - uint16_t tmp_count, count, i; - size_t copied = 0; - - fprintf(llogfile, "%s={", name); - - /* Get the count */ - copied = do_pdu_unpack(&tmp_count, sg, sg_count, offset, sizeof(tmp_count)); - BUG_ON(copied != sizeof(tmp_count)); - count = le16_to_cpupu(&tmp_count); - offset += copied; - - for (i = 0; i < count; i++) { - char str[512]; - if (i) { - fprintf(llogfile, ", "); - } - snprintf(str, sizeof(str), "[%d]", i); - pprint_str(pdu, rx, &offset, str); - } - - fprintf(llogfile, "}"); - - *offsetp = offset; -} - -static void pprint_qids(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name) -{ - int sg_count = get_sg_count(pdu, rx); - struct iovec *sg = get_sg(pdu, rx); - size_t offset = *offsetp; - uint16_t tmp_count, count, i; - size_t copied = 0; - - fprintf(llogfile, "%s={", name); - - copied = do_pdu_unpack(&tmp_count, sg, sg_count, offset, sizeof(tmp_count)); - BUG_ON(copied != sizeof(tmp_count)); - count = le16_to_cpupu(&tmp_count); - offset += copied; - - for (i = 0; i < count; i++) { - char str[512]; - if (i) { - fprintf(llogfile, ", "); - } - snprintf(str, sizeof(str), "[%d]", i); - pprint_qid(pdu, rx, &offset, str); - } - - fprintf(llogfile, "}"); - - *offsetp = offset; -} - -static void pprint_sg(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name) -{ - struct iovec *sg = get_sg(pdu, rx); - unsigned int count; - int i; - - if (rx) { - count = pdu->elem.in_num; - } else { - count = pdu->elem.out_num; - } - - fprintf(llogfile, "%s={", name); - for (i = 0; i < count; i++) { - if (i) { - fprintf(llogfile, ", "); - } - fprintf(llogfile, "(%p, 0x%zx)", sg[i].iov_base, sg[i].iov_len); - } - fprintf(llogfile, "}"); -} - -/* FIXME: read from a directory fid returns serialized stat_t's */ -#ifdef DEBUG_DATA -static void pprint_data(V9fsPDU *pdu, int rx, size_t *offsetp, const char *name) -{ - struct iovec *sg = get_sg(pdu, rx); - size_t offset = *offsetp; - unsigned int count; - int32_t size; - int total, i, j; - ssize_t len; - - if (rx) { - count = pdu->elem.in_num; - } else - count = pdu->elem.out_num; - } - - BUG_ON((offset + sizeof(size)) > sg[0].iov_len); - - memcpy(&size, sg[0].iov_base + offset, sizeof(size)); - offset += sizeof(size); - - fprintf(llogfile, "size: %x\n", size); - - sg[0].iov_base += 11; /* skip header */ - sg[0].iov_len -= 11; - - total = 0; - for (i = 0; i < count; i++) { - total += sg[i].iov_len; - if (total >= size) { - /* trim sg list so writev does the right thing */ - sg[i].iov_len -= (total - size); - i++; - break; - } - } - - fprintf(llogfile, "%s={\"", name); - fflush(llogfile); - for (j = 0; j < i; j++) { - if (j) { - fprintf(llogfile, "\", \""); - fflush(llogfile); - } - - do { - len = writev(fileno(llogfile), &sg[j], 1); - } while (len == -1 && errno == EINTR); - fprintf(llogfile, "len == %ld: %m\n", len); - BUG_ON(len != sg[j].iov_len); - } - fprintf(llogfile, "\"}"); - - sg[0].iov_base -= 11; - sg[0].iov_len += 11; - -} -#endif - -void pprint_pdu(V9fsPDU *pdu) -{ - size_t offset = 7; - - if (llogfile == NULL) { - llogfile = fopen("/tmp/pdu.log", "w"); - } - - BUG_ON(!llogfile); - - switch (pdu->id) { - case P9_TREADDIR: - fprintf(llogfile, "TREADDIR: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int64(pdu, 0, &offset, ", initial offset"); - pprint_int32(pdu, 0, &offset, ", max count"); - break; - case P9_RREADDIR: - fprintf(llogfile, "RREADDIR: ("); - pprint_int32(pdu, 1, &offset, "count"); -#ifdef DEBUG_DATA - pprint_data(pdu, 1, &offset, ", data"); -#endif - break; - case P9_TMKDIR: - fprintf(llogfile, "TMKDIR: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_str(pdu, 0, &offset, "name"); - pprint_int32(pdu, 0, &offset, "mode"); - pprint_int32(pdu, 0, &offset, "gid"); - break; - case P9_RMKDIR: - fprintf(llogfile, "RMKDIR: ("); - pprint_qid(pdu, 0, &offset, "qid"); - break; - case P9_TVERSION: - fprintf(llogfile, "TVERSION: ("); - pprint_int32(pdu, 0, &offset, "msize"); - pprint_str(pdu, 0, &offset, ", version"); - break; - case P9_RVERSION: - fprintf(llogfile, "RVERSION: ("); - pprint_int32(pdu, 1, &offset, "msize"); - pprint_str(pdu, 1, &offset, ", version"); - break; - case P9_TGETATTR: - fprintf(llogfile, "TGETATTR: ("); - pprint_int32(pdu, 0, &offset, "fid"); - break; - case P9_RGETATTR: - fprintf(llogfile, "RGETATTR: ("); - pprint_stat_dotl(pdu, 1, &offset, "getattr"); - break; - case P9_TAUTH: - fprintf(llogfile, "TAUTH: ("); - pprint_int32(pdu, 0, &offset, "afid"); - pprint_str(pdu, 0, &offset, ", uname"); - pprint_str(pdu, 0, &offset, ", aname"); - pprint_int32(pdu, 0, &offset, ", n_uname"); - break; - case P9_RAUTH: - fprintf(llogfile, "RAUTH: ("); - pprint_qid(pdu, 1, &offset, "qid"); - break; - case P9_TATTACH: - fprintf(llogfile, "TATTACH: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int32(pdu, 0, &offset, ", afid"); - pprint_str(pdu, 0, &offset, ", uname"); - pprint_str(pdu, 0, &offset, ", aname"); - pprint_int32(pdu, 0, &offset, ", n_uname"); - break; - case P9_RATTACH: - fprintf(llogfile, "RATTACH: ("); - pprint_qid(pdu, 1, &offset, "qid"); - break; - case P9_TERROR: - fprintf(llogfile, "TERROR: ("); - break; - case P9_RERROR: - fprintf(llogfile, "RERROR: ("); - pprint_str(pdu, 1, &offset, "ename"); - pprint_int32(pdu, 1, &offset, ", ecode"); - break; - case P9_TFLUSH: - fprintf(llogfile, "TFLUSH: ("); - pprint_int16(pdu, 0, &offset, "oldtag"); - break; - case P9_RFLUSH: - fprintf(llogfile, "RFLUSH: ("); - break; - case P9_TWALK: - fprintf(llogfile, "TWALK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int32(pdu, 0, &offset, ", newfid"); - pprint_strs(pdu, 0, &offset, ", wnames"); - break; - case P9_RWALK: - fprintf(llogfile, "RWALK: ("); - pprint_qids(pdu, 1, &offset, "wqids"); - break; - case P9_TOPEN: - fprintf(llogfile, "TOPEN: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int8(pdu, 0, &offset, ", mode"); - break; - case P9_ROPEN: - fprintf(llogfile, "ROPEN: ("); - pprint_qid(pdu, 1, &offset, "qid"); - pprint_int32(pdu, 1, &offset, ", iounit"); - break; - case P9_TCREATE: - fprintf(llogfile, "TCREATE: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_str(pdu, 0, &offset, ", name"); - pprint_int32(pdu, 0, &offset, ", perm"); - pprint_int8(pdu, 0, &offset, ", mode"); - pprint_str(pdu, 0, &offset, ", extension"); - break; - case P9_RCREATE: - fprintf(llogfile, "RCREATE: ("); - pprint_qid(pdu, 1, &offset, "qid"); - pprint_int32(pdu, 1, &offset, ", iounit"); - break; - case P9_TSYMLINK: - fprintf(llogfile, "TSYMLINK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_str(pdu, 0, &offset, ", name"); - pprint_str(pdu, 0, &offset, ", symname"); - pprint_int32(pdu, 0, &offset, ", gid"); - break; - case P9_RSYMLINK: - fprintf(llogfile, "RSYMLINK: ("); - pprint_qid(pdu, 1, &offset, "qid"); - break; - case P9_TLCREATE: - fprintf(llogfile, "TLCREATE: ("); - pprint_int32(pdu, 0, &offset, "dfid"); - pprint_str(pdu, 0, &offset, ", name"); - pprint_int32(pdu, 0, &offset, ", flags"); - pprint_int32(pdu, 0, &offset, ", mode"); - pprint_int32(pdu, 0, &offset, ", gid"); - break; - case P9_RLCREATE: - fprintf(llogfile, "RLCREATE: ("); - pprint_qid(pdu, 1, &offset, "qid"); - pprint_int32(pdu, 1, &offset, ", iounit"); - break; - case P9_TMKNOD: - fprintf(llogfile, "TMKNOD: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_str(pdu, 0, &offset, "name"); - pprint_int32(pdu, 0, &offset, "mode"); - pprint_int32(pdu, 0, &offset, "major"); - pprint_int32(pdu, 0, &offset, "minor"); - pprint_int32(pdu, 0, &offset, "gid"); - break; - case P9_RMKNOD: - fprintf(llogfile, "RMKNOD: )"); - pprint_qid(pdu, 0, &offset, "qid"); - break; - case P9_TREADLINK: - fprintf(llogfile, "TREADLINK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - break; - case P9_RREADLINK: - fprintf(llogfile, "RREADLINK: ("); - pprint_str(pdu, 0, &offset, "target"); - break; - case P9_TREAD: - fprintf(llogfile, "TREAD: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int64(pdu, 0, &offset, ", offset"); - pprint_int32(pdu, 0, &offset, ", count"); - pprint_sg(pdu, 0, &offset, ", sg"); - break; - case P9_RREAD: - fprintf(llogfile, "RREAD: ("); - pprint_int32(pdu, 1, &offset, "count"); - pprint_sg(pdu, 1, &offset, ", sg"); - offset = 7; -#ifdef DEBUG_DATA - pprint_data(pdu, 1, &offset, ", data"); -#endif - break; - case P9_TWRITE: - fprintf(llogfile, "TWRITE: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int64(pdu, 0, &offset, ", offset"); - pprint_int32(pdu, 0, &offset, ", count"); - break; - case P9_RWRITE: - fprintf(llogfile, "RWRITE: ("); - pprint_int32(pdu, 1, &offset, "count"); - break; - case P9_TCLUNK: - fprintf(llogfile, "TCLUNK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - break; - case P9_RCLUNK: - fprintf(llogfile, "RCLUNK: ("); - break; - case P9_TFSYNC: - fprintf(llogfile, "TFSYNC: ("); - pprint_int32(pdu, 0, &offset, "fid"); - break; - case P9_RFSYNC: - fprintf(llogfile, "RFSYNC: ("); - break; - case P9_TLINK: - fprintf(llogfile, "TLINK: ("); - pprint_int32(pdu, 0, &offset, "dfid"); - pprint_int32(pdu, 0, &offset, ", fid"); - pprint_str(pdu, 0, &offset, ", newpath"); - break; - case P9_RLINK: - fprintf(llogfile, "RLINK: ("); - break; - case P9_TREMOVE: - fprintf(llogfile, "TREMOVE: ("); - pprint_int32(pdu, 0, &offset, "fid"); - break; - case P9_RREMOVE: - fprintf(llogfile, "RREMOVE: ("); - break; - case P9_TSTAT: - fprintf(llogfile, "TSTAT: ("); - pprint_int32(pdu, 0, &offset, "fid"); - break; - case P9_RSTAT: - fprintf(llogfile, "RSTAT: ("); - offset += 2; /* ignored */ - pprint_stat(pdu, 1, &offset, "stat"); - break; - case P9_TWSTAT: - fprintf(llogfile, "TWSTAT: ("); - pprint_int32(pdu, 0, &offset, "fid"); - offset += 2; /* ignored */ - pprint_stat(pdu, 0, &offset, ", stat"); - break; - case P9_RWSTAT: - fprintf(llogfile, "RWSTAT: ("); - break; - case P9_TXATTRWALK: - fprintf(llogfile, "TXATTRWALK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int32(pdu, 0, &offset, ", newfid"); - pprint_str(pdu, 0, &offset, ", xattr name"); - break; - case P9_RXATTRWALK: - fprintf(llogfile, "RXATTRWALK: ("); - pprint_int64(pdu, 1, &offset, "xattrsize"); - case P9_TXATTRCREATE: - fprintf(llogfile, "TXATTRCREATE: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_str(pdu, 0, &offset, ", name"); - pprint_int64(pdu, 0, &offset, ", xattrsize"); - pprint_int32(pdu, 0, &offset, ", flags"); - break; - case P9_RXATTRCREATE: - fprintf(llogfile, "RXATTRCREATE: ("); - break; - case P9_TLOCK: - fprintf(llogfile, "TLOCK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int8(pdu, 0, &offset, ", type"); - pprint_int32(pdu, 0, &offset, ", flags"); - pprint_int64(pdu, 0, &offset, ", start"); - pprint_int64(pdu, 0, &offset, ", length"); - pprint_int32(pdu, 0, &offset, ", proc_id"); - pprint_str(pdu, 0, &offset, ", client_id"); - break; - case P9_RLOCK: - fprintf(llogfile, "RLOCK: ("); - pprint_int8(pdu, 0, &offset, "status"); - break; - case P9_TGETLOCK: - fprintf(llogfile, "TGETLOCK: ("); - pprint_int32(pdu, 0, &offset, "fid"); - pprint_int8(pdu, 0, &offset, ", type"); - pprint_int64(pdu, 0, &offset, ", start"); - pprint_int64(pdu, 0, &offset, ", length"); - pprint_int32(pdu, 0, &offset, ", proc_id"); - pprint_str(pdu, 0, &offset, ", client_id"); - break; - case P9_RGETLOCK: - fprintf(llogfile, "RGETLOCK: ("); - pprint_int8(pdu, 0, &offset, "type"); - pprint_int64(pdu, 0, &offset, ", start"); - pprint_int64(pdu, 0, &offset, ", length"); - pprint_int32(pdu, 0, &offset, ", proc_id"); - pprint_str(pdu, 0, &offset, ", client_id"); - break; - default: - fprintf(llogfile, "unknown(%d): (", pdu->id); - break; - } - - fprintf(llogfile, ")\n"); - /* Flush the log message out */ - fflush(llogfile); -} diff --git a/hw/virtio-9p-debug.h b/hw/virtio-9p-debug.h deleted file mode 100644 index d9a2491..0000000 --- a/hw/virtio-9p-debug.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _QEMU_VIRTIO_9P_DEBUG_H -#define _QEMU_VIRTIO_9P_DEBUG_H - -void pprint_pdu(V9fsPDU *pdu); - -#endif diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c deleted file mode 100644 index a8e7525..0000000 --- a/hw/virtio-9p-local.c +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Virtio 9p Posix callback - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Anthony Liguori - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ -#include "virtio.h" -#include "virtio-9p.h" -#include "virtio-9p-xattr.h" -#include -#include -#include -#include -#include -#include - - -static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf) -{ - int err; - err = lstat(rpath(fs_ctx, path), stbuf); - if (err) { - return err; - } - if (fs_ctx->fs_sm == SM_MAPPED) { - /* Actual credentials are part of extended attrs */ - uid_t tmp_uid; - gid_t tmp_gid; - mode_t tmp_mode; - dev_t tmp_dev; - if (getxattr(rpath(fs_ctx, path), "user.virtfs.uid", &tmp_uid, - sizeof(uid_t)) > 0) { - stbuf->st_uid = tmp_uid; - } - if (getxattr(rpath(fs_ctx, path), "user.virtfs.gid", &tmp_gid, - sizeof(gid_t)) > 0) { - stbuf->st_gid = tmp_gid; - } - if (getxattr(rpath(fs_ctx, path), "user.virtfs.mode", &tmp_mode, - sizeof(mode_t)) > 0) { - stbuf->st_mode = tmp_mode; - } - if (getxattr(rpath(fs_ctx, path), "user.virtfs.rdev", &tmp_dev, - sizeof(dev_t)) > 0) { - stbuf->st_rdev = tmp_dev; - } - } - return err; -} - -static int local_set_xattr(const char *path, FsCred *credp) -{ - int err; - if (credp->fc_uid != -1) { - err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t), - 0); - if (err) { - return err; - } - } - if (credp->fc_gid != -1) { - err = setxattr(path, "user.virtfs.gid", &credp->fc_gid, sizeof(gid_t), - 0); - if (err) { - return err; - } - } - if (credp->fc_mode != -1) { - err = setxattr(path, "user.virtfs.mode", &credp->fc_mode, - sizeof(mode_t), 0); - if (err) { - return err; - } - } - if (credp->fc_rdev != -1) { - err = setxattr(path, "user.virtfs.rdev", &credp->fc_rdev, - sizeof(dev_t), 0); - if (err) { - return err; - } - } - return 0; -} - -static int local_post_create_passthrough(FsContext *fs_ctx, const char *path, - FsCred *credp) -{ - if (chmod(rpath(fs_ctx, path), credp->fc_mode & 07777) < 0) { - return -1; - } - if (lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid) < 0) { - /* - * If we fail to change ownership and if we are - * using security model none. Ignore the error - */ - if (fs_ctx->fs_sm != SM_NONE) { - return -1; - } - } - return 0; -} - -static ssize_t local_readlink(FsContext *fs_ctx, const char *path, - char *buf, size_t bufsz) -{ - ssize_t tsize = -1; - if (fs_ctx->fs_sm == SM_MAPPED) { - int fd; - fd = open(rpath(fs_ctx, path), O_RDONLY); - if (fd == -1) { - return -1; - } - do { - tsize = read(fd, (void *)buf, bufsz); - } while (tsize == -1 && errno == EINTR); - close(fd); - return tsize; - } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || - (fs_ctx->fs_sm == SM_NONE)) { - tsize = readlink(rpath(fs_ctx, path), buf, bufsz); - } - return tsize; -} - -static int local_close(FsContext *ctx, int fd) -{ - return close(fd); -} - -static int local_closedir(FsContext *ctx, DIR *dir) -{ - return closedir(dir); -} - -static int local_open(FsContext *ctx, const char *path, int flags) -{ - return open(rpath(ctx, path), flags); -} - -static DIR *local_opendir(FsContext *ctx, const char *path) -{ - return opendir(rpath(ctx, path)); -} - -static void local_rewinddir(FsContext *ctx, DIR *dir) -{ - return rewinddir(dir); -} - -static off_t local_telldir(FsContext *ctx, DIR *dir) -{ - return telldir(dir); -} - -static struct dirent *local_readdir(FsContext *ctx, DIR *dir) -{ - return readdir(dir); -} - -static void local_seekdir(FsContext *ctx, DIR *dir, off_t off) -{ - return seekdir(dir, off); -} - -static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov, - int iovcnt, off_t offset) -{ -#ifdef CONFIG_PREADV - return preadv(fd, iov, iovcnt, offset); -#else - int err = lseek(fd, offset, SEEK_SET); - if (err == -1) { - return err; - } else { - return readv(fd, iov, iovcnt); - } -#endif -} - -static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, - int iovcnt, off_t offset) -{ -#ifdef CONFIG_PREADV - return pwritev(fd, iov, iovcnt, offset); -#else - int err = lseek(fd, offset, SEEK_SET); - if (err == -1) { - return err; - } else { - return writev(fd, iov, iovcnt); - } -#endif -} - -static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp) -{ - if (fs_ctx->fs_sm == SM_MAPPED) { - return local_set_xattr(rpath(fs_ctx, path), credp); - } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || - (fs_ctx->fs_sm == SM_NONE)) { - return chmod(rpath(fs_ctx, path), credp->fc_mode); - } - return -1; -} - -static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp) -{ - int err = -1; - int serrno = 0; - - /* Determine the security model */ - if (fs_ctx->fs_sm == SM_MAPPED) { - err = mknod(rpath(fs_ctx, path), SM_LOCAL_MODE_BITS|S_IFREG, 0); - if (err == -1) { - return err; - } - local_set_xattr(rpath(fs_ctx, path), credp); - if (err == -1) { - serrno = errno; - goto err_end; - } - } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || - (fs_ctx->fs_sm == SM_NONE)) { - err = mknod(rpath(fs_ctx, path), credp->fc_mode, credp->fc_rdev); - if (err == -1) { - return err; - } - err = local_post_create_passthrough(fs_ctx, path, credp); - if (err == -1) { - serrno = errno; - goto err_end; - } - } - return err; - -err_end: - remove(rpath(fs_ctx, path)); - errno = serrno; - return err; -} - -static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp) -{ - int err = -1; - int serrno = 0; - - /* Determine the security model */ - if (fs_ctx->fs_sm == SM_MAPPED) { - err = mkdir(rpath(fs_ctx, path), SM_LOCAL_DIR_MODE_BITS); - if (err == -1) { - return err; - } - credp->fc_mode = credp->fc_mode|S_IFDIR; - err = local_set_xattr(rpath(fs_ctx, path), credp); - if (err == -1) { - serrno = errno; - goto err_end; - } - } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || - (fs_ctx->fs_sm == SM_NONE)) { - err = mkdir(rpath(fs_ctx, path), credp->fc_mode); - if (err == -1) { - return err; - } - err = local_post_create_passthrough(fs_ctx, path, credp); - if (err == -1) { - serrno = errno; - goto err_end; - } - } - return err; - -err_end: - remove(rpath(fs_ctx, path)); - errno = serrno; - return err; -} - -static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) -{ - int err; - err = fstat(fd, stbuf); - if (err) { - return err; - } - if (fs_ctx->fs_sm == SM_MAPPED) { - /* Actual credentials are part of extended attrs */ - uid_t tmp_uid; - gid_t tmp_gid; - mode_t tmp_mode; - dev_t tmp_dev; - - if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { - stbuf->st_uid = tmp_uid; - } - if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) { - stbuf->st_gid = tmp_gid; - } - if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) { - stbuf->st_mode = tmp_mode; - } - if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) { - stbuf->st_rdev = tmp_dev; - } - } - return err; -} - -static int local_open2(FsContext *fs_ctx, const char *path, int flags, - FsCred *credp) -{ - int fd = -1; - int err = -1; - int serrno = 0; - - /* Determine the security model */ - if (fs_ctx->fs_sm == SM_MAPPED) { - fd = open(rpath(fs_ctx, path), flags, SM_LOCAL_MODE_BITS); - if (fd == -1) { - return fd; - } - credp->fc_mode = credp->fc_mode|S_IFREG; - /* Set cleint credentials in xattr */ - err = local_set_xattr(rpath(fs_ctx, path), credp); - if (err == -1) { - serrno = errno; - goto err_end; - } - } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || - (fs_ctx->fs_sm == SM_NONE)) { - fd = open(rpath(fs_ctx, path), flags, credp->fc_mode); - if (fd == -1) { - return fd; - } - err = local_post_create_passthrough(fs_ctx, path, credp); - if (err == -1) { - serrno = errno; - goto err_end; - } - } - return fd; - -err_end: - close(fd); - remove(rpath(fs_ctx, path)); - errno = serrno; - return err; -} - - -static int local_symlink(FsContext *fs_ctx, const char *oldpath, - const char *newpath, FsCred *credp) -{ - int err = -1; - int serrno = 0; - - /* Determine the security model */ - if (fs_ctx->fs_sm == SM_MAPPED) { - int fd; - ssize_t oldpath_size, write_size; - fd = open(rpath(fs_ctx, newpath), O_CREAT|O_EXCL|O_RDWR, - SM_LOCAL_MODE_BITS); - if (fd == -1) { - return fd; - } - /* Write the oldpath (target) to the file. */ - oldpath_size = strlen(oldpath) + 1; - do { - write_size = write(fd, (void *)oldpath, oldpath_size); - } while (write_size == -1 && errno == EINTR); - - if (write_size != oldpath_size) { - serrno = errno; - close(fd); - err = -1; - goto err_end; - } - close(fd); - /* Set cleint credentials in symlink's xattr */ - credp->fc_mode = credp->fc_mode|S_IFLNK; - err = local_set_xattr(rpath(fs_ctx, newpath), credp); - if (err == -1) { - serrno = errno; - goto err_end; - } - } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || - (fs_ctx->fs_sm == SM_NONE)) { - err = symlink(oldpath, rpath(fs_ctx, newpath)); - if (err) { - return err; - } - err = lchown(rpath(fs_ctx, newpath), credp->fc_uid, credp->fc_gid); - if (err == -1) { - /* - * If we fail to change ownership and if we are - * using security model none. Ignore the error - */ - if (fs_ctx->fs_sm != SM_NONE) { - serrno = errno; - goto err_end; - } else - err = 0; - } - } - return err; - -err_end: - remove(rpath(fs_ctx, newpath)); - errno = serrno; - return err; -} - -static int local_link(FsContext *ctx, const char *oldpath, const char *newpath) -{ - char *tmp = qemu_strdup(rpath(ctx, oldpath)); - int err, serrno = 0; - - if (tmp == NULL) { - return -ENOMEM; - } - - err = link(tmp, rpath(ctx, newpath)); - if (err == -1) { - serrno = errno; - } - - qemu_free(tmp); - - if (err == -1) { - errno = serrno; - } - - return err; -} - -static int local_truncate(FsContext *ctx, const char *path, off_t size) -{ - return truncate(rpath(ctx, path), size); -} - -static int local_rename(FsContext *ctx, const char *oldpath, - const char *newpath) -{ - char *tmp; - int err; - - tmp = qemu_strdup(rpath(ctx, oldpath)); - - err = rename(tmp, rpath(ctx, newpath)); - if (err == -1) { - int serrno = errno; - qemu_free(tmp); - errno = serrno; - } else { - qemu_free(tmp); - } - - return err; - -} - -static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp) -{ - if ((credp->fc_uid == -1 && credp->fc_gid == -1) || - (fs_ctx->fs_sm == SM_PASSTHROUGH)) { - return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid); - } else if (fs_ctx->fs_sm == SM_MAPPED) { - return local_set_xattr(rpath(fs_ctx, path), credp); - } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || - (fs_ctx->fs_sm == SM_NONE)) { - return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid); - } - return -1; -} - -static int local_utimensat(FsContext *s, const char *path, - const struct timespec *buf) -{ - return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW); -} - -static int local_remove(FsContext *ctx, const char *path) -{ - return remove(rpath(ctx, path)); -} - -static int local_fsync(FsContext *ctx, int fd, int datasync) -{ - if (datasync) { - return qemu_fdatasync(fd); - } else { - return fsync(fd); - } -} - -static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf) -{ - return statfs(rpath(s, path), stbuf); -} - -static ssize_t local_lgetxattr(FsContext *ctx, const char *path, - const char *name, void *value, size_t size) -{ - return v9fs_get_xattr(ctx, path, name, value, size); -} - -static ssize_t local_llistxattr(FsContext *ctx, const char *path, - void *value, size_t size) -{ - return v9fs_list_xattr(ctx, path, value, size); -} - -static int local_lsetxattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) -{ - return v9fs_set_xattr(ctx, path, name, value, size, flags); -} - -static int local_lremovexattr(FsContext *ctx, - const char *path, const char *name) -{ - return v9fs_remove_xattr(ctx, path, name); -} - - -FileOperations local_ops = { - .lstat = local_lstat, - .readlink = local_readlink, - .close = local_close, - .closedir = local_closedir, - .open = local_open, - .opendir = local_opendir, - .rewinddir = local_rewinddir, - .telldir = local_telldir, - .readdir = local_readdir, - .seekdir = local_seekdir, - .preadv = local_preadv, - .pwritev = local_pwritev, - .chmod = local_chmod, - .mknod = local_mknod, - .mkdir = local_mkdir, - .fstat = local_fstat, - .open2 = local_open2, - .symlink = local_symlink, - .link = local_link, - .truncate = local_truncate, - .rename = local_rename, - .chown = local_chown, - .utimensat = local_utimensat, - .remove = local_remove, - .fsync = local_fsync, - .statfs = local_statfs, - .lgetxattr = local_lgetxattr, - .llistxattr = local_llistxattr, - .lsetxattr = local_lsetxattr, - .lremovexattr = local_lremovexattr, -}; diff --git a/hw/virtio-9p-posix-acl.c b/hw/virtio-9p-posix-acl.c deleted file mode 100644 index 3978d0c..0000000 --- a/hw/virtio-9p-posix-acl.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Virtio 9p system.posix* xattr callback - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Aneesh Kumar K.V - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include -#include -#include "virtio.h" -#include "virtio-9p.h" -#include "file-op-9p.h" -#include "virtio-9p-xattr.h" - -#define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access" -#define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default" -#define ACL_ACCESS "system.posix_acl_access" -#define ACL_DEFAULT "system.posix_acl_default" - -static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path, - const char *name, void *value, size_t size) -{ - return lgetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size); -} - -static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, - char *name, void *value, size_t osize) -{ - ssize_t len = sizeof(ACL_ACCESS); - - if (!value) { - return len; - } - - if (osize < len) { - errno = ERANGE; - return -1; - } - - strncpy(value, ACL_ACCESS, len); - return 0; -} - -static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) -{ - return lsetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size, flags); -} - -static int mp_pacl_removexattr(FsContext *ctx, - const char *path, const char *name) -{ - int ret; - ret = lremovexattr(rpath(ctx, path), MAP_ACL_ACCESS); - if (ret == -1 && errno == ENODATA) { - /* - * We don't get ENODATA error when trying to remote a - * posix acl that is not present. So don't throw the error - * even in case of mapped security model - */ - errno = 0; - ret = 0; - } - return ret; -} - -static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path, - const char *name, void *value, size_t size) -{ - return lgetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size); -} - -static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, - char *name, void *value, size_t osize) -{ - ssize_t len = sizeof(ACL_DEFAULT); - - if (!value) { - return len; - } - - if (osize < len) { - errno = ERANGE; - return -1; - } - - strncpy(value, ACL_DEFAULT, len); - return 0; -} - -static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) -{ - return lsetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size, flags); -} - -static int mp_dacl_removexattr(FsContext *ctx, - const char *path, const char *name) -{ - return lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT); -} - - -XattrOperations mapped_pacl_xattr = { - .name = "system.posix_acl_access", - .getxattr = mp_pacl_getxattr, - .setxattr = mp_pacl_setxattr, - .listxattr = mp_pacl_listxattr, - .removexattr = mp_pacl_removexattr, -}; - -XattrOperations mapped_dacl_xattr = { - .name = "system.posix_acl_default", - .getxattr = mp_dacl_getxattr, - .setxattr = mp_dacl_setxattr, - .listxattr = mp_dacl_listxattr, - .removexattr = mp_dacl_removexattr, -}; - -XattrOperations passthrough_acl_xattr = { - .name = "system.posix_acl_", - .getxattr = pt_getxattr, - .setxattr = pt_setxattr, - .listxattr = pt_listxattr, - .removexattr = pt_removexattr, -}; - -XattrOperations none_acl_xattr = { - .name = "system.posix_acl_", - .getxattr = notsup_getxattr, - .setxattr = notsup_setxattr, - .listxattr = notsup_listxattr, - .removexattr = notsup_removexattr, -}; diff --git a/hw/virtio-9p-xattr-user.c b/hw/virtio-9p-xattr-user.c deleted file mode 100644 index faa02a1..0000000 --- a/hw/virtio-9p-xattr-user.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Virtio 9p user. xattr callback - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Aneesh Kumar K.V - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include -#include "virtio.h" -#include "virtio-9p.h" -#include "file-op-9p.h" -#include "virtio-9p-xattr.h" - - -static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, - const char *name, void *value, size_t size) -{ - if (strncmp(name, "user.virtfs.", 12) == 0) { - /* - * Don't allow fetch of user.virtfs namesapce - * in case of mapped security - */ - errno = ENOATTR; - return -1; - } - return lgetxattr(rpath(ctx, path), name, value, size); -} - -static ssize_t mp_user_listxattr(FsContext *ctx, const char *path, - char *name, void *value, size_t size) -{ - int name_size = strlen(name) + 1; - if (strncmp(name, "user.virtfs.", 12) == 0) { - - /* check if it is a mapped posix acl */ - if (strncmp(name, "user.virtfs.system.posix_acl_", 29) == 0) { - /* adjust the name and size */ - name += 12; - name_size -= 12; - } else { - /* - * Don't allow fetch of user.virtfs namesapce - * in case of mapped security - */ - return 0; - } - } - if (!value) { - return name_size; - } - - if (size < name_size) { - errno = ERANGE; - return -1; - } - - strncpy(value, name, name_size); - return name_size; -} - -static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) -{ - if (strncmp(name, "user.virtfs.", 12) == 0) { - /* - * Don't allow fetch of user.virtfs namesapce - * in case of mapped security - */ - errno = EACCES; - return -1; - } - return lsetxattr(rpath(ctx, path), name, value, size, flags); -} - -static int mp_user_removexattr(FsContext *ctx, - const char *path, const char *name) -{ - if (strncmp(name, "user.virtfs.", 12) == 0) { - /* - * Don't allow fetch of user.virtfs namesapce - * in case of mapped security - */ - errno = EACCES; - return -1; - } - return lremovexattr(rpath(ctx, path), name); -} - -XattrOperations mapped_user_xattr = { - .name = "user.", - .getxattr = mp_user_getxattr, - .setxattr = mp_user_setxattr, - .listxattr = mp_user_listxattr, - .removexattr = mp_user_removexattr, -}; - -XattrOperations passthrough_user_xattr = { - .name = "user.", - .getxattr = pt_getxattr, - .setxattr = pt_setxattr, - .listxattr = pt_listxattr, - .removexattr = pt_removexattr, -}; diff --git a/hw/virtio-9p-xattr.c b/hw/virtio-9p-xattr.c deleted file mode 100644 index 1aab081..0000000 --- a/hw/virtio-9p-xattr.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Virtio 9p xattr callback - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Aneesh Kumar K.V - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include "virtio.h" -#include "virtio-9p.h" -#include "file-op-9p.h" -#include "virtio-9p-xattr.h" - - -static XattrOperations *get_xattr_operations(XattrOperations **h, - const char *name) -{ - XattrOperations *xops; - for (xops = *(h)++; xops != NULL; xops = *(h)++) { - if (!strncmp(name, xops->name, strlen(xops->name))) { - return xops; - } - } - return NULL; -} - -ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, - const char *name, void *value, size_t size) -{ - XattrOperations *xops = get_xattr_operations(ctx->xops, name); - if (xops) { - return xops->getxattr(ctx, path, name, value, size); - } - errno = -EOPNOTSUPP; - return -1; -} - -ssize_t pt_listxattr(FsContext *ctx, const char *path, - char *name, void *value, size_t size) -{ - int name_size = strlen(name) + 1; - if (!value) { - return name_size; - } - - if (size < name_size) { - errno = ERANGE; - return -1; - } - - strncpy(value, name, name_size); - return name_size; -} - - -/* - * Get the list and pass to each layer to find out whether - * to send the data or not - */ -ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, - void *value, size_t vsize) -{ - ssize_t size = 0; - void *ovalue = value; - XattrOperations *xops; - char *orig_value, *orig_value_start; - ssize_t xattr_len, parsed_len = 0, attr_len; - - /* Get the actual len */ - xattr_len = llistxattr(rpath(ctx, path), value, 0); - if (xattr_len <= 0) { - return xattr_len; - } - - /* Now fetch the xattr and find the actual size */ - orig_value = qemu_malloc(xattr_len); - xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len); - - /* store the orig pointer */ - orig_value_start = orig_value; - while (xattr_len > parsed_len) { - xops = get_xattr_operations(ctx->xops, orig_value); - if (!xops) { - goto next_entry; - } - - if (!value) { - size += xops->listxattr(ctx, path, orig_value, value, vsize); - } else { - size = xops->listxattr(ctx, path, orig_value, value, vsize); - if (size < 0) { - goto err_out; - } - value += size; - vsize -= size; - } -next_entry: - /* Got the next entry */ - attr_len = strlen(orig_value) + 1; - parsed_len += attr_len; - orig_value += attr_len; - } - if (value) { - size = value - ovalue; - } - -err_out: - qemu_free(orig_value_start); - return size; -} - -int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) -{ - XattrOperations *xops = get_xattr_operations(ctx->xops, name); - if (xops) { - return xops->setxattr(ctx, path, name, value, size, flags); - } - errno = -EOPNOTSUPP; - return -1; - -} - -int v9fs_remove_xattr(FsContext *ctx, - const char *path, const char *name) -{ - XattrOperations *xops = get_xattr_operations(ctx->xops, name); - if (xops) { - return xops->removexattr(ctx, path, name); - } - errno = -EOPNOTSUPP; - return -1; - -} - -XattrOperations *mapped_xattr_ops[] = { - &mapped_user_xattr, - &mapped_pacl_xattr, - &mapped_dacl_xattr, - NULL, -}; - -XattrOperations *passthrough_xattr_ops[] = { - &passthrough_user_xattr, - &passthrough_acl_xattr, - NULL, -}; - -/* for .user none model should be same as passthrough */ -XattrOperations *none_xattr_ops[] = { - &passthrough_user_xattr, - &none_acl_xattr, - NULL, -}; diff --git a/hw/virtio-9p-xattr.h b/hw/virtio-9p-xattr.h deleted file mode 100644 index 2bbae2d..0000000 --- a/hw/virtio-9p-xattr.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Virtio 9p - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Aneesh Kumar K.V - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ -#ifndef _QEMU_VIRTIO_9P_XATTR_H -#define _QEMU_VIRTIO_9P_XATTR_H - -#include - -typedef struct xattr_operations -{ - const char *name; - ssize_t (*getxattr)(FsContext *ctx, const char *path, - const char *name, void *value, size_t size); - ssize_t (*listxattr)(FsContext *ctx, const char *path, - char *name, void *value, size_t size); - int (*setxattr)(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags); - int (*removexattr)(FsContext *ctx, - const char *path, const char *name); -} XattrOperations; - - -extern XattrOperations mapped_user_xattr; -extern XattrOperations passthrough_user_xattr; - -extern XattrOperations mapped_pacl_xattr; -extern XattrOperations mapped_dacl_xattr; -extern XattrOperations passthrough_acl_xattr; -extern XattrOperations none_acl_xattr; - -extern XattrOperations *mapped_xattr_ops[]; -extern XattrOperations *passthrough_xattr_ops[]; -extern XattrOperations *none_xattr_ops[]; - -ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size); -ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, void *value, - size_t vsize); -int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags); -int v9fs_remove_xattr(FsContext *ctx, const char *path, const char *name); -ssize_t pt_listxattr(FsContext *ctx, const char *path, char *name, void *value, - size_t size); - -static inline ssize_t pt_getxattr(FsContext *ctx, const char *path, - const char *name, void *value, size_t size) -{ - return lgetxattr(rpath(ctx, path), name, value, size); -} - -static inline int pt_setxattr(FsContext *ctx, const char *path, - const char *name, void *value, - size_t size, int flags) -{ - return lsetxattr(rpath(ctx, path), name, value, size, flags); -} - -static inline int pt_removexattr(FsContext *ctx, - const char *path, const char *name) -{ - return lremovexattr(rpath(ctx, path), name); -} - -static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path, - const char *name, void *value, - size_t size) -{ - errno = ENOTSUP; - return -1; -} - -static inline int notsup_setxattr(FsContext *ctx, const char *path, - const char *name, void *value, - size_t size, int flags) -{ - errno = ENOTSUP; - return -1; -} - -static inline ssize_t notsup_listxattr(FsContext *ctx, const char *path, - char *name, void *value, size_t size) -{ - return 0; -} - -static inline int notsup_removexattr(FsContext *ctx, - const char *path, const char *name) -{ - errno = ENOTSUP; - return -1; -} - -#endif diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c deleted file mode 100644 index 7c59988..0000000 --- a/hw/virtio-9p.c +++ /dev/null @@ -1,3744 +0,0 @@ -/* - * Virtio 9p backend - * - * Copyright IBM, Corp. 2010 - * - * Authors: - * Anthony Liguori - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include "virtio.h" -#include "pc.h" -#include "qemu_socket.h" -#include "virtio-9p.h" -#include "fsdev/qemu-fsdev.h" -#include "virtio-9p-debug.h" -#include "virtio-9p-xattr.h" - -int debug_9p_pdu; - -enum { - Oread = 0x00, - Owrite = 0x01, - Ordwr = 0x02, - Oexec = 0x03, - Oexcl = 0x04, - Otrunc = 0x10, - Orexec = 0x20, - Orclose = 0x40, - Oappend = 0x80, -}; - -static int omode_to_uflags(int8_t mode) -{ - int ret = 0; - - switch (mode & 3) { - case Oread: - ret = O_RDONLY; - break; - case Ordwr: - ret = O_RDWR; - break; - case Owrite: - ret = O_WRONLY; - break; - case Oexec: - ret = O_RDONLY; - break; - } - - if (mode & Otrunc) { - ret |= O_TRUNC; - } - - if (mode & Oappend) { - ret |= O_APPEND; - } - - if (mode & Oexcl) { - ret |= O_EXCL; - } - - return ret; -} - -void cred_init(FsCred *credp) -{ - credp->fc_uid = -1; - credp->fc_gid = -1; - credp->fc_mode = -1; - credp->fc_rdev = -1; -} - -static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf) -{ - return s->ops->lstat(&s->ctx, path->data, stbuf); -} - -static ssize_t v9fs_do_readlink(V9fsState *s, V9fsString *path, V9fsString *buf) -{ - ssize_t len; - - buf->data = qemu_malloc(1024); - - len = s->ops->readlink(&s->ctx, path->data, buf->data, 1024 - 1); - if (len > -1) { - buf->size = len; - buf->data[len] = 0; - } - - return len; -} - -static int v9fs_do_close(V9fsState *s, int fd) -{ - return s->ops->close(&s->ctx, fd); -} - -static int v9fs_do_closedir(V9fsState *s, DIR *dir) -{ - return s->ops->closedir(&s->ctx, dir); -} - -static int v9fs_do_open(V9fsState *s, V9fsString *path, int flags) -{ - return s->ops->open(&s->ctx, path->data, flags); -} - -static DIR *v9fs_do_opendir(V9fsState *s, V9fsString *path) -{ - return s->ops->opendir(&s->ctx, path->data); -} - -static void v9fs_do_rewinddir(V9fsState *s, DIR *dir) -{ - return s->ops->rewinddir(&s->ctx, dir); -} - -static off_t v9fs_do_telldir(V9fsState *s, DIR *dir) -{ - return s->ops->telldir(&s->ctx, dir); -} - -static struct dirent *v9fs_do_readdir(V9fsState *s, DIR *dir) -{ - return s->ops->readdir(&s->ctx, dir); -} - -static void v9fs_do_seekdir(V9fsState *s, DIR *dir, off_t off) -{ - return s->ops->seekdir(&s->ctx, dir, off); -} - -static int v9fs_do_preadv(V9fsState *s, int fd, const struct iovec *iov, - int iovcnt, int64_t offset) -{ - return s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset); -} - -static int v9fs_do_pwritev(V9fsState *s, int fd, const struct iovec *iov, - int iovcnt, int64_t offset) -{ - return s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset); -} - -static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode) -{ - FsCred cred; - cred_init(&cred); - cred.fc_mode = mode; - return s->ops->chmod(&s->ctx, path->data, &cred); -} - -static int v9fs_do_mknod(V9fsState *s, char *name, - mode_t mode, dev_t dev, uid_t uid, gid_t gid) -{ - FsCred cred; - cred_init(&cred); - cred.fc_uid = uid; - cred.fc_gid = gid; - cred.fc_mode = mode; - cred.fc_rdev = dev; - return s->ops->mknod(&s->ctx, name, &cred); -} - -static int v9fs_do_mkdir(V9fsState *s, char *name, mode_t mode, - uid_t uid, gid_t gid) -{ - FsCred cred; - - cred_init(&cred); - cred.fc_uid = uid; - cred.fc_gid = gid; - cred.fc_mode = mode; - - return s->ops->mkdir(&s->ctx, name, &cred); -} - -static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf) -{ - return s->ops->fstat(&s->ctx, fd, stbuf); -} - -static int v9fs_do_open2(V9fsState *s, char *fullname, uid_t uid, gid_t gid, - int flags, int mode) -{ - FsCred cred; - - cred_init(&cred); - cred.fc_uid = uid; - cred.fc_gid = gid; - cred.fc_mode = mode & 07777; - flags = flags; - - return s->ops->open2(&s->ctx, fullname, flags, &cred); -} - -static int v9fs_do_symlink(V9fsState *s, V9fsFidState *fidp, - const char *oldpath, const char *newpath, gid_t gid) -{ - FsCred cred; - cred_init(&cred); - cred.fc_uid = fidp->uid; - cred.fc_gid = gid; - cred.fc_mode = 0777; - - return s->ops->symlink(&s->ctx, oldpath, newpath, &cred); -} - -static int v9fs_do_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath) -{ - return s->ops->link(&s->ctx, oldpath->data, newpath->data); -} - -static int v9fs_do_truncate(V9fsState *s, V9fsString *path, off_t size) -{ - return s->ops->truncate(&s->ctx, path->data, size); -} - -static int v9fs_do_rename(V9fsState *s, V9fsString *oldpath, - V9fsString *newpath) -{ - return s->ops->rename(&s->ctx, oldpath->data, newpath->data); -} - -static int v9fs_do_chown(V9fsState *s, V9fsString *path, uid_t uid, gid_t gid) -{ - FsCred cred; - cred_init(&cred); - cred.fc_uid = uid; - cred.fc_gid = gid; - - return s->ops->chown(&s->ctx, path->data, &cred); -} - -static int v9fs_do_utimensat(V9fsState *s, V9fsString *path, - const struct timespec times[2]) -{ - return s->ops->utimensat(&s->ctx, path->data, times); -} - -static int v9fs_do_remove(V9fsState *s, V9fsString *path) -{ - return s->ops->remove(&s->ctx, path->data); -} - -static int v9fs_do_fsync(V9fsState *s, int fd, int datasync) -{ - return s->ops->fsync(&s->ctx, fd, datasync); -} - -static int v9fs_do_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf) -{ - return s->ops->statfs(&s->ctx, path->data, stbuf); -} - -static ssize_t v9fs_do_lgetxattr(V9fsState *s, V9fsString *path, - V9fsString *xattr_name, - void *value, size_t size) -{ - return s->ops->lgetxattr(&s->ctx, path->data, - xattr_name->data, value, size); -} - -static ssize_t v9fs_do_llistxattr(V9fsState *s, V9fsString *path, - void *value, size_t size) -{ - return s->ops->llistxattr(&s->ctx, path->data, - value, size); -} - -static int v9fs_do_lsetxattr(V9fsState *s, V9fsString *path, - V9fsString *xattr_name, - void *value, size_t size, int flags) -{ - return s->ops->lsetxattr(&s->ctx, path->data, - xattr_name->data, value, size, flags); -} - -static int v9fs_do_lremovexattr(V9fsState *s, V9fsString *path, - V9fsString *xattr_name) -{ - return s->ops->lremovexattr(&s->ctx, path->data, - xattr_name->data); -} - - -static void v9fs_string_init(V9fsString *str) -{ - str->data = NULL; - str->size = 0; -} - -static void v9fs_string_free(V9fsString *str) -{ - qemu_free(str->data); - str->data = NULL; - str->size = 0; -} - -static void v9fs_string_null(V9fsString *str) -{ - v9fs_string_free(str); -} - -static int number_to_string(void *arg, char type) -{ - unsigned int ret = 0; - - switch (type) { - case 'u': { - unsigned int num = *(unsigned int *)arg; - - do { - ret++; - num = num/10; - } while (num); - break; - } - case 'U': { - unsigned long num = *(unsigned long *)arg; - do { - ret++; - num = num/10; - } while (num); - break; - } - default: - printf("Number_to_string: Unknown number format\n"); - return -1; - } - - return ret; -} - -static int GCC_FMT_ATTR(2, 0) -v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap) -{ - va_list ap2; - char *iter = (char *)fmt; - int len = 0; - int nr_args = 0; - char *arg_char_ptr; - unsigned int arg_uint; - unsigned long arg_ulong; - - /* Find the number of %'s that denotes an argument */ - for (iter = strstr(iter, "%"); iter; iter = strstr(iter, "%")) { - nr_args++; - iter++; - } - - len = strlen(fmt) - 2*nr_args; - - if (!nr_args) { - goto alloc_print; - } - - va_copy(ap2, ap); - - iter = (char *)fmt; - - /* Now parse the format string */ - for (iter = strstr(iter, "%"); iter; iter = strstr(iter, "%")) { - iter++; - switch (*iter) { - case 'u': - arg_uint = va_arg(ap2, unsigned int); - len += number_to_string((void *)&arg_uint, 'u'); - break; - case 'l': - if (*++iter == 'u') { - arg_ulong = va_arg(ap2, unsigned long); - len += number_to_string((void *)&arg_ulong, 'U'); - } else { - return -1; - } - break; - case 's': - arg_char_ptr = va_arg(ap2, char *); - len += strlen(arg_char_ptr); - break; - case 'c': - len += 1; - break; - default: - fprintf(stderr, - "v9fs_string_alloc_printf:Incorrect format %c", *iter); - return -1; - } - iter++; - } - -alloc_print: - *strp = qemu_malloc((len + 1) * sizeof(**strp)); - - return vsprintf(*strp, fmt, ap); -} - -static void GCC_FMT_ATTR(2, 3) -v9fs_string_sprintf(V9fsString *str, const char *fmt, ...) -{ - va_list ap; - int err; - - v9fs_string_free(str); - - va_start(ap, fmt); - err = v9fs_string_alloc_printf(&str->data, fmt, ap); - BUG_ON(err == -1); - va_end(ap); - - str->size = err; -} - -static void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs) -{ - v9fs_string_free(lhs); - v9fs_string_sprintf(lhs, "%s", rhs->data); -} - -static size_t v9fs_string_size(V9fsString *str) -{ - return str->size; -} - -static V9fsFidState *lookup_fid(V9fsState *s, int32_t fid) -{ - V9fsFidState *f; - - for (f = s->fid_list; f; f = f->next) { - if (f->fid == fid) { - return f; - } - } - - return NULL; -} - -static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid) -{ - V9fsFidState *f; - - f = lookup_fid(s, fid); - if (f) { - return NULL; - } - - f = qemu_mallocz(sizeof(V9fsFidState)); - - f->fid = fid; - f->fid_type = P9_FID_NONE; - - f->next = s->fid_list; - s->fid_list = f; - - return f; -} - -static int v9fs_xattr_fid_clunk(V9fsState *s, V9fsFidState *fidp) -{ - int retval = 0; - - if (fidp->fs.xattr.copied_len == -1) { - /* getxattr/listxattr fid */ - goto free_value; - } - /* - * if this is fid for setxattr. clunk should - * result in setxattr localcall - */ - if (fidp->fs.xattr.len != fidp->fs.xattr.copied_len) { - /* clunk after partial write */ - retval = -EINVAL; - goto free_out; - } - if (fidp->fs.xattr.len) { - retval = v9fs_do_lsetxattr(s, &fidp->path, &fidp->fs.xattr.name, - fidp->fs.xattr.value, - fidp->fs.xattr.len, - fidp->fs.xattr.flags); - } else { - retval = v9fs_do_lremovexattr(s, &fidp->path, &fidp->fs.xattr.name); - } -free_out: - v9fs_string_free(&fidp->fs.xattr.name); -free_value: - if (fidp->fs.xattr.value) { - qemu_free(fidp->fs.xattr.value); - } - return retval; -} - -static int free_fid(V9fsState *s, int32_t fid) -{ - int retval = 0; - V9fsFidState **fidpp, *fidp; - - for (fidpp = &s->fid_list; *fidpp; fidpp = &(*fidpp)->next) { - if ((*fidpp)->fid == fid) { - break; - } - } - - if (*fidpp == NULL) { - return -ENOENT; - } - - fidp = *fidpp; - *fidpp = fidp->next; - - if (fidp->fid_type == P9_FID_FILE) { - v9fs_do_close(s, fidp->fs.fd); - } else if (fidp->fid_type == P9_FID_DIR) { - v9fs_do_closedir(s, fidp->fs.dir); - } else if (fidp->fid_type == P9_FID_XATTR) { - retval = v9fs_xattr_fid_clunk(s, fidp); - } - v9fs_string_free(&fidp->path); - qemu_free(fidp); - - return retval; -} - -#define P9_QID_TYPE_DIR 0x80 -#define P9_QID_TYPE_SYMLINK 0x02 - -#define P9_STAT_MODE_DIR 0x80000000 -#define P9_STAT_MODE_APPEND 0x40000000 -#define P9_STAT_MODE_EXCL 0x20000000 -#define P9_STAT_MODE_MOUNT 0x10000000 -#define P9_STAT_MODE_AUTH 0x08000000 -#define P9_STAT_MODE_TMP 0x04000000 -#define P9_STAT_MODE_SYMLINK 0x02000000 -#define P9_STAT_MODE_LINK 0x01000000 -#define P9_STAT_MODE_DEVICE 0x00800000 -#define P9_STAT_MODE_NAMED_PIPE 0x00200000 -#define P9_STAT_MODE_SOCKET 0x00100000 -#define P9_STAT_MODE_SETUID 0x00080000 -#define P9_STAT_MODE_SETGID 0x00040000 -#define P9_STAT_MODE_SETVTX 0x00010000 - -#define P9_STAT_MODE_TYPE_BITS (P9_STAT_MODE_DIR | \ - P9_STAT_MODE_SYMLINK | \ - P9_STAT_MODE_LINK | \ - P9_STAT_MODE_DEVICE | \ - P9_STAT_MODE_NAMED_PIPE | \ - P9_STAT_MODE_SOCKET) - -/* This is the algorithm from ufs in spfs */ -static void stat_to_qid(const struct stat *stbuf, V9fsQID *qidp) -{ - size_t size; - - size = MIN(sizeof(stbuf->st_ino), sizeof(qidp->path)); - memcpy(&qidp->path, &stbuf->st_ino, size); - qidp->version = stbuf->st_mtime ^ (stbuf->st_size << 8); - qidp->type = 0; - if (S_ISDIR(stbuf->st_mode)) { - qidp->type |= P9_QID_TYPE_DIR; - } - if (S_ISLNK(stbuf->st_mode)) { - qidp->type |= P9_QID_TYPE_SYMLINK; - } -} - -static int fid_to_qid(V9fsState *s, V9fsFidState *fidp, V9fsQID *qidp) -{ - struct stat stbuf; - int err; - - err = v9fs_do_lstat(s, &fidp->path, &stbuf); - if (err) { - return err; - } - - stat_to_qid(&stbuf, qidp); - return 0; -} - -static V9fsPDU *alloc_pdu(V9fsState *s) -{ - V9fsPDU *pdu = NULL; - - if (!QLIST_EMPTY(&s->free_list)) { - pdu = QLIST_FIRST(&s->free_list); - QLIST_REMOVE(pdu, next); - } - return pdu; -} - -static void free_pdu(V9fsState *s, V9fsPDU *pdu) -{ - if (pdu) { - QLIST_INSERT_HEAD(&s->free_list, pdu, next); - } -} - -size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count, - size_t offset, size_t size, int pack) -{ - int i = 0; - size_t copied = 0; - - for (i = 0; size && i < sg_count; i++) { - size_t len; - if (offset >= sg[i].iov_len) { - /* skip this sg */ - offset -= sg[i].iov_len; - continue; - } else { - len = MIN(sg[i].iov_len - offset, size); - if (pack) { - memcpy(sg[i].iov_base + offset, addr, len); - } else { - memcpy(addr, sg[i].iov_base + offset, len); - } - size -= len; - copied += len; - addr += len; - if (size) { - offset = 0; - continue; - } - } - } - - return copied; -} - -static size_t pdu_unpack(void *dst, V9fsPDU *pdu, size_t offset, size_t size) -{ - return pdu_packunpack(dst, pdu->elem.out_sg, pdu->elem.out_num, - offset, size, 0); -} - -static size_t pdu_pack(V9fsPDU *pdu, size_t offset, const void *src, - size_t size) -{ - return pdu_packunpack((void *)src, pdu->elem.in_sg, pdu->elem.in_num, - offset, size, 1); -} - -static int pdu_copy_sg(V9fsPDU *pdu, size_t offset, int rx, struct iovec *sg) -{ - size_t pos = 0; - int i, j; - struct iovec *src_sg; - unsigned int num; - - if (rx) { - src_sg = pdu->elem.in_sg; - num = pdu->elem.in_num; - } else { - src_sg = pdu->elem.out_sg; - num = pdu->elem.out_num; - } - - j = 0; - for (i = 0; i < num; i++) { - if (offset <= pos) { - sg[j].iov_base = src_sg[i].iov_base; - sg[j].iov_len = src_sg[i].iov_len; - j++; - } else if (offset < (src_sg[i].iov_len + pos)) { - sg[j].iov_base = src_sg[i].iov_base; - sg[j].iov_len = src_sg[i].iov_len; - sg[j].iov_base += (offset - pos); - sg[j].iov_len -= (offset - pos); - j++; - } - pos += src_sg[i].iov_len; - } - - return j; -} - -static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...) -{ - size_t old_offset = offset; - va_list ap; - int i; - - va_start(ap, fmt); - for (i = 0; fmt[i]; i++) { - switch (fmt[i]) { - case 'b': { - uint8_t *valp = va_arg(ap, uint8_t *); - offset += pdu_unpack(valp, pdu, offset, sizeof(*valp)); - break; - } - case 'w': { - uint16_t val, *valp; - valp = va_arg(ap, uint16_t *); - val = le16_to_cpupu(valp); - offset += pdu_unpack(&val, pdu, offset, sizeof(val)); - *valp = val; - break; - } - case 'd': { - uint32_t val, *valp; - valp = va_arg(ap, uint32_t *); - val = le32_to_cpupu(valp); - offset += pdu_unpack(&val, pdu, offset, sizeof(val)); - *valp = val; - break; - } - case 'q': { - uint64_t val, *valp; - valp = va_arg(ap, uint64_t *); - val = le64_to_cpup(valp); - offset += pdu_unpack(&val, pdu, offset, sizeof(val)); - *valp = val; - break; - } - case 'v': { - struct iovec *iov = va_arg(ap, struct iovec *); - int *iovcnt = va_arg(ap, int *); - *iovcnt = pdu_copy_sg(pdu, offset, 0, iov); - break; - } - case 's': { - V9fsString *str = va_arg(ap, V9fsString *); - offset += pdu_unmarshal(pdu, offset, "w", &str->size); - /* FIXME: sanity check str->size */ - str->data = qemu_malloc(str->size + 1); - offset += pdu_unpack(str->data, pdu, offset, str->size); - str->data[str->size] = 0; - break; - } - case 'Q': { - V9fsQID *qidp = va_arg(ap, V9fsQID *); - offset += pdu_unmarshal(pdu, offset, "bdq", - &qidp->type, &qidp->version, &qidp->path); - break; - } - case 'S': { - V9fsStat *statp = va_arg(ap, V9fsStat *); - offset += pdu_unmarshal(pdu, offset, "wwdQdddqsssssddd", - &statp->size, &statp->type, &statp->dev, - &statp->qid, &statp->mode, &statp->atime, - &statp->mtime, &statp->length, - &statp->name, &statp->uid, &statp->gid, - &statp->muid, &statp->extension, - &statp->n_uid, &statp->n_gid, - &statp->n_muid); - break; - } - case 'I': { - V9fsIattr *iattr = va_arg(ap, V9fsIattr *); - offset += pdu_unmarshal(pdu, offset, "ddddqqqqq", - &iattr->valid, &iattr->mode, - &iattr->uid, &iattr->gid, &iattr->size, - &iattr->atime_sec, &iattr->atime_nsec, - &iattr->mtime_sec, &iattr->mtime_nsec); - break; - } - default: - break; - } - } - - va_end(ap); - - return offset - old_offset; -} - -static size_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...) -{ - size_t old_offset = offset; - va_list ap; - int i; - - va_start(ap, fmt); - for (i = 0; fmt[i]; i++) { - switch (fmt[i]) { - case 'b': { - uint8_t val = va_arg(ap, int); - offset += pdu_pack(pdu, offset, &val, sizeof(val)); - break; - } - case 'w': { - uint16_t val; - cpu_to_le16w(&val, va_arg(ap, int)); - offset += pdu_pack(pdu, offset, &val, sizeof(val)); - break; - } - case 'd': { - uint32_t val; - cpu_to_le32w(&val, va_arg(ap, uint32_t)); - offset += pdu_pack(pdu, offset, &val, sizeof(val)); - break; - } - case 'q': { - uint64_t val; - cpu_to_le64w(&val, va_arg(ap, uint64_t)); - offset += pdu_pack(pdu, offset, &val, sizeof(val)); - break; - } - case 'v': { - struct iovec *iov = va_arg(ap, struct iovec *); - int *iovcnt = va_arg(ap, int *); - *iovcnt = pdu_copy_sg(pdu, offset, 1, iov); - break; - } - case 's': { - V9fsString *str = va_arg(ap, V9fsString *); - offset += pdu_marshal(pdu, offset, "w", str->size); - offset += pdu_pack(pdu, offset, str->data, str->size); - break; - } - case 'Q': { - V9fsQID *qidp = va_arg(ap, V9fsQID *); - offset += pdu_marshal(pdu, offset, "bdq", - qidp->type, qidp->version, qidp->path); - break; - } - case 'S': { - V9fsStat *statp = va_arg(ap, V9fsStat *); - offset += pdu_marshal(pdu, offset, "wwdQdddqsssssddd", - statp->size, statp->type, statp->dev, - &statp->qid, statp->mode, statp->atime, - statp->mtime, statp->length, &statp->name, - &statp->uid, &statp->gid, &statp->muid, - &statp->extension, statp->n_uid, - statp->n_gid, statp->n_muid); - break; - } - case 'A': { - V9fsStatDotl *statp = va_arg(ap, V9fsStatDotl *); - offset += pdu_marshal(pdu, offset, "qQdddqqqqqqqqqqqqqqq", - statp->st_result_mask, - &statp->qid, statp->st_mode, - statp->st_uid, statp->st_gid, - statp->st_nlink, statp->st_rdev, - statp->st_size, statp->st_blksize, statp->st_blocks, - statp->st_atime_sec, statp->st_atime_nsec, - statp->st_mtime_sec, statp->st_mtime_nsec, - statp->st_ctime_sec, statp->st_ctime_nsec, - statp->st_btime_sec, statp->st_btime_nsec, - statp->st_gen, statp->st_data_version); - break; - } - default: - break; - } - } - va_end(ap); - - return offset - old_offset; -} - -static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len) -{ - int8_t id = pdu->id + 1; /* Response */ - - if (len < 0) { - int err = -len; - len = 7; - - if (s->proto_version != V9FS_PROTO_2000L) { - V9fsString str; - - str.data = strerror(err); - str.size = strlen(str.data); - - len += pdu_marshal(pdu, len, "s", &str); - id = P9_RERROR; - } - - len += pdu_marshal(pdu, len, "d", err); - - if (s->proto_version == V9FS_PROTO_2000L) { - id = P9_RLERROR; - } - } - - /* fill out the header */ - pdu_marshal(pdu, 0, "dbw", (int32_t)len, id, pdu->tag); - - /* keep these in sync */ - pdu->size = len; - pdu->id = id; - - /* push onto queue and notify */ - virtqueue_push(s->vq, &pdu->elem, len); - - /* FIXME: we should batch these completions */ - virtio_notify(&s->vdev, s->vq); - - free_pdu(s, pdu); -} - -static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension) -{ - mode_t ret; - - ret = mode & 0777; - if (mode & P9_STAT_MODE_DIR) { - ret |= S_IFDIR; - } - - if (mode & P9_STAT_MODE_SYMLINK) { - ret |= S_IFLNK; - } - if (mode & P9_STAT_MODE_SOCKET) { - ret |= S_IFSOCK; - } - if (mode & P9_STAT_MODE_NAMED_PIPE) { - ret |= S_IFIFO; - } - if (mode & P9_STAT_MODE_DEVICE) { - if (extension && extension->data[0] == 'c') { - ret |= S_IFCHR; - } else { - ret |= S_IFBLK; - } - } - - if (!(ret&~0777)) { - ret |= S_IFREG; - } - - if (mode & P9_STAT_MODE_SETUID) { - ret |= S_ISUID; - } - if (mode & P9_STAT_MODE_SETGID) { - ret |= S_ISGID; - } - if (mode & P9_STAT_MODE_SETVTX) { - ret |= S_ISVTX; - } - - return ret; -} - -static int donttouch_stat(V9fsStat *stat) -{ - if (stat->type == -1 && - stat->dev == -1 && - stat->qid.type == -1 && - stat->qid.version == -1 && - stat->qid.path == -1 && - stat->mode == -1 && - stat->atime == -1 && - stat->mtime == -1 && - stat->length == -1 && - !stat->name.size && - !stat->uid.size && - !stat->gid.size && - !stat->muid.size && - stat->n_uid == -1 && - stat->n_gid == -1 && - stat->n_muid == -1) { - return 1; - } - - return 0; -} - -static void v9fs_stat_free(V9fsStat *stat) -{ - v9fs_string_free(&stat->name); - v9fs_string_free(&stat->uid); - v9fs_string_free(&stat->gid); - v9fs_string_free(&stat->muid); - v9fs_string_free(&stat->extension); -} - -static uint32_t stat_to_v9mode(const struct stat *stbuf) -{ - uint32_t mode; - - mode = stbuf->st_mode & 0777; - if (S_ISDIR(stbuf->st_mode)) { - mode |= P9_STAT_MODE_DIR; - } - - if (S_ISLNK(stbuf->st_mode)) { - mode |= P9_STAT_MODE_SYMLINK; - } - - if (S_ISSOCK(stbuf->st_mode)) { - mode |= P9_STAT_MODE_SOCKET; - } - - if (S_ISFIFO(stbuf->st_mode)) { - mode |= P9_STAT_MODE_NAMED_PIPE; - } - - if (S_ISBLK(stbuf->st_mode) || S_ISCHR(stbuf->st_mode)) { - mode |= P9_STAT_MODE_DEVICE; - } - - if (stbuf->st_mode & S_ISUID) { - mode |= P9_STAT_MODE_SETUID; - } - - if (stbuf->st_mode & S_ISGID) { - mode |= P9_STAT_MODE_SETGID; - } - - if (stbuf->st_mode & S_ISVTX) { - mode |= P9_STAT_MODE_SETVTX; - } - - return mode; -} - -static int stat_to_v9stat(V9fsState *s, V9fsString *name, - const struct stat *stbuf, - V9fsStat *v9stat) -{ - int err; - const char *str; - - memset(v9stat, 0, sizeof(*v9stat)); - - stat_to_qid(stbuf, &v9stat->qid); - v9stat->mode = stat_to_v9mode(stbuf); - v9stat->atime = stbuf->st_atime; - v9stat->mtime = stbuf->st_mtime; - v9stat->length = stbuf->st_size; - - v9fs_string_null(&v9stat->uid); - v9fs_string_null(&v9stat->gid); - v9fs_string_null(&v9stat->muid); - - v9stat->n_uid = stbuf->st_uid; - v9stat->n_gid = stbuf->st_gid; - v9stat->n_muid = 0; - - v9fs_string_null(&v9stat->extension); - - if (v9stat->mode & P9_STAT_MODE_SYMLINK) { - err = v9fs_do_readlink(s, name, &v9stat->extension); - if (err == -1) { - err = -errno; - return err; - } - v9stat->extension.data[err] = 0; - v9stat->extension.size = err; - } else if (v9stat->mode & P9_STAT_MODE_DEVICE) { - v9fs_string_sprintf(&v9stat->extension, "%c %u %u", - S_ISCHR(stbuf->st_mode) ? 'c' : 'b', - major(stbuf->st_rdev), minor(stbuf->st_rdev)); - } else if (S_ISDIR(stbuf->st_mode) || S_ISREG(stbuf->st_mode)) { - v9fs_string_sprintf(&v9stat->extension, "%s %lu", - "HARDLINKCOUNT", (unsigned long)stbuf->st_nlink); - } - - str = strrchr(name->data, '/'); - if (str) { - str += 1; - } else { - str = name->data; - } - - v9fs_string_sprintf(&v9stat->name, "%s", str); - - v9stat->size = 61 + - v9fs_string_size(&v9stat->name) + - v9fs_string_size(&v9stat->uid) + - v9fs_string_size(&v9stat->gid) + - v9fs_string_size(&v9stat->muid) + - v9fs_string_size(&v9stat->extension); - return 0; -} - -#define P9_STATS_MODE 0x00000001ULL -#define P9_STATS_NLINK 0x00000002ULL -#define P9_STATS_UID 0x00000004ULL -#define P9_STATS_GID 0x00000008ULL -#define P9_STATS_RDEV 0x00000010ULL -#define P9_STATS_ATIME 0x00000020ULL -#define P9_STATS_MTIME 0x00000040ULL -#define P9_STATS_CTIME 0x00000080ULL -#define P9_STATS_INO 0x00000100ULL -#define P9_STATS_SIZE 0x00000200ULL -#define P9_STATS_BLOCKS 0x00000400ULL - -#define P9_STATS_BTIME 0x00000800ULL -#define P9_STATS_GEN 0x00001000ULL -#define P9_STATS_DATA_VERSION 0x00002000ULL - -#define P9_STATS_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */ -#define P9_STATS_ALL 0x00003fffULL /* Mask for All fields above */ - - -static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf, - V9fsStatDotl *v9lstat) -{ - memset(v9lstat, 0, sizeof(*v9lstat)); - - v9lstat->st_mode = stbuf->st_mode; - v9lstat->st_nlink = stbuf->st_nlink; - v9lstat->st_uid = stbuf->st_uid; - v9lstat->st_gid = stbuf->st_gid; - v9lstat->st_rdev = stbuf->st_rdev; - v9lstat->st_size = stbuf->st_size; - v9lstat->st_blksize = stbuf->st_blksize; - v9lstat->st_blocks = stbuf->st_blocks; - v9lstat->st_atime_sec = stbuf->st_atime; - v9lstat->st_atime_nsec = stbuf->st_atim.tv_nsec; - v9lstat->st_mtime_sec = stbuf->st_mtime; - v9lstat->st_mtime_nsec = stbuf->st_mtim.tv_nsec; - v9lstat->st_ctime_sec = stbuf->st_ctime; - v9lstat->st_ctime_nsec = stbuf->st_ctim.tv_nsec; - /* Currently we only support BASIC fields in stat */ - v9lstat->st_result_mask = P9_STATS_BASIC; - - stat_to_qid(stbuf, &v9lstat->qid); -} - -static struct iovec *adjust_sg(struct iovec *sg, int len, int *iovcnt) -{ - while (len && *iovcnt) { - if (len < sg->iov_len) { - sg->iov_len -= len; - sg->iov_base += len; - len = 0; - } else { - len -= sg->iov_len; - sg++; - *iovcnt -= 1; - } - } - - return sg; -} - -static struct iovec *cap_sg(struct iovec *sg, int cap, int *cnt) -{ - int i; - int total = 0; - - for (i = 0; i < *cnt; i++) { - if ((total + sg[i].iov_len) > cap) { - sg[i].iov_len -= ((total + sg[i].iov_len) - cap); - i++; - break; - } - total += sg[i].iov_len; - } - - *cnt = i; - - return sg; -} - -static void print_sg(struct iovec *sg, int cnt) -{ - int i; - - printf("sg[%d]: {", cnt); - for (i = 0; i < cnt; i++) { - if (i) { - printf(", "); - } - printf("(%p, %zd)", sg[i].iov_base, sg[i].iov_len); - } - printf("}\n"); -} - -static void v9fs_fix_path(V9fsString *dst, V9fsString *src, int len) -{ - V9fsString str; - v9fs_string_init(&str); - v9fs_string_copy(&str, dst); - v9fs_string_sprintf(dst, "%s%s", src->data, str.data+len); - v9fs_string_free(&str); -} - -static void v9fs_version(V9fsState *s, V9fsPDU *pdu) -{ - V9fsString version; - size_t offset = 7; - - pdu_unmarshal(pdu, offset, "ds", &s->msize, &version); - - if (!strcmp(version.data, "9P2000.u")) { - s->proto_version = V9FS_PROTO_2000U; - } else if (!strcmp(version.data, "9P2000.L")) { - s->proto_version = V9FS_PROTO_2000L; - } else { - v9fs_string_sprintf(&version, "unknown"); - } - - offset += pdu_marshal(pdu, offset, "ds", s->msize, &version); - complete_pdu(s, pdu, offset); - - v9fs_string_free(&version); -} - -static void v9fs_attach(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid, afid, n_uname; - V9fsString uname, aname; - V9fsFidState *fidp; - V9fsQID qid; - size_t offset = 7; - ssize_t err; - - pdu_unmarshal(pdu, offset, "ddssd", &fid, &afid, &uname, &aname, &n_uname); - - fidp = alloc_fid(s, fid); - if (fidp == NULL) { - err = -EINVAL; - goto out; - } - - fidp->uid = n_uname; - - v9fs_string_sprintf(&fidp->path, "%s", "/"); - err = fid_to_qid(s, fidp, &qid); - if (err) { - err = -EINVAL; - free_fid(s, fid); - goto out; - } - - offset += pdu_marshal(pdu, offset, "Q", &qid); - - err = offset; -out: - complete_pdu(s, pdu, err); - v9fs_string_free(&uname); - v9fs_string_free(&aname); -} - -static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - err = stat_to_v9stat(s, &vs->fidp->path, &vs->stbuf, &vs->v9stat); - if (err) { - goto out; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "wS", 0, &vs->v9stat); - err = vs->offset; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_stat_free(&vs->v9stat); - qemu_free(vs); -} - -static void v9fs_stat(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsStatState *vs; - ssize_t err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - memset(&vs->v9stat, 0, sizeof(vs->v9stat)); - - pdu_unmarshal(vs->pdu, vs->offset, "d", &fid); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); - v9fs_stat_post_lstat(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_stat_free(&vs->v9stat); - qemu_free(vs); -} - -static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs, - int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - stat_to_v9stat_dotl(s, &vs->stbuf, &vs->v9stat_dotl); - vs->offset += pdu_marshal(vs->pdu, vs->offset, "A", &vs->v9stat_dotl); - err = vs->offset; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsStatStateDotl *vs; - ssize_t err = 0; - V9fsFidState *fidp; - uint64_t request_mask; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - memset(&vs->v9stat_dotl, 0, sizeof(vs->v9stat_dotl)); - - pdu_unmarshal(vs->pdu, vs->offset, "dq", &fid, &request_mask); - - fidp = lookup_fid(s, fid); - if (fidp == NULL) { - err = -ENOENT; - goto out; - } - - /* Currently we only support BASIC fields in stat, so there is no - * need to look at request_mask. - */ - err = v9fs_do_lstat(s, &fidp->path, &vs->stbuf); - v9fs_getattr_post_lstat(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -/* From Linux kernel code */ -#define ATTR_MODE (1 << 0) -#define ATTR_UID (1 << 1) -#define ATTR_GID (1 << 2) -#define ATTR_SIZE (1 << 3) -#define ATTR_ATIME (1 << 4) -#define ATTR_MTIME (1 << 5) -#define ATTR_CTIME (1 << 6) -#define ATTR_MASK 127 -#define ATTR_ATIME_SET (1 << 7) -#define ATTR_MTIME_SET (1 << 8) - -static void v9fs_setattr_post_truncate(V9fsState *s, V9fsSetattrState *vs, - int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - err = vs->offset; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_setattr_post_chown(V9fsState *s, V9fsSetattrState *vs, int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - if (vs->v9iattr.valid & (ATTR_SIZE)) { - err = v9fs_do_truncate(s, &vs->fidp->path, vs->v9iattr.size); - } - v9fs_setattr_post_truncate(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_setattr_post_utimensat(V9fsState *s, V9fsSetattrState *vs, - int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - /* If the only valid entry in iattr is ctime we can call - * chown(-1,-1) to update the ctime of the file - */ - if ((vs->v9iattr.valid & (ATTR_UID | ATTR_GID)) || - ((vs->v9iattr.valid & ATTR_CTIME) - && !((vs->v9iattr.valid & ATTR_MASK) & ~ATTR_CTIME))) { - if (!(vs->v9iattr.valid & ATTR_UID)) { - vs->v9iattr.uid = -1; - } - if (!(vs->v9iattr.valid & ATTR_GID)) { - vs->v9iattr.gid = -1; - } - err = v9fs_do_chown(s, &vs->fidp->path, vs->v9iattr.uid, - vs->v9iattr.gid); - } - v9fs_setattr_post_chown(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_setattr_post_chmod(V9fsState *s, V9fsSetattrState *vs, int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - if (vs->v9iattr.valid & (ATTR_ATIME | ATTR_MTIME)) { - struct timespec times[2]; - if (vs->v9iattr.valid & ATTR_ATIME) { - if (vs->v9iattr.valid & ATTR_ATIME_SET) { - times[0].tv_sec = vs->v9iattr.atime_sec; - times[0].tv_nsec = vs->v9iattr.atime_nsec; - } else { - times[0].tv_nsec = UTIME_NOW; - } - } else { - times[0].tv_nsec = UTIME_OMIT; - } - - if (vs->v9iattr.valid & ATTR_MTIME) { - if (vs->v9iattr.valid & ATTR_MTIME_SET) { - times[1].tv_sec = vs->v9iattr.mtime_sec; - times[1].tv_nsec = vs->v9iattr.mtime_nsec; - } else { - times[1].tv_nsec = UTIME_NOW; - } - } else { - times[1].tv_nsec = UTIME_OMIT; - } - err = v9fs_do_utimensat(s, &vs->fidp->path, times); - } - v9fs_setattr_post_utimensat(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_setattr(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsSetattrState *vs; - int err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - pdu_unmarshal(pdu, vs->offset, "dI", &fid, &vs->v9iattr); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -EINVAL; - goto out; - } - - if (vs->v9iattr.valid & ATTR_MODE) { - err = v9fs_do_chmod(s, &vs->fidp->path, vs->v9iattr.mode); - } - - v9fs_setattr_post_chmod(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err) -{ - complete_pdu(s, vs->pdu, err); - - if (vs->nwnames) { - for (vs->name_idx = 0; vs->name_idx < vs->nwnames; vs->name_idx++) { - v9fs_string_free(&vs->wnames[vs->name_idx]); - } - - qemu_free(vs->wnames); - qemu_free(vs->qids); - } -} - -static void v9fs_walk_marshal(V9fsWalkState *vs) -{ - int i; - vs->offset = 7; - vs->offset += pdu_marshal(vs->pdu, vs->offset, "w", vs->nwnames); - - for (i = 0; i < vs->nwnames; i++) { - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qids[i]); - } -} - -static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs, - int err) -{ - if (err == -1) { - free_fid(s, vs->newfidp->fid); - v9fs_string_free(&vs->path); - err = -ENOENT; - goto out; - } - - stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]); - - vs->name_idx++; - if (vs->name_idx < vs->nwnames) { - v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data, - vs->wnames[vs->name_idx].data); - v9fs_string_copy(&vs->newfidp->path, &vs->path); - - err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf); - v9fs_walk_post_newfid_lstat(s, vs, err); - return; - } - - v9fs_string_free(&vs->path); - v9fs_walk_marshal(vs); - err = vs->offset; -out: - v9fs_walk_complete(s, vs, err); -} - -static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs, - int err) -{ - if (err == -1) { - v9fs_string_free(&vs->path); - err = -ENOENT; - goto out; - } - - stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]); - vs->name_idx++; - if (vs->name_idx < vs->nwnames) { - - v9fs_string_sprintf(&vs->path, "%s/%s", - vs->fidp->path.data, vs->wnames[vs->name_idx].data); - v9fs_string_copy(&vs->fidp->path, &vs->path); - - err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); - v9fs_walk_post_oldfid_lstat(s, vs, err); - return; - } - - v9fs_string_free(&vs->path); - v9fs_walk_marshal(vs); - err = vs->offset; -out: - v9fs_walk_complete(s, vs, err); -} - -static void v9fs_walk(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid, newfid; - V9fsWalkState *vs; - int err = 0; - int i; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->wnames = NULL; - vs->qids = NULL; - vs->offset = 7; - - vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid, - &newfid, &vs->nwnames); - - if (vs->nwnames) { - vs->wnames = qemu_mallocz(sizeof(vs->wnames[0]) * vs->nwnames); - - vs->qids = qemu_mallocz(sizeof(vs->qids[0]) * vs->nwnames); - - for (i = 0; i < vs->nwnames; i++) { - vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "s", - &vs->wnames[i]); - } - } - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - /* FIXME: is this really valid? */ - if (fid == newfid) { - - BUG_ON(vs->fidp->fid_type != P9_FID_NONE); - v9fs_string_init(&vs->path); - vs->name_idx = 0; - - if (vs->name_idx < vs->nwnames) { - v9fs_string_sprintf(&vs->path, "%s/%s", - vs->fidp->path.data, vs->wnames[vs->name_idx].data); - v9fs_string_copy(&vs->fidp->path, &vs->path); - - err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); - v9fs_walk_post_oldfid_lstat(s, vs, err); - return; - } - } else { - vs->newfidp = alloc_fid(s, newfid); - if (vs->newfidp == NULL) { - err = -EINVAL; - goto out; - } - - vs->newfidp->uid = vs->fidp->uid; - v9fs_string_init(&vs->path); - vs->name_idx = 0; - v9fs_string_copy(&vs->newfidp->path, &vs->fidp->path); - - if (vs->name_idx < vs->nwnames) { - v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data, - vs->wnames[vs->name_idx].data); - v9fs_string_copy(&vs->newfidp->path, &vs->path); - - err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf); - v9fs_walk_post_newfid_lstat(s, vs, err); - return; - } - } - - v9fs_walk_marshal(vs); - err = vs->offset; -out: - v9fs_walk_complete(s, vs, err); -} - -static int32_t get_iounit(V9fsState *s, V9fsString *name) -{ - struct statfs stbuf; - int32_t iounit = 0; - - /* - * iounit should be multiples of f_bsize (host filesystem block size - * and as well as less than (client msize - P9_IOHDRSZ)) - */ - if (!v9fs_do_statfs(s, name, &stbuf)) { - iounit = stbuf.f_bsize; - iounit *= (s->msize - P9_IOHDRSZ)/stbuf.f_bsize; - } - - if (!iounit) { - iounit = s->msize - P9_IOHDRSZ; - } - return iounit; -} - -static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err) -{ - if (vs->fidp->fs.dir == NULL) { - err = -errno; - goto out; - } - vs->fidp->fid_type = P9_FID_DIR; - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); - -} - -static void v9fs_open_post_getiounit(V9fsState *s, V9fsOpenState *vs) -{ - int err; - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit); - err = vs->offset; - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err) -{ - if (vs->fidp->fs.fd == -1) { - err = -errno; - goto out; - } - vs->fidp->fid_type = P9_FID_FILE; - vs->iounit = get_iounit(s, &vs->fidp->path); - v9fs_open_post_getiounit(s, vs); - return; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err) -{ - int flags; - - if (err) { - err = -errno; - goto out; - } - - stat_to_qid(&vs->stbuf, &vs->qid); - - if (S_ISDIR(vs->stbuf.st_mode)) { - vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fidp->path); - v9fs_open_post_opendir(s, vs, err); - } else { - if (s->proto_version == V9FS_PROTO_2000L) { - flags = vs->mode; - flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT); - /* Ignore direct disk access hint until the server supports it. */ - flags &= ~O_DIRECT; - } else { - flags = omode_to_uflags(vs->mode); - } - vs->fidp->fs.fd = v9fs_do_open(s, &vs->fidp->path, flags); - v9fs_open_post_open(s, vs, err); - } - return; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_open(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsOpenState *vs; - ssize_t err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - vs->mode = 0; - - if (s->proto_version == V9FS_PROTO_2000L) { - pdu_unmarshal(vs->pdu, vs->offset, "dd", &fid, &vs->mode); - } else { - pdu_unmarshal(vs->pdu, vs->offset, "db", &fid, &vs->mode); - } - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - BUG_ON(vs->fidp->fid_type != P9_FID_NONE); - - err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); - - v9fs_open_post_lstat(s, vs, err); - return; -out: - complete_pdu(s, pdu, err); - qemu_free(vs); -} - -static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err) -{ - if (err == 0) { - v9fs_string_copy(&vs->fidp->path, &vs->fullname); - stat_to_qid(&vs->stbuf, &vs->qid); - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, - &vs->iounit); - err = vs->offset; - } else { - vs->fidp->fid_type = P9_FID_NONE; - err = -errno; - if (vs->fidp->fs.fd > 0) { - close(vs->fidp->fs.fd); - } - } - - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - v9fs_string_free(&vs->fullname); - qemu_free(vs); -} - -static void v9fs_lcreate_post_get_iounit(V9fsState *s, V9fsLcreateState *vs, - int err) -{ - if (err) { - err = -errno; - goto out; - } - err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf); - -out: - v9fs_post_lcreate(s, vs, err); -} - -static void v9fs_lcreate_post_do_open2(V9fsState *s, V9fsLcreateState *vs, - int err) -{ - if (vs->fidp->fs.fd == -1) { - err = -errno; - goto out; - } - vs->fidp->fid_type = P9_FID_FILE; - vs->iounit = get_iounit(s, &vs->fullname); - v9fs_lcreate_post_get_iounit(s, vs, err); - return; - -out: - v9fs_post_lcreate(s, vs, err); -} - -static void v9fs_lcreate(V9fsState *s, V9fsPDU *pdu) -{ - int32_t dfid, flags, mode; - gid_t gid; - V9fsLcreateState *vs; - ssize_t err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - v9fs_string_init(&vs->fullname); - - pdu_unmarshal(vs->pdu, vs->offset, "dsddd", &dfid, &vs->name, &flags, - &mode, &gid); - - vs->fidp = lookup_fid(s, dfid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->fidp->path.data, - vs->name.data); - - /* Ignore direct disk access hint until the server supports it. */ - flags &= ~O_DIRECT; - - vs->fidp->fs.fd = v9fs_do_open2(s, vs->fullname.data, vs->fidp->uid, - gid, flags, mode); - v9fs_lcreate_post_do_open2(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err) -{ - if (err == -1) { - err = -errno; - } - complete_pdu(s, pdu, err); -} - -static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - size_t offset = 7; - V9fsFidState *fidp; - int datasync; - int err; - - pdu_unmarshal(pdu, offset, "dd", &fid, &datasync); - fidp = lookup_fid(s, fid); - if (fidp == NULL) { - err = -ENOENT; - v9fs_post_do_fsync(s, pdu, err); - return; - } - err = v9fs_do_fsync(s, fidp->fs.fd, datasync); - v9fs_post_do_fsync(s, pdu, err); -} - -static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - size_t offset = 7; - int err; - - pdu_unmarshal(pdu, offset, "d", &fid); - - err = free_fid(s, fid); - if (err < 0) { - goto out; - } - - offset = 7; - err = offset; -out: - complete_pdu(s, pdu, err); -} - -static void v9fs_read_post_readdir(V9fsState *, V9fsReadState *, ssize_t); - -static void v9fs_read_post_seekdir(V9fsState *s, V9fsReadState *vs, ssize_t err) -{ - if (err) { - goto out; - } - v9fs_stat_free(&vs->v9stat); - v9fs_string_free(&vs->name); - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count); - vs->offset += vs->count; - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); - return; -} - -static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs, - ssize_t err) -{ - if (err) { - err = -errno; - goto out; - } - err = stat_to_v9stat(s, &vs->name, &vs->stbuf, &vs->v9stat); - if (err) { - goto out; - } - - vs->len = pdu_marshal(vs->pdu, vs->offset + 4 + vs->count, "S", - &vs->v9stat); - if ((vs->len != (vs->v9stat.size + 2)) || - ((vs->count + vs->len) > vs->max_count)) { - v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos); - v9fs_read_post_seekdir(s, vs, err); - return; - } - vs->count += vs->len; - v9fs_stat_free(&vs->v9stat); - v9fs_string_free(&vs->name); - vs->dir_pos = vs->dent->d_off; - vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir); - v9fs_read_post_readdir(s, vs, err); - return; -out: - v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos); - v9fs_read_post_seekdir(s, vs, err); - return; - -} - -static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err) -{ - if (vs->dent) { - memset(&vs->v9stat, 0, sizeof(vs->v9stat)); - v9fs_string_init(&vs->name); - v9fs_string_sprintf(&vs->name, "%s/%s", vs->fidp->path.data, - vs->dent->d_name); - err = v9fs_do_lstat(s, &vs->name, &vs->stbuf); - v9fs_read_post_dir_lstat(s, vs, err); - return; - } - - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count); - vs->offset += vs->count; - err = vs->offset; - complete_pdu(s, vs->pdu, err); - qemu_free(vs); - return; -} - -static void v9fs_read_post_telldir(V9fsState *s, V9fsReadState *vs, ssize_t err) -{ - vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir); - v9fs_read_post_readdir(s, vs, err); - return; -} - -static void v9fs_read_post_rewinddir(V9fsState *s, V9fsReadState *vs, - ssize_t err) -{ - vs->dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir); - v9fs_read_post_telldir(s, vs, err); - return; -} - -static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err) -{ - if (err < 0) { - /* IO error return the error */ - err = -errno; - goto out; - } - vs->total += vs->len; - vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt); - if (vs->total < vs->count && vs->len > 0) { - do { - if (0) { - print_sg(vs->sg, vs->cnt); - } - vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt, - vs->off); - if (vs->len > 0) { - vs->off += vs->len; - } - } while (vs->len == -1 && errno == EINTR); - if (vs->len == -1) { - err = -errno; - } - v9fs_read_post_preadv(s, vs, err); - return; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total); - vs->offset += vs->count; - err = vs->offset; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs) -{ - ssize_t err = 0; - int read_count; - int64_t xattr_len; - - xattr_len = vs->fidp->fs.xattr.len; - read_count = xattr_len - vs->off; - if (read_count > vs->count) { - read_count = vs->count; - } else if (read_count < 0) { - /* - * read beyond XATTR value - */ - read_count = 0; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", read_count); - vs->offset += pdu_pack(vs->pdu, vs->offset, - ((char *)vs->fidp->fs.xattr.value) + vs->off, - read_count); - err = vs->offset; - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_read(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsReadState *vs; - ssize_t err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - vs->total = 0; - vs->len = 0; - vs->count = 0; - - pdu_unmarshal(vs->pdu, vs->offset, "dqd", &fid, &vs->off, &vs->count); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -EINVAL; - goto out; - } - - if (vs->fidp->fid_type == P9_FID_DIR) { - vs->max_count = vs->count; - vs->count = 0; - if (vs->off == 0) { - v9fs_do_rewinddir(s, vs->fidp->fs.dir); - } - v9fs_read_post_rewinddir(s, vs, err); - return; - } else if (vs->fidp->fid_type == P9_FID_FILE) { - vs->sg = vs->iov; - pdu_marshal(vs->pdu, vs->offset + 4, "v", vs->sg, &vs->cnt); - vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); - if (vs->total <= vs->count) { - vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt, - vs->off); - if (vs->len > 0) { - vs->off += vs->len; - } - err = vs->len; - v9fs_read_post_preadv(s, vs, err); - } - return; - } else if (vs->fidp->fid_type == P9_FID_XATTR) { - v9fs_xattr_read(s, vs); - return; - } else { - err = -EINVAL; - } -out: - complete_pdu(s, pdu, err); - qemu_free(vs); -} - -typedef struct V9fsReadDirState { - V9fsPDU *pdu; - V9fsFidState *fidp; - V9fsQID qid; - off_t saved_dir_pos; - struct dirent *dent; - int32_t count; - int32_t max_count; - size_t offset; - int64_t initial_offset; - V9fsString name; -} V9fsReadDirState; - -static void v9fs_readdir_post_seekdir(V9fsState *s, V9fsReadDirState *vs) -{ - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count); - vs->offset += vs->count; - complete_pdu(s, vs->pdu, vs->offset); - qemu_free(vs); - return; -} - -/* Size of each dirent on the wire: size of qid (13) + size of offset (8) - * size of type (1) + size of name.size (2) + strlen(name.data) - */ -#define V9_READDIR_DATA_SZ (24 + strlen(vs->name.data)) - -static void v9fs_readdir_post_readdir(V9fsState *s, V9fsReadDirState *vs) -{ - int len; - size_t size; - - if (vs->dent) { - v9fs_string_init(&vs->name); - v9fs_string_sprintf(&vs->name, "%s", vs->dent->d_name); - - if ((vs->count + V9_READDIR_DATA_SZ) > vs->max_count) { - /* Ran out of buffer. Set dir back to old position and return */ - v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->saved_dir_pos); - v9fs_readdir_post_seekdir(s, vs); - return; - } - - /* Fill up just the path field of qid because the client uses - * only that. To fill the entire qid structure we will have - * to stat each dirent found, which is expensive - */ - size = MIN(sizeof(vs->dent->d_ino), sizeof(vs->qid.path)); - memcpy(&vs->qid.path, &vs->dent->d_ino, size); - /* Fill the other fields with dummy values */ - vs->qid.type = 0; - vs->qid.version = 0; - - len = pdu_marshal(vs->pdu, vs->offset+4+vs->count, "Qqbs", - &vs->qid, vs->dent->d_off, - vs->dent->d_type, &vs->name); - vs->count += len; - v9fs_string_free(&vs->name); - vs->saved_dir_pos = vs->dent->d_off; - vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir); - v9fs_readdir_post_readdir(s, vs); - return; - } - - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count); - vs->offset += vs->count; - complete_pdu(s, vs->pdu, vs->offset); - qemu_free(vs); - return; -} - -static void v9fs_readdir_post_telldir(V9fsState *s, V9fsReadDirState *vs) -{ - vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir); - v9fs_readdir_post_readdir(s, vs); - return; -} - -static void v9fs_readdir_post_setdir(V9fsState *s, V9fsReadDirState *vs) -{ - vs->saved_dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir); - v9fs_readdir_post_telldir(s, vs); - return; -} - -static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsReadDirState *vs; - ssize_t err = 0; - size_t offset = 7; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - vs->count = 0; - - pdu_unmarshal(vs->pdu, offset, "dqd", &fid, &vs->initial_offset, - &vs->max_count); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL || !(vs->fidp->fs.dir)) { - err = -EINVAL; - goto out; - } - - if (vs->initial_offset == 0) { - v9fs_do_rewinddir(s, vs->fidp->fs.dir); - } else { - v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->initial_offset); - } - - v9fs_readdir_post_setdir(s, vs); - return; - -out: - complete_pdu(s, pdu, err); - qemu_free(vs); - return; -} - -static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs, - ssize_t err) -{ - if (err < 0) { - /* IO error return the error */ - err = -errno; - goto out; - } - vs->total += vs->len; - vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt); - if (vs->total < vs->count && vs->len > 0) { - do { - if (0) { - print_sg(vs->sg, vs->cnt); - } - vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, - vs->off); - if (vs->len > 0) { - vs->off += vs->len; - } - } while (vs->len == -1 && errno == EINTR); - if (vs->len == -1) { - err = -errno; - } - v9fs_write_post_pwritev(s, vs, err); - return; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs) -{ - int i, to_copy; - ssize_t err = 0; - int write_count; - int64_t xattr_len; - - xattr_len = vs->fidp->fs.xattr.len; - write_count = xattr_len - vs->off; - if (write_count > vs->count) { - write_count = vs->count; - } else if (write_count < 0) { - /* - * write beyond XATTR value len specified in - * xattrcreate - */ - err = -ENOSPC; - goto out; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", write_count); - err = vs->offset; - vs->fidp->fs.xattr.copied_len += write_count; - /* - * Now copy the content from sg list - */ - for (i = 0; i < vs->cnt; i++) { - if (write_count > vs->sg[i].iov_len) { - to_copy = vs->sg[i].iov_len; - } else { - to_copy = write_count; - } - memcpy((char *)vs->fidp->fs.xattr.value + vs->off, - vs->sg[i].iov_base, to_copy); - /* updating vs->off since we are not using below */ - vs->off += to_copy; - write_count -= to_copy; - } -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_write(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsWriteState *vs; - ssize_t err; - - vs = qemu_malloc(sizeof(*vs)); - - vs->pdu = pdu; - vs->offset = 7; - vs->sg = vs->iov; - vs->total = 0; - vs->len = 0; - - pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &fid, &vs->off, &vs->count, - vs->sg, &vs->cnt); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -EINVAL; - goto out; - } - - if (vs->fidp->fid_type == P9_FID_FILE) { - if (vs->fidp->fs.fd == -1) { - err = -EINVAL; - goto out; - } - } else if (vs->fidp->fid_type == P9_FID_XATTR) { - /* - * setxattr operation - */ - v9fs_xattr_write(s, vs); - return; - } else { - err = -EINVAL; - goto out; - } - vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); - if (vs->total <= vs->count) { - vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off); - if (vs->len > 0) { - vs->off += vs->len; - } - err = vs->len; - v9fs_write_post_pwritev(s, vs, err); - } - return; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_create_post_getiounit(V9fsState *s, V9fsCreateState *vs) -{ - int err; - v9fs_string_copy(&vs->fidp->path, &vs->fullname); - stat_to_qid(&vs->stbuf, &vs->qid); - - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit); - err = vs->offset; - - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - v9fs_string_free(&vs->extension); - v9fs_string_free(&vs->fullname); - qemu_free(vs); -} - -static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err) -{ - if (err == 0) { - vs->iounit = get_iounit(s, &vs->fidp->path); - v9fs_create_post_getiounit(s, vs); - return; - } - - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - v9fs_string_free(&vs->extension); - v9fs_string_free(&vs->fullname); - qemu_free(vs); -} - -static void v9fs_create_post_perms(V9fsState *s, V9fsCreateState *vs, int err) -{ - if (err) { - err = -errno; - } - v9fs_post_create(s, vs, err); -} - -static void v9fs_create_post_opendir(V9fsState *s, V9fsCreateState *vs, - int err) -{ - if (!vs->fidp->fs.dir) { - err = -errno; - } - vs->fidp->fid_type = P9_FID_DIR; - v9fs_post_create(s, vs, err); -} - -static void v9fs_create_post_dir_lstat(V9fsState *s, V9fsCreateState *vs, - int err) -{ - if (err) { - err = -errno; - goto out; - } - - vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fullname); - v9fs_create_post_opendir(s, vs, err); - return; - -out: - v9fs_post_create(s, vs, err); -} - -static void v9fs_create_post_mkdir(V9fsState *s, V9fsCreateState *vs, int err) -{ - if (err) { - err = -errno; - goto out; - } - - err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf); - v9fs_create_post_dir_lstat(s, vs, err); - return; - -out: - v9fs_post_create(s, vs, err); -} - -static void v9fs_create_post_fstat(V9fsState *s, V9fsCreateState *vs, int err) -{ - if (err) { - vs->fidp->fid_type = P9_FID_NONE; - close(vs->fidp->fs.fd); - err = -errno; - } - v9fs_post_create(s, vs, err); - return; -} - -static void v9fs_create_post_open2(V9fsState *s, V9fsCreateState *vs, int err) -{ - if (vs->fidp->fs.fd == -1) { - err = -errno; - goto out; - } - vs->fidp->fid_type = P9_FID_FILE; - err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf); - v9fs_create_post_fstat(s, vs, err); - - return; - -out: - v9fs_post_create(s, vs, err); - -} - -static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err) -{ - - if (err == 0 || errno != ENOENT) { - err = -errno; - goto out; - } - - if (vs->perm & P9_STAT_MODE_DIR) { - err = v9fs_do_mkdir(s, vs->fullname.data, vs->perm & 0777, - vs->fidp->uid, -1); - v9fs_create_post_mkdir(s, vs, err); - } else if (vs->perm & P9_STAT_MODE_SYMLINK) { - err = v9fs_do_symlink(s, vs->fidp, vs->extension.data, - vs->fullname.data, -1); - v9fs_create_post_perms(s, vs, err); - } else if (vs->perm & P9_STAT_MODE_LINK) { - int32_t nfid = atoi(vs->extension.data); - V9fsFidState *nfidp = lookup_fid(s, nfid); - if (nfidp == NULL) { - err = -errno; - v9fs_post_create(s, vs, err); - } - err = v9fs_do_link(s, &nfidp->path, &vs->fullname); - v9fs_create_post_perms(s, vs, err); - } else if (vs->perm & P9_STAT_MODE_DEVICE) { - char ctype; - uint32_t major, minor; - mode_t nmode = 0; - - if (sscanf(vs->extension.data, "%c %u %u", &ctype, &major, - &minor) != 3) { - err = -errno; - v9fs_post_create(s, vs, err); - } - - switch (ctype) { - case 'c': - nmode = S_IFCHR; - break; - case 'b': - nmode = S_IFBLK; - break; - default: - err = -EIO; - v9fs_post_create(s, vs, err); - } - - nmode |= vs->perm & 0777; - err = v9fs_do_mknod(s, vs->fullname.data, nmode, - makedev(major, minor), vs->fidp->uid, -1); - v9fs_create_post_perms(s, vs, err); - } else if (vs->perm & P9_STAT_MODE_NAMED_PIPE) { - err = v9fs_do_mknod(s, vs->fullname.data, S_IFIFO | (vs->perm & 0777), - 0, vs->fidp->uid, -1); - v9fs_post_create(s, vs, err); - } else if (vs->perm & P9_STAT_MODE_SOCKET) { - err = v9fs_do_mknod(s, vs->fullname.data, S_IFSOCK | (vs->perm & 0777), - 0, vs->fidp->uid, -1); - v9fs_post_create(s, vs, err); - } else { - vs->fidp->fs.fd = v9fs_do_open2(s, vs->fullname.data, vs->fidp->uid, - -1, omode_to_uflags(vs->mode)|O_CREAT, vs->perm); - - v9fs_create_post_open2(s, vs, err); - } - - return; - -out: - v9fs_post_create(s, vs, err); -} - -static void v9fs_create(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsCreateState *vs; - int err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - v9fs_string_init(&vs->fullname); - - pdu_unmarshal(vs->pdu, vs->offset, "dsdbs", &fid, &vs->name, - &vs->perm, &vs->mode, &vs->extension); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -EINVAL; - goto out; - } - - v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->fidp->path.data, - vs->name.data); - - err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf); - v9fs_create_post_lstat(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - v9fs_string_free(&vs->extension); - qemu_free(vs); -} - -static void v9fs_post_symlink(V9fsState *s, V9fsSymlinkState *vs, int err) -{ - if (err == 0) { - stat_to_qid(&vs->stbuf, &vs->qid); - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid); - err = vs->offset; - } else { - err = -errno; - } - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - v9fs_string_free(&vs->symname); - v9fs_string_free(&vs->fullname); - qemu_free(vs); -} - -static void v9fs_symlink_post_do_symlink(V9fsState *s, V9fsSymlinkState *vs, - int err) -{ - if (err) { - goto out; - } - err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf); -out: - v9fs_post_symlink(s, vs, err); -} - -static void v9fs_symlink(V9fsState *s, V9fsPDU *pdu) -{ - int32_t dfid; - V9fsSymlinkState *vs; - int err = 0; - gid_t gid; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - v9fs_string_init(&vs->fullname); - - pdu_unmarshal(vs->pdu, vs->offset, "dssd", &dfid, &vs->name, - &vs->symname, &gid); - - vs->dfidp = lookup_fid(s, dfid); - if (vs->dfidp == NULL) { - err = -EINVAL; - goto out; - } - - v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->dfidp->path.data, - vs->name.data); - err = v9fs_do_symlink(s, vs->dfidp, vs->symname.data, - vs->fullname.data, gid); - v9fs_symlink_post_do_symlink(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - v9fs_string_free(&vs->symname); - qemu_free(vs); -} - -static void v9fs_flush(V9fsState *s, V9fsPDU *pdu) -{ - /* A nop call with no return */ - complete_pdu(s, pdu, 7); -} - -static void v9fs_link(V9fsState *s, V9fsPDU *pdu) -{ - int32_t dfid, oldfid; - V9fsFidState *dfidp, *oldfidp; - V9fsString name, fullname; - size_t offset = 7; - int err = 0; - - v9fs_string_init(&fullname); - - pdu_unmarshal(pdu, offset, "dds", &dfid, &oldfid, &name); - - dfidp = lookup_fid(s, dfid); - if (dfidp == NULL) { - err = -errno; - goto out; - } - - oldfidp = lookup_fid(s, oldfid); - if (oldfidp == NULL) { - err = -errno; - goto out; - } - - v9fs_string_sprintf(&fullname, "%s/%s", dfidp->path.data, name.data); - err = offset; - err = v9fs_do_link(s, &oldfidp->path, &fullname); - if (err) { - err = -errno; - } - v9fs_string_free(&fullname); - -out: - v9fs_string_free(&name); - complete_pdu(s, pdu, err); -} - -static void v9fs_remove_post_remove(V9fsState *s, V9fsRemoveState *vs, - int err) -{ - if (err < 0) { - err = -errno; - } else { - err = vs->offset; - } - - /* For TREMOVE we need to clunk the fid even on failed remove */ - free_fid(s, vs->fidp->fid); - - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_remove(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsRemoveState *vs; - int err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - pdu_unmarshal(vs->pdu, vs->offset, "d", &fid); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -EINVAL; - goto out; - } - - err = v9fs_do_remove(s, &vs->fidp->path); - v9fs_remove_post_remove(s, vs, err); - return; - -out: - complete_pdu(s, pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err) -{ - if (err < 0) { - goto out; - } - - err = vs->offset; - -out: - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat_post_rename(V9fsState *s, V9fsWstatState *vs, int err) -{ - if (err < 0) { - goto out; - } - if (vs->v9stat.length != -1) { - if (v9fs_do_truncate(s, &vs->fidp->path, vs->v9stat.length) < 0) { - err = -errno; - } - } - v9fs_wstat_post_truncate(s, vs, err); - return; - -out: - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static int v9fs_complete_rename(V9fsState *s, V9fsRenameState *vs) -{ - int err = 0; - char *old_name, *new_name; - char *end; - - if (vs->newdirfid != -1) { - V9fsFidState *dirfidp; - dirfidp = lookup_fid(s, vs->newdirfid); - - if (dirfidp == NULL) { - err = -ENOENT; - goto out; - } - - BUG_ON(dirfidp->fid_type != P9_FID_NONE); - - new_name = qemu_mallocz(dirfidp->path.size + vs->name.size + 2); - - strcpy(new_name, dirfidp->path.data); - strcat(new_name, "/"); - strcat(new_name + dirfidp->path.size, vs->name.data); - } else { - old_name = vs->fidp->path.data; - end = strrchr(old_name, '/'); - if (end) { - end++; - } else { - end = old_name; - } - new_name = qemu_mallocz(end - old_name + vs->name.size + 1); - - strncat(new_name, old_name, end - old_name); - strncat(new_name + (end - old_name), vs->name.data, vs->name.size); - } - - v9fs_string_free(&vs->name); - vs->name.data = qemu_strdup(new_name); - vs->name.size = strlen(new_name); - - if (strcmp(new_name, vs->fidp->path.data) != 0) { - if (v9fs_do_rename(s, &vs->fidp->path, &vs->name)) { - err = -errno; - } else { - V9fsFidState *fidp; - /* - * Fixup fid's pointing to the old name to - * start pointing to the new name - */ - for (fidp = s->fid_list; fidp; fidp = fidp->next) { - if (vs->fidp == fidp) { - /* - * we replace name of this fid towards the end - * so that our below strcmp will work - */ - continue; - } - if (!strncmp(vs->fidp->path.data, fidp->path.data, - strlen(vs->fidp->path.data))) { - /* replace the name */ - v9fs_fix_path(&fidp->path, &vs->name, - strlen(vs->fidp->path.data)); - } - } - v9fs_string_copy(&vs->fidp->path, &vs->name); - } - } -out: - v9fs_string_free(&vs->name); - return err; -} - -static void v9fs_rename_post_rename(V9fsState *s, V9fsRenameState *vs, int err) -{ - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat_post_chown(V9fsState *s, V9fsWstatState *vs, int err) -{ - if (err < 0) { - goto out; - } - - if (vs->v9stat.name.size != 0) { - V9fsRenameState *vr; - - vr = qemu_mallocz(sizeof(V9fsRenameState)); - vr->newdirfid = -1; - vr->pdu = vs->pdu; - vr->fidp = vs->fidp; - vr->offset = vs->offset; - vr->name.size = vs->v9stat.name.size; - vr->name.data = qemu_strdup(vs->v9stat.name.data); - - err = v9fs_complete_rename(s, vr); - qemu_free(vr); - } - v9fs_wstat_post_rename(s, vs, err); - return; - -out: - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_rename(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsRenameState *vs; - ssize_t err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - pdu_unmarshal(vs->pdu, vs->offset, "dds", &fid, &vs->newdirfid, &vs->name); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - BUG_ON(vs->fidp->fid_type != P9_FID_NONE); - - err = v9fs_complete_rename(s, vs); - v9fs_rename_post_rename(s, vs, err); - return; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat_post_utime(V9fsState *s, V9fsWstatState *vs, int err) -{ - if (err < 0) { - goto out; - } - - if (vs->v9stat.n_gid != -1 || vs->v9stat.n_uid != -1) { - if (v9fs_do_chown(s, &vs->fidp->path, vs->v9stat.n_uid, - vs->v9stat.n_gid)) { - err = -errno; - } - } - v9fs_wstat_post_chown(s, vs, err); - return; - -out: - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat_post_chmod(V9fsState *s, V9fsWstatState *vs, int err) -{ - if (err < 0) { - goto out; - } - - if (vs->v9stat.mtime != -1 || vs->v9stat.atime != -1) { - struct timespec times[2]; - if (vs->v9stat.atime != -1) { - times[0].tv_sec = vs->v9stat.atime; - times[0].tv_nsec = 0; - } else { - times[0].tv_nsec = UTIME_OMIT; - } - if (vs->v9stat.mtime != -1) { - times[1].tv_sec = vs->v9stat.mtime; - times[1].tv_nsec = 0; - } else { - times[1].tv_nsec = UTIME_OMIT; - } - - if (v9fs_do_utimensat(s, &vs->fidp->path, times)) { - err = -errno; - } - } - - v9fs_wstat_post_utime(s, vs, err); - return; - -out: - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat_post_fsync(V9fsState *s, V9fsWstatState *vs, int err) -{ - if (err == -1) { - err = -errno; - } - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err) -{ - uint32_t v9_mode; - - if (err == -1) { - err = -errno; - goto out; - } - - v9_mode = stat_to_v9mode(&vs->stbuf); - - if ((vs->v9stat.mode & P9_STAT_MODE_TYPE_BITS) != - (v9_mode & P9_STAT_MODE_TYPE_BITS)) { - /* Attempting to change the type */ - err = -EIO; - goto out; - } - - if (v9fs_do_chmod(s, &vs->fidp->path, v9mode_to_mode(vs->v9stat.mode, - &vs->v9stat.extension))) { - err = -errno; - } - v9fs_wstat_post_chmod(s, vs, err); - return; - -out: - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsWstatState *vs; - int err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - pdu_unmarshal(pdu, vs->offset, "dwS", &fid, &vs->unused, &vs->v9stat); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -EINVAL; - goto out; - } - - /* do we need to sync the file? */ - if (donttouch_stat(&vs->v9stat)) { - err = v9fs_do_fsync(s, vs->fidp->fs.fd, 0); - v9fs_wstat_post_fsync(s, vs, err); - return; - } - - if (vs->v9stat.mode != -1) { - err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); - v9fs_wstat_post_lstat(s, vs, err); - return; - } - - v9fs_wstat_post_chmod(s, vs, err); - return; - -out: - v9fs_stat_free(&vs->v9stat); - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_statfs_post_statfs(V9fsState *s, V9fsStatfsState *vs, int err) -{ - int32_t bsize_factor; - - if (err) { - err = -errno; - goto out; - } - - /* - * compute bsize factor based on host file system block size - * and client msize - */ - bsize_factor = (s->msize - P9_IOHDRSZ)/vs->stbuf.f_bsize; - if (!bsize_factor) { - bsize_factor = 1; - } - vs->v9statfs.f_type = vs->stbuf.f_type; - vs->v9statfs.f_bsize = vs->stbuf.f_bsize; - vs->v9statfs.f_bsize *= bsize_factor; - /* - * f_bsize is adjusted(multiplied) by bsize factor, so we need to - * adjust(divide) the number of blocks, free blocks and available - * blocks by bsize factor - */ - vs->v9statfs.f_blocks = vs->stbuf.f_blocks/bsize_factor; - vs->v9statfs.f_bfree = vs->stbuf.f_bfree/bsize_factor; - vs->v9statfs.f_bavail = vs->stbuf.f_bavail/bsize_factor; - vs->v9statfs.f_files = vs->stbuf.f_files; - vs->v9statfs.f_ffree = vs->stbuf.f_ffree; - vs->v9statfs.fsid_val = (unsigned int) vs->stbuf.f_fsid.__val[0] | - (unsigned long long)vs->stbuf.f_fsid.__val[1] << 32; - vs->v9statfs.f_namelen = vs->stbuf.f_namelen; - - vs->offset += pdu_marshal(vs->pdu, vs->offset, "ddqqqqqqd", - vs->v9statfs.f_type, vs->v9statfs.f_bsize, vs->v9statfs.f_blocks, - vs->v9statfs.f_bfree, vs->v9statfs.f_bavail, vs->v9statfs.f_files, - vs->v9statfs.f_ffree, vs->v9statfs.fsid_val, - vs->v9statfs.f_namelen); - -out: - complete_pdu(s, vs->pdu, vs->offset); - qemu_free(vs); -} - -static void v9fs_statfs(V9fsState *s, V9fsPDU *pdu) -{ - V9fsStatfsState *vs; - ssize_t err = 0; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - memset(&vs->v9statfs, 0, sizeof(vs->v9statfs)); - - pdu_unmarshal(vs->pdu, vs->offset, "d", &vs->fid); - - vs->fidp = lookup_fid(s, vs->fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - err = v9fs_do_statfs(s, &vs->fidp->path, &vs->stbuf); - v9fs_statfs_post_statfs(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_mknod_post_lstat(V9fsState *s, V9fsMkState *vs, int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - stat_to_qid(&vs->stbuf, &vs->qid); - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->fullname); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_mknod_post_mknod(V9fsState *s, V9fsMkState *vs, int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf); - v9fs_mknod_post_lstat(s, vs, err); - return; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->fullname); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_mknod(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsMkState *vs; - int err = 0; - V9fsFidState *fidp; - gid_t gid; - int mode; - int major, minor; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - v9fs_string_init(&vs->fullname); - pdu_unmarshal(vs->pdu, vs->offset, "dsdddd", &fid, &vs->name, &mode, - &major, &minor, &gid); - - fidp = lookup_fid(s, fid); - if (fidp == NULL) { - err = -ENOENT; - goto out; - } - - v9fs_string_sprintf(&vs->fullname, "%s/%s", fidp->path.data, vs->name.data); - err = v9fs_do_mknod(s, vs->fullname.data, mode, makedev(major, minor), - fidp->uid, gid); - v9fs_mknod_post_mknod(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->fullname); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -/* - * Implement posix byte range locking code - * Server side handling of locking code is very simple, because 9p server in - * QEMU can handle only one client. And most of the lock handling - * (like conflict, merging) etc is done by the VFS layer itself, so no need to - * do any thing in * qemu 9p server side lock code path. - * So when a TLOCK request comes, always return success - */ - -static void v9fs_lock(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid, err = 0; - V9fsLockState *vs; - - vs = qemu_mallocz(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - vs->flock = qemu_malloc(sizeof(*vs->flock)); - pdu_unmarshal(vs->pdu, vs->offset, "dbdqqds", &fid, &vs->flock->type, - &vs->flock->flags, &vs->flock->start, &vs->flock->length, - &vs->flock->proc_id, &vs->flock->client_id); - - vs->status = P9_LOCK_ERROR; - - /* We support only block flag now (that too ignored currently) */ - if (vs->flock->flags & ~P9_LOCK_FLAGS_BLOCK) { - err = -EINVAL; - goto out; - } - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf); - if (err < 0) { - err = -errno; - goto out; - } - vs->status = P9_LOCK_SUCCESS; -out: - vs->offset += pdu_marshal(vs->pdu, vs->offset, "b", vs->status); - complete_pdu(s, vs->pdu, err); - qemu_free(vs->flock); - qemu_free(vs); -} - -/* - * When a TGETLOCK request comes, always return success because all lock - * handling is done by client's VFS layer. - */ - -static void v9fs_getlock(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid, err = 0; - V9fsGetlockState *vs; - - vs = qemu_mallocz(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - vs->glock = qemu_malloc(sizeof(*vs->glock)); - pdu_unmarshal(vs->pdu, vs->offset, "dbqqds", &fid, &vs->glock->type, - &vs->glock->start, &vs->glock->length, &vs->glock->proc_id, - &vs->glock->client_id); - - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf); - if (err < 0) { - err = -errno; - goto out; - } - vs->glock->type = F_UNLCK; - vs->offset += pdu_marshal(vs->pdu, vs->offset, "bqqds", vs->glock->type, - vs->glock->start, vs->glock->length, vs->glock->proc_id, - &vs->glock->client_id); -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs->glock); - qemu_free(vs); -} - -static void v9fs_mkdir_post_lstat(V9fsState *s, V9fsMkState *vs, int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - stat_to_qid(&vs->stbuf, &vs->qid); - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->fullname); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_mkdir_post_mkdir(V9fsState *s, V9fsMkState *vs, int err) -{ - if (err == -1) { - err = -errno; - goto out; - } - - err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf); - v9fs_mkdir_post_lstat(s, vs, err); - return; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->fullname); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_mkdir(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsMkState *vs; - int err = 0; - V9fsFidState *fidp; - gid_t gid; - int mode; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - v9fs_string_init(&vs->fullname); - pdu_unmarshal(vs->pdu, vs->offset, "dsdd", &fid, &vs->name, &mode, - &gid); - - fidp = lookup_fid(s, fid); - if (fidp == NULL) { - err = -ENOENT; - goto out; - } - - v9fs_string_sprintf(&vs->fullname, "%s/%s", fidp->path.data, vs->name.data); - err = v9fs_do_mkdir(s, vs->fullname.data, mode, fidp->uid, gid); - v9fs_mkdir_post_mkdir(s, vs, err); - return; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->fullname); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_post_xattr_getvalue(V9fsState *s, V9fsXattrState *vs, int err) -{ - - if (err < 0) { - err = -errno; - free_fid(s, vs->xattr_fidp->fid); - goto out; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "q", vs->size); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - qemu_free(vs); - return; -} - -static void v9fs_post_xattr_check(V9fsState *s, V9fsXattrState *vs, ssize_t err) -{ - if (err < 0) { - err = -errno; - free_fid(s, vs->xattr_fidp->fid); - goto out; - } - /* - * Read the xattr value - */ - vs->xattr_fidp->fs.xattr.len = vs->size; - vs->xattr_fidp->fid_type = P9_FID_XATTR; - vs->xattr_fidp->fs.xattr.copied_len = -1; - if (vs->size) { - vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size); - err = v9fs_do_lgetxattr(s, &vs->xattr_fidp->path, - &vs->name, vs->xattr_fidp->fs.xattr.value, - vs->xattr_fidp->fs.xattr.len); - } - v9fs_post_xattr_getvalue(s, vs, err); - return; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_post_lxattr_getvalue(V9fsState *s, - V9fsXattrState *vs, int err) -{ - if (err < 0) { - err = -errno; - free_fid(s, vs->xattr_fidp->fid); - goto out; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "q", vs->size); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - qemu_free(vs); - return; -} - -static void v9fs_post_lxattr_check(V9fsState *s, - V9fsXattrState *vs, ssize_t err) -{ - if (err < 0) { - err = -errno; - free_fid(s, vs->xattr_fidp->fid); - goto out; - } - /* - * Read the xattr value - */ - vs->xattr_fidp->fs.xattr.len = vs->size; - vs->xattr_fidp->fid_type = P9_FID_XATTR; - vs->xattr_fidp->fs.xattr.copied_len = -1; - if (vs->size) { - vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size); - err = v9fs_do_llistxattr(s, &vs->xattr_fidp->path, - vs->xattr_fidp->fs.xattr.value, - vs->xattr_fidp->fs.xattr.len); - } - v9fs_post_lxattr_getvalue(s, vs, err); - return; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_xattrwalk(V9fsState *s, V9fsPDU *pdu) -{ - ssize_t err = 0; - V9fsXattrState *vs; - int32_t fid, newfid; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - pdu_unmarshal(vs->pdu, vs->offset, "dds", &fid, &newfid, &vs->name); - vs->file_fidp = lookup_fid(s, fid); - if (vs->file_fidp == NULL) { - err = -ENOENT; - goto out; - } - - vs->xattr_fidp = alloc_fid(s, newfid); - if (vs->xattr_fidp == NULL) { - err = -EINVAL; - goto out; - } - - v9fs_string_copy(&vs->xattr_fidp->path, &vs->file_fidp->path); - if (vs->name.data[0] == 0) { - /* - * listxattr request. Get the size first - */ - vs->size = v9fs_do_llistxattr(s, &vs->xattr_fidp->path, - NULL, 0); - if (vs->size < 0) { - err = vs->size; - } - v9fs_post_lxattr_check(s, vs, err); - return; - } else { - /* - * specific xattr fid. We check for xattr - * presence also collect the xattr size - */ - vs->size = v9fs_do_lgetxattr(s, &vs->xattr_fidp->path, - &vs->name, NULL, 0); - if (vs->size < 0) { - err = vs->size; - } - v9fs_post_xattr_check(s, vs, err); - return; - } -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_xattrcreate(V9fsState *s, V9fsPDU *pdu) -{ - int flags; - int32_t fid; - ssize_t err = 0; - V9fsXattrState *vs; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - pdu_unmarshal(vs->pdu, vs->offset, "dsqd", - &fid, &vs->name, &vs->size, &flags); - - vs->file_fidp = lookup_fid(s, fid); - if (vs->file_fidp == NULL) { - err = -EINVAL; - goto out; - } - - /* Make the file fid point to xattr */ - vs->xattr_fidp = vs->file_fidp; - vs->xattr_fidp->fid_type = P9_FID_XATTR; - vs->xattr_fidp->fs.xattr.copied_len = 0; - vs->xattr_fidp->fs.xattr.len = vs->size; - vs->xattr_fidp->fs.xattr.flags = flags; - v9fs_string_init(&vs->xattr_fidp->fs.xattr.name); - v9fs_string_copy(&vs->xattr_fidp->fs.xattr.name, &vs->name); - if (vs->size) - vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size); - else - vs->xattr_fidp->fs.xattr.value = NULL; - -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->name); - qemu_free(vs); -} - -static void v9fs_readlink_post_readlink(V9fsState *s, V9fsReadLinkState *vs, - int err) -{ - if (err < 0) { - err = -errno; - goto out; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "s", &vs->target); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - v9fs_string_free(&vs->target); - qemu_free(vs); -} - -static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu) -{ - int32_t fid; - V9fsReadLinkState *vs; - int err = 0; - V9fsFidState *fidp; - - vs = qemu_malloc(sizeof(*vs)); - vs->pdu = pdu; - vs->offset = 7; - - pdu_unmarshal(vs->pdu, vs->offset, "d", &fid); - - fidp = lookup_fid(s, fid); - if (fidp == NULL) { - err = -ENOENT; - goto out; - } - - v9fs_string_init(&vs->target); - err = v9fs_do_readlink(s, &fidp->path, &vs->target); - v9fs_readlink_post_readlink(s, vs, err); - return; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu); - -static pdu_handler_t *pdu_handlers[] = { - [P9_TREADDIR] = v9fs_readdir, - [P9_TSTATFS] = v9fs_statfs, - [P9_TGETATTR] = v9fs_getattr, - [P9_TSETATTR] = v9fs_setattr, - [P9_TXATTRWALK] = v9fs_xattrwalk, - [P9_TXATTRCREATE] = v9fs_xattrcreate, - [P9_TMKNOD] = v9fs_mknod, - [P9_TRENAME] = v9fs_rename, - [P9_TLOCK] = v9fs_lock, - [P9_TGETLOCK] = v9fs_getlock, - [P9_TREADLINK] = v9fs_readlink, - [P9_TMKDIR] = v9fs_mkdir, - [P9_TVERSION] = v9fs_version, - [P9_TLOPEN] = v9fs_open, - [P9_TATTACH] = v9fs_attach, - [P9_TSTAT] = v9fs_stat, - [P9_TWALK] = v9fs_walk, - [P9_TCLUNK] = v9fs_clunk, - [P9_TFSYNC] = v9fs_fsync, - [P9_TOPEN] = v9fs_open, - [P9_TREAD] = v9fs_read, -#if 0 - [P9_TAUTH] = v9fs_auth, -#endif - [P9_TFLUSH] = v9fs_flush, - [P9_TLINK] = v9fs_link, - [P9_TSYMLINK] = v9fs_symlink, - [P9_TCREATE] = v9fs_create, - [P9_TLCREATE] = v9fs_lcreate, - [P9_TWRITE] = v9fs_write, - [P9_TWSTAT] = v9fs_wstat, - [P9_TREMOVE] = v9fs_remove, -}; - -static void submit_pdu(V9fsState *s, V9fsPDU *pdu) -{ - pdu_handler_t *handler; - - if (debug_9p_pdu) { - pprint_pdu(pdu); - } - - BUG_ON(pdu->id >= ARRAY_SIZE(pdu_handlers)); - - handler = pdu_handlers[pdu->id]; - BUG_ON(handler == NULL); - - handler(s, pdu); -} - -static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq) -{ - V9fsState *s = (V9fsState *)vdev; - V9fsPDU *pdu; - ssize_t len; - - while ((pdu = alloc_pdu(s)) && - (len = virtqueue_pop(vq, &pdu->elem)) != 0) { - uint8_t *ptr; - - BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0); - BUG_ON(pdu->elem.out_sg[0].iov_len < 7); - - ptr = pdu->elem.out_sg[0].iov_base; - - memcpy(&pdu->size, ptr, 4); - pdu->id = ptr[4]; - memcpy(&pdu->tag, ptr + 5, 2); - - submit_pdu(s, pdu); - } - - free_pdu(s, pdu); -} - -static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features) -{ - features |= 1 << VIRTIO_9P_MOUNT_TAG; - return features; -} - -static V9fsState *to_virtio_9p(VirtIODevice *vdev) -{ - return (V9fsState *)vdev; -} - -static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config) -{ - struct virtio_9p_config *cfg; - V9fsState *s = to_virtio_9p(vdev); - - cfg = qemu_mallocz(sizeof(struct virtio_9p_config) + - s->tag_len); - stw_raw(&cfg->tag_len, s->tag_len); - memcpy(cfg->tag, s->tag, s->tag_len); - memcpy(config, cfg, s->config_size); - qemu_free(cfg); -} - -VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf) - { - V9fsState *s; - int i, len; - struct stat stat; - FsTypeEntry *fse; - - - s = (V9fsState *)virtio_common_init("virtio-9p", - VIRTIO_ID_9P, - sizeof(struct virtio_9p_config)+ - MAX_TAG_LEN, - sizeof(V9fsState)); - - /* initialize pdu allocator */ - QLIST_INIT(&s->free_list); - for (i = 0; i < (MAX_REQ - 1); i++) { - QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next); - } - - s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output); - - fse = get_fsdev_fsentry(conf->fsdev_id); - - if (!fse) { - /* We don't have a fsdev identified by fsdev_id */ - fprintf(stderr, "Virtio-9p device couldn't find fsdev with the " - "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL"); - exit(1); - } - - if (!fse->path || !conf->tag) { - /* we haven't specified a mount_tag or the path */ - fprintf(stderr, "fsdev with id %s needs path " - "and Virtio-9p device needs mount_tag arguments\n", - conf->fsdev_id); - exit(1); - } - - if (!strcmp(fse->security_model, "passthrough")) { - /* Files on the Fileserver set to client user credentials */ - s->ctx.fs_sm = SM_PASSTHROUGH; - s->ctx.xops = passthrough_xattr_ops; - } else if (!strcmp(fse->security_model, "mapped")) { - /* Files on the fileserver are set to QEMU credentials. - * Client user credentials are saved in extended attributes. - */ - s->ctx.fs_sm = SM_MAPPED; - s->ctx.xops = mapped_xattr_ops; - } else if (!strcmp(fse->security_model, "none")) { - /* - * Files on the fileserver are set to QEMU credentials. - */ - s->ctx.fs_sm = SM_NONE; - s->ctx.xops = none_xattr_ops; - } else { - fprintf(stderr, "Default to security_model=none. You may want" - " enable advanced security model using " - "security option:\n\t security_model=passthrough \n\t " - "security_model=mapped\n"); - s->ctx.fs_sm = SM_NONE; - s->ctx.xops = none_xattr_ops; - } - - if (lstat(fse->path, &stat)) { - fprintf(stderr, "share path %s does not exist\n", fse->path); - exit(1); - } else if (!S_ISDIR(stat.st_mode)) { - fprintf(stderr, "share path %s is not a directory \n", fse->path); - exit(1); - } - - s->ctx.fs_root = qemu_strdup(fse->path); - len = strlen(conf->tag); - if (len > MAX_TAG_LEN) { - len = MAX_TAG_LEN; - } - /* s->tag is non-NULL terminated string */ - s->tag = qemu_malloc(len); - memcpy(s->tag, conf->tag, len); - s->tag_len = len; - s->ctx.uid = -1; - - s->ops = fse->ops; - s->vdev.get_features = virtio_9p_get_features; - s->config_size = sizeof(struct virtio_9p_config) + - s->tag_len; - s->vdev.get_config = virtio_9p_get_config; - - return &s->vdev; -} diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h deleted file mode 100644 index 2ae4ce7..0000000 --- a/hw/virtio-9p.h +++ /dev/null @@ -1,507 +0,0 @@ -#ifndef _QEMU_VIRTIO_9P_H -#define _QEMU_VIRTIO_9P_H - -#include -#include -#include -#include - -#include "file-op-9p.h" - -/* The feature bitmap for virtio 9P */ -/* The mount point is specified in a config variable */ -#define VIRTIO_9P_MOUNT_TAG 0 - -enum { - P9_TLERROR = 6, - P9_RLERROR, - P9_TSTATFS = 8, - P9_RSTATFS, - P9_TLOPEN = 12, - P9_RLOPEN, - P9_TLCREATE = 14, - P9_RLCREATE, - P9_TSYMLINK = 16, - P9_RSYMLINK, - P9_TMKNOD = 18, - P9_RMKNOD, - P9_TRENAME = 20, - P9_RRENAME, - P9_TREADLINK = 22, - P9_RREADLINK, - P9_TGETATTR = 24, - P9_RGETATTR, - P9_TSETATTR = 26, - P9_RSETATTR, - P9_TXATTRWALK = 30, - P9_RXATTRWALK, - P9_TXATTRCREATE = 32, - P9_RXATTRCREATE, - P9_TREADDIR = 40, - P9_RREADDIR, - P9_TFSYNC = 50, - P9_RFSYNC, - P9_TLOCK = 52, - P9_RLOCK, - P9_TGETLOCK = 54, - P9_RGETLOCK, - P9_TLINK = 70, - P9_RLINK, - P9_TMKDIR = 72, - P9_RMKDIR, - P9_TVERSION = 100, - P9_RVERSION, - P9_TAUTH = 102, - P9_RAUTH, - P9_TATTACH = 104, - P9_RATTACH, - P9_TERROR = 106, - P9_RERROR, - P9_TFLUSH = 108, - P9_RFLUSH, - P9_TWALK = 110, - P9_RWALK, - P9_TOPEN = 112, - P9_ROPEN, - P9_TCREATE = 114, - P9_RCREATE, - P9_TREAD = 116, - P9_RREAD, - P9_TWRITE = 118, - P9_RWRITE, - P9_TCLUNK = 120, - P9_RCLUNK, - P9_TREMOVE = 122, - P9_RREMOVE, - P9_TSTAT = 124, - P9_RSTAT, - P9_TWSTAT = 126, - P9_RWSTAT, -}; - - -/* qid.types */ -enum { - P9_QTDIR = 0x80, - P9_QTAPPEND = 0x40, - P9_QTEXCL = 0x20, - P9_QTMOUNT = 0x10, - P9_QTAUTH = 0x08, - P9_QTTMP = 0x04, - P9_QTSYMLINK = 0x02, - P9_QTLINK = 0x01, - P9_QTFILE = 0x00, -}; - -enum p9_proto_version { - V9FS_PROTO_2000U = 0x01, - V9FS_PROTO_2000L = 0x02, -}; - -#define P9_NOTAG (u16)(~0) -#define P9_NOFID (u32)(~0) -#define P9_MAXWELEM 16 - -/* - * ample room for Twrite/Rread header - * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4] - */ -#define P9_IOHDRSZ 24 - -typedef struct V9fsPDU V9fsPDU; - -struct V9fsPDU -{ - uint32_t size; - uint16_t tag; - uint8_t id; - VirtQueueElement elem; - QLIST_ENTRY(V9fsPDU) next; -}; - - -/* FIXME - * 1) change user needs to set groups and stuff - */ - -/* from Linux's linux/virtio_9p.h */ - -/* The ID for virtio console */ -#define VIRTIO_ID_9P 9 -#define MAX_REQ 128 -#define MAX_TAG_LEN 32 - -#define BUG_ON(cond) assert(!(cond)) - -typedef struct V9fsFidState V9fsFidState; - -typedef struct V9fsString -{ - int16_t size; - char *data; -} V9fsString; - -typedef struct V9fsQID -{ - int8_t type; - int32_t version; - int64_t path; -} V9fsQID; - -typedef struct V9fsStat -{ - int16_t size; - int16_t type; - int32_t dev; - V9fsQID qid; - int32_t mode; - int32_t atime; - int32_t mtime; - int64_t length; - V9fsString name; - V9fsString uid; - V9fsString gid; - V9fsString muid; - /* 9p2000.u */ - V9fsString extension; - int32_t n_uid; - int32_t n_gid; - int32_t n_muid; -} V9fsStat; - -enum { - P9_FID_NONE = 0, - P9_FID_FILE, - P9_FID_DIR, - P9_FID_XATTR, -}; - -typedef struct V9fsXattr -{ - int64_t copied_len; - int64_t len; - void *value; - V9fsString name; - int flags; -} V9fsXattr; - -struct V9fsFidState -{ - int fid_type; - int32_t fid; - V9fsString path; - union { - int fd; - DIR *dir; - V9fsXattr xattr; - } fs; - uid_t uid; - V9fsFidState *next; -}; - -typedef struct V9fsState -{ - VirtIODevice vdev; - VirtQueue *vq; - V9fsPDU pdus[MAX_REQ]; - QLIST_HEAD(, V9fsPDU) free_list; - V9fsFidState *fid_list; - FileOperations *ops; - FsContext ctx; - uint16_t tag_len; - uint8_t *tag; - size_t config_size; - enum p9_proto_version proto_version; - int32_t msize; -} V9fsState; - -typedef struct V9fsCreateState { - V9fsPDU *pdu; - size_t offset; - V9fsFidState *fidp; - V9fsQID qid; - int32_t perm; - int8_t mode; - struct stat stbuf; - V9fsString name; - V9fsString extension; - V9fsString fullname; - int iounit; -} V9fsCreateState; - -typedef struct V9fsLcreateState { - V9fsPDU *pdu; - size_t offset; - V9fsFidState *fidp; - V9fsQID qid; - int32_t iounit; - struct stat stbuf; - V9fsString name; - V9fsString fullname; -} V9fsLcreateState; - -typedef struct V9fsStatState { - V9fsPDU *pdu; - size_t offset; - V9fsStat v9stat; - V9fsFidState *fidp; - struct stat stbuf; -} V9fsStatState; - -typedef struct V9fsStatDotl { - uint64_t st_result_mask; - V9fsQID qid; - uint32_t st_mode; - uint32_t st_uid; - uint32_t st_gid; - uint64_t st_nlink; - uint64_t st_rdev; - uint64_t st_size; - uint64_t st_blksize; - uint64_t st_blocks; - uint64_t st_atime_sec; - uint64_t st_atime_nsec; - uint64_t st_mtime_sec; - uint64_t st_mtime_nsec; - uint64_t st_ctime_sec; - uint64_t st_ctime_nsec; - uint64_t st_btime_sec; - uint64_t st_btime_nsec; - uint64_t st_gen; - uint64_t st_data_version; -} V9fsStatDotl; - -typedef struct V9fsStatStateDotl { - V9fsPDU *pdu; - size_t offset; - V9fsStatDotl v9stat_dotl; - struct stat stbuf; -} V9fsStatStateDotl; - - -typedef struct V9fsWalkState { - V9fsPDU *pdu; - size_t offset; - int16_t nwnames; - int name_idx; - V9fsQID *qids; - V9fsFidState *fidp; - V9fsFidState *newfidp; - V9fsString path; - V9fsString *wnames; - struct stat stbuf; -} V9fsWalkState; - -typedef struct V9fsOpenState { - V9fsPDU *pdu; - size_t offset; - int32_t mode; - V9fsFidState *fidp; - V9fsQID qid; - struct stat stbuf; - int iounit; -} V9fsOpenState; - -typedef struct V9fsReadState { - V9fsPDU *pdu; - size_t offset; - int32_t count; - int32_t total; - int64_t off; - V9fsFidState *fidp; - struct iovec iov[128]; /* FIXME: bad, bad, bad */ - struct iovec *sg; - off_t dir_pos; - struct dirent *dent; - struct stat stbuf; - V9fsString name; - V9fsStat v9stat; - int32_t len; - int32_t cnt; - int32_t max_count; -} V9fsReadState; - -typedef struct V9fsWriteState { - V9fsPDU *pdu; - size_t offset; - int32_t len; - int32_t count; - int32_t total; - int64_t off; - V9fsFidState *fidp; - struct iovec iov[128]; /* FIXME: bad, bad, bad */ - struct iovec *sg; - int cnt; -} V9fsWriteState; - -typedef struct V9fsRemoveState { - V9fsPDU *pdu; - size_t offset; - V9fsFidState *fidp; -} V9fsRemoveState; - -typedef struct V9fsWstatState -{ - V9fsPDU *pdu; - size_t offset; - int16_t unused; - V9fsStat v9stat; - V9fsFidState *fidp; - struct stat stbuf; -} V9fsWstatState; - -typedef struct V9fsSymlinkState -{ - V9fsPDU *pdu; - size_t offset; - V9fsString name; - V9fsString symname; - V9fsString fullname; - V9fsFidState *dfidp; - V9fsQID qid; - struct stat stbuf; -} V9fsSymlinkState; - -typedef struct V9fsIattr -{ - int32_t valid; - int32_t mode; - int32_t uid; - int32_t gid; - int64_t size; - int64_t atime_sec; - int64_t atime_nsec; - int64_t mtime_sec; - int64_t mtime_nsec; -} V9fsIattr; - -typedef struct V9fsSetattrState -{ - V9fsPDU *pdu; - size_t offset; - V9fsIattr v9iattr; - V9fsFidState *fidp; -} V9fsSetattrState; - -struct virtio_9p_config -{ - /* number of characters in tag */ - uint16_t tag_len; - /* Variable size tag name */ - uint8_t tag[0]; -} __attribute__((packed)); - -typedef struct V9fsStatfs -{ - uint32_t f_type; - uint32_t f_bsize; - uint64_t f_blocks; - uint64_t f_bfree; - uint64_t f_bavail; - uint64_t f_files; - uint64_t f_ffree; - uint64_t fsid_val; - uint32_t f_namelen; -} V9fsStatfs; - -typedef struct V9fsStatfsState { - V9fsPDU *pdu; - size_t offset; - int32_t fid; - V9fsStatfs v9statfs; - V9fsFidState *fidp; - struct statfs stbuf; -} V9fsStatfsState; - -typedef struct V9fsMkState { - V9fsPDU *pdu; - size_t offset; - V9fsQID qid; - struct stat stbuf; - V9fsString name; - V9fsString fullname; -} V9fsMkState; - -typedef struct V9fsRenameState { - V9fsPDU *pdu; - V9fsFidState *fidp; - size_t offset; - int32_t newdirfid; - V9fsString name; -} V9fsRenameState; - -typedef struct V9fsXattrState -{ - V9fsPDU *pdu; - size_t offset; - V9fsFidState *file_fidp; - V9fsFidState *xattr_fidp; - V9fsString name; - int64_t size; - int flags; - void *value; -} V9fsXattrState; - -#define P9_LOCK_SUCCESS 0 -#define P9_LOCK_BLOCKED 1 -#define P9_LOCK_ERROR 2 -#define P9_LOCK_GRACE 3 - -#define P9_LOCK_FLAGS_BLOCK 1 -#define P9_LOCK_FLAGS_RECLAIM 2 - -typedef struct V9fsFlock -{ - uint8_t type; - uint32_t flags; - uint64_t start; /* absolute offset */ - uint64_t length; - uint32_t proc_id; - V9fsString client_id; -} V9fsFlock; - -typedef struct V9fsLockState -{ - V9fsPDU *pdu; - size_t offset; - int8_t status; - struct stat stbuf; - V9fsFidState *fidp; - V9fsFlock *flock; -} V9fsLockState; - -typedef struct V9fsGetlock -{ - uint8_t type; - uint64_t start; /* absolute offset */ - uint64_t length; - uint32_t proc_id; - V9fsString client_id; -} V9fsGetlock; - -typedef struct V9fsGetlockState -{ - V9fsPDU *pdu; - size_t offset; - struct stat stbuf; - V9fsFidState *fidp; - V9fsGetlock *glock; -} V9fsGetlockState; - -typedef struct V9fsReadLinkState -{ - V9fsPDU *pdu; - size_t offset; - V9fsString target; -} V9fsReadLinkState; - -size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count, - size_t offset, size_t size, int pack); - -static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count, - size_t offset, size_t size) -{ - return pdu_packunpack(dst, sg, sg_count, offset, size, 0); -} - -#endif diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c index 8adddea..e24a2bf 100644 --- a/hw/virtio-balloon.c +++ b/hw/virtio-balloon.c @@ -1,7 +1,9 @@ /* - * Virtio Block Device + * Virtio Balloon Device * * Copyright IBM, Corp. 2008 + * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2011 Amit Shah * * Authors: * Anthony Liguori @@ -15,24 +17,15 @@ #include "qemu-common.h" #include "virtio.h" #include "pc.h" -#include "sysemu.h" #include "cpu.h" -#include "monitor.h" #include "balloon.h" #include "virtio-balloon.h" #include "kvm.h" -#include "qlist.h" -#include "qint.h" -#include "qstring.h" #if defined(__linux__) #include #endif -/* Disable guest-provided stats by now (https://bugzilla.redhat.com/show_bug.cgi?id=623903) */ -#define ENABLE_GUEST_STATS 0 - - typedef struct VirtIOBalloon { VirtIODevice vdev; @@ -42,8 +35,7 @@ typedef struct VirtIOBalloon uint64_t stats[VIRTIO_BALLOON_S_NR]; VirtQueueElement stats_vq_elem; size_t stats_vq_offset; - MonitorCompletion *stats_callback; - void *stats_opaque_callback_data; + DeviceState *qdev; } VirtIOBalloon; static VirtIOBalloon *to_virtio_balloon(VirtIODevice *vdev) @@ -74,31 +66,6 @@ static inline void reset_stats(VirtIOBalloon *dev) for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1); } -static void stat_put(QDict *dict, const char *label, uint64_t val) -{ - if (val != -1) - qdict_put(dict, label, qint_from_int(val)); -} - -static QObject *get_stats_qobject(VirtIOBalloon *dev) -{ - QDict *dict = qdict_new(); - uint64_t actual = ram_size - ((uint64_t) dev->actual << - VIRTIO_BALLOON_PFN_SHIFT); - - stat_put(dict, "actual", actual); -#if ENABLE_GUEST_STATS - stat_put(dict, "mem_swapped_in", dev->stats[VIRTIO_BALLOON_S_SWAP_IN]); - stat_put(dict, "mem_swapped_out", dev->stats[VIRTIO_BALLOON_S_SWAP_OUT]); - stat_put(dict, "major_page_faults", dev->stats[VIRTIO_BALLOON_S_MAJFLT]); - stat_put(dict, "minor_page_faults", dev->stats[VIRTIO_BALLOON_S_MINFLT]); - stat_put(dict, "free_mem", dev->stats[VIRTIO_BALLOON_S_MEMFREE]); - stat_put(dict, "total_mem", dev->stats[VIRTIO_BALLOON_S_MEMTOT]); -#endif - - return QOBJECT(dict); -} - static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) { VirtIOBalloon *s = to_virtio_balloon(vdev); @@ -129,20 +96,6 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) } } -static void complete_stats_request(VirtIOBalloon *vb) -{ - QObject *stats; - - if (!vb->stats_opaque_callback_data) - return; - - stats = get_stats_qobject(vb); - vb->stats_callback(vb->stats_opaque_callback_data, stats); - qobject_decref(stats); - vb->stats_opaque_callback_data = NULL; - vb->stats_callback = NULL; -} - static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq) { VirtIOBalloon *s = DO_UPCAST(VirtIOBalloon, vdev, vdev); @@ -170,8 +123,6 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq) s->stats[tag] = val; } s->stats_vq_offset = offset; - - complete_stats_request(s); } static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data) @@ -191,7 +142,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev, VirtIOBalloon *dev = to_virtio_balloon(vdev); struct virtio_balloon_config config; memcpy(&config, config_data, 8); - dev->actual = config.actual; + dev->actual = le32_to_cpu(config.actual); } static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f) @@ -200,36 +151,45 @@ static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f) return f; } -static void virtio_balloon_to_target(void *opaque, ram_addr_t target, - MonitorCompletion cb, void *cb_data) +static void virtio_balloon_stat(void *opaque, BalloonInfo *info) { VirtIOBalloon *dev = opaque; - if (target > ram_size) - target = ram_size; +#if 0 + /* Disable guest-provided stats for now. For more details please check: + * https://bugzilla.redhat.com/show_bug.cgi?id=623903 + * + * If you do enable it (which is probably not going to happen as we + * need a new command for it), remember that you also need to fill the + * appropriate members of the BalloonInfo structure so that the stats + * are returned to the client. + */ + if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) { + virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset); + virtio_notify(&dev->vdev, dev->svq); + return; + } +#endif + + /* Stats are not supported. Clear out any stale values that might + * have been set by a more featureful guest kernel. + */ + reset_stats(dev); + + info->actual = ram_size - ((uint64_t) dev->actual << + VIRTIO_BALLOON_PFN_SHIFT); +} +static void virtio_balloon_to_target(void *opaque, ram_addr_t target) +{ + VirtIOBalloon *dev = opaque; + + if (target > ram_size) { + target = ram_size; + } if (target) { dev->num_pages = (ram_size - target) >> VIRTIO_BALLOON_PFN_SHIFT; virtio_notify_config(&dev->vdev); - } else { - /* For now, only allow one request at a time. This restriction can be - * removed later by queueing callback and data pairs. - */ - if (dev->stats_callback != NULL) { - return; - } - dev->stats_callback = cb; - dev->stats_opaque_callback_data = cb_data; - if (ENABLE_GUEST_STATS && (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ))) { - virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset); - virtio_notify(&dev->vdev, dev->svq); - } else { - /* Stats are not supported. Clear out any stale values that might - * have been set by a more featureful guest kernel. - */ - reset_stats(dev); - complete_stats_request(dev); - } } } @@ -260,6 +220,7 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id) VirtIODevice *virtio_balloon_init(DeviceState *dev) { VirtIOBalloon *s; + int ret; s = (VirtIOBalloon *)virtio_common_init("virtio-balloon", VIRTIO_ID_BALLOON, @@ -269,15 +230,31 @@ VirtIODevice *virtio_balloon_init(DeviceState *dev) s->vdev.set_config = virtio_balloon_set_config; s->vdev.get_features = virtio_balloon_get_features; + ret = qemu_add_balloon_handler(virtio_balloon_to_target, + virtio_balloon_stat, s); + if (ret < 0) { + virtio_cleanup(&s->vdev); + return NULL; + } + s->ivq = virtio_add_queue(&s->vdev, 128, virtio_balloon_handle_output); s->dvq = virtio_add_queue(&s->vdev, 128, virtio_balloon_handle_output); s->svq = virtio_add_queue(&s->vdev, 128, virtio_balloon_receive_stats); reset_stats(s); - qemu_add_balloon_handler(virtio_balloon_to_target, s); + s->qdev = dev; register_savevm(dev, "virtio-balloon", -1, 1, virtio_balloon_save, virtio_balloon_load, s); return &s->vdev; } + +void virtio_balloon_exit(VirtIODevice *vdev) +{ + VirtIOBalloon *s = DO_UPCAST(VirtIOBalloon, vdev, vdev); + + qemu_remove_balloon_handler(s); + unregister_savevm(s->qdev, "virtio-balloon", s); + virtio_cleanup(vdev); +} diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h index e20cf6b..73300dd 100644 --- a/hw/virtio-balloon.h +++ b/hw/virtio-balloon.h @@ -50,6 +50,6 @@ struct virtio_balloon_config typedef struct VirtIOBalloonStat { uint16_t tag; uint64_t val; -} __attribute__((packed)) VirtIOBalloonStat; +} QEMU_PACKED VirtIOBalloonStat; #endif diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 114c638..d6d1f87 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -11,11 +11,12 @@ * */ -#include +#include "qemu-common.h" #include "qemu-error.h" #include "trace.h" #include "blockdev.h" #include "virtio-blk.h" +#include "scsi-defs.h" #ifdef __linux__ # include #endif @@ -28,8 +29,8 @@ typedef struct VirtIOBlock void *rq; QEMUBH *bh; BlockConf *conf; + char *serial; unsigned short sector_mask; - char sn[BLOCK_SERIAL_STRLEN]; DeviceState *qdev; } VirtIOBlock; @@ -47,6 +48,7 @@ typedef struct VirtIOBlockReq struct virtio_scsi_inhdr *scsi; QEMUIOVector qiov; struct VirtIOBlockReq *next; + BlockAcctCookie acct; } VirtIOBlockReq; static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) @@ -58,8 +60,6 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) stb_p(&req->in->status, status); virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in)); virtio_notify(&s->vdev, s->vq); - - qemu_free(req); } static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, @@ -78,9 +78,12 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, req->next = s->rq; s->rq = req; bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); - vm_stop(0); + vm_stop(RUN_STATE_IO_ERROR); + bdrv_iostatus_set_err(s->bs, error); } else { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); + bdrv_acct_done(s->bs, &req->acct); + g_free(req); bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read); } @@ -100,6 +103,8 @@ static void virtio_blk_rw_complete(void *opaque, int ret) } virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + bdrv_acct_done(req->dev->bs, &req->acct); + g_free(req); } static void virtio_blk_flush_complete(void *opaque, int ret) @@ -113,11 +118,13 @@ static void virtio_blk_flush_complete(void *opaque, int ret) } virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + bdrv_acct_done(req->dev->bs, &req->acct); + g_free(req); } static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s) { - VirtIOBlockReq *req = qemu_malloc(sizeof(*req)); + VirtIOBlockReq *req = g_malloc(sizeof(*req)); req->dev = s; req->qiov.size = 0; req->next = NULL; @@ -130,7 +137,7 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s) if (req != NULL) { if (!virtqueue_pop(s->vq, &req->elem)) { - qemu_free(req); + g_free(req); return NULL; } } @@ -155,6 +162,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) */ if (req->elem.out_num < 2 || req->elem.in_num < 3) { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); + g_free(req); return; } @@ -163,6 +171,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) */ if (req->elem.out_num > 2 && req->elem.in_num > 3) { virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP); + g_free(req); return; } @@ -223,17 +232,32 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) status = VIRTIO_BLK_S_OK; } - stl_p(&req->scsi->errors, hdr.status); + /* + * From SCSI-Generic-HOWTO: "Some lower level drivers (e.g. ide-scsi) + * clear the masked_status field [hence status gets cleared too, see + * block/scsi_ioctl.c] even when a CHECK_CONDITION or COMMAND_TERMINATED + * status has occurred. However they do set DRIVER_SENSE in driver_status + * field. Also a (sb_len_wr > 0) indicates there is a sense buffer. + */ + if (hdr.status == 0 && hdr.sb_len_wr > 0) { + hdr.status = CHECK_CONDITION; + } + + stl_p(&req->scsi->errors, + hdr.status | (hdr.msg_status << 8) | + (hdr.host_status << 16) | (hdr.driver_status << 24)); stl_p(&req->scsi->residual, hdr.resid); stl_p(&req->scsi->sense_len, hdr.sb_len_wr); stl_p(&req->scsi->data_len, hdr.dxfer_len); virtio_blk_req_complete(req, status); + g_free(req); } #else static void virtio_blk_handle_scsi(VirtIOBlockReq *req) { virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP); + g_free(req); } #endif /* __linux__ */ @@ -266,6 +290,8 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb) { BlockDriverAIOCB *acb; + bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH); + /* * Make sure all outstanding writes are posted to the backing device. */ @@ -284,6 +310,8 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb) sector = ldq_p(&req->out->sector); + bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE); + trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512); if (sector & req->dev->sector_mask) { @@ -317,6 +345,8 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req) sector = ldq_p(&req->out->sector); + bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ); + if (sector & req->dev->sector_mask) { virtio_blk_rw_complete(req, -EIO); return; @@ -362,9 +392,15 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, } else if (type & VIRTIO_BLK_T_GET_ID) { VirtIOBlock *s = req->dev; - memcpy(req->elem.in_sg[0].iov_base, s->sn, - MIN(req->elem.in_sg[0].iov_len, sizeof(s->sn))); + /* + * NB: per existing s/n string convention the string is + * terminated by '\0' only when shorter than buffer. + */ + strncpy(req->elem.in_sg[0].iov_base, + s->serial ? s->serial : "", + MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES)); virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); + g_free(req); } else if (type & VIRTIO_BLK_T_OUT) { qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1], req->elem.out_num - 1); @@ -418,7 +454,8 @@ static void virtio_blk_dma_restart_bh(void *opaque) virtio_submit_multiwrite(s->bs, &mrb); } -static void virtio_blk_dma_restart_cb(void *opaque, int running, int reason) +static void virtio_blk_dma_restart_cb(void *opaque, int running, + RunState state) { VirtIOBlock *s = opaque; @@ -448,6 +485,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) struct virtio_blk_config blkcfg; uint64_t capacity; int cylinders, heads, secs; + int blk_size = s->conf->logical_block_size; bdrv_get_geometry(s->bs, &capacity); bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs); @@ -455,14 +493,14 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) stq_raw(&blkcfg.capacity, capacity); stl_raw(&blkcfg.seg_max, 128 - 2); stw_raw(&blkcfg.cylinders, cylinders); + stl_raw(&blkcfg.blk_size, blk_size); + stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size); + stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size); blkcfg.heads = heads; blkcfg.sectors = secs & ~s->sector_mask; - blkcfg.blk_size = s->conf->logical_block_size; blkcfg.size_max = 0; blkcfg.physical_block_exp = get_physical_block_exp(s->conf); blkcfg.alignment_offset = 0; - blkcfg.min_io_size = s->conf->min_io_size / blkcfg.blk_size; - blkcfg.opt_io_size = s->conf->opt_io_size / blkcfg.blk_size; memcpy(config, &blkcfg, sizeof(struct virtio_blk_config)); } @@ -522,16 +560,19 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) return 0; } -static void virtio_blk_change_cb(void *opaque, int reason) +static void virtio_blk_resize(void *opaque) { VirtIOBlock *s = opaque; - if (reason & CHANGE_SIZE) { - virtio_notify_config(&s->vdev); - } + virtio_notify_config(&s->vdev); } -VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf) +static const BlockDevOps virtio_block_ops = { + .resize_cb = virtio_blk_resize, +}; + +VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf, + char **serial) { VirtIOBlock *s; int cylinders, heads, secs; @@ -547,6 +588,14 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf) return NULL; } + if (!*serial) { + /* try to fall back to value set with legacy -drive serial=... */ + dinfo = drive_get_by_blockdev(conf->bs); + if (*dinfo->serial) { + *serial = strdup(dinfo->serial); + } + } + s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK, sizeof(struct virtio_blk_config), sizeof(VirtIOBlock)); @@ -556,26 +605,21 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf) s->vdev.reset = virtio_blk_reset; s->bs = conf->bs; s->conf = conf; + s->serial = *serial; s->rq = NULL; s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1; bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs); - /* NB: per existing s/n string convention the string is terminated - * by '\0' only when less than sizeof (s->sn) - */ - dinfo = drive_get_by_blockdev(s->bs); - strncpy(s->sn, dinfo->serial, sizeof (s->sn)); - s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output); qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s); s->qdev = dev; register_savevm(dev, "virtio-blk", virtio_blk_id++, 2, virtio_blk_save, virtio_blk_load, s); - bdrv_set_removable(s->bs, 0); - bdrv_set_change_cb(s->bs, virtio_blk_change_cb, s); - s->bs->buffer_alignment = conf->logical_block_size; + bdrv_set_dev_ops(s->bs, &virtio_block_ops, s); + bdrv_set_buffer_alignment(s->bs, conf->logical_block_size); + bdrv_iostatus_enable(s->bs); add_boot_device_path(conf->bootindex, dev, "/disk@0,0"); return &s->vdev; @@ -585,4 +629,5 @@ void virtio_blk_exit(VirtIODevice *vdev) { VirtIOBlock *s = to_virtio_blk(vdev); unregister_savevm(s->qdev, "virtio-blk", s); + virtio_cleanup(vdev); } diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h index fff46da..244dce4 100644 --- a/hw/virtio-blk.h +++ b/hw/virtio-blk.h @@ -34,6 +34,8 @@ #define VIRTIO_BLK_F_WCACHE 9 /* write cache enabled */ #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ +#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */ + struct virtio_blk_config { uint64_t capacity; @@ -47,7 +49,7 @@ struct virtio_blk_config uint8_t alignment_offset; uint16_t min_io_size; uint32_t opt_io_size; -} __attribute__((packed)); +} QEMU_PACKED; /* These two define direction. */ #define VIRTIO_BLK_T_IN 0 diff --git a/hw/virtio-console.c b/hw/virtio-console.c index 62624ec..d3351c8 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -11,6 +11,8 @@ */ #include "qemu-char.h" +#include "qemu-error.h" +#include "trace.h" #include "virtio-serial.h" typedef struct VirtConsole { @@ -23,8 +25,42 @@ typedef struct VirtConsole { static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); + ssize_t ret; + + ret = qemu_chr_fe_write(vcon->chr, buf, len); + trace_virtio_console_flush_buf(port->id, len, ret); + + if (ret < 0) { + /* + * Ideally we'd get a better error code than just -1, but + * that's what the chardev interface gives us right now. If + * we had a finer-grained message, like -EPIPE, we could close + * this connection. Absent such error messages, the most we + * can do is to return 0 here. + * + * This will prevent stray -1 values to go to + * virtio-serial-bus.c and cause abort()s in + * do_flush_queued_data(). + */ + ret = 0; + } + return ret; +} - return qemu_chr_write(vcon->chr, buf, len); +/* Callback function that's called when the guest opens the port */ +static void guest_open(VirtIOSerialPort *port) +{ + VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); + + qemu_chr_fe_open(vcon->chr); +} + +/* Callback function that's called when the guest closes the port */ +static void guest_close(VirtIOSerialPort *port) +{ + VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); + + qemu_chr_fe_close(vcon->chr); } /* Readiness of the guest to accept data on a port */ @@ -40,6 +76,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) { VirtConsole *vcon = opaque; + trace_virtio_console_chr_read(vcon->port.id, size); virtio_serial_write(&vcon->port, buf, size); } @@ -47,6 +84,7 @@ static void chr_event(void *opaque, int event) { VirtConsole *vcon = opaque; + trace_virtio_console_chr_event(vcon->port.id, event); switch (event) { case CHR_EVENT_OPENED: virtio_serial_open(&vcon->port); @@ -57,36 +95,38 @@ static void chr_event(void *opaque, int event) } } -static int generic_port_init(VirtConsole *vcon, VirtIOSerialDevice *dev) +static int virtconsole_initfn(VirtIOSerialPort *port) { - vcon->port.info = dev->info; + VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); + VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, + vcon->port.dev.info); + + if (port->id == 0 && !info->is_console) { + error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility."); + return -1; + } if (vcon->chr) { qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, vcon); - vcon->port.info->have_data = flush_buf; + info->have_data = flush_buf; + info->guest_open = guest_open; + info->guest_close = guest_close; } - return 0; -} - -/* Virtio Console Ports */ -static int virtconsole_initfn(VirtIOSerialDevice *dev) -{ - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); - VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); - port->is_console = true; - return generic_port_init(vcon, dev); + return 0; } -static int virtconsole_exitfn(VirtIOSerialDevice *dev) +static int virtconsole_exitfn(VirtIOSerialPort *port) { - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); if (vcon->chr) { - port->info->have_data = NULL; - qemu_chr_close(vcon->chr); + /* + * Instead of closing the chardev, free it so it can be used + * for other purposes. + */ + qemu_chr_add_handlers(vcon->chr, NULL, NULL, NULL, NULL); } return 0; @@ -95,13 +135,11 @@ static int virtconsole_exitfn(VirtIOSerialDevice *dev) static VirtIOSerialPortInfo virtconsole_info = { .qdev.name = "virtconsole", .qdev.size = sizeof(VirtConsole), + .is_console = true, .init = virtconsole_initfn, .exit = virtconsole_exitfn, .qdev.props = (Property[]) { - DEFINE_PROP_UINT8("is_console", VirtConsole, port.is_console, 1), - DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID), DEFINE_PROP_CHR("chardev", VirtConsole, chr), - DEFINE_PROP_STRING("name", VirtConsole, port.name), DEFINE_PROP_END_OF_LIST(), }, }; @@ -112,24 +150,13 @@ static void virtconsole_register(void) } device_init(virtconsole_register) -/* Generic Virtio Serial Ports */ -static int virtserialport_initfn(VirtIOSerialDevice *dev) -{ - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); - VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); - - return generic_port_init(vcon, dev); -} - static VirtIOSerialPortInfo virtserialport_info = { .qdev.name = "virtserialport", .qdev.size = sizeof(VirtConsole), - .init = virtserialport_initfn, + .init = virtconsole_initfn, .exit = virtconsole_exitfn, .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("nr", VirtConsole, port.id, VIRTIO_CONSOLE_BAD_ID), DEFINE_PROP_CHR("chardev", VirtConsole, chr), - DEFINE_PROP_STRING("name", VirtConsole, port.name), DEFINE_PROP_END_OF_LIST(), }, }; diff --git a/hw/virtio-gpi.c b/hw/virtio-gpi.c deleted file mode 100644 index f1503c8..0000000 --- a/hw/virtio-gpi.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Virtio general purpose interface - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: - * YeongKyoon Lee - * DongKyun Yun - * - * 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. - * - * Contributors: - * - S-Core Co., Ltd - * - */ - -#include "hw.h" -#include "virtio.h" -#include "qemu-log.h" -#include - -#include "tizen/src/debug_ch.h" -MULTI_DEBUG_CHANNEL(qemu, gpi); - -/* fixme: move to virtio-gpi.h */ -#define VIRTIO_ID_GPI 20 - -/* Enable debug messages. */ -//#define VIRTIO_GPI_DEBUG - -#if defined(VIRTIO_GPI_DEBUG) - -static int log_dump(char *buffer, int size) -{ - TRACE("buffer[%p] size[%d] \n", buffer, size); - - int i; - unsigned char *ptr = (unsigned char*)buffer; - - TRACE("DATA BEGIN -------------- \n"); - - for(i=0; i < size; i++) - { - TRACE("[%d] %02x(%c) ",i, ptr[i], ptr[i]); - } - - TRACE("DATA END -------------- \n"); - return 0; -} - -#else -#define log_dump(fmt, ...) ((void)0) -#endif - -int call_gpi(int pid, int call_num, char *in_args, int args_len, char *r_buffer, int r_length); - -#define SIZE_GPI_HEADER (4*4) - -typedef struct VirtIOGPI -{ - VirtIODevice vdev; - VirtQueue *vq; -} VirtIOGPI; - -static void virtio_gpi_handle(VirtIODevice *vdev, VirtQueue *vq) -{ - int i, ret = 0; - int pid, length, r_length, ftn_num; - char *buffer = NULL; - char *r_buffer = NULL; - char *ptr = NULL; - int *i_buffer = NULL; - - VirtQueueElement elem; - - while(virtqueue_pop(vq, &elem)) - { - pid = ((int*)elem.out_sg[0].iov_base)[0]; - length = ((int*)elem.out_sg[0].iov_base)[1]; - r_length = ((int*)elem.out_sg[0].iov_base)[2]; - ftn_num = ((int*)elem.out_sg[0].iov_base)[3]; - - TRACE("pid(%d) length(%d) r_length(%d) ftn num(%d) \n" - , pid, length, r_length, ftn_num); - - if(length < SIZE_GPI_HEADER){ - ERR("wrong protocal \n"); - goto done; - } - - /* alloc */ - buffer = qemu_mallocz(length); - r_buffer = qemu_mallocz(r_length); - - i_buffer = (int*)buffer; - - /* get whole data */ - i = 0; - ptr = buffer; - while(length){ - int next = length; - if(next > elem.out_sg[i].iov_len) - next = elem.out_sg[i].iov_len; - memcpy(ptr, (char *)elem.out_sg[i].iov_base, next); - ptr += next; - ret += next; - i++; - length -= next; - } - log_dump(buffer, ((int*)elem.out_sg[0].iov_base)[1]); - - /* procedure */ - call_gpi(i_buffer[0], /* pid */ - ftn_num, /* call function number */ - buffer + SIZE_GPI_HEADER, /* command_buffer */ - i_buffer[1] - SIZE_GPI_HEADER, /* cmd buffer length */ - r_buffer, /* return buffer length */ - r_length); /* return buffer */ - - log_dump(r_buffer, r_length); - - if(r_length) - ret = r_length; - - /* put whole data */ - i = 0; - ptr = r_buffer; - while(r_length) { - int next = r_length; - if(next > elem.in_sg[i].iov_len) - next = elem.in_sg[i].iov_len; - memcpy(elem.in_sg[i].iov_base, ptr, next); - ptr += next; - r_length -= next; - i++; - } - - /* free */ - qemu_free(buffer); - qemu_free(r_buffer); - -done: - virtqueue_push(vq, &elem, ret); - virtio_notify(vdev, vq); - } - - return; -} - -static uint32_t virtio_gpi_get_features(VirtIODevice *vdev, uint32_t f) -{ - TRACE("virtio gpi get features: %x \n", f); - return 0; -} - -static void virtio_gpi_save(QEMUFile *f, void *opaque) -{ - VirtIOGPI *s = opaque; - - TRACE("virtio gpi save \n"); - - virtio_save(&s->vdev, f); -} - -static int virtio_gpi_load(QEMUFile *f, void *opaque, int version_id) -{ - VirtIOGPI *s = opaque; - TRACE("virtio gpi load \n"); - - if (version_id != 1) - return -EINVAL; - - virtio_load(&s->vdev, f); - return 0; -} - -VirtIODevice *virtio_gpi_init(DeviceState *dev) -{ - VirtIOGPI *s = NULL; - - TRACE("initialize \n"); - - s = (VirtIOGPI *)virtio_common_init("virtio-gpi", - VIRTIO_ID_GPI, - 0, sizeof(VirtIOGPI)); - if (!s) - return NULL; - - s->vdev.get_features = virtio_gpi_get_features; - - s->vq = virtio_add_queue(&s->vdev, 128, virtio_gpi_handle); - - register_savevm(dev, "virtio-gpi", -1, 1, virtio_gpi_save, virtio_gpi_load, s); - - return &s->vdev; -} - diff --git a/hw/virtio-net.c b/hw/virtio-net.c index e9775a6..8c2f460 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -115,7 +115,8 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status) if (!tap_get_vhost_net(n->nic->nc.peer)) { return; } - if (!!n->vhost_started == virtio_net_started(n, status)) { + if (!!n->vhost_started == virtio_net_started(n, status) && + !n->nic->nc.peer->link_down) { return; } if (!n->vhost_started) { @@ -149,7 +150,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) if (virtio_net_started(n, status) && !n->vhost_started) { if (n->tx_timer) { qemu_mod_timer(n->tx_timer, - qemu_get_clock(vm_clock) + n->tx_timeout); + qemu_get_clock_ns(vm_clock) + n->tx_timeout); } else { qemu_bh_schedule(n->tx_bh); } @@ -656,7 +657,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ /* copy in packet. ugh */ len = iov_from_buf(sg, elem.in_num, - buf + offset, size - offset); + buf + offset, 0, size - offset); total += len; offset += len; /* If buffers can't be merged, at this point we @@ -784,7 +785,7 @@ static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq) virtio_net_flush_tx(n, vq); } else { qemu_mod_timer(n->tx_timer, - qemu_get_clock(vm_clock) + n->tx_timeout); + qemu_get_clock_ns(vm_clock) + n->tx_timeout); n->tx_waiting = 1; virtio_queue_set_notification(vq, 0); } @@ -1018,7 +1019,7 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, if (net->tx && !strcmp(net->tx, "timer")) { n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx_timer); - n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n); + n->tx_timer = qemu_new_timer_ns(vm_clock, virtio_net_tx_timer, n); n->tx_timeout = net->txtimer; } else { n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx_bh); @@ -1038,9 +1039,9 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, n->mergeable_rx_bufs = 0; n->promisc = 1; /* for compatibility */ - n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN); + n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN); - n->vlans = qemu_mallocz(MAX_VLAN >> 3); + n->vlans = g_malloc0(MAX_VLAN >> 3); n->qdev = dev; register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION, @@ -1062,8 +1063,8 @@ void virtio_net_exit(VirtIODevice *vdev) unregister_savevm(n->qdev, "virtio-net", n); - qemu_free(n->mac_table.macs); - qemu_free(n->vlans); + g_free(n->mac_table.macs); + g_free(n->vlans); if (n->tx_timer) { qemu_del_timer(n->tx_timer); @@ -1072,6 +1073,6 @@ void virtio_net_exit(VirtIODevice *vdev) qemu_bh_delete(n->tx_bh); } - virtio_cleanup(&n->vdev); qemu_del_vlan_client(&n->nic->nc); + virtio_cleanup(&n->vdev); } diff --git a/hw/virtio-net.h b/hw/virtio-net.h index 8af9a1c..4468741 100644 --- a/hw/virtio-net.h +++ b/hw/virtio-net.h @@ -72,7 +72,7 @@ struct virtio_net_config uint8_t mac[ETH_ALEN]; /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */ uint16_t status; -} __attribute__((packed)); +} QEMU_PACKED; /* This is the first element of the scatter-gather list. If you don't * specify GSO or CSUM features, you can simply ignore the header. */ diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 5a3acde..8645edd 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -13,11 +13,13 @@ * */ + #include #include "virtio.h" #include "virtio-blk.h" #include "virtio-net.h" +#include "virtio-serial.h" #include "pci.h" #include "qemu-error.h" #include "msix.h" @@ -25,6 +27,11 @@ #include "loader.h" #include "kvm.h" #include "blockdev.h" +#include "virtio-pci.h" +#include "range.h" +#ifdef CONFIG_MARU +#include "../tizen/src/hw/maru_device_ids.h" +#endif /* from Linux's linux/virtio_pci.h */ @@ -64,17 +71,14 @@ #define VIRTIO_PCI_CONFIG_NOMSI 20 #define VIRTIO_PCI_CONFIG_MSI 24 #define VIRTIO_PCI_REGION_SIZE(dev) (msix_present(dev) ? \ -VIRTIO_PCI_CONFIG_MSI : \ - VIRTIO_PCI_CONFIG_NOMSI) + VIRTIO_PCI_CONFIG_MSI : \ + VIRTIO_PCI_CONFIG_NOMSI) /* The remaining space is defined by each driver as the per-driver * configuration space */ #define VIRTIO_PCI_CONFIG(dev) (msix_enabled(dev) ? \ - VIRTIO_PCI_CONFIG_MSI : \ - VIRTIO_PCI_CONFIG_NOMSI) - -/* Virtio ABI version, if we increment this, we break the guest driver. */ -#define VIRTIO_PCI_ABI_VERSION 0 + VIRTIO_PCI_CONFIG_MSI : \ + VIRTIO_PCI_CONFIG_NOMSI) /* How many bits to shift physical queue address written to QUEUE_PFN. * 12 is historical, and due to x86 page size. */ @@ -83,885 +87,869 @@ VIRTIO_PCI_CONFIG_MSI : \ /* Flags track per-device state like workarounds for quirks in older guests. */ #define VIRTIO_PCI_FLAG_BUS_MASTER_BUG (1 << 0) -/* Performance improves when virtqueue kick processing is decoupled from the - * vcpu thread using ioeventfd for some devices. */ -#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1 -#define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT) - /* QEMU doesn't strictly need write barriers since everything runs in * lock-step. We'll leave the calls to wmb() in though to make it obvious for * KVM or if kqemu gets SMP support. */ #define wmb() do { } while (0) -/* PCI bindings. */ - -typedef struct { - PCIDevice pci_dev; - VirtIODevice *vdev; - uint32_t flags; - uint32_t addr; - uint32_t class_code; - uint32_t nvectors; - BlockConf block; - NICConf nic; - uint32_t host_features; -#ifdef CONFIG_LINUX - V9fsConf fsconf; -#endif - /* Max. number of ports we can have for a the virtio-serial device */ - uint32_t max_virtserial_ports; - virtio_net_conf net; - bool ioeventfd_disabled; - bool ioeventfd_started; -} VirtIOPCIProxy; - /* virtio device */ static void virtio_pci_notify(void *opaque, uint16_t vector) { - VirtIOPCIProxy *proxy = opaque; - if (msix_enabled(&proxy->pci_dev)) - msix_notify(&proxy->pci_dev, vector); - else - qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); + VirtIOPCIProxy *proxy = opaque; + if (msix_enabled(&proxy->pci_dev)) + msix_notify(&proxy->pci_dev, vector); + else + qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); } static void virtio_pci_save_config(void * opaque, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; - pci_device_save(&proxy->pci_dev, f); - msix_save(&proxy->pci_dev, f); - if (msix_present(&proxy->pci_dev)) - qemu_put_be16(f, proxy->vdev->config_vector); + VirtIOPCIProxy *proxy = opaque; + pci_device_save(&proxy->pci_dev, f); + msix_save(&proxy->pci_dev, f); + if (msix_present(&proxy->pci_dev)) + qemu_put_be16(f, proxy->vdev->config_vector); } static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; - if (msix_present(&proxy->pci_dev)) - qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n)); + VirtIOPCIProxy *proxy = opaque; + if (msix_present(&proxy->pci_dev)) + qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n)); } static int virtio_pci_load_config(void * opaque, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; - int ret; - ret = pci_device_load(&proxy->pci_dev, f); - if (ret) { - return ret; - } - msix_load(&proxy->pci_dev, f); - if (msix_present(&proxy->pci_dev)) { - qemu_get_be16s(f, &proxy->vdev->config_vector); - } else { - proxy->vdev->config_vector = VIRTIO_NO_VECTOR; - } - if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) { - return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector); - } - return 0; + VirtIOPCIProxy *proxy = opaque; + int ret; + ret = pci_device_load(&proxy->pci_dev, f); + if (ret) { + return ret; + } + msix_load(&proxy->pci_dev, f); + if (msix_present(&proxy->pci_dev)) { + qemu_get_be16s(f, &proxy->vdev->config_vector); + } else { + proxy->vdev->config_vector = VIRTIO_NO_VECTOR; + } + if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) { + return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector); + } + return 0; } static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f) { - VirtIOPCIProxy *proxy = opaque; - uint16_t vector; - if (msix_present(&proxy->pci_dev)) { - qemu_get_be16s(f, &vector); - } else { - vector = VIRTIO_NO_VECTOR; - } - virtio_queue_set_vector(proxy->vdev, n, vector); - if (vector != VIRTIO_NO_VECTOR) { - return msix_vector_use(&proxy->pci_dev, vector); - } - return 0; + VirtIOPCIProxy *proxy = opaque; + uint16_t vector; + if (msix_present(&proxy->pci_dev)) { + qemu_get_be16s(f, &vector); + } else { + vector = VIRTIO_NO_VECTOR; + } + virtio_queue_set_vector(proxy->vdev, n, vector); + if (vector != VIRTIO_NO_VECTOR) { + return msix_vector_use(&proxy->pci_dev, vector); + } + return 0; } static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy, - int n, bool assign) -{ - VirtQueue *vq = virtio_get_queue(proxy->vdev, n); - EventNotifier *notifier = virtio_queue_get_host_notifier(vq); - int r; - if (assign) { - r = event_notifier_init(notifier, 1); - if (r < 0) { - error_report("%s: unable to init event notifier: %d", - __func__, r); - return r; - } - r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier), - proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY, - n, assign); - if (r < 0) { - error_report("%s: unable to map ioeventfd: %d", - __func__, r); - event_notifier_cleanup(notifier); - } - } else { - r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier), - proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY, - n, assign); - if (r < 0) { - error_report("%s: unable to unmap ioeventfd: %d", - __func__, r); - return r; - } - - /* Handle the race condition where the guest kicked and we deassigned - * before we got around to handling the kick. - */ - if (event_notifier_test_and_clear(notifier)) { - virtio_queue_notify_vq(vq); - } - - event_notifier_cleanup(notifier); - } - return r; + int n, bool assign) +{ + VirtQueue *vq = virtio_get_queue(proxy->vdev, n); + EventNotifier *notifier = virtio_queue_get_host_notifier(vq); + int r = 0; + + if (assign) { + r = event_notifier_init(notifier, 1); + if (r < 0) { + error_report("%s: unable to init event notifier: %d", + __func__, r); + return r; + } + memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, + true, n, event_notifier_get_fd(notifier)); + } else { + memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, + true, n, event_notifier_get_fd(notifier)); + /* Handle the race condition where the guest kicked and we deassigned + * before we got around to handling the kick. + */ + if (event_notifier_test_and_clear(notifier)) { + virtio_queue_notify_vq(vq); + } + + event_notifier_cleanup(notifier); + } + return r; } static void virtio_pci_host_notifier_read(void *opaque) { - VirtQueue *vq = opaque; - EventNotifier *n = virtio_queue_get_host_notifier(vq); - if (event_notifier_test_and_clear(n)) { - virtio_queue_notify_vq(vq); - } + VirtQueue *vq = opaque; + EventNotifier *n = virtio_queue_get_host_notifier(vq); + if (event_notifier_test_and_clear(n)) { + virtio_queue_notify_vq(vq); + } } static void virtio_pci_set_host_notifier_fd_handler(VirtIOPCIProxy *proxy, - int n, bool assign) -{ - VirtQueue *vq = virtio_get_queue(proxy->vdev, n); - EventNotifier *notifier = virtio_queue_get_host_notifier(vq); - if (assign) { - qemu_set_fd_handler(event_notifier_get_fd(notifier), - virtio_pci_host_notifier_read, NULL, vq); - } else { - qemu_set_fd_handler(event_notifier_get_fd(notifier), - NULL, NULL, NULL); - } + int n, bool assign) +{ + VirtQueue *vq = virtio_get_queue(proxy->vdev, n); + EventNotifier *notifier = virtio_queue_get_host_notifier(vq); + if (assign) { + qemu_set_fd_handler(event_notifier_get_fd(notifier), + virtio_pci_host_notifier_read, NULL, vq); + } else { + qemu_set_fd_handler(event_notifier_get_fd(notifier), + NULL, NULL, NULL); + } } static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) { - int n, r; + int n, r; - if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) || - proxy->ioeventfd_disabled || - proxy->ioeventfd_started) { - return; - } + if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) || + proxy->ioeventfd_disabled || + proxy->ioeventfd_started) { + return; + } - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { - if (!virtio_queue_get_num(proxy->vdev, n)) { - continue; - } + for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + if (!virtio_queue_get_num(proxy->vdev, n)) { + continue; + } - r = virtio_pci_set_host_notifier_internal(proxy, n, true); - if (r < 0) { - goto assign_error; - } + r = virtio_pci_set_host_notifier_internal(proxy, n, true); + if (r < 0) { + goto assign_error; + } - virtio_pci_set_host_notifier_fd_handler(proxy, n, true); - } - proxy->ioeventfd_started = true; - return; + virtio_pci_set_host_notifier_fd_handler(proxy, n, true); + } + proxy->ioeventfd_started = true; + return; assign_error: - while (--n >= 0) { - if (!virtio_queue_get_num(proxy->vdev, n)) { - continue; - } - - virtio_pci_set_host_notifier_fd_handler(proxy, n, false); - r = virtio_pci_set_host_notifier_internal(proxy, n, false); - assert(r >= 0); - } - proxy->ioeventfd_started = false; - error_report("%s: failed. Fallback to a userspace (slower).", __func__); + while (--n >= 0) { + if (!virtio_queue_get_num(proxy->vdev, n)) { + continue; + } + + virtio_pci_set_host_notifier_fd_handler(proxy, n, false); + r = virtio_pci_set_host_notifier_internal(proxy, n, false); + assert(r >= 0); + } + proxy->ioeventfd_started = false; + error_report("%s: failed. Fallback to a userspace (slower).", __func__); } static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) { - int r; - int n; + int r; + int n; - if (!proxy->ioeventfd_started) { - return; - } + if (!proxy->ioeventfd_started) { + return; + } - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { - if (!virtio_queue_get_num(proxy->vdev, n)) { - continue; - } + for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + if (!virtio_queue_get_num(proxy->vdev, n)) { + continue; + } - virtio_pci_set_host_notifier_fd_handler(proxy, n, false); - r = virtio_pci_set_host_notifier_internal(proxy, n, false); - assert(r >= 0); - } - proxy->ioeventfd_started = false; + virtio_pci_set_host_notifier_fd_handler(proxy, n, false); + r = virtio_pci_set_host_notifier_internal(proxy, n, false); + assert(r >= 0); + } + proxy->ioeventfd_started = false; } -static void virtio_pci_reset(DeviceState *d) +void virtio_pci_reset(DeviceState *d) { - VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev); - virtio_pci_stop_ioeventfd(proxy); - virtio_reset(proxy->vdev); - msix_reset(&proxy->pci_dev); - proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG; + VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev); + virtio_pci_stop_ioeventfd(proxy); + virtio_reset(proxy->vdev); + msix_reset(&proxy->pci_dev); + proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG; } static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) { - VirtIOPCIProxy *proxy = opaque; - VirtIODevice *vdev = proxy->vdev; - target_phys_addr_t pa; - - switch (addr) { - case VIRTIO_PCI_GUEST_FEATURES: - /* Guest does not negotiate properly? We have to assume nothing. */ - if (val & (1 << VIRTIO_F_BAD_FEATURE)) { - if (vdev->bad_features) - val = proxy->host_features & vdev->bad_features(vdev); - else - val = 0; - } - if (vdev->set_features) - vdev->set_features(vdev, val); - vdev->guest_features = val; - break; - case VIRTIO_PCI_QUEUE_PFN: - pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; - if (pa == 0) { - virtio_pci_stop_ioeventfd(proxy); - virtio_reset(proxy->vdev); - msix_unuse_all_vectors(&proxy->pci_dev); - } - else - virtio_queue_set_addr(vdev, vdev->queue_sel, pa); - break; - case VIRTIO_PCI_QUEUE_SEL: - if (val < VIRTIO_PCI_QUEUE_MAX) - vdev->queue_sel = val; - break; - case VIRTIO_PCI_QUEUE_NOTIFY: - virtio_queue_notify(vdev, val); - break; - case VIRTIO_PCI_STATUS: - if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) { - virtio_pci_stop_ioeventfd(proxy); - } - - virtio_set_status(vdev, val & 0xFF); - - if (val & VIRTIO_CONFIG_S_DRIVER_OK) { - virtio_pci_start_ioeventfd(proxy); - } - - if (vdev->status == 0) { - virtio_reset(proxy->vdev); - msix_unuse_all_vectors(&proxy->pci_dev); - } - - /* Linux before 2.6.34 sets the device as OK without enabling - the PCI device bus master bit. In this case we need to disable - some safety checks. */ - if ((val & VIRTIO_CONFIG_S_DRIVER_OK) && - !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { - proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; - } - break; - case VIRTIO_MSI_CONFIG_VECTOR: - msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); - /* Make it possible for guest to discover an error took place. */ - if (msix_vector_use(&proxy->pci_dev, val) < 0) - val = VIRTIO_NO_VECTOR; - vdev->config_vector = val; - break; - case VIRTIO_MSI_QUEUE_VECTOR: - msix_vector_unuse(&proxy->pci_dev, - virtio_queue_vector(vdev, vdev->queue_sel)); - /* Make it possible for guest to discover an error took place. */ - if (msix_vector_use(&proxy->pci_dev, val) < 0) - val = VIRTIO_NO_VECTOR; - virtio_queue_set_vector(vdev, vdev->queue_sel, val); - break; - default: - error_report("%s: unexpected address 0x%x value 0x%x", - __func__, addr, val); - break; + VirtIOPCIProxy *proxy = opaque; + VirtIODevice *vdev = proxy->vdev; + target_phys_addr_t pa; + + switch (addr) { + case VIRTIO_PCI_GUEST_FEATURES: + /* Guest does not negotiate properly? We have to assume nothing. */ + if (val & (1 << VIRTIO_F_BAD_FEATURE)) { + val = vdev->bad_features ? vdev->bad_features(vdev) : 0; } + virtio_set_features(vdev, val); + break; + case VIRTIO_PCI_QUEUE_PFN: + pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; + if (pa == 0) { + virtio_pci_stop_ioeventfd(proxy); + virtio_reset(proxy->vdev); + msix_unuse_all_vectors(&proxy->pci_dev); + } + else + virtio_queue_set_addr(vdev, vdev->queue_sel, pa); + break; + case VIRTIO_PCI_QUEUE_SEL: + if (val < VIRTIO_PCI_QUEUE_MAX) + vdev->queue_sel = val; + break; + case VIRTIO_PCI_QUEUE_NOTIFY: + if (val < VIRTIO_PCI_QUEUE_MAX) { + virtio_queue_notify(vdev, val); + } + break; + case VIRTIO_PCI_STATUS: + if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) { + virtio_pci_stop_ioeventfd(proxy); + } + + virtio_set_status(vdev, val & 0xFF); + + if (val & VIRTIO_CONFIG_S_DRIVER_OK) { + virtio_pci_start_ioeventfd(proxy); + } + + if (vdev->status == 0) { + virtio_reset(proxy->vdev); + msix_unuse_all_vectors(&proxy->pci_dev); + } + + /* Linux before 2.6.34 sets the device as OK without enabling + the PCI device bus master bit. In this case we need to disable + some safety checks. */ + if ((val & VIRTIO_CONFIG_S_DRIVER_OK) && + !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { + proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; + } + break; + case VIRTIO_MSI_CONFIG_VECTOR: + msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); + /* Make it possible for guest to discover an error took place. */ + if (msix_vector_use(&proxy->pci_dev, val) < 0) + val = VIRTIO_NO_VECTOR; + vdev->config_vector = val; + break; + case VIRTIO_MSI_QUEUE_VECTOR: + msix_vector_unuse(&proxy->pci_dev, + virtio_queue_vector(vdev, vdev->queue_sel)); + /* Make it possible for guest to discover an error took place. */ + if (msix_vector_use(&proxy->pci_dev, val) < 0) + val = VIRTIO_NO_VECTOR; + virtio_queue_set_vector(vdev, vdev->queue_sel, val); + break; + default: + error_report("%s: unexpected address 0x%x value 0x%x", + __func__, addr, val); + break; + } } static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr) { - VirtIODevice *vdev = proxy->vdev; - uint32_t ret = 0xFFFFFFFF; - - switch (addr) { - case VIRTIO_PCI_HOST_FEATURES: - ret = proxy->host_features; - break; - case VIRTIO_PCI_GUEST_FEATURES: - ret = vdev->guest_features; - break; - case VIRTIO_PCI_QUEUE_PFN: - ret = virtio_queue_get_addr(vdev, vdev->queue_sel) - >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; - break; - case VIRTIO_PCI_QUEUE_NUM: - ret = virtio_queue_get_num(vdev, vdev->queue_sel); - break; - case VIRTIO_PCI_QUEUE_SEL: - ret = vdev->queue_sel; - break; - case VIRTIO_PCI_STATUS: - ret = vdev->status; - break; - case VIRTIO_PCI_ISR: - /* reading from the ISR also clears it. */ - ret = vdev->isr; - vdev->isr = 0; - qemu_set_irq(proxy->pci_dev.irq[0], 0); - break; - case VIRTIO_MSI_CONFIG_VECTOR: - ret = vdev->config_vector; - break; - case VIRTIO_MSI_QUEUE_VECTOR: - ret = virtio_queue_vector(vdev, vdev->queue_sel); - break; - default: - break; - } - - return ret; + VirtIODevice *vdev = proxy->vdev; + uint32_t ret = 0xFFFFFFFF; + + switch (addr) { + case VIRTIO_PCI_HOST_FEATURES: + ret = proxy->host_features; + break; + case VIRTIO_PCI_GUEST_FEATURES: + ret = vdev->guest_features; + break; + case VIRTIO_PCI_QUEUE_PFN: + ret = virtio_queue_get_addr(vdev, vdev->queue_sel) + >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; + break; + case VIRTIO_PCI_QUEUE_NUM: + ret = virtio_queue_get_num(vdev, vdev->queue_sel); + break; + case VIRTIO_PCI_QUEUE_SEL: + ret = vdev->queue_sel; + break; + case VIRTIO_PCI_STATUS: + ret = vdev->status; + break; + case VIRTIO_PCI_ISR: + /* reading from the ISR also clears it. */ + ret = vdev->isr; + vdev->isr = 0; + qemu_set_irq(proxy->pci_dev.irq[0], 0); + break; + case VIRTIO_MSI_CONFIG_VECTOR: + ret = vdev->config_vector; + break; + case VIRTIO_MSI_QUEUE_VECTOR: + ret = virtio_queue_vector(vdev, vdev->queue_sel); + break; + default: + break; + } + + return ret; } static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr) { - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - return virtio_config_readb(proxy->vdev, addr); + VirtIOPCIProxy *proxy = opaque; + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + if (addr < config) + return virtio_ioport_read(proxy, addr); + addr -= config; + return virtio_config_readb(proxy->vdev, addr); } static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr) { - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - return virtio_config_readw(proxy->vdev, addr); + VirtIOPCIProxy *proxy = opaque; + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + if (addr < config) + return virtio_ioport_read(proxy, addr); + addr -= config; + return virtio_config_readw(proxy->vdev, addr); } static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr) { - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - return virtio_config_readl(proxy->vdev, addr); + VirtIOPCIProxy *proxy = opaque; + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + if (addr < config) + return virtio_ioport_read(proxy, addr); + addr -= config; + return virtio_config_readl(proxy->vdev, addr); } static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val) { - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; - if (addr < config) { - virtio_ioport_write(proxy, addr, val); - return; - } - addr -= config; - virtio_config_writeb(proxy->vdev, addr, val); + VirtIOPCIProxy *proxy = opaque; + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + if (addr < config) { + virtio_ioport_write(proxy, addr, val); + return; + } + addr -= config; + virtio_config_writeb(proxy->vdev, addr, val); } static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val) { - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; - if (addr < config) { - virtio_ioport_write(proxy, addr, val); - return; - } - addr -= config; - virtio_config_writew(proxy->vdev, addr, val); + VirtIOPCIProxy *proxy = opaque; + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + if (addr < config) { + virtio_ioport_write(proxy, addr, val); + return; + } + addr -= config; + virtio_config_writew(proxy->vdev, addr, val); } static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) { - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - addr -= proxy->addr; - if (addr < config) { - virtio_ioport_write(proxy, addr, val); - return; - } - addr -= config; - virtio_config_writel(proxy->vdev, addr, val); -} - -static void virtio_map(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = proxy->vdev; - unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len; + VirtIOPCIProxy *proxy = opaque; + uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + if (addr < config) { + virtio_ioport_write(proxy, addr, val); + return; + } + addr -= config; + virtio_config_writel(proxy->vdev, addr, val); +} + +const MemoryRegionPortio virtio_portio[] = { + { 0, 0x10000, 1, .write = virtio_pci_config_writeb, }, + { 0, 0x10000, 2, .write = virtio_pci_config_writew, }, + { 0, 0x10000, 4, .write = virtio_pci_config_writel, }, + { 0, 0x10000, 1, .read = virtio_pci_config_readb, }, + { 0, 0x10000, 2, .read = virtio_pci_config_readw, }, + { 0, 0x10000, 4, .read = virtio_pci_config_readl, }, + PORTIO_END_OF_LIST() +}; - proxy->addr = addr; +static const MemoryRegionOps virtio_pci_config_ops = { + .old_portio = virtio_portio, + .endianness = DEVICE_LITTLE_ENDIAN, +}; - register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy); - register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy); - register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy); - register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy); - register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy); - register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy); +static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - if (vdev->config_len) - vdev->get_config(vdev, vdev->config); -} + pci_default_write_config(pci_dev, address, val, len); -static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, - uint32_t val, int len) -{ - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - - if (PCI_COMMAND == address) { - if (!(val & PCI_COMMAND_MASTER)) { - if (!(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) { - virtio_pci_stop_ioeventfd(proxy); - virtio_set_status(proxy->vdev, - proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK); - } - } - } + if (range_covers_byte(address, len, PCI_COMMAND) && + !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) && + !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) { + virtio_pci_stop_ioeventfd(proxy); + virtio_set_status(proxy->vdev, + proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK); + } - pci_default_write_config(pci_dev, address, val, len); - msix_write_config(pci_dev, address, val, len); + msix_write_config(pci_dev, address, val, len); } static unsigned virtio_pci_get_features(void *opaque) { - VirtIOPCIProxy *proxy = opaque; - return proxy->host_features; + VirtIOPCIProxy *proxy = opaque; + return proxy->host_features; } static void virtio_pci_guest_notifier_read(void *opaque) { - VirtQueue *vq = opaque; - EventNotifier *n = virtio_queue_get_guest_notifier(vq); - if (event_notifier_test_and_clear(n)) { - virtio_irq(vq); - } + VirtQueue *vq = opaque; + EventNotifier *n = virtio_queue_get_guest_notifier(vq); + if (event_notifier_test_and_clear(n)) { + virtio_irq(vq); + } } static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign) { - VirtIOPCIProxy *proxy = opaque; - VirtQueue *vq = virtio_get_queue(proxy->vdev, n); - EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); - - if (assign) { - int r = event_notifier_init(notifier, 0); - if (r < 0) { - return r; - } - qemu_set_fd_handler(event_notifier_get_fd(notifier), - virtio_pci_guest_notifier_read, NULL, vq); - } else { - qemu_set_fd_handler(event_notifier_get_fd(notifier), - NULL, NULL, NULL); - event_notifier_cleanup(notifier); - } + VirtIOPCIProxy *proxy = opaque; + VirtQueue *vq = virtio_get_queue(proxy->vdev, n); + EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); + + if (assign) { + int r = event_notifier_init(notifier, 0); + if (r < 0) { + return r; + } + qemu_set_fd_handler(event_notifier_get_fd(notifier), + virtio_pci_guest_notifier_read, NULL, vq); + } else { + qemu_set_fd_handler(event_notifier_get_fd(notifier), + NULL, NULL, NULL); + event_notifier_cleanup(notifier); + } - return 0; + return 0; } static bool virtio_pci_query_guest_notifiers(void *opaque) { - VirtIOPCIProxy *proxy = opaque; - return msix_enabled(&proxy->pci_dev); + VirtIOPCIProxy *proxy = opaque; + return msix_enabled(&proxy->pci_dev); } static int virtio_pci_set_guest_notifiers(void *opaque, bool assign) { - VirtIOPCIProxy *proxy = opaque; - VirtIODevice *vdev = proxy->vdev; - int r, n; + VirtIOPCIProxy *proxy = opaque; + VirtIODevice *vdev = proxy->vdev; + int r, n; - for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { - if (!virtio_queue_get_num(vdev, n)) { - break; - } + for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) { + if (!virtio_queue_get_num(vdev, n)) { + break; + } - r = virtio_pci_set_guest_notifier(opaque, n, assign); - if (r < 0) { - goto assign_error; - } - } + r = virtio_pci_set_guest_notifier(opaque, n, assign); + if (r < 0) { + goto assign_error; + } + } - return 0; + return 0; assign_error: - /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ - while (--n >= 0) { - virtio_pci_set_guest_notifier(opaque, n, !assign); - } - return r; + /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ + while (--n >= 0) { + virtio_pci_set_guest_notifier(opaque, n, !assign); + } + return r; } static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign) { - VirtIOPCIProxy *proxy = opaque; + VirtIOPCIProxy *proxy = opaque; - /* Stop using ioeventfd for virtqueue kick if the device starts using host - * notifiers. This makes it easy to avoid stepping on each others' toes. - */ - proxy->ioeventfd_disabled = assign; - if (assign) { - virtio_pci_stop_ioeventfd(proxy); - } - /* We don't need to start here: it's not needed because backend - * currently only stops on status change away from ok, - * reset, vmstop and such. If we do add code to start here, - * need to check vmstate, device state etc. */ - return virtio_pci_set_host_notifier_internal(proxy, n, assign); + /* Stop using ioeventfd for virtqueue kick if the device starts using host + * notifiers. This makes it easy to avoid stepping on each others' toes. + */ + proxy->ioeventfd_disabled = assign; + if (assign) { + virtio_pci_stop_ioeventfd(proxy); + } + /* We don't need to start here: it's not needed because backend + * currently only stops on status change away from ok, + * reset, vmstop and such. If we do add code to start here, + * need to check vmstate, device state etc. */ + return virtio_pci_set_host_notifier_internal(proxy, n, assign); } static void virtio_pci_vmstate_change(void *opaque, bool running) { - VirtIOPCIProxy *proxy = opaque; - - if (running) { - /* Try to find out if the guest has bus master disabled, but is - in ready state. Then we have a buggy guest OS. */ - if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) && - !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { - proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; - } - virtio_pci_start_ioeventfd(proxy); - } else { - virtio_pci_stop_ioeventfd(proxy); - } + VirtIOPCIProxy *proxy = opaque; + + if (running) { + /* Try to find out if the guest has bus master disabled, but is + in ready state. Then we have a buggy guest OS. */ + if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) && + !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { + proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; + } + virtio_pci_start_ioeventfd(proxy); + } else { + virtio_pci_stop_ioeventfd(proxy); + } } static const VirtIOBindings virtio_pci_bindings = { - .notify = virtio_pci_notify, - .save_config = virtio_pci_save_config, - .load_config = virtio_pci_load_config, - .save_queue = virtio_pci_save_queue, - .load_queue = virtio_pci_load_queue, - .get_features = virtio_pci_get_features, - .query_guest_notifiers = virtio_pci_query_guest_notifiers, - .set_host_notifier = virtio_pci_set_host_notifier, - .set_guest_notifiers = virtio_pci_set_guest_notifiers, - .vmstate_change = virtio_pci_vmstate_change, + .notify = virtio_pci_notify, + .save_config = virtio_pci_save_config, + .load_config = virtio_pci_load_config, + .save_queue = virtio_pci_save_queue, + .load_queue = virtio_pci_load_queue, + .get_features = virtio_pci_get_features, + .query_guest_notifiers = virtio_pci_query_guest_notifiers, + .set_host_notifier = virtio_pci_set_host_notifier, + .set_guest_notifiers = virtio_pci_set_guest_notifiers, + .vmstate_change = virtio_pci_vmstate_change, }; -static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, - uint16_t vendor, uint16_t device, - uint16_t class_code, uint8_t pif) +void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev) { - uint8_t *config; - uint32_t size; - - proxy->vdev = vdev; - - config = proxy->pci_dev.config; - pci_config_set_vendor_id(config, vendor); - pci_config_set_device_id(config, device); + uint8_t *config; + uint32_t size; - config[0x08] = VIRTIO_PCI_ABI_VERSION; + proxy->vdev = vdev; - config[0x09] = pif; - pci_config_set_class(config, class_code); + config = proxy->pci_dev.config; - config[0x2c] = vendor & 0xFF; - config[0x2d] = (vendor >> 8) & 0xFF; - config[0x2e] = vdev->device_id & 0xFF; - config[0x2f] = (vdev->device_id >> 8) & 0xFF; + if (proxy->class_code) { + pci_config_set_class(config, proxy->class_code); + } + pci_set_word(config + 0x2c, pci_get_word(config + PCI_VENDOR_ID)); + pci_set_word(config + 0x2e, vdev->device_id); + config[0x3d] = 1; - config[0x3d] = 1; + memory_region_init(&proxy->msix_bar, "virtio-msix", 4096); + if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, + &proxy->msix_bar, 1, 0)) { + pci_register_bar(&proxy->pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, + &proxy->msix_bar); + } else + vdev->nvectors = 0; - if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) { - pci_register_bar(&proxy->pci_dev, 1, - msix_bar_size(&proxy->pci_dev), - PCI_BASE_ADDRESS_SPACE_MEMORY, - msix_mmio_map); - } else - vdev->nvectors = 0; + proxy->pci_dev.config_write = virtio_write_config; - proxy->pci_dev.config_write = virtio_write_config; + size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len; + if (size & (size-1)) + size = 1 << qemu_fls(size); - size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len; - if (size & (size-1)) - size = 1 << qemu_fls(size); + memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy, + "virtio-pci", size); + pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, + &proxy->bar); - pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO, - virtio_map); + if (!kvm_has_many_ioeventfds()) { + proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; + } - if (!kvm_has_many_ioeventfds()) { - proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; - } - - virtio_bind_device(vdev, &virtio_pci_bindings, proxy); - proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY; - proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE; - proxy->host_features = vdev->get_features(vdev, proxy->host_features); + virtio_bind_device(vdev, &virtio_pci_bindings, proxy); + proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY; + proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE; + proxy->host_features = vdev->get_features(vdev, proxy->host_features); } static int virtio_blk_init_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; - if (proxy->class_code != PCI_CLASS_STORAGE_SCSI && - proxy->class_code != PCI_CLASS_STORAGE_OTHER) - proxy->class_code = PCI_CLASS_STORAGE_SCSI; + if (proxy->class_code != PCI_CLASS_STORAGE_SCSI && + proxy->class_code != PCI_CLASS_STORAGE_OTHER) + proxy->class_code = PCI_CLASS_STORAGE_SCSI; - vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block); - if (!vdev) { - return -1; - } - vdev->nvectors = proxy->nvectors; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - PCI_DEVICE_ID_VIRTIO_BLOCK, - proxy->class_code, 0x00); - /* make the actual value visible */ - proxy->nvectors = vdev->nvectors; - return 0; + vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block, + &proxy->block_serial); + if (!vdev) { + return -1; + } + vdev->nvectors = proxy->nvectors; + virtio_init_pci(proxy, vdev); + /* make the actual value visible */ + proxy->nvectors = vdev->nvectors; + return 0; } static int virtio_exit_pci(PCIDevice *pci_dev) { - return msix_uninit(pci_dev); + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + int r; + + memory_region_destroy(&proxy->bar); + r = msix_uninit(pci_dev, &proxy->msix_bar); + memory_region_destroy(&proxy->msix_bar); + return r; } static int virtio_blk_exit_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - virtio_pci_stop_ioeventfd(proxy); - virtio_blk_exit(proxy->vdev); - blockdev_mark_auto_del(proxy->block.bs); - return virtio_exit_pci(pci_dev); + virtio_pci_stop_ioeventfd(proxy); + virtio_blk_exit(proxy->vdev); + blockdev_mark_auto_del(proxy->block.bs); + return virtio_exit_pci(pci_dev); } static int virtio_serial_init_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; - if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER && - proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */ - proxy->class_code != PCI_CLASS_OTHERS) /* qemu-kvm */ - proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER; + if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER && + proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */ + proxy->class_code != PCI_CLASS_OTHERS) /* qemu-kvm */ + proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER; - vdev = virtio_serial_init(&pci_dev->qdev, proxy->max_virtserial_ports); - if (!vdev) { - return -1; - } - vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED - ? proxy->max_virtserial_ports + 1 - : proxy->nvectors; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - PCI_DEVICE_ID_VIRTIO_CONSOLE, - proxy->class_code, 0x00); - proxy->nvectors = vdev->nvectors; - return 0; + vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial); + if (!vdev) { + return -1; + } + vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED + ? proxy->serial.max_virtserial_ports + 1 + : proxy->nvectors; + virtio_init_pci(proxy, vdev); + proxy->nvectors = vdev->nvectors; + return 0; } static int virtio_serial_exit_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - virtio_serial_exit(proxy->vdev); - return virtio_exit_pci(pci_dev); + virtio_pci_stop_ioeventfd(proxy); + virtio_serial_exit(proxy->vdev); + return virtio_exit_pci(pci_dev); } static int virtio_net_init_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; - vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net); + vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net); - vdev->nvectors = proxy->nvectors; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - PCI_DEVICE_ID_VIRTIO_NET, - PCI_CLASS_NETWORK_ETHERNET, - 0x00); + vdev->nvectors = proxy->nvectors; + virtio_init_pci(proxy, vdev); - /* make the actual value visible */ - proxy->nvectors = vdev->nvectors; - return 0; + /* make the actual value visible */ + proxy->nvectors = vdev->nvectors; + return 0; } static int virtio_net_exit_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - virtio_pci_stop_ioeventfd(proxy); - virtio_net_exit(proxy->vdev); - return virtio_exit_pci(pci_dev); + virtio_pci_stop_ioeventfd(proxy); + virtio_net_exit(proxy->vdev); + return virtio_exit_pci(pci_dev); } static int virtio_balloon_init_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; - vdev = virtio_balloon_init(&pci_dev->qdev); - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - PCI_DEVICE_ID_VIRTIO_BALLOON, - PCI_CLASS_MEMORY_RAM, - 0x00); - return 0; + vdev = virtio_balloon_init(&pci_dev->qdev); + if (!vdev) { + return -1; + } + virtio_init_pci(proxy, vdev); + return 0; } -static int virtio_gpi_init_pci(PCIDevice *pci_dev) +static int virtio_balloon_exit_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - vdev = virtio_gpi_init(&pci_dev->qdev); - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - PCI_DEVICE_ID_VIRTIO_EXAMPLE, - PCI_CLASS_MEMORY_RAM, - 0x00); - return 0; + virtio_pci_stop_ioeventfd(proxy); + virtio_balloon_exit(proxy->vdev); + return virtio_exit_pci(pci_dev); } -#ifdef CONFIG_VIRTFS -static int virtio_9p_init_pci(PCIDevice *pci_dev) +#if defined(CONFIG_MARU) && (!defined(CONFIG_DARWIN)) +extern VirtIODevice *virtio_gl_init(DeviceState *dev); +static int virtio_gl_init_pci(PCIDevice *pci_dev) { - VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); - VirtIODevice *vdev; + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; - vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf); - vdev->nvectors = proxy->nvectors; - virtio_init_pci(proxy, vdev, - PCI_VENDOR_ID_REDHAT_QUMRANET, - 0x1009, - 0x2, - 0x00); - /* make the actual value visible */ - proxy->nvectors = vdev->nvectors; - return 0; + vdev = virtio_gl_init(&pci_dev->qdev); + if (!vdev) { + return -1; + } + virtio_init_pci(proxy, vdev); + return 0; } #endif +#ifdef CONFIG_MARU +static int maru_virtio_touchscreen_init_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + VirtIODevice *vdev; + + vdev = maru_virtio_touchscreen_init(&pci_dev->qdev); + if (!vdev) { + return -1; + } + virtio_init_pci(proxy, vdev); + return 0; +} + +static int maru_virtio_touchscreen_exit_pci(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); + + virtio_pci_stop_ioeventfd(proxy); + maru_virtio_touchscreen_exit(proxy->vdev); + return virtio_exit_pci(pci_dev); +} +#endif + + static PCIDeviceInfo virtio_info[] = { - { - .qdev.name = "virtio-blk-pci", - .qdev.alias = "virtio-blk", + { + .qdev.name = "virtio-blk-pci", + .qdev.alias = "virtio-blk", + .qdev.size = sizeof(VirtIOPCIProxy), + .init = virtio_blk_init_pci, + .exit = virtio_blk_exit_pci, + .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK, + .revision = VIRTIO_PCI_ABI_VERSION, + .class_id = PCI_CLASS_STORAGE_SCSI, + .qdev.props = (Property[]) { + DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), + DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block), + DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial), + DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, + VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), + DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_PROP_END_OF_LIST(), + }, + .qdev.reset = virtio_pci_reset, + },{ + .qdev.name = "virtio-net-pci", + .qdev.alias = "virtio-net", + .qdev.size = sizeof(VirtIOPCIProxy), + .init = virtio_net_init_pci, + .exit = virtio_net_exit_pci, + .romfile = "pxe-virtio.rom", + .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = PCI_DEVICE_ID_VIRTIO_NET, + .revision = VIRTIO_PCI_ABI_VERSION, + .class_id = PCI_CLASS_NETWORK_ETHERNET, + .qdev.props = (Property[]) { + DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, + VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), + DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3), + DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic), + DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, + net.txtimer, TX_TIMER_INTERVAL), + DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, + net.txburst, TX_BURST), + DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx), + DEFINE_PROP_END_OF_LIST(), + }, + .qdev.reset = virtio_pci_reset, + },{ + .qdev.name = "virtio-serial-pci", + .qdev.alias = "virtio-serial", + .qdev.size = sizeof(VirtIOPCIProxy), + .init = virtio_serial_init_pci, + .exit = virtio_serial_exit_pci, + .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE, + .revision = VIRTIO_PCI_ABI_VERSION, + .class_id = PCI_CLASS_COMMUNICATION_OTHER, + .qdev.props = (Property[]) { + DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, + VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, + DEV_NVECTORS_UNSPECIFIED), + DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), + DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, + serial.max_virtserial_ports, 31), + DEFINE_PROP_END_OF_LIST(), + }, + .qdev.reset = virtio_pci_reset, + },{ + .qdev.name = "virtio-balloon-pci", + .qdev.alias = "virtio-balloon", + .qdev.size = sizeof(VirtIOPCIProxy), + .init = virtio_balloon_init_pci, + .exit = virtio_balloon_exit_pci, + .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON, + .revision = VIRTIO_PCI_ABI_VERSION, + .class_id = PCI_CLASS_MEMORY_RAM, + .qdev.props = (Property[]) { + DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), + DEFINE_PROP_END_OF_LIST(), + }, + .qdev.reset = virtio_pci_reset, + },{ +#if defined(CONFIG_MARU) && (!defined(CONFIG_DARWIN)) + .qdev.name = "virtio-gl-pci", + .qdev.alias = "virtio-gl", .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_blk_init_pci, - .exit = virtio_blk_exit_pci, - .qdev.props = (Property[]) { - DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), - DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block), - DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, - VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), - DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_END_OF_LIST(), - }, - .qdev.reset = virtio_pci_reset, - },{ - .qdev.name = "virtio-net-pci", - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_net_init_pci, - .exit = virtio_net_exit_pci, - .romfile = "pxe-virtio.bin", + .init = virtio_gl_init_pci, + .exit = virtio_exit_pci, + .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = PCI_DEVICE_ID_VIRTIO_GL, + .revision = VIRTIO_PCI_ABI_VERSION, + .class_id = PCI_CLASS_OTHERS, .qdev.props = (Property[]) { - DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, - VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3), - DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic), - DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, - net.txtimer, TX_TIMER_INTERVAL), - DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, - net.txburst, TX_BURST), - DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx), DEFINE_PROP_END_OF_LIST(), }, .qdev.reset = virtio_pci_reset, },{ - .qdev.name = "virtio-serial-pci", - .qdev.alias = "virtio-serial", - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_serial_init_pci, - .exit = virtio_serial_exit_pci, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, - DEV_NVECTORS_UNSPECIFIED), - DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0), - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports, - 31), - DEFINE_PROP_END_OF_LIST(), - }, - .qdev.reset = virtio_pci_reset, - },{ - .qdev.name = "virtio-balloon-pci", - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_balloon_init_pci, - .exit = virtio_exit_pci, - .qdev.props = (Property[]) { - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_END_OF_LIST(), - }, - .qdev.reset = virtio_pci_reset, - },{ - .qdev.name = "virtio-gpi-pci", - .qdev.alias = "virtio-gpi", - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_gpi_init_pci, - .exit = virtio_exit_pci, - .qdev.props = (Property[]) { - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_END_OF_LIST(), - }, - .qdev.reset = virtio_pci_reset, - },{ -#ifdef CONFIG_VIRTFS - .qdev.name = "virtio-9p-pci", - .qdev.size = sizeof(VirtIOPCIProxy), - .init = virtio_9p_init_pci, - .qdev.props = (Property[]) { - DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), - DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), - DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag), - DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id), - DEFINE_PROP_END_OF_LIST(), - }, - }, { #endif - /* end of list */ - } + +#ifdef CONFIG_MARU + .qdev.name = "virtio-touchscreen-pci", + .qdev.alias = "virtio-touchscreen", + .qdev.size = sizeof(VirtIOPCIProxy), + .init = maru_virtio_touchscreen_init_pci, + .exit = maru_virtio_touchscreen_exit_pci, + .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, + .device_id = PCI_DEVICE_ID_VIRTIO_TOUCHSCREEN, + .revision = VIRTIO_PCI_ABI_VERSION, + .class_id = PCI_CLASS_OTHERS, + .qdev.props = (Property[]) { + DEFINE_PROP_END_OF_LIST(), + }, + .qdev.reset = virtio_pci_reset, + },{ +#endif + + /* end of list */ + } }; static void virtio_pci_register_devices(void) { - pci_qdev_register_many(virtio_info); + pci_qdev_register_many(virtio_info); } device_init(virtio_pci_register_devices) diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index e05ab5e..a4825b9 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -19,6 +19,7 @@ #include "monitor.h" #include "qemu-queue.h" #include "sysbus.h" +#include "trace.h" #include "virtio-serial.h" /* The virtio-serial bus on top of which the ports will ride as devices */ @@ -39,7 +40,7 @@ struct VirtIOSerial { /* Arrays of ivqs and ovqs: one per port */ VirtQueue **ivqs, **ovqs; - VirtIOSerialBus *bus; + VirtIOSerialBus bus; DeviceState *qdev; @@ -103,7 +104,7 @@ static size_t write_to_port(VirtIOSerialPort *port, } len = iov_from_buf(elem.in_sg, elem.in_num, - buf + offset, size - offset); + buf + offset, 0, size - offset); offset += len; virtqueue_push(vq, &elem, len); @@ -129,9 +130,13 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev) static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq, VirtIODevice *vdev) { + VirtIOSerialPortInfo *info; + assert(port); assert(virtio_queue_ready(vq)); + info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info); + while (!port->throttled) { unsigned int i; @@ -149,10 +154,10 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq, ssize_t ret; buf_size = port->elem.out_sg[i].iov_len - port->iov_offset; - ret = port->info->have_data(port, - port->elem.out_sg[i].iov_base - + port->iov_offset, - buf_size); + ret = info->have_data(port, + port->elem.out_sg[i].iov_base + + port->iov_offset, + buf_size); if (ret < 0 && ret != -EAGAIN) { /* We don't handle any other type of errors here */ abort(); @@ -217,6 +222,7 @@ static size_t send_control_event(VirtIOSerialPort *port, uint16_t event, stw_p(&cpkt.event, event); stw_p(&cpkt.value, value); + trace_virtio_serial_send_control_event(port->id, event, value); return send_control_msg(port, &cpkt, sizeof(cpkt)); } @@ -285,24 +291,32 @@ size_t virtio_serial_guest_ready(VirtIOSerialPort *port) return 0; } +static void flush_queued_data_bh(void *opaque) +{ + VirtIOSerialPort *port = opaque; + + flush_queued_data(port); +} + void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle) { if (!port) { return; } + trace_virtio_serial_throttle_port(port->id, throttle); port->throttled = throttle; if (throttle) { return; } - - flush_queued_data(port); + qemu_bh_schedule(port->bh); } /* Guest wants to notify us of some event */ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) { struct VirtIOSerialPort *port; + struct VirtIOSerialPortInfo *info; struct virtio_console_control cpkt, *gcpkt; uint8_t *buffer; size_t buffer_len; @@ -317,16 +331,13 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) cpkt.event = lduw_p(&gcpkt->event); cpkt.value = lduw_p(&gcpkt->value); - port = find_port_by_id(vser, ldl_p(&gcpkt->id)); - if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY) - return; + trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value); - switch(cpkt.event) { - case VIRTIO_CONSOLE_DEVICE_READY: + if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) { if (!cpkt.value) { - error_report("virtio-serial-bus: Guest failure in adding device %s\n", - vser->bus->qbus.name); - break; + error_report("virtio-serial-bus: Guest failure in adding device %s", + vser->bus.qbus.name); + return; } /* * The device is up, we can now tell the device about all the @@ -335,12 +346,25 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) QTAILQ_FOREACH(port, &vser->ports, next) { send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1); } - break; + return; + } + + port = find_port_by_id(vser, ldl_p(&gcpkt->id)); + if (!port) { + error_report("virtio-serial-bus: Unexpected port id %u for device %s", + ldl_p(&gcpkt->id), vser->bus.qbus.name); + return; + } + + trace_virtio_serial_handle_control_message_port(port->id); + info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info); + + switch(cpkt.event) { case VIRTIO_CONSOLE_PORT_READY: if (!cpkt.value) { - error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n", - port->id, vser->bus->qbus.name); + error_report("virtio-serial-bus: Guest failure in adding port %u for device %s", + port->id, vser->bus.qbus.name); break; } /* @@ -350,7 +374,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) * this port is a console port so that the guest can hook it * up to hvc. */ - if (port->is_console) { + if (info->is_console) { send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1); } @@ -359,14 +383,14 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) stw_p(&cpkt.value, 1); buffer_len = sizeof(cpkt) + strlen(port->name) + 1; - buffer = qemu_malloc(buffer_len); + buffer = g_malloc(buffer_len); memcpy(buffer, &cpkt, sizeof(cpkt)); memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name)); buffer[buffer_len - 1] = 0; send_control_msg(port, buffer, buffer_len); - qemu_free(buffer); + g_free(buffer); } if (port->host_connected) { @@ -379,21 +403,21 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) * initialised. If some app is interested in knowing about * this event, let it know. */ - if (port->info->guest_ready) { - port->info->guest_ready(port); + if (info->guest_ready) { + info->guest_ready(port); } break; case VIRTIO_CONSOLE_PORT_OPEN: port->guest_connected = cpkt.value; - if (cpkt.value && port->info->guest_open) { + if (cpkt.value && info->guest_open) { /* Send the guest opened notification if an app is interested */ - port->info->guest_open(port); + info->guest_open(port); } - if (!cpkt.value && port->info->guest_close) { + if (!cpkt.value && info->guest_close) { /* Send the guest closed notification if an app is interested */ - port->info->guest_close(port); + info->guest_close(port); } break; } @@ -423,9 +447,9 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq) * if the size of the buf differs */ if (cur_len > len) { - qemu_free(buf); + g_free(buf); - buf = qemu_malloc(cur_len); + buf = g_malloc(cur_len); len = cur_len; } copied = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, len); @@ -433,7 +457,7 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq) handle_control_message(vser, buf, copied); virtqueue_push(vq, &elem, 0); } - qemu_free(buf); + g_free(buf); virtio_notify(vdev, vq); } @@ -442,25 +466,21 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq) { VirtIOSerial *vser; VirtIOSerialPort *port; - bool discard; + VirtIOSerialPortInfo *info; vser = DO_UPCAST(VirtIOSerial, vdev, vdev); port = find_port_by_vq(vser, vq); + info = port ? DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info) : NULL; - discard = false; - if (!port || !port->host_connected || !port->info->have_data) { - discard = true; - } - - if (discard) { + if (!port || !port->host_connected || !info->have_data) { discard_vq_data(vq, vdev); return; } - if (port->throttled) { + + if (!port->throttled) { + do_flush_queued_data(port, vq, vdev); return; } - - do_flush_queued_data(port, vq, vdev); } static void handle_input(VirtIODevice *vdev, VirtQueue *vq) @@ -473,7 +493,7 @@ static uint32_t get_features(VirtIODevice *vdev, uint32_t features) vser = DO_UPCAST(VirtIOSerial, vdev, vdev); - if (vser->bus->max_nr_ports > 1) { + if (vser->bus.max_nr_ports > 1) { features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT); } return features; @@ -500,7 +520,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque) VirtIOSerial *s = opaque; VirtIOSerialPort *port; uint32_t nr_active_ports; - unsigned int i; + unsigned int i, max_nr_ports; /* The virtio device */ virtio_save(&s->vdev, f); @@ -512,8 +532,8 @@ static void virtio_serial_save(QEMUFile *f, void *opaque) qemu_put_be32s(f, &s->config.max_nr_ports); /* The ports map */ - - for (i = 0; i < (s->config.max_nr_ports + 31) / 32; i++) { + max_nr_ports = tswap32(s->config.max_nr_ports); + for (i = 0; i < (max_nr_ports + 31) / 32; i++) { qemu_put_be32s(f, &s->ports_map[i]); } @@ -574,7 +594,8 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be16s(f, &s->config.rows); qemu_get_be32s(f, &max_nr_ports); - if (max_nr_ports > s->config.max_nr_ports) { + tswap32s(&max_nr_ports); + if (max_nr_ports > tswap32(s->config.max_nr_ports)) { /* Source could have had more ports than us. Fail migration. */ return -EINVAL; } @@ -600,6 +621,9 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) id = qemu_get_be32(f); port = find_port_by_id(s, id); + if (!port) { + return -EINVAL; + } port->guest_connected = qemu_get_byte(f); host_connected = qemu_get_byte(f); @@ -644,39 +668,31 @@ static struct BusInfo virtser_bus_info = { .name = "virtio-serial-bus", .size = sizeof(VirtIOSerialBus), .print_dev = virtser_bus_dev_print, + .props = (Property[]) { + DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID), + DEFINE_PROP_STRING("name", VirtIOSerialPort, name), + DEFINE_PROP_END_OF_LIST() + } }; -static VirtIOSerialBus *virtser_bus_new(DeviceState *dev) -{ - VirtIOSerialBus *bus; - - bus = FROM_QBUS(VirtIOSerialBus, qbus_create(&virtser_bus_info, dev, NULL)); - bus->qbus.allow_hotplug = 1; - - return bus; -} - static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) { - VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev); - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); + VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev); - monitor_printf(mon, "%*s dev-prop-int: id: %u\n", - indent, "", port->id); - monitor_printf(mon, "%*s dev-prop-int: guest_connected: %d\n", - indent, "", port->guest_connected); - monitor_printf(mon, "%*s dev-prop-int: host_connected: %d\n", - indent, "", port->host_connected); - monitor_printf(mon, "%*s dev-prop-int: throttled: %d\n", - indent, "", port->throttled); + monitor_printf(mon, "%*sport %d, guest %s, host %s, throttle %s\n", + indent, "", port->id, + port->guest_connected ? "on" : "off", + port->host_connected ? "on" : "off", + port->throttled ? "on" : "off"); } /* This function is only used if a port id is not provided by the user */ static uint32_t find_free_port_id(VirtIOSerial *vser) { - unsigned int i; + unsigned int i, max_nr_ports; - for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) { + max_nr_ports = tswap32(vser->config.max_nr_ports); + for (i = 0; i < (max_nr_ports + 31) / 32; i++) { uint32_t map, bit; map = vser->ports_map[i]; @@ -721,24 +737,24 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id) static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) { - VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev); + VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev); VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base); - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus); - int ret; + int ret, max_nr_ports; bool plugging_port0; port->vser = bus->vser; + port->bh = qemu_bh_new(flush_queued_data_bh, port); /* * Is the first console port we're seeing? If so, put it up at * location 0. This is done for backward compatibility (old * kernel, new qemu). */ - plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0); + plugging_port0 = info->is_console && !find_port_by_id(port->vser, 0); if (find_port_by_id(port->vser, port->id)) { - error_report("virtio-serial-bus: A port already exists at id %u\n", + error_report("virtio-serial-bus: A port already exists at id %u", port->id); return -1; } @@ -749,20 +765,20 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) } else { port->id = find_free_port_id(port->vser); if (port->id == VIRTIO_CONSOLE_BAD_ID) { - error_report("virtio-serial-bus: Maximum port limit for this device reached\n"); + error_report("virtio-serial-bus: Maximum port limit for this device reached"); return -1; } } } - if (port->id >= port->vser->config.max_nr_ports) { - error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n", - port->vser->config.max_nr_ports - 1); + max_nr_ports = tswap32(port->vser->config.max_nr_ports); + if (port->id >= max_nr_ports) { + error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u", + max_nr_ports - 1); return -1; } - dev->info = info; - ret = info->init(dev); + ret = info->init(port); if (ret) { return ret; } @@ -791,17 +807,19 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) static int virtser_port_qdev_exit(DeviceState *qdev) { - VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev); - VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev); + VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev); + VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, + port->dev.info); VirtIOSerial *vser = port->vser; + qemu_bh_delete(port->bh); remove_port(port->vser, port->id); QTAILQ_REMOVE(&vser->ports, port, next); - if (port->info->exit) - port->info->exit(dev); - + if (info->exit) { + info->exit(port); + } return 0; } @@ -814,19 +832,19 @@ void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info) qdev_register(&info->qdev); } -VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports) +VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf) { VirtIOSerial *vser; VirtIODevice *vdev; uint32_t i, max_supported_ports; - if (!max_nr_ports) + if (!conf->max_virtserial_ports) return NULL; /* Each port takes 2 queues, and one pair is for the control queue */ max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1; - if (max_nr_ports > max_supported_ports) { + if (conf->max_virtserial_ports > max_supported_ports) { error_report("maximum ports supported: %u", max_supported_ports); return NULL; } @@ -838,13 +856,14 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports) vser = DO_UPCAST(VirtIOSerial, vdev, vdev); /* Spawn a new virtio-serial bus on which the ports will ride as devices */ - vser->bus = virtser_bus_new(dev); - vser->bus->vser = vser; + qbus_create_inplace(&vser->bus.qbus, &virtser_bus_info, dev, NULL); + vser->bus.qbus.allow_hotplug = 1; + vser->bus.vser = vser; QTAILQ_INIT(&vser->ports); - vser->bus->max_nr_ports = max_nr_ports; - vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *)); - vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *)); + vser->bus.max_nr_ports = conf->max_virtserial_ports; + vser->ivqs = g_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *)); + vser->ovqs = g_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *)); /* Add a queue for host to guest transfers for port 0 (backward compat) */ vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input); @@ -862,15 +881,15 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports) /* control queue: guest to host */ vser->c_ovq = virtio_add_queue(vdev, 32, control_out); - for (i = 1; i < vser->bus->max_nr_ports; i++) { + for (i = 1; i < vser->bus.max_nr_ports; i++) { /* Add a per-port queue for host to guest transfers */ vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input); /* Add a per-per queue for guest to host transfers */ vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output); } - vser->config.max_nr_ports = max_nr_ports; - vser->ports_map = qemu_mallocz(((max_nr_ports + 31) / 32) + vser->config.max_nr_ports = tswap32(conf->max_virtserial_ports); + vser->ports_map = g_malloc0(((conf->max_virtserial_ports + 31) / 32) * sizeof(vser->ports_map[0])); /* * Reserve location 0 for a console port for backward compat @@ -900,9 +919,9 @@ void virtio_serial_exit(VirtIODevice *vdev) unregister_savevm(vser->qdev, "virtio-console", vser); - qemu_free(vser->ivqs); - qemu_free(vser->ovqs); - qemu_free(vser->ports_map); + g_free(vser->ivqs); + g_free(vser->ovqs); + g_free(vser->ports_map); virtio_cleanup(vdev); } diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h index a308196..ab13803 100644 --- a/hw/virtio-serial.h +++ b/hw/virtio-serial.h @@ -37,7 +37,7 @@ struct virtio_console_config { uint16_t rows; uint32_t max_nr_ports; -} __attribute__((packed)); +} QEMU_PACKED; struct virtio_console_control { uint32_t id; /* Port number */ @@ -45,6 +45,11 @@ struct virtio_console_control { uint16_t value; /* Extra information for the key */ }; +struct virtio_serial_conf { + /* Max. number of ports we can have for a virtio-serial device */ + uint32_t max_virtserial_ports; +}; + /* Some events for the internal messages (control packets) */ #define VIRTIO_CONSOLE_DEVICE_READY 0 #define VIRTIO_CONSOLE_PORT_ADD 1 @@ -62,11 +67,6 @@ typedef struct VirtIOSerialBus VirtIOSerialBus; typedef struct VirtIOSerialPort VirtIOSerialPort; typedef struct VirtIOSerialPortInfo VirtIOSerialPortInfo; -typedef struct VirtIOSerialDevice { - DeviceState qdev; - VirtIOSerialPortInfo *info; -} VirtIOSerialDevice; - /* * This is the state that's shared between all the ports. Some of the * state is configurable via command-line options. Some of it can be @@ -75,7 +75,6 @@ typedef struct VirtIOSerialDevice { */ struct VirtIOSerialPort { DeviceState dev; - VirtIOSerialPortInfo *info; QTAILQ_ENTRY(VirtIOSerialPort) next; @@ -119,8 +118,10 @@ struct VirtIOSerialPort { uint32_t iov_idx; uint64_t iov_offset; - /* Identify if this is a port that binds with hvc in the guest */ - uint8_t is_console; + /* + * When unthrottling we use a bottom-half to call flush_queued_data. + */ + QEMUBH *bh; /* Is the corresponding guest device open? */ bool guest_connected; @@ -132,16 +133,20 @@ struct VirtIOSerialPort { struct VirtIOSerialPortInfo { DeviceInfo qdev; + + /* Is this a device that binds with hvc in the guest? */ + bool is_console; + /* * The per-port (or per-app) init function that's called when a * new device is found on the bus. */ - int (*init)(VirtIOSerialDevice *dev); + int (*init)(VirtIOSerialPort *port); /* * Per-port exit function that's called when a port gets * hot-unplugged or removed. */ - int (*exit)(VirtIOSerialDevice *dev); + int (*exit)(VirtIOSerialPort *port); /* Callbacks for guest events */ /* Guest opened device. */ diff --git a/hw/virtio.c b/hw/virtio.c index 31bd9e3..81ecc40 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -16,21 +16,12 @@ #include "trace.h" #include "qemu-error.h" #include "virtio.h" -#include "sysemu.h" +#include "qemu-barrier.h" /* The alignment to use between consumer and producer parts of vring. * x86 pagesize again. */ #define VIRTIO_PCI_VRING_ALIGN 4096 -/* QEMU doesn't strictly need write barriers since everything runs in - * lock-step. We'll leave the calls to wmb() in though to make it obvious for - * KVM or if kqemu gets SMP support. - * In any case, we must prevent the compiler from reordering the code. - * TODO: we likely need some rmb()/mb() as well. - */ - -#define wmb() __asm__ __volatile__("": : :"memory") - typedef struct VRingDesc { uint64_t addr; @@ -72,7 +63,17 @@ struct VirtQueue VRing vring; target_phys_addr_t pa; uint16_t last_avail_idx; + /* Last used index value we have signalled on */ + uint16_t signalled_used; + + /* Last used index value we have signalled on */ + bool signalled_used_valid; + + /* Notification enabled? */ + bool notification; + int inuse; + uint16_t vector; void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); VirtIODevice *vdev; @@ -141,6 +142,11 @@ static inline uint16_t vring_avail_ring(VirtQueue *vq, int i) return lduw_phys(pa); } +static inline uint16_t vring_used_event(VirtQueue *vq) +{ + return vring_avail_ring(vq, vq->vring.num); +} + static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val) { target_phys_addr_t pa; @@ -162,11 +168,11 @@ static uint16_t vring_used_idx(VirtQueue *vq) return lduw_phys(pa); } -static inline void vring_used_idx_increment(VirtQueue *vq, uint16_t val) +static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val) { target_phys_addr_t pa; pa = vq->vring.used + offsetof(VRingUsed, idx); - stw_phys(pa, vring_used_idx(vq) + val); + stw_phys(pa, val); } static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask) @@ -183,12 +189,26 @@ static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask) stw_phys(pa, lduw_phys(pa) & ~mask); } +static inline void vring_avail_event(VirtQueue *vq, uint16_t val) +{ + target_phys_addr_t pa; + if (!vq->notification) { + return; + } + pa = vq->vring.used + offsetof(VRingUsed, ring[vq->vring.num]); + stw_phys(pa, val); +} + void virtio_queue_set_notification(VirtQueue *vq, int enable) { - if (enable) + vq->notification = enable; + if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { + vring_avail_event(vq, vring_avail_idx(vq)); + } else if (enable) { vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY); - else + } else { vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY); + } } int virtio_queue_ready(VirtQueue *vq) @@ -234,11 +254,16 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, void virtqueue_flush(VirtQueue *vq, unsigned int count) { + uint16_t old, new; /* Make sure buffer is written before we update index. */ - wmb(); + smp_wmb(); trace_virtqueue_flush(vq, count); - vring_used_idx_increment(vq, count); + old = vring_used_idx(vq); + new = old + count; + vring_used_idx_set(vq, new); vq->inuse -= count; + if (unlikely((int16_t)(new - vq->signalled_used) < (uint16_t)(new - old))) + vq->signalled_used_valid = false; } void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, @@ -291,7 +316,7 @@ static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa, /* Check they're not leading us off end of descriptors. */ next = vring_desc_next(desc_pa, i); /* Make sure compiler knows to grab that: we don't want it changing! */ - wmb(); + smp_wmb(); if (next >= max) { error_report("Desc next is %u", next); @@ -395,6 +420,9 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) max = vq->vring.num; i = head = virtqueue_get_head(vq, vq->last_avail_idx++); + if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { + vring_avail_event(vq, vring_avail_idx(vq)); + } if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) { if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) { @@ -413,9 +441,17 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) struct iovec *sg; if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) { + if (elem->in_num >= ARRAY_SIZE(elem->in_sg)) { + error_report("Too many write descriptors in indirect table"); + exit(1); + } elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i); sg = &elem->in_sg[elem->in_num++]; } else { + if (elem->out_num >= ARRAY_SIZE(elem->out_sg)) { + error_report("Too many read descriptors in indirect table"); + exit(1); + } elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i); sg = &elem->out_sg[elem->out_num++]; } @@ -454,6 +490,16 @@ void virtio_update_irq(VirtIODevice *vdev) virtio_notify_vector(vdev, VIRTIO_NO_VECTOR); } +void virtio_set_status(VirtIODevice *vdev, uint8_t val) +{ + trace_virtio_set_status(vdev, val); + + if (vdev->set_status) { + vdev->set_status(vdev, val); + } + vdev->status = val; +} + void virtio_reset(void *opaque) { VirtIODevice *vdev = opaque; @@ -478,6 +524,9 @@ void virtio_reset(void *opaque) vdev->vq[i].last_avail_idx = 0; vdev->vq[i].pa = 0; vdev->vq[i].vector = VIRTIO_NO_VECTOR; + vdev->vq[i].signalled_used = 0; + vdev->vq[i].signalled_used_valid = false; + vdev->vq[i].notification = true; } } @@ -586,9 +635,7 @@ void virtio_queue_notify_vq(VirtQueue *vq) void virtio_queue_notify(VirtIODevice *vdev, int n) { - if (n < VIRTIO_PCI_QUEUE_MAX) { - virtio_queue_notify_vq(&vdev->vq[n]); - } + virtio_queue_notify_vq(&vdev->vq[n]); } uint16_t virtio_queue_vector(VirtIODevice *vdev, int n) @@ -629,13 +676,45 @@ void virtio_irq(VirtQueue *vq) virtio_notify_vector(vq->vdev, vq->vector); } -void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) +/* Assuming a given event_idx value from the other size, if + * we have just incremented index from old to new_idx, + * should we trigger an event? */ +static inline int vring_need_event(uint16_t event, uint16_t new, uint16_t old) +{ + /* Note: Xen has similar logic for notification hold-off + * in include/xen/interface/io/ring.h with req_event and req_prod + * corresponding to event_idx + 1 and new respectively. + * Note also that req_event and req_prod in Xen start at 1, + * event indexes in virtio start at 0. */ + return (uint16_t)(new - event - 1) < (uint16_t)(new - old); +} + +static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq) { + uint16_t old, new; + bool v; /* Always notify when queue is empty (when feature acknowledge) */ - if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) && - (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) || - (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx))) + if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) && + !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) { + return true; + } + + if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) { + return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT); + } + + v = vq->signalled_used_valid; + vq->signalled_used_valid = true; + old = vq->signalled_used; + new = vq->signalled_used = vring_used_idx(vq); + return !v || vring_need_event(vring_used_event(vq), new, old); +} + +void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) +{ + if (!vring_notify(vdev, vq)) { return; + } trace_virtio_notify(vdev, vq); vdev->isr |= 0x01; @@ -684,12 +763,25 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) } } +int virtio_set_features(VirtIODevice *vdev, uint32_t val) +{ + uint32_t supported_features = + vdev->binding->get_features(vdev->binding_opaque); + bool bad = (val & ~supported_features) != 0; + + val &= supported_features; + if (vdev->set_features) { + vdev->set_features(vdev, val); + } + vdev->guest_features = val; + return bad ? -1 : 0; +} + int virtio_load(VirtIODevice *vdev, QEMUFile *f) { int num, i, ret; uint32_t features; - uint32_t supported_features = - vdev->binding->get_features(vdev->binding_opaque); + uint32_t supported_features; if (vdev->binding->load_config) { ret = vdev->binding->load_config(vdev->binding_opaque, f); @@ -701,14 +793,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) qemu_get_8s(f, &vdev->isr); qemu_get_be16s(f, &vdev->queue_sel); qemu_get_be32s(f, &features); - if (features & ~supported_features) { + + if (virtio_set_features(vdev, features) < 0) { + supported_features = vdev->binding->get_features(vdev->binding_opaque); error_report("Features 0x%x unsupported. Allowed features: 0x%x", features, supported_features); return -1; } - if (vdev->set_features) - vdev->set_features(vdev, features); - vdev->guest_features = features; vdev->config_len = qemu_get_be32(f); qemu_get_buffer(f, vdev->config, vdev->config_len); @@ -718,6 +809,8 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) vdev->vq[i].vring.num = qemu_get_be32(f); vdev->vq[i].pa = qemu_get_be64(f); qemu_get_be16s(f, &vdev->vq[i].last_avail_idx); + vdev->vq[i].signalled_used_valid = false; + vdev->vq[i].notification = true; if (vdev->vq[i].pa) { uint16_t nheads; @@ -726,7 +819,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) /* Check it isn't doing very strange things with descriptor numbers. */ if (nheads > vdev->vq[i].vring.num) { error_report("VQ %d size 0x%x Guest index 0x%x " - "inconsistent with Host index 0x%x: delta 0x%x\n", + "inconsistent with Host index 0x%x: delta 0x%x", i, vdev->vq[i].vring.num, vring_avail_idx(&vdev->vq[i]), vdev->vq[i].last_avail_idx, nheads); @@ -734,7 +827,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) } } else if (vdev->vq[i].last_avail_idx) { error_report("VQ %d address 0x0 " - "inconsistent with Host index 0x%x\n", + "inconsistent with Host index 0x%x", i, vdev->vq[i].last_avail_idx); return -1; } @@ -753,11 +846,12 @@ void virtio_cleanup(VirtIODevice *vdev) { qemu_del_vm_change_state_handler(vdev->vmstate); if (vdev->config) - qemu_free(vdev->config); - qemu_free(vdev->vq); + g_free(vdev->config); + g_free(vdev->vq); + g_free(vdev); } -static void virtio_vmstate_change(void *opaque, int running, int reason) +static void virtio_vmstate_change(void *opaque, int running, RunState state) { VirtIODevice *vdev = opaque; bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK); @@ -782,14 +876,15 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, VirtIODevice *vdev; int i; - vdev = qemu_mallocz(struct_size); + vdev = g_malloc0(struct_size); vdev->device_id = device_id; vdev->status = 0; vdev->isr = 0; vdev->queue_sel = 0; vdev->config_vector = VIRTIO_NO_VECTOR; - vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); + vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); + vdev->vm_running = runstate_is_running(); for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { vdev->vq[i].vector = VIRTIO_NO_VECTOR; vdev->vq[i].vdev = vdev; @@ -798,7 +893,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, vdev->name = name; vdev->config_len = config_size; if (vdev->config_len) - vdev->config = qemu_mallocz(config_size); + vdev->config = g_malloc0(config_size); else vdev->config = NULL; diff --git a/hw/virtio.h b/hw/virtio.h index 4ceb52e..7dd8839 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -18,11 +18,12 @@ #include "net.h" #include "qdev.h" #include "sysemu.h" -#include "block_int.h" +#include "block.h" #include "event_notifier.h" #ifdef CONFIG_LINUX #include "9p.h" #endif +#define VIRTIO_ID_GL 6 /* from Linux's linux/virtio_config.h */ @@ -46,6 +47,11 @@ #define VIRTIO_F_NOTIFY_ON_EMPTY 24 /* We support indirect buffer descriptors */ #define VIRTIO_RING_F_INDIRECT_DESC 28 +/* The Guest publishes the used index for which it expects an interrupt + * at the end of the avail ring. Host should ignore the avail->flags field. */ +/* The Host publishes the avail index for which it expects a kick + * at the end of the used ring. Guest should ignore the used->flags field. */ +#define VIRTIO_RING_F_EVENT_IDX 29 /* A guest should never accept this. It implies negotiation is broken. */ #define VIRTIO_F_BAD_FEATURE 30 @@ -130,14 +136,6 @@ struct VirtIODevice VMChangeStateEntry *vmstate; }; -static inline void virtio_set_status(VirtIODevice *vdev, uint8_t val) -{ - if (vdev->set_status) { - vdev->set_status(vdev, val); - } - vdev->status = val; -} - VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void (*handle_output)(VirtIODevice *, VirtQueue *)); @@ -185,32 +183,45 @@ int virtio_queue_get_num(VirtIODevice *vdev, int n); void virtio_queue_notify(VirtIODevice *vdev, int n); uint16_t virtio_queue_vector(VirtIODevice *vdev, int n); void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector); +void virtio_set_status(VirtIODevice *vdev, uint8_t val); void virtio_reset(void *opaque); void virtio_update_irq(VirtIODevice *vdev); +int virtio_set_features(VirtIODevice *vdev, uint32_t val); void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding, void *opaque); /* Base devices. */ -VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf); +VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf, + char **serial); struct virtio_net_conf; VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf, struct virtio_net_conf *net); -VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports); +typedef struct virtio_serial_conf virtio_serial_conf; +VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial); VirtIODevice *virtio_balloon_init(DeviceState *dev); #ifdef CONFIG_LINUX VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf); #endif -VirtIODevice *virtio_gpi_init(DeviceState *dev); void virtio_net_exit(VirtIODevice *vdev); void virtio_blk_exit(VirtIODevice *vdev); void virtio_serial_exit(VirtIODevice *vdev); +void virtio_balloon_exit(VirtIODevice *vdev); + +/* Maru devices */ +#ifdef CONFIG_MARU +VirtIODevice *maru_virtio_touchscreen_init(DeviceState *dev); +void maru_virtio_touchscreen_exit(VirtIODevice *vdev); +#endif + #define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \ DEFINE_PROP_BIT("indirect_desc", _state, _field, \ - VIRTIO_RING_F_INDIRECT_DESC, true) + VIRTIO_RING_F_INDIRECT_DESC, true), \ + DEFINE_PROP_BIT("event_idx", _state, _field, \ + VIRTIO_RING_F_EVENT_IDX, true) target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n); diff --git a/hw/vmmouse.c b/hw/vmmouse.c index 2097119..1113f33 100644 --- a/hw/vmmouse.c +++ b/hw/vmmouse.c @@ -25,6 +25,7 @@ #include "console.h" #include "ps2.h" #include "pc.h" +#include "qdev.h" /* debug only vmmouse */ //#define DEBUG_VMMOUSE @@ -52,6 +53,7 @@ typedef struct _VMMouseState { + ISADevice dev; uint32_t queue[VMMOUSE_QUEUE_SIZE]; int32_t queue_size; uint16_t nb_queue; @@ -176,30 +178,6 @@ static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size) memmove(s->queue, &s->queue[size], sizeof(s->queue[0]) * s->nb_queue); } -static void vmmouse_get_data(uint32_t *data) -{ - CPUState *env = cpu_single_env; - - data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX]; - data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX]; - data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI]; - - DPRINTF("get_data = {%x, %x, %x, %x, %x, %x}\n", - data[0], data[1], data[2], data[3], data[4], data[5]); -} - -static void vmmouse_set_data(const uint32_t *data) -{ - CPUState *env = cpu_single_env; - - DPRINTF("set_data = {%x, %x, %x, %x, %x, %x}\n", - data[0], data[1], data[2], data[3], data[4], data[5]); - - env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1]; - env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3]; - env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5]; -} - static uint32_t vmmouse_ioport_read(void *opaque, uint32_t addr) { VMMouseState *s = opaque; @@ -270,22 +248,42 @@ static const VMStateDescription vmstate_vmmouse = { } }; -void *vmmouse_init(void *m) +static void vmmouse_reset(DeviceState *d) { - VMMouseState *s = NULL; - - DPRINTF("vmmouse_init\n"); - - s = qemu_mallocz(sizeof(VMMouseState)); + VMMouseState *s = container_of(d, VMMouseState, dev.qdev); s->status = 0xffff; - s->ps2_mouse = m; s->queue_size = VMMOUSE_QUEUE_SIZE; +} + +static int vmmouse_initfn(ISADevice *dev) +{ + VMMouseState *s = DO_UPCAST(VMMouseState, dev, dev); + + DPRINTF("vmmouse_init\n"); vmport_register(VMMOUSE_STATUS, vmmouse_ioport_read, s); vmport_register(VMMOUSE_COMMAND, vmmouse_ioport_read, s); vmport_register(VMMOUSE_DATA, vmmouse_ioport_read, s); - vmstate_register(NULL, 0, &vmstate_vmmouse, s); - return s; + return 0; +} + +static ISADeviceInfo vmmouse_info = { + .init = vmmouse_initfn, + .qdev.name = "vmmouse", + .qdev.size = sizeof(VMMouseState), + .qdev.vmsd = &vmstate_vmmouse, + .qdev.no_user = 1, + .qdev.reset = vmmouse_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_PTR("ps2_mouse", VMMouseState, ps2_mouse), + DEFINE_PROP_END_OF_LIST(), + } +}; + +static void vmmouse_dev_register(void) +{ + isa_qdev_register(&vmmouse_info); } +device_init(vmmouse_dev_register) diff --git a/hw/vmport.c b/hw/vmport.c index 6c9d7c9..b5c6fa1 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -24,8 +24,8 @@ #include "hw.h" #include "isa.h" #include "pc.h" -#include "sysemu.h" #include "kvm.h" +#include "qdev.h" //#define VMPORT_DEBUG @@ -37,19 +37,21 @@ typedef struct _VMPortState { + ISADevice dev; + MemoryRegion io; IOPortReadFunc *func[VMPORT_ENTRIES]; void *opaque[VMPORT_ENTRIES]; } VMPortState; -static VMPortState port_state; +static VMPortState *port_state; void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque) { if (command >= VMPORT_ENTRIES) return; - port_state.func[command] = func; - port_state.opaque[command] = opaque; + port_state->func[command] = func; + port_state->opaque[command] = opaque; } static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) @@ -100,12 +102,57 @@ static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr) return ram_size; } -void vmport_init(void) +/* vmmouse helpers */ +void vmmouse_get_data(uint32_t *data) { - register_ioport_read(0x5658, 1, 4, vmport_ioport_read, &port_state); - register_ioport_write(0x5658, 1, 4, vmport_ioport_write, &port_state); + CPUState *env = cpu_single_env; + + data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX]; + data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX]; + data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI]; +} + +void vmmouse_set_data(const uint32_t *data) +{ + CPUState *env = cpu_single_env; + + env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1]; + env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3]; + env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5]; +} + +static const MemoryRegionPortio vmport_portio[] = { + {0, 1, 4, .read = vmport_ioport_read, .write = vmport_ioport_write }, + PORTIO_END_OF_LIST(), +}; +static const MemoryRegionOps vmport_ops = { + .old_portio = vmport_portio +}; + +static int vmport_initfn(ISADevice *dev) +{ + VMPortState *s = DO_UPCAST(VMPortState, dev, dev); + + memory_region_init_io(&s->io, &vmport_ops, s, "vmport", 1); + isa_register_ioport(dev, &s->io, 0x5658); + + port_state = s; /* Register some generic port commands */ vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL); vmport_register(VMPORT_CMD_GETRAMSIZE, vmport_cmd_ram_size, NULL); + return 0; +} + +static ISADeviceInfo vmport_info = { + .qdev.name = "vmport", + .qdev.size = sizeof(VMPortState), + .qdev.no_user = 1, + .init = vmport_initfn, +}; + +static void vmport_dev_register(void) +{ + isa_qdev_register(&vmport_info); } +device_init(vmport_dev_register) diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 6c59053..af70bde 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -27,8 +27,7 @@ #include "pci.h" #include "vmware_vga.h" -#define VERBOSE -#undef DIRECT_VRAM +#undef VERBOSE #define HW_RECT_ACCEL #define HW_FILL_ACCEL #define HW_MOUSE_ACCEL @@ -52,8 +51,6 @@ struct vmsvga_state_s { int on; } cursor; - target_phys_addr_t vram_base; - int index; int scratch_size; uint32_t *scratch; @@ -67,14 +64,13 @@ struct vmsvga_state_s { int syncing; int fb_size; - ram_addr_t fifo_offset; + MemoryRegion fifo_ram; uint8_t *fifo_ptr; unsigned int fifo_size; - target_phys_addr_t fifo_base; union { uint32_t *fifo; - struct __attribute__((__packed__)) { + struct QEMU_PACKED { uint32_t min; uint32_t max; uint32_t next_cmd; @@ -94,6 +90,7 @@ struct vmsvga_state_s { struct pci_vmsvga_state_s { PCIDevice card; struct vmsvga_state_s chip; + MemoryRegion io_bar; }; #define SVGA_MAGIC 0x900000UL @@ -294,7 +291,6 @@ enum { static inline void vmsvga_update_rect(struct vmsvga_state_s *s, int x, int y, int w, int h) { -#ifndef DIRECT_VRAM int line; int bypl; int width; @@ -325,23 +321,17 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s, for (; line > 0; line --, src += bypl, dst += bypl) memcpy(dst, src, width); -#endif dpy_update(s->vga.ds, x, y, w, h); } static inline void vmsvga_update_screen(struct vmsvga_state_s *s) { -#ifndef DIRECT_VRAM - memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr, s->bypp * s->width * s->height); -#endif - + memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr, + s->bypp * s->width * s->height); dpy_update(s->vga.ds, 0, 0, s->width, s->height); } -#ifdef DIRECT_VRAM -# define vmsvga_update_rect_delayed vmsvga_update_rect -#else static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s, int x, int y, int w, int h) { @@ -352,7 +342,6 @@ static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s, rect->w = w; rect->h = h; } -#endif static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s) { @@ -374,32 +363,23 @@ static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s) static inline void vmsvga_copy_rect(struct vmsvga_state_s *s, int x0, int y0, int x1, int y1, int w, int h) { -# ifdef DIRECT_VRAM - uint8_t *vram = ds_get_data(s->ds); -# else uint8_t *vram = s->vga.vram_ptr; -# endif int bypl = s->bypp * s->width; int width = s->bypp * w; int line = h; uint8_t *ptr[2]; -# ifdef DIRECT_VRAM - if (s->ds->dpy_copy) - qemu_console_copy(s->ds, x0, y0, x1, y1, w, h); - else -# endif - { - if (y1 > y0) { - ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1); - ptr[1] = vram + s->bypp * x1 + bypl * (y1 + h - 1); - for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl) - memmove(ptr[1], ptr[0], width); - } else { - ptr[0] = vram + s->bypp * x0 + bypl * y0; - ptr[1] = vram + s->bypp * x1 + bypl * y1; - for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) - memmove(ptr[1], ptr[0], width); + if (y1 > y0) { + ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1); + ptr[1] = vram + s->bypp * x1 + bypl * (y1 + h - 1); + for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl) { + memmove(ptr[1], ptr[0], width); + } + } else { + ptr[0] = vram + s->bypp * x0 + bypl * y0; + ptr[1] = vram + s->bypp * x1 + bypl * y1; + for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) { + memmove(ptr[1], ptr[0], width); } } @@ -411,11 +391,7 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s, static inline void vmsvga_fill_rect(struct vmsvga_state_s *s, uint32_t c, int x, int y, int w, int h) { -# ifdef DIRECT_VRAM - uint8_t *vram = ds_get_data(s->ds); -# else uint8_t *vram = s->vga.vram_ptr; -# endif int bypp = s->bypp; int bypl = bypp * s->width; int width = bypp * w; @@ -426,31 +402,25 @@ static inline void vmsvga_fill_rect(struct vmsvga_state_s *s, uint8_t *src; uint8_t col[4]; -# ifdef DIRECT_VRAM - if (s->ds->dpy_fill) - s->ds->dpy_fill(s->ds, x, y, w, h, c); - else -# endif - { - col[0] = c; - col[1] = c >> 8; - col[2] = c >> 16; - col[3] = c >> 24; - - if (line --) { - dst = fst; - src = col; - for (column = width; column > 0; column --) { - *(dst ++) = *(src ++); - if (src - col == bypp) - src = col; - } - dst = fst; - for (; line > 0; line --) { - dst += bypl; - memcpy(dst, fst, width); + col[0] = c; + col[1] = c >> 8; + col[2] = c >> 16; + col[3] = c >> 24; + + if (line--) { + dst = fst; + src = col; + for (column = width; column > 0; column--) { + *(dst++) = *(src++); + if (src - col == bypp) { + src = col; } } + dst = fst; + for (; line > 0; line--) { + dst += bypl; + memcpy(dst, fst, width); + } } vmsvga_update_rect_delayed(s, x, y, w, h); @@ -761,8 +731,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) case SVGA_REG_BYTES_PER_LINE: return ((s->depth + 7) >> 3) * s->new_width; - case SVGA_REG_FB_START: - return s->vram_base; + case SVGA_REG_FB_START: { + struct pci_vmsvga_state_s *pci_vmsvga + = container_of(s, struct pci_vmsvga_state_s, chip); + return pci_get_bar_addr(&pci_vmsvga->card, 1); + } case SVGA_REG_FB_OFFSET: return 0x0; @@ -788,8 +761,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) #endif return caps; - case SVGA_REG_MEM_START: - return s->fifo_base; + case SVGA_REG_MEM_START: { + struct pci_vmsvga_state_s *pci_vmsvga + = container_of(s, struct pci_vmsvga_state_s, chip); + return pci_get_bar_addr(&pci_vmsvga->card, 2); + } case SVGA_REG_MEM_SIZE: return s->fifo_size; @@ -994,46 +970,21 @@ static void vmsvga_update_display(void *opaque) } } -static void vmsvga_reset(struct vmsvga_state_s *s) +static void vmsvga_reset(DeviceState *dev) { + struct pci_vmsvga_state_s *pci = + DO_UPCAST(struct pci_vmsvga_state_s, card.qdev, dev); + struct vmsvga_state_s *s = &pci->chip; + s->index = 0; s->enable = 0; s->config = 0; s->width = -1; s->height = -1; s->svgaid = SVGA_ID; - s->depth = ds_get_bits_per_pixel(s->vga.ds); - s->bypp = ds_get_bytes_per_pixel(s->vga.ds); s->cursor.on = 0; s->redraw_fifo_first = 0; s->redraw_fifo_last = 0; - switch (s->depth) { - case 8: - s->wred = 0x00000007; - s->wgreen = 0x00000038; - s->wblue = 0x000000c0; - break; - case 15: - s->wred = 0x0000001f; - s->wgreen = 0x000003e0; - s->wblue = 0x00007c00; - break; - case 16: - s->wred = 0x0000001f; - s->wgreen = 0x000007e0; - s->wblue = 0x0000f800; - break; - case 24: - s->wred = 0x00ff0000; - s->wgreen = 0x0000ff00; - s->wblue = 0x000000ff; - break; - case 32: - s->wred = 0x00ff0000; - s->wgreen = 0x0000ff00; - s->wblue = 0x000000ff; - break; - } s->syncing = 0; vga_dirty_log_start(&s->vga); @@ -1064,7 +1015,7 @@ static void vmsvga_screen_dump(void *opaque, const char *filename) DisplaySurface *ds = qemu_create_displaysurface_from(s->width, s->height, 32, ds_get_linesize(s->vga.ds), s->vga.vram_ptr); ppm_save(filename, ds); - qemu_free(ds); + g_free(ds); } } @@ -1076,77 +1027,6 @@ static void vmsvga_text_update(void *opaque, console_ch_t *chardata) s->vga.text_update(&s->vga, chardata); } -#ifdef DIRECT_VRAM -static uint32_t vmsvga_vram_readb(void *opaque, target_phys_addr_t addr) -{ - struct vmsvga_state_s *s = opaque; - if (addr < s->fb_size) - return *(uint8_t *) (ds_get_data(s->ds) + addr); - else - return *(uint8_t *) (s->vram_ptr + addr); -} - -static uint32_t vmsvga_vram_readw(void *opaque, target_phys_addr_t addr) -{ - struct vmsvga_state_s *s = opaque; - if (addr < s->fb_size) - return *(uint16_t *) (ds_get_data(s->ds) + addr); - else - return *(uint16_t *) (s->vram_ptr + addr); -} - -static uint32_t vmsvga_vram_readl(void *opaque, target_phys_addr_t addr) -{ - struct vmsvga_state_s *s = opaque; - if (addr < s->fb_size) - return *(uint32_t *) (ds_get_data(s->ds) + addr); - else - return *(uint32_t *) (s->vram_ptr + addr); -} - -static void vmsvga_vram_writeb(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - struct vmsvga_state_s *s = opaque; - if (addr < s->fb_size) - *(uint8_t *) (ds_get_data(s->ds) + addr) = value; - else - *(uint8_t *) (s->vram_ptr + addr) = value; -} - -static void vmsvga_vram_writew(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - struct vmsvga_state_s *s = opaque; - if (addr < s->fb_size) - *(uint16_t *) (ds_get_data(s->ds) + addr) = value; - else - *(uint16_t *) (s->vram_ptr + addr) = value; -} - -static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - struct vmsvga_state_s *s = opaque; - if (addr < s->fb_size) - *(uint32_t *) (ds_get_data(s->ds) + addr) = value; - else - *(uint32_t *) (s->vram_ptr + addr) = value; -} - -static CPUReadMemoryFunc * const vmsvga_vram_read[] = { - vmsvga_vram_readb, - vmsvga_vram_readw, - vmsvga_vram_readl, -}; - -static CPUWriteMemoryFunc * const vmsvga_vram_write[] = { - vmsvga_vram_writeb, - vmsvga_vram_writew, - vmsvga_vram_writel, -}; -#endif - static int vmsvga_post_load(void *opaque, int version_id) { struct vmsvga_state_s *s = opaque; @@ -1198,10 +1078,11 @@ static const VMStateDescription vmstate_vmware_vga = { } }; -static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) +static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size, + MemoryRegion *address_space, MemoryRegion *io) { s->scratch_size = SVGA_SCRATCH_SIZE; - s->scratch = qemu_malloc(s->scratch_size * 4); + s->scratch = g_malloc(s->scratch_size * 4); s->vga.ds = graphic_console_init(vmsvga_update_display, vmsvga_invalidate_display, @@ -1210,117 +1091,127 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) s->fifo_size = SVGA_FIFO_SIZE; - s->fifo_offset = qemu_ram_alloc(NULL, "vmsvga.fifo", s->fifo_size); - s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset); + memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size); + s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram); vga_common_init(&s->vga, vga_ram_size); - vga_init(&s->vga); + vga_init(&s->vga, address_space, io, true); vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); - vmsvga_reset(s); + s->depth = ds_get_bits_per_pixel(s->vga.ds); + s->bypp = ds_get_bytes_per_pixel(s->vga.ds); + switch (s->depth) { + case 8: + s->wred = 0x00000007; + s->wgreen = 0x00000038; + s->wblue = 0x000000c0; + break; + case 15: + s->wred = 0x0000001f; + s->wgreen = 0x000003e0; + s->wblue = 0x00007c00; + break; + case 16: + s->wred = 0x0000001f; + s->wgreen = 0x000007e0; + s->wblue = 0x0000f800; + break; + case 24: + s->wred = 0x00ff0000; + s->wgreen = 0x0000ff00; + s->wblue = 0x000000ff; + break; + case 32: + s->wred = 0x00ff0000; + s->wgreen = 0x0000ff00; + s->wblue = 0x000000ff; + break; + } } -static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - - register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, - 1, 4, vmsvga_index_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT, - 1, 4, vmsvga_index_write, s); - register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, - 1, 4, vmsvga_value_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT, - 1, 4, vmsvga_value_write, s); - register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, - 1, 4, vmsvga_bios_read, s); - register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT, - 1, 4, vmsvga_bios_write, s); + struct vmsvga_state_s *s = opaque; + + switch (addr) { + case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr); + case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr); + case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr); + default: return -1u; + } } -static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void vmsvga_io_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - ram_addr_t iomemtype; - - s->vram_base = addr; -#ifdef DIRECT_VRAM - iomemtype = cpu_register_io_memory(vmsvga_vram_read, - vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN); -#else - iomemtype = s->vga.vram_offset | IO_MEM_RAM; -#endif - cpu_register_physical_memory(s->vram_base, s->vga.vram_size, - iomemtype); + struct vmsvga_state_s *s = opaque; - s->vga.map_addr = addr; - s->vga.map_end = addr + s->vga.vram_size; - vga_dirty_log_restart(&s->vga); + switch (addr) { + case SVGA_IO_MUL * SVGA_INDEX_PORT: + return vmsvga_index_write(s, addr, data); + case SVGA_IO_MUL * SVGA_VALUE_PORT: + return vmsvga_value_write(s, addr, data); + case SVGA_IO_MUL * SVGA_BIOS_PORT: + return vmsvga_bios_write(s, addr, data); + } } -static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; - struct vmsvga_state_s *s = &d->chip; - ram_addr_t iomemtype; - - s->fifo_base = addr; - iomemtype = s->fifo_offset | IO_MEM_RAM; - cpu_register_physical_memory(s->fifo_base, s->fifo_size, - iomemtype); -} +static const MemoryRegionOps vmsvga_io_ops = { + .read = vmsvga_io_read, + .write = vmsvga_io_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; static int pci_vmsvga_initfn(PCIDevice *dev) { struct pci_vmsvga_state_s *s = DO_UPCAST(struct pci_vmsvga_state_s, card, dev); + MemoryRegion *iomem; + + iomem = &s->chip.vga.vram; - pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE); - pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID); - pci_config_set_class(s->card.config, PCI_CLASS_DISPLAY_VGA); s->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */ s->card.config[PCI_LATENCY_TIMER] = 0x40; /* Latency timer */ - s->card.config[PCI_SUBSYSTEM_VENDOR_ID] = PCI_VENDOR_ID_VMWARE & 0xff; - s->card.config[PCI_SUBSYSTEM_VENDOR_ID + 1] = PCI_VENDOR_ID_VMWARE >> 8; - s->card.config[PCI_SUBSYSTEM_ID] = SVGA_PCI_DEVICE_ID & 0xff; - s->card.config[PCI_SUBSYSTEM_ID + 1] = SVGA_PCI_DEVICE_ID >> 8; s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */ - pci_register_bar(&s->card, 0, 0x10, - PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport); - pci_register_bar(&s->card, 1, VGA_RAM_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem); + memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip, + "vmsvga-io", 0x10); + pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar); - pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE, - PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo); + vmsvga_init(&s->chip, VGA_RAM_SIZE, pci_address_space(dev), + pci_address_space_io(dev)); - vmsvga_init(&s->chip, VGA_RAM_SIZE); + pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem); + pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH, + &s->chip.fifo_ram); if (!dev->rom_bar) { /* compatibility with pc-0.13 and older */ - vga_init_vbe(&s->chip.vga); + vga_init_vbe(&s->chip.vga, pci_address_space(dev)); } return 0; } -void pci_vmsvga_init(PCIBus *bus) -{ - pci_create_simple(bus, -1, "vmware-svga"); -} - static PCIDeviceInfo vmsvga_info = { .qdev.name = "vmware-svga", .qdev.size = sizeof(struct pci_vmsvga_state_s), .qdev.vmsd = &vmstate_vmware_vga, + .qdev.reset = vmsvga_reset, .no_hotplug = 1, .init = pci_vmsvga_initfn, .romfile = "vgabios-vmware.bin", + + .vendor_id = PCI_VENDOR_ID_VMWARE, + .device_id = SVGA_PCI_DEVICE_ID, + .class_id = PCI_CLASS_DISPLAY_VGA, + .subsystem_vendor_id = PCI_VENDOR_ID_VMWARE, + .subsystem_id = SVGA_PCI_DEVICE_ID, }; static void vmsvga_register(void) diff --git a/hw/vmware_vga.h b/hw/vmware_vga.h index 2e0813c..5132573 100644 --- a/hw/vmware_vga.h +++ b/hw/vmware_vga.h @@ -4,6 +4,16 @@ #include "qemu-common.h" /* vmware_vga.c */ -void pci_vmsvga_init(PCIBus *bus); +static inline bool pci_vmsvga_init(PCIBus *bus) +{ + PCIDevice *dev; + + dev = pci_try_create(bus, -1, "vmware-svga"); + if (!dev || qdev_init(&dev->qdev) < 0) { + return false; + } else { + return true; + } +} #endif diff --git a/hw/vt82c686.c b/hw/vt82c686.c index cacc217..2845959 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -49,7 +49,7 @@ static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data) int can_write; SuperIOConfig *superio_conf = opaque; - DPRINTF("superio_ioport_writeb address 0x%x val 0x%x \n", addr, data); + DPRINTF("superio_ioport_writeb address 0x%x val 0x%x\n", addr, data); if (addr == 0x3f0) { superio_conf->index = data & 0xff; } else { @@ -73,12 +73,12 @@ static void superio_ioport_writeb(void *opaque, uint32_t addr, uint32_t data) switch (superio_conf->index) { case 0xe7: if ((data & 0xff) != 0xfe) { - DPRINTF("chage uart 1 base. unsupported yet \n"); + DPRINTF("chage uart 1 base. unsupported yet\n"); } break; case 0xe8: if ((data & 0xff) != 0xbe) { - DPRINTF("chage uart 2 base. unsupported yet \n"); + DPRINTF("chage uart 2 base. unsupported yet\n"); } break; @@ -95,7 +95,7 @@ static uint32_t superio_ioport_readb(void *opaque, uint32_t addr) { SuperIOConfig *superio_conf = opaque; - DPRINTF("superio_ioport_readb address 0x%x \n", addr); + DPRINTF("superio_ioport_readb address 0x%x\n", addr); return (superio_conf->config[superio_conf->index]); } @@ -133,7 +133,7 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address, { VT82C686BState *vt686 = DO_UPCAST(VT82C686BState, dev, d); - DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x \n", + DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", address, val, len); pci_default_write_config(d, address, val, len); @@ -156,12 +156,10 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address, typedef struct VT686PMState { PCIDevice dev; - uint16_t pmsts; - uint16_t pmen; - uint16_t pmcntrl; + ACPIPM1EVT pm1a; + ACPIPM1CNT pm1_cnt; APMState apm; - QEMUTimer *tmr_timer; - int64_t tmr_overflow_time; + ACPIPMTimer tmr; PMSMBus smb; uint32_t smb_io_base; } VT686PMState; @@ -174,54 +172,25 @@ typedef struct VT686MC97State { PCIDevice dev; } VT686MC97State; -#define RTC_EN (1 << 10) -#define PWRBTN_EN (1 << 8) -#define GBL_EN (1 << 5) -#define TMROF_EN (1 << 0) -#define SUS_EN (1 << 13) - -#define ACPI_ENABLE 0xf1 -#define ACPI_DISABLE 0xf0 - -static uint32_t get_pmtmr(VT686PMState *s) -{ - uint32_t d; - d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec()); - return d & 0xffffff; -} - -static int get_pmsts(VT686PMState *s) -{ - int64_t d; - int pmsts; - pmsts = s->pmsts; - d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec()); - if (d >= s->tmr_overflow_time) - s->pmsts |= TMROF_EN; - return pmsts; -} - static void pm_update_sci(VT686PMState *s) { int sci_level, pmsts; - int64_t expire_time; - pmsts = get_pmsts(s); - sci_level = (((pmsts & s->pmen) & - (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0); + pmsts = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time); + sci_level = (((pmsts & s->pm1a.en) & + (ACPI_BITMASK_RT_CLOCK_ENABLE | + ACPI_BITMASK_POWER_BUTTON_ENABLE | + ACPI_BITMASK_GLOBAL_LOCK_ENABLE | + ACPI_BITMASK_TIMER_ENABLE)) != 0); qemu_set_irq(s->dev.irq[0], sci_level); /* schedule a timer interruption if needed */ - if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) { - expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(), PM_TIMER_FREQUENCY); - qemu_mod_timer(s->tmr_timer, expire_time); - } else { - qemu_del_timer(s->tmr_timer); - } + acpi_pm_tmr_update(&s->tmr, (s->pm1a.en & ACPI_BITMASK_TIMER_ENABLE) && + !(pmsts & ACPI_BITMASK_TIMER_STATUS)); } -static void pm_tmr_timer(void *opaque) +static void pm_tmr_timer(ACPIPMTimer *tmr) { - VT686PMState *s = opaque; + VT686PMState *s = container_of(tmr, VT686PMState, tmr); pm_update_sci(s); } @@ -232,39 +201,15 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) addr &= 0x0f; switch (addr) { case 0x00: - { - int64_t d; - int pmsts; - pmsts = get_pmsts(s); - if (pmsts & val & TMROF_EN) { - /* if TMRSTS is reset, then compute the new overflow time */ - d = muldiv64(qemu_get_clock(vm_clock), PM_TIMER_FREQUENCY, get_ticks_per_sec()); - s->tmr_overflow_time = (d + 0x800000LL) & ~0x7fffffLL; - } - s->pmsts &= ~val; - pm_update_sci(s); - } + acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val); + pm_update_sci(s); break; case 0x02: - s->pmen = val; + s->pm1a.en = val; pm_update_sci(s); break; case 0x04: - { - int sus_typ; - s->pmcntrl = val & ~(SUS_EN); - if (val & SUS_EN) { - /* change suspend type */ - sus_typ = (val >> 10) & 3; - switch (sus_typ) { - case 0: /* soft power off */ - qemu_system_shutdown_request(); - break; - default: - break; - } - } - } + acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val); break; default: break; @@ -280,13 +225,13 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) addr &= 0x0f; switch (addr) { case 0x00: - val = get_pmsts(s); + val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time); break; case 0x02: - val = s->pmen; + val = s->pm1a.en; break; case 0x04: - val = s->pmcntrl; + val = s->pm1_cnt.cnt; break; default: val = 0; @@ -310,7 +255,7 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) addr &= 0x0f; switch (addr) { case 0x08: - val = get_pmtmr(s); + val = acpi_pm_tmr_get(&s->tmr); break; default: val = 0; @@ -340,7 +285,7 @@ static void pm_io_space_update(VT686PMState *s) static void pm_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { - DPRINTF("pm_write_config address 0x%x val 0x%x len 0x%x \n", + DPRINTF("pm_write_config address 0x%x val 0x%x len 0x%x\n", address, val, len); pci_default_write_config(d, address, val, len); } @@ -361,12 +306,12 @@ static const VMStateDescription vmstate_acpi = { .post_load = vmstate_acpi_post_load, .fields = (VMStateField []) { VMSTATE_PCI_DEVICE(dev, VT686PMState), - VMSTATE_UINT16(pmsts, VT686PMState), - VMSTATE_UINT16(pmen, VT686PMState), - VMSTATE_UINT16(pmcntrl, VT686PMState), + VMSTATE_UINT16(pm1a.sts, VT686PMState), + VMSTATE_UINT16(pm1a.en, VT686PMState), + VMSTATE_UINT16(pm1_cnt.cnt, VT686PMState), VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState), - VMSTATE_TIMER(tmr_timer, VT686PMState), - VMSTATE_INT64(tmr_overflow_time, VT686PMState), + VMSTATE_TIMER(tmr.timer, VT686PMState), + VMSTATE_INT64(tmr.overflow_time, VT686PMState), VMSTATE_END_OF_LIST() } }; @@ -381,11 +326,6 @@ static int vt82c686b_ac97_initfn(PCIDevice *dev) VT686AC97State *s = DO_UPCAST(VT686AC97State, dev, dev); uint8_t *pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_AC97); - pci_config_set_class(pci_conf, PCI_CLASS_MULTIMEDIA_AUDIO); - pci_config_set_revision(pci_conf, 0x50); - pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY); pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST | @@ -408,6 +348,10 @@ static PCIDeviceInfo via_ac97_info = { .qdev.desc = "AC97", .qdev.size = sizeof(VT686AC97State), .init = vt82c686b_ac97_initfn, + .vendor_id = PCI_VENDOR_ID_VIA, + .device_id = PCI_DEVICE_ID_VIA_AC97, + .revision = 0x50, + .class_id = PCI_CLASS_MULTIMEDIA_AUDIO, }; static void vt82c686b_ac97_register(void) @@ -422,11 +366,6 @@ static int vt82c686b_mc97_initfn(PCIDevice *dev) VT686MC97State *s = DO_UPCAST(VT686MC97State, dev, dev); uint8_t *pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_MC97); - pci_config_set_class(pci_conf, PCI_CLASS_COMMUNICATION_OTHER); - pci_config_set_revision(pci_conf, 0x30); - pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | PCI_COMMAND_VGA_PALETTE); pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); @@ -448,6 +387,10 @@ static PCIDeviceInfo via_mc97_info = { .qdev.desc = "MC97", .qdev.size = sizeof(VT686MC97State), .init = vt82c686b_mc97_initfn, + .vendor_id = PCI_VENDOR_ID_VIA, + .device_id = PCI_DEVICE_ID_VIA_MC97, + .class_id = PCI_CLASS_COMMUNICATION_OTHER, + .revision = 0x30, }; static void vt82c686b_mc97_register(void) @@ -464,11 +407,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) uint8_t *pci_conf; pci_conf = s->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_ACPI); - pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER); - pci_config_set_revision(pci_conf, 0x40); - pci_set_word(pci_conf + PCI_COMMAND, 0); pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); @@ -486,7 +424,8 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) apm_init(&s->apm, NULL, s); - s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s); + acpi_pm_tmr_init(&s->tmr, pm_tmr_timer); + acpi_pm1_cnt_init(&s->pm1_cnt, NULL); pm_smbus_init(&s->dev.qdev, &s->smb); @@ -516,6 +455,10 @@ static PCIDeviceInfo via_pm_info = { .qdev.vmsd = &vmstate_acpi, .init = vt82c686b_pm_initfn, .config_write = pm_write_config, + .vendor_id = PCI_VENDOR_ID_VIA, + .device_id = PCI_DEVICE_ID_VIA_ACPI, + .class_id = PCI_CLASS_BRIDGE_OTHER, + .revision = 0x40, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0), DEFINE_PROP_END_OF_LIST(), @@ -547,14 +490,10 @@ static int vt82c686b_initfn(PCIDevice *d) uint8_t *wmask; int i; - isa_bus_new(&d->qdev); + isa_bus_new(&d->qdev, pci_address_space_io(d)); pci_conf = d->config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_ISA_BRIDGE); - pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); pci_config_set_prog_interface(pci_conf, 0x0); - pci_config_set_revision(pci_conf,0x40); /* Revision 4.0 */ wmask = d->wmask; for (i = 0x00; i < 0xff; i++) { @@ -585,6 +524,10 @@ static PCIDeviceInfo via_info = { .qdev.no_user = 1, .init = vt82c686b_initfn, .config_write = vt82c686b_write_config, + .vendor_id = PCI_VENDOR_ID_VIA, + .device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE, + .class_id = PCI_CLASS_BRIDGE_ISA, + .revision = 0x40, }; static void vt82c686b_register(void) diff --git a/hw/watchdog.c b/hw/watchdog.c index e9dd56e..4c18965 100644 --- a/hw/watchdog.c +++ b/hw/watchdog.c @@ -132,7 +132,7 @@ void watchdog_perform_action(void) case WDT_PAUSE: /* same as 'stop' command in monitor */ watchdog_mon_event("pause"); - vm_stop(0); + vm_stop(RUN_STATE_WATCHDOG); break; case WDT_DEBUG: diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c index 90bf5f6..20d8673 100644 --- a/hw/wdt_i6300esb.c +++ b/hw/wdt_i6300esb.c @@ -66,6 +66,7 @@ /* Device state. */ struct I6300State { PCIDevice dev; + MemoryRegion io_mem; int reboot_enabled; /* "Reboot" on timer expiry. The real action * performed depends on the -watchdog-action @@ -129,7 +130,7 @@ static void i6300esb_restart_timer(I6300State *d, int stage) i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout); - qemu_mod_timer(d->timer, qemu_get_clock(vm_clock) + timeout); + qemu_mod_timer(d->timer, qemu_get_clock_ns(vm_clock) + timeout); } /* This is called when the guest disables the watchdog. */ @@ -355,30 +356,21 @@ static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val) } } -static void i6300esb_map(PCIDevice *dev, int region_num, - pcibus_t addr, pcibus_t size, int type) -{ - static CPUReadMemoryFunc * const mem_read[3] = { - i6300esb_mem_readb, - i6300esb_mem_readw, - i6300esb_mem_readl, - }; - static CPUWriteMemoryFunc * const mem_write[3] = { - i6300esb_mem_writeb, - i6300esb_mem_writew, - i6300esb_mem_writel, - }; - I6300State *d = DO_UPCAST(I6300State, dev, dev); - int io_mem; - - i6300esb_debug("addr = %"FMT_PCIBUS", size = %"FMT_PCIBUS", type = %d\n", - addr, size, type); - - io_mem = cpu_register_io_memory(mem_read, mem_write, d, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory (addr, 0x10, io_mem); - /* qemu_register_coalesced_mmio (addr, 0x10); ? */ -} +static const MemoryRegionOps i6300esb_ops = { + .old_mmio = { + .read = { + i6300esb_mem_readb, + i6300esb_mem_readw, + i6300esb_mem_readl, + }, + .write = { + i6300esb_mem_writeb, + i6300esb_mem_writew, + i6300esb_mem_writel, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, +}; static const VMStateDescription vmstate_i6300esb = { .name = "i6300esb_wdt", @@ -406,20 +398,24 @@ static const VMStateDescription vmstate_i6300esb = { static int i6300esb_init(PCIDevice *dev) { I6300State *d = DO_UPCAST(I6300State, dev, dev); - uint8_t *pci_conf; i6300esb_debug("I6300State = %p\n", d); - d->timer = qemu_new_timer(vm_clock, i6300esb_timer_expired, d); + d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d); d->previous_reboot_flag = 0; - pci_conf = d->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_ESB_9); - pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); + memory_region_init_io(&d->io_mem, &i6300esb_ops, d, "i6300esb", 0x10); + pci_register_bar(&d->dev, 0, 0, &d->io_mem); + /* qemu_register_coalesced_mmio (addr, 0x10); ? */ + + return 0; +} + +static int i6300esb_exit(PCIDevice *dev) +{ + I6300State *d = DO_UPCAST(I6300State, dev, dev); - pci_register_bar(&d->dev, 0, 0x10, - PCI_BASE_ADDRESS_SPACE_MEMORY, i6300esb_map); + memory_region_destroy(&d->io_mem); return 0; } @@ -437,6 +433,10 @@ static PCIDeviceInfo i6300esb_info = { .config_read = i6300esb_config_read, .config_write = i6300esb_config_write, .init = i6300esb_init, + .exit = i6300esb_exit, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = PCI_DEVICE_ID_INTEL_ESB_9, + .class_id = PCI_CLASS_SYSTEM_OTHER, }; static void i6300esb_register_devices(void) diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c index 1248464..81f22d0 100644 --- a/hw/wdt_ib700.c +++ b/hw/wdt_ib700.c @@ -58,7 +58,7 @@ static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data) ib700_debug("addr = %x, data = %x\n", addr, data); timeout = (int64_t) time_map[data & 0xF] * get_ticks_per_sec(); - qemu_mod_timer(s->timer, qemu_get_clock (vm_clock) + timeout); + qemu_mod_timer(s->timer, qemu_get_clock_ns (vm_clock) + timeout); } /* A write (of any value) to this register disables the timer. */ @@ -99,7 +99,7 @@ static int wdt_ib700_init(ISADevice *dev) ib700_debug("watchdog init\n"); - s->timer = qemu_new_timer(vm_clock, ib700_timer_expired, s); + s->timer = qemu_new_timer_ns(vm_clock, ib700_timer_expired, s); register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, s); register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, s); diff --git a/hw/wm8750.c b/hw/wm8750.c index c9c6744..39383f4 100644 --- a/hw/wm8750.c +++ b/hw/wm8750.c @@ -625,7 +625,7 @@ static void wm8750_fini(i2c_slave *i2c) WM8750State *s = (WM8750State *) i2c; wm8750_reset(&s->i2c); AUD_remove_card(&s->card); - qemu_free(s); + g_free(s); } #endif diff --git a/hw/wm8994.c b/hw/wm8994.c deleted file mode 100644 index d56a502..0000000 --- a/hw/wm8994.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * WM8994 Audio Codec - * - * Copyright (c) 2010 Samsung Electronics. - * Contributed by Alexey Merkulov - * Dmitry Zhurikhin - * Vladimir Monakhov - */ - -#include "i2c-addressable.h" -#include "audio/audio.h" -#include "wm8994_reg.h" - - -#define CODEC "wm8994" - - -typedef struct WM8994State { - - I2CAddressableState i2c_addressable; - - uint16_t registers[WM8994_REGISTER_MEM_SIZE]; - - void (*data_req)(void *, int); - void *opaque; - - SWVoiceOut *dac_voice; - QEMUSoundCard card; - - uint8_t data_out[4 * 4096]; /* magic */ - - int idx_out, req_out; -} WM8994State; - - -static inline uint8_t wm8994_volume(WM8994State *s, uint16_t reg) -{ - return s->registers[reg] & 0x3F; -} - -static inline uint8_t wm8994_mute(WM8994State *s, uint16_t reg) -{ - return (s->registers[reg] >> 6) & 1; -} - -static inline uint8_t wm8994_outvol_transform(WM8994State *s, uint16_t reg) -{ - return 0xFF * wm8994_volume(s, reg) / 0x3F; -} - -static inline int wm8994_rate(WM8994State *s, uint16_t reg) -{ - switch ((s->registers[reg] >> 4) & 0xF) { - case 0: return 8000; - case 1: return 11025; - case 2: return 12000; - case 3: return 16000; - case 4: return 22050; - case 5: return 24000; - case 6: return 32000; - case 7: return 44100; - case 8: return 48000; - case 9: return 88200; - case 10: return 96000; - - default: - return 0; - } -} - -static inline audfmt_e wm8994_format(WM8994State *s, uint16_t reg) -{ - switch ((s->registers[reg] >> 5) & 0x3) { - case 0: return AUD_FMT_S16; - case 3: return AUD_FMT_S32; - case 1: - /*TODO: implement conversion */ - hw_error("wm8994: unsupported format (20 bits for channel)\n"); - return AUD_FMT_S16; - case 2: - /*TODO: implement conversion */ - hw_error("wm8994: unsupported format (24 bits for channel)\n"); - return AUD_FMT_S16; - default: - hw_error("wm8994: unknown format\n"); - return AUD_FMT_S16; - } -} - -static inline void wm8994_out_flush(WM8994State *s) -{ - int sent = 0; - - if (!s->dac_voice) - return; - while (sent < s->idx_out) { - sent += - AUD_write(s->dac_voice, s->data_out + sent, s->idx_out - sent) ?: - s->idx_out; - } - s->idx_out = 0; -} - -static void wm8994_audio_out_cb(void *opaque, int free_b) -{ - WM8994State *s = (WM8994State *) opaque; - - if (s->idx_out >= free_b) { - s->idx_out = free_b; - s->req_out = 0; - wm8994_out_flush(s); - } else { - s->req_out = free_b - s->idx_out; - } - - if (s->data_req) { - s->data_req(s->opaque, s->req_out >> 2); - } -} - -static void wm8994_vol_update(WM8994State *s) -{ - int volume_left = wm8994_volume(s, WM8994_SPEAKER_VOLUME_LEFT); - int volume_right = wm8994_volume(s, WM8994_SPEAKER_VOLUME_RIGHT); - - /* Speaker */ - AUD_set_volume_out(s->dac_voice, 1, volume_left, volume_right); -} - -static void wm8994_set_format(WM8994State *s) -{ - struct audsettings out_fmt; - - wm8994_out_flush(s); - - if (s->dac_voice) { - AUD_set_active_out(s->dac_voice, 0); - } - - if (s->dac_voice) { - AUD_close_out(&s->card, s->dac_voice); - s->dac_voice = NULL; - } - - /* Setup output */ - out_fmt.endianness = 0; - out_fmt.nchannels = 2; - out_fmt.freq = wm8994_rate(s, WM8994_AIF1_RATE); - out_fmt.fmt = wm8994_format(s, WM8994_AIF1_CONTROL_1); - - s->dac_voice = - AUD_open_out(&s->card, s->dac_voice, CODEC ".speaker", - s, wm8994_audio_out_cb, &out_fmt); - wm8994_vol_update(s); - - if (s->dac_voice) { - AUD_set_active_out(s->dac_voice, 1); - } -} - -static void wm8994_reset(DeviceState *d) -{ - WM8994State *s = - FROM_I2CADDR_SLAVE(WM8994State, I2CADDR_SLAVE_FROM_QDEV(d)); - - memset(s->registers, 0, sizeof(s->registers)); - s->registers[WM8994_SOFTWARE_RESET] = 0x8994; - - s->registers[WM8994_POWER_MANAGEMENT_2] = 0x6000; - - s->registers[WM8994_SPEAKER_VOLUME_LEFT] = 0x79; - s->registers[WM8994_SPEAKER_VOLUME_RIGHT] = 0x79; - - s->registers[WM8994_AIF1_RATE] = 0x73; - - s->idx_out = 0; - s->req_out = 0; - s->dac_voice = NULL; - - wm8994_set_format(s); -} - -static uint8_t wm8994_read(void *opaque, uint32_t address, uint8_t offset) -{ - WM8994State *s = (WM8994State *)opaque; - - if (offset >= 2) { - /* FIXME: there should be an error but kernel wants to read more - * than allowed; so just pretend there's nothing here */ - /* hw_error("wm8994: too much data requested"); */ - return 0; - } - if (address < WM8994_REGISTER_MEM_SIZE) { - return (s->registers[address] >> ((1 - offset) * 8)) & 0xFF; - } else { - hw_error("wm8994: illegal read offset 0x%x\n", address + offset); - } -} - -static void wm8994_write(void *opaque, uint32_t address, uint8_t offset, - uint8_t val) -{ - WM8994State *s = (WM8994State *)opaque; - - address += offset / 2; - offset %= 2; - - if (address < WM8994_REGISTER_MEM_SIZE) { - s->registers[address] &= ~(0xFF << ((1 - offset) * 8)); - s->registers[address] |= val << ((1 - offset) * 8); - - if (offset == 1) { - switch (address) { - case WM8994_SOFTWARE_RESET: - wm8994_reset(&s->i2c_addressable.i2c.qdev); - break; - - case WM8994_SPEAKER_VOLUME_LEFT: - case WM8994_SPEAKER_VOLUME_RIGHT: - wm8994_vol_update(s); - break; - - case WM8994_AIF1_RATE: - case WM8994_AIF1_CONTROL_1: - wm8994_set_format(s); - break; - - default: - break; - } - } - } else { - hw_error("wm8994: illegal write offset 0x%x\n", address + offset); - } -} - -void wm8994_data_req_set(DeviceState *dev, void (*data_req)(void *, int), - void *opaque) -{ - WM8994State *s = - FROM_I2CADDR_SLAVE(WM8994State, I2CADDR_SLAVE_FROM_QDEV(dev)); - - s->data_req = data_req; - s->opaque = opaque; -} - -void *wm8994_dac_buffer(DeviceState *dev, int samples) -{ - WM8994State *s = - FROM_I2CADDR_SLAVE(WM8994State, I2CADDR_SLAVE_FROM_QDEV(dev)); - - /* XXX: Should check if there are samples free samples available */ - void *ret = s->data_out + s->idx_out; - - s->idx_out += samples << 2; - s->req_out -= samples << 2; - return ret; -} - -void wm8994_dac_dat(DeviceState *dev, uint32_t sample) -{ - WM8994State *s = - FROM_I2CADDR_SLAVE(WM8994State, I2CADDR_SLAVE_FROM_QDEV(dev)); - - *(uint32_t *) &s->data_out[s->idx_out] = sample; - s->req_out -= 4; - s->idx_out += 4; - if (s->idx_out >= sizeof(s->data_out) || s->req_out <= 0) { - wm8994_out_flush(s); - } -} - -void wm8994_dac_commit(DeviceState *dev) -{ - WM8994State *s = - FROM_I2CADDR_SLAVE(WM8994State, I2CADDR_SLAVE_FROM_QDEV(dev)); - - return wm8994_out_flush(s); -} - -static int wm8994_init(I2CAddressableState *i2c) -{ - WM8994State *s = FROM_I2CADDR_SLAVE(WM8994State, i2c); - - AUD_register_card(CODEC, &s->card); - - wm8994_reset(&i2c->i2c.qdev); - - return 0; -} - -static I2CAddressableDeviceInfo wm8994_info = { - .i2c.qdev.name = "wm8994", - .i2c.qdev.size = sizeof(WM8994State), - .i2c.qdev.reset = wm8994_reset, - .init = wm8994_init, - .read = wm8994_read, - .write = wm8994_write, - .size = 2, - .rev = 1 -}; - -static void wm8994_register_devices(void) -{ - i2c_addressable_register_device(&wm8994_info); -} - -device_init(wm8994_register_devices) diff --git a/hw/wm8994_reg.h b/hw/wm8994_reg.h deleted file mode 100644 index daa109c..0000000 --- a/hw/wm8994_reg.h +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef hw_s5pc1xx_wm8994_reg_h -#define hw_s5pc1xx_wm8994_reg_h "s5pc1xx_wm8994_reg.h" - -#define WM8994_SOFTWARE_RESET 0x00 -#define WM8994_POWER_MANAGEMENT_1 0x01 -#define WM8994_POWER_MANAGEMENT_2 0x02 -#define WM8994_POWER_MANAGEMENT_3 0x03 -#define WM8994_POWER_MANAGEMENT_4 0x04 -#define WM8994_POWER_MANAGEMENT_5 0x05 -#define WM8994_POWER_MANAGEMENT_6 0x06 -#define WM8994_INPUT_MIXER_1 0x15 -#define WM8994_LEFT_LINE_INPUT_1_2_VOLUME 0x18 -#define WM8994_LEFT_LINE_INPUT_3_4_VOLUME 0x19 -#define WM8994_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A -#define WM8994_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B -#define WM8994_LEFT_OUTPUT_VOLUME 0x1C /* Headphone */ -#define WM8994_RIGHT_OUTPUT_VOLUME 0x1D -#define WM8994_LINE_OUTPUTS_VOLUME 0x1E -#define WM8994_HPOUT2_VOLUME 0x1F -#define WM8994_LEFT_OPGA_VOLUME 0x20 -#define WM8994_RIGHT_OPGA_VOLUME 0x21 -#define WM8994_SPKMIXL_ATTENUATION 0x22 -#define WM8994_SPKMIXR_ATTENUATION 0x23 -#define WM8994_SPKOUT_MIXERS 0x24 -#define WM8994_CLASSD 0x25 -#define WM8994_SPEAKER_VOLUME_LEFT 0x26 /* Speaker */ -#define WM8994_SPEAKER_VOLUME_RIGHT 0x27 -#define WM8994_INPUT_MIXER_2 0x28 -#define WM8994_INPUT_MIXER_3 0x29 -#define WM8994_INPUT_MIXER_4 0x2A -#define WM8994_INPUT_MIXER_5 0x2B -#define WM8994_INPUT_MIXER_6 0x2C -#define WM8994_OUTPUT_MIXER_1 0x2D -#define WM8994_OUTPUT_MIXER_2 0x2E -#define WM8994_OUTPUT_MIXER_3 0x2F -#define WM8994_OUTPUT_MIXER_4 0x30 -#define WM8994_OUTPUT_MIXER_5 0x31 -#define WM8994_OUTPUT_MIXER_6 0x32 -#define WM8994_HPOUT2_MIXER 0x33 -#define WM8994_LINE_MIXER_1 0x34 -#define WM8994_LINE_MIXER_2 0x35 -#define WM8994_SPEAKER_MIXER 0x36 -#define WM8994_ADDITIONAL_CONTROL 0x37 -#define WM8994_ANTIPOP_1 0x38 -#define WM8994_ANTIPOP_2 0x39 -#define WM8994_MICBIAS 0x3A -#define WM8994_LDO_1 0x3B -#define WM8994_LDO_2 0x3C -#define WM8994_CHARGE_PUMP_1 0x4C -#define WM8994_CLASS_W_1 0x51 -#define WM8994_DC_SERVO_1 0x54 -#define WM8994_DC_SERVO_2 0x55 -#define WM8994_DC_SERVO_4 0x57 -#define WM8994_DC_SERVO_READBACK 0x58 -#define WM8994_DC_SERVO_ANA_1 0x5B -#define WM8994_DC_SERVO_ANA_2 0x5C -#define WM8994_ANALOGUE_HP_1 0x60 -#define WM8994_REVISION 0x100 -#define WM8994_CONTROL_INTERFACE 0x101 -#define WM8994_WRITE_SEQUENCER_CTRL_1 0x110 -#define WM8994_WRITE_SEQUENCER_CTRL_2 0x111 -#define WM8994_AIF1_CLOCKING_1 0x200 -#define WM8994_AIF1_CLOCKING_2 0x201 -#define WM8994_AIF2_CLOCKING_1 0x204 -#define WM8994_AIF2_CLOCKING_2 0x205 -#define WM8994_CLOCKING_1 0x208 -#define WM8994_CLOCKING_2 0x209 -#define WM8994_AIF1_RATE 0x210 -#define WM8994_AIF2_RATE 0x211 -#define WM8994_RATE_STATUS 0x212 -#define WM8994_FLL1_CONTROL_1 0x220 -#define WM8994_FLL1_CONTROL_2 0x221 -#define WM8994_FLL1_CONTROL_3 0x222 -#define WM8994_FLL1_CONTROL_4 0x223 -#define WM8994_FLL1_CONTROL_5 0x224 -#define WM8994_FLL2_CONTROL_1 0x240 -#define WM8994_FLL2_CONTROL_2 0x241 -#define WM8994_FLL2_CONTROL_3 0x242 -#define WM8994_FLL2_CONTROL_4 0x243 -#define WM8994_FLL2_CONTROL_5 0x244 -#define WM8994_AIF1_CONTROL_1 0x300 -#define WM8994_AIF1_CONTROL_2 0x301 -#define WM8994_AIF1_MASTER_SLAVE 0x302 -#define WM8994_AIF1_BCLK 0x303 -#define WM8994_AIF1ADC_LRCLK 0x304 -#define WM8994_AIF1DAC_LRCLK 0x305 -#define WM8994_AIF1DAC_DATA 0x306 -#define WM8994_AIF1ADC_DATA 0x307 -#define WM8994_AIF2_CONTROL_1 0x310 -#define WM8994_AIF2_CONTROL_2 0x311 -#define WM8994_AIF2_MASTER_SLAVE 0x312 -#define WM8994_AIF2_BCLK 0x313 -#define WM8994_AIF2ADC_LRCLK 0x314 -#define WM8994_AIF2DAC_LRCLK 0x315 -#define WM8994_AIF2DAC_DATA 0x316 -#define WM8994_AIF2ADC_DATA 0x317 -#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400 -#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401 -#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402 -#define WM8994_AIF1_DAC1_RIGHT_VOLUME 0x403 -#define WM8994_AIF1_ADC2_LEFT_VOLUME 0x404 -#define WM8994_AIF1_ADC2_RIGHT_VOLUME 0x405 -#define WM8994_AIF1_DAC2_LEFT_VOLUME 0x406 -#define WM8994_AIF1_DAC2_RIGHT_VOLUME 0x407 -#define WM8994_AIF1_ADC1_FILTERS 0x410 -#define WM8994_AIF1_ADC2_FILTERS 0x411 -#define WM8994_AIF1_DAC1_FILTERS_1 0x420 -#define WM8994_AIF1_DAC1_FILTERS_2 0x421 -#define WM8994_AIF1_DAC2_FILTERS_1 0x422 -#define WM8994_AIF1_DAC2_FILTERS_2 0x423 -#define WM8994_AIF1_DRC1_1 0x440 -#define WM8994_AIF1_DRC1_2 0x441 -#define WM8994_AIF1_DRC1_3 0x442 -#define WM8994_AIF1_DRC1_4 0x443 -#define WM8994_AIF1_DRC1_5 0x444 -#define WM8994_AIF1_DRC2_1 0x450 -#define WM8994_AIF1_DRC2_2 0x451 -#define WM8994_AIF1_DRC2_3 0x452 -#define WM8994_AIF1_DRC2_4 0x453 -#define WM8994_AIF1_DRC2_5 0x454 -#define WM8994_AIF1_DAC1_EQ_GAINS_1 0x480 -#define WM8994_AIF1_DAC1_EQ_GAINS_2 0x481 -#define WM8994_AIF1_DAC1_EQ_BAND_1_A 0x482 -#define WM8994_AIF1_DAC1_EQ_BAND_1_B 0x483 -#define WM8994_AIF1_DAC1_EQ_BAND_1_PG 0x484 -#define WM8994_AIF1_DAC1_EQ_BAND_2_A 0x485 -#define WM8994_AIF1_DAC1_EQ_BAND_2_B 0x486 -#define WM8994_AIF1_DAC1_EQ_BAND_2_C 0x487 -#define WM8994_AIF1_DAC1_EQ_BAND_2_PG 0x488 -#define WM8994_AIF1_DAC1_EQ_BAND_3_A 0x489 -#define WM8994_AIF1_DAC1_EQ_BAND_3_B 0x48A -#define WM8994_AIF1_DAC1_EQ_BAND_3_C 0x48B -#define WM8994_AIF1_DAC1_EQ_BAND_3_PG 0x48C -#define WM8994_AIF1_DAC1_EQ_BAND_4_A 0x48D -#define WM8994_AIF1_DAC1_EQ_BAND_4_B 0x48E -#define WM8994_AIF1_DAC1_EQ_BAND_4_C 0x48F -#define WM8994_AIF1_DAC1_EQ_BAND_4_PG 0x490 -#define WM8994_AIF1_DAC1_EQ_BAND_5_A 0x491 -#define WM8994_AIF1_DAC1_EQ_BAND_5_B 0x492 -#define WM8994_AIF1_DAC1_EQ_BAND_5_PG 0x493 -#define WM8994_AIF1_DAC2_EQ_GAINS_1 0x4A0 -#define WM8994_AIF1_DAC2_EQ_GAINS_2 0x4A1 -#define WM8994_AIF1_DAC2_EQ_BAND_1_A 0x4A2 -#define WM8994_AIF1_DAC2_EQ_BAND_1_B 0x4A3 -#define WM8994_AIF1_DAC2_EQ_BAND_1_PG 0x4A4 -#define WM8994_AIF1_DAC2_EQ_BAND_2_A 0x4A5 -#define WM8994_AIF1_DAC2_EQ_BAND_2_B 0x4A6 -#define WM8994_AIF1_DAC2_EQ_BAND_2_C 0x4A7 -#define WM8994_AIF1_DAC2_EQ_BAND_2_PG 0x4A8 -#define WM8994_AIF1_DAC2_EQ_BAND_3_A 0x4A9 -#define WM8994_AIF1_DAC2_EQ_BAND_3_B 0x4AA -#define WM8994_AIF1_DAC2_EQ_BAND_3_C 0x4AB -#define WM8994_AIF1_DAC2_EQ_BAND_3_PG 0x4AC -#define WM8994_AIF1_DAC2_EQ_BAND_4_A 0x4AD -#define WM8994_AIF1_DAC2_EQ_BAND_4_B 0x4AE -#define WM8994_AIF1_DAC2_EQ_BAND_4_C 0x4AF -#define WM8994_AIF1_DAC2_EQ_BAND_4_PG 0x4B0 -#define WM8994_AIF1_DAC2_EQ_BAND_5_A 0x4B1 -#define WM8994_AIF1_DAC2_EQ_BAND_5_B 0x4B2 -#define WM8994_AIF1_DAC2_EQ_BAND_5_PG 0x4B3 -#define WM8994_AIF2_ADC_LEFT_VOLUME 0x500 -#define WM8994_AIF2_ADC_RIGHT_VOLUME 0x501 -#define WM8994_AIF2_DAC_LEFT_VOLUME 0x502 -#define WM8994_AIF2_DAC_RIGHT_VOLUME 0x503 -#define WM8994_AIF2_ADC_FILTERS 0x510 -#define WM8994_AIF2_DAC_FILTERS_1 0x520 -#define WM8994_AIF2_DAC_FILTERS_2 0x521 -#define WM8994_AIF2_DRC_1 0x540 -#define WM8994_AIF2_DRC_2 0x541 -#define WM8994_AIF2_DRC_3 0x542 -#define WM8994_AIF2_DRC_4 0x543 -#define WM8994_AIF2_DRC_5 0x544 -#define WM8994_AIF2_EQ_GAINS_1 0x580 -#define WM8994_AIF2_EQ_GAINS_2 0x581 -#define WM8994_AIF2_EQ_BAND_1_A 0x582 -#define WM8994_AIF2_EQ_BAND_1_B 0x583 -#define WM8994_AIF2_EQ_BAND_1_PG 0x584 -#define WM8994_AIF2_EQ_BAND_2_A 0x585 -#define WM8994_AIF2_EQ_BAND_2_B 0x586 -#define WM8994_AIF2_EQ_BAND_2_C 0x587 -#define WM8994_AIF2_EQ_BAND_2_PG 0x588 -#define WM8994_AIF2_EQ_BAND_3_A 0x589 -#define WM8994_AIF2_EQ_BAND_3_B 0x58A -#define WM8994_AIF2_EQ_BAND_3_C 0x58B -#define WM8994_AIF2_EQ_BAND_3_PG 0x58C -#define WM8994_AIF2_EQ_BAND_4_A 0x58D -#define WM8994_AIF2_EQ_BAND_4_B 0x58E -#define WM8994_AIF2_EQ_BAND_4_C 0x58F -#define WM8994_AIF2_EQ_BAND_4_PG 0x590 -#define WM8994_AIF2_EQ_BAND_5_A 0x591 -#define WM8994_AIF2_EQ_BAND_5_B 0x592 -#define WM8994_AIF2_EQ_BAND_5_PG 0x593 -#define WM8994_DAC1_MIXER_VOLUMES 0x600 -#define WM8994_DAC1_LEFT_MIXER_ROUTING 0x601 -#define WM8994_DAC1_RIGHT_MIXER_ROUTING 0x602 -#define WM8994_DAC2_MIXER_VOLUMES 0x603 -#define WM8994_DAC2_LEFT_MIXER_ROUTING 0x604 -#define WM8994_DAC2_RIGHT_MIXER_ROUTING 0x605 -#define WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606 -#define WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607 -#define WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608 -#define WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609 -#define WM8994_DAC1_LEFT_VOLUME 0x610 -#define WM8994_DAC1_RIGHT_VOLUME 0x611 -#define WM8994_DAC2_LEFT_VOLUME 0x612 -#define WM8994_DAC2_RIGHT_VOLUME 0x613 -#define WM8994_DAC_SOFTMUTE 0x614 -#define WM8994_OVERSAMPLING 0x620 -#define WM8994_SIDETONE 0x621 -#define WM8994_GPIO_1 0x700 -#define WM8994_GPIO_2 0x701 -#define WM8994_GPIO_3 0x702 -#define WM8994_GPIO_4 0x703 -#define WM8994_GPIO_5 0x704 -#define WM8994_GPIO_6 0x705 -#define WM8994_GPIO_7 0x706 -#define WM8994_GPIO_8 0x707 -#define WM8994_GPIO_9 0x708 -#define WM8994_GPIO_10 0x709 -#define WM8994_GPIO_11 0x70A -#define WM8994_DIGITAL_PULLS 0x720 -#define WM8994_INTERRUPT_STATUS_1 0x730 -#define WM8994_INTERRUPT_STATUS_2 0x731 -#define WM8994_INTERRUPT_STATUS_1_MASK 0x738 -#define WM8994_INTERRUPT_STATUS_2_MASK 0x739 -#define WM8994_INTERRUPT_CONTROL 0x740 -#define WM8994_IRQ_DEBOUNCE 0x748 -#define WM8994_IRQ_POLARITY 0x749 - -#define WM8994_REGISTER_MEM_SIZE 0x74A - -#endif /* hw_s5pc1xx_wm8994_reg_h */ diff --git a/hw/xen.h b/hw/xen.h index 780dcf7..2162111 100644 --- a/hw/xen.h +++ b/hw/xen.h @@ -8,6 +8,8 @@ */ #include +#include "qemu-common.h" + /* xen-machine.c */ enum xen_mode { XEN_EMULATE = 0, // xen emulation, using xenner (default) @@ -18,4 +20,35 @@ enum xen_mode { extern uint32_t xen_domid; extern enum xen_mode xen_mode; +extern int xen_allowed; + +static inline int xen_enabled(void) +{ +#if defined(CONFIG_XEN_BACKEND) && !defined(CONFIG_NO_XEN) + return xen_allowed; +#else + return 0; +#endif +} + +int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num); +void xen_piix3_set_irq(void *opaque, int irq_num, int level); +void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len); +void xen_cmos_set_s3_resume(void *opaque, int irq, int level); + +qemu_irq *xen_interrupt_controller_init(void); + +int xen_init(void); +int xen_hvm_init(void); +void xen_vcpu_init(void); +void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); + +#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) +void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size); +#endif + +#if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400 +# define HVM_MAX_VCPUS 32 +#endif + #endif /* QEMU_HW_XEN_H */ diff --git a/hw/xen_backend.c b/hw/xen_backend.c index a2e408f..d876cab 100644 --- a/hw/xen_backend.c +++ b/hw/xen_backend.c @@ -43,7 +43,8 @@ /* ------------------------------------------------------------- */ /* public */ -int xen_xc; +XenXC xen_xc = XC_HANDLER_INITIAL_VALUE; +XenGnttab xen_xcg = XC_HANDLER_INITIAL_VALUE; struct xs_handle *xenstore = NULL; const char *xen_protocol; @@ -58,8 +59,9 @@ int xenstore_write_str(const char *base, const char *node, const char *val) char abspath[XEN_BUFSIZE]; snprintf(abspath, sizeof(abspath), "%s/%s", base, node); - if (!xs_write(xenstore, 0, abspath, val, strlen(val))) - return -1; + if (!xs_write(xenstore, 0, abspath, val, strlen(val))) { + return -1; + } return 0; } @@ -73,8 +75,8 @@ char *xenstore_read_str(const char *base, const char *node) str = xs_read(xenstore, 0, abspath, &len); if (str != NULL) { /* move to qemu-allocated memory to make sure - * callers can savely qemu_free() stuff. */ - ret = qemu_strdup(str); + * callers can savely g_free() stuff. */ + ret = g_strdup(str); free(str); } return ret; @@ -94,9 +96,10 @@ int xenstore_read_int(const char *base, const char *node, int *ival) int rc = -1; val = xenstore_read_str(base, node); - if (val && 1 == sscanf(val, "%d", ival)) - rc = 0; - qemu_free(val); + if (val && 1 == sscanf(val, "%d", ival)) { + rc = 0; + } + g_free(val); return rc; } @@ -134,16 +137,16 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival) const char *xenbus_strstate(enum xenbus_state state) { - static const char *const name[] = { - [ XenbusStateUnknown ] = "Unknown", - [ XenbusStateInitialising ] = "Initialising", - [ XenbusStateInitWait ] = "InitWait", - [ XenbusStateInitialised ] = "Initialised", - [ XenbusStateConnected ] = "Connected", - [ XenbusStateClosing ] = "Closing", - [ XenbusStateClosed ] = "Closed", - }; - return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID"; + static const char *const name[] = { + [ XenbusStateUnknown ] = "Unknown", + [ XenbusStateInitialising ] = "Initialising", + [ XenbusStateInitWait ] = "InitWait", + [ XenbusStateInitialised ] = "Initialised", + [ XenbusStateConnected ] = "Connected", + [ XenbusStateClosing ] = "Closing", + [ XenbusStateClosed ] = "Closed", + }; + return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID"; } int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state) @@ -151,10 +154,11 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state) int rc; rc = xenstore_write_be_int(xendev, "state", state); - if (rc < 0) - return rc; + if (rc < 0) { + return rc; + } xen_be_printf(xendev, 1, "backend state: %s -> %s\n", - xenbus_strstate(xendev->be_state), xenbus_strstate(state)); + xenbus_strstate(xendev->be_state), xenbus_strstate(state)); xendev->be_state = state; return 0; } @@ -166,13 +170,16 @@ struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev) struct XenDevice *xendev; QTAILQ_FOREACH(xendev, &xendevs, next) { - if (xendev->dom != dom) - continue; - if (xendev->dev != dev) - continue; - if (strcmp(xendev->type, type) != 0) - continue; - return xendev; + if (xendev->dom != dom) { + continue; + } + if (xendev->dev != dev) { + continue; + } + if (strcmp(xendev->type, type) != 0) { + continue; + } + return xendev; } return NULL; } @@ -187,11 +194,12 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, char *dom0; xendev = xen_be_find_xendev(type, dom, dev); - if (xendev) - return xendev; + if (xendev) { + return xendev; + } /* init new xendev */ - xendev = qemu_mallocz(ops->size); + xendev = g_malloc0(ops->size); xendev->type = type; xendev->dom = dom; xendev->dev = dev; @@ -199,38 +207,39 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, dom0 = xs_get_domain_path(xenstore, 0); snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d", - dom0, xendev->type, xendev->dom, xendev->dev); + dom0, xendev->type, xendev->dom, xendev->dev); snprintf(xendev->name, sizeof(xendev->name), "%s-%d", - xendev->type, xendev->dev); + xendev->type, xendev->dev); free(dom0); xendev->debug = debug; xendev->local_port = -1; - xendev->evtchndev = xc_evtchn_open(); - if (xendev->evtchndev < 0) { - xen_be_printf(NULL, 0, "can't open evtchn device\n"); - qemu_free(xendev); - return NULL; + xendev->evtchndev = xen_xc_evtchn_open(NULL, 0); + if (xendev->evtchndev == XC_HANDLER_INITIAL_VALUE) { + xen_be_printf(NULL, 0, "can't open evtchn device\n"); + g_free(xendev); + return NULL; } fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC); if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) { - xendev->gnttabdev = xc_gnttab_open(); - if (xendev->gnttabdev < 0) { - xen_be_printf(NULL, 0, "can't open gnttab device\n"); - xc_evtchn_close(xendev->evtchndev); - qemu_free(xendev); - return NULL; - } + xendev->gnttabdev = xen_xc_gnttab_open(NULL, 0); + if (xendev->gnttabdev == XC_HANDLER_INITIAL_VALUE) { + xen_be_printf(NULL, 0, "can't open gnttab device\n"); + xc_evtchn_close(xendev->evtchndev); + g_free(xendev); + return NULL; + } } else { - xendev->gnttabdev = -1; + xendev->gnttabdev = XC_HANDLER_INITIAL_VALUE; } QTAILQ_INSERT_TAIL(&xendevs, xendev, next); - if (xendev->ops->alloc) - xendev->ops->alloc(xendev); + if (xendev->ops->alloc) { + xendev->ops->alloc(xendev); + } return xendev; } @@ -251,28 +260,33 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev) xendev = xnext; xnext = xendev->next.tqe_next; - if (xendev->dom != dom) - continue; - if (xendev->dev != dev && dev != -1) - continue; - - if (xendev->ops->free) - xendev->ops->free(xendev); - - if (xendev->fe) { - char token[XEN_BUFSIZE]; - snprintf(token, sizeof(token), "fe:%p", xendev); - xs_unwatch(xenstore, xendev->fe, token); - qemu_free(xendev->fe); - } - - if (xendev->evtchndev >= 0) - xc_evtchn_close(xendev->evtchndev); - if (xendev->gnttabdev >= 0) - xc_gnttab_close(xendev->gnttabdev); - - QTAILQ_REMOVE(&xendevs, xendev, next); - qemu_free(xendev); + if (xendev->dom != dom) { + continue; + } + if (xendev->dev != dev && dev != -1) { + continue; + } + + if (xendev->ops->free) { + xendev->ops->free(xendev); + } + + if (xendev->fe) { + char token[XEN_BUFSIZE]; + snprintf(token, sizeof(token), "fe:%p", xendev); + xs_unwatch(xenstore, xendev->fe, token); + g_free(xendev->fe); + } + + if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE) { + xc_evtchn_close(xendev->evtchndev); + } + if (xendev->gnttabdev != XC_HANDLER_INITIAL_VALUE) { + xc_gnttab_close(xendev->gnttabdev); + } + + QTAILQ_REMOVE(&xendevs, xendev, next); + g_free(xendev); } return NULL; } @@ -285,14 +299,16 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev) static void xen_be_backend_changed(struct XenDevice *xendev, const char *node) { if (node == NULL || strcmp(node, "online") == 0) { - if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) - xendev->online = 0; + if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) { + xendev->online = 0; + } } if (node) { - xen_be_printf(xendev, 2, "backend update: %s\n", node); - if (xendev->ops->backend_changed) - xendev->ops->backend_changed(xendev, node); + xen_be_printf(xendev, 2, "backend update: %s\n", node); + if (xendev->ops->backend_changed) { + xendev->ops->backend_changed(xendev, node); + } } } @@ -301,25 +317,29 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node) int fe_state; if (node == NULL || strcmp(node, "state") == 0) { - if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) - fe_state = XenbusStateUnknown; - if (xendev->fe_state != fe_state) - xen_be_printf(xendev, 1, "frontend state: %s -> %s\n", - xenbus_strstate(xendev->fe_state), - xenbus_strstate(fe_state)); - xendev->fe_state = fe_state; + if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) { + fe_state = XenbusStateUnknown; + } + if (xendev->fe_state != fe_state) { + xen_be_printf(xendev, 1, "frontend state: %s -> %s\n", + xenbus_strstate(xendev->fe_state), + xenbus_strstate(fe_state)); + } + xendev->fe_state = fe_state; } if (node == NULL || strcmp(node, "protocol") == 0) { - qemu_free(xendev->protocol); - xendev->protocol = xenstore_read_fe_str(xendev, "protocol"); - if (xendev->protocol) - xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol); + g_free(xendev->protocol); + xendev->protocol = xenstore_read_fe_str(xendev, "protocol"); + if (xendev->protocol) { + xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol); + } } if (node) { - xen_be_printf(xendev, 2, "frontend update: %s\n", node); - if (xendev->ops->frontend_changed) - xendev->ops->frontend_changed(xendev, node); + xen_be_printf(xendev, 2, "frontend update: %s\n", node); + if (xendev->ops->frontend_changed) { + xendev->ops->frontend_changed(xendev, node); + } } } @@ -340,28 +360,28 @@ static int xen_be_try_setup(struct XenDevice *xendev) int be_state; if (xenstore_read_be_int(xendev, "state", &be_state) == -1) { - xen_be_printf(xendev, 0, "reading backend state failed\n"); - return -1; + xen_be_printf(xendev, 0, "reading backend state failed\n"); + return -1; } if (be_state != XenbusStateInitialising) { - xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n", - xenbus_strstate(be_state)); - return -1; + xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n", + xenbus_strstate(be_state)); + return -1; } xendev->fe = xenstore_read_be_str(xendev, "frontend"); if (xendev->fe == NULL) { - xen_be_printf(xendev, 0, "reading frontend path failed\n"); - return -1; + xen_be_printf(xendev, 0, "reading frontend path failed\n"); + return -1; } /* setup frontend watch */ snprintf(token, sizeof(token), "fe:%p", xendev); if (!xs_watch(xenstore, xendev->fe, token)) { - xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n", - xendev->fe); - return -1; + xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n", + xendev->fe); + return -1; } xen_be_set_state(xendev, XenbusStateInitialising); @@ -383,15 +403,16 @@ static int xen_be_try_init(struct XenDevice *xendev) int rc = 0; if (!xendev->online) { - xen_be_printf(xendev, 1, "not online\n"); - return -1; + xen_be_printf(xendev, 1, "not online\n"); + return -1; } - if (xendev->ops->init) - rc = xendev->ops->init(xendev); + if (xendev->ops->init) { + rc = xendev->ops->init(xendev); + } if (rc != 0) { - xen_be_printf(xendev, 1, "init() failed\n"); - return rc; + xen_be_printf(xendev, 1, "init() failed\n"); + return rc; } xenstore_write_be_str(xendev, "hotplug-status", "connected"); @@ -400,31 +421,32 @@ static int xen_be_try_init(struct XenDevice *xendev) } /* - * Try to connect xendev. Depends on the frontend being ready + * Try to initialise xendev. Depends on the frontend being ready * for it (shared ring and evtchn info in xenstore, state being * Initialised or Connected). * * Goes to Connected on success. */ -static int xen_be_try_connect(struct XenDevice *xendev) +static int xen_be_try_initialise(struct XenDevice *xendev) { int rc = 0; if (xendev->fe_state != XenbusStateInitialised && - xendev->fe_state != XenbusStateConnected) { - if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) { - xen_be_printf(xendev, 2, "frontend not ready, ignoring\n"); - } else { - xen_be_printf(xendev, 2, "frontend not ready (yet)\n"); - return -1; - } + xendev->fe_state != XenbusStateConnected) { + if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) { + xen_be_printf(xendev, 2, "frontend not ready, ignoring\n"); + } else { + xen_be_printf(xendev, 2, "frontend not ready (yet)\n"); + return -1; + } } - if (xendev->ops->connect) - rc = xendev->ops->connect(xendev); + if (xendev->ops->initialise) { + rc = xendev->ops->initialise(xendev); + } if (rc != 0) { - xen_be_printf(xendev, 0, "connect() failed\n"); - return rc; + xen_be_printf(xendev, 0, "initialise() failed\n"); + return rc; } xen_be_set_state(xendev, XenbusStateConnected); @@ -432,6 +454,29 @@ static int xen_be_try_connect(struct XenDevice *xendev) } /* + * Try to let xendev know that it is connected. Depends on the + * frontend being Connected. Note that this may be called more + * than once since the backend state is not modified. + */ +static void xen_be_try_connected(struct XenDevice *xendev) +{ + if (!xendev->ops->connected) { + return; + } + + if (xendev->fe_state != XenbusStateConnected) { + if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) { + xen_be_printf(xendev, 2, "frontend not ready, ignoring\n"); + } else { + xen_be_printf(xendev, 2, "frontend not ready (yet)\n"); + return; + } + } + + xendev->ops->connected(xendev); +} + +/* * Teardown connection. * * Goes to Closed when done. @@ -440,10 +485,12 @@ static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state) { if (xendev->be_state != XenbusStateClosing && xendev->be_state != XenbusStateClosed && - xendev->ops->disconnect) - xendev->ops->disconnect(xendev); - if (xendev->be_state != state) + xendev->ops->disconnect) { + xendev->ops->disconnect(xendev); + } + if (xendev->be_state != state) { xen_be_set_state(xendev, state); + } } /* @@ -451,8 +498,9 @@ static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state) */ static int xen_be_try_reset(struct XenDevice *xendev) { - if (xendev->fe_state != XenbusStateInitialising) + if (xendev->fe_state != XenbusStateInitialising) { return -1; + } xen_be_printf(xendev, 1, "device reset (for re-connect)\n"); xen_be_set_state(xendev, XenbusStateInitialising); @@ -468,31 +516,37 @@ void xen_be_check_state(struct XenDevice *xendev) /* frontend may request shutdown from almost anywhere */ if (xendev->fe_state == XenbusStateClosing || - xendev->fe_state == XenbusStateClosed) { - xen_be_disconnect(xendev, xendev->fe_state); - return; + xendev->fe_state == XenbusStateClosed) { + xen_be_disconnect(xendev, xendev->fe_state); + return; } /* check for possible backend state transitions */ for (;;) { - switch (xendev->be_state) { - case XenbusStateUnknown: - rc = xen_be_try_setup(xendev); - break; - case XenbusStateInitialising: - rc = xen_be_try_init(xendev); - break; - case XenbusStateInitWait: - rc = xen_be_try_connect(xendev); - break; + switch (xendev->be_state) { + case XenbusStateUnknown: + rc = xen_be_try_setup(xendev); + break; + case XenbusStateInitialising: + rc = xen_be_try_init(xendev); + break; + case XenbusStateInitWait: + rc = xen_be_try_initialise(xendev); + break; + case XenbusStateConnected: + /* xendev->be_state doesn't change */ + xen_be_try_connected(xendev); + rc = -1; + break; case XenbusStateClosed: rc = xen_be_try_reset(xendev); break; - default: - rc = -1; - } - if (rc != 0) - break; + default: + rc = -1; + } + if (rc != 0) { + break; + } } } @@ -511,26 +565,28 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops) snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom); free(dom0); if (!xs_watch(xenstore, path, token)) { - xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path); - return -1; + xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path); + return -1; } /* look for backends */ dev = xs_directory(xenstore, 0, path, &cdev); - if (!dev) - return 0; + if (!dev) { + return 0; + } for (j = 0; j < cdev; j++) { - xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops); - if (xendev == NULL) - continue; - xen_be_check_state(xendev); + xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops); + if (xendev == NULL) { + continue; + } + xen_be_check_state(xendev); } free(dev); return 0; } static void xenstore_update_be(char *watch, char *type, int dom, - struct XenDevOps *ops) + struct XenDevOps *ops) { struct XenDevice *xendev; char path[XEN_BUFSIZE], *dom0; @@ -539,25 +595,28 @@ static void xenstore_update_be(char *watch, char *type, int dom, dom0 = xs_get_domain_path(xenstore, 0); len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom); free(dom0); - if (strncmp(path, watch, len) != 0) - return; + if (strncmp(path, watch, len) != 0) { + return; + } if (sscanf(watch+len, "/%u/%255s", &dev, path) != 2) { - strcpy(path, ""); - if (sscanf(watch+len, "/%u", &dev) != 1) - dev = -1; + strcpy(path, ""); + if (sscanf(watch+len, "/%u", &dev) != 1) { + dev = -1; + } + } + if (dev == -1) { + return; } - if (dev == -1) - return; if (0) { - /* FIXME: detect devices being deleted from xenstore ... */ - xen_be_del_xendev(dom, dev); + /* FIXME: detect devices being deleted from xenstore ... */ + xen_be_del_xendev(dom, dev); } xendev = xen_be_get_xendev(type, dom, dev, ops); if (xendev != NULL) { - xen_be_backend_changed(xendev, path); - xen_be_check_state(xendev); + xen_be_backend_changed(xendev, path); + xen_be_check_state(xendev); } } @@ -567,10 +626,12 @@ static void xenstore_update_fe(char *watch, struct XenDevice *xendev) unsigned int len; len = strlen(xendev->fe); - if (strncmp(xendev->fe, watch, len) != 0) - return; - if (watch[len] != '/') - return; + if (strncmp(xendev->fe, watch, len) != 0) { + return; + } + if (watch[len] != '/') { + return; + } node = watch + len + 1; xen_be_frontend_changed(xendev, node); @@ -584,14 +645,17 @@ static void xenstore_update(void *unused) unsigned int dom, count; vec = xs_read_watch(xenstore, &count); - if (vec == NULL) - goto cleanup; + if (vec == NULL) { + goto cleanup; + } if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR, - &type, &dom, &ops) == 3) - xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops); - if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) - xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr); + &type, &dom, &ops) == 3) { + xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops); + } + if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) { + xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr); + } cleanup: free(vec); @@ -604,14 +668,15 @@ static void xen_be_evtchn_event(void *opaque) port = xc_evtchn_pending(xendev->evtchndev); if (port != xendev->local_port) { - xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n", - port, xendev->local_port); - return; + xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n", + port, xendev->local_port); + return; } xc_evtchn_unmask(xendev->evtchndev, port); - if (xendev->ops->event) - xendev->ops->event(xendev); + if (xendev->ops->event) { + xendev->ops->event(xendev); + } } /* -------------------------------------------------------------------- */ @@ -620,17 +685,17 @@ int xen_be_init(void) { xenstore = xs_daemon_open(); if (!xenstore) { - xen_be_printf(NULL, 0, "can't connect to xenstored\n"); - return -1; + xen_be_printf(NULL, 0, "can't connect to xenstored\n"); + return -1; } - if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0) - goto err; + if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0) { + goto err; + } - xen_xc = xc_interface_open(); - if (xen_xc == -1) { - xen_be_printf(NULL, 0, "can't open xen interface\n"); - goto err; + if (xen_xc == XC_HANDLER_INITIAL_VALUE) { + /* Check if xen_init() have been called */ + goto err; } return 0; @@ -649,24 +714,26 @@ int xen_be_register(const char *type, struct XenDevOps *ops) int xen_be_bind_evtchn(struct XenDevice *xendev) { - if (xendev->local_port != -1) - return 0; + if (xendev->local_port != -1) { + return 0; + } xendev->local_port = xc_evtchn_bind_interdomain - (xendev->evtchndev, xendev->dom, xendev->remote_port); + (xendev->evtchndev, xendev->dom, xendev->remote_port); if (xendev->local_port == -1) { - xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n"); - return -1; + xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n"); + return -1; } xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), - xen_be_evtchn_event, NULL, xendev); + xen_be_evtchn_event, NULL, xendev); return 0; } void xen_be_unbind_evtchn(struct XenDevice *xendev) { - if (xendev->local_port == -1) - return; + if (xendev->local_port == -1) { + return; + } qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL); xc_evtchn_unbind(xendev->evtchndev, xendev->local_port); xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port); @@ -690,17 +757,21 @@ void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ... va_list args; if (xendev) { - if (msg_level > xendev->debug) + if (msg_level > xendev->debug) { return; + } qemu_log("xen be: %s: ", xendev->name); - if (msg_level == 0) + if (msg_level == 0) { fprintf(stderr, "xen be: %s: ", xendev->name); + } } else { - if (msg_level > debug) + if (msg_level > debug) { return; + } qemu_log("xen be core: "); - if (msg_level == 0) + if (msg_level == 0) { fprintf(stderr, "xen be core: "); + } } va_start(args, fmt); qemu_log_vprintf(fmt, args); diff --git a/hw/xen_backend.h b/hw/xen_backend.h index 1b428e3..3305630 100644 --- a/hw/xen_backend.h +++ b/hw/xen_backend.h @@ -21,7 +21,8 @@ struct XenDevOps { uint32_t flags; void (*alloc)(struct XenDevice *xendev); int (*init)(struct XenDevice *xendev); - int (*connect)(struct XenDevice *xendev); + int (*initialise)(struct XenDevice *xendev); + void (*connected)(struct XenDevice *xendev); void (*event)(struct XenDevice *xendev); void (*disconnect)(struct XenDevice *xendev); int (*free)(struct XenDevice *xendev); @@ -45,8 +46,8 @@ struct XenDevice { int remote_port; int local_port; - int evtchndev; - int gnttabdev; + XenEvtchn evtchndev; + XenGnttab gnttabdev; struct XenDevOps *ops; QTAILQ_ENTRY(XenDevice) next; @@ -55,7 +56,7 @@ struct XenDevice { /* ------------------------------------------------------------- */ /* variables */ -extern int xen_xc; +extern XenXC xen_xc; extern struct xs_handle *xenstore; extern const char *xen_protocol; diff --git a/hw/xen_common.h b/hw/xen_common.h index 8a55b44..0409ac7 100644 --- a/hw/xen_common.h +++ b/hw/xen_common.h @@ -1,6 +1,8 @@ #ifndef QEMU_HW_XEN_COMMON_H #define QEMU_HW_XEN_COMMON_H 1 +#include "config-host.h" + #include #include @@ -13,22 +15,124 @@ #include "qemu-queue.h" /* - * tweaks needed to build with different xen versions - * 0x00030205 -> 3.1.0 - * 0x00030207 -> 3.2.0 - * 0x00030208 -> unstable + * We don't support Xen prior to 3.3.0. */ -#include -#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00030205 -# define evtchn_port_or_error_t int -#endif -#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00030207 -# define xc_map_foreign_pages xc_map_foreign_batch + +/* Xen before 4.0 */ +#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 400 +static inline void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot, + xen_pfn_t *arr, int *err, + unsigned int num) +{ + return xc_map_foreign_batch(xc_handle, dom, prot, arr, num); +} #endif -#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00030208 -# define xen_mb() mb() -# define xen_rmb() rmb() -# define xen_wmb() wmb() + + +/* Xen before 4.1 */ +#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410 + +typedef int XenXC; +typedef int XenEvtchn; +typedef int XenGnttab; + +# define XC_INTERFACE_FMT "%i" +# define XC_HANDLER_INITIAL_VALUE -1 + +static inline XenEvtchn xen_xc_evtchn_open(void *logger, + unsigned int open_flags) +{ + return xc_evtchn_open(); +} + +static inline XenGnttab xen_xc_gnttab_open(void *logger, + unsigned int open_flags) +{ + return xc_gnttab_open(); +} + +static inline XenXC xen_xc_interface_open(void *logger, void *dombuild_logger, + unsigned int open_flags) +{ + return xc_interface_open(); +} + +static inline int xc_fd(int xen_xc) +{ + return xen_xc; +} + + +static inline int xc_domain_populate_physmap_exact + (XenXC xc_handle, uint32_t domid, unsigned long nr_extents, + unsigned int extent_order, unsigned int mem_flags, xen_pfn_t *extent_start) +{ + return xc_domain_memory_populate_physmap + (xc_handle, domid, nr_extents, extent_order, mem_flags, extent_start); +} + +static inline int xc_domain_add_to_physmap(int xc_handle, uint32_t domid, + unsigned int space, unsigned long idx, + xen_pfn_t gpfn) +{ + struct xen_add_to_physmap xatp = { + .domid = domid, + .space = space, + .idx = idx, + .gpfn = gpfn, + }; + + return xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp); +} + +static inline struct xs_handle *xs_open(unsigned long flags) +{ + return xs_daemon_open(); +} + +static inline void xs_close(struct xs_handle *xsh) +{ + if (xsh != NULL) { + xs_daemon_close(xsh); + } +} + + +/* Xen 4.1 */ +#else + +typedef xc_interface *XenXC; +typedef xc_evtchn *XenEvtchn; +typedef xc_gnttab *XenGnttab; + +# define XC_INTERFACE_FMT "%p" +# define XC_HANDLER_INITIAL_VALUE NULL + +static inline XenEvtchn xen_xc_evtchn_open(void *logger, + unsigned int open_flags) +{ + return xc_evtchn_open(logger, open_flags); +} + +static inline XenGnttab xen_xc_gnttab_open(void *logger, + unsigned int open_flags) +{ + return xc_gnttab_open(logger, open_flags); +} + +static inline XenXC xen_xc_interface_open(void *logger, void *dombuild_logger, + unsigned int open_flags) +{ + return xc_interface_open(logger, dombuild_logger, open_flags); +} + +/* FIXME There is now way to have the xen fd */ +static inline int xc_fd(xc_interface *xen_xc) +{ + return -1; +} #endif +void destroy_hvm_domain(void); + #endif /* QEMU_HW_XEN_COMMON_H */ diff --git a/hw/xen_console.c b/hw/xen_console.c index d2261f4..edcb31c 100644 --- a/hw/xen_console.c +++ b/hw/xen_console.c @@ -33,7 +33,6 @@ #include #include "hw.h" -#include "sysemu.h" #include "qemu-char.h" #include "xen_backend.h" @@ -71,7 +70,7 @@ static void buffer_append(struct XenConsole *con) if ((buffer->capacity - buffer->size) < size) { buffer->capacity += (size + 1024); - buffer->data = qemu_realloc(buffer->data, buffer->capacity); + buffer->data = g_realloc(buffer->data, buffer->capacity); } while (cons != prod) @@ -90,7 +89,7 @@ static void buffer_append(struct XenConsole *con) uint8_t *maxpos = buffer->data + buffer->max_capacity; memmove(maxpos - over, maxpos, over); - buffer->data = qemu_realloc(buffer->data, buffer->max_capacity); + buffer->data = g_realloc(buffer->data, buffer->max_capacity); buffer->size = buffer->capacity = buffer->max_capacity; if (buffer->consumed > buffer->max_capacity - over) @@ -157,7 +156,7 @@ static void xencons_send(struct XenConsole *con) size = con->buffer.size - con->buffer.consumed; if (con->chr) - len = qemu_chr_write(con->chr, con->buffer.data + con->buffer.consumed, + len = qemu_chr_fe_write(con->chr, con->buffer.data + con->buffer.consumed, size); else len = size; @@ -180,7 +179,9 @@ static void xencons_send(struct XenConsole *con) static int con_init(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); - char *type, *dom; + char *type, *dom, label[32]; + int ret = 0; + const char *output; /* setup */ dom = xs_get_domain_path(xenstore, con->xendev.dom); @@ -190,19 +191,28 @@ static int con_init(struct XenDevice *xendev) type = xenstore_read_str(con->console, "type"); if (!type || strcmp(type, "ioemu") != 0) { xen_be_printf(xendev, 1, "not for me (type=%s)\n", type); - return -1; + ret = -1; + goto out; } - if (!serial_hds[con->xendev.dev]) - xen_be_printf(xendev, 1, "WARNING: serial line %d not configured\n", - con->xendev.dev); - else + output = xenstore_read_str(con->console, "output"); + + /* no Xen override, use qemu output device */ + if (output == NULL) { con->chr = serial_hds[con->xendev.dev]; + } else { + snprintf(label, sizeof(label), "xencons%d", con->xendev.dev); + con->chr = qemu_chr_new(label, output, NULL); + } - return 0; + xenstore_store_pv_console_info(con->xendev.dev, con->chr); + +out: + g_free(type); + return ret; } -static int con_connect(struct XenDevice *xendev) +static int con_initialise(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); int limit; @@ -263,7 +273,7 @@ struct XenDevOps xen_console_ops = { .size = sizeof(struct XenConsole), .flags = DEVOPS_FLAG_IGNORE_STATE, .init = con_init, - .connect = con_connect, + .initialise = con_initialise, .event = con_event, .disconnect = con_disconnect, }; diff --git a/hw/xen_devconfig.c b/hw/xen_devconfig.c index 8d50216..41accbb 100644 --- a/hw/xen_devconfig.c +++ b/hw/xen_devconfig.c @@ -14,7 +14,7 @@ static void xen_config_cleanup_dir(char *dir) { struct xs_dirs *d; - d = qemu_malloc(sizeof(*d)); + d = g_malloc(sizeof(*d)); d->xs_dir = dir; QTAILQ_INSERT_TAIL(&xs_cleanup, d, list); } @@ -43,7 +43,7 @@ static int xen_config_dev_mkdir(char *dev, int p) xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev); return -1; } - xen_config_cleanup_dir(qemu_strdup(dev)); + xen_config_cleanup_dir(g_strdup(dev)); if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) { xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev); @@ -96,7 +96,7 @@ int xen_config_dev_blk(DriveInfo *disk) { char fe[256], be[256]; int vdev = 202 * 256 + 16 * disk->unit; - int cdrom = disk->bdrv->type == BDRV_TYPE_CDROM; + int cdrom = disk->media_cd; const char *devtype = cdrom ? "cdrom" : "disk"; const char *mode = cdrom ? "r" : "w"; @@ -126,8 +126,8 @@ int xen_config_dev_nic(NICInfo *nic) char mac[20]; snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x", - nic->macaddr[0], nic->macaddr[1], nic->macaddr[2], - nic->macaddr[3], nic->macaddr[4], nic->macaddr[5]); + nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2], + nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]); xen_be_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", nic->vlan->id, mac); xen_config_dev_dirs("vif", "qnic", nic->vlan->id, fe, be, sizeof(fe)); diff --git a/hw/xen_disk.c b/hw/xen_disk.c index ed9e5eb..286bbac 100644 --- a/hw/xen_disk.c +++ b/hw/xen_disk.c @@ -79,6 +79,7 @@ struct ioreq { struct XenBlkDev *blkdev; QLIST_ENTRY(ioreq) list; + BlockAcctCookie acct; }; struct XenBlkDev { @@ -120,17 +121,18 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev) struct ioreq *ioreq = NULL; if (QLIST_EMPTY(&blkdev->freelist)) { - if (blkdev->requests_total >= max_requests) - goto out; - /* allocate new struct */ - ioreq = qemu_mallocz(sizeof(*ioreq)); - ioreq->blkdev = blkdev; - blkdev->requests_total++; + if (blkdev->requests_total >= max_requests) { + goto out; + } + /* allocate new struct */ + ioreq = g_malloc0(sizeof(*ioreq)); + ioreq->blkdev = blkdev; + blkdev->requests_total++; qemu_iovec_init(&ioreq->v, BLKIF_MAX_SEGMENTS_PER_REQUEST); } else { - /* get one from freelist */ - ioreq = QLIST_FIRST(&blkdev->freelist); - QLIST_REMOVE(ioreq, list); + /* get one from freelist */ + ioreq = QLIST_FIRST(&blkdev->freelist); + QLIST_REMOVE(ioreq, list); qemu_iovec_reset(&ioreq->v); } QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list); @@ -173,30 +175,32 @@ static int ioreq_parse(struct ioreq *ioreq) int i; xen_be_printf(&blkdev->xendev, 3, - "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n", - ioreq->req.operation, ioreq->req.nr_segments, - ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number); + "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n", + ioreq->req.operation, ioreq->req.nr_segments, + ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number); switch (ioreq->req.operation) { case BLKIF_OP_READ: - ioreq->prot = PROT_WRITE; /* to memory */ - break; + ioreq->prot = PROT_WRITE; /* to memory */ + break; case BLKIF_OP_WRITE_BARRIER: if (!ioreq->req.nr_segments) { ioreq->presync = 1; return 0; } - if (!syncwrite) - ioreq->presync = ioreq->postsync = 1; - /* fall through */ + if (!syncwrite) { + ioreq->presync = ioreq->postsync = 1; + } + /* fall through */ case BLKIF_OP_WRITE: - ioreq->prot = PROT_READ; /* from memory */ - if (syncwrite) - ioreq->postsync = 1; - break; + ioreq->prot = PROT_READ; /* from memory */ + if (syncwrite) { + ioreq->postsync = 1; + } + break; default: - xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n", - ioreq->req.operation); - goto err; + xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n", + ioreq->req.operation); + goto err; }; if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') { @@ -206,29 +210,29 @@ static int ioreq_parse(struct ioreq *ioreq) ioreq->start = ioreq->req.sector_number * blkdev->file_blk; for (i = 0; i < ioreq->req.nr_segments; i++) { - if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) { - xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n"); - goto err; - } - if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) { - xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n"); - goto err; - } - if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) { - xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n"); - goto err; - } - - ioreq->domids[i] = blkdev->xendev.dom; - ioreq->refs[i] = ioreq->req.seg[i].gref; - - mem = ioreq->req.seg[i].first_sect * blkdev->file_blk; - len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk; + if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) { + xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n"); + goto err; + } + if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) { + xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n"); + goto err; + } + if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) { + xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n"); + goto err; + } + + ioreq->domids[i] = blkdev->xendev.dom; + ioreq->refs[i] = ioreq->req.seg[i].gref; + + mem = ioreq->req.seg[i].first_sect * blkdev->file_blk; + len = (ioreq->req.seg[i].last_sect - ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk; qemu_iovec_add(&ioreq->v, (void*)mem, len); } if (ioreq->start + ioreq->v.size > blkdev->file_size) { - xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n"); - goto err; + xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n"); + goto err; } return 0; @@ -239,66 +243,73 @@ err: static void ioreq_unmap(struct ioreq *ioreq) { - int gnt = ioreq->blkdev->xendev.gnttabdev; + XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev; int i; - if (ioreq->v.niov == 0) + if (ioreq->v.niov == 0) { return; + } if (batch_maps) { - if (!ioreq->pages) - return; - if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0) - xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n", - strerror(errno)); - ioreq->blkdev->cnt_map -= ioreq->v.niov; - ioreq->pages = NULL; + if (!ioreq->pages) { + return; + } + if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0) { + xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n", + strerror(errno)); + } + ioreq->blkdev->cnt_map -= ioreq->v.niov; + ioreq->pages = NULL; } else { - for (i = 0; i < ioreq->v.niov; i++) { - if (!ioreq->page[i]) - continue; - if (xc_gnttab_munmap(gnt, ioreq->page[i], 1) != 0) - xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n", - strerror(errno)); - ioreq->blkdev->cnt_map--; - ioreq->page[i] = NULL; - } + for (i = 0; i < ioreq->v.niov; i++) { + if (!ioreq->page[i]) { + continue; + } + if (xc_gnttab_munmap(gnt, ioreq->page[i], 1) != 0) { + xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n", + strerror(errno)); + } + ioreq->blkdev->cnt_map--; + ioreq->page[i] = NULL; + } } } static int ioreq_map(struct ioreq *ioreq) { - int gnt = ioreq->blkdev->xendev.gnttabdev; + XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev; int i; - if (ioreq->v.niov == 0) + if (ioreq->v.niov == 0) { return 0; + } if (batch_maps) { - ioreq->pages = xc_gnttab_map_grant_refs - (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot); - if (ioreq->pages == NULL) { - xen_be_printf(&ioreq->blkdev->xendev, 0, - "can't map %d grant refs (%s, %d maps)\n", - ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map); - return -1; - } - for (i = 0; i < ioreq->v.niov; i++) - ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE + - (uintptr_t)ioreq->v.iov[i].iov_base; - ioreq->blkdev->cnt_map += ioreq->v.niov; + ioreq->pages = xc_gnttab_map_grant_refs + (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot); + if (ioreq->pages == NULL) { + xen_be_printf(&ioreq->blkdev->xendev, 0, + "can't map %d grant refs (%s, %d maps)\n", + ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map); + return -1; + } + for (i = 0; i < ioreq->v.niov; i++) { + ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE + + (uintptr_t)ioreq->v.iov[i].iov_base; + } + ioreq->blkdev->cnt_map += ioreq->v.niov; } else { - for (i = 0; i < ioreq->v.niov; i++) { - ioreq->page[i] = xc_gnttab_map_grant_ref - (gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot); - if (ioreq->page[i] == NULL) { - xen_be_printf(&ioreq->blkdev->xendev, 0, - "can't map grant ref %d (%s, %d maps)\n", - ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map); - ioreq_unmap(ioreq); - return -1; - } - ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base; - ioreq->blkdev->cnt_map++; - } + for (i = 0; i < ioreq->v.niov; i++) { + ioreq->page[i] = xc_gnttab_map_grant_ref + (gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot); + if (ioreq->page[i] == NULL) { + xen_be_printf(&ioreq->blkdev->xendev, 0, + "can't map grant ref %d (%s, %d maps)\n", + ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map); + ioreq_unmap(ioreq); + return -1; + } + ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base; + ioreq->blkdev->cnt_map++; + } } return 0; } @@ -306,57 +317,59 @@ static int ioreq_map(struct ioreq *ioreq) static int ioreq_runio_qemu_sync(struct ioreq *ioreq) { struct XenBlkDev *blkdev = ioreq->blkdev; - int i, rc, len = 0; + int i, rc; off_t pos; - if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1) - goto err; - if (ioreq->presync) - bdrv_flush(blkdev->bs); + if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1) { + goto err_no_map; + } + if (ioreq->presync) { + bdrv_flush(blkdev->bs); + } switch (ioreq->req.operation) { case BLKIF_OP_READ: - pos = ioreq->start; - for (i = 0; i < ioreq->v.niov; i++) { - rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE, - ioreq->v.iov[i].iov_base, - ioreq->v.iov[i].iov_len / BLOCK_SIZE); - if (rc != 0) { - xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n", - ioreq->v.iov[i].iov_base, - ioreq->v.iov[i].iov_len); - goto err; - } - len += ioreq->v.iov[i].iov_len; - pos += ioreq->v.iov[i].iov_len; - } - break; + pos = ioreq->start; + for (i = 0; i < ioreq->v.niov; i++) { + rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE, + ioreq->v.iov[i].iov_base, + ioreq->v.iov[i].iov_len / BLOCK_SIZE); + if (rc != 0) { + xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n", + ioreq->v.iov[i].iov_base, + ioreq->v.iov[i].iov_len); + goto err; + } + pos += ioreq->v.iov[i].iov_len; + } + break; case BLKIF_OP_WRITE: case BLKIF_OP_WRITE_BARRIER: - if (!ioreq->req.nr_segments) + if (!ioreq->req.nr_segments) { break; - pos = ioreq->start; - for (i = 0; i < ioreq->v.niov; i++) { - rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE, - ioreq->v.iov[i].iov_base, - ioreq->v.iov[i].iov_len / BLOCK_SIZE); - if (rc != 0) { - xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n", - ioreq->v.iov[i].iov_base, - ioreq->v.iov[i].iov_len); - goto err; - } - len += ioreq->v.iov[i].iov_len; - pos += ioreq->v.iov[i].iov_len; - } - break; + } + pos = ioreq->start; + for (i = 0; i < ioreq->v.niov; i++) { + rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE, + ioreq->v.iov[i].iov_base, + ioreq->v.iov[i].iov_len / BLOCK_SIZE); + if (rc != 0) { + xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n", + ioreq->v.iov[i].iov_base, + ioreq->v.iov[i].iov_len); + goto err; + } + pos += ioreq->v.iov[i].iov_len; + } + break; default: - /* unknown operation (shouldn't happen -- parse catches this) */ - goto err; + /* unknown operation (shouldn't happen -- parse catches this) */ + goto err; } - if (ioreq->postsync) - bdrv_flush(blkdev->bs); + if (ioreq->postsync) { + bdrv_flush(blkdev->bs); + } ioreq->status = BLKIF_RSP_OKAY; ioreq_unmap(ioreq); @@ -364,6 +377,9 @@ static int ioreq_runio_qemu_sync(struct ioreq *ioreq) return 0; err: + ioreq_unmap(ioreq); +err_no_map: + ioreq_finish(ioreq); ioreq->status = BLKIF_RSP_ERROR; return -1; } @@ -379,12 +395,14 @@ static void qemu_aio_complete(void *opaque, int ret) } ioreq->aio_inflight--; - if (ioreq->aio_inflight > 0) + if (ioreq->aio_inflight > 0) { return; + } ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY; ioreq_unmap(ioreq); ioreq_finish(ioreq); + bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct); qemu_bh_schedule(ioreq->blkdev->bh); } @@ -392,41 +410,51 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) { struct XenBlkDev *blkdev = ioreq->blkdev; - if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1) - goto err; + if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1) { + goto err_no_map; + } ioreq->aio_inflight++; - if (ioreq->presync) - bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */ + if (ioreq->presync) { + bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */ + } switch (ioreq->req.operation) { case BLKIF_OP_READ: + bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_READ); ioreq->aio_inflight++; bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE, &ioreq->v, ioreq->v.size / BLOCK_SIZE, qemu_aio_complete, ioreq); - break; + break; case BLKIF_OP_WRITE: case BLKIF_OP_WRITE_BARRIER: - ioreq->aio_inflight++; - if (!ioreq->req.nr_segments) + if (!ioreq->req.nr_segments) { break; + } + + bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_WRITE); + ioreq->aio_inflight++; bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE, &ioreq->v, ioreq->v.size / BLOCK_SIZE, qemu_aio_complete, ioreq); - break; + break; default: - /* unknown operation (shouldn't happen -- parse catches this) */ - goto err; + /* unknown operation (shouldn't happen -- parse catches this) */ + goto err; } - if (ioreq->postsync) - bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */ + if (ioreq->postsync) { + bdrv_flush(blkdev->bs); /* FIXME: aio_flush() ??? */ + } qemu_aio_complete(ioreq, 0); return 0; err: + ioreq_unmap(ioreq); +err_no_map: + ioreq_finish(ioreq); ioreq->status = BLKIF_RSP_ERROR; return -1; } @@ -446,36 +474,37 @@ static int blk_send_response_one(struct ioreq *ioreq) /* Place on the response ring for the relevant domain. */ switch (blkdev->protocol) { case BLKIF_PROTOCOL_NATIVE: - dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt); - break; + dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt); + break; case BLKIF_PROTOCOL_X86_32: dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part, blkdev->rings.x86_32_part.rsp_prod_pvt); - break; + break; case BLKIF_PROTOCOL_X86_64: dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part, blkdev->rings.x86_64_part.rsp_prod_pvt); - break; + break; default: - dst = NULL; + dst = NULL; } memcpy(dst, &resp, sizeof(resp)); blkdev->rings.common.rsp_prod_pvt++; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify); if (blkdev->rings.common.rsp_prod_pvt == blkdev->rings.common.req_cons) { - /* - * Tail check for pending requests. Allows frontend to avoid - * notifications if requests are already in flight (lower - * overheads and promotes batching). - */ - RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests); + /* + * Tail check for pending requests. Allows frontend to avoid + * notifications if requests are already in flight (lower + * overheads and promotes batching). + */ + RING_FINAL_CHECK_FOR_REQUESTS(&blkdev->rings.common, have_requests); } else if (RING_HAS_UNCONSUMED_REQUESTS(&blkdev->rings.common)) { - have_requests = 1; + have_requests = 1; } - if (have_requests) - blkdev->more_work++; + if (have_requests) { + blkdev->more_work++; + } return send_notify; } @@ -487,28 +516,29 @@ static void blk_send_response_all(struct XenBlkDev *blkdev) while (!QLIST_EMPTY(&blkdev->finished)) { ioreq = QLIST_FIRST(&blkdev->finished); - send_notify += blk_send_response_one(ioreq); - ioreq_release(ioreq); + send_notify += blk_send_response_one(ioreq); + ioreq_release(ioreq); + } + if (send_notify) { + xen_be_send_notify(&blkdev->xendev); } - if (send_notify) - xen_be_send_notify(&blkdev->xendev); } static int blk_get_request(struct XenBlkDev *blkdev, struct ioreq *ioreq, RING_IDX rc) { switch (blkdev->protocol) { case BLKIF_PROTOCOL_NATIVE: - memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc), - sizeof(ioreq->req)); - break; + memcpy(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.native, rc), + sizeof(ioreq->req)); + break; case BLKIF_PROTOCOL_X86_32: blkif_get_x86_32_req(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.x86_32_part, rc)); - break; + break; case BLKIF_PROTOCOL_X86_64: blkif_get_x86_64_req(&ioreq->req, RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc)); - break; + break; } return 0; } @@ -524,12 +554,14 @@ static void blk_handle_requests(struct XenBlkDev *blkdev) rp = blkdev->rings.common.sring->req_prod; xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ - if (use_aio) + if (use_aio) { blk_send_response_all(blkdev); + } while (rc != rp) { /* pull request from ring */ - if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) + if (RING_REQUEST_CONS_OVERFLOW(&blkdev->rings.common, rc)) { break; + } ioreq = ioreq_start(blkdev); if (ioreq == NULL) { blkdev->more_work++; @@ -540,8 +572,9 @@ static void blk_handle_requests(struct XenBlkDev *blkdev) /* parse them */ if (ioreq_parse(ioreq) != 0) { - if (blk_send_response_one(ioreq)) + if (blk_send_response_one(ioreq)) { xen_be_send_notify(&blkdev->xendev); + } ioreq_release(ioreq); continue; } @@ -554,11 +587,13 @@ static void blk_handle_requests(struct XenBlkDev *blkdev) ioreq_runio_qemu_sync(ioreq); } } - if (!use_aio) + if (!use_aio) { blk_send_response_all(blkdev); + } - if (blkdev->more_work && blkdev->requests_inflight < max_requests) + if (blkdev->more_work && blkdev->requests_inflight < max_requests) { qemu_bh_schedule(blkdev->bh); + } } /* ------------------------------------------------------------- */ @@ -577,56 +612,68 @@ static void blk_alloc(struct XenDevice *xendev) QLIST_INIT(&blkdev->finished); QLIST_INIT(&blkdev->freelist); blkdev->bh = qemu_bh_new(blk_bh, blkdev); - if (xen_mode != XEN_EMULATE) + if (xen_mode != XEN_EMULATE) { batch_maps = 1; + } } static int blk_init(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); - int index, qflags, have_barriers, info = 0; - char *h; + int index, qflags, info = 0; /* read xenstore entries */ if (blkdev->params == NULL) { - blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params"); - h = strchr(blkdev->params, ':'); - if (h != NULL) { - blkdev->fileproto = blkdev->params; - blkdev->filename = h+1; - *h = 0; - } else { - blkdev->fileproto = ""; - blkdev->filename = blkdev->params; - } - } - if (blkdev->mode == NULL) - blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode"); - if (blkdev->type == NULL) - blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type"); - if (blkdev->dev == NULL) - blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev"); - if (blkdev->devtype == NULL) - blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type"); + char *h = NULL; + blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params"); + if (blkdev->params != NULL) { + h = strchr(blkdev->params, ':'); + } + if (h != NULL) { + blkdev->fileproto = blkdev->params; + blkdev->filename = h+1; + *h = 0; + } else { + blkdev->fileproto = ""; + blkdev->filename = blkdev->params; + } + } + if (!strcmp("aio", blkdev->fileproto)) { + blkdev->fileproto = "raw"; + } + if (blkdev->mode == NULL) { + blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode"); + } + if (blkdev->type == NULL) { + blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type"); + } + if (blkdev->dev == NULL) { + blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev"); + } + if (blkdev->devtype == NULL) { + blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type"); + } /* do we have all we need? */ if (blkdev->params == NULL || - blkdev->mode == NULL || - blkdev->type == NULL || - blkdev->dev == NULL) - return -1; + blkdev->mode == NULL || + blkdev->type == NULL || + blkdev->dev == NULL) { + goto out_error; + } /* read-only ? */ if (strcmp(blkdev->mode, "w") == 0) { - qflags = BDRV_O_RDWR; + qflags = BDRV_O_RDWR; } else { - qflags = 0; - info |= VDISK_READONLY; + qflags = 0; + info |= VDISK_READONLY; } /* cdrom ? */ - if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) - info |= VDISK_CDROM; + if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) { + info |= VDISK_CDROM; + } /* init qemu block driver */ index = (blkdev->xendev.dev - 202 * 256) / 16; @@ -635,95 +682,118 @@ static int blk_init(struct XenDevice *xendev) /* setup via xenbus -> create new block driver instance */ xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); blkdev->bs = bdrv_new(blkdev->dev); - if (bdrv_open(blkdev->bs, blkdev->filename, qflags, - bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) { - bdrv_delete(blkdev->bs); - return -1; + if (blkdev->bs) { + if (bdrv_open(blkdev->bs, blkdev->filename, qflags, + bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) { + bdrv_delete(blkdev->bs); + blkdev->bs = NULL; + } + } + if (!blkdev->bs) { + goto out_error; } } else { /* setup via qemu cmdline -> already setup for us */ xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); - blkdev->bs = blkdev->dinfo->bdrv; + blkdev->bs = blkdev->dinfo->bdrv; } + bdrv_attach_dev_nofail(blkdev->bs, blkdev); blkdev->file_blk = BLOCK_SIZE; blkdev->file_size = bdrv_getlength(blkdev->bs); if (blkdev->file_size < 0) { xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n", (int)blkdev->file_size, strerror(-blkdev->file_size), blkdev->bs->drv ? blkdev->bs->drv->format_name : "-"); - blkdev->file_size = 0; + blkdev->file_size = 0; } - have_barriers = blkdev->bs->drv && blkdev->bs->drv->bdrv_flush ? 1 : 0; xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\"," - " size %" PRId64 " (%" PRId64 " MB)\n", - blkdev->type, blkdev->fileproto, blkdev->filename, - blkdev->file_size, blkdev->file_size >> 20); + " size %" PRId64 " (%" PRId64 " MB)\n", + blkdev->type, blkdev->fileproto, blkdev->filename, + blkdev->file_size, blkdev->file_size >> 20); /* fill info */ - xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers); + xenstore_write_be_int(&blkdev->xendev, "feature-barrier", 1); xenstore_write_be_int(&blkdev->xendev, "info", info); xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk); xenstore_write_be_int(&blkdev->xendev, "sectors", - blkdev->file_size / blkdev->file_blk); + blkdev->file_size / blkdev->file_blk); return 0; + +out_error: + g_free(blkdev->params); + blkdev->params = NULL; + g_free(blkdev->mode); + blkdev->mode = NULL; + g_free(blkdev->type); + blkdev->type = NULL; + g_free(blkdev->dev); + blkdev->dev = NULL; + g_free(blkdev->devtype); + blkdev->devtype = NULL; + return -1; } static int blk_connect(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); - if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1) - return -1; + if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1) { + return -1; + } if (xenstore_read_fe_int(&blkdev->xendev, "event-channel", - &blkdev->xendev.remote_port) == -1) - return -1; + &blkdev->xendev.remote_port) == -1) { + return -1; + } blkdev->protocol = BLKIF_PROTOCOL_NATIVE; if (blkdev->xendev.protocol) { - if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_32) == 0) + if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_32) == 0) { blkdev->protocol = BLKIF_PROTOCOL_X86_32; - if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_64) == 0) + } + if (strcmp(blkdev->xendev.protocol, XEN_IO_PROTO_ABI_X86_64) == 0) { blkdev->protocol = BLKIF_PROTOCOL_X86_64; + } } blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev, - blkdev->xendev.dom, - blkdev->ring_ref, - PROT_READ | PROT_WRITE); - if (!blkdev->sring) - return -1; + blkdev->xendev.dom, + blkdev->ring_ref, + PROT_READ | PROT_WRITE); + if (!blkdev->sring) { + return -1; + } blkdev->cnt_map++; switch (blkdev->protocol) { case BLKIF_PROTOCOL_NATIVE: { - blkif_sring_t *sring_native = blkdev->sring; - BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE); - break; + blkif_sring_t *sring_native = blkdev->sring; + BACK_RING_INIT(&blkdev->rings.native, sring_native, XC_PAGE_SIZE); + break; } case BLKIF_PROTOCOL_X86_32: { - blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring; + blkif_x86_32_sring_t *sring_x86_32 = blkdev->sring; BACK_RING_INIT(&blkdev->rings.x86_32_part, sring_x86_32, XC_PAGE_SIZE); - break; + break; } case BLKIF_PROTOCOL_X86_64: { - blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring; + blkif_x86_64_sring_t *sring_x86_64 = blkdev->sring; BACK_RING_INIT(&blkdev->rings.x86_64_part, sring_x86_64, XC_PAGE_SIZE); - break; + break; } } xen_be_bind_evtchn(&blkdev->xendev); xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, " - "remote port %d, local port %d\n", - blkdev->xendev.protocol, blkdev->ring_ref, - blkdev->xendev.remote_port, blkdev->xendev.local_port); + "remote port %d, local port %d\n", + blkdev->xendev.protocol, blkdev->ring_ref, + blkdev->xendev.remote_port, blkdev->xendev.local_port); return 0; } @@ -737,14 +807,14 @@ static void blk_disconnect(struct XenDevice *xendev) bdrv_close(blkdev->bs); bdrv_delete(blkdev->bs); } - blkdev->bs = NULL; + blkdev->bs = NULL; } xen_be_unbind_evtchn(&blkdev->xendev); if (blkdev->sring) { - xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1); - blkdev->cnt_map--; - blkdev->sring = NULL; + xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1); + blkdev->cnt_map--; + blkdev->sring = NULL; } } @@ -754,17 +824,17 @@ static int blk_free(struct XenDevice *xendev) struct ioreq *ioreq; while (!QLIST_EMPTY(&blkdev->freelist)) { - ioreq = QLIST_FIRST(&blkdev->freelist); + ioreq = QLIST_FIRST(&blkdev->freelist); QLIST_REMOVE(ioreq, list); qemu_iovec_destroy(&ioreq->v); - qemu_free(ioreq); + g_free(ioreq); } - qemu_free(blkdev->params); - qemu_free(blkdev->mode); - qemu_free(blkdev->type); - qemu_free(blkdev->dev); - qemu_free(blkdev->devtype); + g_free(blkdev->params); + g_free(blkdev->mode); + g_free(blkdev->type); + g_free(blkdev->dev); + g_free(blkdev->devtype); qemu_bh_delete(blkdev->bh); return 0; } @@ -781,7 +851,7 @@ struct XenDevOps xen_blkdev_ops = { .flags = DEVOPS_FLAG_NEED_GNTDEV, .alloc = blk_alloc, .init = blk_init, - .connect = blk_connect, + .initialise = blk_connect, .disconnect = blk_disconnect, .event = blk_event, .free = blk_free, diff --git a/hw/xen_domainbuild.c b/hw/xen_domainbuild.c index 7f1fd66..a6a12e5 100644 --- a/hw/xen_domainbuild.c +++ b/hw/xen_domainbuild.c @@ -1,7 +1,6 @@ #include #include "xen_backend.h" #include "xen_domainbuild.h" -#include "sysemu.h" #include "qemu-timer.h" #include "qemu-log.h" @@ -149,7 +148,7 @@ static void xen_domain_poll(void *opaque) goto quit; } - qemu_mod_timer(xen_poll, qemu_get_clock(rt_clock) + 1000); + qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000); return; quit: @@ -176,8 +175,9 @@ static int xen_domain_watcher(void) for (i = 3; i < n; i++) { if (i == fd[0]) continue; - if (i == xen_xc) + if (i == xc_fd(xen_xc)) { continue; + } close(i); } @@ -291,8 +291,8 @@ int xen_domain_build_pv(const char *kernel, const char *ramdisk, goto err; } - xen_poll = qemu_new_timer(rt_clock, xen_domain_poll, NULL); - qemu_mod_timer(xen_poll, qemu_get_clock(rt_clock) + 1000); + xen_poll = qemu_new_timer_ms(rt_clock, xen_domain_poll, NULL); + qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000); return 0; err: diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c index 77a34bf..7985d11 100644 --- a/hw/xen_machine_pv.c +++ b/hw/xen_machine_pv.c @@ -24,7 +24,6 @@ #include "hw.h" #include "pc.h" -#include "sysemu.h" #include "boards.h" #include "xen_backend.h" #include "xen_domainbuild.h" @@ -114,6 +113,7 @@ static QEMUMachine xenpv_machine = { .desc = "Xen Para-virtualized PC", .init = xen_init_pv, .max_cpus = 1, + .default_machine_opts = "accel=xen", }; static void xenpv_machine_init(void) diff --git a/hw/xen_nic.c b/hw/xen_nic.c index 08055b8..ef2a2d6 100644 --- a/hw/xen_nic.c +++ b/hw/xen_nic.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -74,20 +73,23 @@ static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, i resp->status = st; #if 0 - if (txp->flags & NETTXF_extra_info) - RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL; + if (txp->flags & NETTXF_extra_info) { + RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL; + } #endif netdev->tx_ring.rsp_prod_pvt = ++i; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify); - if (notify) - xen_be_send_notify(&netdev->xendev); + if (notify) { + xen_be_send_notify(&netdev->xendev); + } if (i == netdev->tx_ring.req_cons) { - int more_to_do; - RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do); - if (more_to_do) - netdev->tx_work++; + int more_to_do; + RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do); + if (more_to_do) { + netdev->tx_work++; + } } } @@ -101,10 +103,11 @@ static void net_tx_error(struct XenNetDev *netdev, netif_tx_request_t *txp, RING RING_IDX cons = netdev->tx_ring.req_cons; do { - make_tx_response(netif, txp, NETIF_RSP_ERROR); - if (cons >= end) - break; - txp = RING_GET_REQUEST(&netdev->tx_ring, cons++); + make_tx_response(netif, txp, NETIF_RSP_ERROR); + if (cons >= end) { + break; + } + txp = RING_GET_REQUEST(&netdev->tx_ring, cons++); } while (1); netdev->tx_ring.req_cons = cons; netif_schedule_work(netif); @@ -122,85 +125,88 @@ static void net_tx_packets(struct XenNetDev *netdev) void *tmpbuf = NULL; for (;;) { - rc = netdev->tx_ring.req_cons; - rp = netdev->tx_ring.sring->req_prod; - xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ + rc = netdev->tx_ring.req_cons; + rp = netdev->tx_ring.sring->req_prod; + xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ - while ((rc != rp)) { - if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc)) - break; - memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq)); - netdev->tx_ring.req_cons = ++rc; + while ((rc != rp)) { + if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc)) { + break; + } + memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq)); + netdev->tx_ring.req_cons = ++rc; #if 1 - /* should not happen in theory, we don't announce the * - * feature-{sg,gso,whatelse} flags in xenstore (yet?) */ - if (txreq.flags & NETTXF_extra_info) { - xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n"); - net_tx_error(netdev, &txreq, rc); - continue; - } - if (txreq.flags & NETTXF_more_data) { - xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n"); - net_tx_error(netdev, &txreq, rc); - continue; - } + /* should not happen in theory, we don't announce the * + * feature-{sg,gso,whatelse} flags in xenstore (yet?) */ + if (txreq.flags & NETTXF_extra_info) { + xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n"); + net_tx_error(netdev, &txreq, rc); + continue; + } + if (txreq.flags & NETTXF_more_data) { + xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n"); + net_tx_error(netdev, &txreq, rc); + continue; + } #endif - if (txreq.size < 14) { - xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size); - net_tx_error(netdev, &txreq, rc); - continue; - } - - if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) { - xen_be_printf(&netdev->xendev, 0, "error: page crossing\n"); - net_tx_error(netdev, &txreq, rc); - continue; - } - - xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n", - txreq.gref, txreq.offset, txreq.size, txreq.flags, - (txreq.flags & NETTXF_csum_blank) ? " csum_blank" : "", - (txreq.flags & NETTXF_data_validated) ? " data_validated" : "", - (txreq.flags & NETTXF_more_data) ? " more_data" : "", - (txreq.flags & NETTXF_extra_info) ? " extra_info" : ""); - - page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev, - netdev->xendev.dom, - txreq.gref, PROT_READ); - if (page == NULL) { - xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n", + if (txreq.size < 14) { + xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size); + net_tx_error(netdev, &txreq, rc); + continue; + } + + if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) { + xen_be_printf(&netdev->xendev, 0, "error: page crossing\n"); + net_tx_error(netdev, &txreq, rc); + continue; + } + + xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n", + txreq.gref, txreq.offset, txreq.size, txreq.flags, + (txreq.flags & NETTXF_csum_blank) ? " csum_blank" : "", + (txreq.flags & NETTXF_data_validated) ? " data_validated" : "", + (txreq.flags & NETTXF_more_data) ? " more_data" : "", + (txreq.flags & NETTXF_extra_info) ? " extra_info" : ""); + + page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev, + netdev->xendev.dom, + txreq.gref, PROT_READ); + if (page == NULL) { + xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n", txreq.gref); - net_tx_error(netdev, &txreq, rc); - continue; - } - if (txreq.flags & NETTXF_csum_blank) { + net_tx_error(netdev, &txreq, rc); + continue; + } + if (txreq.flags & NETTXF_csum_blank) { /* have read-only mapping -> can't fill checksum in-place */ - if (!tmpbuf) - tmpbuf = qemu_malloc(XC_PAGE_SIZE); + if (!tmpbuf) { + tmpbuf = g_malloc(XC_PAGE_SIZE); + } memcpy(tmpbuf, page + txreq.offset, txreq.size); - net_checksum_calculate(tmpbuf, txreq.size); + net_checksum_calculate(tmpbuf, txreq.size); qemu_send_packet(&netdev->nic->nc, tmpbuf, txreq.size); } else { qemu_send_packet(&netdev->nic->nc, page + txreq.offset, txreq.size); } - xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1); - net_tx_response(netdev, &txreq, NETIF_RSP_OKAY); - } - if (!netdev->tx_work) - break; - netdev->tx_work = 0; + xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1); + net_tx_response(netdev, &txreq, NETIF_RSP_OKAY); + } + if (!netdev->tx_work) { + break; + } + netdev->tx_work = 0; } - qemu_free(tmpbuf); + g_free(tmpbuf); } /* ------------------------------------------------------------- */ static void net_rx_response(struct XenNetDev *netdev, - netif_rx_request_t *req, int8_t st, - uint16_t offset, uint16_t size, - uint16_t flags) + netif_rx_request_t *req, int8_t st, + uint16_t offset, uint16_t size, + uint16_t flags) { RING_IDX i = netdev->rx_ring.rsp_prod_pvt; netif_rx_response_t *resp; @@ -211,16 +217,18 @@ static void net_rx_response(struct XenNetDev *netdev, resp->flags = flags; resp->id = req->id; resp->status = (int16_t)size; - if (st < 0) - resp->status = (int16_t)st; + if (st < 0) { + resp->status = (int16_t)st; + } xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n", - i, resp->status, resp->flags); + i, resp->status, resp->flags); netdev->rx_ring.rsp_prod_pvt = ++i; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify); - if (notify) - xen_be_send_notify(&netdev->xendev); + if (notify) { + xen_be_send_notify(&netdev->xendev); + } } #define NET_IP_ALIGN 2 @@ -230,17 +238,18 @@ static int net_rx_ok(VLANClientState *nc) struct XenNetDev *netdev = DO_UPCAST(NICState, nc, nc)->opaque; RING_IDX rc, rp; - if (netdev->xendev.be_state != XenbusStateConnected) - return 0; + if (netdev->xendev.be_state != XenbusStateConnected) { + return 0; + } rc = netdev->rx_ring.req_cons; rp = netdev->rx_ring.sring->req_prod; xen_rmb(); if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) { - xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n", - __FUNCTION__, rc, rp); - return 0; + xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n", + __FUNCTION__, rc, rp); + return 0; } return 1; } @@ -252,34 +261,35 @@ static ssize_t net_rx_packet(VLANClientState *nc, const uint8_t *buf, size_t siz RING_IDX rc, rp; void *page; - if (netdev->xendev.be_state != XenbusStateConnected) - return -1; + if (netdev->xendev.be_state != XenbusStateConnected) { + return -1; + } rc = netdev->rx_ring.req_cons; rp = netdev->rx_ring.sring->req_prod; xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) { - xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n"); - return -1; + xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n"); + return -1; } if (size > XC_PAGE_SIZE - NET_IP_ALIGN) { - xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)", - (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN); - return -1; + xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)", + (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN); + return -1; } memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq)); netdev->rx_ring.req_cons = ++rc; page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev, - netdev->xendev.dom, - rxreq.gref, PROT_WRITE); + netdev->xendev.dom, + rxreq.gref, PROT_WRITE); if (page == NULL) { - xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n", + xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n", rxreq.gref); - net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0); - return -1; + net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0); + return -1; } memcpy(page + NET_IP_ALIGN, buf, size); xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1); @@ -302,15 +312,18 @@ static int net_init(struct XenDevice *xendev) struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev); /* read xenstore entries */ - if (netdev->mac == NULL) - netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac"); + if (netdev->mac == NULL) { + netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac"); + } /* do we have all we need? */ - if (netdev->mac == NULL) - return -1; + if (netdev->mac == NULL) { + return -1; + } - if (net_parse_macaddr(netdev->conf.macaddr.a, netdev->mac) < 0) + if (net_parse_macaddr(netdev->conf.macaddr.a, netdev->mac) < 0) { return -1; + } netdev->conf.vlan = qemu_find_vlan(netdev->xendev.dev, 1); netdev->conf.peer = NULL; @@ -334,41 +347,46 @@ static int net_connect(struct XenDevice *xendev) int rx_copy; if (xenstore_read_fe_int(&netdev->xendev, "tx-ring-ref", - &netdev->tx_ring_ref) == -1) - return -1; + &netdev->tx_ring_ref) == -1) { + return -1; + } if (xenstore_read_fe_int(&netdev->xendev, "rx-ring-ref", - &netdev->rx_ring_ref) == -1) - return 1; + &netdev->rx_ring_ref) == -1) { + return 1; + } if (xenstore_read_fe_int(&netdev->xendev, "event-channel", - &netdev->xendev.remote_port) == -1) - return -1; + &netdev->xendev.remote_port) == -1) { + return -1; + } - if (xenstore_read_fe_int(&netdev->xendev, "request-rx-copy", &rx_copy) == -1) - rx_copy = 0; + if (xenstore_read_fe_int(&netdev->xendev, "request-rx-copy", &rx_copy) == -1) { + rx_copy = 0; + } if (rx_copy == 0) { - xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n"); - return -1; + xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n"); + return -1; } netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev, - netdev->xendev.dom, - netdev->tx_ring_ref, - PROT_READ | PROT_WRITE); + netdev->xendev.dom, + netdev->tx_ring_ref, + PROT_READ | PROT_WRITE); netdev->rxs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev, - netdev->xendev.dom, - netdev->rx_ring_ref, - PROT_READ | PROT_WRITE); - if (!netdev->txs || !netdev->rxs) - return -1; + netdev->xendev.dom, + netdev->rx_ring_ref, + PROT_READ | PROT_WRITE); + if (!netdev->txs || !netdev->rxs) { + return -1; + } BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XC_PAGE_SIZE); BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XC_PAGE_SIZE); xen_be_bind_evtchn(&netdev->xendev); xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, " - "remote port %d, local port %d\n", - netdev->tx_ring_ref, netdev->rx_ring_ref, - netdev->xendev.remote_port, netdev->xendev.local_port); + "remote port %d, local port %d\n", + netdev->tx_ring_ref, netdev->rx_ring_ref, + netdev->xendev.remote_port, netdev->xendev.local_port); net_tx_packets(netdev); return 0; @@ -381,12 +399,12 @@ static void net_disconnect(struct XenDevice *xendev) xen_be_unbind_evtchn(&netdev->xendev); if (netdev->txs) { - xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1); - netdev->txs = NULL; + xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1); + netdev->txs = NULL; } if (netdev->rxs) { - xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1); - netdev->rxs = NULL; + xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1); + netdev->rxs = NULL; } if (netdev->nic) { qemu_del_vlan_client(&netdev->nic->nc); @@ -404,7 +422,7 @@ static int net_free(struct XenDevice *xendev) { struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev); - qemu_free(netdev->mac); + g_free(netdev->mac); return 0; } @@ -414,7 +432,7 @@ struct XenDevOps xen_netdev_ops = { .size = sizeof(struct XenNetDev), .flags = DEVOPS_FLAG_NEED_GNTDEV, .init = net_init, - .connect = net_connect, + .initialise = net_connect, .event = net_event, .disconnect = net_disconnect, .free = net_free, diff --git a/hw/xenfb.c b/hw/xenfb.c index da5297b..1bcf171 100644 --- a/hw/xenfb.c +++ b/hw/xenfb.c @@ -44,7 +44,6 @@ #include #include "hw.h" -#include "sysemu.h" #include "console.h" #include "qemu-char.h" #include "xen_backend.h" @@ -348,35 +347,50 @@ static void xenfb_mouse_event(void *opaque, static int input_init(struct XenDevice *xendev) { - struct XenInput *in = container_of(xendev, struct XenInput, c.xendev); - - if (!in->c.ds) { - xen_be_printf(xendev, 1, "ds not set (yet)\n"); - return -1; - } - xenstore_write_be_int(xendev, "feature-abs-pointer", 1); return 0; } -static int input_connect(struct XenDevice *xendev) +static int input_initialise(struct XenDevice *xendev) { struct XenInput *in = container_of(xendev, struct XenInput, c.xendev); int rc; - if (xenstore_read_fe_int(xendev, "request-abs-pointer", - &in->abs_pointer_wanted) == -1) - in->abs_pointer_wanted = 0; + if (!in->c.ds) { + char *vfb = xenstore_read_str(NULL, "device/vfb"); + if (vfb == NULL) { + /* there is no vfb, run vkbd on its own */ + in->c.ds = get_displaystate(); + } else { + g_free(vfb); + xen_be_printf(xendev, 1, "ds not set (yet)\n"); + return -1; + } + } rc = common_bind(&in->c); if (rc != 0) return rc; qemu_add_kbd_event_handler(xenfb_key_event, in); + return 0; +} + +static void input_connected(struct XenDevice *xendev) +{ + struct XenInput *in = container_of(xendev, struct XenInput, c.xendev); + + if (xenstore_read_fe_int(xendev, "request-abs-pointer", + &in->abs_pointer_wanted) == -1) { + in->abs_pointer_wanted = 0; + } + + if (in->qmouse) { + qemu_remove_mouse_event_handler(in->qmouse); + } in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in, in->abs_pointer_wanted, "Xen PVFB Mouse"); - return 0; } static void input_disconnect(struct XenDevice *xendev) @@ -479,8 +493,8 @@ static int xenfb_map_fb(struct XenFB *xenfb) n_fbdirs = xenfb->fbpages * mode / 8; n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; - pgmfns = qemu_mallocz(sizeof(unsigned long) * n_fbdirs); - fbmfns = qemu_mallocz(sizeof(unsigned long) * xenfb->fbpages); + pgmfns = g_malloc0(sizeof(unsigned long) * n_fbdirs); + fbmfns = g_malloc0(sizeof(unsigned long) * xenfb->fbpages); xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd); map = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom, @@ -498,8 +512,8 @@ static int xenfb_map_fb(struct XenFB *xenfb) ret = 0; /* all is fine */ out: - qemu_free(pgmfns); - qemu_free(fbmfns); + g_free(pgmfns); + g_free(fbmfns); return ret; } @@ -861,7 +875,7 @@ static int fb_init(struct XenDevice *xendev) return 0; } -static int fb_connect(struct XenDevice *xendev) +static int fb_initialise(struct XenDevice *xendev) { struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev); struct xenfb_page *fb_page; @@ -955,7 +969,8 @@ static void fb_event(struct XenDevice *xendev) struct XenDevOps xen_kbdmouse_ops = { .size = sizeof(struct XenInput), .init = input_init, - .connect = input_connect, + .initialise = input_initialise, + .connected = input_connected, .disconnect = input_disconnect, .event = input_event, }; @@ -963,7 +978,7 @@ struct XenDevOps xen_kbdmouse_ops = { struct XenDevOps xen_framebuffer_ops = { .size = sizeof(struct XenFB), .init = fb_init, - .connect = fb_connect, + .initialise = fb_initialise, .disconnect = fb_disconnect, .event = fb_event, .frontend_changed = fb_frontend_changed, diff --git a/hw/xilinx.h b/hw/xilinx.h index 705ff5b..35f35bd7 100644 --- a/hw/xilinx.h +++ b/hw/xilinx.h @@ -1,6 +1,5 @@ - -/* OPB Interrupt Controller. */ -qemu_irq *microblaze_pic_init_cpu(CPUState *env); +#include "qemu-common.h" +#include "net.h" static inline DeviceState * xilinx_intc_create(target_phys_addr_t base, qemu_irq irq, int kind_of_intr) @@ -48,3 +47,42 @@ xilinx_ethlite_create(NICInfo *nd, target_phys_addr_t base, qemu_irq irq, sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); return dev; } + +static inline DeviceState * +xilinx_axiethernet_create(void *dmach, + NICInfo *nd, target_phys_addr_t base, qemu_irq irq, + int txmem, int rxmem) +{ + DeviceState *dev; + qemu_check_nic_model(nd, "xilinx-axienet"); + + dev = qdev_create(NULL, "xilinx,axienet"); + qdev_set_nic_properties(dev, nd); + qdev_prop_set_uint32(dev, "c_rxmem", rxmem); + qdev_prop_set_uint32(dev, "c_txmem", txmem); + qdev_prop_set_ptr(dev, "dmach", dmach); + qdev_init_nofail(dev); + sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); + sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); + + return dev; +} + +static inline DeviceState * +xilinx_axiethernetdma_create(void *dmach, + target_phys_addr_t base, qemu_irq irq, + qemu_irq irq2, int freqhz) +{ + DeviceState *dev = NULL; + + dev = qdev_create(NULL, "xilinx,axidma"); + qdev_prop_set_uint32(dev, "freqhz", freqhz); + qdev_prop_set_ptr(dev, "dmach", dmach); + qdev_init_nofail(dev); + + sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); + sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq2); + sysbus_connect_irq(sysbus_from_qdev(dev), 1, irq); + + return dev; +} diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c index 54b57d7..6f44c84 100644 --- a/hw/xilinx_ethlite.c +++ b/hw/xilinx_ethlite.c @@ -50,6 +50,7 @@ struct xlx_ethlite { SysBusDevice busdev; + MemoryRegion mmio; qemu_irq irq; NICState *nic; NICConf conf; @@ -70,7 +71,8 @@ static inline void eth_pulse_irq(struct xlx_ethlite *s) } } -static uint32_t eth_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +eth_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct xlx_ethlite *s = opaque; uint32_t r = 0; @@ -90,23 +92,20 @@ static uint32_t eth_readl (void *opaque, target_phys_addr_t addr) D(qemu_log("%s %x=%x\n", __func__, addr * 4, r)); break; - /* Rx packet data is endian fixed at the way into the rx rams. This - * speeds things up because the ethlite MAC does not have a len - * register. That means the CPU will issue MMIO reads for the entire - * 2k rx buffer even for small packets. - */ default: - r = s->regs[addr]; + r = tswap32(s->regs[addr]); break; } return r; } static void -eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +eth_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct xlx_ethlite *s = opaque; unsigned int base = 0; + uint32_t value = val64; addr >>= 2; switch (addr) @@ -145,19 +144,20 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value) s->regs[addr] = value; break; - /* Packet data, make sure it stays BE. */ default: - s->regs[addr] = cpu_to_be32(value); + s->regs[addr] = tswap32(value); break; } } -static CPUReadMemoryFunc * const eth_read[] = { - NULL, NULL, ð_readl, -}; - -static CPUWriteMemoryFunc * const eth_write[] = { - NULL, NULL, ð_writel, +static const MemoryRegionOps eth_ops = { + .read = eth_read, + .write = eth_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static int eth_can_rx(VLANClientState *nc) @@ -172,7 +172,6 @@ static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size) { struct xlx_ethlite *s = DO_UPCAST(NICState, nc, nc)->opaque; unsigned int rxbase = s->rxbuf * (0x800 / 4); - int i; /* DA filter. */ if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6)) @@ -186,12 +185,6 @@ static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size) D(qemu_log("%s %d rxbase=%x\n", __func__, size, rxbase)); memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size); - /* Bring it into host endianess. */ - for (i = 0; i < ((size + 3) / 4); i++) { - uint32_t d = s->regs[rxbase + R_RX_BUF0 + i]; - s->regs[rxbase + R_RX_BUF0 + i] = be32_to_cpu(d); - } - s->regs[rxbase + R_RX_CTRL0] |= CTRL_S; if (s->regs[rxbase + R_RX_CTRL0] & CTRL_I) eth_pulse_irq(s); @@ -219,13 +212,12 @@ static NetClientInfo net_xilinx_ethlite_info = { static int xilinx_ethlite_init(SysBusDevice *dev) { struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev); - int regs; sysbus_init_irq(dev, &s->irq); s->rxbuf = 0; - regs = cpu_register_io_memory(eth_read, eth_write, s, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, regs); + memory_region_init_io(&s->mmio, ð_ops, s, "xilinx-ethlite", R_MAX * 4); + sysbus_init_mmio_region(dev, &s->mmio); qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf, diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c index cb72d5a..58b73d9 100644 --- a/hw/xilinx_intc.c +++ b/hw/xilinx_intc.c @@ -40,6 +40,7 @@ struct xlx_pic { SysBusDevice busdev; + MemoryRegion mmio; qemu_irq parent_irq; /* Configuration reg chosen at synthesis-time. QEMU populates @@ -72,7 +73,8 @@ static void update_irq(struct xlx_pic *p) } } -static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +pic_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct xlx_pic *p = opaque; uint32_t r = 0; @@ -91,9 +93,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) } static void -pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +pic_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct xlx_pic *p = opaque; + uint32_t value = val64; addr >>= 2; D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value)); @@ -116,14 +120,14 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) update_irq(p); } -static CPUReadMemoryFunc * const pic_read[] = { - NULL, NULL, - &pic_readl, -}; - -static CPUWriteMemoryFunc * const pic_write[] = { - NULL, NULL, - &pic_writel, +static const MemoryRegionOps pic_ops = { + .read = pic_read, + .write = pic_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void irq_handler(void *opaque, int irq, int level) @@ -148,13 +152,12 @@ static void irq_handler(void *opaque, int irq, int level) static int xilinx_intc_init(SysBusDevice *dev) { struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev); - int pic_regs; qdev_init_gpio_in(&dev->qdev, irq_handler, 32); sysbus_init_irq(dev, &p->parent_irq); - pic_regs = cpu_register_io_memory(pic_read, pic_write, p, DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, pic_regs); + memory_region_init_io(&p->mmio, &pic_ops, p, "xilinx-pic", R_MAX * 4); + sysbus_init_mmio_region(dev, &p->mmio); return 0; } diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c index 30827b0..8779c56 100644 --- a/hw/xilinx_timer.c +++ b/hw/xilinx_timer.c @@ -23,7 +23,6 @@ */ #include "sysbus.h" -#include "sysemu.h" #include "qemu-timer.h" #define D(x) @@ -60,6 +59,7 @@ struct xlx_timer struct timerblock { SysBusDevice busdev; + MemoryRegion mmio; qemu_irq irq; uint32_t nr_timers; uint32_t freq_hz; @@ -86,7 +86,8 @@ static void timer_update_irq(struct timerblock *t) qemu_set_irq(t->irq, !!irq); } -static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +timer_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct timerblock *t = opaque; struct xlx_timer *xt; @@ -135,11 +136,13 @@ static void timer_enable(struct xlx_timer *xt) } static void -timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +timer_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct timerblock *t = opaque; struct xlx_timer *xt; unsigned int timer; + uint32_t value = val64; addr >>= 2; timer = timer_from_addr(addr); @@ -167,14 +170,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) timer_update_irq(t); } -static CPUReadMemoryFunc * const timer_read[] = { - NULL, NULL, - &timer_readl, -}; - -static CPUWriteMemoryFunc * const timer_write[] = { - NULL, NULL, - &timer_writel, +static const MemoryRegionOps timer_ops = { + .read = timer_read, + .write = timer_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void timer_hit(void *opaque) @@ -193,13 +196,12 @@ static int xilinx_timer_init(SysBusDevice *dev) { struct timerblock *t = FROM_SYSBUS(typeof (*t), dev); unsigned int i; - int timer_regs; /* All timers share a single irq line. */ sysbus_init_irq(dev, &t->irq); /* Init all the ptimers. */ - t->timers = qemu_mallocz(sizeof t->timers[0] * t->nr_timers); + t->timers = g_malloc0(sizeof t->timers[0] * t->nr_timers); for (i = 0; i < t->nr_timers; i++) { struct xlx_timer *xt = &t->timers[i]; @@ -210,9 +212,9 @@ static int xilinx_timer_init(SysBusDevice *dev) ptimer_set_freq(xt->ptimer, t->freq_hz); } - timer_regs = cpu_register_io_memory(timer_read, timer_write, t, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs); + memory_region_init_io(&t->mmio, &timer_ops, t, "xilinx-timer", + R_MAX * 4 * t->nr_timers); + sysbus_init_mmio_region(dev, &t->mmio); return 0; } diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c index 9b94e98..ceb7b4d 100644 --- a/hw/xilinx_uartlite.c +++ b/hw/xilinx_uartlite.c @@ -49,6 +49,7 @@ struct xlx_uartlite { SysBusDevice busdev; + MemoryRegion mmio; CharDriverState *chr; qemu_irq irq; @@ -82,7 +83,8 @@ static void uart_update_status(struct xlx_uartlite *s) s->regs[R_STATUS] = r; } -static uint32_t uart_readl (void *opaque, target_phys_addr_t addr) +static uint64_t +uart_read(void *opaque, target_phys_addr_t addr, unsigned int size) { struct xlx_uartlite *s = opaque; uint32_t r = 0; @@ -107,9 +109,11 @@ static uint32_t uart_readl (void *opaque, target_phys_addr_t addr) } static void -uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value) +uart_write(void *opaque, target_phys_addr_t addr, + uint64_t val64, unsigned int size) { struct xlx_uartlite *s = opaque; + uint32_t value = val64; unsigned char ch = value; addr >>= 2; @@ -129,7 +133,7 @@ uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value) case R_TX: if (s->chr) - qemu_chr_write(s->chr, &ch, 1); + qemu_chr_fe_write(s->chr, &ch, 1); s->regs[addr] = value; @@ -147,16 +151,14 @@ uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value) uart_update_irq(s); } -static CPUReadMemoryFunc * const uart_read[] = { - &uart_readl, - &uart_readl, - &uart_readl, -}; - -static CPUWriteMemoryFunc * const uart_write[] = { - &uart_writel, - &uart_writel, - &uart_writel, +static const MemoryRegionOps uart_ops = { + .read = uart_read, + .write = uart_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4 + } }; static void uart_rx(void *opaque, const uint8_t *buf, int size) @@ -196,14 +198,12 @@ static void uart_event(void *opaque, int event) static int xilinx_uartlite_init(SysBusDevice *dev) { struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev); - int uart_regs; sysbus_init_irq(dev, &s->irq); uart_update_status(s); - uart_regs = cpu_register_io_memory(uart_read, uart_write, s, - DEVICE_NATIVE_ENDIAN); - sysbus_init_mmio(dev, R_MAX * 4, uart_regs); + memory_region_init_io(&s->mmio, &uart_ops, s, "xilinx-uartlite", R_MAX * 4); + sysbus_init_mmio_region(dev, &s->mmio); s->chr = qdev_init_chardev(&dev->qdev); if (s->chr) diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c index 5aa6a6b..d3c387d 100644 --- a/hw/xio3130_downstream.c +++ b/hw/xio3130_downstream.c @@ -69,9 +69,6 @@ static int xio3130_downstream_initfn(PCIDevice *d) } pcie_port_init_reg(d); - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130D); - d->config[PCI_REVISION_ID] = XIO3130_REVISION; rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR, XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, @@ -182,6 +179,9 @@ static PCIDeviceInfo xio3130_downstream_info = { .config_write = xio3130_downstream_write_config, .init = xio3130_downstream_initfn, .exit = xio3130_downstream_exitfn, + .vendor_id = PCI_VENDOR_ID_TI, + .device_id = PCI_DEVICE_ID_TI_XIO3130D, + .revision = XIO3130_REVISION, .qdev.props = (Property[]) { DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0), diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c index a7640f5..8283695 100644 --- a/hw/xio3130_upstream.c +++ b/hw/xio3130_upstream.c @@ -65,9 +65,6 @@ static int xio3130_upstream_initfn(PCIDevice *d) } pcie_port_init_reg(d); - pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI); - pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130U); - d->config[PCI_REVISION_ID] = XIO3130_REVISION; rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR, XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, @@ -159,6 +156,9 @@ static PCIDeviceInfo xio3130_upstream_info = { .config_write = xio3130_upstream_write_config, .init = xio3130_upstream_initfn, .exit = xio3130_upstream_exitfn, + .vendor_id = PCI_VENDOR_ID_TI, + .device_id = PCI_DEVICE_ID_TI_XIO3130U, + .revision = XIO3130_REVISION, .qdev.props = (Property[]) { DEFINE_PROP_UINT8("port", PCIEPort, port, 0), diff --git a/hw/zaurus.c b/hw/zaurus.c index fca11a5..0eeacf7 100644 --- a/hw/zaurus.c +++ b/hw/zaurus.c @@ -16,7 +16,6 @@ * with this program; if not, see . */ #include "hw.h" -#include "pxa.h" #include "sharpsl.h" #include "sysbus.h" @@ -181,17 +180,34 @@ static int scoop_init(SysBusDevice *dev) return 0; } +static int scoop_post_load(void *opaque, int version_id) +{ + ScoopInfo *s = (ScoopInfo *) opaque; + int i; + uint32_t level; + + level = s->gpio_level & s->gpio_dir; + + for (i = 0; i < 16; i++) { + qemu_set_irq(s->handler[i], (level >> i) & 1); + } + + s->prev_level = level; + + return 0; +} + static bool is_version_0 (void *opaque, int version_id) { return version_id == 0; } - static const VMStateDescription vmstate_scoop_regs = { .name = "scoop", .version_id = 1, .minimum_version_id = 0, .minimum_version_id_old = 0, + .post_load = scoop_post_load, .fields = (VMStateField []) { VMSTATE_UINT16(status, ScoopInfo), VMSTATE_UINT16(power, ScoopInfo), @@ -230,7 +246,7 @@ device_init(scoop_register); #define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a) -static struct __attribute__ ((__packed__)) sl_param_info { +static struct QEMU_PACKED sl_param_info { uint32_t comadj_keyword; int32_t comadj; diff --git a/i386.ld b/i386.ld index f8df7bf..cc3f160 100644 --- a/i386.ld +++ b/i386.ld @@ -42,16 +42,16 @@ SECTIONS .rel.plt : { *(.rel.plt) - PROVIDE_HIDDEN (__rel_iplt_start = .); + PROVIDE (__rel_iplt_start = .); *(.rel.iplt) - PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE (__rel_iplt_end = .); } .rela.plt : { *(.rela.plt) - PROVIDE_HIDDEN (__rela_iplt_start = .); + PROVIDE (__rela_iplt_start = .); *(.rela.iplt) - PROVIDE_HIDDEN (__rela_iplt_end = .); + PROVIDE (__rela_iplt_end = .); } .init : { *(.init) } =0x47ff041f .text : diff --git a/ia64-dis.c b/ia64-dis.c index 2886df3..2a103e6 100644 --- a/ia64-dis.c +++ b/ia64-dis.c @@ -781,6 +781,9 @@ ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) return 0; } +/* glib.h defines ABS so we must undefine it to avoid a clash */ +#undef ABS + #define CST IA64_OPND_CLASS_CST #define REG IA64_OPND_CLASS_REG #define IND IA64_OPND_CLASS_IND diff --git a/input.c b/input.c index 7e5fa1a..37c88c7 100644 --- a/input.c +++ b/input.c @@ -26,12 +26,15 @@ #include "net.h" #include "monitor.h" #include "console.h" -#include "qjson.h" +#include "error.h" +#include "qmp-commands.h" static QEMUPutKBDEvent *qemu_put_kbd_event; static void *qemu_put_kbd_event_opaque; +#ifdef CONFIG_MARU static QEMUPutKBDEvent *qemu_put_ps2kbd_event; static void *qemu_put_ps2kbd_event_opaque; +#endif static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers); static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers = QTAILQ_HEAD_INITIALIZER(mouse_handlers); @@ -50,9 +53,10 @@ void qemu_remove_kbd_event_handler(void) qemu_put_kbd_event = NULL; } +#ifdef CONFIG_MARU + void qemu_add_ps2kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) { - qemu_add_kbd_event_handler(func,opaque); // temporary code for compatibility with Xserver qemu_put_ps2kbd_event_opaque = opaque; qemu_put_ps2kbd_event = func; } @@ -63,6 +67,15 @@ void qemu_remove_ps2kbd_event_handler(void) qemu_put_ps2kbd_event = NULL; } +void ps2kbd_put_keycode(int keycode) +{ + if (qemu_put_ps2kbd_event) { + qemu_put_ps2kbd_event(qemu_put_ps2kbd_event_opaque, keycode); + } +} + +#endif + static void check_mode_change(void) { static int current_is_absolute, current_has_absolute; @@ -74,7 +87,7 @@ static void check_mode_change(void) if (is_absolute != current_is_absolute || has_absolute != current_has_absolute) { - notifier_list_notify(&mouse_mode_notifiers); + notifier_list_notify(&mouse_mode_notifiers, NULL); } current_is_absolute = is_absolute; @@ -88,12 +101,12 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, QEMUPutMouseEntry *s; static int mouse_index = 0; - s = qemu_mallocz(sizeof(QEMUPutMouseEntry)); + s = g_malloc0(sizeof(QEMUPutMouseEntry)); s->qemu_put_mouse_event = func; s->qemu_put_mouse_event_opaque = opaque; s->qemu_put_mouse_event_absolute = absolute; - s->qemu_put_mouse_event_name = qemu_strdup(name); + s->qemu_put_mouse_event_name = g_strdup(name); s->index = mouse_index++; QTAILQ_INSERT_TAIL(&mouse_handlers, s, node); @@ -115,8 +128,8 @@ void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) { QTAILQ_REMOVE(&mouse_handlers, entry, node); - qemu_free(entry->qemu_put_mouse_event_name); - qemu_free(entry); + g_free(entry->qemu_put_mouse_event_name); + g_free(entry); check_mode_change(); } @@ -126,7 +139,7 @@ QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, { QEMUPutLEDEntry *s; - s = qemu_mallocz(sizeof(QEMUPutLEDEntry)); + s = g_malloc0(sizeof(QEMUPutLEDEntry)); s->put_led = func; s->opaque = opaque; @@ -139,7 +152,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) if (entry == NULL) return; QTAILQ_REMOVE(&led_handlers, entry, next); - qemu_free(entry); + g_free(entry); } void kbd_put_keycode(int keycode) @@ -149,13 +162,6 @@ void kbd_put_keycode(int keycode) } } -void ps2kbd_put_keycode(int keycode) -{ - if (qemu_put_ps2kbd_event) { - qemu_put_ps2kbd_event(qemu_put_ps2kbd_event_opaque, keycode); - } -} - void kbd_put_ledstate(int ledstate) { QEMUPutLEDEntry *cursor; @@ -170,7 +176,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) QEMUPutMouseEntry *entry; QEMUPutMouseEvent *mouse_event; void *mouse_event_opaque; - int width; + int width, height; if (QTAILQ_EMPTY(&mouse_handlers)) { return; @@ -182,16 +188,32 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) mouse_event_opaque = entry->qemu_put_mouse_event_opaque; if (mouse_event) { - if (graphic_rotate) { - if (entry->qemu_put_mouse_event_absolute) - width = 0x7fff; - else - width = graphic_width - 1; + if (entry->qemu_put_mouse_event_absolute) { + width = 0x7fff; + height = 0x7fff; + } else { + width = graphic_width - 1; + height = graphic_height - 1; + } + + switch (graphic_rotate) { + case 0: + mouse_event(mouse_event_opaque, + dx, dy, dz, buttons_state); + break; + case 90: mouse_event(mouse_event_opaque, width - dy, dx, dz, buttons_state); - } else + break; + case 180: mouse_event(mouse_event_opaque, - dx, dy, dz, buttons_state); + width - dx, height - dy, dz, buttons_state); + break; + case 270: + mouse_event(mouse_event_opaque, + dy, height - dx, dz, buttons_state); + break; + } } } @@ -217,60 +239,27 @@ int kbd_mouse_has_absolute(void) return 0; } -static void info_mice_iter(QObject *data, void *opaque) -{ - QDict *mouse; - Monitor *mon = opaque; - - mouse = qobject_to_qdict(data); - monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n", - (qdict_get_bool(mouse, "current") ? '*' : ' '), - qdict_get_int(mouse, "index"), qdict_get_str(mouse, "name"), - qdict_get_bool(mouse, "absolute") ? " (absolute)" : ""); -} - -void do_info_mice_print(Monitor *mon, const QObject *data) -{ - QList *mice_list; - - mice_list = qobject_to_qlist(data); - if (qlist_empty(mice_list)) { - monitor_printf(mon, "No mouse devices connected\n"); - return; - } - - qlist_iter(mice_list, info_mice_iter, mon); -} - -void do_info_mice(Monitor *mon, QObject **ret_data) +MouseInfoList *qmp_query_mice(Error **errp) { + MouseInfoList *mice_list = NULL; QEMUPutMouseEntry *cursor; - QList *mice_list; - int current; + bool current = true; - mice_list = qlist_new(); - - if (QTAILQ_EMPTY(&mouse_handlers)) { - goto out; - } + QTAILQ_FOREACH(cursor, &mouse_handlers, node) { + MouseInfoList *info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->name = g_strdup(cursor->qemu_put_mouse_event_name); + info->value->index = cursor->index; + info->value->absolute = !!cursor->qemu_put_mouse_event_absolute; + info->value->current = current; - current = QTAILQ_FIRST(&mouse_handlers)->index; + current = false; - QTAILQ_FOREACH(cursor, &mouse_handlers, node) { - QObject *obj; - obj = qobject_from_jsonf("{ 'name': %s," - " 'index': %d," - " 'current': %i," - " 'absolute': %i }", - cursor->qemu_put_mouse_event_name, - cursor->index, - cursor->index == current, - !!cursor->qemu_put_mouse_event_absolute); - qlist_append_obj(mice_list, obj); + info->next = mice_list; + mice_list = info; } -out: - *ret_data = QOBJECT(mice_list); + return mice_list; } void do_mouse_set(Monitor *mon, const QDict *qdict) diff --git a/ioport.c b/ioport.c index aa4188a..36fa3a4 100644 --- a/ioport.c +++ b/ioport.c @@ -27,6 +27,7 @@ #include "ioport.h" #include "trace.h" +#include "memory.h" /***********************************************************/ /* IO Port */ @@ -146,10 +147,11 @@ int register_ioport_read(pio_addr_t start, int length, int size, hw_error("register_ioport_read: invalid size"); return -1; } - for(i = start; i < start + length; i += size) { + for(i = start; i < start + length; ++i) { ioport_read_table[bsize][i] = func; if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) - hw_error("register_ioport_read: invalid opaque"); + hw_error("register_ioport_read: invalid opaque for address 0x%x", + i); ioport_opaque[i] = opaque; } return 0; @@ -165,10 +167,11 @@ int register_ioport_write(pio_addr_t start, int length, int size, hw_error("register_ioport_write: invalid size"); return -1; } - for(i = start; i < start + length; i += size) { + for(i = start; i < start + length; ++i) { ioport_write_table[bsize][i] = func; if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) - hw_error("register_ioport_write: invalid opaque"); + hw_error("register_ioport_write: invalid opaque for address 0x%x", + i); ioport_opaque[i] = opaque; } return 0; @@ -243,18 +246,25 @@ void isa_unassign_ioport(pio_addr_t start, int length) int i; for(i = start; i < start + length; i++) { - ioport_read_table[0][i] = default_ioport_readb; - ioport_read_table[1][i] = default_ioport_readw; - ioport_read_table[2][i] = default_ioport_readl; + ioport_read_table[0][i] = NULL; + ioport_read_table[1][i] = NULL; + ioport_read_table[2][i] = NULL; - ioport_write_table[0][i] = default_ioport_writeb; - ioport_write_table[1][i] = default_ioport_writew; - ioport_write_table[2][i] = default_ioport_writel; + ioport_write_table[0][i] = NULL; + ioport_write_table[1][i] = NULL; + ioport_write_table[2][i] = NULL; ioport_opaque[i] = NULL; } } +bool isa_is_ioport_assigned(pio_addr_t start) +{ + return (ioport_read_table[0][start] || ioport_write_table[0][start] || + ioport_read_table[1][start] || ioport_write_table[1][start] || + ioport_read_table[2][start] || ioport_write_table[2][start]); +} + /***********************************************************/ void cpu_outb(pio_addr_t addr, uint8_t val) @@ -304,3 +314,110 @@ uint32_t cpu_inl(pio_addr_t addr) LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val); return val; } + +void portio_list_init(PortioList *piolist, + const MemoryRegionPortio *callbacks, + void *opaque, const char *name) +{ + unsigned n = 0; + + while (callbacks[n].size) { + ++n; + } + + piolist->ports = callbacks; + piolist->nr = 0; + piolist->regions = g_new0(MemoryRegion *, n); + piolist->address_space = NULL; + piolist->opaque = opaque; + piolist->name = name; +} + +void portio_list_destroy(PortioList *piolist) +{ + g_free(piolist->regions); +} + +static void portio_list_add_1(PortioList *piolist, + const MemoryRegionPortio *pio_init, + unsigned count, unsigned start, + unsigned off_low, unsigned off_high) +{ + MemoryRegionPortio *pio; + MemoryRegionOps *ops; + MemoryRegion *region; + unsigned i; + + /* Copy the sub-list and null-terminate it. */ + pio = g_new(MemoryRegionPortio, count + 1); + memcpy(pio, pio_init, sizeof(MemoryRegionPortio) * count); + memset(pio + count, 0, sizeof(MemoryRegionPortio)); + + /* Adjust the offsets to all be zero-based for the region. */ + for (i = 0; i < count; ++i) { + pio[i].offset -= off_low; + } + + ops = g_new0(MemoryRegionOps, 1); + ops->old_portio = pio; + + region = g_new(MemoryRegion, 1); + memory_region_init_io(region, ops, piolist->opaque, piolist->name, + off_high - off_low); + memory_region_set_offset(region, start + off_low); + memory_region_add_subregion(piolist->address_space, + start + off_low, region); + piolist->regions[piolist->nr++] = region; +} + +void portio_list_add(PortioList *piolist, + MemoryRegion *address_space, + uint32_t start) +{ + const MemoryRegionPortio *pio, *pio_start = piolist->ports; + unsigned int off_low, off_high, off_last, count; + + piolist->address_space = address_space; + + /* Handle the first entry specially. */ + off_last = off_low = pio_start->offset; + off_high = off_low + pio_start->len; + count = 1; + + for (pio = pio_start + 1; pio->size != 0; pio++, count++) { + /* All entries must be sorted by offset. */ + assert(pio->offset >= off_last); + off_last = pio->offset; + + /* If we see a hole, break the region. */ + if (off_last > off_high) { + portio_list_add_1(piolist, pio_start, count, start, off_low, + off_high); + /* ... and start collecting anew. */ + pio_start = pio; + off_low = off_last; + off_high = off_low + pio->len; + count = 0; + } else if (off_last + pio->len > off_high) { + off_high = off_last + pio->len; + } + } + + /* There will always be an open sub-list. */ + portio_list_add_1(piolist, pio_start, count, start, off_low, off_high); +} + +void portio_list_del(PortioList *piolist) +{ + MemoryRegion *mr; + unsigned i; + + for (i = 0; i < piolist->nr; ++i) { + mr = piolist->regions[i]; + memory_region_del_subregion(piolist->address_space, mr); + memory_region_destroy(mr); + g_free((MemoryRegionOps *)mr->ops); + g_free(mr); + piolist->regions[i] = NULL; + } +} diff --git a/ioport.h b/ioport.h index 5ae62a3..ae3e9da 100644 --- a/ioport.h +++ b/ioport.h @@ -43,7 +43,7 @@ int register_ioport_read(pio_addr_t start, int length, int size, int register_ioport_write(pio_addr_t start, int length, int size, IOPortWriteFunc *func, void *opaque); void isa_unassign_ioport(pio_addr_t start, int length); - +bool isa_is_ioport_assigned(pio_addr_t start); void cpu_outb(pio_addr_t addr, uint8_t val); void cpu_outw(pio_addr_t addr, uint16_t val); @@ -52,4 +52,25 @@ uint8_t cpu_inb(pio_addr_t addr); uint16_t cpu_inw(pio_addr_t addr); uint32_t cpu_inl(pio_addr_t addr); +struct MemoryRegion; +struct MemoryRegionPortio; + +typedef struct PortioList { + const struct MemoryRegionPortio *ports; + struct MemoryRegion *address_space; + unsigned nr; + struct MemoryRegion **regions; + void *opaque; + const char *name; +} PortioList; + +void portio_list_init(PortioList *piolist, + const struct MemoryRegionPortio *callbacks, + void *opaque, const char *name); +void portio_list_destroy(PortioList *piolist); +void portio_list_add(PortioList *piolist, + struct MemoryRegion *address_space, + uint32_t addr); +void portio_list_del(PortioList *piolist); + #endif /* IOPORT_H */ diff --git a/iov.c b/iov.c index 588cd04..e7385c4 100644 --- a/iov.c +++ b/iov.c @@ -14,57 +14,116 @@ #include "iov.h" -size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, - const void *buf, size_t size) +size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, + const void *buf, size_t iov_off, size_t size) { - size_t offset; + size_t iovec_off, buf_off; unsigned int i; - offset = 0; - for (i = 0; offset < size && i < iovcnt; i++) { - size_t len; + iovec_off = 0; + buf_off = 0; + for (i = 0; i < iov_cnt && size; i++) { + if (iov_off < (iovec_off + iov[i].iov_len)) { + size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off, size); - len = MIN(iov[i].iov_len, size - offset); + memcpy(iov[i].iov_base + (iov_off - iovec_off), buf + buf_off, len); - memcpy(iov[i].iov_base, buf + offset, len); - offset += len; + buf_off += len; + iov_off += len; + size -= len; + } + iovec_off += iov[i].iov_len; } - return offset; + return buf_off; } -size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, - void *buf, size_t offset, size_t size) +size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, + void *buf, size_t iov_off, size_t size) { uint8_t *ptr; - size_t iov_off, buf_off; + size_t iovec_off, buf_off; unsigned int i; ptr = buf; - iov_off = 0; + iovec_off = 0; + buf_off = 0; + for (i = 0; i < iov_cnt && size; i++) { + if (iov_off < (iovec_off + iov[i].iov_len)) { + size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size); + + memcpy(ptr + buf_off, iov[i].iov_base + (iov_off - iovec_off), len); + + buf_off += len; + iov_off += len; + size -= len; + } + iovec_off += iov[i].iov_len; + } + return buf_off; +} + +size_t iov_clear(const struct iovec *iov, const unsigned int iov_cnt, + size_t iov_off, size_t size) +{ + size_t iovec_off, buf_off; + unsigned int i; + + iovec_off = 0; buf_off = 0; - for (i = 0; i < iovcnt && size; i++) { - if (offset < (iov_off + iov[i].iov_len)) { - size_t len = MIN((iov_off + iov[i].iov_len) - offset , size); + for (i = 0; i < iov_cnt && size; i++) { + if (iov_off < (iovec_off + iov[i].iov_len)) { + size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size); - memcpy(ptr + buf_off, iov[i].iov_base + (offset - iov_off), len); + memset(iov[i].iov_base + (iov_off - iovec_off), 0, len); buf_off += len; - offset += len; + iov_off += len; size -= len; } - iov_off += iov[i].iov_len; + iovec_off += iov[i].iov_len; } return buf_off; } -size_t iov_size(const struct iovec *iov, const unsigned int iovcnt) +size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt) { size_t len; unsigned int i; len = 0; - for (i = 0; i < iovcnt; i++) { + for (i = 0; i < iov_cnt; i++) { len += iov[i].iov_len; } return len; } + +void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, + FILE *fp, const char *prefix, size_t limit) +{ + unsigned int i, v, b; + uint8_t *c; + + c = iov[0].iov_base; + for (i = 0, v = 0, b = 0; b < limit; i++, b++) { + if (i == iov[v].iov_len) { + i = 0; v++; + if (v == iov_cnt) { + break; + } + c = iov[v].iov_base; + } + if ((b % 16) == 0) { + fprintf(fp, "%s: %04x:", prefix, b); + } + if ((b % 4) == 0) { + fprintf(fp, " "); + } + fprintf(fp, " %02x", c[i]); + if ((b % 16) == 15) { + fprintf(fp, "\n"); + } + } + if ((b % 16) != 0) { + fprintf(fp, "\n"); + } +} diff --git a/iov.h b/iov.h index 60a8547..94d2f78 100644 --- a/iov.h +++ b/iov.h @@ -12,8 +12,12 @@ #include "qemu-common.h" -size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, - const void *buf, size_t size); -size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, - void *buf, size_t offset, size_t size); -size_t iov_size(const struct iovec *iov, const unsigned int iovcnt); +size_t iov_from_buf(struct iovec *iov, unsigned int iov_cnt, + const void *buf, size_t iov_off, size_t size); +size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, + void *buf, size_t iov_off, size_t size); +size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt); +size_t iov_clear(const struct iovec *iov, const unsigned int iov_cnt, + size_t iov_off, size_t size); +void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, + FILE *fp, const char *prefix, size_t limit); diff --git a/json-lexer.c b/json-lexer.c index c736f42..c21338f 100644 --- a/json-lexer.c +++ b/json-lexer.c @@ -18,6 +18,8 @@ #include "qemu-common.h" #include "json-lexer.h" +#define MAX_TOKEN_SIZE (64ULL << 20) + /* * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\" * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*' @@ -28,7 +30,7 @@ */ enum json_lexer_state { - ERROR = 0, + IN_ERROR = 0, IN_DQ_UCODE3, IN_DQ_UCODE2, IN_DQ_UCODE1, @@ -103,7 +105,8 @@ static const uint8_t json_lexer[][256] = { ['u'] = IN_DQ_UCODE0, }, [IN_DQ_STRING] = { - [1 ... 0xFF] = IN_DQ_STRING, + [1 ... 0xBF] = IN_DQ_STRING, + [0xC2 ... 0xF4] = IN_DQ_STRING, ['\\'] = IN_DQ_STRING_ESCAPE, ['"'] = JSON_STRING, }, @@ -142,7 +145,8 @@ static const uint8_t json_lexer[][256] = { ['u'] = IN_SQ_UCODE0, }, [IN_SQ_STRING] = { - [1 ... 0xFF] = IN_SQ_STRING, + [1 ... 0xBF] = IN_SQ_STRING, + [0xC2 ... 0xF4] = IN_SQ_STRING, ['\\'] = IN_SQ_STRING_ESCAPE, ['\''] = JSON_STRING, }, @@ -150,7 +154,7 @@ static const uint8_t json_lexer[][256] = { /* Zero */ [IN_ZERO] = { TERMINAL(JSON_INTEGER), - ['0' ... '9'] = ERROR, + ['0' ... '9'] = IN_ERROR, ['.'] = IN_MANTISSA, }, @@ -272,7 +276,7 @@ void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func) lexer->x = lexer->y = 0; } -static int json_lexer_feed_char(JSONLexer *lexer, char ch) +static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush) { int char_consumed, new_state; @@ -302,13 +306,42 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch) lexer->token = qstring_new(); new_state = IN_START; break; - case ERROR: - return -EINVAL; + case IN_ERROR: + /* XXX: To avoid having previous bad input leaving the parser in an + * unresponsive state where we consume unpredictable amounts of + * subsequent "good" input, percolate this error state up to the + * tokenizer/parser by forcing a NULL object to be emitted, then + * reset state. + * + * Also note that this handling is required for reliable channel + * negotiation between QMP and the guest agent, since chr(0xFF) + * is placed at the beginning of certain events to ensure proper + * delivery when the channel is in an unknown state. chr(0xFF) is + * never a valid ASCII/UTF-8 sequence, so this should reliably + * induce an error/flush state. + */ + lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y); + QDECREF(lexer->token); + lexer->token = qstring_new(); + new_state = IN_START; + lexer->state = new_state; + return 0; default: break; } lexer->state = new_state; - } while (!char_consumed); + } while (!char_consumed && !flush); + + /* Do not let a single token grow to an arbitrarily large size, + * this is a security consideration. + */ + if (lexer->token->length > MAX_TOKEN_SIZE) { + lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y); + QDECREF(lexer->token); + lexer->token = qstring_new(); + lexer->state = IN_START; + } + return 0; } @@ -319,7 +352,7 @@ int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) for (i = 0; i < size; i++) { int err; - err = json_lexer_feed_char(lexer, buffer[i]); + err = json_lexer_feed_char(lexer, buffer[i], false); if (err < 0) { return err; } @@ -330,7 +363,7 @@ int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) int json_lexer_flush(JSONLexer *lexer) { - return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0); + return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0, true); } void json_lexer_destroy(JSONLexer *lexer) diff --git a/json-lexer.h b/json-lexer.h index 3b50c46..10bc0a7 100644 --- a/json-lexer.h +++ b/json-lexer.h @@ -25,6 +25,7 @@ typedef enum json_token_type { JSON_STRING, JSON_ESCAPE, JSON_SKIP, + JSON_ERROR, } JSONTokenType; typedef struct JSONLexer JSONLexer; diff --git a/json-parser.c b/json-parser.c index 6c06ef9..849e215 100644 --- a/json-parser.c +++ b/json-parser.c @@ -22,9 +22,11 @@ #include "qbool.h" #include "json-parser.h" #include "json-lexer.h" +#include "qerror.h" typedef struct JSONParserContext { + Error *err; } JSONParserContext; #define BUG_ON(cond) assert(!(cond)) @@ -95,11 +97,15 @@ static void GCC_FMT_ATTR(3, 4) parse_error(JSONParserContext *ctxt, QObject *token, const char *msg, ...) { va_list ap; + char message[1024]; va_start(ap, msg); - fprintf(stderr, "parse error: "); - vfprintf(stderr, msg, ap); - fprintf(stderr, "\n"); + vsnprintf(message, sizeof(message), msg, ap); va_end(ap); + if (ctxt->err) { + error_free(ctxt->err); + ctxt->err = NULL; + } + error_set(&ctxt->err, QERR_JSON_PARSE_ERROR, message); } /** @@ -269,10 +275,15 @@ out: */ static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_list *ap) { - QObject *key, *token = NULL, *value, *peek; + QObject *key = NULL, *token = NULL, *value, *peek; QList *working = qlist_copy(*tokens); peek = qlist_peek(working); + if (peek == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + key = parse_value(ctxt, &working, ap); if (!key || qobject_type(key) != QTYPE_QSTRING) { parse_error(ctxt, peek, "key is not a string in object"); @@ -280,6 +291,11 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_l } token = qlist_pop(working); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + if (!token_is_operator(token, ':')) { parse_error(ctxt, token, "missing : in object pair"); goto out; @@ -315,6 +331,10 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a QList *working = qlist_copy(*tokens); token = qlist_pop(working); + if (token == NULL) { + goto out; + } + if (!token_is_operator(token, '{')) { goto out; } @@ -324,12 +344,22 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a dict = qdict_new(); peek = qlist_peek(working); + if (peek == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + if (!token_is_operator(peek, '}')) { if (parse_pair(ctxt, dict, &working, ap) == -1) { goto out; } token = qlist_pop(working); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + while (!token_is_operator(token, '}')) { if (!token_is_operator(token, ',')) { parse_error(ctxt, token, "expected separator in dict"); @@ -343,6 +373,10 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a } token = qlist_pop(working); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } } qobject_decref(token); token = NULL; @@ -371,6 +405,10 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap QList *working = qlist_copy(*tokens); token = qlist_pop(working); + if (token == NULL) { + goto out; + } + if (!token_is_operator(token, '[')) { goto out; } @@ -380,6 +418,11 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap list = qlist_new(); peek = qlist_peek(working); + if (peek == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + if (!token_is_operator(peek, ']')) { QObject *obj; @@ -392,6 +435,11 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap qlist_append_obj(list, obj); token = qlist_pop(working); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + while (!token_is_operator(token, ']')) { if (!token_is_operator(token, ',')) { parse_error(ctxt, token, "expected separator in list"); @@ -410,6 +458,10 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap qlist_append_obj(list, obj); token = qlist_pop(working); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } } qobject_decref(token); @@ -438,6 +490,9 @@ static QObject *parse_keyword(JSONParserContext *ctxt, QList **tokens) QList *working = qlist_copy(*tokens); token = qlist_pop(working); + if (token == NULL) { + goto out; + } if (token_get_type(token) != JSON_KEYWORD) { goto out; @@ -475,6 +530,9 @@ static QObject *parse_escape(JSONParserContext *ctxt, QList **tokens, va_list *a } token = qlist_pop(working); + if (token == NULL) { + goto out; + } if (token_is_escape(token, "%p")) { obj = va_arg(*ap, QObject *); @@ -514,6 +572,10 @@ static QObject *parse_literal(JSONParserContext *ctxt, QList **tokens) QList *working = qlist_copy(*tokens); token = qlist_pop(working); + if (token == NULL) { + goto out; + } + switch (token_get_type(token)) { case JSON_STRING: obj = QOBJECT(qstring_from_escaped_str(ctxt, token)); @@ -565,13 +627,24 @@ static QObject *parse_value(JSONParserContext *ctxt, QList **tokens, va_list *ap QObject *json_parser_parse(QList *tokens, va_list *ap) { + return json_parser_parse_err(tokens, ap, NULL); +} + +QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp) +{ JSONParserContext ctxt = {}; - QList *working = qlist_copy(tokens); + QList *working; QObject *result; + if (!tokens) { + return NULL; + } + working = qlist_copy(tokens); result = parse_value(&ctxt, &working, ap); QDECREF(working); + error_propagate(errp, ctxt.err); + return result; } diff --git a/json-parser.h b/json-parser.h index 97f43f6..8f2b5ec 100644 --- a/json-parser.h +++ b/json-parser.h @@ -16,7 +16,9 @@ #include "qemu-common.h" #include "qlist.h" +#include "error.h" QObject *json_parser_parse(QList *tokens, va_list *ap); +QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp); #endif diff --git a/json-streamer.c b/json-streamer.c index f7e7a68..c255c78 100644 --- a/json-streamer.c +++ b/json-streamer.c @@ -18,6 +18,9 @@ #include "json-lexer.h" #include "json-streamer.h" +#define MAX_TOKEN_SIZE (64ULL << 20) +#define MAX_NESTING (1ULL << 10) + static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y) { JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer); @@ -49,14 +52,44 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok qdict_put(dict, "x", qint_from_int(x)); qdict_put(dict, "y", qint_from_int(y)); + parser->token_size += token->length; + qlist_append(parser->tokens, dict); - if (parser->brace_count == 0 && - parser->bracket_count == 0) { - parser->emit(parser, parser->tokens); + if (type == JSON_ERROR) { + goto out_emit_bad; + } else if (parser->brace_count < 0 || + parser->bracket_count < 0 || + (parser->brace_count == 0 && + parser->bracket_count == 0)) { + goto out_emit; + } else if (parser->token_size > MAX_TOKEN_SIZE || + parser->bracket_count > MAX_NESTING || + parser->brace_count > MAX_NESTING) { + /* Security consideration, we limit total memory allocated per object + * and the maximum recursion depth that a message can force. + */ + goto out_emit; + } + + return; + +out_emit_bad: + /* clear out token list and tell the parser to emit and error + * indication by passing it a NULL list + */ + QDECREF(parser->tokens); + parser->tokens = NULL; +out_emit: + /* send current list of tokens to parser and reset tokenizer */ + parser->brace_count = 0; + parser->bracket_count = 0; + parser->emit(parser, parser->tokens); + if (parser->tokens) { QDECREF(parser->tokens); - parser->tokens = qlist_new(); } + parser->tokens = qlist_new(); + parser->token_size = 0; } void json_message_parser_init(JSONMessageParser *parser, @@ -66,6 +99,7 @@ void json_message_parser_init(JSONMessageParser *parser, parser->brace_count = 0; parser->bracket_count = 0; parser->tokens = qlist_new(); + parser->token_size = 0; json_lexer_init(&parser->lexer, json_message_process_token); } diff --git a/json-streamer.h b/json-streamer.h index 09f3bd7..f09bc4d 100644 --- a/json-streamer.h +++ b/json-streamer.h @@ -24,6 +24,7 @@ typedef struct JSONMessageParser int brace_count; int bracket_count; QList *tokens; + uint64_t token_size; } JSONMessageParser; void json_message_parser_init(JSONMessageParser *parser, diff --git a/kvm-all.c b/kvm-all.c index 9151831..4c466d6 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -19,7 +19,6 @@ #include #include -#include #include "qemu-common.h" #include "qemu-barrier.h" @@ -41,313 +40,324 @@ #ifdef DEBUG_KVM #define DPRINTF(fmt, ...) \ - do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) + do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) #else #define DPRINTF(fmt, ...) \ - do { } while (0) + do { } while (0) #endif -extern void show_message(const char *szTitle, const char *szMessage); - typedef struct KVMSlot { - target_phys_addr_t start_addr; - ram_addr_t memory_size; - ram_addr_t phys_offset; - int slot; - int flags; + target_phys_addr_t start_addr; + ram_addr_t memory_size; + ram_addr_t phys_offset; + int slot; + int flags; } KVMSlot; typedef struct kvm_dirty_log KVMDirtyLog; struct KVMState { - KVMSlot slots[32]; - int fd; - int vmfd; - int coalesced_mmio; - struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; - int broken_set_mem_region; - int migration_log; - int vcpu_events; - int robust_singlestep; - int debugregs; + KVMSlot slots[32]; + int fd; + int vmfd; + int coalesced_mmio; + struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; + bool coalesced_flush_in_progress; + int broken_set_mem_region; + int migration_log; + int vcpu_events; + int robust_singlestep; + int debugregs; #ifdef KVM_CAP_SET_GUEST_DEBUG - struct kvm_sw_breakpoint_head kvm_sw_breakpoints; + struct kvm_sw_breakpoint_head kvm_sw_breakpoints; #endif - int irqchip_in_kernel; - int pit_in_kernel; - int xsave, xcrs; - int many_ioeventfds; + int irqchip_in_kernel; + int pit_in_kernel; + int xsave, xcrs; + int many_ioeventfds; }; -static KVMState *kvm_state; +KVMState *kvm_state; static const KVMCapabilityInfo kvm_required_capabilites[] = { - KVM_CAP_INFO(USER_MEMORY), - KVM_CAP_INFO(DESTROY_MEMORY_REGION_WORKS), - KVM_CAP_LAST_INFO + KVM_CAP_INFO(USER_MEMORY), + KVM_CAP_INFO(DESTROY_MEMORY_REGION_WORKS), + KVM_CAP_LAST_INFO }; static KVMSlot *kvm_alloc_slot(KVMState *s) { - int i; + int i; - for (i = 0; i < ARRAY_SIZE(s->slots); i++) { - /* KVM private memory slots */ - if (i >= 8 && i < 12) { - continue; - } - if (s->slots[i].memory_size == 0) { - return &s->slots[i]; - } - } + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + if (s->slots[i].memory_size == 0) { + return &s->slots[i]; + } + } - fprintf(stderr, "%s: no free slot available\n", __func__); - abort(); + fprintf(stderr, "%s: no free slot available\n", __func__); + abort(); } static KVMSlot *kvm_lookup_matching_slot(KVMState *s, - target_phys_addr_t start_addr, - target_phys_addr_t end_addr) + target_phys_addr_t start_addr, + target_phys_addr_t end_addr) { - int i; + int i; - for (i = 0; i < ARRAY_SIZE(s->slots); i++) { - KVMSlot *mem = &s->slots[i]; + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + KVMSlot *mem = &s->slots[i]; - if (start_addr == mem->start_addr && - end_addr == mem->start_addr + mem->memory_size) { - return mem; - } - } + if (start_addr == mem->start_addr && + end_addr == mem->start_addr + mem->memory_size) { + return mem; + } + } - return NULL; + return NULL; } /* * Find overlapping slot with lowest start address */ static KVMSlot *kvm_lookup_overlapping_slot(KVMState *s, - target_phys_addr_t start_addr, - target_phys_addr_t end_addr) + target_phys_addr_t start_addr, + target_phys_addr_t end_addr) { - KVMSlot *found = NULL; - int i; + KVMSlot *found = NULL; + int i; - for (i = 0; i < ARRAY_SIZE(s->slots); i++) { - KVMSlot *mem = &s->slots[i]; + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + KVMSlot *mem = &s->slots[i]; - if (mem->memory_size == 0 || - (found && found->start_addr < mem->start_addr)) { - continue; - } + if (mem->memory_size == 0 || + (found && found->start_addr < mem->start_addr)) { + continue; + } - if (end_addr > mem->start_addr && - start_addr < mem->start_addr + mem->memory_size) { - found = mem; - } - } + if (end_addr > mem->start_addr && + start_addr < mem->start_addr + mem->memory_size) { + found = mem; + } + } - return found; + return found; } int kvm_physical_memory_addr_from_ram(KVMState *s, ram_addr_t ram_addr, - target_phys_addr_t *phys_addr) + target_phys_addr_t *phys_addr) { - int i; + int i; - for (i = 0; i < ARRAY_SIZE(s->slots); i++) { - KVMSlot *mem = &s->slots[i]; + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + KVMSlot *mem = &s->slots[i]; - if (ram_addr >= mem->phys_offset && - ram_addr < mem->phys_offset + mem->memory_size) { - *phys_addr = mem->start_addr + (ram_addr - mem->phys_offset); - return 1; - } - } + if (ram_addr >= mem->phys_offset && + ram_addr < mem->phys_offset + mem->memory_size) { + *phys_addr = mem->start_addr + (ram_addr - mem->phys_offset); + return 1; + } + } - return 0; + return 0; } static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot) { - struct kvm_userspace_memory_region mem; - - mem.slot = slot->slot; - mem.guest_phys_addr = slot->start_addr; - mem.memory_size = slot->memory_size; - mem.userspace_addr = (unsigned long)qemu_safe_ram_ptr(slot->phys_offset); - mem.flags = slot->flags; - if (s->migration_log) { - mem.flags |= KVM_MEM_LOG_DIRTY_PAGES; - } - return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); + struct kvm_userspace_memory_region mem; + + mem.slot = slot->slot; + mem.guest_phys_addr = slot->start_addr; + mem.memory_size = slot->memory_size; + mem.userspace_addr = (unsigned long)qemu_safe_ram_ptr(slot->phys_offset); + mem.flags = slot->flags; + if (s->migration_log) { + mem.flags |= KVM_MEM_LOG_DIRTY_PAGES; + } + return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem); } static void kvm_reset_vcpu(void *opaque) { - CPUState *env = opaque; + CPUState *env = opaque; - kvm_arch_reset_vcpu(env); + kvm_arch_reset_vcpu(env); } int kvm_irqchip_in_kernel(void) { - return kvm_state->irqchip_in_kernel; + return kvm_state->irqchip_in_kernel; } int kvm_pit_in_kernel(void) { - return kvm_state->pit_in_kernel; + return kvm_state->pit_in_kernel; } int kvm_init_vcpu(CPUState *env) { - KVMState *s = kvm_state; - long mmap_size; - int ret; - - DPRINTF("kvm_init_vcpu\n"); - - ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index); - if (ret < 0) { - DPRINTF("kvm_create_vcpu failed\n"); - goto err; - } - - env->kvm_fd = ret; - env->kvm_state = s; - - mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0); - if (mmap_size < 0) { - DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n"); - goto err; - } - - env->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, - env->kvm_fd, 0); - if (env->kvm_run == MAP_FAILED) { - ret = -errno; - DPRINTF("mmap'ing vcpu state failed\n"); - goto err; - } - - if (s->coalesced_mmio && !s->coalesced_mmio_ring) { - s->coalesced_mmio_ring = - (void *)env->kvm_run + s->coalesced_mmio * PAGE_SIZE; - } - - ret = kvm_arch_init_vcpu(env); - if (ret == 0) { - qemu_register_reset(kvm_reset_vcpu, env); - kvm_arch_reset_vcpu(env); - } + KVMState *s = kvm_state; + long mmap_size; + int ret; + + DPRINTF("kvm_init_vcpu\n"); + + ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index); + if (ret < 0) { + DPRINTF("kvm_create_vcpu failed\n"); + goto err; + } + + env->kvm_fd = ret; + env->kvm_state = s; + env->kvm_vcpu_dirty = 1; + + mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0); + if (mmap_size < 0) { + ret = mmap_size; + DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n"); + goto err; + } + + env->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, + env->kvm_fd, 0); + if (env->kvm_run == MAP_FAILED) { + ret = -errno; + DPRINTF("mmap'ing vcpu state failed\n"); + goto err; + } + + if (s->coalesced_mmio && !s->coalesced_mmio_ring) { + s->coalesced_mmio_ring = + (void *)env->kvm_run + s->coalesced_mmio * PAGE_SIZE; + } + + ret = kvm_arch_init_vcpu(env); + if (ret == 0) { + qemu_register_reset(kvm_reset_vcpu, env); + kvm_arch_reset_vcpu(env); + } err: - return ret; + return ret; } /* * dirty pages logging control */ -static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, - ram_addr_t size, int flags, int mask) + +static int kvm_mem_flags(KVMState *s, bool log_dirty) { - KVMState *s = kvm_state; - KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size); - int old_flags; + return log_dirty ? KVM_MEM_LOG_DIRTY_PAGES : 0; +} + +static int kvm_slot_dirty_pages_log_change(KVMSlot *mem, bool log_dirty) +{ + KVMState *s = kvm_state; + int flags, mask = KVM_MEM_LOG_DIRTY_PAGES; + int old_flags; + + old_flags = mem->flags; - if (mem == NULL) { - fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-" - TARGET_FMT_plx "\n", __func__, phys_addr, - (target_phys_addr_t)(phys_addr + size - 1)); - return -EINVAL; - } + flags = (mem->flags & ~mask) | kvm_mem_flags(s, log_dirty); + mem->flags = flags; - old_flags = mem->flags; + /* If nothing changed effectively, no need to issue ioctl */ + if (s->migration_log) { + flags |= KVM_MEM_LOG_DIRTY_PAGES; + } - flags = (mem->flags & ~mask) | flags; - mem->flags = flags; + if (flags == old_flags) { + return 0; + } - /* If nothing changed effectively, no need to issue ioctl */ - if (s->migration_log) { - flags |= KVM_MEM_LOG_DIRTY_PAGES; - } - if (flags == old_flags) { - return 0; - } + return kvm_set_user_memory_region(s, mem); +} - return kvm_set_user_memory_region(s, mem); +static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr, + ram_addr_t size, bool log_dirty) +{ + KVMState *s = kvm_state; + KVMSlot *mem = kvm_lookup_matching_slot(s, phys_addr, phys_addr + size); + + if (mem == NULL) { + fprintf(stderr, "BUG: %s: invalid parameters " TARGET_FMT_plx "-" + TARGET_FMT_plx "\n", __func__, phys_addr, + (target_phys_addr_t)(phys_addr + size - 1)); + return -EINVAL; + } + return kvm_slot_dirty_pages_log_change(mem, log_dirty); } -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) +static int kvm_log_start(CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size) { - return kvm_dirty_pages_log_change(phys_addr, size, KVM_MEM_LOG_DIRTY_PAGES, - KVM_MEM_LOG_DIRTY_PAGES); + return kvm_dirty_pages_log_change(phys_addr, size, true); } -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) +static int kvm_log_stop(CPUPhysMemoryClient *client, + target_phys_addr_t phys_addr, ram_addr_t size) { - return kvm_dirty_pages_log_change(phys_addr, size, 0, - KVM_MEM_LOG_DIRTY_PAGES); + return kvm_dirty_pages_log_change(phys_addr, size, false); } static int kvm_set_migration_log(int enable) { - KVMState *s = kvm_state; - KVMSlot *mem; - int i, err; - - s->migration_log = enable; - - for (i = 0; i < ARRAY_SIZE(s->slots); i++) { - mem = &s->slots[i]; - - if (!mem->memory_size) { - continue; - } - if (!!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES) == enable) { - continue; - } - err = kvm_set_user_memory_region(s, mem); - if (err) { - return err; - } - } - return 0; + KVMState *s = kvm_state; + KVMSlot *mem; + int i, err; + + s->migration_log = enable; + + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + mem = &s->slots[i]; + + if (!mem->memory_size) { + continue; + } + if (!!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES) == enable) { + continue; + } + err = kvm_set_user_memory_region(s, mem); + if (err) { + return err; + } + } + return 0; } /* get kvm's dirty pages bitmap and update qemu's */ static int kvm_get_dirty_pages_log_range(unsigned long start_addr, - unsigned long *bitmap, - unsigned long offset, - unsigned long mem_size) -{ - unsigned int i, j; - unsigned long page_number, addr, addr1, c; - ram_addr_t ram_addr; - unsigned int len = ((mem_size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) / - HOST_LONG_BITS; - - /* - * bitmap-traveling is faster than memory-traveling (for addr...) - * especially when most of the memory is not dirty. - */ - for (i = 0; i < len; i++) { - if (bitmap[i] != 0) { - c = leul_to_cpu(bitmap[i]); - do { - j = ffsl(c) - 1; - c &= ~(1ul << j); - page_number = i * HOST_LONG_BITS + j; - addr1 = page_number * TARGET_PAGE_SIZE; - addr = offset + addr1; - ram_addr = cpu_get_physical_page_desc(addr); - cpu_physical_memory_set_dirty(ram_addr); - } while (c != 0); - } - } - return 0; + unsigned long *bitmap, + unsigned long offset, + unsigned long mem_size) +{ + unsigned int i, j; + unsigned long page_number, addr, addr1, c; + ram_addr_t ram_addr; + unsigned int len = ((mem_size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) / + HOST_LONG_BITS; + + /* + * bitmap-traveling is faster than memory-traveling (for addr...) + * especially when most of the memory is not dirty. + */ + for (i = 0; i < len; i++) { + if (bitmap[i] != 0) { + c = leul_to_cpu(bitmap[i]); + do { + j = ffsl(c) - 1; + c &= ~(1ul << j); + page_number = i * HOST_LONG_BITS + j; + addr1 = page_number * TARGET_PAGE_SIZE; + addr = offset + addr1; + ram_addr = cpu_get_physical_page_desc(addr); + cpu_physical_memory_set_dirty(ram_addr); + } while (c != 0); + } + } + return 0; } #define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1)) @@ -361,943 +371,946 @@ static int kvm_get_dirty_pages_log_range(unsigned long start_addr, * @end_addr: end of logged region. */ static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, - target_phys_addr_t end_addr) -{ - KVMState *s = kvm_state; - unsigned long size, allocated_size = 0; - KVMDirtyLog d; - KVMSlot *mem; - int ret = 0; - - d.dirty_bitmap = NULL; - while (start_addr < end_addr) { - mem = kvm_lookup_overlapping_slot(s, start_addr, end_addr); - if (mem == NULL) { - break; - } - - size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), HOST_LONG_BITS) / 8; - if (!d.dirty_bitmap) { - d.dirty_bitmap = qemu_malloc(size); - } else if (size > allocated_size) { - d.dirty_bitmap = qemu_realloc(d.dirty_bitmap, size); - } - allocated_size = size; - memset(d.dirty_bitmap, 0, allocated_size); - - d.slot = mem->slot; - - if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) { - DPRINTF("ioctl failed %d\n", errno); - ret = -1; - break; - } - - kvm_get_dirty_pages_log_range(mem->start_addr, d.dirty_bitmap, - mem->start_addr, mem->memory_size); - start_addr = mem->start_addr + mem->memory_size; - } - qemu_free(d.dirty_bitmap); - - return ret; + target_phys_addr_t end_addr) +{ + KVMState *s = kvm_state; + unsigned long size, allocated_size = 0; + KVMDirtyLog d; + KVMSlot *mem; + int ret = 0; + + d.dirty_bitmap = NULL; + while (start_addr < end_addr) { + mem = kvm_lookup_overlapping_slot(s, start_addr, end_addr); + if (mem == NULL) { + break; + } + + /* XXX bad kernel interface alert + * For dirty bitmap, kernel allocates array of size aligned to + * bits-per-long. But for case when the kernel is 64bits and + * the userspace is 32bits, userspace can't align to the same + * bits-per-long, since sizeof(long) is different between kernel + * and user space. This way, userspace will provide buffer which + * may be 4 bytes less than the kernel will use, resulting in + * userspace memory corruption (which is not detectable by valgrind + * too, in most cases). + * So for now, let's align to 64 instead of HOST_LONG_BITS here, in + * a hope that sizeof(long) wont become >8 any time soon. + */ + size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), + /*HOST_LONG_BITS*/ 64) / 8; + if (!d.dirty_bitmap) { + d.dirty_bitmap = g_malloc(size); + } else if (size > allocated_size) { + d.dirty_bitmap = g_realloc(d.dirty_bitmap, size); + } + allocated_size = size; + memset(d.dirty_bitmap, 0, allocated_size); + + d.slot = mem->slot; + + if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) { + DPRINTF("ioctl failed %d\n", errno); + ret = -1; + break; + } + + kvm_get_dirty_pages_log_range(mem->start_addr, d.dirty_bitmap, + mem->start_addr, mem->memory_size); + start_addr = mem->start_addr + mem->memory_size; + } + g_free(d.dirty_bitmap); + + return ret; } int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) { - int ret = -ENOSYS; - KVMState *s = kvm_state; + int ret = -ENOSYS; + KVMState *s = kvm_state; - if (s->coalesced_mmio) { - struct kvm_coalesced_mmio_zone zone; + if (s->coalesced_mmio) { + struct kvm_coalesced_mmio_zone zone; - zone.addr = start; - zone.size = size; + zone.addr = start; + zone.size = size; - ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone); - } + ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone); + } - return ret; + return ret; } int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) { - int ret = -ENOSYS; - KVMState *s = kvm_state; + int ret = -ENOSYS; + KVMState *s = kvm_state; - if (s->coalesced_mmio) { - struct kvm_coalesced_mmio_zone zone; + if (s->coalesced_mmio) { + struct kvm_coalesced_mmio_zone zone; - zone.addr = start; - zone.size = size; + zone.addr = start; + zone.size = size; - ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone); - } + ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone); + } - return ret; + return ret; } int kvm_check_extension(KVMState *s, unsigned int extension) { - int ret; + int ret; - ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, extension); - if (ret < 0) { - ret = 0; - } + ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, extension); + if (ret < 0) { + ret = 0; + } - return ret; + return ret; } static int kvm_check_many_ioeventfds(void) { - /* Userspace can use ioeventfd for io notification. This requires a host - * that supports eventfd(2) and an I/O thread; since eventfd does not - * support SIGIO it cannot interrupt the vcpu. - * - * Older kernels have a 6 device limit on the KVM io bus. Find out so we - * can avoid creating too many ioeventfds. - */ -#if defined(CONFIG_EVENTFD) && defined(CONFIG_IOTHREAD) - int ioeventfds[7]; - int i, ret = 0; - for (i = 0; i < ARRAY_SIZE(ioeventfds); i++) { - ioeventfds[i] = eventfd(0, EFD_CLOEXEC); - if (ioeventfds[i] < 0) { - break; - } - ret = kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, true); - if (ret < 0) { - close(ioeventfds[i]); - break; - } - } - - /* Decide whether many devices are supported or not */ - ret = i == ARRAY_SIZE(ioeventfds); - - while (i-- > 0) { - kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, false); - close(ioeventfds[i]); - } - return ret; + /* Userspace can use ioeventfd for io notification. This requires a host + * that supports eventfd(2) and an I/O thread; since eventfd does not + * support SIGIO it cannot interrupt the vcpu. + * + * Older kernels have a 6 device limit on the KVM io bus. Find out so we + * can avoid creating too many ioeventfds. + */ +#if defined(CONFIG_EVENTFD) + int ioeventfds[7]; + int i, ret = 0; + for (i = 0; i < ARRAY_SIZE(ioeventfds); i++) { + ioeventfds[i] = eventfd(0, EFD_CLOEXEC); + if (ioeventfds[i] < 0) { + break; + } + ret = kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, true); + if (ret < 0) { + close(ioeventfds[i]); + break; + } + } + + /* Decide whether many devices are supported or not */ + ret = i == ARRAY_SIZE(ioeventfds); + + while (i-- > 0) { + kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, false); + close(ioeventfds[i]); + } + return ret; #else - return 0; + return 0; #endif } - static const KVMCapabilityInfo * +static const KVMCapabilityInfo * kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list) { - while (list->name) { - if (!kvm_check_extension(s, list->value)) { - return list; - } - list++; - } - return NULL; + while (list->name) { + if (!kvm_check_extension(s, list->value)) { + return list; + } + list++; + } + return NULL; } static void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size, - ram_addr_t phys_offset) -{ - KVMState *s = kvm_state; - ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; - KVMSlot *mem, old; - int err; - - /* kvm works in page size chunks, but the function may be called - with sub-page size and unaligned start address. */ - size = TARGET_PAGE_ALIGN(size); - start_addr = TARGET_PAGE_ALIGN(start_addr); - - /* KVM does not support read-only slots */ - phys_offset &= ~IO_MEM_ROM; - - while (1) { - mem = kvm_lookup_overlapping_slot(s, start_addr, start_addr + size); - if (!mem) { - break; - } - - if (flags < IO_MEM_UNASSIGNED && start_addr >= mem->start_addr && - (start_addr + size <= mem->start_addr + mem->memory_size) && - (phys_offset - start_addr == mem->phys_offset - mem->start_addr)) { - /* The new slot fits into the existing one and comes with - * identical parameters - nothing to be done. */ - return; - } - - old = *mem; - - /* unregister the overlapping slot */ - mem->memory_size = 0; - err = kvm_set_user_memory_region(s, mem); - if (err) { - fprintf(stderr, "%s: error unregistering overlapping slot: %s\n", - __func__, strerror(-err)); - abort(); - } - - /* Workaround for older KVM versions: we can't join slots, even not by - * unregistering the previous ones and then registering the larger - * slot. We have to maintain the existing fragmentation. Sigh. - * - * This workaround assumes that the new slot starts at the same - * address as the first existing one. If not or if some overlapping - * slot comes around later, we will fail (not seen in practice so far) - * - and actually require a recent KVM version. */ - if (s->broken_set_mem_region && - old.start_addr == start_addr && old.memory_size < size && - flags < IO_MEM_UNASSIGNED) { - mem = kvm_alloc_slot(s); - mem->memory_size = old.memory_size; - mem->start_addr = old.start_addr; - mem->phys_offset = old.phys_offset; - mem->flags = 0; - - err = kvm_set_user_memory_region(s, mem); - if (err) { - fprintf(stderr, "%s: error updating slot: %s\n", __func__, - strerror(-err)); - abort(); - } - - start_addr += old.memory_size; - phys_offset += old.memory_size; - size -= old.memory_size; - continue; - } - - /* register prefix slot */ - if (old.start_addr < start_addr) { - mem = kvm_alloc_slot(s); - mem->memory_size = start_addr - old.start_addr; - mem->start_addr = old.start_addr; - mem->phys_offset = old.phys_offset; - mem->flags = 0; - - err = kvm_set_user_memory_region(s, mem); - if (err) { - fprintf(stderr, "%s: error registering prefix slot: %s\n", - __func__, strerror(-err)); - abort(); - } - } - - /* register suffix slot */ - if (old.start_addr + old.memory_size > start_addr + size) { - ram_addr_t size_delta; - - mem = kvm_alloc_slot(s); - mem->start_addr = start_addr + size; - size_delta = mem->start_addr - old.start_addr; - mem->memory_size = old.memory_size - size_delta; - mem->phys_offset = old.phys_offset + size_delta; - mem->flags = 0; - - err = kvm_set_user_memory_region(s, mem); - if (err) { - fprintf(stderr, "%s: error registering suffix slot: %s\n", - __func__, strerror(-err)); - abort(); - } - } - } - - /* in case the KVM bug workaround already "consumed" the new slot */ - if (!size) { - return; - } - /* KVM does not need to know about this memory */ - if (flags >= IO_MEM_UNASSIGNED) { - return; - } - mem = kvm_alloc_slot(s); - mem->memory_size = size; - mem->start_addr = start_addr; - mem->phys_offset = phys_offset; - mem->flags = 0; - - err = kvm_set_user_memory_region(s, mem); - if (err) { - fprintf(stderr, "%s: error registering slot: %s\n", __func__, - strerror(-err)); - abort(); - } + ram_addr_t phys_offset, bool log_dirty) +{ + KVMState *s = kvm_state; + ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; + KVMSlot *mem, old; + int err; + + /* kvm works in page size chunks, but the function may be called + with sub-page size and unaligned start address. */ + size = TARGET_PAGE_ALIGN(size); + start_addr = TARGET_PAGE_ALIGN(start_addr); + + /* KVM does not support read-only slots */ + phys_offset &= ~IO_MEM_ROM; + + while (1) { + mem = kvm_lookup_overlapping_slot(s, start_addr, start_addr + size); + if (!mem) { + break; + } + + if (flags < IO_MEM_UNASSIGNED && start_addr >= mem->start_addr && + (start_addr + size <= mem->start_addr + mem->memory_size) && + (phys_offset - start_addr == mem->phys_offset - mem->start_addr)) { + /* The new slot fits into the existing one and comes with + * identical parameters - update flags and done. */ + kvm_slot_dirty_pages_log_change(mem, log_dirty); + return; + } + + old = *mem; + + /* unregister the overlapping slot */ + mem->memory_size = 0; + err = kvm_set_user_memory_region(s, mem); + if (err) { + fprintf(stderr, "%s: error unregistering overlapping slot: %s\n", + __func__, strerror(-err)); + abort(); + } + + /* Workaround for older KVM versions: we can't join slots, even not by + * unregistering the previous ones and then registering the larger + * slot. We have to maintain the existing fragmentation. Sigh. + * + * This workaround assumes that the new slot starts at the same + * address as the first existing one. If not or if some overlapping + * slot comes around later, we will fail (not seen in practice so far) + * - and actually require a recent KVM version. */ + if (s->broken_set_mem_region && + old.start_addr == start_addr && old.memory_size < size && + flags < IO_MEM_UNASSIGNED) { + mem = kvm_alloc_slot(s); + mem->memory_size = old.memory_size; + mem->start_addr = old.start_addr; + mem->phys_offset = old.phys_offset; + mem->flags = kvm_mem_flags(s, log_dirty); + + err = kvm_set_user_memory_region(s, mem); + if (err) { + fprintf(stderr, "%s: error updating slot: %s\n", __func__, + strerror(-err)); + abort(); + } + + start_addr += old.memory_size; + phys_offset += old.memory_size; + size -= old.memory_size; + continue; + } + + /* register prefix slot */ + if (old.start_addr < start_addr) { + mem = kvm_alloc_slot(s); + mem->memory_size = start_addr - old.start_addr; + mem->start_addr = old.start_addr; + mem->phys_offset = old.phys_offset; + mem->flags = kvm_mem_flags(s, log_dirty); + + err = kvm_set_user_memory_region(s, mem); + if (err) { + fprintf(stderr, "%s: error registering prefix slot: %s\n", + __func__, strerror(-err)); +#ifdef TARGET_PPC + fprintf(stderr, "%s: This is probably because your kernel's " \ + "PAGE_SIZE is too big. Please try to use 4k " \ + "PAGE_SIZE!\n", __func__); +#endif + abort(); + } + } + + /* register suffix slot */ + if (old.start_addr + old.memory_size > start_addr + size) { + ram_addr_t size_delta; + + mem = kvm_alloc_slot(s); + mem->start_addr = start_addr + size; + size_delta = mem->start_addr - old.start_addr; + mem->memory_size = old.memory_size - size_delta; + mem->phys_offset = old.phys_offset + size_delta; + mem->flags = kvm_mem_flags(s, log_dirty); + + err = kvm_set_user_memory_region(s, mem); + if (err) { + fprintf(stderr, "%s: error registering suffix slot: %s\n", + __func__, strerror(-err)); + abort(); + } + } + } + + /* in case the KVM bug workaround already "consumed" the new slot */ + if (!size) { + return; + } + /* KVM does not need to know about this memory */ + if (flags >= IO_MEM_UNASSIGNED) { + return; + } + mem = kvm_alloc_slot(s); + mem->memory_size = size; + mem->start_addr = start_addr; + mem->phys_offset = phys_offset; + mem->flags = kvm_mem_flags(s, log_dirty); + + err = kvm_set_user_memory_region(s, mem); + if (err) { + fprintf(stderr, "%s: error registering slot: %s\n", __func__, + strerror(-err)); + abort(); + } } static void kvm_client_set_memory(struct CPUPhysMemoryClient *client, - target_phys_addr_t start_addr, - ram_addr_t size, ram_addr_t phys_offset) + target_phys_addr_t start_addr, + ram_addr_t size, ram_addr_t phys_offset, + bool log_dirty) { - kvm_set_phys_mem(start_addr, size, phys_offset); + kvm_set_phys_mem(start_addr, size, phys_offset, log_dirty); } static int kvm_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *client, - target_phys_addr_t start_addr, - target_phys_addr_t end_addr) + target_phys_addr_t start_addr, + target_phys_addr_t end_addr) { - return kvm_physical_sync_dirty_bitmap(start_addr, end_addr); + return kvm_physical_sync_dirty_bitmap(start_addr, end_addr); } static int kvm_client_migration_log(struct CPUPhysMemoryClient *client, - int enable) + int enable) { - return kvm_set_migration_log(enable); + return kvm_set_migration_log(enable); } static CPUPhysMemoryClient kvm_cpu_phys_memory_client = { - .set_memory = kvm_client_set_memory, - .sync_dirty_bitmap = kvm_client_sync_dirty_bitmap, - .migration_log = kvm_client_migration_log, + .set_memory = kvm_client_set_memory, + .sync_dirty_bitmap = kvm_client_sync_dirty_bitmap, + .migration_log = kvm_client_migration_log, + .log_start = kvm_log_start, + .log_stop = kvm_log_stop, }; +static void kvm_handle_interrupt(CPUState *env, int mask) +{ + env->interrupt_request |= mask; + + if (!qemu_cpu_is_self(env)) { + qemu_cpu_kick(env); + } +} + int kvm_init(void) { - static const char upgrade_note[] = - "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n" - "(see http://sourceforge.net/projects/kvm).\n"; - KVMState *s; - const KVMCapabilityInfo *missing_cap; - int ret; - int i; + static const char upgrade_note[] = + "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n" + "(see http://sourceforge.net/projects/kvm).\n"; + KVMState *s; + const KVMCapabilityInfo *missing_cap; + int ret; + int i; - s = qemu_mallocz(sizeof(KVMState)); + s = g_malloc0(sizeof(KVMState)); #ifdef KVM_CAP_SET_GUEST_DEBUG - QTAILQ_INIT(&s->kvm_sw_breakpoints); + QTAILQ_INIT(&s->kvm_sw_breakpoints); #endif - for (i = 0; i < ARRAY_SIZE(s->slots); i++) { - s->slots[i].slot = i; - } - s->vmfd = -1; - s->fd = qemu_open("/dev/kvm", O_RDWR); - if (s->fd == -1) { - fprintf(stderr, "Could not access KVM kernel module: %m\n"); - - show_message("Error", "Could not access KVM kernel module: Permission denied\n" - "You can add the login user to the KVM group by following command \n" - " - $sudo addgroup `whoami` kvm"); - exit(0); - - ret = -errno; - goto err; - } - - ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0); - if (ret < KVM_API_VERSION) { - if (ret > 0) { - ret = -EINVAL; - } - fprintf(stderr, "kvm version too old\n"); - show_message("Error", "KVM version too old \n"); - goto err; - } - - if (ret > KVM_API_VERSION) { - ret = -EINVAL; - fprintf(stderr, "kvm version not supported\n"); - show_message("Error", "KVM version not supported \n"); - goto err; - } - - s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0); - if (s->vmfd < 0) { + for (i = 0; i < ARRAY_SIZE(s->slots); i++) { + s->slots[i].slot = i; + } + s->vmfd = -1; + s->fd = qemu_open("/dev/kvm", O_RDWR); + if (s->fd == -1) { + fprintf(stderr, "Could not access KVM kernel module: %m\n"); + ret = -errno; + goto err; + } + + ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0); + if (ret < KVM_API_VERSION) { + if (ret > 0) { + ret = -EINVAL; + } + fprintf(stderr, "kvm version too old\n"); + goto err; + } + + if (ret > KVM_API_VERSION) { + ret = -EINVAL; + fprintf(stderr, "kvm version not supported\n"); + goto err; + } + + s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0); + if (s->vmfd < 0) { #ifdef TARGET_S390X - fprintf(stderr, "Please add the 'switch_amode' kernel parameter to " - "your host kernel command line\n"); -#endif - goto err; - } - - missing_cap = kvm_check_extension_list(s, kvm_required_capabilites); - if (!missing_cap) { - missing_cap = - kvm_check_extension_list(s, kvm_arch_required_capabilities); - } - if (missing_cap) { - ret = -EINVAL; - fprintf(stderr, "kvm does not support %s\n%s", - missing_cap->name, upgrade_note); - goto err; - } - - s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO); - - s->broken_set_mem_region = 1; -#ifdef KVM_CAP_JOIN_MEMORY_REGIONS_WORKS - ret = kvm_check_extension(s, KVM_CAP_JOIN_MEMORY_REGIONS_WORKS); - if (ret > 0) { - s->broken_set_mem_region = 0; - } + fprintf(stderr, "Please add the 'switch_amode' kernel parameter to " + "your host kernel command line\n"); #endif + ret = s->vmfd; + goto err; + } + + missing_cap = kvm_check_extension_list(s, kvm_required_capabilites); + if (!missing_cap) { + missing_cap = + kvm_check_extension_list(s, kvm_arch_required_capabilities); + } + if (missing_cap) { + ret = -EINVAL; + fprintf(stderr, "kvm does not support %s\n%s", + missing_cap->name, upgrade_note); + goto err; + } + + s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO); + + s->broken_set_mem_region = 1; + ret = kvm_check_extension(s, KVM_CAP_JOIN_MEMORY_REGIONS_WORKS); + if (ret > 0) { + s->broken_set_mem_region = 0; + } - s->vcpu_events = 0; #ifdef KVM_CAP_VCPU_EVENTS - s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS); + s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS); #endif - s->robust_singlestep = 0; -#ifdef KVM_CAP_X86_ROBUST_SINGLESTEP - s->robust_singlestep = - kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP); -#endif + s->robust_singlestep = + kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP); - s->debugregs = 0; #ifdef KVM_CAP_DEBUGREGS - s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS); + s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS); #endif - s->xsave = 0; #ifdef KVM_CAP_XSAVE - s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE); + s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE); #endif - s->xcrs = 0; #ifdef KVM_CAP_XCRS - s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS); + s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS); #endif - ret = kvm_arch_init(s); - if (ret < 0) { - goto err; - } + ret = kvm_arch_init(s); + if (ret < 0) { + goto err; + } + + kvm_state = s; + cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client); - kvm_state = s; - cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client); + s->many_ioeventfds = kvm_check_many_ioeventfds(); - s->many_ioeventfds = kvm_check_many_ioeventfds(); + cpu_interrupt_handler = kvm_handle_interrupt; - return 0; + return 0; err: - if (s) { - if (s->vmfd != -1) { - close(s->vmfd); - } - if (s->fd != -1) { - close(s->fd); - } - } - qemu_free(s); - - return ret; + if (s) { + if (s->vmfd >= 0) { + close(s->vmfd); + } + if (s->fd != -1) { + close(s->fd); + } + } + g_free(s); + + return ret; } -static int kvm_handle_io(uint16_t port, void *data, int direction, int size, - uint32_t count) -{ - int i; - uint8_t *ptr = data; - - for (i = 0; i < count; i++) { - if (direction == KVM_EXIT_IO_IN) { - switch (size) { - case 1: - stb_p(ptr, cpu_inb(port)); - break; - case 2: - stw_p(ptr, cpu_inw(port)); - break; - case 4: - stl_p(ptr, cpu_inl(port)); - break; - } - } else { - switch (size) { - case 1: - cpu_outb(port, ldub_p(ptr)); - break; - case 2: - cpu_outw(port, lduw_p(ptr)); - break; - case 4: - cpu_outl(port, ldl_p(ptr)); - break; - } - } - - ptr += size; - } - - return 1; +static void kvm_handle_io(uint16_t port, void *data, int direction, int size, + uint32_t count) +{ + int i; + uint8_t *ptr = data; + + for (i = 0; i < count; i++) { + if (direction == KVM_EXIT_IO_IN) { + switch (size) { + case 1: + stb_p(ptr, cpu_inb(port)); + break; + case 2: + stw_p(ptr, cpu_inw(port)); + break; + case 4: + stl_p(ptr, cpu_inl(port)); + break; + } + } else { + switch (size) { + case 1: + cpu_outb(port, ldub_p(ptr)); + break; + case 2: + cpu_outw(port, lduw_p(ptr)); + break; + case 4: + cpu_outl(port, ldl_p(ptr)); + break; + } + } + + ptr += size; + } } -#ifdef KVM_CAP_INTERNAL_ERROR_DATA static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run) { - fprintf(stderr, "KVM internal error."); - if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) { - int i; - - fprintf(stderr, " Suberror: %d\n", run->internal.suberror); - for (i = 0; i < run->internal.ndata; ++i) { - fprintf(stderr, "extra data[%d]: %"PRIx64"\n", - i, (uint64_t)run->internal.data[i]); - } - } else { - fprintf(stderr, "\n"); - } - if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) { - fprintf(stderr, "emulation failure\n"); - if (!kvm_arch_stop_on_emulation_error(env)) { - cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); - return 0; - } - } - /* FIXME: Should trigger a qmp message to let management know - * something went wrong. - */ - return -1; + fprintf(stderr, "KVM internal error."); + if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) { + int i; + + fprintf(stderr, " Suberror: %d\n", run->internal.suberror); + for (i = 0; i < run->internal.ndata; ++i) { + fprintf(stderr, "extra data[%d]: %"PRIx64"\n", + i, (uint64_t)run->internal.data[i]); + } + } else { + fprintf(stderr, "\n"); + } + if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) { + fprintf(stderr, "emulation failure\n"); + if (!kvm_arch_stop_on_emulation_error(env)) { + cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); + return EXCP_INTERRUPT; + } + } + /* FIXME: Should trigger a qmp message to let management know + * something went wrong. + */ + return -1; } -#endif void kvm_flush_coalesced_mmio_buffer(void) { - KVMState *s = kvm_state; - if (s->coalesced_mmio_ring) { - struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring; - while (ring->first != ring->last) { - struct kvm_coalesced_mmio *ent; + KVMState *s = kvm_state; + + if (s->coalesced_flush_in_progress) { + return; + } + + s->coalesced_flush_in_progress = true; + + if (s->coalesced_mmio_ring) { + struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring; + while (ring->first != ring->last) { + struct kvm_coalesced_mmio *ent; + + ent = &ring->coalesced_mmio[ring->first]; - ent = &ring->coalesced_mmio[ring->first]; + cpu_physical_memory_write(ent->phys_addr, ent->data, ent->len); + smp_wmb(); + ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX; + } + } - cpu_physical_memory_write(ent->phys_addr, ent->data, ent->len); - smp_wmb(); - ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX; - } - } + s->coalesced_flush_in_progress = false; } static void do_kvm_cpu_synchronize_state(void *_env) { - CPUState *env = _env; + CPUState *env = _env; - if (!env->kvm_vcpu_dirty) { - kvm_arch_get_registers(env); - env->kvm_vcpu_dirty = 1; - } + if (!env->kvm_vcpu_dirty) { + kvm_arch_get_registers(env); + env->kvm_vcpu_dirty = 1; + } } void kvm_cpu_synchronize_state(CPUState *env) { - if (!env->kvm_vcpu_dirty) { - run_on_cpu(env, do_kvm_cpu_synchronize_state, env); - } + if (!env->kvm_vcpu_dirty) { + run_on_cpu(env, do_kvm_cpu_synchronize_state, env); + } } void kvm_cpu_synchronize_post_reset(CPUState *env) { - kvm_arch_put_registers(env, KVM_PUT_RESET_STATE); - env->kvm_vcpu_dirty = 0; + kvm_arch_put_registers(env, KVM_PUT_RESET_STATE); + env->kvm_vcpu_dirty = 0; } void kvm_cpu_synchronize_post_init(CPUState *env) { - kvm_arch_put_registers(env, KVM_PUT_FULL_STATE); - env->kvm_vcpu_dirty = 0; + kvm_arch_put_registers(env, KVM_PUT_FULL_STATE); + env->kvm_vcpu_dirty = 0; } int kvm_cpu_exec(CPUState *env) { - struct kvm_run *run = env->kvm_run; - int ret; - - DPRINTF("kvm_cpu_exec()\n"); - - do { -#ifndef CONFIG_IOTHREAD - if (env->exit_request) { - DPRINTF("interrupt exit requested\n"); - ret = 0; - break; - } -#endif - - if (kvm_arch_process_irqchip_events(env)) { - ret = 0; - break; - } - - if (env->kvm_vcpu_dirty) { - kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE); - env->kvm_vcpu_dirty = 0; - } - - kvm_arch_pre_run(env, run); - cpu_single_env = NULL; - qemu_mutex_unlock_iothread(); - ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); - qemu_mutex_lock_iothread(); - cpu_single_env = env; - kvm_arch_post_run(env, run); - - kvm_flush_coalesced_mmio_buffer(); - - if (ret == -EINTR || ret == -EAGAIN) { - cpu_exit(env); - DPRINTF("io window exit\n"); - ret = 0; - break; - } - - if (ret < 0) { - DPRINTF("kvm run failed %s\n", strerror(-ret)); - abort(); - } - - ret = 0; /* exit loop */ - switch (run->exit_reason) { - case KVM_EXIT_IO: - DPRINTF("handle_io\n"); - ret = kvm_handle_io(run->io.port, - (uint8_t *)run + run->io.data_offset, - run->io.direction, - run->io.size, - run->io.count); - break; - case KVM_EXIT_MMIO: - DPRINTF("handle_mmio\n"); - cpu_physical_memory_rw(run->mmio.phys_addr, - run->mmio.data, - run->mmio.len, - run->mmio.is_write); - ret = 1; - break; - case KVM_EXIT_IRQ_WINDOW_OPEN: - DPRINTF("irq_window_open\n"); - break; - case KVM_EXIT_SHUTDOWN: - DPRINTF("shutdown\n"); - qemu_system_reset_request(); - ret = 1; - break; - case KVM_EXIT_UNKNOWN: - fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n", - (uint64_t)run->hw.hardware_exit_reason); - ret = -1; - break; -#ifdef KVM_CAP_INTERNAL_ERROR_DATA - case KVM_EXIT_INTERNAL_ERROR: - ret = kvm_handle_internal_error(env, run); - break; -#endif - case KVM_EXIT_DEBUG: - DPRINTF("kvm_exit_debug\n"); -#ifdef KVM_CAP_SET_GUEST_DEBUG - if (kvm_arch_debug(&run->debug.arch)) { - env->exception_index = EXCP_DEBUG; - return 0; - } - /* re-enter, this exception was guest-internal */ - ret = 1; -#endif /* KVM_CAP_SET_GUEST_DEBUG */ - break; - default: - DPRINTF("kvm_arch_handle_exit\n"); - ret = kvm_arch_handle_exit(env, run); - break; - } - } while (ret > 0); - - if (ret < 0) { - - show_message("Error", "Emulator can't operate in VMX root mode(KVM) \n" - "Please disable the VT-x kernel extension(Ex: Virtualbox)"); - - cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); - vm_stop(0); - - exit(0); - - env->exit_request = 1; - } - if (env->exit_request) { - env->exit_request = 0; - env->exception_index = EXCP_INTERRUPT; - } - - return ret; + struct kvm_run *run = env->kvm_run; + int ret, run_ret; + + DPRINTF("kvm_cpu_exec()\n"); + + if (kvm_arch_process_async_events(env)) { + env->exit_request = 0; + return EXCP_HLT; + } + + cpu_single_env = env; + + do { + if (env->kvm_vcpu_dirty) { + kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE); + env->kvm_vcpu_dirty = 0; + } + + kvm_arch_pre_run(env, run); + if (env->exit_request) { + DPRINTF("interrupt exit requested\n"); + /* + * KVM requires us to reenter the kernel after IO exits to complete + * instruction emulation. This self-signal will ensure that we + * leave ASAP again. + */ + qemu_cpu_kick_self(); + } + cpu_single_env = NULL; + qemu_mutex_unlock_iothread(); + + run_ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); + + qemu_mutex_lock_iothread(); + cpu_single_env = env; + kvm_arch_post_run(env, run); + + kvm_flush_coalesced_mmio_buffer(); + + if (run_ret < 0) { + if (run_ret == -EINTR || run_ret == -EAGAIN) { + DPRINTF("io window exit\n"); + ret = EXCP_INTERRUPT; + break; + } + DPRINTF("kvm run failed %s\n", strerror(-run_ret)); + abort(); + } + + switch (run->exit_reason) { + case KVM_EXIT_IO: + DPRINTF("handle_io\n"); + kvm_handle_io(run->io.port, + (uint8_t *)run + run->io.data_offset, + run->io.direction, + run->io.size, + run->io.count); + ret = 0; + break; + case KVM_EXIT_MMIO: + DPRINTF("handle_mmio\n"); + cpu_physical_memory_rw(run->mmio.phys_addr, + run->mmio.data, + run->mmio.len, + run->mmio.is_write); + ret = 0; + break; + case KVM_EXIT_IRQ_WINDOW_OPEN: + DPRINTF("irq_window_open\n"); + ret = EXCP_INTERRUPT; + break; + case KVM_EXIT_SHUTDOWN: + DPRINTF("shutdown\n"); + qemu_system_reset_request(); + ret = EXCP_INTERRUPT; + break; + case KVM_EXIT_UNKNOWN: + fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n", + (uint64_t)run->hw.hardware_exit_reason); + ret = -1; + break; + case KVM_EXIT_INTERNAL_ERROR: + ret = kvm_handle_internal_error(env, run); + break; + default: + DPRINTF("kvm_arch_handle_exit\n"); + ret = kvm_arch_handle_exit(env, run); + break; + } + } while (ret == 0); + + if (ret < 0) { + cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); + vm_stop(RUN_STATE_INTERNAL_ERROR); + } + + env->exit_request = 0; + cpu_single_env = NULL; + return ret; } int kvm_ioctl(KVMState *s, int type, ...) { - int ret; - void *arg; - va_list ap; - - va_start(ap, type); - arg = va_arg(ap, void *); - va_end(ap); - - ret = ioctl(s->fd, type, arg); - if (ret == -1) { - ret = -errno; - } - return ret; + int ret; + void *arg; + va_list ap; + + va_start(ap, type); + arg = va_arg(ap, void *); + va_end(ap); + + ret = ioctl(s->fd, type, arg); + if (ret == -1) { + ret = -errno; + } + return ret; } int kvm_vm_ioctl(KVMState *s, int type, ...) { - int ret; - void *arg; - va_list ap; - - va_start(ap, type); - arg = va_arg(ap, void *); - va_end(ap); - - ret = ioctl(s->vmfd, type, arg); - if (ret == -1) { - ret = -errno; - } - return ret; + int ret; + void *arg; + va_list ap; + + va_start(ap, type); + arg = va_arg(ap, void *); + va_end(ap); + + ret = ioctl(s->vmfd, type, arg); + if (ret == -1) { + ret = -errno; + } + return ret; } int kvm_vcpu_ioctl(CPUState *env, int type, ...) { - int ret; - void *arg; - va_list ap; - - va_start(ap, type); - arg = va_arg(ap, void *); - va_end(ap); - - ret = ioctl(env->kvm_fd, type, arg); - if (ret == -1) { - ret = -errno; - } - return ret; + int ret; + void *arg; + va_list ap; + + va_start(ap, type); + arg = va_arg(ap, void *); + va_end(ap); + + ret = ioctl(env->kvm_fd, type, arg); + if (ret == -1) { + ret = -errno; + } + return ret; } int kvm_has_sync_mmu(void) { - return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU); + return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU); } int kvm_has_vcpu_events(void) { - return kvm_state->vcpu_events; + return kvm_state->vcpu_events; } int kvm_has_robust_singlestep(void) { - return kvm_state->robust_singlestep; + return kvm_state->robust_singlestep; } int kvm_has_debugregs(void) { - return kvm_state->debugregs; + return kvm_state->debugregs; } int kvm_has_xsave(void) { - return kvm_state->xsave; + return kvm_state->xsave; } int kvm_has_xcrs(void) { - return kvm_state->xcrs; + return kvm_state->xcrs; } int kvm_has_many_ioeventfds(void) { - if (!kvm_enabled()) { - return 0; - } - return kvm_state->many_ioeventfds; + if (!kvm_enabled()) { + return 0; + } + return kvm_state->many_ioeventfds; } void kvm_setup_guest_memory(void *start, size_t size) { - if (!kvm_has_sync_mmu()) { - int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK); - - if (ret) { - perror("qemu_madvise"); - fprintf(stderr, - "Need MADV_DONTFORK in absence of synchronous KVM MMU\n"); - exit(1); - } - } + if (!kvm_has_sync_mmu()) { + int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK); + + if (ret) { + perror("qemu_madvise"); + fprintf(stderr, + "Need MADV_DONTFORK in absence of synchronous KVM MMU\n"); + exit(1); + } + } } #ifdef KVM_CAP_SET_GUEST_DEBUG struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env, - target_ulong pc) + target_ulong pc) { - struct kvm_sw_breakpoint *bp; - - QTAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) { - if (bp->pc == pc) { - return bp; - } - } - return NULL; + struct kvm_sw_breakpoint *bp; + + QTAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) { + if (bp->pc == pc) { + return bp; + } + } + return NULL; } int kvm_sw_breakpoints_active(CPUState *env) { - return !QTAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints); + return !QTAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints); } struct kvm_set_guest_debug_data { - struct kvm_guest_debug dbg; - CPUState *env; - int err; + struct kvm_guest_debug dbg; + CPUState *env; + int err; }; static void kvm_invoke_set_guest_debug(void *data) { - struct kvm_set_guest_debug_data *dbg_data = data; - CPUState *env = dbg_data->env; + struct kvm_set_guest_debug_data *dbg_data = data; + CPUState *env = dbg_data->env; - dbg_data->err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg); + dbg_data->err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg); } int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap) { - struct kvm_set_guest_debug_data data; + struct kvm_set_guest_debug_data data; - data.dbg.control = reinject_trap; + data.dbg.control = reinject_trap; - if (env->singlestep_enabled) { - data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; - } - kvm_arch_update_guest_debug(env, &data.dbg); - data.env = env; + if (env->singlestep_enabled) { + data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; + } + kvm_arch_update_guest_debug(env, &data.dbg); + data.env = env; - run_on_cpu(env, kvm_invoke_set_guest_debug, &data); - return data.err; + run_on_cpu(env, kvm_invoke_set_guest_debug, &data); + return data.err; } int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr, - target_ulong len, int type) -{ - struct kvm_sw_breakpoint *bp; - CPUState *env; - int err; - - if (type == GDB_BREAKPOINT_SW) { - bp = kvm_find_sw_breakpoint(current_env, addr); - if (bp) { - bp->use_count++; - return 0; - } - - bp = qemu_malloc(sizeof(struct kvm_sw_breakpoint)); - if (!bp) { - return -ENOMEM; - } - - bp->pc = addr; - bp->use_count = 1; - err = kvm_arch_insert_sw_breakpoint(current_env, bp); - if (err) { - free(bp); - return err; - } - - QTAILQ_INSERT_HEAD(¤t_env->kvm_state->kvm_sw_breakpoints, - bp, entry); - } else { - err = kvm_arch_insert_hw_breakpoint(addr, len, type); - if (err) { - return err; - } - } - - for (env = first_cpu; env != NULL; env = env->next_cpu) { - err = kvm_update_guest_debug(env, 0); - if (err) { - return err; - } - } - return 0; + target_ulong len, int type) +{ + struct kvm_sw_breakpoint *bp; + CPUState *env; + int err; + + if (type == GDB_BREAKPOINT_SW) { + bp = kvm_find_sw_breakpoint(current_env, addr); + if (bp) { + bp->use_count++; + return 0; + } + + bp = g_malloc(sizeof(struct kvm_sw_breakpoint)); + if (!bp) { + return -ENOMEM; + } + + bp->pc = addr; + bp->use_count = 1; + err = kvm_arch_insert_sw_breakpoint(current_env, bp); + if (err) { + g_free(bp); + return err; + } + + QTAILQ_INSERT_HEAD(¤t_env->kvm_state->kvm_sw_breakpoints, + bp, entry); + } else { + err = kvm_arch_insert_hw_breakpoint(addr, len, type); + if (err) { + return err; + } + } + + for (env = first_cpu; env != NULL; env = env->next_cpu) { + err = kvm_update_guest_debug(env, 0); + if (err) { + return err; + } + } + return 0; } int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr, - target_ulong len, int type) -{ - struct kvm_sw_breakpoint *bp; - CPUState *env; - int err; - - if (type == GDB_BREAKPOINT_SW) { - bp = kvm_find_sw_breakpoint(current_env, addr); - if (!bp) { - return -ENOENT; - } - - if (bp->use_count > 1) { - bp->use_count--; - return 0; - } - - err = kvm_arch_remove_sw_breakpoint(current_env, bp); - if (err) { - return err; - } - - QTAILQ_REMOVE(¤t_env->kvm_state->kvm_sw_breakpoints, bp, entry); - qemu_free(bp); - } else { - err = kvm_arch_remove_hw_breakpoint(addr, len, type); - if (err) { - return err; - } - } - - for (env = first_cpu; env != NULL; env = env->next_cpu) { - err = kvm_update_guest_debug(env, 0); - if (err) { - return err; - } - } - return 0; + target_ulong len, int type) +{ + struct kvm_sw_breakpoint *bp; + CPUState *env; + int err; + + if (type == GDB_BREAKPOINT_SW) { + bp = kvm_find_sw_breakpoint(current_env, addr); + if (!bp) { + return -ENOENT; + } + + if (bp->use_count > 1) { + bp->use_count--; + return 0; + } + + err = kvm_arch_remove_sw_breakpoint(current_env, bp); + if (err) { + return err; + } + + QTAILQ_REMOVE(¤t_env->kvm_state->kvm_sw_breakpoints, bp, entry); + g_free(bp); + } else { + err = kvm_arch_remove_hw_breakpoint(addr, len, type); + if (err) { + return err; + } + } + + for (env = first_cpu; env != NULL; env = env->next_cpu) { + err = kvm_update_guest_debug(env, 0); + if (err) { + return err; + } + } + return 0; } void kvm_remove_all_breakpoints(CPUState *current_env) { - struct kvm_sw_breakpoint *bp, *next; - KVMState *s = current_env->kvm_state; - CPUState *env; - - QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) { - if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) { - /* Try harder to find a CPU that currently sees the breakpoint. */ - for (env = first_cpu; env != NULL; env = env->next_cpu) { - if (kvm_arch_remove_sw_breakpoint(env, bp) == 0) { - break; - } - } - } - } - kvm_arch_remove_all_hw_breakpoints(); - - for (env = first_cpu; env != NULL; env = env->next_cpu) { - kvm_update_guest_debug(env, 0); - } + struct kvm_sw_breakpoint *bp, *next; + KVMState *s = current_env->kvm_state; + CPUState *env; + + QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) { + if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) { + /* Try harder to find a CPU that currently sees the breakpoint. */ + for (env = first_cpu; env != NULL; env = env->next_cpu) { + if (kvm_arch_remove_sw_breakpoint(env, bp) == 0) { + break; + } + } + } + } + kvm_arch_remove_all_hw_breakpoints(); + + for (env = first_cpu; env != NULL; env = env->next_cpu) { + kvm_update_guest_debug(env, 0); + } } #else /* !KVM_CAP_SET_GUEST_DEBUG */ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap) { - return -EINVAL; + return -EINVAL; } int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr, - target_ulong len, int type) + target_ulong len, int type) { - return -EINVAL; + return -EINVAL; } int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr, - target_ulong len, int type) + target_ulong len, int type) { - return -EINVAL; + return -EINVAL; } void kvm_remove_all_breakpoints(CPUState *current_env) @@ -1307,78 +1320,80 @@ void kvm_remove_all_breakpoints(CPUState *current_env) int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset) { - struct kvm_signal_mask *sigmask; - int r; + struct kvm_signal_mask *sigmask; + int r; - if (!sigset) { - return kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, NULL); - } + if (!sigset) { + return kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, NULL); + } - sigmask = qemu_malloc(sizeof(*sigmask) + sizeof(*sigset)); + sigmask = g_malloc(sizeof(*sigmask) + sizeof(*sigset)); - sigmask->len = 8; - memcpy(sigmask->sigset, sigset, sizeof(*sigset)); - r = kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, sigmask); - free(sigmask); + sigmask->len = 8; + memcpy(sigmask->sigset, sigset, sizeof(*sigset)); + r = kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, sigmask); + g_free(sigmask); - return r; + return r; } int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign) { -#ifdef KVM_IOEVENTFD - int ret; - struct kvm_ioeventfd iofd; + int ret; + struct kvm_ioeventfd iofd; - iofd.datamatch = val; - iofd.addr = addr; - iofd.len = 4; - iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH; - iofd.fd = fd; + iofd.datamatch = val; + iofd.addr = addr; + iofd.len = 4; + iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH; + iofd.fd = fd; - if (!kvm_enabled()) { - return -ENOSYS; - } + if (!kvm_enabled()) { + return -ENOSYS; + } - if (!assign) { - iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; - } + if (!assign) { + iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; + } - ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd); + ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd); - if (ret < 0) { - return -errno; - } + if (ret < 0) { + return -errno; + } - return 0; -#else - return -ENOSYS; -#endif + return 0; } int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) { -#ifdef KVM_IOEVENTFD - struct kvm_ioeventfd kick = { - .datamatch = val, - .addr = addr, - .len = 2, - .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO, - .fd = fd, - }; - int r; - if (!kvm_enabled()) { - return -ENOSYS; - } - if (!assign) { - kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; - } - r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); - if (r < 0) { - return r; - } - return 0; -#else - return -ENOSYS; -#endif + struct kvm_ioeventfd kick = { + .datamatch = val, + .addr = addr, + .len = 2, + .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO, + .fd = fd, + }; + int r; + if (!kvm_enabled()) { + return -ENOSYS; + } + if (!assign) { + kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; + } + r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); + if (r < 0) { + return r; + } + return 0; +} + +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ + return kvm_arch_on_sigbus_vcpu(env, code, addr); +} + +int kvm_on_sigbus(int code, void *addr) +{ + return kvm_arch_on_sigbus(code, addr); } diff --git a/kvm-stub.c b/kvm-stub.c index 88682f2..06064b9 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -11,9 +11,8 @@ */ #include "qemu-common.h" -#include "sysemu.h" #include "hw/hw.h" -#include "exec-all.h" +#include "cpu.h" #include "gdbstub.h" #include "kvm.h" @@ -33,16 +32,6 @@ int kvm_init_vcpu(CPUState *env) return -ENOSYS; } -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) -{ - return -ENOSYS; -} - -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) -{ - return -ENOSYS; -} - int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) { return -ENOSYS; @@ -53,11 +42,6 @@ int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size) return -ENOSYS; } -int kvm_check_extension(KVMState *s, unsigned int extension) -{ - return 0; -} - int kvm_init(void) { return -ENOSYS; @@ -89,16 +73,6 @@ int kvm_has_sync_mmu(void) return 0; } -int kvm_has_vcpu_events(void) -{ - return 0; -} - -int kvm_has_robust_singlestep(void) -{ - return 0; -} - int kvm_has_many_ioeventfds(void) { return 0; @@ -110,8 +84,7 @@ void kvm_setup_guest_memory(void *start, size_t size) int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap) { - tb_flush(env); - return 0; + return -ENOSYS; } int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr, @@ -147,6 +120,11 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign) return -ENOSYS; } +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ + return 1; +} + int kvm_on_sigbus(int code, void *addr) { return 1; diff --git a/kvm.h b/kvm.h index ca57517..e764682 100644 --- a/kvm.h +++ b/kvm.h @@ -58,9 +58,6 @@ int kvm_init_vcpu(CPUState *env); int kvm_cpu_exec(CPUState *env); #if !defined(CONFIG_USER_ONLY) -int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size); -int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size); - void kvm_setup_guest_memory(void *start, size_t size); int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); @@ -81,10 +78,14 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset); int kvm_pit_in_kernel(void); int kvm_irqchip_in_kernel(void); +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr); +int kvm_on_sigbus(int code, void *addr); + /* internal API */ struct KVMState; typedef struct KVMState KVMState; +extern KVMState *kvm_state; int kvm_ioctl(KVMState *s, int type, ...); @@ -96,13 +97,12 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...); extern const KVMCapabilityInfo kvm_arch_required_capabilities[]; -int kvm_arch_post_run(CPUState *env, struct kvm_run *run); +void kvm_arch_pre_run(CPUState *env, struct kvm_run *run); +void kvm_arch_post_run(CPUState *env, struct kvm_run *run); int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run); -int kvm_arch_pre_run(CPUState *env, struct kvm_run *run); - -int kvm_arch_process_irqchip_events(CPUState *env); +int kvm_arch_process_async_events(CPUState *env); int kvm_arch_get_registers(CPUState *env); @@ -121,8 +121,8 @@ int kvm_arch_init_vcpu(CPUState *env); void kvm_arch_reset_vcpu(CPUState *env); -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr); -int kvm_on_sigbus(int code, void *addr); +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr); +int kvm_arch_on_sigbus(int code, void *addr); struct kvm_guest_debug; struct kvm_debug_exit_arch; @@ -136,8 +136,6 @@ struct kvm_sw_breakpoint { QTAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint); -int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info); - struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env, target_ulong pc); @@ -159,19 +157,26 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env); int kvm_check_extension(KVMState *s, unsigned int extension); -uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, +uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function, uint32_t index, int reg); void kvm_cpu_synchronize_state(CPUState *env); void kvm_cpu_synchronize_post_reset(CPUState *env); void kvm_cpu_synchronize_post_init(CPUState *env); /* generic hooks - to be moved/refactored once there are more users */ - +#ifdef CONFIG_HAX +void hax_cpu_synchronize_state(CPUState *env); +void hax_cpu_synchronize_post_reset(CPUState *env); +void hax_cpu_synchronize_post_init(CPUState *env); +#endif static inline void cpu_synchronize_state(CPUState *env) { if (kvm_enabled()) { kvm_cpu_synchronize_state(env); } +#ifdef CONFIG_HAX + hax_cpu_synchronize_state(env); +#endif } static inline void cpu_synchronize_post_reset(CPUState *env) @@ -179,6 +184,9 @@ static inline void cpu_synchronize_post_reset(CPUState *env) if (kvm_enabled()) { kvm_cpu_synchronize_post_reset(env); } +#ifdef CONFIG_HAX + hax_cpu_synchronize_post_reset(env); +#endif } static inline void cpu_synchronize_post_init(CPUState *env) @@ -186,6 +194,9 @@ static inline void cpu_synchronize_post_init(CPUState *env) if (kvm_enabled()) { kvm_cpu_synchronize_post_init(env); } +#ifdef CONFIG_HAX + hax_cpu_synchronize_post_init(env); +#endif } diff --git a/libfdt_env.h b/libfdt_env.h index ee0419f..90d7f3b 100644 --- a/libfdt_env.h +++ b/libfdt_env.h @@ -19,13 +19,9 @@ #ifndef _LIBFDT_ENV_H #define _LIBFDT_ENV_H -#include -#include -#include -#include -#include +#include "bswap.h" -#if __BYTE_ORDER == __BIG_ENDIAN +#ifdef HOST_WORDS_BIGENDIAN #define fdt32_to_cpu(x) (x) #define cpu_to_fdt32(x) (x) #define fdt64_to_cpu(x) (x) diff --git a/linux-aio.c b/linux-aio.c index 68f4b3d..1c635ef 100644 --- a/linux-aio.c +++ b/linux-aio.c @@ -31,7 +31,8 @@ struct qemu_laiocb { struct iocb iocb; ssize_t ret; size_t nbytes; - int async_context_id; + QEMUIOVector *qiov; + bool is_read; QLIST_ENTRY(qemu_laiocb) node; }; @@ -39,7 +40,6 @@ struct qemu_laio_state { io_context_t ctx; int efd; int count; - QLIST_HEAD(, qemu_laiocb) completed_reqs; }; static inline ssize_t io_event_ret(struct io_event *ev) @@ -49,7 +49,6 @@ static inline ssize_t io_event_ret(struct io_event *ev) /* * Completes an AIO request (calls the callback and frees the ACB). - * Be sure to be in the right AsyncContext before calling this function. */ static void qemu_laio_process_completion(struct qemu_laio_state *s, struct qemu_laiocb *laiocb) @@ -60,10 +59,17 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s, ret = laiocb->ret; if (ret != -ECANCELED) { - if (ret == laiocb->nbytes) + if (ret == laiocb->nbytes) { ret = 0; - else if (ret >= 0) - ret = -EINVAL; + } else if (ret >= 0) { + /* Short reads mean EOF, pad with zeros. */ + if (laiocb->is_read) { + qemu_iovec_memset_skip(laiocb->qiov, 0, + laiocb->qiov->size - ret, ret); + } else { + ret = -EINVAL; + } + } laiocb->common.cb(laiocb->common.opaque, ret); } @@ -71,45 +77,6 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s, qemu_aio_release(laiocb); } -/* - * Processes all queued AIO requests, i.e. requests that have return from OS - * but their callback was not called yet. Requests that cannot have their - * callback called in the current AsyncContext, remain in the queue. - * - * Returns 1 if at least one request could be completed, 0 otherwise. - */ -static int qemu_laio_process_requests(void *opaque) -{ - struct qemu_laio_state *s = opaque; - struct qemu_laiocb *laiocb, *next; - int res = 0; - - QLIST_FOREACH_SAFE (laiocb, &s->completed_reqs, node, next) { - if (laiocb->async_context_id == get_async_context_id()) { - qemu_laio_process_completion(s, laiocb); - QLIST_REMOVE(laiocb, node); - res = 1; - } - } - - return res; -} - -/* - * Puts a request in the completion queue so that its callback is called the - * next time when it's possible. If we already are in the right AsyncContext, - * the request is completed immediately instead. - */ -static void qemu_laio_enqueue_completed(struct qemu_laio_state *s, - struct qemu_laiocb* laiocb) -{ - if (laiocb->async_context_id == get_async_context_id()) { - qemu_laio_process_completion(s, laiocb); - } else { - QLIST_INSERT_HEAD(&s->completed_reqs, laiocb, node); - } -} - static void qemu_laio_completion_cb(void *opaque) { struct qemu_laio_state *s = opaque; @@ -141,7 +108,7 @@ static void qemu_laio_completion_cb(void *opaque) container_of(iocb, struct qemu_laiocb, iocb); laiocb->ret = io_event_ret(&events[i]); - qemu_laio_enqueue_completed(s, laiocb); + qemu_laio_process_completion(s, laiocb); } } } @@ -204,7 +171,8 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, laiocb->nbytes = nb_sectors * 512; laiocb->ctx = s; laiocb->ret = -EINPROGRESS; - laiocb->async_context_id = get_async_context_id(); + laiocb->is_read = (type == QEMU_AIO_READ); + laiocb->qiov = qiov; iocbs = &laiocb->iocb; @@ -215,6 +183,7 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, case QEMU_AIO_READ: io_prep_preadv(iocbs, fd, qiov->iov, qiov->niov, offset); break; + /* Currently Linux kernel does not support other operations */ default: fprintf(stderr, "%s: invalid AIO request type 0x%x.\n", __func__, type); @@ -227,10 +196,10 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, goto out_dec_count; return &laiocb->common; -out_free_aiocb: - qemu_aio_release(laiocb); out_dec_count: s->count--; +out_free_aiocb: + qemu_aio_release(laiocb); return NULL; } @@ -238,8 +207,7 @@ void *laio_init(void) { struct qemu_laio_state *s; - s = qemu_mallocz(sizeof(*s)); - QLIST_INIT(&s->completed_reqs); + s = g_malloc0(sizeof(*s)); s->efd = eventfd(0, 0); if (s->efd == -1) goto out_free_state; @@ -249,13 +217,13 @@ void *laio_init(void) goto out_close_efd; qemu_aio_set_fd_handler(s->efd, qemu_laio_completion_cb, NULL, - qemu_laio_flush_cb, qemu_laio_process_requests, s); + qemu_laio_flush_cb, NULL, s); return s; out_close_efd: close(s->efd); out_free_state: - qemu_free(s); + g_free(s); return NULL; } diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h index 7182223..f6284db 100644 --- a/linux-user/alpha/syscall_nr.h +++ b/linux-user/alpha/syscall_nr.h @@ -411,11 +411,25 @@ #define TARGET_NR_signalfd 476 #define TARGET_NR_timerfd 477 #define TARGET_NR_eventfd 478 - -/* The following aliases are defined in order to match up with the - standard i386 syscalls implemented in syscalls.c. */ -#define TARGET_NR_chown32 TARGET_NR_chown -#define TARGET_NR_setuid32 TARGET_NR_setuid -#define TARGET_NR_setgid32 TARGET_NR_setgid -#define TARGET_NR_setfsuid32 TARGET_NR_setfsuid -#define TARGET_NR_setfsgid32 TARGET_NR_setfsgid +#define TARGET_NR_recvmmsg 479 +#define TARGET_NR_fallocate 480 +#define TARGET_NR_timerfd_create 481 +#define TARGET_NR_timerfd_settime 482 +#define TARGET_NR_timerfd_gettime 483 +#define TARGET_NR_signalfd4 484 +#define TARGET_NR_eventfd2 485 +#define TARGET_NR_epoll_create1 486 +#define TARGET_NR_dup3 487 +#define TARGET_NR_pipe2 488 +#define TARGET_NR_inotify_init1 489 +#define TARGET_NR_preadv 490 +#define TARGET_NR_pwritev 491 +#define TARGET_NR_rt_tgsigqueueinfo 492 +#define TARGET_NR_perf_event_open 493 +#define TARGET_NR_fanotify_init 494 +#define TARGET_NR_fanotify_mark 495 +#define TARGET_NR_prlimit64 496 +#define TARGET_NR_name_to_handle_at 497 +#define TARGET_NR_open_by_handle_at 498 +#define TARGET_NR_clock_adjtime 499 +#define TARGET_NR_syncfs 500 diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c index 0a87c43..eebd93f 100644 --- a/linux-user/arm/nwfpe/fpa11.c +++ b/linux-user/arm/nwfpe/fpa11.c @@ -144,7 +144,7 @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs) #if 0 fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n", - opcode, qregs[REG_PC]); + opcode, qregs[ARM_REG_PC]); #endif fpa11 = GET_FPA11(); diff --git a/linux-user/arm/nwfpe/fpa11.h b/linux-user/arm/nwfpe/fpa11.h index f17647b..002b3cb 100644 --- a/linux-user/arm/nwfpe/fpa11.h +++ b/linux-user/arm/nwfpe/fpa11.h @@ -111,7 +111,7 @@ static inline void writeConditionCodes(unsigned int x) cpsr_write(user_registers,x,CPSR_NZCV); } -#define REG_PC 15 +#define ARM_REG_PC 15 unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs); diff --git a/linux-user/arm/nwfpe/fpa11_cpdt.c b/linux-user/arm/nwfpe/fpa11_cpdt.c index 1346fd6..3e7a938 100644 --- a/linux-user/arm/nwfpe/fpa11_cpdt.c +++ b/linux-user/arm/nwfpe/fpa11_cpdt.c @@ -33,7 +33,7 @@ void loadSingle(const unsigned int Fn, target_ulong addr) FPA11 *fpa11 = GET_FPA11(); fpa11->fType[Fn] = typeSingle; /* FIXME - handle failure of get_user() */ - get_user_u32(fpa11->fpreg[Fn].fSingle, addr); + get_user_u32(float32_val(fpa11->fpreg[Fn].fSingle), addr); } static inline @@ -220,7 +220,7 @@ static unsigned int PerformLDF(const unsigned int opcode) //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); pBase = readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) + if (ARM_REG_PC == getRn(opcode)) { pBase += 8; write_back = 0; @@ -256,7 +256,7 @@ static unsigned int PerformSTF(const unsigned int opcode) SetRoundingMode(ROUND_TO_NEAREST); pBase = readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) + if (ARM_REG_PC == getRn(opcode)) { pBase += 8; write_back = 0; @@ -289,7 +289,7 @@ static unsigned int PerformLFM(const unsigned int opcode) target_ulong pBase, pAddress, pFinal; pBase = readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) + if (ARM_REG_PC == getRn(opcode)) { pBase += 8; write_back = 0; @@ -322,7 +322,7 @@ static unsigned int PerformSFM(const unsigned int opcode) target_ulong pBase, pAddress, pFinal; pBase = readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) + if (ARM_REG_PC == getRn(opcode)) { pBase += 8; write_back = 0; diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c index be54e95..8011897 100644 --- a/linux-user/arm/nwfpe/fpa11_cprt.c +++ b/linux-user/arm/nwfpe/fpa11_cprt.c @@ -159,7 +159,7 @@ PerformComparisonOperation(floatx80 Fn, floatx80 Fm) } /* test for equal condition */ - if (floatx80_eq(Fn,Fm, &fpa11->fp_status)) + if (floatx80_eq_quiet(Fn,Fm, &fpa11->fp_status)) { flags |= CC_ZERO; } diff --git a/linux-user/arm/nwfpe/fpopcode.c b/linux-user/arm/nwfpe/fpopcode.c index 240061d..82ac92f 100644 --- a/linux-user/arm/nwfpe/fpopcode.c +++ b/linux-user/arm/nwfpe/fpopcode.c @@ -37,25 +37,25 @@ const floatx80 floatx80Constant[] = { }; const float64 float64Constant[] = { - 0x0000000000000000ULL, /* double 0.0 */ - 0x3ff0000000000000ULL, /* double 1.0 */ - 0x4000000000000000ULL, /* double 2.0 */ - 0x4008000000000000ULL, /* double 3.0 */ - 0x4010000000000000ULL, /* double 4.0 */ - 0x4014000000000000ULL, /* double 5.0 */ - 0x3fe0000000000000ULL, /* double 0.5 */ - 0x4024000000000000ULL /* double 10.0 */ + const_float64(0x0000000000000000ULL), /* double 0.0 */ + const_float64(0x3ff0000000000000ULL), /* double 1.0 */ + const_float64(0x4000000000000000ULL), /* double 2.0 */ + const_float64(0x4008000000000000ULL), /* double 3.0 */ + const_float64(0x4010000000000000ULL), /* double 4.0 */ + const_float64(0x4014000000000000ULL), /* double 5.0 */ + const_float64(0x3fe0000000000000ULL), /* double 0.5 */ + const_float64(0x4024000000000000ULL) /* double 10.0 */ }; const float32 float32Constant[] = { - 0x00000000, /* single 0.0 */ - 0x3f800000, /* single 1.0 */ - 0x40000000, /* single 2.0 */ - 0x40400000, /* single 3.0 */ - 0x40800000, /* single 4.0 */ - 0x40a00000, /* single 5.0 */ - 0x3f000000, /* single 0.5 */ - 0x41200000 /* single 10.0 */ + const_float32(0x00000000), /* single 0.0 */ + const_float32(0x3f800000), /* single 1.0 */ + const_float32(0x40000000), /* single 2.0 */ + const_float32(0x40400000), /* single 3.0 */ + const_float32(0x40800000), /* single 4.0 */ + const_float32(0x40a00000), /* single 5.0 */ + const_float32(0x3f000000), /* single 0.5 */ + const_float32(0x41200000) /* single 10.0 */ }; unsigned int getRegisterCount(const unsigned int opcode) diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h index 79a216a..7f05879 100644 --- a/linux-user/arm/syscall_nr.h +++ b/linux-user/arm/syscall_nr.h @@ -365,3 +365,16 @@ #define TARGET_NR_dup3 (358) #define TARGET_NR_pipe2 (359) #define TARGET_NR_inotify_init1 (360) +#define TARGET_NR_preadv (361) +#define TARGET_NR_pwritev (362) +#define TARGET_NR_rt_tgsigqueueinfo (363) +#define TARGET_NR_perf_event_open (364) +#define TARGET_NR_recvmmsg (365) +#define TARGET_NR_accept4 (366) +#define TARGET_NR_fanotify_init (367) +#define TARGET_NR_fanotify_mark (368) +#define TARGET_NR_prlimit64 (369) +#define TARGET_NR_name_to_handle_at (370) +#define TARGET_NR_open_by_handle_at (371) +#define TARGET_NR_clock_adjtime (372) +#define TARGET_NR_syncfs (373) diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h index 6132817..98f1a0b 100644 --- a/linux-user/cris/syscall_nr.h +++ b/linux-user/cris/syscall_nr.h @@ -333,3 +333,5 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2 331 #define TARGET_NR_inotify_init1 332 +#define TARGET_NR_preadv 333 +#define TARGET_NR_pwritev 334 diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 08c44d8..4635bb2 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -103,13 +103,13 @@ enum { typedef target_ulong target_elf_greg_t; #ifdef USE_UID16 -typedef uint16_t target_uid_t; -typedef uint16_t target_gid_t; +typedef target_ushort target_uid_t; +typedef target_ushort target_gid_t; #else -typedef uint32_t target_uid_t; -typedef uint32_t target_gid_t; +typedef target_uint target_uid_t; +typedef target_uint target_gid_t; #endif -typedef int32_t target_pid_t; +typedef target_int target_pid_t; #ifdef TARGET_I386 @@ -332,6 +332,49 @@ enum ARM_HWCAP_ARM_VFPv3D16 = 1 << 13, }; +#define TARGET_HAS_GUEST_VALIDATE_BASE +/* We want the opportunity to check the suggested base */ +bool guest_validate_base(unsigned long guest_base) +{ + unsigned long real_start, test_page_addr; + + /* We need to check that we can force a fault on access to the + * commpage at 0xffff0fxx + */ + test_page_addr = guest_base + (0xffff0f00 & qemu_host_page_mask); + /* Note it needs to be writeable to let us initialise it */ + real_start = (unsigned long) + mmap((void *)test_page_addr, qemu_host_page_size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + /* If we can't map it then try another address */ + if (real_start == -1ul) { + return 0; + } + + if (real_start != test_page_addr) { + /* OS didn't put the page where we asked - unmap and reject */ + munmap((void *)real_start, qemu_host_page_size); + return 0; + } + + /* Leave the page mapped + * Populate it (mmap should have left it all 0'd) + */ + + /* Kernel helper versions */ + __put_user(5, (uint32_t *)g2h(0xffff0ffcul)); + + /* Now it's populated make it RO */ + if (mprotect((void *)test_page_addr, qemu_host_page_size, PROT_READ)) { + perror("Protecting guest commpage"); + exit(-1); + } + + return 1; /* All good */ +} + #define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \ | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \ | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP \ @@ -339,11 +382,86 @@ enum #endif +#ifdef TARGET_UNICORE32 + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ((x) == EM_UNICORE32) + +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_UNICORE32 + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + abi_long stack = infop->start_stack; + memset(regs, 0, sizeof(*regs)); + regs->UC32_REG_asr = 0x10; + regs->UC32_REG_pc = infop->entry & 0xfffffffe; + regs->UC32_REG_sp = infop->start_stack; + /* FIXME - what to for failure of get_user()? */ + get_user_ual(regs->UC32_REG_02, stack + 8); /* envp */ + get_user_ual(regs->UC32_REG_01, stack + 4); /* envp */ + /* XXX: it seems that r0 is zeroed after ! */ + regs->UC32_REG_00 = 0; +} + +#define ELF_NREG 34 +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; + +static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env) +{ + (*regs)[0] = env->regs[0]; + (*regs)[1] = env->regs[1]; + (*regs)[2] = env->regs[2]; + (*regs)[3] = env->regs[3]; + (*regs)[4] = env->regs[4]; + (*regs)[5] = env->regs[5]; + (*regs)[6] = env->regs[6]; + (*regs)[7] = env->regs[7]; + (*regs)[8] = env->regs[8]; + (*regs)[9] = env->regs[9]; + (*regs)[10] = env->regs[10]; + (*regs)[11] = env->regs[11]; + (*regs)[12] = env->regs[12]; + (*regs)[13] = env->regs[13]; + (*regs)[14] = env->regs[14]; + (*regs)[15] = env->regs[15]; + (*regs)[16] = env->regs[16]; + (*regs)[17] = env->regs[17]; + (*regs)[18] = env->regs[18]; + (*regs)[19] = env->regs[19]; + (*regs)[20] = env->regs[20]; + (*regs)[21] = env->regs[21]; + (*regs)[22] = env->regs[22]; + (*regs)[23] = env->regs[23]; + (*regs)[24] = env->regs[24]; + (*regs)[25] = env->regs[25]; + (*regs)[26] = env->regs[26]; + (*regs)[27] = env->regs[27]; + (*regs)[28] = env->regs[28]; + (*regs)[29] = env->regs[29]; + (*regs)[30] = env->regs[30]; + (*regs)[31] = env->regs[31]; + + (*regs)[32] = cpu_asr_read((CPUState *)env); + (*regs)[33] = env->regs[0]; /* XXX */ +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#define ELF_HWCAP (UC32_HWCAP_CMOV | UC32_HWCAP_UCF64) + +#endif + #ifdef TARGET_SPARC #ifdef TARGET_SPARC64 #define ELF_START_MMAP 0x80000000 - +#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \ + | HWCAP_SPARC_MULDIV | HWCAP_SPARC_V9) #ifndef TARGET_ABI32 #define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS ) #else @@ -376,7 +494,8 @@ static inline void init_thread(struct target_pt_regs *regs, #else #define ELF_START_MMAP 0x80000000 - +#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \ + | HWCAP_SPARC_MULDIV) #define elf_check_arch(x) ( (x) == EM_SPARC ) #define ELF_CLASS ELFCLASS32 @@ -499,8 +618,8 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * { _regs->gpr[1] = infop->start_stack; #if defined(TARGET_PPC64) && !defined(TARGET_ABI32) - _regs->gpr[2] = ldq_raw(infop->entry + 8) + infop->load_addr; - infop->entry = ldq_raw(infop->entry) + infop->load_addr; + _regs->gpr[2] = ldq_raw(infop->entry + 8) + infop->load_bias; + infop->entry = ldq_raw(infop->entry) + infop->load_bias; #endif _regs->nip = infop->entry; } @@ -793,6 +912,25 @@ static inline void init_thread(struct target_pt_regs *regs, #endif /* TARGET_ALPHA */ +#ifdef TARGET_S390X + +#define ELF_START_MMAP (0x20000000000ULL) + +#define elf_check_arch(x) ( (x) == ELF_ARCH ) + +#define ELF_CLASS ELFCLASS64 +#define ELF_DATA ELFDATA2MSB +#define ELF_ARCH EM_S390 + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ + regs->psw.addr = infop->entry; + regs->psw.mask = PSW_MASK_64 | PSW_MASK_32; + regs->gprs[15] = infop->start_stack; +} + +#endif /* TARGET_S390X */ + #ifndef ELF_PLATFORM #define ELF_PLATFORM (NULL) #endif @@ -834,7 +972,7 @@ struct exec #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -#define DLINFO_ITEMS 12 +#define DLINFO_ITEMS 13 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) { @@ -967,8 +1105,7 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page, offset = p % TARGET_PAGE_SIZE; pag = (char *)page[p/TARGET_PAGE_SIZE]; if (!pag) { - pag = (char *)malloc(TARGET_PAGE_SIZE); - memset(pag, 0, TARGET_PAGE_SIZE); + pag = g_try_malloc0(TARGET_PAGE_SIZE); page[p/TARGET_PAGE_SIZE] = pag; if (!pag) return 0; @@ -1026,7 +1163,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, info->rss++; /* FIXME - check return value of memcpy_to_target() for failure */ memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE); - free(bprm->page[i]); + g_free(bprm->page[i]); } stack_base += TARGET_PAGE_SIZE; } @@ -1075,6 +1212,33 @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot) } } +#ifdef CONFIG_USE_FDPIC +static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong sp) +{ + uint16_t n; + struct elf32_fdpic_loadseg *loadsegs = info->loadsegs; + + /* elf32_fdpic_loadseg */ + n = info->nsegs; + while (n--) { + sp -= 12; + put_user_u32(loadsegs[n].addr, sp+0); + put_user_u32(loadsegs[n].p_vaddr, sp+4); + put_user_u32(loadsegs[n].p_memsz, sp+8); + } + + /* elf32_fdpic_loadmap */ + sp -= 4; + put_user_u16(0, sp+0); /* version */ + put_user_u16(info->nsegs, sp+2); /* nsegs */ + + info->personality = PER_LINUX_FDPIC; + info->loadmap_addr = sp; + + return sp; +} +#endif + static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, struct elfhdr *exec, struct image_info *info, @@ -1082,11 +1246,29 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, { abi_ulong sp; int size; + int i; + abi_ulong u_rand_bytes; + uint8_t k_rand_bytes[16]; abi_ulong u_platform; const char *k_platform; const int n = sizeof(elf_addr_t); sp = p; + +#ifdef CONFIG_USE_FDPIC + /* Needs to be before we load the env/argc/... */ + if (elf_is_fdpic(exec)) { + /* Need 4 byte alignment for these structs */ + sp &= ~3; + sp = loader_build_fdpic_loadmap(info, sp); + info->other_info = interp_info; + if (interp_info) { + interp_info->other_info = info; + sp = loader_build_fdpic_loadmap(interp_info, sp); + } + } +#endif + u_platform = 0; k_platform = ELF_PLATFORM; if (k_platform) { @@ -1096,6 +1278,20 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, /* FIXME - check return value of memcpy_to_target() for failure */ memcpy_to_target(sp, k_platform, len); } + + /* + * Generate 16 random bytes for userspace PRNG seeding (not + * cryptically secure but it's not the aim of QEMU). + */ + srand((unsigned int) time(NULL)); + for (i = 0; i < 16; i++) { + k_rand_bytes[i] = rand(); + } + sp -= 16; + u_rand_bytes = sp; + /* FIXME - check return value of memcpy_to_target() for failure */ + memcpy_to_target(sp, k_rand_bytes, 16); + /* * Force 16 byte _final_ alignment here for generality. */ @@ -1136,6 +1332,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); + NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes); + if (k_platform) NEW_AUX_ENT(AT_PLATFORM, u_platform); #ifdef ARCH_DLINFO @@ -1153,6 +1351,87 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, return sp; } +#ifndef TARGET_HAS_GUEST_VALIDATE_BASE +/* If the guest doesn't have a validation function just agree */ +bool guest_validate_base(unsigned long guest_base) +{ + return 1; +} +#endif + +static void probe_guest_base(const char *image_name, + abi_ulong loaddr, abi_ulong hiaddr) +{ + /* Probe for a suitable guest base address, if the user has not set + * it explicitly, and set guest_base appropriately. + * In case of error we will print a suitable message and exit. + */ +#if defined(CONFIG_USE_GUEST_BASE) + const char *errmsg; + if (!have_guest_base && !reserved_va) { + unsigned long host_start, real_start, host_size; + + /* Round addresses to page boundaries. */ + loaddr &= qemu_host_page_mask; + hiaddr = HOST_PAGE_ALIGN(hiaddr); + + if (loaddr < mmap_min_addr) { + host_start = HOST_PAGE_ALIGN(mmap_min_addr); + } else { + host_start = loaddr; + if (host_start != loaddr) { + errmsg = "Address overflow loading ELF binary"; + goto exit_errmsg; + } + } + host_size = hiaddr - loaddr; + while (1) { + /* Do not use mmap_find_vma here because that is limited to the + guest address space. We are going to make the + guest address space fit whatever we're given. */ + real_start = (unsigned long) + mmap((void *)host_start, host_size, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); + if (real_start == (unsigned long)-1) { + goto exit_perror; + } + guest_base = real_start - loaddr; + if ((real_start == host_start) && + guest_validate_base(guest_base)) { + break; + } + /* That address didn't work. Unmap and try a different one. + The address the host picked because is typically right at + the top of the host address space and leaves the guest with + no usable address space. Resort to a linear search. We + already compensated for mmap_min_addr, so this should not + happen often. Probably means we got unlucky and host + address space randomization put a shared library somewhere + inconvenient. */ + munmap((void *)real_start, host_size); + host_start += qemu_host_page_size; + if (host_start == loaddr) { + /* Theoretically possible if host doesn't have any suitably + aligned areas. Normally the first mmap will fail. */ + errmsg = "Unable to find space for application"; + goto exit_errmsg; + } + } + qemu_log("Relocating guest address space from 0x" + TARGET_ABI_FMT_lx " to 0x%lx\n", + loaddr, real_start); + } + return; + +exit_perror: + errmsg = strerror(errno); +exit_errmsg: + fprintf(stderr, "%s: %s\n", image_name, errmsg); + exit(-1); +#endif +} + + /* Load an ELF image into the address space. IMAGE_NAME is the filename of the image, to use in error messages. @@ -1197,6 +1476,11 @@ static void load_elf_image(const char *image_name, int image_fd, } bswap_phdr(phdr, ehdr->e_phnum); +#ifdef CONFIG_USE_FDPIC + info->nsegs = 0; + info->pt_dynamic_addr = 0; +#endif + /* Find the maximum size of the image and allocate an appropriate amount of memory to handle that. */ loaddr = -1, hiaddr = 0; @@ -1210,6 +1494,9 @@ static void load_elf_image(const char *image_name, int image_fd, if (a > hiaddr) { hiaddr = a; } +#ifdef CONFIG_USE_FDPIC + ++info->nsegs; +#endif } } @@ -1230,65 +1517,30 @@ static void load_elf_image(const char *image_name, int image_fd, /* This is the main executable. Make sure that the low address does not conflict with MMAP_MIN_ADDR or the QEMU application itself. */ -#if defined(CONFIG_USE_GUEST_BASE) - /* - * In case where user has not explicitly set the guest_base, we - * probe here that should we set it automatically. - */ - if (!have_guest_base && !reserved_va) { - unsigned long host_start, real_start, host_size; - - /* Round addresses to page boundaries. */ - loaddr &= qemu_host_page_mask; - hiaddr = HOST_PAGE_ALIGN(hiaddr); - - if (loaddr < mmap_min_addr) { - host_start = HOST_PAGE_ALIGN(mmap_min_addr); - } else { - host_start = loaddr; - if (host_start != loaddr) { - errmsg = "Address overflow loading ELF binary"; - goto exit_errmsg; - } - } - host_size = hiaddr - loaddr; - while (1) { - /* Do not use mmap_find_vma here because that is limited to the - guest address space. We are going to make the - guest address space fit whatever we're given. */ - real_start = (unsigned long) - mmap((void *)host_start, host_size, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); - if (real_start == (unsigned long)-1) { - goto exit_perror; - } - if (real_start == host_start) { - break; - } - /* That address didn't work. Unmap and try a different one. - The address the host picked because is typically right at - the top of the host address space and leaves the guest with - no usable address space. Resort to a linear search. We - already compensated for mmap_min_addr, so this should not - happen often. Probably means we got unlucky and host - address space randomization put a shared library somewhere - inconvenient. */ - munmap((void *)real_start, host_size); - host_start += qemu_host_page_size; - if (host_start == loaddr) { - /* Theoretically possible if host doesn't have any suitably - aligned areas. Normally the first mmap will fail. */ - errmsg = "Unable to find space for application"; - goto exit_errmsg; - } + probe_guest_base(image_name, loaddr, hiaddr); + } + load_bias = load_addr - loaddr; + +#ifdef CONFIG_USE_FDPIC + { + struct elf32_fdpic_loadseg *loadsegs = info->loadsegs = + g_malloc(sizeof(*loadsegs) * info->nsegs); + + for (i = 0; i < ehdr->e_phnum; ++i) { + switch (phdr[i].p_type) { + case PT_DYNAMIC: + info->pt_dynamic_addr = phdr[i].p_vaddr + load_bias; + break; + case PT_LOAD: + loadsegs->addr = phdr[i].p_vaddr + load_bias; + loadsegs->p_vaddr = phdr[i].p_vaddr; + loadsegs->p_memsz = phdr[i].p_memsz; + ++loadsegs; + break; } - qemu_log("Relocating guest address space from 0x" - TARGET_ABI_FMT_lx " to 0x%lx\n", loaddr, real_start); - guest_base = real_start - loaddr; } -#endif } - load_bias = load_addr - loaddr; +#endif info->load_bias = load_bias; info->load_addr = load_addr; @@ -1479,9 +1731,9 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) { int i, shnum, nsyms, sym_idx = 0, str_idx = 0; struct elf_shdr *shdr; - char *strings; - struct syminfo *s; - struct elf_sym *syms, *new_syms; + char *strings = NULL; + struct syminfo *s = NULL; + struct elf_sym *new_syms, *syms = NULL; shnum = hdr->e_shnum; i = shnum * sizeof(struct elf_shdr); @@ -1506,24 +1758,19 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) /* Now know where the strtab and symtab are. Snarf them. */ s = malloc(sizeof(*s)); if (!s) { - return; + goto give_up; } i = shdr[str_idx].sh_size; s->disas_strtab = strings = malloc(i); if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) { - free(s); - free(strings); - return; + goto give_up; } i = shdr[sym_idx].sh_size; syms = malloc(i); if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) { - free(s); - free(strings); - free(syms); - return; + goto give_up; } nsyms = i / sizeof(struct elf_sym); @@ -1546,16 +1793,18 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) } } + /* No "useful" symbol. */ + if (nsyms == 0) { + goto give_up; + } + /* Attempt to free the storage associated with the local symbols that we threw away. Whether or not this has any effect on the memory allocation depends on the malloc implementation and how many symbols we managed to discard. */ new_syms = realloc(syms, nsyms * sizeof(*syms)); if (new_syms == NULL) { - free(s); - free(syms); - free(strings); - return; + goto give_up; } syms = new_syms; @@ -1570,6 +1819,13 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) s->lookup_symbol = lookup_symbolxx; s->next = syminfos; syminfos = s; + + return; + +give_up: + free(s); + free(strings); + free(syms); } int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, @@ -1627,11 +1883,11 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, info->start_stack = bprm->p; /* If we have an interpreter, set that as the program's entry point. - Copy the load_addr as well, to help PPC64 interpret the entry + Copy the load_bias as well, to help PPC64 interpret the entry point as a function descriptor. Do this after creating elf tables so that we copy the original program entry point into the AUXV. */ if (elf_interpreter) { - info->load_addr = interp_info.load_addr; + info->load_bias = interp_info.load_bias; info->entry = interp_info.entry; free(elf_interpreter); } @@ -1690,19 +1946,20 @@ struct memelfnote { size_t namesz_rounded; int type; size_t datasz; + size_t datasz_rounded; void *data; size_t notesz; }; struct target_elf_siginfo { - int si_signo; /* signal number */ - int si_code; /* extra code */ - int si_errno; /* errno */ + target_int si_signo; /* signal number */ + target_int si_code; /* extra code */ + target_int si_errno; /* errno */ }; struct target_elf_prstatus { struct target_elf_siginfo pr_info; /* Info associated with signal */ - short pr_cursig; /* Current signal */ + target_short pr_cursig; /* Current signal */ target_ulong pr_sigpend; /* XXX */ target_ulong pr_sighold; /* XXX */ target_pid_t pr_pid; @@ -1714,7 +1971,7 @@ struct target_elf_prstatus { struct target_timeval pr_cutime; /* XXX Cumulative user time */ struct target_timeval pr_cstime; /* XXX Cumulative system time */ target_elf_gregset_t pr_reg; /* GP registers */ - int pr_fpvalid; /* XXX */ + target_int pr_fpvalid; /* XXX */ }; #define ELF_PRARGSZ (80) /* Number of chars for args */ @@ -1857,7 +2114,7 @@ static struct mm_struct *vma_init(void) { struct mm_struct *mm; - if ((mm = qemu_malloc(sizeof (*mm))) == NULL) + if ((mm = g_malloc(sizeof (*mm))) == NULL) return (NULL); mm->mm_count = 0; @@ -1872,9 +2129,9 @@ static void vma_delete(struct mm_struct *mm) while ((vma = vma_first(mm)) != NULL) { QTAILQ_REMOVE(&mm->mm_mmap, vma, vma_link); - qemu_free(vma); + g_free(vma); } - qemu_free(mm); + g_free(mm); } static int vma_add_mapping(struct mm_struct *mm, abi_ulong start, @@ -1882,7 +2139,7 @@ static int vma_add_mapping(struct mm_struct *mm, abi_ulong start, { struct vm_area_struct *vma; - if ((vma = qemu_mallocz(sizeof (*vma))) == NULL) + if ((vma = g_malloc0(sizeof (*vma))) == NULL) return (-1); vma->vma_start = start; @@ -1965,7 +2222,9 @@ static void fill_note(struct memelfnote *note, const char *name, int type, note->namesz = namesz; note->namesz_rounded = roundup(namesz, sizeof (int32_t)); note->type = type; - note->datasz = roundup(sz, sizeof (int32_t));; + note->datasz = sz; + note->datasz_rounded = roundup(sz, sizeof (int32_t)); + note->data = data; /* @@ -1973,7 +2232,7 @@ static void fill_note(struct memelfnote *note, const char *name, int type, * ELF document. */ note->notesz = sizeof (struct elf_note) + - note->namesz_rounded + note->datasz; + note->namesz_rounded + note->datasz_rounded; } static void fill_elf_header(struct elfhdr *elf, int segs, uint16_t machine, @@ -2193,7 +2452,7 @@ static int write_note(struct memelfnote *men, int fd) return (-1); if (dump_write(fd, men->name, men->namesz_rounded) != 0) return (-1); - if (dump_write(fd, men->data, men->datasz) != 0) + if (dump_write(fd, men->data, men->datasz_rounded) != 0) return (-1); return (0); @@ -2204,7 +2463,7 @@ static void fill_thread_info(struct elf_note_info *info, const CPUState *env) TaskState *ts = (TaskState *)env->opaque; struct elf_thread_status *ets; - ets = qemu_mallocz(sizeof (*ets)); + ets = g_malloc0(sizeof (*ets)); ets->num_notes = 1; /* only prstatus is dumped */ fill_prstatus(&ets->prstatus, ts, 0); elf_core_copy_regs(&ets->prstatus.pr_reg, env); @@ -2228,13 +2487,13 @@ static int fill_note_info(struct elf_note_info *info, QTAILQ_INIT(&info->thread_list); - info->notes = qemu_mallocz(NUMNOTES * sizeof (struct memelfnote)); + info->notes = g_malloc0(NUMNOTES * sizeof (struct memelfnote)); if (info->notes == NULL) return (-ENOMEM); - info->prstatus = qemu_mallocz(sizeof (*info->prstatus)); + info->prstatus = g_malloc0(sizeof (*info->prstatus)); if (info->prstatus == NULL) return (-ENOMEM); - info->psinfo = qemu_mallocz(sizeof (*info->psinfo)); + info->psinfo = g_malloc0(sizeof (*info->psinfo)); if (info->prstatus == NULL) return (-ENOMEM); @@ -2275,12 +2534,12 @@ static void free_note_info(struct elf_note_info *info) while (!QTAILQ_EMPTY(&info->thread_list)) { ets = QTAILQ_FIRST(&info->thread_list); QTAILQ_REMOVE(&info->thread_list, ets, ets_link); - qemu_free(ets); + g_free(ets); } - qemu_free(info->prstatus); - qemu_free(info->psinfo); - qemu_free(info->notes); + g_free(info->prstatus); + g_free(info->psinfo); + g_free(info->notes); } static int write_note_info(struct elf_note_info *info, int fd) @@ -2409,7 +2668,7 @@ static int elf_core_dump(int signr, const CPUState *env) * ELF specification wants data to start at page boundary so * we align it here. */ - offset = roundup(offset, ELF_EXEC_PAGESIZE); + data_offset = offset = roundup(offset, ELF_EXEC_PAGESIZE); /* * Write program headers for memory regions mapped in @@ -2432,6 +2691,7 @@ static int elf_core_dump(int signr, const CPUState *env) phdr.p_flags |= PF_X; phdr.p_align = ELF_EXEC_PAGESIZE; + bswap_phdr(&phdr, 1); dump_write(fd, &phdr, sizeof (phdr)); } @@ -2443,8 +2703,6 @@ static int elf_core_dump(int signr, const CPUState *env) goto out; /* align data to page boundary */ - data_offset = lseek(fd, 0, SEEK_CUR); - data_offset = TARGET_PAGE_ALIGN(data_offset); if (lseek(fd, data_offset, SEEK_SET) != data_offset) goto out; diff --git a/linux-user/elfload32.c b/linux-user/elfload32.c deleted file mode 100644 index 4b4648c..0000000 --- a/linux-user/elfload32.c +++ /dev/null @@ -1,30 +0,0 @@ -#define TARGET_ABI32 -#define load_elf_binary load_elf_binary32 -#define do_init_thread do_init_thread32 - -#include "elfload.c" - -#undef load_elf_binary -#undef do_init_thread - -int load_elf_binary(struct linux_binprm *bprm, struct target_pt_regs *regs, - struct image_info *info); - -int load_elf_binary_multi(struct linux_binprm *bprm, - struct target_pt_regs *regs, - struct image_info *info) -{ - struct elfhdr *elf_ex; - int retval; - - elf_ex = (struct elfhdr *) bprm->buf; /* exec-header */ - if (elf_ex->e_ident[EI_CLASS] == ELFCLASS64) { - retval = load_elf_binary(bprm, regs, info); - } else { - retval = load_elf_binary32(bprm, regs, info); - if (personality(info->personality) == PER_LINUX) - info->personality = PER_LINUX32; - } - - return retval; -} diff --git a/linux-user/flatload.c b/linux-user/flatload.c index 8f9f4a5..1062da3 100644 --- a/linux-user/flatload.c +++ b/linux-user/flatload.c @@ -41,6 +41,8 @@ #include "qemu.h" #include "flat.h" +#define ntohl(x) be32_to_cpu(x) +#include //#define DEBUG @@ -50,14 +52,6 @@ #define DBG_FLT(...) #endif -#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) -#define flat_old_ram_flag(flag) (flag) -#ifdef TARGET_WORDS_BIGENDIAN -#define flat_get_relocate_addr(relval) (relval) -#else -#define flat_get_relocate_addr(relval) bswap32(relval) -#endif - #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ @@ -78,8 +72,6 @@ static int load_flat_shared_library(int id, struct lib_info *p); struct linux_binprm; -#define ntohl(x) be32_to_cpu(x) - /****************************************************************************/ /* * create_flat_tables() parses the env- and arg-strings in new user @@ -387,12 +379,11 @@ static int load_flat_file(struct linux_binprm * bprm, abi_long result; abi_ulong realdatastart = 0; abi_ulong text_len, data_len, bss_len, stack_len, flags; - abi_ulong memp = 0; /* for finding the brk area */ abi_ulong extra; abi_ulong reloc = 0, rp; int i, rev, relocs = 0; abi_ulong fpos; - abi_ulong start_code, end_code; + abi_ulong start_code; abi_ulong indx_len; hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ @@ -499,7 +490,6 @@ static int load_flat_file(struct linux_binprm * bprm, } reloc = datapos + (ntohl(hdr->reloc_start) - text_len); - memp = realdatastart; } else { @@ -514,7 +504,6 @@ static int load_flat_file(struct linux_binprm * bprm, realdatastart = textpos + ntohl(hdr->data_start); datapos = realdatastart + indx_len; reloc = (textpos + ntohl(hdr->reloc_start) + indx_len); - memp = textpos; #ifdef CONFIG_BINFMT_ZFLAT #error code needs checking @@ -560,11 +549,10 @@ static int load_flat_file(struct linux_binprm * bprm, /* The main program needs a little extra setup in the task structure */ start_code = textpos + sizeof (struct flat_hdr); - end_code = textpos + text_len; DBG_FLT("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n", id ? "Lib" : "Load", bprm->filename, - (int) start_code, (int) end_code, + (int) start_code, (int) (textpos + text_len), (int) datapos, (int) (datapos + data_len), (int) (datapos + data_len), @@ -625,6 +613,7 @@ static int load_flat_file(struct linux_binprm * bprm, * __start to address 4 so that is okay). */ if (rev > OLD_FLAT_VERSION) { + abi_ulong persistent = 0; for (i = 0; i < relocs; i++) { abi_ulong addr, relval; @@ -633,6 +622,9 @@ static int load_flat_file(struct linux_binprm * bprm, relocated first). */ if (get_user_ual(relval, reloc + i * sizeof(abi_ulong))) return -EFAULT; + relval = ntohl(relval); + if (flat_set_persistent(relval, &persistent)) + continue; addr = flat_get_relocate_addr(relval); rp = calc_reloc(addr, libinfo, id, 1); if (rp == RELOC_FAILED) @@ -641,22 +633,20 @@ static int load_flat_file(struct linux_binprm * bprm, /* Get the pointer's value. */ if (get_user_ual(addr, rp)) return -EFAULT; + addr = flat_get_addr_from_rp(rp, relval, flags, &persistent); if (addr != 0) { /* * Do the relocation. PIC relocs in the data section are * already in target order */ - -#ifndef TARGET_WORDS_BIGENDIAN if ((flags & FLAT_FLAG_GOTPIC) == 0) - addr = bswap32(addr); -#endif + addr = ntohl(addr); addr = calc_reloc(addr, libinfo, id, 0); if (addr == RELOC_FAILED) return -ENOEXEC; /* Write back the relocated pointer. */ - if (put_user_ual(addr, rp)) + if (flat_put_addr_at_rp(rp, addr, relval)) return -EFAULT; } } @@ -733,8 +723,15 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, * pedantic and include space for the argv/envp array as it may have * a lot of entries. */ -#define TOP_OF_ARGS (TARGET_PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *)) - stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ + stack_len = 0; + for (i = 0; i < bprm->argc; ++i) { + /* the argv strings */ + stack_len += strlen(bprm->argv[i]); + } + for (i = 0; i < bprm->envc; ++i) { + /* the envp strings */ + stack_len += strlen(bprm->envp[i]); + } stack_len += (bprm->argc + 1) * 4; /* the argv array */ stack_len += (bprm->envc + 1) * 4; /* the envp array */ @@ -775,7 +772,8 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, stack_len *= sizeof(abi_ulong); if ((sp + stack_len) & 15) sp -= 16 - ((sp + stack_len) & 15); - sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, 1); + sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, + flat_argvp_envp_on_stack()); /* Fake some return addresses to ensure the call chain will * initialise library in order for us. We are required to call diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h index 3ef71ce..74abfca 100644 --- a/linux-user/i386/syscall_nr.h +++ b/linux-user/i386/syscall_nr.h @@ -335,3 +335,15 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2 331 #define TARGET_NR_inotify_init1 332 +#define TARGET_NR_preadv 333 +#define TARGET_NR_pwritev 334 +#define TARGET_NR_rt_tgsigqueueinfo 335 +#define TARGET_NR_perf_event_open 336 +#define TARGET_NR_recvmmsg 337 +#define TARGET_NR_fanotify_init 338 +#define TARGET_NR_fanotify_mark 339 +#define TARGET_NR_prlimit64 340 +#define TARGET_NR_name_to_handle_at 341 +#define TARGET_NR_open_by_handle_at 342 +#define TARGET_NR_clock_adjtime 343 +#define TARGET_NR_syncfs 344 diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 526aaa2..6514502 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -59,6 +59,10 @@ IOCTL(KDSKBMODE, 0, TYPE_INT) IOCTL(KDGKBENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbentry))) IOCTL(KDGKBSENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbsentry))) + IOCTL(KDGKBLED, 0, TYPE_INT) + IOCTL(KDSKBLED, 0, TYPE_INT) + IOCTL(KDGETLED, 0, TYPE_INT) + IOCTL(KDSETLED, 0, TYPE_INT) IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) @@ -112,7 +116,8 @@ IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq))) IOCTL(SIOCSIFLINK, 0, TYPE_NULL) - IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf))) + IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf, + MK_PTR(MK_STRUCT(STRUCT_ifconf))) IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT)) IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT)) IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) @@ -121,6 +126,7 @@ IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq))) IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq))) + IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq))) IOCTL(CDROMPAUSE, 0, TYPE_NULL) IOCTL(CDROMSTART, 0, TYPE_NULL) @@ -323,6 +329,11 @@ IOCTL(FBIOGET_FSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_fix_screeninfo))) IOCTL(FBIOGET_VSCREENINFO, IOC_R, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo))) IOCTL(FBIOPUT_VSCREENINFO, IOC_W, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo))) + IOCTL(FBIOGETCMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap))) + IOCTL(FBIOPUTCMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_cmap))) + IOCTL(FBIOPAN_DISPLAY, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_var_screeninfo))) + IOCTL(FBIOGET_CON2FBMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap))) + IOCTL(FBIOPUT_CON2FBMAP, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_fb_con2fbmap))) IOCTL(VT_OPENQRY, IOC_R, MK_PTR(TYPE_INT)) IOCTL(VT_GETSTATE, IOC_R, MK_PTR(MK_STRUCT(STRUCT_vt_stat))) @@ -330,3 +341,7 @@ IOCTL(VT_WAITACTIVE, 0, TYPE_INT) IOCTL(VT_LOCKSWITCH, 0, TYPE_INT) IOCTL(VT_UNLOCKSWITCH, 0, TYPE_INT) + IOCTL(VT_GETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode))) + IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode))) + IOCTL(VT_RELDISP, 0, TYPE_INT) + IOCTL(VT_DISALLOCATE, 0, TYPE_INT) diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index ac8c486..b47025f 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -26,22 +26,6 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src, return 0; } -static int in_group_p(gid_t g) -{ - /* return TRUE if we're in the specified group, FALSE otherwise */ - int ngroup; - int i; - gid_t grouplist[NGROUPS]; - - ngroup = getgroups(NGROUPS, grouplist); - for(i = 0; i < ngroup; i++) { - if(grouplist[i] == g) { - return 1; - } - } - return 0; -} - static int count(char ** vec) { int i; @@ -57,7 +41,7 @@ static int prepare_binprm(struct linux_binprm *bprm) { struct stat st; int mode; - int retval, id_change; + int retval; if(fstat(bprm->fd, &st) < 0) { return(-errno); @@ -73,14 +57,10 @@ static int prepare_binprm(struct linux_binprm *bprm) bprm->e_uid = geteuid(); bprm->e_gid = getegid(); - id_change = 0; /* Set-uid? */ if(mode & S_ISUID) { bprm->e_uid = st.st_uid; - if(bprm->e_uid != geteuid()) { - id_change = 1; - } } /* Set-gid? */ @@ -91,9 +71,6 @@ static int prepare_binprm(struct linux_binprm *bprm) */ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { bprm->e_gid = st.st_gid; - if (!in_group_p(bprm->e_gid)) { - id_change = 1; - } } retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE); @@ -201,7 +178,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp, /* Something went wrong, return the inode and free the argument pages*/ for (i=0 ; ipage[i]); + g_free(bprm->page[i]); } return(retval); } diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h index 1c0ba07..4d0937e 100644 --- a/linux-user/m68k/syscall_nr.h +++ b/linux-user/m68k/syscall_nr.h @@ -328,3 +328,19 @@ #define TARGET_NR_dup3 326 #define TARGET_NR_pipe2 327 #define TARGET_NR_inotify_init1 328 +#define TARGET_NR_inotify_init1 328 +#define TARGET_NR_preadv 329 +#define TARGET_NR_pwritev 330 +#define TARGET_NR_rt_tgsigqueueinfo 331 +#define TARGET_NR_perf_event_open 332 +#define TARGET_NR_get_thread_area 333 +#define TARGET_NR_set_thread_area 334 +#define TARGET_NR_atomic_cmpxchg_32 335 +#define TARGET_NR_atomic_barrier 336 +#define TARGET_NR_fanotify_init 337 +#define TARGET_NR_fanotify_mark 338 +#define TARGET_NR_prlimit64 339 +#define TARGET_NR_name_to_handle_at 340 +#define TARGET_NR_open_by_handle_at 341 +#define TARGET_NR_clock_adjtime 342 +#define TARGET_NR_syncfs 343 diff --git a/linux-user/main.c b/linux-user/main.c index 0d627d6..d1bbc57 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -29,8 +29,7 @@ #include "qemu.h" #include "qemu-common.h" #include "cache-utils.h" -/* For tb_lock */ -#include "exec-all.h" +#include "cpu.h" #include "tcg.h" #include "qemu-timer.h" #include "envlist.h" @@ -40,6 +39,11 @@ char *exec_path; int singlestep; +const char *filename; +const char *argv0; +int gdbstub_port; +envlist_t *envlist; +const char *cpu_model; unsigned long mmap_min_addr; #if defined(CONFIG_USE_GUEST_BASE) unsigned long guest_base; @@ -47,6 +51,8 @@ int have_guest_base; unsigned long reserved_va; #endif +static void usage(void); + static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; const char *qemu_uname_release = CONFIG_UNAME_RELEASE; @@ -319,11 +325,12 @@ void cpu_loop(CPUX86State *env) env->regs[R_EDX], env->regs[R_ESI], env->regs[R_EDI], - env->regs[R_EBP]); + env->regs[R_EBP], + 0, 0); break; #ifndef TARGET_ABI32 case EXCP_SYSCALL: - /* linux syscall from syscall intruction */ + /* linux syscall from syscall instruction */ env->regs[R_EAX] = do_syscall(env, env->regs[R_EAX], env->regs[R_EDI], @@ -331,7 +338,8 @@ void cpu_loop(CPUX86State *env) env->regs[R_EDX], env->regs[10], env->regs[8], - env->regs[9]); + env->regs[9], + 0, 0); env->eip = env->exception_next_eip; break; #endif @@ -455,22 +463,81 @@ void cpu_loop(CPUX86State *env) #ifdef TARGET_ARM -static void arm_cache_flush(abi_ulong start, abi_ulong last) +/* + * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt + * Input: + * r0 = pointer to oldval + * r1 = pointer to newval + * r2 = pointer to target value + * + * Output: + * r0 = 0 if *ptr was changed, non-0 if no exchange happened + * C set if *ptr was changed, clear if no exchange happened + * + * Note segv's in kernel helpers are a bit tricky, we can set the + * data address sensibly but the PC address is just the entry point. + */ +static void arm_kernel_cmpxchg64_helper(CPUARMState *env) { - abi_ulong addr, last1; + uint64_t oldval, newval, val; + uint32_t addr, cpsr; + target_siginfo_t info; - if (last < start) - return; - addr = start; - for(;;) { - last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1; - if (last1 > last) - last1 = last; - tb_invalidate_page_range(addr, last1 + 1); - if (last1 == last) - break; - addr = last1 + 1; + /* Based on the 32 bit code in do_kernel_trap */ + + /* XXX: This only works between threads, not between processes. + It's probably possible to implement this with native host + operations. However things like ldrex/strex are much harder so + there's not much point trying. */ + start_exclusive(); + cpsr = cpsr_read(env); + addr = env->regs[2]; + + if (get_user_u64(oldval, env->regs[0])) { + env->cp15.c6_data = env->regs[0]; + goto segv; + }; + + if (get_user_u64(newval, env->regs[1])) { + env->cp15.c6_data = env->regs[1]; + goto segv; + }; + + if (get_user_u64(val, addr)) { + env->cp15.c6_data = addr; + goto segv; } + + if (val == oldval) { + val = newval; + + if (put_user_u64(val, addr)) { + env->cp15.c6_data = addr; + goto segv; + }; + + env->regs[0] = 0; + cpsr |= CPSR_C; + } else { + env->regs[0] = -1; + cpsr &= ~CPSR_C; + } + cpsr_write(env, cpsr, CPSR_C); + end_exclusive(); + return; + +segv: + end_exclusive(); + /* We get the PC of the entry address - which is as good as anything, + on a real kernel what you get depends on which mode it uses. */ + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->cp15.c6_data; + queue_signal(env, info.si_signo, &info); + + end_exclusive(); } /* Handle a jump to the kernel code page. */ @@ -512,6 +579,10 @@ do_kernel_trap(CPUARMState *env) case 0xffff0fe0: /* __kernel_get_tls */ env->regs[0] = env->cp15.c13_tls2; break; + case 0xffff0f60: /* __kernel_cmpxchg64 */ + arm_kernel_cmpxchg64_helper(env); + break; + default: return 1; } @@ -717,7 +788,7 @@ void cpu_loop(CPUARMState *env) } if (n == ARM_NR_cacheflush) { - arm_cache_flush(env->regs[0], env->regs[1]); + /* nop */ } else if (n == ARM_NR_semihosting || n == ARM_NR_thumb_semihosting) { env->regs[0] = do_arm_semihosting (env); @@ -733,7 +804,7 @@ void cpu_loop(CPUARMState *env) if ( n > ARM_NR_BASE) { switch (n) { case ARM_NR_cacheflush: - arm_cache_flush(env->regs[0], env->regs[1]); + /* nop */ break; case ARM_NR_set_tls: cpu_set_tls(env, env->regs[0]); @@ -753,7 +824,8 @@ void cpu_loop(CPUARMState *env) env->regs[2], env->regs[3], env->regs[4], - env->regs[5]); + env->regs[5], + 0, 0); } } else { goto error; @@ -768,7 +840,6 @@ void cpu_loop(CPUARMState *env) goto do_segv; case EXCP_DATA_ABORT: addr = env->cp15.c6_data; - goto do_segv; do_segv: { info.si_signo = SIGSEGV; @@ -816,6 +887,84 @@ void cpu_loop(CPUARMState *env) #endif +#ifdef TARGET_UNICORE32 + +void cpu_loop(CPUState *env) +{ + int trapnr; + unsigned int n, insn; + target_siginfo_t info; + + for (;;) { + cpu_exec_start(env); + trapnr = uc32_cpu_exec(env); + cpu_exec_end(env); + switch (trapnr) { + case UC32_EXCP_PRIV: + { + /* system call */ + get_user_u32(insn, env->regs[31] - 4); + n = insn & 0xffffff; + + if (n >= UC32_SYSCALL_BASE) { + /* linux syscall */ + n -= UC32_SYSCALL_BASE; + if (n == UC32_SYSCALL_NR_set_tls) { + cpu_set_tls(env, env->regs[0]); + env->regs[0] = 0; + } else { + env->regs[0] = do_syscall(env, + n, + env->regs[0], + env->regs[1], + env->regs[2], + env->regs[3], + env->regs[4], + env->regs[5], + 0, 0); + } + } else { + goto error; + } + } + break; + case UC32_EXCP_TRAP: + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->cp0.c4_faultaddr; + queue_signal(env, info.si_signo, &info); + break; + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_DEBUG: + { + int sig; + + sig = gdb_handlesig(env, TARGET_SIGTRAP); + if (sig) { + info.si_signo = sig; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(env, info.si_signo, &info); + } + } + break; + default: + goto error; + } + process_pending_signals(env); + } + +error: + fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr); + cpu_dump_state(env, stderr, fprintf, 0); + abort(); +} +#endif + #ifdef TARGET_SPARC #define SPARC64_STACK_BIAS 2047 @@ -959,7 +1108,8 @@ void cpu_loop (CPUSPARCState *env) ret = do_syscall (env, env->gregs[1], env->regwptr[0], env->regwptr[1], env->regwptr[2], env->regwptr[3], - env->regwptr[4], env->regwptr[5]); + env->regwptr[4], env->regwptr[5], + 0, 0); if ((abi_ulong)ret >= (abi_ulong)(-515)) { #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc |= PSR_CARRY; @@ -998,7 +1148,7 @@ void cpu_loop (CPUSPARCState *env) case TT_TFAULT: case TT_DFAULT: { - info.si_signo = SIGSEGV; + info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; /* XXX: check env->error_code */ info.si_code = TARGET_SEGV_MAPERR; @@ -1016,7 +1166,7 @@ void cpu_loop (CPUSPARCState *env) case TT_TFAULT: case TT_DFAULT: { - info.si_signo = SIGSEGV; + info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; /* XXX: check env->error_code */ info.si_code = TARGET_SEGV_MAPERR; @@ -1041,6 +1191,15 @@ void cpu_loop (CPUSPARCState *env) case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; + case TT_ILL_INSN: + { + info.si_signo = TARGET_SIGILL; + info.si_errno = 0; + info.si_code = TARGET_ILL_ILLOPC; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, &info); + } + break; case EXCP_DEBUG: { int sig; @@ -1182,7 +1341,7 @@ void cpu_loop(CPUPPCState *env) { target_siginfo_t info; int trapnr; - uint32_t ret; + target_ulong ret; for(;;) { cpu_exec_start(env); @@ -1545,27 +1704,20 @@ void cpu_loop(CPUPPCState *env) * PPC ABI uses overflow flag in cr0 to signal an error * in syscalls. */ -#if 0 - printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0], - env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]); -#endif env->crf[0] &= ~0x1; ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6], env->gpr[7], - env->gpr[8]); - if (ret == (uint32_t)(-TARGET_QEMU_ESIGRETURN)) { + env->gpr[8], 0, 0); + if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) { /* Returning from a successful sigreturn syscall. Avoid corrupting register state. */ break; } - if (ret > (uint32_t)(-515)) { + if (ret > (target_ulong)(-515)) { env->crf[0] |= 0x1; ret = -ret; } env->gpr[3] = ret; -#if 0 - printf("syscall returned 0x%08x (%d)\n", ret, ret); -#endif break; case POWERPC_EXCP_STCX: if (do_store_exclusive(env)) { @@ -1606,7 +1758,7 @@ void cpu_loop(CPUPPCState *env) #define MIPS_SYS(name, args) args, static const uint8_t mips_syscall_args[] = { - MIPS_SYS(sys_syscall , 0) /* 4000 */ + MIPS_SYS(sys_syscall , 8) /* 4000 */ MIPS_SYS(sys_exit , 1) MIPS_SYS(sys_fork , 0) MIPS_SYS(sys_read , 3) @@ -1812,7 +1964,7 @@ static const uint8_t mips_syscall_args[] = { MIPS_SYS(sys_getcwd , 2) MIPS_SYS(sys_capget , 2) MIPS_SYS(sys_capset , 2) /* 4205 */ - MIPS_SYS(sys_sigaltstack , 0) + MIPS_SYS(sys_sigaltstack , 2) MIPS_SYS(sys_sendfile , 4) MIPS_SYS(sys_ni_syscall , 0) MIPS_SYS(sys_ni_syscall , 0) @@ -1922,6 +2074,33 @@ static const uint8_t mips_syscall_args[] = { MIPS_SYS(sys_epoll_pwait, 6) MIPS_SYS(sys_ioprio_set, 3) MIPS_SYS(sys_ioprio_get, 2) + MIPS_SYS(sys_utimensat, 4) + MIPS_SYS(sys_signalfd, 3) + MIPS_SYS(sys_ni_syscall, 0) /* was timerfd */ + MIPS_SYS(sys_eventfd, 1) + MIPS_SYS(sys_fallocate, 6) /* 4320 */ + MIPS_SYS(sys_timerfd_create, 2) + MIPS_SYS(sys_timerfd_gettime, 2) + MIPS_SYS(sys_timerfd_settime, 4) + MIPS_SYS(sys_signalfd4, 4) + MIPS_SYS(sys_eventfd2, 2) /* 4325 */ + MIPS_SYS(sys_epoll_create1, 1) + MIPS_SYS(sys_dup3, 3) + MIPS_SYS(sys_pipe2, 2) + MIPS_SYS(sys_inotify_init1, 1) + MIPS_SYS(sys_preadv, 6) /* 4330 */ + MIPS_SYS(sys_pwritev, 6) + MIPS_SYS(sys_rt_tgsigqueueinfo, 4) + MIPS_SYS(sys_perf_event_open, 5) + MIPS_SYS(sys_accept4, 4) + MIPS_SYS(sys_recvmmsg, 5) /* 4335 */ + MIPS_SYS(sys_fanotify_init, 2) + MIPS_SYS(sys_fanotify_mark, 6) + MIPS_SYS(sys_prlimit64, 4) + MIPS_SYS(sys_name_to_handle_at, 5) + MIPS_SYS(sys_open_by_handle_at, 3) /* 4340 */ + MIPS_SYS(sys_clock_adjtime, 2) + MIPS_SYS(sys_syncfs, 1) }; #undef MIPS_SYS @@ -1990,7 +2169,7 @@ void cpu_loop(CPUMIPSState *env) syscall_num = env->active_tc.gpr[2] - 4000; env->active_tc.PC += 4; if (syscall_num >= sizeof(mips_syscall_args)) { - ret = -ENOSYS; + ret = -TARGET_ENOSYS; } else { int nb_args; abi_ulong sp_reg; @@ -2000,11 +2179,22 @@ void cpu_loop(CPUMIPSState *env) sp_reg = env->active_tc.gpr[29]; switch (nb_args) { /* these arguments are taken from the stack */ - /* FIXME - what to do if get_user() fails? */ - case 8: get_user_ual(arg8, sp_reg + 28); - case 7: get_user_ual(arg7, sp_reg + 24); - case 6: get_user_ual(arg6, sp_reg + 20); - case 5: get_user_ual(arg5, sp_reg + 16); + case 8: + if ((ret = get_user_ual(arg8, sp_reg + 28)) != 0) { + goto done_syscall; + } + case 7: + if ((ret = get_user_ual(arg7, sp_reg + 24)) != 0) { + goto done_syscall; + } + case 6: + if ((ret = get_user_ual(arg6, sp_reg + 20)) != 0) { + goto done_syscall; + } + case 5: + if ((ret = get_user_ual(arg5, sp_reg + 16)) != 0) { + goto done_syscall; + } default: break; } @@ -2013,8 +2203,9 @@ void cpu_loop(CPUMIPSState *env) env->active_tc.gpr[5], env->active_tc.gpr[6], env->active_tc.gpr[7], - arg5, arg6/*, arg7, arg8*/); + arg5, arg6, arg7, arg8); } +done_syscall: if (ret == -TARGET_QEMU_ESIGRETURN) { /* Returning from a successful sigreturn syscall. Avoid clobbering register state. */ @@ -2030,6 +2221,8 @@ void cpu_loop(CPUMIPSState *env) break; case EXCP_TLBL: case EXCP_TLBS: + case EXCP_AdEL: + case EXCP_AdES: info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; /* XXX: check env->error_code */ @@ -2101,7 +2294,8 @@ void cpu_loop (CPUState *env) env->gregs[6], env->gregs[7], env->gregs[0], - env->gregs[1]); + env->gregs[1], + 0, 0); env->gregs[0] = ret; break; case EXCP_INTERRUPT: @@ -2170,7 +2364,8 @@ void cpu_loop (CPUState *env) env->regs[12], env->regs[13], env->pregs[7], - env->pregs[11]); + env->pregs[11], + 0, 0); env->regs[10] = ret; break; case EXCP_DEBUG: @@ -2229,7 +2424,8 @@ void cpu_loop (CPUState *env) env->regs[7], env->regs[8], env->regs[9], - env->regs[10]); + env->regs[10], + 0, 0); env->regs[3] = ret; env->sregs[SR_PC] = env->regs[14]; break; @@ -2244,6 +2440,13 @@ void cpu_loop (CPUState *env) env->iflags &= ~(IMM_FLAG | D_FLAG); switch (env->sregs[SR_ESR] & 31) { + case ESR_EC_DIVZERO: + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = TARGET_FPE_FLTDIV; + info._sifields._sigfault._addr = 0; + queue_signal(env, info.si_signo, &info); + break; case ESR_EC_FPU: info.si_signo = SIGFPE; info.si_errno = 0; @@ -2258,7 +2461,7 @@ void cpu_loop (CPUState *env) break; default: printf ("Unhandled hw-exception: 0x%x\n", - env->sregs[SR_ESR] & 5); + env->sregs[SR_ESR] & ESR_EC_MASK); cpu_dump_state(env, stderr, fprintf, 0); exit (1); break; @@ -2339,7 +2542,8 @@ void cpu_loop(CPUM68KState *env) env->dregs[3], env->dregs[4], env->dregs[5], - env->aregs[0]); + env->aregs[0], + 0, 0); } break; case EXCP_INTERRUPT: @@ -2449,49 +2653,27 @@ void cpu_loop (CPUState *env) fprintf(stderr, "Machine check exception. Exit\n"); exit(1); break; - case EXCP_ARITH: - env->lock_addr = -1; - info.si_signo = TARGET_SIGFPE; - info.si_errno = 0; - info.si_code = TARGET_FPE_FLTINV; - info._sifields._sigfault._addr = env->pc; - queue_signal(env, info.si_signo, &info); - break; - case EXCP_HW_INTERRUPT: + case EXCP_SMP_INTERRUPT: + case EXCP_CLK_INTERRUPT: + case EXCP_DEV_INTERRUPT: fprintf(stderr, "External interrupt. Exit\n"); exit(1); break; - case EXCP_DFAULT: + case EXCP_MMFAULT: env->lock_addr = -1; info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; - info.si_code = (page_get_flags(env->ipr[IPR_EXC_ADDR]) & PAGE_VALID + info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR); - info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR]; + info._sifields._sigfault._addr = env->trap_arg0; queue_signal(env, info.si_signo, &info); break; - case EXCP_DTB_MISS_PAL: - fprintf(stderr, "MMU data TLB miss in PALcode\n"); - exit(1); - break; - case EXCP_ITB_MISS: - fprintf(stderr, "MMU instruction TLB miss\n"); - exit(1); - break; - case EXCP_ITB_ACV: - fprintf(stderr, "MMU instruction access violation\n"); - exit(1); - break; - case EXCP_DTB_MISS_NATIVE: - fprintf(stderr, "MMU data TLB miss\n"); - exit(1); - break; case EXCP_UNALIGN: env->lock_addr = -1; info.si_signo = TARGET_SIGBUS; info.si_errno = 0; info.si_code = TARGET_BUS_ADRALN; - info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR]; + info._sifields._sigfault._addr = env->trap_arg0; queue_signal(env, info.si_signo, &info); break; case EXCP_OPCDEC: @@ -2503,12 +2685,20 @@ void cpu_loop (CPUState *env) info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, &info); break; + case EXCP_ARITH: + env->lock_addr = -1; + info.si_signo = TARGET_SIGFPE; + info.si_errno = 0; + info.si_code = TARGET_FPE_FLTINV; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, &info); + break; case EXCP_FEN: /* No-op. Linux simply re-enables the FPU. */ break; - case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1): + case EXCP_CALL_PAL: env->lock_addr = -1; - switch ((trapnr >> 6) | 0x80) { + switch (env->error_code) { case 0x80: /* BPT */ info.si_signo = TARGET_SIGTRAP; @@ -2531,7 +2721,8 @@ void cpu_loop (CPUState *env) sysret = do_syscall(env, trapnr, env->ir[IR_A0], env->ir[IR_A1], env->ir[IR_A2], env->ir[IR_A3], - env->ir[IR_A4], env->ir[IR_A5]); + env->ir[IR_A4], env->ir[IR_A5], + 0, 0); if (trapnr == TARGET_NR_sigreturn || trapnr == TARGET_NR_rt_sigreturn) { break; @@ -2599,8 +2790,6 @@ void cpu_loop (CPUState *env) goto do_sigill; } break; - case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1): - goto do_sigill; case EXCP_DEBUG: info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP); if (info.si_signo) { @@ -2624,50 +2813,81 @@ void cpu_loop (CPUState *env) } #endif /* TARGET_ALPHA */ -static void usage(void) +#ifdef TARGET_S390X +void cpu_loop(CPUS390XState *env) { - printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n" - "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n" - "Linux CPU emulator (compiled for %s emulation)\n" - "\n" - "Standard options:\n" - "-h print this help\n" - "-g port wait gdb connection to port\n" - "-L path set the elf interpreter prefix (default=%s)\n" - "-s size set the stack size in bytes (default=%ld)\n" - "-cpu model select CPU (-cpu ? for list)\n" - "-drop-ld-preload drop LD_PRELOAD for target process\n" - "-E var=value sets/modifies targets environment variable(s)\n" - "-U var unsets targets environment variable(s)\n" - "-0 argv0 forces target process argv[0] to be argv0\n" -#if defined(CONFIG_USE_GUEST_BASE) - "-B address set guest_base address to address\n" - "-R size reserve size bytes for guest virtual address space\n" -#endif - "\n" - "Debug options:\n" - "-d options activate log (logfile=%s)\n" - "-p pagesize set the host page size to 'pagesize'\n" - "-singlestep always run in singlestep mode\n" - "-strace log system calls\n" - "\n" - "Environment variables:\n" - "QEMU_STRACE Print system calls and arguments similar to the\n" - " 'strace' program. Enable by setting to any value.\n" - "You can use -E and -U options to set/unset environment variables\n" - "for target process. It is possible to provide several variables\n" - "by repeating the option. For example:\n" - " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n" - "Note that if you provide several changes to single variable\n" - "last change will stay in effect.\n" - , - TARGET_ARCH, - interp_prefix, - guest_stack_size, - DEBUG_LOGFILE); - exit(1); + int trapnr; + target_siginfo_t info; + + while (1) { + trapnr = cpu_s390x_exec (env); + + switch (trapnr) { + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_DEBUG: + { + int sig; + + sig = gdb_handlesig (env, TARGET_SIGTRAP); + if (sig) { + info.si_signo = sig; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(env, info.si_signo, &info); + } + } + break; + case EXCP_SVC: + { + int n = env->int_svc_code; + if (!n) { + /* syscalls > 255 */ + n = env->regs[1]; + } + env->psw.addr += env->int_svc_ilc; + env->regs[2] = do_syscall(env, n, + env->regs[2], + env->regs[3], + env->regs[4], + env->regs[5], + env->regs[6], + env->regs[7], + 0, 0); + } + break; + case EXCP_ADDR: + { + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->__excp_addr; + queue_signal(env, info.si_signo, &info); + } + break; + case EXCP_SPEC: + { + fprintf(stderr,"specification exception insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4)); + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = TARGET_ILL_ILLOPC; + info._sifields._sigfault._addr = env->__excp_addr; + queue_signal(env, info.si_signo, &info); + } + break; + default: + printf ("Unhandled trap: 0x%x\n", trapnr); + cpu_dump_state(env, stderr, fprintf, 0); + exit (1); + } + process_pending_signals (env); + } } +#endif /* TARGET_S390X */ + THREAD CPUState *thread_env; void task_settid(TaskState *ts) @@ -2703,35 +2923,363 @@ void init_task_state(TaskState *ts) } ts->sigqueue_table[i].next = NULL; } - + +static void handle_arg_help(const char *arg) +{ + usage(); +} + +static void handle_arg_log(const char *arg) +{ + int mask; + const CPULogItem *item; + + mask = cpu_str_to_log_mask(arg); + if (!mask) { + printf("Log items (comma separated):\n"); + for (item = cpu_log_items; item->mask != 0; item++) { + printf("%-10s %s\n", item->name, item->help); + } + exit(1); + } + cpu_set_log(mask); +} + +static void handle_arg_set_env(const char *arg) +{ + char *r, *p, *token; + r = p = strdup(arg); + while ((token = strsep(&p, ",")) != NULL) { + if (envlist_setenv(envlist, token) != 0) { + usage(); + } + } + free(r); +} + +static void handle_arg_unset_env(const char *arg) +{ + char *r, *p, *token; + r = p = strdup(arg); + while ((token = strsep(&p, ",")) != NULL) { + if (envlist_unsetenv(envlist, token) != 0) { + usage(); + } + } + free(r); +} + +static void handle_arg_argv0(const char *arg) +{ + argv0 = strdup(arg); +} + +static void handle_arg_stack_size(const char *arg) +{ + char *p; + guest_stack_size = strtoul(arg, &p, 0); + if (guest_stack_size == 0) { + usage(); + } + + if (*p == 'M') { + guest_stack_size *= 1024 * 1024; + } else if (*p == 'k' || *p == 'K') { + guest_stack_size *= 1024; + } +} + +static void handle_arg_ld_prefix(const char *arg) +{ + interp_prefix = strdup(arg); +} + +static void handle_arg_pagesize(const char *arg) +{ + qemu_host_page_size = atoi(arg); + if (qemu_host_page_size == 0 || + (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { + fprintf(stderr, "page size must be a power of two\n"); + exit(1); + } +} + +static void handle_arg_gdb(const char *arg) +{ + gdbstub_port = atoi(arg); +} + +static void handle_arg_uname(const char *arg) +{ + qemu_uname_release = strdup(arg); +} + +static void handle_arg_cpu(const char *arg) +{ + cpu_model = strdup(arg); + if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) { + /* XXX: implement xxx_cpu_list for targets that still miss it */ +#if defined(cpu_list_id) + cpu_list_id(stdout, &fprintf, ""); +#elif defined(cpu_list) + cpu_list(stdout, &fprintf); /* deprecated */ +#endif + exit(1); + } +} + +#if defined(CONFIG_USE_GUEST_BASE) +static void handle_arg_guest_base(const char *arg) +{ + guest_base = strtol(arg, NULL, 0); + have_guest_base = 1; +} + +static void handle_arg_reserved_va(const char *arg) +{ + char *p; + int shift = 0; + reserved_va = strtoul(arg, &p, 0); + switch (*p) { + case 'k': + case 'K': + shift = 10; + break; + case 'M': + shift = 20; + break; + case 'G': + shift = 30; + break; + } + if (shift) { + unsigned long unshifted = reserved_va; + p++; + reserved_va <<= shift; + if (((reserved_va >> shift) != unshifted) +#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS + || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) +#endif + ) { + fprintf(stderr, "Reserved virtual address too big\n"); + exit(1); + } + } + if (*p) { + fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p); + exit(1); + } +} +#endif + +static void handle_arg_singlestep(const char *arg) +{ + singlestep = 1; +} + +static void handle_arg_strace(const char *arg) +{ + do_strace = 1; +} + +static void handle_arg_version(const char *arg) +{ + printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION + ", Copyright (c) 2003-2008 Fabrice Bellard\n"); + exit(0); +} + +struct qemu_argument { + const char *argv; + const char *env; + bool has_arg; + void (*handle_opt)(const char *arg); + const char *example; + const char *help; +}; + +struct qemu_argument arg_table[] = { + {"h", "", false, handle_arg_help, + "", "print this help"}, + {"g", "QEMU_GDB", true, handle_arg_gdb, + "port", "wait gdb connection to 'port'"}, + {"L", "QEMU_LD_PREFIX", true, handle_arg_ld_prefix, + "path", "set the elf interpreter prefix to 'path'"}, + {"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size, + "size", "set the stack size to 'size' bytes"}, + {"cpu", "QEMU_CPU", true, handle_arg_cpu, + "model", "select CPU (-cpu ? for list)"}, + {"E", "QEMU_SET_ENV", true, handle_arg_set_env, + "var=value", "sets targets environment variable (see below)"}, + {"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env, + "var", "unsets targets environment variable (see below)"}, + {"0", "QEMU_ARGV0", true, handle_arg_argv0, + "argv0", "forces target process argv[0] to be 'argv0'"}, + {"r", "QEMU_UNAME", true, handle_arg_uname, + "uname", "set qemu uname release string to 'uname'"}, +#if defined(CONFIG_USE_GUEST_BASE) + {"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base, + "address", "set guest_base address to 'address'"}, + {"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va, + "size", "reserve 'size' bytes for guest virtual address space"}, +#endif + {"d", "QEMU_LOG", true, handle_arg_log, + "options", "activate log"}, + {"p", "QEMU_PAGESIZE", true, handle_arg_pagesize, + "pagesize", "set the host page size to 'pagesize'"}, + {"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep, + "", "run in singlestep mode"}, + {"strace", "QEMU_STRACE", false, handle_arg_strace, + "", "log system calls"}, + {"version", "QEMU_VERSION", false, handle_arg_version, + "", "display version information and exit"}, + {NULL, NULL, false, NULL, NULL, NULL} +}; + +static void usage(void) +{ + struct qemu_argument *arginfo; + int maxarglen; + int maxenvlen; + + printf("usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n" + "Linux CPU emulator (compiled for " TARGET_ARCH " emulation)\n" + "\n" + "Options and associated environment variables:\n" + "\n"); + + maxarglen = maxenvlen = 0; + + for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { + if (strlen(arginfo->env) > maxenvlen) { + maxenvlen = strlen(arginfo->env); + } + if (strlen(arginfo->argv) > maxarglen) { + maxarglen = strlen(arginfo->argv); + } + } + + printf("%-*s%-*sDescription\n", maxarglen+3, "Argument", + maxenvlen+1, "Env-variable"); + + for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { + if (arginfo->has_arg) { + printf("-%s %-*s %-*s %s\n", arginfo->argv, + (int)(maxarglen-strlen(arginfo->argv)), arginfo->example, + maxenvlen, arginfo->env, arginfo->help); + } else { + printf("-%-*s %-*s %s\n", maxarglen+1, arginfo->argv, + maxenvlen, arginfo->env, + arginfo->help); + } + } + + printf("\n" + "Defaults:\n" + "QEMU_LD_PREFIX = %s\n" + "QEMU_STACK_SIZE = %ld byte\n" + "QEMU_LOG = %s\n", + interp_prefix, + guest_stack_size, + DEBUG_LOGFILE); + + printf("\n" + "You can use -E and -U options or the QEMU_SET_ENV and\n" + "QEMU_UNSET_ENV environment variables to set and unset\n" + "environment variables for the target process.\n" + "It is possible to provide several variables by separating them\n" + "by commas in getsubopt(3) style. Additionally it is possible to\n" + "provide the -E and -U options multiple times.\n" + "The following lines are equivalent:\n" + " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n" + " -E var1=val2,var2=val2 -U LD_PRELOAD,LD_DEBUG\n" + " QEMU_SET_ENV=var1=val2,var2=val2 QEMU_UNSET_ENV=LD_PRELOAD,LD_DEBUG\n" + "Note that if you provide several changes to a single variable\n" + "the last change will stay in effect.\n"); + + exit(1); +} + +static int parse_args(int argc, char **argv) +{ + const char *r; + int optind; + struct qemu_argument *arginfo; + + for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { + if (arginfo->env == NULL) { + continue; + } + + r = getenv(arginfo->env); + if (r != NULL) { + arginfo->handle_opt(r); + } + } + + optind = 1; + for (;;) { + if (optind >= argc) { + break; + } + r = argv[optind]; + if (r[0] != '-') { + break; + } + optind++; + r++; + if (!strcmp(r, "-")) { + break; + } + + for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { + if (!strcmp(r, arginfo->argv)) { + if (arginfo->has_arg) { + if (optind >= argc) { + usage(); + } + arginfo->handle_opt(argv[optind]); + optind++; + } else { + arginfo->handle_opt(NULL); + } + break; + } + } + + /* no option matched the current argv */ + if (arginfo->handle_opt == NULL) { + usage(); + } + } + + if (optind >= argc) { + usage(); + } + + filename = argv[optind]; + exec_path = argv[optind]; + + return optind; +} + int main(int argc, char **argv, char **envp) { - const char *filename; - const char *cpu_model; + const char *log_file = DEBUG_LOGFILE; struct target_pt_regs regs1, *regs = ®s1; struct image_info info1, *info = &info1; struct linux_binprm bprm; TaskState *ts; CPUState *env; int optind; - const char *r; - int gdbstub_port = 0; char **target_environ, **wrk; char **target_argv; int target_argc; - envlist_t *envlist = NULL; - const char *argv0 = NULL; int i; int ret; - if (argc <= 1) - usage(); - qemu_cache_utils_init(envp); - /* init debug */ - cpu_set_log_filename(DEBUG_LOGFILE); - if ((envlist = envlist_create()) == NULL) { (void) fprintf(stderr, "Unable to allocate envlist\n"); exit(1); @@ -2758,143 +3306,9 @@ int main(int argc, char **argv, char **envp) cpudef_setup(); /* parse cpu definitions in target config file (TBD) */ #endif - optind = 1; - for(;;) { - if (optind >= argc) - break; - r = argv[optind]; - if (r[0] != '-') - break; - optind++; - r++; - if (!strcmp(r, "-")) { - break; - } else if (!strcmp(r, "d")) { - int mask; - const CPULogItem *item; - - if (optind >= argc) - break; - - r = argv[optind++]; - mask = cpu_str_to_log_mask(r); - if (!mask) { - printf("Log items (comma separated):\n"); - for(item = cpu_log_items; item->mask != 0; item++) { - printf("%-10s %s\n", item->name, item->help); - } - exit(1); - } - cpu_set_log(mask); - } else if (!strcmp(r, "E")) { - r = argv[optind++]; - if (envlist_setenv(envlist, r) != 0) - usage(); - } else if (!strcmp(r, "ignore-environment")) { - envlist_free(envlist); - if ((envlist = envlist_create()) == NULL) { - (void) fprintf(stderr, "Unable to allocate envlist\n"); - exit(1); - } - } else if (!strcmp(r, "U")) { - r = argv[optind++]; - if (envlist_unsetenv(envlist, r) != 0) - usage(); - } else if (!strcmp(r, "0")) { - r = argv[optind++]; - argv0 = r; - } else if (!strcmp(r, "s")) { - if (optind >= argc) - break; - r = argv[optind++]; - guest_stack_size = strtoul(r, (char **)&r, 0); - if (guest_stack_size == 0) - usage(); - if (*r == 'M') - guest_stack_size *= 1024 * 1024; - else if (*r == 'k' || *r == 'K') - guest_stack_size *= 1024; - } else if (!strcmp(r, "L")) { - interp_prefix = argv[optind++]; - } else if (!strcmp(r, "p")) { - if (optind >= argc) - break; - qemu_host_page_size = atoi(argv[optind++]); - if (qemu_host_page_size == 0 || - (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { - fprintf(stderr, "page size must be a power of two\n"); - exit(1); - } - } else if (!strcmp(r, "g")) { - if (optind >= argc) - break; - gdbstub_port = atoi(argv[optind++]); - } else if (!strcmp(r, "r")) { - qemu_uname_release = argv[optind++]; - } else if (!strcmp(r, "cpu")) { - cpu_model = argv[optind++]; - if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) { -/* XXX: implement xxx_cpu_list for targets that still miss it */ -#if defined(cpu_list_id) - cpu_list_id(stdout, &fprintf, ""); -#elif defined(cpu_list) - cpu_list(stdout, &fprintf); /* deprecated */ -#endif - exit(1); - } -#if defined(CONFIG_USE_GUEST_BASE) - } else if (!strcmp(r, "B")) { - guest_base = strtol(argv[optind++], NULL, 0); - have_guest_base = 1; - } else if (!strcmp(r, "R")) { - char *p; - int shift = 0; - reserved_va = strtoul(argv[optind++], &p, 0); - switch (*p) { - case 'k': - case 'K': - shift = 10; - break; - case 'M': - shift = 20; - break; - case 'G': - shift = 30; - break; - } - if (shift) { - unsigned long unshifted = reserved_va; - p++; - reserved_va <<= shift; - if (((reserved_va >> shift) != unshifted) -#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS - || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) -#endif - ) { - fprintf(stderr, "Reserved virtual address too big\n"); - exit(1); - } - } - if (*p) { - fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p); - exit(1); - } -#endif - } else if (!strcmp(r, "drop-ld-preload")) { - (void) envlist_unsetenv(envlist, "LD_PRELOAD"); - } else if (!strcmp(r, "singlestep")) { - singlestep = 1; - } else if (!strcmp(r, "strace")) { - do_strace = 1; - } else - { - usage(); - } - } - if (optind >= argc) - usage(); - filename = argv[optind]; - exec_path = argv[optind]; + /* init debug */ + cpu_set_log_filename(log_file); + optind = parse_args(argc, argv); /* Zero out regs */ memset(regs, 0, sizeof(struct target_pt_regs)); @@ -2916,6 +3330,8 @@ int main(int argc, char **argv, char **envp) #endif #elif defined(TARGET_ARM) cpu_model = "any"; +#elif defined(TARGET_UNICORE32) + cpu_model = "any"; #elif defined(TARGET_M68K) cpu_model = "any"; #elif defined(TARGET_SPARC) @@ -2940,7 +3356,8 @@ int main(int argc, char **argv, char **envp) cpu_model = "any"; #endif } - cpu_exec_init_all(0); + tcg_exec_init(0); + cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(cpu_model); @@ -2995,6 +3412,13 @@ int main(int argc, char **argv, char **envp) } qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va); } + + if (reserved_va || have_guest_base) { + if (!guest_validate_base(guest_base)) { + fprintf(stderr, "Guest base/Reserved VA rejected by guest code\n"); + exit(1); + } + } #endif /* CONFIG_USE_GUEST_BASE */ /* @@ -3038,7 +3462,7 @@ int main(int argc, char **argv, char **envp) } target_argv[target_argc] = NULL; - ts = qemu_mallocz (sizeof(TaskState)); + ts = g_malloc0 (sizeof(TaskState)); init_task_state(ts); /* build Task State */ ts->info = info; @@ -3218,6 +3642,14 @@ int main(int argc, char **argv, char **envp) env->regs[i] = regs->uregs[i]; } } +#elif defined(TARGET_UNICORE32) + { + int i; + cpu_asr_write(env, regs->uregs[32], 0xffffffff); + for (i = 0; i < 32; i++) { + env->regs[i] = regs->uregs[i]; + } + } #elif defined(TARGET_SPARC) { int i; @@ -3354,11 +3786,20 @@ int main(int argc, char **argv, char **envp) env->regs[15] = regs->acr; env->pc = regs->erp; } +#elif defined(TARGET_S390X) + { + int i; + for (i = 0; i < 16; i++) { + env->regs[i] = regs->gprs[i]; + } + env->psw.mask = regs->psw.mask; + env->psw.addr = regs->psw.addr; + } #else #error unsupported target CPU #endif -#if defined(TARGET_ARM) || defined(TARGET_M68K) +#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32) ts->stack_base = info->start_stack; ts->heap_base = info->brk; /* This will be filled in on the first SYS_HEAPINFO call. */ @@ -3366,7 +3807,11 @@ int main(int argc, char **argv, char **envp) #endif if (gdbstub_port) { - gdbserver_start (gdbstub_port); + if (gdbserver_start(gdbstub_port) < 0) { + fprintf(stderr, "qemu: could not open gdbserver on port %d\n", + gdbstub_port); + exit(1); + } gdb_handlesig(env, 0); } cpu_loop(env); diff --git a/linux-user/microblaze/syscall_nr.h b/linux-user/microblaze/syscall_nr.h index 3e641cd..f1fe0e7 100644 --- a/linux-user/microblaze/syscall_nr.h +++ b/linux-user/microblaze/syscall_nr.h @@ -364,6 +364,16 @@ #define TARGET_NR_sendmsg 360 /* new */ #define TARGET_NR_recvmsg 361 /* new */ #define TARGET_NR_accept04 362 /* new */ - -#define TARGET_NR_syscalls 363 +#define TARGET_NR_preadv 363 /* new */ +#define TARGET_NR_pwritev 364 /* new */ +#define TARGET_NR_rt_tgsigqueueinfo 365 /* new */ +#define TARGET_NR_perf_event_open 366 /* new */ +#define TARGET_NR_recvmmsg 367 /* new */ +#define TARGET_NR_fanotify_init 368 +#define TARGET_NR_fanotify_mark 369 +#define TARGET_NR_prlimit64 370 +#define TARGET_NR_name_to_handle_at 371 +#define TARGET_NR_open_by_handle_at 372 +#define TARGET_NR_clock_adjtime 373 +#define TARGET_NR_syncfs 374 diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h index 0595308..fbdc348 100644 --- a/linux-user/mips/syscall_nr.h +++ b/linux-user/mips/syscall_nr.h @@ -332,3 +332,16 @@ #define TARGET_NR_dup3 (TARGET_NR_Linux + 327) #define TARGET_NR_pipe2 (TARGET_NR_Linux + 328) #define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 329) +#define TARGET_NR_preadv (TARGET_NR_Linux + 330) +#define TARGET_NR_pwritev (TARGET_NR_Linux + 331) +#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 332) +#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 333) +#define TARGET_NR_accept4 (TARGET_NR_Linux + 334) +#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 335) +#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 336) +#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 337) +#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 338) +#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 339) +#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 340) +#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 341) +#define TARGET_NR_syncfs (TARGET_NR_Linux + 342) diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h index ee1d134..36d27b5 100644 --- a/linux-user/mips64/syscall_nr.h +++ b/linux-user/mips64/syscall_nr.h @@ -291,3 +291,16 @@ #define TARGET_NR_dup3 (TARGET_NR_Linux + 286) #define TARGET_NR_pipe2 (TARGET_NR_Linux + 287) #define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 288) +#define TARGET_NR_preadv (TARGET_NR_Linux + 289) +#define TARGET_NR_pwritev (TARGET_NR_Linux + 290) +#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 291) +#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 292) +#define TARGET_NR_accept4 (TARGET_NR_Linux + 293) +#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 294) +#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 295) +#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 296) +#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 297) +#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 298) +#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 299) +#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 300) +#define TARGET_NR_syncfs (TARGET_NR_Linux + 301) diff --git a/linux-user/mipsn32/syscall_nr.h b/linux-user/mipsn32/syscall_nr.h index 60a99dd..4e1aca3 100644 --- a/linux-user/mipsn32/syscall_nr.h +++ b/linux-user/mipsn32/syscall_nr.h @@ -295,3 +295,17 @@ #define TARGET_NR_dup3 (TARGET_NR_Linux + 290) #define TARGET_NR_pipe2 (TARGET_NR_Linux + 291) #define TARGET_NR_inotify_init1 (TARGET_NR_Linux + 292) +#define TARGET_NR_preadv (TARGET_NR_Linux + 293) +#define TARGET_NR_pwritev (TARGET_NR_Linux + 294) +#define TARGET_NR_rt_tgsigqueueinfo (TARGET_NR_Linux + 295) +#define TARGET_NR_perf_event_open (TARGET_NR_Linux + 296) +#define TARGET_NR_accept4 (TARGET_NR_Linux + 297) +#define TARGET_NR_recvmmsg (TARGET_NR_Linux + 298) +#define TARGET_NR_getdents64 (TARGET_NR_Linux + 299) +#define TARGET_NR_fanotify_init (TARGET_NR_Linux + 300) +#define TARGET_NR_fanotify_mark (TARGET_NR_Linux + 301) +#define TARGET_NR_prlimit64 (TARGET_NR_Linux + 302) +#define TARGET_NR_name_to_handle_at (TARGET_NR_Linux + 303) +#define TARGET_NR_open_by_handle_at (TARGET_NR_Linux + 304) +#define TARGET_NR_clock_adjtime (TARGET_NR_Linux + 305) +#define TARGET_NR_syncfs (TARGET_NR_Linux + 306) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index abf21f6..994c02b 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -216,6 +216,7 @@ static abi_ulong mmap_next_start = TASK_UNMAPPED_BASE; unsigned long last_brk; +#ifdef CONFIG_USE_GUEST_BASE /* Subroutine of mmap_find_vma, used when we have pre-allocated a chunk of guest address space. */ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size) @@ -249,6 +250,7 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size) mmap_next_start = addr; return last_addr; } +#endif /* * Find and reserve a free memory area of size 'size'. The search @@ -271,9 +273,11 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) size = HOST_PAGE_ALIGN(size); +#ifdef CONFIG_USE_GUEST_BASE if (RESERVED_VA) { return mmap_find_vma_reserved(start, size); } +#endif addr = start; wrapped = repeat = 0; @@ -350,7 +354,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) } wrapped = 1; /* Don't actually use 0 when wrapping, instead indicate - that we'd truely like an allocation in low memory. */ + that we'd truly like an allocation in low memory. */ addr = (mmap_min_addr > TARGET_PAGE_SIZE ? TARGET_PAGE_ALIGN(mmap_min_addr) : TARGET_PAGE_SIZE); diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h index cc84a4c..0673b7d 100644 --- a/linux-user/ppc/syscall_nr.h +++ b/linux-user/ppc/syscall_nr.h @@ -332,3 +332,33 @@ #define TARGET_NR_dup3 316 #define TARGET_NR_pipe2 317 #define TARGET_NR_inotify_init1 318 +#define TARGET_NR_perf_event_open 319 +#define TARGET_NR_preadv 320 +#define TARGET_NR_pwritev 321 +#define TARGET_NR_rt_tgsigqueueinfo 322 +#define TARGET_NR_fanotify_init 323 +#define TARGET_NR_fanotify_mark 324 +#define TARGET_NR_prlimit64 325 +#define TARGET_NR_socket 326 +#define TARGET_NR_bind 327 +#define TARGET_NR_connect 328 +#define TARGET_NR_listen 329 +#define TARGET_NR_accept 330 +#define TARGET_NR_getsockname 331 +#define TARGET_NR_getpeername 332 +#define TARGET_NR_socketpair 333 +#define TARGET_NR_send 334 +#define TARGET_NR_sendto 335 +#define TARGET_NR_recv 336 +#define TARGET_NR_recvfrom 337 +#define TARGET_NR_shutdown 338 +#define TARGET_NR_setsockopt 339 +#define TARGET_NR_getsockopt 340 +#define TARGET_NR_sendmsg 341 +#define TARGET_NR_recvmsg 342 +#define TARGET_NR_recvmmsg 343 +#define TARGET_NR_accept4 344 +#define TARGET_NR_name_to_handle_at 345 +#define TARGET_NR_open_by_handle_at 346 +#define TARGET_NR_clock_adjtime 347 +#define TARGET_NR_syncfs 348 diff --git a/linux-user/qemu-types.h b/linux-user/qemu-types.h index 1adda9f..fe7f662 100644 --- a/linux-user/qemu-types.h +++ b/linux-user/qemu-types.h @@ -9,6 +9,12 @@ typedef int32_t abi_long; #define TARGET_ABI_FMT_ld "%d" #define TARGET_ABI_FMT_lu "%u" #define TARGET_ABI_BITS 32 + +static inline abi_ulong tswapal(abi_ulong v) +{ + return tswap32(v); +} + #else typedef target_ulong abi_ulong; typedef target_long abi_long; @@ -20,5 +26,11 @@ typedef target_long abi_long; #if TARGET_ABI_BITS == 32 #define TARGET_ABI32 1 #endif + +static inline abi_ulong tswapal(abi_ulong v) +{ + return tswapl(v); +} + #endif #endif diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 32de241..55ad9d8 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -51,6 +51,13 @@ struct image_info { abi_ulong arg_start; abi_ulong arg_end; int personality; +#ifdef CONFIG_USE_FDPIC + abi_ulong loadmap_addr; + uint16_t nsegs; + void *loadsegs; + abi_ulong pt_dynamic_addr; + struct image_info *other_info; +#endif }; #ifdef TARGET_I386 @@ -98,6 +105,9 @@ typedef struct TaskState { FPA11 fpa; int swi_errno; #endif +#ifdef TARGET_UNICORE32 + int swi_errno; +#endif #if defined(TARGET_I386) && !defined(TARGET_X86_64) abi_ulong target_v86; struct vm86_saved_state vm86_saved_regs; @@ -111,7 +121,7 @@ typedef struct TaskState { #ifdef TARGET_M68K int sim_syscalls; #endif -#if defined(TARGET_ARM) || defined(TARGET_M68K) +#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32) /* Extra fields for semihosted binaries. */ uint32_t stack_base; uint32_t heap_base; @@ -182,7 +192,8 @@ abi_long do_brk(abi_ulong new_brk); void syscall_init(void); abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, - abi_long arg5, abi_long arg6); + abi_long arg5, abi_long arg6, abi_long arg7, + abi_long arg8); void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2); extern THREAD CPUState *thread_env; void cpu_loop(CPUState *env); @@ -191,6 +202,12 @@ int get_osversion(void); void fork_start(void); void fork_end(int child); +/* Return true if the proposed guest_base is suitable for the guest. + * The guest code may leave a page mapped and populate it if the + * address is suitable. + */ +bool guest_validate_base(unsigned long guest_base); + #include "qemu-log.h" /* strace.c */ @@ -369,7 +386,7 @@ abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len); abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len); /* Functions for accessing guest memory. The tget and tput functions - read/write single values, byteswapping as neccessary. The lock_user + read/write single values, byteswapping as necessary. The lock_user gets a pointer to a contiguous area of guest memory, but does not perform and byteswapping. lock_user may return either a pointer to the guest memory, or a temporary buffer. */ diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h index 262b236..365db58 100644 --- a/linux-user/sh4/syscall_nr.h +++ b/linux-user/sh4/syscall_nr.h @@ -125,7 +125,7 @@ #define TARGET_NR_clone 120 #define TARGET_NR_setdomainname 121 #define TARGET_NR_uname 122 -#define TARGET_NR_modify_ldt 123 +#define TARGET_NR_cacheflush 123 #define TARGET_NR_adjtimex 124 #define TARGET_NR_mprotect 125 #define TARGET_NR_sigprocmask 126 @@ -334,3 +334,35 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2 331 #define TARGET_NR_inotify_init1 332 +#define TARGET_NR_preadv 333 +#define TARGET_NR_pwritev 334 +#define TARGET_NR_rt_tgsigqueueinfo 335 +#define TARGET_NR_perf_event_open 336 +#define TARGET_NR_fanotify_init 337 +#define TARGET_NR_fanotify_mark 338 +#define TARGET_NR_prlimit64 339 + +/* Non-multiplexed socket family */ +#define TARGET_NR_socket 340 +#define TARGET_NR_bind 341 +#define TARGET_NR_connect 342 +#define TARGET_NR_listen 343 +#define TARGET_NR_accept 344 +#define TARGET_NR_getsockname 345 +#define TARGET_NR_getpeername 346 +#define TARGET_NR_socketpair 347 +#define TARGET_NR_send 348 +#define TARGET_NR_sendto 349 +#define TARGET_NR_recv 350 +#define TARGET_NR_recvfrom 351 +#define TARGET_NR_shutdown 352 +#define TARGET_NR_setsockopt 353 +#define TARGET_NR_getsockopt 354 +#define TARGET_NR_sendmsg 355 +#define TARGET_NR_recvmsg 356 +#define TARGET_NR_recvmmsg 357 +#define TARGET_NR_accept4 358 +#define TARGET_NR_name_to_handle_at 359 +#define TARGET_NR_open_by_handle_at 360 +#define TARGET_NR_clock_adjtime 361 +#define TARGET_NR_syncfs 362 diff --git a/linux-user/signal.c b/linux-user/signal.c index b01bd64..78e3380 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -153,7 +152,7 @@ void host_to_target_sigset(target_sigset_t *d, const sigset_t *s) host_to_target_sigset_internal(&d1, s); for(i = 0;i < TARGET_NSIG_WORDS; i++) - d->sig[i] = tswapl(d1.sig[i]); + d->sig[i] = tswapal(d1.sig[i]); } static void target_to_host_sigset_internal(sigset_t *d, @@ -174,7 +173,7 @@ void target_to_host_sigset(sigset_t *d, const target_sigset_t *s) int i; for(i = 0;i < TARGET_NSIG_WORDS; i++) - s1.sig[i] = tswapl(s->sig[i]); + s1.sig[i] = tswapal(s->sig[i]); target_to_host_sigset_internal(d, &s1); } @@ -235,14 +234,14 @@ static void tswap_siginfo(target_siginfo_t *tinfo, if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGTRAP) { tinfo->_sifields._sigfault._addr = - tswapl(info->_sifields._sigfault._addr); + tswapal(info->_sifields._sigfault._addr); } else if (sig == SIGIO) { tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid); tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid); tinfo->_sifields._rt._sigval.sival_ptr = - tswapl(info->_sifields._rt._sigval.sival_ptr); + tswapal(info->_sifields._rt._sigval.sival_ptr); } } @@ -263,7 +262,7 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) info->si_pid = tswap32(tinfo->_sifields._rt._pid); info->si_uid = tswap32(tinfo->_sifields._rt._uid); info->si_value.sival_ptr = - (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr); + (void *)(long)tswapal(tinfo->_sifields._rt._sigval.sival_ptr); } static int fatal_signal (int sig) @@ -391,7 +390,7 @@ static void QEMU_NORETURN force_sig(int target_sig) target_sig, strsignal(host_sig), "core dumped" ); } - /* The proper exit code for dieing from an uncaught signal is + /* The proper exit code for dying from an uncaught signal is * -. The kernel doesn't allow exit() or _exit() to pass * a negative value. To get the proper exit code we need to * actually die from an uncaught signal. Here the default signal @@ -587,19 +586,19 @@ int do_sigaction(int sig, const struct target_sigaction *act, sig, act, oact); #endif if (oact) { - oact->_sa_handler = tswapl(k->_sa_handler); - oact->sa_flags = tswapl(k->sa_flags); + oact->_sa_handler = tswapal(k->_sa_handler); + oact->sa_flags = tswapal(k->sa_flags); #if !defined(TARGET_MIPS) - oact->sa_restorer = tswapl(k->sa_restorer); + oact->sa_restorer = tswapal(k->sa_restorer); #endif oact->sa_mask = k->sa_mask; } if (act) { /* FIXME: This is not threadsafe. */ - k->_sa_handler = tswapl(act->_sa_handler); - k->sa_flags = tswapl(act->sa_flags); + k->_sa_handler = tswapal(act->_sa_handler); + k->sa_flags = tswapal(act->sa_flags); #if !defined(TARGET_MIPS) - k->sa_restorer = tswapl(act->sa_restorer); + k->sa_restorer = tswapal(act->sa_restorer); #endif k->sa_mask = act->sa_mask; @@ -982,8 +981,8 @@ restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax) env->regs[R_ECX] = tswapl(sc->ecx); env->eip = tswapl(sc->eip); - cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3); - cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3); + cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3); + cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3); tmpflags = tswapl(sc->eflags); env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); @@ -1275,10 +1274,7 @@ setup_return(CPUState *env, struct target_sigaction *ka, if (__put_user(retcodes[idx], rc)) return 1; -#if 0 - flush_icache_range((abi_ulong)rc, - (abi_ulong)(rc + 1)); -#endif + retcode = rc_addr + thumb; } @@ -1299,7 +1295,7 @@ static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env) __put_user(TARGET_VFP_MAGIC, &vfpframe->magic); __put_user(sizeof(*vfpframe), &vfpframe->size); for (i = 0; i < 32; i++) { - __put_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]); + __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]); } __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr); __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc); @@ -1588,7 +1584,7 @@ static abi_ulong *restore_sigframe_v2_vfp(CPUState *env, abi_ulong *regspace) return 0; } for (i = 0; i < 32; i++) { - __get_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]); + __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]); } __get_user(fpscr, &vfpframe->ufp.fpscr); vfp_set_fpscr(env, fpscr); @@ -2081,7 +2077,6 @@ long do_sigreturn(CPUState *env) uint32_t up_psr, pc, npc; target_sigset_t set; sigset_t host_set; - abi_ulong fpu_save_addr; int err, i; sf_addr = env->regwptr[UREG_FP]; @@ -2121,10 +2116,11 @@ long do_sigreturn(CPUState *env) err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]); } - err |= __get_user(fpu_save_addr, &sf->fpu_save); - - //if (fpu_save) - // err |= restore_fpu_state(env, fpu_save); + /* FIXME: implement FPU save/restore: + * __get_user(fpu_save, &sf->fpu_save); + * if (fpu_save) + * err |= restore_fpu_state(env, fpu_save); + */ /* This is pretty much atomic, no amount locking would prevent * the races which exist anyways. @@ -2229,7 +2225,6 @@ void sparc64_set_context(CPUSPARCState *env) target_mc_gregset_t *grp; abi_ulong pc, npc, tstate; abi_ulong fp, i7, w_addr; - unsigned char fenab; int err; unsigned int i; @@ -2294,15 +2289,21 @@ void sparc64_set_context(CPUSPARCState *env) if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), abi_ulong) != 0) goto do_sigsegv; - err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab)); + /* FIXME this does not match how the kernel handles the FPU in + * its sparc64_set_context implementation. In particular the FPU + * is only restored if fenab is non-zero in: + * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab)); + */ err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs)); { - uint32_t *src, *dst; - src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; - dst = env->fpr; - /* XXX: check that the CPU storage is the same as user context */ - for (i = 0; i < 64; i++, dst++, src++) - err |= __get_user(*dst, src); + uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; + for (i = 0; i < 64; i++, src++) { + if (i & 1) { + err |= __get_user(env->fpr[i/2].l.lower, src); + } else { + err |= __get_user(env->fpr[i/2].l.upper, src); + } + } } err |= __get_user(env->fsr, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr)); @@ -2391,12 +2392,14 @@ void sparc64_get_context(CPUSPARCState *env) err |= __put_user(i7, &(mcp->mc_i7)); { - uint32_t *src, *dst; - src = env->fpr; - dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; - /* XXX: check that the CPU storage is the same as user context */ - for (i = 0; i < 64; i++, dst++, src++) - err |= __put_user(*src, dst); + uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; + for (i = 0; i < 64; i++, dst++) { + if (i & 1) { + err |= __put_user(env->fpr[i/2].l.lower, dst); + } else { + err |= __put_user(env->fpr[i/2].l.upper, dst); + } + } } err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr)); err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr)); @@ -3062,10 +3065,10 @@ static void setup_frame(int sig, struct target_sigaction *ka, goto give_sigsegv; /* Set up registers for signal handler */ - regs->gregs[15] = (unsigned long) frame; + regs->gregs[15] = frame_addr; regs->gregs[4] = signal; /* Arg for signal handler */ regs->gregs[5] = 0; - regs->gregs[6] = (unsigned long) &frame->sc; + regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc); regs->pc = (unsigned long) ka->_sa_handler; unlock_user_struct(frame, frame_addr, 1); @@ -3125,10 +3128,10 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, goto give_sigsegv; /* Set up registers for signal handler */ - regs->gregs[15] = (unsigned long) frame; + regs->gregs[15] = frame_addr; regs->gregs[4] = signal; /* Arg for signal handler */ - regs->gregs[5] = (unsigned long) &frame->info; - regs->gregs[6] = (unsigned long) &frame->uc; + regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info); + regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc); regs->pc = (unsigned long) ka->_sa_handler; unlock_user_struct(frame, frame_addr, 1); @@ -3379,11 +3382,12 @@ static void setup_frame(int sig, struct target_sigaction *ka, goto badframe; /* Set up registers for signal handler */ - env->regs[1] = (unsigned long) frame; + env->regs[1] = frame_addr; /* Signal handler args: */ env->regs[5] = sig; /* Arg 0: signum */ env->regs[6] = 0; - env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */ + /* arg 1: sigcontext */ + env->regs[7] = frame_addr += offsetof(typeof(*frame), uc); /* Offset of 4 to handle microblaze rtid r14, 0 */ env->sregs[SR_PC] = (unsigned long)ka->_sa_handler; @@ -3557,11 +3561,11 @@ static void setup_frame(int sig, struct target_sigaction *ka, setup_sigcontext(&frame->sc, env); /* Move the stack and setup the arguments for the handler. */ - env->regs[R_SP] = (uint32_t) (unsigned long) frame; + env->regs[R_SP] = frame_addr; env->regs[10] = sig; env->pc = (unsigned long) ka->_sa_handler; /* Link SRP so the guest returns through the trampoline. */ - env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0]; + env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode); unlock_user_struct(frame, frame_addr, 1); return; @@ -3614,6 +3618,339 @@ long do_rt_sigreturn(CPUState *env) return -TARGET_ENOSYS; } +#elif defined(TARGET_S390X) + +#define __NUM_GPRS 16 +#define __NUM_FPRS 16 +#define __NUM_ACRS 16 + +#define S390_SYSCALL_SIZE 2 +#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */ + +#define _SIGCONTEXT_NSIG 64 +#define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */ +#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) +#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) +#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */ +#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00) + +typedef struct { + target_psw_t psw; + target_ulong gprs[__NUM_GPRS]; + unsigned int acrs[__NUM_ACRS]; +} target_s390_regs_common; + +typedef struct { + unsigned int fpc; + double fprs[__NUM_FPRS]; +} target_s390_fp_regs; + +typedef struct { + target_s390_regs_common regs; + target_s390_fp_regs fpregs; +} target_sigregs; + +struct target_sigcontext { + target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; + target_sigregs *sregs; +}; + +typedef struct { + uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; + struct target_sigcontext sc; + target_sigregs sregs; + int signo; + uint8_t retcode[S390_SYSCALL_SIZE]; +} sigframe; + +struct target_ucontext { + target_ulong tuc_flags; + struct target_ucontext *tuc_link; + target_stack_t tuc_stack; + target_sigregs tuc_mcontext; + target_sigset_t tuc_sigmask; /* mask last for extensibility */ +}; + +typedef struct { + uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; + uint8_t retcode[S390_SYSCALL_SIZE]; + struct target_siginfo info; + struct target_ucontext uc; +} rt_sigframe; + +static inline abi_ulong +get_sigframe(struct target_sigaction *ka, CPUState *env, size_t frame_size) +{ + abi_ulong sp; + + /* Default to using normal stack */ + sp = env->regs[15]; + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa_flags & TARGET_SA_ONSTACK) { + if (!sas_ss_flags(sp)) { + sp = target_sigaltstack_used.ss_sp + + target_sigaltstack_used.ss_size; + } + } + + /* This is the legacy signal stack switching. */ + else if (/* FIXME !user_mode(regs) */ 0 && + !(ka->sa_flags & TARGET_SA_RESTORER) && + ka->sa_restorer) { + sp = (abi_ulong) ka->sa_restorer; + } + + return (sp - frame_size) & -8ul; +} + +static void save_sigregs(CPUState *env, target_sigregs *sregs) +{ + int i; + //save_access_regs(current->thread.acrs); FIXME + + /* Copy a 'clean' PSW mask to the user to avoid leaking + information about whether PER is currently on. */ + __put_user(env->psw.mask, &sregs->regs.psw.mask); + __put_user(env->psw.addr, &sregs->regs.psw.addr); + for (i = 0; i < 16; i++) { + __put_user(env->regs[i], &sregs->regs.gprs[i]); + } + for (i = 0; i < 16; i++) { + __put_user(env->aregs[i], &sregs->regs.acrs[i]); + } + /* + * We have to store the fp registers to current->thread.fp_regs + * to merge them with the emulated registers. + */ + //save_fp_regs(¤t->thread.fp_regs); FIXME + for (i = 0; i < 16; i++) { + __put_user(env->fregs[i].ll, &sregs->fpregs.fprs[i]); + } +} + +static void setup_frame(int sig, struct target_sigaction *ka, + target_sigset_t *set, CPUState *env) +{ + sigframe *frame; + abi_ulong frame_addr; + + frame_addr = get_sigframe(ka, env, sizeof(*frame)); + qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__, + (unsigned long long)frame_addr); + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { + goto give_sigsegv; + } + + qemu_log("%s: 1\n", __FUNCTION__); + if (__put_user(set->sig[0], &frame->sc.oldmask[0])) { + goto give_sigsegv; + } + + save_sigregs(env, &frame->sregs); + + __put_user((abi_ulong)(unsigned long)&frame->sregs, + (abi_ulong *)&frame->sc.sregs); + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa_flags & TARGET_SA_RESTORER) { + env->regs[14] = (unsigned long) + ka->sa_restorer | PSW_ADDR_AMODE; + } else { + env->regs[14] = (unsigned long) + frame->retcode | PSW_ADDR_AMODE; + if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, + (uint16_t *)(frame->retcode))) + goto give_sigsegv; + } + + /* Set up backchain. */ + if (__put_user(env->regs[15], (abi_ulong *) frame)) { + goto give_sigsegv; + } + + /* Set up registers for signal handler */ + env->regs[15] = frame_addr; + env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; + + env->regs[2] = sig; //map_signal(sig); + env->regs[3] = frame_addr += offsetof(typeof(*frame), sc); + + /* We forgot to include these in the sigcontext. + To avoid breaking binary compatibility, they are passed as args. */ + env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no; + env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr; + + /* Place signal number on stack to allow backtrace from handler. */ + if (__put_user(env->regs[2], (int *) &frame->signo)) { + goto give_sigsegv; + } + unlock_user_struct(frame, frame_addr, 1); + return; + +give_sigsegv: + qemu_log("%s: give_sigsegv\n", __FUNCTION__); + unlock_user_struct(frame, frame_addr, 1); + force_sig(TARGET_SIGSEGV); +} + +static void setup_rt_frame(int sig, struct target_sigaction *ka, + target_siginfo_t *info, + target_sigset_t *set, CPUState *env) +{ + int i; + rt_sigframe *frame; + abi_ulong frame_addr; + + frame_addr = get_sigframe(ka, env, sizeof *frame); + qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__, + (unsigned long long)frame_addr); + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { + goto give_sigsegv; + } + + qemu_log("%s: 1\n", __FUNCTION__); + if (copy_siginfo_to_user(&frame->info, info)) { + goto give_sigsegv; + } + + /* Create the ucontext. */ + __put_user(0, &frame->uc.tuc_flags); + __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link); + __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); + __put_user(sas_ss_flags(get_sp_from_cpustate(env)), + &frame->uc.tuc_stack.ss_flags); + __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size); + save_sigregs(env, &frame->uc.tuc_mcontext); + for (i = 0; i < TARGET_NSIG_WORDS; i++) { + __put_user((abi_ulong)set->sig[i], + (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]); + } + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa_flags & TARGET_SA_RESTORER) { + env->regs[14] = (unsigned long) ka->sa_restorer | PSW_ADDR_AMODE; + } else { + env->regs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE; + if (__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, + (uint16_t *)(frame->retcode))) { + goto give_sigsegv; + } + } + + /* Set up backchain. */ + if (__put_user(env->regs[15], (abi_ulong *) frame)) { + goto give_sigsegv; + } + + /* Set up registers for signal handler */ + env->regs[15] = frame_addr; + env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; + + env->regs[2] = sig; //map_signal(sig); + env->regs[3] = frame_addr + offsetof(typeof(*frame), info); + env->regs[4] = frame_addr + offsetof(typeof(*frame), uc); + return; + +give_sigsegv: + qemu_log("%s: give_sigsegv\n", __FUNCTION__); + unlock_user_struct(frame, frame_addr, 1); + force_sig(TARGET_SIGSEGV); +} + +static int +restore_sigregs(CPUState *env, target_sigregs *sc) +{ + int err = 0; + int i; + + for (i = 0; i < 16; i++) { + err |= __get_user(env->regs[i], &sc->regs.gprs[i]); + } + + err |= __get_user(env->psw.mask, &sc->regs.psw.mask); + qemu_log("%s: sc->regs.psw.addr 0x%llx env->psw.addr 0x%llx\n", + __FUNCTION__, (unsigned long long)sc->regs.psw.addr, + (unsigned long long)env->psw.addr); + err |= __get_user(env->psw.addr, &sc->regs.psw.addr); + /* FIXME: 31-bit -> | PSW_ADDR_AMODE */ + + for (i = 0; i < 16; i++) { + err |= __get_user(env->aregs[i], &sc->regs.acrs[i]); + } + for (i = 0; i < 16; i++) { + err |= __get_user(env->fregs[i].ll, &sc->fpregs.fprs[i]); + } + + return err; +} + +long do_sigreturn(CPUState *env) +{ + sigframe *frame; + abi_ulong frame_addr = env->regs[15]; + qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__, + (unsigned long long)frame_addr); + target_sigset_t target_set; + sigset_t set; + + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { + goto badframe; + } + if (__get_user(target_set.sig[0], &frame->sc.oldmask[0])) { + goto badframe; + } + + target_to_host_sigset_internal(&set, &target_set); + sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ + + if (restore_sigregs(env, &frame->sregs)) { + goto badframe; + } + + unlock_user_struct(frame, frame_addr, 0); + return env->regs[2]; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return 0; +} + +long do_rt_sigreturn(CPUState *env) +{ + rt_sigframe *frame; + abi_ulong frame_addr = env->regs[15]; + qemu_log("%s: frame_addr 0x%llx\n", __FUNCTION__, + (unsigned long long)frame_addr); + sigset_t set; + + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { + goto badframe; + } + target_to_host_sigset(&set, &frame->uc.tuc_sigmask); + + sigprocmask(SIG_SETMASK, &set, NULL); /* ~_BLOCKABLE? */ + + if (restore_sigregs(env, &frame->uc.tuc_mcontext)) { + goto badframe; + } + + if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0, + get_sp_from_cpustate(env)) == -EFAULT) { + goto badframe; + } + unlock_user_struct(frame, frame_addr, 0); + return env->regs[2]; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return 0; +} + #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) /* FIXME: Many of the structures are defined for both PPC and PPC64, but diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h index 5d1ac21..f201f9f 100644 --- a/linux-user/sparc/syscall_nr.h +++ b/linux-user/sparc/syscall_nr.h @@ -136,6 +136,7 @@ #define TARGET_NR_utimes 138 /* SunOS Specific */ #define TARGET_NR_stat64 139 /* Linux sparc32 Specific */ #define TARGET_NR_getpeername 141 /* Common */ +#define TARGET_NR_futex 142 /* gethostid under SunOS */ #define TARGET_NR_gettid 143 /* ENOSYS under SunOS */ #define TARGET_NR_getrlimit 144 /* Common */ #define TARGET_NR_setrlimit 145 /* Common */ @@ -153,6 +154,7 @@ #define TARGET_NR_getdomainname 162 /* SunOS Specific */ #define TARGET_NR_setdomainname 163 /* Common */ #define TARGET_NR_quotactl 165 /* Common */ +#define TARGET_NR_set_tid_address 166 /* Linux specific, exportfs under SunOS */ #define TARGET_NR_mount 167 /* Common */ #define TARGET_NR_ustat 168 /* Common */ #define TARGET_NR_getdents 174 /* Common */ @@ -177,6 +179,7 @@ #define TARGET_NR_readahead 205 /* Linux Specific */ #define TARGET_NR_socketcall 206 /* Linux Specific */ #define TARGET_NR_syslog 207 /* Linux Specific */ +#define TARGET_NR_tgkill 211 /* Linux Specific */ #define TARGET_NR_waitpid 212 /* Linux Specific */ #define TARGET_NR_swapoff 213 /* Linux Specific */ #define TARGET_NR_sysinfo 214 /* Linux Specific */ @@ -285,3 +288,15 @@ #define TARGET_NR_pipe2 321 #define TARGET_NR_inotify_init1 322 #define TARGET_NR_accept4 323 +#define TARGET_NR_preadv 324 +#define TARGET_NR_pwritev 325 +#define TARGET_NR_rt_tgsigqueueinfo 326 +#define TARGET_NR_perf_event_open 327 +#define TARGET_NR_recvmmsg 328 +#define TARGET_NR_fanotify_init 329 +#define TARGET_NR_fanotify_mark 330 +#define TARGET_NR_prlimit64 331 +#define TARGET_NR_name_to_handle_at 332 +#define TARGET_NR_open_by_handle_at 333 +#define TARGET_NR_clock_adjtime 334 +#define TARGET_NR_syncfs 335 diff --git a/linux-user/sparc64/syscall_nr.h b/linux-user/sparc64/syscall_nr.h index bdca2a7..70988b2 100644 --- a/linux-user/sparc64/syscall_nr.h +++ b/linux-user/sparc64/syscall_nr.h @@ -322,3 +322,15 @@ #define TARGET_NR_pipe2 321 #define TARGET_NR_inotify_init1 322 #define TARGET_NR_accept4 323 +#define TARGET_NR_preadv 324 +#define TARGET_NR_pwritev 325 +#define TARGET_NR_rt_tgsigqueueinfo 326 +#define TARGET_NR_perf_event_open 327 +#define TARGET_NR_recvmmsg 328 +#define TARGET_NR_fanotify_init 329 +#define TARGET_NR_fanotify_mark 330 +#define TARGET_NR_prlimit64 331 +#define TARGET_NR_name_to_handle_at 332 +#define TARGET_NR_open_by_handle_at 333 +#define TARGET_NR_clock_adjtime 334 +#define TARGET_NR_syncfs 335 diff --git a/linux-user/strace.c b/linux-user/strace.c index bf9a0d9..90027a1 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "qemu.h" int do_strace=0; @@ -63,6 +64,7 @@ UNUSED static void print_string(abi_long, int); UNUSED static void print_raw_param(const char *, abi_long, int); UNUSED static void print_timeval(abi_ulong, int); UNUSED static void print_number(abi_long, int); +UNUSED static void print_signal(abi_ulong, int); /* * Utility functions @@ -117,6 +119,37 @@ if( cmd == val ) { \ gemu_log("%d",cmd); } +static void +print_signal(abi_ulong arg, int last) +{ + const char *signal_name = NULL; + switch(arg) { + case TARGET_SIGHUP: signal_name = "SIGHUP"; break; + case TARGET_SIGINT: signal_name = "SIGINT"; break; + case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break; + case TARGET_SIGILL: signal_name = "SIGILL"; break; + case TARGET_SIGABRT: signal_name = "SIGABRT"; break; + case TARGET_SIGFPE: signal_name = "SIGFPE"; break; + case TARGET_SIGKILL: signal_name = "SIGKILL"; break; + case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break; + case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break; + case TARGET_SIGALRM: signal_name = "SIGALRM"; break; + case TARGET_SIGTERM: signal_name = "SIGTERM"; break; + case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break; + case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break; + case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break; + case TARGET_SIGCONT: signal_name = "SIGCONT"; break; + case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break; + case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break; + case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break; + } + if (signal_name == NULL) { + print_raw_param("%ld", arg, 1); + return; + } + gemu_log("%s%s", signal_name, get_comma(last)); +} + #ifdef TARGET_NR__newselect static void print_fdset(int n, abi_ulong target_fds_addr) @@ -136,7 +169,7 @@ print_fdset(int n, abi_ulong target_fds_addr) return; for (i=n; i>=0; i--) { - if ((tswapl(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1) + if ((tswapal(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1) gemu_log("%d,", i ); } unlock_user(target_fds, target_fds_addr, 0); @@ -212,7 +245,7 @@ print_execve(const struct syscallname *name, arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1); if (!arg_ptr) return; - arg_addr = tswapl(*arg_ptr); + arg_addr = tswapal(*arg_ptr); unlock_user(arg_ptr, arg_ptr_addr, 0); if (!arg_addr) break; @@ -398,6 +431,7 @@ UNUSED static struct flags mmap_flags[] = { FLAG_TARGET(MAP_DENYWRITE), FLAG_TARGET(MAP_FIXED), FLAG_TARGET(MAP_GROWSDOWN), + FLAG_TARGET(MAP_EXECUTABLE), #ifdef MAP_LOCKED FLAG_TARGET(MAP_LOCKED), #endif @@ -408,6 +442,9 @@ UNUSED static struct flags mmap_flags[] = { #ifdef MAP_POPULATE FLAG_TARGET(MAP_POPULATE), #endif +#ifdef TARGET_MAP_UNINITIALIZED + FLAG_TARGET(MAP_UNINITIALIZED), +#endif FLAG_END, }; @@ -423,6 +460,44 @@ UNUSED static struct flags fcntl_flags[] = { FLAG_END, }; +UNUSED static struct flags clone_flags[] = { + FLAG_GENERIC(CLONE_VM), + FLAG_GENERIC(CLONE_FS), + FLAG_GENERIC(CLONE_FILES), + FLAG_GENERIC(CLONE_SIGHAND), + FLAG_GENERIC(CLONE_PTRACE), + FLAG_GENERIC(CLONE_VFORK), + FLAG_GENERIC(CLONE_PARENT), + FLAG_GENERIC(CLONE_THREAD), + FLAG_GENERIC(CLONE_NEWNS), + FLAG_GENERIC(CLONE_SYSVSEM), + FLAG_GENERIC(CLONE_SETTLS), + FLAG_GENERIC(CLONE_PARENT_SETTID), + FLAG_GENERIC(CLONE_CHILD_CLEARTID), + FLAG_GENERIC(CLONE_DETACHED), + FLAG_GENERIC(CLONE_UNTRACED), + FLAG_GENERIC(CLONE_CHILD_SETTID), +#if defined(CLONE_NEWUTS) + FLAG_GENERIC(CLONE_NEWUTS), +#endif +#if defined(CLONE_NEWIPC) + FLAG_GENERIC(CLONE_NEWIPC), +#endif +#if defined(CLONE_NEWUSER) + FLAG_GENERIC(CLONE_NEWUSER), +#endif +#if defined(CLONE_NEWPID) + FLAG_GENERIC(CLONE_NEWPID), +#endif +#if defined(CLONE_NEWNET) + FLAG_GENERIC(CLONE_NEWNET), +#endif +#if defined(CLONE_IO) + FLAG_GENERIC(CLONE_IO), +#endif + FLAG_END, +}; + /* * print_xxx utility functions. These are used to print syscall * parameters in certain format. All of these have parameter @@ -437,14 +512,11 @@ get_comma(int last) } static void -print_flags(const struct flags *f, abi_long tflags, int last) +print_flags(const struct flags *f, abi_long flags, int last) { const char *sep = ""; - int flags; int n; - flags = (int)tswap32(tflags); - if ((flags == 0) && (f->f_value == 0)) { gemu_log("%s%s", f->f_string, get_comma(last)); return; @@ -461,36 +533,33 @@ print_flags(const struct flags *f, abi_long tflags, int last) if (n > 0) { /* print rest of the flags as numeric */ if (flags != 0) { - gemu_log("%s%#x%s", sep, flags, get_comma(last)); + gemu_log("%s%#x%s", sep, (unsigned int)flags, get_comma(last)); } else { gemu_log("%s", get_comma(last)); } } else { /* no string version of flags found, print them in hex then */ - gemu_log("%#x%s", flags, get_comma(last)); + gemu_log("%#x%s", (unsigned int)flags, get_comma(last)); } } static void -print_at_dirfd(abi_long tdirfd, int last) +print_at_dirfd(abi_long dirfd, int last) { - int dirfd = tswap32(tdirfd); - #ifdef AT_FDCWD if (dirfd == AT_FDCWD) { gemu_log("AT_FDCWD%s", get_comma(last)); return; } #endif - gemu_log("%d%s", dirfd, get_comma(last)); + gemu_log("%d%s", (int)dirfd, get_comma(last)); } static void -print_file_mode(abi_long tmode, int last) +print_file_mode(abi_long mode, int last) { const char *sep = ""; const struct flags *m; - mode_t mode = (mode_t)tswap32(tmode); for (m = &mode_flags[0]; m->f_string != NULL; m++) { if ((m->f_value & mode) == m->f_value) { @@ -504,16 +573,14 @@ print_file_mode(abi_long tmode, int last) mode &= ~S_IFMT; /* print rest of the mode as octal */ if (mode != 0) - gemu_log("%s%#o", sep, mode); + gemu_log("%s%#o", sep, (unsigned int)mode); gemu_log("%s", get_comma(last)); } static void -print_open_flags(abi_long tflags, int last) +print_open_flags(abi_long flags, int last) { - int flags = tswap32(tflags); - print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1); flags &= ~TARGET_O_ACCMODE; if (flags == 0) { @@ -616,7 +683,7 @@ print_accept(const struct syscallname *name, abi_long arg3, abi_long arg4, abi_long arg5) { print_syscall_prologue(name); - print_raw_param("%d", tswap32(arg0), 0); + print_raw_param("%d", arg0, 0); print_pointer(arg1, 0); print_number(arg2, 1); print_syscall_epilogue(name); @@ -673,6 +740,39 @@ print_chmod(const struct syscallname *name, } #endif +#ifdef TARGET_NR_clone +static void +print_clone(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); +#if defined(TARGET_M68K) + print_flags(clone_flags, arg0, 0); + print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1); +#elif defined(TARGET_SH4) || defined(TARGET_ALPHA) + print_flags(clone_flags, arg0, 0); + print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0); + print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0); + print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0); + print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1); +#elif defined(TARGET_CRIS) + print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0); + print_flags(clone_flags, arg1, 0); + print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0); + print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0); + print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1); +#else + print_flags(clone_flags, arg0, 0); + print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0); + print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0); + print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0); + print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1); +#endif + print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_creat static void print_creat(const struct syscallname *name, @@ -694,7 +794,7 @@ print_execv(const struct syscallname *name, { print_syscall_prologue(name); print_string(arg0, 0); - print_raw_param("0x" TARGET_ABI_FMT_lx, tswapl(arg1), 1); + print_raw_param("0x" TARGET_ABI_FMT_lx, arg1, 1); print_syscall_epilogue(name); } #endif @@ -738,13 +838,8 @@ print_fchownat(const struct syscallname *name, print_syscall_prologue(name); print_at_dirfd(arg0, 0); print_string(arg1, 0); -#ifdef USE_UID16 - print_raw_param("%d", tswap16(arg2), 0); - print_raw_param("%d", tswap16(arg3), 0); -#else - print_raw_param("%d", tswap32(arg2), 0); - print_raw_param("%d", tswap32(arg3), 0); -#endif + print_raw_param("%d", arg2, 0); + print_raw_param("%d", arg3, 0); print_flags(at_file_flags, arg4, 1); print_syscall_epilogue(name); } @@ -757,7 +852,7 @@ print_fcntl(const struct syscallname *name, abi_long arg3, abi_long arg4, abi_long arg5) { print_syscall_prologue(name); - print_raw_param("%d", tswap32(arg0), 0); + print_raw_param("%d", arg0, 0); print_flags(fcntl_flags, arg1, 0); /* * TODO: check flags and print following argument only @@ -814,6 +909,28 @@ print_linkat(const struct syscallname *name, } #endif +#ifdef TARGET_NR__llseek +static void +print__llseek(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + const char *whence = "UNKNOWN"; + print_syscall_prologue(name); + print_raw_param("%d", arg0, 0); + print_raw_param("%ld", arg1, 0); + print_raw_param("%ld", arg2, 0); + print_pointer(arg3, 0); + switch(arg4) { + case SEEK_SET: whence = "SEEK_SET"; break; + case SEEK_CUR: whence = "SEEK_CUR"; break; + case SEEK_END: whence = "SEEK_END"; break; + } + gemu_log("%s",whence); + print_syscall_epilogue(name); +} +#endif + #if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \ defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) static void @@ -838,7 +955,7 @@ print_fstat(const struct syscallname *name, abi_long arg3, abi_long arg4, abi_long arg5) { print_syscall_prologue(name); - print_raw_param("%d", tswap32(arg0), 0); + print_raw_param("%d", arg0, 0); print_pointer(arg1, 1); print_syscall_epilogue(name); } @@ -872,20 +989,66 @@ print_mkdirat(const struct syscallname *name, } #endif +#ifdef TARGET_NR_rmdir +static void +print_rmdir(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_string(arg0, 0); + print_syscall_epilogue(name); +} +#endif + +#ifdef TARGET_NR_rt_sigaction +static void +print_rt_sigaction(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_signal(arg0, 0); + print_pointer(arg1, 0); + print_pointer(arg2, 1); + print_syscall_epilogue(name); +} +#endif + +#ifdef TARGET_NR_rt_sigprocmask +static void +print_rt_sigprocmask(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + const char *how = "UNKNOWN"; + print_syscall_prologue(name); + switch(arg0) { + case TARGET_SIG_BLOCK: how = "SIG_BLOCK"; break; + case TARGET_SIG_UNBLOCK: how = "SIG_UNBLOCK"; break; + case TARGET_SIG_SETMASK: how = "SIG_SETMASK"; break; + } + gemu_log("%s,",how); + print_pointer(arg1, 0); + print_pointer(arg2, 1); + print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_mknod static void print_mknod(const struct syscallname *name, abi_long arg0, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5) { - int hasdev = (tswapl(arg1) & (S_IFCHR|S_IFBLK)); + int hasdev = (arg1 & (S_IFCHR|S_IFBLK)); print_syscall_prologue(name); print_string(arg0, 0); print_file_mode(arg1, (hasdev == 0)); if (hasdev) { - print_raw_param("makedev(%d", major(tswapl(arg2)), 0); - print_raw_param("%d)", minor(tswapl(arg2)), 1); + print_raw_param("makedev(%d", major(arg2), 0); + print_raw_param("%d)", minor(arg2), 1); } print_syscall_epilogue(name); } @@ -897,15 +1060,15 @@ print_mknodat(const struct syscallname *name, abi_long arg0, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5) { - int hasdev = (tswapl(arg2) & (S_IFCHR|S_IFBLK)); + int hasdev = (arg2 & (S_IFCHR|S_IFBLK)); print_syscall_prologue(name); print_at_dirfd(arg0, 0); print_string(arg1, 0); print_file_mode(arg2, (hasdev == 0)); if (hasdev) { - print_raw_param("makedev(%d", major(tswapl(arg3)), 0); - print_raw_param("%d)", minor(tswapl(arg3)), 1); + print_raw_param("makedev(%d", major(arg3), 0); + print_raw_param("%d)", minor(arg3), 1); } print_syscall_epilogue(name); } @@ -917,7 +1080,7 @@ print_mq_open(const struct syscallname *name, abi_long arg0, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5) { - int is_creat = (tswapl(arg1) & TARGET_O_CREAT); + int is_creat = (arg1 & TARGET_O_CREAT); print_syscall_prologue(name); print_string(arg0, 0); @@ -936,7 +1099,7 @@ print_open(const struct syscallname *name, abi_long arg0, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5) { - int is_creat = (tswap32(arg1) & TARGET_O_CREAT); + int is_creat = (arg1 & TARGET_O_CREAT); print_syscall_prologue(name); print_string(arg0, 0); @@ -953,7 +1116,7 @@ print_openat(const struct syscallname *name, abi_long arg0, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5) { - int is_creat = (tswap32(arg2) & TARGET_O_CREAT); + int is_creat = (arg2 & TARGET_O_CREAT); print_syscall_prologue(name); print_at_dirfd(arg0, 0); @@ -1002,7 +1165,7 @@ print_readlink(const struct syscallname *name, print_syscall_prologue(name); print_string(arg0, 0); print_pointer(arg1, 0); - print_raw_param("%u", tswapl(arg2), 1); + print_raw_param("%u", arg2, 1); print_syscall_epilogue(name); } #endif @@ -1017,7 +1180,7 @@ print_readlinkat(const struct syscallname *name, print_at_dirfd(arg0, 0); print_string(arg1, 0); print_pointer(arg2, 0); - print_raw_param("%u", tswapl(arg3), 1); + print_raw_param("%u", arg3, 1); print_syscall_epilogue(name); } #endif @@ -1199,7 +1362,7 @@ print_utimensat(const struct syscallname *name, } #endif -#ifdef TARGET_NR_mmap +#if defined(TARGET_NR_mmap) || defined(TARGET_NR_mmap2) static void print_mmap(const struct syscallname *name, abi_long arg0, abi_long arg1, abi_long arg2, @@ -1207,11 +1370,11 @@ print_mmap(const struct syscallname *name, { print_syscall_prologue(name); print_pointer(arg0, 0); - print_raw_param("%d", tswapl(arg1), 0); + print_raw_param("%d", arg1, 0); print_flags(mmap_prot_flags, arg2, 0); print_flags(mmap_flags, arg3, 0); - print_raw_param("%d", tswapl(arg4), 0); - print_raw_param("%#x", tswapl(arg5), 1); + print_raw_param("%d", arg4, 0); + print_raw_param("%#x", arg5, 1); print_syscall_epilogue(name); } #define print_mmap2 print_mmap @@ -1225,7 +1388,7 @@ print_mprotect(const struct syscallname *name, { print_syscall_prologue(name); print_pointer(arg0, 0); - print_raw_param("%d", tswapl(arg1), 0); + print_raw_param("%d", arg1, 0); print_flags(mmap_prot_flags, arg2, 1); print_syscall_epilogue(name); } @@ -1239,7 +1402,7 @@ print_munmap(const struct syscallname *name, { print_syscall_prologue(name); print_pointer(arg0, 0); - print_raw_param("%d", tswapl(arg1), 1); + print_raw_param("%d", arg1, 1); print_syscall_epilogue(name); } #endif @@ -1253,7 +1416,7 @@ if( cmd == val ) { \ return; \ } - int cmd = (int)tswap32(tflag); + int cmd = (int)tflag; #ifdef FUTEX_PRIVATE_FLAG if (cmd & FUTEX_PRIVATE_FLAG) { gemu_log("FUTEX_PRIVATE_FLAG|"); @@ -1287,10 +1450,23 @@ print_futex(const struct syscallname *name, print_syscall_prologue(name); print_pointer(arg0, 0); print_futex_op(arg1, 0); - print_raw_param(",%d", tswapl(arg2), 0); + print_raw_param(",%d", arg2, 0); print_pointer(arg3, 0); /* struct timespec */ print_pointer(arg4, 0); - print_raw_param("%d", tswapl(arg4), 1); + print_raw_param("%d", arg4, 1); + print_syscall_epilogue(name); +} +#endif + +#ifdef TARGET_NR_kill +static void +print_kill(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_raw_param("%d", arg0, 0); + print_signal(arg1, 1); print_syscall_epilogue(name); } #endif diff --git a/linux-user/strace.list b/linux-user/strace.list index d7be0e7..a7eeaef 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -85,7 +85,7 @@ { TARGET_NR_clock_settime, "clock_settime" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_clone -{ TARGET_NR_clone, "clone" , NULL, NULL, NULL }, +{ TARGET_NR_clone, "clone" , NULL, print_clone, NULL }, #endif #ifdef TARGET_NR_close { TARGET_NR_close, "close" , "%s(%d)", NULL, NULL }, @@ -292,7 +292,7 @@ { TARGET_NR_getpgrp, "getpgrp" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_getpid -{ TARGET_NR_getpid, "getpid" , NULL, NULL, NULL }, +{ TARGET_NR_getpid, "getpid" , "%s()", NULL, NULL }, #endif #ifdef TARGET_NR_getpmsg { TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL }, @@ -418,7 +418,7 @@ { TARGET_NR_keyctl, "keyctl" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_kill -{ TARGET_NR_kill, "kill" , NULL, NULL, NULL }, +{ TARGET_NR_kill, "kill", NULL, print_kill, NULL }, #endif #ifdef TARGET_NR_lchown { TARGET_NR_lchown, "lchown" , NULL, NULL, NULL }, @@ -448,7 +448,7 @@ { TARGET_NR_llistxattr, "llistxattr" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR__llseek -{ TARGET_NR__llseek, "_llseek" , NULL, NULL, NULL }, +{ TARGET_NR__llseek, "_llseek" , NULL, print__llseek, NULL }, #endif #ifdef TARGET_NR_lock { TARGET_NR_lock, "lock" , NULL, NULL, NULL }, @@ -495,6 +495,9 @@ #ifdef TARGET_NR_mkdirat { TARGET_NR_mkdirat, "mkdirat" , NULL, print_mkdirat, NULL }, #endif +#ifdef TARGET_NR_rmdir +{ TARGET_NR_rmdir, "rmdir" , NULL, print_rmdir, NULL }, +#endif #ifdef TARGET_NR_mknod { TARGET_NR_mknod, "mknod" , NULL, print_mknod, NULL }, #endif @@ -1060,13 +1063,13 @@ { TARGET_NR_rmdir, "rmdir" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_rt_sigaction -{ TARGET_NR_rt_sigaction, "rt_sigaction" , NULL, NULL, NULL }, +{ TARGET_NR_rt_sigaction, "rt_sigaction" , NULL, print_rt_sigaction, NULL }, #endif #ifdef TARGET_NR_rt_sigpending { TARGET_NR_rt_sigpending, "rt_sigpending" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_rt_sigprocmask -{ TARGET_NR_rt_sigprocmask, "rt_sigprocmask" , NULL, NULL, NULL }, +{ TARGET_NR_rt_sigprocmask, "rt_sigprocmask" , NULL, print_rt_sigprocmask, NULL }, #endif #ifdef TARGET_NR_rt_sigqueueinfo { TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, NULL, NULL }, diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 499c4d7..f227097 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -59,13 +59,20 @@ int __clone2(int (*fn)(void *), void *child_stack_base, //#include #include #include -#include +#include +#include "qemu-common.h" #ifdef TARGET_GPROF #include #endif #ifdef CONFIG_EVENTFD #include #endif +#ifdef CONFIG_EPOLL +#include +#endif +#ifdef CONFIG_ATTR +#include "qemu-xattr.h" +#endif #define termios host_termios #define winsize host_winsize @@ -92,7 +99,6 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include "cpu-uname.h" #include "qemu.h" -#include "qemu-common.h" #if defined(CONFIG_USE_NPTL) #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \ @@ -193,7 +199,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ #define __NR_sys_inotify_add_watch __NR_inotify_add_watch #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch -#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) +#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \ + defined(__s390x__) #define __NR__llseek __NR_lseek #endif @@ -235,6 +242,14 @@ _syscall6(int,sys_futex,int *,uaddr,int,op,int,val, const struct timespec *,timeout,int *,uaddr2,int,val3) #endif #endif +#define __NR_sys_sched_getaffinity __NR_sched_getaffinity +_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len, + unsigned long *, user_mask_ptr); +#define __NR_sys_sched_setaffinity __NR_sched_setaffinity +_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len, + unsigned long *, user_mask_ptr); +_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd, + void *, arg); static bitmask_transtbl fcntl_flags_tbl[] = { { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, }, @@ -276,7 +291,7 @@ static int sys_uname(struct new_utsname *buf) * struct linux kernel uses). */ - bzero(buf, sizeof (*buf)); + memset(buf, 0, sizeof(*buf)); COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname); COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename); COPY_UTSNAME_FIELD(buf->release, uts_buf.release); @@ -317,7 +332,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode) return (fchmodat(dirfd, pathname, mode, 0)); } #endif -#if defined(TARGET_NR_fchownat) && defined(USE_UID16) +#if defined(TARGET_NR_fchownat) static int sys_fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags) { @@ -366,25 +381,13 @@ static int sys_mknodat(int dirfd, const char *pathname, mode_t mode, } #endif #ifdef TARGET_NR_openat -static int sys_openat(int dirfd, const char *pathname, int flags, ...) +static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode) { /* * open(2) has extra parameter 'mode' when called with * flag O_CREAT. */ if ((flags & O_CREAT) != 0) { - va_list ap; - mode_t mode; - - /* - * Get the 'mode' parameter and translate it to - * host bits. - */ - va_start(ap, flags); - mode = va_arg(ap, mode_t); - mode = target_to_host_bitmask(mode, fcntl_flags_tbl); - va_end(ap); - return (openat(dirfd, pathname, flags, mode)); } return (openat(dirfd, pathname, flags)); @@ -426,7 +429,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode) #if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat) _syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode) #endif -#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16) +#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname, uid_t,owner,gid_t,group,int,flags) #endif @@ -529,6 +532,39 @@ static int sys_inotify_init1(int flags) #undef TARGET_NR_inotify_rm_watch #endif /* CONFIG_INOTIFY */ +#if defined(TARGET_NR_ppoll) +#ifndef __NR_ppoll +# define __NR_ppoll -1 +#endif +#define __NR_sys_ppoll __NR_ppoll +_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds, + struct timespec *, timeout, const __sigset_t *, sigmask, + size_t, sigsetsize) +#endif + +#if defined(TARGET_NR_pselect6) +#ifndef __NR_pselect6 +# define __NR_pselect6 -1 +#endif +#define __NR_sys_pselect6 __NR_pselect6 +_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, + fd_set *, exceptfds, struct timespec *, timeout, void *, sig); +#endif + +#if defined(TARGET_NR_prlimit64) +#ifndef __NR_prlimit64 +# define __NR_prlimit64 -1 +#endif +#define __NR_sys_prlimit64 __NR_prlimit64 +/* The glibc rlimit structure may not be that used by the underlying syscall */ +struct host_rlimit64 { + uint64_t rlim_cur; + uint64_t rlim_max; +}; +_syscall4(int, sys_prlimit64, pid_t, pid, int, resource, + const struct host_rlimit64 *, new_limit, + struct host_rlimit64 *, old_limit) +#endif extern int personality(int); extern int flock(int, int); @@ -536,6 +572,17 @@ extern int setfsuid(int); extern int setfsgid(int); extern int setgroups(int, gid_t *); +/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */ +#ifdef TARGET_ARM +static inline int regpairs_aligned(void *cpu_env) { + return ((((CPUARMState *)cpu_env)->eabi) == 1) ; +} +#elif defined(TARGET_MIPS) +static inline int regpairs_aligned(void *cpu_env) { return 1; } +#else +static inline int regpairs_aligned(void *cpu_env) { return 0; } +#endif + #define ERRNO_TABLE_SIZE 1200 /* target_to_host_errno_table[] is initialized from @@ -689,49 +736,90 @@ char *target_strerror(int err) static abi_ulong target_brk; static abi_ulong target_original_brk; +static abi_ulong brk_page; void target_set_brk(abi_ulong new_brk) { target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); + brk_page = HOST_PAGE_ALIGN(target_brk); } +//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0) +#define DEBUGF_BRK(message, args...) + /* do_brk() must return target values and target errnos. */ abi_long do_brk(abi_ulong new_brk) { - abi_ulong brk_page; abi_long mapped_addr; int new_alloc_size; - if (!new_brk) + DEBUGF_BRK("do_brk(%#010x) -> ", new_brk); + + if (!new_brk) { + DEBUGF_BRK("%#010x (!new_brk)\n", target_brk); return target_brk; - if (new_brk < target_original_brk) + } + if (new_brk < target_original_brk) { + DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk); return target_brk; + } - brk_page = HOST_PAGE_ALIGN(target_brk); - - /* If the new brk is less than this, set it and we're done... */ - if (new_brk < brk_page) { + /* If the new brk is less than the highest page reserved to the + * target heap allocation, set it and we're almost done... */ + if (new_brk <= brk_page) { + /* Heap contents are initialized to zero, as for anonymous + * mapped pages. */ + if (new_brk > target_brk) { + memset(g2h(target_brk), 0, new_brk - target_brk); + } target_brk = new_brk; + DEBUGF_BRK("%#010x (new_brk <= brk_page)\n", target_brk); return target_brk; } - /* We need to allocate more memory after the brk... */ - new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); + /* We need to allocate more memory after the brk... Note that + * we don't use MAP_FIXED because that will map over the top of + * any existing mapping (like the one with the host libc or qemu + * itself); instead we treat "mapped but at wrong address" as + * a failure and unmap again. + */ + new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page); mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); + MAP_ANON|MAP_PRIVATE, 0, 0)); + + if (mapped_addr == brk_page) { + /* Heap contents are initialized to zero, as for anonymous + * mapped pages. Technically the new pages are already + * initialized to zero since they *are* anonymous mapped + * pages, however we have to take care with the contents that + * come from the remaining part of the previous page: it may + * contains garbage data due to a previous heap usage (grown + * then shrunken). */ + memset(g2h(target_brk), 0, brk_page - target_brk); + + target_brk = new_brk; + brk_page = HOST_PAGE_ALIGN(target_brk); + DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk); + return target_brk; + } else if (mapped_addr != -1) { + /* Mapped but at wrong address, meaning there wasn't actually + * enough space for this brk. + */ + target_munmap(mapped_addr, new_alloc_size); + mapped_addr = -1; + DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk); + } + else { + DEBUGF_BRK("%#010x (otherwise)\n", target_brk); + } #if defined(TARGET_ALPHA) /* We (partially) emulate OSF/1 on Alpha, which requires we return a proper errno, not an unchanged brk value. */ - if (is_error(mapped_addr)) { - return -TARGET_ENOMEM; - } + return -TARGET_ENOMEM; #endif - - if (!is_error(mapped_addr)) { - target_brk = new_brk; - } + /* For everything else, return the previous break. */ return target_brk; } @@ -767,6 +855,20 @@ static inline abi_long copy_from_user_fdset(fd_set *fds, return 0; } +static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr, + abi_ulong target_fds_addr, + int n) +{ + if (target_fds_addr) { + if (copy_from_user_fdset(fds, target_fds_addr, n)) + return -TARGET_EFAULT; + *fds_ptr = fds; + } else { + *fds_ptr = NULL; + } + return 0; +} + static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds, int n) @@ -819,43 +921,95 @@ static inline abi_long host_to_target_rusage(abi_ulong target_addr, if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) return -TARGET_EFAULT; - target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); - target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); - target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); - target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec); - target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss); - target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss); - target_rusage->ru_idrss = tswapl(rusage->ru_idrss); - target_rusage->ru_isrss = tswapl(rusage->ru_isrss); - target_rusage->ru_minflt = tswapl(rusage->ru_minflt); - target_rusage->ru_majflt = tswapl(rusage->ru_majflt); - target_rusage->ru_nswap = tswapl(rusage->ru_nswap); - target_rusage->ru_inblock = tswapl(rusage->ru_inblock); - target_rusage->ru_oublock = tswapl(rusage->ru_oublock); - target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd); - target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv); - target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals); - target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); - target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); + target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec); + target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec); + target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec); + target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec); + target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss); + target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss); + target_rusage->ru_idrss = tswapal(rusage->ru_idrss); + target_rusage->ru_isrss = tswapal(rusage->ru_isrss); + target_rusage->ru_minflt = tswapal(rusage->ru_minflt); + target_rusage->ru_majflt = tswapal(rusage->ru_majflt); + target_rusage->ru_nswap = tswapal(rusage->ru_nswap); + target_rusage->ru_inblock = tswapal(rusage->ru_inblock); + target_rusage->ru_oublock = tswapal(rusage->ru_oublock); + target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd); + target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv); + target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals); + target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw); + target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw); unlock_user_struct(target_rusage, target_addr, 1); return 0; } -static inline rlim_t target_to_host_rlim(target_ulong target_rlim) +static inline rlim_t target_to_host_rlim(abi_ulong target_rlim) { - if (target_rlim == TARGET_RLIM_INFINITY) + abi_ulong target_rlim_swap; + rlim_t result; + + target_rlim_swap = tswapal(target_rlim); + if (target_rlim_swap == TARGET_RLIM_INFINITY) return RLIM_INFINITY; - else - return tswapl(target_rlim); + + result = target_rlim_swap; + if (target_rlim_swap != (rlim_t)result) + return RLIM_INFINITY; + + return result; } -static inline target_ulong host_to_target_rlim(rlim_t rlim) +static inline abi_ulong host_to_target_rlim(rlim_t rlim) { - if (rlim == RLIM_INFINITY || rlim != (target_long)rlim) - return TARGET_RLIM_INFINITY; + abi_ulong target_rlim_swap; + abi_ulong result; + + if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim) + target_rlim_swap = TARGET_RLIM_INFINITY; else - return tswapl(rlim); + target_rlim_swap = rlim; + result = tswapal(target_rlim_swap); + + return result; +} + +static inline int target_to_host_resource(int code) +{ + switch (code) { + case TARGET_RLIMIT_AS: + return RLIMIT_AS; + case TARGET_RLIMIT_CORE: + return RLIMIT_CORE; + case TARGET_RLIMIT_CPU: + return RLIMIT_CPU; + case TARGET_RLIMIT_DATA: + return RLIMIT_DATA; + case TARGET_RLIMIT_FSIZE: + return RLIMIT_FSIZE; + case TARGET_RLIMIT_LOCKS: + return RLIMIT_LOCKS; + case TARGET_RLIMIT_MEMLOCK: + return RLIMIT_MEMLOCK; + case TARGET_RLIMIT_MSGQUEUE: + return RLIMIT_MSGQUEUE; + case TARGET_RLIMIT_NICE: + return RLIMIT_NICE; + case TARGET_RLIMIT_NOFILE: + return RLIMIT_NOFILE; + case TARGET_RLIMIT_NPROC: + return RLIMIT_NPROC; + case TARGET_RLIMIT_RSS: + return RLIMIT_RSS; + case TARGET_RLIMIT_RTPRIO: + return RLIMIT_RTPRIO; + case TARGET_RLIMIT_SIGPENDING: + return RLIMIT_SIGPENDING; + case TARGET_RLIMIT_STACK: + return RLIMIT_STACK; + default: + return code; + } } static inline abi_long copy_from_user_timeval(struct timeval *tv, @@ -932,6 +1086,7 @@ static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr, } #endif +#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) /* do_select() must return target values and target errnos. */ static abi_long do_select(int n, abi_ulong rfd_addr, abi_ulong wfd_addr, @@ -942,26 +1097,17 @@ static abi_long do_select(int n, struct timeval tv, *tv_ptr; abi_long ret; - if (rfd_addr) { - if (copy_from_user_fdset(&rfds, rfd_addr, n)) - return -TARGET_EFAULT; - rfds_ptr = &rfds; - } else { - rfds_ptr = NULL; + ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); + if (ret) { + return ret; } - if (wfd_addr) { - if (copy_from_user_fdset(&wfds, wfd_addr, n)) - return -TARGET_EFAULT; - wfds_ptr = &wfds; - } else { - wfds_ptr = NULL; + ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); + if (ret) { + return ret; } - if (efd_addr) { - if (copy_from_user_fdset(&efds, efd_addr, n)) - return -TARGET_EFAULT; - efds_ptr = &efds; - } else { - efds_ptr = NULL; + ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); + if (ret) { + return ret; } if (target_tv_addr) { @@ -988,6 +1134,7 @@ static abi_long do_select(int n, return ret; } +#endif static abi_long do_pipe2(int host_pipe[], int flags) { @@ -1041,7 +1188,7 @@ static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr; mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr; if (len == sizeof(struct target_ip_mreqn)) - mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex); + mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex); unlock_user(target_smreqn, target_addr, 0); return 0; @@ -1113,10 +1260,10 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh, struct target_cmsghdr *target_cmsg; socklen_t space = 0; - msg_controllen = tswapl(target_msgh->msg_controllen); + msg_controllen = tswapal(target_msgh->msg_controllen); if (msg_controllen < sizeof (struct target_cmsghdr)) goto the_end; - target_cmsg_addr = tswapl(target_msgh->msg_control); + target_cmsg_addr = tswapal(target_msgh->msg_control); target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); if (!target_cmsg) return -TARGET_EFAULT; @@ -1125,7 +1272,7 @@ static inline abi_long target_to_host_cmsg(struct msghdr *msgh, void *data = CMSG_DATA(cmsg); void *target_data = TARGET_CMSG_DATA(target_cmsg); - int len = tswapl(target_cmsg->cmsg_len) + int len = tswapal(target_cmsg->cmsg_len) - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr)); space += CMSG_SPACE(len); @@ -1170,10 +1317,10 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, struct target_cmsghdr *target_cmsg; socklen_t space = 0; - msg_controllen = tswapl(target_msgh->msg_controllen); + msg_controllen = tswapal(target_msgh->msg_controllen); if (msg_controllen < sizeof (struct target_cmsghdr)) goto the_end; - target_cmsg_addr = tswapl(target_msgh->msg_control); + target_cmsg_addr = tswapal(target_msgh->msg_control); target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0); if (!target_cmsg) return -TARGET_EFAULT; @@ -1193,7 +1340,7 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level); target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type); - target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len)); + target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len)); if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); @@ -1212,7 +1359,7 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, } unlock_user(target_cmsg, target_cmsg_addr, space); the_end: - target_msgh->msg_controllen = tswapl(space); + target_msgh->msg_controllen = tswapal(space); return 0; } @@ -1361,7 +1508,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, break; default: unimplemented: - gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname); + gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname); ret = -TARGET_ENOPROTOOPT; } return ret; @@ -1448,7 +1595,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, return -TARGET_EFAULT; if (len < 0) return -TARGET_EINVAL; - lv = sizeof(int); + lv = sizeof(lv); ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); if (ret < 0) return ret; @@ -1485,7 +1632,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, return -TARGET_EFAULT; if (len < 0) return -TARGET_EINVAL; - lv = sizeof(int); + lv = sizeof(lv); ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); if (ret < 0) return ret; @@ -1532,8 +1679,8 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, if (!target_vec) return -TARGET_EFAULT; for(i = 0;i < count; i++) { - base = tswapl(target_vec[i].iov_base); - vec[i].iov_len = tswapl(target_vec[i].iov_len); + base = tswapal(target_vec[i].iov_base); + vec[i].iov_len = tswapal(target_vec[i].iov_len); if (vec[i].iov_len != 0) { vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); /* Don't check lock_user return value. We must call writev even @@ -1559,7 +1706,7 @@ static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, return -TARGET_EFAULT; for(i = 0;i < count; i++) { if (target_vec[i].iov_base) { - base = tswapl(target_vec[i].iov_base); + base = tswapal(target_vec[i].iov_base); unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); } } @@ -1658,7 +1805,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, if (msgp->msg_name) { msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_name = alloca(msg.msg_namelen); - ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), + ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name), msg.msg_namelen); if (ret) { unlock_user_struct(msgp, target_msg, send ? 0 : 1); @@ -1668,13 +1815,13 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, msg.msg_name = NULL; msg.msg_namelen = 0; } - msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); + msg.msg_controllen = 2 * tswapal(msgp->msg_controllen); msg.msg_control = alloca(msg.msg_controllen); msg.msg_flags = tswap32(msgp->msg_flags); - count = tswapl(msgp->msg_iovlen); + count = tswapal(msgp->msg_iovlen); vec = alloca(count * sizeof(struct iovec)); - target_vec = tswapl(msgp->msg_iov); + target_vec = tswapal(msgp->msg_iov); lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send); msg.msg_iovlen = count; msg.msg_iov = vec; @@ -1860,7 +2007,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen)); } else { addr = NULL; /* To keep compiler quiet. */ - ret = get_errno(recv(fd, host_msg, len, flags)); + ret = get_errno(qemu_recv(fd, host_msg, len, flags)); } if (!is_error(ret)) { if (target_addr) { @@ -2177,12 +2324,12 @@ static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip, if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) return -TARGET_EFAULT; target_ip = &(target_sd->sem_perm); - host_ip->__key = tswapl(target_ip->__key); - host_ip->uid = tswapl(target_ip->uid); - host_ip->gid = tswapl(target_ip->gid); - host_ip->cuid = tswapl(target_ip->cuid); - host_ip->cgid = tswapl(target_ip->cgid); - host_ip->mode = tswapl(target_ip->mode); + host_ip->__key = tswapal(target_ip->__key); + host_ip->uid = tswapal(target_ip->uid); + host_ip->gid = tswapal(target_ip->gid); + host_ip->cuid = tswapal(target_ip->cuid); + host_ip->cgid = tswapal(target_ip->cgid); + host_ip->mode = tswap16(target_ip->mode); unlock_user_struct(target_sd, target_addr, 0); return 0; } @@ -2196,12 +2343,12 @@ static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr, if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) return -TARGET_EFAULT; target_ip = &(target_sd->sem_perm); - target_ip->__key = tswapl(host_ip->__key); - target_ip->uid = tswapl(host_ip->uid); - target_ip->gid = tswapl(host_ip->gid); - target_ip->cuid = tswapl(host_ip->cuid); - target_ip->cgid = tswapl(host_ip->cgid); - target_ip->mode = tswapl(host_ip->mode); + target_ip->__key = tswapal(host_ip->__key); + target_ip->uid = tswapal(host_ip->uid); + target_ip->gid = tswapal(host_ip->gid); + target_ip->cuid = tswapal(host_ip->cuid); + target_ip->cgid = tswapal(host_ip->cgid); + target_ip->mode = tswap16(host_ip->mode); unlock_user_struct(target_sd, target_addr, 1); return 0; } @@ -2215,9 +2362,9 @@ static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd, return -TARGET_EFAULT; if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr)) return -TARGET_EFAULT; - host_sd->sem_nsems = tswapl(target_sd->sem_nsems); - host_sd->sem_otime = tswapl(target_sd->sem_otime); - host_sd->sem_ctime = tswapl(target_sd->sem_ctime); + host_sd->sem_nsems = tswapal(target_sd->sem_nsems); + host_sd->sem_otime = tswapal(target_sd->sem_otime); + host_sd->sem_ctime = tswapal(target_sd->sem_ctime); unlock_user_struct(target_sd, target_addr, 0); return 0; } @@ -2231,9 +2378,9 @@ static inline abi_long host_to_target_semid_ds(abi_ulong target_addr, return -TARGET_EFAULT; if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm))) return -TARGET_EFAULT;; - target_sd->sem_nsems = tswapl(host_sd->sem_nsems); - target_sd->sem_otime = tswapl(host_sd->sem_otime); - target_sd->sem_ctime = tswapl(host_sd->sem_ctime); + target_sd->sem_nsems = tswapal(host_sd->sem_nsems); + target_sd->sem_otime = tswapal(host_sd->sem_otime); + target_sd->sem_ctime = tswapal(host_sd->sem_ctime); unlock_user_struct(target_sd, target_addr, 1); return 0; } @@ -2361,9 +2508,9 @@ static inline abi_long do_semctl(int semid, int semnum, int cmd, switch( cmd ) { case GETVAL: case SETVAL: - arg.val = tswapl(target_su.val); + arg.val = tswap32(target_su.val); ret = get_errno(semctl(semid, semnum, cmd, arg)); - target_su.val = tswapl(arg.val); + target_su.val = tswap32(arg.val); break; case GETALL: case SETALL: @@ -2479,14 +2626,14 @@ static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md, return -TARGET_EFAULT; if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr)) return -TARGET_EFAULT; - host_md->msg_stime = tswapl(target_md->msg_stime); - host_md->msg_rtime = tswapl(target_md->msg_rtime); - host_md->msg_ctime = tswapl(target_md->msg_ctime); - host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes); - host_md->msg_qnum = tswapl(target_md->msg_qnum); - host_md->msg_qbytes = tswapl(target_md->msg_qbytes); - host_md->msg_lspid = tswapl(target_md->msg_lspid); - host_md->msg_lrpid = tswapl(target_md->msg_lrpid); + host_md->msg_stime = tswapal(target_md->msg_stime); + host_md->msg_rtime = tswapal(target_md->msg_rtime); + host_md->msg_ctime = tswapal(target_md->msg_ctime); + host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes); + host_md->msg_qnum = tswapal(target_md->msg_qnum); + host_md->msg_qbytes = tswapal(target_md->msg_qbytes); + host_md->msg_lspid = tswapal(target_md->msg_lspid); + host_md->msg_lrpid = tswapal(target_md->msg_lrpid); unlock_user_struct(target_md, target_addr, 0); return 0; } @@ -2500,14 +2647,14 @@ static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr, return -TARGET_EFAULT; if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm))) return -TARGET_EFAULT; - target_md->msg_stime = tswapl(host_md->msg_stime); - target_md->msg_rtime = tswapl(host_md->msg_rtime); - target_md->msg_ctime = tswapl(host_md->msg_ctime); - target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes); - target_md->msg_qnum = tswapl(host_md->msg_qnum); - target_md->msg_qbytes = tswapl(host_md->msg_qbytes); - target_md->msg_lspid = tswapl(host_md->msg_lspid); - target_md->msg_lrpid = tswapl(host_md->msg_lrpid); + target_md->msg_stime = tswapal(host_md->msg_stime); + target_md->msg_rtime = tswapal(host_md->msg_rtime); + target_md->msg_ctime = tswapal(host_md->msg_ctime); + target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes); + target_md->msg_qnum = tswapal(host_md->msg_qnum); + target_md->msg_qbytes = tswapal(host_md->msg_qbytes); + target_md->msg_lspid = tswapal(host_md->msg_lspid); + target_md->msg_lrpid = tswapal(host_md->msg_lrpid); unlock_user_struct(target_md, target_addr, 1); return 0; } @@ -2588,7 +2735,7 @@ static inline abi_long do_msgsnd(int msqid, abi_long msgp, if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) return -TARGET_EFAULT; host_mb = malloc(msgsz+sizeof(long)); - host_mb->mtype = (abi_long) tswapl(target_mb->mtype); + host_mb->mtype = (abi_long) tswapal(target_mb->mtype); memcpy(host_mb->mtext, target_mb->mtext, msgsz); ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg)); free(host_mb); @@ -2610,7 +2757,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, return -TARGET_EFAULT; host_mb = malloc(msgsz+sizeof(long)); - ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg)); + ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg)); if (ret > 0) { abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); @@ -2623,7 +2770,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp, unlock_user(target_mtext, target_mtext_addr, ret); } - target_mb->mtype = tswapl(host_mb->mtype); + target_mb->mtype = tswapal(host_mb->mtype); free(host_mb); end: @@ -2952,7 +3099,6 @@ static abi_long do_ipc(unsigned int call, int first, #endif /* kernel structure types definitions */ -#define IFNAMSIZ 16 #define STRUCT(name, ...) STRUCT_ ## name, #define STRUCT_SPECIAL(name) STRUCT_ ## name, @@ -3077,6 +3223,100 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp, } #endif +static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, + int fd, abi_long cmd, abi_long arg) +{ + const argtype *arg_type = ie->arg_type; + int target_size; + void *argptr; + int ret; + struct ifconf *host_ifconf; + uint32_t outbufsz; + const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) }; + int target_ifreq_size; + int nb_ifreq; + int free_buf = 0; + int i; + int target_ifc_len; + abi_long target_ifc_buf; + int host_ifc_len; + char *host_ifc_buf; + + assert(arg_type[0] == TYPE_PTR); + assert(ie->access == IOC_RW); + + arg_type++; + target_size = thunk_type_size(arg_type, 0); + + argptr = lock_user(VERIFY_READ, arg, target_size, 1); + if (!argptr) + return -TARGET_EFAULT; + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); + unlock_user(argptr, arg, 0); + + host_ifconf = (struct ifconf *)(unsigned long)buf_temp; + target_ifc_len = host_ifconf->ifc_len; + target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf; + + target_ifreq_size = thunk_type_size(ifreq_arg_type, 0); + nb_ifreq = target_ifc_len / target_ifreq_size; + host_ifc_len = nb_ifreq * sizeof(struct ifreq); + + outbufsz = sizeof(*host_ifconf) + host_ifc_len; + if (outbufsz > MAX_STRUCT_SIZE) { + /* We can't fit all the extents into the fixed size buffer. + * Allocate one that is large enough and use it instead. + */ + host_ifconf = malloc(outbufsz); + if (!host_ifconf) { + return -TARGET_ENOMEM; + } + memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf)); + free_buf = 1; + } + host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf); + + host_ifconf->ifc_len = host_ifc_len; + host_ifconf->ifc_buf = host_ifc_buf; + + ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf)); + if (!is_error(ret)) { + /* convert host ifc_len to target ifc_len */ + + nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq); + target_ifc_len = nb_ifreq * target_ifreq_size; + host_ifconf->ifc_len = target_ifc_len; + + /* restore target ifc_buf */ + + host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf; + + /* copy struct ifconf to target user */ + + argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); + if (!argptr) + return -TARGET_EFAULT; + thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET); + unlock_user(argptr, arg, target_size); + + /* copy ifreq[] to target user */ + + argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0); + for (i = 0; i < nb_ifreq ; i++) { + thunk_convert(argptr + i * target_ifreq_size, + host_ifc_buf + i * sizeof(struct ifreq), + ifreq_arg_type, THUNK_TARGET); + } + unlock_user(argptr, target_ifc_buf, target_ifc_len); + } + + if (free_buf) { + free(host_ifconf); + } + + return ret; +} + static IOCTLEntry ioctl_entries[] = { #define IOCTL(cmd, access, ...) \ { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, @@ -3401,7 +3641,7 @@ static abi_long write_ldt(CPUX86State *env, if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1)) return -TARGET_EFAULT; ldt_info.entry_number = tswap32(target_ldt_info->entry_number); - ldt_info.base_addr = tswapl(target_ldt_info->base_addr); + ldt_info.base_addr = tswapal(target_ldt_info->base_addr); ldt_info.limit = tswap32(target_ldt_info->limit); ldt_info.flags = tswap32(target_ldt_info->flags); unlock_user_struct(target_ldt_info, ptr, 0); @@ -3516,7 +3756,7 @@ static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr) if (!target_ldt_info) return -TARGET_EFAULT; ldt_info.entry_number = tswap32(target_ldt_info->entry_number); - ldt_info.base_addr = tswapl(target_ldt_info->base_addr); + ldt_info.base_addr = tswapal(target_ldt_info->base_addr); ldt_info.limit = tswap32(target_ldt_info->limit); ldt_info.flags = tswap32(target_ldt_info->flags); if (ldt_info.entry_number == -1) { @@ -3627,7 +3867,7 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) base_addr = (entry_1 >> 16) | (entry_2 & 0xff000000) | ((entry_2 & 0xff) << 16); - target_ldt_info->base_addr = tswapl(base_addr); + target_ldt_info->base_addr = tswapal(base_addr); target_ldt_info->limit = tswap32(limit); target_ldt_info->flags = tswap32(flags); unlock_user_struct(target_ldt_info, ptr, 1); @@ -3638,10 +3878,10 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) #ifndef TARGET_ABI32 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr) { - abi_long ret; + abi_long ret = 0; abi_ulong val; int idx; - + switch(code) { case TARGET_ARCH_SET_GS: case TARGET_ARCH_SET_FS: @@ -3660,21 +3900,21 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr) idx = R_FS; val = env->segs[idx].base; if (put_user(val, addr, abi_ulong)) - return -TARGET_EFAULT; + ret = -TARGET_EFAULT; break; default: ret = -TARGET_EINVAL; break; } - return 0; + return ret; } #endif #endif /* defined(TARGET_I386) */ -#if defined(CONFIG_USE_NPTL) +#define NEW_STACK_SIZE 0x40000 -#define NEW_STACK_SIZE PTHREAD_STACK_MIN +#if defined(CONFIG_USE_NPTL) static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER; typedef struct { @@ -3718,9 +3958,6 @@ static void *clone_func(void *arg) return NULL; } #else -/* this stack is the equivalent of the kernel stack associated with a - thread/process */ -#define NEW_STACK_SIZE 8192 static int clone_func(void *arg) { @@ -3757,7 +3994,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, new_thread_info info; pthread_attr_t attr; #endif - ts = qemu_mallocz(sizeof(TaskState)); + ts = g_malloc0(sizeof(TaskState)); init_task_state(ts); /* we create a new CPU instance. */ new_env = cpu_copy(env); @@ -3823,7 +4060,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, if (flags & CLONE_NPTL_FLAGS2) return -EINVAL; /* This is probably going to die very quickly, but do it anyway. */ - new_stack = qemu_mallocz (NEW_STACK_SIZE); + new_stack = g_malloc0 (NEW_STACK_SIZE); #ifdef __ia64__ ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env); #else @@ -3930,8 +4167,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) return -TARGET_EFAULT; fl.l_type = tswap16(target_fl->l_type); fl.l_whence = tswap16(target_fl->l_whence); - fl.l_start = tswapl(target_fl->l_start); - fl.l_len = tswapl(target_fl->l_len); + fl.l_start = tswapal(target_fl->l_start); + fl.l_len = tswapal(target_fl->l_len); fl.l_pid = tswap32(target_fl->l_pid); unlock_user_struct(target_fl, arg, 0); ret = get_errno(fcntl(fd, host_cmd, &fl)); @@ -3940,8 +4177,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) return -TARGET_EFAULT; target_fl->l_type = tswap16(fl.l_type); target_fl->l_whence = tswap16(fl.l_whence); - target_fl->l_start = tswapl(fl.l_start); - target_fl->l_len = tswapl(fl.l_len); + target_fl->l_start = tswapal(fl.l_start); + target_fl->l_len = tswapal(fl.l_len); target_fl->l_pid = tswap32(fl.l_pid); unlock_user_struct(target_fl, arg, 1); } @@ -3953,8 +4190,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) return -TARGET_EFAULT; fl.l_type = tswap16(target_fl->l_type); fl.l_whence = tswap16(target_fl->l_whence); - fl.l_start = tswapl(target_fl->l_start); - fl.l_len = tswapl(target_fl->l_len); + fl.l_start = tswapal(target_fl->l_start); + fl.l_len = tswapal(target_fl->l_len); fl.l_pid = tswap32(target_fl->l_pid); unlock_user_struct(target_fl, arg, 0); ret = get_errno(fcntl(fd, host_cmd, &fl)); @@ -3965,8 +4202,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) return -TARGET_EFAULT; fl64.l_type = tswap16(target_fl64->l_type) >> 1; fl64.l_whence = tswap16(target_fl64->l_whence); - fl64.l_start = tswapl(target_fl64->l_start); - fl64.l_len = tswapl(target_fl64->l_len); + fl64.l_start = tswap64(target_fl64->l_start); + fl64.l_len = tswap64(target_fl64->l_len); fl64.l_pid = tswap32(target_fl64->l_pid); unlock_user_struct(target_fl64, arg, 0); ret = get_errno(fcntl(fd, host_cmd, &fl64)); @@ -3975,8 +4212,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) return -TARGET_EFAULT; target_fl64->l_type = tswap16(fl64.l_type) >> 1; target_fl64->l_whence = tswap16(fl64.l_whence); - target_fl64->l_start = tswapl(fl64.l_start); - target_fl64->l_len = tswapl(fl64.l_len); + target_fl64->l_start = tswap64(fl64.l_start); + target_fl64->l_len = tswap64(fl64.l_len); target_fl64->l_pid = tswap32(fl64.l_pid); unlock_user_struct(target_fl64, arg, 1); } @@ -3987,8 +4224,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) return -TARGET_EFAULT; fl64.l_type = tswap16(target_fl64->l_type) >> 1; fl64.l_whence = tswap16(target_fl64->l_whence); - fl64.l_start = tswapl(target_fl64->l_start); - fl64.l_len = tswapl(target_fl64->l_len); + fl64.l_start = tswap64(target_fl64->l_start); + fl64.l_len = tswap64(target_fl64->l_len); fl64.l_pid = tswap32(target_fl64->l_pid); unlock_user_struct(target_fl64, arg, 0); ret = get_errno(fcntl(fd, host_cmd, &fl64)); @@ -4054,7 +4291,31 @@ static inline int low2highgid(int gid) else return gid; } - +static inline int tswapid(int id) +{ + return tswap16(id); +} +#else /* !USE_UID16 */ +static inline int high2lowuid(int uid) +{ + return uid; +} +static inline int high2lowgid(int gid) +{ + return gid; +} +static inline int low2highuid(int uid) +{ + return uid; +} +static inline int low2highgid(int gid) +{ + return gid; +} +static inline int tswapid(int id) +{ + return tswap32(id); +} #endif /* USE_UID16 */ void syscall_init(void) @@ -4128,13 +4389,10 @@ static inline abi_long target_truncate64(void *cpu_env, const char *arg1, abi_long arg3, abi_long arg4) { -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) - { + if (regpairs_aligned(cpu_env)) { arg2 = arg3; arg3 = arg4; - } -#endif + } return get_errno(truncate64(arg1, target_offset64(arg2, arg3))); } #endif @@ -4145,13 +4403,10 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1, abi_long arg3, abi_long arg4) { -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) - { + if (regpairs_aligned(cpu_env)) { arg2 = arg3; arg3 = arg4; - } -#endif + } return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3))); } #endif @@ -4163,8 +4418,8 @@ static inline abi_long target_to_host_timespec(struct timespec *host_ts, if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) return -TARGET_EFAULT; - host_ts->tv_sec = tswapl(target_ts->tv_sec); - host_ts->tv_nsec = tswapl(target_ts->tv_nsec); + host_ts->tv_sec = tswapal(target_ts->tv_sec); + host_ts->tv_nsec = tswapal(target_ts->tv_nsec); unlock_user_struct(target_ts, target_addr, 0); return 0; } @@ -4176,8 +4431,8 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr, if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) return -TARGET_EFAULT; - target_ts->tv_sec = tswapl(host_ts->tv_sec); - target_ts->tv_nsec = tswapl(host_ts->tv_nsec); + target_ts->tv_sec = tswapal(host_ts->tv_sec); + target_ts->tv_nsec = tswapal(host_ts->tv_nsec); unlock_user_struct(target_ts, target_addr, 1); return 0; } @@ -4350,7 +4605,8 @@ int get_osversion(void) All errnos that do_syscall() returns must be -TARGET_. */ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, - abi_long arg5, abi_long arg6) + abi_long arg5, abi_long arg6, abi_long arg7, + abi_long arg8) { abi_long ret; struct stat st; @@ -4398,8 +4654,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, NULL, NULL, 0); } thread_env = NULL; - qemu_free(cpu_env); - qemu_free(ts); + g_free(cpu_env); + g_free(ts); pthread_exit(NULL); } #endif @@ -4740,8 +4996,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (arg2) { if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1)) goto efault; - tbuf.actime = tswapl(target_tbuf->actime); - tbuf.modtime = tswapl(target_tbuf->modtime); + tbuf.actime = tswapal(target_tbuf->actime); + tbuf.modtime = tswapal(target_tbuf->modtime); unlock_user_struct(target_tbuf, arg2, 0); host_tbuf = &tbuf; } else { @@ -4898,10 +5154,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0); if (!tmsp) goto efault; - tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); - tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); - tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); - tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime)); + tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime)); + tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime)); + tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime)); + tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime)); } if (!is_error(ret)) ret = host_to_target_clock_t(ret); @@ -5360,7 +5616,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; case TARGET_NR_setrlimit: { - int resource = arg1; + int resource = target_to_host_resource(arg1); struct target_rlimit *target_rlim; struct rlimit rlim; if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) @@ -5373,7 +5629,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; case TARGET_NR_getrlimit: { - int resource = arg1; + int resource = target_to_host_resource(arg1); struct target_rlimit *target_rlim; struct rlimit rlim; @@ -5414,7 +5670,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(settimeofday(&tv, NULL)); } break; -#ifdef TARGET_NR_select +#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390) case TARGET_NR_select: { struct target_sel_arg_struct *sel; @@ -5423,11 +5679,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) goto efault; - nsel = tswapl(sel->n); - inp = tswapl(sel->inp); - outp = tswapl(sel->outp); - exp = tswapl(sel->exp); - tvp = tswapl(sel->tvp); + nsel = tswapal(sel->n); + inp = tswapal(sel->inp); + outp = tswapal(sel->outp); + exp = tswapal(sel->exp); + tvp = tswapal(sel->tvp); unlock_user_struct(sel, arg1, 0); ret = do_select(nsel, inp, outp, exp, tvp); } @@ -5435,7 +5691,107 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_pselect6 case TARGET_NR_pselect6: - goto unimplemented_nowarn; + { + abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr; + fd_set rfds, wfds, efds; + fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; + struct timespec ts, *ts_ptr; + + /* + * The 6th arg is actually two args smashed together, + * so we cannot use the C library. + */ + sigset_t set; + struct { + sigset_t *set; + size_t size; + } sig, *sig_ptr; + + abi_ulong arg_sigset, arg_sigsize, *arg7; + target_sigset_t *target_sigset; + + n = arg1; + rfd_addr = arg2; + wfd_addr = arg3; + efd_addr = arg4; + ts_addr = arg5; + + ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); + if (ret) { + goto fail; + } + ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); + if (ret) { + goto fail; + } + ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); + if (ret) { + goto fail; + } + + /* + * This takes a timespec, and not a timeval, so we cannot + * use the do_select() helper ... + */ + if (ts_addr) { + if (target_to_host_timespec(&ts, ts_addr)) { + goto efault; + } + ts_ptr = &ts; + } else { + ts_ptr = NULL; + } + + /* Extract the two packed args for the sigset */ + if (arg6) { + sig_ptr = &sig; + sig.size = _NSIG / 8; + + arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1); + if (!arg7) { + goto efault; + } + arg_sigset = tswapal(arg7[0]); + arg_sigsize = tswapal(arg7[1]); + unlock_user(arg7, arg6, 0); + + if (arg_sigset) { + sig.set = &set; + if (arg_sigsize != sizeof(*target_sigset)) { + /* Like the kernel, we enforce correct size sigsets */ + ret = -TARGET_EINVAL; + goto fail; + } + target_sigset = lock_user(VERIFY_READ, arg_sigset, + sizeof(*target_sigset), 1); + if (!target_sigset) { + goto efault; + } + target_to_host_sigset(&set, target_sigset); + unlock_user(target_sigset, arg_sigset, 0); + } else { + sig.set = NULL; + } + } else { + sig_ptr = NULL; + } + + ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr, + ts_ptr, sig_ptr)); + + if (!is_error(ret)) { + if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) + goto efault; + if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) + goto efault; + if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) + goto efault; + + if (ts_addr && host_to_target_timespec(ts_addr, &ts)) + goto efault; + } + } + break; #endif case TARGET_NR_symlink: { @@ -5518,25 +5874,31 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif case TARGET_NR_reboot: - goto unimplemented; + if (!(p = lock_user_string(arg4))) + goto efault; + ret = reboot(arg1, arg2, arg3, p); + unlock_user(p, arg4, 0); + break; #ifdef TARGET_NR_readdir case TARGET_NR_readdir: goto unimplemented; #endif #ifdef TARGET_NR_mmap case TARGET_NR_mmap: -#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) +#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \ + defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \ + || defined(TARGET_S390X) { abi_ulong *v; abi_ulong v1, v2, v3, v4, v5, v6; if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1))) goto efault; - v1 = tswapl(v[0]); - v2 = tswapl(v[1]); - v3 = tswapl(v[2]); - v4 = tswapl(v[3]); - v5 = tswapl(v[4]); - v6 = tswapl(v[5]); + v1 = tswapal(v[0]); + v2 = tswapal(v[1]); + v3 = tswapal(v[2]); + v4 = tswapal(v[3]); + v5 = tswapal(v[4]); + v6 = tswapal(v[5]); unlock_user(v, arg1, 0); ret = get_errno(target_mmap(v1, v2, v3, target_to_host_bitmask(v4, mmap_flags_tbl), @@ -5893,8 +6255,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_syscall case TARGET_NR_syscall: - ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0); - break; + ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, 0); + break; #endif case TARGET_NR_wait4: { @@ -6021,6 +6384,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4)); #elif defined(TARGET_CRIS) ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5)); +#elif defined(TARGET_S390X) + ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4)); #else ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5)); #endif @@ -6109,16 +6474,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR__llseek /* Not on alpha */ case TARGET_NR__llseek: { + int64_t res; #if !defined(__NR_llseek) - ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5)); - if (put_user_s64(ret, arg4)) - goto efault; + res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5); + if (res == -1) { + ret = get_errno(res); + } else { + ret = 0; + } #else - int64_t res; ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); - if (put_user_s64(res, arg4)) - goto efault; #endif + if ((ret == 0) && put_user_s64(res, arg4)) { + goto efault; + } } break; #endif @@ -6152,8 +6521,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, reclen = de->d_reclen; treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long))); tde->d_reclen = tswap16(treclen); - tde->d_ino = tswapl(de->d_ino); - tde->d_off = tswapl(de->d_off); + tde->d_ino = tswapal(de->d_ino); + tde->d_off = tswapal(de->d_off); tnamelen = treclen - (2 * sizeof(abi_long) + 2); if (tnamelen > 256) tnamelen = 256; @@ -6225,13 +6594,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; #endif /* TARGET_NR_getdents64 */ -#ifdef TARGET_NR__newselect +#if defined(TARGET_NR__newselect) || defined(TARGET_S390X) +#ifdef TARGET_S390X + case TARGET_NR_select: +#else case TARGET_NR__newselect: +#endif ret = do_select(arg1, arg2, arg3, arg4, arg5); break; #endif -#ifdef TARGET_NR_poll +#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll) +# ifdef TARGET_NR_poll case TARGET_NR_poll: +# endif +# ifdef TARGET_NR_ppoll + case TARGET_NR_ppoll: +# endif { struct target_pollfd *target_pfd; unsigned int nfds = arg2; @@ -6242,20 +6620,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1); if (!target_pfd) goto efault; + pfd = alloca(sizeof(struct pollfd) * nfds); for(i = 0; i < nfds; i++) { pfd[i].fd = tswap32(target_pfd[i].fd); pfd[i].events = tswap16(target_pfd[i].events); } - ret = get_errno(poll(pfd, nfds, timeout)); + +# ifdef TARGET_NR_ppoll + if (num == TARGET_NR_ppoll) { + struct timespec _timeout_ts, *timeout_ts = &_timeout_ts; + target_sigset_t *target_set; + sigset_t _set, *set = &_set; + + if (arg3) { + if (target_to_host_timespec(timeout_ts, arg3)) { + unlock_user(target_pfd, arg1, 0); + goto efault; + } + } else { + timeout_ts = NULL; + } + + if (arg4) { + target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1); + if (!target_set) { + unlock_user(target_pfd, arg1, 0); + goto efault; + } + target_to_host_sigset(set, target_set); + } else { + set = NULL; + } + + ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8)); + + if (!is_error(ret) && arg3) { + host_to_target_timespec(arg3, timeout_ts); + } + if (arg4) { + unlock_user(target_set, arg4, 0); + } + } else +# endif + ret = get_errno(poll(pfd, nfds, timeout)); + if (!is_error(ret)) { for(i = 0; i < nfds; i++) { target_pfd[i].revents = tswap16(pfd[i].revents); } - ret += nfds * (sizeof(struct target_pollfd) - - sizeof(struct pollfd)); } - unlock_user(target_pfd, arg1, ret); + unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds); } break; #endif @@ -6301,6 +6716,56 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, return value. */ ret = -TARGET_ENOTDIR; break; + case TARGET_NR_sched_getaffinity: + { + unsigned int mask_size; + unsigned long *mask; + + /* + * sched_getaffinity needs multiples of ulong, so need to take + * care of mismatches between target ulong and host ulong sizes. + */ + if (arg2 & (sizeof(abi_ulong) - 1)) { + ret = -TARGET_EINVAL; + break; + } + mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1); + + mask = alloca(mask_size); + ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask)); + + if (!is_error(ret)) { + if (copy_to_user(arg3, mask, ret)) { + goto efault; + } + } + } + break; + case TARGET_NR_sched_setaffinity: + { + unsigned int mask_size; + unsigned long *mask; + + /* + * sched_setaffinity needs multiples of ulong, so need to take + * care of mismatches between target ulong and host ulong sizes. + */ + if (arg2 & (sizeof(abi_ulong) - 1)) { + ret = -TARGET_EINVAL; + break; + } + mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1); + + mask = alloca(mask_size); + if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) { + goto efault; + } + memcpy(mask, p, arg2); + unlock_user_struct(p, arg2, 0); + + ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask)); + } + break; case TARGET_NR_sched_setparam: { struct sched_param *target_schp; @@ -6404,20 +6869,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_pread case TARGET_NR_pread: -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) + if (regpairs_aligned(cpu_env)) arg4 = arg5; -#endif if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) goto efault; ret = get_errno(pread(arg1, p, arg3, arg4)); unlock_user(p, arg2, ret); break; case TARGET_NR_pwrite: -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) + if (regpairs_aligned(cpu_env)) arg4 = arg5; -#endif if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) goto efault; ret = get_errno(pwrite(arg1, p, arg3, arg4)); @@ -6451,7 +6912,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_sigaltstack: #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \ defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \ - defined(TARGET_M68K) + defined(TARGET_M68K) || defined(TARGET_S390X) ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env)); break; #else @@ -6477,7 +6938,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_ugetrlimit: { struct rlimit rlim; - ret = get_errno(getrlimit(arg1, &rlim)); + int resource = target_to_host_resource(arg1); + ret = get_errno(getrlimit(resource, &rlim)); if (!is_error(ret)) { struct target_rlimit *target_rlim; if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) @@ -6548,25 +7010,32 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = host_to_target_stat64(cpu_env, arg3, &st); break; #endif -#ifdef USE_UID16 case TARGET_NR_lchown: if (!(p = lock_user_string(arg1))) goto efault; ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3))); unlock_user(p, arg1, 0); break; +#ifdef TARGET_NR_getuid case TARGET_NR_getuid: ret = get_errno(high2lowuid(getuid())); break; +#endif +#ifdef TARGET_NR_getgid case TARGET_NR_getgid: ret = get_errno(high2lowgid(getgid())); break; +#endif +#ifdef TARGET_NR_geteuid case TARGET_NR_geteuid: ret = get_errno(high2lowuid(geteuid())); break; +#endif +#ifdef TARGET_NR_getegid case TARGET_NR_getegid: ret = get_errno(high2lowgid(getegid())); break; +#endif case TARGET_NR_setreuid: ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2))); break; @@ -6576,7 +7045,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_getgroups: { int gidsetsize = arg1; - uint16_t *target_grouplist; + target_id *target_grouplist; gid_t *grouplist; int i; @@ -6589,7 +7058,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, if (!target_grouplist) goto efault; for(i = 0;i < ret; i++) - target_grouplist[i] = tswap16(grouplist[i]); + target_grouplist[i] = tswapid(high2lowgid(grouplist[i])); unlock_user(target_grouplist, arg2, gidsetsize * 2); } } @@ -6597,7 +7066,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_setgroups: { int gidsetsize = arg1; - uint16_t *target_grouplist; + target_id *target_grouplist; gid_t *grouplist; int i; @@ -6608,7 +7077,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto fail; } for(i = 0;i < gidsetsize; i++) - grouplist[i] = tswap16(target_grouplist[i]); + grouplist[i] = low2highgid(tswapid(target_grouplist[i])); unlock_user(target_grouplist, arg2, 0); ret = get_errno(setgroups(gidsetsize, grouplist)); } @@ -6684,7 +7153,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_setfsgid: ret = get_errno(setfsgid(arg1)); break; -#endif /* USE_UID16 */ #ifdef TARGET_NR_lchown32 case TARGET_NR_lchown32: @@ -6814,7 +7282,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_osf_sigprocmask: { abi_ulong mask; - int how = arg1; + int how; sigset_t set, oldset; switch(arg1) { @@ -6833,7 +7301,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } mask = arg2; target_to_host_old_sigset(&set, &mask); - sigprocmask(arg1, &set, &oldset); + sigprocmask(how, &set, &oldset); host_to_target_old_sigset(&mask, &oldset); ret = mask; } @@ -7161,36 +7629,78 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_readahead case TARGET_NR_readahead: #if TARGET_ABI_BITS == 32 -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) - { + if (regpairs_aligned(cpu_env)) { arg2 = arg3; arg3 = arg4; arg4 = arg5; } -#endif ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4)); #else ret = get_errno(readahead(arg1, arg2, arg3)); #endif break; #endif +#ifdef CONFIG_ATTR #ifdef TARGET_NR_setxattr - case TARGET_NR_setxattr: case TARGET_NR_lsetxattr: case TARGET_NR_fsetxattr: - case TARGET_NR_getxattr: case TARGET_NR_lgetxattr: case TARGET_NR_fgetxattr: case TARGET_NR_listxattr: case TARGET_NR_llistxattr: case TARGET_NR_flistxattr: - case TARGET_NR_removexattr: case TARGET_NR_lremovexattr: case TARGET_NR_fremovexattr: ret = -TARGET_EOPNOTSUPP; break; + case TARGET_NR_setxattr: + { + void *p, *n, *v; + p = lock_user_string(arg1); + n = lock_user_string(arg2); + v = lock_user(VERIFY_READ, arg3, arg4, 1); + if (p && n && v) { + ret = get_errno(setxattr(p, n, v, arg4, arg5)); + } else { + ret = -TARGET_EFAULT; + } + unlock_user(p, arg1, 0); + unlock_user(n, arg2, 0); + unlock_user(v, arg3, 0); + } + break; + case TARGET_NR_getxattr: + { + void *p, *n, *v; + p = lock_user_string(arg1); + n = lock_user_string(arg2); + v = lock_user(VERIFY_WRITE, arg3, arg4, 0); + if (p && n && v) { + ret = get_errno(getxattr(p, n, v, arg4)); + } else { + ret = -TARGET_EFAULT; + } + unlock_user(p, arg1, 0); + unlock_user(n, arg2, 0); + unlock_user(v, arg3, arg4); + } + break; + case TARGET_NR_removexattr: + { + void *p, *n; + p = lock_user_string(arg1); + n = lock_user_string(arg2); + if (p && n) { + ret = get_errno(removexattr(p, n)); + } else { + ret = -TARGET_EFAULT; + } + unlock_user(p, arg1, 0); + unlock_user(n, arg2, 0); + } + break; #endif +#endif /* CONFIG_ATTR */ #ifdef TARGET_NR_set_thread_area case TARGET_NR_set_thread_area: #if defined(TARGET_MIPS) @@ -7473,8 +7983,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_sync_file_range) case TARGET_NR_sync_file_range: #if TARGET_ABI_BITS == 32 +#if defined(TARGET_MIPS) + ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4), + target_offset64(arg5, arg6), arg7)); +#else ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3), target_offset64(arg4, arg5), arg6)); +#endif /* !TARGET_MIPS */ #else ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4)); #endif @@ -7492,6 +8007,138 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; #endif #endif +#if defined(CONFIG_EPOLL) +#if defined(TARGET_NR_epoll_create) + case TARGET_NR_epoll_create: + ret = get_errno(epoll_create(arg1)); + break; +#endif +#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1) + case TARGET_NR_epoll_create1: + ret = get_errno(epoll_create1(arg1)); + break; +#endif +#if defined(TARGET_NR_epoll_ctl) + case TARGET_NR_epoll_ctl: + { + struct epoll_event ep; + struct epoll_event *epp = 0; + if (arg4) { + struct target_epoll_event *target_ep; + if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) { + goto efault; + } + ep.events = tswap32(target_ep->events); + /* The epoll_data_t union is just opaque data to the kernel, + * so we transfer all 64 bits across and need not worry what + * actual data type it is. + */ + ep.data.u64 = tswap64(target_ep->data.u64); + unlock_user_struct(target_ep, arg4, 0); + epp = &ep; + } + ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp)); + break; + } +#endif + +#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT) +#define IMPLEMENT_EPOLL_PWAIT +#endif +#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT) +#if defined(TARGET_NR_epoll_wait) + case TARGET_NR_epoll_wait: +#endif +#if defined(IMPLEMENT_EPOLL_PWAIT) + case TARGET_NR_epoll_pwait: +#endif + { + struct target_epoll_event *target_ep; + struct epoll_event *ep; + int epfd = arg1; + int maxevents = arg3; + int timeout = arg4; + + target_ep = lock_user(VERIFY_WRITE, arg2, + maxevents * sizeof(struct target_epoll_event), 1); + if (!target_ep) { + goto efault; + } + + ep = alloca(maxevents * sizeof(struct epoll_event)); + + switch (num) { +#if defined(IMPLEMENT_EPOLL_PWAIT) + case TARGET_NR_epoll_pwait: + { + target_sigset_t *target_set; + sigset_t _set, *set = &_set; + + if (arg5) { + target_set = lock_user(VERIFY_READ, arg5, + sizeof(target_sigset_t), 1); + if (!target_set) { + unlock_user(target_ep, arg2, 0); + goto efault; + } + target_to_host_sigset(set, target_set); + unlock_user(target_set, arg5, 0); + } else { + set = NULL; + } + + ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set)); + break; + } +#endif +#if defined(TARGET_NR_epoll_wait) + case TARGET_NR_epoll_wait: + ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout)); + break; +#endif + default: + ret = -TARGET_ENOSYS; + } + if (!is_error(ret)) { + int i; + for (i = 0; i < ret; i++) { + target_ep[i].events = tswap32(ep[i].events); + target_ep[i].data.u64 = tswap64(ep[i].data.u64); + } + } + unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event)); + break; + } +#endif +#endif +#ifdef TARGET_NR_prlimit64 + case TARGET_NR_prlimit64: + { + /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */ + struct target_rlimit64 *target_rnew, *target_rold; + struct host_rlimit64 rnew, rold, *rnewp = 0; + if (arg3) { + if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) { + goto efault; + } + rnew.rlim_cur = tswap64(target_rnew->rlim_cur); + rnew.rlim_max = tswap64(target_rnew->rlim_max); + unlock_user_struct(target_rnew, arg3, 0); + rnewp = &rnew; + } + + ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0)); + if (!is_error(ret) && arg4) { + if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) { + goto efault; + } + target_rold->rlim_cur = tswap64(rold.rlim_cur); + target_rold->rlim_max = tswap64(rold.rlim_max); + unlock_user_struct(target_rold, arg4, 1); + } + break; + } +#endif default: unimplemented: gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index d02a9bf..9dd1b8e 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -49,13 +49,17 @@ #define TARGET_IOC_TYPEBITS 8 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ - || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) || defined(TARGET_PPC) || defined(TARGET_MIPS) + || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) /* 16 bit uid wrappers emulation */ #define USE_UID16 +#define target_id uint16_t +#else +#define target_id uint32_t #endif #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ - || defined(TARGET_M68K) || defined(TARGET_CRIS) + || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_UNICORE32) \ + || defined(TARGET_S390X) #define TARGET_IOC_SIZEBITS 14 #define TARGET_IOC_DIRBITS 2 @@ -205,9 +209,9 @@ __target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct target_cmsghdr *__cms struct target_cmsghdr *__ptr; __ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg - + TARGET_CMSG_ALIGN (tswapl(__cmsg->cmsg_len))); - if ((unsigned long)((char *)(__ptr+1) - (char *)(size_t)tswapl(__mhdr->msg_control)) - > tswapl(__mhdr->msg_controllen)) + + TARGET_CMSG_ALIGN (tswapal(__cmsg->cmsg_len))); + if ((unsigned long)((char *)(__ptr+1) - (char *)(size_t)tswapal(__mhdr->msg_control)) + > tswapal(__mhdr->msg_controllen)) /* No more entries. */ return (struct target_cmsghdr *)0; return __cmsg; @@ -288,7 +292,7 @@ static inline void tswap_sigset(target_sigset_t *d, const target_sigset_t *s) { int i; for(i = 0;i < TARGET_NSIG_WORDS; i++) - d->sig[i] = tswapl(s->sig[i]); + d->sig[i] = tswapal(s->sig[i]); } #else static inline void tswap_sigset(target_sigset_t *d, const target_sigset_t *s) @@ -315,7 +319,11 @@ struct target_sigaction; int do_sigaction(int sig, const struct target_sigaction *act, struct target_sigaction *oact); -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ + || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \ + || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \ + || defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \ + || defined(TARGET_S390X) #if defined(TARGET_SPARC) #define TARGET_SA_NOCLDSTOP 8u @@ -679,10 +687,49 @@ struct target_rlimit { #if defined(TARGET_ALPHA) #define TARGET_RLIM_INFINITY 0x7fffffffffffffffull -#elif defined(TARGET_MIPS) || defined(TARGET_SPARC) +#elif defined(TARGET_MIPS) || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32) #define TARGET_RLIM_INFINITY 0x7fffffffUL #else -#define TARGET_RLIM_INFINITY ((target_ulong)~0UL) +#define TARGET_RLIM_INFINITY ((abi_ulong)-1) +#endif + +#if defined(TARGET_MIPS) +#define TARGET_RLIMIT_CPU 0 +#define TARGET_RLIMIT_FSIZE 1 +#define TARGET_RLIMIT_DATA 2 +#define TARGET_RLIMIT_STACK 3 +#define TARGET_RLIMIT_CORE 4 +#define TARGET_RLIMIT_RSS 7 +#define TARGET_RLIMIT_NPROC 8 +#define TARGET_RLIMIT_NOFILE 5 +#define TARGET_RLIMIT_MEMLOCK 9 +#define TARGET_RLIMIT_AS 6 +#define TARGET_RLIMIT_LOCKS 10 +#define TARGET_RLIMIT_SIGPENDING 11 +#define TARGET_RLIMIT_MSGQUEUE 12 +#define TARGET_RLIMIT_NICE 13 +#define TARGET_RLIMIT_RTPRIO 14 +#else +#define TARGET_RLIMIT_CPU 0 +#define TARGET_RLIMIT_FSIZE 1 +#define TARGET_RLIMIT_DATA 2 +#define TARGET_RLIMIT_STACK 3 +#define TARGET_RLIMIT_CORE 4 +#define TARGET_RLIMIT_RSS 5 +#if defined(TARGET_SPARC) +#define TARGET_RLIMIT_NOFILE 6 +#define TARGET_RLIMIT_NPROC 7 +#else +#define TARGET_RLIMIT_NPROC 6 +#define TARGET_RLIMIT_NOFILE 7 +#endif +#define TARGET_RLIMIT_MEMLOCK 8 +#define TARGET_RLIMIT_AS 9 +#define TARGET_RLIMIT_LOCKS 10 +#define TARGET_RLIMIT_SIGPENDING 11 +#define TARGET_RLIMIT_MSGQUEUE 12 +#define TARGET_RLIMIT_NICE 13 +#define TARGET_RLIMIT_RTPRIO 14 #endif struct target_pollfd { @@ -700,6 +747,10 @@ struct target_pollfd { #define TARGET_KDSKBMODE 0x4b45 #define TARGET_KDGKBENT 0x4B46 /* gets one entry in translation table */ #define TARGET_KDGKBSENT 0x4B48 /* gets one function key string entry */ +#define TARGET_KDGKBLED 0x4B64 /* get led flags (not lights) */ +#define TARGET_KDSKBLED 0x4B65 /* set led flags (not lights) */ +#define TARGET_KDGETLED 0x4B31 /* return current led state */ +#define TARGET_KDSETLED 0x4B32 /* set led state [lights, not flags] */ #define TARGET_SIOCATMARK 0x8905 @@ -762,6 +813,9 @@ struct target_pollfd { #define TARGET_SIOCADDDLCI 0x8980 /* Create new DLCI device */ #define TARGET_SIOCDELDLCI 0x8981 /* Delete DLCI device */ +/* From */ + +#define TARGET_SIOCGIWNAME 0x8B01 /* get name == wireless protocol */ /* From */ @@ -917,6 +971,11 @@ struct target_pollfd { #define TARGET_FBIOGET_VSCREENINFO 0x4600 #define TARGET_FBIOPUT_VSCREENINFO 0x4601 #define TARGET_FBIOGET_FSCREENINFO 0x4602 +#define TARGET_FBIOGETCMAP 0x4604 +#define TARGET_FBIOPUTCMAP 0x4605 +#define TARGET_FBIOPAN_DISPLAY 0x4606 +#define TARGET_FBIOGET_CON2FBMAP 0x460F +#define TARGET_FBIOPUT_CON2FBMAP 0x4610 /* vt ioctls */ #define TARGET_VT_OPENQRY 0x5600 @@ -925,6 +984,10 @@ struct target_pollfd { #define TARGET_VT_WAITACTIVE 0x5607 #define TARGET_VT_LOCKSWITCH 0x560b #define TARGET_VT_UNLOCKSWITCH 0x560c +#define TARGET_VT_GETMODE 0x5601 +#define TARGET_VT_SETMODE 0x5602 +#define TARGET_VT_RELDISP 0x5605 +#define TARGET_VT_DISALLOCATE 0x5608 /* from asm/termbits.h */ @@ -999,9 +1062,11 @@ struct target_winsize { #define TARGET_MAP_NORESERVE 0x4000 /* don't check for reservations */ #define TARGET_MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ #define TARGET_MAP_NONBLOCK 0x10000 /* do not block on IO */ +#define TARGET_MAP_UNINITIALIZED 0x4000000 /* for anonymous mmap, memory could be uninitialized */ #endif -#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_CRIS) +#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) \ + || defined(TARGET_CRIS) || defined(TARGET_UNICORE32) struct target_stat { unsigned short st_dev; unsigned short __pad1; @@ -1060,7 +1125,7 @@ struct target_stat64 { abi_ulong __pad7; /* will be high 32 bits of ctime someday */ unsigned long long st_ino; -} __attribute__((packed)); +} QEMU_PACKED; #ifdef TARGET_ARM struct target_eabi_stat64 { @@ -1091,7 +1156,7 @@ struct target_eabi_stat64 { abi_ulong target_st_ctime_nsec; unsigned long long st_ino; -} __attribute__ ((packed)); +} QEMU_PACKED; #endif #elif defined(TARGET_SPARC64) && !defined(TARGET_ABI32) @@ -1234,7 +1299,7 @@ struct target_stat { #endif }; -struct __attribute__((__packed__)) target_stat64 { +struct QEMU_PACKED target_stat64 { unsigned long long st_dev; unsigned long long st_ino; unsigned int st_mode; @@ -1281,7 +1346,7 @@ struct target_stat { }; /* FIXME: Microblaze no-mmu user-space has a difference stat64 layout... */ -struct __attribute__((__packed__)) target_stat64 { +struct QEMU_PACKED target_stat64 { uint64_t st_dev; #define TARGET_STAT64_HAS_BROKEN_ST_INO 1 uint32_t pad0; @@ -1368,7 +1433,7 @@ struct target_stat64 { abi_ulong target_st_ctime_nsec; unsigned long long st_ino; -} __attribute__((packed)); +} QEMU_PACKED; #elif defined(TARGET_ABI_MIPSN64) @@ -1620,7 +1685,7 @@ struct target_stat { /* This matches struct stat64 in glibc2.1, hence the absolutely * insane amounts of padding around dev_t's. */ -struct __attribute__((__packed__)) target_stat64 { +struct QEMU_PACKED target_stat64 { unsigned long long st_dev; unsigned char __pad0[4]; @@ -1677,6 +1742,27 @@ struct target_stat { abi_long __unused[3]; }; +#elif defined(TARGET_S390X) +struct target_stat { + abi_ulong st_dev; + abi_ulong st_ino; + abi_ulong st_nlink; + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int __pad1; + abi_ulong st_rdev; + abi_ulong st_size; + abi_ulong target_st_atime; + abi_ulong target_st_atime_nsec; + abi_ulong target_st_mtime; + abi_ulong target_st_mtime_nsec; + abi_ulong target_st_ctime; + abi_ulong target_st_ctime_nsec; + abi_ulong st_blksize; + abi_long st_blocks; + abi_ulong __unused[3]; +}; #else #error unsupported CPU #endif @@ -1763,6 +1849,34 @@ struct target_statfs64 { abi_long f_frsize; abi_long f_spare[5]; }; +#elif defined(TARGET_S390X) +struct target_statfs { + int32_t f_type; + int32_t f_bsize; + abi_long f_blocks; + abi_long f_bfree; + abi_long f_bavail; + abi_long f_files; + abi_long f_ffree; + kernel_fsid_t f_fsid; + int32_t f_namelen; + int32_t f_frsize; + int32_t f_spare[5]; +}; + +struct target_statfs64 { + int32_t f_type; + int32_t f_bsize; + abi_long f_blocks; + abi_long f_bfree; + abi_long f_bavail; + abi_long f_files; + abi_long f_ffree; + kernel_fsid_t f_fsid; + int32_t f_namelen; + int32_t f_frsize; + int32_t f_spare[5]; +}; #else struct target_statfs { uint32_t f_type; @@ -1986,7 +2100,7 @@ struct target_flock64 { unsigned long long l_start; unsigned long long l_len; int l_pid; -}__attribute__((packed)); +} QEMU_PACKED; #ifdef TARGET_ARM struct target_eabi_flock64 { @@ -1996,7 +2110,7 @@ struct target_eabi_flock64 { unsigned long long l_start; unsigned long long l_len; int l_pid; -}__attribute__((packed)); +} QEMU_PACKED; #endif /* soundcard defines */ @@ -2205,3 +2319,20 @@ struct target_mq_attr { #define FUTEX_CLOCK_REALTIME 256 #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) +#ifdef CONFIG_EPOLL +typedef union target_epoll_data { + abi_ulong ptr; + abi_ulong fd; + uint32_t u32; + uint64_t u64; +} target_epoll_data_t; + +struct target_epoll_event { + uint32_t events; + target_epoll_data_t data; +}; +#endif +struct target_rlimit64 { + uint64_t rlim_cur; + uint64_t rlim_max; +}; diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 0e67cd8..c370125 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -161,11 +161,31 @@ STRUCT(fb_var_screeninfo, TYPE_INT, /* rotate */ MK_ARRAY(TYPE_INT, 5)) /* reserved */ +STRUCT(fb_cmap, + TYPE_INT, /* start */ + TYPE_INT, /* len */ + TYPE_PTRVOID, /* red */ + TYPE_PTRVOID, /* green */ + TYPE_PTRVOID, /* blue */ + TYPE_PTRVOID) /* transp */ + +STRUCT(fb_con2fbmap, + TYPE_INT, /* console */ + TYPE_INT) /* framebuffer */ + + STRUCT(vt_stat, TYPE_SHORT, /* v_active */ TYPE_SHORT, /* v_signal */ TYPE_SHORT) /* v_state */ +STRUCT(vt_mode, + TYPE_CHAR, /* mode */ + TYPE_CHAR, /* waitv */ + TYPE_SHORT, /* relsig */ + TYPE_SHORT, /* acqsig */ + TYPE_SHORT) /* frsig */ + STRUCT(fiemap_extent, TYPE_ULONGLONG, /* fe_logical */ TYPE_ULONGLONG, /* fe_physical */ diff --git a/linux-user/vm86.c b/linux-user/vm86.c index 0b2439d..2c4ffeb 100644 --- a/linux-user/vm86.c +++ b/linux-user/vm86.c @@ -432,7 +432,7 @@ int do_vm86(CPUX86State *env, long subfunction, abi_ulong vm86_addr) env->eflags = (env->eflags & ~SAFE_MASK) | (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK; - ts->vm86plus.cpu_type = tswapl(target_v86->cpu_type); + ts->vm86plus.cpu_type = tswapal(target_v86->cpu_type); switch (ts->vm86plus.cpu_type) { case TARGET_CPU_286: ts->v86mask = 0; @@ -468,7 +468,7 @@ int do_vm86(CPUX86State *env, long subfunction, abi_ulong vm86_addr) &target_v86->int_revectored, 32); memcpy(&ts->vm86plus.int21_revectored, &target_v86->int21_revectored, 32); - ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags); + ts->vm86plus.vm86plus.flags = tswapal(target_v86->vm86plus.flags); memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab, target_v86->vm86plus.vm86dbg_intxxtab, 32); unlock_user_struct(target_v86, vm86_addr, 0); diff --git a/linux-user/x86_64/syscall_nr.h b/linux-user/x86_64/syscall_nr.h index 568a901..947e961 100644 --- a/linux-user/x86_64/syscall_nr.h +++ b/linux-user/x86_64/syscall_nr.h @@ -293,3 +293,15 @@ #define TARGET_NR_dup3 292 #define TARGET_NR_pipe2 293 #define TARGET_NR_inotify_init1 294 +#define TARGET_NR_preadv 295 +#define TARGET_NR_pwritev 296 +#define TARGET_NR_rt_tgsigqueueinfo 297 +#define TARGET_NR_perf_event_open 298 +#define TARGET_NR_recvmmsg 299 +#define TARGET_NR_fanotify_init 300 +#define TARGET_NR_fanotify_mark 301 +#define TARGET_NR_prlimit64 302 +#define TARGET_NR_name_to_handle_at 303 +#define TARGET_NR_open_by_handle_at 304 +#define TARGET_NR_clock_adjtime 305 +#define TARGET_NR_syncfs 306 diff --git a/m68k-semi.c b/m68k-semi.c index 0371089..bab01ee 100644 --- a/m68k-semi.c +++ b/m68k-semi.c @@ -70,12 +70,12 @@ struct m68k_gdb_stat { gdb_time_t gdb_st_atime; /* time of last access */ gdb_time_t gdb_st_mtime; /* time of last modification */ gdb_time_t gdb_st_ctime; /* time of last change */ -} __attribute__((packed)); +} QEMU_PACKED; struct gdb_timeval { gdb_time_t tv_sec; /* second */ uint64_t tv_usec; /* microsecond */ -} __attribute__((packed)); +} QEMU_PACKED; #define GDB_O_RDONLY 0x0 #define GDB_O_WRONLY 0x1 @@ -370,7 +370,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) TaskState *ts = env->opaque; /* Allocate the heap using sbrk. */ if (!ts->heap_limit) { - long ret; + abi_ulong ret; uint32_t size; uint32_t base; @@ -379,8 +379,9 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) /* Try a big heap, and reduce the size if that fails. */ for (;;) { ret = do_brk(base + size); - if (ret != -1) + if (ret >= (base + size)) { break; + } size >>= 1; } ts->heap_limit = base + size; diff --git a/migration-exec.c b/migration-exec.c index 14718dd..b7b1055 100644 --- a/migration-exec.c +++ b/migration-exec.c @@ -17,7 +17,6 @@ #include "qemu_socket.h" #include "migration.h" #include "qemu-char.h" -#include "sysemu.h" #include "buffered_file.h" #include "block.h" #include @@ -33,17 +32,17 @@ do { } while (0) #endif -static int file_errno(FdMigrationState *s) +static int file_errno(MigrationState *s) { return errno; } -static int file_write(FdMigrationState *s, const void * buf, size_t size) +static int file_write(MigrationState *s, const void * buf, size_t size) { return write(s->fd, buf, size); } -static int exec_close(FdMigrationState *s) +static int exec_close(MigrationState *s) { int ret = 0; DPRINTF("exec_close\n"); @@ -62,22 +61,14 @@ static int exec_close(FdMigrationState *s) return ret; } -MigrationState *exec_start_outgoing_migration(Monitor *mon, - const char *command, - int64_t bandwidth_limit, - int detach, - int blk, - int inc) +int exec_start_outgoing_migration(MigrationState *s, const char *command) { - FdMigrationState *s; FILE *f; - s = qemu_mallocz(sizeof(*s)); - f = popen(command, "w"); if (f == NULL) { DPRINTF("Unable to popen exec target\n"); - goto err_after_alloc; + goto err_after_popen; } s->fd = fileno(f); @@ -93,29 +84,14 @@ MigrationState *exec_start_outgoing_migration(Monitor *mon, s->close = exec_close; s->get_error = file_errno; s->write = file_write; - s->mig_state.cancel = migrate_fd_cancel; - s->mig_state.get_status = migrate_fd_get_status; - s->mig_state.release = migrate_fd_release; - - s->mig_state.blk = blk; - s->mig_state.shared = inc; - - s->state = MIG_STATE_ACTIVE; - s->mon = NULL; - s->bandwidth_limit = bandwidth_limit; - - if (!detach) { - migrate_fd_monitor_suspend(s, mon); - } migrate_fd_connect(s); - return &s->mig_state; + return 0; err_after_open: pclose(f); -err_after_alloc: - qemu_free(s); - return NULL; +err_after_popen: + return -1; } static void exec_accept_incoming_migration(void *opaque) diff --git a/migration-fd.c b/migration-fd.c index 6d14505..6211124 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -16,7 +16,6 @@ #include "migration.h" #include "monitor.h" #include "qemu-char.h" -#include "sysemu.h" #include "buffered_file.h" #include "block.h" #include "qemu_socket.h" @@ -31,41 +30,53 @@ do { } while (0) #endif -static int fd_errno(FdMigrationState *s) +static int fd_errno(MigrationState *s) { return errno; } -static int fd_write(FdMigrationState *s, const void * buf, size_t size) +static int fd_write(MigrationState *s, const void * buf, size_t size) { return write(s->fd, buf, size); } -static int fd_close(FdMigrationState *s) +static int fd_close(MigrationState *s) { + struct stat st; + int ret; + DPRINTF("fd_close\n"); if (s->fd != -1) { - close(s->fd); + ret = fstat(s->fd, &st); + if (ret == 0 && S_ISREG(st.st_mode)) { + /* + * If the file handle is a regular file make sure the + * data is flushed to disk before signaling success. + */ + ret = fsync(s->fd); + if (ret != 0) { + ret = -errno; + perror("migration-fd: fsync"); + return ret; + } + } + ret = close(s->fd); s->fd = -1; + if (ret != 0) { + ret = -errno; + perror("migration-fd: close"); + return ret; + } } return 0; } -MigrationState *fd_start_outgoing_migration(Monitor *mon, - const char *fdname, - int64_t bandwidth_limit, - int detach, - int blk, - int inc) +int fd_start_outgoing_migration(MigrationState *s, const char *fdname) { - FdMigrationState *s; - - s = qemu_mallocz(sizeof(*s)); - - s->fd = monitor_get_fd(mon, fdname); + s->fd = monitor_get_fd(s->mon, fdname); if (s->fd == -1) { DPRINTF("fd_migration: invalid file descriptor identifier\n"); - goto err_after_alloc; + goto err_after_get_fd; } if (fcntl(s->fd, F_SETFL, O_NONBLOCK) == -1) { @@ -76,29 +87,14 @@ MigrationState *fd_start_outgoing_migration(Monitor *mon, s->get_error = fd_errno; s->write = fd_write; s->close = fd_close; - s->mig_state.cancel = migrate_fd_cancel; - s->mig_state.get_status = migrate_fd_get_status; - s->mig_state.release = migrate_fd_release; - - s->mig_state.blk = blk; - s->mig_state.shared = inc; - - s->state = MIG_STATE_ACTIVE; - s->mon = NULL; - s->bandwidth_limit = bandwidth_limit; - - if (!detach) { - migrate_fd_monitor_suspend(s, mon); - } migrate_fd_connect(s); - return &s->mig_state; + return 0; err_after_open: close(s->fd); -err_after_alloc: - qemu_free(s); - return NULL; +err_after_get_fd: + return -1; } static void fd_accept_incoming_migration(void *opaque) diff --git a/migration-tcp.c b/migration-tcp.c index b55f419..5aa742c 100644 --- a/migration-tcp.c +++ b/migration-tcp.c @@ -15,7 +15,6 @@ #include "qemu_socket.h" #include "migration.h" #include "qemu-char.h" -#include "sysemu.h" #include "buffered_file.h" #include "block.h" @@ -29,17 +28,17 @@ do { } while (0) #endif -static int socket_errno(FdMigrationState *s) +static int socket_errno(MigrationState *s) { return socket_error(); } -static int socket_write(FdMigrationState *s, const void * buf, size_t size) +static int socket_write(MigrationState *s, const void * buf, size_t size) { return send(s->fd, buf, size, 0); } -static int tcp_close(FdMigrationState *s) +static int tcp_close(MigrationState *s) { DPRINTF("tcp_close\n"); if (s->fd != -1) { @@ -49,17 +48,16 @@ static int tcp_close(FdMigrationState *s) return 0; } - static void tcp_wait_for_connect(void *opaque) { - FdMigrationState *s = opaque; + MigrationState *s = opaque; int val, ret; socklen_t valsize = sizeof(val); DPRINTF("connect completed\n"); do { ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, (void *) &val, &valsize); - } while (ret == -1 && (s->get_error(s)) == EINTR); + } while (ret == -1 && (socket_error()) == EINTR); if (ret < 0) { migrate_fd_error(s); @@ -76,70 +74,53 @@ static void tcp_wait_for_connect(void *opaque) } } -MigrationState *tcp_start_outgoing_migration(Monitor *mon, - const char *host_port, - int64_t bandwidth_limit, - int detach, - int blk, - int inc) +int tcp_start_outgoing_migration(MigrationState *s, const char *host_port) { struct sockaddr_in addr; - FdMigrationState *s; int ret; - if (parse_host_port(&addr, host_port) < 0) - return NULL; - - s = qemu_mallocz(sizeof(*s)); + ret = parse_host_port(&addr, host_port); + if (ret < 0) { + return ret; + } s->get_error = socket_errno; s->write = socket_write; s->close = tcp_close; - s->mig_state.cancel = migrate_fd_cancel; - s->mig_state.get_status = migrate_fd_get_status; - s->mig_state.release = migrate_fd_release; - - s->mig_state.blk = blk; - s->mig_state.shared = inc; - s->state = MIG_STATE_ACTIVE; - s->mon = NULL; - s->bandwidth_limit = bandwidth_limit; s->fd = qemu_socket(PF_INET, SOCK_STREAM, 0); if (s->fd == -1) { - qemu_free(s); - return NULL; + DPRINTF("Unable to open socket"); + return -socket_error(); } socket_set_nonblock(s->fd); - if (!detach) { - migrate_fd_monitor_suspend(s, mon); - } - do { ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); - if (ret == -1) - ret = -(s->get_error(s)); - - if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) + if (ret == -1) { + ret = -socket_error(); + } + if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) { qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); + return 0; + } } while (ret == -EINTR); - if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { + if (ret < 0) { DPRINTF("connect failed\n"); migrate_fd_error(s); - } else if (ret >= 0) - migrate_fd_connect(s); - - return &s->mig_state; + return ret; + } + migrate_fd_connect(s); + return 0; } static void tcp_accept_incoming_migration(void *opaque) { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); - int s = (unsigned long)opaque; + int s = (intptr_t)opaque; QEMUFile *f; int c; @@ -175,26 +156,30 @@ int tcp_start_incoming_migration(const char *host_port) int val; int s; + DPRINTF("Attempting to start an incoming migration\n"); + if (parse_host_port(&addr, host_port) < 0) { fprintf(stderr, "invalid host/port combination: %s\n", host_port); return -EINVAL; } s = qemu_socket(PF_INET, SOCK_STREAM, 0); - if (s == -1) + if (s == -1) { return -socket_error(); + } val = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); - if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { goto err; - - if (listen(s, 1) == -1) + } + if (listen(s, 1) == -1) { goto err; + } qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL, - (void *)(unsigned long)s); + (void *)(intptr_t)s); return 0; diff --git a/migration-unix.c b/migration-unix.c index 57232c0..8596353 100644 --- a/migration-unix.c +++ b/migration-unix.c @@ -15,7 +15,6 @@ #include "qemu_socket.h" #include "migration.h" #include "qemu-char.h" -#include "sysemu.h" #include "buffered_file.h" #include "block.h" @@ -29,17 +28,17 @@ do { } while (0) #endif -static int unix_errno(FdMigrationState *s) +static int unix_errno(MigrationState *s) { return errno; } -static int unix_write(FdMigrationState *s, const void * buf, size_t size) +static int unix_write(MigrationState *s, const void * buf, size_t size) { return write(s->fd, buf, size); } -static int unix_close(FdMigrationState *s) +static int unix_close(MigrationState *s) { DPRINTF("unix_close\n"); if (s->fd != -1) { @@ -51,14 +50,14 @@ static int unix_close(FdMigrationState *s) static void unix_wait_for_connect(void *opaque) { - FdMigrationState *s = opaque; + MigrationState *s = opaque; int val, ret; socklen_t valsize = sizeof(val); DPRINTF("connect completed\n"); do { ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, (void *) &val, &valsize); - } while (ret == -1 && (s->get_error(s)) == EINTR); + } while (ret == -1 && errno == EINTR); if (ret < 0) { migrate_fd_error(s); @@ -75,91 +74,62 @@ static void unix_wait_for_connect(void *opaque) } } -MigrationState *unix_start_outgoing_migration(Monitor *mon, - const char *path, - int64_t bandwidth_limit, - int detach, - int blk, - int inc) +int unix_start_outgoing_migration(MigrationState *s, const char *path) { - FdMigrationState *s; struct sockaddr_un addr; int ret; addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); - - s = qemu_mallocz(sizeof(*s)); - s->get_error = unix_errno; s->write = unix_write; s->close = unix_close; - s->mig_state.cancel = migrate_fd_cancel; - s->mig_state.get_status = migrate_fd_get_status; - s->mig_state.release = migrate_fd_release; - - s->mig_state.blk = blk; - s->mig_state.shared = inc; - s->state = MIG_STATE_ACTIVE; - s->mon = NULL; - s->bandwidth_limit = bandwidth_limit; s->fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); - if (s->fd < 0) { + if (s->fd == -1) { DPRINTF("Unable to open socket"); - goto err_after_alloc; + return -errno; } socket_set_nonblock(s->fd); do { ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); - if (ret == -1) - ret = -(s->get_error(s)); - - if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) + if (ret == -1) { + ret = -errno; + } + if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) { qemu_set_fd_handler2(s->fd, NULL, NULL, unix_wait_for_connect, s); + return 0; + } } while (ret == -EINTR); - if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { + if (ret < 0) { DPRINTF("connect failed\n"); - goto err_after_open; - } - - if (!detach) { - migrate_fd_monitor_suspend(s, mon); + migrate_fd_error(s); + return ret; } - - if (ret >= 0) - migrate_fd_connect(s); - - return &s->mig_state; - -err_after_open: - close(s->fd); - -err_after_alloc: - qemu_free(s); - return NULL; + migrate_fd_connect(s); + return 0; } static void unix_accept_incoming_migration(void *opaque) { struct sockaddr_un addr; socklen_t addrlen = sizeof(addr); - int s = (unsigned long)opaque; + int s = (intptr_t)opaque; QEMUFile *f; int c; do { c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen); - } while (c == -1 && socket_error() == EINTR); + } while (c == -1 && errno == EINTR); DPRINTF("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); - return; + goto out2; } f = qemu_fopen_socket(c); @@ -171,45 +141,49 @@ static void unix_accept_incoming_migration(void *opaque) process_incoming_migration(f); qemu_fclose(f); out: + close(c); +out2: qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); close(s); - close(c); } int unix_start_incoming_migration(const char *path) { - struct sockaddr_un un; - int sock; + struct sockaddr_un addr; + int s; + int ret; DPRINTF("Attempting to start an incoming migration\n"); - sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { + s = qemu_socket(PF_UNIX, SOCK_STREAM, 0); + if (s == -1) { fprintf(stderr, "Could not open unix socket: %s\n", strerror(errno)); - return -EINVAL; + return -errno; } - memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; - snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); - unlink(un.sun_path); - if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { - fprintf(stderr, "bind(unix:%s): %s\n", un.sun_path, strerror(errno)); + unlink(addr.sun_path); + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + ret = -errno; + fprintf(stderr, "bind(unix:%s): %s\n", addr.sun_path, strerror(errno)); goto err; } - if (listen(sock, 1) < 0) { - fprintf(stderr, "listen(unix:%s): %s\n", un.sun_path, strerror(errno)); + if (listen(s, 1) == -1) { + fprintf(stderr, "listen(unix:%s): %s\n", addr.sun_path, + strerror(errno)); + ret = -errno; goto err; } - qemu_set_fd_handler2(sock, NULL, unix_accept_incoming_migration, NULL, - (void *)(unsigned long)sock); + qemu_set_fd_handler2(s, NULL, unix_accept_incoming_migration, NULL, + (void *)(intptr_t)s); return 0; err: - close(sock); - - return -EINVAL; + close(s); + return ret; } diff --git a/migration.c b/migration.c index 3612572..8280d71 100644 --- a/migration.c +++ b/migration.c @@ -19,7 +19,7 @@ #include "block.h" #include "qemu_socket.h" #include "block-migration.h" -#include "qemu-objects.h" +#include "qmp-commands.h" //#define DEBUG_MIGRATION @@ -31,14 +31,33 @@ do { } while (0) #endif -/* Migration speed throttling */ -static int64_t max_throttle = (32 << 20); +enum { + MIG_STATE_ERROR, + MIG_STATE_SETUP, + MIG_STATE_CANCELLED, + MIG_STATE_ACTIVE, + MIG_STATE_COMPLETED, +}; -static MigrationState *current_migration; +#define MAX_THROTTLE (32 << 20) /* Migration speed throttling */ static NotifierList migration_state_notifiers = NOTIFIER_LIST_INITIALIZER(migration_state_notifiers); +/* When we add fault tolerance, we could have several + migrations at once. For now we don't need to add + dynamic creation of migration */ + +static MigrationState *migrate_get_current(void) +{ + static MigrationState current_migration = { + .state = MIG_STATE_SETUP, + .bandwidth_limit = MAX_THROTTLE, + }; + + return ¤t_migration; +} + int qemu_start_incoming_migration(const char *uri) { const char *p; @@ -70,91 +89,14 @@ void process_incoming_migration(QEMUFile *f) qemu_announce_self(); DPRINTF("successfully loaded vm state\n"); - incoming_expected = false; + /* Make sure all file formats flush their mutable metadata */ + bdrv_invalidate_cache_all(); - if (autostart) + if (autostart) { vm_start(); -} - -int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - MigrationState *s = NULL; - const char *p; - int detach = qdict_get_try_bool(qdict, "detach", 0); - int blk = qdict_get_try_bool(qdict, "blk", 0); - int inc = qdict_get_try_bool(qdict, "inc", 0); - const char *uri = qdict_get_str(qdict, "uri"); - - if (current_migration && - current_migration->get_status(current_migration) == MIG_STATE_ACTIVE) { - monitor_printf(mon, "migration already in progress\n"); - return -1; - } - - if (qemu_savevm_state_blocked(mon)) { - return -1; - } - - if (strstart(uri, "tcp:", &p)) { - s = tcp_start_outgoing_migration(mon, p, max_throttle, detach, - blk, inc); -#if !defined(WIN32) - } else if (strstart(uri, "exec:", &p)) { - s = exec_start_outgoing_migration(mon, p, max_throttle, detach, - blk, inc); - } else if (strstart(uri, "unix:", &p)) { - s = unix_start_outgoing_migration(mon, p, max_throttle, detach, - blk, inc); - } else if (strstart(uri, "fd:", &p)) { - s = fd_start_outgoing_migration(mon, p, max_throttle, detach, - blk, inc); -#endif } else { - monitor_printf(mon, "unknown migration protocol: %s\n", uri); - return -1; + runstate_set(RUN_STATE_PRELAUNCH); } - - if (s == NULL) { - monitor_printf(mon, "migration failed\n"); - return -1; - } - - if (current_migration) { - current_migration->release(current_migration); - } - - current_migration = s; - notifier_list_notify(&migration_state_notifiers); - return 0; -} - -int do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - MigrationState *s = current_migration; - - if (s) - s->cancel(s); - - return 0; -} - -int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - int64_t d; - FdMigrationState *s; - - d = qdict_get_int(qdict, "value"); - if (d < 0) { - d = 0; - } - max_throttle = d; - - s = migrate_to_fms(current_migration); - if (s && s->file) { - qemu_file_set_rate_limit(s->file, max_throttle); - } - - return 0; } /* amount of nanoseconds we are willing to wait for migration to be down. @@ -168,102 +110,54 @@ uint64_t migrate_max_downtime(void) return max_downtime; } -int do_migrate_set_downtime(Monitor *mon, const QDict *qdict, - QObject **ret_data) +MigrationInfo *qmp_query_migrate(Error **errp) { - double d; - - d = qdict_get_double(qdict, "value") * 1e9; - d = MAX(0, MIN(UINT64_MAX, d)); - max_downtime = (uint64_t)d; - - return 0; -} - -static void migrate_print_status(Monitor *mon, const char *name, - const QDict *status_dict) -{ - QDict *qdict; - - qdict = qobject_to_qdict(qdict_get(status_dict, name)); - - monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name, - qdict_get_int(qdict, "transferred") >> 10); - monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name, - qdict_get_int(qdict, "remaining") >> 10); - monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name, - qdict_get_int(qdict, "total") >> 10); -} - -void do_info_migrate_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - - qdict = qobject_to_qdict(data); - - monitor_printf(mon, "Migration status: %s\n", - qdict_get_str(qdict, "status")); - - if (qdict_haskey(qdict, "ram")) { - migrate_print_status(mon, "ram", qdict); - } - - if (qdict_haskey(qdict, "disk")) { - migrate_print_status(mon, "disk", qdict); - } -} - -static void migrate_put_status(QDict *qdict, const char *name, - uint64_t trans, uint64_t rem, uint64_t total) -{ - QObject *obj; - - obj = qobject_from_jsonf("{ 'transferred': %" PRId64 ", " - "'remaining': %" PRId64 ", " - "'total': %" PRId64 " }", trans, rem, total); - qdict_put_obj(qdict, name, obj); -} - -void do_info_migrate(Monitor *mon, QObject **ret_data) -{ - QDict *qdict; - MigrationState *s = current_migration; - - if (s) { - switch (s->get_status(s)) { - case MIG_STATE_ACTIVE: - qdict = qdict_new(); - qdict_put(qdict, "status", qstring_from_str("active")); - - migrate_put_status(qdict, "ram", ram_bytes_transferred(), - ram_bytes_remaining(), ram_bytes_total()); - - if (blk_mig_active()) { - migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(), - blk_mig_bytes_remaining(), - blk_mig_bytes_total()); - } - - *ret_data = QOBJECT(qdict); - break; - case MIG_STATE_COMPLETED: - *ret_data = qobject_from_jsonf("{ 'status': 'completed' }"); - break; - case MIG_STATE_ERROR: - *ret_data = qobject_from_jsonf("{ 'status': 'failed' }"); - break; - case MIG_STATE_CANCELLED: - *ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }"); - break; + MigrationInfo *info = g_malloc0(sizeof(*info)); + MigrationState *s = migrate_get_current(); + + switch (s->state) { + case MIG_STATE_SETUP: + /* no migration has happened ever */ + break; + case MIG_STATE_ACTIVE: + info->has_status = true; + info->status = g_strdup("active"); + + info->has_ram = true; + info->ram = g_malloc0(sizeof(*info->ram)); + info->ram->transferred = ram_bytes_transferred(); + info->ram->remaining = ram_bytes_remaining(); + info->ram->total = ram_bytes_total(); + + if (blk_mig_active()) { + info->has_disk = true; + info->disk = g_malloc0(sizeof(*info->disk)); + info->disk->transferred = blk_mig_bytes_transferred(); + info->disk->remaining = blk_mig_bytes_remaining(); + info->disk->total = blk_mig_bytes_total(); } + break; + case MIG_STATE_COMPLETED: + info->has_status = true; + info->status = g_strdup("completed"); + break; + case MIG_STATE_ERROR: + info->has_status = true; + info->status = g_strdup("failed"); + break; + case MIG_STATE_CANCELLED: + info->has_status = true; + info->status = g_strdup("cancelled"); + break; } + + return info; } /* shared migration helpers */ -void migrate_fd_monitor_suspend(FdMigrationState *s, Monitor *mon) +static void migrate_fd_monitor_suspend(MigrationState *s, Monitor *mon) { - s->mon = mon; if (monitor_suspend(mon) == 0) { DPRINTF("suspending monitor\n"); } else { @@ -272,15 +166,7 @@ void migrate_fd_monitor_suspend(FdMigrationState *s, Monitor *mon) } } -void migrate_fd_error(FdMigrationState *s) -{ - DPRINTF("setting error state\n"); - s->state = MIG_STATE_ERROR; - notifier_list_notify(&migration_state_notifiers); - migrate_fd_cleanup(s); -} - -int migrate_fd_cleanup(FdMigrationState *s) +static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; @@ -292,34 +178,61 @@ int migrate_fd_cleanup(FdMigrationState *s) ret = -1; } s->file = NULL; + } else { + if (s->mon) { + monitor_resume(s->mon); + } } - if (s->fd != -1) + if (s->fd != -1) { close(s->fd); - - /* Don't resume monitor until we've flushed all of the buffers */ - if (s->mon) { - monitor_resume(s->mon); + s->fd = -1; } - s->fd = -1; - return ret; } -void migrate_fd_put_notify(void *opaque) +void migrate_fd_error(MigrationState *s) { - FdMigrationState *s = opaque; + DPRINTF("setting error state\n"); + s->state = MIG_STATE_ERROR; + notifier_list_notify(&migration_state_notifiers, s); + migrate_fd_cleanup(s); +} + +static void migrate_fd_completed(MigrationState *s) +{ + DPRINTF("setting completed state\n"); + if (migrate_fd_cleanup(s) < 0) { + s->state = MIG_STATE_ERROR; + } else { + s->state = MIG_STATE_COMPLETED; + runstate_set(RUN_STATE_POSTMIGRATE); + } + notifier_list_notify(&migration_state_notifiers, s); +} + +static void migrate_fd_put_notify(void *opaque) +{ + MigrationState *s = opaque; qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); qemu_file_put_notify(s->file); + if (s->file && qemu_file_get_error(s->file)) { + migrate_fd_error(s); + } } -ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) +static ssize_t migrate_fd_put_buffer(void *opaque, const void *data, + size_t size) { - FdMigrationState *s = opaque; + MigrationState *s = opaque; ssize_t ret; + if (s->state != MIG_STATE_ACTIVE) { + return -EIO; + } + do { ret = s->write(s, data, size); } while (ret == -1 && ((s->get_error(s)) == EINTR)); @@ -329,115 +242,61 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) if (ret == -EAGAIN) { qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); - } else if (ret < 0) { - if (s->mon) { - monitor_resume(s->mon); - } - s->state = MIG_STATE_ERROR; - notifier_list_notify(&migration_state_notifiers); } return ret; } -void migrate_fd_connect(FdMigrationState *s) +static void migrate_fd_put_ready(void *opaque) { + MigrationState *s = opaque; int ret; - s->file = qemu_fopen_ops_buffered(s, - s->bandwidth_limit, - migrate_fd_put_buffer, - migrate_fd_put_ready, - migrate_fd_wait_for_unfreeze, - migrate_fd_close); - - DPRINTF("beginning savevm\n"); - ret = qemu_savevm_state_begin(s->mon, s->file, s->mig_state.blk, - s->mig_state.shared); - if (ret < 0) { - DPRINTF("failed, %d\n", ret); - migrate_fd_error(s); - return; - } - - migrate_fd_put_ready(s); -} - -void migrate_fd_put_ready(void *opaque) -{ - FdMigrationState *s = opaque; - if (s->state != MIG_STATE_ACTIVE) { DPRINTF("put_ready returning because of non-active state\n"); return; } DPRINTF("iterate\n"); - if (qemu_savevm_state_iterate(s->mon, s->file) == 1) { - int state; - int old_vm_running = vm_running; + ret = qemu_savevm_state_iterate(s->mon, s->file); + if (ret < 0) { + migrate_fd_error(s); + } else if (ret == 1) { + int old_vm_running = runstate_is_running(); DPRINTF("done iterating\n"); - vm_stop(0); + vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); - if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) { - if (old_vm_running) { - vm_start(); - } - state = MIG_STATE_ERROR; + if (qemu_savevm_state_complete(s->mon, s->file) < 0) { + migrate_fd_error(s); } else { - state = MIG_STATE_COMPLETED; + migrate_fd_completed(s); } - if (migrate_fd_cleanup(s) < 0) { + if (s->state != MIG_STATE_COMPLETED) { if (old_vm_running) { vm_start(); } - state = MIG_STATE_ERROR; } - s->state = state; - notifier_list_notify(&migration_state_notifiers); } } -int migrate_fd_get_status(MigrationState *mig_state) -{ - FdMigrationState *s = migrate_to_fms(mig_state); - return s->state; -} - -void migrate_fd_cancel(MigrationState *mig_state) +static void migrate_fd_cancel(MigrationState *s) { - FdMigrationState *s = migrate_to_fms(mig_state); - if (s->state != MIG_STATE_ACTIVE) return; DPRINTF("cancelling migration\n"); s->state = MIG_STATE_CANCELLED; - notifier_list_notify(&migration_state_notifiers); + notifier_list_notify(&migration_state_notifiers, s); qemu_savevm_state_cancel(s->mon, s->file); migrate_fd_cleanup(s); } -void migrate_fd_release(MigrationState *mig_state) +static void migrate_fd_wait_for_unfreeze(void *opaque) { - FdMigrationState *s = migrate_to_fms(mig_state); - - DPRINTF("releasing state\n"); - - if (s->state == MIG_STATE_ACTIVE) { - s->state = MIG_STATE_CANCELLED; - notifier_list_notify(&migration_state_notifiers); - migrate_fd_cleanup(s); - } - qemu_free(s); -} - -void migrate_fd_wait_for_unfreeze(void *opaque) -{ - FdMigrationState *s = opaque; + MigrationState *s = opaque; int ret; DPRINTF("wait for unfreeze\n"); @@ -452,12 +311,19 @@ void migrate_fd_wait_for_unfreeze(void *opaque) ret = select(s->fd + 1, NULL, &wfds, NULL, NULL); } while (ret == -1 && (s->get_error(s)) == EINTR); + + if (ret == -1) { + qemu_file_set_error(s->file, -s->get_error(s)); + } } -int migrate_fd_close(void *opaque) +static int migrate_fd_close(void *opaque) { - FdMigrationState *s = opaque; + MigrationState *s = opaque; + if (s->mon) { + monitor_resume(s->mon); + } qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); return s->close(s); } @@ -472,11 +338,167 @@ void remove_migration_state_change_notifier(Notifier *notify) notifier_list_remove(&migration_state_notifiers, notify); } -int get_migration_state(void) +bool migration_is_active(MigrationState *s) +{ + return s->state == MIG_STATE_ACTIVE; +} + +bool migration_has_finished(MigrationState *s) +{ + return s->state == MIG_STATE_COMPLETED; +} + +bool migration_has_failed(MigrationState *s) +{ + return (s->state == MIG_STATE_CANCELLED || + s->state == MIG_STATE_ERROR); +} + +void migrate_fd_connect(MigrationState *s) +{ + int ret; + + s->state = MIG_STATE_ACTIVE; + s->file = qemu_fopen_ops_buffered(s, + s->bandwidth_limit, + migrate_fd_put_buffer, + migrate_fd_put_ready, + migrate_fd_wait_for_unfreeze, + migrate_fd_close); + + DPRINTF("beginning savevm\n"); + ret = qemu_savevm_state_begin(s->mon, s->file, s->blk, s->shared); + if (ret < 0) { + DPRINTF("failed, %d\n", ret); + migrate_fd_error(s); + return; + } + migrate_fd_put_ready(s); +} + +static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc) +{ + MigrationState *s = migrate_get_current(); + int64_t bandwidth_limit = s->bandwidth_limit; + + memset(s, 0, sizeof(*s)); + s->bandwidth_limit = bandwidth_limit; + s->blk = blk; + s->shared = inc; + + /* s->mon is used for two things: + - pass fd in fd migration + - suspend/resume monitor for not detached migration + */ + s->mon = mon; + s->bandwidth_limit = bandwidth_limit; + s->state = MIG_STATE_SETUP; + + if (!detach) { + migrate_fd_monitor_suspend(s, mon); + } + + return s; +} + +static GSList *migration_blockers; + +void migrate_add_blocker(Error *reason) +{ + migration_blockers = g_slist_prepend(migration_blockers, reason); +} + +void migrate_del_blocker(Error *reason) { - if (current_migration) { - return migrate_fd_get_status(current_migration); + migration_blockers = g_slist_remove(migration_blockers, reason); +} + +int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + MigrationState *s = migrate_get_current(); + const char *p; + int detach = qdict_get_try_bool(qdict, "detach", 0); + int blk = qdict_get_try_bool(qdict, "blk", 0); + int inc = qdict_get_try_bool(qdict, "inc", 0); + const char *uri = qdict_get_str(qdict, "uri"); + int ret; + + if (s->state == MIG_STATE_ACTIVE) { + monitor_printf(mon, "migration already in progress\n"); + return -1; + } + + if (qemu_savevm_state_blocked(mon)) { + return -1; + } + + if (migration_blockers) { + Error *err = migration_blockers->data; + qerror_report_err(err); + return -1; + } + + s = migrate_init(mon, detach, blk, inc); + + if (strstart(uri, "tcp:", &p)) { + ret = tcp_start_outgoing_migration(s, p); +#if !defined(WIN32) + } else if (strstart(uri, "exec:", &p)) { + ret = exec_start_outgoing_migration(s, p); + } else if (strstart(uri, "unix:", &p)) { + ret = unix_start_outgoing_migration(s, p); + } else if (strstart(uri, "fd:", &p)) { + ret = fd_start_outgoing_migration(s, p); +#endif } else { - return MIG_STATE_ERROR; + monitor_printf(mon, "unknown migration protocol: %s\n", uri); + ret = -EINVAL; + } + + if (ret < 0) { + monitor_printf(mon, "migration failed: %s\n", strerror(-ret)); + return ret; } + + if (detach) { + s->mon = NULL; + } + + notifier_list_notify(&migration_state_notifiers, s); + return 0; +} + +int do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + migrate_fd_cancel(migrate_get_current()); + return 0; +} + +int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + int64_t d; + MigrationState *s; + + d = qdict_get_int(qdict, "value"); + if (d < 0) { + d = 0; + } + + s = migrate_get_current(); + s->bandwidth_limit = d; + qemu_file_set_rate_limit(s->file, s->bandwidth_limit); + + return 0; +} + +int do_migrate_set_downtime(Monitor *mon, const QDict *qdict, + QObject **ret_data) +{ + double d; + + d = qdict_get_double(qdict, "value") * 1e9; + d = MAX(0, MIN(UINT64_MAX, d)); + max_downtime = (uint64_t)d; + + return 0; } diff --git a/migration.h b/migration.h index 2170792..0682179 100644 --- a/migration.h +++ b/migration.h @@ -17,38 +17,23 @@ #include "qdict.h" #include "qemu-common.h" #include "notify.h" - -#define MIG_STATE_ERROR -1 -#define MIG_STATE_COMPLETED 0 -#define MIG_STATE_CANCELLED 1 -#define MIG_STATE_ACTIVE 2 +#include "error.h" typedef struct MigrationState MigrationState; struct MigrationState { - /* FIXME: add more accessors to print migration info */ - void (*cancel)(MigrationState *s); - int (*get_status)(MigrationState *s); - void (*release)(MigrationState *s); - int blk; - int shared; -}; - -typedef struct FdMigrationState FdMigrationState; - -struct FdMigrationState -{ - MigrationState mig_state; int64_t bandwidth_limit; QEMUFile *file; int fd; Monitor *mon; int state; - int (*get_error)(struct FdMigrationState*); - int (*close)(struct FdMigrationState*); - int (*write)(struct FdMigrationState*, const void *, size_t); + int (*get_error)(MigrationState *s); + int (*close)(MigrationState *s); + int (*write)(MigrationState *s, const void *buff, size_t size); void *opaque; + int blk; + int shared; }; void process_incoming_migration(QEMUFile *f); @@ -72,71 +57,51 @@ void do_info_migrate(Monitor *mon, QObject **ret_data); int exec_start_incoming_migration(const char *host_port); -MigrationState *exec_start_outgoing_migration(Monitor *mon, - const char *host_port, - int64_t bandwidth_limit, - int detach, - int blk, - int inc); +int exec_start_outgoing_migration(MigrationState *s, const char *host_port); int tcp_start_incoming_migration(const char *host_port); -MigrationState *tcp_start_outgoing_migration(Monitor *mon, - const char *host_port, - int64_t bandwidth_limit, - int detach, - int blk, - int inc); +int tcp_start_outgoing_migration(MigrationState *s, const char *host_port); int unix_start_incoming_migration(const char *path); -MigrationState *unix_start_outgoing_migration(Monitor *mon, - const char *path, - int64_t bandwidth_limit, - int detach, - int blk, - int inc); +int unix_start_outgoing_migration(MigrationState *s, const char *path); int fd_start_incoming_migration(const char *path); -MigrationState *fd_start_outgoing_migration(Monitor *mon, - const char *fdname, - int64_t bandwidth_limit, - int detach, - int blk, - int inc); - -void migrate_fd_monitor_suspend(FdMigrationState *s, Monitor *mon); - -void migrate_fd_error(FdMigrationState *s); - -int migrate_fd_cleanup(FdMigrationState *s); +int fd_start_outgoing_migration(MigrationState *s, const char *fdname); -void migrate_fd_put_notify(void *opaque); +void migrate_fd_error(MigrationState *s); -ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size); +void migrate_fd_connect(MigrationState *s); -void migrate_fd_connect(FdMigrationState *s); - -void migrate_fd_put_ready(void *opaque); - -int migrate_fd_get_status(MigrationState *mig_state); - -void migrate_fd_cancel(MigrationState *mig_state); +void add_migration_state_change_notifier(Notifier *notify); +void remove_migration_state_change_notifier(Notifier *notify); +bool migration_is_active(MigrationState *); +bool migration_has_finished(MigrationState *); +bool migration_has_failed(MigrationState *); -void migrate_fd_release(MigrationState *mig_state); +uint64_t ram_bytes_remaining(void); +uint64_t ram_bytes_transferred(void); +uint64_t ram_bytes_total(void); -void migrate_fd_wait_for_unfreeze(void *opaque); +int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque); +int ram_load(QEMUFile *f, void *opaque, int version_id); -int migrate_fd_close(void *opaque); +extern int incoming_expected; -static inline FdMigrationState *migrate_to_fms(MigrationState *mig_state) -{ - return container_of(mig_state, FdMigrationState, mig_state); -} +/** + * @migrate_add_blocker - prevent migration from proceeding + * + * @reason - an error to be returned whenever migration is attempted + */ +void migrate_add_blocker(Error *reason); -void add_migration_state_change_notifier(Notifier *notify); -void remove_migration_state_change_notifier(Notifier *notify); -int get_migration_state(void); +/** + * @migrate_del_blocker - remove a blocking error from migration + * + * @reason - the error blocking migration + */ +void migrate_del_blocker(Error *reason); #endif diff --git a/mips-dis.c b/mips-dis.c index 4d8e85b..e3a6e0b 100644 --- a/mips-dis.c +++ b/mips-dis.c @@ -4841,7 +4841,7 @@ with the -M switch (multiple options should be separated by commas):\n")); Default: based on binary being disassembled.\n")); fprintf (stream, _("\n\ - hwr-names=ARCH Print HWR names according to specified \n\ + hwr-names=ARCH Print HWR names according to specified\n\ architecture.\n\ Default: based on binary being disassembled.\n")); diff --git a/mips.ld b/mips.ld index 4294761..7b610ce 100644 --- a/mips.ld +++ b/mips.ld @@ -79,36 +79,34 @@ SECTIONS } .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. */ . = ALIGN (0x40000) - ((0x40000 - .) & (0x40000 - 1)); . = DATA_SEGMENT_ALIGN (0x40000, 0x1000); /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } /* Thread Local Storage sections */ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } .preinit_array : { - PROVIDE_HIDDEN (__preinit_array_start = .); + PROVIDE (__preinit_array_start = .); KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE (__preinit_array_end = .); } .init_array : { - PROVIDE_HIDDEN (__init_array_start = .); + PROVIDE (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE (__init_array_end = .); } .fini_array : { - PROVIDE_HIDDEN (__fini_array_start = .); + PROVIDE (__fini_array_start = .); KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE (__fini_array_end = .); } .ctors : { diff --git a/module.c b/module.c index e77d569..91f0e61 100644 --- a/module.c +++ b/module.c @@ -59,7 +59,7 @@ void register_module_init(void (*fn)(void), module_init_type type) ModuleEntry *e; ModuleTypeList *l; - e = qemu_mallocz(sizeof(*e)); + e = g_malloc0(sizeof(*e)); e->init = fn; l = find_type(type); diff --git a/module.h b/module.h index 9263f1c..ef66730 100644 --- a/module.h +++ b/module.h @@ -24,12 +24,14 @@ typedef enum { MODULE_INIT_BLOCK, MODULE_INIT_DEVICE, MODULE_INIT_MACHINE, + MODULE_INIT_QAPI, MODULE_INIT_MAX } module_init_type; #define block_init(function) module_init(function, MODULE_INIT_BLOCK) #define device_init(function) module_init(function, MODULE_INIT_DEVICE) #define machine_init(function) module_init(function, MODULE_INIT_MACHINE) +#define qapi_init(function) module_init(function, MODULE_INIT_QAPI) void register_module_init(void (*fn)(void), module_init_type type); diff --git a/monitor.c b/monitor.c index 7fc311d..1be222e 100644 --- a/monitor.c +++ b/monitor.c @@ -56,11 +56,22 @@ #include "json-streamer.h" #include "json-parser.h" #include "osdep.h" -#include "exec-all.h" -#ifdef CONFIG_SIMPLE_TRACE +#include "cpu.h" #include "trace.h" +#include "trace/control.h" +#ifdef CONFIG_TRACE_SIMPLE +#include "trace/simple.h" #endif #include "ui/qemu-spice.h" +#include "memory.h" +#include "qmp-commands.h" +#include "hmp.h" + +/* for pic/irq_info */ +#if defined(TARGET_SPARC) +#include "hw/sun4m.h" +#endif +#include "hw/lm32_pic.h" //#define DEBUG //#define DEBUG_COMPLETION @@ -112,13 +123,12 @@ typedef struct mon_cmd_t { void (*user_print)(Monitor *mon, const QObject *data); union { void (*info)(Monitor *mon); - void (*info_new)(Monitor *mon, QObject **ret_data); - int (*info_async)(Monitor *mon, MonitorCompletion *cb, void *opaque); void (*cmd)(Monitor *mon, const QDict *qdict); int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data); int (*cmd_async)(Monitor *mon, const QDict *params, MonitorCompletion *cb, void *opaque); } mhandler; + bool qapi; int flags; } mon_cmd_t; @@ -189,11 +199,10 @@ static inline int mon_print_count_get(const Monitor *mon) { return 0; } static QLIST_HEAD(mon_list, Monitor) mon_list; -static const mon_cmd_t mon_cmds[]; -static const mon_cmd_t info_cmds[]; +static mon_cmd_t mon_cmds[]; +static mon_cmd_t info_cmds[]; static const mon_cmd_t qmp_cmds[]; -static const mon_cmd_t qmp_query_cmds[]; Monitor *cur_mon; Monitor *default_mon; @@ -247,7 +256,7 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, void monitor_flush(Monitor *mon) { if (mon && mon->outbuf_index != 0 && !mon->mux_out) { - qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index); + qemu_chr_fe_write(mon->chr, mon->outbuf, mon->outbuf_index); mon->outbuf_index = 0; } } @@ -367,6 +376,8 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data) { QDict *qmp; + trace_monitor_protocol_emitter(mon); + qmp = qdict_new(); if (!monitor_has_error(mon)) { @@ -500,7 +511,6 @@ static int do_qmp_capabilities(Monitor *mon, const QDict *params, return 0; } -static int mon_set_cpu(int cpu_index); static void handle_user_command(Monitor *mon, const char *cmdline); static int do_hmp_passthrough(Monitor *mon, const QDict *params, @@ -518,7 +528,7 @@ static int do_hmp_passthrough(Monitor *mon, const QDict *params, cur_mon = &hmp; if (qdict_haskey(params, "cpu-index")) { - ret = mon_set_cpu(qdict_get_int(params, "cpu-index")); + ret = monitor_set_cpu(qdict_get_int(params, "cpu-index")); if (ret < 0) { cur_mon = old_mon; qerror_report(QERR_INVALID_PARAMETER_VALUE, "cpu-index", "a CPU number"); @@ -592,18 +602,18 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict) help_cmd(mon, qdict_get_try_str(qdict, "name")); } -#ifdef CONFIG_SIMPLE_TRACE -static void do_change_trace_event_state(Monitor *mon, const QDict *qdict) +static void do_trace_event_set_state(Monitor *mon, const QDict *qdict) { const char *tp_name = qdict_get_str(qdict, "name"); bool new_state = qdict_get_bool(qdict, "option"); - int ret = st_change_trace_event_state(tp_name, new_state); + int ret = trace_event_set_state(tp_name, new_state); if (!ret) { monitor_printf(mon, "unknown event name \"%s\"\n", tp_name); } } +#ifdef CONFIG_TRACE_SIMPLE static void do_trace_file(Monitor *mon, const QDict *qdict) { const char *op = qdict_get_try_str(qdict, "op"); @@ -636,7 +646,7 @@ static void user_monitor_complete(void *opaque, QObject *ret_data) data->user_print(data->mon, ret_data); } monitor_resume(data->mon); - qemu_free(data); + g_free(data); } static void qmp_monitor_complete(void *opaque, QObject *ret_data) @@ -650,17 +660,12 @@ static int qmp_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd, return cmd->mhandler.cmd_async(mon, params, qmp_monitor_complete, mon); } -static void qmp_async_info_handler(Monitor *mon, const mon_cmd_t *cmd) -{ - cmd->mhandler.info_async(mon, qmp_monitor_complete, mon); -} - static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd, const QDict *params) { int ret; - MonitorCompletionData *cb_data = qemu_malloc(sizeof(*cb_data)); + MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data)); cb_data->mon = mon; cb_data->user_print = cmd->user_print; monitor_suspend(mon); @@ -668,22 +673,7 @@ static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd, user_monitor_complete, cb_data); if (ret < 0) { monitor_resume(mon); - qemu_free(cb_data); - } -} - -static void user_async_info_handler(Monitor *mon, const mon_cmd_t *cmd) -{ - int ret; - - MonitorCompletionData *cb_data = qemu_malloc(sizeof(*cb_data)); - cb_data->mon = mon; - cb_data->user_print = cmd->user_print; - monitor_suspend(mon); - ret = cmd->mhandler.info_async(mon, user_monitor_complete, cb_data); - if (ret < 0) { - monitor_resume(mon); - qemu_free(cb_data); + g_free(cb_data); } } @@ -705,129 +695,32 @@ static void do_info(Monitor *mon, const QDict *qdict) goto help; } - if (handler_is_async(cmd)) { - user_async_info_handler(mon, cmd); - } else if (handler_is_qobject(cmd)) { - QObject *info_data = NULL; - - cmd->mhandler.info_new(mon, &info_data); - if (info_data) { - cmd->user_print(mon, info_data); - qobject_decref(info_data); - } - } else { - cmd->mhandler.info(mon); - } - + cmd->mhandler.info(mon); return; help: help_cmd(mon, "info"); } -static void do_info_version_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - QDict *qemu; - - qdict = qobject_to_qdict(data); - qemu = qdict_get_qdict(qdict, "qemu"); - - monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n", - qdict_get_int(qemu, "major"), - qdict_get_int(qemu, "minor"), - qdict_get_int(qemu, "micro"), - qdict_get_str(qdict, "package")); -} - -static void do_info_version(Monitor *mon, QObject **ret_data) +CommandInfoList *qmp_query_commands(Error **errp) { - const char *version = QEMU_VERSION; - int major = 0, minor = 0, micro = 0; - char *tmp; - - major = strtol(version, &tmp, 10); - tmp++; - minor = strtol(tmp, &tmp, 10); - tmp++; - micro = strtol(tmp, &tmp, 10); - - *ret_data = qobject_from_jsonf("{ 'qemu': { 'major': %d, 'minor': %d, \ - 'micro': %d }, 'package': %s }", major, minor, micro, QEMU_PKGVERSION); -} - -static void do_info_name_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - - qdict = qobject_to_qdict(data); - if (qdict_size(qdict) == 0) { - return; - } - - monitor_printf(mon, "%s\n", qdict_get_str(qdict, "name")); -} - -static void do_info_name(Monitor *mon, QObject **ret_data) -{ - *ret_data = qemu_name ? qobject_from_jsonf("{'name': %s }", qemu_name) : - qobject_from_jsonf("{}"); -} - -static QObject *get_cmd_dict(const char *name) -{ - const char *p; - - /* Remove '|' from some commands */ - p = strchr(name, '|'); - if (p) { - p++; - } else { - p = name; - } - - return qobject_from_jsonf("{ 'name': %s }", p); -} - -static void do_info_commands(Monitor *mon, QObject **ret_data) -{ - QList *cmd_list; + CommandInfoList *info, *cmd_list = NULL; const mon_cmd_t *cmd; - cmd_list = qlist_new(); - for (cmd = qmp_cmds; cmd->name != NULL; cmd++) { - qlist_append_obj(cmd_list, get_cmd_dict(cmd->name)); - } + info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->name = g_strdup(cmd->name); - for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) { - char buf[128]; - snprintf(buf, sizeof(buf), "query-%s", cmd->name); - qlist_append_obj(cmd_list, get_cmd_dict(buf)); + info->next = cmd_list; + cmd_list = info; } - *ret_data = QOBJECT(cmd_list); + return cmd_list; } -static void do_info_uuid_print(Monitor *mon, const QObject *data) -{ - monitor_printf(mon, "%s\n", qdict_get_str(qobject_to_qdict(data), "UUID")); -} - -static void do_info_uuid(Monitor *mon, QObject **ret_data) -{ - char uuid[64]; - - snprintf(uuid, sizeof(uuid), UUID_FMT, qemu_uuid[0], qemu_uuid[1], - qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], - qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], - qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], - qemu_uuid[14], qemu_uuid[15]); - *ret_data = qobject_from_jsonf("{ 'UUID': %s }", uuid); -} - -/* get the current CPU defined by the user */ -static int mon_set_cpu(int cpu_index) +/* set the current CPU defined by the user */ +int monitor_set_cpu(int cpu_index) { CPUState *env; @@ -843,12 +736,17 @@ static int mon_set_cpu(int cpu_index) static CPUState *mon_get_cpu(void) { if (!cur_mon->mon_cpu) { - mon_set_cpu(0); + monitor_set_cpu(0); } cpu_synchronize_state(cur_mon->mon_cpu); return cur_mon->mon_cpu; } +int monitor_get_cpu_index(void) +{ + return mon_get_cpu()->cpu_index; +} + static void do_info_registers(Monitor *mon) { CPUState *env; @@ -862,103 +760,6 @@ static void do_info_registers(Monitor *mon) #endif } -static void print_cpu_iter(QObject *obj, void *opaque) -{ - QDict *cpu; - int active = ' '; - Monitor *mon = opaque; - - assert(qobject_type(obj) == QTYPE_QDICT); - cpu = qobject_to_qdict(obj); - - if (qdict_get_bool(cpu, "current")) { - active = '*'; - } - - monitor_printf(mon, "%c CPU #%d: ", active, (int)qdict_get_int(cpu, "CPU")); - -#if defined(TARGET_I386) - monitor_printf(mon, "pc=0x" TARGET_FMT_lx, - (target_ulong) qdict_get_int(cpu, "pc")); -#elif defined(TARGET_PPC) - monitor_printf(mon, "nip=0x" TARGET_FMT_lx, - (target_long) qdict_get_int(cpu, "nip")); -#elif defined(TARGET_SPARC) - monitor_printf(mon, "pc=0x " TARGET_FMT_lx, - (target_long) qdict_get_int(cpu, "pc")); - monitor_printf(mon, "npc=0x" TARGET_FMT_lx, - (target_long) qdict_get_int(cpu, "npc")); -#elif defined(TARGET_MIPS) - monitor_printf(mon, "PC=0x" TARGET_FMT_lx, - (target_long) qdict_get_int(cpu, "PC")); -#endif - - if (qdict_get_bool(cpu, "halted")) { - monitor_printf(mon, " (halted)"); - } - - monitor_printf(mon, "\n"); -} - -static void monitor_print_cpus(Monitor *mon, const QObject *data) -{ - QList *cpu_list; - - assert(qobject_type(data) == QTYPE_QLIST); - cpu_list = qobject_to_qlist(data); - qlist_iter(cpu_list, print_cpu_iter, mon); -} - -static void do_info_cpus(Monitor *mon, QObject **ret_data) -{ - CPUState *env; - QList *cpu_list; - - cpu_list = qlist_new(); - - /* just to set the default cpu if not already done */ - mon_get_cpu(); - - for(env = first_cpu; env != NULL; env = env->next_cpu) { - QDict *cpu; - QObject *obj; - - cpu_synchronize_state(env); - - obj = qobject_from_jsonf("{ 'CPU': %d, 'current': %i, 'halted': %i }", - env->cpu_index, env == mon->mon_cpu, - env->halted); - - cpu = qobject_to_qdict(obj); - -#if defined(TARGET_I386) - qdict_put(cpu, "pc", qint_from_int(env->eip + env->segs[R_CS].base)); -#elif defined(TARGET_PPC) - qdict_put(cpu, "nip", qint_from_int(env->nip)); -#elif defined(TARGET_SPARC) - qdict_put(cpu, "pc", qint_from_int(env->pc)); - qdict_put(cpu, "npc", qint_from_int(env->npc)); -#elif defined(TARGET_MIPS) - qdict_put(cpu, "PC", qint_from_int(env->active_tc.PC)); -#endif - - qlist_append(cpu_list, cpu); - } - - *ret_data = QOBJECT(cpu_list); -} - -static int do_cpu_set(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - int index = qdict_get_int(qdict, "index"); - if (mon_set_cpu(index) < 0) { - qerror_report(QERR_INVALID_PARAMETER_VALUE, "index", - "a CPU number"); - return -1; - } - return 0; -} - static void do_info_jit(Monitor *mon) { dump_exec_info((FILE *)mon, monitor_fprintf); @@ -992,30 +793,19 @@ static void do_info_cpu_stats(Monitor *mon) } #endif -#if defined(CONFIG_SIMPLE_TRACE) +#if defined(CONFIG_TRACE_SIMPLE) static void do_info_trace(Monitor *mon) { st_print_trace((FILE *)mon, &monitor_fprintf); } - -static void do_info_trace_events(Monitor *mon) -{ - st_print_trace_events((FILE *)mon, &monitor_fprintf); -} #endif -/** - * do_quit(): Quit QEMU execution - */ -static int do_quit(Monitor *mon, const QDict *qdict, QObject **ret_data) +static void do_trace_print_events(Monitor *mon) { - monitor_suspend(mon); - no_shutdown = 0; - qemu_system_shutdown_request(); - - return 0; + trace_print_events((FILE *)mon, &monitor_fprintf); } +#ifdef CONFIG_VNC static int change_vnc_password(const char *password) { if (!password || !password[0]) { @@ -1062,6 +852,13 @@ static int do_change_vnc(Monitor *mon, const char *target, const char *arg) return 0; } +#else +static int do_change_vnc(Monitor *mon, const char *target, const char *arg) +{ + qerror_report(QERR_FEATURE_DISABLED, "vnc"); + return -ENODEV; +} +#endif /** * do_change(): Change a removable medium, or VNC configuration @@ -1127,12 +924,7 @@ static int set_password(Monitor *mon, const QDict *qdict, QObject **ret_data) } /* Note that setting an empty password will not disable login through * this interface. */ - rc = vnc_display_password(NULL, password); - if (rc != 0) { - qerror_report(QERR_SET_PASSWD_FAILED); - return -1; - } - return 0; + return vnc_display_password(NULL, password); } qerror_report(QERR_INVALID_PARAMETER, "protocol"); @@ -1171,19 +963,49 @@ static int expire_password(Monitor *mon, const QDict *qdict, QObject **ret_data) } if (strcmp(protocol, "vnc") == 0) { - rc = vnc_display_pw_expire(NULL, when); - if (rc != 0) { - qerror_report(QERR_SET_PASSWD_FAILED); + return vnc_display_pw_expire(NULL, when); + } + + qerror_report(QERR_INVALID_PARAMETER, "protocol"); + return -1; +} + +static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + const char *protocol = qdict_get_str(qdict, "protocol"); + const char *fdname = qdict_get_str(qdict, "fdname"); + CharDriverState *s; + + if (strcmp(protocol, "spice") == 0) { + if (!using_spice) { + /* correct one? spice isn't a device ,,, */ + qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice"); return -1; } - return 0; + qerror_report(QERR_ADD_CLIENT_FAILED); + return -1; +#ifdef CONFIG_VNC + } else if (strcmp(protocol, "vnc") == 0) { + int fd = monitor_get_fd(mon, fdname); + int skipauth = qdict_get_try_bool(qdict, "skipauth", 0); + vnc_display_add_client(NULL, fd, skipauth); + return 0; +#endif + } else if ((s = qemu_chr_find(protocol)) != NULL) { + int fd = monitor_get_fd(mon, fdname); + if (qemu_chr_add_client(s, fd) < 0) { + qerror_report(QERR_ADD_CLIENT_FAILED); + return -1; + } + return 0; } qerror_report(QERR_INVALID_PARAMETER, "protocol"); return -1; } -static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_data) +static int client_migrate_info(Monitor *mon, const QDict *qdict, + MonitorCompletion cb, void *opaque) { const char *protocol = qdict_get_str(qdict, "protocol"); const char *hostname = qdict_get_str(qdict, "hostname"); @@ -1198,7 +1020,8 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_d return -1; } - ret = qemu_spice_migrate_info(hostname, port, tls_port, subject); + ret = qemu_spice_migrate_info(hostname, port, tls_port, subject, + cb, opaque); if (ret != 0) { qerror_report(QERR_UNDEFINED_ERROR); return -1; @@ -1250,15 +1073,6 @@ static void do_singlestep(Monitor *mon, const QDict *qdict) } } -/** - * do_stop(): Stop VM execution - */ -static int do_stop(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - vm_stop(EXCP_INTERRUPT); - return 0; -} - static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs); struct bdrv_iterate_context { @@ -1266,6 +1080,11 @@ struct bdrv_iterate_context { int err; }; +static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +{ + bdrv_iostatus_reset(bs); +} + /** * do_cont(): Resume emulation. */ @@ -1273,10 +1092,16 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) { struct bdrv_iterate_context context = { mon, 0 }; - if (incoming_expected) { + if (runstate_check(RUN_STATE_INMIGRATE)) { qerror_report(QERR_MIGRATION_EXPECTED); return -1; + } else if (runstate_check(RUN_STATE_INTERNAL_ERROR) || + runstate_check(RUN_STATE_SHUTDOWN)) { + qerror_report(QERR_RESET_REQUIRED); + return -1; } + + bdrv_iterate(iostatus_bdrv_it, NULL); bdrv_iterate(encrypted_bdrv_it, &context); /* only resume the vm if all keys are set and valid */ if (!context.err) { @@ -1427,7 +1252,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize, if (l > line_size) l = line_size; if (is_physical) { - cpu_physical_memory_rw(addr, buf, l, 0); + cpu_physical_memory_read(addr, buf, l); } else { env = mon_get_cpu(); if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) { @@ -1603,7 +1428,7 @@ static int do_physical_memory_save(Monitor *mon, const QDict *qdict, l = sizeof(buf); if (l > size) l = size; - cpu_physical_memory_rw(addr, buf, l, 0); + cpu_physical_memory_read(addr, buf, l); if (fwrite(buf, 1, l, f) != l) { monitor_printf(mon, "fwrite() error in do_physical_memory_save\n"); goto exit; @@ -1623,17 +1448,16 @@ exit: static void do_sum(Monitor *mon, const QDict *qdict) { uint32_t addr; - uint8_t buf[1]; uint16_t sum; uint32_t start = qdict_get_int(qdict, "start"); uint32_t size = qdict_get_int(qdict, "size"); sum = 0; for(addr = start; addr < (start + size); addr++) { - cpu_physical_memory_rw(addr, buf, 1, 0); + uint8_t val = ldub_phys(addr); /* BSD sum algorithm ('sum' Unix command) */ sum = (sum >> 1) | (sum << 15); - sum += buf[0]; + sum += val; } monitor_printf(mon, "%05d\n", sum); } @@ -1873,7 +1697,7 @@ static void do_sendkey(Monitor *mon, const QDict *qdict) kbd_put_keycode(keycode & 0x7f); } /* delayed key up events */ - qemu_mod_timer(key_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) + muldiv64(get_ticks_per_sec(), hold_time, 1000)); } @@ -1973,16 +1797,6 @@ static void do_boot_set(Monitor *mon, const QDict *qdict) } /** - * do_system_reset(): Issue a machine reset - */ -static int do_system_reset(Monitor *mon, const QDict *qdict, - QObject **ret_data) -{ - qemu_system_reset_request(); - return 0; -} - -/** * do_system_powerdown(): Issue a machine powerdown */ static int do_system_powerdown(Monitor *mon, const QDict *qdict, @@ -2019,12 +1833,12 @@ static void print_pte(Monitor *mon, target_phys_addr_t addr, static void tlb_info_32(Monitor *mon, CPUState *env) { - int l1, l2; + unsigned int l1, l2; uint32_t pgd, pde, pte; pgd = env->cr[3] & ~0xfff; for(l1 = 0; l1 < 1024; l1++) { - cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4); + cpu_physical_memory_read(pgd + l1 * 4, &pde, 4); pde = le32_to_cpu(pde); if (pde & PG_PRESENT_MASK) { if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { @@ -2032,8 +1846,7 @@ static void tlb_info_32(Monitor *mon, CPUState *env) print_pte(mon, (l1 << 22), pde, ~((1 << 21) - 1)); } else { for(l2 = 0; l2 < 1024; l2++) { - cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, - (uint8_t *)&pte, 4); + cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4); pte = le32_to_cpu(pte); if (pte & PG_PRESENT_MASK) { print_pte(mon, (l1 << 22) + (l2 << 12), @@ -2048,19 +1861,18 @@ static void tlb_info_32(Monitor *mon, CPUState *env) static void tlb_info_pae32(Monitor *mon, CPUState *env) { - int l1, l2, l3; + unsigned int l1, l2, l3; uint64_t pdpe, pde, pte; uint64_t pdp_addr, pd_addr, pt_addr; pdp_addr = env->cr[3] & ~0x1f; for (l1 = 0; l1 < 4; l1++) { - cpu_physical_memory_read(pdp_addr + l1 * 8, (uint8_t *)&pdpe, 8); + cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8); pdpe = le64_to_cpu(pdpe); if (pdpe & PG_PRESENT_MASK) { pd_addr = pdpe & 0x3fffffffff000ULL; for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pd_addr + l2 * 8, - (uint8_t *)&pde, 8); + cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8); pde = le64_to_cpu(pde); if (pde & PG_PRESENT_MASK) { if (pde & PG_PSE_MASK) { @@ -2070,8 +1882,7 @@ static void tlb_info_pae32(Monitor *mon, CPUState *env) } else { pt_addr = pde & 0x3fffffffff000ULL; for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pt_addr + l3 * 8, - (uint8_t *)&pte, 8); + cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8); pte = le64_to_cpu(pte); if (pte & PG_PRESENT_MASK) { print_pte(mon, (l1 << 30 ) + (l2 << 21) @@ -2096,13 +1907,12 @@ static void tlb_info_64(Monitor *mon, CPUState *env) pml4_addr = env->cr[3] & 0x3fffffffff000ULL; for (l1 = 0; l1 < 512; l1++) { - cpu_physical_memory_read(pml4_addr + l1 * 8, (uint8_t *)&pml4e, 8); + cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); pml4e = le64_to_cpu(pml4e); if (pml4e & PG_PRESENT_MASK) { pdp_addr = pml4e & 0x3fffffffff000ULL; for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pdp_addr + l2 * 8, (uint8_t *)&pdpe, - 8); + cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); pdpe = le64_to_cpu(pdpe); if (pdpe & PG_PRESENT_MASK) { if (pdpe & PG_PSE_MASK) { @@ -2112,8 +1922,7 @@ static void tlb_info_64(Monitor *mon, CPUState *env) } else { pd_addr = pdpe & 0x3fffffffff000ULL; for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pd_addr + l3 * 8, - (uint8_t *)&pde, 8); + cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); pde = le64_to_cpu(pde); if (pde & PG_PRESENT_MASK) { if (pde & PG_PSE_MASK) { @@ -2126,8 +1935,7 @@ static void tlb_info_64(Monitor *mon, CPUState *env) for (l4 = 0; l4 < 512; l4++) { cpu_physical_memory_read(pt_addr + l4 * 8, - (uint8_t *)&pte, - 8); + &pte, 8); pte = le64_to_cpu(pte); if (pte & PG_PRESENT_MASK) { print_pte(mon, (l1 << 39) + @@ -2197,7 +2005,8 @@ static void mem_print(Monitor *mon, target_phys_addr_t *pstart, static void mem_info_32(Monitor *mon, CPUState *env) { - int l1, l2, prot, last_prot; + unsigned int l1, l2; + int prot, last_prot; uint32_t pgd, pde, pte; target_phys_addr_t start, end; @@ -2205,7 +2014,7 @@ static void mem_info_32(Monitor *mon, CPUState *env) last_prot = 0; start = -1; for(l1 = 0; l1 < 1024; l1++) { - cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4); + cpu_physical_memory_read(pgd + l1 * 4, &pde, 4); pde = le32_to_cpu(pde); end = l1 << 22; if (pde & PG_PRESENT_MASK) { @@ -2214,12 +2023,12 @@ static void mem_info_32(Monitor *mon, CPUState *env) mem_print(mon, &start, &last_prot, end, prot); } else { for(l2 = 0; l2 < 1024; l2++) { - cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, - (uint8_t *)&pte, 4); + cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4); pte = le32_to_cpu(pte); end = (l1 << 22) + (l2 << 12); if (pte & PG_PRESENT_MASK) { - prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + prot = pte & pde & + (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); } else { prot = 0; } @@ -2231,11 +2040,14 @@ static void mem_info_32(Monitor *mon, CPUState *env) mem_print(mon, &start, &last_prot, end, prot); } } + /* Flush last range */ + mem_print(mon, &start, &last_prot, (target_phys_addr_t)1 << 32, 0); } static void mem_info_pae32(Monitor *mon, CPUState *env) { - int l1, l2, l3, prot, last_prot; + unsigned int l1, l2, l3; + int prot, last_prot; uint64_t pdpe, pde, pte; uint64_t pdp_addr, pd_addr, pt_addr; target_phys_addr_t start, end; @@ -2244,14 +2056,13 @@ static void mem_info_pae32(Monitor *mon, CPUState *env) last_prot = 0; start = -1; for (l1 = 0; l1 < 4; l1++) { - cpu_physical_memory_read(pdp_addr + l1 * 8, (uint8_t *)&pdpe, 8); + cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8); pdpe = le64_to_cpu(pdpe); end = l1 << 30; if (pdpe & PG_PRESENT_MASK) { pd_addr = pdpe & 0x3fffffffff000ULL; for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pd_addr + l2 * 8, - (uint8_t *)&pde, 8); + cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8); pde = le64_to_cpu(pde); end = (l1 << 30) + (l2 << 21); if (pde & PG_PRESENT_MASK) { @@ -2262,13 +2073,12 @@ static void mem_info_pae32(Monitor *mon, CPUState *env) } else { pt_addr = pde & 0x3fffffffff000ULL; for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pt_addr + l3 * 8, - (uint8_t *)&pte, 8); + cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8); pte = le64_to_cpu(pte); end = (l1 << 30) + (l2 << 21) + (l3 << 12); if (pte & PG_PRESENT_MASK) { - prot = pte & (PG_USER_MASK | PG_RW_MASK | - PG_PRESENT_MASK); + prot = pte & pde & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); } else { prot = 0; } @@ -2285,6 +2095,8 @@ static void mem_info_pae32(Monitor *mon, CPUState *env) mem_print(mon, &start, &last_prot, end, prot); } } + /* Flush last range */ + mem_print(mon, &start, &last_prot, (target_phys_addr_t)1 << 32, 0); } @@ -2300,46 +2112,46 @@ static void mem_info_64(Monitor *mon, CPUState *env) last_prot = 0; start = -1; for (l1 = 0; l1 < 512; l1++) { - cpu_physical_memory_read(pml4_addr + l1 * 8, (uint8_t *)&pml4e, 8); + cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); pml4e = le64_to_cpu(pml4e); end = l1 << 39; if (pml4e & PG_PRESENT_MASK) { pdp_addr = pml4e & 0x3fffffffff000ULL; for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pdp_addr + l2 * 8, (uint8_t *)&pdpe, - 8); + cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); pdpe = le64_to_cpu(pdpe); end = (l1 << 39) + (l2 << 30); if (pdpe & PG_PRESENT_MASK) { if (pdpe & PG_PSE_MASK) { prot = pdpe & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + prot &= pml4e; mem_print(mon, &start, &last_prot, end, prot); } else { pd_addr = pdpe & 0x3fffffffff000ULL; for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pd_addr + l3 * 8, - (uint8_t *)&pde, 8); + cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); pde = le64_to_cpu(pde); end = (l1 << 39) + (l2 << 30) + (l3 << 21); if (pde & PG_PRESENT_MASK) { if (pde & PG_PSE_MASK) { prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + prot &= pml4e & pdpe; mem_print(mon, &start, &last_prot, end, prot); } else { pt_addr = pde & 0x3fffffffff000ULL; for (l4 = 0; l4 < 512; l4++) { cpu_physical_memory_read(pt_addr + l4 * 8, - (uint8_t *)&pte, - 8); + &pte, 8); pte = le64_to_cpu(pte); end = (l1 << 39) + (l2 << 30) + (l3 << 21) + (l4 << 12); if (pte & PG_PRESENT_MASK) { prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + prot &= pml4e & pdpe & pde; } else { prot = 0; } @@ -2362,6 +2174,8 @@ static void mem_info_64(Monitor *mon, CPUState *env) mem_print(mon, &start, &last_prot, end, prot); } } + /* Flush last range */ + mem_print(mon, &start, &last_prot, (target_phys_addr_t)1 << 48, 0); } #endif @@ -2419,7 +2233,7 @@ static void tlb_info(Monitor *mon) #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_PPC) static void tlb_info(Monitor *mon) { CPUState *env1 = mon_get_cpu(); @@ -2428,29 +2242,9 @@ static void tlb_info(Monitor *mon) } #endif -static void do_info_kvm_print(Monitor *mon, const QObject *data) +static void do_info_mtree(Monitor *mon) { - QDict *qdict; - - qdict = qobject_to_qdict(data); - - monitor_printf(mon, "kvm support: "); - if (qdict_get_bool(qdict, "present")) { - monitor_printf(mon, "%s\n", qdict_get_bool(qdict, "enabled") ? - "enabled" : "disabled"); - } else { - monitor_printf(mon, "not compiled\n"); - } -} - -static void do_info_kvm(Monitor *mon, QObject **ret_data) -{ -#ifdef CONFIG_KVM - *ret_data = qobject_from_jsonf("{ 'enabled': %i, 'present': true }", - kvm_enabled()); -#else - *ret_data = qobject_from_jsonf("{ 'enabled': false, 'present': false }"); -#endif + mtree_info((fprintf_function)monitor_printf, mon); } static void do_info_numa(Monitor *mon) @@ -2522,7 +2316,7 @@ static void do_stop_capture(Monitor *mon, const QDict *qdict) if (i == n) { s->ops.destroy (s->opaque); QLIST_REMOVE (s, entries); - qemu_free (s); + g_free (s); return; } } @@ -2539,7 +2333,7 @@ static void do_wav_capture(Monitor *mon, const QDict *qdict) int nchannels = qdict_get_try_int(qdict, "nchannels", -1); CaptureState *s; - s = qemu_mallocz (sizeof (*s)); + s = g_malloc0 (sizeof (*s)); freq = has_freq ? freq : 44100; bits = has_bits ? bits : 16; @@ -2547,7 +2341,7 @@ static void do_wav_capture(Monitor *mon, const QDict *qdict) if (wav_start_capture (s, path, freq, bits, nchannels)) { monitor_printf(mon, "Failed to add wave capture\n"); - qemu_free (s); + g_free (s); return; } QLIST_INSERT_HEAD (&capture_head, s, entries); @@ -2555,43 +2349,23 @@ static void do_wav_capture(Monitor *mon, const QDict *qdict) #endif #if defined(TARGET_I386) -static void do_inject_nmi(Monitor *mon, const QDict *qdict) +static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data) { CPUState *env; - int cpu_index = qdict_get_int(qdict, "cpu_index"); - for (env = first_cpu; env != NULL; env = env->next_cpu) - if (env->cpu_index == cpu_index) { - cpu_interrupt(env, CPU_INTERRUPT_NMI); - break; - } -} -#endif - -static void do_info_status_print(Monitor *mon, const QObject *data) -{ - QDict *qdict; - - qdict = qobject_to_qdict(data); - - monitor_printf(mon, "VM status: "); - if (qdict_get_bool(qdict, "running")) { - monitor_printf(mon, "running"); - if (qdict_get_bool(qdict, "singlestep")) { - monitor_printf(mon, " (single step mode)"); - } - } else { - monitor_printf(mon, "paused"); + for (env = first_cpu; env != NULL; env = env->next_cpu) { + cpu_interrupt(env, CPU_INTERRUPT_NMI); } - monitor_printf(mon, "\n"); + return 0; } - -static void do_info_status(Monitor *mon, QObject **ret_data) +#else +static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data) { - *ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i }", - vm_running, singlestep); + qerror_report(QERR_UNSUPPORTED); + return -1; } +#endif static qemu_acl *find_acl(Monitor *mon, const char *name) { @@ -2709,12 +2483,15 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict) uint64_t mcg_status = qdict_get_int(qdict, "mcg_status"); uint64_t addr = qdict_get_int(qdict, "addr"); uint64_t misc = qdict_get_int(qdict, "misc"); - int broadcast = qdict_get_try_bool(qdict, "broadcast", 0); + int flags = MCE_INJECT_UNCOND_AO; + if (qdict_get_try_bool(qdict, "broadcast", 0)) { + flags |= MCE_INJECT_BROADCAST; + } for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) { - if (cenv->cpu_index == cpu_index && cenv->mcg_cap) { - cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, - broadcast); + if (cenv->cpu_index == cpu_index) { + cpu_x86_inject_mce(mon, cenv, bank, status, mcg_status, addr, misc, + flags); break; } } @@ -2727,7 +2504,7 @@ static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data) mon_fd_t *monfd; int fd; - fd = qemu_chr_get_msgfd(mon->chr); + fd = qemu_chr_fe_get_msgfd(mon->chr); if (fd == -1) { qerror_report(QERR_FD_NOT_SUPPLIED); return -1; @@ -2749,8 +2526,8 @@ static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data) return 0; } - monfd = qemu_mallocz(sizeof(mon_fd_t)); - monfd->name = qemu_strdup(fdname); + monfd = g_malloc0(sizeof(mon_fd_t)); + monfd->name = g_strdup(fdname); monfd->fd = fd; QLIST_INSERT_HEAD(&mon->fds, monfd, next); @@ -2769,8 +2546,8 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data) QLIST_REMOVE(monfd, next); close(monfd->fd); - qemu_free(monfd->name); - qemu_free(monfd); + g_free(monfd->name); + g_free(monfd); return 0; } @@ -2780,10 +2557,10 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data) static void do_loadvm(Monitor *mon, const QDict *qdict) { - int saved_vm_running = vm_running; + int saved_vm_running = runstate_is_running(); const char *name = qdict_get_str(qdict, "name"); - vm_stop(0); + vm_stop(RUN_STATE_RESTORE_VM); if (load_vmstate(name) == 0 && saved_vm_running) { vm_start(); @@ -2805,8 +2582,8 @@ int monitor_get_fd(Monitor *mon, const char *fdname) /* caller takes ownership of fd */ QLIST_REMOVE(monfd, next); - qemu_free(monfd->name); - qemu_free(monfd); + g_free(monfd->name); + g_free(monfd); return fd; } @@ -2814,20 +2591,20 @@ int monitor_get_fd(Monitor *mon, const char *fdname) return -1; } -static const mon_cmd_t mon_cmds[] = { +/* mon_cmds and info_cmds would be sorted at runtime */ +static mon_cmd_t mon_cmds[] = { #include "hmp-commands.h" { NULL, NULL, }, }; /* Please update hmp-commands.hx when adding or changing commands */ -static const mon_cmd_t info_cmds[] = { +static mon_cmd_t info_cmds[] = { { .name = "version", .args_type = "", .params = "", .help = "show the version of QEMU", - .user_print = do_info_version_print, - .mhandler.info_new = do_info_version, + .mhandler.info = hmp_info_version, }, { .name = "network", @@ -2841,24 +2618,21 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the character devices", - .user_print = qemu_chr_info_print, - .mhandler.info_new = qemu_chr_info, + .mhandler.info = hmp_info_chardev, }, { .name = "block", .args_type = "", .params = "", .help = "show the block devices", - .user_print = bdrv_info_print, - .mhandler.info_new = bdrv_info, + .mhandler.info = hmp_info_block, }, { .name = "blockstats", .args_type = "", .params = "", .help = "show block device statistics", - .user_print = bdrv_stats_print, - .mhandler.info_new = bdrv_info_stats, + .mhandler.info = hmp_info_blockstats, }, { .name = "registers", @@ -2872,8 +2646,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show infos for each CPU", - .user_print = monitor_print_cpus, - .mhandler.info_new = do_info_cpus, + .mhandler.info = hmp_info_cpus, }, { .name = "history", @@ -2882,29 +2655,44 @@ static const mon_cmd_t info_cmds[] = { .help = "show the command line history", .mhandler.info = do_info_history, }, +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \ + defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64)) { .name = "irq", .args_type = "", .params = "", .help = "show the interrupts statistics (if available)", +#ifdef TARGET_SPARC + .mhandler.info = sun4m_irq_info, +#elif defined(TARGET_LM32) + .mhandler.info = lm32_irq_info, +#else .mhandler.info = irq_info, +#endif }, { .name = "pic", .args_type = "", .params = "", .help = "show i8259 (PIC) state", +#ifdef TARGET_SPARC + .mhandler.info = sun4m_pic_info, +#elif defined(TARGET_LM32) + .mhandler.info = lm32_do_pic_info, +#else .mhandler.info = pic_info, +#endif }, +#endif { .name = "pci", .args_type = "", .params = "", .help = "show PCI info", - .user_print = do_pci_info_print, - .mhandler.info_new = do_pci_info, + .mhandler.info = hmp_info_pci, }, -#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) +#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \ + defined(TARGET_PPC) { .name = "tlb", .args_type = "", @@ -2923,6 +2711,13 @@ static const mon_cmd_t info_cmds[] = { }, #endif { + .name = "mtree", + .args_type = "", + .params = "", + .help = "show memory tree", + .mhandler.info = do_info_mtree, + }, + { .name = "jit", .args_type = "", .params = "", @@ -2934,8 +2729,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show KVM information", - .user_print = do_info_kvm_print, - .mhandler.info_new = do_info_kvm, + .mhandler.info = hmp_info_kvm, }, { .name = "numa", @@ -2984,8 +2778,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the current VM status (running|paused)", - .user_print = do_info_status_print, - .mhandler.info_new = do_info_status, + .mhandler.info = hmp_info_status, }, { .name = "pcmcia", @@ -2999,16 +2792,14 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show which guest mouse is receiving events", - .user_print = do_info_mice_print, - .mhandler.info_new = do_info_mice, + .mhandler.info = hmp_info_mice, }, { .name = "vnc", .args_type = "", .params = "", .help = "show the vnc server status", - .user_print = do_info_vnc_print, - .mhandler.info_new = do_info_vnc, + .mhandler.info = hmp_info_vnc, }, #if defined(CONFIG_SPICE) { @@ -3016,8 +2807,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the spice server status", - .user_print = do_info_spice_print, - .mhandler.info_new = do_info_spice, + .mhandler.info = hmp_info_spice, }, #endif { @@ -3025,16 +2815,14 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the current VM name", - .user_print = do_info_name_print, - .mhandler.info_new = do_info_name, + .mhandler.info = hmp_info_name, }, { .name = "uuid", .args_type = "", .params = "", .help = "show the current VM UUID", - .user_print = do_info_uuid_print, - .mhandler.info_new = do_info_uuid, + .mhandler.info = hmp_info_uuid, }, #if defined(TARGET_PPC) { @@ -3059,17 +2847,14 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show migration status", - .user_print = do_info_migrate_print, - .mhandler.info_new = do_info_migrate, + .mhandler.info = hmp_info_migrate, }, { .name = "balloon", .args_type = "", .params = "", .help = "show balloon information", - .user_print = monitor_print_balloon, - .mhandler.info_async = do_info_balloon, - .flags = MONITOR_CMD_ASYNC, + .mhandler.info = hmp_info_balloon, }, { .name = "qtree", @@ -3092,7 +2877,7 @@ static const mon_cmd_t info_cmds[] = { .help = "show roms", .mhandler.info = do_info_roms, }, -#if defined(CONFIG_SIMPLE_TRACE) +#if defined(CONFIG_TRACE_SIMPLE) { .name = "trace", .args_type = "", @@ -3100,156 +2885,21 @@ static const mon_cmd_t info_cmds[] = { .help = "show current contents of trace buffer", .mhandler.info = do_info_trace, }, +#endif { .name = "trace-events", .args_type = "", .params = "", .help = "show available trace-events & their state", - .mhandler.info = do_info_trace_events, + .mhandler.info = do_trace_print_events, }, -#endif { .name = NULL, }, }; static const mon_cmd_t qmp_cmds[] = { -#include "qmp-commands.h" - { /* NULL */ }, -}; - -static const mon_cmd_t qmp_query_cmds[] = { - { - .name = "version", - .args_type = "", - .params = "", - .help = "show the version of QEMU", - .user_print = do_info_version_print, - .mhandler.info_new = do_info_version, - }, - { - .name = "commands", - .args_type = "", - .params = "", - .help = "list QMP available commands", - .user_print = monitor_user_noop, - .mhandler.info_new = do_info_commands, - }, - { - .name = "chardev", - .args_type = "", - .params = "", - .help = "show the character devices", - .user_print = qemu_chr_info_print, - .mhandler.info_new = qemu_chr_info, - }, - { - .name = "block", - .args_type = "", - .params = "", - .help = "show the block devices", - .user_print = bdrv_info_print, - .mhandler.info_new = bdrv_info, - }, - { - .name = "blockstats", - .args_type = "", - .params = "", - .help = "show block device statistics", - .user_print = bdrv_stats_print, - .mhandler.info_new = bdrv_info_stats, - }, - { - .name = "cpus", - .args_type = "", - .params = "", - .help = "show infos for each CPU", - .user_print = monitor_print_cpus, - .mhandler.info_new = do_info_cpus, - }, - { - .name = "pci", - .args_type = "", - .params = "", - .help = "show PCI info", - .user_print = do_pci_info_print, - .mhandler.info_new = do_pci_info, - }, - { - .name = "kvm", - .args_type = "", - .params = "", - .help = "show KVM information", - .user_print = do_info_kvm_print, - .mhandler.info_new = do_info_kvm, - }, - { - .name = "status", - .args_type = "", - .params = "", - .help = "show the current VM status (running|paused)", - .user_print = do_info_status_print, - .mhandler.info_new = do_info_status, - }, - { - .name = "mice", - .args_type = "", - .params = "", - .help = "show which guest mouse is receiving events", - .user_print = do_info_mice_print, - .mhandler.info_new = do_info_mice, - }, - { - .name = "vnc", - .args_type = "", - .params = "", - .help = "show the vnc server status", - .user_print = do_info_vnc_print, - .mhandler.info_new = do_info_vnc, - }, -#if defined(CONFIG_SPICE) - { - .name = "spice", - .args_type = "", - .params = "", - .help = "show the spice server status", - .user_print = do_info_spice_print, - .mhandler.info_new = do_info_spice, - }, -#endif - { - .name = "name", - .args_type = "", - .params = "", - .help = "show the current VM name", - .user_print = do_info_name_print, - .mhandler.info_new = do_info_name, - }, - { - .name = "uuid", - .args_type = "", - .params = "", - .help = "show the current VM UUID", - .user_print = do_info_uuid_print, - .mhandler.info_new = do_info_uuid, - }, - { - .name = "migrate", - .args_type = "", - .params = "", - .help = "show migration status", - .user_print = do_info_migrate_print, - .mhandler.info_new = do_info_migrate, - }, - { - .name = "balloon", - .args_type = "", - .params = "", - .help = "show balloon information", - .user_print = monitor_print_balloon, - .mhandler.info_async = do_info_balloon, - .flags = MONITOR_CMD_ASYNC, - }, +#include "qmp-commands-old.h" { /* NULL */ }, }; @@ -3457,7 +3107,7 @@ static const MonitorDef monitor_defs[] = { { "asr", offsetof(CPUState, asr) }, #endif /* Segment registers */ - { "sdr1", offsetof(CPUState, sdr1) }, + { "sdr1", offsetof(CPUState, spr[SPR_SDR1]) }, { "sr0", offsetof(CPUState, sr[0]) }, { "sr1", offsetof(CPUState, sr[1]) }, { "sr2", offsetof(CPUState, sr[2]) }, @@ -3474,7 +3124,76 @@ static const MonitorDef monitor_defs[] = { { "sr13", offsetof(CPUState, sr[13]) }, { "sr14", offsetof(CPUState, sr[14]) }, { "sr15", offsetof(CPUState, sr[15]) }, - /* Too lazy to put BATs and SPRs ... */ + /* Too lazy to put BATs... */ + { "pvr", offsetof(CPUState, spr[SPR_PVR]) }, + + { "srr0", offsetof(CPUState, spr[SPR_SRR0]) }, + { "srr1", offsetof(CPUState, spr[SPR_SRR1]) }, + { "sprg0", offsetof(CPUState, spr[SPR_SPRG0]) }, + { "sprg1", offsetof(CPUState, spr[SPR_SPRG1]) }, + { "sprg2", offsetof(CPUState, spr[SPR_SPRG2]) }, + { "sprg3", offsetof(CPUState, spr[SPR_SPRG3]) }, + { "sprg4", offsetof(CPUState, spr[SPR_SPRG4]) }, + { "sprg5", offsetof(CPUState, spr[SPR_SPRG5]) }, + { "sprg6", offsetof(CPUState, spr[SPR_SPRG6]) }, + { "sprg7", offsetof(CPUState, spr[SPR_SPRG7]) }, + { "pid", offsetof(CPUState, spr[SPR_BOOKE_PID]) }, + { "csrr0", offsetof(CPUState, spr[SPR_BOOKE_CSRR0]) }, + { "csrr1", offsetof(CPUState, spr[SPR_BOOKE_CSRR1]) }, + { "esr", offsetof(CPUState, spr[SPR_BOOKE_ESR]) }, + { "dear", offsetof(CPUState, spr[SPR_BOOKE_DEAR]) }, + { "mcsr", offsetof(CPUState, spr[SPR_BOOKE_MCSR]) }, + { "tsr", offsetof(CPUState, spr[SPR_BOOKE_TSR]) }, + { "tcr", offsetof(CPUState, spr[SPR_BOOKE_TCR]) }, + { "vrsave", offsetof(CPUState, spr[SPR_VRSAVE]) }, + { "pir", offsetof(CPUState, spr[SPR_BOOKE_PIR]) }, + { "mcsrr0", offsetof(CPUState, spr[SPR_BOOKE_MCSRR0]) }, + { "mcsrr1", offsetof(CPUState, spr[SPR_BOOKE_MCSRR1]) }, + { "decar", offsetof(CPUState, spr[SPR_BOOKE_DECAR]) }, + { "ivpr", offsetof(CPUState, spr[SPR_BOOKE_IVPR]) }, + { "epcr", offsetof(CPUState, spr[SPR_BOOKE_EPCR]) }, + { "sprg8", offsetof(CPUState, spr[SPR_BOOKE_SPRG8]) }, + { "ivor0", offsetof(CPUState, spr[SPR_BOOKE_IVOR0]) }, + { "ivor1", offsetof(CPUState, spr[SPR_BOOKE_IVOR1]) }, + { "ivor2", offsetof(CPUState, spr[SPR_BOOKE_IVOR2]) }, + { "ivor3", offsetof(CPUState, spr[SPR_BOOKE_IVOR3]) }, + { "ivor4", offsetof(CPUState, spr[SPR_BOOKE_IVOR4]) }, + { "ivor5", offsetof(CPUState, spr[SPR_BOOKE_IVOR5]) }, + { "ivor6", offsetof(CPUState, spr[SPR_BOOKE_IVOR6]) }, + { "ivor7", offsetof(CPUState, spr[SPR_BOOKE_IVOR7]) }, + { "ivor8", offsetof(CPUState, spr[SPR_BOOKE_IVOR8]) }, + { "ivor9", offsetof(CPUState, spr[SPR_BOOKE_IVOR9]) }, + { "ivor10", offsetof(CPUState, spr[SPR_BOOKE_IVOR10]) }, + { "ivor11", offsetof(CPUState, spr[SPR_BOOKE_IVOR11]) }, + { "ivor12", offsetof(CPUState, spr[SPR_BOOKE_IVOR12]) }, + { "ivor13", offsetof(CPUState, spr[SPR_BOOKE_IVOR13]) }, + { "ivor14", offsetof(CPUState, spr[SPR_BOOKE_IVOR14]) }, + { "ivor15", offsetof(CPUState, spr[SPR_BOOKE_IVOR15]) }, + { "ivor32", offsetof(CPUState, spr[SPR_BOOKE_IVOR32]) }, + { "ivor33", offsetof(CPUState, spr[SPR_BOOKE_IVOR33]) }, + { "ivor34", offsetof(CPUState, spr[SPR_BOOKE_IVOR34]) }, + { "ivor35", offsetof(CPUState, spr[SPR_BOOKE_IVOR35]) }, + { "ivor36", offsetof(CPUState, spr[SPR_BOOKE_IVOR36]) }, + { "ivor37", offsetof(CPUState, spr[SPR_BOOKE_IVOR37]) }, + { "mas0", offsetof(CPUState, spr[SPR_BOOKE_MAS0]) }, + { "mas1", offsetof(CPUState, spr[SPR_BOOKE_MAS1]) }, + { "mas2", offsetof(CPUState, spr[SPR_BOOKE_MAS2]) }, + { "mas3", offsetof(CPUState, spr[SPR_BOOKE_MAS3]) }, + { "mas4", offsetof(CPUState, spr[SPR_BOOKE_MAS4]) }, + { "mas6", offsetof(CPUState, spr[SPR_BOOKE_MAS6]) }, + { "mas7", offsetof(CPUState, spr[SPR_BOOKE_MAS7]) }, + { "mmucfg", offsetof(CPUState, spr[SPR_MMUCFG]) }, + { "tlb0cfg", offsetof(CPUState, spr[SPR_BOOKE_TLB0CFG]) }, + { "tlb1cfg", offsetof(CPUState, spr[SPR_BOOKE_TLB1CFG]) }, + { "epr", offsetof(CPUState, spr[SPR_BOOKE_EPR]) }, + { "eplc", offsetof(CPUState, spr[SPR_BOOKE_EPLC]) }, + { "epsc", offsetof(CPUState, spr[SPR_BOOKE_EPSC]) }, + { "svr", offsetof(CPUState, spr[SPR_E500_SVR]) }, + { "mcar", offsetof(CPUState, spr[SPR_Exxx_MCAR]) }, + { "pid1", offsetof(CPUState, spr[SPR_BOOKE_PID1]) }, + { "pid2", offsetof(CPUState, spr[SPR_BOOKE_PID2]) }, + { "hid0", offsetof(CPUState, spr[SPR_HID0]) }, + #elif defined(TARGET_SPARC) { "g0", offsetof(CPUState, gregs[0]) }, { "g1", offsetof(CPUState, gregs[1]) }, @@ -3517,55 +3236,55 @@ static const MonitorDef monitor_defs[] = { #endif { "tbr", offsetof(CPUState, tbr) }, { "fsr", offsetof(CPUState, fsr) }, - { "f0", offsetof(CPUState, fpr[0]) }, - { "f1", offsetof(CPUState, fpr[1]) }, - { "f2", offsetof(CPUState, fpr[2]) }, - { "f3", offsetof(CPUState, fpr[3]) }, - { "f4", offsetof(CPUState, fpr[4]) }, - { "f5", offsetof(CPUState, fpr[5]) }, - { "f6", offsetof(CPUState, fpr[6]) }, - { "f7", offsetof(CPUState, fpr[7]) }, - { "f8", offsetof(CPUState, fpr[8]) }, - { "f9", offsetof(CPUState, fpr[9]) }, - { "f10", offsetof(CPUState, fpr[10]) }, - { "f11", offsetof(CPUState, fpr[11]) }, - { "f12", offsetof(CPUState, fpr[12]) }, - { "f13", offsetof(CPUState, fpr[13]) }, - { "f14", offsetof(CPUState, fpr[14]) }, - { "f15", offsetof(CPUState, fpr[15]) }, - { "f16", offsetof(CPUState, fpr[16]) }, - { "f17", offsetof(CPUState, fpr[17]) }, - { "f18", offsetof(CPUState, fpr[18]) }, - { "f19", offsetof(CPUState, fpr[19]) }, - { "f20", offsetof(CPUState, fpr[20]) }, - { "f21", offsetof(CPUState, fpr[21]) }, - { "f22", offsetof(CPUState, fpr[22]) }, - { "f23", offsetof(CPUState, fpr[23]) }, - { "f24", offsetof(CPUState, fpr[24]) }, - { "f25", offsetof(CPUState, fpr[25]) }, - { "f26", offsetof(CPUState, fpr[26]) }, - { "f27", offsetof(CPUState, fpr[27]) }, - { "f28", offsetof(CPUState, fpr[28]) }, - { "f29", offsetof(CPUState, fpr[29]) }, - { "f30", offsetof(CPUState, fpr[30]) }, - { "f31", offsetof(CPUState, fpr[31]) }, + { "f0", offsetof(CPUState, fpr[0].l.upper) }, + { "f1", offsetof(CPUState, fpr[0].l.lower) }, + { "f2", offsetof(CPUState, fpr[1].l.upper) }, + { "f3", offsetof(CPUState, fpr[1].l.lower) }, + { "f4", offsetof(CPUState, fpr[2].l.upper) }, + { "f5", offsetof(CPUState, fpr[2].l.lower) }, + { "f6", offsetof(CPUState, fpr[3].l.upper) }, + { "f7", offsetof(CPUState, fpr[3].l.lower) }, + { "f8", offsetof(CPUState, fpr[4].l.upper) }, + { "f9", offsetof(CPUState, fpr[4].l.lower) }, + { "f10", offsetof(CPUState, fpr[5].l.upper) }, + { "f11", offsetof(CPUState, fpr[5].l.lower) }, + { "f12", offsetof(CPUState, fpr[6].l.upper) }, + { "f13", offsetof(CPUState, fpr[6].l.lower) }, + { "f14", offsetof(CPUState, fpr[7].l.upper) }, + { "f15", offsetof(CPUState, fpr[7].l.lower) }, + { "f16", offsetof(CPUState, fpr[8].l.upper) }, + { "f17", offsetof(CPUState, fpr[8].l.lower) }, + { "f18", offsetof(CPUState, fpr[9].l.upper) }, + { "f19", offsetof(CPUState, fpr[9].l.lower) }, + { "f20", offsetof(CPUState, fpr[10].l.upper) }, + { "f21", offsetof(CPUState, fpr[10].l.lower) }, + { "f22", offsetof(CPUState, fpr[11].l.upper) }, + { "f23", offsetof(CPUState, fpr[11].l.lower) }, + { "f24", offsetof(CPUState, fpr[12].l.upper) }, + { "f25", offsetof(CPUState, fpr[12].l.lower) }, + { "f26", offsetof(CPUState, fpr[13].l.upper) }, + { "f27", offsetof(CPUState, fpr[13].l.lower) }, + { "f28", offsetof(CPUState, fpr[14].l.upper) }, + { "f29", offsetof(CPUState, fpr[14].l.lower) }, + { "f30", offsetof(CPUState, fpr[15].l.upper) }, + { "f31", offsetof(CPUState, fpr[15].l.lower) }, #ifdef TARGET_SPARC64 - { "f32", offsetof(CPUState, fpr[32]) }, - { "f34", offsetof(CPUState, fpr[34]) }, - { "f36", offsetof(CPUState, fpr[36]) }, - { "f38", offsetof(CPUState, fpr[38]) }, - { "f40", offsetof(CPUState, fpr[40]) }, - { "f42", offsetof(CPUState, fpr[42]) }, - { "f44", offsetof(CPUState, fpr[44]) }, - { "f46", offsetof(CPUState, fpr[46]) }, - { "f48", offsetof(CPUState, fpr[48]) }, - { "f50", offsetof(CPUState, fpr[50]) }, - { "f52", offsetof(CPUState, fpr[52]) }, - { "f54", offsetof(CPUState, fpr[54]) }, - { "f56", offsetof(CPUState, fpr[56]) }, - { "f58", offsetof(CPUState, fpr[58]) }, - { "f60", offsetof(CPUState, fpr[60]) }, - { "f62", offsetof(CPUState, fpr[62]) }, + { "f32", offsetof(CPUState, fpr[16]) }, + { "f34", offsetof(CPUState, fpr[17]) }, + { "f36", offsetof(CPUState, fpr[18]) }, + { "f38", offsetof(CPUState, fpr[19]) }, + { "f40", offsetof(CPUState, fpr[20]) }, + { "f42", offsetof(CPUState, fpr[21]) }, + { "f44", offsetof(CPUState, fpr[22]) }, + { "f46", offsetof(CPUState, fpr[23]) }, + { "f48", offsetof(CPUState, fpr[24]) }, + { "f50", offsetof(CPUState, fpr[25]) }, + { "f52", offsetof(CPUState, fpr[26]) }, + { "f54", offsetof(CPUState, fpr[27]) }, + { "f56", offsetof(CPUState, fpr[28]) }, + { "f58", offsetof(CPUState, fpr[29]) }, + { "f60", offsetof(CPUState, fpr[30]) }, + { "f62", offsetof(CPUState, fpr[31]) }, { "asi", offsetof(CPUState, asi) }, { "pstate", offsetof(CPUState, pstate) }, { "cansave", offsetof(CPUState, cansave) }, @@ -3934,7 +3653,7 @@ static char *key_get_info(const char *type, char **key) } len = p - type; - str = qemu_malloc(len + 1); + str = g_malloc(len + 1); memcpy(str, type, len); str[len] = '\0'; @@ -3978,11 +3697,6 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname) return search_dispatch_table(mon_cmds, cmdname); } -static const mon_cmd_t *qmp_find_query_cmd(const char *info_item) -{ - return search_dispatch_table(qmp_query_cmds, info_item); -} - static const mon_cmd_t *qmp_find_cmd(const char *cmdname) { return search_dispatch_table(qmp_cmds, cmdname); @@ -4317,7 +4031,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c); goto fail; } - qemu_free(key); + g_free(key); key = NULL; } /* check that all arguments were parsed */ @@ -4332,7 +4046,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, return cmd; fail: - qemu_free(key); + g_free(key); return NULL; } @@ -4493,9 +4207,9 @@ static void file_completion(const char *input) /* stat the file to find out if it's a directory. * In that case add a slash to speed up typing long paths */ - stat(file, &sb); - if(S_ISDIR(sb.st_mode)) + if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) { pstrcat(file, sizeof(file), "/"); + } readline_add_completion(cur_mon->rs, file); } } @@ -4531,7 +4245,7 @@ static void parse_cmdline(const char *cmdline, if (nb_args >= MAX_ARGS) break; ret = get_str(buf, sizeof(buf), &p); - args[nb_args] = qemu_strdup(buf); + args[nb_args] = g_strdup(buf); nb_args++; if (ret < 0) break; @@ -4568,7 +4282,7 @@ static void monitor_find_completion(const char *cmdline) if (nb_args >= MAX_ARGS) { goto cleanup; } - args[nb_args++] = qemu_strdup(""); + args[nb_args++] = g_strdup(""); } if (nb_args <= 1) { /* command completion */ @@ -4643,7 +4357,7 @@ static void monitor_find_completion(const char *cmdline) cleanup: for (i = 0; i < nb_args; i++) { - qemu_free(args[i]); + g_free(args[i]); } } @@ -4906,22 +4620,6 @@ static QDict *qmp_check_input_obj(QObject *input_obj) return input_dict; } -static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd) -{ - QObject *ret_data = NULL; - - if (handler_is_async(cmd)) { - qmp_async_info_handler(mon, cmd); - if (monitor_has_error(mon)) { - monitor_protocol_emitter(mon, NULL); - } - } else { - cmd->mhandler.info_new(mon, &ret_data); - monitor_protocol_emitter(mon, ret_data); - qobject_decref(ret_data); - } -} - static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd, const QDict *params) { @@ -4942,10 +4640,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) QObject *obj; QDict *input, *args; const mon_cmd_t *cmd; + const char *cmd_name; Monitor *mon = cur_mon; - const char *cmd_name, *query_cmd; - query_cmd = NULL; args = input = NULL; obj = json_parser_parse(tokens, NULL); @@ -4965,17 +4662,13 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) qobject_incref(mon->mc->id); cmd_name = qdict_get_str(input, "execute"); + trace_handle_qmp_command(mon, cmd_name); if (invalid_qmp_mode(mon, cmd_name)) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_out; } - if (strstart(cmd_name, "query-", &query_cmd)) { - cmd = qmp_find_query_cmd(query_cmd); - } else { - cmd = qmp_find_cmd(cmd_name); - } - + cmd = qmp_find_cmd(cmd_name); if (!cmd) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_out; @@ -4994,9 +4687,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } - if (query_cmd) { - qmp_call_query_cmd(mon, cmd); - } else if (handler_is_async(cmd)) { + if (handler_is_async(cmd)) { err = qmp_async_cmd_handler(mon, cmd, args); if (err) { /* emit the error response */ @@ -5074,9 +4765,9 @@ void monitor_resume(Monitor *mon) static QObject *get_qmp_greeting(void) { - QObject *ver; + QObject *ver = NULL; - do_info_version(NULL, &ver); + qmp_marshal_input_query_version(NULL, NULL, &ver); return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver); } @@ -5142,6 +4833,25 @@ static void monitor_event(void *opaque, int event) } } +static int +compare_mon_cmd(const void *a, const void *b) +{ + return strcmp(((const mon_cmd_t *)a)->name, + ((const mon_cmd_t *)b)->name); +} + +static void sortcmdlist(void) +{ + int array_num; + int elem_size = sizeof(mon_cmd_t); + + array_num = sizeof(mon_cmds)/elem_size-1; + qsort((void *)mon_cmds, array_num, elem_size, compare_mon_cmd); + + array_num = sizeof(info_cmds)/elem_size-1; + qsort((void *)info_cmds, array_num, elem_size, compare_mon_cmd); +} + /* * Local variables: @@ -5157,11 +4867,11 @@ void monitor_init(CharDriverState *chr, int flags) Monitor *mon; if (is_first_init) { - key_timer = qemu_new_timer(vm_clock, release_keys, NULL); + key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL); is_first_init = 0; } - mon = qemu_mallocz(sizeof(*mon)); + mon = g_malloc0(sizeof(*mon)); mon->chr = chr; mon->flags = flags; @@ -5171,11 +4881,11 @@ void monitor_init(CharDriverState *chr, int flags) } if (monitor_ctrl_mode(mon)) { - mon->mc = qemu_mallocz(sizeof(MonitorControl)); + mon->mc = g_malloc0(sizeof(MonitorControl)); /* Control mode requires special handlers */ qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read, monitor_control_event, mon); - qemu_chr_set_echo(chr, true); + qemu_chr_fe_set_echo(chr, true); } else { qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event, mon); @@ -5184,6 +4894,8 @@ void monitor_init(CharDriverState *chr, int flags) QLIST_INSERT_HEAD(&mon_list, mon, entry); if (!default_mon || (flags & MONITOR_IS_DEFAULT)) default_mon = mon; + + sortcmdlist(); } static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque) diff --git a/monitor.h b/monitor.h index 4f2d328..e76795f 100644 --- a/monitor.h +++ b/monitor.h @@ -57,6 +57,8 @@ void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void monitor_print_filename(Monitor *mon, const char *filename); void monitor_flush(Monitor *mon); +int monitor_set_cpu(int cpu_index); +int monitor_get_cpu_index(void); typedef void (MonitorCompletion)(void *opaque, QObject *ret_data); diff --git a/nbd.c b/nbd.c index d8ebc42..e6c931c 100644 --- a/nbd.c +++ b/nbd.c @@ -17,6 +17,7 @@ */ #include "nbd.h" +#include "block.h" #include #include @@ -29,6 +30,10 @@ #include #include +#ifdef __linux__ +#include +#endif + #include "qemu_socket.h" //#define DEBUG_NBD @@ -49,7 +54,7 @@ /* This is all part of the "official" NBD API */ -#define NBD_REPLY_SIZE (4 + 4 + 8) +#define NBD_REPLY_SIZE (4 + 4 + 8) #define NBD_REQUEST_MAGIC 0x25609513 #define NBD_REPLY_MAGIC 0x67446698 @@ -59,11 +64,13 @@ #define NBD_DO_IT _IO(0xab, 3) #define NBD_CLEAR_SOCK _IO(0xab, 4) #define NBD_CLEAR_QUE _IO(0xab, 5) -#define NBD_PRINT_DEBUG _IO(0xab, 6) -#define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) +#define NBD_PRINT_DEBUG _IO(0xab, 6) +#define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) #define NBD_DISCONNECT _IO(0xab, 8) +#define NBD_SET_TIMEOUT _IO(0xab, 9) +#define NBD_SET_FLAGS _IO(0xab, 10) -#define NBD_OPT_EXPORT_NAME (1 << 0) +#define NBD_OPT_EXPORT_NAME (1 << 0) /* That's all folks */ @@ -78,7 +85,7 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read) ssize_t len; if (do_read) { - len = recv(fd, buffer + offset, size - offset, 0); + len = qemu_recv(fd, buffer + offset, size - offset, 0); } else { len = send(fd, buffer + offset, size - offset, 0); } @@ -107,155 +114,55 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read) return offset; } -int tcp_socket_outgoing(const char *address, uint16_t port) +static void combine_addr(char *buf, size_t len, const char* address, + uint16_t port) { - int s; - struct in_addr in; - struct sockaddr_in addr; - - s = socket(PF_INET, SOCK_STREAM, 0); - if (s == -1) { - return -1; - } - - if (inet_aton(address, &in) == 0) { - struct hostent *ent; - - ent = gethostbyname(address); - if (ent == NULL) { - goto error; - } - - memcpy(&in, ent->h_addr, sizeof(in)); + /* If the address-part contains a colon, it's an IPv6 IP so needs [] */ + if (strstr(address, ":")) { + snprintf(buf, len, "[%s]:%u", address, port); + } else { + snprintf(buf, len, "%s:%u", address, port); } - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - memcpy(&addr.sin_addr.s_addr, &in, sizeof(in)); - - if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - goto error; - } - - return s; -error: - closesocket(s); - return -1; } -int tcp_socket_incoming(const char *address, uint16_t port) +int tcp_socket_outgoing(const char *address, uint16_t port) { - int s; - struct in_addr in; - struct sockaddr_in addr; - int opt; - - s = socket(PF_INET, SOCK_STREAM, 0); - if (s == -1) { - return -1; - } - - if (inet_aton(address, &in) == 0) { - struct hostent *ent; - - ent = gethostbyname(address); - if (ent == NULL) { - goto error; - } - - memcpy(&in, ent->h_addr, sizeof(in)); - } - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - memcpy(&addr.sin_addr.s_addr, &in, sizeof(in)); - - opt = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &opt, sizeof(opt)) == -1) { - goto error; - } - - if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - goto error; - } - - if (listen(s, 128) == -1) { - goto error; - } - - return s; -error: - closesocket(s); - return -1; + char address_and_port[128]; + combine_addr(address_and_port, 128, address, port); + return tcp_socket_outgoing_spec(address_and_port); } -#ifndef _WIN32 -int unix_socket_incoming(const char *path) +int tcp_socket_outgoing_spec(const char *address_and_port) { - int s; - struct sockaddr_un addr; - - s = socket(PF_UNIX, SOCK_STREAM, 0); - if (s == -1) { - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - pstrcpy(addr.sun_path, sizeof(addr.sun_path), path); - - if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - goto error; - } - - if (listen(s, 128) == -1) { - goto error; - } - - return s; -error: - closesocket(s); - return -1; + return inet_connect(address_and_port, SOCK_STREAM); } -int unix_socket_outgoing(const char *path) +int tcp_socket_incoming(const char *address, uint16_t port) { - int s; - struct sockaddr_un addr; - - s = socket(PF_UNIX, SOCK_STREAM, 0); - if (s == -1) { - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - pstrcpy(addr.sun_path, sizeof(addr.sun_path), path); - - if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - goto error; - } + char address_and_port[128]; + combine_addr(address_and_port, 128, address, port); + return tcp_socket_incoming_spec(address_and_port); +} - return s; -error: - closesocket(s); - return -1; +int tcp_socket_incoming_spec(const char *address_and_port) +{ + char *ostr = NULL; + int olen = 0; + return inet_listen(address_and_port, ostr, olen, SOCK_STREAM, 0); } -#else + int unix_socket_incoming(const char *path) { - errno = ENOTSUP; - return -1; + char *ostr = NULL; + int olen = 0; + + return unix_listen(path, ostr, olen); } int unix_socket_outgoing(const char *path) { - errno = ENOTSUP; - return -1; + return unix_connect(path); } -#endif - /* Basic flow @@ -271,246 +178,275 @@ int unix_socket_outgoing(const char *path) Request (type == 2) */ -int nbd_negotiate(int csock, off_t size) +int nbd_negotiate(int csock, off_t size, uint32_t flags) { - char buf[8 + 8 + 8 + 128]; - - /* Negotiate - [ 0 .. 7] passwd ("NBDMAGIC") - [ 8 .. 15] magic (0x00420281861253) - [16 .. 23] size - [24 .. 151] reserved (0) - */ - - TRACE("Beginning negotiation."); - memcpy(buf, "NBDMAGIC", 8); - cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL); - cpu_to_be64w((uint64_t*)(buf + 16), size); - memset(buf + 24, 0, 128); - - if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { - LOG("write failed"); - errno = EINVAL; - return -1; - } - - TRACE("Negotation succeeded."); - - return 0; + char buf[8 + 8 + 8 + 128]; + + /* Negotiate + [ 0 .. 7] passwd ("NBDMAGIC") + [ 8 .. 15] magic (0x00420281861253) + [16 .. 23] size + [24 .. 27] flags + [28 .. 151] reserved (0) + */ + + TRACE("Beginning negotiation."); + memcpy(buf, "NBDMAGIC", 8); + cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL); + cpu_to_be64w((uint64_t*)(buf + 16), size); + cpu_to_be32w((uint32_t*)(buf + 24), flags | NBD_FLAG_HAS_FLAGS); + memset(buf + 28, 0, 124); + + if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { + LOG("write failed"); + errno = EINVAL; + return -1; + } + + TRACE("Negotation succeeded."); + + return 0; } int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags, off_t *size, size_t *blocksize) { - char buf[256]; - uint64_t magic, s; - uint16_t tmp; - - TRACE("Receiving negotation."); - - if (read_sync(csock, buf, 8) != 8) { - LOG("read failed"); - errno = EINVAL; - return -1; - } - - buf[8] = '\0'; - if (strlen(buf) == 0) { - LOG("server connection closed"); - errno = EINVAL; - return -1; - } - - TRACE("Magic is %c%c%c%c%c%c%c%c", - qemu_isprint(buf[0]) ? buf[0] : '.', - qemu_isprint(buf[1]) ? buf[1] : '.', - qemu_isprint(buf[2]) ? buf[2] : '.', - qemu_isprint(buf[3]) ? buf[3] : '.', - qemu_isprint(buf[4]) ? buf[4] : '.', - qemu_isprint(buf[5]) ? buf[5] : '.', - qemu_isprint(buf[6]) ? buf[6] : '.', - qemu_isprint(buf[7]) ? buf[7] : '.'); - - if (memcmp(buf, "NBDMAGIC", 8) != 0) { - LOG("Invalid magic received"); - errno = EINVAL; - return -1; - } - - if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { - LOG("read failed"); - errno = EINVAL; - return -1; - } - magic = be64_to_cpu(magic); - TRACE("Magic is 0x%" PRIx64, magic); - - if (name) { - uint32_t reserved = 0; - uint32_t opt; - uint32_t namesize; - - TRACE("Checking magic (opts_magic)"); - if (magic != 0x49484156454F5054LL) { - LOG("Bad magic received"); - errno = EINVAL; - return -1; - } - if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { - LOG("flags read failed"); - errno = EINVAL; - return -1; - } - *flags = be16_to_cpu(tmp) << 16; - /* reserved for future use */ - if (write_sync(csock, &reserved, sizeof(reserved)) != - sizeof(reserved)) { - LOG("write failed (reserved)"); - errno = EINVAL; - return -1; - } - /* write the export name */ - magic = cpu_to_be64(magic); - if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { - LOG("write failed (magic)"); - errno = EINVAL; - return -1; - } - opt = cpu_to_be32(NBD_OPT_EXPORT_NAME); - if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) { - LOG("write failed (opt)"); - errno = EINVAL; - return -1; - } - namesize = cpu_to_be32(strlen(name)); - if (write_sync(csock, &namesize, sizeof(namesize)) != - sizeof(namesize)) { - LOG("write failed (namesize)"); - errno = EINVAL; - return -1; - } - if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) { - LOG("write failed (name)"); - errno = EINVAL; - return -1; - } - } else { - TRACE("Checking magic (cli_magic)"); - - if (magic != 0x00420281861253LL) { - LOG("Bad magic received"); - errno = EINVAL; - return -1; - } - } - - if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) { - LOG("read failed"); - errno = EINVAL; - return -1; - } - *size = be64_to_cpu(s); - *blocksize = 1024; - TRACE("Size is %" PRIu64, *size); - - if (!name) { - if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) { - LOG("read failed (flags)"); - errno = EINVAL; - return -1; - } - *flags = be32_to_cpup(flags); - } else { - if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { - LOG("read failed (tmp)"); - errno = EINVAL; - return -1; - } - *flags |= be32_to_cpu(tmp); - } - if (read_sync(csock, &buf, 124) != 124) { - LOG("read failed (buf)"); - errno = EINVAL; - return -1; - } + char buf[256]; + uint64_t magic, s; + uint16_t tmp; + + TRACE("Receiving negotation."); + + if (read_sync(csock, buf, 8) != 8) { + LOG("read failed"); + errno = EINVAL; + return -1; + } + + buf[8] = '\0'; + if (strlen(buf) == 0) { + LOG("server connection closed"); + errno = EINVAL; + return -1; + } + + TRACE("Magic is %c%c%c%c%c%c%c%c", + qemu_isprint(buf[0]) ? buf[0] : '.', + qemu_isprint(buf[1]) ? buf[1] : '.', + qemu_isprint(buf[2]) ? buf[2] : '.', + qemu_isprint(buf[3]) ? buf[3] : '.', + qemu_isprint(buf[4]) ? buf[4] : '.', + qemu_isprint(buf[5]) ? buf[5] : '.', + qemu_isprint(buf[6]) ? buf[6] : '.', + qemu_isprint(buf[7]) ? buf[7] : '.'); + + if (memcmp(buf, "NBDMAGIC", 8) != 0) { + LOG("Invalid magic received"); + errno = EINVAL; + return -1; + } + + if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { + LOG("read failed"); + errno = EINVAL; + return -1; + } + magic = be64_to_cpu(magic); + TRACE("Magic is 0x%" PRIx64, magic); + + if (name) { + uint32_t reserved = 0; + uint32_t opt; + uint32_t namesize; + + TRACE("Checking magic (opts_magic)"); + if (magic != 0x49484156454F5054LL) { + LOG("Bad magic received"); + errno = EINVAL; + return -1; + } + if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { + LOG("flags read failed"); + errno = EINVAL; + return -1; + } + *flags = be16_to_cpu(tmp) << 16; + /* reserved for future use */ + if (write_sync(csock, &reserved, sizeof(reserved)) != + sizeof(reserved)) { + LOG("write failed (reserved)"); + errno = EINVAL; + return -1; + } + /* write the export name */ + magic = cpu_to_be64(magic); + if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { + LOG("write failed (magic)"); + errno = EINVAL; + return -1; + } + opt = cpu_to_be32(NBD_OPT_EXPORT_NAME); + if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) { + LOG("write failed (opt)"); + errno = EINVAL; + return -1; + } + namesize = cpu_to_be32(strlen(name)); + if (write_sync(csock, &namesize, sizeof(namesize)) != + sizeof(namesize)) { + LOG("write failed (namesize)"); + errno = EINVAL; + return -1; + } + if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) { + LOG("write failed (name)"); + errno = EINVAL; + return -1; + } + } else { + TRACE("Checking magic (cli_magic)"); + + if (magic != 0x00420281861253LL) { + LOG("Bad magic received"); + errno = EINVAL; + return -1; + } + } + + if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) { + LOG("read failed"); + errno = EINVAL; + return -1; + } + *size = be64_to_cpu(s); + *blocksize = 1024; + TRACE("Size is %" PRIu64, *size); + + if (!name) { + if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) { + LOG("read failed (flags)"); + errno = EINVAL; + return -1; + } + *flags = be32_to_cpup(flags); + } else { + if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { + LOG("read failed (tmp)"); + errno = EINVAL; + return -1; + } + *flags |= be32_to_cpu(tmp); + } + if (read_sync(csock, &buf, 124) != 124) { + LOG("read failed (buf)"); + errno = EINVAL; + return -1; + } return 0; } -#ifndef _WIN32 -int nbd_init(int fd, int csock, off_t size, size_t blocksize) +#ifdef __linux__ +int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize) { - TRACE("Setting block size to %lu", (unsigned long)blocksize); + TRACE("Setting block size to %lu", (unsigned long)blocksize); - if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) == -1) { - int serrno = errno; - LOG("Failed setting NBD block size"); - errno = serrno; - return -1; - } + if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) == -1) { + int serrno = errno; + LOG("Failed setting NBD block size"); + errno = serrno; + return -1; + } TRACE("Setting size to %zd block(s)", (size_t)(size / blocksize)); - if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) == -1) { - int serrno = errno; - LOG("Failed setting size (in blocks)"); - errno = serrno; - return -1; - } + if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) == -1) { + int serrno = errno; + LOG("Failed setting size (in blocks)"); + errno = serrno; + return -1; + } - TRACE("Clearing NBD socket"); + if (flags & NBD_FLAG_READ_ONLY) { + int read_only = 1; + TRACE("Setting readonly attribute"); - if (ioctl(fd, NBD_CLEAR_SOCK) == -1) { - int serrno = errno; - LOG("Failed clearing NBD socket"); - errno = serrno; - return -1; - } + if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { + int serrno = errno; + LOG("Failed setting read-only attribute"); + errno = serrno; + return -1; + } + } - TRACE("Setting NBD socket"); + if (ioctl(fd, NBD_SET_FLAGS, flags) < 0 + && errno != ENOTTY) { + int serrno = errno; + LOG("Failed setting flags"); + errno = serrno; + return -1; + } + + TRACE("Clearing NBD socket"); - if (ioctl(fd, NBD_SET_SOCK, csock) == -1) { - int serrno = errno; - LOG("Failed to set NBD socket"); - errno = serrno; - return -1; - } + if (ioctl(fd, NBD_CLEAR_SOCK) == -1) { + int serrno = errno; + LOG("Failed clearing NBD socket"); + errno = serrno; + return -1; + } - TRACE("Negotiation ended"); + TRACE("Setting NBD socket"); - return 0; + if (ioctl(fd, NBD_SET_SOCK, csock) == -1) { + int serrno = errno; + LOG("Failed to set NBD socket"); + errno = serrno; + return -1; + } + + TRACE("Negotiation ended"); + + return 0; } int nbd_disconnect(int fd) { - ioctl(fd, NBD_CLEAR_QUE); - ioctl(fd, NBD_DISCONNECT); - ioctl(fd, NBD_CLEAR_SOCK); - return 0; + ioctl(fd, NBD_CLEAR_QUE); + ioctl(fd, NBD_DISCONNECT); + ioctl(fd, NBD_CLEAR_SOCK); + return 0; } int nbd_client(int fd) { - int ret; - int serrno; - - TRACE("Doing NBD loop"); - - ret = ioctl(fd, NBD_DO_IT); - serrno = errno; + int ret; + int serrno; + + TRACE("Doing NBD loop"); + + ret = ioctl(fd, NBD_DO_IT); + if (ret == -1 && errno == EPIPE) { + /* NBD_DO_IT normally returns EPIPE when someone has disconnected + * the socket via NBD_DISCONNECT. We do not want to return 1 in + * that case. + */ + ret = 0; + } + serrno = errno; - TRACE("NBD loop returned %d: %s", ret, strerror(serrno)); + TRACE("NBD loop returned %d: %s", ret, strerror(serrno)); - TRACE("Clearing NBD queue"); - ioctl(fd, NBD_CLEAR_QUE); + TRACE("Clearing NBD queue"); + ioctl(fd, NBD_CLEAR_QUE); - TRACE("Clearing NBD socket"); - ioctl(fd, NBD_CLEAR_SOCK); + TRACE("Clearing NBD socket"); + ioctl(fd, NBD_CLEAR_SOCK); - errno = serrno; - return ret; + errno = serrno; + return ret; } #else -int nbd_init(int fd, int csock, off_t size, size_t blocksize) +int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize) { errno = ENOTSUP; return -1; @@ -531,235 +467,236 @@ int nbd_client(int fd) int nbd_send_request(int csock, struct nbd_request *request) { - uint8_t buf[4 + 4 + 8 + 8 + 4]; - - cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC); - cpu_to_be32w((uint32_t*)(buf + 4), request->type); - cpu_to_be64w((uint64_t*)(buf + 8), request->handle); - cpu_to_be64w((uint64_t*)(buf + 16), request->from); - cpu_to_be32w((uint32_t*)(buf + 24), request->len); - - TRACE("Sending request to client"); - - if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { - LOG("writing to socket failed"); - errno = EINVAL; - return -1; - } - return 0; -} + uint8_t buf[4 + 4 + 8 + 8 + 4]; + + cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC); + cpu_to_be32w((uint32_t*)(buf + 4), request->type); + cpu_to_be64w((uint64_t*)(buf + 8), request->handle); + cpu_to_be64w((uint64_t*)(buf + 16), request->from); + cpu_to_be32w((uint32_t*)(buf + 24), request->len); + TRACE("Sending request to client: " + "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}", + request->from, request->len, request->handle, request->type); + + if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { + LOG("writing to socket failed"); + errno = EINVAL; + return -1; + } + return 0; +} static int nbd_receive_request(int csock, struct nbd_request *request) { - uint8_t buf[4 + 4 + 8 + 8 + 4]; - uint32_t magic; - - if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { - LOG("read failed"); - errno = EINVAL; - return -1; - } - - /* Request - [ 0 .. 3] magic (NBD_REQUEST_MAGIC) - [ 4 .. 7] type (0 == READ, 1 == WRITE) - [ 8 .. 15] handle - [16 .. 23] from - [24 .. 27] len - */ - - magic = be32_to_cpup((uint32_t*)buf); - request->type = be32_to_cpup((uint32_t*)(buf + 4)); - request->handle = be64_to_cpup((uint64_t*)(buf + 8)); - request->from = be64_to_cpup((uint64_t*)(buf + 16)); - request->len = be32_to_cpup((uint32_t*)(buf + 24)); - - TRACE("Got request: " - "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }", - magic, request->type, request->from, request->len); - - if (magic != NBD_REQUEST_MAGIC) { - LOG("invalid magic (got 0x%x)", magic); - errno = EINVAL; - return -1; - } - return 0; + uint8_t buf[4 + 4 + 8 + 8 + 4]; + uint32_t magic; + + if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { + LOG("read failed"); + errno = EINVAL; + return -1; + } + + /* Request + [ 0 .. 3] magic (NBD_REQUEST_MAGIC) + [ 4 .. 7] type (0 == READ, 1 == WRITE) + [ 8 .. 15] handle + [16 .. 23] from + [24 .. 27] len + */ + + magic = be32_to_cpup((uint32_t*)buf); + request->type = be32_to_cpup((uint32_t*)(buf + 4)); + request->handle = be64_to_cpup((uint64_t*)(buf + 8)); + request->from = be64_to_cpup((uint64_t*)(buf + 16)); + request->len = be32_to_cpup((uint32_t*)(buf + 24)); + + TRACE("Got request: " + "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }", + magic, request->type, request->from, request->len); + + if (magic != NBD_REQUEST_MAGIC) { + LOG("invalid magic (got 0x%x)", magic); + errno = EINVAL; + return -1; + } + return 0; } int nbd_receive_reply(int csock, struct nbd_reply *reply) { - uint8_t buf[NBD_REPLY_SIZE]; - uint32_t magic; - - memset(buf, 0xAA, sizeof(buf)); - - if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { - LOG("read failed"); - errno = EINVAL; - return -1; - } - - /* Reply - [ 0 .. 3] magic (NBD_REPLY_MAGIC) - [ 4 .. 7] error (0 == no error) - [ 7 .. 15] handle - */ - - magic = be32_to_cpup((uint32_t*)buf); - reply->error = be32_to_cpup((uint32_t*)(buf + 4)); - reply->handle = be64_to_cpup((uint64_t*)(buf + 8)); - - TRACE("Got reply: " - "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }", - magic, reply->error, reply->handle); - - if (magic != NBD_REPLY_MAGIC) { - LOG("invalid magic (got 0x%x)", magic); - errno = EINVAL; - return -1; - } - return 0; + uint8_t buf[NBD_REPLY_SIZE]; + uint32_t magic; + + memset(buf, 0xAA, sizeof(buf)); + + if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { + LOG("read failed"); + errno = EINVAL; + return -1; + } + + /* Reply + [ 0 .. 3] magic (NBD_REPLY_MAGIC) + [ 4 .. 7] error (0 == no error) + [ 7 .. 15] handle + */ + + magic = be32_to_cpup((uint32_t*)buf); + reply->error = be32_to_cpup((uint32_t*)(buf + 4)); + reply->handle = be64_to_cpup((uint64_t*)(buf + 8)); + + TRACE("Got reply: " + "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }", + magic, reply->error, reply->handle); + + if (magic != NBD_REPLY_MAGIC) { + LOG("invalid magic (got 0x%x)", magic); + errno = EINVAL; + return -1; + } + return 0; } static int nbd_send_reply(int csock, struct nbd_reply *reply) { - uint8_t buf[4 + 4 + 8]; - - /* Reply - [ 0 .. 3] magic (NBD_REPLY_MAGIC) - [ 4 .. 7] error (0 == no error) - [ 7 .. 15] handle - */ - cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC); - cpu_to_be32w((uint32_t*)(buf + 4), reply->error); - cpu_to_be64w((uint64_t*)(buf + 8), reply->handle); - - TRACE("Sending response to client"); - - if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { - LOG("writing to socket failed"); - errno = EINVAL; - return -1; - } - return 0; + uint8_t buf[4 + 4 + 8]; + + /* Reply + [ 0 .. 3] magic (NBD_REPLY_MAGIC) + [ 4 .. 7] error (0 == no error) + [ 7 .. 15] handle + */ + cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC); + cpu_to_be32w((uint32_t*)(buf + 4), reply->error); + cpu_to_be64w((uint64_t*)(buf + 8), reply->handle); + + TRACE("Sending response to client"); + + if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { + LOG("writing to socket failed"); + errno = EINVAL; + return -1; + } + return 0; } int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, - off_t *offset, bool readonly, uint8_t *data, int data_size) + off_t *offset, uint32_t nbdflags, uint8_t *data, int data_size) { - struct nbd_request request; - struct nbd_reply reply; - - TRACE("Reading request."); - - if (nbd_receive_request(csock, &request) == -1) - return -1; - - if (request.len + NBD_REPLY_SIZE > data_size) { - LOG("len (%u) is larger than max len (%u)", - request.len + NBD_REPLY_SIZE, data_size); - errno = EINVAL; - return -1; - } - - if ((request.from + request.len) < request.from) { - LOG("integer overflow detected! " - "you're probably being attacked"); - errno = EINVAL; - return -1; - } - - if ((request.from + request.len) > size) { - LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64 - ", Offset: %" PRIu64 "\n", + struct nbd_request request; + struct nbd_reply reply; + + TRACE("Reading request."); + + if (nbd_receive_request(csock, &request) == -1) + return -1; + + if (request.len + NBD_REPLY_SIZE > data_size) { + LOG("len (%u) is larger than max len (%u)", + request.len + NBD_REPLY_SIZE, data_size); + errno = EINVAL; + return -1; + } + + if ((request.from + request.len) < request.from) { + LOG("integer overflow detected! " + "you're probably being attacked"); + errno = EINVAL; + return -1; + } + + if ((request.from + request.len) > size) { + LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64 + ", Offset: %" PRIu64 "\n", request.from, request.len, (uint64_t)size, dev_offset); - LOG("requested operation past EOF--bad client?"); - errno = EINVAL; - return -1; - } - - TRACE("Decoding type"); - - reply.handle = request.handle; - reply.error = 0; - - switch (request.type) { - case NBD_CMD_READ: - TRACE("Request type is READ"); - - if (bdrv_read(bs, (request.from + dev_offset) / 512, - data + NBD_REPLY_SIZE, - request.len / 512) == -1) { - LOG("reading from file failed"); - errno = EINVAL; - return -1; - } - *offset += request.len; - - TRACE("Read %u byte(s)", request.len); - - /* Reply - [ 0 .. 3] magic (NBD_REPLY_MAGIC) - [ 4 .. 7] error (0 == no error) - [ 7 .. 15] handle - */ - - cpu_to_be32w((uint32_t*)data, NBD_REPLY_MAGIC); - cpu_to_be32w((uint32_t*)(data + 4), reply.error); - cpu_to_be64w((uint64_t*)(data + 8), reply.handle); - - TRACE("Sending data to client"); - - if (write_sync(csock, data, - request.len + NBD_REPLY_SIZE) != - request.len + NBD_REPLY_SIZE) { - LOG("writing to socket failed"); - errno = EINVAL; - return -1; - } - break; - case NBD_CMD_WRITE: - TRACE("Request type is WRITE"); - - TRACE("Reading %u byte(s)", request.len); - - if (read_sync(csock, data, request.len) != request.len) { - LOG("reading from socket failed"); - errno = EINVAL; - return -1; - } - - if (readonly) { - TRACE("Server is read-only, return error"); - reply.error = 1; - } else { - TRACE("Writing to device"); - - if (bdrv_write(bs, (request.from + dev_offset) / 512, - data, request.len / 512) == -1) { - LOG("writing to file failed"); - errno = EINVAL; - return -1; - } - - *offset += request.len; - } - - if (nbd_send_reply(csock, &reply) == -1) - return -1; - break; - case NBD_CMD_DISC: - TRACE("Request type is DISCONNECT"); - errno = 0; - return 1; - default: - LOG("invalid request type (%u) received", request.type); - errno = EINVAL; - return -1; - } - - TRACE("Request/Reply complete"); - - return 0; + LOG("requested operation past EOF--bad client?"); + errno = EINVAL; + return -1; + } + + TRACE("Decoding type"); + + reply.handle = request.handle; + reply.error = 0; + + switch (request.type) { + case NBD_CMD_READ: + TRACE("Request type is READ"); + + if (bdrv_read(bs, (request.from + dev_offset) / 512, + data + NBD_REPLY_SIZE, + request.len / 512) == -1) { + LOG("reading from file failed"); + errno = EINVAL; + return -1; + } + *offset += request.len; + + TRACE("Read %u byte(s)", request.len); + + /* Reply + [ 0 .. 3] magic (NBD_REPLY_MAGIC) + [ 4 .. 7] error (0 == no error) + [ 7 .. 15] handle + */ + + cpu_to_be32w((uint32_t*)data, NBD_REPLY_MAGIC); + cpu_to_be32w((uint32_t*)(data + 4), reply.error); + cpu_to_be64w((uint64_t*)(data + 8), reply.handle); + + TRACE("Sending data to client"); + + if (write_sync(csock, data, + request.len + NBD_REPLY_SIZE) != + request.len + NBD_REPLY_SIZE) { + LOG("writing to socket failed"); + errno = EINVAL; + return -1; + } + break; + case NBD_CMD_WRITE: + TRACE("Request type is WRITE"); + + TRACE("Reading %u byte(s)", request.len); + + if (read_sync(csock, data, request.len) != request.len) { + LOG("reading from socket failed"); + errno = EINVAL; + return -1; + } + + if (nbdflags & NBD_FLAG_READ_ONLY) { + TRACE("Server is read-only, return error"); + reply.error = 1; + } else { + TRACE("Writing to device"); + + if (bdrv_write(bs, (request.from + dev_offset) / 512, + data, request.len / 512) == -1) { + LOG("writing to file failed"); + errno = EINVAL; + return -1; + } + + *offset += request.len; + } + + if (nbd_send_reply(csock, &reply) == -1) + return -1; + break; + case NBD_CMD_DISC: + TRACE("Request type is DISCONNECT"); + errno = 0; + return 1; + default: + LOG("invalid request type (%u) received", request.type); + errno = EINVAL; + return -1; + } + + TRACE("Request/Reply complete"); + + return 0; } diff --git a/nbd.h b/nbd.h index fc3a594..61553f4 100644 --- a/nbd.h +++ b/nbd.h @@ -21,25 +21,38 @@ #include -#include -#include "block_int.h" +#include "qemu-common.h" struct nbd_request { + uint32_t magic; uint32_t type; uint64_t handle; uint64_t from; uint32_t len; -}; +} QEMU_PACKED; struct nbd_reply { + uint32_t magic; uint32_t error; uint64_t handle; -}; +} QEMU_PACKED; + +#define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */ +#define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */ +#define NBD_FLAG_SEND_FLUSH (1 << 2) /* Send FLUSH */ +#define NBD_FLAG_SEND_FUA (1 << 3) /* Send FUA (Force Unit Access) */ +#define NBD_FLAG_ROTATIONAL (1 << 4) /* Use elevator algorithm - rotational media */ +#define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */ + +#define NBD_CMD_MASK_COMMAND 0x0000ffff +#define NBD_CMD_FLAG_FUA (1 << 16) enum { NBD_CMD_READ = 0, NBD_CMD_WRITE = 1, - NBD_CMD_DISC = 2 + NBD_CMD_DISC = 2, + NBD_CMD_FLUSH = 3, + NBD_CMD_TRIM = 4 }; #define NBD_DEFAULT_PORT 10809 @@ -47,17 +60,19 @@ enum { size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read); int tcp_socket_outgoing(const char *address, uint16_t port); int tcp_socket_incoming(const char *address, uint16_t port); +int tcp_socket_outgoing_spec(const char *address_and_port); +int tcp_socket_incoming_spec(const char *address_and_port); int unix_socket_outgoing(const char *path); int unix_socket_incoming(const char *path); -int nbd_negotiate(int csock, off_t size); +int nbd_negotiate(int csock, off_t size, uint32_t flags); int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags, off_t *size, size_t *blocksize); -int nbd_init(int fd, int csock, off_t size, size_t blocksize); +int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize); int nbd_send_request(int csock, struct nbd_request *request); int nbd_receive_reply(int csock, struct nbd_reply *reply); int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, - off_t *offset, bool readonly, uint8_t *data, int data_size); + off_t *offset, uint32_t nbdflags, uint8_t *data, int data_size); int nbd_client(int fd); int nbd_disconnect(int fd); diff --git a/net-checksum.c b/net-checksum.c deleted file mode 100644 index 4956c5c..0000000 --- a/net-checksum.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * IP checksumming functions. - * (c) 2008 Gerd Hoffmann - * - * 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; under version 2 of the License. - * - * 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, see . - */ - -#include "hw/hw.h" -#include "net.h" - -#define PROTO_TCP 6 -#define PROTO_UDP 17 - -uint32_t net_checksum_add(int len, uint8_t *buf) -{ - uint32_t sum = 0; - int i; - - for (i = 0; i < len; i++) { - if (i & 1) - sum += (uint32_t)buf[i]; - else - sum += (uint32_t)buf[i] << 8; - } - return sum; -} - -uint16_t net_checksum_finish(uint32_t sum) -{ - while (sum>>16) - sum = (sum & 0xFFFF)+(sum >> 16); - return ~sum; -} - -uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto, - uint8_t *addrs, uint8_t *buf) -{ - uint32_t sum = 0; - - sum += net_checksum_add(length, buf); // payload - sum += net_checksum_add(8, addrs); // src + dst address - sum += proto + length; // protocol & length - return net_checksum_finish(sum); -} - -void net_checksum_calculate(uint8_t *data, int length) -{ - int hlen, plen, proto, csum_offset; - uint16_t csum; - - if ((data[14] & 0xf0) != 0x40) - return; /* not IPv4 */ - hlen = (data[14] & 0x0f) * 4; - plen = (data[16] << 8 | data[17]) - hlen; - proto = data[23]; - - switch (proto) { - case PROTO_TCP: - csum_offset = 16; - break; - case PROTO_UDP: - csum_offset = 6; - break; - default: - return; - } - - if (plen < csum_offset+2) - return; - - data[14+hlen+csum_offset] = 0; - data[14+hlen+csum_offset+1] = 0; - csum = net_checksum_tcpudp(plen, proto, data+14+12, data+14+hlen); - data[14+hlen+csum_offset] = csum >> 8; - data[14+hlen+csum_offset+1] = csum & 0xff; -} diff --git a/net.c b/net.c index 21d4443..cb52050 100644 --- a/net.c +++ b/net.c @@ -32,10 +32,10 @@ #include "net/vde.h" #include "net/util.h" #include "monitor.h" -#include "sysemu.h" #include "qemu-common.h" #include "qemu_socket.h" #include "hw/qdev.h" +#include "iov.h" static QTAILQ_HEAD(, VLANState) vlans; static QTAILQ_HEAD(, VLANClientState) non_vlan_clients; @@ -93,47 +93,6 @@ static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) return 0; } -int parse_host_src_port(struct sockaddr_in *haddr, - struct sockaddr_in *saddr, - const char *input_str) -{ - char *str = qemu_strdup(input_str); - char *host_str = str; - char *src_str; - const char *src_str2; - char *ptr; - - /* - * Chop off any extra arguments at the end of the string which - * would start with a comma, then fill in the src port information - * if it was provided else use the "any address" and "any port". - */ - if ((ptr = strchr(str,','))) - *ptr = '\0'; - - if ((src_str = strchr(input_str,'@'))) { - *src_str = '\0'; - src_str++; - } - - if (parse_host_port(haddr, host_str) < 0) - goto fail; - - src_str2 = src_str; - if (!src_str || *src_str == '\0') - src_str2 = ":0"; - - if (parse_host_port(saddr, src_str2) < 0) - goto fail; - - free(str); - return(0); - -fail: - free(str); - return -1; -} - int parse_host_port(struct sockaddr_in *saddr, const char *str) { char buf[512]; @@ -191,12 +150,11 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr) static char *assign_name(VLANClientState *vc1, const char *model) { VLANState *vlan; + VLANClientState *vc; char buf[256]; int id = 0; QTAILQ_FOREACH(vlan, &vlans, next) { - VLANClientState *vc; - QTAILQ_FOREACH(vc, &vlan->clients, next) { if (vc != vc1 && strcmp(vc->model, model) == 0) { id++; @@ -204,9 +162,15 @@ static char *assign_name(VLANClientState *vc1, const char *model) } } + QTAILQ_FOREACH(vc, &non_vlan_clients, next) { + if (vc != vc1 && strcmp(vc->model, model) == 0) { + id++; + } + } + snprintf(buf, sizeof(buf), "%s.%d", model, id); - return qemu_strdup(buf); + return g_strdup(buf); } static ssize_t qemu_deliver_packet(VLANClientState *sender, @@ -230,12 +194,12 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info, assert(info->size >= sizeof(VLANClientState)); - vc = qemu_mallocz(info->size); + vc = g_malloc0(info->size); vc->info = info; - vc->model = qemu_strdup(model); + vc->model = g_strdup(model); if (name) { - vc->name = qemu_strdup(name); + vc->name = g_strdup(name); } else { vc->name = assign_name(vc, model); } @@ -304,9 +268,9 @@ static void qemu_free_vlan_client(VLANClientState *vc) vc->peer->peer = NULL; } } - qemu_free(vc->name); - qemu_free(vc->model); - qemu_free(vc); + g_free(vc->name); + g_free(vc->model); + g_free(vc); } void qemu_del_vlan_client(VLANClientState *vc) @@ -411,11 +375,11 @@ int qemu_can_send_packet(VLANClientState *sender) } /* no can_receive() handler, they can always receive */ - if (!vc->info->can_receive || vc->info->can_receive(vc)) { - return 1; + if (vc->info->can_receive && !vc->info->can_receive(vc)) { + return 0; } } - return 0; + return 1; } static ssize_t qemu_deliver_packet(VLANClientState *sender, @@ -572,30 +536,13 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov, int iovcnt) { uint8_t buffer[4096]; - size_t offset = 0; - int i; - - for (i = 0; i < iovcnt; i++) { - size_t len; + size_t offset; - len = MIN(sizeof(buffer) - offset, iov[i].iov_len); - memcpy(buffer + offset, iov[i].iov_base, len); - offset += len; - } + offset = iov_to_buf(iov, iovcnt, buffer, 0, sizeof(buffer)); return vc->info->receive(vc, buffer, offset); } -static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt) -{ - size_t offset = 0; - int i; - - for (i = 0; i < iovcnt; i++) - offset += iov[i].iov_len; - return offset; -} - static ssize_t qemu_deliver_packet_iov(VLANClientState *sender, unsigned flags, const struct iovec *iov, @@ -605,7 +552,7 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState *sender, VLANClientState *vc = opaque; if (vc->link_down) { - return calc_iov_length(iov, iovcnt); + return iov_size(iov, iovcnt); } if (vc->info->receive_iov) { @@ -633,7 +580,7 @@ static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender, } if (vc->link_down) { - ret = calc_iov_length(iov, iovcnt); + ret = iov_size(iov, iovcnt); continue; } @@ -658,7 +605,7 @@ ssize_t qemu_sendv_packet_async(VLANClientState *sender, NetQueue *queue; if (sender->link_down || (!sender->peer && !sender->vlan)) { - return calc_iov_length(iov, iovcnt); + return iov_size(iov, iovcnt); } if (sender->peer) { @@ -693,7 +640,7 @@ VLANState *qemu_find_vlan(int id, int allocate) return NULL; } - vlan = qemu_mallocz(sizeof(VLANState)); + vlan = g_malloc0(sizeof(VLANState)); vlan->id = id; QTAILQ_INIT(&vlan->clients); @@ -711,6 +658,8 @@ VLANClientState *qemu_find_netdev(const char *id) VLANClientState *vc; QTAILQ_FOREACH(vc, &non_vlan_clients, next) { + if (vc->info->type == NET_CLIENT_TYPE_NIC) + continue; if (!strcmp(vc->name, id)) { return vc; } @@ -761,14 +710,14 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models, int i; if (!nd->model) - nd->model = qemu_strdup(default_model); + nd->model = g_strdup(default_model); for (i = 0 ; models[i]; i++) { if (strcmp(nd->model, models[i]) == 0) return i; } - error_report("qemu: Unsupported NIC model: %s", nd->model); + error_report("Unsupported NIC model: %s", nd->model); return -1; } @@ -784,12 +733,7 @@ int net_handle_fd_param(Monitor *mon, const char *param) return -1; } } else { - char *endptr = NULL; - - fd = strtol(param, &endptr, 10); - if (*endptr || (fd == 0 && param == endptr)) { - return -1; - } + fd = qemu_parse_fd(param); } return fd; @@ -825,27 +769,21 @@ static int net_init_nic(QemuOpts *opts, nd->vlan = vlan; } if (name) { - nd->name = qemu_strdup(name); + nd->name = g_strdup(name); } if (qemu_opt_get(opts, "model")) { - nd->model = qemu_strdup(qemu_opt_get(opts, "model")); + nd->model = g_strdup(qemu_opt_get(opts, "model")); } if (qemu_opt_get(opts, "addr")) { - nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr")); + nd->devaddr = g_strdup(qemu_opt_get(opts, "addr")); } - nd->macaddr[0] = 0x52; - nd->macaddr[1] = 0x54; - nd->macaddr[2] = 0x00; - nd->macaddr[3] = 0x12; - nd->macaddr[4] = 0x34; - nd->macaddr[5] = 0x56 + idx; - if (qemu_opt_get(opts, "macaddr") && - net_parse_macaddr(nd->macaddr, qemu_opt_get(opts, "macaddr")) < 0) { + net_parse_macaddr(nd->macaddr.a, qemu_opt_get(opts, "macaddr")) < 0) { error_report("invalid syntax for ethernet address"); return -1; } + qemu_macaddr_default_if_unset(&nd->macaddr); nd->nvectors = qemu_opt_get_number(opts, "vectors", DEV_NVECTORS_UNSPECIFIED); @@ -888,14 +826,15 @@ static const struct { const char *type; net_client_init_func init; QemuOptDesc desc[NET_MAX_DESC]; -} net_client_types[] = { - { +} net_client_types[NET_CLIENT_TYPE_MAX] = { + [NET_CLIENT_TYPE_NONE] = { .type = "none", .desc = { NET_COMMON_PARAMS_DESC, { /* end of list */ } }, - }, { + }, + [NET_CLIENT_TYPE_NIC] = { .type = "nic", .init = net_init_nic, .desc = { @@ -924,8 +863,9 @@ static const struct { }, { /* end of list */ } }, + }, #ifdef CONFIG_SLIRP - }, { + [NET_CLIENT_TYPE_USER] = { .type = "user", .init = net_init_slirp, .desc = { @@ -985,8 +925,9 @@ static const struct { }, { /* end of list */ } }, + }, #endif - }, { + [NET_CLIENT_TYPE_TAP] = { .type = "tap", .init = net_init_tap, .desc = { @@ -1033,7 +974,8 @@ static const struct { #endif /* _WIN32 */ { /* end of list */ } }, - }, { + }, + [NET_CLIENT_TYPE_SOCKET] = { .type = "socket", .init = net_init_socket, .desc = { @@ -1061,8 +1003,9 @@ static const struct { }, { /* end of list */ } }, + }, #ifdef CONFIG_VDE - }, { + [NET_CLIENT_TYPE_VDE] = { .type = "vde", .init = net_init_vde, .desc = { @@ -1086,8 +1029,9 @@ static const struct { }, { /* end of list */ } }, + }, #endif - }, { + [NET_CLIENT_TYPE_DUMP] = { .type = "dump", .init = net_init_dump, .desc = { @@ -1104,7 +1048,6 @@ static const struct { { /* end of list */ } }, }, - { /* end of list */ } }; int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev) @@ -1152,8 +1095,9 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev) name = qemu_opt_get(opts, "name"); } - for (i = 0; net_client_types[i].type != NULL; i++) { - if (!strcmp(net_client_types[i].type, type)) { + for (i = 0; i < NET_CLIENT_TYPE_MAX; i++) { + if (net_client_types[i].type != NULL && + !strcmp(net_client_types[i].type, type)) { VLANState *vlan = NULL; int ret; @@ -1270,7 +1214,7 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data) VLANClientState *vc; vc = qemu_find_netdev(id); - if (!vc || vc->info->type == NET_CLIENT_TYPE_NIC) { + if (!vc) { qerror_report(QERR_DEVICE_NOT_FOUND, id); return -1; } @@ -1279,25 +1223,38 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data) return 0; } +static void print_net_client(Monitor *mon, VLANClientState *vc) +{ + monitor_printf(mon, "%s: type=%s,%s\n", vc->name, + net_client_types[vc->info->type].type, vc->info_str); +} + void do_info_network(Monitor *mon) { VLANState *vlan; - VLANClientState *vc; + VLANClientState *vc, *peer; + net_client_type type; QTAILQ_FOREACH(vlan, &vlans, next) { monitor_printf(mon, "VLAN %d devices:\n", vlan->id); QTAILQ_FOREACH(vc, &vlan->clients, next) { - monitor_printf(mon, " %s: %s\n", vc->name, vc->info_str); + monitor_printf(mon, " "); + print_net_client(mon, vc); } } monitor_printf(mon, "Devices not on any VLAN:\n"); QTAILQ_FOREACH(vc, &non_vlan_clients, next) { - monitor_printf(mon, " %s: %s", vc->name, vc->info_str); - if (vc->peer) { - monitor_printf(mon, " peer=%s", vc->peer->name); + peer = vc->peer; + type = vc->info->type; + if (!peer || type == NET_CLIENT_TYPE_NIC) { + monitor_printf(mon, " "); + print_net_client(mon, vc); + } /* else it's a netdev connected to a NIC, printed with the NIC */ + if (peer && type == NET_CLIENT_TYPE_NIC) { + monitor_printf(mon, " \\ "); + print_net_client(mon, peer); } - monitor_printf(mon, "\n"); } } @@ -1315,7 +1272,11 @@ int do_set_link(Monitor *mon, const QDict *qdict, QObject **ret_data) } } } - vc = qemu_find_netdev(name); + QTAILQ_FOREACH(vc, &non_vlan_clients, next) { + if (!strcmp(vc->name, name)) { + goto done; + } + } done: if (!vc) { @@ -1328,6 +1289,17 @@ done: if (vc->info->link_status_changed) { vc->info->link_status_changed(vc); } + + /* Notify peer. Don't update peer link status: this makes it possible to + * disconnect from host network without notifying the guest. + * FIXME: is disconnected link status change operation useful? + * + * Current behaviour is compatible with qemu vlans where there could be + * multiple clients that can still communicate with each other in + * disconnected mode. For now maintain this compatibility. */ + if (vc->peer && vc->peer->info->link_status_changed) { + vc->peer->info->link_status_changed(vc->peer); + } return 0; } @@ -1351,15 +1323,29 @@ void net_check_clients(void) { VLANState *vlan; VLANClientState *vc; - int has_nic = 0, has_host_dev = 0; + int i; + + /* Don't warn about the default network setup that you get if + * no command line -net or -netdev options are specified. There + * are two cases that we would otherwise complain about: + * (1) board doesn't support a NIC but the implicit "-net nic" + * requested one + * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic" + * sets up a nic that isn't connected to anything. + */ + if (default_net) { + return; + } QTAILQ_FOREACH(vlan, &vlans, next) { + int has_nic = 0, has_host_dev = 0; + QTAILQ_FOREACH(vc, &vlan->clients, next) { switch (vc->info->type) { case NET_CLIENT_TYPE_NIC: has_nic = 1; break; - case NET_CLIENT_TYPE_SLIRP: + case NET_CLIENT_TYPE_USER: case NET_CLIENT_TYPE_TAP: case NET_CLIENT_TYPE_SOCKET: case NET_CLIENT_TYPE_VDE: @@ -1382,6 +1368,20 @@ void net_check_clients(void) vc->name); } } + + /* Check that all NICs requested via -net nic actually got created. + * NICs created via -device don't need to be checked here because + * they are always instantiated. + */ + for (i = 0; i < MAX_NICS; i++) { + NICInfo *nd = &nd_table[i]; + if (nd->used && !nd->instantiated) { + fprintf(stderr, "Warning: requested NIC (%s, model %s) " + "was not created (not supported by this machine?)\n", + nd->name ? nd->name : "anonymous", + nd->model ? nd->model : "unspecified"); + } + } } static int net_init_client(QemuOpts *opts, void *dummy) diff --git a/net.h b/net.h index 6ceca50..9f633f8 100644 --- a/net.h +++ b/net.h @@ -31,11 +31,13 @@ typedef struct NICConf { typedef enum { NET_CLIENT_TYPE_NONE, NET_CLIENT_TYPE_NIC, - NET_CLIENT_TYPE_SLIRP, + NET_CLIENT_TYPE_USER, NET_CLIENT_TYPE_TAP, NET_CLIENT_TYPE_SOCKET, NET_CLIENT_TYPE_VDE, - NET_CLIENT_TYPE_DUMP + NET_CLIENT_TYPE_DUMP, + + NET_CLIENT_TYPE_MAX } net_client_type; typedef void (NetPoll)(VLANClientState *, bool enable); @@ -127,13 +129,14 @@ int do_set_link(Monitor *mon, const QDict *qdict, QObject **ret_data); #define MAX_NICS 8 struct NICInfo { - uint8_t macaddr[6]; + MACAddr macaddr; char *model; char *name; char *devaddr; VLANState *vlan; VLANClientState *netdev; - int used; + int used; /* is this slot in nd_table[] being used? */ + int instantiated; /* does this NICInfo correspond to an instantiated NIC? */ int nvectors; }; @@ -171,11 +174,6 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data); #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown" -#ifdef __sun__ -#define SMBD_COMMAND "/usr/sfw/sbin/smbd" -#else -#define SMBD_COMMAND "/usr/sbin/smbd" -#endif void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd); diff --git a/net/dump.c b/net/dump.c index 6db7ecf..0d0cbb2 100644 --- a/net/dump.c +++ b/net/dump.c @@ -24,9 +24,9 @@ #include "dump.h" #include "qemu-common.h" -#include "sysemu.h" #include "qemu-error.h" #include "qemu-log.h" +#include "qemu-timer.h" typedef struct DumpState { VLANClientState nc; @@ -67,7 +67,7 @@ static ssize_t dump_receive(VLANClientState *nc, const uint8_t *buf, size_t size return size; } - ts = muldiv64(qemu_get_clock(vm_clock), 1000000, get_ticks_per_sec()); + ts = muldiv64(qemu_get_clock_ns(vm_clock), 1000000, get_ticks_per_sec()); caplen = size > s->pcap_caplen ? s->pcap_caplen : size; hdr.ts.tv_sec = ts / 1000000; diff --git a/net/queue.c b/net/queue.c index 2ea6cd0..1ab5247 100644 --- a/net/queue.c +++ b/net/queue.c @@ -63,7 +63,7 @@ NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver, { NetQueue *queue; - queue = qemu_mallocz(sizeof(NetQueue)); + queue = g_malloc0(sizeof(NetQueue)); queue->deliver = deliver; queue->deliver_iov = deliver_iov; @@ -82,10 +82,10 @@ void qemu_del_net_queue(NetQueue *queue) QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) { QTAILQ_REMOVE(&queue->packets, packet, entry); - qemu_free(packet); + g_free(packet); } - qemu_free(queue); + g_free(queue); } static ssize_t qemu_net_queue_append(NetQueue *queue, @@ -97,7 +97,7 @@ static ssize_t qemu_net_queue_append(NetQueue *queue, { NetPacket *packet; - packet = qemu_malloc(sizeof(NetPacket) + size); + packet = g_malloc(sizeof(NetPacket) + size); packet->sender = sender; packet->flags = flags; packet->size = size; @@ -124,7 +124,7 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue, max_len += iov[i].iov_len; } - packet = qemu_malloc(sizeof(NetPacket) + max_len); + packet = g_malloc(sizeof(NetPacket) + max_len); packet->sender = sender; packet->sent_cb = sent_cb; packet->flags = flags; @@ -227,7 +227,7 @@ void qemu_net_queue_purge(NetQueue *queue, VLANClientState *from) QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) { if (packet->sender == from) { QTAILQ_REMOVE(&queue->packets, packet, entry); - qemu_free(packet); + g_free(packet); } } } @@ -255,6 +255,6 @@ void qemu_net_queue_flush(NetQueue *queue) packet->sent_cb(packet->sender, ret); } - qemu_free(packet); + g_free(packet); } } diff --git a/net/slirp.c b/net/slirp.c index 96dff61..6646ecb 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -30,7 +30,6 @@ #endif #include "net.h" #include "monitor.h" -#include "sysemu.h" #include "qemu_socket.h" #include "slirp/libslirp.h" @@ -129,7 +128,7 @@ static void net_slirp_cleanup(VLANClientState *nc) } static NetClientInfo net_slirp_info = { - .type = NET_CLIENT_TYPE_SLIRP, + .type = NET_CLIENT_TYPE_USER, .size = sizeof(SlirpState), .receive = net_slirp_receive, .cleanup = net_slirp_cleanup, @@ -241,7 +240,8 @@ static int net_slirp_init(VLANState *vlan, const char *model, nc = qemu_new_net_client(&net_slirp_info, vlan, NULL, model, name); snprintf(nc->info_str, sizeof(nc->info_str), - "net=%s, restricted=%c", inet_ntoa(net), restricted ? 'y' : 'n'); + "net=%s,restrict=%s", inet_ntoa(net), + restricted ? "on" : "off"); s = DO_UPCAST(SlirpState, nc, nc); @@ -305,7 +305,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict) { struct in_addr host_addr = { .s_addr = INADDR_ANY }; int host_port; - char buf[256] = ""; + char buf[256]; const char *src_str, *p; SlirpState *s; int is_udp = 0; @@ -325,11 +325,10 @@ void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict) return; } - if (!src_str || !src_str[0]) - goto fail_syntax; - p = src_str; - get_str_sep(buf, sizeof(buf), &p, ':'); + if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) { + goto fail_syntax; + } if (!strcmp(buf, "tcp") || buf[0] == '\0') { is_udp = 0; @@ -413,9 +412,8 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr, guest_port) < 0) { - // normal case with sdb & multi emulator => comment-out - // error_report("could not set up host forwarding rule '%s'", - // redir_str); + error_report("could not set up host forwarding rule '%s'", + redir_str); return -1; } return 0; @@ -451,7 +449,7 @@ int net_slirp_redir(const char *redir_str) struct slirp_config_str *config; if (QTAILQ_EMPTY(&slirp_stacks)) { - config = qemu_malloc(sizeof(*config)); + config = g_malloc(sizeof(*config)); pstrcpy(config->str, sizeof(config->str), redir_str); config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY; config->next = slirp_configs; @@ -530,7 +528,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir, fclose(f); snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s", - SMBD_COMMAND, smb_conf); + CONFIG_SMBD_COMMAND, smb_conf); if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0) { slirp_smb_cleanup(s); @@ -615,19 +613,19 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, goto fail_syntax; } - fwd = qemu_malloc(sizeof(struct GuestFwd)); - snprintf(buf, sizeof(buf), "guestfwd.tcp:%d", port); - fwd->hd = qemu_chr_open(buf, p, NULL); + fwd = g_malloc(sizeof(struct GuestFwd)); + snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port); + fwd->hd = qemu_chr_new(buf, p, NULL); if (!fwd->hd) { error_report("could not open guest forwarding device '%s'", buf); - qemu_free(fwd); + g_free(fwd); return -1; } if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) { error_report("conflicting/invalid host:port in guest forwarding " "rule '%s'", config_str); - qemu_free(fwd); + g_free(fwd); return -1; } fwd->server = server; @@ -663,7 +661,7 @@ static int net_init_slirp_configs(const char *name, const char *value, void *opa return 0; } - config = qemu_mallocz(sizeof(*config)); + config = g_malloc0(sizeof(*config)); pstrcpy(config->str, sizeof(config->str), value); @@ -691,6 +689,7 @@ int net_init_slirp(QemuOpts *opts, const char *bootfile; const char *smb_export; const char *vsmbsrv; + const char *restrict_opt; char *vnet = NULL; int restricted = 0; int ret; @@ -704,11 +703,23 @@ int net_init_slirp(QemuOpts *opts, smb_export = qemu_opt_get(opts, "smb"); vsmbsrv = qemu_opt_get(opts, "smbserver"); + restrict_opt = qemu_opt_get(opts, "restrict"); + if (restrict_opt) { + if (!strcmp(restrict_opt, "on") || + !strcmp(restrict_opt, "yes") || !strcmp(restrict_opt, "y")) { + restricted = 1; + } else if (strcmp(restrict_opt, "off") && + strcmp(restrict_opt, "no") && strcmp(restrict_opt, "n")) { + error_report("invalid option: 'restrict=%s'", restrict_opt); + return -1; + } + } + if (qemu_opt_get(opts, "ip")) { const char *ip = qemu_opt_get(opts, "ip"); int l = strlen(ip) + strlen("/24") + 1; - vnet = qemu_malloc(l); + vnet = g_malloc(l); /* emulate legacy ip= parameter */ pstrcpy(vnet, l, ip); @@ -717,14 +728,9 @@ int net_init_slirp(QemuOpts *opts, if (qemu_opt_get(opts, "net")) { if (vnet) { - qemu_free(vnet); + g_free(vnet); } - vnet = qemu_strdup(qemu_opt_get(opts, "net")); - } - - if (qemu_opt_get(opts, "restrict") && - qemu_opt_get(opts, "restrict")[0] == 'y') { - restricted = 1; + vnet = g_strdup(qemu_opt_get(opts, "net")); } qemu_opt_foreach(opts, net_init_slirp_configs, NULL, 0); @@ -736,10 +742,10 @@ int net_init_slirp(QemuOpts *opts, while (slirp_configs) { config = slirp_configs; slirp_configs = config->next; - qemu_free(config); + g_free(config); } - qemu_free(vnet); + g_free(vnet); return ret; } @@ -757,7 +763,7 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret if (QTAILQ_EMPTY(&slirp_stacks)) { struct slirp_config_str *config; - config = qemu_malloc(sizeof(*config)); + config = g_malloc(sizeof(*config)); pstrcpy(config->str, sizeof(config->str), optarg); config->flags = SLIRP_CFG_LEGACY; config->next = slirp_configs; diff --git a/net/socket.c b/net/socket.c index 3182b37..e9ef128 100644 --- a/net/socket.c +++ b/net/socket.c @@ -76,7 +76,7 @@ static void net_socket_send(void *opaque) uint8_t buf1[4096]; const uint8_t *buf; - size = recv(s->fd, (void *)buf1, sizeof(buf1), 0); + size = qemu_recv(s->fd, buf1, sizeof(buf1), 0); if (size < 0) { err = socket_error(); if (err != EWOULDBLOCK) @@ -138,7 +138,7 @@ static void net_socket_send_dgram(void *opaque) NetSocketState *s = opaque; int size; - size = recv(s->fd, (void *)s->buf, sizeof(s->buf), 0); + size = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0); if (size < 0) return; if (size == 0) { @@ -154,6 +154,12 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr struct ip_mreq imr; int fd; int val, ret; +#ifdef __OpenBSD__ + unsigned char loop; +#else + int loop; +#endif + if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n", inet_ntoa(mcastaddr->sin_addr), @@ -197,9 +203,9 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr } /* Force mcast msgs to loopback (eg. several QEMUs in same host */ - val = 1; + loop = 1; ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, - (const char *)&val, sizeof(val)); + (const char *)&loop, sizeof(loop)); if (ret < 0) { perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)"); goto fail; @@ -398,7 +404,7 @@ static int net_socket_listen_init(VLANState *vlan, if (parse_host_port(&saddr, host_str) < 0) return -1; - s = qemu_mallocz(sizeof(NetSocketListenState)); + s = g_malloc0(sizeof(NetSocketListenState)); fd = qemu_socket(PF_INET, SOCK_STREAM, 0); if (fd < 0) { @@ -422,8 +428,8 @@ static int net_socket_listen_init(VLANState *vlan, return -1; } s->vlan = vlan; - s->model = qemu_strdup(model); - s->name = name ? qemu_strdup(name) : NULL; + s->model = g_strdup(model); + s->name = name ? g_strdup(name) : NULL; s->fd = fd; qemu_set_fd_handler(fd, net_socket_accept, NULL, s); return 0; @@ -457,7 +463,7 @@ static int net_socket_connect_init(VLANState *vlan, } else if (err == EINPROGRESS) { break; #ifdef _WIN32 - } else if (err == WSAEALREADY) { + } else if (err == WSAEALREADY || err == WSAEINVAL) { break; #endif } else { @@ -530,7 +536,7 @@ int net_init_socket(QemuOpts *opts, qemu_opt_get(opts, "connect") || qemu_opt_get(opts, "mcast") || qemu_opt_get(opts, "localaddr")) { - error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=\n"); + error_report("listen=, connect=, mcast= and localaddr= is invalid with fd="); return -1; } @@ -550,7 +556,7 @@ int net_init_socket(QemuOpts *opts, qemu_opt_get(opts, "connect") || qemu_opt_get(opts, "mcast") || qemu_opt_get(opts, "localaddr")) { - error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=\n"); + error_report("fd=, connect=, mcast= and localaddr= is invalid with listen="); return -1; } @@ -566,7 +572,7 @@ int net_init_socket(QemuOpts *opts, qemu_opt_get(opts, "listen") || qemu_opt_get(opts, "mcast") || qemu_opt_get(opts, "localaddr")) { - error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=\n"); + error_report("fd=, listen=, mcast= and localaddr= is invalid with connect="); return -1; } diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 2f3efde..4b6b3a4 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -28,6 +28,8 @@ #include "qemu-error.h" #ifdef __NetBSD__ +#include +#include #include #endif @@ -40,8 +42,12 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required) { int fd; +#ifdef TAPGIFNAME + struct ifreq ifr; +#else char *dev; struct stat s; +#endif #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) /* if no ifname is given, always start the search from tap0/tun0. */ @@ -77,14 +83,30 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required #else TFR(fd = open("/dev/tap", O_RDWR)); if (fd < 0) { - fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n"); + fprintf(stderr, + "warning: could not open /dev/tap: no virtual network emulation: %s\n", + strerror(errno)); return -1; } #endif - fstat(fd, &s); +#ifdef TAPGIFNAME + if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) { + fprintf(stderr, "warning: could not get tap name: %s\n", + strerror(errno)); + return -1; + } + pstrcpy(ifname, ifname_size, ifr.ifr_name); +#else + if (fstat(fd, &s) < 0) { + fprintf(stderr, + "warning: could not stat /dev/tap: no virtual network emulation: %s\n", + strerror(errno)); + return -1; + } dev = devname(s.st_rdev, S_IFCHR); pstrcpy(ifname, ifname_size, dev); +#endif if (*vnet_hdr) { /* BSD doesn't have IFF_VNET_HDR */ diff --git a/net/tap-linux.c b/net/tap-linux.c index ff8cad0..41d581b 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -73,7 +73,11 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d"); ret = ioctl(fd, TUNSETIFF, (void *) &ifr); if (ret != 0) { - error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name); + if (ifname[0] != '\0') { + error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name); + } else { + error_report("could not configure %s: %m", PATH_NET_TUN); + } close(fd); return -1; } diff --git a/net/tap-win32.c b/net/tap-win32.c index 081904e..8918147 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -480,7 +480,7 @@ static int tap_win32_write(tap_win32_overlapped_t *overlapped, } } - return 0; + return write_size; } static DWORD WINAPI tap_win32_thread_entry(LPVOID param) @@ -591,7 +591,7 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle, USERMODEDEVICEDIR, device_guid, TAPSUFFIX); - +#ifndef CONFIG_MARU handle = CreateFile ( device_path, GENERIC_READ | GENERIC_WRITE, @@ -600,7 +600,17 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0 ); +#else + handle = CreateFile ( + g_win32_locale_filename_from_utf8(device_path), + GENERIC_READ | GENERIC_WRITE, + 0, + 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, + 0 ); +#endif if (handle == INVALID_HANDLE_VALUE) { return -1; } diff --git a/net/tap.c b/net/tap.c index b8cd252..1f26dc9 100644 --- a/net/tap.c +++ b/net/tap.c @@ -27,7 +27,6 @@ #include "config-host.h" -#include #include #include #include diff --git a/net/vde.c b/net/vde.c index 0b46fa6..ac48ab2 100644 --- a/net/vde.c +++ b/net/vde.c @@ -31,7 +31,6 @@ #include "qemu-char.h" #include "qemu-common.h" #include "qemu-option.h" -#include "sysemu.h" typedef struct VDEState { VLANClientState nc; diff --git a/notify.c b/notify.c index bcd3fc5..a6bac1f 100644 --- a/notify.c +++ b/notify.c @@ -29,11 +29,11 @@ void notifier_list_remove(NotifierList *list, Notifier *notifier) QTAILQ_REMOVE(&list->notifiers, notifier, node); } -void notifier_list_notify(NotifierList *list) +void notifier_list_notify(NotifierList *list, void *data) { Notifier *notifier, *next; QTAILQ_FOREACH_SAFE(notifier, &list->notifiers, node, next) { - notifier->notify(notifier); + notifier->notify(notifier, data); } } diff --git a/notify.h b/notify.h index b40522f..54fc57c 100644 --- a/notify.h +++ b/notify.h @@ -20,7 +20,7 @@ typedef struct Notifier Notifier; struct Notifier { - void (*notify)(Notifier *notifier); + void (*notify)(Notifier *notifier, void *data); QTAILQ_ENTRY(Notifier) node; }; @@ -38,6 +38,6 @@ void notifier_list_add(NotifierList *list, Notifier *notifier); void notifier_list_remove(NotifierList *list, Notifier *notifier); -void notifier_list_notify(NotifierList *list); +void notifier_list_notify(NotifierList *list, void *data); #endif diff --git a/os-posix.c b/os-posix.c index 38c29d1..dc4a6bb 100644 --- a/os-posix.c +++ b/os-posix.c @@ -31,6 +31,7 @@ /*needed for MAP_POPULATE before including qemu-options.h */ #include #include +#include #include /* Needed early for CONFIG_BSD etc. */ @@ -41,6 +42,7 @@ #ifdef CONFIG_LINUX #include +#include #endif #ifdef CONFIG_EVENTFD @@ -61,14 +63,9 @@ void os_setup_early_signal_handling(void) sigaction(SIGPIPE, &act, NULL); } -static void termsig_handler(int signal) +static void termsig_handler(int signal, siginfo_t *info, void *c) { - qemu_system_shutdown_request(); -} - -static void sigchld_handler(int signal) -{ - waitpid(-1, NULL, WNOHANG); + qemu_system_killed(info->si_signo, info->si_pid); } void os_setup_signal_handling(void) @@ -76,14 +73,11 @@ void os_setup_signal_handling(void) struct sigaction act; memset(&act, 0, sizeof(act)); - act.sa_handler = termsig_handler; + act.sa_sigaction = termsig_handler; + act.sa_flags = SA_SIGINFO; sigaction(SIGINT, &act, NULL); sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); - - act.sa_handler = sigchld_handler; - act.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &act, NULL); } /* Find a likely location for support files using the location of the binary. @@ -134,12 +128,12 @@ char *os_find_datadir(const char *argv0) max_len = strlen(dir) + MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1; - res = qemu_mallocz(max_len); + res = g_malloc0(max_len); snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX); if (access(res, R_OK)) { snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX); if (access(res, R_OK)) { - qemu_free(res); + g_free(res); res = NULL; } } @@ -206,6 +200,11 @@ static void change_process_uid(void) fprintf(stderr, "Failed to setgid(%d)\n", user_pwd->pw_gid); exit(1); } + if (initgroups(user_pwd->pw_name, user_pwd->pw_gid) < 0) { + fprintf(stderr, "Failed to initgroups(\"%s\", %d)\n", + user_pwd->pw_name, user_pwd->pw_gid); + exit(1); + } if (setuid(user_pwd->pw_uid) < 0) { fprintf(stderr, "Failed to setuid(%d)\n", user_pwd->pw_uid); exit(1); @@ -373,12 +372,24 @@ int qemu_create_pidfile(const char *filename) return -1; } if (lockf(fd, F_TLOCK, 0) == -1) { + close(fd); return -1; } - len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); + len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid()); if (write(fd, buffer, len) != len) { + close(fd); return -1; } + close(fd); return 0; } + +int qemu_get_thread_id(void) +{ +#if defined (__linux__) + return syscall(SYS_gettid); +#else + return getpid(); +#endif +} diff --git a/os-win32.c b/os-win32.c index 566d5e9..7970515 100644 --- a/os-win32.c +++ b/os-win32.c @@ -41,146 +41,31 @@ int setenv(const char *name, const char *value, int overwrite) int result = 0; if (overwrite || !getenv(name)) { size_t length = strlen(name) + strlen(value) + 2; - char *string = qemu_malloc(length); + char *string = g_malloc(length); snprintf(string, length, "%s=%s", name, value); result = putenv(string); } return result; } -/***********************************************************/ -/* Polling handling */ - -typedef struct PollingEntry { - PollingFunc *func; - void *opaque; - struct PollingEntry *next; -} PollingEntry; - -static PollingEntry *first_polling_entry; - -int qemu_add_polling_cb(PollingFunc *func, void *opaque) -{ - PollingEntry **ppe, *pe; - pe = qemu_mallocz(sizeof(PollingEntry)); - pe->func = func; - pe->opaque = opaque; - for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next); - *ppe = pe; - return 0; -} - -void qemu_del_polling_cb(PollingFunc *func, void *opaque) -{ - PollingEntry **ppe, *pe; - for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) { - pe = *ppe; - if (pe->func == func && pe->opaque == opaque) { - *ppe = pe->next; - qemu_free(pe); - break; - } - } -} - -/***********************************************************/ -/* Wait objects support */ -typedef struct WaitObjects { - int num; - HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; - WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1]; - void *opaque[MAXIMUM_WAIT_OBJECTS + 1]; -} WaitObjects; - -static WaitObjects wait_objects = {0}; - -int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) -{ - WaitObjects *w = &wait_objects; - - if (w->num >= MAXIMUM_WAIT_OBJECTS) - return -1; - w->events[w->num] = handle; - w->func[w->num] = func; - w->opaque[w->num] = opaque; - w->num++; - return 0; -} - -void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) -{ - int i, found; - WaitObjects *w = &wait_objects; - - found = 0; - for (i = 0; i < w->num; i++) { - if (w->events[i] == handle) - found = 1; - if (found) { - w->events[i] = w->events[i + 1]; - w->func[i] = w->func[i + 1]; - w->opaque[i] = w->opaque[i + 1]; - } - } - if (found) - w->num--; -} - -void os_host_main_loop_wait(int *timeout) -{ - int ret, ret2, i; - PollingEntry *pe; - - /* XXX: need to suppress polling by better using win32 events */ - ret = 0; - for(pe = first_polling_entry; pe != NULL; pe = pe->next) { - ret |= pe->func(pe->opaque); - } - if (ret == 0) { - int err; - WaitObjects *w = &wait_objects; - - ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout); - if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) { - if (w->func[ret - WAIT_OBJECT_0]) - w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]); - - /* Check for additional signaled events */ - for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) { - - /* Check if event is signaled */ - ret2 = WaitForSingleObject(w->events[i], 0); - if(ret2 == WAIT_OBJECT_0) { - if (w->func[i]) - w->func[i](w->opaque[i]); - } else if (ret2 == WAIT_TIMEOUT) { - } else { - err = GetLastError(); - fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err); - } - } - } else if (ret == WAIT_TIMEOUT) { - } else { - err = GetLastError(); - fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err); - } - } - - *timeout = 0; -} - static BOOL WINAPI qemu_ctrl_handler(DWORD type) { exit(STATUS_CONTROL_C_EXIT); return TRUE; } +#ifdef CONFIG_MARU +void os_setup_early_signal_handling(void) +{ + SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE); +} +#else void os_setup_early_signal_handling(void) { /* Note: cpu_interrupt() is currently not SMP safe, so we force QEMU to run on a single CPU */ HANDLE h; - DWORD mask, smask; + DWORD_PTR mask, smask; int i; SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE); @@ -197,6 +82,7 @@ void os_setup_early_signal_handling(void) } } } +#endif /* CONFIG_MARU */ /* Look for support files in the same directory as the executable. */ char *os_find_datadir(const char *argv0) @@ -216,7 +102,7 @@ char *os_find_datadir(const char *argv0) p--; *p = 0; if (access(buf, R_OK) == 0) { - return qemu_strdup(buf); + return g_strdup(buf); } return NULL; } @@ -249,18 +135,27 @@ int qemu_create_pidfile(const char *filename) OVERLAPPED overlap; BOOL ret; memset(&overlap, 0, sizeof(overlap)); - +#ifndef CONFIG_MARU file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +#else + file = CreateFile(g_win32_locale_filename_from_utf8(filename), GENERIC_WRITE, FILE_SHARE_READ, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +#endif if (file == INVALID_HANDLE_VALUE) { return -1; } - len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); - ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, - &overlap, NULL); + len = snprintf(buffer, sizeof(buffer), "%d\n", getpid()); + ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len, + NULL, &overlap); + CloseHandle(file); if (ret == 0) { return -1; } return 0; } + +int qemu_get_thread_id(void) +{ + return GetCurrentThreadId(); +} diff --git a/osdep.c b/osdep.c index 327583b..56e6963 100644 --- a/osdep.c +++ b/osdep.c @@ -46,7 +46,6 @@ extern int madvise(caddr_t, size_t, int); #include "qemu-common.h" #include "trace.h" -#include "sysemu.h" #include "qemu_socket.h" int qemu_madvise(void *addr, size_t len, int advice) diff --git a/osdep.h b/osdep.h index 8bd30d7..432b91e 100644 --- a/osdep.h +++ b/osdep.h @@ -8,9 +8,7 @@ #include #endif -#ifndef _WIN32 #include -#endif #ifndef glue #define xglue(x, y) x ## y @@ -57,6 +55,10 @@ #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif +#ifndef DIV_ROUND_UP +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#endif + #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif @@ -79,13 +81,7 @@ #define qemu_printf printf -#if defined (__GNUC__) && defined (__GNUC_MINOR__) -# define QEMU_GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -#else -# define QEMU_GNUC_PREREQ(maj, min) 0 -#endif - +int qemu_daemon(int nochdir, int noclose); void *qemu_memalign(size_t alignment, size_t size); void *qemu_vmalloc(size_t size); void qemu_vfree(void *ptr); @@ -125,6 +121,32 @@ void qemu_vfree(void *ptr); int qemu_madvise(void *addr, size_t len, int advice); +#if defined(__HAIKU__) && defined(__i386__) +#define FMT_pid "%ld" +#elif defined(WIN64) +#define FMT_pid "%" PRId64 +#else +#define FMT_pid "%d" +#endif + int qemu_create_pidfile(const char *filename); +int qemu_get_thread_id(void); + +#ifdef _WIN32 +static inline void qemu_timersub(const struct timeval *val1, + const struct timeval *val2, + struct timeval *res) +{ + res->tv_sec = val1->tv_sec - val2->tv_sec; + if (val1->tv_usec < val2->tv_usec) { + res->tv_sec--; + res->tv_usec = val1->tv_usec - val2->tv_usec + 1000 * 1000; + } else { + res->tv_usec = val1->tv_usec - val2->tv_usec; + } +} +#else +#define qemu_timersub timersub +#endif #endif diff --git a/oslib-posix.c b/oslib-posix.c index 7bc5f7c..bef0be1 100644 --- a/oslib-posix.c +++ b/oslib-posix.c @@ -26,15 +26,66 @@ * THE SOFTWARE. */ +/* The following block of code temporarily renames the daemon() function so the + compiler does not see the warning associated with it in stdlib.h on OSX */ +#ifdef __APPLE__ +#define daemon qemu_fake_daemon_function +#include +#undef daemon +extern int daemon(int, int); +#endif + +#if defined(__linux__) && defined(__x86_64__) + /* Use 2 MiB alignment so transparent hugepages can be used by KVM. + Valgrind does not support alignments larger than 1 MiB, + therefore we need special code which handles running on Valgrind. */ +# define QEMU_VMALLOC_ALIGN (512 * 4096) +# define CONFIG_VALGRIND +#else +# define QEMU_VMALLOC_ALIGN getpagesize() +#endif + #include "config-host.h" #include "sysemu.h" #include "trace.h" #include "qemu_socket.h" + +#ifdef CONFIG_MARU +#include "../tizen/src/skin/maruskin_client.h" +#endif + +#if defined(CONFIG_VALGRIND) +static int running_on_valgrind = -1; +#else +# define running_on_valgrind 0 +#endif + +int qemu_daemon(int nochdir, int noclose) +{ + return daemon(nochdir, noclose); +} + void *qemu_oom_check(void *ptr) { if (ptr == NULL) { fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno)); + +#ifdef CONFIG_MARU + char _msg[] = "Failed to allocate memory in qemu."; + char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, }; + + int len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) + strlen(JAR_SKINFILE_PATH) + + strlen(JAVA_SIMPLEMODE_OPTION) + strlen(_msg) + 7; + if (len > JAVA_MAX_COMMAND_LENGTH) { + len = JAVA_MAX_COMMAND_LENGTH; + } + + snprintf(cmd, len, "%s %s %s %s=\"%s\"", + JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAR_SKINFILE_PATH, JAVA_SIMPLEMODE_OPTION, _msg); + int ret = system(cmd); +#endif + abort(); } return ptr; @@ -63,7 +114,24 @@ void *qemu_memalign(size_t alignment, size_t size) /* alloc shared memory pages */ void *qemu_vmalloc(size_t size) { - return qemu_memalign(getpagesize(), size); + void *ptr; + size_t align = QEMU_VMALLOC_ALIGN; + +#if defined(CONFIG_VALGRIND) + if (running_on_valgrind < 0) { + /* First call, test whether we are running on Valgrind. + This is a substitute for RUNNING_ON_VALGRIND from valgrind.h. */ + const char *ld = getenv("LD_PRELOAD"); + running_on_valgrind = (ld != NULL && strstr(ld, "vgpreload")); + } +#endif + + if (size < align || running_on_valgrind) { + align = getpagesize(); + } + ptr = qemu_memalign(align, size); + trace_qemu_vmalloc(size, ptr); + return ptr; } void qemu_vfree(void *ptr) @@ -72,6 +140,13 @@ void qemu_vfree(void *ptr) free(ptr); } +void socket_set_block(int fd) +{ + int f; + f = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, f & ~O_NONBLOCK); +} + void socket_set_nonblock(int fd) { int f; @@ -108,8 +183,7 @@ int qemu_pipe(int pipefd[2]) return ret; } -int qemu_utimensat(int dirfd, const char *path, const struct timespec *times, - int flags) +int qemu_utimens(const char *path, const struct timespec *times) { struct timeval tv[2], tv_now; struct stat st; @@ -117,7 +191,7 @@ int qemu_utimensat(int dirfd, const char *path, const struct timespec *times, #ifdef CONFIG_UTIMENSAT int ret; - ret = utimensat(dirfd, path, times, flags); + ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW); if (ret != -1 || errno != ENOSYS) { return ret; } diff --git a/oslib-win32.c b/oslib-win32.c index ab29eae..1ad6b8a 100644 --- a/oslib-win32.c +++ b/oslib-win32.c @@ -31,10 +31,112 @@ #include "trace.h" #include "qemu_socket.h" +#ifdef CONFIG_MARU +#include "../tizen/src/skin/maruskin_client.h" + +#ifdef CONFIG_WIN32 +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); +LPFN_ISWOW64PROCESS fnIsWow64Process; + +int is_wow64_temp(void) +{ + int result = 0; + + //IsWow64Process is not available on all supported versions of Windows. + //Use GetModuleHandle to get a handle to the DLL that contains the function + //and GetProcAddress to get a pointer to the function if available. + + fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress( + GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); + + if(NULL != fnIsWow64Process) + { + if (!fnIsWow64Process(GetCurrentProcess(),&result)) + { + //handle error + //INFO("Can not find 'IsWow64Process'\n"); + } + } + return result; +} + +int get_java_path_temp(char** java_path) +{ + HKEY hKeyNew; + HKEY hKey; + //char strJavaRuntimePath[JAVA_MAX_COMMAND_LENGTH] = {0}; + char strChoosenName[JAVA_MAX_COMMAND_LENGTH] = {0}; + char strSubKeyName[JAVA_MAX_COMMAND_LENGTH] = {0}; + char strJavaHome[JAVA_MAX_COMMAND_LENGTH] = {0}; + int index; + DWORD dwSubKeyNameMax = JAVA_MAX_COMMAND_LENGTH; + DWORD dwBufLen = JAVA_MAX_COMMAND_LENGTH; + + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\JavaSoft\\Java Runtime Environment", 0, + KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | MY_KEY_WOW64_64KEY, &hKey); + RegEnumKeyEx(hKey, 0, (LPSTR)strSubKeyName, &dwSubKeyNameMax, NULL, NULL, NULL, NULL); + strcpy(strChoosenName, strSubKeyName); + + index = 1; + while (ERROR_SUCCESS == RegEnumKeyEx(hKey, index, (LPSTR)strSubKeyName, &dwSubKeyNameMax, + NULL, NULL, NULL, NULL)) { + if (strcmp(strChoosenName, strSubKeyName) < 0) { + strcpy(strChoosenName, strSubKeyName); + } + index++; + } + + RegOpenKeyEx(hKey, strChoosenName, 0, KEY_QUERY_VALUE | MY_KEY_WOW64_64KEY, &hKeyNew); + RegQueryValueEx(hKeyNew, "JavaHome", NULL, NULL, (LPBYTE)strJavaHome, &dwBufLen); + RegCloseKey(hKey); + if (strJavaHome[0] != '\0') { + sprintf(*java_path, "\"%s\\bin\\java\"", strJavaHome); + //strcpy(*java_path, strJavaHome); + //strcat(*java_path, "\\bin\\java"); + } else { + return 0; + } + return 1; +} +#endif +#endif // CONFIG_MARU + void *qemu_oom_check(void *ptr) { if (ptr == NULL) { fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError()); + +#ifdef CONFIG_MARU + char _msg[] = "Failed to allocate memory in qemu."; + char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, }; + +#ifdef CONFIG_WIN32 + char* JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH); + memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH); + if (is_wow64_temp()) { + if (!get_java_path_temp(&JAVA_EXEFILE_PATH)) { + strcpy(JAVA_EXEFILE_PATH, "java"); + } + } else { + strcpy(JAVA_EXEFILE_PATH, "java"); + } +#endif + int len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) + strlen(JAR_SKINFILE_PATH) + + strlen(JAVA_SIMPLEMODE_OPTION) + strlen(_msg) + 7; + if (len > JAVA_MAX_COMMAND_LENGTH) { + len = JAVA_MAX_COMMAND_LENGTH; + } + + snprintf(cmd, len, "%s %s %s %s=\"%s\"", + JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAR_SKINFILE_PATH, JAVA_SIMPLEMODE_OPTION, _msg); + int ret = WinExec(cmd, SW_SHOW); +#ifdef CONFIG_WIN32 + // for 64bit windows + free(JAVA_EXEFILE_PATH); + JAVA_EXEFILE_PATH=0; +#endif +#endif + abort(); } return ptr; @@ -73,6 +175,12 @@ void qemu_vfree(void *ptr) VirtualFree(ptr, 0, MEM_RELEASE); } +void socket_set_block(int fd) +{ + unsigned long opt = 0; + ioctlsocket(fd, FIONBIO, &opt); +} + void socket_set_nonblock(int fd) { unsigned long opt = 1; @@ -93,13 +201,6 @@ void qemu_set_cloexec(int fd) { } -/* mingw32 needs ffs for compilations without optimization. */ -int ffs(int i) -{ - /* Use gcc's builtin ffs. */ - return __builtin_ffs(i); -} - /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ #define _W32_FT_OFFSET (116444736000000000ULL) diff --git a/package/build.linux b/package/build.linux deleted file mode 100755 index 9d69c62..0000000 --- a/package/build.linux +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -xe -# clean -clean() -{ - cd $SRCDIR/tizen/ - if test -e "Makefile" - then - make clean - fi - rm -rf $SRCDIR/*.zip - rm -rf $SRCDIR/*.tar.gz -} - -# build -build() -{ - cd $SRCDIR/tizen/ - autoconf - ./configure - make -} - -# install -install() -{ - BIN_DIR=$SRCDIR/package/emulator.package.linux/data - mkdir -p $BIN_DIR - - cd $SRCDIR/tizen - make install - mv Emulator $BIN_DIR - cp $SRCDIR/package/emulator.install.linux $BIN_DIR/../ - cp $SRCDIR/package/emulator.remove.linux $BIN_DIR/../ -} - -[ "$1" = "clean" ] && clean -[ "$1" = "build" ] && build -[ "$1" = "install" ] && install - -echo "success" diff --git a/package/build.windows b/package/build.windows deleted file mode 100755 index 64281a5..0000000 --- a/package/build.windows +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh -xe -# clean -clean() -{ - cd $SRCDIR/tizen/ - if test -e "Makefile" - then - make clean - fi - rm -rf $SRCDIR/*.zip - rm -rf $SRCDIR/*.tar.gz -} - -# build -build() -{ - cd $SRCDIR/tizen/ - autoconf - ./configure - make -} - -# install -install() -{ - BIN_DIR=$SRCDIR/package/emulator.package.windows/data - VTM_DIR=$BIN_DIR/Emulator/bin/emulator-manager.exe - EMUL_DIR=$BIN_DIR/Emulator/bin/emulator-x86.exe - - mkdir -p $BIN_DIR - - cd $SRCDIR/tizen - make install - mv Emulator $BIN_DIR - editbin.exe /SUBSYSTEM:WINDOWS $VTM_DIR - editbin.exe /SUBSYSTEM:WINDOWS $EMUL_DIR - cp $SRCDIR/package/emulator.install.windows $BIN_DIR/../ - cp $SRCDIR/package/emulator.remove.windows $BIN_DIR/../ -} - -[ "$1" = "clean" ] && clean -[ "$1" = "build" ] && build -[ "$1" = "install" ] && install -echo "Success" diff --git a/package/emulator.install.linux b/package/emulator.install.linux deleted file mode 100755 index ecd3c1e..0000000 --- a/package/emulator.install.linux +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -## User Define for desktop menu -currentPath=`pwd` -desktoppath=~/.local/share/applications - -## Do not modify the followings (Make desktop menu) -TIZEN_SDK_INSTALL_PATH=`echo $INSTALLED_PATH` -if [ -z $TIZEN_SDK_INSTALL_PATH ] -then -# echo "There is no TIZEN_SDK_PATH ENV" >> /tmp/emulator.log - exit 2; -fi - -iconpath=~/.local/share/icons - -## vtm shortcut -vtm_desktopfile=$desktoppath/tizen-sdk-vtm.desktop -vtm_iconfile=vtm.ico -vtm_iconpath=Emulator/skins/icons -vtm_exefile=Emulator/bin/emulator-manager -vtm_exepath=$TIZEN_SDK_INSTALL_PATH/$vtm_exefile -vtm_comment="Emulator manager is a tool which can make a cloned emulator image" -vtm_name="Emulator Manager" -mkdir -p $iconpath - -if test -e $TIZEN_SDK_INSTALL_PATH/$vtm_iconpath/$vtm_iconfile -then - cp -f $TIZEN_SDK_INSTALL_PATH/$vtm_iconpath/$vtm_iconfile $iconpath/$vtm_iconfile -else - echo "$vtm_iconfile does not exist!!" - exit 1 -fi - -${MAKESHORTCUT_PATH} \ - -f "$vtm_desktopfile" \ - -e "$vtm_exepath" \ - -i "$iconpath/$vtm_iconfile" \ - -n "$vtm_name" \ - -c "$vtm_comment" diff --git a/package/emulator.install.windows b/package/emulator.install.windows deleted file mode 100755 index 37693ca..0000000 --- a/package/emulator.install.windows +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO OFF -set vtm_shortcut_name=Emulator Manager -set execute_path=Emulator\bin -set vtm_execute_file=emulator-manager.exe -set icon_path=Emulator\skins\icons -set vtm_icon_file=vtm.ico - -set program_path=%INSTALLED_PATH%\%execute_path% -set desktop_menu_icon_path=%INSTALLED_PATH%\%icon_path% - -echo Program path : %program_path% -echo Desktop menu icon path : %desktop_menu_icon_path% -echo Setting shortcut... -wscript.exe %MAKESHORTCUT_PATH% /shortcut:"%vtm_shortcut_name%" /target:"%program_path%\%vtm_execute_file%" /icon:"%desktop_menu_icon_path%\%vtm_icon_file%" -echo Setting registry -reg add "hklm\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /f /v %program_path%\%vtm_execute_file% /t REG_SZ /d RUNASADMIN -echo COMPLETE diff --git a/package/emulator.remove.linux b/package/emulator.remove.linux deleted file mode 100755 index 95533e7..0000000 --- a/package/emulator.remove.linux +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -desktoppath=~/.local/share/applications -## Register .desktop file -${REMOVE_SHORTCUT} $desktoppath/tizen-sdk-vtm.desktop -### END Register Menu ### - -## Remove icon file ## -rm -f ~/.local/share/icons/vtm.ico -## End remove icon file ## diff --git a/package/emulator.remove.windows b/package/emulator.remove.windows deleted file mode 100755 index 1a75966..0000000 --- a/package/emulator.remove.windows +++ /dev/null @@ -1,9 +0,0 @@ -set vtm_shortcut_name=Emulator Manager -set execute_path=Emulator\bin -set vtm_execute_file=emulator-manager.exe -set program_path=%INSTALLED_PATH%\%execute_path% -ECHO Start menu path=%start_menu_programs_path% -echo delete from registry -reg delete "hklm\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /f /v %program_path%\%vtm_execute_file% -wscript.exe %REMOVE_SHORTCUT% /shortcut:%vtm_shortcut_name% - diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest index 3d15f16..e101806 100644 --- a/package/pkginfo.manifest +++ b/package/pkginfo.manifest @@ -1,17 +1,31 @@ -Package: emulator -Version: 1.2.22 -OS: linux -Build-host-os: linux +Version: 1.3.53 Maintainer: Yeong-Kyoon Lee -Install-dependency: emulator-kernel [ linux ] Source: emulator + +Package: emulator-qemu-x86 +OS: ubuntu-32 +Build-host-os: ubuntu-32 +Build-dependency: emulator-lib [ ubuntu-32 ] +Install-dependency: emulator-kernel-x86 [ ubuntu-32 ], vgabios [ ubuntu-32 ] Description: Tizen Emulator -Package: emulator -Version: 1.2.22 -OS: windows -Build-host-os: windows -Maintainer: Yeong-Kyoon Lee -Install-dependency: emulator-kernel [ windows ],emulator-dll [ windows ] -Source: emulator +Package: emulator-qemu-x86 +OS: ubuntu-64 +Build-host-os: ubuntu-64 +Build-dependency: emulator-lib [ ubuntu-64 ] +Install-dependency: emulator-kernel-x86 [ ubuntu-64 ], vgabios [ ubuntu-64 ] +Description: Tizen Emulator + +Package: emulator-qemu-x86 +OS: windows-32, windows-64 +Build-host-os: windows-32 +Build-dependency: SDL-1.2.14 [ windows-32 ], apache-ant-1.8.3-bin [ windows-32 ], gtk-bundle_2.16.6 [ windows-32 ], directx-dev [ windows-32 ], libcurl-4 [ windows-32 ], emulator-lib [ windows-32 ] +Install-dependency: emulator-kernel-x86 [ windows-32 ], vgabios [ windows-32 ] +Description: Tizen Emulator + +Package: emulator-qemu-x86 +OS: macos-64 +Build-host-os: macos-64 +Build-dependency: emulator-lib [ macos-64 ] +Install-dependency: emulator-kernel-x86 [ macos-64 ], vgabios [ macos-64 ] Description: Tizen Emulator diff --git a/path.c b/path.c index 0d2bf14..ef3f277 100644 --- a/path.c +++ b/path.c @@ -38,7 +38,8 @@ static int strneq(const char *s1, unsigned int n, const char *s2) return s2[i] == 0; } -static struct pathelem *add_entry(struct pathelem *root, const char *name); +static struct pathelem *add_entry(struct pathelem *root, const char *name, + unsigned char type); static struct pathelem *new_entry(const char *root, struct pathelem *parent, @@ -56,6 +57,15 @@ static struct pathelem *new_entry(const char *root, #define streq(a,b) (strcmp((a), (b)) == 0) +/* Not all systems provide this feature */ +#if defined(DT_DIR) && defined(DT_UNKNOWN) +# define dirent_type(dirent) ((dirent)->d_type) +# define is_dir_maybe(type) ((type) == DT_DIR || (type) == DT_UNKNOWN) +#else +# define dirent_type(dirent) (1) +# define is_dir_maybe(type) (type) +#endif + static struct pathelem *add_dir_maybe(struct pathelem *path) { DIR *dir; @@ -65,7 +75,7 @@ static struct pathelem *add_dir_maybe(struct pathelem *path) while ((dirent = readdir(dir)) != NULL) { if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){ - path = add_entry(path, dirent->d_name); + path = add_entry(path, dirent->d_name, dirent_type(dirent)); } } closedir(dir); @@ -73,16 +83,22 @@ static struct pathelem *add_dir_maybe(struct pathelem *path) return path; } -static struct pathelem *add_entry(struct pathelem *root, const char *name) +static struct pathelem *add_entry(struct pathelem *root, const char *name, + unsigned char type) { + struct pathelem **e; + root->num_entries++; root = realloc(root, sizeof(*root) + sizeof(root->entries[0])*root->num_entries); + e = &root->entries[root->num_entries-1]; + + *e = new_entry(root->pathname, root, name); + if (is_dir_maybe(type)) { + *e = add_dir_maybe(*e); + } - root->entries[root->num_entries-1] = new_entry(root->pathname, root, name); - root->entries[root->num_entries-1] - = add_dir_maybe(root->entries[root->num_entries-1]); return root; } diff --git a/pc-bios/README b/pc-bios/README index 3fc0944..1cebbbc 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -10,20 +10,34 @@ - OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable firmware implementation. The goal is to implement a 100% IEEE 1275-1994 (referred to as Open Firmware) compliant firmware. - The included image for PowerPC (for 32 and 64 bit PPC CPUs), Sparc32 - and Sparc64 are built from OpenBIOS SVN revision 1018. + The included images for PowerPC (for 32 and 64 bit PPC CPUs), + Sparc32 and Sparc64 are built from OpenBIOS SVN revision + 1047. -- The PXE roms come from Rom-o-Matic gPXE 0.9.9 with BANNER_TIMEOUT=0 +- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware + implementation for certain IBM POWER hardware. The sources are at + https://github.com/dgibson/SLOF, and the image currently in qemu is + built from git tag qemu-slof-20111013. - e1000 8086:100E - eepro100 8086:1209 (also used for 8086:1229 and 8086:2449) - ns8390 1050:0940 - pcnet32 1022:2000 - rtl8139 10ec:8139 - virtio 1af4:1000 +- sgabios (the Serial Graphics Adapter option ROM) provides a means for + legacy x86 software to communicate with an attached serial console as + if a video card were attached. The master sources reside in a subversion + repository at http://sgabios.googlecode.com/svn/trunk. A git mirror is + available at git://git.qemu.org/sgabios.git. - http://rom-o-matic.net/ +- The PXE roms come from the iPXE project. Built with BANNER_TIME 0. + Sources available at http://ipxe.org. Vendor:Device ID -> ROM mapping: + + 8086:100e -> pxe-e1000.rom + 8086:1209 -> pxe-eepro100.rom + 1050:0940 -> pxe-ne2k_pci.rom + 1022:2000 -> pxe-pcnet.rom + 10ec:8139 -> pxe-rtl8139.rom + 1af4:1000 -> pxe-virtio.rom - The S390 zipl loader is an addition to the official IBM s390-tools package. That fork is maintained in its own git repository at: git://repo.or.cz/s390-tools.git + +- The sources for the Alpha palcode image is available from: + git://repo.or.cz/qemu-palcode.git diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin index e191908bbb06d6ab8fc6a3f16a63c57ce4eb1d6b..bd9ad0e78255baf80fdb0c0ad67853db0a9e7c06 100644 GIT binary patch delta 65777 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 z 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 delta 53931 zcmb4s349b)ws-ZCq?0sM0}TX-5VXJqA`nDPBuGO-hyvOW0uc~l2HR$F2BjNtM5;5D zXl{xgooSSrH_oV|zHuBJ8O3ZOq)Etv8-fdpOF+bG8b|q{EIyxQM@#y@Z3pn*V%+xJ^@ceC$IV5i6o(l2^UdyUr>{4pn-gb+ z+qR{q8gA=5(I^PMj!_STARs#Hz(Xeg^hkpsq#dTxb;xHy zg1IWwAqrX!vi3wxqNoWJrP|bd3%kQY&wiTo$4I1j%7KqWf&RUT?ia_1vY_pYL?T5$ zDSaMUJH8KJS-7A;IhD#hHWp7HKZhQAYu`%#RC9p13j8uc4*tTV+|Sc!O@ zQ;)!Lg?6dPP@=<>5mKo03%YllI+arj#UK&0^(zDOP-K{|;mEB|$I>n~ggR zWjRCCf@Bw}v%1t-!_|Tm`UX%IwZNKf6ifC4@NAPiVyE#u(D3v6%jWCBld6?gcA4WoDakmgc492JWh*4!9Y9F2e2ITeqfJJ-wTGj+fVXa97%&sXw&{yF#ln{;X7mY@Z)R#iB zvK9Yl@UIolBmAZEr-Wzo+yeI?8Tm0F6STCBNW{g~5zS0+u^h9DJrb+bJBaw|qIJ(j z-tZO<#mj|YGWLG?P~T;7{Sf!30Mz|`H*tM=iHoQ3WU=BMzqKr|S6(o0Dz@K^Flo?M`a5iKJpULEDNz_+KF4#Y^i5QstDH1=%NM zdzE8xo%_AX`P&RP7zWEGB^am1GPCq{yHyY-Tcu4gN^>Oq3$gOE;5Qa_xDUGJV<%f{ zenhhCbiPYzzp}p1gwVF(j?PV4A7QM8D}AZvKu{tMu(J#NFI)lF7^ z^$uXs@dCxM%l@42r%?Ez;V$Ko?~UHUs?%KFH#32c%{&aw0vemT@Zqe>p1$l7jgA$g zGnojb(PR|ZI&))=<@xa<7l=BV(HHifSb2`M1zRlCr^ezB2#M8%AJ)$H0~@Z>T!8S< zo=%GI(4)+%S?XgUl<#k4G9tM!!Q>@Y&X!`sHz^$vk2!0R* zt9O7p%a&0K8I;UUvbM;F8MWd5N}XLDPDch0hn(5a2nX|6;< z-&$2RKoBmDLLJ_5hAHw(AZ_>I?mBjU--WR7by^1k;eTe-Ufhe>U-0yw=l(k}?30MD z0?sicO1*7y7l^q}&Q}Gc#Q-K6Qrj!CQ81wI`rHoes~au;NlyWCL7i#yU!OZ+extwz zZWkw2tw0(9C<+EMXBT7)oSb!?y?%0+%xF805y>G$2S&~wkT#kCeU*KPS&t;iC6m{} z4g|G$K*L9+jsywMy>#{vpfB+7?CY2Jp`NepuJUeFNirx-`y0N(bw%LwI%rOQ^HUB0 zWSV9Nmnp|CV@l@LVfyXn?`i`1d4l-j(Jq*C?AwNoH)IdI8_k4gYJ;iLoyz+THbF(w zn(>B7GBgsw{bM%->(1#A^wDXQHnL_%q;Sdxqq%iPt ziyZ!<@6}mWb#AiSUpdyMPEEu1mS@3g88 zYxsG8QN6k@Tiu+*E~)*LV=Y-7-XZSCsJ$iG7;-OB-NLhx$RF++IJOTcj~xc9h5m6m z62bd_pz!144O#N7pg#AhZY;k89X2}Mq-gz6Y528_+6#LfMBaa+hF(F2-sDa4vG`Oy z!4Lh6&6cd?`DSH*#CHigN*v}g-z5yheSj7NAy($tAy4e(1p~_FOC!XJoId@6EpcK+ zLI3yzzDI^``^N;sOykLpZRaK!cHcAx5*fH1IN2kay~j%<;!`<8Lt9ak3X{OSm!OfL zT{PyH5eJndCrMj-Y1_9MhHEpX(-h|rD+_Yjhry$^_$IMpR!;D!m48eN9<{_bK^H*# zGlMOIk(O7PIngl2Ab-X=7?^9!u~DUsId*!fIoaCnfCl|q$_^CQQ+G+6?KKPf{9xxQ zjs<fA5lDU2^7i0`uwV{!6f&s$yF@x`_aly zVzTY0wDX0WRxuNG&6^Ek{PUTZjWKD8l^3>+yUFl7`QCf@ zTp(69u_nx?eTvX%RMWU}>Sdc(thpO-u%_yH>p;#Q)`xG$(Hvr~@bulqxwPyFf{rwlBkQQ9sYZ+T?@VtDM7_BMoR{6U067g(#L|tQ6X6)U{(#yh3BzNl9{c6(FuD1 zShlm>yxM=E+Tg;Js!W-03Ng`EKd&8R*Y3VDLW2*s;3O z+K1l{fiuAMUqYoVey5v+*x^^FNSo6ifevS8?-N(!Z>_Mhq%G38i+&9cRD_ z2||tFGYOp6SR?!7{7cnuFX<~3hn~c9H$B*==U-%pQ3T{*-nQTtL%RGW&q4Wi(}Qw| z@f>Q^EK$`7XE0_Q(S__=kgRfQg8xwqo1uYr=X{~Yu^ER|*~}jONbS!G-&MU@urpRU zVN&O4%F(H8PK#>(p=ucj(Eh_Nyu?=z96EU+n1U(lK*m9(*E0_tknjC$rh5W0+z zdSgvL6bUpfO_ldic(OXOJ5-fjD=|)Gjug@hxYw&~`*uoAKaPw<;P8 ztQoChMc>JDG&JDp&w{+(u;JA0%B6_+Qh2pGS!p!0$>nz%%I3VI&iN?qQdaQMWH$*Q zy#bjs^6}$nVXPTw3}><6`88r?VXJ8X8_-}B)B*lG3@lNsnDdTOYt9Nj6x%S}AVf^+ zj4vXBYD#NU3lC2=t~WAcWX5rI&he}{^BulP9fwPD@5@#zEjz+*&I> zwf9iVp=0qn&f{er=^VvjW5z*tz<=NO7|Z6pmZ-S5K@uKf?`70>;d}U1_}(P-?S=4M zsV|=cbc}<9bcAfIg7g(wkXYdS8Wl2E37K4&KrJ$CSl=coLGYTw@m*+}$#W)Nol~sH zl@g(D#EX@XR9S~TeNnUr)dLV>t-LwHA9ya@KVp_ZqFDe#EPVtFi#|Y0CEI}{Yw;1pl1= zHT}Db1Opkr7-o1WFb7W-Sow=#!yf3)n>5WoXGqPE?z{zoXMf?6PeD0DU9m3MZVtge zE1@QVa`Ynr4)mlYIN*qT#Oj~bx2A7*`VKwa+>p~Zz99#*!guUwjjcQR_dMA%aDn@m zSD_+~P_e+hlu%(ITrAWUw*0(J z)lghdRYYYoJ0w=N`Rz{;5X$9Pufz?{|1ilj4rUv~t$Y3Uk0&6bo(CVk;$z?@S%^On zomGEiO|9^XxB#iv@HOY$ZV!T;eL{9?e;B1u=BYu_T9l4hZyIZ-*%?B(Yj);-063e# zG8MIc`##<(EOb31wT!YB(6Si{g^X}~kVAmx;VnR#Rq2fN+Fx(y5mf@L{MNVV8BU?8 z76u8KM@N)zzE{HLo{~^VTe&Mk7u=``7C6apD)jn~t*TiXd6?B*Jfc9=5lb4;@CCCZ z8$36u1Cyb9_~#FZjNEJZ{A~&pLyrS1KK3|rEm-J&m~gW5D=@+lrQRCaqL;OJGF_PA z`@4cCEuI_Hff5Rq9`sz-T@yu6O?x`mPjd@GZ7iyK1yzNwR|lr(P0D(k6r!Awi|dn+ zQ?MXs{~OS#Big7fJPc0J!Twnh(;Q)Bkj=rI$J({aAb7()0{W)3#AP%q?PhUn5E(~6 zg&RgQ5k%i85}JuXdDl2+)V8vws0t>-5X(3MI%1z=?jHd51ag%lksJ`z<}lg5V&&oL zHq06jafh`nXs`Nv$RsZJ5b+2_tVMDSO&*9?MG+p#!6nz>#i1g^K+0DOLWwWqV2BKJ zJ?KMF4&92dt_RvdNJP<((WFl_f`1z%pN(|@w#YX$rx!P1Tm%LuVCYNw_)@Gq1hvK- zJZ6E_&ps^X%IWT?VtS5yTrgobF?@ECQ>7N_Q)Ho7QRieQ#fk>m>0VEGKJo{ zs%5t!oPnu}oPEU~fZu#@*F>udD$OPyVoh-7w1SH5#m(82g*S2K6giIT$?=@*3Z6D8 z-;VHmQad>OR_hC#B==HW@i87r5ONw1erI9X5^Lu^z9>;$IaN}NMWc#Z z?MBd$I)yV)BX8q7-UN@~fLzs%Y~~HA*Kl5`+Qz0q-OcgpLp0u)&*_QOizZq+n4Z;GY>m&eyM;L6{Qd*E`8= z1oT_sg*SVLAU>Ic1nrZXjCfmt{D_(^6~C8)YV|fX6h>ZaP_q#suxQwvPZ6E2*2zmG zi+2!mB)vdgdyBv)g_c)km5Q4sRP}bd48hqYr7T@_k<{|%08m~Nbtjd&bFvloA;^wI zS)X)0hKCm}aKAxBJnVDS?vZTxPj(-mn0Uk#ASk&{Q?TPR^dnc2`f#Gol_oJ6Ixd`& zN=v6wFJ)a^59f~oF1Mps2>uNT)I(AO5Z`R%<{n~fFz+Bhn#`O7vZdk=I0LjJdN+4z zp5t!2W+NDdaDnSTH zTnHFjK&?Rqmd?{$4q(W_^To+4r` zM9yHm@YR_i*Xopjaq>?i)=Sc!{hHb+ZQdB0g*occzkxPvoMqO)n1gp!+e{f6yCso5 zvg#aotM@S05#J}UWQa1GK8dwqBy{m%oecDNMq%76 zPWMDAFarg6E|bumM4AV#8%SGdp97rkSEyYdwQEATVFY@AO1f8cx<8<_`;fNi z?q1M$qL1R4ZsgC@2Pft$!hLB3auL#5^p~MIr9QbAZJ8UeRx03O!kDxLzWVhr)5}xD zz>mL9)7htNU+^>> z@ln&eFTDQb!_vO^c-yD97_#NH2lchogx-esPps?8j{$g_wl~`#XhD2;nb`W&XI5=k zPBVH$m$KIq1UUJa0RIE5S&spFej{($99l{{cnwc#;9d5y)ezU1K zQ*!>w=^cRCTNEolh-xs}UeZ`9a*U`lCK4xLjs$fW>ew~pvVvOzOKDBqiwdQyBHXyJ zfPLC!@=ZilZT8vkmH}?(`XM60}{I4BYT< z3T~CMhYu3bO^8}>PXf1~g>1D98HDnF{<{tAkM!BOS1dgM)vbK4!GE_=j}t4-!M&O- zmh3`;ucKZpc@E8P=RqUFU8WO2!%%DAy&*a`tLS%RdY8M9nFk4 z356~G^YA>qeX(N5G(DPqrW_Tq`XD|r8^wcR7@#@yaWvNdj0Ia3$VK|8x`P8fsBAzU z!zbFGmZMy9cp=l3lheRQ@;^eO(EIMAR0Se7 z!3fT1ZUkbeVY$wXEdj(vXI4TV<$1PSvXPaok*tl7+LX_~L~^2EU_``_1xGS0cO_=r zjK=>svY@O~ zUMQ3ehTssN247V_)ngR0?CuNKSM(%Zb<}@sk3Fi!^q0+*p;K~H3N%Q<+9C__~B8&Y!1B& zS%q0__R8qcG?rL0$>D(2Oi-%$gb&gsv1G;Ol`C1S$o}#{in3RW zuMM+Tp;bG@J=7IvucF|(Wq~EWQL&q#Zl&M)hU&8!47UWHDXx*xcoGeU37+xbl|+_q zBr^1;XHj5{(X3`m{`A}QfCU+okkO_Gt;lH`i}JxpBHLuNsp(SM59~~^Gm&|WcG@tK z_C7lsyp+gh8`ayD!aB63pNH*K|kR!PmimfQDkJ&>nmCrFyOU1BZy6;xO+kpaN+TQ6I z&Duo}7VS)6^5=ZDy0mt4Up;^65wY|-bP52#yy)@Eyex~QwES889+^k_>Wu~!y_y?N z`%lARNkP7H2lIvp*#6VXiB7*WqI6slAICC|kkufTRNxI2U2q6fA`yA2L452b#BlA6 zX|Tp%MZivh;$M7g;VWWk84|_H=}CUGu{hJ2bNf8+!((6C6wpJ{O^b4n46&3CWg5diA;k$T&7MS_+cQ0!NNclA5$lKh< zf39m3($2BZpv`Rn@3J}>eSs5+w1H|qf>-nrgvSF5OCO@*FHkXtrjWYIcc=7VbCwGd0E5`A=Lqc37!v^+}lP`Y7f?z81$g^r8?R-nh3U07ueJCnKCp`+LSYczI z2ER)nL1SpdlQ=gCioDg60C22&6~#vdh&J@sw(=l-8TONB%p$CZce>922zc|n7ZUE-cvQ9HRNxkGliYQi2IX2htcs`<9bvt)}m7W;2lz6}fa z;emw7#++2t5D8l_-`Rl!S|qe9^-{N;QhaJVklUpuj@4HN$k~jQm|fB`C`oY~oscr9|1e(h_~2CGEV?_gRvM9r2T*@qn``UnZ0l>Is>8 zLh3>!@QS8z76Gn?V&YyRcn08=DR``WHxIri30}MV1$5lKgm{_knowN~mYy*hlN!uM zqPO#n#s$-7OytV0zeKtft@hG(OJr#QVuZV>1hfnn+bZ3L2nq&i^&0CQU=Av?MJ)Y?Iq-KiOWqjA-lD2# zd%;cz%Z5es*+B^WU)5!2>` zJuq#A&=y*Vsuxo!f>4y?wvasG~-#aCWtUtbu$q zp=``OKX5!e`5eAiq5-ZqZyi9OvM0Cbkybr&u;n_6d=imLZ8E$w z*3-2Mu=t(Pj$rHz-8d=lg%WJz6-$3@1pZ5##nSr$QprKF^j^G`x2W$1vGish z*ogoZq|QsgL z7;K3(9FUP>h0S`SSdj+d3r%j)c)YWr|2?$>3g9rbo z2H(^hM7Pmk6L0YFRSja#bXSAWW_jJ@S^Z-3F7{+$-wFUs-1FYl`To`OOiLdG5XtX{v?bRogMc6C~ zB6i}x2wl1^Y*F?ZL*GFe)^}oePb1nxZ^N=WhXlTep7mA=hDIzMSp){(Va|GkM6XzS z2SUM4Gwk1N2tu|CPXEC7e@K&G1~`7T48sN_yi0*M99UREzBT^091xYr+CtI)15ygg&?Zzx(tW$sPBt~_ z0v({PAN9I0MW8Nf3`3I*hX^Vo9T;Zj7O4s!tI>rCsPq|%Jb{ld@IkyC{4NH-)>8C$ z_}EF&VB+An@o4KXLMtKAI7B7VN0c~U%60^gC7`(j2x4|zix<5;(f3CFE|FfOH~!Qu zyw%`Q6JW6d#85}z=B<Q{Nr&1;MF@3hnh*hfPu=p{68ap3OtzBd zhexpe$}!nQC7Ocm7TTMvXQrSne3yhmNeqWKR-5NK{aYkb!w_XhlbvW1JF3wpWS0&5 z)Z?%RMZMEPswhCVP9=~%@LO~PIX4`5@2MmUhXwwd!0D%k%M{StO8L)bXgApE?q)!~ zgTYQz0xnSK8gz8U>d$^WJQf(GXn*z-Iuv>zE*>xtk|4JQ@rm1M0z#Q82a1nHJh3d3 zOSUXS!79=y(wZjcS-mEuAsMa<3yN7{#ZosI0^SZg3y}C?|0K~B*(p&W?A0(6b0@r?{=ULO8N6!K(7m$U>TU)4S zS*vG3yv}o|s6@|2bgyOTxo8g)-&TTLM4-rJMilCTJi&3SL}bI(n1xAVNgjxWJ~4aI z%O;jA0u$5RDTIo^Ug}QHI>8f04D1Rp%O)^lG6vg@97Lxn^k&aUHZ%~THEwW@1?XF* zrvDQ&A(=lGb>|xd9-AbszA{l>dEvJx;@^3T4=?PIN5y33K+Q6u?g>;LyCqRJmvshD z#2C&XL%urcEW22qES155M@F^N4Mjj(ww> z0DuSX&Wk7#ZGMsYs`eAQ+FxYuYB=U64M*FR7sa5KXrr+|+bA|-#ZjXZ{FAN#Z-mlZ zzvoTjtqD3Jy1_`g3W{zlBt?NJ`f2a4jL7F`Dx%)&KotFK&x?#$n&3eEwC6=;HC^&2 zj|;T?Y2YYFSy2o-KNdJIzRXc)30@w7VJPb9WKnD&<1YgPVjM^xyt~E(2Nw!TC{Gon(i?TApw2RULdv?)REkMw zEy#FkDYTA+$!w56+zcr7Q}X9|8j1XufZjcTHuw-; z>u2}?#2>t31o2Oxij;3ms3aGzI`F|)J$#_ETW?;_WBwO@kbjmT{{Q#^9r{mRFkzA+ z0npQa4?mc?_`%HNt2wc&VRJVrE{geCeuzP%|4+Q|Qz(AI4>G9rKN;fxl^+O*|KJ6a zx?S&i^0=QcKv%zu%-#Hv1VUQh#UMSsE{Y)rkz@EAv^Q3%jg7L$OWo{2n#zB&2N@_o zWsen{JwU@CQk^&M?dFZ`T=n>Q_Gpzc6Z|ji@ubckE28YNg@Rzn(0byHEnII39yNkP zKq251kK_OlHsm5c;~WEOc88`>OYm!{*^h&-X#pom-Cml*d1O21w$&FWuKbvD$JRkU z6c2XL-X9Cw8|*ORBbn9doG~GIEXMFTVsh2&5B-zI2Oj_H7=tD7`d`NxtbwC{y?z8F zN}2sJ6fc|qm;r6(s%tKpF&z@S`aJ^!*FQTJ`3s&MiTvJYM~$QW^B*(n1x$oqzr9NY zPw;PgN>C?V>MEW-DA4rm7>mV!j{)6E4s<-5GBCOLTbize-6Q zn|4ZDDF}@tM7wLF(k0vnA2f1dGYYvQCDL;UC?&jX3f@$R-bAMp@FoJCAmfANx&!YL zdSg_xvv%>a;+AnZ1%--UL;^VZFkWDfjnI@nqE9IF80`b}IbT`}5+^k(3z{cl9+d&= zM&P^%mIOf${1ll=q*{CeO&g(A6FjQCN%CL{D}rG`a7A-Hqv!G<7eNU;uLYiqU~dqt z(M-GaOly&eAaB$=j4vU?ohvG-rYcuc0rAU-*K)psRlx0TRUu2ev{v>E>urd4ncq`B zLw1k7idJBp?lLk|FKv%R?kNhd{lB>pxfjt0yLc-%u6^&rF5W8L0hDMDU~du`zT{^l z!}s4*-#<{_y2BB*8C=0@U3l+S!*e&@fvyP5+preXW0F zYM8ubR( z5mZJ%wG@YAm*L%W3xKy3^f<|h`Z7-Qt!VyTT;unbNIrlFnx~^FnV~rdfRZPv{rGm2 zaT^j`cZj8D&|Vk^Wjjosesm(eBSkDFk04$1APX56LO}$u*CLC3xw{H&pe-(&!yDMS zj9P46*^q#p7pnOwD;!mkwKl(bxYPX^L0kCGNF-0GhZ`!!g0!rLP49)?KxJy)k1l0% zyU`ni?BSuX?%KoVGK*t6d~aq?Y_@)==%l+JV86D`44lEAergE2t%KaRm z#!2d`zD(0M&WM$#{pqO$Nsta-05QlwOY;2gfY1zBOvUwN3U@D1D5p}QK7L=9D}U25 zkR^)3Y)y9WLT2~zDPq6qUZlVMgAYLHLPFr)6*n5Cy1>>Iqm3u)1G`qF8f)tVI1t?5 zUr&_kiBq#BLt}X0Zc|1e?Y`@$&gaoyafceX~CnJSOTnEDbsR zg@&8~X8$aEjh$$&RvTO&c;dc+69hd6cIOYozWzZqgY?u8y!)sR(SsuXS%Yf^>(K}6 z0w3LXtMTPvz~)LduBi*$>KbdDS{JzAHO4rgE)Z~~8MVEE-LC76d-evtb6q>^&sZVT z>q&}bXZ3RhK!BkAc5gtsf28r=y@8qc=NiY>2K@J@8e4;b%KOuY1@-kJG#+C>AsC(l z_e5!ExAXoqE`6_LJ21Sti&4f1?r`Y-6@GkvDR3- zQ?%N^Zg*1F`?Va%xW*ikdO$#NjjzQ8-}!Np}j4e$0v<{opC9_5`w5l@9!27cV*rE34;t+pk31 z4xCvv#QK_^T7b<|9|Z=ic21mx))Qk02G3?ctQJ3 z12~^ry~g_HTfCL!yq-R5mRh>%39MV=7(rbNYWB2-p4w2iR7J$5ou~;MT(i~atO>Xu zm|(Q-3jEgt4&xWqfiE5yVhmOXE@#fyU}mYyz3HH&DU`GiTlmeOH)+)%ciWWcvY58wStK3S4*nT0O?wBg(DSI0H9}Td zRI7CU#UYKRdkf~=3xXTbkP~Zc$cZBm;L|M#eEqA`erOK2TMS~WlMrj8*ulTflnV>o zeKXMVj=ypaMh`675LB*27r}dj7rGtWG-=OWL%GA8ZS;7vP3my5gtQ60kIB?WzVJ5! zIcq40epuZ%khn;plh3QWm+o+Mx!NSS(1TCUztrd;DCOr zG3ZIWE%o*kmT#rS+i5A`d#e#C)a2u#S2~L-r6BLZvs7trHoCB_R~NFYO@Yp7!{sD( z2uo6$jLg6eK!|pqV*CzWM57JoUn;-Dh!w4}*;0&4ori&d#t$TB9HDz!-bEguGF|d4 z?1e|Z7X2zVdG_G3oPcP<4$yF64-iFGCZEvT`ML*_g}|gUNi9rL6PP8uvRCJLy$h(` zXy=BwQ=m+^t>~PNu}7Zav=Gkh)krq$-3DJ$XmpTSjI-%Ua~*g`+afF&8NX$z=eR;P zHn&aqPh41mkDFZTL%;`!m>!v8#XRf-i3|8<43$A+V##T=0py@O>?ylgLi;j-J)6>z zu$dOvZM4cq%tQx9lFR2yx0J!bAy&}Z;Zd9$&y{YD55jDtyjFs@91dM1jR&_BbLL2K9+bWMOPFbCexyFs?Zzt7gTGv|-R zKrBua2{U2QV84@XGR`4ydP}b}8K$^R@ZLbTPPC~uHh_Ju>^Cx7)=WFDG`N=zFx#`H zgZs$HVT+PN?Eo4u*ly=1P7WPYtxvK<_sm-?w0kxP)=M8RIw>9pkiyK{I2}>=-mV zAGF`ops@oOHVj#c0}op-sUY)l%fhBtK5n+F$899V)41VgrcZi}T0F&L)Wni_5DNBD zmC!D1+B$IwFjl4F(KBR_8d#F}$&j&vWDJ3g#jHzVtEIq0`4dEI@I+jETYM8UiA1D< zf9Kx_t0^5LsydP|0A|5!Qw7y&Wd&ANWDVU05&=HVy>X1oDbVk34BLTW9l>@(lhQF_ z{kf0@rEmZlSD(DF6`jzuXYf*SChCCp2YdmIy^uSTQhHcI=ECQocbfZe#1kKNiEEIC zRa?3Zc@Jyv2Jq6feRyH8u%}0>!6zV=s4vjDLow)1uOZ3)xgl9SiLIW%3NkS;mf#6& z56z*gA7sH1-}b*<`M~dm=wnF6N^TC;jBNfHDcA!Hrnw8UD7p9q)=uQ&_kE}ims2%P z26uXmxVda&OQYjBAQRYHjX6(EQ)*Md3>Ku@HXSCWQm5Nx)nUiz<8B^|zS7b{><3O_ zN#UD`n|hCal*7#3<8SUBe{&CmK_Db4_1WDjJndZ5Il@V!!)N7&_kmE_CpM@Wo(s%& zJc(};+s>2p0_jwMt13@ZEa@Zh{I<2y)7~`q2^y~z-Nz8#e2S0Nb${Svm5dji7q*6P zyrUs^Ah_qC_X4}erY?|Jp;UfnYS|ndN4X%>0o^@y;TWbx?2>)~5-BjaL?@YTOoG*FW9#hf^Qv)|`wH692u#7O&WBFHg6@NY z$|FgF_lKVOJe}3)2tw0B6<65izDEcmD6^wr^61GF-943%Xx6h|NAV4MB|Wiy-V3n1 zuI-!O#RJ+%uxz0EuKN;_*}5bE2o)ue>YO5HJD{o2p%)NQs%j#3H$Bh!9B58g3vde* z9Y)i3KY>Uzuf2&6Z1MXSz1p?E)9bMI99~x+KyjdBh7iq+P^3o zyU8%AQC<*4vYSkH_siYDzXuWs*yfHm*aD8ZDgAExFYHv#05bTcc(~&y@Zj8Jr2TGg zdP)@);&+%0L?L46Pf=Inv=lr^84P?r*KZv6r@+d2qvd?+JDqj}A7`s3?Q1Bkr5C&@ zbc2r5TzpI*3FyRyP-Y z*mOM_m!uIxT<};*aSInXsh_(NW!!7Jl&A3BYJoj4rC^xI?_YwH#eHQ~+*lO2zhHO@ zoEFi%yw~|p>b*7rmD=wR2)tA<%U}a4>|%i1~F z)g%RB^4M-~Fk7&%$a@hkM(EBY1k)iTZS#RKB9T(;0EA4L0D^&V*CNpFXo4wi#{A$N zryT2~mTdY#{7X-B#Qjs1@ov*zRPoZZztHQj_B38f{iJRt#U9KkL!*6%FFsmJtX4rBP>`PYQ)ZHrR7H#%fm+CS|{|zmN-0J!9Z(HV&Z7B zOkVmOYP=kX$xV^l`_!T+N>vGi20-ocCzkt*uTQgO4i8DJ-{BvRWr81(lFC%6f4gMPsnt_55#jd z@NI0Stry^$Nog5@gKu9KxaSb~?}7%4--iO_V{N>@`titE9*UkLo{4*&><~VYMu(MN z1an8#)9*!L9toJq>RO^Yvh!J9Hpp(Ove_YcvNDdi)ZD+qIoEFR_JhO9@Hv!>zb0!_ zAtS;A5pDDi>=li3U39kF;%&y+?ga(vT8lsVDF^y*T51oBpEJzZur)Ay&alxA-@7Te z{3twR)MZrUd)I(~e)HNBkWAQOl>pk98t~6alI?1a*>}8?GSE0^i;)3Q$_J5`4W5B~ z1LVtQuQievtrH0-+lFdcdyizrmU(sv7qsHKzV-Hb?)8MY!YybDKHJbxP`)mRoZUlp z0UjUL00%IpGK@&?nd}Rmq{kAA=rdUZ#Reg|E^xNZSmkmjbbC6XjAr0D|DBm zAFG@TP`^z}L;b4x%je#QI|5-g&4|#82)Wp_*c$SGR*{2L`vo*xrQYV7V)-a=`%Bl4 zX6;Kk!(rOO6>Md7>=X7u_q}OV0xsO4tKPP~d8^^(TZ*VhT(UHkqZa*6$T+PpnhsYl zqBCz^%KEi^dMT`4L4(6hak!UE!m&mKVqNM+@XtCME+*yMn#pw0^>%Bc znXoD-jYbzVDqJvu>?mUQ=h5^@_Kuac(lraQuJaFI4Z*^%TsVbzdlxJ}jKVq(_Cv?I z($?9+KFb02>aKBj9Mrm8L(Z>_uPf60Y~b z9Su$VQU#nRuJz&`(ktUJ3I7w|QpCm?V34?KOlXntt-hmJu)3M({4#~dTnHLGiT=WE zQ>FswScu-=5W@s_SkSvOINCX+_TmAh#TwFdD4{B;x2F;ri#8;p^N1;`#B9W2prftAX7J<@baWU5&T#AkBVCeLiP}YI3F$bnN74*ZE%qC#UFa zg-)Awz#!pQWd9AEh2GiL<}ggm9m4s-?VPC<=WAq+ubehi_R|g zMkYlzD#VQBm&lbSx|nh+6~oFHQ@4%GHH=<(A$Y=!l~FsY@t1J&DTAW*EXJyu=(e=B z+%AcwNAOv4&+s}vIge~W z-+09p&A}FjxB`gW^olPWSJq^gD3b-CLwS zCQ~WWay;WU#Jcjm*M$2bWTK0-YkgiZyb725piwLoJ^Uy5J4XXh)M5y);QlKvFT%$m zEsfeq=*X~YK<0m=23Dg1kU8%2qUNj@#R?8v&QP14)Tc zdi0a(IGh*wBl`9GZm~-@?v27}?v8H=B?q-z&~06o)m53{;Md-)-d2%k7-9Vfn6IiG zri4~rz3ph8A<0%__iZ5u*?F|TCE zzqvrs;bSx(7oRF2s|b4i;BA!_ zQ(1WGK=`R@mRQ+{ic+*|9^)dbY#nF~oHp1nF{2DcZ{RpUQ>=_=YFY}5v zF60rXvUhkUa{MF#Kgoojk97RJx9V5!+1h<*6>LGg4iAMb7vs?X_$@Pek@eu z0Kj~Yu=dG0bc0rYt!HSUiM6Yr$Af(i5k>{H0bpQ~)ty(xzW5zLgsLr;oIreoV8Y!5 zLj_o*y2h(pEaYdu0fvtvx5wbRu{~dci@>)rdp^Mj-*GEeZs$Ac%Yxzy`yPtP_g=_o zhPy&tlXJ5xxDU?%?YTs7*t=u*h8jvFg-{L1ev5ZF0sNoOSN~&tnJJ#LxWcJDgOfyibrT^c1wr>2TJHZ5;d}4Fv|zyroRU8g zFQ2WUh5ss==e4iFnjrQh(Y>d<9bN8u8x zxErx6PIRG=Bya=$>H|=St2lC{aWH*{(+8%RykxvH@lLr=A{|1-W=~&LX~KsZco)xb zjGD6%SCr&g*aEA#{Xk;yWFn|ygZ1q>NS#7kqt?rmkboQe-=2xMYTD~8R_@Xx&K`f-YcS%%|NdnuOU0!*LpyfrM6|SL_n*7t*ip!vx%Qq8mrb@yiUP z%cWwQ#}pG351en2kw5Ee@pqr0Lco*CE`!-6YEU`a&hL(#l7g&a=^AQr2Higl-orLE z{VKI|x=Ibgm>uAb4t`o%_tCVGT*PJSuv%>HB6M4;d>FbO|7jTA*v>^GRkv|R^WxWu z;HxO6+hk(DA}^2$Kw07KVSCF-zcw6Td3>EotoQ`&S_8$wf$}`}I;uY(^&_{`bzhaF zLleE|OLwD~DFc3KfNs&^*Lal)Q|Nw$U=C~6dNT#bL*906lVDOMMO@`OGFAc=)-@5Z|R>OV7MoJ17O!+ z;~6OEGFTGIL=IK+b;fjg_V28&D{Li67dJ_0%E6p1Uyih+uCe5Pfx_Fqt z&{bZbpUhzVCo>wc-;T2tU48O7>X`%4&l)mLBLQ>(YoiZ(BUXMzKX~zV@drd3tUXHc z{01=ttPa}gh99)ZMk2^8dRGEz95$J?(@$LROaF*BUWN;w4OIlbibCrhf2l z;bwCn@j4WC6BKTlz~E3JMIV?rBsRpX$H3Rt{N^f}0s-wI0y>N`z`ri6{gAqtMsysZeRe+i%qx_m(b4 ze<*b_`U2^uFX6kYk_RH78}ALKINV}KD@%_^ObaaEJxEUVKiHpCzEoUD2<3I|fKxk6 z{G%_e+4$#LArvE}F%L*o@P60$z!nS>e9yBn%#QCJ$Y(^_?*pf==c2Jaj_EZyX^T3}Q&n384R= zW<`JOSX&!P*VEzO=AI}MjF%tOp??9efrTbb$eXTorr>h<{imyG`Q~MZhm4I}7n?N{ za(x0AdJ-+X7Fh99L4wgUOsxEH9_q8=-|jA=DqrSR+QJ3M4+}PDIO!hK@qsI8a-|%6 zq`-SNi_7c7n&;sN-Rz*l^f<~xPXz3m8MUCXR90Zy5r>cLGnhESgHdw#1Dq4>+MD=* z_wHYM*yiAZ^c=((U3kTpnF0w$Y8_g|>b6>Fgy=?$d1>nY|% z#8ho3OA?kzM8gtHo7oL7*W;+=(G{Xjx456<^yt82}M z27i%+1KnxrY@39O%q+!OdDC*7o)}zd6t=?;iv0HCOvDx7=8Ph1INom^koEqC0~ts7 zF=JrE*lku~xj3c3{V@S%1z_wjcAd&}tJ^nXd>vGcF-z|aC%ey5`srT-@HWsU=00+Y zkdiTa@lP(#i$NuR`U$kYSRGXKA37s9Hhz_bebVF5Vr}FI=Qb8!b3495tY{)f>TSoD zT?pL1eeg)jO=!|hO_GHJ`+l*0E#gRucOpJey#3m#e@B{oYqxbZ4DnGO;CE=S+71VhaU<$DwtcK&X~6dCoRr-dP_n0JLz-6gD|qErNC~Z2ZC(aW z)1KQ9c=Xi~<8MN3qzmX~SIu+aQ&7r%H04ulnTCeSVry35MRQo-omVBpu|V6a0}cHH zvH!Z+a3nD0Un33c0{8xFu)H{0%9}cq@ALUKBN84|^F5kJ(GpN6S2_~Q%(u;)oGoqo zmW45Ji8?qdF)Ks-^xC=w6k~%Lek{n~8LO}U{0dz^z6>i!Hm|lS*S)hFNiA!L@?~qN z1z^H`U_>YB8WYXVYZXhI5D)9Zm|f_>rR=zh@^;`nJPO(VN!d<&bxb`U&4z3I2J&p{ zXlNAFe)r-~2@-p*lWFjcM9B%LAp+5%J&WGm1o(f+TX`kg%Jb9;Zf>gj0cEvK$b&58 zr#AvZS5=!$b6*Jz+A(6_Og$;l{XR8#X*Gmt(c-|I9oHJnfweoXxyw##IOR(Rlr51` z%k%nU{!cDn&<_@-_LIlt(gUM;Hv3t7_pMWO4s3RWxzxdWf%VhD5FLvB% zpx@C+fBkxyR19}g_fq(mD10_QpIjZ~=P6eU5oa+C|KQSZ51e#5AoPMS2LD50Z+bwjs( z3rj=k*yEPhCOBvw_QXTj+q9t|Mtr1)Zb0Se71A~*xIaM6q2HoP z;ukvmksxb=Dy^=wU>D85sm{&V;`T$7M6oZ2`f)gd>+bfEczcENK4S67eKw1ax1vV% z7I@>Qabw+IBFS42)$K^dF(V3>FSM3zm7c^GZnWSBkt~9?vH=h_usBp&@-mWeRq28_ zIAt+&U55>&Mz6Kp5nGm*0Qq1G<2wQ0NG^9ImgOaeVVWii4S5Md75TcgUqa%*+tCbn z9{e>W5*bD@V#Ulp&@oD+cMzhM-@{w~`hb6BH2b%r4BBqf9>khGc;MO{Mr|-ED@W0? znSILguFoj-mpy7`Jxcumkad91*|;(w0Vnw z^|#-20ibDTFX|%oI#h{;qhi$KceeXFGR4Pjh=O!=u^ATL$)9Tht`2H}`p^4HJ&YIN za;wEhPb*uZt?Z5^*}PTSi&UztDE40;OvoCf93$U^=c%0gJA8bS8fp30_1D|-+* zvCGb?G{(#2Gh?zX9xK*nE!pv6>7A4WKY>^=Jthi!*Z9Q$PebG1$p;2n*EzUZKZTE+ z2vwlk03NOJQbTCq6+jiO_&K~~8u=c)r~N11;|M9AAs4TCbF}8aV>zovLM#*)M-Tnt zth-uBJe@CAY?Z!3`iI95f{$#gM5{&kUIO#Tv3(gNd(L~2$VBL;%iQ*x5gY;*yn896 z$ua@=525~04jx!fppCX^^sAzlY^)-e2Bv*-t(-+A_AdwbL7aEOAp5CRwC2C~$k_FG zGH`UOXgz&NOmx%TGQ8pR zrwvPgs{=@R5@-dN6w~G|9!^y@(=Rz>Qhrd^1ibmq9cVNwqN=EjEm0n6?G77AYzI2f zt)XIIDcm3Lop?*MK;tpcSkZ;!Yw%vdcUNhTeX0}6A&5$`f}HSVdE%nS-J7Iqf~_NH zbeUO#pdt!D)7jAjV|EEES27(`I}6kyAz9g*f|5zdN+Jv~>CvpTS)u1l8^M5W+5m&H z*6LZMpUt`uv|&Z2qsTik1?`bfbYwIkpq5A<<0Uq!TX{}#{}i&|JX5D&uepHVshlmX zb;*s`9b>tAYfLX+yA_i|IN#~sL9}{hDJ>j_*Q)=gvM+&(>d5|n)ilszL!%<1BDRV< z5^%>A1aU_qYTOZp>Q-C`bcoPj9b)XCMG8C zG2ONrT;hhp_q+9)#mvli&YyGWS9{&6x^?T`Teqrk-;AOi$EpZ(C{!X%Gg8^cuPNQX zkPd0qJ6^+d5RT8WQ~}G;0W=2G5wtSU*Fumc8t)>X5cGOEqLkcWP(Y$XoS$M?jh;hL ztVM|ka=7N8!)hGY@NrGFTD+hFqP^zgY+^bz#R1+?|IPvj2!u9uA!L3Kud(_ zMScBl0+#044ul#+rx9tY`L0Kp+;c1_=HS4Uq%{ z=6<5~f8yxcZmIwac}L@H>d$}8!zot`ht?52yT1Ma`j7Ts$sYkfZcuhOURsL2==;Fj zvf1j&vh?+nf^rUDLVCf*G_AC*>-Nt+3+?eS3Ks9B{#qR?&WhNsfJMNDZek6X>{x+} zxMP=qKzaB!0j`(_vjK3@u>442@*tYn=9?(%8VBh;kjC zY0RK@ESQVx=<;y;wbK5URpg_`T7O%4+g}blZaARQdHz*U?6qrbkHyn3%j@dxub1`dczSdLH<*FqF{@m9We>E| zBK!HW4k4dV&CxVP=)o9z&>QeCNJc_ZR@j4oc*z2Y+!i)84a@vVEAfE?IWT>IKm{jp z##vc(Xn9l?ojI?HcxWZeKE@Qxb!R)IDl;L0(X z#{>%$`r`@aUl&rZXQZK&y#&ZUQiy;Po{UCAi7_zpOW4}HCQcR=^`pa)?n`()zoM^ zxaTDRrF)gdL`ON+-|36;_9Z37O&9Yd$Nu5P4x7-PTQp@uQJW+GGt^Zn+>oH!8_Dj+xTCQ))eKCo>6ateZhQXa;gf># zxG`9Q{*X#N+ER@bS3H_AnUTd*7`j`JehoC{vF`aIFC`(}IY&aG7%}w8 zDxmE6DwQ-506ZjZXmxxjvOo^VEsuch9JW_oL(pec(agUf(f-MmPMws&skF^f<2`LG z_+y5PmSqw`>Fp)gI@w!X9qEm`DvESP$@VE%L;b|T+j=lGVd%#QyX9&~n=tVV#-;*P z1u-zJ%{+wfxjIFKL$dW(2deZM`+=*W_Sx6M@Tl6RYcKW;j=^rN_LYwSP_KPS(_#o2 zLLI}wcEh1}oSh;Zq4v6Kfi#MNKP7bhM3A-i#&xs;4{hw#b7;HW@>91Y>+|97A)LsD zS3HlpkXeYnz+LX2(o6?Yc799)h2Hfp4(MfbxY`;EpUdr9FFMg)^OK&nvA4QDX%Q(g zlV%!E6WO^wRTQ0bnCMC~F?1)qk!K4|U-!NK{hspc|Ay-uqj>q?Hf8$=*~$)+7Ipgt zXmw@_J*xLm_+LZJEc>17p{hGq?d^U(r)q!9e&=Vd+IGr5+c9BOwRrv$g=4Fho=l_x zb-&iIHv;)TX>}7ql5{plP#0i$GG=_~$;8vPb0r zavYA215@oUWxtTS!JmNxj>B&D7juFwLI-#oQwz@u1mxbPQ(pnnnm6{6JiSlKz&a-m zV4XmUy)~$DUk%!=tczt7CQ0=ED1MX;sy`qMLls(F1S37zm?-B`N)XzJ0k(4({te00 zXQ#gj)k&vOV72Et{3@<*;G(~3&(&xv{n<+$v7X|9j=kOy=t;*7{p}r`gF28xeLq=l z*^a_?>t3R95sk;r37Gv$oTCDg=jWBL84ezU4x3R?q}1E*?5SQwDXu%yJ*zx3@Lc57 z8zHK}kL)XNbg`6O`OU`iMcNnq2D7VLtXKq2wdZ&+eDo*w6?N}DsKVua;{A~;dR^W> zun-6pzO6#nAOD}7BLfEOPfV9b$7<=|<~Dq3&g~`Tur8w7vj7btx24*1i@VX)p4%E- zR3A-nFx!N)^am&5E&VCC9zcg6@c9l#13h08^>wC474ynDMBbPjAXp2@d;^Duggu#3 z5M~DzLJ;ggWr=hJa8W0!E&Xe)Z6kqFME(yjd}&JTlcF_L`x(?OQSH%~ zZKxd=iJEU-9Q9jN3j8cFaK4WfKylD}5kOVT{1N*Gqvfl8au ze*87>+hyRT&Vx}1vpHg;e#wMNDtI%Jc;+0D{4t4fTE)>&1a6ZOt@}`+DDF83)1(`^ zh}=3|c3}Dit*wXvwe1%T`zrw$ACrUXB`dU`k26|O)AFIzthZlwb+U+y$YD|i6$)Ss z1K#7xr^vHPab43-5g!m{+fGGRi@p-j=QOlCo-)KV>k-z0cgR|jL{B(qgQ^-b8xVum zBASbsZsa73C>L2L;X->Y-cWPoPR4d1Hcan2zK767{KT5e$o(g%0hB#Z$62^eBP$3y z83+qX&tY!`Hv=%U@Ld5ih9Jv4xK#*C#n-Ha8R7ImPzJta##k+G?*Tn&w)w=XtsEf2 zpz;ecS}Cabqzr5aT-|Gs4p;QRKGA(kj}i{!5Fd1in~f+ttU#w3NtBotqCHIa9vCA} z>vfem)Mz0hJ0z9}IPr;sFnJQUO0EUYTll3IdrHl6OYInJ_EIX`=6~1LNsy*NYNUiP z;a>f_h}D0OPAvV@*?Tc??zf)BFra1SyQzGDpiu;eEFV#*2oXySxv zg}w(x$_M~NVbLS4Xten*fkZK76v%h42f8cbC=m!nYkhSM@Cv&V4QI#H&Z!>Y!Me2Zi7GgTzQbK1o!>YWbf&{v=R9mn>MW=h}bAMJ1hg7A5{8rh5Zg9nAd+}=9OigZ80CD=m zAGw zs$*4nltqtYH(q*uZlxv~Gm<8rV-=P11k>yDGRg*Bpi57BQGMh%}BHV*yMxx^4uiC_!%MGYszV9PfhK=v^JDN!}O;#18~CVPtgZ9+K;E)C**{*A8ul zbTwY-45CewLx%yfAm`SGv9h4kA5ta6it2VB%3RS59Oxn^V+bdyn`$it@C8ZU4OC;K zA~UFj%pgvJKyV=HK{5ku%*iR4+JT*g&dLk74XIo{JB0YdaE~y^ ziLKrGDi7R3#b87p3nD}?*nj?Yh$Xt>k!nf#$rC3|fD;Jl{Sdb!*WrLl1hakL`vy8e z+ZQ8WQR`70jJ@djUAb+Bx^Rj&(E*pIYPzQsja^f1=C7FCQ@q7=M!U5N6TJqu1z6kN zI~`yt+{|?fg$rpkcfAEHxjDkPACb*w^u`fL;c(Opb<4*;!vVSf5nO4WEnq#We-I#8A&R^A81TH5fId@fLnqe z!2~PbPOxH31Dw!!){}Xox5eydbLE|1t${Mc39?fk;{-LW$7y?;FSR`PalOe`S6ZQn z%ClaEP)AE)SvTr}&M^-QExYPWp-QYK0M_) zk}(q=p~OL*zhr=6iD$Maj;Cl8*;uaG50jKJRCy{mQRiBi97{ZBINq=vTo|i@@yiR) zEL4a$EWe~TEZfIKRnQxjy1d_k4{836<+Uh*DLIuACK%Qdt+Nk+$HX5cE z>=Mj8!5i7esLSS~GMv3L`PeK7Mphrn9LGo+~>U{(_C)*G_@Qt}2z@A{W#E~8^*i@3?V0qIEpS}obf%XMb`*vVS z(GItW=fZRw>6opfJManEauL(HIkrFnLzgfXwWVX)McRD&*nGurfbi%_M=n5u;Ufv~ zSA5f}wVni~<40(A4v-5^L+YYxP2NzQe~GYITva)|6D3}6aaMbtKza06?U@Ijg#N4} z>0k;rISb(Vtkl2)q4I<@{M?(l!n8;-u>!)VyCmh;%H*JWApkTwlLmC|VxOPIlo^ z6M9{%+V(Gxb(%Km+WIX2mu4hRn`wND(jG+G_}of7r4>9}6tVtvp)aXk6n+pr1uoBC z_gH870u~kx$Ndr-x8I3n$iz9kL%)Er!a2Nk059k8PCzBpiA~SD0#~qNfMPa#7#43Q zJjGm1#?RNue$rw5e~SM<;a|po0shzEKW5o7J#2C_(^68i^ov(6&sdgbN(+}Kj$@tV zj^kLQ{K8Z=(JQlG+G1mt{QfZ(B2OC6*2%jjuvM1KG{cgWEA-t{hv_3$caIpl+DBTl zQtu93$@RS!rE-c{tzVRqiDbR?i&IwgH0c+m>6fQuWTd5r`$!p?X?%Iw^8ZsVeQMfb z0Bp%h(~p@kVRBqD_`xY-rz9s$m@`(NvLY3QQA?IAOAFU$Em@nU?+(cR&y_4$L6!V} z>hS+qqM6QU`>IZs_eJHAE6L|1*;MqKWJ$Id&rJ zBCnmy=E_s1ut{kvOlj!WtYJQqUY{^y@?;+=ZBc59e)-B(X{maixpFxgt~ad|%}>ls z%gWNnNA}nAm6`fQD_5HI%hOhv!+m@t@?>Q!OUW{ZFU>GW2`lw8@qQW7nO9(h^p(=3yw{kp`T)0JF>gk zM^d^;8lRGxs*hWel`apP&HkuaWk|uWWW6BsBsNSAo5P04Tj#J4=Chski%LmNP0C0? z7vK->8L;FX_AI)XG?H@cF z>M>~z#n~S{8zHi_dAX^yWF=}~-S~EPo1a9L`8SJ380Gw+F32LHK$98x1A?VTp_056 zk~a^dIQnY{`*owA6aYRto`A>7Lvh1%l`zqwW?|__*N)PmrIcfaj$?91x?Jr)!S=Z^YquMK5-OGNnK@W}A~{rX2lMn>Q#Idbrz zK@kJ{nUac@0IQ+4O)gPckn+E|2bd# zNe}V=@^U{Z4jZSm*UZ|FnUxrey9s7dh+q_@2?^8tP4328=>3D|Npr1nW5y-3mT`N0 z)N^xMlE(u-llA@+|DBvPCVB40NoPu<7_)nq{-j~2JjYMz8&2V%V-a&V_L(^@CRvjl z6E_VkrAi9WBqv42Nq-QI{tb=+!57N}mR@1f4v&2iwu|UuvCn z!c!+1Jar$lmswlof)+I{!TEOqPSAMQ9Ww`ymsvm74o{d@co%uu)S-gK#apcFJ;8dr z7Bz|t=t8=7$t?+thlR(pRlX1z%y^wx<2n`NI_{PV8jerhB(VUu5@m+i23!F{|Uxd&Cp24Jl8)v@aAI~!UtFE+yBnIk6cMmbW)fQun)ll+~PXj-u-W;=8^IkRAA! z=I7j+2TGd8i(XrQ5u6qTf`HKcvnGrDAer?UFsr1h2i;I0KGEte%R&Q7%E6u&!8p#; zOAn@;L{KPcNJWIp6yibyRi*Zn7Zzimh|H^-G`kZ+{098DX^U`q_)f)Ezr<(qB))f+2uQFPI0S(p9{B(*fIEUm-r^6x!`&(+N5~(qHE_%i z#j^otfgkbSr+Js7JnB*QVgm;@XU^l1UzSu*;uUHR?%RXgDjR}q14IlibXC5wnvx0w zFAnfWavX0esj!e^oxc(r@BS`ur=BmlS}8RThPZ^IyY(E0#^&(3d;w49^Z6mQ7Fm)Ov(x zrm+!0e>x>efV;r2ND4>uCk2EX3IqQ2{wcXCjrEYXUT2f#pVHVUWDMo33$x1cob}Lk z6;)$wDbMNvc^zlVRhOU2H#i&4cFH{rNHYer60wbG<{H>?#^f&z>?QU`xr>p7>Ly^$ zH71D;kf$5LyTn0GAOwKPQ~oZ=Q0RpeGet#f1LU`jEKcQkQhL?M(peiEF|Oc5l(|Bc zyYcbz%6b-TK{r%*BOmet_qZU=z%`I(FHZD%9S4EtQ0h=e3gW`)6f_rP`W6TMeYQ$R zR2s=arVsNN7mU7@V0_H2QNjg{a1mGxJ(7Gb^Rr@yjRVEO$Xu;HrT zN%GELSk_pf(g`5urB}4GlLGO$2f|_2ji_qQ1)V zrs{337!gnFfqduzCf*!*>vGnYspb94fgZW?x62u43*=ENSW!fwXh;CJ9fCF-6btC6 z>j4mkQu}ac!Eb_l$&XjCo~fY0zln$--0l5{S3DvF#YJ2g_c!^&I&M3SK|xrt8nX!z z8X_+S9)*MQy1XG6-{Kfdp(eQPCa!Rnng5v{;`^E_nm%I!peqwW4Pn) zn9>*5FqL}9Y|zYxMWGV#p=$Ia^@QUj=+Tq=u4h>D1XVKobK_VT7<0!PFUzJ^*Z|EG z;hX=m{Lw3Hu%>x-)?xRk+ywF?Q{cRQ&>4@_a}a0eWD690lOH z$JNeu2s*`_{*<7$DduXe^BF^Vbt=gBIpzIb{NeIcrsW40kzCCx?Zl$Vafd>5X%pW-^g38VaR)k z>vlV``T$<<=2`xR1zFy_kxf_6AlJo>Y+Rtb=+;dI6CW&($Yt@Z-Er+GjyrZz_>No_ zJ8ClK@dHyZ(P3OG;0SO5U??YBa@!^D*o0)RYkZcQ$x?VAoH)kZ3Fk$AxH5BB9xL?S zffHcd7>BOo4ki!H$Bk$>FOQi=3Ud6S6EXjy#j+nAik57XVB1c!)(aj8BJcpNbSx~e zMMnlKMPhGW%vvo`ug8c#DvClP$OD8cI4)47GJu)xK)F$vs4y5#R=?^aySQu0?T!9z`n}>HMv(0!@ZTRuFoeLfkZzyPh_~aoDz4qiF7!g!X5GG zd0Ml)487C+UGw-9Li%c6$qlg?OwXl@DBR@5%N`4?Ivgr*+r-*~b&&tMi6xG3Q#mJp#%H+sUYt}02SsdL zBD%S7d@n*^5A^ZxsKe1oE^c#hNB?K?@P}-as!P4R?jb9}0tEggsI<*y7S33xJf?tk z4|o+ruPn*t-pE+R9c`b<>k8O()l0SVnF7{E9#qKsdr>t>z2xPEEWCB~Y+Q2ULtWJR zHqc`f0R3Ab8`SX>;73bz1tXXNR~2cX$uE|WARGx=?PhJ|)&cgZ0FYU&ShnppSm?9gBSx65OBpTO_#%=}1S99Cf+;+;1_di`> z%X_5=j31Q(FldShTRhiFK26Mh5Wck{J|sn6dzFO;yiXWw{AaT|e^@AgewFoR zb+@R)G4qDH{IM84lTQ@04n4Ok7`7VwXt1l3uoW-L9#4c+NIha6Cd#c!SZDqs?{{C! z3NWxeT(Nwl6T4)leik1-l1!A$tzCh9qyt(fQ%^qf9(_9t0i)7TrTUAZ3im0x{NR+x zsm6~gmE@~RqVwP}gbAW^|5*8A32SSqma_eEgePwRGZeZdFe5K@W){YZM+*##@hQ7lK7p27DXe356lIH&Gh z!2Tm~Pbsf_wZ>32AhwgI^GDW@A2S8-tu)I|{QwjF5nkZru?hi6tqys`R@R-_m5Frst2X@6m zrp4mY8`T*KwKzNnX~~L=1t<(3ZW|@v+{W6sBusK+lf32<8_|x|gmQB~G;VUJH{W*) zsKOl=#>giwF^ei@f;{Ci+XYebm&>fXYDbJ5c!d@9d~V)cOT~D00m18H0)O?MmVl8FV2;1~ILBi@0|{ z?J((Q%R}B^Lx@~uyus1}{zxNY{HEC?zdlQLzQIEMUJ|+X%|bjnTkiNK8^$#9%r{x* zU~igY6;7x*z_WqpFZ3b0-533z=p}D|6X@wFzyBud#{5c;zsV|@cDN`jY9`7`mVftq zki;N)-|tx$0^`Tuv*ds~glNVent@@NAt%1Y2DZvcQcun@w^;`kBY*fd3u0sBBX6^XY@FhY zFCG03Yo*d=iXyXLM3J-Qc{?Fz0opfrvN?0HXg%Z=zo<*9X<0`5LktD;LOratV1%u; z9_9d7cR{F<8!7W4HKvRW*ETnz?tEv>Lw8Uk^Y6S_OY(Jxu3BO;jqeEnW+%dpEnm`I zIo`QYUmwnQo%lv>_h)vlL9&20ZsA{8m}Qhlb}CScXjyh|K%>jkvTR)*#Ga3&y5qR1 z#MfCa0YF{eQ+#ms@GW0wYX)4@<^8J4Ze^{7TonpG&QpKw>->|-S_|{-3Vd4OwJ>~q zb@}^!oe#9u+BlrxRcH6L*2d`ae(<2IZFPD4B+>-x^55`vZbfH|(dBult+lbb{LQ{j z69Nf^8 z&d7huFaMS4V@*WvW_E&cMSi?5(m_3G$Tfu4IY;^`yqL?2i(8EUS3%p)%3uAJ1-5T0 z`lqK5Ac%lr%?v>o*Zq}sYug_A)x-m?R^ulcQYYY&BR^yvHJWdTYe2&3AF{aK+c0Ks zIBYMeU6Izu7qbHz>0+Uu8L`F5b*><};zQQf!}%SPFMP;`_MwJU#Rr4SU1SgpR&P5L&4Mlr=caPB8qQa9U!fSRub~8)7yi-cR(*q zlC!0UfK*BLTo2}b;|9}e36PxITfjGuN?HeBZj(>G@pq<|Tl}4M)g1C6E&>f5@OL)I ze<1Zn0`GUJ5W&jqBv$jD@(=2;!Q+l8R4QkAgrGmXPR9 z%#b@ilsWZ22=zi}4D}oiU1AaMY4Eu{04bT0FMB|b1^NH;dPcVWqe80 z6K7(ae`4-@g-HR{Cl_^_{78(Z{w-V(Y^}xWzgf!kp?Q(NxP{Y$H4e@$zlM==Z)7{E^d7OU-84f zLJUDt0%eP?bgBk=B4&V05|I0-efBVe)gtfN&$`Rc_A#Bs`8w%0wLpZz7DW2n!52(u zF*n2jYbIbVL>72g1mkCe-hj=6*2Lv6fEde*5+GO=#dn~>Aqk0bFTs%ON;5V5U;^KR#1PBkb|6E%FlNr{@RvbY21KqK^JJ#s8jRG08YNx?!YZ^MD;%{S8I*A^5x`}jcmgp< z;sy0zHL%)qmLhm2S%fc zEE;yg7haS_I1~%H4}A-)I6!hAzOM@z8@&s(DSXF^ghAVneE&jJ0K~B1`dD)qauZ=L zOl%)<9`6(c^Zj&Pk@X2PwSp5VaXULy==(L;n#M%5jf!VN*5f!vO8&s{ig?F(`?KI< zYIyDq+Q2D*%?8NQaX2Qy0o6QQlPQSk*Axn}h*_5aCqkxDNbYg}9=4D~aw5(aI1R2( zS|N5i1?{7D^T_j{Cn|0`!kJ4*b~6xacJYVjDc6@!%*_B@MAygYHq|zez!H#gU1<`q z|HlK^>NnWtgaH2pMNlv!QS*;b5Q{l_gW{j1AqWfwNnM%+06A>wU8%p{(NJIJ*4FFt zc1rFP*it$OCIe*d5i-Wps{1@nV&}Xek`xmr%X1hzp(z&V<<1HYNx^88IJ2jlsANN3 z`#rkao8vAeP{VrO;z@;z6qB9Bc1Vlw2|s5>&~L&(=VoQjVRnc)fR-Il>aq~IjU_l~ zl~B59E@G1eBqEaFd_FR!DU!fcB0&lW%(<8t1xWzYi+nIZ#KtE9u~vXGaUjw+Cyka* zVvzpDUX8T!AJgHV-Mi6Gv3(kS%7DDsw=saC!=Cf?d(IdBobLsd)dGy~{Zyn{Uiti*Daygi{FXTQ**3z{e zsfe~%*D9;dgpZl7rE6qUURsMRO0CF^d6N(dxx9%_ggll6@H6m^xo-16Nn?AK&_4jL znFE*USo*s#-MvA!hjcjxR@P2|*;u!92gY~e;<0u9^;Mp8bu?QjnKKkNt91jzASgkM zl~^?Lmf+W}dp6yNt4_M)N=vuUdE zE^_f@81l)D~*NNm!};tRuEKuN4<9feO9VeaW;-BxCE#Sh zJJLpWYsI|=Th7&)o={D>t^g-t2aI1+DAb@>RWYaWtH&?S@ozZ|#4e{jARuULb%O&Y;Nq#9VkcSwlcBYx{)hS& z8KK9uUEsOb@of7qq@m^Fls3u_4&8FDYOh3K7!6UZ%f#Pg>l7$4QUS!sZDLT?(9Nbu&{4T-gh?6#~hyqRQOC?dgSk5X`=fIiiDIeU%sxk8<-#7)cB#D~Ua>w#W)i zm}B#MiqiNsMdRu28D43tDAS{5CFe?@%qh84;@~%CRLeELu(pvis(VQ~J%GDZr|VjN zBehzp3D>cZ&{Mz$Bt(XD(Enh+z7h)aL_cGh99zxSTa2xblClswcEuG&+IGic{5tJ} zPx>FHBD=%)E((3}l$UKq^>oH@gk)~x)+lA5tBsfaVF;Bnn8wVV20eBC<+5l13yElC z`MVoD%F5prKzwc_g&~I0{B2i09msQyzlE|Bp~Ic#6|&__$#+11vB&TOHZ0|Uqim$A z{98HcD2sxHYVlDvY}7|@0nEOISf?;prR!MR3_3eVI3Rk8 znt%FpvOK>*U}_|}%_A&Ro?o)qev2NV`Jds^6`>pxO*wWE%CXmQ{;MhIT?*Pbuyos( z>=Tt@!fhDG!nUhA$$RE9Z+Z6#7NTjeG?l+N!8Xg&PqMD6njhrVC)t>mL*2&mfT;9~ zlk7q(4`=z$@}iq;iR%7m^2wV}{U7{HR^4LVI<Bu*1u!xW(getZqXF`^H?f~J-my~ug^I?yl?a#dk#EW5fqPw0K<-L8=AVRgrJ z`3_hjVI?+g$Q)~Z0xkDB$@z}t47Y)KMtag(fmQAaiwoQ(?8U_y9cSboB^KJE&%sJV ztMn;8D$`=;4a>(^5L^4}Hg6}!?7(;|j9_IYj+1nlZVwO9Ng-W+vGlRWgG0UWypv?T zqBe2ogbN~D_PpO_QgWE5A+>oLr5)z1(kN*o{xj{zl7&g;9z?u+D6wC2sF!|ksE!62 zadGku?~vg=B)1|+nMp>lAd>U-pH2oHmz+<30@%;}HE2%@qdU>vcL@xZiOiIm*^5kE zit(bkF8@!ej?P13%itE%ZCpXy26>BABR)opRZgoMeTPM-<=5}QwAPTjIJC}%H3w_}_V!b@ z8HiyM6dMf0!gtXLJFnoU)m4r3RAQ!RbOWdTIAexb-iW!t@( zT}B>m%!Ku^bM2Letvw6M($sFdw+&R{U^JzGiC#5y3JW@j&x+tEm$?m=SF?t6LD9}X zNVWH$JawHX{eg<_rz|Ddk)XsH@|?@KzlWNJO8Js<@^E$(e(N8?-m>NUl5=1Nzc+AP5UCfxn2kEY*x{)X%+AB46(>+C96pUe>}~_? z2EuW{R1X`J*8+fEfCp_gcNCl@g52C>lAD=L(z;rUQ0fk`ZU}MRpcovwFS)1AuO#L5k_A$P$ggv`y*dLT8|Lw3ZVvZ~^kT#tDV3kdtj`GtB7R z2eh8^qZ_R)NxKS3~eU#?VaiM+DK8y)={BUm{h5%d= zHl!|VU>d_)93{nKe?(0pJ>!xNh(98dL%}3o3vGez-u(6|=M7 zTq3Rnubzer*)?2wIW*o%FNeMb&2=p}HP;Zj@1ACXg*N?f^1XEw+7*e+$btP(yb6q1 z$o`m3VhVmq>?XY|Dqz6n1H64Xe|Q?aq}DlEoadMXQAf7Y%HD}pyf+D6XXu{eg%zIqS#581@!{~jkN($G~D92x=%@w z&?Nm)5$fT5sqb@19edp=L&;We95jHj#GVAA;#(-4UXehJ4}Ue_u~NLrXtW7=ZFNgv z-hA3wz*jt0>e4p&z{6N*mQ8QO)yn69Fsb_zTPKWigghr6G!-30_Ba@cn_|qD>}(iw zovnABbAH{)HUi&muqbmzd=G&IYa<4awwZ8IQzUvzl)$-ntdDPJ?EO1Aa zpw=|b-+@|_$cMwUIkiOn%{uISM`VNh6DHgap9pscR7!GO4eQk^;kz=a22$#Qf{W<2 zqLA_OD>Y!1FMT8Ls$r>e`|WJM+5u`-dTu)_Q|Z9blT>q*kyKNBUw(H73-$TO{RZhq zKDmQ+z+HE;a|io_>Xl#Rt*@~m!M89`oIk;2VN5U>F3kwAHC2*pA~rjb^2%#$g35GJ z?)N&2RNenUUidmrqbwf3^2ZdIqQ4jFbztDfc3sF&E8~-0Vn)Ocr diff --git a/pc-bios/gpxe-eepro100-80861209.rom b/pc-bios/gpxe-eepro100-80861209.rom deleted file mode 100644 index 2ca59ec369fa3aa829aa64b80339dc9aaab9026f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56832 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 W%qy)>$jMJkNiEu($W+A0_zwV_ffC>V delta 49 zcmZqRXyA|tUB#3ZAZK`>@5XVq6b1=~9=x-N!Xmp87&{9)_ zwB_2^)Mn6Ld$vS_K~(3c4;%a7yYHUwd*|G9&hd6PnCJw)-vE4F0LTJ(JNQi?!^jX4 z!KP5ZIGdZey$dlZT-PiwBg#yCb6^7#+%gJgE}coGNK%k)q)vhSQs(8A5{}m>LXhi6 zo*<`@E~Jyulut^G>9VJ+{`3E`JH{?$(>>{ewrsgKj^G~au|G8*hB3XvN@lfKFjc#5 zm`2^;BF9q*bOt@p&|Y1b$-R9on@OkDl3f>lchvV9jFZye4fRcUL{fbh$bct`10+3* zQFsREk?X*R7s_}+zROe3>p~N6POr{RBB(h#L5=J_e(NYQ1-lcF&`OMu6RoZu3 zet6f}m`t%)us?0NvCpjoLsTuP`?hASLZ!q76m6mE7O&a7qBTI{rl}g09exO!S=Dw& WmR#}Y1GJ2CL8z9fYnD9sFaH7$iDUKv literal 12288 zcmeHIJ8u&~5Z)um5MBxr1r@SLgOE>gBs)q$VJkovDTp5sUCx{MlzVY^28Sx5qJ!T+ zNtKd0PEYG{D@_IA$pB`MM&G$W079^cH)ez$l2eEs)#rP_+*gHo3YTJMqG zBwZpUakiCed@SvM>esQ;EYNxd_U6{cdbiVg__RzQev7m*jT>t`E)mFIB*j_Li~Xkc z9WM;LT<7GP+#On5D|zB$lb&vuvXbj8@WNiF+cqptv7NKAYqQuJ)c3(k>IbIhI<>`) zN?jmz{B&dnAe-kqZC>D=t>lHywl-R3zOo6|^r;Up>~F#$VgCu)%^BaX`BZ#Jp$h-1 z=D$Ibg!{cK-O4|*KF(y$73nC+4onm^mq`1y*ky|GoB*1-I{iqH@V=*UGy81&RL}UU zWHj<1N<;1LSeDV}8tE~qn&4*%Kc>H#XJT9vUI1>d1eH(GU zy4LNQhsH5F`y)!3YtFrxN5*_1zpNKajOD$+n+q*5c!wJPFiTrWs$-XSFey{NNM?UNT=m8G z0X(3$;p^mU$XGS|9G3{+*v-RMl;U&HcBzg+6}CU)6V|z_)KBDDz&Xw|pZPvoXU;JqM=H)9PC?E8)1UpUd%nwtg?SFOXZglP8AL7SI9mACdrzzN&0PY5^G&jOf8cTV zkb|1LHc^LUE|D6X;}4Tu$8ZgX{ui9hv%mG#{{r@aE=I{fhssZ))GLCWP^)EcFvxVC zyS@&?TrKCpOKt7)ThUhKx~k}2wbejB4}85{9Hd%hdQS~p-}8ss4TD&_C|1FV2xI2b z#wmhG@6aEeyPN4}BOUt(iav)ko*yRu{*0e_@gDsxVpunb2YRf6xX@WPN{f7Ix~Z4x zxR?p}NnB(}80t(dR~7c0H2P@VN{3!NAVQ|u$V=VG%lGF)W; #size-cells = <0>; - - PowerPC,8544@0 { - device_type = "cpu"; - reg = <0x0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <0x8000>; // L1, 32K - i-cache-size = <0x8000>; // L1, 32K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - }; }; memory { @@ -82,6 +70,12 @@ compatible = "chrp,open-pic"; device_type = "open-pic"; }; + + global-utilities@e0000 { //global utilities block + compatible = "fsl,mpc8544-guts"; + reg = <0xe0000 0x1000>; + fsl,has-rstcr; + }; }; pci0: pci@e0008000 { @@ -119,4 +113,7 @@ chosen { linux,stdout-path = "/soc8544@e0000000/serial@4500"; }; + + hypervisor { + }; }; diff --git a/pc-bios/multiboot.bin b/pc-bios/multiboot.bin index d7da6e04ad6d71d26f577d9d6a019719bcce8766..f74a6e142fddc054d7f40ab346a108532afac40f 100644 GIT binary patch delta 130 zcmZqRXy9N8UBz^IvLch1k_>}NKwbbN69W|3F*(E8Hej)d650wJOlgdVQ`0)-7#MbQ zFr;?Mu`qPYSug<^Yz%4La#jcdDVPs61{F2d7QUGW|psQ~vLvCqKNoG=heu+X( Qequ^$(Pl-aHH?gB0YzjTu>b%7 delta 97 zcmZqRXyA|tUB#3ZAZK`>@5XVq6b1=~9=#D3-}pp@k%fVQ!ErJtlOfXw#?6UL^B5-=Fu5{T0RW9z B8_WOz diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc index ee6f5ae3b93a0570ff1eea5998716c361b15e989..83b7794ad1ca6edf4693bb8636ddb6e0b30e683a 100644 GIT binary patch delta 47467 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

lwYtk80;`@m|8X#YfHqeV)&p z$BV&QUjGbhM5=V`8N3Rd=JpG$@jRwFoRLiSGrZ=w7}Zw54D)&goP|9;pTfo9lhKB- z;Hv%XOWWpQ3JE2lnOZjyYVc` zO$|z^@U16dl|9Q!Qk9?zgoY)l^F}PR%iwQ6%QBHiTzr-_rZr%5Uynk53Smn_8E<+H z3r896d5--_(uHNt8d+nGJE{d{aQve$sx@M}+=w0<$%(#lHbSU-gBxJj_C8l@^mD zG<9BpkRV*$45Jv4mr1%jT3mHk&0?$rl~7h_R{94z^eo&WCVxKGgt{$J?Q{aD+!O5{ zDhIBpN4xT2p4Y-M_K%=5q-dL`aLvQnk8E7UUsP*B+|iPWVpE{lh44wU*-@>dEULN7 zTs|*eq~XwiC*>LBrU(t4DA|0X1v#9i8!jyL-Mq$yDKXBkyV!+Y>p)O=#Ey;3Zv{uf1?YGd#~tFA{i@n?1e@#sRl3-pkMdq~JUn4uqOpJ>g41m8EuFvIba;$Dz&I-O-WC9HXvgug#ZaJ+!Qo+{|`_-Uu_AxBQ} zz%8VWu>jF=sFof+gKl7^tQ9k;hc~pclemnuB8z3=HEkHfY#wfd>{T|HzRSYzx5HoL z5vbsibMf}r6?J&R?E$xnL)!a!gO{C#Mn=8t3TgDSY`geQ6~Z9!fuIzI!1^GhcY=?j znjfoW5A!d4mO1dLBmj+&&~}lXOdFIsz`PdnH{)B5i|lyneFcU}0GhpsA$M|{4?)5p zcly94T%!-VnCF8&_IZazDFN#WE&D=~xR=ovzBQz8t%6-*Li&byT?bzLO!9#aDB8@& zJJ`vTaY+DuZSk{L@zaoE{^4=Vk1#TuFZfx;Mn>rB43@A5ev>!%bf@3LG@RJPGFUi69g-!xw_Aac>=}$i|2qW-SFSop6mJm_b*t zJ1saF#Cu*GY*#U85M%H>+pcqTwGUi%qqtGpMNfu*h-2c&7S%!n1gC9-!`Iv*&Vk_> z2>mENZti4{JB9(FDS^W};%z1drX876pQn?)SJj@siz={7x!dP&@?a;sk}6%J1da0t zop|5n=GQ_np__am1RG%TX`G(Yx#xe9(pLQ?Xa$=1tuP#hnfG_G9G=?64k0S7>%w>n zP#a8Ou?vRPe!J`imX#!ubHZcna;cBhwHIf=kA(U3!!R%2kHI=Z>X62Z%Q0A}v$IgR zgl;lQ*%q)O2_vs4VL{i+xCfuzG=l-dCUaM3p$@E#A$At&u%CEsDYBeG2 zM?~?=&;YE6pHzz-J=N<87dTebFZ1hH5y{y3})$_04+dcS)_~((+k?1cUtCljG5y_dc$1@|^GmoL%LHS3N ze@6K>3VyuH{1(a#$}9?E6*HoE^E}E=P!>@>LRrS|KP91BPL%p>Zr3t@Vbb!k7#q7W3wjFE#I%&^!KCxph1xyQc8TzVq=i0>o1#j|J3jhEB delta 48446 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

c$nfz#*!oARbj*$8v5+Uh7x_l)1kXt6 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⪻pjjEDKS5_}m4+8)dEs4DjH-V(HV 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 literal 377388 zcmd444|rA8mG{5z&CR_b1h@$y|ItIBNs1H$qT-*LQ%fziwo+>?ZLPftR;hJ5jAO0S zSIZ$rq}FjlM4Dl&Jp_u>I&EYqrHnPVw;9TG94Et2OPy9PXl=%6ZH7UN7;@jw_uO+~ zgF0`2&oj^OAuT76_-V#5p(=6YNEVHazg=Tfhqp+#o?P{ zBBsT}O|jDXUn-h_t~i}GWm%CW_%G2*(yMw*M1}vPSAD26=|n8}72qIe;YfcOxX4O> z2{=}OH!e2jktL$5X%)_b-yiZn3w@$MkGyAqODuRV@B|Bf8o1Pge+E3!f_DR#S#Sn; zk_A5rJlTSG0Z*~u9l%Ko-UeK5!QTb0u;535r&{n9;7SYb1Dw!<~wotDk6`iFE-N7(CL((4Q9z^j29EVvVRdI1jkM=ky@lYV9)9sb*Z z9Sgn%c!mXk0l3kEZvvia!8ZWUvfvKjcUbUsz)cqXN#JG+z6Q9(g0BL8rv-l)c(w&! z4t$mcUj{tKf-ePrmjzz}JlBFR1U}n>&jSv8RXFT1A9$XXJ{Net1p@Im1BS@3hfms#+$z(Fh!j`;Ho@M0@{FYpH} z_-WwFE%;}^AGF}zz*kss2KYl3{3P&)EqE93l@`1Mc!>pX1OA8we;4>F3w{*%qZYgc z_-YI81OAu=KMZ`01#bZUxCO5VUTVQTz@M<-`++}c!S@1x%7Rw|Uu(ggz@N6@uK-_X z!Cwacj0N8YoU-6sfZHwj3&0%~d=v083%&vPdJFCV{;UOG2YiDCe-ijc3%&+;xdmSZ z{5cE$Fz`(ld^zyvE%-9vn=SZK;6Jh8OMt&%!50GmsRf@0yuyO#1OJ%?&jr54f@cH& zxdk@?-)g~)z+bfBGk|Zi;5y(hS#TBb?G{`C{1+BH8TiWqrd z8wdW11s?@oX~9Q;Jqtbryvl-K0q(Tmmx1rH;Fo~AEchVs-4^^D@M;Tw7Wf_ueg=4r z1@8s^ss%p{e6I!n4ESpnyc_sF3(f%lr3F6;e7^TJU#)do1`- z;0G*t3-CG%?gM_%f*%H6Z^0XYziz?nfqN~u2l%fo_;hoSnxH# zTP^r1;BQ;-hk+lp;LCx(W5JgJKW4#~0{^WAUjqDH3%(Hedlq~iaK8o52Y%dw=K^oD z;Mu@`XTeRt+by^e`1=-o2Jj9Gt^@vo1y=#@wBQQhA6oEa;9VA63jFsL90z{Ff}_Ac zIssRX13ziOM}Y?{_y};?f)4@z*n(dH&RFovz(29zmw*Q?_#p5%0Dj$qCj%d~;8Nf>EI1B4 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 z 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 vO>N0kW$+{XdFLs0mK diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64 index 70a223d573aead9505cf2579e59af37b897c6202..c8972acaeb320a74a49dceee3c2cb1190d2c8882 100644 GIT binary patch delta 39840 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

7QjREN z4}o4O(Qa@#H0P&DX(WfxI%oU6Z_cE<92)93iqxMbUnu?>;@5M;lg!lF+O-e&*V6vF zXp}VL*44VGn@C-Y1{m4vZ%6Q6`BG{Kp~IG+rnMDk>c|k?zML_KK$P_-c#Z6dI5z4T z)&Vhb;#aJcaE}nLzlfNTlRHhL9e*d0)~sUZax^T_|IlrV<3T1-a0U~NY?|yz6e8*n zj0GG;CSHR_q<&+z1z{lt1dLr8sYjb|uL&_b2iQpVJ6>61ZjF;l(PlL`6xj@up=z=Rpy1?JAf@IQz9ZBVYtBL1 zvW9j?X|?r>BDbK6x?mE$t$j z2+@!lo2Y=e7@9%e^5A?i1#M?BAoJK4kS#yj2HA$Riv^To&2fL6$=3ely&(3Q&&bZh zoZTAq3#M)vKNp3xQIgadYbwsA%^XGrqe0G`h(cj!T(lOA84_I0o=OK7c=!PwIM7Ns zi0XsxhjswbX((w#YM;$OfM*-~5^v-vG@l#4gqj2<)zxd&%%iCSq7FDS>2 z0ax^a`N}wq17TmcC18^k`QB?Ovb&aUu*`Y&A^>7 zGd9-5cO%~Ro^7)bF#w6=9c&bQz0kWGq)b)o|LAzWC9AdjeRW1tg$iFfjbs7#fsTTd z()-7@*5y=giO%9ine zY>#aQ+LG6%w|@-R8O|HnNr$M7gP)*vj^T<#+GeF<4`j%Ifb~wM*EiwHKaw=pp4crm z8(U_jl-8rGvx)4x5wItT6^u~!Abw-*N)NE@faEdQ=4?;XLk))>z@rnyVb*mstJAe@ zMj+yy+csaKIS+^$h9Pg7^EHh?c%6}?(T`#TCMw7v%UAF&jzRrTPOsVV zX^foZ*X6W97-kd5#)RN98}y{2w{6q6run{(Mep<%?D(0{juDI@9Z0yEd(m>E4*jXH z*_S((QZmnD<9vhorBHKb=9uOUvMSgtm=iWwCOg7HCNZZrHN`?N`NC6IBvE&f{A5^5 z`dP#Z1RD_?8*PVuLo~@O2=6zGm`o-)DOhN3Scl3Ne&*O9Oa)C0^Wbw8%8bA?ghr#a z&1A-Z6T3l+kZ;FHh%rAPWY6duA9oeko}NFk=@zl0LtfqMj>3k-hctPj&E zSAJ6cQL#8V2x&B?GJqLVnM|<+fln-oz!OqThv`A2rd`4vU|cqy>Z0IaDn~@X5xBI} z{j|8W05HiPhDx~8aulS`wbGcQSH3hVLdjtacW{FFw)?;!aS!_7N6ENW+3qL&_ShEX zgrbiQ-tER>+89iT=Skgxy2iTZz@FA4U}Ql`(YoEf*43a*>uS0dEN3oqY9c>H3`lT3 zAP&NFW8jtUtK*Quy7Vjg$jNy9VO_w>_{;>p(Q{ns+nm1njk-T+_V$5E88@K&$n#kQ*_vzVS z^#}T4I$fZz*RvA(n!2`ST?4l-Yej~*u#l}X5@?efvvaNY2wb8rioM;mb0(Si3()8t%|hT$|m@E0;J#Nbx^H^mBn ze&tJXzu5P%`|*^@xXe`duTP(qv*_o{ou?CYUoB+>8k@KOgvR&Ni3=Cpa?_1B%y<9# z7yC}1b-ViDPNdwf?hI(u05W`a2Y#!KsiF%D0+>Y_)Ad3kOa&fOg2WIf5tPnPiV>tQ3n9K0>4Rd4^(bqvkAZ=!?# zTY~gAfAb=p@Kw$pk7qGgR&r&#XNmLVQeyMXHO2B=CbwI1cj0p9X>Pk5WiEg(S>Ysc zo=aBS-zCm-sgq@ed{cx+n|7c-I}XCxzomGcT{aLMGKv% zL4&X6Mptu{t%s|lSDAZuq*m-xBD+CY>08cWtJ9q!!ID>uCkTdMNrOuX9EEf-#g;m&o( zg9g*#T<)1|8)S2@tjD?7&?C17w~v=Qaoa^hg8$Z^bHCwLSCGJY&t~!ZY zm@V(-GRD7sS0iIc+NEpd?n;tJ-{&YO`JL}_Tq|H%$la3+ik5n1kfQE#ls+yTad~!B zyGLb{u2uGA=5O^o?(nPg6bC}}^Vhlmk>>;UQ``ydZ~N)~`F+m!ed;Pz0Zp_2T(BzK z=x9EE8#5rL>qV`_U%QiLDp6TGe=%y1>Y&ts7*&AK%6{_QQ@*=8&rG%dk1o=o@);;k z;s;7T`R%Pq;Xq7rEp=F)SYu(_i)&KB7_{@0T z?o#TCgaK%f)Ow|^Ok9xIH&M>pxGE`&;?)MFMt8WB3e`sL6zn*tBX1Q-Wp^6fiMLHk z4NYE{+%H+(t<>1gmvttr60e+;q?C;*ysHjSd3h>zN9y&dT~bwQ4tK}R>(aA}>XM_D zcb(8RzN_k*qtRtuCQhTXhIqIg~clEwVRI%!oi+*rXpNr(Jb4KTkjv4aS z_P4liZeLel)i+0#^egPwt)J?bqqtSs6X#K$9HskT*FT}Z>Yt;07f-x6@nUsxjw-rj z(j`fks7rFxt(j9YJ7%iP9JO-5)B&9ar~x^uIBQx~a+b=?(iPN z)$km(Bs(uVCR=6as8u6oj7S-wM&zj5Mou5ud88VdqlR4Wh1He6VWY;4vfqYZajhVF zyT41Xy7a1c0epDI*#ET)zedeg3sezdUNuK8R4aHJtLCaj>Q>&ysd;L#TFKkBYQ9>c zSXxz%xGHkm#Wd~rp7*vSE|vCH#eF< ze)_6xH4IpFRsGe)>JrscWvT%xON~?`I9#q5PO9BhKb59>sNt%M8mhXhAy|vXLgM08 zf=Z-&9aKlvNo6RPN&yUGxGAW!>a8wPg8l=cVuRJ?YLvP{U9GMG*~Wrg*MdyBAWuHX zG7kj1s_{D2=e=2t6B{Qt7BM_t{k`M zO>6*u5F0J%7LmL4gQh5T9y+dF`h^_egXPX6Jym@(%HT$Gd3GWpwLN}_b>9|H+G-PdR=+Dx~sul>xU0)uR;J5)ySr+s z%ljjD^$HhvL!;2L669ADyP{M70x_30!*PC&xZ%+sY-=;DE6}pJpS}wt2=~(^y~37j zS&vp2rA0ZigkLyH`n0^=QOooKN?tx$`7 zo=OA?aN~#=u2*g5 zP}nqu-D!e7x&f(z484n{7L_ak@)Ns9?rXO#0^Y>ZL_C(xJ#-3Ko@hdc7P0t2$Kx0Q zplNG!(&j`k_tOWy-s$q+$O&M^F)1D+1(zOksx({7ni7exw;oX5)7-eKye*}@R-{f*`WBfr^Y88(3bTK=XL;_tfaI5g*mNUQ2m0C z2RSW^ZddN9IA;1P7a|9aRvh7$oV#1Bx|X`#xJl%#$9v0S=Jg2%F5#Q0 zBPXdav+YxlSqK7e11qkP;I~lRq&U+`4$YLII)M>tICzR2XK84!T*8f#mWyP%_-Yay ztlt@DE4D=wj}luq&w8M>^)wf2Dy#HJk~*tge!&Lr%ZOugnQ1kUiD{Ds-P|2jgvp7m z8%J7<{xNCW|LLMGA25%0z1M!iyzUUbXLCsIP-=0y>n%4c1+UCdW4C@7Z^sW5_ZJNJ&2IBxYgWGB0)Fhg|y~4D>MvOl? zvDZ5na@m%5)8Yo|TRXQ;`Cm@TfpQzo<#^fS5hg0nS? zKG_EnH1835cSHCn2*|d;Im#O4)$aRrQ3se5t1=}Du&@fOQDXdI+n?r$^#_m`Mok4n z_z~lH9TY>!J0R6zJ4fM^&N)xR*zIF~nmU%tD*DshJ#s{=+*k3g?!wVn+*i@bxv#=~ z&wt9;OyR^qW1A=DVeh#i({LAXFz4O}t^@CiiD>xZ3L40HLHrhDjs$*6E+O!FcvnZ+ z3EIqxiGWtNkHE&s zPVoAa7)yaAz~TuxCIpLDn5lNXvb!W$z%kE|4`Zlh?lX^Sl9^`VZirn~xLh#_v`=Pg zfA~lnNRlwb6JQ8PqJh!=M3T1joRs^C826kHLX7Pa+eR3JTOj@gw{jfA5bS*n!S-R7 zS0m1A;-JC!PNb;D4q{={iU*=tUWqLjzs5x8=KoiOo1jvi2%Q-1}Z> zmfrTBplfsAhsaX-enrh8)*8-Yl+#l?ny`HnxEjiQpMH=u?x%NQOa9q|uql6j9*q9g zU!pJ?zN|qwc^OU6^(4gAIT?v9fCRt}Mh@zSX9e?YTg@r<3!ZI` z)!QL{a1~siwBnJrl4rY~eZ(!ZTq0_}ibT|0Ljz;=v&$rt6TQ+z@044ycAV~~`wN@v zf?=c@VYc1XTaT=fUxNDrmN$arz zv&^7im@gyA4B&p8=7GPYsnzu$ZE~ic32n1i5w^Ddow|+-~LI1X@X^k z?1e+RDd(q}gH5^DBhEf4N)L{ldDnJ_k-an8^=dkcOqAJ&F3P`^sxSRhV8=F(v_E3A zsE>9yo~{VaJ}-EXiaJm`{do95ZT9VAELU$f4sf@vN6bJ$)a1i# zCzp16PBhTZDs-^h%h>m1*N0-ZR{Vn1?RsG(esXA=I*!TT3ojj}%fY_m*~Y))7qXPX zzw2Z%o15g$#x){YPYu1VkGCewe^Xet|BL=2l*!rV;Bztr$ZYrCU>UQ?F^^Qi`UJ$cbe(ouD&jQtBuh$`Q5kPZE(9L zKYeSJyw&VvO843tG&sptgs(Jfk4rbl+PVG1w$?VS-kQ~PN91Juo#tfx$|Fb&UWwtH z>N~b>mfTynm|tpQU(uaVYT_-OH)`UoS6dlaT4Q=^mjHcUq&w`C+XlpUP&WtGIqj~C z+ZvEEX;b>v8t1M1)_a||w5?A%Z@oy7VR7$P^K?6}f5bo5YU>hHmD60Ra=JiOyrt0v zs%qbb8vH(vY!pz`9Izfz4g_I2cIRW%^SDPY6VT1imz%!)!%*B5X+ouW6DU@Pn;>-w zfv;>_2(j`s-C@mdySKm|9o9x-o9-|m6*S^P2-=^4#H#91S6Lr!izvc*6j>HKf-B^T zlQ)z%$z9ze*1FE+<#?olF-Wrzer;jjP+-ix3jxyT8uZvU41;pDvhCNjvPVW zlNy7ZXxm{KCHV0CH0HHOUgFAHAdTBFNOnJS7g+ldoC^30*6x-UuBqbyiO>vA1*I=L z8aez5mxoF0gxP_}ZEF%Fc3TyC`$>^peEQ^B{R!tiBSpauyoCFX<#4_|T>jHh=%Fm* z>l#c`I5%SbtVxc@MS?j3krVCUxrmZUMUD{U#N2A9ya}O_@r#L+`l!(87s@&)5 z)H}1S-e)8A{#-zQk980cgdC{5M-MnlAMB1ugRp)_C}w7^-77hk6&m@&v-DB+y6IN+ zKav;l+Ic^b6DPQ6#sE3)?^Y|oWZfi7kMCR^7z8BSntO~ByT5BU5m89qNOM26e#yEG zKK%WrGJ^T(wD;3c@vvZz-;1x?LH4Wo(VF}mB+uo9!EAQ^Q($2%PC1Z(K+>4kN)lx> z0vzRFrzyvr-XzY6+x#k&)p${DS>xfQ6&HZNif0MMa5M~}N_*~9F3oJQuYTENU;Sck zWED&L$YLN8fxz2llO<7w0vE>*_yL8fg9sY z^~z5Rn6Wd>+}Ki>U}Qrlxh?!u#e1pTFCh8*+~?%qME)6U3Bavmf?Jg*GfPKOWFn|g z=t8V>ooti}W8@7#hb@J%@`mr*mclrB>m+aSys-myGRQ{F&L9J1XArEkGqBE@4E!e6 z?4ecl?YI55HN4{@U~K&vGLf&y?lV;^;BOAw_PQUv!0fi?4gtqiW3}bAjAGeBU8p z|K_p~`5B>vHRd+^#yL5qm-9%5hs;&+TuU#OWlowa>g+U7zzr@gr*l`8@n9wYGMwV7 zAL0z$HPwCZRGC^YOu`M_5Ai{1D#7T|LqDRP5I~2f3@qaa{y#LEmsA*6nk$ zC!d!+oL9L_&K7QmAm;}vw9d)$Cz&DbYCN&?2~*vx>g%0JrO774Q?h%&$s)R2_wE*S zynd8;_SH`6>L171Gi8@WTK@IUAG)gpNZ_f!RL!E#m9WbpC z#@3c8?RvEve5&)eVbi~Edj4mdHf(5pr*+pyts9D4T3XhR#%y==dh;B;ezXLvPqhQq zV}|JUri&HyN4rSh$~`7|dD^R5cm3@7=YO`V)t%`6!T$aG%e`7_Z~BJxYcIbxJA3u< z#*IriE?w$ts{h%I-j6==-uSbM#*-~48!J>y%D9$sTyC81-H@KX!JAGttuY+k_|7|b zU3Ae!YTVM%#l@rdW6_Lh@`ep29m!fv`gF{J`Qw{rCATE=P}z%G7716a>g(%ad{w4y z)tNlWU@W*>TTOCFA%EHB<=Gh7s^a2e^Icrr!hgjodwqR*@<|G6*q@%Q8`S9H(QE&* zf2~@ysNSSY&t9}>QFglGUpnvLy|>k?iOSACOM&)ZwnQM|4F3_4kWA|O3bnrBwZmUG ztykHrv-vx#%J(OaUbNqSCez&vZ}I+?v zPpXzBMdd|HTI}bd<0k$!Jx(#kWZSQR9)IPkZ!*oKJx#i}yjVA>&v!kGY4zvL_5-?%zM`uRJ%T%!3qEA>%)wj%f2 zEypO2LMThZX+pVbY1o`TlKRT2chRD9C7n-Bh*9N&AnE1cGl|>&TC)voB%nNbJ>%NA zXc7JYi+t~|r~Zs&f(e)Jv%qO|@gll(obR;)@so{EI4SiPdMpK+^7`_e*f}So+ax%QbPb|Fz)}&q=RyaADKW(wEsK&LP!zOd}i-wncUU*26mARkZt;ZZM9ZKeCJ{mRm zrzm?q(UU4qezUe)#rugI(j`Ug)43tUwsaq+BEsO`A{cL}n-Njvy} z1DW7Ik=A)Q?ci&czT16=`yThb?z`N4SfTUg4q^OS@EfUlIIa1$Kw9UWK*Iw8X@&>V z3~#3yo=h{mlxFxp&G7B%w9cn#&2I#byL}L6Nb5O~#=rdl&|xfTtPV^J3~8NipVIgl z!#<>SzDe7`$iTqBuXG@7hX9b#cVGuQUUwbe!GTx);0{5CG+SN`A*A#?-rhurZUA_NQ+MK=(C>>b}BPQXA3Gy~Ii0D}?~sK5kr;N`==ARY+( V{|_W)orlnq&V$89i9sI%b^rzF84v&f diff --git a/tizen/data/pc-bios/pxe-rtl8139.bin b/tizen/data/pc-bios/pxe-rtl8139.bin deleted file mode 100644 index db7d76d9ca41889cb993fdfd73a9f260f0debbd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56320 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∋T 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�OC$lv5n%3xi{UJC%+fPZP@xqoyML}ctd z`X~J{-0@k7KzK~!&ukorv%l*Tu0=h^d)(PKc*bDt^u<>0Q9+pj)Wp0Jy_{1$G`X<~ z30^W!2DP6PfbbD}R-pa!E(8x5aQODB8SRz1uwR*PNUgcopqc0B`@y#1q9`mpiPh23 zeNat4`d;@lpqGOEuWWmiyGsDl+$R9We7lxC^$?3XZ@6C9;G{(wYli;`XF!A@4{e8+ z6H4XY&lXFV>7Q#4AeS^f5P%K}(WfO8g>#1@#|<%4o?z3TWLEX*v-J=FRCyuf0pmdY{EbR6cM&U&Ekn)zWMDf_mAKEyLL9o2ekK1!1)%t zXPaHu5lfObQ>+>r6i=m$M3tm`Ls<$kzE4lQ>CAS{c>)p0^s_@?dR>(^aT?)g%1@v*8e zLZz?y;1^X@v??X}LECr=6YQ8~na z^u8bjR66){@%E@#AMizhPm6adzEsb`&n6tLKTr~aK}G$tdVB+%-p;o(s$aI4fj+yt z3D1|pSq3b)OPF;H*cI*3uMZVg%sPegi4nhdX^C#CjFh2tU7far8?*)=LH1L(kcmu7dC-OcDJrlz5ZHFT6=W z=gLe(B{fw2oKu9V+M?3*o`)s^L_r!D9XsDZ%Ef!dZDF@tSN{YroZs^YT>Sms=930o zP+kZUjC>OJ^^Uqgv>5{PxT8M;EUWUj$fst`9{{0AyF?#tUfZM`Jc`7Gqrh8GgQ|g5 zXN^w_qy=wRwZ}rX5 zHDBWr)Oe*Ux5GVRq;K<`8shsf{YzMt?gg(q9Y;y-d9g%`IIz*5P z`tX%GU~uH?n@r!*caPk*Jc3TZZ@l);jT<*DLc-;0ZWv=D=yH)T#M_1l`RpM>=67cA z6Qe^NlA)Kiemvhy$hFYGvj&nr*fZJfd)|#h?l1^`2)T_#kGY+jf|Qlk_#I2$a{!VFtLLhpyDKe_THguwtx<$fG?{K)-Ul+T~kt(tfn+K-Fv?Dph!~#H9j(^E zDRh^_wHQh=%*9-&J9!EYySN>bR?&pNv1%u#xZ6$2>8gN_I3^=7>lTuZ&O|;1zXawJ z937ld(?`|UQs6jDPt&ps(~fCyCZ_iteA#$%;veU3cSqESj*DqyNM>II;Ikd`%h5wn zm@-MrgZG*iV2&lWEgyyJF~}CU9rK+rDTeyt`xrDxgNNf2J|7!gtUEmT$|GO#9>hMz z3P&^+VZH+LxPkwySy`F^X6C)-bj=kI&Uo0bU8uV6B7Qm7D}xo3x-D?^I1p8Hc9WrM v_2$2zQrAg+TvtA{t;C8FJ+eu@(FOQxcjpf14fsD$5U@ny`riTV|M~qNI?NBh diff --git a/tizen/data/pc-bios/pxe-virtio.bin b/tizen/data/pc-bios/pxe-virtio.bin deleted file mode 100644 index 6dde514c79304041837ed0de99678149844d9419..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56320 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 diff --git a/tizen/data/pc-bios/vgabios-tizenvga.bin b/tizen/data/pc-bios/vgabios-tizenvga.bin deleted file mode 100644 index 24d03a84da03ce67ce8cc09ad8f6b397fb5f7b74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38912 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 diff --git a/tizen/data/pc-bios/vgabios.bin b/tizen/data/pc-bios/vgabios.bin deleted file mode 100644 index 75a3c5c4ef95dccdea8ec012a3d762c55bcf228a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36352 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 MrD5Lx_vNPiACof$8~^|S diff --git a/tizen/data/sdcard_1024.img b/tizen/data/sdcard_1024.img deleted file mode 100644 index 616fa8b6e0c391f558eabfdda5c53fa757d237e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2097152 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 diff --git a/tizen/data/sdcard_256.img b/tizen/data/sdcard_256.img deleted file mode 100644 index c2442b0aebbe3bfc8099c9305da3f97cdfbab939..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5308416 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 h3ty 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 %qw(3V+>eG<2 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 diff --git a/tizen/data/sdcard_512.img b/tizen/data/sdcard_512.img deleted file mode 100644 index b836b2f9023a4e3a5979f6732c2e0360bd95b59e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1245184 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 - Copyright (C) - - 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. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/tizen/distrib/ffmpeg/COPYING.GPLv3 b/tizen/distrib/ffmpeg/COPYING.GPLv3 deleted file mode 100644 index 94a9ed0..0000000 --- a/tizen/distrib/ffmpeg/COPYING.GPLv3 +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, 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 -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state 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 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 3 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, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/tizen/distrib/ffmpeg/COPYING.LGPLv2.1 b/tizen/distrib/ffmpeg/COPYING.LGPLv2.1 deleted file mode 100644 index 00b4fed..0000000 --- a/tizen/distrib/ffmpeg/COPYING.LGPLv2.1 +++ /dev/null @@ -1,504 +0,0 @@ - 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.1 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 - -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/tizen/distrib/ffmpeg/COPYING.LGPLv3 b/tizen/distrib/ffmpeg/COPYING.LGPLv3 deleted file mode 100644 index 65c5ca8..0000000 --- a/tizen/distrib/ffmpeg/COPYING.LGPLv3 +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - 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 that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU 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 as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/tizen/distrib/ffmpeg/CREDITS b/tizen/distrib/ffmpeg/CREDITS deleted file mode 100644 index 404cf38..0000000 --- a/tizen/distrib/ffmpeg/CREDITS +++ /dev/null @@ -1,53 +0,0 @@ -This file contains the name of the people who have contributed to -FFmpeg. The names are sorted alphabetically by last name. - -Dénes Balatoni -Michel Bardiaux -Fabrice Bellard -Patrice Bensoussan -Alex Beregszaszi -BERO -Thilo Borgmann -Mario Brito -Ronald Bultje -Alex Converse -Maarten Daniels -Reimar Doeffinger -Tim Ferguson -Brian Foley -Arpad Gereoffy -Philip Gladstone -Vladimir Gneushev -Roine Gustafsson -David Hammerton -Wolfgang Hesseler -Marc Hoffman -Falk Hueffner -Aurélien Jacobs -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 -Stefano Sabatini -Roman Shaposhnik -Oded Shimon -Dieter Shirley -Konstantin Shishkov -Juan J. Sierralta -Ewald Snel -Sascha Sommer -Leon van Stuivenberg -Roberto Togni -Lionel Ulmer -Reynaldo Verdejo diff --git a/tizen/distrib/ffmpeg/Changelog b/tizen/distrib/ffmpeg/Changelog deleted file mode 100644 index 1ecc118..0000000 --- a/tizen/distrib/ffmpeg/Changelog +++ /dev/null @@ -1,596 +0,0 @@ -Entries are sorted chronologically from oldest to youngest within each release, -releases are sorted from youngest to oldest. - -version 0.6: - -- PB-frame decoding for H.263 -- deprecated vhook subsystem removed -- deprecated old scaler removed -- VQF demuxer -- Alpha channel scaler -- PCX encoder -- RTP packetization of H.263 -- RTP packetization of AMR -- RTP depacketization of Vorbis -- CorePNG decoding support -- Cook multichannel decoding support -- introduced avlanguage helpers in libavformat -- 8088flex TMV demuxer and decoder -- per-stream language-tags extraction in asfdec -- V210 decoder and encoder -- remaining GPL parts in AC-3 decoder converted to LGPL -- QCP demuxer -- SoX native format muxer and demuxer -- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries -- DPX image decoder -- Electronic Arts Madcow decoder -- DivX (XSUB) subtitle encoder -- nonfree libamr support for AMR-NB/WB decoding/encoding removed -- experimental AAC encoder -- RTP depacketization of ASF and RTSP from WMS servers -- RTMP support in libavformat -- noX handling for OPT_BOOL X options -- Wave64 demuxer -- IEC-61937 compatible Muxer -- TwinVQ decoder -- Bluray (PGS) subtitle decoder -- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks) -- WMA Pro decoder -- Core Audio Format demuxer -- Atrac1 decoder -- MD STUDIO audio demuxer -- RF64 support in WAV demuxer -- MPEG-4 Audio Lossless Coding (ALS) decoder -- -formats option split into -formats, -codecs, -bsfs, and -protocols -- IV8 demuxer -- CDG demuxer and decoder -- R210 decoder -- Auravision Aura 1 and 2 decoders -- Deluxe Paint Animation playback system -- SIPR decoder -- Adobe Filmstrip muxer and demuxer -- RTP depacketization of H.263 -- Bink demuxer and audio/video decoders -- enable symbol versioning by default for linkers that support it -- IFF PBM/ILBM bitmap decoder -- concat protocol -- Indeo 5 decoder -- RTP depacketization of AMR -- WMA Voice decoder -- ffprobe tool -- AMR-NB decoder -- RTSP muxer -- HE-AAC v1 decoder -- Kega Game Video (KGV1) decoder -- VorbisComment writing for FLAC, Ogg FLAC and Ogg Speex files -- RTP depacketization of Theora -- HTTP Digest authentication -- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp -- Psygnosis YOP demuxer and video decoder -- spectral extension support in the E-AC-3 decoder -- unsharp video filter -- RTP hinting in the mov/3gp/mp4 muxer -- Dirac in Ogg demuxing -- seek to keyframes in Ogg -- 4:2:2 and 4:4:4 Theora decoding -- 35% faster VP3/Theora decoding -- faster AAC decoding -- faster H.264 decoding -- WebM support in Matroska de/muxer -- low overhead Ogg muxing -- VP8 de/encoding via libvpx -- CODEC_CAP_EXPERIMENTAL added - - - -version 0.5: - -- 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 decoder -- build system improvements -- tabs and trailing whitespace removed from the codebase -- CamStudio video decoder -- 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 Motion Blocks Video decoder -- improved Theora/VP3 decoder -- True Audio (TTA) decoder -- AVS demuxer and video decoder -- JPEG-LS encoder -- Smacker demuxer and decoder -- NuppelVideo/MythTV demuxer and RTjpeg decoder -- KMVC decoder -- MPEG-2 intra VLC support -- MPEG-2 4:2:2 encoder -- Flash Screen Video decoder -- GXF demuxer -- Chinese AVS decoder -- GXF muxer -- MXF demuxer -- VC-1/WMV3/WMV9 video decoder -- MacIntel support -- AVISynth support -- VMware video decoder -- VP5 video decoder -- VP6 video decoder -- WavPack lossless audio decoder -- Targa (.TGA) picture decoder -- Vorbis audio encoder -- Delphine Software .cin demuxer/audio and video decoder -- Tiertex .seq demuxer/video decoder -- MTV demuxer -- TIFF picture encoder and decoder -- GIF picture decoder -- Intel Music Coder decoder -- Zip Motion Blocks Video encoder -- Musepack decoder -- Flash Screen Video encoder -- Theora encoding via libtheora -- BMP encoder -- WMA encoder -- GSM-MS encoder and decoder -- DCA decoder -- DXA demuxer and decoder -- DNxHD decoder -- Gamecube movie (.THP) playback system -- Blackfin optimizations -- Interplay C93 demuxer and video decoder -- Bethsoft VID demuxer and video decoder -- CRYO APC demuxer -- Atrac3 decoder -- V.Flash PTX decoder -- RoQ muxer, RoQ audio encoder -- Renderware TXD demuxer and decoder -- extern C declarations for C++ removed from headers -- sws_flags command line option -- codebook generator -- RoQ video encoder -- QTRLE encoder -- OS/2 support removed and restored again -- AC-3 decoder -- NUT muxer -- additional SPARC (VIS) optimizations -- Matroska muxer -- slice-based parallel H.264 decoding -- Monkey's Audio demuxer and decoder -- AMV audio and video decoder -- DNxHD encoder -- H.264 PAFF decoding -- Nellymoser ASAO decoder -- Beam Software SIFF demuxer and decoder -- libvorbis Vorbis decoding removed in favor of native decoder -- IntraX8 (J-Frame) subdecoder for WMV2 and VC-1 -- Ogg (Theora, Vorbis and FLAC) muxer -- The "device" muxers and demuxers are now in a new libavdevice library -- PC Paintbrush PCX decoder -- Sun Rasterfile decoder -- TechnoTrend PVA demuxer -- Linux Media Labs MPEG-4 (LMLM4) demuxer -- AVM2 (Flash 9) SWF muxer -- QT variant of IMA ADPCM encoder -- VFW grabber -- iPod/iPhone compatible mp4 muxer -- Mimic decoder -- MSN TCP Webcam stream demuxer -- RL2 demuxer / decoder -- IFF demuxer -- 8SVX audio decoder -- non-recursive Makefiles -- BFI demuxer -- MAXIS EA XA (.xa) demuxer / decoder -- BFI video decoder -- OMA demuxer -- MLP/TrueHD decoder -- Electronic Arts CMV decoder -- Motion Pixels Video decoder -- Motion Pixels MVI demuxer -- removed animated GIF decoder/demuxer -- D-Cinema audio muxer -- Electronic Arts TGV decoder -- Apple Lossless Audio Codec (ALAC) encoder -- AAC decoder -- floating point PCM encoder/decoder -- MXF muxer -- DV100 AKA DVCPRO HD decoder and demuxer -- E-AC-3 support added to AC-3 decoder -- Nellymoser ASAO encoder -- ASS and SSA demuxer and muxer -- liba52 wrapper removed -- SVQ3 watermark decoding support -- Speex decoding via libspeex -- Electronic Arts TGQ decoder -- RV40 decoder -- QCELP / PureVoice decoder -- RV30 decoder -- hybrid WavPack support -- R3D REDCODE demuxer -- ALSA support for playback and record -- Electronic Arts TQI decoder -- OpenJPEG based JPEG 2000 decoder -- NC (NC4600) camera file demuxer -- Gopher client support -- MXF D-10 muxer -- generic metadata API - - - -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 visualization -- 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 -- FunCom ISS audio file demuxer and according ADPCM decoding - - - -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 optimization). 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/tizen/distrib/ffmpeg/Doxyfile b/tizen/distrib/ffmpeg/Doxyfile deleted file mode 100644 index ee233b9..0000000 --- a/tizen/distrib/ffmpeg/Doxyfile +++ /dev/null @@ -1,1037 +0,0 @@ -# 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 = *.svn *.git - -# 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 optimized 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_AV_CONFIG_H HAVE_MMX HAVE_MMX2 HAVE_AMD3DNOW \ - -# 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/tizen/distrib/ffmpeg/INSTALL b/tizen/distrib/ffmpeg/INSTALL deleted file mode 100644 index 8cd22bd..0000000 --- a/tizen/distrib/ffmpeg/INSTALL +++ /dev/null @@ -1,11 +0,0 @@ - -1) Type './configure' to create the configuration. A list of configure -options is printed by running 'configure --help'. - -'configure' can be launched from a directory different from the FFmpeg -sources to build the objects out of tree. To do this, use an absolute -path when launching 'configure', e.g. '/ffmpegdir/ffmpeg/configure'. - -2) Then type 'make' to build FFmpeg. GNU Make 3.81 or later is required. - -3) Type 'make install' to install all binaries and libraries you built. diff --git a/tizen/distrib/ffmpeg/LICENSE b/tizen/distrib/ffmpeg/LICENSE deleted file mode 100644 index 668350b..0000000 --- a/tizen/distrib/ffmpeg/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ -FFmpeg: -------- - -Most files in FFmpeg are under the GNU Lesser General Public License version 2.1 -or later (LGPL v2.1+). Read the file COPYING.LGPLv2.1 for details. Some other -files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to -FFmpeg. - -Some optional parts of FFmpeg are licensed under the GNU General Public License -version 2 or later (GPL v2+). See the file COPYING.GPLv2 for details. None of -these parts are used by default, you have to explicitly pass --enable-gpl to -configure to activate them. In this case, FFmpeg's license changes to GPL v2+. - -Specifically, the GPL parts of FFmpeg are - -- libpostproc -- optional MMX optimizations for YUV to RGB colorspace conversion in - libswscale/x86/yuv2rgb_template.c -- optional x86 optimizations in the files - libavcodec/x86/h264_deblock_sse2.asm - libavcodec/x86/h264_idct_sse2.asm - libavcodec/x86/idct_mmx.c -- the X11 grabber in libavdevice/x11grab.c - -There are a handful of files under other licensing terms, namely: - -* The files libavcodec/jfdctfst.c, libavcodec/jfdctint.c, libavcodec/jrevdct.c - are taken from libjpeg, see the top of the files for licensing details. - -Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then -the configure parameter --enable-version3 will activate this licensing option -for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts, -COPYING.GPLv3 to learn the exact legal terms that apply in this case. - - -external libraries: -------------------- - -Some external libraries, e.g. libx264, are under GPL and can be used in -conjunction with FFmpeg. They require --enable-gpl to be passed to configure -as well. - -The OpenCORE external libraries are under the Apache License 2.0. That license -is incompatible with the LGPL v2.1 and the GPL v2, but not with version 3 of -those licenses. So to combine the OpenCORE libraries with FFmpeg, the license -version needs to be upgraded by passing --enable-version3 to configure. - -The nonfree external library libfaac can be hooked up in FFmpeg. You need to -pass --enable-nonfree to configure to enable it. Employ this option with care -as FFmpeg then becomes nonfree and unredistributable. diff --git a/tizen/distrib/ffmpeg/MAINTAINERS b/tizen/distrib/ffmpeg/MAINTAINERS deleted file mode 100644 index f9891fe..0000000 --- a/tizen/distrib/ffmpeg/MAINTAINERS +++ /dev/null @@ -1,359 +0,0 @@ -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 - -ffplay: - ffplay.c Michael Niedermayer - -ffserver: - ffserver.c, ffserver.h Baptiste Coudurier - -Commandline utility code: - cmdutils.c, cmdutils.h Michael Niedermayer - -QuickTime faststart: - tools/qt-faststart.c Baptiste Coudurier - - -Miscellaneous Areas -=================== - -documentation Mike Melanson, Diego Biurrun -website Robert Swain -build system (configure,Makefiles) Diego Biurrun, Mans Rullgard -project server Diego Biurrun, Mans Rullgard -mailinglists Michael Niedermayer, Baptiste Coudurier -presets Robert Swain -metadata subsystem Aurelien Jacobs -release management Diego Biurrun, Reinhard Tartler - - -libavutil -========= - -External Interfaces: - libavutil/avutil.h Michael Niedermayer -Internal Interfaces: - libavutil/common.h Michael Niedermayer - -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 Michael Niedermayer - mem.c Michael Niedermayer - opt.c, opt.h Michael Niedermayer - arithmetic expression evaluator: - eval.c Michael Niedermayer - audio and video frame extraction: - parser.c Michael Niedermayer - bitstream 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 - lzw.* Michael Niedermayer - floating point AAN DCT: - faandct.c, faandct.h Michael Niedermayer - Golomb coding: - golomb.c, golomb.h Michael Niedermayer - LPC: - lpc.c, lpc.h Justin Ruggles - motion estimation: - motion* Michael Niedermayer - rate control: - ratecontrol.c Michael Niedermayer - libxvid_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 - 8svx.c Jaikrishnan Menon - aasc.c Kostya Shishkov - aac*, sbr.h Alex Converse - ac3* Justin Ruggles - alacenc.c Jaikrishnan Menon - alsdec.c Thilo Borgmann - apedec.c Kostya Shishkov - asv* Michael Niedermayer - atrac3* Benjamin Larsson - bgmc.c, bgmc.h Thilo Borgmann - bink.c Kostya Shishkov - binkaudio.c Peter Ross - bmp.c Mans Rullgard, Kostya Shishkov - cavs* Stefan Gehrer - celp_filters.* Vitor Sessak - cinepak.c Roberto Togni - cljr Alex Beregszaszi - cook.c, cookdata.h Benjamin Larsson - cscd.c Reimar Doeffinger - dca.c Kostya Shishkov, Benjamin Larsson - dnxhd* Baptiste Coudurier - dpcm.c Mike Melanson - dxa.c Kostya Shishkov - dv.c Roman Shaposhnik - eacmv*, eaidct*, eat* Peter Ross - ffv1.c Michael Niedermayer - flac* Justin Ruggles - flashsv* Benjamin Larsson - flicvideo.c Mike Melanson - g726.c Roman Shaposhnik - gifdec.c Baptiste Coudurier - h264* Loren Merritt, Michael Niedermayer - h261* Michael Niedermayer - h263* Michael Niedermayer - huffyuv.c Michael Niedermayer - idcinvideo.c Mike Melanson - imc* Benjamin Larsson - indeo2* Kostya Shishkov - indeo5* Kostya Shishkov - interplayvideo.c Mike Melanson - ivi* Kostya Shishkov - jpeg_ls.c Kostya Shishkov - kmvc.c Kostya Shishkov - lcl*.c Roberto Togni, Reimar Doeffinger - libgsm.c Michel Bardiaux - libdirac* David Conrad - libopenjpeg.c Jaikrishnan Menon - libschroedinger* David Conrad - libspeexdec.c Justin Ruggles - libtheoraenc.c David Conrad - libx264.c Mans Rullgard, Jason Garrett-Glaser - loco.c Kostya Shishkov - lzo.h, lzo.c Reimar Doeffinger - mdec.c Michael Niedermayer - mimic.c Ramiro Polla - mjpeg.c Michael Niedermayer - mlp* Ramiro Polla - mmvideo.c Peter Ross - mpc* Kostya Shishkov - 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 - nellymoserdec.c Benjamin Larsson - nuv.c Reimar Doeffinger - pcx.c Ivo van Poorten - ptx.c Ivo van Poorten - qcelp* Reynaldo H. Verdejo Pinochet - qdm2.c, qdm2data.h Roberto Togni, Benjamin Larsson - 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 - rl2.c Sascha Sommer - rpza.c Roberto Togni - rtjpeg.c, rtjpeg.h Reimar Doeffinger - rv10.c Michael Niedermayer - rv3* Kostya Shishkov - rv4* Kostya Shishkov - s3tc* Ivo van Poorten - smacker.c Kostya Shishkov - smc.c Mike Melanson - snow.c Michael Niedermayer, Loren Merritt - sonic.c Alex Beregszaszi - sunrast.c Ivo van Poorten - svq3.c Michael Niedermayer - targa.c Kostya Shishkov - tiff.c Kostya Shishkov - truemotion1* Mike Melanson - truemotion2* Kostya Shishkov - truespeech.c Kostya Shishkov - tscc.c Kostya Shishkov - tta.c Alex Beregszaszi, Jaikrishnan Menon - txd.c Ivo van Poorten - ulti* Kostya Shishkov - vb.c Kostya Shishkov - vc1* Kostya Shishkov - vcr1.c Michael Niedermayer - vmnc.c Kostya Shishkov - vorbis_enc.c Oded Shimon - vorbis_dec.c Denes Balatoni - vp3* Mike Melanson - vp5 Aurelien Jacobs - vp6 Aurelien Jacobs - vqavideo.c Mike Melanson - wavpack.c Kostya Shishkov - wmaprodec.c Sascha Sommer - wmavoice.c Ronald S. Bultje - wmv2.c Michael Niedermayer - wnv1.c Kostya Shishkov - xan.c Mike Melanson - xl.c Kostya Shishkov - xvmc.c Ivan Kalvachev - zmbv* Kostya Shishkov - -Hardware acceleration: - dxva2* Laurent Aimar - vaapi* Gwenole Beauchesne - vdpau* Carl Eugen Hoyos - - -libavdevice -=========== - External Interface: - libavdevice/avdevice.h - - - libdc1394.c Roman Shaposhnik - v4l2.c Luca Abeni - vfwcap.c Ramiro Polla - - -libavformat -=========== - -Generic parts: - External Interface: - libavformat/avformat.h Michael Niedermayer - Utility Code: - libavformat/utils.c Michael Niedermayer - - -Muxers/Demuxers: - 4xm.c Mike Melanson - adtsenc.c Robert Swain - aiff.c Baptiste Coudurier - ape.c Kostya Shishkov - avi* Michael Niedermayer - bink.c Peter Ross - crc.c Michael Niedermayer - daud.c Reimar Doeffinger - dv.c Roman Shaposhnik - dxa.c Kostya Shishkov - electronicarts.c Peter Ross - ffm* Baptiste Coudurier - flac* Justin Ruggles - flic.c Mike Melanson - flvdec.c, flvenc.c Michael Niedermayer - gxf.c Reimar Doeffinger - gxfenc.c Baptiste Coudurier - idcin.c Mike Melanson - idroq.c Mike Melanson - iff.c Jaikrishnan Menon - ipmovie.c Mike Melanson - img2.c Michael Niedermayer - iss.c Stefan Gehrer - libnut.c Oded Shimon - lmlm4.c Ivo van Poorten - matroska.c Aurelien Jacobs - matroskadec.c Aurelien Jacobs - matroskaenc.c David Conrad - metadata* Aurelien Jacobs - mm.c Peter Ross - mov.c Michael Niedermayer, Baptiste Coudurier - movenc.c Michael Niedermayer, Baptiste Coudurier - mpc.c Kostya Shishkov - mpeg.c Michael Niedermayer - mpegenc.c Michael Niedermayer - mpegts* Baptiste Coudurier - msnwc_tcp.c Ramiro Polla - mtv.c Reynaldo H. Verdejo Pinochet - mxf* Baptiste Coudurier - nsvdec.c Francois Revol - nut.c Michael Niedermayer - nuv.c Reimar Doeffinger - oggdec.c, oggdec.h David Conrad - oggenc.c Baptiste Coudurier - oggparse*.c David Conrad - psxstr.c Mike Melanson - pva.c Ivo van Poorten - r3d.c Baptiste Coudurier - raw.c Michael Niedermayer - rdt.c Ronald S. Bultje - rl2.c Sascha Sommer - rmdec.c, rmenc.c Ronald S. Bultje, Kostya Shishkov - rtmp* Kostya Shishkov - rtp.c, rtpenc.c Luca Abeni - rtp_asf.* Ronald S. Bultje - rtp_mpv.*, rtp_aac.* Luca Abeni - rtsp.c Luca Barbato - sdp.c Luca Abeni - segafilm.c Mike Melanson - siff.c Kostya Shishkov - smacker.c Kostya Shishkov - swf.c Baptiste Coudurier - tta.c Alex Beregszaszi - txd.c Ivo van Poorten - voc.c Aurelien Jacobs - wav.c Michael Niedermayer - wc3movie.c Mike Melanson - westwood.c Mike Melanson - wv.c Kostya Shishkov - -Protocols: - http.c Ronald S. Bultje - udp.c Luca Abeni - - -Operating systems / CPU architectures -===================================== - -Alpha Mans Rullgard, Falk Hueffner -ARM Mans Rullgard -AVR32 Mans Rullgard -MIPS Mans Rullgard -BeOS Francois Revol -Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier -Amiga / PowerPC Colin Ward -Linux / PowerPC Luca Barbato -Windows MinGW Alex Beregszaszi, Ramiro Polla -Windows Cygwin Victor Paesa -ADI/Blackfin DSP Marc Hoffman -Sparc Roman Shaposhnik -x86 Michael Niedermayer - - -GnuPG Fingerprints of maintainers and others who have svn write access -====================================================================== - -Attila Kinali 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765 -Baptiste Coudurier 8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA -Benoit Fouet B22A 4F4F 43EF 636B BB66 FCDC 0023 AE1E 2985 49C8 -Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7 -Diego Biurrun 8227 1E31 B6D9 4994 7427 E220 9CAE D6CC 4757 FCC5 -Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368 -Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE -Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB -Panagiotis Issaris 515C E262 10A8 FDCE 5481 7B9C 3AD7 D9A5 071D B3A9 -Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B -Reimar Döffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7 -Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4 -Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A -Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C diff --git a/tizen/distrib/ffmpeg/Makefile b/tizen/distrib/ffmpeg/Makefile deleted file mode 100644 index 18ab3a6..0000000 --- a/tizen/distrib/ffmpeg/Makefile +++ /dev/null @@ -1,353 +0,0 @@ -include config.mak - -SRC_DIR = $(SRC_PATH_BARE) - -vpath %.texi $(SRC_PATH_BARE) - -PROGS-$(CONFIG_FFMPEG) += ffmpeg -PROGS-$(CONFIG_FFPLAY) += ffplay -PROGS-$(CONFIG_FFPROBE) += ffprobe -PROGS-$(CONFIG_FFSERVER) += ffserver - -PROGS := $(addsuffix $(EXESUF), $(PROGS-yes)) -PROGS_G = $(addsuffix _g$(EXESUF), $(PROGS-yes)) -OBJS = $(addsuffix .o, $(PROGS-yes)) cmdutils.o -MANPAGES = $(addprefix doc/, $(addsuffix .1, $(PROGS-yes))) -TOOLS = $(addprefix tools/, $(addsuffix $(EXESUF), cws2fws pktdumper probetest qt-faststart trasher)) -HOSTPROGS = $(addprefix tests/, audiogen videogen rotozoom tiny_psnr) - -BASENAMES = ffmpeg ffplay ffprobe ffserver -ALLPROGS = $(addsuffix $(EXESUF), $(BASENAMES)) -ALLPROGS_G = $(addsuffix _g$(EXESUF), $(BASENAMES)) -ALLMANPAGES = $(addsuffix .1, $(BASENAMES)) - -FFLIBS-$(CONFIG_AVDEVICE) += avdevice -FFLIBS-$(CONFIG_AVFILTER) += avfilter -FFLIBS-$(CONFIG_AVFORMAT) += avformat -FFLIBS-$(CONFIG_AVCODEC) += avcodec -FFLIBS-$(CONFIG_POSTPROC) += postproc -FFLIBS-$(CONFIG_SWSCALE) += swscale - -FFLIBS := avutil - -DATA_FILES := $(wildcard $(SRC_DIR)/ffpresets/*.ffpreset) - -SKIPHEADERS = cmdutils_common_opts.h - -include common.mak - -FF_LDFLAGS := $(FFLDFLAGS) -FF_EXTRALIBS := $(FFEXTRALIBS) -FF_DEP_LIBS := $(DEP_LIBS) - -ALL_TARGETS-$(CONFIG_DOC) += documentation - -ifdef PROGS -INSTALL_TARGETS-yes += install-progs install-data -INSTALL_TARGETS-$(CONFIG_DOC) += install-man -endif -INSTALL_PROGS_TARGETS-$(CONFIG_SHARED) = install-libs - -all: $(FF_DEP_LIBS) $(PROGS) $(ALL_TARGETS-yes) - -$(PROGS): %$(EXESUF): %_g$(EXESUF) - $(CP) $< $@ - $(STRIP) $@ - -SUBDIR_VARS := OBJS FFLIBS CLEANFILES DIRS TESTPROGS EXAMPLES SKIPHEADERS \ - ALTIVEC-OBJS MMX-OBJS NEON-OBJS X86-OBJS YASM-OBJS-FFT YASM-OBJS \ - HOSTPROGS BUILT_HEADERS TESTOBJS ARCH_HEADERS - -define RESET -$(1) := -$(1)-yes := -endef - -define DOSUBDIR -$(foreach V,$(SUBDIR_VARS),$(eval $(call RESET,$(V)))) -SUBDIR := $(1)/ -include $(1)/Makefile -endef - -$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D)))) - -ffplay_g$(EXESUF): FF_EXTRALIBS += $(SDL_LIBS) -ffserver_g$(EXESUF): FF_LDFLAGS += $(FFSERVERLDFLAGS) - -%_g$(EXESUF): %.o cmdutils.o $(FF_DEP_LIBS) - $(LD) $(FF_LDFLAGS) -o $@ $< cmdutils.o $(FF_EXTRALIBS) - -tools/%$(EXESUF): tools/%.o - $(LD) $(FF_LDFLAGS) -o $@ $< $(FF_EXTRALIBS) - -tools/%.o: tools/%.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(CC_O) $< - -ffplay.o ffplay.d: CFLAGS += $(SDL_CFLAGS) - -VERSION_SH = $(SRC_PATH_BARE)/version.sh -GIT_LOG = $(SRC_PATH_BARE)/.git/logs/HEAD -SVN_ENTRIES = $(SRC_PATH_BARE)/.svn/entries - -.version: $(wildcard $(GIT_LOG) $(SVN_ENTRIES)) $(VERSION_SH) config.mak -.version: M=@ - -version.h .version: - $(M)$(VERSION_SH) $(SRC_PATH) version.h $(EXTRA_VERSION) - $(Q)touch .version - -# force version.sh to run whenever version might have changed --include .version - -alltools: $(TOOLS) - -documentation: $(addprefix doc/, developer.html faq.html ffmpeg-doc.html \ - ffplay-doc.html ffprobe-doc.html ffserver-doc.html \ - general.html libavfilter.html $(ALLMANPAGES)) - -doc/%.html: TAG = HTML -doc/%.html: doc/%.texi - $(M)cd doc && texi2html -monolithic -number $(<:doc/%=%) - -doc/%.pod: TAG = POD -doc/%.pod: doc/%-doc.texi - $(M)doc/texi2pod.pl $< $@ - -doc/%.1: TAG = MAN -doc/%.1: doc/%.pod - $(M)pod2man --section=1 --center=" " --release=" " $< > $@ - -install: $(INSTALL_TARGETS-yes) - -install-progs: $(PROGS) $(INSTALL_PROGS_TARGETS-yes) - $(Q)mkdir -p "$(BINDIR)" - $(INSTALL) -c -m 755 $(PROGS) "$(BINDIR)" - -install-data: $(DATA_FILES) - $(Q)mkdir -p "$(DATADIR)" - $(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)" - -install-man: $(MANPAGES) - $(Q)mkdir -p "$(MANDIR)/man1" - $(INSTALL) -m 644 $(MANPAGES) "$(MANDIR)/man1" - -uninstall: uninstall-progs uninstall-data uninstall-man - -uninstall-progs: - $(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS)) - -uninstall-data: - $(RM) -r "$(DATADIR)" - -uninstall-man: - $(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES)) - -testclean: - $(RM) -r tests/vsynth1 tests/vsynth2 tests/data - $(RM) $(addprefix tests/,$(CLEANSUFFIXES)) - $(RM) tests/seek_test$(EXESUF) tests/seek_test.o - $(RM) $(addprefix tests/,$(addsuffix $(HOSTEXESUF),audiogen videogen rotozoom tiny_psnr)) - -clean:: testclean - $(RM) $(ALLPROGS) $(ALLPROGS_G) - $(RM) $(CLEANSUFFIXES) - $(RM) doc/*.html doc/*.pod doc/*.1 - $(RM) $(TOOLS) - -distclean:: - $(RM) $(DISTCLEANSUFFIXES) - $(RM) version.h config.* libavutil/avconfig.h - -config: - $(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION) - -# regression tests - -check: test checkheaders - -fulltest test: codectest lavftest seektest - -FFSERVER_REFFILE = $(SRC_PATH)/tests/ffserver.regression.ref -SEEK_REFFILE = $(SRC_PATH)/tests/seek.regression.ref - -ENCDEC = $(and $(CONFIG_$(1)_ENCODER),$(CONFIG_$(1)_DECODER)) -MUXDEM = $(and $(CONFIG_$(1)_MUXER),$(CONFIG_$(or $(2),$(1))_DEMUXER)) - -VCODEC_TESTS = -VCODEC_TESTS-$(call ENCDEC,ASV1) += asv1 -VCODEC_TESTS-$(call ENCDEC,ASV2) += asv2 -VCODEC_TESTS-$(call ENCDEC,DNXHD) += dnxhd_1080i dnxhd_720p dnxhd_720p_rd -VCODEC_TESTS-$(call ENCDEC,DVVIDEO) += dv dv50 -VCODEC_TESTS-$(call ENCDEC,FFV1) += ffv1 -VCODEC_TESTS-$(call ENCDEC,FLASHSV) += flashsv -VCODEC_TESTS-$(call ENCDEC,FLV) += flv -VCODEC_TESTS-$(call ENCDEC,H261) += h261 -VCODEC_TESTS-$(call ENCDEC,H263) += h263 h263p -VCODEC_TESTS-$(call ENCDEC,HUFFYUV) += huffyuv -VCODEC_TESTS-$(call ENCDEC,JPEGLS) += jpegls -VCODEC_TESTS-$(call ENCDEC,MJPEG) += mjpeg ljpeg -VCODEC_TESTS-$(call ENCDEC,MPEG1VIDEO) += mpeg mpeg1b -VCODEC_TESTS-$(call ENCDEC,MPEG2VIDEO) += mpeg2 mpeg2thread -VCODEC_TESTS-$(call ENCDEC,MPEG4) += mpeg4 mpeg4adv mpeg4nr mpeg4thread error rc -VCODEC_TESTS-$(call ENCDEC,MSMPEG4V1) += msmpeg4 -VCODEC_TESTS-$(call ENCDEC,MSMPEG4V2) += msmpeg4v2 -VCODEC_TESTS-$(call ENCDEC,ROQ) += roq -VCODEC_TESTS-$(call ENCDEC,RV10) += rv10 -VCODEC_TESTS-$(call ENCDEC,RV20) += rv20 -VCODEC_TESTS-$(call ENCDEC,SNOW) += snow snowll -VCODEC_TESTS-$(call ENCDEC,SVQ1) += svq1 -VCODEC_TESTS-$(call ENCDEC,WMV1) += wmv1 -VCODEC_TESTS-$(call ENCDEC,WMV2) += wmv2 - -ACODEC_TESTS = -ACODEC_TESTS-$(call ENCDEC,AC3) += ac3 -ACODEC_TESTS-$(call ENCDEC,ADPCM_G726) += g726 -ACODEC_TESTS-$(call ENCDEC,ADPCM_IMA_QT) += adpcm_ima_qt -ACODEC_TESTS-$(call ENCDEC,ADPCM_IMA_WAV) += adpcm_ima_wav -ACODEC_TESTS-$(call ENCDEC,ADPCM_MS) += adpcm_ms -ACODEC_TESTS-$(call ENCDEC,ADPCM_SWF) += adpcm_swf -ACODEC_TESTS-$(call ENCDEC,ADPCM_YAMAHA) += adpcm_yam -ACODEC_TESTS-$(call ENCDEC,ALAC) += alac -ACODEC_TESTS-$(call ENCDEC,FLAC) += flac -ACODEC_TESTS-$(call ENCDEC,MP2) += mp2 -ACODEC_TESTS-$(call ENCDEC,PCM_S16LE) += pcm # fixme -ACODEC_TESTS-$(call ENCDEC,WMAV1) += wmav1 -ACODEC_TESTS-$(call ENCDEC,WMAV1) += wmav2 - -LAVF_TESTS = -LAVF_TESTS-$(call MUXDEM,AIFF) += aiff -LAVF_TESTS-$(call MUXDEM,PCM_ALAW) += alaw -LAVF_TESTS-$(call MUXDEM,ASF) += asf -LAVF_TESTS-$(call MUXDEM,AU) += au -LAVF_TESTS-$(call MUXDEM,AVI) += avi -LAVF_TESTS-$(call ENCDEC,BMP) += bmp -LAVF_TESTS-$(call MUXDEM,DV) += dv_fmt -LAVF_TESTS-$(call MUXDEM,FFM) += ffm -LAVF_TESTS-$(call MUXDEM,FLV) += flv_fmt -LAVF_TESTS-$(call ENCDEC,GIF) += gif -LAVF_TESTS-$(call MUXDEM,GXF) += gxf -LAVF_TESTS-$(call ENCDEC,MJPEG) += jpg -LAVF_TESTS-$(call MUXDEM,MATROSKA) += mkv -LAVF_TESTS-$(call MUXDEM,MMF) += mmf -LAVF_TESTS-$(call MUXDEM,MOV) += mov -LAVF_TESTS-$(call MUXDEM,MPEG1SYSTEM,MPEGPS) += mpg -LAVF_TESTS-$(call MUXDEM,PCM_MULAW) += mulaw -LAVF_TESTS-$(call MUXDEM,MXF) += mxf -LAVF_TESTS-$(call MUXDEM,NUT) += nut -LAVF_TESTS-$(call MUXDEM,OGG) += ogg -LAVF_TESTS-$(call ENCDEC,PBM) += pbmpipe -LAVF_TESTS-$(call ENCDEC,PCX) += pcx -LAVF_TESTS-$(call ENCDEC,PGM) += pgm pgmpipe -LAVF_TESTS-$(call MUXDEM,RAWVIDEO) += pixfmt -LAVF_TESTS-$(call ENCDEC,PPM) += ppm ppmpipe -LAVF_TESTS-$(call MUXDEM,RM) += rm -LAVF_TESTS-$(call ENCDEC,SGI) += sgi -LAVF_TESTS-$(call MUXDEM,SWF) += swf -LAVF_TESTS-$(call ENCDEC,TARGA) += tga -LAVF_TESTS-$(call ENCDEC,TIFF) += tiff -LAVF_TESTS-$(call MUXDEM,MPEGTS) += ts -LAVF_TESTS-$(call MUXDEM,VOC) += voc -LAVF_TESTS-$(call MUXDEM,WAV) += wav -LAVF_TESTS-$(call MUXDEM,YUV4MPEGPIPE) += yuv4mpeg - -LAVFI_TESTS = \ - crop \ - crop_scale \ - crop_scale_vflip \ - crop_vflip \ - null \ - scale200 \ - scale500 \ - vflip \ - vflip_crop \ - vflip_vflip \ - -ACODEC_TESTS := $(addprefix regtest-, $(ACODEC_TESTS) $(ACODEC_TESTS-yes)) -VCODEC_TESTS := $(addprefix regtest-, $(VCODEC_TESTS) $(VCODEC_TESTS-yes)) -LAVF_TESTS := $(addprefix regtest-, $(LAVF_TESTS) $(LAVF_TESTS-yes)) -LAVFI_TESTS := $(addprefix regtest-, $(LAVFI_TESTS) $(LAVFI_TESTS-yes)) - -CODEC_TESTS = $(VCODEC_TESTS) $(ACODEC_TESTS) - -codectest: $(CODEC_TESTS) -lavftest: $(LAVF_TESTS) -lavfitest: $(LAVFI_TESTS) - -$(ACODEC_TESTS): regtest-aref -$(VCODEC_TESTS): regtest-vref -$(LAVF_TESTS) $(LAVFI_TESTS): regtest-ref - -REFFILE = $(SRC_PATH)/tests/ref/$(1)/$(2:regtest-%=%) -RESFILE = tests/data/$(2:regtest-%=%).$(1).regression - -define CODECTEST_CMD - $(SRC_PATH)/tests/codec-regression.sh $@ vsynth1 tests/vsynth1 "$(TARGET_EXEC)" "$(TARGET_PATH)" - $(SRC_PATH)/tests/codec-regression.sh $@ vsynth2 tests/vsynth2 "$(TARGET_EXEC)" "$(TARGET_PATH)" -endef - -regtest-ref: regtest-aref regtest-vref - -regtest-vref: ffmpeg$(EXESUF) tests/vsynth1/00.pgm tests/vsynth2/00.pgm - $(CODECTEST_CMD) - -regtest-aref: ffmpeg$(EXESUF) tests/data/asynth1.sw - @$(SRC_PATH)/tests/codec-regression.sh $@ acodec tests/acodec "$(TARGET_EXEC)" "$(TARGET_PATH)" - -$(VCODEC_TESTS): tests/tiny_psnr$(HOSTEXESUF) - @echo "TEST VCODEC $(@:regtest-%=%)" - @$(CODECTEST_CMD) - @diff -u -w $(call REFFILE,vsynth1,$@) $(call RESFILE,vsynth1,$@) - @diff -u -w $(call REFFILE,vsynth2,$@) $(call RESFILE,vsynth2,$@) - -$(ACODEC_TESTS): tests/tiny_psnr$(HOSTEXESUF) - @echo "TEST ACODEC $(@:regtest-%=%)" - @$(SRC_PATH)/tests/codec-regression.sh $@ acodec tests/acodec "$(TARGET_EXEC)" "$(TARGET_PATH)" - @diff -u -w $(call REFFILE,acodec,$@) $(call RESFILE,acodec,$@) - -$(LAVF_TESTS): - @echo "TEST LAVF $(@:regtest-%=%)" - @$(SRC_PATH)/tests/lavf-regression.sh $@ lavf tests/vsynth1 "$(TARGET_EXEC)" "$(TARGET_PATH)" - @diff -u -w $(call REFFILE,lavf,$@) $(call RESFILE,lavf,$@) - -$(LAVFI_TESTS): - @echo "TEST LAVFI $(@:regtest-%=%)" - @$(SRC_PATH)/tests/lavfi-regression.sh $@ lavfi tests/vsynth1 "$(TARGET_EXEC)" "$(TARGET_PATH)" - @diff -u -w $(call REFFILE,lavfi,$@) $(call RESFILE,lavfi,$@) - -seektest: codectest lavftest tests/seek_test$(EXESUF) - $(SRC_PATH)/tests/seek-regression.sh $(SRC_PATH) "$(TARGET_EXEC)" "$(TARGET_PATH)" - -ffservertest: ffserver$(EXESUF) tests/vsynth1/00.pgm tests/data/asynth1.sw - @echo - @echo "Unfortunately ffserver is broken and therefore its regression" - @echo "test fails randomly. Treat the results accordingly." - @echo - $(SRC_PATH)/tests/ffserver-regression.sh $(FFSERVER_REFFILE) $(SRC_PATH)/tests/ffserver.conf - -tests/vsynth1/00.pgm: tests/videogen$(HOSTEXESUF) - mkdir -p tests/vsynth1 - $(BUILD_ROOT)/$< 'tests/vsynth1/' - -tests/vsynth2/00.pgm: tests/rotozoom$(HOSTEXESUF) - mkdir -p tests/vsynth2 - $(BUILD_ROOT)/$< 'tests/vsynth2/' $(SRC_PATH)/tests/lena.pnm - -tests/data/asynth1.sw: tests/audiogen$(HOSTEXESUF) - mkdir -p tests/data - $(BUILD_ROOT)/$< $@ - -tests/seek_test$(EXESUF): tests/seek_test.o $(FF_DEP_LIBS) - $(LD) $(FF_LDFLAGS) -o $@ $< $(FF_EXTRALIBS) - -ifdef SAMPLES -include $(SRC_PATH_BARE)/tests/fate.mak -fate: $(FATE_TESTS) -$(FATE_TESTS): ffmpeg$(EXESUF) - @echo "TEST FATE $(@:fate-%=%)" - @$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' -else -fate: - @echo "SAMPLES not specified, cannot run FATE" -endif - -.PHONY: documentation *test regtest-* zlib-error alltools check config diff --git a/tizen/distrib/ffmpeg/README b/tizen/distrib/ffmpeg/README deleted file mode 100644 index e907e90..0000000 --- a/tizen/distrib/ffmpeg/README +++ /dev/null @@ -1,12 +0,0 @@ -FFmpeg README -------------- - -1) Documentation ----------------- - -* Read the documentation in the doc/ directory. - -2) Licensing ------------- - -* See the LICENSE file. diff --git a/tizen/distrib/ffmpeg/RELEASE b/tizen/distrib/ffmpeg/RELEASE deleted file mode 100644 index c68e42a..0000000 --- a/tizen/distrib/ffmpeg/RELEASE +++ /dev/null @@ -1,96 +0,0 @@ -Release Notes -============= - -* 0.6 "Works with HTML5" June, 2010 - -General notes -------------- - -This release features a lot of improvements that are relevant for HTML5 video. -The H.264 and Theora decoders are now significantly faster, the vorbis decoder -has seen important updates and this release supports Google's newly released -libvpx library for the VP8 codec and WEBM container. - -Other important changes are additions of decoders including, but not limited to, -Intel Indeo 5, WMA Pro, WMA Voice and HE-AAC. - -See the Changelog file for a list of significant changes. - -Please note that our policy on bug reports has not changed. We still only accept -bug reports against HEAD of the FFmpeg trunk repository. If you are experiencing -any issues with any formally released version of FFmpeg, please try a current -version of the development code to check if the issue still exists. If it does, -make your report against the development code following the usual bug reporting -guidelines. - - -API and other notable Changes ------------------------------ - -Please see the file doc/APIchanges for programmer-centric information. - -Notable changes: -- deprecated vhook subsystem removed -- deprecated old scaler removed -- nonfree libamr support for AMR-NB/WB decoding/encoding removed -- RTMP support in libavformat -- -formats option split into -formats, -codecs, -bsfs, and -protocols -- ffprobe tool -- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp -- CODEC_CAP_EXPERIMENTAL added - - -Added Codecs: -------------- - -- VQF demuxer -- PCX encoder -- CorePNG decoding support -- 8088flex TMV demuxer and decoder -- enable symbol versioning by default for linkers that support it -- V210 decoder and encoder -- QCP demuxer -- SoX native format muxer and demuxer -- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries -- DPX image decoder -- Electronic Arts Madcow decoder -- DivX (XSUB) subtitle encoder -- experimental AAC encoder -- Wave64 demuxer -- IEC-61937 compatible Muxer -- TwinVQ decoder -- Bluray (PGS) subtitle decoder -- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks) -- WMA Pro decoder -- Core Audio Format demuxer -- Atrac1 decoder -- MD STUDIO audio demuxer -- RF64 support in WAV demuxer -- MPEG-4 Audio Lossless Coding (ALS) decoder -- IV8 demuxer -- CDG demuxer and decoder -- R210 decoder -- Auravision Aura 1 and 2 decoders -- Deluxe Paint Animation playback system -- SIPR decoder -- Adobe Filmstrip muxer and demuxer -- RTP packetization and depacketization of H.263 and AMR -- Bink demuxer and audio/video decoders -- IFF PBM/ILBM bitmap decoder -- Indeo 5 decoder -- WMA Voice decoder -- AMR-NB decoder -- RTSP muxer -- HE-AAC v1 decoder -- Kega Game Video (KGV1) decoder -- Psygnosis YOP demuxer and video decoder -- RTP hinting in the mov/3gp/mp4 muxer -- VP8 decoding via libvpx - - -Notable license related changes -------------------------------- - -- remaining GPL parts in AC-3 decoder converted to LGPL -- libswscale can now be compiled in LGPL mode -- libvpx is considered (L)GPL incompatible diff --git a/tizen/distrib/ffmpeg/VERSION b/tizen/distrib/ffmpeg/VERSION deleted file mode 100644 index 5a2a580..0000000 --- a/tizen/distrib/ffmpeg/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.6 diff --git a/tizen/distrib/ffmpeg/cmdutils.c b/tizen/distrib/ffmpeg/cmdutils.c deleted file mode 100644 index 2349b70..0000000 --- a/tizen/distrib/ffmpeg/cmdutils.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Various utilities for command line tools - * Copyright (c) 2000-2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -/* Include only the enabled headers since some compilers (namely, Sun - Studio) will not omit unused inline functions and create undefined - references to libraries that are not being built. */ - -#include "config.h" -#include "libavformat/avformat.h" -#include "libavfilter/avfilter.h" -#include "libavdevice/avdevice.h" -#include "libswscale/swscale.h" -#include "libpostproc/postprocess.h" -#include "libavutil/avstring.h" -#include "libavutil/pixdesc.h" -#include "libavcodec/opt.h" -#include "cmdutils.h" -#include "version.h" -#if CONFIG_NETWORK -#include "libavformat/network.h" -#endif -#if HAVE_SYS_RESOURCE_H -#include -#endif - -const char **opt_names; -static int opt_name_count; -AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; -AVFormatContext *avformat_opts; -struct SwsContext *sws_opts; - -const int this_year = 2010; - -double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max) -{ - char *tail; - const char *error; - double d = strtod(numstr, &tail); - if (*tail) - error= "Expected number for %s but found: %s\n"; - else if (d < min || d > max) - error= "The value for %s was %s which is not within %f - %f\n"; - else if(type == OPT_INT64 && (int64_t)d != d) - error= "Expected int64 for %s but found %s\n"; - else - return d; - fprintf(stderr, error, context, numstr, min, max); - exit(1); -} - -int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration) -{ - int64_t us = parse_date(timestr, is_duration); - if (us == INT64_MIN) { - fprintf(stderr, "Invalid %s specification for %s: %s\n", - is_duration ? "duration" : "date", context, timestr); - exit(1); - } - return us; -} - -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; - } - av_strlcpy(buf, po->name, sizeof(buf)); - if (po->flags & HAS_ARG) { - av_strlcat(buf, " ", sizeof(buf)); - av_strlcat(buf, po->argname, sizeof(buf)); - } - 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, - void (* parse_arg_function)(const char*)) -{ - const char *opt, *arg; - int optindex, handleoptions=1; - const OptionDef *po; - - /* parse options */ - optindex = 1; - while (optindex < argc) { - opt = argv[optindex++]; - - if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - int bool_val = 1; - if (opt[1] == '-' && opt[2] == '\0') { - handleoptions = 0; - continue; - } - opt++; - po= find_option(options, opt); - if (!po->name && opt[0] == 'n' && opt[1] == 'o') { - /* handle 'no' bool option */ - po = find_option(options, opt + 2); - if (!(po->name && (po->flags & OPT_BOOL))) - goto unknown_opt; - bool_val = 0; - } - 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 = bool_val; - } else if (po->flags & OPT_INT) { - *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); - } else if (po->flags & OPT_INT64) { - *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX); - } else if (po->flags & OPT_FLOAT) { - *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0); - } else if (po->flags & OPT_FUNC2) { - if (po->u.func2_arg(opt, arg) < 0) { - fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt); - exit(1); - } - } else { - po->u.func_arg(arg); - } - if(po->flags & OPT_EXIT) - exit(0); - } else { - if (parse_arg_function) - parse_arg_function(opt); - } - } -} - -int opt_default(const char *opt, const char *arg){ - int type; - int ret= 0; - const AVOption *o= NULL; - int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0}; - - for(type=0; type= 0; type++){ - const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]); - if(o2) - ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o); - } - if(!o) - ret = av_set_string3(avformat_opts, opt, arg, 1, &o); - if(!o && sws_opts) - ret = av_set_string3(sws_opts, opt, arg, 1, &o); - if(!o){ - if(opt[0] == 'a') - ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o); - else if(opt[0] == 'v') - ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o); - else if(opt[0] == 's') - ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o); - } - if (o && ret < 0) { - fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt); - exit(1); - } - if (!o) { - fprintf(stderr, "Unrecognized option '%s'\n", opt); - exit(1); - } - -// av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL)); - - //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this - opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1)); - opt_names[opt_name_count++]= o->name; - - if(avcodec_opts[0]->debug || avformat_opts->debug) - av_log_set_level(AV_LOG_DEBUG); - return 0; -} - -int opt_loglevel(const char *opt, const char *arg) -{ - const struct { const char *name; int level; } log_levels[] = { - { "quiet" , AV_LOG_QUIET }, - { "panic" , AV_LOG_PANIC }, - { "fatal" , AV_LOG_FATAL }, - { "error" , AV_LOG_ERROR }, - { "warning", AV_LOG_WARNING }, - { "info" , AV_LOG_INFO }, - { "verbose", AV_LOG_VERBOSE }, - { "debug" , AV_LOG_DEBUG }, - }; - char *tail; - int level; - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) { - if (!strcmp(log_levels[i].name, arg)) { - av_log_set_level(log_levels[i].level); - return 0; - } - } - - level = strtol(arg, &tail, 10); - if (*tail) { - fprintf(stderr, "Invalid loglevel \"%s\". " - "Possible levels are numbers or:\n", arg); - for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) - fprintf(stderr, "\"%s\"\n", log_levels[i].name); - exit(1); - } - av_log_set_level(level); - return 0; -} - -int opt_timelimit(const char *opt, const char *arg) -{ -#if HAVE_SETRLIMIT - int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); - struct rlimit rl = { lim, lim + 1 }; - if (setrlimit(RLIMIT_CPU, &rl)) - perror("setrlimit"); -#else - fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt); -#endif - return 0; -} - -void set_context_opts(void *ctx, void *opts_ctx, int flags) -{ - int i; - for(i=0; iflags & flags) == flags)) - av_set_string3(ctx, opt_names[i], str, 1, NULL); - } -} - -void print_error(const char *filename, int err) -{ - char errbuf[128]; - const char *errbuf_ptr = errbuf; - - if (av_strerror(err, errbuf, sizeof(errbuf)) < 0) - errbuf_ptr = strerror(AVUNERROR(err)); - fprintf(stderr, "%s: %s\n", filename, errbuf_ptr); -} - -#define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \ - if (CONFIG_##LIBNAME) { \ - unsigned int version = libname##_version(); \ - fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", \ - indent? " " : "", #libname, \ - LIB##LIBNAME##_VERSION_MAJOR, \ - LIB##LIBNAME##_VERSION_MINOR, \ - LIB##LIBNAME##_VERSION_MICRO, \ - version >> 16, version >> 8 & 0xff, version & 0xff); \ - } - -static void print_all_lib_versions(FILE* outstream, int indent) -{ - PRINT_LIB_VERSION(outstream, avutil, AVUTIL, indent); - PRINT_LIB_VERSION(outstream, avcodec, AVCODEC, indent); - PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent); - PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent); - PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent); - PRINT_LIB_VERSION(outstream, swscale, SWSCALE, indent); - PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent); -} - -static void maybe_print_config(const char *lib, const char *cfg) -{ - static int warned_cfg; - - if (strcmp(FFMPEG_CONFIGURATION, cfg)) { - if (!warned_cfg) { - fprintf(stderr, " WARNING: library configuration mismatch\n"); - warned_cfg = 1; - } - fprintf(stderr, " %-11s configuration: %s\n", lib, cfg); - } -} - -#define PRINT_LIB_CONFIG(lib, tag, cfg) do { \ - if (CONFIG_##lib) \ - maybe_print_config(tag, cfg); \ - } while (0) - -void show_banner(void) -{ - fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n", - program_name, program_birth_year, this_year); - fprintf(stderr, " built on %s %s with %s %s\n", - __DATE__, __TIME__, CC_TYPE, CC_VERSION); - fprintf(stderr, " configuration: " FFMPEG_CONFIGURATION "\n"); - PRINT_LIB_CONFIG(AVUTIL, "libavutil", avutil_configuration()); - PRINT_LIB_CONFIG(AVCODEC, "libavcodec", avcodec_configuration()); - PRINT_LIB_CONFIG(AVFORMAT, "libavformat", avformat_configuration()); - PRINT_LIB_CONFIG(AVDEVICE, "libavdevice", avdevice_configuration()); - PRINT_LIB_CONFIG(AVFILTER, "libavfilter", avfilter_configuration()); - PRINT_LIB_CONFIG(SWSCALE, "libswscale", swscale_configuration()); - PRINT_LIB_CONFIG(POSTPROC, "libpostproc", postproc_configuration()); - print_all_lib_versions(stderr, 1); -} - -void show_version(void) { - printf("%s " FFMPEG_VERSION "\n", program_name); - print_all_lib_versions(stdout, 0); -} - -void show_license(void) -{ - printf( -#if CONFIG_NONFREE - "This version of %s has nonfree parts compiled in.\n" - "Therefore it is not legally redistributable.\n", - program_name -#elif CONFIG_GPLV3 - "%s 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 3 of the License, or\n" - "(at your option) any later version.\n" - "\n" - "%s 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 %s. If not, see .\n", - program_name, program_name, program_name -#elif CONFIG_GPL - "%s 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" - "%s 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 %s; if not, write to the Free Software\n" - "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n", - program_name, program_name, program_name -#elif CONFIG_LGPLV3 - "%s is free software; you can redistribute it and/or modify\n" - "it under the terms of the GNU Lesser General Public License as published by\n" - "the Free Software Foundation; either version 3 of the License, or\n" - "(at your option) any later version.\n" - "\n" - "%s 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 Lesser General Public License for more details.\n" - "\n" - "You should have received a copy of the GNU Lesser General Public License\n" - "along with %s. If not, see .\n", - program_name, program_name, program_name -#else - "%s 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.1 of the License, or (at your option) any later version.\n" - "\n" - "%s 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 %s; if not, write to the Free Software\n" - "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n", - program_name, program_name, program_name -#endif - ); -} - -void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts) -{ - int i; - char fmt_str[128]; - for (i=-1; i < nb_fmts; i++) { - get_fmt_string (fmt_str, sizeof(fmt_str), i); - fprintf(stdout, "%s\n", fmt_str); - } -} - -void show_formats(void) -{ - AVInputFormat *ifmt=NULL; - AVOutputFormat *ofmt=NULL; - const char *last_name; - - printf( - "File formats:\n" - " D. = Demuxing supported\n" - " .E = Muxing supported\n" - " --\n"); - last_name= "000"; - for(;;){ - int decode=0; - int encode=0; - const char *name=NULL; - const char *long_name=NULL; - - while((ofmt= av_oformat_next(ofmt))) { - if((name == NULL || strcmp(ofmt->name, name)<0) && - strcmp(ofmt->name, last_name)>0){ - name= ofmt->name; - long_name= ofmt->long_name; - encode=1; - } - } - while((ifmt= av_iformat_next(ifmt))) { - 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:" "); - } -} - -void show_codecs(void) -{ - AVCodec *p=NULL, *p2; - const char *last_name; - printf( - "Codecs:\n" - " D..... = Decoding supported\n" - " .E.... = Encoding supported\n" - " ..V... = Video codec\n" - " ..A... = Audio codec\n" - " ..S... = Subtitle codec\n" - " ...S.. = Supports draw_horiz_band\n" - " ....D. = Supports direct rendering method 1\n" - " .....T = Supports weird frame truncation\n" - " ------\n"); - last_name= "000"; - for(;;){ - int decode=0; - int encode=0; - int cap=0; - const char *type_str; - - p2=NULL; - while((p= av_codec_next(p))) { - 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 AVMEDIA_TYPE_VIDEO: - type_str = "V"; - break; - case AVMEDIA_TYPE_AUDIO: - type_str = "A"; - break; - case AVMEDIA_TYPE_SUBTITLE: - type_str = "S"; - break; - default: - type_str = "?"; - break; - } - printf( - " %s%s%s%s%s%s %-15s %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, - p2->long_name ? p2->long_name : ""); - /* if(p2->decoder && decode==0) - printf(" use %s for decoding", p2->decoder->name);*/ - printf("\n"); - } - printf("\n"); - printf( -"Note, the names of encoders and decoders do not 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 it is even\n" -"worse.\n"); -} - -void show_bsfs(void) -{ - AVBitStreamFilter *bsf=NULL; - - printf("Bitstream filters:\n"); - while((bsf = av_bitstream_filter_next(bsf))) - printf("%s\n", bsf->name); - printf("\n"); -} - -void show_protocols(void) -{ - URLProtocol *up=NULL; - - printf("Supported file protocols:\n"); - while((up = av_protocol_next(up))) - printf("%s\n", up->name); -} - -void show_filters(void) -{ - AVFilter av_unused(**filter) = NULL; - - printf("Filters:\n"); -#if CONFIG_AVFILTER - while ((filter = av_filter_next(filter)) && *filter) - printf("%-16s %s\n", (*filter)->name, (*filter)->description); -#endif -} - -void show_pix_fmts(void) -{ - enum PixelFormat pix_fmt; - - printf( - "Pixel formats:\n" - "I.... = Supported Input format for conversion\n" - ".O... = Supported Output format for conversion\n" - "..H.. = Hardware accelerated format\n" - "...P. = Paletted format\n" - "....B = Bitstream format\n" - "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n" - "-----\n"); - -#if !CONFIG_SWSCALE -# define sws_isSupportedInput(x) 0 -# define sws_isSupportedOutput(x) 0 -#endif - - for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) { - const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt]; - printf("%c%c%c%c%c %-16s %d %2d\n", - sws_isSupportedInput (pix_fmt) ? 'I' : '.', - sws_isSupportedOutput(pix_fmt) ? 'O' : '.', - pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.', - pix_desc->flags & PIX_FMT_PAL ? 'P' : '.', - pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.', - pix_desc->name, - pix_desc->nb_components, - av_get_bits_per_pixel(pix_desc)); - } -} - -int read_yesno(void) -{ - int c = getchar(); - int yesno = (toupper(c) == 'Y'); - - while (c != '\n' && c != EOF) - c = getchar(); - - return yesno; -} - -int read_file(const char *filename, char **bufptr, size_t *size) -{ - FILE *f = fopen(filename, "rb"); - - if (!f) { - fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno)); - return AVERROR(errno); - } - fseek(f, 0, SEEK_END); - *size = ftell(f); - fseek(f, 0, SEEK_SET); - *bufptr = av_malloc(*size + 1); - if (!*bufptr) { - fprintf(stderr, "Could not allocate file buffer\n"); - fclose(f); - return AVERROR(ENOMEM); - } - fread(*bufptr, 1, *size, f); - (*bufptr)[*size++] = '\0'; - - fclose(f); - return 0; -} diff --git a/tizen/distrib/ffmpeg/cmdutils.h b/tizen/distrib/ffmpeg/cmdutils.h deleted file mode 100644 index 5656370..0000000 --- a/tizen/distrib/ffmpeg/cmdutils.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Various utilities for command line tools - * copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef FFMPEG_CMDUTILS_H -#define FFMPEG_CMDUTILS_H - -#include -#include "libavcodec/avcodec.h" -#include "libavformat/avformat.h" -#include "libswscale/swscale.h" - -/** - * program name, defined by the program for show_version(). - */ -extern const char program_name[]; - -/** - * program birth year, defined by the program for show_banner() - */ -extern const int program_birth_year; - -extern const int this_year; - -extern const char **opt_names; -extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; -extern AVFormatContext *avformat_opts; -extern struct SwsContext *sws_opts; - -/** - * Fallback for options that are not explicitly handled, these will be - * parsed through AVOptions. - */ -int opt_default(const char *opt, const char *arg); - -/** - * Sets the libav* libraries log level. - */ -int opt_loglevel(const char *opt, const char *arg); - -/** - * Limit the execution time. - */ -int opt_timelimit(const char *opt, const char *arg); - -/** - * Parses a string and returns its corresponding value as a double. - * Exits from the application if the string cannot be correctly - * parsed or the corresponding value is invalid. - * - * @param context the context of the value to be set (e.g. the - * corresponding commandline option name) - * @param numstr the string to be parsed - * @param type the type (OPT_INT64 or OPT_FLOAT) as which the - * string should be parsed - * @param min the minimum valid accepted value - * @param max the maximum valid accepted value - */ -double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max); - -/** - * Parses a string specifying a time and returns its corresponding - * value as a number of microseconds. Exits from the application if - * the string cannot be correctly parsed. - * - * @param context the context of the value to be set (e.g. the - * corresponding commandline option name) - * @param timestr the string to be parsed - * @param is_duration a flag which tells how to interpret timestr, if - * not zero timestr is interpreted as a duration, otherwise as a - * date - * - * @see parse_date() - */ -int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration); - -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 -#define OPT_INT64 0x0800 -#define OPT_EXIT 0x1000 - 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 *); - int64_t *int64_arg; - } u; - const char *help; - const char *argname; -} OptionDef; - -void show_help_options(const OptionDef *options, const char *msg, int mask, int value); - -/** - * Parses the command line arguments. - * @param options Array with the definitions required to interpret every - * option of the form: - [] - * @param parse_arg_function Name of the function called to process every - * argument without a leading option name flag. NULL if such arguments do - * not have to be processed. - */ -void parse_options(int argc, char **argv, const OptionDef *options, - void (* parse_arg_function)(const char*)); - -void set_context_opts(void *ctx, void *opts_ctx, int flags); - -/** - * Prints an error message to stderr, indicating filename and a human - * readable description of the error code err. - * - * If strerror_r() is not available the use of this function in a - * multithreaded application may be unsafe. - * - * @see av_strerror() - */ -void print_error(const char *filename, int err); - -void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts); - -/** - * Prints the program banner to stderr. The banner contents depend on the - * current version of the repository and of the libav* libraries used by - * the program. - */ -void show_banner(void); - -/** - * Prints the version of the program to stdout. The version message - * depends on the current versions of the repository and of the libav* - * libraries. - */ -void show_version(void); - -/** - * Prints the license of the program to stdout. The license depends on - * the license of the libraries compiled into the program. - */ -void show_license(void); - -/** - * Prints a listing containing all the formats supported by the - * program. - */ -void show_formats(void); - -/** - * Prints a listing containing all the codecs supported by the - * program. - */ -void show_codecs(void); - -/** - * Prints a listing containing all the filters supported by the - * program. - */ -void show_filters(void); - -/** - * Prints a listing containing all the bit stream filters supported by the - * program. - */ -void show_bsfs(void); - -/** - * Prints a listing containing all the protocols supported by the - * program. - */ -void show_protocols(void); - -/** - * Prints a listing containing all the pixel formats supported by the - * program. - */ -void show_pix_fmts(void); - -/** - * Returns a positive value if reads from standard input a line - * starting with [yY], otherwise returns 0. - */ -int read_yesno(void); - -/** - * Reads the file with name filename, and puts its content in a newly - * allocated 0-terminated buffer. - * - * @param bufptr puts here the pointer to the newly allocated buffer - * @param size puts here the size of the newly allocated buffer - * @return 0 in case of success, a negative value corresponding to an - * AVERROR error code in case of failure. - */ -int read_file(const char *filename, char **bufptr, size_t *size); - -#endif /* FFMPEG_CMDUTILS_H */ diff --git a/tizen/distrib/ffmpeg/cmdutils_common_opts.h b/tizen/distrib/ffmpeg/cmdutils_common_opts.h deleted file mode 100644 index da30997..0000000 --- a/tizen/distrib/ffmpeg/cmdutils_common_opts.h +++ /dev/null @@ -1,13 +0,0 @@ - { "L", OPT_EXIT, {(void*)show_license}, "show license" }, - { "h", OPT_EXIT, {(void*)show_help}, "show help" }, - { "?", OPT_EXIT, {(void*)show_help}, "show help" }, - { "help", OPT_EXIT, {(void*)show_help}, "show help" }, - { "-help", OPT_EXIT, {(void*)show_help}, "show help" }, - { "version", OPT_EXIT, {(void*)show_version}, "show version" }, - { "formats" , OPT_EXIT, {(void*)show_formats }, "show available formats" }, - { "codecs" , OPT_EXIT, {(void*)show_codecs }, "show available codecs" }, - { "bsfs" , OPT_EXIT, {(void*)show_bsfs }, "show available bit stream filters" }, - { "protocols", OPT_EXIT, {(void*)show_protocols}, "show available protocols" }, - { "filters", OPT_EXIT, {(void*)show_filters }, "show available filters" }, - { "pix_fmts" , OPT_EXIT, {(void*)show_pix_fmts }, "show available pixel formats" }, - { "loglevel", HAS_ARG | OPT_FUNC2, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" }, diff --git a/tizen/distrib/ffmpeg/common.mak b/tizen/distrib/ffmpeg/common.mak deleted file mode 100644 index 25a5d81..0000000 --- a/tizen/distrib/ffmpeg/common.mak +++ /dev/null @@ -1,109 +0,0 @@ -# -# common bits used by all libraries -# - -# first so "all" becomes default target -all: all-yes - -ifndef SUBDIR -vpath %.c $(SRC_DIR) -vpath %.h $(SRC_DIR) -vpath %.S $(SRC_DIR) -vpath %.asm $(SRC_DIR) -vpath %.v $(SRC_DIR) - -ifeq ($(SRC_DIR),$(SRC_PATH_BARE)) -BUILD_ROOT_REL = . -else -BUILD_ROOT_REL = .. -endif - -ifndef V -Q = @ -ECHO = printf "$(1)\t%s\n" $(2) -BRIEF = CC AS YASM AR LD HOSTCC STRIP CP -SILENT = DEPCC YASMDEP RM RANLIB -MSG = $@ -M = @$(call ECHO,$(TAG),$@); -$(foreach VAR,$(BRIEF), \ - $(eval $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR)))) -$(foreach VAR,$(SILENT),$(eval $(VAR) = @$($(VAR)))) -$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL)) -endif - -ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale - -CPPFLAGS := -I$(BUILD_ROOT_REL) -I$(SRC_PATH) $(CPPFLAGS) -CFLAGS += $(ECFLAGS) - -%.o: %.c - $(CCDEP) - $(CC) $(CPPFLAGS) $(CFLAGS) $(CC_DEPFLAGS) -c $(CC_O) $< - -%.o: %.S - $(ASDEP) - $(AS) $(CPPFLAGS) $(ASFLAGS) $(AS_DEPFLAGS) -c -o $@ $< - -%.ho: %.h - $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused -c -o $@ -x c $< - -%$(EXESUF): %.c - -%.ver: %.v - $(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@ - -%.c %.h: TAG = GEN - -install: install-libs install-headers -install-libs: install-libs-yes - -uninstall: uninstall-libs uninstall-headers - -.PHONY: all depend dep *clean install* uninstall* examples testprogs - -# Disable suffix rules. Most of the builtin rules are suffix rules, -# so this saves some time on slow systems. -.SUFFIXES: - -# Do not delete intermediate files from chains of implicit rules -$(OBJS): -endif - -OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes) - -CFLAGS += $(CFLAGS-yes) -OBJS += $(OBJS-yes) -FFLIBS := $(FFLIBS-yes) $(FFLIBS) -TESTPROGS += $(TESTPROGS-yes) - -FFEXTRALIBS := $(addprefix -l,$(addsuffix $(BUILDSUF),$(FFLIBS))) $(EXTRALIBS) -FFLDFLAGS := $(addprefix -L$(BUILD_ROOT)/lib,$(ALLFFLIBS)) $(LDFLAGS) - -EXAMPLES := $(addprefix $(SUBDIR),$(addsuffix -example$(EXESUF),$(EXAMPLES))) -OBJS := $(addprefix $(SUBDIR),$(sort $(OBJS))) -TESTOBJS := $(addprefix $(SUBDIR),$(TESTOBJS)) -TESTPROGS := $(addprefix $(SUBDIR),$(addsuffix -test$(EXESUF),$(TESTPROGS))) -HOSTOBJS := $(addprefix $(SUBDIR),$(addsuffix .o,$(HOSTPROGS))) -HOSTPROGS := $(addprefix $(SUBDIR),$(addsuffix $(HOSTEXESUF),$(HOSTPROGS))) - -DEP_LIBS := $(foreach NAME,$(FFLIBS),$(BUILD_ROOT_REL)/lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME)) - -ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h)) -SKIPHEADERS += $(addprefix $(ARCH)/,$(ARCH_HEADERS)) -SKIPHEADERS := $(addprefix $(SUBDIR),$(SKIPHEADERS-) $(SKIPHEADERS)) -checkheaders: $(filter-out $(SKIPHEADERS:.h=.ho),$(ALLHEADERS:.h=.ho)) - -$(HOSTOBJS): %.o: %.c - $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $< - -$(HOSTPROGS): %$(HOSTEXESUF): %.o - $(HOSTCC) $(HOSTLDFLAGS) -o $@ $< $(HOSTLIBS) - -DEPS := $(OBJS:.o=.d) -depend dep: $(DEPS) - -CLEANSUFFIXES = *.d *.o *~ *.ho *.map *.ver -DISTCLEANSUFFIXES = *.pc -LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a *.exp - --include $(wildcard $(DEPS)) diff --git a/tizen/distrib/ffmpeg/configure b/tizen/distrib/ffmpeg/configure deleted file mode 100755 index 0166829..0000000 --- a/tizen/distrib/ffmpeg/configure +++ /dev/null @@ -1,3172 +0,0 @@ -#!/bin/sh -# -# FFmpeg configure script -# -# Copyright (c) 2000-2002 Fabrice Bellard -# Copyright (c) 2005-2008 Diego Biurrun -# Copyright (c) 2005-2008 Mans Rullgard -# - -# Prevent locale nonsense from breaking basic text processing. -LC_ALL=C -export LC_ALL - -# make sure we are running under a compatible shell -# try to make this part work with most shells - -try_exec(){ - echo "Trying shell $1" - type "$1" > /dev/null 2>&1 && exec "$@" -} - -unset foo -(: ${foo%%bar}) 2> /dev/null -E1="$?" - -(: ${foo?}) 2> /dev/null -E2="$?" - -if test "$E1" != 0 || test "$E2" = 0; then - echo "Broken shell detected. Trying alternatives." - export FF_CONF_EXEC - if test "0$FF_CONF_EXEC" -lt 1; then - FF_CONF_EXEC=1 - try_exec bash "$0" "$@" - fi - if test "0$FF_CONF_EXEC" -lt 2; then - FF_CONF_EXEC=2 - try_exec ksh "$0" "$@" - fi - if test "0$FF_CONF_EXEC" -lt 3; then - FF_CONF_EXEC=3 - try_exec /usr/xpg4/bin/sh "$0" "$@" - fi - echo "No compatible shell script interpreter found." - echo "This configure script requires a POSIX-compatible shell" - echo "such as bash or ksh." - echo "THIS IS NOT A BUG IN FFMPEG, DO NOT REPORT IT AS SUCH." - echo "Instead, install a working POSIX-compatible shell." - echo "Disabling this configure test will create a broken FFmpeg." - if test "$BASH_VERSION" = '2.04.0(1)-release'; then - echo "This bash version ($BASH_VERSION) is broken on your platform." - echo "Upgrade to a later version if available." - fi - exit 1 -fi - -show_help(){ -cat <> $logfile -} - -log_file(){ - log BEGIN $1 - pr -n -t $1 >> $logfile - log END $1 -} - -echolog(){ - log "$@" - echo "$@" -} - -die(){ - echolog "$@" - cat <> $header - echo "${pfx}${ucname}=yes" >> $makefile - else - echo "#define ${pfx}${ucname} 0" >> $header - echo "!${pfx}${ucname}=yes" >> $makefile - fi - done -} - -flags_saved(){ - (: ${SAVE_CFLAGS?}) 2> /dev/null -} - -save_flags(){ - flags_saved && return - SAVE_CFLAGS="$CFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - SAVE_extralibs="$extralibs" -} - -restore_flags(){ - flags_saved || return - CFLAGS="$SAVE_CFLAGS" - LDFLAGS="$SAVE_LDFLAGS" - extralibs="$SAVE_extralibs" - unset SAVE_CFLAGS - unset SAVE_LDFLAGS - unset SAVE_extralibs -} - -temp_cflags(){ - save_flags - CFLAGS="$CFLAGS $*" -} - -temp_ldflags(){ - save_flags - LDFLAGS="$LDFLAGS $*" -} - -temp_extralibs(){ - save_flags - extralibs="$extralibs $*" -} - -append(){ - var=$1 - shift - flags_saved && eval "SAVE_$var=\"\$SAVE_$var $*\"" - eval "$var=\"\$$var $*\"" -} - -add_cppflags(){ - append CPPFLAGS $($filter_cppflags "$@") -} - -add_cflags(){ - append CFLAGS $($filter_cflags "$@") -} - -add_asflags(){ - append ASFLAGS $($filter_asflags "$@") -} - -add_ldflags(){ - append LDFLAGS "$@" -} - -add_extralibs(){ - append extralibs "$@" -} - -check_cmd(){ - log "$@" - "$@" >> $logfile 2>&1 -} - -check_cc(){ - log check_cc "$@" - cat > $TMPC - log_file $TMPC - check_cmd $cc $CPPFLAGS $CFLAGS "$@" -c -o $TMPO $TMPC -} - -check_cpp(){ - log check_cpp "$@" - cat > $TMPC - log_file $TMPC - check_cmd $cc $CPPFLAGS $CFLAGS "$@" -E -o $TMPO $TMPC -} - -check_as(){ - log check_as "$@" - cat > $TMPC - log_file $TMPC - check_cmd $as $CPPFLAGS $ASFLAGS "$@" -c -o $TMPO $TMPC -} - -check_asm(){ - log check_asm "$@" - name="$1" - code="$2" - shift 2 - disable $name - check_as "$@" < $TMPS - log_file $TMPS - shift 1 - check_cmd $yasmexe $YASMFLAGS "$@" -o $TMPO $TMPS -} - -check_ld(){ - log check_ld "$@" - flags='' - libs='' - for f; do - test "${f}" = "${f#-l}" && flags="$flags $f" || libs="$libs $f" - done - check_cc $($filter_cflags $flags) || return - check_cmd $ld $LDFLAGS $flags -o $TMPE $TMPO $extralibs $libs -} - -check_cppflags(){ - log check_cppflags "$@" - set -- $($filter_cppflags "$@") - check_cc "$@" < -int x; -EOF -} - -check_func(){ - log check_func "$@" - func=$1 - shift - disable $func - check_ld "$@" < -float foo(float f) { return $func(f); } -int main(void){ return 0; } -EOF -} - -check_func_headers(){ - log check_func_headers "$@" - headers=$1 - func=$2 - shift 2 - disable $func - incs="" - for hdr in $headers; do - incs="$incs -#include <$hdr>" - done - check_ld "$@" < -#if !($condition) -#error "unsatisfied condition: $condition" -#endif -EOF -} - -check_lib(){ - log check_lib "$@" - header="$1" - func="$2" - shift 2 - temp_extralibs "$@" - check_header $header && check_func $func && add_extralibs "$@" - err=$? - restore_flags - return $err -} - -check_lib2(){ - log check_lib2 "$@" - headers="$1" - func="$2" - shift 2 - check_func_headers "$headers" $func "$@" && add_extralibs "$@" -} - -check_exec(){ - check_ld "$@" && { enabled cross_compile || $TMPE >> $logfile 2>&1; } -} - -check_exec_crash(){ - code=$(cat) - - # exit() is not async signal safe. _Exit (C99) and _exit (POSIX) - # are safe but may not be available everywhere. Thus we use - # raise(SIGTERM) instead. The check is run in a subshell so we - # can redirect the "Terminated" message from the shell. SIGBUS - # is not defined by standard C so it is used conditionally. - - (check_exec "$@") >> $logfile 2>&1 < -static void sighandler(int sig){ - raise(SIGTERM); -} -int main(void){ - signal(SIGILL, sighandler); - signal(SIGFPE, sighandler); - signal(SIGSEGV, sighandler); -#ifdef SIGBUS - signal(SIGBUS, sighandler); -#endif - { $code } -} -EOF -} - -check_type(){ - log check_type "$@" - headers=$1 - type=$2 - shift 2 - disable_safe "$type" - incs="" - for hdr in $headers; do - incs="$incs -#include <$hdr>" - done - check_cc "$@" <$member; -EOF -} - -require(){ - name="$1" - header="$2" - func="$3" - shift 3 - check_lib $header $func "$@" || die "ERROR: $name not found" -} - -require2(){ - name="$1" - headers="$2" - func="$3" - shift 3 - check_lib2 "$headers" $func "$@" || die "ERROR: $name not found" -} - -check_foo_config(){ - cfg=$1 - pkg=$2 - header=$3 - func=$4 - shift 4 - disable $cfg - check_cmd ${pkg}-config --version - err=$? - if test "$err" = 0; then - temp_cflags $(${pkg}-config --cflags) - temp_extralibs $(${pkg}-config --libs) - check_lib "$@" $header $func && enable $cfg - fi - return $err -} - -check_host_cc(){ - log check_host_cc "$@" - cat > $TMPC - log_file $TMPC - check_cmd $host_cc $host_cflags "$@" -c -o $TMPO $TMPC -} - -check_host_cflags(){ - log check_host_cflags "$@" - check_host_cc "$@" < "$file.tmp" && mv "$file.tmp" "$file" || rm "$file.tmp" -} - -cp_if_changed(){ - cmp -s "$1" "$2" && - echo "$2 is unchanged" || - cp -f "$1" "$2" -} - -# CONFIG_LIST contains configurable options, while HAVE_LIST is for -# system-dependent things. - -COMPONENT_LIST=" - bsfs - decoders - demuxers - encoders - filters - hwaccels - indevs - muxers - outdevs - parsers - protocols -" - -CONFIG_LIST=" - $COMPONENT_LIST - aandct - avcodec - avdevice - avfilter - avfilter_lavf - avformat - avisynth - beos_netserver - bzlib - dct - doc - dwt - dxva2 - fastdiv - ffmpeg - ffplay - ffprobe - ffserver - fft - golomb - gpl - gprof - gray - h264dsp - hardcoded_tables - libdc1394 - libdirac - libfaac - libfaad - libfaadbin - libgsm - libmp3lame - libnut - libopencore_amrnb - libopencore_amrwb - libopenjpeg - librtmp - libschroedinger - libspeex - libtheora - libvorbis - libvpx - libx264 - libxvid - lpc - lsp - mdct - memalign_hack - mlib - mpegaudio_hp - network - nonfree - pic - postproc - powerpc_perf - rdft - runtime_cpudetect - shared - small - sram - static - swscale - swscale_alpha - vaapi - vdpau - version3 - x11grab - zlib -" - -THREADS_LIST=' - beosthreads - os2threads - pthreads - w32threads -' - -ARCH_LIST=' - alpha - arm - avr32 - avr32_ap - avr32_uc - bfin - ia64 - m68k - mips - mips64 - parisc - ppc - ppc64 - s390 - sh4 - sparc - sparc64 - tomi - x86 - x86_32 - x86_64 -' - -ARCH_EXT_LIST=' - altivec - amd3dnow - amd3dnowext - armv5te - armv6 - armv6t2 - armvfp - iwmmxt - mmi - mmx - mmx2 - neon - ppc4xx - sse - ssse3 - vis -' - -HAVE_LIST_PUB=' - bigendian -' - -HAVE_LIST=" - $ARCH_EXT_LIST - $HAVE_LIST_PUB - $THREADS_LIST - alsa_asoundlib_h - altivec_h - arpa_inet_h - attribute_may_alias - attribute_packed - bswap - closesocket - cmov - conio_h - dcbzl - dev_bktr_ioctl_bt848_h - dev_bktr_ioctl_meteor_h - dev_ic_bt8xx_h - dev_video_meteor_ioctl_meteor_h - dev_video_bktr_ioctl_bt848_h - dlfcn_h - dlopen - dos_paths - ebp_available - ebx_available - exp2 - exp2f - fast_64bit - fast_clz - fast_cmov - fast_unaligned - fork - getaddrinfo - gethrtime - GetProcessMemoryInfo - GetProcessTimes - getrusage - struct_rusage_ru_maxrss - inet_aton - inline_asm - isatty - ldbrx - libdc1394_1 - libdc1394_2 - llrint - llrintf - local_aligned_16 - local_aligned_8 - log2 - log2f - loongson - lrint - lrintf - lzo1x_999_compress - machine_ioctl_bt848_h - machine_ioctl_meteor_h - malloc_h - memalign - mkstemp - pld - posix_memalign - round - roundf - sdl - sdl_video_size - setmode - socklen_t - soundcard_h - poll_h - setrlimit - strerror_r - struct_addrinfo - struct_ipv6_mreq - struct_sockaddr_in6 - struct_sockaddr_sa_len - struct_sockaddr_storage - symver - symver_gnu_asm - symver_asm_label - sys_mman_h - sys_resource_h - sys_select_h - sys_soundcard_h - sys_videoio_h - ten_operands - termios_h - threads - truncf - vfp_args - VirtualAlloc - winsock2_h - xform_asm - yasm -" - -# options emitted with CONFIG_ prefix but not available on command line -CONFIG_EXTRA=" - avutil - gplv3 - lgplv3 -" - -CMDLINE_SELECT=" - $ARCH_EXT_LIST - $CONFIG_LIST - $THREADS_LIST - asm - cross_compile - debug - extra_warnings - logging - optimizations - stripping - yasm -" - -PATHS_LIST=' - bindir - datadir - incdir - libdir - mandir - prefix - shlibdir -' - -CMDLINE_SET=" - $PATHS_LIST - ar - arch - as - build_suffix - cc - cpu - cross_prefix - dep_cc - extra_version - host_cc - host_cflags - host_ldflags - host_libs - host_os - ld - logfile - malloc_prefix - nm - samples - source_path - strip - sysinclude - sysroot - target_exec - target_os - target_path -" - -CMDLINE_APPEND=" - extra_cflags -" - -# code dependency declarations - -# architecture extensions - -armv5te_deps="arm" -armv6_deps="arm" -armv6t2_deps="arm" -armvfp_deps="arm" -iwmmxt_deps="arm" -neon_deps="arm" - -mmi_deps="mips" - -altivec_deps="ppc" -ppc4xx_deps="ppc" - -vis_deps="sparc" - -x86_64_suggest="cmov fast_cmov" -amd3dnow_deps="mmx" -amd3dnowext_deps="amd3dnow" -mmx_deps="x86" -mmx2_deps="mmx" -sse_deps="mmx" -ssse3_deps="sse" - -fast_64bit_if_any="alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64" -fast_clz_if_any="alpha armv5te avr32 mips ppc x86" -fast_unaligned_if_any="armv6 ppc x86" - -need_memalign="altivec neon sse" -inline_asm_deps="!tms470" - -symver_if_any="symver_asm_label symver_gnu_asm" - -# subsystems -mdct_select="fft" -rdft_select="fft" - -# decoders / encoders / hardware accelerators -aac_decoder_select="mdct rdft aac_parser" -aac_encoder_select="mdct" -ac3_decoder_select="mdct ac3_parser" -alac_encoder_select="lpc" -amrnb_decoder_select="lsp" -atrac1_decoder_select="mdct" -atrac3_decoder_select="mdct" -binkaudio_dct_decoder_select="mdct rdft dct" -binkaudio_rdft_decoder_select="mdct rdft" -cavs_decoder_select="golomb" -cook_decoder_select="mdct" -cscd_decoder_suggest="zlib" -dca_decoder_select="mdct" -dnxhd_encoder_select="aandct" -dxa_decoder_select="zlib" -eac3_decoder_select="ac3_decoder" -eamad_decoder_select="aandct" -eatgq_decoder_select="aandct" -eatqi_decoder_select="aandct" -ffv1_decoder_select="golomb" -flac_decoder_select="golomb" -flac_encoder_select="golomb lpc" -flashsv_decoder_select="zlib" -flashsv_encoder_select="zlib" -flv_decoder_select="h263_decoder" -flv_encoder_select="h263_encoder" -h261_encoder_select="aandct" -h263_decoder_select="h263_parser" -h263_encoder_select="aandct" -h263_vaapi_hwaccel_select="vaapi h263_decoder" -h263i_decoder_select="h263_decoder" -h263p_encoder_select="h263_encoder" -h264_decoder_select="golomb h264dsp" -h264_dxva2_hwaccel_deps="dxva2api_h" -h264_dxva2_hwaccel_select="dxva2 h264_decoder" -h264_vaapi_hwaccel_select="vaapi" -h264_vdpau_decoder_select="vdpau h264_decoder" -imc_decoder_select="fft mdct" -jpegls_decoder_select="golomb" -jpegls_encoder_select="golomb" -ljpeg_encoder_select="aandct" -loco_decoder_select="golomb" -mjpeg_encoder_select="aandct" -mlp_decoder_select="mlp_parser" -mpeg1video_encoder_select="aandct" -mpeg2video_encoder_select="aandct" -mpeg4_decoder_select="h263_decoder mpeg4video_parser" -mpeg4_encoder_select="h263_encoder" -mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder" -mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder" -mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder" -mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder" -mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder" -mpeg_xvmc_decoder_deps="X11_extensions_XvMClib_h" -mpeg_xvmc_decoder_select="mpegvideo_decoder" -msmpeg4v1_decoder_select="h263_decoder" -msmpeg4v1_encoder_select="h263_encoder" -msmpeg4v2_decoder_select="h263_decoder" -msmpeg4v2_encoder_select="h263_encoder" -msmpeg4v3_decoder_select="h263_decoder" -msmpeg4v3_encoder_select="h263_encoder" -nellymoser_decoder_select="mdct" -nellymoser_encoder_select="mdct" -png_decoder_select="zlib" -png_encoder_select="zlib" -qcelp_decoder_select="lsp" -qdm2_decoder_select="mdct rdft" -rv10_decoder_select="h263_decoder" -rv10_encoder_select="h263_encoder" -rv20_decoder_select="h263_decoder" -rv20_encoder_select="h263_encoder" -rv30_decoder_select="golomb h264dsp" -rv40_decoder_select="golomb h264dsp" -shorten_decoder_select="golomb" -sipr_decoder_select="lsp" -snow_decoder_select="dwt" -snow_encoder_select="aandct dwt" -sonic_decoder_select="golomb" -sonic_encoder_select="golomb" -sonic_ls_encoder_select="golomb" -svq1_encoder_select="aandct" -svq3_decoder_select="golomb h264dsp" -svq3_decoder_suggest="zlib" -theora_decoder_select="vp3_decoder" -tiff_decoder_suggest="zlib" -tiff_encoder_suggest="zlib" -truehd_decoder_select="mlp_decoder" -tscc_decoder_select="zlib" -twinvq_decoder_select="mdct lsp" -vc1_decoder_select="h263_decoder" -vc1_dxva2_hwaccel_deps="dxva2api_h DXVA_PictureParameters_wDecodedPictureIndex" -vc1_dxva2_hwaccel_select="dxva2 vc1_decoder" -vc1_vaapi_hwaccel_select="vaapi vc1_decoder" -vc1_vdpau_decoder_select="vdpau vc1_decoder" -vorbis_decoder_select="mdct" -vorbis_encoder_select="mdct" -vp6a_decoder_select="vp6_decoder" -vp6f_decoder_select="vp6_decoder" -wmapro_decoder_select="mdct" -wmav1_decoder_select="mdct" -wmav1_encoder_select="mdct" -wmav2_decoder_select="mdct" -wmav2_encoder_select="mdct" -wmavoice_decoder_select="lsp rdft dct" -wmv1_decoder_select="h263_decoder" -wmv1_encoder_select="h263_encoder" -wmv2_decoder_select="h263_decoder" -wmv2_encoder_select="h263_encoder" -wmv3_decoder_select="vc1_decoder" -wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" -wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" -wmv3_vdpau_decoder_select="vc1_vdpau_decoder" -zlib_decoder_select="zlib" -zlib_encoder_select="zlib" -zmbv_decoder_select="zlib" -zmbv_encoder_select="zlib" - -vaapi_deps="va_va_h" -vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" - -# parsers -h264_parser_select="golomb h264dsp" - -# bitstream_filters -aac_adtstoasc_bsf_select="aac_parser" - -# external libraries -libdirac_decoder_deps="libdirac !libschroedinger" -libdirac_encoder_deps="libdirac" -libfaac_encoder_deps="libfaac" -libfaad_decoder_deps="libfaad" -libfaadbin_extralibs='$ldl' -libgsm_decoder_deps="libgsm" -libgsm_encoder_deps="libgsm" -libgsm_ms_decoder_deps="libgsm" -libgsm_ms_encoder_deps="libgsm" -libmp3lame_encoder_deps="libmp3lame" -libopencore_amrnb_decoder_deps="libopencore_amrnb" -libopencore_amrnb_encoder_deps="libopencore_amrnb" -libopencore_amrwb_decoder_deps="libopencore_amrwb" -libopenjpeg_decoder_deps="libopenjpeg" -libschroedinger_decoder_deps="libschroedinger" -libschroedinger_encoder_deps="libschroedinger" -libspeex_decoder_deps="libspeex" -libtheora_encoder_deps="libtheora" -libvorbis_encoder_deps="libvorbis" -libvpx_decoder_deps="libvpx" -libvpx_encoder_deps="libvpx" -libx264_encoder_deps="libx264" -libxvid_encoder_deps="libxvid" - -# demuxers / muxers -ac3_demuxer_deps="ac3_parser" -asf_stream_muxer_select="asf_muxer" -avisynth_demuxer_deps="avisynth" -dirac_demuxer_deps="dirac_parser" -eac3_demuxer_select="ac3_parser" -ipod_muxer_select="mov_muxer" -libnut_demuxer_deps="libnut" -libnut_muxer_deps="libnut" -matroska_audio_muxer_select="matroska_muxer" -matroska_demuxer_suggest="zlib bzlib" -mov_demuxer_suggest="zlib" -mp3_demuxer_deps="mpegaudio_parser" -mp4_muxer_select="mov_muxer" -mpegtsraw_demuxer_select="mpegts_demuxer" -mxf_d10_muxer_select="mxf_muxer" -ogg_demuxer_select="golomb" -psp_muxer_select="mov_muxer" -rtsp_demuxer_deps="sdp_demuxer" -rtsp_muxer_deps="sdp_demuxer" -rtsp_muxer_select="rtp_muxer" -sdp_demuxer_deps="rtp_protocol mpegts_demuxer" -sdp_demuxer_select="asf_demuxer rm_demuxer" -spdif_muxer_select="aac_parser" -tg2_muxer_select="mov_muxer" -tgp_muxer_select="mov_muxer" -w64_demuxer_deps="wav_demuxer" - -# indevs / outdevs -alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp" -alsa_indev_extralibs="-lasound" -alsa_outdev_deps="alsa_asoundlib_h" -alsa_outdev_extralibs="-lasound" -audio_beos_indev_deps="audio_beos" -audio_beos_indev_extralibs="-lmedia -lbe" -audio_beos_outdev_deps="audio_beos" -audio_beos_outdev_extralibs="-lmedia -lbe" -bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" -dv1394_indev_deps="dv1394 dv_demuxer" -jack_indev_deps="jack_jack_h" -jack_indev_extralibs="-ljack" -libdc1394_indev_deps="libdc1394" -oss_indev_deps_any="soundcard_h sys_soundcard_h" -oss_outdev_deps_any="soundcard_h sys_soundcard_h" -v4l_indev_deps="linux_videodev_h" -v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" -vfwcap_indev_deps="capCreateCaptureWindow" -vfwcap_indev_extralibs="-lavicap32" -x11_grab_device_indev_deps="x11grab XShmCreateImage" -x11_grab_device_indev_extralibs="-lX11 -lXext -lXfixes" - -# protocols -gopher_protocol_deps="network" -http_protocol_deps="network" -http_protocol_select="tcp_protocol" -rtmp_protocol_deps="tcp_protocol" -rtp_protocol_deps="udp_protocol" -tcp_protocol_deps="network" -udp_protocol_deps="network" - -# filters -movie_filter_deps="avfilter_lavf" -avfilter_lavf_deps="avformat" - -# libraries -avdevice_deps="avcodec avformat" -avformat_deps="avcodec" - -# programs -ffmpeg_deps="avcodec avformat swscale" -ffplay_deps="avcodec avformat swscale sdl" -ffplay_select="rdft" -ffprobe_deps="avcodec avformat" -ffserver_deps="avformat ffm_muxer rtp_protocol rtsp_demuxer" -ffserver_extralibs='$ldl' - -doc_deps="texi2html" - -# default parameters - -logfile="config.err" - -# installation paths -prefix_default="/usr/local" -bindir_default='${prefix}/bin' -datadir_default='${prefix}/share/ffmpeg' -incdir_default='${prefix}/include' -libdir_default='${prefix}/lib' -mandir_default='${prefix}/share/man' -shlibdir_default="$libdir_default" - -# toolchain -ar_default="ar" -cc_default="gcc" -cc_version=\"unknown\" -host_cc_default="gcc" -ln_s="ln -sf" -nm_default="nm" -objformat="elf" -ranlib="ranlib" -strip_default="strip" -yasmexe="yasm" - -nm_opts='-g' - -# machine -arch_default=$(uname -m) -cpu="generic" - -# OS -target_os_default=$(tolower $(uname -s)) -host_os=$target_os_default - -# configurable options -enable avcodec -enable avdevice -enable avformat -enable avutil -enable asm -enable debug -enable doc -enable fastdiv -enable ffmpeg -enable ffplay -enable ffprobe -enable ffserver -enable mpegaudio_hp -enable network -enable optimizations -enable protocols -enable static -enable stripping -enable swscale -enable swscale_alpha - -# build settings -SHFLAGS='-shared -Wl,-soname,$$(@F)' -FFSERVERLDFLAGS=-Wl,-E -LIBPREF="lib" -LIBSUF=".a" -FULLNAME='$(NAME)$(BUILDSUF)' -LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)' -SLIBPREF="lib" -SLIBSUF=".so" -SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)' -SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)' -SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)' -LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' - -CC_O='-o $@' - -host_cflags='-D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -O3 -g -Wall' -host_libs='-lm' - -target_path='$(CURDIR)' - -# gcc stupidly only outputs the basename of targets with -MM, but we need the -# full relative path for objects in subdirectories for non-recursive Make. -DEPEND_CMD='$(DEPCC) $(DEPFLAGS) $< | sed -e "/^\#.*/d" -e "s,^[[:space:]]*$(*F)\\.o,$(@D)/$(*F).o," > $(@:.o=.d)' -DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -MM' - -# find source path -source_path="$(dirname "$0")" -enable source_path_used -if test -f configure; then - source_path="$(pwd)" - disable source_path_used -else - source_path="$(cd "$source_path"; pwd)" - echo "$source_path" | grep -q '[[:blank:]]' && - die "Out of tree builds are impossible with whitespace in source path." - test -e "$source_path/config.h" && - die "Out of tree builds are impossible with config.h in source dir." -fi - -for v in "$@"; do - r=${v#*=} - l=${v%"$r"} - r=$(sh_quote "$r") - FFMPEG_CONFIGURATION="${FFMPEG_CONFIGURATION# } ${l}${r}" -done - -find_things(){ - thing=$1 - pattern=$2 - file=$source_path/$3 - sed -n "s/^[^#]*$pattern.*([^,]*, *\([^,]*\)\(,.*\)*).*/\1_$thing/p" "$file" -} - -ENCODER_LIST=$(find_things encoder ENC libavcodec/allcodecs.c) -DECODER_LIST=$(find_things decoder DEC libavcodec/allcodecs.c) -HWACCEL_LIST=$(find_things hwaccel HWACCEL libavcodec/allcodecs.c) -PARSER_LIST=$(find_things parser PARSER libavcodec/allcodecs.c) -BSF_LIST=$(find_things bsf BSF libavcodec/allcodecs.c) -MUXER_LIST=$(find_things muxer _MUX libavformat/allformats.c) -DEMUXER_LIST=$(find_things demuxer DEMUX libavformat/allformats.c) -OUTDEV_LIST=$(find_things outdev OUTDEV libavdevice/alldevices.c) -INDEV_LIST=$(find_things indev _IN libavdevice/alldevices.c) -PROTOCOL_LIST=$(find_things protocol PROTOCOL libavformat/allformats.c) -FILTER_LIST=$(find_things filter FILTER libavfilter/allfilters.c) - -for n in $COMPONENT_LIST; do - v=$(toupper ${n%s})_LIST - eval enable \$$v - eval ${n}_if_any="\$$v" -done - -enable $ARCH_EXT_LIST - -die_unknown(){ - echo "Unknown option \"$1\"." - echo "See $0 --help for available options." - exit 1 -} - -show_list() { - suffix=_$1 - shift - echo $* | sed s/$suffix//g | tr ' ' '\n' | sort | pr -3 -t - exit 0 -} - -for opt do - optval="${opt#*=}" - case "$opt" in - --extra-ldflags=*) add_ldflags $optval - ;; - --extra-libs=*) add_extralibs $optval - ;; - --disable-devices) disable $INDEV_LIST $OUTDEV_LIST - ;; - --enable-debug=*) debuglevel="$optval" - ;; - --disable-everything) - map 'eval disable \${$(toupper ${v%s})_LIST}' $COMPONENT_LIST - ;; - --enable-*=*|--disable-*=*) - eval $(echo "${opt%%=*}" | sed 's/--/action=/;s/-/ thing=/') - is_in "${thing}s" $COMPONENT_LIST || die_unknown "$opt" - eval list=\$$(toupper $thing)_LIST - name=$(echo "${optval}" | sed "s/,/_${thing}|/g")_${thing} - $action $(filter "$name" $list) - ;; - --enable-?*|--disable-?*) - eval $(echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g') - if is_in $option $COMPONENT_LIST; then - test $action = disable && action=unset - eval $action \$$(toupper ${option%s})_LIST - elif is_in $option $CMDLINE_SELECT; then - $action $option - else - die_unknown $opt - fi - ;; - --list-*) - NAME="${opt#--list-}" - is_in $NAME $COMPONENT_LIST || die_unknown $opt - NAME=${NAME%s} - eval show_list $NAME \$$(toupper $NAME)_LIST - ;; - --help|-h) show_help - ;; - *) - optname="${opt%%=*}" - optname="${optname#--}" - optname=$(echo "$optname" | sed 's/-/_/g') - if is_in $optname $CMDLINE_SET; then - eval $optname='$optval' - elif is_in $optname $CMDLINE_APPEND; then - append $optname "$optval" - else - die_unknown $opt - fi - ;; - esac -done - -disabled logging && logfile=/dev/null - -echo "# $0 $FFMPEG_CONFIGURATION" > $logfile -set >> $logfile - -test -n "$cross_prefix" && enable cross_compile - -if enabled cross_compile; then - test -n "$arch" && test -n "$target_os" || - die "Must specify target arch and OS when cross-compiling" -fi - -set_default arch target_os - -ar_default="${cross_prefix}${ar_default}" -cc_default="${cross_prefix}${cc_default}" -nm_default="${cross_prefix}${nm_default}" -ranlib="${cross_prefix}${ranlib}" -strip_default="${cross_prefix}${strip_default}" - -sysinclude_default="${sysroot}/usr/include" - -set_default cc nm strip sysinclude -enabled cross_compile || host_cc_default=$cc -set_default host_cc - -exesuf() { - case $1 in - mingw32*|cygwin*|*-dos|freedos|opendos|os/2*) echo .exe ;; - esac -} - -EXESUF=$(exesuf $target_os) -HOSTEXESUF=$(exesuf $host_os) - -# set temporary file name -: ${TMPDIR:=$TEMPDIR} -: ${TMPDIR:=$TMP} -: ${TMPDIR:=/tmp} - -if ! check_cmd type mktemp; then - # simple replacement for missing mktemp - # NOT SAFE FOR GENERAL USE - mktemp(){ - echo "${2%XXX*}.${HOSTNAME}.${UID}.$$" - } -fi - -tmpfile(){ - tmp=$(mktemp -u "${TMPDIR}/ffconf.XXXXXXXX")$2 && - (set -C; exec > $tmp) 2>/dev/null || - die "Unable to create temporary file in $TMPDIR." - append TMPFILES $tmp - eval $1=$tmp -} - -trap 'rm -f -- $TMPFILES' EXIT -trap exit HUP INT TERM - -tmpfile TMPC .c -tmpfile TMPE $EXESUF -tmpfile TMPH .h -tmpfile TMPO .o -tmpfile TMPS .S -tmpfile TMPV .ver -tmpfile TMPSH .sh - -unset -f mktemp - -# make sure we can execute files in $TMPDIR -cat > $TMPSH 2>> $logfile <> $logfile 2>&1 -if ! $TMPSH >> $logfile 2>&1; then - cat <&1 | grep -qi ^gcc; then - cc_type=gcc - cc_version=__VERSION__ - if ! $cc -dumpversion | grep -q '^2\.'; then - CC_DEPFLAGS='-MMD -MF $(@:.o=.d) -MT $@' - AS_DEPFLAGS='-MMD -MF $(@:.o=.d) -MT $@' - fi - speed_cflags='-O3' - size_cflags='-Os' -elif $cc --version 2>/dev/null | grep -q Intel; then - cc_type=icc - cc_version="AV_STRINGIFY(__INTEL_COMPILER)" - CC_DEPFLAGS='-MMD' - AS_DEPFLAGS='-MMD' - speed_cflags='-O3' - size_cflags='-Os' - noopt_cflags='-O1' -elif $cc -v 2>&1 | grep -q xlc; then - cc_type=xlc - cc_version="AV_STRINGIFY(__IBMC__)" - speed_cflags='-O5' - size_cflags='-O5 -qcompact' -elif $cc -V 2>/dev/null | grep -q Compaq; then - cc_type=ccc - cc_version="AV_STRINGIFY(__DECC_VER)" - DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -M' - debuglevel=3 - add_ldflags -Wl,-z,now # calls to libots crash without this - speed_cflags='-fast' - size_cflags='-O1' -elif $cc --vsn 2>/dev/null | grep -q "ARM C/C++ Compiler"; then - test -d "$sysroot" || die "No valid sysroot specified." - cc_type=armcc - cc_version="AV_STRINGIFY(__ARMCC_VERSION)" - armcc_conf="$PWD/armcc.conf" - $cc --arm_linux_configure \ - --arm_linux_config_file="$armcc_conf" \ - --configure_sysroot="$sysroot" \ - --configure_cpp_headers="$sysinclude" >>$logfile 2>&1 || - die "Error creating armcc configuration file." - cc="$cc --arm_linux_config_file=$armcc_conf --translate_gcc" - as_default="${cross_prefix}gcc" - CC_DEPFLAGS='-MMD' - AS_DEPFLAGS='-MMD' - speed_cflags='-O3' - size_cflags='-Os' -elif $cc -version 2>/dev/null | grep -q TMS470; then - cc_type=tms470 - cc_version="AV_STRINGIFY(__TI_COMPILER_VERSION__)" - cc="$cc --gcc --abi=eabi -eo=.o -mc -me" - CC_O='-fr=$(@D)' - as_default="${cross_prefix}gcc" - ld_default="${cross_prefix}gcc" - TMPO=$(basename $TMPC .c).o - append TMPFILES $TMPO - add_cflags -D__gnuc_va_list=va_list -D__USER_LABEL_PREFIX__= - CC_DEPFLAGS='-ppa -ppd=$(@:.o=.d)' - AS_DEPFLAGS='-MMD' - speed_cflags='-O3 -mf=5' - size_cflags='-O3 -mf=2' - filter_cflags=tms470_flags - tms470_flags(){ - for flag; do - case $flag in - -march=*|-mcpu=*) - case "${flag#*=}" in - armv7-a|cortex-a*) echo -mv=7a8 ;; - armv7-r|cortex-r*) echo -mv=7r4 ;; - armv7-m|cortex-m*) echo -mv=7m3 ;; - armv6*|arm11*) echo -mv=6 ;; - armv5*e|arm[79]*e*|arm9[24]6*|arm96*|arm102[26]) - echo -mv=5e ;; - armv4*|arm7*|arm9[24]*) echo -mv=4 ;; - esac - ;; - -mfpu=neon) echo --float_support=vfpv3 --neon ;; - -mfpu=vfp) echo --float_support=vfpv2 ;; - -mfpu=vfpv3) echo --float_support=vfpv3 ;; - -msoft-float) echo --float_support=vfplib ;; - -O[0-3]|-mf=*) echo $flag ;; - -g) echo -g -mn ;; - -pds=*) echo $flag ;; - esac - done - } -elif $cc -v 2>&1 | grep -q clang; then - cc_type=clang - cc_version=__VERSION__ - CC_DEPFLAGS='-MMD' - AS_DEPFLAGS='-MMD' - speed_cflags='-O3' - size_cflags='-Os' -elif $cc -V 2>&1 | grep -q Sun; then - cc_type=suncc - cc_version="AV_STRINGIFY(__SUNPRO_C)" - DEPEND_CMD='$(DEPCC) $(DEPFLAGS) $< | sed -e "1s,^.*: ,$@: ," -e "\$$!s,\$$, \\\," -e "1!s,^.*: , ," > $(@:.o=.d)' - DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -xM1' - speed_cflags='-O5' - size_cflags='-O5 -xspace' - filter_cflags=suncc_flags - suncc_flags(){ - for flag; do - case $flag in - -march=*|-mcpu=*) - case "${flag#*=}" in - native) echo -xtarget=native ;; - v9) echo -xarch=sparc ;; - ultrasparc) echo -xarch=sparcvis ;; - ultrasparc3|niagara*) echo -xarch=sparcvis2 ;; - i586|pentium) echo -xchip=pentium ;; - i686|pentiumpro|pentium2) echo -xtarget=pentium_pro ;; - pentium3*|c3-2) echo -xtarget=pentium3 ;; - pentium-m) echo -xarch=sse2 -xchip=pentium3 ;; - pentium4*) echo -xtarget=pentium4 ;; - prescott|nocona) echo -xarch=sse3 -xchip=pentium4 ;; - *-sse3) echo -xarch=sse3 ;; - core2) echo -xarch=ssse3 -xchip=core2 ;; - amdfam10|barcelona) echo -xarch=sse4_1 ;; - athlon-4|athlon-[mx]p) echo -xarch=ssea ;; - k8|opteron|athlon64|athlon-fx) - echo -xarch=sse2a ;; - athlon*) echo -xarch=pentium_proa ;; - esac - ;; - -std=c99) echo -xc99 ;; - -fomit-frame-pointer) echo -xregs=frameptr ;; - -fPIC) echo -KPIC -xcode=pic32 ;; - -W*,*) echo $flag ;; - -f*-*|-W*) ;; - *) echo $flag ;; - esac - done - } -fi - -test -n "$cc_type" && enable $cc_type || echolog "Unknown C compiler $cc" - -: ${as_default:=$cc} -: ${dep_cc_default:=$cc} -: ${ld_default:=$cc} -set_default ar as dep_cc ld - -test -n "$CC_DEPFLAGS" || CCDEP=$DEPEND_CMD -test -n "$AS_DEPFLAGS" || ASDEP=$DEPEND_CMD - -add_cflags $extra_cflags -add_asflags $extra_cflags - -if test -n "$sysroot"; then - case "$cc_type" in - gcc) - add_cppflags --sysroot="$sysroot" - add_ldflags --sysroot="$sysroot" - ;; - tms470) - add_cppflags -I"$sysinclude" - add_ldflags --sysroot="$sysroot" - ;; - clang) - add_cppflags -isysroot "$sysroot" - add_ldflags -isysroot "$sysroot" - ;; - esac -fi - -if test "$cpu" = host; then - enabled cross_compile && die "--cpu=host makes no sense when cross-compiling." - - case "$cc_type" in - gcc) - check_native(){ - $cc $1=native -v -c -o $TMPO $TMPC >$TMPE 2>&1 || return - sed -n "/$1=/{ - s/.*$1=\\([^ ]*\\).*/\\1/ - p - q - }" $TMPE - } - cpu=$(check_native -march || check_native -mcpu) - ;; - esac - - test "${cpu:-host}" = host && die "--cpu=host not supported with compiler $cc" -fi - -# Deal with common $arch aliases -case "$arch" in - arm*) - arch="arm" - ;; - mips|mipsel|IP*) - arch="mips" - ;; - mips64*) - arch="mips" - subarch="mips64" - ;; - parisc|hppa) - arch="parisc" - ;; - parisc64|hppa64) - arch="parisc" - subarch="parisc64" - ;; - "Power Macintosh"|ppc|powerpc) - arch="ppc" - ;; - ppc64|powerpc64) - arch="ppc" - subarch="ppc64" - ;; - s390|s390x) - arch="s390" - ;; - sh4|sh) - arch="sh4" - ;; - sun4u|sparc64) - arch="sparc" - subarch="sparc64" - ;; - i[3-6]86|i86pc|BePC|x86_64|amd64) - arch="x86" - ;; -esac - -is_in $arch $ARCH_LIST || echo "WARNING: unknown arch $arch" -enable $arch - -# Add processor-specific flags -if test "$cpu" = generic; then - : do nothing -elif enabled ppc; then - - case $(tolower $cpu) in - 601|ppc601|powerpc601) - cpuflags="-mcpu=601" - disable altivec - ;; - 603*|ppc603*|powerpc603*) - cpuflags="-mcpu=603" - disable altivec - ;; - 604*|ppc604*|powerpc604*) - cpuflags="-mcpu=604" - disable altivec - ;; - g3|75*|ppc75*|powerpc75*) - cpuflags="-mcpu=750 -mpowerpc-gfxopt" - disable altivec - ;; - g4|745*|ppc745*|powerpc745*) - cpuflags="-mcpu=7450 -mpowerpc-gfxopt" - ;; - 74*|ppc74*|powerpc74*) - cpuflags="-mcpu=7400 -mpowerpc-gfxopt" - ;; - g5|970|ppc970|powerpc970|power4*) - cpuflags="-mcpu=970 -mpowerpc-gfxopt -mpowerpc64" - ;; - cell) - cpuflags="-mcpu=cell" - enable ldbrx - ;; - e500v2) - cpuflags="-mcpu=8548 -mhard-float -mfloat-gprs=double" - disable altivec - ;; - e500) - cpuflags="-mcpu=8540 -mhard-float" - disable altivec - ;; - esac - -elif enabled x86; then - - case $cpu in - i[345]86|pentium) - cpuflags="-march=$cpu" - disable mmx - ;; - # targets that do NOT support conditional mov (cmov) - pentium-mmx|k6|k6-[23]|winchip-c6|winchip2|c3) - cpuflags="-march=$cpu" - disable cmov - ;; - # targets that do support conditional mov (cmov) - i686|pentiumpro|pentium[23]|pentium-m|athlon|athlon-tbird|athlon-4|athlon-[mx]p|athlon64|k8|opteron|athlon-fx|core2|amdfam10) - cpuflags="-march=$cpu" - enable cmov - enable fast_cmov - ;; - # targets that do support conditional mov but on which it's slow - pentium4|pentium4m|prescott|nocona) - cpuflags="-march=$cpu" - enable cmov - disable fast_cmov - ;; - esac - -elif enabled sparc; then - - case $cpu in - sparc64) - cpuflags="-mcpu=v9" - ;; - esac - -elif enabled arm; then - - case $cpu in - armv*) - cpuflags="-march=$cpu" - ;; - *) - cpuflags="-mcpu=$cpu" - ;; - esac - -elif enabled alpha; then - - enabled ccc && cpuflags="-arch $cpu" || cpuflags="-mcpu=$cpu" - -elif enabled bfin; then - - cpuflags="-mcpu=$cpu" - -elif enabled mips; then - - cpuflags="-march=$cpu" - -elif enabled avr32; then - - case $cpu in - ap7[02]0[0-2]) - subarch="avr32_ap" - cpuflags="-mpart=$cpu" - ;; - ap) - subarch="avr32_ap" - cpuflags="-march=$cpu" - ;; - uc3[ab]*) - subarch="avr32_uc" - cpuflags="-mcpu=$cpu" - ;; - uc) - subarch="avr32_uc" - cpuflags="-march=$cpu" - ;; - esac - -fi - -add_cflags $cpuflags -add_asflags $cpuflags - -# compiler sanity check -check_exec < -EOF -check_cc -D_LARGEFILE_SOURCE < -EOF - -check_host_cflags -std=c99 - -case "$arch" in - alpha|ia64|mips|parisc|sparc) - spic=$shared - ;; - x86) - subarch="x86_32" - check_cc < 3) || (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" || - die "ERROR: MinGW runtime version must be >= 3.15." - enabled_any avisynth vfwcap_indev && - { check_cpp_condition w32api.h "(__W32API_MAJOR_VERSION > 3) || (__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION >= 13)" || - die "ERROR: avisynth and vfwcap_indev require w32api version 3.13 or later."; } - fi - ;; - cygwin*) - target_os=cygwin - shlibdir_default="$bindir_default" - SLIBPREF="cyg" - SLIBSUF=".dll" - SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)' - SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' - SHFLAGS='-shared -Wl,--enable-auto-image-base' - objformat="win32" - enable dos_paths - check_cflags -fno-common - ;; - *-dos|freedos|opendos) - disable ffplay ffserver - disable $INDEV_LIST $OUTDEV_LIST - network_extralibs="-lsocket" - objformat="coff" - enable dos_paths - ;; - linux) - enable dv1394 - ;; - irix*) - target_os=irix - ranlib="echo ignoring ranlib" - ;; - os/2*) - strip="lxlite" - ln_s="cp -f" - FFLDFLAGS="-Zomf -Zbin-files -Zargs-wild -Zmap" - SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf' - FFSERVERLDFLAGS="" - LIBSUF="_s.a" - SLIBPREF="" - SLIBSUF=".dll" - SLIBNAME_WITH_VERSION='$(SLIBPREF)$(NAME)-$(LIBVERSION)$(SLIBSUF)' - SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(shell echo $(NAME) | cut -c1-6)$(LIBMAJOR)$(SLIBSUF)' - SLIB_CREATE_DEF_CMD='echo LIBRARY $(SLIBNAME_WITH_MAJOR) INITINSTANCE TERMINSTANCE > $(SUBDIR)$(NAME).def; \ - echo PROTMODE >> $(SUBDIR)$(NAME).def; \ - echo CODE PRELOAD MOVEABLE DISCARDABLE >> $(SUBDIR)$(NAME).def; \ - echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $(SUBDIR)$(NAME).def; \ - echo EXPORTS >> $(SUBDIR)$(NAME).def; \ - emxexp -o $(OBJS) >> $(SUBDIR)$(NAME).def' - SLIB_EXTRA_CMD='emximp -o $(SUBDIR)$(LIBPREF)$(NAME)_dll.a $(SUBDIR)$(NAME).def; \ - emximp -o $(SUBDIR)$(LIBPREF)$(NAME)_dll.lib $(SUBDIR)$(NAME).def;' - SLIB_INSTALL_EXTRA_CMD='install -m 644 $(SUBDIR)$(LIBPREF)$(NAME)_dll.a $(SUBDIR)$(LIBPREF)$(NAME)_dll.lib "$(LIBDIR)"' - SLIB_UNINSTALL_EXTRA_CMD='rm -f "$(LIBDIR)"/$(LIBPREF)$(NAME)_dll.a "$(LIBDIR)"/$(LIBPREF)$(NAME)_dll.lib' - enable dos_paths - ;; - gnu/kfreebsd) - ;; - gnu) - ;; - none) - ;; - *) - die "Unknown OS '$target_os'." - ;; -esac - -check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic - -set_default $PATHS_LIST - -add_extralibs $osextralibs - -# Combine FFLDFLAGS and the LDFLAGS environment variable. -LDFLAGS="$FFLDFLAGS $LDFLAGS" - -# we need to build at least one lib type -if ! enabled_any static shared; then - cat < -#ifndef FAAD2_VERSION -ok faad1 -#endif -int main(void) { return 0; } -EOF - test $? = 0 && enable libfaad2 - else - die "FAAD test failed." - fi -fi - - -die_license_disabled() { - enabled $1 || { enabled $2 && die "$2 is $1 and --enable-$1 is not specified."; } -} - -die_license_disabled gpl libfaad2 -die_license_disabled gpl libx264 -die_license_disabled gpl libxvid -die_license_disabled gpl postproc -die_license_disabled gpl x11grab - -die_license_disabled nonfree libfaac - -die_license_disabled version3 libopencore_amrnb -die_license_disabled version3 libopencore_amrwb - -enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; } - -check_deps $ARCH_EXT_LIST - -disabled optimizations || check_cflags -fomit-frame-pointer - -enable_pic() { - enable pic - add_cppflags -DPIC - add_cflags -fPIC - add_asflags -fPIC -} - -enabled pic && enable_pic - -check_cc <= 83" || - die "ERROR: libx264 version must be >= 0.83."; } -enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore -enabled mlib && require mediaLib mlib_types.h mlib_VectorSub_S16_U8_Mod -lmlib - -# libdc1394 check -if enabled libdc1394; then - { check_lib dc1394/dc1394.h dc1394_new -ldc1394 -lraw1394 && - enable libdc1394_2; } || - { check_lib libdc1394/dc1394_control.h dc1394_create_handle -ldc1394_control -lraw1394 && - enable libdc1394_1; } || - die "ERROR: No version of libdc1394 found " -fi - -SDL_CONFIG="${cross_prefix}sdl-config" -if "${SDL_CONFIG}" --version > /dev/null 2>&1; then - sdl_cflags=$("${SDL_CONFIG}" --cflags) - sdl_libs=$("${SDL_CONFIG}" --libs) - check_func_headers SDL.h SDL_Init $sdl_cflags $sdl_libs && - check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags && - enable sdl && - check_struct SDL.h SDL_VideoInfo current_w $sdl_cflags && enable sdl_video_size -fi - -texi2html -version > /dev/null 2>&1 && enable texi2html || disable texi2html - -if enabled network; then - check_type "sys/types.h sys/socket.h" socklen_t - check_type netdb.h "struct addrinfo" - check_type netinet/in.h "struct ipv6_mreq" - check_type netinet/in.h "struct sockaddr_in6" - check_type "sys/types.h sys/socket.h" "struct sockaddr_storage" - check_struct "sys/types.h sys/socket.h" "struct sockaddr" sa_len - # Prefer arpa/inet.h over winsock2 - if check_header arpa/inet.h ; then - check_func closesocket - elif check_header winsock2.h ; then - check_func_headers winsock2.h closesocket -lws2 && \ - network_extralibs="-lws2" || \ - { check_func_headers winsock2.h closesocket -lws2_32 && \ - network_extralibs="-lws2_32"; } - check_type ws2tcpip.h socklen_t - check_type ws2tcpip.h "struct addrinfo" - check_type ws2tcpip.h "struct ipv6_mreq" - check_type ws2tcpip.h "struct sockaddr_in6" - check_type ws2tcpip.h "struct sockaddr_storage" - check_struct winsock2.h "struct sockaddr" sa_len - else - disable network - fi -fi - -check_header linux/videodev.h -check_header linux/videodev2.h -check_header sys/videoio.h - -check_func_headers "windows.h vfw.h" capCreateCaptureWindow "$vfwcap_indev_extralibs" - -# check for ioctl_meteor.h, ioctl_bt848.h and alternatives -{ check_header dev/bktr/ioctl_meteor.h && - check_header dev/bktr/ioctl_bt848.h; } || -{ check_header machine/ioctl_meteor.h && - check_header machine/ioctl_bt848.h; } || -{ check_header dev/video/meteor/ioctl_meteor.h && - check_header dev/video/bktr/ioctl_bt848.h; } || -check_header dev/ic/bt8xx.h - -check_header sys/soundcard.h -check_header soundcard.h - -enabled_any alsa_indev alsa_outdev && check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound - -enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack - -enabled x11grab && -check_header X11/Xlib.h && -check_header X11/extensions/XShm.h && -check_header X11/extensions/Xfixes.h && -check_func XOpenDisplay -lX11 && -check_func XShmCreateImage -lX11 -lXext && -check_func XFixesGetCursorImage -lX11 -lXext -lXfixes - -if ! disabled vdpau && enabled vdpau_vdpau_h; then -check_cpp_condition \ - vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" || - { echolog "Please upgrade to libvdpau >= 0.2 if you would like vdpau support." && - disable vdpau; } -fi - -enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" - -# add some useful compiler flags if supported -check_cflags -Wdeclaration-after-statement -check_cflags -Wall -check_cflags -Wno-switch -check_cflags -Wdisabled-optimization -check_cflags -Wpointer-arith -check_cflags -Wredundant-decls -check_cflags -Wno-pointer-sign -check_cflags -Wcast-qual -check_cflags -Wwrite-strings -check_cflags -Wtype-limits -check_cflags -Wundef -check_cflags -Wmissing-prototypes -enabled extra_warnings && check_cflags -Winline - -# add some linker flags -check_ldflags -Wl,--warn-common -check_ldflags -Wl,--as-needed -check_ldflags '-Wl,-rpath-link,\$(BUILD_ROOT)/libpostproc -Wl,-rpath-link,\$(BUILD_ROOT)/libswscale -Wl,-rpath-link,\$(BUILD_ROOT)/libavfilter -Wl,-rpath-link,\$(BUILD_ROOT)/libavdevice -Wl,-rpath-link,\$(BUILD_ROOT)/libavformat -Wl,-rpath-link,\$(BUILD_ROOT)/libavcodec -Wl,-rpath-link,\$(BUILD_ROOT)/libavutil' -check_ldflags -Wl,-Bsymbolic - -echo "X{};" > $TMPV -if test_ldflags -Wl,--version-script,$TMPV; then - append SHFLAGS '-Wl,--version-script,\$(SUBDIR)lib\$(NAME).ver' - check_cc < config.mak <> config.mak - eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak -} - -get_version LIBSWSCALE libswscale/swscale.h -get_version LIBPOSTPROC libpostproc/postprocess.h -get_version LIBAVCODEC libavcodec/avcodec.h -get_version LIBAVDEVICE libavdevice/avdevice.h -get_version LIBAVFORMAT libavformat/avformat.h -get_version LIBAVUTIL libavutil/avutil.h -get_version LIBAVFILTER libavfilter/avfilter.h - -enabled asmalign_pot || align_shift="1 <<" - -cat > $TMPH <>$TMPH - -if enabled small || disabled optimizations; then - echo "#undef av_always_inline" >> $TMPH - echo "#define av_always_inline" >> $TMPH -fi - -print_config ARCH_ $TMPH config.mak $ARCH_LIST -print_config HAVE_ $TMPH config.mak $HAVE_LIST -print_config CONFIG_ $TMPH config.mak $CONFIG_LIST \ - $CONFIG_EXTRA \ - $DECODER_LIST \ - $ENCODER_LIST \ - $HWACCEL_LIST \ - $PARSER_LIST \ - $BSF_LIST \ - $DEMUXER_LIST \ - $MUXER_LIST \ - $FILTER_LIST \ - $PROTOCOL_LIST \ - $INDEV_LIST \ - $OUTDEV_LIST \ - -echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH -echo "endif # FFMPEG_CONFIG_MAK" >> config.mak - -# Do not overwrite an unchanged config.h to avoid superfluous rebuilds. -cp_if_changed $TMPH config.h - -cat > $TMPH <> $TMPH - -cp_if_changed $TMPH libavutil/avconfig.h - -# build pkg-config files - -pkgconfig_generate(){ -name=$1 -shortname=${name#lib}${build_suffix} -comment=$2 -version=$3 -libs=$4 -requires=$5 -cat < $name/$name.pc -prefix=$prefix -exec_prefix=\${prefix} -libdir=$libdir -includedir=$incdir - -Name: $name -Description: $comment -Version: $version -Requires: $(enabled shared || echo $requires) -Requires.private: $(enabled shared && echo $requires) -Conflicts: -Libs: -L\${libdir} -l${shortname} $(enabled shared || echo $libs) -Libs.private: $(enabled shared && echo $libs) -Cflags: -I\${includedir} -EOF -cat < $name/$name-uninstalled.pc -prefix= -exec_prefix= -libdir=\${pcfiledir} -includedir=${source_path} - -Name: $name -Description: $comment -Version: $version -Requires: $requires -Conflicts: -Libs: \${libdir}/${LIBPREF}${shortname}${LIBSUF} $libs -Cflags: -I\${includedir} -EOF -} - -pkgconfig_generate libavutil "FFmpeg utility library" "$LIBAVUTIL_VERSION" -pkgconfig_generate libavcodec "FFmpeg codec library" "$LIBAVCODEC_VERSION" "$extralibs" "libavutil = $LIBAVUTIL_VERSION" -pkgconfig_generate libavformat "FFmpeg container format library" "$LIBAVFORMAT_VERSION" "$extralibs" "libavcodec = $LIBAVCODEC_VERSION" -pkgconfig_generate libavdevice "FFmpeg device handling library" "$LIBAVDEVICE_VERSION" "$extralibs" "libavformat = $LIBAVFORMAT_VERSION" -enabled avfilter && - pkgconfig_generate libavfilter "FFmpeg video filtering library" "$LIBAVFILTER_VERSION" "$extralibs" "libavutil = $LIBAVUTIL_VERSION" -enabled postproc && - pkgconfig_generate libpostproc "FFmpeg post processing library" "$LIBPOSTPROC_VERSION" -pkgconfig_generate libswscale "FFmpeg image rescaling library" "$LIBSWSCALE_VERSION" "" "libavutil = $LIBAVUTIL_VERSION" diff --git a/tizen/distrib/ffmpeg/doc/APIchanges b/tizen/distrib/ffmpeg/doc/APIchanges deleted file mode 100644 index db69658..0000000 --- a/tizen/distrib/ffmpeg/doc/APIchanges +++ /dev/null @@ -1,239 +0,0 @@ -Never assume the API of libav* to be stable unless at least 1 week has passed since -the last major version increase. -The last version increases were: -libavcodec: ? -libavdevice: ? -libavfilter: 2009-10-18 -libavformat: ? -libpostproc: ? -libswscale: ? -libavutil: 2009-03-08 - - -API changes, most recent first: - -2010-06-01 - r31301 - lsws 0.11.0 - convertPalette API - Add sws_convertPalette8ToPacked32 and sws_convertPalette8ToPacked24 - -2010-05-26 - r23334 - lavc 52.72.0 - CODEC_CAP_EXPERIMENTAL - Add CODEC_CAP_EXPERIMENTAL flag. - -2010-05-18 - r23161 - lavf 52.63.0 - AVFMT_FLAG_RTP_HINT - Add AVFMT_FLAG_RTP_HINT as possible value for AVFormatContext.flags - -2010-05-01 - r23002 - lavf 52.62.0 - probe function - Add av_probe_input_format2 to API, it allows ignoring probe - results below given score and returns the actual probe score. - -2010-04-01 - r22806 - lavf 52.61.0 - metadata API - Add a flag for av_metadata_set2() to disable overwriting of - existing tags. - -2010-04-01 - r22753 - lavc 52.66.0 - Add avcodec_get_edge_width() - -2010-03-31 - r22750 - lavc 52.65.0 - Add avcodec_copy_context(). - -2010-03-31 - r22748 - lavf 52.60.0 - av_match_ext() - Make av_match_ext() public. - -2010-03-31 - r22736 - lavu 50.14.0 - AVMediaType - Move AVMediaType enum from libavcodec to libavutil. - -2010-03-31 - r22735 - lavc 52.64.0 - AVMediaType - Define AVMediaType enum, and use it instead of enum CodecType, which - is deprecated and will be dropped at the next major bump. - -2010-03-25 - r22684 - lavu 50.13.0 - av_strerror() - Implement av_strerror(). - -2010-03-23 - r22649 - lavc 52.60.0 - av_dct_init() - Support DCT-I and DST-I - -2010-03-15 - r22540 - lavf 52.56.0 - AVFormatContext.start_time_realtime - Add AVFormatContext.start_time_realtime field. - -2010-03-13 - r22506 - lavfi 1.18.0 - AVFilterPicRef.pos - Add AVFilterPicRef.pos field. - -2010-03-13 - r22501 - lavu 50.12.0 - error.h - Move error code definitions from libavcodec/avcodec.h to - the new public header libavutil/error.h. - -2010-03-07 - r22291 - lavc 52.56.0 - avfft.h - Add public FFT interface. - -2010-03-06 - r22251 - lavu 50.11.0 - av_stristr() - Add av_stristr(). - -2010-03-03 - r22174 - lavu 50.10.0 - av_tree_enumerate() - Add av_tree_enumerate(). - -2010-02-07 - r21673 - lavu 50.9.0 - av_compare_ts() - Add av_compare_ts(). - -2010-02-05 - r30513 - lsws 0.10.0 - sws_getCoefficients() - Add sws_getCoefficients(). - -2010-02-01 - r21587 - lavf 52.50.0 - metadata API - Add a list of generic tag names, change 'author' -> 'artist', - 'year' -> 'date'. - -2010-01-30 - r21545 - lavu 50.8.0 - av_get_pix_fmt() - Add av_get_pix_fmt(). - -2010-01-21 - r30381 - lsws 0.9.0 - sws_scale - Change constness attributes of sws_scale() parameters. - -2010-01-10 - r21121 - lavfi 1.15.0 - avfilter_graph_config_links() - Add a log_ctx parameter to avfilter_graph_config_links(). - -2010-01-07 - r30236 - lsws 0.8.0 - sws_isSupported{In,Out}put - Add sws_isSupportedInput() and sws_isSupportedOutput() functions. - -2010-01-06 - r21035 - lavfi 1.14.0 - avfilter_add_colorspace() - Change the avfilter_add_colorspace() signature, make it accept an - (AVFilterFormats **) rather than an (AVFilterFormats *) as before. - -2010-01-03 - r21007 - lavfi 1.13.0 - avfilter_add_colorspace() - Add avfilter_add_colorspace(). - -2010-01-02 - r20998 - lavf 52.46.0 - av_match_ext() - Add av_match_ext(), it should be used in place of match_ext(). - -2010-01-01 - r20991 - lavf 52.45.0 - av_guess_format() - Add av_guess_format(), it should be used in place of guess_format(). - -2009-12-13 - r20834 - lavf 52.43.0 - metadata API - Add av_metadata_set2(), AV_METADATA_DONT_STRDUP_KEY and AV_METADATA_DONT_STRDUP_VAL. - -2009-12-13 - r20829 - lavu 50.7.0 - avstring.h API - Add av_d2str(). - -2009-12-13 - r20826 - lavc 52.42.0 - AVStream - Add avg_frame_rate. - -2009-12-12 - r20808 - lavu 50.6.0 - av_bmg_next() - Introduce the av_bmg_next() function. - -2009-12-05 - r20734 - lavfi 1.12.0 - avfilter_draw_slice() - Add a slice_dir parameter to avfilter_draw_slice(). - -2009-11-26 - r20611 - lavfi 1.11.0 - AVFilter - Remove the next field from AVFilter, this is not anymore required. - -2009-11-25 - r20607 - lavfi 1.10.0 - avfilter_next() - Introduce the avfilter_next() function. - -2009-11-25 - r20605 - lavfi 1.9.0 - avfilter_register() - Change the signature of avfilter_register() to make it return an - int. This is required since now the registration operation may fail. - -2009-11-25 - r20603 - lavu 50.5.0 - pixdesc.h API - Make the pixdesc.h API public. - -2009-10-27 - r20385 - lavfi 1.5.0 - AVFilter.next - Add a next field to AVFilter, this is used for simplifying the - registration and management of the registered filters. - -2009-10-23 - r20356 - lavfi 1.4.1 - AVFilter.description - Add a description field to AVFilter. - -2009-10-19 - r20302 - lavfi 1.3.0 - avfilter_make_format_list() - Change the interface of avfilter_make_format_list() from - avfilter_make_format_list(int n, ...) to - avfilter_make_format_list(enum PixelFormat *pix_fmts). - -2009-10-18 - r20272 - lavfi 1.0.0 - avfilter_get_video_buffer() - Make avfilter_get_video_buffer() recursive and add the w and h - parameters to it. - -2009-10-07 - r20189 - lavfi 0.5.1 - AVFilterPic - Add w and h fields to AVFilterPic. - -2009-06-22 - r19250 - lavf 52.34.1 - AVFormatContext.packet_size - This is now an unsigned int instead of a signed int. - -2009-06-19 - r19222 - lavc 52.32.0 - AVSubtitle.pts - Add a pts field to AVSubtitle which gives the subtitle packet pts - in AV_TIME_BASE. Some subtitle de-/encoders (e.g. XSUB) will - not work right without this. - -2009-06-03 - r19078 - lavc 52.30.2 - AV_PKT_FLAG_KEY - PKT_FLAG_KEY has been deprecated and will be dropped at the next - major version. Use AV_PKT_FLAG_KEY instead. - -2009-06-01 - r19025 - lavc 52.30.0 - av_lockmgr_register() - av_lockmgr_register() can be used to register a callback function - that lavc (and in the future, libraries that depend on lavc) can use - to implement mutexes. The application should provide a callback function - that implements the AV_LOCK_* operations described in avcodec.h. - When the lock manager is registered, FFmpeg is guaranteed to behave - correctly in a multi-threaded application. - -2009-04-30 - r18719 - lavc 52.28.0 - av_free_packet - av_free_packet() is no longer an inline function. It is now exported. - -2009-04-11 - r18431 - lavc 52.25.0 - deprecate av_destruct_packet_nofree - Please use NULL instead. This has been supported since r16506 - (lavf > 52.23.1, lavc > 52.10.0). - -2009-04-07 - r18351 - lavc 52.23.0 - avcodec_decode_video/audio/subtitle - The old decoding functions are deprecated, all new code should use the - new functions avcodec_decode_video2(), avcodec_decode_audio3() and - avcodec_decode_subtitle2(). These new functions take an AVPacket *pkt - argument instead of a const uint8_t *buf / int buf_size pair. - -2009-04-03 - r18321 - lavu 50.3.0 - av_fifo_space - Introduce the av_fifo_space() function. - -2009-04-02 - r18317 - lavc 52.23.0 - AVPacket - Move AVPacket declaration from libavformat/avformat.h to - libavcodec/avcodec.h. - -2009-03-22 - r18163 - lavu 50.2.0 - RGB32 pixel formats - Convert the pixel formats PIX_FMT_ARGB, PIX_FMT_RGBA, PIX_FMT_ABGR, - PIX_FMT_BGRA, which were defined as macros, into enum PixelFormat values. - Conversely PIX_FMT_RGB32, PIX_FMT_RGB32_1, PIX_FMT_BGR32 and - PIX_FMT_BGR32_1 are now macros. - avcodec_get_pix_fmt() now recognizes the "rgb32" and "bgr32" aliases. - Re-sort the enum PixelFormat list accordingly. - This change breaks API/ABI backward compatibility. - -2009-03-22 - r18133 - lavu 50.1.0 - PIX_FMT_RGB5X5 endian variants - Add the enum PixelFormat values: - PIX_FMT_RGB565BE, PIX_FMT_RGB565LE, PIX_FMT_RGB555BE, PIX_FMT_RGB555LE, - PIX_FMT_BGR565BE, PIX_FMT_BGR565LE, PIX_FMT_BGR555BE, PIX_FMT_BGR555LE. - -2009-03-21 - r18116 - lavu 50.0.0 - av_random* - The Mersenne Twister PRNG implemented through the av_random* functions - was removed. Use the lagged Fibonacci PRNG through the av_lfg* functions - instead. - -2009-03-08 - r17869 - lavu 50.0.0 - AVFifoBuffer - av_fifo_init, av_fifo_read, av_fifo_write and av_fifo_realloc were dropped - and replaced by av_fifo_alloc, av_fifo_generic_read, av_fifo_generic_write - and av_fifo_realloc2. - In addition, the order of the function arguments of av_fifo_generic_read - was changed to match av_fifo_generic_write. - The AVFifoBuffer/struct AVFifoBuffer may only be used in an opaque way by - applications, they may not use sizeof() or directly access members. - -2009-03-01 - r17682 - lavf 52.31.0 - Generic metadata API - Introduce a new metadata API (see av_metadata_get() and friends). - The old API is now deprecated and should not be used anymore. This especially - includes the following structure fields: - - AVFormatContext.title - - AVFormatContext.author - - AVFormatContext.copyright - - AVFormatContext.comment - - AVFormatContext.album - - AVFormatContext.year - - AVFormatContext.track - - AVFormatContext.genre - - AVStream.language - - AVStream.filename - - AVProgram.provider_name - - AVProgram.name - - AVChapter.title diff --git a/tizen/distrib/ffmpeg/doc/TODO b/tizen/distrib/ffmpeg/doc/TODO deleted file mode 100644 index f03270e..0000000 --- a/tizen/distrib/ffmpeg/doc/TODO +++ /dev/null @@ -1,90 +0,0 @@ -ffmpeg TODO list: ----------------- - -Fabrice's TODO list: (unordered) -------------------- -Short term: - -- 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 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 -- 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) -------------------- -- optimize H264 CABAC -- more optimizations -- simper rate control - -Francois' TODO list: (unordered, without any timeframe) -------------------- -- test MACE decoder against the openquicktime one as suggested by A'rpi -- BeOS audio input grabbing backend -- BeOS video input grabbing backend -- 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. - -Baptiste's TODO list: ------------------ -- mov edit list support (AVEditList) -- YUV 10 bit per component support "2vuy" -- mxf muxer -- mpeg2 non linear quantizer - -unassigned TODO: (unordered) ---------------- -- use AVFrame for audio codecs too -- rework aviobuf.c buffering strategy and fix url_fskip -- generate optimal huffman tables for mjpeg encoding -- fix ffserver regression tests -- support xvids motion estimation -- support x264s motion estimation -- support x264s rate control -- SNOW: non translational motion compensation -- SNOW: more optimal quantization -- SNOW: 4x4 block support -- SNOW: 1/8 pel motion compensation support -- SNOW: iterative motion estimation based on subsampled images -- SNOW: try B frames and MCTF and see how their PSNR/bitrate/complexity behaves -- SNOW: try to use the wavelet transformed MC-ed reference frame as context for the entropy coder -- SNOW: think about/analyize how to make snow use multiple cpus/threads -- SNOW: finish spec -- FLAC: lossy encoding (viterbi and naive scalar quantization) -- libavfilter -- JPEG2000 decoder & encoder -- MPEG4 GMC encoding support -- macroblock based pixel format (better cache locality, somewhat complex, one paper claimed it faster for high res) -- regression tests for codecs which do not have an encoder (I+P-frame bitstream in svn) -- add support for using mplayers video filters to ffmpeg -- H264 encoder -- per MB ratecontrol (so VCD and such do work better) -- write a script which iteratively changes all functions between always_inline and noinline and benchmarks the result to find the best set of inlined functions -- convert all the non SIMD asm into small asm vs. C testcases and submit them to the gcc devels so they can improve gcc -- generic audio mixing API -- extract PES packetizer from PS muxer and use it for new TS muxer -- implement automatic AVBistreamFilter activation -- make cabac encoder use bytestream (see http://trac.videolan.org/x264/changeset/?format=diff&new=651) -- merge imdct and windowing, the current code does considerable amounts of redundant work diff --git a/tizen/distrib/ffmpeg/doc/avutil.txt b/tizen/distrib/ffmpeg/doc/avutil.txt deleted file mode 100644 index 210bd07..0000000 --- a/tizen/distrib/ffmpeg/doc/avutil.txt +++ /dev/null @@ -1,37 +0,0 @@ -AVUtil -====== -libavutil is a small lightweight library of generally useful functions. -It is not a library for code needed by both libavcodec and libavformat. - - -Overview: -========= -adler32.c adler32 checksum -aes.c AES encryption and decryption -fifo.c resizeable first in first out buffer -intfloat_readwrite.c portable reading and writing of floating point values -log.c "printf" with context and level -md5.c MD5 Message-Digest Algorithm -rational.c code to perform exact calculations with rational numbers -tree.c generic AVL tree -crc.c generic CRC checksumming code -integer.c 128bit integer math -lls.c -mathematics.c greatest common divisor, integer sqrt, integer log2, ... -mem.c memory allocation routines with guaranteed alignment -softfloat.c - -Headers: -bswap.h big/little/native-endian conversion code -x86_cpu.h a few useful macros for unifying x86-64 and x86-32 code -avutil.h -common.h -intreadwrite.h reading and writing of unaligned big/little/native-endian integers - - -Goals: -====== -* Modular (few interdependencies and the possibility of disabling individual parts during ./configure) -* Small (source and object) -* Efficient (low CPU and memory usage) -* Useful (avoid useless features almost no one needs) diff --git a/tizen/distrib/ffmpeg/doc/developer.texi b/tizen/distrib/ffmpeg/doc/developer.texi deleted file mode 100644 index edce7ea..0000000 --- a/tizen/distrib/ffmpeg/doc/developer.texi +++ /dev/null @@ -1,436 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@settitle Developer Documentation -@titlepage -@sp 7 -@center @titlefont{Developer Documentation} -@sp 3 -@end titlepage - - -@chapter Developers Guide - -@section API -@itemize @bullet -@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{libavformat/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. - -@anchor{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 will not -accept patches to remove their use unless they absolutely do not 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 do not 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 one inspired 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 Subversion repository. - -The main priority in FFmpeg is simplicity and small code size in order to -minimize the bug count. - -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 is 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. - -Casts should be used only when necessary. Unneeded parentheses -should also be avoided if they don't make the code easier to understand. - -@section Development Policy - -@enumerate -@item - Contributions should be licensed under the LGPL 2.1, including an - "or any later version" clause, or the MIT license. GPL 2 including - an "or any later version" clause is also acceptable, but LGPL is - preferred. -@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 do not 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. Also do not forget that if part B depends on part A, but A does not - depend on B, then A can and should be committed first and separate from B. - Keeping changes well split into self-contained parts makes reviewing and - understanding them on the commit log mailing list easier. This also helps - in case of debugging later on. - Also if you have doubts about splitting or not splitting, do not hesitate to - ask/discuss it on the developer mailing list. -@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 do not.). 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 (do not - 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 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 - When applying patches that have been discussed (at length) on the mailing - list, reference the thread in the log message. -@item - Do NOT commit to code actively maintained by others without permission. - Send a patch to ffmpeg-devel instead. If no one answers within a reasonable - timeframe (12h for build failures and security fixes, 3 days small changes, - 1 week for big patches) then commit your patch if you think it is OK. - Also note, the maintainer can simply ask for more time to review! -@item - Subscribe to the ffmpeg-cvslog mailing list. The diffs of all 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 - Try to keep important discussions and requests (also) on the public - developer mailing list, so that all developers can benefit from them. -@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. - Incrementing the first component means no backward compatibility to - previous versions (e.g. removal of a function from the public API). - Incrementing the second component means backward compatible change - (e.g. addition of a function to the public API or extension of an - existing data structure). - Incrementing the third component means a noteworthy binary compatible - change (e.g. encoder bug fix that matters for the decoder). -@item - Compiler warnings indicate potential bugs or code with bad style. If a type of - warning always points to correct and clean code, that warning should - be disabled, not the code changed. - Thus the remaining warnings can either be bugs or correct code. - If it is a bug, the bug has to be fixed. If it is not, the code should - be changed to not generate a warning unless that causes a slowdown - or obfuscates the code. -@item - If you add a new file, give it a proper license header. Do not copy and - paste it from a random place, use an existing file as template. -@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. - -@section Submitting patches - -First, (@pxref{Coding Rules}) above if you did not yet. - -When you submit your patch, try to send a unified diff (diff '-up' -option). We cannot read other diffs :-) - -Also please do not submit a patch which contains several unrelated changes. -Split it into separate, self-contained pieces. This does not mean splitting -file by file. Instead, make the patch as small as possible while still -keeping it as a logical unit that contains an individual change, even -if it spans multiple files. This makes reviewing your patches much easier -for us and greatly increases your chances of getting your patch applied. - -Use the patcheck tool of FFmpeg to check your patch. -The tool is located in the tools directory. - -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 will not be trashed during -transmission) to the ffmpeg-devel mailing list, see -@url{http://lists.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()') - -Also please if you send several patches, send each patch as a separate mail, -do not attach several unrelated patches to the same mail. - -Your patch will be reviewed on the mailing list. You will likely be asked -to make some changes and are expected to send in an improved version that -incorporates the requests from the review. This process may go through -several iterations. Once your patch is deemed good enough, some developer -will pick it up and commit it to the official FFmpeg tree. - -Give us a few days to react. But if some time passes without reaction, -send a reminder by email. Your patch should eventually be dealt with. - - -@section New codecs or formats checklist - -@enumerate -@item - Did you use av_cold for codec initialization and close functions? -@item - Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or - AVInputFormat/AVOutputFormat struct? -@item - Did you bump the minor version number in @file{avcodec.h} or - @file{avformat.h}? -@item - Did you register it in @file{allcodecs.c} or @file{allformats.c}? -@item - Did you add the CodecID to @file{avcodec.h}? -@item - If it has a fourcc, did you add it to @file{libavformat/riff.c}, - even if it is only a decoder? -@item - Did you add a rule to compile the appropriate files in the Makefile? - Remember to do this even if you're just adding a format to a file that is - already being compiled by some other rule, like a raw demuxer. -@item - Did you add an entry to the table of supported formats or codecs in - @file{doc/general.texi}? -@item - Did you add an entry in the Changelog? -@item - If it depends on a parser or a library, did you add that dependency in - configure? -@item - Did you "svn add" the appropriate files before commiting? -@end enumerate - -@section patch submission checklist - -@enumerate -@item - Do the regression tests pass with the patch applied? -@item - Does @code{make checkheaders} pass with the patch applied? -@item - Is the patch a unified diff? -@item - Is the patch against latest FFmpeg SVN? -@item - Are you subscribed to ffmpeg-dev? - (the list is subscribers only due to spam) -@item - Have you checked that the changes are minimal, so that the same cannot be - achieved with a smaller patch and/or simpler final code? -@item - If the change is to speed critical code, did you benchmark it? -@item - If you did any benchmarks, did you provide them in the mail? -@item - Have you checked that the patch does not introduce buffer overflows or - other security issues? -@item - Did you test your decoder or demuxer against damaged data? If no, see - tools/trasher and the noise bitstream filter. Your decoder or demuxer - should not crash or end in a (near) infinite loop when fed damaged data. -@item - Is the patch created from the root of the source tree, so it can be - applied with @code{patch -p0}? -@item - Does the patch not mix functional and cosmetic changes? -@item - Did you add tabs or trailing whitespace to the code? Both are forbidden. -@item - Is the patch attached to the email you send? -@item - Is the mime type of the patch correct? It should be text/x-diff or - text/x-patch or at least text/plain and not application/octet-stream. -@item - If the patch fixes a bug, did you provide a verbose analysis of the bug? -@item - If the patch fixes a bug, did you provide enough information, including - a sample, so the bug can be reproduced and the fix can be verified? - Note please do not attach samples >100k to mails but rather provide a - URL, you can upload to ftp://upload.ffmpeg.org -@item - Did you provide a verbose summary about what the patch does change? -@item - Did you provide a verbose explanation why it changes things like it does? -@item - Did you provide a verbose summary of the user visible advantages and - disadvantages if the patch is applied? -@item - Did you provide an example so we can verify the new feature added by the - patch easily? -@item - If you added a new file, did you insert a license header? It should be - taken from FFmpeg, not randomly copied and pasted from somewhere else. -@item - You should maintain alphabetical order in alphabetically ordered lists as - long as doing so does not break API/ABI compatibility. -@item - Lines with similar content should be aligned vertically when doing so - improves readability. -@item - Did you provide a suggestion for a clear commit log message? -@end enumerate - -@section Patch review process - -All patches posted to ffmpeg-devel will be reviewed, unless they contain a -clear note that the patch is not for SVN. -Reviews and comments will be posted as replies to the patch on the -mailing list. The patch submitter then has to take care of every comment, -that can be by resubmitting a changed patch or by discussion. Resubmitted -patches will themselves be reviewed like any other patch. If at some point -a patch passes review with no comments then it is approved, that can for -simple and small patches happen immediately while large patches will generally -have to be changed and reviewed many times before they are approved. -After a patch is approved it will be committed to the repository. - -We will review all submitted patches, but sometimes we are quite busy so -especially for large patches this can take several weeks. - -When resubmitting patches, please do not make any significant changes -not related to the comments received during review. Such patches will -be rejected. Instead, submit significant changes or new features as -separate patches. - -@section Regression tests - -Before submitting a patch (or committing to the repository), 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 output is checked immediately after each test -has run. - -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. Commands like -'make regtest-mpeg2' can be used to run a single test. By default, -make will abort if any test fails. To run all tests regardless, -use make -k. To get a more verbose output, use 'make V=1 test' or -'make V=2 test'. - -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/tizen/distrib/ffmpeg/doc/faq.texi b/tizen/distrib/ffmpeg/doc/faq.texi deleted file mode 100644 index ec01b9e..0000000 --- a/tizen/distrib/ffmpeg/doc/faq.texi +++ /dev/null @@ -1,503 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@settitle FFmpeg FAQ -@titlepage -@sp 7 -@center @titlefont{FFmpeg FAQ} -@sp 3 -@end titlepage - - -@chapter General Questions - -@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 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 Subversion HEAD. 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 Subversion HEAD". - -@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 or sponsor a developer. - -@section FFmpeg does not support codec XXX. Can you include a Windows DLL loader to support it? - -No. Windows DLLs are not portable, bloated and often slow. -Moreover FFmpeg strives to support all codecs natively. -A DLL loader is not conducive to that goal. - -@section My bug report/mail to ffmpeg-devel/user has not received any replies. - -Likely reasons -@itemize -@item We are busy and haven't had time yet to read your report or -investigate the issue. -@item You didn't follow bugreports.html. -@item You didn't use Subversion HEAD. -@item You reported a segmentation fault without gdb output. -@item You describe a problem but not how to reproduce it. -@item It's unclear if you use ffmpeg as command line tool or use -libav* from another application. -@item You speak about a video having problems on playback but -not what you use to play it. -@item We have no faint clue what you are talking about besides -that it is related to FFmpeg. -@end itemize - -@section Is there a forum for FFmpeg? I do not like mailing lists. - -You may view our mailing lists with a more forum-alike look here: -@url{http://dir.gmane.org/gmane.comp.video.ffmpeg.user}, -but, if you post, please remember that our mailing list rules still apply there. - -@section I cannot read this file although this format seems to be supported by ffmpeg. - -Even if ffmpeg can read the container format, it may not support all its -codecs. Please consult the supported codec list in the ffmpeg -documentation. - -@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 like ffdshow or Xvid installed. -@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 -always -@item mp3 -If some MP3 codec like LAME is installed. -@end table - - -@chapter Compilation - -@section @code{error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'} - -This is a bug in gcc. Do not report it to us. Instead, please report it to -the gcc developers. Note that we will not add workarounds for gcc bugs. - -Also note that (some of) the gcc developers believe this is not a bug or -not a bug they should fix: -@url{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11203}. -Then again, some of them do not know the difference between an undecidable -problem and an NP-hard problem... - -@chapter Usage - -@section ffmpeg does not work; what is wrong? - -Try a @code{make distclean} in the ffmpeg source directory before the build. If this does not help see -(@url{http://ffmpeg.org/bugreports.html}). - -@section How do I encode single pictures into movies? - -First, rename your pictures to follow a numerical sequence. -For example, img1.jpg, img2.jpg, img3.jpg,... -Then you may run: - -@example - ffmpeg -f image2 -i img%d.jpg /tmp/a.mpg -@end example - -Notice that @samp{%d} is replaced by the image number. - -@file{img%03d.jpg} means the sequence @file{img001.jpg}, @file{img002.jpg}, etc... - -If you have large number of pictures to rename, you can use the -following command to ease the burden. The command, using the bourne -shell syntax, symbolically links all files in the current directory -that match @code{*jpg} to the @file{/tmp} directory in the sequence of -@file{img001.jpg}, @file{img002.jpg} and so on. - -@example - x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done -@end example - -If you want to sequence them by oldest modified first, substitute -@code{$(ls -r -t *jpg)} in place of @code{*jpg}. - -Then run: - -@example - ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg -@end example - -The same logic is used for any image format that ffmpeg reads. - -@section How do I encode movie to single pictures? - -Use: - -@example - ffmpeg -i movie.mpg movie%d.jpg -@end example - -The @file{movie.mpg} used as input will be converted to -@file{movie1.jpg}, @file{movie2.jpg}, etc... - -Instead of relying on file format self-recognition, you may also use -@table @option -@item -vcodec ppm -@item -vcodec png -@item -vcodec mjpeg -@end table -to force the encoding. - -Applying that to the previous example: -@example - ffmpeg -i movie.mpg -f image2 -vcodec mjpeg menu%d.jpg -@end example - -Beware that there is no "jpeg" codec. Use "mjpeg" instead. - -@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 file name. - -@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://svn.ffmpeg.org/michael/trunk/patches/bttv-420-2.4.26.patch?view=co}). 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://svn.ffmpeg.org/michael/trunk/patches/bttv-comb-2.4.26.patch?view=co}) -or (@url{http://svn.ffmpeg.org/michael/trunk/patches/bttv-comb-2.6.6.patch?view=co}) -and pass 'combfilter=2'. - -@section -f jpeg doesn't work. - -Try '-f image2 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 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 in 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. - -@section How do I encode videos which play on the iPod? - -@table @option -@item needed stuff --acodec libfaac -vcodec mpeg4 width<=320 height<=240 -@item working stuff -4mv, title -@item non-working stuff -B-frames -@item example command line -ffmpeg -i input -acodec libfaac -ab 128kb -vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv -trellis 2 -aic 2 -cmp 2 -subcmp 2 -s 320x180 -metadata title=X output.mp4 -@end table - -@section How do I encode videos which play on the PSP? - -@table @option -@item needed stuff --acodec libfaac -vcodec mpeg4 width*height<=76800 width%16=0 height%16=0 -ar 24000 -r 30000/1001 or 15000/1001 -f psp -@item working stuff -4mv, title -@item non-working stuff -B-frames -@item example command line -ffmpeg -i input -acodec libfaac -ab 128kb -vcodec mpeg4 -b 1200kb -ar 24000 -mbd 2 -flags +4mv -trellis 2 -aic 2 -cmp 2 -subcmp 2 -s 368x192 -r 30000/1001 -metadata title=X -f psp output.mp4 -@item needed stuff for H.264 --acodec libfaac -vcodec libx264 width*height<=76800 width%16=0? height%16=0? -ar 48000 -coder 1 -r 30000/1001 or 15000/1001 -f psp -@item working stuff for H.264 -title, loop filter -@item non-working stuff for H.264 -CAVLC -@item example command line -ffmpeg -i input -acodec libfaac -ab 128kb -vcodec libx264 -b 1200kb -ar 48000 -mbd 2 -coder 1 -cmp 2 -subcmp 2 -s 368x192 -r 30000/1001 -metadata title=X -f psp -flags loop -trellis 2 -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 output.mp4 -@item higher resolution for newer PSP firmwares, width<=480, height<=272 --vcodec libx264 -level 21 -coder 1 -f psp -@item example command line -ffmpeg -i input -acodec libfaac -ab 128kb -ac 2 -ar 48000 -vcodec libx264 -level 21 -b 640kb -coder 1 -f psp -flags +loop -trellis 2 -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -g 250 -s 480x272 output.mp4 -@end table - -@section Which are good parameters for encoding high quality MPEG-4? - -'-mbd rd -flags +4mv+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2', -things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd'. - -@section Which are good parameters for encoding high quality MPEG-1/MPEG-2? - -'-mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -pass 1/2' -but beware the '-g 100' might cause problems with some decoders. -Things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd. - -@section Interlaced video looks very bad when encoded with ffmpeg, what is wrong? - -You should use '-flags +ilme+ildct' and maybe '-flags +alt' for interlaced -material, and try '-top 0/1' if the result looks really messed-up. - -@section How can I read DirectShow files? - -If you have built FFmpeg with @code{./configure --enable-avisynth} -(only possible on MinGW/Cygwin platforms), -then you may use any file that DirectShow can read as input. -(Be aware that this feature has been recently added, -so you will need to help yourself in case of problems.) - -Just create an "input.avs" text file with this single line ... -@example - DirectShowSource("C:\path to your file\yourfile.asf") -@end example -... and then feed that text file to FFmpeg: -@example - ffmpeg -i input.avs -@end example - -For ANY other help on Avisynth, please visit @url{http://www.avisynth.org/}. - -@section How can I join video files? - -A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to join video files by -merely concatenating them. - -Hence you may concatenate your multimedia files by first transcoding them to -these privileged formats, then using the humble @code{cat} command (or the -equally humble @code{copy} under Windows), and finally transcoding back to your -format of choice. - -@example -ffmpeg -i input1.avi -sameq intermediate1.mpg -ffmpeg -i input2.avi -sameq intermediate2.mpg -cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg -ffmpeg -i intermediate_all.mpg -sameq output.avi -@end example - -Notice that you should either use @code{-sameq} or set a reasonably high -bitrate for your intermediate and output files, if you want to preserve -video quality. - -Also notice that you may avoid the huge intermediate files by taking advantage -of named pipes, should your platform support it: - -@example -mkfifo intermediate1.mpg -mkfifo intermediate2.mpg -ffmpeg -i input1.avi -sameq -y intermediate1.mpg < /dev/null & -ffmpeg -i input2.avi -sameq -y intermediate2.mpg < /dev/null & -cat intermediate1.mpg intermediate2.mpg |\ -ffmpeg -f mpeg -i - -sameq -vcodec mpeg4 -acodec libmp3lame output.avi -@end example - -Similarly, the yuv4mpegpipe format, and the raw video, raw audio codecs also -allow concatenation, and the transcoding step is almost lossless. -When using multiple yuv4mpegpipe(s), the first line needs to be discarded -from all but the first stream. This can be accomplished by piping through -@code{tail} as seen below. Note that when piping through @code{tail} you -must use command grouping, @code{@{ ;@}}, to background properly. - -For example, let's say we want to join two FLV files into an output.flv file: - -@example -mkfifo temp1.a -mkfifo temp1.v -mkfifo temp2.a -mkfifo temp2.v -mkfifo all.a -mkfifo all.v -ffmpeg -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null & -ffmpeg -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null & -ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null & -@{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} & -cat temp1.a temp2.a > all.a & -cat temp1.v temp2.v > all.v & -ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \ - -f yuv4mpegpipe -i all.v \ - -sameq -y output.flv -rm temp[12].[av] all.[av] -@end example - -@section FFmpeg does not adhere to the -maxrate setting, some frames are bigger than maxrate/fps. - -Read the MPEG spec about video buffer verifier. - -@section I want CBR, but no matter what I do frame sizes differ. - -You do not understand what CBR is, please read the MPEG spec. -Read about video buffer verifier and constant bitrate. -The one sentence summary is that there is a buffer and the input rate is -constant, the output can vary as needed. - -@section How do I check if a stream is CBR? - -To quote the MPEG-2 spec: -"There is no way to tell that a bitstream is constant bitrate without -examining all of the vbv_delay values and making complicated computations." - - -@chapter Development - -@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.html}). - -@section Can you support my C compiler XXX? - -It depends. If your compiler is C99-compliant, then patches to support -it are likely to be welcome if they do not pollute the source code -with @code{#ifdef}s related to the compiler. - -@section Is Microsoft Visual C++ supported? - -No. Microsoft Visual C++ is not compliant to the C99 standard and does -not - among other things - support the inline assembly used in FFmpeg. -If you wish to use MSVC++ for your -project then you can link the MSVC++ code with libav* as long as -you compile the latter with a working C compiler. For more information, see -the @emph{Microsoft Visual C++ compatibility} section in the FFmpeg -documentation. - -There have been efforts to make FFmpeg compatible with MSVC++ in the -past. However, they have all been rejected as too intrusive, especially -since MinGW does the job adequately. None of the core developers -work with MSVC++ and thus this item is low priority. Should you find -the silver bullet that solves this problem, feel free to shoot it at us. - -We strongly recommend you to move over from MSVC++ to MinGW tools. - -@section Can I use FFmpeg or libavcodec under Windows? - -Yes, but the Cygwin or MinGW tools @emph{must} be used to compile FFmpeg. -Read the @emph{Windows} section in the FFmpeg documentation to find more -information. - -To get help and instructions for building FFmpeg under Windows, check out -the FFmpeg Windows Help Forum at -@url{http://ffmpeg.arrozcru.org/}. - -@section Can you add automake, libtool or autoconf support? - -No. These tools are too bloated and they complicate the build. - -@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://www.tux.org/lkml/#s15}). - -@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 stripped 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 #if CONFIG_GPL without breaking anything. So for example a new codec -or filter would be OK under GPL while a bug fix 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 I'm using libavcodec from within my C++ application but the linker complains about missing symbols which seem to be available. - -FFmpeg is a pure C project, so to use the libraries within your C++ application -you need to explicitly state that you are using a C library. You can do this by -encompassing your FFmpeg includes using @code{extern "C"}. - -See @url{http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3} - -@section I have a file in memory / a API different from *open/*read/ libc how do I use it with libavformat? - -You have to implement a URLProtocol, see libavformat/file.c in FFmpeg -and libmpdemux/demux_lavf.c in MPlayer sources. - -@section I get "No compatible shell script interpreter found." in MSys. - -The standard MSys bash (2.04) is broken. You need to install 2.05 or later. - -@section I get "./configure: line : pr: command not found" in MSys. - -The standard MSys install doesn't come with pr. You need to get it from the coreutils package. - -@section I tried to pass RTP packets into a decoder, but it doesn't work. - -RTP is a container format like any other, you must first depacketize the -codec frames/samples stored in RTP and then feed to the decoder. - -@section Where can I find libav* headers for Pascal/Delphi? - -see @url{http://www.iversenit.dk/dev/ffmpeg-headers/} - -@section Where is the documentation about ffv1, msmpeg4, asv1, 4xm? - -see @url{http://svn.ffmpeg.org/michael/trunk/docs/} - -@section How do I feed H.263-RTP (and other codecs in RTP) to libavcodec? - -Even if peculiar since it is network oriented, RTP is a container like any -other. You have to @emph{demux} RTP before feeding the payload to libavcodec. -In this specific case please look at RFC 4629 to see how it should be done. - -@section AVStream.r_frame_rate is wrong, it is much larger than the framerate. - -r_frame_rate is NOT the average framerate, it is the smallest framerate -that can accurately represent all timestamps. So no, it is not -wrong if it is larger than the average! -For example, if you have mixed 25 and 30 fps content, then r_frame_rate -will be 150. - -@bye diff --git a/tizen/distrib/ffmpeg/doc/ffmpeg-doc.texi b/tizen/distrib/ffmpeg/doc/ffmpeg-doc.texi deleted file mode 100644 index 7be11d2..0000000 --- a/tizen/distrib/ffmpeg/doc/ffmpeg-doc.texi +++ /dev/null @@ -1,956 +0,0 @@ -\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 grab video and audio from devices given that you specify the input -format and device. - -@example -ffmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /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://linux.bytesex.org/xawtv/}) by Gerd Knorr. You also -have to set the audio recording levels correctly with a -standard mixer. - -@section X11 grabbing - -FFmpeg can grab the X11 display. - -@example -ffmpeg -f x11grab -s cif -i :0.0 /tmp/out.mpg -@end example - -0.0 is display.screen number of your X11 server, same as -the DISPLAY environment variable. - -@example -ffmpeg -f x11grab -s cif -i :0.0+10,20 /tmp/out.mpg -@end example - -0.0 is display.screen number of your X11 server, same as the DISPLAY environment -variable. 10 is the x-offset and 20 the y-offset for the grabbing. - -@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 22050 Hz 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 64k /tmp/a.mp2 -ab 128k /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 800k -g 300 -bf 2 -acodec libmp3lame -ab 128k 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-libmp3lame} 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}. - -* You can extract images from a video, or create a video from many images: - -For extracting images from a video: -@example -ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg -@end example - -This will extract one video frame per second from the video and will -output them in files named @file{foo-001.jpeg}, @file{foo-002.jpeg}, -etc. Images will be rescaled to fit the new WxH values. - -If you want to extract just a limited number of frames, you can use the -above command in combination with the -vframes or -t option, or in -combination with -ss to start extracting from a certain point in time. - -For creating a video from many images: -@example -ffmpeg -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi -@end example - -The syntax @code{foo-%03d.jpeg} specifies to use a decimal number -composed of three digits padded with zeroes to express the sequence -number. It is the same syntax supported by the C printf function, but -only formats accepting a normal integer are suitable. - -* You can put many streams of the same type in the output: - -@example -ffmpeg -i test1.avi -i test2.avi -vcodec copy -acodec copy -vcodec copy -acodec copy test12.avi -newvideo -newaudio -@end example - -In addition to the first video and audio streams, the resulting -output file @file{test12.avi} will contain the second video -and the second audio stream found in the input streams list. - -The @code{-newvideo}, @code{-newaudio} and @code{-newsubtitle} -options have to be specified immediately after the name of the output -file to which you want to add them. -@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 -As a general rule, options are applied to the next specified -file. Therefore, order is important, and you can have the same -option on the command line multiple times. Each occurrence is -then applied to the next input or output file. - -* To set the video bitrate of the output file to 64kbit/s: -@example -ffmpeg -i input.avi -b 64k output.avi -@end example - -* To force the frame rate of the output file to 24 fps: -@example -ffmpeg -i input.avi -r 24 output.avi -@end example - -* To force the frame rate of the input file (valid for raw formats only) -to 1 fps and the frame rate of the output file to 24 fps: -@example -ffmpeg -r 1 -i input.m2v -r 24 output.avi -@end example - -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 - -@include fftools-common-opts.texi - -@section Main options - -@table @option - -@item -f @var{fmt} -Force format. - -@item -i @var{filename} -input file name - -@item -y -Overwrite output files. - -@item -t @var{duration} -Restrict the transcoded/captured video sequence -to the duration specified in seconds. -@code{hh:mm:ss[.xxx]} syntax is also supported. - -@item -fs @var{limit_size} -Set the file size limit. - -@item -ss @var{position} -Seek to given time position in seconds. -@code{hh:mm:ss[.xxx]} syntax is also supported. - -@item -itsoffset @var{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. - -@item -timestamp @var{time} -Set the timestamp. - -@item -metadata @var{key}=@var{value} -Set a metadata key/value pair. - -For example, for setting the title in the output file: -@example -ffmpeg -i in.avi -metadata title="my title" out.flv -@end example - -@item -v @var{number} -Set the logging verbosity level. - -@item -target @var{type} -Specify target file type ("vcd", "svcd", "dvd", "dv", "dv50", "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 -dframes @var{number} -Set the number of data frames to record. - -@item -scodec @var{codec} -Force subtitle codec ('copy' to copy stream). - -@item -newsubtitle -Add a new subtitle stream to the current output stream. - -@item -slang @var{code} -Set the ISO 639 language code (3 letters) of the current subtitle stream. - -@end table - -@section Video Options - -@table @option -@item -b @var{bitrate} -Set the video bitrate in bit/s (default = 200 kb/s). -@item -vframes @var{number} -Set the number of video frames to record. -@item -r @var{fps} -Set frame rate (Hz value, fraction or abbreviation), (default = 25). -@item -s @var{size} -Set frame size. The format is @samp{wxh} (ffserver default = 160x128, ffmpeg default = same as source). -The following abbreviations are recognized: -@table @samp -@item sqcif -128x96 -@item qcif -176x144 -@item cif -352x288 -@item 4cif -704x576 -@item 16cif -1408x1152 -@item qqvga -160x120 -@item qvga -320x240 -@item vga -640x480 -@item svga -800x600 -@item xga -1024x768 -@item uxga -1600x1200 -@item qxga -2048x1536 -@item sxga -1280x1024 -@item qsxga -2560x2048 -@item hsxga -5120x4096 -@item wvga -852x480 -@item wxga -1366x768 -@item wsxga -1600x1024 -@item wuxga -1920x1200 -@item woxga -2560x1600 -@item wqsxga -3200x2048 -@item wquxga -3840x2400 -@item whsxga -6400x4096 -@item whuxga -7680x4800 -@item cga -320x200 -@item ega -640x350 -@item hd480 -852x480 -@item hd720 -1280x720 -@item hd1080 -1920x1080 -@end table - -@item -aspect @var{aspect} -Set aspect ratio (4:3, 16:9 or 1.3333, 1.7777). -@item -croptop @var{size} -Set top crop band size (in pixels). -@item -cropbottom @var{size} -Set bottom crop band size (in pixels). -@item -cropleft @var{size} -Set left crop band size (in pixels). -@item -cropright @var{size} -Set right crop band size (in pixels). -@item -padtop @var{size} -Set top pad band size (in pixels). -@item -padbottom @var{size} -Set bottom pad band size (in pixels). -@item -padleft @var{size} -Set left pad band size (in pixels). -@item -padright @var{size} -Set right pad band size (in pixels). -@item -padcolor @var{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 @var{tolerance} -Set video bitrate tolerance (in bits, default 4000k). -Has a minimum value of: (target_bitrate/target_framerate). -In 1-pass mode, bitrate tolerance specifies how far ratecontrol is -willing to deviate from the target average bitrate value. This is -not related to min/max bitrate. Lowering tolerance too much has -an adverse effect on quality. -@item -maxrate @var{bitrate} -Set max video bitrate (in bit/s). -Requires -bufsize to be set. -@item -minrate @var{bitrate} -Set min video bitrate (in bit/s). -Most useful in setting up a CBR encode: -@example -ffmpeg -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v -@end example -It is of little use elsewise. -@item -bufsize @var{size} -Set video buffer verifier buffer size (in bits). -@item -vcodec @var{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 @var{n} -Select the pass number (1 or 2). It is used to do two-pass -video encoding. The statistics of the video are recorded in the first -pass into a log file (see also the option -passlogfile), -and in the second pass that log file is used to generate the video -at the exact requested bitrate. -On pass 1, you may just deactivate audio and set output to null, -examples for Windows and Unix: -@example -ffmpeg -i foo.mov -vcodec libxvid -pass 1 -an -f rawvideo -y NUL -ffmpeg -i foo.mov -vcodec libxvid -pass 1 -an -f rawvideo -y /dev/null -@end example - -@item -passlogfile @var{prefix} -Set two-pass log file name prefix to @var{prefix}, the default file name -prefix is ``ffmpeg2pass''. The complete file name will be -@file{PREFIX-N.log}, where N is a number specific to the output -stream. - -@item -newvideo -Add a new video stream to the current output stream. - -@item -vlang @var{code} -Set the ISO 639 language code (3 letters) of the current video stream. - -@end table - -@section Advanced Video Options - -@table @option -@item -pix_fmt @var{format} -Set pixel format. Use 'list' as parameter to show all the supported -pixel formats. -@item -sws_flags @var{flags} -Set SwScaler flags. -@item -g @var{gop_size} -Set the group of pictures size. -@item -intra -Use only intra frames. -@item -vdt @var{n} -Discard threshold. -@item -qscale @var{q} -Use fixed video quantizer scale (VBR). -@item -qmin @var{q} -minimum video quantizer scale (VBR) -@item -qmax @var{q} -maximum video quantizer scale (VBR) -@item -qdiff @var{q} -maximum difference between the quantizer scales (VBR) -@item -qblur @var{blur} -video quantizer scale blur (VBR) (range 0.0 - 1.0) -@item -qcomp @var{compression} -video quantizer scale compression (VBR) (default 0.5). -Constant of ratecontrol equation. Recommended range for default rc_eq: 0.0-1.0 - -@item -lmin @var{lambda} -minimum video lagrange factor (VBR) -@item -lmax @var{lambda} -max video lagrange factor (VBR) -@item -mblmin @var{lambda} -minimum macroblock quantizer scale (VBR) -@item -mblmax @var{lambda} -maximum macroblock quantizer scale (VBR) - -These four options (lmin, lmax, mblmin, mblmax) use 'lambda' units, -but you may use the QP2LAMBDA constant to easily convert from 'q' units: -@example -ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext -@end example - -@item -rc_init_cplx @var{complexity} -initial complexity for single pass encoding -@item -b_qfactor @var{factor} -qp factor between P- and B-frames -@item -i_qfactor @var{factor} -qp factor between P- and I-frames -@item -b_qoffset @var{offset} -qp offset between P- and B-frames -@item -i_qoffset @var{offset} -qp offset between P- and I-frames -@item -rc_eq @var{equation} -Set rate control equation (@pxref{FFmpeg formula -evaluator}) (default = @code{tex^qComp}). -@item -rc_override @var{override} -rate control override for specific intervals -@item -me_method @var{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 hex -@item umh -@item epzs -(default method) -@item full -exhaustive search (slow and marginally better than epzs) -@end table - -@item -dct_algo @var{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 @var{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 @var{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 @var{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 @var{frames} -Use 'frames' B-frames (supported for MPEG-1, MPEG-2 and MPEG-4). -@item -mbd @var{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 @var{param} -Work around encoder bugs that are not auto-detected. -@item -strict @var{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 -ilme -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 -vstats_file @var{file} -Dump video coding statistics to @var{file}. -@item -top @var{n} -top=1/bottom=0/auto=-1 field first -@item -dc @var{precision} -Intra_dc_precision. -@item -vtag @var{fourcc/tag} -Force video tag/fourcc. -@item -qphist -Show QP histogram. -@item -vbsf @var{bitstream_filter} -Bitstream filters available are "dump_extra", "remove_extra", "noise", "h264_mp4toannexb", "imxdump", "mjpegadump". -@example -ffmpeg -i h264.mp4 -vcodec copy -vbsf h264_mp4toannexb -an out.h264 -@end example -@end table - -@section Audio Options - -@table @option -@item -aframes @var{number} -Set the number of audio frames to record. -@item -ar @var{freq} -Set the audio sampling frequency (default = 44100 Hz). -@item -ab @var{bitrate} -Set the audio bitrate in bit/s (default = 64k). -@item -aq @var{q} -Set the audio quality (codec-specific, VBR). -@item -ac @var{channels} -Set the number of audio channels (default = 1). -@item -an -Disable audio recording. -@item -acodec @var{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. -@item -newaudio -Add a new audio track to the output file. If you want to specify parameters, -do so before @code{-newaudio} (@code{-acodec}, @code{-ab}, etc..). - -Mapping will be done automatically, if the number of output streams is equal to -the number of input streams, else it will pick the first one that matches. You -can override the mapping using @code{-map} as usual. - -Example: -@example -ffmpeg -i file.mpg -vcodec copy -acodec ac3 -ab 384k test.mpg -acodec mp2 -ab 192k -newaudio -@end example -@item -alang @var{code} -Set the ISO 639 language code (3 letters) of the current audio stream. -@end table - -@section Advanced Audio options: - -@table @option -@item -atag @var{fourcc/tag} -Force audio tag/fourcc. -@item -absf @var{bitstream_filter} -Bitstream filters available are "dump_extra", "remove_extra", "noise", "mp3comp", "mp3decomp". -@end table - -@section Subtitle options: - -@table @option -@item -scodec @var{codec} -Force subtitle codec ('copy' to copy stream). -@item -newsubtitle -Add a new subtitle stream to the current output stream. -@item -slang @var{code} -Set the ISO 639 language code (3 letters) of the current subtitle stream. -@item -sn -Disable subtitle recording. -@item -sbsf @var{bitstream_filter} -Bitstream filters available are "mov2textsub", "text2movsub". -@example -ffmpeg -i file.mov -an -vn -sbsf mov2textsub -scodec copy -f rawvideo sub.txt -@end example -@end table - -@section Audio/Video grab options - -@table @option -@item -vc @var{channel} -Set video grab channel (DV1394 only). -@item -tvstd @var{standard} -Set television standard (NTSC, PAL (SECAM)). -@item -isync -Synchronize read on input. -@end table - -@section Advanced options - -@table @option -@item -map @var{input_stream_id}[:@var{sync_stream_id}] -Set stream mapping from input streams to output streams. -Just enumerate the input streams in the order you want them in the output. -@var{sync_stream_id} if specified sets the input stream to sync -against. -@item -map_meta_data @var{outfile}:@var{infile} -Set meta data information of @var{outfile} from @var{infile}. -@item -debug -Print specific debug info. -@item -benchmark -Show benchmarking information at the end of an encode. -Shows CPU time used and maximum memory consumption. -Maximum memory consumption is not supported on all systems, -it will usually display as 0 if not supported. -@item -dump -Dump each input packet. -@item -hex -When dumping packets, also dump the payload. -@item -bitexact -Only use bit exact algorithms (for codec testing). -@item -ps @var{size} -Set RTP payload size in bytes. -@item -re -Read input at native frame rate. Mainly used to simulate a grab device. -@item -loop_input -Loop over the input stream. Currently it works only for image -streams. This option is used for automatic FFserver testing. -@item -loop_output @var{number_of_times} -Repeatedly loop output for formats that support looping such as animated GIF -(0 will loop the output infinitely). -@item -threads @var{count} -Thread count. -@item -vsync @var{parameter} -Video sync method. -0 Each frame is passed with its timestamp from the demuxer to the muxer -1 Frames will be duplicated and dropped to achieve exactly the requested - constant framerate. -2 Frames are passed through with their timestamp or dropped so as to prevent - 2 frames from having the same timestamp --1 Chooses between 1 and 2 depending on muxer capabilities. This is the default method. - -With -map you can select from -which stream the timestamps should be taken. You can leave either video or -audio unchanged and sync the remaining stream(s) to the unchanged one. -@item -async @var{samples_per_second} -Audio sync method. "Stretches/squeezes" the audio stream to match the timestamps, -the parameter is the maximum samples per second by which the audio is changed. --async 1 is a special case where only the start of the audio stream is corrected -without any later correction. -@item -copyts -Copy timestamps from input to output. -@item -shortest -Finish encoding when the shortest input stream ends. -@item -dts_delta_threshold -Timestamp discontinuity delta threshold. -@item -muxdelay @var{seconds} -Set the maximum demux-decode delay. -@item -muxpreload @var{seconds} -Set the initial demux-decode delay. -@end table - -@section Preset files - -A preset file contains a sequence of @var{option}=@var{value} pairs, -one for each line, specifying a sequence of options which would be -awkward to specify on the command line. Lines starting with the hash -('#') character are ignored and are used to provide comments. Check -the @file{ffpresets} directory in the FFmpeg source tree for examples. - -Preset files are specified with the @code{vpre}, @code{apre}, -@code{spre}, and @code{fpre} options. The @code{fpre} option takes the -filename of the preset instead of a preset name as input and can be -used for any kind of codec. For the @code{vpre}, @code{apre}, and -@code{spre} options, the options specified in a preset file are -applied to the currently selected codec of the same type as the preset -option. - -The argument passed to the @code{vpre}, @code{apre}, and @code{spre} -preset options identifies the preset file to use according to the -following rules: - -First ffmpeg searches for a file named @var{arg}.ffpreset in the -directories @file{$FFMPEG_DATADIR} (if set), and @file{$HOME/.ffmpeg}, and in -the datadir defined at configuration time (usually @file{PREFIX/share/ffmpeg}) -in that order. For example, if the argument is @code{libx264-max}, it will -search for the file @file{libx264-max.ffpreset}. - -If no such file is found, then ffmpeg will search for a file named -@var{codec_name}-@var{arg}.ffpreset in the above-mentioned -directories, where @var{codec_name} is the name of the codec to which -the preset file options will be applied. For example, if you select -the video codec with @code{-vcodec libx264} and use @code{-vpre max}, -then it will search for the file @file{libx264-max.ffpreset}. - -@anchor{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 statements are available: @code{ld}, @code{st}, -@code{while}. - -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 atan(x) -@item asin(x) -@item acos(x) -@item exp(x) -@item log(x) -@item abs(x) -@item squish(x) -@item gauss(x) -@item mod(x, y) -@item max(x, y) -@item min(x, y) -@item eq(x, y) -@item gte(x, y) -@item gt(x, y) -@item lte(x, y) -@item lt(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 file name 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 -protocols' 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 50k -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 Hz for MPEG audio, 22050 or 11025 for AC-3). - -@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 - -@bye diff --git a/tizen/distrib/ffmpeg/doc/ffmpeg_powerpc_performance_evaluation_howto.txt b/tizen/distrib/ffmpeg/doc/ffmpeg_powerpc_performance_evaluation_howto.txt deleted file mode 100644 index 2eb4ee7..0000000 --- a/tizen/distrib/ffmpeg/doc/ffmpeg_powerpc_performance_evaluation_howto.txt +++ /dev/null @@ -1,172 +0,0 @@ -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-svn --cc=gcc-3.3 --tune=7450 --powerpc-perf-enable -##### - -This will configure FFmpeg to install inside /usr/local/ffmpeg-svn, -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. - -If you are using CHUD 4.4.2 or later, you'll notice that MONster is -no longer available. It's been superseeded by Shark, where -configuration of PMCs is available as a plugin. - - - -V) Enabling the PMC on Linux - -On linux you may use oprofile from http://oprofile.sf.net, depending on the -version and the cpu you may need to apply a patch[1] to access a set of the -possibile counters from the userspace application. You can always define them -using the kernel interface /dev/oprofile/* . - -[1] http://dev.gentoo.org/~lu_zero/development/oprofile-g4-20060423.patch - --- -Romain Dolbeau -Luca Barbato diff --git a/tizen/distrib/ffmpeg/doc/ffplay-doc.texi b/tizen/distrib/ffmpeg/doc/ffplay-doc.texi deleted file mode 100644 index e0ca79d..0000000 --- a/tizen/distrib/ffmpeg/doc/ffplay-doc.texi +++ /dev/null @@ -1,160 +0,0 @@ -\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 - -@include fftools-common-opts.texi - -@section Main options - -@table @option -@item -x @var{width} -Force displayed width. -@item -y @var{height} -Force displayed height. -@item -s @var{size} -Set frame size (WxH or abbreviation), needed for videos which don't -contain a header with the frame size like raw YUV. -@item -an -Disable audio. -@item -vn -Disable video. -@item -ss @var{pos} -Seek to a given position in seconds. -@item -t @var{duration} -play seconds of audio/video -@item -bytes -Seek by bytes. -@item -nodisp -Disable graphical display. -@item -f @var{fmt} -Force format. -@item -window_title @var{title} -Set window title (default is the input filename). -@item -loop @var{number} -Loops movie playback times. 0 means forever. -@end table - -@section Advanced options -@table @option -@item -pix_fmt @var{format} -Set pixel format. -@item -stats -Show the stream duration, the codec parameters, the current position in -the stream and the audio/video synchronisation drift. -@item -debug -Print specific debug info. -@item -bug -Work around bugs. -@item -vismv -Visualize motion vectors. -@item -fast -Non-spec-compliant optimizations. -@item -genpts -Generate pts. -@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 @var{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. -@item -threads @var{count} -Set the thread count. -@item -ast @var{audio_stream_number} -Select the desired audio stream number, counting from 0. The number -refers to the list of all the input audio streams. If it is greater -than the number of audio streams minus one, then the last one is -selected, if it is negative the audio playback is disabled. -@item -vst @var{video_stream_number} -Select the desired video stream number, counting from 0. The number -refers to the list of all the input video streams. If it is greater -than the number of video streams minus one, then the last one is -selected, if it is negative the video playback is disabled. -@item -sst @var{subtitle_stream_number} -Select the desired subtitle stream number, counting from 0. The number -refers to the list of all the input subtitle streams. If it is greater -than the number of subtitle streams minus one, then the last one is -selected, if it is negative the subtitle rendering is disabled. -@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 t -Cycle subtitle channel. - -@item w -Show audio waves. - -@item left/right -Seek backward/forward 10 seconds. - -@item down/up -Seek backward/forward 1 minute. - -@item mouse click -Seek to percentage in file corresponding to fraction of width. - -@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/tizen/distrib/ffmpeg/doc/ffprobe-doc.texi b/tizen/distrib/ffmpeg/doc/ffprobe-doc.texi deleted file mode 100644 index 8eb3ed9..0000000 --- a/tizen/distrib/ffmpeg/doc/ffprobe-doc.texi +++ /dev/null @@ -1,121 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@settitle FFprobe Documentation -@titlepage -@sp 7 -@center @titlefont{FFprobe Documentation} -@sp 3 -@end titlepage - -@chapter Introduction - -@c man begin DESCRIPTION - -FFprobe gathers information from multimedia streams and prints it in -human- and machine-readable fashion. - -For example it can be used to check the format of the container used -by a multimedia stream and the format and type of each media stream -contained in it. - -If a filename is specified in input, ffprobe will try to open and -probe the file content. If the file cannot be opened or recognized as -a multimedia file, a positive exit code is returned. - -FFprobe may be employed both as a standalone application or in -combination with a textual filter, which may perform more -sophisticated processing, e.g. statistical processing or plotting. - -Options are used to list some of the formats supported by ffprobe or -for specifying which information to display, and for setting how -ffprobe will show it. - -FFprobe output is designed to be easily parsable by a textual filter, -and consists of one or more sections of the form: -@example -[SECTION] -key1=val1 -... -keyN=valN -[/SECTION] -@end example - -Metadata tags stored in the container or in the streams are recognized -and printed in the corresponding ``FORMAT'' or ``STREAM'' section, and -are prefixed by the string ``TAG:''. - -@c man end - -@chapter Invocation - -@section Syntax - -The generic syntax is: - -@example -@c man begin SYNOPSIS -ffprobe [options] [@file{input_file}] -@c man end -@end example - -@c man begin OPTIONS - -@include fftools-common-opts.texi - -@section Main options - -@table @option - -@item -convert_tags -Convert the tag names in the format container to the generic FFmpeg tag names. - -@item -f @var{format} -Force format to use. - -@item -unit -Show the unit of the displayed values. - -@item -prefix -Show a SI prefixes of the displayed values. -Unless ``-byte_binary_prefix'' option is used all the prefix -are decimal. - -@item -byte_binary_prefix -Force the use of binary prefixes for byte values. - -@item -sexagesimal -Use sexagesimal format HH:MM:SS.MICROSECONDS for time values. - -@item -pretty -Prettify the format of the displayed values, it corresponds to the -options ``-unit -prefix -byte_binary_prefix -sexagesimal''. - -@item -show_format -Show information about the container format of the input multimedia -stream. - -All the container format information is printed within a section with -name ``FORMAT''. - -@item -show_streams -Show information about each media stream contained in the input -multimedia stream. - -Each media stream information is printed within a dedicated section -with name ``STREAM''. - -@end table -@c man end - -@ignore - -@setfilename ffprobe -@settitle FFprobe media prober - -@c man begin SEEALSO -ffmpeg(1), ffplay(1), ffserver(1) -@c man end - -@end ignore - -@bye diff --git a/tizen/distrib/ffmpeg/doc/ffserver-doc.texi b/tizen/distrib/ffmpeg/doc/ffserver-doc.texi deleted file mode 100644 index 0a2440a..0000000 --- a/tizen/distrib/ffmpeg/doc/ffserver-doc.texi +++ /dev/null @@ -1,274 +0,0 @@ -\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). - -FFserver runs in daemon mode by default; that is, it puts itself in -the background and detaches from its TTY, unless it is launched in -debug mode or a NoDaemon option is specified in the configuration -file. - -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. - -@section How does it work? - -FFserver receives prerecorded files or FFM streams from some ffmpeg -instance as input, then streams them over RTP/RTSP/HTTP. - -An ffserver instance will listen on some port as specified in the -configuration file. You can launch one or more instances of ffmpeg and -send one or more FFM streams to the port where ffserver is expecting -to receive them. Alternately, you can make ffserver launch such ffmpeg -instances at startup. - -Input streams are called feeds, and each one is specified by a -section in the configuration file. - -For each feed you can have different output streams in various -formats, each one specified by a section in the configuration -file. - -@section Status stream - -FFserver supports an HTTP interface which exposes the current status -of the server. - -Simply point your browser to the address of the special status stream -specified in the configuration file. - -For example if you have: -@example - -Format status - -# Only allow local people to get the status -ACL allow localhost -ACL allow 192.168.0.0 192.168.255.255 - -@end example - -then the server will post a page with the status information when -the special stream @file{status.html} is requested. - -@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 900 MHz 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 -@code{--enable-libmp3lame} 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 where INPUTFILE -is some file which you can decode with ffmpeg: - -@example -./ffserver -f doc/ffserver.conf & -./ffmpeg -i INPUTFILE 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}. -@c man end - -@chapter Invocation -@section Syntax -@example -@c man begin SYNOPSIS -ffserver [options] -@c man end -@end example - -@section Options -@c man begin OPTIONS - -@include fftools-common-opts.texi - -@section Main options - -@table @option -@item -f @var{configfile} -Use @file{configfile} instead of @file{/etc/ffserver.conf}. -@item -n -Enable no-launch mode. This option disables all the Launch directives -within the various sections. FFserver will not launch any -ffmpeg instance, so you will have to launch them manually. -@item -d -Enable debug mode. This option increases log verbosity, directs log -messages to stdout and causes ffserver to run in the foreground -rather than as a daemon. -@end table -@c man end - -@ignore - -@setfilename ffserver -@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/tizen/distrib/ffmpeg/doc/ffserver.conf b/tizen/distrib/ffmpeg/doc/ffserver.conf deleted file mode 100644 index 2fbfecd..0000000 --- a/tizen/distrib/ffmpeg/doc/ffserver.conf +++ /dev/null @@ -1,356 +0,0 @@ -# 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 HTTP connections that can be handled. It has -# to be defined *before* the MaxClients parameter, since it defines the -# MaxClients maximum limit. -MaxHTTPConnections 2000 - -# 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) -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, qqvga, -# qvga, vga, svga, xga, uxga, qxga, sxga, qsxga, hsxga, wvga, wxga, wsxga, -# wuxga, woxga, wqsxga, wquxga, whsxga, whuxga, cga, ega, hd480, hd720, -# hd1080 -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/tizen/distrib/ffmpeg/doc/fftools-common-opts.texi b/tizen/distrib/ffmpeg/doc/fftools-common-opts.texi deleted file mode 100644 index 4fc271d..0000000 --- a/tizen/distrib/ffmpeg/doc/fftools-common-opts.texi +++ /dev/null @@ -1,72 +0,0 @@ -@section Generic options - -These options are shared amongst the ff* tools. - -@table @option - -@item -L -Show license. - -@item -h, -?, -help, --help -Show help. - -@item -version -Show version. - -@item -formats -Show available formats. - -The fields preceding the format names have the following meanings: -@table @samp -@item D -Decoding available -@item E -Encoding available -@end table - -@item -codecs -Show available codecs. - -The fields preceding the codec names have the following meanings: -@table @samp -@item D -Decoding available -@item E -Encoding available -@item V/A/S -Video/audio/subtitle codec -@item S -Codec supports slices -@item D -Codec supports direct rendering -@item T -Codec can handle input truncated at random locations instead of only at frame boundaries -@end table - -@item -bsfs -Show available bitstream filters. - -@item -protocols -Show available protocols. - -@item -filters -Show available libavfilter filters. - -@item -pix_fmts -Show available pixel formats. - -@item -loglevel @var{loglevel} -Set the logging level used by the library. -@var{loglevel} is a number or a string containing one of the following values: -@table @samp -@item quiet -@item panic -@item fatal -@item error -@item warning -@item info -@item verbose -@item debug -@end table - -@end table diff --git a/tizen/distrib/ffmpeg/doc/general.texi b/tizen/distrib/ffmpeg/doc/general.texi deleted file mode 100644 index dfa5b07..0000000 --- a/tizen/distrib/ffmpeg/doc/general.texi +++ /dev/null @@ -1,1061 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@settitle General Documentation -@titlepage -@sp 7 -@center @titlefont{General Documentation} -@sp 3 -@end titlepage - - -@chapter external libraries - -FFmpeg can be hooked up with a number of external libraries to add support -for more formats. None of them are used by default, their use has to be -explicitly requested by passing the appropriate flags to @file{./configure}. - -@section OpenCORE AMR - -FFmpeg can make use of the OpenCORE libraries for AMR-NB -decoding/encoding and AMR-WB decoding. - -Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the instructions for -installing the libraries. Then pass @code{--enable-libopencore-amrnb} and/or -@code{--enable-libopencore-amrwb} to configure to enable the libraries. - -Note that OpenCORE is under the Apache License 2.0 (see -@url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is -incompatible with the LGPL version 2.1 and GPL version 2. You have to -upgrade FFmpeg's license to LGPL version 3 (or if you have enabled -GPL components, GPL version 3) to use it. - - -@chapter Supported File Formats and Codecs - -You can use the @code{-formats} and @code{-codecs} options 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 Name @tab Encoding @tab Decoding @tab Comments -@item 4xm @tab @tab X - @tab 4X Technologies format, used in some games. -@item 8088flex TMV @tab @tab X -@item Adobe Filmstrip @tab X @tab X -@item Audio IFF (AIFF) @tab X @tab X -@item American Laser Games MM @tab @tab X - @tab Multimedia format used in games like Mad Dog McCree. -@item 3GPP AMR @tab X @tab X -@item ASF @tab X @tab X -@item AVI @tab X @tab X -@item AVISynth @tab @tab X -@item AVS @tab @tab X - @tab Multimedia format used by the Creature Shock game. -@item Beam Software SIFF @tab @tab X - @tab Audio and video format used in some games by Beam Software. -@item Bethesda Softworks VID @tab @tab X - @tab Used in some games from Bethesda Softworks. -@item Bink @tab @tab X - @tab Multimedia format used by many games. -@item Brute Force & Ignorance @tab @tab X - @tab Used in the game Flash Traffic: City of Angels. -@item Interplay C93 @tab @tab X - @tab Used in the game Cyberia from Interplay. -@item Delphine Software International CIN @tab @tab X - @tab Multimedia format used by Delphine Software games. -@item CD+G @tab @tab X - @tab Video format used by CD+G karaoke disks -@item Core Audio Format @tab @tab X - @tab Apple Core Audio Format -@item CRC testing format @tab X @tab -@item Creative Voice @tab X @tab X - @tab Created for the Sound Blaster Pro. -@item CRYO APC @tab @tab X - @tab Audio format used in some games by CRYO Interactive Entertainment. -@item D-Cinema audio @tab X @tab X -@item Deluxe Paint Animation @tab @tab X -@item DV video @tab X @tab X -@item DXA @tab @tab X - @tab This format is used in the non-Windows version of the Feeble Files - game and different game cutscenes repacked for use with ScummVM. -@item Electronic Arts cdata @tab @tab X -@item Electronic Arts Multimedia @tab @tab X - @tab Used in various EA games; files have extensions like WVE and UV2. -@item FFM (FFserver live feed) @tab X @tab X -@item Flash (SWF) @tab X @tab X -@item Flash 9 (AVM2) @tab X @tab X - @tab Only embedded audio is decoded. -@item FLI/FLC/FLX animation @tab @tab X - @tab .fli/.flc files -@item Flash Video (FLV) @tab @tab X - @tab Macromedia Flash video files -@item framecrc testing format @tab X @tab -@item FunCom ISS @tab @tab X - @tab Audio format used in various games from FunCom like The Longest Journey. -@item GIF Animation @tab X @tab -@item GXF @tab X @tab X - @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley - playout servers. -@item id Quake II CIN video @tab @tab X -@item id RoQ @tab X @tab X - @tab Used in Quake III, Jedi Knight 2, other computer games. -@item IEC61937 encapsulation @tab X @tab -@item IFF @tab @tab X - @tab Interchange File Format -@item Interplay MVE @tab @tab X - @tab Format used in various Interplay computer games. -@item IV8 @tab @tab X - @tab A format generated by IndigoVision 8000 video server. -@item LMLM4 @tab @tab X - @tab Used by Linux Media Labs MPEG-4 PCI boards -@item Matroska @tab X @tab X -@item Matroska audio @tab X @tab -@item MAXIS XA @tab @tab X - @tab Used in Sim City 3000; file extension .xa. -@item MD Studio @tab @tab X -@item Monkey's Audio @tab @tab X -@item Motion Pixels MVI @tab @tab X -@item MOV/QuickTime/MP4 @tab X @tab X - @tab 3GP, 3GP2, PSP, iPod variants supported -@item MP2 @tab X @tab X -@item MP3 @tab X @tab X -@item MPEG-1 System @tab X @tab X - @tab muxed audio and video, VCD format supported -@item MPEG-PS (program stream) @tab X @tab X - @tab also known as @code{VOB} file, SVCD and DVD format supported -@item MPEG-TS (transport stream) @tab X @tab X - @tab also known as DVB Transport Stream -@item MPEG-4 @tab X @tab X - @tab MPEG-4 is a variant of QuickTime. -@item MIME multipart JPEG @tab X @tab -@item MSN TCP webcam @tab @tab X - @tab Used by MSN Messenger webcam streams. -@item MTV @tab @tab X -@item Musepack @tab @tab X -@item Musepack SV8 @tab @tab X -@item Material eXchange Format (MXF) @tab X @tab X - @tab SMPTE 377M, used by D-Cinema, broadcast industry. -@item Material eXchange Format (MXF), D-10 Mapping @tab X @tab X - @tab SMPTE 386M, D-10/IMX Mapping. -@item NC camera feed @tab @tab X - @tab NC (AVIP NC4600) camera streams -@item NTT TwinVQ (VQF) @tab @tab X - @tab Nippon Telegraph and Telephone Corporation TwinVQ. -@item Nullsoft Streaming Video @tab @tab X -@item NuppelVideo @tab @tab X -@item NUT @tab X @tab X - @tab NUT Open Container Format -@item Ogg @tab X @tab X -@item TechnoTrend PVA @tab @tab X - @tab Used by TechnoTrend DVB PCI boards. -@item QCP @tab @tab X -@item raw ADTS (AAC) @tab X @tab X -@item raw AC-3 @tab X @tab X -@item raw Chinese AVS video @tab @tab X -@item raw CRI ADX @tab X @tab X -@item raw Dirac @tab X @tab X -@item raw DNxHD @tab X @tab X -@item raw DTS @tab X @tab X -@item raw E-AC-3 @tab X @tab X -@item raw FLAC @tab X @tab X -@item raw GSM @tab @tab X -@item raw H.261 @tab X @tab X -@item raw H.263 @tab X @tab X -@item raw H.264 @tab X @tab X -@item raw Ingenient MJPEG @tab @tab X -@item raw MJPEG @tab X @tab X -@item raw MLP @tab @tab X -@item raw MPEG @tab @tab X -@item raw MPEG-1 @tab @tab X -@item raw MPEG-2 @tab @tab X -@item raw MPEG-4 @tab X @tab X -@item raw NULL @tab X @tab -@item raw video @tab X @tab X -@item raw id RoQ @tab X @tab -@item raw Shorten @tab @tab X -@item raw TrueHD @tab X @tab X -@item raw VC-1 @tab @tab X -@item raw PCM A-law @tab X @tab X -@item raw PCM mu-law @tab X @tab X -@item raw PCM signed 8 bit @tab X @tab X -@item raw PCM signed 16 bit big-endian @tab X @tab X -@item raw PCM signed 16 bit little-endian @tab X @tab X -@item raw PCM signed 24 bit big-endian @tab X @tab X -@item raw PCM signed 24 bit little-endian @tab X @tab X -@item raw PCM signed 32 bit big-endian @tab X @tab X -@item raw PCM signed 32 bit little-endian @tab X @tab X -@item raw PCM unsigned 8 bit @tab X @tab X -@item raw PCM unsigned 16 bit big-endian @tab X @tab X -@item raw PCM unsigned 16 bit little-endian @tab X @tab X -@item raw PCM unsigned 24 bit big-endian @tab X @tab X -@item raw PCM unsigned 24 bit little-endian @tab X @tab X -@item raw PCM unsigned 32 bit big-endian @tab X @tab X -@item raw PCM unsigned 32 bit little-endian @tab X @tab X -@item raw PCM floating-point 32 bit big-endian @tab X @tab X -@item raw PCM floating-point 32 bit little-endian @tab X @tab X -@item raw PCM floating-point 64 bit big-endian @tab X @tab X -@item raw PCM floating-point 64 bit little-endian @tab X @tab X -@item RDT @tab @tab X -@item REDCODE R3D @tab @tab X - @tab File format used by RED Digital cameras, contains JPEG 2000 frames and PCM audio. -@item RealMedia @tab X @tab X -@item Redirector @tab @tab X -@item Renderware TeXture Dictionary @tab @tab X -@item RL2 @tab @tab X - @tab Audio and video format used in some games by Entertainment Software Partners. -@item RPL/ARMovie @tab @tab X -@item RTMP @tab X @tab X - @tab Output is performed by publishing stream to RTMP server -@item RTP @tab @tab X -@item RTSP @tab X @tab X -@item SDP @tab @tab X -@item Sega FILM/CPK @tab @tab X - @tab Used in many Sega Saturn console games. -@item Sierra SOL @tab @tab X - @tab .sol files used in Sierra Online games. -@item Sierra VMD @tab @tab X - @tab Used in Sierra CD-ROM games. -@item Smacker @tab @tab X - @tab Multimedia format used by many games. -@item Sony OpenMG (OMA) @tab @tab X - @tab Audio format used in Sony Sonic Stage and Sony Vegas. -@item Sony PlayStation STR @tab @tab X -@item Sony Wave64 (W64) @tab @tab X -@item SoX native format @tab X @tab X -@item SUN AU format @tab X @tab X -@item THP @tab @tab X - @tab Used on the Nintendo GameCube. -@item Tiertex Limited SEQ @tab @tab X - @tab Tiertex .seq files used in the DOS CD-ROM version of the game Flashback. -@item True Audio @tab @tab X -@item VC-1 test bitstream @tab X @tab X -@item WAV @tab X @tab X -@item WavPack @tab @tab X -@item WebM @tab X @tab X -@item Wing Commander III movie @tab @tab X - @tab Multimedia format used in Origin's Wing Commander III computer game. -@item Westwood Studios audio @tab @tab X - @tab Multimedia format used in Westwood Studios games. -@item Westwood Studios VQA @tab @tab X - @tab Multimedia format used in Westwood Studios games. -@item YUV4MPEG pipe @tab X @tab X -@item Psygnosis YOP @tab @tab X -@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 Name @tab Encoding @tab Decoding @tab Comments -@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 BMP @tab X @tab X - @tab Microsoft BMP image -@item DPX @tab @tab X - @tab Digital Picture Exchange -@item JPEG @tab X @tab X - @tab Progressive JPEG is not supported. -@item JPEG 2000 @tab @tab E - @tab decoding supported through external library libopenjpeg -@item JPEG-LS @tab X @tab X -@item LJPEG @tab X @tab - @tab Lossless JPEG -@item PAM @tab X @tab X - @tab PAM is a PNM extension with alpha support. -@item PBM @tab X @tab X - @tab Portable BitMap image -@item PCX @tab X @tab X - @tab PC Paintbrush -@item PGM @tab X @tab X - @tab Portable GrayMap image -@item PGMYUV @tab X @tab X - @tab PGM with U and V components in YUV 4:2:0 -@item PNG @tab X @tab X - @tab 2/4 bpp not supported yet -@item PPM @tab X @tab X - @tab Portable PixelMap image -@item PTX @tab @tab X - @tab V.Flash PTX format -@item SGI @tab X @tab X - @tab SGI RGB image format -@item Sun Rasterfile @tab @tab X - @tab Sun RAS image format -@item TIFF @tab X @tab X - @tab YUV, JPEG and some extension is not supported yet. -@item Truevision Targa @tab X @tab X - @tab Targa (.TGA) image format -@end multitable - -@code{X} means that encoding (resp. decoding) is supported. - -@code{E} means that support is provided through an external library. - -@section Video Codecs - -@multitable @columnfractions .4 .1 .1 .4 -@item Name @tab Encoding @tab Decoding @tab Comments -@item 4X Movie @tab @tab X - @tab Used in certain computer games. -@item 8088flex TMV @tab @tab X -@item 8SVX exponential @tab @tab X -@item 8SVX fibonacci @tab @tab X -@item American Laser Games MM @tab @tab X - @tab Used in games like Mad Dog McCree. -@item AMV Video @tab @tab X - @tab Used in Chinese MP3 players. -@item Apple MJPEG-B @tab @tab X -@item Apple QuickDraw @tab @tab X - @tab fourcc: qdrw -@item Asus v1 @tab X @tab X - @tab fourcc: ASV1 -@item Asus v2 @tab X @tab X - @tab fourcc: ASV2 -@item ATI VCR1 @tab @tab X - @tab fourcc: VCR1 -@item ATI VCR2 @tab @tab X - @tab fourcc: VCR2 -@item Auravision Aura @tab @tab X -@item Auravision Aura 2 @tab @tab X -@item Autodesk Animator Flic video @tab @tab X -@item Autodesk RLE @tab @tab X - @tab fourcc: AASC -@item AVS (Audio Video Standard) video @tab @tab X - @tab Video encoding used by the Creature Shock game. -@item Beam Software VB @tab @tab X -@item Bethesda VID video @tab @tab X - @tab Used in some games from Bethesda Softworks. -@item Bink Video @tab @tab X - @tab Support for version 'b' is missing. -@item Brute Force & Ignorance @tab @tab X - @tab Used in the game Flash Traffic: City of Angels. -@item C93 video @tab @tab X - @tab Codec used in Cyberia game. -@item CamStudio @tab @tab X - @tab fourcc: CSCD -@item CD+G @tab @tab X - @tab Video codec for CD+G karaoke disks -@item Chinese AVS video @tab @tab X - @tab AVS1-P2, JiZhun profile -@item Delphine Software International CIN video @tab @tab X - @tab Codec used in Delphine Software International games. -@item Cinepak @tab @tab X -@item Cirrus Logic AccuPak @tab @tab X - @tab fourcc: CLJR -@item Creative YUV (CYUV) @tab @tab X -@item Dirac @tab E @tab E - @tab supported through external libdirac/libschroedinger libraries -@item Deluxe Paint Animation @tab @tab X -@item DNxHD @tab X @tab X - @tab aka SMPTE VC3 -@item Duck TrueMotion 1.0 @tab @tab X - @tab fourcc: DUCK -@item Duck TrueMotion 2.0 @tab @tab X - @tab fourcc: TM20 -@item DV (Digital Video) @tab X @tab X -@item Feeble Files/ScummVM DXA @tab @tab X - @tab Codec originally used in Feeble Files game. -@item Electronic Arts CMV video @tab @tab X - @tab Used in NHL 95 game. -@item Electronic Arts Madcow video @tab @tab X -@item Electronic Arts TGV video @tab @tab X -@item Electronic Arts TGQ video @tab @tab X -@item Electronic Arts TQI video @tab @tab X -@item Escape 124 @tab @tab X -@item FFmpeg video codec #1 @tab X @tab X - @tab experimental lossless codec (fourcc: FFV1) -@item Flash Screen Video v1 @tab X @tab X - @tab fourcc: FSV1 -@item Flash Video (FLV) @tab X @tab X - @tab Sorenson H.263 used in Flash -@item Fraps @tab @tab X -@item H.261 @tab X @tab X -@item H.263 / H.263-1996 @tab X @tab X -@item H.263+ / H.263-1998 / H.263 version 2 @tab X @tab X -@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 @tab E @tab X - @tab encoding supported through external library libx264 -@item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration) @tab E @tab X -@item HuffYUV @tab X @tab X -@item HuffYUV FFmpeg variant @tab X @tab X -@item IBM Ultimotion @tab @tab X - @tab fourcc: ULTI -@item id Cinematic video @tab @tab X - @tab Used in Quake II. -@item id RoQ video @tab X @tab X - @tab Used in Quake III, Jedi Knight 2, other computer games. -@item IFF ILBM @tab @tab X - @tab IFF interlaved bitmap -@item IFF ByteRun1 @tab @tab X - @tab IFF run length encoded bitmap -@item Intel H.263 @tab @tab X -@item Intel Indeo 2 @tab @tab X -@item Intel Indeo 3 @tab @tab X -@item Intel Indeo 5 @tab @tab X -@item Interplay C93 @tab @tab X - @tab Used in the game Cyberia from Interplay. -@item Interplay MVE video @tab @tab X - @tab Used in Interplay .MVE files. -@item Karl Morton's video codec @tab @tab X - @tab Codec used in Worms games. -@item Kega Game Video (KGV1) @tab @tab X - @tab Kega emulator screen capture codec. -@item LCL (LossLess Codec Library) MSZH @tab @tab X -@item LCL (LossLess Codec Library) ZLIB @tab E @tab E -@item LOCO @tab @tab X -@item lossless MJPEG @tab X @tab X -@item Microsoft RLE @tab @tab X -@item Microsoft Video 1 @tab @tab X -@item Mimic @tab @tab X - @tab Used in MSN Messenger Webcam streams. -@item Miro VideoXL @tab @tab X - @tab fourcc: VIXL -@item MJPEG (Motion JPEG) @tab X @tab X -@item Motion Pixels video @tab @tab X -@item MPEG-1 video @tab X @tab X -@item MPEG-1/2 video XvMC (X-Video Motion Compensation) @tab @tab X -@item MPEG-1/2 video (VDPAU acceleration) @tab @tab X -@item MPEG-2 video @tab X @tab X -@item MPEG-4 part 2 @tab X @tab X - @ libxvidcore can be used alternatively for encoding. -@item MPEG-4 part 2 Microsoft variant version 1 @tab X @tab X -@item MPEG-4 part 2 Microsoft variant version 2 @tab X @tab X -@item MPEG-4 part 2 Microsoft variant version 3 @tab X @tab X -@item Nintendo Gamecube THP video @tab @tab X -@item NuppelVideo/RTjpeg @tab @tab X - @tab Video encoding used in NuppelVideo files. -@item On2 VP3 @tab @tab X - @tab still experimental -@item On2 VP5 @tab @tab X - @tab fourcc: VP50 -@item On2 VP6 @tab @tab X - @tab fourcc: VP60,VP61,VP62 -@item VP8 @tab X @tab X - @tab fourcc: VP80, de/encoding supported through external library libvpx -@item planar RGB @tab @tab X - @tab fourcc: 8BPS -@item Q-team QPEG @tab @tab X - @tab fourccs: QPEG, Q1.0, Q1.1 -@item QuickTime 8BPS video @tab @tab X -@item QuickTime Animation (RLE) video @tab X @tab X - @tab fourcc: 'rle ' -@item QuickTime Graphics (SMC) @tab @tab X - @tab fourcc: 'smc ' -@item QuickTime video (RPZA) @tab @tab X - @tab fourcc: rpza -@item R210 Quicktime Uncompressed RGB 10-bit @tab @tab X -@item Raw Video @tab X @tab X -@item RealVideo 1.0 @tab X @tab X -@item RealVideo 2.0 @tab X @tab X -@item RealVideo 3.0 @tab @tab X - @tab still far from ideal -@item RealVideo 4.0 @tab @tab X -@item Renderware TXD (TeXture Dictionary) @tab @tab X - @tab Texture dictionaries used by the Renderware Engine. -@item RL2 video @tab @tab X - @tab used in some games by Entertainment Software Partners -@item Sierra VMD video @tab @tab X - @tab Used in Sierra VMD files. -@item Smacker video @tab @tab X - @tab Video encoding used in Smacker. -@item SMPTE VC-1 @tab @tab X -@item Snow @tab X @tab X - @tab experimental wavelet codec (fourcc: SNOW) -@item Sony PlayStation MDEC (Motion DECoder) @tab @tab X -@item Sorenson Vector Quantizer 1 @tab X @tab X - @tab fourcc: SVQ1 -@item Sorenson Vector Quantizer 3 @tab @tab X - @tab fourcc: SVQ3 -@item Sunplus JPEG (SP5X) @tab @tab X - @tab fourcc: SP5X -@item TechSmith Screen Capture Codec @tab @tab X - @tab fourcc: TSCC -@item Theora @tab E @tab X - @tab encoding supported through external library libtheora -@item Tiertex Limited SEQ video @tab @tab X - @tab Codec used in DOS CD-ROM FlashBack game. -@item V210 Quicktime Uncompressed 4:2:2 10-bit @tab X @tab X -@item VMware Screen Codec / VMware Video @tab @tab X - @tab Codec used in videos captured by VMware. -@item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X -@item Windows Media Video 7 @tab X @tab X -@item Windows Media Video 8 @tab X @tab X -@item Windows Media Video 9 @tab @tab X - @tab not completely working -@item Wing Commander III / Xan @tab @tab X - @tab Used in Wing Commander III .MVE files. -@item Winnov WNV1 @tab @tab X -@item WMV7 @tab X @tab X -@item YAMAHA SMAF @tab X @tab X -@item Psygnosis YOP Video @tab @tab X -@item ZLIB @tab X @tab X - @tab part of LCL, encoder experimental -@item Zip Motion Blocks Video @tab X @tab X - @tab Encoder works only in PAL8. -@end multitable - -@code{X} means that encoding (resp. decoding) is supported. - -@code{E} means that support is provided through an external library. - -@section Audio Codecs - -@multitable @columnfractions .4 .1 .1 .4 -@item Name @tab Encoding @tab Decoding @tab Comments -@item 8SVX audio @tab @tab X -@item AAC @tab E @tab X - @tab encoding supported through external library libfaac -@item AC-3 @tab IX @tab X -@item ADPCM 4X Movie @tab @tab X -@item ADPCM CDROM XA @tab @tab X -@item ADPCM Creative Technology @tab @tab X - @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 -@item ADPCM Electronic Arts @tab @tab X - @tab Used in various EA titles. -@item ADPCM Electronic Arts Maxis CDROM XS @tab @tab X - @tab Used in Sim City 3000. -@item ADPCM Electronic Arts R1 @tab @tab X -@item ADPCM Electronic Arts R2 @tab @tab X -@item ADPCM Electronic Arts R3 @tab @tab X -@item ADPCM Electronic Arts XAS @tab @tab X -@item ADPCM G.726 @tab X @tab X -@item ADPCM IMA AMV @tab @tab X - @tab Used in AMV files -@item ADPCM IMA Electronic Arts EACS @tab @tab X -@item ADPCM IMA Electronic Arts SEAD @tab @tab X -@item ADPCM IMA Funcom @tab @tab X -@item ADPCM IMA QuickTime @tab X @tab X -@item ADPCM IMA Loki SDL MJPEG @tab @tab X -@item ADPCM IMA WAV @tab X @tab X -@item ADPCM IMA Westwood @tab @tab X -@item ADPCM ISS IMA @tab @tab X - @tab Used in FunCom games. -@item ADPCM IMA Duck DK3 @tab @tab X - @tab Used in some Sega Saturn console games. -@item ADPCM IMA Duck DK4 @tab @tab X - @tab Used in some Sega Saturn console games. -@item ADPCM Microsoft @tab X @tab X -@item ADPCM MS IMA @tab X @tab X -@item ADPCM Nintendo Gamecube THP @tab @tab X -@item ADPCM QT IMA @tab X @tab X -@item ADPCM SEGA CRI ADX @tab X @tab X - @tab Used in Sega Dreamcast games. -@item ADPCM Shockwave Flash @tab X @tab X -@item ADPCM SMJPEG IMA @tab @tab X - @tab Used in certain Loki game ports. -@item ADPCM Sound Blaster Pro 2-bit @tab @tab X -@item ADPCM Sound Blaster Pro 2.6-bit @tab @tab X -@item ADPCM Sound Blaster Pro 4-bit @tab @tab X -@item ADPCM Westwood Studios IMA @tab @tab X - @tab Used in Westwood Studios games like Command and Conquer. -@item ADPCM Yamaha @tab X @tab X -@item AMR-NB @tab E @tab X - @tab encoding supported through external library libopencore-amrnb -@item AMR-WB @tab @tab E - @tab decoding supported through external library libopencore-amrwb -@item Apple lossless audio @tab X @tab X - @tab QuickTime fourcc 'alac' -@item Atrac 1 @tab @tab X -@item Atrac 3 @tab @tab X -@item Bink Audio @tab @tab X - @tab Used in Bink and Smacker files in many games. -@item Delphine Software International CIN audio @tab @tab X - @tab Codec used in Delphine Software International games. -@item COOK @tab @tab X - @tab All versions except 5.1 are supported. -@item DCA (DTS Coherent Acoustics) @tab @tab X -@item DPCM id RoQ @tab X @tab X - @tab Used in Quake III, Jedi Knight 2, other computer games. -@item DPCM Interplay @tab @tab X - @tab Used in various Interplay computer games. -@item DPCM Sierra Online @tab @tab X - @tab Used in Sierra Online game audio files. -@item DPCM Sol @tab @tab X -@item DPCM Xan @tab @tab X - @tab Used in Origin's Wing Commander IV AVI files. -@item DSP Group TrueSpeech @tab @tab X -@item DV audio @tab @tab X -@item Enhanced AC-3 @tab @tab X -@item FLAC (Free Lossless Audio Codec) @tab X @tab IX -@item G.729 @tab @tab X -@item GSM @tab E @tab E - @tab supported through external library libgsm -@item GSM Microsoft variant @tab E @tab E - @tab supported through external library libgsm -@item IMC (Intel Music Coder) @tab @tab X -@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X -@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X -@item MLP (Meridian Lossless Packing) @tab @tab X - @tab Used in DVD-Audio discs. -@item Monkey's Audio @tab @tab X - @tab Only versions 3.97-3.99 are supported. -@item MP1 (MPEG audio layer 1) @tab @tab IX -@item MP2 (MPEG audio layer 2) @tab IX @tab IX -@item MP3 (MPEG audio layer 3) @tab E @tab IX - @tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported -@item MPEG-4 Audio Lossless Coding (ALS) @tab @tab X -@item Musepack SV7 @tab @tab X -@item Musepack SV8 @tab @tab X -@item Nellymoser Asao @tab X @tab X -@item PCM A-law @tab X @tab X -@item PCM mu-law @tab X @tab X -@item PCM 16-bit little-endian planar @tab @tab X -@item PCM 32-bit floating point big-endian @tab X @tab X -@item PCM 32-bit floating point little-endian @tab X @tab X -@item PCM 64-bit floating point big-endian @tab X @tab X -@item PCM 64-bit floating point little-endian @tab X @tab X -@item PCM D-Cinema audio signed 24-bit @tab X @tab X -@item PCM signed 8-bit @tab X @tab X -@item PCM signed 16-bit big-endian @tab X @tab X -@item PCM signed 16-bit little-endian @tab X @tab X -@item PCM signed 24-bit big-endian @tab X @tab X -@item PCM signed 24-bit little-endian @tab X @tab X -@item PCM signed 32-bit big-endian @tab X @tab X -@item PCM signed 32-bit little-endian @tab X @tab X -@item PCM signed 16/20/24-bit big-endian in MPEG-TS @tab @tab X -@item PCM unsigned 8-bit @tab X @tab X -@item PCM unsigned 16-bit big-endian @tab X @tab X -@item PCM unsigned 16-bit little-endian @tab X @tab X -@item PCM unsigned 24-bit big-endian @tab X @tab X -@item PCM unsigned 24-bit little-endian @tab X @tab X -@item PCM unsigned 32-bit big-endian @tab X @tab X -@item PCM unsigned 32-bit little-endian @tab X @tab X -@item PCM Zork @tab X @tab X -@item QCELP / PureVoice @tab @tab X -@item QDesign Music Codec 2 @tab @tab X - @tab There are still some distortions. -@item RealAudio 1.0 (14.4K) @tab @tab X - @tab Real 14400 bit/s codec -@item RealAudio 2.0 (28.8K) @tab @tab X - @tab Real 28800 bit/s codec -@item RealAudio 3.0 (dnet) @tab IX @tab X - @tab Real low bitrate AC-3 codec -@item RealAudio SIPR / ACELP.NET @tab @tab X -@item Shorten @tab @tab X -@item Sierra VMD audio @tab @tab X - @tab Used in Sierra VMD files. -@item Smacker audio @tab @tab X -@item Sonic @tab X @tab X - @tab experimental codec -@item Sonic lossless @tab X @tab X - @tab experimental codec -@item Speex @tab @tab E - @tab supported through external library libspeex -@item True Audio (TTA) @tab @tab X -@item TrueHD @tab @tab X - @tab Used in HD-DVD and Blu-Ray discs. -@item TwinVQ (VQF flavor) @tab @tab X -@item Vorbis @tab E @tab X - @tab A native but very primitive encoder exists. -@item WavPack @tab @tab X -@item Westwood Audio (SND1) @tab @tab X -@item Windows Media Audio 1 @tab X @tab X -@item Windows Media Audio 2 @tab X @tab X -@item Windows Media Audio Pro @tab @tab X -@item Windows Media Audio Voice @tab @tab X -@end multitable - -@code{X} means that encoding (resp. decoding) is supported. - -@code{E} means that support is provided through an external library. - -@code{I} means that an integer-only version is available, too (ensures high -performance on systems without hardware floating point support). - -@section Subtitle Formats - -@multitable @columnfractions .4 .1 .1 .1 .1 -@item Name @tab Muxing @tab Demuxing @tab Encoding @tab Decoding -@item SSA/ASS @tab X @tab X -@item DVB @tab X @tab X @tab X @tab X -@item DVD @tab X @tab X @tab X @tab X -@item PGS @tab @tab @tab @tab X -@item XSUB @tab @tab @tab X @tab X -@end multitable - -@code{X} means that the feature is supported. - -@section Network Protocols - -@multitable @columnfractions .4 .1 -@item Name @tab Support -@item file @tab X -@item Gopher @tab X -@item HTTP @tab X -@item pipe @tab X -@item RTP @tab X -@item TCP @tab X -@item UDP @tab X -@end multitable - -@code{X} means that the protocol is supported. - - -@section Input/Output Devices - -@multitable @columnfractions .4 .1 .1 -@item Name @tab Input @tab Output -@item ALSA @tab X @tab X -@item BEOS audio @tab X @tab X -@item BKTR @tab X @tab -@item DV1394 @tab X @tab -@item JACK @tab X @tab -@item LIBDC1394 @tab X @tab -@item OSS @tab X @tab X -@item Video4Linux @tab X @tab -@item Video4Linux2 @tab X @tab -@item VfW capture @tab X @tab -@item X11 grabbing @tab X @tab -@end multitable - -@code{X} means that input/output is supported. - - -@chapter Platform Specific information - -@section BeOS - -BeOS support is broken in mysterious ways. - -@section DOS - -Using a cross-compiler is preferred for various reasons. - -@subsection DJGPP - -FFmpeg cannot be compiled because of broken system headers, add -@code{--extra-cflags=-U__STRICT_ANSI__} to the configure options as a -workaround. - -@section OS/2 - -For information about compiling FFmpeg on OS/2 see -@url{http://www.edm2.com/index.php/FFmpeg}. - -@section Unix-like - -Some parts of FFmpeg cannot be built with version 2.15 of the GNU -assembler which is still provided by a few AMD64 distributions. To -make sure your compiler really uses the required version of gas -after a binutils upgrade, run: - -@example -$(gcc -print-prog-name=as) --version -@end example - -If not, then you should install a different compiler that has no -hard-coded path to gas. In the worst case pass @code{--disable-asm} -to configure. - -@subsection BSD - -BSD make will not build FFmpeg, you need to install and use GNU Make -(@file{gmake}). - -@subsubsection FreeBSD - -FreeBSD will not compile out-of-the-box due to broken system headers. -Passing @code{--extra-cflags=-D__BSD_VISIBLE} to configure will work -around the problem. This may have unexpected sideeffects, so use it at -your own risk. If you care about FreeBSD, please make an attempt at -getting the system headers fixed. - -@subsection (Open)Solaris - -GNU Make is required to build FFmpeg, so you have to invoke (@file{gmake}), -standard Solaris Make will not work. When building with a non-c99 front-end -(gcc, generic suncc) add either @code{--extra-libs=/usr/lib/values-xpg6.o} -or @code{--extra-libs=/usr/lib/64/values-xpg6.o} to the configure options -since the libc is not c99-compliant by default. The probes performed by -configure may raise an exception leading to the death of configure itself -due to a bug in the system shell. Simply invoke a different shell such as -bash directly to work around this: - -@example -bash ./configure -@end example - -@section Windows - -To get help and instructions for building FFmpeg under Windows, check out -the FFmpeg Windows Help Forum at -@url{http://ffmpeg.arrozcru.org/}. - -@subsection Native Windows compilation - -FFmpeg can be built to run natively on Windows using the MinGW tools. Install -the latest versions of MSYS and MinGW from @url{http://www.mingw.org/}. -You can find detailed installation -instructions in the download section and the FAQ. - -FFmpeg does not build out-of-the-box with the packages the automated MinGW -installer provides. It also requires coreutils to be installed and many other -packages updated to the latest version. The minimum version for some packages -are listed below: - -@itemize -@item bash 3.1 -@item msys-make 3.81-2 (note: not mingw32-make) -@item w32api 3.13 -@item mingw-runtime 3.15 -@end itemize - -FFmpeg automatically passes @code{-fno-common} to the compiler to work around -a GCC bug (see @url{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37216}). - -Within the MSYS shell, configure and make with: - -@example -./configure --enable-memalign-hack -make -make install -@end example - -This will install @file{ffmpeg.exe} along with many other development files -to @file{/usr/local}. You may specify another install path using the -@code{--prefix} option in @file{configure}. - -Notes: - -@itemize - -@item Building natively using MSYS can be sped up by disabling implicit rules -in the Makefile by calling @code{make -r} instead of plain @code{make}. This -speed up is close to non-existent for normal one-off builds and is only -noticeable when running make for a second time (for example in -@code{make install}). - -@item In order to compile FFplay, you must have the MinGW development library -of SDL. Get it from @url{http://www.libsdl.org}. -Edit the @file{bin/sdl-config} script so that it points to the correct prefix -where SDL was installed. Verify that @file{sdl-config} can be launched from -the MSYS command line. - -@item By using @code{./configure --enable-shared} when configuring FFmpeg, -you can build libavutil, libavcodec and libavformat as DLLs. - -@end itemize - -@subsection Microsoft Visual C++ compatibility - -As stated in the FAQ, FFmpeg will not compile under MSVC++. However, if you -want to use the libav* libraries in your own applications, you can still -compile those applications using MSVC++. But the libav* libraries you link -to @emph{must} be built with MinGW. However, you will not be able to debug -inside the libav* libraries, since MSVC++ does not recognize the debug -symbols generated by GCC. -We strongly recommend you to move over from MSVC++ to MinGW tools. - -This description of how to use the FFmpeg libraries with MSVC++ is based on -Microsoft Visual C++ 2005 Express Edition. If you have a different version, -you might have to modify the procedures slightly. - -@subsubsection Using static libraries - -Assuming you have just built and installed FFmpeg in @file{/usr/local}. - -@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 MSVC++ has already created for you. For example, you can copy -@file{libavformat/output-example.c} from the FFmpeg distribution. - -@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 path where the FFmpeg includes were -installed (i.e. @file{c:\msys\1.0\local\include}). -Do not add MinGW's include directory here, or the include files will -conflict with MSVC's. - -@item Still in the "Project / Properties" dialog box, select -"Linker / General" from the tree view and edit the -"Additional Library Directories" setting to contain the @file{lib} -directory where FFmpeg was installed (i.e. @file{c:\msys\1.0\local\lib}), -the directory where MinGW libs are installed (i.e. @file{c:\mingw\lib}), -and the directory where MinGW's GCC libs are installed -(i.e. @file{C:\mingw\lib\gcc\mingw32\4.2.1-sjlj}). Then select -"Linker / Input" from the tree view, and add the files @file{libavformat.a}, -@file{libavcodec.a}, @file{libavutil.a}, @file{libmingwex.a}, -@file{libgcc.a}, and any other libraries you used (i.e. @file{libz.a}) -to the end of "Additional Dependencies". - -@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. - -@item MSVC++ lacks some C99 header files that are fundamental for FFmpeg. -Get msinttypes from @url{http://code.google.com/p/msinttypes/downloads/list} -and install it in MSVC++'s include directory -(i.e. @file{C:\Program Files\Microsoft Visual Studio 8\VC\include}). - -@item MSVC++ also does not understand the @code{inline} keyword used by -FFmpeg, so you must add this line before @code{#include}ing libav*: -@example -#define inline _inline -@end example - -@item Build your application, everything should work. - -@end enumerate - -@subsubsection Using shared libraries - -This is how to create DLL and LIB files that are compatible with MSVC++: - -@enumerate - -@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}: - -@example -call "C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat" -@end example - -Alternatively, you may start the @file{Visual Studio 2005 Command Prompt}, -and run @file{c:\msys\1.0\msys.bat} from there. - -@item Within the MSYS shell, run @code{lib.exe}. If you get a help message -from @file{Microsoft (R) Library Manager}, this means your environment -variables are set up correctly, the @file{Microsoft (R) Library Manager} -is on the path and will be used by FFmpeg to create -MSVC++-compatible import libraries. - -@item Build FFmpeg with - -@example -./configure --enable-shared --enable-memalign-hack -make -make install -@end example - -Your install path (@file{/usr/local/} by default) should now have the -necessary DLL and LIB files under the @file{bin} directory. - -@end enumerate - -To use those files with MSVC++, do the same as you would do with -the static libraries, as described above. But in Step 4, -you should only need to add the directory where the LIB files are installed -(i.e. @file{c:\msys\usr\local\bin}). This is not a typo, the LIB files are -installed in the @file{bin} directory. And instead of adding @file{libxx.a} -files, you should add @file{avcodec.lib}, @file{avformat.lib}, and -@file{avutil.lib}. There should be no need for @file{libmingwex.a}, -@file{libgcc.a}, and @file{wsock32.lib}, nor any other external library -statically linked into the DLLs. The @file{bin} directory contains a bunch -of DLL files, but the ones that are actually used to run your application -are the ones with a major version number in their filenames -(i.e. @file{avcodec-51.dll}). - -@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 --target-os=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/}). - -@subsection Compilation under Cygwin - -Please use Cygwin 1.7.x as the obsolete 1.5.x Cygwin versions lack -llrint() in its C library. - -Install your Cygwin with all the "Base" packages, plus the -following "Devel" ones: -@example -binutils, gcc4-core, make, subversion, mingw-runtime, texi2html -@end example - -And the following "Utils" one: -@example -diffutils -@end example - -Then run - -@example -./configure --enable-static --disable-shared -@end example - -to make a static build. - -The current @code{gcc4-core} package is buggy and needs this flag to build -shared libraries: - -@example -./configure --enable-shared --disable-static --extra-cflags=-fno-reorder-functions -@end example - -If you want to build FFmpeg with additional libraries, download Cygwin -"Devel" packages for Ogg and Vorbis from any Cygwin packages repository: -@example -libogg-devel, libvorbis-devel -@end example - -These library packages are only available from Cygwin Ports -(@url{http://sourceware.org/cygwinports/}) : - -@example -yasm, libSDL-devel, libdirac-devel, libfaac-devel, libfaad-devel, libgsm-devel, -libmp3lame-devel, libschroedinger1.0-devel, speex-devel, libtheora-devel, -libxvidcore-devel -@end example - -The recommendation for libnut and x264 is to build them from source by -yourself, as they evolve too quickly for Cygwin Ports to be up to date. - -Cygwin 1.7.x has IPv6 support. You can add IPv6 to Cygwin 1.5.x by means -of the @code{libgetaddrinfo-devel} package, available at Cygwin Ports. - -@subsection Crosscompilation for Windows under Cygwin - -With Cygwin you can create Windows binaries that do not need the cygwin1.dll. - -Just install your Cygwin as explained before, plus these additional -"Devel" packages: -@example -gcc-mingw-core, mingw-runtime, mingw-zlib -@end example - -and add some special flags to your configure invocation. - -For a static build run -@example -./configure --target-os=mingw32 --enable-memalign-hack --enable-static --disable-shared --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin -@end example - -and for a build with shared libraries -@example -./configure --target-os=mingw32 --enable-memalign-hack --enable-shared --disable-static --extra-cflags=-mno-cygwin --extra-libs=-mno-cygwin -@end example - -@bye diff --git a/tizen/distrib/ffmpeg/doc/issue_tracker.txt b/tizen/distrib/ffmpeg/doc/issue_tracker.txt deleted file mode 100644 index e5a74db..0000000 --- a/tizen/distrib/ffmpeg/doc/issue_tracker.txt +++ /dev/null @@ -1,228 +0,0 @@ -FFmpeg's bug/patch/feature request tracker manual -================================================= - -NOTE: This is a draft. - -Overview: ---------- -FFmpeg uses Roundup for tracking issues, new issues and changes to -existing issues can be done through a web interface and through email. -It is possible to subscribe to individual issues by adding yourself to the -nosy list or to subscribe to the ffmpeg-issues mailing list which receives -a mail for every change to every issue. Replies to such mails will also -be properly added to the respective issue. -(the above does all work already after light testing) -The subscription URL for the ffmpeg-issues list is: -http://live.polito/mailman/listinfo/ffmpeg-issues -The URL of the webinterface of the tracker is: -http(s)://roundup.ffmpeg/roundup/ffmpeg/ -Note the URLs in this document are obfuscated, you must append the top level -domain for non-profit organizations to the tracker, and of Italy to the -mailing list. - -Email Interface: ----------------- -There is a mailing list to which all new issues and changes to existing issues -are sent. You can subscribe through -http://live.polito/mailman/listinfo/ffmpeg-issues -Replies to messages there will have their text added to the specific issues. -Attachments will be added as if they had been uploaded via the web interface. -You can change the status, substatus, topic, ... by changing the subject in -your reply like: -Re: [issue94] register_avcodec and allcodecs.h [type=patch;status=open;substatus=approved] -Roundup will then change things as you requested and remove the [...] from -the subject before forwarding the mail to the mailing list. - - -NOTE: issue = (bug report || patch || feature request) - -Type: ------ -bug - An error, flaw, mistake, failure, or fault in FFmpeg or libav* that - prevents it from behaving as intended. - -feature request - Request of support for encoding or decoding of a new codec, container - or variant. - Request of support for more, less or plain different output or behavior - where the current implementation cannot be considered wrong. - -patch - A patch as generated by diff which conforms to the patch submission and - development policy. - - -Priority: ---------- -critical - Bugs and patches which deal with data loss and security issues. - No feature request can be critical. - -important - Bugs which make FFmpeg unusable for a significant number of users, and - patches fixing them. - Examples here might be completely broken MPEG-4 decoding or a build issue - on Linux. - While broken 4xm decoding or a broken OS/2 build would not be important, - the separation to normal is somewhat fuzzy. - For feature requests this priority would be used for things many people - want. - -normal - - -minor - Bugs and patches about things like spelling errors, "mp2" instead of - "mp3" being shown and such. - Feature requests about things few people want or which do not make a big - difference. - -wish - Something that is desirable to have but that there is no urgency at - all to implement, e.g. something completely cosmetic like a website - restyle or a personalized doxy template or the FFmpeg logo. - This priority is not valid for bugs. - - -Status: -------- -new - initial state - -open - intermediate states - -closed - final state - - -Type/Status/Substatus: ----------- -*/new/new - Initial state of new bugs, patches and feature requests submitted by - users. - -*/open/open - Issues which have been briefly looked at and which did not look outright - invalid. - This implicates that no real more detailed state applies yet. Conversely, - the more detailed states below implicate that the issue has been briefly - looked at. - -*/closed/duplicate - Bugs, patches or feature requests which are duplicates. - Note that patches dealing with the same thing in a different way are not - duplicates. - Note, if you mark something as duplicate, do not forget setting the - superseder so bug reports are properly linked. - -*/closed/invalid - Bugs caused by user errors, random ineligible or otherwise nonsense stuff. - -*/closed/needs_more_info - Issues for which some information has been requested by the developers, - but which has not been provided by anyone within reasonable time. - -bug/open/reproduced - Bugs which have been reproduced. - -bug/open/analyzed - Bugs which have been analyzed and where it is understood what causes them - and which exact chain of events triggers them. This analysis should be - available as a message in the bug report. - Note, do not change the status to analyzed without also providing a clear - and understandable analysis. - This state implicates that the bug either has been reproduced or that - reproduction is not needed as the bug is already understood. - -bug/open/needs_more_info - Bug reports which are incomplete and or where more information is needed - from the submitter or another person who can provide it. - This state implicates that the bug has not been analyzed or reproduced. - Note, the idea behind needs_more_info is to offload work from the - developers to the users whenever possible. - -bug/closed/fixed - Bugs which have to the best of our knowledge been fixed. - -bug/closed/wont_fix - Bugs which we will not fix. Possible reasons include legality, high - complexity for the sake of supporting obscure corner cases, speed loss - for similarly esoteric purposes, et cetera. - This also means that we would reject a patch. - If we are just too lazy to fix a bug then the correct state is open - and unassigned. Closed means that the case is closed which is not - the case if we are just waiting for a patch. - -bug/closed/works_for_me - Bugs for which sufficient information was provided to reproduce but - reproduction failed - that is the code seems to work correctly to the - best of our knowledge. - -patch/open/approved - Patches which have been reviewed and approved by a developer. - Such patches can be applied anytime by any other developer after some - reasonable testing (compile + regression tests + does the patch do - what the author claimed). - -patch/open/needs_changes - Patches which have been reviewed and need changes to be accepted. - -patch/closed/applied - Patches which have been applied. - -patch/closed/rejected - Patches which have been rejected. - -feature_request/open/needs_more_info - Feature requests where it is not clear what exactly is wanted - (these also could be closed as invalid ...). - -feature_request/closed/implemented - Feature requests which have been implemented. - -feature_request/closed/wont_implement - Feature requests which will not be implemented. The reasons here could - be legal, philosophical or others. - -Note, please do not use type-status-substatus combinations other than the -above without asking on ffmpeg-dev first! - -Note2, if you provide the requested info do not forget to remove the -needs_more_info substate. - -Topic: ------- -A topic is a tag you should add to your issue in order to make grouping them -easier. - -avcodec - issues in libavcodec/* - -avformat - issues in libavformat/* - -avutil - issues in libavutil/* - -regression test - issues in tests/* - -ffmpeg - issues in or related to ffmpeg.c - -ffplay - issues in or related to ffplay.c - -ffserver - issues in or related to ffserver.c - -build system - issues in or related to configure/Makefile - -regression - bugs which were working in a past revision - -roundup - issues related to our issue tracker diff --git a/tizen/distrib/ffmpeg/doc/libavfilter.texi b/tizen/distrib/ffmpeg/doc/libavfilter.texi deleted file mode 100644 index 20ef445..0000000 --- a/tizen/distrib/ffmpeg/doc/libavfilter.texi +++ /dev/null @@ -1,307 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@settitle Libavfilter Documentation -@titlepage -@sp 7 -@center @titlefont{Libavfilter Documentation} -@sp 3 -@end titlepage - - -@chapter Introduction - -Libavfilter is the filtering API of FFmpeg. It is the substitute of the -now deprecated 'vhooks' and started as a Google Summer of Code project. - -Integrating libavfilter into the main FFmpeg repository is a work in -progress. If you wish to try the unfinished development code of -libavfilter then check it out from the libavfilter repository into -some directory of your choice by: - -@example - svn checkout svn://svn.ffmpeg.org/soc/libavfilter -@end example - -And then read the README file in the top directory to learn how to -integrate it into ffmpeg and ffplay. - -But note that there may still be serious bugs in the code and its API -and ABI should not be considered stable yet! - -@chapter Tutorial - -In libavfilter, it is possible for filters to have multiple inputs and -multiple outputs. -To illustrate the sorts of things that are possible, we can -use a complex filter graph. For example, the following one: - -@example -input --> split --> fifo -----------------------> overlay --> output - | ^ - | | - +------> fifo --> crop --> vflip --------+ -@end example - -splits the stream in two streams, sends one stream through the crop filter -and the vflip filter before merging it back with the other stream by -overlaying it on top. You can use the following command to achieve this: - -@example -./ffmpeg -i in.avi -s 240x320 -vfilters "[in] split [T1], fifo, [T2] overlay= 0:240 [out]; [T1] fifo, crop=0:0:-1:240, vflip [T2] -@end example - -where input_video.avi has a vertical resolution of 480 pixels. The -result will be that in output the top half of the video is mirrored -onto the bottom half. - -Video filters are loaded using the @var{-vfilters} option passed to -ffmpeg or to ffplay. Filters in the same linear chain are separated by -commas. In our example, @var{split, fifo, overlay} are in one linear -chain, and @var{fifo, crop, vflip} are in another. The points where -the linear chains join are labeled by names enclosed in square -brackets. In our example, that is @var{[T1]} and @var{[T2]}. The magic -labels @var{[in]} and @var{[out]} are the points where video is input -and output. - -Some filters take in input a list of parameters: they are specified -after the filter name and an equal sign, and are separated each other -by a semicolon. - -There exist so-called @var{source filters} that do not have a video -input, and we expect in the future some @var{sink filters} that will -not have video output. - -@chapter graph2dot - -The @file{graph2dot} program included in the FFmpeg @file{tools} -directory can be used to parse a filter graph description and issue a -corresponding textual representation in the dot language. - -Invoke the command: -@example -graph2dot -h -@end example - -to see how to use @file{graph2dot}. - -You can then pass the dot description to the @file{dot} program (from -the graphviz suite of programs) and obtain a graphical representation -of the filter graph. - -For example the sequence of commands: -@example -echo @var{GRAPH_DESCRIPTION} | \ -tools/graph2dot -o graph.tmp && \ -dot -Tpng graph.tmp -o graph.png && \ -display graph.png -@end example - -can be used to create and display an image representing the graph -described by the @var{GRAPH_DESCRIPTION} string. - -@chapter Available video filters - -When you configure your FFmpeg build, you can disable any of the -existing video filters. -The configure output will show the video filters included in your -build. - -Below is a description of the currently available video filters. - -@section crop - -Crop the input video to @var{x}:@var{y}:@var{width}:@var{height}. - -@example -./ffmpeg -i in.avi -vfilters "crop=0:0:0:240" out.avi -@end example - -@var{x} and @var{y} specify the position of the top-left corner of the -output (non-cropped) area. - -The default value of @var{x} and @var{y} is 0. - -The @var{width} and @var{height} parameters specify the width and height -of the output (non-cropped) area. - -A value of 0 is interpreted as the maximum possible size contained in -the area delimited by the top-left corner at position x:y. - -For example the parameters: - -@example -"crop=100:100:0:0" -@end example - -will delimit the rectangle with the top-left corner placed at position -100:100 and the right-bottom corner corresponding to the right-bottom -corner of the input image. - -The default value of @var{width} and @var{height} is 0. - -@section format - -Convert the input video to one of the specified pixel formats. -Libavfilter will try to pick one that is supported for the input to -the next filter. - -The filter accepts a list of pixel format names, separated by ``:'', -for example ``yuv420p:monow:rgb24''. - -The following command: - -@example -./ffmpeg -i in.avi -vfilters "format=yuv420p" out.avi -@end example - -will convert the input video to the format ``yuv420p''. - -@section noformat - -Force libavfilter not to use any of the specified pixel formats for the -input to the next filter. - -The filter accepts a list of pixel format names, separated by ``:'', -for example ``yuv420p:monow:rgb24''. - -The following command: - -@example -./ffmpeg -i in.avi -vfilters "noformat=yuv420p, vflip" out.avi -@end example - -will make libavfilter use a format different from ``yuv420p'' for the -input to the vflip filter. - -@section null - -Pass the source unchanged to the output. - -@section scale - -Scale the input video to @var{width}:@var{height} and/or convert the image format. - -For example the command: - -@example -./ffmpeg -i in.avi -vfilters "scale=200:100" out.avi -@end example - -will scale the input video to a size of 200x100. - -If the input image format is different from the format requested by -the next filter, the scale filter will convert the input to the -requested format. - -If the value for @var{width} or @var{height} is 0, the respective input -size is used for the output. - -If the value for @var{width} or @var{height} is -1, the scale filter will -use, for the respective output size, a value that maintains the aspect -ratio of the input image. - -The default value of @var{width} and @var{height} is 0. - -@section slicify - -Pass the images of input video on to next video filter as multiple -slices. - -@example -./ffmpeg -i in.avi -vfilters "slicify=32" out.avi -@end example - -The filter accepts the slice height as parameter. If the parameter is -not specified it will use the default value of 16. - -Adding this in the beginning of filter chains should make filtering -faster due to better use of the memory cache. - -@section unsharp - -Sharpen or blur the input video. It accepts the following parameters: - -@multitable @columnfractions .2 .5 .1 .1 .1 -@headitem Name @tab Description @tab Min @tab Max @tab Default -@item @var{luma_msize_x} -@tab Luma matrix horizontal size -@tab 3 -@tab 13 -@tab 5 -@item @var{luma_msize_y} -@tab Luma matrix vertical size -@tab 3 -@tab 13 -@tab 5 -@item @var{luma_amount} -@tab Luma effect strength -@tab -2.0 -@tab 5.0 -@tab 1.0 -@item @var{chroma_msize_x} -@tab Chroma matrix horizontal size -@tab 3 -@tab 13 -@tab 0 -@item @var{chroma_msize_y} -@tab Chroma matrix vertical size -@tab 3 -@tab 13 -@tab 0 -@item @var{chroma_amount} -@tab Chroma effect strength -@tab -2.0 -@tab 5.0 -@tab 0.0 -@end multitable - -Negative values for the amount will blur the input video, while positive -values will sharpen. All parameters are optional and default to the -equivalent of the string '5:5:1.0:0:0:0.0'. - -@example -# Strong luma sharpen effect parameters -unsharp=7:7:2.5 - -# Strong blur of both luma and chroma parameters -unsharp=7:7:-2:7:7:-2 - -# Use the default values with @command{ffmpeg} -./ffmpeg -i in.avi -vfilters "unsharp" out.mp4 -@end example - -@section vflip - -Flip the input video vertically. - -@example -./ffmpeg -i in.avi -vfilters "vflip" out.avi -@end example - -@chapter Available video sources - -Below is a description of the currently available video sources. - -@section nullsrc - -Null video source, never return images. It is mainly useful as a -template and to be employed in analysis / debugging tools. - -It accepts as optional parameter a string of the form -@var{width}:@var{height}, where @var{width} and @var{height} specify the size of -the configured source. - -The default values of @var{width} and @var{height} are respectively 352 -and 288 (corresponding to the CIF size format). - -@chapter Available video sinks - -Below is a description of the currently available video sinks. - -@section nullsink - -Null video sink, do absolutely nothing with the input video. It is -mainly useful as a template and to be employed in analysis / debugging -tools. - -@bye diff --git a/tizen/distrib/ffmpeg/doc/optimization.txt b/tizen/distrib/ffmpeg/doc/optimization.txt deleted file mode 100644 index 5469adc..0000000 --- a/tizen/distrib/ffmpeg/doc/optimization.txt +++ /dev/null @@ -1,235 +0,0 @@ -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 x86/ 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 x86 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 recommended to look at older -revisions of the interesting files (for a web frontend try ViewVC at -http://svn.ffmpeg.org/ffmpeg/trunk/). -Alternatively, look into the other architecture-specific versions in -the x86/, 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://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel) - - -When is an optimization justified? ----------------------------------- -Normally, clean and simple optimizations for widely used codecs are -justified even if they only achieve an overall speedup of 0.1%. These -speedups accumulate and can make a big difference after awhile. Also, if -none of the following factors get worse due to an optimization -- speed, -binary code size, source size, source readability -- and at least one -factor improves, then an optimization is always a good idea even if the -overall gain is less than 0.1%. For obscure codecs that are not often -used, the goal is more toward keeping the code clean, small, and -readable instead of making it 1% faster. - - -WTF is that function good for ....: ------------------------------------ -The primary purpose of this list is to avoid wasting time optimizing 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. - -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); - - -General Tips: -------------- -Use asm loops like: -__asm__( - "1: .... - ... - "jump_instruciton .... -Do not use C loops: -do{ - __asm__( - ... -}while() - -Use __asm__() instead of intrinsics. The latter requires a good optimizing compiler -which gcc is not. - - -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 - - -ARM-specific: -------------- -ARM Architecture Reference Manual (up to ARMv5TE): -http://www.arm.com/community/university/eulaarmarm.html - -Procedure Call Standard for the ARM Architecture: -http://www.arm.com/pdfs/aapcs.pdf - -Optimization guide for ARM9E (used in Nokia 770 Internet Tablet): -http://infocenter.arm.com/help/topic/com.arm.doc.ddi0240b/DDI0240A.pdf -Optimization guide for ARM11 (used in Nokia N800 Internet Tablet): -http://infocenter.arm.com/help/topic/com.arm.doc.ddi0211j/DDI0211J_arm1136_r1p5_trm.pdf -Optimization guide for Intel XScale (used in Sharp Zaurus PDA): -http://download.intel.com/design/intelxscale/27347302.pdf -Intel Wireless MMX2 Coprocessor: Programmers Reference Manual -http://download.intel.com/design/intelxscale/31451001.pdf - -PowerPC-specific: ------------------ -PowerPC32/AltiVec PIM: -www.freescale.com/files/32bit/doc/ref_manual/ALTIVECPEM.pdf - -PowerPC32/AltiVec PEM: -www.freescale.com/files/32bit/doc/ref_manual/ALTIVECPIM.pdf - -CELL/SPU: -http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/30B3520C93F437AB87257060006FFE5E/$file/Language_Extensions_for_CBEA_2.4.pdf -http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/9F820A5FFA3ECE8C8725716A0062585F/$file/CBE_Handbook_v1.1_24APR2007_pub.pdf - -SPARC-specific: ---------------- -SPARC Joint Programming Specification (JPS1): Commonality -http://www.fujitsu.com/downloads/PRMPWR/JPS1-R1.0.4-Common-pub.pdf - -UltraSPARC III Processor User's Manual (contains instruction timings) -http://www.sun.com/processors/manuals/USIIIv2.pdf - -VIS Whitepaper (contains optimization guidelines) -http://www.sun.com/processors/vis/download/vis/vis_whitepaper.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/tizen/distrib/ffmpeg/doc/rate_distortion.txt b/tizen/distrib/ffmpeg/doc/rate_distortion.txt deleted file mode 100644 index a7d2c87..0000000 --- a/tizen/distrib/ffmpeg/doc/rate_distortion.txt +++ /dev/null @@ -1,61 +0,0 @@ -A Quick Description Of Rate Distortion Theory. - -We want to encode a video, picture or piece of music optimally. What does -"optimally" really mean? It means that we want to get the best quality at a -given filesize OR we want to get the smallest filesize at a given quality -(in practice, these 2 goals are usually the same). - -Solving this directly is not practical; trying all byte sequences 1 -megabyte in length and selecting the "best looking" sequence will yield -256^1000000 cases to try. - -But first, a word about quality, which is also called distortion. -Distortion can be quantified by almost any quality measurement one chooses. -Commonly, the sum of squared differences is used but more complex methods -that consider psychovisual effects can be used as well. It makes no -difference in this discussion. - - -First step: that rate distortion factor called lambda... -Let's consider the problem of minimizing: - - distortion + lambda*rate - -rate is the filesize -distortion is the quality -lambda is a fixed value choosen as a tradeoff between quality and filesize -Is this equivalent to finding the best quality for a given max -filesize? The answer is yes. For each filesize limit there is some lambda -factor for which minimizing above will get you the best quality (using your -chosen quality measurement) at the desired (or lower) filesize. - - -Second step: splitting the problem. -Directly splitting the problem of finding the best quality at a given -filesize is hard because we do not know how many bits from the total -filesize should be allocated to each of the subproblems. But the formula -from above: - - distortion + lambda*rate - -can be trivially split. Consider: - - (distortion0 + distortion1) + lambda*(rate0 + rate1) - -This creates a problem made of 2 independent subproblems. The subproblems -might be 2 16x16 macroblocks in a frame of 32x16 size. To minimize: - - (distortion0 + distortion1) + lambda*(rate0 + rate1) - -we just have to minimize: - - distortion0 + lambda*rate0 - -and - - distortion1 + lambda*rate1 - -I.e, the 2 problems can be solved independently. - -Author: Michael Niedermayer -Copyright: LGPL diff --git a/tizen/distrib/ffmpeg/doc/snow.txt b/tizen/distrib/ffmpeg/doc/snow.txt deleted file mode 100644 index f991339..0000000 --- a/tizen/distrib/ffmpeg/doc/snow.txt +++ /dev/null @@ -1,630 +0,0 @@ -============================================= -Snow Video Codec Specification Draft 20080110 -============================================= - -Introduction: -============= -This specification describes the Snow bitstream syntax and semantics as -well as the formal Snow decoding process. - -The decoding process is described precisely and any compliant decoder -MUST produce the exact same output for a spec-conformant Snow stream. -For encoding, though, any process which generates a stream compliant to -the syntactical and semantic requirements and which is decodable by -the process described in this spec shall be considered a conformant -Snow encoder. - -Definitions: -============ - -MUST the specific part must be done to conform to this standard -SHOULD it is recommended to be done that way, but not strictly required - -ilog2(x) is the rounded down logarithm of x with basis 2 -ilog2(0) = 0 - -Type definitions: -================= - -b 1-bit range coded -u unsigned scalar value range coded -s signed scalar value range coded - - -Bitstream syntax: -================= - -frame: - header - prediction - residual - -header: - keyframe b MID_STATE - if(keyframe || always_reset) - reset_contexts - if(keyframe){ - version u header_state - always_reset b header_state - temporal_decomposition_type u header_state - temporal_decomposition_count u header_state - spatial_decomposition_count u header_state - colorspace_type u header_state - chroma_h_shift u header_state - chroma_v_shift u header_state - spatial_scalability b header_state - max_ref_frames-1 u header_state - qlogs - } - if(!keyframe){ - update_mc b header_state - if(update_mc){ - for(plane=0; plane<2; plane++){ - diag_mc b header_state - htaps/2-1 u header_state - for(i= p->htaps/2; i; i--) - |hcoeff[i]| u header_state - } - } - update_qlogs b header_state - if(update_qlogs){ - spatial_decomposition_count u header_state - qlogs - } - } - - spatial_decomposition_type s header_state - qlog s header_state - mv_scale s header_state - qbias s header_state - block_max_depth s header_state - -qlogs: - for(plane=0; plane<2; plane++){ - quant_table[plane][0][0] s header_state - for(level=0; level < spatial_decomposition_count; level++){ - quant_table[plane][level][1]s header_state - quant_table[plane][level][3]s header_state - } - } - -reset_contexts - *_state[*]= MID_STATE - -prediction: - for(y=0; ylevel + 2*top->level + topleft->level + topright->level - leaf b block_state[4 + s_context] - } - if(level==max_block_depth || leaf){ - intra b block_state[1 + left->intra + top->intra] - if(intra){ - y_diff s block_state[32] - cb_diff s block_state[64] - cr_diff s block_state[96] - }else{ - ref_context= ilog2(2*left->ref) + ilog2(2*top->ref) - if(ref_frames > 1) - ref u block_state[128 + 1024 + 32*ref_context] - mx_context= ilog2(2*abs(left->mx - top->mx)) - my_context= ilog2(2*abs(left->my - top->my)) - mvx_diff s block_state[128 + 32*(mx_context + 16*!!ref)] - mvy_diff s block_state[128 + 32*(my_context + 16*!!ref)] - } - }else{ - block(level+1) - block(level+1) - block(level+1) - block(level+1) - } - } - - -residual: - residual2(luma) - residual2(chroma_cr) - residual2(chroma_cb) - -residual2: - for(level=0; level0 and <10 - -hcoeff - half pel interpolation filter coefficients, hcoeff[0] are the 2 middle - coefficients [1] are the next outer ones and so on, resulting in a filter - like: ...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... - the sign of the coefficients is not explicitly stored but alternates - after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... - hcoeff[0] is not explicitly stored but found by subtracting the sum - of all stored coefficients with signs from 32 - hcoeff[0]= 32 - hcoeff[1] - hcoeff[2] - ... - a good choice for hcoeff and htaps is - htaps= 6 - hcoeff={40,-10,2} - an alternative which requires more computations at both encoder and - decoder side and may or may not be better is - htaps= 8 - hcoeff={42,-14,6,-2} - - -ref_frames - minimum of the number of available reference frames and max_ref_frames - for example the first frame after a key frame always has ref_frames=1 - -spatial_decomposition_type - wavelet type - 0 is a 9/7 symmetric compact integer wavelet - 1 is a 5/3 symmetric compact integer wavelet - others are reserved - stored as delta from last, last is reset to 0 if always_reset || keyframe - -qlog - quality (logarthmic quantizer scale) - stored as delta from last, last is reset to 0 if always_reset || keyframe - -mv_scale - stored as delta from last, last is reset to 0 if always_reset || keyframe - FIXME check that everything works fine if this changes between frames - -qbias - dequantization bias - stored as delta from last, last is reset to 0 if always_reset || keyframe - -block_max_depth - maximum depth of the block tree - stored as delta from last, last is reset to 0 if always_reset || keyframe - -quant_table - quantiztation table - - -Highlevel bitstream structure: -============================= - -------------------------------------------- -| Header | - -------------------------------------------- -| ------------------------------------ | -| | Block0 | | -| | split? | | -| | yes no | | -| | ......... intra? | | -| | : Block01 : yes no | | -| | : Block02 : ....... .......... | | -| | : Block03 : : y DC : : ref index: | | -| | : Block04 : : cb DC : : motion x : | | -| | ......... : cr DC : : motion y : | | -| | ....... .......... | | -| ------------------------------------ | -| ------------------------------------ | -| | Block1 | | -| ... | - -------------------------------------------- -| ------------ ------------ ------------ | -|| Y subbands | | Cb subbands| | Cr subbands|| -|| --- --- | | --- --- | | --- --- || -|| |LL0||HL0| | | |LL0||HL0| | | |LL0||HL0| || -|| --- --- | | --- --- | | --- --- || -|| --- --- | | --- --- | | --- --- || -|| |LH0||HH0| | | |LH0||HH0| | | |LH0||HH0| || -|| --- --- | | --- --- | | --- --- || -|| --- --- | | --- --- | | --- --- || -|| |HL1||LH1| | | |HL1||LH1| | | |HL1||LH1| || -|| --- --- | | --- --- | | --- --- || -|| --- --- | | --- --- | | --- --- || -|| |HH1||HL2| | | |HH1||HL2| | | |HH1||HL2| || -|| ... | | ... | | ... || -| ------------ ------------ ------------ | - -------------------------------------------- - -Decoding process: -================= - - ------------ - | | - | Subbands | - ------------ | | - | | ------------ - | Intra DC | | - | | LL0 subband prediction - ------------ | - \ Dequantizaton - ------------------- \ | -| Reference frames | \ IDWT -| ------- ------- | Motion \ | -||Frame 0| |Frame 1|| Compensation . OBMC v ------- -| ------- ------- | --------------. \------> + --->|Frame n|-->output -| ------- ------- | ------- -||Frame 2| |Frame 3||<----------------------------------/ -| ... | - ------------------- - - -Range Coder: -============ - -Binary Range Coder: -------------------- -The implemented range coder is an adapted version based upon "Range encoding: -an algorithm for removing redundancy from a digitised message." by G. N. N. -Martin. -The symbols encoded by the Snow range coder are bits (0|1). The -associated probabilities are not fix but change depending on the symbol mix -seen so far. - - -bit seen | new state ----------+----------------------------------------------- - 0 | 256 - state_transition_table[256 - old_state]; - 1 | state_transition_table[ old_state]; - -state_transition_table = { - 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, -104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, -119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, -134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, -150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, -165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, -180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, -195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, -210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, -226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, -241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0}; - -FIXME - - -Range Coding of integers: -------------------------- -FIXME - - -Neighboring Blocks: -=================== -left and top are set to the respective blocks unless they are outside of -the image in which case they are set to the Null block - -top-left is set to the top left block unless it is outside of the image in -which case it is set to the left block - -if this block has no larger parent block or it is at the left side of its -parent block and the top right block is not outside of the image then the -top right block is used for top-right else the top-left block is used - -Null block -y,cb,cr are 128 -level, ref, mx and my are 0 - - -Motion Vector Prediction: -========================= -1. the motion vectors of all the neighboring blocks are scaled to -compensate for the difference of reference frames - -scaled_mv= (mv * (256 * (current_reference+1) / (mv.reference+1)) + 128)>>8 - -2. the median of the scaled left, top and top-right vectors is used as -motion vector prediction - -3. the used motion vector is the sum of the predictor and - (mvx_diff, mvy_diff)*mv_scale - - -Intra DC Predicton: -====================== -the luma and chroma values of the left block are used as predictors - -the used luma and chroma is the sum of the predictor and y_diff, cb_diff, cr_diff -to reverse this in the decoder apply the following: -block[y][x].dc[0] = block[y][x-1].dc[0] + y_diff; -block[y][x].dc[1] = block[y][x-1].dc[1] + cb_diff; -block[y][x].dc[2] = block[y][x-1].dc[2] + cr_diff; -block[*][-1].dc[*]= 128; - - -Motion Compensation: -==================== - -Halfpel interpolation: ----------------------- -halfpel interpolation is done by convolution with the halfpel filter stored -in the header: - -horizontal halfpel samples are found by -H1[y][x] = hcoeff[0]*(F[y][x ] + F[y][x+1]) - + hcoeff[1]*(F[y][x-1] + F[y][x+2]) - + hcoeff[2]*(F[y][x-2] + F[y][x+3]) - + ... -h1[y][x] = (H1[y][x] + 32)>>6; - -vertical halfpel samples are found by -H2[y][x] = hcoeff[0]*(F[y ][x] + F[y+1][x]) - + hcoeff[1]*(F[y-1][x] + F[y+2][x]) - + ... -h2[y][x] = (H2[y][x] + 32)>>6; - -vertical+horizontal halfpel samples are found by -H3[y][x] = hcoeff[0]*(H2[y][x ] + H2[y][x+1]) - + hcoeff[1]*(H2[y][x-1] + H2[y][x+2]) - + ... -H3[y][x] = hcoeff[0]*(H1[y ][x] + H1[y+1][x]) - + hcoeff[1]*(H1[y+1][x] + H1[y+2][x]) - + ... -h3[y][x] = (H3[y][x] + 2048)>>12; - - - F H1 F - | | | - | | | - | | | - F H1 F - | | | - | | | - | | | - F-------F-------F-> H1<-F-------F-------F - v v v - H2 H3 H2 - ^ ^ ^ - F-------F-------F-> H1<-F-------F-------F - | | | - | | | - | | | - F H1 F - | | | - | | | - | | | - F H1 F - - -unavailable fullpel samples (outside the picture for example) shall be equal -to the closest available fullpel sample - - -Smaller pel interpolation: --------------------------- -if diag_mc is set then points which lie on a line between 2 vertically, -horiziontally or diagonally adjacent halfpel points shall be interpolated -linearls with rounding to nearest and halfway values rounded up. -points which lie on 2 diagonals at the same time should only use the one -diagonal not containing the fullpel point - - - - F-->O---q---O<--h1->O---q---O<--F - v \ / v \ / v - O O O O O O O - | / | \ | - q q q q q - | / | \ | - O O O O O O O - ^ / \ ^ / \ ^ - h2-->O---q---O<--h3->O---q---O<--h2 - v \ / v \ / v - O O O O O O O - | \ | / | - q q q q q - | \ | / | - O O O O O O O - ^ / \ ^ / \ ^ - F-->O---q---O<--h1->O---q---O<--F - - - -the remaining points shall be bilinearly interpolated from the -up to 4 surrounding halfpel and fullpel points, again rounding should be to -nearest and halfway values rounded up - -compliant Snow decoders MUST support 1-1/8 pel luma and 1/2-1/16 pel chroma -interpolation at least - - -Overlapped block motion compensation: -------------------------------------- -FIXME - -LL band prediction: -=================== -Each sample in the LL0 subband is predicted by the median of the left, top and -left+top-topleft samples, samples outside the subband shall be considered to -be 0. To reverse this prediction in the decoder apply the following. -for(y=0; y|-------+-------|->|-------+-------|->| L1 | H1 |->... -| | | | | | | | | | | | -| LH1 | HH1 | | LH1 | HH1 | | LH1 | HH1 | | | | -| | | | | | | | | | | | - --------------- --------------- --------------- --------------- - - -1D Filter: ----------- -1. interleave the samples of the low and high frequency subbands like -s={L0, H0, L1, H1, L2, H2, L3, H3, ... } -note, this can end with a L or a H, the number of elements shall be w -s[-1] shall be considered equivalent to s[1 ] -s[w ] shall be considered equivalent to s[w-2] - -2. perform the lifting steps in order as described below - -5/3 Integer filter: -1. s[i] -= (s[i-1] + s[i+1] + 2)>>2; for all even i < w -2. s[i] += (s[i-1] + s[i+1] )>>1; for all odd i < w - -\ | /|\ | /|\ | /|\ | /|\ - \|/ | \|/ | \|/ | \|/ | - + | + | + | + | -1/4 - /|\ | /|\ | /|\ | /|\ | -/ | \|/ | \|/ | \|/ | \|/ - | + | + | + | + +1/2 - - -Snow's 9/7 Integer filter: -1. s[i] -= (3*(s[i-1] + s[i+1]) + 4)>>3; for all even i < w -2. s[i] -= s[i-1] + s[i+1] ; for all odd i < w -3. s[i] += ( s[i-1] + s[i+1] + 4*s[i] + 8)>>4; for all even i < w -4. s[i] += (3*(s[i-1] + s[i+1]) )>>1; for all odd i < w - -\ | /|\ | /|\ | /|\ | /|\ - \|/ | \|/ | \|/ | \|/ | - + | + | + | + | -3/8 - /|\ | /|\ | /|\ | /|\ | -/ | \|/ | \|/ | \|/ | \|/ - (| + (| + (| + (| + -1 -\ + /|\ + /|\ + /|\ + /|\ +1/4 - \|/ | \|/ | \|/ | \|/ | - + | + | + | + | +1/16 - /|\ | /|\ | /|\ | /|\ | -/ | \|/ | \|/ | \|/ | \|/ - | + | + | + | + +3/2 - -optimization tips: -following are exactly identical -(3a)>>1 == a + (a>>1) -(a + 4b + 8)>>4 == ((a>>2) + b + 2)>>2 - -16bit implementation note: -The IDWT can be implemented with 16bits, but this requires some care to -prevent overflows, the following list, lists the minimum number of bits needed -for some terms -1. lifting step -A= s[i-1] + s[i+1] 16bit -3*A + 4 18bit -A + (A>>1) + 2 17bit - -3. lifting step -s[i-1] + s[i+1] 17bit - -4. lifiting step -3*(s[i-1] + s[i+1]) 17bit - - -TODO: -===== -Important: -finetune initial contexts -flip wavelet? -try to use the wavelet transformed predicted image (motion compensated image) as context for coding the residual coefficients -try the MV length as context for coding the residual coefficients -use extradata for stuff which is in the keyframes now? -the MV median predictor is patented IIRC -implement per picture halfpel interpolation -try different range coder state transition tables for different contexts - -Not Important: -compare the 6 tap and 8 tap hpel filters (psnr/bitrate and subjective quality) -spatial_scalability b vs u (!= 0 breaks syntax anyway so we can add a u later) - - -Credits: -======== -Michael Niedermayer -Loren Merritt - - -Copyright: -========== -GPL + GFDL + whatever is needed to make this a RFC diff --git a/tizen/distrib/ffmpeg/doc/soc.txt b/tizen/distrib/ffmpeg/doc/soc.txt deleted file mode 100644 index 8b4a86d..0000000 --- a/tizen/distrib/ffmpeg/doc/soc.txt +++ /dev/null @@ -1,24 +0,0 @@ -Google Summer of Code and similar project guidelines - -Summer of Code is a project by Google in which students are paid to implement -some nice new features for various participating open source projects ... - -This text is a collection of things to take care of for the next soc as -it's a little late for this year's soc (2006). - -The Goal: -Our goal in respect to soc is and must be of course exactly one thing and -that is to improve FFmpeg, to reach this goal, code must -* conform to the svn policy and patch submission guidelines -* must improve FFmpeg somehow (faster, smaller, "better", - more codecs supported, fewer bugs, cleaner, ...) - -for mentors and other developers to help students to reach that goal it is -essential that changes to their codebase are publicly visible, clean and -easy reviewable that again leads us to: -* use of a revision control system like svn -* separation of cosmetic from non-cosmetic changes (this is almost entirely - ignored by mentors and students in soc 2006 which might lead to a suprise - when the code will be reviewed at the end before a possible inclusion in - FFmpeg, individual changes were generally not reviewable due to cosmetics). -* frequent commits, so that comments can be provided early diff --git a/tizen/distrib/ffmpeg/doc/swscale.txt b/tizen/distrib/ffmpeg/doc/swscale.txt deleted file mode 100644 index 4c62e67..0000000 --- a/tizen/distrib/ffmpeg/doc/swscale.txt +++ /dev/null @@ -1,99 +0,0 @@ - The official guide to swscale for confused developers. - ======================================================== - -Current (simplified) Architecture: ---------------------------------- - Input - v - _______OR_________ - / \ - / \ - special converter [Input to YUV converter] - | | - | (8bit YUV 4:4:4 / 4:2:2 / 4:2:0 / 4:0:0 ) - | | - | v - | Horizontal scaler - | | - | (15bit YUV 4:4:4 / 4:2:2 / 4:2:0 / 4:1:1 / 4:0:0 ) - | | - | v - | Vertical scaler and output converter - | | - v v - output - - -Swscale has 2 scaler paths. Each side must be capable of handling -slices, that is, consecutive non-overlapping rectangles of dimension -(0,slice_top) - (picture_width, slice_bottom). - -special converter - These generally are unscaled converters of common - formats, like YUV 4:2:0/4:2:2 -> RGB12/15/16/24/32. Though it could also - in principle contain scalers optimized for specific common cases. - -Main path - The main path is used when no special converter can be used. The code - is designed as a destination line pull architecture. That is, for each - output line the vertical scaler pulls lines from a ring buffer. When - the ring buffer does not contain the wanted line, then it is pulled from - the input slice through the input converter and horizontal scaler. - The result is also stored in the ring buffer to serve future vertical - scaler requests. - When no more output can be generated because lines from a future slice - would be needed, then all remaining lines in the current slice are - converted, horizontally scaled and put in the ring buffer. - [This is done for luma and chroma, each with possibly different numbers - of lines per picture.] - -Input to YUV Converter - When the input to the main path is not planar 8 bits per component YUV or - 8-bit gray, it is converted to planar 8-bit YUV. Two sets of converters - exist for this currently: One performs horizontal downscaling by 2 - before the conversion, the other leaves the full chroma resolution, - but is slightly slower. The scaler will try to preserve full chroma - when the output uses it. It is possible to force full chroma with - SWS_FULL_CHR_H_INP even for cases where the scaler thinks it is useless. - -Horizontal scaler - There are several horizontal scalers. A special case worth mentioning is - the fast bilinear scaler that is made of runtime-generated MMX2 code - using specially tuned pshufw instructions. - The remaining scalers are specially-tuned for various filter lengths. - They scale 8-bit unsigned planar data to 16-bit signed planar data. - Future >8 bits per component inputs will need to add a new horizontal - scaler that preserves the input precision. - -Vertical scaler and output converter - There is a large number of combined vertical scalers + output converters. - Some are: - * unscaled output converters - * unscaled output converters that average 2 chroma lines - * bilinear converters (C, MMX and accurate MMX) - * arbitrary filter length converters (C, MMX and accurate MMX) - And - * Plain C 8-bit 4:2:2 YUV -> RGB converters using LUTs - * Plain C 17-bit 4:4:4 YUV -> RGB converters using multiplies - * MMX 11-bit 4:2:2 YUV -> RGB converters - * Plain C 16-bit Y -> 16-bit gray - ... - - RGB with less than 8 bits per component uses dither to improve the - subjective quality and low-frequency accuracy. - - -Filter coefficients: --------------------- -There are several different scalers (bilinear, bicubic, lanczos, area, -sinc, ...). Their coefficients are calculated in initFilter(). -Horizontal filter coefficients have a 1.0 point at 1 << 14, vertical ones at -1 << 12. The 1.0 points have been chosen to maximize precision while leaving -a little headroom for convolutional filters like sharpening filters and -minimizing SIMD instructions needed to apply them. -It would be trivial to use a different 1.0 point if some specific scaler -would benefit from it. -Also, as already hinted at, initFilter() accepts an optional convolutional -filter as input that can be used for contrast, saturation, blur, sharpening -shift, chroma vs. luma shift, ... - diff --git a/tizen/distrib/ffmpeg/doc/tablegen.txt b/tizen/distrib/ffmpeg/doc/tablegen.txt deleted file mode 100644 index 8dfcd7d..0000000 --- a/tizen/distrib/ffmpeg/doc/tablegen.txt +++ /dev/null @@ -1,64 +0,0 @@ -Writing a table generator - -This documentation is preliminary. -Parts of the API are not good and should be changed. - -Basic concepts - -A table generator consists of two files, *_tablegen.c and *_tablegen.h. -The .h file will provide the variable declarations and initialization -code for the tables, the .c calls the initialization code and then prints -the tables as a header file using the tableprint.h helpers. -Both of these files will be compiled for the host system, so to avoid -breakage with cross-compilation neither of them may include, directly -or indirectly, config.h or avconfig.h. -Due to this, the .c file or Makefile may have to provide additional defines -or stubs, though if possible this should be avoided. -In particular, CONFIG_HARDCODED_TABLES should always be defined to 0. - -The .c file - -This file should include the *_tablegen.h and tableprint.h files and -anything else it needs as long as it does not depend on config.h or -avconfig.h. -In addition to that it must contain a main() function which initializes -all tables by calling the init functions from the .h file and then prints -them. -The printing code typically looks like this: - write_fileheader(); - printf("static const uint8_t my_array[100] = {\n"); - write_uint8_array(my_array, 100); - printf("};\n"); - -write_fileheader() adds some minor things like a "this is a generated file" -comment and some standard includes. -tablegen.h defines some write functions for one- and two-dimensional arrays -for standard types - they print only the "core" parts so they are easier -to reuse for multi-dimensional arrays so the outermost {} must be printed -separately. -If there's no standard function for printing the type you need, the -WRITE_1D_FUNC_ARGV macro is a very quick way to create one. -See libavcodec/dv_tablegen.c for an example. - - -The .h file - -This file should contain: - - one or more initialization functions - - the table variable declarations -If CONFIG_HARDCODED_TABLES is set, the initialization functions should -not do anything, and instead of the variable declarations the -generated *_tables.h file should be included. -Since that will be generated in the build directory, the path must be -included, i.e. -#include "libavcodec/example_tables.h" -not -#include "example_tables.h" - -Makefile changes - -To make the automatic table creation work, you must manually declare the -new dependency. -For this add a line similar to this: -$(SUBDIR)example.o: $(SUBDIR)example_tables.h -under the "ifdef CONFIG_HARDCODED_TABLES" section in the Makefile. diff --git a/tizen/distrib/ffmpeg/doc/texi2pod.pl b/tizen/distrib/ffmpeg/doc/texi2pod.pl deleted file mode 100755 index c414ffc..0000000 --- a/tizen/distrib/ffmpeg/doc/texi2pod.pl +++ /dev/null @@ -1,427 +0,0 @@ -#! /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/tizen/distrib/ffmpeg/doc/viterbi.txt b/tizen/distrib/ffmpeg/doc/viterbi.txt deleted file mode 100644 index d9d924f..0000000 --- a/tizen/distrib/ffmpeg/doc/viterbi.txt +++ /dev/null @@ -1,110 +0,0 @@ -This is a quick description of the viterbi aka dynamic programing -algorthm. - -Its reason for existence is that wikipedia has become very poor on -describing algorithms in a way that makes it useable for understanding -them or anything else actually. It tends now to describe the very same -algorithm under 50 different names and pages with few understandable -by even people who fully understand the algorithm and the theory behind. - -Problem description: (that is what it can solve) -assume we have a 2d table, or you could call it a graph or matrix if you -prefer - - O O O O O O O - - O O O O O O O - - O O O O O O O - - O O O O O O O - - -That table has edges connecting points from each column to the next column -and each edge has a score like: (only some edge and scores shown to keep it -readable) - - - O--5--O-----O-----O-----O-----O - 2 / 7 / \ / \ / \ / - \ / \ / \ / \ / \ / - O7-/--O--/--O--/--O--/--O--/--O - \/ \/ 1/ \/ \/ \/ \/ \/ \/ \/ - /\ /\ 2\ /\ /\ /\ /\ /\ /\ /\ - O3-/--O--/--O--/--O--/--O--/--O - / \ / \ / \ / \ / \ - 1 \ 9 \ / \ / \ / \ - O--2--O--1--O--5--O--3--O--8--O - - - -Our goal is to find a path from left to right through it which -minimizes the sum of the score of all edges. -(and of course left/right is just a convention here it could be top down too) -Similarly the minimum could be the maximum by just fliping the sign, -Example of a path with scores: - - O O O O O O O - ->---O. O O .O-2-O O O - 5. .7 . - O O-1-O O O 8 O O - . - O O O O O O-1-O---> (sum here is 24) - - -The viterbi algorthm now solves this simply column by column -For the previous column each point has a best path and a associated -score: - - O-----5 O - \ - \ - O \ 1 O - \/ - /\ - O / 2 O - / - / - O-----2 O - - -To move one column forward we just need to find the best path and associated -scores for the next column -here are some edges we could choose from: - - - O-----5--3--O - \ \8 - \ \ - O \ 1--9--O - \/ \3 - /\ \ - O / 2--1--O - / \2 - / \ - O-----2--4--O - -Finding the new best pathes and scores for each point of our new column is -trivial given we know the previous column best pathes and scores: - - O-----0-----8 - \ - \ - O \ 0----10 - \/ - /\ - O / 0-----3 - / \ - / \ - O 0 4 - - -the viterbi algorthm continues exactly like this column for column until the -end and then just picks the path with the best score (above that would be the -one with score 3) - - -Author: Michael niedermayer -Copyright LGPL - diff --git a/tizen/distrib/ffmpeg/ffmpeg.c b/tizen/distrib/ffmpeg/ffmpeg.c deleted file mode 100644 index 6b9380f..0000000 --- a/tizen/distrib/ffmpeg/ffmpeg.c +++ /dev/null @@ -1,4173 +0,0 @@ -/* - * FFmpeg main - * Copyright (c) 2000-2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* needed for usleep() */ -#define _XOPEN_SOURCE 600 - -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#include "libswscale/swscale.h" -#include "libavcodec/opt.h" -#include "libavcodec/audioconvert.h" -#include "libavcodec/colorspace.h" -#include "libavutil/fifo.h" -#include "libavutil/pixdesc.h" -#include "libavutil/avstring.h" -#include "libavutil/libm.h" -#include "libavformat/os_support.h" - -#if HAVE_SYS_RESOURCE_H -#include -#include -#include -#elif HAVE_GETPROCESSTIMES -#include -#endif -#if HAVE_GETPROCESSMEMORYINFO -#include -#include -#endif - -#if HAVE_SYS_SELECT_H -#include -#endif - -#if HAVE_TERMIOS_H -#include -#include -#include -#include -#elif HAVE_CONIO_H -#include -#endif -#include - -#include "cmdutils.h" - -#undef NDEBUG -#include - -const char program_name[] = "FFmpeg"; -const int program_birth_year = 2000; - -/* 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; - -static const OptionDef options[]; - -#define MAX_FILES 100 - -static const char *last_asked_format = NULL; -static AVFormatContext *input_files[MAX_FILES]; -static int64_t input_files_ts_offset[MAX_FILES]; -static double input_files_ts_scale[MAX_FILES][MAX_STREAMS]; -static AVCodec *input_codecs[MAX_FILES*MAX_STREAMS]; -static int nb_input_files = 0; -static int nb_icodecs; - -static AVFormatContext *output_files[MAX_FILES]; -static AVCodec *output_codecs[MAX_FILES*MAX_STREAMS]; -static int nb_output_files = 0; -static int nb_ocodecs; - -static AVStreamMap stream_maps[MAX_FILES*MAX_STREAMS]; -static int nb_stream_maps; - -static AVMetaDataMap meta_data_maps[MAX_FILES]; -static int nb_meta_data_maps; - -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 enum SampleFormat audio_sample_fmt = SAMPLE_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 AVRational frame_rate; -static float video_qscale = 0; -static uint16_t *intra_matrix = NULL; -static uint16_t *inter_matrix = NULL; -static const char *video_rc_override_string=NULL; -static int video_disable = 0; -static int video_discard = 0; -static char *video_codec_name = NULL; -static int video_codec_tag = 0; -static char *video_language = NULL; -static int same_quality = 0; -static int do_deinterlace = 0; -static int top_field_first = -1; -static int me_threshold = 0; -static int intra_dc_precision = 8; -static int loop_input = 0; -static int loop_output = AVFMT_NOOUTPUTLOOP; -static int qp_hist = 0; - -static int intra_only = 0; -static int audio_sample_rate = 44100; -static int64_t channel_layout = 0; -#define QSCALE_NONE -99999 -static float audio_qscale = QSCALE_NONE; -static int audio_disable = 0; -static int audio_channels = 1; -static char *audio_codec_name = NULL; -static int audio_codec_tag = 0; -static char *audio_language = NULL; - -static int subtitle_disable = 0; -static char *subtitle_codec_name = NULL; -static char *subtitle_language = NULL; -static int subtitle_codec_tag = 0; - -static float mux_preload= 0.5; -static float mux_max_delay= 0.7; - -static int64_t recording_time = INT64_MAX; -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 int metadata_count; -static AVMetadataTag *metadata; -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_pass = 0; -static char *pass_logfilename_prefix = 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 float audio_drift_threshold= 0.1; -static int copy_ts= 0; -static int opt_shortest = 0; -static int video_global_header = 0; -static char *vstats_filename; -static FILE *vstats_file; -static int opt_programid = 0; -static int copy_initial_nonkeyframes = 0; - -static int rate_emu = 0; - -static int video_channel = 0; -static char *video_standard; - -static int audio_volume = 256; - -static int exit_on_error = 0; -static int using_stdin = 0; -static int verbose = 1; -static int thread_count= 1; -static int q_pressed = 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 uint64_t limit_filesize = 0; -static int force_fps = 0; - -static int pgmyuv_compatibility_hack=0; -static float dts_delta_threshold = 10; - -static unsigned int sws_flags = SWS_BICUBIC; - -static int64_t timer_start; - -static uint8_t *audio_buf; -static uint8_t *audio_out; -unsigned int allocated_audio_out_size, allocated_audio_buf_size; - -static short *samples; - -static AVBitStreamFilterContext *video_bitstream_filters=NULL; -static AVBitStreamFilterContext *audio_bitstream_filters=NULL; -static AVBitStreamFilterContext *subtitle_bitstream_filters=NULL; -static AVBitStreamFilterContext *bitstream_filters[MAX_FILES][MAX_STREAMS]; - -#define DEFAULT_PASS_LOGFILENAME_PREFIX "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 */ - struct SwsContext *img_resample_ctx; /* for image resampling */ - int resample_height; - int resample_width; - int resample_pix_fmt; - - /* full frame size of first frame */ - int original_height; - int original_width; - - /* cropping area sizes */ - int video_crop; - int topBand; - int bottomBand; - int leftBand; - int rightBand; - - /* cropping area of first frame */ - int original_topBand; - int original_bottomBand; - int original_leftBand; - int original_rightBand; - - /* padding area sizes */ - int video_pad; - int padtop; - int padbottom; - int padleft; - int padright; - - /* audio only */ - int audio_resample; - ReSampleContext *resample; /* for audio resampling */ - int reformat_pair; - AVAudioConvert *reformat_ctx; - AVFifoBuffer *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 */ - 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 */ - int showed_multi_packet_warning; - int is_past_recording_time; -} 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 nb_streams; /* nb streams we are aware of */ -} AVInputFile; - -#if HAVE_TERMIOS_H - -/* init terminal so that we can grab keys */ -static struct termios oldtty; -#endif - -static void term_exit(void) -{ -#if HAVE_TERMIOS_H - tcsetattr (0, TCSANOW, &oldtty); -#endif -} - -static volatile int received_sigterm = 0; - -static void -sigterm_handler(int sig) -{ - received_sigterm = sig; - term_exit(); -} - -static void term_init(void) -{ -#if HAVE_TERMIOS_H - struct termios tty; - - tcgetattr (0, &tty); - oldtty = tty; - atexit(term_exit); - - 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(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ -#endif - - signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ - signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ -#ifdef SIGXCPU - signal(SIGXCPU, sigterm_handler); -#endif - -#if CONFIG_BEOS_NETSERVER - fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); -#endif -} - -/* read a key without blocking */ -static int read_key(void) -{ -#if HAVE_TERMIOS_H - int n = 1; - unsigned char ch; -#if !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; - } -#elif HAVE_CONIO_H - if(kbhit()) - return(getch()); -#endif - return -1; -} - -static int decode_interrupt_cb(void) -{ - return q_pressed || (q_pressed = read_key() == 'q'); -} - -static int av_exit(int ret) -{ - int i; - - /* close files */ - for(i=0;ioformat->flags & AVFMT_NOFILE) && s->pb) - url_fclose(s->pb); - for(j=0;jnb_streams;j++) { - av_metadata_free(&s->streams[j]->metadata); - av_free(s->streams[j]->codec); - av_free(s->streams[j]); - } - for(j=0;jnb_programs;j++) { - av_metadata_free(&s->programs[j]->metadata); - } - for(j=0;jnb_chapters;j++) { - av_metadata_free(&s->chapters[j]->metadata); - } - av_metadata_free(&s->metadata); - av_free(s); - } - for(i=0;isample_fmts){ - const enum SampleFormat *p= codec->sample_fmts; - for(; *p!=-1; p++){ - if(*p == st->codec->sample_fmt) - break; - } - if(*p == -1) - st->codec->sample_fmt = codec->sample_fmts[0]; - } -} - -static void choose_sample_rate(AVStream *st, AVCodec *codec) -{ - if(codec && codec->supported_samplerates){ - const int *p= codec->supported_samplerates; - int best; - int best_dist=INT_MAX; - for(; *p; p++){ - int dist= abs(st->codec->sample_rate - *p); - if(dist < best_dist){ - best_dist= dist; - best= *p; - } - } - if(best_dist){ - av_log(st->codec, AV_LOG_WARNING, "Requested sampling rate unsupported using closest supported (%d)\n", best); - } - st->codec->sample_rate= best; - } -} - -static void choose_pixel_fmt(AVStream *st, AVCodec *codec) -{ - if(codec && codec->pix_fmts){ - const enum PixelFormat *p= codec->pix_fmts; - for(; *p!=-1; p++){ - if(*p == st->codec->pix_fmt) - break; - } - if(*p == -1 - && !( st->codec->codec_id==CODEC_ID_MJPEG - && st->codec->strict_std_compliance <= FF_COMPLIANCE_INOFFICIAL - && ( st->codec->pix_fmt == PIX_FMT_YUV420P - || st->codec->pix_fmt == PIX_FMT_YUV422P))) - st->codec->pix_fmt = codec->pix_fmts[0]; - } -} - -static int read_ffserver_streams(AVFormatContext *s, const char *filename) -{ - int i, err; - AVFormatContext *ic; - int nopts = 0; - - 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; - AVCodec *codec; - - // FIXME: a more elegant solution is needed - st = av_mallocz(sizeof(AVStream)); - memcpy(st, ic->streams[i], sizeof(AVStream)); - st->codec = avcodec_alloc_context(); - if (!st->codec) { - print_error(filename, AVERROR(ENOMEM)); - av_exit(1); - } - avcodec_copy_context(st->codec, ic->streams[i]->codec); - s->streams[i] = st; - - codec = avcodec_find_encoder(st->codec->codec_id); - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (audio_stream_copy) { - st->stream_copy = 1; - } else - choose_sample_fmt(st, codec); - } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (video_stream_copy) { - st->stream_copy = 1; - } else - choose_pixel_fmt(st, codec); - } - - if(!st->codec->thread_count) - st->codec->thread_count = 1; - if(st->codec->thread_count>1) - avcodec_thread_init(st->codec, st->codec->thread_count); - - if(st->codec->flags & CODEC_FLAG_BITEXACT) - nopts = 1; - } - - if (!nopts) - s->timestamp = av_gettime(); - - 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 - start_time)/AV_TIME_BASE; -} - -static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc){ - int ret; - - while(bsfc){ - AVPacket new_pkt= *pkt; - int a= av_bitstream_filter_filter(bsfc, avctx, NULL, - &new_pkt.data, &new_pkt.size, - pkt->data, pkt->size, - pkt->flags & AV_PKT_FLAG_KEY); - if(a>0){ - av_free_packet(pkt); - new_pkt.destruct= av_destruct_packet; - } else if(a<0){ - fprintf(stderr, "%s failed for stream %d, codec %s", - bsfc->filter->name, pkt->stream_index, - avctx->codec ? avctx->codec->name : "copy"); - print_error("", a); - if (exit_on_error) - av_exit(1); - } - *pkt= new_pkt; - - bsfc= bsfc->next; - } - - ret= av_interleaved_write_frame(s, pkt); - if(ret < 0){ - print_error("av_interleaved_write_frame()", ret); - av_exit(1); - } -} - -#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; - int64_t audio_out_size, audio_buf_size; - int64_t allocated_for_size= size; - - int size_out, frame_bytes, ret; - AVCodecContext *enc= ost->st->codec; - AVCodecContext *dec= ist->st->codec; - int osize= av_get_bits_per_sample_format(enc->sample_fmt)/8; - int isize= av_get_bits_per_sample_format(dec->sample_fmt)/8; - const int coded_bps = av_get_bits_per_sample(enc->codec->id); - -need_realloc: - audio_buf_size= (allocated_for_size + isize*dec->channels - 1) / (isize*dec->channels); - audio_buf_size= (audio_buf_size*enc->sample_rate + dec->sample_rate) / dec->sample_rate; - audio_buf_size= audio_buf_size*2 + 10000; //safety factors for the deprecated resampling API - audio_buf_size*= osize*enc->channels; - - audio_out_size= FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels); - if(coded_bps > 8*osize) - audio_out_size= audio_out_size * coded_bps / (8*osize); - audio_out_size += FF_MIN_BUFFER_SIZE; - - if(audio_out_size > INT_MAX || audio_buf_size > INT_MAX){ - fprintf(stderr, "Buffer sizes too large\n"); - av_exit(1); - } - - av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size); - av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size); - if (!audio_buf || !audio_out){ - fprintf(stderr, "Out of memory in do_audio_out\n"); - av_exit(1); - } - - if (enc->channels != dec->channels) - ost->audio_resample = 1; - - if (ost->audio_resample && !ost->resample) { - if (dec->sample_fmt != SAMPLE_FMT_S16) - fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n"); - ost->resample = av_audio_resample_init(enc->channels, dec->channels, - enc->sample_rate, dec->sample_rate, - enc->sample_fmt, dec->sample_fmt, - 16, 10, 0, 0.8); - if (!ost->resample) { - fprintf(stderr, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n", - dec->channels, dec->sample_rate, - enc->channels, enc->sample_rate); - av_exit(1); - } - } - -#define MAKE_SFMT_PAIR(a,b) ((a)+SAMPLE_FMT_NB*(b)) - if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt && - MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt)!=ost->reformat_pair) { - if (ost->reformat_ctx) - av_audio_convert_free(ost->reformat_ctx); - ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1, - dec->sample_fmt, 1, NULL, 0); - if (!ost->reformat_ctx) { - fprintf(stderr, "Cannot convert %s sample format to %s sample format\n", - avcodec_get_sample_fmt_name(dec->sample_fmt), - avcodec_get_sample_fmt_name(enc->sample_fmt)); - av_exit(1); - } - ost->reformat_pair=MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt); - } - - if(audio_sync_method){ - double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts - - av_fifo_size(ost->fifo)/(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 || fabs(delta) > audio_drift_threshold*enc->sample_rate){ - 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 > allocated_for_size - size){ - allocated_for_size= byte_delta + (int64_t)size; - goto need_realloc; - } - ist->is_start=0; - - 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= av_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:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(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) - - av_fifo_size(ost->fifo)/(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 * isize)); - size_out = size_out * enc->channels * osize; - } else { - buftmp = buf; - size_out = size; - } - - if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt) { - const void *ibuf[6]= {buftmp}; - void *obuf[6]= {audio_buf}; - int istride[6]= {isize}; - int ostride[6]= {osize}; - int len= size_out/istride[0]; - if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) { - printf("av_audio_convert() failed\n"); - if (exit_on_error) - av_exit(1); - return; - } - buftmp = audio_buf; - size_out = len*osize; - } - - /* now encode as many frames as possible */ - if (enc->frame_size > 1) { - /* output resampled raw samples */ - if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) { - fprintf(stderr, "av_fifo_realloc2() failed\n"); - av_exit(1); - } - av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL); - - frame_bytes = enc->frame_size * osize * enc->channels; - - while (av_fifo_size(ost->fifo) >= frame_bytes) { - AVPacket pkt; - av_init_packet(&pkt); - - av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL); - - //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio() - - ret = avcodec_encode_audio(enc, audio_out, audio_out_size, - (short *)audio_buf); - if (ret < 0) { - fprintf(stderr, "Audio encoding failed\n"); - av_exit(1); - } - 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 |= AV_PKT_FLAG_KEY; - write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); - - ost->sync_opts += enc->frame_size; - } - } else { - AVPacket pkt; - av_init_packet(&pkt); - - ost->sync_opts += size_out / (osize * enc->channels); - - /* output a pcm frame */ - /* determine the size of the coded buffer */ - size_out /= osize; - if (coded_bps) - size_out = size_out*coded_bps/8; - - if(size_out > audio_out_size){ - fprintf(stderr, "Internal error, buffer size too small\n"); - av_exit(1); - } - - //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio() - ret = avcodec_encode_audio(enc, audio_out, size_out, - (short *)buftmp); - if (ret < 0) { - fprintf(stderr, "Audio encoding failed\n"); - av_exit(1); - } - 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 |= AV_PKT_FLAG_KEY; - write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); - } -} - -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) { - 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(avpicture_deinterlace(picture2, picture, - dec->pix_fmt, dec->width, dec->height) < 0) { - /* if error, do not deinterlace */ - fprintf(stderr, "Deinterlacing failed\n"); - av_free(buf); - buf = NULL; - picture2 = picture; - } - } else { - picture2 = picture; - } - - 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 = 1024 * 1024; - int subtitle_out_size, nb, i; - AVCodecContext *enc; - AVPacket pkt; - - if (pts == AV_NOPTS_VALUE) { - fprintf(stderr, "Subtitle packets must have a pts\n"); - if (exit_on_error) - av_exit(1); - 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++) { - sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q); - // start_display_time is required to be 0 - sub->pts += av_rescale_q(sub->start_display_time, (AVRational){1, 1000}, AV_TIME_BASE_Q); - sub->end_display_time -= sub->start_display_time; - sub->start_display_time = 0; - subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out, - subtitle_out_max_size, sub); - if (subtitle_out_size < 0) { - fprintf(stderr, "Subtitle encoding failed\n"); - av_exit(1); - } - - av_init_packet(&pkt); - pkt.stream_index = ost->index; - pkt.data = subtitle_out; - pkt.size = subtitle_out_size; - pkt.pts = av_rescale_q(sub->pts, 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; - } - write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); - } -} - -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; - int64_t topBand, bottomBand, leftBand, rightBand; - AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src; - AVFrame picture_crop_temp, picture_pad_temp; - AVCodecContext *enc, *dec; - double sync_ipts; - - avcodec_get_frame_defaults(&picture_crop_temp); - avcodec_get_frame_defaults(&picture_pad_temp); - - enc = ost->st->codec; - dec = ist->st->codec; - - sync_ipts = get_sync_ipts(ost) / av_q2d(enc->time_base); - - /* by default, we output a single frame */ - nb_frames = 1; - - *frame_size = 0; - - if(video_sync_method){ - double vdelta = sync_ipts - 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 (video_sync_method == 2 || (video_sync_method<0 && (s->oformat->flags & AVFMT_VARIABLE_FPS))){ - if(vdelta<=-0.6){ - nb_frames=0; - }else if(vdelta>0.6) - ost->sync_opts= lrintf(sync_ipts); - }else if (vdelta > 1.1) - nb_frames = lrintf(vdelta); -//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, get_sync_ipts(ost), 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 - 1; - if (verbose>2) - fprintf(stderr, "*** %d dup!\n", nb_frames-1); - } - }else - ost->sync_opts= lrintf(sync_ipts); - - nb_frames= FFMIN(nb_frames, max_frames[AVMEDIA_TYPE_VIDEO] - ost->frame_number); - if (nb_frames <= 0) - return; - - if (ost->video_crop) { - if (av_picture_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) { - fprintf(stderr, "error cropping picture\n"); - if (exit_on_error) - av_exit(1); - return; - } - formatted_picture = &picture_crop_temp; - } else { - formatted_picture = in_picture; - } - - 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 (av_picture_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, enc->pix_fmt, ost->padtop, ost->padleft) < 0) { - fprintf(stderr, "error padding picture\n"); - if (exit_on_error) - av_exit(1); - return; - } - resampling_dst = &picture_pad_temp; - } - } - - if( (ost->resample_height != (ist->st->codec->height - (ost->topBand + ost->bottomBand))) - || (ost->resample_width != (ist->st->codec->width - (ost->leftBand + ost->rightBand))) - || (ost->resample_pix_fmt!= ist->st->codec->pix_fmt) ) { - - fprintf(stderr,"Input Stream #%d.%d frame size changed to %dx%d, %s\n", ist->file_index, ist->index, ist->st->codec->width, ist->st->codec->height,avcodec_get_pix_fmt_name(ist->st->codec->pix_fmt)); - if(!ost->video_resample) - av_exit(1); - } - - if (ost->video_resample) { - padding_src = NULL; - final_picture = &ost->pict_tmp; - if( (ost->resample_height != (ist->st->codec->height - (ost->topBand + ost->bottomBand))) - || (ost->resample_width != (ist->st->codec->width - (ost->leftBand + ost->rightBand))) - || (ost->resample_pix_fmt!= ist->st->codec->pix_fmt) ) { - - /* keep bands proportional to the frame size */ - topBand = ((int64_t)ist->st->codec->height * ost->original_topBand / ost->original_height) & ~1; - bottomBand = ((int64_t)ist->st->codec->height * ost->original_bottomBand / ost->original_height) & ~1; - leftBand = ((int64_t)ist->st->codec->width * ost->original_leftBand / ost->original_width) & ~1; - rightBand = ((int64_t)ist->st->codec->width * ost->original_rightBand / ost->original_width) & ~1; - - /* sanity check to ensure no bad band sizes sneak in */ - assert(topBand <= INT_MAX && topBand >= 0); - assert(bottomBand <= INT_MAX && bottomBand >= 0); - assert(leftBand <= INT_MAX && leftBand >= 0); - assert(rightBand <= INT_MAX && rightBand >= 0); - - ost->topBand = topBand; - ost->bottomBand = bottomBand; - ost->leftBand = leftBand; - ost->rightBand = rightBand; - - ost->resample_height = ist->st->codec->height - (ost->topBand + ost->bottomBand); - ost->resample_width = ist->st->codec->width - (ost->leftBand + ost->rightBand); - ost->resample_pix_fmt= ist->st->codec->pix_fmt; - - /* initialize a new scaler context */ - sws_freeContext(ost->img_resample_ctx); - sws_flags = av_get_int(sws_opts, "sws_flags", NULL); - ost->img_resample_ctx = sws_getContext( - ist->st->codec->width - (ost->leftBand + ost->rightBand), - ist->st->codec->height - (ost->topBand + ost->bottomBand), - ist->st->codec->pix_fmt, - ost->st->codec->width - (ost->padleft + ost->padright), - ost->st->codec->height - (ost->padtop + ost->padbottom), - ost->st->codec->pix_fmt, - sws_flags, NULL, NULL, NULL); - if (ost->img_resample_ctx == NULL) { - fprintf(stderr, "Cannot get resampling context\n"); - av_exit(1); - } - } - sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize, - 0, ost->resample_height, resampling_dst->data, resampling_dst->linesize); - } - - if (ost->video_pad) { - av_picture_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); - pkt.pts= av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base); - pkt.flags |= AV_PKT_FLAG_KEY; - - write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); - 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(avcodec_opts[AVMEDIA_TYPE_VIDEO]->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, "%"PRId64" -> encoder\n", ost->sync_opts); - ret = avcodec_encode_video(enc, - bit_buffer, bit_buffer_size, - &big_picture); - if (ret < 0) { - fprintf(stderr, "Video encoding failed\n"); - av_exit(1); - } - - if(ret>0){ - pkt.data= bit_buffer; - pkt.size= ret; - if(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 -> %"PRId64"/%"PRId64"\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->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); - *frame_size = ret; - video_size += ret; - //fprintf(stderr,"\nFrame: %3d size: %5d type: %d", - // enc->frame_number-1, 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++; - } -} - -static double psnr(double d){ - return -10.0*log(d)/log(10.0); -} - -static void do_video_stats(AVFormatContext *os, AVOutputStream *ost, - int frame_size) -{ - AVCodecContext *enc; - int frame_number; - double ti1, bitrate, avg_bitrate; - - /* this is executed just the first time do_video_stats is called */ - if (!vstats_file) { - vstats_file = fopen(vstats_filename, "w"); - if (!vstats_file) { - perror("fopen"); - av_exit(1); - } - } - - enc = ost->st->codec; - if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { - frame_number = ost->frame_number; - fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality/(float)FF_QP2LAMBDA); - if (enc->flags&CODEC_FLAG_PSNR) - fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0]/(enc->width*enc->height*255.0*255.0))); - - fprintf(vstats_file,"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(vstats_file, "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(vstats_file,"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; - 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_fsize(oc->pb); - if(total_size<0) // FIXME improve url_fsize() so it works with non seekable output too - total_size= url_ftell(oc->pb); - - buf[0] = '\0'; - ti1 = 1e10; - vid = 0; - for(i=0;ist->codec; - if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", - !ost->st->stream_copy ? - enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1); - } - if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { - float t = (av_gettime()-timer_start) / 1000000.0; - - frame_number = ost->frame_number; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ", - frame_number, (t>1)?(int)(frame_number/t+0.5) : 0, - !ost->st->stream_copy ? - enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1); - if(is_last_report) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L"); - if(qp_hist){ - 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 * av_q2d(ost->st->time_base); - 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.2f bitrate=%6.1fkbits/s", - (double)total_size / 1024, ti1, bitrate); - - if (nb_frames_dup || nb_frames_drop) - 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; - int ret, i; - int got_picture; - AVFrame picture; - void *buffer_to_free; - static unsigned int samples_size= 0; - AVSubtitle subtitle, *subtitle_to_free; - int got_subtitle; - AVPacket avpkt; - int bps = av_get_bits_per_sample_format(ist->st->codec->sample_fmt)>>3; - - if(ist->next_pts == AV_NOPTS_VALUE) - ist->next_pts= ist->pts; - - if (pkt == NULL) { - /* EOF handling */ - av_init_packet(&avpkt); - avpkt.data = NULL; - avpkt.size = 0; - goto handle_eof; - } else { - avpkt = *pkt; - } - - if(pkt->dts != AV_NOPTS_VALUE) - ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); - - //while we have more to decode or while the decoder did output something on EOF - while (avpkt.size > 0 || (!pkt && ist->next_pts != ist->pts)) { - uint8_t *data_buf, *decoded_data_buf; - int data_size, decoded_data_size; - handle_eof: - ist->pts= ist->next_pts; - - if(avpkt.size && avpkt.size != pkt->size && - ((!ist->showed_multi_packet_warning && verbose>0) || verbose>1)){ - fprintf(stderr, "Multiple frames in a packet from stream %d\n", pkt->stream_index); - ist->showed_multi_packet_warning=1; - } - - /* decode the packet if needed */ - decoded_data_buf = NULL; /* fail safe */ - decoded_data_size= 0; - data_buf = avpkt.data; - data_size = avpkt.size; - subtitle_to_free = NULL; - if (ist->decoding_needed) { - switch(ist->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO:{ - if(pkt && samples_size < FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE)) { - samples_size = FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE); - av_free(samples); - samples= av_malloc(samples_size); - } - decoded_data_size= samples_size; - /* XXX: could avoid copy if PCM 16 bits with same - endianness as CPU */ - ret = avcodec_decode_audio3(ist->st->codec, samples, &decoded_data_size, - &avpkt); - if (ret < 0) - goto fail_decode; - avpkt.data += ret; - avpkt.size -= ret; - data_size = ret; - /* Some bug in mpeg audio decoder gives */ - /* decoded_data_size < 0, it seems they are overflows */ - if (decoded_data_size <= 0) { - /* no audio frame */ - continue; - } - decoded_data_buf = (uint8_t *)samples; - ist->next_pts += ((int64_t)AV_TIME_BASE/bps * decoded_data_size) / - (ist->st->codec->sample_rate * ist->st->codec->channels); - break;} - case AVMEDIA_TYPE_VIDEO: - decoded_data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2; - /* XXX: allocate picture correctly */ - avcodec_get_frame_defaults(&picture); - - ret = avcodec_decode_video2(ist->st->codec, - &picture, &got_picture, &avpkt); - 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) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; - ist->next_pts += ((int64_t)AV_TIME_BASE * - ist->st->codec->time_base.num * ticks) / - ist->st->codec->time_base.den; - } - avpkt.size = 0; - break; - case AVMEDIA_TYPE_SUBTITLE: - ret = avcodec_decode_subtitle2(ist->st->codec, - &subtitle, &got_subtitle, &avpkt); - if (ret < 0) - goto fail_decode; - if (!got_subtitle) { - goto discard_packet; - } - subtitle_to_free = &subtitle; - avpkt.size = 0; - break; - default: - goto fail_decode; - } - } else { - switch(ist->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / - ist->st->codec->sample_rate; - break; - case AVMEDIA_TYPE_VIDEO: - if (ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; - ist->next_pts += ((int64_t)AV_TIME_BASE * - ist->st->codec->time_base.num * ticks) / - ist->st->codec->time_base.den; - } - break; - } - ret = avpkt.size; - avpkt.size = 0; - } - - buffer_to_free = NULL; - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - pre_process_video_frame(ist, (AVPicture *)&picture, - &buffer_to_free); - } - - // preprocess audio (volume) - if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (audio_volume != 256) { - short *volp; - volp = samples; - for(i=0;i<(decoded_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 (rate_emu) { - int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE); - int64_t now = av_gettime() - ist->start; - if (pts > now) - usleep(pts - now); - } - - /* 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]; - - /* 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) { - assert(ist->decoding_needed); - switch(ost->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - do_audio_out(os, ost, ist, decoded_data_buf, decoded_data_size); - break; - case AVMEDIA_TYPE_VIDEO: - do_video_out(os, ost, ist, &picture, &frame_size); - if (vstats_filename && frame_size) - do_video_stats(os, ost, frame_size); - break; - case AVMEDIA_TYPE_SUBTITLE: - do_subtitle_out(os, ost, ist, &subtitle, - pkt->pts); - break; - default: - abort(); - } - } else { - AVFrame avframe; //FIXME/XXX remove this - AVPacket opkt; - int64_t ost_tb_start_time= av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base); - - av_init_packet(&opkt); - - if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes) - continue; - - /* 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 & AV_PKT_FLAG_KEY; - - if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - audio_size += data_size; - else if (ost->st->codec->codec_type == AVMEDIA_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(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time; - else - opkt.pts= AV_NOPTS_VALUE; - - if (pkt->dts == AV_NOPTS_VALUE) - opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base); - else - opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base); - opkt.dts -= ost_tb_start_time; - - opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); - opkt.flags= pkt->flags; - - //FIXME remove the following 2 lines they shall be replaced by the bitstream filters - if( ost->st->codec->codec_id != CODEC_ID_H264 - && ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO - && ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO - ) { - if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & AV_PKT_FLAG_KEY)) - opkt.destruct= av_destruct_packet; - } else { - opkt.data = data_buf; - opkt.size = data_size; - } - - write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][opkt.stream_index]); - 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_freep(&subtitle_to_free->rects[i]->pict.data[0]); - av_freep(&subtitle_to_free->rects[i]->pict.data[1]); - av_freep(&subtitle_to_free->rects[i]); - } - 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 == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) - continue; - if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE)) - continue; - - if (ost->encoding_needed) { - for(;;) { - AVPacket pkt; - int fifo_bytes; - av_init_packet(&pkt); - pkt.stream_index= ost->index; - - switch(ost->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - fifo_bytes = av_fifo_size(ost->fifo); - ret = 0; - /* encode any samples remaining in fifo */ - if (fifo_bytes > 0) { - int osize = av_get_bits_per_sample_format(enc->sample_fmt) >> 3; - int fs_tmp = enc->frame_size; - - av_fifo_generic_read(ost->fifo, samples, fifo_bytes, NULL); - if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { - enc->frame_size = fifo_bytes / (osize * enc->channels); - } else { /* pad */ - int frame_bytes = enc->frame_size*osize*enc->channels; - if (samples_size < frame_bytes) - av_exit(1); - memset((uint8_t*)samples+fifo_bytes, 0, frame_bytes - fifo_bytes); - } - - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples); - pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den, - ost->st->time_base.num, enc->sample_rate); - enc->frame_size = fs_tmp; - } - if(ret <= 0) { - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); - } - if (ret < 0) { - fprintf(stderr, "Audio encoding failed\n"); - av_exit(1); - } - audio_size += ret; - pkt.flags |= AV_PKT_FLAG_KEY; - break; - case AVMEDIA_TYPE_VIDEO: - ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); - if (ret < 0) { - fprintf(stderr, "Video encoding failed\n"); - av_exit(1); - } - video_size += ret; - if(enc->coded_frame && enc->coded_frame->key_frame) - pkt.flags |= AV_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); - write_frame(os, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); - } - } - } - } - } - - return 0; - fail_decode: - return -1; -} - -static void print_sdp(AVFormatContext **avc, int n) -{ - char sdp[2048]; - - avf_sdp_create(avc, n, sdp, sizeof(sdp)); - printf("SDP:\n%s\n", sdp); - fflush(stdout); -} - -static int copy_chapters(int infile, int outfile) -{ - AVFormatContext *is = input_files[infile]; - AVFormatContext *os = output_files[outfile]; - int i; - - for (i = 0; i < is->nb_chapters; i++) { - AVChapter *in_ch = is->chapters[i], *out_ch; - AVMetadataTag *t = NULL; - int64_t ts_off = av_rescale_q(start_time - input_files_ts_offset[infile], - AV_TIME_BASE_Q, in_ch->time_base); - int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX : - av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base); - - - if (in_ch->end < ts_off) - continue; - if (rt != INT64_MAX && in_ch->start > rt + ts_off) - break; - - out_ch = av_mallocz(sizeof(AVChapter)); - if (!out_ch) - return AVERROR(ENOMEM); - - out_ch->id = in_ch->id; - out_ch->time_base = in_ch->time_base; - out_ch->start = FFMAX(0, in_ch->start - ts_off); - out_ch->end = FFMIN(rt, in_ch->end - ts_off); - - while ((t = av_metadata_get(in_ch->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) - av_metadata_set2(&out_ch->metadata, t->key, t->value, 0); - - os->nb_chapters++; - os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters); - if (!os->chapters) - return AVERROR(ENOMEM); - os->chapters[os->nb_chapters - 1] = out_ch; - } - return 0; -} - -/* - * The following code is the main loop of the file converter - */ -static int av_transcode(AVFormatContext **output_files, - int nb_output_files, - AVFormatContext **input_files, - int nb_input_files, - AVStreamMap *stream_maps, int nb_stream_maps) -{ - int ret = 0, 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; - char error[1024]; - int key; - int want_sdp = 1; - uint8_t no_packet[MAX_FILES]={0}; - int no_packet_count=0; - - file_table= 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 (rate_emu) { - ist->start = av_gettime(); - } - } - } - - /* output stream init */ - nb_ostreams = 0; - for(i=0;inb_streams) { - dump_format(output_files[i], i, output_files[i]->filename, 1); - fprintf(stderr, "Output file #%d does not contain any stream\n", i); - av_exit(1); - } - nb_ostreams += os->nb_streams; - } - if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) { - fprintf(stderr, "Number of stream maps must match number of output streams\n"); - av_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); - av_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); - av_exit(1); - } - } - - ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams); - if (!ost_table) - goto fail; - for(i=0;inb_streams;i++,n++) { - 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].file_index].ist_index + - stream_maps[n].stream_index; - - /* Sanity check that the stream types match */ - if (ist_table[ost->source_index]->st->codec->codec_type != ost->st->codec->codec_type) { - int i= ost->file_index; - dump_format(output_files[i], i, output_files[i]->filename, 1); - fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n", - stream_maps[n].file_index, stream_maps[n].stream_index, - ost->file_index, ost->index); - av_exit(1); - } - - } else { - int best_nb_frames=-1; - /* get corresponding input stream index : we select the first one with the right type */ - found = 0; - for(j=0;jfile_index ]; - skip=1; - for(pi=0; pinb_programs; pi++){ - AVProgram *p= f->programs[pi]; - if(p->id == opt_programid) - for(si=0; sinb_stream_indexes; si++){ - if(f->streams[ p->stream_index[si] ] == ist->st) - skip=0; - } - } - } - if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip && - ist->st->codec->codec_type == ost->st->codec->codec_type) { - if(best_nb_frames < ist->st->codec_info_nb_frames){ - best_nb_frames= ist->st->codec_info_nb_frames; - ost->source_index = j; - found = 1; - } - } - } - - if (!found) { - if(! opt_programid) { - /* try again and reuse existing stream */ - for(j=0;jst->codec->codec_type == ost->st->codec->codec_type - && ist->st->discard != AVDISCARD_ALL) { - ost->source_index = j; - found = 1; - } - } - } - if (!found) { - int i= ost->file_index; - dump_format(output_files[i], i, output_files[i]->filename, 1); - fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n", - ost->file_index, ost->index); - av_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].sync_file_index].ist_index + - stream_maps[n].sync_stream_index] : ist; - } - } - - /* for each output stream, we compute the right encoding parameters */ - for(i=0;ifile_index]; - ist = ist_table[ost->source_index]; - - codec = ost->st->codec; - icodec = ist->st->codec; - - while ((t = av_metadata_get(ist->st->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { - av_metadata_set2(&ost->st->metadata, t->key, t->value, AV_METADATA_DONT_OVERWRITE); - } - - ost->st->disposition = ist->st->disposition; - codec->bits_per_raw_sample= icodec->bits_per_raw_sample; - codec->chroma_sample_location = icodec->chroma_sample_location; - - 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){ - if( !os->oformat->codec_tag - || av_codec_get_id (os->oformat->codec_tag, icodec->codec_tag) == codec->codec_id - || av_codec_get_tag(os->oformat->codec_tag, icodec->codec_id) <= 0) - codec->codec_tag = icodec->codec_tag; - } - - codec->bit_rate = icodec->bit_rate; - codec->extradata= icodec->extradata; - codec->extradata_size= icodec->extradata_size; - if(av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000){ - codec->time_base = icodec->time_base; - codec->time_base.num *= icodec->ticks_per_frame; - }else - codec->time_base = ist->st->time_base; - switch(codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if(audio_volume != 256) { - fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n"); - av_exit(1); - } - codec->channel_layout = icodec->channel_layout; - codec->sample_rate = icodec->sample_rate; - codec->channels = icodec->channels; - codec->frame_size = icodec->frame_size; - codec->block_align= icodec->block_align; - if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3) - codec->block_align= 0; - if(codec->codec_id == CODEC_ID_AC3) - codec->block_align= 0; - break; - case AVMEDIA_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 AVMEDIA_TYPE_SUBTITLE: - codec->width = icodec->width; - codec->height = icodec->height; - break; - default: - abort(); - } - } else { - switch(codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - ost->fifo= av_fifo_alloc(1024); - if(!ost->fifo) - goto fail; - ost->reformat_pair = MAKE_SFMT_PAIR(SAMPLE_FMT_NONE,SAMPLE_FMT_NONE); - ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1; - icodec->request_channels = codec->channels; - ist->decoding_needed = 1; - ost->encoding_needed = 1; - break; - case AVMEDIA_TYPE_VIDEO: - if (ost->st->codec->pix_fmt == PIX_FMT_NONE) { - fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n"); - av_exit(1); - } - 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)) || - (codec->pix_fmt != icodec->pix_fmt)); - if (ost->video_crop) { - ost->topBand = ost->original_topBand = frame_topBand; - ost->bottomBand = ost->original_bottomBand = frame_bottomBand; - ost->leftBand = ost->original_leftBand = frame_leftBand; - ost->rightBand = ost->original_rightBand = frame_rightBand; - } - 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, codec->pix_fmt, - codec->width, codec->height)) { - fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n"); - av_exit(1); - } - sws_flags = av_get_int(sws_opts, "sws_flags", NULL); - ost->img_resample_ctx = sws_getContext( - icodec->width - (frame_leftBand + frame_rightBand), - icodec->height - (frame_topBand + frame_bottomBand), - icodec->pix_fmt, - codec->width - (frame_padleft + frame_padright), - codec->height - (frame_padtop + frame_padbottom), - codec->pix_fmt, - sws_flags, NULL, NULL, NULL); - if (ost->img_resample_ctx == NULL) { - fprintf(stderr, "Cannot get resampling context\n"); - av_exit(1); - } - - ost->original_height = icodec->height; - ost->original_width = icodec->width; - - codec->bits_per_raw_sample= 0; - } - ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand); - ost->resample_width = icodec->width - (frame_leftBand + frame_rightBand); - ost->resample_pix_fmt= icodec->pix_fmt; - ost->encoding_needed = 1; - ist->decoding_needed = 1; - break; - case AVMEDIA_TYPE_SUBTITLE: - ost->encoding_needed = 1; - ist->decoding_needed = 1; - break; - default: - abort(); - break; - } - /* two pass mode */ - if (ost->encoding_needed && - (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) { - char logfilename[1024]; - FILE *f; - - snprintf(logfilename, sizeof(logfilename), "%s-%d.log", - pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX, - i); - if (codec->flags & CODEC_FLAG_PASS1) { - f = fopen(logfilename, "wb"); - if (!f) { - fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno)); - av_exit(1); - } - ost->logfile = f; - } else { - char *logbuffer; - size_t logbuffer_size; - if (read_file(logfilename, &logbuffer, &logbuffer_size) < 0) { - fprintf(stderr, "Error reading log file '%s' for pass-2 encoding\n", logfilename); - av_exit(1); - } - codec->stats_in = logbuffer; - } - } - } - if(codec->codec_type == AVMEDIA_TYPE_VIDEO){ - int size= codec->width * codec->height; - bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 200); - } - } - - if (!bit_buffer) - bit_buffer = av_malloc(bit_buffer_size); - if (!bit_buffer) { - fprintf(stderr, "Cannot allocate %d bytes output buffer\n", - bit_buffer_size); - ret = AVERROR(ENOMEM); - goto fail; - } - - /* open each encoder */ - for(i=0;iencoding_needed) { - AVCodec *codec = output_codecs[i]; - if (!codec) - codec = avcodec_find_encoder(ost->st->codec->codec_id); - if (!codec) { - snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d", - ost->st->codec->codec_id, ost->file_index, ost->index); - ret = AVERROR(EINVAL); - goto dump_format; - } - if (avcodec_open(ost->st->codec, codec) < 0) { - snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height", - ost->file_index, ost->index); - ret = AVERROR(EINVAL); - goto dump_format; - } - extra_size += ost->st->codec->extradata_size; - } - } - - /* open each decoder */ - for(i=0;idecoding_needed) { - AVCodec *codec = input_codecs[i]; - if (!codec) - codec = avcodec_find_decoder(ist->st->codec->codec_id); - if (!codec) { - snprintf(error, sizeof(error), "Decoder (codec id %d) not found for input stream #%d.%d", - ist->st->codec->codec_id, ist->file_index, ist->index); - ret = AVERROR(EINVAL); - goto dump_format; - } - if (avcodec_open(ist->st->codec, codec) < 0) { - snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d", - ist->file_index, ist->index); - ret = AVERROR(EINVAL); - goto dump_format; - } - //if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - // ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD; - } - } - - /* init pts */ - for(i=0;ist; - ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0; - ist->next_pts = AV_NOPTS_VALUE; - ist->is_start = 1; - } - - /* set meta data information from input file if required */ - for (i=0;i= nb_output_files) { - snprintf(error, sizeof(error), "Invalid output file index %d map_meta_data(%d,%d)", - out_file_index, out_file_index, in_file_index); - ret = AVERROR(EINVAL); - goto dump_format; - } - if (in_file_index < 0 || in_file_index >= nb_input_files) { - snprintf(error, sizeof(error), "Invalid input file index %d map_meta_data(%d,%d)", - in_file_index, out_file_index, in_file_index); - ret = AVERROR(EINVAL); - goto dump_format; - } - - out_file = output_files[out_file_index]; - in_file = input_files[in_file_index]; - - - mtag=NULL; - while((mtag=av_metadata_get(in_file->metadata, "", mtag, AV_METADATA_IGNORE_SUFFIX))) - av_metadata_set2(&out_file->metadata, mtag->key, mtag->value, AV_METADATA_DONT_OVERWRITE); - av_metadata_conv(out_file, out_file->oformat->metadata_conv, - in_file->iformat->metadata_conv); - } - - /* copy chapters from the first input file that has them*/ - for (i = 0; i < nb_input_files; i++) { - if (!input_files[i]->nb_chapters) - continue; - - for (j = 0; j < nb_output_files; j++) - if ((ret = copy_chapters(i, j)) < 0) - goto dump_format; - } - - /* open files and write file headers */ - for(i=0;ioformat->name, "rtp")) { - want_sdp = 0; - } - } - - dump_format: - /* 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"); - } - } - - if (ret) { - fprintf(stderr, "%s\n", error); - goto fail; - } - - if (want_sdp) { - print_sdp(output_files, nb_output_files); - } - - if (!using_stdin && verbose >= 0) { - fprintf(stderr, "Press [q] to stop encoding\n"); - url_set_interrupt_cb(decode_interrupt_cb); - } - term_init(); - - timer_start = av_gettime(); - - 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(ist->is_past_recording_time || no_packet[ist->file_index]) - continue; - 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) { - if(no_packet_count){ - no_packet_count=0; - memset(no_packet, 0, sizeof(no_packet)); - usleep(10000); - continue; - } - break; - } - - /* finish if limit size exhausted */ - if (limit_filesize != 0 && limit_filesize < url_ftell(output_files[0]->pb)) - break; - - /* read a frame from it and output it in the fifo */ - is = input_files[file_index]; - ret= av_read_frame(is, &pkt); - if(ret == AVERROR(EAGAIN)){ - no_packet[file_index]=1; - no_packet_count++; - continue; - } - if (ret < 0) { - file_table[file_index].eof_reached = 1; - if (opt_shortest) - break; - else - continue; - } - - no_packet_count=0; - memset(no_packet, 0, sizeof(no_packet)); - - if (do_pkt_dump) { - av_pkt_dump_log(NULL, AV_LOG_DEBUG, &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; - - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base); - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base); - - if(input_files_ts_scale[file_index][pkt.stream_index]){ - if(pkt.pts != AV_NOPTS_VALUE) - pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index]; - if(pkt.dts != AV_NOPTS_VALUE) - pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index]; - } - -// fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %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 - && (is->iformat->flags & AVFMT_TS_DISCONT)) { - int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q); - int64_t delta= pkt_dts - ist->next_pts; - if((FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE || pkt_dts+1pts)&& !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]); - pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - if(pkt.pts != AV_NOPTS_VALUE) - pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - } - } - - /* finish if recording time exhausted */ - if (recording_time != INT64_MAX && - av_compare_ts(pkt.pts, ist->st->time_base, recording_time + start_time, (AVRational){1, 1000000}) >= 0) { - ist->is_past_recording_time = 1; - goto discard_packet; - } - - //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); - if (exit_on_error) - av_exit(1); - 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; - - fail: - av_freep(&bit_buffer); - av_free(file_table); - - if (ist_table) { - for(i=0;ilogfile) { - fclose(ost->logfile); - ost->logfile = NULL; - } - av_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) - sws_freeContext(ost->img_resample_ctx); - if (ost->resample) - audio_resample_close(ost->resample); - if (ost->reformat_ctx) - av_audio_convert_free(ost->reformat_ctx); - av_free(ost); - } - } - av_free(ost_table); - } - return ret; -} - -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"; - fprintf(stderr, "pgmyuv format is deprecated, use image2\n"); - } - - last_asked_format = arg; -} - -static void opt_video_rc_override_string(const char *arg) -{ - video_rc_override_string = arg; -} - -static int opt_me_threshold(const char *opt, const char *arg) -{ - me_threshold = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); - return 0; -} - -static int opt_verbose(const char *opt, const char *arg) -{ - verbose = parse_number_or_die(opt, arg, OPT_INT64, -10, 10); - return 0; -} - -static int opt_frame_rate(const char *opt, const char *arg) -{ - if (av_parse_video_frame_rate(&frame_rate, arg) < 0) { - fprintf(stderr, "Incorrect value for %s: %s\n", opt, arg); - av_exit(1); - } - return 0; -} - -static int opt_bitrate(const char *opt, const char *arg) -{ - int codec_type = opt[0]=='a' ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO; - - opt_default(opt, arg); - - if (av_get_int(avcodec_opts[codec_type], "b", NULL) < 1000) - fprintf(stderr, "WARNING: The bitrate parameter is set too low. It takes bits/s as argument, not kbits/s\n"); - - return 0; -} - -static void opt_frame_crop_top(const char *arg) -{ - frame_topBand = atoi(arg); - if (frame_topBand < 0) { - fprintf(stderr, "Incorrect top crop size\n"); - av_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"); - av_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"); - av_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"); - av_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"); - av_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"); - av_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"); - av_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"); - av_exit(1); - } - frame_width -= frame_rightBand; -} - -static void opt_frame_size(const char *arg) -{ - if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) { - fprintf(stderr, "Incorrect frame size\n"); - av_exit(1); - } -} - -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"); - av_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"); - av_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"); - av_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"); - av_exit(1); - } -} - -static void opt_frame_pix_fmt(const char *arg) -{ - if (strcmp(arg, "list")) { - frame_pix_fmt = av_get_pix_fmt(arg); - if (frame_pix_fmt == PIX_FMT_NONE) { - fprintf(stderr, "Unknown pixel format requested: %s\n", arg); - av_exit(1); - } - } else { - show_pix_fmts(); - av_exit(0); - } -} - -static void opt_frame_aspect_ratio(const char *arg) -{ - int x = 0, y = 0; - double ar = 0; - const char *p; - char *end; - - p = strchr(arg, ':'); - if (p) { - x = strtol(arg, &end, 10); - if (end == p) - y = strtol(end+1, &end, 10); - if (x > 0 && y > 0) - ar = (double)x / (double)y; - } else - ar = strtod(arg, NULL); - - if (!ar) { - fprintf(stderr, "Incorrect aspect ratio specification.\n"); - av_exit(1); - } - frame_aspect_ratio = ar; -} - -static int opt_metadata(const char *opt, const char *arg) -{ - char *mid= strchr(arg, '='); - - if(!mid){ - fprintf(stderr, "Missing =\n"); - av_exit(1); - } - *mid++= 0; - - metadata_count++; - metadata= av_realloc(metadata, sizeof(*metadata)*metadata_count); - metadata[metadata_count-1].key = av_strdup(arg); - metadata[metadata_count-1].value= av_strdup(mid); - - return 0; -} - -static void opt_qscale(const char *arg) -{ - video_qscale = atof(arg); - if (video_qscale <= 0 || - video_qscale > 255) { - fprintf(stderr, "qscale must be > 0.0 and <= 255\n"); - av_exit(1); - } -} - -static void opt_top_field_first(const char *arg) -{ - top_field_first= atoi(arg); -} - -static int opt_thread_count(const char *opt, const char *arg) -{ - thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); -#if !HAVE_THREADS - if (verbose >= 0) - fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n"); -#endif - return 0; -} - -static void opt_audio_sample_fmt(const char *arg) -{ - if (strcmp(arg, "list")) - audio_sample_fmt = avcodec_get_sample_fmt(arg); - else { - list_fmts(avcodec_sample_fmt_string, SAMPLE_FMT_NB); - av_exit(0); - } -} - -static int opt_audio_rate(const char *opt, const char *arg) -{ - audio_sample_rate = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); - return 0; -} - -static int opt_audio_channels(const char *opt, const char *arg) -{ - audio_channels = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); - return 0; -} - -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_codec(int *pstream_copy, char **pcodec_name, - int codec_type, const char *arg) -{ - av_freep(pcodec_name); - if (!strcmp(arg, "copy")) { - *pstream_copy = 1; - } else { - *pcodec_name = av_strdup(arg); - } -} - -static void opt_audio_codec(const char *arg) -{ - opt_codec(&audio_stream_copy, &audio_codec_name, AVMEDIA_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 opt_video_codec(const char *arg) -{ - opt_codec(&video_stream_copy, &video_codec_name, AVMEDIA_TYPE_VIDEO, arg); -} - -static void opt_subtitle_codec(const char *arg) -{ - opt_codec(&subtitle_stream_copy, &subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, arg); -} - -static void opt_subtitle_tag(const char *arg) -{ - char *tail; - subtitle_codec_tag= strtol(arg, &tail, 0); - - if(!tail || *tail) - subtitle_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24); -} - -static void opt_map(const char *arg) -{ - AVStreamMap *m; - char *p; - - m = &stream_maps[nb_stream_maps++]; - - m->file_index = strtol(arg, &p, 0); - if (*p) - p++; - - m->stream_index = strtol(p, &p, 0); - if (*p) { - p++; - m->sync_file_index = strtol(p, &p, 0); - if (*p) - p++; - m->sync_stream_index = strtol(p, &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; - char *p; - - m = &meta_data_maps[nb_meta_data_maps++]; - - m->out_file = strtol(arg, &p, 0); - if (*p) - p++; - - m->in_file = strtol(p, &p, 0); -} - -static void opt_input_ts_scale(const char *arg) -{ - unsigned int stream; - double scale; - char *p; - - stream = strtol(arg, &p, 0); - if (*p) - p++; - scale= strtod(p, &p); - - if(stream >= MAX_STREAMS) - av_exit(1); - - input_files_ts_scale[nb_input_files][stream]= scale; -} - -static int opt_recording_time(const char *opt, const char *arg) -{ - recording_time = parse_time_or_die(opt, arg, 1); - return 0; -} - -static int opt_start_time(const char *opt, const char *arg) -{ - start_time = parse_time_or_die(opt, arg, 1); - return 0; -} - -static int opt_rec_timestamp(const char *opt, const char *arg) -{ - rec_timestamp = parse_time_or_die(opt, arg, 0) / 1000000; - return 0; -} - -static int opt_input_ts_offset(const char *opt, const char *arg) -{ - input_ts_offset = parse_time_or_die(opt, arg, 1); - return 0; -} - -static enum CodecID find_codec_or_die(const char *name, int type, int encoder, int strict) -{ - const char *codec_string = encoder ? "encoder" : "decoder"; - AVCodec *codec; - - if(!name) - return CODEC_ID_NONE; - codec = encoder ? - avcodec_find_encoder_by_name(name) : - avcodec_find_decoder_by_name(name); - if(!codec) { - fprintf(stderr, "Unknown %s '%s'\n", codec_string, name); - av_exit(1); - } - if(codec->type != type) { - fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name); - av_exit(1); - } - if(codec->capabilities & CODEC_CAP_EXPERIMENTAL && - strict > FF_COMPLIANCE_EXPERIMENTAL) { - fprintf(stderr, "%s '%s' is experimental and might produce bad " - "results.\nAdd '-strict experimental' if you want to use it.\n", - codec_string, codec->name); - codec = encoder ? - avcodec_find_encoder(codec->id) : - avcodec_find_decoder(codec->id); - if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL)) - fprintf(stderr, "Or use the non experimental %s '%s'.\n", - codec_string, codec->name); - av_exit(1); - } - return codec->id; -} - -static void opt_input_file(const char *filename) -{ - AVFormatContext *ic; - AVFormatParameters params, *ap = ¶ms; - AVInputFormat *file_iformat = NULL; - int err, i, ret, rfps, rfps_base; - int64_t timestamp; - - if (last_asked_format) { - if (!(file_iformat = av_find_input_format(last_asked_format))) { - fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format); - av_exit(1); - } - last_asked_format = NULL; - } - - if (!strcmp(filename, "-")) - filename = "pipe:"; - - using_stdin |= !strncmp(filename, "pipe:", 5) || - !strcmp(filename, "/dev/stdin"); - - /* get default parameters from command line */ - ic = avformat_alloc_context(); - if (!ic) { - print_error(filename, AVERROR(ENOMEM)); - av_exit(1); - } - - memset(ap, 0, sizeof(*ap)); - ap->prealloced_context = 1; - ap->sample_rate = audio_sample_rate; - ap->channels = audio_channels; - ap->time_base.den = frame_rate.num; - ap->time_base.num = frame_rate.den; - ap->width = frame_width + frame_padleft + frame_padright; - ap->height = frame_height + frame_padtop + frame_padbottom; - ap->pix_fmt = frame_pix_fmt; - // ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat - ap->channel = video_channel; - ap->standard = video_standard; - - set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM); - - ic->video_codec_id = - find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0, - avcodec_opts[AVMEDIA_TYPE_VIDEO ]->strict_std_compliance); - ic->audio_codec_id = - find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0, - avcodec_opts[AVMEDIA_TYPE_AUDIO ]->strict_std_compliance); - ic->subtitle_codec_id= - find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0, - avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance); - ic->flags |= AVFMT_FLAG_NONBLOCK; - - if(pgmyuv_compatibility_hack) - ic->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); - av_exit(1); - } - if(opt_programid) { - int i, j; - int found=0; - for(i=0; inb_streams; i++){ - ic->streams[i]->discard= AVDISCARD_ALL; - } - for(i=0; inb_programs; i++){ - AVProgram *p= ic->programs[i]; - if(p->id != opt_programid){ - p->discard = AVDISCARD_ALL; - }else{ - found=1; - for(j=0; jnb_stream_indexes; j++){ - ic->streams[p->stream_index[j]]->discard= AVDISCARD_DEFAULT; - } - } - } - if(!found){ - fprintf(stderr, "Specified program id not found\n"); - av_exit(1); - } - opt_programid=0; - } - - ic->loop_input = loop_input; - - /* 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); - av_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++) { - AVStream *st = ic->streams[i]; - AVCodecContext *enc = st->codec; - avcodec_thread_init(enc, thread_count); - switch(enc->codec_type) { - case AVMEDIA_TYPE_AUDIO: - set_context_opts(enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM); - //fprintf(stderr, "\nInput Audio channels: %d", enc->channels); - channel_layout = enc->channel_layout; - audio_channels = enc->channels; - audio_sample_rate = enc->sample_rate; - audio_sample_fmt = enc->sample_fmt; - input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name); - if(audio_disable) - st->discard= AVDISCARD_ALL; - break; - case AVMEDIA_TYPE_VIDEO: - set_context_opts(enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM); - frame_height = enc->height; - frame_width = enc->width; - if(ic->streams[i]->sample_aspect_ratio.num) - frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio); - else - frame_aspect_ratio=av_q2d(enc->sample_aspect_ratio); - frame_aspect_ratio *= (float) 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; - if(enc->lowres) { - enc->flags |= CODEC_FLAG_EMU_EDGE; - frame_height >>= enc->lowres; - frame_width >>= enc->lowres; - } - if(me_threshold) - enc->debug |= FF_DEBUG_MV; - - if (enc->time_base.den != rfps*enc->ticks_per_frame || enc->time_base.num != rfps_base) { - - if (verbose >= 0) - fprintf(stderr,"\nSeems stream %d codec frame rate differs from container frame rate: %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.num = rfps; - frame_rate.den = rfps_base; - - input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name); - if(video_disable) - st->discard= AVDISCARD_ALL; - else if(video_discard) - st->discard= video_discard; - break; - case AVMEDIA_TYPE_DATA: - break; - case AVMEDIA_TYPE_SUBTITLE: - input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(subtitle_codec_name); - if(subtitle_disable) - st->discard = AVDISCARD_ALL; - break; - case AVMEDIA_TYPE_ATTACHMENT: - case AVMEDIA_TYPE_UNKNOWN: - nb_icodecs++; - break; - default: - 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++; - - video_channel = 0; - - av_freep(&video_codec_name); - av_freep(&audio_codec_name); - av_freep(&subtitle_codec_name); -} - -static void check_audio_video_sub_inputs(int *has_video_ptr, int *has_audio_ptr, - int *has_subtitle_ptr) -{ - int has_video, has_audio, has_subtitle, i, j; - AVFormatContext *ic; - - has_video = 0; - has_audio = 0; - has_subtitle = 0; - for(j=0;jnb_streams;i++) { - AVCodecContext *enc = ic->streams[i]->codec; - switch(enc->codec_type) { - case AVMEDIA_TYPE_AUDIO: - has_audio = 1; - break; - case AVMEDIA_TYPE_VIDEO: - has_video = 1; - break; - case AVMEDIA_TYPE_SUBTITLE: - has_subtitle = 1; - break; - case AVMEDIA_TYPE_DATA: - case AVMEDIA_TYPE_ATTACHMENT: - case AVMEDIA_TYPE_UNKNOWN: - break; - default: - abort(); - } - } - } - *has_video_ptr = has_video; - *has_audio_ptr = has_audio; - *has_subtitle_ptr = has_subtitle; -} - -static void new_video_stream(AVFormatContext *oc) -{ - AVStream *st; - AVCodecContext *video_enc; - enum CodecID codec_id; - - st = av_new_stream(oc, oc->nb_streams); - if (!st) { - fprintf(stderr, "Could not alloc stream\n"); - av_exit(1); - } - avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_VIDEO); - bitstream_filters[nb_output_files][oc->nb_streams - 1]= video_bitstream_filters; - video_bitstream_filters= NULL; - - avcodec_thread_init(st->codec, thread_count); - - 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; - avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER; - } - if(video_global_header&2){ - video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER; - avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER; - } - - if (video_stream_copy) { - st->stream_copy = 1; - video_enc->codec_type = AVMEDIA_TYPE_VIDEO; - video_enc->sample_aspect_ratio = - st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); - } else { - const char *p; - int i; - AVCodec *codec; - AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1}; - - if (video_codec_name) { - codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1, - video_enc->strict_std_compliance); - codec = avcodec_find_encoder_by_name(video_codec_name); - output_codecs[nb_ocodecs] = codec; - } else { - codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); - codec = avcodec_find_encoder(codec_id); - } - - video_enc->codec_id = codec_id; - - set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM); - - if (codec && codec->supported_framerates && !force_fps) - fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)]; - video_enc->time_base.den = fps.num; - video_enc->time_base.num = fps.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*video_enc->height/video_enc->width, 255); - video_enc->pix_fmt = frame_pix_fmt; - st->sample_aspect_ratio = video_enc->sample_aspect_ratio; - - choose_pixel_fmt(st, codec); - - if (intra_only) - 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; - - 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"); - av_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; - if (!video_enc->rc_initial_buffer_occupancy) - video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4; - video_enc->me_threshold= me_threshold; - video_enc->intra_dc_precision= intra_dc_precision - 8; - - if (do_psnr) - video_enc->flags|= CODEC_FLAG_PSNR; - - /* two pass mode */ - if (do_pass) { - if (do_pass == 1) { - video_enc->flags |= CODEC_FLAG_PASS1; - } else { - video_enc->flags |= CODEC_FLAG_PASS2; - } - } - } - nb_ocodecs++; - if (video_language) { - av_metadata_set2(&st->metadata, "language", video_language, 0); - av_freep(&video_language); - } - - /* reset some key parameters */ - video_disable = 0; - av_freep(&video_codec_name); - video_stream_copy = 0; - frame_pix_fmt = PIX_FMT_NONE; -} - -static void new_audio_stream(AVFormatContext *oc) -{ - AVStream *st; - AVCodecContext *audio_enc; - enum CodecID codec_id; - - st = av_new_stream(oc, oc->nb_streams); - if (!st) { - fprintf(stderr, "Could not alloc stream\n"); - av_exit(1); - } - avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_AUDIO); - - bitstream_filters[nb_output_files][oc->nb_streams - 1]= audio_bitstream_filters; - audio_bitstream_filters= NULL; - - avcodec_thread_init(st->codec, thread_count); - - audio_enc = st->codec; - audio_enc->codec_type = AVMEDIA_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; - avcodec_opts[AVMEDIA_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER; - } - if (audio_stream_copy) { - st->stream_copy = 1; - audio_enc->channels = audio_channels; - audio_enc->sample_rate = audio_sample_rate; - } else { - AVCodec *codec; - - set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM); - - if (audio_codec_name) { - codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1, - audio_enc->strict_std_compliance); - codec = avcodec_find_encoder_by_name(audio_codec_name); - output_codecs[nb_ocodecs] = codec; - } else { - codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO); - codec = avcodec_find_encoder(codec_id); - } - audio_enc->codec_id = codec_id; - - if (audio_qscale > QSCALE_NONE) { - audio_enc->flags |= CODEC_FLAG_QSCALE; - audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale; - } - audio_enc->channels = audio_channels; - audio_enc->sample_fmt = audio_sample_fmt; - audio_enc->sample_rate = audio_sample_rate; - audio_enc->channel_layout = channel_layout; - if (avcodec_channel_layout_num_channels(channel_layout) != audio_channels) - audio_enc->channel_layout = 0; - choose_sample_fmt(st, codec); - choose_sample_rate(st, codec); - } - nb_ocodecs++; - audio_enc->time_base= (AVRational){1, audio_sample_rate}; - if (audio_language) { - av_metadata_set2(&st->metadata, "language", audio_language, 0); - av_freep(&audio_language); - } - - /* reset some key parameters */ - audio_disable = 0; - av_freep(&audio_codec_name); - audio_stream_copy = 0; -} - -static void new_subtitle_stream(AVFormatContext *oc) -{ - AVStream *st; - AVCodecContext *subtitle_enc; - - st = av_new_stream(oc, oc->nb_streams); - if (!st) { - fprintf(stderr, "Could not alloc stream\n"); - av_exit(1); - } - avcodec_get_context_defaults2(st->codec, AVMEDIA_TYPE_SUBTITLE); - - bitstream_filters[nb_output_files][oc->nb_streams - 1]= subtitle_bitstream_filters; - subtitle_bitstream_filters= NULL; - - subtitle_enc = st->codec; - subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE; - - if(subtitle_codec_tag) - subtitle_enc->codec_tag= subtitle_codec_tag; - - if (subtitle_stream_copy) { - st->stream_copy = 1; - } else { - set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM); - subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1, - subtitle_enc->strict_std_compliance); - output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name); - } - nb_ocodecs++; - - if (subtitle_language) { - av_metadata_set2(&st->metadata, "language", subtitle_language, 0); - av_freep(&subtitle_language); - } - - subtitle_disable = 0; - av_freep(&subtitle_codec_name); - 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"); - av_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"); - av_exit(1); - } - oc = output_files[nb_output_files - 1]; - new_video_stream(oc); -} - -static void opt_new_subtitle_stream(void) -{ - AVFormatContext *oc; - if (nb_output_files <= 0) { - fprintf(stderr, "At least one output file must be specified\n"); - av_exit(1); - } - oc = output_files[nb_output_files - 1]; - new_subtitle_stream(oc); -} - -static void opt_output_file(const char *filename) -{ - AVFormatContext *oc; - int err, use_video, use_audio, use_subtitle; - int input_has_video, input_has_audio, input_has_subtitle; - AVFormatParameters params, *ap = ¶ms; - AVOutputFormat *file_oformat; - - if (!strcmp(filename, "-")) - filename = "pipe:"; - - oc = avformat_alloc_context(); - if (!oc) { - print_error(filename, AVERROR(ENOMEM)); - av_exit(1); - } - - if (last_asked_format) { - file_oformat = av_guess_format(last_asked_format, NULL, NULL); - if (!file_oformat) { - fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", last_asked_format); - av_exit(1); - } - last_asked_format = NULL; - } else { - file_oformat = av_guess_format(NULL, filename, NULL); - if (!file_oformat) { - fprintf(stderr, "Unable to find a suitable output format for '%s'\n", - filename); - av_exit(1); - } - } - - oc->oformat = file_oformat; - av_strlcpy(oc->filename, filename, sizeof(oc->filename)); - - if (!strcmp(file_oformat->name, "ffm") && - av_strstart(filename, "http:", NULL)) { - /* special case for files sent to ffserver: we get the stream - parameters from ffserver */ - int err = read_ffserver_streams(oc, filename); - if (err < 0) { - print_error(filename, err); - av_exit(1); - } - } else { - use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_name; - use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_name; - use_subtitle = file_oformat->subtitle_codec != CODEC_ID_NONE || subtitle_stream_copy || subtitle_codec_name; - - /* disable if no corresponding type found and at least one - input file */ - if (nb_input_files > 0) { - check_audio_video_sub_inputs(&input_has_video, &input_has_audio, - &input_has_subtitle); - if (!input_has_video) - use_video = 0; - if (!input_has_audio) - use_audio = 0; - if (!input_has_subtitle) - use_subtitle = 0; - } - - /* manual disable */ - if (audio_disable) { - use_audio = 0; - } - if (video_disable) { - use_video = 0; - } - if (subtitle_disable) { - use_subtitle = 0; - } - - if (use_video) { - new_video_stream(oc); - } - - if (use_audio) { - new_audio_stream(oc); - } - - if (use_subtitle) { - new_subtitle_stream(oc); - } - - oc->timestamp = rec_timestamp; - - for(; metadata_count>0; metadata_count--){ - av_metadata_set2(&oc->metadata, metadata[metadata_count-1].key, - metadata[metadata_count-1].value, 0); - } - av_metadata_conv(oc, oc->oformat->metadata_conv, NULL); - } - - output_files[nb_output_files++] = oc; - - /* check filename in case of an image number is expected */ - if (oc->oformat->flags & AVFMT_NEEDNUMBER) { - if (!av_filename_number_test(oc->filename)) { - print_error(oc->filename, AVERROR_NUMEXPECTED); - av_exit(1); - } - } - - if (!(oc->oformat->flags & AVFMT_NOFILE)) { - /* test if it already exists to avoid loosing precious files */ - if (!file_overwrite && - (strchr(filename, ':') == NULL || - filename[1] == ':' || - av_strstart(filename, "file:", NULL))) { - if (url_exist(filename)) { - if (!using_stdin) { - fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename); - fflush(stderr); - if (!read_yesno()) { - fprintf(stderr, "Not overwriting - exiting\n"); - av_exit(1); - } - } - else { - fprintf(stderr,"File '%s' already exists. Exiting.\n", filename); - av_exit(1); - } - } - } - - /* open the file */ - if ((err = url_fopen(&oc->pb, filename, URL_WRONLY)) < 0) { - print_error(filename, err); - av_exit(1); - } - } - - memset(ap, 0, sizeof(*ap)); - if (av_set_parameters(oc, ap) < 0) { - fprintf(stderr, "%s: Invalid encoding parameters\n", - oc->filename); - av_exit(1); - } - - oc->preload= (int)(mux_preload*AV_TIME_BASE); - oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE); - oc->loop_output = loop_output; - oc->flags |= AVFMT_FLAG_NONBLOCK; - - set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM); -} - -/* 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"); - av_exit(1); - } - do_pass = pass; -} - -static int64_t getutime(void) -{ -#if HAVE_GETRUSAGE - struct rusage rusage; - - getrusage(RUSAGE_SELF, &rusage); - return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec; -#elif HAVE_GETPROCESSTIMES - HANDLE proc; - FILETIME c, e, k, u; - proc = GetCurrentProcess(); - GetProcessTimes(proc, &c, &e, &k, &u); - return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10; -#else - return av_gettime(); -#endif -} - -static int64_t getmaxrss(void) -{ -#if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS - struct rusage rusage; - getrusage(RUSAGE_SELF, &rusage); - return (int64_t)rusage.ru_maxrss * 1024; -#elif HAVE_GETPROCESSMEMORYINFO - HANDLE proc; - PROCESS_MEMORY_COUNTERS memcounters; - proc = GetCurrentProcess(); - memcounters.cb = sizeof(memcounters); - GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters)); - return memcounters.PeakPagefileUsage; -#else - return 0; -#endif -} - -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); - av_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); -} - -/** - * Trivial log callback. - * Only suitable for show_help and similar since it lacks prefix handling. - */ -static void log_callback_help(void* ptr, int level, const char* fmt, va_list vl) -{ - vfprintf(stdout, fmt, vl); -} - -static void show_usage(void) -{ - printf("Hyper fast Audio and Video encoder\n"); - printf("usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...\n"); - printf("\n"); -} - -static void show_help(void) -{ - av_log_set_callback(log_callback_help); - show_usage(); - show_help_options(options, "Main options:\n", - OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB, 0); - show_help_options(options, "\nAdvanced options:\n", - OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB, - OPT_EXPERT); - 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); - printf("\n"); - av_opt_show(avcodec_opts[0], NULL); - printf("\n"); - av_opt_show(avformat_opts, NULL); - printf("\n"); - av_opt_show(sws_opts, NULL); -} - -static void opt_target(const char *arg) -{ - enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN; - static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"}; - - if(!strncmp(arg, "pal-", 4)) { - norm = PAL; - arg += 4; - } else if(!strncmp(arg, "ntsc-", 5)) { - norm = NTSC; - arg += 5; - } else if(!strncmp(arg, "film-", 5)) { - norm = FILM; - arg += 5; - } else { - int fr; - /* Calculate FR via float to avoid int overflow */ - fr = (int)(frame_rate.num * 1000.0 / frame_rate.den); - if(fr == 25000) { - norm = PAL; - } else if((fr == 29970) || (fr == 23976)) { - norm = NTSC; - } 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 != AVMEDIA_TYPE_VIDEO) - continue; - fr = c->time_base.den * 1000 / c->time_base.num; - if(fr == 25000) { - norm = PAL; - break; - } else if((fr == 29970) || (fr == 23976)) { - norm = NTSC; - break; - } - } - if(norm != UNKNOWN) - break; - } - } - } - if(verbose && norm != UNKNOWN) - fprintf(stderr, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC"); - } - - if(norm == UNKNOWN) { - 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"); - av_exit(1); - } - - if(!strcmp(arg, "vcd")) { - - opt_video_codec("mpeg1video"); - opt_audio_codec("mp2"); - opt_format("vcd"); - - opt_frame_size(norm == PAL ? "352x288" : "352x240"); - opt_frame_rate(NULL, frame_rates[norm]); - opt_default("g", norm == PAL ? "15" : "18"); - - opt_default("b", "1150000"); - opt_default("maxrate", "1150000"); - opt_default("minrate", "1150000"); - opt_default("bufsize", "327680"); // 40*1024*8; - - opt_default("ab", "224000"); - audio_sample_rate = 44100; - audio_channels = 2; - - opt_default("packetsize", "2324"); - opt_default("muxrate", "1411200"); // 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 == PAL ? "480x576" : "480x480"); - opt_frame_rate(NULL, frame_rates[norm]); - opt_default("g", norm == PAL ? "15" : "18"); - - opt_default("b", "2040000"); - opt_default("maxrate", "2516000"); - opt_default("minrate", "0"); //1145000; - opt_default("bufsize", "1835008"); //224*1024*8; - opt_default("flags", "+scan_offset"); - - - opt_default("ab", "224000"); - audio_sample_rate = 44100; - - opt_default("packetsize", "2324"); - - } else if(!strcmp(arg, "dvd")) { - - opt_video_codec("mpeg2video"); - opt_audio_codec("ac3"); - opt_format("dvd"); - - opt_frame_size(norm == PAL ? "720x576" : "720x480"); - opt_frame_rate(NULL, frame_rates[norm]); - opt_default("g", norm == PAL ? "15" : "18"); - - opt_default("b", "6000000"); - opt_default("maxrate", "9000000"); - opt_default("minrate", "0"); //1500000; - opt_default("bufsize", "1835008"); //224*1024*8; - - opt_default("packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack. - opt_default("muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8 - - opt_default("ab", "448000"); - audio_sample_rate = 48000; - - } else if(!strncmp(arg, "dv", 2)) { - - opt_format("dv"); - - opt_frame_size(norm == PAL ? "720x576" : "720x480"); - opt_frame_pix_fmt(!strncmp(arg, "dv50", 4) ? "yuv422p" : - (norm == PAL ? "yuv420p" : "yuv411p")); - opt_frame_rate(NULL, frame_rates[norm]); - - audio_sample_rate = 48000; - audio_channels = 2; - - } else { - fprintf(stderr, "Unknown target: %s\n", arg); - av_exit(1); - } -} - -static void opt_vstats_file (const char *arg) -{ - av_free (vstats_filename); - vstats_filename=av_strdup (arg); -} - -static void opt_vstats (void) -{ - char filename[40]; - time_t today2 = time(NULL); - struct tm *today = localtime(&today2); - - snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min, - today->tm_sec); - opt_vstats_file(filename); -} - -static int opt_bsf(const char *opt, const char *arg) -{ - AVBitStreamFilterContext *bsfc= av_bitstream_filter_init(arg); //FIXME split name and args for filter at '=' - AVBitStreamFilterContext **bsfp; - - if(!bsfc){ - fprintf(stderr, "Unknown bitstream filter %s\n", arg); - av_exit(1); - } - - bsfp= *opt == 'v' ? &video_bitstream_filters : - *opt == 'a' ? &audio_bitstream_filters : - &subtitle_bitstream_filters; - while(*bsfp) - bsfp= &(*bsfp)->next; - - *bsfp= bsfc; - - return 0; -} - -static int opt_preset(const char *opt, const char *arg) -{ - FILE *f=NULL; - char filename[1000], tmp[1000], tmp2[1000], line[1000]; - int i; - const char *base[3]= { getenv("FFMPEG_DATADIR"), - getenv("HOME"), - FFMPEG_DATADIR, - }; - - if (*opt != 'f') { - for(i=0; i<3 && !f; i++){ - if(!base[i]) - continue; - snprintf(filename, sizeof(filename), "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", arg); - f= fopen(filename, "r"); - if(!f){ - char *codec_name= *opt == 'v' ? video_codec_name : - *opt == 'a' ? audio_codec_name : - subtitle_codec_name; - snprintf(filename, sizeof(filename), "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", codec_name, arg); - f= fopen(filename, "r"); - } - } - } else { - av_strlcpy(filename, arg, sizeof(filename)); - f= fopen(filename, "r"); - } - - if(!f){ - fprintf(stderr, "File for preset '%s' not found\n", arg); - av_exit(1); - } - - while(!feof(f)){ - int e= fscanf(f, "%999[^\n]\n", line) - 1; - if(line[0] == '#' && !e) - continue; - e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2; - if(e){ - fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line); - av_exit(1); - } - if(!strcmp(tmp, "acodec")){ - opt_audio_codec(tmp2); - }else if(!strcmp(tmp, "vcodec")){ - opt_video_codec(tmp2); - }else if(!strcmp(tmp, "scodec")){ - opt_subtitle_codec(tmp2); - }else if(opt_default(tmp, tmp2) < 0){ - fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2); - av_exit(1); - } - } - - fclose(f); - - return 0; -} - -static const OptionDef options[] = { - /* main options */ -#include "cmdutils_common_opts.h" - { "f", HAS_ARG, {(void*)opt_format}, "force format", "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", OPT_FUNC2 | HAS_ARG, {(void*)opt_recording_time}, "record or transcode \"duration\" seconds of audio/video", "duration" }, - { "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, // - { "ss", OPT_FUNC2 | HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" }, - { "itsoffset", OPT_FUNC2 | HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" }, - { "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "stream:scale" }, - { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)opt_rec_timestamp}, "set the timestamp ('now' to set the current time)", "time" }, - { "metadata", OPT_FUNC2 | HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" }, - { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" }, - { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark}, - "add timings for benchmarking" }, - { "timelimit", OPT_FUNC2 | HAS_ARG, {(void*)opt_timelimit}, "set max runtime in seconds", "limit" }, - { "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 | OPT_FUNC2, {(void*)opt_verbose}, "set ffmpeg verbosity level", "number" }, - { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, - { "threads", OPT_FUNC2 | 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", "" }, - { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&audio_drift_threshold}, "audio drift threshold", "threshold" }, - { "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_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" }, - { "programid", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&opt_programid}, "desired program number", "" }, - { "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" }, - { "copyinkf", OPT_BOOL | OPT_EXPERT, {(void*)©_initial_nonkeyframes}, "copy initial non-keyframes" }, - - /* video options */ - { "b", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, - { "vb", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, - { "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&max_frames[AVMEDIA_TYPE_VIDEO]}, "set the number of video frames to record", "number" }, - { "r", OPT_FUNC2 | 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, 'list' as argument shows all the pixel formats supported", "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" }, - { "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 quantizer scale (VBR)", "q" }, - { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" }, - { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" }, - { "me_threshold", HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "threshold" }, - { "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_prefix}, "select two pass log file name prefix", "prefix" }, - { "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_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" }, - { "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" }, - { "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", "" }, - { "dc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_dc_precision}, "intra_dc_precision", "precision" }, - { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" }, - { "newvideo", OPT_VIDEO, {(void*)opt_new_video_stream}, "add a new video stream to the current output stream" }, - { "vlang", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void *)&video_language}, "set the ISO 639 language code (3 letters) of the current video stream" , "code" }, - { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" }, - { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" }, - - /* audio options */ - { "ab", OPT_FUNC2 | HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" }, - { "aframes", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&max_frames[AVMEDIA_TYPE_AUDIO]}, "set the number of audio frames to record", "number" }, - { "aq", OPT_FLOAT | HAS_ARG | OPT_AUDIO, {(void*)&audio_qscale}, "set audio quality (codec-specific)", "quality", }, - { "ar", HAS_ARG | OPT_FUNC2 | OPT_AUDIO, {(void*)opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" }, - { "ac", HAS_ARG | OPT_FUNC2 | 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" }, - { "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_sample_fmt}, "set sample format, 'list' as argument shows all the sample formats supported", "format" }, - - /* subtitle options */ - { "sn", OPT_BOOL | OPT_SUBTITLE, {(void*)&subtitle_disable}, "disable subtitle" }, - { "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" }, - { "stag", HAS_ARG | OPT_EXPERT | OPT_SUBTITLE, {(void*)opt_subtitle_tag}, "force subtitle tag/fourcc", "fourcc/tag" }, - - /* grab options */ - { "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" }, - { "isync", OPT_BOOL | OPT_EXPERT | OPT_GRAB, {(void*)&input_sync}, "sync read on input", "" }, - - /* muxer options */ - { "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" }, - - { "absf", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_EXPERT, {(void*)opt_bsf}, "", "bitstream_filter" }, - { "vbsf", OPT_FUNC2 | HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_bsf}, "", "bitstream_filter" }, - { "sbsf", OPT_FUNC2 | HAS_ARG | OPT_SUBTITLE | OPT_EXPERT, {(void*)opt_bsf}, "", "bitstream_filter" }, - - { "apre", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_EXPERT, {(void*)opt_preset}, "set the audio options to the indicated preset", "preset" }, - { "vpre", OPT_FUNC2 | HAS_ARG | OPT_VIDEO | OPT_EXPERT, {(void*)opt_preset}, "set the video options to the indicated preset", "preset" }, - { "spre", OPT_FUNC2 | HAS_ARG | OPT_SUBTITLE | OPT_EXPERT, {(void*)opt_preset}, "set the subtitle options to the indicated preset", "preset" }, - { "fpre", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_preset}, "set options from indicated preset file", "filename" }, - - { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" }, - { NULL, }, -}; - -int main(int argc, char **argv) -{ - int i; - int64_t ti; - - avcodec_register_all(); -#if CONFIG_AVDEVICE - avdevice_register_all(); -#endif - av_register_all(); - -#if HAVE_ISATTY - if(isatty(STDIN_FILENO)) - url_set_interrupt_cb(decode_interrupt_cb); -#endif - - for(i=0; i -#include -#include -#include "libavutil/avstring.h" -#include "libavutil/pixdesc.h" -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#include "libswscale/swscale.h" -#include "libavcodec/audioconvert.h" -#include "libavcodec/colorspace.h" -#include "libavcodec/opt.h" -#include "libavcodec/avfft.h" - -#if CONFIG_AVFILTER -# include "libavfilter/avfilter.h" -# include "libavfilter/avfiltergraph.h" -# include "libavfilter/graphparser.h" -#endif - -#include "cmdutils.h" - -#include -#include - -#ifdef __MINGW32__ -#undef main /* We don't want SDL to override our main() */ -#endif - -#include -#include - -const char program_name[] = "FFplay"; -const int program_birth_year = 2003; - -//#define DEBUG_SYNC - -#define MAX_QUEUE_SIZE (15 * 1024 * 1024) -#define MIN_AUDIOQ_SIZE (20 * 16 * 1024) -#define MIN_FRAMES 5 - -/* 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 - -#define FRAME_SKIP_FACTOR 0.05 - -/* 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) - -#if !CONFIG_AVFILTER -static int sws_flags = SWS_BICUBIC; -#endif - -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 2 -#define SUBPICTURE_QUEUE_SIZE 4 - -typedef struct VideoPicture { - double pts; ///mutex = SDL_CreateMutex(); - q->cond = SDL_CreateCond(); - packet_queue_put(q, &flush_pkt); -} - -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 (pkt!=&flush_pkt && 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 + sizeof(*pkt1); - /* 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 + sizeof(*pkt1); - *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 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 imgw, int imgh) -{ - 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; - int dstx, dsty, dstw, dsth; - - dstw = av_clip(rect->w, 0, imgw); - dsth = av_clip(rect->h, 0, imgh); - dstx = av_clip(rect->x, 0, imgw - dstw); - dsty = av_clip(rect->y, 0, imgh - dsth); - lum = dst->data[0] + dsty * dst->linesize[0]; - cb = dst->data[1] + (dsty >> 1) * dst->linesize[1]; - cr = dst->data[2] + (dsty >> 1) * dst->linesize[2]; - - width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1); - skip2 = dstx >> 1; - wrap = dst->linesize[0]; - wrap3 = rect->pict.linesize[0]; - p = rect->pict.data[0]; - pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */ - - if (dsty & 1) { - lum += dstx; - cb += skip2; - cr += skip2; - - if (dstx & 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 = dstw - (dstx & 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++; - lum++; - } - p += wrap3 - dstw * BPP; - lum += wrap - dstw - dstx; - cb += dst->linesize[1] - width2 - skip2; - cr += dst->linesize[2] - width2 - skip2; - } - for(h = dsth - (dsty & 1); h >= 2; h -= 2) { - lum += dstx; - cb += skip2; - cr += skip2; - - if (dstx & 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 = dstw - (dstx & 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); - 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 + 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, 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 - dstw * BPP); - lum += wrap + (wrap - dstw - dstx); - cb += dst->linesize[1] - width2 - skip2; - cr += dst->linesize[2] - width2 - skip2; - } - /* handle odd height */ - if (h) { - lum += dstx; - cb += skip2; - cr += skip2; - - if (dstx & 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 = dstw - (dstx & 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_freep(&sp->sub.rects[i]->pict.data[0]); - av_freep(&sp->sub.rects[i]->pict.data[1]); - av_freep(&sp->sub.rects[i]); - } - - 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) { -#if CONFIG_AVFILTER - if (vp->picref->pixel_aspect.num == 0) - aspect_ratio = 0; - else - aspect_ratio = av_q2d(vp->picref->pixel_aspect); -#else - - /* XXX: use variable in the frame */ - if (is->video_st->sample_aspect_ratio.num) - aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio); - else if (is->video_st->codec->sample_aspect_ratio.num) - aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio); - else - aspect_ratio = 0; -#endif - if (aspect_ratio <= 0.0) - aspect_ratio = 1.0; - aspect_ratio *= (float)vp->width / (float)vp->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], - vp->bmp->w, vp->bmp->h); - - SDL_UnlockYUVOverlay (vp->bmp); - } - } - } - - - /* XXX: we suppose the screen has a 1.0 pixel ratio */ - height = is->height; - width = ((int)rint(height * aspect_ratio)) & ~1; - if (width > is->width) { - width = is->width; - height = ((int)rint(width / aspect_ratio)) & ~1; - } - 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->ytop + 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; - int rdft_bits, nb_freq; - - for(rdft_bits=1; (1<height; rdft_bits++) - ; - nb_freq= 1<<(rdft_bits-1); - - /* compute display index : center on currently output samples */ - channels = s->audio_st->codec->channels; - nb_display_channels = channels; - if (!s->paused) { - int data_used= s->show_audio==1 ? s->width : (2*nb_freq); - 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 += 2*data_used; - if (delay < data_used) - delay = data_used; - - i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE); - if(s->show_audio==1){ - h= INT_MIN; - for(i=0; i<1000; i+=channels){ - int idx= (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE; - int a= s->sample_array[idx]; - int b= s->sample_array[(idx + 4*channels)%SAMPLE_ARRAY_SIZE]; - int c= s->sample_array[(idx + 5*channels)%SAMPLE_ARRAY_SIZE]; - int d= s->sample_array[(idx + 9*channels)%SAMPLE_ARRAY_SIZE]; - int score= a-d; - if(hlast_i_start = i_start; - } else { - i_start = s->last_i_start; - } - - bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); - if(s->show_audio==1){ - 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); - }else{ - nb_display_channels= FFMIN(nb_display_channels, 2); - if(rdft_bits != s->rdft_bits){ - av_rdft_end(s->rdft); - s->rdft = av_rdft_init(rdft_bits, DFT_R2C); - s->rdft_bits= rdft_bits; - } - { - FFTSample data[2][2*nb_freq]; - for(ch = 0;ch < nb_display_channels; ch++) { - i = i_start + ch; - for(x = 0; x < 2*nb_freq; x++) { - double w= (x-nb_freq)*(1.0/nb_freq); - data[ch][x]= s->sample_array[i]*(1.0-w*w); - i += channels; - if (i >= SAMPLE_ARRAY_SIZE) - i -= SAMPLE_ARRAY_SIZE; - } - av_rdft_calc(s->rdft, data[ch]); - } - //least efficient way to do this, we should of course directly access it but its more than fast enough - for(y=0; yheight; y++){ - double w= 1/sqrt(nb_freq); - int a= sqrt(w*sqrt(data[0][2*y+0]*data[0][2*y+0] + data[0][2*y+1]*data[0][2*y+1])); - int b= sqrt(w*sqrt(data[1][2*y+0]*data[1][2*y+0] + data[1][2*y+1]*data[1][2*y+1])); - a= FFMIN(a,255); - b= FFMIN(b,255); - fgcolor = SDL_MapRGB(screen->format, a, b, (a+b)/2); - - fill_rectangle(screen, - s->xpos, s->height-y, 1, 1, - fgcolor); - } - } - SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height); - s->xpos++; - if(s->xpos >= s->width) - s->xpos= s->xleft; - } -} - -static int video_open(VideoState *is){ - int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; - int w,h; - - if(is_full_screen) flags |= SDL_FULLSCREEN; - else flags |= SDL_RESIZABLE; - - if (is_full_screen && fs_screen_width) { - w = fs_screen_width; - h = fs_screen_height; - } else if(!is_full_screen && screen_width){ - w = screen_width; - h = screen_height; -#if CONFIG_AVFILTER - }else if (is->out_video_filter && is->out_video_filter->inputs[0]){ - w = is->out_video_filter->inputs[0]->w; - h = is->out_video_filter->inputs[0]->h; -#else - }else if (is->video_st && is->video_st->codec->width){ - w = is->video_st->codec->width; - h = is->video_st->codec->height; -#endif - } else { - w = 640; - h = 480; - } - if(screen && is->width == screen->w && screen->w == w - && is->height== screen->h && screen->h == h) - return 0; - -#ifndef __APPLE__ - screen = SDL_SetVideoMode(w, h, 0, flags); -#else - /* setting bits_per_pixel = 0 or 32 causes blank video on OS X */ - screen = SDL_SetVideoMode(w, h, 24, flags); -#endif - if (!screen) { - fprintf(stderr, "SDL: could not set video mode - exiting\n"); - return -1; - } - if (!window_title) - window_title = input_filename; - SDL_WM_SetCaption(window_title, window_title); - - is->width = screen->w; - is->height = screen->h; - - return 0; -} - -/* display the current picture, if any */ -static void video_display(VideoState *is) -{ - if(!screen) - video_open(cur_stream); - if (is->audio_st && is->show_audio) - video_audio_display(is); - else if (is->video_st) - video_image_display(is); -} - -static int refresh_thread(void *opaque) -{ - VideoState *is= opaque; - while(!is->abort_request){ - SDL_Event event; - event.type = FF_REFRESH_EVENT; - event.user.data1 = opaque; - if(!is->refresh){ - is->refresh=1; - SDL_PushEvent(&event); - } - usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000); //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly - } - return 0; -} - -/* 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) -{ - if (is->paused) { - return is->video_current_pts; - } else { - return is->video_current_pts_drift + av_gettime() / 1000000.0; - } -} - -/* 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, int64_t rel, int seek_by_bytes) -{ - if (!is->seek_req) { - is->seek_pos = pos; - is->seek_rel = rel; - is->seek_flags &= ~AVSEEK_FLAG_BYTE; - if (seek_by_bytes) - is->seek_flags |= AVSEEK_FLAG_BYTE; - is->seek_req = 1; - } -} - -/* pause or resume the video */ -static void stream_pause(VideoState *is) -{ - if (is->paused) { - is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts; - if(is->read_pause_return != AVERROR(ENOSYS)){ - is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0; - } - is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0; - } - is->paused = !is->paused; -} - -static double compute_target_time(double frame_current_pts, VideoState *is) -{ - double delay, sync_threshold, diff; - - /* compute nominal delay */ - delay = frame_current_pts - is->frame_last_pts; - if (delay <= 0 || delay >= 10.0) { - /* if incorrect delay, use previous one */ - delay = is->frame_last_delay; - } else { - is->frame_last_delay = delay; - } - is->frame_last_pts = frame_current_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 */ - diff = get_video_clock(is) - get_master_clock(is); - - /* 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 = FFMAX(AV_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; -#if defined(DEBUG_SYNC) - printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n", - delay, actual_delay, frame_current_pts, -diff); -#endif - - return is->frame_timer; -} - -/* called to display each frame */ -static void video_refresh_timer(void *opaque) -{ - VideoState *is = opaque; - VideoPicture *vp; - - SubPicture *sp, *sp2; - - if (is->video_st) { -retry: - if (is->pictq_size == 0) { - //nothing to do, no picture to display in the que - } else { - double time= av_gettime()/1000000.0; - double next_target; - /* dequeue the picture */ - vp = &is->pictq[is->pictq_rindex]; - - if(time < vp->target_clock) - return; - /* update current video pts */ - is->video_current_pts = vp->pts; - is->video_current_pts_drift = is->video_current_pts - time; - is->video_current_pos = vp->pos; - if(is->pictq_size > 1){ - VideoPicture *nextvp= &is->pictq[(is->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE]; - assert(nextvp->target_clock >= vp->target_clock); - next_target= nextvp->target_clock; - }else{ - next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly - } - if(framedrop && time > next_target){ - is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR; - if(is->pictq_size > 1 || time > next_target + 0.5){ - /* 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); - goto retry; - } - } - - 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 */ - - /* if only audio stream, then display the audio bars (better - than nothing, just to test the implementation */ - - /* display picture */ - video_display(is); - } - 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) >= 30000) { - 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 s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r", - get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts); - 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 CONFIG_AVFILTER - if (vp->picref) - avfilter_unref_pic(vp->picref); - vp->picref = NULL; - - vp->width = is->out_video_filter->inputs[0]->w; - vp->height = is->out_video_filter->inputs[0]->h; - vp->pix_fmt = is->out_video_filter->inputs[0]->format; -#else - vp->width = is->video_st->codec->width; - vp->height = is->video_st->codec->height; - vp->pix_fmt = is->video_st->codec->pix_fmt; -#endif - - vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height, - SDL_YV12_OVERLAY, - screen); - - 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, int64_t pos) -{ - VideoPicture *vp; - int dst_pix_fmt; -#if CONFIG_AVFILTER - AVPicture pict_src; -#endif - /* wait until we have space to put a new picture */ - SDL_LockMutex(is->pictq_mutex); - - if(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE && !is->refresh) - is->skip_frames= FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0-FRAME_SKIP_FACTOR)); - - 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 || -#if CONFIG_AVFILTER - vp->width != is->out_video_filter->inputs[0]->w || - vp->height != is->out_video_filter->inputs[0]->h) { -#else - vp->width != is->video_st->codec->width || - vp->height != is->video_st->codec->height) { -#endif - 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) { - AVPicture pict; -#if CONFIG_AVFILTER - if(vp->picref) - avfilter_unref_pic(vp->picref); - vp->picref = src_frame->opaque; -#endif - - /* get a pointer on the bitmap */ - SDL_LockYUVOverlay (vp->bmp); - - dst_pix_fmt = PIX_FMT_YUV420P; - memset(&pict,0,sizeof(AVPicture)); - 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]; - -#if CONFIG_AVFILTER - pict_src.data[0] = src_frame->data[0]; - pict_src.data[1] = src_frame->data[1]; - pict_src.data[2] = src_frame->data[2]; - - pict_src.linesize[0] = src_frame->linesize[0]; - pict_src.linesize[1] = src_frame->linesize[1]; - pict_src.linesize[2] = src_frame->linesize[2]; - - //FIXME use direct rendering - av_picture_copy(&pict, &pict_src, - vp->pix_fmt, vp->width, vp->height); -#else - sws_flags = av_get_int(sws_opts, "sws_flags", NULL); - is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx, - vp->width, vp->height, vp->pix_fmt, vp->width, vp->height, - dst_pix_fmt, sws_flags, NULL, NULL, NULL); - if (is->img_convert_ctx == NULL) { - fprintf(stderr, "Cannot initialize the conversion context\n"); - exit(1); - } - sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize, - 0, vp->height, pict.data, pict.linesize); -#endif - /* update the bitmap content */ - SDL_UnlockYUVOverlay(vp->bmp); - - vp->pts = pts; - vp->pos = pos; - - /* now we can update the picture count */ - if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) - is->pictq_windex = 0; - SDL_LockMutex(is->pictq_mutex); - vp->target_clock= compute_target_time(vp->pts, is); - - 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, int64_t pos) -{ - 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 - printf("frame_type=%c clock=%0.3f pts=%0.3f\n", - av_get_pict_type_char(src_frame->pict_type), pts, pts1); -#endif - return queue_picture(is, src_frame, pts, pos); -} - -static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt) -{ - int len1, got_picture, i; - - if (packet_queue_get(&is->videoq, pkt, 1) < 0) - return -1; - - if(pkt->data == flush_pkt.data){ - avcodec_flush_buffers(is->video_st->codec); - - SDL_LockMutex(is->pictq_mutex); - //Make sure there are no long delay timers (ideally we should just flush the que but thats harder) - for(i=0; ipictq[i].target_clock= 0; - } - while (is->pictq_size && !is->videoq.abort_request) { - SDL_CondWait(is->pictq_cond, is->pictq_mutex); - } - is->video_current_pos= -1; - SDL_UnlockMutex(is->pictq_mutex); - - is->last_dts_for_fault_detection= - is->last_pts_for_fault_detection= INT64_MIN; - is->frame_last_pts= AV_NOPTS_VALUE; - is->frame_last_delay = 0; - is->frame_timer = (double)av_gettime() / 1000000.0; - is->skip_frames= 1; - is->skip_frames_index= 0; - return 0; - } - - /* NOTE: ipts is the PTS of the _first_ picture beginning in - this packet, if any */ - is->video_st->codec->reordered_opaque= pkt->pts; - len1 = avcodec_decode_video2(is->video_st->codec, - frame, &got_picture, - pkt); - - if (got_picture) { - if(pkt->dts != AV_NOPTS_VALUE){ - is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection; - is->last_dts_for_fault_detection= pkt->dts; - } - if(frame->reordered_opaque != AV_NOPTS_VALUE){ - is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection; - is->last_pts_for_fault_detection= frame->reordered_opaque; - } - } - - if( ( decoder_reorder_pts==1 - || (decoder_reorder_pts && is->faulty_ptsfaulty_dts) - || pkt->dts == AV_NOPTS_VALUE) - && frame->reordered_opaque != AV_NOPTS_VALUE) - *pts= frame->reordered_opaque; - else if(pkt->dts != AV_NOPTS_VALUE) - *pts= pkt->dts; - else - *pts= 0; - -// if (len1 < 0) -// break; - if (got_picture){ - is->skip_frames_index += 1; - if(is->skip_frames_index >= is->skip_frames){ - is->skip_frames_index -= FFMAX(is->skip_frames, 1.0); - return 1; - } - - } - return 0; -} - -#if CONFIG_AVFILTER -typedef struct { - VideoState *is; - AVFrame *frame; - int use_dr1; -} FilterPriv; - -static int input_get_buffer(AVCodecContext *codec, AVFrame *pic) -{ - AVFilterContext *ctx = codec->opaque; - AVFilterPicRef *ref; - int perms = AV_PERM_WRITE; - int w, h, stride[4]; - unsigned edge; - - if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) { - if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ; - if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE; - if(pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2; - } - if(pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE; - - w = codec->width; - h = codec->height; - avcodec_align_dimensions2(codec, &w, &h, stride); - edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width(); - w += edge << 1; - h += edge << 1; - - if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h))) - return -1; - - ref->w = codec->width; - ref->h = codec->height; - for(int i = 0; i < 3; i ++) { - unsigned hshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_w; - unsigned vshift = i == 0 ? 0 : av_pix_fmt_descriptors[ref->pic->format].log2_chroma_h; - - if (ref->data[i]) { - ref->data[i] += (edge >> hshift) + ((edge * ref->linesize[i]) >> vshift); - } - pic->data[i] = ref->data[i]; - pic->linesize[i] = ref->linesize[i]; - } - pic->opaque = ref; - pic->age = INT_MAX; - pic->type = FF_BUFFER_TYPE_USER; - return 0; -} - -static void input_release_buffer(AVCodecContext *codec, AVFrame *pic) -{ - memset(pic->data, 0, sizeof(pic->data)); - avfilter_unref_pic(pic->opaque); -} - -static int input_init(AVFilterContext *ctx, const char *args, void *opaque) -{ - FilterPriv *priv = ctx->priv; - AVCodecContext *codec; - if(!opaque) return -1; - - priv->is = opaque; - codec = priv->is->video_st->codec; - codec->opaque = ctx; - if(codec->codec->capabilities & CODEC_CAP_DR1) { - priv->use_dr1 = 1; - codec->get_buffer = input_get_buffer; - codec->release_buffer = input_release_buffer; - } - - priv->frame = avcodec_alloc_frame(); - - return 0; -} - -static void input_uninit(AVFilterContext *ctx) -{ - FilterPriv *priv = ctx->priv; - av_free(priv->frame); -} - -static int input_request_frame(AVFilterLink *link) -{ - FilterPriv *priv = link->src->priv; - AVFilterPicRef *picref; - int64_t pts = 0; - AVPacket pkt; - int ret; - - while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt))) - av_free_packet(&pkt); - if (ret < 0) - return -1; - - if(priv->use_dr1) { - picref = avfilter_ref_pic(priv->frame->opaque, ~0); - } else { - picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h); - av_picture_copy((AVPicture *)&picref->data, (AVPicture *)priv->frame, - picref->pic->format, link->w, link->h); - } - av_free_packet(&pkt); - - picref->pts = pts; - picref->pos = pkt.pos; - picref->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio; - avfilter_start_frame(link, picref); - avfilter_draw_slice(link, 0, link->h, 1); - avfilter_end_frame(link); - - return 0; -} - -static int input_query_formats(AVFilterContext *ctx) -{ - FilterPriv *priv = ctx->priv; - enum PixelFormat pix_fmts[] = { - priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE - }; - - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); - return 0; -} - -static int input_config_props(AVFilterLink *link) -{ - FilterPriv *priv = link->src->priv; - AVCodecContext *c = priv->is->video_st->codec; - - link->w = c->width; - link->h = c->height; - - return 0; -} - -static AVFilter input_filter = -{ - .name = "ffplay_input", - - .priv_size = sizeof(FilterPriv), - - .init = input_init, - .uninit = input_uninit, - - .query_formats = input_query_formats, - - .inputs = (AVFilterPad[]) {{ .name = NULL }}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = input_request_frame, - .config_props = input_config_props, }, - { .name = NULL }}, -}; - -static void output_end_frame(AVFilterLink *link) -{ -} - -static int output_query_formats(AVFilterContext *ctx) -{ - enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE }; - - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); - return 0; -} - -static int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame, - int64_t *pts, int64_t *pos) -{ - AVFilterPicRef *pic; - - if(avfilter_request_frame(ctx->inputs[0])) - return -1; - if(!(pic = ctx->inputs[0]->cur_pic)) - return -1; - ctx->inputs[0]->cur_pic = NULL; - - frame->opaque = pic; - *pts = pic->pts; - *pos = pic->pos; - - memcpy(frame->data, pic->data, sizeof(frame->data)); - memcpy(frame->linesize, pic->linesize, sizeof(frame->linesize)); - - return 1; -} - -static AVFilter output_filter = -{ - .name = "ffplay_output", - - .query_formats = output_query_formats, - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .end_frame = output_end_frame, - .min_perms = AV_PERM_READ, }, - { .name = NULL }}, - .outputs = (AVFilterPad[]) {{ .name = NULL }}, -}; -#endif /* CONFIG_AVFILTER */ - -static int video_thread(void *arg) -{ - VideoState *is = arg; - AVFrame *frame= avcodec_alloc_frame(); - int64_t pts_int; - double pts; - int ret; - -#if CONFIG_AVFILTER - int64_t pos; - AVFilterContext *filt_src = NULL, *filt_out = NULL; - AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph)); - graph->scale_sws_opts = av_strdup("sws_flags=bilinear"); - - if(!(filt_src = avfilter_open(&input_filter, "src"))) goto the_end; - if(!(filt_out = avfilter_open(&output_filter, "out"))) goto the_end; - - if(avfilter_init_filter(filt_src, NULL, is)) goto the_end; - if(avfilter_init_filter(filt_out, NULL, frame)) goto the_end; - - - if(vfilters) { - AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut)); - AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut)); - - outputs->name = av_strdup("in"); - outputs->filter = filt_src; - outputs->pad_idx = 0; - outputs->next = NULL; - - inputs->name = av_strdup("out"); - inputs->filter = filt_out; - inputs->pad_idx = 0; - inputs->next = NULL; - - if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0) - goto the_end; - av_freep(&vfilters); - } else { - if(avfilter_link(filt_src, 0, filt_out, 0) < 0) goto the_end; - } - avfilter_graph_add_filter(graph, filt_src); - avfilter_graph_add_filter(graph, filt_out); - - if(avfilter_graph_check_validity(graph, NULL)) goto the_end; - if(avfilter_graph_config_formats(graph, NULL)) goto the_end; - if(avfilter_graph_config_links(graph, NULL)) goto the_end; - - is->out_video_filter = filt_out; -#endif - - for(;;) { -#if !CONFIG_AVFILTER - AVPacket pkt; -#endif - while (is->paused && !is->videoq.abort_request) - SDL_Delay(10); -#if CONFIG_AVFILTER - ret = get_filtered_video_frame(filt_out, frame, &pts_int, &pos); -#else - ret = get_video_frame(is, frame, &pts_int, &pkt); -#endif - - if (ret < 0) goto the_end; - - if (!ret) - continue; - - pts = pts_int*av_q2d(is->video_st->time_base); - -#if CONFIG_AVFILTER - ret = output_picture2(is, frame, pts, pos); -#else - ret = output_picture2(is, frame, pts, pkt.pos); - av_free_packet(&pkt); -#endif - if (ret < 0) - goto the_end; - - if (step) - if (cur_stream) - stream_pause(cur_stream); - } - the_end: -#if CONFIG_AVFILTER - avfilter_graph_destroy(graph); - av_freep(&graph); -#endif - 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; - - if(pkt->data == flush_pkt.data){ - avcodec_flush_buffers(is->subtitle_st->codec); - continue; - } - 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; - - len1 = avcodec_decode_subtitle2(is->subtitle_st->codec, - &sp->sub, &got_subtitle, - pkt); -// 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, (uint32_t*)sp->sub.rects[i]->pict.data[1] + 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((uint32_t*)sp->sub.rects[i]->pict.data[1] + 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, double *pts_ptr) -{ - AVPacket *pkt_temp = &is->audio_pkt_temp; - AVPacket *pkt = &is->audio_pkt; - AVCodecContext *dec= is->audio_st->codec; - int n, len1, data_size; - double pts; - - for(;;) { - /* NOTE: the audio packet can contain several frames */ - while (pkt_temp->size > 0) { - data_size = sizeof(is->audio_buf1); - len1 = avcodec_decode_audio3(dec, - (int16_t *)is->audio_buf1, &data_size, - pkt_temp); - if (len1 < 0) { - /* if error, we skip the frame */ - pkt_temp->size = 0; - break; - } - - pkt_temp->data += len1; - pkt_temp->size -= len1; - if (data_size <= 0) - continue; - - if (dec->sample_fmt != is->audio_src_fmt) { - if (is->reformat_ctx) - av_audio_convert_free(is->reformat_ctx); - is->reformat_ctx= av_audio_convert_alloc(SAMPLE_FMT_S16, 1, - dec->sample_fmt, 1, NULL, 0); - if (!is->reformat_ctx) { - fprintf(stderr, "Cannot convert %s sample format to %s sample format\n", - avcodec_get_sample_fmt_name(dec->sample_fmt), - avcodec_get_sample_fmt_name(SAMPLE_FMT_S16)); - break; - } - is->audio_src_fmt= dec->sample_fmt; - } - - if (is->reformat_ctx) { - const void *ibuf[6]= {is->audio_buf1}; - void *obuf[6]= {is->audio_buf2}; - int istride[6]= {av_get_bits_per_sample_format(dec->sample_fmt)/8}; - int ostride[6]= {2}; - int len= data_size/istride[0]; - if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) { - printf("av_audio_convert() failed\n"); - break; - } - is->audio_buf= is->audio_buf2; - /* FIXME: existing code assume that data_size equals framesize*channels*2 - remove this legacy cruft */ - data_size= len*2; - }else{ - is->audio_buf= is->audio_buf1; - } - - /* if no pts, then compute it */ - pts = is->audio_clock; - *pts_ptr = pts; - n = 2 * dec->channels; - is->audio_clock += (double)data_size / - (double)(n * dec->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; - if(pkt->data == flush_pkt.data){ - avcodec_flush_buffers(dec); - continue; - } - - pkt_temp->data = pkt->data; - pkt_temp->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_buf_size - is->audio_buf_index; -} - - -/* prepare a new audio buffer */ -static 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, &pts); - if (audio_size < 0) { - /* if error, just output silence */ - is->audio_buf = is->audio_buf1; - 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 *avctx; - AVCodec *codec; - SDL_AudioSpec wanted_spec, spec; - - if (stream_index < 0 || stream_index >= ic->nb_streams) - return -1; - avctx = ic->streams[stream_index]->codec; - - /* prepare audio output */ - if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - if (avctx->channels > 0) { - avctx->request_channels = FFMIN(2, avctx->channels); - } else { - avctx->request_channels = 2; - } - } - - codec = avcodec_find_decoder(avctx->codec_id); - avctx->debug_mv = debug_mv; - avctx->debug = debug; - avctx->workaround_bugs = workaround_bugs; - avctx->lowres = lowres; - if(lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE; - avctx->idct_algo= idct; - if(fast) avctx->flags2 |= CODEC_FLAG2_FAST; - avctx->skip_frame= skip_frame; - avctx->skip_idct= skip_idct; - avctx->skip_loop_filter= skip_loop_filter; - avctx->error_recognition= error_recognition; - avctx->error_concealment= error_concealment; - avcodec_thread_init(avctx, thread_count); - - set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0); - - if (!codec || - avcodec_open(avctx, codec) < 0) - return -1; - - /* prepare audio output */ - if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - wanted_spec.freq = avctx->sample_rate; - wanted_spec.format = AUDIO_S16SYS; - wanted_spec.channels = avctx->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; - is->audio_src_fmt= SAMPLE_FMT_S16; - } - - ic->streams[stream_index]->discard = AVDISCARD_DEFAULT; - switch(avctx->codec_type) { - case AVMEDIA_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 / avctx->sample_rate; - - memset(&is->audio_pkt, 0, sizeof(is->audio_pkt)); - packet_queue_init(&is->audioq); - SDL_PauseAudio(0); - break; - case AVMEDIA_TYPE_VIDEO: - is->video_stream = stream_index; - is->video_st = ic->streams[stream_index]; - -// is->video_current_pts_time = av_gettime(); - - packet_queue_init(&is->videoq); - is->video_tid = SDL_CreateThread(video_thread, is); - break; - case AVMEDIA_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 *avctx; - - if (stream_index < 0 || stream_index >= ic->nb_streams) - return; - avctx = ic->streams[stream_index]->codec; - - switch(avctx->codec_type) { - case AVMEDIA_TYPE_AUDIO: - packet_queue_abort(&is->audioq); - - SDL_CloseAudio(); - - packet_queue_end(&is->audioq); - if (is->reformat_ctx) - av_audio_convert_free(is->reformat_ctx); - is->reformat_ctx = NULL; - break; - case AVMEDIA_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 AVMEDIA_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; - } - - ic->streams[stream_index]->discard = AVDISCARD_ALL; - avcodec_close(avctx); - switch(avctx->codec_type) { - case AVMEDIA_TYPE_AUDIO: - is->audio_st = NULL; - is->audio_stream = -1; - break; - case AVMEDIA_TYPE_VIDEO: - is->video_st = NULL; - is->video_stream = -1; - break; - case AVMEDIA_TYPE_SUBTITLE: - is->subtitle_st = NULL; - is->subtitle_stream = -1; - break; - default: - break; - } -} - -/* 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; - int st_index[AVMEDIA_TYPE_NB]; - int st_count[AVMEDIA_TYPE_NB]={0}; - int st_best_packet_count[AVMEDIA_TYPE_NB]; - AVPacket pkt1, *pkt = &pkt1; - AVFormatParameters params, *ap = ¶ms; - int eof=0; - int pkt_in_play_range = 0; - - ic = avformat_alloc_context(); - - memset(st_index, -1, sizeof(st_index)); - memset(st_best_packet_count, -1, sizeof(st_best_packet_count)); - 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->prealloced_context = 1; - ap->width = frame_width; - ap->height= frame_height; - ap->time_base= (AVRational){1, 25}; - ap->pix_fmt = frame_pix_fmt; - - set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM); - - 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; - - if(genpts) - ic->flags |= AVFMT_FLAG_GENPTS; - - err = av_find_stream_info(ic); - if (err < 0) { - fprintf(stderr, "%s: could not find codec parameters\n", is->filename); - ret = -1; - goto fail; - } - if(ic->pb) - ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end - - if(seek_by_bytes<0) - seek_by_bytes= !!(ic->iformat->flags & AVFMT_TS_DISCONT); - - /* 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 = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0); - if (ret < 0) { - fprintf(stderr, "%s: could not seek to position %0.3f\n", - is->filename, (double)timestamp / AV_TIME_BASE); - } - } - - for(i = 0; i < ic->nb_streams; i++) { - AVStream *st= ic->streams[i]; - AVCodecContext *avctx = st->codec; - ic->streams[i]->discard = AVDISCARD_ALL; - if(avctx->codec_type >= (unsigned)AVMEDIA_TYPE_NB) - continue; - if(st_count[avctx->codec_type]++ != wanted_stream[avctx->codec_type] && wanted_stream[avctx->codec_type] >= 0) - continue; - - if(st_best_packet_count[avctx->codec_type] >= st->codec_info_nb_frames) - continue; - st_best_packet_count[avctx->codec_type]= st->codec_info_nb_frames; - - switch(avctx->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if (!audio_disable) - st_index[AVMEDIA_TYPE_AUDIO] = i; - break; - case AVMEDIA_TYPE_VIDEO: - case AVMEDIA_TYPE_SUBTITLE: - if (!video_disable) - st_index[avctx->codec_type] = i; - break; - default: - break; - } - } - if (show_status) { - dump_format(ic, 0, is->filename, 0); - } - - /* open the streams */ - if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) { - stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]); - } - - ret=-1; - if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) { - ret= stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]); - } - is->refresh_tid = SDL_CreateThread(refresh_thread, is); - if(ret<0) { - if (!display_disable) - is->show_audio = 2; - } - - if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) { - stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]); - } - - 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; - if (is->paused != is->last_paused) { - is->last_paused = is->paused; - if (is->paused) - is->read_pause_return= av_read_pause(ic); - else - av_read_play(ic); - } -#if CONFIG_RTSP_DEMUXER - if (is->paused && !strcmp(ic->iformat->name, "rtsp")) { - /* wait 10 ms to avoid trying to get another packet */ - /* XXX: horrible */ - SDL_Delay(10); - continue; - } -#endif - if (is->seek_req) { - int64_t seek_target= is->seek_pos; - int64_t seek_min= is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN; - int64_t seek_max= is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX; -//FIXME the +-2 is due to rounding being not done in the correct direction in generation -// of the seek_pos/seek_rel variables - - ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, 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); - packet_queue_put(&is->audioq, &flush_pkt); - } - if (is->subtitle_stream >= 0) { - packet_queue_flush(&is->subtitleq); - packet_queue_put(&is->subtitleq, &flush_pkt); - } - if (is->video_stream >= 0) { - packet_queue_flush(&is->videoq); - packet_queue_put(&is->videoq, &flush_pkt); - } - } - is->seek_req = 0; - eof= 0; - } - - /* if the queue are full, no need to read more */ - if ( is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE - || ( (is->audioq .size > MIN_AUDIOQ_SIZE || is->audio_stream<0) - && (is->videoq .nb_packets > MIN_FRAMES || is->video_stream<0) - && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream<0))) { - /* wait 10 ms */ - SDL_Delay(10); - continue; - } - if(url_feof(ic->pb) || eof) { - if(is->video_stream >= 0){ - av_init_packet(pkt); - pkt->data=NULL; - pkt->size=0; - pkt->stream_index= is->video_stream; - packet_queue_put(&is->videoq, pkt); - } - SDL_Delay(10); - if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){ - if(loop!=1 && (!loop || --loop)){ - stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0); - }else if(autoexit){ - ret=AVERROR_EOF; - goto fail; - } - } - continue; - } - ret = av_read_frame(ic, pkt); - if (ret < 0) { - if (ret == AVERROR_EOF) - eof=1; - if (url_ferror(ic->pb)) - break; - SDL_Delay(100); /* wait for user event */ - continue; - } - /* check if packet is in play range specified by user, then queue, otherwise discard */ - pkt_in_play_range = duration == AV_NOPTS_VALUE || - (pkt->pts - ic->streams[pkt->stream_index]->start_time) * - av_q2d(ic->streams[pkt->stream_index]->time_base) - - (double)(start_time != AV_NOPTS_VALUE ? start_time : 0)/1000000 - <= ((double)duration/1000000); - if (pkt->stream_index == is->audio_stream && pkt_in_play_range) { - packet_queue_put(&is->audioq, pkt); - } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) { - packet_queue_put(&is->videoq, pkt); - } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) { - 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; - av_strlcpy(is->filename, filename, sizeof(is->filename)); - is->iformat = iformat; - 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->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); - SDL_WaitThread(is->refresh_tid, NULL); - - /* free all pictures */ - for(i=0;ipictq[i]; -#if CONFIG_AVFILTER - if (vp->picref) { - avfilter_unref_pic(vp->picref); - vp->picref = NULL; - } -#endif - 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); -#if !CONFIG_AVFILTER - if (is->img_convert_ctx) - sws_freeContext(is->img_convert_ctx); -#endif - av_free(is); -} - -static void stream_cycle_channel(VideoState *is, int codec_type) -{ - AVFormatContext *ic = is->ic; - int start_index, stream_index; - AVStream *st; - - if (codec_type == AVMEDIA_TYPE_VIDEO) - start_index = is->video_stream; - else if (codec_type == AVMEDIA_TYPE_AUDIO) - start_index = is->audio_stream; - else - start_index = is->subtitle_stream; - if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0)) - return; - stream_index = start_index; - for(;;) { - if (++stream_index >= is->ic->nb_streams) - { - if (codec_type == AVMEDIA_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 AVMEDIA_TYPE_AUDIO: - if (st->codec->sample_rate != 0 && - st->codec->channels != 0) - goto the_end; - break; - case AVMEDIA_TYPE_VIDEO: - case AVMEDIA_TYPE_SUBTITLE: - goto the_end; - default: - break; - } - } - } - the_end: - stream_component_close(is, start_index); - stream_component_open(is, stream_index); -} - - -static void toggle_full_screen(void) -{ - is_full_screen = !is_full_screen; - if (!fs_screen_width) { - /* use default SDL method */ -// SDL_WM_ToggleFullScreen(screen); - } - video_open(cur_stream); -} - -static void toggle_pause(void) -{ - if (cur_stream) - stream_pause(cur_stream); - step = 0; -} - -static void step_to_next_frame(void) -{ - if (cur_stream) { - /* if the stream is paused unpause it, then step */ - if (cur_stream->paused) - stream_pause(cur_stream); - } - step = 1; -} - -static void do_exit(void) -{ - int i; - if (cur_stream) { - stream_close(cur_stream); - cur_stream = NULL; - } - for (i = 0; i < AVMEDIA_TYPE_NB; i++) - av_free(avcodec_opts[i]); - av_free(avformat_opts); - av_free(sws_opts); -#if CONFIG_AVFILTER - avfilter_uninit(); -#endif - if (show_status) - printf("\n"); - SDL_Quit(); - exit(0); -} - -static void toggle_audio_display(void) -{ - if (cur_stream) { - int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); - cur_stream->show_audio = (cur_stream->show_audio + 1) % 3; - fill_rectangle(screen, - cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height, - bgcolor); - SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height); - } -} - -/* handle an event sent by the GUI */ -static void event_loop(void) -{ - SDL_Event event; - double incr, pos, frac; - - for(;;) { - double x; - 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, AVMEDIA_TYPE_AUDIO); - break; - case SDLK_v: - if (cur_stream) - stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO); - break; - case SDLK_t: - if (cur_stream) - stream_cycle_channel(cur_stream, AVMEDIA_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) { - if (seek_by_bytes) { - if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos>=0){ - pos= cur_stream->video_current_pos; - }else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){ - pos= cur_stream->audio_pkt.pos; - }else - pos = url_ftell(cur_stream->ic->pb); - if (cur_stream->ic->bit_rate) - incr *= cur_stream->ic->bit_rate / 8.0; - else - incr *= 180000.0; - pos += incr; - stream_seek(cur_stream, pos, incr, 1); - } else { - pos = get_master_clock(cur_stream); - pos += incr; - stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0); - } - } - break; - default: - break; - } - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEMOTION: - if(event.type ==SDL_MOUSEBUTTONDOWN){ - x= event.button.x; - }else{ - if(event.motion.state != SDL_PRESSED) - break; - x= event.motion.x; - } - if (cur_stream) { - if(seek_by_bytes || cur_stream->ic->duration<=0){ - uint64_t size= url_fsize(cur_stream->ic->pb); - stream_seek(cur_stream, size*x/cur_stream->width, 0, 1); - }else{ - int64_t ts; - 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 = x/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); - ts = frac*cur_stream->ic->duration; - if (cur_stream->ic->start_time != AV_NOPTS_VALUE) - ts += cur_stream->ic->start_time; - stream_seek(cur_stream, ts, 0, 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); - screen_width = cur_stream->width = event.resize.w; - screen_height= cur_stream->height= event.resize.h; - } - break; - case SDL_QUIT: - case FF_QUIT_EVENT: - do_exit(); - break; - case FF_ALLOC_EVENT: - video_open(event.user.data1); - alloc_picture(event.user.data1); - break; - case FF_REFRESH_EVENT: - video_refresh_timer(event.user.data1); - cur_stream->refresh=0; - break; - default: - break; - } - } -} - -static void opt_frame_size(const char *arg) -{ - if (av_parse_video_frame_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); - } -} - -static int opt_width(const char *opt, const char *arg) -{ - screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX); - return 0; -} - -static int opt_height(const char *opt, const char *arg) -{ - screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX); - return 0; -} - -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_frame_pix_fmt(const char *arg) -{ - frame_pix_fmt = av_get_pix_fmt(arg); -} - -static int opt_sync(const char *opt, 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 { - fprintf(stderr, "Unknown value for %s: %s\n", opt, arg); - exit(1); - } - return 0; -} - -static int opt_seek(const char *opt, const char *arg) -{ - start_time = parse_time_or_die(opt, arg, 1); - return 0; -} - -static int opt_duration(const char *opt, const char *arg) -{ - duration = parse_time_or_die(opt, arg, 1); - return 0; -} - -static int opt_debug(const char *opt, const char *arg) -{ - av_log_set_level(99); - debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); - return 0; -} - -static int opt_vismv(const char *opt, const char *arg) -{ - debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX); - return 0; -} - -static int opt_thread_count(const char *opt, const char *arg) -{ - thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); -#if !HAVE_THREADS - fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n"); -#endif - return 0; -} - -static const OptionDef options[] = { -#include "cmdutils_common_opts.h" - { "x", HAS_ARG | OPT_FUNC2, {(void*)opt_width}, "force displayed width", "width" }, - { "y", HAS_ARG | OPT_FUNC2, {(void*)opt_height}, "force displayed height", "height" }, - { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" }, - { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" }, - { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" }, - { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" }, - { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_AUDIO]}, "select desired audio stream", "stream_number" }, - { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_VIDEO]}, "select desired video stream", "stream_number" }, - { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&wanted_stream[AVMEDIA_TYPE_SUBTITLE]}, "select desired subtitle stream", "stream_number" }, - { "ss", HAS_ARG | OPT_FUNC2, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" }, - { "t", HAS_ARG | OPT_FUNC2, {(void*)&opt_duration}, "play \"duration\" seconds of audio/video", "duration" }, - { "bytes", OPT_INT | HAS_ARG, {(void*)&seek_by_bytes}, "seek by bytes 0=off 1=on -1=auto", "val" }, - { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" }, - { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, - { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" }, - { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" }, - { "debug", HAS_ARG | OPT_FUNC2 | 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_FUNC2 | 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", "" }, - { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts 0=off 1=on -1=auto", ""}, - { "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_recognition}, "set error detection threshold (0-4)", "threshold" }, - { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" }, - { "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" }, - { "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" }, - { "autoexit", OPT_BOOL | OPT_EXPERT, {(void*)&autoexit}, "exit at the end", "" }, - { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&loop}, "set number of times the playback shall be looped", "loop count" }, - { "framedrop", OPT_BOOL | OPT_EXPERT, {(void*)&framedrop}, "drop frames when cpu is too slow", "" }, - { "window_title", OPT_STRING | HAS_ARG, {(void*)&window_title}, "set window title", "window title" }, -#if CONFIG_AVFILTER - { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" }, -#endif - { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, {(void*)&rdftspeed}, "rdft speed", "msecs" }, - { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" }, - { NULL, }, -}; - -static void show_usage(void) -{ - printf("Simple media player\n"); - printf("usage: ffplay [options] input_file\n"); - printf("\n"); -} - -static void show_help(void) -{ - show_usage(); - 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" - "s activate frame-step mode\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" - ); -} - -static void opt_input_file(const char *filename) -{ - if (input_filename) { - fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", - filename, input_filename); - exit(1); - } - if (!strcmp(filename, "-")) - filename = "pipe:"; - input_filename = filename; -} - -/* Called from the main */ -int main(int argc, char **argv) -{ - int flags, i; - - /* register all codecs, demux and protocols */ - avcodec_register_all(); -#if CONFIG_AVDEVICE - avdevice_register_all(); -#endif -#if CONFIG_AVFILTER - avfilter_register_all(); -#endif - av_register_all(); - - for(i=0; icurrent_w; - fs_screen_height = vi->current_h; -#endif - } - - SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); - SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); - SDL_EventState(SDL_USEREVENT, SDL_IGNORE); - - av_init_packet(&flush_pkt); - flush_pkt.data= "FLUSH"; - - cur_stream = stream_open(input_filename, file_iformat); - - event_loop(); - - /* never returns */ - - return 0; -} diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-baseline.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-baseline.ffpreset deleted file mode 100644 index ee7654b..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-baseline.ffpreset +++ /dev/null @@ -1,4 +0,0 @@ -coder=0 -bf=0 -flags2=-wpred-dct8x8 -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-default.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-default.ffpreset deleted file mode 100644 index 75191e2..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-default.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=hex -subq=7 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=3 -directpred=1 -trellis=1 -flags2=+mixed_refs+wpred+dct8x8+fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-fast.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-fast.ffpreset deleted file mode 100644 index cac6534..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-fast.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=hex -subq=6 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=2 -directpred=1 -trellis=1 -flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip -wpredp=2 -rc_lookahead=30 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-fast_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-fast_firstpass.ffpreset deleted file mode 100644 index 65ec011..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-fast_firstpass.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=1 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip -wpredp=2 -rc_lookahead=30 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-faster.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-faster.ffpreset deleted file mode 100644 index a32eed3..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-faster.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=hex -subq=4 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=2 -directpred=1 -trellis=1 -flags2=+bpyramid-mixed_refs+wpred+dct8x8+fastpskip -wpredp=1 -rc_lookahead=20 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-faster_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-faster_firstpass.ffpreset deleted file mode 100644 index c777eb4..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-faster_firstpass.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=1 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip -wpredp=1 -rc_lookahead=20 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-fastfirstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-fastfirstpass.ffpreset deleted file mode 100644 index 7278f77..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-fastfirstpass.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partp4x4-partb8x8 -me_method=dia -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=3 -trellis=0 -flags2=-bpyramid-wpred-mixed_refs-dct8x8+fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-hq.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-hq.ffpreset deleted file mode 100644 index 9c14d8f..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-hq.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=umh -subq=8 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=4 -directpred=3 -trellis=1 -flags2=+wpred+mixed_refs+dct8x8+fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-ipod320.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-ipod320.ffpreset deleted file mode 100644 index 943b521..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-ipod320.ffpreset +++ /dev/null @@ -1,7 +0,0 @@ -coder=0 -bf=0 -flags2=-wpred-dct8x8 -level=13 -maxrate=768000 -bufsize=3000000 -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-ipod640.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-ipod640.ffpreset deleted file mode 100644 index 1ed3d9f..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-ipod640.ffpreset +++ /dev/null @@ -1,8 +0,0 @@ -coder=0 -bf=0 -refs=1 -flags2=-wpred-dct8x8 -level=30 -maxrate=10000000 -bufsize=10000000 -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_fast.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_fast.ffpreset deleted file mode 100644 index ea08d3c..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_fast.ffpreset +++ /dev/null @@ -1,20 +0,0 @@ -coder=0 -flags=+loop -cmp=+chroma -partitions=-parti8x8+parti4x4+partp8x8-partp4x4-partb8x8 -me_method=hex -subq=3 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -directpred=1 -flags2=+fastpskip -cqp=0 -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_max.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_max.ffpreset deleted file mode 100644 index 8c049c9..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_max.ffpreset +++ /dev/null @@ -1,21 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4-partb8x8 -me_method=esa -subq=8 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -refs=16 -directpred=1 -flags2=+mixed_refs+dct8x8+fastpskip -cqp=0 -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_medium.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_medium.ffpreset deleted file mode 100644 index 558be6c..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_medium.ffpreset +++ /dev/null @@ -1,20 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8+parti4x4+partp8x8+partp4x4-partb8x8 -me_method=hex -subq=5 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -directpred=1 -flags2=+fastpskip -cqp=0 -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slow.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slow.ffpreset deleted file mode 100644 index ff641cf..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slow.ffpreset +++ /dev/null @@ -1,21 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4-partb8x8 -me_method=umh -subq=6 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -refs=2 -directpred=1 -flags2=+dct8x8+fastpskip -cqp=0 -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slower.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slower.ffpreset deleted file mode 100644 index 854f74b..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_slower.ffpreset +++ /dev/null @@ -1,21 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4-partb8x8 -me_method=umh -subq=8 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -refs=4 -directpred=1 -flags2=+mixed_refs+dct8x8+fastpskip -cqp=0 -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_ultrafast.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_ultrafast.ffpreset deleted file mode 100644 index 1c429f2..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-lossless_ultrafast.ffpreset +++ /dev/null @@ -1,19 +0,0 @@ -coder=0 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partp4x4-partb8x8 -me_method=dia -subq=0 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -directpred=1 -flags2=+fastpskip -cqp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-main.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-main.ffpreset deleted file mode 100644 index d1dc7dd..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-main.ffpreset +++ /dev/null @@ -1 +0,0 @@ -flags2=-dct8x8 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-max.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-max.ffpreset deleted file mode 100644 index 667ba85..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-max.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 -me_method=tesa -subq=10 -me_range=24 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=16 -directpred=3 -trellis=2 -flags2=+wpred+mixed_refs+dct8x8-fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-medium.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-medium.ffpreset deleted file mode 100644 index 039f1d6..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-medium.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=hex -subq=7 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=3 -directpred=1 -trellis=1 -flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-medium_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-medium_firstpass.ffpreset deleted file mode 100644 index e415989..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-medium_firstpass.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=1 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-normal.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-normal.ffpreset deleted file mode 100644 index ee790b6..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-normal.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=hex -subq=6 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=2 -directpred=3 -trellis=0 -flags2=+wpred+dct8x8+fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-placebo.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-placebo.ffpreset deleted file mode 100644 index fae2222..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-placebo.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 -me_method=tesa -subq=10 -me_range=24 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=16 -refs=16 -directpred=3 -trellis=2 -flags2=+bpyramid+mixed_refs+wpred+dct8x8-fastpskip -wpredp=2 -rc_lookahead=60 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-placebo_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-placebo_firstpass.ffpreset deleted file mode 100644 index fae2222..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-placebo_firstpass.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 -me_method=tesa -subq=10 -me_range=24 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=16 -refs=16 -directpred=3 -trellis=2 -flags2=+bpyramid+mixed_refs+wpred+dct8x8-fastpskip -wpredp=2 -rc_lookahead=60 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-slow.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-slow.ffpreset deleted file mode 100644 index 0f3f4d4..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-slow.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=umh -subq=8 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=5 -directpred=3 -trellis=1 -flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip -wpredp=2 -rc_lookahead=50 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-slow_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-slow_firstpass.ffpreset deleted file mode 100644 index 89e74e4..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-slow_firstpass.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=3 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip -wpredp=2 -rc_lookahead=50 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-slower.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-slower.ffpreset deleted file mode 100644 index f3a412c..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-slower.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 -me_method=umh -subq=9 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=8 -directpred=3 -trellis=2 -flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip -wpredp=2 -rc_lookahead=60 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-slower_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-slower_firstpass.ffpreset deleted file mode 100644 index aa1eb1e..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-slower_firstpass.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=3 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip -wpredp=2 -rc_lookahead=60 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-slowfirstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-slowfirstpass.ffpreset deleted file mode 100644 index fe07331..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-slowfirstpass.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=hex -subq=6 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=3 -trellis=0 -flags2=+wpred+dct8x8+fastpskip -wpredp=2 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-superfast.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-superfast.ffpreset deleted file mode 100644 index e2cb959..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-superfast.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4-partp8x8-partb8x8 -me_method=dia -subq=1 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=1 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred+dct8x8+fastpskip-mbtree -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-superfast_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-superfast_firstpass.ffpreset deleted file mode 100644 index 5f44bea..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-superfast_firstpass.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=1 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=1 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip-mbtree -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast.ffpreset deleted file mode 100644 index 70acb00..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=0 -flags=-loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=0 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=0 -i_qfactor=0.71 -b_strategy=0 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=0 -refs=1 -directpred=1 -trellis=0 -flags2=-bpyramid-mixed_refs-wpred-dct8x8+fastpskip-mbtree -wpredp=0 -aq_mode=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast_firstpass.ffpreset deleted file mode 100644 index 70acb00..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-ultrafast_firstpass.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=0 -flags=-loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=0 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=0 -i_qfactor=0.71 -b_strategy=0 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=0 -refs=1 -directpred=1 -trellis=0 -flags2=-bpyramid-mixed_refs-wpred-dct8x8+fastpskip-mbtree -wpredp=0 -aq_mode=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-veryfast.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-veryfast.ffpreset deleted file mode 100644 index a29b115..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-veryfast.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partb8x8 -me_method=hex -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=1 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred+dct8x8+fastpskip-mbtree -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-veryfast_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-veryfast_firstpass.ffpreset deleted file mode 100644 index bab5d9b..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-veryfast_firstpass.ffpreset +++ /dev/null @@ -1,22 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=2 -me_range=16 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=1 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=3 -refs=1 -directpred=1 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip-mbtree -wpredp=0 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-veryslow.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-veryslow.ffpreset deleted file mode 100644 index a060625..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-veryslow.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=+parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 -me_method=umh -subq=10 -me_range=24 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=8 -refs=16 -directpred=3 -trellis=2 -flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip -wpredp=2 -rc_lookahead=60 diff --git a/tizen/distrib/ffmpeg/ffpresets/libx264-veryslow_firstpass.ffpreset b/tizen/distrib/ffmpeg/ffpresets/libx264-veryslow_firstpass.ffpreset deleted file mode 100644 index 6e7079b..0000000 --- a/tizen/distrib/ffmpeg/ffpresets/libx264-veryslow_firstpass.ffpreset +++ /dev/null @@ -1,23 +0,0 @@ -coder=1 -flags=+loop -cmp=+chroma -partitions=-parti8x8-parti4x4-partp8x8-partb8x8 -me_method=dia -subq=2 -me_range=24 -g=250 -keyint_min=25 -sc_threshold=40 -i_qfactor=0.71 -b_strategy=2 -qcomp=0.6 -qmin=10 -qmax=51 -qdiff=4 -bf=8 -refs=1 -directpred=3 -trellis=0 -flags2=+bpyramid-mixed_refs+wpred-dct8x8+fastpskip -wpredp=2 -rc_lookahead=60 diff --git a/tizen/distrib/ffmpeg/ffprobe.c b/tizen/distrib/ffmpeg/ffprobe.c deleted file mode 100644 index 7cb6167..0000000 --- a/tizen/distrib/ffmpeg/ffprobe.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * FFprobe : Simple Media Prober based on the FFmpeg libraries - * Copyright (c) 2007-2010 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include "libavformat/avformat.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/opt.h" -#include "libavutil/pixdesc.h" -#include "libavdevice/avdevice.h" -#include "cmdutils.h" - -const char program_name[] = "FFprobe"; -const int program_birth_year = 2007; - -static int do_show_format = 0; -static int do_show_streams = 0; - -static int convert_tags = 0; -static int show_value_unit = 0; -static int use_value_prefix = 0; -static int use_byte_value_binary_prefix = 0; -static int use_value_sexagesimal_format = 0; - -/* globals */ -static const OptionDef options[]; - -/* FFprobe context */ -static const char *input_filename; -static AVInputFormat *iformat = NULL; - -static const char *binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" }; -static const char *decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P" }; - -static const char *unit_second_str = "s" ; -static const char *unit_hertz_str = "Hz" ; -static const char *unit_byte_str = "byte" ; -static const char *unit_bit_per_second_str = "bit/s"; - -static char *value_string(char *buf, int buf_size, double val, const char *unit) -{ - if (unit == unit_second_str && use_value_sexagesimal_format) { - double secs; - int hours, mins; - secs = val; - mins = (int)secs / 60; - secs = secs - mins * 60; - hours = mins / 60; - mins %= 60; - snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs); - } else if (use_value_prefix) { - const char *prefix_string; - int index; - - if (unit == unit_byte_str && use_byte_value_binary_prefix) { - index = (int) (log(val)/log(2)) / 10; - index = av_clip(index, 0, FF_ARRAY_ELEMS(binary_unit_prefixes) -1); - val /= pow(2, index*10); - prefix_string = binary_unit_prefixes[index]; - } else { - index = (int) (log10(val)) / 3; - index = av_clip(index, 0, FF_ARRAY_ELEMS(decimal_unit_prefixes) -1); - val /= pow(10, index*3); - prefix_string = decimal_unit_prefixes[index]; - } - - snprintf(buf, buf_size, "%.3f %s%s", val, prefix_string, show_value_unit ? unit : ""); - } else { - snprintf(buf, buf_size, "%f %s", val, show_value_unit ? unit : ""); - } - - return buf; -} - -static char *time_value_string(char *buf, int buf_size, int64_t val, const AVRational *time_base) -{ - if (val == AV_NOPTS_VALUE) { - snprintf(buf, buf_size, "N/A"); - } else { - value_string(buf, buf_size, val * av_q2d(*time_base), unit_second_str); - } - - return buf; -} - -static const char *media_type_string(enum AVMediaType media_type) -{ - switch (media_type) { - case AVMEDIA_TYPE_VIDEO: return "video"; - case AVMEDIA_TYPE_AUDIO: return "audio"; - case AVMEDIA_TYPE_DATA: return "data"; - case AVMEDIA_TYPE_SUBTITLE: return "subtitle"; - case AVMEDIA_TYPE_ATTACHMENT: return "attachment"; - default: return "unknown"; - } -} - -static void show_stream(AVFormatContext *fmt_ctx, int stream_idx) -{ - AVStream *stream = fmt_ctx->streams[stream_idx]; - AVCodecContext *dec_ctx; - AVCodec *dec; - char val_str[128]; - AVMetadataTag *tag = NULL; - char a, b, c, d; - AVRational display_aspect_ratio; - - printf("[STREAM]\n"); - - printf("index=%d\n", stream->index); - - if ((dec_ctx = stream->codec)) { - if ((dec = dec_ctx->codec)) { - printf("codec_name=%s\n", dec->name); - printf("codec_long_name=%s\n", dec->long_name); - } else { - printf("codec_name=unknown\n"); - } - - printf("codec_type=%s\n", media_type_string(dec_ctx->codec_type)); - printf("codec_time_base=%d/%d\n", dec_ctx->time_base.num, dec_ctx->time_base.den); - - /* print AVI/FourCC tag */ - a = dec_ctx->codec_tag & 0xff; - b = dec_ctx->codec_tag>>8 & 0xff; - c = dec_ctx->codec_tag>>16 & 0xff; - d = dec_ctx->codec_tag>>24 & 0xff; - printf("codec_tag_string="); - if (isprint(a)) printf("%c", a); else printf("[%d]", a); - if (isprint(b)) printf("%c", b); else printf("[%d]", b); - if (isprint(c)) printf("%c", c); else printf("[%d]", c); - if (isprint(d)) printf("%c", d); else printf("[%d]", d); - printf("\ncodec_tag=0x%04x\n", dec_ctx->codec_tag); - - switch (dec_ctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - printf("width=%d\n", dec_ctx->width); - printf("height=%d\n", dec_ctx->height); - printf("has_b_frames=%d\n", dec_ctx->has_b_frames); - if (dec_ctx->sample_aspect_ratio.num) { - printf("sample_aspect_ratio=%d:%d\n", dec_ctx->sample_aspect_ratio.num, - dec_ctx->sample_aspect_ratio.den); - av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, - dec_ctx->width * dec_ctx->sample_aspect_ratio.num, - dec_ctx->height * dec_ctx->sample_aspect_ratio.den, - 1024*1024); - printf("display_aspect_ratio=%d:%d\n", display_aspect_ratio.num, - display_aspect_ratio.den); - } - printf("pix_fmt=%s\n", dec_ctx->pix_fmt != PIX_FMT_NONE ? - av_pix_fmt_descriptors[dec_ctx->pix_fmt].name : "unknown"); - break; - - case AVMEDIA_TYPE_AUDIO: - printf("sample_rate=%s\n", value_string(val_str, sizeof(val_str), - dec_ctx->sample_rate, - unit_hertz_str)); - printf("channels=%d\n", dec_ctx->channels); - printf("bits_per_sample=%d\n", av_get_bits_per_sample(dec_ctx->codec_id)); - break; - } - } else { - printf("codec_type=unknown\n"); - } - - if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) - printf("id=0x%x\n", stream->id); - printf("r_frame_rate=%d/%d\n", stream->r_frame_rate.num, stream->r_frame_rate.den); - printf("avg_frame_rate=%d/%d\n", stream->avg_frame_rate.num, stream->avg_frame_rate.den); - printf("time_base=%d/%d\n", stream->time_base.num, stream->time_base.den); - if (stream->language[0]) - printf("language=%s\n", stream->language); - printf("start_time=%s\n", time_value_string(val_str, sizeof(val_str), stream->start_time, - &stream->time_base)); - printf("duration=%s\n", time_value_string(val_str, sizeof(val_str), stream->duration, - &stream->time_base)); - if (stream->nb_frames) - printf("nb_frames=%"PRId64"\n", stream->nb_frames); - - while ((tag = av_metadata_get(stream->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) - printf("TAG:%s=%s\n", tag->key, tag->value); - - printf("[/STREAM]\n"); -} - -static void show_format(AVFormatContext *fmt_ctx) -{ - AVMetadataTag *tag = NULL; - char val_str[128]; - - printf("[FORMAT]\n"); - - printf("filename=%s\n", fmt_ctx->filename); - printf("nb_streams=%d\n", fmt_ctx->nb_streams); - printf("format_name=%s\n", fmt_ctx->iformat->name); - printf("format_long_name=%s\n", fmt_ctx->iformat->long_name); - printf("start_time=%s\n", time_value_string(val_str, sizeof(val_str), fmt_ctx->start_time, - &AV_TIME_BASE_Q)); - printf("duration=%s\n", time_value_string(val_str, sizeof(val_str), fmt_ctx->duration, - &AV_TIME_BASE_Q)); - printf("size=%s\n", value_string(val_str, sizeof(val_str), fmt_ctx->file_size, - unit_byte_str)); - printf("bit_rate=%s\n", value_string(val_str, sizeof(val_str), fmt_ctx->bit_rate, - unit_bit_per_second_str)); - - if (convert_tags) - av_metadata_conv(fmt_ctx, NULL, fmt_ctx->iformat->metadata_conv); - while ((tag = av_metadata_get(fmt_ctx->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) - printf("TAG:%s=%s\n", tag->key, tag->value); - - printf("[/FORMAT]\n"); -} - -static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename) -{ - int err, i; - AVFormatContext *fmt_ctx; - - fmt_ctx = avformat_alloc_context(); - - if ((err = av_open_input_file(&fmt_ctx, filename, iformat, 0, NULL)) < 0) { - print_error(filename, err); - return err; - } - - /* fill the streams in the format context */ - if ((err = av_find_stream_info(fmt_ctx)) < 0) { - print_error(filename, err); - return err; - } - - dump_format(fmt_ctx, 0, filename, 0); - - /* bind a decoder to each input stream */ - for (i = 0; i < fmt_ctx->nb_streams; i++) { - AVStream *stream = fmt_ctx->streams[i]; - AVCodec *codec; - - if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) { - fprintf(stderr, "Unsupported codec (id=%d) for input stream %d\n", - stream->codec->codec_id, stream->index); - } else if (avcodec_open(stream->codec, codec) < 0) { - fprintf(stderr, "Error while opening codec for input stream %d\n", - stream->index); - } - } - - *fmt_ctx_ptr = fmt_ctx; - return 0; -} - -static int probe_file(const char *filename) -{ - AVFormatContext *fmt_ctx; - int ret, i; - - if ((ret = open_input_file(&fmt_ctx, filename))) - return ret; - - if (do_show_streams) - for (i = 0; i < fmt_ctx->nb_streams; i++) - show_stream(fmt_ctx, i); - - if (do_show_format) - show_format(fmt_ctx); - - av_close_input_file(fmt_ctx); - return 0; -} - -static void show_usage(void) -{ - printf("Simple multimedia streams analyzer\n"); - printf("usage: ffprobe [OPTIONS] [INPUT_FILE]\n"); - printf("\n"); -} - -static void opt_format(const char *arg) -{ - iformat = av_find_input_format(arg); - if (!iformat) { - fprintf(stderr, "Unknown input format: %s\n", arg); - exit(1); - } -} - -static void opt_input_file(const char *arg) -{ - if (input_filename) { - fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", - arg, input_filename); - exit(1); - } - if (!strcmp(arg, "-")) - arg = "pipe:"; - input_filename = arg; -} - -static void show_help(void) -{ - show_usage(); - show_help_options(options, "Main options:\n", 0, 0); - printf("\n"); -} - -static void opt_pretty(void) -{ - show_value_unit = 1; - use_value_prefix = 1; - use_byte_value_binary_prefix = 1; - use_value_sexagesimal_format = 1; -} - -static const OptionDef options[] = { -#include "cmdutils_common_opts.h" - { "convert_tags", OPT_BOOL, {(void*)&convert_tags}, "convert tag names to the FFmpeg generic tag names" }, - { "f", HAS_ARG, {(void*)opt_format}, "force format", "format" }, - { "unit", OPT_BOOL, {(void*)&show_value_unit}, "show unit of the displayed values" }, - { "prefix", OPT_BOOL, {(void*)&use_value_prefix}, "use SI prefixes for the displayed values" }, - { "byte_binary_prefix", OPT_BOOL, {(void*)&use_byte_value_binary_prefix}, - "use binary prefixes for byte units" }, - { "sexagesimal", OPT_BOOL, {(void*)&use_value_sexagesimal_format}, - "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" }, - { "pretty", 0, {(void*)&opt_pretty}, - "prettify the format of displayed values, make it more human readable" }, - { "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" }, - { "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" }, - { NULL, }, -}; - -int main(int argc, char **argv) -{ - av_register_all(); -#if CONFIG_AVDEVICE - avdevice_register_all(); -#endif - - show_banner(); - parse_options(argc, argv, options, opt_input_file); - - if (!input_filename) { - show_usage(); - fprintf(stderr, "You have to specify one input file.\n"); - fprintf(stderr, "Use -h to get full help or, even better, run 'man ffprobe'.\n"); - exit(1); - } - - return probe_file(input_filename); -} diff --git a/tizen/distrib/ffmpeg/ffserver.c b/tizen/distrib/ffmpeg/ffserver.c deleted file mode 100644 index a1bd526..0000000 --- a/tizen/distrib/ffmpeg/ffserver.c +++ /dev/null @@ -1,4697 +0,0 @@ -/* - * Multiple format streaming server - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _XOPEN_SOURCE 600 - -#include "config.h" -#if !HAVE_CLOSESOCKET -#define closesocket close -#endif -#include -#include -#include -#include "libavformat/avformat.h" -#include "libavformat/network.h" -#include "libavformat/os_support.h" -#include "libavformat/rtpdec.h" -#include "libavformat/rtsp.h" -#include "libavutil/avstring.h" -#include "libavutil/lfg.h" -#include "libavutil/random_seed.h" -#include "libavcodec/opt.h" -#include -#include -#include -#include -#if HAVE_POLL_H -#include -#endif -#include -#include -#include -#include -#include -#if HAVE_DLFCN_H -#include -#endif - -#include "cmdutils.h" - -const char program_name[] = "FFserver"; -const int program_birth_year = 2000; - -static const OptionDef options[]; - -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, -}; - -static 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 - -/* timeouts are in ms */ -#define HTTP_REQUEST_TIMEOUT (15 * 1000) -#define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000) - -#define SYNC_TIMEOUT (10 * 1000) - -typedef struct RTSPActionServerSetup { - uint32_t ipaddr; - char transport_option[512]; -} RTSPActionServerSetup; - -typedef struct { - int64_t count1, count2; - int64_t 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 */ - int64_t timeout; - uint8_t *buffer_ptr, *buffer_end; - int http_error; - int post; - int chunked_encoding; - int chunk_size; /* 0 if it needs to be read */ - 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; - int64_t 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 RTSPLowerTransport 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; - -/* 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; - char dynamic_acl[1024]; - int nb_streams; - int prebuffer; /* Number of millseconds early to start */ - int64_t 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; - unsigned 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 truncate; /* True if feeder connection truncate the feed 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 around) */ - 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 averaged over last frames with exponential mean */ -} FeedData; - -static struct sockaddr_in my_http_addr; -static 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_status(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, RTSPMessageHeader *h); -static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h); -static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h); -static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *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 RTSPLowerTransport 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 const char *config_filename = "/etc/ffserver.conf"; - -static int ffserver_debug; -static int ffserver_daemon; -static int no_launch; -static int need_to_start_children; - -/* maximum number of simultaneous HTTP connections */ -static unsigned int nb_max_http_connections = 2000; -static unsigned int nb_max_connections = 5; -static unsigned int nb_connections; - -static uint64_t max_bandwidth = 1000; -static uint64_t current_bandwidth; - -static int64_t cur_time; // Making this global saves on passing it around everywhere - -static AVLFG random_state; - -static FILE *logfile = NULL; - -/* FIXME: make ffserver work with IPv6 */ -/* resolve host with also IP address parsing */ -static int resolve_host(struct in_addr *sin_addr, const char *hostname) -{ - - if (!ff_inet_aton(hostname, sin_addr)) { -#if HAVE_GETADDRINFO - struct addrinfo *ai, *cur; - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - if (getaddrinfo(hostname, NULL, &hints, &ai)) - return -1; - /* getaddrinfo returns a linked list of addrinfo structs. - * Even if we set ai_family = AF_INET above, make sure - * that the returned one actually is of the correct type. */ - for (cur = ai; cur; cur = cur->ai_next) { - if (cur->ai_family == AF_INET) { - *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr; - freeaddrinfo(ai); - return 0; - } - } - freeaddrinfo(ai); - return -1; -#else - struct hostent *hp; - hp = gethostbyname(hostname); - if (!hp) - return -1; - memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); -#endif - } - return 0; -} - -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 http_vlog(const char *fmt, va_list vargs) -{ - static int print_prefix = 1; - if (logfile) { - if (print_prefix) { - char buf[32]; - ctime1(buf); - fprintf(logfile, "%s ", buf); - } - print_prefix = strstr(fmt, "\n") != NULL; - vfprintf(logfile, fmt, vargs); - fflush(logfile); - } -} - -static void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...) -{ - va_list vargs; - va_start(vargs, fmt); - http_vlog(fmt, vargs); - va_end(vargs); -} - -static void http_av_log(void *ptr, int level, const char *fmt, va_list vargs) -{ - static int print_prefix = 1; - AVClass *avc = ptr ? *(AVClass**)ptr : NULL; - if (level > av_log_get_level()) - return; - if (print_prefix && avc) - http_log("[%s @ %p]", avc->item_name(ptr), ptr); - print_prefix = strstr(fmt, "\n") != NULL; - http_vlog(fmt, vargs); -} - -static void log_connection(HTTPContext *c) -{ - if (c->suppress_log) - return; - - http_log("%s - - [%s] \"%s %s\" %d %"PRId64"\n", - inet_ntoa(c->from_addr.sin_addr), 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) { - http_log("Unable to create children\n"); - exit(1); - } - if (!feed->pid) { - /* In child */ - char pathname[1024]; - char *slash; - int i; - - av_strlcpy(pathname, my_program_name, sizeof(pathname)); - - slash = strrchr(pathname, '/'); - if (!slash) - slash = pathname; - else - slash++; - strcpy(slash, "ffmpeg"); - - http_log("Launch commandline: "); - http_log("%s ", pathname); - for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++) - http_log("%s ", feed->child_argv[i]); - http_log("\n"); - - for (i = 3; i < 256; i++) - close(i); - - if (!ffserver_debug) { - i = open("/dev/null", O_RDWR); - if (i != -1) { - dup2(i, 0); - dup2(i, 1); - dup2(i, 2); - close(i); - } - } - - /* 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); - closesocket(server_fd); - return -1; - } - - if (listen (server_fd, 5) < 0) { - perror ("listen"); - closesocket(server_fd); - return -1; - } - ff_socket_nonblock(server_fd, 1); - - 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", - av_lfg_get(&random_state), av_lfg_get(&random_state)); - - /* 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_LOWER_TRANSPORT_UDP_MULTICAST); - if (!rtp_c) - continue; - - if (open_input_stream(rtp_c, "") < 0) { - http_log("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) { - http_log("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 = 0, rtsp_server_fd = 0; - int ret, delay, delay1; - struct pollfd *poll_table, *poll_entry; - HTTPContext *c, *c_next; - - if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) { - http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections); - return -1; - } - - if (my_http_addr.sin_port) { - server_fd = socket_open_listen(&my_http_addr); - if (server_fd < 0) - return -1; - } - - if (my_rtsp_addr.sin_port) { - rtsp_server_fd = socket_open_listen(&my_rtsp_addr); - if (rtsp_server_fd < 0) - return -1; - } - - if (!rtsp_server_fd && !server_fd) { - http_log("HTTP and RTSP disabled.\n"); - return -1; - } - - http_log("FFserver started.\n"); - - start_children(first_feed); - - start_multicast(); - - for(;;) { - poll_entry = poll_table; - if (server_fd) { - poll_entry->fd = server_fd; - poll_entry->events = POLLIN; - poll_entry++; - } - if (rtsp_server_fd) { - 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 && ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(EINTR)) - return -1; - } while (ret < 0); - - cur_time = av_gettime() / 1000; - - 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; - if (server_fd) { - /* new HTTP connection request ? */ - if (poll_entry->revents & POLLIN) - new_connection(server_fd, 0); - poll_entry++; - } - if (rtsp_server_fd) { - /* 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 http_send_too_busy_reply(int fd) -{ - char buffer[300]; - int len = snprintf(buffer, sizeof(buffer), - "HTTP/1.0 200 Server too busy\r\n" - "Content-type: text/html\r\n" - "\r\n" - "Too busy\r\n" - "

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

\r\n" - "

The number of current connections is %d, and this exceeds the limit of %d.

\r\n" - "\r\n", - nb_connections, nb_max_connections); - send(fd, buffer, len, 0); -} - - -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) { - http_log("error during accept %s\n", strerror(errno)); - return; - } - ff_socket_nonblock(fd, 1); - - if (nb_connections >= nb_max_connections) { - http_send_too_busy_reply(fd); - 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); - } - closesocket(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) - closesocket(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_metadata_free(&ctx->metadata); - av_free(ctx->streams[0]); - av_free(ctx); - } - h = c->rtp_handles[i]; - if (h) - url_close(h); - } - - ctx = &c->fmt_ctx; - - if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) { - if (ctx->oformat) { - /* prepare header */ - if (url_open_dyn_buf(&ctx->pb) >= 0) { - av_write_trailer(ctx); - av_freep(&c->pb_buffer); - 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; - - /* signal that there is no feed if we are the feeder socket */ - if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) { - c->stream->feed_opened = 0; - close(c->feed_fd); - } - - 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 = recv(c->fd, c->buffer_ptr, 1, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(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 = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(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; - /* close connection if trailer sent */ - if (c->state == HTTPSTATE_SEND_DATA_TRAILER) - 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 = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(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 = send(c->fd, c->packet_buffer_ptr, - c->packet_buffer_end - c->packet_buffer_ptr, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(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 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; -} - -static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl, - const char *p, const char *filename, int line_num) -{ - char arg[1024]; - IPAddressACL acl; - int errors = 0; - - 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); - - if (resolve_host(&acl.first, arg) != 0) { - fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n", - filename, line_num, arg); - errors++; - } else - acl.last = acl.first; - - get_arg(arg, sizeof(arg), &p); - - if (arg[0]) { - if (resolve_host(&acl.last, arg) != 0) { - fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n", - filename, line_num, arg); - errors++; - } - } - - if (!errors) { - IPAddressACL *nacl = av_mallocz(sizeof(*nacl)); - IPAddressACL **naclp = 0; - - acl.next = 0; - *nacl = acl; - - if (stream) - naclp = &stream->acl; - else if (feed) - naclp = &feed->acl; - else if (ext_acl) - naclp = &ext_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; - } - } -} - - -static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c) -{ - FILE* f; - char line[1024]; - char cmd[1024]; - IPAddressACL *acl = NULL; - int line_num = 0; - const char *p; - - f = fopen(stream->dynamic_acl, "r"); - if (!f) { - perror(stream->dynamic_acl); - return NULL; - } - - acl = av_mallocz(sizeof(IPAddressACL)); - - /* Build ACL */ - 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, "ACL")) - parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num); - } - fclose(f); - return acl; -} - - -static void free_acl_list(IPAddressACL *in_acl) -{ - IPAddressACL *pacl,*pacl2; - - pacl = in_acl; - while(pacl) { - pacl2 = pacl; - pacl = pacl->next; - av_freep(pacl2); - } -} - -static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c) -{ - enum IPAddressAction last_action = IP_DENY; - IPAddressACL *acl; - struct in_addr *src = &c->from_addr.sin_addr; - unsigned long src_addr = src->s_addr; - - for (acl = in_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; -} - -static int validate_acl(FFStream *stream, HTTPContext *c) -{ - int ret = 0; - IPAddressACL *acl; - - - /* if stream->acl is null validate_acl_list will return 1 */ - ret = validate_acl_list(stream->acl, c); - - if (stream->dynamic_acl[0]) { - acl = parse_dynamic_acl(stream, c); - - ret = validate_acl_list(acl, c); - - free_acl_list(acl); - } - - return ret; -} - -/* 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 */ - av_strlcpy(file1, filename, sizeof(file1)); - p = strrchr(file1, '.'); - if (p) - *p = '\0'; - for(stream = first_stream; stream != NULL; stream = stream->next) { - av_strlcpy(file2, stream->filename, sizeof(file2)); - p = strrchr(file2, '.'); - if (p) - *p = '\0'; - if (!strcmp(file1, file2)) { - av_strlcpy(filename, stream->filename, max_size); - 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[1024]; - 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); - av_strlcpy(c->method, cmd, sizeof(c->method)); - - 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); - av_strlcpy(c->url, url, sizeof(c->url)); - - get_word(protocol, sizeof(protocol), (const char **)&p); - if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1")) - return -1; - - av_strlcpy(c->protocol, protocol, sizeof(c->protocol)); - - if (ffserver_debug) - http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url); - - /* find the filename and the optional info string in the request */ - p = strchr(url, '?'); - if (p) { - av_strlcpy(info, p, sizeof(info)); - *p = '\0'; - } else - info[0] = '\0'; - - av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1); - - 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 (av_match_ext(filename, "asx")) { - redir_type = REDIR_ASX; - filename[strlen(filename)-1] = 'f'; - } else if (av_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 (av_match_ext(filename, "rpm,ram")) { - redir_type = REDIR_RAM; - strcpy(filename + strlen(filename)-2, "m"); - } else if (av_match_ext(filename, "rtsp")) { - redir_type = REDIR_RTSP; - compute_real_filename(filename, sizeof(filename) - 1); - } else if (av_match_ext(filename, "sdp")) { - redir_type = REDIR_SDP; - compute_real_filename(filename, sizeof(filename) - 1); - } - - // "redirect" / request to index.html - if (!strlen(filename)) - av_strlcpy(filename, "index.html", sizeof(filename) - 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); - http_log("File '%s' not found\n", 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, c->buffer_size, - "HTTP/1.0 301 Moved\r\n" - "Location: %s\r\n" - "Content-type: text/html\r\n" - "\r\n" - "Moved\r\n" - "You should be
redirected.\r\n" - "\r\n", stream->feed_filename, stream->feed_filename); - /* 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 < FF_ARRAY_ELEMS(c->feed_streams); 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 already streaming this feed, do not let start another feeder. */ - if (stream->feed_opened) { - snprintf(msg, sizeof(msg), "This feed is already being received."); - http_log("Feed '%s' already being received\n", stream->feed_filename); - goto send_error; - } - - if (c->post == 0 && max_bandwidth < current_bandwidth) { - c->http_error = 200; - q = c->buffer; - q += snprintf(q, c->buffer_size, - "HTTP/1.0 200 Server too busy\r\n" - "Content-type: text/html\r\n" - "\r\n" - "Too busy\r\n" - "

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

\r\n" - "

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

\r\n" - "\r\n", current_bandwidth, max_bandwidth); - /* 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, c->buffer_size, - "HTTP/1.0 200 ASX Follows\r\n" - "Content-type: video/x-ms-asf\r\n" - "\r\n" - "\r\n" - //"\r\n" - "\r\n" - "\r\n", hostbuf, filename, info); - break; - case REDIR_RAM: - q += snprintf(q, c->buffer_size, - "HTTP/1.0 200 RAM Follows\r\n" - "Content-type: audio/x-pn-realaudio\r\n" - "\r\n" - "# Autogenerated by ffserver\r\n" - "http://%s/%s%s\r\n", hostbuf, filename, info); - break; - case REDIR_ASF: - q += snprintf(q, c->buffer_size, - "HTTP/1.0 200 ASF Redirect follows\r\n" - "Content-type: video/x-ms-asf\r\n" - "\r\n" - "[Reference]\r\n" - "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info); - break; - case REDIR_RTSP: - { - char hostname[256], *p; - /* extract only hostname */ - av_strlcpy(hostname, hostbuf, sizeof(hostname)); - p = strrchr(hostname, ':'); - if (p) - *p = '\0'; - q += snprintf(q, c->buffer_size, - "HTTP/1.0 200 RTSP Redirect follows\r\n" - /* XXX: incorrect mime type ? */ - "Content-type: application/x-rtsp\r\n" - "\r\n" - "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, c->buffer_size, - "HTTP/1.0 200 OK\r\n" - "Content-type: application/sdp\r\n" - "\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: - 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! Let us 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 && 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_status; - - /* 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 = av_lfg_get(&random_state); - - 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, c->buffer_size, - "HTTP/1.0 404 Not Found\r\n" - "Content-type: text/html\r\n" - "\r\n" - "\n" - "404 Not Found\n" - "%s\n" - "\n", msg); - /* prepare output buffer */ - c->buffer_ptr = c->buffer; - c->buffer_end = q; - c->state = HTTPSTATE_SEND_HEADER; - return 0; - send_status: - compute_status(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_status(HTTPContext *c) -{ - HTTPContext *c1; - FFStream *stream; - char *p; - time_t ti; - int i, len; - ByteIOContext *pb; - - 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, "%s Status\n", program_name); - if (c->stream->feed_filename[0]) - url_fprintf(pb, "\n", c->stream->feed_filename); - url_fprintf(pb, "\n"); - url_fprintf(pb, "

%s Status

\n", program_name); - /* 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) { - av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10); - 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 && !strcmp(stream->fmt->name, "rtp")) { - /* 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 AVMEDIA_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 AVMEDIA_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 AVMEDIA_TYPE_DATA: - video_bit_rate += st->codec->bit_rate; - break; - default: - 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 AVMEDIA_TYPE_AUDIO: - type = "audio"; - snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate); - break; - case AVMEDIA_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: - 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; - } - - /* 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: %"PRIu64"k / %"PRIu64"k
\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, ret; - 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); - if (stream_pos == INT64_MIN) - return -1; - } 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); - if (stream_pos == INT64_MIN) - return -1; - } else - stream_pos = 0; - } - if (input_filename[0] == '\0') - return -1; - - /* open stream */ - if ((ret = av_open_input_file(&s, input_filename, c->stream->ifmt, - buf_size, c->stream->ap_in)) < 0) { - http_log("could not open %s: %d\n", input_filename, ret); - return -1; - } - s->flags |= AVFMT_FLAG_GENPTS; - c->fmt_in = s; - if (strcmp(s->iformat->name, "ffm") && av_find_stream_info(c->fmt_in) < 0) { - http_log("Could not find stream info '%s'\n", input_filename); - av_close_input_file(s); - return -1; - } - - /* 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 == AVMEDIA_TYPE_VIDEO) { - c->pts_stream_index = i; - } - } - -#if 1 - if (c->fmt_in->iformat->read_seek) - av_seek_frame(c->fmt_in, -1, 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 (cur_time - c->start_time) * 1000; -} - -/* 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)); - av_metadata_set2(&c->fmt_ctx.metadata, "author" , c->stream->author , 0); - av_metadata_set2(&c->fmt_ctx.metadata, "comment" , c->stream->comment , 0); - av_metadata_set2(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0); - av_metadata_set2(&c->fmt_ctx.metadata, "title" , c->stream->title , 0); - - for(i=0;istream->nb_streams;i++) { - AVStream *st; - AVStream *src; - st = av_mallocz(sizeof(AVStream)); - 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 */ - } - /* set output format parameters */ - c->fmt_ctx.oformat = c->stream->fmt; - c->fmt_ctx.nb_streams = c->stream->nb_streams; - - 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; - - /* - * HACK to avoid mpeg ps muxer to spit many underflow errors - * Default value from FFmpeg - * Try to set it use configuration option - */ - c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE); - c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); - - av_set_parameters(&c->fmt_ctx, NULL); - if (av_write_header(&c->fmt_ctx) < 0) { - http_log("Error writing output header\n"); - return -1; - } - av_metadata_free(&c->fmt_ctx.metadata); - - 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 */ - /* 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 { - AVPacket pkt; - 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 { - int source_index = pkt.stream_index; - /* 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 & AV_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->stream->feed_streams[i] == pkt.stream_index) { - AVStream *st = c->fmt_in->streams[source_index]; - pkt.stream_index = i; - if (pkt.flags & AV_PKT_FLAG_KEY && - (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || - c->stream->nb_streams == 1)) - c->got_key_frame = 1; - if (!c->stream->send_on_key || c->got_key_frame) - goto send_it; - } - } - } else { - AVCodecContext *codec; - AVStream *ist, *ost; - send_it: - ist = c->fmt_in->streams[source_index]; - /* specific handling for RTP: we use several - output stream (one for each RTP - connection). XXX: need more abstract handling */ - if (c->is_packetized) { - /* compute send time and duration */ - c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q); - if (ist->start_time != AV_NOPTS_VALUE) - c->cur_pts -= av_rescale_q(ist->start_time, ist->time_base, AV_TIME_BASE_Q); - c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q); - /* 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; - } - - if (c->is_packetized) { - int max_packet_size; - if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_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; - } - ost = ctx->streams[pkt.stream_index]; - - ctx->pb->is_streamed = 1; - if (pkt.dts != AV_NOPTS_VALUE) - pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base); - if (pkt.pts != AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base); - pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base); - if (av_write_frame(ctx, &pkt) < 0) { - http_log("Error writing frame to output\n"); - 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) { - av_free_packet(&pkt); - 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; - } - c->fmt_ctx.pb->is_streamed = 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; -} - -/* 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_LOWER_TRANSPORT_TCP) { - /* RTP packets are sent inside the RTSP TCP connection */ - ByteIOContext *pb; - 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 = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr, - rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0); - 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 = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(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) { - http_log("Error opening feeder file: %s\n", strerror(errno)); - return -1; - } - c->feed_fd = fd; - - if (c->stream->truncate) { - /* truncate feed file */ - ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE); - ftruncate(c->feed_fd, FFM_PACKET_SIZE); - http_log("Truncating feed file '%s'\n", c->stream->feed_filename); - } else { - if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) { - http_log("Error reading write index from feed file: %s\n", strerror(errno)); - return -1; - } - } - - c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE); - 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; - c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked"); - return 0; -} - -static int http_receive_data(HTTPContext *c) -{ - HTTPContext *c1; - int len, loop_run = 0; - - while (c->chunked_encoding && !c->chunk_size && - c->buffer_end > c->buffer_ptr) { - /* read chunk header, if present */ - len = recv(c->fd, c->buffer_ptr, 1, 0); - - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(EINTR)) - /* error : close connection */ - goto fail; - } else if (len == 0) { - /* end of connection : close it */ - goto fail; - } else if (c->buffer_ptr - c->buffer >= 2 && - !memcmp(c->buffer_ptr - 1, "\r\n", 2)) { - c->chunk_size = strtol(c->buffer, 0, 16); - if (c->chunk_size == 0) // end of stream - goto fail; - c->buffer_ptr = c->buffer; - break; - } else if (++loop_run > 10) { - /* no chunk header, abort */ - goto fail; - } else { - c->buffer_ptr++; - } - } - - if (c->buffer_end > c->buffer_ptr) { - len = recv(c->fd, c->buffer_ptr, - FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(EINTR)) - /* error : close connection */ - goto fail; - } else if (len == 0) - /* end of connection : close it */ - goto fail; - else { - c->chunk_size -= len; - 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%"PRIx64" size=0x%"PRIx64"\n", feed->feed_write_index, feed->feed_size); - /* XXX: use llseek or url_seek */ - lseek(c->feed_fd, feed->feed_write_index, SEEK_SET); - if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) { - http_log("Error writing to feed file: %s\n", strerror(errno)); - goto fail; - } - - 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 */ - if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) { - http_log("Error writing index to feed file: %s\n", strerror(errno)); - goto fail; - } - - /* 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 = NULL; - ByteIOContext *pb; - AVInputFormat *fmt_in; - int i; - - /* use feed output format name to find corresponding input format */ - fmt_in = av_find_input_format(feed->fmt->name); - if (!fmt_in) - goto fail; - - url_open_buf(&pb, c->buffer, c->buffer_end - c->buffer, URL_RDONLY); - pb->is_streamed = 1; - - if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) { - av_free(pb); - goto fail; - } - - /* Now we have the actual streams */ - if (s->nb_streams != feed->nb_streams) { - av_close_input_stream(s); - av_free(pb); - http_log("Feed '%s' stream number does not match registered feed\n", - c->stream->feed_filename); - goto fail; - } - - for (i = 0; i < s->nb_streams; i++) { - AVStream *fst = feed->streams[i]; - AVStream *st = s->streams[i]; - memcpy(fst->codec, st->codec, sizeof(AVCodecContext)); - if (fst->codec->extradata_size) { - fst->codec->extradata = av_malloc(fst->codec->extradata_size); - if (!fst->codec->extradata) - goto fail; - memcpy(fst->codec->extradata, st->codec->extradata, - fst->codec->extradata_size); - } - } - - av_close_input_stream(s); - av_free(pb); - } - c->buffer_ptr = c->buffer; - } - - return 0; - fail: - c->stream->feed_opened = 0; - close(c->feed_fd); - /* wake up any waiting connections to stop waiting for feed */ - 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_TRAILER; - } - 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) { - case RTSP_STATUS_OK: - str = "OK"; - break; - case RTSP_STATUS_METHOD: - str = "Method Not Allowed"; - break; - case RTSP_STATUS_BANDWIDTH: - str = "Not Enough Bandwidth"; - break; - case RTSP_STATUS_SESSION: - str = "Session Not Found"; - break; - case RTSP_STATUS_STATE: - str = "Method Not Valid in This State"; - break; - case RTSP_STATUS_AGGREGATE: - str = "Aggregate operation not allowed"; - break; - case RTSP_STATUS_ONLY_AGGREGATE: - str = "Only aggregate operation allowed"; - break; - case RTSP_STATUS_TRANSPORT: - str = "Unsupported transport"; - break; - case RTSP_STATUS_INTERNAL: - str = "Internal Server Error"; - break; - case RTSP_STATUS_SERVICE: - str = "Service Unavailable"; - break; - case RTSP_STATUS_VERSION: - str = "RTSP Version not supported"; - break; - 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]; - int len; - RTSPMessageHeader 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); - - av_strlcpy(c->method, cmd, sizeof(c->method)); - av_strlcpy(c->url, url, sizeof(c->url)); - av_strlcpy(c->protocol, protocol, sizeof(c->protocol)); - - 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(*header)); - /* skip to next line */ - while (*p != '\n' && *p != '\0') - p++; - if (*p == '\n') - p++; - while (*p != '\0') { - p1 = memchr(p, '\n', (char *)c->buffer_ptr - p); - 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'; - ff_rtsp_parse_line(header, line, NULL); - 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; -} - -static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, - struct in_addr my_ip) -{ - AVFormatContext *avc; - AVStream avs[MAX_STREAMS]; - int i; - - avc = avformat_alloc_context(); - if (avc == NULL) { - return -1; - } - av_metadata_set2(&avc->metadata, "title", - stream->title[0] ? stream->title : "No Title", 0); - avc->nb_streams = stream->nb_streams; - if (stream->is_multicast) { - snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d", - inet_ntoa(stream->multicast_ip), - stream->multicast_port, stream->multicast_ttl); - } else { - snprintf(avc->filename, 1024, "rtp://0.0.0.0"); - } - - for(i = 0; i < stream->nb_streams; i++) { - avc->streams[i] = &avs[i]; - avc->streams[i]->codec = stream->streams[i]->codec; - } - *pbuffer = av_mallocz(2048); - avf_sdp_create(&avc, 1, *pbuffer, 2048); - av_metadata_free(&avc->metadata); - av_free(avc); - - return strlen(*pbuffer); -} - -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 */ - ff_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 && !strcmp(stream->fmt->name, "rtp") && - !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-Base: %s/\r\n", url); - 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); - av_free(content); -} - -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(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport) -{ - RTSPTransportField *th; - int i; - - for(i=0;inb_transports;i++) { - th = &h->transports[i]; - if (th->lower_transport == lower_transport) - return th; - } - return NULL; -} - -static void rtsp_cmd_setup(HTTPContext *c, const char *url, - RTSPMessageHeader *h) -{ - FFStream *stream; - int stream_index, rtp_port, rtcp_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 */ - ff_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 && !strcmp(stream->fmt->name, "rtp")) { - /* 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", - av_lfg_get(&random_state), av_lfg_get(&random_state)); - - /* 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_LOWER_TRANSPORT_UDP); - if (!th) { - th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP); - if (!th) { - rtsp_reply_error(c, RTSP_STATUS_TRANSPORT); - return; - } - } - - rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id, - th->lower_transport); - 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->lower_transport == RTSP_LOWER_TRANSPORT_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); - - /* 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_LOWER_TRANSPORT_UDP: - rtp_port = rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]); - rtcp_port = rtp_get_local_rtcp_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_max, - rtp_port, rtcp_port); - break; - case RTSP_LOWER_TRANSPORT_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 */ - ff_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, RTSPMessageHeader *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; - } - - 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, RTSPMessageHeader *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, RTSPMessageHeader *h) -{ - HTTPContext *rtp_c; - char session_id[32]; - - rtp_c = find_rtp_session_with_url(url, h->session_id); - if (!rtp_c) { - rtsp_reply_error(c, RTSP_STATUS_SESSION); - return; - } - - av_strlcpy(session_id, rtp_c->session_id, sizeof(session_id)); - - /* abort the session */ - close_connection(rtp_c); - - /* 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", 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 RTSPLowerTransport 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; - av_strlcpy(c->session_id, session_id, sizeof(c->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_LOWER_TRANSPORT_UDP_MULTICAST: - proto_str = "MCAST"; - break; - case RTSP_LOWER_TRANSPORT_UDP: - proto_str = "UDP"; - break; - case RTSP_LOWER_TRANSPORT_TCP: - proto_str = "TCP"; - break; - default: - proto_str = "???"; - break; - } - av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol)); - av_strlcat(c->protocol, proto_str, sizeof(c->protocol)); - - 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 = NULL; - uint8_t *dummy_buf; - int max_packet_size; - - /* now we can open the relevant output stream */ - ctx = avformat_alloc_context(); - if (!ctx) - return -1; - ctx->oformat = av_guess_format("rtp", NULL, NULL); - - st = av_mallocz(sizeof(AVStream)); - if (!st) - goto fail; - 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)); - st->priv_data = NULL; - - /* build destination RTP address */ - ipaddr = inet_ntoa(dest_addr->sin_addr); - - switch(c->rtp_protocol) { - case RTSP_LOWER_TRANSPORT_UDP: - case RTSP_LOWER_TRANSPORT_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_LOWER_TRANSPORT_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 - - \"PLAY %s/streamid=%d %s\"\n", - ipaddr, ntohs(dest_addr->sin_port), - 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, int copy) -{ - AVStream *fst; - - fst = av_mallocz(sizeof(AVStream)); - if (!fst) - return NULL; - if (copy) { - fst->codec= avcodec_alloc_context(); - memcpy(fst->codec, codec, sizeof(AVCodecContext)); - if (codec->extradata_size) { - fst->codec->extradata = av_malloc(codec->extradata_size); - memcpy(fst->codec->extradata, codec->extradata, - codec->extradata_size); - } - } else { - /* live streams must use the actual feed's codec since it may be - * updated later to carry extradata needed by the streams. - */ - fst->codec = codec; - } - fst->priv_data = av_mallocz(sizeof(FeedData)); - 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 AVMEDIA_TYPE_AUDIO: - if (av1->channels == av->channels && - av1->sample_rate == av->sample_rate) - goto found; - break; - case AVMEDIA_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: - abort(); - } - } - } - - fst = add_av_stream1(feed, av, 0); - 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_log(infile, AV_LOG_DEBUG, 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, ret; - - /* 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 && !strcmp(stream->fmt->name, "rtp")) { - /* 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; - } - - http_log("Opening file '%s'\n", stream->feed_filename); - if ((ret = av_open_input_file(&infile, stream->feed_filename, - stream->ifmt, 0, stream->ap_in)) < 0) { - http_log("Could not open '%s': %d\n", stream->feed_filename, ret); - /* 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'\n", - 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, 1); - - 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) { - http_log("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_id) || CHECK_CODEC(codec_type)) { - http_log("Codecs do not match for stream %d\n", i); - matches = 0; - } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) { - http_log("Codec bitrates do not match for stream %d\n", i); - matches = 0; - } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) { - if (CHECK_CODEC(time_base.den) || - CHECK_CODEC(time_base.num) || - CHECK_CODEC(width) || - CHECK_CODEC(height)) { - http_log("Codec width, height and framerate do not match for stream %d\n", i); - matches = 0; - } - } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) { - if (CHECK_CODEC(sample_rate) || - CHECK_CODEC(channels) || - CHECK_CODEC(frame_size)) { - http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i); - matches = 0; - } - } else { - http_log("Unknown codec type\n"); - matches = 0; - } - } - if (!matches) - break; - } - } else - http_log("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 - http_log("Deleting feed file '%s' as it appears to be corrupt\n", - feed->feed_filename); - - if (!matches) { - if (feed->readonly) { - http_log("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 = {0}, *s = &s1; - - if (feed->readonly) { - http_log("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) { - http_log("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); - if (av_write_header(s) < 0) { - http_log("Container doesn't supports the required parameters\n"); - exit(1); - } - /* 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) { - http_log("Could not open output feed file '%s'\n", - feed->feed_filename); - exit(1); - } - - feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE); - 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) -{ - unsigned bandwidth; - int 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 AVMEDIA_TYPE_AUDIO: - case AVMEDIA_TYPE_VIDEO: - bandwidth += st->codec->bit_rate; - break; - default: - break; - } - } - stream->bandwidth = (bandwidth + 999) / 1000; - } -} - -/* 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 AVMEDIA_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 AVMEDIA_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 = FFMAX(av->bit_rate / 4, - (int64_t)av->bit_rate*av->time_base.num/av->time_base.den); - 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: - 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 enum CodecID opt_audio_codec(const char *arg) -{ - AVCodec *p= avcodec_find_encoder_by_name(arg); - - if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO) - return CODEC_ID_NONE; - - return p->id; -} - -static enum CodecID opt_video_codec(const char *arg) -{ - AVCodec *p= avcodec_find_encoder_by_name(arg); - - if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO) - return CODEC_ID_NONE; - - return p->id; -} - -/* simplistic plugin support */ - -#if HAVE_DLOPEN -static 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 ffserver_opt_default(const char *opt, const char *arg, - AVCodecContext *avctx, int type) -{ - int ret = 0; - const AVOption *o = av_find_opt(avctx, opt, NULL, type, type); - if(o) - ret = av_set_string3(avctx, opt, arg, 1, NULL); - return ret; -} - -static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename, - const char *mime_type) -{ - AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type); - - if (fmt) { - AVOutputFormat *stream_fmt; - char stream_format_name[64]; - - snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name); - stream_fmt = av_guess_format(stream_format_name, NULL, NULL); - - if (stream_fmt) - fmt = stream_fmt; - } - - return fmt; -} - -static void report_config_error(const char *filename, int line_num, int *errors, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - fprintf(stderr, "%s:%d: ", filename, line_num); - vfprintf(stderr, fmt, vl); - va_end(vl); - - (*errors)++; -} - -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, *s; - AVCodecContext audio_enc, video_enc; - enum CodecID 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; - -#define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__) - 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); - val = atoi(arg); - if (val < 1 || val > 65536) { - ERROR("Invalid_port: %s\n", arg); - } - my_http_addr.sin_port = htons(val); - } else if (!strcasecmp(cmd, "BindAddress")) { - get_arg(arg, sizeof(arg), &p); - if (resolve_host(&my_http_addr.sin_addr, arg) != 0) { - ERROR("%s:%d: Invalid host/IP address: %s\n", arg); - } - } else if (!strcasecmp(cmd, "NoDaemon")) { - ffserver_daemon = 0; - } else if (!strcasecmp(cmd, "RTSPPort")) { - get_arg(arg, sizeof(arg), &p); - val = atoi(arg); - if (val < 1 || val > 65536) { - ERROR("%s:%d: Invalid port: %s\n", arg); - } - my_rtsp_addr.sin_port = htons(atoi(arg)); - } else if (!strcasecmp(cmd, "RTSPBindAddress")) { - get_arg(arg, sizeof(arg), &p); - if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) { - ERROR("Invalid host/IP address: %s\n", arg); - } - } else if (!strcasecmp(cmd, "MaxHTTPConnections")) { - get_arg(arg, sizeof(arg), &p); - val = atoi(arg); - if (val < 1 || val > 65536) { - ERROR("Invalid MaxHTTPConnections: %s\n", arg); - } - nb_max_http_connections = val; - } else if (!strcasecmp(cmd, "MaxClients")) { - get_arg(arg, sizeof(arg), &p); - val = atoi(arg); - if (val < 1 || val > nb_max_http_connections) { - ERROR("Invalid MaxClients: %s\n", arg); - } else { - nb_max_connections = val; - } - } else if (!strcasecmp(cmd, "MaxBandwidth")) { - int64_t llval; - get_arg(arg, sizeof(arg), &p); - llval = atoll(arg); - if (llval < 10 || llval > 10000000) { - ERROR("Invalid MaxBandwidth: %s\n", arg); - } else - max_bandwidth = llval; - } else if (!strcasecmp(cmd, "CustomLog")) { - if (!ffserver_debug) - get_arg(logfilename, sizeof(logfilename), &p); - } else if (!strcasecmp(cmd, "filename, sizeof(feed->filename), &p); - q = strrchr(feed->filename, '>'); - if (*q) - *q = '\0'; - - for (s = first_feed; s; s = s->next) { - if (!strcmp(feed->filename, s->filename)) { - ERROR("Feed '%s' already registered\n", s->filename); - } - } - - feed->fmt = av_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 :-) */ - - /* add in stream list */ - *last_stream = feed; - last_stream = &feed->next; - /* add in feed list */ - *last_feed = feed; - last_feed = &feed->next_feed; - } - } else if (!strcasecmp(cmd, "Launch")) { - if (feed) { - int i; - - feed->child_argv = av_mallocz(64 * sizeof(char *)); - - for (i = 0; i < 62; i++) { - get_arg(arg, sizeof(arg), &p); - if (!arg[0]) - break; - - feed->child_argv[i] = av_strdup(arg); - } - - 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); - } - } 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, "Truncate")) { - if (feed) { - get_arg(arg, sizeof(arg), &p); - feed->truncate = strtod(arg, NULL); - } - } else if (!strcasecmp(cmd, "FileMaxSize")) { - if (feed) { - char *p1; - double fsize; - - get_arg(arg, sizeof(arg), &p); - p1 = arg; - fsize = strtod(p1, &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; - if (feed->feed_max_size < FFM_PACKET_SIZE*4) { - ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4); - } - } - } else if (!strcasecmp(cmd, "")) { - if (!feed) { - ERROR("No corresponding for \n"); - } - feed = NULL; - } else if (!strcasecmp(cmd, "filename, sizeof(stream->filename), &p); - q = strrchr(stream->filename, '>'); - if (*q) - *q = '\0'; - - for (s = first_stream; s; s = s->next) { - if (!strcmp(stream->filename, s->filename)) { - ERROR("Stream '%s' already registered\n", s->filename); - } - } - - stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL); - avcodec_get_context_defaults2(&video_enc, AVMEDIA_TYPE_VIDEO); - avcodec_get_context_defaults2(&audio_enc, AVMEDIA_TYPE_AUDIO); - 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; - } - - *last_stream = stream; - last_stream = &stream->next; - } - } 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) - ERROR("feed '%s' not defined\n", arg); - else - stream->feed = sfeed; - } - } else if (!strcasecmp(cmd, "Format")) { - get_arg(arg, sizeof(arg), &p); - if (stream) { - 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 = ffserver_guess_format(arg, NULL, NULL); - if (!stream->fmt) { - ERROR("Unknown Format: %s\n", arg); - } - } - if (stream->fmt) { - audio_id = stream->fmt->audio_codec; - video_id = stream->fmt->video_codec; - } - } - } else if (!strcasecmp(cmd, "InputFormat")) { - get_arg(arg, sizeof(arg), &p); - if (stream) { - stream->ifmt = av_find_input_format(arg); - if (!stream->ifmt) { - ERROR("Unknown input format: %s\n", 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 { - ERROR("FaviconURL only permitted for status streams\n"); - } - } 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) { - ERROR("Unknown AudioCodec: %s\n", arg); - } - } else if (!strcasecmp(cmd, "VideoCodec")) { - get_arg(arg, sizeof(arg), &p); - video_id = opt_video_codec(arg); - if (video_id == CODEC_ID_NONE) { - ERROR("Unknown VideoCodec: %s\n", arg); - } - } 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 { - ERROR("Incorrect format for VideoBitRateRange -- should be -: %s\n", arg); - } - } - } 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) { - av_parse_video_frame_size(&video_enc.width, &video_enc.height, arg); - if ((video_enc.width % 16) != 0 || - (video_enc.height % 16) != 0) { - ERROR("Image size must be a multiple of 16\n"); - } - } - } else if (!strcasecmp(cmd, "VideoFrameRate")) { - get_arg(arg, sizeof(arg), &p); - if (stream) { - AVRational frame_rate; - if (av_parse_video_frame_rate(&frame_rate, arg) < 0) { - ERROR("Incorrect frame rate: %s\n", arg); - } else { - video_enc.time_base.num = frame_rate.den; - video_enc.time_base.den = frame_rate.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, "AVOptionVideo") || - !strcasecmp(cmd, "AVOptionAudio")) { - char arg2[1024]; - AVCodecContext *avctx; - int type; - get_arg(arg, sizeof(arg), &p); - get_arg(arg2, sizeof(arg2), &p); - if (!strcasecmp(cmd, "AVOptionVideo")) { - avctx = &video_enc; - type = AV_OPT_FLAG_VIDEO_PARAM; - } else { - avctx = &audio_enc; - type = AV_OPT_FLAG_AUDIO_PARAM; - } - if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) { - ERROR("AVOption error: %s %s\n", arg, arg2); - } - } else if (!strcasecmp(cmd, "VideoTag")) { - get_arg(arg, sizeof(arg), &p); - if ((strlen(arg) == 4) && stream) - video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]); - } 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) { - ERROR("VideoQDiff out of range\n"); - } - } - } 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) { - ERROR("VideoQMax out of range\n"); - } - } - } 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) { - ERROR("VideoQMin out of range\n"); - } - } - } 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")) { - parse_acl_row(stream, feed, NULL, p, filename, line_num); - } else if (!strcasecmp(cmd, "DynamicACL")) { - if (stream) { - get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p); - } - } else if (!strcasecmp(cmd, "RTSPOption")) { - get_arg(arg, sizeof(arg), &p); - if (stream) { - av_freep(&stream->rtsp_option); - stream->rtsp_option = av_strdup(arg); - } - } else if (!strcasecmp(cmd, "MulticastAddress")) { - get_arg(arg, sizeof(arg), &p); - if (stream) { - if (resolve_host(&stream->multicast_ip, arg) != 0) { - ERROR("Invalid host/IP address: %s\n", arg); - } - 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) { - ERROR("No corresponding for \n"); - } else { - if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) { - if (audio_id != CODEC_ID_NONE) { - audio_enc.codec_type = AVMEDIA_TYPE_AUDIO; - audio_enc.codec_id = audio_id; - add_codec(stream, &audio_enc); - } - if (video_id != CODEC_ID_NONE) { - video_enc.codec_type = AVMEDIA_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) { - ERROR("No corresponding for \n"); - } else { - if (!redirect->feed_filename[0]) { - ERROR("No URL found for \n"); - } - redirect = NULL; - } - } else if (!strcasecmp(cmd, "LoadModule")) { - get_arg(arg, sizeof(arg), &p); -#if HAVE_DLOPEN - load_module(arg); -#else - ERROR("Module support not compiled into this version: '%s'\n", arg); -#endif - } else { - ERROR("Incorrect keyword: '%s'\n", cmd); - } - } -#undef ERROR - - fclose(f); - if (errors) - return -1; - else - return 0; -} - -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; -} - -static void opt_debug(void) -{ - ffserver_debug = 1; - ffserver_daemon = 0; - logfilename[0] = '-'; -} - -static void show_help(void) -{ - printf("usage: ffserver [options]\n" - "Hyper fast multi format Audio/Video streaming server\n"); - printf("\n"); - show_help_options(options, "Main options:\n", 0, 0); -} - -static const OptionDef options[] = { -#include "cmdutils_common_opts.h" - { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" }, - { "d", 0, {(void*)opt_debug}, "enable debug mode" }, - { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" }, - { NULL }, -}; - -int main(int argc, char **argv) -{ - struct sigaction sigact; - - av_register_all(); - - show_banner(); - - my_program_name = argv[0]; - my_program_dir = getcwd(0, 0); - ffserver_daemon = 1; - - parse_options(argc, argv, options, NULL); - - unsetenv("http_proxy"); /* Kill the http_proxy */ - - av_lfg_init(&random_state, ff_random_get_seed()); - - 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); - } - - /* open log file if needed */ - if (logfilename[0] != '\0') { - if (!strcmp(logfilename, "-")) - logfile = stdout; - else - logfile = fopen(logfilename, "a"); - av_log_set_callback(http_av_log); - } - - 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(); - 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); - - if (ffserver_daemon) - chdir("/"); - - if (http_server() < 0) { - http_log("Could not start server\n"); - exit(1); - } - - return 0; -} diff --git a/tizen/distrib/ffmpeg/ffserver.h b/tizen/distrib/ffmpeg/ffserver.h deleted file mode 100644 index c76752f..0000000 --- a/tizen/distrib/ffmpeg/ffserver.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Multiple format streaming server - * copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef FFMPEG_FFSERVER_H -#define FFMPEG_FFSERVER_H - -/* interface between ffserver and modules */ - -void ffserver_module_init(void); - -#endif /* FFMPEG_FFSERVER_H */ diff --git a/tizen/distrib/ffmpeg/include/libavcodec/avcodec.h b/tizen/distrib/ffmpeg/include/libavcodec/avcodec.h deleted file mode 100644 index 71a6a13..0000000 --- a/tizen/distrib/ffmpeg/include/libavcodec/avcodec.h +++ /dev/null @@ -1,4021 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AVCODEC_H -#define AVCODEC_AVCODEC_H - -/** - * @file - * external API header - */ - -#include -#include "libavutil/avutil.h" - -#define LIBAVCODEC_VERSION_MAJOR 52 -#define LIBAVCODEC_VERSION_MINOR 72 -#define LIBAVCODEC_VERSION_MICRO 2 - -#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, \ - LIBAVCODEC_VERSION_MICRO) -#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, \ - LIBAVCODEC_VERSION_MICRO) -#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT - -#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) - -#define AV_NOPTS_VALUE INT64_C(0x8000000000000000) -#define AV_TIME_BASE 1000000 -#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} - -/** - * Identifies the syntax and semantics of the bitstream. - * The principle is roughly: - * Two decoders with the same ID can decode the same streams. - * Two encoders with the same ID can encode compatible streams. - * There may be slight deviations from the principle due to implementation - * details. - * - * If you add a codec ID to this list, add it so that - * 1. no value of a existing codec ID changes (that would break ABI), - * 2. it is as close as possible to similar codecs. - */ -enum CodecID { - CODEC_ID_NONE, - - /* video codecs */ - CODEC_ID_MPEG1VIDEO, - CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video 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, -#if LIBAVCODEC_VERSION_MAJOR < 53 - CODEC_ID_XVID, -#endif - 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_VC1, - 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, - CODEC_ID_FLASHSV, - CODEC_ID_CAVS, - CODEC_ID_JPEG2000, - CODEC_ID_VMNC, - CODEC_ID_VP5, - CODEC_ID_VP6, - CODEC_ID_VP6F, - CODEC_ID_TARGA, - CODEC_ID_DSICINVIDEO, - CODEC_ID_TIERTEXSEQVIDEO, - CODEC_ID_TIFF, - CODEC_ID_GIF, - CODEC_ID_FFH264, - CODEC_ID_DXA, - CODEC_ID_DNXHD, - CODEC_ID_THP, - CODEC_ID_SGI, - CODEC_ID_C93, - CODEC_ID_BETHSOFTVID, - CODEC_ID_PTX, - CODEC_ID_TXD, - CODEC_ID_VP6A, - CODEC_ID_AMV, - CODEC_ID_VB, - CODEC_ID_PCX, - CODEC_ID_SUNRAST, - CODEC_ID_INDEO4, - CODEC_ID_INDEO5, - CODEC_ID_MIMIC, - CODEC_ID_RL2, - CODEC_ID_8SVX_EXP, - CODEC_ID_8SVX_FIB, - CODEC_ID_ESCAPE124, - CODEC_ID_DIRAC, - CODEC_ID_BFI, - CODEC_ID_CMV, - CODEC_ID_MOTIONPIXELS, - CODEC_ID_TGV, - CODEC_ID_TGQ, - CODEC_ID_TQI, - CODEC_ID_AURA, - CODEC_ID_AURA2, - CODEC_ID_V210X, - CODEC_ID_TMV, - CODEC_ID_V210, - CODEC_ID_DPX, - CODEC_ID_MAD, - CODEC_ID_FRWU, - CODEC_ID_FLASHSV2, - CODEC_ID_CDGRAPHICS, - CODEC_ID_R210, - CODEC_ID_ANM, - CODEC_ID_BINKVIDEO, - CODEC_ID_IFF_ILBM, - CODEC_ID_IFF_BYTERUN1, - CODEC_ID_KGV1, - CODEC_ID_YOP, - CODEC_ID_VP8, - - /* 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, - CODEC_ID_PCM_ZORK, - CODEC_ID_PCM_S16LE_PLANAR, - CODEC_ID_PCM_DVD, - CODEC_ID_PCM_F32BE, - CODEC_ID_PCM_F32LE, - CODEC_ID_PCM_F64BE, - CODEC_ID_PCM_F64LE, - CODEC_ID_PCM_BLURAY, - - /* 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, - CODEC_ID_ADPCM_THP, - CODEC_ID_ADPCM_IMA_AMV, - CODEC_ID_ADPCM_EA_R1, - CODEC_ID_ADPCM_EA_R3, - CODEC_ID_ADPCM_EA_R2, - CODEC_ID_ADPCM_IMA_EA_SEAD, - CODEC_ID_ADPCM_IMA_EA_EACS, - CODEC_ID_ADPCM_EA_XAS, - CODEC_ID_ADPCM_EA_MAXIS_XA, - CODEC_ID_ADPCM_IMA_ISS, - - /* 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, - - /* audio codecs */ - CODEC_ID_MP2= 0x15000, - CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 - CODEC_ID_AAC, - 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, ///< as in Berlin toast format - CODEC_ID_QDM2, - CODEC_ID_COOK, - CODEC_ID_TRUESPEECH, - CODEC_ID_TTA, - CODEC_ID_SMACKAUDIO, - CODEC_ID_QCELP, - CODEC_ID_WAVPACK, - CODEC_ID_DSICINAUDIO, - CODEC_ID_IMC, - CODEC_ID_MUSEPACK7, - CODEC_ID_MLP, - CODEC_ID_GSM_MS, /* as found in WAV */ - CODEC_ID_ATRAC3, - CODEC_ID_VOXWARE, - CODEC_ID_APE, - CODEC_ID_NELLYMOSER, - CODEC_ID_MUSEPACK8, - CODEC_ID_SPEEX, - CODEC_ID_WMAVOICE, - CODEC_ID_WMAPRO, - CODEC_ID_WMALOSSLESS, - CODEC_ID_ATRAC3P, - CODEC_ID_EAC3, - CODEC_ID_SIPR, - CODEC_ID_MP1, - CODEC_ID_TWINVQ, - CODEC_ID_TRUEHD, - CODEC_ID_MP4ALS, - CODEC_ID_ATRAC1, - CODEC_ID_BINKAUDIO_RDFT, - CODEC_ID_BINKAUDIO_DCT, - - /* subtitle codecs */ - CODEC_ID_DVD_SUBTITLE= 0x17000, - CODEC_ID_DVB_SUBTITLE, - CODEC_ID_TEXT, ///< raw UTF-8 text - CODEC_ID_XSUB, - CODEC_ID_SSA, - CODEC_ID_MOV_TEXT, - CODEC_ID_HDMV_PGS_SUBTITLE, - CODEC_ID_DVB_TELETEXT, - - /* other specific kind of codecs (generally used for attachments) */ - CODEC_ID_TTF= 0x18000, - - CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it - - CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS - * stream (only used by libavformat) */ -}; - -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define CodecType AVMediaType - -#define CODEC_TYPE_UNKNOWN AVMEDIA_TYPE_UNKNOWN -#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO -#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO -#define CODEC_TYPE_DATA AVMEDIA_TYPE_DATA -#define CODEC_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE -#define CODEC_TYPE_ATTACHMENT AVMEDIA_TYPE_ATTACHMENT -#define CODEC_TYPE_NB AVMEDIA_TYPE_NB -#endif - -/** - * all in native-endian format - */ -enum SampleFormat { - SAMPLE_FMT_NONE = -1, - SAMPLE_FMT_U8, ///< unsigned 8 bits - SAMPLE_FMT_S16, ///< signed 16 bits - SAMPLE_FMT_S32, ///< signed 32 bits - SAMPLE_FMT_FLT, ///< float - SAMPLE_FMT_DBL, ///< double - SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec -}; - -/* Audio channel masks */ -#define CH_FRONT_LEFT 0x00000001 -#define CH_FRONT_RIGHT 0x00000002 -#define CH_FRONT_CENTER 0x00000004 -#define CH_LOW_FREQUENCY 0x00000008 -#define CH_BACK_LEFT 0x00000010 -#define CH_BACK_RIGHT 0x00000020 -#define CH_FRONT_LEFT_OF_CENTER 0x00000040 -#define CH_FRONT_RIGHT_OF_CENTER 0x00000080 -#define CH_BACK_CENTER 0x00000100 -#define CH_SIDE_LEFT 0x00000200 -#define CH_SIDE_RIGHT 0x00000400 -#define CH_TOP_CENTER 0x00000800 -#define CH_TOP_FRONT_LEFT 0x00001000 -#define CH_TOP_FRONT_CENTER 0x00002000 -#define CH_TOP_FRONT_RIGHT 0x00004000 -#define CH_TOP_BACK_LEFT 0x00008000 -#define CH_TOP_BACK_CENTER 0x00010000 -#define CH_TOP_BACK_RIGHT 0x00020000 -#define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. -#define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT. - -/** Channel mask value used for AVCodecContext.request_channel_layout - to indicate that the user requests the channel order of the decoder output - to be the native codec channel order. */ -#define CH_LAYOUT_NATIVE 0x8000000000000000LL - -/* Audio channel convenience macros */ -#define CH_LAYOUT_MONO (CH_FRONT_CENTER) -#define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT) -#define CH_LAYOUT_2_1 (CH_LAYOUT_STEREO|CH_BACK_CENTER) -#define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER) -#define CH_LAYOUT_4POINT0 (CH_LAYOUT_SURROUND|CH_BACK_CENTER) -#define CH_LAYOUT_2_2 (CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT) -#define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT) -#define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY) -#define CH_LAYOUT_5POINT0_BACK (CH_LAYOUT_SURROUND|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_5POINT1_BACK (CH_LAYOUT_5POINT0_BACK|CH_LOW_FREQUENCY) -#define CH_LAYOUT_7POINT0 (CH_LAYOUT_5POINT0|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_5POINT1_BACK|\ - CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER) -#define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT) - -/* 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. - */ -enum Motion_Est_ID { - ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed - ME_FULL, - ME_LOG, - ME_PHODS, - ME_EPZS, ///< enhanced predictive zonal search - ME_X1, ///< reserved for experiments - ME_HEX, ///< hexagon based search - ME_UMH, ///< uneven multi-hexagon search - ME_ITER, ///< iterative search - ME_TESA, ///< transformed exhaustive search algorithm -}; - -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 -}; - -enum AVColorPrimaries{ - AVCOL_PRI_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B - AVCOL_PRI_UNSPECIFIED=2, - AVCOL_PRI_BT470M =4, - AVCOL_PRI_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM - AVCOL_PRI_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC - AVCOL_PRI_SMPTE240M =7, ///< functionally identical to above - AVCOL_PRI_FILM =8, - AVCOL_PRI_NB , ///< Not part of ABI -}; - -enum AVColorTransferCharacteristic{ - AVCOL_TRC_BT709 =1, ///< also ITU-R BT1361 - AVCOL_TRC_UNSPECIFIED=2, - AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM - AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG - AVCOL_TRC_NB , ///< Not part of ABI -}; - -enum AVColorSpace{ - AVCOL_SPC_RGB =0, - AVCOL_SPC_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B - AVCOL_SPC_UNSPECIFIED=2, - AVCOL_SPC_FCC =4, - AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 - AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above - AVCOL_SPC_SMPTE240M =7, - AVCOL_SPC_NB , ///< Not part of ABI -}; - -enum AVColorRange{ - AVCOL_RANGE_UNSPECIFIED=0, - AVCOL_RANGE_MPEG =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges - AVCOL_RANGE_JPEG =2, ///< the normal 2^n-1 "JPEG" YUV ranges - AVCOL_RANGE_NB , ///< Not part of ABI -}; - -/** - * X X 3 4 X X are luma samples, - * 1 2 1-6 are possible chroma positions - * X X 5 6 X 0 is undefined/unknown position - */ -enum AVChromaLocation{ - AVCHROMA_LOC_UNSPECIFIED=0, - AVCHROMA_LOC_LEFT =1, ///< mpeg2/4, h264 default - AVCHROMA_LOC_CENTER =2, ///< mpeg1, jpeg, h263 - AVCHROMA_LOC_TOPLEFT =3, ///< DV - AVCHROMA_LOC_TOP =4, - AVCHROMA_LOC_BOTTOMLEFT =5, - AVCHROMA_LOC_BOTTOM =6, - AVCHROMA_LOC_NB , ///< Not part of ABI -}; - -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; - -#define FF_MAX_B_FRAMES 16 - -/* encoding support - These flags can be passed in AVCodecContext.flags before initialization. - 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 H.263. -#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. -/** - * The parent program guarantees that the input for B-frames containing - * streams is not written to for at least s->max_b_frames+1 frames, if - * this is not set 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_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_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 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 ///< H.263 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 one reference per partition, as opposed to one reference per macroblock -#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 -#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table. -#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). -#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. -#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping -#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. -#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer. -#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible -#define CODEC_FLAG2_MBTREE 0x00040000 ///< Use macroblock tree ratecontrol (x264 only) -#define CODEC_FLAG2_PSY 0x00080000 ///< Use psycho visual optimizations. -#define CODEC_FLAG2_SSIM 0x00100000 ///< Compute SSIM during encoding, error[] values are undefined. - -/* Unsupported options : - * Syntax Arithmetic coding (SAC) - * Reference Picture Selection - * Independent 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 and supports custom allocators. - * If not set, it might not use get_buffer() at all or use operations that - * assume the buffer was allocated by avcodec_default_get_buffer. - */ -#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 nonzero delay and needs to be fed with NULL at the end to get the delayed data. - * If this is not set, the codec is guaranteed to never be fed with NULL data. - */ -#define CODEC_CAP_DELAY 0x0020 -/** - * Codec can be fed a final frame with a smaller size. - * This can be used to prevent truncation of the last audio samples. - */ -#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 -/** - * Codec can export data for HW decoding (VDPAU). - */ -#define CODEC_CAP_HWACCEL_VDPAU 0x0080 -/** - * Codec can output multiple frames per AVPacket - * Normally demuxers return one frame at a time, demuxers which do not do - * are connected to a parser to split what they return into proper frames. - * This flag is reserved to the very rare category of codecs which have a - * bitstream that cannot be split into frames without timeconsuming - * operations like full decoding. Demuxers carring such bitstreams thus - * may return multiple frames in a packet. This has many disadvantages like - * prohibiting stream copy in many cases thus it should only be considered - * as a last resort. - */ -#define CODEC_CAP_SUBFRAMES 0x0100 -/** - * Codec is experimental and is thus avoided in favor of non experimental - * encoders - */ -#define CODEC_CAP_EXPERIMENTAL 0x0200 - -//The following defines may change, don't expect compatibility if you use them. -#define MB_TYPE_INTRA4x4 0x0001 -#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific -#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-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 libavcodec. - */ - int id; - - /** - * width and height in 1/16 pel - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - 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 libavcodec. - */ - 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 libavcodec unless the default get/release_buffer() is used.\ - * - encoding: \ - * - decoding: \ - */\ - uint8_t *base[4];\ - /**\ - * 1 -> keyframe, 0-> not\ - * - encoding: Set by libavcodec.\ - * - decoding: Set by libavcodec.\ - */\ - int key_frame;\ -\ - /**\ - * Picture type of the frame, see ?_TYPE below.\ - * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ - * - decoding: Set by libavcodec.\ - */\ - 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 libavcodec.\ - */\ - int64_t pts;\ -\ - /**\ - * picture number in bitstream order\ - * - encoding: set by\ - * - decoding: Set by libavcodec.\ - */\ - int coded_picture_number;\ - /**\ - * picture number in display order\ - * - encoding: set by\ - * - decoding: Set by libavcodec.\ - */\ - int display_picture_number;\ -\ - /**\ - * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ - * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ - * - decoding: Set by libavcodec.\ - */\ - 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\ - * The values for this are the same as the MpegEncContext.picture_structure\ - * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\ - * Set to 4 for delayed, non-reference frames.\ - * - encoding: unused\ - * - decoding: Set by libavcodec. (before get_buffer() call)).\ - */\ - int reference;\ -\ - /**\ - * QP table\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - int8_t *qscale_table;\ - /**\ - * QP store stride\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - int qstride;\ -\ - /**\ - * mbskip_table[mb]>=1 if MB didn't change\ - * stride= mb_width = (width+15)>>4\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - 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 libavcodec.\ - */\ - int16_t (*motion_val[2])[2];\ -\ - /**\ - * macroblock type table\ - * mb_type_base + mb_width + 2\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - 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 libavcodec.\ - */\ - uint8_t motion_subsample_log2;\ -\ - /**\ - * for some private data of the user\ - * - encoding: unused\ - * - decoding: Set by user.\ - */\ - void *opaque;\ -\ - /* - * dummy variable for tizen in Windows. - */\ - int dummy_a;\ -\ - /**\ - * error\ - * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\ - * - decoding: unused\ - */\ - uint64_t error[4];\ -\ - /**\ - * type of the buffer (to keep track of who has to deallocate data[*])\ - * - encoding: Set by the one who allocates it.\ - * - decoding: Set by the one who allocates it.\ - * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\ - */\ - int type;\ - \ - /**\ - * When decoding, this signals how much the picture must be delayed.\ - * extra_delay = repeat_pict / (2*fps)\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - int repeat_pict;\ - \ - /**\ - * \ - */\ - int qscale_type;\ - \ - /**\ - * The content of the picture is interlaced.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec. (default 0)\ - */\ - int interlaced_frame;\ - \ - /**\ - * If the content is interlaced, is top field displayed first.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - int top_field_first;\ - \ - /**\ - * Pan scan.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - AVPanScan *pan_scan;\ - \ - /**\ - * Tell user application that palette has changed from previous frame.\ - * - encoding: ??? (no palette-enabled encoder yet)\ - * - decoding: Set by libavcodec. (default 0).\ - */\ - int palette_has_changed;\ - \ - /**\ - * codec suggestion on buffer type if != 0\ - * - encoding: unused\ - * - decoding: Set by libavcodec. (before get_buffer() call)).\ - */\ - int buffer_hints;\ -\ - /**\ - * DCT coefficients\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - short *dct_coeff;\ -\ - /**\ - * motion reference frame index\ - * the order in which these are stored can depend on the codec.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - int8_t *ref_index[2];\ -\ - /* - * dummy variable for tizen in Windows. - */\ - int dummy_b;\ -\ - /**\ - * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\ - * output in AVFrame.reordered_opaque\ - * - encoding: unused\ - * - decoding: Read by user.\ - */\ - int64_t reordered_opaque;\ -\ - /**\ - * hardware accelerator private data (FFmpeg allocated)\ - * - encoding: unused\ - * - decoding: Set by libavcodec\ - */\ - void *hwaccel_picture_private;\ -\ - /* - * dummy variable for tizen in Windows. - */\ - int dummy_c;\ - - -#define FF_QSCALE_TYPE_MPEG1 0 -#define FF_QSCALE_TYPE_MPEG2 1 -#define FF_QSCALE_TYPE_H264 2 -#define FF_QSCALE_TYPE_VP56 3 - -#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 deallocate 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 deallocate 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 ///< Switching Intra -#define FF_SP_TYPE 6 ///< Switching Predicted -#define FF_BI_TYPE 7 - -#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). - -typedef struct AVPacket { - /** - * Presentation timestamp in AVStream->time_base units; the time at which - * the decompressed packet will be presented to the user. - * Can be AV_NOPTS_VALUE if it is not stored in the file. - * pts MUST be larger or equal to dts as presentation cannot happen before - * decompression, unless one wants to view hex dumps. Some formats misuse - * the terms dts and pts/cts to mean something different. Such timestamps - * must be converted to true pts/dts before they are stored in AVPacket. - */ - int64_t pts; - /** - * Decompression timestamp in AVStream->time_base units; the time at which - * the packet is decompressed. - * Can be AV_NOPTS_VALUE if it is not stored in the file. - */ - int64_t dts; - uint8_t *data; - int size; - int stream_index; - int flags; - /** - * Duration of this packet in AVStream->time_base units, 0 if unknown. - * Equals next_pts - this_pts in presentation order. - */ - int duration; - void (*destruct)(struct AVPacket *); - void *priv; - int64_t pos; ///< byte position in stream, -1 if unknown - /* because of tizen */ - int is_mux; - - /** - * Time difference in AVStream->time_base units from the pts of this - * packet to the point at which the output from the decoder has converged - * independent from the availability of previous frames. That is, the - * frames are virtually identical no matter if decoding started from - * the very first frame or from this keyframe. - * Is AV_NOPTS_VALUE if unknown. - * This field is not the display duration of the current packet. - * - * The purpose of this field is to allow seeking in streams that have no - * keyframes in the conventional sense. It corresponds to the - * recovery point SEI in H.264 and match_time_delta in NUT. It is also - * essential for some types of subtitle streams to ensure that all - * subtitles are correctly displayed after seeking. - */ - int64_t convergence_duration; -} AVPacket; -#define AV_PKT_FLAG_KEY 0x0001 -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define PKT_FLAG_KEY AV_PKT_FLAG_KEY -#endif - -/** - * Audio Video Frame. - * New fields can be added to the end of FF_COMMON_FRAME with minor version - * bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. No fields should be added into AVFrame before or after - * FF_COMMON_FRAME! - * sizeof(AVFrame) must not be used outside libav*. - */ -typedef struct AVFrame { - FF_COMMON_FRAME -} AVFrame; - -/** - * main external API structure. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVCodecContext) must not be used outside libav*. - */ -typedef struct AVCodecContext { - /** - * information on struct for av_log - * - set by avcodec_alloc_context - */ - const AVClass *av_class; - /** - * the average bitrate - * - encoding: Set by user; unused for constant quantizer encoding. - * - decoding: Set by libavcodec. 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 need additional format info. It is stored here. - * If any muxer uses this then ALL demuxers/parsers AND encoders for the - * specific codec MUST set it correctly otherwise stream copy breaks. - * In general use of this field by muxers is not recommanded. - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. (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), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific] - * - encoding: MUST be set by user. - * - decoding: unused - */ - int me_method; - - /** - * some codecs need / can use extradata 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 - * than extradata_size to avoid prolems if it is read with the bitstream reader. - * The bytewise contents of extradata must not depend on the architecture or CPU endianness. - * - encoding: Set/allocated/freed by libavcodec. - * - decoding: Set/allocated/freed by user. - */ - uint8_t *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 libavcodec. - */ - AVRational time_base; - - /* video only */ - /** - * picture width / height. - * - encoding: MUST be set by user. - * - decoding: Set by libavcodec. - * Note: For compatibility it is 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 pictures, 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 libavcodec. - */ - enum PixelFormat pix_fmt; - - /** - * Frame rate emulation. If not zero, the 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 a horizontal band. It improves cache usage. Not - * all codecs can do that. You must check the codec capabilities - * beforehand. - * The function is also used by hardware acceleration APIs. - * It is called at least once during frame decoding to pass - * the data needed for hardware render. - * In that mode instead of pixel data, AVFrame points to - * a structure specific to the acceleration API. The application - * reads the structure and can change some fields to indicate progress - * or mark state. - * - 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 second - int channels; ///< number of audio channels - - /** - * audio sample format - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - enum SampleFormat sample_fmt; ///< sample format - - /* 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 - - /* add i_frame_number and stts_count because of tizen emulator */ - int i_frame_number; - int stts_count; - -#if LIBAVCODEC_VERSION_MAJOR < 53 - int real_pict_num; ///< Returns the real picture number of previous encoded frame. -#endif - - /** - * Number of frames the decoded output will be delayed relative to - * the encoded input. - * - encoding: Set by libavcodec. - * - 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 between 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 - * 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_factor; - - /** obsolete FIXME remove */ - int rc_strategy; -#define FF_RC_STRATEGY_XVID 1 - - int b_frame_strategy; - - /** - * hurry up amount - * - encoding: unused - * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header - * @deprecated Deprecated in favor of skip_idct and skip_frame. - */ - int hurry_up; - - struct AVCodec *codec; - - void *priv_data; - - int rtp_payload_size; /* The size of the RTP payload: the coder will */ - /* do its 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 transmitted RTP payload. */ - - - /* The RTP callback: This function is called */ - /* every time the encoder has a packet to send. */ - /* It 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 libavcodec. - * - 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 AVMediaType codec_type; /* see AVMEDIA_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 work around some encoder bugs. - * A demuxer should set this to what is stored in the field used to identify the codec. - * If there are multiple such fields in a container then the demuxer should choose the one - * which maximizes the information about the used codec. - * If the codec tag field in a container is larger then 32 bits then the demuxer should - * remap the longer ID to 32 bits with a table or other structure. Alternatively a new - * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated - * first. - * - encoding: Set by user, if not then the default based on codec_id will be used. - * - decoding: Set by user, will be converted to uppercase by libavcodec during init. - */ - unsigned int codec_tag; - - /** - * Work around 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 ///< Work around various bugs in Microsoft's broken decoders. -#define FF_BUG_TRUNCATED 16384 -//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%. - - /** - * luma single coefficient 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 standard (MPEG4, ...). - * - encoding: Set by user. - * - decoding: Set by user. - * Setting this to STRICT or higher means the encoder and decoder will - * generally do stupid things. While setting it to inofficial or lower - * will mean the encoder might use things that are not supported by all - * spec compliant decoders. Decoders make no difference between normal, - * inofficial and experimental, that is they always try to decode things - * when they can unless they are explicitly asked to behave stupid - * (=strictly conform to the specs) - */ - 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 nonstandardized experimental things. - - /** - * qscale offset between IP and B-frames - * - encoding: Set by user. - * - decoding: unused - */ - float b_quant_offset; - - /** - * Error recognization; higher values will detect more errors but may - * misdetect some more or less valid parts as errors. - * - encoding: unused - * - decoding: Set by user. - */ - int error_recognition; -#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 libavcodec. - * avcodec_align_dimensions2() should be used to find the required width and - * height, as they normally need to be rounded up to the next multiple of 16. - * if CODEC_CAP_DR1 is not set then get_buffer() must call - * avcodec_default_get_buffer() instead of providing buffers allocated by - * some other means. - * - encoding: unused - * - decoding: Set by libavcodec., user can override. - */ - int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); - - /** - * Called to release buffers which were 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 libavcodec., user can override. - */ - void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); - - /** - * Size of the frame reordering buffer in the decoder. - * For MPEG-2 it is 1 IPB or 0 low delay IP. - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. - */ - 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 libavcodec. - * - 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 - */ - const 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; - - /** - * 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 -#define FF_IDCT_CAVS 15 -#define FF_IDCT_SIMPLEARMV5TE 16 -#define FF_IDCT_SIMPLEARMV6 17 -#define FF_IDCT_SIMPLEVIS 18 -#define FF_IDCT_WMV2 19 -#define FF_IDCT_FAAN 20 -#define FF_IDCT_EA 21 -#define FF_IDCT_SIMPLENEON 22 -#define FF_IDCT_SIMPLEALPHA 23 -#define FF_IDCT_BINK 24 - - /** - * slice count - * - encoding: Set by libavcodec. - * - decoding: Set by user (or 0). - */ - int slice_count; - /** - * slice offsets in the frame in bytes - * - encoding: Set/allocated by libavcodec. - * - 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 the 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 */ -#define FF_MM_MMX 0x0001 ///< standard MMX -#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext -#endif -#define FF_MM_MMX2 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 -#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions -#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions -#define FF_MM_SSE4 0x0100 ///< Penryn SSE4.1 functions -#define FF_MM_SSE42 0x0200 ///< Nehalem SSE4.2 functions -#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT -#define FF_MM_ALTIVEC 0x0001 ///< standard AltiVec - - /** - * bits per sample/pixel from the demuxer (needed for huffyuv). - * - encoding: Set by libavcodec. - * - decoding: Set by user. - */ - int bits_per_coded_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) - * That is the width of a pixel divided by the height of the pixel. - * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - AVRational sample_aspect_ratio; - - /** - * the picture in the bitstream - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. - */ - 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 -#define FF_DEBUG_BUFFERS 0x00008000 - - /** - * 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 - - /* - * dummy variable for tizen in Windows. - */ - int dummy_a; - - /** - * error - * - encoding: Set by libavcodec 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 comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_cmp; - /** - * subpixel motion estimation comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_sub_cmp; - /** - * macroblock comparison function (not supported yet) - * - encoding: Set by user. - * - decoding: unused - */ - int mb_cmp; - /** - * interlaced DCT comparison 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; - - /** - * prepass for motion estimation - * - encoding: Set by user. - * - decoding: unused - */ - int pre_me; - - /** - * motion estimation prepass comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_pre_cmp; - - /** - * ME prepass 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, - * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. - * The first is always the native one. - * @return the chosen format - * - encoding: unused - * - decoding: Set by user, if not set the native format will be chosen. - */ - enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); - - /** - * DTG active format information (additional aspect ratio - * information only used in DVB MPEG-2 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. - * Tables have to be stored somewhere. FIXME - */ - int color_table_id; - - /** - * internal_buffer count - * Don't touch, used by libavcodec default_get_buffer(). - */ - int internal_buffer_count; - - /** - * internal_buffers - * Don't touch, used by libavcodec 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 work around some encoder bugs. - * - encoding: unused - * - decoding: Set by user, will be converted to uppercase by libavcodec 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. libavcodec won't check it. - * libavcodec 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(). - * if CODEC_CAP_DR1 is not set then reget_buffer() must call - * avcodec_default_reget_buffer() instead of providing buffers allocated by - * some other means. - * - encoding: unused - * - decoding: Set by libavcodec., 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 independent 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 independent 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 libavcodec, user can override. - * - decoding: Set by libavcodec, user can override. - */ - int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); - - /** - * 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 below 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 below 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 libavcodec. - */ - int profile; -#define FF_PROFILE_UNKNOWN -99 - -#define FF_PROFILE_AAC_MAIN 0 -#define FF_PROFILE_AAC_LOW 1 -#define FF_PROFILE_AAC_SSR 2 -#define FF_PROFILE_AAC_LTP 3 - -#define FF_PROFILE_H264_BASELINE 66 -#define FF_PROFILE_H264_MAIN 77 -#define FF_PROFILE_H264_EXTENDED 88 -#define FF_PROFILE_H264_HIGH 100 -#define FF_PROFILE_H264_HIGH_10 110 -#define FF_PROFILE_H264_HIGH_422 122 -#define FF_PROFILE_H264_HIGH_444 244 -#define FF_PROFILE_H264_CAVLC_444 44 - - /** - * level - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - 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; - - /** - * Bitstream 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 comparison 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 - */ - float 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: Set by lavc. - */ - 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 /* Analyze i4x4 */ -#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ -#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ -#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */ -#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */ - - /** - * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto) - * - encoding: Set by user. - * - decoding: unused - */ - int directpred; - - /** - * Audio cutoff bandwidth (0 means "automatic") - * - 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; - - /** - * - * Note: Value depends upon the compare function used for fullpel ME. - * - encoding: Set by user. - * - decoding: unused - */ - int mv0_threshold; - - /** - * Adjusts sensitivity of b_frame_strategy 1. - * - encoding: Set by user. - * - decoding: unused - */ - int b_sensitivity; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int compression_level; -#define FF_COMPRESSION_DEFAULT -1 - - /** - * Sets whether to use LPC mode - used by FLAC encoder. - * - encoding: Set by user. - * - decoding: unused - */ - int use_lpc; - - /** - * LPC coefficient precision - used by FLAC encoder - * - encoding: Set by user. - * - decoding: unused - */ - int lpc_coeff_precision; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int min_prediction_order; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int max_prediction_order; - - /** - * search method for selecting prediction order - * - encoding: Set by user. - * - decoding: unused - */ - int prediction_order_method; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int min_partition_order; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int max_partition_order; - - /** - * GOP timecode frame start number, in non drop frame format - * - encoding: Set by user. - * - decoding: unused - */ - int64_t timecode_frame_start; - -#if LIBAVCODEC_VERSION_MAJOR < 53 - /** - * Decoder should decode to this many channels if it can (0 for default) - * - encoding: unused - * - decoding: Set by user. - * @deprecated Deprecated in favor of request_channel_layout. - */ - int request_channels; -#endif - - /** - * Percentage of dynamic range compression to be applied by the decoder. - * The default value is 1.0, corresponding to full compression. - * - encoding: unused - * - decoding: Set by user. - */ - float drc_scale; - - /** - * opaque 64bit number (generally a PTS) that will be reordered and - * output in AVFrame.reordered_opaque - * - encoding: unused - * - decoding: Set by user. - */ - int64_t reordered_opaque; - - /** - * Bits per sample/pixel of internal libavcodec pixel/sample format. - * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. - * - encoding: set by user. - * - decoding: set by libavcodec. - */ - int bits_per_raw_sample; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_b; - - /** - * Audio channel layout. - * - encoding: set by user. - * - decoding: set by libavcodec. - */ - int64_t channel_layout; - - /** - * Request decoder to use this channel layout if it can (0 for default) - * - encoding: unused - * - decoding: Set by user. - */ - int64_t request_channel_layout; - - /** - * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. - * - encoding: Set by user. - * - decoding: unused. - */ - float rc_max_available_vbv_use; - - /** - * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. - * - encoding: Set by user. - * - decoding: unused. - */ - float rc_min_vbv_overflow_use; - - /** - * Hardware accelerator in use - * - encoding: unused. - * - decoding: Set by libavcodec - */ - struct AVHWAccel *hwaccel; - - /** - * For some codecs, the time base is closer to the field rate than the frame rate. - * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration - * if no telecine is used ... - * - * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. - */ - int ticks_per_frame; - - /** - * Hardware accelerator context. - * For some hardware accelerators, a global context needs to be - * provided by the user. In that case, this holds display-dependent - * data FFmpeg cannot instantiate itself. Please refer to the - * FFmpeg HW accelerator documentation to know how to fill this - * is. e.g. for VA API, this is a struct vaapi_context. - * - encoding: unused - * - decoding: Set by user - */ - void *hwaccel_context; - - /** - * Chromaticity coordinates of the source primaries. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorPrimaries color_primaries; - - /** - * Color Transfer Characteristic. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorTransferCharacteristic color_trc; - - /** - * YUV colorspace type. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorSpace colorspace; - - /** - * MPEG vs JPEG YUV range. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorRange color_range; - - /** - * This defines the location of chroma samples. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVChromaLocation chroma_sample_location; - - /** - * The codec may call this to execute several independent 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. - * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. - * @param c context passed also to func - * @param count the number of things to execute - * @param arg2 argument passed unchanged to func - * @param ret return values of executed functions, must have space for "count" values. May be NULL. - * @param func function that will be called count times, with jobnr from 0 to count-1. - * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no - * two instances of func executing at the same time will have the same threadnr. - * @return always 0 currently, but code should handle a future improvement where when any call to func - * returns < 0 no further calls to func may be done and < 0 is returned. - * - encoding: Set by libavcodec, user can override. - * - decoding: Set by libavcodec, user can override. - */ - int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); - - /** - * explicit P-frame weighted prediction analysis method - * 0: off - * 1: fast blind weighting (one reference duplicate with -1 offset) - * 2: smart weighting (full fade detection analysis) - * - encoding: Set by user. - * - decoding: unused - */ - int weighted_p_pred; - - /** - * AQ mode - * 0: Disabled - * 1: Variance AQ (complexity mask) - * 2: Auto-variance AQ (experimental) - * - encoding: Set by user - * - decoding: unused - */ - int aq_mode; - - /** - * AQ strength - * Reduces blocking and blurring in flat and textured areas. - * - encoding: Set by user - * - decoding: unused - */ - float aq_strength; - - /** - * PSY RD - * Strength of psychovisual optimization - * - encoding: Set by user - * - decoding: unused - */ - float psy_rd; - - /** - * PSY trellis - * Strength of psychovisual optimization - * - encoding: Set by user - * - decoding: unused - */ - float psy_trellis; - - /** - * RC lookahead - * Number of frames for frametype and ratecontrol lookahead - * - encoding: Set by user - * - decoding: unused - */ - int rc_lookahead; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_c; -} AVCodecContext; - -/** - * AVCodec. - */ -typedef struct AVCodec { - /** - * Name of the codec implementation. - * The name is globally unique among encoders and among decoders (but an - * encoder and a decoder can share the same name). - * This is the primary way to find a codec from the user perspective. - */ - const char *name; - enum AVMediaType 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, AVPacket *avpkt); - /** - * Codec capabilities. - * see CODEC_CAP_* - */ - int capabilities; - struct AVCodec *next; - /** - * Flush buffers. - * Will be called when seeking - */ - 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 terminated by -1 - /** - * Descriptive name for the codec, meant to be more human readable than name. - * You should use the NULL_IF_CONFIG_SMALL() macro to define it. - */ - const char *long_name; - const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 - const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 - const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 -} AVCodec; - -/** - * AVHWAccel. - */ -typedef struct AVHWAccel { - /** - * Name of the hardware accelerated codec. - * The name is globally unique among encoders and among decoders (but an - * encoder and a decoder can share the same name). - */ - const char *name; - - /** - * Type of codec implemented by the hardware accelerator. - * - * See AVMEDIA_TYPE_xxx - */ - enum AVMediaType type; - - /** - * Codec implemented by the hardware accelerator. - * - * See CODEC_ID_xxx - */ - enum CodecID id; - - /** - * Supported pixel format. - * - * Only hardware accelerated formats are supported here. - */ - enum PixelFormat pix_fmt; - - /** - * Hardware accelerated codec capabilities. - * see FF_HWACCEL_CODEC_CAP_* - */ - int capabilities; - - struct AVHWAccel *next; - - /** - * Called at the beginning of each frame or field picture. - * - * Meaningful frame information (codec specific) is guaranteed to - * be parsed at this point. This function is mandatory. - * - * Note that buf can be NULL along with buf_size set to 0. - * Otherwise, this means the whole frame is available at this point. - * - * @param avctx the codec context - * @param buf the frame data buffer base - * @param buf_size the size of the frame in bytes - * @return zero if successful, a negative value otherwise - */ - int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); - - /** - * Callback for each slice. - * - * Meaningful slice information (codec specific) is guaranteed to - * be parsed at this point. This function is mandatory. - * - * @param avctx the codec context - * @param buf the slice data buffer base - * @param buf_size the size of the slice in bytes - * @return zero if successful, a negative value otherwise - */ - int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); - - /** - * Called at the end of each frame or field picture. - * - * The whole picture is parsed at this point and can now be sent - * to the hardware accelerator. This function is mandatory. - * - * @param avctx the codec context - * @return zero if successful, a negative value otherwise - */ - int (*end_frame)(AVCodecContext *avctx); - - /** - * Size of HW accelerator private data. - * - * Private data is allocated with av_mallocz() before - * AVCodecContext.get_buffer() and deallocated after - * AVCodecContext.release_buffer(). - */ - int priv_data_size; -} AVHWAccel; - -/** - * 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; - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * AVPaletteControl - * This structure defines a method for communicating palette changes - * between and demuxer and a decoder. - * - * @deprecated Use AVPacket to send palette changes instead. - * This is totally broken. - */ -#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 an IBM VGA native format, the component - * data is probably 6 bits in size and needs to be scaled. */ - unsigned int palette[AVPALETTE_COUNT]; - -} AVPaletteControl attribute_deprecated; -#endif - -enum AVSubtitleType { - SUBTITLE_NONE, - - SUBTITLE_BITMAP, ///< A bitmap, pict will be set - - /** - * Plain text, the text field must be set by the decoder and is - * authoritative. ass and pict fields may contain approximations. - */ - SUBTITLE_TEXT, - - /** - * Formatted text, the ass field must be set by the decoder and is - * authoritative. pict and text fields may contain approximations. - */ - SUBTITLE_ASS, -}; - -typedef struct AVSubtitleRect { - int x; ///< top left corner of pict, undefined when pict is not set - int y; ///< top left corner of pict, undefined when pict is not set - int w; ///< width of pict, undefined when pict is not set - int h; ///< height of pict, undefined when pict is not set - int nb_colors; ///< number of colors in pict, undefined when pict is not set - - /** - * data+linesize for the bitmap of this subtitle. - * can be set for text/ass as well once they where rendered - */ - AVPicture pict; - enum AVSubtitleType type; - - char *text; ///< 0 terminated plain UTF-8 text - - /** - * 0 terminated ASS/SSA compatible event line. - * The pressentation of this is unaffected by the other values in this - * struct. - */ - char *ass; -} 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 */ - unsigned num_rects; - AVSubtitleRect **rects; - int64_t pts; ///< Same as packet pts, in AV_TIME_BASE -} AVSubtitle; - -/* packet functions */ - -/** - * @deprecated use NULL instead - */ -attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt); - -/** - * Default packet destructor. - */ -void av_destruct_packet(AVPacket *pkt); - -/** - * Initialize optional fields of a packet with default values. - * - * @param pkt packet - */ -void av_init_packet(AVPacket *pkt); - -/** - * Allocate the payload of a packet and initialize its fields with - * default values. - * - * @param pkt packet - * @param size wanted payload size - * @return 0 if OK, AVERROR_xxx otherwise - */ -int av_new_packet(AVPacket *pkt, int size); - -/** - * Reduce packet size, correctly zeroing padding - * - * @param pkt packet - * @param size new size - */ -void av_shrink_packet(AVPacket *pkt, int size); - -/** - * @warning This is a hack - the packet memory allocation stuff is broken. The - * packet is allocated if it was not really allocated. - */ -int av_dup_packet(AVPacket *pkt); - -/** - * Free a packet. - * - * @param pkt packet to free - */ -void av_free_packet(AVPacket *pkt); - -/* resample.c */ - -struct ReSampleContext; -struct AVResampleContext; - -typedef struct ReSampleContext ReSampleContext; - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * @deprecated Use av_audio_resample_init() instead. - */ -attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels, - int output_rate, int input_rate); -#endif -/** - * Initializes audio resampling context - * - * @param output_channels number of output channels - * @param input_channels number of input channels - * @param output_rate output sample rate - * @param input_rate input sample rate - * @param sample_fmt_out requested output sample format - * @param sample_fmt_in input sample format - * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq - * @param log2_phase_count log2 of the number of entries in the polyphase filterbank - * @param linear If 1 then the used FIR filter will be linearly interpolated - between the 2 closest, if 0 the closest will be used - * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate - * @return allocated ReSampleContext, NULL if error occured - */ -ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, - int output_rate, int input_rate, - enum SampleFormat sample_fmt_out, - enum SampleFormat sample_fmt_in, - int filter_length, int log2_phase_count, - int linear, double cutoff); - -int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); -void audio_resample_close(ReSampleContext *s); - - -/** - * Initializes an audio resampler. - * Note, if either rate is not an integer then simply scale both rates up so they are. - * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq - * @param log2_phase_count log2 of the number of entries in the polyphase filterbank - * @param linear If 1 then the used FIR filter will be linearly interpolated - between the 2 closest, if 0 the closest will be used - * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate - */ -struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); - -/** - * resamples. - * @param src an array of unconsumed samples - * @param consumed the number of samples of src which have been consumed are returned here - * @param src_size the number of unconsumed samples available - * @param dst_size the amount of space in samples available in dst - * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context. - * @return the number of samples written in dst or -1 if an error occurred - */ -int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); - - -/** - * Compensates samplerate/timestamp drift. The compensation is done by changing - * the resampler parameters, so no audible clicks or similar distortions occur - * @param compensation_distance distance in output samples over which the compensation should be performed - * @param sample_delta number of output samples which should be output less - * - * example: av_resample_compensate(c, 10, 500) - * here instead of 510 samples only 500 samples would be output - * - * note, due to rounding the actual compensation might be slightly different, - * especially if the compensation_distance is large and the in_rate used during init is small - */ -void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); -void av_resample_close(struct AVResampleContext *c); - -/** - * 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 zero if successful, a negative value if not - */ -int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int height); - -/** - * Free a picture previously allocated by avpicture_alloc(). - * - * @param picture the AVPicture to be freed - */ -void avpicture_free(AVPicture *picture); - -/** - * Fill in the AVPicture fields. - * The fields of the given AVPicture are filled in by using the 'ptr' address - * which points to the image data buffer. Depending on the specified picture - * format, one or multiple image data pointers and line sizes will be set. - * If a planar format is specified, several pointers will be set pointing to - * the different picture planes and the line sizes of the different planes - * will be stored in the lines_sizes array. - * Call with ptr == NULL to get the required size for the ptr buffer. - * - * @param picture AVPicture whose fields are to be filled in - * @param ptr Buffer which will contain or contains the actual image data - * @param pix_fmt The format in which the picture data is stored. - * @param width the width of the image in pixels - * @param height the height of the image in pixels - * @return size of the image data in bytes - */ -int avpicture_fill(AVPicture *picture, uint8_t *ptr, - enum PixelFormat pix_fmt, int width, int height); -int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, - unsigned char *dest, int dest_size); - -/** - * Calculate the size in bytes that a picture of the given width and height - * would occupy if stored in the given picture format. - * Note that this returns the size of a compact representation as generated - * by avpicture_layout, which can be smaller than the size required for e.g. - * avpicture_fill. - * - * @param pix_fmt the given picture format - * @param width the width of the image - * @param height the height of the image - * @return Image data size in bytes or -1 on error (e.g. too large dimensions). - */ -int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height); -void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift); -const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt); -void avcodec_set_dimensions(AVCodecContext *s, int width, int height); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * Returns the pixel format corresponding to the name name. - * - * If there is no pixel format with name name, then looks for a - * pixel format with the name corresponding to the native endian - * format of name. - * For example in a little-endian system, first looks for "gray16", - * then for "gray16le". - * - * Finally if no pixel format has been found, returns PIX_FMT_NONE. - * - * @deprecated Deprecated in favor of av_get_pix_fmt(). - */ -attribute_deprecated enum PixelFormat avcodec_get_pix_fmt(const char* name); -#endif - -/** - * Returns a value representing the fourCC code associated to the - * pixel format pix_fmt, or 0 if no associated fourCC code can be - * found. - */ -unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat pix_fmt); - -#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) */ - -/** - * Computes what kind of losses will occur when converting from one specific - * pixel format to another. - * When converting from one pixel format to another, information loss may occur. - * For example, when converting from RGB24 to GRAY, the color information will - * be lost. Similarly, other losses occur when converting from some formats to - * other formats. These losses can involve loss of chroma, but also loss of - * resolution, loss of color depth, loss due to the color space conversion, loss - * of the alpha bits or loss due to color quantization. - * avcodec_get_fix_fmt_loss() informs you about the various types of losses - * which will occur when converting from one pixel format to another. - * - * @param[in] dst_pix_fmt destination pixel format - * @param[in] src_pix_fmt source pixel format - * @param[in] has_alpha Whether the source pixel format alpha channel is used. - * @return Combination of flags informing you what kind of losses will occur. - */ -int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, - int has_alpha); - -/** - * Finds the best pixel format to convert to given a certain source pixel - * format. When converting from one pixel format to another, information loss - * may occur. For example, when converting from RGB24 to GRAY, the color - * information will be lost. Similarly, other losses occur when converting from - * some formats to other formats. avcodec_find_best_pix_fmt() searches which of - * the given pixel formats should be used to suffer the least amount of loss. - * The pixel formats from which it chooses one, are determined by the - * pix_fmt_mask parameter. - * - * @code - * src_pix_fmt = PIX_FMT_YUV420P; - * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24); - * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); - * @endcode - * - * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from - * @param[in] src_pix_fmt source pixel format - * @param[in] has_alpha Whether the source pixel format alpha channel is used. - * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. - * @return The best pixel format to convert to or -1 if none was found. - */ -enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, - int has_alpha, int *loss_ptr); - - -/** - * Print in buf the string corresponding to the pixel format with - * number pix_fmt, or an header if pix_fmt is negative. - * - * @param[in] buf the buffer where to write the string - * @param[in] buf_size the size of buf - * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or - * a negative value to print the corresponding header. - * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1. - */ -void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt); - -#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ -#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ - -/** - * 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, - enum PixelFormat pix_fmt, int width, int height); - -/* deinterlace a picture */ -/* deinterlace - if not supported return -1 */ -int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height); - -/* external high level API */ - -/** - * If c is NULL, returns the first registered codec, - * if c is non-NULL, returns the next registered codec after c, - * or NULL if c is the last one. - */ -AVCodec *av_codec_next(AVCodec *c); - -/** - * Returns the LIBAVCODEC_VERSION_INT constant. - */ -unsigned avcodec_version(void); - -/** - * Returns the libavcodec build-time configuration. - */ -const char *avcodec_configuration(void); - -/** - * Returns the libavcodec license. - */ -const char *avcodec_license(void); - -/** - * Initializes libavcodec. - * - * @warning This function must be called before any other libavcodec - * function. - */ -void avcodec_init(void); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * @deprecated Deprecated in favor of avcodec_register(). - */ -attribute_deprecated void register_avcodec(AVCodec *codec); -#endif - -/** - * Register the codec codec and initialize libavcodec. - * - * @see avcodec_init() - */ -void avcodec_register(AVCodec *codec); - -/** - * Finds a registered encoder with a matching codec ID. - * - * @param id CodecID of the requested encoder - * @return An encoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_encoder(enum CodecID id); - -/** - * Finds a registered encoder with the specified name. - * - * @param name name of the requested encoder - * @return An encoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_encoder_by_name(const char *name); - -/** - * Finds a registered decoder with a matching codec ID. - * - * @param id CodecID of the requested decoder - * @return A decoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_decoder(enum CodecID id); - -/** - * Finds a registered decoder with the specified name. - * - * @param name name of the requested decoder - * @return A decoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_decoder_by_name(const char *name); -void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); - -/** - * Sets the fields of the given AVCodecContext to default values. - * - * @param s The AVCodecContext of which the fields should be set to default values. - */ -void avcodec_get_context_defaults(AVCodecContext *s); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); - -/** - * Allocates an AVCodecContext and sets its fields to default values. The - * resulting struct can be deallocated by simply calling av_free(). - * - * @return An AVCodecContext filled with default values or NULL on failure. - * @see avcodec_get_context_defaults - */ -AVCodecContext *avcodec_alloc_context(void); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -AVCodecContext *avcodec_alloc_context2(enum AVMediaType); - -/** - * Copy the settings of the source AVCodecContext into the destination - * AVCodecContext. The resulting destination codec context will be - * unopened, i.e. you are required to call avcodec_open() before you - * can use this AVCodecContext to decode/encode video/audio data. - * - * @param dest target codec context, should be initialized with - * avcodec_alloc_context(), but otherwise uninitialized - * @param src source codec context - * @return AVERROR() on error (e.g. memory allocation error), 0 on success - */ -int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); - -/** - * Sets the fields of the given AVFrame to default values. - * - * @param pic The AVFrame of which the fields should be set to default values. - */ -void avcodec_get_frame_defaults(AVFrame *pic); - -/** - * Allocates an AVFrame and sets its fields to default values. The resulting - * struct can be deallocated by simply calling av_free(). - * - * @return An AVFrame filled with default values or NULL on failure. - * @see avcodec_get_frame_defaults - */ -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); - -/** - * Returns the amount of padding in pixels which the get_buffer callback must - * provide around the edge of the image for codecs which do not have the - * CODEC_FLAG_EMU_EDGE flag. - * - * @return Required padding in pixels. - */ -unsigned avcodec_get_edge_width(void); -/** - * Modifies width and height values so that they will result in a memory - * buffer that is acceptable for the codec if you do not use any horizontal - * padding. - * - * May only be used if a codec with CODEC_CAP_DR1 has been opened. - * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased - * according to avcodec_get_edge_width() before. - */ -void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); -/** - * Modifies width and height values so that they will result in a memory - * buffer that is acceptable for the codec if you also ensure that all - * line sizes are a multiple of the respective linesize_align[i]. - * - * May only be used if a codec with CODEC_CAP_DR1 has been opened. - * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased - * according to avcodec_get_edge_width() before. - */ -void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, - int linesize_align[4]); - -/** - * Checks if the given dimension of a picture is valid, meaning that all - * bytes of the picture can be addressed with a signed int. - * - * @param[in] w Width of the picture. - * @param[in] h Height of the picture. - * @return Zero if valid, a negative value if invalid. - */ -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_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); -int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); -//FIXME func typedef - -/** - * Initializes the AVCodecContext to use the given AVCodec. Prior to using this - * function the context has to be allocated. - * - * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), - * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for - * retrieving a codec. - * - * @warning This function is not thread safe! - * - * @code - * avcodec_register_all(); - * codec = avcodec_find_decoder(CODEC_ID_H264); - * if (!codec) - * exit(1); - * - * context = avcodec_alloc_context(); - * - * if (avcodec_open(context, codec) < 0) - * exit(1); - * @endcode - * - * @param avctx The context which will be set up to use the given codec. - * @param codec The codec to use within the context. - * @return zero on success, a negative value on error - * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder - */ -int avcodec_open(AVCodecContext *avctx, AVCodec *codec); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * Decodes an audio frame from buf into samples. - * Wrapper function which calls avcodec_decode_audio3. - * - * @deprecated Use avcodec_decode_audio3 instead. - * @param avctx the codec context - * @param[out] samples the output buffer - * @param[in,out] frame_size_ptr the output buffer size in bytes - * @param[in] buf the input buffer - * @param[in] buf_size the input buffer size in bytes - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. - */ -attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - const uint8_t *buf, int buf_size); -#endif - -/** - * Decodes the audio frame of size avpkt->size from avpkt->data into samples. - * Some decoders may support multiple frames in a single AVPacket, such - * decoders would then just decode the first frame. In this case, - * avcodec_decode_audio3 has to be called again with an AVPacket that contains - * the remaining data in order to decode the second frame etc. - * If no frame - * could be outputted, frame_size_ptr is zero. Otherwise, it is the - * decompressed frame size in bytes. - * - * @warning You must set frame_size_ptr to the allocated size of the - * output buffer before calling avcodec_decode_audio3(). - * - * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than - * the actual read bytes because some optimized bitstream readers read 32 or 64 - * bits at once and could read over the end. - * - * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that - * no overreading happens for damaged MPEG streams. - * - * @note You might have to align the input buffer avpkt->data and output buffer - * samples. The alignment requirements depend on the CPU: On some CPUs it isn't - * necessary at all, on others it won't work at all if not aligned and on others - * it will work but it will have an impact on performance. - * - * In practice, avpkt->data should have 4 byte alignment at minimum and - * samples should be 16 byte aligned unless the CPU doesn't need it - * (AltiVec and SSE do). - * - * @param avctx the codec context - * @param[out] samples the output buffer, sample type in avctx->sample_fmt - * @param[in,out] frame_size_ptr the output buffer size in bytes - * @param[in] avpkt The input AVPacket containing the input buffer. - * You can create such packet with av_init_packet() and by then setting - * data and size, some decoders might in addition need other fields. - * All decoders are designed to use the least fields possible though. - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame data was decompressed (used) from the input AVPacket. - */ -int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - AVPacket *avpkt); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * Decodes a video frame from buf into picture. - * Wrapper function which calls avcodec_decode_video2. - * - * @deprecated Use avcodec_decode_video2 instead. - * @param avctx the codec context - * @param[out] picture The AVFrame in which the decoded video frame will be stored. - * @param[in] buf the input buffer - * @param[in] buf_size the size of the input buffer in bytes - * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. - */ -attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - const uint8_t *buf, int buf_size); -#endif - -/** - * Decodes the video frame of size avpkt->size from avpkt->data into picture. - * Some decoders may support multiple frames in a single AVPacket, such - * decoders would then just decode the first frame. - * - * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than - * the actual read bytes because some optimized bitstream readers read 32 or 64 - * bits at once and could read over the end. - * - * @warning The end of the input buffer buf should be set to 0 to ensure that - * no overreading happens for damaged MPEG streams. - * - * @note You might have to align the input buffer avpkt->data. - * The alignment requirements depend on the CPU: on some CPUs it isn't - * necessary at all, on others it won't work at all if not aligned and on others - * it will work but it will have an impact on performance. - * - * In practice, avpkt->data should have 4 byte alignment at minimum. - * - * @note Some codecs have a delay between input and output, these need to be - * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames. - * - * @param avctx the codec context - * @param[out] picture The AVFrame in which the decoded video frame will be stored. - * Use avcodec_alloc_frame to get an AVFrame, the codec will - * allocate memory for the actual bitmap. - * @param[in] avpkt The input AVpacket containing the input buffer. - * You can create such packet with av_init_packet() and by then setting - * data and size, some decoders might in addition need other fields like - * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least - * fields possible. - * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. - */ -int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - AVPacket *avpkt); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/* Decode a subtitle message. Return -1 if error, otherwise return the - * number of bytes used. If no subtitle could be decompressed, - * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ -attribute_deprecated int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - const uint8_t *buf, int buf_size); -#endif - -/** - * Decodes a subtitle message. - * Returns a negative value on error, otherwise returns the number of bytes used. - * If no subtitle could be decompressed, got_sub_ptr is zero. - * Otherwise, the subtitle is stored in *sub. - * - * @param avctx the codec context - * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored. - * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. - * @param[in] avpkt The input AVPacket containing the input buffer. - */ -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt); -int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, - int *data_size_ptr, - uint8_t *buf, int buf_size); - -/** - * Encodes an audio frame from samples into buf. - * - * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large. - * However, for PCM audio the user will know how much space is needed - * because it depends on the value passed in buf_size as described - * below. In that case a lower value can be used. - * - * @param avctx the codec context - * @param[out] buf the output buffer - * @param[in] buf_size the output buffer size - * @param[in] samples the input buffer containing the samples - * The number of samples read from this buffer is frame_size*channels, - * both of which are defined in avctx. - * For PCM audio the number of samples read from samples is equal to - * buf_size * input_sample_size / output_sample_size. - * @return On error a negative value is returned, on success zero or the number - * of bytes used to encode the data read from the input buffer. - */ -int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const short *samples); - -/** - * Encodes a video frame from pict into buf. - * The input picture should be - * stored using a specific format, namely avctx.pix_fmt. - * - * @param avctx the codec context - * @param[out] buf the output buffer for the bitstream of encoded frame - * @param[in] buf_size the size of the output buffer in bytes - * @param[in] pict the input picture to encode - * @return On error a negative value is returned, on success zero or the number - * of bytes used from the output buffer. - */ -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); - -/** - * Register all the codecs, parsers and bitstream filters which were enabled at - * configuration time. If you do not call this function you can select exactly - * which formats you want to support, by using the individual registration - * functions. - * - * @see avcodec_register - * @see av_register_codec_parser - * @see av_register_bitstream_filter - */ -void avcodec_register_all(void); - -/** - * Flush buffers, should be called when seeking or when switching to a different stream. - */ -void avcodec_flush_buffers(AVCodecContext *avctx); - -void avcodec_default_free_buffers(AVCodecContext *s); - -/* misc useful functions */ - -/** - * Returns a single letter to describe the given picture type pict_type. - * - * @param[in] pict_type the picture type - * @return A single character representing the picture type. - */ -char av_get_pict_type_char(int pict_type); - -/** - * Returns codec bits per sample. - * - * @param[in] codec_id the codec - * @return Number of bits per sample or zero if unknown for the given codec. - */ -int av_get_bits_per_sample(enum CodecID codec_id); - -/** - * Returns sample format bits per sample. - * - * @param[in] sample_fmt the sample format - * @return Number of bits per sample or zero if unknown for the given sample format. - */ -int av_get_bits_per_sample_format(enum SampleFormat sample_fmt); - -/* 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 next_frame_offset; /* offset of the next frame */ - /* video info */ - int pict_type; /* XXX: Put it back in AVCodecContext. */ - /** - * This field is used for proper frame duration computation in lavf. - * It signals, how much longer the frame duration of the current frame - * is compared to normal frame duration. - * - * frame_duration = (1 + repeat_pict) * time_base - * - * It is used by codecs like H.264 to display telecined material. - */ - 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 - - int64_t offset; ///< byte offset from starting packet start - - /* - * dummy variable for tizen in Windows. - */ - int dummy_a; - - int64_t cur_frame_end[AV_PARSER_PTS_NB]; - - /*! - * Set by parser to 1 for key frames and 0 for non-key frames. - * It is initialized to -1, so if the parser doesn't set this flag, - * old-style fallback using FF_I_TYPE picture type as key frames - * will be used. - */ - int key_frame; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_b; - - /** - * Time difference in stream time base units from the pts of this - * packet to the point at which the output from the decoder has converged - * independent from the availability of previous frames. That is, the - * frames are virtually identical no matter if decoding started from - * the very first frame or from this keyframe. - * Is AV_NOPTS_VALUE if unknown. - * This field is not the display duration of the current frame. - * - * The purpose of this field is to allow seeking in streams that have no - * keyframes in the conventional sense. It corresponds to the - * recovery point SEI in H.264 and match_time_delta in NUT. It is also - * essential for some types of subtitle streams to ensure that all - * subtitles are correctly displayed after seeking. - */ - int64_t convergence_duration; - - // Timestamp generation support: - /** - * Synchronization point for start of timestamp generation. - * - * Set to >0 for sync point, 0 for no sync point and <0 for undefined - * (default). - * - * For example, this corresponds to presence of H.264 buffering period - * SEI message. - */ - int dts_sync_point; - - /** - * Offset of the current timestamp against last timestamp sync point in - * units of AVCodecContext.time_base. - * - * Set to INT_MIN when dts_sync_point unused. Otherwise, it must - * contain a valid timestamp offset. - * - * Note that the timestamp of sync point has usually a nonzero - * dts_ref_dts_delta, which refers to the previous sync point. Offset of - * the next frame after timestamp sync point will be usually 1. - * - * For example, this corresponds to H.264 cpb_removal_delay. - */ - int dts_ref_dts_delta; - - /** - * Presentation delay of current frame in units of AVCodecContext.time_base. - * - * Set to INT_MIN when dts_sync_point unused. Otherwise, it must - * contain valid non-negative timestamp delta (presentation time of a frame - * must not lie in the past). - * - * This delay represents the difference between decoding and presentation - * time of the frame. - * - * For example, this corresponds to H.264 dpb_output_delay. - */ - int pts_dts_delta; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_c; - - /** - * Position of the packet in file. - * - * Analogous to cur_frame_pts/dts - */ - int64_t cur_frame_pos[AV_PARSER_PTS_NB]; - - /** - * Byte position of currently parsed frame in stream. - */ - int64_t pos; - - /** - * Previous frame byte position. - */ - int64_t last_pos; -} 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, - const 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; - -AVCodecParser *av_parser_next(AVCodecParser *c); - -void av_register_codec_parser(AVCodecParser *parser); -AVCodecParserContext *av_parser_init(int codec_id); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -attribute_deprecated -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); -#endif - -/** - * Parse a packet. - * - * @param s parser context. - * @param avctx codec context. - * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. - * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. - * @param buf input buffer. - * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output). - * @param pts input presentation timestamp. - * @param dts input decoding timestamp. - * @param pos input byte position in stream. - * @return the number of bytes of the input bitstream used. - * - * Example: - * @code - * while(in_len){ - * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, - * in_data, in_len, - * pts, dts, pos); - * in_data += len; - * in_len -= len; - * - * if(size) - * decode_frame(data, size); - * } - * @endcode - */ -int av_parser_parse2(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, - int64_t pts, int64_t dts, - int64_t pos); - -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); - - -typedef struct AVBitStreamFilterContext { - void *priv_data; - struct AVBitStreamFilter *filter; - AVCodecParserContext *parser; - struct AVBitStreamFilterContext *next; -} AVBitStreamFilterContext; - - -typedef struct AVBitStreamFilter { - const char *name; - int priv_data_size; - int (*filter)(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); - void (*close)(AVBitStreamFilterContext *bsfc); - struct AVBitStreamFilter *next; -} AVBitStreamFilter; - -void av_register_bitstream_filter(AVBitStreamFilter *bsf); -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); -int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); -void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); - -AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); - -/* memory */ - -/** - * Reallocates the given block if it is not large enough, otherwise it - * does nothing. - * - * @see av_realloc - */ -void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); - -/** - * Allocates a buffer, reusing the given one if large enough. - * - * Contrary to av_fast_realloc the current buffer contents might not be - * preserved and on error the old buffer is freed, thus no special - * handling to avoid memleaks is necessary. - * - * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer - * @param size size of the buffer *ptr points to - * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and - * *size 0 if an error occurred. - */ -void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size); - -/** - * Copy image 'src' to 'dst'. - */ -void av_picture_copy(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height); - -/** - * Crop image top and left side. - */ -int av_picture_crop(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int top_band, int left_band); - -/** - * Pad image. - */ -int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum PixelFormat pix_fmt, - int padtop, int padbottom, int padleft, int padright, int *color); - -/** - * Encodes extradata length to a buffer. Used by xiph codecs. - * - * @param s buffer to write to; must be at least (v/255+1) bytes long - * @param v size of extradata in bytes - * @return number of bytes written to the buffer. - */ -unsigned int av_xiphlacing(unsigned char *s, unsigned int v); - -/** - * Parses str and put in width_ptr and height_ptr the detected values. - * - * @return 0 in case of a successful parsing, a negative value otherwise - * @param[in] str the string to parse: it has to be a string in the format - * x or a valid video frame size abbreviation. - * @param[in,out] width_ptr pointer to the variable which will contain the detected - * frame width value - * @param[in,out] height_ptr pointer to the variable which will contain the detected - * frame height value - */ -int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); - -/** - * Parses str and put in frame_rate the detected values. - * - * @return 0 in case of a successful parsing, a negative value otherwise - * @param[in] str the string to parse: it has to be a string in the format - * /, a float number or a valid video rate abbreviation - * @param[in,out] frame_rate pointer to the AVRational which will contain the detected - * frame rate - */ -int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); - -/** - * Logs a generic warning message about a missing feature. This function is - * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) - * only, and would normally not be used by applications. - * @param[in] avc a pointer to an arbitrary struct of which the first field is - * a pointer to an AVClass struct - * @param[in] feature string containing the name of the missing feature - * @param[in] want_sample indicates if samples are wanted which exhibit this feature. - * If want_sample is non-zero, additional verbage will be added to the log - * message which tells the user how to report samples to the development - * mailing list. - */ -void av_log_missing_feature(void *avc, const char *feature, int want_sample); - -/** - * Logs a generic warning message asking for a sample. This function is - * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) - * only, and would normally not be used by applications. - * @param[in] avc a pointer to an arbitrary struct of which the first field is - * a pointer to an AVClass struct - * @param[in] msg string containing an optional message, or NULL if no message - */ -void av_log_ask_for_sample(void *avc, const char *msg); - -/** - * Registers the hardware accelerator hwaccel. - */ -void av_register_hwaccel(AVHWAccel *hwaccel); - -/** - * If hwaccel is NULL, returns the first registered hardware accelerator, - * if hwaccel is non-NULL, returns the next registered hardware accelerator - * after hwaccel, or NULL if hwaccel is the last one. - */ -AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel); - - -/** - * Lock operation used by lockmgr - */ -enum AVLockOp { - AV_LOCK_CREATE, ///< Create a mutex - AV_LOCK_OBTAIN, ///< Lock the mutex - AV_LOCK_RELEASE, ///< Unlock the mutex - AV_LOCK_DESTROY, ///< Free mutex resources -}; - -/** - * Register a user provided lock manager supporting the operations - * specified by AVLockOp. mutex points to a (void *) where the - * lockmgr should store/get a pointer to a user allocated mutex. It's - * NULL upon AV_LOCK_CREATE and != NULL for all other ops. - * - * @param cb User defined callback. Note: FFmpeg may invoke calls to this - * callback during the call to av_lockmgr_register(). - * Thus, the application must be prepared to handle that. - * If cb is set to NULL the lockmgr will be unregistered. - * Also note that during unregistration the previously registered - * lockmgr callback may also be invoked. - */ -int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); - -#endif /* AVCODEC_AVCODEC_H */ diff --git a/tizen/distrib/ffmpeg/include/libavcodec/avfft.h b/tizen/distrib/ffmpeg/include/libavcodec/avfft.h deleted file mode 100644 index 623f0a3..0000000 --- a/tizen/distrib/ffmpeg/include/libavcodec/avfft.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AVFFT_H -#define AVCODEC_AVFFT_H - -typedef float FFTSample; - -typedef struct FFTComplex { - FFTSample re, im; -} FFTComplex; - -typedef struct FFTContext FFTContext; - -/** - * Set up a complex FFT. - * @param nbits log2 of the length of the input array - * @param inverse if 0 perform the forward transform, if 1 perform the inverse - */ -FFTContext *av_fft_init(int nbits, int inverse); - -/** - * Do the permutation needed BEFORE calling ff_fft_calc(). - */ -void av_fft_permute(FFTContext *s, FFTComplex *z); - -/** - * Do a complex FFT with the parameters defined in av_fft_init(). The - * input data must be permuted before. No 1.0/sqrt(n) normalization is done. - */ -void av_fft_calc(FFTContext *s, FFTComplex *z); - -void av_fft_end(FFTContext *s); - -FFTContext *av_mdct_init(int nbits, int inverse, double scale); -void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); -void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input); -void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); -void av_mdct_end(FFTContext *s); - -/* Real Discrete Fourier Transform */ - -enum RDFTransformType { - DFT_R2C, - IDFT_C2R, - IDFT_R2C, - DFT_C2R, -}; - -typedef struct RDFTContext RDFTContext; - -/** - * Set up a real FFT. - * @param nbits log2 of the length of the input array - * @param trans the type of transform - */ -RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans); -void av_rdft_calc(RDFTContext *s, FFTSample *data); -void av_rdft_end(RDFTContext *s); - -/* Discrete Cosine Transform */ - -typedef struct DCTContext DCTContext; - -enum DCTTransformType { - DCT_II = 0, - DCT_III, - DCT_I, - DST_I, -}; - -/** - * Sets up DCT. - * @param nbits size of the input array: - * (1 << nbits) for DCT-II, DCT-III and DST-I - * (1 << nbits) + 1 for DCT-I - * - * @note the first element of the input of DST-I is ignored - */ -DCTContext *av_dct_init(int nbits, enum DCTTransformType type); -void av_dct_calc(DCTContext *s, FFTSample *data); -void av_dct_end (DCTContext *s); - -#endif /* AVCODEC_AVFFT_H */ diff --git a/tizen/distrib/ffmpeg/include/libavcodec/dxva2.h b/tizen/distrib/ffmpeg/include/libavcodec/dxva2.h deleted file mode 100644 index 5c5fe21..0000000 --- a/tizen/distrib/ffmpeg/include/libavcodec/dxva2.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * DXVA2 HW acceleration - * - * copyright (c) 2009 Laurent Aimar - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DXVA_H -#define AVCODEC_DXVA_H - -#include - -#include - -/** - * This structure is used to provides the necessary configurations and data - * to the DXVA2 FFmpeg HWAccel implementation. - * - * The application must make it available as AVCodecContext.hwaccel_context. - */ -struct dxva_context { - /** - * DXVA2 decoder object - */ - IDirectXVideoDecoder *decoder; - - /** - * DXVA2 configuration used to create the decoder - */ - const DXVA2_ConfigPictureDecode *cfg; - - /** - * The number of surface in the surface array - */ - unsigned surface_count; - - /** - * The array of Direct3D surfaces used to create the decoder - */ - LPDIRECT3DSURFACE9 *surface; - - /** - * A bit field configuring the workarounds needed for using the decoder - */ - uint64_t workaround; - - /** - * Private to the FFmpeg AVHWAccel implementation - */ - unsigned report_id; -}; - -#endif /* AVCODEC_DXVA_H */ diff --git a/tizen/distrib/ffmpeg/include/libavcodec/opt.h b/tizen/distrib/ffmpeg/include/libavcodec/opt.h deleted file mode 100644 index 55ca4ea..0000000 --- a/tizen/distrib/ffmpeg/include/libavcodec/opt.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * AVOptions - * copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_OPT_H -#define AVCODEC_OPT_H - -/** - * @file - * AVOptions - */ - -#include "libavutil/rational.h" -#include "avcodec.h" - -enum AVOptionType{ - FF_OPT_TYPE_FLAGS, - FF_OPT_TYPE_INT, - FF_OPT_TYPE_INT64, - FF_OPT_TYPE_DOUBLE, - FF_OPT_TYPE_FLOAT, - FF_OPT_TYPE_STRING, - FF_OPT_TYPE_RATIONAL, - FF_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length - FF_OPT_TYPE_CONST=128, -}; - -/** - * AVOption - */ -typedef struct AVOption { - const char *name; - - /** - * short English help text - * @todo What about other languages? - */ - const char *help; - - /** - * The offset relative to the context structure where the option - * value is stored. It should be 0 for named constants. - */ - int offset; - enum AVOptionType type; - - /** - * the default value for scalar options - */ - double default_val; - double min; ///< minimum valid value for the option - double max; ///< maximum valid value for the option - - int flags; -#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding -#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding -#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... -#define AV_OPT_FLAG_AUDIO_PARAM 8 -#define AV_OPT_FLAG_VIDEO_PARAM 16 -#define AV_OPT_FLAG_SUBTITLE_PARAM 32 -//FIXME think about enc-audio, ... style flags - - /** - * The logical unit to which the option belongs. Non-constant - * options and corresponding named constants share the same - * unit. May be NULL. - */ - const char *unit; -} AVOption; - -/** - * AVOption2. - * THIS IS NOT PART OF THE API/ABI YET! - * This is identical to AVOption except that default_val was replaced by - * an union, it should be compatible with AVOption on normal platforms. - */ -typedef struct AVOption2 { - const char *name; - - /** - * short English help text - * @todo What about other languages? - */ - const char *help; - - /** - * The offset relative to the context structure where the option - * value is stored. It should be 0 for named constants. - */ - int offset; - enum AVOptionType type; - - /** - * the default value for scalar options - */ - union { - double dbl; - const char *str; - } default_val; - - double min; ///< minimum valid value for the option - double max; ///< maximum valid value for the option - - int flags; -/* -#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding -#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding -#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... -#define AV_OPT_FLAG_AUDIO_PARAM 8 -#define AV_OPT_FLAG_VIDEO_PARAM 16 -#define AV_OPT_FLAG_SUBTITLE_PARAM 32 -*/ -//FIXME think about enc-audio, ... style flags - - /** - * The logical unit to which the option belongs. Non-constant - * options and corresponding named constants share the same - * unit. May be NULL. - */ - const char *unit; -} AVOption2; - - -/** - * Looks for an option in obj. Looks only for the options which - * have the flags set as specified in mask and flags (that is, - * for which it is the case that opt->flags & mask == flags). - * - * @param[in] obj a pointer to a struct whose first element is a - * pointer to an AVClass - * @param[in] name the name of the option to look for - * @param[in] unit the unit of the option to look for, or any if NULL - * @return a pointer to the option found, or NULL if no option - * has been found - */ -const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * @see av_set_string2() - */ -attribute_deprecated const AVOption *av_set_string(void *obj, const char *name, const char *val); - -/** - * @return a pointer to the AVOption corresponding to the field set or - * NULL if no matching AVOption exists, or if the value val is not - * valid - * @see av_set_string3() - */ -attribute_deprecated const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc); -#endif - -/** - * Sets the field of obj with the given name to value. - * - * @param[in] obj A struct whose first element is a pointer to an - * AVClass. - * @param[in] name the name of the field to set - * @param[in] val The value to set. If the field is not of a string - * type, then the given string is parsed. - * SI postfixes and some named scalars are supported. - * If the field is of a numeric type, it has to be a numeric or named - * scalar. Behavior with more than one scalar and +- infix operators - * is undefined. - * If the field is of a flags type, it has to be a sequence of numeric - * scalars or named flags separated by '+' or '-'. Prefixing a flag - * with '+' causes it to be set without affecting the other flags; - * similarly, '-' unsets a flag. - * @param[out] o_out if non-NULL put here a pointer to the AVOption - * found - * @param alloc when 1 then the old value will be av_freed() and the - * new av_strduped() - * when 0 then no av_free() nor av_strdup() will be used - * @return 0 if the value has been set, or an AVERROR code in case of - * error: - * AVERROR(ENOENT) if no matching option exists - * AVERROR(ERANGE) if the value is out of range - * AVERROR(EINVAL) if the value is not valid - */ -int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out); - -const AVOption *av_set_double(void *obj, const char *name, double n); -const AVOption *av_set_q(void *obj, const char *name, AVRational n); -const AVOption *av_set_int(void *obj, const char *name, int64_t n); -double av_get_double(void *obj, const char *name, const AVOption **o_out); -AVRational av_get_q(void *obj, const char *name, const AVOption **o_out); -int64_t av_get_int(void *obj, const char *name, const AVOption **o_out); -const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len); -const AVOption *av_next_option(void *obj, const AVOption *last); -int av_opt_show(void *obj, void *av_log_obj); -void av_opt_set_defaults(void *s); -void av_opt_set_defaults2(void *s, int mask, int flags); - -#endif /* AVCODEC_OPT_H */ diff --git a/tizen/distrib/ffmpeg/include/libavcodec/vaapi.h b/tizen/distrib/ffmpeg/include/libavcodec/vaapi.h deleted file mode 100644 index 07568a4..0000000 --- a/tizen/distrib/ffmpeg/include/libavcodec/vaapi.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Video Acceleration API (shared data between FFmpeg and the video player) - * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VAAPI_H -#define AVCODEC_VAAPI_H - -#include - -/** - * \defgroup VAAPI_Decoding VA API Decoding - * \ingroup Decoder - * @{ - */ - -/** - * This structure is used to share data between the FFmpeg library and - * the client video application. - * This shall be zero-allocated and available as - * AVCodecContext.hwaccel_context. All user members can be set once - * during initialization or through each AVCodecContext.get_buffer() - * function call. In any case, they must be valid prior to calling - * decoding functions. - */ -struct vaapi_context { - /** - * Window system dependent data - * - * - encoding: unused - * - decoding: Set by user - */ - void *display; - - /** - * Configuration ID - * - * - encoding: unused - * - decoding: Set by user - */ - uint32_t config_id; - - /** - * Context ID (video decode pipeline) - * - * - encoding: unused - * - decoding: Set by user - */ - uint32_t context_id; - - /** - * VAPictureParameterBuffer ID - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t pic_param_buf_id; - - /** - * VAIQMatrixBuffer ID - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t iq_matrix_buf_id; - - /** - * VABitPlaneBuffer ID (for VC-1 decoding) - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t bitplane_buf_id; - - /** - * Slice parameter/data buffer IDs - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t *slice_buf_ids; - - /** - * Number of effective slice buffer IDs to send to the HW - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int n_slice_buf_ids; - - /** - * Size of pre-allocated slice_buf_ids - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_buf_ids_alloc; - - /** - * Pointer to VASliceParameterBuffers - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - void *slice_params; - - /** - * Size of a VASliceParameterBuffer element - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_param_size; - - /** - * Size of pre-allocated slice_params - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_params_alloc; - - /** - * Number of slices currently filled in - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_count; - - /** - * Pointer to slice data buffer base - * - encoding: unused - * - decoding: Set by libavcodec - */ - const uint8_t *slice_data; - - /** - * Current size of slice data - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t slice_data_size; -}; - -/* @} */ - -#endif /* AVCODEC_VAAPI_H */ diff --git a/tizen/distrib/ffmpeg/include/libavcodec/vdpau.h b/tizen/distrib/ffmpeg/include/libavcodec/vdpau.h deleted file mode 100644 index a8fa4d3..0000000 --- a/tizen/distrib/ffmpeg/include/libavcodec/vdpau.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * The Video Decode and Presentation API for UNIX (VDPAU) is used for - * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1. - * - * Copyright (C) 2008 NVIDIA - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VDPAU_H -#define AVCODEC_VDPAU_H - -/** - * \defgroup Decoder VDPAU Decoder and Renderer - * - * VDPAU hardware acceleration has two modules - * - VDPAU decoding - * - VDPAU presentation - * - * The VDPAU decoding module parses all headers using FFmpeg - * parsing mechanisms and uses VDPAU for the actual decoding. - * - * As per the current implementation, the actual decoding - * and rendering (API calls) are done as part of the VDPAU - * presentation (vo_vdpau.c) module. - * - * @{ - * \defgroup VDPAU_Decoding VDPAU Decoding - * \ingroup Decoder - * @{ - */ - -#include -#include - -/** \brief The videoSurface is used for rendering. */ -#define FF_VDPAU_STATE_USED_FOR_RENDER 1 - -/** - * \brief The videoSurface is needed for reference/prediction. - * The codec manipulates this. - */ -#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2 - -/** - * \brief This structure is used as a callback between the FFmpeg - * decoder (vd_) and presentation (vo_) module. - * This is used for defining a video frame containing surface, - * picture parameter, bitstream information etc which are passed - * between the FFmpeg decoder and its clients. - */ -struct vdpau_render_state { - VdpVideoSurface surface; ///< Used as rendered surface, never changed. - - int state; ///< Holds FF_VDPAU_STATE_* values. - - /** picture parameter information for all supported codecs */ - union VdpPictureInfo { - VdpPictureInfoH264 h264; - VdpPictureInfoMPEG1Or2 mpeg; - VdpPictureInfoVC1 vc1; - VdpPictureInfoMPEG4Part2 mpeg4; - } info; - - /** Describe size/location of the compressed video data. - Set to 0 when freeing bitstream_buffers. */ - int bitstream_buffers_allocated; - int bitstream_buffers_used; - /** The user is responsible for freeing this buffer using av_freep(). */ - VdpBitstreamBuffer *bitstream_buffers; -}; - -/* @}*/ - -#endif /* AVCODEC_VDPAU_H */ diff --git a/tizen/distrib/ffmpeg/include/libavcodec/xvmc.h b/tizen/distrib/ffmpeg/include/libavcodec/xvmc.h deleted file mode 100644 index 01f84b2..0000000 --- a/tizen/distrib/ffmpeg/include/libavcodec/xvmc.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2003 Ivan Kalvachev - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_XVMC_H -#define AVCODEC_XVMC_H - -#include - -#include "avcodec.h" - -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define AV_XVMC_STATE_DISPLAY_PENDING 1 /** the surface should be shown, the video driver manipulates this */ -#define AV_XVMC_STATE_PREDICTION 2 /** the surface is needed for prediction, the codec manipulates this */ -#define AV_XVMC_STATE_OSD_SOURCE 4 /** the surface is needed for subpicture rendering */ -#endif -#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct - the number is 1337 speak for the letters IDCT MCo (motion compensation) */ - -struct xvmc_pix_fmt { - /** The field contains the special constant value AV_XVMC_ID. - It is used as a test that the application correctly uses the API, - and that there is no corruption caused by pixel routines. - - application - set during initialization - - libavcodec - unchanged - */ - int xvmc_id; - - /** Pointer to the block array allocated by XvMCCreateBlocks(). - The array has to be freed by XvMCDestroyBlocks(). - Each group of 64 values represents one data block of differential - pixel information (in MoCo mode) or coefficients for IDCT. - - application - set the pointer during initialization - - libavcodec - fills coefficients/pixel data into the array - */ - short* data_blocks; - - /** Pointer to the macroblock description array allocated by - XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks(). - - application - set the pointer during initialization - - libavcodec - fills description data into the array - */ - XvMCMacroBlock* mv_blocks; - - /** Number of macroblock descriptions that can be stored in the mv_blocks - array. - - application - set during initialization - - libavcodec - unchanged - */ - int allocated_mv_blocks; - - /** Number of blocks that can be stored at once in the data_blocks array. - - application - set during initialization - - libavcodec - unchanged - */ - int allocated_data_blocks; - - /** Indicates that the hardware would interpret data_blocks as IDCT - coefficients and perform IDCT on them. - - application - set during initialization - - libavcodec - unchanged - */ - int idct; - - /** In MoCo mode it indicates that intra macroblocks are assumed to be in - unsigned format; same as the XVMC_INTRA_UNSIGNED flag. - - application - set during initialization - - libavcodec - unchanged - */ - int unsigned_intra; - - /** Pointer to the surface allocated by XvMCCreateSurface(). - It has to be freed by XvMCDestroySurface() on application exit. - It identifies the frame and its state on the video hardware. - - application - set during initialization - - libavcodec - unchanged - */ - XvMCSurface* p_surface; - -/** Set by the decoder before calling ff_draw_horiz_band(), - needed by the XvMCRenderSurface function. */ -//@{ - /** Pointer to the surface used as past reference - - application - unchanged - - libavcodec - set - */ - XvMCSurface* p_past_surface; - - /** Pointer to the surface used as future reference - - application - unchanged - - libavcodec - set - */ - XvMCSurface* p_future_surface; - - /** top/bottom field or frame - - application - unchanged - - libavcodec - set - */ - unsigned int picture_structure; - - /** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence - - application - unchanged - - libavcodec - set - */ - unsigned int flags; -//}@ - - /** Number of macroblock descriptions in the mv_blocks array - that have already been passed to the hardware. - - application - zeroes it on get_buffer(). - A successful ff_draw_horiz_band() may increment it - with filled_mb_block_num or zero both. - - libavcodec - unchanged - */ - int start_mv_blocks_num; - - /** Number of new macroblock descriptions in the mv_blocks array (after - start_mv_blocks_num) that are filled by libavcodec and have to be - passed to the hardware. - - application - zeroes it on get_buffer() or after successful - ff_draw_horiz_band(). - - libavcodec - increment with one of each stored MB - */ - int filled_mv_blocks_num; - - /** Number of the the next free data block; one data block consists of - 64 short values in the data_blocks array. - All blocks before this one have already been claimed by placing their - position into the corresponding block description structure field, - that are part of the mv_blocks array. - - application - zeroes it on get_buffer(). - A successful ff_draw_horiz_band() may zero it together - with start_mb_blocks_num. - - libavcodec - each decoded macroblock increases it by the number - of coded blocks it contains. - */ - int next_free_data_block_num; - -/** extensions may be placed here */ -#if LIBAVCODEC_VERSION_MAJOR < 53 -//@{ - /** State flags used to work around limitations in the MPlayer video system. - 0 - Surface is not used. - 1 - Surface is still held in application to be displayed or is - still visible. - 2 - Surface is still held in libavcodec buffer for prediction. - */ - int state; - - /** pointer to the surface where the subpicture is rendered */ - void* p_osd_target_surface_render; -//}@ -#endif -}; - -#endif /* AVCODEC_XVMC_H */ diff --git a/tizen/distrib/ffmpeg/include/libavdevice/avdevice.h b/tizen/distrib/ffmpeg/include/libavdevice/avdevice.h deleted file mode 100644 index dcd835c..0000000 --- a/tizen/distrib/ffmpeg/include/libavdevice/avdevice.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVDEVICE_AVDEVICE_H -#define AVDEVICE_AVDEVICE_H - -#include "libavutil/avutil.h" - -#define LIBAVDEVICE_VERSION_MAJOR 52 -#define LIBAVDEVICE_VERSION_MINOR 2 -#define LIBAVDEVICE_VERSION_MICRO 0 - -#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ - LIBAVDEVICE_VERSION_MINOR, \ - LIBAVDEVICE_VERSION_MICRO) -#define LIBAVDEVICE_VERSION AV_VERSION(LIBAVDEVICE_VERSION_MAJOR, \ - LIBAVDEVICE_VERSION_MINOR, \ - LIBAVDEVICE_VERSION_MICRO) -#define LIBAVDEVICE_BUILD LIBAVDEVICE_VERSION_INT - -/** - * Returns the LIBAVDEVICE_VERSION_INT constant. - */ -unsigned avdevice_version(void); - -/** - * Returns the libavdevice build-time configuration. - */ -const char *avdevice_configuration(void); - -/** - * Returns the libavdevice license. - */ -const char *avdevice_license(void); - -/** - * Initialize libavdevice and register all the input and output devices. - * @warning This function is not thread safe. - */ -void avdevice_register_all(void); - -#endif /* AVDEVICE_AVDEVICE_H */ - diff --git a/tizen/distrib/ffmpeg/include/libavfilter/avfilter.h b/tizen/distrib/ffmpeg/include/libavfilter/avfilter.h deleted file mode 100644 index 214b8d4..0000000 --- a/tizen/distrib/ffmpeg/include/libavfilter/avfilter.h +++ /dev/null @@ -1,703 +0,0 @@ -/* - * filter layer - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_AVFILTER_H -#define AVFILTER_AVFILTER_H - -#include "libavutil/avutil.h" - -#define LIBAVFILTER_VERSION_MAJOR 1 -#define LIBAVFILTER_VERSION_MINOR 19 -#define LIBAVFILTER_VERSION_MICRO 0 - -#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ - LIBAVFILTER_VERSION_MINOR, \ - LIBAVFILTER_VERSION_MICRO) -#define LIBAVFILTER_VERSION AV_VERSION(LIBAVFILTER_VERSION_MAJOR, \ - LIBAVFILTER_VERSION_MINOR, \ - LIBAVFILTER_VERSION_MICRO) -#define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT - -#include -#include "libavcodec/avcodec.h" - -/** - * Returns the LIBAVFILTER_VERSION_INT constant. - */ -unsigned avfilter_version(void); - -/** - * Returns the libavfilter build-time configuration. - */ -const char *avfilter_configuration(void); - -/** - * Returns the libavfilter license. - */ -const char *avfilter_license(void); - - -typedef struct AVFilterContext AVFilterContext; -typedef struct AVFilterLink AVFilterLink; -typedef struct AVFilterPad AVFilterPad; - -/* TODO: look for other flags which may be useful in this structure (interlace - * flags, etc) - */ -/** - * A reference-counted picture data type used by the filter system. Filters - * should not store pointers to this structure directly, but instead use the - * AVFilterPicRef structure below. - */ -typedef struct AVFilterPic -{ - uint8_t *data[4]; ///< picture data for each plane - int linesize[4]; ///< number of bytes per line - enum PixelFormat format; ///< colorspace - - unsigned refcount; ///< number of references to this image - - /** private data to be used by a custom free function */ - void *priv; - /** - * A pointer to the function to deallocate this image if the default - * function is not sufficient. This could, for example, add the memory - * back into a memory pool to be reused later without the overhead of - * reallocating it from scratch. - */ - void (*free)(struct AVFilterPic *pic); - - int w, h; ///< width and height of the allocated buffer -} AVFilterPic; - -/** - * A reference to an AVFilterPic. Since filters can manipulate the origin of - * a picture to, for example, crop image without any memcpy, the picture origin - * and dimensions are per-reference properties. Linesize is also useful for - * image flipping, frame to field filters, etc, and so is also per-reference. - * - * TODO: add anything necessary for frame reordering - */ -typedef struct AVFilterPicRef -{ - AVFilterPic *pic; ///< the picture that this is a reference to - uint8_t *data[4]; ///< picture data for each plane - int linesize[4]; ///< number of bytes per line - int w; ///< image width - int h; ///< image height - - int64_t pts; ///< presentation timestamp in units of 1/AV_TIME_BASE - int64_t pos; ///< byte position in stream, -1 if unknown - - AVRational pixel_aspect; ///< pixel aspect ratio - - int perms; ///< permissions -#define AV_PERM_READ 0x01 ///< can read from the buffer -#define AV_PERM_WRITE 0x02 ///< can write to the buffer -#define AV_PERM_PRESERVE 0x04 ///< nobody else can overwrite the buffer -#define AV_PERM_REUSE 0x08 ///< can output the buffer multiple times, with the same contents each time -#define AV_PERM_REUSE2 0x10 ///< can output the buffer multiple times, modified each time -} AVFilterPicRef; - -/** - * Adds a new reference to a picture. - * @param ref an existing reference to the picture - * @param pmask a bitmask containing the allowable permissions in the new - * reference - * @return a new reference to the picture with the same properties as the - * old, excluding any permissions denied by pmask - */ -AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask); - -/** - * Removes a reference to a picture. If this is the last reference to the - * picture, the picture itself is also automatically freed. - * @param ref reference to the picture - */ -void avfilter_unref_pic(AVFilterPicRef *ref); - -/** - * A list of supported formats for one end of a filter link. This is used - * during the format negotiation process to try to pick the best format to - * use to minimize the number of necessary conversions. Each filter gives a - * list of the formats supported by each input and output pad. The list - * given for each pad need not be distinct - they may be references to the - * same list of formats, as is often the case when a filter supports multiple - * formats, but will always output the same format as it is given in input. - * - * In this way, a list of possible input formats and a list of possible - * output formats are associated with each link. When a set of formats is - * negotiated over a link, the input and output lists are merged to form a - * new list containing only the common elements of each list. In the case - * that there were no common elements, a format conversion is necessary. - * Otherwise, the lists are merged, and all other links which reference - * either of the format lists involved in the merge are also affected. - * - * For example, consider the filter chain: - * filter (a) --> (b) filter (b) --> (c) filter - * - * where the letters in parenthesis indicate a list of formats supported on - * the input or output of the link. Suppose the lists are as follows: - * (a) = {A, B} - * (b) = {A, B, C} - * (c) = {B, C} - * - * First, the first link's lists are merged, yielding: - * filter (a) --> (a) filter (a) --> (c) filter - * - * Notice that format list (b) now refers to the same list as filter list (a). - * Next, the lists for the second link are merged, yielding: - * filter (a) --> (a) filter (a) --> (a) filter - * - * where (a) = {B}. - * - * Unfortunately, when the format lists at the two ends of a link are merged, - * we must ensure that all links which reference either pre-merge format list - * get updated as well. Therefore, we have the format list structure store a - * pointer to each of the pointers to itself. - */ -typedef struct AVFilterFormats AVFilterFormats; -struct AVFilterFormats -{ - unsigned format_count; ///< number of formats - enum PixelFormat *formats; ///< list of pixel formats - - unsigned refcount; ///< number of references to this list - AVFilterFormats ***refs; ///< references to this list -}; - -/** - * Creates a list of supported formats. This is intended for use in - * AVFilter->query_formats(). - * @param pix_fmt list of pixel formats, terminated by PIX_FMT_NONE - * @return the format list, with no existing references - */ -AVFilterFormats *avfilter_make_format_list(const enum PixelFormat *pix_fmts); - -/** - * Adds pix_fmt to the list of pixel formats contained in *avff. - * If *avff is NULL the function allocates the filter formats struct - * and puts its pointer in *avff. - * - * @return a non negative value in case of success, or a negative - * value corresponding to an AVERROR code in case of error - */ -int avfilter_add_colorspace(AVFilterFormats **avff, enum PixelFormat pix_fmt); - -/** - * Returns a list of all colorspaces supported by FFmpeg. - */ -AVFilterFormats *avfilter_all_colorspaces(void); - -/** - * Returns a format list which contains the intersection of the formats of - * a and b. Also, all the references of a, all the references of b, and - * a and b themselves will be deallocated. - * - * If a and b do not share any common formats, neither is modified, and NULL - * is returned. - */ -AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b); - -/** - * Adds *ref as a new reference to formats. - * That is the pointers will point like in the ascii art below: - * ________ - * |formats |<--------. - * | ____ | ____|___________________ - * | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| - * | |____| | | |____| - * |________| |________________________ - */ -void avfilter_formats_ref(AVFilterFormats *formats, AVFilterFormats **ref); - -/** - * If *ref is non-NULL, removes *ref as a reference to the format list - * it currently points to, deallocates that list if this was the last - * reference, and sets *ref to NULL. - * - * Before After - * ________ ________ NULL - * |formats |<--------. |formats | ^ - * | ____ | ____|________________ | ____ | ____|________________ - * | |refs| | | __|_ | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| | |* | | | |*ref| - * | |____| | | |____| | |____| | | |____| - * |________| |_____________________ |________| |_____________________ - */ -void avfilter_formats_unref(AVFilterFormats **ref); - -/** - * - * Before After - * ________ ________ - * |formats |<---------. |formats |<---------. - * | ____ | ___|___ | ____ | ___|___ - * | |refs| | | | | | |refs| | | | | NULL - * | |* *--------->|*oldref| | |* *--------->|*newref| ^ - * | |* * | | |_______| | |* * | | |_______| ___|___ - * | |____| | | |____| | | | | - * |________| |________| |*oldref| - * |_______| - */ -void avfilter_formats_changeref(AVFilterFormats **oldref, - AVFilterFormats **newref); - -/** - * A filter pad used for either input or output. - */ -struct AVFilterPad -{ - /** - * Pad name. The name is unique among inputs and among outputs, but an - * input may have the same name as an output. This may be NULL if this - * pad has no need to ever be referenced by name. - */ - const char *name; - - /** - * AVFilterPad type. Only video supported now, hopefully someone will - * add audio in the future. - */ - enum AVMediaType type; - - /** - * Minimum required permissions on incoming buffers. Any buffer with - * insufficient permissions will be automatically copied by the filter - * system to a new buffer which provides the needed access permissions. - * - * Input pads only. - */ - int min_perms; - - /** - * Permissions which are not accepted on incoming buffers. Any buffer - * which has any of these permissions set will be automatically copied - * by the filter system to a new buffer which does not have those - * permissions. This can be used to easily disallow buffers with - * AV_PERM_REUSE. - * - * Input pads only. - */ - int rej_perms; - - /** - * Callback called before passing the first slice of a new frame. If - * NULL, the filter layer will default to storing a reference to the - * picture inside the link structure. - * - * Input video pads only. - */ - void (*start_frame)(AVFilterLink *link, AVFilterPicRef *picref); - - /** - * Callback function to get a buffer. If NULL, the filter system will - * use avfilter_default_get_video_buffer(). - * - * Input video pads only. - */ - AVFilterPicRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h); - - /** - * Callback called after the slices of a frame are completely sent. If - * NULL, the filter layer will default to releasing the reference stored - * in the link structure during start_frame(). - * - * Input video pads only. - */ - void (*end_frame)(AVFilterLink *link); - - /** - * Slice drawing callback. This is where a filter receives video data - * and should do its processing. - * - * Input video pads only. - */ - void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); - - /** - * Frame poll callback. This returns the number of immediately available - * frames. It should return a positive value if the next request_frame() - * is guaranteed to return one frame (with no delay). - * - * Defaults to just calling the source poll_frame() method. - * - * Output video pads only. - */ - int (*poll_frame)(AVFilterLink *link); - - /** - * Frame request callback. A call to this should result in at least one - * frame being output over the given link. This should return zero on - * success, and another value on error. - * - * Output video pads only. - */ - int (*request_frame)(AVFilterLink *link); - - /** - * Link configuration callback. - * - * For output pads, this should set the link properties such as - * width/height. This should NOT set the format property - that is - * negotiated between filters by the filter system using the - * query_formats() callback before this function is called. - * - * For input pads, this should check the properties of the link, and update - * the filter's internal state as necessary. - * - * For both input and output filters, this should return zero on success, - * and another value on error. - */ - int (*config_props)(AVFilterLink *link); -}; - -/** default handler for start_frame() for video inputs */ -void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref); -/** default handler for draw_slice() for video inputs */ -void avfilter_default_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); -/** default handler for end_frame() for video inputs */ -void avfilter_default_end_frame(AVFilterLink *link); -/** default handler for config_props() for video outputs */ -int avfilter_default_config_output_link(AVFilterLink *link); -/** default handler for config_props() for video inputs */ -int avfilter_default_config_input_link (AVFilterLink *link); -/** default handler for get_video_buffer() for video inputs */ -AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, - int perms, int w, int h); -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); -/** Default handler for query_formats() */ -int avfilter_default_query_formats(AVFilterContext *ctx); - -/** start_frame() handler for filters which simply pass video along */ -void avfilter_null_start_frame(AVFilterLink *link, AVFilterPicRef *picref); - -/** draw_slice() handler for filters which simply pass video along */ -void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); - -/** end_frame() handler for filters which simply pass video along */ -void avfilter_null_end_frame(AVFilterLink *link); - -/** get_video_buffer() handler for filters which simply pass video along */ -AVFilterPicRef *avfilter_null_get_video_buffer(AVFilterLink *link, - int perms, int w, int h); - -/** - * Filter definition. This defines the pads a filter contains, and all the - * callback functions used to interact with the filter. - */ -typedef struct AVFilter -{ - const char *name; ///< filter name - - int priv_size; ///< size of private data to allocate for the filter - - /** - * Filter initialization function. Args contains the user-supplied - * parameters. FIXME: maybe an AVOption-based system would be better? - * opaque is data provided by the code requesting creation of the filter, - * and is used to pass data to the filter. - */ - int (*init)(AVFilterContext *ctx, const char *args, void *opaque); - - /** - * Filter uninitialization function. Should deallocate any memory held - * by the filter, release any picture references, etc. This does not need - * to deallocate the AVFilterContext->priv memory itself. - */ - void (*uninit)(AVFilterContext *ctx); - - /** - * Queries formats supported by the filter and its pads, and sets the - * in_formats for links connected to its output pads, and out_formats - * for links connected to its input pads. - * - * @return zero on success, a negative value corresponding to an - * AVERROR code otherwise - */ - int (*query_formats)(AVFilterContext *); - - const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none - const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none - - /** - * A description for the filter. You should use the - * NULL_IF_CONFIG_SMALL() macro to define it. - */ - const char *description; -} AVFilter; - -/** An instance of a filter */ -struct AVFilterContext -{ - const AVClass *av_class; ///< needed for av_log() - - AVFilter *filter; ///< the AVFilter of which this is an instance - - char *name; ///< name of this filter instance - - unsigned input_count; ///< number of input pads - AVFilterPad *input_pads; ///< array of input pads - AVFilterLink **inputs; ///< array of pointers to input links - - unsigned output_count; ///< number of output pads - AVFilterPad *output_pads; ///< array of output pads - AVFilterLink **outputs; ///< array of pointers to output links - - void *priv; ///< private data for use by the filter -}; - -/** - * A link between two filters. This contains pointers to the source and - * destination filters between which this link exists, and the indexes of - * the pads involved. In addition, this link also contains the parameters - * which have been negotiated and agreed upon between the filter, such as - * image dimensions, format, etc. - */ -struct AVFilterLink -{ - AVFilterContext *src; ///< source filter - unsigned int srcpad; ///< index of the output pad on the source filter - - AVFilterContext *dst; ///< dest filter - unsigned int dstpad; ///< index of the input pad on the dest filter - - /** stage of the initialization of the link properties (dimensions, etc) */ - enum { - AVLINK_UNINIT = 0, ///< not started - AVLINK_STARTINIT, ///< started, but incomplete - AVLINK_INIT ///< complete - } init_state; - - int w; ///< agreed upon image width - int h; ///< agreed upon image height - enum PixelFormat format; ///< agreed upon image colorspace - - /** - * Lists of formats supported by the input and output filters respectively. - * These lists are used for negotiating the format to actually be used, - * which will be loaded into the format member, above, when chosen. - */ - AVFilterFormats *in_formats; - AVFilterFormats *out_formats; - - /** - * The picture reference currently being sent across the link by the source - * filter. This is used internally by the filter system to allow - * automatic copying of pictures which do not have sufficient permissions - * for the destination. This should not be accessed directly by the - * filters. - */ - AVFilterPicRef *srcpic; - - AVFilterPicRef *cur_pic; - AVFilterPicRef *outpic; -}; - -/** - * Links two filters together. - * @param src the source filter - * @param srcpad index of the output pad on the source filter - * @param dst the destination filter - * @param dstpad index of the input pad on the destination filter - * @return zero on success - */ -int avfilter_link(AVFilterContext *src, unsigned srcpad, - AVFilterContext *dst, unsigned dstpad); - -/** - * Negotiates the colorspace, dimensions, etc of all inputs to a filter. - * @param filter the filter to negotiate the properties for its inputs - * @return zero on successful negotiation - */ -int avfilter_config_links(AVFilterContext *filter); - -/** - * Requests a picture buffer with a specific set of permissions. - * @param link the output link to the filter from which the picture will - * be requested - * @param perms the required access permissions - * @param w the minimum width of the buffer to allocate - * @param h the minimum height of the buffer to allocate - * @return A reference to the picture. This must be unreferenced with - * avfilter_unref_pic when you are finished with it. - */ -AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, - int w, int h); - -/** - * Requests an input frame from the filter at the other end of the link. - * @param link the input link - * @return zero on success - */ -int avfilter_request_frame(AVFilterLink *link); - -/** - * Polls a frame from the filter chain. - * @param link the input link - * @return the number of immediately available frames, a negative - * number in case of error - */ -int avfilter_poll_frame(AVFilterLink *link); - -/** - * Notifies the next filter of the start of a frame. - * @param link the output link the frame will be sent over - * @param picref A reference to the frame about to be sent. The data for this - * frame need only be valid once draw_slice() is called for that - * portion. The receiving filter will free this reference when - * it no longer needs it. - */ -void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref); - -/** - * Notifies the next filter that the current frame has finished. - * @param link the output link the frame was sent over - */ -void avfilter_end_frame(AVFilterLink *link); - -/** - * Sends a slice to the next filter. - * - * Slices have to be provided in sequential order, either in - * top-bottom or bottom-top order. If slices are provided in - * non-sequential order the behavior of the function is undefined. - * - * @param link the output link over which the frame is being sent - * @param y offset in pixels from the top of the image for this slice - * @param h height of this slice in pixels - * @param slice_dir the assumed direction for sending slices, - * from the top slice to the bottom slice if the value is 1, - * from the bottom slice to the top slice if the value is -1, - * for other values the behavior of the function is undefined. - */ -void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); - -/** Initializes the filter system. Registers all builtin filters. */ -void avfilter_register_all(void); - -/** Uninitializes the filter system. Unregisters all filters. */ -void avfilter_uninit(void); - -/** - * Registers a filter. This is only needed if you plan to use - * avfilter_get_by_name later to lookup the AVFilter structure by name. A - * filter can still by instantiated with avfilter_open even if it is not - * registered. - * @param filter the filter to register - * @return 0 if the registration was succesfull, a negative value - * otherwise - */ -int avfilter_register(AVFilter *filter); - -/** - * Gets a filter definition matching the given name. - * @param name the filter name to find - * @return the filter definition, if any matching one is registered. - * NULL if none found. - */ -AVFilter *avfilter_get_by_name(const char *name); - -/** - * If filter is NULL, returns a pointer to the first registered filter pointer, - * if filter is non-NULL, returns the next pointer after filter. - * If the returned pointer points to NULL, the last registered filter - * was already reached. - */ -AVFilter **av_filter_next(AVFilter **filter); - -/** - * Creates a filter instance. - * @param filter the filter to create an instance of - * @param inst_name Name to give to the new instance. Can be NULL for none. - * @return Pointer to the new instance on success. NULL on failure. - */ -AVFilterContext *avfilter_open(AVFilter *filter, const char *inst_name); - -/** - * Initializes a filter. - * @param filter the filter to initialize - * @param args A string of parameters to use when initializing the filter. - * The format and meaning of this string varies by filter. - * @param opaque Any extra non-string data needed by the filter. The meaning - * of this parameter varies by filter. - * @return zero on success - */ -int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque); - -/** - * Destroys a filter. - * @param filter the filter to destroy - */ -void avfilter_destroy(AVFilterContext *filter); - -/** - * Inserts a filter in the middle of an existing link. - * @param link the link into which the filter should be inserted - * @param filt the filter to be inserted - * @param in the input pad on the filter to connect - * @param out the output pad on the filter to connect - * @return zero on success - */ -int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, - unsigned in, unsigned out); - -/** - * Inserts a new pad. - * @param idx Insertion point. Pad is inserted at the end if this point - * is beyond the end of the list of pads. - * @param count Pointer to the number of pads in the list - * @param padidx_off Offset within an AVFilterLink structure to the element - * to increment when inserting a new pad causes link - * numbering to change - * @param pads Pointer to the pointer to the beginning of the list of pads - * @param links Pointer to the pointer to the beginning of the list of links - * @param newpad The new pad to add. A copy is made when adding. - */ -void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, - AVFilterPad **pads, AVFilterLink ***links, - AVFilterPad *newpad); - -/** Inserts a new input pad for the filter. */ -static inline void avfilter_insert_inpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - avfilter_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad), - &f->input_pads, &f->inputs, p); -} - -/** Inserts a new output pad for the filter. */ -static inline void avfilter_insert_outpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - avfilter_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), - &f->output_pads, &f->outputs, p); -} - -#endif /* AVFILTER_AVFILTER_H */ diff --git a/tizen/distrib/ffmpeg/include/libavformat/avformat.h b/tizen/distrib/ffmpeg/include/libavformat/avformat.h deleted file mode 100644 index 0e93376..0000000 --- a/tizen/distrib/ffmpeg/include/libavformat/avformat.h +++ /dev/null @@ -1,1355 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_AVFORMAT_H -#define AVFORMAT_AVFORMAT_H - -#define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 64 -#define LIBAVFORMAT_VERSION_MICRO 2 - -#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ - LIBAVFORMAT_VERSION_MINOR, \ - LIBAVFORMAT_VERSION_MICRO) -#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \ - LIBAVFORMAT_VERSION_MINOR, \ - LIBAVFORMAT_VERSION_MICRO) -#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT - -#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) - -/** - * I return the LIBAVFORMAT_VERSION_INT constant. You got - * a fucking problem with that, douchebag? - */ -unsigned avformat_version(void); - -/** - * Returns the libavformat build-time configuration. - */ -const char *avformat_configuration(void); - -/** - * Returns the libavformat license. - */ -const char *avformat_license(void); - -#include -#include /* FILE */ -#include "libavcodec/avcodec.h" - -#include "avio.h" - -struct AVFormatContext; - - -/* - * Public Metadata API. - * The metadata API allows libavformat to export metadata tags to a client - * application using a sequence of key/value pairs. Like all strings in FFmpeg, - * metadata must be stored as UTF-8 encoded Unicode. Note that metadata - * exported by demuxers isn't checked to be valid UTF-8 in most cases. - * Important concepts to keep in mind: - * 1. Keys are unique; there can never be 2 tags with the same key. This is - * also meant semantically, i.e., a demuxer should not knowingly produce - * several keys that are literally different but semantically identical. - * E.g., key=Author5, key=Author6. In this example, all authors must be - * placed in the same tag. - * 2. Metadata is flat, not hierarchical; there are no subtags. If you - * want to store, e.g., the email address of the child of producer Alice - * and actor Bob, that could have key=alice_and_bobs_childs_email_address. - * 3. Several modifiers can be applied to the tag name. This is done by - * appending a dash character ('-') and the modifier name in the order - * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng. - * a) language -- a tag whose value is localized for a particular language - * is appended with the ISO 639-2/B 3-letter language code. - * For example: Author-ger=Michael, Author-eng=Mike - * The original/default language is in the unqualified "Author" tag. - * A demuxer should set a default if it sets any translated tag. - * b) sorting -- a modified version of a tag that should be used for - * sorting will have '-sort' appended. E.g. artist="The Beatles", - * artist-sort="Beatles, The". - * - * 4. Tag names are normally exported exactly as stored in the container to - * allow lossless remuxing to the same format. For container-independent - * handling of metadata, av_metadata_conv() can convert it to ffmpeg generic - * format. Follows a list of generic tag names: - * - * album -- name of the set this work belongs to - * album_artist -- main creator of the set/album, if different from artist. - * e.g. "Various Artists" for compilation albums. - * artist -- main creator of the work - * comment -- any additional description of the file. - * composer -- who composed the work, if different from artist. - * copyright -- name of copyright holder. - * date -- date when the work was created, preferably in ISO 8601. - * disc -- number of a subset, e.g. disc in a multi-disc collection. - * encoder -- name/settings of the software/hardware that produced the file. - * encoded_by -- person/group who created the file. - * filename -- original name of the file. - * genre -- . - * language -- main language in which the work is performed, preferably - * in ISO 639-2 format. - * performer -- artist who performed the work, if different from artist. - * E.g for "Also sprach Zarathustra", artist would be "Richard - * Strauss" and performer "London Philharmonic Orchestra". - * publisher -- name of the label/publisher. - * title -- name of the work. - * track -- number of this work in the set, can be in form current/total. - */ - -#define AV_METADATA_MATCH_CASE 1 -#define AV_METADATA_IGNORE_SUFFIX 2 -#define AV_METADATA_DONT_STRDUP_KEY 4 -#define AV_METADATA_DONT_STRDUP_VAL 8 -#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags. - -typedef struct { - char *key; - char *value; -}AVMetadataTag; - -typedef struct AVMetadata AVMetadata; -typedef struct AVMetadataConv AVMetadataConv; - -/** - * Gets a metadata element with matching key. - * @param prev Set to the previous matching element to find the next. - * If set to NULL the first matching element is returned. - * @param flags Allows case as well as suffix-insensitive comparisons. - * @return Found tag or NULL, changing key or value leads to undefined behavior. - */ -AVMetadataTag * -av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags); - -#if LIBAVFORMAT_VERSION_MAJOR == 52 -/** - * Sets the given tag in m, overwriting an existing tag. - * @param key tag key to add to m (will be av_strduped) - * @param value tag value to add to m (will be av_strduped) - * @return >= 0 on success otherwise an error code <0 - * @deprecated Use av_metadata_set2() instead. - */ -attribute_deprecated int av_metadata_set(AVMetadata **pm, const char *key, const char *value); -#endif - -/** - * Sets the given tag in m, overwriting an existing tag. - * @param key tag key to add to m (will be av_strduped depending on flags) - * @param value tag value to add to m (will be av_strduped depending on flags) - * @return >= 0 on success otherwise an error code <0 - */ -int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags); - -/** - * Converts all the metadata sets from ctx according to the source and - * destination conversion tables. If one of the tables is NULL, then - * tags are converted to/from ffmpeg generic tag names. - * @param d_conv destination tags format conversion table - * @param s_conv source tags format conversion table - */ -void av_metadata_conv(struct AVFormatContext *ctx,const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv); - -/** - * Frees all the memory allocated for an AVMetadata struct. - */ -void av_metadata_free(AVMetadata **m); - - -/* packet functions */ - - -/** - * Allocates and reads the payload of a packet and initializes its - * fields with default values. - * - * @param pkt packet - * @param size desired payload size - * @return >0 (read size) if OK, AVERROR_xxx otherwise - */ -int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size); - - -/*************************************************/ -/* fractional numbers for exact pts handling */ - -/** - * The exact value of the fractional number is: 'val + num / den'. - * num is assumed to be 0 <= num < den. - */ -typedef struct AVFrac { - int64_t val, num, den; -} AVFrac; - -/*************************************************/ -/* input/output formats */ - -struct AVCodecTag; - -/** This structure contains the data a format has to probe a file. */ -typedef struct AVProbeData { - const char *filename; - unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */ - int buf_size; /**< Size of buf except extra allocated bytes */ -} AVProbeData; - -#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection -#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer - -typedef struct AVFormatParameters { - AVRational time_base; - int sample_rate; - int channels; - int width; - int height; - enum PixelFormat pix_fmt; - int channel; /**< Used to select DV channel. */ - const char *standard; /**< TV standard, NTSC, PAL, SECAM */ - unsigned int mpeg2ts_raw:1; /**< Force raw MPEG-2 transport stream output, if possible. */ - unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport - stream packet (only meaningful if - mpeg2ts_raw is TRUE). */ - unsigned int initial_pause:1; /**< Do not begin to play the stream - immediately (RTSP only). */ - unsigned int prealloced_context:1; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - enum CodecID video_codec_id; - enum CodecID audio_codec_id; -#endif -} AVFormatParameters; - -//! Demuxer will use url_fopen, no opened file should be provided by the caller. -#define AVFMT_NOFILE 0x0001 -#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ -#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ -#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for - raw picture data. */ -#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ -#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ -#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ -#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. */ -#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */ -#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */ - -typedef struct AVOutputFormat { - const char *name; - /** - * Descriptive name for the format, meant to be more human-readable - * than name. You should use the NULL_IF_CONFIG_SMALL() macro - * to define it. - */ - const char *long_name; - const char *mime_type; - const char *extensions; /**< comma-separated filename extensions */ - /** size of private data so that it can be allocated in the wrapper */ - int priv_data_size; - /* output support */ - enum CodecID audio_codec; /**< default audio codec */ - enum CodecID video_codec; /**< default video codec */ - int (*write_header)(struct AVFormatContext *); - int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); - int (*write_trailer)(struct AVFormatContext *); - /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */ - int flags; - /** Currently only used to set pixel format if not YUV420P. */ - int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *); - int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, - AVPacket *in, int flush); - - /** - * List of supported codec_id-codec_tag pairs, ordered by "better - * choice first". The arrays are all terminated by CODEC_ID_NONE. - */ - const struct AVCodecTag * const *codec_tag; - - enum CodecID subtitle_codec; /**< default subtitle codec */ - - const AVMetadataConv *metadata_conv; - - /* private fields */ - struct AVOutputFormat *next; -} AVOutputFormat; - -typedef struct AVInputFormat { - const char *name; - /** - * Descriptive name for the format, meant to be more human-readable - * than name. You should use the NULL_IF_CONFIG_SMALL() macro - * to define it. - */ - const char *long_name; - /** Size of private data so that it can be allocated in the wrapper. */ - int priv_data_size; - /** - * Tell if a given file has a chance of being parsed as this format. - * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes - * big so you do not have to check for that unless you need more. - */ - int (*read_probe)(AVProbeData *); - /** Read the format header and initialize the AVFormatContext - structure. Return 0 if OK. 'ap' if non-NULL contains - additional parameters. Only used in raw format right - now. 'av_new_stream' should be called to create new streams. */ - int (*read_header)(struct AVFormatContext *, - AVFormatParameters *ap); - /** Read one packet and put it in 'pkt'. pts and flags are also - set. 'av_new_stream' can be called only if the flag - AVFMTCTX_NOHEADER is used. - @return 0 on success, < 0 on error. - When returning an error, pkt must not have been allocated - or must be freed before returning */ - int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); - /** Close the stream. The AVFormatContext and AVStreams are not - freed by this function */ - int (*read_close)(struct AVFormatContext *); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 - /** - * Seek to a given timestamp relative to the frames in - * stream component stream_index. - * @param stream_index Must not be -1. - * @param flags Selects which direction should be preferred if no exact - * match is available. - * @return >= 0 on success (but not necessarily the new offset) - */ - int (*read_seek)(struct AVFormatContext *, - int stream_index, int64_t timestamp, int flags); -#endif - /** - * Gets the next timestamp in stream[stream_index].time_base units. - * @return the timestamp or AV_NOPTS_VALUE if an error occurred - */ - int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit); - /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */ - int flags; - /** If extensions are defined, then no probe is done. You should - usually not use extension format guessing because it is not - reliable enough */ - const char *extensions; - /** General purpose read-only value that the format can use. */ - int value; - - /** Starts/resumes playing - only meaningful if using a network-based format - (RTSP). */ - int (*read_play)(struct AVFormatContext *); - - /** Pauses playing - only meaningful if using a network-based format - (RTSP). */ - int (*read_pause)(struct AVFormatContext *); - - const struct AVCodecTag * const *codec_tag; - - /** - * Seeks to timestamp ts. - * Seeking will be done so that the point from which all active streams - * can be presented successfully will be closest to ts and within min/max_ts. - * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. - */ - int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); - - const AVMetadataConv *metadata_conv; - - /* private fields */ - struct AVInputFormat *next; -} AVInputFormat; - -enum AVStreamParseType { - AVSTREAM_PARSE_NONE, - AVSTREAM_PARSE_FULL, /**< full parsing and repack */ - AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ - AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ -}; - -typedef struct AVIndexEntry { - int64_t pos; - int64_t timestamp; -#define AVINDEX_KEYFRAME 0x0001 - int flags:2; - int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment). - int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ -} AVIndexEntry; - -#define AV_DISPOSITION_DEFAULT 0x0001 -#define AV_DISPOSITION_DUB 0x0002 -#define AV_DISPOSITION_ORIGINAL 0x0004 -#define AV_DISPOSITION_COMMENT 0x0008 -#define AV_DISPOSITION_LYRICS 0x0010 -#define AV_DISPOSITION_KARAOKE 0x0020 - -/** - * Stream structure. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVStream) must not be used outside libav*. - */ -typedef struct AVStream { - int index; /**< stream index in AVFormatContext */ - int id; /**< format-specific stream ID */ - AVCodecContext *codec; /**< codec context */ - /** - * Real base framerate of the stream. - * This is the lowest framerate with which all timestamps can be - * represented accurately (it is the least common multiple of all - * framerates in the stream). Note, this value is just a guess! - * For example, if the time base is 1/90000 and all frames have either - * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. - */ - AVRational r_frame_rate; - void *priv_data; - - /* internal data used in av_find_stream_info() */ - int64_t first_dts; - /** encoding: pts generation when outputting stream */ - struct AVFrac pts; - - /** - * This is the fundamental unit of time (in seconds) in terms - * of which frame timestamps are represented. For fixed-fps content, - * time base should be 1/framerate and timestamp increments should be 1. - */ - AVRational time_base; - int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ - /* ffmpeg.c private use */ - int stream_copy; /**< If set, just copy stream. */ - enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed. - //FIXME move stuff to a flags field? - /** Quality, as it has been removed from AVCodecContext and put in AVVideoFrame. - * MN: dunno if that is the right place for it */ - float quality; - /** - * Decoding: pts of the first frame of the stream, in stream time base. - * Only set this if you are absolutely 100% sure that the value you set - * it to really is the pts of the first frame. - * This may be undefined (AV_NOPTS_VALUE). - * @note The ASF header does NOT contain a correct start_time the ASF - * demuxer must NOT set this. - */ - int64_t start_time; - /** - * Decoding: duration of the stream, in stream time base. - * If a source file does not specify a duration, but does specify - * a bitrate, this value will be estimated from bitrate and file size. - */ - int64_t duration; - -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char language[4]; /** ISO 639-2/B 3-letter language code (empty string if undefined) */ -#endif - - /* av_read_frame() support */ - enum AVStreamParseType need_parsing; - struct AVCodecParserContext *parser; - - int64_t cur_dts; - int last_IP_duration; - int64_t last_IP_pts; - /* av_seek_frame() support */ - AVIndexEntry *index_entries; /**< Only used if the format does not - support seeking natively. */ - int nb_index_entries; - unsigned int index_entries_allocated_size; - - int64_t nb_frames; ///< number of frames in this stream if known or 0 - -#if LIBAVFORMAT_VERSION_INT < (53<<16) - int64_t unused[4+1]; - - char *filename; /**< source filename of the stream */ -#endif - - int disposition; /**< AV_DISPOSITION_* bit field */ - - AVProbeData probe_data; -#define MAX_REORDER_DELAY 16 - int64_t pts_buffer[MAX_REORDER_DELAY+1]; - - /** - * sample aspect ratio (0 if unknown) - * - encoding: Set by user. - * - decoding: Set by libavformat. - */ - AVRational sample_aspect_ratio; - - AVMetadata *metadata; - - /* av_read_frame() support */ - const uint8_t *cur_ptr; - int cur_len; - AVPacket cur_pkt; - - // Timestamp generation support: - /** - * Timestamp corresponding to the last dts sync point. - * - * Initialized when AVCodecParserContext.dts_sync_point >= 0 and - * a DTS is received from the underlying container. Otherwise set to - * AV_NOPTS_VALUE by default. - */ - int64_t reference_dts; - - /** - * Number of packets to buffer for codec probing - * NOT PART OF PUBLIC API - */ -#define MAX_PROBE_PACKETS 2500 - int probe_packets; - - /** - * last packet in packet_buffer for this stream when muxing. - * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav* - */ - struct AVPacketList *last_in_packet_buffer; - - /** - * Average framerate - */ - AVRational avg_frame_rate; - - /** - * Number of frames that have been demuxed during av_find_stream_info() - */ - int codec_info_nb_frames; -} AVStream; - -#define AV_PROGRAM_RUNNING 1 - -/** - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVProgram) must not be used outside libav*. - */ -typedef struct AVProgram { - int id; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char *provider_name; ///< network name for DVB streams - char *name; ///< service name for DVB streams -#endif - int flags; - enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller - unsigned int *stream_index; - unsigned int nb_stream_indexes; - AVMetadata *metadata; -} AVProgram; - -#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present - (streams are added dynamically) */ - -typedef struct AVChapter { - int id; ///< unique ID to identify the chapter - AVRational time_base; ///< time base in which the start/end timestamps are specified - int64_t start, end; ///< chapter start/end time in time_base units -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char *title; ///< chapter title -#endif - AVMetadata *metadata; -} AVChapter; - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -#define MAX_STREAMS 20 -#else -#define MAX_STREAMS 100 -#endif - -/** - * Format I/O context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVFormatContext) must not be used outside libav*. - */ -typedef struct AVFormatContext { - const AVClass *av_class; /**< Set by avformat_alloc_context. */ - /* Can only be iformat or oformat, not both at the same time. */ - struct AVInputFormat *iformat; - struct AVOutputFormat *oformat; - void *priv_data; - ByteIOContext *pb; - unsigned int nb_streams; - AVStream *streams[MAX_STREAMS]; - char filename[1024]; /**< input or output filename */ - /* stream info */ - int64_t timestamp; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char title[512]; - char author[512]; - char copyright[512]; - char comment[512]; - char album[512]; - int year; /**< ID3 year, 0 if none */ - int track; /**< track number, 0 if none */ - char genre[32]; /**< ID3 genre */ -#endif - - int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ - /* private data for pts handling (do not modify directly). */ - /** This buffer is only needed when packets were already buffered but - not decoded, for example to get the codec parameters in MPEG - streams. */ - struct AVPacketList *packet_buffer; - - /** Decoding: position of the first frame of the component, in - AV_TIME_BASE fractional seconds. NEVER set this value directly: - It is deduced from the AVStream values. */ - int64_t start_time; - /** Decoding: duration of the stream, in AV_TIME_BASE fractional - seconds. Only set this value if you know none of the individual stream - durations and also dont set any of them. This is deduced from the - AVStream values if not set. */ - int64_t duration; - /** decoding: total file size, 0 if unknown */ - int64_t file_size; - /** Decoding: total stream bitrate in bit/s, 0 if not - available. Never set it directly if the file_size and the - duration are known as FFmpeg can compute it automatically. */ - int bit_rate; - - /* av_read_frame() support */ - AVStream *cur_st; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - const uint8_t *cur_ptr_deprecated; - int cur_len_deprecated; - AVPacket cur_pkt_deprecated; -#endif - - /* av_seek_frame() support */ - int64_t data_offset; /** offset of the first packet */ - int index_built; - - int mux_rate; - unsigned int packet_size; - int preload; - int max_delay; - -#define AVFMT_NOOUTPUTLOOP -1 -#define AVFMT_INFINITEOUTPUTLOOP 0 - /** number of times to loop output in formats that support it */ - int loop_output; - - int flags; -#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames. -#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. -#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. -#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS -#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container -#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled -#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Add RTP hinting to the output file - - int loop_input; - /** decoding: size of data to probe; encoding: unused. */ - unsigned int probesize; - - /** - * Maximum time (in AV_TIME_BASE units) during which the input should - * be analyzed in av_find_stream_info(). - */ - int max_analyze_duration; - - const uint8_t *key; - int keylen; - - unsigned int nb_programs; - AVProgram **programs; - - /** - * Forced video codec_id. - * Demuxing: Set by user. - */ - enum CodecID video_codec_id; - /** - * Forced audio codec_id. - * Demuxing: Set by user. - */ - enum CodecID audio_codec_id; - /** - * Forced subtitle codec_id. - * Demuxing: Set by user. - */ - enum CodecID subtitle_codec_id; - - /** - * Maximum amount of memory in bytes to use for the index of each stream. - * If the index exceeds this size, entries will be discarded as - * needed to maintain a smaller size. This can lead to slower or less - * accurate seeking (depends on demuxer). - * Demuxers for which a full in-memory index is mandatory will ignore - * this. - * muxing : unused - * demuxing: set by user - */ - unsigned int max_index_size; - - /** - * Maximum amount of memory in bytes to use for buffering frames - * obtained from realtime capture devices. - */ - unsigned int max_picture_buffer; - - unsigned int nb_chapters; - AVChapter **chapters; - - /** - * Flags to enable debugging. - */ - int debug; -#define FF_FDEBUG_TS 0x0001 - - /** - * Raw packets from the demuxer, prior to parsing and decoding. - * This buffer is used for buffering packets until the codec can - * be identified, as parsing cannot be done without knowing the - * codec. - */ - struct AVPacketList *raw_packet_buffer; - struct AVPacketList *raw_packet_buffer_end; - - struct AVPacketList *packet_buffer_end; - - AVMetadata *metadata; - - /** - * Remaining size available for raw_packet_buffer, in bytes. - * NOT PART OF PUBLIC API - */ -#define RAW_PACKET_BUFFER_SIZE 2500000 - int raw_packet_buffer_remaining_size; - - /** - * Start time of the stream in real world time, in microseconds - * since the unix epoch (00:00 1st January 1970). That is, pts=0 - * in the stream was captured at this real world time. - * - encoding: Set by user. - * - decoding: Unused. - */ - int64_t start_time_realtime; -} AVFormatContext; - -typedef struct AVPacketList { - AVPacket pkt; - struct AVPacketList *next; -} AVPacketList; - -#if LIBAVFORMAT_VERSION_INT < (53<<16) -extern AVInputFormat *first_iformat; -extern AVOutputFormat *first_oformat; -#endif - -/** - * If f is NULL, returns the first registered input format, - * if f is non-NULL, returns the next registered input format after f - * or NULL if f is the last one. - */ -AVInputFormat *av_iformat_next(AVInputFormat *f); - -/** - * If f is NULL, returns the first registered output format, - * if f is non-NULL, returns the next registered output format after f - * or NULL if f is the last one. - */ -AVOutputFormat *av_oformat_next(AVOutputFormat *f); - -enum CodecID av_guess_image2_codec(const char *filename); - -/* XXX: Use automatic init with either ELF sections or C file parser */ -/* modules. */ - -/* utils.c */ -void av_register_input_format(AVInputFormat *format); -void av_register_output_format(AVOutputFormat *format); -#if LIBAVFORMAT_VERSION_MAJOR < 53 -attribute_deprecated AVOutputFormat *guess_stream_format(const char *short_name, - const char *filename, - const char *mime_type); - -/** - * @deprecated Use av_guess_format() instead. - */ -attribute_deprecated AVOutputFormat *guess_format(const char *short_name, - const char *filename, - const char *mime_type); -#endif - -/** - * Returns the output format in the list of registered output formats - * which best matches the provided parameters, or returns NULL if - * there is no match. - * - * @param short_name if non-NULL checks if short_name matches with the - * names of the registered formats - * @param filename if non-NULL checks if filename terminates with the - * extensions of the registered formats - * @param mime_type if non-NULL checks if mime_type matches with the - * MIME type of the registered formats - */ -AVOutputFormat *av_guess_format(const char *short_name, - const char *filename, - const char *mime_type); - -/** - * Guesses the codec ID based upon muxer and filename. - */ -enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, - const char *filename, const char *mime_type, - enum AVMediaType type); - -/** - * Sends a nice hexadecimal dump of a buffer to the specified file stream. - * - * @param f The file stream pointer where the dump should be sent to. - * @param buf buffer - * @param size buffer size - * - * @see av_hex_dump_log, av_pkt_dump, av_pkt_dump_log - */ -void av_hex_dump(FILE *f, uint8_t *buf, int size); - -/** - * Sends a nice hexadecimal dump of a buffer to the log. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param buf buffer - * @param size buffer size - * - * @see av_hex_dump, av_pkt_dump, av_pkt_dump_log - */ -void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size); - -/** - * Sends a nice dump of a packet to the specified file stream. - * - * @param f The file stream pointer where the dump should be sent to. - * @param pkt packet to dump - * @param dump_payload True if the payload must be displayed, too. - */ -void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); - -/** - * Sends a nice dump of a packet to the log. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param pkt packet to dump - * @param dump_payload True if the payload must be displayed, too. - */ -void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload); - -/** - * Initializes libavformat and registers all the muxers, demuxers and - * protocols. If you do not call this function, then you can select - * exactly which formats you want to support. - * - * @see av_register_input_format() - * @see av_register_output_format() - * @see av_register_protocol() - */ -void av_register_all(void); - -/** codec tag <-> codec id */ -enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); -unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id); - -/* media file input */ - -/** - * Finds AVInputFormat based on the short name of the input format. - */ -AVInputFormat *av_find_input_format(const char *short_name); - -/** - * Guesses the file format. - * - * @param is_opened Whether the file is already opened; determines whether - * demuxers with or without AVFMT_NOFILE are probed. - */ -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); - -/** - * Guesses the file format. - * - * @param is_opened Whether the file is already opened; determines whether - * demuxers with or without AVFMT_NOFILE are probed. - * @param score_max A probe score larger that this is required to accept a - * detection, the variable is set to the actual detection - * score afterwards. - * If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended - * to retry with a larger probe buffer. - */ -AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max); - -/** - * Allocates all the structures needed to read an input stream. - * This does not open the needed codecs for decoding the stream[s]. - */ -int av_open_input_stream(AVFormatContext **ic_ptr, - ByteIOContext *pb, const char *filename, - AVInputFormat *fmt, AVFormatParameters *ap); - -/** - * Opens a media file as input. The codecs are not opened. Only the file - * header (if present) is read. - * - * @param ic_ptr The opened media file handle is put here. - * @param filename filename to open - * @param fmt If non-NULL, force the file format to use. - * @param buf_size optional buffer size (zero if default is OK) - * @param ap Additional parameters needed when opening the file - * (NULL if default). - * @return 0 if OK, AVERROR_xxx otherwise - */ -int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, - AVInputFormat *fmt, - int buf_size, - AVFormatParameters *ap); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** - * @deprecated Use avformat_alloc_context() instead. - */ -attribute_deprecated AVFormatContext *av_alloc_format_context(void); -#endif - -/** - * Allocates an AVFormatContext. - * Can be freed with av_free() but do not forget to free everything you - * explicitly allocated as well! - */ -AVFormatContext *avformat_alloc_context(void); - -/** - * Reads packets of a media file to get stream information. This - * is useful for file formats with no headers such as MPEG. This - * function also computes the real framerate in case of MPEG-2 repeat - * frame mode. - * The logical file position is not changed by this function; - * examined packets may be buffered for later processing. - * - * @param ic media file handle - * @return >=0 if OK, AVERROR_xxx on error - * @todo Let the user decide somehow what information is needed so that - * we do not waste time getting stuff the user does not need. - */ -int av_find_stream_info(AVFormatContext *ic); - -/** - * Reads a transport packet from a media file. - * - * This function is obsolete and should never be used. - * Use av_read_frame() instead. - * - * @param s media file handle - * @param pkt is filled - * @return 0 if OK, AVERROR_xxx on error - */ -int av_read_packet(AVFormatContext *s, AVPacket *pkt); - -/** - * Returns the next frame of a stream. - * - * The returned packet is valid - * until the next av_read_frame() or until av_close_input_file() and - * must be freed with av_free_packet. For video, the packet contains - * exactly one frame. For audio, it contains an integer number of - * frames if each frame has a known fixed size (e.g. PCM or ADPCM - * data). If the audio frames have a variable size (e.g. MPEG audio), - * then it contains one frame. - * - * pkt->pts, pkt->dts and pkt->duration are always set to correct - * values in AVStream.time_base units (and guessed if the format cannot - * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format - * has B-frames, so it is better to rely on pkt->dts if you do not - * decompress the payload. - * - * @return 0 if OK, < 0 on error or end of file - */ -int av_read_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Seeks to the keyframe at timestamp. - * 'timestamp' in 'stream_index'. - * @param stream_index If stream_index is (-1), a default - * stream is selected, and timestamp is automatically converted - * from AV_TIME_BASE units to the stream specific time_base. - * @param timestamp Timestamp in AVStream.time_base units - * or, if no stream is specified, in AV_TIME_BASE units. - * @param flags flags which select direction and seeking mode - * @return >= 0 on success - */ -int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, - int flags); - -/** - * Seeks to timestamp ts. - * Seeking will be done so that the point from which all active streams - * can be presented successfully will be closest to ts and within min/max_ts. - * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. - * - * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and - * are the file position (this may not be supported by all demuxers). - * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames - * in the stream with stream_index (this may not be supported by all demuxers). - * Otherwise all timestamps are in units of the stream selected by stream_index - * or if stream_index is -1, in AV_TIME_BASE units. - * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as - * keyframes (this may not be supported by all demuxers). - * - * @param stream_index index of the stream which is used as time base reference - * @param min_ts smallest acceptable timestamp - * @param ts target timestamp - * @param max_ts largest acceptable timestamp - * @param flags flags - * @return >=0 on success, error code otherwise - * - * @NOTE This is part of the new seek API which is still under construction. - * Thus do not use this yet. It may change at any time, do not expect - * ABI compatibility yet! - */ -int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); - -/** - * Starts playing a network-based stream (e.g. RTSP stream) at the - * current position. - */ -int av_read_play(AVFormatContext *s); - -/** - * Pauses a network-based stream (e.g. RTSP stream). - * - * Use av_read_play() to resume it. - */ -int av_read_pause(AVFormatContext *s); - -/** - * Frees a AVFormatContext allocated by av_open_input_stream. - * @param s context to free - */ -void av_close_input_stream(AVFormatContext *s); - -/** - * Closes a media file (but not its codecs). - * - * @param s media file handle - */ -void av_close_input_file(AVFormatContext *s); - -/** - * Adds a new stream to a media file. - * - * Can only be called in the read_header() function. If the flag - * AVFMTCTX_NOHEADER is in the format context, then new streams - * can be added in read_packet too. - * - * @param s media file handle - * @param id file-format-dependent stream ID - */ -AVStream *av_new_stream(AVFormatContext *s, int id); -AVProgram *av_new_program(AVFormatContext *s, int id); - -/** - * Adds a new chapter. - * This function is NOT part of the public API - * and should ONLY be used by demuxers. - * - * @param s media file handle - * @param id unique ID for this chapter - * @param start chapter start time in time_base units - * @param end chapter end time in time_base units - * @param title chapter title - * - * @return AVChapter or NULL on error - */ -AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, - int64_t start, int64_t end, const char *title); - -/** - * Sets the pts for a given stream. - * - * @param s stream - * @param pts_wrap_bits number of bits effectively used by the pts - * (used for wrap control, 33 is the value for MPEG) - * @param pts_num numerator to convert to seconds (MPEG: 1) - * @param pts_den denominator to convert to seconds (MPEG: 90000) - */ -void av_set_pts_info(AVStream *s, int pts_wrap_bits, - unsigned int pts_num, unsigned int pts_den); - -#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward -#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes -#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes -#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number - -int av_find_default_stream_index(AVFormatContext *s); - -/** - * Gets the index for a specific timestamp. - * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond - * to the timestamp which is <= the requested one, if backward - * is 0, then it will be >= - * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise - * @return < 0 if no such timestamp could be found - */ -int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); - -/** - * Ensures the index uses less memory than the maximum specified in - * AVFormatContext.max_index_size by discarding entries if it grows - * too large. - * This function is not part of the public API and should only be called - * by demuxers. - */ -void ff_reduce_index(AVFormatContext *s, int stream_index); - -/** - * Adds an index entry into a sorted list. Updates the entry if the list - * already contains it. - * - * @param timestamp timestamp in the time base of the given stream - */ -int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, - int size, int distance, int flags); - -/** - * Does a binary search using av_index_search_timestamp() and - * AVCodec.read_timestamp(). - * This is not supposed to be called directly by a user application, - * but by demuxers. - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ -int av_seek_frame_binary(AVFormatContext *s, int stream_index, - int64_t target_ts, int flags); - -/** - * Updates cur_dts of all streams based on the given timestamp and AVStream. - * - * Stream ref_st unchanged, others set cur_dts in their native time base. - * Only needed for timestamp wrapping or if (dts not set and pts!=dts). - * @param timestamp new dts expressed in time_base of param ref_st - * @param ref_st reference stream giving time_base of param timestamp - */ -void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); - -/** - * Does a binary search using read_timestamp(). - * This is not supposed to be called directly by a user application, - * but by demuxers. - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ -int64_t av_gen_search(AVFormatContext *s, int stream_index, - int64_t target_ts, int64_t pos_min, - int64_t pos_max, int64_t pos_limit, - int64_t ts_min, int64_t ts_max, - int flags, int64_t *ts_ret, - int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); - -/** media file output */ -int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); - -/** - * Allocates the stream private data and writes the stream header to an - * output media file. - * - * @param s media file handle - * @return 0 if OK, AVERROR_xxx on error - */ -int av_write_header(AVFormatContext *s); - -/** - * Writes a packet to an output media file. - * - * The packet shall contain one audio or video frame. - * The packet must be correctly interleaved according to the container - * specification, if not then av_interleaved_write_frame must be used. - * - * @param s media file handle - * @param pkt The packet, which contains the stream_index, buf/buf_size, - dts/pts, ... - * @return < 0 on error, = 0 if OK, 1 if end of stream wanted - */ -int av_write_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Writes a packet to an output media file ensuring correct interleaving. - * - * The packet must contain one audio or video frame. - * If the packets are already correctly interleaved, the application should - * call av_write_frame() instead as it is slightly faster. It is also important - * to keep in mind that completely non-interleaved input will need huge amounts - * of memory to interleave with this, so it is preferable to interleave at the - * demuxer level. - * - * @param s media file handle - * @param pkt The packet, which contains the stream_index, buf/buf_size, - dts/pts, ... - * @return < 0 on error, = 0 if OK, 1 if end of stream wanted - */ -int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Interleaves a packet per dts in an output media file. - * - * Packets with pkt->destruct == av_destruct_packet will be freed inside this - * function, so they cannot be used after it. Note that calling av_free_packet() - * on them is still safe. - * - * @param s media file handle - * @param out the interleaved packet will be output here - * @param in the input packet - * @param flush 1 if no further packets are available as input and all - * remaining packets should be output - * @return 1 if a packet was output, 0 if no packet could be output, - * < 0 if an error occurred - */ -int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, - AVPacket *pkt, int flush); - -/** - * Writes the stream trailer to an output media file and frees the - * file private data. - * - * May only be called after a successful call to av_write_header. - * - * @param s media file handle - * @return 0 if OK, AVERROR_xxx on error - */ -int av_write_trailer(AVFormatContext *s); - -void dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** - * Parses width and height out of string str. - * @deprecated Use av_parse_video_frame_size instead. - */ -attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr, - const char *str); - -/** - * Converts framerate from a string to a fraction. - * @deprecated Use av_parse_video_frame_rate instead. - */ -attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base, - const char *arg); -#endif - -/** - * Parses datestr and returns a corresponding number of microseconds. - * @param datestr String representing a date or a duration. - * - If a date the syntax is: - * @code - * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} - * @endcode - * Time is local time unless Z is appended, in which case it is - * interpreted as UTC. - * If the year-month-day part is not specified it takes the current - * year-month-day. - * Returns the number of microseconds since 1st of January, 1970 up to - * the time of the parsed date or INT64_MIN if datestr cannot be - * successfully parsed. - * - If a duration the syntax is: - * @code - * [-]HH[:MM[:SS[.m...]]] - * [-]S+[.m...] - * @endcode - * Returns the number of microseconds contained in a time interval - * with the specified duration or INT64_MIN if datestr cannot be - * successfully parsed. - * @param duration Flag which tells how to interpret datestr, if - * not zero datestr is interpreted as a duration, otherwise as a - * date. - */ -int64_t parse_date(const char *datestr, int duration); - -/** Gets the current time in microseconds. */ -int64_t av_gettime(void); - -/* ffm-specific for ffserver */ -#define FFM_PACKET_SIZE 4096 -int64_t ffm_read_write_index(int fd); -int ffm_write_write_index(int fd, int64_t pos); -void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size); - -/** - * Attempts to find a specific tag in a URL. - * - * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. - * Return 1 if found. - */ -int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); - -/** - * Returns in 'buf' the path with '%d' replaced by a number. - * - * Also handles the '%0nd' format where 'n' is the total number - * of digits and '%%'. - * - * @param buf destination buffer - * @param buf_size destination buffer size - * @param path numbered sequence string - * @param number frame number - * @return 0 if OK, -1 on format error - */ -int av_get_frame_filename(char *buf, int buf_size, - const char *path, int number); - -/** - * Checks whether filename actually is a numbered sequence generator. - * - * @param filename possible numbered sequence string - * @return 1 if a valid numbered sequence string, 0 otherwise - */ -int av_filename_number_test(const char *filename); - -/** - * Generates an SDP for an RTP session. - * - * @param ac array of AVFormatContexts describing the RTP streams. If the - * array is composed by only one context, such context can contain - * multiple AVStreams (one AVStream per RTP stream). Otherwise, - * all the contexts in the array (an AVCodecContext per RTP stream) - * must contain only one AVStream. - * @param n_files number of AVCodecContexts contained in ac - * @param buff buffer where the SDP will be stored (must be allocated by - * the caller) - * @param size the size of the buffer - * @return 0 if OK, AVERROR_xxx on error - */ -int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size); - -/** - * Returns a positive value if the given filename has one of the given - * extensions, 0 otherwise. - * - * @param extensions a comma-separated list of filename extensions - */ -int av_match_ext(const char *filename, const char *extensions); - -#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/tizen/distrib/ffmpeg/include/libavformat/avio.h b/tizen/distrib/ffmpeg/include/libavformat/avio.h deleted file mode 100644 index 9ffe935..0000000 --- a/tizen/distrib/ffmpeg/include/libavformat/avio.h +++ /dev/null @@ -1,525 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVFORMAT_AVIO_H -#define AVFORMAT_AVIO_H - -/** - * @file - * unbuffered I/O operations - * - * @warning This file has to be considered an internal but installed - * header, so it should not be directly included in your projects. - */ - -#include - -#include "libavutil/common.h" - -/* unbuffered I/O */ - -/** - * URL Context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(URLContext) must not be used outside libav*. - */ -typedef struct URLContext { -#if LIBAVFORMAT_VERSION_MAJOR >= 53 - const AVClass *av_class; ///< information for av_log(). Set by url_open(). -#endif - struct URLProtocol *prot; - int flags; - int is_streamed; /**< true if streamed (no seek possible), default = false */ - int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ - void *priv_data; - char *filename; /**< specified URL */ -} URLContext; - -typedef struct URLPollEntry { - URLContext *handle; - int events; - int revents; -} URLPollEntry; - -#define URL_RDONLY 0 -#define URL_WRONLY 1 -#define URL_RDWR 2 - -typedef int URLInterruptCB(void); - -/** - * Creates an URLContext for accessing to the resource indicated by - * url, and opens it using the URLProtocol up. - * - * @param puc pointer to the location where, in case of success, the - * function puts the pointer to the created URLContext - * @param flags flags which control how the resource indicated by url - * is to be opened - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_open_protocol (URLContext **puc, struct URLProtocol *up, - const char *url, int flags); - -/** - * Creates an URLContext for accessing to the resource indicated by - * url, and opens it. - * - * @param puc pointer to the location where, in case of success, the - * function puts the pointer to the created URLContext - * @param flags flags which control how the resource indicated by url - * is to be opened - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_open(URLContext **h, const char *url, int flags); - -/** - * Reads up to size bytes from the resource accessed by h, and stores - * the read bytes in buf. - * - * @return The number of bytes actually read, or a negative value - * corresponding to an AVERROR code in case of error. A value of zero - * indicates that it is not possible to read more from the accessed - * resource (except if the value of the size argument is also zero). - */ -int url_read(URLContext *h, unsigned char *buf, int size); - -/** - * Read as many bytes as possible (up to size), calling the - * read function multiple times if necessary. - * Will also retry if the read function returns AVERROR(EAGAIN). - * This makes special short-read handling in applications - * unnecessary, if the return value is < size then it is - * certain there was either an error or the end of file was reached. - */ -int url_read_complete(URLContext *h, unsigned char *buf, int size); -int url_write(URLContext *h, unsigned char *buf, int size); - -/** - * Changes the position that will be used by the next read/write - * operation on the resource accessed by h. - * - * @param pos specifies the new position to set - * @param whence specifies how pos should be interpreted, it must be - * one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the - * current position), SEEK_END (seek from the end), or AVSEEK_SIZE - * (return the filesize of the requested resource, pos is ignored). - * @return a negative value corresponding to an AVERROR code in case - * of failure, or the resulting file position, measured in bytes from - * the beginning of the file. You can use this feature together with - * SEEK_CUR to read the current file position. - */ -int64_t url_seek(URLContext *h, int64_t pos, int whence); - -/** - * Closes the resource accessed by the URLContext h, and frees the - * memory used by it. - * - * @return a negative value if an error condition occurred, 0 - * otherwise - */ -int url_close(URLContext *h); - -/** - * Returns a non-zero value if the resource indicated by url - * exists, 0 otherwise. - */ -int url_exist(const char *url); - -int64_t url_filesize(URLContext *h); - -/** - * Return the file descriptor associated with this URL. For RTP, this - * will return only the RTP file descriptor, not the RTCP file descriptor. - * To get both, use rtp_get_file_handles(). - * - * @return the file descriptor associated with this URL, or <0 on error. - */ -int url_get_file_handle(URLContext *h); - -/** - * Return the maximum packet size associated to packetized file - * handle. If the file is not packetized (stream like HTTP or file on - * disk), then 0 is returned. - * - * @param h file handle - * @return maximum packet size in bytes - */ -int url_get_max_packet_size(URLContext *h); -void url_get_filename(URLContext *h, char *buf, int buf_size); - -/** - * The callback is called in blocking functions to test regulary if - * asynchronous interruption is needed. AVERROR(EINTR) is returned - * in this case by the interrupted function. 'NULL' means no interrupt - * callback is given. - */ -void url_set_interrupt_cb(URLInterruptCB *interrupt_cb); - -/* not implemented */ -int url_poll(URLPollEntry *poll_table, int n, int timeout); - -/** - * Pause and resume playing - only meaningful if using a network streaming - * protocol (e.g. MMS). - * @param pause 1 for pause, 0 for resume - */ -int av_url_read_pause(URLContext *h, int pause); - -/** - * Seek to a given timestamp relative to some component stream. - * Only meaningful if using a network streaming protocol (e.g. MMS.). - * @param stream_index The stream index that the timestamp is relative to. - * If stream_index is (-1) the timestamp should be in AV_TIME_BASE - * units from the beginning of the presentation. - * If a stream_index >= 0 is used and the protocol does not support - * seeking based on component streams, the call will fail with ENOTSUP. - * @param timestamp timestamp in AVStream.time_base units - * or if there is no stream specified then in AV_TIME_BASE units. - * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE - * and AVSEEK_FLAG_ANY. The protocol may silently ignore - * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will - * fail with ENOTSUP if used and not supported. - * @return >= 0 on success - * @see AVInputFormat::read_seek - */ -int64_t av_url_read_seek(URLContext *h, int stream_index, - int64_t timestamp, int flags); - -/** - * Passing this as the "whence" parameter to a seek function causes it to - * return the filesize without seeking anywhere. Supporting this is optional. - * If it is not supported then the seek function will return <0. - */ -#define AVSEEK_SIZE 0x10000 - -/** - * Oring this flag as into the "whence" parameter to a seek function causes it to - * seek by any means (like reopening and linear reading) or other normally unreasonble - * means that can be extreemly slow. - * This may be ignored by the seek code. - */ -#define AVSEEK_FORCE 0x20000 - -typedef struct URLProtocol { - const char *name; - int (*url_open)(URLContext *h, const char *url, int flags); - int (*url_read)(URLContext *h, unsigned char *buf, int size); - int (*url_write)(URLContext *h, unsigned char *buf, int size); - int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); - int (*url_close)(URLContext *h); - struct URLProtocol *next; - int (*url_read_pause)(URLContext *h, int pause); - int64_t (*url_read_seek)(URLContext *h, int stream_index, - int64_t timestamp, int flags); - int (*url_get_file_handle)(URLContext *h); -} URLProtocol; - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -extern URLProtocol *first_protocol; -#endif - -extern URLInterruptCB *url_interrupt_cb; - -/** - * If protocol is NULL, returns the first registered protocol, - * if protocol is non-NULL, returns the next registered protocol after protocol, - * or NULL if protocol is the last one. - */ -URLProtocol *av_protocol_next(URLProtocol *p); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** - * @deprecated Use av_register_protocol() instead. - */ -attribute_deprecated int register_protocol(URLProtocol *protocol); -#endif - -/** - * Registers the URLProtocol protocol. - */ -int av_register_protocol(URLProtocol *protocol); - -/** - * Bytestream IO Context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(ByteIOContext) must not be used outside libav*. - */ -typedef struct { - unsigned char *buffer; - int buffer_size; - unsigned char *buf_ptr, *buf_end; - void *opaque; - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); - int64_t (*seek)(void *opaque, int64_t offset, int whence); - int64_t pos; /**< position in the file of the current buffer */ - int must_flush; /**< true if the next seek should flush */ - int eof_reached; /**< true if eof reached */ - int write_flag; /**< true if open for writing */ - int is_streamed; - int max_packet_size; - unsigned long checksum; - unsigned char *checksum_ptr; - unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); - int error; ///< contains the error code or 0 if no error happened - int (*read_pause)(void *opaque, int pause); - int64_t (*read_seek)(void *opaque, int stream_index, - int64_t timestamp, int flags); -} ByteIOContext; - -int init_put_byte(ByteIOContext *s, - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)); -ByteIOContext *av_alloc_put_byte( - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)); - -void put_byte(ByteIOContext *s, int b); -void put_buffer(ByteIOContext *s, const unsigned char *buf, int size); -void put_le64(ByteIOContext *s, uint64_t val); -void put_be64(ByteIOContext *s, uint64_t val); -void put_le32(ByteIOContext *s, unsigned int val); -void put_be32(ByteIOContext *s, unsigned int val); -void put_le24(ByteIOContext *s, unsigned int val); -void put_be24(ByteIOContext *s, unsigned int val); -void put_le16(ByteIOContext *s, unsigned int val); -void put_be16(ByteIOContext *s, unsigned int val); -void put_tag(ByteIOContext *s, const char *tag); - -void put_strz(ByteIOContext *s, const char *buf); - -/** - * fseek() equivalent for ByteIOContext. - * @return new position or AVERROR. - */ -int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence); - -/** - * Skip given number of bytes forward. - * @param offset number of bytes - */ -void url_fskip(ByteIOContext *s, int64_t offset); - -/** - * ftell() equivalent for ByteIOContext. - * @return position or AVERROR. - */ -int64_t url_ftell(ByteIOContext *s); - -/** - * Gets the filesize. - * @return filesize or AVERROR - */ -int64_t url_fsize(ByteIOContext *s); - -/** - * feof() equivalent for ByteIOContext. - * @return non zero if and only if end of file - */ -int url_feof(ByteIOContext *s); - -int url_ferror(ByteIOContext *s); - -int av_url_read_fpause(ByteIOContext *h, int pause); -int64_t av_url_read_fseek(ByteIOContext *h, int stream_index, - int64_t timestamp, int flags); - -#define URL_EOF (-1) -/** @note return URL_EOF (-1) if EOF */ -int url_fgetc(ByteIOContext *s); - -/** @warning currently size is limited */ -#ifdef __GNUC__ -int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); -#else -int url_fprintf(ByteIOContext *s, const char *fmt, ...); -#endif - -/** @note unlike fgets, the EOL character is not returned and a whole - line is parsed. return NULL if first char read was EOF */ -char *url_fgets(ByteIOContext *s, char *buf, int buf_size); - -void put_flush_packet(ByteIOContext *s); - - -/** - * Reads size bytes from ByteIOContext into buf. - * @return number of bytes read or AVERROR - */ -int get_buffer(ByteIOContext *s, unsigned char *buf, int size); - -/** - * Reads size bytes from ByteIOContext into buf. - * This reads at most 1 packet. If that is not enough fewer bytes will be - * returned. - * @return number of bytes read or AVERROR - */ -int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size); - -/** @note return 0 if EOF, so you cannot use it if EOF handling is - necessary */ -int get_byte(ByteIOContext *s); -unsigned int get_le24(ByteIOContext *s); -unsigned int get_le32(ByteIOContext *s); -uint64_t get_le64(ByteIOContext *s); -unsigned int get_le16(ByteIOContext *s); - -char *get_strz(ByteIOContext *s, char *buf, int maxlen); -unsigned int get_be16(ByteIOContext *s); -unsigned int get_be24(ByteIOContext *s); -unsigned int get_be32(ByteIOContext *s); -uint64_t get_be64(ByteIOContext *s); - -uint64_t ff_get_v(ByteIOContext *bc); - -static inline int url_is_streamed(ByteIOContext *s) -{ - return s->is_streamed; -} - -/** - * Creates and initializes a ByteIOContext for accessing the - * resource referenced by the URLContext h. - * @note When the URLContext h has been opened in read+write mode, the - * ByteIOContext can be used only for writing. - * - * @param s Used to return the pointer to the created ByteIOContext. - * In case of failure the pointed to value is set to NULL. - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_fdopen(ByteIOContext **s, URLContext *h); - -/** @warning must be called before any I/O */ -int url_setbufsize(ByteIOContext *s, int buf_size); -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** Reset the buffer for reading or writing. - * @note Will drop any data currently in the buffer without transmitting it. - * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY - * to set up the buffer for writing. */ -int url_resetbuf(ByteIOContext *s, int flags); -#endif - -/** - * Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file. - * Used after probing to avoid seeking. - * Joins buf and s->buffer, taking any overlap into consideration. - * @note s->buffer must overlap with buf or they can't be joined and the function fails - * @note This function is NOT part of the public API - * - * @param s The read-only ByteIOContext to rewind - * @param buf The probe buffer containing the first buf_size bytes of the file - * @param buf_size The size of buf - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size); - -/** - * Creates and initializes a ByteIOContext for accessing the - * resource indicated by url. - * @note When the resource indicated by url has been opened in - * read+write mode, the ByteIOContext can be used only for writing. - * - * @param s Used to return the pointer to the created ByteIOContext. - * In case of failure the pointed to value is set to NULL. - * @param flags flags which control how the resource indicated by url - * is to be opened - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_fopen(ByteIOContext **s, const char *url, int flags); - -int url_fclose(ByteIOContext *s); -URLContext *url_fileno(ByteIOContext *s); - -/** - * Return the maximum packet size associated to packetized buffered file - * handle. If the file is not packetized (stream like http or file on - * disk), then 0 is returned. - * - * @param s buffered file handle - * @return maximum packet size in bytes - */ -int url_fget_max_packet_size(ByteIOContext *s); - -int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags); - -/** return the written or read size */ -int url_close_buf(ByteIOContext *s); - -/** - * Open a write only memory stream. - * - * @param s new IO context - * @return zero if no error. - */ -int url_open_dyn_buf(ByteIOContext **s); - -/** - * Open a write only packetized memory stream with a maximum packet - * size of 'max_packet_size'. The stream is stored in a memory buffer - * with a big endian 4 byte header giving the packet size in bytes. - * - * @param s new IO context - * @param max_packet_size maximum packet size (must be > 0) - * @return zero if no error. - */ -int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size); - -/** - * Return the written size and a pointer to the buffer. The buffer - * must be freed with av_free(). - * @param s IO context - * @param pbuffer pointer to a byte buffer - * @return the length of the byte buffer - */ -int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer); - -unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, - unsigned int len); -unsigned long get_checksum(ByteIOContext *s); -void init_checksum(ByteIOContext *s, - unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), - unsigned long checksum); - -/* udp.c */ -int udp_set_remote_url(URLContext *h, const char *uri); -int udp_get_local_port(URLContext *h); -#if (LIBAVFORMAT_VERSION_MAJOR <= 52) -int udp_get_file_handle(URLContext *h); -#endif - -#endif /* AVFORMAT_AVIO_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/adler32.h b/tizen/distrib/ffmpeg/include/libavutil/adler32.h deleted file mode 100644 index 9626c80..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/adler32.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * copyright (c) 2006 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ADLER32_H -#define AVUTIL_ADLER32_H - -#include -#include "attributes.h" - -unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, - unsigned int len) av_pure; - -#endif /* AVUTIL_ADLER32_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/attributes.h b/tizen/distrib/ffmpeg/include/libavutil/attributes.h deleted file mode 100644 index da45234..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/attributes.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Macro definitions for various function/variable attributes - */ - -#ifndef AVUTIL_ATTRIBUTES_H -#define AVUTIL_ATTRIBUTES_H - -#ifdef __GNUC__ -# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y) -#else -# define AV_GCC_VERSION_AT_LEAST(x,y) 0 -#endif - -#ifndef av_always_inline -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_always_inline __attribute__((always_inline)) inline -#else -# define av_always_inline inline -#endif -#endif - -#ifndef av_noinline -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_noinline __attribute__((noinline)) -#else -# define av_noinline -#endif -#endif - -#ifndef av_pure -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_pure __attribute__((pure)) -#else -# define av_pure -#endif -#endif - -#ifndef av_const -#if AV_GCC_VERSION_AT_LEAST(2,6) -# define av_const __attribute__((const)) -#else -# define av_const -#endif -#endif - -#ifndef av_cold -#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) -# define av_cold __attribute__((cold)) -#else -# define av_cold -#endif -#endif - -#ifndef av_flatten -#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,1) -# define av_flatten __attribute__((flatten)) -#else -# define av_flatten -#endif -#endif - -#ifndef attribute_deprecated -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define attribute_deprecated __attribute__((deprecated)) -#else -# define attribute_deprecated -#endif -#endif - -#ifndef av_unused -#if defined(__GNUC__) -# define av_unused __attribute__((unused)) -#else -# define av_unused -#endif -#endif - -#ifndef av_uninit -#if defined(__GNUC__) && !defined(__ICC) -# define av_uninit(x) x=x -#else -# define av_uninit(x) x -#endif -#endif - -#ifdef __GNUC__ -# define av_builtin_constant_p __builtin_constant_p -#else -# define av_builtin_constant_p(x) 0 -#endif - -#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/avconfig.h b/tizen/distrib/ffmpeg/include/libavutil/avconfig.h deleted file mode 100644 index b028bb4..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/avconfig.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Generated by ffconf */ -#ifndef AVUTIL_AVCONFIG_H -#define AVUTIL_AVCONFIG_H -#define AV_HAVE_BIGENDIAN 0 -#endif /* AVUTIL_AVCONFIG_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/avstring.h b/tizen/distrib/ffmpeg/include/libavutil/avstring.h deleted file mode 100644 index 01c2391..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/avstring.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2007 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AVSTRING_H -#define AVUTIL_AVSTRING_H - -#include - -/** - * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to - * the address of the first character in str after the prefix. - * - * @param str input string - * @param pfx prefix to test - * @param ptr updated if the prefix is matched inside str - * @return non-zero if the prefix matches, zero otherwise - */ -int av_strstart(const char *str, const char *pfx, const char **ptr); - -/** - * Return non-zero if pfx is a prefix of str independent of case. If - * it is, *ptr is set to the address of the first character in str - * after the prefix. - * - * @param str input string - * @param pfx prefix to test - * @param ptr updated if the prefix is matched inside str - * @return non-zero if the prefix matches, zero otherwise - */ -int av_stristart(const char *str, const char *pfx, const char **ptr); - -/** - * Locate the first case-independent occurrence in the string haystack - * of the string needle. A zero-length string needle is considered to - * match at the start of haystack. - * - * This function is a case-insensitive version of the standard strstr(). - * - * @param haystack string to search in - * @param needle string to search for - * @return pointer to the located match within haystack - * or a null pointer if no match - */ -char *av_stristr(const char *haystack, const char *needle); - -/** - * Copy the string src to dst, but no more than size - 1 bytes, and - * null-terminate dst. - * - * This function is the same as BSD strlcpy(). - * - * @param dst destination buffer - * @param src source string - * @param size size of destination buffer - * @return the length of src - * - * WARNING: since the return value is the length of src, src absolutely - * _must_ be a properly 0-terminated string, otherwise this will read beyond - * the end of the buffer and possibly crash. - */ -size_t av_strlcpy(char *dst, const char *src, size_t size); - -/** - * Append the string src to the string dst, but to a total length of - * no more than size - 1 bytes, and null-terminate dst. - * - * This function is similar to BSD strlcat(), but differs when - * size <= strlen(dst). - * - * @param dst destination buffer - * @param src source string - * @param size size of destination buffer - * @return the total length of src and dst - * - * WARNING: since the return value use the length of src and dst, these absolutely - * _must_ be a properly 0-terminated strings, otherwise this will read beyond - * the end of the buffer and possibly crash. - */ -size_t av_strlcat(char *dst, const char *src, size_t size); - -/** - * Append output to a string, according to a format. Never write out of - * the destination buffer, and always put a terminating 0 within - * the buffer. - * @param dst destination buffer (string to which the output is - * appended) - * @param size total size of the destination buffer - * @param fmt printf-compatible format string, specifying how the - * following parameters are used - * @return the length of the string that would have been generated - * if enough space had been available - */ -size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...); - -/** - * Convert a number to a av_malloced string. - */ -char *av_d2str(double d); - -#endif /* AVUTIL_AVSTRING_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/avutil.h b/tizen/distrib/ffmpeg/include/libavutil/avutil.h deleted file mode 100644 index e9e07b9..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/avutil.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AVUTIL_H -#define AVUTIL_AVUTIL_H - -/** - * @file - * external API header - */ - - -#define AV_STRINGIFY(s) AV_TOSTRING(s) -#define AV_TOSTRING(s) #s - -#define AV_GLUE(a, b) a ## b -#define AV_JOIN(a, b) AV_GLUE(a, b) - -#define AV_PRAGMA(s) _Pragma(#s) - -#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) -#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c -#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) - -#define LIBAVUTIL_VERSION_MAJOR 50 -#define LIBAVUTIL_VERSION_MINOR 15 -#define LIBAVUTIL_VERSION_MICRO 1 - -#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ - LIBAVUTIL_VERSION_MINOR, \ - LIBAVUTIL_VERSION_MICRO) -#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ - LIBAVUTIL_VERSION_MINOR, \ - LIBAVUTIL_VERSION_MICRO) -#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT - -#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) - -/** - * Returns the LIBAVUTIL_VERSION_INT constant. - */ -unsigned avutil_version(void); - -/** - * Returns the libavutil build-time configuration. - */ -const char *avutil_configuration(void); - -/** - * Returns the libavutil license. - */ -const char *avutil_license(void); - -enum AVMediaType { - AVMEDIA_TYPE_UNKNOWN = -1, - AVMEDIA_TYPE_VIDEO, - AVMEDIA_TYPE_AUDIO, - AVMEDIA_TYPE_DATA, - AVMEDIA_TYPE_SUBTITLE, - AVMEDIA_TYPE_ATTACHMENT, - AVMEDIA_TYPE_NB -}; - -#include "common.h" -#include "error.h" -#include "mathematics.h" -#include "rational.h" -#include "intfloat_readwrite.h" -#include "log.h" -#include "pixfmt.h" - -#endif /* AVUTIL_AVUTIL_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/base64.h b/tizen/distrib/ffmpeg/include/libavutil/base64.h deleted file mode 100644 index 103860e..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/base64.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_BASE64_H -#define AVUTIL_BASE64_H - -#include - -/** - * Decodes the base64-encoded string in in and puts the decoded - * data in out. - * - * @param out_size size in bytes of the out buffer, it should be at - * least 3/4 of the length of in - * @return the number of bytes written, or a negative value in case of - * error - */ -int av_base64_decode(uint8_t *out, const char *in, int out_size); - -/** - * Encodes in base64 the data in in and puts the resulting string - * in out. - * - * @param out_size size in bytes of the out string, it should be at - * least ((in_size + 2) / 3) * 4 + 1 - * @param in_size size in bytes of the in buffer - * @return the string containing the encoded data, or NULL in case of - * error - */ -char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size); - -#endif /* AVUTIL_BASE64_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/common.h b/tizen/distrib/ffmpeg/include/libavutil/common.h deleted file mode 100644 index 4aa00a9..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/common.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * common internal and external API header - */ - -#ifndef AVUTIL_COMMON_H -#define AVUTIL_COMMON_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "attributes.h" - -//rounded division & shift -#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) -/* assume b>0 */ -#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) -#define FFSIGN(a) ((a) > 0 ? 1 : -1) - -#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) -#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) -#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) -#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) - -#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) -#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) -#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) - -/* misc math functions */ -extern const uint8_t ff_log2_tab[256]; - -extern const uint8_t av_reverse[256]; - -static inline av_const int av_log2_c(unsigned int v) -{ - int n = 0; - if (v & 0xffff0000) { - v >>= 16; - n += 16; - } - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -static inline av_const int av_log2_16bit_c(unsigned int v) -{ - int n = 0; - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -#ifdef HAVE_AV_CONFIG_H -# include "config.h" -# include "intmath.h" -#endif - -#ifndef av_log2 -# define av_log2 av_log2_c -#endif -#ifndef av_log2_16bit -# define av_log2_16bit av_log2_16bit_c -#endif - -/** - * Clips a signed integer value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static inline av_const int av_clip(int a, int amin, int amax) -{ - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** - * Clips a signed integer value into the 0-255 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const uint8_t av_clip_uint8(int a) -{ - if (a&(~0xFF)) return (-a)>>31; - else return a; -} - -/** - * Clips a signed integer value into the 0-65535 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const uint16_t av_clip_uint16(int a) -{ - if (a&(~0xFFFF)) return (-a)>>31; - else return a; -} - -/** - * Clips a signed integer value into the -32768,32767 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const int16_t av_clip_int16(int a) -{ - if ((a+0x8000) & ~0xFFFF) return (a>>31) ^ 0x7FFF; - else return a; -} - -/** - * Clips a signed 64-bit integer value into the -2147483648,2147483647 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const int32_t av_clipl_int32(int64_t a) -{ - if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF; - else return a; -} - -/** - * Clips a float value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static inline av_const float av_clipf(float a, float amin, float amax) -{ - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** Computes ceil(log2(x)). - * @param x value used to compute ceil(log2(x)) - * @return computed ceiling of log2(x) - */ -static inline av_const int av_ceil_log2(int x) -{ - return av_log2((x - 1) << 1); -} - -#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) -#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) - -/*! - * \def GET_UTF8(val, GET_BYTE, ERROR) - * Converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form - * \param val is the output and should be of type uint32_t. It holds the converted - * UCS-4 character and should be a left value. - * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be - * a function or a statement whose return value or evaluated value is of type - * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range, - * and up to 7 times in the general case. - * \param ERROR action that should be taken when an invalid UTF-8 byte is returned - * from GET_BYTE. It should be a statement that jumps out of the macro, - * like exit(), goto, return, break, or continue. - */ -#define GET_UTF8(val, GET_BYTE, ERROR)\ - val= GET_BYTE;\ - {\ - int ones= 7 - av_log2(val ^ 255);\ - if(ones==1)\ - ERROR\ - val&= 127>>ones;\ - while(--ones > 0){\ - int tmp= GET_BYTE - 128;\ - if(tmp>>6)\ - ERROR\ - val= (val<<6) + tmp;\ - }\ - } - -/*! - * \def GET_UTF16(val, GET_16BIT, ERROR) - * Converts a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form - * \param val is the output and should be of type uint32_t. It holds the converted - * UCS-4 character and should be a left value. - * \param GET_16BIT gets two bytes of UTF-16 encoded data converted to native endianness. - * It can be a function or a statement whose return value or evaluated value is of type - * uint16_t. It will be executed up to 2 times. - * \param ERROR action that should be taken when an invalid UTF-16 surrogate is - * returned from GET_BYTE. It should be a statement that jumps out of the macro, - * like exit(), goto, return, break, or continue. - */ -#define GET_UTF16(val, GET_16BIT, ERROR)\ - val = GET_16BIT;\ - {\ - unsigned int hi = val - 0xD800;\ - if (hi < 0x800) {\ - val = GET_16BIT - 0xDC00;\ - if (val > 0x3FFU || hi > 0x3FFU)\ - ERROR\ - val += (hi<<10) + 0x10000;\ - }\ - }\ - -/*! - * \def PUT_UTF8(val, tmp, PUT_BYTE) - * Converts a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). - * \param val is an input-only argument and should be of type uint32_t. It holds - * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If - * val is given as a function it is executed only once. - * \param tmp is a temporary variable and should be of type uint8_t. It - * represents an intermediate value during conversion that is to be - * output by PUT_BYTE. - * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. - * It could be a function or a statement, and uses tmp as the input byte. - * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be - * executed up to 4 times for values in the valid UTF-8 range and up to - * 7 times in the general case, depending on the length of the converted - * Unicode character. - */ -#define PUT_UTF8(val, tmp, PUT_BYTE)\ - {\ - int bytes, shift;\ - uint32_t in = val;\ - if (in < 0x80) {\ - tmp = in;\ - PUT_BYTE\ - } else {\ - bytes = (av_log2(in) + 4) / 5;\ - shift = (bytes - 1) * 6;\ - tmp = (256 - (256 >> bytes)) | (in >> shift);\ - PUT_BYTE\ - while (shift >= 6) {\ - shift -= 6;\ - tmp = 0x80 | ((in >> shift) & 0x3f);\ - PUT_BYTE\ - }\ - }\ - } - -/*! - * \def PUT_UTF16(val, tmp, PUT_16BIT) - * Converts a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). - * \param val is an input-only argument and should be of type uint32_t. It holds - * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If - * val is given as a function it is executed only once. - * \param tmp is a temporary variable and should be of type uint16_t. It - * represents an intermediate value during conversion that is to be - * output by PUT_16BIT. - * \param PUT_16BIT writes the converted UTF-16 data to any proper destination - * in desired endianness. It could be a function or a statement, and uses tmp - * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" - * PUT_BYTE will be executed 1 or 2 times depending on input character. - */ -#define PUT_UTF16(val, tmp, PUT_16BIT)\ - {\ - uint32_t in = val;\ - if (in < 0x10000) {\ - tmp = in;\ - PUT_16BIT\ - } else {\ - tmp = 0xD800 | ((in - 0x10000) >> 10);\ - PUT_16BIT\ - tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ - PUT_16BIT\ - }\ - }\ - - - -#include "mem.h" - -#ifdef HAVE_AV_CONFIG_H -# include "internal.h" -#endif /* HAVE_AV_CONFIG_H */ - -#endif /* AVUTIL_COMMON_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/crc.h b/tizen/distrib/ffmpeg/include/libavutil/crc.h deleted file mode 100644 index 6c0baab..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/crc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_CRC_H -#define AVUTIL_CRC_H - -#include -#include -#include "attributes.h" - -typedef uint32_t AVCRC; - -typedef enum { - AV_CRC_8_ATM, - AV_CRC_16_ANSI, - AV_CRC_16_CCITT, - AV_CRC_32_IEEE, - AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */ - AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */ -}AVCRCId; - -int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size); -const AVCRC *av_crc_get_table(AVCRCId crc_id); -uint32_t av_crc(const AVCRC *ctx, uint32_t start_crc, const uint8_t *buffer, size_t length) av_pure; - -#endif /* AVUTIL_CRC_H */ - diff --git a/tizen/distrib/ffmpeg/include/libavutil/error.h b/tizen/distrib/ffmpeg/include/libavutil/error.h deleted file mode 100644 index 13a9a35..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/error.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * error code definitions - */ - -#ifndef AVUTIL_ERROR_H -#define AVUTIL_ERROR_H - -#include -#include "avutil.h" - -/* error handling */ -#if EDOM > 0 -#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. -#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. -#else -/* Some platforms have E* and errno already negated. */ -#define AVERROR(e) (e) -#define AVUNERROR(e) (e) -#endif - -#if LIBAVUTIL_VERSION_MAJOR < 51 -#define AVERROR_INVALIDDATA AVERROR(EINVAL) ///< Invalid data found when processing input -#define AVERROR_IO AVERROR(EIO) ///< I/O error -#define AVERROR_NOENT AVERROR(ENOENT) ///< No such file or directory -#define AVERROR_NOFMT AVERROR(EILSEQ) ///< Unknown format -#define AVERROR_NOMEM AVERROR(ENOMEM) ///< Not enough memory -#define AVERROR_NOTSUPP AVERROR(ENOSYS) ///< Operation not supported -#define AVERROR_NUMEXPECTED AVERROR(EDOM) ///< Number syntax expected in filename -#define AVERROR_UNKNOWN AVERROR(EINVAL) ///< Unknown error -#endif - -#define AVERROR_EOF AVERROR(EPIPE) ///< End of file - -#define AVERROR_PATCHWELCOME (-MKTAG('P','A','W','E')) ///< Not yet implemented in FFmpeg, patches welcome - -#if LIBAVUTIL_VERSION_MAJOR > 50 -#define AVERROR_INVALIDDATA (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input -#define AVERROR_NUMEXPECTED (-MKTAG('N','U','E','X')) ///< Number syntax expected in filename -#endif - -/** - * Puts a description of the AVERROR code errnum in errbuf. - * In case of failure the global variable errno is set to indicate the - * error. Even in case of failure av_strerror() will print a generic - * error message indicating the errnum provided to errbuf. - * - * @param errbuf_size the size in bytes of errbuf - * @return 0 on success, a negative value if a description for errnum - * cannot be found - */ -int av_strerror(int errnum, char *errbuf, size_t errbuf_size); - -#endif /* AVUTIL_ERROR_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/fifo.h b/tizen/distrib/ffmpeg/include/libavutil/fifo.h deleted file mode 100644 index fb1ed47..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/fifo.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * a very simple circular buffer FIFO implementation - */ - -#ifndef AVUTIL_FIFO_H -#define AVUTIL_FIFO_H - -#include - -typedef struct AVFifoBuffer { - uint8_t *buffer; - uint8_t *rptr, *wptr, *end; - uint32_t rndx, wndx; -} AVFifoBuffer; - -/** - * Initializes an AVFifoBuffer. - * @param size of FIFO - * @return AVFifoBuffer or NULL in case of memory allocation failure - */ -AVFifoBuffer *av_fifo_alloc(unsigned int size); - -/** - * Frees an AVFifoBuffer. - * @param *f AVFifoBuffer to free - */ -void av_fifo_free(AVFifoBuffer *f); - -/** - * Resets the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied. - * @param *f AVFifoBuffer to reset - */ -void av_fifo_reset(AVFifoBuffer *f); - -/** - * Returns the amount of data in bytes in the AVFifoBuffer, that is the - * amount of data you can read from it. - * @param *f AVFifoBuffer to read from - * @return size - */ -int av_fifo_size(AVFifoBuffer *f); - -/** - * Returns the amount of space in bytes in the AVFifoBuffer, that is the - * amount of data you can write into it. - * @param *f AVFifoBuffer to write into - * @return size - */ -int av_fifo_space(AVFifoBuffer *f); - -/** - * Feeds data from an AVFifoBuffer to a user-supplied callback. - * @param *f AVFifoBuffer to read from - * @param buf_size number of bytes to read - * @param *func generic read function - * @param *dest data destination - */ -int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); - -/** - * Feeds data from a user-supplied callback to an AVFifoBuffer. - * @param *f AVFifoBuffer to write to - * @param *src data source; non-const since it may be used as a - * modifiable context by the function defined in func - * @param size number of bytes to write - * @param *func generic write function; the first parameter is src, - * the second is dest_buf, the third is dest_buf_size. - * func must return the number of bytes written to dest_buf, or <= 0 to - * indicate no more data available to write. - * If func is NULL, src is interpreted as a simple byte array for source data. - * @return the number of bytes written to the FIFO - */ -int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)); - -/** - * Resizes an AVFifoBuffer. - * @param *f AVFifoBuffer to resize - * @param size new AVFifoBuffer size in bytes - * @return <0 for failure, >=0 otherwise - */ -int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size); - -/** - * Reads and discards the specified amount of data from an AVFifoBuffer. - * @param *f AVFifoBuffer to read from - * @param size amount of data to read in bytes - */ -void av_fifo_drain(AVFifoBuffer *f, int size); - -static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs) -{ - uint8_t *ptr = f->rptr + offs; - if (ptr >= f->end) - ptr -= f->end - f->buffer; - return *ptr; -} -#endif /* AVUTIL_FIFO_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/intfloat_readwrite.h b/tizen/distrib/ffmpeg/include/libavutil/intfloat_readwrite.h deleted file mode 100644 index 1b80fc6..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/intfloat_readwrite.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_INTFLOAT_READWRITE_H -#define AVUTIL_INTFLOAT_READWRITE_H - -#include -#include "attributes.h" - -/* IEEE 80 bits extended float */ -typedef struct AVExtFloat { - uint8_t exponent[2]; - uint8_t mantissa[8]; -} AVExtFloat; - -double av_int2dbl(int64_t v) av_const; -float av_int2flt(int32_t v) av_const; -double av_ext2dbl(const AVExtFloat ext) av_const; -int64_t av_dbl2int(double d) av_const; -int32_t av_flt2int(float d) av_const; -AVExtFloat av_dbl2ext(double d) av_const; - -#endif /* AVUTIL_INTFLOAT_READWRITE_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/log.h b/tizen/distrib/ffmpeg/include/libavutil/log.h deleted file mode 100644 index 1c3e490..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/log.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LOG_H -#define AVUTIL_LOG_H - -#include -#include "avutil.h" - -/** - * Describes the class of an AVClass context structure. That is an - * arbitrary struct of which the first field is a pointer to an - * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). - */ -typedef struct { - /** - * The name of the class; usually it is the same name as the - * context structure type to which the AVClass is associated. - */ - const char* class_name; - - /** - * A pointer to a function which returns the name of a context - * instance ctx associated with the class. - */ - const char* (*item_name)(void* ctx); - - /** - * a pointer to the first option specified in the class if any or NULL - * - * @see av_set_default_options() - */ - const struct AVOption *option; - - /** - * LIBAVUTIL_VERSION with which this structure was created. - * This is used to allow fields to be added without requiring major - * version bumps everywhere. - */ - - int version; -} AVClass; - -/* av_log API */ - -#define AV_LOG_QUIET -8 - -/** - * Something went really wrong and we will crash now. - */ -#define AV_LOG_PANIC 0 - -/** - * Something went wrong and recovery is not possible. - * For example, no header was found for a format which depends - * on headers or an illegal combination of parameters is used. - */ -#define AV_LOG_FATAL 8 - -/** - * Something went wrong and cannot losslessly be recovered. - * However, not all future data is affected. - */ -#define AV_LOG_ERROR 16 - -/** - * Something somehow does not look correct. This may or may not - * lead to problems. An example would be the use of '-vstrict -2'. - */ -#define AV_LOG_WARNING 24 - -#define AV_LOG_INFO 32 -#define AV_LOG_VERBOSE 40 - -/** - * Stuff which is only useful for libav* developers. - */ -#define AV_LOG_DEBUG 48 - -/** - * Sends the specified message to the log if the level is less than or equal - * to the current av_log_level. By default, all logging messages are sent to - * stderr. This behavior can be altered by setting a different av_vlog callback - * function. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - * @see av_vlog - */ -#ifdef __GNUC__ -void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); -#else -void av_log(void*, int level, const char *fmt, ...); -#endif - -void av_vlog(void*, int level, const char *fmt, va_list); -int av_log_get_level(void); -void av_log_set_level(int); -void av_log_set_callback(void (*)(void*, int, const char*, va_list)); -void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); - -#endif /* AVUTIL_LOG_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/lzo.h b/tizen/distrib/ffmpeg/include/libavutil/lzo.h deleted file mode 100644 index 6788054..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/lzo.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * LZO 1x decompression - * copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LZO_H -#define AVUTIL_LZO_H - -#include - -/** \defgroup errflags Error flags returned by av_lzo1x_decode - * \{ */ -//! end of the input buffer reached before decoding finished -#define AV_LZO_INPUT_DEPLETED 1 -//! decoded data did not fit into output buffer -#define AV_LZO_OUTPUT_FULL 2 -//! a reference to previously decoded data was wrong -#define AV_LZO_INVALID_BACKPTR 4 -//! a non-specific error in the compressed bitstream -#define AV_LZO_ERROR 8 -/** \} */ - -#define AV_LZO_INPUT_PADDING 8 -#define AV_LZO_OUTPUT_PADDING 12 - -/** - * \brief Decodes LZO 1x compressed data. - * \param out output buffer - * \param outlen size of output buffer, number of bytes left are returned here - * \param in input buffer - * \param inlen size of input buffer, number of bytes left are returned here - * \return 0 on success, otherwise a combination of the error flags above - * - * Make sure all buffers are appropriately padded, in must provide - * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes. - */ -int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen); - -/** - * \brief deliberately overlapping memcpy implementation - * \param dst destination buffer; must be padded with 12 additional bytes - * \param back how many bytes back we start (the initial size of the overlapping window) - * \param cnt number of bytes to copy, must be >= 0 - * - * cnt > back is valid, this will copy the bytes we just copied, - * thus creating a repeating pattern with a period length of back. - */ -void av_memcpy_backptr(uint8_t *dst, int back, int cnt); - -#endif /* AVUTIL_LZO_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/mathematics.h b/tizen/distrib/ffmpeg/include/libavutil/mathematics.h deleted file mode 100644 index e198aef..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/mathematics.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_MATHEMATICS_H -#define AVUTIL_MATHEMATICS_H - -#include -#include -#include "attributes.h" -#include "rational.h" - -#ifndef M_E -#define M_E 2.7182818284590452354 /* e */ -#endif -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 /* log_e 2 */ -#endif -#ifndef M_LN10 -#define M_LN10 2.30258509299404568402 /* log_e 10 */ -#endif -#ifndef M_LOG2_10 -#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ -#endif -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif -#ifndef M_SQRT1_2 -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ -#endif -#ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#endif -#ifndef NAN -#define NAN (0.0/0.0) -#endif -#ifndef INFINITY -#define INFINITY (1.0/0.0) -#endif - -enum AVRounding { - AV_ROUND_ZERO = 0, ///< Round toward zero. - AV_ROUND_INF = 1, ///< Round away from zero. - AV_ROUND_DOWN = 2, ///< Round toward -infinity. - AV_ROUND_UP = 3, ///< Round toward +infinity. - AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. -}; - -/** - * Returns the greatest common divisor of a and b. - * If both a and b are 0 or either or both are <0 then behavior is - * undefined. - */ -int64_t av_const av_gcd(int64_t a, int64_t b); - -/** - * Rescales a 64-bit integer with rounding to nearest. - * A simple a*b/c isn't possible as it can overflow. - */ -int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; - -/** - * Rescales a 64-bit integer with specified rounding. - * A simple a*b/c isn't possible as it can overflow. - */ -int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const; - -/** - * Rescales a 64-bit integer by 2 rational numbers. - */ -int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; - -/** - * Compares 2 timestamps each in its own timebases. - * The result of the function is undefined if one of the timestamps - * is outside the int64_t range when represented in the others timebase. - * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position - */ -int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); - - -#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/md5.h b/tizen/distrib/ffmpeg/include/libavutil/md5.h deleted file mode 100644 index 969202a..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/md5.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_MD5_H -#define AVUTIL_MD5_H - -#include - -extern const int av_md5_size; - -struct AVMD5; - -void av_md5_init(struct AVMD5 *ctx); -void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len); -void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); -void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len); - -#endif /* AVUTIL_MD5_H */ - diff --git a/tizen/distrib/ffmpeg/include/libavutil/mem.h b/tizen/distrib/ffmpeg/include/libavutil/mem.h deleted file mode 100644 index 1488792..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/mem.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * memory handling functions - */ - -#ifndef AVUTIL_MEM_H -#define AVUTIL_MEM_H - -#include "attributes.h" - -#if defined(__ICC) || defined(__SUNPRO_C) - #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v - #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v -#elif defined(__TI_COMPILER_VERSION__) - #define DECLARE_ALIGNED(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - t __attribute__((aligned(n))) v - #define DECLARE_ASM_CONST(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - static const t __attribute__((aligned(n))) v -#elif defined(__GNUC__) - #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v - #define DECLARE_ASM_CONST(n,t,v) static const t attribute_used __attribute__ ((aligned (n))) v -#elif defined(_MSC_VER) - #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v - #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v -#else - #define DECLARE_ALIGNED(n,t,v) t v - #define DECLARE_ASM_CONST(n,t,v) static const t v -#endif - -#if AV_GCC_VERSION_AT_LEAST(3,1) - #define av_malloc_attrib __attribute__((__malloc__)) -#else - #define av_malloc_attrib -#endif - -#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) - #define av_alloc_size(n) __attribute__((alloc_size(n))) -#else - #define av_alloc_size(n) -#endif - -/** - * Allocates a block of size bytes with alignment suitable for all - * memory accesses (including vectors if available on the CPU). - * @param size Size in bytes for the memory block to be allocated. - * @return Pointer to the allocated block, NULL if the block cannot - * be allocated. - * @see av_mallocz() - */ -void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1); - -/** - * Allocates or reallocates a block of memory. - * If ptr is NULL and size > 0, allocates a new block. If - * size is zero, frees the memory block pointed to by ptr. - * @param size Size in bytes for the memory block to be allocated or - * reallocated. - * @param ptr Pointer to a memory block already allocated with - * av_malloc(z)() or av_realloc() or NULL. - * @return Pointer to a newly reallocated block or NULL if the block - * cannot be reallocated or the function is used to free the memory block. - * @see av_fast_realloc() - */ -void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2); - -/** - * Frees a memory block which has been allocated with av_malloc(z)() or - * av_realloc(). - * @param ptr Pointer to the memory block which should be freed. - * @note ptr = NULL is explicitly allowed. - * @note It is recommended that you use av_freep() instead. - * @see av_freep() - */ -void av_free(void *ptr); - -/** - * Allocates a block of size bytes with alignment suitable for all - * memory accesses (including vectors if available on the CPU) and - * zeroes all the bytes of the block. - * @param size Size in bytes for the memory block to be allocated. - * @return Pointer to the allocated block, NULL if it cannot be allocated. - * @see av_malloc() - */ -void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1); - -/** - * Duplicates the string s. - * @param s string to be duplicated - * @return Pointer to a newly allocated string containing a - * copy of s or NULL if the string cannot be allocated. - */ -char *av_strdup(const char *s) av_malloc_attrib; - -/** - * Frees a memory block which has been allocated with av_malloc(z)() or - * av_realloc() and set the pointer pointing to it to NULL. - * @param ptr Pointer to the pointer to the memory block which should - * be freed. - * @see av_free() - */ -void av_freep(void *ptr); - -#endif /* AVUTIL_MEM_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/pixdesc.h b/tizen/distrib/ffmpeg/include/libavutil/pixdesc.h deleted file mode 100644 index 8e4c85d..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/pixdesc.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * pixel format descriptor - * Copyright (c) 2009 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PIXDESC_H -#define AVUTIL_PIXDESC_H - -#include - -typedef struct AVComponentDescriptor{ - uint16_t plane :2; ///< which of the 4 planes contains the component - - /** - * Number of elements between 2 horizontally consecutive pixels minus 1. - * Elements are bits for bitstream formats, bytes otherwise. - */ - uint16_t step_minus1 :3; - - /** - * Number of elements before the component of the first pixel plus 1. - * Elements are bits for bitstream formats, bytes otherwise. - */ - uint16_t offset_plus1 :3; - uint16_t shift :3; ///< number of least significant bits that must be shifted away to get the value - uint16_t depth_minus1 :4; ///< number of bits in the component minus 1 -}AVComponentDescriptor; - -/** - * Descriptor that unambiguously describes how the bits of a pixel are - * stored in the up to 4 data planes of an image. It also stores the - * subsampling factors and number of components. - * - * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV - * and all the YUV variants) AVPixFmtDescriptor just stores how values - * are stored not what these values represent. - */ -typedef struct AVPixFmtDescriptor{ - const char *name; - uint8_t nb_components; ///< The number of components each pixel has, (1-4) - - /** - * Amount to shift the luma width right to find the chroma width. - * For YV12 this is 1 for example. - * chroma_width = -((-luma_width) >> log2_chroma_w) - * The note above is needed to ensure rounding up. - * This value only refers to the chroma components. - */ - uint8_t log2_chroma_w; ///< chroma_width = -((-luma_width )>>log2_chroma_w) - - /** - * Amount to shift the luma height right to find the chroma height. - * For YV12 this is 1 for example. - * chroma_height= -((-luma_height) >> log2_chroma_h) - * The note above is needed to ensure rounding up. - * This value only refers to the chroma components. - */ - uint8_t log2_chroma_h; - uint8_t flags; - - /** - * Parameters that describe how pixels are packed. If the format - * has chroma components, they must be stored in comp[1] and - * comp[2]. - */ - AVComponentDescriptor comp[4]; -}AVPixFmtDescriptor; - -#define PIX_FMT_BE 1 ///< Pixel format is big-endian. -#define PIX_FMT_PAL 2 ///< Pixel format has a palette in data[1], values are indexes in this palette. -#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end. -#define PIX_FMT_HWACCEL 8 ///< Pixel format is an HW accelerated format. - -/** - * The array of all the pixel format descriptors. - */ -extern const AVPixFmtDescriptor av_pix_fmt_descriptors[]; - -/** - * Reads a line from an image, and writes the values of the - * pixel format component c to dst. - * - * @param data the array containing the pointers to the planes of the image - * @param linesizes the array containing the linesizes of the image - * @param desc the pixel format descriptor for the image - * @param x the horizontal coordinate of the first pixel to read - * @param y the vertical coordinate of the first pixel to read - * @param w the width of the line to read, that is the number of - * values to write to dst - * @param read_pal_component if not zero and the format is a paletted - * format writes the values corresponding to the palette - * component c in data[1] to dst, rather than the palette indexes in - * data[0]. The behavior is undefined if the format is not paletted. - */ -void read_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4], - const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component); - -/** - * Writes the values from src to the pixel format component c of an - * image line. - * - * @param src array containing the values to write - * @param data the array containing the pointers to the planes of the - * image to write into. It is supposed to be zeroed. - * @param linesizes the array containing the linesizes of the image - * @param desc the pixel format descriptor for the image - * @param x the horizontal coordinate of the first pixel to write - * @param y the vertical coordinate of the first pixel to write - * @param w the width of the line to write, that is the number of - * values to write to the image line - */ -void write_line(const uint16_t *src, uint8_t *data[4], const int linesize[4], - const AVPixFmtDescriptor *desc, int x, int y, int c, int w); - -/** - * Returns the pixel format corresponding to name. - * - * If there is no pixel format with name name, then looks for a - * pixel format with the name corresponding to the native endian - * format of name. - * For example in a little-endian system, first looks for "gray16", - * then for "gray16le". - * - * Finally if no pixel format has been found, returns PIX_FMT_NONE. - */ -enum PixelFormat av_get_pix_fmt(const char *name); - -/** - * Returns the number of bits per pixel used by the pixel format - * described by pixdesc. - * - * The returned number of bits refers to the number of bits actually - * used for storing the pixel information, that is padding bits are - * not counted. - */ -int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); - -#endif /* AVUTIL_PIXDESC_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/pixfmt.h b/tizen/distrib/ffmpeg/include/libavutil/pixfmt.h deleted file mode 100644 index d976f34..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/pixfmt.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PIXFMT_H -#define AVUTIL_PIXFMT_H - -/** - * @file - * pixel format definitions - * - * @warning This file has to be considered an internal but installed - * header, so it should not be directly included in your projects. - */ - -#include "libavutil/avconfig.h" - -/** - * Pixel format. Notes: - * - * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA - * color is put together as: - * (A << 24) | (R << 16) | (G << 8) | B - * This is stored as BGRA on little-endian CPU architectures and ARGB on - * big-endian CPUs. - * - * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized - * image data is stored in AVFrame.data[0]. The palette is transported in - * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is - * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is - * also endian-specific). Note also that the individual RGB palette - * components stored in AVFrame.data[1] should be in the range 0..255. - * This is important as many custom PAL8 video codecs that were designed - * to run on the IBM VGA graphics adapter use 6-bit palette components. - * - * For all the 8bit per pixel formats, an RGB32 palette is in data[1] like - * for pal8. This palette is filled in automatically by the function - * allocating the picture. - * - * Note, make sure that all newly added big endian formats have pix_fmt&1==1 - * and that all newly added little endian formats have pix_fmt&1==0 - * this allows simpler detection of big vs little endian. - */ -enum PixelFormat { - PIX_FMT_NONE= -1, - PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) - PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr - PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... - PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... - PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) - PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) - PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) - PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) - PIX_FMT_GRAY8, ///< Y , 8bpp - PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb - PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb - PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette - PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG) - PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG) - PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG) - PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing - PIX_FMT_XVMC_MPEG2_IDCT, - PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 - PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 - PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) - PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) - PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) - PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) - PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) - PIX_FMT_NV21, ///< as above, but U and V bytes are swapped - - PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... - PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... - PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... - PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... - - PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian - PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian - PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) - PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG) - PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) - PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian - PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian - - PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian - PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian - PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 - PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 - - PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian - PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian - PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 - PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 - - PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers - PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers - PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - - PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian - PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian - PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian - PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer - - PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 - PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 - PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1 - PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1 - PIX_FMT_Y400A, ///< 8bit gray, 8bit alpha - PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions -}; - -#if AV_HAVE_BIGENDIAN -# define PIX_FMT_NE(be, le) PIX_FMT_##be -#else -# define PIX_FMT_NE(be, le) PIX_FMT_##le -#endif - -#define PIX_FMT_RGB32 PIX_FMT_NE(ARGB, BGRA) -#define PIX_FMT_RGB32_1 PIX_FMT_NE(RGBA, ABGR) -#define PIX_FMT_BGR32 PIX_FMT_NE(ABGR, RGBA) -#define PIX_FMT_BGR32_1 PIX_FMT_NE(BGRA, ARGB) - -#define PIX_FMT_GRAY16 PIX_FMT_NE(GRAY16BE, GRAY16LE) -#define PIX_FMT_RGB48 PIX_FMT_NE(RGB48BE, RGB48LE) -#define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE) -#define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE) -#define PIX_FMT_RGB444 PIX_FMT_NE(RGB444BE, RGB444LE) -#define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE) -#define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE) -#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE) - -#define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE) -#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE) -#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE) - -#endif /* AVUTIL_PIXFMT_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/rational.h b/tizen/distrib/ffmpeg/include/libavutil/rational.h deleted file mode 100644 index 4d91f7b..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/rational.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * rational numbers - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * rational numbers - * @author Michael Niedermayer - */ - -#ifndef AVUTIL_RATIONAL_H -#define AVUTIL_RATIONAL_H - -#include -#include "attributes.h" - -/** - * rational number numerator/denominator - */ -typedef struct AVRational{ - int num; ///< numerator - int den; ///< denominator -} AVRational; - -/** - * Compares two rationals. - * @param a first rational - * @param b second rational - * @return 0 if a==b, 1 if a>b and -1 if a>63)|1; - else return 0; -} - -/** - * Converts rational to double. - * @param a rational to convert - * @return (double) a - */ -static inline double av_q2d(AVRational a){ - return a.num / (double) a.den; -} - -/** - * Reduces a fraction. - * This is useful for framerate calculations. - * @param dst_num destination numerator - * @param dst_den destination denominator - * @param num source numerator - * @param den source denominator - * @param max the maximum allowed for dst_num & dst_den - * @return 1 if exact, 0 otherwise - */ -int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); - -/** - * Multiplies two rationals. - * @param b first rational - * @param c second rational - * @return b*c - */ -AVRational av_mul_q(AVRational b, AVRational c) av_const; - -/** - * Divides one rational by another. - * @param b first rational - * @param c second rational - * @return b/c - */ -AVRational av_div_q(AVRational b, AVRational c) av_const; - -/** - * Adds two rationals. - * @param b first rational - * @param c second rational - * @return b+c - */ -AVRational av_add_q(AVRational b, AVRational c) av_const; - -/** - * Subtracts one rational from another. - * @param b first rational - * @param c second rational - * @return b-c - */ -AVRational av_sub_q(AVRational b, AVRational c) av_const; - -/** - * Converts a double precision floating point number to a rational. - * @param d double to convert - * @param max the maximum allowed numerator and denominator - * @return (AVRational) d - */ -AVRational av_d2q(double d, int max) av_const; - -/** - * @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer - * than q1, 0 if they have the same distance. - */ -int av_nearer_q(AVRational q, AVRational q1, AVRational q2); - -/** - * Finds the nearest value in q_list to q. - * @param q_list an array of rationals terminated by {0, 0} - * @return the index of the nearest value found in the array - */ -int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); - -#endif /* AVUTIL_RATIONAL_H */ diff --git a/tizen/distrib/ffmpeg/include/libavutil/sha1.h b/tizen/distrib/ffmpeg/include/libavutil/sha1.h deleted file mode 100644 index cf7c4a6..0000000 --- a/tizen/distrib/ffmpeg/include/libavutil/sha1.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_SHA1_H -#define AVUTIL_SHA1_H - -#include - -extern const int av_sha1_size; - -struct AVSHA1; - -/** - * Initializes SHA-1 hashing. - * - * @param context pointer to the function context (of size av_sha_size) - * @deprecated use av_sha_init() instead - */ -void av_sha1_init(struct AVSHA1* context); - -/** - * Updates hash value. - * - * @param context hash function context - * @param data input data to update hash with - * @param len input data length - * @deprecated use av_sha_update() instead - */ -void av_sha1_update(struct AVSHA1* context, const uint8_t* data, unsigned int len); - -/** - * Finishes hashing and output digest value. - * - * @param context hash function context - * @param digest buffer where output digest value is stored - * @deprecated use av_sha_final() instead - */ -void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]); - -#endif /* AVUTIL_SHA1_H */ diff --git a/tizen/distrib/ffmpeg/include/libswscale/swscale.h b/tizen/distrib/ffmpeg/include/libswscale/swscale.h deleted file mode 100644 index 1e7af3a..0000000 --- a/tizen/distrib/ffmpeg/include/libswscale/swscale.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2001-2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SWSCALE_SWSCALE_H -#define SWSCALE_SWSCALE_H - -/** - * @file - * @brief - * external api for the swscale stuff - */ - -#include "libavutil/avutil.h" - -#define LIBSWSCALE_VERSION_MAJOR 0 -#define LIBSWSCALE_VERSION_MINOR 11 -#define LIBSWSCALE_VERSION_MICRO 0 - -#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ - LIBSWSCALE_VERSION_MINOR, \ - LIBSWSCALE_VERSION_MICRO) -#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \ - LIBSWSCALE_VERSION_MINOR, \ - LIBSWSCALE_VERSION_MICRO) -#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT - -#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION) - -/** - * Returns the LIBSWSCALE_VERSION_INT constant. - */ -unsigned swscale_version(void); - -/** - * Returns the libswscale build-time configuration. - */ -const char *swscale_configuration(void); - -/** - * Returns the libswscale license. - */ -const char *swscale_license(void); - -/* values for the flags, the stuff on the command line is different */ -#define SWS_FAST_BILINEAR 1 -#define SWS_BILINEAR 2 -#define SWS_BICUBIC 4 -#define SWS_X 8 -#define SWS_POINT 0x10 -#define SWS_AREA 0x20 -#define SWS_BICUBLIN 0x40 -#define SWS_GAUSS 0x80 -#define SWS_SINC 0x100 -#define SWS_LANCZOS 0x200 -#define SWS_SPLINE 0x400 - -#define SWS_SRC_V_CHR_DROP_MASK 0x30000 -#define SWS_SRC_V_CHR_DROP_SHIFT 16 - -#define SWS_PARAM_DEFAULT 123456 - -#define SWS_PRINT_INFO 0x1000 - -//the following 3 flags are not completely implemented -//internal chrominace subsampling info -#define SWS_FULL_CHR_H_INT 0x2000 -//input subsampling info -#define SWS_FULL_CHR_H_INP 0x4000 -#define SWS_DIRECT_BGR 0x8000 -#define SWS_ACCURATE_RND 0x40000 -#define SWS_BITEXACT 0x80000 - -#define SWS_CPU_CAPS_MMX 0x80000000 -#define SWS_CPU_CAPS_MMX2 0x20000000 -#define SWS_CPU_CAPS_3DNOW 0x40000000 -#define SWS_CPU_CAPS_ALTIVEC 0x10000000 -#define SWS_CPU_CAPS_BFIN 0x01000000 - -#define SWS_MAX_REDUCE_CUTOFF 0.002 - -#define SWS_CS_ITU709 1 -#define SWS_CS_FCC 4 -#define SWS_CS_ITU601 5 -#define SWS_CS_ITU624 5 -#define SWS_CS_SMPTE170M 5 -#define SWS_CS_SMPTE240M 7 -#define SWS_CS_DEFAULT 5 - -/** - * Returns a pointer to yuv<->rgb coefficients for the given colorspace - * suitable for sws_setColorspaceDetails(). - * - * @param colorspace One of the SWS_CS_* macros. If invalid, - * SWS_CS_DEFAULT is used. - */ -const int *sws_getCoefficients(int colorspace); - - -// when used for filters they must have an odd number of elements -// coeffs cannot be shared between vectors -typedef struct { - double *coeff; ///< pointer to the list of coefficients - int length; ///< number of coefficients in the vector -} SwsVector; - -// vectors can be shared -typedef struct { - SwsVector *lumH; - SwsVector *lumV; - SwsVector *chrH; - SwsVector *chrV; -} SwsFilter; - -struct SwsContext; - -/** - * Returns a positive value if pix_fmt is a supported input format, 0 - * otherwise. - */ -int sws_isSupportedInput(enum PixelFormat pix_fmt); - -/** - * Returns a positive value if pix_fmt is a supported output format, 0 - * otherwise. - */ -int sws_isSupportedOutput(enum PixelFormat pix_fmt); - -/** - * Frees the swscaler context swsContext. - * If swsContext is NULL, then does nothing. - */ -void sws_freeContext(struct SwsContext *swsContext); - -/** - * Allocates and returns a SwsContext. You need it to perform - * scaling/conversion operations using sws_scale(). - * - * @param srcW the width of the source image - * @param srcH the height of the source image - * @param srcFormat the source image format - * @param dstW the width of the destination image - * @param dstH the height of the destination image - * @param dstFormat the destination image format - * @param flags specify which algorithm and options to use for rescaling - * @return a pointer to an allocated context, or NULL in case of error - */ -struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, - int dstW, int dstH, enum PixelFormat dstFormat, - int flags, SwsFilter *srcFilter, - SwsFilter *dstFilter, const double *param); - -/** - * Scales the image slice in srcSlice and puts the resulting scaled - * slice in the image in dst. A slice is a sequence of consecutive - * rows in an image. - * - * Slices have to be provided in sequential order, either in - * top-bottom or bottom-top order. If slices are provided in - * non-sequential order the behavior of the function is undefined. - * - * @param context the scaling context previously created with - * sws_getContext() - * @param srcSlice the array containing the pointers to the planes of - * the source slice - * @param srcStride the array containing the strides for each plane of - * the source image - * @param srcSliceY the position in the source image of the slice to - * process, that is the number (counted starting from - * zero) in the image of the first row of the slice - * @param srcSliceH the height of the source slice, that is the number - * of rows in the slice - * @param dst the array containing the pointers to the planes of - * the destination image - * @param dstStride the array containing the strides for each plane of - * the destination image - * @return the height of the output slice - */ -int sws_scale(struct SwsContext *context, const uint8_t* const srcSlice[], const int srcStride[], - int srcSliceY, int srcSliceH, uint8_t* const dst[], const int dstStride[]); -#if LIBSWSCALE_VERSION_MAJOR < 1 -/** - * @deprecated Use sws_scale() instead. - */ -int sws_scale_ordered(struct SwsContext *context, const uint8_t* const src[], - int srcStride[], int srcSliceY, int srcSliceH, - uint8_t* dst[], int dstStride[]) attribute_deprecated; -#endif - -/** - * @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x] - * @param fullRange if 1 then the luma range is 0..255 if 0 it is 16..235 - * @return -1 if not supported - */ -int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], - int srcRange, const int table[4], int dstRange, - int brightness, int contrast, int saturation); - -/** - * @return -1 if not supported - */ -int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, - int *srcRange, int **table, int *dstRange, - int *brightness, int *contrast, int *saturation); - -/** - * Allocates and returns an uninitialized vector with length coefficients. - */ -SwsVector *sws_allocVec(int length); - -/** - * Returns a normalized Gaussian curve used to filter stuff - * quality=3 is high quality, lower is lower quality. - */ -SwsVector *sws_getGaussianVec(double variance, double quality); - -/** - * Allocates and returns a vector with length coefficients, all - * with the same value c. - */ -SwsVector *sws_getConstVec(double c, int length); - -/** - * Allocates and returns a vector with just one coefficient, with - * value 1.0. - */ -SwsVector *sws_getIdentityVec(void); - -/** - * Scales all the coefficients of a by the scalar value. - */ -void sws_scaleVec(SwsVector *a, double scalar); - -/** - * Scales all the coefficients of a so that their sum equals height. - */ -void sws_normalizeVec(SwsVector *a, double height); -void sws_convVec(SwsVector *a, SwsVector *b); -void sws_addVec(SwsVector *a, SwsVector *b); -void sws_subVec(SwsVector *a, SwsVector *b); -void sws_shiftVec(SwsVector *a, int shift); - -/** - * Allocates and returns a clone of the vector a, that is a vector - * with the same coefficients as a. - */ -SwsVector *sws_cloneVec(SwsVector *a); - -#if LIBSWSCALE_VERSION_MAJOR < 1 -/** - * @deprecated Use sws_printVec2() instead. - */ -attribute_deprecated void sws_printVec(SwsVector *a); -#endif - -/** - * Prints with av_log() a textual representation of the vector a - * if log_level <= av_log_level. - */ -void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level); - -void sws_freeVec(SwsVector *a); - -SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, - float lumaSharpen, float chromaSharpen, - float chromaHShift, float chromaVShift, - int verbose); -void sws_freeFilter(SwsFilter *filter); - -/** - * Checks if context can be reused, otherwise reallocates a new - * one. - * - * If context is NULL, just calls sws_getContext() to get a new - * context. Otherwise, checks if the parameters are the ones already - * saved in context. If that is the case, returns the current - * context. Otherwise, frees context and gets a new context with - * the new parameters. - * - * Be warned that srcFilter and dstFilter are not checked, they - * are assumed to remain the same. - */ -struct SwsContext *sws_getCachedContext(struct SwsContext *context, - int srcW, int srcH, enum PixelFormat srcFormat, - int dstW, int dstH, enum PixelFormat dstFormat, - int flags, SwsFilter *srcFilter, - SwsFilter *dstFilter, const double *param); - -/** - * Converts an 8bit paletted frame into a frame with a color depth of 32-bits. - * - * The output frame will have the same packed format as the palette. - * - * @param src source frame buffer - * @param dst destination frame buffer - * @param num_pixels number of pixels to convert - * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src - */ -void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette); - -/** - * Converts an 8bit paletted frame into a frame with a color depth of 24 bits. - * - * With the palette format "ABCD", the destination frame ends up with the format "ABC". - * - * @param src source frame buffer - * @param dst destination frame buffer - * @param num_pixels number of pixels to convert - * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src - */ -void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette); - - -#endif /* SWSCALE_SWSCALE_H */ diff --git a/tizen/distrib/ffmpeg/lib/libavcodec.a b/tizen/distrib/ffmpeg/lib/libavcodec.a deleted file mode 100644 index 5a0ce4f453969bf719a72e041d887a78815b0c64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9931482 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 z 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 z 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∈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�#5K?Bk#`#(KGnCotig@-iw4h` zUpu$4ZpL8q$?mMdCb+R-&RjPX;@~+$@`nz>_d^?(44O5+aqz6#+QIyQsL#u+C*@gc zXSTykgIWt&z&EJpEXd88%?nw66m-FSxRGJ_*Ugv-H(Iy(zNo80_4y5ON4DT5V1eZ9xecID$a3aA(ry+RoOegZMVB*YRw{3> zc>WA33wCaBE*dkobnwvNZ=ER*j$btR_~V`KA3S)U`@zXh*I?HA!ND0%Zoqamf7-$5K52e~MHRn5@pC z@1XcBM)?$<)`H|T#+y{4x;HL!hBLq%u|e@TO!2{2EmKv_DXzib=4AnV4+}~U@@KMZ z@J;KINQx}qV)rB-o;Ra|J57LT$C52 zRhC+n6;@TDRRz5&XjMVE3Tjmdtb%S)sZ~^AHRfCRT)0(_6*_0mZLsQ2o69cxOWPp` zK%eI@VYVFnvQL}d4d!EKSOS%>aqbi4Ar!C`V8>WuC15D#=E?32O3NArKL({J+>}#>F$G#E!AF%%kJI|ZfV!s~y&Dj5&?RF^Nr3hOTd3xU@lXd!B#5;!F{D^Z9vR#@?B-PhRf29g_c(m>*Ah6Xa{; zM_%i?9dfhlP9m>!-Kpf=t~-tF6kxw?c-}ZVLxAx#GSPLXl1Z*RiR|LK9g_cKm>DuT zC_{9lV5cE6)pe(mVb`5R@~$g%aGG@gxzUinRL`4SW=CspE)wD2FCNj4LB_L9-#4-R z!Mu~gbiT7r^uf?)paM4HLlws zr@8KE!LlI_HGbJwPXbTEZd>JEE*Z?*L-AI{#?Zu#A*#@XCwqGItHsW&lb5;f2)RlA zB>(9_C*s9>9`XwcC*N}24*8kuj*y?rpZvmgM~guDpYkKWblnd5mFrF-zjocJqxT?Ltg2av))D_`)Yny@pA0G zCU7joauZOuV;n9)k+;4tDhH z5&ROM`P!Z}k@y34dXuv;5<{CwyRP^9Kq1C`W1J52%`|HwVLp3iO?m*%{`^m8 zO(Yg$H`;XYb}#&iZP;m?%tS50n`ki=hMd#E62spsFKeXS6taR~nQ4JM+w~^gYN+t4 z!NF+~bryg4)vUvFQ~~7q*lnwV*yuWmE3nflX+FegRS*wjhcfXbc50A+bG-?-nk&3& zj-|`W{uw*tkUX`)6w%Lh61mu^LGmI28pJ8Cli-n}2D#exCV0@GO#BHuHOL!WZ{j}J zNj!?38sv7@n=oHEv?_?Nu~UOIA2hToh_E^S6~qzPsX=DC-UOe9BOgQwc509lTyJ8k z>m=B`s6j4uy$QB7*dW$prv_<0Oo$@Fc@uVM5cgrH2Klh-O_;9`S``FaD>c3VbI~l} z9>YdE(RGg?Cu4^}!h8?Vsvy{&8S{7Gb=aZ7cFiyN(fc_t&a~wUKH*?Hr#E?;>rFIZ zk2M3Y{Zo-0;7(VO;9bm^B74M>*r`aqh#lz@=8Je%1@R7cYLI-o0}bLE*GUA?d#FKn zF+Hh*=;1mEb~tK~dDuIle&XHELh*NQ@EDTa(HHFXPR91S=LqyKcQ`61&ccq<2D>DO zBRIVd2q*jBO6+j5|FN^dN!;x^33f2}61!X{!7c<}!hE3ADks=&;7gRdPQo4I%87Gb zU-lSw59kuNx=w;!0=~p^u9JA#b$UGm3Z{dgLBYuneX@Z32=48k^%Q`H2iO0K=i?DahR>WKiGMRUGPuCbMr`Ns@5>dZQ*d}sytkX&fBxo)!<+H-I>A|N0B zys=BSQF>p3(c=6ft_+8QoB>5nMWQ%w`Xa2Zi`f^hSX_dY>T+?#=B?+&#|)Lz=PjH& zqjlq%lWRg)du?pAJXv>ose)=yu|)w+D^GMhCsqvqVz z3bDfbl!8jDvY@OSt5y`3Rn=g@RbSbd%LyfgJ|Ay=xMN~DtE!kZYD`f~=1P^5a)yrd z#WGf7OAwkxlcQOw95bP!YLsu)(yEeC@R(9LYGQRs(WnVA%UB{e+qdRhS$SRo)+RKq zH>PA3%FN9x!a~F`&&ukFzRHI*BoNGxMr<2yWlZ=WH*cV5iC z>s?Y-P&2t*RTr05#gs;tm0KKd@C2-e3&>+t&c=E3W8np56*c3r(%w8QL^gfSA{^`X z&7-8a*sPCNF=@Q7pheXqYbqy=tSYHO4~|xNMZsjZV!a`6PMulMGJ;kZ)0%>aF==8E zV#P#L$@ww4a?<#Ug32n~l3ak{fJ41!+br}QO}Y~6Sr;L4EG8C@JwO)At9-}VG^pG> zG$`NT6gA1_S2m%lWP-ooG0$9dr25<%K0b^_DJv)(fVqxyFMz^Z)9fg?Zer<@FzMOEaX{>HOXV&}~=H~OF=orqD zn{harjj~FvoS5g&i|6G_#`E$eVye@3?5ZbBnOsoeYai9+L!xKJ{ZGBo3{;mN9V>Ws z`B1-*Z$+0Y`Ol-# z)GJDJJDl>OL1m@oF$1G23vo`#$;I09Sb;ls8G|$N!k89^Kd$6BtKKBGXa=qmxSDIs zX8DkUqDe6si)hA#Lag;0(=6*yEG+6=&c!Bc7UIcyRBd8W8JZ&>D#rXq6%-EP@WV@} zx*0Kljx|-IN=KQK6#86F`#x7Wy2R3jg)f2F*jQQCe%(?t!f@%@n)1?u@dXvJgm8Kt zQsSLDYs^JX`#@jCvZwnRrfK>^a{Z^KlS};#tg4`5bV1D86x32oieFgbUpdOk{R0~Ysc0mg9Vd@;Ph!!5r`_3%U3Q9vSyS$E=QXAqwKF$r zbZ&>Lb`NaTnDXdo*#19EEd5HXXddg6<{F}=aXuCWuH)%P7xdBGYVB%Y>Xjwsz6Oq~ zE?jWLth@Or^j$3!R8^oC`r7&AGXHr1lFv9KUsYilV_%hG(RHj;d%(XhH4Em}?bpuS ztP~V=I6GIGvvd9Yh4@$1Fw?>mpZ$ghwyK;C6>J(`F4w`1)(w^`c25qzYtl*i?vb6l zVE(N3*C-VQH92{{KIdjHZ;G#nRZT7#U+rt71t@SdHD;iAD6cG{UL|F$5O-a&_J_N} zdfzzX`9=yz#ij+gi)^>Q@-`#e-08n9W#Si{$ph26z8X78-z zE^iyPTTt1qEmfk`9k}<6991=@azb$xhtqa{9Al<%Qi%!`)w%w{;~-VGAGFK;V`#~E z{7LY&cO(0(8QIrJjO@E~VF$0lRdrpC3wBvZLtNy!INGYI=bX!E9w$~+pxydfX(dK6 zGchQtVp>=GjE^iCKhCu8nu?-gUxzk5VMwmOCsb4q!9|68y7!s%^}Hzs<7+1S>&^8* zj^}ZW`e>x0a$h7fbofUAGnBL|i2t8x70y{POC?2UsD9ld%uk4>Q&FAgJ8Xr+e8<3T zll%{aE8fac1x0R;u3ONE71Vh(p%zvjv(~;B^Pg`tp`!6q{C_xO#!D(I_Z!V((I$^a zbH&x*9NwY8g6(GA=cv)*Qh#IS0Xca>#W*vTMKgyr<)iLs#M1T`E*0e``^JT$5{%Tb zEX2-`9fm?KEzh$e)_RTRp>P6Pv3n~i zs#je$-j}hmN;c_c6$m3BnpR0(+?!84*jP>Lq|Czb4bZmubGwpBQFiRt& zV`{sz!+509&T5C2QC;Zkt++10$*TR|B-SiW!2ZKmUFiS+dD4XPj(6uw+1sB>d4hJY zfNG{xz<!f zZ0PoGG&5BbeShKfP{N zMjw+q6jw4_T^4t@qD3ee?;B(ai$+%zl#eOFXcoIS+3pXuX*xCg4}>QblogEewV}ew z!Xh^P_Wh->-CrkMcyo}C<)wW5=$KGdnfjR#5CS)C%HlSjm9(YNS*ZDd35-u$UYmddN@g;(D}G^kLN_u?J&3oNQ!`*dsmR`6eK4# z1y={gCr1KHJ0~XTr7-`+Dq!$=Rh%!O5!wfzr;&p(omk@f4y5{JAYe zT6`b_d&NzGy0&CI2Joi*Y(iK)b~mkpPkZO5ga_8hUq?(FUlM1#Y z^~aM#g^7Wm;hUV=hU`6onA;1ILyyPSp^xBk#0WRNLc~f=Elln))-`#0drO$~1U+uk z5NA4Am>e0iI#|>cntWcM5+&LGMB8W-#XLTt9%m3mK&0BlYMFp6u|S+K$c=Mw{*33k z{_+$imlt_u3T!?=flyigV}a_~Pqwn^e>;yi+p^FGT+a4fi)PHtYTy|)t8RM3bSvw$ z`g%BLoYpw2X8LKTEt;{|%A$(vW7@q>#=QC&2w%Xcw4H;Qwr(&z7;n*nEIi7ZKG)Oo zm{nWfkY|~cvktV5ckPn@A@DQ=#xlicem-$w<7w`nqV|4fPQG7n`l9LcXU&Kfw!MV1 zSXrFjKLdZfvgR*nn309+z(Ms5xLolYnYjoPmaVK=ixxC4G>7m%`k96{ix(%N8y}zH zk+7KyIuPVB)pMfdETsyMkIx2w|K z`LM3!rp5Hm#7=riEziK?P+vwO2;(*nyFcB%NOu7ASPm3Dn(j)t8QrV0NPl;Xf|uDM z;u?^8UX@LQo;QwCh2`LW8FuQ$%it2|(cjw`#_eA0e!Zo?pvSqtUL3|-4n4joIgI&)pElJn*=Eh~0|=r}a-%c!tlzbH0l(zr9{Qdj}!Rv-bnsUK}{BgV5n3 zJ`d0N4Z{5PGJN(9Mwn-hFDrX-Xz%EwVUG@NURY;1{Pr?okA0EHm+t|1_Ig9li$fEW zU~dT>+PtuV(qn((_AK;{WyZ8okNeOLdI@E2U+t)8)=T$1!CdJ1H`?M>DSNJj$NkW2 z^#b9^a&VgfKYw|Lqr7**pXKEk<&~FXpVv3ww7wp1S+jihJSV9pN;T`pN$xom-Of4+ zJMFPPnWo>~4!p$R_#%4tpw@2l`-iN5?(+u*+gYT2%);@Kv)1*2C%u3ymV6AOeZh!!#q zpN!_|+fuE1NM2iJ z%VHnoc;s%W*6-m+^F)L#t&uV80JL^*;x_t!tpG#jkvN8}++Dej8kmo%%;~2qNE*491QzxsmFq=QQ{29U@T%wj19?hSj z{5gg{`TQBipB$rz#{zV>{|6ttmEb<4_=RiSn$e{bMi!LTOeij{9930QRWK5dSKHkR zh#A5?FTS~&#b+Q3Yik;2H_ksJ3zx#UR;``4Fd8Wq!JAWuN56UwgnOlDSe_7#alq+% z{wFS8RkgnzfrnH`dT#B)-@=mX#7q+}UWYjCZo2IEc*~u*2k&`NSNoZLX8In&J+=!q zBX0l~qZ~UrXS!oVCkW|~16g>ZT>i&`^dAX^Fc6eVo+9})$s89L&i+sRm6F#<=KE?4 z{{p0aUNfdK5_8lWrK37@SvfilvWN*M#=Y|29|Yd&QRDt{so?=kuRL;Rfn5zM4+cB+#TUNfU4B6xj^lw-BzX^+ zj`54ku&go+vXoCJ@#ll<(|5u(B-f26my+=BgNt$M!<=Q~beu%uG{ox(l4mHA*H$*l zgeoyaRxBH74N^GU0rd*RG2#TVT0BLp6VDJAiD!xDiWiC(i#Lh4i+>fjiGLGc6F(5y zu9&}{#3USV%7=I0WsC;U|it#Bt(8ak9vl%cx%~ z&Jh=gjpEtj3h_LVU!Y_BjUwL=qkOgaXYm&CF7ZC`VX;koO8lGncky-c9g+Qt>3k~k zjWEjJi~Gd5kn5i)hDG*2>hparGF?1UY1nE1oW%DJ~J0iRNW9#9J%*V)1hETJa|FPSLz~hIo%ieq7uk@?&Yt&uij4;>Y6W z;y2nS z*h|b1&1p5ib_65U&$&6}N~FiQB{-;!ENi z;s@fF;&@FTAju6L*lf@Zgy?Cy;PP{_AMSMiuA@a*ttp88MuDC#^ ze3+Om^7G#GpDZpC*NK;rxaPW2yh;9l6}QR%NpS~>+ed#__#Vk$klpbqSo!l08q>u$ zoeU2mku4&?;7#X3g^db8UB#? zwD_9%4vBalh`ULoW8uG=DUaAo%q0JC#zT__?cSafv?@l5-B6*N_tXL|ZD)OVm%ojJd7i8NoB4&#t#By<(xKLa!t`|3n zcZzR|?~5Ocd&Muruf^}gA4QA#ME*jeBbxua%(vt;v4_alH5o4=^4SpODshT9O`I+A zUMBT;--TQ*n&&EzaT#avTDK!p>5uyCLE`2DZowFNfaFZcRg!r>iTb>MM16C=9I>nfT#!w0%+#>mY5^ZSu;+Zqe0(tm~ z7PntpCog|!Hdf2y_Ur59<)@(#*z(Np0Nm~GVIf%yryjF$-L9z_X}&eGxBwhh<0?Y1 zR^w`ZqJax+Wi;n`i;_jSu9yjJ{sQZHaoI1kme|dOBVHaBuo>ek6IXD7+5G*=6+vc; zxY`Xgl49i>(Y}0n$WA_%>1uP!SCuhe%^nnk1QO>{{Llt z{lf8|`oDMlr~I!RU-p&#*UIshw&5x@!Po*hq4w+C#9^Hqtv8d8i@^By%ibj5dwK5a zIcCio$6MG2_b|PMcshG4?Ia##A7PfT!A%IJ*~MKTCporaO~e>Ui7gs~0W!8m4eo;a zSD7g>3&@Nx%f)n!X>qxjZn1S>0vPGqt)vrMoW{434kLB zxH(Ce?nBe`W`E}yY zf_flhvXPSF`3N}B&y`Z+KcUp$mD1v0pym;-l^*d4j4{BKdc{wobkr%vN+kYE#vABL z8S$r4%KV)P8xX&e(jZsLjPF4y>lzc59sd@k!LF1S|4*iu?MnIaVd~_#=?#zHz_46b z8et`jK*Uh+SUzuac(SpaiTJUdm+>2LzQr#dFY;+Xu;6Owgy@_acqAEctLjnLl&Y%L zl|u2?G5%Ipa@<00`vWtQp5zwtakr4EaX8UffhXorKRqpe9<#Uo5u-W93fl2~;SmhP zr6atP77B9WwlH6|!!I2Mcxnsf4o8e&Ac4WgMiMV90YX^v1N1)u~j76 zysMmKet3l7%~sGkR0|=|W-i@8<}isO!ma?iFm~tAayS!h-f>PcKU9M^tEY451_;SK zlLcO~gC9aj!B;!}8OHkXF5 z2iOat*^GS!_A3=*fG@^?SPXMNevrK$noncD4Lfg9GmSxtfntqev5qmtdL9~CNM;w< z1HIHO)-mmhB`MT(BJ*<$)$jpn7IGMEnrG2LC-ezI)9m>$WEa@k5U4&F`*cKL4hocm zt|v470@J`Ygt`tgF-+sb*HzN&$0!%u(-3n7_TOONEDOc$EEKo1P#m*Rgedkndp&R$ z_VciRAPeK#Ss2&O!nl|PKIgN`?N;Ci?Dt?#jB`s-E(@r~o2WI_X6xb5H6Ht0@Z!y3 zw;rc@^~h?rr*Z(phqzgDr!o?sx}d;A7&y}|hcpL!9(LaUWtGjO8X87dHcoq{vfG`H zQFzeJW0=_ozh;y|2fyGd<4D@~QvVElA$&M0Ps2`oXUHC&#F#u+GwJ{EQ_MJ!=Bm?t zESZ;|?kA3oU-a9?=8MQk48y$n4IW}UCq0yzJ=i(xU&F_}atC*3!?>oEPCw@<bw^0{PQNbu8y`f{kG#`$M@aTVziun!Hu;g?yY2|d9_QDE zfOCiIN0zzn2+2O@*X<8E6FZ7a@G~?#yZ|+QmB8M{g`60fPa@MH1W%wB|Ya>L99yjd`(!5W6Ub8_eT)OgXTR3)SQ}}$v8jf#Zvg|Uaz{wdWio`PvdKI*og2@eCo#XjXOAbWV_p3*s{=53x@*r1 z=Shm)y)b#in5N*#s{>2gr-^Y5!n6Xbt*lvakgKBFwc+P=7pUA4}Uq{Ksla7CRh$UW{;Mm z0&Xu3oK}2i=+U9g3u9aN+q*6jt7rPNyeudCCga4bKAwX;uP)#nP3vr*oBl6CZ;h`G zy>u_=pm%B)u3#D4JiXQM^5^f?NGyMd63yRLaC>p!w74)F{k+W!V(4Ta9a83 zjGTw)ZJue;S3GMWZe=ZpM^E^7#m;ouH<_m2-WO2d^A>OOIXy2!zyJR4X82R4eXo?R ziU0mx4S&thp7#{Pv*#b>8P1j&+k$vk!@uqSZUslQ*tY+>6g&d4Ef_u9x_*3Dz{}xy zcy&e1bFQnmbqyrCH<9GQdLQWpf|N@;$WtJfW9RXwy;}|BSmjarB zS0CSdfgrl>w%rxjFU+|ArCIyl^mY7k;Dx5S zi0g3CDbZXR`!4$w!@C0H$7&H8yMRP^OhAb5PeW8P7xi8&F98#aW<3i^B6jJFfS7>j zv1@WqP;?VOw>e(~(4;ZMS)FlV*ar-uK@KO;lsAD4zaC^b$J!A3{R1RU)I1L`{9T2A zLx05Q^UqLkv?Gw=FN2K#F8vS3ycQDi9UNDaK4{VhP5NYpI}R~?wZb{yICKR5nUaVf zkMyGR$I+EJ=JEMD`xMDGV?!5NG3-m?r35It;`AIVm96VC;G2$q(Qk*U>6qkzUisy^##7o3Y;;rHX;*%ne3-j^5 z$bLwf&nUc7Z;JxKTqLiUN!XpEcsUH-6?J%q5qV^ zUlBhNKO>Q!FU4<2=y$>Os;O@h;l0ENiSQ#8evDWq|0>D9ArY@etX23Dg`4@#2w$i0 z8|8n8cpYhX?9M>6+OB2h+DH@m3MmGHxGRG^1mn*zV@@&a-C7&;O zjpQ38-zvFP@;1q@O6E96`(H@@T5>A;4bo2|5uPnMPx2VarIKe$o=f6lefr{s_zuC0 z=+us1o!4=6ZhpjUzdo;{j)Ne!JoCH%yberI2yGu>&Y0UrU~I+>T6coP+J`X0nt2$% zFmIrxI2AKD%;bsf#jb&3W57SzV!g3XL)P{YXm-}}?ITcPN=dGi$vYa`M`XK*xM4h^ zP~iauc$@(qb|8ajTOXY#lG(g8Bco+$MjqyK^zzN+K(-^8kCDB0v@>jb^W2O9i;nZA zg|svoQ|)ryT%2+L*T@8N-wV+qu$a+;SWVk9+tx0&yrQmZZGODrzO`xj+i{?gosle* z)!uOP{M6=i(qJ&Bb)d1^aj-T`=&mYeow{zAD} zY!<7fI^(#FRBbpkr*+kf4F?^l1nXO>Q%&f*EyZbT%bj7*FHSJU-Sa|on&!$pZah|f z+VDtAbsCRuCgQx?c(?po5?sUQJ(lzdjeI{E$0=4#UEs^Gh)cu0mgTih$Tg+ ze6YkM=TR#6keKRhr1BvW)0_n`AKz1A59eNn9xAby!>h9RUJ@ft1ugfHnBnYT+`}Xe zz$&H?BN8*6Hj0Pa&q67Xp6&2PTYQGS(};P_G@9zK66HHzGV~~k!=1j2n`yH;0_h{1 zPRvHOooU1(=NQJ#u?vh??A*Z6Tzi+XJlgq+afjNwjX1_xOz}i}g;6ebQkl>gdyNsR zoP#NrNSxyIp*U9JRHq-saT2FFnG{QH7A%ln=lno%yz)HTd5+mAxA_8WAbqaY=_=-O zOXn-#ofQ87t0A#7V?5~Ah?O{i5gu|YB!oFzkXqd%>{#(3P7R0;J%_ZC*pgVBE^HX| zWt%X*`#j$x;2VbolLMj9JJ3mZ7a=1Oo(=vDo+%3(>aB!Vf|nxz%_pUf;+qm3X983c z{$Vr&>8Z|L6yFNEIZ1P7!$88@5_>pvkj;d5B=&NusQjVCh{J#O2_FUd(qSMy!<=jr zJ`TE-Js^c&A5Yk=bTb`#C+tz&Jm+7u{G&qiQJ(7&o@(;~ILsgTbOGW+eATfl%a`y| z(DnHgKHcm+@CuZfqZPFCaBfTsz+|9|>7<>9pFkN4mBzV1fwDF@5$O*4=P1&gXrvqy z$vm6RVI{kfa!jOy?A}NZvviCF#%~C5MUn0c&%om6hw#lxOrWq1w)vmd?qf#){;lJ7 ze^jrJr+1K@Omi9bG=^h`xwoQf8J=1Xn@_Yc&4p!X#m;|ZnINx}-K4Xndk7DqolV6$ z>^*sa?Oe8m^$_t&`3dwWwE16-&p?sjsZk?^GIFRfQb;41L4pY$J(>JilRW>_{SG#s zK;Y(R%(05u>z@jC6E0)IKQm!eiFr--6ni-$b4cdD^kT7TfAQ1ZFz-;`(z?NdS8D zPh98HV`7nhIYA|0UL$l9kiEwJ?41|0XWfp11*{*DmH%|Ii@WZ)eF z@Xa(DJd42+OG7Y~2DNga#l=xI_yl8g{c&%had_)<4DKu(Z&`8pN0%-~?cjQ^#O>M|r7dsGKlod>I7l=O7ahYruxkf4tap-Ddv37E>3-~JlDbjFKm3xmZL513)am*n{32n6Zem3&HM%C%N!h0_YXA# zD7<+;R1qu=mhhTC<1EjILn3_YXQQp3;dye1qd|Nk*iFd{UGQOYo)`0WGxk_6>mWtH z^1r|c?zfg#cy9AuP@Y@8Z-ibCw^_LYpUUNE6#dvL+lf{K<0+iqCB+j~F3!cXJw+|f z#nV1TvnUMDaah2^{7pCS@ka${9dHtgceTrKe6@dZtN^Tl_VtbBCSpqg{1=lFn7!ya zRIzC+DxUZGUN14^pmw%3r@m%h!B6r4%_qFR^{TM##(wks}%(U-CW=2fZq$%xwMT)JG5c{;Y*EhT`l^@{Czx?_- zrVp9yZ%u{ANtp)js0_jXiG!D|NVTNB=&c0 z-9U5i3XEVs5qlxODH|wi3NCQx%Xs?J5XL`m1F&;z#eNNTd`oxCdH4oxT;=M}xK)9( zI^*lM_zrCmpJ;kCt)kU| z>FyVOJ-f7pasB_F1H(G_54LZh6ZYxl!Oj0)eE!5cqpVBrhhfJdGWWLuYXo-x>B8Jh zg&!VmMV}MHX^p{wTMp754xO<@`~9%f9?nr_+si=TW{x3b9&76VnjWu{XwTbd?^>US z=Nt(I&rRKRNQf5|-sXj!01w>Wk8V$*9B(5NEJp%%=8yU6I0xoXH1fMWBMA4LG&r}YZ#-A;!#FYHf{{r2vU#O$RY%(K^V4$LY9LN&U1_Lzp> zUTegC#?Irx_UqZ(3OD0;*Uf*1y_>woqcDc==%6L{g1_Ye>D#Eo zZ8vt$O?fHwKBhyPcMLy(>@Uaj5zAT*KbE6AcCQ>PlP}v=9XjKGG6&`g752IN z(;S$k=%`Oa$J_jQ_xwn||NlP+#*Uu9*bF#_qdyqI&hsSYVW78hPE5HcfE*)dc97>o zo`#+0QO5s0*oyrc$t|F_G5#gky>ln^uZO$|2Z`rS%3DBhqyB@~mt!ns+h#Z}F`}16 zzkC(5e+VvI5BTNBUz~^HeI~KPWs~m`6^X>Ywb=e@k?F_&Z|T||p8ks?w~q(VFNUIQ zo$<`D0OZ_{=Rx|vEdPJfAKx%AFCpTUJ9&f_X9-kKl(TO+~ zQ~wAO=KcV&%Me|KQ$gPq;6KxFk)H8E3z&?_X6o-mqL~jnpsglh% z?-0+-y+EE9(;vJ@;g?CiQoM%5$>#xuZ0hbvKTE!qgxxzu^UXQL-=Xkb;y2dL0Qb6b`;crHIY<=)ba z;hf54HNT8!^!dK24?90xn{-0+7^h`K5@rdE7`FAC{BKrfuu4KHt8PP&!Q_VgmXw|E z+K)9)PTKlzfZyL}86EOXau^*-S;;X3c^a{*HRb$PxiNPkf9u-;Bv=(38CvztIo)$! zoVmS-!@$h#q4oRrH9ckz`?7Iw%dHv9k>09LQ`UV5wyZJ9V`9bd?fB$I1YTefz`PV4 z*^n`&>777xX+}9Lm$t0T;Bj1=_Fc-oM-7{sF}!6_DCNG9fs{48)!O2f8!^j|+`aSN zRr`?t?37h&5QnugruoZ9ST8$2fok@ur_PxO&C<0=f1KI$+klm_ifv%+@W0>}Npwe^ z{y*y81iZ@P>>GccGv}O~OhOVNLQs@Q!j6!Hh#-p`vOpw0~RTuDK7mj%0?L78e5$wTi! zYWW=(kPK9Sm5Qo58%k8Wsr|z=&>I7M&^x0yQ_WL%hPyt~#8yx5o)heREYkHPXbsY| z-kyXS=@`B-0m+rultZsgdNj542r47T?wS`wedL(>SaUxjosIe^pNs;gmf>&1o{l>3 zkxyOdI`Y{|i@ORR2%sEn7S#W)x1o9wB*_5_guxM4|i8s48(* z5L}fm?h5`A1amsyvr&-3qes3%6g9?7-C2lyRPCqk%(p=(fA5#s7w4qc0?H@^e?9h8h%TST3Rw3o+`9nb=bntD^z76pyN>JJOEJz#?&{xF9Ml8`cYYp8{ms$UkL-Od(s?A3 z_%>*G!5y!nM1xQ@NuB$Hs@WhPRDE~2^NYxuVcj*!hYok{%}71a73h2Beir_MK07w>&CGV*BZ1J51$ClvgOcPa0^hu-Qs3I-_lKOB00 z!o!R@OM$H>y`G4GV<`iC%7 zRiY53O+T~i504iIRgvF+oMR9RqGUHZ2#OHwO4eK8K+#^E422lfJ?&^cTRi9>F|cZ4 z)0A9D#X5Q(crY2*ba(9NE{?z) zZ73mDlt!zY&HlV&Vt3K*uId9_Pd;AsJcwDHZw9(Lc6E2`?kd{fb)Y+TpsVQau8ya2 zKkbSgJo+&rK(3t^4+^BN|C)Krt^*sB(GBdGRFs^$X$J{hJi<<0KM4u}7orWIY7`yp z2G4uC3O@^W7wtms>p4G6-C4B9F?>OL@8OKDqOILUdz8IPw&6;QZFR!;cNN`=y0`V_ zz`f|}5Ek3B_h{O>SB>$Dpgkv&!tU9D?^LM<*{K`CsJPUffsMh>jwWmUN_{{V z|LB*fWcL3%gP%Q^i3B6}g84&-b#Zr7?yH#ifuiSCj_+Kd`{VA|!PEy5yJCvfqkkh2 zWtSkX)SZsJj{eT`k3E(8fM)t=F$kgzsXGlmfq2o~o326j?3R+z5V4&M?sn*D(VbmW zw5sMl*A1llsiS{GnAr=Px-)`GTn}4!KRi=+J~1hloO%UkthzFHyOntZD>HVW8%!Uh ze7j@2Xd;=cTjiX(6J^@TcAL=^dmaT;W0z#vU41YS;@tU+6OB<&hdPQ|hm5$JLzmd| z8=mWqJ4!zb@g%VZo-tb(3Oj*gXA5bkx{A%N%--&`@*T)vq^!+?C31dzj}Y_PA$ZvJK+nNLZwx)kKRtaXouc>jos79EUwvuee|J!DSe+@ zoZOzIM;S_Qv03+QrG`5?_qcO{&I8Akvijm-GLqr9aIm!g1p70-`~Sk8UGBt9Wj~oV zpvUoU$C;hHY7=o^>;;Y_C2>zNx8L@|HeR#+7O!@^h}=PZd_UWZ*xx(vjT?NK7H6$_ zX|Y3B?Ys>QPj`PQq&665`4XX5#o~p3AMsEh3L3*aZn;-%xDQ3>2w#Q>9mxag zD(vcTZPI)two%Rzbyyk6?MDJ*k`QcJr{)`ctUn1>1pUSL4#LY}@d(-m>JS?>2 zqISmneOX=kE*Vuv9--4r*|C+I0>c80u1SsJn;91clM_wp)V}XY9>Q{*;p1CvNr#SA zEAdWI8>>Nls-Fpug=wA$^@i*-ot@az{UKz}x+TTgQ4_QiV0i7H!ty<(tRH5|$}Av) z9pR-L*qY66y09mk%Y^{x#O&}Bpc4p$_+6Q|HJj5MY|Xw9Ajs9=klvaN)CxIUv!}y9 z_%Bcn_1>DzZ{dS?A#QlsEK=wIN8#L|baJUUoHvHf8xbq)?9zT6{=s4JPSCrwPekC> zNUD7U{3Bd1jd;7X*>gs`UE2I=G~(^jjx*HTrOkUJBHk`-E{R6GUE2R5>h02A#O`C^TOk_ZRVYY2QK0 z-Y)IinXk7?yNjr|OM4ATdAqbHlIJ{|0t{r$j9g1n6YNhEIxC_!e0saI`4wBl+ojD* zMk3xWZLX(Ayj|Kn{vhJ*(k>)gYICT@UE053M&2&%*$geW|EcoDF6}gOxkLUDyeCH< zq8O6?L9btHiC9TI94)e23nZ8{nPI+N+P5Gy9Q-5lQv0!49Cw#Cbwc^_+d}2bUE0hr zWh)YdgH)bWY}o!apx*ABd?Nz5JguVJ@ExhbitwLuJ4+N%#|ozX0L2LO*|h}z$2D1f zcKs4zR^OV^0xK=C32lRiNcy$yPrS zNsN)Q3}fLnBQT2R?Xf`g?c z{fOzt>zvck%#cAKpLg6GAFTr-%(*Fa- zTdA2mg)~+IRZRB36hVP1MP5u{5O}OoEcUMfNs(z&24bF0B{EfgpEL$k0}E`y%U_sc zfl6_*osMDzolWiBpnYN@Vg}Ww_7k^&P%!s+c$~OO`Ld;0gSkXuU#3e7CtjOzU-*Ye zoLPqe#>cMq%!RHycuE@rx)=iir?er&AVJ9WGkB-4LWk^Usc%$-GeL9^{P?>i0efwg z5O1UqX}z;cSid(?WTkKoeHwXc6d4R%goO4@OosjFLwP`>eG{YNWXNGJ1KKweYeK@| zdl;xt(Z0tTrfNc=mm_r8K{BM!9}!h5rcl1W8ph9jbm-S`jcBy&ZKTV0h9k~3NF$N+ z4Dtse%MFqXmPagyC{&{F6Kh-!MN#PeK!+(E-p*P-N|X)LzJ(2Q378&91sskr{_I=N zMPWxBg;#h>B%FW3w$Xoq`&W2IAHpA>F`0;XDqrk;j0XhRqC#MNIuQGBmw~`&4En6T zcyNar{tqH>0R#7_fZ+^4eX*)e+JwKrwYE5dWYni?sZRsY3a+IHPCSI9fosRZIY?Q9 z>y=ZPf*&%1HO^MA`bOEANVgKt8KAxx{a_|ef*eI+sK~K*fcj~SfE4z)oX3D#qaVh9 zD`Jo0MKXvrhA&M{{XLM)@I95+#=H$jZXFVq;+aEY50B<6vtby=@Hfuph8=sny%wI+ z5jl>4@8W$@W(z80yvaVBoZ91QlTQTEp;UBRTcjqVVlJBDLgb)&sCVy>s6pLHn z$Rmqmjv$8O@0Y+7e;FvK;_o*gKovCnQ2_Xo*Y{^X1n zyB6NkxP~ z9=mk(13+(A>GJKDsRC)XGRu1qd>2ajAi`>q@oCB|r>TApO>x5SC{Z)6-4Z-qnPrWB zg%lH%wj5{c9wK={1vxoR5e{rgn{X>La?tb%%8K_jkuxUjA?dy*@}LRdXIcl%obW56 z{Y>QS3F`fPKNESxgeyteLB~u`Jwmz(&6&tCiQV63c_u-72dIGYslZ^xHP#924BEu+ zp^@Fmyr$T^mqr=JXAx*kW?%6vye77^w=$S5$eMfvzHfZP*FxC8diyH+W1$Zj91*9`60`Lt9vfm!wOd)1Qro^4 z+;DpJIr5^C>54_)iZY{Ot!ezeQ{KkGt!+PtvznHPm`M|#g^z8g z+y^l2H2R$Js^^o;PVF<`XObJswx;oLiR3{+C6=41O{RqjoXe)*sopEG|0#SD$S8KCK$J za^eL2jTXB2rjA7o|JOd@;^C2cV*so;_KkJ4$LXcN#9G*PL0yafp3D2V3*~Y??t)Y8 zljrfts1LaH$6e3?=i@GT^Cn=ACKEL4`0m$T5Dzx-o3Fbx!hQ8>vp=H32O|$uFNUd? z*>-wls_6TWh_#FHQ_97K54|mBja_m^>Fk%DhzuDsO`N`XcVq}Z;R^G!tw4Aj|2z1% z2!Hm4;n%~WI55f(_fyX6w zBy-%UK-aB#XmKYz*1#Jk42k!Z$5;4D%NFa`kldF@ zFmmLzwVFA_7L)mC{zK9H+&VB72`^t$yQ=8!veg%g z3#XJXDLq51ycw}Sw>BeevnuNc$PjgjV$NI9Q@u|<3mGk>>(sNv`L#qS{!^Lr->mja zXG1d*7mEwV=DVVEm}(-a%N1LRufy3C;pd3UB3A{w&Mo3m>ymL(8}4DvU%TcZ zWOVXbrDx>KxM0%MQ_nmDwNsG8I=4mr*kDjJvZMo8Q6mn(Rof2NNCr$_4A+K0gfTa* zj`V#=JZ(o_k36(x@*ggk^xa7pjMK_`%8TKJcPf*2m_Pp>=PCbucn0hMA$C++@zfI`Ojw4XR3#bJ&I-@v1c`t1G@NF zgR>!}g|Xle?5nakp7|2=^foB1CXCe}~0OlA{V)BzDX74xZzlfIFg!#@j*>L2-Z+8Bh`;j_X|1jeMpnT#)C z$xu?*SDxcP3X6pwZKDmf#md*edzTpA{)fx%ed7)Fbt`(P=GNAR`u5EFW_q03 ziy9VX4qcSFw2lBHl>hj%@eAN5@Cyb*p>Q}MA(AMQlKZ5jI-k#;0xJCElW>T3!_d2* z)h1`bovr=T2#0HTI^hBIZ8&Uxtxd-hct9wf@Ja1XBjjKd{>g+-X?KK>^IB$1$SYJ7 zAv$XCkPzWK?M@@C)$U}%`Pv;JT%g@S!e%^*5FIT#Af1p~Q9(3~kfSYfMA)X?5yE!u z4ia+JLlHtT)h`qORe10TFBb!K_?BI3;8wp({Bz0Fwkilr_-;3RHay={;WYz5o8dTi z9vutkX_{ zzvBt0!s|Sl!9+Hb`s*!n@|hKmH$Zyro>VGK}YgP<;dJ8V)(K+oAJO&piVzQIzq}PU|kR- z9EbvewVT$^F$@m_2w74U;P6cSp`xJp1V&Fv$urA`59>>r=PwkEEv1B7f94Xf5*Wpy z_Fp$7hMHzd@Qr3#3(w_vP{RZa2l44}s-Ke~`1e{G8AU7##6+_)k&f%wG+=~H+MPz& zV*ClYrbe^lq?-bqizy(r%mn+WGITl~5>~{M)x?5{*TQcd z9tw%@677xC`Fb5=`?#=+tTFI)&n=7~jqawmC3!0`k(kIHVKBL!~90q1_R}0_{#FEY$8a z!kOBgPFRZOg@MUI<%j_Rp>)DI+MPyNrrpVe<=Pz~u8Cgj?)BIFe5Vo=|pa?08E z2q0H=Q7=aTxP}Yo#YlFOB9XK05a1hl(El9|N?g)}lM9z5%$jiMcDuBy|LoGL?j0Ji zrf+kC>Gp?Tr?Q`S8^9gfN$@i~u-)Z^KgW|`T>uO!Pvk!3alZB-qP|tJ<`U?FDP|4> zMeBS6K$p>NsO0(<6P` zTryQI^Y}Vvly(y2;6cnP!tr=iwN#;6h;XSs!9umr!&$ett+`~F*`XZFEk!XskGzw) zUZoqWB9?n;%9$ovMJ)HyxWfOhGUj^&EiG60Y#b!W;xc#YG~L?)wQhT2@LI&ThqJZ( zSg|{ofDHzu%0B^Q7AU#Xc;}BJzAgcAZ^Z*Gz6ao!+DWh<52#iV zKBe8|gu2zvBjGRbAfXLbG&}R0Ec{&-BJETW%LzzM^#*ikTB>L?139(x0iaJfg= zEvCa5q~MgCX2g-Vbi9@;X(ecByS5bNgwt0RKD->isoV{`z>7bf&~ z$dbk-c>MwqMF{W4gRz)Ew5wFqEfK=o@c4#kD~a;jS1(LSTG-MPdp10wC|!|^oYa^VNG zp+9(ZiCyWtoA4Mu9M32`oGA^$GaGKMQ8>T<6wd7joR}R0Z)r%+Nzgy>IKP7k<2%E2 zJe+wuKkf-Q9gj27nF9AYc%0vV3g3>nKgPqs^LuzWrsVjMqrgAn;b8k&JkIZb8lQ85 z(RiHky+h~U`EN$ttMR;x=R-W~-`SV5-+c+s!+0LYb1j|+@i@Q#zvVw6QiF@GMzd6KApL}*fbL*luZOa;$Yr~88g399I z1tN|`!}ZM`0UmzlKP3$}nk{T@vT$u(6By=IdU(MIQ{51Ufo^MQ0Q-v@akN@9zlK(K z3iduOONqkVBjO$T7C*nEZV?XB!{HLR6|aG&UopY_b!N*KYG(Z%fH{~;nZ~w`g*qZ% zgDUAz9?U3S-_eS0rm15YPA6O1+}fT=s^)Mw|M7V}`zN*1j>FsPS}Z5;6?IJ=4Ss8{ z-puyy>Utcg#va5GZksMsk8oC_K5&hdtWU91a{ZPQ)>tyl5R0bbBei#yncGon))g67 zhw7Uj?Tv5@BaL!_D!(!Zi=$sFz>c~iv z+~HMre0-jgkpC1p9@3^f%~@$~2kBJN;--$arQTpco$u%Ld8TJ=^Dd6WL30ol{(0P- zQb;2f&8R-xuh$81PCO+Pw_8^dRbCK@Hxkij5<-oav@g{s@<9WXQ1K3(2gLOrrs!75 zk}t=td>De@j7fE_WZQX-IIof~{8zO%wE2%mbPr#Qs!rNCCUOq^b4D_hu>Yt%M-6%oM^x2w8-Y0+R_%arb}Hz+bb0@W z2TSU@SB9y)$LL0JZuIGYbYNZ@tSY`MI%Zq;MUmuSa3cmGK3l8yyEYlin+f$sR-M z$D=qgZ)Q^2xA;cUF)$zgGBGIOLUKV$S`|;ryENFL&&$I}dxa{7r4~Q;!0qx>kdj`g zxe2V0JsBxVT1=lFJWMfkxL(AURxTY?w(>%^X!f@iZC274lb+L@x4|#c&)5*?6DrjS zMNUxei#`^8Jo+evTb!f@nM}gDK^7q57o=o%2EGSb?Mn&vki8m{{olRovbC89SB^y= zm^(Jt8mm!j?El&on7BE237W6DRugPkW4W;gm+o3)mp8XJj72YZD*EsG^T1p~lZm&u zwQgC1HFimBb4QDj|9=PYPN(C15%b~3I7ih9jz6*}Z$5+ZAgbkz&8EZ6d71NLo8j+7 zJihUfm0gN0W$<$*5~M}?L-CNFGuFq)X+3_bp5ZeZ599x*csYnedd`pZx|~Gtbi!u% z+>HApFwR+|^K;@&gNMHygJRl)<>0u|DF;`#oHTG+Ga#r}93lC_=D^*99^U6Ta;CpS z?;MjR50JmX!*rX_n9hs&EyF|T%!w8tUM6tomuVcFD>EKHQsQqd;yJP<&M^M2#^bn& zuSdKoPNn+7Zt=MpZ_fmrk4K03IW+k3hQGYozVdQ6qf_2r!R@3WiAks9{wF%j&k5sf z*-vkbj~?~cq4xybP8yOJJ<+l<=`cSh>`~x;dikKo;- z@KDum&g+G*=!IY03-1J;3FWK>#C9uXf7SxuWAN>O&iI4j_W*Z(%zpS9>);}N9)e$wD+{rKT{c7T99MmkAv#}*=dQGoN{dK zpN3*aifO72y<9s?}@_sZHkOOLa_z>sX+tgGUvq?*EKeAdREtD zxf3~%^j161gd75B$VGti1T0(t@(#=A&@csz#wf@z5shUAAn(q66zzik2My%XVi3oL zl)?s*P6Z(8T#U{$I0W_)kp6!Jr2lVVe3T4S)gkZNDN!{=Wuf{!g0lFv@9zSD^U1K(`q} z+66)+v25f=dq8*!A<8hqgpV_Df`L;FEHrSof%6SqU|@rREe2j};3WoLXW&f+-eKT< z20m=ylLkI(;GYb9%fL?!`cV#}(6{R|vpV6K7F4JJm{A&#SuJK=F@Mc29=U0D>e~IzG!uW4C{x=%`I|-5B;|4xw;422cZQzH5p!*L4 zzaRwvePI{r-=7fq4JU+uzQLy&yx71pLd35$@Eqg6ln{J08~-)~FEHU;@MidR2EWPR zKPLpe`v{T$UK9SLfzKQNR}B89f$tL{-Ny!gZTuw$i1g8C8UM8gb{qd|2vLvQjQ>vzyu*b5)`UM};2(|uUkv_t1HUvd2^~1;onYWd z1Nq{F{xc1%F|fhFE<%+1Is>;8qI|a!q8xlr&G3f|e$c=-4YUx(_(4L%=Q;%ApJ4DD z1B(r8Ap}1w36bt11J@Gb`5_^~Z#QtCfiD>Nxq%W>48|K|;79`}7&yzo?-f zVrGOFru6pxaC~1-pD(o+CABu-ZrJYWY5O*JuVbWrn|)!7+P#I|T`I7v9Pz4i|Bmzc zd?!?OzB>pf`sH-r&xjj7?dbE)6rO9?y&?^Vc}2U!I0lTz0jd-@lkzPbtIB#&cvnlX z>rtMeXzo1jDzZBF59&Ii4_e$win)LH`G796!>MiRdRyG#o9<%-bZ|B=3xuP^jveIr zVmN2?7!LPy$va+1h!ZR`KzSeU0&d66#5nwy2SLKS5XG5=6BVbU{5d!#aYR>M*QD;H zL7=5Pjto&JB5DSbrK4nnR5YAQ2LF6@LRpYk{05IzM?fqS#IkV|rMmJMp9>F7>6au@ zPE6r>LmZy)qm~r!Xe%)SCmanzond;Alr#-dvF*}0(Fui}i*$LuR)W5RH{#sEo9JGx zs}4Mp=4xGYX>O8}6vGNPqB;bskBNvgxp>r8igO2Vsyg=wCMr$eNb5Vhi}7%Jm&bQM zUdgMk?oHR1@*dw0CE&-Byd>I}GIv4w%pg0Wi%3mHAb)tJxQxbDg zXEmwwwXn0)f4&w@>pC-8AC@&d*^AZd%r5V!r@`htDU_UDW~MnpiYTh)6n#Z685rW7 z{Dje@b9HaF=gas*zmdB-Z_0N%O2uAkS=F!jx>bw=S2WO)B4$j7$ z^;G3!UBt$WUx1xkFf#LOxWx!qvNfWEiA6#tQi#uc= zGYAF}HjM%ZCY*_RB*3F69X`Pl7&!z3p~r_JuD%}_JHgnCd&Tgd6Yq?$iHHm9~xudt_nC^zQD9OHsu${ zDwHP<2bybB^nt8m`8C!-(M#%Mh<` zT0-V)fPJnDL)C|pFf^^t479d{(H|)+*k>n-n2`6i!XkYhgWMC&(6n#{mCZDanZ8eR zNpi=(0k<6q29Z(P=kN$WfR&qs$+y56xH%Kro;YP6+L;)Mj&qIRDw8FqVEkl@Q?Rsy z&!VA4Lc9xE2F1)Qh)8gx5*C9Xf&}sBF({~b1p1#SvQI@r5yfcON#f6lpDexx^L<2o z7=$H00JT)Xs!J0G&;*VXyx6&~Xc~(53}P<+)5VWL?RfDnIO#7Q#s2_tA2`Vn6`(dy zjDpskAUJP5QOtx=4H64L=Ol3}(w;0{M9jfr1VoZ4%8}P8ViQU?L>v$PvqbY?d_gIW zA?8rg5Bv-he@4vVVn0%i5dT6O94USe`lCcPD32E0ZZ}4}3ZGL&6sB&hxD#~7iM=oq zIidv=as_Wn$P+KXf4o?bjZu=g71eW^=mV}Mi1VPFr;Ao_J5ekJok`*cNOguN#uD>n zkpuS>!EOCh#WE<~H1VfVI0HgNQPMq@7=XlkEm4+aS&zVuqwe;hE*3yMK{>4h@dfX` zw8W(lHa^NmwgK@b3MWJ+3KSGOQH>$-cN8luZiYok5NE+15hY+VQQQb&NU;Odl0^6v zR@4PZ)knMtc2YzPb}v;dz<-)(!~bz&J&ZwLaW($?i8!h>T{OadyqF3){RIzb8X%s* ze}>o$;SChGKzJvJ1}Mvkq7;+|iLb%KNrF?#lSKxUWw6MCPo~Jl|0&|Mc+hF5W|4Bg8bwWuz#>|0r=6d`63xQLZs!v#O}iP~l?*53w01 zqELYxF%mscuGoY)dEzt(bG%py?avoOQ1;WrJmfM#e1H<2E-r^Hm?*vnNlp?`#5qIM zq1q>ld{puj5d+Ps;ue%{nph0QJX5@mN=8NTQ$SSIZ&40Z)Ewy4K1&oL*Zr1A0+~lG zaWi5*W{EeE!Q+9e8=w5{IE} zuUVoWnE#t49)a{;x5Pql_J$=sg6!Y4#3C^NmL*O{F^^c{09wUSOFV-FZ(E`iMR~^( ze}*jIwZzL%mA``+GJ4Mv$APo=El~ijKfs^^Rr{eOzKfV2LGeNCV@sS2@QEdEfIRr+dN1NIq20Iol`L?R^dg(dz9o%p9Erb5O3Wr>?W>`P0`Krz3v#3m&8+7fjD z$FOpax?gLH!zkZ6TkJ*6USbQH{7zfk0r9N21&7KTY_SGZF15v4@Oc@+05;m4)CDqDElvX0S0g_N zdF|Sus6y0rfZst4UIMt9d;rdd7}f*+1~s$+uo(^FQo!d?zRLig0lpFNZpgO_@DK!b zIp8Z$>2AQ0FbP)xj)$4p1h^0INDB>Wj&fZBcne@B;6`ZedcXkaZvZSq z9b5|d9niZBurJF2_$d^*3-Ep@!{vaFA>VGmV)$PHxElFw0z8T30OXqSRe;k0Hv^6Y z+ya<~+PNC=bntl%;7=g@t$6YyGQjHqHv+zvK>38krI6$0fG;9lH{g7f z^9sOeXx^IuQ%|LQLZSo&uLArj!Z!on553v~_ z9q^}UO1A($lZZ{{fGC#r6ToED$E|?*h<6*{A0VgO0jGe@9e`=z_fEj8Q7=CQtOb4- z;4oO3p8z7OzC7=il%A4NT_ zJq-TPR@VX6px!S5Jc;!On1+1U1M(~J4S-yez7+60ji|`il6i8X(L*y6{<;X8hJcwG&6gQ$ya;*Np1#3b1XZs{X5LbhLTkwnLfJi`@ zg5rB<;UU3sW>_2rcL`z}a*BvL@RVrvp9@96G{!Dr>Wg8RZSg8{4Tu3lnfeIwfY!hr zw)%gecze&jjB#gzmL--W+!muDm4Jw#E`s7JuoDuil9?Y@{1XHhBp{LJz*JCvVc)~l zt41*O0!YLb$AMBnd;kdwtN;0AT80AeFxFkDB}@ERm8lKk0WlH!Bg7b#32hX09TH2C zIxGgF{u8Xkda#ow(*mcVnaBq~T^<*>6f`(X3QDq{K_ilfxyf{uFp!mO zVbt6Kwg-@)JYI2=xCQl;A@2%o0r8B+MV7qRrM(QS$Ol~7%T5Kl%cVUQRW5(4(vfz` zE8yr35K)tgfcm$s0VFT?1ZE*1@c;@wT|O;3AhV1X?5~!85Jz-5G8Pei#h?+n3FVi6 zQ85EqY4U_jpnny*(CP9Z)JPsSXoj3X^i_inl2=j&ZyGdH?n2|1Z;4IRo~&$n5PBew zhR4?g#!WRc+afec{z zufaYK=uhffgl#{a_AvY#tdX-$_rsUfaHM+ z(ql*@hZr>sN-n9%Q3j3ZCYNi_Wce)Yo1ARWG`X6ssL-J4G6RN9&NaG|A%DU4Sz$s4 zq45DdJIJ*Ks=qQii%sYVsf><;j*=nUu+V-q``RGWXt4-)c`4@CC z@|xg3QMy3Z6nPE{c)baoE+1gU{m`I=vXY_OgPe>8vS!I@8lc-vXsNsmc3R$H&~ll= zW_OoCtK=17pg%Kct&EeapBwaSxttc~0fR1(ze9h6#VZC7xS?zKOP4G(wT`6y)t$o#yx=60Xs6xK3LPgeEXf|8MTLxcm z%O-ODzQH%z@;cVbhrwhF4n)=!wtSQg^JCR)Mb>6pUWp!7{=>xIYD?sXX?N&U6(242 zVM;$7B6A`OE%hZ@kOYIHrG7$gBL+uHox_%xXmGUD3@VW{I9lp=*?A=y94++{)T2x` zI9lp@^3%uQXsLYTEz=E-ma5FoiJ^UppFOs0q&l1w8n5_8%e{fsbaDvR7yP~s`A|&< zht%p())8A4lb^Anb5;1ew!D!1pJwQPV9Te50goB{6I)JZ`Kt{6Ins{;zR=)b+Hw{M z$>kwdJnADLKVem`FyZS1^1EP6UKTn>@wYJ`&q9lkn?oH6zak)quzs#L@izx#JQ?`S z2HzTxC(}f4H~94dIgk1M)ZjM-kjrs2~_^ko?0ORj5{M{Llzonu+ zV(_~IvW;zTpP_eeK>n5CPlmp)_}dYXnbf!6nebf!IiK=)I$t@Bp|oYK#Vl_y8%fvDsv3}K|tQe z`aj*!|0E!%(nicP_~!x1B}w_c@F$rp|Ca&z6-~+_6TVi+d2C-TVXa^5h2&S^a-#{~ zDC9Uc=c^2Ug^pzGtXkoPdZbc4SxWC7)MqQQ>{S;g=n27gz`XIQ?G2LC|F2;=7% z{1c>S_~e9JlsrBca(@7LkqQ4&$RCiOYJ;y0%2jCj@@#{z56XL}uZs-6F(~)2KAQ}F zMNmG<`e`-z=AazKLC?yBeX2ce4ay9*hf7WP^+B1+_IkC!Zwku881c&=8hm?DPB<0# zod&-(D7lkM-e>STgYppD=Ys~nJ17&_UiKw$HAiIK825qe!`y={R7~a`uC{`e<~2_4SqN%-y=TU;I9YewXE-4gC7aX z7pPB@4E}CV{*(Gw7|G6J`9BECo8XY8k$p=3p9JOCly9|(|9Mc}#r)4U_?JQXDfz88 z_}Y-%%=G6Pe0@m%g8F&B!8eBFTN3z6gI^Jn!&$#;48A!e(L5}9t--g3Q9hvbc{?{^J; zAS4e^|2{VOQz5yG{QT3TKNylPP#$)ossB($ed}WM?}?h9mw=z&VxbY}@Rvg}%=+nX z@WUaQ1x1r58T|E-oJ9T4Hu#Z{e24wXXoJ5SlJ#uAc?SO=Bxg}xlT3b}gk(PTBWl7w z56MKvFERL+A$bSePr1R@hGm59{cMA;56iFEKhzt1V^}^%`J8L;E5b5Bep?N`IV{JL z-YSD{4a*;~{j4$g^P+!`1Y{;E9JY@;J1e5E{;ELF!-Hext#6c z7K7g%mItYycNqNMuuNio-ed3`VL65Mza#Mo*cMs4!g37d{jdq&6PAU;fInvBwLh$9 zF3*_w2f{Ls@_y08KN!|Coj)7=`LG&GWynaTR^C-*7-KM%_*slO*kwPuv{CE~MwPLXOw zC~IwkJemBAkZO%5Ykh(|gYq3G)jCer#ss;9@|qyk%1qW336if#N&rz2N2`LCuo~;{`JX&f$|zL>FjjNi*I+n`7@Dfs5b~ z2~I)F?58f+A^SQ4T?o1fAdU0UNRZ>PNbqZTpKt`K5e&+clGwS*ACmo3l9)SdtBvh+ zc#?p8P+LfH4YvtymF~x^;8u^Pemjhon51j&X@=~3`&VFVH}9f6p{^3Ys#*k zn)2Hon(~;dDQb58wA8cfWL?{bOl_y>+I~S%4P>S3b;&p6SE^1jWDpxwy)MNS`y($IAH7(? zUW1&eR;su}qn7068Z=ukNmiK1BlJpcr9pEfzuS>D2AwFkBY!#1pwneP+W1;SYL@&Z zN`ra7ZW*O=M;PeYDJ_cUa(NCzzh}@EnE|QDa}=u9C)6_V0+kr!V_VLLj4)_m5k(f( z3)H&fQWK8#f$x#Cb4_}z52%ILRug{Mtn^)AaI6og#o&#G9@YnrXaBO*gkwEm0rl-C z2FH59I~*VV(%@JRP%D8u4UYAI^EiHg*yO)9pqHW_G4wG%UlT<5;|9mgB#93|lgG#> zRUOJ9Y+%1jxkAYX{TQwKQ;IlS<0y`GpH8_?g=WZiXkDL4c}t;#cp_y_z zLl31496?>k)(!i4qbVbxcT^|E##$sWi;M%PZ1O+~^-tw`lM@y+I(#=g()kApObFYE zf34r#h@!%@k}Fi%HKp#Xenh7`65NHT18uVE5c|7Jh8+8viAhKGOne5FnceFzUiKL_XPxe6oEB=-62{*`AJQyYcXs1pOM! zA&Q-)1jifXm@=CwpGSmKn(=oro)6(ML|w`p64;tu9f7xrX| z9#>@z=68qoWX*eI@TC~{+f!H>fi1~{_o8O(DXbM-bTkM@(OC9WYHnal`ruE|DDA0A zJGNvDewxxT*dS}z2WX;6w@qMjd)RickaW97QfT7YVvSuNb|W%Op2*!8ww?B8fE2at zKN|ap&P7zqwuW7Xj=s;J6XAs@Um?n{XHkMarKf5iCK_=?1fc^c^AIvclz+>C$?;q- zvB}_~Z)9+#7su*=ECUuR?!US`XIw{H>$v~5%W`;-6pqUptM1HkZo@%WsLovCZ8#7G z-1;`0pm!S%yjyXQRx{4sLnLS%zM$2Px)mMmjmER3apmG=q=E?M^cx@$0Lk<29FXA= zAI-~k9310h?#@91)B_kn=agZq+cj{v!~7*Vch6qZFfB(UXNvZ*k-oE+-iA9oW=Br> z_2itFKOFZ`WXrbso%eM9Hge0%+2h6qPU{y)gRr}kv-k1th3TLc#ltfd2@AD5LRh5T z$%Mt)okm!t-RXos(e50=+l@cr9on5nc&BzJ6aG}YBZT*AcaZQ`+MPqVOS{tvAJpzN z!iTgQcZ1+tUG0t#(rEb4gggiMB0SiBj(_Dm4-h9;5|AS}?*brEIPtH3SL6R$JUBL) zV7qcw<6r&u;C~+;=0uo^I)gitkfy=U0dd~jOFzQzYj+MIO^83PmKq3JThTD4qOIY} zZ}*FHqm24^rzRcP+OVXt4I285SQbs}x25LS;L4_cTVQ=tb6bP5e%}_V8w1(HmPm5W zA2}Tg7_EslENZN)TGi5E-3Z)00+WSu&Y@#9dIwWI2Mjtr5ofNwqMhoLvLo89&aR>{ zbIz0ET!?NJi8hSL_&lWMD@-CP2`vbZ(}F)YCi4_3e9?X$P;O`=YL3a|W@h&kFm48k z)>N2AYjL#gLpke?))X|=wY6EC(3Cf>Y-lQOZbfsnI5RH5xn%Vvg%*e7m37Nnni@ZgCnP z*Cv8S_&r7qKaQa}ArH*ZDYHn^Z?cQlB3wciA@^N(VE!W0nTW(cGW96kqN=$Rg=J?cwbyikV;PZ)9R~D5=3ud2gN>pA^ z5}z}}D@;{Ib`|&JDMIAh%A&b7C51(0UO)}1q88^5#&J$&OG6X2wyCjwl@}pa zo*yl(GzUaBtZb<7Xm7}~aNHyGjz=Ei z)me?6Xlmw;_aau+7Fz9%D55%e5WO?+MAU3jw%$3Jj`pCcRFjLhFKunWd7Dj(JYrgR zDrb~el*RMD-P@P7KX$&gsG+HD6;#6Q(a?9bt1~TK&UJ#4STsJb(ywvFrM~7iBUbJl zbBTVeq_QAdQ5aXc($d*!&IKK&1s*fu^uVIzx%#G}<#f`172EAt% zo^ae=tHL)x@I1d^jL^STj7LLS9>+j;Ipi5DDlCb{tLB#%#iLbK(SljAqB-cLaU6fc zqD(ZUR@IPOeG|e0ruc|Rz(@CRB2g3ys8ZSVzJLY#ZY5KGxPle z8OO`VrQ<~&o9f$Jo2*40#snyX!f7@-m$o)`5PJ9p6VzJAn(k%qRsZR0ay4bO^P&|+ z*7+!Tldlccl>0QGru;NdxHaVy+`3e%i9wKC;WgzGdmS?D1{GG86qL+CPgUaYQ%h<~ zEvF;p!M|oKW!h_xn&{OXPpquLNUUUrr4?Ko+jceHY`}@jN=H1#FrxGoC|0S6%!*t_U2{i3G2^mi?={W^;ps^N=4aRZD35+bv(Aao#VsCW@?W+lXO!Q zmzETG%+$>AB$%I*6ZIJ?p0@pMlUH>p@-j@sberISyQOYbQ!`qxGPT;~aKr$ugXN=+ zy16^5Z|PnX=KmXW0B26&AG-O5VU@56vvmdN{vK1uR-9suERPzZIQRlbdHPRFhnF&x21I+@P*YMr-Pgg*X^7vtqZ96{VoUoYB@}6!{=BgX!BY5c~EDc2Q9BB$XKZlDZ*%?yeKy>-wWpu(F~K- zTmv0g-4bmKl%eH;<1WLo^6}BaYOAp=zO2JHlAT!@a~XiG)UtvtT-MOOwAt5V$6~rZ zFbs~Lzo^kagq?>@4E5!o@t9g_uCMQaovVkU>nVpGnf4r6%`J@OsYN`DOEHzLi!Z9@ zspa*Jv@aN%sk&O&(6ft*D#^KpD~cA3ry~FR6&@Um&cQdjM9dx4$?D*!sj0EelMqKR zRYj#mYL4Vo3iJme$1n<2%+a_ySQyJPZMiUg%U#iNurT2?bk@eYI8!{A!^)W@ZseM1 zw7eu9D=R3o%<>BL&Np7HC@S{Y@TVD5`Zn-n_hNl^a!! zvUNAE)&dsmDK@*RriPWU5(}F;THT3{33YR=g>svwPow4^NV##mdMKRjGwy!xe5W<) zr9r0{Y*(btDY0IHTDDLzsgJ++Me}u)ZiQM{DAZP$gSEC*%h5cV(Nf%^bBLpK&t;V( z`;yWbJz93uld&NUvFq7_8MM*H>5+bqYAcLZ`O+5FXglEMHJ2)>OViwfhJu#fQQz)m z7Ok#`=2_4`^dPP6SP*fPjP`=ogk7O~KY>TKpa|Aa8wAh#lZ=Y*#)AU0Uu|nx-UiyL zJ8hQ8GnS&V`+Vp%q2Iw)s^UsAQ&cJfj zqPo`ezB$A#pBY0-@`mHR25GZnH3en_tm?6cfryp+2DPzrpES{-cwBP6I#114Io;3; zkl%87hFf0t(zVw4s!?Jd(tx3SeFJW>o-Enb20j?@x2iJoKtaux@_61c%6X@4fM?jE9aEWQ!^^nU8+?Gv+jWjs~K(aI9CgoTe&NFu6&)^)aIOX z*Jiz(=idH+&Z}cdd>Ll`TyWuaDc&NkD~jUMXyvTR8egd@OUf%e(S9d3qsGIqriB#_ zww-3PR&DI9I~ZxLyTCMPFO`;we`PRQRe?U!H@;v`P(r%y;MC=CUd%sZ0OsQrm`@Fg zixHES&Q$_uq~{WgmPS#LSh{f*j}|Jcy%4LPz4?t6)>?I~7|}GEaXQXJS%@_(kCs|5 zoF9!vXZcK&GH*R*&gIckpJgqqsx-E~B06Vgky<##oMt)XxrAyMcc(jUMl=VxTF>-Y zk0zr7ovGmn)6r!dAmDJ|Rx_#axKxHFFW*0(u8DCG4O0`}0JwUhZZPgOI&SV2(Rgk? zR;Ya|$ld~2uR$gXf?mc9QydND#3?@?b9#SIt92s3HfCMWxCqy#V3?pLm_01ajIye# zvRKbqWYxTqIW==FtgS%xu$bu^t+^~mQOS!M+gh*y6z?S~Ex@G>jZ2pLx(N!YcmfCN zE{&2HX<#JS&hd%ok13(Awt*GXaKMJdmqHkN{Oet2ZCn$Ks`B)Uis9c$S9v8KiqPqXM|)+E*F2=gWAv9mhol$;A8?B(>Z zz~u-NRIEnN_UKpCU_kFw8atASetDEfW7d+U=7nJ0j51-;n|XVaM?pdaTm(shT+#1$JJ#xe>h;AD{iNn(4Ddv67g7mRV3%Hk*>;3K`AF`DhSvECyNU zJIe*u!d6U@)WqLszASv5>|2JS@qhyBS9hFvu}@Hzd2vH~{n9wsi_ywJ*JU+Y={HZn z^1MX>j+5MoGm5HaRhAW3aj*w%S4;Z3I@O9^rT<-|n}{#A^{eO0(`2B`4UFizp% z2eT!Y5WBzs#yv$Ge|d{YZIHEv>&DKj!v!dq#iH}_+2pxZ6)<5wgH?%3&D;!C`|Vlw z86|UOD=QbTDD8FF0_nre1}a3&Wf@r%v0@vwA;;@`74g zU+5BMIxbhW(K+#XsK8zx`IedxX`AiPq>;pQyr+>YEU)zvt3K1$913E-=Ab*&9`eEU zQhF|;-T*`6U^(=xRt<-HO}d=dewb=5;fq65r=HLBUQMpT@ZN7FFhBK8;CfHo@j|d< zjvHO|1pXzofN%V(7o^mwaLIHS}nc12Bo4wTq=`>l%9h#JDMTiZM{oBFneq}~>9 z(s)a)E$Im)B!IaBOX^gD?@cCbE!JYufa9FJx;3aR7+=I-9ksG3S_or~WpJ#}nwJjd z(l&F+nVXIsor|a`zKa#ksl`h_^Jc?~5LdSJJg**k8ZMO2RXmYTh!4D1Aa}N zhZQIeH~8L0XstcGpdK@IuY-rupv#G?7jBlj&}#aj#zkt$s>hnISAybFzhz{* z`%YPfveI~Gp^Kv5<~rinQx!E&`nK9s+hJU>m8#VU7p*A&PSm17@hPKPO<*>fYNg1L4jRu{`T1P2^X+Kiu*rQJ*?WG1RroS*8;-NFhhkV1 z*P||%&6?O8pCDqDG`4OaB~9)dlt7W#y!)xIYpGkY7@X)=`Ce%;P*| zMzg_kS*3q_iyrXk*ZVyNJUUh7yke}HId4w9?krmBvl2B0c>UovL6>v2l-p|=o{Bi5 z6zc->IbeV)a;P;k8jD5qCPKs2n`~>@iX5L{J$jW@K11l}7tSl{pQE)x0{9OTS zD=#M}$Kt)1v~Fk-ad#ER(I(y2)ci?}bFi7EqeTyOycKEZW1^_j=D*Sffpm6J1;M{GQ$QXYepBUPnZumA(#v z)r9P9ybbcW_RM`0mZ`-XS-Z?tmd(NR%}GrIq2BtV=*|`ozG0?8@3GBe zUS+&yZd5P%a|@bF56gjNbGXdydyg@@Xg=Pab5ppRk($+_6i&umyzV7%Sl`x$mWDd) zz`-gD#nG&j4dSw&@#T#o@l^_`4~yy}YbgKiKBMmr!bxh+Du|8F-piQsq-A#>Fz2Z|RXHMNcx@TkFw0 z+hL|W+A-{f^f1kU5>k(Gui0$ltm*esIJ7^`tN+cWS+{g#Emlq5zHR(x>e7upuc)$W zURfD7x6CQb^>!Hlf9!n=d{ou7{+yXfG9*K0fB_;#9c0jiL`-1NpbO}2_O}1q-nQ4iOG{fR)=GsGglg-P+Q+?B+ge*t9zH6Fw~+t$ zt-a2fGsz@ijlH+`-ueBK@9cf{UVH7=+H3E<_CD7dJ8W9@U%lw+Yg7<;YQVKZ6hur0LjjmU>x|T+ylP`kinCh0*7enWE zNKS{)$38Ze*=P;~OR7|sW?Vj_hSE*stCP_g+yZf2Sns9%r>ND?{6BINK8Yq@8mEFy zz1n6STQMKtUJQ-7kXbHPr>N9l;<6`&0Zi)6+_|&R5SKJ_Cy^tc>6hvA4y>gb>FjW2 zTX|M!EGo7rZo8ED5%d{c#WQ<;Dec89cBWF7Q3;F1V#4H5$By|TETGvrySqKoPh@RPcVLPIG}{7 zhX4E2DAQO0yn`=5>ssufe&3nL+;Hepeo_3VyIx!#PZh8Yf99LU&L^MEmyIvUFZ1#P z&NF&_?fIg-nfxkr`nR5qAvwuz!yoD6qsO(kdu!T#-l}~6&h4Hk{P^R^l1AW+{IYs} z@%f4lua{qo-nBEuC&SSk-R9eNd*0h`CHMPLeB6V4@Vf@g2l;2Z#LMt! z$HAlL*0b?_VV8&fcnRLQ>HQ^f#T_bsYY_<%)wx&ux=D9v)M(e>Q2JU~|*+e0gcl_J0XouUqB=dKY4{11n{Ei`<`)BjV?;qRG@_s2V zWl#OcAAi{h_a!{Jlo3NYLo^nA$WCbu`>FN!}q{GE8N!e1Ny7@z&r{_(rX58DnP<3G~N z{S@5W@K=vN#(x=T{}}!a+X1B8=c;hJ^We7i1IAB%w>Y(?)Q=H(rdg6~aAf+BF~;*n z7uCJLdV1ZW_s^Pj`OLYC=1#AM#ooY{i+2iWl)c0?*O+ zA5{NUKz<)NL4>gQtm0EZhW{my=}@lmd&F-MRSED%jUM29cNnKKDPJt$NJX}6es_;@ zgGfFtbk{TVJ%$YlU!lnHmhsu1iL({!73V81Qe38ZtzxsHjEjhWo4VI4{)4it>G8_+O~*OB8vlA;UK+^3*lm zpHTd);@1@)P~55btl}RP-%#|TtVw5>B4sz-XDd!qoTIo<@fyX|iV4NfD1J?Gv*II) zzfgQp@eRed6|>RBnSMm^bj9lw|5@>yit@c;gx{&|Unm|?%tf0gy^)Gz70*;WOL4N| zRK*JwXDYr=@lr+kt}*C-Slvq$S14Yu*rNC`#kGnbS4=A2t@v5RFDQOR@mq@DQ+z=2 z$BNq(A60x(k)QZt{{KVq_lkd3+^_hC;t|Cj#ViOC#?Mn6rZ`&h6vc6h#foPuPEkBx zak}C~igOe%SNwqDBE_o}uTkVD1jx@nDc-Euu9#4~OYvUCe^LCB;@1?vqxb{GEs8r7 zpHk#Ul$h>s75|{fZ#~iffZ|^i`H?&NQ-vUAD+U#ZD;6l8su)w8pjf7Oj$)-^wPLN} zC5m$uKd87^ahYPH;!4F<#ak5DDSkq6z2c`8Kd1O_ieFd!jw0`>Vt#+5xJ_}V;?EVI zQT(;y^NN2|d|B~T#Y2jJRrF$PU^)TCe8q_37{#dK8H%Nf^8IVXuTb|i#Tv!giuH=T zrI_hmsd%+wqoRBt8}C=Ed#z%p;$4cLR{Xr;mleOI_>aaDc-Ee`y1)srT8hu&nkXV@oS3TQT&187RBv~@||wbds^MUR(wHGzSoWS z`_=sy#s5_FVxmHRhA4&=M=PGHI9{<-akAohiqjQq72mHoUs1m6jdYf(`x?cSimMdY zD1Ka#U-ck=_bT$XRl2{T_-(}>DE?US5yi(9pH+NL@g>Fmif<|&Rm{pY>F`T}OmCzj zKY2y>c*V06rzl>aI8%|ITx0loiXT?ITJc&%exQ`$ZdUA2Oe)^1_<6;zD1KY<2Z}#d zd_?ha#b*_tQ+!Erzv7#UM-{W6NRywTiX#&$mf{q}3lwK6&QYAF$lLcw_iDv! z6sd!W|3sZf`zv4*6QxwN5o~1ZN@dCw}igOg_DSlY-YQ<|6Z&GYmOeo%^ zc(3BWD1J%tYl`1dd`PidahKxbin|qmqxd_;{fciW9#QO3%)(L!%Og*5nBr)~Qx!`T z%N5U6yg+e=;%vn$6hExU+pd|;3dQRcTNFR0$nTjlT&Lo_it^oe_=UsL>!;zNqv zin|maSKO`m8^sqCUsBwsctjDO))qcSE1scPp?HDf#fnQ6Z&bWZ@#~746kkw0pmQHtXgXDD8#_z}e> z#ak8cRQ$Z+2E~UIA5;8|;$FogibJq;#`I58ELNPVc(LLK6jvy&QcNg*R`DB(6(bDY z8pX>LKcd*Ac&p-_il0~9p!ksDV~W2~+@p9{F&hhv%*RN@nBru`YQ;+x7b{+`c#C3E z@pFpbQv8wPql&!snCbml@sMH`7GCHdQ5>f@S#gHq<%&xbZ&Ykoyj$@;#rqYvEACc& zQSl8$AJ(Rr{s_f!iu|S}{bwlh8;W!QI%N3U>-l*8Fc(>wxiuWsS zSKO`mqT(BhKHe3J^5(aHiQ^O}E6z~7Tycrwjf(Ax_bYB!+^zVc;v0%StO-kcisKX~ zE6z~7TycpaZ-r;PcE!6D?^C>Aal7Jf#TOOdQ1oFfTGCe>r#M-0hT`RlOB8QZY*)Nn z@jk`-6}KzyR(w(M4Mks6(^nj)I9YLq;^m4<6mL{)SG-&CK1FM+p_{LGisE^S7b`AM z{HWqhiXDpgDBh>|eZ_9YrxagMJfL_~@jIs*KDH?SOtEB~@vl(4NO7qmzox}{xlQqt zieFURsQ9qrxR?na8E^1(#d5_e#rG@nvUJkFR5jP zPI0p048_Y8mnhz-*sgfD;(dzuD{fbOQSmQ|)|n>Vu;OWo6BRE|tW*4u;#$RMk%@nn zVx{8y6hElQua2>t{z>t6#d{UMta!iTlZumyO}q;gXA`|1&n1f2seg;QS1I1B{$Eu0 zmleNG#GLbc`uU+|cC*+l&7jZo)J{)y17F&u~+)hX^$byujnQr&l`d%e0hsQbI>eoEcH zAP(_(ey8p~5_6%yedMZ-ESY%y*-`zKPo6Y2KBerObIy%M%W)pV_5YlBJQ|&PP6hn< zTbz6A%(_{Yg$(M?!ai`yg>Pg-r{FIx|BJAPI7Z%M>MpMNw*~NdJT~+>LNMl!3z_<#>0uB0>>uwQe2)+x^^1Lm6r8%qCT9c4<>3Oq0LAl-2MCEi9l%cN~`-%xyfLDa-}yB zfH!=+?LYA$u%?!*`ySq0x&4))>)pS3<&R!b{>=Q#_x!b|r)TYUv`SC=zTmE!n4hJP z2*#4_*y;CleT&Q_kk41n7d}Iq*PT}7gV)~Tr;~9{;??$@R(o5_e_`kJTNAH#PQN8| z*Y`-vAG6wj;%z5AT%nzeCrPKPo&Q6d?>JRxKSY|Bcgot|@l zIe(Zn+zO+uW6Rr@e_r1Cc^6~8<%@ap@}}WEwxabBwV4%yFFFQ+p>jr8zWlsAM9Q+@ z3=B0CvMwIM@1Nt&dqWW0+fKkd2F%ldAi{t_%er_3{fCbATs-1zq>z6G9*_rw3mBFd zE<6#*(RpStDs-@;X1|At1RM_kBPLoG2JOJiVO2I0h@>KTL2zU$3Z0`)vC2nWX3fi9 zkoN&FfqlC25nhxGJ}Zg`1UM<~q(}cTaB7Md1}o8JP8R;NAR1C{81Iyn^THrKJlum} zV?^;DEsG_<&RZ(`!$5%=)P~Hd4}ewB5(== zPf%xNfW|f1rPgW$@{X$t9Aw}!YnnJ~0=Z16+^Q4jEPfitlRe3LLMUGp$Rnw9tmnm9 z8=zfi_J!6R61Xm~l5uOTe-`K5z$!W~R_B7i8aijIb7A1)biPlWivxGkS!Y4<0#{1| z4+# zUMAy>4@LA`+CY@$6z>OwV0Z4xnP9?t^8OWca!NGCydTn4YFvT5NpzKYCH-I?yHZZM zafS0vf^W_wIbsi?IF4z^J!C z1#8dpvu+xF5~5H?8J&*@5-iBVL-r><+2aaOk=cHh$_Q&M-dML=ivcp!0bfKorh0o? zs<%s~?No2qR6*f1ux#CHZ9`0ow2eU8I*`J>O5vmx9_!PLaXtc^)S!-!!r>Xyfd7H7 zu=QEim=ZwXtHu#zZPNNdnj1b_^)TE+Dn1Aw%gVn15G2PVuC?*e9 zJ}o51&}=8SPK+H)q%j|XPtG}vZ&{MY_iYM2pzs(dKXHEMy=Q? zQODd2#&gcwD~^0d5Mq9e7!v$K`S0@-vWr_|N5Vgg_J*E(T0%%znlPBKp2B@d*P431 z35DnUF?cML553e}D!yzz;@f|bX%XFw@LEJ#B6k@dSBZQn73LI{h!vL-0gL#Z!cwrN zNGYffvu>R$Sy!JK^f|}v!xDiQ!k}lFFj6dHiS8A9x8r{9rE$eoXRnxCan4z|7rCYN ztdCyTa`s1;EIE6{IcZ+;iBl#{vOf*uInH-tCY}wV=36Wtk5RJGGSO~Y%(b}q;0j#M zr(KXKIcNZHlmS1_avi_hf-V6v@~IX)8Zvf7$M?7&aQTbJiu%32i+}VV7hF(1&2RZi znm^jIss&yT-`ZRU_fF4`qH`{)pL*8$(=PmWAohhDmj@z&1-`KNbSp5zx3bbVbioC_ zl?yyxgdGMc326KyVKx6f%YPr`zt8jE1^gE{-|?KprwabN+VSgf{I1~>#$Ehh!GF{E zuay5T7QbuW=ga+(H-Lu47LxuO63EHP#xF~M{$4-daem%+`NQ1jzx0=08vpxTYrgx` zt82dY$ctl_UU=cKX&J( zOIkiY=gRBXT>OC*t7pzz+FV_~=(=fjA6$NZ?ffMbGcUbz%JexOm^|&`d1dF%te;p> zT~{*Y!rJ0V=g&N|tYZ53v(A||u4MB0V~fiwqGwK=a_ab!NvDh}E<1VbnP-hTZG1_= zspE=A7mhu1)XCBDBgdRNE>dvH*b$>oK5h7@F{ch2c~W6GGWz7uh*2ly4Ep(Yi^XE&$B#ebj0^cqC$>6vO@3vFINLl2i1q4Eq$+?gGHb`9s0>(g zhu>F@cW%bULDQsBp2zSlZof9vv1Q8?i8y$&A-!Hpj) zmNiQzWTxq4XFQ&GFdcVCa^C4&B)M7~I3|u4oDiix6!lfO>`UU=WcVx}e&SSv$A$Z%nKiE?z_k%t9;sVW7zld3xjdzx`+y`8uKtmu$M}ak z0Z`znz+4M(U%8*&9_*Hqs%`rKJ4ta);V{ax{D{nZLwNy+NrKeLq1-W`mzvpJGr}TX z^nzpUE!SR`s$;#v%6(a;eHlzTciLLt!I594traf{TKbK7pe{|`)iR}^(k@t%9%ie6 zl6`aOBG02QlB?u0oSSDENC2dt`o4>(mpnVa+04ll+?wMbZJ-Nqx1{1&+0NA-h3}aZZp@yywStY zoiyW4KirFr`fNe9JB5bEiW&n=%OJLT-S^?jCOL6>w@^=I6`b;OKj!;) zDdE7Jq%OOq%lT&030xQGTx@Ho>vcqK86a8UwMSPwGRV%ctLq?H2xjNHqm;08-|I!@ zT%T7;7e4R$tU6Z=?H|W$oJFs{-McDxXTE<{9^3``axw5y{NerkZ})nu@Ltvg_<9@u z3NRqy-HiMo&ZbY#kC;R39o|dwqu!(Wk?FlovH!i#man{CE-#qa?-_F(7@KIWDIT07 zAxHm(ki#paA{BgwL-)ZpX)#+q@- z=yrw{>2pkGbc}cMD=-6`x=c7aO7O?<#|u}6FfMkm!sqdoWY=aq#H**IbY1DVK-+cnRL6(L({)qA?3Ypet-&ANKL^TB-sgE;F#}tPmzob{FSfY5I;>C&!6uFbb@HZ)TDBh!ZpW^owyA?TJGu{h|2NaJg22qxL zf3o5P#i@$5idQHuQ*2S}P`pF&Gm2kT+@yF|@t9&h|+e}nqVS!y)OHTpiGc%O#* zriS~D;`jBvoPkFAFKM`a`ulF8y01|8QpFn-+ZFFs{FXtLM z=-M@?OoA)3`qbtg{(TFSD)fkH;sp`Q(X|)yFJSiDJ7f)X682fniw@Y`ucy z6G-qR>R`-vH=o3;t)i>R-&GsvstP8Ku6?P;1n?*PvBX>5dkVVN-R40H_pSRTA@QaO z;W)eZ7wB_n^IqHcarh>VIR2%v?t}Sj|NK{UX!YxYmn-7_#B2J(w{A3(32i!MEj9pVw8FNrf=Q%g`Fp0a^?!v=XLLQ7K#9wE(HeK8)HE$)bZA_o*sCG+jm67 zE=&uQ!-8jC`L-+Ox9{_JwZ#fi!z|5$_MV*3ot$taFGBhFU~`6|N|rvt@a5Y~?5_CQ z&=ZOHZC%Z4{dj1;&5x&mJO%I+l&2t`!txZxQ$(I3cq)*m0z4JUQ(^nIz|=i0-|C9T zlKwZD%+y`CM8rnVP6td(-F540?K}L^ByRG!+C%%k0CVgz|3glq$VrSgfF#$k?Uof? z_w#9&KSo#|+Pn(ww;F%N#czc+pVzhSb{2Q>!O-RvUf;ThO)aeUiia=d;iEO6Z*Hu} zhh|rNP+y?1{bXUPKi2XUJowvp1f;0fv%QkP=7IS;6uR>VU@M(R+EV__d57GW%UOQ=7qKuZc%MwknLtW_w`hh-RHqZ~Gc$!gG;j+(3njp?Y#>KtJHm5a8kEjHv48wLbq0U8x*ww&x0ACqRnA^iqR zTx>0?@ppsQIFZz9ADlkpM2f57b%WnHk?`s)IJ1ls>90nJ8?ucPY^=_KGY3t%5Y4#I zc%yYqNHR}TmlYpGCc#Vt7+3`c=tOI400XPQ0G()b4Pamu7@!kvuK^6K0t0lS2{wR% zRbYTlw8RE5unG*&i3ZsK23ENkpf_6Q1SfU0QFrR6!|6&r2B$0aGvIWkUIeErbr5x@ zUJ7T1)X}t4sh1&)EAMFM?$puT-KnG1yHiKwcc+d%;7%P~Ayew;7pc_IJKU*P!|BR< z4VjbI(lR(b@WSj>Q}+(%KK6{U3p&yrz`Kv;dJG_0Zv!m8{y25cl6~{>S+D!bkou1 z-&&TKg_POprlZZ%iKN)+rlZZ%3EJ#*)6wSX)J``YZJy3tyhVuVX!CTU(@jU}m*p%g zehN;A0BF)TdHU$jWe^25(CcfVqSS@9o@bwH*pega=aJ4ip3qh@mGZFQ0X|Y5UU(qs zl!p%Bdh-UMZZGl%A(e?Yh%0wUmfKb7 zUgT|Qx)*s{mhMH~mZy7>w}x~t^46H{McyF7T)ZXrTCXKnHifoc25EMWmmRfpSZM2f z$P9H|3ZCXeV%SdbGavH8c7m7rkQTNRe9VWeu$|yxJ|uJ4>Yu2r;Qt)i)E@2i+sEnB~={m8AMyKcdpqrH1gXKv_$S}(lTgzn(tr+N8V zeL360TfcexqVx6|`>hvmv(4LIId3_cA>r9RybYMQKXcxO?6-cr%{6a1`^FQPy3~G~ zg||WTmUC6}cAWh-8*lT?TQ2aLx120Xx;ax{4XyhZy0(R_w?hvY9+Fu+9_IBRs>yD0 z7(J>j`j{*xPZ1vpW3rVj79StOD48kZ$)p&*$x_+m(XYZ|;yzH#@_v}4@2h~e=R{MJPZgaa4@KbKL)w6f0+nv+1Hvpne z{Oq2+|L%UD)w6d4+`Z2VN&^X_fkZHx6oeiq!{IwLhbAwOHQ(gt11h;Gn-8eZrT`yM zbxpZ^KrJ-|`G5*(%I8B)=z-R-^>X3}3AGLfl2B`e4G_@2In<_P zeafuw_|w;(3edC)Lt8P}-mK?DWu5e9XnLEiC;}1!h@`tQk={Nq+{ZjrA znk%!7KSXKDAJTJW!1zNKP5DENuFN(5khLj)$kUZU@lW|dsIG)iy*a0se-4Cw*w+|~ zCQ4(W&DVO8Z5Md3vI+5DA=#jIi1kT?fn7^BM}=imVK;v&?HKb1Sm@yk>4Y=P=`^X2^8(gfe|PC=ZZnl+!?&J_D}@ z$TYOUfiexvaG*>>OB^uM6EkGG?1VCnRy|Orp-v8zX{eS1Wg2ScK$(WhIZ&pderCwD zsb%P)8Jl<231zw(ln1Ek8oVB$dC$V@0cslh>p+=?E;~@Bq1R@}bgFq@lA)&SPbkw+ zdI!oh6ySj}4P|(sOhYjqDAQ1q2g)=Q<^eN(Wrj>IKA}us1L;D^m)6m2-WSY$zO&fyjy55<_N?%kpb89bFx{{I6SOvow?8euh@)gzH_+s#}!-@uPe8HRTD~i1F#lnQ`EBd_nt}{$grS}_^9{V3$ zudI>vN^U+Hea)l#nujAl^)(Mie(Gx;j{MZuJRJF{uX#A~Q(yDQ$PazZGdst68QMTN zafF1ZuL&XQYeIJCCWNT32_fohh7j~Mn@|*fBm{lU5Q4sD2ti*ngrKh(LeSR? zA?Ry{5cD;hP#OG42>O~K1bxjAg1%-5L0>b3psyK1(ANwh=xa8iD)^BQ^ff~W`kEmG zea#SpzGetPUo(WDuNgwn*K9)d@FOAUYlaZ?HA4vcnjr*z%@BgVW(YxFGlZb8*@PCu zkA$GF8A8z43?b-ih7j~MLkRksAq0KR5Q4rYgj8emh`#1A`kKe+YaXMod5pg1G5VUv z=xd&IeeIpKCuu7Ia6uK1%26vNB`jNEp~0Oepkq>B_rk5 zp+p?YM_J-<_n)a6E=yn=2n+p9R?3H4K{ue+W8&k4;&#vt=-o{|mmf9~Za^kA`3&Ia`_of_|Uq1YxYqkb_!I&=+OC0TfDM0OPSps`aQ}JSm z%ZpnjtH32nJ{6ApC9A+@Yo6N^e69kYs2W#DFuDqiwhncBg40#tv^C%D307B;)lddj z!~L;3%uT^&b-3HpW_5(y(`Gf|_Ow|Y>Grf)9p(14Ssk5$)q?(5J;_bMW_66)(`NN# zx2Mf&q1)4D^%S?K&FZOcPn*@#GO!x$kJYhm3O1{!yFG1I$GJUiR^3f%waw~ycSxJn zGu)mwt7m3lwWvQ> zoPbs}1l9C>=pvNM&i=a5M+%{fgke-tQNFGGQDdiq1*P_G3=M5u6N`HjZx4CB{Mgz* z9mDVG1I4c|OU%VRL^ZL3^RfTg^0a&X07APEB43QFK(kb6cExi*t_zWdygs=(%afv% zh~zkQenUFF?V~Ula3GL1u8v1_(&qq zwc2m|U7oeHJ1CHZFs`(0lZ1>u#_^^(7V9{4%dNnOTGZ$|T-QV=ks=qlC(HM){XJ70 za`5TB#ZM+Gx~}s($)>Z@J7_CMw-_xSWc#=|7A03xgRz#owQ}6{Ozrz3$a@s)dxeaK z+rEOl@e641&P zN-W;uxs>Gvc4((&?98kSb2m;k}bnDd$}2}2G3u3P+>m|CH}i zzI90YD?6%%E)ja5F3W??`dIl9(?HQYA464zLl0D1iKolo9&%*uAEb0%E`FNZ3d<5f zuhT6a%+&wbKiC9Kk_*}3$`2t*AzBaAIAu&n}Fd+gY#R)ku=?^*b zG&oq60K24hKKen+kL(VBj+wHDYu`uHj#AuY7xy5UBIE`;fkn`5AX!_zp*weAn_%sq zXa;Fa9ou($*Z!H#Wa&ifr^(7`$@ma#y#{Di313eFy&PS}Z|u=Xr3fJrA{^Sh+-tpw z)*V2Ngsp?!JzlI7b|2$nI&@_$&7u?_r`w7UDPGjRiwmA02a()d z%a69vebk%S+gUfsY6lZuPzfT}5!8KTYGW)Ox~o}wZ$akrrwHJ_HnU#Zv8`)T7dF}N zEJ9~YyqY*Vo=r}>#)cyH6w`bWDF$Oq{H({=`3{iTWTjmcm@p$g8kv#z4Und3?b~ko ztF5jHhM>D2BTFb5>i}{RV7GHxJG_b#hszHPIp~P^!{~+0xmH(cZsM?EC@mrF-K8-w z6X>eU1*0gJu+s;vW9-8|hy~OVGP3s1?Cb2O0d)4#fU8?o22iSD6tSO0>_^d-h3*<_ z1S5-f8SNL__tE~W24z`=7E#D@K-pH}S&qdVek!!FyM3DDi-FsLg zi08LtB-(}bqJAGW9kFBjfOT-{Gk`%uL5;e zz{@HNyv@dL7e$U%5aYYO|D4(fYu{1CigfEQgIk|q(N(7$^p0PjyshWIbA6IOh$8f_ z|MvCSzAuWlQAQC>B?BxMpyd=nI8#S0MVAXE;<5If0cNIsR{$@l42AcM!)2+68HPtG zLKfnE5n>jA5@m1%fy&x9rp{vGhKKaIW;IZ*yV8){hU}auUYy zXV%NOjfD{m$D$5TeZ6HL8+zaHqa}P7#!arHIH3xovs_3G5UEw3=DzGr&xK7JHwUP7&-+}_XbDsJCpbxj&_VDbbdNGGhM>P{A#NR1Z+WErmK&W*tpH9cqkKqGIEy z*a{5KflvpH9NKpTwSNB#%U7hNYmV`EE?-IBJ)3xs$``Hof4e?S(a1qU=CB>lbj|d1 zwLqahN`?3*&{2)brgP8psI4JF)Tpka!(p&TN2f+zImFtD4ll}dvSz4E7Afw#mRnsF zX=<*~rvv(enxJ<2{a*B4?Zr^taInm!OeZFFmEyEbz*1U&k{-8d3Yo${$TtXp-W0So zYf=UQFb7q3I4V3pCA3yi)@Ia%e>mpSlNrSz*X^{bqBqAy2cqAtflH|&)A zKU{fNnes*^3PaF>gV1uR3CB?{5o*B^Z}TWLInFi;P(@L`+uIF6xxRfzj8&Ab{|;vT zG^W?j{u8MmiZ0cE|EubUEDT?QoTFRe6NUT(51*rEm=RhiC1%W~9r{`m$)bdjMj)3&u zO=qxMI_rObqdx6BL4Eo^()DSXU;iWK_x=;iZx_P3^?7ricz)su&LlW_WCxlXt0+EF zd?4}D(8isijgN;m9u93hiWvwO(kij^6u_(`h#3mj+(UO>f+N%Lk0*ZVh}7rThc*X7 z8|$FSVJ8%;Tvli!=Ff-$MMjPljc{hwp6c>rCOeDn04kWO*(gr%cxDXE) ziR?@y#1aoAVE54mI=x7Uhl@l`CKB0QtiHx!SUPM29Va89&2?pPqUu@xtV-)i`bl#L zB!eL|va;?YfzJ2mps7__zmhQns&oXcqb$_19rI1hb43zhT$KJ;h32)8P3?9zwRN#I zkPo04Yej?Or5IfQs^7gdR)~?BlNq$s2!gHSo4VLiEKq9!?i3R( zega_@AZ`&{bFFTKLOZF;#!9OnCCWG$DvOf%XbC2UC0x?p*zK!{wIR_`FonQ12#hd+ zgr6fKJc1Ijs0*7dKV^nvd>uxl(%o-$;#(|MyPPOrw-HRD`7cLtH-UOIaV)W?`&hX9 ztuTlO#=Zt#ur`bW+x^z=W9OrELbsJbUt(rL?GGYy`J)}%TJsP!B5yB2$4Ab<#DZkJ z9Nu%0uYmO$7L6@<&V>(hgC%CL7+`V0L$d@2#0GgqxsYAXf!os9?YNY>8Va42#Y7fb z&9V4Yc!bt{8O(rK1!}YrZz>U@+2TTf9LZE99=Bdajw%zo_I`+KYB%*|ynI{7p;l2m zBzKqWBo7NPWrKN~-|F=4-HC|H)+56V2I*viJ;546RkCsrve{y_*)=73#lP;oHBbCYyT~$FN0jH^K$Loo26t!T@0?kol@7?D{AU-_YC&@RtLq=!C*GP~JM z%cuq5BHGb&OFhb{p!^x8S6LR?T#F(tf^2~-Dzi|MEB0@gfN${j%*Rzg+hBcaaVXz&T;BiiyqH&eN2js^IOyz)t93k}V^pJU3O{B7&QAF{}e ztrUM8o-i10UTz74m1V*oIa|>~F5ff$*dAG5+tTXG@aL*8Y`w=PyxaO>`+ryE@gCO~ z+b{Whv`>AR_Uo#z%w@DjgbtTO>8gCTDD%i)oB{S4FIsd5T zG^G~mVHnD4uwy^w69oy(D?;mD00nfw8g@@!iI3;X#IFv&fNm-~9Z)U(=!KjXvnO&c zgCv58jOi*`Iy^`T&8V4kS8Bcyq!H`F0%jW&-8fW`(ovWwbG$|0jKUX26U9);quocd zVK@QJq;V7#u~9-TLeT^&!DRCkP;Cr|Zy5Fg2ok_t6x|lDJl)55=<)s3lWSzA6tJd3 z5l7DaA)`f`?PQTNL8yvBSXUsU2oTuHiBV|g+mMdGVTQ3rgT+$3iOBlyT-e9K+(xsD z&Mb3qTK-16d$JR6cMgM)h}hW=Lp+7SBTxww;p&dvNI&@9ThIYeDFZ;Jt{c-c8 z7WGHdg*d2Jrq^E$$=7hg;?!RRr5+BgyB=9V7OGf(yyOti6^UP=_Kd;93keE(sW(nU zSZ|m+nR+7yRH9RFY#Y&J9JY>jg+-wh(m03}hS-JH-Y)D$9m(d2K&dn~2Sc)P6lVmO zq+`~VY%GqdZ-vwzllD`=M63!_AzB_?HZhKpqp(EaA|`=&FOc6&OnlRbNvt$tXi1Hu zkjG}F=x$3D5g3k^(=;q0&6OyYN8Z37(FE0Sh6@P?E_il zm*}M2rD5$4&3qkg=|5QbD0*Xwgf(6^M(W`h!Js-Jf0!t-`KKC^)P-55>H8MPTVS-r z(a&VOSL93aYB`r|%1pL;zxJW#XonVLTjb0*j8Qun>S&ZP&t%7J2iW)3z4P|y@7*33 znH4W-j~AKe^!A8Ju<9YMbuctT*lMZlV6QjpU=<0r-nhLEra}SPq77Fe{-RoKa^D(TXWU*Z}Q%2PLK8S^{h45?F5v;$>4ndH1E@S^;b33RrIn;$>5C zwY?M%t_84WX8|lF3E5z!FG?=3nAMjD*ZNm8*S~u6AYL{PSc2$F!L|I=%;m4%6vWG> zfW@r76wK;ZGgrUrxcbGV5G)`BlXdy1+2#uI!l_{#@~Epohrq%LKBOyBB?rRX>3xv% z5F*$`{)H@iNqaTx=xEZ?{~V!SW%}R0YyUF?myzh-7HD z=QX9a~ZSDlz8vgc(t5Mlw45EK%5JR?EBcF zN71A22hEQBt0_^oe%_B+P*)@lirE~l)G2|EfU&27GO+l~#GcT`U7?M~ScA1p#OMzk zNDrZ6Xnh0yfp=11NEZ`g-Z6nHs7yR@_<4vynWiCBAc6Uh=noZ=3skZ$cbm2E0*J|I z7d3qh_Au&%%7D}`zTyO6Wj>>D`8x_B%>^I)aTHFroo7AWlXx5F39Zg~99Z(%`SYdo zbFm36E7f&4KBFZY0T31eU@H;H=5w8i;T5z2t+Ad&!TBvtaT4IFqekSV*ruhoKWh(1 zWaJpCMQG-0$f}>(2z2hJSPalAQ1&b)osZ#tN~yrw0>^}u){tzTYGHbcg~XLsXD)|6 zRI$pk&23bJ++n9lSX!+jMerM;ErzLRBuIO6VOSLo-S17w_msY9*LP-pQP_9%#XxA? zMx$ehzW5pQT$y+hwT(+_v0?lI>RR&{#IzUf1nQB=1$#5Hgk5bc*rINz%0M6thsFWz zD~2jVm6xKvpG74^lXFK>^FWnNz#BiD9ynv&Z)f9?7H?0#E!95HLS&@D>PHpRXbg!o z=Hom99@vhOjT6$f5nj0>1QE_?BL&v8@C!p9P0pQQ6UX2?k4BtA+>Ed`aoP;@B`yr4 z5tmpQiKDH~gM4VrXNlw+>MRthBOL#Xrb4S&icF-XS}!t=0V~-&iPisl=R6-csj(hM z11PknVxFI%zVb2Ye~kUwpWDir@bPqmu=QGZc|_kjHir*eYhw?14|hRWjyr_jEgkf zJwc9xU_KBDb?`zMyEkld@1M@QVi5YnX}Cw11xx)qXrBMCKS&oeUF)6n2fMRL*K&F? zn|R;OW|{+EQ8ci}NSKVB4IOQs-zF}jtwY?Ok+_gb<6L58B#sU|FUuw_W3@v(DnOLMn~8#L7q*Q*cHi zHwD)`P%I&OQxM5zQ*fGxn}TZ|m}Uq8Em(3Pt;?q1v>7)A*E~?{AbRs4&CaIaG$c0# z*E~?nAbL}fc4$*@T9=!GnFqEx^FTBKod<@H3z@iZEu<3X=v^idIuC4v`2$yBA{I;- zxljf32Qv>8^9RwxGmqaH);}?=VZGbypS*s6%YY<{xr}Sv=DL}!$2#j~VJt`@B!pyY z*^FA7z1&F^87kWl>apBQg9eqpg2sl5H7Bm1$s!n>TtvePn5dd^ZRzGY79t}JE`?Iz zLW$tPSO_arU$dUUh1g!JYS!cM3s8@(E4GP4kDcSSiJM{5CT?^qB$q~97)T>7 zu_Bp>Lyw)~vxyt2XA?KFus3lbl}21*Wh9Pqdk(Fnq*#okw22$}*_*hKN+T|@G7?AW z&dIWg8>wm&H?p=jaUqpPTw-M;4rx9o+a_+Luua^^=HA4GR2p%Km615c?KvE`M{(R9 zWvJT|1j+}lu%Nr@+(E`|*D7bSx!g=0=j5QR)JQMG+ySe*3CM$6t$QIfZF&WAoD3ocma#5E(_SX#-pjPjig`7jL<+JE>rCGfbW=j~+Uw>`SaQ`*K4QYf%Z3|3aMI!56d!@;^CT;`CfgpwbPV^C zymrl_Z;Q>qYTiGWiOMC2K1nS2%w@w3zT(%4nXK4jgEU0X)@1NOCPeDsPPoeIj~-ab zeV9k05yM~ngiO?PiaA|pM&OBjDTJ;|@3m*dcr^LqGso+li(g}g>sWv&G*^!C zF_er2i1@gpNbW-?P0}hpVjWCXLl)NUj$aRChtbhwS5q0#hH-BH4Wr*GV2h1nRFH!w zF$*8{py@&p_kBVgH;cv@G~cq|dXs6tOA)6HZMY3$x6Rd#tw+I2S@)m4SRiY|Xb|tl zv2+B3Z0>7YmCY zPqtEZFNLGdS^u6u-ryTV{4&h1x$0Ae!2|p9!Cd(Bo&_3r@lz-DE`J&p&xJpYA{My( zInva?KMH>obLoV`zX28QErpBs;(rkDFcO`etot@c>OitC$s~AfV(^;%Z_Azx77DDR z$;N9v*5lnr(F8V3k?Rxpb_Ni#;P7+BM?sR$lvV)-MVD^;2DgFe8zC*eNztRZB=&?H zigyS_gl+8%7D*3fyplRBUx6xF#B-t0E&T?_a;=K;zQ{V7B3jTN(Fzb{1iWXlkybQC zizUsdWZsqK!n7gv+L!|ay%W9#t+2#7(BA3UIq_FF9{y$?TM zywf^r?XriD=I?~%+e_@NlCfi5*hoKyrn)I#n(C{a5H*}o*&~P-B#t>F$ionTD}C0^ zYYx3_*v|)%6l?%Y&&P@@`QKEScQOQm}L^<3K1yOL^kgG(8D5rTTq5&lubcjlJ`XP!+ z;;p#+c1c5?63tbjMp#Li4pE{*9ioz*eu$!yR>C@ipGRm2D$zV8IyA*;t`g06h)Q<) zA&N>`i5|Eb95)PAqH??e?)(%{80<+!g&d-ioqmX-lB%g^f#U|2ZTRr>)+6Zi6pA(9 zL2?bq2d)w}G+9s9!G8NF2uM>xlm-y32C?E}s`p4K4s{8SU_Zj6^CI%Y=qy2+RBvMhQZomOMM%J2b98G&{+dt4Q;2n zA@(_Vg7DV~cf@G?j`$k@$j0vo8w_j`z=#nLYBlv1Wpe=Z(Nt7t<4YBXilcxx_2<7hI`@z~KcqX1GF^P4*cr}Sv5C7T@h9I@b zPX*rB;XQS;!s53ODx9nlO%&K6%9K&@YO+|^l~jmCZ+ygPQbRes<3%v>R_9DMBNha= zwki()+B#bN7P$BwxR74o_;qTeq)9SzX#!OuL%9%hV;A9d4&lz43p_GBGhPW6gAkY3 zOf4XoIW`GTnU0%hed#jUdnitjuuGut%AanT5PivXD>oDBQ?5lL=?da$*R#P zqt=@aC2ED0hSC=4P??GG3^vu%0wGrEB1ZKz;*cvM&tz+h^s&su$_~F!%nO)eH2INf z@dH#)i@-_&g=pn8yyQg$5l&A!x=nAudVB974SQ3mo@hih@9CVaf)^m}2SS=Mo1?zz4F3 z7RHv1Axp9v2h}2nY83*r!cl_Vx#cKFwcU7(5xo6(H1g(DQJK(W-JSc8B? z87NX1I(e=`o*6BE`1!<}Xm3TS)>eZ`EpsZBM-)r#YNbd-wThj2pEg&6kX0qfda3{! zIqoo4#~fr}Y@3_0S_G;Aa|OsI0%O@kvRFsrX_Vp_D2WKRtCh)7R7F4uf!&m9KuPYa zB7;@T-7z#;iud%%2OHWtk?8G@Sg6L})JH-cQH;@Rcl;cIQ|lA_{Gm*hDH6ISCCYJK ziuDuRYTGplN8|?21&UU85<^2cF|4b~kJ~7(+|Kopwfk5#$}5H>wjPLi4(b@0*3h*{ z#uW@u>)=Xqfdl935-(rK)w52{QnP|Q80he!~7Wh``hb4Zp>0}G- z;^ujbr69SyeMe(j@f!Qy-u;Ek5a=tWzr6oIhW=6s1243kIPJXd!CnDi6Ban(xg}OX z*A}dmy4qVQ9FmDbW&)pgw`Bs8+Ou!JW`b}1k~%Um{|zZtMz!-X5~)aE1iop9rB~FhAs4z@Y3;D80Yq{)FUrF!v`o zUw-%d6J%@f_a{ul_`m&$zu*2u2uko^>`#QCi3LFG9q&)DM=@Rrv<)b^|4{oAEWAP4 zpCF+@*`FYx!PuYRIrYKXpQuaUpLq0L?@xr@-Tnkb*NN>TtCO;=<9_4+n@NKzds?$)FAFpP$T`D_9s*${RiHkU{Ma% z{)DKegS9_ltEcaNe}W3?VC_$k)}ZW9kkH`oPmt>1?oW{7;O$SaQU_^&f{YE${sbuv z&i;f=>3`h*MDO*=wDtX-zU%w%Vtw^{Tm|m4zWO1oiDGGSP}W!PdhI=5UoAxvl8LnS z)lVOKck8QS$;$O=G}u=3q-L>it%Au2YzA9lB_hTXv^s_5D|XLX@w5O{*NpXTo+ziG z!d%2}#&A~(3k|HH@YO<)Yfdvk;W2_T&}6{4wZHfnurk@e<>?C0D1x)zoWG`(0n!#* zLE6g3X*XMo_gvtq;o6kgHE??fhAauWnI2}cjyH`z7a}+}SnFK=1-Ov{-aKiJMEOy! z0PI~KhZham)o2zcF2raSrmx)Zg0Si$0S-t(AofoVYi|>0>-G}8)~J31sW89jHq~t1SOFzwv9v~ z48V9yz7(hLB^g{;!|X^F@Fgzf2uTD>Fv1&xW|Nqu#C1He3l=-si0=GnCLbqxw2`PW z!G#4t;%G5H-xT)o`l?_6O$*-(#RlyUs6@%K9|Ag~ zfVn8+iF;F6B*B*9Hhd`X;Y`Hlc)&&VY%;|h%Ko;CdAVT@Ru+b01&H&8PAvpj!iagr z;pdS`q=YvUu%cnhif~+63p*@Fk--cc7s*8h*n%Z}5RP;Pc~L_YJ*MFB^Q2#bcr@O< zGmO_!WIRGUH-=>?gs}lnvacD_c9#V&Z%mUGLpxsF78~mLf4B&_eaB*BQRY7X2Ya$@ zXx-SK`8DAV16u^rI#G3JBBqDX_uJYWw64zn?{2fn54VG zSTJppjZ_2?oMtR7>-C1(vv@%A2gNhdP%S=ZYD-pWjuLiG+Q zeb?JC-fl2)BY69nbjk&I%gPf8VanbWHwy0tI_}3J`gnc6y-H$ZMQv6U#j5#f}(_ix@S9twI~N zo28`unw^SEP|NUA+7*PPObrPBf#h_r1VmKV+M+rbD?u4EJqQ^NN6ZzCX&@wudQ0jW zyu+Y@bn&*Px2TS*sIFC6O2J%8VOJU}fy9AeM#0r3+kQ;p%ul@)QLus-$~3ORTSRp* zqo}sY*C}~OB%YR-tHxTqqY2j7_{4>jamtt`NH!d^oG^m*wLEHz&837+$gjkNGl#)1ax9T%+DdFX*VyQ>aSX!}QFaRMA zF=kvh#ll@6_YlJYsPCxQs0q|7=Vd9*NdTllHrS_FIDVNKGdZV`UN{5s3MJn7^fB1E zaaiIQB}ZDNHO4oa5pAIk>9S3PN@0O(l2S6XloLBY_mHl%7p6*vgD(%`HX$)K6Y2;^ zk_45Sqdb&>f3dg}`V|N!wtsH==pc(VjV3LeDk+@OBIpBUho3hz(Xx3~I4I_EGzvs{ zL17Yu%nGCurG$_!Rf(X5y;TULLQ{AuCW~$L3I?HwScaT5yBbR+{GgfGc@eTKd|C!Z zdl$Yk-kd5ND)Z!^!my3Of!YZVUzC7JWw?szIt+6@9?QURo9aESX~iPijvvHgP&>d= zWva{@p|BZ7D`?vflYAu2{FI5^>;acGoig60j8i|kM~1ji$LJ$8sN06|z-TG&u|3TGNTHpRC) zQmJF9Ofsh|ab#Uj$M>L^x^Sg%FoExa82!8V=}i{PN)!)@rukgZFh}&IXkcg`f7n$t zeU5F~77;uFilQ{}(+>SJzM;sn%|L*s=W*Xcf>hS5|es`6W^FKxk=ShUv6NA@qfjUcDDC_SaGmru!XP>vvo{T6ByHD z9$@v`eK=$5U`Mg#2;)1ak#R2tx*P~Na-?s39&ct(!Er8h7D?YZc#O%7iGRG#!j2*b zkNsW#m=ZzHo8oZ@Acf1kDo%bW8s0r}Si7^{*S^DV&O}h2xMXVkK3etrF5D<3>QG9rhLhrH8OH3MjT2v^yRd$MJAOA&bonZaLX46!gS( zMhd7>p0?)saKtba(vEQp1)Df}W+$$U_dcX9{r|*3Tg^ zii5E@ix8m5?f8{kMG!D!)h4<2(TrDZ(D}H|g{46OJ;iDkzvP%}B`@|cfpGByb|QH* zhzX6Awt5M(6jZo?hSzhg9{g_tJ@LSbiuEYMVBrSKD2qW0Q@1!G)_^8Ml$fNjE-1@w z+)&i0I5%n?a`gbvSPmMEATMitSPLV8WK#f3VUk!g_A!uqFj%ZhS%_2Nx?co)FgTMT z8O0Jhxlq3@T6F z#6eHarXqd>VH$gd;U~UJ5vB}b7b70O%9U)K#^ZLpNF&P8&n!N1(M48qiVuQ6zZ~G( zA_w^Fqn<^efd!2mMh_xb!6_JNr_= zEq5B71%q2QBznL;XvwLoSOs%xo+mon9LU03#H=M|id`$QYcTI_ z%jTq+D;QX}p-@IKP`@A@XfQm}nWjVW5E=>$?3E%O7n35%wjypes8B}~+RtJa!^Cgx z8y{~$qb%7hT#L0W%Pjsd;?f*}rza)tioS8NYidrv`FZ+nrF6zNTX9T%ALjD*9c$2* z#gu9;c3;fw-qi)Pv!Y=}WI3G+jN!xoo{Y?Ycqpn?$AfB&o^qXpW$g-W_F8+A{xwPe z$KlD-$q;d?dzNWoEh~O&Sps8TH8f1QEW*nu)s`y`FYG~_^U|VBM`xj02zk}ulPKmPYcXM}kzWW=c6oDN7>xU6Haik}o|H_^qZI0c^;Y zNLj8(IU32I9toQQ)f@*zf=i@qS0vui&7#XnkA$V^YKneDZU{)E99N_v8Yw$HQa*O6 zihQPa@wvfJM=dUxL}M(v##H_&NKZBb>0@)TkvjKY?qARgf;|i&3c8iWk7--MrB?AI z-f^1%atPUUxFA$v#Er{m4*fZ*!^eLSe+ayu1b~;foRrO zOR=wml(~h0c+E(Vk0SG%&=|!ZlFr%>`r^R4J9o96D6$D;V#yYEz3lq5B^!8hKu+x& zRR(f#E@d~qPeSR74inls2}M#F+6v*k73b=?TDet(a{+=>A#f>zEk;E4yWe{fdARe=Tw!7^+!_n!L7?R(DT=1A8=jBS=W zrqXl*pNv4vCNZ6W$brb_nhB=OLMnYxfV7->PQRqQ*wCv5O{hP-V-QmwLn>{3AayAq zN4S1z`ACbB8uWO>9hM3Vv9zTEA?7RxG!3)@LS$xLG7f z$qu5tUJx3-;VezV7h;Zv-!HLj5~IWi!P!RHH^kDEeIe#3`~4EjAu-kaXQSQW!Y4y4 zP45?Cj^3Y{7zyR@)09{UA>+bc0#b$nb@4Kt(6&|cg3wW{W>`Z@$WbwpLIMb6h5 z{h!{V|JNJ+Ulnes=#b3IL4}*q5S$A||8E98@xTVC>i@M6_)CrcUyCSZ7-Sft#Axvt zjf5g?Cp9W=bdiZeBO*3&z(cGmaK>24l~nrqtI)7EUXGZj^1A(sm4W+ zJH`cK$Yj$jLMev(p{evrUE7CqF%j+9E#^(FW;&AEzruJ{eh4SZ+f?bpz57ATNT?XP z`kcxQXjNfnMiS(Vo?L0j*FMh`6@IN9&N-+BVyh zVk|M4sfUDvg_OOfgjobk(PZLLgIn-q>QMzDUxvgMnE3|gL}tDrbA-@V*nmM%bZUS zk=f&o7AfMWvUJLopqxHhDCH9xFx-SI(+P7JfH4v6NZs%fx-0`ps9=eug7M68AYd%^6SIok^kSO#(`Le{M&;vnhSt97gg-iGz zym>A66`>dK9^t^=ul*i7|AtIj{H}7`0W}H#e}eyUD}i}_aC#zGedYGVAx$qMy^sFE zMUMj*RXpH9jc7K9#@6o#;2}& zzx65}io{uJJIllwx1AN@thAj~;;gZqwc@O^ordyU+qppAF0`GC#ktgWE*EE`?Q9Zf zv+ZmZXPa@}6I;VfgcJ9Oi8HP_!(~Zv?jHu=ueXvV)`{VA;;lWeq1eT0h(Xe>CxhF$ z%q)Q`%5ttn$*+sCtZb{H+_gJcs#h-hu(^|Heed?cq5kTwkr4n&udVzUXpu5RcSC!K z%S4omJwjv7NQzth1f<;+$(c z7l?DA?OZI*rM7dqI2&zelQ^5ZF8lxNy$^g;*LCm9kq*)T17}DlSWVSyy>`-Sj2dek zr4f$eD2^N}JjGFyiA@t;%FQKI5Y;9Ah(z{N07c-;@o-$4OWeGB(>}lVeEXc1)_J{D zc3K(`#s=JC12@KyKaSg*KN`RoXlwy3@V>vj&lw#FN&HLFd>Zrlh&lV;+H0@9_S$Q& zz4qSn_JAB(xkkjLiMpxI!P!w3qj-Qhjl>%k+il7?Ta6cv&{Y?<>6a{`lsLVSlvU?);o|$n9dm%k7Yl{O+YY zWXyWM|Ckvcc3_0V?1WQd~*BXKSVaf4`xy+yQtry3Ss zNI5D`#PHwu|Y% zZiUumj9Fl7#wAj{S#I4ilDRQB(kM{YT@^6Pj7>Zy#J4o~WGvFiXGNxCku_1y+E}F2 z7gOBmIw4FcJSMUsma{R6G?$EqIn8~hsz^@g5lXt<)D&-vMYczg9kIyHC^8?5Togqv zjzunsBA4oeg^F!k#JG_Lwl32}I()yGpW#-^>`jw1`(J*$-1jPRDQ3TMiRt@eWQ~}e zb&Yznth-!O{~8VD^$x!54*s1N%;27)gZF;(iaPj?k6p5Z$L)^}@YWy3Ti-mYmc~M@ z=MD5~d!m>v&U2pjUzzbj?nwVXo#)^FBiR@H1Hv$BDDF*+0fcDc995<592e z@FsUoRJ#s5p2sWJa)K)n~EvV3~ zpv#RwS>Thy5*)k$dV!^F@-Fb=c|i*-bSvmGFGQI(UfQi-VI|w+wb~wkoowYkc%5va zZ_Vr6#@0*kwG7gg;UHZY9yIEWoO8?}rCww~YenEzThAuEQnODRU)goHm_771$Ju|n zaBHR6iAGUS2LD{s*2_Q@&ilS8l(i%e@$pVB`0`GrR9c->x(Y5x-T@@|F-`b~M%y>2fzORaSh zf|uC8$^ApfkC(KUkKBIQ{CMs5*_-!-=BJ+{EzJ&BU9MRKe?OMUcSBj%dLhu z8)D-8XUbl_nM+AfS*K|5eGJYkXz-uE>uMTY=8tQ#r%I!E-JE*a=G2sB_9@J%tC0g? z-(QZs{IPeMzJJ|b{xh;6a^v<(*~|Z!JEN|kgP(oJB|G>cd%29{NzB%|#7<{2YcRbe za6YZ`&zg-I^Dg4^NY&u3L~xsZ_L3*>o>YwcD(jqS&MxPvc;-iKW?&|PRZAhj>hM-_EelcyiG2gf$8?n+h6mdtLYbGMa3TQfWPVOuDXqF%d? zBukOcMrp-!WfapHK-7_-`rRn|@Jko~B9x!vnQ~QQ_FY2|1G{uthXFmjMR{*a#Nkj$ zIr)n+NrfnexY;J~E+iO^`nSsd&m|xbAQRgHSpTy3;7+C-dx{pQ*fMF4o7sq|T&M9c z=dW<=!}8&IzzbYamngPmhR$P7FQ2vKpxsSR$UD%UlUq@dJ>fr{)d>!>0T8rY;DOii zh0Jv+Kry$SREE#jhxX)&tGOMVbis-a_pNZl5}}oFk`iofm>X62T`@f@5uVeVq=dE! zXpcG2UKN%I593Wz0*rL`hdIw)9hL}B+)YvfOQ-JoFh@yvz}`^GoZ5p@6B79L@waop z1u%AIfqd!L-*H}d42KtV7=Hfu{2p#2#}XxsrnbZWms?G)vPDSh)LJ-{!E3A{*YFaN`#*q;iZbqNOtyE`(@6>kMuSma+nZPci!DH5=WA6)U#PPlZaBWsL zaQI;^F*=5++fC{bB=vYVC*MFsoijA@UFYSX>0Mx*3DUamq`}t-k{LKSCJMOcBOXj? zL?PD<hh#)Y2@i? zNIEhmd!|!%anA3;XWLL%VEb^HFIvlRJmFY;-1@sV@!fAjfrNg%ad9Fd@jv`D7}S5HbfXbXHL!kC{Nr8& zeWp)BpXmcTrjMnMZq2zi`ZQGj+t6qFHPEMO68cmP?5G+`A6*c1ZS>I^_uqnls;+@P zy5XoU8er*6dE%-b*ij9An3*(jF@LR8&RQleCNWK1%wK6nCVo%hyp{C^zGu#b>LoeqRBPAzDMAHgK;iI0HKyqwBVqcLHD56&gp^wp&E)!;ptK{Ge$|ANw5PJeGX{d>~wRQ_-ID5uXUr$6#9Vfz2hM>+i< z)UfcEo(bBv`W$I?T`etbuRoG|E>^OS z>L!X`2Z|HLZ=ekm#c!g?6UBcSQcV>92qYdK50jN1p=-20jxCG_j!mHd`p?lg`aej& zi`xn~rA2_Fw(aK&(sdj8y1-aqcyu}p2F8a513a5O1?TdLe9-h)>t74*Mz4L<=RW+( z1u*`aw=6j41rJKEWi^+5#Xk>ulVF(}f%Hj3weuq{9=$H?A9UNK84D!lUdvqw8nUpd z9wbVRJQXUqE(7A+^&`)t;JW1j;c7s*ehKBaomD+$;>zv8HPs7V@DF--j0kK0BuZ^3 zt9M3uke*ZMbZ9_3^|XUzd(hK(-q*W9^Ma1V1xW&D7wx6pIiurq1{*RU5^fCgDQUX0 z=rF#@n*Og|tm((q+6F2K)!O$?q1M*K_5B({6RYp1uU_A$nW@5@@uIWFiUB+Fotoe;m@>Ew(E}1;*GE4ie6;PSK%>|=d)E|7?$0D2t#JgvS$sA*lCD~YwnXtndw}TI*Fua8b_9QGm)XzdV{xdt)e8h?&(K) z%3bVw1hZ-i+fnUnPZ_%rv-_FrNA@$jU!?9bfvn$Nm`MR9 z7)lmq2A!z8JBChIEI83uy&(ycTG zJ(sg?7idsJ_Mm^#A7Nfo6H3iedX2rAsfqmem-W_Ur1u_)>%DiB)BhpTdmoMKz4OZH z8zQ}TX*9LvpO(|zNbh~=V!d~FsP{&Tj#0f9RxJ&Zx@;r5S^b({ z;eYhtg7jdu{kZfRbTdeoEPd4Kzv#D7dAdvKe$xjSQ7Gu{r2S=>}S?uQSl8s%;(}U?Yzn z_^Y$|TD-wIHce;RNHf)SaP2EPHVF8;Y-*iNt)lvRTe3~nv;C(g+dMh|2LvsAlQvJg z9`i_caTqT#^iLJ|5twsvn@kyF*>?SdxdS0Ny}_(ESRJ%Y2gq9jms05tZ*Vya%-bCs zd$(hwJBemn>-LH;8drDa&J)ev)$NsGbft}6L^S&3?QR(D+UUhZvm15$^e}q5jb1`D zTTZuEh0#?udMVM2|Jy_S?yk1cT?0GnxJFSl;0i7CW0|1;>~=ceTmS2!FkpKi5!_k9 zV!EKa{@R1P%y(xsQ-Rh`O+nAy35O>NScG#^C}W5od>clA-x@mOa@{A{T7vuytTFBx zI_vU$0cBc)o_Vm=-C-e@LTzE8Ab*|7dd4-mtGG#%)DCKPLoBWXVpqtq{t?W{pyoGZ z3i(7exjF%#4?8#LSzX4gqh6>j;;jX4{<~}F0y=)7qrQR?i-Y{l5q9}{p|`}Mx7woD zQ7`&01f(Xq#d7$O1t5P*Ej$o z9oM41h2FT=maihC4oz^iwE8^4Rqs(gO7umz+8g*u)pac6F}C->jjOYQEjZmCcQM`% z8xR-a{fMH+Hhf~dg)o@tN0-d8H@ek4q8WUqV(5H@UZs5$w%850BJUADJMgrLW`-oG zqrO^O=t{FMm72CZC;G8wGrZsc?g?d}pF(_q6Y+rVxZbK%vIjj`D7w1XlrcnYtOWFS z(hQ3ve;>{;@y#xE?KJVT6Mzc)E2?igpmhH<;BxeOncJ$k8e44?zfh?T2AEu{qE_l% z&tYQAO-wS=7do2N!hMQoK}v}P!EdPc?$4TP^rA1e0Wvy(JtVLo5cH`npHU4K=?cj3 zZ530OB<~gnjkfY71J5#~=wwnD9~;b-NW7>NF{P-k0j6O>Mm<(x+Zqk}j%KmqF~Mti zgAZ}ao!AN93AO)JIJUun@l_4dC&*shl=+c9t*?rV;-56zE8a?7~sFj9=yiz z5!_mV`h|8yWoD+pR1@50;vAZzDUiw4oXBRD4D$CRoE?I49WczI6)?kNJv7Yzd6!FrqVK!7vxdKw2M`zinFoPEGi7A78c+ zd)UA+-TRh7$k!nFYQy`e*YEKj{5`VeUJKs~&{54UC%aegeIv52&z;Mj&e-bpO&VOXPY ziuyVVi%4Td(^ZKCVTpj!WL7m@(+RVxX|E#8a;U4CFj`i-uJf%UJcBTrQ@afR^@L{; zZXlc_j7rxvn=q6IMYv2!7AZST&6kRWqwxP2%h)7ar#B;k%41+7pI9V^&$rRF6X;x>o0f@ehz+T95fP_P@MCO z)OFcE86l1SbIu6N07pshzK1_fj++OOV~zKypl?e< zmt!2~Tq6MI#L=&0UxDSc-Kv~a(^Q%#&7+*%2$f(E0dYR+(HggP>7$kX?@z)D~ zPM%55Wc>BQqmySs&zDzQFRx2Yo=L-%zg~EC@=W-x$#<<6UY$G>#(q6T)jM;lOtZ+u zUoSj6IV8I69{zga*~v4_CKG?Xv!}{5hfMtS!n+m{eCzp9|Iu$AGRG73;oOAo!snd@ zBV3v!zT|jweePM_S!4!xMv&W$4l_2)%T@WCEc2%DDm7vn`P_eO9jwT#FD(`|=u7&s zS77g2msv|l|Kx)CW&|~}_rnC?U?a7ieXKA0j(QYVw13c%@u3flVc+|lP;6=80Bu(4 zeG`P?3W;^Z_{vJci18IJVWihemoQ>{g~WV@@N~k6n-yC5HW02Nj2K@bv5$OUUzepC zVM)Li!V;6Mgf$Jc5uQP~ovjm^_gL+2`D!_wC-6azM=tl`xXlKev# zDtIntMC!-+?0F4dF2n!=!T>7WtFf!KCyzxDqi4ix1oxFPD{$*I;s9X-4VU9ydW%+D zwVF?Wu9u?fR0A8Hp}ND(?!LM49~$552HkH_{(9P?$FOwaef=cxL4UcPoYPvf!5N{H z-hyhJ1Ufx*Z^ z_#522Lfn^9L)RoVz=O*X6$W~@f!+=Dm6Je+Gw+=fLhlWs_W-?j66ig=&j_C__f&&F zQf$gNFR&?`;>kwr5!vVcBSUAe&pn@g-Z}1ApHwqbvcQm};NEeK_)04eoQIrw4b<&073SnFi#+^5&2b=b0V3anf(~M4_ z!^?HF)9Andkp)U5Nv~f2wSs6${Z(1U=&%emoHeD#{%q>6i7}c6qBr4aeO7Ha5c0Q1 zb7NVR4q6s4;k7ZO6M0&?qdC*1~J(;iw+K;Xe zQ8<2C`Z9`lG)9cJ(PH%FZXQLm%7!NXpSZGN$Jom1aI$ZHeX+N>Y@{vZ>Q<}9>Z znTXfF21707L&CR9zutp?VnuPgLPjdyj2?xq(a3_Q&nTG=Q!2dHjtz-*eH$UEpy+ct z<vLTi&;~XdCoOhn3kGtRnc49W0PDG5fueyyslu>^Dc5mGe zSUn>bmQwXnI$F^~r?1aFm3^vM|Nv^`yK5j$t2aoeg7D4q>U#N1x*lx z4ZMZhca!#2TC>OJ^IWcT9$h}=6`q`~{j^5%dxP{Jk@Q+e!ZEqp=tS3fmPpP~yc=X- ziwXeJ8TU98A%Q;SbeVk9X0j9@FWpXbjaN8>Hx#Qo zD;WPOgE=|PAns{Y*70O%@e1oqx3^bY;H>}$ZqH4OP8OXPqtoUUZl(mep*cA*7724@ z9Z!~4uQ1{ovLr0<4uAu<=O&2*^~!j3y1l|*P{INyr&+`HG%D+OvUGTb6&Cmm3%nEH z!0ovS$-#2?Vsut|g}O3ua`H-%Fjv;`cyxM&@8DTPht9OX^8g2K&rMiP5JnfH)8iHX zvwV>ZS;%Qt+dYlSI-V?fkNs2we3k{yic0Uy_S}S2W1)UAI=x<@stlZ*dcqXUm32H> z7BP;I1z?`Ez!w7?xIH&%c#5ybqtoXV?v?Z~n3L1k1$r8lbv#)XdxhV$z-L?FO8^es zo|}-km=MOJW0z1~p(G{Kz$Y_mjF4CE@u)2E3V%vgke^d*$rLtZiikODKkB;~`w*gB z*5i@+NMU2vOL&F<%@pXGEg7`goFDWCH=BZp$#tfDM`BJ~)G(fe4>FvU;?ns{H~iM{ zTgz`fzk0x}fnV7N8u>L70>3SU+xTtex0~M%epm9_$!`z8d47BOUBqu6zl+%uTnh$# zF425q=2ZrJyN8HiR=a186`V|WD?AA{1oKP}E6PddOfN)QNt3}0LTUVv*yt7cCMR;u zIp6ymC=_mGI#cOpFv53amX@0FQ=#$}G|SfPIc9AdS*o{wI24tkZd%sJ(4$Y1hb`*a z)3RsgcVyB>Wsh~87!gCer42V{rOPdPaLZ9Ee(~FUQB>^p?JF{gi+o zhm$Y;*K)iJR2CmPs zuph?4X)FDI<@h+9meTK*mNo2=j=L~2r4hf0*pu=1Ln@|VpcaoL8>+5s7vb%~% zHOenu|8n4-@6lP~-eQIK*b~w@{nO5gft_8lG=$ffy zBpZbRc#zpEe8n*B-P0-FKvC7-V!)$dYG>aTZX{Z@w*q9kX@cOR3*TUhuNDi*ZKK6h z&_?}gBI@iB^{uJDmEwZlP6Mh;4Jf2~N7Wl#Emx0mBY z`1*Y5@lpeLwq(zk)nul0-{|}Ye3h>Ub{e>8 z;HOKsjHZ*80k<^e8@N&%Y)w1sN?OHB&Z(D>Bh+7?eU3d2C|CMhrG;{nFzGJkGp0Pp zPJG5eskb~2)&Qf4@^uFPgu#Dl={IdU_?hQ^RWmp?gI_avHkbanJkP0YjVaq~%BD(> zlQ!=Dgb(Mo-<8{QCty-^MS3IRpvK#l=N$fH_@40ob zD1F|0>;UdE&c1;&t*iD74OduutG@TK z-+6LlZu^tgP(14YD*qR55)gHT&A_mW)Zq0DV-G2|u(q8(%|F}!!!`Wl{`DW|xBs8k z^3NH`o%Pesz;^c?cv|oH^nnGyS^Wz%49VX1#%a^sx!eJ;;NY5*p;t#}Kh@)cvT2Lr zwbWUsI@u89nFm~&Y`s)kOji40eYt1)|55ci&lZyzTY2tOSTzNy`&sJ7<85^f?Z_^@w(uY|NLiXK|2@k8P~hxI9cobQbn?Y51xLmpq6()k)AvJbHvaedti4L zpe_$wR`?jh_h3{2=Tm;E{u%#ZF`eoE!3DsBw!7wG!C(F7W%%zue)LbQoJeQrJS6TO zuHR=Y`g23N`orGfzN7!s>{p1Ix;Z0;|I4^ac@I7Ud}bo|=vx<*{O7=*(ew`5;N2l4 z>x5Ohq5uN*IvG||5O3LLe89&%Mgq~b_&m76jAzFk|CBd)zGNk{i$Em)adW3@Oe^v{= zM!%7Wg#Te_jZJ<9PcUeJg#vd}zHr5%X4?&!)BFVMGB3ddm{os7XjgcHiN@>A>~AxH zI_8cb>1D1zg0YNW*{7IRn|=28*|9d8+cIT+iofNRCchMoWSBoGlN0%S6FwXAny;j~ z857c{pu_U%ri8r`z}AqaL|P?M{z{`+Q38!srkhXkx4hbvFvrDJ2f3xQ)RC*M*p!*i zlx|N!gi^?(^Xv3rBSlQJR>!KOJ*n0 zRIeXUe1spLd8bTn>S(1_={apinQRYQgfK9&&te`Ry#rvw;^Pg**A?)K0BBrxQR6@~ zuW>S;F&NUYU6rVVw`2&%N!5Y$+JGwtiE`Nwk?c?y&ZFE0eNrYuvYT*( z@*k9iW7>e!CrB!xj3mhEN(n7?bOll$NN&xn1)T`bq{Y)3NJ!KAlT#+zeDUpj20%7$ z!&|J^^9CG|AbCEM1pNr-PSq(@!oHma&dCVpl_W(tf0b`=-lyCgYy+}B!C47$oNKrV zPmcbeU4scs&P)b#?GZ$nrz6ZCR>m#X8GA#fNuZ#DBCV%0t0uFsu7j>y5$ktk@)jbMS)?Oars;${f>ST)W^SOvUSk7v6vviPU?z+RI(s6C|Y zK^oK+G-=*!rC4VysE&~giPxc(6k>kvNAgPn_8&J@TkvB)i^V0Sqm6)rW%Ee5%6 zkn5QQxg`dsXaI4!s2o(ID&kV{OBT%Sd*7xpo- zB5DW9#9BJkpx8U#CNjlsR3}eN#Xb@K;nf4*mT;UblM zBwxT!5@&SKaiu3=(;7)DTBB^V#$>yQ$HQhwhS7}LSThtwGis-9h6Ih}rHr#Xj{ZIp z3>#&#yZs@#!R`j-Zxfr{?K}OY4(#)p~wI=F5r>wY05@w(8lp`JBHYqaV7_Bt%-8)VoO7O5N1# zoq!%s;R{TX+`xwos|@>l6)2%XB#j4vcDd3;M4+=9jg6uyv^M8eza)a~&F*FCl5~cV zfeB2(&nglxW9I}VIHOp0J9bWFpGV}R{SpajQ`9-j?#uq{c>>O`NbjGt61tX$Luo<; z>Qvwwy9f)n`1(T+O^SB>$Oh^Srh=xq06|xfsTnVZiXeHT*?39FqD%xY^(rEdI%-x= zz3iWMRoO_4B(woFV-8{sZHx9VqOnr;wI)^x9jDN#;l(sT>zA7Ben*XRk&QJ#m9OI> z=LoaZS{Q?$1g%h9_6Vtqf`+#`+buf_?C=CKz4PQ9VfQ3t+ zXK1L90X=Q7FJ_LcqYT+Ls^?Jt)Rch7hZ9=z-Hhj9lH#th)M| zb$U$I#OTIpXO@(yQOYrwD~lyycQY%gzUJylNocg$2}rnf3KA|cB-~{2uNPT3xoSwb zBqCw6V(syvr8MhH%DdTWzFUpshx3dfV2fIBoqhOeR7j;PF%4azctq47Jp-DyD${1O zaN?&;p-|u3YIH%`n}XSz+J(z`$e{7js#sW#ljK2@Y_srnNR68Gbb4J+mVS9)4RuB~X>9|s>=mtA#hcit+l@m8;y{Y3)V%09zrdoT} zI3-T8n>k|xiU<@VEn6})B)hS)fFW`X-)u(hASN$LG(jY87ZTeC$(vB5hy_TSXe4Vz zsxoN0ndc>GKcRX!v9I0@8i+DEwK%4!F^ZbuZK>H7wB#5nDYNaXn^a{3=%x{El#y?t zWSX1ZFXCcql4;6}>G=>9%81C_hJc!VXkZsuE6!NCSzKu>Z^-o8ShHY*fZLUKvwi$l z>&*RR(WJ-46B{xsmDjQ!bTO0QR#s4kvTdN@f-d7MAiorG&1XUtcq7d}!U{E{H>zUt*3ox$P_>qHS+wLlP(#DSjE&GzeZY>ST1=uLBx`+3$S>L0I&m1_ zv`X8c=1NazNb8e|0B*L$sLTx+3LLaQPz&*Dfxb~WF(*K-hi&;f%5TyqWq|q!pAp&E z0uvhcr38Qq1v)gHb^Z6gA7+X1^%pP^-jv*3gnwVez` zrjHgzEG;x%Fp3e&C6IqNpr>_fzqdO9?eYoEFurjb^4nU15)A!%r9r%WqG~>*2|AQ+ z2*~0Mw3E)O=Gr;sttH$*Sy|T_AWbIwjH9b(>PeH`vL23Unol{xNz)bQn8T6&d1#Kx zY1`5v66sUBQCqE*gI%_8G6P(~Fy0oUJAsL6t%bbW-fsYU!+c0h_chQT-vCaKw72k_ zp`}g0-Y3`;p~jc=DQOJZ_=MLI8lqgKCSKcYjW>`D-YJvJP8q$561zdNP*LdtexIV5 zXWJ4wDt?Sk3zE&*UH)mXR|sN_(54f7f^`yXWuDPE=@Ctc>w#{)EVm`(`iScxuFn}_ zfw?b6F~dpLdZ6;;>qQ?BSg`()pyL_>0sE+TEkS1p=N%1`mT|V1dV0~lWw#5h zd|F9038HS!VGSt&UHk}z`+k#3tbdV zMS{E{!Ka2c8npv}&|^EX0MTATJx$O=3X*+riyDR0SB&p!o273)CRIWpUr&+x&_ro$ z;4(4SfO0(un)(_*9@JG6sLQh4M;2{w*Jt;F;!7k%hSv>zgRT$+Po;ooBX~Z{Cjf;4 zEjA$;wYQq736K)2O<=u+476Tw0DX)fVZ6?Kfo&75*-j*_QBDeSMT#uIG)R-28UyjE zNf77*VM=3~OcNefoIE}Df_zhi^G221Y~X>~BMOB#U2HJRPK_rO++<~w#R|A}@L?k@ z*heCmKfw=Jm{6YiV6)MQX}TcNmSKKuTg0y*s%ff$1O;hY15pjOF=`eVZ6raQq}hcu zT4P!vc(kI9!L6bs%Mjl{qc{T?t*;h=wQ6LPt)vT5^Ko7Wq>y9?Edlj9V02Sc3IH95 z7@2*#K<7tfv3TkW#5y3yK9!TMM&2^B%tsXw(#VHJV8-b(Knj-*OL*PWs2RH%>^m5m zTEk}dMr1Fj9vP7B;ub=ES@p>j-;K_>*#v2$uqa|$S9V|luM^s;GEGgBI5-Ag*nl48`y^lQtYCiU3*)kd`901*k1Y#Ki!UNP-f1 zD4|bCAhExgoLo;4Zg1r2+@%nvGiaF0EocBTdmDM$xtKo4(?_a^K5C&`GvN~FrV}Z2Xxgb3^doF0Wfij8!vUZ!e8dydNbLZRWsI+)j31u zDg%G^QQsi}jgBt+&&%F$1O*@zyjGdPgvfypV~aI*SbK8AHgmJ8mkdT)mhDaDBeQU6 zy;|vMU`hylrq(NxG=0MXrLMEW3NbT~Xj(ClihgHO73Sbj;#W0}xFX`vwYkm-E3Z z)}}1QsvD#wWnxGhYnnkC6AT!W9dwn6achmv5r2(EG|$o(aa+dH+MiQXp=c$N#j*n$ z?-VLggP@hfqM>mIG&YIRo&tEEHi;1L+bShuhomkjL8Ml3a92i1ZL&>(ItUvwe^uF# z!MVLq8DZUUBi*J*hD~!BEB}n>{hVQv=NQMGY)!xfOZ9ZgenjR{C96B0hH{G?EtMC; z>)`u6K;=%*5Pf7%IJ@*f$@SKtjQEjJ6V8AB)Y$iE7@-J_n* z_6O*;BgJK%Y(pf=nx@@N?f%FL*GirwSm^M0E9pEdCHc%(Ql`)$8PNQu#&OXe;qPS!|##FYO=q`+%vSiB1 zqU;~ie@u)6p*Hiwgt$o|7PJb5cat%@`{-JBr}j}L*q!A^?5BI-p_*Alwq!0m^ys|s zqlp;67-$wu|4vo(q^^4~v9`uQszX@a71WX26Zx0nul9lRWVT?R*RcbKH@Ud|pns?8 z!Dnr}zgqvXPVvSDV;!RMC4@dvd}mtC*=j6OIr%emE7K-xj9F0p%jRD($%d`&bsh15 zwh_%bV*wutWj6_1t$|gMsaRxM--@h>Mb<`jOY=|NoW06f!WV1fr$MP2u zZ_WC}nS5-gO~r*SgT!hgHBlm^%5@(Rjdc<7}p_59^a*W-Au(}Z>Y{p;vCZ{2_>^iT`m#Rpr}m(0_}hdT7d zTHD(OV%{K7$@Vw=OnQt7}(K@nYExxYa z`cJ49;0=AhT2d1O_+00O_1k-IL|oKya&W!r@Uhri%mc2?9`bG@^Z@uI||4xk%$%%~vL#-o2YTK%Js!ezTBlIw;@R57jc}`wuJ0e=F`!1e9 z-r$CLA`leqXk5Q%)z=4}a*iI_h*ZtwUOxI<@#}3Q<_;A9vRza}f685;n;J?R>BN#RWEvj>n!uy zk>qV_Yik_X-ue~wZ_hhfreykeZWk)Urtjtdr^wueqhBmOWcuyp;@3^T(VE-=HKp`U z`FNXiA`L>&#n$FlSTG;^9p0H7#-q=8353LTm2n8GkNcW15(lEwzCkyXfNt^MLyBPZdeT}ju&aI3k!&-9DC$W33fz8=~a@lwy_Orgm>60XCx2lo6*j8}@tBZRp9riWyU&mZ8mP34`8@P03K}r__L|f!j zGn2ST3=}ezw|@FqJ_`NoQv*m%jZZmXYYRb_$eF3ud+vF(eg)2Fa$ZUWlNZoc^H~@NxjmmM{mqRR?#I#IX7S?T@tsw(G49 zOPC|rD#6WCu@aArEdjl7Gq!bzeg><=m=Yf!TLK2{oe`EW=c-i)_e;gd4@MRxiigxX$t$OAx^&D_r$7X|Aos#ZHEe;L6Tb( zN2~PrbE=10TwGkT$Ft{4LxeZRB94Al^Jy%@Vy4)5_)X)&hct*|`5zh=&W{VfVO)40 zN0j2_9~>9%7#E&7F1&kOgYF*}ZW|Y_P#A$Surp;QFRLDG{dKy+o|mXc{&4w*OsM%x z8?wi!vEGAkphu$lONzAggLDS<;8)Shc^OE))!6Ea_{b*F=F=RaIGbfEE!bCs8ucuM zODZCDu0sNy(>E94lQ-%EH&x`(1k)Mr<>i7Ak}Al<2+ecN1Z(=Rpi3m|p67Z9EI?u8 zbRtuV)cyDAFtVCRw!=H-T3vv)NL<%C_Iw+fxH%8H$FY7*a_`|DlRdD;U1H6 zOuKVV>X`F9B3y4pap~=Ju>$lN*jX=9hVr`|`gMtZi-EZm`n8F)-h*2GNAzon)9*co ze($mLYX^lOHG?@{CaZRnTht_<6&>XRyn%4z*P*HFlSZaXtUB-`ZqMm?lk7e>w? zvQCk+h|GkMvxubs^V|iYsm&IjNo2huwG-J8Mka|wQ_piZ0&060Ih#m0E8pl5*%U^4 zL^i3P?Od&Xj&-p)H>HJ>u?=$u_<;GKtL;ZR`kcEo`-*W97IAF1-r?) z5+3TbJoE)7NuD%=CGPMB=Mvv8M)H#xVm{#S;H_gboTZ1{;XF-`5sOwEBjkGt4=& zoRdM&Jy&}0yji0;^%>@zRnFP0oKlMC$*Ux6kv_wm$#TvX<&=gzZ}w8`V_63<39ODdZW zhN}HwsM-&Ps{P=;Df_`VwI7UA`@uN1AI;H6OZ3qieK2@!o}{+RD%s~$gtlKhF#+^2 zn%f=jA#3;6|Dl~uI|p{=&1l|YE(D4ES2-`N1HR^97fnd7-?O?lw`ZgG^|a@0>v{h) z%%#~=5)}J*sIz9(4-E(w{$Y6@c=XwxLk2Wcbv-hn)$otpkGjoelE(5x9=S}oq$RKf z58t-?!Ubf*Xqqv;)CIT6E~Qh3%>&zwiE8+l$ce8g#>mOo zoQxdU+4!XF9aq`j=l{p$w)fA;d9CgJUBS3?ds}T)Q?|GNm@J%_zjjNCha2MIUTo+` zU^itjTyG(Zu`pYM*-n*!wAd>~?Pf%b+XgV{rUx3rYHZib<|Ys!BTTxBz>GX#y)VQb zJ^z7z3(>R~vDfniVET8eAy0-tgXGJEWaO2ilmshwK|f!Z6BT%9y!SFUhuTnaYE+5v#qPXPZ0qJl&YhS zQTm6~B*PYkz%OhxHHB4E(-%xldvXUjXKU(-PGl??@;Y`$_0UV(setoKxt?VI&WBam zX^E53ngjQFVugxoc6M-dz_c6njwb4Sg5gH>n&^Om>+*;IY9W~|e$jEOG57(FGiD1$ zv5DwltGR3FY`QJKjwBVOWb z__ps)Bwrc?CTxWjt?uwIkrVmSfIQVr%Bh|=8bQ}cEt1&H13O!ul)2mr*q~#&4EpVm z*|^#=ATk#T-B8>PZ~vYVJKCrjMKUI4;d$Zue<&O9>=-z@)-q^$KDny)zj^p_+y5^= z{E4;yVS$D~muUaJ7K4e~AHEiohCuSPG#WO!d?xxCDPDqly*TAVps zzNnEra>zO3oJTvUS-<_>mVqPAVdSIcQQ#hSA3EIjMZWGo{N$m(KfL46GcT47Jw-Jy z{{4%4UK~0!bh!2pDM6*H_J8M4SgC2QR(q@&41Er){$*f7Bg;mIw}WmO)swcIVd$9s zz@?3&?FHZU7gpZ@l)BvZV*a*ihbz?NJwQ2pt9z*9ewXjX{qDf_iUqsYyjVuXjPtPl z7sG3d;7y+l-r-vl08bd;iNm)h2_#JbN#jz}&T>s6SU5gxfA`SeQakDI^{=h|b*ie# zZ8!K7)3-x{nZkYhp@nXQ_tR^B5JDSwf5JrY7L0*cJszF_Cjgw#N0JYN@6&6(QLe!n zY|MJm^j8m@A$|sB(EVl0&!0Q&_8&IA{J9rPVUL|y^}~p2J&6M{Prl zzDNIpL5d;`hmRvpGv6wKO+A!v`t&al+xXqmcMg4eR;dZoiMr`KhxCrhTtZ6B?J3DQ zn{j&hnQxW8wf}H!;c(jnE`cN7=XI~);b)G{F#UG;nZtWbj>QF+ED4)M@7I&1it#_1 zo*+FrMS7C-)D-D7=7IDS>1onyrbw?Ly>^Q9TGXKh&#kF0X^Zagp2O|~CiDHe$>}@a zBw~9+23qXhUxBpx&f%jo?f4BdL{u<2rr8{ry`irKu()8UFnPMA!sO|e3X`W>Dombk zsW5rErGobd|DskO`p%)FGx(dnQJ(`lQy-0%QQtYlsAz<-8>Dacm*AGQ>$Rp#u0G`N z&F%5cwI9jSkHkh219}5@?Sh7kcPkbVzok&@d%#_A-uv7u$}l#uuYjO?AfeR%IZ-_InS0 zLuRO!2go@fJElJ}+T4M;He$4i1HT-_M9mt=Mln%S2HqCMMCcE^JBo==9(aEg6QMcq z+a{*8gde@E`0tpftot-sK7)4(fE?lm7{4Cx{^VcfWKe5SdvEXSjhSOT%5JpVt=a$Om&C*KT} z1NyTSay^Spz>mkd?QyvOEI z&$7zYGC#${uUfuQbg`qG>yxM`oS#g6(zEq$Mh*SNadpUuFUPHbTsUX>iC<(@w*1W7 zm=Tt5H~;VX;g4ALHN73RITg4xZDAE9TuRJbex_>%`A)o#E2Nk2d7P^~mv2{$%}wj? zNjgJhbeA8`yJR`tgUinH*EYPWjEXU?(=vu`yP2cjfaS`!Te%jULptCn_y6?J4`vPh zaF+iR-`ujwhJowsUcUXW!F>74`hQ?}?a=AOz{_iWS1ghoI;T~J4jiW)-E$+BO9h+j z*OHe{-BMado@M?G()@zW?^FUMG6Z#INjC@8nhYx{g2zlLR@<-4$09UzfnxW$!PbPL zIjY8C^~AvOwM15NGZ3@wd^mDG$2YLl51mhd*E0WBt^3jj;5`Ia%p5sHu2itDT0m@; zIRiWN*h5W%fmPG$t-o86gkGVKYRNQB{obDPwso#te#Z3ADcdvV{{yCfdfqNGQo`G| zvNOoz=drE5aR`Z9$+P6kkDLCnef65@G1FHN-yOP88Fb7c`$}At^~SPFE@2s$T7KMi zmg%@N=KnqFIF<6Yb@7~#xy{ns)*STAafi+WM~C@_ekf;?dMJ<>`bXW&l=9EbSEoH6 zcGt^mZ4cFO5gV!5=hda-(&RLfc67n8)bm8J^_|n|=skjt3h}JcoMpc3T=o6Cl#(3@ zHowJWk=@SrWsUmMIZxK1^W^SgWULf4cRu41ypq9|8&t%37H50b6Z28p`iBfOJay*` zouyFc5($=}GjmAfbtz(2Hgc69rHBAvd+Rd4x6@`_sbNQdIrO2fky=O}4(x1*CeHGD zvB6)A?M`c+e%+-V9jTEyQhXzCAhoOs;b?Ld$xfV>)Aixjl9S^RmI-6)p~e_4ThVL>E7U$M$^obxW&*+Z`)@%v^q9gEhOF@ z6Hgu9wpC%n=$>`9VYgPoz(%z!`)|vhv^dic>*A2t+e6+jo0g*f4tx3z#N#|VyTXv{ zI&a&ZbYd7%zu)PO20`Xdkcm<&IWkH^wVB6m*Vby=lTk0;3!HLX)O+^=Z8TC3t1gJVH?9O~u$nEa7~oGg3gVV3+ZF1D&wyh&Ec$;2{6-^a zuW(yual5q=k)mPK2->4Iv@K?v1!p_xpBhVl*-0dOWNWF5=zgW+Y}*~W$~VKB5${jrcQ-mnRxaJMe$@0*}SRl_3I6r3j z{bxa3zW(^(pB;$9XE`97nXJ*)nZuYkuIK*J+=1nL9RAsLEy}l_@Y`MIG}qOh(y0T> zALGk24WfU)nM+4=dzK%Fl^=5al;7$4oe94)36y8o9MgTfcTsKPZ>CjZYTKm=WYs)> ze{TCwsbb)tD*pM;d!{ej#XBnGGr!CJ=6uD#u8O1I9-ZH8`L&e1jPifATBTnM4YrX# z0QM0bWn2s)mc;lR#1;(;RZKB(iUQsQ*}pLz_06lQ8VTbQ6ko^se=CaMwT3l+%0{>3nJf zZ>jxs1B_v&!EWZl7mfeC-93V64gL#XtE2Eg|F>YBxp0bnsX)?ny$&RZG?2xtebp$c z2!Xj5zNo_-{(2qYu$d>#XwFOshp`daE|xyRN2?4j>oaB$Ud|4y~p znrZBE-Re(Qxj*yQD6b$lx-AlJcwW3eQ`A!BC$m4(D9|03+@F|XF_?INLi*ysv6XDG z7NA+t-VnuEDHF0s7@gPPujZj2R&W?q(Tq6U`G>w=$+<&?No^+&M>t^lJP0+;w*^U9 z4B&O-VK3HX)y-F1O$_;$z=BGQ@g8tG%q>car+lle)`V~vu$3x=3pCql2DR?s9xbW5 zfY?+llBR+>)t!($u&AJi!kX=j7(7uLZXml>VECHoy#$Uh*@e_1F4MS~!kSu_h%?E* zILwbdNuFTk{JI`#X_#MJjAqoN6|*Em19_7p9KUcCQ#bNm24j78SJ3@33;G+i^k%Un z4aqYq%IR$hkS^S&1)OgG)n&o;{H0WYLjqCubtZdAzk&o9QxvJX3@17AT}sqlR7F?@ z{XZ-qy!GTx$`s&n*l{?O3v`49be)XWifL28;54QYkg#{WY zkfA`WDNr+cf$pe)6s7rWnglI8W^zjcIy4QPcbSvX>gE`lo={efB5}ETC%wyh^AujJ z13On*5l~(a%2?GCalbuM4uRLwAD{TY()>@)b|YA@P)HVG`kBT_O?+>$KdIA(w|*2u z=IMYPY|>pt`K(L-)Vk<&f8wpv1!Ps#z|J1&2%omRZVbOx{`4P9N~DGd3%9bWC$uHH zTv;B`TryzJ8g4d6WJ0X$kvW4{#y^`q6(JW#?SBEa;4TL#Y}^hwA0JPx1Vzwp@J~mG zM@=g6f{s5NSoZ-EjgaHl9M)4srj^jZXY;q?;qy8?`LDDxYOF4xHOD5yMp^v(cdDUJ znz8;1MkA74 ziSDq`Xewduyop|HqnDJUmzwBq8@;j|-D9Hr6ulv{7RD0j1|Nq^X+e^6>0?c7dCjGE%Nu*qCdpg}j>cffRjPBBLOR~@#O>36zOyLv(Hn#$xdoYQT!&u zT;}kA-;f!8;SX&tPQ$hZcNyolcvg9INVn6FN@j+?qTE(>ikhS$WpE7}u-SOwTAjuY zsg2?K<0AWyE@_g9S6&PnxZ(L7y`;n`2R*YyotT@rLrRw)qm+}xTkU@_?UNVIjvStk z*}mf|DLsbV%awWNInJQz)4XYY6Uv@EsbwxHWW?Mj`y_GJMm@ z$>9q&h%bcZD-(wNT^Kgh)xA_B{0+sbRYixo!PXiPsgkEsFVzizUI5vY^br1xGJGQ>CWjBWYT>V;q*Hy!g04g;U#dg+Ge+T8 zh45#V;hRQI2|pqD;N7k>fRgPqLimXg{>)MM<^ln-%qqh-jhr05U?UgXby|=%bU~+k zBKR{x__Idgnu? z@Mj4=c(=1b(W{9h8N#0x!k;|~e`W}OR8X2mP7YtN=~wnTITZ?Q=yXp6-y9quZq6wD zSs{F{jK68*)bQ!og}_~zvhxRIGVD4#Hh*}k!p+S{4sEBF$!1jCyM5Z4Gdl#+<(C}mN7erKLj%W_v9m~MA zLI2%C>N3`@?4h#M)qic?<4qObPV>PTq=J(#jzHg&_Y$86!A8lNI&2#putC zGIN&kzUc-jGX-;tn{-Ro;@pWgPc{?1v{e^0<$~m3kbWRYZZp?{t{jRLOQZ4RGq(w& z_o)7N3**}<2a@^B{|dGlrM)l0_Fcp@1o`VyMCkgvdS-BK1J?@6^dI4S4l9~xIL1_S zmqQ-i_zP;ca2Kx+K1JwC3}+qvi}A{HwhV*PC*JxtvtZ|}>SCi6j9;%>dzoBYnpq~K z>F35+x6-Le$og(xSpO7C(Y=mN#5v}YjC(5rcWvO_Pl}vHf~LV`*%QlrCYX0~hl(DW zy0=2P-yLSJjI!szxj9w>Ka?w};8q}Cs)ji9DpdzUG~wP#XM`^uYepvImT~NvaX1(> zJuYPF7-H|eunY!}$Xu2^zs$cUq4p6?t;;KHap!oska>2?8(d(@n07_w5SX?~$~h{R zixr!sE~>w(x{wi9To(fOs_J69?27B+K;xCvlE3U4_c9*JTM_$|2@a-$! zwiQMbZ2CH3czK5N9G*?mP3UNE+kJR<-18C-PgJb~J=H8y1mX@uI{ zdMcep->HM`NRPWwp;k{P4ocmrW8aYJ?zx6x2Jd_$VF+{gFKXLT);SFGQ1NuoeUq9i zjbs#MdCk!pwRddI(5KL;@}!z_mrbTZzFt$3>^GRiuaHi8t^?3qJQ1OEZ~i2ND&(6T zSc6vU`3X^~BBT_h!D};v z<_1jOjgrDO(@~vVc6)s|EJ4ebza0eA9ni9?N68XkTASMh+QP8MY->%}UEDO@A zGHGVo35u^&ad8Wm-@gr{vSVJTxI-Nw)!IdH54!M12r z7j7}Sa6VLki|D@+K;ds~_*)nLV#7A+_2F-WF)%k4xn`ZK`HSgWt=!apyF_Z;@Lr7f z)YlRjPThf>9pRpXwWlLb{evGGc)ESySbZq|+hQUWdDo(T8aWiW@76X2OA0ih-b!Xa zUIL<4x-zj0)dd;p2gyGmE!0kWW10~9I0L4g8P%-7dFouHjUcsULPe-~RC%IEXn8b? zYFlANtcYtBu3l$s8Q4rO6q(hsYwD?t71FDvVBCx6Gat;vZDs;jWmN+^5(`dw>&@*l ztTG@QBk%WcS?px4Txrh2GH*6Am-6CtyXI5kJDZt8nCMs5!}i2?wGM38)OvzsxnatK zG!bm7GIPH+{$1{fTN|W52YAlp^3C&B#`lmHtIM88IBQ7CaZ8?525I;m*t^e)#qCOj z8?4?Eu0((zFPi6u!Vcp?X*Mc@O$LUL6&&1QNmNPmNFPgvKO`byu4Uyu#8C{=%R#&j zu9lB^hW@P$Hr*KMABN?5N5-xj7?rVdbEpPK?iFu9CqnO7_$%lkHyDwyZN*JcAHTQz z-sEFq-?s2(OR^QW4(uTJ2T#CFb;5?|Ot5)g*mk*1Mh$N;+oHDN@mhaN(%rUq!wse! z`T=4Hl0he}jMU85$tWf_9Fa$zRTHOJ`tk{uUoJf;V<^Uwnx6)f7F-R*JU6cY|tLoqWeLM>cdR?LH9 zzXp{Ud-weZ$fFw(px}z%goN??LU&;=RY%JM{f6mgE4X(p!XDuZuu#q3% z6bO=Uw&?aE*PGpRs;V#hz$|7=*mr7T$`W@!xt+ySWIvg5BPon^@t2aBmZPiZbJ+%LHp*s8w-Q)lSVBN-KWGJ4g zs@h!t8o0Sp_%%F4VPx^e@TomRIVTQWo@}7)4ORn9_DBSIJ!;p?QHUw$)yV;-%K+uI zg*4Js9?~P|c?;SI+QdUv${Oc7l*k67^g|=NG{HRU>_1zeb$znuwq<^cUKBlL(tV#L zXkX^T!cVEcZTxdPGVfPEypuj;mEDuMjeK=v$%Ir>&IR7!8i)AWpwCf9&@9st?&pJ+ z8?@9v9d5FlE-)ud%o1fxH{hnuY#DZfB~vZ1n0uxJ@1_`;Chu4%%$qGC;RS6B)ddb6 zQ&gWj3NAer)kmRe_GOxc^77Kav;oPrvUt!sScuwmL6(OjU^9{2I$MM!j}Z&=zqwwm zC-Yvsx<&ehkdsbn%iIYKA#z{lgChAYL`OYL0)5h#`3N5@`&%nW!=Tib;n>bKkX#2o zehx@(b}()?8y5q+u#s|?T}03iK}bm6mbptL*Di(`9v>C$MeA^cLGsFoZzE_1mIYBAX&aG`98aru<8WfYp_a@k46<>@Qs za$ZCF#9Pga4XfCh=^ovg(fREU4eVSCIgRI-eLpBZN3oE9FAw;7gU>J;L`*=HIt_k7LWx@;Nj$lE||t)()<1G{z*l zDIXN&j^Z=@KfGW>-%0Ors?d6@X=Z3B^d3hMUWT%rkUUIYV1;qCxWf`bY~aiL@A5cdbTG7J?C6+~6FRSr2+UDe z&IwixyfPx(c~wLhCl)3f4vVgh2p_o`A}qcNPWaeF!vVgKTJD0xWy!|Lh_K|^i16{N zA;QwDAi}brBoVsC5y2ard}e6K*x4f{7*|{k5xTE}2zUP^iLi1U5iUJRj+q_qxf&w$ zTm=z6JrNPER8^R4IP_i{5$?NEB6!^>yQya)J{sdi5FN6)ommtmoEOAikVK^%|$> z3bI+Jk6F&y*L$Vk5sk{Ob+lG=E_b4s4S>-_9WS+xTS-q0lJ$5cHgOqGEe(P#)>~lg z!p^u1u&@INO5{ZgJ3~CEwosJ+h&trsJny64`XJK@H|Yr2rgxg{4f%sKXb;Jp z6gKr_p9=Sp&VejwU^Wf9Z*caX^N$qtOi(S$YKy8iFt?PqSF{FUg^ekOMRvHf2ErzD z_@BL4nKC#D&yqs~?Z(t(I|A>pki+%%HT=v&*XEufuJJ@dV2|hIBKkb!*2ArR#t5d9 zfby$2JAmNz$R!}z4(_YIcX;gOM$!9?_riHvuMgm(_?;F5@LTpVSiAnDUI8RF(M zcS~m_o17kNMII6$e?GIC4^r~DP7bcowroR0ZC*GqDc&u8+dphkT54lX9VPcDvx`2dF%ZktmY<}k%^(!DQ$Qrd~*_Nn*D&4J26Boa{)If!6*lSI&gh@vE>Rf~J81VhzeKn913 zU{^}(!)U-z(Ymb*rZpGS3SvMcZY#JlIEjXEaJ2Y+&;H#dCD_x7OZg|5-m%V*L&0c z`_iRbGsV|sxLx@5nc|J{v6+w zl32IEp}3cI&EhTqIfrj_5l+cNfZ3uZ|HP7GUC(a%cUek&RN{bI{M^}?nwQ~iP z1*P2O@)7w9QcLz-TDTy!>HE@N53She=kXbG;d*g4aX;MWU&+k@W@S^n83p39#OaW-6c) ztTQe5u#CT9?6>wcECSd2p89@~)vGSpFAC0gAjCoYMZcS1`^7+2N~m5|JBi2ws|vPX zV1Tc&1Kggcwb1%0JYeg`gpHiiaWnUT?Kfvq{h;r#57p{F3>bwVD_?ZL*3b*mgYG|Y zM$}McKmOR<8jh`c>*t(r+WL7xdeGl~^GvHBEZ%qB)|&6ITxsK9mEJ9b_Tr&ku^wI=O%~{8A8fPRSJd3TAf@r zIElcIMuf=RMk_?9XHkCO`}D(t&z$G`%s@%i_`=InOrGv96#Z?%@mglspXzwJ1N)QX zwbI{`UOx(l+yvcXj_zfn=T3LL7WxailDud(Ay@`}p-0Q;bc zr{jeS(6S(ZaA^ll83+5W`%+~;?ct6IxFMjf3)kkmVER|v0=a;5D~y4*_1_%hH6vmB zvIC>94FawkMjFEfdTjT`@qZYd^aXRrW~YA)2p*h-81JU?FWmR+Nv`cKYrgAjr!{W& zFJQ_qHQ$xK*hymHgW-l^U9z4#aoWI~Ayw^T*f=Fi|Dp4RcwXdlD&Kqd+45cED&&;{ z<}Y^B>MNnuFUIBysFgkxe*ooNh0j@S>#tYpj|U&;@rnJuXke!P{^eege>mX~H6O@7 zR;&;CcjMhBrEa^M?}EPVRAEr~%b9kilZL|gR;u?3soqt{JCE}9Rkl)u&M#v5gK`Ju z9H=V4ejfw(;B2|Ve8A5qeETm^{>D_wBIBF*X*fU#|3>!5ys-80#)+i*n8u+;Qd2x;De==-A0O(gu8;0oMCH|> zcpmk^GooIo^P^r>6gN)?&S`T$0qrlYI1cDPy*7Z!0a8m`sB?hSTB6bZD0rm(`5|b3 z{-FKw6FxwyqOU^PY50SGl03jszjbYYF!hT@`~LL$`_aBb5s*xuQdSz`*w~hBAv*t>dJ#%`=RlOU9SH7 zj;~^F!nTa!1-jd)_=YC?T~&LU#3K$z@)ePtN$_IJzNGW8BPnJ4++XvtTzz>l`#!9# zav8eY$9}0L`;b*@g+EV2Dn`k$RN9JlGn{#XY*J6oU#O6Zj3oyy3#_Ub{K0)i{iu&2 ze0#*HUV?6oI$Bey4_HIx)~`r?^cHVS1$m!aDX*iQ`%6*IRmFiz0;mE@*^A?=W8mdn z_kg?nf)uutxT^-dpq(8t^>g?aPdt{QwNjt@qQmD_(LR%9>d~$Tic3Q)56)5pcIyP2 zyZm!mGyS$^tiDZu$Xq|_AyPNU`-NU`_|i<^_QIlhP}4Pc(@9NZ38KDzbgX9tWGLFS z%jFL|jHvBeJLra4x2XC$_Rdx6Hd?dJdh2Pc-#7oGt>2*1YVTIm`VDGq-hGN%zc^o? z+aMQOzn!PLeiyJ_();(;n`_)&r*u8w(BIo?FVx?y`xn%$2b^l3cVnn_>(%vDJJw+2 zoHTap$^wjuUy%O1fcoBlm#yy?#Ctxx`)8uQ7qDLO8+Y0oe?fZqi93HfYh2?cg8sdL z`hIxY*7pn2!$0)ppZ5CRyD?aZfj1;}y=mH6Z$gM+`8{6}2bHcjA(YP#ZPx#c3gJP_ z<->sxo=1yY1L!&QcwKW_Nz?%IMzw)UynRf%*xu4aIZk z+n2u-Fsxx2Ask-7QhgTn^<37kUh~CJjnSDEsd_C@$!gDrt%Nk4-^Bd{a3RB0zFXbOv-m+-THsON z#W&O5KBmuj)BJ13+lwFMs2=Vze4GsV6F>K_{{xD9W5)Wp8Mi2j243zYBK;(M<4vi% zQ};?XVHRWeaurxum(#>v&1$iH;5@d;KZII_vPltxvgs$_?f{f9avs8_xx+AEfj-Wk z8Se@HjC)7%6L|Ca2{<(n3p6mBY*QZs01E}<-XYxPRUV`KxITkFkKj*I1jOaHGsS$C z@Ms5W5Y%DR|6}Qgkb-V?i1iv`^D8Q#u%dtuMMBnmEPkc8l#lL4Mibr<5TeKU*Z}~e z!rzDB^?3X&@d#Z<ux6N=c38+^=s}z)15Ox6vpn`w~6tr4Fg9^gl$N+@ngTQ%MLF*JW zq9E)T3qYd)1=kaySb91Oq3S**TF?Cn2z1Ae&~U#9c~5%V<%u*qUGhk>2C7t=KktgOeBu~s|EuL&X zoR=k^5lJV_26-aQs63H|I)$Yf=WBk?grt*Zi#(BLQl3b&6;GCC8())VhoqBcr#z8n zN}fow3r{$}q6KpVg>rfsS|*s(HjjJLNcE4G{|6)>0r3mnBoU#FnIUyKkkCm$XO(~s zS2W=7j3Fw2^D+?(9Ksi`Vk01e0E3tXNxArxeA|s z4n6{(oezI@?e**jyHy^BKKl$=-@j!zsXh+AOH%5HcQ|orb$!&1ci0CCi1*&-QXitP zZviD3Y{w7uBN-?&-cJ5CqPIa=oo)gzMSb6a2mgeG$LoHI7I^0|@^46U)ZdVSG{S|R zH)O}|X<7M=_1{NV81#=qYvYLHSPA!)eSar)GbDW_lJa?`Kv6=+f?AbDo-XZ#A}C0K z$i*Pu0ffx8C_>z5lD^1Ibg&F=dxgagC1DwCKsc1M>j+0c9dZqgKh~xle^S4z@X?rB z2iV1Nz$!>63Nh!d#!qD`rWoz|mTJ+emX=1JjOe&m?L>Vb2`Wbux)!&C%L+%$tlLT0_wDM4wt(m+phjF*N@K6*+`7*+z zAs8^ESP!;l%=v6N)MmDbJv!XvRK$WE^TYy48#YJLx{-#t8U+oEqu|Y@d=pp=_onU+ zgO@27JZV3*qQbzITf2CHF3!)%J@nLn1F=MLx$Wb&jk$16+U7pCUZ{QA-S+te`NGI? zTIP@OI<{qQAwITc29Sc5X)j&REyp#R=DtgUrlB%<{gN8Zf(9-BCDHY?Ov&7b9N2#m z!!NJ~gRY0lM;WbHfn=bPd1PlhF2g z7+2|NAHIm`u+l&(CLvBAm=PNfIak|&bAK!Ks-_=r9JUZt4ysNq#e0AXcn&7nav1-g zBr}dg+L0kvhK~;uQ?0@B2ss8NOnV@z#{eup`tqP@p(@re7IoywY&t`Vc`U#1{lC)x zPlbK|H-Cc0NOd(zHj*~5DT#H4^uAIZQp-U(ev5&MZoH8 zUQQv|4hvs^egB=8&ELw?FNLsY{Qai6Q#Sv6^;4)ZI~E-&_bDXCO1aIXij{J=AO%vc zj`?Tu{|@R2e!e>9pPLA;N6NYN1ER>>yg>Pn+hF75KVHYy%q_&n*31C!m90{~c1V^T~gp0-iPHKbh4j|H*N| z^8XX9LDSYP|A$GjQ2F0^w&?$>@B{hTfeDrYvixgW=2SR+^Y|+=$#>udZ-wPe0oUHV z1?F;<{$CF1|L|KtEk+G=EUH%G?`0EC;xrUNbjKh*t%y-Y;Ixw}Ltso1e>Nl#HU@w#tb$m(r#&{)%V+0x3296^9gYB-vl_4?qMB%zAN0vlRe=%i<4~S~%-1 z2_EuVyp9y`TA;o{gP(0!8T{|XLcyiLvcluvBsFdojtheU0bp z6tr&-`_upqvnr!DBmSuW!jzir`^;8B)M(%T7l;M4?_cIDyw3K0J1G|4zL9|o`<|oO zjNj6VSW~7MvD}y(b@J^D5`YVk~Pr+zq@V<#;!3`9_ z;1xaN0{R(m6hGsQ;%7YS-ZX#K5bjB%Z z&n@gevF-U@rqpcD0Y%hk&sPAkfcE@9Ef!v9d+s4ceeH<>1?1`S&$mw|)$_Sbsael+ z>=L@rS&H}1-w%Y;GuD8UW-oELL)-muv&D`iVM8i2Zp4{zh<+R0k><<*L)VLx1` zh#K}oiin!_!#g=#7G^*6>e!=qdmj7p=M_1h{qP@VxYcK04qp)T2rT~BZ(m+cs`~AR z=h;7=xBubVkIdIUUZRK^{o_T7sL?;Z|Ka)i$8{Xc3+o@PB&o~3Jf_`qzW(t~fQh)M zuYVNIx9|n@kENulzki$(`{S%4YAVUT{Nab7o5b0d`;nkjarVdONp{NZ%iVfPK#cwI z38vJX4@MPHV?Ou|Ac6+2$G-f%U$F4`^qOE*d?hJr>ot-6nw#cMN&EhaZ(54wbo>X4 zkQm#(bDIrST>E|lsi)q)e2{%AR&V_(Q);&FHbvBE-}eKtfc7n(XW@0W?^{T*@b-Pa z_Q-4h7rlATKXvXk8>wmp|JrDl6R zfzAa)jrRN&5DRF}f1|Fwp!WPipqf1W8d>v=*EHR|~tKuE>a zVPD>swb**>%j*cQ!@gVxzcV~)o9TXjq4&f5!8occc0bJTFePq3OkY4!y&vXcq~HUG zQSguf&Cjt0w6h;Z?CB7FX)1z`|axid5z$5GFf9^M}y1l>k&bZ5{-Ca6e&mvLd+#z7;iOwOE{gEA%Iw~ za@F+h;q)CQU4qGl|1L>i#mzV!A&+tfuNfzdAH)fN=_*LCasX*z8lc(WH*z4>_m)Vb zup&c^!aBE&Qqiv%{*h)CYjY&E!%U?eOx(Y%D?QJ+TWb~Y zr3Dz|m05znt6PFCR?-G34_zsPg^g3ndoS_Ro__!oEdga#;#a{bXrMHI%dgI$4Uc1t zk&OKLmaDW&*H$&zl1+QrF6Ja=vp=P3{NQZAq(%!3o}cDMlf6TAG}#w=Y?IC3R&>E{ zIa`KYb#uM#=BnmG^lD^;McPZ^tHw3HcSbg7RGLhKdLjK8>kD}&(M93?HMZ0LOpdc> zbkoDa#@Tn%m6kqk#u-+dWDve%WzedecQ|B&A!=o*49Y-De$~_e$q9~)6q2QE&x$P7 zK#1^qXt=#2Yq0kr!0}~)RrL|jOV{Vw}E10rF6~l{QFPN+rmMBKw~^7DM|H? z=ht*qT5TcY`4>N(hw-^x=UaN>6Jov+WNzP1@b z;_|vfU&BfaUU$puUVXjFzRt_*g1&~87@!B_^`O39V_y%+>tTJp&b}Uz*Q0zr;cZ08 zf|LnwT#Jd2GCoN9mT>x{N#ADEw@do3^V|V^=PdrB=E92HtQ(SH`?Z$mep6IW)`w9@ z7UN6?{HezjH~KTGLaaMh5$#6o!^IQ!;nudV-+W2XpJ{?u%^~6byyCG&e@1^lHT`+? zn%e!j;h&J*<&_>>r+;Ga3Oo7MuV;M{`fsd%;_{9vgSX+IsMo1fufB9%yKS=i{1Zo^ z%!YL#>rVRPi>jKd;h*3*s<+87)z&%A2489$t^RR##S=9&-22fDq*Xbo$IV4y|HLEn zYq$-2<|q^>(X-^p4yzXI41{XE z&vTnMCw|2?a{c4^ZAWXg@CkIAu#~RSEyLsam%$0zf2|g7jOSA{onsLU@w99z*BHKsH;|d{Ir$U*J!t%VkEQNmO6c{ixQe{Ew7BAwl0@^sRrD`NF3;gxDg{g3Behab z!Aj{=g)X2f_Mn!ZUh+WK30s#BU|8WSsdZ`palAhkdfykhe^1A2qrJXcN3W>V`{`~k z9b3G1q@~#9wlD-qi+>K%a>X~L1@f+{ULcs)Gc}j`TJa)`x|RN;OP+BFfFG?nf5~TLjLGm1Oc@89%f~EF6@YsrazU4XO(jfUUbeKw0 zRvPl6Qg^C&m8(rq!8oV*-ZW(7<6Y0%n~@&(Wdx}3yA|>>;|ft7CYaeV&UhAIrg&>M zib>tG;sHfvOVj~Q_2l*AnpP^Zt?rqqL9#H_C0bu+tR4ad0}9%$>F1zSK+jiwqA@=` z|B16PKb=X_b9Az)OQDI9s0P%SpVYKddt?D>bX0iOp{zfLiSuWiBwEEkz4OzX$L0#~ zO{_IB#&CgQLk0HF$ldRozK+d2P5z!AeXo>zee+%Cq`r1D!e}nCPaX2qeCM#&!Gw!# zLMNV@?;Pc5>bci8-wE{12-Cm3`Oa_QWeZ<)S$*pR_dCaIT!{z?|23vZU8 z06G3~1xvz*mz4(2XR)%#A_uP=4;jv~Tmv6(Ds@~{8vb0;LD;7xmuFDhl5$^Gr< zD$RF}w@A;(;|3>iD-ADdDdkH%->wsmPGmFe{T{p2K9=sCAT|`}0+RZ!&3W(rEX42Q zO*aaFlIOkmuq1qVTPeSY#iFOT6CO@p)!NE(v3rr27AfK#F@Z(Z>0RC{K=EecNM&m=DYZf!)TxT zmwc^jpS{raW?acczn!6nu?*OGJz`j7w@^#WZXpGAD+oszyk0@Q!YQwu`V@pML*&$NLD4Nk3K~)n z&M^o$4GX6c<+MRT*f*4|>>FZ^iTj2~Frnue2#v-u3-1XHZ9NC+H1Kt=kr@6$BT-XA zqq|@N8g8ybktX!kLfM}*E7Z(quRO7A`|uQe!-QU7NScF^&OJ{LTAD+a<}jWt%@MvP z&77o@=BPX|pC{yr`5ecSrFn+0Nh9Y{NZB%MRr#K*JduV6gIF3KB_cGflFoeEMnJ;RwVD5xjF%&p{Fz8FoTbwlp#Vg@z;0(#RlWe5DLKp=m-Z>)o7bd1Bc(0xeCJ zuSt`WbVgb)lP8v~Rh~%Gh9^to@il2WB%L&!@oG;8FEG(+-48je6qGtAed8Ig3-Y>+3?jLH*fHsZ@dgm-_9jPM zbR#?;Izw1oV2dIJgI(8>xOBwZY??cOBMPZt;0K4o2u<<)96COGI$o-tK@da+e;Rs5 zLu7QI$EnzC=ozO<&-gqxAO=FCem&!Le;*bcb?O;8B@*!@hdNPZ36!7mXPy#{`zgD4 z2T$ZWGo$CwS4_F}{?7@Rnh386%z5~LgDQ;@>B?7wh~f#t#Aq`VPx#Y{r_lYtVfhr* zXF$*pPHLP?p#eqtZRj%%BdC5Os9t^M7ap;q$?WE&qCn|T)1djg>9BOFQ>}Tg62(iW zCA#0cKIwF5=W~!wp8?T4(#iN|8v4^V${q1*Y?mjRPdns^<`X@o)_iJ+s7ZB}a(FiM zr&I5zxutA{RQ>wXl3ig5Rj2-R@D7`k9-$)Q-Ugz1q*FwHnuQ_>yqJ(U9~5m>S?8KTnwWSG5;WzBZ@b}tGCEhoW!+fk zs&k!7)}W*7Te$b)ACF*wV_QJHDB!}DarAujFDsHr9X$hHK2A$9MCG@F0^^!PIOOHw zXt!RTM!X4Q2DXZo)QC5+u@*Vb*NnAj<%7hiaJ5@wR6KcV#G7bb%XZYp{P8B<;`-uE z#Glcaj~o7sz^BuQJ9)w4PU7d|m;FzfkG=Wl#pItdtqI7 zFni?`^7(_gmL8C)mcz4DfBfg4Rp#fsSLeFID2QU?KY!ud>Qf8Z(vA2}6PP{8*_@rF zAv797PqU>|Hh@)fNy;f+{uV=jOBVoZ&r=F2hB5E|%@e7~XFC6zX zao+fa`#&t;g~fk<97GgPjrdO}F0yHCOG7v{Ho-v@|F}27)vM3^!q=^6T3Gz&hr-gS zPPOK}N)#`hmh4-Abm~w}3zJSi^5>OKk@$she0pR53_5Wm{(pN9Sv)IsAAfiqWs z`j^m#y9LF6ZVF4MI`yZ^l_*|+y00Q6=eO?WHcIvjlTLSmXddYl(VrUeCXINLM!X5U zExM2DREMYs>s;~iCja;k7~plqe|~?oB8lpY|GWbfkOQ^iKM`*>HkZb+s%^JF(){5u zPUk#Vu;)OhUoHlkbZkT$w>%{WMitXkyveXIRUjMe_F}Zi9r+7==Ry$-UE29 z>m>ea;eCYfNR8c_D!u}D20p(0QIzTXlF>t{$Ng_~J*0mvdGvvYR(!+nEWTq=@!hzh zP>?87GIU+#*1}QTTKE?XldZasl=uDRao-;fL&v>;C|dJ}Poko_?(8X#Tm5O{mUOJ4xgQ|O>w{ffVs49 z$wO$h2mHd>8Q@{1V3%>dD`S8fyy* zh!f`0sb|@a7Z;m@JS+XGx`Y|_tLt#>qkK)MUsXf<*sru~qqq?gdGZ2B=~wJYECjkY zyL_wZ;-j6Ju36o$RqS3|99Wd;I(Fd*?uazK_gHZxm09wgO9xW+-HPw{cvl=*jO-R= z1z)K$;{8Dy9Xol}$eYb8 zoO9H568S!ces&Rtq2G>c=Ti6kYtyNHD}S{9KmOx8TbK(F|BP(3JlQLmO}0n59}QS- z0p_#B8XWFjAn<03eAHxW&rjv}D^%)d?CEs#_|@oS%^&_QYG>@}O!N5vk_XmL^X>nH zXEb&@<=cP9bJt1#J2;pv?eD>O#bNZyx42^LYrJ`^yyQ48(ZgMr=6=)TeyVs|THl9W zz9ua_3vKht0k0kRji$Y>`yidbSig5Tlc9hbIVZE^(MyNV$!z+e2&hL^JX##iWc`s0 z`p!97Ny}E!@IDK1*!Id%FtzuMqQ1wTKC5~Bll&~bgA^mGz3ZvlPu})e&~Km1{jBD` zRFwZeJ`?akH{*w(T|O@TqeDKU`y7^>_n5 zyw6qZBj@4z)#kf8GR=4Op5tEMdb6KXcF2AGLDM&)^1mOQH-{Ttaq|Y{#@ZCGbM1jd zz?@_TYN_{1Tur)mQE>xBg_Ce=8iHUMO1%tM#I~;g3WfWYVE%)IP+5N4^=QIn$RuZk zL-&MCD&QE)v$siWOr0hyF~w)omK-oGOqB&1F->FsG0wk`EECFIJqw|-AB zqutE>n1uQ428?LVXDAP{Y^n4^^qRB5^5Rfd7okTMuVF^Fn2easJJ<-lf4^p>a?u4&d5%On?998M}oWxzZ5 z-Ri~bR@PN1{h$2e701!pM~d0A{S%l^pEjch5_|v`v49+1bAx{jX^&UZP|LV-P``3usihmnAL5|*Z< zV};2s2*|X{MafFp&$05+OoM21LlyL-L9}@)(mm350LeaQxCBV{xkV9VzB!$G2;iY= zwnNoyn}KAfbJ()eRk1~f1A4fc?{GEW8;fAT{?~Qj!U4-Yb-+jQO6f%12XD^EDcm4oWtjcvS(SApHx@qnxt94w?)2(b=ox@AnxJs`a4rp!S4>zv1 z(#nJBfnzZ;I93$OqP*_V*SNnTc-<|pd-e4y`#LYL3;G(zBnRjLc|EAF*VxxX@_JZb zud}a5QFnJrpr(Xuc3Fl~X zEvPgu*UOh5{YMP03B78bBEb>di;=dA{82k@8V1>f9@U6LZQaE56-bn=u)N;M;hMi9 zjTvT!#mHTbk%O&{_L`sN4?%XN--q;B=8N&o#N`h~#v4-iA~kgk=><1EeF2j9DRIA> zh{1}~{YWikzl?un@L?7m_6AK3Wj}ovFb6bojU=wAB%<@8XB|Xp>Tz`5;jX)l4s;;~ zM(S?AqZ!l>D)l;{UKgdF@(wW-($g(n`bLl*W+F~M#*dqxzmcUsf|OG3N&HJ39qucR zxkyyPv{zOHdy9V*mH4JLZGznqjCK@2E5IZEK&CXtQyt^!6T8FXscKk+ z##7a(2#=>;cgTdt(<(R79ZxbOg0`+2PYFZ9j;Fzxu4Kp48aFX+JPk{yS8W8UNOU~K zj)>5B8jXyn(a3nxo0h^@i?@XTlle*xY#f(UpDXiK2j(Z4uljVpT4m;|oK7CNW-yp)T4nO^^mV&^-65~L z^)(Lp5752xIkanxC|(Csmds?EQAI&w zur|nanX)8Z_gTwKm7}?_1o-M1i%o$UixXFQ^oybn=878Bpko2TbeZW62avK8NM8vo zzzYMW6d*X6oxq_z4A`Xr!5Khz7%;5>!2u8?Ex#X(dQvO{XFrrdaE3!Z%wa|Wf-``= zFkn^zf-``DFo1&=SqRPmR)+!m6d*VQ7zzV86M}=_3}9^-a6kcq6M#(w858lnBlucQ zh-|nFf7Md7HNU~q0LYmUq{IgRy#ykRIiwhYYN>GYKi-8ghZQ4GgPC+NM-(GagW2j} z%8C&vFhLf}?}wf`E;DFJI~w}m9H8YH_P^kIhj16PW%DWIj{<7?q2ydi7CHZfrdPUG zC0#`QaZNY9D{N(}w0{NwYEPr}xF}^Jp4s8d7X|X4yBDECu%`)x4;6@NRg8LuR;3DB*WDK)9u+8~Uzxc; zBBHhP2`Bc#D5ohsr9dz4;D<@_@`uDQmbsvfrP1p=+z(eJi$@w%lq~kLgt?$yIUNQf zelDOG4=Gs`^;XG(->M=1152e|`9CG{|9p(D9jtR5*9GqvO&3U#|1SvxWZ;eKJYhJj z2m@r~sgY!}xGW5qX6EB!9T5;DiTq!gDF3exbC^*MyTf1cx-ei?0fIAyygm%zFhdyx zX8>;r131V45S#(r6b5j70U$U7czYPY!3BWe1Yi^KmWh!6>*taGw_2J6`F}h3gfSd$ zU>}kHzJoce7=dcZC%lh4m?Mf2sKNZXgDERUpuhyhs3HH^{~GdNEXXO@u+otK=nvAz zVvX#E{8yXdRO$c!t)c%v3q^+0T%7!G=>J$&4eBRO{y%U1pZ(9uf6*hHc`>B_ix%M| zhxLC^BAoQF{$J4z?DXin`oE|Lj&d#z)Ik5A@-0sOH}wD7^8b13|LlJa`5&wQH{^fJB3nKB z|8~qTSdr#*54Db3K@gHNE(fScR89^ndekS3n>-wo^ERFYi)h#qLJ1r%Z29LtAp&y{ zYq&XeWthqGfPXfu_ccgZ<|bUj2#O)3R4oaouR_XNq*N^k=dWT6<*X~W~E*w)T^S@Q@Ys+kxg#V(l>x~3rP`d z;wI*A;9}JzQcF1rz5%GP;)Dyshih;alKcJRsLZEL_E^3}m1)-qc^0>WrS&X^<8L<2 zG3ojAuf>0!+`s;gX9^==8(m`1?M9}5RrM9yzdV=3_OEs~CDOmDJBsOF2^~fIS9eS` zYyawTQ>yw`uXKW5(+bi47288X{VOm1E1%H6`h>Mz{L$WN`&V^{L#TgMujj_}uYubA zYxVQ!UktZ-g59g`aGRg$<;$;pTt-V{`SQ$lU-;dDP=ZwZsaU$iq4H<{DY{)W;0K4* zaokoeE7rL8#(37ixjL7l9{H$@=f-kW!gxLd%+c_8{;61s!g#*?WA%<_tS@svANMl^ z`>(#h*&167pkJNzvFRt+?}Ggk*k};!4>N(drR+KWx!ga|7i_f(C%lpSCuF0Z>@@gF zG3#~Bc0CpB`xs6w;f9RS6j?@hUO-jM`J-oHk6G%)0C104EFeq%*qhO|{tIKe15ox$ znEiIxu*Lmkv-}=xk?|h|U$aZmM+AAP@ZzQ|#TDGd({+6LV}asU>h1BbS0sHm7IHsF;G#)^|ubtn-@7u%g<9@ksguf3v)^r~Y_sfNCtx`7QpA+nkbKk$7 z-`6hN^su1}dqq5apQqmkhHO22XRGXQLBp~AxcBYEg`<_dZ`e{JAISDY+sS4(0_?`N z3Vu9=25Lc&*Lr+~Y4LUsvg z%uFf&axl4tvG);1rCbZ@xx>%B6E)QVcC%nN_B95X!wh#eV;C@^+EZm<=|m~!&IZ${ z)ugyK1jdievWN#*L~IB^PHhQH+ay$eLLwtexzB-sAJtdPeLkkReSYo^ussYAG63fx zaK=`N*y8q)vlMp@cr9+!VAJBZ+u|N&=GbTertJw#+oiY|U-C&4-ZLOceG4TXDCVw- zDKYBeT2wGLUf}-;iFeXU9!|($fEko>kAN?uf4F!7?wuJqcFXaL0l!H1zE`i764pjOFe2bu)%4XLBW=~U`rj1 zXI5OVEpr8j|ZZ%}a4I|f0u=Lct@>H3SgKZ>aqbdNtq$+=CiA0=NClspJe zjqlg}lF0-D`O)>tTIH+ATWWFn{STD2@T+X$*JD_DpAAO)M$Kk|Js0nbc??TzUKE;T4ozV(<--IhoK0|; z8cMHC``HVSyoC%Qp0PhE9oY`Y`J;f~z6m`v?3xTx-aSPx*`$=rGZ*apCQl3^PHSOKtnGOQ55Mgi+f zhK&X=?x7t>hV=?8ka<(y>LjEh0-pWgIh2HikPCRyrw!!VB&2#J1D>mZ97#gvvHOan zY+U`|Q{ILoq#^>IdGH)hLQ<$HPmyJCu_qzN#lJ3K_{#;gG%7H-&GiC~Bo9(&D-i<_ zDN#)jGk_;3Xp}&N{pI*G$zM)h&sRVF`OVNz-C*OpaTvH(^!IfS`DNywv)Q3rvuoqiCT|TwN8wlofxT~qCE&)6AKhw%qXSZ zC@iBj;tP5QT9JsuK&Z}ywW-*GiV9XyOf~=cHPfJ=Yhwy(v{Lr5kVYDxJw9JmQb!$) zEo&`x6zW?n4Rt*fqy-(6W`KU*x|m|Co|hL@vz6VM(D2ZZ9uTXH#%Am&qndGTy{^+_ z3yqXn8!;YeqDG-J`ll$Qs}jCDP(xSY+aoGyY*|Iy0+I?S`hu18;YepA*! z;yN`YSaeuQ6ELpmo_z`BMMt3W*$1$zc*YjFVo*`_42oQ^wN}wQ3%1DX3@{MB)kPLn z+<$n_55npu^x?BpC>9mb1QoJBUhR~zoD-EZSJ4MiHJo{dM)CBJ zX`pzdF^Z?aoO&~gCzZSIE_io^hEP#gi&npm@f? zR0YF%2Y>~NXB^BZo>aaDlFMe4uZ^5*t>RhDFrs+U+zAxVY9yRQfkGEmJgbor#gppx zNOCz<-F6kvIG(h;gF!?EIZ!;Skrf3ws(4l-;}p**$||01ka~gQxg;{bAU+$8tU44= z+5dI;EVRbB_XK__`+pDNFYN!F@s2Zf+B?dh7Wg~N*4<)%27lq;i7cHU*k;?3I*!vT zq6beX2>W*l;{II)MfdM22&YeEE2mEomw5UF3CuoT(riT|1iXVgpSaI=2RoVU^A&f2 z&`ilY($L3hX~bth8fvUcGb>NbXRkbwhL*mi5ml5lB3~sRvE3yfQ6}Yk4u@$(c#>vL zc=EIjdM5RI#0VD}+SxWAYJIY=InDkm`DEmYWy{JF%SN5d(un9{KB9XGO`E0hEKPfu zrh~6ZBeF$kdMr(^rJ?>~^T`{Uf~50%M3s>`5IG>;bNd1Bdi z1WryO!>}z22>$?}6m_ZN)raex4N2KTHgE(2QU!o_6o^(JN;x?b3qX!$ z$dJ}3m@9-?2HLeLJC1ZB%t9fZUFV>*tv=4_0;~ftg!)<2w55t2z%71uDX^W&a<;03 z%CaS3*(=55w@?tEh`m)j{p>a1w@Ud@NK_$^E9Pw}VnO(6Y@SB?g6A@XP*I}Gfs^Lr zv>a_(+J5CuaT1SG?t=TXbCtP&ZLeXeSTnetZb=^M?@+ z3)=#3QHBB_!(JhreoF?)WlipvNl$i*WBHA={Fvj}v;ECRLq za5nVpMth0g2?Hhf~KoMh`(of z9#p{Y0AMSC`p~&qm_&yF2>I*}<4^0em-v^4{UmnUGzO;VzzzGUVL#CpqB@{<8fSX7 zZ#fRt#^->0;q0fa?+)8fRc27geyXy9!uHdMYg~oxCs|PlSwD{bq^AwkHlc8_D5tZq z-#p%mqUAG>6=lqxomB(~KyVE3f5BFo7I%D!~LIio6DtR~8*3 zCP&AdYDq?s*O2n^0+iK`W6i1dcwUYq z<57+|wJsS&UOTj0;{nR4FUOqP9M8)!r{awu$DE2cf(T-%_G+o9d_{VM=o*eWMZGK@ zL{5P@wZ9q^HKz^)09yfdnNzxNL+q)eFT(7K4V~%mdej_V%6e1=udyE0#2*YHudyDb zYi0W(WyA)fQl`2$l`hr2DX3KUK8z=;dmrIz>g!axl!l5`V?D~$0R@BB8wbCww-LT( zy-{iTsaTK7oQHPDPL~?%QnPP`UB#PJCS`3(Ef>778^?Jl*kM!%qUjIuM@$<4?BVtV z%qc){2Cya&6_80-5LJNS3}7S-ct!z&Gl0lW*(QiQltFL`(50v_ldNI{YB03N!k8At z2-IM9IG9$&2-IL`jfMHNDMp~c1W7ooQ?PFjp%}1GB(73E5ex-D7*kM;Kn)*?hA^gIF#l7nUgXwlKqlyuz!O)@#mwBUN1Zpq^2Q#4iI8GL`0^)+GaS}h5K@jShX`Oa3`lDs1*aS)yp7I)$|y#l z2164n%qOQ9ff@|$r!Z!jVgzb1G@im3PcZ@oCP0<%_y|T0HKBtjV234;%em+!DP{Z zVa$+X1Zw!SIGDAH5vaj<4rW9#0yUU+2eUyj0yUUk2Q#i1ff~#z2eVl*0tF`c9BI=5 zK&4G56(dl?XSKs;t6~IdFvAXJhhhY3FzX!5PQ?gRFt&oxUQ9%Lje`bFGL65eezc&e zf-SbT`8GRjcPm?xSj;vDvsWP>b?uLU!6}_Upvc!vl{H z^8=8C4rKvLa(cIs6LukxQ^ZMYo!%WRk_{bdB{13P-Kp%_s@O$Chk5~%fR_$sSIgH35pTONX zy@wSx7zb0Q_c}$ai9?`~P3X`lU{aIATEbdR?~TfGT>{In(|bapqkzuq^xmS_jR|ax z(|emK>4cWFmeYH?vfPru(m1`R0IP%!ZBxGD^sX%4pyO%i&@Sb5tsJ?vR4(+-0F-wou7u6d=?}Is!s1i z#NxUQGNsd-57kcZ!^-ghQS`R+A(VCC^nLei)$o1qasifSjLYS*=KgXb019gm`eo4ooI)su{3 zxds%Kk4G6d_-aM<1t>Gw1u;Ix4L+o(fp}iV4Zc=UtCLYI*NCEq;!!55XoI5GCZot} zTu~$ODB}j-tf&piDDs+A)Ob9~xWTt7YI8D*ymlyRG9G2z;5!wyH5o--(~8;=k1}rX z-HO_oj3TeSikfy&&}6YC)5HQPXm=uroDM2zZ!E~T!5>u6z5rx9mt;o}IUP~Z!D>!{ z8@#N52V((@Dw+cz6jgK-f7+;`xck`%X!yg$-^%y}^|#K-6JzXYk*bfDcBl2xHvHj} zy0MFX>H?-Gt+#%8V!hEM)Ow@+XX|Z{uSqi`>Dept6~IdFrRfWZHf^nFhMcII_GW=aZ_|CMxchz z9*0k-VgxD}`$70xCc?1#HfYd5y@VP*-*fn^Qa%yPBMzpZ7=ao-k2{!t#R$}37NK!$ zu~3jf#R$}3mN=L-iV>*6{IY`?R*XOmX1Rk|rx<}6%w-N{R51cIn3WD@qhbVVFmG@$ z6N(WiFyS_R6QI(jTNEQu;bSWX?Zrg2*G&MUnzj*Y@_M_I*LLL-!F<5MOesd7hR-Gk zvr91oHJFb(m>Iw@ic#x(SSE8wEuzc#)giXb%A! z0erx60clzbDLC^Xo16iaQH($h#=T`Nrx<}6jC;$%GQ|kgU_R&Mzyw8=X5^8T z(t+C*BT&QVZii2|Vgzb1_c@pz#R$}3{-=Y##S(@o{1PxPl5*3 zJwT}8^R&ZfwepEzUW^8`?7(11F#r_9{l8$XYU%&iyF>Yxu*z?C?3LeD;O& z`g;fSpkf4Ss^Xs=%n`*1)L|?Kbdd%!yEo^cm^8&aBih-_`^L> z?dU0r3=3V?3AWNU{NbX|HT>b6Y~nrL4SzTfl&065{?CR#yx|Y0`@P{0Z=6>Y_<|W< zW&Ov`(BP#1I1P1Pea;zqqW?H6PmS}6)Q7$qwPEXRf>pzMo0K{_!_F(JBR+h4S0g@L zjw!NMJ?!{awP9QMW9-~Ue0b%O)IqJE{&4+JT!iazjba39>af+p3@b*U2GizX)+t7y z2Gi|eMinDagXwWF8xT zUV9zPA;k#PVD>qf!-^58VjA(`bk66(72AjpuLz~p+F=I5^+U}iJP?KyBT&=vS{%$; z#R$}3JO?wP7=ap0yMx)F7=ap0uY(y^j6e-$m4n%=7=Z#47D@wvCi=ryJAAe(pGp3h zyoMdj4#f!6VAeU9or)2tU~C0f{NdxEna3Z#*=AgDERUpjFkyM8_Zgk(Y=4;d9`|*0QZ0 zjSoK>Bqzm(KNFK4jt_5Q;ha*r@!?rw=7|q)spbP?Gl$@-NPKuJVDrR>w~=NR`dzD=s@!_iySXRe}7nJ8b@!|am{NnxLgUYk+`0zCe+@1LF;W$_% zK73sq0*zc1A3mxjtRp^rV*<;V`0xop>x~cJlEAhqK75;&w2t`j?FlU7zD0 zyApU-#fQ%*yE^>gvk5F~$A|9+m3Wf*V8WP9(6<~c8N`Pl5THRwd^lejXe2)T5V4F8 z=R;zA_+jCQ_;5ZL#^4u?4}StuEHn4|Z{oy^yDEf-?$}1m_ za^l1Ll2PO}pu7g+QBHjL>HuXXyZHFQ~@|uiCIq~6JlTqZgLwW6pM>+oRoyjQjnpR%Z@hB%ge0MU6y!I-uy)Fux zY*l>tzC;i?9aK&SV?j=Q_=5q+b}q@z@rNI&<`j(&FUJBJ@!{Ky|CmQDsQ;J_Gd+`p zR;v0=xk=gjPN(^rzSBm0c;oy@_Jb+R+}d|`$rINeXu4_Np@C-m&J16ZhOQ;0p#w?# z8_hJOp)nRZzrPND_?BO4#D{y0`0$Ebsh<*m+$-?M*!YXkt*qArevU!K2-IMfIG8nx z5vaj5;=?QTyj|;OTezMZ@!^&Fp@oEgNOLOahmH8~Dt~w*KD^RlR%?eDsC1YKuMr3@VN6*8vbzj-{siwjQZCys7CR>^TGJB#Y=xx!yn%8hnu^t%(3AO ze|W=pTVge*=Fex;_L7S_E?H5&mZ;D!MTIw z@1FgiCrh}74(IF*!u8^8!z}k?#jjVOw+6|o=2{<)oVm9K?=gk+yJ>RZ-moTCT}&g< z6zeo`jZ3Ma6r)Jh`#Fab<0u%_hrHK09Pr8nQA_}VL-q=Fi6+t0x-3f1d0!tG?F(buf=3F@d z&!h;7SuG-06{26PMKl^C{lTT2Ibn~h4d5Aypm3Fl;DkLok5Pu%1nwq+;*i4j$H6p$ z;; zKx93f5WRuCMvTNxMe%gz1eC0YD~hX~F({)Ga>)ugawRkYCF|je;&NyV%EU;>@)mBf zPDaU!xbouZS~0xZg0uY|RMfs?6nPy{)WLX^iIFHP>cM0bc`<|sHE|>!Wnv_bE2^A~ zBCoXe{3imGOyZR*flQ19Z58CmT~0AIK@@rA6qQECF(?xwu}o2!WE6RMips^Kj853D zsAb70^6FNU=b|Dp52lc`(Cx>d4u=bVhTlf`mYFvU=7^rcr zRg<+|*}h%bZRfCxD47XbVW7d)p%o@+an)L3pux?f70xCUFeULH(DZR_UZoWV+FKo3VUh+HuNAhk0P|{v zZ3)G!(h8}nfn6P1A$7I5FP~2v26sHxgGC)4Kz=&2@Ad*@k9}=~~e#4Is zA%0P z=yOD|T!C(w21~YMZQU>vpqv~X-7puAa&*H4eU2!WE6@$ScwUZf*q)3cuRu5Kc2RM< zVZ26Xt{Dt;!+b0!M>p(C1hGtkZa7d4it2`|V*&H&hR*rQH{P&mZZFltak<{`rsDZI zj(!A^;w7#doYp(yXXMm*LLc?LDG#ooh!|7XTI6qq&jvJxjT&y&lZJQGnny8nWPZh5@q* z5S#(z!+`w?5S#%-E;T%$0KpkR!3J{zDtO;jvSOJ1FfXJnWa|#fg0Yok}JgNY} z0T3{kEvpl#VMy%Y{+)5XK~b5gwH7W(69gOT^BJ-ej7`K_Cc?s#0guC42sL~-^eq&5 z(HRSh2!?|`jG-qM7=ao-vksetgX03zS zq8Nb!BjobsqW}gQu(v5jpoY&zhtGD!2-ILGsKVu$Qj9fAUFdU z3ImQPKyU^SxyZ1r0KpkRt*`OGK3dVjAYL|iDpBT!^3nMx(B12B+DTNNWvQ~Ys<&kn^1)L=F{ zn4O9dsKIP=Fw=?=sKIP^FuN5aP{D+&iixE_yEXxXzbs+PfE+-+t@Y z%g>xVd2&m`9-^L$QKtGf<&o8cxA8UgU{Q}6_E2D_P*Z8xL#7TmgthN*pavTT>$Hd7 z`UA0t&WBW+02GwK=Q+!5Kj0Qkyvi2+jZ^m)aavfZzZK$}iHogn^o954o4x zG^zZ2hU_FGTN9{dCSt1LCPq|!mQXFsgy&vr)1rJL7~W=M*?~c;VgzdV>~Sz{iV>*6 z@DiIapAN+c)L`68Z8{YrP=k5I;nS-aff|f^sm&_I2-INQO^XG^2-INQO^f}C5vakq zn-&KZBT!(%ZOXfC>b8e?$qlM|nCwhmEAcK|hwC)22<8nAW>hf(HGJOWU^Xg7payf3 zgPBl_Kn>>Y4rYsD1PY84ReCdbF4nMz+)Hh?E1zxrF?qR{+Ds`%pa%2jPI-1IMxcr* zc)uL3z-bU*hzQOAmWKhm6(BeP*hG*q5%$n!Xr{fy84fEg2r2uNLj(}H$mXB|1ZOxz zF0y%00fIAto5EQfQGnnKAaapSSpkAGfXGEQPbffe00hjX={8}!CE7#oMK)=z@Z)5s z8BKWZMK&452-INQjfy$N2-IMBgH8CWmnlY|g0YEc8YV*M@nRdafk&v}<6dObu6!aG z_ad8a#R$~!`My)09>oaMV0dwjEfxxrSByXn#=XdPc?w-X-#R$|?gLG_OY*WJ?y4}fZhw|AP&dYZ&I~5~PQw@LRV5Su# zP=n$9HMTbJ{ks(-(5k9pV#OYM=l`1D9_pIC0b;79I085IsF(G-N_V1PLb1!8jsGv$ zJdjF{&8EhVuUbF%4=|ukcFt~L_)+tnBdPStW6g!{0Fe(655vrI)}IicG&a`)&Z}_3 zeot{2>qiJ9C|!4QD6{y@2VSKR9#f90sx*?e8z>jeDRD@VMJ=Ian^yAr|g zh#Sg&AdeDcn(r9(+Ch*3hji*cUo`5qZ9%EhD-V32x%tk*qNdH+#rTqyU;E(WWA~(9 zH0-ql(!O%U%YN`d6emp{x1SuzgC^7U6#i;!z9a7;q{B=5yo>_>5rJG4{>9HWM2e=M3;H|c=2jw-^Ao-eWkcy73LE6`&Vk?iMG`gO(S%!_! z1j~@JrexCtTbn#_-Z5WS+u8wh*heOP+S2dFlTGJJgwTsuPi%Evb6k}v;e#O{GfMz5 zf)eXf8T^U$sr~rzkC&hLGD7|)f_Oespq+ahbonE@pE>ED@XLHp@_meN) zw-@PclAiZkgWqMrZ!Y+4X<@z?O6ZC*{`_9A{MK=iPi#WtuQ_MaUbeOkb(HwVM*DM3 z^3=Bfm!j=|b!_|Jnb7`tAGH6~&#V3aaN+GgC4Dw&{LeJTe;wn$gkTU1$MR!ekhtHx zj&P1pGr~VUjg(12`N!Sizk!K3UWFq%?Xd$u5DY9x2w*>OVmR zpl*ToqGnN^`b@E3DFwd3-i z{DHJAn2y)(TOA^}iE1$2?p4*XFcYA*Q z*81D?Xj;Z+(;^w4hu8&d9O4|(WPE0rI_1sLyjA@@jW;qTjsDJ67%J})lGu--*dp3| zBao26ZJdsEVdk*(8mS!JMka>BoTO8cJStD5c|x8T5O+LGLkTK0X*87@HyL>%O;(;F zH(b%6$?-J}npR8GW@$W2(~hU0;dCdc&~#gx9!o=^qTjPBOq1tp=2MV#eowzVv1|kK z#Imi%lg($4uSqi`>7-dJPox=^C(^9LlcgEqYtoELI%z~KNkHkirP&;&nJ_eymPTeB zq1k3>wufnU7@8?dLpxU&9H-@pW!sG>Teca#X4&>iI?J|Cp7=fc<%u*0@KoQ4o-hb6 zq-2=z=5UOOzb|YME<4Wmb ze%g>%4SDrEZ_I+5t zYRD@Zu{gZn=t>R!s_q*eSZ{gsSJ5#Gd=R~~VGllEd(gRns6yt-+j^6K#0>XcUppo2lM9l;O$%ll!OR`jd=cq#s?GC{bVi$7ui zvO2A>VV3)7I|JJYF%SakRd4eu1;NinP@e@woy-cthFOBvSkRDg8dgs06od`41Z}XO zxW#Hh&4yXdfm9ujmkCB z%;KHRXRo0VV^L@hSQ@n(N%LTsModSR?T8>*wz8#BKNo3^hH0K4fHcoonkJDL{GPNt zktTyDTed7;lO`wW%x9TAk)~CiNYjQVOXKl1X*wjGG@bH9nr?X_O%I+dO)p=QMueHv zL7$~jxkehwHA^#KXa)tzeAZZ+A$cOrT0B{rVZLTQBa%*<4f4dYjmi^gHsZB;cTd#1`5Jt z20!K7{!-)-S1WiLu>&suE5#MIwgXzNM14&YNhj-D5|IE7S<$qxSi)bkTJgjGDx3~t zsF$wJP#?l#sOFeRSKb98hzUxBkcWxF!+Mxh|7pk*>EqjFB(hKJkSF$uhCFG=lOLZv zx%kgSo^Z7+PM&;ZTMc>gZcVIDo_zebpMyME1ERX*2?aKQl*<*xgz~)WTRb%lNg}Aj zS_x!z=0)Qowl^c-57L?{35I2`^j%4-UjMG7MfDT%1hc^)U3i9r=_+)?k_IJ(`B6y; zl_gG72_tI8)|o771lZ|nDk9;it)Stlt6&<4TPrW$@)_wLNvq?{YP6FB7*Vm{jFjQ8 z#@m%2ftRv4idchbHSi{6t-PpOh<|+3|9%nv^PhalGx%@Q59Qx~=c_&Cv-Ui479%D# z>HERU()1N6{&#mNd#-2pwqS+os`(}Qqw(XdqE^PkkZ_m86vq&lBhMSwZgp@eee&q-rI5`co_QKr2t(}b*N zre@JJSvCz8%T8tOq#gicQ>cf|V%OO8eRh)6K6V>F{U#Kq4~5yMg`uhmiWU~-6!uaS z11AfyVjen6^OsJlWyqhGF5 z=0MPUEsYExjHIAgF=a}hhvKY8al|H>kY#1m%d#JLz1R*jgtCZLq_Mku4xfeMv}(1q z`p2UKIx0j^?W_d*^&)$;x*~&HrHWQd&}rgo=A)>YwI~fOGjv}uK2&!(X~jhqYd4fT0xaEXAoF zNl9hkNSapTSkDeb`-ttQR_Un}cQr>eq>3I&h|-9GJ|Qs{sE*DTqB;V>QYGB-Z%QLe zk+`@un$0rpiI-qP4B=Ax+j!Ts;s90(pWO6=&{QnFg7c|Pf|!uM?cX1CivXzN<>9k1 zT)?#(pOyMHGUG!ai5^!Z*i?kx!1+z7`$h2PQmCS>S|<7{&{7*%Hz$m05GjzB1Dv!d zP8lTU9#98G)H3mfErKaiTv4#o2NM(3#*p<&)zVt8*as4h&ui$LR&6~+`sTB=DF(cx z=)F&VQmlv?`sN3KfLwkF`XW*2O}%J9bVw?vr&9jZ);Cum|I?~(UWNjkLHg!OG{hO9 zZ(fahIb-zA*P$?HguZz_3UUVNn{PpJ&J=y~CY0sO(Kp|Y(wugEb3F=ihUuHPqDY5T z-k)}T^L8!AY121-=6~ksn;+NWoKgBFPhCJ2HT2CUxGR5_{hJ^DSWW-tB_E$p-+VC; z&^JTwz0;y^_MkV5jh|DkaM$!JihonoDSGnG5Pj2l@=%@vD&+L~ zH$#5B)9c?fPP~e@YCt>9>G5xdym+g%9Lr8|=dI}_qPNQWH?1@8jPP%U{CKC!zZp32 z0(ah-;^K7OdZ$n86vZlV>zzg~XVitaPKVLy^Kwc+#kB74J5#)zJ5}pEuJiN;ikLIg z%P9vSh3{9R6BHt<;qN@v{?2nZ*YtPZ@uB(j&k_*OKSS=m)1rT_Jl*c**hcj&yZj5^y;6+sdt9xpCPZ_Y1cokbMK7MKSO@K)2DxmL+^~!KcjBG)2@Gt zo9{I0pHY|IY1cnLt-9V5s_TtFe>(lE?4SLK)jy><$L0E}N_;0B?6UD>GquwhJ)MGK zoH-4vT*jbDIUl7}qAh=N&pVQcO*vvd{z$`ZXjsHw(&j18d_XkH9RBV=y)YiL1@G?- z;xT#N7()381%kGt8?pIHAfPRXSs8@OIH#;GMzXlhgD@5+`PwwnrQ>TDh#o#`PjL0q zS0G)CAl(JxrsuCnV;d3I>r1)I0i{Cgm%H{Yf5`CI=cnHXNE6##9iDD_{sQu#3o>;K z5UPYOBz*x88D-HIlddeXNGWB%jKa_Wq6@F9eBqQln9`K}^j%=pLRRClM@1mia4L{| zGkrXCZ>1gwnC`BwyY))e3&-Wp2OdFiT1PVy>3jm1s(^6fLzI)A@`(={L{im<-3T6S zg7J@{6&^Q5+2^y0#wD;S6fncF zY6E6&*8Luh@e8Sx5Mzx%?C|(~2FFSv0_OaL@%vY!^Nrs>00QmR7{4L{8soQJCBgF= zzoGqFmHF3h{H$ZgCk!oa55;QZeA_-N$mrgR>b;*8sEp zIBjqrpv0odp0C|}CHqci?+!tq>kE zghwo)1fB|^$OIwe^vxWxf1ERQKrcCR;-vzmTO_oooJhH$wz566k|Rf$5OQ);LYcrM z$5uboIxZfYZSmipe$j*o!A&RFE1GY=Uk`zA#cc0&%@*IEL4o(qUtsRSwZ)SH zbCa%p6BL+?+yV<_rNI9`d+!1sRdt08pEG-A5|RyPfFu(jKp?{%AwZOHlLW(60)c>{ zpmGxtk-Lf%HAoav!3IT(iWL*k+U-9oK@_Shb&b7g;Yv~Mh5 zHvi}5ud(DPh(yZv$#)F@8k@=N?~5$pO!L1ojV%cLZ_Hw~!*FyK>*HseU-c4)VSJ@= z3T80;obr_NYZlb`pPI+&{=YDfVVy7YSn3hyF%y{a_v8118z(RFKI!A{4?F(;F!LgC z`^p_|H_Y~l+l}1VaNRpLT<6*0THd=>z--ExofBoab27Ur*)hq+Z%n+*xTwrz;iL>V zO-4pGOCmEXUPiV~EN5X%hWjNWQz|L$p_azW$gYVpW~yO1oNA1WOfgcq!Ut{=au=TQ<5e}CAod*9)>rZ^7#sW(dRrv<<6eTNQpAItj=kFURvufLC< zA7KQMK~N6Y=A+x0@nxZ;{$DviT8(!GVnjRI`ujT$c;*dcM>#)wha5k({%&+^E4E`h zMmo~T!!I~STF?~6a02+RoFY-t;m07yc8c^%*555)^46a>`Pj~psOWH$f6+NoD_FDr z=dC%mb0jJ{+?xN!Inu9OfAjZQYVU{a!J-_`BW#NBhg@(p#nm|$6`1{bn#UxN91RJy@gDNzA(yYT4;vU5*+2oO6CAg^GkWI!7jxW|C@GesB}JJKQZbnn zW>Y3Z=q!gPKBkY3d=#pdCaDanO!LJldEmowk#^MQgl*gm84kCYDux2 z*lL?HYojt1F`4x-nGG?SjY!38+r(_zRwZcj7C^aTg+or81@LJm3(e>f!w@?JyUdj#?TKKpXe z&<|R=eO{u)i+C5A|76e|5TM@i|5$y&$yA`hu-xAlJeoXsgWcg~_%8=r$mj|ESPxEQ zQpyU__?$-ut*8cf2H4yKWuJC=vBmC1AAFC$S3h-MEK3RUX%T8#7RjWh!x=^esiq@M zN_hg_Bx6T1j*4U)%Dh}BmFXwJoNd%)|41D;U|L4mP%*7H*xYZRuD4Ma`jI*?hstys zROT6#c}GzhvMPs)nKW^z(b@Y)I?MC`=qob%ijJbMx79aJ^nGWmJQQrXd1 zy2hwna}<>wt;!0pEl;`1wo!%An@zpOp)Gd5`l&edYM8m+=v;pko!M6Brl^^ljJlj7 znVDnEtTZYskD@Y%D$D+jvbTWo>G%C*FSh%42X@d=cnzOfd35;{&y;O}f@laV@7NyE zlv~!3v0u#sFdl*~j7%KPI33=_BudVT$PRM8kp)c7kEE}Ez8vpdDod#c@=l{~r|63+ zf&t7x!DZ9yvB&fGr=W5_n59%EqRix)f%}z_1BU59l!=K$m~b00;zuSl`K3IR!$dsO z^pmM7(QqY3xtKVVi@H+CwJDMUBAVoz7GK0zdiR9KQpy&lQCYfSOaBQrYKs`Q$dTB} z76z%Qtzl_vS)#?Y_+okQo?y{1CWkCo1(4-Hm+BVZ*b#quN(d(}8D*oOXj3HDaOEDI zi@FL7SHY3Fu$mNIgACW8qjOQ$D8n`C$Xvaxt}%vd%+a~1YqH^*d}OXnt81#^ntF6D z>Y8V`<{gQPVENwCl%AWd-$UPmN)yu?#T>U_n(- zPyfsbp00;#nE5wZ8+Yjkgo;vp2KqUO-US~_XfY* zkBGk`hg%Zn8^VWv*C>`f4!0>rMdE+LMZQmb=*_qo_mRF_WQjldn=SGP(ot^0#pLBa z95*X+=PmYCq8MH7!^uq*9?=Wk+J|6$fr5ujDdP6Q#=s5ne*K~VLu~+#OF?@kU zmrchnvkr~;%X&v@`tJFb4-~NpjKyy*IhcMun?KDK9FY{aO0A^oaX=EeLsjSVt)1)IN<-I3;|qQpuM=VsM(PzP0sI! z_J(I5bjbTdF3Xa3C+m;Lf$<=g)hss;zd$l%=X!0giM(RYm$|;%htjfaj<~s=Ef<^X zW8dF9-k!D#uY&{eOiUscTJnprM}8kne0%EV(w=-?^GNM^e~X`J&vFotxjiSnf9&nK z7h6a4Px=1JCV2+FwtwycP5LJvqr>{0hq-qB&iggeRe$1%y1mEpL>-w9UBn;xi8}ti zdMR8k1L-m*WFRe<6rYM(DJed!vTq#RkvOF5Oo z$#SYB#d0|!=$_6VIadnHAg{gPri2at-% za0C?@KL<;(?I)k8qu)}<%5pMdGMSQMIT1;*oY)g}l<63i$%)D2#$*`2rapN{#cV5J zHp>|*bk?UxQY>ebq*%@vq+&ATm`$09(*#!uHK!r}@C_je;LG5Z8$P7dZC;AKhNwHXDa3}b z(|Z_Hu%X19!sk&iOD8f(n?^(nqNY$JbX!{Kf+NcLA3V z$JbZJ2mh`06?S7g;MbZ5!m>L%!uNwy@ZDOhZ^-rI?+5>jV;zP95@QE$zwZ0NTekkp zh_#=E{JQT4&!X<19t+Tx1#)V>=J0lsV_(c|kdLo91ki#uG16so@Im=ipDax1=N_!3_ zM_pVy$YxPwHpXPkITvLrkrykciVT#I!!41ij>&A56lJ!@%g9j|Wp)Xj=N~mO8FS7> znZ5Bc`^i8VIoy(R987hlK7L72CK0KaZJODXNfA2BNtYDYkQtJqOeRt>nFzBf(^2S@ z$(9slawJ6=o^!=ydNZ3cviK6)2E}BC#$&pjqsVvKhlzWd14LFM{-5&nP@|5A;qg|(z%^T{U z@;nB(%RYqcDyZmEIR$*9qI}*XI?a1@)F}UyvXtSMeY~iO#c(9EFQ|J8&{@2vHwqXR z=~#2{haY}e^bGWI5Y4`39v&&<59Kb5%G5H=I2NWej)f`ZSeX8fTK|+y zd|xtL1fOKXA33Oe?&7N6&+vZtHKq5le(v@kc3!iD({fqxnkAf+%kXZ2B?~2yc+C<{ z$z=odHA^@hmkkJAvt+3xQa=0RHA}`Z2{F$9BF5>zYyiYK`->Q7ei54`iIm;b(OTCm zNg;w{y5yoj4niWyF-RmMl0boNC6Thbt4MMcMM+0;A?cR{%1o35Ox2QrWJnSzyASZ? zkxO=2Nv_z$S}xe6Os?0YOs>_$+5?hE+5IFWmoMI%?V?P`fE#?^*nNQ*!=)pQsTOt^ z!*!#m*zvcS<5<_XT3i1|mpqlw3$|k_4(zDG5}gN)o6BZ^f1kNZH**Bv%tb za*gCda;+pF$tAIrSs@8Xu9rm0?tgtp2e2Daa;fA(a+xF`SuP2bxl$64WVd9QPf&8; zbchX{MW+p%$LbB7&vFJXl!}#D*6W0I6j{dz>o{Q@FRYWvI&dmgP7}V~B%MQv_I zZL%Jd@-vlPDxZPc+CR6x+p1o}WL2+8z54D*cXTj>amMF&RlVfop2@wE-G+GGeOpJ> z%c$!({)m&Dd@`6FCt#C_juT7+nY@F+o8Y>G8&W8-g)_Ke=VZsJ<3Y%Al6WCUa>JPD40PQ4hTSm9YlC?R90HS{}9eLmdQ0Hj1?0Z9!Ty0ylqq`Gai zF)1}5B54g#VsGs@;aD}rl5|@%EODGhR;4woF}2X#CSp_og^5f?I9eI8v1zR#j?*m0 zDzxU}5ImBR*$FbVmUd+dtwkVK0mo@+>492$mZghnky^TuZUrh83bl2PQ6->FGGeB! zC5!jlfgIy)-^uN(<88^2I(CRRu)f>C%?q;X9czvBAxKWBRqKP(JK1tk3aOprAgI~N z2($(;rc15vTFqVKG=sTYQ@2Y)QpY5pA@0cuI9){RiE$M1|4H!~j?=x?HG@Tiu{_u6 zhfio~4{JFgOzjy5LG4xRKvH|hK~VeDmQZW|$#ME2(ibAu$JCJ5$yUc0lP{Hls(v}P zR;REM?0cxM)T$sp!*Tj2gXTB`DCjr?V~vIYskLEHt(_U@ZiC}&Kv_d5%luOhvpb)+y3rzMmqGVRIa2+BCl$e3A(>sqslW7!hULJ(D>Y7Jz`qb)@E z^wsQ~r`6I;#_6>jY{W6Ou&-u@v$&(r;qnRNl-q1F#>%@IAlX@RIW zjt5ko!;W)>x~dn`>&}Ff%EzZqElfd%T9gM)brAInKx<-U6F^_W+kJ5HCv2T9mocZ} z;s*7}qy;MGg4Z87f5tq=pBT97d}Jmjq)osu`Ok|mJm#)ILBY%LAX>umKO^b)2M+c} z&Lt=);o94flki)7Y{P%z41Bmw9e@uFY`x21sdLENE4?;4B+JoDhBiW0yWUww7CW?l^WVoD3zxFp9 z0^%Sjs`I*tY-^3dyvuC#<>Zkg9A{;+=XS*+Pv4w~oRCW?UzVdEMhhgTx^D^e>jg!C zX%;5x^nAdug<5wz1u)&hkp8SCU?U4t^i%Z#8(WyJQ-%XJu`om5PgNNfX6nKYfXyt7 z=;<`0xrJ@@gK%DQriC4KH@GUfrOVd_`LeS0Ta5uD?!^LgbRO&2+SVvne}%S8Zf{|4 z-F+%xNB3T-V4m(b0WjO8gMC>Adh9&FE-stNmo-2?i*Y}>tIHP;`LYJ;D-rR@C%MZ6 z4$`Apg}&}4VIHavjshIyG6sBEqx79801mcrj8>xohgdjHClQ`%;dou2aHu;Lru(uc z>!ecvhgqAa>Kdp_E^@Dva;H0WCuIO{s5fT-+AsMry1^UR1zC?9k2v0V`fHPMh~Mi? zcU77ePIQv|Js^N;9bqUX#8>S;>SPKrwza;DPfu#M`{!o$%0lKf+l4h_dg@R@#) z>cx_Mz0qRuM`H}j>fCIOAQgyN4EvKgg8T~+>QfE|3#Gn8ck!!4@CVd2>CmE1MU*9| z`55C8)$>T#Q90MP{bR}*1b1ND1w zHdJ%)nWCQV4&&ALi2XG6CO*UJA@HQD&(N}sRKG08X{^3(h2@KC)6sD<)Hi21PE++9 zWSgmTp|iPq2UW>b&CuR0)Vt?k6{0?bo-FkkI3r4-7OhkmpRLsljD~I0joq-aP>Ed~ zr=5Dgz;W8E#b-NC2X#3DzoXg%&J)zd(AG)44$C{M9q7c_>hWAG0n{U?bysyg2Apnc zNuuNAs7du4=R`FPvL~t5(9>NN&T^bwHTg_T*D3{{Jyp^`OwOtUH1}3%gD@4VnJE2a zwF~2CU)3C+m5ypY1}}|r)K!rFtD_d7t)4+!l)^xN=;SSkAvOPWHq;!1xvLgTVnZb( zHk7J6lnr$fJ_D*DToP2@p~EMrFT!l7Ohi*1b=6ol)P6K_vYLZt*Qz($#F3-$*r=hMI$! zq=_nkB^m0$R5sL8aCS3wJu1~)JqGhL)n9jmJC_ZWcp)1q;<2Fy zKtne*0b!V43UN!jv?LK{_MMtfL$$xXyf{^2Eaa3g^$9c(7x1pSu9ks8(ab9uM#jv~DQP-X1 zIIlYDt5Y54HAiK)ah%s3m7n4`TOE~v3clf}87S{fN3B8#ZFAILfVMlTN3r9)<)|VQ z`?jM-qf+lU>K3&94oAHMcfRYW8eHCU)bLi0^LIz3W;)JJM>R&V?>p*abo>t-)dnv4 z&{1V*>s^kThvDZVM_mn1eC()hsPrd}`Vv82pXT8)oPRm$raX+Ijyi3E6G{^a^tFA*AxW-jCqGHQj^>Px9u|R9!IM=%BaX936uDS*Npxjk=BSKcV zs#%WXT<5CSAYM}9SI>@y6}YA&q_4zvEXJ(GxVq@xrMQMpgeACsj>50T6^?M0;QD%Z z7=!CsaAg^;-Fw0uTzjI6U4!dm==95QeI0IDj_YKMh}Yt}4dL@UT;~mgQMevJ{H?%s z2%_XVVz}daTt9$!R^s|lXUDk#*BjCBH{zO;;5fg>wGCo(6|OE?yJU@Dbq3!eTrYy2 zD{)tbBLhhIx^y$4RX3fFhKq8_*=o`!nh`WDJxifb9{DZ}+bc=xxsE{&ibxDG;N zEyJ}nytf?J`ZG}vTsQVcJ#f7p*K%Bci|YzpC!qzd!}VG8mg{jH96&vAor~)YxSoyc zjksQca(<6%bsf|L*EMLzn{e$32j7hA#I}xe3$N2rzeV5aW4H6P%o#0j%xy9q!iaYbjYi4 zO*@bNfxdC{Pe5JSpZ*D`*Wm9mTt~E^e*)?U#PT(`{<%H<6Hrso2bbge6aw*DTsJ}A z?{IB0gZ>F9jks8W>wt^spMc7OpRUJs0orpVu1`SU4Y&@0-)_V;G?@MgsNJpTpMZ+M zzc=CfY>55|sDXAQ0`{El-wuFc`+ zJ8<0s`|iYbEaGh~t{dR*yKtRzf#duU*C#QD-i>RcWXD;DYdc);!F5m2aqh*nGyHTP zuD1vemg^u$eu1f=svmRF;%6|ygtC0UNu1zuM{0Y}IjASJ{ z1F8ysUW99)9oh%itLLD7aJ>m5aw)DCVT8R3*E7*>SL6B=+F=Q2S{27rXv?n41&PN>`}*=+lmR{ajAml^1g2KDz)JY7TtnSJNYyxSjAc zbXxO2hn?j zPIx04-yiyi`yP2OMI>PwLmarOGxYk@)9|TZosN+#plqwg^Bu&x_~Jn z=*!ZM-|t@m_oa)%RIw)ce#BaO=w4q9ls7tmvJ+Y#)17h_q#upxJ{gq=ZH(!Da|qy5 zB1hc``(V-cP$KJppM1JbI@O0NeYb&-+#Mm27kWu;fyW!onm5-8ZBq%Z)T7a4!gno9 z)caV=_k`1z71Ecs2K>7+l}^#uq5p+;T9~e%M5Be?w=hHBj&=)uY+UxrHmILj*&KZ@f+}>-Qgg8d;U=fC`yOs!)H3{7y3>yC;15k+V+t4hY+ZyHgzSEo;!8)vJfaQSSh03P$WsTD-=+wIYlZ1J^p3_nwd!;XHs$PL{7F0URmo;5aV2sxF8<)@0 z<4zQ4DmYK~!ypOjM3J4Z3wy<=Dr=RiuV(NYcc`q@uFhcFNAVh02hNYfYhB%bavWag z>h3TC{BxjQWmUMkXh0l&y{jwG_hR}sxVk^aO5pjzztPo;jPaKX-sI}ZwbrYwDp#Lh zB>Zd;m9^Q`L$GFnJS(fRs$D%jo`0+BB+!Lydg&p`94yi47AN^XhG@cR$QcmLg%o=i z^K8FL@{^e4=k2S6ZunsRVj9>Dll+URhnlaA($F6nm!W$8uVF-!-weStqC#PRQVRrW z8Ms0jl4g*uZU)%WhM`|yJQc9Lg^8xib+J(Ee{r1YWnoB9m)<( zh0859SN{=1bm)3NR~Npl-kSGHLaQt_Prrz1A#{_41^W9i;2J+SqrR*``a2F2f3(!0 zx-%pCZVQX_W9I?hYvCw8l^yy%3&-ef?6MD7I8J{v3-D13$LqH-eS{wKb1>&w(7I`W zk6SoZf6dUg7;7c3H<*xn!tGduvmVc$ItBZkE zpj7zLQ`^zjV1WHvdTKNFv;>RMQ!k~56D>whz0U_+$71xZV z53DUlPdx$ag-~6K(NnKJ9XQ2e^i&ykngq6qJ(aG$wg>1<1HTn}(Q{KUPluXuZ3KIF zxq2H`GNI-HIX%j%!N|fns8ax=BNnZWqbxq)>fKF& zCt7^a)&Hjc838st+QX+?vGp#t^irR`uO9G{z@Npwr9OQ<%PS9T5xmT&=QFxjS^jdL z{!23OA1q$!(~lGaud#TQPY2jJ?y-2aPoKxYTOW8!>a)hDQ|Paa7O(Z`nQV_rYu`Gb zE*J*(+{$}UJLLPPi1ZL=_f}3 zzh&u_KHVLJ&`yi1e0o_c;7=^x4Exz%Yi#*jeEJ>^6#Fc$hCi^v3LUU`t53hcdGrU1 zw?p4J;9$_i;|`ymJP|l0X#Bqu^+Q91npnKcr_ag zy*|BwYpw29|9+odIRW@|ix2p8dIR9If~R8mQCSClx)IBtZ0RLRKh3dhR?x&(snXAL zPF-s0OO>91^y*BP@%*NxZ&rFsF7Ue+Z&A7d+h>=>)k?oP5BO7yw!O4o;@LQO2LQTp>Kz%4D_qx6@I z*LD`~Ra$d=$+mdE(%pT)y%G+HKMugYM!@|o{h-p9a=aUDafx5ggXcrzEH3rys`kK> zEne!^f0zwC-Qs0_?J=I_SX}Pc=P`cfCz$bNrC;AN1o&!8U**>uMgd=E@oK-0qypb$ z@fyEAGZT27#cTb#Ax5Im!xpde>$e$?f3dj2uV3l|{7l04Qor?n{T$otMT<9}eD?R( z5==a8^y@b|1HWzMH~IB8#?Si}SNioOjJFz#tNc2d?e|4Omn_D^X1}h(@&9W}-{RMg zGQRzZW_+sl>)l+qB`2Ep-0IgQ{eT--yxp(ov%ZZi-r?7~I6h=rywk6*<#^D>;$42d zg!SuUagAT^WP9|mc#mH{R0Ld*_#3fruU~(}@n>kF@&A6m4sd)QZTS!Q_09DEIExSB zX4k2}lPoR?=o4oGPqVl*py!PTo^A2cfNns2^DSN$(8Y}RD=aP#=nD3a8!TQK(3jKR zTP!U*^a{qiTgSG4pwXl`Q!u~RG4^Z+o;}M6d6vE-pwHuY zm}c?LfUe&ixT(dv0=m)Jz!8gU0=h5j+ri>J0X>ZI*VW>^0ewB!BRy<+`vW?G<4wM$ z9|-8?jE}(<9}MURlYomXE(z)frU8$$xHPE4ZGb0Pyfmoc4#bDW%Yyph0^m6omk0Hg z*}#`tyfUb7zXAYj{)}Wrq@#F)`zdfi=QNX(`-Wk-}`U3B@`fGx^1tImd&+)oNlAH)- zl_coqY`?Zia>kQYnxJpxc+xpZ&T+DqCg^Wl0H2g3Co@^g5_CH48Im+t$}dmQ4{>}O zWy@cgp!;zAJ=@|{3HoK0KPAb;^Xdd$)Ean(#cL9DU#>qcws>uVZo~RtZspe{n4RBZ ziz^baBMZ@@@z|_1c6%b3Dj#`FagmTpPt<;Z|7J|h*y&M0qDqx=yW9QUp*vSb}cVysk58P@DJ)FdjXCh_e zp^@^`A(8T2EK+25{Zf+IU2D_YuiMrRnbv+owED7A%(>)8Nu#6|>AFi}RO+7=W|(8j z?`#}pnivdP4@6+-qF5b&=_E+q%s!dqzf+{1 zj7iZswE|9XIYw6X=nKO83O-Hyd`W(Z0Wl_Kktv|wNQ7Le+SDEk3h(btq2LKR1by9W zkC;?XlEBAbKE;YuJ!MdVX_%fMNqhEnf>fibSXQ&J4|hfCt5^154)(J9BmdPzEElNq zmQ0}6+6nS|d1y@aI+qd{>%DIhfVLW>y~(Ely!X1x57t-2#i^=(6SWriAHjGuf49fO4(9Vy# z3N6Pg9RT#PLAed)PMGYd-MK>R-C*wAa~<`mL8H96nCR4J22J-q#XO<*5UH$E*LxRh z3iY{xtK9|@&!6Y0e;ByIZ7>H~zc6Tv>pexo_Zqm%_1a?jr1lwj(DmxV@#>!juJkpy zl*e7O`qsd$%HyV49W-!{^0?+#-x*ly_ZnbIQ9sO=+G9tlf`Hn+TrhT&lP&;G zw-`IDUi3~RO2-QNJmBmoJ)r-J&{AF9l}0|O-=|AXc3%{X73d|ozGr20}RnIQJkXpVFXiWxJ5>Ps$NZero~%RbrmCOti{_?^|i#~EZ&i- zo3Q?8x$H+OYiFwdH=FMq_cYPBD^;IJ`zN{_<`B(kI;|LqN$wJ%FHO^numV++Enb$U z%W41l?!!VaPt!do15dMfWtzT~qvi$fHleRd(@&8;-A(9*OV;W%U404?Gu#sduSwGh zGl6HiqXe%_({t#*+3qaC>(cb;93tjeT#=^x($IPC5}~h8)0Y!pZ0Q@)^k2>ezQp2< zY1%&=_)_;y;op>|H=G8%z~ysODyuS0e~ul$`i;d^Y5FY2$7SwELf@RGpJn_mauagM zza>pS%Fc16i>Ii8tJCxt`mfaejo__mx@Z{i)$SdFx2Ne92>}Cj}o&)1$E?Q-5*m(9EpTuzr6w5|wT%!Ary1C1aI4Q1G&_-ZTsNS$C@7 z^02-h)3@5}as*XbE5kaE{o@6TSB3Q-Ioxiscy(CcgSCWu-7OXQHDUb>{qdH?Yr}dA z@h2`P9Gv)t^~y9PYGfI#vTDM*DFyes_lW$Sus#`!IJM7xR`A}iJ}CtJmHV0C{b8NU zKs(?ju$yHa27>S*Ba+{*+nOV>AX{82trpYnA58)CoD*t;@a-^uYO zVDYMSJ(4(R@#=Ivq&{$h#cR^_hIHUWi`S;>uTBH5WAVCleQyikB#SH3^$CopWS@=S zbbb9rz}n&s>G~da)Ve+s{~Ocwd8}_ei#Mg~w@CLau1wcAk{+_SDqWw={#xJS&FT7O z?7&n5i?^if7t?^#e2c{&)u<2c4O?8^NZ%0#ZtT0>&>QK87#~f1n+2CN*84eEWcfZ9 zT-sRAWum<=%walfX=D8W+v5bE84s5=)+HwccZ%W+ozC{?62;AQ6ZY4xQJkrl6ajbh znelj8OI;@wILG2uEpv@)28BLHJbUhK!!h!p1?>EHEC6Ahd%8jCuksmcG8EIoGS3#yATZ^X1NZ^`u z5E8N)3|Q8QWR;H#nX>#-kq&(<4w%d2K1otIVLM#U`CYUq^XVj1A!ltg*M)DGVN8$) ziM2|!1TrUZeb2dHv?MtRT*GrN7wpQXXL1=qf)ktsF5DTBf_;YGI*N@&9xUJ_TkC|M zawUbuJJX|DOxX%rICaLgS*)Sa0^~*z#25~%sBEkG0oLVUGEKv&G|n&dchn^tMIYzZ z!x>_#%(0GD`mXSE?md!$QLS}BZ|n{x7oVm`m6UDf;m8efcb4SuCTtw2jIwyc&J-F4 zxmp@TE|zT0#kJYe&sbrhabAw2S-bBM8s}s~i}^HFLXaQO@T_pTm|0V6Kdjx{fF}7r z6OI$eAs?qO6|*~9|8B^Y9V^KaGCx3ekqjVpk=59pMmhPY6}||0V4H>wOm z8yOBMo*Yr1777Cw6LCSz$pI>6AlLM0E^ds1+QO_2zZC^s?Zh!y+Ji#l$|p`aX|*AY zV*VyvTo0Mkffxg80a`*okecFOnt}rsGvYKJI`BqoMv2DmC1jP4!=ir%&0yFYTgZa) zOg|U|Ad>(W6;djOXl^*}jN)Xd<_hER-d#J2SrmpYrVI5ud=~OHzVI0H4pfy*32}G;AO20e!0i_+m(BjR@G0k_{t=E|Ec_D=8LbRT^rmwRZf#J=2~sSzO-o4COGY&dQrnHd z!Lr8(22D_>fI6^G^1z9Y=%jWuv_y{&PZIWczn1gwYx#NUV!E08r0jHJp#x!VxALZWm9`jM!lP@K~q(@sePZs#?X5X{U9}u zNxH6o3!r?X!ta$KXj1!C2`$kZm;iK&aisPhnG00#qR>*j9j$@-lg5Xjyr;3HP90$2 zO4nP$3Jo-Hwd=h<2XK&qYhAC?EWp7AR=D2isenV?hGLbq!Sx=>13Z-$sjMBY_wPo4 zLk-;NdY4Q9Ec{fMaXR%V%@}6jGM_h?s)if5!RNg{53tBUoIib*2snaA!PsUhuRF%s z)R9K>D&^(ilqPl5HYsBZBaAyfMch;=_pH%|?aa z2)6q^r}G-?+f&h@M{LO^*$zg-Jp)%wk|+#n0tEJ-Vc3%-ZZov?+N%iyv?9o zk55O3w;R;k<3kzYw+zbj_yA$}ZG#FtKF}6^$DlzTA7=~iFlea9huOmK8dT)*QMmAX z295Igpj`Ox295Ff7)p4jLE{?Cn&^agaai?bjrTgxEuR?DeD9%&Ks5#}^!OxmcsCIr zR`hP9KR-1P=e%R#yzplRE_FR86L61#=%ia{+~?-Tce(4$BK04Jy2|w)z^PXhqR*Z` z4e$#?UE_LtMg#6O5M6i{;v&4yz;&+Il~(=JK=kNUG}*%St~a0`;FpGq4$kMg!}|@~ z=z8bUxnCK$$@OkU;D*1x_jFdU()H5N0mJ`VFR;q>KEYN!e89lXuJsh=kS??VPoMQ22 zPxr={9ZqwNX{9OpIo2|4@zNCiv;t1Icv*_>J{!1^J3z`SPtonzXBxZDi9M@R^b6>) z;U=<}!!c8ezA7I$!+lfe6)E}*OvB-(E}th+SsPPyKBm)fGkXlRGe!5pO{N&$m7;4f zQihwmoZ)dym7<44fHN)LlcMKf6b`qrcyEf{#P)CLa%@pq`%`pIHgJ~32U2u8dVM(J z2FH+oFh!4mA>mf87F?357t91U-!R7#w8;*F{DC6Mrm*1k=ty1YB+Cs|yXs*BTsySo_nQ2(k_{SwCPaIVFh zQ}s%We&HT27l1f+P1TzjFFmb%b*i3&xhdSsVjP1n;7HNiVjP2W1rqLKF^<94)CWG< zVjP2WehT-s7{}oJL8ow@#Wk>x(VlPdo>cwZIN*M+ncw!N>K-Y;r&v0U%{B1=i*an; zh{Mc4i*anurxwD4EG|!LGf{;j=s7hy-{NE&c5>^=8byrn?T zX#jk$#nlD+`R2g)yL@_4Wo<3czv1Y&-uFT+&~sbE^Ean4ws=~#C6*F)KxHd?%KfKJN={)@$%2I`(?0Y7GO zBT`=VVELLs_-T372kJ9eYuZ!gn$^hm z!TMvi=d%{?94uc`2tQ~2T{Bn@xB&F$E#5O&pFSOUv+H1z!eerS94TPRkD-+u0UV4ctfFl%_97o z#TyIdYZl?xE#6e9FJOFZwYaiSucf`)EUqfl&(MF{qw!FvFXrg^fu(OL)By}5;SVjY zF4PZl^xWlgD-Zt_>OGBtKeF^)g}N>mSszHB2|-=>NIJtB2_hIl%w0c+D`~uRicTi`Nd*J30IP)8ci*^lpx>Us_x-OsfvS z`z>BSOsA9oD~mS_(~r~x{@UV=!}M1Zfd6IjreXU08NdfDt{kSH$Fe5;t;JQtbQ+h9 z2QA(_Ouio#{?6hp(AN$0?`=F)57Rea2>e4d-iGP-sn7B8c^%wz9;V9?sA1RQ4~FS$ z82>(tcMa2fID0FLKOUyXvOoIeYo1tb4buhezX6N)4AY-eU(n*c!}L3CffFp=KTPM- z{zQup4ATv1Zyk#d4%2tCyd;ZDhUq`N}M2 z_u=}_+}EYp@~emIAM$}yE#5j@KSzCO7H=P}XL5E9TfAeq9zpqZi+2v!FJ%HZvUt~U zopKIvV~cBs>w)YqO)TCsT))cxkYVxO;kp?HvT#$2_Yc=KTwOG?_`q=eXdmF_79Sk0 zpJ#u_w78^5zuXA8g~g>s`VU;~wzPO@k-mvLk1UIq73o_TKM{+|i!|rqa4R48a9AxB zHJXJ}v~X*SD~jZ6M&UM=zp6;TJ{TU7CB3;PwypPZ9c1lL*4`}bn zmcDF+UP61LxO{|ul$@x~Fl9m^YR@um@4Q+|lWl_RvrcskYMsu6mIA9$$6n@8vo93KlU-ZDZz zhk+wJ%;M@1`hl~7hg-aLg#MoLMHX)#q3EMPSo*S&`VXAGC)(kme57v2>28vxuNf)d3JITY@!FC4>bam#vv}P|`95*@ z0*fm~>eUg@r(3*!q~6K$F0^>VNc{xunPKt9k-9&Jo0%4G8mar80zAv&%8_~&r?=S_ zSB=!yOa`7~@#c~G6(8`$7H=7;tJxfvSX@0)XAT3t)Z(op_1{TfV28i$BlQFhpTDv6 zog?)HrvWdtc-KhXmdn%2EUp=;?>rT_#Ns_8wZ0hmO6%XfBlWuez>6(?|44l=hp$rK zJZbI&BlQ-B=heQIg4Y%6oFMQL-+I9n#rk)RfS3CICU||ZZZZ`3THhYQ8;W&4r{{8u zHx}zhIow@m@up(^KKWN#Tv@D_Gd^y#xT;up4gjyRcyqBXoeg}m#aoK?P)--CEv_!s zA@cvh;;qH{eh$xTEZ$zM_j7udLrw0r^P#q^%4$mYkemOeOEEgO8NE{ z`Ia|N{OpYl-?^>vkZrhK7i6gxu-Y7&~>?=-s;17dGqcqGqP zJiZ7aT+Fu!@H|pZn2P!BaXhQ<@x=jATBgVM284@$3)Og@UhV=!QBDKCY$06CC8;kf z*BrH3&ODFr42W_Tczk6*6b)*?HwHw}P>(MRh@v8o?+XYQ+t&qnd|g14Hpb)I0>Z`S zaCe-?mj#52?YjcJIW39os{%Z}Dj-~J-xT2SE4$(1ZBmC>9$yp?)j7}Odji76{I;Sm zYrefGETnAKwrVE}jF$d_jQ67X(D9 zIOF5{0iqCRe0)7XxH$TD0FQ462p30R4&d?S08wTf>hawG#_d>XxE@~(U~0!V19*Hh zK$Lka?gyj+jxmR7+g-0SA|-qVoyIRGd$+MhXVPo@F0z-#D4u85ID6d&vt~}h9++*9 z=dfH)v5#DA;6c~Big9v@fh9g~BqyNx2A2A~^9KShFmS2QE9dg|H>V-?aQ5Z%{#+k$ zp;>G#^Ltm&?Uxzm)qc676TZU0HGa9>6D~1ut>4S$%(lpEl-K#ayV+B(G_b<&eNERb zHq-QazxNjFTgrQv*tPk+^16Um8C4r`uYr6tO8OI?A|ZuVnf?{`iQAi`@h~(l*L8yI zR^hAJ0h>LFDvxo)%m0NgXiogE<<|n(!!~fX{T(&%M#OvcTshfzyYE)U{|bZJdT+D` zy3WM-An&dq(Deol^&X^~R`S5amsR9F&LQsxLmT5g!(hD8lrXNrg%fZV^?TDB#(PsT zL0e_eWN#ja@|z6jR4*?b=w^eadoR*mw-_|b+eL4!F=(E*YcA032F*9;|92R)&}-iZ zv^$C9nEg_As5?i|GL{dF-e;=tH#Fz4JUPWS->Yh3SB`u#z} zybd?NE&^O{V1>`?HxBS&1K0b!dQAZTWFYR8-B0QU12_7-)-3=Z=_Unj@_DT|ct2`j zrO%sxA>hWrLd8?w59b2@#lX!z&#e#m*m$9C@p&)z0DPRSirx%WY}QRT33aOtP}V?# z&^+d3U;dGGXf9p>!iThIgyF>$LKbW*p$jVLZ+Bc_iLv$zk z50FL)9v}%V8J=fxB9Rx(joP2K0*=EAPe~9tF0A8p=1JOoy3jO~d|Z8%M){JR1U@*) zJmKvNE)pe|>oUnrh|z9FmWd}W(o8&27-Em$(%9u%&1Ab?}SuU84#3Z2! z&VPz3E}Lq(kez{ybl#B--{s>%Dzju72GKSyZ}_S+L2NM}kjQD71gEJXK0{jsTGj+& z60;^oQ%=jPFnp`wmW?lyCfo2Bn@Ks5!Y=UhV|e*|yRl%IJa--uyLYRnFbg2f`%kT^ z;?i%lkbE{~s~H&3z$59$u>-d0tf|pd>+_?jHmxTxNi$ndjHVC|ACG|8<9^qj1p``f z9StM~oKs)YVnE^~NwXj-e_V>Ba+7j0TVd|;UtrFQZil8869CEHb_ptAlh=l$Nhh)t zb(C^z{*!Vev!GqnbjFbTtIdzR)Cp?P4DQ7-HMSYV3$_`=3&!0?aO6 zc1oTT>3cC4c0=Wwn9AL8DtE`J+$|!lM5Rf?Q;?-{s{G8Vyqi|;hsrNwD)+~!+#jcM zf1FB_rb?5d%CD`;smYLpv@b-5ct1=ypP5 zk%Py8F`Bjf0Q(5{bz9bUTh{AwWxXC(mQ71pugA(VDVDW0uBxnSshAWuTIz)AAKo^b*fB!9^^Q{RlaHShTe??tJfLl?U`ilaRx!p53uKkn4TZv z?D-+i9w(;9SF1-EJ?&jS^%yKPcdgtPp{(tF1C<$mn>j8GR5ilk%2l4+s$#Ha_4eFWW>0AUU!?J?^eGLZZSUAZ-; z%|=Q59(LcLD=NClIbAbOb0Ru z+qBftq@Bp^iB|2h!_|t5j-cugai_l(UvTb!&nm`KdMuu7it%KuVLTc0Z9Ewc6HhiR z@nq8yPc|*_WYZE)HZAdF(-KcME%9X1Xak3>%r+Q+k@k=_I0k1io{T0L$bMWGi6>jG z#FI@+JlV9wlTAxJ*|fxyO-nr4w8WE5OFWr0>asFgmyGictIK~7Pyhe69BQ=)2M*Fg z)rZ&Wf3$^Q^LN~gT$<>*ou)=x;?hJeX3T7C(xx|GDldyN%P5oPV%?-9sthxGh{<#! z=iqQhv@iR=p?!FJXyG@IH?PMg8`gq(P&*n>{+O$NfP0QZTY`M(d&!%PXXVcGf zA86A{`^M7rfys3u?93idZPMQ|Jx9{`J(aV$q zR`@$%EA$W>dnx`qp;`j&CYWZy;{Z;FeMKnXSt+0#cq zrBYkK^Gx3f5(^OU3IPfb@F76wxw9R2Gj9k4748i>w`EsC<_WUF_z$?*@_fi~y6{~N z?pN+k|NSZ|lT(B&*kFm7Ahag&n}0-!gJQ(?AY_yHZ89tn$(b=CzE1A+B=KO|DDlP^ z@njGRNc^sUl=wu9I0%GcBz`|JO57DAjs#&0i9cKsB__jP&WWtbI1nb1=(xOxBNlZf z^(0bDK)H%k1 zU!I9pl!a6Y=$OPp=5kxL4TYcpzV&z|a#zO+*(MwQ7N8m1w@D-C0UO)5TeV{Q+X8lj z*qd9DcZAoDB~G9Fq15$!?s^pRH136s;C^yWv^JicP~46@Q&30_5B36^g6hk;f_0L4 zg062}v<(I@gNlKiKGWMlX~gGNqktx<_=T2w=&G?oB2vf~$TNjRq>y@Ew2)Tug_y_8 zW`gMSxn~5__VBrxP`NMzKMsZ5r(?ICKf1U9z!j8|)(?&?tAI;oHF z#+>v9`k6b!=a!(5zu^Srdhn&sjVhiY%wHhSMAi%+Z;BM5uBIUKD3EoMdG2Q>h)$ov z!BBez+ya#|5mnoeJ2R&C3Q@}+pfPH%5Vcc*joK^X?O!Bd35ZVj(~F>XnNOO17S!I1 z|G$Cq*j$K8>@O2l7`S@L$=xnlLR|u|; z<4z}!HxoiAdo2EEBj*m3pVJ4KF9GBXM&f-W@<$_qvhpX$Rrk99*RMc0iMNb$Av*~F zSn}mu44l#!qSKLRg9OUpordwC---X8$O>W)l2eMz8_8IX#Jx!5uSSAptdpzm_b{$c zf*@sF4%r*x%6ONeEMqSc*fr&HU&GrPg-DnK$zO3>Baf!7M=`oJZre4%PmIvi6nsnu z$jLO8#a{UzZZ_7&E2&<$nF)p!={_s`saWNu_pD$bSm}l z2%^+K4+-Z)x{0qH9D{!-dnd{^D#|v8Y~szc!GaD?HXmv)+OCeW-Ap!#kJ(_Obzl>g z2cj(e?jrso#V8U)S51bNUlt%v9{s)^+CRYmXHa-EaQ=z-fP?e%soBG-v(Cx3%n{rQ!0P0ZgSSMBu4LX)tT{H4Fg z+rovA{KKV(2F;_$iw~L?fuljgH5P*=Zqv!2iQ9KFXbuS}eP~F94h^Z4o^g9n--`5} zaobSeiVQB+q5+p#8*uN!r0nsiLmBE&8*twtyEfpOV%Y43`x7P@`w&fzqO*wb3L{G_ z6NnXq;oU$uHAejxU~9bN$5JKiUPIx75I4xX6#g?ooN0r&FA`1xgZMnyHy!|N!cq*1 z#Q78?@Ym;j&O&IAN-$<&qF#Xf^$Vg?g&Csg@VJ|=ba>qTS2#T0OS*u!*q?zq1O!#* ze-DhloBvO_Cgy)^uW#Gy%eV$t_=8#QZTWwdJb(Tpa&`Kzf{uQPWAO`+u&e(@qJ}_U z0rhK&1b)xn^wy71;8*xZfn^J4x8dr7qVa)*ty%mUGC$zdrkV8INRx z?JoS!0j26U|FK6-f~sohKUR+jS!R-je|^GJj8E2s?auc2F*#5sFO05D zOq6_$JhRp^V>@4U{8MpK+neTsv)2R(cdi+(C!83A{KcYP6D0acO~j(47v6vcYYDpo zI(>G-6UcDa!#4ih?l|NwyX;W=s*x9OUoz&lW3#UioV{gM;TxC~8pd>Tq6&PX9 zwLSMSp~iYHznaslwj(iGjo0PH&Z)0s|%4#$V5d%wPWB+!dln;U8phFplG zJP`aPhx+b%0%q{O?_1eb*Y*7vB{iVSLvC-pIp0*u-~Z zqAVAX1%G{}pDR>%4Y&eWEnN=6m=gF#HYC4hmciaNXmp04?;`y3xB4pnGo5*SUaADT z*5m(8==&V{avnrxS9l@kaU=#Hk^ejrTwcE}SKaSjT+al-$>Sqb6n+o?mm;UrBFKG> z%r~gOHx9odOa=9jpn}G7)%_y4ekTg}@YzlXH|l~XCE=}^RKVAQ%m>Ih1&KS5$RCab z6^xau?#FjcYyrW^rhqs2(M17Vd|G8>8PD7Tc%A6~{^pUwzF-d-6GHBaFGG33`=8C~6(J11$#H>*2y zx1}AhS=|{N+Y*>tB(W_)6xuC86v}a06v&pqfZkBsf2R%d$K_$WvB+YO8}u6>3G&O3 z_#OU{{|s!E2)+eag8V@wOpsrP)ZK z!pWG(n-C_2xIxL4Q1nmye}@0D(2@T&GU1MV9{~K2Ur(-x8o6QtpESc3xe7UE0e|d8 zvIxGXu`B+=_*Sme#K`?$zdX;*nRo43 zGw;k=d+oJ*c%+*4!sqL6QuspsO%7kFzf9me1WlYnjhh+7JMmj{PJ9zTN?B|Ze+YI> z95;bCve5~=gTVyewQ4YdcQBa1I~Yvh9SkP$4(bHn0iD1b_yJ0xvHUxm7-W#OPElP@ zw2L$m#01{fwHL$$-cW%c8GsEARmg~IP~Oy~^A;f@H>?Yru4QutK;O%4yy-_-CJ{Y?)~)!*vjOZB%#_!|AK6JD&p z8M$}!+Y5uC5`4XYkozzt6GV6d;ZhMcAlxXzCWHq?cn?9|1eyC8!iyq&hw!Zkza#vD zz)1I6jsMmxp%x;6?I03$!g4cd2!Mzj+?2O_$Q23d3=Jg=u{o7B53 zK00|>S!{FdL!?LiJk$~T5gS4WkG~hmhq5+>Ts5IaO0!sr5e^e5 zQ!(2HeV#3e*}79QT9T;7&vCx@-Sb!i_T@onJ07IEcl zXpD%9_(+OMBkn9H8u2her4i2-SQ_yUx;7f(DIH{O6rKl+$a~gHBfeBLq7g3z@z*Gs z=@(h@{qqR3qWd;U%~;a(5zDg}Y;rl{N`yigS9$t(07za|l9JxnxAhtHKe2Kl# z6~t6!u;oF%M=8^a#`>EaZmz$Uhv8J%nxKS!lH3LJ%(w~RnK?loE<=d?jJC$J0u@5#&z1G{L^}Ot?Gb|5VsTiRPZ=-xRy!Rsy**ztc7n1w}?CqdGR10%8<4QMc zc|o7Dm_wOe*)UuTw(E2+=$VEfyAGtbnbf?M7^Rz##`HFmV`25I3lCA3wzfvQu;;&| z-~M?Av+Z&{f1{#b1a1?74ED~ehRVhFPD{q_NQC-~#o|M(x$ONioXDqleH zjaR#CFdy1SmW#YLdWputB#Yz2*f<w4g)t-M?@z~_P6VaUE+e1o71aAWW> zh0(R&0NZmBeVeANa`U1ll^ZRNq$g5`Dqkw^#(DH4xjmtyyvNz!sfBGR?D#+_o+Nmf zOv!BheS&WqAH`n^meko@?{2)*2oJ#*3!QvlSDV2uEyq2<2tjwH;Fh_(75pF>6 zI*ERW?Qkw+{Hm4OJN^5d{9leK7W79s{T)tUUR|d4Ya)29#J=3mbcX0B zR8lU@L`AqnobG9&%U`x!t@RsK@(WSl%`%D=^$Oi)(WsJ4*0)k-n?<8aay2{s1h-i< zs$`uzIZNBp!PG2mN(c3rtg))*P*tw~85#)kvP(ul;kZh^N7p--WhSM!MkySp6uzg- zC>*C08lLDV92ZZ)!GMB;N+G1Gy{IY_3{3!W)QVd_tCBBoV%WkmpVCG}E(=*op>h{T zAxkN=0^3HF6;HvzfP#Zcp`EG@psG+XG!5isFO{7|q>{fC_ZQHkZ>03DD20epNXvH= zB1)kp*eFEeDL5EVa8N09R@MGg6$*x?f|y~@rTl_Q{w&-dMqghG3k6D{YF9_0 zKq+K`jY2^@1qTBP4l0G7s@jjLLcx%Hn$^qhF$@a*EBP6?znbL+O7D+S=&uy2baNE? zD}`*ZQRp8}!NGungGyn5st%#5P%v~ch{M|>pfH>*0{2Ifk=rN@UE{JaTq(%2_tqVU zD~0x8qcA+4f`b7C2bIEEsydjeLc!2QATN9FK~NZ1$(OHuJ;!n@r7NNo#wmqEPjVE- zDTQ`mqcAR>f`b7C2bIEjRUJfCp(S(u{~s`qdd z<|u_cuu+&3Pr<=}f`dxo5>-8qszSlg0+5&8hCQ`kSjiuV`%hU`Q2JPuLZMPPs=!ew zR0?wIgHb4qr{G{f!9k@^q^k1e6QN+}E|8bqHvtMaR`Pe^ehx#>bCkBf)@9*FrI1CY ztS{WC6wU@4g&X53I2cfHP$}G`s)bY)3Wkb7oO2!tg{5>y+;?PHdWF&_qZF1Zg-$0s z3QLv3NU%{@8c)H&fP#Zc;VxCZnyNy<(1Rc^do){uzr2#4gZpn-UZynnI+umzN+GwG zqp(~li~t*j7+h zSgRDqfsMl2cnS^%6dY6vkE`nSR22$_9tC;XSDy!k^)v+TJ2Eo9N$H8#yDY3%3i+ov z3hR}^Sg=u8A5X!-fP#ZcVS}n(M^&L<=n;^Yy)Xp|n`j8!f5Y+yr7uP)Y*Gqc`Zx-k zl)@OWQP>nu!NGungG%8wRlSy~Lc!2Vke7YQa47Vv?C-?=?Tn1CQ+oG8mxX?nWxg=` zR7b(^t6-zhPd^18OrsrO8Z9R0VO}TErJ%aZnfq0iXRqq^g$r|LL+u4IXExMd5OZcj zQv@+*Hj6iaLNy?I6HB{@Q!1gjWAXtSibO$lji;b=+nCPZtT68%m zAIAoiP4Tcr@zH%nS!{G!9Fp#D+g*Z<(&+9K6m7d_1Vy8hixQ>LC2)KY+Rk{_L`H;Y zbXgR~Mt2&RV7{zQbp0#)A(X4LVT_`<(~T~={@OF^aA0ZC86F9?==#U@Ob4`QI>6zb z*tc$~J+r^|%$3-X=nTCsi0BM`FNo+29egH;wlgEmL7@>0B2{EdCpuFaNwGy|crKXe zZecq^!_PqZ2s-Os6gRjjKDtu}#z%Jtcz>hYiH*|e(guN|(H$!&8l61WS{mIbP^bnQ zer?E>Mt29rvC;h-OmxQ{9JC$EeQ39jDE^~Nbn^$tN4EvMztJ5t1ai@~%NG=lZls`S zbaMqo+wLwj%p%IH zXBu7$w&>1`?U@c}&vZb0rUTkD2Wrp!6dMxVAVrmifrxIfqDF#%dw1 z=;=g#Sd9~eS^CJRgGq98lLN_m6ZJ%`8QdQ%By9D=nDVmEtZXFGaefukx7R66T@uZl zRvk1Vp2SS>pOZL|M>QrU%g*XgDcpmhP%)mT;klzec4M`kU`0p0tYr8D!FnU6;co@& zO?8H=NqxPm&Twmxaaiv;UqIfj>mNzP(+pVC5wz@#yr_bR_d zWs-CH+40G_6#VDO`O7VIC#JmY%$h+9LEzpCm`YOG^tSjGI{BP<67#@+PU6pc#!70J zwqSasIFancw9fOak8PdL1;@0`fuq1Nt#h>CnAYhcIHq+52##r;Y2Yp~t&>=^ZboeD z+$8$?;FPu2TEWekCxQ?AlaeKjCO7Q@}JxcL3!ToDR?cW5Z zVG7v2N$)78QJPKkytNdsq+#s-a@*?IKJDD5gTcAY=oYFc;2+0AQ!HRDUrt>o$DO#| zj$J*0-|t*D7pJQyp{R6-c}ge7wfTk-7`q|)UY_EJ#L@2wWyH`D9dm?@4# zxD%7rCNbqbFX`lpTJ^FU9B5WDu%RHUFVtE3`~YuXwgP@RxoE?cJg6nr2q?`u=Ii4)QXzv5~N-#CKkOn z-QE><1xVi&m*#ufW2)e168#S!_s;OVLi|))>W02ax^t>C&JBHr$=Ezb#nDV8g!%)-l*{%?V%~gAKP8tYfg@ z(*)}t((q(3$+=v{K#~)J-W`{64wT{*Ws=jFK4%jz3$h3J&yyp2$iLJ=qcP=WPtFKh z2m)QN_Pi@8?RIy33)MP5p2W%EKPRDk$h|bnbZVEjV0xq^x`(vv6tOogJ^(>i%z+e4ba(mkZ%p`x#QNW-%Q>mJhZ9fEZaY4{nzx`#CU ziD2DB8ct#dV0%czjRfl+(r}(&-9s843Z`Lt%KVAmQ9z@-#4?-W%J;b8#&R3oLpm7j zA*1czN^TK6o!T$3U@c$n0!)tH6X@;{4DK1!{b^KtO_J?T^^U+|yz74S2=*9m4;ym2 zx<6gO8u{yb|0%}21fSosFiv)>C~+@)4!dWG-z(%s9+uxQe|tsE*f=>U*>+Jfh*zP1 zi`iM2l#5T0`@Eu7z3k%;H7mtf$SdNEIXkqRdn?#Dj$CvQ&z_crS>Cr%fXP1Ba$f^x zPruJ?jP?eN-zl>Z!EkMMa<(zrdo`j*H4Y}p#x^--xU_mPBerRF#!zTGp7Zc*!==^g z#|qmZ4UZPA8>Hb`f^~y5EW2IXAPuh*tiz?@9fEa(G@QyF%7#nB%>?UkX}BAh4PuMr zoa79I-ftXLkD_?j{qf29g|gV>96oJd$&V&{Q$u_S{a@uSVt?v zHwo6!%J5pjI$9ZiPq5DC4gV%sM=Qg1*pu66Ww=)C_>^e-IznG^qF}rO4&3@V2%+A7O?+4tn&LwhVPGH>N2e#}KK`0u;fHPGDT;9>?Uo3++(u$ zZQRI@*+#{GGfAam+}i$_{_Q8g|WDQk_p!WN}Dc^r;u@BJcZfdze*wL&nT?I z5PP?#MqwT9YqJ0OjnezeP?*cS&;~P$<_Yj$rC@XOy=37%40+j)Bp8JZ+%IJu{f*Lu z74ccP?BaL|Pl5MAft`&t#Gg{wfuYFGM9(|AQ-;!z^IaWd-Yw?MW|pSsP0U(iQQ=G* zXANht-o{zOIf8YZH9S!2>p1J`|2)ISS;G@VU&mR)*NDE3vrhktnKsTEULpEA&KiDA zu#U5azXy}lB0`ehT}(m;k<3Hpc;1B%$0v0OWgTK(WwuRl%uB#JTv9g4Nm(&($>XY; zowjtHKee>;C(G{22>ogLN8loooJ9KdwTD)tqrUdg(cJ*1j#H&cA)75A1j;4gau7gJ#l_eN?jD_R4gMeyB1Cl2JH&S~W3)b@GQ9mBx;y>Z)lYkduSDy`B zE&(}ReHQS|ARw+TDwUlWIq)eB=%R`;@v`6Vg_SxfemWMeV5xdF*PYp5?7VuN_<$S? z0;&@YNN#MeOYM0qSS#nedKPx|e87DOA*ZY70pzYy{<5pqG%AG{Y5%n6T|)WLic+yd zf;uUs=hcttU}keLc^V51e@{iNdfDN?%0Mhs`8T)mL(X4Q!949jF1xK9SV;OYIq4aW zPci#sh0UIHoLZ5JiAB%M=yLE7#jk*qie8_wxUAnic|&|xTxPIGm-dox*;EN{;y)cQ z|2ck>Gi5F{t%z28K;V4#|83CD-46N!#Gjt77bkkU{wyzD?(xZPG|EDnML0J<>v<<% z!zJRi70py!NV8|ghqPekVhv##E(-P$!WFpJ5Na$Sgb^-;4?z57Pf0MgOJJJ3o`*0v zS&;MiezE@@F)5ZI}3gf6u`vJ{=EFiyw^cn`sx7OVgo)(}Ped-ba^da9hx2?nj7h za9!r=+i6rb=dYRuU53b-zvg*AQGOY_(EksjD}>V4eMC3;jv%^9cM{#tF1pV^5?zB4 zL{~4x&mppxSb8kw8PaE5boJt=fer@Kz?%Rb$Q=XqVJ^|NbU5>SO{Jj((*3q$ouC;A;@2&ud`SypMJO&iuw*^kW4=I z`sEhAZOabQVm|ROq?`{s@Z{4F%S8!1p4`m4$i)A%70rcY?=vi{#sawrj|4Nh3ZHJj znLYVEZW)#%2tyG!R zwqx#t?JUQ(<^9I?#d^lJ1g331U=C0D$s6{It(y@$w$Ve9GPyqJea~CC5BBvR2-x3? z5Gi)-uYAzh-`hOsDKLL#3-5iSJmdNOV((_ej(v1ST*}^dLJkKr;wz!BVIR>TP9SbAZy>>*3-n(9@pPe+AJrL0h+j z?1wFy?Ppjt1BqnYN4!Cg^0iD&Z5QfBgMAGS@!LT#L8xfkJOG6g_YuueoCnruRv<)1 zxM;5B+$?|DN1SZY>?D#4KH<$Jl+R;!{0~Ia@naqv-bXYuIrFK}9JGpPmbqxY0!cJ= zt64O&h~x>DQy$~(xfPAZ=4Q0Tx?o0}{Zz0yuEXS=+c*(`*}lx*E0m;ovu+0Lwl+8A zb694;yMvxqjLYjjrI+FMmH&IU>+&s$OK>@BI|s11y`Q;%g`%|?u-i?QGx)@(!_9zQ z_9cVkcOj{HBL*HESzwGbFQ+YOrO&Ixs<;bU*^1kY*%#NqxU_fQI zqhfRMIWcqb?E^78FU9x1;aM&g=HjPEtR@1Xp0mnh(v7fkRf-?N!ZsE;b^UPE z%vJGb91P4{<;)nlt4qmc%X=jJ;uL=;CU@@QWdN9cb`vpcn-@E?_OwrNU?(YS;b~fJ z9%-W+Mn=#rqWT*hnEV|m`>@d+Z25a%99AI(f3zDz~7jn zZ_3#A0-ZtLlu`FZ1bJ)6bOia!uGa#!H%JJ{_>Q+#yw8d^Ir6iFyb+&}H`I;1)=m@R zU~%?l(1dJJcpTIvAzKyQ4AO*r{VONNA>e;!2`PL%NXRA;Bq7JY5hUb3 zIe^|p_pR)EyQ}!#d{*>D%M!9HJ|Vl*4GEFn@T-CY-h=_EFf{dTki1#O;Ku?dPjT>+ z_qY(MUqAgV<)gkb_U)YRwVrk+3=Ta=KXl+#^}U7M;J)$$&wE!`@O_p;4|)r(TzRzb zvmAPmoIE&s3$L2d@3R>01-5r&9eR*;TYaIV1NzmG!*$JcH04<@LpOuG)@Sq2Z*CNp z;Qpe6eQzym&L9~=p?N%o=1QUYR!6~bf3Q(#9!tRirO-mx%t2Eq7`hYWwZ4~ses`l# zi2II*`rdP_`8J@?J)S~$rI5wU*s@@FDA*`;kEP&%Qs|*;7NIE=3_S&6sX!TRIq{Uv(W=*@V3Z6$1vX0O#8PrVDUH@OKcOj< z3^in$Y?RJbyFI~P>$e6&=`y2K44oyleD6Zm96%QlN|(h`x=gG72L+>Kxc(=O(q*xf z98gM^>zXcT3ME4$L0)TlW1D|-&{uGOY#ra5%bIxsg`49k+^iISL%}E*K60C*aC0mL z2b98MT~mOjP%tzW

aI24u}g%Iu^t;>zntf|XcCdtC`cnZsvLK2foqhR=0urMy7Ny+fN9jqx1D6NmDv|g(Y`pi)> zd^y-Ct&gSTfKqy1*F1%$P%`ut$SA#_c581JN(~F3^uAF_hmLoQ?{#I(84OC2rS}~r z{lw4vTJv|-cbLFvYw)PgA*7%9c|Vqr1L^IDFfJb?pKxY)>UeY(4!5Y{04jD23ErxB z8Cb^54;AeY#2{%XXNRy|AhVO7jIA&o6k=gb>O02vr#QAhDcg@(uWSwe1T?lk#jHKM|;Q->>B31SETlI-9!QvG!>`i5l##lJ>bWkgvi4F{8qMur+<#v?QuC`jFj z(UTskg3*YDyAz||voO!=|1Qz;&ay~qu!m~H3uq&$vVUS9*#@ExBwM>g0tdQpavjjeyZ;^_q}sjj=}5eVqB-{^8<^)KH0&fHpD(Zmhv^JD`C5s%ApLbdg^b6jqmPJ*}#pzlY8!zAct|FhkWeMdvyA z7BFuEHCMrF2^)d`d}`*G;Ls1u=RQI>Nrbl%E=C}bt)o%eld0FHiS0tDYlmD@`- zvPlr#ERnrqk^O|GMt10rL1g&|{I$*(txs%Y%pkPuSL_OHku_f5;8YWsA6rOn)Qktqd1tJbz1!xSUs!Lh!|Ky=p?G4*Kyo#yyqt=`d-jk z4juC|h)!(lh6tjA8=4LBT5n@+>mOG|N9uuu@n+cf?qtoK%(i6gIZ$twVQl3IQ!ciA6kY)8j<6R-+|f_2{TtiA4*hiIzjlrg;SyxAMIk zSw0Cga{|pfRMVki>Re<)UTiUDe8{%9YbVtA}c}+ihBg7J8WdW z2lWjN`h)sj>*nXs-G^9r-%3}1v=2vftdi-mboU|A?yhG*hPdvYbz48JXj^sA-G`{3 z;B#dTXm=l~YktD89nTIc)7^*b`WHRl>)}=77IBV1g!p)?MzN&FPj}!mmZ7bxRZxqUDg;_H zRIA_s(=xOIgss|44+E`Ps@0IEQpJ{`lR;jO8g)3gM-P%1FH)_QftH~URI3=R69TP^ zRjclSX3J0)kk?~XT^@}JwC1SRy@8e?z7)$oa#=m|Hd{5uQ6`)WaSoHNp7WnGIF(BG z4xQ?I_fxb5qu~S2)WJMlO@EWZb@ewne6;?ihFj`ydiRd{>viwKFQ;K%Nj-F_-%kLhFNg8|+4eJ_ugx ztWj)XyKK`e#>pl9eeZnMwC0$r4ZGr9Zqu~c=C0_bsgn{1gH3an<|WuP9Y~iK2>)88 zkCExJg-rXu>7Mz3BCm48RguNEwfXN3;rX(TW82# z*sD5^baQCtb<8`FwT9a>S#3A|{Bs?i1MXNW5?%kG;QQJ{@ll*x>sXK87Stauc--J9 zo-BAuC$L{tCPgm_{?{OILRA@*eia;nwx6gtn=@sd1CEeFl+fHwOHRpXld#HunOi*NQWRjt{rS@YFYaW&Ga&1(2l zur;gU1DTCmvl?z8Sew=GQ-ZY_4Igv}Sevn{He)}*+Kk;au$h9j8M`Zf3LHt#u)GaZ zN{Q7anXUVGA#a72w-7nI8^fIQ;bV&NZ=w90&+4&~+`*6++i4dbNfTGBk|SfL`n5aS(dQ2o*r)s^Pvj zhc(3kp@&KdiJolKzp&a8WH_3jhhq6S5b!bBu(t6rbdn$%%+M5&*Sgnn@L3Tw7+jti z;d_f%Bj=lByj>B?XNB@f<7A@oF&yQyB9@N>0Uv{HsVey~G*%FN3_T3;TJMs|xl}e}!rxLZn3{C)AgRP7uIOjSNmCjBrc(*UB+d(LpTf+;%=Jw@S zw+;ku4c>>Y*Ln*ROaB#fyAGE}jAg)Q&G+A!+gIYf@$DZfX=vl_GtqvFCiqEFLk&_a>ReeCU^BQNHcj zFnO^~xb)+v$jPBIg1fwwl$!o@~TRp!e?vvk_&rlD?H8cb6o1rkWPbJ2$} ztaH&15SZ_Xk9+Vj!hE#)wp<^sam7#2xShpUq;Ri}es_-QG>SSpW*lv8j&9h)QKkgb z4&_Yo(jUQGlo7|n`IJ8h=t5jI!7USU$3QNuVS*c|xK3kh#4XnvF!_4;GxIkogvqiy+>SX*0IN4U!7YFaMd_ifQ z9~^U5#5&pLoY?f+!DO3$JD6%Nw*@Zs9LT2%&S*khC;0c~;`7U@{#FUt@u_g+)VkA6PR3lr?A~b68F7|>!tog4E&(*TOh49SGvHi zs=fqt2}|v!zSoEI($)o7VTlZGm2in{Gx~haKgk+q54LIw^;eJZT5=kX3g$8~&C(P!R$`h=?8%z+k4g$E zA0sXo9FNP?G=D4ZA{Y2xV@lg|2He78MXbxzIG0t_^cd4n7X z*GTgVa5tajB}$h>U9!SlYFIVYN0VmGM~%Qokja{X56xt41?|!0>FAU2aYUNG1p7a* z^rtk5v*i{RD`I>cp*|js`ZyxqN5fbjjTOA8K4wYkj^)^QqVKh0`GV4O#K#5nD$0Y* zUBDG&hk_yDxWJ?i3C$H8`!DIHSZT__6Nr8bWxD_s0{w$2IWvPBF`yj3iSiV>h+YR#4 zs&YInS2eYF=f&qMFYu^s5>e0>YhI(wQ}NL&&G(I9fLPpnUWo z=Inv2V`(onCm*%!t#`k`kR`&gx@i;;yx|#y07BbKe^LpA}*N1yrF zEB@drR&O3u%oIT?_C~OZw^FfKDxQ&cm8*ESs0r2QUB%B`#RHFb6`!Qy2B~;v+Im;< z4AyGJ86pVPTSO3#Ped!ePsOcLabTK9dnnaIS_Bnah#(bvi69jxAQ;tOsra*09F*49 zRovhzZg&-vGlPmv5WGBTj+*qf^oCR%oTlEUi;Bc|vk2ntaaZYmsf53ptWBB3;hI!C zCvA!N>p)q9megp0kS{`0gb@g)e>nO%qCYCF#OYt+^jACmucP`|==T-<(PS_H9wYgB&` z`b$KAY+9kyf5GYRcKXM+arRfEze@DSrLA-N{aLH_uNFb<|6BC)B%kk~Un2VB(=^r{ zPB)`%pxYZkCNu|~jn+kJehCd%eHs%Q%E$ih28xT)g1cL6-+xhbpwJ=fqO_IRVBar8 z?!`J3yiN61`7qdyy-L{g=cHv00RPO2kSoj`LCKL>!T<`*Pl3YRG(Q9NI@5ix7b~Xi zb`<8uQ<$rJG#Q|k!dyoo>xE%z#pVJ!KwqYe)?-bkOoo0J#7QAT)!K2UK-iAO_2t5L zep&-OE8`F=LvDpK9zY5AmP>`FQQjsMu1GtH3Y{gykSkQ>t5sQZ@i~eI5SV|Z|EU6sAo9y>z+x-_3Q_A;n3nx%Go-}?+79c15ooo3@|iaN+1(ctaCwl9y7NWpJ&+ z7E)7s#`i$;yhKem?cioJhGkZ!o^R9D<5}%BI#o_8tzc)l9ajyx+_NHW5<4)Rv946T zBjwh#Kpe!h_7N)`L;{?Mf)iom#LQB$WvSSzRBY`;zJERl8XKW8#^YcM8XHS#yi!Ud z5QRobDGet=!->#vA~c)`4JSgwiO?{S?%${rJhn4Uo$h<5T*$nUB;DlGf-m*e6_OiH z&B-?Qxe}<{kzOm!^fNUk&ZJ-MNNYre&SNMGxx(DZpyN@^osG~_gsTz8iLeM^wg`73 z+%7^f!qXzGL3l%i=Mc7w@G8OqISB6|9Erf2Vx{F4&SX=9um4S2=O4i#SC9*BFCsM# zLKrH-VF(u^bZ>x=P}D8A8Nb&_0hyrS#O}HJJ1Vz3zbjdh+ZW+=5!hP2&k*>_&Toe8 zAJY7R_7STvJAq$PxOwBo~kP0;>@*%2lVyNF3? zn8|5^GxJMYoS9$Z&HNHI)AcLaTI;9#8JOtK!mV-_MXl7=H_ym9)#M?nW+PKTrha-r zM&H8KKy`yhOZXVJoUm=2?iXP5VwRJk_iog1<9Nf3)8h;`jx&5zoZ+sOWg6Km-7m!G zd=?1TPn0cI?qqD1{uU_~!g{HonX@bJ;&vd}%f9kZY*bD6mr#G=Y!2igSBw#Bf~xW4 zsyZXq1XUfmR_70-zhPkv7W``I;TyrUROZ$E9+b;I>SBZ(gpkw9y^E47De1l(!R3lR zae6X@4ovrFVd|GToM%TToa6`{7*FWHctQt82|bR{hp?~>3w~;P_+zjTdW+xPLg+<= z7M&pEv~s_pWHKe)e?f>Lw5AG#YNm56%}rY@kE63GN~mT$p_=i8YDNiFVt8sw?Mqqw zI_cqKz(S}#zn^0<^ALpOJP0|h+}4ydqojKnA%;*5Ihw0ZlVPgvrObrT8B)n*sCqo1 z>hXlCM+tSu=nGh=f(8HZ^za0*5IT$B*;vf%k8nFe$Z6%yq+~rM-7iCkA(TD=LWyiR zn7V-FdvxxJ5=x9Glo(Ga(Gl{p=ben1-5l9r;!T$N5$^7cn%Nz{8SjqYjCV&jU%IhUKKG1I#;J2o9QZb^{Q;A+aU7Rik2mV|?S4cxZtTM}&ZOP0;V0iAv< z(KU}z(aS#QG-@tL@G~%fCd+0@AC0sW?SDtCxvWyZ;>3^@qxt{1-P5B70g2b1mNx(=qweS;39w;OxjcplAALxWG? zG}a|@0m<+cVAUl64UJ_vM`VIMMg=lOe@!;^X)`D?X0Dv%S5lxq#I$DihXT~G6Vfr4FY zFnnki+DnJ&*WC#>>3NJZ{JoayQ7;l2iGo1E%pKP+x;P4NqG5h?P$e|2Ni zNpWs&jd$Z<;O5qNH@7)AGwjt1w?`jPwD3{33C?5VyF@o9}yP;r6|#+lBFN z9SqzqjCXrO8MlkdxV^E|ZP%`{uUvpzT#jU60&v7ZF4zU}UL6d)E^uDG>{mu(g-_Fr z#X|8lzIQ9+pNyJuA3CBpk7uKFFfbGS?vXuGJ~3G;^7WS)d7bG|3$WAFQmiLzn(S-{* zZEzCvmQ)wBdy9KO*1>@69xrv5iit%#rnl;NHm^m-+F2}E4^Ia}HayOLGl%gz1yAAA zv>++monQILO~}>Czm}5p{LAFO<9#XSmG>Wf<-3OQUV?{ruJ^sASgT*9g1lQDJAy~- zv9JjX!gC;4c=op6Oy0We9p8iGwnrF%5OUhN7gBNwCHbQel6zjjfBv$=M;WiJSgdsm zyij?x!n{h(!sbFA#K3~^O2E4C`jK*J^e^~5z5reyAPhhVIqlqr!i$ppstD;lYXrP% z)rD8B6h8xt|5*$#RKBn3^5x#+8nm;6K|4oZ>uQ~{R*FC7kAn< zfM*c!5Ry(>E9ETo^4oBt_JD9R{=+;!Lw+;m3-dWW;V)-#dm%&yN~g^Q-3sC~O&tO& z#8RPI>YNMCY{kEAQmrY%;U`mV9jklx1Lcn4-!T+*J_(`cQ2s@Bip?oVr&6AK3BqI% z<|Eu8!Yv4|if|9YZV?_qsMCw_`Duj2qT-p-raCAlrUiYkikH)QIHgP2<=o+WC!k%- zy3F1bz6Qt~i13{VqY%#MO(&m(z^*@BsK3eGZj#^JHT-{))%mjpc3Ud{yUWM^f|+0> zgZ*Rfa};zu1!|iR&J^JTgy|xDfv`e^9}(UcApzFEicl4yc^}sW;scwf4l@Z1i!~vQv3Vf;A$=l?ybK;_jfSp{6A04X z-qhdZZXfZRl`45Cv5j^CsJcL%+TVH88DCjGN2$2$MXkR&Gu;jOubcIpH z%&ZAb-rjdHI4OUk{y#_lhtK4{>^XYzn^@Fsarguk1}qM@(=}em)z7_>f~nXoEm=s( zla%D%hVT2A5CnPQ-&qLuPQc4h3mvIys%^wJnNz~BpbI~wqf;`D}Dq$6xrTnMCN%@cH z|9j+r_!j<4_nFVHcAraBp!-bGH9VpqHeUjKfz8M|L2rSM9Zt9T5Meliz9aH*9Bmdy zYm&4-+`mlR#mgYD6_Zy##(^_t z{Ti+n-Bw?rL10zfAdpy;vskz4YAfi>N2#|VhyO{lya5AkmZT9REkq4%mWx3&OH zj>l48v(#BWfSj4fzb{#z$)UV=)JUq$Vs+0Epxo*Fn@CaT0SG-gte{!MrhMr7LCSL% zAbcsp5`<=FBghLshKsNYVUY;WAiOL>2|~g-2=5`BDZ+My2NC2iyIp0=W+9n;X#*W- zl<(E3S;1_^kC=DN%;RA_?|LkjSj^!|z|!%~wcpIa{N8}4%svR|qY?5E-a?3Mr%Jc^ zprqX8{BLnCiJu~{+fDMn`%?b9ot)Q%w5+AzMYM7^ARI6T;dO*|B5XytU4$J7Z;9|T zLi$*QB$ALPLOQ|{5$YiPj-YAT&aZrQu7s29_p; z7{u#{v2X_#uoiBNcS%D{{Y?s2(O)m*bn=@Ey_WJae<^zWd8(~RdYk6xEFa44+=GAm zalfaaqi;qUGoE4D>FS%2@+U|Ld17N7_1lml*+x5oA7Yi(ntC2d6^rTa!+?R``=^3b?H6#A=^%2vpf3VnpW z)F`FD(xw!C2eY^fx*Du>K~6m+3F`rP2f{ z6bJOnRLGPH*9v{9QA+=OIcYC_pQ=BzEJG!+o}>SF`o8X-S72&G&<|wyEYxKOErWvW zqUASsC$0A<`-{V}pO%9Fx0~LM4c$#AO=QSSJ{lyu>4qTPP0MX;tz>rh8VGKMuf_dnD`Ol3d})8W4oYI0GM+?jpEp26lwcrqt> z5oVErF4!+X8tm@~8thTH%wciCR-Y6EdklgFo7oITOaTi}tNbzt{j7Pbz8ly7>J(5v z9qy)Z1GHslV{np$%hzOLCSK*XYGToV#hKEi>+l|J(?S>K7D^+_T$l|f2Vsst(5crv zT&)vVL7OgNg|_Kt1Pk-@Ak1_^e3_;06kg|&@m~lt4`Vwk8s=iWN5f2R8nos!ltwZH zN!LxD8id&$LBs5dt2V55Va{QNhWR*xh52M}Yt0e~^A$FcXkIl;GEqOGkn!yj-sLb%mVncm<}W`?66q%*_y2$5M5tehL@JY6Ete$x%w3(Zn& zzsWCe!p=P1ChR$-6ZT@UDI3QF*oYf4c4>{Z{p zjWuf;?N>V8*@~FMO}pw7?Vffu#z8y0OvU*sOUg0$-)njsT@<8uCPJh{f|uT!aB(!f zL$S2oEbTMBoSoR?@X}*k()6B<%}5PFlHLbEn%++lG`*v66p}$KNN>H_L3;ZjSbEzX zX6fCD>H)9uXeMiF9r+KWx7j9+-fh60*Z5D;n?5HPvONfNxI_iIov7|g~}p;`J{ z>0Kr^rT6x^1P|*3NqQH7G`*V;G`&~gXtOv9(wlN=kltJbOK-|}OK&=nqgar-9|}&dVDh$4b;XBour2uR z5tf4x@mGC|;~3U#ZTf$ogUj((vL89v?s72YYI5Km7xaTCK-v#}M9>^ugQFU(cKzVk z!XO935iAG08d?t0iND`w-@Ao1J(^W82eDU*{#&PfBM>@KxYtg3@|Zu_>@tdi&2B0} zWS}HNHoM)RV6$6`rAcP#Z*6vkVpF=@@cDRHCP+rLdqA4*j}SE7>v6PB90j9Vt!sjG zpNyb?jUJJ6vm8q%mXPCr;uQb9Zbo1rZGA7xJgBYt*M1$hOLrN9sht*j_)f4Kx8I<@ z$>A%5-wT7^^Z9kh?IX1;DSW#AGN^^f?t_3&;S~u9S`DhSfLuR=Py;~^W#{1VS{9e< zV_2b^cLxOh%l_eD3$+-v&QwONcdB9p|=VcZWl8KGwlKZg|k+ z_F5@LoSRB08j&Y0+Z|&|BwRjgt1X+a?OJZDCKioY94;H>Di`GlC`C$KlnX!_Tv<5G>M+bc?irD3jhLF|3)|yn>P1{@LBf zaH8#=qs?pAX&oG@t$jD{2JV@MeBFk_v0HFr(NJq^ZFHA{NiGFPTu%xLT?$SDX$nRm zXbM)~Xjx1O=CMLkunfUcaB@3KK|0~DXL*h_@_d`!^XK~TKDuO+h|_rriesqRG}Fv^2SSa&KTStYt_`@8#aWw;j()ivpfmFCey4@mZMye{{)zF`@n4yLw!Gy{qS3?1rKxa#znol;~YO zUm)mRJ*VPut59E^^efc$+RqVpBFJ4m{Sa)79*J6$7OJKy^PS3bq9T9U{SdI?=Rp5D zmP40frLCK0{+;WPd2*jqCrtG<&tbXGNoLe?r;}`;a<7y8#@_AZCL?mglUxZ4?stkz z!iHvL9K0e61xZE=QBj#|YO3;{Q~5?z zG$TWMSw@zicF;CXKHkN2Cu_emvJ`X0705{G#Jg-xN?cB+!Ys1WWO-5p0{uM{TaDsmgzx%D?V$*+@LdvXMb1T7Twy<5@Gb{eK}Fy)jrK zzT@u>+)FmPEzXo|{DAjpHnvOra&KVGd&!2!EqR)a(?QxdZbQ&)jK)H!4C%6e-?)&mew^;*VN{-Qd4^o zg7w9>P|J{WF2R?YS38xjMMblJvYZi-y({#;{hUw86>|vG@qdv0XK`2{-0G#=+Tl;K z|0IMo`?Z#n{SnmA?B4(ivR@b4n^`K9eJ<*`dtzOE&A$H-*^ib;_9K*N_NOCg-*1ew zS(eteq)M~Dl9ihMuMjNztx+q9$$sM%fy!wJmi?|HE&JXVTrmEUV-VJSowHxrFK2FJ zN50X{Z`S}Fv}=IvA;2paB!|c0f3Mp@(}#oBn1c|hK@Dw<u1p{}jb=#e1R0}!k=9zbo9sj12Wr?Np* zdT4Um>Xlo=9 z#*-|6w>4aSZH+D14Mj_&H5xt^v_^jfZH-i%ZMHO@Lh3Zt*RWEzjTaHDHR_?3AqR88 z$dtG`P-%@|t#M^nYmKd_=6}s~G}ff#{R6F0?<+ zk@U7fYn<|Av^74((yfH@cU!~N*VcF(yP;@_w1&SfXpOcA+8STuun9!y^y5gKw#GPC z>b7w=g0+SRr?IA{DjzzPL!WZ3@#7e4jdiGgwUgN+YhLVJ!PbbsE!$ncbo+&}53=Y) zrzXB$XZgD+bM-Z4pF%nmEs>NpeL6_lU<6HB1Dq|fT--r?nvX@S)Rb*Pu#~kxZF@}0 zQvMyNbU?5Ud|oio*@-}9Uw zYqp)}Qs%y~9Gq=)FgWKF{p7M;9nDCQihRIlx;;pj5j;<|cKYI$-=EF5Z*ehG++?Jz zKr!6-96cGAS%u#=&%w+`=z|b)nz`*LxrmZ{`TonH`8D~^RfAT?pTWz^u=J5x%O46( z5BKFi=L|Bt@q3-v%RyL;5IlnSBTl1VQQp~wxH;FBPRyUNe1hI}U0mGmcVsFxQ}MF@Z9&TU%J5Nm>DVVw7Q*UkK(DFB!N|bU`8zAXQa%^C(;d+k%IiS{HA9X z^ZyIDWZr>r=my%RljQ7DD*bGgUX)5f-tr}H>6*2+=muGP>4L?XlC>EWMbf#1;PRu*=o#86@w&e>IzTA4$}l z?Jj}xsvjBQAy}uIYbbYmdmm@J?Z|gx>Gck2>K0hLlts>dPXMRqpC$jp{rN9_vWNX< zcH+0v^Q5J<79@p_;aASiGb1=w##`8}!_M75F|k2!&Hl2>6Lt-;)`YhEE9}m}Yo@Tf zUTDV9JFAD$E5=yyue3YsAL?Gw4aO}Ayd^w~Sjq&RFU?XTu2IHgKpQ0q zR*N-md78wYC;m4qbTGS~f;?dNvER7Gg_>hds%RecBHF|<7tzXes%BW9%TgYD zo+Kg$$%=HT&2Z30OWGJTnv&0+C8vU^zI+$Jj zlOASdkDdTo_7WwS3H{-FH=uY{fg|g73;Wnh*xs?O+dEFRy<=UscbpoWxT+f+S9Nb$ zV>c%bS#bX$>51E0)_$4X%HFaqLda?A-f}P{@q5db-5D#z(j#WA9{lqs=)igw|IZd% z{SmGbTTU;3rYHnmRw`B_dZ@&XB-&-8jUJXpw^7wHxt7bQwyj<-m~o)t}{o*pjEl&AKVy5nDNXoQ|&$qwH};BG_iQiAu*nqfAU?N5?Wz z$z_L_@#hrT<tMXiRys*F1;Xg%*S3AC^6)Y)!Jye8xqvQzG!Po63Gk zIwti#@e{l{C0ryu`M;6P-B?^@OmZ;j*u?C=Z^4&la|42>qxmQ(lvt(M9d3Hz z`myOe=3EPEC)WO*nBe`v`i;FR7*zb6%uQNKyNpd*qBxkeBqVs-jekoVmJ{@auLeOs zgy6N5Ny~LqY7b4?VYXD-bJFrAx@9IU2W(<1b2XzA7uhk0sXNSEY!1uc%GkDo@rqfD z^~kjs&@Yw@3i<_x?yi*J9fP}rPWfM?@M}DJ?bZ9F-sPt7ez<7A*^FTGzO#}Nye3xZ z-%@GM6#j;8nG}X!V>g>at+@0xCfa!{Wj5&e^y!{yF!jsN-qmt)kXdsvc3!BQ;9Z60 z=h5u_#aXk>AELA3={iQO!(v|vG$Z9Y43^Wu(q9j7wTC7R`-D{5v)ea(lVUqabcZ{=DGFT|)Qon0x%oy+-C^e9 z4|!ZKVYDdcn8#Hso6Pp-1^on*pC3fa;`oizDwxbNrvxUKIVCVTct?gixcqH`U9l+L zY|0*7+N3BY!E4Pz;(nxg<0eJBpsACh8gI#@DA3eNQJ9kQCPnBxY1Ud0U(BSa3l(%y zG+JzlN6~YWB5gw{7)ExWauJowX~QDw25tD;1UqDXQ_Q)VacwB3UNCcixea$r2)Sxy z+b}FA59RnDlLuB!@OI(&hW`Iwv|*dn1n*Q9=&kNorVXcU4%%=LLda=q8~&S;a@tTV zZ82*u(r~hXwXIl-Y3P+= zOB(uZvE}q!L+hSYDz3N6f4OC@m>hD|%C<~aO0acd^0{gWUh=z4RL}TFT839lGwoA4 z-_SS8X_mpYnc*E-f~ESw*bdy4g5!1=4&W4v6i{) z%yL`iu=j(O$wjc1nRRf2x0r=oz9p4nx0&IhE-f<~A>=f*W$ve>oR$$w^~eI&s*{A6 zmU&8S$u_f1Y&pHSmXV4xt#U0uCmeY%C8L8NV6hfsUE#s<{ZJG2uYnic_EIEvA2FHDd>|e_SC%K}RfZR#0()pe4 zB39w@EsNwi`a)b%58E0fH4`D^G&QNGQ&LV+#Zn&vATNpVk4fq07I&H7Fy<%#}RV$m+ZEUB~-6f%+8k|zW@x4R;CrPbwIFn=++}Flq zTvD?>43gRxA>=eQsTWdGPEy6vBWA5H)?$)+nb?w~%Dv+urx%x0saTEZ_u5mVNtLsO z(WJU+Ws|zlPSN<1&@QzSy!UWCY`9D6-#Z-}9GOH<$GRgEcU8|FnMBVRO)q-}Nqh1n zC|xg+)=eoKRwn6Zd=w;o8bZivYSQndq@1LSrTR71+D5F!B>jG|B}so(Y&kubbUiYW ziqBf*IwYr@S?zzQTjt0l>toEhn$cOUoR<<)O-c5jo>+0`Ny|AewS#l$*$XMcOJ}I~5#8SuFnypK*7SnRa zQ9)a-7edJC#kHJN+-8;E6e@e37nn%hGA*}O%(| z6?gIqLVHH-zqQTTQAo@-rbi)BY)2tiL1BdKx9g_7OW!GHt~+=eIhGUsix6zT-K1`U zcLEEQj)r#JX!wMv%YOSkgpkwJ=B@N;xy>t|!MDi2%Wz`ReKYk# zET`b%XW3NCe2C>GJnDy7+I%fHn|0vc9{CW}-?x2p6 zb&swG_lh_e+)-HiB)gKG9DF5a!3>)hO-@d~L&)-4W%+8%`*>&q6?xb?_Ny@u<59_G z?362{j_kvrvSe@M?V&<;AViaop(}mM%jw3u%sO`e4YFhL(6=12x8PC9rhEt4NsjD| zpt5AIkk_t2HXWkhHB0akzh_9FuwP_fpB|stPiELr-Q?uBZV|!b!g9#Zfq|0$79mpX z$j|v;ZdHa7t{?Oy-m~zlqrjPgeDIoteLL>tX-5~q?yeIjNb&Y%p#EXwl@SZ^D zy7T`Rncs@XHsz4d`6VEKA3~(BBcHu%Px6Dt8+jq#Dl@^m6P->M>=*f)f}yWWAK!+D zN#&3|>eqnmH3*TyDB0ikBwIAh$mT$FR!hjDvvvQ-1|P^8ip6E+klTU>-2l7(4!L!X z+?DxGO%S-3e zAzIJ|vK}X2CONY1E%U*+>|n4HiN18+uDwr+|I}C}7L#+-dfZN91|F2$7YLCIG<1WS z>az!n|I}Fa!}8cMyJI2tbK3;IM9bORD7nA2J9c}xiSc{5>3C=(WXtT1yC(!>A47-~ zII`Un_ays_>@*w+)ZW${}BmTY9ux%tMH*bL8uBgH73P@oGOK zzXam5Iwp9RptJjbLcSP}o68}e%v~}{{yc=p&yIX0ZfGe>zM!6w7vh7%3EpUQ)=d3h zWPT+cYlPK%+y?m#43vC-?l6gj(9jL?8@U0c%m(?bOgZV}V3eolv$a3Ys(v1Cj;Ya23J?~@8trBK@RiO=7UV+j~ zf0Hva_+5mX%<2fwAVf-pVJ_%vkUj_Y2lcmG{Vk+UAM&cg<#>G#tO0_(z2k5gH)U~8 z;sfvDvAS*f@yUdz_P)vXf~ONmYF$K zH_Jlnnt9EPy4^Cgd#$Yg&sy)h&%{AREx*6dA3b}&!+O`d*0a_-?g{M8G3W@vaoIww z7@HvxH_=D8 z9u~plI9M|TBaq1u%tSyyupDHM;%7jx${<-sBp@Prwt(O_K@>x>#E>mw$Ph6kfyKyY z2|h(Zmf%g4h!qk{h8DF+@K2DPmdxo3TP&cgU9sLLtY``Vh9Bei9k^E&T#kb=!Y#on zS;&?SZaxuC4wMMrgMcj$)U4kth_QZyz@u337z!S&-$5!vug$4OKp;F8WK;1o5Dvms zb|&e8fPruk2;LV&J`pzZS%TY9kR@1w66=HnyU!!RdXT*>nL81dwJX+x32-!8%YdRN zR#h^qILQ|OqO^*0z#<@kVOr3Db*X-7ny`EG_q2+-ytj&1#v!4RF%v&*q~TqD0PvR8cMy= z5OCN*b-_~9@!+%a-2LdzZb^1i+*pYEu#l{{5br^Ab^+WM{{vDm1drgdn(Y+mSpA8( zD8=gEg3`K;^_qs#tp0vvvTnEIQi)K14w2C{HThPAZ*UQUNv?0l>JKGj6enPYEr{3{ z0UjRqMF%NKNk{4u@zg#`GNhA~q!gti=vn@)=AX_Z$xe`2=%uPslJzL>E(zT0x@O46 zT@1%yh52J~cVlO4#4R-}agn!-vn9R+hX~rg#62q)wggcp67^Pd8&v0Ii5TpEu_Xe! zLjN?-vHqVSCR!It7l_h7!EM+QgRu?8%6-z!utckoAhWylpMb3;CRrWgvV>(6dI|>< z`LM)TiI+mmYF_vT?N^cUS7ebHPB$)`Zb@c4Iv_ywqo|3>4X4=fa+iweC zg{*OytM<*D2|~7fBpA4#PF~Oef@V2I0X!6PG`W$^#x!J>t_A}a5w_CB#^ki z06YmvZeIXigG~Mc@Cu~!7l2=+0DS@YGYZfbfPbL?eF3;r9|Y(Nz(Xjo6M=aM;E!Jf z``;vtutJ;|dhKrvz4bSSUIQCLZ-I@WmpI4JtA1nX)vvYyJZs9YzFh|%wg`&Rt8YIh z*7V-yY6SSDr)^-JWMmt!zP+}uH0DqQ_|N*!j?$PQeg0M$6FIZ*zAR(Lcp7u7@exY# zYFw@4?+e8Z_D3JPu($+`7 z>6qYj44hoHHusaZ?t_3WDAC>4Q;_6l>qKO-txJ&3wtkrcWa}doAX}fK0NJ`re+05P5K41Eaw?>iGwUXE}erdN>^2kEl8j^+H+WmKMwQZpo zS-+AhBkP|*fUSQkYC1qQ$rm374v^NjAi#gt*QE6~f%MbcaeWRsv+lk6);|q-ssu$okC&B0$#fNddBcIs*7(>(9SkRZac0 zfvYW;Vr2cDR2fTkkuMwLgY@Z0*)jWHQp7+Ij(E(%OmOv`KJ!51d@q zJ^~uHc4O=o*v^8)Wo;{x+^ijieNVP_I?~zN_fmkY{R#!h+TT%ttle-h0%YxO6d-F) zL;!zm?S%lfh_+GN_+L!FzJ+S0mc0Z#Y*iE^+ioJ(WZQorz_wirzCoj0w*3wnY+HY9 zFYuqWW?5%+xWMB;5@e73HjKz*I*yPmWC2++nI<- z+s*=~M+B#J;N-IHe$cRO&r#81AaU8YJ65@Fw(U9^e5oamMLOFyp8{mtrzk+S{fq)+ z+g~U^whh7(iEW#R0RGsvr4uk41G|f~?Ha0?Y?}!lwgVI++m;e*vh6km*tR>tR~h57 z?Pthf+nz;$|EwQ~p3xKxyY`!`DlM@#(@Oq&+vcMFU=p>B|4(qOTIXY%ARpWICj@MX zD8aV94XZC{+ZEtcAUG{4cDL;o(6DX4MZmTfBre;wj`Of>z*uQp8`9afsT3gF7E^$1 zyO#oF+bRl>ZT+wYV%rWx0Do-THzwgiG1y(CZHuU8vTZVW*tSrNYeuOVRU7{g;aauYwiNQQ zZNEgo7J(9MTYJ3Iwj04IO>jzvBCdA(ENIxahY_%C0*TAE*I+^D)^5)dUuw6#kC3#SKA;VGeW>4WDn z=6xfiF+W7W7K}YLHfCQeVr4^p4xAE^4z~z_zO0%Xjo6d+^XLjf}8s}vw(9;5&nv%$?SV^*eOWV`jEjhP5iHf98P*zzbw z#+-~88*?!NY|LN4cMb8C#$1mKVN3*sF=w|%HZFK1!;n?eU`*u1tu~BV$BTOMg+F%< zr5F4x0mmIwIj%T*yxiv&2*EG+LBMvHq^FnrRAa^N`Enn{`in$+fl00`7-UWakZIIDRqMGtcqJqR*6YTUpp8$Dl|2udEk+>`EhVp5fA?vdRtIKFf@X+KLS_}y>qdgXTAH6gWgew-UG(_)O$mgsx*VF z=h2(r6|ok@Yf-z11`X^dCxXqld8+aONLM{_d1~i*nY+f9OxXNOQDd@z;Vf|WfMFyS zaSTHXtifz~1`MsS+VJ$(o9Nk&<8$z?1jr6OhCuWSxj>%N1>}v1aDjPc;$;=-VDqkE z<@x+nIK8T35$ZSIK_H*>!NnnqQONs2pQbd~0=B2XuxP%jY(ViJ{`Oa3tK{Qihro6e zD)hiM3=18`_A~;vO$N4SurTn%b_iiR|1OM8f>S9t)rKv**=?9+8*Ww;+G~J7I)3D= zHNRYQHG7#_Gs zRUSj}=bpGMXpL9>xjtpYy=%SYSYrwR#-IWZD6hv9g`xZx0=6Op%3m>g@Pv}zIxre? zzKEXzK#<25rzWL40r(DMD?R*3U7}IQ8-NcYB>-TU^Z@S8M)9Ggmj{5D`kVpBH9}zz zW%r>5R`&j>P%s)Nnuudj{Hj z2%L{;5esacf$FOafyd7D7MQK`RSEEitiG-DCJIUSq?a!m)-eisTj#MLSO@p*k@8im zRps9(e%uLwaiiWv-nZvDF$G73E{NuNPE0#t*2c5*XP?$BJ zf?(G^ie=DjRrzd|CQUbv2yJb2>_Z zUIPTu@iSbsc0d=q_;><(FI^f$%Pa<)Zsn@75rp);F>%|T6p=Bv&LHV3xc$fAw%OpepUC)I+xJCo+Qnx*`Mqtsq$=xJ@^>S&+-zh7uXW|31i$32w|OiAac3E|Jimb=L#|zp@#2 ze@#_ZBPV&|W!(%+M)3o?Ey>Kf%Ldp)V(+wtVH;^HZWvUiN|d>%hEbbMf}j%Hr2gHo zNi4<4CS4I@o5Ui(Hip;>P_MnzS;B7>140&=m zLAR3%5q6&;(1&^zcY5kos)?Sul^E(%VyHujq245%JlOAE6sKO~1_UfdQO2x~k)oq= z#%&Bz7`JQ$Skq0AtypOKt)Zz8+;)NNu+X$AJgPR_j)7#I;1)q-)G_(M?F`6BCZj8< ziJM~m$3WrCU0A>l7Cz?o%l?(E%--d^_p?95c=m?(2m z&RlyhuS}Hg>~|lGl?c91uL&+Tl-_@ z#$ps_w{CBw3<5*OZZJ|9yU_^TL?h&vsPBJ5jkh+{jvbLS5n@#lSxxMiTQiV!5oAr^ zf@}#N*bxcIR6BNxwQD07^xAr+WYFcmj@zRlas8K#`Qf$o-ot%f81N#pGA9vT9A4Ou zuLt!1b|x32i4ER@(7!p&g|4k9q7C~GY~U6RxQRYuz7qVuC0T;&MZJXnf<9y(L*Frv zp^uoy&=<`4^W{W$faogB*AN|jY&>QJ4*WUpXI8)peG&Tr0gFM)AMySfDexKoe7R9q zg*k>k;vGXJT%0V#pJd^3LB;GxT)7Say5eVQTW?9t%DaP-D<6%3#h_&-3z^AHRj7x` z#}bbl>g^>SZE&d|rZEoTDh{Q@agF7N?H}mN8Br+3GK9hJ{UoYk$$-W1N z@CqEhqVg{w@H3S+=mvj|lt$PH#Gm!tG=P6sJyQV~Osi0p9!UT7Rl}lpd0O-?PmA6q zO(-pDM5RTIXuwVMP{L;LpRpA}E~@twHcn&ccK8^2E+K}Vm5QM!5^kc00En(D(QP$% zAUe;-5rVKU$Tz_cM!;gw4yMP$rXz)KKmP(8GDPG49j?i(;$A98J<4VTL|5@Ykok*> zn54=eIY%TQB56nxmU^q%C5hX!QAR#XF!VtwK^RIE2?+|ILv0c`KsHH85JOFu1(dZ5 zFp7|Sj3^4~Szr^F2>fiuSk%X0EJDCy(6T7&4N=NadW{gJ0XWnq%4;CoPZi18@qS`W zcu8??%7x33B*AbI)53ZWlQip)7V|g`;dJfrC>2?PKs8BY&<=hHDSoTakJ7iu{|gQc zh=Z)A6Ee7(2m}c8Fi=w!lZj|Sy_gAz$Bf1yJPwCMBDW$i83BtyH+ULS@{qz+#GvFD zw<;c{GNj4h5um@0t!TYQU$=_bY)tbj%+zsp;-~&9%+zaj;-~&9oNF-=QaX-^l!aeM z;Vb`XEL!Y|s(7(iVeV=Yi#-v-VvpKp2K4&?zwJ(L>6 zZa9=Q%|d}K1(t0)Kv{e*a zi&z9=gEt_Mga8ja#i(#CeyDI6gydnT5Scsyco+et4~=!tgJioPW0Lg-$$lbXiyfl- zY{_EZf{$33U9`ob2%rPtKX99>90ki`TL4%E5(%(9d^SfP|k30@$C1fNLJfy2tRR0O?N+qlG^;j28aXFq-@c1AnwPFvSKi*$~gR&H&~? z#2A>D5nx}Mg39LL2aP|17OeF_WHK;cBOrj83z8Lrj7feqNSZui0P_j%>!NE`n?Tm; zOmhWR(27TvFRe2qo{@l;BVbDg6$2jitWUrLcdJSuWUU+E4$g43cMxO_rAZ+-501K8_zI}Jiculq5s8q*+TE;%7hz#&^A z)k2e+zQ})r2^pY%Xz%V3s-A3B**Y=F*va72`|BUoGB##TS#H~|Ms$!Uwse# zUOEeQEiCOrI379Lfh=lKBhLBZ(_aJqo=d{T?^oTXaGc@j6H&VZ@Xc@7}P;O~6R za2{0G71?l}M^GIj`wDgzxLH1k^{8|nkkRedMpv1KRTGmWVcti7!g)S~^8okDa30Bl zWw&CkU^!!?kn_BV6qf&P%r>~^Q9r_ER@yJ9Feky%EWf94!g)XzFx@4;r;4P2^)Z^! zV{DCr0@ly4VtYeXw!QP0I1g$}BH{A%LA$)1=P;yT=NXFGfh_}6>^z4N^W{9BVAK|z z=;PxTaGu(Fo;6epIZxCM)VYOX1pW@h82pzoH(>DBpt=K8U4{7*RL9^yjX{+?qwsB~ z^MI_Fp2(BqY#IhrCW*zEM}NY34#9bVd)=JpJGWu$jO4(whhVI+I8#XeCy~PP=kGC` z=P=3j!58&tAlQInO_VnBWuv(J$aUwe>u)R0}zeWk2dnrWk?02{8u$ zDGV^ec~D&*RaapSM0JepD)jN}8CmZ;od;wQ87}8ZLQl&i5$KZWPdLx#a30`(8O|d) zu9%hk3`RN6ie9IEZ9ee{GP%I=K)!=AoHOjDPT2CWb>J#puoe& zv1x?PDtKRAork{~UHcq|VR{BNEfCb=Od*(h9F#Db(Wfy?8&Kss zq5sc&rI|lOCfhI)J%hq9?FQK?H<-$i!z3*$g_#xWNwa`y4HWp_3B273Im7n<88FrR zQdJJ4hPuJz-W3@f7$zP4lEs-qFx`a|_NGzjS{SBAs4^mxy(t(vv8%NERAO)+0s^Ma zAS)1LOmfa3Nuh3ly{R}{z@&VIk+BM|bVJUjck2q1#~RUiIi%rTPcP&(VhGhh!sO}y zgUlW?<|s5But*3{GJ!kqy8m<-hqJaET|ahQD`Kd zeLMrLeT#VzE+QD7UHh_RbuB=5MQQfxZK%N(MKJ<85{}70cR;&gpu-`Uu7=Qz zVheZ-x9XJ$2%sB-EGU=Bn4~^{XOd-P0s6Bhim}(U1|ZM;58i2s9Qy~xg=?|xij_xy zx4m+@!soVKj*ULrEfm|>*g70STh`Bl-C0rdo&Nx;a%bAPQ*G>A%bje-kIDqiVQDXG z$2tN$7{$!5fnpNH2*nb_7{wP6;9bT8sPIetAbSLaWQdL+lOa;!7h;$38<6}a$e5%n za+qW?k?$`EXLUlnRlyn-Spg!kwO0vHu`?+Cq$>-J2L% z#)i{I>TxPb&GHutP^%3527R7UoHgx+6kCR&X&hp#X$}IcX$Qy^DP(I8P>|d% zRiK+8YHEr%%+Z!7Hs>=ym+(CvGe#ZrKfEl5p)LDduqzVAf9L=lM()fzcj}Fud%2U( z4nt+ui82@EFtzX4?X>r3H<>#yC5J)P1sD?*`Ck(GqYwX^PNm8JmQaBF?{NeyMsXJY z6{OhGpo+`?4kC$#{sQ%!6GDG-9-$S8a=jFX{I7=47~>|;5(m2v7SQea8Sjro9i1x; z_o(AFAo8> zieCr4%tAO28&=|a1Y9Yk#E+Ck*PTcGDwX&G1vUxkem{>Azk)1k?s=4eqg2W1{Q*=G zW!9Acp2Igt4_^sKx#1U8X$OvVbCkT_yc~ttjQoQgrRY$d9OVgOWjKn#hB4lW9E&rB zFn;KFiE$@I6Z6fksCTabZzAetFW76+ME5XF)1;#e0a?;K7sfwAW9~s7^aBb0cmyK_ z7>hbNN@raY3K))Juwf+}$hA0ANQt)fHQ^|W{iPB~sP~wVt_zG>n-bX|OS|hlO2APT z(XJ@%XF|bwO*N%sLrwYMv${HpTnEZ0A?2f>dAiZV@Y7~9QNt;cCQttZLVG+n@hocP zM|q|;(iEFMA43A|BhPHCc|CZ-ebwP>H03tP>g9rV8oq*R_EbE4nM>%oP&t5cS4CXj zMZM_$>qBApmd@8-g1oLeqN9>)O5$WVpuvT0R|$D7&J?oU-8mDWt<4ZKMu<*GU~dLba9!tiyAFjs^6g!;c`_BFKE}0RP+8Uie=D@Y#O@biQ6w zMtuHf_}@m<5VeqNTlh~e|LcaD+5f&rz?K9m_P^@3KK(DKg{G_rVcqM{VV~^wzPwHF3%7+DFDmcZ^wAgD(978Ml7@7{pkPq6F#d7|B z6vElMQjCoDQZH$=>~Lwco54E~*>Jog(3dUJr;qfimHiCI>j|<=g)XC=iIgNGqlDw} zf|*oKT*_43aW~~TW{|jDgfE;2$lH}jU6NL)OCoc~mVwgja4!#m+{F|lxgQ)VMH-}Hsq3rbIE>OP_dh2??z0plxhtkfx#y=!x$i|)K`Xeb_YJu{h2oB*oFpoC z$?d6{v*T!rZfYm|?D9Ge;?ffB8g}~q#3gqe1{a25P&y6Rk}pHiY^sE!Vw!}aEwUq4 zvW|yQEt}8>6azuFLy-Bfva#wS`5B2z?>Gz=tiT;Jpnx-lY}sq3RN%8&Qi1DHXX1mb zz~9iwYg1q_$PNoK-wL4P=!(4^7}0bJ#{6-Trrb4KQ|QCOb-Rz(W5somGmab3A11Hj z+83Sl>NtLf6x?y_%!F6xfr>kh-B~_6j$(8(#e!2v)df3_^UXN=pp~y9P8H_tuP?6S zI6%Tt#}S%M4Ul4FG&M&WZC9=|S|)f0uV&uE!J93zEKl|d$LARx$4HPBJj7&7GIXIN zd2+E^$3ZFwKf+WO=s0SdaYUgs%dIVg+{qLpxxYk=JG^I#q}-38ssd4!AJFw76n7lk zNTNqwa(k-g>^Rz?hx`bBR=19WUI5}g;~*}b@8pi7FPyc;YPt3q2XQiH90nJLA@v@# zJ7)?(G2mVa#h3RHT1{x) z)VP(y~|eo%HC-y&c;1}g42zF+0D<5+{i@vPvK^4$eHj`PhpVy0_KKq(`( z;ole6aYTTe4L4>rH9(4y(Yie(jrQHc(rAmpyGZa}4&Ll_8~-MI1^*|Ej$;DIs>)nO zo4!Vp>|5*BagfSIPcqd7I*!_A9P3b;{AfU@~ zdkV!J$9p8vT9@3OsyRE3o){92&%NA^gShlTkBkmJ<3E?&aTr_}h8644?wlzE#iVix zMT3nJib1GWe@38=YHNey4v-ZKG9OkpW*j6xBXQ{+hrxms*!ThzaHfy~i#JIHy1gV7 zu%gc3XIX&;XymmiFcDf|!+t6PH$BR>2UAnr^d#M{3r5#PUAB3_7UEzdFH z^HD9sIb(}#(g9nIR$m6PErN_mwp2)x@!LhK=dp(5XC!>NjMvU`?F(Fk3+tf13Hh8U zq(dcAc71#`p@v1 zBGeFw8ZK{!LR=PLN`a2%(;w^PHSRMMg9{`66jZi2QwZ_gT@vvdc1y$`M74>}GvY6! zT88tjJ<=s6?=!sS1&|#UWK7cVT}iU>JvXl*`5B2id5!lZ#o)p^jQIz2aHfzB-9C^y zd~`tSuoTrM|DAQ10}I!t!_y$E5@f!0fY&r{EW9QP_8jrJreuGF0sl;0y~cBOBj2j- z+)ouRubhDzGS+i#BTjowN{*sdUd=pp5F=(0sCZKH?8n}d622wkEli}=2u>H;JH^hm z+&jh96q+AnGjVR)#w16NNRl;2g_H5#DXD9DfvGMqA=w3W)XE@e;)UfF#u5H~C>@3 zEYp-@g3|>Yi(c1Xn`2FT8cm3}RG1(B@5MP*@XOLbW4?x%u@vK$UnLE6@*8QO=fFDy z+2B1JyxD8k{abp?)c+WcwG3njUSTpO>HLEvsXFE6Sfp;oW~RD;W0AVP9IF_m*|DCf zhTNMdMshDbE#)5kla%`isyZO5x)Dy`LnwBv-$GL)GYx751W$VR4?LZ z{-35C0nd=ImXt1E4AUzs8xcy!O`{<yPnmQ{^$B~IbujJtLc*J7H!x+f*z^NHi_JTe(S;!&EaS| z3isRSimyT(x1P#ewd6XwD^`%ICBXyo6jLsj`vi0Y@{QQCpEYIBpoZW&hjUH8Al}y% z52pC!7-#+-etGHyhBG0awiz-)Wd5 zAMJd4f%w9j>$~IP>xxGFy9Gn(;pQkvpl@YqJZ@UA|0|q-6bNzf zgU!(9yGc?TXrf?_zZ^vKez_{zK!ONg+Wcl{gMcm3sm<>`v{}v8f^DFQ`VzDOQQWUr zMH@(v=1ZGD3~dmw6&TvoSIjkS^TSQTHUZEi5bJ~4AZm5)YG{)P2_EsG&1p!)o_43n zjPB6T<}_k8Jnf+&LYrV{@*UPTx2k64tE-~TXh^Wvhc=%>BGx8OgEq$uZ9Ye=hBi}Z z$%;?89RzsWNp+cJ-&}7Co z3=)23<)_~-Q5$iS)vjElPm>Gse4|e@Zn`r1G#Q`AH(@DTuu%$Gf$b6q;Bgbyi;#*Z z%{kXVqbSmdt{tw>q0vzUn%Z~c7=(M@u208XiLmS)4qd=0Iu&t@IN`VA{6COKk3c}& zB{~G54)u}Lmy>qo;_bBvX(iioEd~qwTBHQnALiq|d|b%KEF4iE`q8&~2m~`wZ1n_Xd;6@U_ z6A0MW7ywo^_6cBp=&=buZvYdUfD5_cT?j;z2f`Qg@i8P09dUO-gT+N4xZETVJb)S( z?#HYQ%(tpn1Hl07J!}yO#z6oN1iJ-D1iweXcECWex~WeDU*Cs?KXma%aD1Rda2WzM z5d7R7L4(CbAXuFw5G+8AA7ESJB{2U`yBY|-3JIzNg7-oI4+O)TNd(U#U{kiqZtz_5 zng}{f%5dnh2|plsfzK68ZUMgZNw#7HT(9sRW-50`#{!$S*spjK`Bmnt0ZY9PaK{1^ zhB8k<01sHATS{2!wE`>_1D5(hK4B^S2=iU&a$#6zg8{?x1Oo1`C{Yju3;tlRx&L$Q zS|fj+p8?CoKI`E5gsNN!IG<3J3jxPp~>5K`gbv&?o@BM6NA8i&EvI4ryYNxvaLf5S}o4HYISh6=x7XQ6Lf zv(i|<8YZcL1bM1^BezzJX8QtB(BzRgR5bZ^^oAOFiEDr zmq}KTRMc_(ih%8uVUiUgK26f$jHY}HU9PN2o^dycQ3adie-OjsOd*p@3za4r5++S@ ztwoxo3IVTk1={A7a0i#t-9e9D@VzxK0cQ z;?5M>b*)4SUxrwFlUdpHIwgr@Ib{2KxJlpV+l1R0Zz=_^Tg zBfx*dOkZMtKo;2n4HjT2ZHX`|NsX_DMZSjwdxb?FZscW=mmn2eMOKj(rJGn{WdJ@8zZ+UD|JO>Gi zNZLI8#wM_c`v;z<4us_Nf#=Xcu*e!v@g_yDC|JZ}lVa$7X?Pz$HY2tOPSKT!(~N3A z&X`f*#;!L+2%XSN96EwE;rdH zJF4m|RaIfW38=-;^e%>GcQG`%i=nw)3{CA~Xl55f)4CX%(Z$eYE`~;^7@ES_0^Wp1 zGz;n+k@VO3lg@8Qw z4B)wEfStq(u#!=Y(sP&eV3QQ)Ux&G;?|ikn>x&rF2`U11@3 z=G#rZJTqa4^vtG1;h9lnN7_DXVe{#k8Q48Y5}fMfneVuHW(LZi-!pF_&!no>VmAPW zKNxt)o@p`Iu#M+KD^7U?jM>H|NMRdqrvTabcM6bq4vMK^;{r-@_s&h=a{`+bSI|4( zH@wr}&61a*W(%c!irQH6myp7eAEf|E-gcOjJOKeO?|gug+`Y4Ey70~bc;=f}B$tEW zqvlt`I};&6k?^Sr5Wu6~42_lES&e{gjp3dDjq~=-KGbjij4g;Y&;@>OcxO2En|Ij3 zg}Tjq5Rknl?W~DjlXljq*W}GzgT?tB6l2dYQ+7Ln;11MSh(+jTFwbapH4yw75^NC& zu5ICkV1z>=cn$&E0RurL!5cvyc}`*FT_rdf2%cx;abZY%YsScBYPvo@qo4$qOjSy?wtwPIzZA_(gX& zE2SW4+U9C_=Nph92tGlrGRVt2gA=89oOwDug&0s}O?=&v_GX zhV`5&H0SMj3v5NN$=EYW&UqK2+E{|2!rTef@`QHQ7^qLHkXA{?oVOHY2Lu_DY#k>_ zCf+LMynLS~$pu7-myfCOnfS(@W$Asz$J(~ycM?r9U@ zpaq~}2c162r-SwkGb_ij__{m?B`$riiiM|qckLxRsKJGe`!VFTI8(^D>n2O%I#Q%@ z2cg{n`u@Gt~VSs zU-$U-mJyZT-pbeSQFz@J$2-TB!{*3B;26SrA><_Nr(D34$PN4cp8yv_ZgTF|_HL=R=#ebd46C77R_=M`M); zqHnK?Hp!46)`vEM`BIw&2-uPhZ35@|(B|4PLK_P-IfpgxTo7#uz8bcf0txbbXmbt{ zal1*I2W^TCZO$Q9qunIjDzs6sPJRzd6Kl zJO}-K>9QQUE}-?=a!2w^QEs1 zh+BF-Mrbf4(MJl*CA3$z4Iy6j87%DKs3ySPm5i~I)VN}-S=j^T z_jkS;2nJ)7lO_}pZZZ(O_Wl|O z4np^I2lUv19}u+9r%o$+HjdO8PQkelg~G=n@B#wS37n%?j57AsNC>dgRrvtSTZfrm zM~Gbv48xMm%2Aa1pzGBDsKspBQ(o^$0R82yLFa`YZvD>NK{Co+09q)2j!S&6G?jm+K+mtZ4DD>=1b#98QfE2R4#h)I-8 zA&43=X+{P`D>-WJpD=(63E6a#&CaqNrAqzHaS?QUqcib8GZCa=0hq;N!wtVa51EyE z-5@Cn^$Z{mbCIIlVtSM13g8DVf+0u;{M2l7Bxpxv(Y>qN8dIa@;-ydjun$>baUwD z|E!EWa|62Nh;`s+G6m2a<(jV0ch!pxzA+xF1U9!PVx1+~32g%K6nB;i;`zfU!%7TTP`bXRd3!8#4;j|keNs#mtd3ch44_A3kCa_Gs+Ic4j z3_0x;hecaK zj%S(hb<|liX3Uz2447iZgzU6g8Ci%RBP%;IeP(KJMBwY$`599v9l@;Z$>}q*5w6GK z$x~7gh9gk=ERhUpjbP@4?DSbPCrn2MDwsYiRRkvFvSgf?k)D?_gBXH9;)Mt#KsA|D zCQP1_nVvmGWT#HazLO9V`OwZSHYJy9K{?bpWzsAZo<-FnA!9;j)|5;Uo{=#nH8*|o z6cSa`L0Th%+7$&iHR4Zu!DO1#Jy=oArqAgRM+ZPBLzX&+w7H>FW+WYCn0eNn6PM63 z?aZkWa}DG0oKUSvlHNiOeuJYyI*UJzB7Nx)O@|0NETY2*It-x0Xgd6p4h!foj}F@0 zBsyi%VGtd*(4iL{o~OeqI^@z}3LUh$*>vJ6gn)URFqcxf_C!HeOs5<=WYJ-uGsLV} zx(A&kWfaoe(NP=E3KwZz%k|t2-IKQ8ulK}lxvE*!URto&Y~s)drX-p6;(|z-cEFS( z(>5)z%d`)jX)id_K60jQbfz72rfqPhee6stccy*fOk3|vt2CvsOnG*{Y(LGvR0^?f zL9rC#QxhSq4w$32$hVa*E2N0to{nT5)k=pDI&7muEFB1MHPtg3Ls7D&>TqUoF#=hQ z(drk!>ter>((1(CtF}5t+a5t9^}I*h1e-E#yB(h?Z~9xdP#^{w_w#o{W66;w%1J5*G)vX#SB} zZe*Ez(!MJc`6gcv-l31vo4NgKuFXl&!#w`|*+~xQcSxx8jn?Hv=t9lE^2u8cKRKbs ze=R>no4XihF(vOCa4638@8h1sv_>i9xDC|;lPU7eoD%-i@{6_lc5P0m6a zVLAMlze*1-Ivuw!$Me5#)$;Z1o3*@bJx4#}{I?;F(jzZA{m_-+qUSiYIaF(CYFt@P z+y<}zdPl9p*2wJ=!V-`b3iK{D7>3$X1wMHX3dY@tB_G22A}jCK_C12Rqg+Cbjyosr zY1iMXwJJ{8zD#}6)WRB}K6BpVlcwhV6F~K-DM(vlu8t&De!AU^CxH>rR?e%Ief;<4 zYQGbH#We|1oCJD`U#XuSSd%2%Ns=NMgRe2DeQ)0CBTWzWtMpsU!;YU`?2^V9_P#f} zIE6a7>*Y>XE~#9Et}6Ade)?iRJv36a2GUPdq;?B*)ud*coP0x_Z1+0Ts-0e8X==3KqLH~($wh-$k_*cvxo|RZK|!+~ zxYbYX!Qfp%c6zBgI*<;{3`f!<{p`+guwRM{Z`JL7c1tWUk8>Zf)MRG(D?{Yt%}66%`JtFMwNLTjQ)8BTmU`@qMWK%L792c~d9 z3s6U!+KmkhiL5BGTKgs19F7DnZ}Ck0SSf$jU(3}`h$suFc56m4b;!k@v^nZv0g}HM zt#fJqt!n->tyQ&L%x6+I&3G+y*YJ32oCAaE-C9tomX?BHSF68RYq?mPz@tjM*0j1v zn`=)@Eli7bIHrtsj2(BV@Q;1t#*Uk)H4D{}Bel$Ot@+~Ekgx%BQgbX?lTx!;`zp5- zzWsQ8J#c*Nz}WaHg=2L`*x16!y+Qw+)@4Bxp501Zq8u0CS~tnH26|vxtdNAHJxvF- zd(-t*LaW+yJnP|dpEz;RKUrT@7_YbY2@9>w1duw59>771kizCTiWPb|mupdZapox+^cbP<5#$t3APF+3LGgt-S`_ z&-Iuto4cL*dbaups?}Rs$67BCb2G|R z2Vd+7ebs;q^;O%##x?H7B3FtO(o zCX!~=-)h-9SBKe)T39d8Z!a4kqs(GcpjwH9Qdj;qfAR;+J_r>*b(t2Z9%~TjR~@YF z%G;`KyGEU1N>MF=YOyKML}w9HhXkrmfSEYyp)fD!whvSnG}A@jrl(v+j-_=0%n?`|tCk#Prl~-*asFi8z0uvg^Po_Yru zL6g+y&BWwI;m3aJpg{Ej0Ee2`qk&Y%Ky?dyZ#}gLl|D(isj_^f`ZJ0HfRAMPN_7Lt z8LD;`lEX0TW#Qid<4(#P7py&*vsL@TzcR_Be-*5)LFAafo?XtdGQ|GnZ&;%M*3el; zgfK)y?Y{!+*{Z2zx+m+{i$6vua=E}=`J7$Lcx!v!8r=mIGBrVX#R5Gwf zR-JzC9zrV&^0>PUetoYDzk5y1wa0U4<%Tr{)?#us;T^%k(3L}Lp^uvA!Fs43YEuu^ zZ`&&+&Fsp`U0XAQCYRRCoTyVXBh*DR1HVgaW;OWTYig#` zicF1ajpIE0Mq;J*GHsBJ)a?kW%T2A-PHpmHHtFMOyyj)ds}$-@2erMJ_4MJBmQOQQ z^(M~gD3bCxsgHZo98S{e^LkO0bh#qY-y<>-fMzIB|Qo2qvAF0t%FC3^k;ro`97tP-mP!U`T^@~h-y zJZ-i)q2{Dezj1sn^;-$tJyHBrn_kYB%dngHdYL}f{eP;yB2~3E-8UdiAM5!)L~E&M zOUv6~ajg;du}?cd57FBdT8BBXL*jChkUy!=xEeL}{F7?3)~Kn5X;6Q+n zcXt52xjydo1V`Zj+O9VFxfy@NjbZMb$`8HZW_*3UyXg^5Rl7A!ReLrq(L=mF0OnV_ znu_&l)-QAZaK!OXZ@WQXgz%mXxTYKa1VY%Snk&wcbG5mpB#qWk=gYh5`=-WP{jI0p zQ_~xr)>ozeZbUW z`_!1Fd@bxG_^MCPfj2f*Q0OonV(DO^!&m<=M72!X1W>icyojeO^R;Wh*Z;WV=EHg- z=8F?rMx@rFRPO+A#O~a9%3>nU=L6?l;z7&eweF9^)`hpelH#YGb?u>0E*&a7(`bK7 zrS3+^#9Fd+Y&Oo-InF^}gdUCyAhAZi<<$aU-tjag3 z+PNtSCzxHl+`gIluD2~!z^2yuh6DC-ErajA(3MCxUj2)f&j{R1)I3P=rKQq$uUzNis}tawxPKGQVpxMOZV54Rgn^8!Uv{l=iay9) zs@q89^LGGjixEU;qk}7SwVJc50dY%VXtX@ub=MlOWw_&m?~%N06rP!IssWYOxKwZc z5avvJV)sSMKxpzK4ko{ibW|5<%`s`>JM#QaaJt%ox-AoRzovLCGkakFCHi5tSAg2J zxf&8MFjno-Tn)RD=Wfg|6ZNW*0r9au|7FI(=j!9NfM6{nR0~L= zaW{Z_@H3R>R^kUP!JQ11n3@n9Hz;;*x)lf=57Gly&Mu)sexc@ieAb>wRXZ7X zJA4@wDUy+zGF_A?ElI`gM4ErLi`xUt?I&<^gcRQA#qYjUy6`M6_MCC@yHD^t6Qoyy z-<)i%L21fQEC96z)o%kGQ|Z9E^O8XJj)NB7%59FjWhUuAS8G(A?uc1xiL<7z;qv0r z4U58b+z*YSEN-C8ZzV-J#9a8G%_-Iz7GoVdFpijMEp&UaK9UHTuNvBn!fG#%Q)lu* zHIok9jrXTe0v*^E+=00IeD3&p8p|Q}A<>3d0?y$%09#rY-Op@R2siW+S8aBs)=V!y zlr^p*%Te)(LvNlM7q8_fPr}e|wwTW}2j*GSQM}E#c zk>w9_PLh7*fB0MH#UFR@cB7WA&#tJbM*1C)(vqbIdLU% zjzv~|(J-stEUqlBWCI<(inGRr#f^&#b5F+&g^opqi$t0=YhM;%|>^`lrUCT|uDe^FG5zIb~1+qhL0nt+n;~cRG ziyYhZePeSM9gfWj$qB}JK|E&bmHS2!{Sj* zTztHq3Vrl(s9`ba9gFmKs4Iy}^ontuiH(QiQm)h`vGIBdsgGLhS_Avx*Gct8k@_N> zxkyxuJ zxx?Z!bK?>-LUKYzc6YzTpNdgP0FTM{Ha|X8iLB@u?^_B7Vi896f4X-o7loo!X&UR+)Zq&ZLBXI-n`h2W%LyGBa!g z{BMf20x3TvOv(z=mt>~ug;{zIg8S64rf5*2nYlG6(M+l7?ORl`Pc%oS)5pn1c6xn| z+Oa9<(0t>pS!gKw_&D7fcRDU?z4aJ+kXU`=>kh}TgxL6k`1mzr5^c5-BW|2Fp?AN8 z=SGCZBy?XUn^{Rnn7(dgf^L}(#Pme9OS6&^t*>ss8)lvdjaF*;yk~w7^`m;*Wm;=J zi7pWRk*@ZjYmP-N={oG$^pu=|h%M#V&*}EsFAjogWlOsB{C%xdW3oz~09gq$`yt() zgGe!#IhC%{RgL17*?M!eTg%N;(^99zPjS4X`6r>@)*5G@Tvnk6Iku}ETAa)TNss1w zs&G+!`IWYcDu}r~6t>z!9wco1E#Y9C5C_Y(?J_AMt5|IFcDp-ID zQYXicb>LR#q$OG7)>;ccB}Rt|$H$<*(6S@7#^ooM%^9xE#8^)Aia9A@Iwj7cwb^PvaUgqGE{A({#}0R?}&)2-DKU zlqkYHKa}aTd@)U@gSyTy05i}~eQCRpp2KL~srvDP#*YWx6_miCtn`z7x2DNYy-kRl zN;f+AO4IhwPti83**L2maK}T*1G(BOsvXf%B=fnf1S!0T!i1LO;M-bEexRwODClTr zZ9;r6XSbsx&1FooAZ4+7RFfp-NiVI+h)87apU;^zuXGjH-_QydL~6g8Lbc@!Qq-H8 zohj5qwEvnGBbu%KY%0Y$5@)-N(>YRa_Me*^f(*=5KbDK8oRAvDxYnOdV&1)cfzE2E zU1^eJ`VSp$!ftadb=YNHTt|)|)3@m~mB-yFNdh3dpPJXqM_P0HHl`C+2gQs}Ra(BTmUpOF7en5W;Mik31FJle;Y?-Z5-M_c`6e!kEK1l&Lcdbi&W(i8^@a zXVJ>4lrxmgb9J7e?OyeUcM?yy`LOFDy<-xK_?5HN1FQ5X?=+sM^5H&|sHqgs46}&E z*!-`PcvT@imBpMwIXq`v)Qg@~sGsB}^Cv5{>x*+I$M>Mdh(!}0^#m+M!VDki4r4n%idZ+9TN714Hxz9XWq%jj+q-6ErVMD#To-7BJ-Wptm2zAB^p zueW0`C4mo_&2-YXO-%BG2!5zERLa0r>e*5R#CBh=Cs7O%Aht)wAOK=}WeoKrwok@T zJ!1Q147DTnE@G%0w`&$_6Dl!#NbjDYRf63{(=5Bz6eny42jYasd79xg-L8dK zN4op2md#UpYvG&I<8sfWjbUSjYk6DoxCA#eOcwFL%3{qQ^G9lEs+J*2b*9+}Jl9ry1v%YR!f7_EOXF_uHW&^Ah zdhG4m4n>blf2}7oPhb;?)d#O#c%j4%i5E58Qn*cUF7E+w1~)2K2I-;lQkNO& zSv)%M3Xh911J^2uL+smJFVhX95_9OFC(x1O+!}QzXBJ!ww+vU5TUQ7bVP-56E5Xw6 zs>@XYhqN20V^g&W427!z7W14wiF*+(7`MUmNPtH@QcEev4K-Guh2Xk)uYemW3&A~< z3tc90NzBCDU%7yAg*byr7<(7Q%w;9X!PpF9i5Lvll#7TP8FXILasu<^l8gic$da&# zzF=cw9y7Tbu8=DzpbGgAMImP8l7wsPM;RmN@E9GK73*`C-c#?0n+qLFXu2Nf$okqn zqIEpcV%Q6MMSO>0U+WboP1>YtJ-ATYJ$W%E`s47=(% zH}QJu&M>4lV8X z{0M~b(3-aTI;=MIQhl#Odygw08y|aGdsQ%7Ovyh^TC9hCnJ}zOD+cX!zGKpfAY!!ByyW9W! zwOOjgqy^fwnTxf+P;Dk=uXqMko3WT4K$$_Y=5}rRVy$_oHl1QE?Ao-&T8mI^8pT@L zwW)ZZB@{C2B?As?({RBW1a_@e3Z6s>PSUY^KudD9vq`-%P`^$8sx0m_?m!A@hI%87 zv=SpNTeX@@725H6cuEUvs|RxQy{S3zJz{G=l*RYRED;Alc*-A7-)Y4;c>0PW*=nce zxDQf$D^Klh(%!sA--}=*0*I>paJRI&(GN%MNlo3@(4=<3vs~J~+1Ueoh=1VmYGXCj zgw%IulZ9SwoW$Y9ZeeOQMmn$R5K&jC&DBl;`d;-Zy?G?I@%3``>G~~bxp;84UT*1; z=KP1!8yf2(hpO0sdm%eF(JR$|H3*^w>Ver2^gth*ruOm2Md%vKJA-wsM{z!ZU@=drh-BOp8@;B6#?rM!MCsTJ6|`1U%?N zK&M6|4m85O;6lI>77!1S5vvlePdsMk9pQ(SK4@|RWG`lrSRXWr)KdUu3p_N3!~?UF zESZ+fHJNGnhrI|;tZz(8d@`G~Ti=)-XGDY~M}+V-a_s7^2CekcS^s=aU3Eh%?X$bK zMr!hQ{dY7>i1W7M#`knQ->0TGb%vS|hmv{v3Gjo&DSDDfpuUq+7UN#`>J(Cx{iTF& z+;!?kmPLg27)s`OMCeg2Lr+5MgC=$?gx&Z^YCM#PqU3nqe8@xsS1&%*KNd3eY{)6pP-hWay2T8_$xHCOU?eG%E+N_ zp)Trjyi5<~hB5kb`BeY4{T6gb*TuSv2bg~_SL>yOf5|-cM$vy%Q|A<#@W~|YgukAYLgYMT7|(hL zIx$A`D7KPE41U%hENP{HvDkgU79~W680|%v9Kt9-L(j^2j1UyO{686@XN z7-9q6<)NX+p!S$d(AZ$eBLx-mhzt=H8P!~`2-5{-lER%z@Dng4aFEE^{#Ox=14UQO4(Uu;!!}=*0Jk@p&pKE5njIh3rWaDoz9y`WF}r|{m|b{f$(e`GJj^512opj7(`V5PnUJONsv-Cah+W{9@nU$QaXV770OyMIH?6D%_de0J8}AfL)#1 z1}3+|JE~EH) zkQOS#1Epcv1M5bA@O&OlmaO4iY{}Z%L@g!Yv^H|u#8$R9A>U84Yg*9Rpj@sjEO>ck zsSS;G)>^}6K5K=|MB}@Jf~;K~`U^qt*|o!=)k(D1gsDE6=K;~f#@Dj5>9(oK+neYY zojaQ}sL{^m`2UZ+F9D3Iy565RGlYjcjSlQLk)^`L2FR!-Zt)5twzPxg=$1wacTSizH{zdh9nkRtn~L! z^zwc8oO91TcYE)?WoELub6-3Io9dSDj`H5AxjX7R+AIfH+*#!raWfp5Z(x9@1OH7= z+|Sd~B{GrVh-Z(M+O{nr-K!tb-vJ@r7I^w!i>aA85DXpX06Y8#a>=oHd+(A5et4Ih ze)Kyo{>8v;Q$QWL|6H=Y0evEK@^Zax{|N)?$jOaWvYnGVSS6g?TqS05!_#(7?!Xf# zH$Ca({uc|knaLeE@3K_xcqw-%~@hv;fwnCraLd;_1eJPQdwi)zazZxITP+zZMaZFROc;)9^Uu}ZYb#0 z%nmD{H(;WdLOZyE?QVkhi$BY_B(r}>E!=5 z`u+J1=yyCqGdFK}H#d48O>SlT&lPQ*)4Z46@(SJV+4O&9e(QQLHx;*KL9`b5=3d&~ zi6KvC{afT(Sl3YW2Cy;G2jyl$^NGtx$>=R7Zt*j3E;U_^+da{@yTHG<-dm^DH&3hW z9)|6mhudAjb{B|F3@xnFQ=e`$e{Q`oQDyE)90zPY#>)!d-aSm~+WL;yR_if7GH+Y= z8vmbMWNpJS{sr#iFRF@%uRzZ0GY|WkyX1=#pPo8qULWM{-i^0qkQ2^bPIG(=pJHsr zQ;a|2GYi+x*bL;EWu3fa@Jxq(kn#K>-!zYRQMhr!n|1tla=aLW*IULQiuj;T5I;Hf z{v-PQ2Z6+w#POAPe5FP!;kM0x`DLpYTI{*sL6!WG05lTcBl#aSbNl-HiLk#TFZ9^Q z`N0g|34$53QwDSNPS7)xc8(>Q_~XTRLdoOj&2qE1yv_#*IMw=M>2$FZCzuO>r zZ#xVU0U^wx4D&DxKkQ<{{LWql_}6`jyG{1}eED#{;N?R^u1_;|!Va!M_g>5H{Q<*m zCh`MX`~2TKP()W==A`~#>T_Nmayf3mv0|$?YHfM3>&EZySQ{)x9%~U~yzkC4SHG#> zUgSCIrthxbUXT;Q8hy0+0{cxKZQ>OxKHB_F4*$U`R(v9}2UiEweG$7^ahM}?8=Icg{D;2H#ZEyKk*s@cf(9M#(A z+r6iidCUu6yxf>MssESyoX6T0UdzN2dp%8EITNp;!tQXIExh)ScoJX!a?zReBs4`I2H^c;DYY5yUP|0MOMbF(g^uS3`q9S~GWN&}#V`LM)D<)J z+IoFp+kd z=y{tg2v{4*qVN;VXrF0IGGf>EHrGU6{RPo#<4qIg-Fbh2@NH@!;*jfir1Numxa)>;9W6xG2RtJm+*Pk3i)I)YS9j1mj!*$TtHNSu z4#VHr1KNnDJ@cQ+u@dg*rXpjl>iTYO%IEI%JshJDGjH^Pk6Uw+aF=ce`!fkS} zd&fJrPKMtMVj5CMUxxsBwxw{-3 zc}-D0R>lu8ZuP>`+`7BpJ{n&DjUTY(H{SC*fN@mBMSndT~7S7)XQ_m%1I zKk;BL(T#W04y{-|{){l1t67`%EmfS^Vl(n4CX+KUnVZASbyQ|Cv(IR*nCSsMu|{u0 zoAa+aH&(onAKdZC$mr1NfT$v)yxt@-L;C+u#-H)J-ZI*~BUGk~b+ytvHbs--W>aL= zrdff_tW8r|N8S&|tbBbsVYYu;tvYj5Fq6rwX){0h-Y?dS@nUjD_f6%@L8`g6Cf|@2 zuEUJ_Opor+>N3MLfn_$&gqgXq@#+q*~W0sOxW#Q#k zlLe@T=EP!7+-5;&&Zu<%;%_x{mS(EV5^JuMF>Iz(M#Y)_%&w-HLOB1(l4?%%4W<6Q zW@%mgKF{!+i7&*C@py(-}SX znm*XZOgP8oZbL75BJ+P|k(-65i#(%e{6lEi0a*X7i<}G8^piQP{Wli59vCv}Z7$Qg z$o*@zjH&!DGvOSUMXv8%?i7ohTlc1Cay@qG+TE5r>@D3C`S;{H;hWa`pUchhMIGs& zDAz!nR*>;vU3;aeQA>sY*X1qt)=tqYIDdqjndp6j9oy~Oz6eaO=uYY1TS4F6+-h+w zcWiGpZNN@3SGKp2-+FJ!lL4M|Gv94$+I=lW{$HB?TL*;G*MIslRO^nAcdyLe?%%uY z(|cZ-mwo1yQ*%QndTjiLOTg&tvNJLnSBkB>L;p#E+3B@>6}ydBeHmt3?GE+5($?Lf z+(-E~c7f4}9`(Q7NB#fFb6ZQT-(Go(y|q*H%75wn*t$Dx?iH-9cMblV6HVni#a!88 zGk<#>wPfGAJ8ZpQh}(ej0nOm1XvY0G9DG}R%Fwzy3~!;fyixm3G#T5zZOpXp4x2m0 zv~=QadWvc3AiKTt7WX?XIr^VGx3$!m?UlFKTRTOswC)c5r@+zcpO(hB#j$Luz>bpd z6mw;J8}qIAR_pGtb$8ghJH)>DJK4g0i(jb$8ghJ8az@w(bt)_HfhPAwL^C^|LVHb(6W3pbrl+GrE+FMl%^t;+o5}uB#oguKLMW7Bv4N6uyvRMEK3s z-^$0|sW=8a572Do3|E1Z#bwGSg9=}b&?LzD6tA+P? zn=ZbV7UlNJw|iRd6bI@ZwJ5jOPm8^^Q}oJzX#sEhWHh}JJsfR&;q9Ht+iTzASZ?p6 z*k1dcVy|uP#A$oSM_N={;t9WPY*l&pQJNre;7H4e6kAnsMxwFUlF2^0;VVldN z(zIiv|IDilb2unX;}M+yU{d+toz1UqJ=N(kKfwSU!*&?&$WoNkN@)xJE-j$ zKKaXl-*l80tvS?3I#gDv>CqGPL8G}vt`8bbCgUM}Mn*Sc{?GL^quPwx@C>9Gjq&}h z{@{SU+03`r{xRR?8V&@%+(!E+_^r!ndY67{kRLyurYC{s;CB2B{J*jp)m%Z$jo@4A z!khN-3R&B~id%U8eH@ngaln3D?(5g!)EoAduiYXa<6WI10I`w`;<^i(xVREE9^)W7P zmdJ@D|XGU#u9t9nku%8av`utc+LQw=vW7-6uK7H}{Ljt;?K?P?2t;my3A%9FVTw*z7d zJ#FVLxF-E%ZssAT9pvf8?{IVbqRfI@br!scFSy=tA#dhA#G82=aNz*52BZokyqVV; z@OIqHYp#cJ`GEe!<--PCK1k2%<-^X_vELBqcXpGkx&D+H%bR%{E*#4KJj`5 zI1~4_#n9U)@^MYpaq{ok{8ygeOeVXH|CI8d-)Ac1(bSUu_PAtLV)0~d?LXV2pK$Km zt;Cmm*mDzkHHq(IQ!j{>%xp7Y{~<973x2mX@d2GvNO;V}e}BY(M;t-FiIvd;nd^KoWaS zN}M@KEs%Xc{sW@?ou~45bKc0k)_d7|?i`L29{=To(D*ID zZ(7b-=jKc}r!r^KjB_Vcops*1In&RWa)z*7Ffm7F*!Ia8IsE9+IhAKjJ7-4Kc(FeB zyegEaqHXKnPSOLG?Y4_2cIntPXU|UUlWm;N-Foy+9hkdU_O4lNck9x<=RtXc56wTg z*WSB#*khml`t(0+NI~EI_dTHBfT4#EJY>)jN5*Wco!d3OOUFHPdZz~WIIvTDz{?V?#edZZw*GE#$`uDDD-*;k<_VBaI4V8!Q@{^yx((bfjGus`vtXI3W zuRm`uT(H2t%pGQ+>~UvJoA#$qYlC>&9CYEKZA$Llr%hIyHf?@$;-=)0 zKYk&ZTK!=1_?jD&XhSk*!zIa+KRPS9^6|3dF~f%^M~}@<9&PtXwmHg8qW)y^$i~Ex zTN)Ar_kS+&=p&CLIy`fCV%}jlC7#>mXNir2mnPn-yEM_$n~@k)e^%m^qH&48?0r&V zUcs@6=hKHL&{v6^-49IU58gMCdu5lzqbVnW%csQq?Z1qtM}87NCOw ziN5u5=j12ieQWFDS$X%xzxV3eIQl34k5$*lyF74B{KYSS8b5ICgcoMXJ0%qzOsH?{Olu7j_?1(N%5{{pBTqD#6S7l(eavwBjPVL z92)QYc|knUGZlYk!ol&xef!6I=H|w4zjp8VLH+iO=hkP(bLYA7^&_2lb&ehHXeW6> zjepYiYisVlTdW_9_{_?=xY4?}Zj-fF=l8AKroU^w{nlI7d8fW%*?)S~nl$reYuMf| zSSLSSZ=H47Z>_xJpR%TPf86?H%Olp*hC1uM=N`0{{r-OI(U;g>xF&FEzBS5r!^;8v+Ikkc$Xrp{kRjYg}08fe)#v}EbpX|R+rnqXFceQuzq~r zaBIR#!>nOP9c5+L9%((3dxUk$RYR>iI}foQNgry>?L63OSUJ$D?=ip{aeIGjz!CXY z`q`8t>lf?xvaX!j%{ug$J*~MNyIN;8>~8&OZ5Qj4%d)MxV>?@y59nlJ z4O;P!J6Pqv-_2@&=dMC)-(0n_b5bim=c2kn1w&wd9Sl7HC1A^nfQ@hxe!iDxC+mgUu*^xoGv&|LZm z=iH(zSmT0uZVW51@NmX3#p9^ebJO&1&gYBr6i(7 zmyJdB)my9?-4<2T*TVVB+apB7SAu^ysCrA*H>kV%##` zRL_}bp^{Z_yrg>7T=E-ON#KPV-y=23AD{moI7e&Y{AsmS1Cfb#t)mu8xNG++ZxHK$R zCw%L2VJknJP`xF4MyhE@&3BSk_F=#6vtLqOiy5~tYe{u|Ti}Q!2zq$o2pbxg#DSy} ziHlC_LXwU4cPHrz)jlNMmsD5oOOmssx@ag#FAZbKqE+3{;-y=#^INhg)t&rn;dOhH z$57XjMU{uKNN)`00tiR+K|cvWhoS2rDOgfnBV;gQplW_EoPU>8H?ZrM=Af_P{AtR2 zi+mM>S=vkFwNFvrN97%8-&^F3taSc+45qrK6XktGUNMC7O(HMsLis9@ui6xkEx96w zDYS5YqiAdQr1l2UR{kX(TexB)+s8AdB_R@*MQ&QJt;j0dz{S@Ku2--IYkNt{#qwt)2$lp^N zi2+@U5v<*hWh<5MPhKUwQTT4luM)mMcBTosh6h2sZgYcnhKb$s&!gGWlD}2t;l#ddgI)=PR<@d3!(ZcIR zK1O)O2-=Jl-Y9&c@S5*YK3Vxl@+oR_EP0jiLg5!GKaTQ?g*UvxKAa=G{;$%X!gFTQ zW`Xd!zfrzecevR-7Oew5B;W<~6-ypn5{NE(J@u!rp z5nf+QUaRu!$kz$4`$`=bSOeVl< zRK5@Sa^dbw@|D6H29RGPykZ&4t`c5&IpsG9uND6{2`@rZ5x?*`9m#8jH)3cJzwn&P z$nO;%!>}QK;f2T1KX(LJJ6EtRN#PAwlH0-?|48l#uUJZZ?)=f-x#Zbu|2l2D3a`0@ z^6tXxe?p!kJO|4X^I3S^YW7cW;f+6}ypP(?Cr_yy%N55rmA^*+gM}AiN#pn?y!L$h zsgtotT|oY*@J8WJ2+z5Y@@JIq&$9KxD~}?7L3o4Mydr$gk(9r#Hp^IVgYej4ly4Ni z>LU7lPk7N_$~P%Ln!HhM4k!Oic-@a^zeRZM5X!$+`^zb>)3(TZe^lEm@+XAnJVg6v zgx72!uNPkU1o;cfafn>F^cCg5BY$1EJBYkNc}v=R)DJYuT3JYQLQQcC7F^k&hBSX8_9<39nC)k5;+IvSWld z^rL*N@WKM}3gHz8l225*%%91^YY(7&it>E&O5w4-iqYm3;q}5_SN?aI55i-)wAm=U(IS6Ocq)f{lk)w@8-*8jBmYde`zifw zQJb!me=WSeCwVN3@f7Vto)li6Ah(5Ab|-g)yBpXpS9p!^Y~h6uQ{Gj0h4Aib{|Mzd z${#21CA{Xh3vU$p7~$^k*jHnP*9)&uUQhW%;YBZ!PZr+zEcq1Sshi0w zg}X14R|&7Zll(&A6>G^a7GD2*@;Pe%Jo!A~sh7wXD1U)`vG6$(XN_?850oz#zDndP zh1ZJw8sT%wId-dr7fvL>k!ebTWj|z9?`1yqJhEpkjMtKo=z3^H*A;A0>UiksXUc&1(lJ^!~|0a1K;kB=kr-ZNi z6M2E~IbuIp`FoTP6<+^3d7 z=TDT6Rr^1aR|t=NKt54;-N)pUg;#z^K1Fzg%=1d&tKO!(N_fqE?o;YR6qKW~OjKxLkB9Id+ zmn^D32W0*=G0fQNx}Q*Z@sdRiM^U&+gsExZOXrX;symnRXGC6GPWe2Qmr-6X^3-(7 z7l=GnN%=aF*PKE*@3vs;#j^A76?uIH<@hIdUm*kw%Z4slQIEk{I3IJA7pCK&e;JpQ zl1rV+l3Rq=PbU9bttOE>^j=+b2DvNT%^}Yg9y^%4tMFCqn)x^r!9JEpp5!1^R|>a< z$MPw6gx3hq7GBh!a#wgx0eM&9tAuwKj`K3)y@WS@N!~{}2Y7yO;jt{1O$o0|k#7=S zC%jR3s*3V4!YhQ26~0P%1-QA(u%h0k=ZT`7a{)_D7G5WON?^Hg{^AI)5u2P#XrJ6w zdO)}>yim%{6PuXu1;UGF(7sZ5jqobr4Z<%}oAYUNvG7&G=YVUp7_|tGIiWlm;WjwN zU+zq8fqh=xr?)PAd2QjRw^lzepHn0@W4A@i=X3Y75C8$?=msOl5t(ub3ahsi&Uk8( z+(SFIdP|!QKYk8Yi{@2h2F0vb{@IXMw_sk@O{haGKYbtD15~$g!-9va-^!|fd+@Vg zw0mmdhU&Mh4R6KUJ+)wYX#3jxtHt&w%e(Tl7*%b0f4;hT7)9T1yW#D`hA$GCr8j_r+92|P$V8J z#135laA|;wH6-FPsOS=oq24&L~P|06dHs#ep@)#1jbTZ3nJ?Y6}h<~EC zzN`*J>q~ileeAQaeAs97O`8PcA;G>OX2r?~*k*th6B>jT5lk-$nrLvI)IT2l-a_J} zAmZkd^bir71agP?o^qFn8wHeS6R%M25_!Lg_C(z15I@8f%7dO}ot;FM^3DQYfMmsr z2#b^wSPD`<(7lk|TSR4qUP=jcVaFhoWds`T5)|th zM2Abo7%sDEM%c=Xhb;NS6?$x#nh~}#!{Jc>hC??>%?MkWxxU$n(3PnfVJow2-)szY z6>3J<%B-tzhFyIOcR<(#UsR3kWhx?QKL^@X5UobyEFfN|+$LVH+#%ke+$G}H7wxl& zhb4q}Ck|1bO&qG+B_6KaAs(UJCLXCg=zqrYviMFXiF-niqtHRdG;%mLmXA`-@hukIpLb*fy zrE;5iqjGrBKgRMy@tsZ*=R=Q9A<#6^KM_ltmPmlxj5aX^!0Rz|5kV^`X<9+b^DBtQ@;twWcr4#z74#jC_4oWb;;{nH zuOuED;Q6t~V}m?aq3s+T>LNHR#k=ak#T=aoCe7nHlix0PoTZ@`%^5vzJs$S;tA zqio_YmAk|nl{>_nl-tCcm4~AWhnM1v%TYZDy46V0Q4Q5enq7uu#Yzc#a{2 zp}T2T#9c|~4)V}lNz>?3!7;{n8;_+t`u!^smkF^mLgO+a<_Yib5x+0Iz$2a`e1Jz> zBz&Mpyjl1lkH{8t5AU~}burdgM4smnKMo@ggtqh*O34_lTDY&-aLF;dvf$wQ$TD;9B7WJ>mx81A_kJD;Cd+ z4995TbINVv^U57!SGEG3x6&HE?eDRqzn%*TF-mUkMMP zzH6>Rwn5t&u0p<@(!;c!n5*0-_Ehc=dntE`2Pn@bUeI0owkz>M<=Mm^DR+q%DR+o7 zmD|LNl?Q#!Sa#W6`~0cB(5cWzj-U~Bl4iRh;c!OyrYrc)=|yCcKYJ z6pD#|L4p&)8+)pl_%;&6gy*}dnD{ah!~_ONCt;w){@8_qraT6!(dBtW4JqFvY8?GN zqE=qu5w*qvp6{At$G*`13dfEw6kTfikT_SlO{`Y#5TDpbLUoBxDtCxaDYuDFD-Xtk zzF!s}X~CSm+42&?SxO0aDkXfSlrS8=U`tq{l<>Gxzmp;rBx?e7(1)QK$411#iaG!N z0672s2sr=!5IFz+7&!lZ*X%<^pzRF%kndtWi-e&}5}#9U6Q5V^5U1>`eMmeZsW!Vi`D{SqmZEDF>?zl7?PN8fbDej(DF{o)s6ztFqJ zRp9wmR6;gYY^##QD&;nDrE-UOm5~##RvxsCJ}wej%3Egik+Wy>>fq?ccg7Cz7;YL$aL;&_n{_K20jQy%d$ z;dvhMYT@}F@ebkrJ>sLn3q0Z@oGLu!5$6lf^N2qap6?NBh4=S}zY$*G z5nmNPz$1Pve4s~6^wd5i?kaq+N9-;<9`Q2a13co@ z!UuZ9+l3GEi1!K~>=7Rqp7MyV3(xb2p9s(Qh*_Ava^eT>B^>h*m=Zp~BOW7sphrAe z_#lrsN%&xoSS38=5f=#0^N807&-aM6!qJDoM}=b^0$&k6z$0!FKF}k^Wa$m^h`J2J z1Mb~eL*r%6req!HJk67Ns`Dsc=8=wbe;H>ThXNS~?WX|}`#05d3+fps^`w);c9?hA zz!BCdC7gy4hm^1jIu(>~w^G6cGzU@wYXb$5KffV3qL0tf^#;o3uo<8PwgQyEMt~C7 z22cWr0FsYw)@A}aIU6a-e~zNiAC@kl(y5>Hod6DKHlh^v&l#MMSlyiU1I zyk2<_AbnpTvalf$Su=Ji@29Z$kRlD4i|jlR1>HXr*{hK7z$KPd8N&eTUoB*7k=PpI zoyu+EUCJF|yZyz+CGMi!A+}d;6CLG2l=S@@@sU=99w*hfF^!yGBbG^)_y-cE5rIxY zqw%WGlt)LlsDttPy(t`zP4i2{o`Q^~aXgps|Nb1>1>wFD+9gBRrG60?E;@=EOkiLq z@{Brv06&ol z!7x-5ObB1Z39$?w)`^$&6u*@;e+!ALgt$WV(}G$;{rRH5TJ+(B2=!A%f34`J2IbF& z&##d1G<9MYi3I~IR!-1Zs{Bx5zU`ifCCkBw2NT`S_epNgx$_pdo^R`W>KvPzG^Q8C zv`DT;-;5(WR8|Fk0vCR5U0GYlufO>8%x?Mnp+2AHdR^e7CsJerv5VeiE5bQNKexat zI+-s({^HD%jM$h3ox_h2Y>=W=N#euGZQ>)!9b(RbGF4n+59JOqSGi5>sXXxgG|D|M zK2qM_f%`%qxhQxSq7RWGrwWQ_iP7=9xdqWy1*MR$${pf$%5CEH%7gx3osP)Tf`#BXxe}HkwZ*DPkIl;Um|@xIi5EqmlTgx0BHh?{ zTAG!%QGgznBDKXiRy;6s4N~Ml<(HD9l2PO8b)rA-PJrwrDN(N3g8$Eq`ZX zX@^&9j_q~q{ypO!oxg$P8qo!!$c3f|g~y4na)JgGjKUrebrWsrK7d@M1XJl`zfxNE z7Ij$xV7Smyf?9@$G=6|+Es~5Z@J{76@h;^K@mI=S;+F@DeJ|oy%3b2u${ph0mD|LB zC=W*#K01pmEqDPq`kt^6Nydc(#mwib^Bcx+pOjG2Ng~~ZBTEmrAj#aIho_NI55f7y zFU664->9SGMg50Jk%P=DM$|FpAHuOI)x-TNc(@)3)&$lSohE-p$uE(1K}jCF^Y_d3 z?lyLjwVel10TR3rjF(_EPlRl=s7nc|4u_C^Z~+p}kh6e`ks^nGs%NU&BF-0e8DW{w zV1Au}>{+TM{IIE(BN9E0uz#NyvtS4FJ7nuc6!_(b;4CE0F+t^a9GFn<5VMrK#7Fvy z{b1sw%3b1blsm-7l-tC|l?QW-bry-gbnF!1FAOKPg)QbAp$aLOZ_F%G-AVvmVs6E< zurbID&dL$TNjg3a35Onnsbg$dM+xgV3@MnAryxV;C=#h-Y*uDn9x2X(RuIE?B!)5+{Q4MQbjI@i< zaCseLYKSba4KR5W3H1|9{iFT*-+*kRs7nc|4wsidn(WNo;JiChWO-5DURpHGBJM8g zGD5DW=smS0FcWrVMUW@tG9qsxnvWr8>fme)9BD?}8OtVi})BrY%FbINVv^U59K zOUhm16^DrZVB&J+F7cyorVConf)=|Pbc7dN@c^!-lonv`L>ey;|g>|I7b6~8E3s2c$ zgHql|<1o6s_D8J;BXLF$OOPVV>%dTLQGJ4_gXQImnp<9%&Yfp_w5Q9=lAc((>}FYr4Ex+gPON^6Fx0h%B!(OqL^Ic@a$g!ScEtvUQ>^ zC8#=FUjAsZGv9!IlbZUAlj_%yptgvA5_K72v(R7}{07-4RZDofsg@Hky1Y19`XfbF zb3bHLA`1NSBjVR1ad{DADdD|{ZIlPg!bQHbkr6AE_ae?Pa=&GBkiXQ(h;x9=V1RTQY6F%WZx1uczqf8wsM>Jj&g^% zd!CG%OWZ@bL+q;DChn;`sG7dN5Fcs5j?iPB6KEP)@)64W4h}2P)Bz~g2D{-@t2Tt>G+(%;P67!UICFUEsZ(E4`QAS1_rrahTque1L ztK21C)n9yfCtj`GCH_pgL%c@0P5im?pl?{`C?pIJ;fF%Y2`kjn4=zSaRhRfOU&L{n z4s$IM-WH_!1>z>W6-e1kk%hPaC|e-1@RlECi$zu$1nbx9+edEARr)vZA{PO^xxrQN zwpu*mp*rw7sb${pfO%3b0Y1=_vDFO|E*uarB)ua(=xzbg+SW}R!0(7lAGg_aZk zrj|jBv{ZG8FY`t0-sfSiMZ)f-`OD%a>|V-V6Is~3l)WdiuzM-nB(kR6>)UT%_r?aG znMj=Jg34`trDQCj+#zNucZnY>?@eqpa^fe-9pYx?Ht|#CLHDxGu_D7e3&0vA93lyC zBL%mgm|@w-;gdykk+2I(5?MUFNkI>9Aj!U%H?Wx5gcLcD`K35Ktbl5Go9GYU&yl}g zij>_5Sfi9+EGvA=eITQ^$n7U)`yn;G{j>_w+mW!7BhVM9@9Ios&lXYXxqxX(38vEE zh6ODz6m{7=z;dCb1huU4UE&TZsz8#FB`UXx3FQtkOSwzT86@^O#2(6BVy<$B*i*Sp z?4>*$S@@VJ{?dYXf@AauonabWOE9xHQgmct(@l#eiF6Z=EIqu66kPFqgp7I!PMCfv zj;vonbY%BH5qibrh-8-EO)PX2Qe@M85VAv%I^xn-FV2H&@ZUrHyjl|&0J_)r6&nHB zNTlelJ`A+Xx4RT3^N}zC2iben^9Z$LG>F^m-%Xb zlT@CDnk42cw~76gJH&y?UE(8yrD+AkN0qz8-zay8k14l_k1G#m0_&V3{?f6_fiDnLI!#~}stW*jnUBpeYUb!>GN z8`hEXu7|NUE?wbwXxN~X=Le0M7Rks^nng`wJ_`ZiGq!{v*byNZ5w&$7R0BjEbYMNQ&m!^2M|@7X zO?+OtLwrfOOPp|+&UfNOwbO(bYY zFyF%lr940A=zQNFl^l%3`A#fBip=)|L$yWq38D^$%NI2_-}SBy?CCOdzUy5Zh)+iH z=er2sgy0<{OhE$M9i8ufeJ#y*hR5of&UZ@3B1PvrJ6H!XXiyrW6-b!x1g$@u?`t5l zWk`bg?vEhn`){EBy_62-dqizL3Dt|D4(j8VCQj8xCW+IO+r;V09pd@QUE&+cyAt0t za$F9-};nnBUo1Y-Gf8=Pso2ywG= zoA{}6hxj+;E^*OO+__fO3t5Z|3cJK5${pfTthQJI zElxd?v(nuo&&nbtvRTrUa3Uq9WTksGUn0d4jG=8T-8-w@Kf^2hh}(jQQJ)N>u)dV{ zI}>5_l*CwOXbUDg(04;>8=DbJcSShskztU5AZGp|rKW_XE{LUbGD;ai(^9G6StaXU zfrQCdfSQg%0wqjU$}a7R1nCICc%?D($KqE=@iG=aTFR6W&QZ$ZXG@u2WwT5!wC!T) zduL~*i?X_Te${fir+@)eqgccyX8!!*=*7arV0I)DWn}HCKJL}aJfW{O;7rw z9&pF5MET6Q;wz%%eOY81$}TnKGbg04h?b8GpI<-AvZtEV?<=C^DcfrNY9LA@an%!- zDYuDND0he}l)J<)m1h&bGIHYA${ph0mD|LBC=V7r>s%|cbgTjRSEROhd@OJ4F!MPQ zjJ zI}S`JcZgZaUE{>Q8wkKzhR7 z&@Vm**-J%Tl_btpZWF7OJH+|QU1F!<+I(VXxkK!t+$Qd>JQ=O?D)E<&Z2@+G zzG?FrnXyVnthQ=?XqEE5Hol_Gr-$2-IQpA`^b~16zu~%v36Geo+$Q!^?hyA^?h+R% z&n7N5a^e!@4soe+n|QhMq~CnjdAP{ZvFX71NWn5-W&u)U8AR-pw5Pi1G6=0w-UY@g z+7YbrL?m{^IY4@fEQ1xl8P&+#&9#+$Qd? zJn44?>%3X~rDHa9`yw@+2NA1e#A>T~5L%@?$M}jipY{A&>cS^ESPxQU9;A@XLqd@x zF<-e&?62G*4piZQ}FF9pX#MU1G@y>8`HCla#x} z(aIfSsdAfGraWjq>-XDR+r)EAL8t$H<8rl{>_D zmD|KWDG$1Ybb>X|jpr@zEwBye+9EHTCK^&&sCLXQaA&yY)5nbKM^&S0dTW&oA{}6hxj+;F7eWlI{L)9%3Wf$a)&rixlO!GdC+{;xr@lK z41gCSh06e$SxC`k5ZWhcPjxfPAh5zRFjmoyV2wSHWElYIDY^`hO^X`K0Ju!KO}s+6 zLtLTUB@Q`GJAyb=xl24;xkEfcxlKG$dC(Cx@Nv8N!!m$wFjCWb5V1-|thSm5p%s>a z@fB@8>-n|Rg=GLeJw@h0A+kpy$ua;AQ*INFR_+i-D0hh;D(_0%WaPxZD0he-DYuCq zD-W8_I>(6&%K-QuQq$%~tdbF{t(qTNVHp@-(dM(BbCF~j0O={xe12*7C!)qO0B%-p z6SpXLh<{h^5<88O?ix(&tlTALD|d)pl-tCv%9BJ-`C#HI<5nyD#}Ng+7l^{A+w_+_qYy1_7D-36HKK+i~Q2)QaUl}pwe2%)*^A?5bsoO6Yo{- z5Fb?T5-Uy=`vT&4#fE6N63+@9Km@Wi*i_Dyevm~7jMZ(OXPxVz4@s*^{TyaoDP+vhm zzl*^Bj)d|AjXQh-_%USd#eF%!sDqh9H6y^d5{x>Scb^98(ug`3#4n7RGsh1eGiTzg zpeItEA2Q^D+aDP{<^~&QY7Lsi;vAdEWGh7WC?q+~0*5KLiN`8;h$kp_iEm=h3;P0M zgL0SnmU4&qwsM>Jp7JE|;FGj0v5#_>*jKqj?5Er&9-=&$E{ykPi6t%glK4)KCcch@ z>GBR>cie;Fv543WE-*(3^cI;e5obv{tw+LehrWs;zLNB{k2okIsIQ=JXQ1p7El<$6 z!`De>L-sRKmlKRSm@ZT^0*nm7sDp8>4%DR)bue8P8a1bjA3UeaKZ2e}d49-{2gk3! z8a4vaLeKxo5*xYA)AN9=|UW&+$J8T+#w#W+$Eld`d~kpSfSh{j#uswPgiae zCo4}9T|7T$Sz<@!F0qqxhuB%UP0UsvOc%y`jl_}`EK}bx;#efKd;;KV5vK(caDg*1 zf!-n~<%qK+oj#6)=@R-Xiug*>XIpVlL{MMBbU6cM7ixKe#vLx?^B`jtn9c;F4yFs$ zmx#KYVAQBk|E5E>NYrHnqYlRPN04c!q&z=(Op8(Tf}Tiue#npq74(K_~P;;?yDLDz}Nfl{>_~%3Y$1hZ-{cz>dmYVkhMev9ofU*j0Iw zxDQqj%M$lh?hE!PH^ADmh_=hMVKMSM@WOMG9sL;OIwP5e-KF#N3Z4UweWVeaBj9}F0a{c=mWb}{C55cH|q4NTDc|={| zm-f{hIzKcHov-K5M16w9P9|zH*ybq&((uI5r^Q>s*e#zBB8^h;Th8;aXJz@IkXHqc|T~5QY}I2Ob5M~2iei0E+-gu(2D~o z6Ll%UsDmN$)$B#T?r1O4zF1q4B$g<*i6<#{h@+Le#B$}?#H>luqdCO3%Cm{Ka+lan zxkKDVxlL@ZJm_70NoV#v@L1gb&(hEh9gvb2ss3;aURY%es$)>{8)dNUGR?aS69{}2-9D}m1O za?bMEzWxyiCyINV81?UYh+ftr1XE;XP~{L2_X}V{)Rx`9>NZyFD4lMO@V$-2=^9!DZ%L11o|5EK^lpN6XG)E zHt`DO4sp41mw2V}Y~nx9m9o8vvGa87iI#F#P`MKaCY0O6r1D_w8OuXR7;wVh)V1K( z;JAM9M}?LfMN~p7I*Lqq-w%hLY8J-g$H3~J3-gYqZel0pHnFpEhnTJ0C3aJuP5kBg zGT|F6k{gjY;fXgXcZoMEcZjzrw~4nZ4;sy29;(zv16D$fIk{#Q3GFfPeld|p8?kzZ zw40#iuoOsGN2EXeDxyo_Rn+x{R9i}53Ale?mhb)p2tN{i5y9wh2=tpF{F~^@2uA-( zp#Ks=XDY)eCm8+f8TxmoQ(xv+nGL(HQlyArimVHY^ntLy=*tO4e{Y~40^u;x7ZHs9 z(Li4U;i;l8Cm8(`8TyH$FC`fLGl9Mg!XJvhh+y>ffqo{0b46cHF!~n){d@?2BKlH- z(KiJ8r4ZJLzKCG-8w35d5MC$xa)Qyn7wCTp;Vq&sB^dptKwpb7UW>$~PCWPm;Wn|4 z@?cgz2>oMXn@$p6K*Ee7ysebbsFd&zr344QU`yCbDIpgrcm&MM0irANN1rwR7KwWd z;%i9QK@r|pO88tUp^cO;CUjOx&>D*gdm{ypmY6vRDRM_DtTE;JHS$Ze{VMq-+J2q< zj$OY}ez~|`E5BTvb3MA0<-Wo%$sY&5-WU*fohc<7h3tk5OAiX5|j?7UeeaR^`E(VJ!5C z(-+~VsusKo97j5WsZmfpg!?#ps1ef=mZmy#7^imMiy1Gzy%wtLk)o%yTIAP?4C@5BP!bL67Nx-O+0X}jMo++2O$HaY~sPnU1A^Q4zaIto7hiz&>0M-J7nk# z0@aay9JTvgDy<{XLiTZ?X|Ru@=}2r>q9?CYkUtFx=SBjZXYAu9K$sNw<^DvO4$%c# zgkXw<`?#49&K7+!!RW(%+#(1s7kw$g=)-;76%bx2`eK67hx@qeA-qxar39l7_i?vE zc!%hV2}U38I9kpVQ3i0+jlMFdkM z+{Zlw;q#&|Cm4OWk9!Tmw?$t>F#2#Gw;95}i@uy-^x-~^`s7cf#|cIs?&JOjeS6Ut z5sbbb#~Jh>?ZQ?UV?ziPsk0WYd4)*-Mkl63UbC{1+ zH3~V`D2UU2gnSr;cc5{WK}!+nKcvIv4=V?ZoXZWB*Z?hr>ScZuc7 zvx&t&m6|>iQi2Q*am169yTsAT9b&0+n^>kiIK(lS;gI3DPM|t+PNz0kL?r}T$T>YU z4bJH_eFrIeAo~>ggRY>*;GF#xM1K}haBN8|!(2e(?GOM%$T;(NhHwwj7ZZ#=Jk585 za39f^64*WH5kX@cp3)D3K|irACK!FVCCGqNZTDHtn+ z;Amq&yiE-nh1_lw#JhZjU$PE@$BY5-#Ot)qILY^sBwFBTU*VUmfMC2aAfB$=CQeZ9 z5GN{kiDz9e4zr18D|d-MRPGR`D7T5{C=U-A@Ua;Q#|gq@sH2Arh&~c+3AH7n4UZBK zQOq-hUzq1~I?;OaF$M!^&;qBg!4(qsm?4bIP-c*|$jZx)Zx7&nE7!+$HXz+#z;VZWH%Zp7c9`vAlzX zekQb6wIGY4=LlLVe0IuGmZ(cug6c>g`93-4e0B74GY959kT}nXxyo%~Pvs7=mvWbQ zfbwkO>f6jwiR3yYILanouiPcxpxhz;Lb*-+rShNy7)-lcr2_~npvKAYvsomx#|FtS zCUU>ySnd~6u7sfFaJfmsIwJkyR}tN%9f2~#qY5 z_j{C1o)jk~1UiEL>schL?qIoM!UIa*0UWoM(h`E!GHsSe!tf$9ijF@*;2l+oEp`8TQlQ9pe|6KHC1fvi4_8&s{vFJ+)MjuWp7P|UQ z`VZz|0*z}c?JOslBA*5GumgmhMPEuV`YnNeF9`P)eG$Rv!>NA&ga?bhoM80f(&-Q3 z(V{OU7=2AJ&xb%bTl7T)qYvltkq~}Q^yLJj59e_u`fw@|=P_}ba+^3^xkIc{?h@xJ z&n7y*lCoWiyDHBn?xx%&c2MpRUF9~hqw-)HGnTLJmfzFm)4imD|Lg${k`aY7^FC!RzID07^F5#8=!$cAL1$`oD%7iQCR2Ym$!tsP) z^x=v*2g0eMFDDp%cx1m6!Wz*R6O2AQvR?+_a?zI)j6Pfu3n5%0`ci_?-y5u`LIi)5 zHXunHrrahTt=u7wQ0@{(D$gdKQzx^d#v(ZviL--vo^qF1soWt>Rc;ffDGz1`gPDVb zDM2{kK^ed~vq>so3ps(sBD032PLWb21eTOTIZ4+Cr0WTTl#T=R76&B+`okQX<%N!e zIY!5H!b3T6U-3{v7@;&~{&JC}V;o8ej5j(lPeQ&N36p@p_z_`vq^AB%(U%d7KAZ%n zKzN$yO9@6FPFxn6`H)oaM>Gwh^QA~RfuqAYN;JhAgQNB=7|a#hQi9QkbND9^E){(- z!RW(vu>!)YMPE)Z`tYcJ9fWs^zLa3};kvv9!n;LZOfdRz4&M&peWEWX7=1X0=b%xS zY6FwRYn0o>pBs71{4GTO3X!Fg#GfHG{jBAZ&`PY0RZM@;DrWvdUn$S`#S1uEYrWwG zTpeT^kT3{I;-8e;#6K$!mcf(AKP$3ylK3(brVimvq~Jbr%>4ZpLMk~=LnHHTG`9Gsqb*O>UO@ctfAg9)#Q+zmMUATe;_BIP!5v608j-`>dYFS2x!Sb&6MIboPm zLXlF!IHiOsN(nQS66PWWcjB4(vFL)+Bx~%8#HJI6h`N|CQYoQaDd7yIgy~8NT4OQc z5~QGqnfVD4dOzAmtuf{KHFD7XD%q!goxBt8SIRr_eyzL{&${TEcjAfKm*JiG8pu|N zzA8x^_%II|c%y=35E2K3IMi485mrDj$rupZK4MCe*hnl%+|^h3C0z(Q8Utb{_*Xq4X?3 zmC_3V)k=R1Sf+FZV71a;0BV)413aYk5y0=1J_q=t(zgJclr{psQW}kgK_p}8M`w9t zj03r6W_e@`1-Tbyd1Qj z-#*S|zjd6;e%m;g{g!bq`|aXf_9KYLhD!Y$)_Cl2&#z|=^7BPjl_XyI8#5zGRw8jm z5`XS1{E|1p`Yt3KMeYGStn@L!vr1nCG$`E&_*m(ufPW~B!{x3>@X!&^U1<*BV5Nru z4pVvrV5HI$0ArL!V_^{JPK*y3<3JAML&i{$!}yRf8ssoOWDE#7j1L)OLJosM#;}lE zH`^m)WXL@*+aqIe*eVS7NEjY6qdXD@h|Fk@WUOY!dL%P7Gtnc_9!*aP#)3V{*g58Y z8#v~VLB_Z_=6?Jfb3b~HxgR^n+^>ma?pG8Y^Hr#PH4=xGc%5>ac)fCmc(Zbs_|L~= zUNl%FvB#ybOSF_bg39eUFrhq2w3&|{OJ0M=KOx~*@&VwlO1}Uk;T}>O&{^pofLx{f z1M-v(02C@64*0&(lK|tCo(?!i=~TeQO6LF;DfQnF(HRz2^qse4#yHQMur@YC1eZ^Im}fu#)ll{Dj7pW4s(@kndUH8 z$?nx0<|-Mx9ES`7dl`lPA8YRdX6JPF|4$}6@z9M;$C)$|)T!-E&Ip3gXj5jUnVD#! z4NcpWRD(#gnasqYD52Q|p=u=(r0Nhv#5p8yoKk`yDk>!oZIvMPqSXKUx$kE^&lB}~ zfB)Zgy{_x_`L5Hw?zPtati5N?Axhi0--Wv*u8_Qn>m#q?>d33OHu5U2jJ%5LBClcu zHUbfwd(|a*>xH2;JN}Yc*Ig;b}eGMjMpf5q3bfd$aMmLS-@2 zuTX5c(g(218l=36`(4PZxI*$Ou8+Kmt0S-C+Q_T8GV&^}i@b^vkXOvlu@>{HUgZX> z(+@3*eOxE7uj?}0&vgaf_;{Kch?`{O6};JX8Q$VLfeT!h;2pA!@~T4~XUKGe%oKvl zxx&pZZxilw`Jk}E0P*hT0p@>E$0 z5LHrMp$2x6vT&ICvd6jGJMo^1s?dvG&K+h$;c~sueg&@A5|B zPM7xx%U#C2A{K(su_&)l#G#V%3PmU?DX&mOqmuFpML;SkuTaFKlJW{gSSl&6P(-GZ z@(M+8Dk-l}#HW(-3Pp%2DX&m}^pf%l^}d&sS17hz=>ynh4N_jk{VwEHTp@WC*GFE( z)sa_mZRAy48F>}gMP9`S$SdaOSc`epsB){-O)S9+WjgkCT@V+g4RPCNsC-#k2Y>#A z=SWw?1ep@71W$_%apW{roRfBdW1dV$B94(CD&F_>s%;!Y^H(A^gVWWx_m{#aIYJd85Qf5r;}jd=#Om zq{K%NjY>*<6alHE#77a6N=kebVX36VM-iDyN_-T-siee55uZv*d=w$7q{K)4!AnYf z)G9A2@lk9uKQJz^%NnG_kNd5L&##cgkLx4xmu=E1SCH5bF3RB zzRFEjryn^Mn_VaHyROUd7}piJ=QC+)Aoh}xS8#9FWw?*)1n%p)1RG=<<<$&%yjrGQ zxmLK{<=w&~E}s-$a=A`;&*ewLCQsY2Ergw2_7)mk4ib)V`5j@D%j1O!E+-4Wav67> zSO`MLqP#*8hf2yT6rrf3yh0I;O3Et~0jZ?CLJ^Zn$}1FMsieF@5t&NLD-^-0q`X2A zpGwLr6d|glyh2U)lJW|5hnJLBD7IPY6L(vKlvi=T3wae+NM6PDkymkb>3d3Gu51(i>vQ(E zREzy5s)3Kc;dGfks|NI!1UJdDkF+V=XKjuD>7_nIFYH8g!%pCbVeAC-$n$R#d|!2h zsgI;e-4Rt;E%Az%%k=r%AB0<7#;HfEm=3G4Va!=ubF!_3p*k?YP^#e)t8N7z#f0ds zW~J($lJVjJpLU(VXIz)zD%TZw&uZ&m2k&)Vf%myC!~0z)@B!D^tHEmd=XyscA^77L>=K&M1@RLZ4RCyHh_la7#bs#+IPg#DNW>r+BjJIuA&wlPibK*4 z@KDzYJj`_&9_hLQ!;9v9Z5PCBnY>rv9M@%djq3!?bzOqaX6!vi$cY|06 z!f!eharjM#A{4*rP(-7WZaNeJsid0@MNBH`dP5PGN*imyI&>d4c$ zHu5yCjGHyCi<>n@z|G419Bc7rU7+$JtD9JY53flx67h(PjD&xT4e<*VB-`jN`O-`JabB4o z^c{uWUG63Hb2&&j%;h(QW|ytPaV~!(OmI0-=yZ9OaFNT4h2OcHBi!h6fpCw@m^;Km z5IR}CYeEr+N_y9XA{3SMt_ejnD(Nmk5s*r{OHjn5lI{`|VX36M1Vv;j=`KMLoJzV& zP{gN_?h+Iss-(LF^^lj8tEe}zu`w2r`#=IgHg5aF>!JHIvaL)Q*PKr=CXMHdyMKmg1r4Qz$ z2uP)Q`e06qm{ht^Uw=vwmP!lt!JHJ4sdTSCn3Eznm6XRQ;!{a^j3Pvpl*g!Vdr5hW zI@wFgV-#Di^a1R$1}UZEei!m8u8_Qn>m#q?>d33OHu5U2jJ%5LBClcu{o0S3TD1(vv9_ z`UwZSJWM#sWwUUs%j1OcE++_6Ty_fQySzxa!sYLT`7Uo1?sR#Nu-xTi!m}=G(*KBs zAapFsD-?04q`X2Aib~2W6w#=pyh0I>O3Et~F{z}yLJ^iq$}1F+sieF@5u8fOD-`jm zq`X2AqDsmu)EX}-uTZtxNVO@iP;9x<2e8X(P+rCTF632QA$b+oM_$F%kymkTRbQACrm4yH4N_U60W)Wu#>UZL1>r4L}2HAs1dV!sP{ z6<0`J#r2U_adqTXTpM{6S4LjNb&*#w0`iLanWmUm>s5Z&>hz}<#rIq%@O{^1_>t=h z{MouRH4rDs$Se4B*JU`tbplUzU4oNj8|Br(uj*@PnG&Q$7~^uR@N<`^3LP%b6fSgG z6|QnQTlj;^TZFq^-Y-1r@{hu5murMKT>f47z-7!UVj&0}i}DIZ94aZVP=unA@(M*X zDk-l}1f-Jk3PnsRDX&n3rIPXrMPw=|uTTW1lJW{gd@3ogP=u(G@(T5-my}ni-r7jD zDX&m$xzY!)%W6s+f~@fY-QA;9S>b_0P*hT0p@>E$05LHrMq3-pP@(T5umy}m1wpr;D zcUyy$S8=}!c@x#R$kN=I2<8c{M@hQ>|`d3BKlf zd-%7sKJNNiDlf9SY6(6m(`x{rtA79G^ib@(Se1NB0scv*Glr<{2y35Mf^W-o?at_ecqeUu8)8E|vHExP+Z-}Z48AP0k%+Zv1AHwu#F6V& z@ow4yzUMlD@4GI;4X!K3^)^#otyuZUW?E)qD-{$%9o*V=1%BCe8P>T@;P$RdaQ(-r zqZrxF@;>-o9M%We@*Y~>ni5ZYAKfRwOE;kV26)Fm(ftB^_5*bP0RQ>l=m7z4Zj%lS za2wNu0_>mG!xqy60zA!h{{SyF-7mm9O!p1&S=0I{ckx}*4FMjiMG-$7W4a;0(@pC) zA;cM``vy4QbiV+XnC>6oYSRM(WTVKS;y&%Ay;8!029s@|ugMnRgYrM=Fk5wZdh;^j zW0!Ynn^($o7p@Vu)=o=4E&SExCqf_XxoY1NHr19(?kqIB+*%vImrS*Tg;QMi(GeUe zQ|)NsVwcT2jGxL>+b-PZ^5hTo?F^Y}X9|zG+(L`qL#Eoe?nDv3pjO=jBjGl-@6|@= zXHXr9?@!#@iRdp=3LEiay%2r`)gk#2OpG3Dz9*Mw z+ZMKhl`=&&4F1KdUlsPYooziqIM-wocvD7a_>on&{!2K_HoWyLVYbO8kXYVVhru1} z99nl0e&}+pu*75&*i%P>XSkmoPwN4~SuU3fYfUzRVLB-~!(;5!T1N?UUA`*R*r_#v zaWXo?Us!eP6k(~$t~$t`c9>1zJQ$`?%apxfwoILe!dtDn^>%?v zL_f5UA5e8D2bG@5u>4G_L*t?RL_2=9ZGH<_Ba`Fd@B^!E0+Z6+hnM^AgAHCi9B$#; z4}K$KDR6;Rw}LutHooE4egDBNUOf!1wCYySPrFTTc$6Oic+#tf!Sz<%3Pxz>=?zb^ z!)OBUc=a$?@ofhaW%Py@S#=ZGQhTlHVX)r!9nAFV;qYdwZUW!%GZ+Ss_A>xCrqyt{ zRW||7M81a>&SqHQY=#%kW>`F%N!t0TzQt|u_ogQsFY`TagAbXWY+U5K*#=)RJ=yr2 z?^~PEc4cx+t@wfOP#f%J+cMd>tuML_9%_2Baeyzc4IXEDvXQm0rG+)M71lI7u4%f~ zbd4oeE4W_PO+Q`IcaOk5%O$G>4qE6EnX;XGmP=N0v6lIQOp<$+OIC8V7Wt7(l6#g* zR`Nq(2Q5jGdzMR9a(gXsKR<8oSuR=C4$|_Dkx6pTa>+`zX>q5^B)Mm~WFe`t2En8AsF|OUse>46MGXKr^|GxQe z#(#(TZ^r-C=D!*L_nZG_{QuefH{<`m&3|+B&kM}EGTwZ__gp9Neb;5U!F9#>FY8}d zD}LCu3okRvOnjsQZ=vAFt}F0guFLQf*9ojCS^pAzuUqOUMz*uOZ}|x`)dyJrDY_xR z#($&x1UTU{bl(7H>2!Gu1s8Wg_YZJ&En06u#D7`<0|Wfj^q>IuwqW$<+{N#h9uVNq zO!p7)Leu>MyvcOm0RL#ZPk{e6-4NgqEsFTz_e?hgc)Dr5g%W3&)>|lXzG=OM5|^0P zTPSh0X~i$HQ5(I5(mw4fQ!)c@&fhF`sO~IlZUa@B@_N{Oafa<~br`%}ruQdcVOkCU z=GC`o&zH;8W0kO(wq5c`;dPfAguQhDs(oMBOhR&J{jb^Ob~=Tx%Tzm9IK}0DI*&$~ zYDWtfyBwv{I9{d|fw3mrz$r4G(DOt;yXweZ+Goy8&o$fsx{L)vjzF$=)Q;^UQxC9* zZD4g+ekj%Ka(_+RvXia3?GxbgmM7puTg*+0+>4rd-WDPOB;ykRz(?oCcvbZM3 zuxbV>u0P1Mso)`#Ez5*M6_s`goMf^UERnH~@F}l;M)=s}7-d1QglGe6Wpsw`T6OFD z!j6_4tuPDW?=3#)FOB3$EgGo8#2WIAy$U8c@M;cTmJx<**; zGC#fQP*Rbz!F4<%?RnvNhH*SE$>bZP8I-;GJ3wbL+>WOe+$WQ>A@F&tZURj@2&&;l zb|@`ig;zJi*R8qh#&sWt3g@kq3TAshaFK9Sm4#e z;DcTb`e}XihDXV?31F2B-|#h=s=){y4!z+?c3w^31Fs$iH?fmx0uyEQh8KA?*jC4Z zZ`j|D2K?5mhr>Ipx*2e4>OHh@dczB+*BDPveTHy+hue|0fb>CY%pbIB_Fn2R9nP`Z z@@`xJy}OK&Jk_`P2R$^Szy6(OWHy!&A8hF##97nfg}nJeVYbHjT#wak=UP^@aJA2K z39gfM)1{*~ag!9o)lHBcF?2>orpr7+I=Wgd>SM3Wr(2xCWx!bwe zRr{&_*TWBsyPb<&wO`Rm4DmzZZs%fG?SWeR44GaL;)YAc{Z@y#a9u@l(W;GW=7l8v z?`x*@;|O!o=!7SnwLeB5-u0RL*be}J2B!u$gQtT#O{z+t8b1vuJt zeSoK$ZV2#v(|rP*W4dpEi%s_n@JZAC1AN`|fB-)=Jutw75@Hw>;0V(V0shEzp8zMB z?i=8*P4^4%dei*_e9H8|0N*j)5Mb9$@!u!FZA|wKa4*yP=7xBn>HYy8WqLq>lS~f` z@IuoK0nRbqC%}cK`v&;9Y3;N4is}9VZZJI{z+RgX&%gi=Hr)_ltLZ)gjyK&mz_U#E z3-C(Q{R6zw^nd{0Ha#%FEx&~Sh5)~2x=(;dn(iCmai;YPcw(pN{sCTYdO(0HO%Dw4 zBh&h$3F5Y8-%t1r(|rRx(saK7$C~aRV5jK;0p4tSV1Q4UZV2#o(|rQ`m+8I%Zf&{W zFTlM`_Yd%3(*pwhvFU*Uo@Kfrz^hF63GjB)eFJ>VbiV*!HQhhJ4W@NQqCa!_$D`zz z=S73%g`a01J5N7{zIG12fBkI#eBIhtt)m#P&oi(vPyXTk|IRZoAbSS%rnIEjzU(>h za&7i3c)4r#Jb1a3JriE;X3quBfS0>x&x5{0*Cl%(RH)6K2o<_!kAw=P?3qxZn>`e@ zN>&xRXHS9(U9v|(h1%>{P@!w~FsM+yxcv+m&pI^jH|8LFUz*tn*Fm( ztF1X8%QC)ooZq?!X4zF+b5NF9wKa!iiB(&3XqH#CHHT$sRa-MO%c|O%!!4=&c0D4? zsoI(&vy`f>`Bs)uwKd<)5~{Xlc$QDKHQ&k7skY{*EStL4B)ev*q(ZMOk5uTLC6Nld zWf`Qx?pgY%ut%0VD(sczjS72bIitcpS-z;SZ)@rXEATScWq7&k1kQ4uzeAFb-sZ1bf~TlmpKqKkR9(jG zC%Uv}0#CB$W_seZ@MbsfSs!S=NTxMqj=rc}uj#RUwz|*pAtiW?>jchqU53}WuE371 z*~^KmOmwQiJ4HCnbs3)FI)P`p&h~*xA2Wy568w(ZwWJ@VT??x#^i1gaGwaz1rnoFF z#C_HW98H$#%cb#O)Xs3)^~uVD&e&mwDylX}Kkz1A>^gy$xGuxXTvy-$+t}iFgM(dH z;DN5o@F3R-JlJ)%5zM*V{OMoR6gN@35@K&*kjr9pY0m_HTu09)diIlPrQ;wIs5*|i zCi7n(7_~~qrWA%{8}xtZJGRhw?C1UJ4}m7#tL5&!GVeOOIG}KhLlo8_7N&k#L_E}W z0uOUthDW-tz_~kEmd)&fm?tC4;I*#H@H*ECyxw)TxlDSVIjol88EV(w0J;{osn9c_ z=ONbIJVUrl#^ypFm3^7{{mg%TVASO@Hut1_Shl%e)K}TJz9Y_Ig}A-3cfP&Rzmg-4 zkc|BoXvSMDQ2n)e@ix~9yxnyfE^=LgSM6v!S_gmUx&p6uU53GR0%yC24?3+Jo(YuZ=4k(=B63zFZOlety54ld@QrBg;+;s(Z z@0q?{A~un6lflGw8E)!2ft$I`HkV01Fo)F=y#Fh~V5UkLqx}2EQPOf0xmYS6rdv<`#V|`KmrNl<8ATz|1JZCx86RlDOHJ$N*2MXy^-W80k?H;cE;l_Oz*VLP2Dr}jpa9=9 zyAnH}x9NTXj@XSp{R6z!^nd`j*q!=;0iI}jP=Jq^-Y>x2_n^=I0iJ34fB;`H zJvczlh@W7FoC{xu#`9q_{?NpwD)3;#%UqY?<*pMr%XJAJSDy}!X-@>h z%zHI^@(XoI?8nUBuRg#rK4vT&FWXGtZ<(aWb*vuOCQUR_rt2G=EYs6EHqMX!BDb_} z|26A7a_QHVRWiK^0x!ulY~ zSH4#L$g~n6nm!eof>beZOyRN_!T-U)9(|S1Gbs7H5bplUvorT1lJ6c_R z7%q;KDJ1Yilg)rpg%|6usyNW9vX4rr`ld{uHP>{XP}2*IlTFj|rl0hRJ2^qsC(BqS zJjHbaPjy{}lU!HeKU{AQ-%jh{JFd%cz3T+N>pEK|b6#w9_2CimIhmFTUN_kc7*$wi zQ1KS4%04ro>Uyhc1;00$rAuFG(m>ja+R zI$IfY_OiPAaE$m9nbrU%nQR1%DrDL>R6N+KvXxOa(5hO&ekQYbS~FCv%2*k^*mVLg zab1R&xvs#&`&$3);SsJY@SCp7aG2`^9_hLS8(nW7bLK|*yWM=(hc)6lnR@M`Zhd8v z`KbJgx;7o9*UL(GhCeOSy+0m)B-5P%{%x`q;E^71h`p3TeW15#z3xqi~!;n{<0 z1KXR67Jx_1mxtU|a9r0tIwnka(7Lro`0BF9jMhhGI$_`)Tj=P4Pc-_V?COdxSy%Ll zj#IMPO)?G_HoH#XcU_lZtLqBfx}P5|{Icr`taDw4+qh2PwysNX7uVV0j+ejF&A0w~ zhWH1WPIQA%qpp(qsQhq$q-I9hu^=v&u`GCnObY?HpgQ{4=osVFc8oarwGRXyMl1M> z)wThmlIJ|Q)`H{w81dx}T3(d&bz~=!&(xI9)J8}A>Ku$dDEnd7=#s@mpT%SBsfF(9 zTU&y?Tqm%%>oVNKbp>AHdV4rCt%sMoF2l=QC-8FD+3mxe!>z7bhOIK47Z~FboZ}MU zKpkT0<>PgGsp%&&eLt{EK%8QIn@<;}y9DkbyK`r&YL1NLh1a-F;9S>bc%ADCJgUF- z-x(h5x&j+rmtm9Z1U9?QR{f-WtTBJ}p|{%hk`)%UIBix^mAljLUow3y32-e5@M>M+ zW;~FOtJt^=Hm(&Ap0*dH<0{#e@n8A4IveNl=D*b!-k-`5}ZqaeY_BGcpaXz*Vlx@LAUhe9m>Yi%fcsIn*1~0bOby7-;)(V>@EX zARIOX*mFO0p8!{x?i=7m`%~X9z;7Rb)?d&OZyJIg5a97P>A(Ozfc*RR1i)PUj4^%h zk!gq5xSa&nCo|I?ULp!`tdqTQebnTbSbs<6zo(R@S*q9n#LFLg%rC z&a<=5zg6csvcj8Ds;;%F>~^?U#s4wDZ4^kl#p|cWE!Gk?Ol84oh|@dbf(zYebQHSJ z>?m});e0QdBBD(t$|BTanGT zr{;THrXDLh5KN=Os^WaBi}S51&bPKW-#VM`37_xH4n#WNTiJa5G{q}E-}(;3xjx^9 z4#d97Mos=<2V$)kKIuSQsoYe{v`$2umZiekorpjAeCKr{;`V3Xa634kZ$@WfzL}kc z`DS$%=DVu1FyHLreDiF+*L=SDorrY4{8I$x`@64iK_?WAu{1a!D5DR6z zxWPMIm*FDU3B1#F_Tt8*yBx;2`T&m_iq_AeiPs#C?i1jPN1*!#*mD@VUx1^JMC%{M z5~qI)Js`l<-$oA%@aMzPg96*%MzOSgiUM~UN?Ih!~G3L-NHP36Us@yOIv9%Vc!u)o`#BW;R z#`alS>L0a4wJc~ye55t1uzm`H0L(%3ilcPwhf@%YSC3DoAkwkZ+Y4jYW~n$(5e=0o z;$P}O&Xq~tE{|P2v<*`bTgdbf43qOWJeCbp5NRx{rp8$CH^Tfi;qP+u*Mz^9@mbS~ zx4q39jRpW&knvQPg>rGQxLu6ONF82F3k0b&DGBq(ae|nu5TaLRvos(Jr61Cd6Mo^0V6!yL#j^+7W5w z>$1r4nvR{;jvy8}n$?a-$6jS)_px}guQ*QE$a}OUP9uGQBD=PlL^sy+AP66*9Fl(;C~~macm2d&*SHEI*P-PS+ea z%OsiMWtk-YYn2;%am9Z>^PjyyTqEDtng7<;g=Drcj+7T@ZP+PR39dWQatFU1TqD?WVaCSQ)J($(mQ-PxwETksf z>><6~W_!Gc8QUH& zVih*D$D3G%58LBatiqD^co(a%zCB*XDlBW~Hja6pZEs<|Pm1$Rn_8Ifys3rxrcW)* z_egQRv!@p3TTz_v&5h=}RxdA#=#wei>ow#JnF{A+Pa+YeJ?@=~n50)7^;j|$!4MT5 znOYdTaw<;d>xD-xtJ@JH8m+KwDx#a;`YWa)(j8c^(R^2WL^Gx$hWmUory|n%uCn=- z_~f&vA}0ELE87w2e6yxLk#F++FPdUraf%lU~_#n}-##-CxxX2}OOqJ=fV9d8{OdH3!sZ6zT_@^2^Qb*2L z)$k`Wy#y8xepUGI_^(&W0g z9nsUG$zE}r<#I>)()N8a1@V*@rnMukluxzHYDe(cs&HQWB>CJ*Zd91pjz|;st?aHT zc%9x}@H(UD^{S%RnZ>7cq1_5hqbU{_=R3PN-}-F6J++Dk+nnq(GOCWTs>Y=X{9)UU z#-GdQnKFH%6whOc7O-5#TV?o-Hm038y9=UTMnmjOxgo8CeOxDSkn1v>Ei)&GIcWpD z#&rVcy3U+`OXXi$o!)Dv?S+rnCKZ}5&6=~9vjwWURYth*HrENf-E|q><+=i2{GNrm zwidBQrok2XlIt@3v+D$|bzOqzj7kT`%~^L$mzob{I8n>^FYXq$_`~F(*vk!k+nlaiFaEdH8oi2TbH$_J;$wqQL!7x>J1jS(E z6xJ)o_^Gnw1P%9%UOW{2Tl3li(&Jl}-J!MmRO?|&ym8r3bn4-e z%)`SQd00~Puwv@4jXXS3^splHP#UQ(y=1xxcM!hn^6SE2mxl>WE=LMKcKI`5ip%2a z@ut63IJ+~TaH!J!&Va(FN((vz3b!gP?hGhAYb%EY1in=m77%B8p)nw?@WRM|NH=3l z_5%lOKhu&-ae59nPR^IqacaKgjT7@FZ=9DespCw18679$%jme!n>EM1G9}AW;VGA^ zh1XsFL-?1=S{+bDroKB0UvpXXgbQuNoB9{orSPKC`i_9YkxCzS1Qfnhnx=nNMGAK+ zo!1$nW0huf2B!F)x6SGdC^kxMI+V}P%kIQk*_}8iyAx+*cjA2PPV~?2MDNAj;gPA; zjP{NFQ)+tkUVJ#W33*+pijmAvbydbi3@>(_z)M`0;T5hc@Y&Ji$HbLg5UXWe#P9{z zW%wu830&*C1b03*9gNsT#$edPbs6?{oxt5(XD>WWa&m_`td74|d{CxK7QE@QTQ(~H z7HX}U7^R*7r|~+DTk$Q`e@{mGP8BbZ=>oh)xXESgSyAyo89m{l*4zRZsJCC>Ntb|4 zP%U`TWFuJTwZJ290Yr~u*i)u)fUS^>J5qS5CFUQRt0r)=%UObl-Ly>7gRyCSt|t6% zZBDZrd0Ta45u_!=vmPA4czx76p15&<{(Q84Qu&_Ws$6+q7O!J8eRQ|1%3ebEl{4mw zcQ6{q>a@D!V+rDncQ88jusZY5U!8IfONJIa=#^R{au1ITEqKUZ##!JrS>gHM@WaMc zap{F#F(K+TOM{H32=;NEz`m}_aDeLyJoEe3e_wc(>k2&Ebs7H3bpp?EojnK4InMl5 zOK`kQSusxCI%S0f$$RRjUe#-wj~Y+cDb_Xnav^W74|Jmo7f|e4yl8T_4dLX}mC|Bt z+>{xrtJ-*7E#k$l6L^X1GQ7-n1wJ;$Hw8ZKx&l|YF2g^%PT&)+vrS>nN6cTf1Xswk z6Zfgx!?MDrP%_5d0R?fIsx)YzwN zy#9Wz__XT;KI6I!pL1P-2mi=6r6(NXx&jYzU51CcPT*m#vrS>n+T-w1Ej{%^ebz4P zUNb>|0j*a+zbY&2Ord*1cbdEFC-LYWmznpe54f(l`*E;NruV|&(6kyJ;niSbS`AP4 zYH(dz4R7#jusW@VYrGn4cD$`<9Na>tDZ${h8V>Pla8gSAK z8kDpX+Qe}%k!eaWAgzY`do>uBR>SdL4X#Y9;niLZ*lB#jXT2J*`BcNr$GV1F$uvC} zWXGNVFhPDE4T1CUL+BHr?|k0?eY^Vw=zH8hK;PH_0s3wZ4A8f5P=LN~`vvHmwSR!V zLk9%t+cG#n--`nS^bI&DKwtI2A?6v6Qohvsz*4^{;}r?EnAX2tAdWMAaDbj&G#)usmp_@?QB0e)zDK!AzucmDvlH?4npR@~Ec z-vIqg`h3Cj(ok4y{!-bfF-k2&o$L!0*LGS|C6*%2>8D8i* zffu>Xt_9{i*ZfsWaE46Rz*KcRS5~+Y@}Bj9p0D_*@pL`Qx@LD}-drE(Mi*W{V%Ope zNba_w(4OCwGc>kpjOP|{e;=7Xb!`H7$*7K3XWq3wFl3Sq>lff- zrUwOx8(w9g`zXB1XgUwFA>5L+=R3Djbx+xNy~>DByH4OUuFLQ_*A;ltc-y&kCVry= zI|paDF2kzp1YYbq+c_rP`lq(o68wrx89Pzka3dMFpwKg+=eh1FHrM3s^?~*iWNab) zxh($L(0KhG0`5;Y_ieyk<-45^uMZ5LX|5Uqyx(-60ADlRH^8k=U^@L$zc|=*{{Vk% zTEEgS&M-YNz&lM33UHn2{Q}(LMEvX@;2_fn1bDpZ!2$l-^nn2`GJQ~hEQ{Zgfxf2v z^z-e}bCb2_r$1YDb8P&?5}fBcf!De&!>3(W;4^7GT;)1}&$`YI8Q*tWU43|5d`eb$ zCcd~i``B--dcSI;CzjyjKVy{>`@t2ivzh37vei{f@I09=$qR+qF2OCbt~Dp0p53&C zVcGAsQ1^9p{%FX!?)m~cP#`*8%P~b)s`!jd!I$7Y zC;39)y{@x`(Dyj2tCryDGEF>HnBfux*+vT~49gZmT@Q6+A#hij76J~j>gsstGc?bW zyg`;NgaXkO7P3UeWf#wTzJ+&#)Z|Z*dSxaU?0~B?CZJ=4{%+9Jx;b=UC;%w zt4xC{u$SvH?Cm;%ySXmGolZ#yBYMaf48P*K412mx;I6K-%p~F?&0)0!N6NGkF=a?K1Y9R_J-P^sO>2F*Xz3+cF~Us*w|IbateFD>Qdk(>~Um zjsCyw1MUCQp3+Xdwol@pWrc+LRiXJh>AS2so1NWyU&iP!WqXvx{!XEJi>x^tU9YOX zGO`sel<7mgB_7G z3uV4^iN$FH>^<@GOIPJw>!78JOH&QskrkJ&V%jyK>$5VgF@bAj`dS7s%9bwrbj78s zvco!P>Ef9(mM+Y(YAs##nVYv%wA;$^rK^C?;?h-Ykg;^w&vgPvxh})eX+1pFb$)B8 ze1z52hY{jPS>f3nqvCPatRGbuk9VEGAGt2W-?^^9tJ8WITqkh0>uhR#w_9B`foIAJ ztBX}U5tpgyN^8z;4ZO{fv3Pim>jchqU53}WuE6JA*TL0kJ$%7+8UD$20$+5UMa-N_ ztgb$+6j#X#o3&QOzgV+=^ih1pbpl^?U52l_uE61^*%IpDcU)KCQLfAIXx9mBbe)C7 zoL#N1YNWl8xHNC-%_WFC-NNzdr@5OqmmxD3-r6&w&Z-*0;j*rJoeT({C_9eWRc}w~ zx^MbfuW+dP94RZDX!Jo&_t{PVN&tT7ql!+eh;eP)bJFK~s-oDFsrZMC`s}8LIIk+Y zSVinfz)dm|299u@z_VSK;jhwqc#i9AxAAd;)zyb7;u*3+0?bgcYR&o@SG?GD0xxl0 zhL^dnz~^1p!PRL!e8F`Y{>gO$Uv!;?#GDJPuA05G%jb{)x(r`;U4e&8@;rryx~{;(T$kZc*9kn_brvRb)>vI0W?okx2C3~JSs~0u6`O2` z4oqxzoxm2?W%wJ{6*wcUhgH`Jyx4UX4!%#cy8M^u^Sb(Qj@qWn3gOIFagGhqg(F_$ zI)T@^F2i?SSKxbTJ$&DF0yntM!ol}FR+op9*VTtN)%Lcm5Khfx6=kF|EV)i#Ki6g0 zKdpxYTxZkbV_U1!TXL~MR+wUliicRU{#2HDsOtnC?z#+5cU^(MNbBJ*T_k{mA zU5QU7^Bg1VUURjDcB=Gg-p9t#Kel~-46hEcze3O5=fAo*O~cP{cO`hX>jd8Ix(x40 z>*2kwvz@}nl~z|DZWZs86?STgiVs?|eqCLB$aMmjx-P?It}F0i*L85aU)n+L2Df)z z2X}B?fjhb`!<}3wu&3)1d~%BWiM#Zke0MvYy87_n@E3&L^r`SAb(aKNng{*M6=I!N zM+f_>I6Q40Am>A58dYo_;v)b(^=txxh0CBd3*jbNIt%r z6xy>ZkM{4|^lgAx`IqMU?53~zW8kVd-72DktVayvM};Uyd_k0Xdv$Eyo<~_|PYUf> zl(hd$wrLElcZuQ@nO>E_1+q%d((xF-=zJPVr1xA?OD*BnExHnm!+N-d-J>x933@ z+LJ4?1tJj?LTipbPCu zp*;(lcEZY|sH6D4Oi_TYnl%d=7xQF=?i8<+6@vbkhQ*+7R@3K$&fBYF^Y%RGLVHqZ z&w{3%u<|Ijr?{0z0d|#TLE~bPtk9j}Vp$>R9aM}#FOmLy(0O}xY~G#+U1(1V?OD*Y z6ILF@&J@2PQxuGNWaCzfk9ljn;dnLZEz`xaiCzW1Y%d6-_ZIrOEOy+?Ivz{Mt*rIf z|7;zVyBQT*x63DCuD#t&54m6>eG&Qv^D$;u@5q>aO^#;Fo;Jo}?Bm0W^Z1xi`8=Z- zFv}7-4dBbk3Ne-jOlGO^#;Fx4a``noVZgl8+gc&ohcK z?mP?Vd-C>U_XtifdF&W<9Pb{%M3Y%Sj2Y`488hDGXvUo29T{_q$t<9J%&2^xQH*it zSwO#(w{zShIN#*4)6{XgdjvC0W&ttgZ12dJ=_W@r=6vtSn2Swj0p(*x<@1bUj62T) zx>DY*bC2K#lgG|h#~a-vSZFc}h%xiLBV%qfIhrvyct^(EW-<#XA2TYSXB1=Hc^1&! z^0wSPg2zlAyF?vVxJR(cWEK!(mU&0UtS~v6F^_pi#yo8@3n(8mDxYT*W88Tb(4XY( zb@vGVX7bpz>iCv>1RG3d0WoHscVx_4CPy>oZ{CqH@0rX3%Eye#=NZKqcb)~bQdiAW zGQK2%PrFXwGp@^Ut9I*Cfm^#S!!Nr|V4dsi4LH7EGavP#thS1*@CKYFsyDTd7W4=G zdu6>;r4JXZDn8nOSMN_`dVW6>x|y$LfLr~cs%g_|v+qImRMoCBRt0;xPGE1>Ww?jy z3fz9G_1_up;JN~LbX|r!xlZ8DuCvvSkdF!GuRdHP{#K@7Zx@!Q)mv)FHnPGdiG)bdJz|eAxy#qiG6&ck7TmxRO6q?WE*j+`kf>5k6P51!UZz<0|eQvWG>(TtO@S02T583B7`md^DRf(P9X^JJTQ8kK%ns|Z?@1nl`QIcA$VB68WiNMZ$ z&V5f+?JBc#6nAr-z};P!;hwH5@Tacp;0b9xJkfO-j(45FpSjM?kvRujT{T8tQ>fdh z-@e{2fsD~7X^DN3M&X+>y~cy%Wco+ey9C6Ky*@h6eb*P7vk&PesQ1Y-wg8^uI)SIU zF2hN#EAVO8+rwwldbrAU89wVefzP?lmd2b{TV2)ou(T2eJn1q9U+7t4#P6-S3EU>r z_ftCpf*A^5gBFG*47=Z&TLF`Ft(nvj5CmQLY?EQ<$n<%A88TE`UbZc#aGgwB4&0Bn z9I?Xd|1)a+alEuy`x~2U)~fC=GWHz4;yQt^x-P@lT~}b!8P`n*x5b&ftP>suWY1AMeYKZGfh7vQe)zaBwz8jdk-9~y^Ws`g#v zzOb`jQPuu3Re^Lw_LmALtL~T9+y>I-EJweqI^r#y@GMnrVpZ7(*WXc9lT34f)JgUi zCeKjaudKNdq|Moy_g3B4y&0ss_p`B25ED)fTLCShBap& zlQgK<&#Kx$IwFg9Gu7?v%^+>gHtYb^Ew$$CXKq$$H$Jwi>|20ibhbZC^8nuJx*je{ z>*E5KsJt|-gIk?x`Bo3Nb)Dr>qsmQb9X!)@0?$h8qu<#o&q?dxHLepl*L4}rb6tVA zxvqn!oXzv9Z(AZxmFc0WgA-j>;AyVQaFXi;PIjFI{*WAg<19;j;~Z%{PGCEAl>|R` z8COsklrVUR4Qc|{%6N$2BCiHGp*nY#{rFt&tUln(Jv0R9!}^3cj9(HVmdWO>U-m*b zP35z!Zej_3_^Wh_5Fg37S7P+H(ZM=bjjd|eI>CIG;5C=UK{cw62kD?xbp`C4nv(b{Az30~&9C%inZk5TWf z@^MyIHJ&S7_)@&koY0MCkG_&^Eq#uW@zw~^haXLaK3)DJpR-jr*V-qR;Lhh-m_6Yx zuCr5kOzj)2Z`HWD+6$o-niIOw{Q1!6^Om`&50E~D27S6bw4SQ#ZS50F@MPEZa8gjZ9ho-Mx&w|AYu9b9Kyfsb0Ns~WeK){8%& zYvGM(-cvs%sHSbLIlJ9@s<^9+)PTKQC-7L;W%&KH9{#{}77RWPwYsWtq_iRcbS(sv z_talHSJP-~&aU$@Djp{z7%09j z-3!Kb(t6DTZ@Y|PS5(~Isv1F0Zw2l%|Kr8<93b7cy<7s-8)Qz!B5a>m4ytMvlRyu_5j*BM-9<)l!T2!&JlH z$O`YD3SASrp5|Q>*lt~00HbuO!=O)B_~{jV^so;4VMVc*OzQxLShapwQS_OcZ;@Oi z%YJ(0K^5?+SEFnJDn2D+h45+D34F$N8Lo0&fzP|HgAe}3w(9IIh=*hx6I|-L0++ci z!~b%fz~!#9V_GSPH(h8;0*lqGADBD46G4AvcpPT+#YF^bZw9#i+!Ap|UdIuSsr-b^ z)CL$KkMlZX`=3<#XKQZ(Y5P@K``fB~&)OS7+J0Wv{;?|mZS8F!ZJ&{~Z+4M>mRY71 zfwX;Q*1n@E>#e;Jr0ugdYVTp~tsrfmowe_w%Dt_<4W#Y!H)`M4+FQXzT7OA@hyE)e zZoo>_JSDTd5TACPz-L{T;r=u1{HJw693azxG92tWfd{%S!NX;GcR5XORQ$h2RkWrZ z;K5bvFryYRL`Dek@Ys-zR7Gpr0UmU5IudcPjFE6?Y=|Q#sA5vu0p4(lja3EnSLu013?>+%KREtl(suJWJ`n+Q9)>>>1Xd4Mp&sviYZmPu`{5URi%471B!{2`@;j` z0xygX2w!}4e3lgX;_I_;ctaF};q7G%g}0Y65PtGMhQaS!$C>!el{gXq9AjKK6EBi+ z3h?5Yc04O<5tqnlfU{yl9QkEcOqc1o0`$>J-jchqU54{q zSKw`~>)^AO+t{A)IoEaYdDj)V+I1Pe;5vbSa-H3Lcgx>H=DS*g535}lJD_XfwW`q5 zMl7}FX5c-utDP9#r+%3xZPqKxxVZkcs{4zK^}|xaEuC$P8cGThB|1%B0a9sGN+tXyy6EfwUb4*tV+1-|XN4Bv5`!1b<6 z@SieWiRM9 z<0Ucr;z5p{c#xwX9@yxGKadc8PxqLK&7)T%>P6~9HB#qPApQ!5=rzy zB+&zr#LjWNZmXL+>FgUqW8a550YHCt{qnw}I5} z!p!eWa`vkEZ3XGL8*Nx zT_?3-SJ!1&a$SL&xUPfy&9kxfaDUfz@Br5pIM{U=9_TuO2f5B3P-6MAOiv=Xd@io@ zZ<^EG+nSrfD>D1Xk6)L#WsVif0dbEPDgklsHP%uW5L?Kl#%v$1l(^0dn+3%Evce4z z=OT@mY_d#e4VX?694-HnfT<+GS2d9&xWpy+*kwGT=#-p{UdhSmmYj@!d6|ojd6|oz zd1`RYs`xvjkcHtB4zT@g2+;RB&-1tewfcvp1D~^+eVn?B>UOo}RzMe}o$=pRon5Q+Ji)5k=tbfbK3CaYRr_0O z6IdkE>|@~FR^0;9*~i2c?WMYUYiq1b1^?2X}W}fqS?v!>_td;GV9tXNg$0 zyq0Zi1g~62;_C;x5v#7ZLTy0w)Iha#4aHRujb0eQVvXjM;A7ckZJ;L?0x298aRhu_QV^d@=dQg_oppnD0$L>=pfZ`J-OZmzO{8g+DgY%m2!L zg#1eR+0HhlWvTF_OYje^h75)u$&~hBJ2|2nepRMw;PK`E%+=NM`+J$55b(GhYSak$ zqRr6^{^@g!fZeq7+FXs#(*p?7xUxSwzF3YQusNE* z%RWaV{JYK33^w&S8sRoJM>D{o=4gZ;_#83zrE>O|`E3PnxZjcRee>G_wsOBC;V$O4 z1q^h*BjEw&w;80dXWwsmLXKatIhw&cKF4VIvCYv8cJMjIz};+)W^l02F$NyybAWV? z?9zKqj{jtHG=YEn9AjX2JHr;Rr_V7C*4rE{;F~_jIQVU!1Eh0|iF;MAWA7{Dl7hF( z^k#3RiG^tcyel@ukw>fIyE5fsn=s1d4}>4O{E2X)%byFUx|}RbaoH(Mm+`X#`kq1l zjeA_ii$bi7R3Zp}uMuo9~`L6VqaRK4$Dtr|g zC+DRw&dse8r{>m)Gjr?2iFtXA^YZcC5yu)>NRsh+ zvsW3sza`VtZ+y_)H|8^C7hjx_ql~k0lyN4GGS0$LGMjHr{sQu`yq~Cj(A%;;3V47_ z$qB|PUd1p5j+3bxoUgE{h8M|H4cu@3j^^L;TWfxs!Nopm1iaElwSaU~_FZ5`^~ghL z%%|A;jImW;dHb)aU)8`lq&#^h0z#TrvSa_Gs(FD>t zvMY2~Io{poXaOUAjk4eXl?!mf$~3qFN4PG-7S{=EbzOp^WHvZP@K1UCNTyBv6f7{= zP1w}s=E7Dkw-I)5xr?x?%iV=OGW)#0c-`X~pZX9$f4CBbTb1;IAPUba>7xV`&Q;PE z?kN1Lq>mC%OrerKI*gO)(jOX_b*M~*VFBT*(}#-1)iE(QMGSzOB2Ldu5hv%Sh*NXv z$BDW0<4j!oaiZd-KVFkxDPtb^gz1I=zhv9rC&0m``vyp`%oAgstiJPYTy->D<9ZC- z!TMImLLZlZpjH?+yfCh@Fm6O)Tz2RDFO2(tiu2c6$8TiHwEKjmF5eSAbGeTe*C11e zxF?-zxl5)KuIY|=R#vNDpn-48l<8n=+n>{Fb`t$Dm~3RPbi+q?V^loOy6T&^;_2Zsb+2h8n>ty!0A$)a($1R4yV-N%2af{RQxW&nN+~U+c2618@w>T4zTb!u)xRtf7 zd)hYF2RO{M-T;W>O!o=!3e$Z9B-rBPww=lYtgbp5wz?hzf8ly8^l|y)Rv0(DFs`vM zZbV^R_PG5ojQf9zbAe*N-PSR&1fP>B71x@0K5d8(##)vClGedjTqp2V*JZfQbp^iR zx(@#8E^|Ju3*sD^9+EnEuImas&vhC8+I0fYcU^+Nktxb)+4t$Tx?P_u$@IXC5l(V> zicppP$3sB(ePo`@s6k#*GNTTcDSw9qM5`Bu1_a(Mvk~}LVR(oWsW2ii;|<<2G9Wx! zeJv9AF;33|5GUsWh*R?b#F=>j;>09ooRl1_iOO`opep3b<>%QW^;nLL2h%}jIigsrV*nbvT~ zoz`Wb!d_@A$UX=8qeeY#4%$HKV3s+cyW*J9iAbl;zX#69cNgNRZ})b%^0I=5-s>#Fme?G0lv5(#AA1=1?1xec;KMS8Pl(V@BGTCdNE&W11Lqkd4V+ z-(J(0H)T31z&Kk7;u(!pVP+>{wRvj;2gr@pBZkN{7^Dl&e|P}r@0#-#@O^hayA$zK znZ|*k?r(M{;%M{N2vUFf4-4S$cz1GDC*mY?(g@agu=6?*|L|bJFn2z$6EVh|w}I4o z{*x3lv@ul~Z>-_Pt`m5P>oT0_x&kkET?Ze2gk709vkT%885bIS)O7_u=DG|Ycb&i$ zuCp)0ad?M0*B_e^XWh+iHQpyYbdO0e_g<3^3-j+Yxk9+@C;IpNMFCSMfp zebD4u;em%t#;jvn=FnX@PcQ6J_h=fG^o9V%Oe*Ou0E)>}(mjb{K4rzwfM7-yh6e<5 zsxTrTm{o<*0a03Ng|Pu~{<7#Cwc~OtEz+M@mzwslmGo`{wM@IEiSOOkXttCQ$wK>>lAX*ck5XcpThgoCll2 zJr*~Idn|4Z_gLH+?(4XG?(4XEe8#ooGp-z;aozZgt1jM+o2NUdVCQv4Cn{Xm8NH}5 z-Hyyt_uJL)_zS)qf`&(+C(RpX)miy){bN zZ`{*7w1V^GMSZ4sA}*9^?*R`C-C-JA{`bU~=Ro|?$g!9qFGxU)MEcbW4>u&*z0 zdMBcvOtFA;o*6bz>OB9^uYKh4aC6=U?sMnUI}s0>^JY-*&d=*a>}SrK!8N{!S)GXM zeGwp?Cw~=Ksr`CNrd=t)r(GxT8P{ca?PJ!b0}jlNmS%qRN6D6P^vKogGsZ;j6+Q|7%4C?&U3Nu*&W$@xs>Fb9;JjYCK|M~VOYy{>yb&%I6lef_??Uf1jWS?gZwy4G6P zx}N9R2eXHS6l;VOy&=V?LT(DigcP3(DZUa?ObIED3Msx9Qk)i2oF6jROk=fa)vu-1 z?jYWtM(!Zq6H=@jQfwGfY#vf<7gFpTQtT5_Ob;oJ3n@+xDb5ZlE(j@pjV;}CP<%7q z#^v!$T-AKG_||$W6XBkG3Cnx)B`j~wm$1A$U&8YCd|5QOLHzemWhA`&@1Nd4-yIk? zT-=xBIPuqz;-4W!$%WyiT&x&UtQArW3;9tnBBa=9BN98w$;Qk)o4oPu?J zoMGei^sMuJita|XcO#FaCHINvLMEg+eM^9MgcPfU6dw#JHV!Ga3@Ijr6uX8L`-T)V zLyB*Q6tR&$@dM0%`6T^Z#>QD#<2xjIBffd%otXK&6*HgrV&?N^%zWOBnKzcM&Afbl z=4aD4Cq3t@Q@Gk6(#yqKa`n)imxbqe-lmVt=L_0Pb9g;Wo)&s7d3xQS$L>#i7S@

NB+w?W2_tG3*50j^bUQ3={_jjVxo`p50&!%}nJxpF0x|DN5 zx8w_<+w#S_U;ZO>DPIcRS?#5?uT6cu)k63@)<~~iccre*+iQ1J=O+tq(Dk~BJ-6T* z^PM0ubU6qv8M-C63Eh@s>VEl|(52iqbY~mO(tda9>#g1ox5gUVSdZq1Qdj3jtVMGa zwp7o7{4d0vpYOjx_kVCOmdSmX+mYi!mvXz%ExCQ@w){87R|!`o@oN1*z81PAdu~lm zOSweoLJr2#_x=9$rafG(T4!OW&Co zpF4`digPf(6am+U{4;nUWM1V`ym#<7Bl1GB6Ms&l4=1B1NoS)c%Lv~6&e{KU-v4RQ zZBAmjbQ%W~a{17uTp@Hzt{A#4ug6k`6gSilJipbXgp?T|yjN+I71 zRtvcn7>X_SElgeOldppL3OOl;#n;3J&@-hlqEhIa#;8i6cN(KBh5l)bsd6A1<0~U> z7EgAp6tT0$w=i>fZ(t7YCx9H0+BVeLU^2rM~_V@*AN?$+JR_mNBpUKejjKO>E4Y)R;H9F|YIE z@V8*zn_A~Q);>S&gZm5@gf8VBpkv%b$NhSm2OrDyIY_ZgvY8r)}u-f3{3 z5&EaWeMT6F2KO1USv0uMh}c>4KG)&XeXfJ2`^;b?ruz&HnC>$)Ub@fFaOpln1El*5 z4K(0B)7~xhai8JLq`A-VUjUJ^WM}t=Misy+6VU;E(l%9g`r#W&d_an-+WWe|E8e0 zALDMf*e zg)Mf^b*)csHa~w=>6RAXZdK`-7C(Pg>6{kdd{yb67O(dzL(t+|u{jubeN<)C&to)3 zSBlsjCDGiSfxYW_0p9f--n*WId)ISl?|KgGUC)uc>p4*Ku1_Y$^g53GLDEAjc|p>{ zDtTAZ!z<}xo3Gt_(LOr$^-q*l=t=Uj(354%>wds!%p22~H?}cvd}Chc=dW+Uyf?MZ zr&;?mX&(m^^4ZX(d@giLz8JbKUtLgNSH)|XcU|@@Ou8kP2wf(IE(XD+u>p7eLrm<& zxa%8$jY4h$MuZ#%Mu!{&#)cdZb__WYd=*>luIpN#+*0nkO1HGQ>nc6d;;yT7PK&#) z(myTky2=o=xa&Dsy6Z-rhNZi%h}|{rdR~HeJukq!p2K_Bb8zo^4(%PxfxYWFl6O4^ zYTosu2>uhyIPy1153S_Vjce%7@zPN(Rhc4v`p<8mr&~3Te?e%q4td4otuM*Rtv?z$p&*SPC>3EsiH0PlJZ z?_JNqz3Vx&cQ6O`uIEVJ^&F^q*MCOvD>389yOQRQdc)_E=DUCJJt-A@-?vUh^RA!I z^BdFH{)zIz(39k=p(jf>$rq8G&mxU^V;b|uHs+0Q%yul`U03Or7I$5xXIk8KmCk8#*H!wb#a&k!f);l@ z2TOO|sF!2ut}9}9jk}(g;2q2h@UG|Z-t`>ZyPiXP2XkQWdXD5>&w-kE{RV>Hj~Pe4 zob=F2u8@v@SS3G^^zcf$*ydfom9dYddHoaR66tyWB)Mwn$uj13?|Nh2n8v)Zjd|l6 z^E!9^EtvPF);X57_oaRCJyAF=bSbwB-ICjfZp$_AOxJbR5{k7j@48$&bW5%ix|Ht^ zUC0k%-1S+VZ$q7f$7_=J-b&t+^w3JanDnqpu9}<-ucS_zS-ODdzfWWPC(4IIPm)Wd zvHg=}%UF>g#`-q^;x@r`+%EWHKu-qbpKS^Lnm4_=Yru+XI(9=atz7P>8$`eS|2 ziouv!l1qnf$ue{)mkC|S|G@@i={P)|mAv;>@`|K~R`O3t536KPax%P0ld*(9|Tt0LuR|wsb zD~E2&zCWddp1p)(9A=i}cA;BxeCSe62wlj}VPt7`rL(t-V zBL_?G8%8|=OYa+s*j?j&BQL?%^Sl7xH*$F2H*#>_H*#q2U=Hm2MvmnBMh?_`-?)t6 zf5MC-UrKstC09zvKdh2lB|W^7F1C5sZ)EJFXu-uqM&(PjI_4QWrJ4p|%WQ^_pqXHA?`#i>L&ey?|klB+@_ex!T zK6P?qumAn&8+)FOt2vmdlbilI>0UW9bRoB_`}2yPVr-fEdMnwR^w3Ji*zVq5Wb7*# zdt08zD`Cj&$)|5mU41@va$|4*{plNf9*e8(F!v^3#dx8gm&9xJ16kZ%Kger3htBKM zfZj?zmGsa`I@s69Ja!I!zs1SZjvFw3BS1KY_euVZsXV&zs{#-3@KH=> za?!nY6ve}s59H(dL5?z!jyo}&3CBc~Jh~CZv6EuJJ<}@H(HI|8gr1qngY5cgdS1kg zEf?MwiyEZ39ZOq>cjX6p=I7|R1>;kNaBRJGl%sjj9D7LW>ilZR12iAR^e-O@UCKqF zTk_Wrq%m!IQRtTZP3Tfy9J=#z{deZQmVERVvb^8bY%f*}Db@-phJ_R(LW*re_JN5Z z#U3HW!6C&lA;k$H#Tg;R?2zJ$koj;Lt4*tZM|!-2SS6(RU`VlXNU>!|F(IVbHKf=# zq?j2}d^@E0aY%7aNb#GH;_8s%daUy+i#BeFXJTIS+2UL4txSY_^5b9Lo5i0u=f}Ui zJ3p4??fLP~;0Ey**JLET`zwog()S2P9f-drIZnJ1QoM~@LLG>eLW*@liVZ@Fks&t+ zV?&BBh7@~+6jMWrZ-x{ng%m#xDbB+>zp`lKg7mEO{?y&b_HN{bwE8}=WE$8fmJ2D~ z7gBsUr1(Tgu~kU1LrAe(NU?uNad=4a-H_rZAw_JYPn?Z)er3_dT&(eOoHybJ^1Kr> zpSNP>^Ipt+-i(>gyD{^|(zThFuh0Bd^j)2v^A9_~YeJXu+R!a|;zRK=B2Nn4l0OJt z${&XAyo}t&y!(@n{zCo*<7Gs=7*Z4ure3jpNU>T-v3|&*V3Uwy>yTo{kmAcB#Q`D3 z5h2B_kmA&kxz-x1O{@NUTH+4k-yy}aY0?g2<&fh2A;m{Sip@fbzL4TeA;s51ifJLm zw?c{^gcPTT6hFl}FC#X78PCM*=Cj4O#>a0q;hwxqd2e2(yg4sZ-kp~zZ_mqQaD#Z6 zWF)-%GI9}p*JIR*xHZXf;+~M=iIC!@kYX@*hZh$yB&1j)zGVCl-Yi&x91Og%od3p8CXlLW*@miVZ`G z%|nXqLW-S3ihV+g=^;gIq)&VU>%5HEI00+CjO2~@GLm;<=JQs}eBO(h&zmvxc{gU> zSh_az^7WZNjlR>BLct+?_o*B9&&k5a@!yZl_m1ZxY7>@B#rY$!J-I5;-UCNJz zF61Y$0pAC@1CMuMyy4sn9t`;ics%4&;F*vwfR{u5TP#Y`mIBLTi+vwR*ZSn+8Q%v| z>6RAX2U6*o7T*U_>6{kd2U6*u7T*U_8G;ty2g@@V z%wrC39&>Q>m_wV#9N0YONPZtE2WoyFXbi!pV#bl@Cq1;1PbNLAlJ8Ba7+y&iYn=RQ zvjfk+na1`{l$V8`Bwr3aS;oBX_kkMo#x&-QZOj|rnAiC}&|5I?O|A2*tbHGhoAwiM zX2=EL{*cRZAj@G4$Y=5;o}7%4;hw>YUt|805As%w&!6Ji)O}#jzhIQXL5ZGKqpU~J z+!XV}zZ@C5l$(Wa$?u15%M5)(E{T&D~O0=Sz`^ zG{2gG|ZoWvb;{So7BE2nur%~!GX5Arou|3>}) z!G(dIdLyp`&!o+ImaEq+mk(Xa6+*Y z9Ex$|r-M03_T38}iQc?Qf4QIE{LTx>PW-)ZeVl`#CrM}fd*3pGcVCjeK;Nzym3%Ci z74m9uW5{R0OCfWt?Pwl@rBYY8QcK-wf3EdkV4U)Si3V<5t^e2c=6SC_Ecf}pKCIPP z%jzi$2NZIR(4|~6bW5%ix-Hj#EZvL;lK2P>ua)c#-I7B?mvUI>LT-q0tsclH*fSoF zKFI%5L3dE&e=2a$jI@N_O8z40p_P0l>0y;zH$@s=Nh38c*XMb@Gsb;71{@#qB5-Mv zV_ybKGKm3s5q|RK&-1O>`3aOxobBb37lxiBo$uw65xjf3zDD2v7?7L^iE@RrO-c( zF;xykV|-=Ax$$JjN)bD2{9bqt@8`E1+|P+Qw4W1mWIre7z!pW0>*vHA$A->n)h~rq=mK_H-}CEnA9hEQ=vG0Go!~9egchuFP8;PZ#O#8LW6W zW<|?k7)K-eQul%UizvAS4oaoqSvB5APNR8x8p@|8ct+?_o*B9&e-^qe|MIxuc{Nr% zj#+B*iO?6vpJQ7QCIV^pQkJB`tmLjN?zR5=ih@s$yWq|NXzv?^j}jZ(|u zErA?7eQAw9BU)-XvZa;-TLL+*rIsUEYB^A|)K($*Xv{crO436s`OBpF=f~imk{(`3 z7uzhgwP}w{ef^{4jL@UyuS1WKF|Yf-U^M1UY|NX~m^ZmGuTyGo!Mr!M&J9`nCoy)p z8`v}C3E=dQH-cM2=2H7G&7CpQ-7{D*6|>aj_b^ILT#&jC?D-9h5;!Q)vuc!D&l5B; z-_;UBmxJJvp<8lr=(haQlZNO20#QuDEH$}v=$70ibSZZYUC6IsX>#7sCU_iyaR{Tp z=#XQ;*pTDFjv*(4Ng*eLuY}wS9D*%YYP!}Z#l?3(RJx_bcR*Bnrp0$aR63`{cR*D7 zr^R9*w z8S}cI2pjXpH0F(M%p2dB*ZB^}TQKiUt@C{LF&E=z-2)y9xhy+c38VK@U{uI_JI`X! zpRiPJif1s(O)j0rP7oi!2Jr!VeHdkMP@-qmD7UZE+&2y74?n~GLYH#?&@DM7bX(r` z*Sca9^DxUz&JW#^3qqH2Vdz5s2^&yu=izZS#&+j|i$h)pt_pb_xGCh#U|z`E!Jk6j z10Kf~D>q&1lR}}~RJx@_xvBI_i*i%xoEGJ#(myTAO=SpLlv@s#%FU?%!cw^@Vt0*l z%S*5f@&YWk9Nu!v!7aBO+A_$2Ew>!Wa?635AhHlGE|5jIwVkBm{$<0Ey%fV8)8TD&eDmO*!u2F7z36@)4faR9MTW&eH<(5NR205_hmLpkiIZ(6QrV#ve z%sBG4q=!~=a60~Bl^mM%@JhPaX1UE^>^W&(|3vx6(39lzWz6fATVvjs#=NnO zdE*=NI_35j%zIPooW(v)!nkQyfa^j&1^yXwH8!^n#(-RI$MED5ER~yLA!fPB$1%!H zye*y2fjw;)WpGfUXVoaTu{8VAQ2rMMI4*Q4w+r2p+lOw;3;teLjN(Gfa+7mHx8&T= zrTlg1LSBLmD7Ww6@p~A1JPG_L1Y z%Poht402%0El0B4a-e3pJxcK9(lPf|^3zEVt>l!XhgI_Qq=#41#Wu_BZ}?a__4QAb zTZWz_XM~(Q0UO|cnfxyhX{%1um7-3Rs@2BQoPO7yH6<#rX#tJ6?^2?kyhx|G+3Zpj-$ zx8=i6r;3@igyIp*a+8mSZpp_&m+~*63;7gAxy|Z)4|!!eMqyq^xnI&lD|t@R!zy`u z(!(pMljcQPo%Wd2*FRBC4LwO-5PGtVdEJZBm^Y>|Z){`U_{O}>MR^P6y{UB$XYCtf zT$G)`?jdJ^ABVga{4Qj^DC^Sv0+ud{VhZL(k;h|P6!FW{ePGWV7|EQH=vg%`%F{HT zNkjSH-{G^NOZi;rmV7aETdw$QoomIrFfWQ+DRfJ&9J-Y64qeFiVFND8HqWpJ%!?w= zN_uD|?@oGHB?l)b!z-zi=0(|#=QGmS{)zIu(39k%(354%>t2+`yfKY=V;l3vH|BLN z%3Cn+O|5e`*1jjkMfpBBIpj6qmXI%ie}&8!I~$_&Kp*ssn+A>!*?jsXx_I|IWqPG@5C5Bd7BUb);ilOeyteD|GRsa$}q z8H17mGW0tnO zCUi?)8@iO&g)ZdpFgE%0GI<5>eV*^hVJu2~C#3iZ#-H=-?j;Z9!1-NyN9)a2_xMkx z_a%(uFXS?e;GD!N7)wobiRqlWYib-?cEXzUk)s^iIn~XX?#>vHH|R2^RoPwRi03ix zPRt{g7rvNIVBR3b9Lxvu;`|^V&2T!-!*C`X6I;)t8&R&};SHG10e$Lx|DN5x8!d_x8>RYip4FZ_&LVp zwmc_vOa3BsDbEdE$k`Y-Xx>tJ1NY(aZ7=DhzmOlqsOgV@u_4EU14AAHeirhV;Ljl+ z1po7Ln)XgGGUQfZO33Np7a=bI_l0}}EdS3mZDp`U$j^YOArA-Vhx|2oDCFZ{2)kf? zuipbFfBV$RUATPnFtt*-16oH-t5j}+)+y5}mHVJIcUq-#E3|H&R;k<#t%s*oDmO&y zm1&jAJ<&Sh&`RaDXq|UxrE+Jqt~<0+xj9<*99pT|AFbyPtyFH2*74ITmAj;M*7Qo{ zMrrX{sal^c)4F|nr8317rZB5Kpr&(v8?Tbx?Dlrf#V=a&sig0Kvr|vPFIw`6_|~7# zBYjJ*UcsQA5h=dcXi(3los#}2?f>nXoO@B4&tI2^b6$xnSt#aW7K8k4evtG0Av%7B zu|eUO*m)k^*tuhSV*vl_jcNkMJDbomGaLU;&QfEim}`|o;Dit8{R$lv7$c~P6t zaS=vr;h0!d9^F{fJRZ)+bS4*sF6F||EqPbywtW9VxE!QEObkb3SG+0 zLl<&uEKSav+69kQ^4?!aC$oh-wvkUq9*(g!;o!))nq5^XQz9xdyo)bSW2xZpphs zx8>bS)F-642lII4y`fw3zR;z-KXf4<#s(bkt4!ZG4d^eVli67w+c@4lGS1YoIvaSV z`_pq$^3ZuxeVXPom|K+3hA!oEpXY`sB)dcJ`9rYfC4LWE;Wz8f`VFn_GM^ZJ=5#7>>!xPd!8iQXq_r}Do#%@cGp zt#V3s+AYp`gqe?}>i`#oF6F||EqPbywmfaAdb^6#G0#e#5xOPM3|-2zLKpHJY`|H) zg2xd>Iv=rjNHHB7aL@D5I3-8xZQv=*p!ZLhM=u}8xKiTZsr!ILmzX}ncGuMS2%DXd zGkxSJ-D6vu>F$gHd4qAv*&Pq^%gJoUU4VJS^1{%ioD;ewe;c|juO6IEY2F~kHJC>% zuMORj*M%ir2+kgbTVg>$2Ka?kxQhfeZs+U*ed-FJnVV&%*WF0 zfeS*Ha$)F}yeo8D-o13aI>kMhTa)*OZpr&Xm-7D5g?tzru(en5xN#c5iwSfx`^jS) zTgxM3KaSPe!2Rq`&q>Kc_r-+fGniYH&xS7LbD>-E<QsFW-04a5K7r{}{#U1Yf^K** zX*lgx#XQ2y$I^9x3qqH2Vd$2;D|A~vux#4yRV~GXm}ey)3f+>6LYMO4(1m;)@uY5<|BJIUsZ?i_nE!1{;up4O@eHK7)~g?Z9p!a|V2BH)ox| zY-D!yA2P55gMW-g22@5In1RL^GSC>)$iV%~+~Dnz0l7KGi-Y(=>OLTtw!=F?UebUJ zWG9gU-PDU|WT1_Qn|gP{xg zC`JZOTRNZdI6Ur&ahhT(mfl6DA$}J9;)2}YoaY#K$3;fz+E(`y>?QQxi;>+$;Hi+= zgHP=yvTz5;yvRm&9e6d?{Py5uwAYA$)S9Xe->5amES}fTsZJ_teJ}&ZAUA|07~aUmJef=tOGe$tpUsZ>1oWEnP#5jLZ59jI<_r?aC|DW+#4vF)Z!!gc5d~ zG2g{Fe^C$T{2Rj?=l^vUurKEM%l$%^a{tgRc}VECym7@i!le{9VV=MIUFeqledtpD zA#@?89Bv`S?}TiuT% zj`>G&+9&Gayt_1pH{M-zFdy@bl`7H6a~;=nU<%nlg$NYukQ zqsH*Y8R=js<{8Ohp-VYDbW3g=x-Cb%J8ko-mSR)PGm;}ix8!D_OF1fZA-BRfqwZ(y zgYfumj5GQ^_-V*|Mn1Kh(-1~MW=H?wjDEnVyD?AYkV<7lTiwstjWHZdV@%^<-nTNl z!hCs`M`M(^_(|$MAknR+4|RD-13uwpCxoYxbyF{QL!^-2IMZGTXNUXrJNkPkYB|HWZ)z`{t_btbHMc>a|V2BH)k!3g3ONoLk51s zsDELR0hJL4W}q>K3^c|xGVtm54C*-nGXwIc7#R?kr|tt1-D*1Yyrcmc$W9^yx~Uh_ z$iUa}urFo?KDsl1K!u1=NNa#MMmk`R`)aZyP5RKj}c719$ zk%c=z=0!HL>%i5q=KI=~w2#2d?ID$_4&SIX$Lx;rdL-)MR6}EUBNt;?Kp&Q>0gek@ z%I!k8bz-IV^N3hlg&-jYGHP3#-@1sdy1H7xEvWTk@sQ zrF=PbAz#G?Y!1AS5zX^|jrPYQAhn>X!#B>~G4D%W`$RpQ^KT4qoPW<6ECBQT6GNAS z;F6(Ra+%O=dHtI85h`xLJb!s(=$5=GbSZxqx{$YG1J3{Bc>GH8-e1V?W1NFH6&rB= zd2F1&qjfj%{LiNMdW=K=1Gpn(K31RFO$6aek$GW_^LOC+So8dEqy4rB$oZ@4@Qw3# z%-=EYzo>_E{*B>{^Ph*4`IzS~7lbb5!q6>wSLn8U|JrecODR5pdH!*pN~CVI;*LucC}-tNR(- zF*{&>egyS!KR$Qpg{HUxvH@To>{ta9_wrz^fsb z!u_fk9@Yk%gnWH0&wfT_G{ew3Z$_muQkz)~v%8<0UcPgXOdSynX zGBB;LvPpUo%y7VH{wcW_w9Z-CQ6o(--Dne&`ual9wY zsElS9T4&9uR7RpTcSfZ$7_IAOR4U`qx_w5aG9;~sXH+Vq(t3VIr8+xWN6oBM4@B#P znU%`zGxDsNos-UMvX=9T%xGSZ8O^IPqj@c6G_S;r=2&JlM`~tt5|MYttZ2DQ=u++) zx+T9Fx-DN@uTGYt=Yvtva*5Eb#L(p+xMb);mbRM}eHM?-D`CWM>__79meonuithBAi7KBH0@h8Ag78HpBYRvC;IX;vAJ z7HL))k``%JO^g<4R((HOq*>+O8QDm4UXW?dD>BV_J*GLY#x&=(nC83^)0|_O<{YV+ z<~EU+!%VYWK6EKp2;Gt^hi=QqKa?^xZ;;{%%olF?WayUsYv@uw6}phmVx)Oq=Y{)I zc$}EL_ZM;>j4bXCjtO}z_({mq!Q7A+gFl444g4kK-$6+TJiG&}6Edec$1-EnE2A04 zj7_gpMlxg5E0w`$9W|p;8IRTpGb)uKX>mhTMy16KQ5l#PH$*i$THFwo+vgcK_5@4mdsJPr=0@F9Uak zya&7x@)fWG(QuYeHOHc$4P^|EonPoi8HN^VRvC#FX;vAG7HL))j}~cG8Il%hR=pA} z(ySUze4deJm3ybvNONA0Y0fJ$&3QehIj_bv=e3yTyb{x#W0~e0shMUYKZu!T`B3Om zE(+a}kB4r{-}cs-Qe1+WW_fAomb@%A7QZv)@h&&%N({e%RQZ5YLl6Qq}%d>~o$x{3rGt=^%&@K6k(4{;#bRlPB12X+D zJgz)6GA%!Zk?CHrS;#HH=R$rF>>Khx@Xe6NgP(>x4_qJeX0Rw^&UB7NK^w{#9{co4 zWf)qdS!EN}v2Q$L#0bJY@xX_yy79+n^E6;5XKv^2B7kl(@hX2SQtPeYyqE(>`T zSQzq;;E9lb0|kDWwk%jHPc`2qRFU0iZWtg5E$@Jtv z&GZ=faLg>oBSM$*$j~kMthFeBvA;FOR#%{i9o;$;%QhM`4y zs*Gg1W>hMJ(V{$6#-l}fsties@>Cg>7UiirI$B&0)kV?bdZ;`asxX0*U=rn-&!thG zd8L+TUZ?rbt2F<4jpjeE(ER81ng6^3^KX2QznT9w?G;lW|9>UidZW5L729B53^_JG z$Y;3$qqj*j`wRI+j5^x|92oKtaD2#F;LMO`gG)kQ0d5a@H+VkezrgZD!`bU&#rYe} zFme7WBgOfv3`UFdR~e5M=dUs(Ee>5}R9cj$%D|~S6(3CdW@9TqLV zW1({UjBI?zBCpAU%PTUYc|B${uf~k#wV2Vo5;K}(nb91nnbDq)b5@ucO$=QQf=h;O z$z?*fW%Y?VS&GvzCb#A3p+Lb%}~bh*k@EK!_XqlDkIS%%_@V@BF!q} z(IU+%L((G6s#l^#npMMz&ok1ja__VnY0e8W&3Q$pIj_ew=hc|zycW}(S7MrTEYqAL zHPbws$QNLySzZ{rlygG2WM2jzQR0gAU6d!w0#-nutAA3=Tq{R(U8I=|{MD?p^aYIypi553R<@OoL z4SD^V(g)mnMP@p$$4uwdnCZM0Go4prrgJPaog+0feHxKZ$IP@mBXlXx4Be9Fgl@}& zK3ykEaWH14|FF{sSH#Pu}|r`3hzYeu^|;$ajJDLaq-s4Y@hk zG2}#WV8}zki6Kt`b3*1*&9NwGLm9(kpI)g9LyI)4j700G8I{Ulv`Dkcc(l%%QK<|` zi!`fFiPm*9D%HYhk!F>9XXL}(H0K4G=DZ@)oY!NT^J+|UUW;kYD>2PEmTAtBnrSxj z;h1TbM}#irk)d1iTcO)>r%mfjDL#jpX8HNhEjclCDZdc9kh@?5(tJK1Z%*F%pbYQF z$n7HVV#t4jw~t7@%Yn5*egJ$TFxj6{n} zs|-eqOskAXi%hEwNsCOYj7p14t7b-vOsg)A7MWJLeMUAio!4Zh^NP%LUXPj1t1;7g zEoM5e#7yT{W;#b|X8P+y-WM~|a=*}}+&^?n9um4Ox7@5wmSQw!rsYVXpv@>!Dx|YmGNkiW|bjnk!ICi(IU;NGowYCRqmaUjWp*4 zndZDA)1231n)7N*b6$&S&MPs^IhJY8k(y~Xavx@z<+#wL+%9xW?i9K$ZyA*`HEWRK zR?IZZ+d{YGywIhbAG(ltVx+nIjj0)UJSBPWFXXQ<(mV&;5c2on-jEN1=R>{({s(7_ zeJ5ByFOzf$v`*J=LqD$RdhqxsJ(H2-;h z=0C5%{2SlnZ|462+7G5ae$oIR3SG)Yp<8m}%_Gh7g~dSb98G#K_J^Y1a}ydn+Grlty;`sfO3;FuY#nlkE8?eGVPe z^Yu>OyJ))(#&wok(yqr9UDuuevv~xMH%(LclTvVG=u&PLx+S*=-IhIDq*Gf-E)lw& z7`inGE*ZL%Md;3w#^Gc4o4Tq7&#C}hRnNej7&53OOMBj=^^t-*A+f{D<98Hk2^W|G)?`RgYUx= z)8kGKK2FnF=HPgEBer-BcA&R*(%H*s`s$g5j15dU8#%y9CkNN^NB8_l_-{*I&qy7@@_HA;r%_in~Mp6|96W z#)?ft=F`^e8jSEa;N*lfsZV?}q_{Ms_*+P^dUDk#CWKtvYj2gk`U;)h`U;)>`U;&L z`wE>sr&nm)9))ouDj8?8QRgeT=UDwZtc35$6@wL?#vuN9*G|ymP#+IH5A~JMb5TDF zJrVWV(34T`1oy3V-q17MKs_mtJMjt{$epMSpU*7Rq|_h4cXUM+kNS^*I#Mv!MG#P#;MlJr=re0`=(>(i5WlU!Xpy zLV8$quMa+tab|^dk#vjt_&P;0i@tu$0+iniUCQr=Zpn{soyN4~$3nN{hM`NjQRt5E zig{NiAN_@V7Ne-d@U4;*JBAd;g**k^6jD4BG9RyA7ho2kTq-^86B~sTdxjLJh7|Kd ziltaAue^(U?X9v`3oyI20JC2UFgvyYvu6uXw;QB$*szjuCfx!&lNH~Ir2<=QuD4dmi5N4#0qR{A^1IP} z38*(*JcX_|T*#MVi2Hs&hLgPa^9XxCRu^EB3}yp`hu{HF4a&3h5&07WMIUiev|~tyBG&n1*EVKhjmz2H zNpEFN+=4GOc`LrqK?ZUyjFLwxGjf;Ib zjyZQUoLuW^@CUU%AO61955i?rc}?jV0()z{CET^vQ{ic~J|Est>-@T8N=!K^=^5P3 z{eCGW<~)6&$+4PqwJ9;@YE$ABR+|#@gA#9i5FRIO1#Nx zQ{q)tn-Z_C+LZjb*3tyT3u~!dKAq>jJ?3KbTAPc5Yi%yht+lzhuh!;bxpcPs_Lz%N zwKf+A)!JPAqSof(-ddZBb~@XAQ!X~EwYiv5Yja@^ykRoRqx-IP5XU_oqcSf9b#WB( zlGMG!BcQI6VkHi?u9HHphH*!?0d>g~a=YlB0qW{0E~A)k!y6-i=Uip5rFUwk>V z!rD6$YkaZhnVpH%@2kpq_1dqHzOe8ncPFSXb0K|=p?eun-|Iqpx9Q#l)K|QaUURzl z0rhP!q&J@KGeCXu3+d&j`wmdoKq0LIx=VIgmqQ^f3A#T4>dGjj)j{{(pe~X^S}1g% z4(fU-q%}kL?Vv85LRvm_FU^V7Ra8hTiSCbsx}XX+3wx=;&gvC@4MsB5;6)-Bz?0d@Hn(h{co2~byZA$?_~dlgU@bs;Tmy2paLz6)uM z(|shEjd^ROFS~S$y6QV0h1xHMKw2r0f9Qd}BR{4L~bVD;_NG%-G;_(n)^Q%LbjNU`+z#@8J-R>2zO*Vswg z(O1(#$B9!yirYepL1{_j#79GluY?po4k>O8nUIz=ZV9kKNU?iJ@uQI9mXIQLGETgT zb-wPf(VKSC`J%YHlitdlxCP5HZ^g3Ad$BC@W-QCR8_UvIy0$E3Wr zcPPxdpTfQdO}qLuX!_L)p@~-y=0wcAdShtn)q6p6udblUS1*8G0`*cX%=D`_g63bn zC-efSPlet9^?bNg+6Z&uvKXJWgqMJ7>iHBLmAc0r397pLBDkQ|kHdFNh~e*r8`b)= zaL-yF0Z*;1_AyF&Ep^ z+FZ=2wYj*U*5=~jTAPb^rL*0)$6Rb(YjZKZ*5+b%tf$Km=Ti3$M}xXfii^>8ofPt_81f{jOQw*|Mfa*4eO*08AG)rd zLhfW*dUiMp)P+>YgGpsuMxUK!m_fV#X2`D}ErLW=52E9BZ3zQ=;P=nA=GbRP-o z`YYsd(R~r9OR;zy?TasmR#=>9pV%b}2|Bzh*? z?NfHj?JlI%!RY@1b&(X(LZN$8P}fT#tr@xx0CnjU((M|>&rAGI&psu(=T6J`<4eH`6qy?LM^1lO7~izuGvCbw{-6S>hdk5B~16RpswUX zTFrD{4(g&Vq=ilQ)1a>JLR#Z=uL;It-dgF)F5RN8`pyTUjX05t0+IJH!xmXZV z_+CP<*eK*yV9$`^)R1C+Na5QE)5L}$#U3H20pCLyAm)V>zJt&!d;>w|_Y7A&6U$$B zs4v9$7$>{~NMYWQ!dxST`9%tIiWKG%Da;*Gm@lL-M@V5_kiuLbh3AhHTZham_QQy) z^y`kiT0h|A<@y09uh$PadBJ|b$t(5)j&2XZ{D320{{hE>`3lA>_>V!ALQW~gO^TC}V?*=boolo3NC(h<~u`ZcesdPY# z{~<=D4_a67ds-;n@TqJ>mHp8eRq43cF+JI$Qp8gGM|XaV?^5;cUC%MR>p6mVJ^S~r zXZPOk?47TNJI=Wo9p45#8H-h_R^y~-T{*K-)r;wV;?EOU`{*iq}-jxDI~l%;tzM^MDs#pPO(#isbwv^T1_!+D-%eMD1vH$C1ysPS3ah z88|n|aiShNcfinH((@f0`ec%wSI$*vemHgY2}f`kb7v}UO8pZ=?e*f0SLgi-WAMc@ z6>~A}qNoR7)*0+!eH`-;^aNYW46o&^^G; zzTVWpH;#800S?Df{lg=pp~Y)Mc1ZR|RC-<+qcO5l#9Dc2Xs%V~=069qh;j(?p9A;; zklp(NkiGi?kexSQ0PH&-i)E_T=cs61${%R24=xs+SCeP3-qBT_Kx3=UcpBYTfIQsA z=g}@cJ8xdzJQfER&2;dXl(zogbV|Vy(=c8Ed~V7q`<&s%E5K?zT{{gNC+agjzT?Q} zUrNvWE(KR5Iabs|XAKxSIX&OOp*<;P=XXhl(KRwX9VZ;Y@@LId+?)C*h}!E39k0&2 z4rA~MGZnwXxQ(J7d`f5VXNb8s<{`=-Bt5i}4sIUe4zzd1@O3bl5i)1br~9X_KA$?7 zPgwu^r*G_eHm)wftaW)|=u*xJ-I8-dx8)_FhsfK$P?xA;9%ik}`Jvl#LFkrT7`l|V zhc4t@*nnDp4(~5voXEcoI5EkkK`Z2n;5{K%1E0Vat96|?n_{5WRXU(Wt*i7wi&|Id zCdwu|B+nx%J#U547+EP|t&LjGVa#+6V!7lHW;zG3*0XzSJ$tv-v-4)H+jk!p%T#@l zqoPHvt6WShI^TypgY}NC@&p=Nb;i@^)_NZ9;`3-1pPe_aX&#G%i)K3b(3G}Dtvlje zj9T}(DW|}5h8wj$mZuZaz;U8J({8Q%{JZIS-;?0!B*%(+Xt&lKdO~`>gF|~$%uadi zLf3xj={VsCmOpEz;_YeZ1W|kK*1GeakHII*RJ@FF8$~_1TkF&Da4O~@${Uj&T1f{t z5Ahqc`!Rg|9Go9AXV0f+rmjApI=NBn|NZG3dwu{{4`SB3d?<7&7lm%gheNmJW1)x0 zr@xd+^sprq&tTTNd^U7jJ{P(rpATKi7eW{EpBS}%Sm&?3Z}>&NzQQ<>O~Do+w*g~A zehz#op6^> z&Ot1f9KuZJ0M>eTZ>?wV)_Qi{taba|#^J;=Rp&&DT35N4SaiNEc?RnpRpkjZHt&q5 zu|@Uz;VwRpcJbMH^O`nXUo_Lf^-*-+*B$W$My;>Rb5l-%=L|P${R9S`oCb~)A7miQ zI&Y?;H_e(L>Hz0;-a(zWFwN_8X#KqV6@kx`ENa9%xlZW>&V=zg~MxURuGM)_pYLo4av<}sd6`$CMneKS}PGAG2RH>R#W zpE|iw?f?Dh8+-1Vge%NyPYhiSf=h;O$s%-HE**M^e8(;x7e%UQV^+IdE_7QiAG#%1 z2wln{p$oY(HlW(K$NT3oPGl0;E#w|xpOA-u86l4Zr(%m$yH1=(>aI*lS7#49KdSN?ydIh-D=Oyo7HaLx;y7( zs&0xF)vj_evFLnT@(k8Hs>%~+Y~C49qg(BHxQoxDU3_-lyry|94lbJM;QA=K)$WL8 zctEvp1WY+~mowa`_Bjl^81uU{U~2~B^}Lyi&xQk02k2J2^PWxf`W#w6?^e6djZ7$? ze?Q4iwO`NEJJRfNVj@q8I(w$#>uKl&QG4xHyYuS7bJO5@M7P>Kt_LxXQNE3xdyLY- z&11ZU=kqb{_LJb5kU4)oeKd9T`P9jcYX9#~-`MkNxLQ4}g@4N#t`WMFYld#gwL-V$ z`$G?rADLVisiGIN+U3yDZ8j8D3>+QuSn%DDCxcT% zo(ZnN7OQrhIGb{y+EqHBMYXH+L5ufxm2RSNvO{jdh)T~lV>Cuqidbu-+H)8)or9R^ z9KuZJ09Jc;Z?$LdR(p2dtakgh+BGjz^_OT-?J5@&i_W(t&tScysyuD0O za3Jac-D-E<^67b>L+j_=YWKO33FY%SF*KjeBRqWpBdR!*r$n7SQ!y(Iogiwj-D-DU zJ$P;!T#x8hyT`QzyY(35dPxthq=TEs_!MKGNzukG%cJEmu6bUgPY0*2KA$?dQSJZz z=^J|a$Tf~&tg`)92>eV`$D(mxX`8CE_5Mx z#0FIRiFp4J#xYdjtdQq`^Fv+?E)RJPxEEWj+I8Y=%7JQE>3|m1uF?lBs$HdHiq;Xu>@y4CKyq3L;_L+j_=YWKO33FY$zF*Kh| zL32pz8Yg~?5q0)V#jjHT1W|kKR=e}+!E@8#dPKL{J+9R-k5O)w^w3H=xOt2%+HH)x zy&mWdnb+vkwNqE0Po3PT_W%C$jXh7o)y|mJE_VrC%3VXZ z*w5p1;_Rqsl@6jfRQjOB&*N0OA@?Jy?2pE%O2-e!lPxMmEVc3TxE#eq=NQ&Yj$op* ze~Uf4x7f3Hi#fxkVGe3`0)r;x=JT6aQ?W3zap2k+q;oa}h<>9V9 zk9O_Zck`0wv3R>=ri1I?-Ji!fVhbKn>pnN(R9((*qt>5f;L{k_Sk#WXHS6>BlB4a9 z0mmgdPSiuYh3L?c>G=*0{X>$SpIiN#r*BVPeZmnef9_1h&r|;dQG4zFJkELFjlmbs zRGg3oj}!IaZl!xz@5VetxpC4%E9v0oAudIG8H{_q7FaK2zV<$SU+UW4r&bR?kLw;_ zXJ2n>;2X!AM1U`2*1vpc&s2t2EvZ<9`9S_9KgcURiqYq!nfx^d_$aWqPG@Pqg?~epGIY7XN09%AL{T-}OTHF)H^*>v{fNRg_z# z#lH)qa+kFDSNT+Klomf$R9%a4VPckj*3d-tU)@7!OT z$@}(YEJq?=oj`n!?0j?ZX@Wn4d7b35p-cHv=$2gJ>*@YIu#{p5#)Ou9XXsL{7`l+} z!F=E7{3WRs_u}OM^S96Ct{CsCyMu3rJRbZqpK}cbc{e*g9k%m=W@5aAC;bf=5F>1>U_+nzlL^6Efe+ya%#)-PFomxO`go zOs!PzfY$R7iPlkvRw}ne z>y$$)l{=#~_s~k^=4jn~Xr*$0v>raRQn^K1uN+#b+$F6OrdKLAO6$Dom1^&3T{pc_ znMR)7!#{gh|Ci6e*VKFh-psszZ)V=TH#6_uo0)g+&CId9nK@GPX0Ar$)iH0TTqATT z*9_f~>xOR2kq6Y5PO%xrVDoj|V01{e}D?#*IA%Tpsdj z@KDG{!3z7P0q+J|hTIlR3wZ?iRmh9LqL5F3ckP#^tqQgYIS$MWc?_5n@)Gb^$iIR2 z?4PEs0X`dYdvJKjoUObE-s0VYYd4)!E0xQq#dTG=16o{Hm7Ac&byc|!T3lC^TcO2u zRk<5lTvwGFqQ!MpxhGm&SC!kM#dTG=Gg@3%m7Al*byc}PT3lC^TcpKxRk=%ATvyfU z(c-$Q%puPj*EJu2*EOGj*ER3o>za4(bL@w~K=oUMLpA zt3RlOZ5%M!&YRJRE`5}J|9t!z5SaC|4whGuf zWFMFj@@Q~j$lroTLp}xGeNdXVI@mVk1aL&iZ-KcX^VQCK@R$#-+=a_G`v+GlcR=g; zgDaJrpmqEqmCAk4I_r>1#v7YD)&U|sHv68ZP7YqYNc{# zwB}B&RBn#e%~LCt`=j;n)Jo+RX}vPFQn^c7CrqnUZj{z}(<;@S(YkJ0r812?yJuSG z#WzJJw>$6O+nsms?aq7mcITaYyK^jWcaGG&-CrfL7mQ0Ryi+WMzsZkFzl4D)u&!$Y^^5ur)JA^X9FAuj@pLOucBH8qW06>Jl79GDsM7%(T~CE&4;e*^ECmZq%%J{xj- zaAe41!EZud0iF!`EO_6cY1%rVFJ!*mc@G?{TX5~B{@_aG@@a9kRqlWmS6k&KXmPbw z?t>OrTjf@0akW+Mh89;_<%Vc+wN>tk7FS#4wrFv+Rql)yS6k)gXmPbw?vEB%TjdsM zakW+Mk``B6wQsbz+A4F%v&PlV2jJDtC*al2`}b<+-Fvn3-o4s+=U(j`%d4FuHLvz` zqR+xOXfYS#@+H=b;?*T*Woee_Rb;U6_OWW}Am77A9n9ikKV}`s?}aYq_d~bj$)VeF z^&{%5tXKoH4&<7lTXLad?I=8FXXZ_(rtSO=nc66m=JO&a7@T= zgG)kQ4gMDL1+d1<V?*|XD?(lmo(=gjSm&@b?Zf{cX=ejoS5@Wx0s(_W ziOL{?s0BX|QCs@OHwCH|sZy|Dk&YCsiXY<#R%mnYJtt_8pivVH8hoRt#h}578YM_{ zqO=&8f>i?qr%2QyQG;eMKp2B$^!@$U+WX$!+IhzJd3m1w{D147kG#_>AjcE`JrX~#I@(FdlPILHePU#YU85Xl29mV!u5V6hZL@&k*dAd)LsECrFg z!D1BdW zbnumCu@poKBgc}Z5a&QkA zbQ^7#?7omYUTt^psFU{6*ya0>pE%xwJnr~k$dMnn6OKmS>iBl#Q;ydnw>jR4JmL5k z-c%(M~-(Re|G#U@~W%svSX2p9N&d>IL7RbJ}|LzL1S0wHxwcb zAB)r$$pb7>TO=p2NNth)z#_Fpas`Xj7RehdQd=a4ut;r@e8M8NMRE&^)E3DzEK*w} z=deg^k^I9VwMB9fi_{j$ODs}b^li6DZINQgu_U$Q1SqxR3@Eju|4QxXy;3{+uGEg6 zE45=^dz0F+r!=*HK<^_oCR#F0Bl%3jppsqw4GdGM$jK6AAERa+#5_#a!3YQMp=ljR z?{%)1-sjvPeZaX<`tP5#R36z^u#Kj5Aic}EL3+1yz4XVtLk%V&$*g@#w2{ zla4y+Sv1zc*~o_+*CW?CUXR@A_!HzWj(fF|3p6fUgk0kI9^~_mUqbG7ya)NKh{NS=Da53aL{a55@+-zS$*(vwS|D*= zv_RslXo18z(E^Dxq6HG?LklF1Knq0uD~-|xavt_SIwoEFbGv?ho%Gz#SW0f$NAMP! z7K3zkJP_kN&Dk&bl;^7S1R5`fPeCqnd|Lc>=8%Y{fD zV6{{Vk(|Klt`s8qfyK*dkzB#r&M%#Ztl3H-l22H?oEFI~EM88F{JX^~vS;^nkRUSjcbS|mrYcsVUvV1eW1w7{d7yqvB@abDGbf89PdIaxI--Oj9~ZFLADyzQege`X1*->07T2+oNDLO?#{K z0_O(l+nnpA7dqET*V1;`TR+1czi)T%sFOZOV+Z>+GUu~~b;!#cUx}RW_|M2E9XpU8 zI^Kai?)Vh)@^-t!tC6=kUW|Ok@jB#o$GedKa{O=P=nlJVKJs?QcOut1UXKhr#(a%F z5MB0Gd73y;Y#ukK>FekK=qOkK+iG$Le2cl;-ho{~yMrYu{zp^Ti+f zo9n{fDtMTt#UP!C2V$ICIQu5Mk}v+yyJ`C35BZbh6UafIvri8}PI5d0`H{L1mS$aBA7 z=e_`Wz2lpZCdVt0Z#v$B{KoMS~Q3bj^`km<5kFa9KVPB&hbByL$9~X<{~Q` zV_rrdh~h9`{4p{OA8U*+{vdgPHO&`)ketA3FvvZj_$><&boOGiY4gC|%~*XX^{HTte}jh-uAV_!2D1GP#&(3EEenV4g zOCNS_kd8aoOMmNJC;bCWsa^Zxk2`+d?#>r~=#Ocn_Ro+h$7$rB3j6d0$m<>7gfux` ziG0)X7UVaMk01wcvda!f-spG^k~v<5e8=&7$nPBg6FGFVT{ahav*UTl#~iOg1{`B* zXN*u|*EI9RAEeZ-LbE|$?n)wn%(cAXC)X( zEKyD|5X$M8T}gINaquykvRnGNbG`Hl=LYFh&W+OiYau}e%`|1V^h)Oj>BpSwr5|^$ zleW@!$?n6x!UjxJsUf|TMs~j+`LtsP@*T(TA`d(M0eOCpo%EXQ+^-0>60&5qwk ze((4wa@dV_*%8Ruj^`sEcl;!BtK$!mKRP~+y!fkj*~^i09AkDzADCFVps_3TeDMcq z_*nYl50VF1q_#*-VCjoLNPb|E+9J7vr7!*=vmlQVcnkq;{MDZQOANl-kjMrFQgQsU3Y+ zYDdqN+Oe;_N$uEEn%Wh5Z>KTQk^vgYXBq~Tyb^u}!&EAAvP9X(s96Uw50iD!&cP0v z)`9d|=X&YqoExOqJ2y(__Jvdy96{4MkRIvWAbqKGz4T?yb<(40yR3sBa>qZ|-TC4V zJ)qaJ?LcIn<3i*-#|w~8IDQ)WzT;NpQO75dBW|)gyb?Lz@t=`TI(8sGbi4z3-0>;o z1o^Dv=aC;d-i`d(@vq3MzGaski(KURE~LXTW_R>~ ziIoc)yF$+we~^Zcr7!*e#k=i1~kYh<|#|cns#~Dy+ zNB@=D(R-zK^j)bPJy&YSzLeUrr!=*HK<^_oCR#F0Bl%3jppsqw4GdGM$jK6AAERa+ z#5_#a!3YQMp=ljR?{%)1-sjvPeZaX<`tJjl%6#z$Y@=x%NbhoPklyWFFa5D|opgl8 zI!M0w)>qULyqf_>m08~?sWVK@)yUwzC$k1xNH$}iQ{{a&pUnz zx!ds`vSI*Wd%wJjxe;j7r1T zr1QleBoDA!_~H+e6Ik7R@dwEdtO36GgX9XbG`IF=LYG|og1Z>-ePHfkn}yyjnelzH%Q;-TrYjUbM=?B>K-$8 zzj?(fj=j^5#{`-)%dwZ+XCF3Q?OeUScKmWXzQ&GUzRU6O*)I1C_o;sNY_5AQjn~YZPU8SY#smH+&2T(OrAVSbpV zZAf~VbG`H<&JEH(IX6nD!spV*oa?2JJ6ESh*Ii|w@$2l+M`=lhwqt(Z4qs+E?p(b* zIlh<93&*Q3hIKrAR{gC&$!F2SIX7_LS84n|X_9XmR{w{qF3bs9I`ez#E%~fELOFGh z-R>O81BTT*{|GbOxlZctS7(0CcNr2*GjHl#zc;#%bAxn0=SJxZZ?*Feksj{cD1DK0 zgY?DD_0pF(R|ouD?(s^y-@M|Z=oe{8M2^F}#13C(+U8unJUPCX&I`w@5z+DR*q^C^M{dbhUZE~46D~H#cZc3dg|>U9RB;ibDNHJ zCujYEmW(SoT&Kgov%}RsG*KJUftS zHpqH`U0Y3zf|K+S&*kbL*^Qs^i<{rSAAc|=CU@;~{=V`aKL7u{$5$DPo*<23m?UfL zIt}3-X04wqL;UwJy+BB`IZ-P zbkE~TjpP|Vk|V3`=%nc4^Eu%KyLQpR;p^3oRv(eSzSPtFa}Dd&3W zjB}lI&i8zoNcVDXG<9y+8{NmbURv*5Cq2vg5a|l%M(LZJ8>DY`u9vQKu9JS$`4H*l z&W+M5oExMYoa?0B*#(O7c+7)x{@JflFS?#8F=DebIxLTp< z>;*La92Re$d=@{lyZU+j7D3Ke0Fsd_1{dyjo8+_VZEBy*E8fTXibZmpX3Q(?HvA@c z^kdHT(vLegNI&7+DE-j)J>{eyc5akj=G-9th;zMkgL9p<#rY8FRnCplPdGP7uXe7N zwmR2I-~Dgiuk=#qM(KN;8>H`bu9v>gxjM_=W$gEuA02hlXLC=sQOS{xan_PE?TY8x z;d3O1JO2Hd^9mjI8&$XXUx#j3BXbsTc#&Oweu4ay#+=0)&G`kV>JH55oMX^;)2z1n z@SG!#tp6g`y>_(r6T_ctH?R6QQM*fBZ9M0_VfPz0^ww@zryKu*mgL1dFfX%@s)?%* zTuW2pO634+MdBA%y-v=wD|CN;pqKcW)wNPPlfT$qJzRZ++{#B`o~j<|4wJNW{Uo2& z=CgX?tRr9CE}#nY?@KW|>~HqKXW zCbxe*<_i0$I;E#$DpQk*{}ASfY4#HudYN;*^drs<((TTT(w~ISr9XA9m;TJTI(544 zD*KFoErkA=Te&huMUi&~u;F0cKtR{N|vW&g`F(i@>WI{1IIsHI zQf_@3O*1Dw-MLCMg!((gJq zN}qk3y-{u7OK>2Kd2Ez6IyXq4<6JL&u5+FA`7~a~wpUlflicy;KhRC)719fh=NHmz zjgKv)+l&_!(j$MU^A{G8%IMiw|ON8arCcI2IgE5F8#e@f#=UdgEA?~p0S7=WaQzFa-%)^yjO3v_dgfn1N1J&_!dfT`IlBd6`sGz~{@Qlg=xoFJlaRzEbMb(y>~qQSS;fW{n#*>A%PBOA1lh0!dPh7l~^eFUM`)zZ+@+W)DiF#qZ>OuD+elE&jw zo!sgeJz)NIt36D5nCCv5=Pj6$(sQ52h$3f(Wj`tz|VYu=Q+~!R* z!v1#TQpY%zx~c9)aQkwB?uXHz3v@?}fn1>bVGQPi$J`jo1z!9hA9G$UJ(960X`~vq)|&JZ=XFw_mD*a917Xa4Hs&zQ0UM@9#F&S2K^V?5 zX&AzaWC*J?gwX98Y3Qn&w@CohW0-aI_W+HoeKt2}q=C9V%zB(^&2E^`ew)xRhl4hU zVcwQX!(1)jeXhd%td@p3S-Yn>QBNT~lAKU?PxwI9$K%R)|{_z-diw2(@K-xyvvw5yqxW zaHJc3nP8b4{h8omH-<97m2Paw1YdSzdnV8jx!Xu4xXq2ROrQaCWM?LL9;3pT%mgR7 zF_j6{xG|dvTHI*P1z&ZeEf;vs@~1vx%o4x)^2D$HJn?HFPy8CpQ@`@)7mIIcbPHZ4 zuLf!Ga_N}!3h7^*S4t0MRGhO)Do5be(II$E^aoxW-GSFdZ{TV%BWFTf`fU6m6azNo zF#AKfKvT=5%cQf;E2LovtE8Xs;jEE*K6F$!*rcm&OM%c;pG7@(Wq}Ui+-~7iA4G60 zi=A0GV{aI(VzuDlZ`h^rDM*^rD1YcN;Q$3vs$XjgV#!f zXVpnedfH_99D3@v6jl!mY>Q>By1*F8VqX|Lv)CENl%=D3!D!xd2JYnOLpC1%1`GNd z=X&YG&JEH>oExP_ZPOjuw*{}HY2TI}?c5-Jm2ZHff z*r88C&USnY@-D~sA{ECgkxs`hn--h&dI*5-qelu(X0@uCoJ}D zkvhX--xjGqEcR`Yy2N7N7O7V(_HB_m#$w+V?RTeH?As!_&#`3Rj$_h(8b_r4G>%96 zb{viN?Kl?g+i@h?w_{)0H)BufzWrQ!KZ~Y*q@OUJUr2|Ik1eEo{kzUtP)N@(=6~Ko zuQpy(NVgd;E~L-3;4Ueo@-E%C59fZz)5yQROmMy%{h8n+ZVY9DPB*q>f^WOAJrmsH z#z-c3)Qz!Bpdnh)3l4N+G81UPwgLq2aAP(TT<1n}F1W>wwp{Q_H`;T--`wcV1)j4V zo2vUk>Q|onl_!1;(r4ojp%}0shuI&>1)5qeT_#=Oyh0j=uuA%C|9p+q z^P#qHr(IbJgsz4x>Y=Oc7U&SpF$<^qAe@s~>)G-$SL#^miw??xM2D~ZP~smHBZ;&Eq|c-)mG9`|I4$GutN z@j#Y%JeVaO4`+$T+p@&t(Jb+JM;3EgPKHSCFuy|ZCd`!(ubGME5<$=X1C70~(E}^yh*b-5AUT6Etnk(qn#Nyj*&@^GfMf=he~!ENwg1 zNZPq@Ur2}{)A-jwBLbkBkl+-tTB4DPjB(gpY0Ezg2`U6xwGy-mAjQ{vu4mbf>S zMfY%gCX4=IH0RMljMhAQh|!)$7csi>=p#n0CQ;Ugr8#Pes+8o6am&rH0H-Y-!T%tRBm=u$TrcwZi%twrmPZW;ENI=$uBQpT1mhl^X-OV4E95xnO?})-vh2 z&MTywomWZ!=)6W6f>`~TFY#~Oww~bMWG0CI*#;B*n@#;|v27&y*Je9M@UPQ0i{M|k z?GM4fo;>kyJWKqW%o6{mv*;hwFq=gOFR3`pePV0h)5yoUGzK!B3FIfn zggJb%8 zL~*3uW^Ah)owf!Zaic32XdQ4`_nsF-;#Xgu_|#k;)BtZFC1-7ne6&tuL42>S-24 z>OJ&y=X&WG&JEHtog1YKM>RdF_kcw-tM|~w&JEHf&h^scoa>|~({`=*xZ_oJcj`T~ zi>7)H`Ih6&$eoUNBfoTf2$^=AK@Rwt*L%oOj;}>t?--v)@8(4HLB*wd4^lU(zo_>h z^@OE*4^n4Xs`nuEhoyQCQkPh&_n-sm221rGq>iyv??IQkrFsvN`y5N_J+62EsrO)w z!|FX$qp*4p)flYaLp1`c_fYk3^b=lYT5qlAv#m6%_t1St#MFD}>x`-Q(5sE9 z_t3kHsrS%1_jo_ji;SuF(61R&@1YMFQ}3bjH0?j9&+FB%yccLN7}R^fgKkjo3FwX^ zQ<>m!H>mdj4Ui+$d%#6*Q11a6E=Q>MfX!}D?*SS-N2vFJhuxsw0}f!A9HHI=7P>*b z2goswQ11a{H>mdjxycdgJz&@k>OJ5IHT&k~Ps%o2}p$`X%n$r6vhmn9zGktH7Al_ehEpCukYP^y2b_^qH?{BF$Cf!8&;V6@7YMgblOJ5_ zH>mf32^t&TQt2`G884S!?z~dE)p@n_083lyJ=9aUwpl8MAyKLKFoJv3dw3Mwo3Y>o z_o(+c65ONS!wBwC?~yOTJ?cG-;2!l}noWs&)O&al+@szL?%_D~UhoftdJjkB7zXto zAkQ$U_W-$uLA@7z#7OEr{0d9+eoNGS7&K@6)^al}z$Yyo!n!QQ%DU0= zEG(v5EVaV=xx=z4ESdYWy&3&!H2R_51Fmv|dJov<2K64WKOPX!Wzutwy;;b`!0+BTTrAN3wbf`8O|7{Nd4Jwg@yqu#>^{!#DMf=Io` zz=MC(dlOG9$AN5}Fk7=OZWAJhegL)5;XBgCbfLz0%-UH+#MpEz5`2ucc^&Yz3 zn0gN#G^XA|pEjo6L(k+!dZ zn(95|TaGs)cRJpU{L=9uWZH2CIpBV;_mHC;UyHonv0CqOqWYlXQoRSM8`WRbdysm< zQoRSMGc476kovS4}G06^&Wb)G4&pL zmofDoI_E!hKJWL?i;SuF(61R&@1YMFQ}3bjH0?j9&+FB%)q8*jgF(FqJm?1Xo`CK+ zLcIqZ?gsT9paF7(dJnkB4eC8W!{rF|9ODY%=Lq#4@UR=yd%yt<0B7AU8Qey$1}tLA?h&;YL#L;Y#qB_j?$@W8Uv!1dn;YSM!+ndkiaj zTuD8yBp&mAkJEz3yx+qJ9`k+=BY4dFJ&fQn@Aoi*$GqQTu)$;A?_mUwdB2AdJm&o# zM(~*TdlOIs`xVBj; zh9PX!do}l{_Y(IkIKe&Yy_$Q}do}l{_iFA@@73I+-mAISnhZtRXbP;1y9(}~vHETnn@_r8|_hHbS!TUWREI{7xVT26i{T@b0I^OSL zggoQ@9{f&NP*77-oy4gZK;YV65xiv&?-I@zDHyCX;Ng6OldoK8(8=bj86UC7(o3X8K zblVzu#Enh4Ki+T^^Vj9;{?*YLt>OG9$7xf;7{L(fgm0R#K zQ@V$j?~R7-X@zv9f4)*0wyIT9dBpjvrE&;fBb6KQ+UO3vE-r7lR`22JX%I_(%0<OE8=AP&`$SiKkevU)G{l-678`D`oA>OFLyF){TX`Z{CkJ@jg0>OJ%>W9mJ0 z&M$R7^&WbWG4&q$HDl^M^dV#FJyf2i{pa*~z52C!571yRsP}*e-JsqR&>csp_khFQ zpxy&CK#oxF0T;PJy$5Kx9HHI=HoHN+2Wapdq22=?c7u8kIDlbtgnAEH=mzy3AjddD zy$6)tpxy)ICP%3EfMGYN_kbtdNS>Uy5 zIq&z<&gcG$U6)2wsP}*y-JsqBCTMJUOQpyB+IYG2a_5!OtSLcIrEODGNz|E}Q zL)RNq@1cXn)O+aD#?*W0ncPSZ73t@UsrS%PW9mKhMRa8E_fVhMq~7Bmb7>5OdJmAF z7}R^f#cojV0l|CfJ&YUu2=yKiLQTDgG2ut3_W%u%yHW1}ni~x2JwOA-pxy&M=mzy3 z5N3>e4`Ztzq22=?af5mf2n&LGFSy0sY70WKo9mrZ?*XT|LA?iD><0B75d5Ov!w7y+ z?_tOtZ9~y5Ww5;3o9^M|(y%?PkgoL4S4zWHwMr^SIDd6?2woHYf!9WN;C0a(xK{7s z;b}BdqE33cbG`Ho=LYGS&W+N~{6_P;zJD*lXKAYUr0vcP(hlc(>9x*v(l5~L;#h;- z$Q^gs-RBk3XFa4F&M%~|Go}tf%f<@|>Ax8-ETm5vFDj%9t)s<-bc6AdLaI(x2gN?W zK|goWi0gPJ*y+YZCisgRlbPTUZp&#?nc!GArZd6WZp>tY_qZ{e2{c5mY0d>#yU~&h zG+>Uj=7I;^Xv+n443Q)4xnQmvow?xkZgk~>ce>G?3w$owxcA^!U!M5YpC^6|{fcvg^d{#<>7(PiBm0TqPc-c((kbT#>0{3I(#M_aq<^OEvY+hx zFe{y=N1gOvjOQ298;y@Gq+`Yl3h7~X!-a+P0^>!6w9|NTA>CoTq>!r9bU)djd%T>+ zyi8_-rEW}Rg15Oboe4I$F_Q_dbz?RYe9MjITyU2gR2P7TXu%Nt-i@|gpaENC1Sh)D znG4pr(Ul9XbfY^LeASIjx!?{rdUAo!W%8(d7F`6t`troD{ygz(AW!@n%oD$c^5~b+ zIl2WelUF-w@N#J#y~8V{M>wyPp6voB8Uq z@rO_h*pS2Q583Q%YPoco^rhbI3TYU^Drv8OzDDZ#P}@(Et|l!7LRZrk_0ZL9CJ5nd zv2dynhS!$I&M-PHg6ajMJCEIA)XF=BCS+N^MI$8EpanpajWIGxdo-=UHZ+VSF zQ+;CUT)#J3@7y5WGNHTh|AGm&(zu{Odb@MI^heHh(rq-mAU-=^&Rv$-9XslzZ>90x z=|bcKj+Y@sHcz+~PPguM^ z5~(vR-XDq79~SSAMCuZY_eUc2iZz`TB6W<_k{6;^Fa)g5yb#HKEdKb`?qkxv8Aqf# zERIL-o#JTp-YJenKO)4D=zUP^OZ#K&DShv=fZm&F>PLFJ@%%zs_j`TLZz4cnZ@i$8 zwi+)iq_-I_Dx`;6Ko=L%ON^Hk(r)A93aLCz`#*(#R@2D2o?M_oVD#pKFS^l}3p6B- z^yh*xHwJQn2FQ`YT<{_{hH`-qyJM+zElt~q)LrOUF1^7&Um?BQd8PDE&a0&ETE}YX z5_6$rjnv)jSS!u_^L5gjoU6NC;$~--xY?B@ZuVq}o4r};W|q2{C2kI9(M={`TNeGq z7|o)i7(24)DaLpfUB#HlqOTa!S#%a-CX3!;wB*rUjMhB*i_w`!hcUXU#jl(U;p;NL zLd1H_l@O#s8@2>pF=4~f05E1Uf%?Q~{a-upwcH7v_glKe&MiYi zRxFiSOA6`xjgKp&@-*%L+1&dm8tL7W3p5Cf z-dylrH~MmchQyKnT+rvnKrYY#IWm|F9(7|V7x=I{mP+T@@H&=B-Gz?j(#!nw71A#{ zuaw^Ayh`e>b*z>?!(8ZCBXu`B)=JOz&(}#eI#+j##Lern#Lero#LXMC#Lb(s#LZi> z#Le$ziJNz1(M=}ct}ObAaeo#a#dsi#o?`qqi>_ikl0{!Jp3I`N7*A!X~=}-(h&WXQgx_jLhM-2gy?koOi+|V{$6K+ z4Jmu0#WG~+Efzinit*oJ5mRh1?zbQ*92mc~xF`Y`Pg*E6=@?hp>?^}CuB%RX(s_?9 zp3r%pt(VaGfGv^G`A{whOJSKbr2h(ONcmOLkmhToA+@W|giU<5nWkrg^akg8=~tW^ zq+fMzl)m>r?fiqJ?{jXHzTde)`Y+D)(hoS-#U1;b++(ZVZ(i{T`dp4Dzx{87kMuFy zv*})T`G=~PC&%~FdExlJQomL87fb5YaComHIeam#`WxW)kK;+sn)7#O)yK1T@9Krz zi{He!Z1>wfOP##i5ANaGy1%=i`g`1;9WEp(|L(K>_}%L1?{JUj+HW6Cez$x4{C~d3 z{zV*BJoo?Q-kM-NZRCYJS^f2^nmT=4o#6Wa+10;0cmKaTcTe;9A#VR+nzB`TnRC7L zBhC%d%bgpgXFh7@A0mCDbEEVu=LYEt=X&XzoU7@UagW08H?Q~)^!0u`PU4&%J{z** zmzzH5T)n<_{KIzq*LM8Fb<#;%^4mOhYB)USX?Q7J?eKr@l>LuRujHI_Xv!k#xz6>{w>URQ&v$N=9{nfJBI&D~8>PoM zH%MRYTrYi%b2SUz&OJ(Yzj?*2=qvnqjN6}ZT`#?N*Sa`Jgyy2~Y>?-G1{F0Zu{&7oWMll*Gp)N79HHtucDE;A6dS0*Z-$!s8jf)$lTbvuDTb=8rw>#HK|D9$R$7#s8qo2@GJs}zXKX7=! z#x}2zK50C^kgk~0(2gynn~fI~(x;6V7SffE>6}G{^xMXZ3+Zzn*XK(L>00CC3h6Dz z#~0FrpU^oc6w(hEpIAumGd`)1zG_3q&5Zp98Z}Yf zeu7>a``QnYVaMMf6OQ}f#j|Lfun;-HaW!&@<2A@<9lwhVIX;X$;`j{tOXCj5A*VQA zihRKFdZcjNj@;|`6!JI6!0f`@0Y)9 z&Ji&kuVz-mN5>hH`-- zMM<_)s_4Kgq+fDgDIIcNBlY#su{I4+h{~izMf1-OL9>}4%t@QgNtlLin}* zpMKka!j`keww$objMy#{HkO^Xv4p*3%J!15eKgzl5q6Ar+cCl>vB@@xurKu6z7Y0; zrP8qeS4y9zu~ODbPhrv-qEeAA7YOfc(4Yc6;bf#901T(H@V-dymc8-uyvOd`XemrFaGS4+c6slHBA zgu?S(feH`x>4BSa$Mf??+!*qj+$1=ln6pd>g6^osYio_xsnX5RI9TkPU9TkH^Xq=!3{EMUJ zf51_*zc*9M37Y%2IBMp<=BRmp+ELSfHjQ&N>t8TDclUKteV?H+Ob4mOt>%s=?lb4| z+MkfqNsTz8LR)&i@%%#CV|;8OecX6KAzg}ZdXX*tjPasEI%d4MkRC0+s5PY`oyEtw!Z`djVMA9lA++ucGP&}DT%*y?(0s|!Uz zuN4Jh-y5)fFH{JFRw0B z5>b@cS(iyeRkBZSbNMb1z1O*3dY^NH^a1Ba>5{sA zh$ue<3y!1dhhXXP&JEHNoa?10I@d{;(subF_(gx=UtaN{?>~DLwUaL2tNL@{KYY@8 z+)bO5^b5xG3+W$?k1eDpKdo~X6w*%Pg@yEY#)}H+(pjCexR8Fycu67sPvheX>8by% zbB-^h*BhTuNFOymv5>C#tIj#8kZv|UxsdMvH+_CeAw9?V)IzH1Nq-=o%XpX4*v!vB z&NMuCE%GkM7UYwTUq|{K??WDNoI&=+Bc7adkykms1-ZbnjC{;-GxD#FcO#>YPfPHZ zI~;|)#&HdDiQ|>XryTo`?>OF%Jm~lrq>kC(4o4yj9akZ5bG#C{+VQJMzvIu4F~>UQ z?3py~un;-H@dD&h$B!YOb=->l$Z)0PF`7NS1yA_r5=}jykCzVu4yN%aKN&gIQR2x; zfgFqbqnJ#^f$JtK0!0F2sv=MPSs`f`CHhtZ!46g!NeT%hQ& zXDyW~V(l0Z?m}%)7@>;9cH-CW;jgh zkWFfs$L%(cVd}cVXCFWs4~FhR4KAj}DWFQ7IJ-8K!u^FH%jPMYU};Nc4C>foWY zoyJMi6~V9EXvqY}@Ht01GeMIZJ(*ye8v~i(;Jxg$;Y_g3jnPc-9XG}^!JNJAwCPOn zW;a@LLAM*7xnRnTo?NhOAG?OX4FGh}2+K0*g!3wC2vPM%WQAxcP30~Ub~1%0Y+uQq zm26asP}rT4ElJS{`%tp^C?H|SQ8>ajqhN%+CD~AtT|{9>whl#t`JG6&hzt4bpK0tC zoyg}M6^(Jja}+saPcR>Dp)WjjgOJeqCu2>V65?H6H-*koHo*cJM1R|q@7 zQfXNIwpp)d&Plno(pzanYo;RD7sP1I1aEPpD-&#Xqc;=$$&JBGa5B@+HQO@5r`*_) z2_A4`A``rVnO8rV;G=G|=7Kxj=*k6$GXI>`n+rbR#$YbEoyMS-OP^^E{EpSquuiH! zASX}!HWu`u*-+|f5P()SrJD5T#rURX$8Utqg(&)I z;}Z($L&hf-(na{FLR5N<@yUhsm&T_Q(z%w4rxsGr#o9MB$zGR4FxmE!U?w|Y64zui zOhTOOi%GPTEiwswvRfuOkZhbuIwX5&k{QW%nj}fGvnKhHY_dt}B>QcWMakBiBvi5s z|0B7jXMI>P(-lE@@Xy$TU$ai$w`77)1+-cf5VpEb+v-9|&}Ah-*!OyD-wX9Yuhj>N z0CyX(O)wM-gH|kr9dX!p#85eGv&tcCkE6CdhB9J@l@VdD9JjqP)D#m|Q-qCk+BVKm zV9Z#75q8m*T%foxoK~wg!j{@;TWTmhx~%k2bU3ZY_SaB{^jaMfHroN)Y(r7P-&i84 z6(toV(omo*mxfJvl~jS^oYm5>A+OuhhO9+#nk^FkZ%_1e=X&WG&JEHtog1Z>Jx60+ zKeeymBQ*WAEM4#1ApNLwz4UVDI%$b!7snq!-pw69XLs+YlMc|>R0okU$A^)|eeKid zBg-7mLN++&NT1`)$WF)KBM0qgmmP*IcRU*@JANGLcf1uDcl;xA$TRG+7b7bi--0wd zUX6Umad#j1x3Z&6g}l)4u_l`ekv!19u`LxMIf2z(Dn#-FYoJt!D|W17t*;0=$sP@>3ZW63+XoFlM3l!4LaxKLYf<&Qb>Pnd}<-p?8(2FKM&*6 z-)QUvqfLSrGH8q)O@iaym~0Zf&5fxhLCKAllHdk6T1$dE+~_U|9(7|=NpKLpa_fPT z;AA%jOM-X1vArbdaATw-xYdpElHj*)Oq2xw#H?`gY)NpE8_i|G+ui6a3$Avft1S4o z8+~QLm>d0NK|S-w-GePTG#*?_rE8p5NEHu0Un%W#UL*CTRC`&X zr4&}rq($ZJp8T^FL5~}4nc#6Zx--FPp4EMs;5s*kGQpqR*q#YAVAk^2Y2&l3%jt?>l^ZRY;08B3Gr@!# zJ(*zPv+WvwQ6tdo#&9Os?#5^)IOIS(Z9EgKb7MLa^t;iL3ufKmWk0aI(XQ#q1)Xm2 z2f2V>(Nvd6kFp)EW0f?7sQR)b3DKx+a3MsKO-YDaN@<8nNr(nYNr<+Wk`RrTk`T?7 z6sr)T&TzH$2eaHHrpx`8lvB0yMtnbF;q!{G}e>^X}T#1Qd=nv zQYi`2P$>!0XekNOWGM+!OF0QrcR2~tKsgE0_Hq)W@p2NR*>VgLqwcK4C}H$fVwf<7 ztGk^xxbWU+eE_t-f#Ox*ejMw!~U>R`WTI*Tq~XDOJt@ZD7n#^ z3GQ&CD-%51mq>3Wc$*u8nc%B#Y|8|XyRjn^oZ?GlA`^VljhRgFb2nOZ!4bY*x^lq> z+~~~(-*aOyH}KW7d>`~o=hf1%lB%y$k_hdv>L5gDs!0$c)M_BRoW?%bwaHLjCrj4iVaB&*l)Jo%T2m5t=Cr6dCfXy%Ix&(OZcz z!q`$tg0!W@ZM~zP?q$iMMyzMEZpD;eDkd7FiTu2YKd^@F( zt}#Bfkb3UbYF7Caw!pC_fgHo@olOF5gBa84emG#-mo^4xf+YHNd)FK}qbUSPhRrDFbq@_W4>P^{(s#M@eOIZ*efvvW?hE?2c z2@;-%n{2C9l5ov{WlMNC4%)t}jN!<3OP%nf9I;I}EcS8Bqwv_AupK$9{8>w?@CvyKGsp{{Yj`BG(($cGi{qz|LC4#WNyjIUmpsoddj+z}@j|54@w3Q~#GcZ3Fo)3lIW+YnZ8M%I5Z9GKh9A8M^ZG1u@{l4*uh4k4k&^ad+(u<8xE~IxDpHfJl zbEwWawUBD|(swXNGTu{ZY=DzZf;DbTH3>Gl(NYq8$&J>MV5=M5CBcLnn@WNM@Q%9; zlmrXi7%U0i=EnAt;NxzLlmy>!W4t8z4>u-Cg8z17wj_8Jlftc=%YqBt=qw99=0;ap z(Bnp5S@07#`pbepyD?lA9KrN)w{2y?o81^I3$AcuXIZe>jp?%BXKu`t1y8!sRuR02 ziRNzY6~S^hdMW~igCo5a!A3WRDgp(EBU>th?QV=#1in{w?5NgKX`Cu)oGMA2W-CdY znzJNMZCMhh_AH50cb3FyQmc*$!PvX>;Cvj@elQ?zfNt`z2Nu2ufBu@Q#5~rbDae6O}2h>vO4bCg1 ziU*&sls@jfM(Rtc_6|lN3ae+*qO#eS#cW0J2RGU>!Ev6|-I?HOH~KQcgKi9Ef<>OL z+cQB(@iCjad;G{`COFFTa5fW^LQ>{}``qZx1xGMuvaK%{#5~Le!NV2OLu|9?SR*~3 z#ud{Q!B^a9$pnwN(U}RB9A>BWWP*>oF^~y<=EiU)IP8UX+Gr+tw;SV`;AS_bGr`~7 zXvqa<9d6fj=7KM{(US`vc4HtHyxMlPj%Cs-oL5Ohh^p^k(h%7O7edrhN2eaHwn`GB9@{Du8bUE-yMtnb zFwo)#mv3xx;7PTP3GGhxd1n(!ECw(TYC{Oz`*gw1}FZ6aZR@3(zJdxZ84Y1kiD zN|z8NK3^-n+#@zq5!~%YYbH3zmq=G8_-8kIGr>)63}%8S-Po21PV*(QBNKeujfqU~ zfEzQJ;AOrwc8U|k-@{>N(>RkmP(8f#*RuFq^2ZD?WH70y`>~bTS`fgc9fDJO_h=$wU(10 zZ7L^08Z0M48Yw41nkXkhYOW+f>Z-&bG3x$Gj1tDSN(>Xm&gx21&386UHLLVGEJ&_~5wmF7HIArk+kFzbdQ-&2eYQYZAwjH)@D&X8;(jp%obW^s6D*7C0 zDGS0=uhllxuyDIAC&D9elkKj`3$7Wk1PRZ>LECDTBplgp*%BU(Bew5`^*wH>6P}b4 zwh4#DK5Kat9-GY-fpUqvby`w|XK0sg&tV(rvkcP~&1wC%S1ZdfhArK+Ut?^ujaw;) zF}CO2Q)slVIAhutSP0FG)e~A|9BIh}Ax^DUT!c7v+Wr{g)Mb@Mh*OVkmLX2PR(6Cq z4cN{Z;xuSANQl$0ZKEMh+pHi7aT>KfHNoMxXujb=p20;?!joO^8#EZOS1|y;k0YI1Shi9pW@-wT|M%V`Z5%)IH0k zVdq{Y4K>heY1qZr#qEJ>tGoCJ$M2!>8l_HpuXDZhKIaDM1I~@oZHpAQ_09EyyJ&g` zBfZNmXKb@Zy{rj41+MDh%4ps5haIjrqXg-HHkjW-n{xrjB}REXpyRww^n2a=;$ef)bJ zXq{Wbr9z}Ia%`+r{kI&oIL@oifZoAG|Md74(8HV z>@(*Un(i(AZ{uSN>FbWt=L-tyr;QgD()*1U719G=sdE+=(svp!DWu;pKCX~HX?%Pk zJ^5&z&od0Y%J{@WdYkb{h4iJb(m5v=()SymQb-4kPc5X68ZRxRn!VJg`HcN68oS|m zN$?RjCQ5=&yD?o7$YoBODGBa%qopj+1aPFaEI1TTF*?fvO$SC-S#XIPJ!OF=haSYBu1x%q2!kMW6}CXsrm|=0;~lpy}sGS4D7x8$A`lPu%FO2%d6dpdwIcxMr{- zIL(dWia>$l$hL~$8aGBO0)>quJ1T;E+!(J2<{V>3CaP6d62a{ok_e7$NFq4CA&KC` zh9rWs82Od>eEF^S-|jY$N@HYO3=xiN|0^u{EDGaHi# zwlyUYY;Q^;*wd6mu(v6R;80T%!7WWm1V@{a2<~V~A~@NUL~yDpiC{}9iC}9fiC}jr ziQuME62XB|62ZYz62a}IB!VNQxQAcIuJ#`^rNRcm3yw5n=LW&WZp>^D+~h|4M!{ol z^llU!|5CeV%SOSKZtU17xXX>Hje_UA%uZ`<5?tWMrY6B=HwK#okGL_?B$)qlyJn(E zu+fd?l3=SFT_wT(z66N^!LsyrN_><&(}&TG}3UU zBDlwm)=Y5Nv38^@6RdNiHxu-`F_;Nv-Po21mM^etc4UH1HzqQ{PB&&U!7&T%H2y>u zu)&S4TrliLZ!S2{>NnmM2rjVaSjTcH|388pTP^kHTdm4W*4EBavbLs5$=Yfzr)#U6 ztgTJuWNr1AleM*_oUE;pa`^ZT3(NYiox+N5k5h zut#TDTQg-rSX-_3fDCJ^%btm0ZS~q?Fs!XXd-8>~wap%OVQuZ$_4$^pt(~Q0ZB3Pu zwbfis)>eBtSzDXR$=d2KCu?gQm*YF0x-`p76AXw(l zsOb%YHaFTf3P#=N*(i9SKcj{=3f8$Xx>3;Q#^gr9v>Po=f|L9i)!ig$abuuKu-%RA zO@f2`88zM{SmVZQlc2|q&XQo#jlPmVH5E<{mjt0A-fs0&D1yhWgbH=<>;^$7bvvz4 z3e|0&)kdM99ky~P)Uab#0fn-4+KQe~skT|26N=LwD{VqOI%L&MC_zW9fC*LSq}42; z&}^|XCDfMPR+)rya=?m_P(f}l9mq54&HlietO!2u#%x9KYd6|5!K?il)tw2-Zty>q z10!w>WrCyq8MQqVT;ax8Cb-j$$xLv#Kci+d!H3*v%LUuq=*|Vt=ix*Y`f|bh-5AOR zTWRe0E2Pij;RLUdzSW;t(-pzj-Dt@KGj4Qdf>Zn<)sqQ6>Bc}N__-UyncxV2NR4KK z54bU&3BK>fbSBu(A5ty3;9NI4bHSJ0=*b0taAP1BEc8d#GHK?#N*W$t)h~^b#Whw+ z7T07cSzNQFba9oF#noL-7FS<6SzJTqWN~dTCyQ&WoGh-%a{R)_7i4UTrKuPWn5hLb7WXtJ@%txSX=}4(_&a$ z!}bGWSX`s_GhtX<JI-CyQ&c zoGh-{a&uhDX{yvEDP@|rFu%d4f5EU(T=vb_E;V`l@MSyi5GkZ6OAI{1s$AN*+* zwRC`i;b&$TbyP&OqYgM)R8+*DPc159@}9lVo6(GhHfTme8*17 zGd6?42F+-&L4yr8XsAIm8uYvG`+0Vil)rs|8^lI7GJDMdBp`DrqwsF@kLQ8lZh|Zq@>~kPs%C&gD)wi_+m}UC@xwt zp&q)x!ybf1Fd98m5ZFirv+7QK+PR?8*az-K^({UJT~VFvqj+l|_=L1WMY9j-o$7Ub zcG{x~+Q;`^bwNH=9Z)&#gZ-fTBcHd9sJ7;f!?lg7bMi^-gbHmh118l|`HXf(Rkzm! zv+A~ddb^+!oVOU?wx~YL=ejGZ$Guu;jRc?gcBnY_(xFqmo6mxKRH@Spd|R)&I-e2` zsBHJ5Vo?2_&yVqv4UYE;V^p1>PnIWC(0jQtsUFd1&NHg+y$4zQHCpE2Saas!xT-C8 za7GIU?%=FSFL!WBs|fDkvg)wpU<)BRsG`gr?9=*!JJ_!Z%^e)kVuL$4s&dU8oYKmJ zJ2V?%;%$F5JOM z6@TvFoYpbi!Fg4J?%;|RHQd40g5VBzX@$cb>{gBF4i0F!!yOz{!RQW-Y3;)u9A91F zIT{tzR&4BJsJp}`SJXq|Q!47?Q9`kgp}tGJp`w0Wd|E~QQ`ArFW2o;IZ>*>{iqEL1 z4@dFDK8AXc_^gWhW%1b+^%#{{KHYvL^x^%1C**vC+f~_g4RIr<&q9f=}tsbaad;{_}WR2=6B7u zr#BFMA!R_5y$Rbh7zn=*=8=!XjmEe2MuIQc3}{kG zJFsUk5>oxEA)4l}J(0j+8Ugwh0Bu4rxjMdOJ}tz|r$tr#?$e4EuiU5BGV`fJD_QPS zXPNobqh&4kskh908qgY-`!rZ)K8%Y7OxGoL23`sF@NmYGj8S_*TYW;K~`pBA(( z<~}W!nNKTPBy*oy>zPj-S}}8CU-M}|YiaHi{;gHqX7_1C3u|w| z54f;K^+mSxsq_Os-%j-fw~MG=oF%`_dpHe z4Hb10Bi>X||3VX#%@y@B z@s^5uqxhVP`q1uyZDPrYXK}6|uwe-13qqQw<%Q(33Q1pcYzqXRw6&|M^aaQ+t&sQ( zu3IIhFPHRbxx}Y){i-*)WP+38&-DO4x5Hl?A>jH6_KayE#V2}r8y9!P7cHl>s^YW0 zX_cj1Sz&v$#Nt!HdDW;~X2G5%t+)7ma9IVbuWhzPf=>?HRlWK`XO~uDe5Tl~QkJVR z__jVR%lNdhUv;f7fevYnhP5pY8&;9abs7X?TCicEi(p(8FBfeP;0<^==^ z+U-7#X$jeV8rK}$eVWpGvimfx3Ay_;r^RLWXSZ(|h`a%-=@!ss6cCU$x#rrAatuCzaNK zFG&`GSKpJE#lE|=|MCXvPmCL>KQ(Tm-ebIuI(n|-d(e9le{wqhZWTDgA5ve6*6b|Kak@$>ey#M&NqA=q}A{f zkRijbL*@;C33=)n`q;A}+YMh2X*2wL$gttRLlz8w1v%kNeeAiA*BYiiHnjn74&Xfr zwt|<>_XwIR5?g=>?@5r@2t;^Kg2Z+p!g~@VHU$yhlOVA*i13~Si48)8_asPc6C%7P zL1MEI;XMfwTZRblNs!n$M0ihv#P%V=dlDoz5fR>#AhDH*@SX&T4Ml|aBuJNAg!d#! zv=RHV_axFiU>Tb30H?aC{haEi)^nUmZRb=swVYGkbS_Rg)0y&j3Yxdz&kL~eyQz;l zhkQy!y+C|wMZH$Mp`zX`KCPlYV=Iq8y`p|tys@I*EXLobKp*}h9)l7W`YQ2R74>TI z*%kG>;!PEG!;5+R=877`TPo_9_?(LRd-2wa%Db1h=|yPA-(W)rI9CupX2E?#PiTX0Q5c(Qc~ z`wD{hDF@Z3csFvp9zyRq?$LASoy9IaYTiFwqo>QegnfFT_~`KN=o#|Fze|se=lYQr zf~WT$Jsh6VH|TlrB)&zDfamRDx$dcYUyb0|d8NGdguG66dJf+7Us zS#HgSEVmXzmRqec%dO6sTV|-VDZ+TnI*E$}R+xF-tGJ)UuXd%SD!6?IBCA?vSNdf5_5n zIArNH9LOzDNI9*!x$5RAu^UyV9J z2bu|wu`%k-X2K2&?r$daSa4MfVa|f?-G3w?P!sQm+(Lxxp;NBKOgAGf&YlQPH zxVA>Kq zC6w2_4>S|J)V*4Tl2^BTRU3IhdqCxo*RXf00`ju;eic1lsa~Zz$BWbJRoZwxdb6q- zFG2560pnHYy{cKf(A=#u#cRuJRhf7>xnISISCEH_XJCwavkh1ak?;izRwCh-7Ic(^ z%{E~5l!Oio21>%L1tTTlEE}UHO2Q{Bm?;V0w_u?p{H2XiD(~wHwi>U9!hEFU-!q+TlD+!G@NOhHjS6k3m68_18p_1@3 z3&u*qDKWNu$;kWHbAy2N6m?hUl%#v#+X2~_D>82;wl4h8mTy2_EdUADX9_h)|r>UbS z*N|q5o?K&^AbN65X-??LHK%EyC)bi@ex6)yn(TRUb!mR*$B#$kMATWa-rxvh*4XS$d6y zEWM^emR@rqORuGnrB_?b(yJ?G>D3ogdf}>vV#+TBV=*Ndg0=S~T7CH9;!#R4F7TxM z;sQ@fFD@RX?Be1Plk4dimbiFCWlC{@C#4qOlSrAx_astcae*i06@N*=w7Lx&-;MGJqU|nG2^3o4C$;9gYU z;&ady)yY1Jw+4bwNIO(C`;gwLUdLyrJ*uF6eD75kI8kVJfVV~w&B|* z)g$`Mc}CT}_aJNUNn{QlXwDowsA|g{yi*GY?%-W2z1+e3wTj>l9#I|U4qnwla0mCO zD02s|*ZP7xc!Mf5ckpH{Hn@Ygs9bXg@6gJFJ9t>Nn>%=~mLc51`&7uegS%@4ckoJ8 zb?)G`TA*+TuTzQV4(``#g*$kY>OFVxkd`jo!P`~*xr29W9m5^GN0p#E_<$BQ+`(N1 z!5zF>D;)0NHL4Na!M$4Ua0mCPU~~r$XzjxtJh-~Ra~yj7?bz7IQ1^&WuBdm4PpPQS zK?%h^hT1INP*MLwd|E~QGt^J)W2i0SjTQBq;xj7h6Hq*{kDHep zHdWM1#hWYYcf?yN>Jw2ov5%ozzq0n81jn~6*wC7pg1|8j!K?v<^X!=6CHD^ag@2qzq`XH)DJ74?qJr;lpP} zH1k_;!Dt}(63c|9fnKCeY8>_TmKn_nzh|GB4Fq3&Scv3tm6#RH7K80+ zjRaqo>Cn`1%Jy_dg0Io^Xdd}&+-Q7TZzTAF&44DAv;%tvBO%ql8lq_q_KZdXhiL@p zR{*pL!PVWv1&Q{f#8$2c2$+W0NJG#5}(0!tHkux$UZHX_;jvc^(L20aMB^Io%q~t zSjDHWQ;umN#V2~>sziO!a!RWzKI@xSS<00awns}WJ_W?z4dJI;X2G5%t+)7ma9IVb zuWhzPf=>?HRlRZn2A}EDN{r7GyH(0^H3ob7v@GM(#(vecz63g?H5%5oIBZx&F4t)g zjA_A!g)V||RlHoZK``~lS8r$ySEg{pl9s64nq^I)eL1+TB(ToMVeOhvyH8zO8+M<% zHMw@5`m|8&KJ{y+?LG}@)!2O+*0kGw8q*T8`!udOxcfAv^Qnu5slIBxgX+`%om5}Jz9cQM;j^pnNi1Ujec1T#Nl^dSxRLrR<0k46<8{>e zx6>-TCqcLe8{dV4Ss;q;EdlU{YqQ7^%Ut7@QLf(`FUybID{ z_!-Ek;kO}6hQEV6@6|f?uOJs0z8%tO_>Yh=!~cLR8~y?E!oSwXPK8`-_)bWd;b$S^ zhTny(7#_17Z<1ldm2HH)&G4aZz?%bjPlB!Biy!=D(YXop2weF zQFn_sR@6h{Gb-v6cJdgMxX?F=&#I``i_fm8|0Uj3QMbK;$8WBv9pWt&bxM3rMSb)e zdCb;|%Db1h={0D_|G|b1aIPSH#)A2Ru-Ag6g1{!@u;qgAzZT$Mhz9Tmum=roHtFUJ{5FU$rf?zBVHd`UB;0F3 zeg!?R*i-Z$kBKEAkCy_Zg z(VRIr*_=5z*PJ;x-<&zP(wsTi+LAlik~`RvIXKXgIXKvoIXKpmIXK>uIXKgjIXK&r zIk?o4Ik?=CIoMIl9PF%R4))bD2m5Q8gCn)f!O>dg;8ZPhaJrT`xKPU+T&!gdwiTI! z?M3EbPmwv;TVxIn6`6y>Mdsi{kvX{b?@8=Oul5^kd=#1qXTCIbU_tOcWn6uVcO#Q}2)*Z+*K_BcMXMe)?;pDLba|IBs0Ye> zfpI-Up7^tRY&_SOTL_-soq9MtqxlN+*%F<&#iV1ke*xJ z8WTOY`ZWxCZVhYX^V}NOVCT6t{owH}&#fZQt&rzd$a5>?xfSx<3VCjYJhwugTOrS_ znCDi^b1UY#6;o~@Z$@KEE(DV?Wfy|kn5S2fr&q|+E9B`F^7IOMdWAf_LY`hBPp^=t zSIpBZ=IIsl^ol9HaMj~6@2UHt*K|7{$ z$ZOacRX|?0E~)78O0`3Eju)qWDs8+T9Z@yoCFqn27_T}PRI_-Y*`_kZYs(&0CSFbs zsTlDJa-#Svj8X5m0c#-=zGA^jB>cgGj*{>y8?bsxLXQOlC1KHmk&&{HRDw9#vzPUx^;q)xaC8-}v;seg&V349UtBQ|0! zMZ$M1Xe$ZF+aT3d65ebfBMs6KqHz9*3-*G!Qm*Fupc*GiEmSICm9 zCuGSr5VGVN30ZPYgeUbS*N|q5o?K&^AbN65X-??LHK%EyC)bi@ex6)y zn(TRUb!mR*$yQ+6SkiFtYzd3uFBy+WQ|Ay2Q6r&q|+ zE9B`F^7IOMdc{1wVxC?xPp_ELi~V;@`GsIArUXMUxBB)Pf9JmCy_FX?@6S@;sQ^~E50YewE8hNz9&ItGVwi$ zlvG^cNjb&$BvMN8cbF-oxWL1NdguZVdk_}EG_fG~SUs!m#HXDLDvf>MUR2-WbI=vl z$v%p=27*sWJ5)6Lklv|Y$7iQKs-S&*?^PG%Q`G^L(>~Y_sz361>xgP=-Z)(7s5&Q~ z#7?Nt_A+2nJ(bUBXH<22O)#r&%cr*sD#5)#SX3Y8bKMoy<6bSaMuJa#J5-!|>Cma( z&1bOFUGLQ5C!;G~K_cW_SY81CS_DnWN}MT;8lU~55e2fMVw;SP4IMsx=UwA|qZ z9{z!aUMSTJ4 zC-yPaE5#ct>i5KFRMbC5@x(rc8pLN+)bEPVuBgve3AL%BULoFGQGY1jQc?c`g%kT2 zs`V>t?@4fcdo?zs#6m&f7>8g{gWV@BSkc7oMhjX4fs;2J)}dM40~T}!f-jf!XiE1A zG?m#F2)=eQp!r?5?HLRNUq~6zWN*Rtj0OTHeE5P1&HT1nFc}EG#4@94pckpL8b^J- zWkGYopV(&>1Hl(xRy0A}h}(y+ZjA(AiRsX6vBUOsMuIQP^l0ihXM1`h!PjU8G><$L zHyYnI7zw^$Gonc)?ZBSVNbvf1LPIpo!Jf%T;4qC~M&mVYLa^3*P7zQdlF2q%am&CE9!{&dQ1i*<4XO#ak-s_r&K^)Q5HtY!gdHJc~;O zfek~jTo8Po))ultvR#FwuQ_&UQN$;0-Kr{m0kTgkBtC=dSBdGXkwaQ8VVQ~Z46EMc zk_mz_t)2MXZd}EuuTxHGA;l+p)2c*$(Q;0!Dn9F*S6RxH6}Cr9EItKXR*mY*nQf8a z^TBo%tiHC{rNtMY9CoXE>1Lsj87YfRoD6w=$O`MSli;T zaTU2-r$I2K1sfK+2&Pr>a?u9C+#g@Pp*38Y!VybaqH=4NHHG%&;I@+B^J)CAh!7;7 zv^Jc4(&Re%q=n+-lV;kEx59_w)%p!ZxZ;_0OgHs`U=4 zPy2ULeFgiHw7`bXuD&O6)Ft@cKQ_K6AvJD%81xw9ChD=q>!`~$I*Rus2uHB-JqhY> zjhm>yGj61=7&lOlF8ssk9fRlM8(*hy-_t<792?$7XomC{{xf9K@CT5Fcj$mWg`8n{ z4&=RtAA0LADyc9P&ZK zhqeK44&Xfrwt|<>_XwIR5?g=>?@5r<2)!pkVmq)8?@5r@6hwGWg2dJ!!g~@VHV6^k zlOVB8i13~SiOoWU_asPc86vzVL1N<&;XMfw+lL76Ns!n?M0ihv#8x80dlDoz6cOH& zAaz-U_asQP5&N?DB-VUfzj_Ba)lKc^IFnk>GBmZFQ{B{ZPIc3{IOR-d%HJvIelPy9 z18n?m>R-N(d`dTI#)^8U_>7AB=YPxNQQ|`1 zCqAp9?iZh3QGY4kR8e^Pm z1@i^rW($@I0-KD(mJ8hjv<*R9co={;06}{ooM%B-AnUS+{}AiT$dsX*Xu#Al`h;YJJQ0)aObd*%b-w-zh~0&g+) zEC<4iEoh4b-f-+`kA%Oopequ1`?04x6250aUnD$WL4PEih`Wx%h9ZI1AQ+B>4_Gi3 z2{a0O#v|b-3#KB0wqeh7BpeOj5X?owdJEQmPmwuzs5x`+_U6pNyPGoy?`h5)e4sgV za92y_;MFaegV(fV4(@Hq9NgEEIe4HYbMRnG=HQ(znS*z=WDefnk~w&!C3EnqTIS%M zTIS&OwamdAYMFyK*D?ohsbvn{QOg`WT+1B1x0X40UoCTRcab@GWsx~}ZIL;6U6DDs zzsMZCsmL5WRAdgW{d*Dz(5wB)yX5h~X2L5hxT~44$ATlxgu@o>X(2rG-TKT8ErfSl za7znep9P0o2uCcquZ8fU_vkZM)(BTxa9xdXy9GDZ2v7b$I_&lu;jI?jQzP79!LEXE zp9R+xgfp#w*jEs|PdTVQ#k-N)^$_xLL#yu5bLXAKEU}kWXXlmj))VqN+37iW(}Nv+ zGm`OhmXM2)@G}cqOTzjOs->MJp>9EMN%)=xgC*fvAJSo?C85=V$&zr;g4vSr)XR0) zVoCUr1+8_$trm3F2~YX34(qKG-ey?wqUv>j9D;W64tfYc}l`X7PQw1{T6iB2}>6A z*9qsKhQqZD*9ljuu-kJk^}EJ9sW!f?Rhe0C%@$d1Ef!gBwT3LWIzyIQy&=o3!I0(F zXvlJFGGw_m8?xM53|Vfq#w@owW0qUJG0UyNnB~@J%yMfoX1O&RnPi?@^BST(x0VZn z=T^H0V$ZE^jlG^*{TgmPw}v&sdTxztQ1#rJ);Q|9HLs!5b89&eJh$34KzeRen#nxizej&vR>BgPrHr^n=H@JhzHGw?dvM1XR?^X%rb?*bs1TS^3R-xq8?OxSJ zUeF#;Ipj6$ovMJmY`tGak5{T!sm}4@^m>&xUXR|aYQ{^@J5<1U)p@UK7B4h+t4#6Q z@>*3UUQX^;G2#{Eq2e5jQKb!73z2ZE1uK#87#pKHO2V5g=qU*U77Ubxqil>CDG6`1 zV4@`aiv=?!;nx-{l!RB=fVEN*dM)Uv6P7LLsS{p~T!IS&bwZB?BXz=k*f5lxPu*<8 z*G1G%*zmO!2|u);tt33p2C1%+@O}&WO2XGH7%B;mut939B)rywsgm$H3+76~&n;Lg z38&j2)mA5b)Pk-$;Wi8U>V&5tlhB%>I^hy*Tu7mQ$#@6Vhp*N5B(mh1DYE2RD6-^Q zDYE412w8IVgevgGQBS#tHnEV%|^mRut-ORkBS zCD%;Ml50-WO;4^R%`iQ=+BB*3^yHe-oY0eNPSZe7 zt|iURDZRLOl(LJ9M@+6Q*toz$WlHgv6e+d%o)9M%4_?`rn z$;9_0Qc`h&C*>61lSnDW-(jYV;sOs7>Y)of>_J!r)5L<{WA&`M6Q6c2s5JJ0dr^Ih z&p}sIC;KSg8VEii?NHI|Lwcur9iN@{sDk$Ky;oh3PgMt0PWxa#sQ$?3ts|s!q@+%gC#>a${0GqR*UX zRNZ?Ivi6(K%)tZAnS%#aZMlPYYT>{gyi28*J9xiV5!}Hes>9sDt6B)|;2sra?%?%W zUvLL+P=)3W-mJw2ckmXKYwqA3T6u5>536=_2k+G~ggbbj3ORRhca7iq=nfvx+J`&1_U}oYjB@HSZ0uvG`@|<#)Ca`)pEpCdp`KzN zL+uuCsHp!VKCPmjjrxgw4D}lE#)|qA@fj8MG!#$lW2hbCvnuL;iO;U6r>cb7R8c=J z-ds_CF5Xg6PeqPt%1PF8xHHx zEbdWg5Q5G?@a2*oP3hiXdwK)G*G>jBzw5U>gMr`+DI=Qft=OK?K;VQAUp=9j-*yWo z1A((Y?3vLt(2LYrjibKavY9K864RmCVvp_Vj09hn z>Cx12$@cU{g0ImGXdd|z+-Q8;U?lj0&4?zIv;%uaBf;z62@TOS2YV(Xfx|R{8I9Mp z3Bg+Lk^2;LpH%TDpR{e$)|emla|ktPxagbXx^So;(V z;KCZ!7un9I`YdHT)fe0@qI!|P`kn;St5vDCzM@WuPp+s>!K8#G2=!v|sTFlVyrH5l zi%+Yl+b|(v_dx9wZ>*>@;xj7h^DrA>_dvZ|d{#vr6`x&En=~oeR8cP!(Q&AtW>Xi#H__jW+#Q03HU!^QpW3XpP z%Q8M~99CWHOQ2&~qhW1}!^TzQa-9YN{;%x-7P<(gRq=As2Ep7PU%jCU8o+ z(|h{F={?n_`sY$<4t~BPnFQWRvwQ{nlC;2vpRc|ru?{`@ar&+8_vzc$SJVaZ$rbgK zz%M_gqFy0BwW5AUyrH5#E%KPtD(d^hr&rYf5O1ugk1u%)UL}XVQ+#Gc{f79gih5j~ z$DCbJ-yz;qQHRBwE9z5QdCZoI`Y!P~6_t(R6e+bS;Myx}c<%8g0bs;}*@AG`f`x+c zTMHHo!k?i%_{>T{ILCt4KzN%49f9!o7IX%}J_~vR;fEIV20{Z`j&Bl4>=})OXIn543HI!v zut`3B4ENl9T8NoXi!t+QC1yUgmYGi-W#&_7nfcUHWX}cS^~@(MnXdWNThDwNsAoP6 z)-#_*>h$RrZ0K;dQjZv)Po*FD`F83nj4z^ED(zV_B)rI;_l}bA zDGPc^!jCN&C<&+7vpZ4}IxLtd3I2%B=+-^Y9?FH1P`6;EBz(_;jymD_xO_ZdJ#|8h z1p{?LdJgLZZ{hjWzx5VU_hQ4xmm=Xl3))J;rd`_8RT4gGL0?I@&4Qtl@RX10u(6VG zsRdId;YJJQO2Y3gSSktUeN3Nes}uggg04E@Cl>V82`9Dbu%SAk85=CxM*XJo4ys$U zx{RDzG@}mAEm|lti&l!vqK=SR)Dtp`20~`hNXRUjP%q>b&4kRNg^*da5;BWAVrEfK z%q$vES3zrF#fW+bdV^phW+u%QnMq4UW>Qu;VC^5bWe4YD&!YM?A8uOJjrj=Esh-ORm0opL zK8_5kfAXPYR9zA~ADm)Ry^s$Ov+8)*#bD2(`WhbwTGhRH&)=yY#XI|6bt2xs531i_ zAHjZu>ixrZ>L;<`=ND5CVZ%w5BjE{_BJCyNEf#c_gnkS9OTv-`!zE#>rO0?m=&)eA zBurZ{UlN{UDY9G=F0-J$P8hMEyH03CZs2nI>x9=?FkB~GiwzfjF7>CzJE@*YtJPTM z(5$KhcW6-sfjiWy8o(Xu)UfXkVKo$nxI=>)+})v3jpy#rq=s;JXjY@PJG7{Q+8t`u z*z68dNl&m88mk=CW{b^#^e!#$(WfmUt}gN7nw=zAv38vWG3~8%%tIvnKT|U zlcqyv(tOBFS`L{>?J+Z{J7y;J$7B+&dN?MR5RAuU6N0t>%K>Y?FJR-68}(=6lPl^; zc&=EpQZE;uT2V*E8!BoO9xB$X)ScqfD{7y3V?|vQpHWda;pyU>n%XWttD;Vc&#tH^ z=(*ZdQQsrpTv3O__-CS_zZRcUQSI4Vt6AA5?*iuv0vm=_&ld!Cg9z|%S^<2}T2_DP zdDj*QK7zHYbMz$alD|Hjb*rcJjO>%y>@D%t{pvPpID#QL?*rYi`cTi+F+B!8>W!;I z<)eVlOzD~MArP;X;HP{puxCyWh>wT!>S{fum-Mvw;JB=Q*YmqA5`3g=S0~KJ2jAAE z=g5c6ZuQ8X`F(n*d<^YZ_w3!kke)Dh(fER4_0@dJ5RB<@V}FfcTpc$bIRsOG{Mn;5 z%qtwRqy%$o@KzOmddT*)l?3+*{}c@Z_o++$qx;mYO2d8XQ)lTu^{eb~pN7YX-a*n`!ucU#C@7m2kSn~t5k8Hmekw2Ps^%X+^4oW!F_615#v5} zsULQqx>eD*Pkri?-KTz)H}2DrdT94)ShWs)Vy#2K^df z)n5Dr%m$yS8R6v()MpttQlD+yL_N`X9rbyiqNA8o6Hdg&IW_h9#!b{07&lU1XxuJD7{ zm$BiwUnmF@7AzKodn{Nf2#-V)a9C>~oMb^qAY5QUXCO3N&=UyPSlSoG!kh)2k??5TO?+EVBy6&vHxk}v!9XPZy#<4ju-}4_NT40~g3(C$nFSM( zKy$EXG7`?T0KZUlo3Ll?R|21b0m-MB`xJAZV(wF!`&8yWmAOx4?o*ljROUXFxld*8 zQ!5w za+5-CQpimTxk({6Ddr}{+@zSB6q8A~>amzyLNFDRO$gRr@L>n%W6z@cw394HTGfsD z2-B&a%LkQSbyhx(461+fp<`5C5<4H9Vp6@34-m8Jc-X~Y&!YMo9|l_0y|5#}o=){B z-r4u66Y>6iQ2mDY6szxg>O0&|W7@ThLu6JO{af%jvHZ{?>xwI^ia4xaf1K ze=y!j^-Nl=#&U;L9VCZT5G03G10;tu>?emb(kF*BxF?4+o+pPigeQkIYA1&@P$!2p zHYbNP94Ch~0@E2ZcQhu85KPA85rWy6n^fc`h1{f&n-p@BLT*yXO$xb5AvY=HCdJ&O zn41)HlVUOnSB*FE-6aImG1-J*?M-jid?VO6r>3rmQL{qN!$ZcJmD(vjwW7|5H&oQ; z;h|#9O1)f+|Me1dRJ^gGHsOh4%}U)VKC`0siSbVgK^MhmSJX{Dozi3Aqu#VSR6Yv$f;l}CJ_OFIcja?| zJxh8(d^}uMSL-R=770E$wyWRe6NArm>Cy3#68}?B{FILm_VnpF@?o=IJ+f#1kRB=@ zLxsB_$x;M`)dT#>bUvHA(;E)&mOH|Ug3x(C74^Yta^e; zhCOX1A^D`@BKf5LG5MrQBl)DxGWn#kBl)DBGx?+%B>ALnH2I{0B>AL1HTk6KB>AKc zHuJd{TLnd{Pgcd{V7LpIGZqz3w@e zN^|h@9myo{PMYPt_$8@(z|U8E@vX?N7b(*&Z=k-|xRH9UaTE3BJ@o4G$%hlp#fEuw z6ZI9wjnwmu8>oMcO&>_V6TB4P@@akJo(Af_VZ-0;e-$!qI0JdW@aRtbr7t!d@IuHN z3@?UUW!MF|#c&*Qzu^kx#69}hddQm$FM;ea?1mgLoPZoLJnGZUC;A$CK20z80C<&R4Hf%Q>E;b8#&qohknt z_r3p!U*coqcT+cYlTWFrrTEl}daHOtMSb)&Jm$2Ddan5NiuyV6#)|qg@fj8Mq<`Y^ zXI9iJ#Aj91Z-~#XsLSF_74;3DUH8R74;tRITiKUN`kEwm3J?1(-mk(CpPt% zgkcNjBjI}%EJXsFjKh{A;qhpjdP)Ls0D|_CaG?cVC4sjCd%8=)XD#R}3A{Pj(_a#P zYQa!R;H|=*;gawI3&u*qg%*sLgb!ITRT6j`@tNt8@O2C3N&;^x_RN<8+%W`8 zVg$=2;guG&)d{@e*wbDoe8z&VI)S$zd%Ej{A6d{>Cp-c-8hiTdgp(}5FINGy2789< zge$PIr=*%+d(NeP!+ySlYToVHNqvO;+H(nYz42;KnRz!+%eCl}ip;ygBJ*yn$h;dbGVf-J%)8kl^KPlgyjw0Z?>a)}U1!L=>kFB8 z{UP&iBxK%=hRnOEka;&9GVc~b=G|h*ylab@ckMBG2P1o8G7mv-Ozt5Vipf6u9g}|u zCSo!W!P;9XKSO`^ywB+I7_SlDW5H~VFkr!QjqnQ#It#+-UG}gQgwlf1f^e$^(*@zt zSL?9Ff^eY)?Sb$)3wi_LXBOapkOesDAM}~YK)Aw!`9S!F1+9_r2Vfk7AJ;SFDL<>n#f!KQ z?$`6+={u@Nz%zDQu6vR$1_CXGHSO}2E+Xiaoiq-?@c+}n*_b)F7&8Z3%iO^-bFjC} z92_h&2S>}y!O1dnaJI}GTr4vOTkDyFo%PJY-g@TXU_CjAo@i?_5WGG42fjG7Z(jYs z+qWDEZeP24`DC9ucDJuzeYx8=tnSwn- zV|@kTtrma;-gk2W&1j0cJh63R@%dv?-c!LFVfpDD#D}iv2 z1znMFvSr^uBydc?og9kRsBib7cud{7kG?bN z!F|A8Qm5@>EdCY)gRKv%ed?NhBpp$2?1Sf&I$$3!7u4ta5ZR_~mK`dZ(4(G}eJFw< zb*3Bu5lpPU)t5Oq6Eg=FV&>pV%pEK<2YbrQ!GSV!aHPx}oG3E~XUfdMg)(z+rOX`c zsAmrL)H4SM>Y0Nh_2eKP%=43h;EOW<=2VNhe@iOA+`l$eT**HbS?*t->MHkdNTrnf zH>T>z{hLz3Du#fs%JDt&?>ut&?*s+mmrD+v(fuu(7nJ(k=eELUN6NF_}!`GEnl2rFF85e=(`# zLk{s*m&ZWq6aQi|`Nh&Y*~MR7uDNwiwdU5=if%o$wC2Of0Ul56OeA<;Gpi@nhy4W& z8s70N>aq12U_~Q{_d=~D!3%;84JY0ub?Slsh4oK88e6=7>ebWjrNV#)8t<$I^{9K@ zFrrb1Hx3s%s^{K|hzSir-i=Kv3B011(Rk#2+N?6d%ZmjKPTs*SDm}c`SkXx3y?HJh6^t5L(vTT%h%<}GUoN#+%VWS+(oH?L2n zotxLM!NtuRQJv@JjcTNE^QKhvxp~tXcHF!LRe)~ZqQ)RMuPqSVymk#pZeEXSLpQHi zqm!FAq(afn8`e4*) za;;$>kRuLcNoqY=-=^VOmE@ zZNSP3){)o>UOv}ZY88nsK!kN95*vXC>qsQF0}hpHWe_{0omiv!Z@nd{#xh zO?-AmZS3bUn=0zN#hWYYKJk`{dPICqMLktXu(hJ{?&WRzINH>U4f!}13F8*bN5W4m zSc(KT8HX)L!gDNWD+#;-*wbDTF14VmB=B}%Pj^Z9R}1<|0&foX^p}KRSuj)*c&o5y zxFnoy!B|PS)PnJn@G%RfN&;^qJ~Les{==~{TK8_7z*EXv8 zwdY*wZT9mWRP%1nPU;io*PctLTa8!eL78`lYMFPp*D~+!u4UfcQ_H-2pq6>JtH`{& zy2!k{rpUb8TV&qtD>Cm66q$Dii_E(_i_E*bip;zFi_E(tMdsaAA@goe$h^BgWZvBn zGVg8R9({^k--E>hU;OBh)Oot40{H;7E<|dkgjygqK~X&)iTDK54-%1>yS^ z94-h?|GW;nuOM7%!IgpVB@3<#gkM{5Qy^^lXMN`OK=`-?_XNUi7VL_ICtA;NO(eY8 zf_;(Ty~#oKCfz<_d1p+OFHCM`8x`^O9*-7IN-1Pr+a5iQRF2>Bk z)-rRjv&~3Gb`f|5#SlzeVH?AJr?VDC7?e@*9Uv~SJ zOM=_iuHM(}>sE*B_Vufeb^C_v1n*1FrF#FlGo>F|w%UKrAp4$vv%p9DFnS%>4b8sbQ4tA88gFR*D;6RxY0NB^~}MMdU6mC=K0A$@I{$_bE?JMza^Dl?q8cK zF88lXMV9;5r@G4h8&WCd{*9@6a{s1OFu8wos*&8kC6z_)Uz;i+_peLEkNelBddK}6 zQiH|FR*{k0_iXYyB4NF%I)NdL$Qom)~M7`B`9rfS-RmYz|9Wq`= z-EZ7P{fcoT^{d7W)ccK3NEgQQAJKR3X`nWKk!`(z@;8S3)FFLpPXm?TfFtrR;L%8< z$5T(!r(U~uu04;>5A|~$Pko*a-JYG`c%I;}PVgFvoon@WzXcz77dD*h66%NS3n(3i zdm+Qvcm(xZ_G8Ml;Un?2$7ACW)MsOZqm(lY&x5=X8%L#gLO*CfrUc;yl-G$Tld5exd z>a~>Yw(v;&G#z-<077hhyrssC4}%_K+(bRrcpddOdzsXi4<18U#)c2CqaHDCqW;#n zk@`F12I^5?@(-sg*otp_y}o@<1NA-F(5m-Cb{X!5bQ|_S_8X2s?l7Ez+;6x7c>+#@ zZ+I%?RKtg!%a$>DHl7AiU#v(x6QZG5k$5shSkxqqSTq$Y(u_rOu_CQlv=l26PmIsC zl@;j%i@M5+#9MRpQLm@)Zt&D)mF^36q$@oM-(z=WeU+}0l~=k-R$l2ES$Xx~_z`TZ zyr?tc(^jv56&BCW+s_Isorm$!`WgJE8aGmpF>azBYrKy7n=dE-0n6CrKlF%k6ZN;o zjnv;6H&Blne5n8U#@FlH;Xm{}*yulGm*H+mw_y)tzu^ev4#OG9{e~-$C*U;nA9AW; zYVB6+H_#FKQU0@OY z2l3X>e+cgePYwS;yf3-`_#V3}@E^>plmAd&oBW6Nh~YnUL=69-Gh+CUujYB>zn|to z{`0ihl>b!YM(Q!fP1IwJ*HMq`a|;Q-#YX?BzcX&4t{68`A24o^-uO`e@r|$7x5Izv zd$7@e$S%X(kZ!{s$bQ2S$Q_0=koyf+AWy*Q=s)CC!&U#Wm*>E3r~e?Hh9M~c)F&ISqaHitW)U8V zjZRbl)VPV-WZX!7lyL*~vDh?Bq`SWz-}p{_`<@1B4I6waA$tt3hV&Z_Kn@sAK<+kN zfIR%)^sy$$pBugq@)E;`o(uOHPV;O$4exxcNIVlFI8EZo5W#5@&xZ(3lNKz3(f84;Q0v&>^v59oVE9jvy@vZBV}|399~u4^WZCc!kmGR*e8V#! zryD->T)5Y8nrGu_c;{n9;+YV^X%bI{2u_oDK16Vu#8V=I(3`NBy_2x>Bs-?)kT72`(gSB)E}BiJ6~^wYnBUs7X3ZQ4NnYi#i8b&yL9 z-vfz;yC7YL-H?AZ{4!+R@Vk(C!(T!kfwSSulGEv2xYux+XX9yj=VL|UnGnHg5>JK* zPLp^(L~xqKQzC-XB%T!!oF@I!A~;QY9xeg<;53QNN0d38u8CECx*|HAu7^&itD)2B zTIh7T5;~pEMW@r5a;Hae=3B7QY3etP8>!ziZlWGEUPrxTL}s-88=YhhYe1*J~G|?qlVGnVx!a4mtliB=Rw|Y_+iNB4R3&a-|$YzBX82N$3eCj zz7+C7!xqRF4EI8QXm}Uo(O=WYo&b5V;VU3l7)Hn!4fjEQY)*epan%@v6)Lp0P}k=Qsy6U`Ng?L#!zT#?vBL@Uh|iLFG`)l!kzP(%YQ z73oro##$;8Ek;>Mp{qD-rlm^$X7%PT@VuD2>sRj!pW}2__#CHu!sj^M5kAN1e(*U? zSHKrEcz!-c`O6Gn#LxJsVSyq&akwVDwX$|it1A~g_W$?#FT;0!K!^>v#UF9P6R;_;Kt67G736D%w?KYjct7M>-_XZSgj{I&Cdl6z?ty&6@Brk04Ua(n;@|bL zzl6Ne@U4(f8eR?grr|-zl3~h^)CO3B{9r41`Fv=us7P!9BIE~&jX;F_Ah8{YkRK#A z1rhRt#MU4}evsH8M92>k+k^=DL1MEIAwNiL86xBdiH$>q{2;M?h>#y7HW3l>gTz)M zLVl3gP(;WN(i2A&AwNj87->MEt2hk#k^If_<8x@exx0S#zA!)1U15Htd&2xkcZB(o z?g#TDT>(gCjhmauK z7u$o<>0*52ZhiZn2I?2EA)USmxy|qn$iu#=pB@W2-EcGHJ%%5Ee9rKC$oC8nLmu%h zee6+?vkYGZdB5R@A)hzA0rGvrJ0Xu8)5ng3Y%zQ(Z;?)H1uq{F z(uu?tAVNBk*a$>OClcF%2jomLWnq zk=QsyNGB58hY0CJViOS|ok(mYBBT?E4Ml`>BHd~c(uqVHu@5K$O> zr1mp$QtO#GsqIXh)N&?HIu{csoheV8V{v9aV8~etpDA1j5+^-fSu*ojK7dHF^c?co zm>s*CWRp1Vc5E!XsNXYgr2eOI6ZNq1I_eeQ@rRl45p2u^YO`?@wZ*uRS~G5-*0DV( z6V}~|MSE;4yr>sqLngctQX1}t+-P_cmykdGT)1^JrcEs$Rr-Vb@!L4E8*$PUBw6r?ubHX{?*3SK^+lq)I{ zTYw0eKw={hArnY!2O?wwiA_O-Odzo}h>!^+HV6?ify6c;LMD*dEJVlz5?h7{nLuLW z5FrytY#$s*C z39UG87dB=B^`pj()Q=fAQLi*!N4@nnJsRjpGaJq^@XVnZ_gHRLkG%OO`AUIV$+@DSv;hDT50Zwj&DW2ZshX83N%KNwyM z`Htc3kl!0V{C50XhS>12Ga;86z7O(GhSx!EGrR-xu#4V3oSx2kZ2?JWyz540auXH9bht~ z_A?n$>zNFx?M#N$awbDM7n32KDNlya;p}|C@XS;AOyNS14C(30l7YuwZ`X}yp7b4T zm@QDe30X3nfbV)HHYNl0S;mdjXB#(BPc&XfZM##?bLTOH-Po86)Q=lCQ9ohaNNqQ6 zpk9RyPeAA@|>u!4Nukn*2~KY;ww@K=!Iru4DnA*UN| zhU_p*4{bUZ4act*@G+hS5tboIJQE@;Lz0Fp!ZIX@=fgfMLy~w(L|BF-@vMlj3`ydN z5n&mU^cIV-3`t`1u`gSO+=|az`|+yu9I74RWSSHg!Vor}wm z=}h@DIpw2Z>Xqe{D^#7MSb}U`SgnV zewn+mqOx^7f4bk_#yMY(b766yD-y;n=#GTf5{N$!Awc;cFnG~>khQ*0&B`Z zo$!4N2J3`3TT_PWgkM-NTqhLPl#x2&PtgL5Y+I?HG2TXf2Cg4JKbN}K_f3SU`1!@u-xyy)wTEx*HJlkV<|4cPg_3Zm1&bx&9d`Xo zCE+&~ESH3jT4Pp9!eepacqm%ygnzQ2txh-*mySK{b;6JZ9d*LXaPipFStm?b&{Zew zz~y64cb)Jf3wr7VHU@io>#0=;`s%4!2>R>k;rj#Hbv#(mPXX5f-i48x!8S;I@ZMgL9*znUIKo$+(g3E5hhM)ct(uivXegM*G z_pW)Zlr$3xQTj=@jB|#fAh9rv>@D% zjYAFf*TzlM-xxPimyH{!4`6%HQ1f+s;}7)hdm5;}#D<~fSCBvbvG6gF7Z_4rV)$~% zTMXY0*=5)c`GVnI$e3YjZ8{e^`z{O_I0a9`t{+1Nh-X4H6f4qmEW%Jj;`y)-T^Wg| zM1-M+#Iqt=iWP|`Muee;^j(WE)R5SG?8}ClL7dmxzkchO$7s|z1er|n5ed%4~lPl_*e?mT`qF(V+GX9rl(9SvXhKkyM zH~F-R`qiJ2Pp_yymbn`%DqEKiH5+lxuVTY9c6B72ffFORCKA4F!S#`_9hZSUH$=jn z7VM9NOL0-yb5kVTZ^3~`*o8~Po`aF_7+fQQJ0hXWg2R#UTwF2s+#LyDvEZIaI33rI zJ@-e#0Sk^q!W+;M?Acus?3vwj@QlEy)$Is8F?ls;{Jq;I+pYNdFY`l}Y4VR9eUqt;+q_p_#*F;_qD|NmasyRYlx`@Ppbt$W>jt^M>gjf6}a z>;LA2%x4yCOUU%H{%=pnY_VWhLgrSh%ZQ{*MS9LdF)}GL!Gh6AnHuz+J!6tGvn?2# zlxa-w*)uLF^Nt1MlQI|4fA&mF$|xCv$w{9T!IY#=i(v1ora!5S23GMOkj%Bt4nXcS zy9KFC-#Or3odq}X3wPa=L4;?kojgWpyOSD)}_ccvz_VmP@wf2B%sUK ze#j`Z0ad60wBC(OGV2%LU?Y1#f2wh6J~JIXz3;0vRU@Zc67i~$(_M*p)yV0_ zM7(O`&b5eFjhxbFU*uI&jWaC&oRS{t72x}$SAZV@y#h1@>VaMXz9)JG_NQOP56EaIJ7?+T- zXO`a{;Gd)Ec97~1YCV=@Ul~+>c>Qr7ynV*2=zln4Z3E-Pc|1#fFdJnnK-db9X-s9U! zpEKWHnor+p?L5oGL5bOn-VgwTd+AH)57|{Eg|!{ z1=|xc-7J}137IVxj7Z81qvt#!Ba<=}tS+OIGUF^5lax7)&U4t$w{9T!IY#=i(v1o=4=*?gw-7xNj? zt+3Cl<~gqTp1XQ+hV*OTRr4+Kr`f-dW4F3iNxs>7$R%bkLvA!X6nV((qsT0?K3jh; z7JFVbx|?pJr9U3Z=}ttvYUB>*WFlTQa=IT8uNpbsl89H0obF1*t42;YCgN2i_ohX> zYUGqY`y#KJ$=u2E&nfAVUID&8dIk6q&?`VgpdRQI;CrH1fWMcPdVi3hSH1wkk1RHJ-5r}htd%{pc_l9Mp#|^8WjfF)_AHLeY_Q<7xXg`okv*&8 zGJjdHAucnD4zuTnxXf|%nBcd#%rpyj#ARyHfA-v-ka^95I}?ZG8b4Xa}zSlEtr>(xyDkNpOD#P!8-|=p_a;`giLu$ zWl2KjUJI5bWNKI{%M&uGyjCV;@-3Cs37G{JtWC&tu)NkMWKwzUebv+dD`1c zXPWOQZAjN??<8GpzKir4vY@?()E>UQubRg6f1V|?DIs&V^?!3h=3NW6C1kF!{%=pn ztg~QOLS`Tx=Q$XWl-X&)$fV4jR;1BMnZxNjhmA?fJY&Jwq)Z;YXV18#%&QiRPs*G} z|JgG!DWhZvCMSJX1XGeeErPwTn$Dy$6j;SqA=}M%A&r}X)^!s4j!hsBn=MD5j|W;O zAkUdSj?UKwTBjg0%+{mhZGqMW$oFP1r_=p_*3XgO&Gw+@aiH~gqzaY5-hzxX>lfc( zH+#VSsYYr(Q+j~;ENKPv+0vI;EO}duI6!7L=v5<~V?Ikd*L)uanVylUi>K2hXV zvp4^ok{;<5;QOOjfbWf70lqJK1^Axm72xlsrQY8u`l=bs-DiPbHPYXl&kdyw{!)8h zD2+LvA4=bMz95tyPQP^@>E+JX4W*&;^+Kt#i@s`Z*R6KQYr&861S;+E38ti83=I$hjWy4l*>ORKxi6?c?2HQz~k zz4bt{p9dn2^kG9!N{b{rxuJ!%A|TS&h?~^b!%c$#wI*B_mePkziI9{NZoIi zD}CyI^V|UGHk7`(za74{zZ<^2?y7s>JNbLzOa58(<9iFU*%d}5Ac5_!78-Se5pMWX zBR<-VcxsTxx%x6m9HlHP3Y(85$I3u<6$_xRm+tQoNXGw>e&y?P5 zK0}&-eb(*oxnj9A*TW3y(ZIT06{&4DA35Lbg~&B#yCOwqhaz{Iy$_jc_6202S^voR zdubhwhq{|?qjfYM%IQu-tlM(B84>HYobE@&x-F+$60vT}>8?bq+j6=w5$m?xMvGXt z<&-}ABI~yAlh#w;Bdy!MKUz^$E_ zp*x(<3#E+@&@uU;^e*QMLg{kn>x9xHTtVxG($3D;3#G~~x^6e)dfkA>ep*uIRtsh% zWgfR+R#Il61#^=!-&w%_R}xdf-MF}k^fdF$rPk5nmeLEYy|vUjUEEeW!`jW>>-|!(k(m zJ{y9ONu|>a2u3Gm`dTn1DN}60*rd!H3&tg7lnUpJPx_n)CMJDS1e23KD}pIWpBBO1 zbz6C*QrYBEN%el4>%IEP;kyzt8eW2tNtp*M7?YGq^<Q(3nu^bP)6=I!#&lh`^|L^vhGLknn-m!d`qeB zhHvZCvgxRs>Rz;Wk^cQ*96{SHZa-h`ptqXOl-_1OOM0jIY-!#>N`xPLmB|OK+tLE_ zS<*V@Go^LSXGj}?JK3+Lleyx@?&`%E(m#N8`%mP=a?YNNTx9kVK|whsN5l^b$|*l0eo#D?J0GE)qBdm!0yr)*j@SpyGt&xl!U(l{t$f)ee4fdKOAdPU5^gYPqf`! zQNuPcQ+lAAlLND)Dkkkk{(OI|hEt=lephv!lEz`aY2&Wy3U#J$Vi?Q1z_vZ5F0g&? zX#D+l+jf^edUvVYZQMH=htRod>R@pBL}a>I-$O81!0kREX8-L%uP)0XZnkwN^sT zGusjwX7(0jrrB4KO=hQ1`V23<>3w0TD}_oRT17iIYz9-{Mi5OI+0 z=4qPrUi0OoPn+-SYvqrP&P)y&4Zev5PT{kWrpN;K_Y1JV>7LOGu)zKO0+9u-)CHKV zf4{))(ihk}r5_^Qslb#zi4*HUWPy8va5_W>XeRM_ZWa!#AYE$yVCfd~gZ%*cWBq8b z!0D95;G0GY#eAmpRr49rH$i{)F8SpP zZMouLclF{7=|jK*_XzTa*>{mGW_KW`9Oe!<6S>N4SL9x^4td2P)BcKJ&=dT6MXRig$ z=dK0LXRZa#-%AUezf*L9+ri!SfbnlSBzmUk2>;l_KV6Z3?4e`z0P?{5=TOJSBgd9} z@R`qXZ-HilbbD%VBq>IgGONSlj9_FfH!tp_}MjgYQp3z56c-iN$pb`i4EY}(O$)CW#$i1aZ#2$^P9vc~KNh?yX#wAjZ?kW*$v%mg_lN5o8!Q+`Cu z1UaQh#7vM=mPE`1IVDQOOpqIG5i>zfWn^DuCipSX8^(`-W`fUOGr?!Cnc#EROz@d& zCir`4Cipu=XToRP{YQwt$+i-YI96=~kC7fy)%oM3r#$ZF=9{+fs;*Fl_e~64nHSho`T~1OUtsT` zli6jm>9B&x3v5_;a}8x9;l28Pbg7-D;AF)H0iobTQit8E5uC$Re{# zkzHmFI3Xj*0oJ2>NDs3&Amh!3$P%-kB0)8G?14yu*+$59X8R)(%|3xFGy6G`exf_g zkD||kv1FZ77V5s%fgz!sG9Y4|lT#8ztaEb8gNSubPN@*F&dDhoBGx%MB}BwJC#Rf< zSm)%F77^>5oH8R~os&~?M67di%8!V3PEIKjvChdUOCr`eIVDQOIwx0yl!;j9zo^g_nsS`?vJ6|`Hu5!L!D6L*Y$J7s{gPm^>N|!j_FqEEfvW{sK zN(VXLIFv4Q{_IeC`YAf*oKQN%`Ex_5Mo;siVZr9O%o+=J#bwe- zL0=IkWKOYQOhTrO1!EI311y-BkeOh?mpOEQh z!IFf`SPPaVWaeA2IwAAD1#1&B6&NGslaR@?U~@vIlLfmHGNUXQk(8Nf!I-4XY753D zWy&*}Ty0`froe*9NtvrGn3j~e&4L+8nddE-mz1%x6gQEs0X|l>mRgC5+e&j?iHbW( ztwhCL{;5R6Cs7Dhh8}GmE~Cm2>>4iPOB9QiC>AYIELx&iv_!FJiDJ(_%7B>_MIvlX=8~B{7-QBfi>=UtN1bH^pS`v0ztBW~~Kd;xhFuuZeM)Q5H;# z%jf|luX%BqRFX?vl5wA;%zGAW8!l7jRCmtEn9Ow+jEl)kw_r+4W~T+SVlwB~bmzPi zleyo5FcD`L-kU1@SUPnibt!Ih*l{Ptx_Udr9`w!iD;D)(JCdPRZ2vwl#Es>8Ld(>TBW3~ z5}j`Di-d3QYlJWPyUIy>7q-oAVLQd<$OyNVrQR@O-SU-ssZ4e&R_Z-6!!1&&SI2y} zE@=hQJa$V_>IJdZtv*_3*t6L!IH}jb2)D*)HDS+Kx2&WV`^j!4Nv-cQ+~T2Sg2U#! z^&+)IEOSf5xiOhO7A%U%%(Y-; zOeVwT$i|pVTMM?wWF}fLIxe%(g7I;g0-GaK<1+lsxKfxKmsxDVqPR>Y_o118pf8h} zN*hb2QnXI)GlH*^`&i)XuakS<`#QN-yswjctNS{+7rC#Kdw2Ufx!1L? zlY2w^I=Pp!uakQZt4=&*O{6LlzO7Wn!FP!kDIP6SB3h(Gv`C3)krL4&C89-2M2nP& z7AX-eQZibkWVA@hXpxe>NOZcTuMxhZFA=`v|8b$ueDhs`IiWO*r%IoVrB^wh7fL5P zpC3v$IbRS;>+^W&Gplr@^L0b%GUw}s(yBa8`phc5&iMwRbe8iCLn%L5!ZD3PX=~>j zhth|fKRcAJb^e@CTHSq4JvWrv2co^7S(Q`jEwwE!qr`Z8x5s6)1`>=+$Y>2D80{9r z)TA5d>X~|fjdv?!Y6ebm#ZA4;rn+S^H63TUN^7aqG;wQYYHq&c%AR`7EpiKJYN9T8 z&p_&(x6-YqdJee2diOx2UVt0j(wdsW+uYNUdK+$c>uhR1k4(y>UX7#OqN~S+tBrHd zP3k>4-mSoTcGxq;Jw#fC38uQ`I5q8OxhE?12A%8HW<6CrInAY7pY?P}^@QQuOSM+x zJ4*Gm;d}hkQ>UV&7Qb!7Wl}}i?mkDPR>F}n8DAmyp~6?lEsMTF?h}TukXs{th1|yt zUm>?(`U<(v9=<|u_4E~TA4GhG+*0Z*#?aXINFEgJdz0!QPbbEbWk-s>R*#Y_vM!M5{mh?~a znbKY6Go)z^QYZUA+}y+!pKw<%&XB$Xe1ozG*<^MrQmvM2Jr!wh_G)Cb+53=rX5U6O zoBac+ai%-%45Xvk&d3b}0C7!t}U10ueIky8>xdpK{qx!yDWUiyy0-zoYXOm1zyVE}yxBYn~N+)%pP z`MgltJV(dmhtl!R^UL7TpPa7~N*m?sn7W~Kg7fu4={o1@htfKEI;KG=9pik%Q2Mp= zjY4UDzK&@eO7C#~>`?ln^XG)px&=Ds+)%2~i+%@lF8#e0n5UcKG6@Sd$7Lp2uq!UJ zz=9D8neQwZlaM)>gt)-igiMYF6B9C5S}-{wleA!3LT0K3GZHeNSTHXkv&(|{37P7Q z1D9TskZEhdvV_bC3sxs&p0;3ZLT0fAn-VfxEZCfosmh3PwOt9B3oICslo@2fn54`^ z3&tj87FsYdDYMOj$w`?ij4fB2mXv8`!HlF#Ukm0XWvnd4O{9~67guYkm8iI_^jB-| zB()Ol{SGEtqT$yv+^P)s-8@`Il~GE=WqgTZ(Gta?C5lB$6pNN97A;XMTB2CAM6qaz zV$l-Cq9uw&OB9QiC>AYIELx&iv_!FJiQ>@`#iJ#PM@tlsmM9)AQ9N3rc(g=umFPZT z5a-8b-m_pyTt)?9&$778QA{9$)o~enokYHaQJqqy+2l&I(3eK0l0DU9VlvlQFfk@G z&4Ot$nZO>`c`=!*ELakgNj>7L-T3`(dp5;n+So(6D<(79f-!NK?G{Xo%UocoOpD9t z0VI`qahX(-OI(s?`y^#XS+H%m%oi4njLFoj<1R2RCezP?DKVK>EtnOPDPPwe_D)Qu zodwHdGLtM=ACvjff^9LGy7k;SBjYl+S}-my^N|Hp;xbiur<200xJ(ZV-igahw_tf( zCRL}s-@!!dFcD`L-kU1@SUPnibt!Ih*l{Ptx_Udr9`w!iD;D)(JCdPRZ2vwl#Es>8Ld(>TBW3~ z5}j`Di-d3QYlJWP4(3`WOlo1<>=w4~Y$}a#Ygy_IGuAC%sh7%Rw_>Hz0+&Vn5lfB&qd%hFd(eOmKnu zZoNn?5zE{X(ak2z+PKW~7Hl6blV)>dbWG+V3&zJ}##t~mCbQOpxiOhqHb)l4WQJO> zGA8qm1sh{B*)~VE$7DKLFgh+X)q?SHnQazKjmw;C6J~B)=1vP1#buUSure-_no4`W zgNfG3eMazgavuwPo!ln@UnlqS_jPjbdtWE_iuZMLZ*^ZM_agUoa_??mC-=Jcb#iZL zUnloc_H}aaVbzI;tcg@*!nc*GIQTBnBE_RcN<@p4h!!akEm9&{q(rnxiD;1$(IO?H zMM_4Cl#CWB87)%M7l}@{^fkhF^d-WVdw`als4z-(q~rbSm*17($&t_52ZDEn)I1fTI77gP&(iFMxiu|M@gSqr5&6< zJCsg#{+v*{&iQjgseK^Y`yGsOO1-7F#buNjGjMxcCiTi1nTRZgqupYdnsnn_JyY+m z@or^I&A=(HxT%-fRJTl~rsFJEX)Tr9XRcc_Rc(TIT-j5vxkYXPO-KQg6fUZk_VmuaNs7;w$8qQePqWsl->vt*gF5?jwq?kXvMZh1};AU!i!kLhi$huaH}Q zeTCd78DAl{7W)dhk2StRZejKna-VTj89i}sl~!p87P${Rstv(%w`8k01S{RAA6187 z{XehY+5Bm+vilPuKlzFtYCcnXnE5Q}G3K+S2R70b`QHP}WP-kfkybFDC9P;aQ+km3 z3~4sFll}J>ZMkAEcXfWVGdc|T4km#Vn|%m}Q#sv_h<|k|x5*;@)v28B%0B+pshn<1 z#J@U~E3}AzbtX*LJkg8YuM#J|&-;nG68vf|NMO9qcwNZccQ1hA6!^~$%k1?MuJ@9N_e@rI0`lA)h zXGtrX&y*fyK0}%f`_`W;_HtLJ{^&4J{gGm`47n9r70I5$;7nTnwLOAj)iCCxIQDLvSHhV)R_xBgtQ zm%BRkM~8vxj})7I5SeOr8uG5$CCCP|n~-wnSpAWc&DKJinJuY52kIVNTJ^{2HYx)3 z$LUT)sy|LQBU1fwx*w71kK1IC>W|CfHtbXVak?>)>W?e5NcG1lefCjw-=}jp-}0x@ zc=f|o8dWb`rO|25Q)zUG^Hdt$}upUv%8QZnz+-dB6Z9*MlLh!N7dhpv8K|xn{K0#kB4%)6A_h`)6Iyew4CloM5X0+ zSwyAfbXWFKX*u1Ph)T;1wunm0DSh@uDt$5MTmCsEJyNB8e^hDT8?EW{I9@%_nl9D- zwWj-fsnY&V(MsoV=Uh;wrFrHvrTONwqz%kxOSd+4#Tt8n%r;P^rN5calKyT!Q~HPb z4CyYQ(ql{hZw=RS#hAN#afb9hpwbT@PnmrddEM+=$a1qQk)O=|7s=$hoK^{`X|^_U zzFA*se=o+GO6zXAjYd8m%IQu-R9a3qBcjrBx*rjhmeVbXsI;8!N<^jQbYmhaEq9$o zR9a5yvoBI<-zWV&f$xzj?fauj``)P1zAvh@?};ky@1;unJ4GuUG-H53m3C@AGaWs^ ze3rC=`E2Ri%~Qpac?VQ!>AU8$qzlbwO5Zb|AzcFdRQfEg*xFsaI78YQC|P%8h}mJt zJ!XrMDQ2f4ubF)lS!wobWV_kFkR!Pp7xR_&_hPK6wC<+cXyo|~wm991h)T=pX8e~* z%jteZR9a5AB%;!Cx+@Wtmix;hDlJ!^F0hYE%PD=LNTq$BRB7KMRoeGQmG-?+rF~yi zY2Oo7+TTl+_IHX_dKq{A7*uKLC+0JypPJ8-t}>r3Eo$Y8HKL--U{Ix{L(FGMZ!(`L z9cn&98V4%9_g|=Gw_v>m{=}Cd?En<#DkNd{cH||quOQ!<{TZopzB~3rv60zaqz9;7&UkX=nCI5%G7Wa!QeizblnfmPGtrshkoe;_pi3hFHYkmCC8a ze5{nHsvO2&oBH}jK5y>fd9mv9|E?oHjfS3MKPq~T{g~)E_9LR_*pG*vW8VY)4WsU_ z$0+(YsIStdM~#1#;h#AA#J^kH+ozI$i>71$*Zz;-nzy)n@mo01Tg_)mZ!@1Iz0-WQ zw8q7$M_lG)(EN~|Vm?cHs`*T5P4gMjGhv_kF`p}La91zRke0vDJ%tsKv&_~(x|!{b zJY@D!*a}Epvu7jMo4pa4WcEqq z6SJ$3j5h8xKR@H+#Qcy` zLPX3DIpsve{E$;xM9dF4Wk$sOkW+F*%nv!`N5uS)Q;I~)4>@H?#QczRiMshAcM2)9 zkNF{|5;F}Xswz8}AHKek`7ynux;Z7|qWR%RMf1atiROnN5zP-j9-1G%2bv$czaFFL z{J5SrJ!;Gk|HRQJ=EvSXmCO$v`@i;I#|{K8#{V8z?nU5#_$5&%Y=?gka%jnQUE?Dp znrA*!nr}W!+Q59abVa+=jF9;pG@Ya?&1Xqhna`AdVLn6pHS9B;25`j(-PMaTq_cs^ z@G7##>;~k}OI+(Q$oXd5Aj8bwf=oC2GP2I>56F>i-D$@m7n;2kNtnGIdCBZ6$aiLc zMyg!uPCF5~*zD!Vt!D2;W|{S)=yPCfnNG?=-6vu?$teROrjwkKAYwYnDGws1lbli^ zVmiqw8zQEYoDw2pI>{*~BBqm^(jsCy$tg1;rjwkKBVszqDL*2nlbli{VmiqwOCqL| zoDwDCbtAXJBBqm^%E-RRkLFxUW>&|Xk`d6v@%d}w`0O=teD0b!K66bRe=kiOf2Zig zIfgsy0b|Ze^i0taCXRo)B9mFi>H%bu`R7o_#v{j;OtQ5c_YLTSmvo)^OzF4gv!p+m z&z9bCMe1Re83mdN($VI#q<5Onl-^}NLwX8D` zjQnnPH*$J=cWf?lt=U54ezOyhg=RlQcA8DQoEH{wi#kX*v%Qgr%sz^|Z}wwkkJ)k^ zSS3I&ETo57KNEZo3^Ox9S*ZJZQig|K_nINaMh?og-%8ZDaAgAPrm!AeEymVK6}jspSxy)&s;OX-%B&W-zhp17ISw!U_9^= zJyUdqnc$zU$V||&dH|UT{yEgK{C->-l>$3_4aX7|gJy#Ce)E~q2h3+lCz#KcuDIGg z%xf#id=BoNfUY#3C0%7cQ~HJZ4C&XvOjuj;zXyJUEB@%NUYsF4sG~aAwi1$Kwg9=@ z?3KtJX752>HTxFwi`n0h>Q}leoQ8BTdku1z*<$1kv+p8X%qpV&z*sU9l!dxa#7vM=21LvRIVC~FOpsF^M9c&^r9#9^kW)59%mg_l zM8r&xQ%*$81UaR}f0+q#%8ZDaAgAPrmVSACcb7Y$og|e)IK2v(S`3z}o*k>{v(usd~4tgy}uLdSVXJmxgk;s!~pFvib{R*jg zjXSn7a*o*+$Uw6w8nwo8e3^5x=o;CX-vc~KN-5-JOIUk}TWP)->TF&X5P1QC-#PI(Y98RV1-5tBhq*$^=qVhMN9@cm63gs z$>7I8lfjRGCWFsklfh@N$>4L>Wbm15GWdIGGWa`1C&P5^t_O@~UZQ7;jxZVg(-oNv zI`(DjH_yD>7r>tuB&if4lOcy|<$@-IG|zmdG~axdw1N3->15z}9+xKbSZas#ar0Ty zC(LI`rU^ZfljI?DOHP&(H6{7^c<`GQdTwDWaB=?l*1gwnar=Z4a^oX-oT z?>nC#Nf0#pWcRoLq-tBxrD1E~DI-zuCs$KfF^Le54Q|I$T=`YUb zhSD9**9oN=EFfCRrInm72&GzB^xXP&MVba$c%)kH@R`zK=Ch>3Q|;22`I429FgU`s z<%Gwfrvj^F0dl@s{_8fKseewZyGiwb-qGEpN%L9K5$3a{_nJRkdIz`R_#Ejd^M^}E zo6nZsX+BGOm-$TT-R4Vree2;ta1YSaX~=A|E0J|(w<5dE9?7}K0mn8$E->2->1~$2 zx$VUA>Y%n!wbFw&_XI)Do}GL3?cTY2P<5LNh7@)$>OZh^&%T5EbiS!~zaIT>V&BiZ z+`gWD`gbkrT-3jF?|wzOb!i{4`=8p`TR5;!Vb>vr9MYdoagUq&4$14>yGQpTnlAmr zHTCY-yQuS^?p^y8b?w%tFj!};h1|GnQDKkHg*|!|cJA9f_{Fk% z+}zIn`}E*S&+jO;FW>JQzO&T6-2Bvet^O>vFW>JwYFDX!xp}GcHk96%@Au8zz0Y}! zPo$&2?J2#pq^ET$2}9&Fv@?BohNhL?S<=^6(@XCx>Fmb`l-^m=+l?6|JNxzTJg{Gn z(t|s^d|8K-^!$*_vJNR3>c=XSbx27T1qYRNNJ%aWv&uT8B%_Xp{L>-(mSIbFna7mm zH1@DEk10v&lf%nArX;HYN0oU@Nm`YwlzB`^UN2R3$8;Uit8|G*99L>zNgfv;Uus`T z|Er!*YF|mee=NPPq`z~kl|Iiu|970Y&%S*Jeo^((J4esihUs2GQW`DRlZtfZGxZeGS6b>9z7<^-4 z*FLO{{aE5UU)O(N?_vE}{)mTu*Iu1_^d87c9h?$v z%qytx+t0T4K{pQWIxSgzaa%d=gwTWN9Us8Sr_!DTSdV<@9P#2eMiKLpg#6jvpf++0WT6YQ-`A9 zKwjv0cle?B!KveqOL=!f%~asd$WI0Clye9;qjS%$gY0^(tYJXWKrVhY!Jyv53b8%0 z=eKIzBFN(hayqxVq_Zn}QP3b2_U$_GhQfitjU1-E?$BB6JFi1Kir&9p*FM2l`-c2s zhrP}EbR9G(xB=g`_t3&V=l37jw`);Qg;#8|{yhr2w`v|NIXDO|>)LlfpTgA6j6-x{ z^WM~ZV2_}#i<T(W^Y5guKjuy1{sxH|E?R@zi-#p{kyv?f~GXK>wXCj)xh383WEps4MTTI z+phgC)1$a&pQvKCF4wke_Ztd}f*+&7?=CohVAsBd{H|RcW&RQ8-7qxc2`?O46x>|H z^+_Y+o31#qq$#-NB>9$CoY%d3VV@wwMQywGDJ&`~)ZqjB_X!^3*D(&J8caAoALQo+ zbM|TA>HUy~=FQr-Xx*YsuoB;YK<5D}&7jUb2lwk9WSkNNMSOl7>z+ zT$jh=)!mIhBX?PIy6KQPbW<{(whHwLD2n+riOe$~X9XOJ!Ql>(FB80RDFc+BuLJtB-QQmHR|J zh?= z+S13t0}F%E?f3cz@NN2Q=Cv49GAQ8{|Iqjt_h>Vquvd$ICC^m;Ri&C(a)Mf5YZ}uv zwVlMDHMGT2RN}L;-D2;PJ*HMBT>H%!4HEwVE+Hm-m?+U9}IyR;J32ck32UBszCO6 z{Am`3;ukjwg4XDD&=gui4%7#~{r$Wuobv|g{7UHl&e!z{;6(0O4|?ErKb_YJ{IO1rcYJ%U&YM;t6h3_)oVL14$toAQCX41kScoF7;-^yyg<~`;nG+e}6 z0D9t2Mg6wF{l9SRX82%n5PSlE;OC-#+u#1g`+O?`SAP%$-Cz{HCF-~R?XR>X2r9!S z*a}C(D)8I>_P?++2<9vcf)8Oi_^qt=u^;oCd=doH;brh!S?ygu4T6F29J~(2@B|En zyTEV5zhM4;83dO?NAO!&?JGIv!PTrm@ErK9toDPx3WAT|8`ubbE35sUH9XUB{nxyg z;351KsNeRt|M;~*P!0Zs^lx~k(2d}?{q3L5IWyqybwO}H%)t*u{kFgT=YGrc3{}^& z?mo05ozm?T~_m9jO*Z@Dm7qAAF z!V2(P#!o?z2{qt3@LT$3-Y;fRP5j^{Q5WE6+{T2ih;CjC8yBRLr8U$Cu>05%J0r)NbPx=J`-@0xomljmS z|8_u{-yNJld}3t($$#7b3-J#4m~&Rc^XX~9Jh&$`C2drE&d9E_HgnZ)_Ewm zI|vR3zm3RA3m$_h@DliKZeCij7!Ku+g!xbbvh>Hp)HW198J<&H!M^Qx()MMl{S)*v z`P9~=Zdz~wbcbHh9H;K7O#DS;3m+qH-L`SxqefdKjyYb`+x9{!80&D(jIM_ z7inLHUkP8qPm%Tm>!k%pz=9@e!F%vLyao*#r3FpkOvr;HpepQYm=+v>Cehnq5DbMY z;96)3t>E1Tj4!+bZ@{DQ98`uQpd3_$&GplQKj14^4}D+&bb&&+5H5xKa4vj6Uzft0 z@D9v^*I*dj0#)He@SAc|+ZW`t29)Ecpd6L+MdZ>Jl%sM!0ZxH?$>9M|Zpu|TwT0#M zc@-!p<*1xqf@*LwC@1B(lfI^*!_g6-T$Gz~I3HHfr!PS{D5r;E5)?pvP!4B;-{iIL zSNi-LD3>2WxhS{m>2p6&E}cNNy8x8K6QEk%1zYLUAD|pIfNHc1&V^>69CAT5stS+L z*GZrp#(-*b6R7V$foh>#+Cc|U-hlc2t;@9N_MP~S39^-X)~4H2I|vQpuW5gRiPRj4o8Fflnr_&Z-*OUF!)VF4PC*dL}4W z<*rn6||)CZJP9w>*0Kz$zynv>-~ zYt2SbUzdT_m@7ejJOie2?-}p_Xm0vVeN_p} zHB`>3q2{vID6O?xo0R)zP|Z|Bje%;Yxve!zW6=e)R%s1Z4OLT(jcTejS8K4wNNcca zs4??fy{7aNDqlo?Pyr5x9TzhG=qkQ!{R%#Y&){8H49~#}FaaKg@hy4Z!x$I`BVjaj zf-W%T0_Fg8fgaESu7cLk7MehFsC9l?kONhqI%Gl?q(M3Oyg6$cd;p)qYw$Ka+$=5l z58Mq8z%6h)41)x;C&!M^657H!&=mZpF;Lt0QgBKtqrzb!; zDre=WoI8<27f^1>)o;pKV{jZbJrPvvV?ec5?Nw{legnDv0IK;npqlF$&=}|$m_}|d z!4#MZs`+FXO)jdja*n}u&T_|P_4g) z=g92^P>q$lYOI=HM^1e}wN>tZ(->%kpX(T8o)mG22a#T*uLAfY5niOIZ)qKqh9o}AE?jW;1v3ro9gp% zsQRp0tf6lkKz&^W|DjKhNBXHgs_km})EOGWd7wVlh5GdI+*DsrL)BOHy&`%vY^INU zKz&vYZ_>BVKz&u;AER$Czz`S->Z|&G0e!q2>OeD4pQ}T8`g}0_OkdMc^;tQ*OCOiO zJa`+Pg}LB2<)pR;>GMPw1^2>@Fc_|b{-9bYSJgtbxq)16fs5cWP_7ri#pKorYCs;O zLwQh*l=F6StB7twH-mEi3REkN!E$o^5*EN>7!8krYNoO1O|G}XmCzMbJB@|LK(%Z@ z?oCo-aRREb(AcP!8k;nz1mBSJCeYY?1R5KSmESZ*8nfl(x)Pp%XF+43vFQmK8`WIT zsA{ffKw~lnG$!3ZW1=z20X-9S7z>S&o&k-Ko&k-K#-ti(Of*IslMSG;_yIH)8XG+m zuYsNkjm>|^`Ek&gj025{#z@bI#z@bIo*9ivCpZP_g2v!D&=~B5RiH7^SbPG0)3dEy z-@lxF@DRKNZQHV*!a2|sYCugm9FB$?FJUc&PS73Bh4Uc?>cR1FGQ56qS}-4`!%Of8 zOoIF10f@l}I0BA_01knd+fW~P8m2=lXbp{^DO74Fv(pXf5ZRENget^yJIjn>B z&=E8yjo>uU7-hpzkO^7v6gfW&qd;Rb2yTMj&=*dClR#smvD!t>8mq6-Z{cHD3AG>x z(m-SLJ-Pk@U%@vp1crgeL}R2exd`e&1JGPp4H_HG4XqiP8-CLq(U_%m;GGI<7=v~2 z39JB(jmD}rW0DWmK+jHjI2bfWe}TqGWA+$Kg|YB3=vlfR+JMIHTXOs!K7kdWXJ|G& z4jQxX$x&nRHoOo0VF+9cg-`%`W=;l;%_MSs62^j_l?2=l{Xt`+XF<<~-!vARK{)^G)AE@*D3=E_yMJr9}#%2m1D397kr^_z0q4ZqR%9iZGcgXVlk zP%f=OwV4L0%_L9`cYGV>74&4WKGig9piVA`F4MKyyoLvvU6&v=(a) zX>HM3qa3x?C`aY2HCS^oXca#oJYS!=N7mev;K zsNA&HsK%*N!3{I9Idgct=>VJQ(8Mlz$nm~s&|go3ay#*Kx>C`dm1#Sw07*IFIq#jcIw@t zIixj1Yo*>PwL!V~ZNn9e7u?^GKQqE^{JrSU=nnAP|9YIRQTs|hXTVjE4`+kl_P2lS zRg4)_zM8cG{MMxt&n2vdjS#})a5qc@zb)*?pNZhK{(Of4oAK3AzwK|oj@7v>pexja zM&P&o?VrT4&%h?w471@2@Z0|Oui@AY@CO_=fLu{s%WwPJpU*jUpbD0$`FsU_JBqd( zIG(n;k@kkPwS^|Mb%?ZIMcV-ALfeo?`!L$Z!U)`zx?~(Rr?%_K3@eIOT@Y}fi(}IBy@Lqzu!Ea@?Up$F^!h5g;rooFa1)hP2 zVIuhL-yW}P>l(WDm!Vx-_tLd>FI`*r^4tH{$3O5m^?*a3puSUh$DkEq7i|Ih1NyUk zYD;j;E${$TduDI@CHVW`A$a6}XkYg%e+L0aJjZ9D7kJO$55@cKH`?mV;Q4~);J32c zZ{nCZ9Qz`lo!}Sz7FZ1%;T3otUW7R?6{bTH?gYQdKLWZ&W7vs52-UTI16|`I@Y{pz z`wZ5?dhlCW?O8AJ=UR9OCV=1mZTnH2TQhQDs!MuI;z~+s8f3y`F>_@Xn&W_bID=+5-9r2fuB{XP^~e zCvAVhM)(;%g_Yp9`HOjPz(Sbv{{Gvya!mRMd_ITD;I~2e1l$6}k@l_lJ&?A9m#!Z-U?Uw_oQifu-%I=l;0c%werx^_^@e#cAN=-j+b`nWYa-Wq9Ixvp z;bAC*q2RY|_=2VU*$SG0-^yxl%`r3K4R|YZ{J(8)&$)$>>rBDxx}#tM^o1n&Z5zH| z8U2K2;J32cTXW1zcmv*w9RF|I+jDMVbl>cTj4!e1%B(ty{5w}@OtFFWwkHlm@_})yJu(we*3rWA900r=~raV=eUJ#D|k`>-1Pb~pRBz-|aW|9{{90OwDM zT<2T7uDcLc!ZdgT{MLed-40`6T;#rGwa??2`YZV!23mpN{%!kvTxTWt>zu~5blviB zG8ByZ%f5YzWW64Dj2(Z7<^7+n^Y9J-=PHhIb5H1yjLqWwkH+nmWP? zn6-BA@nyBo_=fi!%!YC6_8wnW`)3?;#J7ANgBswsvf8iUm}}rqIA}e8HbFmud9Vm3 zz@tzM55s7<7dk_4@SFTF&^4;U7x2J z(UJ3>!aoa(AY%i6-+|5szwK|o&iep9f}N4`nscqR@Ay6#DuLhrZTmG`r$6}XY)M^r zIl2Pgf@N?Q{0IDYA-*ka1fBCWY=D{YIy?g}z#X7-hrq3H8R(vVYfs;+e$VG^I1T*v zZ`=EFodo#n9L%+J-DR}>3KQU2@Y~h+u5bXy=-9vTY3L4gH!K02`wA?EmtZzL2)foC za6fbh-P>=4T;oZY0kgnwWwpP{F(1Gc8(HTe4+`K+s13)%>5vBHU2@~OY&@~?hU1JFNt?`e1-w&hUZtz=K?GriXaX9NI{vHnw zgoEHW+S1UK=xSI7E8so&5T?L%@SFUbple(Lhd~X{wGIJY5X^+PVGN9gVQ>dr16|>AxEfkRJ2(yU!Ef@-LDyIgPr)CbKyRC07k(*kbseJH57v1l*W!w2BEvf2;X#@NHXFbQ&D6jX)d!Eb8w$F%ru|LrIJK^@?9 z7z%#dfIs|C_Q6@;x3b!s{6#Ks9ee`apa=Nv2LAQ#bMP*_53j--@B+*RzwNddCCsx$L~o=KxOC!yJ*`3ep8!2=HznwZ=cUG z@4!ZA$1hk}hpq>|?V&B>K>81Tz;E&cU=Y0fKeX#Nvm6Dd!$aV=v-mA34d5ww3EIKq za5kI^emjKUlyVH*0rx{5+zQ9R3E;P1DyIj3K=(t_gZ@wvI)mTd;J2x~2l@QQlyl(= zd~MWk_ww6KCO~<9lgXi=-*%FYK8l9mw|@LKlbhi?*aG*%I*3CO{C07*^xz738-));D9`8iGB-y+u!~ToUf1!Shy~mf;{ujrU z5tQ`*X}-7z!gJ$G?gH6h4P9Bkf0?pU%(srw7$xH2AHo_H#L= z1+;|rk>l^fKLJm}bCLF~_#JR%%kEb?tmNN7HA5W!8y&vBKIzUZJbjM{Tcl)EP|!* zDlCM%VIquzJE0@=hW5|_@}VxA2)VF@Yaf9Af^LR4VHxX3BkPi)@0vrJWl!q1Mv<^OmPvHr8 z0Um+L;J2Ib_d=YUG+wQs6V!w=;7B+HzNe4d;ak`Mv*2Br0WZNVa6iN$2^T|WxDZ;y zu}}++f@5GKecS=-;X8O47Q%}#6UM*;kbt}366gXKK^v$FXTs4?1^yt1ov;CZgW2#N zyacnrZ_05Tya{@4#-sDVZ~NOniDO@e>6|+sZiD+^7>t0n&>%$Zb1(3qOG07T}k`LUPc!JqgdkWOy9zhe^;Kil8%eg&a5! zYQb4>5F7$K=z9h9ee_FM2#erhmt%(=Zbz!4xQh5pV8gH)JHpk-}blv9FDylF6P`Wa1zvpDo_nJcVPVBd-xe%hs7`pUWL2h zA-Dxb!4=RQE{66{19IS4I1zrmoaY}l!Y}X!ybmwKYj8I_47b8)=mPq+^1K}*PoI*|I1BxmQJ0_xv4nPxV3fR3CIt^}%odf4h$BGyPUhSEh1Oj><_n z`tASraT+__r#ZBTlOZ4eALi}_&Zeq={P-!8(nXR~N(o8IWiA-W<;;y?Zf3@~B-@#p zGZ)TWoO5Q($hAUJ5>iw`xuhtPiYSuY6_O-{eiEgqbW{C5-?h)$XP;qS&%gikJpb2k zzh3WWo%Zar*WPQby>5FQkKW$n^8wWBPk#tCaV36b-vxw+2!Dj${^{{@ZaGJbd#Gn2 zaWo^8I3!MqL*kS;Bu>5k|NdSw*E9iB@g(&2Pxs%$cL$>aaz4HN$mh!kkPk>iJ9I&F zgySkSf!_Y<@p5iCNB?{2S3%;)B9u5JPKiU}lsF_#z5W0G-bk+L4Xnop(Az)VKZ)Tf)S=kWlhLE;=O|4k^@AaTky zNStyFdi&pY9(B!J_fedH+}mf6dy{*Wdy{+B+kg9b9q%^cln|nd`nN zo3;mXZ@)wCP3~3hP3~21|Lx;-yeEiLu46m)+u|?h8Xv<4*oL>T9xq`9regv0_D_$O zbIUot%At>mPjDFPu?rICTKR86xdw?-u0i6IYtY;Ow)3cK=DKgqrR{~>TLVJ5H@R22 zH@R26{kM2+`rr6e}a8WaTF)84~MV?yYU*{hu;3_@p5iCM~yt@&~V00 z--GZF;VDR*pA$-)at#uvT!X|Z*PyrmZRb(f%yq|cFNuMB>p&>?Cig1$Cikkh|Mu}Z z-WJ3y*Ks+nhu$Xhc_F^QSNI6~@gBC}WvqqX{^{{@ZaK% zXS@f!Rky#Phk4i%`a>v&-m2T*rj&Rw%g5X{()m1=P;dY0@8kT`*~1tsV=wep-F`ai5G}?Bzjx6D((_^Fg^>ciRk!~qj%hHN`6xs}Z`JL8f@3y3PTPWm z&|7u;ADqfPK0*1xd(c~T`y0-n{LG~Mpcs0qZhxCu+%IN5OZh=MpT`pF?O*+U+-%Cv zT*?pjLT}aWcRWw|!QcgyA2jB3FG6ek7k?kgu@f-`$8Fzxe<9^(G3Dna$`ABb-TtmG zQ+}}c70M5?`TRJc-u~6!*Kq7+e25mW2ETXFGSYJe5bV9p8-4ccL{q*!KJQJQ`zh^8aH0LmV>+lkuhP_$hpzfu}Ifwtp3$-^F{_ zZrfjTCH-f#!7MaJQ{0G~P!|oLxBvF>avhOqhlgzOM)SEdx}t||e>R^BFa%|`{jc(Q zC01dBZU2{iK8oY`$+o}Q8?AHjsV@z6MB1&&-1YeD{T9Ht0{LFi>=UG zb^9OUm`Rw7HMZmT@_9dgMfHpS$*ZX5RCKbIf z*LHk$`v-AMHr#m3cKpwL{(UX|f_He21ik&!{q@!`F9>~}N+?;gekJdH7U0CMh;xD^uDZjP0>B#v!(3KEwa z5{I07AX=g;^yVQAMxxs~$}LX4%exH1nS}2l1|D3BM)-tdzrjxI#%#O_y*h^Ev zn1dLl_E0%y6F8id~x{*1#ohE-UH#dr;R8_nl&*uXW&J*>bQ$UQ8<2*^EnPzJdNH=-c- z&=f5p>DUNIh+FPyHx5AVX(#4F?&)#Ng51-iFd+AoioTG0>WPMsd#Z=}kbA0w&$w2( zr>)onxu*{>6OtDbF%^2da2wAPPHg8rDCXidq@x72a4R-(%zli+lW-yfdb@?sk+^IJ z{S&O?J9|)$X}A-KIL0x5U_Rc23x4RWnC~X+WIqa^x9ax$Ip(sDNM9U+-u~(SIh8V)h4yHQ z7C6hb)FAwp@Mj#xF|5KmEXHfl+h{(I!v?NF?qLPiK<;4)MnLYtgEGiHxDf@pho)!= zNykPwLfmpsyKw+=PdhOea!-$A7UZ5Dg#o#zRP=@1Q%^L6+*3W&hul*ge8#oPJ#EDv z$US|4nUK7gh^f%qg}W%HII){@in(|V=_o-h+=@*cvmfK|B%H{A-frP@Bre-SImJ4@ zvj^pvhC7jnV;u7b=HpGc;D_Fd`EJ6;>_-9gR^5I-$6WRa>5D_q+dthuhx07J*1&n@ z5H7?N%)|qjh`un;9lg*IP8{D$+=S~1H)AY~UK?9#&utORjAQ=5e7p%4{Lou5-%a?8{V0Ims@w19n9DvVeQ^kS`=|ToaGnL&8aU4!!iAWE znRoyb(H91~qZc~DiQ@-|n{YkhW-P~QEW%QZ!330|5_#~TGvd(-?a>r1aF%PSLHI4< z&p3=@ScP?1jMt#I(R?0<4P1lV!wRf{+`|%#fZT%zWsrMtBMNd4P0iY=evHGDa3TYGyM@n@xa>>HDc13wJt)UC+=)aS zK^%twC|L2oVphq3EX$`Wpa-m2Rl$uV2LW{iYqjs=hZ zr~3`gGRW6?foI z;tV7Fj_?eQ;2W&Qdc1@cn2Uv|#26I93%zyba~wuz$?-O9+1^`~%yu2Wzkq zui-6B!c^Rc2Qd`Gkcc#NKn(O&o6q%-$~DS8bU}B>Jw)ST$UXc*+zvvyhad0`t{ z1G%RxG>7EHb+`q3Tfj9h#wOJMjy99oR$?Otz=s=f6E4QJSj#niXuHmNd|rWfxu$&>g&DXScVIQwv>RC{#$Q}R zeZpr6Uq^Qg!f#x|RfIDMmmwNyI6|C%U?S!s3Q0IjoIl&H;|t>Y2_?U=<{CGnJ+}VJ zIWP>5p$R(T<6meaFagh@1A5`a8QLPkX9-_ND)MmwuE%RXb56K160H%5YjFqk_6OHe zhyQ+@YgmLt55_;=PoJBZRqlV)TJcU;ghXMHE!WxcC2%jNb zffVGyf$OmRf*Ou3$i)cMM=NY{)Np)>;h2g$5r>1sbp}(g2zvALc_J>xuJo z6k{S9pe;5M=OL8gQQU?u_>?$LVG^E4C-lbm#Cb8{T*9}Ifg!jE4ex=y zxCZ~WKn=$>=&ic_M>ysujK92wV?H9$8wW09KOV(gv_&!wUs}WQJ0{_I+>JDRUyJJ` ze1h;rIMENMFR9_EN%#Wc8yJXE+=y1t+uvNnRs8qM#Jv>*Fd7%)2E0Ptn{W^OxCFOg z8F6mGKn%k*XoWY3^F!og4CE7q!t0?-R#<+=uCCgGA_U zDRG{zM|r!ZhU0SRt-Ae9I3^0)uCL)Zfl54$#<&Z+udCts8uwuunxiW|y0(Vn8{Cf> zXp3ZgR-dwk33v|CNWyXA_!D#S8U~;kdh5dHUN}vhS2Z9_2;WC{xbQP^)+U@wxC$xA z$1lWLhwuf$HMj?U{7Ibk36~IVM1S~j8E(cp;@XEwJOaI4N8D{N>?ZOCEfI$!4SA06 zBwj&J`F$j?pMY2|6Pl ztL zfh~|UUxoJ|Y5p4Shord|_d(Kp2=0QUc?(3MA)4ScX(oAa7$+ck@EI0E@?aL8hvdOD zWJB_xAMSzVK{^^h^59Zj4atKVgu4hO57uKVBo9{OQAi$)#CZ5niJp+M-Vt%on>>&5 zOvy7Qc_q)FJac;ccmIAL=O2q&oU;yoYet$AeoJ^7>#zySunI3=F)A?zh45kkvJsAG z+=3RUhX(lOR{Dnc6o;`5yD%4v@Dyg@K|GFr7=%Qm<8H*@DqM#Pa4CLjO1+NF_z-Vl zJzmCgjKxD3is8t`V01uN+>Qv`h{ib8q=w^H9Kvzz!G64mS1}Xw@Cc^Dg#z?Kf5f2& zu16!(LS6h#8ec^C3E@F}fDf?-@8JnNgK?M)y~)0LsG9$hS5hwihqRTv`WOcxd9?%2 zLh@=VW zlwlMkFN)C#k{2z}4w4tm@GEI4d2tMRzmV(0bYULuDp})VqF`?C-7i0u0?BX zYE2!7Qapr)Xp4=lI5&o25?UYzAGRbujKFlXgcDy7$7#&KBBWpt^wx^cUGX(>)(qzu z!c}+z3(yH!I8NL(2xkz!f>;c|x5RxB;Y`BiNJAk`6Zd6=^9WZX6$Nmh9##_Pb`)bQ z^mYZ;a0f=U<#|OEdg6E#&nDq)!j(wJVARA-SQW{0k7A5RW88(k5wxv%81v8>S@@MW zt{_}Y_#XP89D0l3a~hr_&gJNbQe25<*g%{IP=P796LI*GIDf@-yo~M`gtNp|kMLE( zO~}Ov+<-Rth`5epB%XoZYPaKFJMetK54}~le+{~g4@v!e|4q25}qXd1&8o8R$>hn;1$fob0|g`1|lE5&|N<1tiXG*ZwTozV^9Xpfq>0%u68zwr&e$6CCPrFa7`U@`P2`PdDINE1op zkFXz-##=BGlExD;6_UpHqZcHN6VL;a#$8YglE%N0Mi&xFc{z>ckTjo%mmq2WGzLS` zygzavX`X?`kTkE08z5WkTkywv1o}%TnNd7 z)1=uSkUThnRggSbjMpG}@I1VbJSfBvNFHRP1tbp|pa~=ouEt@~RPtaKK7-`JRy+&I zgGVs~4`3qhft2;0$b{bHd6Z{Lo-xTQc?RW~)7!uM_eq@paa_+i8=)5J;%q0PvZa%V;SDWA}q#q%tawe(GS^3 zLOO0ib6kZ62*aiLv?FyVHe(mw#(F%Cr!W=|!;j%eL>f9E26rL?7vK_{x{LlBzQS?5 zg?I5Hmg5=B!%$Sfg~7-~f835XxE_shC9c8Or1eRBf-kWhyD=Xx;|a`$-eli$RLy_M zD=8O0lctha|AUi|ygG;_ki43Q1(3XY8g58l^~OL*UZtQRB(JVOeMnx_gyhW*JPOI1 zkr)rjn{vcM@}@01L-M8-{v-`0Z@wcu1Ie4CcpZ{A^RX0?H?vU$$(wtT2g#c(NM788 z&q+JUi#^y2$&2lH0+JWwFd32;qmT^Ai%v*@U2 z&9QtJA9bVei4mBM+t3C35~$-a22Y_S;;}cLb7KOY#$8CqmvO|0NALnVp%=aL3R`;c++!4G zAObybG?BIyv#=Z~$ipRQh*iY38~GRyy~Xf(5MCk9^(e#`+>CbEL!95@Ar1|% zcK_h8mEgA4h%9<6aQi@FjA@ijieCs=?bn1Sao5szUY+(Bb` zjJ5axE3gWBlYH!hQ>2Nc@gW?Cr15^d2ub6amD zLc;ZglIF{?8j|KOVK^ks2g3(R^BhD#(!4S5fTZ~iI8K^Ln(xOENSg1)JV=^P#nX^9 zpM?I9H1B~7bV4lZLh|53Tn5R5Kd=Ro2dnTNBoAK0{g6DU#C?!F@Zv5=9<)FtBoCV4 zG-)b%a2O{bdGHyQK=R;OEWk9(#1KeXzX!R{n>>&5Ovy7Qc_q)FJac;ccmMu0=bww) zIcFPOkH)whb#W+@{x?3ter&)N%)}f_#8iyH{pf|haH0pIa2IN!4t~oZ%?ZCHJdJhO zgg3DYFJKueF$RV3VgRxcj%eJ17N~~?_$HmY6QANRwqY0MVi6w4EIf#Z(GP==h;-bI z7+i(xZ~-pGPrayDu^AuYEv(1OSdOuH2tzR(xfqNN=!)ABftztFej%;@!q@l#pW_H# z$J>~XrO=z~TaT*wFL@>9;vz_1{Y;wv1<9+ESOdwcRRS&+O)z;%$kxCB>0 z@*<3IFQMecM(l*%TGIx0#i4=hGpPRvm!dsVaqM2|I84DJbV6?&9l*KqBwj)fWaEc> zh>!3Y!WBq{3x5+wUBZ=wn^24~&|39K& zia5{WDZGj#<_*Dr;odzb3cVkxE8sd&$+IzupN8x zE;ix`JcDtVj0%iGGBVK#321|M_>^n^9!v2$W@8~9$CJoI5$=V7L}cM6+=|+`78l@R z>@DWnun{})7T&>RJb_V|fT0+M+tCGo6;W3bo+SJQhwwF4VhtAH70kqQC`K6uA|Jib z2hGqD^>H(5;Yu7N?fwTl@Ci0x3-l)Wn2!rcTS?8zjNE%;{#*p$-7rRI!N%QsC3Q6rA!|?zl&3%Z0qWLCX3N_@Os>9_5*m zXH4=+o`RUSKN*W+=#|FHH7{*4&gZVU_V~OtC)#-cmz}7LIHZA zKjP2>*P{_?p)Sr2CXEO`BHV{f*n$;Uhl!YiO56_*yl|pB!f_Xxq6K~{BuxmvAv}!( zIE-a@6LYZ`(=iK$C`CVHBMIra1RM+2ZOp|)CjJ{_%^&jC{bc2Ck{nT-U za|qu=GTb=h(yl|i%UiMNC;9d;Hm1vBO#I+BjFa>%W$mddA%QdvaKH@x% z_puj67>@>s#75%&0zN!~8_^b>5XoEN$CC)!F8_S@#PF%x1 zSUQ~N6}h+%4G@kUm3$ZXV;0&W1;;CR?g?iTu0%Qpqb6>`s$pCUiZLF|(FyyB>qkt$ z0_ZK9&ttHYI1ghY=Aa9*@Dp)ePPmBhT?~L9bua4qp=Iub7UP(G!Dk z0UBTlac;9+#{>6qESikrdB=yNsfSRB$I$|vv1=4*fYEpo&CwN~j->qI5xjs1B;eo( z$`T&K^Kc>)e-T$5!nX-`KyT0Sc^MM9h64OXoHr6aNBAa^;Kr}Sc@^P&!nH_2KK>xi zdW6dfw;~fo2tz|GBhD?zMmcUk1U@CsZ*A96LYxz@{z0C3RNyhRLOc#XKwFL(Sc)FV z#$WeSUl1-Q+=4ueLIXr#$5_f0?#C?Ljb1oKT$d6qA>0VPP3H3g93jp#cor*=fx);0 zjqo;c?m;OYLQ~w0eZ=_#9>ELfioW=XxGpDLMEEWY_;C$dVLNdiwOz-waeN;g9_ITv zI+3^uA0u3duE@l(hq!jaCkU6IGqUjg1l9u(&Ldof?ihfd#&aEn^9kQV9}GrqG{QFG zJP5tL!sm4`h#0SLrB`WX; zS|J|a5a(Ijb&Mmcd57tE2|eJ#Uyo7_2$vIXK^{h-0V1&D5z-L%V;0&W1;-~* zzYxwQT#3FY!lh_}_lWZV^!5Uu-^Sm>RrfK{knls4U_6@QZtNq@AMglXKv(p|PsDXO z;UdC!F#vwlL33;%&I7m)QxJ|GI6|CfZP!sm+|#D=EZ}wMt-Af|IHu;)9P8 zw&;k%v#6`^2G(LBUd1fTK?%x{hXSO-z-?%SYtaaoq7J^8Nx8vJ?8AC&!jqVd37CT6 z7=s9O$Hl0PU!Ecj36B&0fOoJFui#D0!y*jBDCDCQ_aX;vaW`&7E8Kuv@FQvWJC5L6 ze2OoiH_68ls7cyN8lNF;{)VLS_gD)_B4oTx7D1oGLE?Pm-_$J&2DKFRJ zGtx-Xd@J@q(tHD^LDKvIJOWAc5$Fj?^Nxsvq_M@TctgWWg)$%Acp8j=T7F&&ZzlaK|;g9M~P@*oEF zAbAjmD!pV4xM+;wIdNt8gujK0*Hk zpW_Q`#$L?Ed`!lZ7>fzW!o5g9DmtJGYU3LGHJxXQ@D$-M*of^|iFfcKUco4gLotTI zg?zL_Cp1HAT#uV^avF2aIEb&Y2mA3dUc)n(kEwVHgE18Sk%Kg3p*dRPI^2TVsE4EE z!FSk;FQ7Ns_amz2zvPvaix!Z)YJet?yt*2PNn6RQPw*KeuRg>qNM1dRX^^~n0O^pt zia}3EUUh`zO%1~JgpxPQu^N&$FJU+&ZwA8$$(tNRK=P(B?ttXY4LD9(O5W_p5lG(b z#ym*gOvTfXyqN^aiwx9-te zki2M%iy?XOi=;iF-bPX9_~+=!w${>1PstK)3^M z;9V@ns~C;(C`SddQG)j9jN8x#4bTYRFQAUW7dVDp*oTE!iYGA#4`T{q&==R@CR~g< z_EXSLefXNt!F(`r$@kl~jbjBSBM-5zxA4$Wr_y*rYZ<3FXpgw6U zX8NPy~`5rtE zN%LuV29oBF;2ubt_e3Tn&Es%2B+YB!a!8t=#a2j~uf_&QnyAs)w* z$U_mbU?35xxCytSHm=15xEOoq(l%owcH%9(gUNUTqc8zOF$@VvMmu!D?P!g^<}jB? zc#`lJe1+q98}H#|ypDNTgy9&A!SG=a@(_(KXpV5)gr+z{9{h=;_#S$beKq)d)%=&d zl5%kuB(GW^5|UR6Fui9kn4-rRxTNkhq-T#p+dc~KXilQxnU+p!mt7n|`kBrhgmIwUV9pdTbJ5|Iwci+EfM$%~6o2YP#o zy6{=d!vg57>&v9~5}p_IhTf{(zm(%&;du0h-nv$||5c7(#_{M4y>+c-f7){1v%JQ0 z3^(*v-TvMyDC4g)M})r6TXp+yT}d7A2G1>;LvPjXcf3h`y_#nfd9b!>_P_cza|Z8F z$Gl6O1HDzZf6zMW;SD^?*a*EN?ci5j?)S{TJ<| z9oa=)ge>T-y8S(Ob3J=Vdl=ALb^BL;PP=xH_5wShx9axaag6KvhWZ9wpttJwzjT`R z@<;j@cn5l`ZhxykNteGU4`>d(Rk!~Ej+qXRBg`=hjS+?2e=}czhp_;OxCb?H9oF-m zJ+|}Dgvhiim6e!?`oiXO;AE!=>O9J>$qV>kFRe3T8_E!mM}*{G=<)(+drCPrXajom?I4bZ{<6L69}I}G?MUT z(=f-ccog%|4k`G$Ntojg%))YXMJB#&9Oeike3oz-Qjv|CxDIQH^F!P9&F1r~=tJD) zxEL+4gt#}NKYXZ(oADZPZ^HnTp%xnBUE=%{*|-mNaR=TZ&V4AwgJ_0MI7pnQY}YZ8 zIG@JJ7L=Jg!W=IUu10?hMQt?0`rE@C`%#X`Xn`0UY#!z~gQ-}I1PsLQw{b0mO9?lk z03*==k@$c(k3w(r`1~%e2(U^fKB;gowItZU3T!AzcAPhI+P2&6z9z2Lf zh{hh`{1%fi2Tt_Icf@%)q25Lj_xe_0j?eKG^j6*eF0Hu+oQe!{)QJjn%qDyn-C*F? z2+mJ9hwx1#!;LfHq%Gk>!qw;xFC3_cm)nFnHsD?i#g%A`jl{JNqc8<}8_4HUT+21I z!w1B997Pz928hH);`{oodf;$n1FNyP4OvlUU zi9xsk4X}hbx7n^EtwWe2_AZ_YxS_Xd_jly@yEz_i=q;_f{hc_zGsnXXy`@#Ne^8e& zM@CoD5oOR@b^F~;p6Qq{hYJPJTXp-}#)diS$C1~FhTf{%UnidWvwN7M1m)0Mb^G5< zd*6e5BCkdRk#0| z0hA+yx&e96TXp;U4x$b~4t&tt7(S1~Bs^u?FMn_1Hjf*@XEEs-+3RrVZ|hL@#iqu^ z#~O)oMq)~4e0o}vv!4-{7MtuyOYCbTBxf3F&ZKCEFUMW%&M9ye=evzOSB}5L8~h#z z8_pzWABQ`azq*UcjO?G-b*M`@YgAU?N8 zqEkm3WyNJacWy-JNy~%Zi;2(do{^f6nUxsF4;8xiamvLz^70H2U)a{8jigF?& zjS^2TS6}KXHhej*VuxIxyST)mk0QRJoN&25*<)TqlzGRpqqxNI7Uvq}IpIc5fw!c{ z#nI6mOgwVU5|28A6;V-Pu~F*s`V0MqCB;UGH4?ini`DrS{HA$3a=rO(zmZqsEpquCB!I`r z_LSrdG5oGq1{>TW! zUt;8WN?gQIROXR{_PD$(U#1)xQdFvbx7_fQ3@df{e2ze(Rv5m5!aRTQ<}$h^>NK{c zLP(a{vN|*iyyf9-tduRvHp;mc?n83M>+-uDUiZ*4x6e<8x{8arV~?w{q|EQ|7nQbg z6b&X{i~^slsMO<@T@ms>k@7!L@;_~@2Q4K={=0qETPq0OTQ>KeTj({iT_kl;xuiDd z%qjDF-NjPebNppqw^8b+faK-|(%n|Js@``*peP3mKxVo#*7hXDCGy|FBy`H3BSWu` zgetJo-a1icW`gY!j2sVl&!b1~<`sHLD4(Y=$8C5Di`}7Ti;_|zg}^#fpJe-^&3{FN z{4J6vHMV_<4xvTz}@*63~@K9RUY(7WvP9xoxmcgC2I|%NK z41PU1Ey|gcAvL1Zg^qMem^_Kz5|4f$t(f{cQ_RYm(q7{A%i;3aSr3&i#yO5`d02-9 z3(ZgpuY;oODRNb)#4(?2^#E7@1d?E--okQ+df0uTaY^1qNEVm7rF}3TT(jCSt0uDw z4VLC|pDWi)UM@5AYv%JVv6*Gsku8r`QMQUPkd0RDUZJXYcSR}jx^vCy!RMFfQa54U z(w+Un+a<*Z)7UJ^X%3aAW?SR)yGy0=p?&kI8YtvOeC2^k$Ovh9q<|%~i{jK~o5%g+ zx+|nmrY0HGpau_h@L7xsUO;+kui$@l%Sg5z6>VL2meZM*Xe6h`raE%Hu3-jwTsWMk zzc|-ko^4HuEfYh^L6l*uMasBIQk?df`qx*OUreF}z8H8=sc5a*#VTvbY4P2n0(X|~ zOz9SH^k9#p)K_WHaCbdY>2`ZLeMXtBf@Rk+Rs?bQd9r<3jyI9?tdJ3#I zHj2_@=5|g=S+RNZx>2Wg&*3~JrK&!)?%0`}ZuE&!=h8<;%8^xCQfWg}r6n0%kXKno zO_E1-%uP~yrO^&)-BpvLt6oEHpR5SUE$)$yhP0u&!Vi6RC2uNA-JxGnS0UdCUcS|w zQx(NKV>7B=xQfT>8`vMxV3l5yU1U3DpZJW-KB=j3Mn+0pcxe3UWZ_b!=6MQBX}e1e zFA1GnSe#$=k}|ueIsAn=LwrUl{W`N+l{B@wCF(Ti_8(O3Vs(Xlj$C(6Nv_*LOsWTx zS5|Dh)R@GSp7iA6Q`KEtm4zqD%Fp2KhorvLV=9}igzS^-OiND<-Ua`il$w!|6rYjd zC~z0%7x?9|;8JoNs;6MKak)8kd~+%2fjY)dAC5|xB;hAixvnCYH#geIEzHYv(0=9& zQI{3kUsCtWnN>G2sU*iGg-KNu*@Z5jSqU314^ObYUOazw;4ksJ=%h*4Dey>83wY^# zy8Pb43Wr>24wZkt!)%%Zw-u5wq?fH0p@!vtDp<}fVP!CNGE!3esGA9Gg(Bq1F%LF# z++I0HJ3LgnW{1G%&B@@J$XH6hy`#f_`P}A#UbnBZILFA(u9B2oA`i05?+W&qL&{%l zQjc`?cZZ)^Bf27*Qx^L84!yZR1@6kH2J!g{%M1OL4zt&0cJiczhUSmzJ)gT<)h4Q6 zpz1lR7-dC-x9O`=CeVVN|B0iemW~F^O^Me{!J_>q+g%=q)S;>h9q#s)7&%3y(x0_z z*9e2^M|YkbRIMIvK#$dYW!XGyoFsHtVQw(nf}Q_9=dUQ#kVXnuxlzI>!{aKo-;1r~ zv2Hls*~feWbyl10Syob0~C`U*qPg)t(ACUpS&rxYm)tQZN$g!dIg_Im=R?OO(^V>Q@ zeNyP;o9QhhcFC1<4v)4v41xIvsd7Cf-i%ULjyqV4d&R~lN$bJ`q^gUME0U{cT+P*! z)2e95Bm>Q9;Ms66L12(~bbqo{~zfVyiQH#wAPYR;h=u=aK zlR{2E#z;&xhItG5qU5sfwgvj3`oW9omfp5qTYCpMty^-x-dXDYg4K}Zm^GL)8-hUZ ztUw0xJe|P=u{u^Vz$`D}Vi_556=gnGzAZlz6B3NXq?lwGLGcL4m{~VKl$vr+jy3FJ z4yBOfCu^8n$(4QsWj{Yq4SEW*UFE8gYMtvNPYXS*Li%CBdx*C64@0VxXxqKn%bFTJ zn3Dyzp;kPtV`cDet*%Mvj7cKZfka|Glj>v{WLu`{N}A(Rtpb^lz>_3bq^kkd7%{C7&RNTi z;f49bUHSAnyo{B?+tIot$Hyf)jm&;&@iJ5?E2izE@l^w4Xr#1_o*{h+>r8?q- z?NkAl+_EC?pB$4Vf9gQb%*V7)p20+q%j?d}_MCq#6&im=@0iTQObTgWBG60*oG8-k2Is;9Wlva7L3a?Z(Y7|Vdl)rk*qv)rY z^K!N(Eii*=(CRQHC^=%AOW@RjdO^-mrHP@G2FC$v^3Eu7`wL3w7RunpHW$!8DKRFb zMUPS~x^>HmDRgFS$E*LgO&h5HwpFU?zuT(23O*fNYjF5vow~0~dCFZ`#k@*2mysBo zm=fqs)83Uax|XhJNYPaNW@#F@-?AK9W{Q$gUQ!w?ADQXB90wJGYI4=(NV}nip!PDLtHHim$+3ovVc|187cLN1M~gA&*S&l%Di9l($V zkJ27j$c1~Urd<_0{Ok z(%B%}6Ek9+>2XF(A~UM$%b~ZE<8ix~)m6hlb5JXDUDmB+WH?o))8Q*Ck{2k_M!G$2 zv)dUw%<0UCr6o3>m0W+m!F!s*a^BaNv-H7kT43H-4Y{cNn9VjgbMQo&$ytsx7yW2G z-&mB*v%+A}oNo?Xq3R!~B-Z07t8r8L7oO%|C`Tiso-+@YdyEAZe!h#xj!BMMZixZKY?UcO<9sM0QWijCaU%Jk@%jU&8edma4v( zG?e)nJw&p;$eALd<%v5k@r7<{V;wndap%kq`M)ZYr zhplXjb!KI#KB3gOR=1Y~$#5p8CB>_kYjH72L_tfLUFqk$e9+}bl|B8kDR|Bfk+w07 zs-DV<%{jbA+%6OULnU?1nQZG@S@uc&<@#hY#llaaPQ4G%@g zf7+TDXYX{UBahM;5f!ZtQcupg&8PHH&DTT0)X7NZ8UjrUEr#?-0_97+_n{AH4&=;N zhhC5Q$3VYU`p&^q^-Ru+b@2YjpmBEDW+Lbeb?=>!5Ij)L)<#C~I>1Vr?#$mOs^Vuo z^)gCOuc|_tH?>zPz>u$|h17@P()z1 z30@va-11OLEn`SupXWvP$wOdo+KPA$WffT&zwj(G5pIr+OPTGFF@#xS<*Ad-ke}C= zG$S5rL`F{1KQc!WX8&8Y-m1KlAiNqWp&xF}=reOyKfOwDv)wvhFHY*~;Ov~L_0$s*=taty&K!4y#1K+YR23!no$V?7z;ES%z)HJi+Fwf1G)Ldg=v?TfCkZFG2tumUD z23p1yA(yGTYf_#A^G!Z_UX%y=uf>L~?a6eecXI~IJg+Ux7f#kwkl8Cy>iL-9G3HDX z^Y`Wm(wxLsvsrZ0N~MM!R+!6+Ho2TY16)m8s%l2_4ta4X{RJQGo(vG_lF8Fy-n9AZ zSq=AHQutMwDJ-Fw=9#bMZG|gXwj`C$J7SRZDkA4RYBq=miczXV4S=~~T66tsr*}$5 zT6}C`LSlTJLs}Ky!G<;f)Nt`K#*#0{7%(F_Ei*nMiu#q}Y`c3YODgxRcm8GvO1HOV zJOa|)4(;_sRj6K%l@W1SF-B&5Qha87-%R?%@}R3$Rz1e9LVLx;as)L{4b;?uJ|H!; z8IRAW-petPmKik}Ck9^W<;cu_Fr%aTCaX*goyb$uL+ULLwGHp1bpey>p{t!=DJ9_C z_ZK8UFmI|Pj%o|#kmaH}$a?>+JLK~ICpcFk@5rSP(VNm81ak@?SbGQh z`&Rl&QzBC)){cZEXGV8fYof0zg&AI3Z!aY^B|SbNP(}k2>eiR_o8RE+f)lX3uE~gZ z#yRL1QG-ZYSS3VNXr!MsfV@#BwgmN7I*^m9tEK1k&4QPi9&2=SCMP>1?Cp3IbD!td z2WpB};S2wMFM#rn-1DcC$h-E9#J2Q5T^T)GAf7!>nZ}gro~| zhcdhFE>^9snx~TiX=r+x53F=WtqadeYiFw}`L8Nnj||oI2*xHwk`~TvR9rGMM)Mz- zvQ@)inT}L#kR+_sLQ-TIs+n)ztxHzVvYPUw2KTyEYMF0(JSDs_DP`FV^P$1(%*=FJ zWtQqa#`=#eH7O+n(ITFcL zQ?Cwni!`Y6*jwG>;8n`&5{g|K#mR52fN;o)wC;3Fctx$|+NBkc6b%{4NhT&FGAK~1 zBIw9_i+DZEk@`vHrWrNR57awUg%XkGD5guyKvE_t%lyoJN;lM8c}0K2d~aoCcXG1X zebuF0l?c_fFkj$EZAbRWdVt_}c&u%gYdsuNxk>v`$^SAc&gO-heHn$91uArhrQIOC zrB`Mp*m=793F&=$+oDu6F5GB5lg`$KNLM(yx2)Qe%MYZUT#mhSshUSA`q64Cs_N(@ zJg|O9%`T|yq_@FA!K{}7xa|Q6R&j~EI^{0SzJW~p=*3Gkq}j4`(B;YNt}aa{k$SwP zPZLcf)@|s)Oti$y(nB?wW2l9QytfVv{Q`9_4_Bb$svokFoSZV&@#WaY46604D5qPk z)-JjOO|L3zOlmU7Q?(FHnXiC;62mQ-6AbjC-BMtx7Diq(Maeth9A1_NpMB|P1y)IC8}F#yp`)7^|kX&(urlwEkc| zVe+h4SFT>Cm{Saa^(5-uxNW@UFJM`z40-gb59@TQr!LKsdZx_YDxDNw1JZ3V-?>@G zN_W{Dr&*1Kyg#(%sLE&QVfb83x~Sf$b(Qk8^$u@Gg+o`lt?f&?cfv)KniZXTwNqN6 zJM?CqlP4{a8vIbqC55f0!paS^GeZiQT{~T|QPV})YdNRcZ?fJ|+K!`1cX@LBUQaM} zoy-LBm`ZDCJJ1=LT~^YBJo<8#Ra#&*Q7fuRuQ3RYnH0u%h13rn@w|+Ib&?AV9ou!yH!ngaAZJZWm~nF**DIX1u4la6=&jr zh07)KdOM$f39rfYpuj3)bVp-DYD~3)s5CIVbFfs(%d!(j$>((Mx#*#R!GbPZWbsmpVexbkhP}-8#vi`HUwafr|3$t72<;f^Dc+OyB zM&Xt2h^k=n$~?U6q8DLy+*DDjvMkuv?e&?<;bdCI8WHJ7TfL|@i-?qUHFyk{$vNw; z0@GRab9A<;F0I_TeZ9U^fOLd-ZO7SyQwVgxWmZG4|Fm@hf|)Ppwf(`WFm2=R;N@hc zrpF}Gth*}g6Yb`LbzOTfCbCVw$r}h+>B_L4NlYfI<#i4vD6ovfcIxC5rnZ^%59uq~ zW+Ic*BAs!zPLDG!{@mkPLf|us$|`IN)@3>;Bt0{t?G0h?=#XyMFiH=dS=NdK)(Ej$ zK$d>XJer{vBihR!twTubrK-P>#!L0I%}ylmC(Ku0Azx8Bp_(1u5ZR_!bs4cH9IbXr zvPg}ca9lolhJmWq6^D!>S}RK#4$&az## zl$~jkJU4Tia-ccjlBF^weo6AqDz8A6D2FNv&-n-ds#Hd z>q2wMKkEsY#L-KLeb&lb881nR^p-Q+v`;$7te~7+7UM8qI7}~Hv2xaYR(WA;zWENM z2rszhbXMA_DPF1b^eY2iUaA%-Ebkh)f_ShS*(W!Zgr|5Rm1l&n}}f?Bmi zfz~AS3e5br&vckWEt$X%xm5EJ4Jk}nY32(r{Wiv4va{0K1}}zzskuOgr-5E0KPkv{ z7t^57!6>0T^K$}OIacWN@tX$wxA+xMLCG+gcU9%b80PX8%Q7daMQm-h)ROXcj!X@H zJ5IepHrE$XUigVfATL$o2WBsd)DL0KQ|FjNd;0IZ8s&d0Ra)q0K#l1`o*GpPNxC{b}{SkVI|%nF14OR)~>KZ zwXCS9(r^Vr79*(tCQ5UKpR6>>Gk;B0#?mlzDK?kDa%wkg9RtG@b>(KGrlxJ=bucfg zc~ySCm%^cUW0dd{i$FDR&NGnuk`h+x=~ql4DJWHydeLfMCh17eNe#SPHW#6)S612T zUR0;sO1aq7)SeDcsVsmkA~Lt(Vld5eM&{h?&zpUy>2;U7`L&Nc6~P>cN#-45q0}}; zQ4y_5a6y1AO(LWlZbcnzm8I`WVHwK!jFCHQrfi8W9a>dF8ReOakks;1^R*fE8f$O@ z?YUXAnZ1VKyYh2>`VgGD)U|3LU&%L_siv6u{8Uh8CqXJ?msc-2WH~>rFe7EN`~@C{ zz;bp;un51aRArbw!OY4y$6sOf%z1$sWyJL3&8L+bQiPdxqKBaBu{=+?`62LYF^BvD zM@_?6-(Z~wZwGtofu+=xf!9Y;K%~?J9|7x2R?jTi**7tR{+Yb&>Z*4EE2>;iviyTfXhRo_Unilj;>txEa`vSL-%I z5|y9DFqLNhZZOxa9(9+ew16R!KUaRh$I4sUHmNLJb7mSC&Qh!Ez>V?agLfz7?7y zRbQ)`k*H}Bo-e)r{QOIpl9SScv6%HqMhw5YFl;5wzT4KhvhR+vdSzw`%UFm;fSfX4 zJy|!B%#WTO+1`>NbbY7=hu9)#)ka8)sD8T|RI!TQoUzmuk1RHcVcgv_`1OP&Dwx3I zAKV-KZMB)X!RtuP;;kKT?DTSEF9R-F2kR?v$&(T~W;1`^m=vFoX$_!V-XV0fRMSEA zK^Xi|hnoFvWUUY3Z;tZP$k0{TjD;#F&4Jd&zLLbcMD>8HpU;I9VKvf_df}YCs#*+= zT=mjdd0f;lEUh!g%KJ1)>+|;L&3j=K5v-X5FGmXalP@%7cpsBLC?zNhw{po4_X}6e}qUw=RlRYV=PsU2+l9C~=0wxn3((m)IAlcw2V~qc79Zma7 zVYwF7Rt1^|8Ky}8Rpt|N-Sp^*NG63P;I}5$Usxq@&aW{DrcTe)*>4+^~(#TV42M9!O1gwrVWU;t8e6pqk)j9xca?89hNj_b}nNw|nN#HXpOooh=Wf|Q0 zN-qts8Yigtywdvf5U92OaRR11;^~_}^#-~%^WW@I}YodZe z-f`p<@FPx{ACO55*43C@W%-esbOo&M#?qyhv<(z zg$X2w`6`D<%w_T{Y74BCmxzNewe0H%RM`lOUF-|wtr&Y{rU&Nd0+m4Uy^s9%T>tvP zIzFR!O1d*6Q$LkbeW=G#|6r7Kw*59Qq^1ijSdfuKsdTYitTVUG#HpM+Pxns-z-9bv z4E*Aj)g$KGKdV>;`zh8HN^=mC#LB;Zj^GP_S%fXW%AnR{>5=rB0uO*~tz$w`rYawy zrAIwSu`*f38g$ZG%9rgb1KkmG4%whQ^TUFoa*B>MsVQHudgQ88XkDr-z=^bXwWFfR z4C~Jc>CUu_(7Ki$p=~H9zn0WZy^OBZe3kse7iL~o{VFqW=d_2?{Zs9sswoZWRa)`K zWmV}6@WWD;lbrj6ne!jR7zLJ<2ih8IN?5HYvYj#}xX5~_bhViK4c>$~=|&nbK`pas zvbwJk4

Xby)AqbOrNJ@h@i zCOM@a#L^ZqZAnO;ftlJt+k2xdti+4o+grqAUkR$ zpS49({E&@`zJ$ZZf;lC7Go#d-T4SdFwcNJNZo(Kg%wt=U#b$)i{SyY>t|c-y$`f>G z0kSiOx}B3Evt*)G3_XURtQ;ex-nr(uiz4Y>6bmXV+=0*4<&iB(c7}qeZ|{w`%Fd2! zjUSqK0&^hQ(qMWS&mb)`qn3tcSb3>!>5*~Tw>{sO58e79PacS6ynHV9hl`5VQL`M+ zoMLO8JcsK#lc%+`k|?P+-9I--<2kKGvMJHowx}P+VB)nV+tYifExknVphlj1i<;Vu z<*78$l9Hqc=tWoMGBuw_(DlZRpv)q(%n0c{Lc>J`q+g5ymC`%8OZH-vF?(~Rp2Aej z^>?#76&4P&#^yZvp|vz!9rOY%r-K}gbk1-e9}GEqK}@PL?Hy>Wop`9v%=>V;tEp2= zre;$k%?cP)of?yDwl+P5SGJBCXwLg~Qb?E303Fwv&RVUlb!adRvYP2v;7xM%42i0Q zx9vuD(O^7=0T6o!(Gsz?Xc|zzRZ(3JGg%KYamV%oXCsbN)n#p9s%)Q<$NSJsogKbj zosuFeE6y);_AM^wbIgrBcq|%|b+-vILtya7{srs>LKa|dDyoO1Mei8F)CXbcb|77r zSFQX*vRheXxWL3iECr(2$Ob&w+Tzo2ToYwd`TJ%ZI{UqKThnoI<<`jpJ#m$V73y5s zVq2AFD<(`SCe*d1+LkHZoM}(815M7#0}|Nx#7aTc&slFX?};(Hg0SYBl;C_=Bn!*Y zQK1YM<1ydl=e)7(p`UAz%F@$C?M_eU4xQ7nKC9TsBL>}q>%jN+xf zhm;CnQ|a|)Bympcl1$}}j_RNKC9g~1(K%zf>gwshvwYG%v<@N4s&CMYRfri-Uom47 z9;UVywbuEjG%~3GcFaG6aXgk<%fXDfKFGHw9gRI5&CH;)ASI_3luwczB zotvJYuD=yyb?dB@J+C|+kD=RR>Q{REgCMIDhj99nUeH2Gh?tOD_idCF9 zOLrz5i`;pLSc?DG#4}O5sB?%H`<@Ja@?z z-oqI1U6-YWB_;D?Wff?b{U-ZjxX`u(7%t*T?}w3nyI9}H)5_ShfH7CpD_MYaJ(W(Z zpvpHVj>ml)iVCXw4fJ?ody4ars2MG7m*s&CfXx{spb4>(uwV zR}XK-TBFmAy={CifUhZ)S7m3KDK%DukR|3OXXNnh)bJ@1SpM_9(!|Y^`~u{4d{!|Y z^+&mJ3WdfY^YwCV*jS?VOQR}@;_Kz7JA>u63jgcW+yK0OFdwsA@;)8ST zv@8kpJ3WDWue?P8 z7Coo_$PC6WNA@yd`DR0R^HsZ}bdh=ZjJy@almL}GcTD_iw@!pGvnPAV4 z#-g))Pcc+t0-|@+C(IK|(w}0`ai4>ftVpg|Fmx7Uhk-K$8=b4)7#y#xHuX;Hi7-{V zxl=K#49k?I-U(d?F%k21H{M09DC(ywoHBK1U>M`;tv>K0hZj)1SIog=Khz zj+#_0_J%igV_%W8n$&N@nz8y~>sT+|fMj00*v~2;J9YJgPr5po$KmAp0GWNcNyMPw zt&*YPI!{>kHh0Op7A`UyxP|>S8rlY^}i;3sP;}EW`>6oNpJ8&8fBCeRfVM?a{;ts zym`s7NBZ+o&r>knfw9M^a8MUa6#8p)vQ-^R$MDCvO&)w|3^IjV@Vb zSFH%H3|$cpzH6eoYo@$0T>p0BJ$ZN!q`YL@{pnZnP3l_SD&zkoG#JAs=LmanCuwbd zl766JQY|(LOfn;FO>Hgq0$P*Ai8-Sm2ldHfvBLFsbE|eIACtrZ@1itG3?(=x0ZmFI z%Y4pv#LAh}UbmXKC!66&`+ zzh_NqYwvEDggM}8sNb;j`#d(v>!d~4;N0P6;Qz!leQ%OIX`hX*0~8Mooji%V{v=_5$3JUax6c`9llGPl#Vx% zj_p%SI?xo{bjZ7|oqKR-eXtby=|swRtrW-pd|7*Hz|ChlFSkfK@rq~dpX8PPU4qY9 zNPzsMlNW*#u9L(qS6J4=ye3HJaUzCK($<`Cm*Lp&-@+>o@1J~j!0+Fk zKL5~!UH?|ozX%gDdWE@$)B5M++3k>=W4VwHcVCD{{5jX|hwL27rQsX!B6c^EyldNW z%^$xfeEE!`cH{Rnj{W{^+GtsC9;V!$=;z3Ys?(We{m;&_>8Ki<8IK0 zrfrEE`8nFt1fN$+U=Nt-s#cu8S%(D7$V>-^uCnUu`$xjK>?_c~&d_ur?qvIc(CH?&8 zL)K^C`!Cu_A&dV`Dvc}sjdkA*w%c1e*L@8cr) zEPnZDPr#9_M+fhet!sc^mJ;-SHd27^qU)dNM@Jz4=RtCGACc=J&p<(oo+GmKWAb$- z(N#oV1=-O-MBW71`5h4)YTfM!pybAr_;Yj-aWCy!eo~)?AwN-#^sytSA>SpJq%O<# zlORv>$ul6I3mG3N*VoG-H{n>yUEH4!xev$bl-nS0!EqktZpg?6UB2R8zC5=Dc_HN~ z@>P)2kyc0EAnx&d7=Odi!{44Hr&;&P{cxYIuMe~yg}l=zzX*9R z8K={jiG`+;k zlCr#LNusQ%sG_hkQ5nrEDNMKl^xOLDglnShTgN-x1v69RcO!5ImedY^hkHTap(CF3 zB?I3s87CZ^G9O|vUtKW1i_zH}nKeRltXJ6?3-=jva{v>f>=)G`a)|%|9B!HJ&@Upm zF*(e~CUDJpQh|ru)8gFZD>pGwnu)e^QJV;zN7T}>Ish@^8)Uxzu0o30yV{4vTz_dg4AO<&dXdtuK$26A%93- zNG>O34lC|&B)5_ekWY|*CI3!-MxuMw_YWbDBTplzle5Y5Nc|~Hgu9ILDsm%vJ9$63 zi+q9nJNW_mC26BilJpEC6J#$b-$T^tC4WZ#lDvbwn|y%$Kk^UcN92FWLFgaF-($!L zWQ@FkY$kiii^3A(xUrBCjCV zkk^qnkT;XJlD{HlCrHGmvSjv~jA zr;wTCRB}3*N9u23!oO0=mE?KkLb8!;Av?)sf38=MWAhN0P^pCz2D%Ddd@C zl$6g#ia%v!6?r~cPc9}q$>n4pxr)4&yn(!h{3ZEo@*Z*r`53vI{4@C?`3CuS@&ocS z@@q1nm_MX^cvRANG&z<$nam=mkx{akoI}nhYshAD3AvoSjFbGkO$P8yADw=37hi#J>)~=e~=%L zpORma{~?3014}xGkVlcnl4Hq}$kWIiGD^-QV`K#>-%}F*6J!IqnCv7kCFOfc;{IxK zJ$WPfbMiN&{u(9R|Bmt_B9l@;_t{YaBX%$fL+($+6@~~fI&^-H<3JxJeQnLHjzuomE>*YedIgjC*(Ke z08G>+oKfUSwF9F7grbS@I3?L-K1f6^1_vcO*HUoJtmvRb(UCORgk0 zl3U3K$=&43eT{X7Vob5%O8`4e~?sYcdsPU7ZecJb5}>>&Hdb>tRuJGqnGL+&LHkg|xO!za_pOmYSpCl`_(WFNVX+(K?AcanR^ zz2pH>468bPGM&sMXOMAnA=yFpk?Y7U>>&Hdb>tRu zJGqnGL+&LHkg`~(!za_pOmYSpCl`_(WFNVX+(K?AcanR^z2pJXN@w_FI+;n%Amijh zvV-g+*O6Pu?c`2!54o2-K$ea*;s21lkX%J>ByT70CwGxAknfNO$nVLt6O8|3$cf}x zEyX&HQ7jZlk3QzlXsH8C*LLiMFu9Aa8Dzr zle5WXD9?atgyICzI!pWn_YECod(hBR7+GlaG z+vKO@_vDaC44<4#obB%l?IhLGEo=xICzPi7vBbShuk~fjJ zlY7WF$oI)F$zju&4)Qc|IysXpC#%VNvXks1uOoj-ZYA$0|3K~`|3-dHenY07Y2r14 z97kr8GsseM0eK<0j9f)tPi`iEOa34E4EYNA9{B}npJn261UZ(>B+nsB$@9q;@?!ET z@+NW{`8#qq`4agqId!@TKT5{PACk@FQgQ|P6Y^H_Zt@ZGS@IR~UGiU~YzmU`F^wEe zoc#a8w7@1B^CeJ2g?K!{8_BKYgXC`VWpW?+ z6&aby@X7JyRI-SyA{)tGawWNu+)6%3?j~O*_mN+bky#9%98XRqi^wXnk?bW`k{ijb z_hu;_BAA{)tGawWNu+)6%3?j~O*_mN+bk#iY7Ii8$K z7LiqCBiT!?BsY><$p^{Z%@W+!=$s)3fY$SWhmE=ZpEBPR~n|ztvM}9>{VoWzVo}5Y+kyT_P*-Ne@H72b@X7JyRI-R{AbZFa*Rj&D>77J;&lX>PEI1HljoB2$tH3sxstqryp6n%`~&$sxtIKu{4Y7U z(!^&pc`A7(Sxhb>d&w2#2J)BWz2xKM9`bGSpX7Jspt&aeW64v@3OP^+e%#{~Mm)E`-1L zlMnIwAIax={w4A?A=3FzULSgak;jlH2vL3$DNiGd$l1I;m-2a(>nSfGdwIT(@(Rk= zQQkoL=ag@!e2)<6d4PO~*Pr9{0SObo6NN~}6f#N{@p?iy0Q)zE@UKOP{JTVm`&N+G zlADBZcZ(42?&SFg$VbVig>d(*5boaO`S-|wk_Uxw_pK1_1}y{;?os4%+$|8oT?^0mkUu6@3*m095bkc_`P<36$Q?qsdsql}PxJiqe6Ga#)Qye;j!hc>&o$ZX$P*enU$0?<5~3 z_mKZ0zZYg=KVO{*f21%Q&rnjHEIi$^iYd<%PPOnx1>?R=IKi^6rF^sSB+I&;^1Z^7 zQ9mfZCOpBi{z3VGFvGIGp`20=c^vv3A@cb+;fa=YHs#sE@s>50a;@+*%UVRaTR6$G zuA_X5a5Bo3@-xCLgirZ1;S@Z7(f}g7;ldotI-PQ!@C>|8fpVqr6g&$}d9myeRYxX?8UtMu9eaMwp!H=w+AC0`Gd%QK|!HJQ_|DHPF!!<8G{)xKcyY%ic zSL_T-d;HRUSBJ)}fqyfHU-3j}$1QjT#s!J?WblAl~-!OU-5E>c=pk+KN`Hw|GVPjiB}hl z%UrWy+~_skl(jGJ(E%ed)lE*UrO>RenY*#9lOxJ(`qverx=x29lRD$dRTL;8xG z+kFk(;mjaVuB5^zb9KeeWs}7D)s^FN*9678HHFri16Lz7WM?|EbsR#QaK#f7cQIXX zllzp!-+HQ01MUhwde#aI3!IpC;2CDlA^9!NzU4_{dy^=Wv`` z(NtWAI?Taz2v5XeS|Ct-qLXs5s%C9L}c~x5E*}Ym?nJ^vP+Va?B!VRrgH{K{7=x?5XKXQ{ww0Y zb;BvnbLyeM+sC7wFGH>Uc%m+HYZY5)P@Y5#rOt$2XxVR}N59l=mz(XU|Mv9%<(LL>Nq$H1ycqglu#(;_+vCyA=#loI$B|znD#6@q5K!dj={UUR9vp^3;ekkcqznT^@Y_`jcDv{7qGX@7 z0f(VMAscClbjtBx<>G*oarcJskifst6xIG?5&5BkmADYhu+&gg`|weLC$$(-*H3^r zf?}#V4e1Gwq&P_31`oocC=OLykVoO8DGpbo(YuF_p*TwII~wA#6i2Ib#z7oSFX*_WPY7h%66Z|ysN6d)Fjb2=suS4|9?ulzs#j4~ z;ZrD1SHH)w7@io|suMUveI)m01|L&TE6c%(C! zQLhR|Lo8*So75)B_IRLNhudNetU-$i-#_S-6m%ou-%G3p7iZwq|Ct=I23LxA51R}L z4VGQw;hm<0Q?1m{*C@8sP!_^UlUgUq86p)!&PtuoXKS6aC*f=pgrVYg&@$v#YUIR? zI57-wVMMKD%^8MIm0FRLj1;mW;xICy74D80nv(u^aIidWmU5zajG8w1I}~EdssGYa zXz+R@F(q4`(+p;$4!#cgo^qz~YmjwhK<*Kj!*`ijig!o7hvPtMNNUc|gE$en5j8C3 ztXpvyT$GO5K4AK;Fq*+fXx5k7DGJW*|DwnOc3=#g*tv*+ZSO>0hU}pk$RaxxSrV~F zBMVaO73e`y?Kaf^0rp>TtnATf*aPjm;eL?)5d0i$A2lACWj_ethS*YcL+wtq(P6fN z4@cN1pbZ{rr{Mo^y97QQW#0w8XN0{9|3}*0N1*4m$HTXy?Y;2l7<&wg^H^K9SdX@4 zvmb!V6YXd4f4qGgGVdf? zwmeU;-#{BY*CbVY0muokXTR9x=(X*G4QW z+g^wBQ*7B%m18%ecuu$1B34uF*{Gan*jFI7x%N2tGtDl+U1!>(p?IBT??W7>+h2$A zaI+mn49~XbR=CNwMLn2eSEKgl*w3N@o^Gcjl&SV_kfJl}3z6fw z_VFmdY4%vSIn(Y$v7coZqL8QCGvVhCY}v1WwmktAhT~%f1NpEnwvgOg}=Pg@iA1|QzQ4{`(ks7gn(X!)6>`Rs{ zPdUA8*|QPCD;OUUmsc(OpC?<^YnFW`?t9&`e}s6xVcGX0*f%Zv6BNr^mi-OzH+YR$ zzirunM6T?$>@yITcPx7^YTMr}`*URcKP&zu3=QF*mc0%!`_!_3fLI@Z(t{8_LkMvB zFT@)6eU9!3_yT!`V)+u+&_uqn>>-f;ZP}NjWDX(=aPn)E1M0*#mMt6p{$tsfz_V{H zJBVa{XW6Z|;lGw01-`fJ_mBmB0ed6TcUi!`0wsHS!2TY|ydq$C;M$b|`vCl05wH{R zWhJg5o~r`(_){!vb-;cES-u7u5z=>6z?PS!Tph5N;@aAPU5%W-CSd;?_2k-sEe~^F z7qEYT+O#fUUxZv*AFxLv*4GE@|AUjhzK}fv!CwZBMhRXH{#fDxEx5fgz2lxrf z@g{IGD!@;{C`#*Qa4^cSZ)eDEhQF7AuOlD(_J-_EsXgF#D9*mVu)PcAcNv(88h1H( zAIk3vunhP0Z3){8A5nK&^j&fTA zMp3?3fp_A*tHGmC-`9eVAiu5wA3_7Y790Z)uLB!!eI0lo>eYJiPUPS9;3SmWPrw|w z+W2CwBZvyuK=z~_;!pMmmHou7ky zaQ|j-I^wehT!W@`EBN#P%lZX~WLdui$DllJ1OJ9_ZU=8dK5Yf3!=GP)AEC8v1AmBe zxdWVn`2QOG2I2n(d=A&|1oLp;Z^357<1Vlb_umbsBc$zM3&Ot#yczZSUhwV=7;V6p zQBHk(kuH?;W#DL(`{m#yDL?Qvr29&6HtNR;Fo^iB1W!PHUIlJLy!-kh_VweWoFn#l zq_?jx)f!QW0uHI(z;6*zdm>_Usr@L*481yH5U_7Te1i5bP-|_w5_K_T{~v08*cwra z0tl%+fw$$pS8%<W#n{IIyb`|A0Le ztuJU}q6vS`K?@JtUC4)s{S(A4#a@e$QtcYVX@E82y9sjlzCf|ueLhA2bYBQHX#W{0 z3fcD{jIh1xMBHtScumLcpMh24_A{g$qXe!8?CGeTLHmy=gOGh4q7$}bDF29kC(ftX zW09B0kqwAcNPQjnt=xSgg0<|a$Px5~@F{3-MR<6P*D8s$3I{(DS6wJ2%Wl$XIu6%^ zb~fsdZKokkA$tzWI&2?-G)3$;(Ed`a0TU6Op=xOGbTkun4SZL_f-B*N%-pU+l++Ov zL+Um7q>iMRs=5)L8m?~)W(=~RHLpapM~a8)C>@&tOHfXu)USi<;rXcMdP{A0{mw^J z)bCusN1g_8hwFD5id;RW?-Re%-a?Fi1yA&(BB=idtdZiq+8LaM3j@|8;WN~q?H=UW zs1AHfSiNHJH|ZEvFXCGiQ`H$rzxtbY8O#`}UPsobw{4T?;p#S2Bej>}CtiW1c^`-x z9C`+qBylrP4u{!twz!lSDgXOF(UfLsz~nptg8vwllT`)SD(dkA?Sk#+?C`>-TSaKn+3f;NE|K zK)s9}1oBwzen&u^W8!m?mLGRlN{1KneaIT>}O1;F(fj1)($IM60Z@1OR(0%DR*)ReBM(bm#q>tk!bpoqlNL_+3 z)F~8GO_R%_I7sb9|EA8OI8>EOD=MHkTz!JBPR(K68Kv%!_F2xWqtz#p!3#oSTafCn zJDo;eouG85s^J=bo6hn;qN$4A-E|@W0 zDM{caUY()(q!YY}VuAWz>cy6jOh$tlvy?n@p|>i5UYNizCs}z^171GzfL$5AT6%xsJ^;J8gFQE2F%Xpvil>zl5iS?(HR|nL3 zDVNVegOJ5`##*!lR1fvJZnk#Dx`4VEBdq$8?l%M!Lc_E>e42KTmRc&g9|=o+wlmOD zFPAJ#p^TRLqQo|pGFqyV93Ma#Ep?JqB1IW3^$2O{11Y1W=1DCbL>Vo0iNt3xWwcZ% zC>ZQ0qowL@=h(1mi8}+TSgOOA@Dv?iwA_oNn2rmh_eFf)4XBMW$Q&Qm)}xI50kuHl zGbwzbzW#AQohR`>o&Fy{`o=?!QT`&J-k17SN%>$vJt_H7OZnS?ngx$kTUZJnTUn`jtU7PU`lm@C7=4tAi>o4P#xnN6Tx2YP6KkCc0l2R8wT=|2gFiLG_x{l`WJv z1=TzW?+(hh1XWP{-yVKar)Nu09VOxKpnO|U{Z8EPWc;=T)n=)vf1rG4P)*N(yo>&A z530xH`X9p=>-gOtRR58l?oYhFBdDfH{=N_vE1sS4a8PZPf%r9E-x*Xdi@cZe6G1gX z^6!1hPY2b9Qoj2c{JGZU#a6dUdUjIYf=RN-PgB0lHUsZ-5gB+f zQsTPQpO<<4XhD{WpS6{e{CJo09$Pg^`}mOZi?%A4^cT5ma)giT5`urBkYeVWLDW6Wt z>q5#BrDs{nF5R9sgw#Q~ekM% zb&Kj9$~!}9z2wh+%1?xpyrxQhn)15#|LKt0D)sLxUVk>E{w?>1QceG~C!|)(U^Fn* zl;?{fHAcp{BPhQL|4{MO(Uji|sqdtHrc>SJ*9p4U{*8)l*WQKcl=UthP${w^P0) ztnQKe;>cUV>ZcO^oxFZqSRIt~-$!{{SlxvH)bABw(;q@J16_xSs70M5X)dNzW|3-OdSY=B5-%HhV`HUyR>S8JHk10PLR@w&D&8B=Htd#U8(-__tVfCHlca+x;hLyYyNflH6HmsVZ z|Bh4ci>Uol9t$X68Bur0_)|xDbws@&`Ew!VwGs6viEk(6brE$y>dSJ<8zSmPX+M`z z-V{-l5y-13-x5*FCA@1XZ;7bKB!4$hzAd6I6aC|-l($9H$x^ZT`%GNit_e| zdQs}nZzwh1}kthknB`3UpaG#GBkC`5>4V5`us@ARb=aO{7#cLb{Qk=xD)iqt>E0)CN@mAH*1uBaQq9)vU$g z>Osk)jl4Qa6-g7kQEkvyN2>#fh`NPdrK?+|!u?FgNLyN@z5GIn2`rc~K^02%`=z>5 zixX9ml=f|EBPxZg=AR|u-oX^)sGZXH|62V{JI+P?ApS=EL5tJX9=Z2UCC0p9#th_( zg`kcO$V|lKsnnsQoIC=T^a6K24)i?vcq}kWhKu@SZjvMTWpY~F9UTzeJLzIQPNat9 z<0nT3WY#IsHxA?omu>-u%9Yg6W!mk3ar&6AQ8hvsAqUFfs(vleA3IP&m(rRhTvgzF2pk#bGBg_J;u4qk!lwcELGQz63MCCs>6)@5 zxu!gpR8w}lHAT;^|E$dHdXOpYzp}K4n$mtr`x?v`ZtRlpsqb`|j8gJ07WFTRqm7yJ zJJzFgQwJl=fpLiFDQ+76?WRE=NkY8V0hiyoE~O!RsZA>GzrxW-F>k0Vl{6xgJ!i`e z@(2T=emxrbsc%pl5=qM6Wo;=YKL%iKx(`b&QEci z8oC$%hl=8!8hS(yrRY;bPs^bg98yDnmBalwYhoi^xrvQF5-SfJ9TZ2O>%&)Zn0BGK zN3GHI`Frb_8_|Jh!eW*7`FNyUPv2*xNlc}d*+HC(rd@cFu4QVU3_f{j5~Oqr&r7|` zr#MudFYT?6;wWQ-oT)8UVxrL|xj7Wa8Ixo=9ZxWp+zN`B>R!=Ot0?BG1qffwqc}r- zE;>Xty_%&KAvNlU6id{TXf|p=T8EBvTn(42=Tq!ZqmV1=0xfF$gf;^&)HmB1uoqw- zAI5VXl$`;4fu8>~@jC1SbrQ1+c|Ys}+VI-R>w9VGTS^)B0c{LkP5)pYct!M&4ZIF} zz!Ir%zoZO%z@H>-_fUpCKwAPIqzrq&IWnJkgyHuEjVbyM^dIx{D?+&b6yZGI5hZ|^Q94VDeJ)I`?PltMob1lR=EN`zF zF8|E;ll#!~4qk--2Oe*v)WMUW&J0YK zHiltxuqNS8Rv*K3fMk^|{ap&JTBb+CJJR`yDMh(EDb zjqbt~DKdmQ<^hRbo^+QI>MSVFfqW^b;QG`tRnP+h`BGxR^@B|O3QYWln)nsy^sgU& zyd@5z;=#WqJP(`?j(29kIc= z-{MRlF!XI8P11D)ZaG1U$O>3v<0s(kXz>M3WWV~@<(QGBm1LPSa?}3~kO7?Ub8Gx- zKg7SwJU1Eh(1!%7jz_)*!bk;v^3jH%CHWr+{3mTN{s(Z3_*sFL=GvNG{Xt4=a!*(1 zoKJ3^k~{S@d`hop*=dW~dL}QbtD7ue$n%}j-zs;!vL;Q| zf%J4Yw^&L0-cbyer9X`~sR{AJ=P~QCa}~#kHIC~W8gYzTjoX{s&1rlP79V`9X@L~R zh4w|}pr%)RH^=xmNMoz`0tZYQ1ccOKcH8S?35s6IhxXdrjC%y%TGQQR1gv>Vg|O@~ zfyPIFaMp~oCd>Bh*|RsN&Rc(rJ-k~^&9^VCKKtU?smJ%M-`snaJ)qmZu-hJ;TK$9K z)E{IOZBIS>%*@oCn|tkLslVUc6O16|;UOY+$PcBZe|t#>SC1aIOOEBfpw%5R)W@k3 zJ1JnCA0&*J%G@E`=Pl*0%^R_MFM#<@!?AW+7vwX+m4y z;)F(@;Y$A`zykaQt<25BAL1`y#V-IPa2z^e;m`>OhZ4-q#(_Y3E}RueKsI&Z3M{Fzt`mBTXp1uS_m*;;E31=s1rx$A+g=Ik~=vI}nUU;p;v|3C02B`s`1 zapO2s*kO)CLg^soJe=s?cldui&e@X7a!`Z6fHkif5Vts_OY204C+kyjL4`i75{E0y zq2q8G4uV>^=@e|hLj`rdwA0w!=6uz*p{?FpiOasnS@bP$;ZE;njK}!sbPONMuBpVA zFm*n=-&vL1NXUn26W!Jh=Xh!kq!%EeMdsr0EpwPP703I{v34R|au417m&e-C03=2( zOv%O_GSrEnZ;|b>UCkHa`|_4-F-{bhCGZi?#Smp|60x-F8_rHHkMbYiKEI??h)}$s9Moy}qHYxWE#{x}v7Fqosit z#n2V4Drm-cnmg+)F)P3u`A~Pfvl-ElFMx|}fhQ~RozO0Pp*z0`-w&Wqv?^ZH zR)J4Q>rE7%B)bVjs$1O9ZOJUd6=V%JT2<7EZ=mWWUguaQJQ5>hLw-9xbhWJ8lG#qb zQ!-`dDNANw(W+VVqIGo*EtX6_C6JZ|d}LaD=xlG%^9(wV>%QIbT2#BkUJ$J@>4GK0 zWbzqNgtT{#Z=#_joj^UaFjZj%M{)BfEzSA4U#X793%zf6SCy6L6<1iD-5rTKe0sQ6 zKIm$`#MQO9xdZjEUB2Vof|7MAey#Z!we#U--{+~_5cuhC)@ko_c@!U^cg12dFe5KmztV=BETGG?p)g*__ZTJX%O-rJ#qh*=ZRoBqgP}d~itxYtd_O*8+ z$5YPV3M+B*~S@pkvC((-}ztjsvRSl{V<5WBm}z1shS*KVxi z_^zcZ#LB7?m4(%nhki%fbyA+4m1#kD(Sawr+glpYWa=8Eh|5Y6@>S`)%A7MY^JaR! z&YD|PgxKk(-i2?pC!|l4Dv{I*5BWN_=uGSdJ-?y_@@e_PXrek=L4Ctb5LSUNNhzyt1&=s_$NuKtVSnPx$RO z`8<4GdqZQR=Tl{IAskm%6wawCE+{NR*+{Xw1yY3qskY45!#f&Uq&BxScQ5xG#Ns*8 zk_t=r!B)evhPs~ahHR^|p^@JW$0yYBb#T~SG;=O`~0w-RXQ$YApkd-GlO z#`YfFE((e(@}uPirlxjuHuu6Y+H_reOHXSXYh`75eqwHEMZ7S-xTv_$R~@6Va;dIf zN$J)YLrK=b`);dgX^nLEkjxkXT|NP2zRRl9Ll?hZucs^cn*1WxEB#e^H<86fMTxxm zm4)SVOS2@T4GpI-QC3;uM?fceCFQuwgO$HbY#BHnmO+}DX1#&^2R+IudGJ8`i;`w zRkXXg**WNooCrnBXXg1euJ(?aC3xW5%NlS?T&6i{=;ln(3^9SXClEv*IurR$5q6GCx*UQCM!(Eb+c`>H0K# zCdTZJuH^|Rhfby;&rB)Sws+Q}8W)|C zKGncGc}N$8k*$0R2DY{Y6jo{NvBHAlXrgj{yf6{1tc>Q*iWQb(d~ROU)=;00Hq&WI zV?|#lU8|$0H$hLRHBsvFG;Bm}R(TovrjoM!L}eL9#3Em>6hqMz&dl+vFwQAoES*yl z$CkS8&K9e_hs|7f8i-9R29&NY=)Vc0ctI8ItdSy3BsV!da{AgUQH&oVXHbg120(`;yg3e()#)$Ii|3oj<{q*#UaEX!hf zNgYK?ShU>I3Tth9cXxX$#=pA7U5O5qvmPK!wmnBDKez5xS8r zDk;wQ?yt)8axf<|GwK_UQL|iCQZ%+!%%KvxzKeF3-f2W zX+cMvljH9QORKW7ty(<|g?hB8&6hSAz)b>Vtnf4&Q7$-db<7@xrX^9Phd)d{lk)`~hQ7 z%_7sxbzj-h?aTaFd`h%nuGQR?XzlT7r!y;JZUoTXnY@CE)!NYA)b1N}V=+@6P;C=S z>YM#)={$@>C@=pkhNaYASJ#6ctPWKe-xaQDrJk8c(v;>D#IkW6_DE6I@D=3xx&%6o zx@PG)pla!|s%=OfWuiLg+|nqF=1;MjTeQyH+F@bJr*#|z+S1bO)5=88s4Ofg)KeQL z-%&-7tLUszilXLV8iSqk9nd|H3{$OrPEVhDI)+tt56Ul@}Iyh3P4b6|r;C|FZWp-MQ<(RzqZXO~gy0rO|Q=Q;JrjQ((|uBC0x4 zAc}k)^1;1LdYU+fRCEHEWS~Rlc-Fs=F`7=5v|)~U5$bhYdo%Q)uBMs}8TCx7HGW{u zX|i~U%yp8wL|2b08biBiw7&aH6?CI2 zT6l3uUQ#=bdRa}ck^4rorn$gOWO0OVV>ASa}%CventT|FMO={XZ&}PuCd+K~c zT6AuCG#dj%8-|6>ZkRNjx+cAY^c^y!S&oUt^EST_eVu9kUSBWXX!ou=)MFVRyBaW@ zW3nurzmqTX=gt@1(@Qtp`ua*;2en?>fhN$eRcU?4Y4M&9(W(kD#A4|Kmd%=4DQ=S_ z&zd5It*1b4JgN%f(YcALe9!hUvphOq+XdWYV61kVx2_cKmEuy&rqHzKo3T7eQS(n; za`Rwts)zCPP@ObBGlmA`>CgR?t=X}vd}p>PO(&_Jh{b)%X)Nx`O$;BtjKSP;o}OEZ zj;jrJuoKAK%hj`_%DSnNF}d1Wq8lY94h{Imd|iXIX%jcch{QH2gKtrOzLn6!SyCJd zXJ+@SkfuRa&Wc0*Y;9ehs3B`fp9Wr0S~gGXz7g;yedzExeA60X;kerDziU!b&}4SrEKZmT_&^gD}84w%Q1BN)C?IZ zip5`7`*dSCFXo>TK=Q>ElCORg6~U!+fo|<^47{#q(UK@i7#10)FR0bsc`Xc^zSwCS zU$meaUAgJ)@%E8g*rYsfw2S%CSag=J+tOWL()2eTE%EiX1(g-7Yvs|>nS}{y|Cq0| zAuAV2)l9fk88;wtl4a_i(e|Vp>A^V57-3G?D*6L0INB=j-mE*H>>U53xGE+_F-$vr zDlk6up&OBF#c(|+k0!Ema+2)Ao=FQ$t)bIXGm#LCJk(;GS}T*HoE%Kd{e!Tn4ms5^ zYiV@(i(ZUU6yF918{#)H;|befpXk@&KEY-1sHjjyogoM0+iAJn!d6j2mPV>B|K-?rD zbtcbfKBK)+t5BFCp)xymHYX3nt|4QfQ5xJBVHyf+^K8%m@+v6zPVvbwlk3l!cr<1$ zYH6=U)TxT1!*9oWMuX>ro{Sb&`xkFw8mzvEUl!hEUnbB{5{WF?}3Bg`ToCuJ|E7rpLKoLyWVx(Ywtazgi}G-z234n z)p-kVs1--wIjmO%R~e>tp%&$yVZCS3<-K||s8V-9jpw|Dn4&ez|Fd(348r!2HIW_l ztdx*2SIP(4N4{IsBnnxT_bJ7tni~#D9jqeei(Ly ziKTht?lQY@Ohe>B95|zzLsouNbI_i>8|kMv zrWJanqGgB0q319wTs>JnYh@O>t%o(~4ZJak>NMlu*_*>9nEXfg5?IJat@6%Z#OG$C zo2d`3$AsvOvaD=ORSSpZW;MEFkv%xCq1Z*2r}sb&MDA7VBHf4@!lc~vd1tS+vNC&H z+(Wa>S`y{NdV%GMs5E|*E4Z{%-kuM zX@<>-(`IvlRUeN7TRqV${(6>OFb22o&wSG0T=O3Kz-(;u?5B125-%4vzr2qM(yrmo{u$r!}tzM!8kKc-#^1` zJJ~~Re4pHOT{lkD8(59@b{p~?k{8`KvgKVlqDc4C7~xDY&HdU))tIGB<8@S?-kYc| zOHtvKgLKakWp#RQLB_`D`!?CRXfh4rG%R(@w5pK~%-l$CDGn_dm6DaB&$&fSkN*2Y z!`xn#nSxFA5qbk&pN@%~w_y!U9A_q4_3FDkzaUB@`Niy2>piJy7GsiDC?d-} zn+exVzi#}ExV6h8E3!X!-IVE*ucO&CTFy1tGg=Pz$cm#+otT-8xli9{W@BO%j~;@3 zw8$NghH-09UQ~B*c^2+w)VIQV$@Tv2S-a}Ax50VX9=HP59+^`O9h9Fxs8>ehX0$bR zPLC+XHl$ZP2z#5ec~WB1^$m+}v#^HBOlOY`JBzo3wY z|^;X`9;^Mp<^b7R~ltlOWtgT*no3O>0?BLKM#?^1;G;UIQ zwWKFBIF&Mcx|!2ppAC1xIP7w_T{`+3F#BzMv!rBXZe&hrVeb!j&i=QRs?7Nt za##b)f`9$w?0R&m);Qf!YlGFtw{Dq<-9IxSj@*80xNX?b$wcp;@feF9AM|-8GiI6X zqWb1iufB#kL3Z?#G%Ig-k?B$*+bw3dQVtN9W?G+!p2-ikL|yf2)?2R_?n-EE4Wee@ zmKkmUHd;$YCYFsB2nEnheI67vvh?H9N^j&fx+Tr+9=$zk`u_TuSfgXsu4k0S=*@c5 z^zhRsVbM10b}XTA)aaI(kP*xMB8=q_r_d%Fqx2d-mw!&$>sLeYxp(BEe1fo!)Slh2wD_ZsFHglDP?J zDmW^dSuaD|kU;n3oadOCXnjk*YxpC@$>%6!ns&6d+kGm0r1{Fv3 z{;XcCf05z1ImW`yGU@`{?`e>_p>H3AZpc)|^oCh;y@a|1mki4p0mU_%6^tsl410J54Z;i_k{flaHFBxA-w2>}(`a@p=U^hc_h*?I%EdKu32s{bm*cASrK4#1qbOUw)99SylF=hZ z;BZMnc2C{T^a0+fbL7@8dVq10rp|7Nz%+{WT8#%MC*3lw!K*=eBcnGLVVJt~*ifB- z9gjxmde}win@89p!kB^WM()ewKA`RoalnyV#Pz~5?;(xXiLznZ5GEfh1JfNfnj9iY z&J6048d5ZR6mHV8|J3uzvrgogq71#bSHp<{nshoFCT;-WBLcj&5j{5;RFIF|e8`Uk zBUaC`S1%yhoa@j2@rG>Fm^f)})Ga#QPRC)s*U+*C=VHoSpX4C)T)5?oT`(TL!MP

uNPO^Bbqn=^=mM1m!1R9$H*Uh=^#wol_p{LTEK}Sl7 zTP|1do(oS|K`;79Kz%BO1yLtIabTq({gRR)d|YG}Zya*8GlOE|g$4FUO^;lkUgSJx zhQ#8`6*Uu4s6NES{Wx=PuVKtL8<-8b>yZc>!1`=aed@RmJ`P)9k&C<%$Thm)4Ry(3J0ojrrhF3A8gCMGgkTi ze4J@m4^a$i7CWe!8q_S9)hv{~z<;k(;qy(5YZe^x7F@T(b6Ye2;CNpFoDl9U z1m8ZWnSa|LJS%14AiDlLfZwO^pVh2KNri8Lzbr81UdMMcUQM=b`&(Ov#VZ}k{OD8P z-DciCm3r=mG8&v5xx!8UZu*#eH(jOO#$(g5o4Mz5-T3h{Ce5+BF^F-w@s{hSMROhi z6pn*Q3~1@Zx{VvhC#|}1L4j@VS(9hqa&x!wb0Z1k=4o^)(`S$8BoFyE-mnD?dZv3Mz45qaoJe_VyW@FY z@W@|^T=4m+==2Ja9_xVeu?r-sZ!NAPahSy8NbigPlJ6S$MW;78Dm~h7q`bAb zj!v(C{}POZdlMB& z+l~B1!X1PIuOoloBV6=f#P2saMy~096yd1*$X}!m`M_0lIZ9Cu%0N3v#(zXF)KSEy zaA_@^06U4wAaY5JQoq&aM$4*!BcHF~LxfC^cE&uT)7yBHW!(q2$X_JA2#;X2yWjfh zOvIh&G|HJgQc4rbu^KF6gc8&Ys|%Z%ntEZW)u{Bs=f{g3q7QX2jo3(tE+{o%!% zQH=61wT3^ZQO`+#T28~CqkGV3-m-z<%F#8{;Dna|HxTV_<4aNIk7H_c$lp^qp}DVV zqj8t@!hRw0M?Osm`;Y|m40l94f%K0)!P#v>6#L(%i2uuwH*RR&h{1#M#*G*3SwsKN5Q zEVxN7cZC~*iw+MYo~vzU>Cvef_()0 z2@Vn*Dwr==EO>?BIKfGRHw*If6wL27!Mg;@1S^K?-ncra&DIl=XUuL{-*z9qO*@I%3Uf}aT< z68u*1sNk=Hrv-f&8<=mbU^BsxU~9n?!H$Am1$zl*2wp0fEjV1TP;j*1HG-1_rwGmz z{FC5(!G(fL1Xl!f-MEl6YL<^Rj{{UU%^3w!vseN zUM_gG;6%Zj1!oA}E?6pfui#?A<${k0J|Xz5;ERHr1h)ykC-{-zr-EMz^5aS@_b-CK z3kKqhdsD$g!E*&W2wo`INAMEC9Kn1+e!779@J(dINrF=aXA9mXSRq&?xLoiN!6yWt z6?{=}li)VN_XIx@{8aEO!S4ls5&T^+faM0|Y$}*2c&=av!3zcZ2=Y5ojF%&rFE~o@ zYQaf@Qw3)W-X&NeSS7ez@Daf$1fLarQE-#sHo^A@@GHUZ1%DCzT`+)&yDq;V zKm101u3!hj3kCZKULu$y$WN>=-YCJV1t$qk6`U=2mtcipmEdy0M+Bb`d{*#9!A*kO z1m6?p1TPWH5zH4HC3v;qB*CeI za|Fu-D+QMbE*E@Q@G-%s1fLUpO>nc|cER@q_XvI>ctG%b!DE6a1-n zI9+g_;9|i?1lJ0_CisrvCxUf?Ck2}{H|e($>>`*cm@9aNAYTSed2Sc16ns$dX~7I^ z`!HO#V3FW;g3|@(2`(0VL~yO(Yl8fo6w~`e@UY--f-d$%=$|N1;4^}+3cfA4Pw*STUj+l$cwzb>!Bjzhs*LVgg8aw``2@k4f@OkB1s@lD zL2!%U9>Ifx#{?bh5i#8sf~kVN1+xT;1t$p36f6^5D)_kI3xZn&_Xr*oJSOO1PfF)6 zm@3#?FiWslaDw1W!7{<6f{zQnAh<77I=goGDl) zxK!|Q!50L#2<{O)D0ocJ!KS>f(HeU z2|6i~zhJ6hZ^10VV!;W5GX={8mkK^EXty)zHWNHou&-dQ;26Oh1m_4=2rd(RT=03p z&4RlGKNtK#@OQ!I+8a4G3cf3NL8@`j5F9EvQIH=?q<-%a4-bCS(#eb3TYGRzZ<%cs+-KKR<(SJRA_sUG~ z)8nFxFHTA6iPPy(zZa#ar=(=0_sW1H{;rLimyi!wfa81;0Uat?5nBU7wn)}F#5LUd+tojs9dlY_8wkv6wa0DX_X81X?mP= z!G3*xLSG-y*L%^aRxa47ulMQeUHW<>6oj1pTE4IwE}ib+RjjqMt_d$-QWdpTb7Q>R z6DFU{XB_8s3d9&yL+wg`nvU1yL{(@T%WJP-q;OLBJ|=@uv6XkG`71+dXGXRu+nRUP zHRG<{Qe8ExBjjc=kday#_oz=7*A=ziLY~_RFJL+nM{@12HRM$=->@!zS*>lvFxv1IQy6NS#!`8zY{6j& z>ML7t#K2L)9ylL2`~<)*TX33CrJCC-+N9uWaWa2bq~N!o*1cEJ5w>bnjU4-F6?+v4 za5U9|OszT}==If+veaD#S~bTC!>COuV!glXh*UyURc+S=VG6o1tT$7g-jbnzoH;{l z@XFstag6Of|aFde+t@{!YD=o%kdCy0+NGwAJv68YJbFKhNL4@3v2s zo%ns$%~fTfXxz<^Y;4%AEJ;(y)z3~L(z1*!l~d9}4RS;Yp=~T8M?}$RXd6%)XLM_; zT8~nq*gC8KE1z&)T6$DId1)b3(sxV#zl?J^5=W({8!d!H-g=!y$=aZ>h@jyW)KJgb zvgcT-cG;VDzZEq0O6~3~dgnhd!;-X&2Ae^0Y(CHw%xi`2$4VmR1+Ow)b9UYRh=^d? z?CP$8Dk7xv&9WV5Dn9foS0F^)P52T0h;^8DYQMoD#>@VvHl9yWp>^Bv!+xtlJJ40v zh>esP%c#sti>>)HJ6VHgm!6x1p}BJ-Gt&e#Z1S=VJV z#Le&){tW|D*~#wSlE--QI$Mou{nk1|MbUY&9F*ZqZt z@DftDFkTnWKf)PAxIAqwVSQQ+K#OgL@9?l-cwi{}9H$rI%T@Swp6{rrMM3XGndVlG z>R)-+z}W@i3JZ$p`C&!v?C#+gW6}Lr{5q>ccw^dX#Czo;{2Y5?dj;M3huqcxwp;t~ zJAW$$sN7{5u$F87muMiUmyPJd!po;1Wms|fM**~K?H{g~NVnSAP0<+VmYrzfE#YnX zD*s1F2{9(aw{r95la3a2n78mH_*O!(Z7WZfqXXr=eOUCcDiv2*!TvU!Gq-ZNHo7X# zFt%54VCP>&?e+@h&p)r6!&r-(evE09Rn+KO6H&Xl|Id*eM)!Q@CjE@j)RQDF{8xlfL|J{lF~Xq5Z(sOu9^Vff9(++VJ3NNRnp(9icBLh2x9!LWI!EjE)+-C7A^b48!{@Gr5K@Bf+V!iSY5iq>` zL`VEqoaS%UQT%SN;4lBen~viONtK|HVz5G1h2aW*wFqu`;pMT$Z5Vnb<2EL|JY?L) zhAX%yfPNtxEg!-ABl18qBEbzk=Riz1`d6A9biU|TN-9k(lS-AAEHACFvPw&rmzGyq zMLF03RaQ|BT#c!$q8zvyTUkXp!ufMKPkjQV4Cllm+t_f9-^`h0b{y%{D|&LMMkmgG zuLNUCRIgn*9DY6D?pfRO!@5zp#Qabhh zZTG8J@h}|9HpgH%_%-KJ^iR*Dm+1N71-fir?(Vuf;BUs2vQ6xokVYIw(M_ydkl!hy zp1Wk`jP=Twu%(Y0lex<)FUMu1YnvN&%`=!0_iG!jEB?)tD*O}_qrrQc#R_`^%ygyI zh*7r?w7Tr1@)rCBW>9uA#ar-^Fld+6~hK4e!_nMK{?l)z1T zs|7`Hsrc~r3*lOqhiko_i|Dhijw+aAnJ%~X&YsYcUWXxYD+Dgv!EUZ@FlFMruxy8) zykmqj(Q*)}tVu}CtQSZ1C_9A}P7`#MWv2pO#W4rXY!i)}Mgi0GSN1o^7PDYuM5~A1>Ko##9I6^k zI;z7tJ<3jmymFo?EjtnL%H#D#qF3(2MYw|Fe$NlfPT1bEH!GL(#8h~>A8wTur*X}> z3D;cV6$_CQmf=mxPB>oqI9mVWo%k&~8RIQ^mlvn}SoqPs>M(Rr@%F41I%qnawpY-J zf0!2hdXGLvD=E#OG@Eu}^?>2DyA}=Ucf>_i#WM6`l@%M{S5*sps|u>R&e2Z_ngY#zAFm9$bAJ& z?ye6nXQYY`XOFFXbMvXTzx{#BkzqZZ%GC3xd07~$=f#I}FvamIxYn#ZeE5^^BdPY& zsor&7xJplt-k!ZWA`oU8vBvegO_hI?-PPHel~lHgp`3Y5%Qmq#V4(R_#9cj_&c35e zci+~m8R#t$sAnyDqPf_;seGr)DVW{e1FJ^Q!(ktBu)wLb|_qkP5oL3U=*Y?ykB!;V*&p6#C4UFpkf(j9RIVG)P2NN*NdFb>m`a* z#jz*qW@B@vs^SplgppW>TJV}}tL`s|g~9AhVG8s^RW(KEx<1G?yoqz|a0S;8dceiv z9XoAdIZq;#FFg6ZR>J0l8!hh94x;%bU7% zWWm7D8xz;F1WNiaHMD#OOeI{g9(sN&+jpi}T?JgR%>Ig=?E2B?0wMox=BjRr;0y?Z zSayQlp;?P~r`b8p66_*-l*_NC`I0QBS>O16@wrf~lV-)oUy2ZT7(^~(@trTf?KF#z zXCNDa+|G#62Iq@nY&*9FU1Hl=xh=Y5(%!^Fd^|isV0!T_A~6FDr<$6)0=X?RP}@x- zS>x+~^#OGjo&-c93>fT)^zrNid*#y)3 z%K9>BNs=XNNP-=2Nm9gW%~UAvIa;UyGShL|w2Tx+%ZL+Y5kc^{T76LM*H$Y86P%Q8 zh(l>9SBmy)7l?}2zQN!4riw$LAwrr&(6V+&H?cM82*T7g>C_O@B-I)5>V3O(vj?bX zQPOo0&zCT|wk~KKCc$oQ4|J)Bt_`7l(D{WT10wlgLERe4klUgm5}quG=!cda zVf#i=1nYM$f=Oi5PyeX2Kre}=%R9#pnLOm z$4^YhA$0Kt#t(=xXw z^6~kVm|lx@Ix*QyxgS<-G3hmQ@yE2wg-a&RLdEoZo-VO5pI?d&=~zGH(roBaIJrDg zIM02sBd?pl-F9E;i%9MYXu@%)oR5%hdt5`e{+RoF!t002&}C&%F5gzvVr*4YDAn-? zI(37~ctnU@{2M%DSeEYaimkzgZ8h=7`7dTj+r6zfK>7DVRNr|hQwvFaxX5Z_X$Qv7ym ze6rA>x-1E_mC%qn8VA~1XtKHoRTO`Y&^BuH1)yz&rl>z~rX~J7p=nA{jJ85MtH)5s z@hL*Ps=lba`1badkRRWLS8Y&P@oDz8nx?B3EMrG0QHENL%8fr?Xn%Em7HC%+^EkvE zsQd#!d)TaGUuw2`cQ|NIo7Ut@9irYqlJULl>vhUQm4&H%{6+R0O^2y?7GZ#GKHQt9 z?z|Xun9W-8rIx5GaB3w!SLhg3M&IE=$Ey2CFB5vLx}P-9&e3rvs+m-5fyg{r?SVM) zh4!5~-ziqp0ho2fuWwcjn^5tuQVrfYDR6qtXvFd+Q(qg6Li}D9)m3Y1IM#~ury@d} zpQaE)n_+RZ8PSzCpIp?wZAVcMSvU zYf@JDY9!+@WFmD8S(seXO4vI- zHfp)g4P;yV4%O^)dHU3GTjM^v-~9sN1MZVpB)RT3EDB@XWvKF4Hx6N%xKCnc8|Nk? zfq3`3?kJZ#uNSg%Kg_};!5xLR?zy+ZfP(H%a7l0vLbB%W?PAl0xf|_jQ-VfPYyX}y{IqnMhwsFJgEzWh5(3PF%E=HPd-3};Wiks2F zvf8=b(cQFnix4u^y%{0X+-`{5!5xg>j_&8^<2$+6wZnI<-P=+yCv<0DXj$jGgDGyb+Z3^SxZgm|p6*F#pqKj^a_sH$nYncLAZoLZ`!9sN z$Zd;sE_M$N#qj37i`+BaC-B?XjfZCXxtBwR{_ZARU*f)o+%I*LP{sl7GRRPCxesOH zo(Nt_fC_%oayy`>-vZ6&!qXqT^vR~se*hsYw;iI|?#O|xsEeRN#|=Q`ezzNb1MV28 z#C6wZv!Z&V(qi4wu%;&NpV8IExzh%*qDoNh%DoWcH+6SI{ATVqtyxj0@EdfS!WI); zK4{w9eG$Jc+yiJ^A$K=^6Ww%(pX8=t)M@D+L|)16tB|mjdyB59XFIc^`a_a7?sSNJ zt~(RTKFn=OfHT?f|%4>^_WEk>T>uvP}0E`1W-t4rN7s00Zpr=0kgzxGv~oLhj)z=(Eq4hD_>tufM}8k$?r|8%KP`7T*gngB3iWTx zy$f}}-*QW#&QC433hWgS3IfNa08-0BM~>r2b+1(h7M+~-l(hb;FX zD)KAK-3(29ZMh2}{5O`H1=~7oxqECZ^DOrzH^5wevfNtK#?O!pxgSIBfa8`M?0{#cEcYfP_A3;Eq4zh-EkEC~ zPFQX-gg6O5=<}52UIVlJkLB)!)Tb@?HE8K~EE=fPMjZTB;@t@~`Z4kZfP zZXRHf?eh7~D%%|eD_Cs1ZJ>}PwmTdJtG3;%U?KP0?iT3!&$gQinyyNBR9A9xR% z%soH_oszz<+POMt(i2d)O5g#FzQd=5qZGjKW7u@v|^w6hHO5t{gN;2Ws;6~M86 z%X$FlyAW^P0FFUzm)7{*xd=BOxC80j1N=8o zvJ{x*pd3Jc6?r*u3~&YTedO~1@Y?{&0sIXW_#m(pdVL7k0iEE(zyqwOTEDv<;pPJ^ z=(+TO-+dfT?;e2I(yaeg}J70lcXP^%HPIXbCIn z-jVtVxI>W7LqML0ei&#Y{3_r}F!@J--=f(+3T%n`_zUnYbWk-)o|XoF0DJp8@E+91I^dPa{~y3Eu>0qM-@yJ}09K$UD?Jc!e}#VM10R7L_W)Pq zqJDra*dYKvM|moMvr%sgfa_5Y_X7E5hSE~koi&j4?7A;N&!wfYR?E*|(Ei{Y`?IDP ziEl6Jxv3s_ou*5n~4-57uCm%6$gfbgh<|sC<9$2b=d+ z-Py1t%iRY%u-$B=>vIb-8DlwmGT1r#1K0f$<%@CeM4dq+r?VORr2QFVzX<(WZdX{p z?efmP&)o-&IG9evFjTxi zvEtuFp@PAn?|Q^md^$Xs;2VQ9xPUtsRUT|E)UPHY?_dj|vFess(2$PkOI27{`lq4` zOx6h|YH8wc>JEqC-+XT(@m6>>cW_;O+V}NG?3e4)-Uw?AZm3VYFFK3h8#*4-jzM{> zeMls>hN9_T+e&8g!CK$#@QCMwUIT;gIZwj;TH&(}R`8$BI8%;Re4l9WQ=zfyYnJje z9nzN?R4dS6gP%L5&>^)J?JsyhXtH`0l@|O$XdATx^%neEXo~tA>JEP6ypBwLscGsL zw4LB#$1K}Ax8i5#f_0K_SM@%uIryE#O;^{#j)JGfHv>zMTOn?1djrx+$6Wd9xv6YPmSkG76>Yag6 ze2uN*FqXqV56L^JYi%{LTa^DgTYZD}Rv&-8tv)s4@S#2@b%U*T8{x-jzR_0G8l-np zx7sSuN5^M{IH@~q^=k*sSy(4^m#uD#4!_s7VyHq^y>20RhZQTDN*5mIM>l81^ngoB z#1*mFy67hDD$Y;OIRA2neF{G;UwsN}hH-vWuNA|TCrA9y9%+}sX8v6e;+*C^F^o9D zmi|L2Fw&pVr3TyRYZ~cBL<+VSGxV#!pwkYXFErLPxt>Cms%AgaPiRnerYU6$4XH&m zrIBJg$?EUu+Ji;n+eVE-{~H|Z=iY)ZHAU%8=X&w&taPUnp z_;b(~`%=@@!?cCF#WzE}59i=g{{`*n+h6%8OY7A;DxJ&3PwHa0s+$VId`Ul1MLXx^u-Pj5A zkoI*_OKsJjRsW6fa$Eh4eaDZ&7usq;2KZ0@OJJ~0>LOcxK?^vho2`>tZL40)?H38Z z%vLU2h7-6(heu1rYmYIC2WZbuDq3nT3mPLFE%hy`G*&oTDsR&Tn+Qisy`SR82}es^ z!pM>P2d>REl{KVkJxH7TXG*s|ER5=p}z8kAGcL8>$ybu z30sY${>BSGZL7&l|CRtN9`)f<dM~WHNsc=)NwYBr-iTbsdX2EuM2Rm7d@v>eMb2=2w&|}OIaVa zBHtRH+Q#(W6u#D{MzemlNP6ph>N2+DcLHm*eCvHGi7n_|@!#N62UuSp2Dppoq;B-7 zTK1Hmh<`2QV}1vOZ}q9SF)IsxBYcNXeaG@0mi%}6)cH*BC*iw%YCI|`ctZGIq{nge zjPQNX7rE;id))6+PYnPMxkmp7d}>q^@NQhCWYh5hqANQ$&On`?<{U?flsiS(cJxq6veU&?^73PA$ zh2p=^Q31>cgG+=ja@2#g_lI3}lxUBR>Q4Fo>Q-v~uXNND+Q-upewCw!aD1;7UgMZ? zcZcxRjv07Aa5?ZgscRf{H|^nL@!#R76KUX|3g79ddssh*gzs{c;pmgz_8} zzRyt;Ige7~dm(Egk1@y*Iu@3Ngk7bHx9&qaI^_H%fS^Up>qG#|kg^tEbNapD28x zUo~a>nIe3VUwz8It@|PQnlQ)lVF+ zdI~@6SKC-0nZl3w)ujxd9Xm?Pchs+5XaAEIYxIBIuiCPIA0^>W_*DV*KUVl@zj}f7 zGeLN1Kn)xUev|O>fLg)!cdPJ)0o9f1%@w{VptexI^MqFi)IPS4<-(T*)Kbd(i13vG z^*rtM3E`^(>hBzXBfKV{YIDHXivQ|>num%Fz94)}KwUBr{8iy=1B%bT1~&^|7f|Q2 z|9Lys^k?e>>POCucZvUofcgv_Mev`(HwM%hw#Uze*9O#T+V@wnT+3r78&K73-$#V+ z2&g>T-!b7k1L|g$=aj_X6;SP{PrHfKf1uTb8P{WcZ(`)x2Y%~xE9i;;{(!oH{b7>u z0|B*&mdrT94IG_$t9~THe5>P?fUoYWD1L_pZpDFnr52!+xZ;<$(2&g#P zN3QVG0X4}5FBD$ts$}YatnhMIrMCi~Abg>#Q2nqE;fq`~hU4c9;nl91*cSYD;mch0 z2>Zi%!dJTLuEF5<3SZ@_H1^Mnh1a-h8~d+i!dJVh7t?!4_!?KGu>CwHe66d_VgL4& z@O7^0#5w7+!q-Ed{^0AIjDy%%xwz^z+VdvyuXR-g>+dbm*H+i8T;7-PJ6!cu3j9Bo z@Vi{I()qXWy{>wI{mGXSejjcg_`vIgA8^$dUBHh@`iEVW%lv;6e#BM3aDMYglRr%R zb=45oM@*ctpX08&lKO5DXWH`#SKX8V-a3wZMi@U`_5Kj>c5&Ph!u%;ly-Iy{j^iGW zlUg35*0X=;9>;wgCv{6QlA2;B$npM*1xO-4cIIj9K}W311t771_7ca9=;S z5JH$0B%`X zo2+IHeSh35NDp^e^{&pJ<2bMNrN*ixHjAZNEbQB;bdEyH;$}lD+>EGXC$K#3Ax%Td zWtmrqZ?c-sDtjPqoAzy^ZexwClB7~pmX^~$xa|<1H}!vG<9S+2kgjI1Z~j}{VI4R_J;AQxnYd$`_E)!{X$IHE{h{eV=%puA z)Y|4s#ORbZ)JT(A@Y46WXW=5Y28wBm8_ZNVr%xsluaK6}G{d#FIrnblxf~90{;3$r zLN-^O6yF5k6};X91nCp!e_n?zgY!ABLXCcZ@Z5L~u4)g(Zx_$pxzcXSako=EUqirq z=yCqf5YY(N7r{;P`brn8v8f<9?+TdU92!k0dUgF?oLOBfQ`>u_wu7d&KhmlCQbT56@~gPMx)jOk8BV@_7TU&aQ~oY?lwxeq z6%C|8(5vdp&>59#%Al_r7a1YD!QYgY4Y{GTjjG!ZuVij-1k2;th)jfOjKCixQw)gn zkHfF=qrq#xMDEX+#6*dA)CYQ_K2U>LbVEv85i8DL1Jc^2#Ygga7uRwAgZK?{;vVP! zftRfMIR8mra>F6c@25$y=T2t34n7-4i#C#VhnJB|UoA%AmPNC%{bVB2{d}9$S zVfo|mkMr{d7_IHC_%%w>@~|jcT{u962~xs}4|Ld%bl6}1m#`AyWG_T`!0O1vUHrDT z+u+wEUSAEC?>9{35>|H7!7kLnivDM?hWeMpZ*vjrp{sSQ2|Cu@^|7e9h6t7~J_})A zuGC?d;MZuLFWS&&PtKCaWYBC2<}>998^1*;ZxoCyVG|XC7VRCt$ei#xJ$T6FOW0w; z8-`_DG0giEymU-d*VX4@7{q+Cdrp`C45+?nco|R zj1u+)kqvruFE#+S*D&S%jg|M2VL@*NM!$rQ4GVdH_k;bjtB#lKRg tc}+J7M$?O zVC|RUOF~RLBb)!dU#(_&aZyfe(B!B z-N3#!ETj3%>n2(Wbtkl6|K|9Rpq22gVI|&AE<%21*c9(;j0Oou$S|_oUU#gt623Qd zmE9cQ6tWV2Fm%1$dr?-`G z%+R%9Cq7`n*uxH?WaY3ORl0IWD#D(;V~6m(UF*3=oca z9(R@#2H6j3f6TMyVP2CkIKpGq4Y}Z15#B@{qE53TJWk=ehgL$4z0SmsS1s6lhugK9 z*TkzdYH&HF5MO`I) zU!s~sK34etM0JMczuIOy!oEhLx&rIGgmHF~PVZ2n`WVA`!g!nA9IQD>RbK=?!5*sp z7bdA^62K=4UzDU;u>s#`&(QwWN$OwB?yp&N z|H+=Gd2Ny!jeU!RJA`jdQpah3ciB&9 z{~bw+?@3OWZ*SLpXOdda#&M6`1j(X4lGI7+uiWmZ`Q9Y88vzp**yAIUZ{kwe$0OdO0AorS-8ZS&gK;ErnONQU~bY+E;A+Td5k>$2q=* znwPd#KHM%#NcBCdd3kH~F8jChegD*aVQaOM^>Lxk^oNUDtJm1RxMpj|UJ;(6Qel`0y?v%XUesRwM*B_|zOub4XZyI=_o>crb$iwAeDDmPgJR$gYJ1Gm z-b9Th>Yw^4AZBo!MB+|3{94T`4)(qd5P%UR>Ys**UYtK3u0fN|k2)ATRWtk2 z*^ROA7w1octC^y4x}x)eYcE{4wmD__Z}YW=>7JRs#rcQn@SN2A{|J9p^#4X7!d#ss zEk7dEySO%@au#GVl2UvMhZxRDW6@#h*623F8gI%-&dh@cMzGUQ> zl~6s$cb$r3eyx~txJ-<=;@d(t9gGONLh5TJk^=+BaDLCRU#Ajh#c&SKv0QUo|9Zxi z7NmKM6~l=;EmCuz@&7u)jYJ+K;2_(eg#V_+h%Ah(wbK<*qVjf-3Wv_9I*Ya-hK3Q; z2RN&sdhyI3R8~F$nX2JX8l@NNJ0iwhogT;5vjfy8Wj1dl(MNQ6j=ld)z(}g^=}=8D zkR|fWM54ZuYWCn7T&^WNrh~DgGKobC)*7zRL?b^G>LTsTu{bIU+ZhY2{Wva1`H9>& zYCn$2QF812v`DZ;;LD{KUfBWN0(EDIIqXOx(y@v}HOE*(r}|05d1g={9o8Bd~C zO|*Xg4%gOt_G1#zRU(3Zp#5yj91``9j>kuyAc*PCzSAK%H!>k~_6!lxX;XN$){~tm zBj(_MB)Y-Rv}jIlOacv=i44Pa0-Wtc1rWb!+K)4zsKn{lV8X~ItV3}=WOfJY1HkVe zaEBHx+>UV(IG0u#vN~@WQ@_;zL-Jv&so-ALosOfMivG^ex@D7g6KhjlM07n(uL; zCF4NExkRGYLUiBFAj#YVNyzjCI^o%k!)?%beHUGc&|VU>_xOo8 zUnaBVcF1!nz-+^ClY)u(auSh7vuT)#CO1F-EvCn3oSJuEuH#tVcjzIT_b_q%&G9{C zt9eg~#`NyQdMUz`x3F6S3+lX@_crlDmX8@UPoISJeXpY%YjN&=Tqg0-ZgxAS&B>wE zR+#O3{}==%r?K~9VO~LDLLCf?^$Oa7bu=t!`4}zK=}V;3?1^}6`G>kB;J%kPEeFo$ zn~W`w$38Bg_C_b`?>p+1K7@OY>vbdh1{9*^*Z zE;cN~>%sgo4D0Vbik2UeN*rkUSlCeCG-&I*hfq~(?a+X`(M5RQ41xPVUQ%^eCV~wz zN%+0{uo4UnF4ums-ZT~<%P3NLQ-*_O->3aT-pORJ9QyI7lQ#)96dGdaGTZyTIp|PB zSJ~c|xuC-gU2S_?v7Qd)8oJi@?#==o{tyy&QrFwwD$JHcmr)`ob-(S+gb{`E3_W0b zeFlK$|4j$R?$ln2QDEpIpErX^jWBe*&ufW=OQ_IL>_7b_06LPJyx2x?yunyDgo;ec zEAbvj%nU;%+?U3tk>gb}@F><0&iXjso!Ow5o50we`hil7epQRH#z8kyhwSo(lbBMY{gl@hb(h%Aw9cUSxeM0bgbaD_A>qVS!;-yGFrvgX z!`gV;=-0s*ZHnciD2W~4g|z3LhTR9*;;m?-~~JZbEH2JKsX`zSLx|9TuU^d&aMg$5)>_?;Dol z-3ob}-G-%kL({-MG_13CDcK&wx_XzUfPHivb%}dq-i=u3IUgIpbT6YL*gp-+@OTE= z*=JaPk4G<@PYfIA@tC0VFT=9EXEMP4ZP+l6ht{0^hUIxYvgUkhSfR%QZ_a0im3TZ3 z=X`G17>|cdoCAi9Z9aXxPx-WdyI*EW4z{iU%=v>!-n1I@w~EAN5&(GUJmv7 zt)bZGU5GBg`OeUVws%M~?`hAKlbe-*easlWub9CIjI9>^Bb$s@)5^I zD-Wq(S<05e7lzajA9%9xMIrShEu)p~>inuhYCPLaYkPr~XH`fIMQ7!lV{^pEHd9FD zP)%*@721DoNIgN@J=cCx^9>>O9aV9jY(pIgsiX^|_#vdvI%#WjgvT~jNTs*LMT+nv zA$3nKcst=oL+V@Be|wvKi<5dB>9ysB@Dm~RIon5?{g%%EbV&V?0p7vhsd;Il8jEh+ zG0%--3`kU+8NQRmuTE5T)MpowcUhu70q>kI{wovJBh0v~@KuRw^+50oh1VpiYcPm7 z-Gr}BRH;-{cj0Ri6&jG`^bo!_QT@p9J%z7JRG+ZV=p}r8qIw_)ytnWTiTY6wr;o_D zF;N{(h5tpuYZKKi?E5daYnV;y);h_@%-RBr1+i&H&-q27d;u1 zkwjI(UU;x=#Pie2PL}v%+q@U~5aHN1U&8KSsBmnX^K61MOn7xttBEtGTh4I1 z39CI7+vc2YIG2h4)(pk@hLb0JM~1ot!;zD3^N>CCk)d{CAa@Fc@5)erW&bxq_}&cF z0Rxs(D12XrdN>Vyr11S2Y9Q^kNce#a#rF$3#rA$}e}^*Edu(4N_RpFh&rt2DpHUKi zS*Cg$BdT+`@RgY=kNO`id{w5}$?#)@*JP?5Y`<3sU!AEsQlD1}Uz4fUvd6wk@?V>& zj^VhKGgk87n5o*b{;#%QDg>nN&s2}Gue!!=hW^M&J(Q^r^*iH4U&k}m{p>Wa6@DU9 zeMxyH3O}9MYU&)znPzijMpxfgeZ=NE-R`BkliI$jZ4dBU?Sa~VS6|hy4fqT(@1uQH zJneF(Jy!c4@7rqXB+Hp?k2BipuXbUU;@l>=?Hr&FvpathzH5LgX76;j@Vx`nXqGO* z_YF`78GoMm?;oI^pf*Z{9~hvYXmRG-=CI|V0qQ}vu4VQNEzV)2N9$NFymX+NPU~DD zz2(Y*Y6Uy*mD0La57dV@ormpvbo?~~)d*VCst6yX4|6(?MEGEJn!V4X5uT+Ft2#9z z-;nG zv(-J9fj>v>xE&TKU!9{g{@cV(;2tnO#+KkM@D%~qGN_giN_ zZ>lp}4PtNf58)@WRd-t33pVFSIP8_JrgOAeFT6BI^{4zV+IzKsd5-#)<$c-ajdV=A zbJS~WO&f%77@}@rYkWoc#-VB*Tf?iuYlo@pSiVh?|JGbJo6Y`pyR8jK-I1%>addja zKBV*8m8%~na5n1~csQwhb5#$@v(+}Uk$t%;oAtR(_<>ygFoN@z==*T48k+JF5&C)RcDSSyM?budU4<%3g3{gAEt2j2;Z2mdeJ`i3a`yqaYMlWDST_b+DZNG zi`YZHdXMRUDgHb2)yZ`5gTi;^tCy*tLpGQ4&|kjlo`8$5#QzZdF982q_~Cs0aD?-X z@FV$ZCP&9Qn~MtQ3*l+sN5p?+feNtq|6cg20=26h_z%Ks3e*EE?@z*47pQkQ`u!|? zO@Ug@-u0O9wFTJG{uEBr)(I*0N$5q`Qrr7*uZ;iV%~vyR~L!pldf<*Z00eBlU{N_%MP<5~c- zu@UN5+E+8587@|hPhFdsO#8227RWzZXBWb@fOEC7K_==2$je3ndf5Bo=2$N ztS|FmEJpVcs#7!YkmSE>gnF9xmneMi2(^ppB?;d*Lh&72PD|nYN2o1aVI>PcFhc!@ z{aq{JheoI>jwh{!A0DBmu{`GpKQcnS#rDuf_|XxnA7?}73O_zVRd9B3p70YRRJ+dL zZH1p6p&n;@ND*FIsD^Pi+D>?Rp}K(MTYKRP3)No6PZhqXQ0=2VrU|buRQnmegO6)C z%$5pUO&{M2vt!|F3-!Z9PA3V!wNPzm`|d1!N1<9u`{^QlXQ8@+?csdky9(73@(YCT zEmWImPhExYD^#_Yfp-_azfdh_ef1E2piq^hfcF%Bs89{z_|wa0X8(r^)opADy~Y1X zp}K|kmhP+3?c->nYQy@zNc@i%s`qliGlichR0nME{=!ces&`%ROMGUvQ#w-Rus^s| z{1=T>Wt2C3;k6^xRNB*J!ncl8E0|xN@Es#nJC-M3_|B1P z7|UBAeAh@-OnV(6eD6qgg7FK5?;ELpWqTSaeE&$*;e7C7UpHOe10&Tu`j?3Rp^<9S zaPU#W507kh19k|;_)PbI1nOkDr+7CBUsI%?8g_0LzP3o+z~(VU z__`uBl=)2+zP?DMP@Y?aZzxjwaK|*^8;jIJ?nX=(UR$J2UI2cp@U2Cv%^>g@!gmy@ zt*nkY!gm&_*{qJ+gzqX+kFoo^UHIN2RZjmuN%yy}NPWcSe~0)VC{i=nj_(wHs7MuX zdU}`e!$s;XPOnOZA1P9H9{4??-=jt9U!4AwiT`ovkKI?fFI`vni6YgK=DEOEqWPL) zb;<$1*Ee1BwZ*ClZ?PG=Tt;MPf^IIu=N3lA_;pQRXJB!uljK50wu3{C(@Q(`LTde#nPmS<>#cCXz z(_eibYx(vUtJgEZ9~XY0Slt^BzS{S__CHjNz0&J2fazzsx#JgGV_}Qm3fzNH+3$4u z2~O@_RDtCV!>{eW3wNJ8o^x#1LDl=M^FBd`*x%kgb^zAJ$Hk$Q)zSY8j{ z@$~=^zZ8#e2XKnVAZhLh>NU8q^yYk}f>S(B`(>D|Ht`$i@y!5{c-bCb3=m<%n)AH? z5tiriwEz)T=<%%pPO-ccz~f5+B7S4MJJ<+{&F1b{kFNx9ii2o~K5PQ=jQ~!uyb!>9 zz6aT@TCyn~AIx=%xmE2;o$lSxp3IbJmdCdNIK}cZ0FN&NFn)X&fY&Ltfntx3uL6kp zVvmn+0*FxT@x3#!fntx3?*VX%^Vm<|H2@x80}u&}JwCn#AVRUn$Cm&&#gTUac)PX0 zkyikCd<8%xFgEr01^}aWz5u}E3jj>%`24?jTU6k^wl|C8&=|9+w$Jv)GVT>r8rImh z_X5e4W9%frU?`xX>oo2GN$nWusgU($h@G8H)qvOmov<7$E zDPF0etNq^hRP21SP+sHr-e=197`oQ)C1!w@nPGaJ-}^VqTh4ozShe}RzOlHdFiCB| zy#|J(P`W+g6bXGOm1$p5zqq|gKW>Ibx!RVG&B|H826)~q6nTv8RK0vTTA1GPU(Cb* zY+==CY0eU+z#9>MT5dIi@pj+qwEz1J>+HQs8~?Mh@nK#QKiE>k^1QWF(=u+D_)-hK zK9Jp6Zv4i0GiZz}Ob%n4PrVL%Q4g5baIN=J2!1OKo9Ojs?hl%flfA1vu!jtr;_alm z9yV;ccNeu)W7sV3A-2rN44Z5A|Nm;(o!%-ApO2I2ZT9{&=hcRmqunt7Ck$PPdr~Q& zPa3+&_S$e}^pv61wl|t0tTA*Mj$*e0ecDj8$ag93-wZ{IT*_JVGlrr?@(YXqkFqm? zlcKoWf6vZ>gCd}!lEj!rSG*AR5>P;$yNRPY7cPj9XX@tu>rfw8ZlEAX4&6ijrZh?o_-{ZKYrgtv=c@)-aoO%T{)xc_<-*j zu>k*%$13j^Q6_@-TI1fF(Q#IV`|^zI<2j>uu{Ph&r;6H~Gx~5o)}4!t>r*PAyaQ7R z?J_5A@$qV=EjIe#A}uDu`b8H)FJ^faBR96AVf#q+9ARwT^dEIB1P*L#N(XZt1#4fJ=a_T*KY)-%(jTR- za@XG>&Oux_Nju~BZ1|$1v87yQY!C9>&V`jNPZZK@dE&*mYykLTfU=sk_Lg3n5(W>O z;AF3*z;qx_rf9w!#p68lLizmcam{%12a#CXpwky8Ey;!<%(@#S{&j$j*^Q>2#GmMkWqL|;BIkA(HQ{m^gHbtCF&w0V7;^e^H$lT$D zR(BcLh!9Shhwz3MQUW_=!g!uu3$gN)Z=S+aZc6N&8mKuG1@a;r1S}vQncvTF`9yZ6 zfs0IMy2&{$=>#rj!qGHhzf!*V7r4&5?p8>)i(&uE3mj)Md|pSNXCsP&?PKBbTfEC8 zjD<_`VEk_yb2cq3x(}Be0_!GRTkt(Z9@xf-!M(6LE!NZK1ink-?_exG0U7Z(c>g<& zz%3=yVSF3**btTfx)}hM#{_=Bu!rT)VI2NF28YuUv6K@qGx(f6Iej+lZ=n6)3McRq z{g=`I6h68H!dwDF;Fl!<+`^S`m^ujav_oLpMQ;dTBmP}@zT=#+YX*GUU8n=|&wKzy zDsZaFlNaH0I!o2pkmGm2JABPxQJjUcy_e=`fs$KbJ_YVm-+{%nJ778srfEBIGLI*F zang&EnR9W%9p}d(aXA+Snhfzt~R)(kwY32&m>u`lN0 zGTsQCs9k`4DQ_e+wG$?D7t`RUjCT>JH}^0XW^)hoaLpC=9>yVRa}UelXz!sDu1j&? z9!hx+A#(%Q(Vf4UjP-G(ek)@w4eVqHjF}&7o5~_%BHss-$->uo!Yup;PE7RA{{4&>31M`5d2gta#6IF+WJ&J8H8N{%uE)pir|O}Uke8CkWNqRQD6s(hjV#+m@% zXU*9(GR!q_fjZN)yomcc(la!+gfSAaVs71AL`A zXH)L1y$pLrVD_jlg4gFPgZMqWbt2Ap=DdgVna3iWE0LTKGAeLMVCE9!a4GE8Bdn4s zIC+966B!$PO+5+Trq#k!3KK>M9{@*&ZX28U@6&IM;p5_T-I}ARiu6AQ9hKWILg~e_Jc|u>S6PS_1ISFSb zpY1Yq1otq&?*#q<_mVu=Ex<)3N8@BI!+MTkoeI-d6V~ZevmJ&#$3er%0Gp9u2X$It_nVl zEuBn|@59nWdLqmw($VHW!X1u8jyti$`a29T{_0$Rd9J@-pt_7Zb+Pq#hU;&c>+eg> z9Cm)=3NNufqQK{8fNuC!>z8TQ{q3|izWaM3?Z>^TSF9CpO38oU+A#TZY(j^%nj2?A zm9V3&4HH&#?KyD$ZO(`jfMIw(_|>957PTI*BC-)~4le>CaG*A|0hdhfDxNmww0Kuf|KMpI zJ^hnAT3aV~P06q-nRNQ3A~z_1wAg&GXi71^K98#6I32N6gb_{Zq^Y|v)-ll47VEXf zmgMqiA5L@N5>0jX_R$+|Hh@&fC7_Dwc&#vI7fX+t>}x4xYwka-KUUCo_P1xw-4(oWM(7v!@BGvK z&&D?WF*hf8^hSKI=&S8mTo76qeC3k8H_h(sj@^{#xZlai4V;%73~tE{<-yCV7cJZp zy6C(cZn$|UI6AbwWy?)J-}FK7%WFg9gSF4V+ts)yP27l#*<^;bGTH9|t?H&H?73Sob+??UT%Y#hS zzgAA7)sj%rrI+SR9~-=B)yCvU;pJ?SiSDt7rZ-XZSWTtGn5}*Ji`lj)MnqAN+~Q z$vMOOgTtgZo|y83%Zdza^Ldo*5HRZdxIM<4owOkai6gb%@`i) zK-jN1dvi`4hahiU)ozS4I{8q)z3Rq^Tf2?V8;5tiADZyoZ8F>hUwfQ(d(n8;5Vb;XAke`9X8}GsExiGAC(@{h>;8=Gl_>yeuF?iToMjHI{#TyO3m1B|?d^Bf{F@NWx_Tg)X zf4X#wF>T2SEevhq=^y!T`Vjx4bl)EwX|oOm{kGt-?_Kjy$7v6qea=}E&$@Q{gTb3u zg$_5DKjXaj&tT2kzXiv>mz#5`Ny3$@?%TO3bOF+jwMZL-J6F9IOuZMnKX_-(!r;U1v-;4&U^~*SB1AlcK)HaPRQV_djs|^soIcIBM;wTedC=9Vfpz z$A7_`Egb&CU@G#=PJU9g926JZP@J+$% zk?oJrgvBDE8*!2Y>)=BxLzA}b*%JILxHs6i_x|8(PU!I9b*n;a?+?C+(~jxE9jo@5 ztA6X`U_(n@e?IE^xu>7eb?V&M-06!u7Ocbf0{(sBTDS}in_XL5<``2P)*g&9h=&f=1-d&#mOXsUMqEB@{rdPOY=#g>fJ&X^e54|;J!^%vb zKcUYJmtT**YyDa4D|0toP9bqmno$T>g$ZX~Jg$?FV;~ zZ1ft=`pfQssI=koD{;QzoC16fmEYg{?AnjuxZzr3+Ynkmt7Ok*Aqv^>HT3b}qt`u- zljWxkeLOmqT7Cq+ahYo3hgL6L1P^bF#=oJD$E21IeSFyHODk!`=!ZT&YV^9dc-_%M zA0IJ#-Oa}C$kCVP)5mXNx@yi(@Imd-mmfik8)0E1#fh`$a$i62RO#y zvL|&nZ(Q>^j?9=hR~+avbotJkkpsD)qj%n{IFJjo@Xb>X}X=TFRJZMklM4qf~ zE?~BEHwc# zKB!41=Jmt|Q+dmK`{RfxmUqHJ%KAx@RygPN^rrHVl-AA|ocmLG$<{g-D989_6ztv8l5p(XqK`g#+oyi}sUrxgN` zy*~;z-MCA~Y3c7sB3~Bf#UWrtTKc=z<_2? zg4~ohInVI4!ZXg8GSQx&>bIQc8uAoc9wyW>e$=z`$MW+!s$KREYLESXA7$BWI41vL zTCrH=IOyX+mQD=qjAL z7x08C!hkcM9;=WAIQw7FI^az1$&>TPlU7T1~$OA(HsGqCeWo-Dx;a28ySm~BG5Ko7#h`w|Xcpob#4 zXX6;{3~a@h4WB!E_^|^|ojv@xExeEK;W)%NEOU-s?i{z}QCK{KV}z4%WaTDy8XR17^`}MN={#b7)U3M9H+nwgm(1G z#i>{Dz9dGKW5AhLjKa*-zc?jWwsV|K zMm@)SrsA>}$4Do%s?W)r`o#&$o$+3xU00M6H-o4@J?mrp%L8d z%NH=M{txl9y<`)OR>yoJ;S_rwBH2#Eek2L~7|+L$XQCkEJdd1i&&QB6?DJk?AGx7^8rAau*H;MDDQXW5~Ph`AG7|_B=## z6Ceg;K5YUWGMeYDXcO%3Z6uS5R}^uAI%X7cOqAH)U*L=)3g>!4&Rz|83C^d(-pxav zGwo=BslR3HIQ>-FI1U(a99U_AU9a=uRrPV%m&#&FdP(K2GWRw89^>G z0XDb+`ieJ`#4v_A{b-c7xEIQp9jED2CT!sa+e}RJ2u2)qHhq6p`f9Xt6Sgqs3vd`W zH>h0X*}*p7Tq~-&`>Ykgt;>;r#5Fi@4^3EPfKL<|>+Fk=QV1mDcp-iB*5Glt@!UWh zfA1CK9LUY-a6JbHPF>gk!sG@gIM5IQ$tz^PMp)V`#Nt=b>NuRQZf}oJPa1(9 z8G7vqCxAJhoMqkB)0J{KYnEl-o`~Y*v11UHFOY8MVI9kj61A}MFOJuRGq z^BQ|zT!eFkPA^kRaL%zqzx)sB++6St8O#;mlfhhaFAU-4npj&`vOSY4rWa~Y@PlU*0a;82g#%Bt!LhhOfERMkb|y{$`Of4q#{(ZteN z!a0xE!_|1b5pLn;1}VTD?nCP{o{2mNHz!ncK5|&a^%MG;pTEX0>wv#OfbFi-b8((3(4q;B^~b7jj(Cil!*2u+hd8c&S)aq znu;a5lBup%hr4&nM6%tn(G;!G=@r3S~^i;!_D?QWzJ1D zltI6b5w*kJgPBO=jB8am-m`KzQzK`GI~#|aXDsg}o%wYO>Aq$cHPxGN zxGzQ8#En5vqTM{KKu)f3xPQfdmfVxVXX&PnZ{8iintMgmbK=JJ$JyNs3$FLB>rY`C zNcDh=P3w`y{zS|yNOjM-+ODRT#kC^oWeQ(l-OrLsplUD~R?*`XCocQRvO-(oOvGUu zEYwu}C^hkSl8&RS2V-{}+JPlFINbX_4)>RU-EtfpjnnNTv2iNuNwFNqVu%M68z>0w`d{2B-}&8{ z#!ejLa4lsr_qQ5y5oIe^nxcU9AP)COiHfq5>+affEyVy1R}P|RvMyrL{pRUWCTZK`OfuMRJYl-HNlIQ3NvBb7Bxk@|4;G$+{_>xs2? zvUiNMqc26{=v@cTk#Kc*ffH+kYplB;YSnghyH4lwD0`qttGY1niiYYUhe~Lpq?PXo zr46SwI)EOhD~`@O67Mu(l>)Id<&il0@JLBfK|17KsmO`+_w*-YZAF>E4WxaQ zRy56StgCFIzB}Dh_C`Vmg&~bKWu^6H zW^Uf;PI7TUiK|6UM;2ywMyhJUk$Fx2?u#oE+O5!IddC(kS7H4{qBXKCxvak{*-6Qd zGF@+^J>DCI|L*=c(-@B?oW2MI0~@#c+`&k)v#ULoj=FJHm6I4KEbtQ5-4YqVrHFv{ zmOyXjBx1|@W5`rK-5xxxcyvW?f6D3pD()uInKa^;R~Twbofbsd)|H5~K%R+o4@6R? z-)`;43`0)}LWAj*B7G@e2?;kfgt0}p_x#JNU``v2b8*_-)KuxTcO{S}GjD)r-V;l^ zE~xQ8Z(^j~uff^xneKv^@Ptmf;aQc;NBw=%86bB7qJM%;`&X4LGL2 zB^^C7r-h}UyTyqO_QfDAV|Ik=bCM|*61Op!)ev4(I0a(?FCq5f)%zFvFlQj9V*QQh zi`iZ|r34q+wgH*j78~TFs;iDbz>A<@McdjWbC#qpY^a-;Hq2_Q@%ftOrK&j`uCI#J z)RomaZHege2y&$BLKIL8+PHM4r#F)5X^RZB7P`WzFDE#hGD9f(Oj>zZ&aH72{ushY z=c#u?HT4yeaRIOv}$oQQ%+B8d87}rq|?RW7U~AZSxJll+`P1@ zu7cE!1}7fv;1v+`+Y&1xn94#6fNCCdOxZ&d+TTN`-ab>?ykvxH8X^lyy)m3yH!}+Y zD=CM5>8rdJ2}QLcT-NCHw%~IMp8JA|#-;^zb>)%9+VVoDJ>J!a)~7F$Kq5Hrm-c8& zantO22Lr36$w(iXL|a*sOS}3^0m5hzS9q;x(y=4z%rSu%b7@uWTr|oRb?G=3)P(CB zGR@U>jg8e6jg6SV?CR)D@iCaiXQrvMEk|1`@~jP+Z}ShOIKkEyH{f(eIpLXTn-*#7 zYHxSUaF#)24)<(pY(_{}nbq;X7ot>eDjLsdicRAY!GJc=HRv!Ut!OAa>_lip$@cEL zv9@jjD;kq%#)57UVRf6v7T4d_!i4WwVDOxZBx1=GJ*^R}Gi{5eqUpXW;~|w*&uK93 zZ1z?Cq8%N$HrX}Mm0IE0Hs1CI?3B=7C;PkE0IW!1L~R;6Q;@v`Hy0IR(?&EnOfC8& zOwu9;F}6WJ8I3z#Y${QoY^qGhj{GpX3Dkr*;&g?GWPb|^4X(+w!bicqxNI3?_qm|a zVI3Zba6UVZ_uG7x+gGE#D;vTKY*})%)7H4=>T*{!v8w~Ew9?&+;?RY=HkH*G=uNbA zCDBfC9v8#a-u^!HLmiH-%6-Y61o~zsz->OgXd7$FoK&nElhP;?t$p!96a!QTf4ym% zHIF@eEP*?Br6uqBrdiFHWXF88nSV}a#Jutvh)pK3MjvI{1n;uun)2}c@~S$fFhSWw zUAJiwDVimn6%kYm+pI7nJ5luQ&>Y@}A$@{HmgS|UAd2Lf8eG!p2cSU=MDSzfzvcDd8vJ|OqG==3Q!+blvjl#O^fO)*irZQ zpzT1zW`qRnxn+AQo7=YaMLmkQnPc-) zY@A=(RMmv1p%H^kG71j6HCxQQI3OcLY8p+`U z2wDW_&)D+eR=p8Gq&tR{!suAoW&0$$bE~ULz0rZ~{#LYHcr1~D-oErDO%3xaYU-M*>S}%RXxg&K=|KIr z?XzjJV~Os5$a}n3BQc~G$zTMCK}Sm$8*eU7Hf@^8Wi}MuN!A2kF1z(;VRKDcgtAf* zhDxY}s%EC`>+6kkxlU&BnqNB?onfs{%wt(KVwmZNGTJO$>gs~K(u1MoK*lf$Ee4hs zrMlP{_adO4q}AuD?_#s$WvWI8C~0Ul%&IAbVyi4 zRn4N~ws&rahkI#hi>Cd}F0W~h)X!>+cx9ZrQq&$#=CtM8%}}&KC4~j``!$OtY!+8g z()SVTMe%pJ%B zk!VYjty3%>>o)yc+FLl>ScW#xmYKFxM+6#zt^sHY?C3V#?P#!QT4+>63`HXdIUP__ zO>?H^v%3XFB@xwis#RuGXi5mW19UQwwKKA(u-PGh*HzPiGwVaiLZAr)Yz#tLQWYtJY~gKP&b zc}Q-;i7w;K+99pyt=T{Ru9@FhQ6DawI~8f;0L<$zd;{h1{D!d8j^|xeGR-uWsD7Su z-&fOp6GC2OjWr0|Hcf0jA!jG_1dSHMzNUa`WoI@LaqFnIfjxP;M9i&eF2k!6%P|oL z#YEa39nN|MRKh%FS*dYCaF z3M4f-5ef__F|^yS6M_E3d&(4LP>wNZw(?^iN6qMwtzyJ>lz1X-rum6?MSC#i#Mah| zBevH!EjZg^=1&myrZmd<~=!bHgkoh znWH?R0YMU73T_fZrk;qeF=+}n%nGL;2S)Z*gW)}|rg^@nWyOAsjjayI4v;yFv^|eW z2TuD~-IjN?QGLVOVM`{|M{GiqXsakrbwM$Pr)ma-wz0E~YLpKRqbPO=$lmr|Q_v46 zHt-(1V-5x?@JQ(zqMKvnKa>wuBkD2c*EZHylvPz$VV`NX6VQp7X-V%UQ8g;2`08C_ zO?^{EQAt4!Ms(~N+@`MIq^c*Yp)VOU4ZRmyd2?xmlXguN3!7}wiDHIR0;c*UH14*? zOD5Zx_-PU7SV6QelD%3v!cRY$l7%%^c>%G9Gfdt%4-H@{*0F+FZo~t(-D9Uzgia|f zT2uYUY)7Brww_t4N!DHp)ZVRBR)-sBH$t1|hFXhJCNj$HuxjgS8!9UG5VJ?nt~xCp zTzc3D9Y6n|E z!rt>h^)2-b&1N`3$*%AKcIk(h_E*C4S?C{f8f_UqrI|6c*=7cdX6=Ck(QP2(0xx5! zfWULfn$_lX1si>6?98~Em7dMF6oBfr;zf2jgHfEKi%xVy*9M<%xx;Nj9zaLpTA1Qp zRPXfg`=Kk$2(CYcAz)gog~rw@ZoCB6)Y$&dYiEtXU}a9$B0QRmVOI?bDBFq^_z&5y zC9=Y;oMvE@fSwv^i1dT0Y*;WqZL%^x(p!O{u$KmQi8b>%GviZWWp`z!wPSIc7Qv`f z>M|~OG4igv2E+?9U9GC1e?vNL!_0An6d@FkS};-Ku2bCfT8~Dly8fx;D4` z_O`b6V=|`I*Wa54Zg2q056qlWOs%7N%otEYq_U%yL^RonP6sj&M{nw9V|Z5SWT3@` z?$$qvP$Mhf;LNourYMOz#F4th+5I#lXh@-O?oc;0&@y0!mCQMi(#k5oIEU7(0@-IO zyKO?ukUY}Eg+q{cFqBIt*=RYeOe3KZ@JW;;<^+S_R`GKX7L zPjk#g-oE#Jo zgupp2+m5qOE^Xq_XI92a5jzCIlj=&?p>3is(Th>E>E7``-NNi;AbLS7u%$(2taS1T z%uNf+eRon@1EoA9Ow2*{Qia%o)*Z?nw^#Qv8ogeb)2AL5Q!glMMpRoyxzVo`Ypz?k zAly*F+xlPDHlf&1A&e{-G&+61tn0Xw_qboIe8Rmm0b2_bOGQ!3^wM=err+A&60HfdyH?!$B zYPziHNZ&wJGb<2ItQ3-d&_B*x^4>Q97X$N z#dKiJbq%FeX!W9lMzZ#6g}ef5Dz+Cr^#h#IgD8qI8V1EwpP(j6t?UcBrWQkJs8TXI zJfAkGroK2_?rZYH^%eX3hmJNG>F)O_0eJt7)BG*Z{An3I%W^!(UM%%b^lC-`YFW+* zbCeP>6H?yInBLxYYgkQa^+wDmwBKzG2A!O*k`93C>pm`c!%zh`PbEvsfoH+kVoXCj zW9OR(q_l>(-5x{R#(K!mA;Prsr7_zdVd~llExy*Iq=a+2?CcW*#RU38pxAWB{ZOezBHT*OyM)uP3!q=gvM8Yv1;bQN1x@kU zO{EouG6v$!^}ZmQ>wU^T2zipzupWX_5p8X;9<(3G;9fi+Ot*6ur7M}l+qI32dh%FlL+Zn4wb^LJwU{`0Bxgpf$1ft z*}FA^J=1R3BCxzSu{3IC45`M(v|oRB_lihV#DtYGx4QFloGxs)3rjG48p8~igaHbH zm^JN(p7KCiJV;EO6tG$#-+D|=CRT5EE0u4hmkD? zEhs_gPD=J0@+V?_F)Y9^DswNK(wh2oZlpyc_G6H0mO%u8T!`5REBBeso}HV?cL*|8 z|Idj$tw2DjPhy(Iwt)U_I;~>lDBFn0ZgwS8-YDMaXuXaM)8A;ykPr5$X{@7ZW!`5| zD%!W-ecF21ni}-VEwoxCkF|{uZ~YrmBofRnxtNd4esysZ?)zxWLgt2?oE+QMEX(#yVq#Z6t}& z8HVQmRW@nGr5$u2L-DY<8r-(4MjG@)G)m=OZZ$%0XVz)CD{p*rYm(W_k{-O+o4&|Y zSo_?T+qGG)oWlhnkPVH_Ld_nUjy}#p_4Oi6m@L8=BwfFgcDTx>WtnY9P}b1B526J$ z1veV+>x^<^6fP#hJGW?mSoEWDqmDoW#U^?G1z<+6(A^S+#GWw)WV;>eQz6_qQ7qj- zuhr9y_^jH*C%QM6Vf78vHMYZGE#o9B=giZYM+K#A=V!ExZU6fC@s^u^O$CNMEW+% zs5`QAcn9e2ZQ>v_q^qt}Bb{(cX5K24o4QZ4!VhWuoQeI0`g6m!w0n1s-Vl!!O8ccz zzD)117c}pgW1$X&C`Kgxx?eE}0Wi4?noLS2yoc;DIjUM41b71|dDW^}ZKf1X-K{WY zPd6I1Y^(=OOsiGxnA(H{Qeuq`M7uD92N8`URA`6Nnc1`eGl}!un%feCs+jG8Q5sv} z4Yi01!Hi-XA=n8c+#H7@_1=UAVsa6A=s zY{sfnOr%EGC0fbC8`2pit~W%o3Ddw=*^R97FM+eQ-mN;Op)RpnN;6tEZ9={8-4l0( zmXQ{X!p4(1{L45@pO+!0Q$FRClIb7p*qE(0%AA=3<}*H^P(cq=m7*_#;Mm382hw@b zR8`S{3fovQ&(`G5E@(YkJF&owi@7M8L&I++3+>>LzP8Mcq@jv21?+%5y#xY`&~1pQ z84!@uHHM8(XZwnN=)EECVSof~V)Gy*VEGpic)`zWYCzZM>tRvP+)mc>)HuJkA&fU5keSjfQTXX&4;ICgy+8f! zSXt8Pz3<|M!1kxK8WUfOd>UROI%~m)Pt99d-GuwXN=;Y8=e@NQ!F^(hL-zpk)f;De zaZvwX>`5bL^n+XToGTl`^^Kl0MK3e3VI)?#Fbgu15%#LyMdi&|Z9Ue^L6OeQ%_98+ zYJ{i>Nl!NTt}RW^JuhPyi1t21EM=82U{V5KjBMv!Hf25j!$7%>Xr0 zQWIDuQlvAA2`96P9IHdP-pweG?6N$!vand_l``Bh`lv*=uWVsWuWv12O{2N-Lc3Di zE1z1b?cJm8haph9O#v1-`HCnX`?+-ub3JFZ6juLrpw`z5xw0C1L^E3l(cN)HF>aTM zQs`4(Vk?yfJO}svu>D`hX^ZxmDRZm+j#J4jncqK2m5xDEGwuzQFKiAMMYytUfJ$oY z3WLc2F5mT1S|3g?>Bs%eF^V}V9MX%cFu8;@`sQ2aRxDBzJYba`cw+vw@Ko`dRejmv zK(_~JI9opV(!v!em?o(D!-D0MU zxfZu0-rE9M(k<|K%qBO?&F;4ZhJEfbv%=Ke3zlbK{}~LcGR0*G5dH;FRKc5?mLW@d z8HXWC(KIM|+-V)uRrMN)6a-^xygk20m@+Hfp%Z7zo-uqVYb+~I=Xm<6*_fmGTx9{4 z!+XKQqfgR>$(M<9XZf}3w)RoK*J#(v*sd$91lux+S(XE6DvIm~Lk$@x;{20r^<@h+ z-%I_pmp~RWtRu_{4&AV;_b^hI`#vK?GB_1ST3h|GTH{Ll=7D+j=#{7xUIzeMT?pjEh;JWwWlm4cprjG zN7FZGpIEqjq12%6AW?PG4UV0cRScK~zbw0UB!*FO+2)Ov%t(ZeyL8%nO7qIG{x|dWVPC?rPRAYB zu%S-GT-jfeB-3PsMAjNMW}mZGFg6HX9LCMrqgiK=x&?Ql*ByYy`@7xgSXbr4h|DX~ zZYD#y$=NjJwHC+nl@u)fK=&Dqcl6@1a3zt=6^Zv8SfZ`VSW1mPh_Bh&H5*>W7#X`_ zA!-^%bm(d!v|{v!l?_~u3|$yiGg@bioQ^`)Ob^<#U-2@HnKv487e{-ok{4%r{X!K5 z)?WWu$V#2IMWcjis*};&MKDq81)$XdX$wyB^^z^7n%VF1%my0L_B0O3iQ3(#r!hwDH(m2 zQ5s|ptZea+n!!|`SiGy-m&f~w9$4;R(qh*pm{BXTBV9bwtvBDivFf3;tC_yBl8BL? zYUV&w?n(k&=8fq*zCn*M1>b!@o$<+7&7~^jl(j3%%Cg_0x7tiRAHL9r!j5)c(|3cqUqwarMt+AR9l@}MO8{&mlh!x#x6Iut2ff&GKSodU}e|XsXh(Nw~V&NamVA_LW5r0SkG{ z{+CQNvw%D0kiLm+QHFNKE?8wjgzi`K;daR;6cl!H%za_P2v(*uG83yB)~T;Cd7$-d z(8!pXEIZV*FAQ<$=i6B!*@^A8mpXPCpOgXUGTpL~sfV^LLi#CMJq_PdL~(M*olbXm zE9yav@7ww1YkO0i+CEvjA!Ya9W+^-o-?)Wjb=^Vn>F$}=RG6=VE_g_ zBPtuUi+l_yH_MHhk*$-h1zcrCTdw=Z>K;8{TS&d>FuQQsv{xxiyk^{R8I*+;4QN)_ zI3>~3WxTqKISI2ypKX4BQi@VDn%aLzrLv`m96>gtZlHhZaopE8y$r3ug8BN2LP(6Y z6|*Aq8ym1)3g+mj5#$Zo^{G~T7*3>y$&oF_0b_)N6#5q0M&XO8*!vbDYE+Q(Xm>YDywI$Z?b!>NAN0#(FA(A(>S{h zGlI40WSPQ;;gPQuNjn-r(7YMoK1^?1gr3_h_-~`C$$Qp|N(u`6cQ?DD4)1_TQfk2p z=gt(C^|&)QS*yY*pW?0j7}gTI(rwmAovU2UYdNMk*!Q`(sy$=U6K#EZItmrleMNAf zE6JDbF0{+M@oc!kkgfHdMq_2huKP*0wmtSTu(Hw&IBILkLcu8J}7enp5vR`iW7jFM3 zAic-EgO|~}?Q(MalG}3V5K-hzyUPyQY7E@BLcEu_&Fd_g&8d~h(K+hXFjLx0I9B{) z5qBq|G0;FQ!ruF6B_O>)YQv@%RDS0nOtYfFD{j7bgUu!=ZYf2>WQS3B{8h4Y{e<5$eC7!T7wP8;ZRfi5;uKB4bxW+#@?bN+5a~l<-lDv00F-DfH)~U7~05 z!^&b@a^h2>cuz6RW!{*xWgib^mKrCjiI5Qc_JHQBDR*>wJ6yQ)v8W@6AA1$qX;Y3a zv5wem8sqEvS(oQDXPRva&PtPMY6> zKA?Ycbyp9Ta9Zj5v}yguvgBk*+uV}vGyDQhU}b1zZZ1Ejc#PRy%>FwG2#*Stjmj$@ z%DG@vDE#oK+$Ntp_qv07c+|-7s4=CN6i)*TkNCS@80lU?>NnJ&e#E zLuh-_Y2jwtG3@2$U4ukaj@lZi9U5j6m6JrAWm##Nbx5!?MEk6?lpZqDcaLVDwMoep z-6#~!Bs>bsPWKE;T_+jwdy-l7KdA*X?~`m-8f|I8f;(pty;vLbf}+n%eUWu%5R>|Q z;$2H)m}{B@#SPx}WORj-3Nwu*3Xtvy*)g$CibVKvwMk}?0oP37n;w%|2IZ9^8?_^T zV_$y@1#2WWojll4YnfpO9VsSmGOS!1drwHCGYN&9FQPe<@NtmXB#h`zLuU=;qc3nP zm`>`zg5o}3{{E-axhRu|`8<{2oLdkchvQ@%d_FwBf&*S1cl*L~aPID%hf{7rXntS9 zf8SPv&ONy5BHk0ZWBF!y?vLS(@onPg zx|PC%drrTdU$i?KyVtpHXTidMA1?<3&aNVRAKWUEK{H(qINWP+>Rfj*?0kDkx^A^_ z^M|)}O2Fh9^M&?qcr7^RHEurtWu4vs9#-b(hKHS&Gs3$A;nl;A;T?j*4UhXF^BN@G z{7$+YdnW3fpc{|XqU&!f{1v&8!Hwb3c#Y^jkC(5&hO@A9e|b9jFVKI#&eVW|onuY< zu-UJdz8i4PaQU4J{_@vbH*2zPJbw^}FFDRh@K?HQ8cp+TiUIS}q7s9*4eTXo- zZv0S=KfFPN*M~h{86K*N7v50{&rMSw9^|3b@Sq>V<1s$V-^Fj(??PnzJ4OCn`|rb_ z|HrWSJL>@c%tx-Qvq>LM&xAk!eY`$9T|d~Cx%tAj&zB9(lYc?|bt8kDdrGQ^;>>X# zLB{u?o*$3%lW;J+F*q2fKfIEE;v=&MXb<2mkV zu;!$HK_|2E51NwecW22<|AHA(6vIC@?TE7=dMlRw^i_vCU(WDxs435^|_%)iJo|0&D-ah92T>AOFM&pol-AI<2_ydTX~S!RAh&;8MTNtXE{n0arMb$NgP zmF0eOmig{1^P^ejr?bp|f!URd@uf%yLcaH7di?u+(|kJ8;r?i@%`*37nJ>>WZ_P6A z$}&HnWqvQqe7LVsV*ICOnai`xZCU1vv&`SjGXFTs{HrYU>sjWIuL)y%#%Gz&$TBa? zGWTVfxd*!YV|d@oGXFHo{A`x_!z}YCUz5u4CS;i_vdrganftTMo3qT@v&@fVnP1H^ z^YiiUkLfww6%cVwb3vAQZkD+v%bd(I4`rFZk!9YNW!{lxekjZQOqQ8@pSwS%cbKnB zqM0A8cYidWnq@A^GFQu74!?(?|KT3)?vK}ZWSPy|cTl%r%UwHVW?%nzCRJnGC;Thm zzheF?;y;W6;b1HajqT~Qm||>=+ZpE6T#AL#^lW@go6yv}Z4J%W>2ac{LQ zR^j4$*VYE<1$QPEWd`0DbN%_1Xt2xPE*MsryXO?1HW}k;qz+z9l^OQlv7dwSZD;ES zEEn?%4sTFqd?GyBAIC!MEPpmh<|egGx<6Y?C{Rm!-=8t}%{j8HVC=XUmL?>-?YWs6 z;ETtw&P=tP5XRdP{Ol*4xv-JiNNj+NncG4$NoC@ogHKzzpS%0k(tZvZAr}9K5dH2M zA^IIMLM$x$4{7wdXM~u2p?B90@ZC6eR*TrNQQ~29=2xMrQcaf8zzkm#zI~ijEvH&0XBQX#=2(n}@6jg7M#n4Sc zb{l~qBwEr6IkH#naWd9oy;d}wI6y4iNgmVdra5s>rJ5C;Cl@S;~&Hx$S zVw%6;IBR5nm1Ybs4~L9F_n(2huU~<@FAlGBF(BMXp5-{-5l15fMnFOOB@z<>0Svo? zXG3p7o`ZCeVdzH5QpYJI%kV8svK(U|vI5^-B`X~#O3uQ!qR82fvx2O`*W<`J_+}3| z7vDJ~tMOqt5(Ce>$y&$RP1ZTiFUfkxd7hl-IDaG?@XZ?%gVcYMO-S=da6a_DWHV%T z5}!^wjl_WU404gxx{h4MMfRxyJQQ> z0XX8zj`J9aA^yKfC~w9=J;8k6MxKiN8U?oEyW3g638M$9Y_~cT2 zMfM0V4*en74c!oVCelInAil8(?*zmH=Jw+2m}H;hT!?SnL#o&W5-ZCxEySq!U1yJ4N=?Nznfc5ka%f)Ys z-xYU=4~xGRUlHFCIi_d0qtNb%Z1@vq|F#Q^$8#&eK(sCa~EzVr_FugH9Yc&b<^ zP8Da0Wnz_BCz|h&BfRruj*1;(w@94_)5R~FldHr_#SP*n@mlc)@n-RV#2<=xi}#DW z#XaIL#ovhh9vtI;N&KVurf9yz4R?Njj{g2F2GQ2jJVG2Tnookm{!22C7f%#V6Z!o- zUVnyowpby~75QB}`dc9Kn|d_2id`bVpicXK@gi}Jc!l_1;y1+`#BJgaM1Gu`;oU3l z68DHth);_zh_8zL)&Tl`S`R2&Y0+}yu- zlz6N-L7XH`5zi7U#agjhyg+Ohd&B|p67e$eYVn)mjp8lh?c$Hc2gS$4C&XvO7sWq` zZ;Ky_pNhjV-ZJ+u9wiuUjn2T{G^Wk9eF!5M1Upz%D5T}SUM1J>`;mj86#KmHZ z*eUjiDUsh_<@HyHSBsm){}#83w}{)tABp#hkBN_qzZRbpUlQLE-xEI)KNWK^t~U82 zjuDR%zbu|2o*~W_7l>VAk9eW@4RM=zm-xK+M{x|s?@Y&6#7W{zv06M&{Hl0`c&+%T zxKDgh{HyqhcnAjSjPHx$G;x;LET+UE@$2GE;vM2o#V5qyi*Jel5)Xzhz{D$_BAzME z5ziIBDqbjlP5f{1R`EXZ=i+b0F5DyI>lcT_uZuT{cZfd~pAdg9z9s%kJQ#WrhWiEa zB$0X(+EOIABefoy_)#Ne6d6<7n{U3F(s}OH;dcE9pWS6 zQ{rpl2VyRCy(WG!Un~*J#U`;$Oo{8n&Eht3hxmy2l=zzXftU;3vWZ{J7fZx)u}N$b zQ{p;tv$##%AwD8LCB7zpAm&16YT_63#S*bxY!chVl(wU*iLZ$th`H2_ zv;2$sVu@HTHi>OwN?a#y7PpBz#7D%Z#Mi_R#9Zi{P5ffMSR$5-O=6pv64!~F#ckpa z@ip-SF&DaR6Q7tbmWbtIlh`Jv#C76kahte9d_;Uod`%{MgKNcSqpAugc-xCAJ*?7i?UlAvXFNuE@KM@xnZ?EeT2gPrQ+r+!Xhs1s2 z%i`a}rhFUT!6#U@ii6_S;=66KA#syP=Tq#~DUN3GJcZ!dTFNkl6pNJz*QT*aWafVneE*9hBO7TkZdU3nB zQ+!-}L3~U6L>zgl;uj~1GsJ3fu^1OuidTx)i`&JW;^X2A;#=Y;;>d}LUz{k;5Ua(- zVq9D)UMXHLZWniokBcveZ;79XBTrNO;zV(VSS>CV|JYFmo%fwbODGrI( zh&PLOi4Tjv5nmPG7rA!H#48>z7K>#fK8e@m(=cVZ%R694{7%VR4=q6_<%?#7*K&;+^7d zai92#_^ueJRQ%$2u}}<)^TepQOk5*w5^oak6nBgJ#8&xJ+ClZW3=2?-X~7`@~nocf~-J;upt@ zg<@F5M|@2=jEc*|HR2}mCh<;jx42JyMSNEb%u)Q}c(G6ni}S>&xJ+ClZW3=2?-X~7 z`@~nocg4V5#V?K*3q^d~$ksnGDlQY(h&PFMio3;q;w$32VxU^_isQvXF)Yp#qvA4g zjkrm?NxW0sE$$Ov5#JR9HHu#xFBXc}SKi*Y7!{X^Ys5|BP2!#6ZgHRZj_B0daL0&w zVu5&$ST8OS`^44aMscfnhqz08QhZr_M|A2GznCW$i06p);u5h>TrF-Cw~BX&yTm8O zm&JEPzVOceWsI07V#`Hie~wr$E)o00)#65RtGGw}jrhFylK4mQP4PYPGx5-QHvTV( zCyP_XMlmY(iW|gliQg0N79SS(i7$zN75^oUXt41gElvp)}qfN(AVu@HLHi%KNPh2HlE#4q*7w;E;E-l{2%ciagX?n$Tiq3 z|A&j?#RBncu~s}^jEfhEUlYG2eqUU&z=j`KWch*UoNLV!#A>la+#o(6{!DyE{6HLe zo(<39Jxj!QF&t-m^%)z>M@%M6nTYR5H z{{CC$oW<5WhQxJa#V^bLL=y2$5zm%;nOH0P`Q+hPM@u67PTBX!evQnR$$Xv6-ysq2 zEwaB;_CJ>Sr!w!6`AHJtzbL*T_xDJI^C5|JokTci zlen%<_KReHzSt%Egt$ufL*fP!*Ka0~-mT&fNTlNq67lR1ACmnqWd0S2>who)N$wwt zpOLtp?;OzI5hTL>G70={T zJ`N|5o-fIMg6vO~d5X-_N%*Uhxrs#l3uWIX`))BI`-@~AA`$OK@iy^E@ekr>;z=#m zf4!Ix*NL0N8^t@shs3AEKa2kq4{5dGepx(~OgYXQ0TAW3JO{)v!m;m1jRyIC)R#fN zw^Jga>nh%q1d*{U*HGBAQckze~hU zF)ku&jQgOtT3jbyDQ*<66R#J)EB=por+BycfVf-ynfOcbY4LgS74eVa+v0oT$Kt2r za6VT&gM-DxMY9(W?2nb1dwI~`DdHsYY!O=u8TUD2tvFxg-X6SuiP$D4#pU89;#zUN zc$K(WyiVLAa_FJ38b6t5M(Eq+J5MZ8VCQ`{v!BK|`BmH49g2k|fB+v4BFe~N*i zz0YCdNO6pKwD=|Q6mgPh-d{pkr83VG=ZlNQC1S6b6o;!e@LpM-dREwgz)3Fen&{XVTjWAQ%mA@MQsY4LgS zHSu-vZ{qvn$Kt2rVUYQlFGq^zeI%HVlet)&Dwc|s;sWtJu~qC4dqndd62e_8^JU^y z;wEvcxJ}$4n)i-y{T`WrA^uu4?;XM2yl({lMfU#`|1IW1X65~c#G^&-A3*!##0lbQ zVxf4BST0tJ_2L5YJh4S=7YD=(#Wmuk;+5h?@mlfQ;;o{29|`F-?<0Zt$$q!^sQ9$_ zy!f*Cn)tr>5AmQwY(5+!eo;JDJV88JJVTr*qM336_?JyH9zZ(X@jxE^p$ziJd`I_a zpNnY55w3sGj32-}x#x=~i4#RLo`63yo&cxGeug+(tQPCVCUJ?_CU%N((H&>3lzFwd zPISi^n`O=(Z)}zQHt`N|hj@>;Q`{>)Ekv9pVo09&x9*SA1N2QhZ8$PJBUpS$s`=NBltiNc=<$;hvfABgHY|Sdsg+ z(ES+kB$4BG+Gme%}I~9S60^Z1!2ed0gf`F(s}R*NIn%SBe|O&Ei&Z zoA`ZkyLgYdQ_LPe?UnuG;&b8);>+S|;_KpD;z!~qqN8y|uIP@V#>zZSJVwkD&At!_ zqd?{oahfj8nR`O8n z>mrV0y+2azDXyC)^9;2Iru~AuX}{q9h}_+F=opq;xSMtW;bPySl1aUj^W0xyanTti zrx#3_dPZJeA-<#Q`#+_mBrmUIN?}oP5q&Q?cvVGpWgvh6^$XzPq)m?VdS|Y2DKY;~ za!$hTEOZ}>gG4eie)AVJ54|<<(qFGH&mXtGDgT%~tDn;ro_kim?47;foxP^B(O0lG zY^cs3w;`2(%!V~1(HCx5cL$r!J>~g)k`5V?86An06l{;f#%G#Hzls{(A>T~`A&uu&dVD=&L5+F1io{E31jV$s}RSRaXY`OA*z& zoch}W&id;7vFlU$BN6LK8?Q=Dpx3cTY3>=R{4pCwtRI;_`l{Us8EH7?(p{skc$Vi) z`6J=&7%vdrnO`+>EiTJHH8&rjhu)lT!oO!V zKCm#fGC#EHr>hXw=vtiKXY4*(J-X)E(La3XzC73u?aJHzQRu3{bJl#e3&!QSKRV~+ zht?l9^k`tsW4xoG-J$96{M^(@8_qg)M*h%et5@DK^x3L=*1+$on=buq^rhT`#)S0d z&rG~S<@qB6%*8e3`C}OZa&zS9OAlpg9+`MS`hX!)lhM_4_t_ zorPz^YWBZF9|w@z`Kj|zNb~quSju4UZ1_6M6l`uNI{C?c z9}RQPK{yY=<{zKEu@q_ieAn=&$gq1ERG|O*p?fEyygB{XpeUdSx1m4<*O<~Za>^Nd zM_)R~+ePWMrIx9%rIu%JT#Asc8gQ=Kc_NJqnj44S8na<#e%|Y!;Hotb;}JO{t*xbs9TSi0q2QVU=R2l6YIU^`_Ko z2c_|L<~BGA{5#sjoYv-o47Vjsc}+A9yvxbECk!&KvLS32_zl^0UBa# zFGm0G?>XnrjBMG^{`bY7k9F=nFVA_-bDp>JoO92dRy5m+RN=IuIaZ_!rxi6>kt&>4 zl(iyNIIU=|6{*5$Ma@>E3a1q*i%PAMAiRgwOU_qMsG+<5OE z)F6^r6E4cyyhgoZ+40_IuSn`1EcW|g>pEzMU6MMjqejnU*q9B6zJ07jOzaEc$%O|-pH2fbUDuhN^UV29KkQC@ zkY-=}RQQAN`O%-Gzb#>`1MJWLYQv8ao5pny7|3owwj;5$Uh)IfZrFdXz~1n76jx&^ zUu-~6G|miqx)6^1o-8B&o$r~xra{!09ZzS4WvKyTTff2fyKiG4!S>Ikg6&_b4YvK_ zk)MQr)Ij#IvbS|*>y^<&##b!E$`|l@d*wA9c4yOM{i$WWtOkv|{#m6)me>DUDP6?t z9ro(s*OT$pO7+>i{&{uzTr$2^DPPR%=E`e^*T1mWmv^xStPuip$otE3l||p-_3QSE z(NcL!es^m=olWIivWtSk2udbe1eX18%>f|Te$QKrr1{a>xaIS8-B}3oekNIHYTgsN zyf^wgYSmx_u@Qd@49ce=r)V>UoPtwDPT^lg&W6_{r|45fPK|X6IW=8X>AsgBVAz>mu9k6Ln@@;QTYPI1Pl#NrC<=(|ru!BlXeMHv*>?2-*SAK6 z8wHGtT5hZ2B4v+G%*0iBL7>~Ri`NX2*G!Y<=$ooFI#G{xUbLh$%h>wgoO2B!+t8bf zJO_mv`HSc-jvKF8SWF$D)4BQaG-f9p3wP&#GAq1q^h90$>AKOM)SdH#aQFTb`C=;n zWagYB3dK4i<>W8ScFD%goNppaCdkgy*^zxZLf@^y4OdZ3>$le;jz{Y zW7U2BggJcXCTJsaE{BHotqdHBrNc(2C9#p`X%d)=no^&nqAlB|nR2sNx*Dt4Cpj>p% z4x!O=H0ZfrjB_%$;Yl3Qihc*bIQ^Xj1(ol9=AYLLV&1CeCAw8TEE$xc3kr%;kL4bO zoFuDSEqREy^jPk9cuS4tzRw%U@A5|G!@Sjw<$jMhl6}0*7|X5Zt!^y0pSSw4+<)MW z%mch-#&VzLZRS|+5#G)j%l$rYv&M3d@i+&bRK{1I|o9%AaW6P>2Taf!BHtY-o=MH4EY3vy{ez>Np&H!JgGkIQWu1Yl_0bWA>~L!ogSU zSulS)9ISzDaB$*V+d#>~x>d;g_P2J}v$elfX#4iJ)_`PqxB9Cn*+V8AJZujQ^kol?AZ-t`>CqnMfUZ3>(U(1B!IO@nPtFYo)ArCD4%XYl zf^aZn4~xRV276c>4mR3DOE@^2hq0W&9?;?5YSZ*%K2gY*qNZvV?dpF7Z#&YvX-ZPeK zCP4r$C4uEHBbhyxdk+cRwt(b~W4VPS3&wKqC21VX{VEA8xQOK4W4ZT{ymu`3Ya|zq z<=#*7j0 zvD_y~E*{H$isVLlS!b90^2T zPr{`BClZMKMKa()UT_jAv1`-hbJPA|$$0SgGBMG=%PXfAMAYmx~g#-$AlfW8Z zB!Ol(kU*s`k-!Bx66m>!gxS221S022nA8FZgYF?=8hc5Y#xIk=D19VwR!9Q7-9!Sh zA`+&*p9DUONtlNL5(siL2@^g@0_kocVdDOTWae1zRublKhy+63M#78@lQ3gnA%Qh+ zCxKi4lmyQDGZJ{|zmmX9caT8quadyDe@?>OevJga-b@1P{{;!m@Rua-9Ls&3gjuGv8zeC1H%XYkEhNm}-;gj>TS=IeZ6r*<-6YWZ zZ%H8Qw@9Gi-;qG9dq|+m-;+Rs?Ieu$UJ?ejgM=}Bn*?;fLjq?1KmrmwNnn)klE4!q zBuxJ<5@xzc!laIpFn_yAn5yrQFe`gVn1K68p!FCDWF04gf_q6I*8L>Vk}lf{y&kx<^N0qL;p__cz1#XHa$cFM?Ogc^Zl3vK6{D;mU@~5 z?)eD`jPg?wc;YY#(_bQCrjL*?sn3vnxOCI;$;q^t^jZ=yTSr2-pCO^!>qvsqImZZ09rf`d)+^!I zZ*F?F1$!3_H{k|GI~0tHa*w}l%3?np!ZlZ&hNa+lEG%T}dF?q66n0&Rc^r*;Z^uiR zcRcLRY9EXs=fE}!;;maQCdO3AK2E0ogk^itt$T5g zf^B>25~S0ql5Ym~`vhcQr~27es@vkm^>iJ$E3ae~2P6iw-)hpG z_3En3FBrI&f0%lRfv6f$nJw9(K=vD6LC@w4NIFul*_Eoh#>Mobr|=Us;m6Za$Kra5Gf}}|`-yr0S|=aRFzeQ&Wp~uMJ59c* z5nkUAu4{~3UU>cNaNV3}U^4}go92GwfoMQ;1`c9~@L;@b@{ym;I~k3LlNp7;Dy;k| z1^^2@tL843KJ^y%-t}(&Zr#k^XltLI2XqTaG@!F5KoHkJhY6Bkr1^p+KF7^i(Eok% zdx{$`4n{JmxbwW!{*%5&(60c9@2uy!jq`XE5I@#nr2V{P-lw$d{u1~WzE9_Xo#(Oi zZG(|+8o5b{yO*T)PcGSM2zFoTDZsmi9Q5lX3wcIX*YSKuBi|fQAF7!GBZ&V!ZICxl zpAnNBH#4J8*Fp+~#^UB4;3H8tlcDV> z1V8+RlfIkO{nW|`&VVF)O}=HFiUcIii13Xn>vs^^o~KiTztvUlzM^I_XnQ!g!jXaM z>M8VZCp}S+9f|v_aO+N+-=hAG+{53X=Kx0`q5)ec9~^ypMm+L@majW)s_0CN7`4oc zI_IT9VnV>zWx&rdXuWG0bV8i{c>Ub+OJjKb9QT46>3q+e zs5_XQw7$M6T$haowEPe5&0HN0Oz;#9NKN(J9~2Z78hx^M;dAlG0wBi&>n{bVp=_G` zg$Ka=u#j{-0>{rLJI-9VLr1wEndotp2zqqUH`GzxxczSuMjSm<7q{KKV4Pf5+pTGr z)VqYqQ)ZJ(vM!nH5)e^Yt4rEkvfL%@E?Mo8YhAL|C7qVEotI(ZJ~`fYUZYRv_%y4O zMd6ZR4L>{>e0c#Gs1Oayvq{f$U2j2U7^k}lKq=J?8`-a!6JDKWoO|e}XR_;8*`Z0w zg6&t%>Kpi9%r;L!-#{H>;OXMNfj8LGHE-)1ej`uOKnI~SDBts|>T`HdZ`i(f@b+@S zxDnu~u7%(rKCT;fGk0$OP`Yp67r^fucuBq7dtv^``o7_pl{0*lzqA%!*19ROW}qs5 z5AJRJK>o?vzF{HNH!LKnEY_Y<*-0LiKVy)EZQro4r?MDcm4iYzNwD3xD10FQWU6m? zhE+`4-;;)p?h{fWUCy%Xnf7AvANS$3oSJ|)Ef$o>ZQ_k8{i zdSo_gT!mR2^oq6`FJstrY>Odl>P9DO5dhKSSDkSV@5$cITimEK{xu6HHyz69^)t2k z-F2|H#upDr0zB`>D~R#e!SPu-B1E_)`wCSk6syqSu-iq( zEwjff(86t!kYUBZ;4^8yXkbV$&F_vgAB%>ie^Mpj7HJFSntEp9Tpra^{>fnU$yxNi zQ^iBpZGL2t8pX|ja>-;g)H}DHQ4_WN>CeFRS+%(@!_yOL;LWd7Ls82&qRwx~EUH%6 zeMAQIYnx^mOF8-1&ePcB!qC3^7t@;Yvzp@I0J!JRXANCehQ21G$sOa28=NN+6F^$oAk_x>uGC8-3 zV^j4(6*@1UP;jGd`gL<2qBC1hjdZea3F@kuqOnpO6|EwI{wpMB=B|}4d`bH#(SSMb z1>>-~!m#);e<&C|G|SKXC6kgF&$-=yQ$uu;x1!K+nWInF$L&iRd9zu`+#EO0gF#-Q zMliBG6^twvKL_`AGv7|qMh`Wlj&C|NSui^#Km&s8VLVnaEznA@-I8)DjSm*6C z@FYwIdbM()cT)@f4xeqKb-h~3#O>c*ptC21Vd z`l#iusPnFL=$sT!jqbZ}f9}f2!EqxE*EOdm!;{IZ&>(8r5w2_V)DEw2jmmA7`%%;- zP20nh)`g!^HN3XmaCN2O+HhTGY2sxzU34pBWrY+JZj!<=Wh+-&XTRX#$Em{7g}s~0 ze{RPn!d|VP!U3(C(Bn^0gg|L!ReJPaCMO3M7QNq?3vMe?B0&#(ZH3q?MPB;Riv}ke zFw$<7yPQ9i0@M?#S%Twa&Z72PUIBe6LubM^J)Pq@@0?=wT;$d3FXWGxB_+C(f)5H; zf$MzdWt4v1;mug?pbWBUF0m#Uk@({o-*5c!^mzJa3fKp{IqlMIvwb?p(!ym@;qt6X zpFDx$7;@6yZ(|3nNxNGjYHtT#GHKTVEWZeM>s|I@8lZXHZYCB^mhKh#bY99yTF?Dm^LZ4NA(x|ETr*mlC7M2ze=hZQ=lZ9d)~C*1 zRdtP1_bqXB4B8GuO3|*=$Rry4#LO6I*8_6<#hTRp(N?J%C}#_heuD_pimnSMS;sj7 zYjVs)IpZ8$@h~l{b6c|Dq%U1!IxD#1`Jm0OJ-i|J%#bWdN}tgjI({XTQBUUuGtZ?f znF&uX-*m{jXMneZ&Uo85B!NoZB({B{#lNpoI<`r6VsdPg3p=+x6Q_7g-LUreMxRd4_fd$l z1vK(D&W+mVro)TFt61>Q#TS{I2|uNk{!@SmuhJ5!DCo@x`CBvZVAMD-YM+-5Kh+Rk zC0}MIx#hgs;Z<`?WTRoJsZ!7LhR?9k&ABzD3mIFPZn7xzw^|UZS5#vxvNf2V$4OF4 zT>8aEZ*TtSxyi|Sif5@3L}_;Xskd=cj65Ln78>i_c`nbx5_R^*&6Xy{GaQypbp~|P z9);6v@6pBAs`F*7$RoXOR??rnn*_1~{EfuwYT|S*PVWwO4fV>$ z4R#fJ-%A=dKETnLl>k@{fO}{Xr}rU$D>%y5mR+8IvMxVS7pDi=!(Kslr!q%R)Q%pj z4Ikru6`?w5yN>MYXm~SE!M0;{-Pu)jOQL~0RnX4%_kbujdMM3Hhl{Q}ax%X1B(K-f z_wxLqSv;=gu|2q=BYSPWRL6S@?<-u9YEeWU`R(EUmw&jVJ-e#ALD}}aI*50O(jD0j zaH@a#@wn}yukw_Rdbfzk(m7y=YH4D>y+P+l*}Tmksij26I9HLIQLfAKyUaE+O4>;uN-b(ngaJA4Ik*b&f`aP9& zXIG3))&grM2NW17nDOR^aL zeCsNXb9CfKgC+Ze_L+tbZ^gSI2(p%lxZTU$eom@idGQJch-a zrFSvXK@m+nTe?-_?s{iUB|e|ulM8n3$Wa*VS`h5IYco%A=Kb?t4R&p8vO~wO&ih$R zAdj*M%J8-0MFEj`PI7T(i$ii5+80#*WPNJ_Y&98kLJzD8N@HYD z<_HUMho+$mA*A+vgF?yOT4ER=ikhh@r(4LXK^1;_t>Bk+kX65^l6DS8>F6*Z9ArxF zZl%PdxMQ_yb!8U|Wa^|K5euDHVvLJvEdA36ucWE62q23AGVeILO=q(glObYAq~>>K zvw#e?J&-TuMvvF83G1UwHdQKT%x}&@-);Z0CS2YcY&(+wS#I>z`uuab(Ua7@s|GCS zYSEg|kOS~s0M~Qya5lZyqb6q4N$N$w&F{`GqPMwVl61AaDbBoS-bo6n*bH_VdZ4dz z`D$P0AJh(}wPw)ID5J_o4^gXXs+_e5eMD`7K!+QD2T3kK5l@Gw){r zr+!ng?SwGmuo6)7&)bj~{v<=XJLdqkSW}w}kXrz94UDX5P1q;?0k4MnnxjS8l&C{j zjxqq)tlqjb85GbBovD|S?}%Ou^xYHGTNCb>pg*8)CdogWvs0LMjw{)ZlJ>&8J4RAv zJQ2kw$RVOqQ2DS9@v}E_TU)lH>$CY2wHwy@wTE2(b2KDh)4cOw`%bf}a7t@1(to*P zroqUT%Wo$ooP)I^mLnxbIg;Iu&l&e$tt0sPmVu_A=Ma59bBXgaI3FGq?iCUSS|Fog zGppmE{kRI;Mi_L6o8J?SNHfRH>zpk`XRPwoFup2xi|N$!Y!PXZfa+Kqjo1!TCuYMz zjJr>&U^z3>`Upq$vmL}Oj*-(I^faDNj|E%NVY_-xqF6TV5fM%67@D zbG;`)oLPsA@cCA>$SYm6l!p)9Q8qPXAo)*YtTp}S|NvIqEa^Zqq{T7MGkCYFAt2QE6 z4YQ_KLNKa?d1wVt3%jM956vH{1B({()%t+8nznaPi?Y_yleOU6DVOa&(UfNzZ;X27 zuhq@-jv7Y~0f)0@&CJ<_iCM&x+vNzCrZ@uEbL#G1JC!rHp6 z=G%Fy`E3{aM0Qs|y>y)3B*eqU?4)dbk!JGi4qX6^Z3!<)$)9J;0LAN|Bh;m}4$`g$ z7dZ4G&b5MhOKN|#BAt4mZn^x7Hge=5_T0eLKD^5fmoJANPr>;Kvn>A>jzsMz?B7|X|6TZ!iU{@VP)MH z5ikv#R;wLHj&g3l6JBx)9PyED%#xj~9>g+mzE%$#d0ej5L#JCkh*4Wzk!n!{7gKM! zUp=f0`o&r*aw~}LH}kv_FSN~hq5W^ufdkKfUG7+GVj?^Scx87%@&|S+UYDD;SY@b2-Zk zvEN4psv9xvgqZ$lgY*av57{kDMFT}0fLcJy4798lVpY6H3GhVjjhLW4BCper)Nl08 zu$)GPa>ccbu+lm|BKun#6#iOxbfE81kfTqsrn)G)aTP@UhG;WR=mhfuR_JVd^o6pAni9?MIuXz| zny!djmPLhEz3^f`Uo~+xUPnm1xU$;y;+lrn*GIkjm{vyiOTXZd*-01!A&q(@m>di; zF)3UwQDlU&g+MY@~7%uAzyZH#&(fYzo*vIapkh@?sLG)+qNbZg&jF>te5o!F7> zg%8TR4Mv7$%CB2@K!OwxUDUb7KICjud`(7E@im#qxKW?2$jIx%EeF@JU7|7+`KgcRG^LBQwTJtHZR5;Q zM|8D5m~Kz)_7k?EZfQMdGkWe%8-SI}H;|4iEpxQbr0<@Tx(^*GKV1SiXLIgcm zQ@PP$V`dRPl!cUzaF*&R5U*DH?z=}9cLRNmNpZKO#N9qxiMzcWN8t3h8xcCi-By;4 z`>>GXF0mysw7pVJk{jsCO2b~u0km(?f_0yhgNh97oN3G6U0bGvl-Es~Ozgbej7c{H zLj!5O3Gvz)Chp*2(UIO(gyZzrn*XV@B|E6OqGC&MWW@NLEPG{5kcTNY#Nx|ZZP;Q3 zChPFb&zi+AQP3GI>tvuh%|%^Ny=HN%1}#=Pl>PK9D#^~+V#S$`^#JPVewQ~Yo!xJt zvOJUOg~}h+m*qgpJXxo-#2r|PQ`ae4{ZwS3dY!VqEDL8|r*xlcQ?_JtnzqEIG~cD! z6D2}y$|tmlFH$ZY`hv_zIRO1FNyn4`v`n?!cVvJ7bhIw*B%?L8J9W?npcNeLk}w?< zD3MBwNVmxYtPYA5FY9824HU^fEr6Rd%wRob7K-(&6nToKo*`v7Z8s*19mjvy(yURW zqp4e}R4-AUWkhs)SOfRFKyJBKTF!2c#giqZ7NgLRIG{BD6D#756}90(7H0TLeQ#vS zDC&woUcdhs4#8JPgYEa9!?fl(VS_R&UCvG){GQ0!T5z0B&U6Xc>2ih^mz*sxwR1Sy z@JZmbp8?LT)52Nq;B=PW!zl(ICr`%3+-Y1_uZY_}g}>$F?YgXuDQHo|{p6A(<%oNm zTM2cS0w>2vyv4zn`#8AMT8(Ie4vT{?V!q};2(5lwn1s{g;1$01-!e+K(Lyk!)Ec~! zTHk9m3Wl0!dY)5WS)~ElL`fsL ze&+xRP2ImpeANNlE!Z!CF+X^v@k4ugUqtSpVh(O!#PNd@&guD~GEGSj2!MytO{$oQ zj3$rxT;+9AWnaXvn5y`}DF`W%3O}r*{l9)wt(U|8HUXpfWo-Qc8$o?;S15Pn|w*7CVr)-DjM6s^dK~J**|3~O~kw_!? zLWp;@I(3{Qf!k)2D9y|ub(hevdR7dPm3)I!s5mTfVTD5BQFE{JLFPSg6Dx-xIRauT zzYi$hQph>eu2@pe)ScR&WG-ZnQ_F70V{*@S+M*jKQvBlD)7k(Bm=?#NUFnS_+k9NX z*xISPLgOiKK3)$amChG8IX_HGRP-J7mQSg-@MqK;gBQy6IwVWf>+tnljPno&R!X1O zsTBuL231_fT9&$Ps_UbnzyAz1UpnIHu9X!=UTgO1dWVDlA9H%C)Wx4O>AzJ|^&d_` z>1nFlI)|V;&apHI(7T}K0_lF!aVx-Uh4D4KPM@Y#ypryy(t_G>Hr+xUr<*hWi*#9f zLQ7KJ-f8etq5wn2g-b*8e?0{8Oky9L^SnSv2ql?O7$#ADns)4ku|`=xBuJJKNfeXY zDD7s@6xkZ1^kW&=&x>y@9$fl`2x#vXqbvPq8FG8KwSDQA%I~iJSKWKE-=tF?xF!!W zebJykAc}H2%2mDh)G`>1^mem=#5e1^kBY&)!>d^?t}DuSj_i9N(5X*Tv_|JG4yA)# z2jb2P>Vta+K21gE-^A&eYY4amyY9D8*#*(S4jPDZ4g^6OB8S1Y0VzJBLalXu=9Clm z#n2NimADLNE(V@X6p#`1EnuTUU4sXRFXC)E0^$omq=_b;ZB2hJiz8e*^v#w}{&4Q- zSVM4I!H(DPH6X`p>`_@Fi4H|6{T2Vs(H1+61umKy?1zTA?zlzLop&B{8$qh3ZzwxS z3H=>bveV9ofnPsw%tkj!4cI+O!c=wRUWpcrX0H<0i4<#Q8MD|OeVF~Vs8=CXj^HEm zqEl|CA*y)tMj&f1DJZO{r^>Nf;=eplL#UHoQVgo#!j&U#TTkt@9%>Ip3byV;oO#}P zneA^iw}RIC(Wld?lcwL-x~!@b6SLixRQlmwG5}`5a3=SevQ^745XkG=PxfjlHhaL$(VlDW%HeWK#A7 zN%dx6S9vpVBSTuRkmSZkPC^S!hypl4;Ymf-M{EO-c#U6m?X;sD@YP*Z%a7O7Lt6L} zs)?IR=&E))(*ZJ|cCit7z81?Itz?e3&;rug*5JDPCGu>tXl`lok`f<32Nbn6>T>jU z$bA^FYsl>hy4Pq#dwI5(xSqSm7zO$#M>CjVJxYM7>&ic0$4(&eCXOkAw185{KDcsq z>H8is(Kh633W9C>Qb(e#T4&c?K&JLGRPWAbgWO^36BHhQGcK6B{L z=4dG#n4rx(f=XrErb{Orl}ntd-!NeGdhdQuc--=Y3-R2YRtR0YAl4n^<;R014+s6{ zE%5g%F)HI6l-J9TQ(bl9wq;eZ+GJbM_d{GNNvRD^f)x@t`eDZz^6COP~BBJ7Sg4YWa~aeu3W;$JXg}aXpRX`FiHo*#Pu4F^f?G> z|D|d@J|wVIhEcR@WAo)aZzm|UXrx60!0KgJ!e(1`2^hxNS`QiLu5%8)nJ-vB*)4RZ z5s8Kl*j8e}u{WwhS$+>O1HueQTl|}aq{gG*=z17=BMhrBkekgUKB@`PwzdbS6S^W8 zANEqfeTAuG(TK4vUnNNO(LAT}5wQfel#z7#u<1|Jk4(lNKM93JT1X-GCsA<1D*^7#B)vQrc%@z8|3QNYk>aqJ$56NvsiXhOUkN*h--WBFmWLMvq3DXjMZ%6pH| zbvM#U*|Zyy z$?oSg`;q?CA+t-zPpPZwZOMMKTcA2SI%P`|#GVj6CHOXy$_7i-GTy^1X{xmD$RFc8 zlRg!2>pfbocShT^)PvNrt&Erx^GsN)xXc-6ce06aZ|dRHN!I9Qx1HUghA?sGnBtb> zPI?o$MtLB`EhnI0ky>R>XUNzm=y~t?RnAS1^fNbgb*J*q!%5}4v)$>S=j%j)$m#=v zigu8u^E>UG(lxC6aN6%gO69bFn^Jd*-1+SI75fF!xg_4O z1lwy*-SoP^yx0z$n^QKuWTUn5W$HLidu0r2XbQMtqjWpuVfG5@$F#Cn?U*67x@lD^ zK|FuhykHW7VTh4EO34yn60#_K+$n|IOqWQd_b)fp$9noOhw)DG}n(L;Bs7pGn0F#J^U> z7ih!up046empT=16!zcPIakF_*GMmab|!>5RmI~UbTKi45Nx}zqU%$8qbt*?(Yj^& zBtsp;x9hcIwoMDUA*anB@_L+s?@<+)nZfIm(apS;RkXIg66eIio~GTYOmmwCuPtr& z4j?*B{e>h0A1fm=;RxzdD;UgO2c3a#BGIHQE ze*<7V>N6jsaLBlm6s+s?JrBvF!pFPHvfP}ZFewmOl2a56XEW8}%znA&o>g_8BJs_0 z0^$`lHKaw%DK}=|H0(ZBbjDj3M8xbZa3GjAB42%&} z@XxmxGo8sl|JU%n zEeM(XGyCVJ75&*WN7qyQn!@ZfWA^jrwrkv?h{f#uE7)CK#^Fi7d-M=LqZb~JKQZ;I zhAy{T!?8*^8KUp$UXccMx>qE6dY9-=_;MCcc%%74HZxxDDOBV9A$bU|%OA4l%&Cpt zeeYZr5VPgeJ40SZy)4AtAIB3s?c@f_iLzHyb!-E9EC@Z5J(Jk-8IFEJWPFC1csOS| z%HbTdp4(bS9jP64tAp+9tNkWGC* zatzleM|n-$ygTUmckjnn;q>~uh-cEt4)WoyZZ_~QQ9zC?HB~%EF&r4I8Pz24Fjy7@ z@7AMs;#^zj=umAA<+ek{SZd;-netGWd(lcPMpE{Jc$XV4oj+G*-_28F_`>1K?k7~O zjkiH9aXjrX|ImDT%hTNEy3m8*JY)+vsZj z<1Jlg$0J7iU5Kpl8rBafd1yL9fO=pDH}1c({7pb%w?4Y>cR|Y`mwaqCXXUXFMZi;} zKqiLaQN0bhux3(YudCr1Nj@YUZKPHe`^Ak{`arw)@Ekh=-*_rvL-%?b9|~_5cBFw= z!!u##feLR{vtrLA-y1SJhEm}wR9nKFL1C#Bodwk5VTC`Tpiqdfs*ls-w6W3PqQiX~ z37vUDZZSea0OL{a_w`J-Zoh@le7*~P%%w~{!+;GWr!giBnWc&luHw-qvNSYGbqG-L z&e>%3yDWuMG|?zH82GbeHuJ(|-9aIMWR#@>m?j7DP=mZ=V0DvaOM|NJk^z`>IDD({ z;<1T_+V9gh)1nEFQ;|4)A4o9b@*4JC{Mc)F#I01}fUfWXo_Xk&2j`B`^3+{dxJbwG zlnKn_Jgs93b;2p`3H+;>$+=ob)M?kU71Xr4G~QJ0!z@x+Tg+FiIv5Dax}2wXk1C>z zTrBG;_l7Izf?-TT7fMIarZ|QLWmu5R+PfNR^b!T=2J4=-m1x&R9*pH^AVK`DM!I%O zBu#_P4pv8M>3a^vstXmHkeTvlyZ+M-7s8gDo%VIdYdeI@`r`ua0=E0~=vG1HbGH|> zr$jA{wGyzE+IDLira+4zGR&dVtWctn*Ilg(>(mal=rZa>aV@Q`ywretvOT3bZsiFg zZhPN*P%MQQ{bnj?fan%c!43t6_7U%pn!31`ha#AMI8RhJGuA(YtA}!>f9-5BYXa$c zr?ig^Y}P|==gj;hZG4vfByFql^9T4zsA{Q8YPKuyJ{{Lu4@~W`0kf#Ge%nmLui`UA zI@n1bpYqAQn&MYE4D|h7H~UYVWHK|W-+h#sJ*1;eZWGOIed5Ht#ht|Mcc&0Xwm2^a zxsIDZ7Vd}j`RI=L>c+T#UB$@$xd3@1D_lR;z#bH+9(Jgjg>?cZk!;=vtcR|;NGO2+?Rl;HBUhA2DWFj zQor7&IfitbluVfCtp)(r@F9ttLGfss3{ne5k?K{}>J$qn+{u-h)$n+fnUx}znJv1k zsTOYLE;F<0c%73gzsInaZnR%vBBK5hTkGvL<6xrIm>Wifijq;5t~DI2RTY~5`Y!)nv6i!_HWDx28b%*4vH0=HsWrVr0bieB_xd>VFEw$36lxw*3wKWgzt(Vp?s?D`VO?HzjBK&J zSnbK$!Us~u?Sz94GJ*N0Q+0aZ@^Pm#wl)O?{U|ierP!qUBEDe#Yy)hf<*=}|0Gx3og1UQbcMU%RZ?E9E(AZ(6~!sF>>5=c3s-l5QDca)Q*UJzL5A{u z&{Mi0vo9$8^Ce}~@Cc92>xMW*Rb`sukJiVHk0IKoSH%CWEOB?7gN~}}mZlKBm@%6L zr%Be~O?vlx0+7slS?0Yak(^TE1gz|GpGjj#H)vb{lGm#N^Eew$lxHa2pt%pt1wZl~ z(+v}3ICaG=t*v&$r&S3e5;#pkU@F>8ULvU_#gbrd+KU5B9<>S{p9YVzO89*j|LIP= z@Uwou=Ew9pzF#XkJjy<{R!8{xGxUYrO^J_fE_Yp@sRC1D&d1iFtG==VaKR*Pf;L10 zCbyLnSUSMvnc7a$Z8R@KTHq%0vHMI52=t$rk1g*#cSaw(d_2WZXw^}>jipr^WJAKHh{vBX)N{}~+2rJ}t515utOgMPXoecLeKKYODsA**`wzwc8VhUHt zAI^_9CMw%mzWjJ&^jRGnDgunQ3O{nb%vjoDjnT(+#ejH+qiAxN{aIEs6%q~wB1O^U z+fV1Q20iaK_nBSTtFu71?Y*f&!W>DCysQMXRtY!VHC!w~p2Zo0#V#U}~&Qla}vw8M6oVz0ClrkYvI+Z&d^GOV;-2|8d$ zQ8Eb+TGwpiRIOYlKncp}`?|Gm*+M+f#RmCIy=w6SGSjYHbe=}5moqP2iW;@;8+%Xo zTF+Q;)yCIc#OR2NeL2h^rmkh^R%-QH9 zX2@7k4;S7k%#Q5W?^Ecp{9RU8C5l%1Gkq>_k1nN<1S;HO+htNjo1T_IA^OrlSxt1I zw0BNouLH}9aQOi?9OfZlbfub6xkzr*Ur<5KV zfh^P;Kh8jH!`}yW z-0o_=*qYznO84F2F)_5iEXGBw%(17eg|bmr2rw`cy$DJ#Aa`-JOowNsv3YBjwIiMD za?KTToIQu}sfM;6`}F9JLOsYMoHSdd;;4ERIqo*4OQde$fpMoE$%hm&uUtsROFg#z zd~e&sWACWRnYm~(9S)YvuX_INrsl>GKW&cg`hGHGD(jj?13r6POH2uzURFMy2K8%gK9UQ2mLKI`a-fW4*;$lcI=ZKizv2*Juue(q5 zJQru29WVTVueuWB9u)TSHf6)zi4HrBaBnvLT)o?OS6}{+E6QE^Dj3!f999!OSuei-RG@!`8I-u(eiBdzwINJM5?I>^;oR}U#jUG@I?E{A!{;Dd* z_XgwuSvT>0{b7Gm7YxwS7Vo2X8{=z+{cX}6(a#w27b<6RoDpYF*J}S6Z+A-cA0O8k z@825ocl^Tm>XRugNBsr2v@4M##(j(o#9t)#g0sDIo~|kED&2axtfxJ1o2Qx_S}J{5 zK^&*Yy`E1ZOo@-?K2Kxn6nUGV3*c7#4g129LQTFL1hI%$Znk+vc*&ng5!tDjYzB!- z$k7azgAr!pk}WK8>dHIeRKMi)qU#oirR{Py9p0yGP_$j3U#d}W$wHrA=i(1+oEGsp zl$f|pkF_zG^RyFm-bTfbBC_4z~^ZBWilH$;8G5`gPX~ktt@qWfIGvi zjW)SL5;+$Mhz9*OTZ0d)o8L42fk^p0cOwl8i#?Mp;=A;#6610DyNr-uRgBYP#EWWe z4#unIz!-rqx)Q$k`@Bvd#2S26`Ff|o*vI+jQ>S1jaBK?X&|4_(@a2CY`rA=b^PlCy z_=~`jF-}Wy@l3SU?gC>~y6XF9zYC1crX?1rW zEdB7I#2;bB4ebvY-I+tad2qBpVf^3k_}|eU4diDSqb1tgvcfNZI$``Rj#r(FXo6eC z_bwJRn@To&l@$@flwru)w@!jmp7iBKk4g9F*C4)g?o}SQTs6(9-el<0PJ_wKfK3A{ z!h;XmabCA?J$lBQ*+P@aGf^`KCVm=p=2;BkHk2(6bGBBcPtgA$1L{Wi+&_)(@w9ik zrz(!@bWb(y-7?M;)0t_HpMecE2CAaHF0ypCV1kkGD2?NlkH|0U78?1N{dt-EDnG-i z>a)^6N4ts`T*EaL#E0C9?B7cN!vg8V!2dkq>zo2LEInMY)6PJ<3k}?6k-N-T>LKw= zeSFDZaNy1aAqr)?EOkV64skg1tJRaNpgRODfvKmI)Lco3Eu&`o$DI^=P^IP7k-SQC zd7S@7Eb8#c9j5=i0CiJAn=+*fs^V@gt{3Y2+Z^D^w-W@U7gm_19^l$#nQLhe5EE@v zds9_AL`C5+Wsf!44=M-vlZZZ_?*%u*w*s-9wyNkcIYSNY4P%RJH)=0_6{6spEFpp<&wfCR2nmw2A zVWYN+OpZR5IYl`9U?o^$2MNY$cqQ1lD`M{YUSj9V<96Rwoi_9>|9^(=wy~X3aO1v5 z94=Kn{kR`j@&Cbb7yn0P+)|OS^J~S)bmFy7lQ2!3EPZ;Mtd@GGg~^m@fdJT-nVADP zQK1}Qnl?(7Eb7bp-bKk^5V=qld(eP1KlfE3dGr?5qZd@{)(-SY2`7^)mm<4RlZ>hE8;KN zD!A|Z{Wp`Ks1rpsnrA0HZmT5eh(Rj=q9wiYoivDFz|8<3$A?b|LDzc7>@%ACi7IRj zNOda!njqR)X0oI|JE>!ZpX4{Mum~@rq9`gK&f|V|AH(e|l zqxh(+A}(LeN~w8*H*cc@FKTaZ3jjeQ30^NSEjK1{ou7lb9kB5(SPG=Lw-Zq+tql% z_;oEf)Ufo_E=Ey~H%ToLkg|=1{Ag=50#p{*X9^Yv<4lc)#)TLwsRsV1VkN@gcB$9Xe1E>il_`e16B468dV;3IqTul zjirrj6+n7ZGj3Wrp>{#F%P9eZ?o#ymjR`1zo~TpTvKe9X+SK8h=cjb~FJ$~jA%*kD+YGa<^RVun%o*kNx}VgClK#N)y;F`vdDlmpk`LsuE!9CcJZ=?;5NiHjaOH<31=CbP=| zVuGX$p}LtYuWUHC=O}!5E*oqZr|vlYvG2Ch#*I&$nY2ziEc+N!$LFp_P50Uo$LSe< z@zWVIEmrK%j*pxnc$Kwl8Z3+Slhi%6KLHe$?%<7@swSSn?b9F!DH3nF)4J5!V`FGe zvItsw2M4tM?^cy=AY^KC#Gu{bJ~wL3dE7kLeTkf)9MXS;hG`XhD>!ze$0!bII+Qi5=Oh#nW zu7xNn#TazzIPee8jy`=!O(lKVP^h}%9}Q^k22 zdD5&rn&~C$6wZ?nRgFNLN4HFZ#MebkY%1IagA*-L!v%Gx8I6s^orO@t1gj}Crop^{ za4=B%=;oBcNc$zt{&j;9D^5F@vO}2!1SCe%kV!w&48)6(IZDAE;S|kQ&b@(d|JoEOU#3ZKJ`qoxX{-3R;}DjVZ1QV*1i?+pN|Q-QccLa^JMgcdfkXRk!Bvqhiaqo|dmt zs;z3>o7LCr!*li5h4A~*?{?SzAuv*;3UK|Ff?d7BgyR5_yE?U5m=+DW3wbgPW15_A z?I2CK)lN^kd(FCj>AC~QuXEL3OgY6uB4w|iL})%@-So_-o1>1x>7ejW_#M&k#QSS& z!i%Hfr<8t*pyXkDARO|n9zM#|yD#t%r{BZxRt~(RyyYx{j@bkIRIlh^1+{7xQ>)`r zYF>;(xsR^ZAWg0{sJ90iWb{A-cUMxX6sL7;&*pcaL1naROj^xOTFvpT2AX*A(^aO= zEVaodZRRFzntdD3cLNJ}PaU4xYEjZ^anh>AxAJy(pq2MH{V8?PmQ-GzRBl&c<~atd zF@<{>iKIFjSV6(O!*SYB>qy$IOxmr|14Qt@1U;~tcVGG1r1ILNa;LBCVGpn89lB+L z@PcT#ONCc6ZyW7_dF$50Qo$}7DmhgzP91hZbu^EC_Q16C>%peQS`81XRnp0j3f0N& z_CP0h=)pR1Gq;&{cL%SU`=Q*aO6uh_Mjl6#1fgIV(M5(nEqKcSy3sOOHFu=l4iA`#5*hl zFHkd1Ul^X?$7Ie$vefWO#;`#3j=0Q4dRFE!m7b_`{kgJNk_L-?1LhbwExw7{`iUE3 z5adghXrzXM)c$ZuG?G@8>(kLls~$=&v(0BZ@73P|9*xvntJD#-%lIk-%k@BC?Mgw< zdolwJs=S-wQr76phF9o;@pmX?{QjG-q|I!yo$&CRb5@j^h^NO-2w9oPeEb7?k?+X;LdH-ZqMKGRZ=n^ZroAt z(7Pd*yaNSjdas?Y`pT=+6EB=nBk3pwd%j>DH3;-a7E8H5G^Nk4xr<&^ODIfWoBde$ zal4y{uY9N8Lq1)MmC{gd;#`a3_O!SnVwZ@H0^uITHo zs0I$9=r$`#H(RUKuBgcsU1LQvT+v%xQL8Hotmst-@JHuaU#nfwgS_QNCSB22Tv5&y zg;q4v0qk%^n_baItZ0@iy1*3`T~VDCWn9tsGj3e2sK{Gx?^+NPmYppy2h?4Vy+hDBJ~|U01~Ttn0JD%i#(Kzn|MJE)MUN`KvC3N0C7Mk zBcY2{DqeCx-j`ura|E`Q%T`opy9RO&j^3t6ej2P-SK4^2qpjD9V#%-sG<;y*iD+b1 zb@pc0ZYs`Tn;SVkpZ-C%NR6Q9Jsg0PIJub%^-=W53DpRCGPA9yhI+i6Z$&9L-=nTo zlPmfj6>}rCuITfwsMQs1w4w`K(R^35+7(@DMHjlFjTc#8IahSRiY{?Qm%5_OuIQtN z#+zNyBq~O1=ZapTmE*b6em(#ljJG~`sd9EQ8cuD>a5}daZDnqyb0y8WEIpy0ukhcQ z49j`#IpAj_C=@BfZ<_$X!s5aMz&b3Dzu?@d^jSC_-eb(1KUB|TKSfqNU|}-nxx|?Z zchoH4T8fDtr!a%UC8$3Xo~lY4e&AdvJksNS_+aA)+*PRgVgp|B!ckp0RG-=l0uNGs z4anEfI!^D3+eb6Oz3z2Qm|7Dqtp~^rjJcP?+(c1vWBbc_XA>-w9`?|CSD+?`z_F#PD5kD!w0hlhIdJ`KVA>e2XsGrg&qHFp_2U=+z&Yr75=B}uevk52 zHhy1mMK#W}gjVE@pSI{})#QpUw<2%+Qm&}g75yA+b0gmPZRdqnt6kAuR%FI+!{^A( zDSN{o z(<%BSP1Na`n%K`|JyyDIk}mvm&+7{`ChS8~NegA_rf%5^*Tr1bPvEzn2H!Nbq15i` z|C75WQsy|(M+U#C0$*+FmMwSn|3vi@_%&yN-{$In^bGLj?|A$je2ZN@R(eIA>NMls zT*1eU*M6S(vC}q&L>CsBPrE@Cv4*p9Oew(M(TQ<8=?@v@O z!7n$p-clX;^K`zd8s6%u^_DeM>Se0owN9-^fTj%Z{uit8YnobbS$(Bmuj(cE)l99& zr)Fh%zg`W`7Wx&s)K;pcsHS_>bPaA>*DoLK6(C%lo#&`*5oP-5_5Cj-_4R#l z;lmjU?JF#PZ@n0NZPa_f?tCi>zaDtRvpJ1iTw)M|uN8ys#Z9}9oeRLCce107VI7u| zUmX-4eIB9OA09yvWj9_v5H~8engJ3#Du8^^(^HH)&Yd7zWAAE5@wNCsVlBaD$c(o397hPMAg@JXnbrV&F z#|6G~PJ?F?_R+3-t6*USi)o&~>DWlGEN&VrwVcNY8v zuN3G2wUevf+j0L;^|rk{)H{fW1En5^Qd;~y&Ylvh6r>>@kfbYi(0i;zorZAl;otku z9DVzHs$f6PAfIUk+RF0zcIvu*O+Np)p2D-qr%3v*l+PlcY)vDdHWBX3+*##Q3o3Z% zCC4dl`liUIDlq3(!AnshpTf3UFul0zdOY!}@rRc}FQZ=Mmf5T^GZGcCB^^iz{e&}P zA=2zm{5e3=%C={_W#>fKoaYsaXTd38|825u3gfk9+p0~GZMRGJ^8VCb2x6o2&apfB zfQY+w?EgdAwn;skY#Uo7xA=^{nO)J|Dzq81;!_Q=U*I|>#^2(^^Kj6Jb z1B%NW!2;iteR|?TP_c_UsJd4fO!D!7uaI|Lu~G+ zGT?aWcktb*#J+vi=D(mQ*w0?TF~-CC>@qFPm=e`vX|;k=sT(fB?Je@YCcpDCA91)! zl<>OVS=waT=DXv}uGV#4nVuz-0-pQilrhM@2>aljTAwR7YFtaN5wcMLvT?5;UJ zG8-ve_Mk8<+=nZ!qp~;ea*{3HPZt-|30E3j!A%${#1<@;KnV z6@_^;t)=}K5?e1vwnU(zv6fRrrOhl@lDMVW0Q>T5Xm{yV7Ke#nC*Li}|47B(vkjhj z#iU|AUp|Ci2bK2HB`9i91VJ*euAF=(jWWZV(>}XfJ*{>!_IP-;mSM>TQc^G3?{a&H z`Q7?~+Kifo%`Db?)zZgm-@(VCZhTG{XekX=DwgwI=tyK`Z3uNVY3#P)5wq+UF+5wA zc0dg5WU@ZgqAfw2%CwZf!+{^xTz>ubxB6YdW-5Fmo5A<%$!*Mg z+PbPA_OVE;j$6DY zJr0(>uKr&)Jr0&uR@Z+`dK@gBS6%-#>2a{Mn+YxBlRJ%m6}~h+J6L+Py8dhO*}>9B zRezeeMUk!~D4zH0mRTt1VCm6n_?ypykIBiwQmFdo$0qvXI_`~OMB-v+-=r0#D8$e0 zW;ym&g#4&ZLBCEpSP#FHcBz5ij~P%91*VZ&_%;ktQ~Fap(7|dQzg@opetJ-I_#RLw zeV#8P;GgRH??jHNuLU@P?M`Qt2>q&lBGSj}u59wL=F(TGU)_G#+E2Vz`vtUD?6-6t z_*J)`%?4H3Vx+YV01kxqr}WRH6&Wpoc^{TfOv3M(Rx#{7>Wl(iX!hb!S17f8df|1t znsb_fwY9v`4N51Ql9skxV1*CC@y?!nGLjm;+YY<+4PFMp247-~b&Y=;^}QfjKR4Lk z_Y4nxSEhOTu|3TQw&(s)Ps?Wh?)Ut}#yj7|@M`kUHb?qV^;LZC(Z%6+z9*_WK6muS zA2KJopr?wC8auyjy%dl`Smh z4>fK0m0;v1O#;8S{RY?bi}c)mUDr8%mM=XDp(6+#LFoLR=I=!}DbRz=Hbyt;G$Z;V z6X$`fJe}LE=iFbqf%izEC!3occt(?_0!rldMuVp#{5KlBE);`2B!l_P)=&Os{@E-% zw5V#9#Q^zZGlMVhq8mTuUB3~1OJojT+;k|HgUHAAx9c)uNh5{2m5{ZoW7AJ+$jiT) zy5zvi2lBhm)zkei@8=pSpoRN_D@OBsvcC<-@qLF{{T{7)ir4>Dl;GIlaV(GdnI_5~ zICJ@$!Lv~0nOj8PGsE5^JUBnP@F+BBVFEfB_=+kz1lwoDpGy@FBQC}8#yK3=3AP9M zLvIUjYT}v7tC^Fz`6DTOwi`a}{k!(}5iQzOV)G&O^1ff*``;l`uIqz6M{hVc*Zn?L z1Lx;|ma?a=^VNTTjJNlvYBn5=KT^A7_YLP$#@j5C+PcqQn*Ui{er!hkk<^miU%E41 zHo0W1`>n9cO0ZoOUX7=<-3NwyiHC?0rdEC2@aWmVu$Zj0j|@ctzBJE^!q%0<6E;zSCKw*-eC1Vx~mViH|)@ej_yuvSOore*KWA<=>X^Mfa|VS!$mmY{G0 z>!SR4ir>KHYTt<&<+>b`M$f2TQ?u%=(fX-Z{iKd@Ffaj0dGQKlsqjq(88?17#Ng6N z!b@y?hrLg*P74YTP$A^r<5!@Qa-X%_-v#XG(^|Wf3tqB<_fb%td(3hJa{Y&g)hKNK zuzGkhJ+%j&kq!#_Qo<9+P?gFBg~`;3)B$-_qdzU{UN^ot-6OWEv)WY{E&?N$YwR+ zogX?4ww=@wj+P~?+I9Rj{T+u?cw+R#+n~EXdOG&9KE0t!U9Q@=!*#J_@0ad&-EtN5 zk|STbH5yi^b7673S3k|7e?14fHstp-n|i5CWl*>RIq_zx+9b_PD9qW7fB7IGfIZD- zoUFaB)4q&$&y1m$`QZnP$MQ2e%KE#?`_J|Mb?(Ks^268t8em2S-wQH9PqxlXtDVb- zZl7jOJkIxz*S1n+d|BEh^)AV{q`@VPE}89;IWB2(N!BHEUDE851uj|SlEp4*QNp2f zNcDfcQ=MY_zusy3|3#9BW^RXA*|GT0J5q+7$SD^&S2 z>2T{Y z(-`-(k31|4c?)Rbo}M7D-tt<=b59fGWh}3iJUxXY%Xtd7uF~I;8vPx(R)2ff^4FiE z9Ioeiymt4g48njgTQc+RS zqOyXDihL-@dtEcLn+0j#zW+RLe!uLTYd-I}=bn4+`8abLYVaFs0~?wooQhvG(!2tq zc>xBl^|d!l!vp`^CRzmT4U;u)Z^*-wqCZ1FMP6%fs7v@x(NE62et2@`W#f1HwZ%tw zcU5{E_CnbTW;%VSyLk1KcVR!zbo$>0&ybpGhvoWegE3{ zyhhp;y!nSIMj1c3YShK(93QRYV^L^&QFhIlO3vCVs#(AGI?gXKdfeY$w^u*Ga9-C_ zeQqA&t)lOKd$jWkEU5ZDa%HoQbATi<$MP>`nq19ov*)aJ=I%m;+|igajYUOGgw8~0 zO)5geKVamFMs{X^H<1;X*WtMvs?Fv_V@1pO|+`h$6I#wf8BKvgwJ#E6@W!}azn(9%pOZN ziwV?i2w2Tv1a5hL4A)&IE8?zRiiY9G4W58!s5P%YY#KZK7-K}(P2IV?8aC9*iW=<^ zPA&P@Ue|(O)EO^Vl-S{wr!xLd*mzhzCJUU%E`rE5{5p|6d~TcqhG6TW3+%h2)tKhl zO}|BHi83q53vJ=Kc->_#nbRI2ef&c;WX8PXXr`k5nTbf>ULTJU*>8vMMr6(08nAOC z4khSMUwoV**=&)!Yj$OEX(1ZuimW7$B*X0IebBv~?8e=wPUxV|ZeR^VyZr5ueqW$@ zK?PR;rohGK&>T4Q!lnmkTZpHcJQUW{5sD|noh=!RGpa8mGKynF=*}8veF%Lunum;? zNCAI0I#Kc(bC_LTh=J>qv}#GXq7y>?og`2ORI{sF2I|$#a7R&`-S|yk6skNR2PDy5 zwqg}Tn>_n(@HrZ-hP?%e2{TN6-elz@Jb(AN8)1;HnY*m9TqipMCPn8iLa$#5>N%OH zao%BcdZD6ht-*_BVNQKB+an{B2%97OozXr!{16~?VyM+P zQ^tzY?Y}-M40q^MXCymnf2kW(<0Fm{`w1HygBw>tA~DhC z5`mI}*eNhz+huo=(f%9J(A&F#(s<9udpWA-$4rc-u-R9lGeGu9j@KTRAWJIo1Zm-$ zY3>d+23Pm19bPt~uy%;MVh+WqsTsd8@t;aXdW^bL(OLO~m#+`RFcak!-{WBXk1O6Z zh_9TFDj45sjU9f2Wp>mw5=8dSu3hIAp_KbzgSam=BZfPt;qY4!jmW5mZDrK8H>?9gKu^aoF9-Pc26lV?wKq^1sHYwJDbm*7uw6f+9Id1q z*rWLuw;1Ac!MI`w-8U8TawElA3W*z$inNuw!i}zgC^&1^eBpI*Vu=^kuCZT-PNqy_ zDvytNf1I*qp@dkssL^76;5{e_1aA3S>lGZ$VhVFDWJu|0hicJjr7~-ea5s;C?Gc{W z;vc#Vh20KkVHVjQkvbH(c)#vz&hjF}bnB!hfWQr96D}ur%9bhO!k;t!^B@@uKN!vA zMJLYME#nJnFr&jvt_J7vWi`UBh#8eyp99A3+Gba(*O%A;iUVjOB>kKTk18eZ%w=It z^I^n6?x}F-`sl_v>&ohBvJTW-qwlUjHh=caKL~`7Sng7MkGw%xrfChc@T!`d8`w-Q#>Z zOb)3bZ^jBHj_}u=LHp#HJak@(D4$M*zwQi*uM^>~JA-2FMEL8@ps?%lZ-(T%8vkZY zL^nZN{6-_Pv~~~{nKlf*ZIeQ1X*;Kbx+7VDg=ueFl!CF!LTB4oTpdO3J z+sHEfZuz8atsTmPl~Jbb6+6@&KpQW`n-47K0KkqZm$v6_fF{6qW}!^osO+R_1d}9e z*@5%->@*%n+AU6Gql{hO1!_!%z|?63f+$aoR-SD-k-coeh}0u%Fay&@hg_ROcCB0m z_B)Y%h-HWCm~#0l=p0J%hZI3+vnZW}29TG4X?@hyem>fUsP^jz-ffzxZY*3wee?;o z3MBMK7{29;Q0o|sw=7zYbyC4ObJxitAI(J}%Cv&67#vmNMZ4=hSTsrv$u7I)6LX^@ z4KmVp7qqV%VHOis<3<2Uh_0F|g?7tlV7Js^(fytAnw_?_zD0*$NzIMnq{i8cz7N-) zIn!o#6nt~96Il-zhfJ6{&Q)iv9XScDXt1UKB6Y@Rl8IyRf|6M*Sw0Y-|Chr|xrzU^r{sztLS210Q@{ zVBOhxD~zKVwE1E501h(pfJ;jmdkKzhU~|KcOvg~~ zM%S^?Vbe_^QbUkzdfjMHacnzjaC+?Z6a_YQ+^U~?5($2hrgZ2v({6n&^iA*nuScu8 z!K6nH3*ZldXAbBaM4`64{_8h=fj4%EPQl`&t_ku*S!Zp$cjB~_ z9&w$p54}o@WWSO@QckEJ%&4x zp45ftw_N0XsuRP|=l9ayl#?&rS1Fut;?=kq#IwY9+C!hG;4_O;%`Klf--KUtTBV3K z`It<7>;h9qWHd*~qI_QwQ>Y2dzm?QLP`+YUT|SwF?yu>rym4Urx(re|g;e6ORQLiw zc~G?TM$I`pHH8)Jx^FP_`>A67r=oK?!QhTixO#XPmt7 zuvEq$Me^G0a4FI94pR!7JKsQBqyWqLC?vWWCW zSsNV&EpS|aw8P~{abR2QEVlSw6MH7Agx_OT!kw`WjMs}2p@V1M|I5(9-uDj=9mH#2 z5y&!5I^I7d)GBLUTcz!?(8^_KKXZCHns_GayuU#%ZP?*i!8n`Pn!9^yQL60}YNZew zwaXO~5r{rXCa$;$kK9W)%I1=l_GQvR#tY%sf1^8h8dzU8w+_GdNa;X3jM$_p>5mbt ziH#>`_|7w&cgg98?I@o}HX7BQ-33*TMi*zndRi7g*4cytFh{4%@(&jJ96HOCR@F-a zJM5@$I9@))=p{p;pQ7P{Hb#Vm-72rhkB0ryoKl|wlKM_hk~zK?w|mMF9X)(J6cFY9 z;=IVw=>uG8;FXQY!(0WdDQ?@{74IJ@Pn>EASHlxkDQmw!<}M$Pbl5HKgEe58{~T!( zV*1sojB!hJ+`ZF24S_5l*vFxvUQxu$^U7*4Do4h1u1I@JS-F~t?Zf3hR(lFUkGeCa zK@lPY))C7OQQuN$c&a;N#YON{uN6q&W?oBDzYp^i_^yw~g>QyiUo=AcZb4S zk-i&~e6!v9MOD&wYm#qIw|?hk(sx^uZ=PG9cZKxbp5$BL){nhX`tC^b?dR6dA1!@% zCixb+^;@r&zPplqi`@E*Yo+g=B;OLZz6zhdL*4c!`Ifr%O}~`B`;vUi-THOoq%TLF zICm=CdgCVPdlh>M_TeMw#N$-ns^pJ%A4X^T%WpOz2Qkcb47EP$tljj5yKGJy zJlwAJYuJ#ux*!^O)*01UE#*9~_Wh8`!$fOSq?s26ONzCp22#cj5IY?MF=PjG*c!(Z zTMVS+2!k4KhcRQX(hwM0?#`t}eu`0nEDoAEZJ`|*c*#D}LZdV?f~Bj~zZa3YVGmua z`@a)eh#19f`x_QOJz~iE_$y>5*R7(`Q4DITHjy5&nOGTu7^%|Ab=g?oQuRE86c-#b6_9llv4Db3IpxR_obGT+U zqAQnr5xxK*`Y?XDjMxH4uS}|SJGHH858a4B>TQKXtz7go>`LY7;Gi0>y+jw3(_1y) z0Mng%%ZC~^+3LP5Jo141x7{83L|2r zwl)xPM7%k$1B^%&h(s-bNTrC>!p9nXFKwBuDu~QLq!L7;rbQ$kpr}ENBE(oqFPv6D z=pq%`6Cpe`7*G<0OR1KZ^6FFFg6)a(!Iv2ykoJ3>n2lnn1pz^Lsar|&aSk{uohpe+O#{!FXK zC%Fa_np%xG`S2dRf~pj2Xn1a)!4(!f7?K6;GAfV}`x2+|vC1^; zXUAEtdWt8NfxX)2QPKlulwiRF3WyyXCxP~!$U1upb@`8^C~3BYvspD0Rra)j?&%ad zIMHtSB}9O|l%_1!ZshU4W4m2acjL<0uW>jORpB6j(;D^hb<)^&zP={s;<_#F;EM!m z6Xxf~HR2*j<4_JB+Bl4@l5$-=7(BNlZ-TjT$&alC;HfhuX!4iaDkoyk9xNR|(Bur# zZf(PMRcLST{%fL@m`KJ2Ey`)P(m`d*SD~NbbA>oD>&RzxpW6fMV9n@lAmkz}G=y50 zK|LVa`#1sXM&xmo*V;LX8SNE5<)kV{C?`WX>gY#BwnFOYM@61O1RkDMuas zs3=uP9sP*NqaXjvQXf4!z$;`?7Ol&gsU>xFW~@_)I|xMYXB;O!cBPE;NJQ1;-7 z&wsoZ`{z#f2(Bt%$axpix<%CKk=iiCvoiGq;?8fex zM|Eg7r#*RL3UkjbU-w_H)`CJ`n|j>gx=HH@4fsI@)pJw&QlhO*-@t!rUb@P}y2l(RxPtKevJ$eoF4DHg`Vt%;?SaBF-m zg>TY->*F}K6w1Y&qoYa#4O!4ioI~dz%A}cv(+SZzN2)qJ`YEMV~-+4zV9Sy z<>BBooJNBu$2g|P9B!0u5t?7$$n_kWFf_WP;PX(sg|}#fb9&z zQuXNF(wMmJL*Kjn^?O%8amLsKR>-QRUS#;CE`<~(@*aI zCYBzjs@yll_H*S=uH2AGKdt%7i@O>jJ8ns_D&&nVpVecm=Bi`?3-~6~u2v;Csgl0! z-G7tJ|EvCQI^S%Hg+9}i$1?>R*a(9M;$lcUoW}hCWfiMVKvP0X0v}^zQJ5o1WQEs! zE%)2Y&$Zv&@_9YyaG>LNq~nlW8cia?`9YHLg{-2pX;aL3SPeRFVisxv~UqbUEb zZn4AMMpVyY7vax zk`(Q$EZq>;K`3U2M7FEcC-dY!1xU1!HOY)z13{r8xgFHRxB?I_>#HpAj_WW~M<}+K z#d4k(FLPjQd6H#%Oqu4J>PQcoIUc*14IZ(Pf~Dodjd?nfvpb<~<;5x;PRCCLg~cj$ z>^9Vmsea9afHAJgtI?u12p!S_@=Poz(8b*5W$X)tTICY7G`q1)*A{A(BL{E8mb3fV z1GGb__SuV1)PK)M-*XPc6-21*a5hFFVQ;jz4&n)}yM%(gOP}bOnY3 ztW@699lIb>xk+d@)bZ6SHHAz*g4{7Lg`tdjB(h=;XqSrve2Sg%A&6GnG|S~|Y>m?n z9Y-z9rL*Ttx}c}G@fC#{MIG1u+hQqvzvw73aF)|Dj?n@QwMrvdEqy3r?4dA9a^S$xE@&7k0$=icv<4>yI>y@Mk=9wO_kOSw$Zek!Y`@4&weSB)Vr1*6 zB^OOh<=)tAPMw!;#K^|uJr95d+0)ae2%+jH8=%@AljiW_A1Pw!FO zrqA2iFU=WRdM1XJHq+cxwzu|c`JPFQG5t(VT6o+@o(K2|m!L;BPwi3sS|Z)Dkuu#H z)7)G3`h8!cxT!|1<&CW8SUYzEe!UTHSefxHAQ(1Z!yxj`l^aW6(Kb?>`J7J9ZNr`) z4mzfxA=no3SU_y&M~I|OTZLX)0i|cOH_C-;M5!InAthiY2L{fu@|aq$V6-(NT3QgXtIX@KqLW9K|{8$Ro~4 zYh#IQHoV(WICeJIALY^K7vQOy7t5x5(O=bB4JYD*ER)62NB|-jm&t@AydtAcUW}#9 zNNOT#H5IEC-`JlJ1vw;<5~uMvDHue;cI_IT3gLQ2-7!FE=3XaTEzOk+A=m+tmg8zz zeX0@v#Fut|rfcKt2eDyqA76e_N5gtkf>QGMX~>GoD^`W^sDtjSJ3a@l~##$dh-9bayTf-+>Y-KM(SRUT7tMaoCXu^=i}F>j~+D z?KZ?UYKDbc19&jC)L}Wk%@b@n&;<*UgwrZ3O+i9E#*YOtRrr!0icFzGLdP7BXcU6#!pV z*YSi5pH_fV?|E^-BNtQz-E8g*#&#=;9K6$ofLMg5zB_(QE1{TD#iiAuCc4UA_y8f$fp_DZ^a@Iw3-#$^+GyO18##_Hb?()0Dx@ zJa=w~$ozI+LEU@$3^%7K&RQqjIt2>P4YzJ(O8G7tKYx?Ta!9G94*5vW`Ac!=51x{g z88V7uK)f0dNmgtn&K7aX#(soTut*J)uO|8;Ps2JJpZNl3y8AZOYSum@{#KT`#%yyQkm1q1Lge@Wf8D5j@9Y8ox>3GC=RCk) zH#(E0KEPi$+AN>>i!%>04u4S^e$6$=6|OhJSLd7=`~@|5Q_h*eUpK<{p~W=vAq)wI3jw;$HFo!An&m4MKantCq_q zX_Pk8j*b@$+nmOo10dfc-4g}vV$iQ%ZCrsven0UY&!NVvjY|n$ZCs?BX5};~r;g6< zNa!V&W7Is^p>){9R5)%*yj`iezTW~3t|QOiy-Dt?@%_sBJ&PGvZKO(Z(Qm=5mapZj zZ_O+b=!y8yOyo;&YjRB%UeT#|6!#FUV_La&BJ*41tNj$OK|s&r+Q0W*`8^hVC4#5k zmdIfU-#f;%y794czc3>uLSEI~6evX@ zll99zt2yZjeaiKXQO>OSls$f)c=ZB4spH^wcnr+njt?T7i-jjweeQtWMiKk-Paz;1 zlrs(4>04~%XA;2L&<>uKt3$bVc(sM&5by)QpgWG`s2icx?a-Cje4AD<(Yu=GLctQg z&ppO|e#v1-5^j0m?FFbiZl~sTPjasmP+wDw!S56UrI0!Ln&QZpHGM)yP*8hk$+%HT zmrAJ1obWxfF>az%z6pfVc%yUtPKiWm==47?PE<%Bv_q6(~fVQjaZjk1CV5 zGNVjhRnSpGdGm6G^y#SN39e&K)boCks3$Mq_*Z4}r7YBwH!GveFODno`1_PW_L?0( zyHYt(=KJX=6Ven_7mVmKt8_gRpVdfXTPrc(5vWfg%Un6}MCY-s?Z|d4MaJ(|t{KuH zBQp_EWiPMTf^?u-$@fWB>6?>ypKJ}PqB3dbmlbHPVgk)wnT}5>@V*%NDFt3kqdujO zho_EDDez`NNb#8dyYyEU%zuD@F(`Ia|3jF-kHKe;`X5Pr24SuJ^cQOm;u{JL@+KO@ zT5|+QeyIW9Tc|_cFof_Tw~EA4DRKSR>n|#(kT{vhrh+l#_Y;o)T0(~XQbP+uLCP3s zeg9o2ChX}BipJ@}Kv6Ocb?^p-%t{Ks{5XOuznlQFB&CTjA;_zf?MM{OgPWLHMKsnE zK#9wsFHu1Tazjudv_;)&6QTu>qJr{NP)w%MmqD+CdPIg5D(EjVNM8nBuY$&@pqpfn z{u09ZDyU8cmCCa8rO-b@wIIV574*GKrN4x*LIt&{pl1=JgaqG=v2j&d6KKW9F~cUT zO06NNebt9!79&u-gtm+(1TG$yayS|4^B6eiQJ zmmlgL>Gh@jQm4Z5iynV5zbxUnJNZ!tjF5>A4m?2jVbpr@JdDuOpl3hlxym}w7<-sA zP(`o1niub>Y8AicF5v}y7)!<=8s(@4NoMkKv0Tg9eGc*-g}T&WO=1kRZ#6X*;;Gv? zWgJjj&BY-^P?ynVp|tp&b0B1*chxM}r}gD?ys@t{Z|tiqsA8$LLlf8aQN#Z*044IG zKCF>T{XMFns+jZt?3yQ^tW z;RK;NjcbROa1ul&9C6l@?YQ|NTG?+08x@xVm!FHUG1%fb&3VPGNOec^mYH$LZoE7E zkbCtJ2h*p~0(BjSc;lVnhaC9HTXog6-Oa$&y3W<6bGhHGPIX7{_9_m?UcM<+B}2!+_?n1jQy=cWFT=epKoyP7HrD;kA$QUd=iUtG)&STr2C>FE zzd7VgI?@q8+r6!4BK~CLc;6xSHl)dRZtWRQgObNN_a1U?J>pKya3?0^Z@QEGyc~LB zQvRkh$&dWUxz*Y3h@S3!rh6OWWIGf2W#w^BwdsuT$HXDs()V!iliZOP4YG~du(-33 zjlTJ~+n*CH&3(UcJ(sW8%-X!{p_CRGuM3V z_s)_HU*_Uv??gFW-AS2FnR9DWIbEGeiDqYG#G5{Hl#O3g0}WlrUN}=Z|7qhNm+JqM z2)v8~6uHxOI z;>mI=I^u9DgZ#2Np^*6%B$b<&98Z?ZSKU>-k5OCHBT=rA6xZ93k%;$u6;GB+dqmem zmn#zSt~)NjWg{QlYB|8tK@T{zHi0uIWE8CI(O9ftyoDCeaF;S@+Ds1 zw_@L*W23&Z+~m5da^v-VOTOHKc$i-uCkI&j>5zlBV*QSzucd>3(>mnft=OlkT*<$> zq&TYG@-+Y6iv3B(gGn_`8hzm`o(+N`I@Zufr7)ox7wd*lj*m1FG55e+?=BooLhU%| zN}7zQiNUzo?FiNJIX^=DH~BRIHIX<${MQj0&tHDNCp;h#Kk*3w4B+wn`|9{^gS=-` zDql#-7`I^=ETGtY44$%I{)_Ng5Ly|o?rW-oSdLF#Nhk`f-ghde74vv(7ca|VG7byj zC=c%57HaE;v%8fAMQWq2Gd_pXpXWouydT$H!q+;S1};C)>U@?9a`U(}?`-5{Q7Lw0 z7ghnHt9Rhcv7;|r!lgQh;5IN?Xl+XWwb4sbE-p!r&4wDSk9knwnpp2GJGOi>0cq#$WI1aveSwP?7Py4juout8NB0jKU15h` zpz@u!4?fXLJZ0!O;c zxDM}eRXemdJ}1sa85p`JIx(2IiwUw+6xz`R3Ge|fdB`-86nJ?6GNYSG1C=*ITV>g2k>WyRg z)cE6n#wYnr0rKfJO?~7asB5A-55RUwf?u&-K+w}t6mesm{rps%00J}Fm)3mJDLUsj zCR9Z6(WppsW>J=73ovogH;2uVi^TKfD>F~Gdu5YGC-Un#CH4!2x0bzytI<$&|AY1m zrXYGT2m3n;ZJlQcn1pUXfPxLAhHLnGQxsoWf zND02D=$%K=j!q&;(ElG#nJ)ge3@SY$4nK;_xqab__ksY5|8ce=|w$ZDaZZ>)jgpZf*Ikv5UMlL zRMDL&)~ecJp2}yxZ-&fcvz7xKb%lr>-|zmPyKHO(+0-Gku~OnHutt`<-}eAZwV!`2 zh7AN<_Do{-`yPyY@=mp%se#x&upqRj3d(qF0bk;;fZbdP&W>f$dwMv)IW*JK$Mso4HX5k)qr~eF($#`NZSu=3qbQz;|Vy@6g&FJ z6!d4XrT}CWf+hXj@I3j_;R?B4zLLN03aR&2%60S=@|vDHj*-qvK0Eb%c4v_eNhalD zRfDF}JDdKXR)*Jp7CXeI1yevKC*!*=#@HR(NzW5e|8Gb~;w0+HW=Vasq+Wi@-g!_` z-z=$rP*UHVME!#u)W>cj0e2gtoi$fG?_5>fMXDrfFN-)CyJihE-BuR))=8%V+4 zdOg}CdX*P?WL71Y9pH__rf*MZt}9Q$9jJBFQq(1C@cpUC9PBt`bD z!I0sy@24-tYQ?mI5zemud)-wl*(hLq1{#2~69JcJS-6T)2r;Q3g~(+r-bL5VgO0+U zQ$dn3>|@~th7oB(N{OrCH_>j&r{9HKW|@Z9ODhX1Yr2{Tkkz!2s9|Ml-8BDEqvk90no8Ca zMc``Hf@-j@lI-I$^%JDQ++X)QbQsc5ZAZW_!>wl%GJ?mFgikYH4XxbBkq?(-(#XSV zROrPGV0wx@dnG-<0(i1FPey@-=-uPdKgPN*@zMgAbTH(w6O3gX#H_@7SeV$4TJv>p z_*6S@rlDjov$~1PHDnI%BH=`T;_kbU881$)1aVx=scIs>Cl{m^f62azy2#r<9KET_ zgyoVCNHe1B5ek?c{tf7)LDw6V;eJWvC@F4`m+H>rff(l}r;*5cgeY{d`#nwWoDi90 zzIXH!ncrX~CHK|3^`(dd-ptxcqY#XZ`YgPMLoUBEp&8ry=dAf872AQG)|P!$yBE4C z-T>2ojSYepWZHjk*+x4$07U2=KzwTf_3OB4nTK)9<8`7Op_mboqc!QQ6}}7f0)~kC zb?k1=UTG?|*T)Yi#a@N{pyULwGiN$*D^wQ93`PMK# zH^ztu?dg5pc?B5rcujK;<#2{v0Is6GFuyIFKT8wPm_6IDWylT^${ACPNSUu;1eUo zU;eByW7faRGSNONBUymT?q?b8AAWvnOwmC0maZ=QrC2hdujx%o+o}%*C znMVo3bP{rac+QgbfW=>8;E8+z>%*N#(E|!^mx$6!^ajz@Q~Ah)T%nh=ak=0^}5--k$U$cAMorGr$}d`p%}Qk;1!;5rS9@f(%Dsz1aoQDvR5 zm$6dE=XZi$#z_Dx$UiA`OP)^dT}_`uZ>TQIMvZL)bnDp>&}G8QX;zfLt9Wy4JZMql zXY2!b<3qz3{_OC6$S@4k@KI!!s0qCSoua%A1^Wztt;qsdTpq8VgP#UPl0=v-DGi;S{eHOOeIAu)D!FjCnS z)yY|d&WhM%608jX2Ud~JAzGQjW>8aSgjdU<0)cBj_x5i`$(6C*NU3!l)NA-N!XIpV z*11#^OQ`W2?kBv0Q?g^Rfb*&h?`_ZOfpGd!|4BdUKRh(Y41_5Dpk?CCe(c$m*f=&d zmUCsV#^Md0#}DB0E^a{QiauQKi&Qym?w*O}9)SX4f_7!iareEB1v{sq9i}9im2P#0 zTM=-VG*fOU6vKpr_sr#m5zf#Gq$uP_@GXMfh=F6Jm~<_dSIf0I-`3Q+_%?YJq8zQA z!?q6ljvkqC2ZlF@-0C1R4YL-(cP4wqLcNO)h- z#qGLpv0K%)lMY_K0O;VTa!rqDI7({bdLzTBJ{)TE;a<{x*gV-^lZgaVSDwwBu|Lvo zY{S!ckB8Qcbv7pN(~@?)!o_TN|CRFx7$SI+NEUNw_ah8;b~!j|dL0%nF}AL?n_5uG z{X;LTvm+z%6p|NX!8#g6Ge+H#72yq#`nFAXBu>3?2Ef1e#uofiu{gs^YAfA{JhQ8( z8ctyW<=}*8cR@!#v~9hcUI@zo@8{e{(78=#Wl$t+~*?jQS^=w$JO(b}H%Ac39$&zm*^h{Z!2q)mss2xfO3kNJ?GxJDZg$ zo6X8P^0=ZM?hGpJ1w6s-G%kXFsI{~hjvYB0P3aCbLh`L=V|p(gP#b8k<2asyNbM0h zw#!tMD(dJ8Afu)`Zd=0s_$n!UM(uYnRyoOpuOe3p zKNg&-3PxZqfqX;v7J;HRKCP6-h8=m1HdVEq=XiF5pUR=B99iyJLR3zRjH z%l8e1hAlE`GLT1w^1@7!d}x)duQ{b2W1E&}`9}tyDa2nRD;q&>A1~-9DKX2jW0YVl0=P85~y= ztN7j75ZhQG2MwHYO{#+(9DyAXI^?q(_u*lYN4>G3dWM|; zs7?$<8M|MHgy6y;*~@E&xDoc~&_RC-AgdG52z8184s8XoX&_Ri zKmsH7M+AWF36Z6g#a5DG=m&!(f9zTFbM}sCUrF*)! zOKz90<}b|ARt9FAo}l6Fa&G$I^ozS=kEp;%Pd^_qFfY@Ou>br%)7vFIosmpLvic!K z&(2s|FwKj*(=3}nxUtX!Uq-q)WL{Zt+9?+EXw!)5*Ym#D}RoCd(m zBpA?Ix|mrS#wB!mq8nW*b4FHGDhAVxOsXkDE@KqNy*xQ{ z!>CSXYX{L+XcEz)WXvx*T8;3^!Ni-|1vH$%}44c!zM@Ovq3rD-)6v=|W`%Zs}mr1%m2m;>l2Dw{}pkd?zJ) zkUhrg?aHi&J~q$37RKz^gA9Ww3gUl7Me50OJ3b~RPALKMn$~4yNOl0Wndm!=J|6$H z3Gn$lYA8+}10SEyf9vfvhUbyX;8Qq>aZ>%ue~CEdr@*Ipn#?EldR))x*@9*h182#6 zQhGAy-(Liuk{0^-QaaxZpItrSGx%Bhq^69&8e_(tSE7_|!)fkXO9O^+zx7W}nyj;a zfm&E^T!BQ^S=|udY9EZ4){3r3#QY`0*o+Q7{zmaK5U%g>kub>-X(@H zC&M;-!U`8IO3BDDnV%=$5bMF~j7+l_@jUrH@zlkDK@C&IwdH_W8VYgG`GDCPW{9P* zqcU7DU87Rr{}teA8kUP2uLmqNc^Jc!Um;eZ$uf#e zHnJzbQl#GkSZq?7Jo&?f2|buG(3~K19xfi~1bDW2w}c}^4Xbd08IW03iAf^?N0@9C zPyQ%zHujD(F4l02xPzgWXgF3(CA?I_apHc$Ds!kzJ6_yM#$Kjro+xa1XH=WhWVw@# z&SnqbWnG3{i1y2Pk!-Lhoerv;%azz4kUEwXYVSZsTvh-AI*P z4f11nWW;{IN4%6fP{1d6kY$+)e;dasM)!=ad4pi~*}v

8?H5J>x5^s=r4EUY|Dpy&as}q2{wy$0Hv2%FXH!H>kHInu=PjKP;R|B1ZIeJ z&l#{ntOqJ!f>^2eZ8NM(s&Q7zuwqEP*02tE4C7^R{xJ~f3!MLIXYl`zmmBz<2Et8i z%{6SO=O7zi>qlr&pH(o74K)fZv8>MUPq7wevY{@5Gc1AQ-GJ%!&)YXHa(S`VMbhDt?~W?N@~ z{2XgbZ#LAM7%_6KfuN+PH5`L^FY7Zf`y}fCD%IQiC&Je_AL~}6%C~~& zu%W!@U#D0>2vlF|28#_f3(x(mQ;umgxMNMB>&y8cq!fn!@4WWF#cg!=b)T7 z4C~_y4C771S`W0*u(ch+*|XxB1Di{BVvU4E3ust&JeC-n2GBT4tD51H>+5TC30iVbk)1yAjjs4%Ri8 zRwi<3G_9dxPOKlf_oTz4a2<-Oo+gJ3mUHh?y$>H54bB)eiPgqL5~CX;yly?ZVBq;!o3rX zH52Z)$S(@_S;*lmxZgop%!a!iZZq6h;64cV!Bo@(?xW}}55v6+^`8UxcW~#zZGt-w z?sX{V5xBh&e?Ht2wBw_2dqdJ5gS)%HFn$Yn(>TzD9_~F9H@Fduq#?L}zJmPmTQ?SxKYr`? z;C}<$kynyGe(Qn?^2cwz0De1g?>UM5@mupC%P!pa`;tF?D~3K8h3h~NXTkjt`OSvw z1HYQ#UI)2&5blm!$REEo5%qo;?(Lv_4%{n|-(0w7fp7ERZoY{8@mp1W$REEo4g7r+ z?th`2$KaOqBY*r>4a9i?+y^rZ<9Bew=vBXmy8`k50Qcr@hS36dlGiZ)2=`gg_b0et zfxbV({So|F2)7c0&f{=bvF|p2 z0%NWJLMz>Goq|4XSieV&O>6ZH9Jud8t9q@I!84!L7ZUF`vbv%GUtptI1V&q@pw~^Y zt^v)4H6V|}cwf+yVcl^NhtPqLks>22j4JyA@0+(X#UaR*X*HkA+#iwoniwMd*7G9} zXf=T96st4ZAl3R2E!WA&dKthM_{@BasaHwb^3c~j)(a@lXL(7LwQ(2%jjS6H#~1j@ z+$KwcBw7;Z7gU}vaLD|Lsow;Dq1UUK zIwOUtZ-=CMjjZ3Hp?v|rryM%e+72l&tUT1yv_80svGPzeuk~V2mb3|N;;$}a=#rlC*VfSwoVu3@U!0!0-F$b_DJfr+Q@ zOsK$YW*Eqn)TEDxtYrtD^n8NMb6|l7mL~EZGz!sPNaTGbDiK(b$oq#%z?Wn?=AD8D zGY%q?)E1H^e@!Es*$3J@k0K!bvurFw1^(fE72PUlO3htH;2kg6$9m+9C;ULeRB;vw z|4_#C-1{L4_2d_b zNq)dxUNx=jmow$RP;N|@TPV6fnghFa+7dAeauhhMLrXCQxdY_(Ft;JEO#Z-!y9#N( z4fxGw{Q^h4^hy719_*BW@TGM}o5|XAmd|Xn?*<`WXI~Elv2tZ(b38Opa5e;}>RKdx zF6+tq!v#&@-9w#2|E#XxXP82;T8l5GxJo%HwA4W>3SUyGE zSS+EcV2yaQK*F&y?Nrfvb|Tc9Ki?F0P*xQk-uwlo*oK~;z%8a2_RA!^&=ft*({H>TLlZ9-0*+aZ)>4!|$IL!yf8!6TBsfha`6?+%` zWGoXB$G|k-T*iF@KdfIO2X@0WAJm(X!knApVd#&P%Rm?3UJ#MH49&FE8_4qcpby1h zGPb9DrjUN03)n}Cp--%a(hi)aVXEqK#Tp91&l&{=YnUO1P?Rb)42Twr(iK{EvPD`s z;4gG&Pca>uGceZ2wFggro{&msf)4E`q|%AQLh%8r68JA2S|oB<(A~b9(PcdOCE_q; zVY&`26@Rh-ANE~}+IjNJ#T6uSz7DMrb1^Ig9@Vf?Jcl7F(Bk7{)RR9#^kUk-=+G+h z4aTOx6B<^F5_0274M&L)g8=_W!!hE|;{cavI9A*=9`FSX$BDWMz!!Z~=AQiVVm2fv z@HY)73T${7fwemFWU+;zuW2|%oIVtAqlPu2;!4168cr3bl8ldaR?|dUDd0{S>dmh+ z#SC`R&ovI4!b8dZTH_{DyuzX68{hTNwch-hrs#$7DDa(6NpdqJ{};gD>-cj_@j6D- zfY(1=#z#-xMp`XD`?c(;8(7g4jnPwc$>CIu(NjlyfIDf7o|;1P(=lj~RXx0#}rJ+qfTEa^qhy`UQSB>zfD?@m*^ za5`{rKUa^u`MXS!&5`yDe~S#?V~Ss}C!eMB--~dTH&Ww$$dBzjO5=m3sACVhQRBm= zc$fL#?q|cJJv`z$^7C#T9`=aa1#qMPX-Qv`M?A{%n*FazJQJAGJzvLf_J|FgfPb&? z9FJHq9Joc}`5w`Qo#U?>FYt(h3gD%Ft_6GZTRh@Y(!WCEg&vXV0dCXuE%J!299!0E zyx1d_QWL+d^IPf>bD@(0ulqMh`j&Y_9ozTsI(&sk-pdGl9+o=bt>)!}U( zv7F`Y(0H9ke2ab>_*~=l9&s-F>n>gX29LOsisBoMH+saau&@FLHQwqGFLN9{s_{0D zSkK;JSxO$ad&Jv#3Ir_0{~aFj5&4~~@lKDJM!nQW<6R!{&r^Z>YrMxJ9wz-o8t?Up z%dY@FN9VuKBf2yHt2I985zVas_0~{S%bR}~nBn7fc%4`D3jj~ClzfG~;%bhmO**{E zD;BW-&DMCPSF{WP{;fqt>CJEUia(ORKUsg3{Gaa?|Db&QRmWf871M73ZqvBMtH#~+ z8ZY#!f%i>|1FtuKkyrc=`~TZIe7#p}ECK#N;|*TX#P->#@kXzR+yeZC##_C@hSeO{ ztMN9ka5<9i*Lb^E@RF)PXSvnk&EMe_14&;%X45qPY|VW0S-FYtJc zn|$IB`}1UtXZplg%F~@1H~R#3@QuLK6s2G0_{2Xdfg5!Ae4iLR68IsF7x+Y5H{eG# zZt;n5FW^NQFZ78=Xn8!V@gkq-bsq3ajTifbjX6l*<&=Z6eoKAg2;1v*jhFevui4)> zrzm+^;S+zM{(MiTU*!|O9RmEZ#%(^4N_pF*@j9RQf%5cq%7A>z!+M`+q5j&h!#DWE z*_2;js?tvzed21;o1O|^#NX-@FOuGF8gKK7pIF}8t?FlEtdeFs_{;r zSXl~Otnn_N$R#~x8t?ImJshtpQ)?xCdwn8@{k1Ap@qZu6qr8sR@elgM$>jf7jSu_8 zqZ~YM(zwnq-e&tx(m3oFTgi_*G;Z>XbdDEOHJ<4gUdsFZ8aMmJqbzT(#&i7QZl{NAX;SNO$nKkz#mukwo)tX>2@)VR$rR^JT#X)5RPuw?yW9{cwm zjo16d`{eI;8gKB6T$cBPPQTGFUZ%X8opk&Ab8fnG0><}Fik@x2cT6z?whrI!7q3wt z1~uN{7aorHy)@qG7Y9ZG7ihf8FHU292WY$p^}iZ;pvHUsqVF$&%XE4B{Nf(!n+tXL zLBFWv_;j(xhyCKSRN!ij>nt&s_R3g|!akC{B z76RX^@f=H>JQ4VQjptk9TI#PxjTczrR_fZ?nW%Y`<4Ezt&l5=JJM) zzuppS&OrFvI{rpW&2-+^c&jB&qdxgW$KPg&%^u*G#ycz_$nU*6|6P`7WPduK@g7S| z;CTB}r;`du-(J+8?U9nEO)*iR`U zm+jXtjcYvK{BVl!aC|;9jq5nx{H7EU=nZ^!8dqju&!&j!r00^f+hqC8DWY>v;8D8# zIVoZd_1P~qo}VIqodY}}P090u6hT8QaJ$AWDdOZ5;JYU4LvO5S|67XxD=czf6nC-jf6~cqT>hg=U`~YOpmEJhf9;TcbdeTQIrM{Rv~01Rdr`uGIFogrr$e*FH*B&;(ms`;Jw@yWzy&(1Jn;}2@;gZpS6T|$U;dPKKt}E- z#!{XAIqisqg`yjCUYPbd9B%qQ$jr45#^|67dOnDNZw950g!P zOyF{Or1_%MWF}{wBwt0~6N0{klfjTQ-)0#%1n=DLP%S=RpjSEvSJ6uHPflm)oM}JE zaqiUgak4f(B>V{p6>--hy2@TY$!Z-dDu_M~kyLaJjVd~0BB&T1={(ZhFYs&{JD!r1 z6~{`-OUFpcs|iVwv+IAPsoAwqt-VFJc7|&0w`8uK{D4}Q{50)aS&MA3hsM{p8unDn zlt;82@JEtBjbJAzam#9l4{n$24~Vg0i{15eTQT6R8BV znSejY<}NsCzWed3!YJ@EER*XqDl^T*-zFk`l!(+p7X6UZPNYinwE^@nDe>`gxaE@O z^MWfGG~CmCUHHhRPxIyQkqZuKz5+f{b7!+(2cAl!L@UZJN06dSKFviWBpA&EcgV-H z@R-tq$0>M_vVByoD%Hg?g^JbcnVOlq5uUwj&n_`Cdp?0Qy=n&yG%|ZB-{P~4%#(J= z2&G15Z=UYxHGxs{_R@0#qn>;Kk46f~U`$ya)~7A_^VYo@5@=SqUq@#J3 z4MAo4G$3M6UuMBDgeU?|VSc@8NkCua3j$8Pis7=MkZD}I$wNd703wBZ?k3*yfENXGqC#`U8spD3=BC&N=U90?xDK%_KZ5WhXl!bF0E z*cqO5)FL?l92xCA8STcON9&Mxo%uoN=HO$u$y9gARI?JP$fu43h9~8E#C_pW8TSwP zRg(5H<4ehw#3U$E1$6lbBq$tQ#c6_lH|7SxRx$({%$`&Uw3-1t)U$CY&`Szc8uFY_ zT0h-p7Z@I96I{o#dOrfqRMa*2=BgrOnNtD(P22FuET8HHwE2)kKKoQOW^hX$8!tcA z-fjVHRY=&2&Ifu+p$z+#0MOeC1?&)GzQb1`Jo(u+kH-eLDb&;cB{Wp!3MQu0Wt2KQayNgV$s|3fyaX@6F*9EUJ^NacO+gA6y2%4Z#R!f z+!7RvZUp`>vjENP&0iQ450Za(m=zK)3W}eoBJR|9aZu2v3)Yxd%kZT^v5)v}9lk6m z!q)-cqwxyRI|BG#^DY^GRZzT5b^RN2w#02gab_9te`~xhD5g_8-e)eC;p>B*^I?g%2gOyCKgV1t z@s6MvbULtW?v!|EPz>|{M@>J9!Mb)(T*mgAWe$*dPf)as0)E7-l6Y@W^rrkgZvH~z zeL*oS6Zjc(mc)m_&ntmfn(s;+&JsP?KibUiC2qrHrLun6qWks0UXQ9zbGG=N`pD-|^v=l^Pf-8( zHJ+a>E+e)yUXU%eviuZ{Te8I!LEu!47iNpX%Yi#-yeM1jV1G{2cyYGqMtMs2X!!*_ z6M==s%d*Aa3xPX(l>D#A7QI)KH@O-;W?f!WqAwxh^d2tOFi9D40eqBz)IT;GbB^~Buqe9a5N&* ze6(G9m^4(9VkAfVP)5i^r8DJE!mL8#T=-_Fe2&U!RI18=l*NsKYDToa@Kq)n%@tV= ze23t5;ZT~y z7xFvKk|voS$JXN`B(hSARXWqBWPFajCn7MO>jyGc4o1AptGeSyKIvxW;lzx&l0q*Y zd&q%SWtL1B-uELXm_>5^he>aa#U0+VpRvL+jN@`rn5O$)8OAYLg(dRLlp@F<u^}%16$y(|o<*(ZjrjDI`_$NmF$jBP-IbkkM!+Bt=V(J5@%Y-Ee$_i}aoB1Ufm4=3j%H_MvFj_uInKP_Igi*|IWh~l5YIPtH0by(4o6@ZmC*biQn}Q09 z9!WVKt9auzV~QT;a7L9s$4P$+$)MOPS{Mc8seX_RAO`^&6|z*QXihlpisN)-O$+1r z-rb?a#vngr$P@vS+0pmi%;VE3MIf4gC83!WT5}A?< z2|a_N86}%*Ai*+ECXApiQT$|dI(rgg+fQRRqtiJ|!{v}0I(HzSeQ{TyG8W6_kTI~2 zI#ntp3=cEuH1rhY(WMHOXm-|VZ!^EGKD^d)=3JS^uxl|V$tqH5eBExWonT}YlQia+ ziTPL@347p$9VkPVl{HAE3t&MD1!R@fB7aZX2$a=p4<3VjG`n;f1&^Hk{^z3bDwt$B z1=L=w%pIsq&M69|+QZKT>Z?$O;bF3zQ@hGoc<@Hr`W!6@IFly40c=rG=P1Q z3r;+ElvAj}QtjMKpwkr+HV+x)oS{&L%_BoOXDSr1H&g&=CS=>6`+uHs{%K`l6Aj^?Vod@%ED*&DF7NW zM~0=^gDs$o6eES*FafCYF&P%HZ^W8N&QON&XqWxOaKK>-&N1z5R%p0_3rzd)&442m zTxi;l+yr>Bf{RVt!E`6*k|&X|H-DLFA3*EmTuO?(`P)rT(5_dF^jr-mYL2h>S&wZs0UB$j&C^n&9<#r>5h(|1Q*Q+diHcwc_QL4=YmbtH~ zFkycKHs-#rP=?JTp}BuoC}4ke3($tQkv-Q|r(u$w`wtb?(|!bId+r+w<=Lp?A-S6s>Sxn3%-y0;q0J+Bxo@eR$|CzhFgll~wopQe&Gm`gcN8kMdFDHJn?mI_ zkDBDZt5Ai_W0ASxHI6sd4g*fr7{?Rt#xhoJm;XcCn}=0ZwQs@w&bjYrJ!{y{de*bnUVA|E6~Wf)i0vM%hD5*4 zZC&<(w=`ALmbI|DuwzZOn(IJ?mRozH#6l zlQTZHnOazN7-gPt^BGC6ZeitO8uqj`cM7j*VFfn>Z>P7R>RVV-QyTG8Ev$7ItDg2I zXLxK=wXi}lIz1gUKik4uKN-BE=I2^iU$Xx@nT##=i1RJ1zSy?$L}-4og;j=zc{-aM zFSuQzg>?`8zKcm;hwp`2mk|&=>N$GM0ijj|$5W)vzcSQX*#W$pZtoiKuHex+eQl_9 zg6-|0`T9^Rd^C7Z&8x8O+XlRs<{Lw;x3Pfn^wxZHs5Kmp?1|C5I@D@H_m0(kTd36% z;n5SP`HoPlvKTyG^O{h3w8hg`w{K6VRYt$;r+ICtbutwEIZSy+vftq96d>ieR zsX4aIc`t@1OY@a2TThx(W_Sjhtr3+lURqikQ;|MIr|(a&xZdy#)x0jjs;0fOO+Hir zdn8zq^yeJS4<}evO~7+CKayb8b9m-yel)=v+Xp;f^WzCt5Bh6?=Jg4d*%G|aWIVG+ zoJz1>;rJS6+As{^zX{d_7kH7@U(??TbAk`od~JX0NBZjs&DZz0uF#$%HLvP#b>#RR zrTNDG)=t`UwC0=pTSupWkJ0s4Lmv+48LR8x)8D#$J@`2DKt9`ZyuWpXvFZl1owV;% ze|d<(GhW;4e1GdB2F+s4FZQ=WY5z%@U+Uj_#yrC_%j_fBD+XAvaJZJ4X%bFq2UvG7 z9Nlc@N&4Xd*7K3zv$cDl8(>{v_?Tl(SLPYedd6hKGuNCY);phMRpcRgzOLK zxmEMSDON6{(`}j`NwMVQbUpDy!CN837SS@+HyG&k4$Fe)a+QiXRqj}9ht0_n0E1K`gv_^4__p0W#S=I&~ z-(Fq+{z2Bmj3%#{?M;?fH^`dJ+39ujywrDikUTu$c|%@kf}48>Sv%OC{U)pi{iB1d z|8mv%Z_Vom$-@_(1KQrF2U$PUzHe!Mc93;|(X-Axj39%X{|3p!BA$13`uc3^Afwem z&8xEIVG++E%{OMt!y=ydG~b*p4~ux-*StF0dN&jK4{N?H+qwWlc|Op5N4CW?G0%sZ z*JR7XBc6{m-;-?(rGFgJyf)jqrUd*`&G&z9LpC2{-fqqIo3h0K7Q7GV~!Qv9{d;0H|JPsoZWuaygJ8$9FZKeIM`28)%N@sb7ZK?QQeU3E>VcTPB{#A~3Fa6)9 z`KcVMh~vYq`L{XNn;ef0d3Y78tsLta`h!#RvpLq?EYGF+xg2ZiSnvSN&*xb0v;BdZ zU(B)iZ|yxnnqSJXEY{aV^NL(6h~qt2^JTeKGRLE(d1bD(kp9rr_J@qO6}i?{`d2fX znl9GoTCdTc-I`bDS_jyFAvQH$_vBjNGk&PYfU(-iwd_N|)pNiY&$-s-rr_#9V9f5h zRzM5z7P|h!xmFteFI4j*xz?X7uchWkbFHiZ@K%~1&$XVyGQkt3d3~<+OIz^PnxD$G zUgCVxM)T9T*7J-v9?j3@T0e6P{X9a|Schme}p5^0sh}QgYp7kVocg>IFSzEe* z_t5-ko;9Qtytn4Z^Qj@iplIEB4tO<=_~TB z0Jhi9SLRz=xjwkw)^fDiFW@qWS)OYnvT>sOEL~))L0YY|RhmTQ^~% z^WqzvgOwB;Sg1fahs`G~ara<0)VBPcRusYM-$7#N-z#2yL-=Mp@vcMWh z^OorJ6$MsrPTv!Bcvx9ronm z3ap#y9`iImSYXX!cg)xPaDnwT!{05MA1SbIWBRQ+{2eW@T84oy)amsF)`lGLMVg<2 zJ$Ul8So6~bR&@q=h301qtaWtfJG6bz6<9f`;7fJ-`2y=A!`Cufx^(x&0_zyv^Df&Y z;hPJsSx)ffwhH0Zg;pBFQKfC2@NI=w&_M9}ZF_|8D6~e!fUnfNrqGIIxO-6ZJ%!e4 z>aWqf7W(YZhc(|1PWN1^d0nA(lGDwjnjb8*;%Kk+njbE-22lTT&5xjcJf14ej}}^$ z98OQ#zLoYJFSKUz_@2_dzR>!U!*!$WFGl&kQdhxE7)ehtWO|GhLF+Q^5TdH(!Y0DQtom#r;UxVJg(G zLvZtT2>!GVZoUn{Q;1*+%^0}~;AefB^A!@FLM}=1jDXr|)0(Mnz6rsvneJXqchPBC z&G{Y#KO5@iYY_Y_&)ty&rI1g}+aiX!`4R+w+DNzTh!m>L-LY=I0>M+L-+YGPvOndvgvLC|c!^%RL_MVIuEFhkGkS*X`;=d9%Ykha>e4MXMd|J`6-l)ik{gc^M~{@!BQM z+8pi;^!qziQ8l>MKs`1}#uM%$VG3KN##f_nT;60FH#ZweO}u9X!^(3P2Vnb|IOLJ0 z=f1bFlvF$Z_w!)~j0M8n3nAjrn+%p;S9#Ux|-5=2zxq3j_*yb}zuov}+8V$wnN4Zv9tJoxWPaK2i zUrMvoeJ~X4QN^aaQ)#Ysij}#)qP40ND|a8@$b3Sv1#18QNyQeqy$MKricGfIZFJ|2 ziY_zVKZk=pt!Sm`=5xp%Zrjoqa0B&Z&`pZ2G~F}lp_>(5gDYiRr*2UcBeJ3;=(CDq zL>}NUdQMS{$U~&nif%NU&zTMXef|sB85_p9Z+r3-!?RV<)290g+WiHkjMvGRaz@&w zXtm9KTOsI6if*&H-wgxZt|+dQeZbTmiq_cNL)(Gw9JuNQ0t z@Wx5XL^lOmOcW{CWg-o@nsy^Z%AdGMQ~t!v$aWWg+L&CcDe=`?FU7B*z}2hD%LUW_ zQWDpM<~}Kk%cce`h|fY0#w)U(r)^wFH5=9){vOs<{1n(bh_DKi45HCFHZLCV&^%x`J(S&TyM_5LLcmGUSl-poh zub^>E%X7C#2J5ZZF!!SVV6oAXHq!kKN(_%vY^?haMBwmvrCIErf*=~+N3lundn=aP z;XX2%4}Kv{KZy+Tcufjhli@^7SR3G?EGEhDfr?^2I8K_`T~aY0Y;FyjrBc^m7+1oI zG>14=kP)yN{QCyp#^iA|y7!5Fr{WVAmGA{Bw=sEy|4R!BZX~rar%^$^7>q;jBwfd^ zh64WwLiSlulGjBsi?mV=I^OnhFVnE5HCU3Q@paHo_;b+EN-EzRcrg&QG2g~_D8C?i zA3rk4Xirr>qx`3qsUWbWs;d1p$M`f-#=!QU7uc^3a%+(p| zttPH9JrOKi3ySfuu&WG`rmk;$P}G9}k>}9z_ETr(We5?$a2m zPQA**N}TQ0tGqz>5wzPWt2~Cky%?BIS>)llb$3gIO{c8!@G!EwZzz~7@px~_Z}52M zCfe8*5$^Vq$pVkh{mpL*wne3NcArTFljWT)BFb&EgURa77SY3f6J{)@Ebe$F%DXX~ z&#QcWczBM_8t;?C{z#_gC;Vr!4I7f_nEnH`t3xGu?d@~T&2{)nzxL-!JcFOHdxDhSDJsu;=`H@oIh*i}<91M>junGXrY2S<= z9)fVEeB)e?(saL6t?N>Z2o4+Pk*38ML3tcOrt`BKCt(B~Webi~ArE8XGi3UHCx^QQ z{Z!xY6zEQ1SLyqmEO#-xM&IugBIm@;lPr)UsBe+6NnYkP@UnCQ`p>KRRK?h5)Qm)~%bjX3R~9d5-@h%HScf~Io*kc+aMpTKb) z&R_N*)g`Z4bbZi|QA`#)uCr*g-NpZH;BdWxZ@ga?HMuYq(ck~L6S0^ zJl(=DSsLta6?4RxazzU#+16kh9=9)v1p|#R=5*T4xA4<>8q8U7%w{+P&3&_QAK@Is z8D!cK3s_EDj@TwzVv z=+?SDn~SV&I7FvMr*A8=2Ihl@Yrdn%>KOpuR`Z%7E7%6!PUqiKWL5M9_uu!lzsNe` z2Jfi#>x!(S9E=ermo7L%Ewb){VVs>!uBLDwNm1+4vWbSXi#cXI`NbluEswXWNjJci z*AdnZ`h2A3M@Lu}M}S9Zetd*Af*#vV^ZF51F8wlEItF`GBdo9t@EG$nIto`}M_BzC zXA;b>gjbEUj?w;J^P=!=Bds7TC7j7-i!#w4ZQV@I&d|qOJI0EneFyuGZ;a((WY06B zMgQO!D~182z*L)JE5=!GA!IlUHD5W-$|wdOrt_~EXXRc4K3wy){ldKH3XQDYk+IMlPmB@K_ zk~tjQ5pi*;&GKQ9?woASR)UZ0)(o5pIH#CvMX(ZYhI@!jER`x95o;lMl0H05?ly5m ztcPG%I|y#n8dVUij)34ME!YS_Iwy|lTCf=c7f0nREvSaz<3SLVX~8xKcCZ~cYrzf( zvN}RA$K-n}91%4T9JE6)Pixddu!qMoUkmm_usaHZ1zJ!C!B%$1En098f-o#~oD0p@ zLjJg@e5pno}!^#>3fw~*V5pe{9jzJLI zu4_38!5H@X9cCD221mqk2=Y0smYPu_SpU1j^0L}xX0j6e*I_*#0>Pc;FeShX(75aA zyvJmSht=xK~`?5wQ`1EbJpXSIAusj)=_=B&S1gpIIhlR6{T;8G@DOT}tpm zpp{1ht(F@d91+z&1zP(MQk`qGU=IX;(WVcXPfC`95Oild9@c`xKLxg)F~M-IH8+bw zJrp{mLE&HKD@yQNpe1wK<0em+9TD~a4YXct28|8o+oG}Zk3hK_(fOqIsN;VHww^el z%y6n3f{^8}Kx;AMmbxRz5pjwF29l?>jZZ@`h6Ypj068MgLg1iRZq^#-AUH>JY%z~X zwdWz=E|v3H^PC7OE(cm~cYxqIZNaK5fz~93JG{+wHk-Z?g5OxnRx?}#2O;Q4zkNZT zUq;tLa4jS5HZ53R5oBdYLhz!_avXxBBnV#88fPJR7SYkUT??vj53=^ALa;;b9>uXh z&}#?;FKfX$2+nc*?9_tu5IjSV+NA{-Az02xSfd4(Ajst5zoG>dcLZ5W6Cl{F4YUk` z_Prt4s|A%1?2UuqbuCx{!FGnHeOj;*f-i?b@TL~5f#3#?^!-|}7J`v9;oDlU9)df0 zEbnMR6$Je`I^LCg`RK?&)&d6YgWA=rA$XTjSKSZfh}Z$a?X;=7AqcSmf)5b@okz?b z(l2`;u(2H)!8qA^3&%IHj|kf*^u( zl)Br<5pf!V?r3a%Yh3aVhj11TMN| zGp(_0d$84m4x?^&fjdA@z%1(i6u1Kfzj1Y^Zb)%N?1A9^<`8tY*^tu_Q47J_Y^l1X z1IGfv_nc|fJsFOOItX0!u>@W1K?vs2*S%VB7=oMWFzU7l1bztk&%m8oa-rK1aTJ1` ztYwfE)I)H03}i~)c7wUt5GhJv6S&wAuFjC+1>-!4XAX!GObn>O*Ji&IJ3Z8*OtiSC%tYCt=6o*F-i>NQ4mu{M_Wzrv^pplC?nWBA z43)+?T+(nvER9pR$}8XPm6Y>%BPlFHUCzvnr0QIeX+?&?NxD&*&cS(Dr0zy(JW}4Q zA{%?0cRN&}@Fh4rZnATl6=i+G%K1+e-i5+{K=@Im(GM^j#Sb{=HLBxkzeCyJ^e1VN zN|#|*IBbvv%#Uz-7T2Z$1(5I~(kqa1g&M%iI*d13SB{(EM!2#D>_;tz7?ECsfA~8Y z&;R=Q^+v!}V16W>*L9jgLF~KVFKusx@wClZWMf*hB?$eFb}Iws;QX6c?c1$dilgHB z_alhT?H=SY+9GVtxeRHyS~0w!jM>_)IgCP^y;{l=wkKXKVTZqjm6&+iy{tJs*&JmFM*)z98dx@c`ANF*oR%huy_oJH0jFr<{^@<1>IMn=H_CD?Y9lX7p6r8t^$_d zgAdxe3ae0HPuk2?B#Ca|HmR>v{Gucy=Fw}B_TRStv<{F};8TT9>=$Th&y#36 z{*_G^lznTAVO}BXc5AF*;(1Qld+ULwine)nkc^6RE`2bYyTB<>B9*dUEE13@X5G((w zlV92cdBr(nN1~`6^9)B{mTAOJ)zr(^Xc%!!871k<*aWg=P~9`2pqz6&Q(<}tfzZ*z+}#$$FK zWBgYbbC5F}#Am=c{J0j!;>W+n3uf{0d@2%h!9Nebio3zUpG(=%pNBzuTuO|-e+2Ls zqHTn*DQCQK>++1zap&&J-z`kG*SbbRTm)3V9c?=#5)d)8ADcHIq_N-@y^3 z@gca9AHUeM0Y3((HV?}AYJ4)5tA0GIV*{3uqMpTwmk^@yjsWPqXR`kI783>YwK(zT z2Liuu@=9s^8@2}A6QS2UZ1Rd}{HJjZm^X@;>f9`TYXhe7J~Y`ev5%sP=)OFJFQlo_ z?RoGg6kZ6=GEXXeISRO54nO(@*wj=fQgP8&5CV88G;IT!^C*K zl5%&|Ompz5&uCshG<~Y{Uo(I+6y^)%%z+NxE)d<7j+H4m_S;1ehUIC95hO|Nz;H=N;PraX3o6TFxLoy?!>FQn;YqFQM%E0 zvmIOI=vBTKq>gSZTfw;KbF|`%x;!JcTvce8KPXXLG#}D41DppCHZaRFnDsRe;vC(c zt)uo{WKmH&TcUQJB(mdF)Xr8>dpA}OfidDk_Or->=`k>dR~Wla(4YsGgMqPpjj_@F z&rzthmEANWZ-ZY zanOz>s?~|oYSx>i4z5c$7S;hB%%!Ny-X2<9mv6}}VHgQG z{7RX2L5%)iv=KEn_gQ=fpzyn$JSf|$v56mPL)1Z<#rWj?tD1151lETGd7TQ+@f>Kl8 z1b-SSsWkvU61)I#ode1E>;4dzKks4<^GpRM9lizwjCaL$gJBPfVHqqANe#yJGO^k`_%5Vn)N< zEZOcQLmL!(oeV`P_5+w|!xq(sK)Q^yVTWXnKn1D|FAKjO9Bnw4j5bu-%yXdkV}orx zeuwBbR7xBED;eR|k}V9~msE;s?~%kbP~*D75h$dW%Up>9mSg#H6QoN}NIJT-my3hl z%;RD7c5x`!p=Ct2YRQAg+ao~Cua~M3x+zemD~SP{0-40ox;d~RN^A*~C^0Y+xtc?EloCh|s!Dl&b4Z{O zyNro4=lm)XJ;VGK7>)U++buZZQ`Kb@BfrLD&~)?nK;B>){U!(fMZs~=yjWv8gLoGw z{`5*GTcTa;ZdTN6Fck7sD0E_D-pp56G8U+eaY}1^Bdy{_S|$GCubaSTEDSPNqEF66 z;iWmS{13~OgDsRGJOYhNf{7PNAf5}BD6{FZ`G8Dg`Tvi&2zd#;^v2QMs_J2n{<{Iz{;mzHMNipcZN73j+nI-O&iuxcS zQM^R)3E&y+5p~ye;3l-y35f^%q0`UVO}rL9u@Q z@BI3FYf+T%cd&(EJ`)Z47eP~iw*U~!IE>Dr`)XO~lR>HLz{9YJNL>X`0^l{^ z=Dtl}Rbajs0eJ53+Y1l@|I2(E!1pn}D#*SBNKUn3Y~BU&op3ov3kH5jqAA$}NpDCp z>i{y3;LGrCMxyUwz%(X2$%L&;Fp|$9rI^`xYC8d`zHoqQ03$ijjv#=3^Yw)2SBShF zAn^?VYmNi*4Fu>ykOwdhAag80W+}b~^8Ec-jMmniK>rN<168C(BaF;}TB;p@Q6{x7 zz(#`h05t?H0X`#W3h)C!mcJBVDkM!2bI^_iJL;K>dNR1PkQxD(fy8VQ6oKXrIs@6D zFY%?4|L9~G3z!@fl=eT8UqNyelLLZE{+^t|!dD=)c|Mg_AG^^p30xdYp_EdeeA z3<2PuIP%*Vt{0i{rJ%P^t~l~MC=8|}E3dql`YH6{51<@^dC=S*G>9HAN~XB(<5Fn% zT^On6EG(qb?^cm^mO4u+n}+4zEIEC^P9o4qlo>ClsT#`}lg4t!q_IRqjU{B1H9BS0 zSVD!yZ}ve8)TRIUU}poCbDi1hEJ@CFX3Mz_@zy?ZY5nq{`e)yjbD0 z5x}=8{7g^aC4!CX8B7^iyFmCNES+@^`sPmvhqMB4R^siq0BP3%V7-#&kzYqzr2Gb^ z#mldimLk6)X+z|_hqRa9JYRSG zK1Ge|0QLbG*K_*e34Q~( zpTL-hwh;sa*xDkC(S24ww4|BMw104~8UW2?{X(Z#S0RfOw4X z)RO>92|fn+2*A6Up0)}(xJdD>16WM33E(q;az7*oAmM-gNnu2om4rE(A@1L1 zDu?JIB&2f8?jYbGK1;w+9n}?p!+a6}$9)w61Ho|uMuxCR0EUV@0>+L?0tS;>fI*Bd z5^F9}%;=L6g|_FR1rix<1Cz+Gmw=IhcUnqhm`=dRu$_RB;X49GhK|tyj0__P7#S82 zFftq>U}R|D9e|->3;|=qBLs{MCjjv0tz;`|Xu%%ZI?Ge=KdvD)cPs16LV{Rl69KJr zl7QCnAgqXWMi9_Cs|jeG_X%j7;9dZ~&JZvfNAw1ug>D4!*845= zIG9-ILjqc;HJnl`R8Bw(?INIs>IrC}F0lZ#&=>+*Xd3}7Y#9d)DV2_21|7SI1m(4FG9bF;4Hx71oZ&t z3620H^aZE`SVXV~;2DB#04_wq)QtdB2-X4|AXov=^*VqGfEx+Q0k#4Rx)C6?7+=4D zc}vkkUmvt1Hv!&X3--c;koX{}hQyZ((5*kf7=ZNzQvuuq0OkPP12D8A6YH%kJl(Vs z(h5kOi2y4A`T-aj96{sJ;J^S_<6HBoRcHW5(Qu@SpF9IFh<-ANJ|g~cfob%Qff#z? zAL|L|A7=^ZA4%9C5&u|0K>s)n&@g&>BtuN!xDUX~x2?$N`45=*Mkf4Ld}BKS=T%QC z0DWT~0e$0H0{X@&0{TXq>jCH+i3IeGX9?&VEziJqP4O22O)+^O0EfyU0-B<4W@A%4 z1}3Hm%YrHD{HC}UOiXc^fWzdLK>#$xmjpD$u)zQ{MI`}EafpDXunz&CDOM2B6rn=_ zXo__NG(~VW08O!wfTp+rfIn|wAO!2+B~x+$HUYdvupJ;OSKF#PJT41*<`reDyOAKa z`ix*9s_vEtK(|REpuHX>puJ8L&|b;;0JPT{0@~|81hm(H0sz|U9)JedIYu#EC$SJM ztqerFHbCi4FtOMB1hiMoFaX-?J_6e7Gy&}uUIajU4JV+zRuIr$&lAvI;llxFuSx>i z>jVMq)n^0%?e!3V`s@B<3z(t<);!s3U?l9tbdWVqye!>2$O?ta>!vuJ8j?Mu7)8bD)E3#YdWx6TlWkR4wk)9HWdUVd70w-xK62E2!bEK>^p!)rKrR~# z{e-s}g_y#{(_S3dD)_BAz_#)soMHU|nUQ)9-#Jjp@+bRTFg2e7_Jsi4!=!^cr>`v} zk1;6iVYJV0g&zVMe^7l~CFg;}GK zDl1O)Dx15><>HijmCZF{5K*}p{CqaN21S`OY}?nO=IZi7i{Cl z0&oSlkAO?MF5>{W#;YXYqVEg=SAnx`0N}FlLjtZ7`;G_T!f_P=SCV{VZYr0SdBp%+ zYaSus;xncMfXmSp1YDs01dzcQF>(&JaoOT9+lP-(9V0z`0syDKIRu>Jo+RKL_Z|fb}gT60jU)01Q~I01R&#vvBH6 zrkqnJuGpxl^HBm$oo^9v>O2OJHR(|_WE~`&HhDvrOq<;S_?N=fbWd2V5(Q&5E$iYT zNR)N)QUb1vcN1`3e4c>o;sp4HEW2j|G%UOSOEH(-?aKkU?DozD;Iez-JOHkwH_Zp& zN}8KvvXWj0i^xiPA*8aB?#7&(d9YkbpT$R3(oGfta3$UKHmnNvquu$a=LtAxCRfu& z)>`&DDVLA@6GyH`N7V5EOKpqRL4l6^#*)U4Y*au@M;=ZCL~xK zdEKK_hha*PD2}|6fR6k+0Uh}_0y=WiT>xCH-9bP{t|Rz|9XSszZE)n3V1vbDS?I`9DW@ZEB;XqG0|GkoWdb^KcT8wmm)9erJ_ZRLc@QMx$YTNc zCyv|--dRVhX-DRyEsp#&0Uh}y0UbH)ZU8!RJ^{}k|3ODS&4Z;Q-;2urha*3Nc5^`8 zxbCVW*T5wfpjZFy$a|+^jcefmC)qL{N4x3BTTo_0L_W>Kp(A&OJBcF~6VQ>@6VQ>r zCZHp?$44A_3IQGYNdh|Z2?9ED%M}290CEWE$oCM?k@peMk^dl|BgfqbKu4YlAZO~I zB9LWS(k0E&c@kfqq!!P+j}fq2THFu7ZpkKKx7q^9s7VAIsO1D4sJjU`P|cM99H^ND z|L{Pq;}Kt-aRQrSlbs`qOXT}ey$sZ90uI!J09Z>vNe1d=$~jPbt^(jd9ZkT2x}1Om z^=W`C4$^zzoib2AWD-x*z5$RwiO4r_=10lqcw3Vv0O`mVq0!*T*F6X^9r*!*H2~ic z(2)~Y1JIFI6VQ>56EGqV#KK4%`2hkt@=*dhayXV?;>g7WbmT1rbmSih=*Y1T1JIG@ z63~%f1CXV~O0;+-TO4NVSw(dm(_hqLNB7{g!;T(9z>a>NfE|6FfE_&m(~@*_1;Ibu z(TCY+rc$(_E>p?rEkH=#?^lH2E@BjlDE_i_sl8A0jt*@ zJ`Q2xwQ1nD%JTd}@D#4Cw+umS34wf}Z4jNm!SP+Ns5t(90y_R344icQc^FmV_+8PN z;`kQYCyxIP0VDWj0y=&i#}ys_D*{IF2cHC>&p=1EM&?h#83I!LJBfcFK~DF5&jRpte+2{le$rCLztyE}rf`2qvfd9}w_#zspttp6*u= z@O1wO0Z;dvya2${{d5AJ?k^|c>HhZwJl!9%4S=Wn&l2!-|5pN@?kBwnz|;Me0QmFf zu@zi5zYl>}XUYhqLh9dzj(7>JUXJpo6VN&@6VN(!1hmdI+W}~u(FC;4Qv|fmSpr%o zW(NSRQ%*qZ)BrSC=Mu%VPTtFCS6y?oi`IDnOsw-B0j<+%CjhOpn1I&#fPmHs*ablA z3?`s;?jxXewi3`fAvFNB&MX32r-p#mF<$|ob&3GwPv&-xQ@l3i>fF8osS@(tuL3aS zFCk#a-%KE9le+;J@?R#9xqT17KOFKa(aJ_4zlC9Zf&rSzkT2o>eY8QseZ*ef+p|aG z#suj3x4z~hL3+EEfV~~`8UTAcoPfPOnSi~$m4LndJHR0Jw)AxB>j3QOWd!W$I)H|r zwrU|}PZtAtH=}mx=?!4g(=zY@^8!`}wrSbB+o7H;+q04;nYK!b%3P)rN=c^AjF04)#;-wmcLOh5|{ zJqSPxZz76Egbhg04@9w0WExyfEJ!|m6 zvNj(kqdC4+`>anRNlfu4!2fG&KK}!x(F{)zh?5b}44EGS&T%AC7~k(b9%E7}W|lQauX^<6x(HfK33Y1YG(S0^q_8lq3M$N;w0-Cj<-t_Adb# z0J;z`03-lpaYrp?JtW+Wn9L-e<17H+pDcaZ$Hgevzw}*;L|Hc-Cg8fs^%VfuO(_Ii zH!UUjhu2M2JXkJ$_oA}@v2LnI`mg9_wbu1s1XU-$a%i%#J$pD#XGY-Amf5CPqs83V z{+vzc-u6!bS$+-K+qQj;inzBO3XpZX&MbS|QB30Ab|S#v_O@l5{I~!yGz=Aa)i}w4 zR>L@13nt^_Gy%s+!YKfblXV0fCuayaPOkq3faByD0*;dl1RN&=zXjkpd6!&e)$##qakbpydjR(O%>?ZA z#|YT#Zxj5(y*)9&w4JBGc?7Z^B48ZYNx(SpCjsL?Dfz+oPC7J$Qi00D>jNPsMEWAM_H4D&mg#9_V`08t|bMM_wCjtLAaZxb-A92X5J zHF5BMo$k%EVX@12Ky5x2<59S(c3B=PP!FhGZuEef#&Q#y#&WOhWqHOzJ)ov>=@=<< zBx;G5XLXdESLd#%ht+ltfrcSZoJ2404s0qc53bo1{v{T2yLvuH9&U38j=cn1MIY*m z#LkX@uBaon8JeynUA3gcRY|0l#9fti(~|V7k{B%+epM2yC8bv-@k$b>>gl7Haa~vu z+L7Qii_sOM40ag<% z0O)W5r((+h?5ox;@vR3~0EuriK>y#dm%0+bOs+(W;$FfCo4Xhxq|-dCCN^UY%jSnV z-+mE|&xGs~WJrwxxB}oc+Mt|5FyBRd#se%NxCvkv!CZig1WN!0{};Y_~#7?hvXg9Sr17r>vZpg z8{uP4a7b0ZB05bRaaIL}n%06Zq-rT-5q$0^BLM@F4c&$$^CQR8JJ5!;kl|Tt zTy_M&ow~T}2(XTz9N-;-Qh;9x#sYM*0ptPX6AT2n7r=X%)o%pb0p{BZ@CCuE0Ks;E z0{}e$GCu^!Jb|yFzo9Apcj1;Vv}4Fmkl4#BZ0K&3)Q6&LF{bV1r%hw%>(Fx7KtypD z5!XVT0ntPFOrZF>t73}2!RHo=2VE6Y)b|y1H^pQ8;w%wCJY+~g*pIesbm6LY6bxGE z2Wts@o}#$HfE2xf&#M$S7?7fC_F}t);syg!REkey1A2?mG+(R5Xf_Wi0-&i2$6iTs z3|MzCUlKqzK^DMG09haJg_pbroner?1&R90GmDy_Bl?-eh}=)&^DUA};Xe6@-u?LO z4sPQpSl1pp*YWWf{1=2mb6-n%o=MNGknBC2Ti!!xt+HtO5u&LfAI-)dojVXxO$z2qWakr?KRXNahjU__rgv=}F{p+Q(l#qUoDN!1rmXR!~7&;W9#4ynGd! zM^n*&yXAq$DpcO_Ahxqn!-N{ufV*`AM#>#Jck|uO4+ojXs9WvKmeEmepc(aDas#tQ zY#Kqvwtfj!+VdWgUQIye_}M11Nq&|XOva~2@8vB!J3xmgm!g;z%=r=M=$UiyK*484 z?}CppA8m)Uuf=RJXz_e}Y~_yay3t?jM(0bTzh$Y9F`AlelNEJfsFeI?J)l%ch{IB5}$H{oe?&^sVNWKot3H{C&R5#itPovK^}*7 z+dqE~u_p|NUWtm-%|)i2Pput?QldQIWfT4rI38KVu_U~YQ&1YqvZuZQ?rMfHng@aJ zU9hfTzK;QJ2f*K0^Rtf7eNsJ?TaUx4{TRdbTKw}7#3mlvld>e$hxU}LAVGL%(MDN( z?uV|?{a`Xm8RIg|SY)F)$H=pKTy>6h$vt86c;+}4(~S^5q}lze3CMFF@{D61@rC;& zSCsUk!bW6pCe*%gO4pk$5%5_27wYLw6n{blD%n>SqZx7Qrb~VcHhKo)&N)p-vJXc|yt9*&5WNvkd4cWn;BZ5z9VH$5E0C2Uu zRqQ?})C9vDUKG6tl()CNARYKD*nl}m+$Pk%>hx`i*K^#z=&FJ#&LBCl6aD=q;cZ%) zMs&Zy;M>I>iF^sDxkJ(xBQ1%~lxyC(6*!JvrG7?+)+-j=8s%~wWWFrr6q7&V1>Y&W zRU6aD2v~p{8$Q7n7wg#PI*LinTM6vzgoF*y@bv`vfgk|@|639#d;sGBil@)P8UmTC zkij(|bus92$nlrKF;Iu38kT#&)od@83?Yy`jdX84D`*4u8H?)-&@`Oc2J-bm%Rj|6 zVtmZ^TqVer<>x-vTx?Z9&vy;LOoDI#v#o9j^#U>HxrR$aA|Yo(cz_W{vC!po__ga5 z6zR41Lc`>!5G z=CBU9CNb08z|2oT)(MHJYXLR@7%A-GWl&3{+6;3LyBL21`@L!yYreon#0k{BD&PdO z=Rp?P5!urLk^l^8;-4pRa)IpT)_@yc*GYWBhB0s(5x0k%!2G)qq8 zRLVxeZBX)!0;m;jQBH*NVJhbalv4S$U-?_Va`Pw?wP*09Lg%1tbb|8EfLbbt0sC%5 zLLcb(<^s$mr~s%WxEJ6AKncB|=~q}V;^TTkEF9R4#j0{wKpcaz%vS=!-axroz)~*$ z1D+~(Gy%(f<$eu0%cUh=`5M=3S?)Ul87y}#%cUjEXp}-rECkSD zqXyfO7w|Eyz_n1$@^c9r+n9l2<0t{cMnHFcT<;;zNBHQl5d%5vr@ex|fmgBq(7g%=_PT?B$Mp~akLzauu~!5#N8zK7%hN-Z%LhegLwt_qdICG_gGcgV(G;Z1 z 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 z zIBt}}As!@_iYJJTBHIvj?_Tjuafi|N{2n58cV1T`wu(t{zPLbKC@v9cpXL1*i zE|!T?#c5)V*dR8EZQ`k7O6(T<#Jspz{E~Qq_%(64c%^uac)j>N@mBE%;(v(uiVunp zi%*Eph|h^HihmY2i|>dZh&%3R<8{2apEyB0SUf^37pue*#9HwrF(I~#r-_|nkJv8` ziD!%FieD9%iI7BjP#Ym&J?3uZ!Oh|5aQi z-Xz{C{!m;eJ|O;5d|Z4+q@9cL@{;(f_?GydIBI9bpSY*EuXvz%uy~|cDIO2P4OD>2JvR`cJVH8z4)N`i1;h%>N}MLb1Ji9Oc@jt~4;?v@D;!EOd;@jc};!eBT_}N|DM?6qGL_A8IDxN6L5SzpfF)4P71L8vQ zOX7v%rQ((1O7TYVR`E{p9`Ql(QSmA9Iq@a&HSuln197LZdVX;q@j&qq@hEYsc%nE% zY!W-fq}VMEhzrFpi5H5OidTv&#T&(2#XH4�SMk#izvQ#Fxa^#J9x{#GPPHWq#jX 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

ptP308{yU@|Sh`rBA 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

7+uz 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 Ig- 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�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

ut*Scj&M0 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

TY&UoBr*Rh4!y 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

Y!e^}!!IieZ5)n2c0 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

jxzB&DY(cLU$3p)D!S-o?fm8HH=9$PY9M& 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 +sR?K49Xwc|Esh3a?t(z9q6s?43f!rNBYP?8yl; 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 #Q%lViM5!!BgrQPOpM8Yd7MW^`%~o1%b-7NI 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

Ptto+v-K!YZ9778MsrlCt$U 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

=mjvX1wFb?Ek{>)!Eg)_Kt zpn9NB5~g7W=3pKcVR2StEe5kG+p!~ius26=G$(U9=W{WCWR-k8G#$!SzXKH@Utjxm#3}Q)EU}e^1 zT{dPjwq*#rvnTuUM-JmCPUKY1;e0ORDz4`yZs(ue&%->)v%JC^{D=SYCEqeu?LhBO z7@vulf@zqE*;s_dS&3CyoAud*E!du&*pq$uBY)y3j^$)d=Ugu23jW58+{|e1=0P6i zX`bgb-r@s3=1ab1tUCHKJ`*to(=ZdWF+U5j1k11rtFs;(u{m3_BfBz;;T*&v9K-RP z##vmzC0xyQ+`{eL!~HzVi@eFZe9Y&3#~5|pUB+WlreFqUW^U$Z5KFQmtFSifvng9L zgk2cMa7J(_$8bESb2b-o8P{?HqZrM7Jj9E<%6ojs7ktfF_3V>hGBHy#J+m+p`mUur~*B2uE`qr*k$JaT(WfBe!uU5AX<2^E|KfHXrdB-!Vpgdt^K& zV@hUZ7UtzQEY8xb%xbL1Mr^@0?7~ona{z~N6en^j=W-!eat$LH#X~&CbG*dc{D;r@ zk}(aeuAqKG=E3qc)vI$!-gk9K+efblIa~vmeHs^6USMv{U;V$mw zF`nclUgJOfmoNF2aT?kk6EPXn@oVN{J_fNQE3qo;vLRcr4ZARueL0ZB`7}Bgs=IYaf1UrKW8E)V_Ifp4(4HD7GpV9 zVhz?|V>V+ucH|H2#ep2mQ5?%DoWc2A%+*}S&D_R4+|T1Y#Y?=#Cw#&8jM+HQ@qhf1 zUojOkF&p!-AWO0=tFi_gurXV)9lNmy`|(GP;Al?bG|uB9uHss5<~Hu(e*VqVyv*yo z&qsX4cZ~DBd&q=L%CyYLoXpE2EY1q7%v!9+rfkU&c405}WUpSGoIG0PglIyvN zJGhI7c#P+GiMM!&{>!I~-7L`WQzm3mre#LvWL_3! z307nk)?ouSXKQw5cZPEShjA1qaw_L?Ay;uNH**{R;sKuE8D8a0KI9X=;Rk-&Jkak8 zCS?j{WESS-H!Q(2titMSz{YIN_Uz7{9KZ;U;#f}QOfKY7Mly=KxR*!xH_!1BZ}Ki5 z@fqLn1LL*`^!uC%nUtxSo>`fb1z4CRS(cSqjdj_O&De?|?82Vx!yow*M{z7Cb2{g8 zA%Eu|+{T^U$3r~DbG*u%e8Ja@)iTiY6DDVBe$A{b$`UNkZ&`zN7|f<@!w&4m9_-73 z9K-RP##vmzC0xVx+`{cV%;UVw>wL+#jMXaU|Ns8)6DD91reOwVV=fkA5X-R=YqBmI zvl+WElzlmn!}&8Oa0(Z38P{$k?p|-QqDJGcpVF@*9?5 z8CGF+Heh46W_xyLPYz%NM{z8FM&@K*7G()mU}e@~JvLzrhOi5J zu`dU67^iY3=W{VvaV)!Eg)=yhi@1_& z_y@OeC-?9WkMRsI@CNVjCEqeur$EO~7@vulf@zqE+4v2MupBF~HtVwkJF_?YaRf(m zDra&rmotjd+|R>2&GWp*Tl|+#`IaB~S?55XcudBW{F+&rj|EwrrCFKPSeFgif^FD| z-PniyIg}$gj*~c>^SG2N8O3Ps=V6}adEVe1KIU`2XUs0%C%WRcKH&>~V61L| zUSBW)Q!ov)Fb9jXG%K?j>ob_G*pA)UgZ(*(BRPgsID-qgglo8-QHl4+Tl*_n?8S)8R=nblaA4cUTi*oC3&%YhuupE-e3xP&YCJOAKz z{>cM8!qYs@>%7f>`IK+?fuDrBb4<*yn2ujFC-brhi?ckxWlh%Q_iWDg?8F}I%^&#_ zCvqwmaT(WeJ-2W>_i#Ut@gy(s3UBitKH&?#V~igH9Y5t4Ow6yCo|%}Fd0CjnSe6x8 zjkVa2-?JmTGK}FI!V&z16FGx(xQNTRhU>Y7+qsAPd5kA{fme8&|L_@K@&jY_2=x7& z@tKqFpge1=BDyvok*n zu_Vi~3ahg|gV~a8*@dAD=Kv1nNRH=Z&gMKW<0@`oB%`^Thj@%N>Eh8Dl-Q34xJjsi^ z%Ex@pcZ?CPBjYhCQ!oQFGdJ@yh$UH(Ral$#*_16A!Y&MBI3qZeV>q7EIh%{PjBB}p zQH?C9^eID;cfoICw#$ojL}awe!;~2ifNgV*_oRKS(K$&o>f_c^%=|- zY{O3M#$N2p2oB|Fj^k9$Ea3Adm7i&+{H1@;|;|>;ZPhgiOk`%*bz8 zgk@NP)mfX3*^KSkiTyc)94_W^uH!~-<4*49VV>eS-s3~Q z;A_VGG0-h8<1-OcGA*+(2Me$;OR*fQvIZNlFVoo3I7jvlD+{FAiV? zM{qPJaw->dIoEOnw{i#n;sKuE8D8df-sdB};yZp35$KtKUojOkG7EDvKZ~&xtFty6 zu?btVJ-hM;hI0UiaTKR>HWzX!f8+1m%x&DweLTt&JkQJgmrwbc?-^%spx{R@-)x$J|FQV-!k^F z!1sU31WdxzOwVl0#eyu#GOWOAti?ub!Zz%{?(E6_9K;bE%}Jcbxm?JVT*FP=%3a*c zqddV2yuv%Y&u4tekBmJ$(De%@U~;BrCT3$k7Gw#QVP#fhJvL$swqa*>XCL6wkWSdc|oh80+iwb+PF z*oGb0ojuu~gE)etIf>IamkYU)Yq*J9xr=*wlqYzBS9pi_`HV05k+DbGClfF^Q!^8@ zF&_)E1k128tFay%u?5?(GrO}7`*R3Ka2zLb7Uyy)S8_c!aR+ztAdm74FYpHM@DZQ! zEkE+pQMxh-lQTUtu^@}GG|RIpYp_0p*@A7@iQU+XeHp=_9L;f@%9)(c#azX;+{CT? zlYj9rkMk@q@&@nlUq0n)zGs}D1ARYZ0w!T9rehZ7V15>236|lv{El_lfKAzw9oU&Y z*qZ}6m?JrclQ@mPasiifH8(JlJGhGnc!Z~Tj#qh;_xXtb@eN~+4)l)8cudITOwF&E zm3dfzK`hB?ti|SR%^%o{0~o;(9L>p`&iP!--}pPXatHVE5Kr+Ouk$t^@fqJS#+X32 z&l#UzF%>g08}qXeOR*fkV@)<<6Sidte_${E$e%cx<2aqOxtPoOJOAJg?&2XH<2hd9 zZT`b&e90JN1Kr{#lHNB!#R$VIGgjhoU8c< zw{REt@+>d%ChzhwpYt7K{NgS$9+NT!GcYrAGe3h^k`-BnwOOA{*^(jb!Z3z2fa zmTb!|3}rY6a41J|JSTHD=W!WVaRVb6&D}i2V?4`?yve(K%;$W^7~}1e@tBk;n1Pv@ zoB0{UlB~!otj+pt%9ade7zZ$dBRHCqIE{0;kSq8b|KJwxwq*!I8OHt`#Nqsz6FHT0IG@Y7iW?Zo z9o)r(Jj&BN&+EL+hkU|Ue8)Hw?Uo6cgsGU0S(t+qxAQL^;BlVfMPB7&KIc2em=x&xDZgM6CTDtPVov5|5f*1T zR$>j-VPiI9TZXVZd$KL|rIVI3HF5@vFQ!ouPF&p!-Ad9m!E3qo;vLTzX6+5yk!x+v8 z4&`W$<5bS%d@kljZstzz;ZdI81zzDD-scOxX3VL2GCmVACDSqsbFcslvlPp*Dr>L- z8?zPLu`7RIUk>Cjj^YGP;T+EAa<1k^Zstzz;b9)GsL^OvIE-%Ph>n0xZl@EXS&>!3J#1R&2+v{DFNrki$5N6F7x)IG^jdk=ywv z_wz7M^E_|x4j=P5-|{0rn-S<4kI9&l8JL-QSb)V@nw43N^%=}oY{zcw!Tub?ksQM* zoWTWL!ZlpaC`NNX5A!t7^9JwmF`x52W6lh8`yan#a;9cxW@iBwW@(mZHP&JamTb!|3}rY6a41J|JSTHD=W!WVaRVb6&D}i2V?4`?yve(K%;$W^7_$Q%KVv*5 zWeR3sX69yo2C*b7vI=XnKAW;7L)e933}*y~atz0FI%jhcmvJpOFpAOK$3r~Hv%Jci ze89(i#dnM|M^`3fQl?=BW@l~|Vi3!+BI`4lE!mb`7|L)C;82d_cuwYQ&f_w!;s!=C zn!9<3$9R?(d6Refn9uo+F@DvN@tBk;n1Pv@oB0{UlB~!otj+pt%9ada7ltvM5gf`f z9M9>T%|%?sNJeot_wg7{@*=PDE+6nYUopnqK*ua5RT zwq#p&VJO2nfI~Tw<2jkLIgiV@iW?ZoXzu1A9^+YF)550S2)oE3h(avMw958QU_1 z-Px1<_#=mL6vuNiXK^l3}#EVWfz7roC7$NBRQUvIh*sijH|eTk&NbU9^x^c zzGIBVfu5f+9+NT!GcYrAGe3h^k`-Bn!EDO53}Gn4IDiox$uXSF>72(!T*bAFWE6LE zACK`QFY+qy@&TXo6=N(3bd1AzOvn^W!_3Ui{4B(hEXyja&iV{y2)i(h;f&x=j^TJt z<18-XGOpzYMlqUud5|Z0mREU`5BQj`_>OUw+9eY*Dbp|mvokjfF^FYZk=0q7!EDO5 z3}Gn4IDiox$uXSF>0HKDT+dD1&Of=Ihk24`d4)Il5C7#0zGjSN_Q@}pfL}2cGcpTv zGe3*61k3YV)?gh5vnkuK1G}*Y`*I+MawNxb5*Kg@S92XB8O2@P%VRvr3%tVH{D)8Y zf*%-bd7$&>jL)x_ikX;=dHD@XuneoPI_t3!+p`mYU@s0}1V?c!Cv!UIav@i7EjMv1 zcXJ<)^As=gD(~?j|Kl5ez9P^uK9e#9GcpTvGe3*56u;$ntiuLu&erVA?(EHe9KsPC z&&gcOWh*#fhBCIh@bm`3HA!7Z33m&+r0o@-Cn71wSy> zZ-I_qFac9A4Kpzt^Rp03unfQDcdWw(Y|9Y#VqXsD&z#0tT*g)0%xyftBfP*Xe89(i z&zNfhJ-%dOre`MRXCanjCDvs_wqXZ`F`UCViobFJmvc4$;1=%W9v8H}>El4&iuC=5ns) z7H;Q39_2+|6o3lS%^U_&u>|ib@@G;Gn8Q*zzB}y z7*6JN&f_Ak;#x*Bio3aw$9R$#d6jqhfY14gF*fPPcudF?OvBvF&!Q~B^8A)HSck!E z$~Nr4ZtTIn9LS*@$#I;-nf#TDxtwdcfm^wQfAIj%@e*(G9-r_9-!o=ppzG(1&ty!= zjLgD3EWlzc#Y(KoI&8pZY{ic3%3kct!5qf1oWL2J!^K?Ab==5p+{yhs%u_taYrMsW ze8Sg!&$yd)Wg;eHT4rPp=3!wLV>wo012$$$wq<8_XK(i7U=HILj^{Ma;sP$=YOZ4> zqqvKEd4zxS953-E@A46!@eMyP?iPKSkV%=A8JV5AS(wFGmK9lzwb+o~vlZL13q#q5 z{rMAza~vmeCV%BpuH+VO=RO|d37+9)UgteNBee8~U!hB3DVy2j;~Ow5!_%dE`Ff-K6?EYE7J#b7pNJ9cCb_U0fC;TVqR49?*a zuHbrZVl;R2Fpu**FY^xX^EqEJ=63z~B@;6>(=$7BvoMRXJilcv)?-t)WJh*oZ}#I5 zj^KDs<{ZxF3jW4T+{)eD$KyQ3%e>C}e8g9L$GAJZYbNGbOwUX##2}VsMOJ5R2D2&K zGK8TF;{Zl*B*$amTb!|3}rY6a41J|JSTHD=W#7JFpAOK$3r~Hv%Jcie89(i#dnOe zGtl!hCS+2kVFqSrZWdw?%d#S?vo?d-lx-QpP=;{;BRG;{IGNKqkBhj9YZ=KX?&dxo z<4IoRRo>+TKIbdO_|rZaj|rKAX_%Y&8N`yT$SSPO`fSRU3}F|BF`N+`$}t?z>730) zT*kHBz$iv@9}n>)&+;m7@&O<772h$=F8gFcCS@9CV0PwaAqKH5E3!IkGnh@;mLUvf z7zZ$dBRPhXIi1V6iW?ZoXzu1A9^+YF(SKISXFW1Ky@G9i;P zGqbY*3$rxKvl?qLm`&M^9od7uIfz3zhT}PdbGU>nxSpFB&D}iA<2=vHyu*_-`1gd;eflR1a;xq`oO2Y2xxkMayJ z@D}g!8DH`vWA6=gi_b(%&GgL1Tr9|VQ7VN;z?8Uwu%wZhINu0y^T+Y?p z#I4-Ly*$oSyu@p~$A^5$w~V_l(Cu?3Vlt*>MiyjImSF`}V=Xpf6SiRoc4tra=OB*Y zXinlZ&gDX`yZ3@fu5 zo3I5turqtI4+n7wM{^vfaTXVHDc5j4w{i#f@*q#}46pD8@ADB~@-1T@2z30E37CYb znV#90iv?MfWmtjLSc{F=gl*V?-Pw~vID)@$B4=<87jYTaa6PwhJNIxukMSfg@CtA9 zA3os=zGIAoy7CJq=2uM1jLgp5EXblP&GM|u8m!M?wqP4}VmJ0;Uq)~!Cvh5o`=44Lid@km1{GD65gZp@hmw1hL`G7C@nz0TCdVRw9OvDsS!%WP^y!?hGScX+t zoekKSt=XQv*q0F;%F!Ihshr9AT+CHm%T3(MKlv9A^El7)B5&{x|K(G@=6l9H66pIm zQ!*_xGduIKAd9m!E3qo;Gnj4Ifj!upgE@@jIhjkjl7Dau_wpc5^E_|y9-s3SV;^+~ znTqL{jk#EeK`h5gtjW4;!WIl+7xrRb{>0%N%L$yxU%8mext1HajXSxIhj@zTc$GK# zkWcuE?->7BpkE@UU>as&4(4YemSQ=6$C_-!CTzY$v%wWP>$sU zF5nWb;d(|fn)`W}r+JJGhUBc#7wEowxaj&-jipP6T>=&iMR_shEk`n4g7Mise|B z4cUyX7{V^>#lDQ-P)^|tF5nWb;d<`oJ|5)>-sD|A;xoSC2gW_A6B9BiQ!_oYGA9eL zFe|bOYq1`ivo$-iD|@pa2Xh!Fb2=AuIk)pq?&o2i=6T-W9sbLwe9Mpg>{OsvJSJmG ze$A}R!vZYJimbsp{GQF(jvX1!0UX9roXDx1%Y|IUwcN~Y{EG*8f@gS@H~ElH80&PP z&nHa4Buv8$%)vY?!s4vJ%B;=$Y{pjX#BS`v{v5;coWVIC`6T7iD`|&3Z=P#Vdnf#SYxPrg) z4{qn5JisG7&GWp@+x(YL`Gz0($=N{9|1mMYVmf}!oXpE2EY9-$mNi+I-?KT}vlDx; zH-F?${F%RSDra&5m+&|K&Mn-|zj%Ou^E5B>I{)Fn{Eu%K>zwz@FPWIBn2uSQli#oi zzvXwV%Z6;u*6hS??9G1siNpB|Cvql#an?Ld={>)!El{2}3OZXdq=N4|~Up&CS zd777bo&WG({>L|rb-_OQB@;6h(=jV^@*5UmX_n`AtjUJ_o~_xQz1fdHaX5eBM9$=| zT*4LHz(_`OHxKa`&+;N~@-Cn9KYn1Wi+0H``4v;~Yi4C$e#7D{%_^+U`V3}kwr4l? zU_buI;ry8sIhDV10ax%hMly=KxsS(ql9zd%|L|Y_$2W|1$sYM76EhXlF*|d!5QA8r z-?Ap_@_ROCdv;eT75trla6A9x0UqILp67Mm=3_qRJI1&i==d4q zF)33p12Z!>^D~GgS)H{R%%*J15dOek9LT{O#j%{i8Jy3>T+Mad%x&Dm{XEW7yu@p~ z$A^5u*Nk~3&@nFKGZ9lVEweBO3$QRtu^g+i1{<(3Td^Ix@(1?iKn~+5PT&;I;e0OV zYHs9a?&KaG=5e0mCEnsaKH&?#XUwaCuAehLlQAVTG7Iyt0E@8{E3qo;umPK~6+5yk zd$BJEa~Q{R0_SrvS92XVa~t znT#o!ky)6B1z3!wScz3xhYi?_t=N%W*^7NSn8P@h6F7r&xR}eijvKj+J9(U^c!}3| zj}IC1hCMPq6EP*zG7EFC!2hvyPvLf$UBgDxux;!#wr$(CZ5xekCykRvjcqk*ykpz8 zt^a%fHIByNTF-sWIoCeh%*K2y#8NEBYOKX}?8Khz%b^^}iJZbYoX=%k#ZBDC<2=pF zyw3Z4%-4L+@BHPSd1H7+=O0YOWK73Q%*A}H#A>X^M(oC(9LS-Z!8u&SWn9Ni+{wK> z!sEQn`+UyV{LJqRbzc`oW^~45BBo+GW@9cEVlkFuCDvj+He)MxVmJ2XK#t^CPT>sB z=OV7+I_~8G9_MLZ=5@a2dw%CH4|HRAM&}<)#AHmzOw7f6EXGo-$3|?$cI?KU9LS*@ z%ZZ%9Ib6hL+{wK>!s9&8%e>9|e9qVW%}>Qyv_T3!8iQMpZxW4pkFvf=O0YW=nZ^0h2H-Gcp(R zu{cY!3Tv<-o3b4{aWIE-0{`M-F6Rbr;SnC^1zzD@KIALD<9Gh@G|(d|V=^I=G95E9 zH}kUu%djeIvJsoHJv*~E`*Q@xa0+K|1=nyZ|K$N5;Tc}wP2S}*zT#(oXXs~vPQNn_ z6EHbbGYfMtKMS)I%dskJvH_d0HQTcXdvgd!a3ZJhZ!X{puHj~G=RO|d37+9)UgteN z;!D2e7ye+V=k}117>#k5fXSJfnV5}vS&$`IhLu^J_1K6l*_K_{gZ(&&BRQ6TaXRO6 zA(wMCH*p*Ha6gaoBros^Z}UE%@fAPvD}%oX^bXDNjLcY!%Op&}^vuj$%*UcE$qKB( z+N{rJY{ic3%HHhHVI0MYoWg&&lxw(w+qsJec!Xzof!BGPPxyi#`IW(6>dWwq%vg-e zWK6}3%*s40z>+M>Dy+f!Y|K_{$L{RKfgH*)oWL2J!+*GxYq){?d6=hoj@NmckNKSM z_=&%~3iJ%c==_7Jn2uSQlZ9A}Wm%E6SdY!wnqAm~12}|ZIDykRi~n#bH*-6Kc!KA7 znRobr&-t2P_=90y2YQ8NG{#~|re!wfVj&h|c~)j^)@OTmW^eZAcuwYQ&f`+9;7h*cHwJqX=<+MWF)33rBeOCe3$YZ-u_|k_5u33advYYl@-I&3d@kZj zuH`oFgRz;K>6wkWSeV6Gj+I!O_1S`L*p+{B1jld+ zXK+3jaW&U-J9qH}&+sa5@+IH$8-u;mh2a>Dv6zx+nT@$vn8jIvRaln|*^+HJgd;ef zlR2C7xP&XXkz2W!2Y8I9c$wGvfKT|AANlM1K&Nnw%9xDL#7xC>%*vcBz#=To@~p;M zY{;f;!w&4uUL47>oX*)?$R%9MjoiWAJjfuP=6T-W9lqv!eq*o?fsSDqmQfgk$(V|n znVkh#gk@QgwOEhM*_vJ0g9A8(V>yvC`8Stv1vhdl_woQw@C>i=CLi$`-}5tre++aB z&4`T3xJ<}YOvmiZ%_1zpimb|dY{b@V&mQc}AsoSpoWj4kfGfC$Tlp^!@CeWF0&nsz zpYatx^E*R-3iSJ(Q5lm7nUv|6iMg4dC0K@4S(A;}jP2Q(z1g1=_!sAJK9_Sfw{Qpd z^Ds~IJa6z0pYkO?@f$;Z4)pqsQ5b^>n1pGWk-3dv13uv!e&7!V|K`py0%I^X z6Eiu}Gc$8DKZ~<8E3-Q5voTw|CKqrqH*-7p z@&Hfp3@`IKAMgoZ^F4ns_z(Ay;TeOmnTW}lo|&18`B4x`Ia9U>}Q}`NJeIK#%E$?U=|i+QI=yR)@FTnVGs7_ zV2qO@B**!319F7zcBbOfgYh5gRz;I$(f#+S(wFH zo|Rdf_1T`C*_-`2f@3&`^SP8Oxq(}FkU>1n^Sr@3e9Y(k!QjCIU4CPD#$arwVFqSr zZWdt))?{5aVGDL-SN7#VPU2K9;xew~M(*Hl9%K+t^E|Kd79a8{zwie`h0uwS7>#k5 zfa#f;xtNc|S(;T?gDu&XUD$&IID}(4kqfw(TeyS&@gOhqD(~?TU-Lb`F<3}l7@pA> zi>a87*_oR~Sc2tQnYCDt?b(^V*`FgghEq6$%ek7HxQ#(P!3(^?JAA+we8VsN!BC-e zVkAam94252rePN5Ut@ zZr~2?<{=*CRo>(yKI40SX7Dh9exVtWQ5lyBnTqL{ow-?rC0LVn*^I5&kzLuB138N0 zIE}NofQz|?8~88x@Cc9d0q2Xi>baT4cq5m$08w{a&AGKgn+k&pO{Z~2kIehYL8$?%NK*o@B%%);Ev&tfda zimb{yY{2Gh%}(sbp&ZEx{EM?Vmy5Zao4AdKd5jl%l@IuYpZT33e-HHfm5~{p@tK%u zn1R`un}t}6ST+B7xz<;@iM|hkUc!hWQkgxcT z-}y_pK&L2-!FWu>luXMk%)#O;%}T7srfkW+9LNzI!zrA>1zgNkT*v=-kjHtNmw1g& z`I4XbjiJH^y8Ol{jKLI4!>r87LM+Detjs2C!H(?8z8uI=9LKp_$mLwkE!@HVJj|0k z%PYLWhkVK}{J~HW^kEdnU_2&bN~UEV7GQCfW);?8eKuw*wqqX-;Bb!SBu?cV&gW9D z$3&huq*%M zNRH)H&g4Qa;aYCwPVQw8Pw*nI@)=+8Gru!*WPKQwF`1A_nU0y5oB3IRRal$#*^I5& zi~Ts1BRQS3xq@rBncKOS2Y8N`c$0Veh94Lj@&+4qr zCTziu?8-hIz>yrwDV)ItT+G#6&mG*&Lp;iJyu@3)$7g)S&-~6%(E|N`V-&_<0w!S^ zW?)X{Wm#5a4c1{}HfINRVK4UMcuwX_{>>#^!GF1jM|hk!c!!VqobULFKN%vrJH!Z# z&OextNtuQjn4g7Nise|9HQ9ho*qPlqkV840v$>EGqz`E_GW*M;22Kf3@+eeuHgpm=V6}adEVe1 zKIKb(;x~qhY5y37F_?f!n3frti}_fdm05=k*phA8jXgPt!#JLkIh*sijH|er+qsX2 zc!}3|mk;@ZZ}^oz89J6dWMoEXTqa~Hrejv-WFZz~Syp5X)?rh&WG8lG9}eJnPUcMh z%_UsH_1w&z+{+-I;6+~LJwD<~zU4Ot`@`HZJYz66Q!yR0GA9eM7|XLVYq1`ivL!pQ z8~bq(M{_)EX2|* z&uXm2#%#`Z?8IK|$Dtg_3H*z*Ige|(kvqAUhk1jz?!VfW^BdI?9Toi%rTt68Jxq#T+R*L!ady2 z<2=nfe887{%Wn)8-~D2E#$aqFVG3qsR_0?NmS%a@U>!DPOLk&6_TwOq=6Fu$Y%bz5 zZs#r@;!&RCCEn(JzTg{vazq~USS!Hv6zbKn3XwMfJIoEpE~xPXhfg*&*9hj@}_d6hT$kWcxRANi9ZlGrmwWK70k5~g4V zW?>!{Ulo4Aet@gPs~ zEU)nvAM-gs@C!pE4|EE{NQ}mKOvKbo&m7FdvaHBjtjFeT%`WW00UW}yoXDB{n@hNY z8@ZKxd4MN)hF5u$ulSDN`AdpGr{5WYF&T$RnUa~9jrm!aWmthVS(nY&ik;b={W+Lp zIDs=bhpV}s+qjbl8N{=^$XmR}=X}jC{J}6O1Kq+h8e=g5lQ1naG8gl)JS(#n>#;do zvlF|q9|v(H$8suXay}PvHP>?+ck&>Ec$OD=i}(1Pula>P7$%i|jK)|@#AHm*%*?|A ztjMaY$3|?)w(Q299KazQ%ZZ%M*<8eBT+5Bz$-O+xV?4`?yumws%9s4WFAR~|ePaYh zVH_r4a;9b;7GO!1Wfj(7LpEg_cHp1v!@(TR3H*z*IG0Pgk{h^%yZ9fE@Ho%$5^wS@ z-|z!}GDI5pj}aJ?ahQ}TnSoiDmjzjhKyD|50Ci?KW_vkn`u zCEKzu2XX|*a5AUyZ!X|6uHr^+^ns3{7>m064R*pw~VgS|PJ!#SRlIg4|-ge$m#TezG1c$6o3kym+_5BZXB z`ISEzCPScaSVm<`CSVe#VFngp5td;E)?ghrVGDL(7xrd<4(Djj;#@A_3U1&Q?&dxo z-8e&kn%$Y`$_kx?0k37CRun1wl5fJIn^HQ0bn*oGb0gS|PJ!#SRlIg4|- zh8wt@yLgC4d5)KOoA>#GZ}^oz`D>;?zi^DsKbV-wnSoiDoB3ISWmuIp*@(^9o}Jm7 z{W*eTIEVAOoU6HoJGh^Rd79^WgLn9pFZqez7%Fq1*Kdr%7)-z<%*vcBz#=Tmimb(Y zY|hr~!XE6$K^)1k{EO2$mkYU)Yq^a(d5}Ro%Zt3hJABHQ{KRhzl|?^BVGPD&BBo?o zW?>E%XK7Yp4K`#`wqqyuVm}V!C{E@y&gDX`&KH&>~ z_?5BP+i`JLf%1Uf|GAB@N3OwBCJ!GbKxa;(J0Y|d`%$w3^(@tn-r zoX2Hc#m(H#qddt=yvF-{%s2eNpA3;R&?OurF%gq7Ju@>O3$Y@rvKd>kGrO}t2XhQ3 za0cgaHP>@Hckv*Dc!n2vgLn9bANYg8a|L?*&IpXb*i6ji%+A~_!V)ac%B;nDY|57G z!QLFiVI0eeoX*)?$R%9O_1wmtJjPSJ#B03AM|{P1{KjCp1O0wwIL2i{reGT8W_}i9 zDOO}v)?ov-XJ-!NP>$gQ&fpv_=5p@fZXRS1&+;N~@gCpvGlS&`bP37ujLg`K&lF6< ztjx($EXS&>$wq9(_Uz2w?9UM#!#SMKrCiAk+`?V_k4Jc%*LaJM`J5m4g(30=dWB&m zMq@lCVrr&m4(4H5R%8vvB7dM`SVm+_#$ghsU#}0=hCPV=@7gFby*>2lKE9ORxf~unrrr z1>3L-d$2zTb26uKE*EkI*KiAWa32rxB+v3HZ}K6Z@-08|Cqop}kr5e_ahQZDn1NZC zhXq)IWmttZ*nmygh8@_0y*Ze}Ii8a_i*vbzE4YDMxSRWUlqY$SS9zBY`I2w>l|LD# zkgkl%m`uPVOv4P!!8|O&60E=~tiuLu!8Yu|9_-J-9L@2Z##vm*C0xS|+{Z&a!85$d zn|#10e9ia##$bg59m6mzqc8>&FbUH#BXcnyi?cMVumDiY}Y8zV6q<1hh}Gc_|Y8}qUtORx+p zvpVas5nHk?yRZlQaS%sxEdSzk&gDWb=W1@^Htykm9_2}1;1%BHeLmwWe&kmMFB<3_ zn&BClu^5+0n1bn)FzGa9K`YY-r_?(Dg*#$-&zOw7gtEW$FZz*?-w7Hq>V?7{vV%(0xv8JxpK zT*eLD!o57e<2=o)yvc`r%D4Q;UrGgfgQ-dBQ|3@c4ANV zUqbG*cxyvrwi!H@jP;AH|` zLo+7hFey_q7xS?=OS29eusK_^6T7hw2XHt?a}uX=4(D?%H*yDe^B{wGn&)|skNBRS z8KG>TPZa*acudaJ%)%VZ&%!Lj3arVxY{pjX$gUj9k(|V-oXdq=&ehz_eLTifyv*x- zz$bjmj|^5W&?h9rGcsc{K2tCa^RggIu^g+jHk+^oJF+YLav(=>9H(&>|KU<@<4zuA z5YO@=Z}A?V^EJQl2g8&P^a{&pjKxGu#_Y_^LM+CztjHRy!=`M>4(!5S?8l)T$w{2b zIh@bsT+J=q!T)%WCwZ3Fc#9ADlwbIRp(+IW{l+Ma!FWu>)J)GD%)_EA$x5uo`fSWL z?7#sW!qFVh>730)T*kHB$Q|6xgAC$np63nT;ZwfkCw^n7iuy4Y<1z_TFg-If7xS?w zOR@s1ur}+n8C$U&us8OwQEI!W=BfqAbG-tjW4;!WQhvuI$bJoWQ?0i*vb@E4hJNxQF|BoTqt( zH~5fG`Hr9XOO-&kPz=XN{DbkBlqs2kSy-6GS%Fnpmkrs9?bw~YIGDpZfq!uh=W{t% za|?HHKM(UX&+`WF@F`#N6TdN3Rrigt8J{VbhFO`Dg;>t znX@^M%eac0xt;rXh^Kgt*Lj<7_<=teqMH3=B>us8OwQEI!W=BfqAbTstj+pt!8Yv5 zKRJ*?IgXP!i*vb@E4hi=7{n7i&&#~Udwk1}{K4SW%@xBl8e=g5lQ1>YGaGZUAd9jJ zYp@}kvK>3I7yEHMCv!IEaT!-}Gq-ae5AhVw@j7qw319FdzcOTvK(}8Rnb8@aiJ68O zSdc|oj+I!O_1S`L*p+{BAct}sCvg_%aw%7G6Swg{9^^@$jIa2a z-x<1Apxf_^%9u>aw9Lw!EW~0g$4act`fSeD?7|-G&%qqS37o+>T+HR%!QDK}V?4`? zyv2Kb%9s4aZwyg8&?^ihF&g7A0h2Q|GcgHeeIBWk>d8Uk>9aPUbW&X{>Jc($3#rUbj-$FEW~20##(H|W^Bh!?8&|y%ZZ%9Ib6hLT*pm3z#}}x zbG*sBe8Ue6)j$_UVGJf<5~gKF7Gg1$VD%RM~A zqddb4ywAsc#drM5pA6kF(Cc?bW^~47LS|qV=3xPrU>R0n4K`pCc3}_p;~-At6wc;6 zF5wDp=PsV)SzhBUKIU`&VDLufh~XK7v6+M^n2}kThXq)YWm%7n*oy7gjXgP#Lphcc zIfHY!h|9Q+o4AvEd4$J#o|k!>_xYT!`I+Ats4B`o%=VjjFJwE4ae&RQVYN98jFb3l>5mPfg zb1)AJvpB1<78|lD+p!b>WFHRYNKWEZ&gDX`(?GYd zjL2Aw%VbQ&%*@ULEW)y^$VP0&w(Q6r?9D+O#<85p>731lT*B2{&u!ev{XEQ*Jj*M* z!3TW8H~hfw{H0l-XCy{r9426Lre-E)V_p_y36^1HR%bmnVq11(9}eJXj^|AN%~f2- zf4PT8c$}AbjSu;hANiG`n+H1m&glGushOVHn2Uv3oE2DwwOOAn*oIyCCkJvU$8i#8 zaW0o~B{y&jckw?SvM9^35^J+QTd)ng z@=p%rP>$my&fpv_=5ns%CjQGkJjA2C!W(?bm;AR!{ z9@8^3^RNIbvMTGa0h_ZmJFy%4Z~%vMG$(N?=WssPawB(eHxKg|&+;N~@gAS@C4Vq@ z+d!{~jLMWu%Ph>nf-K5%ti+nE%VuoF&g{L8JqE$jH#HJ*;#-^Se6yph|SoR9odt8IffHBgLAl=>$#0Pxu1u5 zmKS-0clemk`H9~cqD!Dx7)D_XCSxjQWL6en5msh()?*{KW_xyHPmba^PT>qL;9{=g zI{wFlJkHa+!W+EL$Na({4AV8xCoH2d22(H%b22YWu^el&KD)37`*9FQb3CVVCRcC` zH*-7p@eoh&4Da$GU+@jT@+U)g3-tJ%ahQO~nVOlHjm24-wOEhs*_l1rmqR#$<2jiN zxR|TBj@!A52Y7^+c#U`YkT3X#A-dZiMqm{F!FWu{l+3|AEX?98$4YF>=Ip{A9KsQt z!Wmr5<=oAEJjHXo&HH@A4-DHQ@cxL5%Y;nFOw7;1tiUR4$+qmm9_+_K9Lceq%9)(c zMO@AG+{*(z##6k^>wLf`e9Mpg_0K?$aE!{BOvt26$4t!4{H(w#tj+pt##ZdeuI$bJ z9L7yT-V>1zxF)cGP7xS?qtFjIo zuqE5F8+&pPhjBb7b0+`h60YESZstzzWe`vBChzhYU-2`)Gjy*&uiqJ&(HWnKnTqL{ zmjzjll~|vR*@0a+fI~QuQ@DVOxq(}FjHh^!S9y<*_?qwegTZ?TI)r6J#$sG1V=Crm zeimaXR%UfJU=y}wNA_f24&x|J<}@zlN^ay=WqpD$ zVDP@?ixC;0iJ6M&n4P&pE~xSXrGiQBk``+1Znd4X4W zoA>#guNkagpi@YOWkkkeTqa=(re|j6Vm=mSNmgMEHfL*gVmJ2T0FLBX&f`B^!8P2< ze|dmMc!n2vowxafFZiCH8N7d>UucGBWX5KEW?&ZPW_}i9DOO}v)?ov-WLtJ&4-Vrf zPU9>t$#bSc$8;&fe-nVZ}@>>2D(d(%Y;n9G|bHG%*R5k$f~Tv25iZ;?7|)# z#!;NeDV)uDT*poPmwR}KM|p-9c%P5?itqT9KN(?ApjQ+oU=n6zRu*D0)@FUSVF&i% z0FLEEF6MG>;SL_=F<$0%zTpS{VDQ0#cm2)?jKSDU%;ZeZ%*@UFEY8xb&H8N4*6hsg z?8iYI#c`a4x`Gr3iYG|O_Z;ZkijK@Sw z$+XPITrAAutiUR)&H8M?Htfvq?8|{1#c`a%8C<}{T*D3A&Rsmov%JC^e8{JK$4~ri zSfF2cMq?}{Vlt*>M&@81mSsiOU>!DQbGBnA{>eTZ%;B8MnOw*vT+5Bz$-NBX30~w? z-s2;_=6i-7ZciDNF`1A_nU0y5oB3ISWmuIp*@(^9oxM1OBRGw-xPXhfmK(W`hj@zT zc%8TTitqT9KN(>}pidOWVFD&+YGz_K=4C-vVl_5k6Lw~I_T@m1=6L?i1zg5e+`-*E z&eOcfyL`>}{KjA-10BLJEMqf1lQT6lGduIMFiW#MtFty6vpL(dGkdWg$8i#8a1K{; zEw}Pt?&o2i;yGU9Ek5EizT+nb8x`mllF=B837M2>n1R`un}t}6Wm%CmSci?-obA|& zf3gopb3CVU78h~}*Kh-Oa5qo#EU)ke@AENV@f|~qHg}B3s7(AnV+ISBoavdFxtX8E zS(=quo%Pw6t=XR4*^7fXjN>?oGx;}H|IgsTg01Iv?&3iP@d|J70iWB zG{$0amS$yEXMHwiYqn>1_Tngx<5bS%0xsriuIF~{;t8JNWnSk!KH^Kh$#n~c#uIn!wY=GXMD#` z3^p#%CnUo$5@RtglQJbUGAr}4AWO0=tFk5=vMJlLBL{E@$8Z9tb2k6sQm*Aj?&o2i z;yGU9Ek5EizT+nb8?PV3F%n}jE|W4PGcqglvLGw6D(kW#Td)ngum}5b5Jzzwr*bA2 za4}bNJ-2fg4>E{Xc!Ll4gm3tPKNx&MpyTh1z!;3p)J)Ip%+10q&ho6x+N{s!Y|YN> z&VC%kQ5?sqoXG`T%+*}a|9FrWd6iH2g75j6zfKHv3dd-S#e_`Cw9Lqy%*&!I$%?GX zx@^df?8?Fa^Z$N-hjTn9a~9`v30H6fw{SQ2@fc6>60h+dAMq96@f(9p3VhFB8IJLo zh^d&4*_exkSd3*^ku_L{P1u6%*_plBpTjtc6FG&mIgd-Yf*ZM&hj^6Nd7CfzhQCe@ zbPC6)jLC#d$}G&m{4C5$tj4-*$d+u&J{-U?oWSXv&6Qlso!rY)Jja{7%QyVMaDN5f zABhQ=gsGXH1zD68ScQ$*oc%b6<2jiNxR{%`jeEGC7kGtt_<%3?hF|!D5vBy*8-=kM zpUIh;nVFsWS(v3+p4C~Kt=XR4*pnkThJSH7=W-#}|Ih#XdwMf>@jnLf1TXLk@9+U% z@D0E6C&Nq)d|p^aWlSbu5~g7W=3pL{Wkoh(Gqz<%_UB-Z;y6y@EH3A2ZsvCG~3RJF%>g1D~qrME3gXdumM}J4ZE-h`*Scyb3CVU78h~} zw{Qpd@enWaD(~_kKky5KPY?77%?OObcud4h%*OmI%+f5+TCB&GY|B0zz~LOt$(+Wy zT*wXF!d?82K|I0hyv;{^#%~NZBhV!b!!iyNFa^^v3v;jli?9qUum_CrS8Hv#tmkF7Y zX_<|=Sct_~j+I!8_1KK9*ooaZjH5V_Q#gn7xq(}_oBMc_CwY-qd6y6Ql5hEq!RF}3 zaE!)SOvt26%Z$v)ye!8`tjW4;##Zdi?(EOO9K#8m&qZ9tb^MP9d4gwnl{fi_&-k97 z8T{`+r_hYaI84G6OwY{B&HOCR(yYwttk1@5&GzihUL3?>9LGsqz{On6_1w-~Jjftk z;SE0IQ@-OT{xUbvD-=qk!8P2< ze|emzd4)IlkWcxJpZLo>eHeqWnTW}lj+vN?`B;plSc%oxjIG#--8hV+IFVEMHy3aP z*KjNU~B#i?9UCvodS39^0}b|70Hy;RsIP zU;KwlxrQ6~FZb{WkMjbr@Gc+n6TdOs!a$!${DbkBoT-_c`B|Qo*_!RykApallemD3 zxtZH}h8K8)clemk`JSKo%RlY~!!t7fU_2&cDrRCf=3^n2VmVf0EjD5^wqqyuWM2;D zNKWJw&f$D6<0@|AHtyvC9_MLZ=5^lZW4`8le&;WX0$qP&ct+BY%b&yZsv9#owq!?kWgiaU1pdW&{D&*KmRq=k`*?^Kd6f_OlyCWwKNx&fpi=}! zVQj`{dS+%W=3`NoWCd1XV>V|yc4ANVAxPiNV&HFNR|z#$sHiWk%*?UKV9ZR%BJyWka@PTXyB2 z9KazQ!wHCwW`7RnXinxdF60uf z;Rf#DZl2^>Ugb?bik4~wt_E3gXdumM}J4ZE-h`*Scy zb3EsAA=h&=_wf)f@Cu*s1wZi{!)^_9iO2*@!pzLhGOWM`Y{G8r$&nn(*__9X+{(i| z#v8oDH~hd*+XCPJH^yTkW@0v$U>Vk71GZ;pj^G&1<~*+FW*%e^FY`Lz@*~4+Hnyd8guzrhFaL3|Sbgn!3Z@C|Icw^c3!8qtgvbf6PY#nbU@JQu%!m*BVX zYTS(1;kWU7cn5C5`*A1k!pHDAoWTYzVEeXKIkjj)Gdj?TC*VoA7SF*jcH)(|0XO4y z_#ON{{sMoAcjG*812~99EMWz!IELf+XM7f4!oOhy7x4WLwBm6Peh?4CqwpA9jVGcX z19&lh9=kAsDeS>M?8l$t?O4VN)^HRja1vj@-M9zeMBR>7c@2039*M``akvK0z#w+u zm+-521zw5Q;q`b6ejA6dfJH1}4M*{Dd=h7I4jZ_Dx*Fw03tG{MF7%-vFUHT~<#+{d z#_RAq_$r&T-${GL!|@0_4v$Aa1~81B_;vgSZpQ2IJNSLP z6MuzOtl>CL;BI^w-^3*kw#s2bGuqLCr{EeqA1}m9@hh0XB;JbO!Q1gpEMXacj}POY z@mbuBFXOBDIxhWvt6ck{9uLM3;d1;auEdYyC-5XZ70<-8@dEq|egQARZ{WAE8?VJ1 z@Mioj{s4c5ci^w_F5HIq;qUQb{3AYv&*BUCGX4W!$3@hSw&Hm(eh8Q2M{y;796y04 z;i-5go{bmaXYdPn30{U@$8X`)cr9k|X1oo5hIinv@h;qk_u=pHVf-ULh0o#(_%i+j zU&lq<_YbZ3y$=t@LvcBN1XtqGcoLq9XW&{qA1}nu<2w8*UXEAd2HcF-;Z1leejk5? zx8t3-6@QD{@d11YAHiqvdHg%Rf^T5kL#?=JQHLfp<45qLcoZIkC*x`OX*>@v!q4HQ z_!W#}7bY=OFwm%+(hu~p&I39^d z;c<98o`P%ee7q1phhN06;Mee*colBKG~S4};P>!{_)Gi^ma&36@eeqLhWMSqXj>TEAbdS4$r`~cp+Yl>+nl>1zw5Q;AXrYZ^Ccm_wXn9a~#GZma&30 z9K|sl$4Q*Rd2C?&F5-m-G@=EqXh#RS(2b|!>3BAtix=X>xDLOBm*W+<0k6U9@Ou0{ z{s?c!J8>)i7Dw=Yd<>t!zu{zdo`L@x zFTzXlD;UQvyc)alCcG7Yinrsha4X)AJF$*q_$K1v7B9gsmEZ{Jfu#ETN4*VlNh0oyg_%i+j_u!kj?>OTheh?4CBk?Fa7FXjbxCYO{ zPh$s$FotnVVhXdE!+spVAuQmp@h-dzJhyj*%Ph!?2iZGA$T|* zfk)vnxEfEy)9_RHX*>@v!q4H?a6Mjy8!?T&n8!XG!U7htgcYpfDAsWtCvX<$a1ob2 z*^1M_cqo1hSK-Nc8lH{k;^%Q4UV&F)8hi13_(Qx4e}})vhw(4?9R3quL+w+oa_G>E z7IdH!z39UW@nZZcUXGjbI=m5Y!JpvI@ou~a|A4#jS$qLs#n*BFiB@^ukB8ymcnltg zYw!#VVh3J=U&e3Y)p#@BhCjnQ@OQWkAI3-VY5WWR17F2`pKg`sefU8<43EGg@p$|s zuE8_#LcACw7{v{E4PJ-WgcYpf7>?sJ_&mWj2mS`{#tK&PaeNY=!RPT6+=K6*Y?c2YJRFa} z(TC^Y`53_{#<2@~FpGKY!yzo--FOc^f{){$@EQC&zJi+PTjg!XL-2!m zI39t=;qiD1uEF#1Li{|g!z=JgOkodx2fvR$#oO_>crQMLkKi--JidZ^Q1?Qsyau$O z6`klpANnzbVf+$)6|cgLcq86|Kf#~l-FOfF0e9gfPT@Q@P&Z9^(1KQUq6>ZK$Iswr z@iP26UW*z0F8%<2gLmUj`~yzlB+lVHYG+#c*P$6LcpM&&XW&}A2tS8k!}Yic)A()t z9{vJCnji101@Ju`#KZ{?$Z{k(hi#Otr@n?7! z{tkbS594zJuFg5SieuorK{AL38&ZoCKofV=Qn zd;wp@*YSO`t^DiJiZ*ni8`t7F_<3B1SKyU+EoSgL_OFm*bVV0k6aB@fQ3x4q*X{Si)_1A3lVS z;Gggrd=dYOZ{m`_w&JoM9)KUf|H6;qD)gcc0~o{*hB1OsjAIujF@;&oVITJ6AP(U$ z7O{#od>9|aXYhIaEB+n#;G4MYo&|7xAz73hu$SxmJAk!DSkarcHkQy9Tvg{#|{O zQoi5Af@OIXGVRp zK^(#Y4r38ZSjGxgv4*2q$1xno37o_!oW@z4!+F#!r9M%MIy9gWO=w0N+R=edbfFtP z=tUp;F@Qnrzz~M96C)VK7{;*+6WD`U%wZn;upb9-5QngU!&t-;ma&3Wtl=ouaSX?C z0;h2n=WreyxPY2=>JtrUL=&3Pf>yMl9UbUI7rN1dUi6_K0~o{(3}F~MF@jNyVH}f~ z!XC_G4)fTD{WySwID`cp#v+!mj1{b64M(w#V>pfzIEhm@hx6FL1=Q?AeWDh1Xh0)c z(26#+qXV7jLN|KQivbK`2Zk_=ofyM7c3}dOn8F<9u@C!k00(gxi&(-kRVBw00~*nUX0)IcZD>aaI?;u0^q?1g=*JEWVHi6xf>DfN z9J?@qNlal6W-*6(?8AN>!U7Is5ldLc3Rba(qd1NeIEhm@jk7q1^QhUE{)Af8p#hC( zLNnUXjt+F92fgS+KXzaU!`O*2jAIujum`i4!#ob)AP!*xOIXGVRd=5jG@%(S zXhj>^(Sc5Mp&LEuMIZVxfI;lQ5Qec6BN)XP#xaR0?7=MNFpquMj{`V}Ls-CJEMf`E zSivgRa1`q}hT}MalQ@ObIE!;Qj}2Tv&HmIkYEg#?rv zPU9@j;XF2Q0X6TVzEO)hG@ubpXhsWK(S~+(pc7r_Mh|*1fI;lQ5Qec6BN)XlOkfgI z*n?TjVIBu?5QngU!&t-;ma&3Wtl=n*;{;CP6i(wT&fz>ZZ~-+s>JJTQL=&3PhIVwI z6J6*=4|>suehgp`J1~S{?8FF0F@|yM!UQHUg*nV)ANJz_4&o3Na2ShN!ZKE{iZvX? zah$+OoWg0G#W|eE1}>oH0O}95s6zu9(SlaAp&ec5Mh|+?hkguT5X0Ds5sYFC z?7=MNFpquMj{`V}Ls-CJEMf(#Si@1Q;~0+P1Ww`#Z~-;%r+(0YMl_)rZD>aa zI?;n(^r0UE7{oAkVg#cY!#E}}g*}+X9OkhP`*8pVaR>`Ij72PA87o-D8jfNe$8Zv- za2jWE4(G9f3#idkKd40=8qkOqw4x2|=s+jB(2XASq7VHTz#xXP6C)VKE=*t&Q`m!9 z%wZk}a1e*EfWuhC5|*)sqgcl=9LEWq#3`J{S)9XpY~TWF4Ad8DQHKUJq6y7tK`YwO zjt+F93*G2JF9tA(9T>tec47ph7{fSrVFHtw!XC_G4)fTD{WySwID`cp#v+!mj1{b6 z4M(w#V>pRZIE}M7hx6FL1=Ji!{h}6iXh0*H(2O>;qXV7jLN|KQi$3&Y0E5_pAq-n z*nuGoV<$#1iZP615>wcNS?t4p9Kb;w#v+!mj5Qp^I*#EuPT(X?;WW0+j$3E=G z0UX33EZ{H}v4mx;U=?dPigg^rah$+OoWg0G#W|eE1}>oH1JpNaQHKUJq6y7tK`YwO zjt+F93*G2JFZ$4r9T>tec47ph7{fSrVFHtw!XC_G4)fTD{WySwID`cp#v+!mj1{b6 z4M(w#V>pRZIE}M7hx6FL1=Jiu{h}6iXh0*H(2N$eq7CinKqtD;jUM!(5B(UxAa-B~ zBN)XP#<2?%n8XzJU>5tZ9|v#{hp>RdSi};Rv4T~s;V9N|499T-Cvgg=aTXi6fExMT z!RGHnp%!&$KqH#aj25(_4ejVaC%Vv$9`vFQ{n&va3}YuoFp4pZV;3eci7D*CEaote zeb|o!IEX`7z+o(63Cmc)D%Nlm>o|tvIDwNmh0{2Tb2yI;TtKasuehgp`J1~S1jA9Jq*o6s9VhVdOi#g0=ANJz_4&o3Na2ShN!ZOxy z6ze#K<2ZqnIE8aKj}2Tv&41BfQHwe>pb<@IMhjZehIVwJ8$IYnANnzXLF~W~hOrYP z7{wUIF^MVc!7S!5kA2vW12~97SioT{VhPJw!7A2p6ze#K<2ZqnIEB+Vi*q=S4O~FY z2dQ7wq7DscL=&3Pf>yMl9UbUI7rN1dUi6_K0~o{(3}F~MF@jNyVH~?Kfk{kZ4`wlk zdF;b}9Kb;w!U7Is5ldLc3Rba(qgcl=9LEWq#3`J{S)9Xp)O?8gMlI^lfJQW-87*i< z8`{xgGpcexe#10H$7&|e7QH)_6yD))COkodZ zF^75V!+spVK^(>+mavQ!tYQsEv5sRnjuSYEQ#g&YIEVAtzy;JCM*X4zjc7tMTF{C% zw4(!^=t4Jo(2D^KVh4sWjGY+4D8?|3U6{ZmrZ9(j?8AN>!U7Is5ldLc3Rba>V>pfz zIEhm@jkDOm1=K93eo%`#G@ubpXhsWK(S~+(pc7r_Mh|+?hkguT5X0Ds5sYFC zOkxUqFpD|NV;}b85EgJ4i&(-kRB((<2ZqnIEB+Vi*q=S4O~FYhv|=~MI9Q@h$b|n1+8d9J37#bE_9;@z34+f1~7;n z7{V}iVg#cY!#H+f0(&rvIm}}p_TvB!;t&>a7>iiKGS+Yu>o|tvIDwNmh0{2Tb2yI; zTtMyN^iMRP5lv`D3tG{Jc66Wo^HDAsWd$8iED zaSG>f9virT8Y}gOTGXKdjc7tMTF{C%w4(!^=t4Jo(2G9wV*rELfgy}w6k{02E=*t& zQ`m!9%wZn;upb9-5QngU!&t-;ma&3Wtl=ouaSSJM3a4=v=WreyxPY4frhZY2Iy9gW zO=w07TG57fbf6PG=tUp;F@Qnrzz~M96C)VK7{;*+6PUyl_Fxusn8!Zs#{nF~AuM1C z%UHoG)^QBSaRR4t7Uyst8@Pa)Bd9;rq7F@HMhjZehIVwI6J6*=ANnzXK@4LjMlgz9 zn7|~aFo${U!+spX0uEylOIXGVR z+R=q>^q?1g=*IvCu>(UG#!if26k{02E=*t&Q`m!9%wZn;upb9-5QngU!&t-;ma&3W ztl=ouaSX?C0w-|_r*RhNa2_=_`V(qVhXypF3C(ChE85VG4s@am-RMCt`p}OZ7{V}i zVg#cY!#H+f0+X1+9?W76^Vo;|IDmsVj72PA87o-D8jfNe$8a1ca1y6*8fS41=dpnc zs98b%q84>%KqH#aj25(_1D)tXH+s;EKJ;S%gV=!~3}YuoFp4pZV;3eci7D*CEaote zeb|o!IEceo#1fXVf>o^HD30R+R=edbfFtP=*0jAu>(UG#!if26k{02 zE=*t#W-*6(?8AN>z(E|s0uEylD_F%Ej^a2@;3Q7r9L{3{7f@rTzR-Y1G@%(SXhjD) z(S>gGpcj4U#{dSg149_bPK;m_V;ILSOkfgI*n?TjVIKRi9|v#{hp>RdSi};Rv4*2q z$1xno37o_!oW@z4!+C7r0%|@+eWDh1Xh0*H(2N$eq7CinKqtD;jUM!(5B(UxAa-B~ z!`O)tjA9Jqn8XzJU>0+j$3E=G0UX33EZ{H}v4mx;U=?dPigg^rah$+OoWg0G#W|cu z%~8}ZYEg#+mavQ!tYQsEv5sRnjuSYEQ#g&YIEVAtzy;JCP5q)4b!b2%TF{C%w4(!^ z=t4Jo(2G9wV*rELfgucICq^)eF^ppuCNPO9%wZn;upfu8fWuhC3Rba(qgcl=9LEWq z##x-hd2HYUY8=!TYEg#pRZIE}N|zy;JCLw%tZb!b8}TF{C%w4)2%=s_>~(2oHOVh4sWjGY+6ICfzIlbFID z%wi7n*oXZ%gasVNB37`9H5|opoWMz(!a1DB1}>oH*o6s9VhVGZ$3E=G0UX33 zEZ{H}v4mx;;V9N|3@334r*Re=xPY2tY5!a7>iiKGFGsPbsWQSoWMz(!fBkvIh@A^E}-T(>IV&I zL=&3Pf>yMl9UbUI7rN1dUi6_K0~o{(3}FPL7{fSrVFHtw!XC_G4)fTD{WySwID`cp z#v+!mj5Qp^I*#EuPT(X?;WW--0~b*93F;5Es6zu9(S&BSpcQRsM;E%$gI@HZ9|IV~ z4h&%!J28S$?7{>lF@-&t#T@3b5BqTd2XPpSSi&+^u!=Pt#X64RI8NX+&f*--V*?jZ z-De za1e*EfWuhC5|*)sqgcl=9LEWq##x-hd2HYUYFD@FPlpCHq6y7tLpwUqi7s@b5B(Ux zAa-B~!`O)tjA9Jq*o6s9VhVdOi#g0=ANJ!A7H}AgSi&+^u!=Pt#X64RI8NXsPT@4p z;vCLn0~b(xJoSeLG@=R3XhAF5(2fptq6^*VK`#a{h#eTh2u3l6aqPkbCNYIM%wr$+ z;{XogFcz_dWvpNoYdDH^9K&&(z)76KX`ID5oW}+(pymX|OVpwc4QNCYn$dz*w4ogx z=tLK~(Su$LU=TYngkkK&2u3l6aqPkbCNYIQn8h6Cu@C!k00(gh3pk8LEMXZdSj8HS zVjahD94BxRr*IDEv4IPyaZ|r&KqH#aj25(_4ejVaC%Vv$9`vFQ{TRR?c3=p@*ohI0 zVhrP$#1!^m7W=Rt2XGLFuzgGpcexe#10H$1fv+kICfzIdoYVR%;NwK;t&?Fgk`K?73(;L<2ZqnIE8aK zj}2Tv?I*ckp#hC(LNnUXjt+F93*G2LKL#*}9T>t0MlptQOkxUqFpGWIj{`V}Ls-BP zma&3Wtl=n*;{;CP6i(wTHgEwoC(*u9i#jx+87*i<2RhM(ZuFoR0~o{(3}F~MF@|yM z!UQHUg*nV)ANJz_4&pEtv4mx;;V9N|3@334r*RhNa2_=t;*DC=p$W}sK`YwOjxKbg z2fgS+KXzaU!`O)tjA9Jq*o6s9VhVdOi#g0=ANJz_4&o3Na2ShN!ZKE{igg^rah$+O zoWg0G#W|eE1}>oHWaLkr9|IV~4h&%!J28S$jA0zR zFo8)-VGm|8hk5M7ejLC-9L6G+u#6R~Vhu-e94BxRr*IDEv4IPyIfeQ|E$YyKMl_)r zEoem>+R=edbfFtP=tUp;F@Qnrzz~M96C)VK7{;*+6PUyl<}iRNBIFAinK+UPtH)>Ib1~j4x&1gX@I?#zObfX8o=tDmS zFo+!(!Z3DX1fv+kICfzIlbFID%wi7n*oXZ%fP*-UMJ!<%D_F%kj^Q{?;3Q7r9L{3{ z7f|bM)t?RxXhaj5(S~+(pc6glMIZVxfI$pnCq^)eF^ppuCa?#yn8Q5wVLuMwAP!>@ zOIXGVRtec47?U z*o6s9VhVGZ$3E=G0UX3(EMf`ESivgRa1_UJ0w-|_r*Re=xPY29)CU^Sh$b|n4ejVa zCwkC}KJ;S;hA@ns7{MsUFpgcAz#hzE4)ZvGgE)i*9L6G6u!=Pt#c`a#Nu0uIoW%w% zpyqVqjat;93C(ChE85VG4s@aiz34+f1~7$bL5dUmCpA7Xv)_gpu>r&_MJ_j{^+a*VpZUn&1LzxPNRgY^*WU92Zq zFR@-$%JrJxuPW*9{eD%~KCSfKN=ZM;dW`iU)(fmRzaLc2-~0Wbwq>pJ?Mih%>wCXf zbCC7D--Bu2w{^TjDaQv{-}}9g&F^)T^!I+R<0$+0elKJ5`xj+@^ZOU2oiy0Lpp(a)PyDM$o4Nv?;{We+Nqlv$K_4a=`d&R$<-D^Cg zdHSYD^k+Z5`<~vdDy{CS_TtZ8bYJ?FUiG&zoB2Jrd)A%tS_7G&H7FSmOfM`hE^fR} zDn^ruTSJ+o`gbPMMyq7ow0N8P$A~l6svK{s#1EA7f@!zf)xLO}`ukpzNFZ~&D)pw9 z^r;OJy3B8FawXLUHFs;}$EHPn>Q=QqVGWKvuhnlmw5^`rKC)-|tFNs~@2fJh!)vvw zn2Q!clgZg62TOw_osta``wF+Cu!7s8O=(+)!u8|Pd1u+<436LoAg`VOH^Tc z?N{ozou|=nG2Ywu;A%NQf6a-KZufNCYPrI?9jD3Z8y=E;SXU>k7P*>DT`h5Lde3gl zri%XhAz54Mwc1A-hpbDVrrA#p=-%EY30V?HOFq?g3@QM<_AdRl)8sns_x8HAl9u`M z3J10>a@8(XEXk5h#dmeiDFu-&VSWF0{nkg)hVE_6e@Z$2QQ2rwC6IXP(hU`%ebhhd zEQQmm5U1VNX62~Ex~uNbsG96me@nU4xMrz2ntCuS;L0nK@JHF>{SwMeTX5 z6i@0*3iK=W&y~oUMfNU^OukQPnWoD;Z=DOFZZxh`8M2>Z7|L1O;?U$aI$y$dMsTTPbMQc%QOsntgYqhM* zO)eFVa&!MX+TN}ixmHk$Zb|#C*0j^wYJ1(=RNK?U4@k$G0ioHYtm@lbGleEn!`-#E zk;$c!LYxeYJlCF%TD!VSs%>iYsXOFncS$u(jegU$a&C9os=gR@ss4t?RZ2aoTvGT< zE63>vckLmM`fba4+n2o6WS7Yi>e>=gxiMK(te4)UnrinpuWC^14c%9p+WzaMjnApQ zk_XejhD6R&H!yX6RJHm{(yiiglSh6^{%sNg*X~pIM)R#}1yuE^bJV$+yS?h1pZnye zy8bVzV|Az0q!W@z)au%%`pj>eeMW|-Ui(S1!zfKDDCJU>qTi}B=(n|>E$#SvY4*m| z_v^3uoQ!teFRC^l-7qGNLLDEF-V@c|@I~1rYf;IAv3Z%O)x7&88Emfq^AZW8wBnIH zhxDGYn9iq?Di_&QQgyyPOYWB48vWV_WsCaeWEs}>3(D0b;lwGb+e#&pohABh!LwBV zy}nm>{Aw9bFCUO`qWi%%(%g}1rl6uGsi+jLx>ssLHM>=nW^M~s_2s@Y6kAu{+w66> zHpj2H6rjH%eOeVjzr`P_X7lFByuze^3vlBZ5N+LQT;sr#>Ol6Al2 z#VdPN6Z1)0p3Hvf+DK!$9B5uOvSLJfwr`0(^>-;>KOX1sby-! zQG@pn%3iC3>9>rGG?u>Azg9~Aj5oOFu3L*;W>_Dzxc2xf@DTvq(nv(WD>KZ}D2KEB?7ORZw*xJ4~w^ zSDBg>DUB;#ENAzTlM3Y?2}^oM_e@*&Ym4iD(JI)cC)5QJ)`X<*ms29G`(1jMcZj;2#LOXS+0#2D^JXc8v-_pCZ~j^~MPzqkcT5Ux zTCpqrpfvIHu2-K>jax2%w`u~ixz*HX3~wwhrXNr5T3Jk~tFQQ5CYx1P>h&L>S^Zk8 zU=&IPP!^j7dsv0HvADiUja@9~N}-J1Qon7IAMZw~b~Wi(ohqn?qQBw&G9F9MF-oqi za#G+!a#Sc?&NnZn)9Y`zO^$BGBa=@hB)t<_JN3OCvLe@8|AMrhW(y|To#}Ej)7?AT zR!6M?HB{((mrH>dyt=zgOX8h!a6mSw(#iR%XLP9(b|lV_>{#zn>%Go{n)l^=vtMnh z^y-e$pSElDi&vR5g_Nq#Og7alw%mrK+I^wqd5Ws79EiL}P6 zebo0!OJM9$KjyUmnszxPsy++Qtdw3Y6{f%I6Ourn*Qn`jKU+Gux(7$OIr)QP3THJWv4-6;}T$E$T|nszk`UUkgg-qR|? zTO(523J{3{*+Nv=2 zU;RRFOm+6qOt5u7Zg$WQOV(RA2K|<~UhjTw!pNKLy=xZbHaHWM`J7y|OZu+lJ3e!| ztgF$ZIh4#)RU=i?Rq3Tt@CesW?@B+uQrfZ9?23mn#byubjUTI7{pMBw+CyG#Hr=>X z*>u}CchW;lGiOS&y*@Q^hGu@QnvJ^O%5dUcFJp;}8Y2yzRGWLI{dL)=dYsG~XMXV7 z;$m}-C>0e~$IonN$nMqvD3!rj9+kp22iQ$&NFSMAo?h}+wf7p=?ycpvid;dPHn!?| zCe;jPYZh{yn%T@8CW-5}y&~zW`;ZJqjpeHzSn)vmRsEJXrQujsy(E#gtKg{SziROW znI-CbzbpBYdDf&hlW$L|NH9pG?OJs+0^|;+kd^XE`4;`dt5H$lfsM=I@YiL~{O()K5>X!}rEt>|^_O+4B z1(A`-B@&``sd{xzYs$Q-Pwl>?dFXYtLa_cBhtBAj~r5OZrQ6%>zI{On)s2K8&tVg*W#AUEh<;~EzRqy zROR52XO^hb{)cRJs*AR=)%pJ+TNTNIq$b%?OaDo>x~u-?;IuAB_}@MBGoMm}Q1iL+ ze?IQuw~xD7ve0~>*;|!+>v85;X^y$p^Mm?kPKlNyqj_h8Oirs)srK{(tpLiMI&-O3 zzva^QbjsQ<=VjWY?|L%HF=>8jyJ`U)ts{eSq&iw|GMSsycYDhTed+|c(56Q+N%ghg za&%CC+V;$++hxfs9Z`CpwWGV@8EL4;cBkBo)HNR6lMdK2=V^C%bW1k2R_&SdG&?-a zNnz#;UH4xM8+WQ*X`e20on2+6NBzuPSC^Ka?omH8*Nr!q)z8dzW6fptGjoPDbB-nL zv!(-<%z55)pi6pd``&U(*g|URFTJMcPD!!*D(|8`dy*{m%FR-W?oR(zjcz4t28;;p^yUwUgb-z;`|nH*zHuW4_a zPOs5sPO-^kc4m3o$gbBmEvDBP(rZoWwMKpFKvf8tQ>)G&SIa8mz0K>%+%IEap=Ot} z>hhPhcW+buvOS}hoQE=(X$5QMGK1jCTxJyPnafOqFMdF`l-$rgVi2u{%sHx)s>g4a zbanN@r9(Q68uA>nU6)y7*tnx2_gz_O&n%O2ECzpTkXuNzg-HLEJcTl+*mpJL0HZ32 zU!J(5R&8^GA+tu!#M?7#RM_Pjj>TZ<9cNpcC3?r%a#^3sM(b?Jh-5%L#7hd==C$uJ zsGMzlK*d?|Z)uYsw)V^^-rhjl3G#@m&;CutgZ#;TMzW-e_?X;XURvJvSbDpDOKs%E zy2Fv{g!EoxZi5kZ(6BtYpSc1w9u**c3a)0)zbH_%3c+^y{j3yVt1E!F>zFH&>C6wiaZ@X)_i|(X{(42wDqbP z{ob@r_o@lq+*N;(^FkY|s(Uxbmra$fr0SD<^N`utY$c9Oujo@zX~1&#QdgDT>K(1p zr`o>g7p|7~5t5*L)hnwOrABN!HkQ;;@<)R0*|D+A+K!FGZ!HyBlIh`&jYDs3F0dqZ zrjtIdhK01wDsgh{kb+B!YQHQF3s=bhY5-UD`}P?0DetD8QX>|9&o0^DTd=B@FM*Nv zylU|tb^6RT@{~T-UC$clB|-XDy~5lqW-Z;U+Hz zr181*o7SmV%fTuya^c_(jf^LnnJ>#`=7Vzo@Joz61V?H>Cr7Af&1M|_-&xvJS$|)% z+k8cp*h0-_npKmzQB}**W_=udqpFLg&8j^3MpcDva|iB8KOnCl{OS7D+JtF!-0HjH zAjzgHtsXOdlAK@aBP6L?WJYh(->^zeIMtw|-neaQHmUZUypfZmY%*?c+9CUAbn;_e z^M2DkYnQ@%n{~;1Pe-d_H;=05-C9>Am4}Sgb$#!HYRhIdXf@mWDm4&a|5I6Ie7&`# z4t`@qUN_Z8CfoH}S0rDYc>Nlm))-BTowtFDvenlLyb#R=`{MYWRrB!ovYM*PVUt5^ePMO zl8&ysvLxLcV0Ds$Y&7K5dHa;K>b$io;_8gvYh_h-=-M`T)BS)v<=%TND3!-pm&zR?YfW4+pR5w>+}qj~f@?lx%(D{7iF3BX2N{Z<9jE#J;z^vg#3; zg1-8Sgvqily+lGIIncGK+-fB_7X7BDW#E-<#^!y%pbD+kZ~BqiShY8+W24OLC3RaS zBNtK68`JIjt;V*>i%ZnJxUS!_ef19gO)@>Htk|Be@6O2aC&}@LynXyKb$tCrIehoS zvUgGT9{BcNt=hYLYr1idG!$t^hV&kJ8qwcV>7HA@;{IK4^q#fk(HGP8-m|oiPPfj| zZ*6bm{B~=)o-tZqwcePK#ThA5`=gV+M#Ib(-X1XC{(K?*z&l&i##!}o7#}L+trMzr zDQT1Pc-`H6Po{}?_O>R8dF!O?m60N<&d4{Bmp*Nebnk5IzPI@vH=VaOCxuz-lpLy0 zJ=QKQ;&za(9;9i%+GR z3r{7io~Q1R{hFs_`1{k&Cn{>oc(YobHn;ATvL&qc{$E=I@47YiE?djiB$xQNM9Nlm zvv}7t2HtCjx_|uNXUG`cj8(Z=uHMvi^P`1S^A7P;*;xaNuG&rOR@?tJ=*O)tqM!++X2zVnIx=I1w0q?$a{-@KmG zpNi|c^db7xUGJSh;QyV#`38OJqW4ZA_8+7mx8SAkl|sRql#=}ii8%DBpGt||H4^el z;Xg~nqfdS6y%QPu&k_l=rql0{6V)32gW`nsn{JRJTZy!Owko!}()N_RM{lMg?f-wQ z-1B4I4=m|!X!WVxa=dhGRp+!R8Q&e_%?6{|=AU-%?L9I=JLHLAlX^|`&a2N1zO|v% z&Sun)9R1m0|VE*HI(B{EnxKVe?~th@>G$o={yxxITNCG}c8tlk(&hQcbz_z@cYHuqZf zY2)%$J67!2xI?w}bYoXzAI*nkq4{aNFb=C45qY{@q8Vu%v@V?rdSt6iaJ%<-)<4#pm!zdwMww?0 z$!9qvtx}g;fQp=KY3E|H*lb9$Q>OT<_1lh?lBm|zdz!phY&A6fmd8$9l=s#8&6^KU zJLC;mYX@5om93Jpimc3dJd)&sB&Yt!Vp1u8B;a8#FBz2`Dx@kCvZzKV^+y)9jWHFY{se$iml)9T<> zXw_@RWiqjpbJc7^rZY$Cx8=PmRO;2_ZaMPfYF^y)7g@?lDJ93T?$_FSFKE+Wf3S-0 z9+_acWkH|4Lf#ik9jn`^OwgCMW*<_$=5%czm4y>k4)oV9k=j$a_{P8HqNY}}dvmcu zzb)0ug=Fv-vTN0Lea}zCX1&Xxl9a2o$*eUdZ6nH~PEW zzRa>rk7_^NuPwRyfYpU&4E5PRsBCXr?3Vr|ge|dRjn`&tGL>B{^?(LOEQ$DhkN|>d`)@5|WOnJ_%${kf(#a zLxH>}YIaa*$M&}EC&)(*a=1R*{0MHDw1mB}ZPVZIk_`UM5imWn>a`Ukl4f8=y^w1? z2ksq-R<=f>nXk!suExz)WWM^JMdmUY(*EPfyh}*TlKH*QrLB^yXUCPCNiQW}+Kx2ZJ_Z_O`jeiqp6zCaE-SOye%>RUas;du#{N8Y=& zhSpwbInox=txq82{O~(MEpc6J-e_hXkPp0gZ?J4{{90{}_{qd(vDM~O!3T;lC5c}D{%tZsrPZa?u+%2M#AQ5CE)bTjz4DOU z+T46zZe^}Hf+hbom(9NUj$D35Dnq@`Y~9(UcxnvRZ~3D<-si0YvOIISOaoQ>Qp2=d zqqTqgikdV$^UNmIl4N|@yT3K;G~Yh0sLK(7^!Ayj<@3(ov(#s@vAx0B8?KqEB;K6Y z5jEM-%;C&^s*0QWN~-JrTP>;3ze_Et%`UJSUU{ou^`8F8?uP8Q%YNDMPZh(r$Ki`r&C@i5XJ!X9gOv*8Uq( zkl8^BeGwv{IsXI?^Lx&Qy=qnWe!e)jXS-k-JBv-WHl2LVEJGi@Kf3DdLjXxp#f|B12ij*rE!6)b(*ok+Rw_Rs>F##B6#t^bWVNG@wx*+ z@0u(;H3W<^O0)PXjND_xmfCTKd3sw1Q#D>>awb;8{IM}U~ge-F>&PtxYZdALuAkE)epiu5(tliu;jksfk$u2}o=msi#lOzsbj&EL>ax#oK0 zrP4pv6nch8$#3>%fm$&M9&jW3E@xLa$S+Y0x-q=>XWo?{XvIba}FLmef zQ{T<5PnkGMvh`>6(Wp6<(h7TyOs4Kg?E8)>HD7l z(T91t(sy|qdiHz=bT;0&y)tc&PYs6g`ZS&|Nwc&uGAp_Lb%3hpfp$fy1kdT=!=~4w zTa``UppOH6_GM>&RZ7nSFeNY_oD8+HO{@EZ!H#yQV9KxG>#O_2c~8Ak`19Gzd*d(( zfk8nv+xk%-+M8#VqoIAMkKO6>(kd_6%aT}-#UCN)Tfb+{ljZX>WDQrnlgYz0(u*=6 zR%u6K@T%^R5!kcm8&GAgvQ?A8b=JicJIiA)dT{8-?4F^9DmkuX99B3p(e%i8wb0Pa zX5q+exL!ESJvM4qbJMSE4E73^xFOK81bi8J$suOcZ>ReLz6m1zZ0Ks?%CG_ zwH0k2t&F%1U)AXGo}+W+4BWAGHw~++&tJ}Ik#vNNT=%APUxJ50QnXm54p>vQ+B%2|&*S=poqjoa_kzkT{-8g4_xa#v;3 zJv89grIk&C{_EoM@gO)E}AQ=*&Z3XXlB&uX8K&&B2Ktq(}jScuv5LuI>!hf9?pPgrKLe9T46 ziyovaWD4R0(NSrdgDjDxiSmSHb?QOy90?HWqG)QSO z{F~5lVG?CW5E?_!NE32N76;8`o?-e33xSH00-)OLa^jmEp-S*GW(Z|lMY}e4wt@u$F?&td;Ht7m^39pA|nFevgs-ReIgOkGfhE|FdO({nU8dc69^T=mkbbWioNIr%RS z?tYe^`7iI@{qOv}0b=a90bil8R=sRPd|q9#p*h>8Q*9&(s+V1mwkf`{q1I+_(FW^x zu-E(V?e+e5FOuS+-A=#1bEn@QTr|LaVSxCH`Nn~`h(IHi?C;J+f6re+UPZh@I*k?- zuDft>q53^jhCx>fUmJO;+Vp+?omKhLPK+q=$z>yi32c>(oKxcw4ewEls{Q)~tqmk| z5D|`pQ@*7pgNweQ+vLyd&y~&C5%MNUmi+*y#?< zMo+NK>gB=cID1IVw`cs>{6^IU#A#T_SAUaVJx~0&=ftzjf$KF~e+A2ZV%ccE_w8Ir zWD+UK4dK_<`k3Kn{zx+R+}DgonpM2|xi|dU^5UC8y(Zn0C|p*cLHA<*zE0it&wU-Q z_}b$0jW&C0!u<37sj0dGe~zE^e52niXT zXl8;ZP$?qhx+-OZ;a!H0`z0Rk5Xb|hZ5{gsUjw+c7m_N!p;hR#kUHw7qhjSPO^~(L zRvzkkjFW6OT<+l(&coSSXk1L;JbD~}3Gx7(cZ&Iq{|F2m=-=d5&(R+X;yBQY&*rQD zz#W!Z6y((nNq^n>-cjx=ft=2!cM{6&S9V z?|+zP_`wAthDo7rnb>mM3KuM;X`+2IhgXd2ZeT&c|H@xu0KpD$iQ0Dyf_E4k%YwU9 zk?xC8MXl_+%+HfSlBQF+L#P6p_P#)$LCag3gp-Zl$522@rx4-GO(8EN)o{afKjjQkOIg^|LH80j#Kybo||5h8Y zhl6rPti8{$c3mCT)N>7Mx&mwZlkZ>kDtn}rJJxiYwgGG5N`IIGvTdQ-JIbd)S?9DU z8{qALvbP`_4P~Y#Jgi$O@1gw7s7Z$5G=6`k7(Q&1VuxfEm>J zd(XvH-7$2mVZ(*_d)MUh_gTjD zNE^{$O(TsOr#5O#8#Pu}HGo=!!M&^J@XpHFQ+r*VOS@e?x1qYKkym6i;Gmzw5G!X- z9bel_3EbjsdTcargSPaSTmbOv!^zioi>_XUDd?k8^hqdvvT&-URUSR zZdcE3s;-*NE0UF(FGH-HJ#~!Lxpa`#b7`}NY}>2nOr6S{bSgBshPcbMa|0$j#cr%< zuC)M_@8D_soa)LunC0r(+S~?)EP_y4wl`E;-#&C46y!Fv&Si?FFvVPa2VPPb66CMU z@%yTw6OGj?=WJL#SITW5v`$BuQyW2=nh{nv%!xzH-LP`*9LCrd-kKZ7kTZtX;9_Nt z-!?`oIp=fdiu9P}6`|$jVFhmVNQU0q{zmV9L+hKvfae(9N((dk*`nBPT|oUTV)a=$ znsxII*Bz{U!^#VDIfX+dc5v-qP+eJWlJHWR8{EoyB`(z>1k-c%K%?Fxj_u||sFV2NK2AF(~ngx-o&I!~o z6LT?#8JSDsLd+%R%->sp^5D?w(#7o3RhPkb1b)Bu{Z4JP?5nn~=RIp%qs^ta+H9A; zKfKG);Far*$?e5{E-ygxxd5OkJYOKcK!jEI&iOeBh9Etvtqm+x?3cfH={eQH7v#*+ z%=GrzvW^fp?`OlTCSfiNymYaipxvzX=#A7V12MKC^ z^pNP8cdAu2=xtcm`(1gyuDh!%-`~VvSqdiZ8fvSO7QUcy(o4FY@={~%rN&^PWT*cj zc?@iVDL}&XS6;2bPhG}(1PkKq$Q=l@t_R?(T zFJob*`9u36lb--85)m(OuUa75JmmmQ?pzlR^&Bv#wm__ql^3AQ>tAxgQ2)~0+DjQJ zVbm8mC#98osGKgT14W68EKp#_89UAJj*w_f>3D!Ix#9d1g-=*vu!Wb(Wa)6Z&_QF# z5;GXgs%XWCuE~<{ip!G8??{$JOGGa@t2#6hdhn_mz@zG=z(~4zZbNnD)w5gzWq397 zmiThYTaC51rejtUU0RHbu13a^FVt7(vaBPBom5^;X3aD1Lu+fCtpg#t+;S5Vd$N(X>cO< zgy3;*xB2sPgXZDqklkl!(?mQ#0WACr6-(xlgFjh3raZ8oJqpz}<@-PSgi<|pQR(gB zrCGUeO&sC*cw@fzz+$%3<4yVXYpl^iyX5{v2dx!~^SW@(Bw)Jt5n% z&@-OPe`+tMBH@Lu%3_@4niz-i73^81eYi(oUG@;zookkxh@`UVJAR?vErmYJC8(w6 z9t^UlocK*S#exo)7hGg+MpZUhB;Hfk%gN|*lLUT=JB2ITX@PP%YdXuLxH@o|5WwcL zknerwFSLGw)UW&^BlN9e{fcJ)=U?h-rC;?v@l~cbhLLuUronp@z@Z+){-JRq{v)F& z<Zsdt?9ea+o@kl`A5gx3U`6J$km2;58I) z7m-%B2I|z<9yu5^+O95@|Ew5D&ymMjUcA@X;Vs8_)?Gdhs~FL;As9W*%(eBWYKIZu z9szAuzW05gopb9{n|OvOa-n>(d|>FAm*!Lftw4Zwx6up4)$?RS%QMK5ZX>v{7>9Ct z;vT@43B`T=L2fARgP3&XLl!xXH$J3NABD>HK^pZu-L|B#sAJi&eE*Mbws*8jzgt|E zHYC?$Y)B$DG`b;Bcas(fPT=TvWK3@4bC9P&tmg{bk;% z$=iE4eqNKeU;JCTI~E5!_EHG!@X!fdKk`Ir0!ShaX_6O#JHT(A=#TQp6xrJ0G7#gm zD+rQC<-e#&Du~0{Xx^w@YzLE+9HyDT-5GF8EfW| zz)NIG^TPl9n>>XcNC0@Tm)y#E=lrqGt!4!y?W8%}qrlHFKUtUru$ZD*Pvoo)l9jWC z?Hgv4x?NVlp*%_Ix>OI$A#JU=o#eO)VD)jDo30eyyD#&dky8HmndSJZ#2!(a_R|bE)0zS&^gJ7)NFmDVB+KNOWS7kzq zvx=_?TvdEUWxH|I(>MM?rO&u2g!E(Ho2FXq+1Cthm<%7UteH>h3|V@WU9AjQDK$&_ z6VK>5(57<-Z@-3{+l?o-8asu((RO2}5MVJ$@8m_TvcW|UXny-;1Nb>2G=Qt(kR|BC zlY1f!WU>B~_l=%FY(Us2M^7R(JH^xUKEeYp?}QHNC=Zv9tJc#)(1zZDwTN)Swo(Vu z5gn!uh68U&Jh?8AXkz7^V9ykRMHef&rOLd51Q+3On&oQsjI}Lsx?Hv|-@iiHYR(%@ z*`iS@)AldnK^`42pdMfXQUhf%cjC>I_n0RFMWe4UcZ?q}JLVJ=P%QowU5dLM~UhWi-s#3E&WSq;A;KTd$d$wF! zwGTk^LPjt6yiTbF1Qy43^D^UKG2_O(&s4XZf6{)o)0J%$e33t)>sz>AeVrU=3o@37}`iH6DL@^UWJNPbcY zUgE2kll&OaYnJgz3uB1`qdI7!zR>{HrLQPIIy%uvHW9_lTtDV}|M=sgb&MXB`eT1k z9+s>vA08d=d7{Bn#jNtF`Z&=5M@j0W+CW{yTP}%Q1<3X}!tII>FAxNEFj@RNY3KXz zxrrvdwq_@0Et2v_{h#JRe#h=bC9X+}6RFTnL&>b#tGiCdxf5j7c9FM%)&Z&>0)X<0 z&_8<}471MMags7?59p`F`xxT3#dD)*KzD-3f@~x4!v_=Xw@$zD! zCI4M3OUZC4lsqM?Gc9TA+K%F(FF5Atr-24 zEx)c!fZ5^VDHHn-O6;%y=m!`zY+Oa3l|3f)gP&xSu8b6n2<1+3*O61Iw6UBmqRf`# z{4hRC0wqej%Zmag%aARF&qS;;T*$&VG0m4HuCD?w-?&B+A1^Z6A?zfL4u;*ea)1zUBi#nEjFxZ?tLx0Z%qz0LrqVeE-hhvsWebWY{2PWxV`3 zcO~&f$Qo1?!Gr9wj5f1h1SiZE%_cV%?Ux6OZIw;C^~CJl+;Hv?RHA;su_C-iPnaPh z&Nki7SR3t&Xdrr)m^ED%Hnq$lYqz+^#bhQb^DFAcs8};HDwZN8&z-I@J)CZ>l@o8; zHbbq@zU#Z4^*dV`FT0W(M&l{3^wh@sgBJmt?cexCj5gHoIRgf%F45nb`IU`Ee=;^6 zHmdu*ejdAsG{d421*J{-p{ViAVsM#gATvW5X_uRTSOn;nXINjMypKzvOu_+sK|=q~ z=*gicn@o_v1a&lb@3t(>shje6`61DqtYuwKqB*Ew=y*f5X^2fwH)5zD8ql5Ap-5(t zx{hcTsezn|OBaoPxWVbFYuUb=UmT>L-zh?AeRo0+c8=Ijhs1KqF1?yAR`05g>gSF! zX9Fsm%=>yA@9SerXv73r#6Gzjm@fy3j&j~*w&Y4>OV;?)cKTC8!pXgnlY^7ss`t~4 zZD-(TAjU=5)riY0zN-m)vY^cF;Q`7l>{1L_L45eFd45HM0qerNug+D71u4%mrR;=0 zWJiZ=DnsRA+vODH2|%RedtZTRXKsLpKhH!=3bO-R|I19WX7LSv3AFCJuYrN=TQzW! zNC*seBB)CIv~AbuIFl0T;EScqX4q2?Z-x*gKGN+z;vsdl>e%lQUO{#4R6m%5!RH#r z@WcG(b~UPWAAq@CMc>r$?8>h@T4Xj^x2vGXqt5)g1O7;242Rf@gG0x{7S_$78U zF8E&AcyD&!>rka+p4Z^jHmBD52GMKA>I(6JpsyZvDWb_xs>oHA`(R~PFm#uztSmk1!$?o}(O*zs$R*@R&|TnhiV&gTyR=rl#=@2-z)0+aW#m+xEXez8# z4*jm^mvwpwy33sLtNWtQHSQ@yEsvZGZ(vzjKiXPIVoP@DJ z5DWWWY><)~74!2>(S1%md)u_;@_0^EhTL+!oY@=)NfxAFx{ISV0+WY3Sx@D|@(_u4 zD{B-E7o27JuujX1bHUaL1cgrRbCJQefgU|x`H(ysGGS~*gKj_Vm!Y1M=}ULQRdwlk z2r2#2F^=ksinza&ILp?NOy_nkdyaGe6Mw)LP3*oav3&1F?f`4ZU=;UQ*o%_|>pQp%aB}i2tveG}# zfL+nYsKo{3g+1Xom-6V{CG(g;yDFPAzP*i$26&@#jSOnTuth(h6NAl0;|U&>)ab(q z2}`Ai61xMoS$F|mArlW&yB}sJ7x)~;WlK9(l@EjKf^P=}#oW`QCt40^kE25*F5~!& zMQ0t>w{pqxoqY9o`Qb-*97*}!_i_gqps)P=j>$X>m&zu?I=;fsGKypUQ<|EqL*+$_ zKYYN&{NxZ%=glwW#sIBqj}6m$%nWaOM|ceE=0j?-j)dc`6vsLR>jR`XmMa1g!f2Cm zyvcCPTy-8rL7{Hm6~y#zGk@t`4#^ICU+U+sin%}Rq_hyZ!O*waT(j5@9LkRH zgD=%|Nl+xgAo;NNP}|fJlxNVGBHS#950Rhgm=?GsIm5kWYrKKc)zf5PTIs>JfZ7cd`i9tN>;P!GF#jNAMPY)nTy6m2QIIA_y)T zg0*HxupS2l7eR3GrZwEqw=wwwUaXYni|IEyYa5fBF$EPUK8l47u<1Vf0|#+TdSyHQ)Aa5TOg@D)`aY_kgf9+dK{1) zCH7=))&OUK?1IPD#Lp6kg4oRbTs{%Z8e*4x5wmffkW{%t2m_ra%Q#4sr<~G@v@)`1 zazhGI=F1OJ1Zck9JJE=>$4OMmdnkOF+uJf;*`v({IJxY&mj|dWJt&1eikFO7^yrD6 ziShi#3pi)B>`}@`^0(*6kIRo%)_~=-$w`|0BL`HL9nNq17Jqw=oGc$s%Mu)6IsmSl zbMHC%tV>)so-537mu<_f%UOuIfh`}v{om-&#RnO(Ke<&;4fuGZ?P1X$9?th&p;twe z5HA#I-#3B?7IIG+!wb0I2}n(=rihU$m8IrFRVIA=@QrMBlw|VVCI~sir~Md{iEr19 z)AT1veiy5f6lVAZ>V&^+?-!MHTV7)1Vdd7Ks@ImI@^)#ywof z-_U;67d01IQGfL{D!`z*Hr~w-4is1ahi*J^vV1W4YkoQWy}e_cug-j(7Ip%2<1PFI zuYU5f+T~Z>Jx5P6x6b4yuFd|7@0VD2zW2!k_CCh}H~t$xdEbu#R-f{#@O~jlxUPGD zz}~;^L3^K*X&Z0gC-0{x(yG6u8^J`fS#%`t;Z}fiX59;cK8xUB@5W!`C!P3#-s;c# zRhUFEd8w{LOe{q1i)57@MW}6gu?a9v4Yi&{lM!ZDe#nHGJ?^!~;en0|ow0-~%r*&k z`*mmY_e8#zk5901nJna9tyYKgx4%rSj^%rQMy+D`l_Q$eOmeP>oI|S2Ea!eWUr+1g zTt`jL=~aM#3OSeZOUfjtmUC{Ut8{}$mGoLOD{!wYMAe)TknAOqVH3D)H9_7e@yF5v z7kcho6uyyZ?b(7jl}w*r`=U{2!kWU?rQN-DeudDvF8Q;@RQ~E{wM5(vWPxnsFJG6~ zN6o1s37M~iTfZkg zUgP~jvRph-sl_4e+;|#?D0mzqlQ$7F<$htNI0S_6K?t*#kXv#B%ZcGph#^vuE<0y* zJo*{u0O{ywEHTA1^)p%qr5j@GyJR6?ahX{bcIX~Jb0b|T6CkmJmY<>JkhvY}-HrSG zW(N^7HI>IezDR0I2mj;6U8sJgA+5*zllmWf-};B}g(c*jG%rv&$vukuBMfw+A^4~X zH$T~cy;yBO)*?r@rU9jC-e~|s7t-lrJrX6sKcpx`FHeat=tcP?r8KcKyBgcdW8@;a zncBEG5Uh}qv@LP7i}S5yAI-Xo-Zw5P@t!{tvGa&r&?nx)Bc$j0>Ejj}$|$u%F6 z85iOt-)EKot8oi0kYUVEgbAUpXN+5@EpZDq$IB%zPjcmx$kz}M&@K+kHgbKnsUMVT zqN&Hp4I_Adw+GFf>BXOo7Xp9zp5ohqzqNN=>a%K_T%YHwRC}CAhE<)_?2P;E`i}G( zOl!u1ab=yH4vLN}lPl(n=W$_t5Yn6@^;*<;qoLaqNnNB7c`M*kG3s}l-*OmCaCu&{ zQ;JbMGF5I&!dCLILpU`@?)he(|O zQ#9)!yIDy#?gf<)fwaScOtYUodqQwrHgxk(GnJkElpEBu0xYGX@B5or%M}+}wXq{N z@mz`8kMaXjSrFb~7}f65XQJEAr4NQ&$YZM%rR(s)Cwz-MX`bYe^4#a`vS>l4YA91T zW^Z+cm2;xvk1&A`SOu!gd&@vFuF}m^)Ed@CGcu^jVC&nhxroe2lVD)4Vdplq95iYu z?`4cCO&Q6pOaUmaPR=zSC=MG&2^FtB9Liu#K3I@TA+P`dn4h^&-4n*-nwgyXk^o4f z;qC*j`FvR}O~uF|c|(0Lrx;B)E|i~cR|q4x%Xg=49uZU}i7CcP|F1!0=M*C4L+pWwo2Im8bUQ%Jhd^qq@eG`1}nZ+Y4!e&9M#V%{?>RKu7eP$r-* zf*GQFOI2yx!UAmwsN(abEjeJ$O1YK2D&Iu+|)$lX|L0Y9|mGzlW=+TsHR z1cheseBta#Y5^*m9L^R@%l}oiVAwiMwV<|>)WRi?nVsV#Ve}Dlraa#{=q@`*0@)#6 zgOAvfogKd|Lm;|D*CBl$kyajqt(-V4P}E!=5nVVrQ`iI?C_S^V8UQ3p$x-~@NXea! zkboO4B<$$Rkzjj(0eZHXMIgf5rpqT9j3y4w3yp(I%j1VU!Z%{z@wbC~t(+yHR5=e8 zjAuc(2+2JrNp;`@JHu+k^e?~Ch)n?U`vpFr*Z*?vDvl%+vYL)C!DxBphGA0W<%yo{ zaG+dgvQ4m%&nQ?VXBg0=hTOd~pByP< zXs5 z10D30d$4E!a%j-z&D-*nw$Cw_cqsJ8$ETlYl=09=uR=<7X_bHF{510u3_?TbYRF5E zq2$~_qZ&{}Bjcu{O}P=<-$uDa(T{5JorWwcm;}5pRcy7HO1p>jz?~UBe zDV6ydy@HljOyj2OLLZQZzN4=44=PURK`D2`hzWQs%OD1(qPuH)JHW$J;t&3>4yC&w z-Cf?1k}pFvDny|6$*|gISi&tyJW))#+2T<0IOaHPh9K#zY_Jr=lHwX9DD3Y!+9+JQ z7#Mn@q2+L7Xx|BtmI5AQz_ocFipjV;8n!ocm+3L9TbMWkRui& z)i`xy8z@CXcja$C_TQPhj8X))WAt0x2~u|B*ss%WB){ni{`OqIsN+BQ>gQCPN?S*S zeoml>2o)JQUN-AC!-JIYvj{5nGrw-mI=v#4fs0PHFCe!DZ8eMeshHwTZ`a#1;Lgkx zm#qIq+^rbZp+DrUAy0?h2pCl|0V6vPqa6Q$N{}y0VsxAWnNDauLu~KkST|YCCY#kjKmJ7Q&Ws&8NF4NmmWNp~etrcfqM4 z_*EiApAh@>yXh`?T-~Kreug8qY@_rU59>rnGP((%uz_kh8B)iFCdlPIfHmG3Jt)Km z5x~`^aa!2+`t`7NCoPH<{VHeqh6^-NO-{Tge4AO!I)lmK)5Z>AxkO!$Oa%y{aw@=-TXH zueu;Gp~~^JH?Fpp0y|FBW6euESA~bvUHGm}0K*D(*}o;4lKnftpLF+ZXsX*i3+58v z&HROEPILF%Il~Fyl6skT1AUsM7Y69ydG^pK@UF@`nkye^>Umb@;|ya~0c8E2HvtE) z$#0~|Q(N)O9vho*@Yo30=CKjQW;`}-dIbrgvL85#uoB#5!)iNp5?%RPa@@RcEfAQ| zaibyX9XIf-P@tn$+e~QWpf@#h{|$U-oR)RmY)~hD1KKh9<0Mx(kF=xI2`Hk1q|}#r zaR&5bsu$;|@`l_@b;5$8a=vxYS$$_m`eWtQw|E3%ys1dr+#0s;>a>2MWdZu zh&~G^oG>nXuu&u{N0!VHIkFC6s*$i8%mqP+eH-2^opW8xfmRozWCxJQ z$9>fKkzC7gb!lSHj3aDcYU#Evig-sj4mrYui%MKzc4B<`Nn?Ho6U&|N%ASdJ-7a zr={~)%Hl%jNOjMkZG=W`aEm_by#E5;GDcsm0e5S7-+9_hBy%;Jn5Ss{q8g&VcJdIc zK%KFPpMEf3mW@InRbQ@`L8L5o#JMj~H(l}BnmqZ2bN00=MBRSC9yKXF6&$*HO&d|p z+R816Fb8P#TvUj{+o-wP;0m!aBKBNS@aBotpNeu#LiB*fqc_#mm{LCGUBUgypj9)9_sj)FAj1q-?S2HlAXd~=fVg^@mV+&DkRneft`=rh+9>s4hy1Du1f@MS# z0TQ?*&GyvU^j*T2N498T0CG!81Ogxzz(wG4A-x1fP+Y>YHpR-3e`(Tg*$ATgNS!eW)va?;C-gYEbJk-Fx^F6j zj)%o?1jHDWJOmt1p?e)82@J~3P#YpZ=LAKX@@2#ZLsu?V&8qs3-# zF~A=Z#T~wEtMWN#^&C{J2OnS(9A#M!k(ds#piD|Za$U9xUZd1eZh-^zXo|O)xJizQN#0IVY-*&kR`L>n* z-J_4wh1yzDNqifcas}*Oa{8Ef=Og2kIO#L>Xd9aQ8X0eKqObgXxQRmtt56)qYxzy@ z;5TdODj#F;4w{)0`IhGV#?M_ttMUA%zv3?kFrN;wgs-lL*hU4eK+2swcH~xaGOTUhX3G7Kqj#$idXMS4Qc1`LV;b> zDa|Dig#;bXJg?_~J(h&SN?OMFy4LzjZ)6y*q{<1Lk2hM?3%6?Q7{!1PP1|m)B z3mnQR9N691YzGSPkK}v5@?OnqkPh6R)RVLf+R_nS!yl-?K@=Q^YhFBhE8g z5H_MFdB4rpHEsBcpG*+9hSGU=GpOjBj+l5Gs#omlb4>o*=BfE31A;-^hZ%d|cuBXwz05o4 zMIZ{BtwFC^qtXk(!t^^sBu9snk$xZBYQWzXAy{H*c#Z}Q4?U^0Gv9l+qL4}|z2vP* z0?POP&Kr4WU->vw*~{ye{y?Hbc?8M!5b}>iQZ{r4DE}u{{20i#X2%;OTCmoPGW`#H z>*~je2NKbQ5D8uwS1skG6=c}5s~Zm4$^hJ=JA8#yLKD0dGqrGiCr!SSY&G}Nxm)%D z+Pcp+uSdSyuk80vL%DWKY-^ytiPc|4oJdpvs!)a@6r;0JUW%W|FQwNqgmAFr&&NKuX#P^(*WE2y5uR|mk z)pPQNlY!5#@J!`PFOn$+*DT=&C^PvjFm5!))v$GtRCcj;pMa5NkUG4JsWYUDlzJ=4 z_X)Pmr@H|fR>@axdLu8+l&AQVBT~K-54k92-B-EZL~o0X~R)fAIpI_~z1!gbP4C z;yB5>^ax&LS9N|!@^omWf-yLZ>O7!=qWH6ozhV(Y*~FH<(<|SMoaYq@LK7ikUl*;W zgQMSs4yP~Q%lr>wb@to*#m#Z)hsn18C5O>Wfb|TOltAe@~~16gPwK* zk!4h;iS<}4R_n>qqi7K~fE2uSnNiI;07NwxHt|dlSAbUvygOm< zsQh2|g?b4thejwdA8ax?%pf0Q<)?!IUp8UpQjXk;I-@Tb5rc022d^w9AQQ?RhGeXQ z8nR18XpB%(VU;XpxyrJr^4YucAyt?hv6DrIAevZVQf_Xo3P(Mrn=l`wS=g`y-<jOl6C+avW8uq zQJ0CcOFy{~6G1b2+)&8#tFZkkHx$};Kqo9sZ)YeoSadwd>?ZzP3h-VUszP3eG*q0r z1a~+TmwXqij`s`;idYR=Sf{eVj;WEJI6u&rie0xt1e0je*v-oX`)0$OxPg2SejY@N zG%4b+d>`BxnGGww|2`&|FokPTqY6PkiIwFypHhsdJCzb}pGYwQ8 zGdi72r7SkkXdQ7P-#V-9xAN3t@pA9$sEuzcxhrb6>tX#!x4+N}v?%E1`#<}7o;caT z6jtJ0bjfo~HQ)bne_rCkQu+0e_5*%RPh40_2wBg<4hN3_&+V*dw1G=-KDhxJguN453bCt3lAZ2g$9CBmrHC84Vk)i)bLao&X+xHp}-Jw9gQ> zI3p0O&)fDcRs>tCFiK_OWj}1DJos4JOMSb1G&g4LJ;5=3Z#trm`;Yn4hB~M->Gj#& zddjbVY6$~n%fmUPhEi`jV-Kx31xk{7K*Wl|Nyt!VGE$ilYw!Z7?xe^b>;D;wOja*@ zEh+k(^6+ADa6rfRj=1@4fu+yCXa7Zp-=?RV-?h>`{mjN+qR#Auwz$D4?yy&fObr!WT1w-orjx;kK^ypfSs@ zZKVy;g+G>;IVi!MVQNnFD*Y3>q1ei>Yo~YHU99lw-Mv0$18sN9x6wtD# zhQX6=%?oDHN`e>ehs0n}DfGAr;F3c?EKNBO;zfLQ9(3^(K9fFRRqh_&aOHb{i(QO) ze17LQm{>eUynee#Y?CGF;RX7@Z!@8NvX5{8L0JK@vT_yYla-?3ph-y%lgqN(WN z(fHanN3e`GCodaDGTR&?8Y#6-F*h^f6poWYC|1c3Ek-8G%F?Z&c$%FLxRJG4a{&dL z&CE{|!)6S)!C)i-Ei<4Xov|I*T*GQQ7RNfF(#l7gD{pS<`L`UT>2#A{-;)w#*hD)e zg=(7t=*Rr~0P3Div^!y)3LQl)k^%-S*Zra`5uY2S%t#+Rg3us375WLMDdj|bV6o^~ z=c9&e`ADW?oXzksxIv6B5o5GP9&$k~C8QB9xHsVUP@pA#v1|qLOvXx>%_8qE?50DK zMDROG!w&F5R_k}_yBFVkk##HC7)7jB@5gT+(nI&Y1mf^w9CGmQrWFtxRHq>-(rZPQ zELy3j+%`$6TEj-tUNVW>;)dK_PjwMTF*!{jzhk)CWZzScNlbzO4576LXMqXt0j?Qa z6Ahpb+=vwZ8Ghcy0}`18US9i-u9O+5_KdEfL@$x5bO|1KYRfyP(KP0>OYUx>Y3JC z_!FjHvw<@N*^br)J|(L^2n6Y+V2KQeX?iFA8&4@0CZQdJW~wnkDull%^Z9+T5- z5d#ofpk7VL!a-UiWSChxy1EN%xAwIpYa2{w_aFNhMnYll`IGJ8yq~O4wt0wPSq|jq z+ql40r?Hds^%>o=@C-jpXY?lTQza3_h1@1E{hcQ54*-}M3j8x=;L^^&&EdnN9IEmCi) z*8;<;B7qbxh_flC4BC;r{u2;+@Yjd<((0cMw&h#-!J7gZmVv@cR#2rbD5CI^fu@$<7$kxX&HkdCCReI&O+VZJ zbU~4rH)&Av$}W?J0MTV^H>GE>z%;Q@JDBnz4H4KUxppk>Pb$}3Oi&`^L#lD(GR@`S_cfnt>x0$St9Y|(YR<8p=fX{Q}=3iPaqlQBdssFeXOj*%>IRnT;8 z`B3tARG+EDIOzO9rxkucr>3i%PNya_Ih`6jSpf;Lr%k6qQ%a}PM?r<6Dd{|En9}%X zCL--jvFBcAY?RX_QcaAtsL17{A!-E5vn}4NmV|4x>W*UOEszwGb!95ljW59qpz?he zAt?Tn*Hj!}-OZV@BFB=!j3yatBZ;e37PU zSZ*ITn&*X2Fck>O&dSK2^mN%->PO#|+`!OMSpHqf(UW{xQXV7U+s_M5B-g6Recy?4 z?+TCaes3Z4q4@5<@B=`JyhS5{?x3htoUxpR5V(mjiG8u;85E>anq)x%-k-c6Rf!Rq zL5#hM$!&`mxWJjrWril6jqWn}b`AtgVQG)>D$`Hl-6^S`K?%Ut&S+vVH>NcJ@G2z# zafjj|v2wxs7Y~t-a1Q^tJ@5DFKfiuZalPcT{0lvJ1#Lx*)^F!d@|U_TJ1X#P`$FSe z@)yqH7Zh5W#oC>5jf?68qBCx+K`X28CrDl>PODy2ab$YE5_qOQdBNRRNd58*$qU6S z=NeW{k-RWz2<1aQL&v~9puB+EMv5nWj|aM@M~j&zzxl_`ciM)s0`8wWj#}yS_8FHf z&eWYiJ^fDFXM}eS-tF?ekn@RS>6wq zySpm5s37LFlB2dbM;HM^);jPaj*sh3EaK=MOE1KlCUAhdB%cPUPY|t#xp(mQi-Uwewf~GraL|k1+*LEU)ES$9nUO%*+2nmtxdk*cm zjyAL?R;v5vE*qm!i3{$DFXb~(R3Ui4LP#PUShuKzPlpjiykUg8*n~_qSCC2t{Y>8a z7UjmObm;nge@XXQhB!p9sji@^o+m72J}RzhvePW-kE;zzNIFLV1Cg$_UP3qsgo=0b zi>N}EMHZqnPTezKArQpHv!uv7Gbef9V!BHgSzW`3;#0@Mf(rAGXexH0J(3a2N(Kmi z0S~cRXv8xC-F53OVMe#ohn=iLr4RLT#w|=YJkWN_oVrVKhHXyn+Zy!QDdedUe~_o@ z6H-&MbNJ}w^un}PknxXB3Qv$)=A)A#t%+Vb^1Z+Gt3lM15S+CS{5{F-AV#f&(-5Q9 z&eBXe2%y>5ktnktbD7`~B&FIYpszJmu4;lXyBZtd0{FEqfys>rPgJ_7nYMx4se9+5 z*wdTN_D7;Ae4o=Lce<+${7s^jNEFhMSVw1&!{lDh7=dz;VHA;ZbIz2&)R|3Sy5&~n zODIev$q=hfT>6jPR|LxW5;UnINo#T!=54flE{*%@CHw$-%90!rOr3S4E9y=lVfj?s zTNq-#)Es|Ld)JcLu6TB6l`~1xZm>1zv?m8;DEpAR^$Y2Zn20_%+xudyxZxN#F4wEY zBoj!AM#40tah}dl*g#^t)DDu6AGA)?fAV-*Hz>mOKXLh6EbJ+M7+iIL?EfrKg|{;Y z>hKE(RB4G*0d>+)(*sqV7*Id=J#0)sCZ^;@tbmPrG(i@K8jX?UKaTJV{vzjU^mfVz z)gC&Kcvo4WNuN+mdi#UibU|S}f-@}X-4yP-AIWXpkLYF?2Rj$O+Mu3kAA1JV;<4u1 zM;enqp~wsQTiY!FO3|8+F5ne?)W$^XAsyowCpW-1q$9o|)gv~f64J?8g;*79f=SO=&TaILnE&U0xR^m_10CindfYh@pu?tj1V z63shIcXWb@a!8a+B4!>?;%N)wtmI1{jr-miV%KVwaa9{E!qFKKfVrwm{D=WBI(F_yBjBjZ?BhE?dnvj8}yqu4DKFtJMd88w*a1<5hZi${23rDfD4Q(8tZ zLs_-bG6US8i^ut6rDeA1dfL)5^JPEPN3sP|G#%-bKRkzrr{}L`H^Br`XLUe9u&B-p zrD*u0nFNoup;dr(V@e2uHD<`S%mlzQ<_%!UMpuk7+&w)&Z*=VDHIoB8iU*!%B^u4L zF1n(#7+RC&D$UKQn;UjR^qwad`~pK!j_*%Ht!h{7;{Y{;DfmY&)dIyndE5P#;dz{_$k|%Fc|L9%d1r$u>W<8?O-OOZ@ zFFa>*D8R9kAfV~P-&ZuS&M!Ls@eob?%>DNz!1BDH^!?S0&=jvgS}!m(gGb3-qmzcH z0ka0|DXvkICQ@rY{p26>h`+#KFMY6y|wnx-+M2=dCxaI`Reai z{XM@%`3F-yx|2RRUmen# zqdQqDnhiGE`y|0h`GMU*j8c^>WCHq={L~{+AEtJ|o7A7e`Pn3>`i}G}9T~N_Un}V- z`MjWBtF_EutM8gT?fTmBca*bSd{NHucZA>2NdaLlKZyL~$dBZ=v96@wIlj#^omuzI zL1n$)$F2gZt+Z`Br2(~kgSX#q%k?0vpNC+3>2vpQMcbv>E+JLD#Omzk06!+3iO?-p zZqOZcJs;0R*f^dgtTPe1WLHY2y7C=GJuD}iA}kKzRu?Tg6p|h^^D*E1u=cAupIEw# zcT%_CtCk5ZqzhX}ddA##8y3q)VD%n7Hf^&ThL+t0xB>Weu>ZHrB9ZJ42T3@cVTED@ zlge579ct;35&RkIhh&F_P){Y8FrEP9pT7`n(tP8y-IX%Jy_kMc^5;_5`TnP+_0z22 zTAsuJPjlX@mpMTv8o6n26*5NLJ;Kz?7s5UjnsbegU!<81YGv8IO(vhWEH_9nS$T^t zH6nzSeu71Yf@~xy;B_H`Eu=}BeSjy#BP4)Y&Jgo?un$ACP5z{WdqR%EYS6p+L1G5F zK{Nd@xz|6b?6JHFeM#Ohut%rBEaBI-7xIdjZ&~072W7*zq~#950MFjsTdgChJ`;JQkvGu){25J7o(N`IB+{q7grs{?aXiT&>JYW$|xepj%p_e#m=ch^oomn)?O^|Fb3udXdVySChlj2Sm zFw+be#{3BOe1Qg))l>^Q$$*g~4pGYApm1a4SoKUMN3`TP5cEP|tIly?fh`C-2FvQ| znV3CXi)dl9s&@cJ3}~0;wSlmVXyd*BK)OzlTj&hg<5u)KaAE zh&a@mibEm2j4@xtRD{{fV$EI2E8d2#2>a(WK3mkjQUMZmp;JXGI8`K#>YFHuG%(a* zyVZF?CCDyW`Ay^VRG+pkP(Nu01P1RO1&MF*aa#tq=;$(F-{6XOi)6=hQo=tuk< zC_+^9lWhG6fT-JN9F6;of8YlolOIlfWVtA^4RrH@IN>DO&fH&Qn4WAN+fINfm*|q| z`L-;kfQa1THMoXH9QQGvRaVQwpxu;D;`om&8<`cziKU==nlA{)wlSBb0K$19MvI(P zprOj8T!#TXpqaSCAo*JvbAj%{eq{OlAdr8R9|7J*Y8k2ZLc?3YIdgc6U|4Vcb|k`k zz#slZ@K(oX25)1B8Q^WtoZOQ;pQ*vyV;?3x5XUT}HTfW>r+HPXO^b0!4e6xTVM;q6 zM{;$ODXY9~eI=*F1g%Pmvc+{lFZESQ26Qv<)Ef&X4^p}EkmQOE8g!;M_FkG#cD32P zVR*fyhhcAZ=T}qyRP|?MT52DE@Q-+e-7NW?3R!U~bKJn6&1NU2DaA4YX!_8qU`daEv__^{;oHHnBYe?rbLCg&(e>}dETd1s9hxSbQq*T!`DSM#>upz+AYR3Q6+Ul zZ3c2$T*k^WQQagf%Vl(GC}?+Kgf;E%qK%%g87%6WZVO1h@*RPW2uL3&G&06VOA~5T&|L8;BpMalQH_Dsxm$U^h)V*+Mo6YOA z+uwm(MEfC&2XGeglMBRpsZ4Z+mfwMVxccye$p>Fc@`XPL>r4G1znAStV5o~>Ac~Nw z*16kL$xr{G%_DvPuN80%^FS2Div1*ZTN%h|VZThT5|jY^JLZL)!9i2($u0jpF=44* zJnMYqiE?tu)5{LzFHe%I|2E7s>`=ZayGoAz&&#gz9mfU#nuB%}&$n9%Tj*&vEZ)!L-4OColRCpaOE_wjj-reR_u2wEL#vxu$>-4Z zOx>JNmSp$Hlgkcsqk}PLQ($4t(85?klZElxH_vvR?DeFV_xNjfi>!QVO0$*Wj^3x&^zvR(qm@Ri7la6*>{OEW2DbEV#;LevY20RLPXvk0V@&{$!+%qn@*WXX{3y#q*_Uc;XsKF zaJ`jo@&qbDGvav8Z!w>AXLplV05K4aOB2>&rds|XJTC`5ZmK3sO;E%*Ghpr|&roXy z7&RgOISizF34myL{+z|z+4a@Hw1#OtUtra=u3N=GZX5GTUiw$+L@S0|6e#(5yz@0T z^KMq4NAj5I4NPnrO61X8r=t+xu@~8*&$Kg7#**+#=<3HCyld?#%5p6 z3cYcCgtm4VPTg_+c)T9akMwYyb2VNwO4a<<%dDlLJrslxg3YDYzuX@RTDiRpqbGD* z@@x1)@Rub^=?8yGxV4CvSd*@{s*bp3lG6v<2KbSFLIDeuWTrIrEu2)2B^I$rWQOhH z4Zye-q3v#6x1)?`_`H@Mf}B*;1aMBO|3GI&i`(+3XvgHW7m>%;a+>4>vdV_fSNTDv zo!*n&@`;$om#LaTcQ>aqPp{y^ZK6%z{aC4oP^2jqd_dF)-cECp9wA_3wV80}nkQKB zrStrIl^!espeqC2M@KidX{Ejyg= z-{AK}tm#(~1T4EKGHcG-i>h}VMs8@*xnVyCq2s>^Jvh;B{@SUeyhuI|mz*+q}o0^&;$A`hp;1e2*1gpf1W$+bMC3=guSzP_So z8AzOj`ihzXJ!@CtS@rH`nxVL&=4E8=DV~5MlUz_=S@AWmMdbE*1!t?~yj69a#V}sW zx%#$T`S2qr*@?*a$&55SpAoZa!Y8eoFwYhr=UX8i&sr0ebH2Nk)pKXrGZtdlq-z%0 zb%{QC#g~&P`rMq~_(ASsaBb?)(=iGP`+2PGyR}$OkJ7ft8L^n2KBhf$<6_kq&i9%a z@=}>7U6pi(Inlpeo@bt85$Q41P|SI?9y5FGMa>Z{t5!J@yt+`Tn`h|;n0q?E*UjH} zDopL8CO~7_przIBF>l)Llcb{Qwq|YP)*!VEaVw(VOAn4lPqh~u-aYA z`^{!>%T_Dt+-Jp{w_0ImtIk~6VDrwT(SYqX|>9$s~!tq$_c`Of#+OgD`MVq<`-3T`xM3Eke+00(id1_>a zNg^&DXE+E}6`j+B7TdCDC006JxYOJzRmfOz%8@F()Hfq*&Ng|UxMm3QLwK+)FtLT2 znte!fvxpFEg2`XLS~2n;u_VcpVzR2AYoY*;HNb&Hep)1`hI!S>;+FWq>?LwqhLPDD zb?pk?X5XD0#b(v}Soq_XM?XLldsm`@JD?wFZA^vGvMs`1o+MvqL!-2VAMx}~ZV1)M zn%m+{Nh964U?X>!Z`ghz3X^whqY!+5;R|)X5kYR=qpn}O){MO_8foTeEwfk#J+KiP z-OLB3YgX+Y^J%vaqj4`UV1M%J1N>5wf!O?kjWO3PHLoc6RBPCq-A+D^#_e1q~oT{p`0xJ5*z-K zrsEj)itKQ-d}k&{yb`-8zn!IPYu3!~nvJTXX#^Er*0|-w>pJtewy`-m=P#L;HaQ;R zgYJbz`Zlg;!@FPeAC!mr9<1Df?&nKar|r2le>1tPwaw`DTI4>u+DVVWiv}<1IF9PE zrd3pZ^X0o|K&J8IY=+ARlQs9tCsDl|tc?K#4dgxv++Ni;a@W2nP}?fA1hp~0M2R2C zzg(RK{kPB0fZl_r+Qtzp-%Lb*lAo3PMWh~*{e3mYXW!oi>z=YC1IrM{ur#2p zZ!D0^QsRd8;>YTFEdV~b=3d5wVD!bxjrO(5@Oc?_n0)!19bzL>(bV**O1G^QhiGg$ z0o_S{miZvfF8!6-+b8{R<<{7CqM^|zoxG)4(T#W!`DJnhgF9`xTaTTJLv{$FwX$Y4 z_XOJKzK)mh<@0H?kD-swg)Sxbf-H1BdZOh~lZi;Rk@5*V z5&PjgkLnng_&g-}*lXe}a{cdL8Wlf5+%Z2$rBSs6Qc5~2XEnY?3M0Qm&qLO)lcrKP zK!GjK4`#X1;9rgstT667Z+vE96a<8C1O#vL`fM6*fam*uHCKB@)`fdf zBc%?HrpGTq-oNH zz8r{AL18_dY|I36A;_iLX+C%QGpP`42wiK_5D>PvjqwZ)Q_T}HGa0iM)sTHQDQSe7 z>H?`ofM?Z@eX=F4(*eU+yYxggUW;sdcH1}7fSehj?OzsJ0YSiq>=n9Avou(PpxCS) zFjZD>Z>e%Ce@w1mB-Ad#7zW$2cl;`(oGnG!`DCP4n{q#zJX`MHI0p{RwS8Z1|6wi$fk{@Dk*$lhF45Qn+FghNl1n6wJ zTIElFEjzoLG`oHFCEoZQ-hf>tl@{Miivm1ORQ($Viv5R4Cm-0y`iAgT+kwP*v}20H+W3HT9a!w9 z%SA5{X3$GXGadoJa?EM^SW5zWWw)`kIJJ#S&?^6jUd-!<1Pk4gX{ptf3KyF`o-0~^SM51r{G&;jmA(;dX(~Y);^l^7cru0)5!A-Q& z+CQTF#a8Ah>7xKB@`8z*5K<6Sg7h+?r*|bETMWcuS?IRJ9GJ3EvHOmbaUmUv9s?B; z7*9J-4bwWcZbT)r6Tni2xuEe89+ZzIZ^1m^O3j#*ttjxxtJm;^*CyS52;!V!;BBWh zu%^er_kJO6Dn19r&KTQKpBCE@0&SO}sU{<&N;3=lXcZF_GE;=hUIm0(wqJTSEq8uO z2DXGo^&QBh6A~fO(8m0*g(KTin;ZK8Hx3k$93)cVo0Y}P5PT0Xik3bvxC<#PCzoaJ z!4@iKC4caDOer|iB+(p<^wgCsCW2cNWxpimnf$Hnz@zow$}TZr%A|n~l8ZHtr+kb1 z&nASiey_xHDsv6z(8I${54v=_7U^4UKf&@4LBK(qna<=pd*~0L%|HS+#2^d>p_zPF zF&qn-F#Z-EBy-8a0Sa=us#rmr=s6h?u_R*XYzzu(VajPOo7|++T80D(PIn9^|K7t8 zQaE5u;xd|!9x`Kw5)I5yKug|D@(~R^#ooR@|M`=X9s~Aku zApYL)=hjmO66z(6b5uM2I!Ih{Gj|*lzPnF`fK5jEX?|kNfCybWA}%q`mNEnjV1q9R zBwLY+yGj}m(*VCua0|*4>xDg*fEx zH{hRE&Bm|LKb~p(bQ-iK1s9Z?7BpfS)Cj;esK$kEn;9cexYrcJ{BFN1C{em`*-3u1 ziy&sDl6mSUGl0^nl;7i-MrB1I?n>Um>F{aKBZ!FNhIFRG2oiUel4rSiCUat;8iLyQFff@35p2|mT$^1jK@DfF7PAK?wU z)CRAMy`Mnq}rcDMAYp$QF` z%^-hw*w#vI%kl2Du_RNm?%c~R3or9&)byxAw&&{mt?1S%I(Dv(=M4LQY+J!n;z&Bz>~)l^ru`lDOxq7DD6TZcb_g1Bqq=y=0C_ZpRGnr?vP zBJXq`_M=R}?10wKYm&^aBl!{*U3u)QdIjF@Pz~0+f7uhdu-K0rG7fN4`8@~Ze2BG< zL>i!Ct?<{T-$+k)&eCSdc71u3ZflR_wF#*Q&SpZS_q(?_&_W2*+)OA0!dKi`bTy#f zgZCwT+b?VuKKAJdjcPN)p@?u+ut3?$0*u^p`^fk>nrqSbqs5kR4!t6{oQzs`P?>@gQIzNK+bZJn1Ea;p{&#dMmQn|AJA$^Mvo`6}j>-51x8Gtc!vKn!!& zE{^YqB`-N>1SKT}r)Z8$)kM6j#N^sPrGdo#Xw)UaZ++m;co23~;yyWi+^%MnZFE!% z+Z;;<2eit`J2s5QDgJ0NmiKC_)KrqMcQI6&+4=aK`c*RT0nOWGvsqZw`4<;@KT;FJ z%t;90c1QAeU$39JS0ZOraRd#GrP7$wv83fL+F#)X7GK6GzMe5$xi8@d2-J}@bqwiR zyb&YIBrf)qw&e?}O)dP9O{=^Uq++0CGifI|GA%{>gVy3aeH24P36^F&h&H2y7jmNj zmY|K|-Q^4qWq}mS(Xps;XwrlGl4(wV=#2)J{5?tVW25s#ON$@c4!(lGL8;7F$CBcj zPIwmB>g~?~T@mC)CqE}IdQ@FI{!L!?K17F{SzQEA39JNXmJS8TQC5VuH#p)XZIic- zXq$!|A`v9^OTK)ijUW=0_iw-(m-NR?)bhUMgI8Ibg0;y`fhNYe`;t!+NVQFd1h2S9 zp|a4_ZFpu=NWS*+}TRDKx24g{JQWh-^cL)%~ewuZbv4(W+Wl7i9((IH1~ zoj;hk;gSh)C*Vx(*e^eqQ-QwBkgf;P3py{qLxw?fb;bD-Q(CnATC6BIxRobhP|PIv zM+cP|17@|O=5clT(P6`_8|s_AJIf1WLfM=HKGJS)MiJ=;1#~bmBm~GL@8x~j>KSiW z0evrTmu&rA$?X>a$24jngUCbgmxF7Oj;I|eRH7eNXHv+Q!-GPy;45{lBp7M6jX!|Y z1h-oK>3>f_AL&ibZ_!)Cw0=9L<>TngV4&@gO|V1*p3L9_TJVe#1(b-O`37%qVV+MI zg;$%hSsCgqS*!HjaSO?okF&RT&5sEHbYcM3wLj$Cv)?tpOD^r3>ZrR;^Y58P^Xrq+ zCS^UyE6v|7Ht9k0i#5m-^c0O%-(k5B7Y{8tH~H5UEX`P#E%IMsJZ6mY1nV}F4V6;xZd)P2xXieijMiHjA z5lZ4=c%hJ-yq^&~u_R^_Ko@$`QcOgZEhETG9eukwE2Zi%y<>Q@%p zVH${+k`v@2Ab**il2;%y$zby~wmdX?!rb-tQeZvaO%5o10dc3+23}x+wg|l+oJ_uZG<{jx#!veF`kQ!ROemzk&uFf1dNkT-{|x#d1kDUH zZC+pzcjZJhnna35E7LM>Mz!hl$>022?B*KpM)Q-k=cWd|2{JO#_vaqQ?(=iGbxsjh zn%a2B@I|F`wR93))h07fDb^5;fP_kV8I#Bmmd+8Uo&3_IP67f|sYG9eB`e;79|xf) z5rC26_40_N*6r+H_;$Oygcu_6_a_aee_gBF>vlsVMON|L{&y^#!r9#Bm9Tx`~&(Pb1A z+$hky9M^cr_NoTKc`-Jg{1Xx@Qlr`hMlhp6Jo;8f3FmjOE$@HFn%}(jd%K&Vp4(P& z#{RY6_lk=5_Ii6M zYD)_yG>N6tVuk*}0*X+%h?#~z1+o7wH1F@X_Bm%JX$n>Ge&72%U!Est_W!;1-fQo@ z*4k^YZSre%mW!KTt1~2Seyz^Cp**Wheyz@X#m%qPxsKn5dYJ|?4S=6A`w_%HWlCh{ zdiYc38YGd>J|@PB7*-}@tj_!KRVKeyC$BRrlV7WIi@5oF69>vD7YE7+(ZMpN($TBIG4NiLdG7=)1ATR9 zqu<)ZO~**QiXbZ~nw~R_dP~ z{j)~@+@*i+#*dZUjn3x%h-V>BJ6wA;l-AZ4A>8amZR!Y6yato11~?nW1gV4k0TnMA z_+2h$PCY0TW5ZEAU>gmEbNl%I8;%V9k6LyQoOre=xrP*LL=+%vkgv&F7=YR;4Bb`j zF;?eOrENiwlM_|c>4@3z8LQ;=dV4+b0QcZfIhmeCXeiz-JRBb=hsJv(LieYb#gUeuQ{&MyRiI)&^OLBYvvIt6jg8{zNgTq7?tLB#x?`_5Nc@1X=+H-SrtN*9_3Ft4dU+=Om9T>H@gFa}!2^879pI84qC1%f150;I67XU7H@>%^d? z@u3bc0l<$iR+M`eu^~ELo{!ssTMWRHRCe?n0nI53`*L1KcDlp0SCt!y#tX41fG9;5 zA(BpF9GzCJ&+2K$atD*Oe7=mx%C?ju2fRdDdSAOhyhL7lAJtwWF}**~UKUU9676Lb z^tP2FZyzP;e8%$9v*6n#3r26KBjEErNI3rZLwlptZT}2Fk#DKtFZ!V#eH|S>pZ8)@ z2{Qq(M(`I$0zY)wYl24ND&$9})o?hil1_7P+kQxux7&D23=p6Li!f<0Gy^YAM9-7# zEO2^jM#z7N9XyhJ2GC(ZYv2p3L?5fc62ScCNbJsBfftJJ=1fNPRpJZK>a0y1dgO_i zhmGXmY|J)e_2&Uz#bInei-yn9_BrC){px6Z&<~xe@M7g}uLQy`!d_KpJdh~fg0k#L zt_$}FI+JxkwHjx;V|SnSc9+@UesQL|!QE2=h%x+VU5#aPqeB}bIFZ5_!IJw4Y-QLV z#QUBBPUYG*FU;7e}CJ9(1yLn z=0Kf)FYt2ZeVF`NyR(rX@0+zcFJXLUhyH~2x~sFvi&dG``E%OquFlJ~*Ik{DU4X>S z4&8Ph7G_zeu`oAGMFb=Sz$8ALdMUg%_6GtYtMP;VaH`Zh?cNvY^>n=bdji%olC^)+ z{abG&6?^qQp1q5sRmnl_%RmioClO=i|Iq&3Bl|b#`#)#@PH)39-*cMN(0r5AMP{3A zQ%a0kh~s$9yh#Om=3S3pJ@evlxd{L6&Af;+^GK?m{>+nH%<<>Xyo~hZ1dYUD9 z{EID&1!%;}sR7P1K{B{yI&H(mE?}lHvL~()o=U5`!ESToa9?t<8Pp*Xm zGY=s^eT*sFzZ*MC6PjPZQc=EB-dNl)>~Fpf6?O;}o$}Hv;Meb2W>6E90J)gtF4A~0 zxC(w^wfSz^V-ca2wOY5fD0>^?Rt);e!OGDJhSheu zN!i+TlhQG}ay!V6_!jO{c;xeZY#@%%(eeXK^K-cf=nWkRqFb(9K6%BqUbsH;Qt)cGb;a%MQ}l&97w_h?`%_E)qAtmR%xlel5FH z-27U0nYj4{Jt}T~EjuJ`el2^dxcRm08RF*GvdN;VZedjIN^$dR*|WsWua&Ikw;i(I z9&sh>8Ml^S>&AfUiHakrdK$!0pn4XGqe%5MilapJG>M~B^)!p4O!c(TA<|&gB{E@= z2CJ?z&QVij!d)U0HYp8OUHn=i4OU%uQz&cRi?8b97euVMMffWsUezUnUJ>!CE)n#K zh*x!Ol=LF#?Giz+DT3ZE5%db)t1eD&OT@>ji$Y|}f+ZjDcMCYikre+ z)g>Zc+*=GXTEugm{8}PkQk^3HF}cvFPJS(u>x}B;*D|@xs7`*-QR3#;GP%g8PJS_1 z;^x;fxx}bWel4>RwWv;h^-iNYxnNu7Qv|D%-_i4kJiO9e7xZn!Q--OG8AiTcndR`L zZ+#OxUqaRcOh~Q{vK8@qhHhNevXFj(2Xt%n8nRNaAyMpI8U86d@n$C0lHhdSLAdQE zf-AItN*auT<#7WV$3NIq#8Wi544a4b3gnS!LM&EY9XUQ9eth^zuRD%%qy&3G(UD(^ z9A^miH)0oPTCtsJxXoHySg6Q!%$-_-a}Bl$ZWWFk=l?!=4qJ4xJm(AwSFlxr0%^j) zQTkD*X5p`j1#KQWU2C!`pc1s^7v9#H``G;|d>7MHDv30qMD=)lM)evHy= zvmP6RQ%Z|dHiZvGfRZ*Pf+VIC>_&3X14FMKIx!+FNMb1=Lp3RxC9KyawLH?P28 zSd3Mq1+_pfM>m(9Vk9E4H-yGU)MM$dB86tnzDPBG?D1qloC)oo0%QasSyBmC`oYr% z)Jv&HQ0PiGH$+ewX@{hOypgHwh#@S2Qwtb|jC6zPv~=SF@ayCASm_84VKtAn6w-`6 zK*<_wIc;M^J(@NOnifr|x0X6|t)^)0pZLlF?~N@3uM}48Z=Xy|m<0xyD2IEF0gZ4N%`5Nga1D%Cy$+lImk6NBO@Q7j69p?FcQ1a zFpuvr9~PgSO)Ut%t6S3p7?yE6@Lcc-#_De)I&;ootmOL$r#x%Ga^;>iJm#J?=!1sg zhdr+8I*)6r1-f}$(=_ooT+JJp)M+W8mqR}V^3bDJLfy^bpA5_etj3w zXzYId!dnOwYHKUT&NqtfwRv!2EyR)hCazl8xWZUMaTi`6L15*rUv?%)C)np2j2|yD z*7Re+3`6ln6b!639t6}#j=7TK(6SP>o2j?QPZS|{jbT239atSrfYe@3N`ZXaQ-CAi zNZc=SdmagK!(=Jkn~e>F)+P$`{X4kuqp)0)Y62O73B(x9KnXx08VBBPOY%S;Dn+r) z$w3PQ+B^-)HQ7$51UoQDa$zLd!a}x>F2sLA=mR-i;x293JfRuCn1M_&Hq3l%$0=?u zIxO8v#VL_uSV_)U02rL;w9W=uq^aNlouH6b40ezzA=NST*~d?eD51*Jcl_7Mg-pm4 z(t!e5JqlrV2wl8FN~I7I_~|RgDFn@terENVLYN(pf4y+0B*OC z4nXBXg6x3AD`b@vLR3v#;}n7_-9mhsLYN(p07Z14TqA{WDM(*AP9aF`7Se&HxsV_` zAn^(bNFiKY(*O0llbeHdZXv!*A*rCA~{3SbtELZx@aY{e|ZV4UaFPx!asElk} zvXgsD*DyOylQ{tB0xSVdI29Wz{sm~`uRe!3vKadKuF;|0M0ls?aGuk>BT45lNF;w! z2+&N@^YW3*_dI7jowTONBOxEL(x`>xJV2q0QOxjGCq@v2u(EA=mn_Hem9JE8&ABa;3 z&trJ44qt?D!3KoC49$S_c{)7G^c-M>|BB&9ehY@-I8(FN5xSM3dlBmND0?#-M6V|u za#Uo#(hTniF4KdO#_PdGma4mfe4q53(~INxn?uV=ze#V628DB2xukPC2c?hCYH%q* z>qzs9fv98=s4i~-gc#pT0JEqy)&b>@_*$GssxH@f$Ej<1-arIoTDF zO>iso5_k+ojb<>is$zOHwuWp)H|iRPtym2BvCNaLSd0`YvlUZhWMsK79R%6x5CVz8R4}^OZG9hI)c)^;f6oMgTF7kp`OKKq<(4k(iDZxTSq|7ES`0EnPl@ow8d%-s& zIAyjt{`42%%|5kCKf(#UAedf!K#+o5vgUakF{H#t4DQh7DInt$)EfOWdD@$vKY{AV z%{rWIl00qtbF37M$oP1IN~oD2_b~nzEa~fP>i-x^nm}#i;LelWzhmGJA4`7$DgIpc zzUX%tk@MM*F`HZVZomabujSkryxm|UM$_31c9D!5Q-VxUkRu#?&Q@nP;Km@kL7QZk z-C)@`*-?|bnQ(`20l;pZy+zNILS&0hj8jPV7Mpi|$4tndzGL;m|WPsnah&7?YX$ z=^f&A7l`zF@w$^Y{j7N1DV`pL7kEqNs}bEg?!GEZHFa^YGqUTsYq*;l`@mhMEpInC zq<5q+O0IkNcY`}o`uMZlTZ6L~X?KCf%s8FhV5Qy-b{ea$fPTJR@?kVrc6RO@Zdv12 z#LeWS1lSEIv&Eu6dN)9!OfS2^0Ny->%KJDo`Y;Jn&glK=A5!(+p^^}a%t9p%4`9*` z>)lr<0ALaK`h5)lHo`Rpz?p{7K8D`H)c^mPxu*s2f5(~m-Jk}XnOf&zSs;X^MAi~S zoyM8@mtD`X3_LU%_o3tB<_7X2y*T zPlBF^_#dS;fh75HN5#1XTLhh?LPbq=*{9W$6+7Xpld)=nrd~@ZT+wg7yzGJ= z4s7T4JCdBi0^UhZBlku|$!VkrN7Tb2Afrj&$UA5dyrS6@!w`Qmr&FtchDL724L+s- z5{@R~u?Y=*nJK!EB7UsMFn{)zQ1hY;E7B|MxMa*cwIxcaI0|S+6eJ>WhAWvX=&~|G zrjvmmE30Br>Gy+g1NMY*;YRUb6)466$q};a+1;qBz^h*bT*QKHNR1TWvi3BE!s$1E z>6Md%HlQ3KTLgBuys_n++zzQ$WNzi<0DxSu;P-=p~4$Dzt05?Eh%ubPhev}s(4BWFFmEjM< zX}U$GpMuxDe5eo4KhG6v1T{^H5KY+Iz zKmDH-=Mp%}0WCsfaPkk%hD?IGOoEzBf~lDVrI`dJnFRMZ2{52FXw2R4vZFF-S7y?- zx@mhuEjnFeCf%Y;y0DvWO{f}9sMJt(ArYEIPi+gdicrN&c*=DvX28imJMc(3ex}zp zr9@?gVJT5Gp-ahq#Vs9h?mJ-11xuy1U$owfXuMSPr$obr8B(I(qFw7R;V;9e)uLS+ zJr^}vbXb^^27f8D#&gwqu88NV_gqoWMSUFpVe4qb65W^zOrSU3ABZ0=59r;VYsXZraHz~yb~y}C81}{skPXxr=BNvx-k*i`;x2$iT-Q4zB)`x{K@B*5 zT=fsgixsRHUZ2*xLqS+S?tvc*PP2u3nM<2dK%Hg2fYP}zLk*p0_VpO!9T-^X0xn;S z6cM#!+EKeiMi`nt(-$_WJ=2a39Lt@yeNj{Nd8WN) z7yPmuHBUPVONws26b zRdnJwt>xcP=obQC}SxcMf3{5B6uc$k~Q zuVr&&tgbbvfHX$MPN)c$Psc^I_~68Wp zxpsR_(UvBpbX0lNao+hJP)Cm(xZ%#mz1tDgj_j2#m|`Seu4Lm&jKt&O$TJe#;eY}{4ip$=`N7=@v@WyU z_y?yac^O(SF;EzQ8>B}wu%pG_Cj%zUO_|;V+o5buK(&ee1o>&=P24|O++%FUwwbv@ zo!J-dc_Zc_!`uk^(m7}ak?^nZEe63538zF?j@^J0RLmOVj`uqL!#|J<*CHsZ&**M+z(I-vI%dfAt*J zCmaI_FgXweB63K1C9wg_0d|cJB*sAVE*Gw%VQ=k5fI4Dq7|7L;#)e}sJIK(i3tPOF ztS@x|QK&E;b#7?k+SWs}P-1NmWv|p_H|V(8I>1;p-H!zN3KyU3)aC*K6<@gt#QV#U zlXCzxhZLX<6@kFY+*sy&y9K-+tgVrO_|q#ZCYK#J40SB#w@co_7yUR|S9?lAMfgj!wH zxN_?d+Eq7!kkKHk^Smn5@IA%n#1}uniN=M8LnXH`z$ppGTxQlrnZ{E=ieMIDYa-%el<6ea(mCqJ)LI5WZxV4_ zy8l=!Ud{n}cWN)^0=?hWUd{=6+q9Qe(7Wks$;)c!{RX|+H>NmUsGyVnI3iYtIBmFO zZ=qK!JNAZ3;K|%}CRE;S=XyZOu5RL}43B$Xs-E|q>w`w(h6_<9x)#0GH2S{tHWUfm zIsN<2ROyRk?mII-?>oQqeJNh(A;;C=-IrP)>Od2QOQ`prx$hj|edjCDA&j(ILeZ12 zJnsP$->{5Nl{9!)o|$dwPF#7`rD9}-kKU_Kolz*lnT*jZ+q)G{V);(E-Xup zKoz!+H$SI2%9hIqz|tD70NtlR}24Lp-AVjYUN~+#wOutvwpvZe(}Vkuh(A={eddgS&G8e8*?tvBQ-xh0{Jav>sl08z;Dk=#UbBb+K( zgDl3@B4cYfMXt+NphWQ0G#9y;p72Xjdlj%jAvppjGVQiY zdd6)asqpMLHc2Jf7Ar~8JUgyP;^gK>l7zV(K$%Wg@D7OA6}$w3HaTnHyVn(uZDv=L zv-#%md)O6WanBKVhqz3j@}2@BNUIi zt$k@!YdK-C*1q#psN;yQN$wimTDixQl)F30Lz&h-A+3!di#PsLv&VnN-)j6}>JhC4 z${UG~0KYk^V3YxkMt)B9(`v0V@lRuH^`N3>IKo+YkUdY><-`M({L6b0wvMDb!#Un8 z`djs4_eS<2mj}cAU$}WE7L5|$pMc}(UQfh;CpZxRQvLq5AVk1tbkd6*3Y${J-VA#M z;-dizTLe+-k#Zd_Fv^`In6>#QRFE9RQG+%=04lg%$vTX*8hx3Xvrp8`m$E&x}lxENL@ zt^&Bq#Z?4XNL(dwO%+!uTr=njlN^~zm&iJt>O`)*GPI6WvdBuw#A;@Vi(%E`Vl`oL zv6>ojv6?z@v6={7QcXQwCKv3{)%3d6L?sieX%H8yStKr2(?4oxLD1-;$k)H#KmgX(;o3!)RI{5d>JDj2fe)`I@`&b`H)2XFZwT#Ta7`Y= zO5cU8bLa;!o?Eps)C#`XNIW1oFBW_-AJ)<5&4>S;nGc&c%1l_SD(7P2mjG-4m1}Zd zs3L@vB1F{(;3^Xrjj)!Bi%%zn#Km+|#Z>~=3~`mhHB($=dMfDJjm>%*ELH`quM#On z*EdV@u)b<>vA(dlSYM5}SYMsESYJe3tgl{NsE>2Pt#4z9^TBCf6e&j6*C2UV-y(6b zzD9Aez9w<8zGiW;z7}z@zE*LeJ`zT5efr5hr+qP`7+v2I$;0~E#l`wM#Krm&;$nT> z;$nR(#l`x1#D)4eOWgW4iXB#`eQS_nbbWV89@claxLDsk;$nUGii`EF6Bp}SFD}-1 zzqn8zWw362+M=n`zKuvRy1p%vhxPS}i}m%3i}h_27wg+0F4nh8T&!=mxXO4FVH-l9|pnHU9q8D_at&03_=dj}XnEdc{Lp z88JJ=BP4Sov`ajslo7LAJfxK2In{2L2t6aoNE;y80r8M7faeAA%+#JC@yMlVa8crs zThrj8#3NUx!L5B8S;2a%i6|flkD5=j%LU@%BZx)fDuAm*T(s?5DlXdhFB4ZOT;<}T zG4>v8^Nu}DG%8MyT%Jaw#3Q$-v4x9Au1_aI_4hCt`E3-?ARhAD@GKIK+@J<4EgtgQ zh-nhf{o2zk9a zwT%ca6;~5nW#Zz)p5@|dfh#1gR=B2$i;p^zw@~R&mr-UpGKZH#6x}>o*m*LKMl_=@sOW}XSaCdtOmU<9`e(Oc}hHT-5RJQ z9=UIgj{X4>ENrnBG{IUaPf#E_0N6?<3_R81ksH?#Ac%*miioKZ50xL`sS^*?DdCBT zhYFhT)Qd;1T_-|O@yNYvU>2%YaV(`C=5YMaWD5}Pg$jZ?La@DMIx zN+Ai2AM)SSzhyGHSX%xk4^GL7a%KFES1^Hs7FA13prA$J%ti}Zc*LRwEvlB7KtYSD z&AM#=njdv0WoYGu4b74(_HN4rIo!sHXZeR^J<{!yJZz%AuP+5<8ma>&&9cW+BC07z z8*R{(kQ}5W`qYi~JB_BCC#%sS_DKr*h=o=Ue<=b|QVAML5s;FWz(Wy`5_u3j6agtY zUWA7tAf@dEpy5PNui?aFui^A8{}AslI_)N6OS>7P1e~mPOQ1ln-Zz4c8ga^0NfN%;m{Zb!$ScT)->&*fC^XrwTA*KCFi0@Mgf&FWp>G# zSmrcLn|0xNn30%R;2|LwiZds`>st1}>5=d+?$y3B?nZWC6PpCXd1atnQgAL#g>&Ti ztpi40;L_%9E!fjL>K@5J3fp9?`Zky$byTjhf%l5wrFWc+(U5l?uC?KEo7!%y;aQHH zG|IJp$ebFAPzBP&ESzjv3tc;WyO*8G04a=FA?^kH<|xc1dA4tvVSG_@)YyP0ZgT+w zQnhPCi0E@X7VR7$C14@wW&;C^!yCxZ7eHXctz8t)7OVB44njbkG|VPo%me&_(~pRf z*rnS4_IhFw(G#opTL2S)M4=}}dyn;PTO27iECTgW`2a_#T6YB`|B^HLqDnhJrjZe8 zjn-kZHc?{%f&jKs?%VC73S<)+MYgvG;29g><|oDu&>DK+jA5U9hp6L4i;%bp2OA(& z(CjFh{kwCd**vg5ylfFv;u(C*4mu1@fHu`vVZhOJFpuG{amx_dJFUx%t z55{3Q&{(&bS}{+VY#7wKrFrZRD@pYWz}kSZTcj1X9C+V6+kuz*frMA<4ayh+UPxk2 ze|$W6aU0ZwSC0?NrL77;+JFIBq#Wo7m(^E&DK^-VSU#tek@)$0(VIAgr;*O)D*G-D z#OfbC3tcaqcKd--EmfO#OJD?nID(&w^ha}-p9K|xVl9>MxADq|*47xRI6PGLpD?Jf z5Vp2i7-#4$G=qr4{po$XIe|CyF=Be(E_k%+0S3IlTH2yuH4?X|racaSaAbG-Bgn^d z4$%=1=Y>qgskqR24IuG4+ug%p)$o^HPo z=(Ggb6T^TOU=|0R^VTfQ9(^-OFYHu7YCFdfa>WW=baK`$A+8XHIi=5$(`8^~wqxD( zJq+T2Vt&zw!f&LAa*w(I4xu4f0seZu@zJ_$>$>ves^Rf{U)#BK+bIk`dDqQxeh~WY+aHA0rfk8jFm2ce;N|^)&g6Di}_fM zF8zxRFraMU!pvhGlwLMeNKk75s#Cs(i~u`HGjdhkyMiGiA7!GH2uJDqOMx2qfN9CU za3v`N?_6m0O_deaNc@2pSfNGN)*s(!br*7Vv0;RuhADWc@I^FiJw*G7Xj4}BIRB*Y4Y0yDb zp%HHaK>lU$+&MSQHSZSWa!$SoC8$7tAxlz5}TC^XmNR_Zg{c z5AXh_eU?w?K8g+Avu^Ve?&!JeWcoQ?*rQE(FYaU8R|Ql;R~qqAG);mebp-Rb{Z#Pp7xG&g{pyP%ov) zvFtB4_Muv1UWPGtbZHhA9eE1k?hYSDF^$J!Kx*UI16;k&dXN`Bh33KBs?RbVM$Vw= zAtX7;6g-qz{uRMupCuxu;9HptC3fRy_zYw99r*R^vqVnA4t&EncHmoS{ax(9H^D{L zoyB7bi!6P=@ZYYfNYGy=*@KT}*@KUYJ^0>G2eLy4G#aBF?|L*hig9Bnu=mohL+Qn} zc0*fO=+8NPh0p8HE5xU*-DpE>QEVA2rC4+>3tHitW2+zE9NXLW>5ovrsruBh8}v8n zS9GY;x2M~$BuPQOkL_0@QS>Kt82dKUukc3G2hq1s`HoGZimKW81X7tZxry}~<_+{= z$Kv_r|9(UAw`ld*K5B$>PF*G$NX}R6O(*aQ7+wx&^%;pz@p3Ru88KR-a|eP(Uu5Ae z(?AIQ3B$v@q@wvppiTq0LappcQ^bhJmQTGb8X2c1sIfuwisYw??CKrhpD(1w)b5k` zvc%5Q_O*1OUiW=l<9v%N_B`Oj9;g&-Xd+tv@Tb7Q0np27M$cKgajA7wUIXrMk& za=Be8;tp%2DCKAk9sg^_)?$_9s%&ii1k`T0YgnFY4$^K!>H45v(mKkxT0e(b(99*M zj8v&;>uLoT!~7)S6HB=IMFmTqQgHQeX&9}KPyYZ1ASID!g!Gie>lltgFAhtv8pC(8 z8ZQF5+8XAyU?ra33``><7t?acgkmxp4Rgf#R+D`XQea z0zJm`P~!#WgQ=G{gp3U-Fw0T@fb+Nlj#QDzS`fgZ>FDFOI)b4c#_D1)8JLnCNTLI0 z*9MK%|7{3dl3cHaXmbS6G->@q)Ym{V@HOPt`lw4W_Q1s6EQkUs(P6jP&!aVKKy@Owv_@Q+d@H3}2{Uz>pZzz1|y z(_g8QDyx^PlBzi(NKWq5M*BSz{`v_XAc&)Q5yMvBuTA+!#;T+izl}a>{a>h$DyHOI z87ijRtK4iM_yY>QvpVV^5{vvrp3um)=8wrnQIBQIiyC^yU`lfWawarP!uXB%uEy1f z(Bc7F_y0J2d{?8j)SWno&qTaKFFE%oxyNMbbc>xMz0lC8q$Z{?nF=^F^n`MgL+b(X zxD!e;g3@w|hs8%umXnSB*ZRn+hfM%vA*FYA~ zkzIhcOZh=O%Y2Gy2SjlgNNz%J^Xi7(y9WcQ`+@sZkTAPFhD$2m{uae9tOmd2Tz%J; z|2c6u;T>uLvzHw;su+EF^zDn`3LwQmsf4BJwQ*E2&UKl$g@!AK0}Xo&jp9l>su=bx z7Rt9RhAWO!4ABs?oYy)|$7=uR&T&^mbdI37E{E3>bSLXk9?$y!=yKepG%nirn0ooU zF=8wYnCF(}vu2A&wTvlT z4FA(iE~kiW4DO>4Zb`6Y@a4xLy~0_&Q(F47@Kes-Lg^fkL4?5Ri+_<}#yqC12!U8$ z>#&0#8$uI77rGG0lmI0~%=89NF8zK8LJ=oZ2{Um=WY0Qem!NYt$;C{XAaF=ZoQWWD zgs&Hn1lxDQAuplsk3HWbCr@M%lj-|FC8N>^AYF%R!Q2Q~sRu0~#Yl{TG@JH8;wJQC zEd6Wd22q>dvJ)LLG?csc#0Xy>FcJ&T0-SBQJ||ZqvD)KR1i%?h=O86n*KE71?vC0( zF?xn|ov6L;j`~v)ba>etLqkKWe^2j5*|fQZPNo-+5;GPn?`9BtE^`{iyYN5_5QFF- zQu*>IqQ2xIjA;v&Ku~YaBFgT-IADL$ys6O*YXii&sBo!}$~O72s&xQKt5U|w_4uvW zS+Q3};c@g~0|Go=^e^R`n#SQr8ytRAuXa_W0<&1sOK}hGl=d+}rGg*5gRD0Arh4H= zK{WFC$1o@3wy4K=8i^45$`Rfh=GpXV`?SBdVOiW^tiZr)Uen<}rPIU$I9%M?yU)Y9 z3#WKir=gG8W8^d4eu9=LmV)da1NW}r2bd9g$L-1Xnp0Xdhn7?7$bm-Ye_^7C$&EuAWMBu@RFoAB?a;xo-D>@xRUC1biZ7g*<=tNeinPwu(O zFT~@Vt85UDbFT8Tc${;UJ@D}Krlx=bj zq*P)PWF#nwYGT|)vP`7weF4i>5m1Eds!zd6x}L{a?E+Z7O4f{PRPOVXyLdMj(+w$j z#k{q(lw2P-GEghYdr%~7XZs)JTH;vG26bswegjKG6Vl$a-(szswqZQ&Z}`fQ9M-eb zg;jgRdUg|DY;7{G+oMfqD?AUgKR(EZVg4Pt+?Qdddj_;y#~RR%WL}2B%U@joFoj_L zg}iCj(UN9m)5jh`E3}F=S`VFTa?WH)sOGdum}f}-MCa+<(O<(;!z?XXu9tDq*6yP~ z98kQw`fJqGS{E?P?}3O`19*uVgH9T#-l%<49XD$Bdum)%@X81mQYN`~taqeJ-LopK z|7HJmCsVl3YCA_$a?FEEtwWcZJSSs~{7c^h`zbDtr&ohS(wB=L#zMoV3%NN5z*kcd zM7i2Wy<&#ri&tD#f(V6+&fmxKv0@tyb?A3psGXsoFDFGY-s=(#w1xZ5Gq6HT=JI(( zUc@EwhWQYIVlq$`=$;V~;R-I$t^skpmh0WaMHb3DBQEH?j*CIDOVFO6e^2HTE;lub zoj~CszfhXqZCp-h7K{W9EL?~qZRVfahTV)V2%#$HE-t}DIV{hP7V$M<6x-yi44Eo% znu25`Xyhg_OZBRBDDX^GIKcPH_g*_S#EO1tIY!4W<5#Q`pfVcKr(DdrtE^$9K=I-N z?hVhNKXdVPFFe`LE@l|R16VG}7=8?$Yu4iI5hJ1l&+9H ziw_FD3j&7>4qD)**R=f@)-cMEf@P+9N9H2S@=0~aFoyQw$cKR=6>auu4_8*`ji#Q6J(`l5)8)}3^$8aKP zeh%vcrhstn9^pS8)9ell<`HKckTJtsvJ7%B@5H0JY)zGOIXkN2Qvuq8z3=m^ix=OLymyv4vDWqTTzIr#-LAA*KcwsV5S8}N(Pao-(UWnLO3a$bEknw_{@2Ovf5wTDABMy8s z;!1Q}lY*VK0>)j&IIetp32~NekC%6r6H>a$T~3@y>#UcpT=#&QL{V?`$xiNJ<5F7L z1X1K{70jPy44gZ~SYzPflZ}CM*`YNF-eTa=A!}i)OpmP952N6Lo6cjsnj#(Fv?(FS zMt*7o#(Mf>J*(r0BsnQjYvyGgC*i3c*XaPNqxU)hw>E`cEgcuhyrw8%ph(ax-upUX zZoU0SkBK8E-JdO?2LH(vqJ**nP087&{q+rBROO~uL zV+CHU)si%)c-L8x+zrPaa;EWyyp8jP8AuCrKLtf_lIim7QI;Brju>U^lawoELo(WQ z`8h0ImWy%UK3H=dumF8&1GTRO1vlvA221k!uh0@Pb?eeS)a4sf2*mizS%91+nLK@-l_2S&)GQ6A+N--a;WyewmPnVdbIcPKE?*rw2)<5YFOk z!^(F`A>@41YsM*rYm(EPHIWP?bpnYd6adKrDTKUqIy_DxfY>dhBvVL<6v9rpqvJdXiW}18MAl!TeOrLOIW{-IX><?$#m$%4 z=|s(8)I1%{(WBECe1GGHyl8?n2`w5J55bCFgB1w<;{2OpnDPS_Naz zQPefgLiZ?kaS*BXF!p>op~-p(I{jZz`|-@vg^&=2wXCFA%7S!NuUygeJwHXqkCIQg zq6z)L7Z=0^Pd?G0+KeS;`jAx9Be|QX zLpWA3z}R}WmP8m^KQ+$5KZ%_5bsJHS=p|4Q_|MZz=#@IdDCQJ;39eNL$8x|*u^f>8 z2QFuxKH5aIAtRlz14%Z@Ray;-aS_>PV;K4+_!qicn~SQgPOl~!yc4xajkdIn;{e?} zR-kL-`Zt~q9sOKGB1E>#Mp zOA8C9OTeZ-f`(h0PTM$2!P;?EOvE^f6E_wlF^=NI@v^4|H_JGR6UXbG z=ss!KD+tjTU07F5*DkS{JvVtbM$FiHxfsl$ru-(d5m3#s>EZ}1+t=L(KjXQbe&<5)MAcSuMq z4gH8I{zOy;4LJTz1Gp*X(z^|bUfDlT4+6bo=d1*LXy!HUARM1@cbn%4GoX2=9S8Y^ z%62y_x5DhoC_Lx66^e5SYzMwko6c8JS_nLLS(}^PXB?;FK?XmS{FCGKK>|89Wirh;;N6csnj+CD769 z8p-T-lJnLlg@oinn2=n^KLO*$>8Ginx22yROW%eR7+oGT2pyAoMb(i+ItL9xNXm1p zQR%dyq5HlLT>BtVT1#On`t=3}RweygIoROVnxP=G$#am?EX4+vgUHS%&u0OH9r8Rd z&iiKBe=s}+$4nvc^(|6kZkgtgrWlpsB4crzf?*P@_e)0loCPVxa7HW-i=|?AOHc2ob$l)5u`x4=L*QIKwFvY4 zAfvE8B3y6_;U8uA&vkec(_<1UNWd;(_+cI1!1PXdA;TZnRZ#fLESN2<;*Xy})DLwO zmoDaVqMl;Z*Aa!)Skr`?gi%<~f(0x}Z43zb)3JZUI(IbZAx=u;y4_n&jKF{Vgt1_d zY8*=TT*Le+kl1-|7v^)t^9+_K995o~^trL#}9mQ@QbgK}Pu?(DE4ll_8 z_9i7K)get341M?0=(r>pWhYkTDo$*}&clru?C0<4CgaPBfSTHP&Ag%>U9#^gd(8lKKxx5@+DPsCC zxqWV4K6Py1*!j*PP@pjy$Eqsu6LnAxQTKt|&Wy!Z`8w3VVimZ}Fu#m$MAK(Hh==oV zAwJMLvV6u7%vi_R8JceefuNF(5Zy^=4_bz0n6VE=EO|^O}ep>4!0Wx zVygu&rW{7q?5Ypxt_sZOee#pKig%+is66y@x(Z{h0zcOM-nJE^)_%3I`g?3j40qXq z1JWPBmx{exMsQ@Q2l~I5pasXg?VEh+t%0}B$HkqH`jxTaRSZNqJf(;Y85@TDa31*s z=&S1Ld(i^(r#O-}1FjTXz29p7?-Y{Ys@yj$Z!z_TUOMcx3r)zj1KG z{3^Ue&N$k~H)JYT;Nl$Rcle#bUnnmvG3=VRFvv(|?u<>_ayHihN1ivSJZ1LZBp9UsS1%hemsl04ps6 z=NmgzPJA#>(XVbSP!rYl0WV*FJnbKTY0UZ;e~F||iPcH7ODYhuIyV9+-1weXv9rhO z43(pgF1Mp&PL;S!{Vb!7biB&`D72~=?>JYH8dt%i$ zSkCgk__o03{{FK+*R{r9nxPf}zhgl5?ZEV@R>w;r2X*w?%Z08B8Ld?XsLtH0y2t{m zIdyIMsV=7FpVh^CAxLWel)kl+WGzK&R^d&91kJj=RY0?@X(4nw0Nqh_%(!lcv0*QI zW)(@+xX9SlTE0YW0V+(`5Kv=keA|qlyZC!urMa`M$9kB+V9p0f8@!2bf4V(%p0T+m zbl%2-#X!Zfr!kj*vnW)G-}5k~N*%E0*JUAJ-Mn_lQnMd|&a>E_T40&;kCyY88I6 zk^jyXY%*3y4}#IXHL&pz#S>Mlo@VNfyYa1f8E;FU;4(-3_2}>wi+k|U1tMUpXJY&j z|7=WK^{JRz)~x2Ws%0&yc}?YrOwDV=*JmVFbZ`W>oQ6jYjhu}PN zAA!Uwq|XdNE&%lah+|j2H}nE?QD22ef+;sw3y4citB*<#{*vjZ9W~Sq=(CD`$T&vQ zpJ4ZGyaW*}X%RGBU!wEon)r%tIQ+Oq6brS&PviOuc66L1TRO}7avFefKpKPB1waDh%KF*EB ziXlJn!dX2r;ZR}`dkHYeQLDSk!4|ipg%sa0vSJ&%NoKu1A7?v2VGso+-O7&=n zsDtu$=pQ(~u-ySM4@bdi*-y40wbQt&TZ*i2_rh<~4pc2H!FTq;QX>&%b7G-I9%0}h zyY+BC(%#h1SIqoJQ{j4~lfgtnOipooGeZr!$lm=?3;>qi2DeLbOQgT33K!SzVnt|* z4FwdPo#vPc5c()!`K@rJ+X<+m5#fZZ(H+6q<|6c3gh5nLHrQUa6o&4Y61vL#*(&An z78#m^PFrMsC1`~M``$tVjxeeUBe>D3UIADjtzRLDg7&;3OVwcqFn1!n-l#bQh2RK` z{(4TV7{}lXc0Yi3}ZB8$|1^*D*9C*Ai*Hpz_ZV;-5dn8GMYGziNPMh!yFa}J`@kLfR=+;LwX?#Rz7H+r7Xvy@|1W%jT@G z=i@}tgu^#{wpCed-C7wxksHecXthU4ARP?An9Pe-;KBG3V0+?Mg@AyWO)k>b!UDT; zV%7fka}L*rQSBcQTeaJ;hw*EFZDd*sW{%Dk-2Pg%?{-6%;)mfbpxLw(@d!cIeViaD z-mhwXv5Bd0C1#hbpw`+BxKw=@lMv*F_=YdQ5~E@!y4SBh#TfJpS5m=BNm7+s{u>Ao zxQO4#zDMsp$lbJ}f5o88&L{u)A55Lz!&pvHBmUsMth8-X{6QL)^~KJVM%EToNjr^| zrO;eu(!=ww3dH7FU#$T=C$N>Z4qstC%zm`av2LibONwT%eFIZ%=|xuc9lQl%zQ^bL z(%u>Xo4fWXBCH!i>c-01V0f3MESayQzpe(Q4OCrZ-CkoU85L~-X1LfY@yCY(ycF_D zq=~d%d9pth=k93qTje3Jx~vnemmG05Jlx+DsrB9zg@=#6LWO=D4^3 zTM)`~sE_(@Er>5I^TitDOQ-tUK5Z?4l$WcHHK*LVrP{i7mdtu%!y#kC<43+Q%m12t zcd(>bne~^V@?;cWw7LN9fyLA91_@lmuSxe}WjEpnOL+vBaK4UYup)&TQs#OGAi?AJ z0MTLNDt2MKZ`V}7ihn?6j0NXqy_m=`~Yn+7wf ziHi~ZaX*@7eUo2Y0wApFh_#88a|OqhCk%fSQt5$%(BWq^9%Thq)LSbgBX<5HFRJbS zCs%CmV2?cMGuEF7asYFclwwPN#-_y|T!JcmZROUAAq*ex*q$BldjaJEmha$ly{t=j z!htomB!HCG3U)etzybgjgE&A|svQd%QlMo^k zMRk@FjBk>1t4gvYWey>B86M+fpJU~_4EkU3z7TNR*LJbS>G)A>_CJPZw6uI39j-=o zB~pX+9U8hE1`U90-QVJVpj8%*~&RSqwn+>?75^3<7;cnB*u zpL1IPF69x4uWgzxZ!Cg^2rKg*FamnuSmmmIlwfZnQKAu-^kimeY<3RTsffKr=$3B! zWhwsS4=uZ<43X_9v|C(u9sH`BU)>X`yO-H*LD_D8Et_boy7{$)OHke2fWWff#B@;I z{95+ZX>{{z*->%xYuRsH%5Z+IJBUpTss>+wlI~)g zZfmXBW?U74JJrQ-{-wGY$3K6P@x``|XKnmTb+In(Voln`dbEpqw2S%pXRWP=%UVVI zivA?s#WvmXEfI_j3S=9gfgDH}<6UpnH>&|F+%j#qJ9Xyp35>K?v-$2h+4HCZq>C;LN?O9mfvYRrtMZ;_tWp}l<|kj z#$d~T1wW3MuWT#fkc43tf^Vy`{Vj|;^xs&wRV)lp+^3VS3{avcX4 zxUgul+0M-j$mQnX>Qq;OOX75)%rBxgjKQ{q-9lLHIAB8U^RLcxgn850W7C# z$MT&nU|4go~Cl^0e^VhY&T+N$bXQsJg@0Feqe z;){XtA)l47pMVD#YPGgb+kgAR6^AQ8Mhy2`Z8NcIM22mL&}zE?*CXS{O0b4SV2tS4 z6vO-|mPnUExg2g#VZiFh@G$A>!*j2~^`9k}QzTz8mmGrh$3ixePgwJaEDb9k;ha~| z?MqZ-d%J&4Y8{5Icx7rmeq=HQ+IC}RsDm(vz3%`_WDmdBx)wsm(r&*sw-L>Z&ut1S zgy5J6{;xHizw9|oyhUnobbB%Xrq692IFPG4$?}qjP$imAL`ObiB=)l(Kswt?D+scT z&!<|fYntt^1=Mb|J7itQ)6}qaYwPs(P-r^DnFD{wo%Z;^Nba-~Rp>0kzJp8<$?s(| z<0JlCN-7S=M{ID7!B%_3~h&H~^}eYVwPTiG2}(E4#0 zU1}bV70mu|4O~XztpMU=C_)F=cuA}Va9ZUz48-ksA ze$ycmKbE-zVY!?7@wMy_ls0m=)+V8bMp`R*wmq}DC?0liek z(x+N?${K%bz*-)JUFserXlwy?Vjcy1Rz&WsC*!4wD$dt{5;mcAWNjTHDh{LUF!S0y9r&`ef#X4uUl|WH z`=|X%rGe@dznu0<0weJ5eM~90>*cVbqz%y zs*~7>v2WFr2F1qwD1|dRkUk&zDh>~S&95kVhuO9C-yN5;ex^e?y7w z`8ehc<85u0PK2J@JiRjre#4&e2$#j&AIUbfUZ|Yk=xdSBbdoYs8?(cHGpGDFb3)G^ z`|aJKb;$NxSQ)|3vpdK5)1&=Qzw%uA)(iDY_1i_Enb}(nW{Ip-zomi&hUID5jGov>c zk(d43i=UK}zF?7hRJ#U_ z=fP%NH>}`GvW~`_iB6Kbob)9y<*c0DJ^gjcX&|@43XaxMj)hlVQL7B>j1bxr(3RJ= zq~C)zUXBASo_yj~VQ*e9&gOAiJ`Z;g@ZkE9LELQ_QTt;PkNjHgM;8FI7O!}51hidv zvD&zFYB~7)K`R*|XDJ3v7Sv6y<{6BwT4hEUP(Sc@1oEc*pWJD{5~2a^JmYj^w0@uijM<7V!* zwbGUVvRFMNRnamn%aKFKB3ooMs61$Y>wessCK#G~PETWYr?Qkt0NF!tS8e)VkOdV4 z%UPY62WHFMQDsaAV$^n!>Sg%NimN(gM7ArFQU)dqO99mV&Q6qFz`bMQoB}ACK(bP2 zFiXm%AQsC()G)Ca1T!7`#i>Foxn$=JBhE5KSa^k zu3kK=SPl#NSVa|H7Lc{poR6WllC1wh9}ynZ1g1949z^VDpVvhQ!|kl2yh7pDfS>|v zg3DOV}M6 zlVXG;NJ#DgXUWe(7c|S~@>P>RGc+x-`Zv z&EsWV5%;0kh@cFHEj^PIg_inZR3GFJr#F&@z|IgqR%G3VXOhlf|AM;S_oDHbx}3{d z#bNNcHcs=frNxgHshb9*z$e*4#u~aPKF=qOGSWT zQM^B(=C(*2!2oZjZf=UdibvjX;&TZ^x(u~$ZXy$RBDm~6@Ne-~f*p^J4DV*W!x!#* zK0Z*&(ohmrpjyy(Rj&XTb$yeOcmcap{8$it;j;bAnhp*>CqT!CiqaoLj}E+8WY0O2 zKE@6N=;LrI;IN$if=3u{J_{9&xk8_OslO(-lLt|$Fs0nS^ldQ9j$z4?$ZP4RDhMH1 zFXt4^i;%Rj0=>GcY2}c3=WVwLra|Tk`L4@D6oDZs12sZodXbzFkJP9Y=xd0cQZsTyoo& zt#8s}t@&09D)Ik%ch8y}(KxBA;l`{YkRqUR&TLRZJ0EI-11^588$nZZonT`y(^$vGI9Vz}+t{l}i zSkWKR0#&2TZggV$I#k5-9$%~&T^>d zt&m4L<+3L1|A|j`R}E}Oq1VDkUIc1{{ZGQ`(fXr7ux%i$qsHoQ;YNiJ*7ZjG4&JUH zVcofnJqJ#g{Ss)q_OxULoQP;l09ky%Xie;3C2&+cW~QIS-3fFHdCHM*QW!D3i)nea zndJWI|1z!n=P&kOTzKZ>+`{)37W;4TFPu;`0f$6q`*I6EGI{poYj6^j8}dz_{86Mp zQyeE2pFF?+nlt@~o^XNhnlmp0)i=>VIvQQZ5A#hr)1O;7c`}O0W4in)y3D+5&YXpv zc(PlC&sX3joXmt%oP;QZ2@5Yl`JlHT>h%=`+#)4q@l+JanQ#WO1U0uuJRp6(awk476MumdFV$ZNk2eArIUb1#RqA5Ib1{lx!?TLH zkP*$qx%5|4Doz$vY&l( znO8O7DfXY?4^Lq5%uK^_P)tRpHS}Jdsf6AuoN@tC4luEDGEmaz`%qRQct4z7(KTmg zs=AWNS?8?DK+^9aH#x*Dxom zVNRd#+U$aSzK>^l1qmbB0Y2Y??A+|P>oRb0$glsPQ@S3>dVvbzpUBFGIe!Dg%TWC% zy@3JZXBr=M8qZEf?uE{1I(`1B>`dAHdZQGJ@*DCUH1+xZ&UF?8eLtO#dg=H~ro^iY zIJFl!0YD=i@YzfXg7CTQcn0`74q)ArRWaZ%x)wX=V;4YE>p}^U&!LZNcaCp5R3s1NaZ~Y2~2$AlL*-c=0AV-PZ$!Mcxb*v zd}S6Qf;VDSoy7`rz77nVZ1eaaH<0%wK$`QJnFv|ckB~e9brk;-?!m|Jn-~ZNNH(J_ z_k9FE1%b{hk>N@JSFn#sa?S@0J*9%COeame%I8~CX!w7Rp31L8ErmsXmX~vpFaH5_ zTH#s#`CApaYe!&~Zji}I(R3-7s(w{5=ZiHxfr}4^!wrK)g2O;^7Sx${d$ChzF^=b zjC(LZRLCRFusIX%K@|)oPDtoNH}q13eg>XGrVR!b!)X*PtHGQon*T5G6fZ1-)=2Ru zXCQy^nvVe+i)--BDZa1}h*j&X&65?E+$yO(KM)0lBS`rMek7io*$5}2#sz(g+o zmy6iCGl1H@Vjr;5UtEVdkyCsVkS@2l7PBf){2bEf755aQABzXh01;LEB@kD^;xeR} zRJ{BHm}bSLC}47NH&%jz;$>B6Pw~UV#Nu<%dq(l6fp5FtRq zCWMe6prW#gxFD+txJ5u&L<9r`MU9Grii(PYhzg2|3K|h5DkutKR8&yVpn$*kJyjFp zcR%mFf86i!$MZ1#zE!8HPMtb+s=B&o;?K&&7RR3e-D>-N@xEXkzgdc9)%8zzv#fgl zIFzmLPe+{%{1?!}6n`$oRWM$< z-w@Fy!{35o&-7o1WPATeo@I6LFDu0A?hopY8xB7ipB?>&(U)`lTcATH|9n{KT)*#G zSgZXD;pAQXx1hro%Rki>_idKH45eSQ{K@du*I~Db$P9)%KMKwLL6ETgTcEh@Kir!G zH4eTJ@Q-D2pz6W!uAd8&g#5P<7oz-n7_?|#!JDf2^>R5-Uty4A{3kH%vHm`E!t1fiG=Kxu0+XPV-vQP; z*PjSIJNuncLl^&J#8V8^xV|z_?_d$aK;9uP;UwEEe+owT4a+|nk3WNF`QP`) zExG0Y4vn^3ehVbNZTV-xrtet(xls9C%Wn{4SvxGhb=b0YTK;M1^`7NF2a~>U`46Dg zQp+!BW?3It{$7moF3Z0O{`sNhABJALEq@F;_>twWK-C{x{$P0g9?L%nRt8-< z`Kw@(0|*uUEbAb=v&gc(w)_LI#39S)*Al<6{P()!MQF?S;IiLZzKhnsv-~eG%->tS z!pI-C{FV(Z>jxA-LqA%6e2QiLWchc&pO2t8+~ug{@55;PZ29%k`Y)E>3YTM+KfJkR z9k=`|QQ5DSzZ8r6ZUoFl-vBRIVEe0KkUMR^H#)Y^_Ai8o zEVBI@Ve7@VKM2K(i-W$(ffl%q$CR0Y>lDPSnYgyV^qz%lqo&XV*JEh>He50K)@)p_ zh4atBbsJ1M7uOrlhB~+w!qB(ldZ;E8!nG&d><(O?>H(E-eFYWViE9S@U?HxH;D3v7 zosF(8#`O|-^jL=U0$k6A$KQ!-Jgy6IJ=Map7UB9`2>rly1ZK-!xITjZFTwSFT$kdy z3D;$~K81Gf#`QtSFUK_w`mezC9oY3ATsvc1c`vR_F=>mp1pTWZcMGlq;EBcigMKmW zcnhw-W3m(%yFP{m|{M3Viu?T)(eR`?&t@7}^Kz!4VhW zdK~rLiR*XJe<7}o;TMZ=y#V2IF|J$DpSy6y9TDu~`VXMKrMRAizb(Tx3SsSTT)SW< zEXVaB*mni4qtVVixMrr%KCb^#6U$nOYn*3U_u-n2S#>|IM-T;0Z&^)Rkqz#gk`od$b9g6sR37mwn4P7ljkjq7EYQEPC$7T3pceGB$|9M`*G zrzdbd2LD-$>mb^DEHH@qRvZM#P85M*Cl({hIz0SYJ~7&be6VtfcfdEb*D0&l0LW>as70RaLCVwzeics_BMri!Zn@ID6KAy=H|s2f;zCDR{1%gVMBvz584jL z85*tl_n5-*QqW0_#r;nrbU1Z1{_S?sUA$g0aK<4NX=%FlgZ~4XvvN!ym$j z3{6q*!rb9+0)fztz?S5<8ZK2MBH;2DBWiwPh{3v|Vn=MNXh1DyCb5t4}w36nkfmA3`Rj*pZFTd;z z?W;z?H!E`s)Dbu@s6rXu1}|XOBV~uE9hmH(96Bd;sM<}Vdcm3^JWTyblY7DTLdU4# zh_j$HmXmt5T8(86RGWOf8c*+w)I3?WMQ{S`BxR?nUWluG&8TFgUpPUUs7~eBai*7tbx-oI><2NvgR?7Jj_S>Ww?5< z6iU?DgJD`12qy&(roc%@(y(;}(@DD_8igAfHw-GgQEi2r8yc;rTw6n9)mX-va}2Gi z{PRI`4UJc`=t={O?L-SYM@?>D)r20s+Ry?OMQc26=s;z0LO)^X5Oso6_9;V$s`w(%4TcU= z1$4koK?ZXk8Rb#edqUpyUQpi*5BIC+Rna&$3klJ@+TW=h*6%9Pp#Ta}h%Vsq<}hIX&PPnYMw{g|>RR zJNR)UzrMO%BQ(s{)i!mHC^$;B;)^NIxojIA*GZojR_biCb(H#hF>p9VPl= z=Kf6i`tId$yg=$f$TtRW;PUh+kXml5w)B@)Ziz*H*j9WcKb&dmKVqw+v{ygFkJ;)7 zc1huZhF92XEABSJBMd)jtG8MIH7*ApX>nQO14PWA@Mc7e=OAKG`s1GJd_=pXH0Zrb1Bs2q;}QNv3e6%K({ z7{1$48@P`CX?U5VwsUrbLPMm#d(ppM;PD}C|NV}_ytTr03_s{7zb$wp!^<6Yya9Nc z;fEcyn)vI%Iyh0$K=lmsM(x`U7R|eGT z0`M({mjv{>yWQ|rsE-Tp`ynp8fz&kt^+FE#$0mP!K=p18zR&O-0kx3hbI|b8fT}hK z{5!*U2UNop@FRwo1ymwe@?Q<#8&FH>|6Y_HkNp8Pi~7YIelVb3!+twl$MEuiD(VZ~ z$ne7f^#T1g&F~`ubtmIX8^ezU)XntYbE0;MJt_h!4~uL#&*YyBs946k^9?T!ss`Nu z3^jaKQ2ox8f0W^Kf@%xn_SJ^Z52`Wrr-_Cy465tsKU1T0d|47ye{zku&Ezi+s>``^ zSZw&ppnAGG_zJ^Ig6eGcca7nzg6b&8<5|Pk1l6td#}^G>8&qet0)IWKO!~Jjs195mXn_e}mCFK9vU5X6hRgt;chBP}OY*9yYuzsQ3#2;aZ084XPNfuqlS` z52}`&PfZO!7*tEtT!`Hd$R@VP^w2o)%T{WNfE;acZU6mgM-(&b@SCw%-es1^{SKY$(;p=GL%VQ_& zs{1*=4;#MSRsHCHzZky5RogiKemCVyU3HxPZdWto@75YQaWvNVYFeK%@CoCsa1E2c z*HsG`4-*aF?<#&_KU~l7gRVNj_}$p>a#tOtJE% z>uT~VTy?TFcyGf`y2^_JFEG3~q|W1hWvJn^Lh91G;3Ey66H;ekB89Ise11sX!u4~a z;R{3RCC;yDhA#=Jrx_1#Hhg(V^se@jS}bNt>k_SzQG zcP{T4`RyTfJ31Wx*vOZL^qtOUhVKrkHxYQkUm5wbkm}`te{1;uka~^wK4R)G52;MH z|C`~5LuwcIH>aze*7G-{PI3K?Qrdrxh17+#cbwAmxgwt$1dH^)sY$IA0qo zo(N(86s7jjp3M}`cmk=jqEr#%No&P(oIvWFDD^-xczeZ@8SH1HR150UNA<%pg!MB@ z4Ne3fXxd*ArRs40USjz2D3uZqK3ZviUKynxRMQZhY@!(2rO0i2#r^5+2>^@H(4d4(eT~s4au#m_A!F3G*zXjb2y;)iAFqW@i|`} zQhP+Wnd;7P_ORL~w1tXi&8yT~P@nGt_=7EIOXgA}LDFIe1>!jn(&AhiwKye_e2p4YIRcM^||ENs-yHGS(R|} z^|PUM^)cls<3}ml2SdgJjiKm8m3?T2LDhW_^w%y!vK8`mZ#j|A^!6{q9Yj_#k2k`z z6ep1`FpdTIfoh6yi4Icy+os1y z+Ibf^I(Pt|)wywx4*p0uM9Q2X?Fv@ItIGc~R$wu6@Qd{@AwcOf%6 zxB{QG?e+N7Mv?ZZx|qju%CRAeTlT8Rz9F(-|Bb9EP`@Jz+*2Gu-R-}Mof&Uac>@?O?w)>9sz^#*Q(20JI#a-MK1IBY+b~UJZ^oy# z^uv^wkribsHPQ{lreLII#clo+Qr?CHRPZtlf*I^Bho{B8!VJFD@C9hL>(xl6*xbHL@=)KC(`d+iEJ!>%7VKS`bw#UCU825vwEA8-zD<)fUKWe(( z4o^g_KWVnZ_P(OxM>IWXdzWKV6n9k9leTw0_H=PSYr4bk`TF~qcR@^a7 zw>e&K1fjU&n(lSHIvmwsH9h8dyd90J&~$#l~lLiSCv|%;H$gRG|1Y*V zj{>Rt6I3?t>*6l8Ly~_G<(qpy&55cH&Pn4&+8rc+PNMo93sT%D!{;Ze7RZRZ z!X6>{3&HzF-ud(@#Ng%Z(QOz0vKF$sz zo&-`?C8{R0&jdR~_?kq;pOK84X!zPhwG^9^xXE@0$zPYK-Xx!5^4BM-VdsHgXZXfM zwdEY}X?BswZ%$OZa=@qCb_j?7ws2?&q`8X7J+ZEKN3DCNyTyex7oi5pP!^YE(CwWPR2CEeMgci z#1b60-DU(0q%KKPSH*+BZTRvel@JEsVfe}<)sgo4(9V$ZB}r-~?eU4>tCG}w@^5S| zI5@{kQZLs4FPF_N&aso!`_$)%eSwreoTQ#){YUL$zcSh$x9=5xEJ^ur+_(yR zgYb$Z)sXi2-F{j4$t3j@=l3bQC59FERmtiQ<4?fR{aKi-wvz`Pt?!a#^(6|%xrQ%K zRx8LuhObOkuf~8!8D4^|qYoZ!_^M>(a!XRp@HNS57{^Z;zBXCSqkUo=TUW@ZKu1=ucaR2c+_#G3NNm$K1u;kb?y^BtG0?s z18?rUC45e8HId`d($Vp7er>gm^Q%>a*HsHR9&IDMzBP z`gexm%NwcHoF5&WozmW_Mye?sGcL>dML16PYunFaMM#j3$}J$aX52wW2f25tZF8ei zMWU+MDdmG!Hw2*>ZG@1jw`kn1NIOVv1YFzZ zmPMDStoY1M?+k)`mdJBc^S_WkQ}S;SsvIL#((@xqy#%aPJb_FWZ>%X1+#}E;sJI(gWQO@qq*h-l8Xgca1}a@yRmBuiVTr%w zp;JvHnQL*CBAjRJu;g)Fu99c;zCiN0CRfp0+7lP#2Wq%hq@JPFnGd5kZz7|E_lm?m zO324AM3s6+`p-v?a@Wah8QecncB}-DmyuN4u8q|>K|anDJ_~6OOTndjKY^pA#Gg_E z-^4On2{Kysqp()3EnscgCTQhFtg7q~5#YYzUj?d4O%o~ZCjPAy+lqAa0TJa!LyPkG zDxs>tJ0ifHN0qunpsLjOBE|j4ze<@-@;1vIgO6_bujdLU!Cwmqty(QR6&+*|cLhFf zs#=x_y0QOKjB@cdE8>nP;lEh%0i@QJ-H)z79K|U5s^lGIIr)&nA7dz?hz@6;i3ImX zT0)wqM8u}2M1Y%#Do)JB0aesTs-Dr@+~^9X8@-CG;?tH3L&b%`& zjApJEDei~#=|H6b@*YI0`!hav;=c?90~Qmi)cDuH8|fKK)V7;qnN5(7fARhjszJBc zx=;k|>3L9rqOu5ZQz5M)MDvEDD8gep0Di z@4zxV4tWxL)CdcDI54o{v)L?T#*AL<%tmx3@hr`vz2A|V*hI6MIEzEE#HPDYPwa28 zSmhJbY*gpH&>zXob;Fj&*E|!?=A7h#6JNYZY@zd_J-%j>*iy4tk1yFIw$iMo$5&<& zTWc2Y@dcekV}xYyp&(e>)ncH!-d8x~No=Pj8+(IbuEccRUNdi50$7I5YvJV=fn{pe z#^XyoiS0GZ@c7D3Vh7E#yvb}YOS4X16AW;o8N?jRVP_LN#=}~5PhzOn+KFARL5T1! z7=ZK~LYl5lGFVq#MbLW^cY=xCCQDwlhp%{BiQTm!W4-gw2g{uH0sE|t_kvuN)@Or4~Z63L78*1`Fb8tU0u(|a-stdW+C_pZtV zOVupddlOES)L65+-bm)1rJXj#a;QpDlb4`v-D}`CUtB|7K*jt1xy}L`ZX5JjK4>fDy@f9@pBmJbVjW-xKdhW+MFT*={ zHrO7`vOK=??3QWP$>XaQ?kAe%cztuhKGiJOJDLObnP$B_zNF^v)vT|_SJd2nniY6_ z!Oi_#vw3wp)5+bh+0gL#5te(9Vbw_;=7njNZ*%_j^s}*xtvi=&+`kq^qdh50^^Wg|^o<3G_#uyWIAEY%XMxwVmkHk(uWZDAx4t=s+K=+-RrtYpHJD@4 zz~%~%V=6pqt__}I_+jXSj=K#FKN7EQO9F3XGqwa$kHxF8so<%GSH!DjEx;SwFG%|* z<5mBz;Ah#Jg%>BN_Ye?V{q=IJ0SRh1=TlQteqn<8ycT$x(RWFLyz%ZfH~GsG)MDz} z!tj*|>Q~ycrQszB>dAQUR)()iP^EP4)`qW1P&k#rYu$#gO;7{q-fazEm!OU_X0$VW zJ@lbRryIU8LB87IW*YrAC#Yuh%l3wENl-(4@D6r~%$IEmYC7$aW%zcqPk+g_xd9BM z?nqGe=r0{jc^rdpssnzG;W!4ry%4;U;W!584#Yjza2$gl<@k0s9LL~XpWH5n;~0Dd zRwOsa@bUz8C%wI^;fE8{K~AJ@wqDWeR_73sCgITJW`2+2* zgdfXNyIk<|jr@{qmBC0d$nfRa>J|FyV8d5ttC_Ut5W`Ed)y$TwKrTWtMu<-soMlV-?YVvi7Y%Dbon zddE`3i*wZP^v-1_S}w=$QP4Y@-Z_8EBvHxof-=3?EVRz>~X84X=wF299_i@8ZA)g5T zq&-9WyE|8X$Jw^den<~zuKIz|_8G$~a#dq`+jI6Sl7BK+^~(ZZZ+LN@%BKF$+uJ06 zR-U?+{oP>mK{~eGdFmR@rj3Sg?4dStHoj>1=AJ4)4}6p1TY9N}?BC0#{cXL~9!8T_ z>~e{g+k30d>EN&0yQRI--ty%EcdK0?`MZ0omegmPt#>13y;Ydw`G(>9d&`#(+&7KA z%X_Pb87<#3{BUno7t_q$Zm+|BD3E%jw|rT`eb?l#>?dEAaCaD9(oeoD;qEkiRX_Q% zg!`W1Yx>ETCEWK7U)xV@=j<#sd|f{k!`0*i!`JtdFHg9;4ByyKzC7W6X!z!Sst%*Y zZo{|qQzNPG9>cexJ=(7<;t&1Qx2*pwlfR>%8btp%V0dXiwSe|HX!BMc5Aph`u5sXB zoBV_Q)W){phYT<8CtrqezcKu9KlK_{({F9wRKQ;SRBz6&!zO=uzS_*_^Mm0l^VK{! zhWn%8CHZPY4ERyQSLLf^$>2X5z9wHKadrE}@U{7>6T{Il!`J1jw;8^U8@@hYeO(Rw zSHm~vtDAd)|7Q5+d=<}VU19i^d{vLD=^ut~%U7S#e@_~|Jzu`{y+nVmVffnqsw?ATO{ZM+ z-`rn4!T6!S28)-M`>PY|pZ*>!US997_$NJF{Y6;pcKWN&YkLSjUI))$auQqT# z)HVD_e>IxBp?ZcN>#y?rg4Z{^qQ9!aJBJ2_pX{%G=6pyoytqJ}%iU;0!)Fz!8@hrw zGJH;fdYk1_4WD12j&pb2*zkn~std>aEQj}S*ew;*8jnXPZWF`T7RZ-}+@?l;TYS(@p;20@bVqc!pCV{&A#0eaP`@Z}N{7 zsK>efWgA`rc?Z0c;U^2!iYV}N9euY`JU}g@zMW0}`~hky^^Nd_1JngvZ@M}YE)e?- zPyx<|Zl?V50qRoL-`((415|z5tB0v?-2hd}@$6~%`T^<+jz=%UHx5vJ*j{hLHxE#E zGoJM^e9HiJ4*lso!?z7kN7!Cp!?zDmW%S>EhVK}l@@?>Z!%GLK#`M?zhVLGrE)0Md z7+y9&y^ohx+yRE~h5p?C6gexTzxxNMY~~L%`3DE6N4b8SZ+Q8DT9@O5V2Go`|KS1Z z5{8qDO!mnE>g^Qpp@tV1s-Z2xFE)Hup?Z+!zr+mpoI-Um-C?-NpI@k^aQPl#!o$Ks zb%OPcH2Eck@?8)23d2_wse=ly3>UR~f#xP>tgBxZ3b_g=!t!8*BLbLN%KD zTx0mgLbaaZW}M-h(Ox_7@rG|HRI%g}4Bu9$?&S7tqT$;M)oBjL6vKBEs(u`f>kKa~ zRQnnJrWwAwP+i6R=_dS@6{-(7{jWFq`wP|MIp8-Key~uLaeI2B;pK&DE#|pfZ1~|q zRR{ZOcZRX=kwR5J1AL~*KUSzVGJMT)9+2U#C{#DoJ#TYf6~3lOT^R(Q?R+MDZIL?d zgU@k(6~3-WIoaR~oTLjmJ=Pbgk|y8_4c}O#>M`6cHhgoDT0!|GhHoiSlR2Kt4Bu9y zZl`-LH+*}MdX&rCJ%;ZnQbF2lrQxMT>T1g0Z}{#ab%gdSF}$ou-OTCqkkeK4+gqd> zvVRX7zQ0I4#p$}r86x=yi*QytfB}f%hbMla5(`KCR?R1|DhJ)PFOlTeMg+F};vD|0 z!>>qp{3+OD2mJFf^g*lc9|(w@9Ji3?D;|H|z%AmbEYBn5gsI5<9Dv841Bm3Mc>Fa0 zw+O2wB-_YSfC$S7^CuMCB5q0Xj=VlEA6X6k(k4@jL&>6^b)H ze&s(Rj6*$s<6oPdU-2v{WFq!uGz)LhckzPukvO`pI>g7CRo#(cGz; z&T_m@GeM_oI>+%I=l1sc5C#{!EyoMdy>HN)t@%N(AI*NF7G8;i`XbPqH7yCs;~uwI z(^Ww)(?RYn`bK$8&|8oKIz!X7L9a&+=uEv#uM2u}7$;}(*(Jh2&}+zD^sTz8jd<2T zIVvUd32%`whg#|RRpk?pH<`!7&?>2Tb)D17y^RyFZftw}R;lgYu^LOKKJj0`m;E`z zzKDm^oveWmBHp6q7E+9l``Xa|7ireai=m+wYaj3B&0(0kOS8V-XqssW4@{iY0)9~O>yU)J<(iH1_`3}53N1Ot%VXfYN3*NFt7xu! zH5>0;NNbg7HrboWCG0`Xrt0(mhcvsvyOzu6!(?*Iem*DFDotnE-p)kOM>LⅆA`* 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�%mPPZsbjXi-8f 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

n{ikrmm#Gl1JJJ{=X7Izo-6}bk7{{C7VE{+n9 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 z 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�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 S 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�)VMYA?AqXVvU#* z7l}*68^pWB72;ZPgSbiT$-y?4UvY$(A?AqXVvU#*7l}*68^pWB72;ZPgSbiTIb89J zBg70bM=Td>#FV&5Tq52e-X*RO*NUU}@$nrk7K@GIJn;hYYVkMXJ>p7nt@yh5k@%fB zV1$ovPw^1(HSt~XEAjY!z551nu6TubgLtR-i1>{75Al7md_N!FwEaDQES@D^EdE@) zS-e+#Ok5|vBW@P^9N@zpE*>HtDOQPfVoE$)yjZ+OTq%Ak?s1?Gf2w$fxI%nJd`)~; z{8HR@r1!s*xUV=yJXS0b8^u$_^TaE}hs3AEzl(hiQas{*;#Bbzu~j@%yhOZSyjA>@ z_@wxG4bWpSgp zS?o*PE`D*Om?aj9GsIcqJaMsjt$4GzTwE=_EN&Dxi+x8aesQFjB^HV^#987zaj|%< zc(b@%TrIvVZWK3*eGgOo;z%(|EEH#mv&4DgV)0t>W^uW=T6|gDC~g+}j#m8QNHI$+ z6laK!XL?s~19wi

_5@lPY?^m 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

w8v+JT;Bb%bHc#-V1=y%qqAj^newLUUF?N71H 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�u?-){u>xSvX?QWY+9=_>1*tr><>EzU}u^T{F=O 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 diff --git a/tizen/distrib/ffmpeg/lib/libavdevice.dll.a b/tizen/distrib/ffmpeg/lib/libavdevice.dll.a deleted file mode 100644 index c4b0709ffc1c9c3c889e788dfa38f956d446c3b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3464 zcmd^By>1gh5FVeM*fZ|0kC$G-nOm<`Wgw4a*k)^qH>d)%|! zo@rXVmF!K^J`rov9JB!drS=ZMxCUq(3E5r(khH!E+35i6bo^jB3YXC^^gY`jjmLg8 z2`)nL{qrywWj8@9mf>t3O($p=U0nJFdUfwCJd5UwaOMZ&an3xwsm_eip~;-wNZ+pX z%5pfJoJMEwXThS#oAmC;qULp{F}Q!iwC}o%u-$j!Bn;ZGYjuPb;4?~tXIr&yGzu0$ z$K_?L|0ow~v{td5CslO*N-or>?2e`C4o*JFg&M7uoJtU$cyhJAqkPgdY~tAskyM-%uLlGBz4aum&;16hjH4?|8C#dAGatMx-#U8NpZ9ppRlWzpg+P$std zFh$$s8GS!FOX5NNCC%hJ&0dH`kIh6`BORUUh8N2N2 z?D~(ZRZX)?{@LLi-3(^^UA2+{W=W;>Wqj&Y=aZNJ^>eWzY^qkfiKs1tXi!=^C|sj81J|_6^kOKrYqJnq2S(tw>avGl@2t^uIz3x$9@C) Ci6Vgj diff --git a/tizen/distrib/ffmpeg/lib/libavfilter.a b/tizen/distrib/ffmpeg/lib/libavfilter.a deleted file mode 100644 index 377213e8cad9ff59ce327d9efb86c2b1841b889a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 307068 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

g=W}LamS<9;rXTW5ol%E*L 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 Z58$HCzs6|e@yv7#LuK3j0P?5H{vU4tn`Zz3 diff --git a/tizen/distrib/ffmpeg/lib/libavformat.a b/tizen/distrib/ffmpeg/lib/libavformat.a deleted file mode 100644 index 2fc6595ffb380071d5f4fc1c1784d1bd62008e47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 557054 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%0AHb*=$5Z7XB14!KP@L6 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 z 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
!;-D}xs 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 gxBuq->2cnT_RUm5&Bu>b%7 diff --git a/tizen/distrib/ffmpeg/lib/pkgconfig/libavcodec.pc b/tizen/distrib/ffmpeg/lib/pkgconfig/libavcodec.pc deleted file mode 100644 index 759d53f..0000000 --- a/tizen/distrib/ffmpeg/lib/pkgconfig/libavcodec.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=./ -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libavcodec -Description: FFmpeg codec library -Version: 52.72.2 -Requires: libavutil = 50.15.1 -Requires.private: -Conflicts: -Libs: -L${libdir} -lavcodec -lz -lbz2 -lm -Libs.private: -Cflags: -I${includedir} diff --git a/tizen/distrib/ffmpeg/lib/pkgconfig/libavdevice.pc b/tizen/distrib/ffmpeg/lib/pkgconfig/libavdevice.pc deleted file mode 100644 index 28a9698..0000000 --- a/tizen/distrib/ffmpeg/lib/pkgconfig/libavdevice.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=./ -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libavdevice -Description: FFmpeg device handling library -Version: 52.2.0 -Requires: libavformat = 52.64.2 -Requires.private: -Conflicts: -Libs: -L${libdir} -lavdevice -lz -lbz2 -lm -Libs.private: -Cflags: -I${includedir} diff --git a/tizen/distrib/ffmpeg/lib/pkgconfig/libavfilter.pc b/tizen/distrib/ffmpeg/lib/pkgconfig/libavfilter.pc deleted file mode 100644 index 8c39d51..0000000 --- a/tizen/distrib/ffmpeg/lib/pkgconfig/libavfilter.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=./ -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libavfilter -Description: FFmpeg video filtering library -Version: 1.19.0 -Requires: libavutil = 50.15.1 -Requires.private: -Conflicts: -Libs: -L${libdir} -lavfilter -lz -pthread -lm -lasound -lasound -lasound -Libs.private: -Cflags: -I${includedir} diff --git a/tizen/distrib/ffmpeg/lib/pkgconfig/libavformat.pc b/tizen/distrib/ffmpeg/lib/pkgconfig/libavformat.pc deleted file mode 100644 index 3ee39e2..0000000 --- a/tizen/distrib/ffmpeg/lib/pkgconfig/libavformat.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=./ -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libavformat -Description: FFmpeg container format library -Version: 52.64.2 -Requires: libavcodec = 52.72.2 -Requires.private: -Conflicts: -Libs: -L${libdir} -lavformat -lz -lbz2 -lm -Libs.private: -Cflags: -I${includedir} diff --git a/tizen/distrib/ffmpeg/lib/pkgconfig/libavutil.pc b/tizen/distrib/ffmpeg/lib/pkgconfig/libavutil.pc deleted file mode 100644 index 26c6ce2..0000000 --- a/tizen/distrib/ffmpeg/lib/pkgconfig/libavutil.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=./ -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libavutil -Description: FFmpeg utility library -Version: 50.15.1 -Requires: -Requires.private: -Conflicts: -Libs: -L${libdir} -lavutil -Libs.private: -Cflags: -I${includedir} diff --git a/tizen/distrib/ffmpeg/lib/pkgconfig/libswscale.pc b/tizen/distrib/ffmpeg/lib/pkgconfig/libswscale.pc deleted file mode 100644 index 38321a4..0000000 --- a/tizen/distrib/ffmpeg/lib/pkgconfig/libswscale.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=./ -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libswscale -Description: FFmpeg image rescaling library -Version: 0.11.0 -Requires: libavutil = 50.15.1 -Requires.private: -Conflicts: -Libs: -L${libdir} -lswscale -Libs.private: -Cflags: -I${includedir} diff --git a/tizen/distrib/ffmpeg/libavcodec/4xm.c b/tizen/distrib/ffmpeg/libavcodec/4xm.c deleted file mode 100644 index 2198503..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/4xm.c +++ /dev/null @@ -1,855 +0,0 @@ -/* - * 4XM codec - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 4XM codec. - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" -#include "bytestream.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[2][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} - } - },{ - { //{8,4,2}x{8,4,2} - { 1,2}, { 4,3}, { 5,3}, {0,2}, {6,3}, {7,3}, {0,0} - },{//{8,4}x1 - { 1,2}, { 0,0}, { 2,2}, {0,2}, {6,3}, {7,3}, {0,0} - },{//1x{8,4} - { 1,2}, { 2,2}, { 0,0}, {0,2}, {6,3}, {7,3}, {0,0} - },{//1x2, 2x1 - { 1,2}, { 0,0}, { 0,0}, {0,2}, {2,2}, {6,3}, {7,3} - } - } -}; - -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[2][4]; - - -typedef struct CFrameBuffer{ - unsigned int allocated_size; - unsigned 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; - const uint8_t *bytestream; - const uint16_t *wordstream; - int mv[256]; - VLC pre_vlc; - int last_dc; - DECLARE_ALIGNED(16, DCTELEM, block)[6][64]; - void *bitstream_buffer; - unsigned int bitstream_buffer_size; - int version; - 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 av_cold void init_vlcs(FourXContext *f){ - static VLC_TYPE table[8][32][2]; - int i; - - for(i=0; i<8; i++){ - block_type_vlc[0][i].table= table[i]; - block_type_vlc[0][i].table_allocated= 32; - init_vlc(&block_type_vlc[0][i], BLOCK_TYPE_VLC_BITS, 7, - &block_type_tab[0][i][0][1], 2, 1, - &block_type_tab[0][i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC); - } -} - -static void init_mv(FourXContext *f){ - int i; - - for(i=0; i<256; i++){ - if(f->version>1) - f->mv[i] = mv[i][0] + mv[i][1] *f->current_picture.linesize[0]/2; - else - f->mv[i] = (i&15) - 8 + ((i>>4)-8)*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[1-(f->version>1)][index].table, BLOCK_TYPE_VLC_BITS, 1); - uint16_t *start= (uint16_t*)f->last_picture.data[0]; - uint16_t *end= start + stride*(f->avctx->height-h+1) - (1<=0 && code<=6); - - if(code == 0){ - src += f->mv[ *f->bytestream++ ]; - if(start > src || src > end){ - av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); - return; - } - 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<version<2){ - mcdc(dst, src, log2w, h, stride, 1, 0); - }else if(code == 4){ - src += f->mv[ *f->bytestream++ ]; - if(start > src || src > end){ - av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); - return; - } - 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 decode_p_frame(FourXContext *f, const 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; - unsigned int bitstream_size, bytestream_size, wordstream_size, extra; - - if(f->version>1){ - extra=20; - bitstream_size= AV_RL32(buf+8); - wordstream_size= AV_RL32(buf+12); - bytestream_size= AV_RL32(buf+16); - }else{ - extra=0; - bitstream_size = AV_RL16(buf-4); - wordstream_size= AV_RL16(buf-2); - bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0); - } - - if(bitstream_size+ bytestream_size+ wordstream_size + extra != 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; - } - - av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!f->bitstream_buffer) - return AVERROR(ENOMEM); - f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4); - init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); - - f->wordstream= (const uint16_t*)(buf + extra + bitstream_size); - f->bytestream= buf + extra + bitstream_size + wordstream_size; - - init_mv(f); - - for(y=0; ygb)+31)/32*4 - || (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size - || (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size) - av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n", - bitstream_size - (get_bits_count(&f->gb)+31)/32*4, - -(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size), - -(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size) - ); - - return 0; -} - -/** - * decode block and dequantize. - * Note this is almost 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 const uint8_t *read_huffman_tables(FourXContext *f, const 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; - const 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++; - } - start= *ptr++; - if(start==0) break; - - end= *ptr++; - } - frequency[256]=1; - - while((ptr - buf)&3) ptr++; // 4byte align - - 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 mix(int c0, int c1){ - int blue = 2*(c0&0x001F) + (c1&0x001F); - int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5; - int red = 2*(c0>>10) + (c1>>10); - return red/3*1024 + green/3*32 + blue/3; -} - -static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ - int x, y, x2, y2; - 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; - - for(y=0; y>2) + 8*(y2>>2); - dst[y2*stride+x2]= color[(bits>>index)&3]; - } - } - dst+=16; - } - dst += 16*stride - width; - } - - return 0; -} - -static int decode_i_frame(FourXContext *f, const 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= AV_RL32(buf); - const int token_count av_unused = AV_RL32(buf + bitstream_size + 8); - unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4); - const 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; - - av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!f->bitstream_buffer) - return AVERROR(ENOMEM); - f->dsp.bswap_buf(f->bitstream_buffer, (const 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - FourXContext * const f = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p, temp; - int i, frame_4cc, frame_size; - - frame_4cc= AV_RL32(buf); - if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){ - av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4)); - } - - if(frame_4cc == AV_RL32("cfrm")){ - int free_index=-1; - const int data_size= buf_size - 20; - const int id= AV_RL32(buf+12); - const int whole_size= AV_RL32(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); - if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL - av_log(f->avctx, AV_LOG_ERROR, "realloc falure"); - return -1; - } - - 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= AV_RL32("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 == AV_RL32("ifr2")){ - p->pict_type= FF_I_TYPE; - if(decode_i2_frame(f, buf-4, frame_size) < 0) - return -1; - }else if(frame_4cc == AV_RL32("ifrm")){ - p->pict_type= FF_I_TYPE; - if(decode_i_frame(f, buf, frame_size) < 0) - return -1; - }else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){ - p->pict_type= FF_P_TYPE; - if(decode_p_frame(f, buf, frame_size) < 0) - return -1; - }else if(frame_4cc == AV_RL32("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); - } - - p->key_frame= p->pict_type == FF_I_TYPE; - - *picture= *p; - *data_size = sizeof(AVPicture); - - emms_c(); - - return buf_size; -} - - -static av_cold void common_init(AVCodecContext *avctx){ - FourXContext * const f = avctx->priv_data; - - dsputil_init(&f->dsp, avctx); - - f->avctx= avctx; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - FourXContext * const f = avctx->priv_data; - - if(avctx->extradata_size != 4 || !avctx->extradata) { - av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n"); - return 1; - } - - f->version= AV_RL32(avctx->extradata)>>16; - common_init(avctx); - init_vlcs(f); - - if(f->version>2) avctx->pix_fmt= PIX_FMT_RGB565; - else avctx->pix_fmt= PIX_FMT_BGR555; - - return 0; -} - - -static av_cold 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); - if(f->current_picture.data[0]) - avctx->release_buffer(avctx, &f->current_picture); - if(f->last_picture.data[0]) - avctx->release_buffer(avctx, &f->last_picture); - - return 0; -} - -AVCodec fourxm_decoder = { - "4xm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_4XM, - sizeof(FourXContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("4X Movie"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/8bps.c b/tizen/distrib/ffmpeg/libavcodec/8bps.c deleted file mode 100644 index ff57955..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/8bps.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Quicktime Planar RGB (8BPS) Video Decoder - * Copyright (C) 2003 Roberto Togni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 RGB32) - * : RGB32 (RGB 32bpp, 4th plane is probably alpha and it's ignored) - * - */ - -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - - -static const enum PixelFormat pixfmt_rgb24[] = {PIX_FMT_BGR24, PIX_FMT_RGB32, PIX_FMT_NONE}; - -/* - * 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, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - EightBpsContext * const c = avctx->priv_data; - const unsigned char *encoded = buf; - unsigned char *pixptr, *pixptr_end; - unsigned int height = avctx->height; // Real image height - unsigned int dlen, p, row; - const 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_RGB32); - - 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(*(const 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 av_cold int decode_init(AVCodecContext *avctx) -{ - EightBpsContext * const c = avctx->priv_data; - - c->avctx = avctx; - - c->pic.data[0] = NULL; - - switch (avctx->bits_per_coded_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_RGB32; - c->planes = 4; -#if HAVE_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_coded_sample); - return -1; - } - - return 0; -} - - - - -/* - * - * Uninit 8BPS decoder - * - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - EightBpsContext * const c = avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - - - -AVCodec eightbps_decoder = { - "8bps", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_8BPS, - sizeof(EightBpsContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/8svx.c b/tizen/distrib/ffmpeg/libavcodec/8svx.c deleted file mode 100644 index 6e09b11..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/8svx.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 8SVX audio decoder - * Copyright (C) 2008 Jaikrishnan Menon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 8svx audio decoder - * @author Jaikrishnan Menon - * supports: fibonacci delta encoding - * : exponential encoding - */ - -#include "avcodec.h" - -/** decoder context */ -typedef struct EightSvxContext { - int16_t fib_acc; - const int16_t *table; -} EightSvxContext; - -static const int16_t fibonacci[16] = { -34<<8, -21<<8, -13<<8, -8<<8, -5<<8, -3<<8, -2<<8, -1<<8, - 0, 1<<8, 2<<8, 3<<8, 5<<8, 8<<8, 13<<8, 21<<8 }; -static const int16_t exponential[16] = { -128<<8, -64<<8, -32<<8, -16<<8, -8<<8, -4<<8, -2<<8, -1<<8, - 0, 1<<8, 2<<8, 4<<8, 8<<8, 16<<8, 32<<8, 64<<8 }; - -/** decode a frame */ -static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - EightSvxContext *esc = avctx->priv_data; - int16_t *out_data = data; - int consumed = buf_size; - const uint8_t *buf_end = buf + buf_size; - - if((*data_size >> 2) < buf_size) - return -1; - - if(avctx->frame_number == 0) { - esc->fib_acc = buf[1] << 8; - buf_size -= 2; - buf += 2; - } - - *data_size = buf_size << 2; - - while(buf < buf_end) { - uint8_t d = *buf++; - esc->fib_acc += esc->table[d & 0x0f]; - *out_data++ = esc->fib_acc; - esc->fib_acc += esc->table[d >> 4]; - *out_data++ = esc->fib_acc; - } - - return consumed; -} - -/** initialize 8svx decoder */ -static av_cold int eightsvx_decode_init(AVCodecContext *avctx) -{ - EightSvxContext *esc = avctx->priv_data; - - switch(avctx->codec->id) { - case CODEC_ID_8SVX_FIB: - esc->table = fibonacci; - break; - case CODEC_ID_8SVX_EXP: - esc->table = exponential; - break; - default: - return -1; - } - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -AVCodec eightsvx_fib_decoder = { - .name = "8svx_fib", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_8SVX_FIB, - .priv_data_size = sizeof (EightSvxContext), - .init = eightsvx_decode_init, - .decode = eightsvx_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"), -}; - -AVCodec eightsvx_exp_decoder = { - .name = "8svx_exp", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_8SVX_EXP, - .priv_data_size = sizeof (EightSvxContext), - .init = eightsvx_decode_init, - .decode = eightsvx_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/Makefile b/tizen/distrib/ffmpeg/libavcodec/Makefile deleted file mode 100644 index 00e6b57..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/Makefile +++ /dev/null @@ -1,655 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = avcodec -FFLIBS = avutil - -HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vdpau.h xvmc.h - -OBJS = allcodecs.o \ - audioconvert.o \ - avpacket.o \ - bitstream.o \ - bitstream_filter.o \ - dsputil.o \ - eval.o \ - faanidct.o \ - imgconvert.o \ - jrevdct.o \ - opt.o \ - options.o \ - parser.o \ - raw.o \ - resample.o \ - resample2.o \ - simple_idct.o \ - utils.o \ - -# parts needed for many different codecs -OBJS-$(CONFIG_AANDCT) += aandcttab.o -OBJS-$(CONFIG_ENCODERS) += faandct.o jfdctfst.o jfdctint.o -OBJS-$(CONFIG_DCT) += dct.o -OBJS-$(CONFIG_DWT) += dwt.o -OBJS-$(CONFIG_DXVA2) += dxva2.o -FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o -OBJS-$(CONFIG_FFT) += avfft.o fft.o $(FFT-OBJS-yes) -OBJS-$(CONFIG_GOLOMB) += golomb.o -OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o h264pred.o -OBJS-$(CONFIG_LPC) += lpc.o -OBJS-$(CONFIG_LSP) += lsp.o -OBJS-$(CONFIG_MDCT) += mdct.o -RDFT-OBJS-$(CONFIG_HARDCODED_TABLES) += sin_tables.o -OBJS-$(CONFIG_RDFT) += rdft.o $(RDFT-OBJS-yes) -OBJS-$(CONFIG_VAAPI) += vaapi.o -OBJS-$(CONFIG_VDPAU) += vdpau.o - -# decoders/encoders/hardware accelerators -OBJS-$(CONFIG_AAC_DECODER) += aac.o aactab.o aacsbr.o -OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \ - aacpsy.o aactab.o \ - psymodel.o iirfilter.o \ - mpeg4audio.o -OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o -OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o -OBJS-$(CONFIG_AC3_ENCODER) += ac3enc.o ac3tab.o ac3.o -OBJS-$(CONFIG_ALAC_DECODER) += alac.o -OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o -OBJS-$(CONFIG_ALS_DECODER) += alsdec.o bgmc.o mpeg4audio.o -OBJS-$(CONFIG_AMRNB_DECODER) += amrnbdec.o celp_filters.o \ - celp_math.o acelp_filters.o \ - acelp_vectors.o \ - acelp_pitch_delay.o -OBJS-$(CONFIG_AMV_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o -OBJS-$(CONFIG_ANM_DECODER) += anm.o -OBJS-$(CONFIG_APE_DECODER) += apedec.o -OBJS-$(CONFIG_ASV1_DECODER) += asv1.o mpeg12data.o -OBJS-$(CONFIG_ASV1_ENCODER) += asv1.o mpeg12data.o -OBJS-$(CONFIG_ASV2_DECODER) += asv1.o mpeg12data.o -OBJS-$(CONFIG_ASV2_ENCODER) += asv1.o mpeg12data.o -OBJS-$(CONFIG_ATRAC1_DECODER) += atrac1.o atrac.o -OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o -OBJS-$(CONFIG_AURA_DECODER) += cyuv.o -OBJS-$(CONFIG_AURA2_DECODER) += aura.o -OBJS-$(CONFIG_AVS_DECODER) += avs.o -OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o -OBJS-$(CONFIG_BFI_DECODER) += bfi.o -OBJS-$(CONFIG_BINK_DECODER) += bink.o binkidct.o -OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o -OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o -OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o -OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o -OBJS-$(CONFIG_C93_DECODER) += c93.o -OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \ - mpeg12data.o mpegvideo.o -OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o -OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o -OBJS-$(CONFIG_CLJR_DECODER) += cljr.o -OBJS-$(CONFIG_CLJR_ENCODER) += cljr.o -OBJS-$(CONFIG_COOK_DECODER) += cook.o -OBJS-$(CONFIG_CSCD_DECODER) += cscd.o -OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o -OBJS-$(CONFIG_DCA_DECODER) += dca.o synth_filter.o dcadsp.o -OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o -OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o \ - mpegvideo_enc.o motion_est.o \ - ratecontrol.o mpeg12data.o \ - mpegvideo.o -OBJS-$(CONFIG_DPX_DECODER) += dpx.o -OBJS-$(CONFIG_DSICINAUDIO_DECODER) += dsicinav.o -OBJS-$(CONFIG_DSICINVIDEO_DECODER) += dsicinav.o -OBJS-$(CONFIG_DVBSUB_DECODER) += dvbsubdec.o -OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsub.o -OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o -OBJS-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.o -OBJS-$(CONFIG_DVVIDEO_DECODER) += dv.o dvdata.o -OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o -OBJS-$(CONFIG_DXA_DECODER) += dxa.o -OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3dec_data.o -OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o -OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \ - mpeg12data.o mpegvideo.o \ - error_resilience.o -OBJS-$(CONFIG_EATGQ_DECODER) += eatgq.o eaidct.o -OBJS-$(CONFIG_EATGV_DECODER) += eatgv.o -OBJS-$(CONFIG_EATQI_DECODER) += eatqi.o eaidct.o mpeg12.o \ - mpeg12data.o mpegvideo.o \ - error_resilience.o -OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o -OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.o -OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o -OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o -OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o rangecoder.o -OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o rangecoder.o -OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o -OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o -OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o -OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o -OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o -OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o -OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o -OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o huffman.o -OBJS-$(CONFIG_FRWU_DECODER) += frwu.o -OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o -OBJS-$(CONFIG_GIF_ENCODER) += gif.o lzwenc.o -OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_H261_ENCODER) += h261enc.o h261.o \ - mpegvideo_enc.o motion_est.o \ - ratecontrol.o mpeg12data.o \ - mpegvideo.o -OBJS-$(CONFIG_H263_DECODER) += h263dec.o h263.o ituh263dec.o \ - mpeg4video.o mpeg4videodec.o flvdec.o\ - intelh263dec.o mpegvideo.o \ - error_resilience.o -OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o -OBJS-$(CONFIG_H263_ENCODER) += mpegvideo_enc.o mpeg4video.o \ - mpeg4videoenc.o motion_est.o \ - ratecontrol.o h263.o ituh263enc.o \ - flvenc.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_H264_DECODER) += h264.o \ - h264_loopfilter.o h264_direct.o \ - cabac.o h264_sei.o h264_ps.o \ - h264_refs.o h264_cavlc.o h264_cabac.o\ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o -OBJS-$(CONFIG_H264_ENCODER) += h264enc.o h264dspenc.o -OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o -OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o -OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o -OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o -OBJS-$(CONFIG_IFF_BYTERUN1_DECODER) += iff.o -OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o -OBJS-$(CONFIG_IMC_DECODER) += imc.o -OBJS-$(CONFIG_INDEO2_DECODER) += indeo2.o -OBJS-$(CONFIG_INDEO3_DECODER) += indeo3.o -OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi_common.o ivi_dsp.o -OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o -OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o -OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o \ - mjpegdec.o mjpeg.o -OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o -OBJS-$(CONFIG_KGV1_DECODER) += kgv1dec.o -OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o -OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc.o mjpeg.o \ - mpegvideo_enc.o motion_est.o \ - ratecontrol.o mpeg12data.o \ - mpegvideo.o -OBJS-$(CONFIG_LOCO_DECODER) += loco.o -OBJS-$(CONFIG_MACE3_DECODER) += mace.o -OBJS-$(CONFIG_MACE6_DECODER) += mace.o -OBJS-$(CONFIG_MDEC_DECODER) += mdec.o mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o -OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o -OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpeg.o \ - mpegvideo_enc.o motion_est.o \ - ratecontrol.o mpeg12data.o \ - mpegvideo.o -OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o mjpegdec.o mjpeg.o -OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o -OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o -OBJS-$(CONFIG_MOTIONPIXELS_DECODER) += motionpixels.o -OBJS-$(CONFIG_MP1_DECODER) += mpegaudiodec.o mpegaudiodecheader.o \ - mpegaudio.o mpegaudiodata.o -OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec.o mpegaudiodecheader.o \ - mpegaudio.o mpegaudiodata.o -OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o \ - mpegaudiodata.o -OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec.o mpegaudiodecheader.o \ - mpegaudio.o mpegaudiodata.o -OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec.o mpegaudiodecheader.o \ - mpegaudio.o mpegaudiodata.o \ - mpeg4audio.o -OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec.o mpegaudiodecheader.o \ - mpegaudio.o mpegaudiodata.o -OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o mpegaudiodec.o \ - mpegaudiodecheader.o mpegaudio.o \ - mpegaudiodata.o -OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o mpegaudiodec.o \ - mpegaudiodecheader.o mpegaudio.o \ - mpegaudiodata.o -OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MPEG_XVMC_DECODER) += mpegvideo_xvmc.o -OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ - motion_est.o ratecontrol.o \ - mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o -OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ - motion_est.o ratecontrol.o \ - mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o -OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o -OBJS-$(CONFIG_MSMPEG4V1_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o -OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o -OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o -OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o -OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o -OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o -OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o -OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o -OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o -OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o -OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o -OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o pnm.o -OBJS-$(CONFIG_PBM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PCX_DECODER) += pcx.o -OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o -OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o -OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o -OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o -OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PTX_DECODER) += ptx.o -OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o celp_math.o \ - celp_filters.o acelp_vectors.o \ - acelp_filters.o -OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o mpegaudiodec.o \ - mpegaudiodecheader.o mpegaudio.o \ - mpegaudiodata.o -OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o -OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o -OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o -OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o -OBJS-$(CONFIG_R210_DECODER) += r210dec.o -OBJS-$(CONFIG_RA_144_DECODER) += ra144.o celp_filters.o -OBJS-$(CONFIG_RA_288_DECODER) += ra288.o celp_math.o celp_filters.o -OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o -OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o -OBJS-$(CONFIG_RL2_DECODER) += rl2.o -OBJS-$(CONFIG_ROQ_DECODER) += roqvideodec.o roqvideo.o -OBJS-$(CONFIG_ROQ_ENCODER) += roqvideoenc.o roqvideo.o elbg.o -OBJS-$(CONFIG_ROQ_DPCM_DECODER) += dpcm.o -OBJS-$(CONFIG_ROQ_DPCM_ENCODER) += roqaudioenc.o -OBJS-$(CONFIG_RPZA_DECODER) += rpza.o -OBJS-$(CONFIG_RV10_DECODER) += rv10.o -OBJS-$(CONFIG_RV10_ENCODER) += rv10enc.o -OBJS-$(CONFIG_RV20_DECODER) += rv10.o -OBJS-$(CONFIG_RV20_ENCODER) += rv20enc.o -OBJS-$(CONFIG_RV30_DECODER) += rv30.o rv34.o rv30dsp.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_RV40_DECODER) += rv40.o rv34.o rv40dsp.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_SGI_DECODER) += sgidec.o -OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o -OBJS-$(CONFIG_SHORTEN_DECODER) += shorten.o -OBJS-$(CONFIG_SIPR_DECODER) += sipr.o acelp_pitch_delay.o \ - celp_math.o acelp_vectors.o \ - acelp_filters.o celp_filters.o \ - sipr16k.o -OBJS-$(CONFIG_SMACKAUD_DECODER) += smacker.o -OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o -OBJS-$(CONFIG_SMC_DECODER) += smc.o -OBJS-$(CONFIG_SNOW_DECODER) += snow.o rangecoder.o -OBJS-$(CONFIG_SNOW_ENCODER) += snow.o rangecoder.o motion_est.o \ - ratecontrol.o h263.o \ - mpegvideo.o error_resilience.o \ - ituh263enc.o mpegvideo_enc.o \ - mpeg12data.o -OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o -OBJS-$(CONFIG_SONIC_DECODER) += sonic.o -OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o -OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o -OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o -OBJS-$(CONFIG_SUNRAST_DECODER) += sunrast.o -OBJS-$(CONFIG_SVQ1_DECODER) += svq1dec.o svq1.o h263.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_SVQ1_ENCODER) += svq1enc.o svq1.o \ - motion_est.o h263.o \ - mpegvideo.o error_resilience.o \ - ituh263enc.o mpegvideo_enc.o \ - ratecontrol.o mpeg12data.o -OBJS-$(CONFIG_SVQ3_DECODER) += h264.o svq3.o \ - h264_loopfilter.o h264_direct.o \ - h264_sei.o h264_ps.o h264_refs.o \ - h264_cavlc.o h264_cabac.o cabac.o \ - mpegvideo.o error_resilience.o \ - svq1dec.o svq1.o h263.o -OBJS-$(CONFIG_TARGA_DECODER) += targa.o -OBJS-$(CONFIG_TARGA_ENCODER) += targaenc.o rle.o -OBJS-$(CONFIG_THEORA_DECODER) += xiph.o -OBJS-$(CONFIG_THP_DECODER) += mjpegdec.o mjpeg.o -OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o -OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o faxcompr.o -OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o -OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o -OBJS-$(CONFIG_TRUEMOTION1_DECODER) += truemotion1.o -OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o -OBJS-$(CONFIG_TRUESPEECH_DECODER) += truespeech.o -OBJS-$(CONFIG_TSCC_DECODER) += tscc.o msrledec.o -OBJS-$(CONFIG_TTA_DECODER) += tta.o -OBJS-$(CONFIG_TWINVQ_DECODER) += twinvq.o celp_math.o -OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o -OBJS-$(CONFIG_ULTI_DECODER) += ulti.o -OBJS-$(CONFIG_V210_DECODER) += v210dec.o -OBJS-$(CONFIG_V210_ENCODER) += v210enc.o -OBJS-$(CONFIG_V210X_DECODER) += v210x.o -OBJS-$(CONFIG_VB_DECODER) += vb.o -OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \ - msmpeg4.o msmpeg4data.o \ - intrax8.o intrax8dsp.o -OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o -OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o -OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o -OBJS-$(CONFIG_VCR1_ENCODER) += vcr1.o -OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o -OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdav.o -OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o -OBJS-$(CONFIG_VORBIS_DECODER) += vorbis_dec.o vorbis.o \ - vorbis_data.o xiph.o -OBJS-$(CONFIG_VORBIS_ENCODER) += vorbis_enc.o vorbis.o \ - vorbis_data.o -OBJS-$(CONFIG_VP3_DECODER) += vp3.o vp3dsp.o -OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56dsp.o \ - vp3dsp.o -OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp56dsp.o \ - vp3dsp.o vp6dsp.o huffman.o -OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o -OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o -OBJS-$(CONFIG_WMAPRO_DECODER) += wmaprodec.o wma.o -OBJS-$(CONFIG_WMAV1_DECODER) += wmadec.o wma.o aactab.o -OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o aactab.o -OBJS-$(CONFIG_WMAV2_DECODER) += wmadec.o wma.o aactab.o -OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o aactab.o -OBJS-$(CONFIG_WMAVOICE_DECODER) += wmavoice.o \ - celp_math.o celp_filters.o \ - acelp_vectors.o acelp_filters.o -OBJS-$(CONFIG_WMV1_DECODER) += msmpeg4.o msmpeg4data.o -OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o \ - msmpeg4.o msmpeg4data.o \ - intrax8.o intrax8dsp.o -OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o \ - msmpeg4.o msmpeg4data.o \ - mpeg4videodec.o ituh263dec.o h263dec.o -OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o -OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o -OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o -OBJS-$(CONFIG_XAN_WC3_DECODER) += xan.o -OBJS-$(CONFIG_XAN_WC4_DECODER) += xan.o -OBJS-$(CONFIG_XL_DECODER) += xl.o -OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o -OBJS-$(CONFIG_XSUB_ENCODER) += xsubenc.o -OBJS-$(CONFIG_YOP_DECODER) += yop.o -OBJS-$(CONFIG_ZLIB_DECODER) += lcldec.o -OBJS-$(CONFIG_ZLIB_ENCODER) += lclenc.o -OBJS-$(CONFIG_ZMBV_DECODER) += zmbv.o -OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o - -# (AD)PCM decoders/encoders -OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-mpeg.o -OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_DVD_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_F32BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_F32BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_F32LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_F32LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_F64BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_F64BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_F64LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_F64LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_MULAW_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S8_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S8_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S16BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S16BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S16LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S16LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S16LE_PLANAR_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S24DAUD_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24DAUD_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S24LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S32BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S32BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S32LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S32LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U8_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U8_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U16BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U16BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U16LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U16LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U24BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U24BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U24LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U24LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U32BE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U32BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U32LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_ZORK_ENCODER) += pcm.o - -OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o -OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o -OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_MAXIS_XA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o -OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o -OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SWF_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SWF_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcm.o - -# libavformat dependencies -OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o -OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o -OBJS-$(CONFIG_DV_DEMUXER) += dvdata.o -OBJS-$(CONFIG_DV_MUXER) += dvdata.o -OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o -OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o -OBJS-$(CONFIG_IFF_DEMUXER) += iff.o -OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o \ - flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o -OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o \ - flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o -OBJS-$(CONFIG_MPEGTS_MUXER) += mpegvideo.o mpeg4audio.o -OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o -OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o flac.o \ - dirac.o mpeg12data.o -OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_RTP_MUXER) += mpegvideo.o -OBJS-$(CONFIG_WEBM_MUXER) += xiph.o mpeg4audio.o \ - flacdec.o flacdata.o flac.o - -# external codec libraries -OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o -OBJS-$(CONFIG_LIBDIRAC_ENCODER) += libdiracenc.o libdirac_libschro.o -OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o -OBJS-$(CONFIG_LIBFAAD_DECODER) += libfaad.o -OBJS-$(CONFIG_LIBGSM_DECODER) += libgsm.o -OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o -OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsm.o -OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsm.o -OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o -OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o -OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o -OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o -OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpeg.o -OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ - libschroedinger.o \ - libdirac_libschro.o -OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ - libschroedinger.o \ - libdirac_libschro.o -OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o -OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o -OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbis.o -OBJS-$(CONFIG_LIBVPX_DECODER) += libvpxdec.o -OBJS-$(CONFIG_LIBVPX_ENCODER) += libvpxenc.o -OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o -OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvidff.o libxvid_rc.o - -# parsers -OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \ - mpeg4audio.o -OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \ - aac_ac3_parser.o -OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o -OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o -OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o -OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o -OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o -OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o -OBJS-$(CONFIG_H261_PARSER) += h261_parser.o -OBJS-$(CONFIG_H263_PARSER) += h263_parser.o -OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264.o \ - cabac.o \ - h264_refs.o h264_sei.o h264_direct.o \ - h264_loopfilter.o h264_cabac.o \ - h264_cavlc.o h264_ps.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o -OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o -OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \ - mpegvideo.o error_resilience.o \ - mpeg4videodec.o mpeg4video.o \ - ituh263dec.o h263dec.o -OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o \ - mpegaudiodecheader.o mpegaudiodata.o -OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \ - mpeg12.o mpeg12data.o \ - mpegvideo.o error_resilience.o -OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o -OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \ - msmpeg4.o msmpeg4data.o mpeg4video.o \ - h263.o mpegvideo.o error_resilience.o -OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o - -# bitstream filters -OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o -OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o -OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o -OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o -OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o -OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o -OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF) += mp3_header_compress_bsf.o -OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o \ - mpegaudiodata.o -OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o -OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o -OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o - -# thread libraries -OBJS-$(HAVE_BEOSTHREADS) += beosthread.o -OBJS-$(HAVE_OS2THREADS) += os2thread.o -OBJS-$(HAVE_PTHREADS) += pthread.o -OBJS-$(HAVE_W32THREADS) += w32thread.o - -OBJS-$(CONFIG_MLIB) += mlib/dsputil_mlib.o \ - --include $(SUBDIR)$(ARCH)/Makefile - -SKIPHEADERS = %_tablegen.h -SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h -SKIPHEADERS-$(CONFIG_LIBDIRAC) += libdirac.h -SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h -SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h -SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h -SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h -SKIPHEADERS += mpegaudio3.h - -EXAMPLES = api - -TESTPROGS = cabac dct eval fft h264 iirfilter rangecoder snow -TESTPROGS-$(ARCH_X86) += x86/cpuid -TESTPROGS-$(HAVE_MMX) += motion -TESTOBJS = dctref.o - -HOSTPROGS = costablegen - -DIRS = alpha arm bfin mlib ppc ps2 sh4 sparc x86 - -CLEANFILES = sin_tables.c cos_tables.c *_tables.h *_tablegen$(HOSTEXESUF) - -include $(SUBDIR)../subdir.mak - -$(SUBDIR)dct-test$(EXESUF): $(SUBDIR)dctref.o - -$(SUBDIR)cos_tables.c: $(SUBDIR)costablegen$(HOSTEXESUF) - $(M)./$< > $@ - -$(SUBDIR)sin_tables.c: $(SUBDIR)costablegen$(HOSTEXESUF) - $(M)./$< sin > $@ - -ifdef CONFIG_MPEGAUDIO_HP -$(SUBDIR)mpegaudio_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DFRAC_BITS=23 -$(SUBDIR)mpegaudio_tablegen.ho: CPPFLAGS += -DFRAC_BITS=23 -else -$(SUBDIR)mpegaudio_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DFRAC_BITS=15 -$(SUBDIR)mpegaudio_tablegen.ho: CPPFLAGS += -DFRAC_BITS=15 -endif - -ifdef CONFIG_SMALL -$(SUBDIR)%_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DCONFIG_SMALL=1 -else -$(SUBDIR)%_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DCONFIG_SMALL=0 -endif - -$(SUBDIR)%_tablegen$(HOSTEXESUF): $(SUBDIR)%_tablegen.c $(SUBDIR)tableprint.c - $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS) - -$(SUBDIR)%_tables.h: $(SUBDIR)%_tablegen$(HOSTEXESUF) - $(M)./$< > $@ - -ifdef CONFIG_HARDCODED_TABLES -$(SUBDIR)aac.o: $(SUBDIR)cbrt_tables.h -$(SUBDIR)dv.o: $(SUBDIR)dv_tables.h -$(SUBDIR)mdct.o: $(SUBDIR)mdct_tables.h -$(SUBDIR)mpegaudiodec.o: $(SUBDIR)mpegaudio_tables.h -$(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h -$(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h -$(SUBDIR)qdm2.o: $(SUBDIR)qdm2_tables.h -endif diff --git a/tizen/distrib/ffmpeg/libavcodec/aac.c b/tizen/distrib/ffmpeg/libavcodec/aac.c deleted file mode 100644 index 3330e1c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aac.c +++ /dev/null @@ -1,2108 +0,0 @@ -/* - * AAC decoder - * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) - * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC decoder - * @author Oded Shimon ( ods15 ods15 dyndns org ) - * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) - */ - -/* - * supported tools - * - * Support? Name - * N (code in SoC repo) gain control - * Y block switching - * Y window shapes - standard - * N window shapes - Low Delay - * Y filterbank - standard - * N (code in SoC repo) filterbank - Scalable Sample Rate - * Y Temporal Noise Shaping - * N (code in SoC repo) Long Term Prediction - * Y intensity stereo - * Y channel coupling - * Y frequency domain prediction - * Y Perceptual Noise Substitution - * Y Mid/Side stereo - * N Scalable Inverse AAC Quantization - * N Frequency Selective Switch - * N upsampling filter - * Y quantization & coding - AAC - * N quantization & coding - TwinVQ - * N quantization & coding - BSAC - * N AAC Error Resilience tools - * N Error Resilience payload syntax - * N Error Protection tool - * N CELP - * N Silence Compression - * N HVXC - * N HVXC 4kbits/s VR - * N Structured Audio tools - * N Structured Audio Sample Bank Format - * N MIDI - * N Harmonic and Individual Lines plus Noise - * N Text-To-Speech Interface - * Y Spectral Band Replication - * Y (not in this code) Layer-1 - * Y (not in this code) Layer-2 - * Y (not in this code) Layer-3 - * N SinuSoidal Coding (Transient, Sinusoid, Noise) - * N (planned) Parametric Stereo - * N Direct Stream Transfer - * - * Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication. - * - HE AAC v2 comprises LC AAC with Spectral Band Replication and - Parametric Stereo. - */ - - -#include "avcodec.h" -#include "internal.h" -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" -#include "lpc.h" - -#include "aac.h" -#include "aactab.h" -#include "aacdectab.h" -#include "cbrt_tablegen.h" -#include "sbr.h" -#include "aacsbr.h" -#include "mpeg4audio.h" -#include "aac_parser.h" - -#include -#include -#include -#include - -#if ARCH_ARM -# include "arm/aac.h" -#endif - -union float754 { - float f; - uint32_t i; -}; - -static VLC vlc_scalefactors; -static VLC vlc_spectral[11]; - -static const char overread_err[] = "Input buffer exhausted before END element found\n"; - -static ChannelElement *get_che(AACContext *ac, int type, int elem_id) -{ - if (ac->tag_che_map[type][elem_id]) { - return ac->tag_che_map[type][elem_id]; - } - if (ac->tags_mapped >= tags_per_config[ac->m4ac.chan_config]) { - return NULL; - } - switch (ac->m4ac.chan_config) { - case 7: - if (ac->tags_mapped == 3 && type == TYPE_CPE) { - ac->tags_mapped++; - return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2]; - } - case 6: - /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1] - instead of SCE[0] CPE[0] CPE[0] LFE[0]. If we seem to have - encountered such a stream, transfer the LFE[0] element to SCE[1] */ - if (ac->tags_mapped == tags_per_config[ac->m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) { - ac->tags_mapped++; - return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0]; - } - case 5: - if (ac->tags_mapped == 2 && type == TYPE_CPE) { - ac->tags_mapped++; - return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1]; - } - case 4: - if (ac->tags_mapped == 2 && ac->m4ac.chan_config == 4 && type == TYPE_SCE) { - ac->tags_mapped++; - return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1]; - } - case 3: - case 2: - if (ac->tags_mapped == (ac->m4ac.chan_config != 2) && type == TYPE_CPE) { - ac->tags_mapped++; - return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0]; - } else if (ac->m4ac.chan_config == 2) { - return NULL; - } - case 1: - if (!ac->tags_mapped && type == TYPE_SCE) { - ac->tags_mapped++; - return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][0]; - } - default: - return NULL; - } -} - -/** - * Check for the channel element in the current channel position configuration. - * If it exists, make sure the appropriate element is allocated and map the - * channel order to match the internal FFmpeg channel layout. - * - * @param che_pos current channel position configuration - * @param type channel element type - * @param id channel element id - * @param channels count of the number of channels in the configuration - * - * @return Returns error status. 0 - OK, !0 - error - */ -static av_cold int che_configure(AACContext *ac, - enum ChannelPosition che_pos[4][MAX_ELEM_ID], - int type, int id, - int *channels) -{ - if (che_pos[type][id]) { - if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) - return AVERROR(ENOMEM); - ff_aac_sbr_ctx_init(&ac->che[type][id]->sbr); - if (type != TYPE_CCE) { - ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret; - if (type == TYPE_CPE) { - ac->output_data[(*channels)++] = ac->che[type][id]->ch[1].ret; - } - } - } else { - if (ac->che[type][id]) - ff_aac_sbr_ctx_close(&ac->che[type][id]->sbr); - av_freep(&ac->che[type][id]); - } - return 0; -} - -/** - * Configure output channel order based on the current program configuration element. - * - * @param che_pos current channel position configuration - * @param new_che_pos New channel position configuration - we only do something if it differs from the current one. - * - * @return Returns error status. 0 - OK, !0 - error - */ -static av_cold int output_configure(AACContext *ac, - enum ChannelPosition che_pos[4][MAX_ELEM_ID], - enum ChannelPosition new_che_pos[4][MAX_ELEM_ID], - int channel_config, enum OCStatus oc_type) -{ - AVCodecContext *avctx = ac->avccontext; - int i, type, channels = 0, ret; - - memcpy(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])); - - if (channel_config) { - for (i = 0; i < tags_per_config[channel_config]; i++) { - if ((ret = che_configure(ac, che_pos, - aac_channel_layout_map[channel_config - 1][i][0], - aac_channel_layout_map[channel_config - 1][i][1], - &channels))) - return ret; - } - - memset(ac->tag_che_map, 0, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); - ac->tags_mapped = 0; - - avctx->channel_layout = aac_channel_layout[channel_config - 1]; - } else { - /* Allocate or free elements depending on if they are in the - * current program configuration. - * - * Set up default 1:1 output mapping. - * - * For a 5.1 stream the output order will be: - * [ Center ] [ Front Left ] [ Front Right ] [ LFE ] [ Surround Left ] [ Surround Right ] - */ - - for (i = 0; i < MAX_ELEM_ID; i++) { - for (type = 0; type < 4; type++) { - if ((ret = che_configure(ac, che_pos, type, i, &channels))) - return ret; - } - } - - memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); - ac->tags_mapped = 4 * MAX_ELEM_ID; - - avctx->channel_layout = 0; - } - - avctx->channels = channels; - - ac->output_configured = oc_type; - - return 0; -} - -/** - * Decode an array of 4 bit element IDs, optionally interleaved with a stereo/mono switching bit. - * - * @param cpe_map Stereo (Channel Pair Element) map, NULL if stereo bit is not present. - * @param sce_map mono (Single Channel Element) map - * @param type speaker type/position for these channels - */ -static void decode_channel_map(enum ChannelPosition *cpe_map, - enum ChannelPosition *sce_map, - enum ChannelPosition type, - GetBitContext *gb, int n) -{ - while (n--) { - enum ChannelPosition *map = cpe_map && get_bits1(gb) ? cpe_map : sce_map; // stereo or mono map - map[get_bits(gb, 4)] = type; - } -} - -/** - * Decode program configuration element; reference: table 4.2. - * - * @param new_che_pos New channel position configuration - we only do something if it differs from the current one. - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_pce(AACContext *ac, enum ChannelPosition new_che_pos[4][MAX_ELEM_ID], - GetBitContext *gb) -{ - int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc, sampling_index; - int comment_len; - - skip_bits(gb, 2); // object_type - - sampling_index = get_bits(gb, 4); - if (ac->m4ac.sampling_index != sampling_index) - av_log(ac->avccontext, AV_LOG_WARNING, "Sample rate index in program config element does not match the sample rate index configured by the container.\n"); - - num_front = get_bits(gb, 4); - num_side = get_bits(gb, 4); - num_back = get_bits(gb, 4); - num_lfe = get_bits(gb, 2); - num_assoc_data = get_bits(gb, 3); - num_cc = get_bits(gb, 4); - - if (get_bits1(gb)) - skip_bits(gb, 4); // mono_mixdown_tag - if (get_bits1(gb)) - skip_bits(gb, 4); // stereo_mixdown_tag - - if (get_bits1(gb)) - skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround - - decode_channel_map(new_che_pos[TYPE_CPE], new_che_pos[TYPE_SCE], AAC_CHANNEL_FRONT, gb, num_front); - decode_channel_map(new_che_pos[TYPE_CPE], new_che_pos[TYPE_SCE], AAC_CHANNEL_SIDE, gb, num_side ); - decode_channel_map(new_che_pos[TYPE_CPE], new_che_pos[TYPE_SCE], AAC_CHANNEL_BACK, gb, num_back ); - decode_channel_map(NULL, new_che_pos[TYPE_LFE], AAC_CHANNEL_LFE, gb, num_lfe ); - - skip_bits_long(gb, 4 * num_assoc_data); - - decode_channel_map(new_che_pos[TYPE_CCE], new_che_pos[TYPE_CCE], AAC_CHANNEL_CC, gb, num_cc ); - - align_get_bits(gb); - - /* comment field, first byte is length */ - comment_len = get_bits(gb, 8) * 8; - if (get_bits_left(gb) < comment_len) { - av_log(ac->avccontext, AV_LOG_ERROR, overread_err); - return -1; - } - skip_bits_long(gb, comment_len); - return 0; -} - -/** - * Set up channel positions based on a default channel configuration - * as specified in table 1.17. - * - * @param new_che_pos New channel position configuration - we only do something if it differs from the current one. - * - * @return Returns error status. 0 - OK, !0 - error - */ -static av_cold int set_default_channel_config(AACContext *ac, - enum ChannelPosition new_che_pos[4][MAX_ELEM_ID], - int channel_config) -{ - if (channel_config < 1 || channel_config > 7) { - av_log(ac->avccontext, AV_LOG_ERROR, "invalid default channel configuration (%d)\n", - channel_config); - return -1; - } - - /* default channel configurations: - * - * 1ch : front center (mono) - * 2ch : L + R (stereo) - * 3ch : front center + L + R - * 4ch : front center + L + R + back center - * 5ch : front center + L + R + back stereo - * 6ch : front center + L + R + back stereo + LFE - * 7ch : front center + L + R + outer front left + outer front right + back stereo + LFE - */ - - if (channel_config != 2) - new_che_pos[TYPE_SCE][0] = AAC_CHANNEL_FRONT; // front center (or mono) - if (channel_config > 1) - new_che_pos[TYPE_CPE][0] = AAC_CHANNEL_FRONT; // L + R (or stereo) - if (channel_config == 4) - new_che_pos[TYPE_SCE][1] = AAC_CHANNEL_BACK; // back center - if (channel_config > 4) - new_che_pos[TYPE_CPE][(channel_config == 7) + 1] - = AAC_CHANNEL_BACK; // back stereo - if (channel_config > 5) - new_che_pos[TYPE_LFE][0] = AAC_CHANNEL_LFE; // LFE - if (channel_config == 7) - new_che_pos[TYPE_CPE][1] = AAC_CHANNEL_FRONT; // outer front left + outer front right - - return 0; -} - -/** - * Decode GA "General Audio" specific configuration; reference: table 4.1. - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_ga_specific_config(AACContext *ac, GetBitContext *gb, - int channel_config) -{ - enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]; - int extension_flag, ret; - - if (get_bits1(gb)) { // frameLengthFlag - av_log_missing_feature(ac->avccontext, "960/120 MDCT window is", 1); - return -1; - } - - if (get_bits1(gb)) // dependsOnCoreCoder - skip_bits(gb, 14); // coreCoderDelay - extension_flag = get_bits1(gb); - - if (ac->m4ac.object_type == AOT_AAC_SCALABLE || - ac->m4ac.object_type == AOT_ER_AAC_SCALABLE) - skip_bits(gb, 3); // layerNr - - memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])); - if (channel_config == 0) { - skip_bits(gb, 4); // element_instance_tag - if ((ret = decode_pce(ac, new_che_pos, gb))) - return ret; - } else { - if ((ret = set_default_channel_config(ac, new_che_pos, channel_config))) - return ret; - } - if ((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config, OC_GLOBAL_HDR))) - return ret; - - if (extension_flag) { - switch (ac->m4ac.object_type) { - case AOT_ER_BSAC: - skip_bits(gb, 5); // numOfSubFrame - skip_bits(gb, 11); // layer_length - break; - case AOT_ER_AAC_LC: - case AOT_ER_AAC_LTP: - case AOT_ER_AAC_SCALABLE: - case AOT_ER_AAC_LD: - skip_bits(gb, 3); /* aacSectionDataResilienceFlag - * aacScalefactorDataResilienceFlag - * aacSpectralDataResilienceFlag - */ - break; - } - skip_bits1(gb); // extensionFlag3 (TBD in version 3) - } - return 0; -} - -/** - * Decode audio specific configuration; reference: table 1.13. - * - * @param data pointer to AVCodecContext extradata - * @param data_size size of AVCCodecContext extradata - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_audio_specific_config(AACContext *ac, void *data, - int data_size) -{ - GetBitContext gb; - int i; - - init_get_bits(&gb, data, data_size * 8); - - if ((i = ff_mpeg4audio_get_config(&ac->m4ac, data, data_size)) < 0) - return -1; - if (ac->m4ac.sampling_index > 12) { - av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index); - return -1; - } - - skip_bits_long(&gb, i); - - switch (ac->m4ac.object_type) { - case AOT_AAC_MAIN: - case AOT_AAC_LC: - if (decode_ga_specific_config(ac, &gb, ac->m4ac.chan_config)) - return -1; - break; - default: - av_log(ac->avccontext, AV_LOG_ERROR, "Audio object type %s%d is not supported.\n", - ac->m4ac.sbr == 1? "SBR+" : "", ac->m4ac.object_type); - return -1; - } - return 0; -} - -/** - * linear congruential pseudorandom number generator - * - * @param previous_val pointer to the current state of the generator - * - * @return Returns a 32-bit pseudorandom integer - */ -static av_always_inline int lcg_random(int previous_val) -{ - return previous_val * 1664525 + 1013904223; -} - -static av_always_inline void reset_predict_state(PredictorState *ps) -{ - ps->r0 = 0.0f; - ps->r1 = 0.0f; - ps->cor0 = 0.0f; - ps->cor1 = 0.0f; - ps->var0 = 1.0f; - ps->var1 = 1.0f; -} - -static void reset_all_predictors(PredictorState *ps) -{ - int i; - for (i = 0; i < MAX_PREDICTORS; i++) - reset_predict_state(&ps[i]); -} - -static void reset_predictor_group(PredictorState *ps, int group_num) -{ - int i; - for (i = group_num - 1; i < MAX_PREDICTORS; i += 30) - reset_predict_state(&ps[i]); -} - -static av_cold int aac_decode_init(AVCodecContext *avccontext) -{ - AACContext *ac = avccontext->priv_data; - int i; - - ac->avccontext = avccontext; - ac->m4ac.sample_rate = avccontext->sample_rate; - - if (avccontext->extradata_size > 0) { - if (decode_audio_specific_config(ac, avccontext->extradata, avccontext->extradata_size)) - return -1; - } - - avccontext->sample_fmt = SAMPLE_FMT_S16; - - AAC_INIT_VLC_STATIC( 0, 304); - AAC_INIT_VLC_STATIC( 1, 270); - AAC_INIT_VLC_STATIC( 2, 550); - AAC_INIT_VLC_STATIC( 3, 300); - AAC_INIT_VLC_STATIC( 4, 328); - AAC_INIT_VLC_STATIC( 5, 294); - AAC_INIT_VLC_STATIC( 6, 306); - AAC_INIT_VLC_STATIC( 7, 268); - AAC_INIT_VLC_STATIC( 8, 510); - AAC_INIT_VLC_STATIC( 9, 366); - AAC_INIT_VLC_STATIC(10, 462); - - ff_aac_sbr_init(); - - dsputil_init(&ac->dsp, avccontext); - - ac->random_state = 0x1f2e3d4c; - - // -1024 - Compensate wrong IMDCT method. - // 32768 - Required to scale values to the correct range for the bias method - // for float to int16 conversion. - - if (ac->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { - ac->add_bias = 385.0f; - ac->sf_scale = 1. / (-1024. * 32768.); - ac->sf_offset = 0; - } else { - ac->add_bias = 0.0f; - ac->sf_scale = 1. / -1024.; - ac->sf_offset = 60; - } - -#if !CONFIG_HARDCODED_TABLES - for (i = 0; i < 428; i++) - ff_aac_pow2sf_tab[i] = pow(2, (i - 200) / 4.); -#endif /* CONFIG_HARDCODED_TABLES */ - - INIT_VLC_STATIC(&vlc_scalefactors,7,FF_ARRAY_ELEMS(ff_aac_scalefactor_code), - ff_aac_scalefactor_bits, sizeof(ff_aac_scalefactor_bits[0]), sizeof(ff_aac_scalefactor_bits[0]), - ff_aac_scalefactor_code, sizeof(ff_aac_scalefactor_code[0]), sizeof(ff_aac_scalefactor_code[0]), - 352); - - ff_mdct_init(&ac->mdct, 11, 1, 1.0); - ff_mdct_init(&ac->mdct_small, 8, 1, 1.0); - // window initialization - ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); - ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); - ff_init_ff_sine_windows(10); - ff_init_ff_sine_windows( 7); - - cbrt_tableinit(); - - return 0; -} - -/** - * Skip data_stream_element; reference: table 4.10. - */ -static int skip_data_stream_element(AACContext *ac, GetBitContext *gb) -{ - int byte_align = get_bits1(gb); - int count = get_bits(gb, 8); - if (count == 255) - count += get_bits(gb, 8); - if (byte_align) - align_get_bits(gb); - - if (get_bits_left(gb) < 8 * count) { - av_log(ac->avccontext, AV_LOG_ERROR, overread_err); - return -1; - } - skip_bits_long(gb, 8 * count); - return 0; -} - -static int decode_prediction(AACContext *ac, IndividualChannelStream *ics, - GetBitContext *gb) -{ - int sfb; - if (get_bits1(gb)) { - ics->predictor_reset_group = get_bits(gb, 5); - if (ics->predictor_reset_group == 0 || ics->predictor_reset_group > 30) { - av_log(ac->avccontext, AV_LOG_ERROR, "Invalid Predictor Reset Group.\n"); - return -1; - } - } - for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->m4ac.sampling_index]); sfb++) { - ics->prediction_used[sfb] = get_bits1(gb); - } - return 0; -} - -/** - * Decode Individual Channel Stream info; reference: table 4.6. - * - * @param common_window Channels have independent [0], or shared [1], Individual Channel Stream information. - */ -static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, - GetBitContext *gb, int common_window) -{ - if (get_bits1(gb)) { - av_log(ac->avccontext, AV_LOG_ERROR, "Reserved bit set.\n"); - memset(ics, 0, sizeof(IndividualChannelStream)); - return -1; - } - ics->window_sequence[1] = ics->window_sequence[0]; - ics->window_sequence[0] = get_bits(gb, 2); - ics->use_kb_window[1] = ics->use_kb_window[0]; - ics->use_kb_window[0] = get_bits1(gb); - ics->num_window_groups = 1; - ics->group_len[0] = 1; - if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - int i; - ics->max_sfb = get_bits(gb, 4); - for (i = 0; i < 7; i++) { - if (get_bits1(gb)) { - ics->group_len[ics->num_window_groups - 1]++; - } else { - ics->num_window_groups++; - ics->group_len[ics->num_window_groups - 1] = 1; - } - } - ics->num_windows = 8; - ics->swb_offset = ff_swb_offset_128[ac->m4ac.sampling_index]; - ics->num_swb = ff_aac_num_swb_128[ac->m4ac.sampling_index]; - ics->tns_max_bands = ff_tns_max_bands_128[ac->m4ac.sampling_index]; - ics->predictor_present = 0; - } else { - ics->max_sfb = get_bits(gb, 6); - ics->num_windows = 1; - ics->swb_offset = ff_swb_offset_1024[ac->m4ac.sampling_index]; - ics->num_swb = ff_aac_num_swb_1024[ac->m4ac.sampling_index]; - ics->tns_max_bands = ff_tns_max_bands_1024[ac->m4ac.sampling_index]; - ics->predictor_present = get_bits1(gb); - ics->predictor_reset_group = 0; - if (ics->predictor_present) { - if (ac->m4ac.object_type == AOT_AAC_MAIN) { - if (decode_prediction(ac, ics, gb)) { - memset(ics, 0, sizeof(IndividualChannelStream)); - return -1; - } - } else if (ac->m4ac.object_type == AOT_AAC_LC) { - av_log(ac->avccontext, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n"); - memset(ics, 0, sizeof(IndividualChannelStream)); - return -1; - } else { - av_log_missing_feature(ac->avccontext, "Predictor bit set but LTP is", 1); - memset(ics, 0, sizeof(IndividualChannelStream)); - return -1; - } - } - } - - if (ics->max_sfb > ics->num_swb) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Number of scalefactor bands in group (%d) exceeds limit (%d).\n", - ics->max_sfb, ics->num_swb); - memset(ics, 0, sizeof(IndividualChannelStream)); - return -1; - } - - return 0; -} - -/** - * Decode band types (section_data payload); reference: table 4.46. - * - * @param band_type array of the used band type - * @param band_type_run_end array of the last scalefactor band of a band type run - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_band_types(AACContext *ac, enum BandType band_type[120], - int band_type_run_end[120], GetBitContext *gb, - IndividualChannelStream *ics) -{ - int g, idx = 0; - const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5; - for (g = 0; g < ics->num_window_groups; g++) { - int k = 0; - while (k < ics->max_sfb) { - uint8_t sect_end = k; - int sect_len_incr; - int sect_band_type = get_bits(gb, 4); - if (sect_band_type == 12) { - av_log(ac->avccontext, AV_LOG_ERROR, "invalid band type\n"); - return -1; - } - while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1) - sect_end += sect_len_incr; - sect_end += sect_len_incr; - if (get_bits_left(gb) < 0) { - av_log(ac->avccontext, AV_LOG_ERROR, overread_err); - return -1; - } - if (sect_end > ics->max_sfb) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Number of bands (%d) exceeds limit (%d).\n", - sect_end, ics->max_sfb); - return -1; - } - for (; k < sect_end; k++) { - band_type [idx] = sect_band_type; - band_type_run_end[idx++] = sect_end; - } - } - } - return 0; -} - -/** - * Decode scalefactors; reference: table 4.47. - * - * @param global_gain first scalefactor value as scalefactors are differentially coded - * @param band_type array of the used band type - * @param band_type_run_end array of the last scalefactor band of a band type run - * @param sf array of scalefactors or intensity stereo positions - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, - unsigned int global_gain, - IndividualChannelStream *ics, - enum BandType band_type[120], - int band_type_run_end[120]) -{ - const int sf_offset = ac->sf_offset + (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE ? 12 : 0); - int g, i, idx = 0; - int offset[3] = { global_gain, global_gain - 90, 100 }; - int noise_flag = 1; - static const char *sf_str[3] = { "Global gain", "Noise gain", "Intensity stereo position" }; - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb;) { - int run_end = band_type_run_end[idx]; - if (band_type[idx] == ZERO_BT) { - for (; i < run_end; i++, idx++) - sf[idx] = 0.; - } else if ((band_type[idx] == INTENSITY_BT) || (band_type[idx] == INTENSITY_BT2)) { - for (; i < run_end; i++, idx++) { - offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; - if (offset[2] > 255U) { - av_log(ac->avccontext, AV_LOG_ERROR, - "%s (%d) out of range.\n", sf_str[2], offset[2]); - return -1; - } - sf[idx] = ff_aac_pow2sf_tab[-offset[2] + 300]; - } - } else if (band_type[idx] == NOISE_BT) { - for (; i < run_end; i++, idx++) { - if (noise_flag-- > 0) - offset[1] += get_bits(gb, 9) - 256; - else - offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; - if (offset[1] > 255U) { - av_log(ac->avccontext, AV_LOG_ERROR, - "%s (%d) out of range.\n", sf_str[1], offset[1]); - return -1; - } - sf[idx] = -ff_aac_pow2sf_tab[offset[1] + sf_offset + 100]; - } - } else { - for (; i < run_end; i++, idx++) { - offset[0] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; - if (offset[0] > 255U) { - av_log(ac->avccontext, AV_LOG_ERROR, - "%s (%d) out of range.\n", sf_str[0], offset[0]); - return -1; - } - sf[idx] = -ff_aac_pow2sf_tab[ offset[0] + sf_offset]; - } - } - } - } - return 0; -} - -/** - * Decode pulse data; reference: table 4.7. - */ -static int decode_pulses(Pulse *pulse, GetBitContext *gb, - const uint16_t *swb_offset, int num_swb) -{ - int i, pulse_swb; - pulse->num_pulse = get_bits(gb, 2) + 1; - pulse_swb = get_bits(gb, 6); - if (pulse_swb >= num_swb) - return -1; - pulse->pos[0] = swb_offset[pulse_swb]; - pulse->pos[0] += get_bits(gb, 5); - if (pulse->pos[0] > 1023) - return -1; - pulse->amp[0] = get_bits(gb, 4); - for (i = 1; i < pulse->num_pulse; i++) { - pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1]; - if (pulse->pos[i] > 1023) - return -1; - pulse->amp[i] = get_bits(gb, 4); - } - return 0; -} - -/** - * Decode Temporal Noise Shaping data; reference: table 4.48. - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns, - GetBitContext *gb, const IndividualChannelStream *ics) -{ - int w, filt, i, coef_len, coef_res, coef_compress; - const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE; - const int tns_max_order = is8 ? 7 : ac->m4ac.object_type == AOT_AAC_MAIN ? 20 : 12; - for (w = 0; w < ics->num_windows; w++) { - if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) { - coef_res = get_bits1(gb); - - for (filt = 0; filt < tns->n_filt[w]; filt++) { - int tmp2_idx; - tns->length[w][filt] = get_bits(gb, 6 - 2 * is8); - - if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) { - av_log(ac->avccontext, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.\n", - tns->order[w][filt], tns_max_order); - tns->order[w][filt] = 0; - return -1; - } - if (tns->order[w][filt]) { - tns->direction[w][filt] = get_bits1(gb); - coef_compress = get_bits1(gb); - coef_len = coef_res + 3 - coef_compress; - tmp2_idx = 2 * coef_compress + coef_res; - - for (i = 0; i < tns->order[w][filt]; i++) - tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)]; - } - } - } - } - return 0; -} - -/** - * Decode Mid/Side data; reference: table 4.54. - * - * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s; - * [1] mask is decoded from bitstream; [2] mask is all 1s; - * [3] reserved for scalable AAC - */ -static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb, - int ms_present) -{ - int idx; - if (ms_present == 1) { - for (idx = 0; idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; idx++) - cpe->ms_mask[idx] = get_bits1(gb); - } else if (ms_present == 2) { - memset(cpe->ms_mask, 1, cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb * sizeof(cpe->ms_mask[0])); - } -} - -#ifndef VMUL2 -static inline float *VMUL2(float *dst, const float *v, unsigned idx, - const float *scale) -{ - float s = *scale; - *dst++ = v[idx & 15] * s; - *dst++ = v[idx>>4 & 15] * s; - return dst; -} -#endif - -#ifndef VMUL4 -static inline float *VMUL4(float *dst, const float *v, unsigned idx, - const float *scale) -{ - float s = *scale; - *dst++ = v[idx & 3] * s; - *dst++ = v[idx>>2 & 3] * s; - *dst++ = v[idx>>4 & 3] * s; - *dst++ = v[idx>>6 & 3] * s; - return dst; -} -#endif - -#ifndef VMUL2S -static inline float *VMUL2S(float *dst, const float *v, unsigned idx, - unsigned sign, const float *scale) -{ - union float754 s0, s1; - - s0.f = s1.f = *scale; - s0.i ^= sign >> 1 << 31; - s1.i ^= sign << 31; - - *dst++ = v[idx & 15] * s0.f; - *dst++ = v[idx>>4 & 15] * s1.f; - - return dst; -} -#endif - -#ifndef VMUL4S -static inline float *VMUL4S(float *dst, const float *v, unsigned idx, - unsigned sign, const float *scale) -{ - unsigned nz = idx >> 12; - union float754 s = { .f = *scale }; - union float754 t; - - t.i = s.i ^ (sign & 1<<31); - *dst++ = v[idx & 3] * t.f; - - sign <<= nz & 1; nz >>= 1; - t.i = s.i ^ (sign & 1<<31); - *dst++ = v[idx>>2 & 3] * t.f; - - sign <<= nz & 1; nz >>= 1; - t.i = s.i ^ (sign & 1<<31); - *dst++ = v[idx>>4 & 3] * t.f; - - sign <<= nz & 1; nz >>= 1; - t.i = s.i ^ (sign & 1<<31); - *dst++ = v[idx>>6 & 3] * t.f; - - return dst; -} -#endif - -/** - * Decode spectral data; reference: table 4.50. - * Dequantize and scale spectral data; reference: 4.6.3.3. - * - * @param coef array of dequantized, scaled spectral data - * @param sf array of scalefactors or intensity stereo positions - * @param pulse_present set if pulses are present - * @param pulse pointer to pulse data struct - * @param band_type array of the used band type - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], - GetBitContext *gb, const float sf[120], - int pulse_present, const Pulse *pulse, - const IndividualChannelStream *ics, - enum BandType band_type[120]) -{ - int i, k, g, idx = 0; - const int c = 1024 / ics->num_windows; - const uint16_t *offsets = ics->swb_offset; - float *coef_base = coef; - int err_idx; - - for (g = 0; g < ics->num_windows; g++) - memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float) * (c - offsets[ics->max_sfb])); - - for (g = 0; g < ics->num_window_groups; g++) { - unsigned g_len = ics->group_len[g]; - - for (i = 0; i < ics->max_sfb; i++, idx++) { - const unsigned cbt_m1 = band_type[idx] - 1; - float *cfo = coef + offsets[i]; - int off_len = offsets[i + 1] - offsets[i]; - int group; - - if (cbt_m1 >= INTENSITY_BT2 - 1) { - for (group = 0; group < g_len; group++, cfo+=128) { - memset(cfo, 0, off_len * sizeof(float)); - } - } else if (cbt_m1 == NOISE_BT - 1) { - for (group = 0; group < g_len; group++, cfo+=128) { - float scale; - float band_energy; - - for (k = 0; k < off_len; k++) { - ac->random_state = lcg_random(ac->random_state); - cfo[k] = ac->random_state; - } - - band_energy = ac->dsp.scalarproduct_float(cfo, cfo, off_len); - scale = sf[idx] / sqrtf(band_energy); - ac->dsp.vector_fmul_scalar(cfo, cfo, scale, off_len); - } - } else { - const float *vq = ff_aac_codebook_vector_vals[cbt_m1]; - const uint16_t *cb_vector_idx = ff_aac_codebook_vector_idx[cbt_m1]; - VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cbt_m1].table; - const int cb_size = ff_aac_spectral_sizes[cbt_m1]; - OPEN_READER(re, gb); - - switch (cbt_m1 >> 1) { - case 0: - for (group = 0; group < g_len; group++, cfo+=128) { - float *cf = cfo; - int len = off_len; - - do { - int code; - unsigned cb_idx; - - UPDATE_CACHE(re, gb); - GET_VLC(code, re, gb, vlc_tab, 8, 2); - - if (code >= cb_size) { - err_idx = code; - goto err_cb_overflow; - } - - cb_idx = cb_vector_idx[code]; - cf = VMUL4(cf, vq, cb_idx, sf + idx); - } while (len -= 4); - } - break; - - case 1: - for (group = 0; group < g_len; group++, cfo+=128) { - float *cf = cfo; - int len = off_len; - - do { - int code; - unsigned nnz; - unsigned cb_idx; - uint32_t bits; - - UPDATE_CACHE(re, gb); - GET_VLC(code, re, gb, vlc_tab, 8, 2); - - if (code >= cb_size) { - err_idx = code; - goto err_cb_overflow; - } - -#if MIN_CACHE_BITS < 20 - UPDATE_CACHE(re, gb); -#endif - cb_idx = cb_vector_idx[code]; - nnz = cb_idx >> 8 & 15; - bits = SHOW_UBITS(re, gb, nnz) << (32-nnz); - LAST_SKIP_BITS(re, gb, nnz); - cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx); - } while (len -= 4); - } - break; - - case 2: - for (group = 0; group < g_len; group++, cfo+=128) { - float *cf = cfo; - int len = off_len; - - do { - int code; - unsigned cb_idx; - - UPDATE_CACHE(re, gb); - GET_VLC(code, re, gb, vlc_tab, 8, 2); - - if (code >= cb_size) { - err_idx = code; - goto err_cb_overflow; - } - - cb_idx = cb_vector_idx[code]; - cf = VMUL2(cf, vq, cb_idx, sf + idx); - } while (len -= 2); - } - break; - - case 3: - case 4: - for (group = 0; group < g_len; group++, cfo+=128) { - float *cf = cfo; - int len = off_len; - - do { - int code; - unsigned nnz; - unsigned cb_idx; - unsigned sign; - - UPDATE_CACHE(re, gb); - GET_VLC(code, re, gb, vlc_tab, 8, 2); - - if (code >= cb_size) { - err_idx = code; - goto err_cb_overflow; - } - - cb_idx = cb_vector_idx[code]; - nnz = cb_idx >> 8 & 15; - sign = SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12); - LAST_SKIP_BITS(re, gb, nnz); - cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx); - } while (len -= 2); - } - break; - - default: - for (group = 0; group < g_len; group++, cfo+=128) { - float *cf = cfo; - uint32_t *icf = (uint32_t *) cf; - int len = off_len; - - do { - int code; - unsigned nzt, nnz; - unsigned cb_idx; - uint32_t bits; - int j; - - UPDATE_CACHE(re, gb); - GET_VLC(code, re, gb, vlc_tab, 8, 2); - - if (!code) { - *icf++ = 0; - *icf++ = 0; - continue; - } - - if (code >= cb_size) { - err_idx = code; - goto err_cb_overflow; - } - - cb_idx = cb_vector_idx[code]; - nnz = cb_idx >> 12; - nzt = cb_idx >> 8; - bits = SHOW_UBITS(re, gb, nnz) << (32-nnz); - LAST_SKIP_BITS(re, gb, nnz); - - for (j = 0; j < 2; j++) { - if (nzt & 1< 8) { - av_log(ac->avccontext, AV_LOG_ERROR, "error in spectral data, ESC overflow\n"); - return -1; - } - -#if MIN_CACHE_BITS < 21 - LAST_SKIP_BITS(re, gb, b + 1); - UPDATE_CACHE(re, gb); -#else - SKIP_BITS(re, gb, b + 1); -#endif - b += 4; - n = (1 << b) + SHOW_UBITS(re, gb, b); - LAST_SKIP_BITS(re, gb, b); - *icf++ = cbrt_tab[n] | (bits & 1<<31); - bits <<= 1; - } else { - unsigned v = ((const uint32_t*)vq)[cb_idx & 15]; - *icf++ = (bits & 1<<31) | v; - bits <<= !!v; - } - cb_idx >>= 4; - } - } while (len -= 2); - - ac->dsp.vector_fmul_scalar(cfo, cfo, sf[idx], off_len); - } - } - - CLOSE_READER(re, gb); - } - } - coef += g_len << 7; - } - - if (pulse_present) { - idx = 0; - for (i = 0; i < pulse->num_pulse; i++) { - float co = coef_base[ pulse->pos[i] ]; - while (offsets[idx + 1] <= pulse->pos[i]) - idx++; - if (band_type[idx] != NOISE_BT && sf[idx]) { - float ico = -pulse->amp[i]; - if (co) { - co /= sf[idx]; - ico = co / sqrtf(sqrtf(fabsf(co))) + (co > 0 ? -ico : ico); - } - coef_base[ pulse->pos[i] ] = cbrtf(fabsf(ico)) * ico * sf[idx]; - } - } - } - return 0; - -err_cb_overflow: - av_log(ac->avccontext, AV_LOG_ERROR, - "Read beyond end of ff_aac_codebook_vectors[%d][]. index %d >= %d\n", - band_type[idx], err_idx, ff_aac_spectral_sizes[band_type[idx]]); - return -1; -} - -static av_always_inline float flt16_round(float pf) -{ - union float754 tmp; - tmp.f = pf; - tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U; - return tmp.f; -} - -static av_always_inline float flt16_even(float pf) -{ - union float754 tmp; - tmp.f = pf; - tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U; - return tmp.f; -} - -static av_always_inline float flt16_trunc(float pf) -{ - union float754 pun; - pun.f = pf; - pun.i &= 0xFFFF0000U; - return pun.f; -} - -static av_always_inline void predict(AACContext *ac, PredictorState *ps, float *coef, - int output_enable) -{ - const float a = 0.953125; // 61.0 / 64 - const float alpha = 0.90625; // 29.0 / 32 - float e0, e1; - float pv; - float k1, k2; - - k1 = ps->var0 > 1 ? ps->cor0 * flt16_even(a / ps->var0) : 0; - k2 = ps->var1 > 1 ? ps->cor1 * flt16_even(a / ps->var1) : 0; - - pv = flt16_round(k1 * ps->r0 + k2 * ps->r1); - if (output_enable) - *coef += pv * ac->sf_scale; - - e0 = *coef / ac->sf_scale; - e1 = e0 - k1 * ps->r0; - - ps->cor1 = flt16_trunc(alpha * ps->cor1 + ps->r1 * e1); - ps->var1 = flt16_trunc(alpha * ps->var1 + 0.5 * (ps->r1 * ps->r1 + e1 * e1)); - ps->cor0 = flt16_trunc(alpha * ps->cor0 + ps->r0 * e0); - ps->var0 = flt16_trunc(alpha * ps->var0 + 0.5 * (ps->r0 * ps->r0 + e0 * e0)); - - ps->r1 = flt16_trunc(a * (ps->r0 - k1 * e0)); - ps->r0 = flt16_trunc(a * e0); -} - -/** - * Apply AAC-Main style frequency domain prediction. - */ -static void apply_prediction(AACContext *ac, SingleChannelElement *sce) -{ - int sfb, k; - - if (!sce->ics.predictor_initialized) { - reset_all_predictors(sce->predictor_state); - sce->ics.predictor_initialized = 1; - } - - if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { - for (sfb = 0; sfb < ff_aac_pred_sfb_max[ac->m4ac.sampling_index]; sfb++) { - for (k = sce->ics.swb_offset[sfb]; k < sce->ics.swb_offset[sfb + 1]; k++) { - predict(ac, &sce->predictor_state[k], &sce->coeffs[k], - sce->ics.predictor_present && sce->ics.prediction_used[sfb]); - } - } - if (sce->ics.predictor_reset_group) - reset_predictor_group(sce->predictor_state, sce->ics.predictor_reset_group); - } else - reset_all_predictors(sce->predictor_state); -} - -/** - * Decode an individual_channel_stream payload; reference: table 4.44. - * - * @param common_window Channels have independent [0], or shared [1], Individual Channel Stream information. - * @param scale_flag scalable [1] or non-scalable [0] AAC (Unused until scalable AAC is implemented.) - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_ics(AACContext *ac, SingleChannelElement *sce, - GetBitContext *gb, int common_window, int scale_flag) -{ - Pulse pulse; - TemporalNoiseShaping *tns = &sce->tns; - IndividualChannelStream *ics = &sce->ics; - float *out = sce->coeffs; - int global_gain, pulse_present = 0; - - /* This assignment is to silence a GCC warning about the variable being used - * uninitialized when in fact it always is. - */ - pulse.num_pulse = 0; - - global_gain = get_bits(gb, 8); - - if (!common_window && !scale_flag) { - if (decode_ics_info(ac, ics, gb, 0) < 0) - return -1; - } - - if (decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics) < 0) - return -1; - if (decode_scalefactors(ac, sce->sf, gb, global_gain, ics, sce->band_type, sce->band_type_run_end) < 0) - return -1; - - pulse_present = 0; - if (!scale_flag) { - if ((pulse_present = get_bits1(gb))) { - if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - av_log(ac->avccontext, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n"); - return -1; - } - if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) { - av_log(ac->avccontext, AV_LOG_ERROR, "Pulse data corrupt or invalid.\n"); - return -1; - } - } - if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics)) - return -1; - if (get_bits1(gb)) { - av_log_missing_feature(ac->avccontext, "SSR", 1); - return -1; - } - } - - if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, &pulse, ics, sce->band_type) < 0) - return -1; - - if (ac->m4ac.object_type == AOT_AAC_MAIN && !common_window) - apply_prediction(ac, sce); - - return 0; -} - -/** - * Mid/Side stereo decoding; reference: 4.6.8.1.3. - */ -static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) -{ - const IndividualChannelStream *ics = &cpe->ch[0].ics; - float *ch0 = cpe->ch[0].coeffs; - float *ch1 = cpe->ch[1].coeffs; - int g, i, group, idx = 0; - const uint16_t *offsets = ics->swb_offset; - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb; i++, idx++) { - if (cpe->ms_mask[idx] && - cpe->ch[0].band_type[idx] < NOISE_BT && cpe->ch[1].band_type[idx] < NOISE_BT) { - for (group = 0; group < ics->group_len[g]; group++) { - ac->dsp.butterflies_float(ch0 + group * 128 + offsets[i], - ch1 + group * 128 + offsets[i], - offsets[i+1] - offsets[i]); - } - } - } - ch0 += ics->group_len[g] * 128; - ch1 += ics->group_len[g] * 128; - } -} - -/** - * intensity stereo decoding; reference: 4.6.8.2.3 - * - * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s; - * [1] mask is decoded from bitstream; [2] mask is all 1s; - * [3] reserved for scalable AAC - */ -static void apply_intensity_stereo(ChannelElement *cpe, int ms_present) -{ - const IndividualChannelStream *ics = &cpe->ch[1].ics; - SingleChannelElement *sce1 = &cpe->ch[1]; - float *coef0 = cpe->ch[0].coeffs, *coef1 = cpe->ch[1].coeffs; - const uint16_t *offsets = ics->swb_offset; - int g, group, i, k, idx = 0; - int c; - float scale; - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb;) { - if (sce1->band_type[idx] == INTENSITY_BT || sce1->band_type[idx] == INTENSITY_BT2) { - const int bt_run_end = sce1->band_type_run_end[idx]; - for (; i < bt_run_end; i++, idx++) { - c = -1 + 2 * (sce1->band_type[idx] - 14); - if (ms_present) - c *= 1 - 2 * cpe->ms_mask[idx]; - scale = c * sce1->sf[idx]; - for (group = 0; group < ics->group_len[g]; group++) - for (k = offsets[i]; k < offsets[i + 1]; k++) - coef1[group * 128 + k] = scale * coef0[group * 128 + k]; - } - } else { - int bt_run_end = sce1->band_type_run_end[idx]; - idx += bt_run_end - i; - i = bt_run_end; - } - } - coef0 += ics->group_len[g] * 128; - coef1 += ics->group_len[g] * 128; - } -} - -/** - * Decode a channel_pair_element; reference: table 4.4. - * - * @param elem_id Identifies the instance of a syntax element. - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe) -{ - int i, ret, common_window, ms_present = 0; - - common_window = get_bits1(gb); - if (common_window) { - if (decode_ics_info(ac, &cpe->ch[0].ics, gb, 1)) - return -1; - i = cpe->ch[1].ics.use_kb_window[0]; - cpe->ch[1].ics = cpe->ch[0].ics; - cpe->ch[1].ics.use_kb_window[1] = i; - ms_present = get_bits(gb, 2); - if (ms_present == 3) { - av_log(ac->avccontext, AV_LOG_ERROR, "ms_present = 3 is reserved.\n"); - return -1; - } else if (ms_present) - decode_mid_side_stereo(cpe, gb, ms_present); - } - if ((ret = decode_ics(ac, &cpe->ch[0], gb, common_window, 0))) - return ret; - if ((ret = decode_ics(ac, &cpe->ch[1], gb, common_window, 0))) - return ret; - - if (common_window) { - if (ms_present) - apply_mid_side_stereo(ac, cpe); - if (ac->m4ac.object_type == AOT_AAC_MAIN) { - apply_prediction(ac, &cpe->ch[0]); - apply_prediction(ac, &cpe->ch[1]); - } - } - - apply_intensity_stereo(cpe, ms_present); - return 0; -} - -/** - * Decode coupling_channel_element; reference: table 4.8. - * - * @param elem_id Identifies the instance of a syntax element. - * - * @return Returns error status. 0 - OK, !0 - error - */ -static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che) -{ - int num_gain = 0; - int c, g, sfb, ret; - int sign; - float scale; - SingleChannelElement *sce = &che->ch[0]; - ChannelCoupling *coup = &che->coup; - - coup->coupling_point = 2 * get_bits1(gb); - coup->num_coupled = get_bits(gb, 3); - for (c = 0; c <= coup->num_coupled; c++) { - num_gain++; - coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE; - coup->id_select[c] = get_bits(gb, 4); - if (coup->type[c] == TYPE_CPE) { - coup->ch_select[c] = get_bits(gb, 2); - if (coup->ch_select[c] == 3) - num_gain++; - } else - coup->ch_select[c] = 2; - } - coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1); - - sign = get_bits(gb, 1); - scale = pow(2., pow(2., (int)get_bits(gb, 2) - 3)); - - if ((ret = decode_ics(ac, sce, gb, 0, 0))) - return ret; - - for (c = 0; c < num_gain; c++) { - int idx = 0; - int cge = 1; - int gain = 0; - float gain_cache = 1.; - if (c) { - cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb); - gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0; - gain_cache = pow(scale, -gain); - } - if (coup->coupling_point == AFTER_IMDCT) { - coup->gain[c][0] = gain_cache; - } else { - for (g = 0; g < sce->ics.num_window_groups; g++) { - for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) { - if (sce->band_type[idx] != ZERO_BT) { - if (!cge) { - int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; - if (t) { - int s = 1; - t = gain += t; - if (sign) { - s -= 2 * (t & 0x1); - t >>= 1; - } - gain_cache = pow(scale, -t) * s; - } - } - coup->gain[c][idx] = gain_cache; - } - } - } - } - } - return 0; -} - -/** - * Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53. - * - * @return Returns number of bytes consumed. - */ -static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc, - GetBitContext *gb) -{ - int i; - int num_excl_chan = 0; - - do { - for (i = 0; i < 7; i++) - che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb); - } while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb)); - - return num_excl_chan / 7; -} - -/** - * Decode dynamic range information; reference: table 4.52. - * - * @param cnt length of TYPE_FIL syntactic element in bytes - * - * @return Returns number of bytes consumed. - */ -static int decode_dynamic_range(DynamicRangeControl *che_drc, - GetBitContext *gb, int cnt) -{ - int n = 1; - int drc_num_bands = 1; - int i; - - /* pce_tag_present? */ - if (get_bits1(gb)) { - che_drc->pce_instance_tag = get_bits(gb, 4); - skip_bits(gb, 4); // tag_reserved_bits - n++; - } - - /* excluded_chns_present? */ - if (get_bits1(gb)) { - n += decode_drc_channel_exclusions(che_drc, gb); - } - - /* drc_bands_present? */ - if (get_bits1(gb)) { - che_drc->band_incr = get_bits(gb, 4); - che_drc->interpolation_scheme = get_bits(gb, 4); - n++; - drc_num_bands += che_drc->band_incr; - for (i = 0; i < drc_num_bands; i++) { - che_drc->band_top[i] = get_bits(gb, 8); - n++; - } - } - - /* prog_ref_level_present? */ - if (get_bits1(gb)) { - che_drc->prog_ref_level = get_bits(gb, 7); - skip_bits1(gb); // prog_ref_level_reserved_bits - n++; - } - - for (i = 0; i < drc_num_bands; i++) { - che_drc->dyn_rng_sgn[i] = get_bits1(gb); - che_drc->dyn_rng_ctl[i] = get_bits(gb, 7); - n++; - } - - return n; -} - -/** - * Decode extension data (incomplete); reference: table 4.51. - * - * @param cnt length of TYPE_FIL syntactic element in bytes - * - * @return Returns number of bytes consumed - */ -static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, - ChannelElement *che, enum RawDataBlockType elem_type) -{ - int crc_flag = 0; - int res = cnt; - switch (get_bits(gb, 4)) { // extension type - case EXT_SBR_DATA_CRC: - crc_flag++; - case EXT_SBR_DATA: - if (!che) { - av_log(ac->avccontext, AV_LOG_ERROR, "SBR was found before the first channel element.\n"); - return res; - } else if (!ac->m4ac.sbr) { - av_log(ac->avccontext, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n"); - skip_bits_long(gb, 8 * cnt - 4); - return res; - } else if (ac->m4ac.sbr == -1 && ac->output_configured == OC_LOCKED) { - av_log(ac->avccontext, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n"); - skip_bits_long(gb, 8 * cnt - 4); - return res; - } else { - ac->m4ac.sbr = 1; - } - res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type); - break; - case EXT_DYNAMIC_RANGE: - res = decode_dynamic_range(&ac->che_drc, gb, cnt); - break; - case EXT_FILL: - case EXT_FILL_DATA: - case EXT_DATA_ELEMENT: - default: - skip_bits_long(gb, 8 * cnt - 4); - break; - }; - return res; -} - -/** - * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3. - * - * @param decode 1 if tool is used normally, 0 if tool is used in LTP. - * @param coef spectral coefficients - */ -static void apply_tns(float coef[1024], TemporalNoiseShaping *tns, - IndividualChannelStream *ics, int decode) -{ - const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb); - int w, filt, m, i; - int bottom, top, order, start, end, size, inc; - float lpc[TNS_MAX_ORDER]; - - for (w = 0; w < ics->num_windows; w++) { - bottom = ics->num_swb; - for (filt = 0; filt < tns->n_filt[w]; filt++) { - top = bottom; - bottom = FFMAX(0, top - tns->length[w][filt]); - order = tns->order[w][filt]; - if (order == 0) - continue; - - // tns_decode_coef - compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0); - - start = ics->swb_offset[FFMIN(bottom, mmm)]; - end = ics->swb_offset[FFMIN( top, mmm)]; - if ((size = end - start) <= 0) - continue; - if (tns->direction[w][filt]) { - inc = -1; - start = end - 1; - } else { - inc = 1; - } - start += w * 128; - - // ar filter - for (m = 0; m < size; m++, start += inc) - for (i = 1; i <= FFMIN(m, order); i++) - coef[start] -= coef[start - i * inc] * lpc[i - 1]; - } - } -} - -/** - * Conduct IMDCT and windowing. - */ -static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce, float bias) -{ - IndividualChannelStream *ics = &sce->ics; - float *in = sce->coeffs; - float *out = sce->ret; - float *saved = sce->saved; - const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; - const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; - const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; - float *buf = ac->buf_mdct; - float *temp = ac->temp; - int i; - - // imdct - if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - if (ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) - av_log(ac->avccontext, AV_LOG_WARNING, - "Transition from an ONLY_LONG or LONG_STOP to an EIGHT_SHORT sequence detected. " - "If you heard an audible artifact, please submit the sample to the FFmpeg developers.\n"); - for (i = 0; i < 1024; i += 128) - ff_imdct_half(&ac->mdct_small, buf + i, in + i); - } else - ff_imdct_half(&ac->mdct, buf, in); - - /* window overlapping - * NOTE: To simplify the overlapping code, all 'meaningless' short to long - * and long to short transitions are considered to be short to short - * transitions. This leaves just two cases (long to long and short to short) - * with a little special sauce for EIGHT_SHORT_SEQUENCE. - */ - if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) && - (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) { - ac->dsp.vector_fmul_window( out, saved, buf, lwindow_prev, bias, 512); - } else { - for (i = 0; i < 448; i++) - out[i] = saved[i] + bias; - - if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - ac->dsp.vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, bias, 64); - ac->dsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, bias, 64); - ac->dsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, bias, 64); - ac->dsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, bias, 64); - ac->dsp.vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, bias, 64); - memcpy( out + 448 + 4*128, temp, 64 * sizeof(float)); - } else { - ac->dsp.vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, bias, 64); - for (i = 576; i < 1024; i++) - out[i] = buf[i-512] + bias; - } - } - - // buffer update - if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { - for (i = 0; i < 64; i++) - saved[i] = temp[64 + i] - bias; - ac->dsp.vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 0, 64); - ac->dsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 0, 64); - ac->dsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 0, 64); - memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(float)); - } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { - memcpy( saved, buf + 512, 448 * sizeof(float)); - memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(float)); - } else { // LONG_STOP or ONLY_LONG - memcpy( saved, buf + 512, 512 * sizeof(float)); - } -} - -/** - * Apply dependent channel coupling (applied before IMDCT). - * - * @param index index into coupling gain array - */ -static void apply_dependent_coupling(AACContext *ac, - SingleChannelElement *target, - ChannelElement *cce, int index) -{ - IndividualChannelStream *ics = &cce->ch[0].ics; - const uint16_t *offsets = ics->swb_offset; - float *dest = target->coeffs; - const float *src = cce->ch[0].coeffs; - int g, i, group, k, idx = 0; - if (ac->m4ac.object_type == AOT_AAC_LTP) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Dependent coupling is not supported together with LTP\n"); - return; - } - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb; i++, idx++) { - if (cce->ch[0].band_type[idx] != ZERO_BT) { - const float gain = cce->coup.gain[index][idx]; - for (group = 0; group < ics->group_len[g]; group++) { - for (k = offsets[i]; k < offsets[i + 1]; k++) { - // XXX dsputil-ize - dest[group * 128 + k] += gain * src[group * 128 + k]; - } - } - } - } - dest += ics->group_len[g] * 128; - src += ics->group_len[g] * 128; - } -} - -/** - * Apply independent channel coupling (applied after IMDCT). - * - * @param index index into coupling gain array - */ -static void apply_independent_coupling(AACContext *ac, - SingleChannelElement *target, - ChannelElement *cce, int index) -{ - int i; - const float gain = cce->coup.gain[index][0]; - const float bias = ac->add_bias; - const float *src = cce->ch[0].ret; - float *dest = target->ret; - const int len = 1024 << (ac->m4ac.sbr == 1); - - for (i = 0; i < len; i++) - dest[i] += gain * (src[i] - bias); -} - -/** - * channel coupling transformation interface - * - * @param index index into coupling gain array - * @param apply_coupling_method pointer to (in)dependent coupling function - */ -static void apply_channel_coupling(AACContext *ac, ChannelElement *cc, - enum RawDataBlockType type, int elem_id, - enum CouplingPoint coupling_point, - void (*apply_coupling_method)(AACContext *ac, SingleChannelElement *target, ChannelElement *cce, int index)) -{ - int i, c; - - for (i = 0; i < MAX_ELEM_ID; i++) { - ChannelElement *cce = ac->che[TYPE_CCE][i]; - int index = 0; - - if (cce && cce->coup.coupling_point == coupling_point) { - ChannelCoupling *coup = &cce->coup; - - for (c = 0; c <= coup->num_coupled; c++) { - if (coup->type[c] == type && coup->id_select[c] == elem_id) { - if (coup->ch_select[c] != 1) { - apply_coupling_method(ac, &cc->ch[0], cce, index); - if (coup->ch_select[c] != 0) - index++; - } - if (coup->ch_select[c] != 2) - apply_coupling_method(ac, &cc->ch[1], cce, index++); - } else - index += 1 + (coup->ch_select[c] == 3); - } - } - } -} - -/** - * Convert spectral data to float samples, applying all supported tools as appropriate. - */ -static void spectral_to_sample(AACContext *ac) -{ - int i, type; - float imdct_bias = (ac->m4ac.sbr <= 0) ? ac->add_bias : 0.0f; - for (type = 3; type >= 0; type--) { - for (i = 0; i < MAX_ELEM_ID; i++) { - ChannelElement *che = ac->che[type][i]; - if (che) { - if (type <= TYPE_CPE) - apply_channel_coupling(ac, che, type, i, BEFORE_TNS, apply_dependent_coupling); - if (che->ch[0].tns.present) - apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1); - if (che->ch[1].tns.present) - apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1); - if (type <= TYPE_CPE) - apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, apply_dependent_coupling); - if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) { - imdct_and_windowing(ac, &che->ch[0], imdct_bias); - if (type == TYPE_CPE) { - imdct_and_windowing(ac, &che->ch[1], imdct_bias); - } - if (ac->m4ac.sbr > 0) { - ff_sbr_apply(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret); - } - } - if (type <= TYPE_CCE) - apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, apply_independent_coupling); - } - } - } -} - -static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) -{ - int size; - AACADTSHeaderInfo hdr_info; - - size = ff_aac_parse_header(gb, &hdr_info); - if (size > 0) { - if (ac->output_configured != OC_LOCKED && hdr_info.chan_config) { - enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]; - memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])); - ac->m4ac.chan_config = hdr_info.chan_config; - if (set_default_channel_config(ac, new_che_pos, hdr_info.chan_config)) - return -7; - if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME)) - return -7; - } else if (ac->output_configured != OC_LOCKED) { - ac->output_configured = OC_NONE; - } - if (ac->output_configured != OC_LOCKED) - ac->m4ac.sbr = -1; - ac->m4ac.sample_rate = hdr_info.sample_rate; - ac->m4ac.sampling_index = hdr_info.sampling_index; - ac->m4ac.object_type = hdr_info.object_type; - if (!ac->avccontext->sample_rate) - ac->avccontext->sample_rate = hdr_info.sample_rate; - if (hdr_info.num_aac_frames == 1) { - if (!hdr_info.crc_absent) - skip_bits(gb, 16); - } else { - av_log_missing_feature(ac->avccontext, "More than one AAC RDB per ADTS frame is", 0); - return -1; - } - } - return size; -} - -static int aac_decode_frame(AVCodecContext *avccontext, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AACContext *ac = avccontext->priv_data; - ChannelElement *che = NULL, *che_prev = NULL; - GetBitContext gb; - enum RawDataBlockType elem_type, elem_type_prev = TYPE_END; - int err, elem_id, data_size_tmp; - int buf_consumed; - int samples = 1024, multiplier; - int buf_offset; - - init_get_bits(&gb, buf, buf_size * 8); - - if (show_bits(&gb, 12) == 0xfff) { - if (parse_adts_frame_header(ac, &gb) < 0) { - av_log(avccontext, AV_LOG_ERROR, "Error decoding AAC frame header.\n"); - return -1; - } - if (ac->m4ac.sampling_index > 12) { - av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index); - return -1; - } - } - - // parse - while ((elem_type = get_bits(&gb, 3)) != TYPE_END) { - elem_id = get_bits(&gb, 4); - - if (elem_type < TYPE_DSE && !(che=get_che(ac, elem_type, elem_id))) { - av_log(ac->avccontext, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", elem_type, elem_id); - return -1; - } - - switch (elem_type) { - - case TYPE_SCE: - err = decode_ics(ac, &che->ch[0], &gb, 0, 0); - break; - - case TYPE_CPE: - err = decode_cpe(ac, &gb, che); - break; - - case TYPE_CCE: - err = decode_cce(ac, &gb, che); - break; - - case TYPE_LFE: - err = decode_ics(ac, &che->ch[0], &gb, 0, 0); - break; - - case TYPE_DSE: - err = skip_data_stream_element(ac, &gb); - break; - - case TYPE_PCE: { - enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]; - memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])); - if ((err = decode_pce(ac, new_che_pos, &gb))) - break; - if (ac->output_configured > OC_TRIAL_PCE) - av_log(avccontext, AV_LOG_ERROR, - "Not evaluating a further program_config_element as this construct is dubious at best.\n"); - else - err = output_configure(ac, ac->che_pos, new_che_pos, 0, OC_TRIAL_PCE); - break; - } - - case TYPE_FIL: - if (elem_id == 15) - elem_id += get_bits(&gb, 8) - 1; - if (get_bits_left(&gb) < 8 * elem_id) { - av_log(avccontext, AV_LOG_ERROR, overread_err); - return -1; - } - while (elem_id > 0) - elem_id -= decode_extension_payload(ac, &gb, elem_id, che_prev, elem_type_prev); - err = 0; /* FIXME */ - break; - - default: - err = -1; /* should not happen, but keeps compiler happy */ - break; - } - - che_prev = che; - elem_type_prev = elem_type; - - if (err) - return err; - - if (get_bits_left(&gb) < 3) { - av_log(avccontext, AV_LOG_ERROR, overread_err); - return -1; - } - } - - spectral_to_sample(ac); - - multiplier = (ac->m4ac.sbr == 1) ? ac->m4ac.ext_sample_rate > ac->m4ac.sample_rate : 0; - samples <<= multiplier; - if (ac->output_configured < OC_LOCKED) { - avccontext->sample_rate = ac->m4ac.sample_rate << multiplier; - avccontext->frame_size = samples; - } - - data_size_tmp = samples * avccontext->channels * sizeof(int16_t); - if (*data_size < data_size_tmp) { - av_log(avccontext, AV_LOG_ERROR, - "Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n", - *data_size, data_size_tmp); - return -1; - } - *data_size = data_size_tmp; - - ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avccontext->channels); - - if (ac->output_configured) - ac->output_configured = OC_LOCKED; - - buf_consumed = (get_bits_count(&gb) + 7) >> 3; - for (buf_offset = buf_consumed; buf_offset < buf_size; buf_offset++) - if (buf[buf_offset]) - break; - - return buf_size > buf_offset ? buf_consumed : buf_size; -} - -static av_cold int aac_decode_close(AVCodecContext *avccontext) -{ - AACContext *ac = avccontext->priv_data; - int i, type; - - for (i = 0; i < MAX_ELEM_ID; i++) { - for (type = 0; type < 4; type++) { - if (ac->che[type][i]) - ff_aac_sbr_ctx_close(&ac->che[type][i]->sbr); - av_freep(&ac->che[type][i]); - } - } - - ff_mdct_end(&ac->mdct); - ff_mdct_end(&ac->mdct_small); - return 0; -} - -AVCodec aac_decoder = { - "aac", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AAC, - sizeof(AACContext), - aac_decode_init, - NULL, - aac_decode_close, - aac_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"), - .sample_fmts = (const enum SampleFormat[]) { - SAMPLE_FMT_S16,SAMPLE_FMT_NONE - }, - .channel_layouts = aac_channel_layout, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/aac.h b/tizen/distrib/ffmpeg/libavcodec/aac.h deleted file mode 100644 index 1a8aa6c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aac.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - * AAC definitions and structures - * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) - * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC definitions and structures - * @author Oded Shimon ( ods15 ods15 dyndns org ) - * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) - */ - -#ifndef AVCODEC_AAC_H -#define AVCODEC_AAC_H - -#include "avcodec.h" -#include "dsputil.h" -#include "fft.h" -#include "mpeg4audio.h" -#include "sbr.h" - -#include - -#define AAC_INIT_VLC_STATIC(num, size) \ - INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \ - ff_aac_spectral_bits[num], sizeof( ff_aac_spectral_bits[num][0]), sizeof( ff_aac_spectral_bits[num][0]), \ - ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), sizeof(ff_aac_spectral_codes[num][0]), \ - size); - -#define MAX_CHANNELS 64 -#define MAX_ELEM_ID 16 - -#define TNS_MAX_ORDER 20 - -enum RawDataBlockType { - TYPE_SCE, - TYPE_CPE, - TYPE_CCE, - TYPE_LFE, - TYPE_DSE, - TYPE_PCE, - TYPE_FIL, - TYPE_END, -}; - -enum ExtensionPayloadID { - EXT_FILL, - EXT_FILL_DATA, - EXT_DATA_ELEMENT, - EXT_DYNAMIC_RANGE = 0xb, - EXT_SBR_DATA = 0xd, - EXT_SBR_DATA_CRC = 0xe, -}; - -enum WindowSequence { - ONLY_LONG_SEQUENCE, - LONG_START_SEQUENCE, - EIGHT_SHORT_SEQUENCE, - LONG_STOP_SEQUENCE, -}; - -enum BandType { - ZERO_BT = 0, ///< Scalefactors and spectral data are all zero. - FIRST_PAIR_BT = 5, ///< This and later band types encode two values (rather than four) with one code word. - ESC_BT = 11, ///< Spectral data are coded with an escape sequence. - NOISE_BT = 13, ///< Spectral data are scaled white noise not coded in the bitstream. - INTENSITY_BT2 = 14, ///< Scalefactor data are intensity stereo positions. - INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions. -}; - -#define IS_CODEBOOK_UNSIGNED(x) ((x - 1) & 10) - -enum ChannelPosition { - AAC_CHANNEL_FRONT = 1, - AAC_CHANNEL_SIDE = 2, - AAC_CHANNEL_BACK = 3, - AAC_CHANNEL_LFE = 4, - AAC_CHANNEL_CC = 5, -}; - -/** - * The point during decoding at which channel coupling is applied. - */ -enum CouplingPoint { - BEFORE_TNS, - BETWEEN_TNS_AND_IMDCT, - AFTER_IMDCT = 3, -}; - -/** - * Output configuration status - */ -enum OCStatus { - OC_NONE, //< Output unconfigured - OC_TRIAL_PCE, //< Output configuration under trial specified by an inband PCE - OC_TRIAL_FRAME, //< Output configuration under trial specified by a frame header - OC_GLOBAL_HDR, //< Output configuration set in a global header but not yet locked - OC_LOCKED, //< Output configuration locked in place -}; - -/** - * Predictor State - */ -typedef struct { - float cor0; - float cor1; - float var0; - float var1; - float r0; - float r1; -} PredictorState; - -#define MAX_PREDICTORS 672 - -#define SCALE_DIV_512 36 ///< scalefactor difference that corresponds to scale difference in 512 times -#define SCALE_ONE_POS 140 ///< scalefactor index that corresponds to scale=1.0 -#define SCALE_MAX_POS 255 ///< scalefactor index maximum value -#define SCALE_MAX_DIFF 60 ///< maximum scalefactor difference allowed by standard -#define SCALE_DIFF_ZERO 60 ///< codebook index corresponding to zero scalefactor indices difference - -/** - * Individual Channel Stream - */ -typedef struct { - uint8_t max_sfb; ///< number of scalefactor bands per group - enum WindowSequence window_sequence[2]; - uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sinus window. - int num_window_groups; - uint8_t group_len[8]; - const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window - const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window - int num_swb; ///< number of scalefactor window bands - int num_windows; - int tns_max_bands; - int predictor_present; - int predictor_initialized; - int predictor_reset_group; - uint8_t prediction_used[41]; -} IndividualChannelStream; - -/** - * Temporal Noise Shaping - */ -typedef struct { - int present; - int n_filt[8]; - int length[8][4]; - int direction[8][4]; - int order[8][4]; - float coef[8][4][TNS_MAX_ORDER]; -} TemporalNoiseShaping; - -/** - * Dynamic Range Control - decoded from the bitstream but not processed further. - */ -typedef struct { - int pce_instance_tag; ///< Indicates with which program the DRC info is associated. - int dyn_rng_sgn[17]; ///< DRC sign information; 0 - positive, 1 - negative - int dyn_rng_ctl[17]; ///< DRC magnitude information - int exclude_mask[MAX_CHANNELS]; ///< Channels to be excluded from DRC processing. - int band_incr; ///< Number of DRC bands greater than 1 having DRC info. - int interpolation_scheme; ///< Indicates the interpolation scheme used in the SBR QMF domain. - int band_top[17]; ///< Indicates the top of the i-th DRC band in units of 4 spectral lines. - int prog_ref_level; /**< A reference level for the long-term program audio level for all - * channels combined. - */ -} DynamicRangeControl; - -typedef struct { - int num_pulse; - int start; - int pos[4]; - int amp[4]; -} Pulse; - -/** - * coupling parameters - */ -typedef struct { - enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied. - int num_coupled; ///< number of target elements - enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE. - int id_select[8]; ///< element id - int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel; - * [2] list of gains for left channel; [3] lists of gains for both channels - */ - float gain[16][120]; -} ChannelCoupling; - -/** - * Single Channel Element - used for both SCE and LFE elements. - */ -typedef struct { - IndividualChannelStream ics; - TemporalNoiseShaping tns; - Pulse pulse; - enum BandType band_type[128]; ///< band types - int band_type_run_end[120]; ///< band type run end points - float sf[120]; ///< scalefactors - int sf_idx[128]; ///< scalefactor indices (used by encoder) - uint8_t zeroes[128]; ///< band is not coded (used by encoder) - DECLARE_ALIGNED(16, float, coeffs)[1024]; ///< coefficients for IMDCT - DECLARE_ALIGNED(16, float, saved)[1024]; ///< overlap - DECLARE_ALIGNED(16, float, ret)[2048]; ///< PCM output - PredictorState predictor_state[MAX_PREDICTORS]; -} SingleChannelElement; - -/** - * channel element - generic struct for SCE/CPE/CCE/LFE - */ -typedef struct { - // CPE specific - int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream. - int ms_mode; ///< Signals mid/side stereo flags coding mode (used by encoder) - uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band - // shared - SingleChannelElement ch[2]; - // CCE specific - ChannelCoupling coup; - SpectralBandReplication sbr; -} ChannelElement; - -/** - * main AAC context - */ -typedef struct { - AVCodecContext * avccontext; - - MPEG4AudioConfig m4ac; - - int is_saved; ///< Set if elements have stored overlap from previous frame. - DynamicRangeControl che_drc; - - /** - * @defgroup elements Channel element related data. - * @{ - */ - enum ChannelPosition che_pos[4][MAX_ELEM_ID]; /**< channel element channel mapping with the - * first index as the first 4 raw data block types - */ - ChannelElement * che[4][MAX_ELEM_ID]; - ChannelElement * tag_che_map[4][MAX_ELEM_ID]; - int tags_mapped; - /** @} */ - - /** - * @defgroup temporary aligned temporary buffers (We do not want to have these on the stack.) - * @{ - */ - DECLARE_ALIGNED(16, float, buf_mdct)[1024]; - /** @} */ - - /** - * @defgroup tables Computed / set up during initialization. - * @{ - */ - FFTContext mdct; - FFTContext mdct_small; - DSPContext dsp; - int random_state; - /** @} */ - - /** - * @defgroup output Members used for output interleaving. - * @{ - */ - float *output_data[MAX_CHANNELS]; ///< Points to each element's 'ret' buffer (PCM output). - float add_bias; ///< offset for dsp.float_to_int16 - float sf_scale; ///< Pre-scale for correct IMDCT and dsp.float_to_int16. - int sf_offset; ///< offset into pow2sf_tab as appropriate for dsp.float_to_int16 - /** @} */ - - DECLARE_ALIGNED(16, float, temp)[128]; - - enum OCStatus output_configured; -} AACContext; - -#endif /* AVCODEC_AAC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.c b/tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.c deleted file mode 100644 index 8791161..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Common AAC and AC-3 parser - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" -#include "aac_ac3_parser.h" - -int ff_aac_ac3_parse(AVCodecParserContext *s1, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - AACAC3ParseContext *s = s1->priv_data; - ParseContext *pc = &s->pc; - int len, i; - int new_frame_start; - -get_next: - i=END_NOT_FOUND; - if(s->remaining_size <= buf_size){ - if(s->remaining_size && !s->need_next_header){ - i= s->remaining_size; - s->remaining_size = 0; - }else{ //we need a header first - len=0; - for(i=s->remaining_size; istate = (s->state<<8) + buf[i]; - if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start))) - break; - } - if(len<=0){ - i=END_NOT_FOUND; - }else{ - s->state=0; - i-= s->header_size -1; - s->remaining_size = len; - if(!new_frame_start || pc->index+i<=0){ - s->remaining_size += i; - goto get_next; - } - } - } - } - - if(ff_combine_frame(pc, i, &buf, &buf_size)<0){ - s->remaining_size -= FFMIN(s->remaining_size, buf_size); - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - *poutbuf = buf; - *poutbuf_size = buf_size; - - /* update codec info */ - if(s->codec_id) - avctx->codec_id = s->codec_id; - - /* Due to backwards compatible HE-AAC the sample rate, channel count, - and total number of samples found in an AAC ADTS header are not - reliable. Bit rate is still accurate because the total frame duration in - seconds is still correct (as is the number of bits in the frame). */ - if (avctx->codec_id != CODEC_ID_AAC) { - avctx->sample_rate = s->sample_rate; - - /* allow downmixing to stereo (or mono for AC-3) */ - if(avctx->request_channels > 0 && - avctx->request_channels < s->channels && - (avctx->request_channels <= 2 || - (avctx->request_channels == 1 && - (avctx->codec_id == CODEC_ID_AC3 || - avctx->codec_id == CODEC_ID_EAC3)))) { - avctx->channels = avctx->request_channels; - } else { - avctx->channels = s->channels; - avctx->channel_layout = s->channel_layout; - } - avctx->frame_size = s->samples; - } - - avctx->bit_rate = s->bit_rate; - - return i; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.h b/tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.h deleted file mode 100644 index 75f6d4be..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aac_ac3_parser.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Common AAC and AC-3 parser prototypes - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AAC_AC3_PARSER_H -#define AVCODEC_AAC_AC3_PARSER_H - -#include -#include "avcodec.h" -#include "parser.h" - -typedef enum { - AAC_AC3_PARSE_ERROR_SYNC = -1, - AAC_AC3_PARSE_ERROR_BSID = -2, - AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -3, - AAC_AC3_PARSE_ERROR_FRAME_SIZE = -4, - AAC_AC3_PARSE_ERROR_FRAME_TYPE = -5, - AAC_AC3_PARSE_ERROR_CRC = -6, - AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -7, -} AACAC3ParseError; - -typedef struct AACAC3ParseContext { - ParseContext pc; - int frame_size; - int header_size; - int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info, - int *need_next_header, int *new_frame_start); - - int channels; - int sample_rate; - int bit_rate; - int samples; - int64_t channel_layout; - - int remaining_size; - uint64_t state; - - int need_next_header; - enum CodecID codec_id; -} AACAC3ParseContext; - -int ff_aac_ac3_parse(AVCodecParserContext *s1, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size); - -#endif /* AVCODEC_AAC_AC3_PARSER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aac_adtstoasc_bsf.c b/tizen/distrib/ffmpeg/libavcodec/aac_adtstoasc_bsf.c deleted file mode 100644 index 9d53a01..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aac_adtstoasc_bsf.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter - * Copyright (c) 2009 Alex Converse - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "aac_parser.h" -#include "put_bits.h" -#include "get_bits.h" -#include "mpeg4audio.h" -#include "internal.h" - -typedef struct AACBSFContext { - int first_frame_done; -} AACBSFContext; - -/** - * This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4 - * ADTS header and removes the ADTS header. - */ -static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, - int keyframe) -{ - GetBitContext gb; - PutBitContext pb; - AACADTSHeaderInfo hdr; - - AACBSFContext *ctx = bsfc->priv_data; - - init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8); - - *poutbuf = (uint8_t*) buf; - *poutbuf_size = buf_size; - - if (avctx->extradata) - if (show_bits(&gb, 12) != 0xfff) - return 0; - - if (ff_aac_parse_header(&gb, &hdr) < 0) { - av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); - return -1; - } - - if (!hdr.crc_absent && hdr.num_aac_frames > 1) { - av_log_missing_feature(avctx, "Multiple RDBs per frame with CRC is", 0); - return -1; - } - - buf += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; - buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; - - if (!ctx->first_frame_done) { - int pce_size = 0; - uint8_t pce_data[MAX_PCE_SIZE]; - if (!hdr.chan_config) { - init_get_bits(&gb, buf, buf_size); - if (get_bits(&gb, 3) != 5) { - av_log_missing_feature(avctx, "PCE based channel configuration, where the PCE is not the first syntax element is", 0); - return -1; - } - init_put_bits(&pb, pce_data, MAX_PCE_SIZE); - pce_size = ff_copy_pce_data(&pb, &gb)/8; - flush_put_bits(&pb); - buf_size -= get_bits_count(&gb)/8; - buf += get_bits_count(&gb)/8; - } - avctx->extradata_size = 2 + pce_size; - avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - - init_put_bits(&pb, avctx->extradata, avctx->extradata_size); - put_bits(&pb, 5, hdr.object_type); - put_bits(&pb, 4, hdr.sampling_index); - put_bits(&pb, 4, hdr.chan_config); - put_bits(&pb, 1, 0); //frame length - 1024 samples - put_bits(&pb, 1, 0); //does not depend on core coder - put_bits(&pb, 1, 0); //is not extension - flush_put_bits(&pb); - if (pce_size) { - memcpy(avctx->extradata + 2, pce_data, pce_size); - } - - ctx->first_frame_done = 1; - } - - *poutbuf = (uint8_t*) buf; - *poutbuf_size = buf_size; - - return 0; -} - -AVBitStreamFilter aac_adtstoasc_bsf = { - "aac_adtstoasc", - sizeof(AACBSFContext), - aac_adtstoasc_filter, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/aac_parser.c b/tizen/distrib/ffmpeg/libavcodec/aac_parser.c deleted file mode 100644 index 30ce04d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aac_parser.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Audio and Video frame extraction - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" -#include "aac_ac3_parser.h" -#include "aac_parser.h" -#include "get_bits.h" -#include "mpeg4audio.h" - -int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr) -{ - int size, rdb, ch, sr; - int aot, crc_abs; - - if(get_bits(gbc, 12) != 0xfff) - return AAC_AC3_PARSE_ERROR_SYNC; - - skip_bits1(gbc); /* id */ - skip_bits(gbc, 2); /* layer */ - crc_abs = get_bits1(gbc); /* protection_absent */ - aot = get_bits(gbc, 2); /* profile_objecttype */ - sr = get_bits(gbc, 4); /* sample_frequency_index */ - if(!ff_mpeg4audio_sample_rates[sr]) - return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; - skip_bits1(gbc); /* private_bit */ - ch = get_bits(gbc, 3); /* channel_configuration */ - - skip_bits1(gbc); /* original/copy */ - skip_bits1(gbc); /* home */ - - /* adts_variable_header */ - skip_bits1(gbc); /* copyright_identification_bit */ - skip_bits1(gbc); /* copyright_identification_start */ - size = get_bits(gbc, 13); /* aac_frame_length */ - if(size < AAC_ADTS_HEADER_SIZE) - return AAC_AC3_PARSE_ERROR_FRAME_SIZE; - - skip_bits(gbc, 11); /* adts_buffer_fullness */ - rdb = get_bits(gbc, 2); /* number_of_raw_data_blocks_in_frame */ - - hdr->object_type = aot + 1; - hdr->chan_config = ch; - hdr->crc_absent = crc_abs; - hdr->num_aac_frames = rdb + 1; - hdr->sampling_index = sr; - hdr->sample_rate = ff_mpeg4audio_sample_rates[sr]; - hdr->samples = (rdb + 1) * 1024; - hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; - - return size; -} - -static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info, - int *need_next_header, int *new_frame_start) -{ - GetBitContext bits; - AACADTSHeaderInfo hdr; - int size; - union { - uint64_t u64; - uint8_t u8[8]; - } tmp; - - tmp.u64 = be2me_64(state); - init_get_bits(&bits, tmp.u8+8-AAC_ADTS_HEADER_SIZE, AAC_ADTS_HEADER_SIZE * 8); - - if ((size = ff_aac_parse_header(&bits, &hdr)) < 0) - return 0; - *need_next_header = 0; - *new_frame_start = 1; - hdr_info->sample_rate = hdr.sample_rate; - hdr_info->channels = ff_mpeg4audio_channels[hdr.chan_config]; - hdr_info->samples = hdr.samples; - hdr_info->bit_rate = hdr.bit_rate; - return size; -} - -static av_cold int aac_parse_init(AVCodecParserContext *s1) -{ - AACAC3ParseContext *s = s1->priv_data; - s->header_size = AAC_ADTS_HEADER_SIZE; - s->sync = aac_sync; - return 0; -} - - -AVCodecParser aac_parser = { - { CODEC_ID_AAC }, - sizeof(AACAC3ParseContext), - aac_parse_init, - ff_aac_ac3_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/aac_parser.h b/tizen/distrib/ffmpeg/libavcodec/aac_parser.h deleted file mode 100644 index 8dd575b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aac_parser.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * AAC parser prototypes - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AAC_PARSER_H -#define AVCODEC_AAC_PARSER_H - -#include -#include "aac_ac3_parser.h" -#include "get_bits.h" - -#define AAC_ADTS_HEADER_SIZE 7 - -typedef struct { - uint32_t sample_rate; - uint32_t samples; - uint32_t bit_rate; - uint8_t crc_absent; - uint8_t object_type; - uint8_t sampling_index; - uint8_t chan_config; - uint8_t num_aac_frames; -} AACADTSHeaderInfo; - -/** - * Parses AAC frame header. - * Parses the ADTS frame header to the end of the variable header, which is - * the first 54 bits. - * @param gbc[in] BitContext containing the first 54 bits of the frame. - * @param hdr[out] Pointer to struct where header info is written. - * @return Returns 0 on success, -1 if there is a sync word mismatch, - * -2 if the version element is invalid, -3 if the sample rate - * element is invalid, or -4 if the bit rate element is invalid. - */ -int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr); - -#endif /* AVCODEC_AAC_PARSER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aaccoder.c b/tizen/distrib/ffmpeg/libavcodec/aaccoder.c deleted file mode 100644 index 0957469..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aaccoder.c +++ /dev/null @@ -1,960 +0,0 @@ -/* - * AAC coefficients encoder - * Copyright (C) 2008-2009 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC coefficients encoder - */ - -/*********************************** - * TODOs: - * speedup quantizer selection - * add sane pulse detection - ***********************************/ - -#include "avcodec.h" -#include "put_bits.h" -#include "aac.h" -#include "aacenc.h" -#include "aactab.h" - -/** bits needed to code codebook run value for long windows */ -static const uint8_t run_value_bits_long[64] = { - 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, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15 -}; - -/** bits needed to code codebook run value for short windows */ -static const uint8_t run_value_bits_short[16] = { - 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9 -}; - -static const uint8_t *run_value_bits[2] = { - run_value_bits_long, run_value_bits_short -}; - - -/** - * Quantize one coefficient. - * @return absolute value of the quantized coefficient - * @see 3GPP TS26.403 5.6.2 "Scalefactor determination" - */ -static av_always_inline int quant(float coef, const float Q) -{ - float a = coef * Q; - return sqrtf(a * sqrtf(a)) + 0.4054; -} - -static void quantize_bands(int (*out)[2], const float *in, const float *scaled, - int size, float Q34, int is_signed, int maxval) -{ - int i; - double qc; - for (i = 0; i < size; i++) { - qc = scaled[i] * Q34; - out[i][0] = (int)FFMIN(qc, (double)maxval); - out[i][1] = (int)FFMIN(qc + 0.4054, (double)maxval); - if (is_signed && in[i] < 0.0f) { - out[i][0] = -out[i][0]; - out[i][1] = -out[i][1]; - } - } -} - -static void abs_pow34_v(float *out, const float *in, const int size) -{ -#ifndef USE_REALLY_FULL_SEARCH - int i; - for (i = 0; i < size; i++) { - float a = fabsf(in[i]); - out[i] = sqrtf(a * sqrtf(a)); - } -#endif /* USE_REALLY_FULL_SEARCH */ -} - -static const uint8_t aac_cb_range [12] = {0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17}; -static const uint8_t aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16}; - -/** - * Calculate rate distortion cost for quantizing with given codebook - * - * @return quantization distortion - */ -static float quantize_and_encode_band_cost(struct AACEncContext *s, - PutBitContext *pb, const float *in, - const float *scaled, int size, int scale_idx, - int cb, const float lambda, const float uplim, - int *bits) -{ - const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512]; - const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512]; - const float CLIPPED_ESCAPE = 165140.0f*IQ; - int i, j, k; - float cost = 0; - const int dim = cb < FIRST_PAIR_BT ? 4 : 2; - int resbits = 0; -#ifndef USE_REALLY_FULL_SEARCH - const float Q34 = sqrtf(Q * sqrtf(Q)); - const int range = aac_cb_range[cb]; - const int maxval = aac_cb_maxval[cb]; - int offs[4]; -#endif /* USE_REALLY_FULL_SEARCH */ - - if (!cb) { - for (i = 0; i < size; i++) - cost += in[i]*in[i]; - if (bits) - *bits = 0; - return cost * lambda; - } -#ifndef USE_REALLY_FULL_SEARCH - offs[0] = 1; - for (i = 1; i < dim; i++) - offs[i] = offs[i-1]*range; - if (!scaled) { - abs_pow34_v(s->scoefs, in, size); - scaled = s->scoefs; - } - quantize_bands(s->qcoefs, in, scaled, size, Q34, !IS_CODEBOOK_UNSIGNED(cb), maxval); -#endif /* USE_REALLY_FULL_SEARCH */ - for (i = 0; i < size; i += dim) { - float mincost; - int minidx = 0; - int minbits = 0; - const float *vec; -#ifndef USE_REALLY_FULL_SEARCH - int (*quants)[2] = &s->qcoefs[i]; - mincost = 0.0f; - for (j = 0; j < dim; j++) - mincost += in[i+j]*in[i+j]; - minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40; - minbits = ff_aac_spectral_bits[cb-1][minidx]; - mincost = mincost * lambda + minbits; - for (j = 0; j < (1<= CLIPPED_ESCAPE) { - di = t - CLIPPED_ESCAPE; - curbits += 21; - } else { - int c = av_clip(quant(t, Q), 0, 8191); - di = t - c*cbrtf(c)*IQ; - curbits += av_log2(c)*2 - 4 + 1; - } - } else { - di = t - vec[k]*IQ; - } - if (vec[k] != 0.0f) - curbits++; - rd += di*di; - } - } else { - for (k = 0; k < dim; k++) { - float di = in[i+k] - vec[k]*IQ; - rd += di*di; - } - } - rd = rd * lambda + curbits; - if (rd < mincost) { - mincost = rd; - minidx = curidx; - minbits = curbits; - } - } - cost += mincost; - resbits += minbits; - if (cost >= uplim) - return uplim; - if (pb) { - put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]); - if (IS_CODEBOOK_UNSIGNED(cb)) - for (j = 0; j < dim; j++) - if (ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f) - put_bits(pb, 1, in[i+j] < 0.0f); - if (cb == ESC_BT) { - for (j = 0; j < 2; j++) { - if (ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f) { - int coef = av_clip(quant(fabsf(in[i+j]), Q), 0, 8191); - int len = av_log2(coef); - - put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2); - put_bits(pb, len, coef & ((1 << len) - 1)); - } - } - } - } - } - - if (bits) - *bits = resbits; - return cost; -} -static float quantize_band_cost(struct AACEncContext *s, const float *in, - const float *scaled, int size, int scale_idx, - int cb, const float lambda, const float uplim, - int *bits) -{ - return quantize_and_encode_band_cost(s, NULL, in, scaled, size, scale_idx, - cb, lambda, uplim, bits); -} - -static void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb, - const float *in, int size, int scale_idx, - int cb, const float lambda) -{ - quantize_and_encode_band_cost(s, pb, in, NULL, size, scale_idx, cb, lambda, - INFINITY, NULL); -} - -/** - * structure used in optimal codebook search - */ -typedef struct BandCodingPath { - int prev_idx; ///< pointer to the previous path point - float cost; ///< path cost - int run; -} BandCodingPath; - -/** - * Encode band info for single window group bands. - */ -static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce, - int win, int group_len, const float lambda) -{ - BandCodingPath path[120][12]; - int w, swb, cb, start, start2, size; - int i, j; - const int max_sfb = sce->ics.max_sfb; - const int run_bits = sce->ics.num_windows == 1 ? 5 : 3; - const int run_esc = (1 << run_bits) - 1; - int idx, ppos, count; - int stackrun[120], stackcb[120], stack_len; - float next_minrd = INFINITY; - int next_mincb = 0; - - abs_pow34_v(s->scoefs, sce->coeffs, 1024); - start = win*128; - for (cb = 0; cb < 12; cb++) { - path[0][cb].cost = 0.0f; - path[0][cb].prev_idx = -1; - path[0][cb].run = 0; - } - for (swb = 0; swb < max_sfb; swb++) { - start2 = start; - size = sce->ics.swb_sizes[swb]; - if (sce->zeroes[win*16 + swb]) { - for (cb = 0; cb < 12; cb++) { - path[swb+1][cb].prev_idx = cb; - path[swb+1][cb].cost = path[swb][cb].cost; - path[swb+1][cb].run = path[swb][cb].run + 1; - } - } else { - float minrd = next_minrd; - int mincb = next_mincb; - next_minrd = INFINITY; - next_mincb = 0; - for (cb = 0; cb < 12; cb++) { - float cost_stay_here, cost_get_here; - float rd = 0.0f; - for (w = 0; w < group_len; w++) { - FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb]; - rd += quantize_band_cost(s, sce->coeffs + start + w*128, - s->scoefs + start + w*128, size, - sce->sf_idx[(win+w)*16+swb], cb, - lambda / band->threshold, INFINITY, NULL); - } - cost_stay_here = path[swb][cb].cost + rd; - cost_get_here = minrd + rd + run_bits + 4; - if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run] - != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1]) - cost_stay_here += run_bits; - if (cost_get_here < cost_stay_here) { - path[swb+1][cb].prev_idx = mincb; - path[swb+1][cb].cost = cost_get_here; - path[swb+1][cb].run = 1; - } else { - path[swb+1][cb].prev_idx = cb; - path[swb+1][cb].cost = cost_stay_here; - path[swb+1][cb].run = path[swb][cb].run + 1; - } - if (path[swb+1][cb].cost < next_minrd) { - next_minrd = path[swb+1][cb].cost; - next_mincb = cb; - } - } - } - start += sce->ics.swb_sizes[swb]; - } - - //convert resulting path from backward-linked list - stack_len = 0; - idx = 0; - for (cb = 1; cb < 12; cb++) - if (path[max_sfb][cb].cost < path[max_sfb][idx].cost) - idx = cb; - ppos = max_sfb; - while (ppos > 0) { - cb = idx; - stackrun[stack_len] = path[ppos][cb].run; - stackcb [stack_len] = cb; - idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx; - ppos -= path[ppos][cb].run; - stack_len++; - } - //perform actual band info encoding - start = 0; - for (i = stack_len - 1; i >= 0; i--) { - put_bits(&s->pb, 4, stackcb[i]); - count = stackrun[i]; - memset(sce->zeroes + win*16 + start, !stackcb[i], count); - //XXX: memset when band_type is also uint8_t - for (j = 0; j < count; j++) { - sce->band_type[win*16 + start] = stackcb[i]; - start++; - } - while (count >= run_esc) { - put_bits(&s->pb, run_bits, run_esc); - count -= run_esc; - } - put_bits(&s->pb, run_bits, count); - } -} - -typedef struct TrellisPath { - float cost; - int prev; - int min_val; - int max_val; -} TrellisPath; - -#define TRELLIS_STAGES 121 -#define TRELLIS_STATES 256 - -static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s, - SingleChannelElement *sce, - const float lambda) -{ - int q, w, w2, g, start = 0; - int i, j; - int idx; - TrellisPath paths[TRELLIS_STAGES][TRELLIS_STATES]; - int bandaddr[TRELLIS_STAGES]; - int minq; - float mincost; - - for (i = 0; i < TRELLIS_STATES; i++) { - paths[0][i].cost = 0.0f; - paths[0][i].prev = -1; - paths[0][i].min_val = i; - paths[0][i].max_val = i; - } - for (j = 1; j < TRELLIS_STAGES; j++) { - for (i = 0; i < TRELLIS_STATES; i++) { - paths[j][i].cost = INFINITY; - paths[j][i].prev = -2; - paths[j][i].min_val = INT_MAX; - paths[j][i].max_val = 0; - } - } - idx = 1; - abs_pow34_v(s->scoefs, sce->coeffs, 1024); - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = w*128; - for (g = 0; g < sce->ics.num_swb; g++) { - const float *coefs = sce->coeffs + start; - float qmin, qmax; - int nz = 0; - - bandaddr[idx] = w * 16 + g; - qmin = INT_MAX; - qmax = 0.0f; - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g]; - if (band->energy <= band->threshold || band->threshold == 0.0f) { - sce->zeroes[(w+w2)*16+g] = 1; - continue; - } - sce->zeroes[(w+w2)*16+g] = 0; - nz = 1; - for (i = 0; i < sce->ics.swb_sizes[g]; i++) { - float t = fabsf(coefs[w2*128+i]); - if (t > 0.0f) - qmin = FFMIN(qmin, t); - qmax = FFMAX(qmax, t); - } - } - if (nz) { - int minscale, maxscale; - float minrd = INFINITY; - //minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped - minscale = av_clip_uint8(log2(qmin)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512); - //maximum scalefactor index is when maximum coefficient after quantizing is still not zero - maxscale = av_clip_uint8(log2(qmax)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512); - for (q = minscale; q < maxscale; q++) { - float dists[12], dist; - memset(dists, 0, sizeof(dists)); - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g]; - int cb; - for (cb = 0; cb <= ESC_BT; cb++) - dists[cb] += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g], - q, cb, lambda / band->threshold, INFINITY, NULL); - } - dist = dists[0]; - for (i = 1; i <= ESC_BT; i++) - dist = FFMIN(dist, dists[i]); - minrd = FFMIN(minrd, dist); - - for (i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, TRELLIS_STATES); i++) { - float cost; - int minv, maxv; - if (isinf(paths[idx - 1][i].cost)) - continue; - cost = paths[idx - 1][i].cost + dist - + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO]; - minv = FFMIN(paths[idx - 1][i].min_val, q); - maxv = FFMAX(paths[idx - 1][i].max_val, q); - if (cost < paths[idx][q].cost && maxv-minv < SCALE_MAX_DIFF) { - paths[idx][q].cost = cost; - paths[idx][q].prev = i; - paths[idx][q].min_val = minv; - paths[idx][q].max_val = maxv; - } - } - } - } else { - for (q = 0; q < TRELLIS_STATES; q++) { - if (!isinf(paths[idx - 1][q].cost)) { - paths[idx][q].cost = paths[idx - 1][q].cost + 1; - paths[idx][q].prev = q; - paths[idx][q].min_val = FFMIN(paths[idx - 1][q].min_val, q); - paths[idx][q].max_val = FFMAX(paths[idx - 1][q].max_val, q); - continue; - } - for (i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, TRELLIS_STATES); i++) { - float cost; - int minv, maxv; - if (isinf(paths[idx - 1][i].cost)) - continue; - cost = paths[idx - 1][i].cost + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO]; - minv = FFMIN(paths[idx - 1][i].min_val, q); - maxv = FFMAX(paths[idx - 1][i].max_val, q); - if (cost < paths[idx][q].cost && maxv-minv < SCALE_MAX_DIFF) { - paths[idx][q].cost = cost; - paths[idx][q].prev = i; - paths[idx][q].min_val = minv; - paths[idx][q].max_val = maxv; - } - } - } - } - sce->zeroes[w*16+g] = !nz; - start += sce->ics.swb_sizes[g]; - idx++; - } - } - idx--; - mincost = paths[idx][0].cost; - minq = 0; - for (i = 1; i < TRELLIS_STATES; i++) { - if (paths[idx][i].cost < mincost) { - mincost = paths[idx][i].cost; - minq = i; - } - } - while (idx) { - sce->sf_idx[bandaddr[idx]] = minq; - minq = paths[idx][minq].prev; - idx--; - } - //set the same quantizers inside window groups - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) - for (g = 0; g < sce->ics.num_swb; g++) - for (w2 = 1; w2 < sce->ics.group_len[w]; w2++) - sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g]; -} - -/** - * two-loop quantizers search taken from ISO 13818-7 Appendix C - */ -static void search_for_quantizers_twoloop(AVCodecContext *avctx, - AACEncContext *s, - SingleChannelElement *sce, - const float lambda) -{ - int start = 0, i, w, w2, g; - int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels; - float dists[128], uplims[128]; - int fflag, minscaler; - int its = 0; - int allz = 0; - float minthr = INFINITY; - - //XXX: some heuristic to determine initial quantizers will reduce search time - memset(dists, 0, sizeof(dists)); - //determine zero bands and upper limits - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - for (g = 0; g < sce->ics.num_swb; g++) { - int nz = 0; - float uplim = 0.0f; - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g]; - uplim += band->threshold; - if (band->energy <= band->threshold || band->threshold == 0.0f) { - sce->zeroes[(w+w2)*16+g] = 1; - continue; - } - nz = 1; - } - uplims[w*16+g] = uplim *512; - sce->zeroes[w*16+g] = !nz; - if (nz) - minthr = FFMIN(minthr, uplim); - allz = FFMAX(allz, nz); - } - } - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - for (g = 0; g < sce->ics.num_swb; g++) { - if (sce->zeroes[w*16+g]) { - sce->sf_idx[w*16+g] = SCALE_ONE_POS; - continue; - } - sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2(uplims[w*16+g]/minthr)*4,59); - } - } - - if (!allz) - return; - abs_pow34_v(s->scoefs, sce->coeffs, 1024); - //perform two-loop search - //outer loop - improve quality - do { - int tbits, qstep; - minscaler = sce->sf_idx[0]; - //inner loop - quantize spectrum to fit into given number of bits - qstep = its ? 1 : 32; - do { - int prev = -1; - tbits = 0; - fflag = 0; - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = w*128; - for (g = 0; g < sce->ics.num_swb; g++) { - const float *coefs = sce->coeffs + start; - const float *scaled = s->scoefs + start; - int bits = 0; - int cb; - float mindist = INFINITY; - int minbits = 0; - - if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) { - start += sce->ics.swb_sizes[g]; - continue; - } - minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]); - for (cb = 0; cb <= ESC_BT; cb++) { - float dist = 0.0f; - int bb = 0; - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - int b; - dist += quantize_band_cost(s, coefs + w2*128, - scaled + w2*128, - sce->ics.swb_sizes[g], - sce->sf_idx[w*16+g], - cb, - lambda, - INFINITY, - &b); - bb += b; - } - if (dist < mindist) { - mindist = dist; - minbits = bb; - } - } - dists[w*16+g] = (mindist - minbits) / lambda; - bits = minbits; - if (prev != -1) { - bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO]; - } - tbits += bits; - start += sce->ics.swb_sizes[g]; - prev = sce->sf_idx[w*16+g]; - } - } - if (tbits > destbits) { - for (i = 0; i < 128; i++) - if (sce->sf_idx[i] < 218 - qstep) - sce->sf_idx[i] += qstep; - } else { - for (i = 0; i < 128; i++) - if (sce->sf_idx[i] > 60 - qstep) - sce->sf_idx[i] -= qstep; - } - qstep >>= 1; - if (!qstep && tbits > destbits*1.02) - qstep = 1; - if (sce->sf_idx[0] >= 217) - break; - } while (qstep); - - fflag = 0; - minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF); - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = w*128; - for (g = 0; g < sce->ics.num_swb; g++) { - int prevsc = sce->sf_idx[w*16+g]; - if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) - sce->sf_idx[w*16+g]--; - sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF); - sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219); - if (sce->sf_idx[w*16+g] != prevsc) - fflag = 1; - } - } - its++; - } while (fflag && its < 10); -} - -static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s, - SingleChannelElement *sce, - const float lambda) -{ - int start = 0, i, w, w2, g; - float uplim[128], maxq[128]; - int minq, maxsf; - float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda; - int last = 0, lastband = 0, curband = 0; - float avg_energy = 0.0; - if (sce->ics.num_windows == 1) { - start = 0; - for (i = 0; i < 1024; i++) { - if (i - start >= sce->ics.swb_sizes[curband]) { - start += sce->ics.swb_sizes[curband]; - curband++; - } - if (sce->coeffs[i]) { - avg_energy += sce->coeffs[i] * sce->coeffs[i]; - last = i; - lastband = curband; - } - } - } else { - for (w = 0; w < 8; w++) { - const float *coeffs = sce->coeffs + w*128; - start = 0; - for (i = 0; i < 128; i++) { - if (i - start >= sce->ics.swb_sizes[curband]) { - start += sce->ics.swb_sizes[curband]; - curband++; - } - if (coeffs[i]) { - avg_energy += coeffs[i] * coeffs[i]; - last = FFMAX(last, i); - lastband = FFMAX(lastband, curband); - } - } - } - } - last++; - avg_energy /= last; - if (avg_energy == 0.0f) { - for (i = 0; i < FF_ARRAY_ELEMS(sce->sf_idx); i++) - sce->sf_idx[i] = SCALE_ONE_POS; - return; - } - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = w*128; - for (g = 0; g < sce->ics.num_swb; g++) { - float *coefs = sce->coeffs + start; - const int size = sce->ics.swb_sizes[g]; - int start2 = start, end2 = start + size, peakpos = start; - float maxval = -1, thr = 0.0f, t; - maxq[w*16+g] = 0.0f; - if (g > lastband) { - maxq[w*16+g] = 0.0f; - start += size; - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) - memset(coefs + w2*128, 0, sizeof(coefs[0])*size); - continue; - } - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - for (i = 0; i < size; i++) { - float t = coefs[w2*128+i]*coefs[w2*128+i]; - maxq[w*16+g] = FFMAX(maxq[w*16+g], fabsf(coefs[w2*128 + i])); - thr += t; - if (sce->ics.num_windows == 1 && maxval < t) { - maxval = t; - peakpos = start+i; - } - } - } - if (sce->ics.num_windows == 1) { - start2 = FFMAX(peakpos - 2, start2); - end2 = FFMIN(peakpos + 3, end2); - } else { - start2 -= start; - end2 -= start; - } - start += size; - thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband); - t = 1.0 - (1.0 * start2 / last); - uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075); - } - } - memset(sce->sf_idx, 0, sizeof(sce->sf_idx)); - abs_pow34_v(s->scoefs, sce->coeffs, 1024); - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = w*128; - for (g = 0; g < sce->ics.num_swb; g++) { - const float *coefs = sce->coeffs + start; - const float *scaled = s->scoefs + start; - const int size = sce->ics.swb_sizes[g]; - int scf, prev_scf, step; - int min_scf = -1, max_scf = 256; - float curdiff; - if (maxq[w*16+g] < 21.544) { - sce->zeroes[w*16+g] = 1; - start += size; - continue; - } - sce->zeroes[w*16+g] = 0; - scf = prev_scf = av_clip(SCALE_ONE_POS - SCALE_DIV_512 - log2(1/maxq[w*16+g])*16/3, 60, 218); - step = 16; - for (;;) { - float dist = 0.0f; - int quant_max; - - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - int b; - dist += quantize_band_cost(s, coefs + w2*128, - scaled + w2*128, - sce->ics.swb_sizes[g], - scf, - ESC_BT, - lambda, - INFINITY, - &b); - dist -= b; - } - dist *= 1.0f / 512.0f / lambda; - quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[200 - scf + SCALE_ONE_POS - SCALE_DIV_512]); - if (quant_max >= 8191) { // too much, return to the previous quantizer - sce->sf_idx[w*16+g] = prev_scf; - break; - } - prev_scf = scf; - curdiff = fabsf(dist - uplim[w*16+g]); - if (curdiff <= 1.0f) - step = 0; - else - step = log2(curdiff); - if (dist > uplim[w*16+g]) - step = -step; - scf += step; - scf = av_clip_uint8(scf); - step = scf - prev_scf; - if (FFABS(step) <= 1 || (step > 0 && scf >= max_scf) || (step < 0 && scf <= min_scf)) { - sce->sf_idx[w*16+g] = av_clip(scf, min_scf, max_scf); - break; - } - if (step > 0) - min_scf = prev_scf; - else - max_scf = prev_scf; - } - start += size; - } - } - minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX; - for (i = 1; i < 128; i++) { - if (!sce->sf_idx[i]) - sce->sf_idx[i] = sce->sf_idx[i-1]; - else - minq = FFMIN(minq, sce->sf_idx[i]); - } - if (minq == INT_MAX) - minq = 0; - minq = FFMIN(minq, SCALE_MAX_POS); - maxsf = FFMIN(minq + SCALE_MAX_DIFF, SCALE_MAX_POS); - for (i = 126; i >= 0; i--) { - if (!sce->sf_idx[i]) - sce->sf_idx[i] = sce->sf_idx[i+1]; - sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, maxsf); - } -} - -static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s, - SingleChannelElement *sce, - const float lambda) -{ - int start = 0, i, w, w2, g; - int minq = 255; - - memset(sce->sf_idx, 0, sizeof(sce->sf_idx)); - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = w*128; - for (g = 0; g < sce->ics.num_swb; g++) { - for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { - FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g]; - if (band->energy <= band->threshold) { - sce->sf_idx[(w+w2)*16+g] = 218; - sce->zeroes[(w+w2)*16+g] = 1; - } else { - sce->sf_idx[(w+w2)*16+g] = av_clip(SCALE_ONE_POS - SCALE_DIV_512 + log2(band->threshold), 80, 218); - sce->zeroes[(w+w2)*16+g] = 0; - } - minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]); - } - } - } - for (i = 0; i < 128; i++) { - sce->sf_idx[i] = 140; - //av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1); - } - //set the same quantizers inside window groups - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) - for (g = 0; g < sce->ics.num_swb; g++) - for (w2 = 1; w2 < sce->ics.group_len[w]; w2++) - sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g]; -} - -static void search_for_ms(AACEncContext *s, ChannelElement *cpe, - const float lambda) -{ - int start = 0, i, w, w2, g; - float M[128], S[128]; - float *L34 = s->scoefs, *R34 = s->scoefs + 128, *M34 = s->scoefs + 128*2, *S34 = s->scoefs + 128*3; - SingleChannelElement *sce0 = &cpe->ch[0]; - SingleChannelElement *sce1 = &cpe->ch[1]; - if (!cpe->common_window) - return; - for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) { - for (g = 0; g < sce0->ics.num_swb; g++) { - if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) { - float dist1 = 0.0f, dist2 = 0.0f; - for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { - FFPsyBand *band0 = &s->psy.psy_bands[(s->cur_channel+0)*PSY_MAX_BANDS+(w+w2)*16+g]; - FFPsyBand *band1 = &s->psy.psy_bands[(s->cur_channel+1)*PSY_MAX_BANDS+(w+w2)*16+g]; - float minthr = FFMIN(band0->threshold, band1->threshold); - float maxthr = FFMAX(band0->threshold, band1->threshold); - for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { - M[i] = (sce0->coeffs[start+w2*128+i] - + sce1->coeffs[start+w2*128+i]) * 0.5; - S[i] = sce0->coeffs[start+w2*128+i] - - sce1->coeffs[start+w2*128+i]; - } - abs_pow34_v(L34, sce0->coeffs+start+w2*128, sce0->ics.swb_sizes[g]); - abs_pow34_v(R34, sce1->coeffs+start+w2*128, sce0->ics.swb_sizes[g]); - abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]); - abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]); - dist1 += quantize_band_cost(s, sce0->coeffs + start + w2*128, - L34, - sce0->ics.swb_sizes[g], - sce0->sf_idx[(w+w2)*16+g], - sce0->band_type[(w+w2)*16+g], - lambda / band0->threshold, INFINITY, NULL); - dist1 += quantize_band_cost(s, sce1->coeffs + start + w2*128, - R34, - sce1->ics.swb_sizes[g], - sce1->sf_idx[(w+w2)*16+g], - sce1->band_type[(w+w2)*16+g], - lambda / band1->threshold, INFINITY, NULL); - dist2 += quantize_band_cost(s, M, - M34, - sce0->ics.swb_sizes[g], - sce0->sf_idx[(w+w2)*16+g], - sce0->band_type[(w+w2)*16+g], - lambda / maxthr, INFINITY, NULL); - dist2 += quantize_band_cost(s, S, - S34, - sce1->ics.swb_sizes[g], - sce1->sf_idx[(w+w2)*16+g], - sce1->band_type[(w+w2)*16+g], - lambda / minthr, INFINITY, NULL); - } - cpe->ms_mask[w*16+g] = dist2 < dist1; - } - start += sce0->ics.swb_sizes[g]; - } - } -} - -AACCoefficientsEncoder ff_aac_coders[] = { - { - search_for_quantizers_faac, - encode_window_bands_info, - quantize_and_encode_band, - search_for_ms, - }, - { - search_for_quantizers_anmr, - encode_window_bands_info, - quantize_and_encode_band, - search_for_ms, - }, - { - search_for_quantizers_twoloop, - encode_window_bands_info, - quantize_and_encode_band, - search_for_ms, - }, - { - search_for_quantizers_fast, - encode_window_bands_info, - quantize_and_encode_band, - search_for_ms, - }, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/aacdectab.h b/tizen/distrib/ffmpeg/libavcodec/aacdectab.h deleted file mode 100644 index b74f100..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacdectab.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * AAC decoder data - * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) - * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC decoder data - * @author Oded Shimon ( ods15 ods15 dyndns org ) - * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) - */ - -#ifndef AVCODEC_AACDECTAB_H -#define AVCODEC_AACDECTAB_H - -#include "aac.h" - -#include - -/* @name tns_tmp2_map - * Tables of the tmp2[] arrays of LPC coefficients used for TNS. - * The suffix _M_N[] indicate the values of coef_compress and coef_res - * respectively. - * @{ - */ -static const float tns_tmp2_map_1_3[4] = { - 0.00000000, -0.43388373, 0.64278758, 0.34202015, -}; - -static const float tns_tmp2_map_0_3[8] = { - 0.00000000, -0.43388373, -0.78183150, -0.97492790, - 0.98480773, 0.86602539, 0.64278758, 0.34202015, -}; - -static const float tns_tmp2_map_1_4[8] = { - 0.00000000, -0.20791170, -0.40673664, -0.58778524, - 0.67369562, 0.52643216, 0.36124167, 0.18374951, -}; - -static const float tns_tmp2_map_0_4[16] = { - 0.00000000, -0.20791170, -0.40673664, -0.58778524, - -0.74314481, -0.86602539, -0.95105654, -0.99452192, - 0.99573416, 0.96182561, 0.89516330, 0.79801720, - 0.67369562, 0.52643216, 0.36124167, 0.18374951, -}; - -static const float * const tns_tmp2_map[4] = { - tns_tmp2_map_0_3, - tns_tmp2_map_0_4, - tns_tmp2_map_1_3, - tns_tmp2_map_1_4 -}; -// @} - -static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0 }; - -static const uint8_t aac_channel_layout_map[7][5][2] = { - { { TYPE_SCE, 0 }, }, - { { TYPE_CPE, 0 }, }, - { { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, }, - { { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_SCE, 1 }, }, - { { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_CPE, 1 }, }, - { { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_LFE, 0 }, { TYPE_CPE, 1 }, }, - { { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_LFE, 0 }, { TYPE_CPE, 2 }, { TYPE_CPE, 1 }, }, -}; - -static const int64_t aac_channel_layout[8] = { - CH_LAYOUT_MONO, - CH_LAYOUT_STEREO, - CH_LAYOUT_SURROUND, - CH_LAYOUT_4POINT0, - CH_LAYOUT_5POINT0_BACK, - CH_LAYOUT_5POINT1_BACK, - CH_LAYOUT_7POINT1_WIDE, - 0, -}; - -#endif /* AVCODEC_AACDECTAB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aacenc.c b/tizen/distrib/ffmpeg/libavcodec/aacenc.c deleted file mode 100644 index 90dff15..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacenc.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - * AAC encoder - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC encoder - */ - -/*********************************** - * TODOs: - * add sane pulse detection - * add temporal noise shaping - ***********************************/ - -#include "avcodec.h" -#include "put_bits.h" -#include "dsputil.h" -#include "mpeg4audio.h" - -#include "aac.h" -#include "aactab.h" -#include "aacenc.h" - -#include "psymodel.h" - -static const uint8_t swb_size_1024_96[] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 -}; - -static const uint8_t swb_size_1024_64[] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, - 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 -}; - -static const uint8_t swb_size_1024_48[] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 96 -}; - -static const uint8_t swb_size_1024_32[] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 -}; - -static const uint8_t swb_size_1024_24[] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, - 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64 -}; - -static const uint8_t swb_size_1024_16[] = { - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, - 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64 -}; - -static const uint8_t swb_size_1024_8[] = { - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28, - 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80 -}; - -static const uint8_t *swb_size_1024[] = { - swb_size_1024_96, swb_size_1024_96, swb_size_1024_64, - swb_size_1024_48, swb_size_1024_48, swb_size_1024_32, - swb_size_1024_24, swb_size_1024_24, swb_size_1024_16, - swb_size_1024_16, swb_size_1024_16, swb_size_1024_8 -}; - -static const uint8_t swb_size_128_96[] = { - 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 -}; - -static const uint8_t swb_size_128_48[] = { - 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 -}; - -static const uint8_t swb_size_128_24[] = { - 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 -}; - -static const uint8_t swb_size_128_16[] = { - 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 -}; - -static const uint8_t swb_size_128_8[] = { - 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20 -}; - -static const uint8_t *swb_size_128[] = { - /* the last entry on the following row is swb_size_128_64 but is a - duplicate of swb_size_128_96 */ - swb_size_128_96, swb_size_128_96, swb_size_128_96, - swb_size_128_48, swb_size_128_48, swb_size_128_48, - swb_size_128_24, swb_size_128_24, swb_size_128_16, - swb_size_128_16, swb_size_128_16, swb_size_128_8 -}; - -/** default channel configurations */ -static const uint8_t aac_chan_configs[6][5] = { - {1, TYPE_SCE}, // 1 channel - single channel element - {1, TYPE_CPE}, // 2 channels - channel pair - {2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo - {3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center - {3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo - {4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE -}; - -/** - * Make AAC audio config object. - * @see 1.6.2.1 "Syntax - AudioSpecificConfig" - */ -static void put_audio_specific_config(AVCodecContext *avctx) -{ - PutBitContext pb; - AACEncContext *s = avctx->priv_data; - - init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8); - put_bits(&pb, 5, 2); //object type - AAC-LC - put_bits(&pb, 4, s->samplerate_index); //sample rate index - put_bits(&pb, 4, avctx->channels); - //GASpecificConfig - put_bits(&pb, 1, 0); //frame length - 1024 samples - put_bits(&pb, 1, 0); //does not depend on core coder - put_bits(&pb, 1, 0); //is not extension - flush_put_bits(&pb); -} - -static av_cold int aac_encode_init(AVCodecContext *avctx) -{ - AACEncContext *s = avctx->priv_data; - int i; - const uint8_t *sizes[2]; - int lengths[2]; - - avctx->frame_size = 1024; - - for (i = 0; i < 16; i++) - if (avctx->sample_rate == ff_mpeg4audio_sample_rates[i]) - break; - if (i == 16) { - av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate); - return -1; - } - if (avctx->channels > 6) { - av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels); - return -1; - } - if (avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW) { - av_log(avctx, AV_LOG_ERROR, "Unsupported profile %d\n", avctx->profile); - return -1; - } - if (1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Too many bits per frame requested\n"); - return -1; - } - s->samplerate_index = i; - - dsputil_init(&s->dsp, avctx); - ff_mdct_init(&s->mdct1024, 11, 0, 1.0); - ff_mdct_init(&s->mdct128, 8, 0, 1.0); - // window init - ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); - ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); - ff_init_ff_sine_windows(10); - ff_init_ff_sine_windows(7); - - s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0])); - s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]); - avctx->extradata = av_malloc(2); - avctx->extradata_size = 2; - put_audio_specific_config(avctx); - - sizes[0] = swb_size_1024[i]; - sizes[1] = swb_size_128[i]; - lengths[0] = ff_aac_num_swb_1024[i]; - lengths[1] = ff_aac_num_swb_128[i]; - ff_psy_init(&s->psy, avctx, 2, sizes, lengths); - s->psypp = ff_psy_preprocess_init(avctx); - s->coder = &ff_aac_coders[0]; - - s->lambda = avctx->global_quality ? avctx->global_quality : 120; -#if !CONFIG_HARDCODED_TABLES - for (i = 0; i < 428; i++) - ff_aac_pow2sf_tab[i] = pow(2, (i - 200)/4.); -#endif /* CONFIG_HARDCODED_TABLES */ - - if (avctx->channels > 5) - av_log(avctx, AV_LOG_ERROR, "This encoder does not yet enforce the restrictions on LFEs. " - "The output will most likely be an illegal bitstream.\n"); - - return 0; -} - -static void apply_window_and_mdct(AVCodecContext *avctx, AACEncContext *s, - SingleChannelElement *sce, short *audio, int channel) -{ - int i, j, k; - const float * lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; - const float * swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; - const float * pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; - - if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { - memcpy(s->output, sce->saved, sizeof(float)*1024); - if (sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE) { - memset(s->output, 0, sizeof(s->output[0]) * 448); - for (i = 448; i < 576; i++) - s->output[i] = sce->saved[i] * pwindow[i - 448]; - for (i = 576; i < 704; i++) - s->output[i] = sce->saved[i]; - } - if (sce->ics.window_sequence[0] != LONG_START_SEQUENCE) { - j = channel; - for (i = 0; i < 1024; i++, j += avctx->channels) { - s->output[i+1024] = audio[j] * lwindow[1024 - i - 1]; - sce->saved[i] = audio[j] * lwindow[i]; - } - } else { - j = channel; - for (i = 0; i < 448; i++, j += avctx->channels) - s->output[i+1024] = audio[j]; - for (i = 448; i < 576; i++, j += avctx->channels) - s->output[i+1024] = audio[j] * swindow[576 - i - 1]; - memset(s->output+1024+576, 0, sizeof(s->output[0]) * 448); - j = channel; - for (i = 0; i < 1024; i++, j += avctx->channels) - sce->saved[i] = audio[j]; - } - ff_mdct_calc(&s->mdct1024, sce->coeffs, s->output); - } else { - j = channel; - for (k = 0; k < 1024; k += 128) { - for (i = 448 + k; i < 448 + k + 256; i++) - s->output[i - 448 - k] = (i < 1024) - ? sce->saved[i] - : audio[channel + (i-1024)*avctx->channels]; - s->dsp.vector_fmul (s->output, k ? swindow : pwindow, 128); - s->dsp.vector_fmul_reverse(s->output+128, s->output+128, swindow, 128); - ff_mdct_calc(&s->mdct128, sce->coeffs + k, s->output); - } - j = channel; - for (i = 0; i < 1024; i++, j += avctx->channels) - sce->saved[i] = audio[j]; - } -} - -/** - * Encode ics_info element. - * @see Table 4.6 (syntax of ics_info) - */ -static void put_ics_info(AACEncContext *s, IndividualChannelStream *info) -{ - int w; - - put_bits(&s->pb, 1, 0); // ics_reserved bit - put_bits(&s->pb, 2, info->window_sequence[0]); - put_bits(&s->pb, 1, info->use_kb_window[0]); - if (info->window_sequence[0] != EIGHT_SHORT_SEQUENCE) { - put_bits(&s->pb, 6, info->max_sfb); - put_bits(&s->pb, 1, 0); // no prediction - } else { - put_bits(&s->pb, 4, info->max_sfb); - for (w = 1; w < 8; w++) - put_bits(&s->pb, 1, !info->group_len[w]); - } -} - -/** - * Encode MS data. - * @see 4.6.8.1 "Joint Coding - M/S Stereo" - */ -static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe) -{ - int i, w; - - put_bits(pb, 2, cpe->ms_mode); - if (cpe->ms_mode == 1) - for (w = 0; w < cpe->ch[0].ics.num_windows; w += cpe->ch[0].ics.group_len[w]) - for (i = 0; i < cpe->ch[0].ics.max_sfb; i++) - put_bits(pb, 1, cpe->ms_mask[w*16 + i]); -} - -/** - * Produce integer coefficients from scalefactors provided by the model. - */ -static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans) -{ - int i, w, w2, g, ch; - int start, sum, maxsfb, cmaxsfb; - - for (ch = 0; ch < chans; ch++) { - IndividualChannelStream *ics = &cpe->ch[ch].ics; - start = 0; - maxsfb = 0; - cpe->ch[ch].pulse.num_pulse = 0; - for (w = 0; w < ics->num_windows*16; w += 16) { - for (g = 0; g < ics->num_swb; g++) { - sum = 0; - //apply M/S - if (!ch && cpe->ms_mask[w + g]) { - for (i = 0; i < ics->swb_sizes[g]; i++) { - cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0; - cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i]; - } - } - start += ics->swb_sizes[g]; - } - for (cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w+cmaxsfb-1]; cmaxsfb--) - ; - maxsfb = FFMAX(maxsfb, cmaxsfb); - } - ics->max_sfb = maxsfb; - - //adjust zero bands for window groups - for (w = 0; w < ics->num_windows; w += ics->group_len[w]) { - for (g = 0; g < ics->max_sfb; g++) { - i = 1; - for (w2 = w; w2 < w + ics->group_len[w]; w2++) { - if (!cpe->ch[ch].zeroes[w2*16 + g]) { - i = 0; - break; - } - } - cpe->ch[ch].zeroes[w*16 + g] = i; - } - } - } - - if (chans > 1 && cpe->common_window) { - IndividualChannelStream *ics0 = &cpe->ch[0].ics; - IndividualChannelStream *ics1 = &cpe->ch[1].ics; - int msc = 0; - ics0->max_sfb = FFMAX(ics0->max_sfb, ics1->max_sfb); - ics1->max_sfb = ics0->max_sfb; - for (w = 0; w < ics0->num_windows*16; w += 16) - for (i = 0; i < ics0->max_sfb; i++) - if (cpe->ms_mask[w+i]) - msc++; - if (msc == 0 || ics0->max_sfb == 0) - cpe->ms_mode = 0; - else - cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2; - } -} - -/** - * Encode scalefactor band coding type. - */ -static void encode_band_info(AACEncContext *s, SingleChannelElement *sce) -{ - int w; - - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) - s->coder->encode_window_bands_info(s, sce, w, sce->ics.group_len[w], s->lambda); -} - -/** - * Encode scalefactors. - */ -static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s, - SingleChannelElement *sce) -{ - int off = sce->sf_idx[0], diff; - int i, w; - - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - for (i = 0; i < sce->ics.max_sfb; i++) { - if (!sce->zeroes[w*16 + i]) { - diff = sce->sf_idx[w*16 + i] - off + SCALE_DIFF_ZERO; - if (diff < 0 || diff > 120) - av_log(avctx, AV_LOG_ERROR, "Scalefactor difference is too big to be coded\n"); - off = sce->sf_idx[w*16 + i]; - put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]); - } - } - } -} - -/** - * Encode pulse data. - */ -static void encode_pulses(AACEncContext *s, Pulse *pulse) -{ - int i; - - put_bits(&s->pb, 1, !!pulse->num_pulse); - if (!pulse->num_pulse) - return; - - put_bits(&s->pb, 2, pulse->num_pulse - 1); - put_bits(&s->pb, 6, pulse->start); - for (i = 0; i < pulse->num_pulse; i++) { - put_bits(&s->pb, 5, pulse->pos[i]); - put_bits(&s->pb, 4, pulse->amp[i]); - } -} - -/** - * Encode spectral coefficients processed by psychoacoustic model. - */ -static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce) -{ - int start, i, w, w2; - - for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { - start = 0; - for (i = 0; i < sce->ics.max_sfb; i++) { - if (sce->zeroes[w*16 + i]) { - start += sce->ics.swb_sizes[i]; - continue; - } - for (w2 = w; w2 < w + sce->ics.group_len[w]; w2++) - s->coder->quantize_and_encode_band(s, &s->pb, sce->coeffs + start + w2*128, - sce->ics.swb_sizes[i], - sce->sf_idx[w*16 + i], - sce->band_type[w*16 + i], - s->lambda); - start += sce->ics.swb_sizes[i]; - } - } -} - -/** - * Encode one channel of audio data. - */ -static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, - SingleChannelElement *sce, - int common_window) -{ - put_bits(&s->pb, 8, sce->sf_idx[0]); - if (!common_window) - put_ics_info(s, &sce->ics); - encode_band_info(s, sce); - encode_scale_factors(avctx, s, sce); - encode_pulses(s, &sce->pulse); - put_bits(&s->pb, 1, 0); //tns - put_bits(&s->pb, 1, 0); //ssr - encode_spectral_coeffs(s, sce); - return 0; -} - -/** - * Write some auxiliary information about the created AAC file. - */ -static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, - const char *name) -{ - int i, namelen, padbits; - - namelen = strlen(name) + 2; - put_bits(&s->pb, 3, TYPE_FIL); - put_bits(&s->pb, 4, FFMIN(namelen, 15)); - if (namelen >= 15) - put_bits(&s->pb, 8, namelen - 16); - put_bits(&s->pb, 4, 0); //extension type - filler - padbits = 8 - (put_bits_count(&s->pb) & 7); - align_put_bits(&s->pb); - for (i = 0; i < namelen - 2; i++) - put_bits(&s->pb, 8, name[i]); - put_bits(&s->pb, 12 - padbits, 0); -} - -static int aac_encode_frame(AVCodecContext *avctx, - uint8_t *frame, int buf_size, void *data) -{ - AACEncContext *s = avctx->priv_data; - int16_t *samples = s->samples, *samples2, *la; - ChannelElement *cpe; - int i, j, chans, tag, start_ch; - const uint8_t *chan_map = aac_chan_configs[avctx->channels-1]; - int chan_el_counter[4]; - FFPsyWindowInfo windows[avctx->channels]; - - if (s->last_frame) - return 0; - if (data) { - if (!s->psypp) { - memcpy(s->samples + 1024 * avctx->channels, data, - 1024 * avctx->channels * sizeof(s->samples[0])); - } else { - start_ch = 0; - samples2 = s->samples + 1024 * avctx->channels; - for (i = 0; i < chan_map[0]; i++) { - tag = chan_map[i+1]; - chans = tag == TYPE_CPE ? 2 : 1; - ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch, - samples2 + start_ch, start_ch, chans); - start_ch += chans; - } - } - } - if (!avctx->frame_number) { - memcpy(s->samples, s->samples + 1024 * avctx->channels, - 1024 * avctx->channels * sizeof(s->samples[0])); - return 0; - } - - start_ch = 0; - for (i = 0; i < chan_map[0]; i++) { - FFPsyWindowInfo* wi = windows + start_ch; - tag = chan_map[i+1]; - chans = tag == TYPE_CPE ? 2 : 1; - cpe = &s->cpe[i]; - samples2 = samples + start_ch; - la = samples2 + 1024 * avctx->channels + start_ch; - if (!data) - la = NULL; - for (j = 0; j < chans; j++) { - IndividualChannelStream *ics = &cpe->ch[j].ics; - int k; - wi[j] = ff_psy_suggest_window(&s->psy, samples2, la, start_ch + j, ics->window_sequence[0]); - ics->window_sequence[1] = ics->window_sequence[0]; - ics->window_sequence[0] = wi[j].window_type[0]; - ics->use_kb_window[1] = ics->use_kb_window[0]; - ics->use_kb_window[0] = wi[j].window_shape; - ics->num_windows = wi[j].num_windows; - ics->swb_sizes = s->psy.bands [ics->num_windows == 8]; - ics->num_swb = s->psy.num_bands[ics->num_windows == 8]; - for (k = 0; k < ics->num_windows; k++) - ics->group_len[k] = wi[j].grouping[k]; - - s->cur_channel = start_ch + j; - apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j); - } - start_ch += chans; - } - do { - int frame_bits; - init_put_bits(&s->pb, frame, buf_size*8); - if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)) - put_bitstream_info(avctx, s, LIBAVCODEC_IDENT); - start_ch = 0; - memset(chan_el_counter, 0, sizeof(chan_el_counter)); - for (i = 0; i < chan_map[0]; i++) { - FFPsyWindowInfo* wi = windows + start_ch; - tag = chan_map[i+1]; - chans = tag == TYPE_CPE ? 2 : 1; - cpe = &s->cpe[i]; - for (j = 0; j < chans; j++) { - s->cur_channel = start_ch + j; - s->coder->search_for_quantizers(avctx, s, &cpe->ch[j], s->lambda); - } - cpe->common_window = 0; - if (chans > 1 - && wi[0].window_type[0] == wi[1].window_type[0] - && wi[0].window_shape == wi[1].window_shape) { - - cpe->common_window = 1; - for (j = 0; j < wi[0].num_windows; j++) { - if (wi[0].grouping[j] != wi[1].grouping[j]) { - cpe->common_window = 0; - break; - } - } - } - s->cur_channel = start_ch; - if (cpe->common_window && s->coder->search_for_ms) - s->coder->search_for_ms(s, cpe, s->lambda); - adjust_frame_information(s, cpe, chans); - put_bits(&s->pb, 3, tag); - put_bits(&s->pb, 4, chan_el_counter[tag]++); - if (chans == 2) { - put_bits(&s->pb, 1, cpe->common_window); - if (cpe->common_window) { - put_ics_info(s, &cpe->ch[0].ics); - encode_ms_info(&s->pb, cpe); - } - } - for (j = 0; j < chans; j++) { - s->cur_channel = start_ch + j; - ff_psy_set_band_info(&s->psy, s->cur_channel, cpe->ch[j].coeffs, &wi[j]); - encode_individual_channel(avctx, s, &cpe->ch[j], cpe->common_window); - } - start_ch += chans; - } - - frame_bits = put_bits_count(&s->pb); - if (frame_bits <= 6144 * avctx->channels - 3) - break; - - s->lambda *= avctx->bit_rate * 1024.0f / avctx->sample_rate / frame_bits; - - } while (1); - - put_bits(&s->pb, 3, TYPE_END); - flush_put_bits(&s->pb); - avctx->frame_bits = put_bits_count(&s->pb); - - // rate control stuff - if (!(avctx->flags & CODEC_FLAG_QSCALE)) { - float ratio = avctx->bit_rate * 1024.0f / avctx->sample_rate / avctx->frame_bits; - s->lambda *= ratio; - s->lambda = FFMIN(s->lambda, 65536.f); - } - - if (!data) - s->last_frame = 1; - memcpy(s->samples, s->samples + 1024 * avctx->channels, - 1024 * avctx->channels * sizeof(s->samples[0])); - return put_bits_count(&s->pb)>>3; -} - -static av_cold int aac_encode_end(AVCodecContext *avctx) -{ - AACEncContext *s = avctx->priv_data; - - ff_mdct_end(&s->mdct1024); - ff_mdct_end(&s->mdct128); - ff_psy_end(&s->psy); - ff_psy_preprocess_end(s->psypp); - av_freep(&s->samples); - av_freep(&s->cpe); - return 0; -} - -AVCodec aac_encoder = { - "aac", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AAC, - sizeof(AACEncContext), - aac_encode_init, - aac_encode_frame, - aac_encode_end, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/aacenc.h b/tizen/distrib/ffmpeg/libavcodec/aacenc.h deleted file mode 100644 index e99be98..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacenc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * AAC encoder - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AACENC_H -#define AVCODEC_AACENC_H - -#include "avcodec.h" -#include "put_bits.h" -#include "dsputil.h" - -#include "aac.h" - -#include "psymodel.h" - -struct AACEncContext; - -typedef struct AACCoefficientsEncoder { - void (*search_for_quantizers)(AVCodecContext *avctx, struct AACEncContext *s, - SingleChannelElement *sce, const float lambda); - void (*encode_window_bands_info)(struct AACEncContext *s, SingleChannelElement *sce, - int win, int group_len, const float lambda); - void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, int size, - int scale_idx, int cb, const float lambda); - void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe, const float lambda); -} AACCoefficientsEncoder; - -extern AACCoefficientsEncoder ff_aac_coders[]; - -/** - * AAC encoder context - */ -typedef struct AACEncContext { - PutBitContext pb; - FFTContext mdct1024; ///< long (1024 samples) frame transform context - FFTContext mdct128; ///< short (128 samples) frame transform context - DSPContext dsp; - DECLARE_ALIGNED(16, FFTSample, output)[2048]; ///< temporary buffer for MDCT input coefficients - int16_t* samples; ///< saved preprocessed input - - int samplerate_index; ///< MPEG-4 samplerate index - - ChannelElement *cpe; ///< channel elements - FFPsyContext psy; - struct FFPsyPreprocessContext* psypp; - AACCoefficientsEncoder *coder; - int cur_channel; - int last_frame; - float lambda; - DECLARE_ALIGNED(16, int, qcoefs)[96][2]; ///< quantized coefficients - DECLARE_ALIGNED(16, float, scoefs)[1024]; ///< scaled coefficients -} AACEncContext; - -#endif /* AVCODEC_AACENC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aacpsy.c b/tizen/distrib/ffmpeg/libavcodec/aacpsy.c deleted file mode 100644 index 53dac3d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacpsy.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * AAC encoder psychoacoustic model - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC encoder psychoacoustic model - */ - -#include "avcodec.h" -#include "aactab.h" -#include "psymodel.h" - -/*********************************** - * TODOs: - * thresholds linearization after their modifications for attaining given bitrate - * try other bitrate controlling mechanism (maybe use ratecontrol.c?) - * control quality for quality-based output - **********************************/ - -/** - * constants for 3GPP AAC psychoacoustic model - * @{ - */ -#define PSY_3GPP_SPREAD_LOW 1.5f // spreading factor for ascending threshold spreading (15 dB/Bark) -#define PSY_3GPP_SPREAD_HI 3.0f // spreading factor for descending threshold spreading (30 dB/Bark) - -#define PSY_3GPP_RPEMIN 0.01f -#define PSY_3GPP_RPELEV 2.0f -/** - * @} - */ - -/** - * information for single band used by 3GPP TS26.403-inspired psychoacoustic model - */ -typedef struct Psy3gppBand{ - float energy; ///< band energy - float ffac; ///< form factor - float thr; ///< energy threshold - float min_snr; ///< minimal SNR - float thr_quiet; ///< threshold in quiet -}Psy3gppBand; - -/** - * single/pair channel context for psychoacoustic model - */ -typedef struct Psy3gppChannel{ - Psy3gppBand band[128]; ///< bands information - Psy3gppBand prev_band[128]; ///< bands information from the previous frame - - float win_energy; ///< sliding average of channel energy - float iir_state[2]; ///< hi-pass IIR filter state - uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence) - enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame -}Psy3gppChannel; - -/** - * psychoacoustic model frame type-dependent coefficients - */ -typedef struct Psy3gppCoeffs{ - float ath [64]; ///< absolute threshold of hearing per bands - float barks [64]; ///< Bark value for each spectral band in long frame - float spread_low[64]; ///< spreading factor for low-to-high threshold spreading in long frame - float spread_hi [64]; ///< spreading factor for high-to-low threshold spreading in long frame -}Psy3gppCoeffs; - -/** - * 3GPP TS26.403-inspired psychoacoustic model specific data - */ -typedef struct Psy3gppContext{ - Psy3gppCoeffs psy_coef[2]; - Psy3gppChannel *ch; -}Psy3gppContext; - -/** - * Calculate Bark value for given line. - */ -static av_cold float calc_bark(float f) -{ - return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f)); -} - -#define ATH_ADD 4 -/** - * Calculate ATH value for given frequency. - * Borrowed from Lame. - */ -static av_cold float ath(float f, float add) -{ - f /= 1000.0f; - return 3.64 * pow(f, -0.8) - - 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4)) - + 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7)) - + (0.6 + 0.04 * add) * 0.001 * f * f * f * f; -} - -static av_cold int psy_3gpp_init(FFPsyContext *ctx) { - Psy3gppContext *pctx; - float barks[1024]; - int i, j, g, start; - float prev, minscale, minath; - - ctx->model_priv_data = av_mallocz(sizeof(Psy3gppContext)); - pctx = (Psy3gppContext*) ctx->model_priv_data; - - for (i = 0; i < 1024; i++) - barks[i] = calc_bark(i * ctx->avctx->sample_rate / 2048.0); - minath = ath(3410, ATH_ADD); - for (j = 0; j < 2; j++) { - Psy3gppCoeffs *coeffs = &pctx->psy_coef[j]; - i = 0; - prev = 0.0; - for (g = 0; g < ctx->num_bands[j]; g++) { - i += ctx->bands[j][g]; - coeffs->barks[g] = (barks[i - 1] + prev) / 2.0; - prev = barks[i - 1]; - } - for (g = 0; g < ctx->num_bands[j] - 1; g++) { - coeffs->spread_low[g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_LOW); - coeffs->spread_hi [g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_HI); - } - start = 0; - for (g = 0; g < ctx->num_bands[j]; g++) { - minscale = ath(ctx->avctx->sample_rate * start / 1024.0, ATH_ADD); - for (i = 1; i < ctx->bands[j][g]; i++) - minscale = FFMIN(minscale, ath(ctx->avctx->sample_rate * (start + i) / 1024.0 / 2.0, ATH_ADD)); - coeffs->ath[g] = minscale - minath; - start += ctx->bands[j][g]; - } - } - - pctx->ch = av_mallocz(sizeof(Psy3gppChannel) * ctx->avctx->channels); - return 0; -} - -/** - * IIR filter used in block switching decision - */ -static float iir_filter(int in, float state[2]) -{ - float ret; - - ret = 0.7548f * (in - state[0]) + 0.5095f * state[1]; - state[0] = in; - state[1] = ret; - return ret; -} - -/** - * window grouping information stored as bits (0 - new group, 1 - group continues) - */ -static const uint8_t window_grouping[9] = { - 0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36 -}; - -/** - * Tell encoder which window types to use. - * @see 3GPP TS26.403 5.4.1 "Blockswitching" - */ -static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx, - const int16_t *audio, const int16_t *la, - int channel, int prev_type) -{ - int i, j; - int br = ctx->avctx->bit_rate / ctx->avctx->channels; - int attack_ratio = br <= 16000 ? 18 : 10; - Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data; - Psy3gppChannel *pch = &pctx->ch[channel]; - uint8_t grouping = 0; - FFPsyWindowInfo wi; - - memset(&wi, 0, sizeof(wi)); - if (la) { - float s[8], v; - int switch_to_eight = 0; - float sum = 0.0, sum2 = 0.0; - int attack_n = 0; - for (i = 0; i < 8; i++) { - for (j = 0; j < 128; j++) { - v = iir_filter(audio[(i*128+j)*ctx->avctx->channels], pch->iir_state); - sum += v*v; - } - s[i] = sum; - sum2 += sum; - } - for (i = 0; i < 8; i++) { - if (s[i] > pch->win_energy * attack_ratio) { - attack_n = i + 1; - switch_to_eight = 1; - break; - } - } - pch->win_energy = pch->win_energy*7/8 + sum2/64; - - wi.window_type[1] = prev_type; - switch (prev_type) { - case ONLY_LONG_SEQUENCE: - wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; - break; - case LONG_START_SEQUENCE: - wi.window_type[0] = EIGHT_SHORT_SEQUENCE; - grouping = pch->next_grouping; - break; - case LONG_STOP_SEQUENCE: - wi.window_type[0] = ONLY_LONG_SEQUENCE; - break; - case EIGHT_SHORT_SEQUENCE: - wi.window_type[0] = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; - grouping = switch_to_eight ? pch->next_grouping : 0; - break; - } - pch->next_grouping = window_grouping[attack_n]; - } else { - for (i = 0; i < 3; i++) - wi.window_type[i] = prev_type; - grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0; - } - - wi.window_shape = 1; - if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { - wi.num_windows = 1; - wi.grouping[0] = 1; - } else { - int lastgrp = 0; - wi.num_windows = 8; - for (i = 0; i < 8; i++) { - if (!((grouping >> i) & 1)) - lastgrp = i; - wi.grouping[lastgrp]++; - } - } - - return wi; -} - -/** - * Calculate band thresholds as suggested in 3GPP TS26.403 - */ -static void psy_3gpp_analyze(FFPsyContext *ctx, int channel, - const float *coefs, FFPsyWindowInfo *wi) -{ - Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data; - Psy3gppChannel *pch = &pctx->ch[channel]; - int start = 0; - int i, w, g; - const int num_bands = ctx->num_bands[wi->num_windows == 8]; - const uint8_t* band_sizes = ctx->bands[wi->num_windows == 8]; - Psy3gppCoeffs *coeffs = &pctx->psy_coef[wi->num_windows == 8]; - - //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" - for (w = 0; w < wi->num_windows*16; w += 16) { - for (g = 0; g < num_bands; g++) { - Psy3gppBand *band = &pch->band[w+g]; - band->energy = 0.0f; - for (i = 0; i < band_sizes[g]; i++) - band->energy += coefs[start+i] * coefs[start+i]; - band->energy *= 1.0f / (512*512); - band->thr = band->energy * 0.001258925f; - start += band_sizes[g]; - - ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].energy = band->energy; - } - } - //modify thresholds - spread, threshold in quiet - 5.4.3 "Spreaded Energy Calculation" - for (w = 0; w < wi->num_windows*16; w += 16) { - Psy3gppBand *band = &pch->band[w]; - for (g = 1; g < num_bands; g++) - band[g].thr = FFMAX(band[g].thr, band[g-1].thr * coeffs->spread_low[g-1]); - for (g = num_bands - 2; g >= 0; g--) - band[g].thr = FFMAX(band[g].thr, band[g+1].thr * coeffs->spread_hi [g]); - for (g = 0; g < num_bands; g++) { - band[g].thr_quiet = FFMAX(band[g].thr, coeffs->ath[g]); - if (wi->num_windows != 8 && wi->window_type[1] != EIGHT_SHORT_SEQUENCE) - band[g].thr_quiet = FFMAX(PSY_3GPP_RPEMIN*band[g].thr_quiet, - FFMIN(band[g].thr_quiet, - PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet)); - band[g].thr = FFMAX(band[g].thr, band[g].thr_quiet * 0.25); - - ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].threshold = band[g].thr; - } - } - memcpy(pch->prev_band, pch->band, sizeof(pch->band)); -} - -static av_cold void psy_3gpp_end(FFPsyContext *apc) -{ - Psy3gppContext *pctx = (Psy3gppContext*) apc->model_priv_data; - av_freep(&pctx->ch); - av_freep(&apc->model_priv_data); -} - - -const FFPsyModel ff_aac_psy_model = -{ - .name = "3GPP TS 26.403-inspired model", - .init = psy_3gpp_init, - .window = psy_3gpp_window, - .analyze = psy_3gpp_analyze, - .end = psy_3gpp_end, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/aacpsy.h b/tizen/distrib/ffmpeg/libavcodec/aacpsy.h deleted file mode 100644 index 05c93cd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacpsy.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * AAC encoder psychoacoustic model - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AACPSY_H -#define AVCODEC_AACPSY_H - -#include "avcodec.h" -#include "aac.h" -//#include "lowpass.h" - -enum AACPsyModelType{ - AAC_PSY_TEST, ///< a sample model to exercise encoder - AAC_PSY_3GPP, ///< model following recommendations from 3GPP TS 26.403 - - AAC_NB_PSY_MODELS ///< total number of psychoacoustic models, since it's not a part of the ABI new models can be added freely -}; - -/** - * context used by psychoacoustic model - */ -typedef struct AACPsyContext { - AVCodecContext *avctx; ///< encoder context -}AACPsyContext; - -/** - * Cleanup model context at the end. - * - * @param ctx model context - */ -void ff_aac_psy_end(AACPsyContext *ctx); - -#endif /* AVCODEC_AACPSY_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aacsbr.c b/tizen/distrib/ffmpeg/libavcodec/aacsbr.c deleted file mode 100644 index 0de81a5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacsbr.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* - * AAC Spectral Band Replication decoding functions - * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) - * Copyright (c) 2009-2010 Alex Converse - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC Spectral Band Replication decoding functions - * @author Robert Swain ( rob opendot cl ) - */ - -#include "aac.h" -#include "sbr.h" -#include "aacsbr.h" -#include "aacsbrdata.h" -#include "fft.h" - -#include -#include - -#define ENVELOPE_ADJUSTMENT_OFFSET 2 -#define NOISE_FLOOR_OFFSET 6.0f - -/** - * SBR VLC tables - */ -enum { - T_HUFFMAN_ENV_1_5DB, - F_HUFFMAN_ENV_1_5DB, - T_HUFFMAN_ENV_BAL_1_5DB, - F_HUFFMAN_ENV_BAL_1_5DB, - T_HUFFMAN_ENV_3_0DB, - F_HUFFMAN_ENV_3_0DB, - T_HUFFMAN_ENV_BAL_3_0DB, - F_HUFFMAN_ENV_BAL_3_0DB, - T_HUFFMAN_NOISE_3_0DB, - T_HUFFMAN_NOISE_BAL_3_0DB, -}; - -/** - * bs_frame_class - frame class of current SBR frame (14496-3 sp04 p98) - */ -enum { - FIXFIX, - FIXVAR, - VARFIX, - VARVAR, -}; - -enum { - EXTENSION_ID_PS = 2, -}; - -static VLC vlc_sbr[10]; -static const int8_t vlc_sbr_lav[10] = - { 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 }; -static DECLARE_ALIGNED(16, float, analysis_cos_pre)[64]; -static DECLARE_ALIGNED(16, float, analysis_sin_pre)[64]; -static DECLARE_ALIGNED(16, float, analysis_cossin_post)[32][2]; -static const DECLARE_ALIGNED(16, float, zero64)[64]; - -#define SBR_INIT_VLC_STATIC(num, size) \ - INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \ - sbr_tmp[num].sbr_bits , 1, 1, \ - sbr_tmp[num].sbr_codes, sbr_tmp[num].elem_size, sbr_tmp[num].elem_size, \ - size) - -#define SBR_VLC_ROW(name) \ - { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) } - -av_cold void ff_aac_sbr_init(void) -{ - int n, k; - static const struct { - const void *sbr_codes, *sbr_bits; - const unsigned int table_size, elem_size; - } sbr_tmp[] = { - SBR_VLC_ROW(t_huffman_env_1_5dB), - SBR_VLC_ROW(f_huffman_env_1_5dB), - SBR_VLC_ROW(t_huffman_env_bal_1_5dB), - SBR_VLC_ROW(f_huffman_env_bal_1_5dB), - SBR_VLC_ROW(t_huffman_env_3_0dB), - SBR_VLC_ROW(f_huffman_env_3_0dB), - SBR_VLC_ROW(t_huffman_env_bal_3_0dB), - SBR_VLC_ROW(f_huffman_env_bal_3_0dB), - SBR_VLC_ROW(t_huffman_noise_3_0dB), - SBR_VLC_ROW(t_huffman_noise_bal_3_0dB), - }; - - // SBR VLC table initialization - SBR_INIT_VLC_STATIC(0, 1098); - SBR_INIT_VLC_STATIC(1, 1092); - SBR_INIT_VLC_STATIC(2, 768); - SBR_INIT_VLC_STATIC(3, 1026); - SBR_INIT_VLC_STATIC(4, 1058); - SBR_INIT_VLC_STATIC(5, 1052); - SBR_INIT_VLC_STATIC(6, 544); - SBR_INIT_VLC_STATIC(7, 544); - SBR_INIT_VLC_STATIC(8, 592); - SBR_INIT_VLC_STATIC(9, 512); - - for (n = 0; n < 64; n++) { - float pre = M_PI * n / 64; - analysis_cos_pre[n] = cosf(pre); - analysis_sin_pre[n] = sinf(pre); - } - for (k = 0; k < 32; k++) { - float post = M_PI * (k + 0.5) / 128; - analysis_cossin_post[k][0] = 4.0 * cosf(post); - analysis_cossin_post[k][1] = -4.0 * sinf(post); - } - for (n = 1; n < 320; n++) - sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n]; - sbr_qmf_window_us[384] = -sbr_qmf_window_us[384]; - sbr_qmf_window_us[512] = -sbr_qmf_window_us[512]; - - for (n = 0; n < 320; n++) - sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n]; -} - -av_cold void ff_aac_sbr_ctx_init(SpectralBandReplication *sbr) -{ - sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 - sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; - sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); - sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); - ff_mdct_init(&sbr->mdct, 7, 1, 1.0/64); - ff_rdft_init(&sbr->rdft, 6, IDFT_R2C); -} - -av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr) -{ - ff_mdct_end(&sbr->mdct); - ff_rdft_end(&sbr->rdft); -} - -static int qsort_comparison_function_int16(const void *a, const void *b) -{ - return *(const int16_t *)a - *(const int16_t *)b; -} - -static inline int in_table_int16(const int16_t *table, int last_el, int16_t needle) -{ - int i; - for (i = 0; i <= last_el; i++) - if (table[i] == needle) - return 1; - return 0; -} - -/// Limiter Frequency Band Table (14496-3 sp04 p198) -static void sbr_make_f_tablelim(SpectralBandReplication *sbr) -{ - int k; - if (sbr->bs_limiter_bands > 0) { - static const float bands_warped[3] = { 1.32715174233856803909f, //2^(0.49/1.2) - 1.18509277094158210129f, //2^(0.49/2) - 1.11987160404675912501f }; //2^(0.49/3) - const float lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1]; - int16_t patch_borders[7]; - uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim; - - patch_borders[0] = sbr->kx[1]; - for (k = 1; k <= sbr->num_patches; k++) - patch_borders[k] = patch_borders[k-1] + sbr->patch_num_subbands[k-1]; - - memcpy(sbr->f_tablelim, sbr->f_tablelow, - (sbr->n[0] + 1) * sizeof(sbr->f_tablelow[0])); - if (sbr->num_patches > 1) - memcpy(sbr->f_tablelim + sbr->n[0] + 1, patch_borders + 1, - (sbr->num_patches - 1) * sizeof(patch_borders[0])); - - qsort(sbr->f_tablelim, sbr->num_patches + sbr->n[0], - sizeof(sbr->f_tablelim[0]), - qsort_comparison_function_int16); - - sbr->n_lim = sbr->n[0] + sbr->num_patches - 1; - while (out < sbr->f_tablelim + sbr->n_lim) { - if (*in >= *out * lim_bands_per_octave_warped) { - *++out = *in++; - } else if (*in == *out || - !in_table_int16(patch_borders, sbr->num_patches, *in)) { - in++; - sbr->n_lim--; - } else if (!in_table_int16(patch_borders, sbr->num_patches, *out)) { - *out = *in++; - sbr->n_lim--; - } else { - *++out = *in++; - } - } - } else { - sbr->f_tablelim[0] = sbr->f_tablelow[0]; - sbr->f_tablelim[1] = sbr->f_tablelow[sbr->n[0]]; - sbr->n_lim = 1; - } -} - -static unsigned int read_sbr_header(SpectralBandReplication *sbr, GetBitContext *gb) -{ - unsigned int cnt = get_bits_count(gb); - uint8_t bs_header_extra_1; - uint8_t bs_header_extra_2; - int old_bs_limiter_bands = sbr->bs_limiter_bands; - SpectrumParameters old_spectrum_params; - - sbr->start = 1; - - // Save last spectrum parameters variables to compare to new ones - memcpy(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters)); - - sbr->bs_amp_res_header = get_bits1(gb); - sbr->spectrum_params.bs_start_freq = get_bits(gb, 4); - sbr->spectrum_params.bs_stop_freq = get_bits(gb, 4); - sbr->spectrum_params.bs_xover_band = get_bits(gb, 3); - skip_bits(gb, 2); // bs_reserved - - bs_header_extra_1 = get_bits1(gb); - bs_header_extra_2 = get_bits1(gb); - - if (bs_header_extra_1) { - sbr->spectrum_params.bs_freq_scale = get_bits(gb, 2); - sbr->spectrum_params.bs_alter_scale = get_bits1(gb); - sbr->spectrum_params.bs_noise_bands = get_bits(gb, 2); - } else { - sbr->spectrum_params.bs_freq_scale = 2; - sbr->spectrum_params.bs_alter_scale = 1; - sbr->spectrum_params.bs_noise_bands = 2; - } - - // Check if spectrum parameters changed - if (memcmp(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters))) - sbr->reset = 1; - - if (bs_header_extra_2) { - sbr->bs_limiter_bands = get_bits(gb, 2); - sbr->bs_limiter_gains = get_bits(gb, 2); - sbr->bs_interpol_freq = get_bits1(gb); - sbr->bs_smoothing_mode = get_bits1(gb); - } else { - sbr->bs_limiter_bands = 2; - sbr->bs_limiter_gains = 2; - sbr->bs_interpol_freq = 1; - sbr->bs_smoothing_mode = 1; - } - - if (sbr->bs_limiter_bands != old_bs_limiter_bands && !sbr->reset) - sbr_make_f_tablelim(sbr); - - return get_bits_count(gb) - cnt; -} - -static int array_min_int16(const int16_t *array, int nel) -{ - int i, min = array[0]; - for (i = 1; i < nel; i++) - min = FFMIN(array[i], min); - return min; -} - -static void make_bands(int16_t* bands, int start, int stop, int num_bands) -{ - int k, previous, present; - float base, prod; - - base = powf((float)stop / start, 1.0f / num_bands); - prod = start; - previous = start; - - for (k = 0; k < num_bands-1; k++) { - prod *= base; - present = lrintf(prod); - bands[k] = present - previous; - previous = present; - } - bands[num_bands-1] = stop - previous; -} - -static int check_n_master(AVCodecContext *avccontext, int n_master, int bs_xover_band) -{ - // Requirements (14496-3 sp04 p205) - if (n_master <= 0) { - av_log(avccontext, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master); - return -1; - } - if (bs_xover_band >= n_master) { - av_log(avccontext, AV_LOG_ERROR, - "Invalid bitstream, crossover band index beyond array bounds: %d\n", - bs_xover_band); - return -1; - } - return 0; -} - -/// Master Frequency Band Table (14496-3 sp04 p194) -static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, - SpectrumParameters *spectrum) -{ - unsigned int temp, max_qmf_subbands; - unsigned int start_min, stop_min; - int k; - const int8_t *sbr_offset_ptr; - int16_t stop_dk[13]; - - if (sbr->sample_rate < 32000) { - temp = 3000; - } else if (sbr->sample_rate < 64000) { - temp = 4000; - } else - temp = 5000; - - start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate; - stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate; - - switch (sbr->sample_rate) { - case 16000: - sbr_offset_ptr = sbr_offset[0]; - break; - case 22050: - sbr_offset_ptr = sbr_offset[1]; - break; - case 24000: - sbr_offset_ptr = sbr_offset[2]; - break; - case 32000: - sbr_offset_ptr = sbr_offset[3]; - break; - case 44100: case 48000: case 64000: - sbr_offset_ptr = sbr_offset[4]; - break; - case 88200: case 96000: case 128000: case 176400: case 192000: - sbr_offset_ptr = sbr_offset[5]; - break; - default: - av_log(ac->avccontext, AV_LOG_ERROR, - "Unsupported sample rate for SBR: %d\n", sbr->sample_rate); - return -1; - } - - sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq]; - - if (spectrum->bs_stop_freq < 14) { - sbr->k[2] = stop_min; - make_bands(stop_dk, stop_min, 64, 13); - qsort(stop_dk, 13, sizeof(stop_dk[0]), qsort_comparison_function_int16); - for (k = 0; k < spectrum->bs_stop_freq; k++) - sbr->k[2] += stop_dk[k]; - } else if (spectrum->bs_stop_freq == 14) { - sbr->k[2] = 2*sbr->k[0]; - } else if (spectrum->bs_stop_freq == 15) { - sbr->k[2] = 3*sbr->k[0]; - } else { - av_log(ac->avccontext, AV_LOG_ERROR, - "Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq); - return -1; - } - sbr->k[2] = FFMIN(64, sbr->k[2]); - - // Requirements (14496-3 sp04 p205) - if (sbr->sample_rate <= 32000) { - max_qmf_subbands = 48; - } else if (sbr->sample_rate == 44100) { - max_qmf_subbands = 35; - } else if (sbr->sample_rate >= 48000) - max_qmf_subbands = 32; - - if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]); - return -1; - } - - if (!spectrum->bs_freq_scale) { - unsigned int dk; - int k2diff; - - dk = spectrum->bs_alter_scale + 1; - sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1; - if (check_n_master(ac->avccontext, sbr->n_master, sbr->spectrum_params.bs_xover_band)) - return -1; - - for (k = 1; k <= sbr->n_master; k++) - sbr->f_master[k] = dk; - - k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk; - if (k2diff < 0) { - sbr->f_master[1]--; - sbr->f_master[2]-= (k2diff < 1); - } else if (k2diff) { - sbr->f_master[sbr->n_master]++; - } - - sbr->f_master[0] = sbr->k[0]; - for (k = 1; k <= sbr->n_master; k++) - sbr->f_master[k] += sbr->f_master[k - 1]; - - } else { - int half_bands = 7 - spectrum->bs_freq_scale; // bs_freq_scale = {1,2,3} - int two_regions, num_bands_0; - int vdk0_max, vdk1_min; - int16_t vk0[49]; - - if (49 * sbr->k[2] > 110 * sbr->k[0]) { - two_regions = 1; - sbr->k[1] = 2 * sbr->k[0]; - } else { - two_regions = 0; - sbr->k[1] = sbr->k[2]; - } - - num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2; - - if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205) - av_log(ac->avccontext, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0); - return -1; - } - - vk0[0] = 0; - - make_bands(vk0+1, sbr->k[0], sbr->k[1], num_bands_0); - - qsort(vk0 + 1, num_bands_0, sizeof(vk0[1]), qsort_comparison_function_int16); - vdk0_max = vk0[num_bands_0]; - - vk0[0] = sbr->k[0]; - for (k = 1; k <= num_bands_0; k++) { - if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205) - av_log(ac->avccontext, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]); - return -1; - } - vk0[k] += vk0[k-1]; - } - - if (two_regions) { - int16_t vk1[49]; - float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f - : 1.0f; // bs_alter_scale = {0,1} - int num_bands_1 = lrintf(half_bands * invwarp * - log2f(sbr->k[2] / (float)sbr->k[1])) * 2; - - make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1); - - vdk1_min = array_min_int16(vk1 + 1, num_bands_1); - - if (vdk1_min < vdk0_max) { - int change; - qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16); - change = FFMIN(vdk0_max - vk1[1], (vk1[num_bands_1] - vk1[1]) >> 1); - vk1[1] += change; - vk1[num_bands_1] -= change; - } - - qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16); - - vk1[0] = sbr->k[1]; - for (k = 1; k <= num_bands_1; k++) { - if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205) - av_log(ac->avccontext, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]); - return -1; - } - vk1[k] += vk1[k-1]; - } - - sbr->n_master = num_bands_0 + num_bands_1; - if (check_n_master(ac->avccontext, sbr->n_master, sbr->spectrum_params.bs_xover_band)) - return -1; - memcpy(&sbr->f_master[0], vk0, - (num_bands_0 + 1) * sizeof(sbr->f_master[0])); - memcpy(&sbr->f_master[num_bands_0 + 1], vk1 + 1, - num_bands_1 * sizeof(sbr->f_master[0])); - - } else { - sbr->n_master = num_bands_0; - if (check_n_master(ac->avccontext, sbr->n_master, sbr->spectrum_params.bs_xover_band)) - return -1; - memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0])); - } - } - - return 0; -} - -/// High Frequency Generation - Patch Construction (14496-3 sp04 p216 fig. 4.46) -static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) -{ - int i, k, sb = 0; - int msb = sbr->k[0]; - int usb = sbr->kx[1]; - int goal_sb = ((1000 << 11) + (sbr->sample_rate >> 1)) / sbr->sample_rate; - - sbr->num_patches = 0; - - if (goal_sb < sbr->kx[1] + sbr->m[1]) { - for (k = 0; sbr->f_master[k] < goal_sb; k++) ; - } else - k = sbr->n_master; - - do { - int odd = 0; - for (i = k; i == k || sb > (sbr->k[0] - 1 + msb - odd); i--) { - sb = sbr->f_master[i]; - odd = (sb + sbr->k[0]) & 1; - } - - // Requirements (14496-3 sp04 p205) sets the maximum number of patches to 5. - // After this check the final number of patches can still be six which is - // illegal however the Coding Technologies decoder check stream has a final - // count of 6 patches - if (sbr->num_patches > 5) { - av_log(ac->avccontext, AV_LOG_ERROR, "Too many patches: %d\n", sbr->num_patches); - return -1; - } - - sbr->patch_num_subbands[sbr->num_patches] = FFMAX(sb - usb, 0); - sbr->patch_start_subband[sbr->num_patches] = sbr->k[0] - odd - sbr->patch_num_subbands[sbr->num_patches]; - - if (sbr->patch_num_subbands[sbr->num_patches] > 0) { - usb = sb; - msb = sb; - sbr->num_patches++; - } else - msb = sbr->kx[1]; - - if (sbr->f_master[k] - sb < 3) - k = sbr->n_master; - } while (sb != sbr->kx[1] + sbr->m[1]); - - if (sbr->patch_num_subbands[sbr->num_patches-1] < 3 && sbr->num_patches > 1) - sbr->num_patches--; - - return 0; -} - -/// Derived Frequency Band Tables (14496-3 sp04 p197) -static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr) -{ - int k, temp; - - sbr->n[1] = sbr->n_master - sbr->spectrum_params.bs_xover_band; - sbr->n[0] = (sbr->n[1] + 1) >> 1; - - memcpy(sbr->f_tablehigh, &sbr->f_master[sbr->spectrum_params.bs_xover_band], - (sbr->n[1] + 1) * sizeof(sbr->f_master[0])); - sbr->m[1] = sbr->f_tablehigh[sbr->n[1]] - sbr->f_tablehigh[0]; - sbr->kx[1] = sbr->f_tablehigh[0]; - - // Requirements (14496-3 sp04 p205) - if (sbr->kx[1] + sbr->m[1] > 64) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Stop frequency border too high: %d\n", sbr->kx[1] + sbr->m[1]); - return -1; - } - if (sbr->kx[1] > 32) { - av_log(ac->avccontext, AV_LOG_ERROR, "Start frequency border too high: %d\n", sbr->kx[1]); - return -1; - } - - sbr->f_tablelow[0] = sbr->f_tablehigh[0]; - temp = sbr->n[1] & 1; - for (k = 1; k <= sbr->n[0]; k++) - sbr->f_tablelow[k] = sbr->f_tablehigh[2 * k - temp]; - - sbr->n_q = FFMAX(1, lrintf(sbr->spectrum_params.bs_noise_bands * - log2f(sbr->k[2] / (float)sbr->kx[1]))); // 0 <= bs_noise_bands <= 3 - if (sbr->n_q > 5) { - av_log(ac->avccontext, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q); - return -1; - } - - sbr->f_tablenoise[0] = sbr->f_tablelow[0]; - temp = 0; - for (k = 1; k <= sbr->n_q; k++) { - temp += (sbr->n[0] - temp) / (sbr->n_q + 1 - k); - sbr->f_tablenoise[k] = sbr->f_tablelow[temp]; - } - - if (sbr_hf_calc_npatches(ac, sbr) < 0) - return -1; - - sbr_make_f_tablelim(sbr); - - sbr->data[0].f_indexnoise = 0; - sbr->data[1].f_indexnoise = 0; - - return 0; -} - -static av_always_inline void get_bits1_vector(GetBitContext *gb, uint8_t *vec, - int elements) -{ - int i; - for (i = 0; i < elements; i++) { - vec[i] = get_bits1(gb); - } -} - -/** ceil(log2(index+1)) */ -static const int8_t ceil_log2[] = { - 0, 1, 2, 2, 3, 3, -}; - -static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr, - GetBitContext *gb, SBRData *ch_data) -{ - int i; - unsigned bs_pointer = 0; - // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots - int abs_bord_trail = 16; - int num_rel_lead, num_rel_trail; - unsigned bs_num_env_old = ch_data->bs_num_env; - - ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env]; - ch_data->bs_amp_res = sbr->bs_amp_res_header; - ch_data->t_env_num_env_old = ch_data->t_env[bs_num_env_old]; - - switch (ch_data->bs_frame_class = get_bits(gb, 2)) { - case FIXFIX: - ch_data->bs_num_env = 1 << get_bits(gb, 2); - num_rel_lead = ch_data->bs_num_env - 1; - if (ch_data->bs_num_env == 1) - ch_data->bs_amp_res = 0; - - if (ch_data->bs_num_env > 4) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n", - ch_data->bs_num_env); - return -1; - } - - ch_data->t_env[0] = 0; - ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; - - abs_bord_trail = (abs_bord_trail + (ch_data->bs_num_env >> 1)) / - ch_data->bs_num_env; - for (i = 0; i < num_rel_lead; i++) - ch_data->t_env[i + 1] = ch_data->t_env[i] + abs_bord_trail; - - ch_data->bs_freq_res[1] = get_bits1(gb); - for (i = 1; i < ch_data->bs_num_env; i++) - ch_data->bs_freq_res[i + 1] = ch_data->bs_freq_res[1]; - break; - case FIXVAR: - abs_bord_trail += get_bits(gb, 2); - num_rel_trail = get_bits(gb, 2); - ch_data->bs_num_env = num_rel_trail + 1; - ch_data->t_env[0] = 0; - ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; - - for (i = 0; i < num_rel_trail; i++) - ch_data->t_env[ch_data->bs_num_env - 1 - i] = - ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2; - - bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); - - for (i = 0; i < ch_data->bs_num_env; i++) - ch_data->bs_freq_res[ch_data->bs_num_env - i] = get_bits1(gb); - break; - case VARFIX: - ch_data->t_env[0] = get_bits(gb, 2); - num_rel_lead = get_bits(gb, 2); - ch_data->bs_num_env = num_rel_lead + 1; - ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; - - for (i = 0; i < num_rel_lead; i++) - ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2; - - bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); - - get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env); - break; - case VARVAR: - ch_data->t_env[0] = get_bits(gb, 2); - abs_bord_trail += get_bits(gb, 2); - num_rel_lead = get_bits(gb, 2); - num_rel_trail = get_bits(gb, 2); - ch_data->bs_num_env = num_rel_lead + num_rel_trail + 1; - - if (ch_data->bs_num_env > 5) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n", - ch_data->bs_num_env); - return -1; - } - - ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; - - for (i = 0; i < num_rel_lead; i++) - ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2; - for (i = 0; i < num_rel_trail; i++) - ch_data->t_env[ch_data->bs_num_env - 1 - i] = - ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2; - - bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); - - get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env); - break; - } - - if (bs_pointer > ch_data->bs_num_env + 1) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Invalid bitstream, bs_pointer points to a middle noise border outside the time borders table: %d\n", - bs_pointer); - return -1; - } - - for (i = 1; i <= ch_data->bs_num_env; i++) { - if (ch_data->t_env[i-1] > ch_data->t_env[i]) { - av_log(ac->avccontext, AV_LOG_ERROR, "Non monotone time borders\n"); - return -1; - } - } - - ch_data->bs_num_noise = (ch_data->bs_num_env > 1) + 1; - - ch_data->t_q[0] = ch_data->t_env[0]; - ch_data->t_q[ch_data->bs_num_noise] = ch_data->t_env[ch_data->bs_num_env]; - if (ch_data->bs_num_noise > 1) { - unsigned int idx; - if (ch_data->bs_frame_class == FIXFIX) { - idx = ch_data->bs_num_env >> 1; - } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR - idx = ch_data->bs_num_env - FFMAX(bs_pointer - 1, 1); - } else { // VARFIX - if (!bs_pointer) - idx = 1; - else if (bs_pointer == 1) - idx = ch_data->bs_num_env - 1; - else // bs_pointer > 1 - idx = bs_pointer - 1; - } - ch_data->t_q[1] = ch_data->t_env[idx]; - } - - ch_data->e_a[0] = -(ch_data->e_a[1] != bs_num_env_old); // l_APrev - ch_data->e_a[1] = -1; - if ((ch_data->bs_frame_class & 1) && bs_pointer) { // FIXVAR or VARVAR and bs_pointer != 0 - ch_data->e_a[1] = ch_data->bs_num_env + 1 - bs_pointer; - } else if ((ch_data->bs_frame_class == 2) && (bs_pointer > 1)) // VARFIX and bs_pointer > 1 - ch_data->e_a[1] = bs_pointer - 1; - - return 0; -} - -static void copy_sbr_grid(SBRData *dst, const SBRData *src) { - //These variables are saved from the previous frame rather than copied - dst->bs_freq_res[0] = dst->bs_freq_res[dst->bs_num_env]; - dst->t_env_num_env_old = dst->t_env[dst->bs_num_env]; - dst->e_a[0] = -(dst->e_a[1] != dst->bs_num_env); - - //These variables are read from the bitstream and therefore copied - memcpy(dst->bs_freq_res+1, src->bs_freq_res+1, sizeof(dst->bs_freq_res)-sizeof(*dst->bs_freq_res)); - memcpy(dst->t_env, src->t_env, sizeof(dst->t_env)); - memcpy(dst->t_q, src->t_q, sizeof(dst->t_q)); - dst->bs_num_env = src->bs_num_env; - dst->bs_amp_res = src->bs_amp_res; - dst->bs_num_noise = src->bs_num_noise; - dst->bs_frame_class = src->bs_frame_class; - dst->e_a[1] = src->e_a[1]; -} - -/// Read how the envelope and noise floor data is delta coded -static void read_sbr_dtdf(SpectralBandReplication *sbr, GetBitContext *gb, - SBRData *ch_data) -{ - get_bits1_vector(gb, ch_data->bs_df_env, ch_data->bs_num_env); - get_bits1_vector(gb, ch_data->bs_df_noise, ch_data->bs_num_noise); -} - -/// Read inverse filtering data -static void read_sbr_invf(SpectralBandReplication *sbr, GetBitContext *gb, - SBRData *ch_data) -{ - int i; - - memcpy(ch_data->bs_invf_mode[1], ch_data->bs_invf_mode[0], 5 * sizeof(uint8_t)); - for (i = 0; i < sbr->n_q; i++) - ch_data->bs_invf_mode[0][i] = get_bits(gb, 2); -} - -static void read_sbr_envelope(SpectralBandReplication *sbr, GetBitContext *gb, - SBRData *ch_data, int ch) -{ - int bits; - int i, j, k; - VLC_TYPE (*t_huff)[2], (*f_huff)[2]; - int t_lav, f_lav; - const int delta = (ch == 1 && sbr->bs_coupling == 1) + 1; - const int odd = sbr->n[1] & 1; - - if (sbr->bs_coupling && ch) { - if (ch_data->bs_amp_res) { - bits = 5; - t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_3_0DB].table; - t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_3_0DB]; - f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table; - f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB]; - } else { - bits = 6; - t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_1_5DB].table; - t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_1_5DB]; - f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_1_5DB].table; - f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_1_5DB]; - } - } else { - if (ch_data->bs_amp_res) { - bits = 6; - t_huff = vlc_sbr[T_HUFFMAN_ENV_3_0DB].table; - t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_3_0DB]; - f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table; - f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB]; - } else { - bits = 7; - t_huff = vlc_sbr[T_HUFFMAN_ENV_1_5DB].table; - t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_1_5DB]; - f_huff = vlc_sbr[F_HUFFMAN_ENV_1_5DB].table; - f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_1_5DB]; - } - } - - for (i = 0; i < ch_data->bs_num_env; i++) { - if (ch_data->bs_df_env[i]) { - // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame - if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) { - for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) - ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); - } else if (ch_data->bs_freq_res[i + 1]) { - for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { - k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1] - ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); - } - } else { - for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { - k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j] - ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); - } - } - } else { - ch_data->env_facs[i + 1][0] = delta * get_bits(gb, bits); // bs_env_start_value_balance - for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) - ch_data->env_facs[i + 1][j] = ch_data->env_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav); - } - } - - //assign 0th elements of env_facs from last elements - memcpy(ch_data->env_facs[0], ch_data->env_facs[ch_data->bs_num_env], - sizeof(ch_data->env_facs[0])); -} - -static void read_sbr_noise(SpectralBandReplication *sbr, GetBitContext *gb, - SBRData *ch_data, int ch) -{ - int i, j; - VLC_TYPE (*t_huff)[2], (*f_huff)[2]; - int t_lav, f_lav; - int delta = (ch == 1 && sbr->bs_coupling == 1) + 1; - - if (sbr->bs_coupling && ch) { - t_huff = vlc_sbr[T_HUFFMAN_NOISE_BAL_3_0DB].table; - t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_BAL_3_0DB]; - f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table; - f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB]; - } else { - t_huff = vlc_sbr[T_HUFFMAN_NOISE_3_0DB].table; - t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_3_0DB]; - f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table; - f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB]; - } - - for (i = 0; i < ch_data->bs_num_noise; i++) { - if (ch_data->bs_df_noise[i]) { - for (j = 0; j < sbr->n_q; j++) - ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav); - } else { - ch_data->noise_facs[i + 1][0] = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level - for (j = 1; j < sbr->n_q; j++) - ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav); - } - } - - //assign 0th elements of noise_facs from last elements - memcpy(ch_data->noise_facs[0], ch_data->noise_facs[ch_data->bs_num_noise], - sizeof(ch_data->noise_facs[0])); -} - -static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, - GetBitContext *gb, - int bs_extension_id, int *num_bits_left) -{ -//TODO - implement ps_data for parametric stereo parsing - switch (bs_extension_id) { - case EXTENSION_ID_PS: - if (!ac->m4ac.ps) { - av_log(ac->avccontext, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n"); - skip_bits_long(gb, *num_bits_left); // bs_fill_bits - *num_bits_left = 0; - } else { -#if 0 - *num_bits_left -= ff_ps_data(gb, ps); -#else - av_log_missing_feature(ac->avccontext, "Parametric Stereo is", 0); - skip_bits_long(gb, *num_bits_left); // bs_fill_bits - *num_bits_left = 0; -#endif - } - break; - default: - av_log_missing_feature(ac->avccontext, "Reserved SBR extensions are", 1); - skip_bits_long(gb, *num_bits_left); // bs_fill_bits - *num_bits_left = 0; - break; - } -} - -static int read_sbr_single_channel_element(AACContext *ac, - SpectralBandReplication *sbr, - GetBitContext *gb) -{ - if (get_bits1(gb)) // bs_data_extra - skip_bits(gb, 4); // bs_reserved - - if (read_sbr_grid(ac, sbr, gb, &sbr->data[0])) - return -1; - read_sbr_dtdf(sbr, gb, &sbr->data[0]); - read_sbr_invf(sbr, gb, &sbr->data[0]); - read_sbr_envelope(sbr, gb, &sbr->data[0], 0); - read_sbr_noise(sbr, gb, &sbr->data[0], 0); - - if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb))) - get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]); - - return 0; -} - -static int read_sbr_channel_pair_element(AACContext *ac, - SpectralBandReplication *sbr, - GetBitContext *gb) -{ - if (get_bits1(gb)) // bs_data_extra - skip_bits(gb, 8); // bs_reserved - - if ((sbr->bs_coupling = get_bits1(gb))) { - if (read_sbr_grid(ac, sbr, gb, &sbr->data[0])) - return -1; - copy_sbr_grid(&sbr->data[1], &sbr->data[0]); - read_sbr_dtdf(sbr, gb, &sbr->data[0]); - read_sbr_dtdf(sbr, gb, &sbr->data[1]); - read_sbr_invf(sbr, gb, &sbr->data[0]); - memcpy(sbr->data[1].bs_invf_mode[1], sbr->data[1].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0])); - memcpy(sbr->data[1].bs_invf_mode[0], sbr->data[0].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0])); - read_sbr_envelope(sbr, gb, &sbr->data[0], 0); - read_sbr_noise(sbr, gb, &sbr->data[0], 0); - read_sbr_envelope(sbr, gb, &sbr->data[1], 1); - read_sbr_noise(sbr, gb, &sbr->data[1], 1); - } else { - if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) || - read_sbr_grid(ac, sbr, gb, &sbr->data[1])) - return -1; - read_sbr_dtdf(sbr, gb, &sbr->data[0]); - read_sbr_dtdf(sbr, gb, &sbr->data[1]); - read_sbr_invf(sbr, gb, &sbr->data[0]); - read_sbr_invf(sbr, gb, &sbr->data[1]); - read_sbr_envelope(sbr, gb, &sbr->data[0], 0); - read_sbr_envelope(sbr, gb, &sbr->data[1], 1); - read_sbr_noise(sbr, gb, &sbr->data[0], 0); - read_sbr_noise(sbr, gb, &sbr->data[1], 1); - } - - if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb))) - get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]); - if ((sbr->data[1].bs_add_harmonic_flag = get_bits1(gb))) - get_bits1_vector(gb, sbr->data[1].bs_add_harmonic, sbr->n[1]); - - return 0; -} - -static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr, - GetBitContext *gb, int id_aac) -{ - unsigned int cnt = get_bits_count(gb); - - if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) { - if (read_sbr_single_channel_element(ac, sbr, gb)) { - sbr->start = 0; - return get_bits_count(gb) - cnt; - } - } else if (id_aac == TYPE_CPE) { - if (read_sbr_channel_pair_element(ac, sbr, gb)) { - sbr->start = 0; - return get_bits_count(gb) - cnt; - } - } else { - av_log(ac->avccontext, AV_LOG_ERROR, - "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac); - sbr->start = 0; - return get_bits_count(gb) - cnt; - } - if (get_bits1(gb)) { // bs_extended_data - int num_bits_left = get_bits(gb, 4); // bs_extension_size - if (num_bits_left == 15) - num_bits_left += get_bits(gb, 8); // bs_esc_count - - num_bits_left <<= 3; - while (num_bits_left > 7) { - num_bits_left -= 2; - read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), &num_bits_left); // bs_extension_id - } - } - - return get_bits_count(gb) - cnt; -} - -static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr) -{ - int err; - err = sbr_make_f_master(ac, sbr, &sbr->spectrum_params); - if (err >= 0) - err = sbr_make_f_derived(ac, sbr); - if (err < 0) { - av_log(ac->avccontext, AV_LOG_ERROR, - "SBR reset failed. Switching SBR to pure upsampling mode.\n"); - sbr->start = 0; - } -} - -/** - * Decode Spectral Band Replication extension data; reference: table 4.55. - * - * @param crc flag indicating the presence of CRC checksum - * @param cnt length of TYPE_FIL syntactic element in bytes - * - * @return Returns number of bytes consumed from the TYPE_FIL element. - */ -int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, - GetBitContext *gb_host, int crc, int cnt, int id_aac) -{ - unsigned int num_sbr_bits = 0, num_align_bits; - unsigned bytes_read; - GetBitContext gbc = *gb_host, *gb = &gbc; - skip_bits_long(gb_host, cnt*8 - 4); - - sbr->reset = 0; - - if (!sbr->sample_rate) - sbr->sample_rate = 2 * ac->m4ac.sample_rate; //TODO use the nominal sample rate for arbitrary sample rate support - if (!ac->m4ac.ext_sample_rate) - ac->m4ac.ext_sample_rate = 2 * ac->m4ac.sample_rate; - - if (crc) { - skip_bits(gb, 10); // bs_sbr_crc_bits; TODO - implement CRC check - num_sbr_bits += 10; - } - - //Save some state from the previous frame. - sbr->kx[0] = sbr->kx[1]; - sbr->m[0] = sbr->m[1]; - - num_sbr_bits++; - if (get_bits1(gb)) // bs_header_flag - num_sbr_bits += read_sbr_header(sbr, gb); - - if (sbr->reset) - sbr_reset(ac, sbr); - - if (sbr->start) - num_sbr_bits += read_sbr_data(ac, sbr, gb, id_aac); - - num_align_bits = ((cnt << 3) - 4 - num_sbr_bits) & 7; - bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3); - - if (bytes_read > cnt) { - av_log(ac->avccontext, AV_LOG_ERROR, - "Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read); - } - return cnt; -} - -/// Dequantization and stereo decoding (14496-3 sp04 p203) -static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) -{ - int k, e; - int ch; - - if (id_aac == TYPE_CPE && sbr->bs_coupling) { - float alpha = sbr->data[0].bs_amp_res ? 1.0f : 0.5f; - float pan_offset = sbr->data[0].bs_amp_res ? 12.0f : 24.0f; - for (e = 1; e <= sbr->data[0].bs_num_env; e++) { - for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { - float temp1 = exp2f(sbr->data[0].env_facs[e][k] * alpha + 7.0f); - float temp2 = exp2f((pan_offset - sbr->data[1].env_facs[e][k]) * alpha); - float fac = temp1 / (1.0f + temp2); - sbr->data[0].env_facs[e][k] = fac; - sbr->data[1].env_facs[e][k] = fac * temp2; - } - } - for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { - for (k = 0; k < sbr->n_q; k++) { - float temp1 = exp2f(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs[e][k] + 1); - float temp2 = exp2f(12 - sbr->data[1].noise_facs[e][k]); - float fac = temp1 / (1.0f + temp2); - sbr->data[0].noise_facs[e][k] = fac; - sbr->data[1].noise_facs[e][k] = fac * temp2; - } - } - } else { // SCE or one non-coupled CPE - for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { - float alpha = sbr->data[ch].bs_amp_res ? 1.0f : 0.5f; - for (e = 1; e <= sbr->data[ch].bs_num_env; e++) - for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++) - sbr->data[ch].env_facs[e][k] = - exp2f(alpha * sbr->data[ch].env_facs[e][k] + 6.0f); - for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) - for (k = 0; k < sbr->n_q; k++) - sbr->data[ch].noise_facs[e][k] = - exp2f(NOISE_FLOOR_OFFSET - sbr->data[ch].noise_facs[e][k]); - } - } -} - -/** - * Analysis QMF Bank (14496-3 sp04 p206) - * - * @param x pointer to the beginning of the first sample window - * @param W array of complex-valued samples split into subbands - */ -static void sbr_qmf_analysis(DSPContext *dsp, RDFTContext *rdft, const float *in, float *x, - float z[320], float W[2][32][32][2], - float scale) -{ - int i, k; - memcpy(W[0], W[1], sizeof(W[0])); - memcpy(x , x+1024, (320-32)*sizeof(x[0])); - if (scale != 1.0f) - dsp->vector_fmul_scalar(x+288, in, scale, 1024); - else - memcpy(x+288, in, 1024*sizeof(*x)); - for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames - // are not supported - float re, im; - dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320); - for (k = 0; k < 64; k++) { - float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256]; - z[k] = f * analysis_cos_pre[k]; - z[k+64] = f; - } - ff_rdft_calc(rdft, z); - re = z[0] * 0.5f; - im = 0.5f * dsp->scalarproduct_float(z+64, analysis_sin_pre, 64); - W[1][i][0][0] = re * analysis_cossin_post[0][0] - im * analysis_cossin_post[0][1]; - W[1][i][0][1] = re * analysis_cossin_post[0][1] + im * analysis_cossin_post[0][0]; - for (k = 1; k < 32; k++) { - re = z[2*k ] - re; - im = z[2*k+1] - im; - W[1][i][k][0] = re * analysis_cossin_post[k][0] - im * analysis_cossin_post[k][1]; - W[1][i][k][1] = re * analysis_cossin_post[k][1] + im * analysis_cossin_post[k][0]; - } - x += 32; - } -} - -/** - * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank - * (14496-3 sp04 p206) - */ -static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct, - float *out, float X[2][32][64], - float mdct_buf[2][64], - float *v0, int *v_off, const unsigned int div, - float bias, float scale) -{ - int i, n; - const float *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us; - int scale_and_bias = scale != 1.0f || bias != 0.0f; - float *v; - for (i = 0; i < 32; i++) { - if (*v_off == 0) { - int saved_samples = (1280 - 128) >> div; - memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(float)); - *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - (128 >> div); - } else { - *v_off -= 128 >> div; - } - v = v0 + *v_off; - for (n = 1; n < 64 >> div; n+=2) { - X[1][i][n] = -X[1][i][n]; - } - if (div) { - memset(X[0][i]+32, 0, 32*sizeof(float)); - memset(X[1][i]+32, 0, 32*sizeof(float)); - } - ff_imdct_half(mdct, mdct_buf[0], X[0][i]); - ff_imdct_half(mdct, mdct_buf[1], X[1][i]); - if (div) { - for (n = 0; n < 32; n++) { - v[ n] = -mdct_buf[0][63 - 2*n] + mdct_buf[1][2*n ]; - v[ 63 - n] = mdct_buf[0][62 - 2*n] + mdct_buf[1][2*n + 1]; - } - } else { - for (n = 0; n < 64; n++) { - v[ n] = -mdct_buf[0][63 - n] + mdct_buf[1][ n ]; - v[127 - n] = mdct_buf[0][63 - n] + mdct_buf[1][ n ]; - } - } - dsp->vector_fmul_add(out, v , sbr_qmf_window , zero64, 64 >> div); - dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out , 64 >> div); - if (scale_and_bias) - for (n = 0; n < 64 >> div; n++) - out[n] = out[n] * scale + bias; - out += 64 >> div; - } -} - -static void autocorrelate(const float x[40][2], float phi[3][2][2], int lag) -{ - int i; - float real_sum = 0.0f; - float imag_sum = 0.0f; - if (lag) { - for (i = 1; i < 38; i++) { - real_sum += x[i][0] * x[i+lag][0] + x[i][1] * x[i+lag][1]; - imag_sum += x[i][0] * x[i+lag][1] - x[i][1] * x[i+lag][0]; - } - phi[2-lag][1][0] = real_sum + x[ 0][0] * x[lag][0] + x[ 0][1] * x[lag][1]; - phi[2-lag][1][1] = imag_sum + x[ 0][0] * x[lag][1] - x[ 0][1] * x[lag][0]; - if (lag == 1) { - phi[0][0][0] = real_sum + x[38][0] * x[39][0] + x[38][1] * x[39][1]; - phi[0][0][1] = imag_sum + x[38][0] * x[39][1] - x[38][1] * x[39][0]; - } - } else { - for (i = 1; i < 38; i++) { - real_sum += x[i][0] * x[i][0] + x[i][1] * x[i][1]; - } - phi[2][1][0] = real_sum + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1]; - phi[1][0][0] = real_sum + x[38][0] * x[38][0] + x[38][1] * x[38][1]; - } -} - -/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering - * (14496-3 sp04 p214) - * Warning: This routine does not seem numerically stable. - */ -static void sbr_hf_inverse_filter(float (*alpha0)[2], float (*alpha1)[2], - const float X_low[32][40][2], int k0) -{ - int k; - for (k = 0; k < k0; k++) { - float phi[3][2][2], dk; - - autocorrelate(X_low[k], phi, 0); - autocorrelate(X_low[k], phi, 1); - autocorrelate(X_low[k], phi, 2); - - dk = phi[2][1][0] * phi[1][0][0] - - (phi[1][1][0] * phi[1][1][0] + phi[1][1][1] * phi[1][1][1]) / 1.000001f; - - if (!dk) { - alpha1[k][0] = 0; - alpha1[k][1] = 0; - } else { - float temp_real, temp_im; - temp_real = phi[0][0][0] * phi[1][1][0] - - phi[0][0][1] * phi[1][1][1] - - phi[0][1][0] * phi[1][0][0]; - temp_im = phi[0][0][0] * phi[1][1][1] + - phi[0][0][1] * phi[1][1][0] - - phi[0][1][1] * phi[1][0][0]; - - alpha1[k][0] = temp_real / dk; - alpha1[k][1] = temp_im / dk; - } - - if (!phi[1][0][0]) { - alpha0[k][0] = 0; - alpha0[k][1] = 0; - } else { - float temp_real, temp_im; - temp_real = phi[0][0][0] + alpha1[k][0] * phi[1][1][0] + - alpha1[k][1] * phi[1][1][1]; - temp_im = phi[0][0][1] + alpha1[k][1] * phi[1][1][0] - - alpha1[k][0] * phi[1][1][1]; - - alpha0[k][0] = -temp_real / phi[1][0][0]; - alpha0[k][1] = -temp_im / phi[1][0][0]; - } - - if (alpha1[k][0] * alpha1[k][0] + alpha1[k][1] * alpha1[k][1] >= 16.0f || - alpha0[k][0] * alpha0[k][0] + alpha0[k][1] * alpha0[k][1] >= 16.0f) { - alpha1[k][0] = 0; - alpha1[k][1] = 0; - alpha0[k][0] = 0; - alpha0[k][1] = 0; - } - } -} - -/// Chirp Factors (14496-3 sp04 p214) -static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) -{ - int i; - float new_bw; - static const float bw_tab[] = { 0.0f, 0.75f, 0.9f, 0.98f }; - - for (i = 0; i < sbr->n_q; i++) { - if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) { - new_bw = 0.6f; - } else - new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; - - if (new_bw < ch_data->bw_array[i]) { - new_bw = 0.75f * new_bw + 0.25f * ch_data->bw_array[i]; - } else - new_bw = 0.90625f * new_bw + 0.09375f * ch_data->bw_array[i]; - ch_data->bw_array[i] = new_bw < 0.015625f ? 0.0f : new_bw; - } -} - -/// Generate the subband filtered lowband -static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr, - float X_low[32][40][2], const float W[2][32][32][2]) -{ - int i, k; - const int t_HFGen = 8; - const int i_f = 32; - memset(X_low, 0, 32*sizeof(*X_low)); - for (k = 0; k < sbr->kx[1]; k++) { - for (i = t_HFGen; i < i_f + t_HFGen; i++) { - X_low[k][i][0] = W[1][i - t_HFGen][k][0]; - X_low[k][i][1] = W[1][i - t_HFGen][k][1]; - } - } - for (k = 0; k < sbr->kx[0]; k++) { - for (i = 0; i < t_HFGen; i++) { - X_low[k][i][0] = W[0][i + i_f - t_HFGen][k][0]; - X_low[k][i][1] = W[0][i + i_f - t_HFGen][k][1]; - } - } - return 0; -} - -/// High Frequency Generator (14496-3 sp04 p215) -static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr, - float X_high[64][40][2], const float X_low[32][40][2], - const float (*alpha0)[2], const float (*alpha1)[2], - const float bw_array[5], const uint8_t *t_env, - int bs_num_env) -{ - int i, j, x; - int g = 0; - int k = sbr->kx[1]; - for (j = 0; j < sbr->num_patches; j++) { - for (x = 0; x < sbr->patch_num_subbands[j]; x++, k++) { - float alpha[4]; - const int p = sbr->patch_start_subband[j] + x; - while (g <= sbr->n_q && k >= sbr->f_tablenoise[g]) - g++; - g--; - - if (g < 0) { - av_log(ac->avccontext, AV_LOG_ERROR, - "ERROR : no subband found for frequency %d\n", k); - return -1; - } - - alpha[0] = alpha1[p][0] * bw_array[g] * bw_array[g]; - alpha[1] = alpha1[p][1] * bw_array[g] * bw_array[g]; - alpha[2] = alpha0[p][0] * bw_array[g]; - alpha[3] = alpha0[p][1] * bw_array[g]; - - for (i = 2 * t_env[0]; i < 2 * t_env[bs_num_env]; i++) { - const int idx = i + ENVELOPE_ADJUSTMENT_OFFSET; - X_high[k][idx][0] = - X_low[p][idx - 2][0] * alpha[0] - - X_low[p][idx - 2][1] * alpha[1] + - X_low[p][idx - 1][0] * alpha[2] - - X_low[p][idx - 1][1] * alpha[3] + - X_low[p][idx][0]; - X_high[k][idx][1] = - X_low[p][idx - 2][1] * alpha[0] + - X_low[p][idx - 2][0] * alpha[1] + - X_low[p][idx - 1][1] * alpha[2] + - X_low[p][idx - 1][0] * alpha[3] + - X_low[p][idx][1]; - } - } - } - if (k < sbr->m[1] + sbr->kx[1]) - memset(X_high + k, 0, (sbr->m[1] + sbr->kx[1] - k) * sizeof(*X_high)); - - return 0; -} - -/// Generate the subband filtered lowband -static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][32][64], - const float X_low[32][40][2], const float Y[2][38][64][2], - int ch) -{ - int k, i; - const int i_f = 32; - const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0); - memset(X, 0, 2*sizeof(*X)); - for (k = 0; k < sbr->kx[0]; k++) { - for (i = 0; i < i_Temp; i++) { - X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0]; - X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1]; - } - } - for (; k < sbr->kx[0] + sbr->m[0]; k++) { - for (i = 0; i < i_Temp; i++) { - X[0][i][k] = Y[0][i + i_f][k][0]; - X[1][i][k] = Y[0][i + i_f][k][1]; - } - } - - for (k = 0; k < sbr->kx[1]; k++) { - for (i = i_Temp; i < i_f; i++) { - X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0]; - X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1]; - } - } - for (; k < sbr->kx[1] + sbr->m[1]; k++) { - for (i = i_Temp; i < i_f; i++) { - X[0][i][k] = Y[1][i][k][0]; - X[1][i][k] = Y[1][i][k][1]; - } - } - return 0; -} - -/** High Frequency Adjustment (14496-3 sp04 p217) and Mapping - * (14496-3 sp04 p217) - */ -static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, - SBRData *ch_data, int e_a[2]) -{ - int e, i, m; - - memset(ch_data->s_indexmapped[1], 0, 7*sizeof(ch_data->s_indexmapped[1])); - for (e = 0; e < ch_data->bs_num_env; e++) { - const unsigned int ilim = sbr->n[ch_data->bs_freq_res[e + 1]]; - uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; - int k; - - for (i = 0; i < ilim; i++) - for (m = table[i]; m < table[i + 1]; m++) - sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; - - // ch_data->bs_num_noise > 1 => 2 noise floors - k = (ch_data->bs_num_noise > 1) && (ch_data->t_env[e] >= ch_data->t_q[1]); - for (i = 0; i < sbr->n_q; i++) - for (m = sbr->f_tablenoise[i]; m < sbr->f_tablenoise[i + 1]; m++) - sbr->q_mapped[e][m - sbr->kx[1]] = ch_data->noise_facs[k+1][i]; - - for (i = 0; i < sbr->n[1]; i++) { - if (ch_data->bs_add_harmonic_flag) { - const unsigned int m_midpoint = - (sbr->f_tablehigh[i] + sbr->f_tablehigh[i + 1]) >> 1; - - ch_data->s_indexmapped[e + 1][m_midpoint - sbr->kx[1]] = ch_data->bs_add_harmonic[i] * - (e >= e_a[1] || (ch_data->s_indexmapped[0][m_midpoint - sbr->kx[1]] == 1)); - } - } - - for (i = 0; i < ilim; i++) { - int additional_sinusoid_present = 0; - for (m = table[i]; m < table[i + 1]; m++) { - if (ch_data->s_indexmapped[e + 1][m - sbr->kx[1]]) { - additional_sinusoid_present = 1; - break; - } - } - memset(&sbr->s_mapped[e][table[i] - sbr->kx[1]], additional_sinusoid_present, - (table[i + 1] - table[i]) * sizeof(sbr->s_mapped[e][0])); - } - } - - memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0])); -} - -/// Estimation of current envelope (14496-3 sp04 p218) -static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2], - SpectralBandReplication *sbr, SBRData *ch_data) -{ - int e, i, m; - - if (sbr->bs_interpol_freq) { - for (e = 0; e < ch_data->bs_num_env; e++) { - const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]); - int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; - int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; - - for (m = 0; m < sbr->m[1]; m++) { - float sum = 0.0f; - - for (i = ilb; i < iub; i++) { - sum += X_high[m + sbr->kx[1]][i][0] * X_high[m + sbr->kx[1]][i][0] + - X_high[m + sbr->kx[1]][i][1] * X_high[m + sbr->kx[1]][i][1]; - } - e_curr[e][m] = sum * recip_env_size; - } - } - } else { - int k, p; - - for (e = 0; e < ch_data->bs_num_env; e++) { - const int env_size = 2 * (ch_data->t_env[e + 1] - ch_data->t_env[e]); - int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; - int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; - const uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; - - for (p = 0; p < sbr->n[ch_data->bs_freq_res[e + 1]]; p++) { - float sum = 0.0f; - const int den = env_size * (table[p + 1] - table[p]); - - for (k = table[p]; k < table[p + 1]; k++) { - for (i = ilb; i < iub; i++) { - sum += X_high[k][i][0] * X_high[k][i][0] + - X_high[k][i][1] * X_high[k][i][1]; - } - } - sum /= den; - for (k = table[p]; k < table[p + 1]; k++) { - e_curr[e][k - sbr->kx[1]] = sum; - } - } - } - } -} - -/** - * Calculation of levels of additional HF signal components (14496-3 sp04 p219) - * and Calculation of gain (14496-3 sp04 p219) - */ -static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, - SBRData *ch_data, const int e_a[2]) -{ - int e, k, m; - // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) - static const float limgain[4] = { 0.70795, 1.0, 1.41254, 10000000000 }; - - for (e = 0; e < ch_data->bs_num_env; e++) { - int delta = !((e == e_a[1]) || (e == e_a[0])); - for (k = 0; k < sbr->n_lim; k++) { - float gain_boost, gain_max; - float sum[2] = { 0.0f, 0.0f }; - for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { - const float temp = sbr->e_origmapped[e][m] / (1.0f + sbr->q_mapped[e][m]); - sbr->q_m[e][m] = sqrtf(temp * sbr->q_mapped[e][m]); - sbr->s_m[e][m] = sqrtf(temp * ch_data->s_indexmapped[e + 1][m]); - if (!sbr->s_mapped[e][m]) { - sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] / - ((1.0f + sbr->e_curr[e][m]) * - (1.0f + sbr->q_mapped[e][m] * delta))); - } else { - sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] * sbr->q_mapped[e][m] / - ((1.0f + sbr->e_curr[e][m]) * - (1.0f + sbr->q_mapped[e][m]))); - } - } - for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { - sum[0] += sbr->e_origmapped[e][m]; - sum[1] += sbr->e_curr[e][m]; - } - gain_max = limgain[sbr->bs_limiter_gains] * sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); - gain_max = FFMIN(100000, gain_max); - for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { - float q_m_max = sbr->q_m[e][m] * gain_max / sbr->gain[e][m]; - sbr->q_m[e][m] = FFMIN(sbr->q_m[e][m], q_m_max); - sbr->gain[e][m] = FFMIN(sbr->gain[e][m], gain_max); - } - sum[0] = sum[1] = 0.0f; - for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { - sum[0] += sbr->e_origmapped[e][m]; - sum[1] += sbr->e_curr[e][m] * sbr->gain[e][m] * sbr->gain[e][m] - + sbr->s_m[e][m] * sbr->s_m[e][m] - + (delta && !sbr->s_m[e][m]) * sbr->q_m[e][m] * sbr->q_m[e][m]; - } - gain_boost = sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); - gain_boost = FFMIN(1.584893192, gain_boost); - for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { - sbr->gain[e][m] *= gain_boost; - sbr->q_m[e][m] *= gain_boost; - sbr->s_m[e][m] *= gain_boost; - } - } - } -} - -/// Assembling HF Signals (14496-3 sp04 p220) -static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2], - SpectralBandReplication *sbr, SBRData *ch_data, - const int e_a[2]) -{ - int e, i, j, m; - const int h_SL = 4 * !sbr->bs_smoothing_mode; - const int kx = sbr->kx[1]; - const int m_max = sbr->m[1]; - static const float h_smooth[5] = { - 0.33333333333333, - 0.30150283239582, - 0.21816949906249, - 0.11516383427084, - 0.03183050093751, - }; - static const int8_t phi[2][4] = { - { 1, 0, -1, 0}, // real - { 0, 1, 0, -1}, // imaginary - }; - float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; - int indexnoise = ch_data->f_indexnoise; - int indexsine = ch_data->f_indexsine; - memcpy(Y[0], Y[1], sizeof(Y[0])); - - if (sbr->reset) { - for (i = 0; i < h_SL; i++) { - memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); - memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); - } - } else if (h_SL) { - memcpy(g_temp[2*ch_data->t_env[0]], g_temp[2*ch_data->t_env_num_env_old], 4*sizeof(g_temp[0])); - memcpy(q_temp[2*ch_data->t_env[0]], q_temp[2*ch_data->t_env_num_env_old], 4*sizeof(q_temp[0])); - } - - for (e = 0; e < ch_data->bs_num_env; e++) { - for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { - memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); - memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); - } - } - - for (e = 0; e < ch_data->bs_num_env; e++) { - for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { - int phi_sign = (1 - 2*(kx & 1)); - - if (h_SL && e != e_a[0] && e != e_a[1]) { - for (m = 0; m < m_max; m++) { - const int idx1 = i + h_SL; - float g_filt = 0.0f; - for (j = 0; j <= h_SL; j++) - g_filt += g_temp[idx1 - j][m] * h_smooth[j]; - Y[1][i][m + kx][0] = - X_high[m + kx][i + ENVELOPE_ADJUSTMENT_OFFSET][0] * g_filt; - Y[1][i][m + kx][1] = - X_high[m + kx][i + ENVELOPE_ADJUSTMENT_OFFSET][1] * g_filt; - } - } else { - for (m = 0; m < m_max; m++) { - const float g_filt = g_temp[i + h_SL][m]; - Y[1][i][m + kx][0] = - X_high[m + kx][i + ENVELOPE_ADJUSTMENT_OFFSET][0] * g_filt; - Y[1][i][m + kx][1] = - X_high[m + kx][i + ENVELOPE_ADJUSTMENT_OFFSET][1] * g_filt; - } - } - - if (e != e_a[0] && e != e_a[1]) { - for (m = 0; m < m_max; m++) { - indexnoise = (indexnoise + 1) & 0x1ff; - if (sbr->s_m[e][m]) { - Y[1][i][m + kx][0] += - sbr->s_m[e][m] * phi[0][indexsine]; - Y[1][i][m + kx][1] += - sbr->s_m[e][m] * (phi[1][indexsine] * phi_sign); - } else { - float q_filt; - if (h_SL) { - const int idx1 = i + h_SL; - q_filt = 0.0f; - for (j = 0; j <= h_SL; j++) - q_filt += q_temp[idx1 - j][m] * h_smooth[j]; - } else { - q_filt = q_temp[i][m]; - } - Y[1][i][m + kx][0] += - q_filt * sbr_noise_table[indexnoise][0]; - Y[1][i][m + kx][1] += - q_filt * sbr_noise_table[indexnoise][1]; - } - phi_sign = -phi_sign; - } - } else { - indexnoise = (indexnoise + m_max) & 0x1ff; - for (m = 0; m < m_max; m++) { - Y[1][i][m + kx][0] += - sbr->s_m[e][m] * phi[0][indexsine]; - Y[1][i][m + kx][1] += - sbr->s_m[e][m] * (phi[1][indexsine] * phi_sign); - phi_sign = -phi_sign; - } - } - indexsine = (indexsine + 1) & 3; - } - } - ch_data->f_indexnoise = indexnoise; - ch_data->f_indexsine = indexsine; -} - -void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, - float* L, float* R) -{ - int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate; - int ch; - int nch = (id_aac == TYPE_CPE) ? 2 : 1; - - if (sbr->start) { - sbr_dequant(sbr, id_aac); - } - for (ch = 0; ch < nch; ch++) { - /* decode channel */ - sbr_qmf_analysis(&ac->dsp, &sbr->rdft, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, - (float*)sbr->qmf_filter_scratch, - sbr->data[ch].W, 1/(-1024 * ac->sf_scale)); - sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W); - if (sbr->start) { - sbr_hf_inverse_filter(sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); - sbr_chirp(sbr, &sbr->data[ch]); - sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1, - sbr->data[ch].bw_array, sbr->data[ch].t_env, - sbr->data[ch].bs_num_env); - - // hf_adj - sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); - sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]); - sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); - sbr_hf_assemble(sbr->data[ch].Y, sbr->X_high, sbr, &sbr->data[ch], - sbr->data[ch].e_a); - } - - /* synthesis */ - sbr_x_gen(sbr, sbr->X[ch], sbr->X_low, sbr->data[ch].Y, ch); - } - sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, L, sbr->X[0], sbr->qmf_filter_scratch, - sbr->data[0].synthesis_filterbank_samples, - &sbr->data[0].synthesis_filterbank_samples_offset, - downsampled, - ac->add_bias, -1024 * ac->sf_scale); - if (nch == 2) - sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, R, sbr->X[1], sbr->qmf_filter_scratch, - sbr->data[1].synthesis_filterbank_samples, - &sbr->data[1].synthesis_filterbank_samples_offset, - downsampled, - ac->add_bias, -1024 * ac->sf_scale); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/aacsbr.h b/tizen/distrib/ffmpeg/libavcodec/aacsbr.h deleted file mode 100644 index 6b10ed4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacsbr.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * AAC Spectral Band Replication function declarations - * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) - * Copyright (c) 2010 Alex Converse - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC Spectral Band Replication function declarations - * @author Robert Swain ( rob opendot cl ) - */ - -#ifndef AVCODEC_AACSBR_H -#define AVCODEC_AACSBR_H - -#include "get_bits.h" -#include "aac.h" -#include "sbr.h" - -/** Initialize SBR. */ -av_cold void ff_aac_sbr_init(void); -/** Initialize one SBR context. */ -av_cold void ff_aac_sbr_ctx_init(SpectralBandReplication *sbr); -/** Close one SBR context. */ -av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr); -/** Decode one SBR element. */ -int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, - GetBitContext *gb, int crc, int cnt, int id_aac); -/** Apply one SBR element to one AAC element. */ -void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, - float* L, float *R); - -#endif /* AVCODEC_AACSBR_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aacsbrdata.h b/tizen/distrib/ffmpeg/libavcodec/aacsbrdata.h deleted file mode 100644 index 5d33a60..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aacsbrdata.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * AAC Spectral Band Replication decoding data - * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC Spectral Band Replication decoding data - * @author Robert Swain ( rob opendot cl ) - */ - -#ifndef AVCODEC_AACSBRDATA_H -#define AVCODEC_AACSBRDATA_H - -#include -#include "libavutil/mem.h" - -///< Huffman tables for SBR - -static const uint8_t t_huffman_env_1_5dB_bits[121] = { - 18, 18, 18, 18, 18, 18, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 17, 18, 16, 17, 18, 17, - 16, 16, 16, 16, 15, 14, 14, 13, - 13, 12, 11, 10, 9, 8, 7, 6, - 5, 4, 3, 2, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 12, 13, 14, - 14, 15, 16, 17, 16, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, -}; - -static const uint32_t t_huffman_env_1_5dB_codes[121] = { - 0x3ffd6, 0x3ffd7, 0x3ffd8, 0x3ffd9, 0x3ffda, 0x3ffdb, 0x7ffb8, 0x7ffb9, - 0x7ffba, 0x7ffbb, 0x7ffbc, 0x7ffbd, 0x7ffbe, 0x7ffbf, 0x7ffc0, 0x7ffc1, - 0x7ffc2, 0x7ffc3, 0x7ffc4, 0x7ffc5, 0x7ffc6, 0x7ffc7, 0x7ffc8, 0x7ffc9, - 0x7ffca, 0x7ffcb, 0x7ffcc, 0x7ffcd, 0x7ffce, 0x7ffcf, 0x7ffd0, 0x7ffd1, - 0x7ffd2, 0x7ffd3, 0x1ffe6, 0x3ffd4, 0x0fff0, 0x1ffe9, 0x3ffd5, 0x1ffe7, - 0x0fff1, 0x0ffec, 0x0ffed, 0x0ffee, 0x07ff4, 0x03ff9, 0x03ff7, 0x01ffa, - 0x01ff9, 0x00ffb, 0x007fc, 0x003fc, 0x001fd, 0x000fd, 0x0007d, 0x0003d, - 0x0001d, 0x0000d, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000c, 0x0001c, - 0x0003c, 0x0007c, 0x000fc, 0x001fc, 0x003fd, 0x00ffa, 0x01ff8, 0x03ff6, - 0x03ff8, 0x07ff5, 0x0ffef, 0x1ffe8, 0x0fff2, 0x7ffd4, 0x7ffd5, 0x7ffd6, - 0x7ffd7, 0x7ffd8, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, 0x7ffde, - 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffe6, - 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffec, 0x7ffed, 0x7ffee, - 0x7ffef, 0x7fff0, 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, - 0x7fff7, 0x7fff8, 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, - 0x7ffff, -}; - -static const uint8_t f_huffman_env_1_5dB_bits[121] = { - 19, 19, 20, 20, 20, 20, 20, 20, - 20, 19, 20, 20, 20, 20, 19, 20, - 19, 19, 20, 18, 20, 20, 20, 19, - 20, 20, 20, 19, 20, 19, 18, 19, - 18, 18, 17, 18, 17, 17, 17, 16, - 16, 16, 15, 15, 14, 13, 13, 12, - 12, 11, 10, 9, 9, 8, 7, 6, - 5, 4, 3, 2, 2, 3, 4, 5, - 6, 8, 8, 9, 10, 11, 11, 11, - 12, 12, 13, 13, 14, 14, 16, 16, - 17, 17, 18, 18, 18, 18, 18, 18, - 18, 20, 19, 20, 20, 20, 20, 20, - 20, 19, 20, 20, 20, 20, 19, 20, - 18, 20, 20, 19, 19, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, - 20, -}; - -static const uint32_t f_huffman_env_1_5dB_codes[121] = { - 0x7ffe7, 0x7ffe8, 0xfffd2, 0xfffd3, 0xfffd4, 0xfffd5, 0xfffd6, 0xfffd7, - 0xfffd8, 0x7ffda, 0xfffd9, 0xfffda, 0xfffdb, 0xfffdc, 0x7ffdb, 0xfffdd, - 0x7ffdc, 0x7ffdd, 0xfffde, 0x3ffe4, 0xfffdf, 0xfffe0, 0xfffe1, 0x7ffde, - 0xfffe2, 0xfffe3, 0xfffe4, 0x7ffdf, 0xfffe5, 0x7ffe0, 0x3ffe8, 0x7ffe1, - 0x3ffe0, 0x3ffe9, 0x1ffef, 0x3ffe5, 0x1ffec, 0x1ffed, 0x1ffee, 0x0fff4, - 0x0fff3, 0x0fff0, 0x07ff7, 0x07ff6, 0x03ffa, 0x01ffa, 0x01ff9, 0x00ffa, - 0x00ff8, 0x007f9, 0x003fb, 0x001fc, 0x001fa, 0x000fb, 0x0007c, 0x0003c, - 0x0001c, 0x0000c, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000d, 0x0001d, - 0x0003d, 0x000fa, 0x000fc, 0x001fb, 0x003fa, 0x007f8, 0x007fa, 0x007fb, - 0x00ff9, 0x00ffb, 0x01ff8, 0x01ffb, 0x03ff8, 0x03ff9, 0x0fff1, 0x0fff2, - 0x1ffea, 0x1ffeb, 0x3ffe1, 0x3ffe2, 0x3ffea, 0x3ffe3, 0x3ffe6, 0x3ffe7, - 0x3ffeb, 0xfffe6, 0x7ffe2, 0xfffe7, 0xfffe8, 0xfffe9, 0xfffea, 0xfffeb, - 0xfffec, 0x7ffe3, 0xfffed, 0xfffee, 0xfffef, 0xffff0, 0x7ffe4, 0xffff1, - 0x3ffec, 0xffff2, 0xffff3, 0x7ffe5, 0x7ffe6, 0xffff4, 0xffff5, 0xffff6, - 0xffff7, 0xffff8, 0xffff9, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, - 0xfffff, -}; - -static const uint8_t t_huffman_env_bal_1_5dB_bits[49] = { - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 12, 11, 9, 7, 5, 3, - 1, 2, 4, 6, 8, 11, 12, 15, - 16, 16, 16, 16, 16, 16, 16, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, -}; - -static const uint32_t t_huffman_env_bal_1_5dB_codes[49] = { - 0x0ffe4, 0x0ffe5, 0x0ffe6, 0x0ffe7, 0x0ffe8, 0x0ffe9, 0x0ffea, 0x0ffeb, - 0x0ffec, 0x0ffed, 0x0ffee, 0x0ffef, 0x0fff0, 0x0fff1, 0x0fff2, 0x0fff3, - 0x0fff4, 0x0ffe2, 0x00ffc, 0x007fc, 0x001fe, 0x0007e, 0x0001e, 0x00006, - 0x00000, 0x00002, 0x0000e, 0x0003e, 0x000fe, 0x007fd, 0x00ffd, 0x07ff0, - 0x0ffe3, 0x0fff5, 0x0fff6, 0x0fff7, 0x0fff8, 0x0fff9, 0x0fffa, 0x1fff6, - 0x1fff7, 0x1fff8, 0x1fff9, 0x1fffa, 0x1fffb, 0x1fffc, 0x1fffd, 0x1fffe, - 0x1ffff, -}; - -static const uint8_t f_huffman_env_bal_1_5dB_bits[49] = { - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 16, - 17, 14, 11, 11, 8, 7, 4, 2, - 1, 3, 5, 6, 9, 11, 12, 15, - 16, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 19, - 19, -}; - -static const uint32_t f_huffman_env_bal_1_5dB_codes[49] = { - 0x3ffe2, 0x3ffe3, 0x3ffe4, 0x3ffe5, 0x3ffe6, 0x3ffe7, 0x3ffe8, 0x3ffe9, - 0x3ffea, 0x3ffeb, 0x3ffec, 0x3ffed, 0x3ffee, 0x3ffef, 0x3fff0, 0x0fff7, - 0x1fff0, 0x03ffc, 0x007fe, 0x007fc, 0x000fe, 0x0007e, 0x0000e, 0x00002, - 0x00000, 0x00006, 0x0001e, 0x0003e, 0x001fe, 0x007fd, 0x00ffe, 0x07ffa, - 0x0fff6, 0x3fff1, 0x3fff2, 0x3fff3, 0x3fff4, 0x3fff5, 0x3fff6, 0x3fff7, - 0x3fff8, 0x3fff9, 0x3fffa, 0x3fffb, 0x3fffc, 0x3fffd, 0x3fffe, 0x7fffe, - 0x7ffff, -}; - -static const uint8_t t_huffman_env_3_0dB_bits[63] = { - 18, 18, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 17, 16, 16, 16, 14, 14, 14, - 13, 12, 11, 8, 6, 4, 2, 1, - 3, 5, 7, 9, 11, 13, 14, 14, - 15, 16, 17, 18, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, -}; - -static const uint32_t t_huffman_env_3_0dB_codes[63] = { - 0x3ffed, 0x3ffee, 0x7ffde, 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, - 0x7ffe4, 0x7ffe5, 0x7ffe6, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, - 0x7ffec, 0x1fff4, 0x0fff7, 0x0fff9, 0x0fff8, 0x03ffb, 0x03ffa, 0x03ff8, - 0x01ffa, 0x00ffc, 0x007fc, 0x000fe, 0x0003e, 0x0000e, 0x00002, 0x00000, - 0x00006, 0x0001e, 0x0007e, 0x001fe, 0x007fd, 0x01ffb, 0x03ff9, 0x03ffc, - 0x07ffa, 0x0fff6, 0x1fff5, 0x3ffec, 0x7ffed, 0x7ffee, 0x7ffef, 0x7fff0, - 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, 0x7fff7, 0x7fff8, - 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, 0x7ffff, -}; - -static const uint8_t f_huffman_env_3_0dB_bits[63] = { - 20, 20, 20, 20, 20, 20, 20, 18, - 19, 19, 19, 19, 18, 18, 20, 19, - 17, 18, 17, 16, 16, 15, 14, 12, - 11, 10, 9, 8, 6, 4, 2, 1, - 3, 5, 8, 9, 10, 11, 12, 13, - 14, 15, 15, 16, 16, 17, 17, 18, - 18, 18, 20, 19, 19, 19, 20, 19, - 19, 20, 20, 20, 20, 20, 20, -}; - -static const uint32_t f_huffman_env_3_0dB_codes[63] = { - 0xffff0, 0xffff1, 0xffff2, 0xffff3, 0xffff4, 0xffff5, 0xffff6, 0x3fff3, - 0x7fff5, 0x7ffee, 0x7ffef, 0x7fff6, 0x3fff4, 0x3fff2, 0xffff7, 0x7fff0, - 0x1fff5, 0x3fff0, 0x1fff4, 0x0fff7, 0x0fff6, 0x07ff8, 0x03ffb, 0x00ffd, - 0x007fd, 0x003fd, 0x001fd, 0x000fd, 0x0003e, 0x0000e, 0x00002, 0x00000, - 0x00006, 0x0001e, 0x000fc, 0x001fc, 0x003fc, 0x007fc, 0x00ffc, 0x01ffc, - 0x03ffa, 0x07ff9, 0x07ffa, 0x0fff8, 0x0fff9, 0x1fff6, 0x1fff7, 0x3fff5, - 0x3fff6, 0x3fff1, 0xffff8, 0x7fff1, 0x7fff2, 0x7fff3, 0xffff9, 0x7fff7, - 0x7fff4, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, 0xfffff, -}; - -static const uint8_t t_huffman_env_bal_3_0dB_bits[25] = { - 13, 13, 13, 13, 13, 13, 13, 12, - 8, 7, 4, 3, 1, 2, 5, 6, - 9, 13, 13, 13, 13, 13, 13, 14, - 14, -}; - -static const uint16_t t_huffman_env_bal_3_0dB_codes[25] = { - 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x0ff8, - 0x00fe, 0x007e, 0x000e, 0x0006, 0x0000, 0x0002, 0x001e, 0x003e, - 0x01fe, 0x1ff9, 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, - 0x3fff, -}; - -static const uint8_t f_huffman_env_bal_3_0dB_bits[25] = { - 13, 13, 13, 13, 13, 14, 14, 11, - 8, 7, 4, 2, 1, 3, 5, 6, - 9, 12, 13, 14, 14, 14, 14, 14, - 14, -}; - -static const uint16_t f_huffman_env_bal_3_0dB_codes[25] = { - 0x1ff7, 0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, 0x3ff8, 0x3ff9, 0x07fc, - 0x00fe, 0x007e, 0x000e, 0x0002, 0x0000, 0x0006, 0x001e, 0x003e, - 0x01fe, 0x0ffa, 0x1ff6, 0x3ffa, 0x3ffb, 0x3ffc, 0x3ffd, 0x3ffe, - 0x3fff, -}; - -static const uint8_t t_huffman_noise_3_0dB_bits[63] = { - 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, 11, 8, 6, 4, 3, 1, - 2, 5, 8, 10, 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, 14, 14, -}; - -static const uint16_t t_huffman_noise_3_0dB_codes[63] = { - 0x1fce, 0x1fcf, 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, - 0x1fd6, 0x1fd7, 0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, 0x1fdc, 0x1fdd, - 0x1fde, 0x1fdf, 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, - 0x1fe6, 0x1fe7, 0x07f2, 0x00fd, 0x003e, 0x000e, 0x0006, 0x0000, - 0x0002, 0x001e, 0x00fc, 0x03f8, 0x1fcc, 0x1fe8, 0x1fe9, 0x1fea, - 0x1feb, 0x1fec, 0x1fcd, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1, - 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x1ff9, - 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, 0x3fff, -}; - -static const uint8_t t_huffman_noise_bal_3_0dB_bits[25] = { - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 5, 2, 1, 3, 6, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, -}; - -static const uint8_t t_huffman_noise_bal_3_0dB_codes[25] = { - 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, - 0xf4, 0xf5, 0x1c, 0x02, 0x00, 0x06, 0x3a, 0xf6, - 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, - 0xff, -}; - -static const int8_t sbr_offset[6][16] = { - {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // fs_sbr = 16000 Hz - {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}, // fs_sbr = 22050 Hz - {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 24000 Hz - {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 32000 Hz - {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}, // 44100 Hz <= fs_sbr <= 64000 Hz - {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}, // 64000 Hz < fs_sbr -}; - -///< window coefficients for analysis/synthesis QMF banks -static DECLARE_ALIGNED(16, float, sbr_qmf_window_ds)[320]; -static DECLARE_ALIGNED(16, float, sbr_qmf_window_us)[640] = { - 0.0000000000, -0.0005525286, -0.0005617692, -0.0004947518, - -0.0004875227, -0.0004893791, -0.0005040714, -0.0005226564, - -0.0005466565, -0.0005677802, -0.0005870930, -0.0006132747, - -0.0006312493, -0.0006540333, -0.0006777690, -0.0006941614, - -0.0007157736, -0.0007255043, -0.0007440941, -0.0007490598, - -0.0007681371, -0.0007724848, -0.0007834332, -0.0007779869, - -0.0007803664, -0.0007801449, -0.0007757977, -0.0007630793, - -0.0007530001, -0.0007319357, -0.0007215391, -0.0006917937, - -0.0006650415, -0.0006341594, -0.0005946118, -0.0005564576, - -0.0005145572, -0.0004606325, -0.0004095121, -0.0003501175, - -0.0002896981, -0.0002098337, -0.0001446380, -0.0000617334, - 0.0000134949, 0.0001094383, 0.0002043017, 0.0002949531, - 0.0004026540, 0.0005107388, 0.0006239376, 0.0007458025, - 0.0008608443, 0.0009885988, 0.0011250155, 0.0012577884, - 0.0013902494, 0.0015443219, 0.0016868083, 0.0018348265, - 0.0019841140, 0.0021461583, 0.0023017254, 0.0024625616, - 0.0026201758, 0.0027870464, 0.0029469447, 0.0031125420, - 0.0032739613, 0.0034418874, 0.0036008268, 0.0037603922, - 0.0039207432, 0.0040819753, 0.0042264269, 0.0043730719, - 0.0045209852, 0.0046606460, 0.0047932560, 0.0049137603, - 0.0050393022, 0.0051407353, 0.0052461166, 0.0053471681, - 0.0054196775, 0.0054876040, 0.0055475714, 0.0055938023, - 0.0056220643, 0.0056455196, 0.0056389199, 0.0056266114, - 0.0055917128, 0.0055404363, 0.0054753783, 0.0053838975, - 0.0052715758, 0.0051382275, 0.0049839687, 0.0048109469, - 0.0046039530, 0.0043801861, 0.0041251642, 0.0038456408, - 0.0035401246, 0.0032091885, 0.0028446757, 0.0024508540, - 0.0020274176, 0.0015784682, 0.0010902329, 0.0005832264, - 0.0000276045, -0.0005464280, -0.0011568135, -0.0018039472, - -0.0024826723, -0.0031933778, -0.0039401124, -0.0047222596, - -0.0055337211, -0.0063792293, -0.0072615816, -0.0081798233, - -0.0091325329, -0.0101150215, -0.0111315548, -0.0121849995, - 0.0132718220, 0.0143904666, 0.0155405553, 0.0167324712, - 0.0179433381, 0.0191872431, 0.0204531793, 0.0217467550, - 0.0230680169, 0.0244160992, 0.0257875847, 0.0271859429, - 0.0286072173, 0.0300502657, 0.0315017608, 0.0329754081, - 0.0344620948, 0.0359697560, 0.0374812850, 0.0390053679, - 0.0405349170, 0.0420649094, 0.0436097542, 0.0451488405, - 0.0466843027, 0.0482165720, 0.0497385755, 0.0512556155, - 0.0527630746, 0.0542452768, 0.0557173648, 0.0571616450, - 0.0585915683, 0.0599837480, 0.0613455171, 0.0626857808, - 0.0639715898, 0.0652247106, 0.0664367512, 0.0676075985, - 0.0687043828, 0.0697630244, 0.0707628710, 0.0717002673, - 0.0725682583, 0.0733620255, 0.0741003642, 0.0747452558, - 0.0753137336, 0.0758008358, 0.0761992479, 0.0764992170, - 0.0767093490, 0.0768173975, 0.0768230011, 0.0767204924, - 0.0765050718, 0.0761748321, 0.0757305756, 0.0751576255, - 0.0744664394, 0.0736406005, 0.0726774642, 0.0715826364, - 0.0703533073, 0.0689664013, 0.0674525021, 0.0657690668, - 0.0639444805, 0.0619602779, 0.0598166570, 0.0575152691, - 0.0550460034, 0.0524093821, 0.0495978676, 0.0466303305, - 0.0434768782, 0.0401458278, 0.0366418116, 0.0329583930, - 0.0290824006, 0.0250307561, 0.0207997072, 0.0163701258, - 0.0117623832, 0.0069636862, 0.0019765601, -0.0032086896, - -0.0085711749, -0.0141288827, -0.0198834129, -0.0258227288, - -0.0319531274, -0.0382776572, -0.0447806821, -0.0514804176, - -0.0583705326, -0.0654409853, -0.0726943300, -0.0801372934, - -0.0877547536, -0.0955533352, -0.1035329531, -0.1116826931, - -0.1200077984, -0.1285002850, -0.1371551761, -0.1459766491, - -0.1549607071, -0.1640958855, -0.1733808172, -0.1828172548, - -0.1923966745, -0.2021250176, -0.2119735853, -0.2219652696, - -0.2320690870, -0.2423016884, -0.2526480309, -0.2631053299, - -0.2736634040, -0.2843214189, -0.2950716717, -0.3059098575, - -0.3168278913, -0.3278113727, -0.3388722693, -0.3499914122, - 0.3611589903, 0.3723795546, 0.3836350013, 0.3949211761, - 0.4062317676, 0.4175696896, 0.4289119920, 0.4402553754, - 0.4515996535, 0.4629308085, 0.4742453214, 0.4855253091, - 0.4967708254, 0.5079817500, 0.5191234970, 0.5302240895, - 0.5412553448, 0.5522051258, 0.5630789140, 0.5738524131, - 0.5845403235, 0.5951123086, 0.6055783538, 0.6159109932, - 0.6261242695, 0.6361980107, 0.6461269695, 0.6559016302, - 0.6655139880, 0.6749663190, 0.6842353293, 0.6933282376, - 0.7022388719, 0.7109410426, 0.7194462634, 0.7277448900, - 0.7358211758, 0.7436827863, 0.7513137456, 0.7587080760, - 0.7658674865, 0.7727780881, 0.7794287519, 0.7858353120, - 0.7919735841, 0.7978466413, 0.8034485751, 0.8087695004, - 0.8138191270, 0.8185776004, 0.8230419890, 0.8272275347, - 0.8311038457, 0.8346937361, 0.8379717337, 0.8409541392, - 0.8436238281, 0.8459818469, 0.8480315777, 0.8497805198, - 0.8511971524, 0.8523047035, 0.8531020949, 0.8535720573, - 0.8537385600, -}; - -static const float sbr_noise_table[512][2] = { -{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647}, -{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647}, -{ 0.80705063769351, 0.29653668284408}, {-0.38981478896926, 0.89572605717087}, -{-0.01053049862020, -0.66959058036166}, {-0.91266367957293, -0.11522938140034}, -{ 0.54840422910309, 0.75221367176302}, { 0.40009252867955, -0.98929400334421}, -{-0.99867974711855, -0.88147068645358}, {-0.95531076805040, 0.90908757154593}, -{-0.45725933317144, -0.56716323646760}, {-0.72929675029275, -0.98008272727324}, -{ 0.75622801399036, 0.20950329995549}, { 0.07069442601050, -0.78247898470706}, -{ 0.74496252926055, -0.91169004445807}, {-0.96440182703856, -0.94739918296622}, -{ 0.30424629369539, -0.49438267012479}, { 0.66565033746925, 0.64652935542491}, -{ 0.91697008020594, 0.17514097332009}, {-0.70774918760427, 0.52548653416543}, -{-0.70051415345560, -0.45340028808763}, {-0.99496513054797, -0.90071908066973}, -{ 0.98164490790123, -0.77463155528697}, {-0.54671580548181, -0.02570928536004}, -{-0.01689629065389, 0.00287506445732}, {-0.86110349531986, 0.42548583726477}, -{-0.98892980586032, -0.87881132267556}, { 0.51756627678691, 0.66926784710139}, -{-0.99635026409640, -0.58107730574765}, {-0.99969370862163, 0.98369989360250}, -{ 0.55266258627194, 0.59449057465591}, { 0.34581177741673, 0.94879421061866}, -{ 0.62664209577999, -0.74402970906471}, {-0.77149701404973, -0.33883658042801}, -{-0.91592244254432, 0.03687901376713}, {-0.76285492357887, -0.91371867919124}, -{ 0.79788337195331, -0.93180971199849}, { 0.54473080610200, -0.11919206037186}, -{-0.85639281671058, 0.42429854760451}, {-0.92882402971423, 0.27871809078609}, -{-0.11708371046774, -0.99800843444966}, { 0.21356749817493, -0.90716295627033}, -{-0.76191692573909, 0.99768118356265}, { 0.98111043100884, -0.95854459734407}, -{-0.85913269895572, 0.95766566168880}, {-0.93307242253692, 0.49431757696466}, -{ 0.30485754879632, -0.70540034357529}, { 0.85289650925190, 0.46766131791044}, -{ 0.91328082618125, -0.99839597361769}, {-0.05890199924154, 0.70741827819497}, -{ 0.28398686150148, 0.34633555702188}, { 0.95258164539612, -0.54893416026939}, -{-0.78566324168507, -0.75568541079691}, {-0.95789495447877, -0.20423194696966}, -{ 0.82411158711197, 0.96654618432562}, {-0.65185446735885, -0.88734990773289}, -{-0.93643603134666, 0.99870790442385}, { 0.91427159529618, -0.98290505544444}, -{-0.70395684036886, 0.58796798221039}, { 0.00563771969365, 0.61768196727244}, -{ 0.89065051931895, 0.52783352697585}, {-0.68683707712762, 0.80806944710339}, -{ 0.72165342518718, -0.69259857349564}, {-0.62928247730667, 0.13627037407335}, -{ 0.29938434065514, -0.46051329682246}, {-0.91781958879280, -0.74012716684186}, -{ 0.99298717043688, 0.40816610075661}, { 0.82368298622748, -0.74036047190173}, -{-0.98512833386833, -0.99972330709594}, {-0.95915368242257, -0.99237800466040}, -{-0.21411126572790, -0.93424819052545}, {-0.68821476106884, -0.26892306315457}, -{ 0.91851997982317, 0.09358228901785}, {-0.96062769559127, 0.36099095133739}, -{ 0.51646184922287, -0.71373332873917}, { 0.61130721139669, 0.46950141175917}, -{ 0.47336129371299, -0.27333178296162}, { 0.90998308703519, 0.96715662938132}, -{ 0.44844799194357, 0.99211574628306}, { 0.66614891079092, 0.96590176169121}, -{ 0.74922239129237, -0.89879858826087}, {-0.99571588506485, 0.52785521494349}, -{ 0.97401082477563, -0.16855870075190}, { 0.72683747733879, -0.48060774432251}, -{ 0.95432193457128, 0.68849603408441}, {-0.72962208425191, -0.76608443420917}, -{-0.85359479233537, 0.88738125901579}, {-0.81412430338535, -0.97480768049637}, -{-0.87930772356786, 0.74748307690436}, {-0.71573331064977, -0.98570608178923}, -{ 0.83524300028228, 0.83702537075163}, {-0.48086065601423, -0.98848504923531}, -{ 0.97139128574778, 0.80093621198236}, { 0.51992825347895, 0.80247631400510}, -{-0.00848591195325, -0.76670128000486}, {-0.70294374303036, 0.55359910445577}, -{-0.95894428168140, -0.43265504344783}, { 0.97079252950321, 0.09325857238682}, -{-0.92404293670797, 0.85507704027855}, {-0.69506469500450, 0.98633412625459}, -{ 0.26559203620024, 0.73314307966524}, { 0.28038443336943, 0.14537913654427}, -{-0.74138124825523, 0.99310339807762}, {-0.01752795995444, -0.82616635284178}, -{-0.55126773094930, -0.98898543862153}, { 0.97960898850996, -0.94021446752851}, -{-0.99196309146936, 0.67019017358456}, {-0.67684928085260, 0.12631491649378}, -{ 0.09140039465500, -0.20537731453108}, {-0.71658965751996, -0.97788200391224}, -{ 0.81014640078925, 0.53722648362443}, { 0.40616991671205, -0.26469008598449}, -{-0.67680188682972, 0.94502052337695}, { 0.86849774348749, -0.18333598647899}, -{-0.99500381284851, -0.02634122068550}, { 0.84329189340667, 0.10406957462213}, -{-0.09215968531446, 0.69540012101253}, { 0.99956173327206, -0.12358542001404}, -{-0.79732779473535, -0.91582524736159}, { 0.96349973642406, 0.96640458041000}, -{-0.79942778496547, 0.64323902822857}, {-0.11566039853896, 0.28587846253726}, -{-0.39922954514662, 0.94129601616966}, { 0.99089197565987, -0.92062625581587}, -{ 0.28631285179909, -0.91035047143603}, {-0.83302725605608, -0.67330410892084}, -{ 0.95404443402072, 0.49162765398743}, {-0.06449863579434, 0.03250560813135}, -{-0.99575054486311, 0.42389784469507}, {-0.65501142790847, 0.82546114655624}, -{-0.81254441908887, -0.51627234660629}, {-0.99646369485481, 0.84490533520752}, -{ 0.00287840603348, 0.64768261158166}, { 0.70176989408455, -0.20453028573322}, -{ 0.96361882270190, 0.40706967140989}, {-0.68883758192426, 0.91338958840772}, -{-0.34875585502238, 0.71472290693300}, { 0.91980081243087, 0.66507455644919}, -{-0.99009048343881, 0.85868021604848}, { 0.68865791458395, 0.55660316809678}, -{-0.99484402129368, -0.20052559254934}, { 0.94214511408023, -0.99696425367461}, -{-0.67414626793544, 0.49548221180078}, {-0.47339353684664, -0.85904328834047}, -{ 0.14323651387360, -0.94145598222488}, {-0.29268293575672, 0.05759224927952}, -{ 0.43793861458754, -0.78904969892724}, {-0.36345126374441, 0.64874435357162}, -{-0.08750604656825, 0.97686944362527}, {-0.96495267812511, -0.53960305946511}, -{ 0.55526940659947, 0.78891523734774}, { 0.73538215752630, 0.96452072373404}, -{-0.30889773919437, -0.80664389776860}, { 0.03574995626194, -0.97325616900959}, -{ 0.98720684660488, 0.48409133691962}, {-0.81689296271203, -0.90827703628298}, -{ 0.67866860118215, 0.81284503870856}, {-0.15808569732583, 0.85279555024382}, -{ 0.80723395114371, -0.24717418514605}, { 0.47788757329038, -0.46333147839295}, -{ 0.96367554763201, 0.38486749303242}, {-0.99143875716818, -0.24945277239809}, -{ 0.83081876925833, -0.94780851414763}, {-0.58753191905341, 0.01290772389163}, -{ 0.95538108220960, -0.85557052096538}, {-0.96490920476211, -0.64020970923102}, -{-0.97327101028521, 0.12378128133110}, { 0.91400366022124, 0.57972471346930}, -{-0.99925837363824, 0.71084847864067}, {-0.86875903507313, -0.20291699203564}, -{-0.26240034795124, -0.68264554369108}, {-0.24664412953388, -0.87642273115183}, -{ 0.02416275806869, 0.27192914288905}, { 0.82068619590515, -0.85087787994476}, -{ 0.88547373760759, -0.89636802901469}, {-0.18173078152226, -0.26152145156800}, -{ 0.09355476558534, 0.54845123045604}, {-0.54668414224090, 0.95980774020221}, -{ 0.37050990604091, -0.59910140383171}, {-0.70373594262891, 0.91227665827081}, -{-0.34600785879594, -0.99441426144200}, {-0.68774481731008, -0.30238837956299}, -{-0.26843291251234, 0.83115668004362}, { 0.49072334613242, -0.45359708737775}, -{ 0.38975993093975, 0.95515358099121}, {-0.97757125224150, 0.05305894580606}, -{-0.17325552859616, -0.92770672250494}, { 0.99948035025744, 0.58285545563426}, -{-0.64946246527458, 0.68645507104960}, {-0.12016920576437, -0.57147322153312}, -{-0.58947456517751, -0.34847132454388}, {-0.41815140454465, 0.16276422358861}, -{ 0.99885650204884, 0.11136095490444}, {-0.56649614128386, -0.90494866361587}, -{ 0.94138021032330, 0.35281916733018}, {-0.75725076534641, 0.53650549640587}, -{ 0.20541973692630, -0.94435144369918}, { 0.99980371023351, 0.79835913565599}, -{ 0.29078277605775, 0.35393777921520}, {-0.62858772103030, 0.38765693387102}, -{ 0.43440904467688, -0.98546330463232}, {-0.98298583762390, 0.21021524625209}, -{ 0.19513029146934, -0.94239832251867}, {-0.95476662400101, 0.98364554179143}, -{ 0.93379635304810, -0.70881994583682}, {-0.85235410573336, -0.08342347966410}, -{-0.86425093011245, -0.45795025029466}, { 0.38879779059045, 0.97274429344593}, -{ 0.92045124735495, -0.62433652524220}, { 0.89162532251878, 0.54950955570563}, -{-0.36834336949252, 0.96458298020975}, { 0.93891760988045, -0.89968353740388}, -{ 0.99267657565094, -0.03757034316958}, {-0.94063471614176, 0.41332338538963}, -{ 0.99740224117019, -0.16830494996370}, {-0.35899413170555, -0.46633226649613}, -{ 0.05237237274947, -0.25640361602661}, { 0.36703583957424, -0.38653265641875}, -{ 0.91653180367913, -0.30587628726597}, { 0.69000803499316, 0.90952171386132}, -{-0.38658751133527, 0.99501571208985}, {-0.29250814029851, 0.37444994344615}, -{-0.60182204677608, 0.86779651036123}, {-0.97418588163217, 0.96468523666475}, -{ 0.88461574003963, 0.57508405276414}, { 0.05198933055162, 0.21269661669964}, -{-0.53499621979720, 0.97241553731237}, {-0.49429560226497, 0.98183865291903}, -{-0.98935142339139, -0.40249159006933}, {-0.98081380091130, -0.72856895534041}, -{-0.27338148835532, 0.99950922447209}, { 0.06310802338302, -0.54539587529618}, -{-0.20461677199539, -0.14209977628489}, { 0.66223843141647, 0.72528579940326}, -{-0.84764345483665, 0.02372316801261}, {-0.89039863483811, 0.88866581484602}, -{ 0.95903308477986, 0.76744927173873}, { 0.73504123909879, -0.03747203173192}, -{-0.31744434966056, -0.36834111883652}, {-0.34110827591623, 0.40211222807691}, -{ 0.47803883714199, -0.39423219786288}, { 0.98299195879514, 0.01989791390047}, -{-0.30963073129751, -0.18076720599336}, { 0.99992588229018, -0.26281872094289}, -{-0.93149731080767, -0.98313162570490}, { 0.99923472302773, -0.80142993767554}, -{-0.26024169633417, -0.75999759855752}, {-0.35712514743563, 0.19298963768574}, -{-0.99899084509530, 0.74645156992493}, { 0.86557171579452, 0.55593866696299}, -{ 0.33408042438752, 0.86185953874709}, { 0.99010736374716, 0.04602397576623}, -{-0.66694269691195, -0.91643611810148}, { 0.64016792079480, 0.15649530836856}, -{ 0.99570534804836, 0.45844586038111}, {-0.63431466947340, 0.21079116459234}, -{-0.07706847005931, -0.89581437101329}, { 0.98590090577724, 0.88241721133981}, -{ 0.80099335254678, -0.36851896710853}, { 0.78368131392666, 0.45506999802597}, -{ 0.08707806671691, 0.80938994918745}, {-0.86811883080712, 0.39347308654705}, -{-0.39466529740375, -0.66809432114456}, { 0.97875325649683, -0.72467840967746}, -{-0.95038560288864, 0.89563219587625}, { 0.17005239424212, 0.54683053962658}, -{-0.76910792026848, -0.96226617549298}, { 0.99743281016846, 0.42697157037567}, -{ 0.95437383549973, 0.97002324109952}, { 0.99578905365569, -0.54106826257356}, -{ 0.28058259829990, -0.85361420634036}, { 0.85256524470573, -0.64567607735589}, -{-0.50608540105128, -0.65846015480300}, {-0.97210735183243, -0.23095213067791}, -{ 0.95424048234441, -0.99240147091219}, {-0.96926570524023, 0.73775654896574}, -{ 0.30872163214726, 0.41514960556126}, {-0.24523839572639, 0.63206633394807}, -{-0.33813265086024, -0.38661779441897}, {-0.05826828420146, -0.06940774188029}, -{-0.22898461455054, 0.97054853316316}, {-0.18509915019881, 0.47565762892084}, -{-0.10488238045009, -0.87769947402394}, {-0.71886586182037, 0.78030982480538}, -{ 0.99793873738654, 0.90041310491497}, { 0.57563307626120, -0.91034337352097}, -{ 0.28909646383717, 0.96307783970534}, { 0.42188998312520, 0.48148651230437}, -{ 0.93335049681047, -0.43537023883588}, {-0.97087374418267, 0.86636445711364}, -{ 0.36722871286923, 0.65291654172961}, {-0.81093025665696, 0.08778370229363}, -{-0.26240603062237, -0.92774095379098}, { 0.83996497984604, 0.55839849139647}, -{-0.99909615720225, -0.96024605713970}, { 0.74649464155061, 0.12144893606462}, -{-0.74774595569805, -0.26898062008959}, { 0.95781667469567, -0.79047927052628}, -{ 0.95472308713099, -0.08588776019550}, { 0.48708332746299, 0.99999041579432}, -{ 0.46332038247497, 0.10964126185063}, {-0.76497004940162, 0.89210929242238}, -{ 0.57397389364339, 0.35289703373760}, { 0.75374316974495, 0.96705214651335}, -{-0.59174397685714, -0.89405370422752}, { 0.75087906691890, -0.29612672982396}, -{-0.98607857336230, 0.25034911730023}, {-0.40761056640505, -0.90045573444695}, -{ 0.66929266740477, 0.98629493401748}, {-0.97463695257310, -0.00190223301301}, -{ 0.90145509409859, 0.99781390365446}, {-0.87259289048043, 0.99233587353666}, -{-0.91529461447692, -0.15698707534206}, {-0.03305738840705, -0.37205262859764}, -{ 0.07223051368337, -0.88805001733626}, { 0.99498012188353, 0.97094358113387}, -{-0.74904939500519, 0.99985483641521}, { 0.04585228574211, 0.99812337444082}, -{-0.89054954257993, -0.31791913188064}, {-0.83782144651251, 0.97637632547466}, -{ 0.33454804933804, -0.86231516800408}, {-0.99707579362824, 0.93237990079441}, -{-0.22827527843994, 0.18874759397997}, { 0.67248046289143, -0.03646211390569}, -{-0.05146538187944, -0.92599700120679}, { 0.99947295749905, 0.93625229707912}, -{ 0.66951124390363, 0.98905825623893}, {-0.99602956559179, -0.44654715757688}, -{ 0.82104905483590, 0.99540741724928}, { 0.99186510988782, 0.72023001312947}, -{-0.65284592392918, 0.52186723253637}, { 0.93885443798188, -0.74895312615259}, -{ 0.96735248738388, 0.90891816978629}, {-0.22225968841114, 0.57124029781228}, -{-0.44132783753414, -0.92688840659280}, {-0.85694974219574, 0.88844532719844}, -{ 0.91783042091762, -0.46356892383970}, { 0.72556974415690, -0.99899555770747}, -{-0.99711581834508, 0.58211560180426}, { 0.77638976371966, 0.94321834873819}, -{ 0.07717324253925, 0.58638399856595}, {-0.56049829194163, 0.82522301569036}, -{ 0.98398893639988, 0.39467440420569}, { 0.47546946844938, 0.68613044836811}, -{ 0.65675089314631, 0.18331637134880}, { 0.03273375457980, -0.74933109564108}, -{-0.38684144784738, 0.51337349030406}, {-0.97346267944545, -0.96549364384098}, -{-0.53282156061942, -0.91423265091354}, { 0.99817310731176, 0.61133572482148}, -{-0.50254500772635, -0.88829338134294}, { 0.01995873238855, 0.85223515096765}, -{ 0.99930381973804, 0.94578896296649}, { 0.82907767600783, -0.06323442598128}, -{-0.58660709669728, 0.96840773806582}, {-0.17573736667267, -0.48166920859485}, -{ 0.83434292401346, -0.13023450646997}, { 0.05946491307025, 0.20511047074866}, -{ 0.81505484574602, -0.94685947861369}, {-0.44976380954860, 0.40894572671545}, -{-0.89746474625671, 0.99846578838537}, { 0.39677256130792, -0.74854668609359}, -{-0.07588948563079, 0.74096214084170}, { 0.76343198951445, 0.41746629422634}, -{-0.74490104699626, 0.94725911744610}, { 0.64880119792759, 0.41336660830571}, -{ 0.62319537462542, -0.93098313552599}, { 0.42215817594807, -0.07712787385208}, -{ 0.02704554141885, -0.05417518053666}, { 0.80001773566818, 0.91542195141039}, -{-0.79351832348816, -0.36208897989136}, { 0.63872359151636, 0.08128252493444}, -{ 0.52890520960295, 0.60048872455592}, { 0.74238552914587, 0.04491915291044}, -{ 0.99096131449250, -0.19451182854402}, {-0.80412329643109, -0.88513818199457}, -{-0.64612616129736, 0.72198674804544}, { 0.11657770663191, -0.83662833815041}, -{-0.95053182488101, -0.96939905138082}, {-0.62228872928622, 0.82767262846661}, -{ 0.03004475787316, -0.99738896333384}, {-0.97987214341034, 0.36526129686425}, -{-0.99986980746200, -0.36021610299715}, { 0.89110648599879, -0.97894250343044}, -{ 0.10407960510582, 0.77357793811619}, { 0.95964737821728, -0.35435818285502}, -{ 0.50843233159162, 0.96107691266205}, { 0.17006334670615, -0.76854025314829}, -{ 0.25872675063360, 0.99893303933816}, {-0.01115998681937, 0.98496019742444}, -{-0.79598702973261, 0.97138411318894}, {-0.99264708948101, -0.99542822402536}, -{-0.99829663752818, 0.01877138824311}, {-0.70801016548184, 0.33680685948117}, -{-0.70467057786826, 0.93272777501857}, { 0.99846021905254, -0.98725746254433}, -{-0.63364968534650, -0.16473594423746}, {-0.16258217500792, -0.95939125400802}, -{-0.43645594360633, -0.94805030113284}, {-0.99848471702976, 0.96245166923809}, -{-0.16796458968998, -0.98987511890470}, {-0.87979225745213, -0.71725725041680}, -{ 0.44183099021786, -0.93568974498761}, { 0.93310180125532, -0.99913308068246}, -{-0.93941931782002, -0.56409379640356}, {-0.88590003188677, 0.47624600491382}, -{ 0.99971463703691, -0.83889954253462}, {-0.75376385639978, 0.00814643438625}, -{ 0.93887685615875, -0.11284528204636}, { 0.85126435782309, 0.52349251543547}, -{ 0.39701421446381, 0.81779634174316}, {-0.37024464187437, -0.87071656222959}, -{-0.36024828242896, 0.34655735648287}, {-0.93388812549209, -0.84476541096429}, -{-0.65298804552119, -0.18439575450921}, { 0.11960319006843, 0.99899346780168}, -{ 0.94292565553160, 0.83163906518293}, { 0.75081145286948, -0.35533223142265}, -{ 0.56721979748394, -0.24076836414499}, { 0.46857766746029, -0.30140233457198}, -{ 0.97312313923635, -0.99548191630031}, {-0.38299976567017, 0.98516909715427}, -{ 0.41025800019463, 0.02116736935734}, { 0.09638062008048, 0.04411984381457}, -{-0.85283249275397, 0.91475563922421}, { 0.88866808958124, -0.99735267083226}, -{-0.48202429536989, -0.96805608884164}, { 0.27572582416567, 0.58634753335832}, -{-0.65889129659168, 0.58835634138583}, { 0.98838086953732, 0.99994349600236}, -{-0.20651349620689, 0.54593044066355}, {-0.62126416356920, -0.59893681700392}, -{ 0.20320105410437, -0.86879180355289}, {-0.97790548600584, 0.96290806999242}, -{ 0.11112534735126, 0.21484763313301}, {-0.41368337314182, 0.28216837680365}, -{ 0.24133038992960, 0.51294362630238}, {-0.66393410674885, -0.08249679629081}, -{-0.53697829178752, -0.97649903936228}, {-0.97224737889348, 0.22081333579837}, -{ 0.87392477144549, -0.12796173740361}, { 0.19050361015753, 0.01602615387195}, -{-0.46353441212724, -0.95249041539006}, {-0.07064096339021, -0.94479803205886}, -{-0.92444085484466, -0.10457590187436}, {-0.83822593578728, -0.01695043208885}, -{ 0.75214681811150, -0.99955681042665}, {-0.42102998829339, 0.99720941999394}, -{-0.72094786237696, -0.35008961934255}, { 0.78843311019251, 0.52851398958271}, -{ 0.97394027897442, -0.26695944086561}, { 0.99206463477946, -0.57010120849429}, -{ 0.76789609461795, -0.76519356730966}, {-0.82002421836409, -0.73530179553767}, -{ 0.81924990025724, 0.99698425250579}, {-0.26719850873357, 0.68903369776193}, -{-0.43311260380975, 0.85321815947490}, { 0.99194979673836, 0.91876249766422}, -{-0.80692001248487, -0.32627540663214}, { 0.43080003649976, -0.21919095636638}, -{ 0.67709491937357, -0.95478075822906}, { 0.56151770568316, -0.70693811747778}, -{ 0.10831862810749, -0.08628837174592}, { 0.91229417540436, -0.65987351408410}, -{-0.48972893932274, 0.56289246362686}, {-0.89033658689697, -0.71656563987082}, -{ 0.65269447475094, 0.65916004833932}, { 0.67439478141121, -0.81684380846796}, -{-0.47770832416973, -0.16789556203025}, {-0.99715979260878, -0.93565784007648}, -{-0.90889593602546, 0.62034397054380}, {-0.06618622548177, -0.23812217221359}, -{ 0.99430266919728, 0.18812555317553}, { 0.97686402381843, -0.28664534366620}, -{ 0.94813650221268, -0.97506640027128}, {-0.95434497492853, -0.79607978501983}, -{-0.49104783137150, 0.32895214359663}, { 0.99881175120751, 0.88993983831354}, -{ 0.50449166760303, -0.85995072408434}, { 0.47162891065108, -0.18680204049569}, -{-0.62081581361840, 0.75000676218956}, {-0.43867015250812, 0.99998069244322}, -{ 0.98630563232075, -0.53578899600662}, {-0.61510362277374, -0.89515019899997}, -{-0.03841517601843, -0.69888815681179}, {-0.30102157304644, -0.07667808922205}, -{ 0.41881284182683, 0.02188098922282}, {-0.86135454941237, 0.98947480909359}, -{ 0.67226861393788, -0.13494389011014}, {-0.70737398842068, -0.76547349325992}, -{ 0.94044946687963, 0.09026201157416}, {-0.82386352534327, 0.08924768823676}, -{-0.32070666698656, 0.50143421908753}, { 0.57593163224487, -0.98966422921509}, -{-0.36326018419965, 0.07440243123228}, { 0.99979044674350, -0.14130287347405}, -{-0.92366023326932, -0.97979298068180}, {-0.44607178518598, -0.54233252016394}, -{ 0.44226800932956, 0.71326756742752}, { 0.03671907158312, 0.63606389366675}, -{ 0.52175424682195, -0.85396826735705}, {-0.94701139690956, -0.01826348194255}, -{-0.98759606946049, 0.82288714303073}, { 0.87434794743625, 0.89399495655433}, -{-0.93412041758744, 0.41374052024363}, { 0.96063943315511, 0.93116709541280}, -{ 0.97534253457837, 0.86150930812689}, { 0.99642466504163, 0.70190043427512}, -{-0.94705089665984, -0.29580042814306}, { 0.91599807087376, -0.98147830385781}, -}; - -#endif /* AVCODEC_AACSBRDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aactab.c b/tizen/distrib/ffmpeg/libavcodec/aactab.c deleted file mode 100644 index eaa5486..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aactab.c +++ /dev/null @@ -1,1332 +0,0 @@ -/* - * AAC data - * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) - * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC data - * @author Oded Shimon ( ods15 ods15 dyndns org ) - * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) - */ - -#include "libavutil/mem.h" -#include "aac.h" - -#include - -DECLARE_ALIGNED(16, float, ff_aac_kbd_long_1024)[1024]; -DECLARE_ALIGNED(16, float, ff_aac_kbd_short_128)[128]; - -const uint8_t ff_aac_num_swb_1024[] = { - 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40 -}; - -const uint8_t ff_aac_num_swb_128[] = { - 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15 -}; - -const uint8_t ff_aac_pred_sfb_max[] = { - 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34, 34 -}; - -const uint32_t ff_aac_scalefactor_code[121] = { - 0x3ffe8, 0x3ffe6, 0x3ffe7, 0x3ffe5, 0x7fff5, 0x7fff1, 0x7ffed, 0x7fff6, - 0x7ffee, 0x7ffef, 0x7fff0, 0x7fffc, 0x7fffd, 0x7ffff, 0x7fffe, 0x7fff7, - 0x7fff8, 0x7fffb, 0x7fff9, 0x3ffe4, 0x7fffa, 0x3ffe3, 0x1ffef, 0x1fff0, - 0x0fff5, 0x1ffee, 0x0fff2, 0x0fff3, 0x0fff4, 0x0fff1, 0x07ff6, 0x07ff7, - 0x03ff9, 0x03ff5, 0x03ff7, 0x03ff3, 0x03ff6, 0x03ff2, 0x01ff7, 0x01ff5, - 0x00ff9, 0x00ff7, 0x00ff6, 0x007f9, 0x00ff4, 0x007f8, 0x003f9, 0x003f7, - 0x003f5, 0x001f8, 0x001f7, 0x000fa, 0x000f8, 0x000f6, 0x00079, 0x0003a, - 0x00038, 0x0001a, 0x0000b, 0x00004, 0x00000, 0x0000a, 0x0000c, 0x0001b, - 0x00039, 0x0003b, 0x00078, 0x0007a, 0x000f7, 0x000f9, 0x001f6, 0x001f9, - 0x003f4, 0x003f6, 0x003f8, 0x007f5, 0x007f4, 0x007f6, 0x007f7, 0x00ff5, - 0x00ff8, 0x01ff4, 0x01ff6, 0x01ff8, 0x03ff8, 0x03ff4, 0x0fff0, 0x07ff4, - 0x0fff6, 0x07ff5, 0x3ffe2, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, - 0x7ffde, 0x7ffd8, 0x7ffd2, 0x7ffd3, 0x7ffd4, 0x7ffd5, 0x7ffd6, 0x7fff2, - 0x7ffdf, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffe6, 0x7ffe0, - 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffd7, 0x7ffec, 0x7fff4, - 0x7fff3, -}; - -const uint8_t ff_aac_scalefactor_bits[121] = { - 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 18, 19, 18, 17, 17, 16, 17, 16, 16, 16, 16, 15, 15, - 14, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 11, 12, 11, 10, 10, - 10, 9, 9, 8, 8, 8, 7, 6, 6, 5, 4, 3, 1, 4, 4, 5, - 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, - 12, 13, 13, 13, 14, 14, 16, 15, 16, 15, 18, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, -}; - -static const uint16_t codes1[81] = { - 0x7f8, 0x1f1, 0x7fd, 0x3f5, 0x068, 0x3f0, 0x7f7, 0x1ec, - 0x7f5, 0x3f1, 0x072, 0x3f4, 0x074, 0x011, 0x076, 0x1eb, - 0x06c, 0x3f6, 0x7fc, 0x1e1, 0x7f1, 0x1f0, 0x061, 0x1f6, - 0x7f2, 0x1ea, 0x7fb, 0x1f2, 0x069, 0x1ed, 0x077, 0x017, - 0x06f, 0x1e6, 0x064, 0x1e5, 0x067, 0x015, 0x062, 0x012, - 0x000, 0x014, 0x065, 0x016, 0x06d, 0x1e9, 0x063, 0x1e4, - 0x06b, 0x013, 0x071, 0x1e3, 0x070, 0x1f3, 0x7fe, 0x1e7, - 0x7f3, 0x1ef, 0x060, 0x1ee, 0x7f0, 0x1e2, 0x7fa, 0x3f3, - 0x06a, 0x1e8, 0x075, 0x010, 0x073, 0x1f4, 0x06e, 0x3f7, - 0x7f6, 0x1e0, 0x7f9, 0x3f2, 0x066, 0x1f5, 0x7ff, 0x1f7, - 0x7f4, -}; - -static const uint8_t bits1[81] = { - 11, 9, 11, 10, 7, 10, 11, 9, 11, 10, 7, 10, 7, 5, 7, 9, - 7, 10, 11, 9, 11, 9, 7, 9, 11, 9, 11, 9, 7, 9, 7, 5, - 7, 9, 7, 9, 7, 5, 7, 5, 1, 5, 7, 5, 7, 9, 7, 9, - 7, 5, 7, 9, 7, 9, 11, 9, 11, 9, 7, 9, 11, 9, 11, 10, - 7, 9, 7, 5, 7, 9, 7, 10, 11, 9, 11, 10, 7, 9, 11, 9, - 11, -}; - -static const uint16_t codes2[81] = { - 0x1f3, 0x06f, 0x1fd, 0x0eb, 0x023, 0x0ea, 0x1f7, 0x0e8, - 0x1fa, 0x0f2, 0x02d, 0x070, 0x020, 0x006, 0x02b, 0x06e, - 0x028, 0x0e9, 0x1f9, 0x066, 0x0f8, 0x0e7, 0x01b, 0x0f1, - 0x1f4, 0x06b, 0x1f5, 0x0ec, 0x02a, 0x06c, 0x02c, 0x00a, - 0x027, 0x067, 0x01a, 0x0f5, 0x024, 0x008, 0x01f, 0x009, - 0x000, 0x007, 0x01d, 0x00b, 0x030, 0x0ef, 0x01c, 0x064, - 0x01e, 0x00c, 0x029, 0x0f3, 0x02f, 0x0f0, 0x1fc, 0x071, - 0x1f2, 0x0f4, 0x021, 0x0e6, 0x0f7, 0x068, 0x1f8, 0x0ee, - 0x022, 0x065, 0x031, 0x002, 0x026, 0x0ed, 0x025, 0x06a, - 0x1fb, 0x072, 0x1fe, 0x069, 0x02e, 0x0f6, 0x1ff, 0x06d, - 0x1f6, -}; - -static const uint8_t bits2[81] = { - 9, 7, 9, 8, 6, 8, 9, 8, 9, 8, 6, 7, 6, 5, 6, 7, - 6, 8, 9, 7, 8, 8, 6, 8, 9, 7, 9, 8, 6, 7, 6, 5, - 6, 7, 6, 8, 6, 5, 6, 5, 3, 5, 6, 5, 6, 8, 6, 7, - 6, 5, 6, 8, 6, 8, 9, 7, 9, 8, 6, 8, 8, 7, 9, 8, - 6, 7, 6, 4, 6, 8, 6, 7, 9, 7, 9, 7, 6, 8, 9, 7, - 9, -}; - -static const uint16_t codes3[81] = { - 0x0000, 0x0009, 0x00ef, 0x000b, 0x0019, 0x00f0, 0x01eb, 0x01e6, - 0x03f2, 0x000a, 0x0035, 0x01ef, 0x0034, 0x0037, 0x01e9, 0x01ed, - 0x01e7, 0x03f3, 0x01ee, 0x03ed, 0x1ffa, 0x01ec, 0x01f2, 0x07f9, - 0x07f8, 0x03f8, 0x0ff8, 0x0008, 0x0038, 0x03f6, 0x0036, 0x0075, - 0x03f1, 0x03eb, 0x03ec, 0x0ff4, 0x0018, 0x0076, 0x07f4, 0x0039, - 0x0074, 0x03ef, 0x01f3, 0x01f4, 0x07f6, 0x01e8, 0x03ea, 0x1ffc, - 0x00f2, 0x01f1, 0x0ffb, 0x03f5, 0x07f3, 0x0ffc, 0x00ee, 0x03f7, - 0x7ffe, 0x01f0, 0x07f5, 0x7ffd, 0x1ffb, 0x3ffa, 0xffff, 0x00f1, - 0x03f0, 0x3ffc, 0x01ea, 0x03ee, 0x3ffb, 0x0ff6, 0x0ffa, 0x7ffc, - 0x07f2, 0x0ff5, 0xfffe, 0x03f4, 0x07f7, 0x7ffb, 0x0ff7, 0x0ff9, - 0x7ffa, -}; - -static const uint8_t bits3[81] = { - 1, 4, 8, 4, 5, 8, 9, 9, 10, 4, 6, 9, 6, 6, 9, 9, - 9, 10, 9, 10, 13, 9, 9, 11, 11, 10, 12, 4, 6, 10, 6, 7, - 10, 10, 10, 12, 5, 7, 11, 6, 7, 10, 9, 9, 11, 9, 10, 13, - 8, 9, 12, 10, 11, 12, 8, 10, 15, 9, 11, 15, 13, 14, 16, 8, - 10, 14, 9, 10, 14, 12, 12, 15, 11, 12, 16, 10, 11, 15, 12, 12, - 15, -}; - -static const uint16_t codes4[81] = { - 0x007, 0x016, 0x0f6, 0x018, 0x008, 0x0ef, 0x1ef, 0x0f3, - 0x7f8, 0x019, 0x017, 0x0ed, 0x015, 0x001, 0x0e2, 0x0f0, - 0x070, 0x3f0, 0x1ee, 0x0f1, 0x7fa, 0x0ee, 0x0e4, 0x3f2, - 0x7f6, 0x3ef, 0x7fd, 0x005, 0x014, 0x0f2, 0x009, 0x004, - 0x0e5, 0x0f4, 0x0e8, 0x3f4, 0x006, 0x002, 0x0e7, 0x003, - 0x000, 0x06b, 0x0e3, 0x069, 0x1f3, 0x0eb, 0x0e6, 0x3f6, - 0x06e, 0x06a, 0x1f4, 0x3ec, 0x1f0, 0x3f9, 0x0f5, 0x0ec, - 0x7fb, 0x0ea, 0x06f, 0x3f7, 0x7f9, 0x3f3, 0xfff, 0x0e9, - 0x06d, 0x3f8, 0x06c, 0x068, 0x1f5, 0x3ee, 0x1f2, 0x7f4, - 0x7f7, 0x3f1, 0xffe, 0x3ed, 0x1f1, 0x7f5, 0x7fe, 0x3f5, - 0x7fc, -}; - -static const uint8_t bits4[81] = { - 4, 5, 8, 5, 4, 8, 9, 8, 11, 5, 5, 8, 5, 4, 8, 8, - 7, 10, 9, 8, 11, 8, 8, 10, 11, 10, 11, 4, 5, 8, 4, 4, - 8, 8, 8, 10, 4, 4, 8, 4, 4, 7, 8, 7, 9, 8, 8, 10, - 7, 7, 9, 10, 9, 10, 8, 8, 11, 8, 7, 10, 11, 10, 12, 8, - 7, 10, 7, 7, 9, 10, 9, 11, 11, 10, 12, 10, 9, 11, 11, 10, - 11, -}; - -static const uint16_t codes5[81] = { - 0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, - 0x1ffd, 0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, - 0x07f2, 0x0ffa, 0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, - 0x01f0, 0x03ea, 0x07f3, 0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, - 0x0019, 0x00ee, 0x01ef, 0x07ed, 0x03f0, 0x00f2, 0x0073, 0x000b, - 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9, 0x07ef, 0x01ee, 0x00ef, - 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec, 0x07f6, 0x03eb, - 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7, 0x0ff6, - 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9, - 0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, - 0x1ffe, -}; - -static const uint8_t bits5[81] = { - 13, 12, 11, 11, 10, 11, 11, 12, 13, 12, 11, 10, 9, 8, 9, 10, - 11, 12, 12, 10, 9, 8, 7, 8, 9, 10, 11, 11, 9, 8, 5, 4, - 5, 8, 9, 11, 10, 8, 7, 4, 1, 4, 7, 8, 11, 11, 9, 8, - 5, 4, 5, 8, 9, 11, 11, 10, 9, 8, 7, 8, 9, 10, 11, 12, - 11, 10, 9, 8, 9, 10, 11, 12, 13, 12, 12, 11, 10, 10, 11, 12, - 13, -}; - -static const uint16_t codes6[81] = { - 0x7fe, 0x3fd, 0x1f1, 0x1eb, 0x1f4, 0x1ea, 0x1f0, 0x3fc, - 0x7fd, 0x3f6, 0x1e5, 0x0ea, 0x06c, 0x071, 0x068, 0x0f0, - 0x1e6, 0x3f7, 0x1f3, 0x0ef, 0x032, 0x027, 0x028, 0x026, - 0x031, 0x0eb, 0x1f7, 0x1e8, 0x06f, 0x02e, 0x008, 0x004, - 0x006, 0x029, 0x06b, 0x1ee, 0x1ef, 0x072, 0x02d, 0x002, - 0x000, 0x003, 0x02f, 0x073, 0x1fa, 0x1e7, 0x06e, 0x02b, - 0x007, 0x001, 0x005, 0x02c, 0x06d, 0x1ec, 0x1f9, 0x0ee, - 0x030, 0x024, 0x02a, 0x025, 0x033, 0x0ec, 0x1f2, 0x3f8, - 0x1e4, 0x0ed, 0x06a, 0x070, 0x069, 0x074, 0x0f1, 0x3fa, - 0x7ff, 0x3f9, 0x1f6, 0x1ed, 0x1f8, 0x1e9, 0x1f5, 0x3fb, - 0x7fc, -}; - -static const uint8_t bits6[81] = { - 11, 10, 9, 9, 9, 9, 9, 10, 11, 10, 9, 8, 7, 7, 7, 8, - 9, 10, 9, 8, 6, 6, 6, 6, 6, 8, 9, 9, 7, 6, 4, 4, - 4, 6, 7, 9, 9, 7, 6, 4, 4, 4, 6, 7, 9, 9, 7, 6, - 4, 4, 4, 6, 7, 9, 9, 8, 6, 6, 6, 6, 6, 8, 9, 10, - 9, 8, 7, 7, 7, 7, 8, 10, 11, 10, 9, 9, 9, 9, 9, 10, - 11, -}; - -static const uint16_t codes7[64] = { - 0x000, 0x005, 0x037, 0x074, 0x0f2, 0x1eb, 0x3ed, 0x7f7, - 0x004, 0x00c, 0x035, 0x071, 0x0ec, 0x0ee, 0x1ee, 0x1f5, - 0x036, 0x034, 0x072, 0x0ea, 0x0f1, 0x1e9, 0x1f3, 0x3f5, - 0x073, 0x070, 0x0eb, 0x0f0, 0x1f1, 0x1f0, 0x3ec, 0x3fa, - 0x0f3, 0x0ed, 0x1e8, 0x1ef, 0x3ef, 0x3f1, 0x3f9, 0x7fb, - 0x1ed, 0x0ef, 0x1ea, 0x1f2, 0x3f3, 0x3f8, 0x7f9, 0x7fc, - 0x3ee, 0x1ec, 0x1f4, 0x3f4, 0x3f7, 0x7f8, 0xffd, 0xffe, - 0x7f6, 0x3f0, 0x3f2, 0x3f6, 0x7fa, 0x7fd, 0xffc, 0xfff, -}; - -static const uint8_t bits7[64] = { - 1, 3, 6, 7, 8, 9, 10, 11, 3, 4, 6, 7, 8, 8, 9, 9, - 6, 6, 7, 8, 8, 9, 9, 10, 7, 7, 8, 8, 9, 9, 10, 10, - 8, 8, 9, 9, 10, 10, 10, 11, 9, 8, 9, 9, 10, 10, 11, 11, - 10, 9, 9, 10, 10, 11, 12, 12, 11, 10, 10, 10, 11, 11, 12, 12, -}; - -static const uint16_t codes8[64] = { - 0x00e, 0x005, 0x010, 0x030, 0x06f, 0x0f1, 0x1fa, 0x3fe, - 0x003, 0x000, 0x004, 0x012, 0x02c, 0x06a, 0x075, 0x0f8, - 0x00f, 0x002, 0x006, 0x014, 0x02e, 0x069, 0x072, 0x0f5, - 0x02f, 0x011, 0x013, 0x02a, 0x032, 0x06c, 0x0ec, 0x0fa, - 0x071, 0x02b, 0x02d, 0x031, 0x06d, 0x070, 0x0f2, 0x1f9, - 0x0ef, 0x068, 0x033, 0x06b, 0x06e, 0x0ee, 0x0f9, 0x3fc, - 0x1f8, 0x074, 0x073, 0x0ed, 0x0f0, 0x0f6, 0x1f6, 0x1fd, - 0x3fd, 0x0f3, 0x0f4, 0x0f7, 0x1f7, 0x1fb, 0x1fc, 0x3ff, -}; - -static const uint8_t bits8[64] = { - 5, 4, 5, 6, 7, 8, 9, 10, 4, 3, 4, 5, 6, 7, 7, 8, - 5, 4, 4, 5, 6, 7, 7, 8, 6, 5, 5, 6, 6, 7, 8, 8, - 7, 6, 6, 6, 7, 7, 8, 9, 8, 7, 6, 7, 7, 8, 8, 10, - 9, 7, 7, 8, 8, 8, 9, 9, 10, 8, 8, 8, 9, 9, 9, 10, -}; - -static const uint16_t codes9[169] = { - 0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, - 0x07cd, 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec, 0x0004, 0x000c, 0x0035, - 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3, 0x03e0, 0x07d8, - 0x0fcf, 0x0fd5, 0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, - 0x03cf, 0x03dd, 0x03db, 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4, 0x00e6, - 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca, - 0x07de, 0x0fd8, 0x0fea, 0x1fdb, 0x01df, 0x00eb, 0x01dc, 0x01e6, - 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc, 0x0fcd, 0x0fe2, 0x0fe7, - 0x1fe1, 0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, - 0x0fd2, 0x07e0, 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9, 0x07c4, 0x01e5, - 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3, 0x0fe9, - 0x1fe6, 0x1ff3, 0x1ff7, 0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, - 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9, 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6, - 0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, - 0x1fd8, 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2, 0x07e1, 0x03df, 0x07c9, - 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb, 0x1fef, 0x3ff3, - 0x3ff4, 0x3ff5, 0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, - 0x1fe0, 0x1fe8, 0x1ff0, 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc, 0x0fe8, - 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5, - 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe, 0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, - 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa, 0x3ff7, 0x3ffc, 0x3ffd, - 0x7fff, -}; - -static const uint8_t bits9[169] = { - 1, 3, 6, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 3, 4, 6, - 7, 8, 8, 9, 10, 10, 10, 11, 12, 12, 6, 6, 7, 8, 8, 9, - 10, 10, 10, 11, 12, 12, 12, 8, 7, 8, 9, 9, 10, 10, 11, 11, - 11, 12, 12, 13, 9, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, - 13, 10, 9, 9, 10, 11, 11, 11, 12, 11, 12, 12, 13, 13, 11, 9, - 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 11, 10, 10, 11, 11, - 12, 12, 13, 13, 13, 13, 13, 13, 11, 10, 10, 11, 11, 11, 12, 12, - 13, 13, 14, 13, 14, 11, 10, 11, 11, 12, 12, 12, 12, 13, 13, 14, - 14, 14, 12, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 12, - 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15, 13, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 14, 15, -}; - -static const uint16_t codes10[169] = { - 0x022, 0x008, 0x01d, 0x026, 0x05f, 0x0d3, 0x1cf, 0x3d0, - 0x3d7, 0x3ed, 0x7f0, 0x7f6, 0xffd, 0x007, 0x000, 0x001, - 0x009, 0x020, 0x054, 0x060, 0x0d5, 0x0dc, 0x1d4, 0x3cd, - 0x3de, 0x7e7, 0x01c, 0x002, 0x006, 0x00c, 0x01e, 0x028, - 0x05b, 0x0cd, 0x0d9, 0x1ce, 0x1dc, 0x3d9, 0x3f1, 0x025, - 0x00b, 0x00a, 0x00d, 0x024, 0x057, 0x061, 0x0cc, 0x0dd, - 0x1cc, 0x1de, 0x3d3, 0x3e7, 0x05d, 0x021, 0x01f, 0x023, - 0x027, 0x059, 0x064, 0x0d8, 0x0df, 0x1d2, 0x1e2, 0x3dd, - 0x3ee, 0x0d1, 0x055, 0x029, 0x056, 0x058, 0x062, 0x0ce, - 0x0e0, 0x0e2, 0x1da, 0x3d4, 0x3e3, 0x7eb, 0x1c9, 0x05e, - 0x05a, 0x05c, 0x063, 0x0ca, 0x0da, 0x1c7, 0x1ca, 0x1e0, - 0x3db, 0x3e8, 0x7ec, 0x1e3, 0x0d2, 0x0cb, 0x0d0, 0x0d7, - 0x0db, 0x1c6, 0x1d5, 0x1d8, 0x3ca, 0x3da, 0x7ea, 0x7f1, - 0x1e1, 0x0d4, 0x0cf, 0x0d6, 0x0de, 0x0e1, 0x1d0, 0x1d6, - 0x3d1, 0x3d5, 0x3f2, 0x7ee, 0x7fb, 0x3e9, 0x1cd, 0x1c8, - 0x1cb, 0x1d1, 0x1d7, 0x1df, 0x3cf, 0x3e0, 0x3ef, 0x7e6, - 0x7f8, 0xffa, 0x3eb, 0x1dd, 0x1d3, 0x1d9, 0x1db, 0x3d2, - 0x3cc, 0x3dc, 0x3ea, 0x7ed, 0x7f3, 0x7f9, 0xff9, 0x7f2, - 0x3ce, 0x1e4, 0x3cb, 0x3d8, 0x3d6, 0x3e2, 0x3e5, 0x7e8, - 0x7f4, 0x7f5, 0x7f7, 0xffb, 0x7fa, 0x3ec, 0x3df, 0x3e1, - 0x3e4, 0x3e6, 0x3f0, 0x7e9, 0x7ef, 0xff8, 0xffe, 0xffc, - 0xfff, -}; - -static const uint8_t bits10[169] = { - 6, 5, 6, 6, 7, 8, 9, 10, 10, 10, 11, 11, 12, 5, 4, 4, - 5, 6, 7, 7, 8, 8, 9, 10, 10, 11, 6, 4, 5, 5, 6, 6, - 7, 8, 8, 9, 9, 10, 10, 6, 5, 5, 5, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 7, 6, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, - 10, 8, 7, 6, 7, 7, 7, 8, 8, 8, 9, 10, 10, 11, 9, 7, - 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 9, 8, 8, 8, 8, - 8, 9, 9, 9, 10, 10, 11, 11, 9, 8, 8, 8, 8, 8, 9, 9, - 10, 10, 10, 11, 11, 10, 9, 9, 9, 9, 9, 9, 10, 10, 10, 11, - 11, 12, 10, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 11, - 10, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 11, 10, 10, 10, - 10, 10, 10, 11, 11, 12, 12, 12, 12, -}; - -static const uint16_t codes11[289] = { - 0x000, 0x006, 0x019, 0x03d, 0x09c, 0x0c6, 0x1a7, 0x390, - 0x3c2, 0x3df, 0x7e6, 0x7f3, 0xffb, 0x7ec, 0xffa, 0xffe, - 0x38e, 0x005, 0x001, 0x008, 0x014, 0x037, 0x042, 0x092, - 0x0af, 0x191, 0x1a5, 0x1b5, 0x39e, 0x3c0, 0x3a2, 0x3cd, - 0x7d6, 0x0ae, 0x017, 0x007, 0x009, 0x018, 0x039, 0x040, - 0x08e, 0x0a3, 0x0b8, 0x199, 0x1ac, 0x1c1, 0x3b1, 0x396, - 0x3be, 0x3ca, 0x09d, 0x03c, 0x015, 0x016, 0x01a, 0x03b, - 0x044, 0x091, 0x0a5, 0x0be, 0x196, 0x1ae, 0x1b9, 0x3a1, - 0x391, 0x3a5, 0x3d5, 0x094, 0x09a, 0x036, 0x038, 0x03a, - 0x041, 0x08c, 0x09b, 0x0b0, 0x0c3, 0x19e, 0x1ab, 0x1bc, - 0x39f, 0x38f, 0x3a9, 0x3cf, 0x093, 0x0bf, 0x03e, 0x03f, - 0x043, 0x045, 0x09e, 0x0a7, 0x0b9, 0x194, 0x1a2, 0x1ba, - 0x1c3, 0x3a6, 0x3a7, 0x3bb, 0x3d4, 0x09f, 0x1a0, 0x08f, - 0x08d, 0x090, 0x098, 0x0a6, 0x0b6, 0x0c4, 0x19f, 0x1af, - 0x1bf, 0x399, 0x3bf, 0x3b4, 0x3c9, 0x3e7, 0x0a8, 0x1b6, - 0x0ab, 0x0a4, 0x0aa, 0x0b2, 0x0c2, 0x0c5, 0x198, 0x1a4, - 0x1b8, 0x38c, 0x3a4, 0x3c4, 0x3c6, 0x3dd, 0x3e8, 0x0ad, - 0x3af, 0x192, 0x0bd, 0x0bc, 0x18e, 0x197, 0x19a, 0x1a3, - 0x1b1, 0x38d, 0x398, 0x3b7, 0x3d3, 0x3d1, 0x3db, 0x7dd, - 0x0b4, 0x3de, 0x1a9, 0x19b, 0x19c, 0x1a1, 0x1aa, 0x1ad, - 0x1b3, 0x38b, 0x3b2, 0x3b8, 0x3ce, 0x3e1, 0x3e0, 0x7d2, - 0x7e5, 0x0b7, 0x7e3, 0x1bb, 0x1a8, 0x1a6, 0x1b0, 0x1b2, - 0x1b7, 0x39b, 0x39a, 0x3ba, 0x3b5, 0x3d6, 0x7d7, 0x3e4, - 0x7d8, 0x7ea, 0x0ba, 0x7e8, 0x3a0, 0x1bd, 0x1b4, 0x38a, - 0x1c4, 0x392, 0x3aa, 0x3b0, 0x3bc, 0x3d7, 0x7d4, 0x7dc, - 0x7db, 0x7d5, 0x7f0, 0x0c1, 0x7fb, 0x3c8, 0x3a3, 0x395, - 0x39d, 0x3ac, 0x3ae, 0x3c5, 0x3d8, 0x3e2, 0x3e6, 0x7e4, - 0x7e7, 0x7e0, 0x7e9, 0x7f7, 0x190, 0x7f2, 0x393, 0x1be, - 0x1c0, 0x394, 0x397, 0x3ad, 0x3c3, 0x3c1, 0x3d2, 0x7da, - 0x7d9, 0x7df, 0x7eb, 0x7f4, 0x7fa, 0x195, 0x7f8, 0x3bd, - 0x39c, 0x3ab, 0x3a8, 0x3b3, 0x3b9, 0x3d0, 0x3e3, 0x3e5, - 0x7e2, 0x7de, 0x7ed, 0x7f1, 0x7f9, 0x7fc, 0x193, 0xffd, - 0x3dc, 0x3b6, 0x3c7, 0x3cc, 0x3cb, 0x3d9, 0x3da, 0x7d3, - 0x7e1, 0x7ee, 0x7ef, 0x7f5, 0x7f6, 0xffc, 0xfff, 0x19d, - 0x1c2, 0x0b5, 0x0a1, 0x096, 0x097, 0x095, 0x099, 0x0a0, - 0x0a2, 0x0ac, 0x0a9, 0x0b1, 0x0b3, 0x0bb, 0x0c0, 0x18f, - 0x004, -}; - -static const uint8_t bits11[289] = { - 4, 5, 6, 7, 8, 8, 9, 10, 10, 10, 11, 11, 12, 11, 12, 12, - 10, 5, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, - 11, 8, 6, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, - 10, 10, 8, 7, 6, 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, - 10, 10, 10, 8, 8, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, - 10, 10, 10, 10, 8, 8, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, - 9, 10, 10, 10, 10, 8, 9, 8, 8, 8, 8, 8, 8, 8, 9, 9, - 9, 10, 10, 10, 10, 10, 8, 9, 8, 8, 8, 8, 8, 8, 9, 9, - 9, 10, 10, 10, 10, 10, 10, 8, 10, 9, 8, 8, 9, 9, 9, 9, - 9, 10, 10, 10, 10, 10, 10, 11, 8, 10, 9, 9, 9, 9, 9, 9, - 9, 10, 10, 10, 10, 10, 10, 11, 11, 8, 11, 9, 9, 9, 9, 9, - 9, 10, 10, 10, 10, 10, 11, 10, 11, 11, 8, 11, 10, 9, 9, 10, - 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 8, 11, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 9, 11, 10, 9, - 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 9, 11, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 9, 12, - 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 9, - 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, - 5, -}; - -const uint16_t * const ff_aac_spectral_codes[11] = { - codes1, codes2, codes3, codes4, codes5, codes6, codes7, codes8, - codes9, codes10, codes11, -}; - -const uint8_t * const ff_aac_spectral_bits[11] = { - bits1, bits2, bits3, bits4, bits5, bits6, bits7, bits8, - bits9, bits10, bits11, -}; - -const uint16_t ff_aac_spectral_sizes[11] = { - 81, 81, 81, 81, 81, 81, 64, 64, 169, 169, 289, -}; - -/* NOTE: - * 64.0f is a special value indicating the existence of an escape code in the - * bitstream. - */ -static const DECLARE_ALIGNED(16, float, codebook_vector0)[324] = { - -1.0000000, -1.0000000, -1.0000000, -1.0000000, - -1.0000000, -1.0000000, -1.0000000, 0.0000000, - -1.0000000, -1.0000000, -1.0000000, 1.0000000, - -1.0000000, -1.0000000, 0.0000000, -1.0000000, - -1.0000000, -1.0000000, 0.0000000, 0.0000000, - -1.0000000, -1.0000000, 0.0000000, 1.0000000, - -1.0000000, -1.0000000, 1.0000000, -1.0000000, - -1.0000000, -1.0000000, 1.0000000, 0.0000000, - -1.0000000, -1.0000000, 1.0000000, 1.0000000, - -1.0000000, 0.0000000, -1.0000000, -1.0000000, - -1.0000000, 0.0000000, -1.0000000, 0.0000000, - -1.0000000, 0.0000000, -1.0000000, 1.0000000, - -1.0000000, 0.0000000, 0.0000000, -1.0000000, - -1.0000000, 0.0000000, 0.0000000, 0.0000000, - -1.0000000, 0.0000000, 0.0000000, 1.0000000, - -1.0000000, 0.0000000, 1.0000000, -1.0000000, - -1.0000000, 0.0000000, 1.0000000, 0.0000000, - -1.0000000, 0.0000000, 1.0000000, 1.0000000, - -1.0000000, 1.0000000, -1.0000000, -1.0000000, - -1.0000000, 1.0000000, -1.0000000, 0.0000000, - -1.0000000, 1.0000000, -1.0000000, 1.0000000, - -1.0000000, 1.0000000, 0.0000000, -1.0000000, - -1.0000000, 1.0000000, 0.0000000, 0.0000000, - -1.0000000, 1.0000000, 0.0000000, 1.0000000, - -1.0000000, 1.0000000, 1.0000000, -1.0000000, - -1.0000000, 1.0000000, 1.0000000, 0.0000000, - -1.0000000, 1.0000000, 1.0000000, 1.0000000, - 0.0000000, -1.0000000, -1.0000000, -1.0000000, - 0.0000000, -1.0000000, -1.0000000, 0.0000000, - 0.0000000, -1.0000000, -1.0000000, 1.0000000, - 0.0000000, -1.0000000, 0.0000000, -1.0000000, - 0.0000000, -1.0000000, 0.0000000, 0.0000000, - 0.0000000, -1.0000000, 0.0000000, 1.0000000, - 0.0000000, -1.0000000, 1.0000000, -1.0000000, - 0.0000000, -1.0000000, 1.0000000, 0.0000000, - 0.0000000, -1.0000000, 1.0000000, 1.0000000, - 0.0000000, 0.0000000, -1.0000000, -1.0000000, - 0.0000000, 0.0000000, -1.0000000, 0.0000000, - 0.0000000, 0.0000000, -1.0000000, 1.0000000, - 0.0000000, 0.0000000, 0.0000000, -1.0000000, - 0.0000000, 0.0000000, 0.0000000, 0.0000000, - 0.0000000, 0.0000000, 0.0000000, 1.0000000, - 0.0000000, 0.0000000, 1.0000000, -1.0000000, - 0.0000000, 0.0000000, 1.0000000, 0.0000000, - 0.0000000, 0.0000000, 1.0000000, 1.0000000, - 0.0000000, 1.0000000, -1.0000000, -1.0000000, - 0.0000000, 1.0000000, -1.0000000, 0.0000000, - 0.0000000, 1.0000000, -1.0000000, 1.0000000, - 0.0000000, 1.0000000, 0.0000000, -1.0000000, - 0.0000000, 1.0000000, 0.0000000, 0.0000000, - 0.0000000, 1.0000000, 0.0000000, 1.0000000, - 0.0000000, 1.0000000, 1.0000000, -1.0000000, - 0.0000000, 1.0000000, 1.0000000, 0.0000000, - 0.0000000, 1.0000000, 1.0000000, 1.0000000, - 1.0000000, -1.0000000, -1.0000000, -1.0000000, - 1.0000000, -1.0000000, -1.0000000, 0.0000000, - 1.0000000, -1.0000000, -1.0000000, 1.0000000, - 1.0000000, -1.0000000, 0.0000000, -1.0000000, - 1.0000000, -1.0000000, 0.0000000, 0.0000000, - 1.0000000, -1.0000000, 0.0000000, 1.0000000, - 1.0000000, -1.0000000, 1.0000000, -1.0000000, - 1.0000000, -1.0000000, 1.0000000, 0.0000000, - 1.0000000, -1.0000000, 1.0000000, 1.0000000, - 1.0000000, 0.0000000, -1.0000000, -1.0000000, - 1.0000000, 0.0000000, -1.0000000, 0.0000000, - 1.0000000, 0.0000000, -1.0000000, 1.0000000, - 1.0000000, 0.0000000, 0.0000000, -1.0000000, - 1.0000000, 0.0000000, 0.0000000, 0.0000000, - 1.0000000, 0.0000000, 0.0000000, 1.0000000, - 1.0000000, 0.0000000, 1.0000000, -1.0000000, - 1.0000000, 0.0000000, 1.0000000, 0.0000000, - 1.0000000, 0.0000000, 1.0000000, 1.0000000, - 1.0000000, 1.0000000, -1.0000000, -1.0000000, - 1.0000000, 1.0000000, -1.0000000, 0.0000000, - 1.0000000, 1.0000000, -1.0000000, 1.0000000, - 1.0000000, 1.0000000, 0.0000000, -1.0000000, - 1.0000000, 1.0000000, 0.0000000, 0.0000000, - 1.0000000, 1.0000000, 0.0000000, 1.0000000, - 1.0000000, 1.0000000, 1.0000000, -1.0000000, - 1.0000000, 1.0000000, 1.0000000, 0.0000000, - 1.0000000, 1.0000000, 1.0000000, 1.0000000, -}; - -static const DECLARE_ALIGNED(16, float, codebook_vector2)[324] = { - 0.0000000, 0.0000000, 0.0000000, 0.0000000, - 0.0000000, 0.0000000, 0.0000000, 1.0000000, - 0.0000000, 0.0000000, 0.0000000, 2.5198421, - 0.0000000, 0.0000000, 1.0000000, 0.0000000, - 0.0000000, 0.0000000, 1.0000000, 1.0000000, - 0.0000000, 0.0000000, 1.0000000, 2.5198421, - 0.0000000, 0.0000000, 2.5198421, 0.0000000, - 0.0000000, 0.0000000, 2.5198421, 1.0000000, - 0.0000000, 0.0000000, 2.5198421, 2.5198421, - 0.0000000, 1.0000000, 0.0000000, 0.0000000, - 0.0000000, 1.0000000, 0.0000000, 1.0000000, - 0.0000000, 1.0000000, 0.0000000, 2.5198421, - 0.0000000, 1.0000000, 1.0000000, 0.0000000, - 0.0000000, 1.0000000, 1.0000000, 1.0000000, - 0.0000000, 1.0000000, 1.0000000, 2.5198421, - 0.0000000, 1.0000000, 2.5198421, 0.0000000, - 0.0000000, 1.0000000, 2.5198421, 1.0000000, - 0.0000000, 1.0000000, 2.5198421, 2.5198421, - 0.0000000, 2.5198421, 0.0000000, 0.0000000, - 0.0000000, 2.5198421, 0.0000000, 1.0000000, - 0.0000000, 2.5198421, 0.0000000, 2.5198421, - 0.0000000, 2.5198421, 1.0000000, 0.0000000, - 0.0000000, 2.5198421, 1.0000000, 1.0000000, - 0.0000000, 2.5198421, 1.0000000, 2.5198421, - 0.0000000, 2.5198421, 2.5198421, 0.0000000, - 0.0000000, 2.5198421, 2.5198421, 1.0000000, - 0.0000000, 2.5198421, 2.5198421, 2.5198421, - 1.0000000, 0.0000000, 0.0000000, 0.0000000, - 1.0000000, 0.0000000, 0.0000000, 1.0000000, - 1.0000000, 0.0000000, 0.0000000, 2.5198421, - 1.0000000, 0.0000000, 1.0000000, 0.0000000, - 1.0000000, 0.0000000, 1.0000000, 1.0000000, - 1.0000000, 0.0000000, 1.0000000, 2.5198421, - 1.0000000, 0.0000000, 2.5198421, 0.0000000, - 1.0000000, 0.0000000, 2.5198421, 1.0000000, - 1.0000000, 0.0000000, 2.5198421, 2.5198421, - 1.0000000, 1.0000000, 0.0000000, 0.0000000, - 1.0000000, 1.0000000, 0.0000000, 1.0000000, - 1.0000000, 1.0000000, 0.0000000, 2.5198421, - 1.0000000, 1.0000000, 1.0000000, 0.0000000, - 1.0000000, 1.0000000, 1.0000000, 1.0000000, - 1.0000000, 1.0000000, 1.0000000, 2.5198421, - 1.0000000, 1.0000000, 2.5198421, 0.0000000, - 1.0000000, 1.0000000, 2.5198421, 1.0000000, - 1.0000000, 1.0000000, 2.5198421, 2.5198421, - 1.0000000, 2.5198421, 0.0000000, 0.0000000, - 1.0000000, 2.5198421, 0.0000000, 1.0000000, - 1.0000000, 2.5198421, 0.0000000, 2.5198421, - 1.0000000, 2.5198421, 1.0000000, 0.0000000, - 1.0000000, 2.5198421, 1.0000000, 1.0000000, - 1.0000000, 2.5198421, 1.0000000, 2.5198421, - 1.0000000, 2.5198421, 2.5198421, 0.0000000, - 1.0000000, 2.5198421, 2.5198421, 1.0000000, - 1.0000000, 2.5198421, 2.5198421, 2.5198421, - 2.5198421, 0.0000000, 0.0000000, 0.0000000, - 2.5198421, 0.0000000, 0.0000000, 1.0000000, - 2.5198421, 0.0000000, 0.0000000, 2.5198421, - 2.5198421, 0.0000000, 1.0000000, 0.0000000, - 2.5198421, 0.0000000, 1.0000000, 1.0000000, - 2.5198421, 0.0000000, 1.0000000, 2.5198421, - 2.5198421, 0.0000000, 2.5198421, 0.0000000, - 2.5198421, 0.0000000, 2.5198421, 1.0000000, - 2.5198421, 0.0000000, 2.5198421, 2.5198421, - 2.5198421, 1.0000000, 0.0000000, 0.0000000, - 2.5198421, 1.0000000, 0.0000000, 1.0000000, - 2.5198421, 1.0000000, 0.0000000, 2.5198421, - 2.5198421, 1.0000000, 1.0000000, 0.0000000, - 2.5198421, 1.0000000, 1.0000000, 1.0000000, - 2.5198421, 1.0000000, 1.0000000, 2.5198421, - 2.5198421, 1.0000000, 2.5198421, 0.0000000, - 2.5198421, 1.0000000, 2.5198421, 1.0000000, - 2.5198421, 1.0000000, 2.5198421, 2.5198421, - 2.5198421, 2.5198421, 0.0000000, 0.0000000, - 2.5198421, 2.5198421, 0.0000000, 1.0000000, - 2.5198421, 2.5198421, 0.0000000, 2.5198421, - 2.5198421, 2.5198421, 1.0000000, 0.0000000, - 2.5198421, 2.5198421, 1.0000000, 1.0000000, - 2.5198421, 2.5198421, 1.0000000, 2.5198421, - 2.5198421, 2.5198421, 2.5198421, 0.0000000, - 2.5198421, 2.5198421, 2.5198421, 1.0000000, - 2.5198421, 2.5198421, 2.5198421, 2.5198421, -}; - -static const DECLARE_ALIGNED(16, float, codebook_vector4)[162] = { - -6.3496042, -6.3496042, -6.3496042, -4.3267487, - -6.3496042, -2.5198421, -6.3496042, -1.0000000, - -6.3496042, 0.0000000, -6.3496042, 1.0000000, - -6.3496042, 2.5198421, -6.3496042, 4.3267487, - -6.3496042, 6.3496042, -4.3267487, -6.3496042, - -4.3267487, -4.3267487, -4.3267487, -2.5198421, - -4.3267487, -1.0000000, -4.3267487, 0.0000000, - -4.3267487, 1.0000000, -4.3267487, 2.5198421, - -4.3267487, 4.3267487, -4.3267487, 6.3496042, - -2.5198421, -6.3496042, -2.5198421, -4.3267487, - -2.5198421, -2.5198421, -2.5198421, -1.0000000, - -2.5198421, 0.0000000, -2.5198421, 1.0000000, - -2.5198421, 2.5198421, -2.5198421, 4.3267487, - -2.5198421, 6.3496042, -1.0000000, -6.3496042, - -1.0000000, -4.3267487, -1.0000000, -2.5198421, - -1.0000000, -1.0000000, -1.0000000, 0.0000000, - -1.0000000, 1.0000000, -1.0000000, 2.5198421, - -1.0000000, 4.3267487, -1.0000000, 6.3496042, - 0.0000000, -6.3496042, 0.0000000, -4.3267487, - 0.0000000, -2.5198421, 0.0000000, -1.0000000, - 0.0000000, 0.0000000, 0.0000000, 1.0000000, - 0.0000000, 2.5198421, 0.0000000, 4.3267487, - 0.0000000, 6.3496042, 1.0000000, -6.3496042, - 1.0000000, -4.3267487, 1.0000000, -2.5198421, - 1.0000000, -1.0000000, 1.0000000, 0.0000000, - 1.0000000, 1.0000000, 1.0000000, 2.5198421, - 1.0000000, 4.3267487, 1.0000000, 6.3496042, - 2.5198421, -6.3496042, 2.5198421, -4.3267487, - 2.5198421, -2.5198421, 2.5198421, -1.0000000, - 2.5198421, 0.0000000, 2.5198421, 1.0000000, - 2.5198421, 2.5198421, 2.5198421, 4.3267487, - 2.5198421, 6.3496042, 4.3267487, -6.3496042, - 4.3267487, -4.3267487, 4.3267487, -2.5198421, - 4.3267487, -1.0000000, 4.3267487, 0.0000000, - 4.3267487, 1.0000000, 4.3267487, 2.5198421, - 4.3267487, 4.3267487, 4.3267487, 6.3496042, - 6.3496042, -6.3496042, 6.3496042, -4.3267487, - 6.3496042, -2.5198421, 6.3496042, -1.0000000, - 6.3496042, 0.0000000, 6.3496042, 1.0000000, - 6.3496042, 2.5198421, 6.3496042, 4.3267487, - 6.3496042, 6.3496042, -}; - -static const DECLARE_ALIGNED(16, float, codebook_vector6)[128] = { - 0.0000000, 0.0000000, 0.0000000, 1.0000000, - 0.0000000, 2.5198421, 0.0000000, 4.3267487, - 0.0000000, 6.3496042, 0.0000000, 8.5498797, - 0.0000000, 10.9027236, 0.0000000, 13.3905183, - 1.0000000, 0.0000000, 1.0000000, 1.0000000, - 1.0000000, 2.5198421, 1.0000000, 4.3267487, - 1.0000000, 6.3496042, 1.0000000, 8.5498797, - 1.0000000, 10.9027236, 1.0000000, 13.3905183, - 2.5198421, 0.0000000, 2.5198421, 1.0000000, - 2.5198421, 2.5198421, 2.5198421, 4.3267487, - 2.5198421, 6.3496042, 2.5198421, 8.5498797, - 2.5198421, 10.9027236, 2.5198421, 13.3905183, - 4.3267487, 0.0000000, 4.3267487, 1.0000000, - 4.3267487, 2.5198421, 4.3267487, 4.3267487, - 4.3267487, 6.3496042, 4.3267487, 8.5498797, - 4.3267487, 10.9027236, 4.3267487, 13.3905183, - 6.3496042, 0.0000000, 6.3496042, 1.0000000, - 6.3496042, 2.5198421, 6.3496042, 4.3267487, - 6.3496042, 6.3496042, 6.3496042, 8.5498797, - 6.3496042, 10.9027236, 6.3496042, 13.3905183, - 8.5498797, 0.0000000, 8.5498797, 1.0000000, - 8.5498797, 2.5198421, 8.5498797, 4.3267487, - 8.5498797, 6.3496042, 8.5498797, 8.5498797, - 8.5498797, 10.9027236, 8.5498797, 13.3905183, - 10.9027236, 0.0000000, 10.9027236, 1.0000000, - 10.9027236, 2.5198421, 10.9027236, 4.3267487, - 10.9027236, 6.3496042, 10.9027236, 8.5498797, - 10.9027236, 10.9027236, 10.9027236, 13.3905183, - 13.3905183, 0.0000000, 13.3905183, 1.0000000, - 13.3905183, 2.5198421, 13.3905183, 4.3267487, - 13.3905183, 6.3496042, 13.3905183, 8.5498797, - 13.3905183, 10.9027236, 13.3905183, 13.3905183, -}; - -static const DECLARE_ALIGNED(16, float, codebook_vector8)[338] = { - 0.0000000, 0.0000000, 0.0000000, 1.0000000, - 0.0000000, 2.5198421, 0.0000000, 4.3267487, - 0.0000000, 6.3496042, 0.0000000, 8.5498797, - 0.0000000, 10.9027236, 0.0000000, 13.3905183, - 0.0000000, 16.0000000, 0.0000000, 18.7207544, - 0.0000000, 21.5443469, 0.0000000, 24.4637810, - 0.0000000, 27.4731418, 1.0000000, 0.0000000, - 1.0000000, 1.0000000, 1.0000000, 2.5198421, - 1.0000000, 4.3267487, 1.0000000, 6.3496042, - 1.0000000, 8.5498797, 1.0000000, 10.9027236, - 1.0000000, 13.3905183, 1.0000000, 16.0000000, - 1.0000000, 18.7207544, 1.0000000, 21.5443469, - 1.0000000, 24.4637810, 1.0000000, 27.4731418, - 2.5198421, 0.0000000, 2.5198421, 1.0000000, - 2.5198421, 2.5198421, 2.5198421, 4.3267487, - 2.5198421, 6.3496042, 2.5198421, 8.5498797, - 2.5198421, 10.9027236, 2.5198421, 13.3905183, - 2.5198421, 16.0000000, 2.5198421, 18.7207544, - 2.5198421, 21.5443469, 2.5198421, 24.4637810, - 2.5198421, 27.4731418, 4.3267487, 0.0000000, - 4.3267487, 1.0000000, 4.3267487, 2.5198421, - 4.3267487, 4.3267487, 4.3267487, 6.3496042, - 4.3267487, 8.5498797, 4.3267487, 10.9027236, - 4.3267487, 13.3905183, 4.3267487, 16.0000000, - 4.3267487, 18.7207544, 4.3267487, 21.5443469, - 4.3267487, 24.4637810, 4.3267487, 27.4731418, - 6.3496042, 0.0000000, 6.3496042, 1.0000000, - 6.3496042, 2.5198421, 6.3496042, 4.3267487, - 6.3496042, 6.3496042, 6.3496042, 8.5498797, - 6.3496042, 10.9027236, 6.3496042, 13.3905183, - 6.3496042, 16.0000000, 6.3496042, 18.7207544, - 6.3496042, 21.5443469, 6.3496042, 24.4637810, - 6.3496042, 27.4731418, 8.5498797, 0.0000000, - 8.5498797, 1.0000000, 8.5498797, 2.5198421, - 8.5498797, 4.3267487, 8.5498797, 6.3496042, - 8.5498797, 8.5498797, 8.5498797, 10.9027236, - 8.5498797, 13.3905183, 8.5498797, 16.0000000, - 8.5498797, 18.7207544, 8.5498797, 21.5443469, - 8.5498797, 24.4637810, 8.5498797, 27.4731418, - 10.9027236, 0.0000000, 10.9027236, 1.0000000, - 10.9027236, 2.5198421, 10.9027236, 4.3267487, - 10.9027236, 6.3496042, 10.9027236, 8.5498797, - 10.9027236, 10.9027236, 10.9027236, 13.3905183, - 10.9027236, 16.0000000, 10.9027236, 18.7207544, - 10.9027236, 21.5443469, 10.9027236, 24.4637810, - 10.9027236, 27.4731418, 13.3905183, 0.0000000, - 13.3905183, 1.0000000, 13.3905183, 2.5198421, - 13.3905183, 4.3267487, 13.3905183, 6.3496042, - 13.3905183, 8.5498797, 13.3905183, 10.9027236, - 13.3905183, 13.3905183, 13.3905183, 16.0000000, - 13.3905183, 18.7207544, 13.3905183, 21.5443469, - 13.3905183, 24.4637810, 13.3905183, 27.4731418, - 16.0000000, 0.0000000, 16.0000000, 1.0000000, - 16.0000000, 2.5198421, 16.0000000, 4.3267487, - 16.0000000, 6.3496042, 16.0000000, 8.5498797, - 16.0000000, 10.9027236, 16.0000000, 13.3905183, - 16.0000000, 16.0000000, 16.0000000, 18.7207544, - 16.0000000, 21.5443469, 16.0000000, 24.4637810, - 16.0000000, 27.4731418, 18.7207544, 0.0000000, - 18.7207544, 1.0000000, 18.7207544, 2.5198421, - 18.7207544, 4.3267487, 18.7207544, 6.3496042, - 18.7207544, 8.5498797, 18.7207544, 10.9027236, - 18.7207544, 13.3905183, 18.7207544, 16.0000000, - 18.7207544, 18.7207544, 18.7207544, 21.5443469, - 18.7207544, 24.4637810, 18.7207544, 27.4731418, - 21.5443469, 0.0000000, 21.5443469, 1.0000000, - 21.5443469, 2.5198421, 21.5443469, 4.3267487, - 21.5443469, 6.3496042, 21.5443469, 8.5498797, - 21.5443469, 10.9027236, 21.5443469, 13.3905183, - 21.5443469, 16.0000000, 21.5443469, 18.7207544, - 21.5443469, 21.5443469, 21.5443469, 24.4637810, - 21.5443469, 27.4731418, 24.4637810, 0.0000000, - 24.4637810, 1.0000000, 24.4637810, 2.5198421, - 24.4637810, 4.3267487, 24.4637810, 6.3496042, - 24.4637810, 8.5498797, 24.4637810, 10.9027236, - 24.4637810, 13.3905183, 24.4637810, 16.0000000, - 24.4637810, 18.7207544, 24.4637810, 21.5443469, - 24.4637810, 24.4637810, 24.4637810, 27.4731418, - 27.4731418, 0.0000000, 27.4731418, 1.0000000, - 27.4731418, 2.5198421, 27.4731418, 4.3267487, - 27.4731418, 6.3496042, 27.4731418, 8.5498797, - 27.4731418, 10.9027236, 27.4731418, 13.3905183, - 27.4731418, 16.0000000, 27.4731418, 18.7207544, - 27.4731418, 21.5443469, 27.4731418, 24.4637810, - 27.4731418, 27.4731418, -}; - -static const DECLARE_ALIGNED(16, float, codebook_vector10)[578] = { - 0.0000000, 0.0000000, 0.0000000, 1.0000000, - 0.0000000, 2.5198421, 0.0000000, 4.3267487, - 0.0000000, 6.3496042, 0.0000000, 8.5498797, - 0.0000000, 10.9027236, 0.0000000, 13.3905183, - 0.0000000, 16.0000000, 0.0000000, 18.7207544, - 0.0000000, 21.5443469, 0.0000000, 24.4637810, - 0.0000000, 27.4731418, 0.0000000, 30.5673509, - 0.0000000, 33.7419917, 0.0000000, 36.9931811, - 0.0000000, 64.0f, 1.0000000, 0.0000000, - 1.0000000, 1.0000000, 1.0000000, 2.5198421, - 1.0000000, 4.3267487, 1.0000000, 6.3496042, - 1.0000000, 8.5498797, 1.0000000, 10.9027236, - 1.0000000, 13.3905183, 1.0000000, 16.0000000, - 1.0000000, 18.7207544, 1.0000000, 21.5443469, - 1.0000000, 24.4637810, 1.0000000, 27.4731418, - 1.0000000, 30.5673509, 1.0000000, 33.7419917, - 1.0000000, 36.9931811, 1.0000000, 64.0f, - 2.5198421, 0.0000000, 2.5198421, 1.0000000, - 2.5198421, 2.5198421, 2.5198421, 4.3267487, - 2.5198421, 6.3496042, 2.5198421, 8.5498797, - 2.5198421, 10.9027236, 2.5198421, 13.3905183, - 2.5198421, 16.0000000, 2.5198421, 18.7207544, - 2.5198421, 21.5443469, 2.5198421, 24.4637810, - 2.5198421, 27.4731418, 2.5198421, 30.5673509, - 2.5198421, 33.7419917, 2.5198421, 36.9931811, - 2.5198421, 64.0f, 4.3267487, 0.0000000, - 4.3267487, 1.0000000, 4.3267487, 2.5198421, - 4.3267487, 4.3267487, 4.3267487, 6.3496042, - 4.3267487, 8.5498797, 4.3267487, 10.9027236, - 4.3267487, 13.3905183, 4.3267487, 16.0000000, - 4.3267487, 18.7207544, 4.3267487, 21.5443469, - 4.3267487, 24.4637810, 4.3267487, 27.4731418, - 4.3267487, 30.5673509, 4.3267487, 33.7419917, - 4.3267487, 36.9931811, 4.3267487, 64.0f, - 6.3496042, 0.0000000, 6.3496042, 1.0000000, - 6.3496042, 2.5198421, 6.3496042, 4.3267487, - 6.3496042, 6.3496042, 6.3496042, 8.5498797, - 6.3496042, 10.9027236, 6.3496042, 13.3905183, - 6.3496042, 16.0000000, 6.3496042, 18.7207544, - 6.3496042, 21.5443469, 6.3496042, 24.4637810, - 6.3496042, 27.4731418, 6.3496042, 30.5673509, - 6.3496042, 33.7419917, 6.3496042, 36.9931811, - 6.3496042, 64.0f, 8.5498797, 0.0000000, - 8.5498797, 1.0000000, 8.5498797, 2.5198421, - 8.5498797, 4.3267487, 8.5498797, 6.3496042, - 8.5498797, 8.5498797, 8.5498797, 10.9027236, - 8.5498797, 13.3905183, 8.5498797, 16.0000000, - 8.5498797, 18.7207544, 8.5498797, 21.5443469, - 8.5498797, 24.4637810, 8.5498797, 27.4731418, - 8.5498797, 30.5673509, 8.5498797, 33.7419917, - 8.5498797, 36.9931811, 8.5498797, 64.0f, - 10.9027236, 0.0000000, 10.9027236, 1.0000000, - 10.9027236, 2.5198421, 10.9027236, 4.3267487, - 10.9027236, 6.3496042, 10.9027236, 8.5498797, - 10.9027236, 10.9027236, 10.9027236, 13.3905183, - 10.9027236, 16.0000000, 10.9027236, 18.7207544, - 10.9027236, 21.5443469, 10.9027236, 24.4637810, - 10.9027236, 27.4731418, 10.9027236, 30.5673509, - 10.9027236, 33.7419917, 10.9027236, 36.9931811, - 10.9027236, 64.0f, 13.3905183, 0.0000000, - 13.3905183, 1.0000000, 13.3905183, 2.5198421, - 13.3905183, 4.3267487, 13.3905183, 6.3496042, - 13.3905183, 8.5498797, 13.3905183, 10.9027236, - 13.3905183, 13.3905183, 13.3905183, 16.0000000, - 13.3905183, 18.7207544, 13.3905183, 21.5443469, - 13.3905183, 24.4637810, 13.3905183, 27.4731418, - 13.3905183, 30.5673509, 13.3905183, 33.7419917, - 13.3905183, 36.9931811, 13.3905183, 64.0f, - 16.0000000, 0.0000000, 16.0000000, 1.0000000, - 16.0000000, 2.5198421, 16.0000000, 4.3267487, - 16.0000000, 6.3496042, 16.0000000, 8.5498797, - 16.0000000, 10.9027236, 16.0000000, 13.3905183, - 16.0000000, 16.0000000, 16.0000000, 18.7207544, - 16.0000000, 21.5443469, 16.0000000, 24.4637810, - 16.0000000, 27.4731418, 16.0000000, 30.5673509, - 16.0000000, 33.7419917, 16.0000000, 36.9931811, - 16.0000000, 64.0f, 18.7207544, 0.0000000, - 18.7207544, 1.0000000, 18.7207544, 2.5198421, - 18.7207544, 4.3267487, 18.7207544, 6.3496042, - 18.7207544, 8.5498797, 18.7207544, 10.9027236, - 18.7207544, 13.3905183, 18.7207544, 16.0000000, - 18.7207544, 18.7207544, 18.7207544, 21.5443469, - 18.7207544, 24.4637810, 18.7207544, 27.4731418, - 18.7207544, 30.5673509, 18.7207544, 33.7419917, - 18.7207544, 36.9931811, 18.7207544, 64.0f, - 21.5443469, 0.0000000, 21.5443469, 1.0000000, - 21.5443469, 2.5198421, 21.5443469, 4.3267487, - 21.5443469, 6.3496042, 21.5443469, 8.5498797, - 21.5443469, 10.9027236, 21.5443469, 13.3905183, - 21.5443469, 16.0000000, 21.5443469, 18.7207544, - 21.5443469, 21.5443469, 21.5443469, 24.4637810, - 21.5443469, 27.4731418, 21.5443469, 30.5673509, - 21.5443469, 33.7419917, 21.5443469, 36.9931811, - 21.5443469, 64.0f, 24.4637810, 0.0000000, - 24.4637810, 1.0000000, 24.4637810, 2.5198421, - 24.4637810, 4.3267487, 24.4637810, 6.3496042, - 24.4637810, 8.5498797, 24.4637810, 10.9027236, - 24.4637810, 13.3905183, 24.4637810, 16.0000000, - 24.4637810, 18.7207544, 24.4637810, 21.5443469, - 24.4637810, 24.4637810, 24.4637810, 27.4731418, - 24.4637810, 30.5673509, 24.4637810, 33.7419917, - 24.4637810, 36.9931811, 24.4637810, 64.0f, - 27.4731418, 0.0000000, 27.4731418, 1.0000000, - 27.4731418, 2.5198421, 27.4731418, 4.3267487, - 27.4731418, 6.3496042, 27.4731418, 8.5498797, - 27.4731418, 10.9027236, 27.4731418, 13.3905183, - 27.4731418, 16.0000000, 27.4731418, 18.7207544, - 27.4731418, 21.5443469, 27.4731418, 24.4637810, - 27.4731418, 27.4731418, 27.4731418, 30.5673509, - 27.4731418, 33.7419917, 27.4731418, 36.9931811, - 27.4731418, 64.0f, 30.5673509, 0.0000000, - 30.5673509, 1.0000000, 30.5673509, 2.5198421, - 30.5673509, 4.3267487, 30.5673509, 6.3496042, - 30.5673509, 8.5498797, 30.5673509, 10.9027236, - 30.5673509, 13.3905183, 30.5673509, 16.0000000, - 30.5673509, 18.7207544, 30.5673509, 21.5443469, - 30.5673509, 24.4637810, 30.5673509, 27.4731418, - 30.5673509, 30.5673509, 30.5673509, 33.7419917, - 30.5673509, 36.9931811, 30.5673509, 64.0f, - 33.7419917, 0.0000000, 33.7419917, 1.0000000, - 33.7419917, 2.5198421, 33.7419917, 4.3267487, - 33.7419917, 6.3496042, 33.7419917, 8.5498797, - 33.7419917, 10.9027236, 33.7419917, 13.3905183, - 33.7419917, 16.0000000, 33.7419917, 18.7207544, - 33.7419917, 21.5443469, 33.7419917, 24.4637810, - 33.7419917, 27.4731418, 33.7419917, 30.5673509, - 33.7419917, 33.7419917, 33.7419917, 36.9931811, - 33.7419917, 64.0f, 36.9931811, 0.0000000, - 36.9931811, 1.0000000, 36.9931811, 2.5198421, - 36.9931811, 4.3267487, 36.9931811, 6.3496042, - 36.9931811, 8.5498797, 36.9931811, 10.9027236, - 36.9931811, 13.3905183, 36.9931811, 16.0000000, - 36.9931811, 18.7207544, 36.9931811, 21.5443469, - 36.9931811, 24.4637810, 36.9931811, 27.4731418, - 36.9931811, 30.5673509, 36.9931811, 33.7419917, - 36.9931811, 36.9931811, 36.9931811, 64.0f, - 64.0f, 0.0000000, 64.0f, 1.0000000, - 64.0f, 2.5198421, 64.0f, 4.3267487, - 64.0f, 6.3496042, 64.0f, 8.5498797, - 64.0f, 10.9027236, 64.0f, 13.3905183, - 64.0f, 16.0000000, 64.0f, 18.7207544, - 64.0f, 21.5443469, 64.0f, 24.4637810, - 64.0f, 27.4731418, 64.0f, 30.5673509, - 64.0f, 33.7419917, 64.0f, 36.9931811, - 64.0f, 64.0f, -}; - -const float * const ff_aac_codebook_vectors[] = { - codebook_vector0, codebook_vector0, codebook_vector2, - codebook_vector2, codebook_vector4, codebook_vector4, - codebook_vector6, codebook_vector6, codebook_vector8, - codebook_vector8, codebook_vector10, -}; - -static const float codebook_vector0_vals[] = { - -1.0000000, 0.0000000, 1.0000000 -}; - -/* - * bits 0:1, 2:3, 4:5, 6:7 index into _vals array - * 8:11 number of non-zero values - * 12:15 bit mask of non-zero values - */ -static const uint16_t codebook_vector02_idx[] = { - 0x0000, 0x8140, 0x8180, 0x4110, 0xc250, 0xc290, 0x4120, 0xc260, 0xc2a0, - 0x2104, 0xa244, 0xa284, 0x6214, 0xe354, 0xe394, 0x6224, 0xe364, 0xe3a4, - 0x2108, 0xa248, 0xa288, 0x6218, 0xe358, 0xe398, 0x6228, 0xe368, 0xe3a8, - 0x1101, 0x9241, 0x9281, 0x5211, 0xd351, 0xd391, 0x5221, 0xd361, 0xd3a1, - 0x3205, 0xb345, 0xb385, 0x7315, 0xf455, 0xf495, 0x7325, 0xf465, 0xf4a5, - 0x3209, 0xb349, 0xb389, 0x7319, 0xf459, 0xf499, 0x7329, 0xf469, 0xf4a9, - 0x1102, 0x9242, 0x9282, 0x5212, 0xd352, 0xd392, 0x5222, 0xd362, 0xd3a2, - 0x3206, 0xb346, 0xb386, 0x7316, 0xf456, 0xf496, 0x7326, 0xf466, 0xf4a6, - 0x320a, 0xb34a, 0xb38a, 0x731a, 0xf45a, 0xf49a, 0x732a, 0xf46a, 0xf4aa, -}; - -static const float codebook_vector4_vals[] = { - -6.3496042, -4.3267487, - -2.5198421, -1.0000000, - 0.0000000, 1.0000000, - 2.5198421, 4.3267487, - 6.3496042, -}; - -/* - * bits 0:3, 4:7 index into _vals array - */ -static const uint16_t codebook_vector4_idx[] = { - 0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080, - 0x0001, 0x0011, 0x0021, 0x0031, 0x0041, 0x0051, 0x0061, 0x0071, 0x0081, - 0x0002, 0x0012, 0x0022, 0x0032, 0x0042, 0x0052, 0x0062, 0x0072, 0x0082, - 0x0003, 0x0013, 0x0023, 0x0033, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, - 0x0004, 0x0014, 0x0024, 0x0034, 0x0044, 0x0054, 0x0064, 0x0074, 0x0084, - 0x0005, 0x0015, 0x0025, 0x0035, 0x0045, 0x0055, 0x0065, 0x0075, 0x0085, - 0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0076, 0x0086, - 0x0007, 0x0017, 0x0027, 0x0037, 0x0047, 0x0057, 0x0067, 0x0077, 0x0087, - 0x0008, 0x0018, 0x0028, 0x0038, 0x0048, 0x0058, 0x0068, 0x0078, 0x0088, -}; - -/* - * bits 0:3, 4:7 index into _vals array - * 8:11 number of non-zero values - * 12:15 1: only second value non-zero - * 0: other cases - */ -static const uint16_t codebook_vector6_idx[] = { - 0x0000, 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, - 0x1101, 0x0211, 0x0221, 0x0231, 0x0241, 0x0251, 0x0261, 0x0271, - 0x1102, 0x0212, 0x0222, 0x0232, 0x0242, 0x0252, 0x0262, 0x0272, - 0x1103, 0x0213, 0x0223, 0x0233, 0x0243, 0x0253, 0x0263, 0x0273, - 0x1104, 0x0214, 0x0224, 0x0234, 0x0244, 0x0254, 0x0264, 0x0274, - 0x1105, 0x0215, 0x0225, 0x0235, 0x0245, 0x0255, 0x0265, 0x0275, - 0x1106, 0x0216, 0x0226, 0x0236, 0x0246, 0x0256, 0x0266, 0x0276, - 0x1107, 0x0217, 0x0227, 0x0237, 0x0247, 0x0257, 0x0267, 0x0277, -}; - -/* - * bits 0:3, 4:7 index into _vals array - * 8:11 number of non-zero values - * 12:15 1: only second value non-zero - * 0: other cases - */ -static const uint16_t codebook_vector8_idx[] = { - 0x0000, 0x0110, 0x0120, 0x0130, 0x0140, 0x0150, 0x0160, - 0x0170, 0x0180, 0x0190, 0x01a0, 0x01b0, 0x01c0, - 0x1101, 0x0211, 0x0221, 0x0231, 0x0241, 0x0251, 0x0261, - 0x0271, 0x0281, 0x0291, 0x02a1, 0x02b1, 0x02c1, - 0x1102, 0x0212, 0x0222, 0x0232, 0x0242, 0x0252, 0x0262, - 0x0272, 0x0282, 0x0292, 0x02a2, 0x02b2, 0x02c2, - 0x1103, 0x0213, 0x0223, 0x0233, 0x0243, 0x0253, 0x0263, - 0x0273, 0x0283, 0x0293, 0x02a3, 0x02b3, 0x02c3, - 0x1104, 0x0214, 0x0224, 0x0234, 0x0244, 0x0254, 0x0264, - 0x0274, 0x0284, 0x0294, 0x02a4, 0x02b4, 0x02c4, - 0x1105, 0x0215, 0x0225, 0x0235, 0x0245, 0x0255, 0x0265, - 0x0275, 0x0285, 0x0295, 0x02a5, 0x02b5, 0x02c5, - 0x1106, 0x0216, 0x0226, 0x0236, 0x0246, 0x0256, 0x0266, - 0x0276, 0x0286, 0x0296, 0x02a6, 0x02b6, 0x02c6, - 0x1107, 0x0217, 0x0227, 0x0237, 0x0247, 0x0257, 0x0267, - 0x0277, 0x0287, 0x0297, 0x02a7, 0x02b7, 0x02c7, - 0x1108, 0x0218, 0x0228, 0x0238, 0x0248, 0x0258, 0x0268, - 0x0278, 0x0288, 0x0298, 0x02a8, 0x02b8, 0x02c8, - 0x1109, 0x0219, 0x0229, 0x0239, 0x0249, 0x0259, 0x0269, - 0x0279, 0x0289, 0x0299, 0x02a9, 0x02b9, 0x02c9, - 0x110a, 0x021a, 0x022a, 0x023a, 0x024a, 0x025a, 0x026a, - 0x027a, 0x028a, 0x029a, 0x02aa, 0x02ba, 0x02ca, - 0x110b, 0x021b, 0x022b, 0x023b, 0x024b, 0x025b, 0x026b, - 0x027b, 0x028b, 0x029b, 0x02ab, 0x02bb, 0x02cb, - 0x110c, 0x021c, 0x022c, 0x023c, 0x024c, 0x025c, 0x026c, - 0x027c, 0x028c, 0x029c, 0x02ac, 0x02bc, 0x02cc, -}; - -static const float codebook_vector10_vals[] = { - 0.0000000, 1.0000000, - 2.5198421, 4.3267487, - 6.3496042, 8.5498797, - 10.9027236, 13.3905183, - 16.0000000, 18.7207544, - 21.5443469, 24.4637810, - 27.4731418, 30.5673509, - 33.7419917, 36.9931811, -}; - -/* - * bits 0:3, 4:7 index into _vals array - * 8:9 bit mask of escape-coded entries - * 12:15 number of non-zero values - */ -static const uint16_t codebook_vector10_idx[] = { - 0x0000, 0x1010, 0x1020, 0x1030, 0x1040, 0x1050, 0x1060, 0x1070, - 0x1080, 0x1090, 0x10a0, 0x10b0, 0x10c0, 0x10d0, 0x10e0, 0x10f0, 0x1200, - 0x1001, 0x2011, 0x2021, 0x2031, 0x2041, 0x2051, 0x2061, 0x2071, - 0x2081, 0x2091, 0x20a1, 0x20b1, 0x20c1, 0x20d1, 0x20e1, 0x20f1, 0x2201, - 0x1002, 0x2012, 0x2022, 0x2032, 0x2042, 0x2052, 0x2062, 0x2072, - 0x2082, 0x2092, 0x20a2, 0x20b2, 0x20c2, 0x20d2, 0x20e2, 0x20f2, 0x2202, - 0x1003, 0x2013, 0x2023, 0x2033, 0x2043, 0x2053, 0x2063, 0x2073, - 0x2083, 0x2093, 0x20a3, 0x20b3, 0x20c3, 0x20d3, 0x20e3, 0x20f3, 0x2203, - 0x1004, 0x2014, 0x2024, 0x2034, 0x2044, 0x2054, 0x2064, 0x2074, - 0x2084, 0x2094, 0x20a4, 0x20b4, 0x20c4, 0x20d4, 0x20e4, 0x20f4, 0x2204, - 0x1005, 0x2015, 0x2025, 0x2035, 0x2045, 0x2055, 0x2065, 0x2075, - 0x2085, 0x2095, 0x20a5, 0x20b5, 0x20c5, 0x20d5, 0x20e5, 0x20f5, 0x2205, - 0x1006, 0x2016, 0x2026, 0x2036, 0x2046, 0x2056, 0x2066, 0x2076, - 0x2086, 0x2096, 0x20a6, 0x20b6, 0x20c6, 0x20d6, 0x20e6, 0x20f6, 0x2206, - 0x1007, 0x2017, 0x2027, 0x2037, 0x2047, 0x2057, 0x2067, 0x2077, - 0x2087, 0x2097, 0x20a7, 0x20b7, 0x20c7, 0x20d7, 0x20e7, 0x20f7, 0x2207, - 0x1008, 0x2018, 0x2028, 0x2038, 0x2048, 0x2058, 0x2068, 0x2078, - 0x2088, 0x2098, 0x20a8, 0x20b8, 0x20c8, 0x20d8, 0x20e8, 0x20f8, 0x2208, - 0x1009, 0x2019, 0x2029, 0x2039, 0x2049, 0x2059, 0x2069, 0x2079, - 0x2089, 0x2099, 0x20a9, 0x20b9, 0x20c9, 0x20d9, 0x20e9, 0x20f9, 0x2209, - 0x100a, 0x201a, 0x202a, 0x203a, 0x204a, 0x205a, 0x206a, 0x207a, - 0x208a, 0x209a, 0x20aa, 0x20ba, 0x20ca, 0x20da, 0x20ea, 0x20fa, 0x220a, - 0x100b, 0x201b, 0x202b, 0x203b, 0x204b, 0x205b, 0x206b, 0x207b, - 0x208b, 0x209b, 0x20ab, 0x20bb, 0x20cb, 0x20db, 0x20eb, 0x20fb, 0x220b, - 0x100c, 0x201c, 0x202c, 0x203c, 0x204c, 0x205c, 0x206c, 0x207c, - 0x208c, 0x209c, 0x20ac, 0x20bc, 0x20cc, 0x20dc, 0x20ec, 0x20fc, 0x220c, - 0x100d, 0x201d, 0x202d, 0x203d, 0x204d, 0x205d, 0x206d, 0x207d, - 0x208d, 0x209d, 0x20ad, 0x20bd, 0x20cd, 0x20dd, 0x20ed, 0x20fd, 0x220d, - 0x100e, 0x201e, 0x202e, 0x203e, 0x204e, 0x205e, 0x206e, 0x207e, - 0x208e, 0x209e, 0x20ae, 0x20be, 0x20ce, 0x20de, 0x20ee, 0x20fe, 0x220e, - 0x100f, 0x201f, 0x202f, 0x203f, 0x204f, 0x205f, 0x206f, 0x207f, - 0x208f, 0x209f, 0x20af, 0x20bf, 0x20cf, 0x20df, 0x20ef, 0x20ff, 0x220f, - 0x1100, 0x2110, 0x2120, 0x2130, 0x2140, 0x2150, 0x2160, 0x2170, - 0x2180, 0x2190, 0x21a0, 0x21b0, 0x21c0, 0x21d0, 0x21e0, 0x21f0, 0x2300, -}; - -const float *const ff_aac_codebook_vector_vals[] = { - codebook_vector0_vals, codebook_vector0_vals, - codebook_vector10_vals, codebook_vector10_vals, - codebook_vector4_vals, codebook_vector4_vals, - codebook_vector10_vals, codebook_vector10_vals, - codebook_vector10_vals, codebook_vector10_vals, - codebook_vector10_vals, -}; - -const uint16_t *const ff_aac_codebook_vector_idx[] = { - codebook_vector02_idx, codebook_vector02_idx, - codebook_vector02_idx, codebook_vector02_idx, - codebook_vector4_idx, codebook_vector4_idx, - codebook_vector6_idx, codebook_vector6_idx, - codebook_vector8_idx, codebook_vector8_idx, - codebook_vector10_idx, -}; - -/* @name swb_offsets - * Sample offset into the window indicating the beginning of a scalefactor - * window band - * - * scalefactor window band - term for scalefactor bands within a window, - * given in Table 4.110 to Table 4.128. - * - * scalefactor band - a set of spectral coefficients which are scaled by one - * scalefactor. In case of EIGHT_SHORT_SEQUENCE and grouping a scalefactor band - * may contain several scalefactor window bands of corresponding frequency. For - * all other window_sequences scalefactor bands and scalefactor window bands are - * identical. - * @{ - */ - -static const uint16_t swb_offset_1024_96[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 64, - 72, 80, 88, 96, 108, 120, 132, 144, - 156, 172, 188, 212, 240, 276, 320, 384, - 448, 512, 576, 640, 704, 768, 832, 896, - 960, 1024 -}; - -static const uint16_t swb_offset_128_96[] = { - 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128 -}; - -static const uint16_t swb_offset_1024_64[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 64, - 72, 80, 88, 100, 112, 124, 140, 156, - 172, 192, 216, 240, 268, 304, 344, 384, - 424, 464, 504, 544, 584, 624, 664, 704, - 744, 784, 824, 864, 904, 944, 984, 1024 -}; - -static const uint16_t swb_offset_1024_48[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 48, 56, 64, 72, 80, - 88, 96, 108, 120, 132, 144, 160, 176, - 196, 216, 240, 264, 292, 320, 352, 384, - 416, 448, 480, 512, 544, 576, 608, 640, - 672, 704, 736, 768, 800, 832, 864, 896, - 928, 1024 -}; - -static const uint16_t swb_offset_128_48[] = { - 0, 4, 8, 12, 16, 20, 28, 36, - 44, 56, 68, 80, 96, 112, 128 -}; - -static const uint16_t swb_offset_1024_32[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 48, 56, 64, 72, 80, - 88, 96, 108, 120, 132, 144, 160, 176, - 196, 216, 240, 264, 292, 320, 352, 384, - 416, 448, 480, 512, 544, 576, 608, 640, - 672, 704, 736, 768, 800, 832, 864, 896, - 928, 960, 992, 1024 -}; - -static const uint16_t swb_offset_1024_24[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 52, 60, 68, 76, - 84, 92, 100, 108, 116, 124, 136, 148, - 160, 172, 188, 204, 220, 240, 260, 284, - 308, 336, 364, 396, 432, 468, 508, 552, - 600, 652, 704, 768, 832, 896, 960, 1024 -}; - -static const uint16_t swb_offset_128_24[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 36, 44, 52, 64, 76, 92, 108, 128 -}; - -static const uint16_t swb_offset_1024_16[] = { - 0, 8, 16, 24, 32, 40, 48, 56, - 64, 72, 80, 88, 100, 112, 124, 136, - 148, 160, 172, 184, 196, 212, 228, 244, - 260, 280, 300, 320, 344, 368, 396, 424, - 456, 492, 532, 572, 616, 664, 716, 772, - 832, 896, 960, 1024 -}; - -static const uint16_t swb_offset_128_16[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 40, 48, 60, 72, 88, 108, 128 -}; - -static const uint16_t swb_offset_1024_8[] = { - 0, 12, 24, 36, 48, 60, 72, 84, - 96, 108, 120, 132, 144, 156, 172, 188, - 204, 220, 236, 252, 268, 288, 308, 328, - 348, 372, 396, 420, 448, 476, 508, 544, - 580, 620, 664, 712, 764, 820, 880, 944, - 1024 -}; - -static const uint16_t swb_offset_128_8[] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 36, 44, 52, 60, 72, 88, 108, 128 -}; - -const uint16_t * const ff_swb_offset_1024[] = { - swb_offset_1024_96, swb_offset_1024_96, swb_offset_1024_64, - swb_offset_1024_48, swb_offset_1024_48, swb_offset_1024_32, - swb_offset_1024_24, swb_offset_1024_24, swb_offset_1024_16, - swb_offset_1024_16, swb_offset_1024_16, swb_offset_1024_8, - swb_offset_1024_8 -}; - -const uint16_t * const ff_swb_offset_128[] = { - /* The last entry on the following row is swb_offset_128_64 but is a - duplicate of swb_offset_128_96. */ - swb_offset_128_96, swb_offset_128_96, swb_offset_128_96, - swb_offset_128_48, swb_offset_128_48, swb_offset_128_48, - swb_offset_128_24, swb_offset_128_24, swb_offset_128_16, - swb_offset_128_16, swb_offset_128_16, swb_offset_128_8, - swb_offset_128_8 -}; - -// @} - -/* @name ff_tns_max_bands - * The maximum number of scalefactor bands on which TNS can operate for the long - * and short transforms respectively. The index to these tables is related to - * the sample rate of the audio. - * @{ - */ -const uint8_t ff_tns_max_bands_1024[] = { - 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39, 39 -}; - -const uint8_t ff_tns_max_bands_128[] = { - 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 -}; -// @} - - -#if CONFIG_HARDCODED_TABLES - -/** - * Table of pow(2, (i - 200)/4.) used for different purposes depending on the - * range of indices to the table: - * [ 0, 255] scale factor decoding when using C dsp.float_to_int16 - * [60, 315] scale factor decoding when using SIMD dsp.float_to_int16 - * [45, 300] intensity stereo position decoding mapped in reverse order i.e. 0->300, 1->299, ..., 254->46, 255->45 - */ -const float ff_aac_pow2sf_tab[428] = { - 8.88178420e-16, 1.05622810e-15, 1.25607397e-15, 1.49373210e-15, - 1.77635684e-15, 2.11245619e-15, 2.51214793e-15, 2.98746420e-15, - 3.55271368e-15, 4.22491238e-15, 5.02429587e-15, 5.97492839e-15, - 7.10542736e-15, 8.44982477e-15, 1.00485917e-14, 1.19498568e-14, - 1.42108547e-14, 1.68996495e-14, 2.00971835e-14, 2.38997136e-14, - 2.84217094e-14, 3.37992991e-14, 4.01943669e-14, 4.77994272e-14, - 5.68434189e-14, 6.75985982e-14, 8.03887339e-14, 9.55988543e-14, - 1.13686838e-13, 1.35197196e-13, 1.60777468e-13, 1.91197709e-13, - 2.27373675e-13, 2.70394393e-13, 3.21554936e-13, 3.82395417e-13, - 4.54747351e-13, 5.40788785e-13, 6.43109871e-13, 7.64790834e-13, - 9.09494702e-13, 1.08157757e-12, 1.28621974e-12, 1.52958167e-12, - 1.81898940e-12, 2.16315514e-12, 2.57243948e-12, 3.05916334e-12, - 3.63797881e-12, 4.32631028e-12, 5.14487897e-12, 6.11832668e-12, - 7.27595761e-12, 8.65262056e-12, 1.02897579e-11, 1.22366534e-11, - 1.45519152e-11, 1.73052411e-11, 2.05795159e-11, 2.44733067e-11, - 2.91038305e-11, 3.46104823e-11, 4.11590317e-11, 4.89466134e-11, - 5.82076609e-11, 6.92209645e-11, 8.23180635e-11, 9.78932268e-11, - 1.16415322e-10, 1.38441929e-10, 1.64636127e-10, 1.95786454e-10, - 2.32830644e-10, 2.76883858e-10, 3.29272254e-10, 3.91572907e-10, - 4.65661287e-10, 5.53767716e-10, 6.58544508e-10, 7.83145814e-10, - 9.31322575e-10, 1.10753543e-09, 1.31708902e-09, 1.56629163e-09, - 1.86264515e-09, 2.21507086e-09, 2.63417803e-09, 3.13258326e-09, - 3.72529030e-09, 4.43014173e-09, 5.26835606e-09, 6.26516652e-09, - 7.45058060e-09, 8.86028346e-09, 1.05367121e-08, 1.25303330e-08, - 1.49011612e-08, 1.77205669e-08, 2.10734243e-08, 2.50606661e-08, - 2.98023224e-08, 3.54411338e-08, 4.21468485e-08, 5.01213321e-08, - 5.96046448e-08, 7.08822677e-08, 8.42936970e-08, 1.00242664e-07, - 1.19209290e-07, 1.41764535e-07, 1.68587394e-07, 2.00485328e-07, - 2.38418579e-07, 2.83529071e-07, 3.37174788e-07, 4.00970657e-07, - 4.76837158e-07, 5.67058141e-07, 6.74349576e-07, 8.01941314e-07, - 9.53674316e-07, 1.13411628e-06, 1.34869915e-06, 1.60388263e-06, - 1.90734863e-06, 2.26823256e-06, 2.69739830e-06, 3.20776526e-06, - 3.81469727e-06, 4.53646513e-06, 5.39479661e-06, 6.41553051e-06, - 7.62939453e-06, 9.07293026e-06, 1.07895932e-05, 1.28310610e-05, - 1.52587891e-05, 1.81458605e-05, 2.15791864e-05, 2.56621220e-05, - 3.05175781e-05, 3.62917210e-05, 4.31583729e-05, 5.13242441e-05, - 6.10351562e-05, 7.25834421e-05, 8.63167458e-05, 1.02648488e-04, - 1.22070312e-04, 1.45166884e-04, 1.72633492e-04, 2.05296976e-04, - 2.44140625e-04, 2.90333768e-04, 3.45266983e-04, 4.10593953e-04, - 4.88281250e-04, 5.80667537e-04, 6.90533966e-04, 8.21187906e-04, - 9.76562500e-04, 1.16133507e-03, 1.38106793e-03, 1.64237581e-03, - 1.95312500e-03, 2.32267015e-03, 2.76213586e-03, 3.28475162e-03, - 3.90625000e-03, 4.64534029e-03, 5.52427173e-03, 6.56950324e-03, - 7.81250000e-03, 9.29068059e-03, 1.10485435e-02, 1.31390065e-02, - 1.56250000e-02, 1.85813612e-02, 2.20970869e-02, 2.62780130e-02, - 3.12500000e-02, 3.71627223e-02, 4.41941738e-02, 5.25560260e-02, - 6.25000000e-02, 7.43254447e-02, 8.83883476e-02, 1.05112052e-01, - 1.25000000e-01, 1.48650889e-01, 1.76776695e-01, 2.10224104e-01, - 2.50000000e-01, 2.97301779e-01, 3.53553391e-01, 4.20448208e-01, - 5.00000000e-01, 5.94603558e-01, 7.07106781e-01, 8.40896415e-01, - 1.00000000e+00, 1.18920712e+00, 1.41421356e+00, 1.68179283e+00, - 2.00000000e+00, 2.37841423e+00, 2.82842712e+00, 3.36358566e+00, - 4.00000000e+00, 4.75682846e+00, 5.65685425e+00, 6.72717132e+00, - 8.00000000e+00, 9.51365692e+00, 1.13137085e+01, 1.34543426e+01, - 1.60000000e+01, 1.90273138e+01, 2.26274170e+01, 2.69086853e+01, - 3.20000000e+01, 3.80546277e+01, 4.52548340e+01, 5.38173706e+01, - 6.40000000e+01, 7.61092554e+01, 9.05096680e+01, 1.07634741e+02, - 1.28000000e+02, 1.52218511e+02, 1.81019336e+02, 2.15269482e+02, - 2.56000000e+02, 3.04437021e+02, 3.62038672e+02, 4.30538965e+02, - 5.12000000e+02, 6.08874043e+02, 7.24077344e+02, 8.61077929e+02, - 1.02400000e+03, 1.21774809e+03, 1.44815469e+03, 1.72215586e+03, - 2.04800000e+03, 2.43549617e+03, 2.89630938e+03, 3.44431172e+03, - 4.09600000e+03, 4.87099234e+03, 5.79261875e+03, 6.88862343e+03, - 8.19200000e+03, 9.74198469e+03, 1.15852375e+04, 1.37772469e+04, - 1.63840000e+04, 1.94839694e+04, 2.31704750e+04, 2.75544937e+04, - 3.27680000e+04, 3.89679387e+04, 4.63409500e+04, 5.51089875e+04, - 6.55360000e+04, 7.79358775e+04, 9.26819000e+04, 1.10217975e+05, - 1.31072000e+05, 1.55871755e+05, 1.85363800e+05, 2.20435950e+05, - 2.62144000e+05, 3.11743510e+05, 3.70727600e+05, 4.40871900e+05, - 5.24288000e+05, 6.23487020e+05, 7.41455200e+05, 8.81743800e+05, - 1.04857600e+06, 1.24697404e+06, 1.48291040e+06, 1.76348760e+06, - 2.09715200e+06, 2.49394808e+06, 2.96582080e+06, 3.52697520e+06, - 4.19430400e+06, 4.98789616e+06, 5.93164160e+06, 7.05395040e+06, - 8.38860800e+06, 9.97579232e+06, 1.18632832e+07, 1.41079008e+07, - 1.67772160e+07, 1.99515846e+07, 2.37265664e+07, 2.82158016e+07, - 3.35544320e+07, 3.99031693e+07, 4.74531328e+07, 5.64316032e+07, - 6.71088640e+07, 7.98063385e+07, 9.49062656e+07, 1.12863206e+08, - 1.34217728e+08, 1.59612677e+08, 1.89812531e+08, 2.25726413e+08, - 2.68435456e+08, 3.19225354e+08, 3.79625062e+08, 4.51452825e+08, - 5.36870912e+08, 6.38450708e+08, 7.59250125e+08, 9.02905651e+08, - 1.07374182e+09, 1.27690142e+09, 1.51850025e+09, 1.80581130e+09, - 2.14748365e+09, 2.55380283e+09, 3.03700050e+09, 3.61162260e+09, - 4.29496730e+09, 5.10760567e+09, 6.07400100e+09, 7.22324521e+09, - 8.58993459e+09, 1.02152113e+10, 1.21480020e+10, 1.44464904e+10, - 1.71798692e+10, 2.04304227e+10, 2.42960040e+10, 2.88929808e+10, - 3.43597384e+10, 4.08608453e+10, 4.85920080e+10, 5.77859616e+10, - 6.87194767e+10, 8.17216907e+10, 9.71840160e+10, 1.15571923e+11, - 1.37438953e+11, 1.63443381e+11, 1.94368032e+11, 2.31143847e+11, - 2.74877907e+11, 3.26886763e+11, 3.88736064e+11, 4.62287693e+11, - 5.49755814e+11, 6.53773525e+11, 7.77472128e+11, 9.24575386e+11, - 1.09951163e+12, 1.30754705e+12, 1.55494426e+12, 1.84915077e+12, - 2.19902326e+12, 2.61509410e+12, 3.10988851e+12, 3.69830155e+12, - 4.39804651e+12, 5.23018820e+12, 6.21977702e+12, 7.39660309e+12, - 8.79609302e+12, 1.04603764e+13, 1.24395540e+13, 1.47932062e+13, - 1.75921860e+13, 2.09207528e+13, 2.48791081e+13, 2.95864124e+13, - 3.51843721e+13, 4.18415056e+13, 4.97582162e+13, 5.91728247e+13, - 7.03687442e+13, 8.36830112e+13, 9.95164324e+13, 1.18345649e+14, - 1.40737488e+14, 1.67366022e+14, 1.99032865e+14, 2.36691299e+14, - 2.81474977e+14, 3.34732045e+14, 3.98065730e+14, 4.73382598e+14, - 5.62949953e+14, 6.69464090e+14, 7.96131459e+14, 9.46765196e+14, - 1.12589991e+15, 1.33892818e+15, 1.59226292e+15, 1.89353039e+15, - 2.25179981e+15, 2.67785636e+15, 3.18452584e+15, 3.78706078e+15, - 4.50359963e+15, 5.35571272e+15, 6.36905167e+15, 7.57412156e+15, - 9.00719925e+15, 1.07114254e+16, 1.27381033e+16, 1.51482431e+16, - 1.80143985e+16, 2.14228509e+16, 2.54762067e+16, 3.02964863e+16, - 3.60287970e+16, 4.28457018e+16, 5.09524134e+16, 6.05929725e+16, - 7.20575940e+16, 8.56914035e+16, 1.01904827e+17, 1.21185945e+17, -}; - -#else - -float ff_aac_pow2sf_tab[428]; - -#endif /* CONFIG_HARDCODED_TABLES */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aactab.h b/tizen/distrib/ffmpeg/libavcodec/aactab.h deleted file mode 100644 index 283d6c3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aactab.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * AAC data declarations - * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) - * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC data declarations - * @author Oded Shimon ( ods15 ods15 dyndns org ) - * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) - */ - -#ifndef AVCODEC_AACTAB_H -#define AVCODEC_AACTAB_H - -#include "libavutil/mem.h" -#include "aac.h" - -#include - -/* NOTE: - * Tables in this file are used by the AAC decoder and will be used by the AAC - * encoder. - */ - -/* @name window coefficients - * @{ - */ -DECLARE_ALIGNED(16, extern float, ff_aac_kbd_long_1024)[1024]; -DECLARE_ALIGNED(16, extern float, ff_aac_kbd_short_128)[128]; -// @} - -/* @name number of scalefactor window bands for long and short transform windows respectively - * @{ - */ -extern const uint8_t ff_aac_num_swb_1024[]; -extern const uint8_t ff_aac_num_swb_128 []; -// @} - -extern const uint8_t ff_aac_pred_sfb_max []; - -extern const uint32_t ff_aac_scalefactor_code[121]; -extern const uint8_t ff_aac_scalefactor_bits[121]; - -extern const uint16_t * const ff_aac_spectral_codes[11]; -extern const uint8_t * const ff_aac_spectral_bits [11]; -extern const uint16_t ff_aac_spectral_sizes[11]; - -extern const float *ff_aac_codebook_vectors[]; -extern const float *ff_aac_codebook_vector_vals[]; -extern const uint16_t *ff_aac_codebook_vector_idx[]; - -extern const uint16_t * const ff_swb_offset_1024[13]; -extern const uint16_t * const ff_swb_offset_128 [13]; - -extern const uint8_t ff_tns_max_bands_1024[13]; -extern const uint8_t ff_tns_max_bands_128 [13]; - -#if CONFIG_HARDCODED_TABLES -extern const float ff_aac_pow2sf_tab[428]; -#else -extern float ff_aac_pow2sf_tab[428]; -#endif /* CONFIG_HARDCODED_TABLES */ - -#endif /* AVCODEC_AACTAB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aandcttab.c b/tizen/distrib/ffmpeg/libavcodec/aandcttab.c deleted file mode 100644 index 87c50b3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aandcttab.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAN (Arai Agui Aakajima) (I)DCT tables - */ - -#include - -const uint16_t ff_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 -}; - -const uint16_t ff_inv_aanscales[64] = { - 4096, 2953, 3135, 3483, 4096, 5213, 7568, 14846, - 2953, 2129, 2260, 2511, 2953, 3759, 5457, 10703, - 3135, 2260, 2399, 2666, 3135, 3990, 5793, 11363, - 3483, 2511, 2666, 2962, 3483, 4433, 6436, 12625, - 4096, 2953, 3135, 3483, 4096, 5213, 7568, 14846, - 5213, 3759, 3990, 4433, 5213, 6635, 9633, 18895, - 7568, 5457, 5793, 6436, 7568, 9633, 13985, 27432, - 14846, 10703, 11363, 12625, 14846, 18895, 27432, 53809, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/aandcttab.h b/tizen/distrib/ffmpeg/libavcodec/aandcttab.h deleted file mode 100644 index d774828..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aandcttab.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAN (Arai Agui Nakajima) (I)DCT tables - */ - -#ifndef AVCODEC_AANDCTTAB_H -#define AVCODEC_AANDCTTAB_H - -#include - -extern const uint16_t ff_aanscales[64]; -extern const uint16_t ff_inv_aanscales[64]; - -#endif /* AVCODEC_AANDCTTAB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aasc.c b/tizen/distrib/ffmpeg/libavcodec/aasc.c deleted file mode 100644 index 82bd2bf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aasc.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Autodesk RLE Decoder - * Copyright (C) 2005 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Autodesk RLE Video Decoder by Konstantin Shishkov - */ - -#include -#include -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "msrledec.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 av_cold int aasc_decode_init(AVCodecContext *avctx) -{ - AascContext *s = avctx->priv_data; - - s->avctx = avctx; - - avctx->pix_fmt = PIX_FMT_BGR24; - - return 0; -} - -static int aasc_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AascContext *s = avctx->priv_data; - int compr, i, stride; - - 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; - } - - compr = AV_RL32(buf); - buf += 4; - buf_size -= 4; - switch(compr){ - case 0: - stride = (avctx->width * 3 + 3) & ~3; - for(i = avctx->height - 1; i >= 0; i--){ - memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width*3); - buf += stride; - } - break; - case 1: - ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, buf - 4, buf_size + 4); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); - return -1; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /* report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int aasc_decode_end(AVCodecContext *avctx) -{ - AascContext *s = avctx->priv_data; - - /* release the last frame */ - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec aasc_decoder = { - "aasc", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_AASC, - sizeof(AascContext), - aasc_decode_init, - NULL, - aasc_decode_end, - aasc_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Autodesk RLE"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3.c b/tizen/distrib/ffmpeg/libavcodec/ac3.c deleted file mode 100644 index 3fce5bc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Common code between the AC-3 encoder and decoder - * Copyright (c) 2000 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Common code between the AC-3 encoder and decoder. - */ - -#include "avcodec.h" -#include "ac3.h" -#include "get_bits.h" - -#if CONFIG_HARDCODED_TABLES - -/** - * Starting frequency coefficient bin for each critical band. - */ -static const uint8_t band_start_tab[51] = { - 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, 31, - 34, 37, 40, 43, 46, 49, 55, 61, 67, 73, - 79, 85, 97, 109, 121, 133, 157, 181, 205, 229, 253 -}; - -/** - * Maps each frequency coefficient bin to the critical band that contains it. - */ -static const uint8_t bin_to_band_tab[253] = { - 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, 28, 28, 29, 29, 29, 30, 30, 30, - 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, - 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, - 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, - 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49 -}; - -#else /* CONFIG_HARDCODED_TABLES */ -static uint8_t band_start_tab[51]; -static uint8_t bin_to_band_tab[253]; -#endif - -static inline int calc_lowcomp1(int a, int b0, int b1, int c) -{ - if ((b0 + 256) == b1) { - a = c; - } else if (b0 > b1) { - a = FFMAX(a - 64, 0); - } - return a; -} - -static inline int calc_lowcomp(int a, int b0, int b1, int bin) -{ - if (bin < 7) { - return calc_lowcomp1(a, b0, b1, 384); - } else if (bin < 20) { - return calc_lowcomp1(a, b0, b1, 320); - } else { - return FFMAX(a - 128, 0); - } -} - -void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, - int16_t *band_psd) -{ - int bin, band; - - /* exponent mapping to PSD */ - for (bin = start; bin < end; bin++) { - psd[bin]=(3072 - (exp[bin] << 7)); - } - - /* PSD integration */ - bin = start; - band = bin_to_band_tab[start]; - do { - int v = psd[bin++]; - int band_end = FFMIN(band_start_tab[band+1], end); - for (; bin < band_end; bin++) { - int max = FFMAX(v, psd[bin]); - /* logadd */ - int adr = FFMIN(max - ((v + psd[bin] + 1) >> 1), 255); - v = max + ff_ac3_log_add_tab[adr]; - } - band_psd[band++] = v; - } while (end > band_start_tab[band]); -} - -int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, - int start, int end, int fast_gain, int is_lfe, - int dba_mode, int dba_nsegs, uint8_t *dba_offsets, - uint8_t *dba_lengths, uint8_t *dba_values, - int16_t *mask) -{ - int16_t excite[50]; /* excitation */ - int band; - int band_start, band_end, begin, end1; - int lowcomp, fastleak, slowleak; - - /* excitation function */ - band_start = bin_to_band_tab[start]; - band_end = bin_to_band_tab[end-1] + 1; - - if (band_start == 0) { - lowcomp = 0; - lowcomp = calc_lowcomp1(lowcomp, band_psd[0], band_psd[1], 384); - excite[0] = band_psd[0] - fast_gain - lowcomp; - lowcomp = calc_lowcomp1(lowcomp, band_psd[1], band_psd[2], 384); - excite[1] = band_psd[1] - fast_gain - lowcomp; - begin = 7; - for (band = 2; band < 7; band++) { - if (!(is_lfe && band == 6)) - lowcomp = calc_lowcomp1(lowcomp, band_psd[band], band_psd[band+1], 384); - fastleak = band_psd[band] - fast_gain; - slowleak = band_psd[band] - s->slow_gain; - excite[band] = fastleak - lowcomp; - if (!(is_lfe && band == 6)) { - if (band_psd[band] <= band_psd[band+1]) { - begin = band + 1; - break; - } - } - } - - end1 = FFMIN(band_end, 22); - for (band = begin; band < end1; band++) { - if (!(is_lfe && band == 6)) - lowcomp = calc_lowcomp(lowcomp, band_psd[band], band_psd[band+1], band); - fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain); - slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain); - excite[band] = FFMAX(fastleak - lowcomp, slowleak); - } - begin = 22; - } else { - /* coupling channel */ - begin = band_start; - fastleak = (s->cpl_fast_leak << 8) + 768; - slowleak = (s->cpl_slow_leak << 8) + 768; - } - - for (band = begin; band < band_end; band++) { - fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain); - slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain); - excite[band] = FFMAX(fastleak, slowleak); - } - - /* compute masking curve */ - - for (band = band_start; band < band_end; band++) { - int tmp = s->db_per_bit - band_psd[band]; - if (tmp > 0) { - excite[band] += tmp >> 2; - } - mask[band] = FFMAX(ff_ac3_hearing_threshold_tab[band >> s->sr_shift][s->sr_code], excite[band]); - } - - /* delta bit allocation */ - - if (dba_mode == DBA_REUSE || dba_mode == DBA_NEW) { - int i, seg, delta; - if (dba_nsegs >= 8) - return -1; - band = 0; - for (seg = 0; seg < dba_nsegs; seg++) { - band += dba_offsets[seg]; - if (band >= 50 || dba_lengths[seg] > 50-band) - return -1; - if (dba_values[seg] >= 4) { - delta = (dba_values[seg] - 3) << 7; - } else { - delta = (dba_values[seg] - 4) << 7; - } - for (i = 0; i < dba_lengths[seg]; i++) { - mask[band++] += delta; - } - } - } - return 0; -} - -void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end, - int snr_offset, int floor, - const uint8_t *bap_tab, uint8_t *bap) -{ - int bin, band; - - /* special case, if snr offset is -960, set all bap's to zero */ - if (snr_offset == -960) { - memset(bap, 0, 256); - return; - } - - bin = start; - band = bin_to_band_tab[start]; - do { - int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor; - int band_end = FFMIN(band_start_tab[band+1], end); - for (; bin < band_end; bin++) { - int address = av_clip((psd[bin] - m) >> 5, 0, 63); - bap[bin] = bap_tab[address]; - } - } while (end > band_start_tab[band++]); -} - -/* AC-3 bit allocation. The algorithm is the one described in the AC-3 - spec. */ -void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap, - int8_t *exp, int start, int end, - int snr_offset, int fast_gain, int is_lfe, - int dba_mode, int dba_nsegs, - uint8_t *dba_offsets, uint8_t *dba_lengths, - uint8_t *dba_values) -{ - int16_t psd[256]; /* scaled exponents */ - int16_t band_psd[50]; /* interpolated exponents */ - int16_t mask[50]; /* masking value */ - - ff_ac3_bit_alloc_calc_psd(exp, start, end, psd, band_psd); - - ff_ac3_bit_alloc_calc_mask(s, band_psd, start, end, fast_gain, is_lfe, - dba_mode, dba_nsegs, dba_offsets, dba_lengths, - dba_values, mask); - - ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snr_offset, s->floor, - ff_ac3_bap_tab, bap); -} - -/** - * Initializes some tables. - * note: This function must remain thread safe because it is called by the - * AVParser init code. - */ -av_cold void ac3_common_init(void) -{ -#if !CONFIG_HARDCODED_TABLES - /* compute bndtab and masktab from bandsz */ - int bin = 0, band; - for (band = 0; band < 50; band++) { - int band_end = bin + ff_ac3_critical_band_size_tab[band]; - band_start_tab[band] = bin; - while (bin < band_end) - bin_to_band_tab[bin++] = band; - } - band_start_tab[50] = bin; -#endif /* !CONFIG_HARDCODED_TABLES */ -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3.h b/tizen/distrib/ffmpeg/libavcodec/ac3.h deleted file mode 100644 index 0def3b0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Common code between the AC-3 encoder and decoder - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Common code between the AC-3 encoder and decoder. - */ - -#ifndef AVCODEC_AC3_H -#define AVCODEC_AC3_H - -#include "ac3tab.h" - -#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 AC-3 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 - -/** Delta bit allocation strategy */ -typedef enum { - DBA_REUSE = 0, - DBA_NEW, - DBA_NONE, - DBA_RESERVED -} AC3DeltaStrategy; - -/** Channel mode (audio coding mode) */ -typedef enum { - AC3_CHMODE_DUALMONO = 0, - AC3_CHMODE_MONO, - AC3_CHMODE_STEREO, - AC3_CHMODE_3F, - AC3_CHMODE_2F1R, - AC3_CHMODE_3F1R, - AC3_CHMODE_2F2R, - AC3_CHMODE_3F2R -} AC3ChannelMode; - -typedef struct AC3BitAllocParameters { - int sr_code; - int sr_shift; - int slow_gain, slow_decay, fast_decay, db_per_bit, floor; - int cpl_fast_leak, cpl_slow_leak; -} AC3BitAllocParameters; - -/** - * @struct AC3HeaderInfo - * Coded AC-3 header values up to the lfeon element, plus derived values. - */ -typedef struct { - /** @defgroup coded Coded elements - * @{ - */ - uint16_t sync_word; - uint16_t crc1; - uint8_t sr_code; - uint8_t bitstream_id; - uint8_t channel_mode; - uint8_t lfe_on; - uint8_t frame_type; - int substreamid; ///< substream identification - int center_mix_level; ///< Center mix level index - int surround_mix_level; ///< Surround mix level index - uint16_t channel_map; - int num_blocks; ///< number of audio blocks - /** @} */ - - /** @defgroup derived Derived values - * @{ - */ - uint8_t sr_shift; - uint16_t sample_rate; - uint32_t bit_rate; - uint8_t channels; - uint16_t frame_size; - int64_t channel_layout; - /** @} */ -} AC3HeaderInfo; - -typedef enum { - EAC3_FRAME_TYPE_INDEPENDENT = 0, - EAC3_FRAME_TYPE_DEPENDENT, - EAC3_FRAME_TYPE_AC3_CONVERT, - EAC3_FRAME_TYPE_RESERVED -} EAC3FrameType; - -void ac3_common_init(void); - -/** - * Calculates the log power-spectral density of the input signal. - * This gives a rough estimate of signal power in the frequency domain by using - * the spectral envelope (exponents). The psd is also separately grouped - * into critical bands for use in the calculating the masking curve. - * 128 units in psd = -6 dB. The dbknee parameter in AC3BitAllocParameters - * determines the reference level. - * - * @param[in] exp frequency coefficient exponents - * @param[in] start starting bin location - * @param[in] end ending bin location - * @param[out] psd signal power for each frequency bin - * @param[out] band_psd signal power for each critical band - */ -void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, - int16_t *band_psd); - -/** - * Calculates the masking curve. - * First, the excitation is calculated using parameters in s and the signal - * power in each critical band. The excitation is compared with a predefined - * hearing threshold table to produce the masking curve. If delta bit - * allocation information is provided, it is used for adjusting the masking - * curve, usually to give a closer match to a better psychoacoustic model. - * - * @param[in] s adjustable bit allocation parameters - * @param[in] band_psd signal power for each critical band - * @param[in] start starting bin location - * @param[in] end ending bin location - * @param[in] fast_gain fast gain (estimated signal-to-mask ratio) - * @param[in] is_lfe whether or not the channel being processed is the LFE - * @param[in] dba_mode delta bit allocation mode (none, reuse, or new) - * @param[in] dba_nsegs number of delta segments - * @param[in] dba_offsets location offsets for each segment - * @param[in] dba_lengths length of each segment - * @param[in] dba_values delta bit allocation for each segment - * @param[out] mask calculated masking curve - * @return returns 0 for success, non-zero for error - */ -int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, - int start, int end, int fast_gain, int is_lfe, - int dba_mode, int dba_nsegs, uint8_t *dba_offsets, - uint8_t *dba_lengths, uint8_t *dba_values, - int16_t *mask); - -/** - * Calculates bit allocation pointers. - * The SNR is the difference between the masking curve and the signal. AC-3 - * uses this value for each frequency bin to allocate bits. The snroffset - * parameter is a global adjustment to the SNR for all bins. - * - * @param[in] mask masking curve - * @param[in] psd signal power for each frequency bin - * @param[in] start starting bin location - * @param[in] end ending bin location - * @param[in] snr_offset SNR adjustment - * @param[in] floor noise floor - * @param[in] bap_tab look-up table for bit allocation pointers - * @param[out] bap bit allocation pointers - */ -void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end, - int snr_offset, int floor, - const uint8_t *bap_tab, uint8_t *bap); - -void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap, - int8_t *exp, int start, int end, - int snr_offset, int fast_gain, int is_lfe, - int dba_mode, int dba_nsegs, - uint8_t *dba_offsets, uint8_t *dba_lengths, - uint8_t *dba_values); - -#endif /* AVCODEC_AC3_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3_parser.c b/tizen/distrib/ffmpeg/libavcodec/ac3_parser.c deleted file mode 100644 index 856f97a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3_parser.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * AC-3 parser - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" -#include "ac3_parser.h" -#include "aac_ac3_parser.h" -#include "get_bits.h" - - -#define AC3_HEADER_SIZE 7 - - -static const uint8_t eac3_blocks[4] = { - 1, 2, 3, 6 -}; - - -int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) -{ - int frame_size_code; - - memset(hdr, 0, sizeof(*hdr)); - - hdr->sync_word = get_bits(gbc, 16); - if(hdr->sync_word != 0x0B77) - return AAC_AC3_PARSE_ERROR_SYNC; - - /* read ahead to bsid to distinguish between AC-3 and E-AC-3 */ - hdr->bitstream_id = show_bits_long(gbc, 29) & 0x1F; - if(hdr->bitstream_id > 16) - return AAC_AC3_PARSE_ERROR_BSID; - - hdr->num_blocks = 6; - - /* set default mix levels */ - hdr->center_mix_level = 1; // -4.5dB - hdr->surround_mix_level = 1; // -6.0dB - - if(hdr->bitstream_id <= 10) { - /* Normal AC-3 */ - hdr->crc1 = get_bits(gbc, 16); - hdr->sr_code = get_bits(gbc, 2); - if(hdr->sr_code == 3) - return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; - - frame_size_code = get_bits(gbc, 6); - if(frame_size_code > 37) - return AAC_AC3_PARSE_ERROR_FRAME_SIZE; - - skip_bits(gbc, 5); // skip bsid, already got it - - skip_bits(gbc, 3); // skip bitstream mode - hdr->channel_mode = get_bits(gbc, 3); - - if(hdr->channel_mode == AC3_CHMODE_STEREO) { - skip_bits(gbc, 2); // skip dsurmod - } else { - if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) - hdr->center_mix_level = get_bits(gbc, 2); - if(hdr->channel_mode & 4) - hdr->surround_mix_level = get_bits(gbc, 2); - } - hdr->lfe_on = get_bits1(gbc); - - hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8; - hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; - hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift; - hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; - hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; - hdr->frame_type = EAC3_FRAME_TYPE_AC3_CONVERT; //EAC3_FRAME_TYPE_INDEPENDENT; - hdr->substreamid = 0; - } else { - /* Enhanced AC-3 */ - hdr->crc1 = 0; - hdr->frame_type = get_bits(gbc, 2); - if(hdr->frame_type == EAC3_FRAME_TYPE_RESERVED) - return AAC_AC3_PARSE_ERROR_FRAME_TYPE; - - hdr->substreamid = get_bits(gbc, 3); - - hdr->frame_size = (get_bits(gbc, 11) + 1) << 1; - if(hdr->frame_size < AC3_HEADER_SIZE) - return AAC_AC3_PARSE_ERROR_FRAME_SIZE; - - hdr->sr_code = get_bits(gbc, 2); - if (hdr->sr_code == 3) { - int sr_code2 = get_bits(gbc, 2); - if(sr_code2 == 3) - return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; - hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; - hdr->sr_shift = 1; - } else { - hdr->num_blocks = eac3_blocks[get_bits(gbc, 2)]; - hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code]; - hdr->sr_shift = 0; - } - - hdr->channel_mode = get_bits(gbc, 3); - hdr->lfe_on = get_bits1(gbc); - - hdr->bit_rate = (uint32_t)(8.0 * hdr->frame_size * hdr->sample_rate / - (hdr->num_blocks * 256.0)); - hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; - } - hdr->channel_layout = ff_ac3_channel_layout_tab[hdr->channel_mode]; - if (hdr->lfe_on) - hdr->channel_layout |= CH_LOW_FREQUENCY; - - return 0; -} - -int ff_ac3_parse_header_full(GetBitContext *gbc, AC3HeaderInfo *hdr){ - int ret, i; - ret = ff_ac3_parse_header(gbc, hdr); - if(!ret){ - if(hdr->bitstream_id>10){ - /* Enhanced AC-3 */ - skip_bits(gbc, 5); // skip bitstream id - - /* skip dialog normalization and compression gain */ - for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { - skip_bits(gbc, 5); // skip dialog normalization - if (get_bits1(gbc)) { - skip_bits(gbc, 8); //skip Compression gain word - } - } - /* dependent stream channel map */ - if (hdr->frame_type == EAC3_FRAME_TYPE_DEPENDENT && get_bits1(gbc)) { - hdr->channel_map = get_bits(gbc, 16); //custom channel map - return 0; - } - } - //default channel map based on acmod and lfeon - hdr->channel_map = ff_eac3_default_chmap[hdr->channel_mode]; - if(hdr->lfe_on) - hdr->channel_map |= AC3_CHMAP_LFE; - } - return ret; -} - -static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, - int *need_next_header, int *new_frame_start) -{ - int err; - union { - uint64_t u64; - uint8_t u8[8]; - } tmp = { be2me_64(state) }; - AC3HeaderInfo hdr; - GetBitContext gbc; - - init_get_bits(&gbc, tmp.u8+8-AC3_HEADER_SIZE, 54); - err = ff_ac3_parse_header(&gbc, &hdr); - - if(err < 0) - return 0; - - hdr_info->sample_rate = hdr.sample_rate; - hdr_info->bit_rate = hdr.bit_rate; - hdr_info->channels = hdr.channels; - hdr_info->channel_layout = hdr.channel_layout; - hdr_info->samples = hdr.num_blocks * 256; - if(hdr.bitstream_id>10) - hdr_info->codec_id = CODEC_ID_EAC3; - else - hdr_info->codec_id = CODEC_ID_AC3; - - *need_next_header = (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT); - *new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT); - return hdr.frame_size; -} - -static av_cold int ac3_parse_init(AVCodecParserContext *s1) -{ - AACAC3ParseContext *s = s1->priv_data; - s->header_size = AC3_HEADER_SIZE; - s->sync = ac3_sync; - return 0; -} - - -AVCodecParser ac3_parser = { - { CODEC_ID_AC3, CODEC_ID_EAC3 }, - sizeof(AACAC3ParseContext), - ac3_parse_init, - ff_aac_ac3_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3_parser.h b/tizen/distrib/ffmpeg/libavcodec/ac3_parser.h deleted file mode 100644 index 766c68b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3_parser.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * AC-3 parser prototypes - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AC3_PARSER_H -#define AVCODEC_AC3_PARSER_H - -#include "ac3.h" -#include "get_bits.h" - -/** - * Parses AC-3 frame header. - * Parses the header up to the lfeon element, which is the first 52 or 54 bits - * depending on the audio coding mode. - * @param gbc[in] BitContext containing the first 54 bits of the frame. - * @param hdr[out] Pointer to struct where header info is written. - * @return Returns 0 on success, -1 if there is a sync word mismatch, - * -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate) - * element is invalid, or -4 if the frmsizecod (bit rate) element is invalid. - */ -int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr); - -/** - * Parses AC-3 frame header and sets channel_map - * Parses the header up to the lfeon (channel_map in E-AC-3) - * element, which is the first 52, 54 or 104 bits depending - * on the audio coding mode. - * @param gbc[in] BitContext containing the first 54 bits of the frame. - * @param hdr[out] Pointer to struct where header info is written. - * @return value returned by ff_ac3_parse_header - */ -int ff_ac3_parse_header_full(GetBitContext *gbc, AC3HeaderInfo *hdr); - -#endif /* AVCODEC_AC3_PARSER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3dec.c b/tizen/distrib/ffmpeg/libavcodec/ac3dec.c deleted file mode 100644 index f2f6e5c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3dec.c +++ /dev/null @@ -1,1462 +0,0 @@ -/* - * AC-3 Audio Decoder - * This code was developed as part of Google Summer of Code 2006. - * E-AC-3 support was added as part of Google Summer of Code 2007. - * - * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com) - * Copyright (c) 2007-2008 Bartlomiej Wolowiec - * Copyright (c) 2007 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -#include "libavutil/crc.h" -#include "internal.h" -#include "aac_ac3_parser.h" -#include "ac3_parser.h" -#include "ac3dec.h" -#include "ac3dec_data.h" - -/** Large enough for maximum possible frame size when the specification limit is ignored */ -#define AC3_FRAME_BUFFER_SIZE 32768 - -/** - * table for ungrouping 3 values in 7 bits. - * used for exponents and bap=2 mantissas - */ -static uint8_t ungroup_3_in_7_bits_tab[128][3]; - - -/** tables for ungrouping mantissas */ -static int b1_mantissas[32][3]; -static int b2_mantissas[128][3]; -static int b3_mantissas[8]; -static int b4_mantissas[128][2]; -static int b5_mantissas[16]; - -/** - * Quantization table: levels for symmetric. bits for asymmetric. - * reference: Table 7.18 Mapping of bap to Quantizer - */ -static const uint8_t quantization_tab[16] = { - 0, 3, 5, 7, 11, 15, - 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 -}; - -/** dynamic range table. converts codes to scale factors. */ -static float dynamic_range_tab[256]; - -/** Adjustments in dB gain */ -#define LEVEL_PLUS_3DB 1.4142135623730950 -#define LEVEL_PLUS_1POINT5DB 1.1892071150027209 -#define LEVEL_MINUS_1POINT5DB 0.8408964152537145 -#define LEVEL_MINUS_3DB 0.7071067811865476 -#define LEVEL_MINUS_4POINT5DB 0.5946035575013605 -#define LEVEL_MINUS_6DB 0.5000000000000000 -#define LEVEL_MINUS_9DB 0.3535533905932738 -#define LEVEL_ZERO 0.0000000000000000 -#define LEVEL_ONE 1.0000000000000000 - -static const float gain_levels[9] = { - LEVEL_PLUS_3DB, - LEVEL_PLUS_1POINT5DB, - LEVEL_ONE, - LEVEL_MINUS_1POINT5DB, - LEVEL_MINUS_3DB, - LEVEL_MINUS_4POINT5DB, - LEVEL_MINUS_6DB, - LEVEL_ZERO, - LEVEL_MINUS_9DB -}; - -/** - * Table for center mix levels - * reference: Section 5.4.2.4 cmixlev - */ -static const uint8_t center_levels[4] = { 4, 5, 6, 5 }; - -/** - * Table for surround mix levels - * reference: Section 5.4.2.5 surmixlev - */ -static const uint8_t surround_levels[4] = { 4, 6, 7, 6 }; - -/** - * Table for default stereo downmixing coefficients - * reference: Section 7.8.2 Downmixing Into Two Channels - */ -static const uint8_t ac3_default_coeffs[8][5][2] = { - { { 2, 7 }, { 7, 2 }, }, - { { 4, 4 }, }, - { { 2, 7 }, { 7, 2 }, }, - { { 2, 7 }, { 5, 5 }, { 7, 2 }, }, - { { 2, 7 }, { 7, 2 }, { 6, 6 }, }, - { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 8, 8 }, }, - { { 2, 7 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, - { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, }, -}; - -/** - * Symmetrical Dequantization - * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization - * Tables 7.19 to 7.23 - */ -static inline int -symmetric_dequant(int code, int levels) -{ - return ((code - (levels >> 1)) << 24) / levels; -} - -/* - * Initialize tables at runtime. - */ -static av_cold void ac3_tables_init(void) -{ - int i; - - /* generate table for ungrouping 3 values in 7 bits - reference: Section 7.1.3 Exponent Decoding */ - for(i=0; i<128; i++) { - ungroup_3_in_7_bits_tab[i][0] = i / 25; - ungroup_3_in_7_bits_tab[i][1] = (i % 25) / 5; - ungroup_3_in_7_bits_tab[i][2] = (i % 25) % 5; - } - - /* generate grouped mantissa tables - reference: Section 7.3.5 Ungrouping of Mantissas */ - for(i=0; i<32; i++) { - /* bap=1 mantissas */ - b1_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][0], 3); - b1_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][1], 3); - b1_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][2], 3); - } - for(i=0; i<128; i++) { - /* bap=2 mantissas */ - b2_mantissas[i][0] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][0], 5); - b2_mantissas[i][1] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][1], 5); - b2_mantissas[i][2] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][2], 5); - - /* bap=4 mantissas */ - b4_mantissas[i][0] = symmetric_dequant(i / 11, 11); - b4_mantissas[i][1] = symmetric_dequant(i % 11, 11); - } - /* generate ungrouped mantissa tables - reference: Tables 7.21 and 7.23 */ - for(i=0; i<7; i++) { - /* bap=3 mantissas */ - b3_mantissas[i] = symmetric_dequant(i, 7); - } - for(i=0; i<15; i++) { - /* bap=5 mantissas */ - b5_mantissas[i] = symmetric_dequant(i, 15); - } - - /* generate dynamic range table - reference: Section 7.7.1 Dynamic Range Control */ - for(i=0; i<256; i++) { - int v = (i >> 5) - ((i >> 7) << 3) - 5; - dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20); - } -} - - -/** - * AVCodec initialization - */ -static av_cold int ac3_decode_init(AVCodecContext *avctx) -{ - AC3DecodeContext *s = avctx->priv_data; - s->avctx = avctx; - - ac3_common_init(); - ac3_tables_init(); - ff_mdct_init(&s->imdct_256, 8, 1, 1.0); - ff_mdct_init(&s->imdct_512, 9, 1, 1.0); - ff_kbd_window_init(s->window, 5.0, 256); - dsputil_init(&s->dsp, avctx); - av_lfg_init(&s->dith_state, 0); - - /* set bias values for float to int16 conversion */ - if(s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { - s->add_bias = 385.0f; - s->mul_bias = 1.0f; - } else { - s->add_bias = 0.0f; - s->mul_bias = 32767.0f; - } - - /* allow downmixing to stereo or mono */ - if (avctx->channels > 0 && avctx->request_channels > 0 && - avctx->request_channels < avctx->channels && - avctx->request_channels <= 2) { - avctx->channels = avctx->request_channels; - } - s->downmixed = 1; - - /* allocate context input buffer */ - if (avctx->error_recognition >= FF_ER_CAREFUL) { - s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - if (!s->input_buffer) - return AVERROR(ENOMEM); - } - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -/** - * Parse the 'sync info' and 'bit stream info' from the AC-3 bitstream. - * GetBitContext within AC3DecodeContext must point to - * the start of the synchronized AC-3 bitstream. - */ -static int ac3_parse_header(AC3DecodeContext *s) -{ - GetBitContext *gbc = &s->gbc; - int i; - - /* read the rest of the bsi. read twice for dual mono mode. */ - i = !(s->channel_mode); - do { - skip_bits(gbc, 5); // skip dialog normalization - if (get_bits1(gbc)) - skip_bits(gbc, 8); //skip compression - if (get_bits1(gbc)) - skip_bits(gbc, 8); //skip language code - if (get_bits1(gbc)) - skip_bits(gbc, 7); //skip audio production information - } while (i--); - - skip_bits(gbc, 2); //skip copyright bit and original bitstream bit - - /* skip the timecodes (or extra bitstream information for Alternate Syntax) - TODO: read & use the xbsi1 downmix levels */ - if (get_bits1(gbc)) - skip_bits(gbc, 14); //skip timecode1 / xbsi1 - if (get_bits1(gbc)) - skip_bits(gbc, 14); //skip timecode2 / xbsi2 - - /* skip additional bitstream info */ - if (get_bits1(gbc)) { - i = get_bits(gbc, 6); - do { - skip_bits(gbc, 8); - } while(i--); - } - - return 0; -} - -/** - * Common function to parse AC-3 or E-AC-3 frame header - */ -static int parse_frame_header(AC3DecodeContext *s) -{ - AC3HeaderInfo hdr; - int err; - - err = ff_ac3_parse_header(&s->gbc, &hdr); - if(err) - return err; - - /* get decoding parameters from header info */ - s->bit_alloc_params.sr_code = hdr.sr_code; - s->channel_mode = hdr.channel_mode; - s->channel_layout = hdr.channel_layout; - s->lfe_on = hdr.lfe_on; - s->bit_alloc_params.sr_shift = hdr.sr_shift; - s->sample_rate = hdr.sample_rate; - s->bit_rate = hdr.bit_rate; - s->channels = hdr.channels; - s->fbw_channels = s->channels - s->lfe_on; - s->lfe_ch = s->fbw_channels + 1; - s->frame_size = hdr.frame_size; - s->center_mix_level = hdr.center_mix_level; - s->surround_mix_level = hdr.surround_mix_level; - s->num_blocks = hdr.num_blocks; - s->frame_type = hdr.frame_type; - s->substreamid = hdr.substreamid; - - if(s->lfe_on) { - s->start_freq[s->lfe_ch] = 0; - s->end_freq[s->lfe_ch] = 7; - s->num_exp_groups[s->lfe_ch] = 2; - s->channel_in_cpl[s->lfe_ch] = 0; - } - - if (hdr.bitstream_id <= 10) { - s->eac3 = 0; - s->snr_offset_strategy = 2; - s->block_switch_syntax = 1; - s->dither_flag_syntax = 1; - s->bit_allocation_syntax = 1; - s->fast_gain_syntax = 0; - s->first_cpl_leak = 0; - s->dba_syntax = 1; - s->skip_syntax = 1; - memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht)); - return ac3_parse_header(s); - } else if (CONFIG_EAC3_DECODER) { - s->eac3 = 1; - return ff_eac3_parse_header(s); - } else { - av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n"); - return -1; - } -} - -/** - * Set stereo downmixing coefficients based on frame header info. - * reference: Section 7.8.2 Downmixing Into Two Channels - */ -static void set_downmix_coeffs(AC3DecodeContext *s) -{ - int i; - float cmix = gain_levels[center_levels[s->center_mix_level]]; - float smix = gain_levels[surround_levels[s->surround_mix_level]]; - float norm0, norm1; - - for(i=0; ifbw_channels; i++) { - s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; - s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; - } - if(s->channel_mode > 1 && s->channel_mode & 1) { - s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = cmix; - } - if(s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) { - int nf = s->channel_mode - 2; - s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB; - } - if(s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) { - int nf = s->channel_mode - 4; - s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix; - } - - /* renormalize */ - norm0 = norm1 = 0.0; - for(i=0; ifbw_channels; i++) { - norm0 += s->downmix_coeffs[i][0]; - norm1 += s->downmix_coeffs[i][1]; - } - norm0 = 1.0f / norm0; - norm1 = 1.0f / norm1; - for(i=0; ifbw_channels; i++) { - s->downmix_coeffs[i][0] *= norm0; - s->downmix_coeffs[i][1] *= norm1; - } - - if(s->output_mode == AC3_CHMODE_MONO) { - for(i=0; ifbw_channels; i++) - s->downmix_coeffs[i][0] = (s->downmix_coeffs[i][0] + s->downmix_coeffs[i][1]) * LEVEL_MINUS_3DB; - } -} - -/** - * Decode the grouped exponents according to exponent strategy. - * reference: Section 7.1.3 Exponent Decoding - */ -static int decode_exponents(GetBitContext *gbc, int exp_strategy, int ngrps, - uint8_t absexp, int8_t *dexps) -{ - int i, j, grp, group_size; - int dexp[256]; - int expacc, prevexp; - - /* unpack groups */ - group_size = exp_strategy + (exp_strategy == EXP_D45); - for(grp=0,i=0; grp 24U) - return -1; - switch (group_size) { - case 4: dexps[j++] = prevexp; - dexps[j++] = prevexp; - case 2: dexps[j++] = prevexp; - case 1: dexps[j++] = prevexp; - } - } - return 0; -} - -/** - * Generate transform coefficients for each coupled channel in the coupling - * range using the coupling coefficients and coupling coordinates. - * reference: Section 7.4.3 Coupling Coordinate Format - */ -static void calc_transform_coeffs_cpl(AC3DecodeContext *s) -{ - int bin, band, ch; - - bin = s->start_freq[CPL_CH]; - for (band = 0; band < s->num_cpl_bands; band++) { - int band_start = bin; - int band_end = bin + s->cpl_band_sizes[band]; - for (ch = 1; ch <= s->fbw_channels; ch++) { - if (s->channel_in_cpl[ch]) { - int cpl_coord = s->cpl_coords[ch][band] << 5; - for (bin = band_start; bin < band_end; bin++) { - s->fixed_coeffs[ch][bin] = MULH(s->fixed_coeffs[CPL_CH][bin] << 4, cpl_coord); - } - if (ch == 2 && s->phase_flags[band]) { - for (bin = band_start; bin < band_end; bin++) - s->fixed_coeffs[2][bin] = -s->fixed_coeffs[2][bin]; - } - } - } - bin = band_end; - } -} - -/** - * Grouped mantissas for 3-level 5-level and 11-level quantization - */ -typedef struct { - int b1_mant[2]; - int b2_mant[2]; - int b4_mant; - int b1; - int b2; - int b4; -} mant_groups; - -/** - * Decode the transform coefficients for a particular channel - * reference: Section 7.3 Quantization and Decoding of Mantissas - */ -static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m) -{ - int start_freq = s->start_freq[ch_index]; - int end_freq = s->end_freq[ch_index]; - uint8_t *baps = s->bap[ch_index]; - int8_t *exps = s->dexps[ch_index]; - int *coeffs = s->fixed_coeffs[ch_index]; - int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index]; - GetBitContext *gbc = &s->gbc; - int freq; - - for(freq = start_freq; freq < end_freq; freq++){ - int bap = baps[freq]; - int mantissa; - switch(bap){ - case 0: - if (dither) - mantissa = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000; - else - mantissa = 0; - break; - case 1: - if(m->b1){ - m->b1--; - mantissa = m->b1_mant[m->b1]; - } - else{ - int bits = get_bits(gbc, 5); - mantissa = b1_mantissas[bits][0]; - m->b1_mant[1] = b1_mantissas[bits][1]; - m->b1_mant[0] = b1_mantissas[bits][2]; - m->b1 = 2; - } - break; - case 2: - if(m->b2){ - m->b2--; - mantissa = m->b2_mant[m->b2]; - } - else{ - int bits = get_bits(gbc, 7); - mantissa = b2_mantissas[bits][0]; - m->b2_mant[1] = b2_mantissas[bits][1]; - m->b2_mant[0] = b2_mantissas[bits][2]; - m->b2 = 2; - } - break; - case 3: - mantissa = b3_mantissas[get_bits(gbc, 3)]; - break; - case 4: - if(m->b4){ - m->b4 = 0; - mantissa = m->b4_mant; - } - else{ - int bits = get_bits(gbc, 7); - mantissa = b4_mantissas[bits][0]; - m->b4_mant = b4_mantissas[bits][1]; - m->b4 = 1; - } - break; - case 5: - mantissa = b5_mantissas[get_bits(gbc, 4)]; - break; - default: /* 6 to 15 */ - mantissa = get_bits(gbc, quantization_tab[bap]); - /* Shift mantissa and sign-extend it. */ - mantissa = (mantissa << (32-quantization_tab[bap]))>>8; - break; - } - coeffs[freq] = mantissa >> exps[freq]; - } -} - -/** - * Remove random dithering from coupling range coefficients with zero-bit - * mantissas for coupled channels which do not use dithering. - * reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0) - */ -static void remove_dithering(AC3DecodeContext *s) { - int ch, i; - - for(ch=1; ch<=s->fbw_channels; ch++) { - if(!s->dither_flag[ch] && s->channel_in_cpl[ch]) { - for(i = s->start_freq[CPL_CH]; iend_freq[CPL_CH]; i++) { - if(!s->bap[CPL_CH][i]) - s->fixed_coeffs[ch][i] = 0; - } - } - } -} - -static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch, - mant_groups *m) -{ - if (!s->channel_uses_aht[ch]) { - ac3_decode_transform_coeffs_ch(s, ch, m); - } else { - /* if AHT is used, mantissas for all blocks are encoded in the first - block of the frame. */ - int bin; - if (!blk && CONFIG_EAC3_DECODER) - ff_eac3_decode_transform_coeffs_aht_ch(s, ch); - for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { - s->fixed_coeffs[ch][bin] = s->pre_mantissa[ch][bin][blk] >> s->dexps[ch][bin]; - } - } -} - -/** - * Decode the transform coefficients. - */ -static void decode_transform_coeffs(AC3DecodeContext *s, int blk) -{ - int ch, end; - int got_cplchan = 0; - mant_groups m; - - m.b1 = m.b2 = m.b4 = 0; - - for (ch = 1; ch <= s->channels; ch++) { - /* transform coefficients for full-bandwidth channel */ - decode_transform_coeffs_ch(s, blk, ch, &m); - /* tranform coefficients for coupling channel come right after the - coefficients for the first coupled channel*/ - if (s->channel_in_cpl[ch]) { - if (!got_cplchan) { - decode_transform_coeffs_ch(s, blk, CPL_CH, &m); - calc_transform_coeffs_cpl(s); - got_cplchan = 1; - } - end = s->end_freq[CPL_CH]; - } else { - end = s->end_freq[ch]; - } - do - s->fixed_coeffs[ch][end] = 0; - while(++end < 256); - } - - /* zero the dithered coefficients for appropriate channels */ - remove_dithering(s); -} - -/** - * Stereo rematrixing. - * reference: Section 7.5.4 Rematrixing : Decoding Technique - */ -static void do_rematrixing(AC3DecodeContext *s) -{ - int bnd, i; - int end, bndend; - - end = FFMIN(s->end_freq[1], s->end_freq[2]); - - for(bnd=0; bndnum_rematrixing_bands; bnd++) { - if(s->rematrixing_flags[bnd]) { - bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd+1]); - for(i=ff_ac3_rematrix_band_tab[bnd]; ifixed_coeffs[1][i]; - s->fixed_coeffs[1][i] += s->fixed_coeffs[2][i]; - s->fixed_coeffs[2][i] = tmp0 - s->fixed_coeffs[2][i]; - } - } - } -} - -/** - * Inverse MDCT Transform. - * Convert frequency domain coefficients to time-domain audio samples. - * reference: Section 7.9.4 Transformation Equations - */ -static inline void do_imdct(AC3DecodeContext *s, int channels) -{ - int ch; - float add_bias = s->add_bias; - if(s->out_channels==1 && channels>1) - add_bias *= LEVEL_MINUS_3DB; // compensate for the gain in downmix - - for (ch=1; ch<=channels; ch++) { - if (s->block_switch[ch]) { - int i; - float *x = s->tmp_output+128; - for(i=0; i<128; i++) - x[i] = s->transform_coeffs[ch][2*i]; - ff_imdct_half(&s->imdct_256, s->tmp_output, x); - s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, add_bias, 128); - for(i=0; i<128; i++) - x[i] = s->transform_coeffs[ch][2*i+1]; - ff_imdct_half(&s->imdct_256, s->delay[ch-1], x); - } else { - ff_imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]); - s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, add_bias, 128); - memcpy(s->delay[ch-1], s->tmp_output+128, 128*sizeof(float)); - } - } -} - -/** - * Downmix the output to mono or stereo. - */ -void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len) -{ - int i, j; - float v0, v1; - if(out_ch == 2) { - for(i=0; idelay[0]); - switch(s->channel_mode) { - case AC3_CHMODE_DUALMONO: - case AC3_CHMODE_STEREO: - /* upmix mono to stereo */ - memcpy(s->delay[1], s->delay[0], channel_data_size); - break; - case AC3_CHMODE_2F2R: - memset(s->delay[3], 0, channel_data_size); - case AC3_CHMODE_2F1R: - memset(s->delay[2], 0, channel_data_size); - break; - case AC3_CHMODE_3F2R: - memset(s->delay[4], 0, channel_data_size); - case AC3_CHMODE_3F1R: - memset(s->delay[3], 0, channel_data_size); - case AC3_CHMODE_3F: - memcpy(s->delay[2], s->delay[1], channel_data_size); - memset(s->delay[1], 0, channel_data_size); - break; - } -} - -/** - * Decode band structure for coupling, spectral extension, or enhanced coupling. - * The band structure defines how many subbands are in each band. For each - * subband in the range, 1 means it is combined with the previous band, and 0 - * means that it starts a new band. - * - * @param[in] gbc bit reader context - * @param[in] blk block number - * @param[in] eac3 flag to indicate E-AC-3 - * @param[in] ecpl flag to indicate enhanced coupling - * @param[in] start_subband subband number for start of range - * @param[in] end_subband subband number for end of range - * @param[in] default_band_struct default band structure table - * @param[out] num_bands number of bands (optionally NULL) - * @param[out] band_sizes array containing the number of bins in each band (optionally NULL) - */ -static void decode_band_structure(GetBitContext *gbc, int blk, int eac3, - int ecpl, int start_subband, int end_subband, - const uint8_t *default_band_struct, - int *num_bands, uint8_t *band_sizes) -{ - int subbnd, bnd, n_subbands, n_bands=0; - uint8_t bnd_sz[22]; - uint8_t coded_band_struct[22]; - const uint8_t *band_struct; - - n_subbands = end_subband - start_subband; - - /* decode band structure from bitstream or use default */ - if (!eac3 || get_bits1(gbc)) { - for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) { - coded_band_struct[subbnd] = get_bits1(gbc); - } - band_struct = coded_band_struct; - } else if (!blk) { - band_struct = &default_band_struct[start_subband+1]; - } else { - /* no change in band structure */ - return; - } - - /* calculate number of bands and band sizes based on band structure. - note that the first 4 subbands in enhanced coupling span only 6 bins - instead of 12. */ - if (num_bands || band_sizes ) { - n_bands = n_subbands; - bnd_sz[0] = ecpl ? 6 : 12; - for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) { - int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12; - if (band_struct[subbnd-1]) { - n_bands--; - bnd_sz[bnd] += subbnd_size; - } else { - bnd_sz[++bnd] = subbnd_size; - } - } - } - - /* set optional output params */ - if (num_bands) - *num_bands = n_bands; - if (band_sizes) - memcpy(band_sizes, bnd_sz, n_bands); -} - -/** - * Decode a single audio block from the AC-3 bitstream. - */ -static int decode_audio_block(AC3DecodeContext *s, int blk) -{ - int fbw_channels = s->fbw_channels; - int channel_mode = s->channel_mode; - int i, bnd, seg, ch; - int different_transforms; - int downmix_output; - int cpl_in_use; - GetBitContext *gbc = &s->gbc; - uint8_t bit_alloc_stages[AC3_MAX_CHANNELS]; - - memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS); - - /* block switch flags */ - different_transforms = 0; - if (s->block_switch_syntax) { - for (ch = 1; ch <= fbw_channels; ch++) { - s->block_switch[ch] = get_bits1(gbc); - if(ch > 1 && s->block_switch[ch] != s->block_switch[1]) - different_transforms = 1; - } - } - - /* dithering flags */ - if (s->dither_flag_syntax) { - for (ch = 1; ch <= fbw_channels; ch++) { - s->dither_flag[ch] = get_bits1(gbc); - } - } - - /* dynamic range */ - i = !(s->channel_mode); - do { - if(get_bits1(gbc)) { - s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)]-1.0) * - s->avctx->drc_scale)+1.0; - } else if(blk == 0) { - s->dynamic_range[i] = 1.0f; - } - } while(i--); - - /* spectral extension strategy */ - if (s->eac3 && (!blk || get_bits1(gbc))) { - s->spx_in_use = get_bits1(gbc); - if (s->spx_in_use) { - int dst_start_freq, dst_end_freq, src_start_freq, - start_subband, end_subband; - - /* determine which channels use spx */ - if (s->channel_mode == AC3_CHMODE_MONO) { - s->channel_uses_spx[1] = 1; - } else { - for (ch = 1; ch <= fbw_channels; ch++) - s->channel_uses_spx[ch] = get_bits1(gbc); - } - - /* get the frequency bins of the spx copy region and the spx start - and end subbands */ - dst_start_freq = get_bits(gbc, 2); - start_subband = get_bits(gbc, 3) + 2; - if (start_subband > 7) - start_subband += start_subband - 7; - end_subband = get_bits(gbc, 3) + 5; - if (end_subband > 7) - end_subband += end_subband - 7; - dst_start_freq = dst_start_freq * 12 + 25; - src_start_freq = start_subband * 12 + 25; - dst_end_freq = end_subband * 12 + 25; - - /* check validity of spx ranges */ - if (start_subband >= end_subband) { - av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " - "range (%d >= %d)\n", start_subband, end_subband); - return -1; - } - if (dst_start_freq >= src_start_freq) { - av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " - "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); - return -1; - } - - s->spx_dst_start_freq = dst_start_freq; - s->spx_src_start_freq = src_start_freq; - s->spx_dst_end_freq = dst_end_freq; - - decode_band_structure(gbc, blk, s->eac3, 0, - start_subband, end_subband, - ff_eac3_default_spx_band_struct, - &s->num_spx_bands, - s->spx_band_sizes); - } else { - for (ch = 1; ch <= fbw_channels; ch++) { - s->channel_uses_spx[ch] = 0; - s->first_spx_coords[ch] = 1; - } - } - } - - /* spectral extension coordinates */ - if (s->spx_in_use) { - for (ch = 1; ch <= fbw_channels; ch++) { - if (s->channel_uses_spx[ch]) { - if (s->first_spx_coords[ch] || get_bits1(gbc)) { - float spx_blend; - int bin, master_spx_coord; - - s->first_spx_coords[ch] = 0; - spx_blend = get_bits(gbc, 5) * (1.0f/32); - master_spx_coord = get_bits(gbc, 2) * 3; - - bin = s->spx_src_start_freq; - for (bnd = 0; bnd < s->num_spx_bands; bnd++) { - int bandsize; - int spx_coord_exp, spx_coord_mant; - float nratio, sblend, nblend, spx_coord; - - /* calculate blending factors */ - bandsize = s->spx_band_sizes[bnd]; - nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend; - nratio = av_clipf(nratio, 0.0f, 1.0f); - nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3) to give unity variance - sblend = sqrtf(1.0f - nratio); - bin += bandsize; - - /* decode spx coordinates */ - spx_coord_exp = get_bits(gbc, 4); - spx_coord_mant = get_bits(gbc, 2); - if (spx_coord_exp == 15) spx_coord_mant <<= 1; - else spx_coord_mant += 4; - spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); - spx_coord = spx_coord_mant * (1.0f/(1<<23)); - - /* multiply noise and signal blending factors by spx coordinate */ - s->spx_noise_blend [ch][bnd] = nblend * spx_coord; - s->spx_signal_blend[ch][bnd] = sblend * spx_coord; - } - } - } else { - s->first_spx_coords[ch] = 1; - } - } - } - - /* coupling strategy */ - if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) { - memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); - if (!s->eac3) - s->cpl_in_use[blk] = get_bits1(gbc); - if (s->cpl_in_use[blk]) { - /* coupling in use */ - int cpl_start_subband, cpl_end_subband; - - if (channel_mode < AC3_CHMODE_STEREO) { - av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); - return -1; - } - - /* check for enhanced coupling */ - if (s->eac3 && get_bits1(gbc)) { - /* TODO: parse enhanced coupling strategy info */ - av_log_missing_feature(s->avctx, "Enhanced coupling", 1); - return -1; - } - - /* determine which channels are coupled */ - if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) { - s->channel_in_cpl[1] = 1; - s->channel_in_cpl[2] = 1; - } else { - for (ch = 1; ch <= fbw_channels; ch++) - s->channel_in_cpl[ch] = get_bits1(gbc); - } - - /* phase flags in use */ - if (channel_mode == AC3_CHMODE_STEREO) - s->phase_flags_in_use = get_bits1(gbc); - - /* coupling frequency range */ - cpl_start_subband = get_bits(gbc, 4); - cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 : - get_bits(gbc, 4) + 3; - if (cpl_start_subband >= cpl_end_subband) { - av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", - cpl_start_subband, cpl_end_subband); - return -1; - } - s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; - s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; - - decode_band_structure(gbc, blk, s->eac3, 0, cpl_start_subband, - cpl_end_subband, - ff_eac3_default_cpl_band_struct, - &s->num_cpl_bands, s->cpl_band_sizes); - } else { - /* coupling not in use */ - for (ch = 1; ch <= fbw_channels; ch++) { - s->channel_in_cpl[ch] = 0; - s->first_cpl_coords[ch] = 1; - } - s->first_cpl_leak = s->eac3; - s->phase_flags_in_use = 0; - } - } else if (!s->eac3) { - if(!blk) { - av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must be present in block 0\n"); - return -1; - } else { - s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; - } - } - cpl_in_use = s->cpl_in_use[blk]; - - /* coupling coordinates */ - if (cpl_in_use) { - int cpl_coords_exist = 0; - - for (ch = 1; ch <= fbw_channels; ch++) { - if (s->channel_in_cpl[ch]) { - if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(gbc)) { - int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; - s->first_cpl_coords[ch] = 0; - cpl_coords_exist = 1; - master_cpl_coord = 3 * get_bits(gbc, 2); - for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { - cpl_coord_exp = get_bits(gbc, 4); - cpl_coord_mant = get_bits(gbc, 4); - if (cpl_coord_exp == 15) - s->cpl_coords[ch][bnd] = cpl_coord_mant << 22; - else - s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21; - s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord); - } - } else if (!blk) { - av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must be present in block 0\n"); - return -1; - } - } else { - /* channel not in coupling */ - s->first_cpl_coords[ch] = 1; - } - } - /* phase flags */ - if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) { - for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { - s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0; - } - } - } - - /* stereo rematrixing strategy and band structure */ - if (channel_mode == AC3_CHMODE_STEREO) { - if ((s->eac3 && !blk) || get_bits1(gbc)) { - s->num_rematrixing_bands = 4; - if (cpl_in_use && s->start_freq[CPL_CH] <= 61) { - s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37); - } else if (s->spx_in_use && s->spx_src_start_freq <= 61) { - s->num_rematrixing_bands--; - } - for(bnd=0; bndnum_rematrixing_bands; bnd++) - s->rematrixing_flags[bnd] = get_bits1(gbc); - } else if (!blk) { - av_log(s->avctx, AV_LOG_WARNING, "Warning: new rematrixing strategy not present in block 0\n"); - s->num_rematrixing_bands = 0; - } - } - - /* exponent strategies for each channel */ - for (ch = !cpl_in_use; ch <= s->channels; ch++) { - if (!s->eac3) - s->exp_strategy[blk][ch] = get_bits(gbc, 2 - (ch == s->lfe_ch)); - if(s->exp_strategy[blk][ch] != EXP_REUSE) - bit_alloc_stages[ch] = 3; - } - - /* channel bandwidth */ - for (ch = 1; ch <= fbw_channels; ch++) { - s->start_freq[ch] = 0; - if (s->exp_strategy[blk][ch] != EXP_REUSE) { - int group_size; - int prev = s->end_freq[ch]; - if (s->channel_in_cpl[ch]) - s->end_freq[ch] = s->start_freq[CPL_CH]; - else if (s->channel_uses_spx[ch]) - s->end_freq[ch] = s->spx_src_start_freq; - else { - int bandwidth_code = get_bits(gbc, 6); - if (bandwidth_code > 60) { - av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code); - return -1; - } - s->end_freq[ch] = bandwidth_code * 3 + 73; - } - group_size = 3 << (s->exp_strategy[blk][ch] - 1); - s->num_exp_groups[ch] = (s->end_freq[ch]+group_size-4) / group_size; - if(blk > 0 && s->end_freq[ch] != prev) - memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); - } - } - if (cpl_in_use && s->exp_strategy[blk][CPL_CH] != EXP_REUSE) { - s->num_exp_groups[CPL_CH] = (s->end_freq[CPL_CH] - s->start_freq[CPL_CH]) / - (3 << (s->exp_strategy[blk][CPL_CH] - 1)); - } - - /* decode exponents for each channel */ - for (ch = !cpl_in_use; ch <= s->channels; ch++) { - if (s->exp_strategy[blk][ch] != EXP_REUSE) { - s->dexps[ch][0] = get_bits(gbc, 4) << !ch; - if (decode_exponents(gbc, s->exp_strategy[blk][ch], - s->num_exp_groups[ch], s->dexps[ch][0], - &s->dexps[ch][s->start_freq[ch]+!!ch])) { - av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n"); - return -1; - } - if(ch != CPL_CH && ch != s->lfe_ch) - skip_bits(gbc, 2); /* skip gainrng */ - } - } - - /* bit allocation information */ - if (s->bit_allocation_syntax) { - if (get_bits1(gbc)) { - s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift; - s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift; - s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab[get_bits(gbc, 2)]; - s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[get_bits(gbc, 2)]; - s->bit_alloc_params.floor = ff_ac3_floor_tab[get_bits(gbc, 3)]; - for(ch=!cpl_in_use; ch<=s->channels; ch++) - bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); - } else if (!blk) { - av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must be present in block 0\n"); - return -1; - } - } - - /* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */ - if(!s->eac3 || !blk){ - if(s->snr_offset_strategy && get_bits1(gbc)) { - int snr = 0; - int csnr; - csnr = (get_bits(gbc, 6) - 15) << 4; - for (i = ch = !cpl_in_use; ch <= s->channels; ch++) { - /* snr offset */ - if (ch == i || s->snr_offset_strategy == 2) - snr = (csnr + get_bits(gbc, 4)) << 2; - /* run at least last bit allocation stage if snr offset changes */ - if(blk && s->snr_offset[ch] != snr) { - bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 1); - } - s->snr_offset[ch] = snr; - - /* fast gain (normal AC-3 only) */ - if (!s->eac3) { - int prev = s->fast_gain[ch]; - s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)]; - /* run last 2 bit allocation stages if fast gain changes */ - if(blk && prev != s->fast_gain[ch]) - bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); - } - } - } else if (!s->eac3 && !blk) { - av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n"); - return -1; - } - } - - /* fast gain (E-AC-3 only) */ - if (s->fast_gain_syntax && get_bits1(gbc)) { - for (ch = !cpl_in_use; ch <= s->channels; ch++) { - int prev = s->fast_gain[ch]; - s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)]; - /* run last 2 bit allocation stages if fast gain changes */ - if(blk && prev != s->fast_gain[ch]) - bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); - } - } else if (s->eac3 && !blk) { - for (ch = !cpl_in_use; ch <= s->channels; ch++) - s->fast_gain[ch] = ff_ac3_fast_gain_tab[4]; - } - - /* E-AC-3 to AC-3 converter SNR offset */ - if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && get_bits1(gbc)) { - skip_bits(gbc, 10); // skip converter snr offset - } - - /* coupling leak information */ - if (cpl_in_use) { - if (s->first_cpl_leak || get_bits1(gbc)) { - int fl = get_bits(gbc, 3); - int sl = get_bits(gbc, 3); - /* run last 2 bit allocation stages for coupling channel if - coupling leak changes */ - if(blk && (fl != s->bit_alloc_params.cpl_fast_leak || - sl != s->bit_alloc_params.cpl_slow_leak)) { - bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2); - } - s->bit_alloc_params.cpl_fast_leak = fl; - s->bit_alloc_params.cpl_slow_leak = sl; - } else if (!s->eac3 && !blk) { - av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must be present in block 0\n"); - return -1; - } - s->first_cpl_leak = 0; - } - - /* delta bit allocation information */ - if (s->dba_syntax && get_bits1(gbc)) { - /* delta bit allocation exists (strategy) */ - for (ch = !cpl_in_use; ch <= fbw_channels; ch++) { - s->dba_mode[ch] = get_bits(gbc, 2); - if (s->dba_mode[ch] == DBA_RESERVED) { - av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n"); - return -1; - } - bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); - } - /* channel delta offset, len and bit allocation */ - for (ch = !cpl_in_use; ch <= fbw_channels; ch++) { - if (s->dba_mode[ch] == DBA_NEW) { - s->dba_nsegs[ch] = get_bits(gbc, 3); - for (seg = 0; seg <= s->dba_nsegs[ch]; seg++) { - s->dba_offsets[ch][seg] = get_bits(gbc, 5); - s->dba_lengths[ch][seg] = get_bits(gbc, 4); - s->dba_values[ch][seg] = get_bits(gbc, 3); - } - /* run last 2 bit allocation stages if new dba values */ - bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); - } - } - } else if(blk == 0) { - for(ch=0; ch<=s->channels; ch++) { - s->dba_mode[ch] = DBA_NONE; - } - } - - /* Bit allocation */ - for(ch=!cpl_in_use; ch<=s->channels; ch++) { - if(bit_alloc_stages[ch] > 2) { - /* Exponent mapping into PSD and PSD integration */ - ff_ac3_bit_alloc_calc_psd(s->dexps[ch], - s->start_freq[ch], s->end_freq[ch], - s->psd[ch], s->band_psd[ch]); - } - if(bit_alloc_stages[ch] > 1) { - /* Compute excitation function, Compute masking curve, and - Apply delta bit allocation */ - if (ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch], - s->start_freq[ch], s->end_freq[ch], - s->fast_gain[ch], (ch == s->lfe_ch), - s->dba_mode[ch], s->dba_nsegs[ch], - s->dba_offsets[ch], s->dba_lengths[ch], - s->dba_values[ch], s->mask[ch])) { - av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n"); - return -1; - } - } - if(bit_alloc_stages[ch] > 0) { - /* Compute bit allocation */ - const uint8_t *bap_tab = s->channel_uses_aht[ch] ? - ff_eac3_hebap_tab : ff_ac3_bap_tab; - ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch], - s->start_freq[ch], s->end_freq[ch], - s->snr_offset[ch], - s->bit_alloc_params.floor, - bap_tab, s->bap[ch]); - } - } - - /* unused dummy data */ - if (s->skip_syntax && get_bits1(gbc)) { - int skipl = get_bits(gbc, 9); - while(skipl--) - skip_bits(gbc, 8); - } - - /* unpack the transform coefficients - this also uncouples channels if coupling is in use. */ - decode_transform_coeffs(s, blk); - - /* TODO: generate enhanced coupling coordinates and uncouple */ - - /* recover coefficients if rematrixing is in use */ - if(s->channel_mode == AC3_CHMODE_STEREO) - do_rematrixing(s); - - /* apply scaling to coefficients (headroom, dynrng) */ - for(ch=1; ch<=s->channels; ch++) { - float gain = s->mul_bias / 4194304.0f; - if(s->channel_mode == AC3_CHMODE_DUALMONO) { - gain *= s->dynamic_range[2-ch]; - } else { - gain *= s->dynamic_range[0]; - } - s->dsp.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256); - } - - /* apply spectral extension to high frequency bins */ - if (s->spx_in_use && CONFIG_EAC3_DECODER) { - ff_eac3_apply_spectral_extension(s); - } - - /* downmix and MDCT. order depends on whether block switching is used for - any channel in this block. this is because coefficients for the long - and short transforms cannot be mixed. */ - downmix_output = s->channels != s->out_channels && - !((s->output_mode & AC3_OUTPUT_LFEON) && - s->fbw_channels == s->out_channels); - if(different_transforms) { - /* the delay samples have already been downmixed, so we upmix the delay - samples in order to reconstruct all channels before downmixing. */ - if(s->downmixed) { - s->downmixed = 0; - ac3_upmix_delay(s); - } - - do_imdct(s, s->channels); - - if(downmix_output) { - s->dsp.ac3_downmix(s->output, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256); - } - } else { - if(downmix_output) { - s->dsp.ac3_downmix(s->transform_coeffs+1, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256); - } - - if(downmix_output && !s->downmixed) { - s->downmixed = 1; - s->dsp.ac3_downmix(s->delay, s->downmix_coeffs, s->out_channels, s->fbw_channels, 128); - } - - do_imdct(s, s->out_channels); - } - - return 0; -} - -/** - * Decode a single AC-3 frame. - */ -static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AC3DecodeContext *s = avctx->priv_data; - int16_t *out_samples = (int16_t *)data; - int blk, ch, err; - const uint8_t *channel_map; - const float *output[AC3_MAX_CHANNELS]; - - /* initialize the GetBitContext with the start of valid AC-3 Frame */ - if (s->input_buffer) { - /* copy input buffer to decoder context to avoid reading past the end - of the buffer, which can be caused by a damaged input stream. */ - memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); - init_get_bits(&s->gbc, s->input_buffer, buf_size * 8); - } else { - init_get_bits(&s->gbc, buf, buf_size * 8); - } - - /* parse the syncinfo */ - *data_size = 0; - err = parse_frame_header(s); - - if (err) { - switch(err) { - case AAC_AC3_PARSE_ERROR_SYNC: - av_log(avctx, AV_LOG_ERROR, "frame sync error\n"); - return -1; - case AAC_AC3_PARSE_ERROR_BSID: - av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n"); - break; - case AAC_AC3_PARSE_ERROR_SAMPLE_RATE: - av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); - break; - case AAC_AC3_PARSE_ERROR_FRAME_SIZE: - av_log(avctx, AV_LOG_ERROR, "invalid frame size\n"); - break; - case AAC_AC3_PARSE_ERROR_FRAME_TYPE: - /* skip frame if CRC is ok. otherwise use error concealment. */ - /* TODO: add support for substreams and dependent frames */ - if(s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) { - av_log(avctx, AV_LOG_ERROR, "unsupported frame type : skipping frame\n"); - return s->frame_size; - } else { - av_log(avctx, AV_LOG_ERROR, "invalid frame type\n"); - } - break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid header\n"); - break; - } - } else { - /* check that reported frame size fits in input buffer */ - if (s->frame_size > buf_size) { - av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); - err = AAC_AC3_PARSE_ERROR_FRAME_SIZE; - } else if (avctx->error_recognition >= FF_ER_CAREFUL) { - /* check for crc mismatch */ - if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size-2)) { - av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n"); - err = AAC_AC3_PARSE_ERROR_CRC; - } - } - } - - /* if frame is ok, set audio parameters */ - if (!err) { - avctx->sample_rate = s->sample_rate; - avctx->bit_rate = s->bit_rate; - - /* channel config */ - s->out_channels = s->channels; - s->output_mode = s->channel_mode; - if(s->lfe_on) - s->output_mode |= AC3_OUTPUT_LFEON; - if (avctx->request_channels > 0 && avctx->request_channels <= 2 && - avctx->request_channels < s->channels) { - s->out_channels = avctx->request_channels; - s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; - s->channel_layout = ff_ac3_channel_layout_tab[s->output_mode]; - } - avctx->channels = s->out_channels; - avctx->channel_layout = s->channel_layout; - - /* set downmixing coefficients if needed */ - if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && - s->fbw_channels == s->out_channels)) { - set_downmix_coeffs(s); - } - } else if (!s->out_channels) { - s->out_channels = avctx->channels; - if(s->out_channels < s->channels) - s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; - } - - /* decode the audio blocks */ - channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; - for (ch = 0; ch < s->out_channels; ch++) - output[ch] = s->output[channel_map[ch]]; - for (blk = 0; blk < s->num_blocks; blk++) { - if (!err && decode_audio_block(s, blk)) { - av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n"); - err = 1; - } - s->dsp.float_to_int16_interleave(out_samples, output, 256, s->out_channels); - out_samples += 256 * s->out_channels; - } - *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t); - return FFMIN(buf_size, s->frame_size); -} - -/** - * Uninitialize the AC-3 decoder. - */ -static av_cold int ac3_decode_end(AVCodecContext *avctx) -{ - AC3DecodeContext *s = avctx->priv_data; - ff_mdct_end(&s->imdct_512); - ff_mdct_end(&s->imdct_256); - - av_freep(&s->input_buffer); - - return 0; -} - -AVCodec ac3_decoder = { - .name = "ac3", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_AC3, - .priv_data_size = sizeof (AC3DecodeContext), - .init = ac3_decode_init, - .close = ac3_decode_end, - .decode = ac3_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), -}; - -#if CONFIG_EAC3_DECODER -AVCodec eac3_decoder = { - .name = "eac3", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_EAC3, - .priv_data_size = sizeof (AC3DecodeContext), - .init = ac3_decode_init, - .close = ac3_decode_end, - .decode = ac3_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3dec.h b/tizen/distrib/ffmpeg/libavcodec/ac3dec.h deleted file mode 100644 index 8c0d442..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3dec.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Common code between the AC-3 and E-AC-3 decoders - * Copyright (c) 2007 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Common code between the AC-3 and E-AC-3 decoders. - * - * Summary of MDCT Coefficient Grouping: - * The individual MDCT coefficient indices are often referred to in the - * (E-)AC-3 specification as frequency bins. These bins are grouped together - * into subbands of 12 coefficients each. The subbands are grouped together - * into bands as defined in the bitstream by the band structures, which - * determine the number of bands and the size of each band. The full spectrum - * of 256 frequency bins is divided into 1 DC bin + 21 subbands = 253 bins. - * This system of grouping coefficients is used for channel bandwidth, stereo - * rematrixing, channel coupling, enhanced coupling, and spectral extension. - * - * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+ - * |1| |12| | [12|12|12|12] | | | | | | | | | | | | |3| - * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+ - * ~~~ ~~~~ ~~~~~~~~~~~~~ ~~~ - * | | | | - * | | | 3 unused frequency bins--+ - * | | | - * | | +--1 band containing 4 subbands - * | | - * | +--1 subband of 12 frequency bins - * | - * +--DC frequency bin - */ - -#ifndef AVCODEC_AC3DEC_H -#define AVCODEC_AC3DEC_H - -#include "libavutil/lfg.h" -#include "ac3.h" -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" - -/* override ac3.h to include coupling channel */ -#undef AC3_MAX_CHANNELS -#define AC3_MAX_CHANNELS 7 -#define CPL_CH 0 - -#define AC3_OUTPUT_LFEON 8 - -#define AC3_MAX_COEFS 256 -#define AC3_BLOCK_SIZE 256 -#define MAX_BLOCKS 6 -#define SPX_MAX_BANDS 17 - -typedef struct { - AVCodecContext *avctx; ///< parent context - GetBitContext gbc; ///< bitstream reader - uint8_t *input_buffer; ///< temp buffer to prevent overread - -///@defgroup bsi bit stream information -///@{ - int frame_type; ///< frame type (strmtyp) - int substreamid; ///< substream identification - int frame_size; ///< current frame size, in bytes - int bit_rate; ///< stream bit rate, in bits-per-second - int sample_rate; ///< sample frequency, in Hz - int num_blocks; ///< number of audio blocks - int channel_mode; ///< channel mode (acmod) - int channel_layout; ///< channel layout - int lfe_on; ///< lfe channel in use - int channel_map; ///< custom channel map - int center_mix_level; ///< Center mix level index - int surround_mix_level; ///< Surround mix level index - int eac3; ///< indicates if current frame is E-AC-3 -///@} - -///@defgroup audfrm frame syntax parameters - int snr_offset_strategy; ///< SNR offset strategy (snroffststr) - int block_switch_syntax; ///< block switch syntax enabled (blkswe) - int dither_flag_syntax; ///< dither flag syntax enabled (dithflage) - int bit_allocation_syntax; ///< bit allocation model syntax enabled (bamode) - int fast_gain_syntax; ///< fast gain codes enabled (frmfgaincode) - int dba_syntax; ///< delta bit allocation syntax enabled (dbaflde) - int skip_syntax; ///< skip field syntax enabled (skipflde) - ///@} - -///@defgroup cpl standard coupling - int cpl_in_use[MAX_BLOCKS]; ///< coupling in use (cplinu) - int cpl_strategy_exists[MAX_BLOCKS]; ///< coupling strategy exists (cplstre) - int channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) - int phase_flags_in_use; ///< phase flags in use (phsflginu) - int phase_flags[18]; ///< phase flags (phsflg) - int num_cpl_bands; ///< number of coupling bands (ncplbnd) - uint8_t cpl_band_sizes[18]; ///< number of coeffs in each coupling band - int firstchincpl; ///< first channel in coupling - int first_cpl_coords[AC3_MAX_CHANNELS]; ///< first coupling coordinates states (firstcplcos) - int cpl_coords[AC3_MAX_CHANNELS][18]; ///< coupling coordinates (cplco) -///@} - -///@defgroup spx spectral extension -///@{ - int spx_in_use; ///< spectral extension in use (spxinu) - uint8_t channel_uses_spx[AC3_MAX_CHANNELS]; ///< channel uses spectral extension (chinspx) - int8_t spx_atten_code[AC3_MAX_CHANNELS]; ///< spx attenuation code (spxattencod) - int spx_src_start_freq; ///< spx start frequency bin - int spx_dst_end_freq; ///< spx end frequency bin - int spx_dst_start_freq; ///< spx starting frequency bin for copying (copystartmant) - ///< the copy region ends at the start of the spx region. - int num_spx_bands; ///< number of spx bands (nspxbnds) - uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each spx band - uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos) - float spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact) - float spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact) -///@} - -///@defgroup aht adaptive hybrid transform - int channel_uses_aht[AC3_MAX_CHANNELS]; ///< channel AHT in use (chahtinu) - int pre_mantissa[AC3_MAX_CHANNELS][AC3_MAX_COEFS][MAX_BLOCKS]; ///< pre-IDCT mantissas -///@} - -///@defgroup channel channel - int fbw_channels; ///< number of full-bandwidth channels - int channels; ///< number of total channels - int lfe_ch; ///< index of LFE channel - float downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients - int downmixed; ///< indicates if coeffs are currently downmixed - int output_mode; ///< output channel configuration - int out_channels; ///< number of output channels -///@} - -///@defgroup dynrng dynamic range - float dynamic_range[2]; ///< dynamic range -///@} - -///@defgroup bandwidth bandwidth - int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant) - int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant) -///@} - -///@defgroup rematrixing rematrixing - int num_rematrixing_bands; ///< number of rematrixing bands (nrematbnd) - int rematrixing_flags[4]; ///< rematrixing flags (rematflg) -///@} - -///@defgroup exponents exponents - int num_exp_groups[AC3_MAX_CHANNELS]; ///< Number of exponent groups (nexpgrp) - int8_t dexps[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< decoded exponents - int exp_strategy[MAX_BLOCKS][AC3_MAX_CHANNELS]; ///< exponent strategies (expstr) -///@} - -///@defgroup bitalloc bit allocation - AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters - int first_cpl_leak; ///< first coupling leak state (firstcplleak) - int snr_offset[AC3_MAX_CHANNELS]; ///< signal-to-noise ratio offsets (snroffst) - int fast_gain[AC3_MAX_CHANNELS]; ///< fast gain values/SMR's (fgain) - uint8_t bap[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< bit allocation pointers - int16_t psd[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< scaled exponents - int16_t band_psd[AC3_MAX_CHANNELS][50]; ///< interpolated exponents - int16_t mask[AC3_MAX_CHANNELS][50]; ///< masking curve values - int dba_mode[AC3_MAX_CHANNELS]; ///< delta bit allocation mode - int dba_nsegs[AC3_MAX_CHANNELS]; ///< number of delta segments - uint8_t dba_offsets[AC3_MAX_CHANNELS][8]; ///< delta segment offsets - uint8_t dba_lengths[AC3_MAX_CHANNELS][8]; ///< delta segment lengths - uint8_t dba_values[AC3_MAX_CHANNELS][8]; ///< delta values for each segment -///@} - -///@defgroup dithering zero-mantissa dithering - int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags (dithflg) - AVLFG dith_state; ///< for dither generation -///@} - -///@defgroup imdct IMDCT - int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags (blksw) - FFTContext imdct_512; ///< for 512 sample IMDCT - FFTContext imdct_256; ///< for 256 sample IMDCT -///@} - -///@defgroup opt optimization - DSPContext dsp; ///< for optimization - float add_bias; ///< offset for float_to_int16 conversion - float mul_bias; ///< scaling for float_to_int16 conversion -///@} - -///@defgroup arrays aligned arrays - DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///> fixed-point transform coefficients - DECLARE_ALIGNED(16, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients - DECLARE_ALIGNED(16, float, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block - DECLARE_ALIGNED(16, float, window)[AC3_BLOCK_SIZE]; ///< window coefficients - DECLARE_ALIGNED(16, float, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing - DECLARE_ALIGNED(16, float, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing -///@} -} AC3DecodeContext; - -/** - * Parse the E-AC-3 frame header. - * This parses both the bit stream info and audio frame header. - */ -int ff_eac3_parse_header(AC3DecodeContext *s); - -/** - * Decode mantissas in a single channel for the entire frame. - * This is used when AHT mode is enabled. - */ -void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch); - -void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2], - int out_ch, int in_ch, int len); - -/** - * Apply spectral extension to each channel by copying lower frequency - * coefficients to higher frequency bins and applying side information to - * approximate the original high frequency signal. - */ -void ff_eac3_apply_spectral_extension(AC3DecodeContext *s); - -#endif /* AVCODEC_AC3DEC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3dec_data.c b/tizen/distrib/ffmpeg/libavcodec/ac3dec_data.c deleted file mode 100644 index ea13d3d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3dec_data.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * AC-3 and E-AC-3 decoder tables - * Copyright (c) 2007 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Tables taken directly from the AC-3 spec. - */ - -#include "ac3dec_data.h" -#include "ac3.h" - -/** - * Table used to ungroup 3 values stored in 5 bits. - * Used by bap=1 mantissas and GAQ. - * ff_ac3_ungroup_3_in_5_bits_tab[i] = { i/9, (i%9)/3, (i%9)%3 } - */ -const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3] = { - { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 2 }, { 0, 1, 0 }, - { 0, 1, 1 }, { 0, 1, 2 }, { 0, 2, 0 }, { 0, 2, 1 }, - { 0, 2, 2 }, { 1, 0, 0 }, { 1, 0, 1 }, { 1, 0, 2 }, - { 1, 1, 0 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 2, 0 }, - { 1, 2, 1 }, { 1, 2, 2 }, { 2, 0, 0 }, { 2, 0, 1 }, - { 2, 0, 2 }, { 2, 1, 0 }, { 2, 1, 1 }, { 2, 1, 2 }, - { 2, 2, 0 }, { 2, 2, 1 }, { 2, 2, 2 }, { 3, 0, 0 }, - { 3, 0, 1 }, { 3, 0, 2 }, { 3, 1, 0 }, { 3, 1, 1 } -}; - -/** - * Table of bin locations for rematrixing bands - * reference: Section 7.5.2 Rematrixing : Frequency Band Definitions - */ -const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 }; - -const uint8_t ff_eac3_hebap_tab[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, - 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, - 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, - 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, - 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, - 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, - 19, 19, 19, 19, -}; - -/** - * Table E2.16 Default Coupling Banding Structure - */ -const uint8_t ff_eac3_default_cpl_band_struct[18] = -{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 }; - -/** - * Table E2.15 Default Spectral Extension Banding Structure - */ -const uint8_t ff_eac3_default_spx_band_struct[17] = -{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3dec_data.h b/tizen/distrib/ffmpeg/libavcodec/ac3dec_data.h deleted file mode 100644 index 9ed7c73..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3dec_data.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * AC-3 and E-AC-3 decoder tables - * Copyright (c) 2007 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AC3DEC_DATA_H -#define AVCODEC_AC3DEC_DATA_H - -#include - -extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; -extern const uint8_t ff_ac3_rematrix_band_tab[5]; - -extern const uint8_t ff_eac3_hebap_tab[64]; -extern const uint8_t ff_eac3_default_cpl_band_struct[18]; -extern const uint8_t ff_eac3_default_spx_band_struct[17]; - -#endif /* AVCODEC_AC3DEC_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ac3enc.c b/tizen/distrib/ffmpeg/libavcodec/ac3enc.c deleted file mode 100644 index e30e1bd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ac3enc.c +++ /dev/null @@ -1,1425 +0,0 @@ -/* - * The simplest AC-3 encoder - * Copyright (c) 2000 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * The simplest AC-3 encoder. - */ -//#define DEBUG -//#define DEBUG_BITALLOC -#include "libavutil/crc.h" -#include "avcodec.h" -#include "libavutil/common.h" /* for av_reverse */ -#include "put_bits.h" -#include "ac3.h" -#include "audioconvert.h" - -typedef struct AC3EncodeContext { - PutBitContext pb; - int nb_channels; - int nb_all_channels; - int lfe_channel; - const uint8_t *channel_map; - int bit_rate; - unsigned int sample_rate; - unsigned int bitstream_id; - 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 sr_shift; - unsigned int frame_size_code; - unsigned int sr_code; /* frequency */ - unsigned int channel_mode; - int lfe; - unsigned int bitstream_mode; - short last_samples[AC3_MAX_CHANNELS][256]; - unsigned int chbwcod[AC3_MAX_CHANNELS]; - int nb_coefs[AC3_MAX_CHANNELS]; - - /* bitrate allocation control */ - int slow_gain_code, slow_decay_code, fast_decay_code, db_per_bit_code, floor_code; - AC3BitAllocParameters bit_alloc; - int coarse_snr_offset; - int fast_gain_code[AC3_MAX_CHANNELS]; - int fine_snr_offset[AC3_MAX_CHANNELS]; - /* mantissa encoding */ - int mant1_cnt, mant2_cnt, mant4_cnt; -} AC3EncodeContext; - -static int16_t costab[64]; -static int16_t sintab[64]; -static int16_t xcos1[128]; -static int16_t xsin1[128]; - -#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 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; -} - -typedef struct IComplex { - short re,im; -} IComplex; - -static av_cold void fft_init(int ln) -{ - int i, 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)); - } -} - -/* 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 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> (8 - ln); - if (k < j) - FFSWAP(IComplex, z[k], z[j]); - } - - /* 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; - 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 void bit_alloc_masking(AC3EncodeContext *s, - uint8_t encoded_exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], - uint8_t exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS], - int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], - int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50]) -{ - int blk, ch; - int16_t band_psd[NB_BLOCKS][AC3_MAX_CHANNELS][50]; - - for(blk=0; blknb_all_channels;ch++) { - if(exp_strategy[blk][ch] == EXP_REUSE) { - memcpy(psd[blk][ch], psd[blk-1][ch], (N/2)*sizeof(int16_t)); - memcpy(mask[blk][ch], mask[blk-1][ch], 50*sizeof(int16_t)); - } else { - ff_ac3_bit_alloc_calc_psd(encoded_exp[blk][ch], 0, - s->nb_coefs[ch], - psd[blk][ch], band_psd[blk][ch]); - ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, band_psd[blk][ch], - 0, s->nb_coefs[ch], - ff_ac3_fast_gain_tab[s->fast_gain_code[ch]], - ch == s->lfe_channel, - DBA_NONE, 0, NULL, NULL, NULL, - mask[blk][ch]); - } - } - } -} - -static int bit_alloc(AC3EncodeContext *s, - int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50], - int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], - uint8_t bap[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], - int frame_bits, int coarse_snr_offset, int fine_snr_offset) -{ - int i, ch; - int snr_offset; - - snr_offset = (((coarse_snr_offset - 15) << 4) + fine_snr_offset) << 2; - - /* compute size */ - for(i=0;imant1_cnt = 0; - s->mant2_cnt = 0; - s->mant4_cnt = 0; - for(ch=0;chnb_all_channels;ch++) { - ff_ac3_bit_alloc_calc_bap(mask[i][ch], psd[i][ch], 0, - s->nb_coefs[ch], snr_offset, - s->bit_alloc.floor, ff_ac3_bap_tab, - bap[i][ch]); - 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", - coarse_snr_offset, fine_snr_offset, 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 coarse_snr_offset, fine_snr_offset; - uint8_t bap1[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; - int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; - int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50]; - static const int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; - - /* init default parameters */ - s->slow_decay_code = 2; - s->fast_decay_code = 1; - s->slow_gain_code = 1; - s->db_per_bit_code = 2; - s->floor_code = 4; - for(ch=0;chnb_all_channels;ch++) - s->fast_gain_code[ch] = 4; - - /* compute real values */ - s->bit_alloc.sr_code = s->sr_code; - s->bit_alloc.sr_shift = s->sr_shift; - s->bit_alloc.slow_decay = ff_ac3_slow_decay_tab[s->slow_decay_code] >> s->sr_shift; - s->bit_alloc.fast_decay = ff_ac3_fast_decay_tab[s->fast_decay_code] >> s->sr_shift; - s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code]; - s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code]; - s->bit_alloc.floor = ff_ac3_floor_tab[s->floor_code]; - - /* header size */ - frame_bits += 65; - // if (s->channel_mode == 2) - // frame_bits += 2; - frame_bits += frame_bits_inc[s->channel_mode]; - - /* audio blocks */ - for(i=0;inb_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */ - if (s->channel_mode == AC3_CHMODE_STEREO) { - 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; - - /* calculate psd and masking curve before doing bit allocation */ - bit_alloc_masking(s, encoded_exp, exp_strategy, psd, mask); - - /* now the big work begins : do the bit allocation. Modify the snr - offset until we can pack everything in the requested frame size */ - - coarse_snr_offset = s->coarse_snr_offset; - while (coarse_snr_offset >= 0 && - bit_alloc(s, mask, psd, bap, frame_bits, coarse_snr_offset, 0) < 0) - coarse_snr_offset -= SNR_INC1; - if (coarse_snr_offset < 0) { - av_log(NULL, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n"); - return -1; - } - while ((coarse_snr_offset + SNR_INC1) <= 63 && - bit_alloc(s, mask, psd, bap1, frame_bits, - coarse_snr_offset + SNR_INC1, 0) >= 0) { - coarse_snr_offset += SNR_INC1; - memcpy(bap, bap1, sizeof(bap1)); - } - while ((coarse_snr_offset + 1) <= 63 && - bit_alloc(s, mask, psd, bap1, frame_bits, coarse_snr_offset + 1, 0) >= 0) { - coarse_snr_offset++; - memcpy(bap, bap1, sizeof(bap1)); - } - - fine_snr_offset = 0; - while ((fine_snr_offset + SNR_INC1) <= 15 && - bit_alloc(s, mask, psd, bap1, frame_bits, - coarse_snr_offset, fine_snr_offset + SNR_INC1) >= 0) { - fine_snr_offset += SNR_INC1; - memcpy(bap, bap1, sizeof(bap1)); - } - while ((fine_snr_offset + 1) <= 15 && - bit_alloc(s, mask, psd, bap1, frame_bits, - coarse_snr_offset, fine_snr_offset + 1) >= 0) { - fine_snr_offset++; - memcpy(bap, bap1, sizeof(bap1)); - } - - s->coarse_snr_offset = coarse_snr_offset; - for(ch=0;chnb_all_channels;ch++) - s->fine_snr_offset[ch] = fine_snr_offset; -#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; -} - -static av_cold int set_channel_info(AC3EncodeContext *s, int channels, - int64_t *channel_layout) -{ - int ch_layout; - - if (channels < 1 || channels > AC3_MAX_CHANNELS) - return -1; - if ((uint64_t)*channel_layout > 0x7FF) - return -1; - ch_layout = *channel_layout; - if (!ch_layout) - ch_layout = avcodec_guess_channel_layout(channels, CODEC_ID_AC3, NULL); - if (avcodec_channel_layout_num_channels(ch_layout) != channels) - return -1; - - s->lfe = !!(ch_layout & CH_LOW_FREQUENCY); - s->nb_all_channels = channels; - s->nb_channels = channels - s->lfe; - s->lfe_channel = s->lfe ? s->nb_channels : -1; - if (s->lfe) - ch_layout -= CH_LOW_FREQUENCY; - - switch (ch_layout) { - case CH_LAYOUT_MONO: s->channel_mode = AC3_CHMODE_MONO; break; - case CH_LAYOUT_STEREO: s->channel_mode = AC3_CHMODE_STEREO; break; - case CH_LAYOUT_SURROUND: s->channel_mode = AC3_CHMODE_3F; break; - case CH_LAYOUT_2_1: s->channel_mode = AC3_CHMODE_2F1R; break; - case CH_LAYOUT_4POINT0: s->channel_mode = AC3_CHMODE_3F1R; break; - case CH_LAYOUT_QUAD: - case CH_LAYOUT_2_2: s->channel_mode = AC3_CHMODE_2F2R; break; - case CH_LAYOUT_5POINT0: - case CH_LAYOUT_5POINT0_BACK: s->channel_mode = AC3_CHMODE_3F2R; break; - default: - return -1; - } - - s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe]; - *channel_layout = ch_layout; - if (s->lfe) - *channel_layout |= CH_LOW_FREQUENCY; - - return 0; -} - -static av_cold int AC3_encode_init(AVCodecContext *avctx) -{ - int freq = avctx->sample_rate; - int bitrate = avctx->bit_rate; - AC3EncodeContext *s = avctx->priv_data; - int i, j, ch; - float alpha; - int bw_code; - - avctx->frame_size = AC3_FRAME_SIZE; - - ac3_common_init(); - - if (!avctx->channel_layout) { - av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The " - "encoder will guess the layout, but it " - "might be incorrect.\n"); - } - if (set_channel_info(s, avctx->channels, &avctx->channel_layout)) { - av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n"); - return -1; - } - - /* frequency */ - for(i=0;i<3;i++) { - for(j=0;j<3;j++) - if ((ff_ac3_sample_rate_tab[j] >> i) == freq) - goto found; - } - return -1; - found: - s->sample_rate = freq; - s->sr_shift = i; - s->sr_code = j; - s->bitstream_id = 8 + s->sr_shift; - s->bitstream_mode = 0; /* complete main audio service */ - - /* bitrate & frame size */ - for(i=0;i<19;i++) { - if ((ff_ac3_bitrate_tab[i] >> s->sr_shift)*1000 == bitrate) - break; - } - if (i == 19) - return -1; - s->bit_rate = bitrate; - s->frame_size_code = i << 1; - s->frame_size_min = ff_ac3_frame_size_tab[s->frame_size_code][s->sr_code]; - s->bits_written = 0; - s->samples_written = 0; - s->frame_size = s->frame_size_min; - - /* bit allocation init */ - if(avctx->cutoff) { - /* calculate bandwidth based on user-specified cutoff frequency */ - int cutoff = av_clip(avctx->cutoff, 1, s->sample_rate >> 1); - int fbw_coeffs = cutoff * 512 / s->sample_rate; - bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); - } else { - /* use default bandwidth setting */ - /* XXX: should compute the bandwidth according to the frame - size, so that we avoid annoying high frequency artifacts */ - bw_code = 50; - } - for(ch=0;chnb_channels;ch++) { - /* bandwidth for each channel */ - s->chbwcod[ch] = bw_code; - s->nb_coefs[ch] = bw_code * 3 + 73; - } - if (s->lfe) { - s->nb_coefs[s->lfe_channel] = 7; /* fixed */ - } - /* initial snr offset */ - s->coarse_snr_offset = 40; - - /* mdct init */ - fft_init(MDCT_NBITS - 2); - for(i=0;icoded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; -} - -/* output the AC-3 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->sr_code); - put_bits(&s->pb, 6, s->frame_size_code + (s->frame_size - s->frame_size_min)); - put_bits(&s->pb, 5, s->bitstream_id); - put_bits(&s->pb, 3, s->bitstream_mode); - put_bits(&s->pb, 3, s->channel_mode); - if ((s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO) - put_bits(&s->pb, 2, 1); /* XXX -4.5 dB */ - if (s->channel_mode & 0x04) - put_bits(&s->pb, 2, 1); /* XXX -6 dB */ - if (s->channel_mode == AC3_CHMODE_STEREO) - 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 additional 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 AC-3 - 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->channel_mode == AC3_CHMODE_STEREO) - { - 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->slow_decay_code); - put_bits(&s->pb, 2, s->fast_decay_code); - put_bits(&s->pb, 2, s->slow_gain_code); - put_bits(&s->pb, 2, s->db_per_bit_code); - put_bits(&s->pb, 3, s->floor_code); - } - - /* snr offset */ - put_bits(&s->pb, 1, baie); /* always present with bai */ - if (baie) { - put_bits(&s->pb, 6, s->coarse_snr_offset); - for(ch=0;chnb_all_channels;ch++) { - put_bits(&s->pb, 4, s->fine_snr_offset[ch]); - put_bits(&s->pb, 3, s->fast_gain_code[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 - (put_bits_ptr(&s->pb) - frame) - 2; - assert(n >= 0); - if(n>0) - memset(put_bits_ptr(&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_crc_get_table(AV_CRC_16_ANSI), 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); - AV_WB16(frame+2,crc1); - - crc2 = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, - frame + 2 * frame_size_58, - (frame_size - frame_size_58) * 2 - 2)); - AV_WB16(frame+2*frame_size-2,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++) { - int ich = s->channel_map[ch]; - /* fixed mdct to the six sub blocks & exponent computation */ - for(i=0;ilast_samples[ich], N/2 * sizeof(int16_t)); - sinc = s->nb_all_channels; - sptr = samples + (sinc * (N/2) * i) + ich; - for(j=0;jlast_samples[ich][j] = v; - sptr += sinc; - } - - /* apply the MDCT window */ - for(j=0;j> 15; - input_samples[N-j-1] = MUL16(input_samples[N-j-1], - ff_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 && s->samples_written >= s->sample_rate) { - s->bits_written -= s->bit_rate; - 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); - 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 */ - -#undef random -#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 - -#include "avcodec.h" -#include "acelp_filters.h" - -const int16_t ff_acelp_interp_filter[61] = { /* (0.15) */ - 29443, 28346, 25207, 20449, 14701, 8693, - 3143, -1352, -4402, -5865, -5850, -4673, - -2783, -672, 1211, 2536, 3130, 2991, - 2259, 1170, 0, -1001, -1652, -1868, - -1666, -1147, -464, 218, 756, 1060, - 1099, 904, 550, 135, -245, -514, - -634, -602, -451, -231, 0, 191, - 308, 340, 296, 198, 78, -36, - -120, -163, -165, -132, -79, -19, - 34, 73, 91, 89, 70, 38, - 0, -}; - -void ff_acelp_interpolate(int16_t* out, const int16_t* in, - const int16_t* filter_coeffs, int precision, - int frac_pos, int filter_length, int length) -{ - int n, i; - - assert(frac_pos >= 0 && frac_pos < precision); - - for (n = 0; n < length; n++) { - int idx = 0; - int v = 0x4000; - - for (i = 0; i < filter_length;) { - - /* The reference G.729 and AMR fixed point code performs clipping after - each of the two following accumulations. - Since clipping affects only the synthetic OVERFLOW test without - causing an int type overflow, it was moved outside the loop. */ - - /* R(x):=ac_v[-k+x] - v += R(n-i)*ff_acelp_interp_filter(t+6i) - v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */ - - v += in[n + i] * filter_coeffs[idx + frac_pos]; - idx += precision; - i++; - v += in[n - i] * filter_coeffs[idx - frac_pos]; - } - if (av_clip_int16(v >> 15) != (v >> 15)) - av_log(NULL, AV_LOG_WARNING, "overflow that would need cliping in ff_acelp_interpolate()\n"); - out[n] = v >> 15; - } -} - -void ff_acelp_interpolatef(float *out, const float *in, - const float *filter_coeffs, int precision, - int frac_pos, int filter_length, int length) -{ - int n, i; - - for (n = 0; n < length; n++) { - int idx = 0; - float v = 0; - - for (i = 0; i < filter_length;) { - v += in[n + i] * filter_coeffs[idx + frac_pos]; - idx += precision; - i++; - v += in[n - i] * filter_coeffs[idx - frac_pos]; - } - out[n] = v; - } -} - - -void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2], - const int16_t* in, int length) -{ - int i; - int tmp; - - for (i = 0; i < length; i++) { - tmp = (hpf_f[0]* 15836LL) >> 13; - tmp += (hpf_f[1]* -7667LL) >> 13; - tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]); - - /* With "+0x800" rounding, clipping is needed - for ALGTHM and SPEECH tests. */ - out[i] = av_clip_int16((tmp + 0x800) >> 12); - - hpf_f[1] = hpf_f[0]; - hpf_f[0] = tmp; - } -} - -void ff_acelp_apply_order_2_transfer_function(float *out, const float *in, - const float zero_coeffs[2], - const float pole_coeffs[2], - float gain, float mem[2], int n) -{ - int i; - float tmp; - - for (i = 0; i < n; i++) { - tmp = gain * in[i] - pole_coeffs[0] * mem[0] - pole_coeffs[1] * mem[1]; - out[i] = tmp + zero_coeffs[0] * mem[0] + zero_coeffs[1] * mem[1]; - - mem[1] = mem[0]; - mem[0] = tmp; - } -} - -void ff_tilt_compensation(float *mem, float tilt, float *samples, int size) -{ - float new_tilt_mem = samples[size - 1]; - int i; - - for (i = size - 1; i > 0; i--) - samples[i] -= tilt * samples[i - 1]; - - samples[0] -= tilt * *mem; - *mem = new_tilt_mem; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/acelp_filters.h b/tizen/distrib/ffmpeg/libavcodec/acelp_filters.h deleted file mode 100644 index 09b5da4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/acelp_filters.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * various filters for ACELP-based codecs - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ACELP_FILTERS_H -#define AVCODEC_ACELP_FILTERS_H - -#include - -/** - * low-pass Finite Impulse Response filter coefficients. - * - * Hamming windowed sinc filter with cutoff freq 3/40 of the sampling freq, - * the coefficients are scaled by 2^15. - * This array only contains the right half of the filter. - * This filter is likely identical to the one used in G.729, though this - * could not be determined from the original comments with certainity. - */ -extern const int16_t ff_acelp_interp_filter[61]; - -/** - * Generic FIR interpolation routine. - * @param out [out] buffer for interpolated data - * @param in input data - * @param filter_coeffs interpolation filter coefficients (0.15) - * @param precision sub sample factor, that is the precision of the position - * @param frac_pos fractional part of position [0..precision-1] - * @param filter_length filter length - * @param length length of output - * - * filter_coeffs contains coefficients of the right half of the symmetric - * interpolation filter. filter_coeffs[0] should the central (unpaired) coefficient. - * See ff_acelp_interp_filter for an example. - * - */ -void ff_acelp_interpolate(int16_t* out, const int16_t* in, - const int16_t* filter_coeffs, int precision, - int frac_pos, int filter_length, int length); - -/** - * Floating point version of ff_acelp_interpolate() - */ -void ff_acelp_interpolatef(float *out, const float *in, - const float *filter_coeffs, int precision, - int frac_pos, int filter_length, int length); - - -/** - * high-pass filtering and upscaling (4.2.5 of G.729). - * @param out [out] output buffer for filtered speech data - * @param hpf_f [in/out] past filtered data from previous (2 items long) - * frames (-0x20000000 <= (14.13) < 0x20000000) - * @param in speech data to process - * @param length input data size - * - * out[i] = 0.93980581 * in[i] - 1.8795834 * in[i-1] + 0.93980581 * in[i-2] + - * 1.9330735 * out[i-1] - 0.93589199 * out[i-2] - * - * The filter has a cut-off frequency of 1/80 of the sampling freq - * - * @note Two items before the top of the out buffer must contain two items from the - * tail of the previous subframe. - * - * @remark It is safe to pass the same array in in and out parameters. - * - * @remark AMR uses mostly the same filter (cut-off frequency 60Hz, same formula, - * but constants differs in 5th sign after comma). Fortunately in - * fixed-point all coefficients are the same as in G.729. Thus this - * routine can be used for the fixed-point AMR decoder, too. - */ -void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2], - const int16_t* in, int length); - -/** - * Apply an order 2 rational transfer function in-place. - * - * @param out output buffer for filtered speech samples - * @param in input buffer containing speech data (may be the same as out) - * @param zero_coeffs z^-1 and z^-2 coefficients of the numerator - * @param pole_coeffs z^-1 and z^-2 coefficients of the denominator - * @param gain scale factor for final output - * @param mem intermediate values used by filter (should be 0 initially) - * @param n number of samples - */ -void ff_acelp_apply_order_2_transfer_function(float *out, const float *in, - const float zero_coeffs[2], - const float pole_coeffs[2], - float gain, - float mem[2], int n); - -/** - * Apply tilt compensation filter, 1 - tilt * z-1. - * - * @param mem pointer to the filter's state (one single float) - * @param tilt tilt factor - * @param samples array where the filter is applied - * @param size the size of the samples array - */ -void ff_tilt_compensation(float *mem, float tilt, float *samples, int size); - - -#endif /* AVCODEC_ACELP_FILTERS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.c b/tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.c deleted file mode 100644 index cddf726..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * gain code, gain pitch and pitch delay decoding - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "acelp_pitch_delay.h" -#include "celp_math.h" - -int ff_acelp_decode_8bit_to_1st_delay3(int ac_index) -{ - ac_index += 58; - if(ac_index > 254) - ac_index = 3 * ac_index - 510; - return ac_index; -} - -int ff_acelp_decode_4bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min) -{ - if(ac_index < 4) - return 3 * (ac_index + pitch_delay_min); - else if(ac_index < 12) - return 3 * pitch_delay_min + ac_index + 6; - else - return 3 * (ac_index + pitch_delay_min) - 18; -} - -int ff_acelp_decode_5_6_bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min) -{ - return 3 * pitch_delay_min + ac_index - 2; -} - -int ff_acelp_decode_9bit_to_1st_delay6(int ac_index) -{ - if(ac_index < 463) - return ac_index + 105; - else - return 6 * (ac_index - 368); -} -int ff_acelp_decode_6bit_to_2nd_delay6( - int ac_index, - int pitch_delay_min) -{ - return 6 * pitch_delay_min + ac_index - 3; -} - -void ff_acelp_update_past_gain( - int16_t* quant_energy, - int gain_corr_factor, - int log2_ma_pred_order, - int erasure) -{ - int i; - int avg_gain=quant_energy[(1 << log2_ma_pred_order) - 1]; // (5.10) - - for(i=(1 << log2_ma_pred_order) - 1; i>0; i--) - { - avg_gain += quant_energy[i-1]; - quant_energy[i] = quant_energy[i-1]; - } - - if(erasure) - quant_energy[0] = FFMAX(avg_gain >> log2_ma_pred_order, -10240) - 4096; // -10 and -4 in (5.10) - else - quant_energy[0] = (6165 * ((ff_log2(gain_corr_factor) >> 2) - (13 << 13))) >> 13; -} - -int16_t ff_acelp_decode_gain_code( - DSPContext *dsp, - int gain_corr_factor, - const int16_t* fc_v, - int mr_energy, - const int16_t* quant_energy, - const int16_t* ma_prediction_coeff, - int subframe_size, - int ma_pred_order) -{ - int i; - - mr_energy <<= 10; - - for(i=0; iscalarproduct_int16(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff); - - mr_energy = (5439 * (mr_energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23) - - return bidir_sal( - ((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1), - (mr_energy >> 15) - 25 - ); -#else - mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) / - sqrt(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0)); - return mr_energy >> 12; -#endif -} - -float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy, - float *prediction_error, float energy_mean, - const float *pred_table) -{ - // Equations 66-69: - // ^g_c = ^gamma_gc * 100.05 (predicted dB + mean dB - dB of fixed vector) - // Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)). - float val = fixed_gain_factor * - exp2f(M_LOG2_10 * 0.05 * - (ff_dot_productf(pred_table, prediction_error, 4) + - energy_mean)) / - sqrtf(fixed_mean_energy); - - // update quantified prediction error energy history - memmove(&prediction_error[0], &prediction_error[1], - 3 * sizeof(prediction_error[0])); - prediction_error[3] = 20.0 * log10f(fixed_gain_factor); - - return val; -} - -void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index, - const int prev_lag_int, const int subframe, - int third_as_first, int resolution) -{ - /* Note n * 10923 >> 15 is floor(x/3) for 0 <= n <= 32767 */ - if (subframe == 0 || (subframe == 2 && third_as_first)) { - - if (pitch_index < 197) - pitch_index += 59; - else - pitch_index = 3 * pitch_index - 335; - - } else { - if (resolution == 4) { - int search_range_min = av_clip(prev_lag_int - 5, PITCH_DELAY_MIN, - PITCH_DELAY_MAX - 9); - - // decoding with 4-bit resolution - if (pitch_index < 4) { - // integer only precision for [search_range_min, search_range_min+3] - pitch_index = 3 * (pitch_index + search_range_min) + 1; - } else if (pitch_index < 12) { - // 1/3 fractional precision for [search_range_min+3 1/3, search_range_min+5 2/3] - pitch_index += 3 * search_range_min + 7; - } else { - // integer only precision for [search_range_min+6, search_range_min+9] - pitch_index = 3 * (pitch_index + search_range_min - 6) + 1; - } - } else { - // decoding with 5 or 6 bit resolution, 1/3 fractional precision - pitch_index--; - - if (resolution == 5) { - pitch_index += 3 * av_clip(prev_lag_int - 10, PITCH_DELAY_MIN, - PITCH_DELAY_MAX - 19); - } else - pitch_index += 3 * av_clip(prev_lag_int - 5, PITCH_DELAY_MIN, - PITCH_DELAY_MAX - 9); - } - } - *lag_int = pitch_index * 10923 >> 15; - *lag_frac = pitch_index - 3 * *lag_int - 1; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.h b/tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.h deleted file mode 100644 index 2413145..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/acelp_pitch_delay.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * gain code, gain pitch and pitch delay decoding - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ACELP_PITCH_DELAY_H -#define AVCODEC_ACELP_PITCH_DELAY_H - -#include -#include "dsputil.h" - -#define PITCH_DELAY_MIN 20 -#define PITCH_DELAY_MAX 143 - -/** - * \brief Decode pitch delay of the first subframe encoded by 8 bits with 1/3 - * resolution. - * \param ac_index adaptive codebook index (8 bits) - * - * \return pitch delay in 1/3 units - * - * Pitch delay is coded: - * with 1/3 resolution, 19 < pitch_delay < 85 - * integers only, 85 <= pitch_delay <= 143 - */ -int ff_acelp_decode_8bit_to_1st_delay3(int ac_index); - -/** - * \brief Decode pitch delay of the second subframe encoded by 5 or 6 bits - * with 1/3 precision. - * \param ac_index adaptive codebook index (5 or 6 bits) - * \param pitch_delay_min lower bound (integer) of pitch delay interval - * for second subframe - * - * \return pitch delay in 1/3 units - * - * Pitch delay is coded: - * with 1/3 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5 - * - * \remark The routine is used in G.729 @8k, AMR @10.2k, AMR @7.95k, - * AMR @7.4k for the second subframe. - */ -int ff_acelp_decode_5_6_bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min); - -/** - * \brief Decode pitch delay with 1/3 precision. - * \param ac_index adaptive codebook index (4 bits) - * \param pitch_delay_min lower bound (integer) of pitch delay interval for - * second subframe - * - * \return pitch delay in 1/3 units - * - * Pitch delay is coded: - * integers only, -6 < pitch_delay - int(prev_pitch_delay) <= -2 - * with 1/3 resolution, -2 < pitch_delay - int(prev_pitch_delay) < 1 - * integers only, 1 <= pitch_delay - int(prev_pitch_delay) < 5 - * - * \remark The routine is used in G.729 @6.4k, AMR @6.7k, AMR @5.9k, - * AMR @5.15k, AMR @4.75k for the second subframe. - */ -int ff_acelp_decode_4bit_to_2nd_delay3( - int ac_index, - int pitch_delay_min); - -/** - * \brief Decode pitch delay of the first subframe encoded by 9 bits - * with 1/6 precision. - * \param ac_index adaptive codebook index (9 bits) - * \param pitch_delay_min lower bound (integer) of pitch delay interval for - * second subframe - * - * \return pitch delay in 1/6 units - * - * Pitch delay is coded: - * with 1/6 resolution, 17 < pitch_delay < 95 - * integers only, 95 <= pitch_delay <= 143 - * - * \remark The routine is used in AMR @12.2k for the first and third subframes. - */ -int ff_acelp_decode_9bit_to_1st_delay6(int ac_index); - -/** - * \brief Decode pitch delay of the second subframe encoded by 6 bits - * with 1/6 precision. - * \param ac_index adaptive codebook index (6 bits) - * \param pitch_delay_min lower bound (integer) of pitch delay interval for - * second subframe - * - * \return pitch delay in 1/6 units - * - * Pitch delay is coded: - * with 1/6 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5 - * - * \remark The routine is used in AMR @12.2k for the second and fourth subframes. - */ -int ff_acelp_decode_6bit_to_2nd_delay6( - int ac_index, - int pitch_delay_min); - -/** - * \brief Update past quantized energies - * \param quant_energy [in/out] past quantized energies (5.10) - * \param gain_corr_factor gain correction factor - * \param log2_ma_pred_order log2() of MA prediction order - * \param erasure frame erasure flag - * - * If frame erasure flag is not equal to zero, memory is updated with - * averaged energy, attenuated by 4dB: - * max(avg(quant_energy[i])-4, -14), i=0,ma_pred_order - * - * In normal mode memory is updated with - * Er - Ep = 20 * log10(gain_corr_factor) - * - * \remark The routine is used in G.729 and AMR (all modes). - */ -void ff_acelp_update_past_gain( - int16_t* quant_energy, - int gain_corr_factor, - int log2_ma_pred_order, - int erasure); - -/** - * \brief Decode the adaptive codebook gain and add - * correction (4.1.5 and 3.9.1 of G.729). - * \param dsp initialized dsputil context - * \param gain_corr_factor gain correction factor (2.13) - * \param fc_v fixed-codebook vector (2.13) - * \param mr_energy mean innovation energy and fixed-point correction (7.13) - * \param quant_energy [in/out] past quantized energies (5.10) - * \param subframe_size length of subframe - * \param ma_pred_order MA prediction order - * - * \return quantized fixed-codebook gain (14.1) - * - * The routine implements equations 69, 66 and 71 of the G.729 specification (3.9.1) - * - * Em - mean innovation energy (dB, constant, depends on decoding algorithm) - * Ep - mean-removed predicted energy (dB) - * Er - mean-removed innovation energy (dB) - * Ei - mean energy of the fixed-codebook contribution (dB) - * N - subframe_size - * M - MA (Moving Average) prediction order - * gc - fixed-codebook gain - * gc_p - predicted fixed-codebook gain - * - * Fixed codebook gain is computed using predicted gain gc_p and - * correction factor gain_corr_factor as shown below: - * - * gc = gc_p * gain_corr_factor - * - * The predicted fixed codebook gain gc_p is found by predicting - * the energy of the fixed-codebook contribution from the energy - * of previous fixed-codebook contributions. - * - * mean = 1/N * sum(i,0,N){ fc_v[i] * fc_v[i] } - * - * Ei = 10log(mean) - * - * Er = 10log(1/N * gc^2 * mean) - Em = 20log(gc) + Ei - Em - * - * Replacing Er with Ep and gc with gc_p we will receive: - * - * Ep = 10log(1/N * gc_p^2 * mean) - Em = 20log(gc_p) + Ei - Em - * - * and from above: - * - * gc_p = 10^((Ep - Ei + Em) / 20) - * - * Ep is predicted using past energies and prediction coefficients: - * - * Ep = sum(i,0,M){ ma_prediction_coeff[i] * quant_energy[i] } - * - * gc_p in fixed-point arithmetic is calculated as following: - * - * mean = 1/N * sum(i,0,N){ (fc_v[i] / 2^13) * (fc_v[i] / 2^13) } = - * = 1/N * sum(i,0,N) { fc_v[i] * fc_v[i] } / 2^26 - * - * Ei = 10log(mean) = -10log(N) - 10log(2^26) + - * + 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) - * - * Ep - Ei + Em = Ep + Em + 10log(N) + 10log(2^26) - - * - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) = - * = Ep + mr_energy - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) - * - * gc_p = 10 ^ ((Ep - Ei + Em) / 20) = - * = 2 ^ (3.3219 * (Ep - Ei + Em) / 20) = 2 ^ (0.166 * (Ep - Ei + Em)) - * - * where - * - * mr_energy = Em + 10log(N) + 10log(2^26) - * - * \remark The routine is used in G.729 and AMR (all modes). - */ -int16_t ff_acelp_decode_gain_code( - DSPContext *dsp, - int gain_corr_factor, - const int16_t* fc_v, - int mr_energy, - const int16_t* quant_energy, - const int16_t* ma_prediction_coeff, - int subframe_size, - int max_pred_order); - -/** - * Calculate fixed gain (part of section 6.1.3 of AMR spec) - * - * @param fixed_gain_factor gain correction factor - * @param fixed_energy decoded algebraic codebook vector energy - * @param prediction_error vector of the quantified predictor errors of - * the four previous subframes. It is updated by this function. - * @param energy_mean desired mean innovation energy - * @param pred_table table of four moving average coefficients - */ -float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy, - float *prediction_error, float energy_mean, - const float *pred_table); - - -/** - * Decode the adaptive codebook index to the integer and fractional parts - * of the pitch lag for one subframe at 1/3 fractional precision. - * - * The choice of pitch lag is described in 3GPP TS 26.090 section 5.6.1. - * - * @param lag_int integer part of pitch lag of the current subframe - * @param lag_frac fractional part of pitch lag of the current subframe - * @param pitch_index parsed adaptive codebook (pitch) index - * @param prev_lag_int integer part of pitch lag for the previous subframe - * @param subframe current subframe number - * @param third_as_first treat the third frame the same way as the first - */ -void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index, - const int prev_lag_int, const int subframe, - int third_as_first, int resolution); - -#endif /* AVCODEC_ACELP_PITCH_DELAY_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/acelp_vectors.c b/tizen/distrib/ffmpeg/libavcodec/acelp_vectors.c deleted file mode 100644 index e41e5fa..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/acelp_vectors.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * adaptive and fixed codebook vector operations for ACELP-based codecs - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avcodec.h" -#include "acelp_vectors.h" -#include "celp_math.h" - -const uint8_t ff_fc_2pulses_9bits_track1[16] = -{ - 1, 3, - 6, 8, - 11, 13, - 16, 18, - 21, 23, - 26, 28, - 31, 33, - 36, 38 -}; -const uint8_t ff_fc_2pulses_9bits_track1_gray[16] = -{ - 1, 3, - 8, 6, - 18, 16, - 11, 13, - 38, 36, - 31, 33, - 21, 23, - 28, 26, -}; - -const uint8_t ff_fc_2pulses_9bits_track2_gray[32] = -{ - 0, 2, - 5, 4, - 12, 10, - 7, 9, - 25, 24, - 20, 22, - 14, 15, - 19, 17, - 36, 31, - 21, 26, - 1, 6, - 16, 11, - 27, 29, - 32, 30, - 39, 37, - 34, 35, -}; - -const uint8_t ff_fc_4pulses_8bits_tracks_13[16] = -{ - 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, -}; - -const uint8_t ff_fc_4pulses_8bits_track_4[32] = -{ - 3, 4, - 8, 9, - 13, 14, - 18, 19, - 23, 24, - 28, 29, - 33, 34, - 38, 39, - 43, 44, - 48, 49, - 53, 54, - 58, 59, - 63, 64, - 68, 69, - 73, 74, - 78, 79, -}; - -#if 0 -static uint8_t gray_decode[32] = -{ - 0, 1, 3, 2, 7, 6, 4, 5, - 15, 14, 12, 13, 8, 9, 11, 10, - 31, 30, 28, 29, 24, 25, 27, 26, - 16, 17, 19, 18, 23, 22, 20, 21 -}; -#endif - -const float ff_pow_0_7[10] = { - 0.700000, 0.490000, 0.343000, 0.240100, 0.168070, - 0.117649, 0.082354, 0.057648, 0.040354, 0.028248 -}; - -const float ff_pow_0_75[10] = { - 0.750000, 0.562500, 0.421875, 0.316406, 0.237305, - 0.177979, 0.133484, 0.100113, 0.075085, 0.056314 -}; - -const float ff_pow_0_55[10] = { - 0.550000, 0.302500, 0.166375, 0.091506, 0.050328, - 0.027681, 0.015224, 0.008373, 0.004605, 0.002533 -}; - -const float ff_b60_sinc[61] = { - 0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 , - 0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 , --0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 , - 0.0689392 , 0.0357056 , 0. , -0.0305481 , -0.0504150 , -0.0570068 , --0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 , - 0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 , --0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0. , 0.00582886 , - 0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 , --0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834, - 0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 , - 0. -}; - -void ff_acelp_fc_pulse_per_track( - int16_t* fc_v, - const uint8_t *tab1, - const uint8_t *tab2, - int pulse_indexes, - int pulse_signs, - int pulse_count, - int bits) -{ - int mask = (1 << bits) - 1; - int i; - - for(i=0; i>= bits; - pulse_signs >>= 1; - } - - fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192; -} - -void ff_decode_10_pulses_35bits(const int16_t *fixed_index, - AMRFixed *fixed_sparse, - const uint8_t *gray_decode, - int half_pulse_count, int bits) -{ - int i; - int mask = (1 << bits) - 1; - - fixed_sparse->no_repeat_mask = 0; - fixed_sparse->n = 2 * half_pulse_count; - for (i = 0; i < half_pulse_count; i++) { - const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i; - const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i; - const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0; - fixed_sparse->x[2*i+1] = pos1; - fixed_sparse->x[2*i ] = pos2; - fixed_sparse->y[2*i+1] = sign; - fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign; - } -} - -void ff_acelp_weighted_vector_sum( - int16_t* out, - const int16_t *in_a, - const int16_t *in_b, - int16_t weight_coeff_a, - int16_t weight_coeff_b, - int16_t rounder, - int shift, - int length) -{ - int i; - - // Clipping required here; breaks OVERFLOW test. - for(i=0; i> shift); -} - -void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b, - float weight_coeff_a, float weight_coeff_b, int length) -{ - int i; - - for(i=0; in; i++) { - int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); - float y = in->y[i] * scale; - - do { - out[x] += y; - y *= in->pitch_fac; - x += in->pitch_lag; - } while (x < size && repeats); - } -} - -void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size) -{ - int i; - - for (i=0; i < in->n; i++) { - int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); - - do { - out[x] = 0.0; - x += in->pitch_lag; - } while (x < size && repeats); - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/acelp_vectors.h b/tizen/distrib/ffmpeg/libavcodec/acelp_vectors.h deleted file mode 100644 index ba3437f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/acelp_vectors.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * adaptive and fixed codebook vector operations for ACELP-based codecs - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ACELP_VECTORS_H -#define AVCODEC_ACELP_VECTORS_H - -#include - -/** Sparse representation for the algebraic codebook (fixed) vector */ -typedef struct { - int n; - int x[10]; - float y[10]; - int no_repeat_mask; - int pitch_lag; - float pitch_fac; -} AMRFixed; - -/** - * Track|Pulse| Positions - * ------------------------------------------------------------------------- - * 1 | 0 | 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75 - * ------------------------------------------------------------------------- - * 2 | 1 | 1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76 - * ------------------------------------------------------------------------- - * 3 | 2 | 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77 - * ------------------------------------------------------------------------- - * - * Table contains only first the pulse indexes. - * - * Used in G.729 @8k, G.729 @4.4k, AMR @7.95k, AMR @7.40k - */ -extern const uint8_t ff_fc_4pulses_8bits_tracks_13[16]; - -/** - * Track|Pulse| Positions - * ------------------------------------------------------------------------- - * 4 | 3 | 3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58, 63, 68, 73, 78 - * | | 4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79 - * ------------------------------------------------------------------------- - * - * @remark Track in the table should be read top-to-bottom, left-to-right. - * - * Used in G.729 @8k, G.729 @4.4k, AMR @7.95k, AMR @7.40k - */ -extern const uint8_t ff_fc_4pulses_8bits_track_4[32]; - -/** - * Track|Pulse| Positions - * ----------------------------------------- - * 1 | 0 | 1, 6, 11, 16, 21, 26, 31, 36 - * | | 3, 8, 13, 18, 23, 28, 33, 38 - * ----------------------------------------- - * - * @remark Track in the table should be read top-to-bottom, left-to-right. - * - * @note (EE) Reference G.729D code also uses gray decoding for each - * pulse index before looking up the value in the table. - * - * Used in G.729 @6.4k (with gray coding), AMR @5.9k (without gray coding) - */ -extern const uint8_t ff_fc_2pulses_9bits_track1[16]; -extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16]; - -/** - * Track|Pulse| Positions - * ----------------------------------------- - * 2 | 1 | 0, 7, 14, 20, 27, 34, 1, 21 - * | | 2, 9, 15, 22, 29, 35, 6, 26 - * | | 4,10, 17, 24, 30, 37, 11, 31 - * | | 5,12, 19, 25, 32, 39, 16, 36 - * ----------------------------------------- - * - * @remark Track in the table should be read top-to-bottom, left-to-right. - * - * @note (EE.1) This table (from the reference code) does not comply with - * the specification. - * The specification contains the following table: - * - * Track|Pulse| Positions - * ----------------------------------------- - * 2 | 1 | 0, 5, 10, 15, 20, 25, 30, 35 - * | | 1, 6, 11, 16, 21, 26, 31, 36 - * | | 2, 7, 12, 17, 22, 27, 32, 37 - * | | 4, 9, 14, 19, 24, 29, 34, 39 - * - * ----------------------------------------- - * - * @note (EE.2) Reference G.729D code also uses gray decoding for each - * pulse index before looking up the value in the table. - * - * Used in G.729 @6.4k (with gray coding) - */ -extern const uint8_t ff_fc_2pulses_9bits_track2_gray[32]; - -/** - * b60 hamming windowed sinc function coefficients - */ -extern const float ff_b60_sinc[61]; - -/** - * Table of pow(0.7,n) - */ -extern const float ff_pow_0_7[10]; - -/** - * Table of pow(0.75,n) - */ -extern const float ff_pow_0_75[10]; - -/** - * Table of pow(0.55,n) - */ -extern const float ff_pow_0_55[10]; - -/** - * Decode fixed-codebook vector (3.8 and D.5.8 of G.729, 5.7.1 of AMR). - * @param fc_v [out] decoded fixed codebook vector (2.13) - * @param tab1 table used for first pulse_count pulses - * @param tab2 table used for last pulse - * @param pulse_indexes fixed codebook indexes - * @param pulse_signs signs of the excitation pulses (0 bit value - * means negative sign) - * @param bits number of bits per one pulse index - * @param pulse_count number of pulses decoded using first table - * @param bits length of one pulse index in bits - * - * Used in G.729 @8k, G.729 @4.4k, G.729 @6.4k, AMR @7.95k, AMR @7.40k - */ -void ff_acelp_fc_pulse_per_track(int16_t* fc_v, - const uint8_t *tab1, - const uint8_t *tab2, - int pulse_indexes, - int pulse_signs, - int pulse_count, - int bits); - -/** - * Decode the algebraic codebook index to pulse positions and signs and - * construct the algebraic codebook vector for MODE_12k2. - * - * @note: The positions and signs are explicitly coded in MODE_12k2. - * - * @param fixed_index positions of the ten pulses - * @param fixed_sparse pointer to the algebraic codebook vector - * @param gray_decode gray decoding table - * @param half_pulse_count number of couples of pulses - * @param bits length of one pulse index in bits - */ -void ff_decode_10_pulses_35bits(const int16_t *fixed_index, - AMRFixed *fixed_sparse, - const uint8_t *gray_decode, - int half_pulse_count, int bits); - - -/** - * weighted sum of two vectors with rounding. - * @param out [out] result of addition - * @param in_a first vector - * @param in_b second vector - * @param weight_coeff_a first vector weight coefficient - * @param weight_coeff_a second vector weight coefficient - * @param rounder this value will be added to the sum of the two vectors - * @param shift result will be shifted to right by this value - * @param length vectors length - * - * @note It is safe to pass the same buffer for out and in_a or in_b. - * - * out[i] = (in_a[i]*weight_a + in_b[i]*weight_b + rounder) >> shift - */ -void ff_acelp_weighted_vector_sum(int16_t* out, - const int16_t *in_a, - const int16_t *in_b, - int16_t weight_coeff_a, - int16_t weight_coeff_b, - int16_t rounder, - int shift, - int length); - -/** - * float implementation of weighted sum of two vectors. - * @param out [out] result of addition - * @param in_a first vector - * @param in_b second vector - * @param weight_coeff_a first vector weight coefficient - * @param weight_coeff_a second vector weight coefficient - * @param length vectors length - * - * @note It is safe to pass the same buffer for out and in_a or in_b. - */ -void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b, - float weight_coeff_a, float weight_coeff_b, - int length); - -/** - * Adaptive gain control (as used in AMR postfiltering) - * - * @param out output buffer for filtered speech data - * @param in the input speech buffer (may be the same as out) - * @param speech_energ input energy - * @param size the input buffer size - * @param alpha exponential filter factor - * @param gain_mem a pointer to the filter memory (single float of size) - */ -void ff_adaptive_gain_control(float *out, const float *in, float speech_energ, - int size, float alpha, float *gain_mem); - -/** - * Set the sum of squares of a signal by scaling - * - * @param out output samples - * @param in input samples - * @param sum_of_squares new sum of squares - * @param n number of samples - * - * @note If the input is zero (or its energy underflows), the output is zero. - * This is the behavior of AGC in the AMR reference decoder. The QCELP - * reference decoder seems to have undefined behavior. - * - * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6 - * 3GPP TS 26.090 6.1 (6) - */ -void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in, - float sum_of_squares, const int n); - -/** - * Add fixed vector to an array from a sparse representation - * - * @param out fixed vector with pitch sharpening - * @param in sparse fixed vector - * @param scale number to multiply the fixed vector by - * @param size the output vector size - */ -void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size); - -/** - * Clear array values set by set_fixed_vector - * - * @param out fixed vector to be cleared - * @param in sparse fixed vector - * @param size the output vector size - */ -void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size); - -#endif /* AVCODEC_ACELP_VECTORS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/adpcm.c b/tizen/distrib/ffmpeg/libavcodec/adpcm.c deleted file mode 100644 index 68bd656..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/adpcm.c +++ /dev/null @@ -1,1701 +0,0 @@ -/* - * ADPCM codecs - * Copyright (c) 2001-2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "get_bits.h" -#include "put_bits.h" -#include "bytestream.h" - -/** - * @file - * ADPCM codecs. - * First version by Francois Revol (revol@free.fr) - * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood) - * by Mike Melanson (melanson@pcisys.net) - * CD-ROM XA ADPCM codec by BERO - * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com) - * EA ADPCM R1/R2/R3 decoder by Peter Ross (pross@xvid.org) - * EA IMA EACS decoder by Peter Ross (pross@xvid.org) - * EA IMA SEAD decoder by Peter Ross (pross@xvid.org) - * EA ADPCM XAS decoder by Peter Ross (pross@xvid.org) - * MAXIS EA ADPCM decoder by Robert Marston (rmarston@gmail.com) - * THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl) - * - * Features and limitations: - * - * Reference documents: - * http://www.pcisys.net/~melanson/codecs/simpleaudio.html - * http://www.geocities.com/SiliconValley/8682/aud3.txt - * http://openquicktime.sourceforge.net/plugins.htm - * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html - * http://www.cs.ucla.edu/~leec/mediabench/applications.html - * SoX source code http://home.sprynet.com/~cbagwell/sox.html - * - * CD-ROM XA: - * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html - * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html - * readstr http://www.geocities.co.jp/Playtown/2004/ - */ - -#define BLKSIZE 1024 - -/* 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 -}; - -/** Divided by 4 to fit in 8-bit integers */ -static const uint8_t AdaptCoeff1[] = { - 64, 128, 0, 48, 60, 115, 98 -}; - -/** Divided by 4 to fit in 8-bit integers */ -static const int8_t AdaptCoeff2[] = { - 0, -64, 0, 16, 0, -52, -58 -}; - -/* 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 -}; - -// 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 { - ADPCMChannelStatus status[6]; -} ADPCMContext; - -/* XXX: implement encoding */ - -#if CONFIG_ENCODERS -static av_cold int adpcm_encode_init(AVCodecContext *avctx) -{ - uint8_t *extradata; - int i; - if (avctx->channels > 2) - return -1; /* only stereo or mono =) */ - - if(avctx->trellis && (unsigned)avctx->trellis > 16U){ - av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n"); - return -1; - } - - switch(avctx->codec->id) { - 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_IMA_QT: - avctx->frame_size = 64; - avctx->block_align = 34 * avctx->channels; - 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; - avctx->extradata_size = 32; - extradata = avctx->extradata = av_malloc(avctx->extradata_size); - if (!extradata) - return AVERROR(ENOMEM); - bytestream_put_le16(&extradata, avctx->frame_size); - bytestream_put_le16(&extradata, 7); /* wNumCoef */ - for (i = 0; i < 7; i++) { - bytestream_put_le16(&extradata, AdaptCoeff1[i] * 4); - bytestream_put_le16(&extradata, AdaptCoeff2[i] * 4); - } - break; - case CODEC_ID_ADPCM_YAMAHA: - avctx->frame_size = BLKSIZE * avctx->channels; - avctx->block_align = BLKSIZE; - break; - case CODEC_ID_ADPCM_SWF: - if (avctx->sample_rate != 11025 && - avctx->sample_rate != 22050 && - avctx->sample_rate != 44100) { - av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, 22050 or 44100\n"); - return -1; - } - avctx->frame_size = 512 * (avctx->sample_rate / 11025); - break; - default: - return -1; - } - - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; -} - -static av_cold 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 delta = sample - c->prev_sample; - int nibble = FFMIN(7, abs(delta)*4/step_table[c->step_index]) + (delta<0)*8; - c->prev_sample += ((step_table[c->step_index] * yamaha_difflookup[nibble]) / 8); - c->prev_sample = av_clip_int16(c->prev_sample); - c->step_index = av_clip(c->step_index + index_table[nibble], 0, 88); - 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))) / 64; - - nibble= sample - predictor; - if(nibble>=0) bias= c->idelta/2; - else bias=-c->idelta/2; - - nibble= (nibble + bias) / c->idelta; - nibble= av_clip(nibble, -8, 7)&0x0F; - - predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; - - c->sample2 = c->sample1; - c->sample1 = av_clip_int16(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 nibble, delta; - - if(!c->step) { - c->predictor = 0; - c->step = 127; - } - - delta = sample - c->predictor; - - nibble = FFMIN(7, abs(delta)*4/c->step) + (delta<0)*8; - - c->predictor += ((c->step * yamaha_difflookup[nibble]) / 8); - c->predictor = av_clip_int16(c->predictor); - c->step = (c->step * yamaha_indexscale[nibble]) >> 8; - c->step = av_clip(c->step, 127, 24567); - - return nibble; -} - -typedef struct TrellisPath { - int nibble; - int prev; -} TrellisPath; - -typedef struct TrellisNode { - uint32_t ssd; - int path; - int sample1; - int sample2; - int step; -} TrellisNode; - -static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples, - uint8_t *dst, ADPCMChannelStatus *c, int n) -{ -#define FREEZE_INTERVAL 128 - //FIXME 6% faster if frontier is a compile-time constant - const int frontier = 1 << avctx->trellis; - const int stride = avctx->channels; - const int version = avctx->codec->id; - const int max_paths = frontier*FREEZE_INTERVAL; - TrellisPath paths[max_paths], *p; - TrellisNode node_buf[2][frontier]; - TrellisNode *nodep_buf[2][frontier]; - TrellisNode **nodes = nodep_buf[0]; // nodes[] is always sorted by .ssd - TrellisNode **nodes_next = nodep_buf[1]; - int pathn = 0, froze = -1, i, j, k; - - assert(!(max_paths&(max_paths-1))); - - memset(nodep_buf, 0, sizeof(nodep_buf)); - nodes[0] = &node_buf[1][0]; - nodes[0]->ssd = 0; - nodes[0]->path = 0; - nodes[0]->step = c->step_index; - nodes[0]->sample1 = c->sample1; - nodes[0]->sample2 = c->sample2; - if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_IMA_QT) || (version == CODEC_ID_ADPCM_SWF)) - nodes[0]->sample1 = c->prev_sample; - if(version == CODEC_ID_ADPCM_MS) - nodes[0]->step = c->idelta; - if(version == CODEC_ID_ADPCM_YAMAHA) { - if(c->step == 0) { - nodes[0]->step = 127; - nodes[0]->sample1 = 0; - } else { - nodes[0]->step = c->step; - nodes[0]->sample1 = c->predictor; - } - } - - for(i=0; istep; - int nidx; - if(version == CODEC_ID_ADPCM_MS) { - const int predictor = ((nodes[j]->sample1 * c->coeff1) + (nodes[j]->sample2 * c->coeff2)) / 64; - const int div = (sample - predictor) / step; - const int nmin = av_clip(div-range, -8, 6); - const int nmax = av_clip(div+range, -7, 7); - for(nidx=nmin; nidx<=nmax; nidx++) { - const int nibble = nidx & 0xf; - int dec_sample = predictor + nidx * step; -#define STORE_NODE(NAME, STEP_INDEX)\ - int d;\ - uint32_t ssd;\ - dec_sample = av_clip_int16(dec_sample);\ - d = sample - dec_sample;\ - ssd = nodes[j]->ssd + d*d;\ - if(nodes_next[frontier-1] && ssd >= nodes_next[frontier-1]->ssd)\ - continue;\ - /* Collapse any two states with the same previous sample value. \ - * One could also distinguish states by step and by 2nd to last - * sample, but the effects of that are negligible. */\ - for(k=0; ksample1) {\ - assert(ssd >= nodes_next[k]->ssd);\ - goto next_##NAME;\ - }\ - }\ - for(k=0; kssd) {\ - TrellisNode *u = nodes_next[frontier-1];\ - if(!u) {\ - assert(pathn < max_paths);\ - u = t++;\ - u->path = pathn++;\ - }\ - u->ssd = ssd;\ - u->step = STEP_INDEX;\ - u->sample2 = nodes[j]->sample1;\ - u->sample1 = dec_sample;\ - paths[u->path].nibble = nibble;\ - paths[u->path].prev = nodes[j]->path;\ - memmove(&nodes_next[k+1], &nodes_next[k], (frontier-k-1)*sizeof(TrellisNode*));\ - nodes_next[k] = u;\ - break;\ - }\ - }\ - next_##NAME:; - STORE_NODE(ms, FFMAX(16, (AdaptationTable[nibble] * step) >> 8)); - } - } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_IMA_QT)|| (version == CODEC_ID_ADPCM_SWF)) { -#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\ - const int predictor = nodes[j]->sample1;\ - const int div = (sample - predictor) * 4 / STEP_TABLE;\ - int nmin = av_clip(div-range, -7, 6);\ - int nmax = av_clip(div+range, -6, 7);\ - if(nmin<=0) nmin--; /* distinguish -0 from +0 */\ - if(nmax<0) nmax--;\ - for(nidx=nmin; nidx<=nmax; nidx++) {\ - const int nibble = nidx<0 ? 7-nidx : nidx;\ - int dec_sample = predictor + (STEP_TABLE * yamaha_difflookup[nibble]) / 8;\ - STORE_NODE(NAME, STEP_INDEX);\ - } - LOOP_NODES(ima, step_table[step], av_clip(step + index_table[nibble], 0, 88)); - } else { //CODEC_ID_ADPCM_YAMAHA - LOOP_NODES(yamaha, step, av_clip((step * yamaha_indexscale[nibble]) >> 8, 127, 24567)); -#undef LOOP_NODES -#undef STORE_NODE - } - } - - u = nodes; - nodes = nodes_next; - nodes_next = u; - - // prevent overflow - if(nodes[0]->ssd > (1<<28)) { - for(j=1; jssd -= nodes[0]->ssd; - nodes[0]->ssd = 0; - } - - // merge old paths to save memory - if(i == froze + FREEZE_INTERVAL) { - p = &paths[nodes[0]->path]; - for(k=i; k>froze; k--) { - dst[k] = p->nibble; - p = &paths[p->prev]; - } - froze = i; - pathn = 0; - // other nodes might use paths that don't coincide with the frozen one. - // checking which nodes do so is too slow, so just kill them all. - // this also slightly improves quality, but I don't know why. - memset(nodes+1, 0, (frontier-1)*sizeof(TrellisNode*)); - } - } - - p = &paths[nodes[0]->path]; - for(i=n-1; i>froze; i--) { - dst[i] = p->nibble; - p = &paths[p->prev]; - } - - c->predictor = nodes[0]->sample1; - c->sample1 = nodes[0]->sample1; - c->sample2 = nodes[0]->sample2; - c->step_index = nodes[0]->step; - c->step = nodes[0]->step; - c->idelta = nodes[0]->step; -} - -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_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 */ - bytestream_put_le16(&dst, c->status[0].prev_sample); - *dst++ = (unsigned char)c->status[0].step_index; - *dst++ = 0; /* unknown */ - samples++; - if (avctx->channels == 2) { - c->status[1].prev_sample = (signed short)samples[0]; -/* c->status[1].step_index = 0; */ - bytestream_put_le16(&dst, c->status[1].prev_sample); - *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, ... */ - if(avctx->trellis > 0) { - uint8_t buf[2][n*8]; - adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n*8); - if(avctx->channels == 2) - adpcm_compress_trellis(avctx, samples+1, buf[1], &c->status[1], n*8); - for(i=0; ichannels == 2) { - *dst++ = buf[1][8*i+0] | (buf[1][8*i+1] << 4); - *dst++ = buf[1][8*i+2] | (buf[1][8*i+3] << 4); - *dst++ = buf[1][8*i+4] | (buf[1][8*i+5] << 4); - *dst++ = buf[1][8*i+6] | (buf[1][8*i+7] << 4); - } - } - } else - for (; n>0; n--) { - *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]); - *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4; - dst++; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]); - *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4; - dst++; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]); - *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4; - dst++; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]); - *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4; - 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_IMA_QT: - { - int ch, i; - PutBitContext pb; - init_put_bits(&pb, dst, buf_size*8); - - for(ch=0; chchannels; ch++){ - put_bits(&pb, 9, (c->status[ch].prev_sample + 0x10000) >> 7); - put_bits(&pb, 7, c->status[ch].step_index); - if(avctx->trellis > 0) { - uint8_t buf[64]; - adpcm_compress_trellis(avctx, samples+ch, buf, &c->status[ch], 64); - for(i=0; i<64; i++) - put_bits(&pb, 4, buf[i^1]); - c->status[ch].prev_sample = c->status[ch].predictor & ~0x7F; - } else { - for (i=0; i<64; i+=2){ - int t1, t2; - t1 = adpcm_ima_compress_sample(&c->status[ch], samples[avctx->channels*(i+0)+ch]); - t2 = adpcm_ima_compress_sample(&c->status[ch], samples[avctx->channels*(i+1)+ch]); - put_bits(&pb, 4, t2); - put_bits(&pb, 4, t1); - } - c->status[ch].prev_sample &= ~0x7F; - } - } - - dst += put_bits_count(&pb)>>3; - break; - } - case CODEC_ID_ADPCM_SWF: - { - int i; - PutBitContext pb; - init_put_bits(&pb, dst, buf_size*8); - - n = avctx->frame_size-1; - - //Store AdpcmCodeSize - put_bits(&pb, 2, 2); //Set 4bits flash adpcm format - - //Init the encoder state - for(i=0; ichannels; i++){ - c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); // clip step so it fits 6 bits - put_sbits(&pb, 16, samples[i]); - put_bits(&pb, 6, c->status[i].step_index); - c->status[i].prev_sample = (signed short)samples[i]; - } - - if(avctx->trellis > 0) { - uint8_t buf[2][n]; - adpcm_compress_trellis(avctx, samples+2, buf[0], &c->status[0], n); - if (avctx->channels == 2) - adpcm_compress_trellis(avctx, samples+3, buf[1], &c->status[1], n); - for(i=0; ichannels == 2) - put_bits(&pb, 4, buf[1][i]); - } - } else { - for (i=1; iframe_size; i++) { - put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels*i])); - if (avctx->channels == 2) - put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1], samples[2*i+1])); - } - } - flush_put_bits(&pb); - dst += put_bits_count(&pb)>>3; - 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; - - bytestream_put_le16(&dst, c->status[i].idelta); - } - for(i=0; ichannels; i++){ - c->status[i].sample2= *samples++; - } - for(i=0; ichannels; i++){ - c->status[i].sample1= *samples++; - - bytestream_put_le16(&dst, c->status[i].sample1); - } - for(i=0; ichannels; i++) - bytestream_put_le16(&dst, c->status[i].sample2); - - if(avctx->trellis > 0) { - int n = avctx->block_align - 7*avctx->channels; - uint8_t buf[2][n]; - if(avctx->channels == 1) { - n *= 2; - adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n); - for(i=0; istatus[0], n); - adpcm_compress_trellis(avctx, samples+1, buf[1], &c->status[1], n); - for(i=0; ichannels; 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; - if(avctx->trellis > 0) { - uint8_t buf[2][n*2]; - n *= 2; - if(avctx->channels == 1) { - adpcm_compress_trellis(avctx, samples, buf[0], &c->status[0], n); - for(i=0; istatus[0], n); - adpcm_compress_trellis(avctx, samples+1, buf[1], &c->status[1], n); - for(i=0; ichannels; n>0; n--) { - int nibble; - nibble = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++); - nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4; - *dst++ = nibble; - } - break; - default: - return -1; - } - return dst - frame; -} -#endif //CONFIG_ENCODERS - -static av_cold int adpcm_decode_init(AVCodecContext * avctx) -{ - ADPCMContext *c = avctx->priv_data; - unsigned int max_channels = 2; - - switch(avctx->codec->id) { - case CODEC_ID_ADPCM_EA_R1: - case CODEC_ID_ADPCM_EA_R2: - case CODEC_ID_ADPCM_EA_R3: - max_channels = 6; - break; - } - if(avctx->channels > max_channels){ - return -1; - } - - switch(avctx->codec->id) { - case CODEC_ID_ADPCM_CT: - c->status[0].step = c->status[1].step = 511; - break; - case CODEC_ID_ADPCM_IMA_WS: - if (avctx->extradata && avctx->extradata_size == 2 * 4) { - c->status[0].predictor = AV_RL32(avctx->extradata); - c->status[1].predictor = AV_RL32(avctx->extradata + 4); - } - break; - default: - break; - } - avctx->sample_fmt = SAMPLE_FMT_S16; - 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; - - c->predictor = av_clip_int16(predictor); - c->step_index = step_index; - - return (short)c->predictor; -} - -static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) -{ - int predictor; - - predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 64; - predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; - - c->sample2 = c->sample1; - c->sample1 = av_clip_int16(predictor); - c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8; - if (c->idelta < 16) c->idelta = 16; - - return c->sample1; -} - -static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble) -{ - 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 update is not so trivial: predictor is multiplied on 254/256 before updating */ - c->predictor = ((c->predictor * 254) >> 8) + (sign ? -diff : diff); - c->predictor = av_clip_int16(c->predictor); - /* calculate new step and clamp it to range 511..32767 */ - new_step = (AdaptationTable[nibble & 7] * c->step) >> 8; - c->step = av_clip(new_step, 511, 32767); - - return (short)c->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); - - /* clamp result */ - c->predictor = av_clip(c->predictor + (sign ? -diff : diff), -16384,16256); - - /* 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; - c->predictor = av_clip_int16(c->predictor); - c->step = (c->step * yamaha_indexscale[nibble]) >> 8; - c->step = av_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); - s_2 = s_1; - s_1 = av_clip_int16(s); - *out = s_1; - out += inc; - } - - 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); - s_2 = s_1; - s_1 = av_clip_int16(s); - *out = s_1; - out += inc; - } - - 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; \ - 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - ADPCMContext *c = avctx->priv_data; - ADPCMChannelStatus *cs; - int n, m, channel, i; - int block_predictor[2]; - short *samples; - short *samples_end; - const 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; - int coeff[2][2], shift[2];//used in EA MAXIS ADPCM - - if (!buf_size) - return 0; - - //should protect all 4bit ADPCM variants - //8 is needed for CODEC_ID_ADPCM_IMA_WAV with 2 channels - // - if(*data_size/4 < buf_size + 8) - return -1; - - samples = data; - samples_end= samples + *data_size/2; - *data_size= 0; - src = buf; - - st = avctx->channels == 2 ? 1 : 0; - - switch(avctx->codec->id) { - case CODEC_ID_ADPCM_IMA_QT: - n = buf_size - 2*avctx->channels; - for (channel = 0; channel < avctx->channels; 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; - - cs->predictor = av_clip_int16(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]; - - samples = (short*)data + channel; - - 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 , 3); - samples += avctx->channels; - src ++; - } - } - if (st) - samples--; - 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 = *samples++ = (int16_t)bytestream_get_le16(&src); - - 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)bytestream_get_le16(&src); - if(st){ - c->status[1].predictor= (int16_t)bytestream_get_le16(&src); - } - c->status[0].step_index= (int16_t)bytestream_get_le16(&src); - if(st){ - c->status[1].step_index= (int16_t)bytestream_get_le16(&src); - } - 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] = av_clip(*src++, 0, 6); - block_predictor[1] = 0; - if (st) - block_predictor[1] = av_clip(*src++, 0, 6); - c->status[0].idelta = (int16_t)bytestream_get_le16(&src); - if (st){ - c->status[1].idelta = (int16_t)bytestream_get_le16(&src); - } - 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 = bytestream_get_le16(&src); - if (st) c->status[1].sample1 = bytestream_get_le16(&src); - c->status[0].sample2 = bytestream_get_le16(&src); - if (st) c->status[1].sample2 = bytestream_get_le16(&src); - - *samples++ = c->status[0].sample2; - if (st) *samples++ = c->status[1].sample2; - *samples++ = c->status[0].sample1; - if (st) *samples++ = c->status[1].sample1; - for(;n>0;n--) { - *samples++ = adpcm_ms_expand_nibble(&c->status[0 ], src[0] >> 4 ); - *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)bytestream_get_le16(&src); - c->status[0].step_index = *src++; - src++; - *samples++ = c->status[0].predictor; - if (st) { - c->status[1].predictor = (int16_t)bytestream_get_le16(&src); - c->status[1].step_index = *src++; - src++; - *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, 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; - - if(buf_size + 16 > (samples_end - samples)*3/8) - return -1; - - c->status[0].predictor = (int16_t)AV_RL16(src + 10); - c->status[1].predictor = (int16_t)AV_RL16(src + 12); - 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_ISS: - c->status[0].predictor = (int16_t)AV_RL16(src + 0); - c->status[0].step_index = src[2]; - src += 4; - if(st) { - c->status[1].predictor = (int16_t)AV_RL16(src + 0); - c->status[1].step_index = src[2]; - src += 4; - } - - while (src < buf + buf_size) { - - if (st) { - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] >> 4 , 3); - *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); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] >> 4 , 3); - } - - src++; - } - 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 , 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 , 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - src[0] & 0x0F, 3); - } - - src++; - } - break; - case CODEC_ID_ADPCM_XA: - 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_IMA_EA_EACS: - samples_in_chunk = bytestream_get_le32(&src) >> (1-st); - - if (samples_in_chunk > buf_size-4-(8<status[i].step_index = bytestream_get_le32(&src); - for (i=0; i<=st; i++) - c->status[i].predictor = bytestream_get_le32(&src); - - for (; samples_in_chunk; samples_in_chunk--, src++) { - *samples++ = adpcm_ima_expand_nibble(&c->status[0], *src>>4, 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3); - } - break; - case CODEC_ID_ADPCM_IMA_EA_SEAD: - for (; src < buf+buf_size; src++) { - *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6); - *samples++ = adpcm_ima_expand_nibble(&c->status[st],src[0]&0x0F, 6); - } - break; - case CODEC_ID_ADPCM_EA: - if (buf_size < 4 || AV_RL32(src) >= ((buf_size - 12) * 2)) { - src += buf_size; - break; - } - samples_in_chunk = AV_RL32(src); - src += 4; - current_left_sample = (int16_t)bytestream_get_le16(&src); - previous_left_sample = (int16_t)bytestream_get_le16(&src); - current_right_sample = (int16_t)bytestream_get_le16(&src); - previous_right_sample = (int16_t)bytestream_get_le16(&src); - - for (count1 = 0; count1 < samples_in_chunk/28;count1++) { - coeff1l = ea_adpcm_table[ *src >> 4 ]; - coeff2l = ea_adpcm_table[(*src >> 4 ) + 4]; - coeff1r = ea_adpcm_table[*src & 0x0F]; - coeff2r = ea_adpcm_table[(*src & 0x0F) + 4]; - src++; - - shift_left = (*src >> 4 ) + 8; - shift_right = (*src & 0x0F) + 8; - src++; - - for (count2 = 0; count2 < 28; count2++) { - next_left_sample = (int32_t)((*src & 0xF0) << 24) >> shift_left; - next_right_sample = (int32_t)((*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; - - previous_left_sample = current_left_sample; - current_left_sample = av_clip_int16(next_left_sample); - previous_right_sample = current_right_sample; - current_right_sample = av_clip_int16(next_right_sample); - *samples++ = (unsigned short)current_left_sample; - *samples++ = (unsigned short)current_right_sample; - } - } - - if (src - buf == buf_size - 2) - src += 2; // Skip terminating 0x0000 - - break; - case CODEC_ID_ADPCM_EA_MAXIS_XA: - for(channel = 0; channel < avctx->channels; channel++) { - for (i=0; i<2; i++) - coeff[channel][i] = ea_adpcm_table[(*src >> 4) + 4*i]; - shift[channel] = (*src & 0x0F) + 8; - src++; - } - for (count1 = 0; count1 < (buf_size - avctx->channels) / avctx->channels; count1++) { - for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */ - for(channel = 0; channel < avctx->channels; channel++) { - int32_t sample = (int32_t)(((*(src+channel) >> i) & 0x0F) << 0x1C) >> shift[channel]; - sample = (sample + - c->status[channel].sample1 * coeff[channel][0] + - c->status[channel].sample2 * coeff[channel][1] + 0x80) >> 8; - c->status[channel].sample2 = c->status[channel].sample1; - c->status[channel].sample1 = av_clip_int16(sample); - *samples++ = c->status[channel].sample1; - } - } - src+=avctx->channels; - } - break; - case CODEC_ID_ADPCM_EA_R1: - case CODEC_ID_ADPCM_EA_R2: - case CODEC_ID_ADPCM_EA_R3: { - /* channel numbering - 2chan: 0=fl, 1=fr - 4chan: 0=fl, 1=rl, 2=fr, 3=rr - 6chan: 0=fl, 1=c, 2=fr, 3=rl, 4=rr, 5=sub */ - const int big_endian = avctx->codec->id == CODEC_ID_ADPCM_EA_R3; - int32_t previous_sample, current_sample, next_sample; - int32_t coeff1, coeff2; - uint8_t shift; - unsigned int channel; - uint16_t *samplesC; - const uint8_t *srcC; - const uint8_t *src_end = buf + buf_size; - - samples_in_chunk = (big_endian ? bytestream_get_be32(&src) - : bytestream_get_le32(&src)) / 28; - if (samples_in_chunk > UINT32_MAX/(28*avctx->channels) || - 28*samples_in_chunk*avctx->channels > samples_end-samples) { - src += buf_size - 4; - break; - } - - for (channel=0; channelchannels; channel++) { - int32_t offset = (big_endian ? bytestream_get_be32(&src) - : bytestream_get_le32(&src)) - + (avctx->channels-channel-1) * 4; - - if ((offset < 0) || (offset >= src_end - src - 4)) break; - srcC = src + offset; - samplesC = samples + channel; - - if (avctx->codec->id == CODEC_ID_ADPCM_EA_R1) { - current_sample = (int16_t)bytestream_get_le16(&srcC); - previous_sample = (int16_t)bytestream_get_le16(&srcC); - } else { - current_sample = c->status[channel].predictor; - previous_sample = c->status[channel].prev_sample; - } - - for (count1=0; count1 src_end - 30*2) break; - current_sample = (int16_t)bytestream_get_be16(&srcC); - previous_sample = (int16_t)bytestream_get_be16(&srcC); - - for (count2=0; count2<28; count2++) { - *samplesC = (int16_t)bytestream_get_be16(&srcC); - samplesC += avctx->channels; - } - } else { - coeff1 = ea_adpcm_table[ *srcC>>4 ]; - coeff2 = ea_adpcm_table[(*srcC>>4) + 4]; - shift = (*srcC++ & 0x0F) + 8; - - if (srcC > src_end - 14) break; - for (count2=0; count2<28; count2++) { - if (count2 & 1) - next_sample = (int32_t)((*srcC++ & 0x0F) << 28) >> shift; - else - next_sample = (int32_t)((*srcC & 0xF0) << 24) >> shift; - - next_sample += (current_sample * coeff1) + - (previous_sample * coeff2); - next_sample = av_clip_int16(next_sample >> 8); - - previous_sample = current_sample; - current_sample = next_sample; - *samplesC = current_sample; - samplesC += avctx->channels; - } - } - } - - if (avctx->codec->id != CODEC_ID_ADPCM_EA_R1) { - c->status[channel].predictor = current_sample; - c->status[channel].prev_sample = previous_sample; - } - } - - src = src + buf_size - (4 + 4*avctx->channels); - samples += 28 * samples_in_chunk * avctx->channels; - break; - } - case CODEC_ID_ADPCM_EA_XAS: - if (samples_end-samples < 32*4*avctx->channels - || buf_size < (4+15)*4*avctx->channels) { - src += buf_size; - break; - } - for (channel=0; channelchannels; channel++) { - int coeff[2][4], shift[4]; - short *s2, *s = &samples[channel]; - for (n=0; n<4; n++, s+=32*avctx->channels) { - for (i=0; i<2; i++) - coeff[i][n] = ea_adpcm_table[(src[0]&0x0F)+4*i]; - shift[n] = (src[2]&0x0F) + 8; - for (s2=s, i=0; i<2; i++, src+=2, s2+=avctx->channels) - s2[0] = (src[0]&0xF0) + (src[1]<<8); - } - - for (m=2; m<32; m+=2) { - s = &samples[m*avctx->channels + channel]; - for (n=0; n<4; n++, src++, s+=32*avctx->channels) { - for (s2=s, i=0; i<8; i+=4, s2+=avctx->channels) { - int level = (int32_t)((*src & (0xF0>>i)) << (24+i)) >> shift[n]; - int pred = s2[-1*avctx->channels] * coeff[0][n] - + s2[-2*avctx->channels] * coeff[1][n]; - s2[0] = av_clip_int16((level + pred + 0x80) >> 8); - } - } - } - } - samples += 32*4*avctx->channels; - break; - case CODEC_ID_ADPCM_IMA_AMV: - case CODEC_ID_ADPCM_IMA_SMJPEG: - c->status[0].predictor = (int16_t)bytestream_get_le16(&src); - c->status[0].step_index = bytestream_get_le16(&src); - - if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV) - src+=4; - - while (src < buf + buf_size) { - char hi, lo; - lo = *src & 0x0F; - hi = *src >> 4; - - if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV) - FFSWAP(char, hi, lo); - - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - lo, 3); - *samples++ = adpcm_ima_expand_nibble(&c->status[0], - hi, 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); - *samples++ = adpcm_ct_expand_nibble(&c->status[1], - src[0] & 0x0F); - } else { - *samples++ = adpcm_ct_expand_nibble(&c->status[0], - src[0] >> 4); - *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, 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 + 2 < samples_end) { - *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], - src[0] >> 5 , 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 + 3 < samples_end) { - *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], - src[0] >> 6 , 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, nb_bits, count; - int size = buf_size*8; - - init_get_bits(&gb, buf, size); - - //read bits & initial values - nb_bits = get_bits(&gb, 2)+2; - //av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", nb_bits); - table = swf_index_tables[nb_bits-2]; - k0 = 1 << (nb_bits-2); - signmask = 1 << (nb_bits-1); - - while (get_bits_count(&gb) <= size - 22*avctx->channels) { - for (i = 0; i < avctx->channels; i++) { - *samples++ = c->status[i].predictor = get_sbits(&gb, 16); - c->status[i].step_index = get_bits(&gb, 6); - } - - for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) { - int i; - - for (i = 0; i < avctx->channels; i++) { - // similar to IMA adpcm - int delta = get_bits(&gb, 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 = av_clip(c->status[i].step_index, 0, 88); - c->status[i].predictor = av_clip_int16(c->status[i].predictor); - - *samples++ = c->status[i].predictor; - if (samples >= samples_end) { - av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); - return -1; - } - } - } - } - src += buf_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 ); - } else { - *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], - src[0] & 0x0F); - *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], - src[0] >> 4 ); - } - src++; - } - break; - case CODEC_ID_ADPCM_THP: - { - int table[2][16]; - unsigned int samplecnt; - int prev[2][2]; - int ch; - - if (buf_size < 80) { - av_log(avctx, AV_LOG_ERROR, "frame too small\n"); - return -1; - } - - src+=4; - samplecnt = bytestream_get_be32(&src); - - for (i = 0; i < 32; i++) - table[0][i] = (int16_t)bytestream_get_be16(&src); - - /* Initialize the previous sample. */ - for (i = 0; i < 4; i++) - prev[0][i] = (int16_t)bytestream_get_be16(&src); - - if (samplecnt >= (samples_end - samples) / (st + 1)) { - av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); - return -1; - } - - for (ch = 0; ch <= st; ch++) { - samples = (unsigned short *) data + ch; - - /* Read in every sample for this channel. */ - for (i = 0; i < samplecnt / 14; i++) { - int index = (*src >> 4) & 7; - unsigned int exp = 28 - (*src++ & 15); - int factor1 = table[ch][index * 2]; - int factor2 = table[ch][index * 2 + 1]; - - /* Decode 14 samples. */ - for (n = 0; n < 14; n++) { - int32_t sampledat; - if(n&1) sampledat= *src++ <<28; - else sampledat= (*src&0xF0)<<24; - - sampledat = ((prev[ch][0]*factor1 - + prev[ch][1]*factor2) >> 11) + (sampledat>>exp); - *samples = av_clip_int16(sampledat); - prev[ch][1] = prev[ch][0]; - prev[ch][0] = *samples++; - - /* In case of stereo, skip one sample, this sample - is for the other channel. */ - samples += st; - } - } - } - - /* In the previous loop, in case stereo is used, samples is - increased exactly one time too often. */ - samples -= st; - break; - } - - default: - return -1; - } - *data_size = (uint8_t *)samples - (uint8_t *)data; - return src - buf; -} - - - -#if CONFIG_ENCODERS -#define ADPCM_ENCODER(id,name,long_name_) \ -AVCodec name ## _encoder = { \ - #name, \ - AVMEDIA_TYPE_AUDIO, \ - id, \ - sizeof(ADPCMContext), \ - adpcm_encode_init, \ - adpcm_encode_frame, \ - adpcm_encode_close, \ - NULL, \ - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ -}; -#else -#define ADPCM_ENCODER(id,name,long_name_) -#endif - -#if CONFIG_DECODERS -#define ADPCM_DECODER(id,name,long_name_) \ -AVCodec name ## _decoder = { \ - #name, \ - AVMEDIA_TYPE_AUDIO, \ - id, \ - sizeof(ADPCMContext), \ - adpcm_decode_init, \ - NULL, \ - NULL, \ - adpcm_decode_frame, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ -}; -#else -#define ADPCM_DECODER(id,name,long_name_) -#endif - -#define ADPCM_CODEC(id,name,long_name_) \ - ADPCM_ENCODER(id,name,long_name_) ADPCM_DECODER(id,name,long_name_) - -/* Note: Do not forget to add new entries to the Makefile as well. */ -ADPCM_DECODER(CODEC_ID_ADPCM_4XM, adpcm_4xm, "ADPCM 4X Movie"); -ADPCM_DECODER(CODEC_ID_ADPCM_CT, adpcm_ct, "ADPCM Creative Technology"); -ADPCM_DECODER(CODEC_ID_ADPCM_EA, adpcm_ea, "ADPCM Electronic Arts"); -ADPCM_DECODER(CODEC_ID_ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa, "ADPCM Electronic Arts Maxis CDROM XA"); -ADPCM_DECODER(CODEC_ID_ADPCM_EA_R1, adpcm_ea_r1, "ADPCM Electronic Arts R1"); -ADPCM_DECODER(CODEC_ID_ADPCM_EA_R2, adpcm_ea_r2, "ADPCM Electronic Arts R2"); -ADPCM_DECODER(CODEC_ID_ADPCM_EA_R3, adpcm_ea_r3, "ADPCM Electronic Arts R3"); -ADPCM_DECODER(CODEC_ID_ADPCM_EA_XAS, adpcm_ea_xas, "ADPCM Electronic Arts XAS"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv, "ADPCM IMA AMV"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3, "ADPCM IMA Duck DK3"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4, "ADPCM IMA Duck DK4"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_ISS, adpcm_ima_iss, "ADPCM IMA Funcom ISS"); -ADPCM_CODEC (CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG"); -ADPCM_CODEC (CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV"); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws, "ADPCM IMA Westwood"); -ADPCM_CODEC (CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft"); -ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit"); -ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit"); -ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit"); -ADPCM_CODEC (CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash"); -ADPCM_DECODER(CODEC_ID_ADPCM_THP, adpcm_thp, "ADPCM Nintendo Gamecube THP"); -ADPCM_DECODER(CODEC_ID_ADPCM_XA, adpcm_xa, "ADPCM CDROM XA"); -ADPCM_CODEC (CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha"); diff --git a/tizen/distrib/ffmpeg/libavcodec/adx.h b/tizen/distrib/ffmpeg/libavcodec/adx.h deleted file mode 100644 index 0fa1003..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/adx.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ADX ADPCM codecs - * Copyright (c) 2001,2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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/ - */ - -#ifndef AVCODEC_ADX_H -#define AVCODEC_ADX_H - -typedef struct { - int s1,s2; -} PREV; - -typedef struct { - PREV prev[2]; - int header_parsed; - unsigned char dec_temp[18*2]; - int in_temp; -} ADXContext; - -#define BASEVOL 0x4000 -#define SCALE1 0x7298 -#define SCALE2 0x3350 - -#endif /* AVCODEC_ADX_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/adxdec.c b/tizen/distrib/ffmpeg/libavcodec/adxdec.c deleted file mode 100644 index adb22fc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/adxdec.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * ADX ADPCM codecs - * Copyright (c) 2001,2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "adx.h" - -/** - * @file - * 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/ - */ - -static av_cold int adx_decode_init(AVCodecContext *avctx) -{ - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -/* 18 bytes <-> 32 samples */ - -static void adx_decode(short *out,const unsigned char *in,PREV *prev) -{ - int scale = AV_RB16(in); - 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; - s2 = s1; - s1 = av_clip_int16(s0); - *out++=s1; - - 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; - s2 = s1; - s1 = av_clip_int16(s0); - *out++=s1; - } - 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]; - } -} - -/* return data offset or 0 */ -static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) -{ - int offset; - - if (buf[0]!=0x80) return 0; - offset = (AV_RB32(buf)^0x80000000)+4; - if (bufsizechannels = buf[7]; - avctx->sample_rate = AV_RB32(buf+8); - avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; - - return offset; -} - -static int adx_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf0 = avpkt->data; - int buf_size = avpkt->size; - ADXContext *c = avctx->priv_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; - } - - /* 18 bytes of data are expanded into 32*2 bytes of audio, - so guard against buffer overflows */ - if(rest/18 > *data_size/64) - rest = (*data_size/64) * 18; - - 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; -} - -AVCodec adpcm_adx_decoder = { - "adpcm_adx", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_ADPCM_ADX, - sizeof(ADXContext), - adx_decode_init, - NULL, - NULL, - adx_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/adxenc.c b/tizen/distrib/ffmpeg/libavcodec/adxenc.c deleted file mode 100644 index 116b746..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/adxenc.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * ADX ADPCM codecs - * Copyright (c) 2001,2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "adx.h" - -/** - * @file - * 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/ - */ - -/* 18 bytes <-> 32 samples */ - -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; - - AV_WB16(adx, scale); - - for(i=0;i<16;i++) { - adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf); - } -} - -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 - AV_WB32(buf+0x00,0x80000000|0x20); - AV_WB32(buf+0x04,0x03120400|avctx->channels); - AV_WB32(buf+0x08,avctx->sample_rate); - AV_WB32(buf+0x0c,0); /* FIXME: set after */ - AV_WB32(buf+0x10,0x01040300); - AV_WB32(buf+0x14,0x00000000); - AV_WB32(buf+0x18,0x00000000); - memcpy(buf+0x1c,"\0\0(c)CRI",8); - return 0x20+4; -} - -static av_cold 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"); - - return 0; -} - -static av_cold 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; -} - -AVCodec adpcm_adx_encoder = { - "adpcm_adx", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_ADPCM_ADX, - sizeof(ADXContext), - adx_encode_init, - adx_encode_frame, - adx_encode_close, - NULL, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/alac.c b/tizen/distrib/ffmpeg/libavcodec/alac.c deleted file mode 100644 index 50fc7a1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alac.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * ALAC (Apple Lossless Audio Codec) decoder - * Copyright (c) 2005 David Hammerton - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 "get_bits.h" -#include "bytestream.h" -#include "unary.h" -#include "mathops.h" - -#define ALAC_EXTRADATA_SIZE 36 -#define MAX_CHANNELS 2 - -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 numchannels; - int bytespersample; - - /* buffers */ - int32_t *predicterror_buffer[MAX_CHANNELS]; - - int32_t *outputsamples_buffer[MAX_CHANNELS]; - - int32_t *wasted_bits_buffer[MAX_CHANNELS]; - - /* stuff from setinfo */ - uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */ - uint8_t setinfo_sample_size; /* 0x10 */ - uint8_t setinfo_rice_historymult; /* 0x28 */ - uint8_t setinfo_rice_initialhistory; /* 0x0a */ - uint8_t setinfo_rice_kmodifier; /* 0x0e */ - /* end setinfo stuff */ - - int wasted_bits; -} ALACContext; - -static void allocate_buffers(ALACContext *alac) -{ - int chan; - for (chan = 0; chan < MAX_CHANNELS; chan++) { - alac->predicterror_buffer[chan] = - av_malloc(alac->setinfo_max_samples_per_frame * 4); - - alac->outputsamples_buffer[chan] = - av_malloc(alac->setinfo_max_samples_per_frame * 4); - - alac->wasted_bits_buffer[chan] = av_malloc(alac->setinfo_max_samples_per_frame * 4); - } -} - -static int alac_set_info(ALACContext *alac) -{ - const unsigned char *ptr = alac->avctx->extradata; - - ptr += 4; /* size */ - ptr += 4; /* alac */ - ptr += 4; /* 0 ? */ - - if(AV_RB32(ptr) >= UINT_MAX/4){ - av_log(alac->avctx, AV_LOG_ERROR, "setinfo_max_samples_per_frame too large\n"); - return -1; - } - - /* buffer size / 2 ? */ - alac->setinfo_max_samples_per_frame = bytestream_get_be32(&ptr); - ptr++; /* ??? */ - alac->setinfo_sample_size = *ptr++; - if (alac->setinfo_sample_size > 32) { - av_log(alac->avctx, AV_LOG_ERROR, "setinfo_sample_size too large\n"); - return -1; - } - alac->setinfo_rice_historymult = *ptr++; - alac->setinfo_rice_initialhistory = *ptr++; - alac->setinfo_rice_kmodifier = *ptr++; - ptr++; /* channels? */ - bytestream_get_be16(&ptr); /* ??? */ - bytestream_get_be32(&ptr); /* max coded frame size */ - bytestream_get_be32(&ptr); /* bitrate ? */ - bytestream_get_be32(&ptr); /* samplerate */ - - allocate_buffers(alac); - - return 0; -} - -static inline int decode_scalar(GetBitContext *gb, int k, int limit, int readsamplesize){ - /* read x - number of 1s before 0 represent the rice */ - int x = get_unary_0_9(gb); - - if (x > 8) { /* RICE THRESHOLD */ - /* use alternative encoding */ - x = get_bits(gb, readsamplesize); - } else { - if (k >= limit) - k = limit; - - if (k != 1) { - int extrabits = show_bits(gb, k); - - /* multiply x by 2^k - 1, as part of their strange algorithm */ - x = (x << k) - x; - - if (extrabits > 1) { - x += extrabits - 1; - skip_bits(gb, k); - } else - skip_bits(gb, k - 1); - } - } - return x; -} - -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; - int32_t x_modified; - int32_t final_val; - - /* standard rice encoding */ - int k; /* size of extra bits */ - - /* read k, that is bits as is */ - k = av_log2((history >> 9) + 3); - x= decode_scalar(&alac->gb, k, rice_kmodifier, readsamplesize); - - 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 k; - unsigned int block_size; - - sign_modifier = 1; - - k = 7 - av_log2(history) + ((history + 16) >> 6 /* / 64 */); - - block_size= decode_scalar(&alac->gb, k, rice_kmodifier, 16); - - if (block_size > 0) { - if(block_size >= output_size - output_count){ - av_log(alac->avctx, AV_LOG_ERROR, "invalid zero block size of %d %d %d\n", block_size, output_size, output_count); - block_size= output_size - output_count - 1; - } - memset(&output_buffer[output_count+1], 0, block_size * 4); - output_count += block_size; - } - - if (block_size > 0xffff) - sign_modifier = 0; - - history = 0; - } - } -} - -static inline int sign_only(int v) -{ - return v ? FFSIGN(v) : 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_extend((prev_value + error_value), readsamplesize); - } - return; - } - - /* read warm-up samples */ - if (predictor_coef_num > 0) - for (i = 0; i < predictor_coef_num; i++) { - int32_t val; - - val = buffer_out[i] + error_buffer[i+1]; - val = sign_extend(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 optimized - */ - if (predictor_coef_num == 4) { - /* FIXME: optimized general case */ - return; - } - - if (predictor_coef_table == 8) { - /* FIXME: optimized 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_extend(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++; - } - } -} - -static void reconstruct_stereo_16(int32_t *buffer[MAX_CHANNELS], - 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 a, b; - - a = buffer[0][i]; - b = buffer[1][i]; - - a -= (b * interlacing_leftweight) >> interlacing_shift; - b += a; - - buffer_out[i*numchannels] = b; - buffer_out[i*numchannels + 1] = a; - } - - return; - } - - /* otherwise basic interlacing took place */ - for (i = 0; i < numsamples; i++) { - int16_t left, right; - - left = buffer[0][i]; - right = buffer[1][i]; - - buffer_out[i*numchannels] = left; - buffer_out[i*numchannels + 1] = right; - } -} - -static void decorrelate_stereo_24(int32_t *buffer[MAX_CHANNELS], - int32_t *buffer_out, - int32_t *wasted_bits_buffer[MAX_CHANNELS], - int wasted_bits, - 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 a, b; - - a = buffer[0][i]; - b = buffer[1][i]; - - a -= (b * interlacing_leftweight) >> interlacing_shift; - b += a; - - if (wasted_bits) { - b = (b << wasted_bits) | wasted_bits_buffer[0][i]; - a = (a << wasted_bits) | wasted_bits_buffer[1][i]; - } - - buffer_out[i * numchannels] = b << 8; - buffer_out[i * numchannels + 1] = a << 8; - } - } else { - for (i = 0; i < numsamples; i++) { - int32_t left, right; - - left = buffer[0][i]; - right = buffer[1][i]; - - if (wasted_bits) { - left = (left << wasted_bits) | wasted_bits_buffer[0][i]; - right = (right << wasted_bits) | wasted_bits_buffer[1][i]; - } - - buffer_out[i * numchannels] = left << 8; - buffer_out[i * numchannels + 1] = right << 8; - } - } -} - -static int alac_decode_frame(AVCodecContext *avctx, - void *outbuffer, int *outputsize, - AVPacket *avpkt) -{ - const uint8_t *inbuffer = avpkt->data; - int input_buffer_size = avpkt->size; - ALACContext *alac = avctx->priv_data; - - int channels; - unsigned int outputsamples; - int hassize; - unsigned int readsamplesize; - int isnotcompressed; - uint8_t interlacing_shift; - uint8_t interlacing_leftweight; - - /* 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; - } - if (alac_set_info(alac)) { - av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n"); - return input_buffer_size; - } - alac->context_initialized = 1; - } - - init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8); - - channels = get_bits(&alac->gb, 3) + 1; - if (channels > MAX_CHANNELS) { - av_log(avctx, AV_LOG_ERROR, "channels > %d not supported\n", - MAX_CHANNELS); - return input_buffer_size; - } - - /* 2^result = something to do with output waiting. - * perhaps matters if we read > 1 frame in a pass? - */ - skip_bits(&alac->gb, 4); - - skip_bits(&alac->gb, 12); /* unknown, skip 12 bits */ - - /* the output sample size is stored soon */ - hassize = get_bits1(&alac->gb); - - alac->wasted_bits = get_bits(&alac->gb, 2) << 3; - - /* whether the frame is compressed */ - isnotcompressed = get_bits1(&alac->gb); - - if (hassize) { - /* now read the number of samples as a 32bit integer */ - outputsamples = get_bits_long(&alac->gb, 32); - if(outputsamples > alac->setinfo_max_samples_per_frame){ - av_log(avctx, AV_LOG_ERROR, "outputsamples %d > %d\n", outputsamples, alac->setinfo_max_samples_per_frame); - return -1; - } - } else - outputsamples = alac->setinfo_max_samples_per_frame; - - switch (alac->setinfo_sample_size) { - case 16: avctx->sample_fmt = SAMPLE_FMT_S16; - alac->bytespersample = channels << 1; - break; - case 24: avctx->sample_fmt = SAMPLE_FMT_S32; - alac->bytespersample = channels << 2; - break; - default: av_log(avctx, AV_LOG_ERROR, "Sample depth %d is not supported.\n", - alac->setinfo_sample_size); - return -1; - } - - if(outputsamples > *outputsize / alac->bytespersample){ - av_log(avctx, AV_LOG_ERROR, "sample buffer too small\n"); - return -1; - } - - *outputsize = outputsamples * alac->bytespersample; - readsamplesize = alac->setinfo_sample_size - (alac->wasted_bits) + channels - 1; - if (readsamplesize > MIN_CACHE_BITS) { - av_log(avctx, AV_LOG_ERROR, "readsamplesize too big (%d)\n", readsamplesize); - return -1; - } - - if (!isnotcompressed) { - /* so it is compressed */ - int16_t predictor_coef_table[channels][32]; - int predictor_coef_num[channels]; - int prediction_type[channels]; - int prediction_quantitization[channels]; - int ricemodifier[channels]; - int i, chan; - - interlacing_shift = get_bits(&alac->gb, 8); - interlacing_leftweight = get_bits(&alac->gb, 8); - - for (chan = 0; chan < channels; chan++) { - prediction_type[chan] = get_bits(&alac->gb, 4); - prediction_quantitization[chan] = get_bits(&alac->gb, 4); - - ricemodifier[chan] = get_bits(&alac->gb, 3); - predictor_coef_num[chan] = get_bits(&alac->gb, 5); - - /* read the predictor table */ - for (i = 0; i < predictor_coef_num[chan]; i++) - predictor_coef_table[chan][i] = (int16_t)get_bits(&alac->gb, 16); - } - - if (alac->wasted_bits) { - int i, ch; - for (i = 0; i < outputsamples; i++) { - for (ch = 0; ch < channels; ch++) - alac->wasted_bits_buffer[ch][i] = get_bits(&alac->gb, alac->wasted_bits); - } - } - for (chan = 0; chan < channels; chan++) { - bastardized_rice_decompress(alac, - alac->predicterror_buffer[chan], - outputsamples, - readsamplesize, - alac->setinfo_rice_initialhistory, - alac->setinfo_rice_kmodifier, - ricemodifier[chan] * alac->setinfo_rice_historymult / 4, - (1 << alac->setinfo_rice_kmodifier) - 1); - - if (prediction_type[chan] == 0) { - /* adaptive fir */ - predictor_decompress_fir_adapt(alac->predicterror_buffer[chan], - alac->outputsamples_buffer[chan], - outputsamples, - readsamplesize, - predictor_coef_table[chan], - predictor_coef_num[chan], - prediction_quantitization[chan]); - } else { - av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[chan]); - /* 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 */ - int i, chan; - if (alac->setinfo_sample_size <= 16) { - for (i = 0; i < outputsamples; i++) - for (chan = 0; chan < channels; chan++) { - int32_t audiobits; - - audiobits = get_sbits_long(&alac->gb, alac->setinfo_sample_size); - - alac->outputsamples_buffer[chan][i] = audiobits; - } - } else { - for (i = 0; i < outputsamples; i++) { - for (chan = 0; chan < channels; chan++) { - alac->outputsamples_buffer[chan][i] = get_bits(&alac->gb, - alac->setinfo_sample_size); - alac->outputsamples_buffer[chan][i] = sign_extend(alac->outputsamples_buffer[chan][i], - alac->setinfo_sample_size); - } - } - } - alac->wasted_bits = 0; - interlacing_shift = 0; - interlacing_leftweight = 0; - } - if (get_bits(&alac->gb, 3) != 7) - av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n"); - - switch(alac->setinfo_sample_size) { - case 16: - if (channels == 2) { - reconstruct_stereo_16(alac->outputsamples_buffer, - (int16_t*)outbuffer, - alac->numchannels, - outputsamples, - interlacing_shift, - interlacing_leftweight); - } else { - int i; - for (i = 0; i < outputsamples; i++) { - ((int16_t*)outbuffer)[i] = alac->outputsamples_buffer[0][i]; - } - } - break; - case 24: - if (channels == 2) { - decorrelate_stereo_24(alac->outputsamples_buffer, - outbuffer, - alac->wasted_bits_buffer, - alac->wasted_bits, - alac->numchannels, - outputsamples, - interlacing_shift, - interlacing_leftweight); - } else { - int i; - for (i = 0; i < outputsamples; i++) - ((int32_t *)outbuffer)[i] = alac->outputsamples_buffer[0][i] << 8; - } - break; - } - - if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8) - av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", input_buffer_size * 8 - get_bits_count(&alac->gb)); - - return input_buffer_size; -} - -static av_cold int alac_decode_init(AVCodecContext * avctx) -{ - ALACContext *alac = avctx->priv_data; - alac->avctx = avctx; - alac->context_initialized = 0; - - alac->numchannels = alac->avctx->channels; - - return 0; -} - -static av_cold int alac_decode_close(AVCodecContext *avctx) -{ - ALACContext *alac = avctx->priv_data; - - int chan; - for (chan = 0; chan < MAX_CHANNELS; chan++) { - av_freep(&alac->predicterror_buffer[chan]); - av_freep(&alac->outputsamples_buffer[chan]); - av_freep(&alac->wasted_bits_buffer[chan]); - } - - return 0; -} - -AVCodec alac_decoder = { - "alac", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_ALAC, - sizeof(ALACContext), - alac_decode_init, - NULL, - alac_decode_close, - alac_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/alacenc.c b/tizen/distrib/ffmpeg/libavcodec/alacenc.c deleted file mode 100644 index 0876633..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alacenc.c +++ /dev/null @@ -1,532 +0,0 @@ -/** - * ALAC audio encoder - * Copyright (c) 2008 Jaikrishnan Menon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "put_bits.h" -#include "dsputil.h" -#include "lpc.h" -#include "mathops.h" - -#define DEFAULT_FRAME_SIZE 4096 -#define DEFAULT_SAMPLE_SIZE 16 -#define MAX_CHANNELS 8 -#define ALAC_EXTRADATA_SIZE 36 -#define ALAC_FRAME_HEADER_SIZE 55 -#define ALAC_FRAME_FOOTER_SIZE 3 - -#define ALAC_ESCAPE_CODE 0x1FF -#define ALAC_MAX_LPC_ORDER 30 -#define DEFAULT_MAX_PRED_ORDER 6 -#define DEFAULT_MIN_PRED_ORDER 4 -#define ALAC_MAX_LPC_PRECISION 9 -#define ALAC_MAX_LPC_SHIFT 9 - -#define ALAC_CHMODE_LEFT_RIGHT 0 -#define ALAC_CHMODE_LEFT_SIDE 1 -#define ALAC_CHMODE_RIGHT_SIDE 2 -#define ALAC_CHMODE_MID_SIDE 3 - -typedef struct RiceContext { - int history_mult; - int initial_history; - int k_modifier; - int rice_modifier; -} RiceContext; - -typedef struct LPCContext { - int lpc_order; - int lpc_coeff[ALAC_MAX_LPC_ORDER+1]; - int lpc_quant; -} LPCContext; - -typedef struct AlacEncodeContext { - int compression_level; - int min_prediction_order; - int max_prediction_order; - int max_coded_frame_size; - int write_sample_size; - int32_t sample_buf[MAX_CHANNELS][DEFAULT_FRAME_SIZE]; - int32_t predictor_buf[DEFAULT_FRAME_SIZE]; - int interlacing_shift; - int interlacing_leftweight; - PutBitContext pbctx; - RiceContext rc; - LPCContext lpc[MAX_CHANNELS]; - DSPContext dspctx; - AVCodecContext *avctx; -} AlacEncodeContext; - - -static void init_sample_buffers(AlacEncodeContext *s, int16_t *input_samples) -{ - int ch, i; - - for(ch=0;chavctx->channels;ch++) { - int16_t *sptr = input_samples + ch; - for(i=0;iavctx->frame_size;i++) { - s->sample_buf[ch][i] = *sptr; - sptr += s->avctx->channels; - } - } -} - -static void encode_scalar(AlacEncodeContext *s, int x, int k, int write_sample_size) -{ - int divisor, q, r; - - k = FFMIN(k, s->rc.k_modifier); - divisor = (1< 8) { - // write escape code and sample value directly - put_bits(&s->pbctx, 9, ALAC_ESCAPE_CODE); - put_bits(&s->pbctx, write_sample_size, x); - } else { - if(q) - put_bits(&s->pbctx, q, (1<pbctx, 1, 0); - - if(k != 1) { - if(r > 0) - put_bits(&s->pbctx, k, r+1); - else - put_bits(&s->pbctx, k-1, 0); - } - } -} - -static void write_frame_header(AlacEncodeContext *s, int is_verbatim) -{ - put_bits(&s->pbctx, 3, s->avctx->channels-1); // No. of channels -1 - put_bits(&s->pbctx, 16, 0); // Seems to be zero - put_bits(&s->pbctx, 1, 1); // Sample count is in the header - put_bits(&s->pbctx, 2, 0); // FIXME: Wasted bytes field - put_bits(&s->pbctx, 1, is_verbatim); // Audio block is verbatim - put_bits32(&s->pbctx, s->avctx->frame_size); // No. of samples in the frame -} - -static void calc_predictor_params(AlacEncodeContext *s, int ch) -{ - int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER]; - int shift[MAX_LPC_ORDER]; - int opt_order; - - if (s->compression_level == 1) { - s->lpc[ch].lpc_order = 6; - s->lpc[ch].lpc_quant = 6; - s->lpc[ch].lpc_coeff[0] = 160; - s->lpc[ch].lpc_coeff[1] = -190; - s->lpc[ch].lpc_coeff[2] = 170; - s->lpc[ch].lpc_coeff[3] = -130; - s->lpc[ch].lpc_coeff[4] = 80; - s->lpc[ch].lpc_coeff[5] = -25; - } else { - opt_order = ff_lpc_calc_coefs(&s->dspctx, s->sample_buf[ch], - s->avctx->frame_size, - s->min_prediction_order, - s->max_prediction_order, - ALAC_MAX_LPC_PRECISION, coefs, shift, 1, - ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1); - - s->lpc[ch].lpc_order = opt_order; - s->lpc[ch].lpc_quant = shift[opt_order-1]; - memcpy(s->lpc[ch].lpc_coeff, coefs[opt_order-1], opt_order*sizeof(int)); - } -} - -static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) -{ - int i, best; - int32_t lt, rt; - uint64_t sum[4]; - uint64_t score[4]; - - /* calculate sum of 2nd order residual for each channel */ - sum[0] = sum[1] = sum[2] = sum[3] = 0; - for(i=2; i> 1); - sum[3] += FFABS(lt - rt); - sum[0] += FFABS(lt); - sum[1] += FFABS(rt); - } - - /* calculate score for each mode */ - score[0] = sum[0] + sum[1]; - score[1] = sum[0] + sum[3]; - score[2] = sum[1] + sum[3]; - score[3] = sum[2] + sum[3]; - - /* return mode with lowest score */ - best = 0; - for(i=1; i<4; i++) { - if(score[i] < score[best]) { - best = i; - } - } - return best; -} - -static void alac_stereo_decorrelation(AlacEncodeContext *s) -{ - int32_t *left = s->sample_buf[0], *right = s->sample_buf[1]; - int i, mode, n = s->avctx->frame_size; - int32_t tmp; - - mode = estimate_stereo_mode(left, right, n); - - switch(mode) - { - case ALAC_CHMODE_LEFT_RIGHT: - s->interlacing_leftweight = 0; - s->interlacing_shift = 0; - break; - - case ALAC_CHMODE_LEFT_SIDE: - for(i=0; iinterlacing_leftweight = 1; - s->interlacing_shift = 0; - break; - - case ALAC_CHMODE_RIGHT_SIDE: - for(i=0; i> 31); - } - s->interlacing_leftweight = 1; - s->interlacing_shift = 31; - break; - - default: - for(i=0; i> 1; - right[i] = tmp - right[i]; - } - s->interlacing_leftweight = 1; - s->interlacing_shift = 1; - break; - } -} - -static void alac_linear_predictor(AlacEncodeContext *s, int ch) -{ - int i; - LPCContext lpc = s->lpc[ch]; - - if(lpc.lpc_order == 31) { - s->predictor_buf[0] = s->sample_buf[ch][0]; - - for(i=1; iavctx->frame_size; i++) - s->predictor_buf[i] = s->sample_buf[ch][i] - s->sample_buf[ch][i-1]; - - return; - } - - // generalised linear predictor - - if(lpc.lpc_order > 0) { - int32_t *samples = s->sample_buf[ch]; - int32_t *residual = s->predictor_buf; - - // generate warm-up samples - residual[0] = samples[0]; - for(i=1;i<=lpc.lpc_order;i++) - residual[i] = samples[i] - samples[i-1]; - - // perform lpc on remaining samples - for(i = lpc.lpc_order + 1; i < s->avctx->frame_size; i++) { - int sum = 1 << (lpc.lpc_quant - 1), res_val, j; - - for (j = 0; j < lpc.lpc_order; j++) { - sum += (samples[lpc.lpc_order-j] - samples[0]) * - lpc.lpc_coeff[j]; - } - - sum >>= lpc.lpc_quant; - sum += samples[0]; - residual[i] = sign_extend(samples[lpc.lpc_order+1] - sum, - s->write_sample_size); - res_val = residual[i]; - - if(res_val) { - int index = lpc.lpc_order - 1; - int neg = (res_val < 0); - - while(index >= 0 && (neg ? (res_val < 0):(res_val > 0))) { - int val = samples[0] - samples[lpc.lpc_order - index]; - int sign = (val ? FFSIGN(val) : 0); - - if(neg) - sign*=-1; - - lpc.lpc_coeff[index] -= sign; - val *= sign; - res_val -= ((val >> lpc.lpc_quant) * - (lpc.lpc_order - index)); - index--; - } - } - samples++; - } - } -} - -static void alac_entropy_coder(AlacEncodeContext *s) -{ - unsigned int history = s->rc.initial_history; - int sign_modifier = 0, i, k; - int32_t *samples = s->predictor_buf; - - for(i=0;i < s->avctx->frame_size;) { - int x; - - k = av_log2((history >> 9) + 3); - - x = -2*(*samples)-1; - x ^= (x>>31); - - samples++; - i++; - - encode_scalar(s, x - sign_modifier, k, s->write_sample_size); - - history += x * s->rc.history_mult - - ((history * s->rc.history_mult) >> 9); - - sign_modifier = 0; - if(x > 0xFFFF) - history = 0xFFFF; - - if((history < 128) && (i < s->avctx->frame_size)) { - unsigned int block_size = 0; - - k = 7 - av_log2(history) + ((history + 16) >> 6); - - while((*samples == 0) && (i < s->avctx->frame_size)) { - samples++; - i++; - block_size++; - } - encode_scalar(s, block_size, k, 16); - - sign_modifier = (block_size <= 0xFFFF); - - history = 0; - } - - } -} - -static void write_compressed_frame(AlacEncodeContext *s) -{ - int i, j; - - if(s->avctx->channels == 2) - alac_stereo_decorrelation(s); - put_bits(&s->pbctx, 8, s->interlacing_shift); - put_bits(&s->pbctx, 8, s->interlacing_leftweight); - - for(i=0;iavctx->channels;i++) { - - calc_predictor_params(s, i); - - put_bits(&s->pbctx, 4, 0); // prediction type : currently only type 0 has been RE'd - put_bits(&s->pbctx, 4, s->lpc[i].lpc_quant); - - put_bits(&s->pbctx, 3, s->rc.rice_modifier); - put_bits(&s->pbctx, 5, s->lpc[i].lpc_order); - // predictor coeff. table - for(j=0;jlpc[i].lpc_order;j++) { - put_sbits(&s->pbctx, 16, s->lpc[i].lpc_coeff[j]); - } - } - - // apply lpc and entropy coding to audio samples - - for(i=0;iavctx->channels;i++) { - alac_linear_predictor(s, i); - alac_entropy_coder(s); - } -} - -static av_cold int alac_encode_init(AVCodecContext *avctx) -{ - AlacEncodeContext *s = avctx->priv_data; - uint8_t *alac_extradata = av_mallocz(ALAC_EXTRADATA_SIZE+1); - - avctx->frame_size = DEFAULT_FRAME_SIZE; - avctx->bits_per_coded_sample = DEFAULT_SAMPLE_SIZE; - - if(avctx->sample_fmt != SAMPLE_FMT_S16) { - av_log(avctx, AV_LOG_ERROR, "only pcm_s16 input samples are supported\n"); - return -1; - } - - // Set default compression level - if(avctx->compression_level == FF_COMPRESSION_DEFAULT) - s->compression_level = 2; - else - s->compression_level = av_clip(avctx->compression_level, 0, 2); - - // Initialize default Rice parameters - s->rc.history_mult = 40; - s->rc.initial_history = 10; - s->rc.k_modifier = 14; - s->rc.rice_modifier = 4; - - s->max_coded_frame_size = 8 + (avctx->frame_size*avctx->channels*avctx->bits_per_coded_sample>>3); - - s->write_sample_size = avctx->bits_per_coded_sample + avctx->channels - 1; // FIXME: consider wasted_bytes - - AV_WB32(alac_extradata, ALAC_EXTRADATA_SIZE); - AV_WB32(alac_extradata+4, MKBETAG('a','l','a','c')); - AV_WB32(alac_extradata+12, avctx->frame_size); - AV_WB8 (alac_extradata+17, avctx->bits_per_coded_sample); - AV_WB8 (alac_extradata+21, avctx->channels); - AV_WB32(alac_extradata+24, s->max_coded_frame_size); - AV_WB32(alac_extradata+28, avctx->sample_rate*avctx->channels*avctx->bits_per_coded_sample); // average bitrate - AV_WB32(alac_extradata+32, avctx->sample_rate); - - // Set relevant extradata fields - if(s->compression_level > 0) { - AV_WB8(alac_extradata+18, s->rc.history_mult); - AV_WB8(alac_extradata+19, s->rc.initial_history); - AV_WB8(alac_extradata+20, s->rc.k_modifier); - } - - s->min_prediction_order = DEFAULT_MIN_PRED_ORDER; - if(avctx->min_prediction_order >= 0) { - if(avctx->min_prediction_order < MIN_LPC_ORDER || - avctx->min_prediction_order > ALAC_MAX_LPC_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n", avctx->min_prediction_order); - return -1; - } - - s->min_prediction_order = avctx->min_prediction_order; - } - - s->max_prediction_order = DEFAULT_MAX_PRED_ORDER; - if(avctx->max_prediction_order >= 0) { - if(avctx->max_prediction_order < MIN_LPC_ORDER || - avctx->max_prediction_order > ALAC_MAX_LPC_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n", avctx->max_prediction_order); - return -1; - } - - s->max_prediction_order = avctx->max_prediction_order; - } - - if(s->max_prediction_order < s->min_prediction_order) { - av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n", - s->min_prediction_order, s->max_prediction_order); - return -1; - } - - avctx->extradata = alac_extradata; - avctx->extradata_size = ALAC_EXTRADATA_SIZE; - - avctx->coded_frame = avcodec_alloc_frame(); - avctx->coded_frame->key_frame = 1; - - s->avctx = avctx; - dsputil_init(&s->dspctx, avctx); - - return 0; -} - -static int alac_encode_frame(AVCodecContext *avctx, uint8_t *frame, - int buf_size, void *data) -{ - AlacEncodeContext *s = avctx->priv_data; - PutBitContext *pb = &s->pbctx; - int i, out_bytes, verbatim_flag = 0; - - if(avctx->frame_size > DEFAULT_FRAME_SIZE) { - av_log(avctx, AV_LOG_ERROR, "input frame size exceeded\n"); - return -1; - } - - if(buf_size < 2*s->max_coded_frame_size) { - av_log(avctx, AV_LOG_ERROR, "buffer size is too small\n"); - return -1; - } - -verbatim: - init_put_bits(pb, frame, buf_size); - - if((s->compression_level == 0) || verbatim_flag) { - // Verbatim mode - int16_t *samples = data; - write_frame_header(s, 1); - for(i=0; iframe_size*avctx->channels; i++) { - put_sbits(pb, 16, *samples++); - } - } else { - init_sample_buffers(s, data); - write_frame_header(s, 0); - write_compressed_frame(s); - } - - put_bits(pb, 3, 7); - flush_put_bits(pb); - out_bytes = put_bits_count(pb) >> 3; - - if(out_bytes > s->max_coded_frame_size) { - /* frame too large. use verbatim mode */ - if(verbatim_flag || (s->compression_level == 0)) { - /* still too large. must be an error. */ - av_log(avctx, AV_LOG_ERROR, "error encoding frame\n"); - return -1; - } - verbatim_flag = 1; - goto verbatim; - } - - return out_bytes; -} - -static av_cold int alac_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->extradata); - avctx->extradata_size = 0; - av_freep(&avctx->coded_frame); - return 0; -} - -AVCodec alac_encoder = { - "alac", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_ALAC, - sizeof(AlacEncodeContext), - alac_encode_init, - alac_encode_frame, - alac_encode_close, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME, - .sample_fmts = (const enum SampleFormat[]){ SAMPLE_FMT_S16, SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/allcodecs.c b/tizen/distrib/ffmpeg/libavcodec/allcodecs.c deleted file mode 100644 index aa3001c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/allcodecs.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Provides registration of all codecs, parsers and bitstream filters for libavcodec. - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Provides registration of all codecs, parsers and bitstream filters for libavcodec. - */ - -#include "avcodec.h" - -#define REGISTER_HWACCEL(X,x) { \ - extern AVHWAccel x##_hwaccel; \ - if(CONFIG_##X##_HWACCEL) av_register_hwaccel(&x##_hwaccel); } - -#define REGISTER_ENCODER(X,x) { \ - extern AVCodec x##_encoder; \ - if(CONFIG_##X##_ENCODER) avcodec_register(&x##_encoder); } -#define REGISTER_DECODER(X,x) { \ - extern AVCodec x##_decoder; \ - if(CONFIG_##X##_DECODER) avcodec_register(&x##_decoder); } -#define REGISTER_ENCDEC(X,x) REGISTER_ENCODER(X,x); REGISTER_DECODER(X,x) - -#define REGISTER_PARSER(X,x) { \ - extern AVCodecParser x##_parser; \ - if(CONFIG_##X##_PARSER) av_register_codec_parser(&x##_parser); } -#define REGISTER_BSF(X,x) { \ - extern AVBitStreamFilter x##_bsf; \ - if(CONFIG_##X##_BSF) av_register_bitstream_filter(&x##_bsf); } - -void avcodec_register_all(void) -{ - static int initialized; - - if (initialized) - return; - initialized = 1; - - /* hardware accelerators */ - REGISTER_HWACCEL (H263_VAAPI, h263_vaapi); - REGISTER_HWACCEL (H264_DXVA2, h264_dxva2); - REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); - REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); - REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); - REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); - REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); - REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2); - REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi); - - /* video codecs */ - REGISTER_DECODER (AASC, aasc); - REGISTER_DECODER (AMV, amv); - REGISTER_DECODER (ANM, anm); - REGISTER_ENCDEC (ASV1, asv1); - REGISTER_ENCDEC (ASV2, asv2); - REGISTER_DECODER (AURA, aura); - REGISTER_DECODER (AURA2, aura2); - REGISTER_DECODER (AVS, avs); - REGISTER_DECODER (BETHSOFTVID, bethsoftvid); - REGISTER_DECODER (BFI, bfi); - REGISTER_DECODER (BINK, bink); - REGISTER_ENCDEC (BMP, bmp); - REGISTER_DECODER (C93, c93); - REGISTER_DECODER (CAVS, cavs); - REGISTER_DECODER (CDGRAPHICS, cdgraphics); - REGISTER_DECODER (CINEPAK, cinepak); - REGISTER_DECODER (CLJR, cljr); - REGISTER_DECODER (CSCD, cscd); - REGISTER_DECODER (CYUV, cyuv); - REGISTER_ENCDEC (DNXHD, dnxhd); - REGISTER_DECODER (DPX, dpx); - REGISTER_DECODER (DSICINVIDEO, dsicinvideo); - REGISTER_ENCDEC (DVVIDEO, dvvideo); - REGISTER_DECODER (DXA, dxa); - REGISTER_DECODER (EACMV, eacmv); - REGISTER_DECODER (EAMAD, eamad); - REGISTER_DECODER (EATGQ, eatgq); - REGISTER_DECODER (EATGV, eatgv); - REGISTER_DECODER (EATQI, eatqi); - REGISTER_DECODER (EIGHTBPS, eightbps); - REGISTER_DECODER (EIGHTSVX_EXP, eightsvx_exp); - REGISTER_DECODER (EIGHTSVX_FIB, eightsvx_fib); - REGISTER_DECODER (ESCAPE124, escape124); - REGISTER_ENCDEC (FFV1, ffv1); - REGISTER_ENCDEC (FFVHUFF, ffvhuff); - REGISTER_ENCDEC (FLASHSV, flashsv); - REGISTER_DECODER (FLIC, flic); - REGISTER_ENCDEC (FLV, flv); - REGISTER_DECODER (FOURXM, fourxm); - REGISTER_DECODER (FRAPS, fraps); - REGISTER_DECODER (FRWU, frwu); - REGISTER_ENCDEC (GIF, gif); - REGISTER_ENCDEC (H261, h261); - REGISTER_ENCDEC (H263, h263); - REGISTER_DECODER (H263I, h263i); - REGISTER_ENCODER (H263P, h263p); - REGISTER_DECODER (H264, h264); - REGISTER_DECODER (H264_VDPAU, h264_vdpau); - REGISTER_ENCDEC (HUFFYUV, huffyuv); - REGISTER_DECODER (IDCIN, idcin); - REGISTER_DECODER (IFF_BYTERUN1, iff_byterun1); - REGISTER_DECODER (IFF_ILBM, iff_ilbm); - REGISTER_DECODER (INDEO2, indeo2); - REGISTER_DECODER (INDEO3, indeo3); - REGISTER_DECODER (INDEO5, indeo5); - REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video); - REGISTER_ENCDEC (JPEGLS, jpegls); - REGISTER_DECODER (KGV1, kgv1); - REGISTER_DECODER (KMVC, kmvc); - REGISTER_ENCODER (LJPEG, ljpeg); - REGISTER_DECODER (LOCO, loco); - REGISTER_DECODER (MDEC, mdec); - REGISTER_DECODER (MIMIC, mimic); - REGISTER_ENCDEC (MJPEG, mjpeg); - REGISTER_DECODER (MJPEGB, mjpegb); - REGISTER_DECODER (MMVIDEO, mmvideo); - REGISTER_DECODER (MOTIONPIXELS, motionpixels); - REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc); - REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); - REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); - REGISTER_ENCDEC (MPEG4, mpeg4); - REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau); - REGISTER_DECODER (MPEGVIDEO, mpegvideo); - REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau); - REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau); - REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); - REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); - REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); - REGISTER_DECODER (MSRLE, msrle); - REGISTER_DECODER (MSVIDEO1, msvideo1); - REGISTER_DECODER (MSZH, mszh); - REGISTER_DECODER (NUV, nuv); - REGISTER_ENCDEC (PAM, pam); - REGISTER_ENCDEC (PBM, pbm); - REGISTER_ENCDEC (PCX, pcx); - REGISTER_ENCDEC (PGM, pgm); - REGISTER_ENCDEC (PGMYUV, pgmyuv); - REGISTER_ENCDEC (PNG, png); - REGISTER_ENCDEC (PPM, ppm); - REGISTER_DECODER (PTX, ptx); - REGISTER_DECODER (QDRAW, qdraw); - REGISTER_DECODER (QPEG, qpeg); - REGISTER_ENCDEC (QTRLE, qtrle); - REGISTER_DECODER (R210, r210); - REGISTER_ENCDEC (RAWVIDEO, rawvideo); - REGISTER_DECODER (RL2, rl2); - REGISTER_ENCDEC (ROQ, roq); - REGISTER_DECODER (RPZA, rpza); - REGISTER_ENCDEC (RV10, rv10); - REGISTER_ENCDEC (RV20, rv20); - REGISTER_DECODER (RV30, rv30); - REGISTER_DECODER (RV40, rv40); - REGISTER_ENCDEC (SGI, sgi); - REGISTER_DECODER (SMACKER, smacker); - REGISTER_DECODER (SMC, smc); - REGISTER_ENCDEC (SNOW, snow); - REGISTER_DECODER (SP5X, sp5x); - REGISTER_DECODER (SUNRAST, sunrast); - REGISTER_ENCDEC (SVQ1, svq1); - REGISTER_DECODER (SVQ3, svq3); - REGISTER_ENCDEC (TARGA, targa); - REGISTER_DECODER (THEORA, theora); - REGISTER_DECODER (THP, thp); - REGISTER_DECODER (TIERTEXSEQVIDEO, tiertexseqvideo); - REGISTER_ENCDEC (TIFF, tiff); - REGISTER_DECODER (TMV, tmv); - REGISTER_DECODER (TRUEMOTION1, truemotion1); - REGISTER_DECODER (TRUEMOTION2, truemotion2); - REGISTER_DECODER (TSCC, tscc); - REGISTER_DECODER (TXD, txd); - REGISTER_DECODER (ULTI, ulti); - REGISTER_ENCDEC (V210, v210); - REGISTER_DECODER (V210X, v210x); - REGISTER_DECODER (VB, vb); - REGISTER_DECODER (VC1, vc1); - REGISTER_DECODER (VC1_VDPAU, vc1_vdpau); - REGISTER_DECODER (VCR1, vcr1); - REGISTER_DECODER (VMDVIDEO, vmdvideo); - REGISTER_DECODER (VMNC, vmnc); - REGISTER_DECODER (VP3, vp3); - REGISTER_DECODER (VP5, vp5); - REGISTER_DECODER (VP6, vp6); - REGISTER_DECODER (VP6A, vp6a); - REGISTER_DECODER (VP6F, vp6f); - REGISTER_DECODER (VQA, vqa); - REGISTER_ENCDEC (WMV1, wmv1); - REGISTER_ENCDEC (WMV2, wmv2); - REGISTER_DECODER (WMV3, wmv3); - REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau); - REGISTER_DECODER (WNV1, wnv1); - REGISTER_DECODER (XAN_WC3, xan_wc3); - REGISTER_DECODER (XL, xl); - REGISTER_DECODER (YOP, yop); - REGISTER_ENCDEC (ZLIB, zlib); - REGISTER_ENCDEC (ZMBV, zmbv); - - /* audio codecs */ - REGISTER_ENCDEC (AAC, aac); - REGISTER_ENCDEC (AC3, ac3); - REGISTER_ENCDEC (ALAC, alac); - REGISTER_DECODER (ALS, als); - REGISTER_DECODER (AMRNB, amrnb); - REGISTER_DECODER (APE, ape); - REGISTER_DECODER (ATRAC1, atrac1); - REGISTER_DECODER (ATRAC3, atrac3); - REGISTER_DECODER (BINKAUDIO_DCT, binkaudio_dct); - REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft); - REGISTER_DECODER (COOK, cook); - REGISTER_DECODER (DCA, dca); - REGISTER_DECODER (DSICINAUDIO, dsicinaudio); - REGISTER_DECODER (EAC3, eac3); - REGISTER_ENCDEC (FLAC, flac); - REGISTER_DECODER (IMC, imc); - REGISTER_DECODER (MACE3, mace3); - REGISTER_DECODER (MACE6, mace6); - REGISTER_DECODER (MLP, mlp); - REGISTER_DECODER (MP1, mp1); - REGISTER_ENCDEC (MP2, mp2); - REGISTER_DECODER (MP3, mp3); - REGISTER_DECODER (MP3ADU, mp3adu); - REGISTER_DECODER (MP3ON4, mp3on4); - REGISTER_DECODER (MPC7, mpc7); - REGISTER_DECODER (MPC8, mpc8); - REGISTER_ENCDEC (NELLYMOSER, nellymoser); - REGISTER_DECODER (QCELP, qcelp); - REGISTER_DECODER (QDM2, qdm2); - REGISTER_DECODER (RA_144, ra_144); - REGISTER_DECODER (RA_288, ra_288); - REGISTER_DECODER (SHORTEN, shorten); - REGISTER_DECODER (SIPR, sipr); - REGISTER_DECODER (SMACKAUD, smackaud); - REGISTER_ENCDEC (SONIC, sonic); - REGISTER_ENCODER (SONIC_LS, sonic_ls); - REGISTER_DECODER (TRUEHD, truehd); - REGISTER_DECODER (TRUESPEECH, truespeech); - REGISTER_DECODER (TTA, tta); - REGISTER_DECODER (TWINVQ, twinvq); - REGISTER_DECODER (VMDAUDIO, vmdaudio); - REGISTER_DECODER (VORBIS, vorbis); - REGISTER_DECODER (WAVPACK, wavpack); - REGISTER_DECODER (WMAPRO, wmapro); - REGISTER_ENCDEC (WMAV1, wmav1); - REGISTER_ENCDEC (WMAV2, wmav2); - REGISTER_DECODER (WMAVOICE, wmavoice); - REGISTER_DECODER (WS_SND1, ws_snd1); - - /* PCM codecs */ - REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); - REGISTER_DECODER (PCM_BLURAY, pcm_bluray); - REGISTER_DECODER (PCM_DVD, pcm_dvd); - REGISTER_ENCDEC (PCM_F32BE, pcm_f32be); - REGISTER_ENCDEC (PCM_F32LE, pcm_f32le); - REGISTER_ENCDEC (PCM_F64BE, pcm_f64be); - REGISTER_ENCDEC (PCM_F64LE, pcm_f64le); - REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw); - REGISTER_ENCDEC (PCM_S8, pcm_s8); - REGISTER_ENCDEC (PCM_S16BE, pcm_s16be); - REGISTER_ENCDEC (PCM_S16LE, pcm_s16le); - REGISTER_DECODER (PCM_S16LE_PLANAR, pcm_s16le_planar); - REGISTER_ENCDEC (PCM_S24BE, pcm_s24be); - REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud); - REGISTER_ENCDEC (PCM_S24LE, pcm_s24le); - REGISTER_ENCDEC (PCM_S32BE, pcm_s32be); - REGISTER_ENCDEC (PCM_S32LE, pcm_s32le); - REGISTER_ENCDEC (PCM_U8, pcm_u8); - REGISTER_ENCDEC (PCM_U16BE, pcm_u16be); - REGISTER_ENCDEC (PCM_U16LE, pcm_u16le); - REGISTER_ENCDEC (PCM_U24BE, pcm_u24be); - REGISTER_ENCDEC (PCM_U24LE, pcm_u24le); - REGISTER_ENCDEC (PCM_U32BE, pcm_u32be); - REGISTER_ENCDEC (PCM_U32LE, pcm_u32le); - REGISTER_ENCDEC (PCM_ZORK , pcm_zork); - - /* DPCM codecs */ - REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm); - REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm); - REGISTER_DECODER (SOL_DPCM, sol_dpcm); - REGISTER_DECODER (XAN_DPCM, xan_dpcm); - - /* ADPCM codecs */ - REGISTER_DECODER (ADPCM_4XM, adpcm_4xm); - REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx); - REGISTER_DECODER (ADPCM_CT, adpcm_ct); - REGISTER_DECODER (ADPCM_EA, adpcm_ea); - REGISTER_DECODER (ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa); - REGISTER_DECODER (ADPCM_EA_R1, adpcm_ea_r1); - REGISTER_DECODER (ADPCM_EA_R2, adpcm_ea_r2); - REGISTER_DECODER (ADPCM_EA_R3, adpcm_ea_r3); - REGISTER_DECODER (ADPCM_EA_XAS, adpcm_ea_xas); - REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); - REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv); - REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3); - REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4); - REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); - REGISTER_DECODER (ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead); - REGISTER_DECODER (ADPCM_IMA_ISS, adpcm_ima_iss); - REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt); - REGISTER_DECODER (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); - REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav); - REGISTER_DECODER (ADPCM_IMA_WS, adpcm_ima_ws); - REGISTER_ENCDEC (ADPCM_MS, adpcm_ms); - REGISTER_DECODER (ADPCM_SBPRO_2, adpcm_sbpro_2); - REGISTER_DECODER (ADPCM_SBPRO_3, adpcm_sbpro_3); - REGISTER_DECODER (ADPCM_SBPRO_4, adpcm_sbpro_4); - REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf); - REGISTER_DECODER (ADPCM_THP, adpcm_thp); - REGISTER_DECODER (ADPCM_XA, adpcm_xa); - REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha); - - /* subtitles */ - REGISTER_ENCDEC (DVBSUB, dvbsub); - REGISTER_ENCDEC (DVDSUB, dvdsub); - REGISTER_DECODER (PGSSUB, pgssub); - REGISTER_ENCDEC (XSUB, xsub); - - /* external libraries */ - REGISTER_ENCDEC (LIBDIRAC, libdirac); - REGISTER_ENCODER (LIBFAAC, libfaac); - REGISTER_DECODER (LIBFAAD, libfaad); - REGISTER_ENCDEC (LIBGSM, libgsm); - REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); - REGISTER_ENCODER (LIBMP3LAME, libmp3lame); - REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb); - REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); - REGISTER_DECODER (LIBOPENJPEG, libopenjpeg); - REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); - REGISTER_DECODER (LIBSPEEX, libspeex); - REGISTER_ENCODER (LIBTHEORA, libtheora); - REGISTER_ENCODER (LIBVORBIS, libvorbis); - REGISTER_ENCDEC (LIBVPX, libvpx); - REGISTER_ENCODER (LIBX264, libx264); - REGISTER_ENCODER (LIBXVID, libxvid); - - /* parsers */ - REGISTER_PARSER (AAC, aac); - REGISTER_PARSER (AC3, ac3); - REGISTER_PARSER (CAVSVIDEO, cavsvideo); - REGISTER_PARSER (DCA, dca); - REGISTER_PARSER (DIRAC, dirac); - REGISTER_PARSER (DNXHD, dnxhd); - REGISTER_PARSER (DVBSUB, dvbsub); - REGISTER_PARSER (DVDSUB, dvdsub); - REGISTER_PARSER (H261, h261); - REGISTER_PARSER (H263, h263); - REGISTER_PARSER (H264, h264); - REGISTER_PARSER (MJPEG, mjpeg); - REGISTER_PARSER (MLP, mlp); - REGISTER_PARSER (MPEG4VIDEO, mpeg4video); - REGISTER_PARSER (MPEGAUDIO, mpegaudio); - REGISTER_PARSER (MPEGVIDEO, mpegvideo); - REGISTER_PARSER (PNM, pnm); - REGISTER_PARSER (VC1, vc1); - REGISTER_PARSER (VP3, vp3); - - /* bitstream filters */ - REGISTER_BSF (AAC_ADTSTOASC, aac_adtstoasc); - REGISTER_BSF (DUMP_EXTRADATA, dump_extradata); - REGISTER_BSF (H264_MP4TOANNEXB, h264_mp4toannexb); - REGISTER_BSF (IMX_DUMP_HEADER, imx_dump_header); - REGISTER_BSF (MJPEGA_DUMP_HEADER, mjpega_dump_header); - REGISTER_BSF (MP3_HEADER_COMPRESS, mp3_header_compress); - REGISTER_BSF (MP3_HEADER_DECOMPRESS, mp3_header_decompress); - REGISTER_BSF (MOV2TEXTSUB, mov2textsub); - REGISTER_BSF (NOISE, noise); - REGISTER_BSF (REMOVE_EXTRADATA, remove_extradata); - REGISTER_BSF (TEXT2MOVSUB, text2movsub); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/alpha/Makefile b/tizen/distrib/ffmpeg/libavcodec/alpha/Makefile deleted file mode 100644 index 2779a23..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -OBJS += alpha/dsputil_alpha.o \ - alpha/dsputil_alpha_asm.o \ - alpha/motion_est_alpha.o \ - alpha/motion_est_mvi_asm.o \ - alpha/mpegvideo_alpha.o \ - alpha/simple_idct_alpha.o \ diff --git a/tizen/distrib/ffmpeg/libavcodec/alpha/asm.h b/tizen/distrib/ffmpeg/libavcodec/alpha/asm.h deleted file mode 100644 index 827721e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/asm.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Alpha optimized DSP utils - * Copyright (c) 2002 Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ALPHA_ASM_H -#define AVCODEC_ALPHA_ASM_H - -#include - -#include "libavutil/common.h" - -#if AV_GCC_VERSION_AT_LEAST(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) \ - (((const union { \ - uint64_t __l; \ - __typeof__(*(p)) __s[sizeof (uint64_t) / sizeof *(p)]; \ - } *) (p))->__l) -#define ldl(p) \ - (((const 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 AV_GCC_VERSION_AT_LEAST(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 AV_GCC_VERSION_AT_LEAST(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 /* AVCODEC_ALPHA_ASM_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c b/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c deleted file mode 100644 index b87367f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Alpha optimized DSP utils - * Copyright (c) 2002 Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_alpha.h" -#include "asm.h" - -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); - -#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); - -static 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); -} - -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] = pix_abs16x16_mvi_asm; - c->sad[1] = pix_abs8x8_mvi; - c->pix_abs[0][0] = pix_abs16x16_mvi_asm; - 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; - - if (!avctx->lowres && - (avctx->idct_algo == FF_IDCT_AUTO || - avctx->idct_algo == FF_IDCT_SIMPLEALPHA)) { - c->idct_put = ff_simple_idct_put_axp; - c->idct_add = ff_simple_idct_add_axp; - c->idct = ff_simple_idct_axp; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.h b/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.h deleted file mode 100644 index a3fa3dd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ALPHA_DSPUTIL_ALPHA_H -#define AVCODEC_ALPHA_DSPUTIL_ALPHA_H - -#include "libavcodec/dsputil.h" - -void ff_simple_idct_axp(DCTELEM *block); -void ff_simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block); -void ff_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); -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); - -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(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h); -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); - - -#endif /* AVCODEC_ALPHA_DSPUTIL_ALPHA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S b/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S deleted file mode 100644 index 57b21fc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/dsputil_alpha_asm.S +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Alpha optimized DSP utils - * Copyright (c) 2002 Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 - -#if CONFIG_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 - -#if CONFIG_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 - -#if CONFIG_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/tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c b/tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c deleted file mode 100644 index 863dd23..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Alpha optimized DSP utils - * Copyright (c) 2002 Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_alpha.h" -#include "asm.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/tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_mvi_asm.S b/tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_mvi_asm.S deleted file mode 100644 index 2a08b07..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/motion_est_mvi_asm.S +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Alpha optimized DSP utils - * Copyright (c) 2002 Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 - -#if CONFIG_GPROF - lda AT, _mcount - jsr AT, (AT), _mcount -#endif - - and a2, 7, t0 - clr v0 - 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(a2) # left_u - ldq_u t1, 8(a2) # mid - ldq_u t2, 16(a2) # right_u - ldq t3, 0(a1) # ref left - ldq t4, 8(a1) # ref right - addq a1, a3, a1 # pix1 - addq a2, a3, a2 # pix2 - /* load line 1 */ - ldq_u t5, 0(a2) # left_u - ldq_u t6, 8(a2) # mid - ldq_u t7, 16(a2) # right_u - ldq t8, 0(a1) # ref left - ldq t9, 8(a1) # ref right - addq a1, a3, a1 # pix1 - addq a2, a3, a2 # pix2 - /* calc line 0 */ - extql t0, a2, t0 # left lo - extqh t1, a2, ta # left hi - extql t1, a2, tb # right lo - or t0, ta, t0 # left - extqh t2, a2, 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, a2, t5 # left lo - extqh t6, a2, ta # left hi - extql t6, a2, tb # right lo - or t5, ta, t5 # left - extqh t7, a2, 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 a4, 2, a4 # h -= 2 - bne a4, $unaligned - ret - - .align 4 -$aligned: - /* load line 0 */ - ldq t0, 0(a2) # left - ldq t1, 8(a2) # right - addq a2, a3, a2 # pix2 - ldq t2, 0(a1) # ref left - ldq t3, 8(a1) # ref right - addq a1, a3, a1 # pix1 - /* load line 1 */ - ldq t4, 0(a2) # left - ldq t5, 8(a2) # right - addq a2, a3, a2 # pix2 - ldq t6, 0(a1) # ref left - ldq t7, 8(a1) # ref right - addq a1, a3, a1 # pix1 - /* load line 2 */ - ldq t8, 0(a2) # left - ldq t9, 8(a2) # right - addq a2, a3, a2 # pix2 - ldq ta, 0(a1) # ref left - ldq tb, 8(a1) # ref right - addq a1, a3, a1 # pix1 - /* load line 3 */ - ldq tc, 0(a2) # left - ldq td, 8(a2) # right - addq a2, a3, a2 # pix2 - ldq te, 0(a1) # ref left - ldq a0, 8(a1) # ref right - /* calc line 0 */ - perr t0, t2, t0 # error left - addq a1, a3, a1 # 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, a0, t1 # error right - addq v0, t0, v0 # add error left - addq v0, t1, v0 # add error right - /* loop */ - subq a4, 4, a4 # h -= 4 - bne a4, $aligned - ret - .end pix_abs16x16_mvi_asm diff --git a/tizen/distrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c b/tizen/distrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c deleted file mode 100644 index de32545..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Alpha optimized DSP utils - * Copyright (c) 2002 Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" -#include "asm.h" - -static void dct_unquantize_h263_axp(DCTELEM *block, int n_coeffs, - uint64_t qscale, uint64_t qadd) -{ - uint64_t qmul = qscale << 1; - uint64_t correction = WORD_VEC(qmul * 255 >> 8); - int i; - - qadd = WORD_VEC(qadd); - - for(i = 0; i <= n_coeffs; block += 4, i += 4) { - uint64_t levels, negmask, zeros, add, sub; - - 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); - - add = qadd & ~negmask; - sub = qadd & negmask; - /* Set qadd to 0 for levels == 0. */ - add = zap(add, zeros); - levels += add; - levels -= sub; - - stq(levels, block); - } -} - -static void dct_unquantize_h263_intra_axp(MpegEncContext *s, DCTELEM *block, - int n, int qscale) -{ - int n_coeffs; - uint64_t qadd; - DCTELEM block0 = block[0]; - - if (!s->h263_aic) { - if (n < 4) - block0 *= s->y_dc_scale; - else - block0 *= s->c_dc_scale; - qadd = (qscale - 1) | 1; - } else { - qadd = 0; - } - - if(s->ac_pred) - n_coeffs = 63; - else - n_coeffs = s->inter_scantable.raster_end[s->block_last_index[n]]; - - dct_unquantize_h263_axp(block, n_coeffs, qscale, qadd); - - block[0] = block0; -} - -static void dct_unquantize_h263_inter_axp(MpegEncContext *s, DCTELEM *block, - int n, int qscale) -{ - int n_coeffs = s->inter_scantable.raster_end[s->block_last_index[n]]; - dct_unquantize_h263_axp(block, n_coeffs, qscale, (qscale - 1) | 1); -} - -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/tizen/distrib/ffmpeg/libavcodec/alpha/regdef.h b/tizen/distrib/ffmpeg/libavcodec/alpha/regdef.h deleted file mode 100644 index aa1959f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/regdef.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Alpha optimized DSP utils - * copyright (c) 2002 Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Some BSDs don't seem to have regdef.h... sigh */ -#ifndef AVCODEC_ALPHA_REGDEF_H -#define AVCODEC_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 /* AVCODEC_ALPHA_REGDEF_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c b/tizen/distrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c deleted file mode 100644 index 0c0689a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Simple IDCT (Alpha optimized) - * - * Copyright (c) 2001 Michael Niedermayer - * - * based upon some outcommented C code from mpeg2dec (idct_mmx.c - * written by Aaron Holtzman ) - * - * Alpha optimizations by Måns Rullgård - * and Falk Hueffner - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_alpha.h" -#include "asm.h" - -// 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 ff_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 ff_simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_simple_idct_axp(block); - put_pixels_clamped_axp_p(block, dest, line_size); -} - -void ff_simple_idct_add_axp(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_simple_idct_axp(block); - add_pixels_clamped_axp_p(block, dest, line_size); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/alsdec.c b/tizen/distrib/ffmpeg/libavcodec/alsdec.c deleted file mode 100644 index 2058a85..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/alsdec.c +++ /dev/null @@ -1,1636 +0,0 @@ -/* - * MPEG-4 ALS decoder - * Copyright (c) 2009 Thilo Borgmann - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG-4 ALS decoder - * @author Thilo Borgmann - */ - - -//#define DEBUG - - -#include "avcodec.h" -#include "get_bits.h" -#include "unary.h" -#include "mpeg4audio.h" -#include "bytestream.h" -#include "bgmc.h" - -#include - -/** Rice parameters and corresponding index offsets for decoding the - * indices of scaled PARCOR values. The table choosen is set globally - * by the encoder and stored in ALSSpecificConfig. - */ -static const int8_t parcor_rice_table[3][20][2] = { - { {-52, 4}, {-29, 5}, {-31, 4}, { 19, 4}, {-16, 4}, - { 12, 3}, { -7, 3}, { 9, 3}, { -5, 3}, { 6, 3}, - { -4, 3}, { 3, 3}, { -3, 2}, { 3, 2}, { -2, 2}, - { 3, 2}, { -1, 2}, { 2, 2}, { -1, 2}, { 2, 2} }, - { {-58, 3}, {-42, 4}, {-46, 4}, { 37, 5}, {-36, 4}, - { 29, 4}, {-29, 4}, { 25, 4}, {-23, 4}, { 20, 4}, - {-17, 4}, { 16, 4}, {-12, 4}, { 12, 3}, {-10, 4}, - { 7, 3}, { -4, 4}, { 3, 3}, { -1, 3}, { 1, 3} }, - { {-59, 3}, {-45, 5}, {-50, 4}, { 38, 4}, {-39, 4}, - { 32, 4}, {-30, 4}, { 25, 3}, {-23, 3}, { 20, 3}, - {-20, 3}, { 16, 3}, {-13, 3}, { 10, 3}, { -7, 3}, - { 3, 3}, { 0, 3}, { -1, 3}, { 2, 3}, { -1, 2} } -}; - - -/** Scaled PARCOR values used for the first two PARCOR coefficients. - * To be indexed by the Rice coded indices. - * Generated by: parcor_scaled_values[i] = 32 + ((i * (i+1)) << 7) - (1 << 20) - * Actual values are divided by 32 in order to be stored in 16 bits. - */ -static const int16_t parcor_scaled_values[] = { - -1048544 / 32, -1048288 / 32, -1047776 / 32, -1047008 / 32, - -1045984 / 32, -1044704 / 32, -1043168 / 32, -1041376 / 32, - -1039328 / 32, -1037024 / 32, -1034464 / 32, -1031648 / 32, - -1028576 / 32, -1025248 / 32, -1021664 / 32, -1017824 / 32, - -1013728 / 32, -1009376 / 32, -1004768 / 32, -999904 / 32, - -994784 / 32, -989408 / 32, -983776 / 32, -977888 / 32, - -971744 / 32, -965344 / 32, -958688 / 32, -951776 / 32, - -944608 / 32, -937184 / 32, -929504 / 32, -921568 / 32, - -913376 / 32, -904928 / 32, -896224 / 32, -887264 / 32, - -878048 / 32, -868576 / 32, -858848 / 32, -848864 / 32, - -838624 / 32, -828128 / 32, -817376 / 32, -806368 / 32, - -795104 / 32, -783584 / 32, -771808 / 32, -759776 / 32, - -747488 / 32, -734944 / 32, -722144 / 32, -709088 / 32, - -695776 / 32, -682208 / 32, -668384 / 32, -654304 / 32, - -639968 / 32, -625376 / 32, -610528 / 32, -595424 / 32, - -580064 / 32, -564448 / 32, -548576 / 32, -532448 / 32, - -516064 / 32, -499424 / 32, -482528 / 32, -465376 / 32, - -447968 / 32, -430304 / 32, -412384 / 32, -394208 / 32, - -375776 / 32, -357088 / 32, -338144 / 32, -318944 / 32, - -299488 / 32, -279776 / 32, -259808 / 32, -239584 / 32, - -219104 / 32, -198368 / 32, -177376 / 32, -156128 / 32, - -134624 / 32, -112864 / 32, -90848 / 32, -68576 / 32, - -46048 / 32, -23264 / 32, -224 / 32, 23072 / 32, - 46624 / 32, 70432 / 32, 94496 / 32, 118816 / 32, - 143392 / 32, 168224 / 32, 193312 / 32, 218656 / 32, - 244256 / 32, 270112 / 32, 296224 / 32, 322592 / 32, - 349216 / 32, 376096 / 32, 403232 / 32, 430624 / 32, - 458272 / 32, 486176 / 32, 514336 / 32, 542752 / 32, - 571424 / 32, 600352 / 32, 629536 / 32, 658976 / 32, - 688672 / 32, 718624 / 32, 748832 / 32, 779296 / 32, - 810016 / 32, 840992 / 32, 872224 / 32, 903712 / 32, - 935456 / 32, 967456 / 32, 999712 / 32, 1032224 / 32 -}; - - -/** Gain values of p(0) for long-term prediction. - * To be indexed by the Rice coded indices. - */ -static const uint8_t ltp_gain_values [4][4] = { - { 0, 8, 16, 24}, - {32, 40, 48, 56}, - {64, 70, 76, 82}, - {88, 92, 96, 100} -}; - - -/** Inter-channel weighting factors for multi-channel correlation. - * To be indexed by the Rice coded indices. - */ -static const int16_t mcc_weightings[] = { - 204, 192, 179, 166, 153, 140, 128, 115, - 102, 89, 76, 64, 51, 38, 25, 12, - 0, -12, -25, -38, -51, -64, -76, -89, - -102, -115, -128, -140, -153, -166, -179, -192 -}; - - -/** Tail codes used in arithmetic coding using block Gilbert-Moore codes. - */ -static const uint8_t tail_code[16][6] = { - { 74, 44, 25, 13, 7, 3}, - { 68, 42, 24, 13, 7, 3}, - { 58, 39, 23, 13, 7, 3}, - {126, 70, 37, 19, 10, 5}, - {132, 70, 37, 20, 10, 5}, - {124, 70, 38, 20, 10, 5}, - {120, 69, 37, 20, 11, 5}, - {116, 67, 37, 20, 11, 5}, - {108, 66, 36, 20, 10, 5}, - {102, 62, 36, 20, 10, 5}, - { 88, 58, 34, 19, 10, 5}, - {162, 89, 49, 25, 13, 7}, - {156, 87, 49, 26, 14, 7}, - {150, 86, 47, 26, 14, 7}, - {142, 84, 47, 26, 14, 7}, - {131, 79, 46, 26, 14, 7} -}; - - -enum RA_Flag { - RA_FLAG_NONE, - RA_FLAG_FRAMES, - RA_FLAG_HEADER -}; - - -typedef struct { - uint32_t samples; ///< number of samples, 0xFFFFFFFF if unknown - int resolution; ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit - int floating; ///< 1 = IEEE 32-bit floating-point, 0 = integer - int frame_length; ///< frame length for each frame (last frame may differ) - int ra_distance; ///< distance between RA frames (in frames, 0...255) - enum RA_Flag ra_flag; ///< indicates where the size of ra units is stored - int adapt_order; ///< adaptive order: 1 = on, 0 = off - int coef_table; ///< table index of Rice code parameters - int long_term_prediction; ///< long term prediction (LTP): 1 = on, 0 = off - int max_order; ///< maximum prediction order (0..1023) - int block_switching; ///< number of block switching levels - int bgmc; ///< "Block Gilbert-Moore Code": 1 = on, 0 = off (Rice coding only) - int sb_part; ///< sub-block partition - int joint_stereo; ///< joint stereo: 1 = on, 0 = off - int mc_coding; ///< extended inter-channel coding (multi channel coding): 1 = on, 0 = off - int chan_config; ///< indicates that a chan_config_info field is present - int chan_sort; ///< channel rearrangement: 1 = on, 0 = off - int rlslms; ///< use "Recursive Least Square-Least Mean Square" predictor: 1 = on, 0 = off - int chan_config_info; ///< mapping of channels to loudspeaker locations. Unused until setting channel configuration is implemented. - int *chan_pos; ///< original channel positions -} ALSSpecificConfig; - - -typedef struct { - int stop_flag; - int master_channel; - int time_diff_flag; - int time_diff_sign; - int time_diff_index; - int weighting[6]; -} ALSChannelData; - - -typedef struct { - AVCodecContext *avctx; - ALSSpecificConfig sconf; - GetBitContext gb; - unsigned int cur_frame_length; ///< length of the current frame to decode - unsigned int frame_id; ///< the frame ID / number of the current frame - unsigned int js_switch; ///< if true, joint-stereo decoding is enforced - unsigned int num_blocks; ///< number of blocks used in the current frame - unsigned int s_max; ///< maximum Rice parameter allowed in entropy coding - uint8_t *bgmc_lut; ///< pointer at lookup tables used for BGMC - unsigned int *bgmc_lut_status; ///< pointer at lookup table status flags used for BGMC - int ltp_lag_length; ///< number of bits used for ltp lag value - int *use_ltp; ///< contains use_ltp flags for all channels - int *ltp_lag; ///< contains ltp lag values for all channels - int **ltp_gain; ///< gain values for ltp 5-tap filter for a channel - int *ltp_gain_buffer; ///< contains all gain values for ltp 5-tap filter - int32_t **quant_cof; ///< quantized parcor coefficients for a channel - int32_t *quant_cof_buffer; ///< contains all quantized parcor coefficients - int32_t **lpc_cof; ///< coefficients of the direct form prediction filter for a channel - int32_t *lpc_cof_buffer; ///< contains all coefficients of the direct form prediction filter - int32_t *lpc_cof_reversed_buffer; ///< temporary buffer to set up a reversed versio of lpc_cof_buffer - ALSChannelData **chan_data; ///< channel data for multi-channel correlation - ALSChannelData *chan_data_buffer; ///< contains channel data for all channels - int *reverted_channels; ///< stores a flag for each reverted channel - int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block - int32_t **raw_samples; ///< decoded raw samples for each channel - int32_t *raw_buffer; ///< contains all decoded raw samples including carryover samples -} ALSDecContext; - - -typedef struct { - unsigned int block_length; ///< number of samples within the block - unsigned int ra_block; ///< if true, this is a random access block - int const_block; ///< if true, this is a constant value block - int32_t const_val; ///< the sample value of a constant block - int js_blocks; ///< true if this block contains a difference signal - unsigned int shift_lsbs; ///< shift of values for this block - unsigned int opt_order; ///< prediction order of this block - int store_prev_samples;///< if true, carryover samples have to be stored - int *use_ltp; ///< if true, long-term prediction is used - int *ltp_lag; ///< lag value for long-term prediction - int *ltp_gain; ///< gain values for ltp 5-tap filter - int32_t *quant_cof; ///< quantized parcor coefficients - int32_t *lpc_cof; ///< coefficients of the direct form prediction - int32_t *raw_samples; ///< decoded raw samples / residuals for this block - int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block - int32_t *raw_other; ///< decoded raw samples of the other channel of a channel pair -} ALSBlockData; - - -static av_cold void dprint_specific_config(ALSDecContext *ctx) -{ -#ifdef DEBUG - AVCodecContext *avctx = ctx->avctx; - ALSSpecificConfig *sconf = &ctx->sconf; - - dprintf(avctx, "resolution = %i\n", sconf->resolution); - dprintf(avctx, "floating = %i\n", sconf->floating); - dprintf(avctx, "frame_length = %i\n", sconf->frame_length); - dprintf(avctx, "ra_distance = %i\n", sconf->ra_distance); - dprintf(avctx, "ra_flag = %i\n", sconf->ra_flag); - dprintf(avctx, "adapt_order = %i\n", sconf->adapt_order); - dprintf(avctx, "coef_table = %i\n", sconf->coef_table); - dprintf(avctx, "long_term_prediction = %i\n", sconf->long_term_prediction); - dprintf(avctx, "max_order = %i\n", sconf->max_order); - dprintf(avctx, "block_switching = %i\n", sconf->block_switching); - dprintf(avctx, "bgmc = %i\n", sconf->bgmc); - dprintf(avctx, "sb_part = %i\n", sconf->sb_part); - dprintf(avctx, "joint_stereo = %i\n", sconf->joint_stereo); - dprintf(avctx, "mc_coding = %i\n", sconf->mc_coding); - dprintf(avctx, "chan_config = %i\n", sconf->chan_config); - dprintf(avctx, "chan_sort = %i\n", sconf->chan_sort); - dprintf(avctx, "RLSLMS = %i\n", sconf->rlslms); - dprintf(avctx, "chan_config_info = %i\n", sconf->chan_config_info); -#endif -} - - -/** Reads an ALSSpecificConfig from a buffer into the output struct. - */ -static av_cold int read_specific_config(ALSDecContext *ctx) -{ - GetBitContext gb; - uint64_t ht_size; - int i, config_offset, crc_enabled; - MPEG4AudioConfig m4ac; - ALSSpecificConfig *sconf = &ctx->sconf; - AVCodecContext *avctx = ctx->avctx; - uint32_t als_id, header_size, trailer_size; - - init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); - - config_offset = ff_mpeg4audio_get_config(&m4ac, avctx->extradata, - avctx->extradata_size); - - if (config_offset < 0) - return -1; - - skip_bits_long(&gb, config_offset); - - if (get_bits_left(&gb) < (30 << 3)) - return -1; - - // read the fixed items - als_id = get_bits_long(&gb, 32); - avctx->sample_rate = m4ac.sample_rate; - skip_bits_long(&gb, 32); // sample rate already known - sconf->samples = get_bits_long(&gb, 32); - avctx->channels = m4ac.channels; - skip_bits(&gb, 16); // number of channels already knwon - skip_bits(&gb, 3); // skip file_type - sconf->resolution = get_bits(&gb, 3); - sconf->floating = get_bits1(&gb); - skip_bits1(&gb); // skip msb_first - sconf->frame_length = get_bits(&gb, 16) + 1; - sconf->ra_distance = get_bits(&gb, 8); - sconf->ra_flag = get_bits(&gb, 2); - sconf->adapt_order = get_bits1(&gb); - sconf->coef_table = get_bits(&gb, 2); - sconf->long_term_prediction = get_bits1(&gb); - sconf->max_order = get_bits(&gb, 10); - sconf->block_switching = get_bits(&gb, 2); - sconf->bgmc = get_bits1(&gb); - sconf->sb_part = get_bits1(&gb); - sconf->joint_stereo = get_bits1(&gb); - sconf->mc_coding = get_bits1(&gb); - sconf->chan_config = get_bits1(&gb); - sconf->chan_sort = get_bits1(&gb); - crc_enabled = get_bits1(&gb); - sconf->rlslms = get_bits1(&gb); - skip_bits(&gb, 5); // skip 5 reserved bits - skip_bits1(&gb); // skip aux_data_enabled - - - // check for ALSSpecificConfig struct - if (als_id != MKBETAG('A','L','S','\0')) - return -1; - - ctx->cur_frame_length = sconf->frame_length; - - // read channel config - if (sconf->chan_config) - sconf->chan_config_info = get_bits(&gb, 16); - // TODO: use this to set avctx->channel_layout - - - // read channel sorting - if (sconf->chan_sort && avctx->channels > 1) { - int chan_pos_bits = av_ceil_log2(avctx->channels); - int bits_needed = avctx->channels * chan_pos_bits + 7; - if (get_bits_left(&gb) < bits_needed) - return -1; - - if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos)))) - return AVERROR(ENOMEM); - - for (i = 0; i < avctx->channels; i++) - sconf->chan_pos[i] = get_bits(&gb, chan_pos_bits); - - align_get_bits(&gb); - // TODO: use this to actually do channel sorting - } else { - sconf->chan_sort = 0; - } - - - // read fixed header and trailer sizes, - // if size = 0xFFFFFFFF then there is no data field! - if (get_bits_left(&gb) < 64) - return -1; - - header_size = get_bits_long(&gb, 32); - trailer_size = get_bits_long(&gb, 32); - if (header_size == 0xFFFFFFFF) - header_size = 0; - if (trailer_size == 0xFFFFFFFF) - trailer_size = 0; - - ht_size = ((int64_t)(header_size) + (int64_t)(trailer_size)) << 3; - - - // skip the header and trailer data - if (get_bits_left(&gb) < ht_size) - return -1; - - if (ht_size > INT32_MAX) - return -1; - - skip_bits_long(&gb, ht_size); - - - // skip the crc data - if (crc_enabled) { - if (get_bits_left(&gb) < 32) - return -1; - - skip_bits_long(&gb, 32); - } - - - // no need to read the rest of ALSSpecificConfig (ra_unit_size & aux data) - - dprint_specific_config(ctx); - - return 0; -} - - -/** Checks the ALSSpecificConfig for unsupported features. - */ -static int check_specific_config(ALSDecContext *ctx) -{ - ALSSpecificConfig *sconf = &ctx->sconf; - int error = 0; - - // report unsupported feature and set error value - #define MISSING_ERR(cond, str, errval) \ - { \ - if (cond) { \ - av_log_missing_feature(ctx->avctx, str, 0); \ - error = errval; \ - } \ - } - - MISSING_ERR(sconf->floating, "Floating point decoding", -1); - MISSING_ERR(sconf->rlslms, "Adaptive RLS-LMS prediction", -1); - MISSING_ERR(sconf->chan_sort, "Channel sorting", 0); - - return error; -} - - -/** Parses the bs_info field to extract the block partitioning used in - * block switching mode, refer to ISO/IEC 14496-3, section 11.6.2. - */ -static void parse_bs_info(const uint32_t bs_info, unsigned int n, - unsigned int div, unsigned int **div_blocks, - unsigned int *num_blocks) -{ - if (n < 31 && ((bs_info << n) & 0x40000000)) { - // if the level is valid and the investigated bit n is set - // then recursively check both children at bits (2n+1) and (2n+2) - n *= 2; - div += 1; - parse_bs_info(bs_info, n + 1, div, div_blocks, num_blocks); - parse_bs_info(bs_info, n + 2, div, div_blocks, num_blocks); - } else { - // else the bit is not set or the last level has been reached - // (bit implicitly not set) - **div_blocks = div; - (*div_blocks)++; - (*num_blocks)++; - } -} - - -/** Reads and decodes a Rice codeword. - */ -static int32_t decode_rice(GetBitContext *gb, unsigned int k) -{ - int max = get_bits_left(gb) - k; - int q = get_unary(gb, 0, max); - int r = k ? get_bits1(gb) : !(q & 1); - - if (k > 1) { - q <<= (k - 1); - q += get_bits_long(gb, k - 1); - } else if (!k) { - q >>= 1; - } - return r ? q : ~q; -} - - -/** Converts PARCOR coefficient k to direct filter coefficient. - */ -static void parcor_to_lpc(unsigned int k, const int32_t *par, int32_t *cof) -{ - int i, j; - - for (i = 0, j = k - 1; i < j; i++, j--) { - int tmp1 = ((MUL64(par[k], cof[j]) + (1 << 19)) >> 20); - cof[j] += ((MUL64(par[k], cof[i]) + (1 << 19)) >> 20); - cof[i] += tmp1; - } - if (i == j) - cof[i] += ((MUL64(par[k], cof[j]) + (1 << 19)) >> 20); - - cof[k] = par[k]; -} - - -/** Reads block switching field if necessary and sets actual block sizes. - * Also assures that the block sizes of the last frame correspond to the - * actual number of samples. - */ -static void get_block_sizes(ALSDecContext *ctx, unsigned int *div_blocks, - uint32_t *bs_info) -{ - ALSSpecificConfig *sconf = &ctx->sconf; - GetBitContext *gb = &ctx->gb; - unsigned int *ptr_div_blocks = div_blocks; - unsigned int b; - - if (sconf->block_switching) { - unsigned int bs_info_len = 1 << (sconf->block_switching + 2); - *bs_info = get_bits_long(gb, bs_info_len); - *bs_info <<= (32 - bs_info_len); - } - - ctx->num_blocks = 0; - parse_bs_info(*bs_info, 0, 0, &ptr_div_blocks, &ctx->num_blocks); - - // The last frame may have an overdetermined block structure given in - // the bitstream. In that case the defined block structure would need - // more samples than available to be consistent. - // The block structure is actually used but the block sizes are adapted - // to fit the actual number of available samples. - // Example: 5 samples, 2nd level block sizes: 2 2 2 2. - // This results in the actual block sizes: 2 2 1 0. - // This is not specified in 14496-3 but actually done by the reference - // codec RM22 revision 2. - // This appears to happen in case of an odd number of samples in the last - // frame which is actually not allowed by the block length switching part - // of 14496-3. - // The ALS conformance files feature an odd number of samples in the last - // frame. - - for (b = 0; b < ctx->num_blocks; b++) - div_blocks[b] = ctx->sconf.frame_length >> div_blocks[b]; - - if (ctx->cur_frame_length != ctx->sconf.frame_length) { - unsigned int remaining = ctx->cur_frame_length; - - for (b = 0; b < ctx->num_blocks; b++) { - if (remaining <= div_blocks[b]) { - div_blocks[b] = remaining; - ctx->num_blocks = b + 1; - break; - } - - remaining -= div_blocks[b]; - } - } -} - - -/** Reads the block data for a constant block - */ -static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) -{ - ALSSpecificConfig *sconf = &ctx->sconf; - AVCodecContext *avctx = ctx->avctx; - GetBitContext *gb = &ctx->gb; - - bd->const_val = 0; - bd->const_block = get_bits1(gb); // 1 = constant value, 0 = zero block (silence) - bd->js_blocks = get_bits1(gb); - - // skip 5 reserved bits - skip_bits(gb, 5); - - if (bd->const_block) { - unsigned int const_val_bits = sconf->floating ? 24 : avctx->bits_per_raw_sample; - bd->const_val = get_sbits_long(gb, const_val_bits); - } - - // ensure constant block decoding by reusing this field - bd->const_block = 1; -} - - -/** Decodes the block data for a constant block - */ -static void decode_const_block_data(ALSDecContext *ctx, ALSBlockData *bd) -{ - int smp = bd->block_length; - int32_t val = bd->const_val; - int32_t *dst = bd->raw_samples; - - // write raw samples into buffer - for (; smp; smp--) - *dst++ = val; -} - - -/** Reads the block data for a non-constant block - */ -static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) -{ - ALSSpecificConfig *sconf = &ctx->sconf; - AVCodecContext *avctx = ctx->avctx; - GetBitContext *gb = &ctx->gb; - unsigned int k; - unsigned int s[8]; - unsigned int sx[8]; - unsigned int sub_blocks, log2_sub_blocks, sb_length; - unsigned int start = 0; - unsigned int opt_order; - int sb; - int32_t *quant_cof = bd->quant_cof; - int32_t *current_res; - - - // ensure variable block decoding by reusing this field - bd->const_block = 0; - - bd->opt_order = 1; - bd->js_blocks = get_bits1(gb); - - opt_order = bd->opt_order; - - // determine the number of subblocks for entropy decoding - if (!sconf->bgmc && !sconf->sb_part) { - log2_sub_blocks = 0; - } else { - if (sconf->bgmc && sconf->sb_part) - log2_sub_blocks = get_bits(gb, 2); - else - log2_sub_blocks = 2 * get_bits1(gb); - } - - sub_blocks = 1 << log2_sub_blocks; - - // do not continue in case of a damaged stream since - // block_length must be evenly divisible by sub_blocks - if (bd->block_length & (sub_blocks - 1)) { - av_log(avctx, AV_LOG_WARNING, - "Block length is not evenly divisible by the number of subblocks.\n"); - return -1; - } - - sb_length = bd->block_length >> log2_sub_blocks; - - if (sconf->bgmc) { - s[0] = get_bits(gb, 8 + (sconf->resolution > 1)); - for (k = 1; k < sub_blocks; k++) - s[k] = s[k - 1] + decode_rice(gb, 2); - - for (k = 0; k < sub_blocks; k++) { - sx[k] = s[k] & 0x0F; - s [k] >>= 4; - } - } else { - s[0] = get_bits(gb, 4 + (sconf->resolution > 1)); - for (k = 1; k < sub_blocks; k++) - s[k] = s[k - 1] + decode_rice(gb, 0); - } - - if (get_bits1(gb)) - bd->shift_lsbs = get_bits(gb, 4) + 1; - - bd->store_prev_samples = (bd->js_blocks && bd->raw_other) || bd->shift_lsbs; - - - if (!sconf->rlslms) { - if (sconf->adapt_order) { - int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1, - 2, sconf->max_order + 1)); - bd->opt_order = get_bits(gb, opt_order_length); - } else { - bd->opt_order = sconf->max_order; - } - - opt_order = bd->opt_order; - - if (opt_order) { - int add_base; - - if (sconf->coef_table == 3) { - add_base = 0x7F; - - // read coefficient 0 - quant_cof[0] = 32 * parcor_scaled_values[get_bits(gb, 7)]; - - // read coefficient 1 - if (opt_order > 1) - quant_cof[1] = -32 * parcor_scaled_values[get_bits(gb, 7)]; - - // read coefficients 2 to opt_order - for (k = 2; k < opt_order; k++) - quant_cof[k] = get_bits(gb, 7); - } else { - int k_max; - add_base = 1; - - // read coefficient 0 to 19 - k_max = FFMIN(opt_order, 20); - for (k = 0; k < k_max; k++) { - int rice_param = parcor_rice_table[sconf->coef_table][k][1]; - int offset = parcor_rice_table[sconf->coef_table][k][0]; - quant_cof[k] = decode_rice(gb, rice_param) + offset; - } - - // read coefficients 20 to 126 - k_max = FFMIN(opt_order, 127); - for (; k < k_max; k++) - quant_cof[k] = decode_rice(gb, 2) + (k & 1); - - // read coefficients 127 to opt_order - for (; k < opt_order; k++) - quant_cof[k] = decode_rice(gb, 1); - - quant_cof[0] = 32 * parcor_scaled_values[quant_cof[0] + 64]; - - if (opt_order > 1) - quant_cof[1] = -32 * parcor_scaled_values[quant_cof[1] + 64]; - } - - for (k = 2; k < opt_order; k++) - quant_cof[k] = (quant_cof[k] << 14) + (add_base << 13); - } - } - - // read LTP gain and lag values - if (sconf->long_term_prediction) { - *bd->use_ltp = get_bits1(gb); - - if (*bd->use_ltp) { - int r, c; - - bd->ltp_gain[0] = decode_rice(gb, 1) << 3; - bd->ltp_gain[1] = decode_rice(gb, 2) << 3; - - r = get_unary(gb, 0, 4); - c = get_bits(gb, 2); - bd->ltp_gain[2] = ltp_gain_values[r][c]; - - bd->ltp_gain[3] = decode_rice(gb, 2) << 3; - bd->ltp_gain[4] = decode_rice(gb, 1) << 3; - - *bd->ltp_lag = get_bits(gb, ctx->ltp_lag_length); - *bd->ltp_lag += FFMAX(4, opt_order + 1); - } - } - - // read first value and residuals in case of a random access block - if (bd->ra_block) { - if (opt_order) - bd->raw_samples[0] = decode_rice(gb, avctx->bits_per_raw_sample - 4); - if (opt_order > 1) - bd->raw_samples[1] = decode_rice(gb, FFMIN(s[0] + 3, ctx->s_max)); - if (opt_order > 2) - bd->raw_samples[2] = decode_rice(gb, FFMIN(s[0] + 1, ctx->s_max)); - - start = FFMIN(opt_order, 3); - } - - // read all residuals - if (sconf->bgmc) { - unsigned int delta[sub_blocks]; - unsigned int k [sub_blocks]; - unsigned int b = av_clip((av_ceil_log2(bd->block_length) - 3) >> 1, 0, 5); - unsigned int i = start; - - // read most significant bits - unsigned int high; - unsigned int low; - unsigned int value; - - ff_bgmc_decode_init(gb, &high, &low, &value); - - current_res = bd->raw_samples + start; - - for (sb = 0; sb < sub_blocks; sb++, i = 0) { - k [sb] = s[sb] > b ? s[sb] - b : 0; - delta[sb] = 5 - s[sb] + k[sb]; - - ff_bgmc_decode(gb, sb_length, current_res, - delta[sb], sx[sb], &high, &low, &value, ctx->bgmc_lut, ctx->bgmc_lut_status); - - current_res += sb_length; - } - - ff_bgmc_decode_end(gb); - - - // read least significant bits and tails - i = start; - current_res = bd->raw_samples + start; - - for (sb = 0; sb < sub_blocks; sb++, i = 0) { - unsigned int cur_tail_code = tail_code[sx[sb]][delta[sb]]; - unsigned int cur_k = k[sb]; - unsigned int cur_s = s[sb]; - - for (; i < sb_length; i++) { - int32_t res = *current_res; - - if (res == cur_tail_code) { - unsigned int max_msb = (2 + (sx[sb] > 2) + (sx[sb] > 10)) - << (5 - delta[sb]); - - res = decode_rice(gb, cur_s); - - if (res >= 0) { - res += (max_msb ) << cur_k; - } else { - res -= (max_msb - 1) << cur_k; - } - } else { - if (res > cur_tail_code) - res--; - - if (res & 1) - res = -res; - - res >>= 1; - - if (cur_k) { - res <<= cur_k; - res |= get_bits_long(gb, cur_k); - } - } - - *current_res++ = res; - } - } - } else { - current_res = bd->raw_samples + start; - - for (sb = 0; sb < sub_blocks; sb++, start = 0) - for (; start < sb_length; start++) - *current_res++ = decode_rice(gb, s[sb]); - } - - if (!sconf->mc_coding || ctx->js_switch) - align_get_bits(gb); - - return 0; -} - - -/** Decodes the block data for a non-constant block - */ -static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) -{ - ALSSpecificConfig *sconf = &ctx->sconf; - unsigned int block_length = bd->block_length; - unsigned int smp = 0; - unsigned int k; - int opt_order = bd->opt_order; - int sb; - int64_t y; - int32_t *quant_cof = bd->quant_cof; - int32_t *lpc_cof = bd->lpc_cof; - int32_t *raw_samples = bd->raw_samples; - int32_t *raw_samples_end = bd->raw_samples + bd->block_length; - int32_t *lpc_cof_reversed = ctx->lpc_cof_reversed_buffer; - - // reverse long-term prediction - if (*bd->use_ltp) { - int ltp_smp; - - for (ltp_smp = FFMAX(*bd->ltp_lag - 2, 0); ltp_smp < block_length; ltp_smp++) { - int center = ltp_smp - *bd->ltp_lag; - int begin = FFMAX(0, center - 2); - int end = center + 3; - int tab = 5 - (end - begin); - int base; - - y = 1 << 6; - - for (base = begin; base < end; base++, tab++) - y += MUL64(bd->ltp_gain[tab], raw_samples[base]); - - raw_samples[ltp_smp] += y >> 7; - } - } - - // reconstruct all samples from residuals - if (bd->ra_block) { - for (smp = 0; smp < opt_order; smp++) { - y = 1 << 19; - - for (sb = 0; sb < smp; sb++) - y += MUL64(lpc_cof[sb], raw_samples[-(sb + 1)]); - - *raw_samples++ -= y >> 20; - parcor_to_lpc(smp, quant_cof, lpc_cof); - } - } else { - for (k = 0; k < opt_order; k++) - parcor_to_lpc(k, quant_cof, lpc_cof); - - // store previous samples in case that they have to be altered - if (bd->store_prev_samples) - memcpy(bd->prev_raw_samples, raw_samples - sconf->max_order, - sizeof(*bd->prev_raw_samples) * sconf->max_order); - - // reconstruct difference signal for prediction (joint-stereo) - if (bd->js_blocks && bd->raw_other) { - int32_t *left, *right; - - if (bd->raw_other > raw_samples) { // D = R - L - left = raw_samples; - right = bd->raw_other; - } else { // D = R - L - left = bd->raw_other; - right = raw_samples; - } - - for (sb = -1; sb >= -sconf->max_order; sb--) - raw_samples[sb] = right[sb] - left[sb]; - } - - // reconstruct shifted signal - if (bd->shift_lsbs) - for (sb = -1; sb >= -sconf->max_order; sb--) - raw_samples[sb] >>= bd->shift_lsbs; - } - - // reverse linear prediction coefficients for efficiency - lpc_cof = lpc_cof + opt_order; - - for (sb = 0; sb < opt_order; sb++) - lpc_cof_reversed[sb] = lpc_cof[-(sb + 1)]; - - // reconstruct raw samples - raw_samples = bd->raw_samples + smp; - lpc_cof = lpc_cof_reversed + opt_order; - - for (; raw_samples < raw_samples_end; raw_samples++) { - y = 1 << 19; - - for (sb = -opt_order; sb < 0; sb++) - y += MUL64(lpc_cof[sb], raw_samples[sb]); - - *raw_samples -= y >> 20; - } - - raw_samples = bd->raw_samples; - - // restore previous samples in case that they have been altered - if (bd->store_prev_samples) - memcpy(raw_samples - sconf->max_order, bd->prev_raw_samples, - sizeof(*raw_samples) * sconf->max_order); - - return 0; -} - - -/** Reads the block data. - */ -static int read_block(ALSDecContext *ctx, ALSBlockData *bd) -{ - GetBitContext *gb = &ctx->gb; - - // read block type flag and read the samples accordingly - if (get_bits1(gb)) { - if (read_var_block_data(ctx, bd)) - return -1; - } else { - read_const_block_data(ctx, bd); - } - - return 0; -} - - -/** Decodes the block data. - */ -static int decode_block(ALSDecContext *ctx, ALSBlockData *bd) -{ - unsigned int smp; - - // read block type flag and read the samples accordingly - if (bd->const_block) - decode_const_block_data(ctx, bd); - else if (decode_var_block_data(ctx, bd)) - return -1; - - // TODO: read RLSLMS extension data - - if (bd->shift_lsbs) - for (smp = 0; smp < bd->block_length; smp++) - bd->raw_samples[smp] <<= bd->shift_lsbs; - - return 0; -} - - -/** Reads and decodes block data successively. - */ -static int read_decode_block(ALSDecContext *ctx, ALSBlockData *bd) -{ - int ret; - - ret = read_block(ctx, bd); - - if (ret) - return ret; - - ret = decode_block(ctx, bd); - - return ret; -} - - -/** Computes the number of samples left to decode for the current frame and - * sets these samples to zero. - */ -static void zero_remaining(unsigned int b, unsigned int b_max, - const unsigned int *div_blocks, int32_t *buf) -{ - unsigned int count = 0; - - while (b < b_max) - count += div_blocks[b]; - - if (count) - memset(buf, 0, sizeof(*buf) * count); -} - - -/** Decodes blocks independently. - */ -static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame, - unsigned int c, const unsigned int *div_blocks, - unsigned int *js_blocks) -{ - unsigned int b; - ALSBlockData bd; - - memset(&bd, 0, sizeof(ALSBlockData)); - - bd.ra_block = ra_frame; - bd.use_ltp = ctx->use_ltp; - bd.ltp_lag = ctx->ltp_lag; - bd.ltp_gain = ctx->ltp_gain[0]; - bd.quant_cof = ctx->quant_cof[0]; - bd.lpc_cof = ctx->lpc_cof[0]; - bd.prev_raw_samples = ctx->prev_raw_samples; - bd.raw_samples = ctx->raw_samples[c]; - - - for (b = 0; b < ctx->num_blocks; b++) { - bd.shift_lsbs = 0; - bd.block_length = div_blocks[b]; - - if (read_decode_block(ctx, &bd)) { - // damaged block, write zero for the rest of the frame - zero_remaining(b, ctx->num_blocks, div_blocks, bd.raw_samples); - return -1; - } - bd.raw_samples += div_blocks[b]; - bd.ra_block = 0; - } - - return 0; -} - - -/** Decodes blocks dependently. - */ -static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, - unsigned int c, const unsigned int *div_blocks, - unsigned int *js_blocks) -{ - ALSSpecificConfig *sconf = &ctx->sconf; - unsigned int offset = 0; - unsigned int b; - ALSBlockData bd[2]; - - memset(bd, 0, 2 * sizeof(ALSBlockData)); - - bd[0].ra_block = ra_frame; - bd[0].use_ltp = ctx->use_ltp; - bd[0].ltp_lag = ctx->ltp_lag; - bd[0].ltp_gain = ctx->ltp_gain[0]; - bd[0].quant_cof = ctx->quant_cof[0]; - bd[0].lpc_cof = ctx->lpc_cof[0]; - bd[0].prev_raw_samples = ctx->prev_raw_samples; - bd[0].js_blocks = *js_blocks; - - bd[1].ra_block = ra_frame; - bd[1].use_ltp = ctx->use_ltp; - bd[1].ltp_lag = ctx->ltp_lag; - bd[1].ltp_gain = ctx->ltp_gain[0]; - bd[1].quant_cof = ctx->quant_cof[0]; - bd[1].lpc_cof = ctx->lpc_cof[0]; - bd[1].prev_raw_samples = ctx->prev_raw_samples; - bd[1].js_blocks = *(js_blocks + 1); - - // decode all blocks - for (b = 0; b < ctx->num_blocks; b++) { - unsigned int s; - - bd[0].shift_lsbs = 0; - bd[1].shift_lsbs = 0; - - bd[0].block_length = div_blocks[b]; - bd[1].block_length = div_blocks[b]; - - bd[0].raw_samples = ctx->raw_samples[c ] + offset; - bd[1].raw_samples = ctx->raw_samples[c + 1] + offset; - - bd[0].raw_other = bd[1].raw_samples; - bd[1].raw_other = bd[0].raw_samples; - - if(read_decode_block(ctx, &bd[0]) || read_decode_block(ctx, &bd[1])) { - // damaged block, write zero for the rest of the frame - zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples); - zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples); - return -1; - } - - // reconstruct joint-stereo blocks - if (bd[0].js_blocks) { - if (bd[1].js_blocks) - av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair!\n"); - - for (s = 0; s < div_blocks[b]; s++) - bd[0].raw_samples[s] = bd[1].raw_samples[s] - bd[0].raw_samples[s]; - } else if (bd[1].js_blocks) { - for (s = 0; s < div_blocks[b]; s++) - bd[1].raw_samples[s] = bd[1].raw_samples[s] + bd[0].raw_samples[s]; - } - - offset += div_blocks[b]; - bd[0].ra_block = 0; - bd[1].ra_block = 0; - } - - // store carryover raw samples, - // the others channel raw samples are stored by the calling function. - memmove(ctx->raw_samples[c] - sconf->max_order, - ctx->raw_samples[c] - sconf->max_order + sconf->frame_length, - sizeof(*ctx->raw_samples[c]) * sconf->max_order); - - return 0; -} - - -/** Reads the channel data. - */ -static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) -{ - GetBitContext *gb = &ctx->gb; - ALSChannelData *current = cd; - unsigned int channels = ctx->avctx->channels; - int entries = 0; - - while (entries < channels && !(current->stop_flag = get_bits1(gb))) { - current->master_channel = get_bits_long(gb, av_ceil_log2(channels)); - - if (current->master_channel >= channels) { - av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel!\n"); - return -1; - } - - if (current->master_channel != c) { - current->time_diff_flag = get_bits1(gb); - current->weighting[0] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - current->weighting[1] = mcc_weightings[av_clip(decode_rice(gb, 2) + 14, 0, 32)]; - current->weighting[2] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - - if (current->time_diff_flag) { - current->weighting[3] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - current->weighting[4] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - current->weighting[5] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - - current->time_diff_sign = get_bits1(gb); - current->time_diff_index = get_bits(gb, ctx->ltp_lag_length - 3) + 3; - } - } - - current++; - entries++; - } - - if (entries == channels) { - av_log(ctx->avctx, AV_LOG_ERROR, "Damaged channel data!\n"); - return -1; - } - - align_get_bits(gb); - return 0; -} - - -/** Recursively reverts the inter-channel correlation for a block. - */ -static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, - ALSChannelData **cd, int *reverted, - unsigned int offset, int c) -{ - ALSChannelData *ch = cd[c]; - unsigned int dep = 0; - unsigned int channels = ctx->avctx->channels; - - if (reverted[c]) - return 0; - - reverted[c] = 1; - - while (dep < channels && !ch[dep].stop_flag) { - revert_channel_correlation(ctx, bd, cd, reverted, offset, - ch[dep].master_channel); - - dep++; - } - - if (dep == channels) { - av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel correlation!\n"); - return -1; - } - - bd->use_ltp = ctx->use_ltp + c; - bd->ltp_lag = ctx->ltp_lag + c; - bd->ltp_gain = ctx->ltp_gain[c]; - bd->lpc_cof = ctx->lpc_cof[c]; - bd->quant_cof = ctx->quant_cof[c]; - bd->raw_samples = ctx->raw_samples[c] + offset; - - dep = 0; - while (!ch[dep].stop_flag) { - unsigned int smp; - unsigned int begin = 1; - unsigned int end = bd->block_length - 1; - int64_t y; - int32_t *master = ctx->raw_samples[ch[dep].master_channel] + offset; - - if (ch[dep].time_diff_flag) { - int t = ch[dep].time_diff_index; - - if (ch[dep].time_diff_sign) { - t = -t; - begin -= t; - } else { - end -= t; - } - - for (smp = begin; smp < end; smp++) { - y = (1 << 6) + - MUL64(ch[dep].weighting[0], master[smp - 1 ]) + - MUL64(ch[dep].weighting[1], master[smp ]) + - MUL64(ch[dep].weighting[2], master[smp + 1 ]) + - MUL64(ch[dep].weighting[3], master[smp - 1 + t]) + - MUL64(ch[dep].weighting[4], master[smp + t]) + - MUL64(ch[dep].weighting[5], master[smp + 1 + t]); - - bd->raw_samples[smp] += y >> 7; - } - } else { - for (smp = begin; smp < end; smp++) { - y = (1 << 6) + - MUL64(ch[dep].weighting[0], master[smp - 1]) + - MUL64(ch[dep].weighting[1], master[smp ]) + - MUL64(ch[dep].weighting[2], master[smp + 1]); - - bd->raw_samples[smp] += y >> 7; - } - } - - dep++; - } - - return 0; -} - - -/** Reads the frame data. - */ -static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) -{ - ALSSpecificConfig *sconf = &ctx->sconf; - AVCodecContext *avctx = ctx->avctx; - GetBitContext *gb = &ctx->gb; - unsigned int div_blocks[32]; ///< block sizes. - unsigned int c; - unsigned int js_blocks[2]; - - uint32_t bs_info = 0; - - // skip the size of the ra unit if present in the frame - if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame) - skip_bits_long(gb, 32); - - if (sconf->mc_coding && sconf->joint_stereo) { - ctx->js_switch = get_bits1(gb); - align_get_bits(gb); - } - - if (!sconf->mc_coding || ctx->js_switch) { - int independent_bs = !sconf->joint_stereo; - - for (c = 0; c < avctx->channels; c++) { - js_blocks[0] = 0; - js_blocks[1] = 0; - - get_block_sizes(ctx, div_blocks, &bs_info); - - // if joint_stereo and block_switching is set, independent decoding - // is signaled via the first bit of bs_info - if (sconf->joint_stereo && sconf->block_switching) - if (bs_info >> 31) - independent_bs = 2; - - // if this is the last channel, it has to be decoded independently - if (c == avctx->channels - 1) - independent_bs = 1; - - if (independent_bs) { - if (decode_blocks_ind(ctx, ra_frame, c, div_blocks, js_blocks)) - return -1; - - independent_bs--; - } else { - if (decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks)) - return -1; - - c++; - } - - // store carryover raw samples - memmove(ctx->raw_samples[c] - sconf->max_order, - ctx->raw_samples[c] - sconf->max_order + sconf->frame_length, - sizeof(*ctx->raw_samples[c]) * sconf->max_order); - } - } else { // multi-channel coding - ALSBlockData bd; - int b; - int *reverted_channels = ctx->reverted_channels; - unsigned int offset = 0; - - for (c = 0; c < avctx->channels; c++) - if (ctx->chan_data[c] < ctx->chan_data_buffer) { - av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data!\n"); - return -1; - } - - memset(&bd, 0, sizeof(ALSBlockData)); - memset(reverted_channels, 0, sizeof(*reverted_channels) * avctx->channels); - - bd.ra_block = ra_frame; - bd.prev_raw_samples = ctx->prev_raw_samples; - - get_block_sizes(ctx, div_blocks, &bs_info); - - for (b = 0; b < ctx->num_blocks; b++) { - bd.shift_lsbs = 0; - bd.block_length = div_blocks[b]; - - for (c = 0; c < avctx->channels; c++) { - bd.use_ltp = ctx->use_ltp + c; - bd.ltp_lag = ctx->ltp_lag + c; - bd.ltp_gain = ctx->ltp_gain[c]; - bd.lpc_cof = ctx->lpc_cof[c]; - bd.quant_cof = ctx->quant_cof[c]; - bd.raw_samples = ctx->raw_samples[c] + offset; - bd.raw_other = NULL; - - read_block(ctx, &bd); - if (read_channel_data(ctx, ctx->chan_data[c], c)) - return -1; - } - - for (c = 0; c < avctx->channels; c++) - if (revert_channel_correlation(ctx, &bd, ctx->chan_data, - reverted_channels, offset, c)) - return -1; - - for (c = 0; c < avctx->channels; c++) { - bd.use_ltp = ctx->use_ltp + c; - bd.ltp_lag = ctx->ltp_lag + c; - bd.ltp_gain = ctx->ltp_gain[c]; - bd.lpc_cof = ctx->lpc_cof[c]; - bd.quant_cof = ctx->quant_cof[c]; - bd.raw_samples = ctx->raw_samples[c] + offset; - decode_block(ctx, &bd); - } - - memset(reverted_channels, 0, avctx->channels * sizeof(*reverted_channels)); - offset += div_blocks[b]; - bd.ra_block = 0; - } - - // store carryover raw samples - for (c = 0; c < avctx->channels; c++) - memmove(ctx->raw_samples[c] - sconf->max_order, - ctx->raw_samples[c] - sconf->max_order + sconf->frame_length, - sizeof(*ctx->raw_samples[c]) * sconf->max_order); - } - - // TODO: read_diff_float_data - - return 0; -} - - -/** Decodes an ALS frame. - */ -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - ALSDecContext *ctx = avctx->priv_data; - ALSSpecificConfig *sconf = &ctx->sconf; - const uint8_t *buffer = avpkt->data; - int buffer_size = avpkt->size; - int invalid_frame, size; - unsigned int c, sample, ra_frame, bytes_read, shift; - - init_get_bits(&ctx->gb, buffer, buffer_size * 8); - - // In the case that the distance between random access frames is set to zero - // (sconf->ra_distance == 0) no frame is treated as a random access frame. - // For the first frame, if prediction is used, all samples used from the - // previous frame are assumed to be zero. - ra_frame = sconf->ra_distance && !(ctx->frame_id % sconf->ra_distance); - - // the last frame to decode might have a different length - if (sconf->samples != 0xFFFFFFFF) - ctx->cur_frame_length = FFMIN(sconf->samples - ctx->frame_id * (uint64_t) sconf->frame_length, - sconf->frame_length); - else - ctx->cur_frame_length = sconf->frame_length; - - // decode the frame data - if ((invalid_frame = read_frame_data(ctx, ra_frame) < 0)) - av_log(ctx->avctx, AV_LOG_WARNING, - "Reading frame data failed. Skipping RA unit.\n"); - - ctx->frame_id++; - - // check for size of decoded data - size = ctx->cur_frame_length * avctx->channels * - (av_get_bits_per_sample_format(avctx->sample_fmt) >> 3); - - if (size > *data_size) { - av_log(avctx, AV_LOG_ERROR, "Decoded data exceeds buffer size.\n"); - return -1; - } - - *data_size = size; - - // transform decoded frame into output format - #define INTERLEAVE_OUTPUT(bps) \ - { \ - int##bps##_t *dest = (int##bps##_t*) data; \ - shift = bps - ctx->avctx->bits_per_raw_sample; \ - for (sample = 0; sample < ctx->cur_frame_length; sample++) \ - for (c = 0; c < avctx->channels; c++) \ - *dest++ = ctx->raw_samples[c][sample] << shift; \ - } - - if (ctx->avctx->bits_per_raw_sample <= 16) { - INTERLEAVE_OUTPUT(16) - } else { - INTERLEAVE_OUTPUT(32) - } - - bytes_read = invalid_frame ? buffer_size : - (get_bits_count(&ctx->gb) + 7) >> 3; - - return bytes_read; -} - - -/** Uninitializes the ALS decoder. - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - ALSDecContext *ctx = avctx->priv_data; - - av_freep(&ctx->sconf.chan_pos); - - ff_bgmc_end(&ctx->bgmc_lut, &ctx->bgmc_lut_status); - - av_freep(&ctx->use_ltp); - av_freep(&ctx->ltp_lag); - av_freep(&ctx->ltp_gain); - av_freep(&ctx->ltp_gain_buffer); - av_freep(&ctx->quant_cof); - av_freep(&ctx->lpc_cof); - av_freep(&ctx->quant_cof_buffer); - av_freep(&ctx->lpc_cof_buffer); - av_freep(&ctx->lpc_cof_reversed_buffer); - av_freep(&ctx->prev_raw_samples); - av_freep(&ctx->raw_samples); - av_freep(&ctx->raw_buffer); - av_freep(&ctx->chan_data); - av_freep(&ctx->chan_data_buffer); - av_freep(&ctx->reverted_channels); - - return 0; -} - - -/** Initializes the ALS decoder. - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - unsigned int c; - unsigned int channel_size; - int num_buffers; - ALSDecContext *ctx = avctx->priv_data; - ALSSpecificConfig *sconf = &ctx->sconf; - ctx->avctx = avctx; - - if (!avctx->extradata) { - av_log(avctx, AV_LOG_ERROR, "Missing required ALS extradata.\n"); - return -1; - } - - if (read_specific_config(ctx)) { - av_log(avctx, AV_LOG_ERROR, "Reading ALSSpecificConfig failed.\n"); - decode_end(avctx); - return -1; - } - - if (check_specific_config(ctx)) { - decode_end(avctx); - return -1; - } - - if (sconf->bgmc) - ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status); - - if (sconf->floating) { - avctx->sample_fmt = SAMPLE_FMT_FLT; - avctx->bits_per_raw_sample = 32; - } else { - avctx->sample_fmt = sconf->resolution > 1 - ? SAMPLE_FMT_S32 : SAMPLE_FMT_S16; - avctx->bits_per_raw_sample = (sconf->resolution + 1) * 8; - } - - // set maximum Rice parameter for progressive decoding based on resolution - // This is not specified in 14496-3 but actually done by the reference - // codec RM22 revision 2. - ctx->s_max = sconf->resolution > 1 ? 31 : 15; - - // set lag value for long-term prediction - ctx->ltp_lag_length = 8 + (avctx->sample_rate >= 96000) + - (avctx->sample_rate >= 192000); - - // allocate quantized parcor coefficient buffer - num_buffers = sconf->mc_coding ? avctx->channels : 1; - - ctx->quant_cof = av_malloc(sizeof(*ctx->quant_cof) * num_buffers); - ctx->lpc_cof = av_malloc(sizeof(*ctx->lpc_cof) * num_buffers); - ctx->quant_cof_buffer = av_malloc(sizeof(*ctx->quant_cof_buffer) * - num_buffers * sconf->max_order); - ctx->lpc_cof_buffer = av_malloc(sizeof(*ctx->lpc_cof_buffer) * - num_buffers * sconf->max_order); - ctx->lpc_cof_reversed_buffer = av_malloc(sizeof(*ctx->lpc_cof_buffer) * - sconf->max_order); - - if (!ctx->quant_cof || !ctx->lpc_cof || - !ctx->quant_cof_buffer || !ctx->lpc_cof_buffer || - !ctx->lpc_cof_reversed_buffer) { - av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - return AVERROR(ENOMEM); - } - - // assign quantized parcor coefficient buffers - for (c = 0; c < num_buffers; c++) { - ctx->quant_cof[c] = ctx->quant_cof_buffer + c * sconf->max_order; - ctx->lpc_cof[c] = ctx->lpc_cof_buffer + c * sconf->max_order; - } - - // allocate and assign lag and gain data buffer for ltp mode - ctx->use_ltp = av_mallocz(sizeof(*ctx->use_ltp) * num_buffers); - ctx->ltp_lag = av_malloc (sizeof(*ctx->ltp_lag) * num_buffers); - ctx->ltp_gain = av_malloc (sizeof(*ctx->ltp_gain) * num_buffers); - ctx->ltp_gain_buffer = av_malloc (sizeof(*ctx->ltp_gain_buffer) * - num_buffers * 5); - - if (!ctx->use_ltp || !ctx->ltp_lag || - !ctx->ltp_gain || !ctx->ltp_gain_buffer) { - av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); - } - - for (c = 0; c < num_buffers; c++) - ctx->ltp_gain[c] = ctx->ltp_gain_buffer + c * 5; - - // allocate and assign channel data buffer for mcc mode - if (sconf->mc_coding) { - ctx->chan_data_buffer = av_malloc(sizeof(*ctx->chan_data_buffer) * - num_buffers * num_buffers); - ctx->chan_data = av_malloc(sizeof(*ctx->chan_data) * - num_buffers); - ctx->reverted_channels = av_malloc(sizeof(*ctx->reverted_channels) * - num_buffers); - - if (!ctx->chan_data_buffer || !ctx->chan_data || !ctx->reverted_channels) { - av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); - } - - for (c = 0; c < num_buffers; c++) - ctx->chan_data[c] = ctx->chan_data_buffer + c * num_buffers; - } else { - ctx->chan_data = NULL; - ctx->chan_data_buffer = NULL; - ctx->reverted_channels = NULL; - } - - avctx->frame_size = sconf->frame_length; - channel_size = sconf->frame_length + sconf->max_order; - - ctx->prev_raw_samples = av_malloc (sizeof(*ctx->prev_raw_samples) * sconf->max_order); - ctx->raw_buffer = av_mallocz(sizeof(*ctx-> raw_buffer) * avctx->channels * channel_size); - ctx->raw_samples = av_malloc (sizeof(*ctx-> raw_samples) * avctx->channels); - - // allocate previous raw sample buffer - if (!ctx->prev_raw_samples || !ctx->raw_buffer|| !ctx->raw_samples) { - av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); - } - - // assign raw samples buffers - ctx->raw_samples[0] = ctx->raw_buffer + sconf->max_order; - for (c = 1; c < avctx->channels; c++) - ctx->raw_samples[c] = ctx->raw_samples[c - 1] + channel_size; - - return 0; -} - - -/** Flushes (resets) the frame ID after seeking. - */ -static av_cold void flush(AVCodecContext *avctx) -{ - ALSDecContext *ctx = avctx->priv_data; - - ctx->frame_id = 0; -} - - -AVCodec als_decoder = { - "als", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP4ALS, - sizeof(ALSDecContext), - decode_init, - NULL, - decode_end, - decode_frame, - .flush = flush, - .capabilities = CODEC_CAP_SUBFRAMES, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/amrnbdata.h b/tizen/distrib/ffmpeg/libavcodec/amrnbdata.h deleted file mode 100644 index 2f21439..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/amrnbdata.h +++ /dev/null @@ -1,1672 +0,0 @@ -/* - * AMR narrowband data and definitions - * Copyright (c) 2006-2007 Robert Swain - * Copyright (c) 2009 Colin McQuillan - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -/** - * @file - * AMR narrowband data and definitions - */ - -#ifndef AVCODEC_AMRNBDATA_H -#define AVCODEC_AMRNBDATA_H - -#include - -#include "libavutil/common.h" /* offsetof */ - -#define AMR_SUBFRAME_SIZE 40 ///< samples per subframe - -/** Frame type (Table 1a in 3GPP TS 26.101) */ -enum Mode { - MODE_4k75 = 0, ///< 4.75 kbit/s - MODE_5k15, ///< 5.15 kbit/s - MODE_5k9, ///< 5.90 kbit/s - MODE_6k7, ///< 6.70 kbit/s - MODE_7k4, ///< 7.40 kbit/s - MODE_7k95, ///< 7.95 kbit/s - MODE_10k2, ///< 10.2 kbit/s - MODE_12k2, ///< 12.2 kbit/s - MODE_DTX, ///< silent frame - N_MODES, ///< number of modes - NO_DATA = 15 ///< no transmission -}; - -#define LP_FILTER_ORDER 10 ///< linear predictive coding filter order - -/** - * AMRNB unpacked data subframe - */ -typedef struct { - uint16_t p_lag; ///< index to decode the pitch lag - uint16_t p_gain; ///< index to decode the pitch gain - uint16_t fixed_gain; ///< index to decode the fixed gain factor, for MODE_12k2 and MODE_7k95 - uint16_t pulses[10]; ///< pulses: 10 for MODE_12k2, 7 for MODE_10k2, and index and sign for others -} AMRNBSubframe; - -/** - * AMRNB unpacked data frame - */ -typedef struct { - uint16_t lsf[5]; ///< lsf parameters: 5 parameters for MODE_12k2, only 3 for other modes - AMRNBSubframe subframe[4]; ///< unpacked data for each subframe -} AMRNBFrame; - -/** The index of a frame parameter */ -#define AMR_BIT(field) (offsetof(AMRNBFrame, field) >> 1) -/** The index of a subframe-specific parameter */ -#define AMR_OF(frame_num, variable) AMR_BIT(subframe[frame_num].variable) - -// The following order* tables are used to convert AMR frame parameters to and -// from a bitstream. See 3GPP TS 26.101 for more information. -// Each field in AMRNBFrame is stored as: -// * one byte for the number of bits in the field -// * one byte for the field index -// * then, one byte for each bit of the field (from most-significant to least) -// of the position of that bit in the AMR frame. -static const uint8_t order_MODE_4k75[] = { - 8, AMR_BIT(lsf[0]), 7, 6, 5, 4, 3, 2, 1, 0, - 8, AMR_BIT(lsf[1]), 15, 14, 13, 12, 11, 10, 9, 8, - 7, AMR_BIT(lsf[2]), 51, 35, 34, 50, 33, 49, 32, - 8, AMR_OF(0,p_lag), 23, 22, 21, 20, 19, 18, 43, 42, - 8, AMR_OF(0,p_gain), 54, 55, 40, 41, 24, 25, 26, 27, - 7, AMR_OF(0,pulses[0]), 92, 68, 67, 84, 66, 65, 80, - 2, AMR_OF(0,pulses[1]), 53, 52, - 4, AMR_OF(1,p_lag), 17, 16, 48, 63, - 7, AMR_OF(1,pulses[0]), 91, 64, 79, 83, 78, 77, 95, - 2, AMR_OF(1,pulses[1]), 62, 61, - 4, AMR_OF(2,p_lag), 31, 30, 60, 59, - 8, AMR_OF(2,p_gain), 44, 45, 46, 47, 36, 37, 38, 39, - 7, AMR_OF(2,pulses[0]), 90, 76, 75, 82, 74, 73, 94, - 2, AMR_OF(2,pulses[1]), 58, 57, - 4, AMR_OF(3,p_lag), 29, 28, 56, 71, - 7, AMR_OF(3,pulses[0]), 89, 72, 87, 81, 86, 85, 93, - 2, AMR_OF(3,pulses[1]), 70, 69, - 0 -}; - -static const uint8_t order_MODE_5k15[] = { - 8, AMR_BIT(lsf[0]), 0, 1, 2, 3, 4, 5, 6, 7, - 8, AMR_BIT(lsf[1]), 8, 9, 10, 11, 12, 13, 14, 15, - 7, AMR_BIT(lsf[2]), 70, 51, 43, 71, 50, 60, 49, - 8, AMR_OF(0,p_lag), 23, 22, 21, 20, 19, 47, 54, 59, - 6, AMR_OF(0,p_gain), 48, 42, 35, 29, 30, 31, - 7, AMR_OF(0,pulses[0]), 92, 84, 82, 100, 79, 72, 88, - 2, AMR_OF(0,pulses[1]), 67, 68, - 4, AMR_OF(1,p_lag), 18, 46, 53, 58, - 6, AMR_OF(1,p_gain), 63, 41, 34, 26, 27, 28, - 7, AMR_OF(1,pulses[0]), 91, 83, 81, 99, 78, 87, 103, - 2, AMR_OF(1,pulses[1]), 65, 66, - 4, AMR_OF(2,p_lag), 17, 45, 52, 57, - 6, AMR_OF(2,p_gain), 62, 40, 33, 39, 24, 25, - 7, AMR_OF(2,pulses[0]), 90, 80, 95, 98, 77, 86, 102, - 2, AMR_OF(2,pulses[1]), 75, 64, - 4, AMR_OF(3,p_lag), 16, 44, 56, 69, - 6, AMR_OF(3,p_gain), 61, 55, 32, 36, 37, 38, - 7, AMR_OF(3,pulses[0]), 89, 94, 93, 97, 76, 85, 101, - 2, AMR_OF(3,pulses[1]), 73, 74, - 0 -}; - -static const uint8_t order_MODE_5k9[] = { - 8, AMR_BIT(lsf[0]), 7, 6, 0, 3, 5, 4, 2, 1, - 9, AMR_BIT(lsf[1]), 13, 12, 8, 11, 10, 15, 9, 14, 23, - 9, AMR_BIT(lsf[2]), 71, 56, 60, 70, 59, 57, 58, 69, 76, - 8, AMR_OF(0,p_lag), 16, 18, 22, 20, 30, 38, 44, 42, - 6, AMR_OF(0,p_gain), 75, 48, 52, 40, 34, 26, - 9, AMR_OF(0,pulses[0]), 101, 89, 93, 117, 105, 81, 85, 109, 97, - 2, AMR_OF(0,pulses[1]), 67, 78, - 4, AMR_OF(1,p_lag), 28, 36, 46, 87, - 6, AMR_OF(1,p_gain), 74, 63, 51, 55, 33, 25, - 9, AMR_OF(1,pulses[0]), 100, 88, 92, 116, 104, 80, 84, 108, 96, - 2, AMR_OF(1,pulses[1]), 64, 79, - 8, AMR_OF(2,p_lag), 31, 17, 21, 19, 29, 37, 43, 41, - 6, AMR_OF(2,p_gain), 73, 62, 50, 54, 32, 24, - 9, AMR_OF(2,pulses[0]), 99, 103, 91, 115, 119, 95, 83, 107, 111, - 2, AMR_OF(2,pulses[1]), 66, 77, - 4, AMR_OF(3,p_lag), 27, 35, 45, 86, - 6, AMR_OF(3,p_gain), 72, 61, 49, 53, 47, 39, - 9, AMR_OF(3,pulses[0]), 98, 102, 90, 114, 118, 94, 82, 106, 110, - 2, AMR_OF(3,pulses[1]), 65, 68, - 0 -}; - -static const uint8_t order_MODE_6k7[] = { - 8, AMR_BIT(lsf[0]), 7, 6, 15, 4, 5, 3, 2, 0, - 9, AMR_BIT(lsf[1]), 14, 13, 8, 12, 10, 1, 9, 11, 29, - 9, AMR_BIT(lsf[2]), 57, 58, 50, 56, 60, 59, 49, 71, 70, - 8, AMR_OF(0,p_lag), 17, 19, 23, 21, 31, 24, 32, 52, - 7, AMR_OF(0,p_gain), 36, 82, 69, 46, 42, 48, 77, - 11, AMR_OF(0,pulses[0]), 109, 97, 133, 121, 101, 89, 125, 113, 93, 117, - 105, - 3, AMR_OF(0,pulses[1]), 81, 73, 65, - 4, AMR_OF(1,p_lag), 28, 26, 38, 54, - 7, AMR_OF(1,p_gain), 35, 83, 68, 45, 41, 63, 76, - 11, AMR_OF(1,pulses[0]), 108, 96, 132, 120, 100, 88, 124, 112, 92, 116, - 104, - 3, AMR_OF(1,pulses[1]), 80, 72, 64, - 8, AMR_OF(2,p_lag), 16, 18, 22, 20, 30, 39, 47, 51, - 7, AMR_OF(2,p_gain), 34, 84, 67, 44, 40, 62, 75, - 11, AMR_OF(2,pulses[0]), 107, 111, 131, 135, 99, 103, 123, 127, 91, 115, - 119, - 3, AMR_OF(2,pulses[1]), 95, 87, 79, - 4, AMR_OF(3,p_lag), 27, 25, 37, 53, - 7, AMR_OF(3,p_gain), 33, 85, 66, 43, 55, 61, 74, - 11, AMR_OF(3,pulses[0]), 106, 110, 130, 134, 98, 102, 122, 126, 90, 114, - 118, - 3, AMR_OF(3,pulses[1]), 94, 86, 78, - 0 -}; - -static const uint8_t order_MODE_7k4[] = { - 8, AMR_BIT(lsf[0]), 7, 6, 5, 4, 3, 2, 1, 0, - 9, AMR_BIT(lsf[1]), 15, 14, 13, 12, 11, 10, 9, 8, 23, - 9, AMR_BIT(lsf[2]), 53, 52, 51, 58, 40, 55, 54, 57, 56, - 8, AMR_OF(0,p_lag), 22, 20, 18, 16, 30, 50, 95, 94, - 7, AMR_OF(0,p_gain), 28, 24, 73, 36, 32, 62, 67, - 13, AMR_OF(0,pulses[0]), 127, 123, 135, 131, 143, 139, 151, 103, 102, 101, - 100, 99, 98, - 4, AMR_OF(0,pulses[1]), 83, 75, 79, 71, - 5, AMR_OF(1,p_lag), 44, 42, 49, 93, 92, - 7, AMR_OF(1,p_gain), 27, 39, 72, 35, 47, 61, 66, - 13, AMR_OF(1,pulses[0]), 126, 122, 134, 130, 142, 138, 150, 97, 96, 111, - 110, 109, 108, - 4, AMR_OF(1,pulses[1]), 82, 74, 78, 70, - 8, AMR_OF(2,p_lag), 21, 19, 17, 31, 29, 48, 91, 90, - 7, AMR_OF(2,p_gain), 26, 38, 87, 34, 46, 60, 65, - 13, AMR_OF(2,pulses[0]), 125, 121, 133, 129, 141, 137, 149, 107, 106, 105, - 104, 119, 118, - 4, AMR_OF(2,pulses[1]), 81, 85, 77, 69, - 5, AMR_OF(3,p_lag), 43, 41, 63, 89, 88, - 7, AMR_OF(3,p_gain), 25, 37, 86, 33, 45, 59, 64, - 13, AMR_OF(3,pulses[0]), 124, 120, 132, 128, 140, 136, 148, 117, 116, 115, - 114, 113, 112, - 4, AMR_OF(3,pulses[1]), 80, 84, 76, 68, - 0 -}; - -static const uint8_t order_MODE_7k95[] = { - 9, AMR_BIT(lsf[0]), 67, 68, 1, 2, 3, 4, 5, 6, 7, - 9, AMR_BIT(lsf[1]), 14, 13, 9, 12, 11, 0, 10, 15, 8, - 9, AMR_BIT(lsf[2]), 18, 19, 23, 17, 22, 20, 21, 66, 65, - 8, AMR_OF(0,p_lag), 44, 42, 40, 54, 52, 56, 64, 78, - 4, AMR_OF(0,p_gain), 36, 32, 72, 80, - 5, AMR_OF(0,fixed_gain), 16, 28, 24, 60, 84, - 13, AMR_OF(0,pulses[0]), 135, 109, 144, 156, 120, 97, 148, 121, 101, 122, - 123, 89, 124, - 4, AMR_OF(0,pulses[1]), 125, 126, 127, 112, - 6, AMR_OF(1,p_lag), 50, 48, 62, 70, 76, 74, - 4, AMR_OF(1,p_gain), 35, 47, 87, 95, - 5, AMR_OF(1,fixed_gain), 31, 27, 39, 59, 83, - 13, AMR_OF(1,pulses[0]), 129, 108, 159, 155, 130, 96, 147, 131, 100, 132, - 133, 88, 134, - 4, AMR_OF(1,pulses[1]), 113, 114, 115, 116, - 8, AMR_OF(2,p_lag), 43, 41, 55, 53, 51, 71, 79, 77, - 4, AMR_OF(2,p_gain), 34, 46, 86, 94, - 5, AMR_OF(2,fixed_gain), 30, 26, 38, 58, 82, - 13, AMR_OF(2,pulses[0]), 139, 107, 158, 154, 140, 111, 146, 141, 99, 142, - 143, 103, 128, - 4, AMR_OF(2,pulses[1]), 105, 90, 91, 92, - 6, AMR_OF(3,p_lag), 49, 63, 61, 69, 75, 73, - 4, AMR_OF(3,p_gain), 33, 45, 85, 93, - 5, AMR_OF(3,fixed_gain), 29, 25, 37, 57, 81, - 13, AMR_OF(3,pulses[0]), 149, 106, 157, 153, 150, 110, 145, 151, 98, 136, - 137, 102, 138, - 4, AMR_OF(3,pulses[1]), 117, 118, 119, 104, - 0 -}; - -static const uint8_t order_MODE_10k2[] = { - 8, AMR_BIT(lsf[0]), 0, 1, 2, 3, 4, 5, 6, 7, - 9, AMR_BIT(lsf[1]), 23, 8, 9, 10, 11, 12, 13, 14, 15, - 9, AMR_BIT(lsf[2]), 57, 58, 62, 56, 60, 59, 61, 71, 70, - 8, AMR_OF(0,p_lag), 22, 21, 20, 19, 18, 17, 42, 41, - 7, AMR_OF(0,p_gain), 38, 50, 84, 37, 36, 85, 83, - 1, AMR_OF(0,pulses[0]), 66, - 1, AMR_OF(0,pulses[1]), 67, - 1, AMR_OF(0,pulses[2]), 68, - 1, AMR_OF(0,pulses[3]), 69, - 10, AMR_OF(0,pulses[4]), 145, 144, 156, 153, 154, 163, 161, 192, 206, 195, - 10, AMR_OF(0,pulses[5]), 158, 159, 157, 152, 155, 165, 160, 205, 204, 194, - 7, AMR_OF(0,pulses[6]), 167, 166, 162, 164, 196, 207, 193, - 5, AMR_OF(1,p_lag), 26, 25, 54, 53, 89, - 7, AMR_OF(1,p_gain), 35, 49, 81, 34, 33, 82, 80, - 1, AMR_OF(1,pulses[0]), 78, - 1, AMR_OF(1,pulses[1]), 79, - 1, AMR_OF(1,pulses[2]), 64, - 1, AMR_OF(1,pulses[3]), 65, - 10, AMR_OF(1,pulses[4]), 103, 102, 98, 111, 96, 105, 119, 185, 199, 188, - 10, AMR_OF(1,pulses[5]), 100, 101, 99, 110, 97, 107, 118, 198, 197, 187, - 7, AMR_OF(1,pulses[6]), 109, 108, 104, 106, 189, 184, 186, - 8, AMR_OF(2,p_lag), 16, 31, 30, 29, 28, 27, 40, 55, - 7, AMR_OF(2,p_gain), 32, 48, 94, 47, 46, 95, 93, - 1, AMR_OF(2,pulses[0]), 74, - 1, AMR_OF(2,pulses[1]), 75, - 1, AMR_OF(2,pulses[2]), 76, - 1, AMR_OF(2,pulses[3]), 77, - 10, AMR_OF(2,pulses[4]), 117, 116, 112, 125, 126, 135, 133, 178, 176, 181, - 10, AMR_OF(2,pulses[5]), 114, 115, 113, 124, 127, 121, 132, 191, 190, 180, - 7, AMR_OF(2,pulses[6]), 123, 122, 134, 120, 182, 177, 179, - 5, AMR_OF(3,p_lag), 24, 39, 52, 51, 88, - 7, AMR_OF(3,p_gain), 45, 63, 91, 44, 43, 92, 90, - 1, AMR_OF(3,pulses[0]), 86, - 1, AMR_OF(3,pulses[1]), 87, - 1, AMR_OF(3,pulses[2]), 72, - 1, AMR_OF(3,pulses[3]), 73, - 10, AMR_OF(3,pulses[4]), 131, 130, 142, 139, 140, 149, 147, 171, 169, 174, - 10, AMR_OF(3,pulses[5]), 128, 129, 143, 138, 141, 151, 146, 168, 183, 173, - 7, AMR_OF(3,pulses[6]), 137, 136, 148, 150, 175, 170, 172, - 0 -}; - -static const uint8_t order_MODE_12k2[] = { - 7, AMR_BIT(lsf[0]), 7, 6, 5, 4, 3, 2, 1, - 8, AMR_BIT(lsf[1]), 0, 15, 14, 13, 12, 11, 10, 9, - 9, AMR_BIT(lsf[2]), 23, 22, 21, 20, 19, 18, 17, 16, 8, - 8, AMR_BIT(lsf[3]), 31, 30, 29, 28, 27, 86, 85, 84, - 6, AMR_BIT(lsf[4]), 83, 82, 81, 80, 127, 126, - 9, AMR_OF(0,p_lag), 26, 24, 38, 36, 34, 32, 46, 44, 42, - 4, AMR_OF(0,p_gain), 40, 52, 48, 95, - 5, AMR_OF(0,fixed_gain), 60, 56, 68, 91, 111, - 3, AMR_OF(0,pulses[0]), 191, 176, 177, - 4, AMR_OF(0,pulses[1]), 103, 123, 124, 125, - 3, AMR_OF(0,pulses[2]), 188, 189, 190, - 4, AMR_OF(0,pulses[3]), 99, 120, 121, 122, - 3, AMR_OF(0,pulses[4]), 185, 186, 187, - 4, AMR_OF(0,pulses[5]), 107, 133, 134, 135, - 3, AMR_OF(0,pulses[6]), 198, 199, 184, - 4, AMR_OF(0,pulses[7]), 119, 130, 131, 132, - 3, AMR_OF(0,pulses[8]), 195, 196, 197, - 4, AMR_OF(0,pulses[9]), 115, 143, 128, 129, - 6, AMR_OF(1,p_lag), 64, 78, 76, 74, 72, 245, - 4, AMR_OF(1,p_gain), 55, 51, 63, 94, - 5, AMR_OF(1,fixed_gain), 59, 71, 67, 90, 110, - 3, AMR_OF(1,pulses[0]), 192, 193, 194, - 4, AMR_OF(1,pulses[1]), 102, 140, 141, 142, - 3, AMR_OF(1,pulses[2]), 205, 206, 207, - 4, AMR_OF(1,pulses[3]), 98, 137, 138, 139, - 3, AMR_OF(1,pulses[4]), 202, 203, 204, - 4, AMR_OF(1,pulses[5]), 106, 150, 151, 136, - 3, AMR_OF(1,pulses[6]), 215, 200, 201, - 4, AMR_OF(1,pulses[7]), 118, 147, 148, 149, - 3, AMR_OF(1,pulses[8]), 212, 213, 214, - 4, AMR_OF(1,pulses[9]), 114, 144, 145, 146, - 9, AMR_OF(2,p_lag), 25, 39, 37, 35, 33, 47, 45, 43, 41, - 4, AMR_OF(2,p_gain), 54, 50, 62, 93, - 5, AMR_OF(2,fixed_gain), 58, 70, 66, 89, 109, - 3, AMR_OF(2,pulses[0]), 209, 210, 211, - 4, AMR_OF(2,pulses[1]), 101, 157, 158, 159, - 3, AMR_OF(2,pulses[2]), 222, 223, 208, - 4, AMR_OF(2,pulses[3]), 97, 154, 155, 156, - 3, AMR_OF(2,pulses[4]), 219, 220, 221, - 4, AMR_OF(2,pulses[5]), 105, 167, 152, 153, - 3, AMR_OF(2,pulses[6]), 216, 217, 218, - 4, AMR_OF(2,pulses[7]), 117, 164, 165, 166, - 3, AMR_OF(2,pulses[8]), 229, 230, 231, - 4, AMR_OF(2,pulses[9]), 113, 161, 162, 163, - 6, AMR_OF(3,p_lag), 79, 77, 75, 73, 87, 244, - 4, AMR_OF(3,p_gain), 53, 49, 61, 92, - 5, AMR_OF(3,fixed_gain), 57, 69, 65, 88, 108, - 3, AMR_OF(3,pulses[0]), 226, 227, 228, - 4, AMR_OF(3,pulses[1]), 100, 174, 175, 160, - 3, AMR_OF(3,pulses[2]), 239, 224, 225, - 4, AMR_OF(3,pulses[3]), 96, 171, 172, 173, - 3, AMR_OF(3,pulses[4]), 236, 237, 238, - 4, AMR_OF(3,pulses[5]), 104, 168, 169, 170, - 3, AMR_OF(3,pulses[6]), 233, 234, 235, - 4, AMR_OF(3,pulses[7]), 116, 181, 182, 183, - 3, AMR_OF(3,pulses[8]), 246, 247, 232, - 4, AMR_OF(3,pulses[9]), 112, 178, 179, 180, - 0 -}; - -/** - * position of the bitmapping data for each packet type in - * the AMRNBFrame - */ -static const uint8_t * const amr_unpacking_bitmaps_per_mode[N_MODES] = { - order_MODE_4k75, - order_MODE_5k15, - order_MODE_5k9, - order_MODE_6k7, - order_MODE_7k4, - order_MODE_7k95, - order_MODE_10k2, - order_MODE_12k2, -}; - -/** number of bytes for each mode */ -static const uint8_t frame_sizes_nb[N_MODES] = { - 12, 13, 15, 17, 19, 20, 26, 31, 5 -}; - -/** - * Base-5 representation for values 0-124 - * - * This is useful for decoding pulse positions in 10.2 kbit/s frames. - * Safe values are provided for out of range positions 125-127. - */ -static const uint8_t base_five_table[128][3] = { - {0, 0, 0}, {0, 0, 1}, {0, 0, 2}, {0, 0, 3}, {0, 0, 4}, {0, 1, 0}, {0, 1, 1}, - {0, 1, 2}, {0, 1, 3}, {0, 1, 4}, {0, 2, 0}, {0, 2, 1}, {0, 2, 2}, {0, 2, 3}, - {0, 2, 4}, {0, 3, 0}, {0, 3, 1}, {0, 3, 2}, {0, 3, 3}, {0, 3, 4}, {0, 4, 0}, - {0, 4, 1}, {0, 4, 2}, {0, 4, 3}, {0, 4, 4}, {1, 0, 0}, {1, 0, 1}, {1, 0, 2}, - {1, 0, 3}, {1, 0, 4}, {1, 1, 0}, {1, 1, 1}, {1, 1, 2}, {1, 1, 3}, {1, 1, 4}, - {1, 2, 0}, {1, 2, 1}, {1, 2, 2}, {1, 2, 3}, {1, 2, 4}, {1, 3, 0}, {1, 3, 1}, - {1, 3, 2}, {1, 3, 3}, {1, 3, 4}, {1, 4, 0}, {1, 4, 1}, {1, 4, 2}, {1, 4, 3}, - {1, 4, 4}, {2, 0, 0}, {2, 0, 1}, {2, 0, 2}, {2, 0, 3}, {2, 0, 4}, {2, 1, 0}, - {2, 1, 1}, {2, 1, 2}, {2, 1, 3}, {2, 1, 4}, {2, 2, 0}, {2, 2, 1}, {2, 2, 2}, - {2, 2, 3}, {2, 2, 4}, {2, 3, 0}, {2, 3, 1}, {2, 3, 2}, {2, 3, 3}, {2, 3, 4}, - {2, 4, 0}, {2, 4, 1}, {2, 4, 2}, {2, 4, 3}, {2, 4, 4}, {3, 0, 0}, {3, 0, 1}, - {3, 0, 2}, {3, 0, 3}, {3, 0, 4}, {3, 1, 0}, {3, 1, 1}, {3, 1, 2}, {3, 1, 3}, - {3, 1, 4}, {3, 2, 0}, {3, 2, 1}, {3, 2, 2}, {3, 2, 3}, {3, 2, 4}, {3, 3, 0}, - {3, 3, 1}, {3, 3, 2}, {3, 3, 3}, {3, 3, 4}, {3, 4, 0}, {3, 4, 1}, {3, 4, 2}, - {3, 4, 3}, {3, 4, 4}, {4, 0, 0}, {4, 0, 1}, {4, 0, 2}, {4, 0, 3}, {4, 0, 4}, - {4, 1, 0}, {4, 1, 1}, {4, 1, 2}, {4, 1, 3}, {4, 1, 4}, {4, 2, 0}, {4, 2, 1}, - {4, 2, 2}, {4, 2, 3}, {4, 2, 4}, {4, 3, 0}, {4, 3, 1}, {4, 3, 2}, {4, 3, 3}, - {4, 3, 4}, {4, 4, 0}, {4, 4, 1}, {4, 4, 2}, {4, 4, 3}, {4, 4, 4}, {0, 0, 0}, - {0, 0, 0}, {0, 0, 0} -}; - -/** - * Values for the lsp vector from the 4th subframe of the - * previous subframe values. - * - * @note: Taken from Decoder_amr_reset in Q15 using val/1000 - */ -static const int8_t lsp_sub4_init[LP_FILTER_ORDER] = { - 30, 26, 21, 15, 8, 0, -8, -15, -21, -26 -}; - -/** - * Mean lsp values. - * - * @note: Taken from Decoder_amr_reset in Q15 - */ -static const int16_t lsp_avg_init[LP_FILTER_ORDER] = { - 1384, 2077, 3420, 5108, 6742, 8122, 9863, 11092, 12714, 13701 -}; - -// LSF tables - -// These are stored as integers to save space. The values are taken from -// q_plsf_3.tab and q_plsf_5.tab in 3GPP TS 26.090. - -static const int16_t lsf_3_3_MODE_5k15[128][4] = { -{ 419, 163, -30, -262}, { -455, -789,-1430, -721}, { 1006, 664, 269, 25}, -{ 619, 260, 183, 96}, { -968,-1358, -388, 135}, { -693, 835, 456, 154}, -{ 1105, 703, 569, 363}, { 1625, 1326, 985, 748}, { -220, 219, 76, -208}, -{-1455,-1662, 49, 149}, { -964, -172, -752, -336}, { 625, 209, -250, -66}, -{-1017, -838, -2, 317}, {-2168,-1485, -138, 123}, {-1876,-2099, -521, 85}, -{ -967, -366, -695, -881}, { -921,-1011, -763, -949}, { -124, -256, -352, -660}, -{ 178, 463, 354, 304}, {-1744, -591, -282, 79}, {-2249, 175, 867, 499}, -{ -138, -180, -181, -21}, {-2291,-1241, -460, -520}, { -771, 451, -10, -308}, -{ 271, -65, 4, 214}, { -279, -435, -43, -348}, { -670, 35, -65, -211}, -{ 806, 535, 85, 297}, { 57, 239, 722, 493}, { 225, 661, 840, 547}, -{ -540, -376, 14, 349}, { 469, 721, 331, 162}, { -544, -752, -62, -10}, -{ 398, -88, 724, 701}, { -19, -533, -94, 601}, { 136, -71, -681, -747}, -{ -166, -344, 261, -50}, { 161, -52, 485, 337}, {-1675, 50, 190, -93}, -{-2282, -231, -194, -82}, { -95, -595, -154, 128}, { 894, 501, 588, 457}, -{ -345, 206, 122, 110}, { -631, -227, -569, 3}, { 408, 239, 397, 226}, -{ -197, -2, 128, 491}, { 1281, 904, 292, 215}, { 538, 306, 259, 509}, -{ -677,-1047, 13, 321}, { -679, -588, -358, -212}, { -558, 243, 646, 479}, -{ 486, 342, 634, 532}, { 107, 802, 331, 136}, { -112, -398,-1031, -286}, -{ -326, -705, 288, 272}, { 1299, 1144, 1178, 860}, { -423, 121, -385, -148}, -{ -295, -302, -834, -819}, { 16, -24, -201, -476}, { 555, 91, -245, 294}, -{ -38, -379, -962,-1221}, {-1191,-1518, -273, -395}, { -390,-1013, -645, 573}, -{-1843,-1030, 505, 468}, { 744, 947, 609, 493}, { -689,-1172, -628, -135}, -{-1026, 195, 411, 196}, { 1582, 1147, 575, 337}, {-1239, -777, -648, -142}, -{ 595, 825, 967, 735}, {-1206, -970, -81, -342}, { -745, 13, -72, 375}, -{ 454, 19, 1407, 921}, {-1647, -172, 861, 562}, { 928, 1537, 1063, 740}, -{-2472, -952, 264, 82}, { -502, -965,-1334, 123}, { 867, 1236, 534, 171}, -{-2320, -460, 780, 363}, {-1190, -617, 252, -61}, { -174, 34, 1011, 788}, -{-2333, 247, 423, 153}, { -16, -355, 262, 449}, {-1576,-1073, -544, -371}, -{ -615, -305, 1051, 805}, { 687, 528, 6, -182}, { 935, 875, 1002, 809}, -{ 199, 257, 126, 76}, { -584,-1138, 599, 556}, {-1105,-1391,-1591, -519}, -{ -977,-1325, 108, 347}, { -722, -975, 365, 101}, { -145, 681, 249, -153}, -{ 0, -334, -570, 159}, { 412, 285, -336, -617}, { -953, -966, 887, 689}, -{-1251, 84, -185, -398}, { -592, 433, 1044, 653}, { 85, 329, -40, 361}, -{ -433, -705, 466, 574}, { -154, 654, 592, 290}, { -167, 72, 349, 175}, -{ 674, 297, 977, 720}, { 1235, 1204, 757, 488}, { -400, -269, 538, 372}, -{-1350,-1387,-1194, -91}, { 1262, 876, 775, 700}, { -599, -38, -430, -722}, -{ 1976, 1630, 991, 608}, { 111, 276, -226, -96}, { -947, -388, -11, -7}, -{ -303, -531, -839, 338}, { 1734, 1710, 1405, 1013}, { -516, -855, -645, 210}, -{ -688, -416, 513, 230}, { -822, -637,-1146, -320}, { -952, -658, -694, 183}, -{ -114, -623, 818, 674}, { -191, -204, 731, 635}, { 51, 1221, 883, 576}, -{ -954, -431, 826, 598}, { -342, -755, -900, -407}, {-1126, -354, -206, -512}, -{ -547, -810, -357, -620}, { 66, 515, -73, -410}, { -872, -945,-1444,-1227}, -{ 191, -17, -544, -231}, {-1540, -544, -901, -886} -}; - -static const int16_t lsf_3_1_MODE_7k95[512][3] = { -{ -890,-1550,-2541}, { -819, -970, 175}, { -826,-1234, -762}, -{ -599, -22, 634}, { -811, -987, -902}, { -323, 203, 26}, -{ -383, -235, -781}, { -399, 1262, 906}, { -932,-1399,-1380}, -{ -624, 93, 87}, { -414, -539, -691}, { 37, 633, 510}, -{ -387, -476,-1330}, { 399, 66, 263}, { -407, -49, -335}, -{ -417, 1041, 1865}, { -779,-1089,-1440}, { -746, -858, 832}, -{ -581, -759, -371}, { -673, -506, 2088}, { -560, -634,-1179}, -{ 271, 241, 14}, { -438, -244, -397}, { 463, 1202, 1047}, -{ -606, -797,-1438}, { -51, -323, 481}, { -224, -584, -527}, -{ 494, 881, 682}, { -433, -306,-1002}, { 554, 659, 222}, -{ 171, -160, -353}, { 681, 1798, 1565}, { -852,-1181,-1695}, -{ -336, -666, 114}, { -581, -756, -744}, { -195, 375, 497}, -{ -465, -804,-1098}, { 154, 282, -131}, { -50, -191, -719}, -{ 323, 732, 1542}, { -722, -819,-1404}, { 105, -250, 185}, -{ -178, -502, -742}, { 321, 510, 1111}, { -323, -567, -966}, -{ 127, 484, 338}, { -160, 52, -338}, { 732, 1367, 1554}, -{ -626, -802,-1696}, { -286, -586, 676}, { -695, -343, -370}, -{ -490, 295, 1893}, { -630, -574,-1014}, { -80, 645, -69}, -{ -6, -318, -364}, { 782, 1450, 1038}, { -313, -733,-1395}, -{ 120, 60, 477}, { -264, -585, -123}, { 711, 1245, 633}, -{ -91, -355,-1016}, { 771, 758, 261}, { 253, 81, -474}, -{ 930, 2215, 1720}, { -808,-1099,-1925}, { -560, -782, 169}, -{ -804,-1074, -188}, { -626, -55, 1405}, { -694, -716,-1194}, -{ -660, 354, 329}, { -514, -55, -543}, { 366, 1033, 1182}, -{ -658, -959,-1357}, { -55, -184, 93}, { -605, -286, -662}, -{ 404, 449, 827}, { -286, -350,-1263}, { 628, 306, 227}, -{ -16, 147, -623}, { 186, 923, 2146}, { -674, -890,-1606}, -{ -443, -228, 339}, { -369, -790, -409}, { 231, 86, 1469}, -{ -448, -581,-1061}, { 594, 450, -177}, { -124, -170, -447}, -{ 671, 1159, 1404}, { -476, -667,-1511}, { -77, -138, 716}, -{ -177, -372, -381}, { 451, 934, 915}, { -250, -432, -822}, -{ 272, 828, 446}, { 26, 19, -31}, { 698, 1692, 2168}, -{ -646, -977,-1924}, { -179, -473, 268}, { -379, -745, -691}, -{ 11, 127, 1033}, { -488, -917, -825}, { 61, 323, 135}, -{ 147, -145, -686}, { 685, 786, 1682}, { -506, -848,-1297}, -{ 35, 90, 222}, { -23, -346, -670}, { 455, 591, 1287}, -{ -203, -593,-1086}, { 652, 352, 437}, { 39, 63, -457}, -{ 841, 1265, 2105}, { -520, -882,-1584}, { -328, -711, 1421}, -{ -596, -342, -70}, { 209, 173, 1928}, { -423, -598, -921}, -{ 421, 605, -38}, { -2, -245, -127}, { 896, 1969, 1135}, -{ -379, -518,-1579}, { 173, 118, 753}, { -55, -381, -52}, -{ 985, 1021, 753}, { -2, -291, -891}, { 753, 992, 423}, -{ 264, 131, -196}, { 895, 2274, 2543}, { -635,-1088,-2499}, -{ -529, -982, 526}, { -764, -830, -548}, { -436, 316, 599}, -{ -675, -940, -746}, { -57, 236, -11}, { -201, -81, -798}, -{ 16, 845, 1558}, { -737, -985,-1212}, { -468, 17, 290}, -{ -279, -584, -700}, { 183, 822, 705}, { -265, -492,-1187}, -{ 421, 152, 468}, { -390, 166, -268}, { 39, 1550, 1868}, -{ -635, -966,-1571}, { -453, -492, 910}, { -284,-1027, -75}, -{ -181, -133, 1852}, { -445, -624,-1174}, { 420, 367, -49}, -{ -389, -212, -169}, { 707, 1073, 1208}, { -539, -710,-1449}, -{ 83, -163, 484}, { -236, -543, -355}, { 338, 1175, 814}, -{ -246, -309, -958}, { 606, 760, 60}, { 166, -8, -163}, -{ -306, 1849, 2563}, { -747,-1025,-1783}, { -419, -446, 209}, -{ -718, -566, -534}, { -506, 693, 857}, { -463, -697,-1082}, -{ 325, 431, -206}, { -15, -8, -763}, { 545, 919, 1518}, -{ -611, -783,-1313}, { 256, -55, 208}, { -165, -348, -662}, -{ 321, 680, 930}, { -326, -429, -951}, { 484, 446, 570}, -{ -197, 72, -73}, { 909, 1455, 1741}, { -563, -737,-1974}, -{ -124, -416, 718}, { -478, -404, -314}, { -16, 446, 1636}, -{ -551, -537, -750}, { -58, 638, 214}, { 55, -185, -271}, -{ 1148, 1301, 1212}, { -483, -671,-1264}, { 117, 285, 543}, -{ -204, -391, -111}, { 513, 1538, 854}, { -114, -190, -978}, -{ 877, 595, 464}, { 260, 260, -311}, { 748, 2283, 2216}, -{ -517, -945,-2171}, { -326, -708, 378}, { -812, -691, -232}, -{ -560, 687, 1409}, { -732, -690, -836}, { -359, 645, 386}, -{ -265, 62, -678}, { 145, 1644, 1208}, { -555, -988,-1233}, -{ -78, 14, 114}, { -327, -358, -489}, { 392, 677, 697}, -{ -201, -236,-1140}, { 693, 449, 178}, { -243, 256, -433}, -{ 611, 1385, 2456}, { -612, -901,-1464}, { -307, -17, 499}, -{ -315, -667, -254}, { 256, 428, 1463}, { -486, -422,-1056}, -{ 655, 370, 18}, { -102, -185, -276}, { 755, 1578, 1335}, -{ -488, -603,-1418}, { 182, -93, 870}, { -73, -458, -348}, -{ 835, 862, 957}, { -282, -333, -746}, { 547, 839, 428}, -{ 273, -89, 13}, { 940, 1708, 2576}, { -418,-1084,-1758}, -{ -44, -358, 259}, { -497, -643, -560}, { 99, 557, 961}, -{ -421, -766, -917}, { 295, 326, 184}, { 175, 15, -626}, -{ 532, 878, 1981}, { -443, -768,-1275}, { 221, 156, 268}, -{ 39, -363, -505}, { 695, 772, 1140}, { -162, -459, -912}, -{ 709, 444, 658}, { 25, 303, -312}, { 1268, 1410, 1715}, -{ -297, -766,-1836}, { -263, -108, 1070}, { -406, -13, -129}, -{ 57, 438, 2734}, { -374, -487, -835}, { 304, 696, 164}, -{ 104, -235, 5}, { 1611, 1900, 1399}, { -229, -582,-1325}, -{ 405, 192, 817}, { -87, -438, 111}, { 1028, 1199, 993}, -{ 68, -175, -934}, { 1033, 1117, 451}, { 478, 200, -248}, -{ 2127, 2696, 2042}, { -835,-1323,-2131}, { -799, -692, 466}, -{ -812,-1032, -469}, { -622, 288, 920}, { -701, -841,-1070}, -{ -411, 512, 8}, { -390, -91, -744}, { -30, 1043, 1161}, -{ -822,-1148,-1156}, { -294, -46, 110}, { -411, -374, -678}, -{ 214, 531, 668}, { -406, -420,-1194}, { 487, 232, 303}, -{ -318, 91, -472}, { 123, 1232, 2445}, { -722, -952,-1495}, -{ -738, -675, 1332}, { -543, -606, -211}, { -95, -98, 1508}, -{ -549, -514,-1193}, { 473, 211, 73}, { -288, -112, -389}, -{ 537, 1332, 1258}, { -567, -755,-1545}, { 71, -283, 632}, -{ -170, -481, -493}, { 681, 1002, 817}, { -356, -331, -877}, -{ 419, 706, 346}, { 241, -34, -326}, { 377, 1950, 1883}, -{ -727,-1075,-1625}, { -233, -543, 116}, { -524, -806, -585}, -{ -73, 478, 729}, { -288, -925,-1143}, { 173, 447, -52}, -{ 68, -229, -606}, { 449, 529, 1797}, { -591, -875,-1363}, -{ 183, -144, 324}, { -103, -452, -666}, { 623, 488, 1176}, -{ -238, -511,-1004}, { 326, 552, 458}, { 136, 108, -319}, -{ 626, 1343, 1883}, { -490, -646,-1730}, { -186, -449, 984}, -{ -738, -76, -170}, { -550, 755, 2560}, { -496, -510, -947}, -{ 210, 694, -52}, { 84, -322, -199}, { 1090, 1625, 1224}, -{ -376, -603,-1396}, { 343, 74, 632}, { -175, -502, -32}, -{ 972, 1332, 734}, { 52, -295,-1113}, { 1065, 918, 160}, -{ 393, 107, -397}, { 1214, 2649, 1741}, { -632,-1201,-1891}, -{ -719, -277, 353}, { -651, -880, -122}, { -211, 209, 1338}, -{ -562, -714,-1059}, { -208, 388, 159}, { -320, -61, -551}, -{ 293, 1092, 1443}, { -648, -865,-1253}, { -49, -143, 305}, -{ -401, -227, -585}, { 561, 532, 927}, { -117, -443,-1188}, -{ 507, 436, 292}, { -79, 233, -458}, { 671, 1025, 2396}, -{ -633, -842,-1525}, { -308, -286, 640}, { -373, -621, -407}, -{ 418, 253, 1305}, { -315, -581,-1137}, { 572, 685, -281}, -{ 61, -68, -371}, { 991, 1101, 1498}, { -493, -683,-1362}, -{ -47, 164, 704}, { -256, -314, -268}, { 631, 949, 1052}, -{ -118, -348, -833}, { 68, 1180, 568}, { 152, 117, 34}, -{ 1113, 1902, 2239}, { -601, -959,-1706}, { -143, -489, 480}, -{ -332, -655, -574}, { 54, 353, 1192}, { -462, -652, -796}, -{ 150, 549, 112}, { 195, -111, -515}, { 679, 1108, 1647}, -{ -558, -749,-1217}, { -9, 272, 341}, { -53, -265, -535}, -{ 489, 843, 1298}, { -120, -482,-1032}, { 632, 543, 408}, -{ 179, 306, -526}, { 1124, 1464, 2244}, { -417, -786,-1562}, -{ -224, -384, 1364}, { -377, -459, -25}, { 385, 489, 2174}, -{ -332, -651, -829}, { 544, 553, 61}, { 22, -113, -89}, -{ 1128, 1725, 1524}, { -216, -373,-1653}, { 161, 316, 908}, -{ -165, -222, -67}, { 1362, 1175, 789}, { 73, -252, -767}, -{ 738, 932, 616}, { 362, 246, -126}, { 787, 2654, 3027}, -{ -691,-1106,-2190}, { -565, -588, 524}, { -590, -979, -490}, -{ -263, 397, 982}, { -577, -837, -945}, { -22, 435, -49}, -{ -190, -118, -629}, { -88, 1240, 1513}, { -636,-1051,-1019}, -{ -291, 189, 259}, { -257, -470, -629}, { 145, 945, 894}, -{ -326, -364,-1094}, { 543, 260, 630}, { -202, 189, -209}, -{ 357, 1379, 2091}, { -569,-1075,-1449}, { -714, -239, 919}, -{ -420, -705, -84}, { -109, -114, 2407}, { -413, -529,-1177}, -{ 482, 368, 131}, { -186, -72, -131}, { 861, 1255, 1220}, -{ -611, -658,-1341}, { 227, -121, 631}, { -176, -489, -218}, -{ 745, 1175, 957}, { -321, -148, -936}, { 671, 966, 216}, -{ 340, -3, -143}, { 469, 1848, 2437}, { -729, -961,-1683}, -{ -213, -254, 321}, { -511, -438, -521}, { -126, 725, 903}, -{ -340, -685,-1032}, { 316, 480, 20}, { 23, -89, -551}, -{ 353, 1051, 1789}, { -544, -757,-1364}, { 298, -25, 436}, -{ -100, -392, -519}, { 467, 754, 1078}, { -210, -398,-1078}, -{ 620, 658, 630}, { 33, 147, -178}, { 921, 1687, 1921}, -{ -325, -528,-1978}, { 2, -285, 910}, { -371, -490, -230}, -{ 0, 597, 2010}, { -496, -395, -834}, { 37, 945, 245}, -{ 181, -160, -144}, { 1481, 1373, 1357}, { -355, -601,-1270}, -{ 298, 322, 672}, { -193, -336, 77}, { 1089, 1533, 922}, -{ 177, -39,-1125}, { 996, 781, 536}, { 456, 366, -432}, -{ 1415, 2440, 2279}, { -466, -758,-2325}, { -303, -509, 387}, -{ -727, -557, 66}, { -145, 643, 1248}, { -544, -676, -916}, -{ -225, 862, 588}, { -152, 40, -533}, { 423, 1423, 1558}, -{ -572, -843,-1145}, { -128, 85, 461}, { -238, -257, -584}, -{ 605, 748, 861}, { 24, -202,-1409}, { 797, 487, 303}, -{ -181, 364, -182}, { 616, 1378, 2942}, { -494, -852,-1441}, -{ -292, 61, 812}, { -84, -723, -182}, { 555, 532, 1506}, -{ -365, -493,-1057}, { 822, 588, 11}, { -14, -18, -230}, -{ 1001, 1401, 1451}, { -474, -569,-1292}, { 302, 62, 1062}, -{ -70, -376, -222}, { 982, 974, 1149}, { -196, -234, -795}, -{ 479, 1098, 499}, { 362, 58, 70}, { 1147, 2069, 2857}, -{ -487, -878,-1824}, { 73, -288, 348}, { -358, -500, -508}, -{ 199, 721, 1242}, { -78, -697, -795}, { 361, 536, 196}, -{ 374, 110, -735}, { 847, 1051, 1896}, { -366, -713,-1182}, -{ 315, 320, 429}, { 72, -215, -450}, { 759, 886, 1363}, -{ -30, -428, -834}, { 861, 627, 796}, { 118, 468, -279}, -{ 1355, 1883, 1893}, { -188, -642,-1612}, { 63, -175, 1198}, -{ -418, -211, 51}, { 414, 587, 2601}, { -234, -557, -858}, -{ 424, 889, 222}, { 136, -101, 83}, { 1413, 2278, 1383}, -{ -84, -445,-1389}, { 414, 313, 1045}, { 29, -343, 65}, -{ 1552, 1647, 980}, { 183, -91, -829}, { 1273, 1413, 360}, -{ 553, 272, -107}, { 1587, 3149, 2603} -}; - -static const int16_t lsf_3_1[256][3] = { -{ 6, 82, -131}, { 154, -56, -735}, { 183, -65, -265}, -{ 9, -210, -361}, { 113, 718, 1817}, { 1010, 1214, 1573}, -{ 857, 1333, 2276}, { 827, 1568, 1933}, { 717, 1989, 2206}, -{ 838, 1172, 1823}, { 721, 1000, 2154}, { 286, 476, 1509}, -{ -247, -531, 230}, { 147, -82, 569}, { 26, -177, -944}, -{ -27, -273, 692}, { -164, -264, -183}, { 224, 790, 1039}, -{ 899, 946, 601}, { 485, 771, 1150}, { 524, 677, 903}, -{ -140, 375, 778}, { 410, 676, 429}, { 301, 530, 1009}, -{ 719, 646, 38}, { 226, 367, 40}, { 145, -45, -505}, -{ 290, 121, -121}, { 302, 127, 166}, { -124, -383, -956}, -{ -358, -455, -977}, { 715, 878, 894}, { 978, 923, 211}, -{ 477, 272, 64}, { 188, -78, 17}, { -143, -65, 38}, -{ 643, 586, 621}, { -134, -426, -651}, { 347, 545, 2820}, -{ 1188, 2726, 2442}, { 142, -80, 1735}, { 283, 130, 461}, -{ -262, -399,-1145}, { -411, 155, 430}, { 329, 375, 779}, -{ 53, -226, -139}, { -129, -236, 1682}, { 285, 744, 1327}, -{ 738, 697, 1664}, { 312, 409, 266}, { 325, 720, 135}, -{ 1, 221, 453}, { 8, 203, 145}, { 299, 640, 760}, -{ 29, 468, 638}, { 103, 429, 379}, { 420, 954, 932}, -{ 1326, 1210, 1258}, { 704, 1012, 1152}, { -166, -444, -266}, -{ -316, -130, -376}, { 191, 1151, 1904}, { -240, -543,-1260}, -{ -112, 268, 1207}, { 70, 1062, 1583}, { 278, 1360, 1574}, -{ -258, -272, -768}, { 19, 563, 2240}, { -3, -265, 135}, -{ -295, -591, -388}, { 140, 354, -206}, { -260, -504, -795}, -{ -433, -718,-1319}, { 109, 331, 962}, { -429, -87, 652}, -{ -296, 426, 1019}, { -239, 775, 851}, { 489, 1334, 1073}, -{ -334, -332, 25}, { 543, 1206, 1807}, { 326, 61, 727}, -{ 578, 849, 1405}, { -208, -277, 329}, { -152, 64, 669}, -{ -434, -678, -727}, { -454, -71, 251}, { 605, 480, 254}, -{ -482, 11, 996}, { -289, 395, 486}, { 722, 1049, 1440}, -{ -30, -316, -786}, { -106, -115, -619}, { 861, 1474, 1412}, -{ 1055, 1366, 1184}, { 812, 1237, 925}, { 42, -251, -576}, -{ 342, 141, -454}, { -168, -80, 1359}, { -342, -656,-1763}, -{ 100, 821, 725}, { 990, 747, 800}, { 332, 440, 568}, -{ 663, 379, 852}, { 112, 165, -369}, { 597, 910, 282}, -{ -8, 834, 1281}, { -352, 572, 695}, { 462, 2246, 1806}, -{ 345, 190, 1374}, { 416, 915, 2166}, { 168, -82, 280}, -{ -516, -446, 840}, { 47, 533, 44}, { -362, -711,-1143}, -{ 22, 193, 1472}, { -85, 233, 1813}, { -62, 579, 1504}, -{ 550, 944, 1749}, { 723, 650, 1148}, { 972, 884, 1395}, -{ -425, 643, 0}, { 1000, 952, 1098}, { 249, 1446, 672}, -{ -334, -87, 2172}, { -554, 1882, 2672}, { 140, 1826, 1853}, -{ 920, 1749, 2590}, { 1076, 1933, 2038}, { -137, -443,-1555}, -{ 1269, 1174, 468}, { -493, -122, 1521}, { -451, 1033, 1214}, -{ 482, 1695, 1118}, { 815, 649, 384}, { -446, -692, 107}, -{ -319, -605, -118}, { -207, -505, 525}, { -468, -12, 2736}, -{ 75, 1934, 1305}, { 880, 2358, 2267}, { 1285, 1575, 2004}, -{ -48, -304,-1186}, { -435, -461, -251}, { -366, -404, -547}, -{ -289, -605, -597}, { -538, -810, -165}, { -120, 3, 356}, -{ 639, 1241, 1502}, { 96, 177, 750}, { -435, -585,-1174}, -{ -356, 109, -79}, { -485, 288, 2005}, { 9, 1116, 731}, -{ 880, 2134, 946}, { -265, 1585, 1065}, { 1157, 1210, 843}, -{ -498, -668, 431}, { 374, 321, -229}, { 1440, 2101, 1381}, -{ 449, 461, 1155}, { -105, 39, -384}, { -263, 367, 182}, -{ -371, -660, 773}, { -188, 1151, 971}, { 1333, 1632, 1435}, -{ 774, 1267, 1221}, { -482, -832,-1489}, { -237, -210, 860}, -{ 890, 1615, 1064}, { 472, 1062, 1192}, { 185, 1077, 989}, -{ -568, -992,-1704}, { -449, -902,-2043}, { -142, -377, -458}, -{ -210, -554,-1029}, { -11, 1133, 2265}, { -329, -675, -893}, -{ -250, 657, 1187}, { 519, 1510, 1779}, { 520, 539, 1403}, -{ 527, 1421, 1302}, { -563, -871,-1248}, { -147, -463, 879}, -{ -76, 2334, 2840}, { 563, 2573, 2385}, { 632, 1926, 2920}, -{ 719, 2023, 1840}, { -545, -723, 1108}, { 129, -125, 884}, -{ 1417, 1632, 925}, { -94, 1566, 1751}, { -341, 1533, 1551}, -{ 591, 395, -274}, { -76, 981, 2831}, { 153, 2985, 1844}, -{ 1032, 2565, 2749}, { 1508, 2832, 1879}, { 791, 1199, 538}, -{ -190, -453, 1489}, { -278, -548, 1158}, { -245, 1941, 2044}, -{ 1024, 1560, 1650}, { 512, 253, 466}, { -62, -323, 1151}, -{ -473, -376, 507}, { -433, 1380, 2162}, { 899, 1943, 1445}, -{ 134, 704, 440}, { 460, 525, -28}, { -450, 279, 1338}, -{ 0, 971, 252}, { -445, -627, -991}, { -348, -602,-1424}, -{ 398, 712, 1656}, { -107, 314, -178}, { 93, 2226, 2238}, -{ 518, 849, 656}, { -462, -711, -447}, { 174, -34, 1191}, -{ -119, 42, 1005}, { -372, 274, 758}, { 1036, 2352, 1838}, -{ 675, 1724, 1498}, { 430, 1286, 2133}, { -129, -439, 0}, -{ -373, 800, 2144}, { 6, 1587, 2478}, { 478, 596, 2128}, -{ -428, -736, 1505}, { 385, 178, 980}, { 139, 449, 1225}, -{ -526, -842, -982}, { 145, 1554, 1242}, { 623, 1448, 656}, -{ 349, 1016, 1482}, { 31, -280, 415}, { -316, 724, 1641}, -{ 360, 1058, 556}, { -436, -358, 1201}, { -355, 1123, 1939}, -{ 401, 1584, 2248}, { -527,-1012, 355}, { 233, 238, 2233}, -{ -550, -897, -639}, { -365, -501, 1957}, { 389, 1860, 1621}, -{ 162, 1132, 1264}, { -237, 1174, 1390}, { -640, -411, 116}, -{ -228, 1694, 2298}, { 1639, 2186, 2267}, { 562, 1273, 2658}, -{ 323, 338, 1774}, { 578, 1107, 852}, { 22, 594, 934}, -{ -143, 718, 446} -}; - - -static const int16_t lsf_3_2[512][3] = { -{ 50, 71, -9}, { -338, -698,-1407}, { 102, -138, -820}, -{ -310, -469,-1147}, { 414, 67, -267}, { 1060, 814, 1441}, -{ 1548, 1360, 1272}, { 1754, 1895, 1661}, { 2019, 2133, 1820}, -{ 1808, 2318, 1845}, { 644, -93, 454}, { 858, 329, -136}, -{ 489, -258, -128}, { -198, -745, -41}, { -52, -265, -985}, -{ 346, 137, 479}, {-1741, -748, -684}, {-1163,-1725, -367}, -{ -895,-1145, -784}, { -488, -946, -968}, { -85, -390, -725}, -{ 215, -340, -171}, { 1020, 916, 1969}, { 564, 179, 746}, -{ 662, 977, 1734}, { 887, 622, 914}, { 939, 856, 1165}, -{ 309, 688, 803}, { 917, 161, 570}, { 118, -20, -283}, -{ -816, -42, 204}, {-1228, -325, -462}, { -963, -202, -143}, -{ -988, -484, -361}, { -702, -978, -477}, { -302, -790,-1188}, -{ -100, -786,-1088}, {-1054, -947,-1684}, { -202, -843, -782}, -{-1039,-1378, -901}, { -624, -110, -85}, { 356, 213, -10}, -{ -493, 364, 774}, { 425, 822, 479}, { -83, 557, 520}, -{ -992,-1560, -572}, { -603, -741, -26}, { -502, -638, -903}, -{ 209, 306, 147}, { -316, -593, -596}, { -85, -211, -225}, -{ -918, -529, 117}, { 233, -439, -738}, { 1101, 751, 633}, -{ 1457, 1716, 1511}, { 1765, 1457, 910}, { 1122, 1156, 849}, -{ 1354, 868, 470}, { -871,-1150,-1796}, { -871, -861, -992}, -{ -118, 155, 212}, {-1051, -849, -606}, {-1117,-1849,-2750}, -{-1019,-1427,-1869}, { 370, -184, -414}, { 959, 493, 104}, -{ 958, 1039, 543}, { 154, 653, 201}, { 1249, 507, 150}, -{ 663, 503, 230}, { 623, 777, 675}, { 659, 88, -110}, -{ 843, 244, 224}, { 382, 541, 302}, { 724, 433, 666}, -{ 1166, 734, 341}, { -138, 20, -397}, {-1183, -424, -46}, -{ -321, -352, -124}, { 1333, 1021, 1080}, { 262, 366, 723}, -{ 922, 283, -551}, { 31, -636, -611}, { -689, -697, -415}, -{ -952, -779, -201}, {-1329, -598, -359}, { -953,-1285, 166}, -{ 493, 305, 221}, { 846, 703, 610}, { 840, 936, 774}, -{ -723,-1324,-1261}, { -357,-1025,-1388}, {-1096,-1376, -365}, -{-1416,-1881, -608}, {-1798,-1727, -674}, { -545,-1173, -703}, -{ 678, 786, 148}, { -123, 696, 1288}, { 644, 350, -10}, -{ 414, 614, 15}, { 137, 344, -211}, { -814,-1512, -819}, -{ -391, -930, -588}, { 47, -591, -898}, { -909,-1097, -163}, -{-1272,-1167, -157}, {-1464,-1525, -389}, {-1274,-1188, -624}, -{ 671, 213, 454}, { 124, -274, -525}, { -729, -496, -152}, -{-1344, 122, 135}, {-2905, -589, -394}, {-1728, 441, -50}, -{ 1476, 904, 787}, { 316, 236, -440}, { -347, 217, 413}, -{ -911, -917, 121}, { -455, -932, 202}, { -92, -465, -375}, -{ 488, 390, 474}, { 876, 729, 316}, {-1815,-1312, -669}, -{ 87, 962, 432}, { 563, -249,-1058}, { 250, 285, 1105}, -{ 1141, 427, 696}, {-1038,-1664,-1582}, { -948, 346, 160}, -{ -309, -272, -858}, { 670, 624, 1250}, { -944, -408, -666}, -{ -606, -320, -384}, { -492, 230, 65}, { 334, -50, -16}, -{ -16, -690,-1397}, { 1791, 1716, 1399}, { 2478, 2063, 1404}, -{ 1245, 1471, 1426}, { -382,-1037, -2}, { 173, -398, 1145}, -{ 1491, 2024, 1801}, { 772, 1274, 1506}, { 1429, 1735, 2001}, -{ 1079, 1218, 1273}, {-1154,-1851,-1329}, { -808,-1133,-1096}, -{ -451,-1033,-1722}, { 65, 578, -84}, {-1476,-2434,-1778}, -{ -765,-1366, -494}, { -218, -594, -931}, { 337, -236, 562}, -{ 2357, 2662, 1938}, { 1489, 1276, 874}, { 189, 358, 374}, -{-1519,-2281,-2346}, { -967,-1271,-2095}, { -628,-1188,-1542}, -{ 1661, 1043, 546}, { 565, 1061, 732}, { -64, -836, -434}, -{ -436, -96, 203}, { 1078, 1216, 1636}, { 907, 1534, 986}, -{ 326, 965, 845}, { 142, -84, 197}, { 470, 2379, 1570}, -{ 1133, 470, 1214}, { 395, 1376, 1200}, { 1125, 1042, 348}, -{ -543,-1234, -376}, { -215, -181, 481}, {-1947,-1621, -210}, -{ -750,-1185, 390}, { 29, -399, 27}, { 820, 1236, 755}, -{ 695, 979, 409}, { -174, 1197, 1035}, { 912, 1356, 1846}, -{ -992,-1437, 484}, {-1485,-1700, 208}, { -412, 1204, 1432}, -{ -271, 896, 1144}, { -416, 1777, 1434}, {-1696,-2644, -204}, -{-1789,-1551, 1033}, {-1656,-1559, 1303}, {-1253,-1589, 1081}, -{ -669,-1095, -66}, { -682, 320, -345}, { 659, 305, 1069}, -{-1292, -804, -19}, {-1635,-1291, 29}, {-1683, -497, 71}, -{ -287, -7, -100}, { -494, -962, -237}, { 852, 1881, 1740}, -{-1217,-1387, 227}, { -660, 302, 373}, { 96, 1087, 1257}, -{-1074,-1669, 160}, { 485, 2076, 1798}, { -934, -220, 552}, -{ -596, -612, 237}, { 336, 1720, 879}, { 643, 629, 434}, -{ 1267, 522, 1633}, { 15, 244, -441}, { 1475, 717, 184}, -{ 1819, 1590, 1709}, { 988, 261, 937}, { 2093, 2345, 1520}, -{ 2139, 1858, 1606}, { -577, -579,-1203}, { -956, 135, -488}, -{ -464, 51, -338}, { -629, -348, -723}, { 1146, 2073, 1442}, -{ 2192, 1466, 911}, {-1444,-1572,-2278}, { 1400, 710, 1297}, -{ 1335, 633, 928}, { 1434, 2194, 2594}, { 2422, 2204, 1881}, -{ 982, 2242, 1854}, { 380, 792, 1145}, { -63, -539, 414}, -{ -252, -964, -314}, {-1261, -683, -780}, { -831, -526,-1005}, -{-1666,-1135, -424}, {-1611, -452, -299}, { 1268, 1048, 642}, -{ 1147, 853, 856}, { -675, -336, 139}, { 2268, 1343, 1418}, -{ 29, 768, 797}, {-1224, 423, 564}, {-1318,-1082, 245}, -{-1302, -812, 573}, {-1298,-1617, 646}, { -968, 834, 723}, -{ 993, 1652, 2027}, { -191, -817, 432}, { 662, 60, 198}, -{ 626, 997, 1330}, { 1648, 1963, 1289}, {-1597, -93, -45}, -{-1088, 37, -84}, { 1653, 2607, 2337}, { 1065, 2040, 2377}, -{ 1139, 2326, 2118}, { 859, 357, 1510}, { 664, 1227, 1099}, -{ 479, 1360, 912}, { 1897, 1754, 2019}, { 1168, 1909, 1784}, -{ 399, 34, 256}, { -593, -304,-1053}, { 547, 1694, 1407}, -{ 647, -99, -341}, { 1492, 1647, 1190}, { 38, -644, -212}, -{ 395, 846, 222}, { -704, -765, -716}, { -724,-1964,-2804}, -{ -150, 291, -82}, { 1233, 1459, 1007}, { -140, -155, 153}, -{ 439, 297, 1568}, {-1529, -410, -636}, { 1536, 455, -237}, -{-1328, -139, -260}, { 531, 554, 868}, { 269, 1264, 606}, -{ -233, 883, 463}, { 742, 600, -120}, { -73, 421, 212}, -{ -439, -58, 804}, {-1286,-1241, 728}, { 294, -490, 50}, -{ -591, -905,-1254}, { 42, -687, 147}, { -25, 273, 596}, -{ -311, 1213, 601}, { -754, 849, 584}, { 429, 607, 587}, -{ -602, -166, 461}, { -796, -823, 777}, { 1380, 910, 1755}, -{ 119, 1417, 972}, { -219, -880,-1596}, {-1049,-1010, 438}, -{ -713,-1379, 78}, { 0, -447,-1179}, {-1136,-1319,-1573}, -{ 2248, 1767, 1309}, { 946, 1583, 1432}, { 1150, 482, 436}, -{ -469,-1108, 618}, { -447, -966, 1088}, {-1252,-1515, -114}, -{-1104,-2008, -579}, { 210, 613, 497}, {-1975,-1437, 642}, -{-1269, -856, 1011}, {-1646,-1185, 1063}, {-1555, -672, 1204}, -{-1692,-1114, 623}, { -979,-1326,-1277}, { 539, -147, 894}, -{-1354, -897, -434}, { 888, 475, 428}, { 153, -384, 338}, -{-1492, -511, 359}, { -974,-1115, -470}, { 105, -550, 677}, -{ -937,-1145, 877}, { 380, -260, 210}, { 1685, 924, 1256}, -{ 1775, 1190, 1095}, { 1419, 631, 533}, { 627, 299, -347}, -{ -411, -534, 647}, { -650, 29, -595}, { -378,-1367, 1563}, -{ 1402, 1121, 1465}, { 1089, 1410, 648}, {-2096,-1090, -6}, -{ 311, -194, -869}, { -639, -831, 416}, {-1162,-1224, 1349}, -{-1247, -941, 1813}, {-2193,-1987, 453}, { -619,-1367, -956}, -{-1606,-1972,-1507}, {-1175,-1057,-1104}, { -377, 601, 201}, -{ 1876, 825, 374}, { -430,-1323, 29}, {-1397,-1249,-1331}, -{-1007,-1504, 960}, {-1401,-2009, 197}, {-1379,-1949, -236}, -{-1077, 123, 422}, { 615, 1269, 546}, { -306, 1526, 904}, -{ 1194, 1788, 1177}, { -626, -884,-1526}, { 199, 766, 1504}, -{-1065, 862, 197}, {-1034,-1773, -887}, { -800, 145, 599}, -{-1134, -519, 626}, {-1205,-1926, 500}, { -910,-1041,-1395}, -{-1476,-1567, -969}, { -523, 842, 34}, { 1794, 646, 862}, -{-1207,-1888,-1002}, { -78, -9, -672}, { 1044, 759, 80}, -{ -600, 1139, 1019}, { 57, 2000, 1422}, { -833, 1414, 1121}, -{-1202, 1630, 1260}, { -461, 1420, 1244}, { 1537, 975, 253}, -{ -283, 324, -359}, { 599, -195, 106}, { 588, 62, -587}, -{ -757, 645, 205}, { 51, 1201, 758}, {-1209, 673, -390}, -{ -624, 1581, 941}, { -151, 1023, 735}, { 2820, 1301, 690}, -{ -302, 524, -99}, { -900,-1588,-1189}, { 1084, 251, 238}, -{ 2014, 1792, 1010}, { 1245, 1633, 1741}, {-1227,-1540,-1208}, -{ -621, 456, -109}, { 40, -65, 788}, { -805, -699,-1350}, -{ -583, 904, 832}, { -801, 532, 594}, { 1972, 1408, 1351}, -{-1177,-1880,-2114}, { -773, 568, 948}, {-1015, 1079, 1260}, -{-1111, 482, -130}, { 1778, 1044, 780}, {-1491, 245, 912}, -{ -316,-1141, -917}, { -536,-1442,-2346}, { -785,-1546,-1988}, -{-2003, 257, 909}, {-1849, -633,-1209}, {-1538,-1918,-1054}, -{ 1606, 2239, 1576}, { -567,-1500,-1544}, {-1279, 195, 1369}, -{ -817, 293, 1219}, { -525, 630, 1197}, {-1698,-2425,-1840}, -{ -303, 731, 747}, {-1169, -251, 269}, { -950, -75, 1684}, -{-1182, -453, 1005}, {-1599, 585, 378}, {-2075, -571, -427}, -{ -529,-1159,-1171}, { -283, -205, -564}, { -796, 1246, 717}, -{ 2277, 927, 539}, { -454, 559, 440}, { -717, 1460, 1615}, -{-1030, 1052, 1610}, {-1169, -138, 847}, { 226, 39, -612}, -{-1251, -106, -729}, { -651, 968, 1302}, { -714, -636, 1727}, -{ 353, 1069, 410}, { -798, -156, 1099}, { -574, 918, 446}, -{-1310, 1012, 466}, { 1408, 1591, 765}, { 1429, 1380, 1757}, -{ 1949, 1956, 2378}, { 1578, 2047, 2148}, { 916, 98, -7}, -{ 1893, 1418, 2141}, { 348, 1405, 1579}, { 152, 1134, 1801}, -{ -267, 154, 1395}, {-1166, 469, 1054}, {-1142, -405,-1073}, -{-1341,-2264,-1581}, { -364, 869, 1706}, {-1162, 549, 1550}, -{-1225,-1932,-1666}, {-1485,-1977,-2055}, {-1727, -906, -98}, -{-1897, 233, 1492}, { 892, 108, -331}, {-1728,-1170,-1700}, -{-1060, 1980, 1790}, {-1070,-1741,-1909}, { -11, 1539, 1317}, -{-1600, 94, 497}, { 421, 443, -197}, {-1578, -349, -994}, -{ -599, -539, 1140}, { -965,-1419, -129}, {-1341, 175, -447}, -{ -375, 1311, 2055}, { -371, -650, -307}, {-1073, 605, 365}, -{-2057, -113, 430}, { 652, 914, 967}, {-1012,-1586,-2323}, -{ 1505, 1248, 559}, { 262, -486, -401}, {-1727, 1342, 1546}, -{ 50, 56, 432}, { -330, 119, -604}, {-1517,-1080, -810}, -{ 946, 1127, 1055}, {-1400,-1703,-1712}, {-1270, -704,-1317}, -{ 807, 1821, 1143}, { 2760, 1606, 2171}, { 1120, 409, -150}, -{ -147, 404, 959}, { 2439, 1911, 2189}, { -906, -141, -866}, -{ -904, -142, -458}, { -557, -708,-1679}, { -830,-1431,-1583}, -{-1842,-1346,-1086}, {-1604, -272, 915}, {-1196, 772, 1056}, -{ -638,-1234,-1897}, { -500, -81, -822}, {-1289,-1613, -735}, -{ -117, 785, 168}, {-1090, 1133, 922}, {-1096, -746, 1384}, -{ 287, -547,-1063}, {-1376,-2201,-1204}, {-2176,-1570,-1757}, -{-1511,-2241, -771}, {-1737, 1099, 830}, {-1588, 724, 1243}, -{-1542, 693, 805}, {-1690, -240, 1665}, {-1700, -4, -668}, -{ 2149, 816, 1042}, { -818,-1841, 22}, { -764, -507, 449}, -{-1151, -617, 289}, { -843,-1596, -240}, { 498, -234, -657}, -{ -752, 480, 1678}, { -319, -481, 193}, { -811, 171, -119}, -{-2128, -202, -848}, { 1717, 1140, 1700} -}; - -static const int16_t lsf_3_3[512][4] = { -{ 67, -17, 66, -12}, {-1690, -581, -104, -272}, {-1076,-1186,-1845, -376}, -{-1140, -926, -420, -58}, { -259, -656,-1134, -553}, { 1788, 1227, 455, 129}, -{ 462, 441, -240, -528}, { 840, 514, 130, -75}, { 1114, 623, 153, 216}, -{ 1068, 564, -6, -276}, { 1119, 727, 190, -68}, { 704, 306, 119, -264}, -{ 329, 61, -100, 156}, { 364, 123, 183, -208}, { -171, -123, 220, -65}, -{ -306, -62, 402, 17}, { -660, -938, -266, 0}, { 385, 235, 276, 285}, -{ 320, 268, -336, -200}, { -724, 17, -84, 381}, { -544, 429, 494, 519}, -{ -117, 288, 304, 329}, { 643, 157, 701, 508}, { 1200, 625, 796, 608}, -{ 998, 421, 492, 632}, { 1204, 780, 446, 132}, { 1257, 844, 547, 449}, -{ 829, 658, 541, 470}, { 1132, 1258, 918, 639}, { 547, 51, 423, 279}, -{ 9, 392, 83, 94}, { 542, 543, 229, -147}, { -198, 129, 194, -185}, -{ -863,-1321, -302, 30}, { -597, -629, -19, 114}, { -900,-1081, 466, 353}, -{-1483,-1573, 15, -143}, {-1708,-2059, -751, 196}, {-1876,-2067, -642, -258}, -{-2335,-1470, -450, -564}, { -584, -186, -872, -414}, {-1805, -988,-1125,-1310}, -{ -726,-1129, 28, 169}, {-1039, -864, -718, -246}, { 484, 36, -233, -49}, -{ 265, 67, 289, 467}, { 178, 543, 810, 540}, { 84, 282, 672, 703}, -{ -975, -777, 129, 287}, { -938, -227, 955, 595}, {-1617, -289, 836, 649}, -{-1847, -215, 1106, 718}, {-2034,-1085, 650, 440}, {-2101, -529, 907, 575}, -{-2011, -336, 670, 204}, {-2389, -692, 360, 137}, {-2156,-2204, -9, 280}, -{ -266, 119, 39, 193}, { 78, -59, -120, 226}, { -975, -858, -781,-1095}, -{ -619, -413, -451, -842}, {-1216,-1321, -813, -883}, {-1376,-1615, -394, -428}, -{ -737,-1113, -549, -790}, { -880, -975, -967, -642}, { -985, -886,-1273,-1361}, -{ -473, -804,-1401,-1407}, { 160, -265, -919, -275}, { -248, -250, -718, -380}, -{ 97, -103, -375, -229}, { -415, -193, -135, -555}, { 628, 361, 119, 216}, -{ 579, 364, 391, 209}, { 634, 522, -154, -148}, { 526, 389, 170, 33}, -{ 105, 267, 64, 380}, {-1503,-1000, -30, -369}, {-1070, 58, 647, 223}, -{-1520, -291, 621, 307}, {-1531, 156, 762, 404}, {-2029, 141, 734, 499}, -{-1849, -650, 306, 512}, { -187, -104, -59, 438}, { 134, -230, 156, -186}, -{ -61, -260, -16, 10}, { -569, -3, -421, -297}, {-1725, -521, -346, 178}, -{-1362, -59, -44, 157}, {-2146, -461, -470, -349}, {-2170, -1, -369, -121}, -{-1579, -373, -900,-1015}, {-1117, -591, -613, -784}, { -561, 122, -75, -449}, -{ -4, -171, -123, -372}, { 192, 168, -76, -132}, { 252, -107, 340, 210}, -{ 392, 509, 272, 181}, { -109, 145, 218, 119}, { -416, -263, 485, 265}, -{ -181, -8, -286, 226}, { -244, -218, 69, -290}, { -158, 191, -1, -64}, -{ -592, -90, 213, -96}, { 255, 435, 178, -80}, { -369, -18, -33, -80}, -{ -42, 415, 140, -222}, { 1143, 651, 649, 329}, { 767, 556, 249, 235}, -{ 948, 413, 442, 279}, { 141, 339, 356, 557}, { -470, -170, 99, 237}, -{ -569, -800, 352, 565}, { 282, 473, 470, 332}, { -199, -690,-1284, -917}, -{ -193, -426, -800,-1122}, { -26, -371, -490, -193}, { 637, 595, 519, 330}, -{ 408, -115, 79, 12}, { 477, 87, -103, -376}, { -666, -347, -277, -291}, -{ -510, -481, 169, 297}, { -829, -738, -205, -171}, { -320, -540, 328, 283}, -{ -859, -958, 442, -2}, { 556, 686, 130, 56}, { 1383, 1012, 755, 427}, -{ 612, 741, 628, 553}, { -339, -796, 134, 277}, { -633,-1085, -2, -246}, -{ -880,-1035,-1607,-1064}, { -994, -474,-1138, -488}, { -414, -795, 73, -206}, -{ -8, -139, 439, 204}, { -176, -578, 23, 131}, { -269, -757, -191, 245}, -{ -109, -338, 112, 316}, { 120, -406, -118, 611}, { -180, -186, -645, 115}, -{ -173, 34, -518, -489}, { -151, 61, -583, -844}, { 220, -138, -681,-1020}, -{ 391, -17, -598, -321}, { 157, -295, 129, 155}, { -926, -875, -987, 285}, -{ 241, -83, -125, -125}, { 620, 597, 432, 92}, { 393, 78, 409, 61}, -{ -393, -739, -413, -748}, { 83, 54, 361, 27}, {-1084, 130, -337, -694}, -{-1565, 297, 318, -19}, {-1873, 36, 51, -317}, {-2323, -246, 231, -84}, -{-2306, -783, 40, -179}, {-2233, -930, -474, -462}, { -754, -86, -288, -626}, -{-2411, -455, -63, 171}, {-1099,-1094, -26, -143}, {-1193, -455, -406, -381}, -{ -605, -210, -96, -51}, { -580, -476, -276, -15}, {-1195, -634,-1203, -881}, -{ -378, -221, -669, -952}, { 594, 178, -403, -676}, { 763, 327, 601, 290}, -{ 172, 300, 203, 157}, { -56, -336, 356, 24}, { -228, -296, -259, -29}, -{ -186, 263, 416, 14}, { -353, 373, -12, -216}, { 257, 96, 174, 57}, -{-1526, -616, -954, -499}, { -497, -152, -333, 125}, { 105, 200, 179, -97}, -{ -331, -224, 765, 697}, { 760, 256, 301, 59}, { 455, -85, 204, 288}, -{ -514, 240, 251, -109}, { 256, 417, -34, -413}, { 101, 430, 384, 156}, -{ -31, -10, 206, 426}, { 589, 145, 143, 71}, { 808, 906, 333, 349}, -{ 986, 938, 589, 331}, { 1300, 824, 187, 509}, { 1062, 653, 379, 466}, -{ 1462, 937, 401, 274}, { 787, 861, 265, 2}, { 609, 553, 28, 305}, -{ 926, 340, 106, 386}, { 241, -267, -147, 225}, { -178, -534, 347, 502}, -{ -643, -381, 397, 30}, { -651, -733, -435, 398}, { -407, -726, -484, -248}, -{ -789, -914, -438, -476}, { -498, -390, 75, -295}, { -964, -590, -606, 150}, -{ -121, -49, -155, -78}, { 935, 550, 389, 38}, { -321, 127, 424, 315}, -{ -285, -113, 283, 259}, { 658, 203, 322, 486}, { 903, 505, 748, 417}, -{ 611, 423, 555, 512}, { 239, -83, -578, -19}, { -339, -731, 349, 13}, -{ -934,-1399, -114, -360}, { 107, 692, 182, 90}, {-1243,-1538,-1551, -725}, -{ -568, -903,-1363, -525}, { -517, -853, -861,-1004}, { -168, -690, -835, 63}, -{ -137, -556, -547, 144}, { -286, -817, 485, 319}, { -147, -408, 526, 246}, -{ -347, -434, 297, -28}, { -290, -471,-1110,-1285}, { -460, -359, -988, -794}, -{ 1347, 1299, 690, 523}, { 1216, 1068, 1094, 757}, { 825, 1140, 752, 494}, -{ 1252, 1365, 1195, 898}, { 521, 1053, 532, 432}, { -334, -216, -313, -263}, -{ -160, 52, -472, -155}, { 127, 136, -380, 44}, { 851, 410, -162, -489}, -{ 123, -255, -796, -667}, { 1090, 917, 789, 493}, { 1397, 1197, 558, 202}, -{ -51, -118, -342, -701}, { 83, 108, -42, -441}, { 61, 95, 287, 256}, -{ -27, 89, 524, 531}, { 351, 227, 592, 545}, { 697, 155, -164, 307}, -{ 638, 274, -489, -50}, { 754, 240, -166, -124}, { -116, -579,-1212, -63}, -{ 190, -295,-1040,-1296}, { 147, -376, -177, -113}, { 841, 1241, 1051, 668}, -{ 2, 293, 551, 304}, {-1096, -953, -248, 376}, { -750, -965, 87, 516}, -{ -275, -516, 689, 391}, { -379, -643, 876, 594}, { -390,-1013, -645, 573}, -{ -107, -568, -689, -826}, {-1025, -27, -328, -203}, { 861, 749, 548, 233}, -{-1660,-1043, 451, 108}, { -660, -620, 430, 236}, { 21, -396,-1158, -631}, -{ 1372, 1298, 967, 577}, { 1125, 1125, 589, 454}, { -323, -865, -467, 153}, -{ -468, -699, -804, -509}, { -392, -718, -204, -35}, { -603,-1093, -567, -162}, -{ -505,-1004, -102, 350}, { 219, 224, 423, 252}, { 395, 591, 608, 363}, -{ -746, -96, 373, 172}, { 171, 295, 714, 339}, { 233, 77, 107, 277}, -{ 157, 153, -499, -356}, { 1547, 1073, 576, 494}, { -292, -339, -504, -592}, -{ -903, -72, -619, -481}, {-1594,-1117, -567, -254}, { -793, -507, -564, -291}, -{ -492, -532, 502, 560}, { -382, 427, 600, 230}, { -227, 477, 251, 75}, -{ 285, 842, 813, 476}, {-1310,-1333, 186, 377}, { -587, -917, 643, 381}, -{-1186, -553, 411, 82}, {-1127, -820, -174, -540}, { -604, 119, 543, 205}, -{ -380, 657, 909, 567}, { 112, -298, -374, 114}, { -857, -251, 56, 159}, -{ 401, 345, -34, -140}, { -111, -607, 41, 614}, { 355, -114, -77, 474}, -{ 578, 56, 1450, 924}, { 1098, 1420, 741, 400}, { 246, 22, 588, 313}, -{ -121, 327, 831, 472}, {-1138, -608, 856, 552}, {-1241,-1072, 638, 600}, -{ -358, 254, -333, -303}, { -646, 739, 358, 74}, { 1226, 1671, 1221, 849}, -{ 2241, 1624, 983, 636}, { 1841, 1477, 749, 384}, { 350, 263, 87, 128}, -{-1902, -941, -144, -64}, {-1734, -255, 288, -31}, {-2644,-1238, 366, 235}, -{-1643,-1092,-1344, -304}, { -541,-1075,-1116, 123}, {-1178, -252, -816, -180}, -{-1016, 533, 565, 233}, { -487, -430, -188, 334}, { 867, 1236, 534, 171}, -{-1590,-1607, 635, 630}, {-2196, 310, 924, 412}, {-2358, -328, 956, 529}, -{-2639, -377, 630, 278}, {-2602, 317, 799, 299}, {-2406, 133, 340, 31}, -{-2156,-1468, 131, 125}, {-1184, -490, -139, 46}, { -744, 447, 891, 564}, -{ 67, -451, 646, 604}, { -553, -429, -876, 396}, { 162, -66, 1305, 915}, -{ 479, 579, 1088, 794}, { 450, 278, 566, 324}, {-1057, -154, 148, -177}, -{-2545, 168, 1070, 592}, {-2351, -42, 819, 345}, {-2344, -707, 721, 250}, -{-2175,-1497, -309, 122}, { -78, -73, 120, 173}, { -4, 262, -263, -261}, -{ -431, -64, -405, -732}, {-2609, 116, -83, -193}, {-1525, -944, -477, -725}, -{ -508, 307, 170, 172}, { 832, 417, 832, 686}, { -225, 177, 894, 818}, -{ -482, -389, 1279, 1039}, { -383, 201, -350, 40}, { 730, 635, 226, 526}, -{ 503, 462, 338, 398}, { 535, 714, 40, -282}, { 1482, 1471, 1085, 731}, -{ 1561, 1072, 909, 693}, { 1419, 1282, 889, 879}, { 1153, 728, 1186, 840}, -{ -226, 1130, 949, 689}, { -494, -986,-1556, -128}, { -568, -721, -713, -26}, -{ 317, 524, 70, 135}, { -405, -865,-1766, -652}, { -174, -801, 885, 773}, -{ -153, -91, 1099, 751}, { -506,-1149, 853, 646}, { 241, 782, 519, 539}, -{ 1853, 1700, 1101, 684}, {-1249,-1486, -464, 188}, { -893,-1409,-1312, -341}, -{ -135, 438, -175, 18}, { 1111, 976, 319, 208}, {-1430,-1768, 83, 458}, -{ -530,-1000, 307, 129}, { -840, -15, -29, -356}, { -911, -924,-1147, -242}, -{ -119, -528, 127, -133}, { -761, -765, 190, -83}, { -315, 895, 522, 231}, -{ -222, 102, -63, -428}, { 316, 699, 379, 70}, { 25, 716, 314, -108}, -{ 507, 874, 566, 238}, { 108, 941, 519, 195}, { 425, -60, -427, 257}, -{ 139, -103, -630, 446}, { 334, 370, 412, 48}, { -172, -690, -283, 557}, -{ 187, -286, 158, 483}, { 140, 270, -344, -631}, { 924, 579, -116, 132}, -{ 142, 466, -68, -64}, { 230, -145, -302, -542}, { -803, -912, 1018, 737}, -{ -773, 1015, 630, 297}, {-2596, 95, 445, 336}, {-2122, 491, 510, 191}, -{-1253, 161, -2, -324}, {-1450, -633, -712, -105}, { -842, -254, -411, 100}, -{ -640, -290, 1010, 763}, { -650, 313, 1169, 730}, { 140, 505, 1030, 766}, -{ 772, 287, 1067, 823}, { 495, 749, 305, 323}, { -164, 462, 78, 399}, -{ -342, -874, 69, 597}, { -16, 620, 621, 337}, { -138, -444, -265, 218}, -{ 84, -450, 953, 666}, { -222, -803, 541, 604}, { -921,-1376, 244, 116}, -{ -841, -723, 630, 588}, { 140, 663, 294, 368}, { 935, 1046, 881, 759}, -{ 1746, 1464, 916, 628}, { 436, 963, 281, 1}, { -119, 74, 542, 213}, -{ 1, -567, 301, 241}, { 260, 435, 222, 396}, { 936, 957, 1108, 703}, -{ 510, 506, 808, 478}, { 601, 694, 960, 620}, { 972, 741, 980, 600}, -{ 834, 717, 767, 684}, { 643, 972, 935, 638}, { 501, 661, 720, 851}, -{ -105, -632, -303, -117}, { -429, 130, 789, 442}, { -522, -188, 704, 373}, -{ -759, 42, 814, 523}, { -531,-1137, 373, 578}, { -682,-1203, -455, 285}, -{-1163,-1577,-1098, 44}, { 81, -82, 712, 363}, { 477, 246, 954, 622}, -{ 1604, 1622, 1277, 891}, { 1409, 859, 924, 892}, { 774, 1041, 947, 1142}, -{ 40, -546, -75, 288}, { -616, -106, -697, -26}, { -169, -160, -891, -739}, -{ -279, -384,-1029, -350}, { 1781, 1308, 1046, 816}, { 1580, 1533, 1472, 1178}, -{ 1505, 1076, 1216, 899}, { 890, 904, 564, 654}, { 920, 692, 1021, 856}, -{ -493, 132, 177, 505}, { 71, 195, -28, 97}, { 456, 351, -164, 88}, -{ 439, 278, -40, 350}, { 1395, 949, 234, -95}, { -805, -472, 38, -163}, -{ 367, -98, 489, 523}, { 1025, 1178, 1212, 906}, { 319, 1314, 814, 461}, -{ -123, -543, -804, 447}, { -748, -324, -897,-1127}, { -737, -501, -789, -713}, -{ 715, 777, 1239, 922}, { 1949, 1939, 1368, 865}, { 730, 880, 758, 388}, -{ -871, 454, 17, -251}, { -381, -810,-1583, 239}, { -521, -966, -792, 259}, -{ -890,-1358, -770, -73}, { 166, 349, -212, 323}, { -840, -301, 473, 435}, -{ -679, -464, 728, 351}, { -156, -199, 667, 432}, { 29, -252, 415, 480}, -{ -731, -379, 145, 559}, { -528, -631,-1158, -159}, { 445, 273, 123, 639}, -{ 373, -126, 800, 568}, { 84, -162, 720, 712}, { -830, -536, -185, 222}, -{ 408, 452, 501, 771}, { -897,-1355, -67, 442}, { -792,-1406, 566, 602}, -{ 167, -326, 509, 330}, { -95, -626, -730, -344}, { 1668, 1217, 779, 455}, -{ 1316, 828, 584, 719}, { 404, -31, 1013, 789}, { 89, 107, 891, 549}, -{ 871, 1581, 917, 671}, { 866, 1479, 1289, 854}, { 391, 1068, 1122, 812}, -{ 78, -562, 345, 563}, { 429, -103, 417, 787}, { -122, -437, 411, 788}, -{ -913, -417, 602, 754}, { -226, -16, 151, 760}, { -700, 118, -104, -14}, -{-1128, 48, 284, 393}, { -390, -419, -639, -116}, { -910, 306, 316, -13}, -{ 1207, 984, 821, 669}, {-1195, -693, 140, -213}, { -884, -416, -199, -558}, -{ -616, 245, -404, -664}, { 262, 56, -617, -724}, { -85, -491, -320, -656}, -{ -570, -831, -129, -528}, {-1506, -63, -367, -385}, { -358, -321, 4, 51}, -{ -366, -214, 319, 511}, { 146, 671, -17, -291}, { -110, 464, -139, -496}, -{ -202, 220, -312, -631}, { -660, -73, -655, -820}, { -662, -653,-1288, -857}, -{ -430, -953, -959, -264}, { -49, -468, -72, -381}, { -350, -563, -193, -407}, -{ 55, -408, -803, 11}, { -309, 649, 188, -198}, { -512, 461, -79, -458}, -{-1318, -263, -134, -523}, {-1657, -435, -495, -765}, { 57, -347, -414, 434}, -{-1141, -242, -664, -857}, { 34, -68, -707, -338} -}; - -static const int16_t lsf_5_1[128][4] = { -{ -451,-1065, -529,-1305}, { -450, -756, -497, -863}, { -384, -619, -413, -669}, -{ -317, -538, -331, -556}, { -414, -508, -424, -378}, { -274, -324, -434, -614}, -{ -226, -500, -232, -514}, { -263, -377, -298, -410}, { -151, -710, -174, -818}, -{ -149, -412, -156, -429}, { -288, -462, -186, -203}, { -170, -302, -191, -321}, -{ -131, -147, -297, -395}, { -228, -214, -245, -192}, { -67, -316, -71, -327}, -{ -104, -205, -94, -183}, { -143, -38, -193, -95}, { 16, -76, -124, -248}, -{ 23, -237, 24, -244}, { 18, -136, 44, -111}, { -33, -24, -25, 0}, -{ 149, 19, 23, -143}, { 158, -169, 174, -181}, { 133, -55, 165, -26}, -{ 111, 84, 98, 75}, { 87, 183, -115, -11}, { -8, 130, 11, 170}, -{ 254, 77, 205, 17}, { 183, 112, 262, 194}, { 202, 287, 95, 189}, -{ -42, -105, 234, 179}, { 39, 186, 163, 345}, { 332, 199, 299, 161}, -{ -54, 285, -78, 281}, { -133, 141, -182, 111}, { 249, 341, 271, 364}, -{ 93, 403, 75, 391}, { 92, 510, -138, 220}, { -185, -29, -34, 361}, -{ -115, 320, 3, 554}, { 99, 286, 218, 591}, { -245, 406, -268, 453}, -{ 0, 580, 25, 606}, { 275, 532, 148, 450}, { -73, 739, -285, 518}, -{ -288, 94, -203, 674}, { -140, -74, 205, 714}, { -114, 299, 176, 923}, -{ 182, 557, 240, 705}, { -16, 513, 485, 593}, { 293, 384, 451, 617}, -{ -38, 50, 563, 529}, { 303, 209, 459, 363}, { 433, 452, 450, 454}, -{ 367, 606, 477, 741}, { 432, 353, 368, 267}, { 361, 716, 273, 583}, -{ 453, 166, 510, 172}, { 201, 629, 274, 191}, { 568, 639, 302, 298}, -{ 634, 387, 643, 350}, { 587, 560, 612, 565}, { 600, 788, 487, 672}, -{ 512, 1015, 321, 333}, { 357, 854, -125, 413}, { 474, 712, 17, -151}, -{ 564, 285, 270, -241}, { 971, 889, 489, 220}, { 510, 896, 549, 924}, -{ 327, 825, 290, 911}, { 540, 1108, 158, 805}, { 199, 957, 511, 730}, -{ 100, 874, 13, 791}, { 435, 632, 676, 972}, { 249, 900, 467, 1218}, -{ 781, 1074, 585, 785}, { -23, 669, 267, 1043}, { 619, 1084, 615, 1145}, -{ 622, 905, 916, 1049}, { 80, 331, 584, 1075}, { 89, 639, 988, 961}, -{ 770, 720, 798, 699}, { 492, 447, 899, 627}, { 271, 1188, 725, 1333}, -{ 87, 603, 832, 1603}, { 616, 1127, 890, 1505}, { 1000, 1156, 866, 1009}, -{ 995, 827, 1149, 858}, { 817, 1450, 773, 1320}, { 500, 1389, 312, 1153}, -{ -20, 1084, 64, 1283}, { 2, 1172, 399, 1869}, { 514, 1706, 502, 1636}, -{ 886, 1522, 416, 600}, { 1131, 1350, 1275, 1390}, { 889, 1795, 914, 1766}, -{ 227, 1183, 1250, 1826}, { 505, 1854, 919, 2353}, { -199, 431, 152, 1735}, -{ -213, -28, 392, 1334}, { -153, -52, 978, 1151}, { -323, -400, 813, 1703}, -{ -136, 84, 1449, 2015}, { -331, -143, -137, 1192}, { -256, 534, -157, 1031}, -{ -307, -439, 542, 731}, { -329, -420, -97, 616}, { -362, -168, -322, 366}, -{ -247, -110, -211, 89}, { -196, -309, 20, 59}, { -364, -463, -286, 89}, -{ -336, 175, -432, 141}, { -379, -190, -434, -196}, { -79, 150, -278, -227}, -{ -280, 166, -555, -422}, { -155, 541, -366, 54}, { -29, -83, -301, -774}, -{ 186, 628, -397, -264}, { 242, 293, -197, -585}, { 124, 410, 53, -133}, -{ 10, 340, -570,-1065}, { 65, -446, 68, -493}, { 383, 937, -357, -711}, -{ -359, -250, -677,-1068}, { 292, -26, 363, 6}, { 607, 1313, -127, -10}, -{ 1513, 1886, 713, 972}, { 1469, 2181, 1443, 2016} -}; - -static const int16_t lsf_5_2[256][4] = { -{-1631,-1600,-1796,-2290}, {-1027,-1770,-1100,-2025}, {-1277,-1388,-1367,-1534}, -{ -947,-1461, -972,-1524}, { -999,-1222,-1020,-1172}, { -815, -987, -992,-1371}, -{-1216,-1006,-1289,-1094}, { -744,-1268, -755,-1293}, { -862, -923, -905, -984}, -{ -678,-1051, -685,-1050}, {-1087, -985,-1062, -679}, { -989, -641,-1127, -976}, -{ -762, -654, -890, -806}, { -833,-1091, -706, -629}, { -621, -806, -640, -812}, -{ -775, -634, -779, -543}, { -996, -565,-1075, -580}, { -546, -611, -572, -619}, -{ -760, -290, -879, -526}, { -823, -462, -795, -253}, { -553, -415, -589, -439}, -{ -533, -340, -692, -935}, { -505, -772, -702,-1131}, { -263, -306, -971, -483}, -{ -445, -74, -555, -548}, { -614, -129, -693, -234}, { -396, -246, -475, -250}, -{ -265, -404, -376, -514}, { -417, -510, -300, -313}, { -334, -664, -463, -814}, -{ -386, -704, -337, -615}, { -234, -201, -233, -239}, { -167, -567, -203, -619}, -{ -147, -415, -115, -352}, { -166, -750, -171, -761}, { -270, -879, -264, -903}, -{ -367, -744, 43, -475}, { 14, -653, 43, -670}, { 11, -448, -59, -521}, -{ -126, -119, -155, -613}, { -42, -863, -27, -931}, { 136, -483, 183, -468}, -{ 55, -298, 55, -304}, { 313, -609, 313, -720}, { 322, -167, 100, -541}, -{ -3, -119, -111, -187}, { 233, -236, 260, -234}, { 26, -165, 134, -45}, -{ -40, -549, 360, -203}, { 378, -388, 450, -383}, { 275, 20, 182, -103}, -{ 246, -111, 431, 37}, { 462, -146, 487, -157}, { -284, -59, 503, -184}, -{ 24, 53, -3, 54}, { 122, 259, 333, 66}, { 484, 104, 436, 68}, -{ 195, 116, 190, 206}, { 269, -9, 482, 352}, { 382, 285, 399, 277}, -{ 452, 256, 69, 186}, { 13, 297, -13, 259}, { -95, 30, 56, 394}, -{ 196, 425, 205, 456}, { 281, 577, 15, 191}, { 375, 290, 407, 576}, -{ -56, 227, 544, 405}, { 0, 549, -92, 528}, { -229, 351, -245, 338}, -{ -362, 435, 167, 527}, { -75, 302, 91, 824}, { 129, 599, 496, 679}, -{ 186, 749, 153, 737}, { -281, 600, -348, 615}, { -236, 769, 41, 881}, -{ 38, 890, -220, 841}, { -357, 883, -393, 903}, { -634, 474, -444, 850}, -{ -175, 678, -493, 242}, { -519, 785, -714, 582}, { -541, 366, -543, 434}, -{ -597, 500, -765, 222}, { -702, 917, -743, 962}, { -869, 501, -899, 548}, -{ -379, 200, -435, 157}, { -819, 214, -861, 157}, { -614, 40, -632, 94}, -{ -883, -54, -741, 516}, { -501, 298, -614, -171}, { -870, -161, -865, -23}, -{ -818, 93,-1015, -267}, { -662, -359, -549, 2}, { -442, -121, -377, 0}, -{ -227, 33, -414, -126}, { -129, 212, -934, 34}, {-1082, -282,-1119, -268}, -{ -710, -825, -420, -191}, {-1076, -928, -917, -93}, { -628, -358, 97, 7}, -{ -206, -393, -101, 24}, { -203, 38, -168, 83}, { -599, -423, -279, 426}, -{ -700, 118, -75, 206}, { -981, -673, -680, 417}, { -367, 37, -279, 474}, -{ -129, -318, 319, 296}, { -626, -39, 343, 602}, { -696, -39, -303, 940}, -{ 104, 233, -380, 137}, { -36, 269, -75, -214}, { 120, 43, -529, -477}, -{ 459, 164, -202, -229}, { -49, -167, 609, 792}, { 98, -220, 915, 148}, -{ 293, 283, 869, 91}, { 575, 394, 326, -78}, { 717, 67, 365, -323}, -{ 616, -36, 731, 27}, { 619, 238, 632, 273}, { 448, 99, 801, 476}, -{ 869, 273, 685, 64}, { 789, 72, 1021, 217}, { 793, 459, 734, 360}, -{ 646, 480, 360, 322}, { 429, 464, 638, 430}, { 756, 363, 1000, 404}, -{ 683, 528, 602, 615}, { 655, 413, 946, 687}, { 937, 602, 904, 604}, -{ 555, 737, 786, 662}, { 467, 654, 362, 589}, { 929, 710, 498, 478}, -{ 415, 420, 693, 883}, { 813, 683, 781, 925}, { 913, 939, 726, 732}, -{ 491, 853, 531, 948}, { 734, 963, 315, 808}, { 761, 755, 1144, 760}, -{ 655, 1076, 826, 1057}, { 1091, 838, 1003, 808}, { 1047, 1133, 659, 1101}, -{ 992, 1050, 1074, 1075}, { 971, 694, 1226, 1054}, { 571, 841, 884, 1404}, -{ 1379, 1096, 1080, 861}, { 1231, 735, 1284, 760}, { 1272, 991, 1367, 1053}, -{ 1257, 700, 1050, 534}, { 988, 453, 1264, 599}, { 1140, 679, 1621, 815}, -{ 1384, 521, 1317, 393}, { 1564, 805, 1448, 686}, { 1068, 648, 875, 307}, -{ 1083, 361, 1047, 317}, { 1417, 964, 675, 571}, { 1152, 79, 1114, -47}, -{ 1530, 311, 1721, 314}, { 1166, 689, 514, -94}, { 349, 282, 1412, 328}, -{ 1025, 487, -65, 57}, { 805, 970, 36, 62}, { 769, -263, 791, -346}, -{ 637, 699, -137, 620}, { 534, 541, -735, 194}, { 711, 300, -268, -863}, -{ 926, 769, -708, -428}, { 506, 174, -892, -630}, { 435, 547,-1435, -258}, -{ 621, 471,-1018,-1368}, { -393, 521, -920, -686}, { -25, 20, -982,-1156}, -{ 340, 9,-1558,-1135}, { -352, 48,-1579, -402}, { -887, 6,-1156, -888}, -{ -548, -352,-1643,-1168}, { -159, 610,-2024, -963}, { -225, 193,-1656,-1960}, -{ -245, -493, -964,-1680}, { -936, -635,-1299,-1744}, {-1388, -604,-1540, -835}, -{-1397, -135,-1588, -290}, {-1670, -712,-2011,-1632}, {-1663, -27,-2258, -811}, -{-1157, 184,-1265, 189}, {-1367, 586,-2011, 201}, { -790, 712,-1210, 3}, -{-1033, 808,-1251, 830}, { -111, 635,-1636, 447}, { -463, -949, -445, -928}, -{ -504,-1162, -501,-1211}, { 144, -351, -372,-1052}, { -283,-1059, -279,-1123}, -{ -575,-1438, -587,-1614}, { -935, -984, 229, 690}, { -921, -719, -403, 1362}, -{ -685, -465, 874, 397}, { -509, -46, 317, 1334}, { -485, 456, 813, 439}, -{ -411, 339, 898, 1067}, { -425, 46, 1441, 497}, { -909, -800, 1465, 1046}, -{ -254, -321, 1430, 1165}, { 68, 350, 1034, 666}, { 370, 11, 1311, 790}, -{ 143, 232, 1041, 1562}, { -114, 663, 1616, 1078}, { 454, 579, 1275, 1040}, -{ -76, 909, 752, 1067}, { 153, 512, 348, 1214}, { 614, 385, 1843, 808}, -{ 269, 1034, 203, 1086}, { 652, 1017, 1783, 1130}, { 429, 1327, 387, 1384}, -{ -49, 1183, -72, 1215}, { -416, 1001, 544, 1749}, { -352, 1223, -502, 1199}, -{ -589, 569, -227, 1630}, { -142, 1578, -230, 1715}, { -714, 1288, -838, 1398}, -{ 1131, 1357, -208, 1232}, { 437, 965, -929, 818}, { 811, 1410, 859, 1507}, -{ 164, 1212, 1387, 1793}, { 484, 1874, 456, 2063}, { 996, 1170, 1326, 1402}, -{ 1316, 1360, 1135, 1262}, { 1234, 1618, 1361, 1768}, { 1421, 1227, 1584, 1347}, -{ 854, 672, 1685, 1566}, { 1139, 1270, 2016, 1825}, { 1773, 1581, 1532, 1460}, -{ 1487, 946, 1659, 1021}, { 1744, 1212, 1392, 977}, { 1772, 1161, 1826, 1164}, -{ 1718, 1429, 1973, 1591}, { 1185, 864, 2132, 1061}, { 1799, 814, 1838, 757}, -{ 2104, 1315, 2054, 1258}, { 2113, 915, 2331, 930}, { 1467, 1147, 2590, 1439}, -{ 2245, 1744, 2090, 1620}, { 2358, 1454, 2666, 1506}, { 1876, 1837, 2070, 1975}, -{ 1739, 1577, 682, 1289}, { 1584, 2045, 1454, 2098}, { 2498, 2004, 2711, 2066}, -{ 726, 1588, 2756, 2336}, { 228, 847, 2456, 1659}, { 36, 301, 1942, 1957}, -{ -446, -96, 2154, 1396}, { 1533, 1101, 14, 608}, { -923, -732, 1383, 1982}, -{ 1345, 952, -680, 321}, { 1281, 1268,-1594, 365}, { 941, 946,-1737, -822}, -{ 2374, 2787, 1821, 2788} -}; - -static const int16_t lsf_5_3[256][4] = { -{-1812,-2275,-1879,-2537}, {-1640,-1848,-1695,-2004}, {-1220,-1912,-1221,-2106}, -{-1559,-1588,-1573,-1556}, {-1195,-1615,-1224,-1727}, {-1359,-1151,-1616,-1948}, -{-1274,-1391,-1305,-1403}, {-1607,-1179,-1676,-1311}, {-1443,-1478,-1367, -898}, -{-1256,-1059,-1331,-1134}, { -982,-1133,-1149,-1504}, {-1080,-1308,-1020,-1183}, -{ -980,-1486, -967,-1495}, { -988, -922,-1047,-1077}, { -838,-1179, -858,-1222}, -{-1131,-1041,-1064, -767}, { -872,-1157, -701, -880}, { -706, -906, -774,-1016}, -{ -578,-1080, -801,-1478}, { -591,-1111, -592,-1146}, { -713,-1388, -640,-1376}, -{ -597,-1059, -416, -903}, { -686, -832, -661, -708}, { -444, -868, -490, -921}, -{ -374, -776, -619,-1170}, { -585, -549, -769, -795}, { -435, -659, -530, -741}, -{ -498, -837, -357, -597}, { -279, -871, -243, -887}, { -282, -665, -280, -667}, -{ -165, -560, -394, -903}, { -362, -410, -448, -583}, { -409, -574, -313, -357}, -{ -637, -548, -570, -436}, { -896, -504, -382, -757}, { -58, -481, -165, -618}, -{ -191, -374, -234, -382}, { -222, -683, -25, -480}, { -418, -359, -730, -353}, -{ -324, -157, -432, -322}, { -394, -303, -284, -104}, { -601, -289, -556, -196}, -{ -588, -150, -659, -608}, { -473, -24, -68, -448}, { -474, -8, -506, -45}, -{ -748, -184, -844, -252}, { -901, -91, -584, -97}, { -652, 138, -764, -131}, -{ -678, -12, -670, 165}, { -259, -3, -840, -107}, { -909, 37, -992, 44}, -{ -854, -415, -839, 13}, {-1001, -271,-1026, -309}, { -798, -478, -832, -488}, -{ -943, 168,-1112, -387}, {-1185, -101,-1183, -40}, { -941, -316,-1030, -770}, -{-1044, -625,-1081, -538}, {-1224, -299,-1312, -436}, {-1197, -663,-1167, -161}, -{-1216, -690,-1237, -831}, {-1432, -720,-1403, -493}, { -898, -740, -922, -801}, -{-1102, -402,-1579, -964}, {-1061, -638,-1269,-1438}, {-1499, -934,-1502, -895}, -{-1598, -564,-1723, -717}, { -606, -597,-1166,-1085}, {-1369, -468,-1946,-1493}, -{-1838, -953,-1932, -931}, {-1499, -188,-1635, -421}, {-1457, -338,-1448, -22}, -{-1942, -422,-2006, -249}, { -496, -114,-1910, -755}, {-1289, 174,-1451, -109}, -{ -482, -257,-1221, -508}, {-1617, 151,-1694, 208}, { -654, 107,-1651, 29}, -{-1141, 279,-1215, 306}, {-1228, -506, -730, -175}, {-1236, -101, -969, 551}, -{ -870, 278, -823, 315}, { -563, 376,-1051, 228}, { -507, 280, -599, 281}, -{ -758, 253, -305, 379}, { -755, -134, -611, 660}, { -824, 536, -817, 646}, -{ -413, 49, -341, 177}, { -453, 526, -482, 589}, { -71, 339, -657, 264}, -{ -244, 295, -237, 315}, { -387, 569, -506, -9}, { -377, 14, -160, 661}, -{ -216, 40, -308, -46}, { 95, 214, -242, 167}, { -86, 192, -56, 27}, -{ -76, 31, 36, 309}, { -106, -182, -113, 74}, { -441, -22, 23, 139}, -{ 81, -11, 44, 15}, { -87, -137, -118, -207}, { -158, -58, 272, -92}, -{ -156, -441, 8, -136}, { 128, -221, 101, -218}, { 40, -197, -76, -456}, -{ 9, -445, 33, -423}, { 226, 60, 73, -222}, { 156, -399, 280, -318}, -{ 245, -341, 166, -499}, { 339, -190, 327, -219}, { 325, -137, -89, -596}, -{ 100, -627, 144, -677}, { 487, 28, 252, -391}, { 214, -41, 282, -28}, -{ 99, -286, 331, 49}, { 459, -388, 565, -369}, { 436, 28, 336, -9}, -{ 397, -167, 618, 34}, { 596, -17, 561, -140}, { 299, 79, 522, 125}, -{ 203, 2, 244, 288}, { 255, 211, 175, 82}, { 596, 187, 517, 108}, -{ 381, 255, 365, 297}, { 497, 352, 327, -82}, { 25, 210, 371, 245}, -{ 261, 3, 545, 449}, { 140, 294, 44, 295}, { 212, 347, 244, 494}, -{ 331, 528, 201, 307}, { 349, 411, 613, 284}, { 614, 413, 464, 322}, -{ 624, 397, 97, 200}, { -160, 384, 149, 362}, { 495, 525, 269, 585}, -{ 33, 491, -121, 433}, { 427, 611, 498, 516}, { 171, 443, 497, 666}, -{ 440, 275, 566, 575}, { 146, 639, 155, 670}, { -33, 173, 212, 696}, -{ -166, 601, -191, 695}, { -489, 503, 175, 742}, { 214, 476, 372, 1083}, -{ 578, 530, 586, 777}, { 425, 874, 315, 841}, { 374, 848, -165, 565}, -{ 35, 991, -39, 1062}, { 329, 712, 786, 840}, { 645, 795, 661, 676}, -{ 571, 918, 632, 1079}, { 673, 817, 318, 388}, { 874, 1012, 564, 848}, -{ 880, 620, 557, 479}, { 671, 453, 692, 468}, { 840, 642, 844, 645}, -{ 506, 428, 897, 567}, { 837, 387, 962, 499}, { 691, 561, 939, 926}, -{ 783, 296, 790, 268}, { 1028, 530, 874, 329}, { 548, 143, 675, 291}, -{ 503, 66, 1041, 359}, { 786, 97, 805, 33}, { 837, 470, 511, 49}, -{ 1092, 327, 1174, 323}, { 3, 242, 872, 474}, { 689, 429, 1329, 678}, -{ 1042, 620, 1109, 664}, { 321, 193, 889, 950}, { 1153, 874, 893, 635}, -{ 877, 862, 948, 913}, { 1293, 665, 1320, 639}, { 997, 793, 1402, 1030}, -{ 1176, 1012, 1110, 959}, { 1410, 925, 1403, 915}, { 543, 862, 1116, 1222}, -{ 835, 1190, 835, 1190}, { 959, 1148, 1147, 1376}, { 1300, 1193, 1415, 1231}, -{ 1335, 1341, 746, 1092}, { 1711, 1283, 1389, 1073}, { 1334, 1566, 1153, 1475}, -{ 1645, 1137, 1825, 1220}, { 1056, 1382, 1521, 1730}, { 1632, 1545, 1620, 1542}, -{ 855, 1596, 865, 1667}, { 693, 885, 1716, 1519}, { 1167, 1296, 2209, 1760}, -{ 1952, 1493, 2020, 1482}, { 1534, 1866, 1694, 2008}, { 1566, 748, 1761, 825}, -{ 294, 1392, 1084, 2058}, { 621, 1315, 365, 1287}, { 198, 1028, 488, 1408}, -{ 249, 403, 1014, 1561}, { 324, 363, 1645, 1044}, { 193, 367, 2034, 1859}, -{ -251, 579, 750, 994}, { -243, 30, 1325, 879}, { -28, -169, 624, 917}, -{ -453, 159, 186, 1370}, { -614, 6, 537, 392}, { -94, -291, 781, 229}, -{ -128, -298, 245, 491}, { -701, -648, 972, 789}, { -501, -640, 178, 255}, -{ -365, -390, -255, 317}, { -958, -294, -191, 228}, { -775, -447, 157, -237}, -{ -657, -720, -407, 92}, { -117, -611, 334, -230}, { -679,-1084, -144, -317}, -{ -901, -861, -738, -360}, { -85, -727, -90, -787}, { 100, -22, -391, -263}, -{ -56, -73, -337, -754}, { 5, -189, -706, -624}, { 89, -344, -135,-1113}, -{ -353, -237, -684,-1135}, { -275,-1102, -269,-1203}, { 152, 145, -722,-1232}, -{ 49, 80,-1248, -776}, { -248, 391, -732, -547}, { 469, 218, -255, -864}, -{ 69, 366, -166, -485}, { -688, 191,-1212,-1196}, { -170, -169,-1308,-1631}, -{ 321, 470,-1419,-1243}, { -64, 272,-1361, -248}, { 492, 565, -721, -609}, -{ 195, 485, -573, -133}, { 427, 202, -171, -118}, { 199, 575, 2, -31}, -{ 694, 755,-1366, -39}, { 552, 557, -489, 271}, { 680, 537, 13, -453}, -{ 855, 954, -133, -52}, { -81, 738,-1169, 637}, { 1055, 1059, -95, 676}, -{ 1259, 1081, 489, 305}, { -449, 954, -534, 996}, { -969, 866,-1058, 1059}, -{-1294, 618,-1416, 617}, { -458, 1366, -159, 1821}, { -774, -528, -14, 1110}, -{-1202, -901, -772, 433}, {-1256,-1255,-1011, -302}, { -602, -585, -759,-1618}, -{ -760,-1549, -840,-1921}, { -816, -539,-1769,-2235}, { -227, -36,-2034,-1831}, -{-2107,-1126,-2471,-1816}, {-1470, 252,-2701, -415}, { -571, -467, 1509, 1554}, -{ 2180, 1975, 2326, 2020} -}; - -static const int16_t lsf_5_4[256][4] = { -{-1857,-1681,-1857,-1755}, {-2056,-1150,-2134,-1654}, {-1619,-1099,-1704,-1131}, -{-1345,-1608,-1359,-1638}, {-1338,-1293,-1325,-1265}, {-1664,-1649,-1487, -851}, -{-1346,-1832,-1413,-2188}, {-1282, -681,-1785,-1649}, { -966,-1082,-1183,-1676}, -{-1054,-1073,-1142,-1158}, {-1207, -744,-1274, -997}, { -934,-1383, -927,-1416}, -{-1010,-1305, -783, -955}, {-1049, -900, -993, -817}, { -737, -823, -972,-1189}, -{ -738,-1094, -738,-1154}, { -784, -801, -810, -786}, { -892, -520,-1000, -818}, -{ -644, -965, -577, -882}, { -541, -694, -671, -917}, { -595, -642, -646, -615}, -{ -956, -621, -925, -515}, { -727, -483, -815, -485}, { -840, -578, -440, -713}, -{ -578, -325, -657, -670}, { -386, -570, -441, -666}, { -514, -787, -392, -529}, -{ -522, -453, -487, -423}, { -616, -585, -617, -157}, { -662, -268, -680, -348}, -{ -322, -323, -632, -444}, { -304, -430, -332, -458}, { -277, -468, -659, -793}, -{ -319, -636, -227, -554}, { -373, -347, -334, -210}, { -456, -192, -530, -242}, -{ -216, -198, -366, -370}, { -338, -161, -409, -748}, { -107, -380, -294, -643}, -{ -223, -665, -234, -741}, { -141, -496, -130, -510}, { -139, -327, -172, -305}, -{ -306, -580, -164, -263}, { -262, -172, -67, -402}, { 31, -366, -10, -436}, -{ -86, -527, 71, -377}, { -22, -609, -12, -678}, { -67, -319, 63, -191}, -{ 35, -181, -39, -242}, { 126, -167, -140, -544}, { 155, -297, 174, -297}, -{ 38, -8, 117, -380}, { 197, -452, 240, -522}, { 223, -103, 110, -187}, -{ 87, -155, 169, -47}, { 157, 26, -83, -100}, { 128, 80, 209, -62}, -{ 6, 7, 22, 5}, { 318, -20, 248, -45}, { -200, -63, 156, -69}, -{ 250, -183, 369, -126}, { -113, -76, -142, -122}, { -64, -254, -31, 35}, -{ -177, -71, -7, 171}, { 93, 27, 108, 212}, { -330, -209, -123, -70}, -{ -279, 95, -96, 20}, { -188, -61, -314, 87}, { -300, -78, -354, -134}, -{ 11, 122, -140, 122}, { -275, 152, -293, 140}, { -82, 138, -321, -111}, -{ -480, -156, -359, 76}, { -254, -40, -635, -96}, { -522, 79, -507, 8}, -{ -268, 303, -539, 68}, { -446, 61, -522, 306}, { 111, 189, -435, 122}, -{ -379, 166, -571, -398}, { -632, -74, -747, -95}, { -455, 194, -952, 83}, -{ -798, 192, -755, 192}, { -781, -162, -619, 234}, { -663, -297, -488, -109}, -{ -964, -132, -838, -68}, { -843, 58,-1112, -86}, { -805, -299, -944, -253}, -{ -778, -50, -965, -549}, { -352, -98, -992, -343}, {-1117, -315,-1117, -307}, -{-1155, -374, -637, -230}, {-1166, -43,-1299, -100}, { -925, -393,-1274, -600}, -{ -689, -130,-1479, -312}, {-1321, -254,-1464, -442}, {-1292, -613,-1261, -503}, -{-1501, -368,-1322, 26}, {-1432, -66,-1743, -161}, {-1644, -467,-1760, -548}, -{-1393, -568,-1556, -871}, {-1495,-1034,-1387, -571}, {-1917, -528,-1783, -123}, -{-1897, -231,-2054, -323}, {-2052, -906,-1976, -567}, {-1917, -620,-2047, -989}, -{-1077, -370,-2031, -704}, {-2355, -749,-2740,-1089}, {-1909, 159,-2012, 248}, -{ -626, -123,-2339, -962}, { -669, -408,-1379,-1174}, { -452, -364,-1044, -735}, -{ -132, 183,-1620, -752}, { -547, -307, -777,-1261}, { -98, 41, -880,-1091}, -{ -257, 97,-1602,-1833}, { 31, -26, -644, -561}, { -180, -546, -385,-1095}, -{ -410, -802, -414, -827}, { -457, -970, -490,-1109}, { -215, -916, -144, -937}, -{ -493,-1269, -517,-1507}, { 181, 101, -332, -889}, { -836, -937, -559, -429}, -{ -629, -547, -183, -337}, { -545, -82, -250, -286}, { 5, -132, -348, -252}, -{ -293, -472, -158, 100}, { -29, 197, -236, -424}, { -861, -213, -140, -7}, -{ -427, -443, 187, -97}, { -684, -736, -293, 258}, { -368, -152, -150, 392}, -{ -609, 175, -142, 299}, { -138, 152, -119, 329}, { -486, -52, 293, 198}, -{ -183, 117, 175, 331}, { -58, -274, 231, 300}, { -288, 330, -305, 372}, -{ -111, 409, -9, 423}, { 83, 256, 67, 367}, { -19, 248, 91, 113}, -{ -35, 406, -191, 154}, { 238, 296, 5, 197}, { 141, 221, 313, 198}, -{ 211, 421, 244, 334}, { 88, 426, -243, 454}, { 202, 552, -5, 403}, -{ 291, 185, 219, 301}, { 251, 138, 128, 69}, { 197, 288, -140, -61}, -{ 188, 361, 197, 598}, { 442, 273, 290, 143}, { 472, 482, 157, 370}, -{ 415, 321, 372, 385}, { 402, 552, 155, 24}, { 550, 263, -11, 21}, -{ 360, 227, 147, -254}, { 424, 97, 366, -13}, { 375, 141, 449, 232}, -{ 396, 507, 474, 272}, { 701, 324, 362, -47}, { 587, 148, 543, 69}, -{ 400, -51, 561, 59}, { 220, -10, 352, 147}, { 206, 211, 653, 185}, -{ 563, 297, 565, 284}, { 594, 121, 766, 192}, { 398, 118, 642, 434}, -{ 233, 264, 481, 467}, { 129, -165, 699, 239}, { 90, 26, 342, 474}, -{ -55, 27, 388, 94}, { -172, 0, 725, 379}, { -60, 337, 370, 465}, -{ 95, 319, 806, 595}, { 78, 260, 497, 851}, { 210, 560, 458, 574}, -{ -464, 202, 497, 625}, { -202, 152, 48, 712}, { -20, 566, 100, 715}, -{ 455, 468, 411, 605}, { 319, 646, 195, 615}, { 401, 538, 680, 739}, -{ 201, 667, 434, 954}, { 454, 425, 646, 491}, { 606, 681, 416, 508}, -{ 497, 822, 426, 815}, { 660, 647, 628, 716}, { 697, 466, 618, 457}, -{ 685, 460, 365, 309}, { 721, 567, 836, 601}, { 609, 300, 825, 459}, -{ 943, 687, 681, 533}, { 915, 598, 591, 243}, { 876, 451, 874, 420}, -{ 786, 317, 732, 220}, { 922, 317, 1108, 367}, { 531, 466, 1028, 649}, -{ 1053, 615, 1034, 553}, { 829, 602, 1021, 799}, { 927, 803, 878, 763}, -{ 799, 496, 1373, 773}, { 585, 770, 803, 930}, { 1099, 793, 1222, 862}, -{ 1209, 895, 1025, 727}, { 772, 845, 1172, 1115}, { 867, 1021, 830, 1013}, -{ 841, 910, 506, 703}, { 1239, 1077, 620, 819}, { 1196, 1083, 1155, 1081}, -{ 1142, 907, 1547, 1121}, { 1309, 648, 1343, 612}, { 1484, 988, 1479, 937}, -{ 985, 1328, 955, 1341}, { 429, 910, 841, 1338}, { 564, 1179, 412, 1156}, -{ 1427, 1320, 1434, 1330}, { 640, 760, 1726, 1410}, { 190, 555, 1073, 1005}, -{ 426, 257, 839, 980}, { 235, 231, 1520, 1167}, { 109, 293, 1014, 1569}, -{ 305, 142, 1148, 539}, { -291, -108, 1213, 972}, { 22, -216, 667, 828}, -{ -482, 438, 453, 1431}, { -581, -422, 789, 387}, { -358, -454, 174, 780}, -{ -36, -372, 390, -134}, { -629, 160, -306, 751}, {-1258, -331, 177, 522}, -{ -248, 574, -251, 639}, { -531, 407, -596, 394}, { -419, 789, -617, 801}, -{ -986, 399, -857, 727}, { -7, 518, -703, 310}, {-1143, -24,-1002, 287}, -{ -960, 363,-1299, 312}, {-1534, 245,-1557, 305}, { 28, 153, -859, -175}, -{ -33, 332,-1398, -154}, { 212, 410, -593, -197}, {-1092, -704, -904, -65}, -{ 282, 367, -918, -686}, { 345, 93, -258, -357}, { 696, 644, -693, -28}, -{ 448, 493, -273, 193}, { 527, 546, -243, -513}, { 384, -136, 273, -353}, -{ 512, -142, 537, -198}, { 941, 750, 83, 248}, { 578, 861, -56, 592}, -{ 842, 44, 892, 24}, { 33, 890, -16, 982}, { 831, 1398, 1535, 1898}, -{ 1716, 1376, 1948, 1465} -}; - -static const int16_t lsf_5_5[64][4] = { -{-1002, -929,-1096,-1203}, { -641, -931, -604, -961}, { -779, -673, -835, -788}, -{ -416, -664, -458, -766}, { -652, -521, -662, -495}, {-1023, -509,-1023, -428}, -{ -444, -552, -368, -449}, { -479, -211,-1054, -903}, { -316, -249, -569, -591}, -{ -569, -275, -541, -191}, { -716, -188, -842, -264}, { -333, -248, -318, -228}, -{ -275, 1, -567, -228}, { -115, -221, -238, -374}, { -197, -507, -222, -579}, -{ -258, -432, -61, -244}, { -345, 2, -338, 39}, { -215, -169, -58, 0}, -{ -56, -6, -203, -131}, { 1, -186, -5, -211}, { 6, -380, 11, -418}, -{ -116, 131, -134, 113}, { 89, -4, 71, -2}, { -19, -192, 262, 24}, -{ 189, 151, -133, -109}, { 186, -153, 166, -219}, { 37, 139, 193, 171}, -{ 337, 124, 158, -61}, { 141, 226, -13, 190}, { 231, 34, 354, 109}, -{ 316, 201, 244, 164}, { 330, -85, 390, -84}, { 254, 327, 257, 335}, -{ 491, 147, 476, 105}, { 54, 77, 437, 370}, { 421, 314, 449, 342}, -{ 329, 126, 673, 292}, { 571, 388, 243, 193}, { 653, 320, 621, 280}, -{ 194, 380, 517, 581}, { 45, 323, 111, 422}, { 489, 395, 734, 534}, -{ 622, 546, 486, 502}, { 318, 572, 189, 550}, { 385, 422, -157, 153}, -{ -125, 382, -197, 386}, { -263, 334, 228, 697}, { -188, 1, 51, 297}, -{ -507, 213, -376, 397}, { -24, 255, -547, 89}, { -502, -94, 387, 179}, -{ -620, 68, -684, 112}, { -642, -350, -260, 172}, { -438, -324, 264, 648}, -{ -964, -4,-1121, 7}, { -134, 134,-1133, -306}, { 143, 96, -420, -497}, -{-1221, -350,-1527, -685}, { -161, 72, 873, 691}, { 732, 283, 921, 353}, -{ 334, 475, 1095, 821}, { 864, 524, 843, 497}, { 714, 711, 788, 750}, -{ 1076, 714, 1204, 753} -}; - -static const float lsf_3_mean[LP_FILTER_ORDER] = { - 377.441, 554.688, 922.363, 1339.84, 1702.15, - 2046.390, 2452.880, 2741.460, 3116.70, 3348.14 -}; - -static const float lsf_5_mean[LP_FILTER_ORDER] = { - 337.891, 507.080, 834.961, 1247.07, 1646.00, - 1982.910, 2407.960, 2708.010, 3104.00, 3344.97 -}; - -/** Prediction factor table for modes other than 12.2kbit/s */ -static const float pred_fac[LP_FILTER_ORDER] = { - 0.291626, 0.328644, 0.383636, 0.405640, 0.438873, - 0.355560, 0.323120, 0.298065, 0.262238, 0.197876, -}; - -// fixed tables - -/** - * number of pulses per mode - */ -static const uint8_t pulses_nb_per_mode[] = {2, 2, 2, 3, 4, 4, 8, 10}; - -/** track start positions for algebraic code book routines */ -static const uint8_t track_position[16] = { - 0, 2, 0, 3, 0, 2, 0, 3, 1, 3, 2, 4, 1, 4, 1, 4 -}; - -/** 3-bit Gray code to binary lookup table */ -static const uint8_t gray_decode[8] = { 0, 5, 15, 10, 25, 30, 20, 35 }; - - -// gain tables - -/** scalar quantized pitch gain table for 7.95 and 12.2 kbps modes */ -static const uint16_t qua_gain_pit[16] = { - 0, 3277, 6556, 8192, 9830, 11469, 12288, 13107, - 13926, 14746, 15565, 16384, 17203, 18022, 18842, 19661 -}; - -/** scalar quantized fixed gain table for 7.95 and 12.2 kbps modes */ -static const uint16_t qua_gain_code[32] = { - 159, 206, 268, 349, 419, 482, 554, 637, - 733, 842, 969, 1114, 1281, 1473, 1694, 1948, - 2241, 2577, 2963, 3408, 3919, 4507, 5183, 5960, - 6855, 7883, 9065, 10425, 12510, 16263, 21142, 27485 -}; - -/** desired mean innovation energy, indexed by active mode */ -static const float energy_mean[8] = { - 33.0, 33.0, 33.0, 28.75, 30.0, 36.0, 33.0, 36.0 -}; - -/** 4-tap moving average prediction coefficients in reverse order */ -static const float energy_pred_fac[4] = { 0.19, 0.34, 0.58, 0.68 }; - -/** gain table for 4.75 kbps mode - * - * first index has even/odd indexes for subframes 0,2/1,3 - * second index is {pitch_gain, fixed_gain_factor} */ -static const uint16_t gains_MODE_4k75[512][2] = { -{ 812, 128}, { 542, 140}, { 2873, 1135}, { 2266, 3402}, { 2067, 563}, -{12677, 647}, { 4132, 1798}, { 5601, 5285}, { 7689, 374}, { 3735, 441}, -{10912, 2638}, {11807, 2494}, {20490, 797}, { 5218, 675}, { 6724, 8354}, -{ 5282, 1696}, { 1488, 428}, { 5882, 452}, { 5332, 4072}, { 3583, 1268}, -{ 2469, 901}, {15894, 1005}, {14982, 3271}, {10331, 4858}, { 3635, 2021}, -{ 2596, 835}, {12360, 4892}, {12206, 1704}, {13432, 1604}, { 9118, 2341}, -{ 3968, 1538}, { 5479, 9936}, { 3795, 417}, { 1359, 414}, { 3640, 1569}, -{ 7995, 3541}, {11405, 645}, { 8552, 635}, { 4056, 1377}, {16608, 6124}, -{11420, 700}, { 2007, 607}, {12415, 1578}, {11119, 4654}, {13680, 1708}, -{11990, 1229}, { 7996, 7297}, {13231, 5715}, { 2428, 1159}, { 2073, 1941}, -{ 6218, 6121}, { 3546, 1804}, { 8925, 1802}, { 8679, 1580}, {13935, 3576}, -{13313, 6237}, { 6142, 1130}, { 5994, 1734}, {14141, 4662}, {11271, 3321}, -{12226, 1551}, {13931, 3015}, { 5081,10464}, { 9444, 6706}, { 1689, 683}, -{ 1436, 1306}, { 7212, 3933}, { 4082, 2713}, { 7793, 704}, {15070, 802}, -{ 6299, 5212}, { 4337, 5357}, { 6676, 541}, { 6062, 626}, {13651, 3700}, -{11498, 2408}, {16156, 716}, {12177, 751}, { 8065,11489}, { 6314, 2256}, -{ 4466, 496}, { 7293, 523}, {10213, 3833}, { 8394, 3037}, { 8403, 966}, -{14228, 1880}, { 8703, 5409}, {16395, 4863}, { 7420, 1979}, { 6089, 1230}, -{ 9371, 4398}, {14558, 3363}, {13559, 2873}, {13163, 1465}, { 5534, 1678}, -{13138,14771}, { 7338, 600}, { 1318, 548}, { 4252, 3539}, {10044, 2364}, -{10587, 622}, {13088, 669}, {14126, 3526}, { 5039, 9784}, {15338, 619}, -{ 3115, 590}, {16442, 3013}, {15542, 4168}, {15537, 1611}, {15405, 1228}, -{16023, 9299}, { 7534, 4976}, { 1990, 1213}, {11447, 1157}, {12512, 5519}, -{ 9475, 2644}, { 7716, 2034}, {13280, 2239}, {16011, 5093}, { 8066, 6761}, -{10083, 1413}, { 5002, 2347}, {12523, 5975}, {15126, 2899}, {18264, 2289}, -{15827, 2527}, {16265,10254}, {14651,11319}, { 1797, 337}, { 3115, 397}, -{ 3510, 2928}, { 4592, 2670}, { 7519, 628}, {11415, 656}, { 5946, 2435}, -{ 6544, 7367}, { 8238, 829}, { 4000, 863}, {10032, 2492}, {16057, 3551}, -{18204, 1054}, { 6103, 1454}, { 5884, 7900}, {18752, 3468}, { 1864, 544}, -{ 9198, 683}, {11623, 4160}, { 4594, 1644}, { 3158, 1157}, {15953, 2560}, -{12349, 3733}, {17420, 5260}, { 6106, 2004}, { 2917, 1742}, {16467, 5257}, -{16787, 1680}, {17205, 1759}, { 4773, 3231}, { 7386, 6035}, {14342,10012}, -{ 4035, 442}, { 4194, 458}, { 9214, 2242}, { 7427, 4217}, {12860, 801}, -{11186, 825}, {12648, 2084}, {12956, 6554}, { 9505, 996}, { 6629, 985}, -{10537, 2502}, {15289, 5006}, {12602, 2055}, {15484, 1653}, {16194, 6921}, -{14231, 5790}, { 2626, 828}, { 5615, 1686}, {13663, 5778}, { 3668, 1554}, -{11313, 2633}, { 9770, 1459}, {14003, 4733}, {15897, 6291}, { 6278, 1870}, -{ 7910, 2285}, {16978, 4571}, {16576, 3849}, {15248, 2311}, {16023, 3244}, -{14459,17808}, {11847, 2763}, { 1981, 1407}, { 1400, 876}, { 4335, 3547}, -{ 4391, 4210}, { 5405, 680}, {17461, 781}, { 6501, 5118}, { 8091, 7677}, -{ 7355, 794}, { 8333, 1182}, {15041, 3160}, {14928, 3039}, {20421, 880}, -{14545, 852}, {12337,14708}, { 6904, 1920}, { 4225, 933}, { 8218, 1087}, -{10659, 4084}, {10082, 4533}, { 2735, 840}, {20657, 1081}, {16711, 5966}, -{15873, 4578}, {10871, 2574}, { 3773, 1166}, {14519, 4044}, {20699, 2627}, -{15219, 2734}, {15274, 2186}, { 6257, 3226}, {13125,19480}, { 7196, 930}, -{ 2462, 1618}, { 4515, 3092}, {13852, 4277}, {10460, 833}, {17339, 810}, -{16891, 2289}, {15546, 8217}, {13603, 1684}, { 3197, 1834}, {15948, 2820}, -{15812, 5327}, {17006, 2438}, {16788, 1326}, {15671, 8156}, {11726, 8556}, -{ 3762, 2053}, { 9563, 1317}, {13561, 6790}, {12227, 1936}, { 8180, 3550}, -{13287, 1778}, {16299, 6599}, {16291, 7758}, { 8521, 2551}, { 7225, 2645}, -{18269, 7489}, {16885, 2248}, {17882, 2884}, {17265, 3328}, { 9417,20162}, -{11042, 8320}, { 1286, 620}, { 1431, 583}, { 5993, 2289}, { 3978, 3626}, -{ 5144, 752}, {13409, 830}, { 5553, 2860}, {11764, 5908}, {10737, 560}, -{ 5446, 564}, {13321, 3008}, {11946, 3683}, {19887, 798}, { 9825, 728}, -{13663, 8748}, { 7391, 3053}, { 2515, 778}, { 6050, 833}, { 6469, 5074}, -{ 8305, 2463}, { 6141, 1865}, {15308, 1262}, {14408, 4547}, {13663, 4515}, -{ 3137, 2983}, { 2479, 1259}, {15088, 4647}, {15382, 2607}, {14492, 2392}, -{12462, 2537}, { 7539, 2949}, {12909,12060}, { 5468, 684}, { 3141, 722}, -{ 5081, 1274}, {12732, 4200}, {15302, 681}, { 7819, 592}, { 6534, 2021}, -{16478, 8737}, {13364, 882}, { 5397, 899}, {14656, 2178}, {14741, 4227}, -{14270, 1298}, {13929, 2029}, {15477, 7482}, {15815, 4572}, { 2521, 2013}, -{ 5062, 1804}, { 5159, 6582}, { 7130, 3597}, {10920, 1611}, {11729, 1708}, -{16903, 3455}, {16268, 6640}, { 9306, 1007}, { 9369, 2106}, {19182, 5037}, -{12441, 4269}, {15919, 1332}, {15357, 3512}, {11898,14141}, {16101, 6854}, -{ 2010, 737}, { 3779, 861}, {11454, 2880}, { 3564, 3540}, { 9057, 1241}, -{12391, 896}, { 8546, 4629}, {11561, 5776}, { 8129, 589}, { 8218, 588}, -{18728, 3755}, {12973, 3149}, {15729, 758}, {16634, 754}, {15222,11138}, -{15871, 2208}, { 4673, 610}, {10218, 678}, {15257, 4146}, { 5729, 3327}, -{ 8377, 1670}, {19862, 2321}, {15450, 5511}, {14054, 5481}, { 5728, 2888}, -{ 7580, 1346}, {14384, 5325}, {16236, 3950}, {15118, 3744}, {15306, 1435}, -{14597, 4070}, {12301,15696}, { 7617, 1699}, { 2170, 884}, { 4459, 4567}, -{18094, 3306}, {12742, 815}, {14926, 907}, {15016, 4281}, {15518, 8368}, -{17994, 1087}, { 2358, 865}, {16281, 3787}, {15679, 4596}, {16356, 1534}, -{16584, 2210}, {16833, 9697}, {15929, 4513}, { 3277, 1085}, { 9643, 2187}, -{11973, 6068}, { 9199, 4462}, { 8955, 1629}, {10289, 3062}, {16481, 5155}, -{15466, 7066}, {13678, 2543}, { 5273, 2277}, {16746, 6213}, {16655, 3408}, -{20304, 3363}, {18688, 1985}, {14172,12867}, {15154,15703}, { 4473, 1020}, -{ 1681, 886}, { 4311, 4301}, { 8952, 3657}, { 5893, 1147}, {11647, 1452}, -{15886, 2227}, { 4582, 6644}, { 6929, 1205}, { 6220, 799}, {12415, 3409}, -{15968, 3877}, {19859, 2109}, { 9689, 2141}, {14742, 8830}, {14480, 2599}, -{ 1817, 1238}, { 7771, 813}, {19079, 4410}, { 5554, 2064}, { 3687, 2844}, -{17435, 2256}, {16697, 4486}, {16199, 5388}, { 8028, 2763}, { 3405, 2119}, -{17426, 5477}, {13698, 2786}, {19879, 2720}, { 9098, 3880}, {18172, 4833}, -{17336,12207}, { 5116, 996}, { 4935, 988}, { 9888, 3081}, { 6014, 5371}, -{15881, 1667}, { 8405, 1183}, {15087, 2366}, {19777, 7002}, {11963, 1562}, -{ 7279, 1128}, {16859, 1532}, {15762, 5381}, {14708, 2065}, {20105, 2155}, -{17158, 8245}, {17911, 6318}, { 5467, 1504}, { 4100, 2574}, {17421, 6810}, -{ 5673, 2888}, {16636, 3382}, { 8975, 1831}, {20159, 4737}, {19550, 7294}, -{ 6658, 2781}, {11472, 3321}, {19397, 5054}, {18878, 4722}, {16439, 2373}, -{20430, 4386}, {11353,26526}, {11593, 3068}, { 2866, 1566}, { 5108, 1070}, -{ 9614, 4915}, { 4939, 3536}, { 7541, 878}, {20717, 851}, { 6938, 4395}, -{16799, 7733}, {10137, 1019}, { 9845, 964}, {15494, 3955}, {15459, 3430}, -{18863, 982}, {20120, 963}, {16876,12887}, {14334, 4200}, { 6599, 1220}, -{ 9222, 814}, {16942, 5134}, { 5661, 4898}, { 5488, 1798}, {20258, 3962}, -{17005, 6178}, {17929, 5929}, { 9365, 3420}, { 7474, 1971}, {19537, 5177}, -{19003, 3006}, {16454, 3788}, {16070, 2367}, { 8664, 2743}, { 9445,26358}, -{10856, 1287}, { 3555, 1009}, { 5606, 3622}, {19453, 5512}, {12453, 797}, -{20634, 911}, {15427, 3066}, {17037,10275}, {18883, 2633}, { 3913, 1268}, -{19519, 3371}, {18052, 5230}, {19291, 1678}, {19508, 3172}, {18072,10754}, -{16625, 6845}, { 3134, 2298}, {10869, 2437}, {15580, 6913}, {12597, 3381}, -{11116, 3297}, {16762, 2424}, {18853, 6715}, {17171, 9887}, {12743, 2605}, -{ 8937, 3140}, {19033, 7764}, {18347, 3880}, {20475, 3682}, {19602, 3380}, -{13044,19373}, {10526,23124} -}; - -/** gain table for 6.70, 7.40 and 10.2 kbps modes - * - * second index is {pitch_gain, fixed_gain_factor} */ -static const uint16_t gains_high[128][2] = { -{ 577, 662}, { 806, 1836}, { 3109, 1052}, { 4181, 1387}, { 2373, 1425}, -{ 3248, 1985}, { 1827, 2320}, { 941, 3314}, { 2351, 2977}, { 3616, 2420}, -{ 3451, 3096}, { 2955, 4301}, { 1848, 4500}, { 3884, 5416}, { 1187, 7210}, -{ 3083, 9000}, { 7384, 883}, { 5962, 1506}, { 5155, 2134}, { 7944, 2009}, -{ 6507, 2250}, { 7670, 2752}, { 5952, 3016}, { 4898, 3764}, { 6989, 3588}, -{ 8174, 3978}, { 6064, 4404}, { 7709, 5087}, { 5523, 6021}, { 7769, 7126}, -{ 6060, 7938}, { 5594,11487}, {10581, 1356}, { 9049, 1597}, { 9794, 2035}, -{ 8946, 2415}, {10296, 2584}, { 9407, 2734}, { 8700, 3218}, { 9757, 3395}, -{10177, 3892}, { 9170, 4528}, {10152, 5004}, { 9114, 5735}, {10500, 6266}, -{10110, 7631}, { 8844, 8727}, { 8956,12496}, {12924, 976}, {11435, 1755}, -{12138, 2328}, {11388, 2368}, {10700, 3064}, {12332, 2861}, {11722, 3327}, -{11270, 3700}, {10861, 4413}, {12082, 4533}, {11283, 5205}, {11960, 6305}, -{11167, 7534}, {12128, 8329}, {10969,10777}, {10300,17376}, {13899, 1681}, -{12580, 2045}, {13265, 2439}, {14033, 2989}, {13452, 3098}, {12396, 3658}, -{13510, 3780}, {12880, 4272}, {13533, 4861}, {12667, 5457}, {13854, 6106}, -{13031, 6483}, {13557, 7721}, {12957, 9311}, {13714,11551}, {12591,15206}, -{15113, 1540}, {15072, 2333}, {14527, 2511}, {14692, 3199}, {15382, 3560}, -{14133, 3960}, {15102, 4236}, {14332, 4824}, {14846, 5451}, {15306, 6083}, -{14329, 6888}, {15060, 7689}, {14406, 9426}, {15387, 9741}, {14824,14271}, -{13600,24939}, {16396, 1969}, {16817, 2832}, {15713, 2843}, {16104, 3336}, -{16384, 3963}, {16940, 4579}, {15711, 4599}, {16222, 5448}, {16832, 6382}, -{15745, 7141}, {16326, 7469}, {16611, 8624}, {17028,10418}, {15905,11817}, -{16878,14690}, {16515,20870}, {18142, 2083}, {19401, 3178}, {17508, 3426}, -{20054, 4027}, {18069, 4249}, {18952, 5066}, {17711, 5402}, {19835, 6192}, -{17950, 7014}, {21318, 7877}, {17910, 9289}, {19144, 9290}, {20517,11381}, -{18075,14485}, {19999,17882}, {18842,32764} -}; - -/** gain table for 5.15 and 5.90 kbps modes - * - * second index is {pitch_gain, fixed_gain_factor} */ -static const uint16_t gains_low[64][2] = { -{10813,28753}, {20480, 2785}, {18841, 6594}, { 6225, 7413}, {17203,10444}, -{21626, 1269}, {21135, 4423}, {11304, 1556}, {19005,12820}, {17367, 2498}, -{17858, 4833}, { 9994, 2498}, {17530, 7864}, {14254, 1884}, {15892, 3153}, -{ 6717, 1802}, {18186,20193}, {18022, 3031}, {16711, 5857}, { 8847, 4014}, -{15892, 8970}, {18022, 1392}, {16711, 4096}, { 8192, 655}, {15237,13926}, -{14254, 3112}, {14090, 4669}, { 5406, 2703}, {13434, 6553}, {12451, 901}, -{12451, 2662}, { 3768, 655}, {14745,23511}, {19169, 2457}, {20152, 5079}, -{ 6881, 4096}, {20480, 8560}, {19660, 737}, {19005, 4259}, { 7864, 2088}, -{11468,12288}, {15892, 1474}, {15728, 4628}, { 9175, 1433}, {16056, 7004}, -{14827, 737}, {15073, 2252}, { 5079, 1228}, {13271,17326}, {16547, 2334}, -{15073, 5816}, { 3932, 3686}, {14254, 8601}, {16875, 778}, {15073, 3809}, -{ 6062, 614}, { 9338, 9256}, {13271, 1761}, {13271, 3522}, { 2457, 1966}, -{11468, 5529}, {10485, 737}, {11632, 3194}, { 1474, 778} -}; - - -// pre-processing tables - -/** impulse response filter tables converted to float from Q15 int32_t - * used for anti-sparseness processing */ -static const float ir_filter_strong_MODE_7k95[AMR_SUBFRAME_SIZE] = { - 0.817169, 0.024445, 0.076447, -0.020844, -0.042175, 0.017761, 0.018433, --0.038879, 0.107147, -0.179871, 0.138367, -0.015228, -0.059204, 0.091888, --0.154358, 0.171326, -0.060730, -0.032379, -0.044525, 0.135559, -0.021362, --0.162811, 0.140656, 0.013794, -0.017975, -0.102295, 0.090118, 0.038666, --0.036987, -0.079041, 0.052826, 0.112000, -0.136566, -0.029755, 0.134003, --0.077423, 0.028961, -0.041595, -0.029877, 0.174988, -}; - -static const float ir_filter_strong[AMR_SUBFRAME_SIZE] = { - 0.448303, 0.351501, 0.038696, -0.084259, -0.173065, 0.229309, -0.001068, --0.085663, -0.092773, 0.147186, 0.090088, -0.257080, 0.115509, 0.044403, - 0.066498, -0.263580, 0.245697, -0.064178, -0.044373, 0.023712, 0.033813, --0.072784, 0.068787, -0.011078, -0.020569, -0.064178, 0.184509, -0.173370, - 0.032715, 0.095306, -0.154358, 0.162109, -0.071075, -0.113770, 0.211304, --0.118683, 0.020599, -0.054169, 0.000885, 0.309601, -}; - -static const float ir_filter_medium[AMR_SUBFRAME_SIZE] = { - 0.923889, 0.116913, -0.123169, 0.090698, -0.031982, -0.030579, 0.075592, --0.092865, 0.085907, -0.068085, 0.053497, -0.049164, 0.052307, -0.054169, - 0.047089, -0.030762, 0.013092, -0.005157, 0.014404, -0.038574, 0.066406, --0.082581, 0.076996, -0.049469, 0.010498, 0.025208, -0.046661, 0.052612, --0.050568, 0.051910, -0.062958, 0.080688, -0.093384, 0.088409, -0.060364, - 0.016998, 0.023804, -0.041779, 0.025696, 0.019989, -}; - -static const float *ir_filters_lookup[2] = { - ir_filter_strong, ir_filter_medium -}; -static const float *ir_filters_lookup_MODE_7k95[2] = { - ir_filter_strong_MODE_7k95, ir_filter_medium -}; - -// High-pass coefficients - -static const float highpass_zeros[2] = { -2.0, 1.0 }; -static const float highpass_poles[2] = { -1.933105469, 0.935913085 }; -static const float highpass_gain = 0.939819335; - -#endif /* AVCODEC_AMRNBDATA_H */ - diff --git a/tizen/distrib/ffmpeg/libavcodec/amrnbdec.c b/tizen/distrib/ffmpeg/libavcodec/amrnbdec.c deleted file mode 100644 index d3fa765..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/amrnbdec.c +++ /dev/null @@ -1,1076 +0,0 @@ -/* - * AMR narrowband decoder - * Copyright (c) 2006-2007 Robert Swain - * Copyright (c) 2009 Colin McQuillan - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -/** - * @file - * AMR narrowband decoder - * - * This decoder uses floats for simplicity and so is not bit-exact. One - * difference is that differences in phase can accumulate. The test sequences - * in 3GPP TS 26.074 can still be useful. - * - * - Comparing this file's output to the output of the ref decoder gives a - * PSNR of 30 to 80. Plotting the output samples shows a difference in - * phase in some areas. - * - * - Comparing both decoders against their input, this decoder gives a similar - * PSNR. If the test sequence homing frames are removed (this decoder does - * not detect them), the PSNR is at least as good as the reference on 140 - * out of 169 tests. - */ - - -#include -#include - -#include "avcodec.h" -#include "get_bits.h" -#include "libavutil/common.h" -#include "celp_math.h" -#include "celp_filters.h" -#include "acelp_filters.h" -#include "acelp_vectors.h" -#include "acelp_pitch_delay.h" -#include "lsp.h" - -#include "amrnbdata.h" - -#define AMR_BLOCK_SIZE 160 ///< samples per frame -#define AMR_SAMPLE_BOUND 32768.0 ///< threshold for synthesis overflow - -/** - * Scale from constructed speech to [-1,1] - * - * AMR is designed to produce 16-bit PCM samples (3GPP TS 26.090 4.2) but - * upscales by two (section 6.2.2). - * - * Fundamentally, this scale is determined by energy_mean through - * the fixed vector contribution to the excitation vector. - */ -#define AMR_SAMPLE_SCALE (2.0 / 32768.0) - -/** Prediction factor for 12.2kbit/s mode */ -#define PRED_FAC_MODE_12k2 0.65 - -#define LSF_R_FAC (8000.0 / 32768.0) ///< LSF residual tables to Hertz -#define MIN_LSF_SPACING (50.0488 / 8000.0) ///< Ensures stability of LPC filter -#define PITCH_LAG_MIN_MODE_12k2 18 ///< Lower bound on decoded lag search in 12.2kbit/s mode - -/** Initial energy in dB. Also used for bad frames (unimplemented). */ -#define MIN_ENERGY -14.0 - -/** Maximum sharpening factor - * - * The specification says 0.8, which should be 13107, but the reference C code - * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in g729dec.c.) - */ -#define SHARP_MAX 0.79449462890625 - -/** Number of impulse response coefficients used for tilt factor */ -#define AMR_TILT_RESPONSE 22 -/** Tilt factor = 1st reflection coefficient * gamma_t */ -#define AMR_TILT_GAMMA_T 0.8 -/** Adaptive gain control factor used in post-filter */ -#define AMR_AGC_ALPHA 0.9 - -typedef struct AMRContext { - AMRNBFrame frame; ///< decoded AMR parameters (lsf coefficients, codebook indexes, etc) - uint8_t bad_frame_indicator; ///< bad frame ? 1 : 0 - enum Mode cur_frame_mode; - - int16_t prev_lsf_r[LP_FILTER_ORDER]; ///< residual LSF vector from previous subframe - double lsp[4][LP_FILTER_ORDER]; ///< lsp vectors from current frame - double prev_lsp_sub4[LP_FILTER_ORDER]; ///< lsp vector for the 4th subframe of the previous frame - - float lsf_q[4][LP_FILTER_ORDER]; ///< Interpolated LSF vector for fixed gain smoothing - float lsf_avg[LP_FILTER_ORDER]; ///< vector of averaged lsf vector - - float lpc[4][LP_FILTER_ORDER]; ///< lpc coefficient vectors for 4 subframes - - uint8_t pitch_lag_int; ///< integer part of pitch lag from current subframe - - float excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1 + AMR_SUBFRAME_SIZE]; ///< current excitation and all necessary excitation history - float *excitation; ///< pointer to the current excitation vector in excitation_buf - - float pitch_vector[AMR_SUBFRAME_SIZE]; ///< adaptive code book (pitch) vector - float fixed_vector[AMR_SUBFRAME_SIZE]; ///< algebraic codebook (fixed) vector (must be kept zero between frames) - - float prediction_error[4]; ///< quantified prediction errors {20log10(^gamma_gc)} for previous four subframes - float pitch_gain[5]; ///< quantified pitch gains for the current and previous four subframes - float fixed_gain[5]; ///< quantified fixed gains for the current and previous four subframes - - float beta; ///< previous pitch_gain, bounded by [0.0,SHARP_MAX] - uint8_t diff_count; ///< the number of subframes for which diff has been above 0.65 - uint8_t hang_count; ///< the number of subframes since a hangover period started - - float prev_sparse_fixed_gain; ///< previous fixed gain; used by anti-sparseness processing to determine "onset" - uint8_t prev_ir_filter_nr; ///< previous impulse response filter "impNr": 0 - strong, 1 - medium, 2 - none - uint8_t ir_filter_onset; ///< flag for impulse response filter strength - - float postfilter_mem[10]; ///< previous intermediate values in the formant filter - float tilt_mem; ///< previous input to tilt compensation filter - float postfilter_agc; ///< previous factor used for adaptive gain control - float high_pass_mem[2]; ///< previous intermediate values in the high-pass filter - - float samples_in[LP_FILTER_ORDER + AMR_SUBFRAME_SIZE]; ///< floating point samples - -} AMRContext; - -/** Double version of ff_weighted_vector_sumf() */ -static void weighted_vector_sumd(double *out, const double *in_a, - const double *in_b, double weight_coeff_a, - double weight_coeff_b, int length) -{ - int i; - - for (i = 0; i < length; i++) - out[i] = weight_coeff_a * in_a[i] - + weight_coeff_b * in_b[i]; -} - -static av_cold int amrnb_decode_init(AVCodecContext *avctx) -{ - AMRContext *p = avctx->priv_data; - int i; - - avctx->sample_fmt = SAMPLE_FMT_FLT; - - // p->excitation always points to the same position in p->excitation_buf - p->excitation = &p->excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1]; - - for (i = 0; i < LP_FILTER_ORDER; i++) { - p->prev_lsp_sub4[i] = lsp_sub4_init[i] * 1000 / (float)(1 << 15); - p->lsf_avg[i] = p->lsf_q[3][i] = lsp_avg_init[i] / (float)(1 << 15); - } - - for (i = 0; i < 4; i++) - p->prediction_error[i] = MIN_ENERGY; - - return 0; -} - - -/** - * Unpack an RFC4867 speech frame into the AMR frame mode and parameters. - * - * The order of speech bits is specified by 3GPP TS 26.101. - * - * @param p the context - * @param buf pointer to the input buffer - * @param buf_size size of the input buffer - * - * @return the frame mode - */ -static enum Mode unpack_bitstream(AMRContext *p, const uint8_t *buf, - int buf_size) -{ - GetBitContext gb; - enum Mode mode; - - init_get_bits(&gb, buf, buf_size * 8); - - // Decode the first octet. - skip_bits(&gb, 1); // padding bit - mode = get_bits(&gb, 4); // frame type - p->bad_frame_indicator = !get_bits1(&gb); // quality bit - skip_bits(&gb, 2); // two padding bits - - if (mode < MODE_DTX) { - uint16_t *data = (uint16_t *)&p->frame; - const uint8_t *order = amr_unpacking_bitmaps_per_mode[mode]; - int field_size; - - memset(&p->frame, 0, sizeof(AMRNBFrame)); - buf++; - while ((field_size = *order++)) { - int field = 0; - int field_offset = *order++; - while (field_size--) { - int bit = *order++; - field <<= 1; - field |= buf[bit >> 3] >> (bit & 7) & 1; - } - data[field_offset] = field; - } - } - - return mode; -} - - -/// @defgroup amr_lpc_decoding AMR pitch LPC coefficient decoding functions -/// @{ - -/** - * Convert an lsf vector into an lsp vector. - * - * @param lsf input lsf vector - * @param lsp output lsp vector - */ -static void lsf2lsp(const float *lsf, double *lsp) -{ - int i; - - for (i = 0; i < LP_FILTER_ORDER; i++) - lsp[i] = cos(2.0 * M_PI * lsf[i]); -} - -/** - * Interpolate the LSF vector (used for fixed gain smoothing). - * The interpolation is done over all four subframes even in MODE_12k2. - * - * @param[in,out] lsf_q LSFs in [0,1] for each subframe - * @param[in] lsf_new New LSFs in [0,1] for subframe 4 - */ -static void interpolate_lsf(float lsf_q[4][LP_FILTER_ORDER], float *lsf_new) -{ - int i; - - for (i = 0; i < 4; i++) - ff_weighted_vector_sumf(lsf_q[i], lsf_q[3], lsf_new, - 0.25 * (3 - i), 0.25 * (i + 1), - LP_FILTER_ORDER); -} - -/** - * Decode a set of 5 split-matrix quantized lsf indexes into an lsp vector. - * - * @param p the context - * @param lsp output LSP vector - * @param lsf_no_r LSF vector without the residual vector added - * @param lsf_quantizer pointers to LSF dictionary tables - * @param quantizer_offset offset in tables - * @param sign for the 3 dictionary table - * @param update store data for computing the next frame's LSFs - */ -static void lsf2lsp_for_mode12k2(AMRContext *p, double lsp[LP_FILTER_ORDER], - const float lsf_no_r[LP_FILTER_ORDER], - const int16_t *lsf_quantizer[5], - const int quantizer_offset, - const int sign, const int update) -{ - int16_t lsf_r[LP_FILTER_ORDER]; // residual LSF vector - float lsf_q[LP_FILTER_ORDER]; // quantified LSF vector - int i; - - for (i = 0; i < LP_FILTER_ORDER >> 1; i++) - memcpy(&lsf_r[i << 1], &lsf_quantizer[i][quantizer_offset], - 2 * sizeof(*lsf_r)); - - if (sign) { - lsf_r[4] *= -1; - lsf_r[5] *= -1; - } - - if (update) - memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(float)); - - for (i = 0; i < LP_FILTER_ORDER; i++) - lsf_q[i] = lsf_r[i] * (LSF_R_FAC / 8000.0) + lsf_no_r[i] * (1.0 / 8000.0); - - ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER); - - if (update) - interpolate_lsf(p->lsf_q, lsf_q); - - lsf2lsp(lsf_q, lsp); -} - -/** - * Decode a set of 5 split-matrix quantized lsf indexes into 2 lsp vectors. - * - * @param p pointer to the AMRContext - */ -static void lsf2lsp_5(AMRContext *p) -{ - const uint16_t *lsf_param = p->frame.lsf; - float lsf_no_r[LP_FILTER_ORDER]; // LSFs without the residual vector - const int16_t *lsf_quantizer[5]; - int i; - - lsf_quantizer[0] = lsf_5_1[lsf_param[0]]; - lsf_quantizer[1] = lsf_5_2[lsf_param[1]]; - lsf_quantizer[2] = lsf_5_3[lsf_param[2] >> 1]; - lsf_quantizer[3] = lsf_5_4[lsf_param[3]]; - lsf_quantizer[4] = lsf_5_5[lsf_param[4]]; - - for (i = 0; i < LP_FILTER_ORDER; i++) - lsf_no_r[i] = p->prev_lsf_r[i] * LSF_R_FAC * PRED_FAC_MODE_12k2 + lsf_5_mean[i]; - - lsf2lsp_for_mode12k2(p, p->lsp[1], lsf_no_r, lsf_quantizer, 0, lsf_param[2] & 1, 0); - lsf2lsp_for_mode12k2(p, p->lsp[3], lsf_no_r, lsf_quantizer, 2, lsf_param[2] & 1, 1); - - // interpolate LSP vectors at subframes 1 and 3 - weighted_vector_sumd(p->lsp[0], p->prev_lsp_sub4, p->lsp[1], 0.5, 0.5, LP_FILTER_ORDER); - weighted_vector_sumd(p->lsp[2], p->lsp[1] , p->lsp[3], 0.5, 0.5, LP_FILTER_ORDER); -} - -/** - * Decode a set of 3 split-matrix quantized lsf indexes into an lsp vector. - * - * @param p pointer to the AMRContext - */ -static void lsf2lsp_3(AMRContext *p) -{ - const uint16_t *lsf_param = p->frame.lsf; - int16_t lsf_r[LP_FILTER_ORDER]; // residual LSF vector - float lsf_q[LP_FILTER_ORDER]; // quantified LSF vector - const int16_t *lsf_quantizer; - int i, j; - - lsf_quantizer = (p->cur_frame_mode == MODE_7k95 ? lsf_3_1_MODE_7k95 : lsf_3_1)[lsf_param[0]]; - memcpy(lsf_r, lsf_quantizer, 3 * sizeof(*lsf_r)); - - lsf_quantizer = lsf_3_2[lsf_param[1] << (p->cur_frame_mode <= MODE_5k15)]; - memcpy(lsf_r + 3, lsf_quantizer, 3 * sizeof(*lsf_r)); - - lsf_quantizer = (p->cur_frame_mode <= MODE_5k15 ? lsf_3_3_MODE_5k15 : lsf_3_3)[lsf_param[2]]; - memcpy(lsf_r + 6, lsf_quantizer, 4 * sizeof(*lsf_r)); - - // calculate mean-removed LSF vector and add mean - for (i = 0; i < LP_FILTER_ORDER; i++) - lsf_q[i] = (lsf_r[i] + p->prev_lsf_r[i] * pred_fac[i]) * (LSF_R_FAC / 8000.0) + lsf_3_mean[i] * (1.0 / 8000.0); - - ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER); - - // store data for computing the next frame's LSFs - interpolate_lsf(p->lsf_q, lsf_q); - memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(*lsf_r)); - - lsf2lsp(lsf_q, p->lsp[3]); - - // interpolate LSP vectors at subframes 1, 2 and 3 - for (i = 1; i <= 3; i++) - for(j = 0; j < LP_FILTER_ORDER; j++) - p->lsp[i-1][j] = p->prev_lsp_sub4[j] + - (p->lsp[3][j] - p->prev_lsp_sub4[j]) * 0.25 * i; -} - -/// @} - - -/// @defgroup amr_pitch_vector_decoding AMR pitch vector decoding functions -/// @{ - -/** - * Like ff_decode_pitch_lag(), but with 1/6 resolution - */ -static void decode_pitch_lag_1_6(int *lag_int, int *lag_frac, int pitch_index, - const int prev_lag_int, const int subframe) -{ - if (subframe == 0 || subframe == 2) { - if (pitch_index < 463) { - *lag_int = (pitch_index + 107) * 10923 >> 16; - *lag_frac = pitch_index - *lag_int * 6 + 105; - } else { - *lag_int = pitch_index - 368; - *lag_frac = 0; - } - } else { - *lag_int = ((pitch_index + 5) * 10923 >> 16) - 1; - *lag_frac = pitch_index - *lag_int * 6 - 3; - *lag_int += av_clip(prev_lag_int - 5, PITCH_LAG_MIN_MODE_12k2, - PITCH_DELAY_MAX - 9); - } -} - -static void decode_pitch_vector(AMRContext *p, - const AMRNBSubframe *amr_subframe, - const int subframe) -{ - int pitch_lag_int, pitch_lag_frac; - enum Mode mode = p->cur_frame_mode; - - if (p->cur_frame_mode == MODE_12k2) { - decode_pitch_lag_1_6(&pitch_lag_int, &pitch_lag_frac, - amr_subframe->p_lag, p->pitch_lag_int, - subframe); - } else - ff_decode_pitch_lag(&pitch_lag_int, &pitch_lag_frac, - amr_subframe->p_lag, - p->pitch_lag_int, subframe, - mode != MODE_4k75 && mode != MODE_5k15, - mode <= MODE_6k7 ? 4 : (mode == MODE_7k95 ? 5 : 6)); - - p->pitch_lag_int = pitch_lag_int; // store previous lag in a uint8_t - - pitch_lag_frac <<= (p->cur_frame_mode != MODE_12k2); - - pitch_lag_int += pitch_lag_frac > 0; - - /* Calculate the pitch vector by interpolating the past excitation at the - pitch lag using a b60 hamming windowed sinc function. */ - ff_acelp_interpolatef(p->excitation, p->excitation + 1 - pitch_lag_int, - ff_b60_sinc, 6, - pitch_lag_frac + 6 - 6*(pitch_lag_frac > 0), - 10, AMR_SUBFRAME_SIZE); - - memcpy(p->pitch_vector, p->excitation, AMR_SUBFRAME_SIZE * sizeof(float)); -} - -/// @} - - -/// @defgroup amr_algebraic_code_book AMR algebraic code book (fixed) vector decoding functions -/// @{ - -/** - * Decode a 10-bit algebraic codebook index from a 10.2 kbit/s frame. - */ -static void decode_10bit_pulse(int code, int pulse_position[8], - int i1, int i2, int i3) -{ - // coded using 7+3 bits with the 3 LSBs being, individually, the LSB of 1 of - // the 3 pulses and the upper 7 bits being coded in base 5 - const uint8_t *positions = base_five_table[code >> 3]; - pulse_position[i1] = (positions[2] << 1) + ( code & 1); - pulse_position[i2] = (positions[1] << 1) + ((code >> 1) & 1); - pulse_position[i3] = (positions[0] << 1) + ((code >> 2) & 1); -} - -/** - * Decode the algebraic codebook index to pulse positions and signs and - * construct the algebraic codebook vector for MODE_10k2. - * - * @param fixed_index positions of the eight pulses - * @param fixed_sparse pointer to the algebraic codebook vector - */ -static void decode_8_pulses_31bits(const int16_t *fixed_index, - AMRFixed *fixed_sparse) -{ - int pulse_position[8]; - int i, temp; - - decode_10bit_pulse(fixed_index[4], pulse_position, 0, 4, 1); - decode_10bit_pulse(fixed_index[5], pulse_position, 2, 6, 5); - - // coded using 5+2 bits with the 2 LSBs being, individually, the LSB of 1 of - // the 2 pulses and the upper 5 bits being coded in base 5 - temp = ((fixed_index[6] >> 2) * 25 + 12) >> 5; - pulse_position[3] = temp % 5; - pulse_position[7] = temp / 5; - if (pulse_position[7] & 1) - pulse_position[3] = 4 - pulse_position[3]; - pulse_position[3] = (pulse_position[3] << 1) + ( fixed_index[6] & 1); - pulse_position[7] = (pulse_position[7] << 1) + ((fixed_index[6] >> 1) & 1); - - fixed_sparse->n = 8; - for (i = 0; i < 4; i++) { - const int pos1 = (pulse_position[i] << 2) + i; - const int pos2 = (pulse_position[i + 4] << 2) + i; - const float sign = fixed_index[i] ? -1.0 : 1.0; - fixed_sparse->x[i ] = pos1; - fixed_sparse->x[i + 4] = pos2; - fixed_sparse->y[i ] = sign; - fixed_sparse->y[i + 4] = pos2 < pos1 ? -sign : sign; - } -} - -/** - * Decode the algebraic codebook index to pulse positions and signs, - * then construct the algebraic codebook vector. - * - * nb of pulses | bits encoding pulses - * For MODE_4k75 or MODE_5k15, 2 | 1-3, 4-6, 7 - * MODE_5k9, 2 | 1, 2-4, 5-6, 7-9 - * MODE_6k7, 3 | 1-3, 4, 5-7, 8, 9-11 - * MODE_7k4 or MODE_7k95, 4 | 1-3, 4-6, 7-9, 10, 11-13 - * - * @param fixed_sparse pointer to the algebraic codebook vector - * @param pulses algebraic codebook indexes - * @param mode mode of the current frame - * @param subframe current subframe number - */ -static void decode_fixed_sparse(AMRFixed *fixed_sparse, const uint16_t *pulses, - const enum Mode mode, const int subframe) -{ - assert(MODE_4k75 <= mode && mode <= MODE_12k2); - - if (mode == MODE_12k2) { - ff_decode_10_pulses_35bits(pulses, fixed_sparse, gray_decode, 5, 3); - } else if (mode == MODE_10k2) { - decode_8_pulses_31bits(pulses, fixed_sparse); - } else { - int *pulse_position = fixed_sparse->x; - int i, pulse_subset; - const int fixed_index = pulses[0]; - - if (mode <= MODE_5k15) { - pulse_subset = ((fixed_index >> 3) & 8) + (subframe << 1); - pulse_position[0] = ( fixed_index & 7) * 5 + track_position[pulse_subset]; - pulse_position[1] = ((fixed_index >> 3) & 7) * 5 + track_position[pulse_subset + 1]; - fixed_sparse->n = 2; - } else if (mode == MODE_5k9) { - pulse_subset = ((fixed_index & 1) << 1) + 1; - pulse_position[0] = ((fixed_index >> 1) & 7) * 5 + pulse_subset; - pulse_subset = (fixed_index >> 4) & 3; - pulse_position[1] = ((fixed_index >> 6) & 7) * 5 + pulse_subset + (pulse_subset == 3 ? 1 : 0); - fixed_sparse->n = pulse_position[0] == pulse_position[1] ? 1 : 2; - } else if (mode == MODE_6k7) { - pulse_position[0] = (fixed_index & 7) * 5; - pulse_subset = (fixed_index >> 2) & 2; - pulse_position[1] = ((fixed_index >> 4) & 7) * 5 + pulse_subset + 1; - pulse_subset = (fixed_index >> 6) & 2; - pulse_position[2] = ((fixed_index >> 8) & 7) * 5 + pulse_subset + 2; - fixed_sparse->n = 3; - } else { // mode <= MODE_7k95 - pulse_position[0] = gray_decode[ fixed_index & 7]; - pulse_position[1] = gray_decode[(fixed_index >> 3) & 7] + 1; - pulse_position[2] = gray_decode[(fixed_index >> 6) & 7] + 2; - pulse_subset = (fixed_index >> 9) & 1; - pulse_position[3] = gray_decode[(fixed_index >> 10) & 7] + pulse_subset + 3; - fixed_sparse->n = 4; - } - for (i = 0; i < fixed_sparse->n; i++) - fixed_sparse->y[i] = (pulses[1] >> i) & 1 ? 1.0 : -1.0; - } -} - -/** - * Apply pitch lag to obtain the sharpened fixed vector (section 6.1.2) - * - * @param p the context - * @param subframe unpacked amr subframe - * @param mode mode of the current frame - * @param fixed_sparse sparse respresentation of the fixed vector - */ -static void pitch_sharpening(AMRContext *p, int subframe, enum Mode mode, - AMRFixed *fixed_sparse) -{ - // The spec suggests the current pitch gain is always used, but in other - // modes the pitch and codebook gains are joinly quantized (sec 5.8.2) - // so the codebook gain cannot depend on the quantized pitch gain. - if (mode == MODE_12k2) - p->beta = FFMIN(p->pitch_gain[4], 1.0); - - fixed_sparse->pitch_lag = p->pitch_lag_int; - fixed_sparse->pitch_fac = p->beta; - - // Save pitch sharpening factor for the next subframe - // MODE_4k75 only updates on the 2nd and 4th subframes - this follows from - // the fact that the gains for two subframes are jointly quantized. - if (mode != MODE_4k75 || subframe & 1) - p->beta = av_clipf(p->pitch_gain[4], 0.0, SHARP_MAX); -} -/// @} - - -/// @defgroup amr_gain_decoding AMR gain decoding functions -/// @{ - -/** - * fixed gain smoothing - * Note that where the spec specifies the "spectrum in the q domain" - * in section 6.1.4, in fact frequencies should be used. - * - * @param p the context - * @param lsf LSFs for the current subframe, in the range [0,1] - * @param lsf_avg averaged LSFs - * @param mode mode of the current frame - * - * @return fixed gain smoothed - */ -static float fixed_gain_smooth(AMRContext *p , const float *lsf, - const float *lsf_avg, const enum Mode mode) -{ - float diff = 0.0; - int i; - - for (i = 0; i < LP_FILTER_ORDER; i++) - diff += fabs(lsf_avg[i] - lsf[i]) / lsf_avg[i]; - - // If diff is large for ten subframes, disable smoothing for a 40-subframe - // hangover period. - p->diff_count++; - if (diff <= 0.65) - p->diff_count = 0; - - if (p->diff_count > 10) { - p->hang_count = 0; - p->diff_count--; // don't let diff_count overflow - } - - if (p->hang_count < 40) { - p->hang_count++; - } else if (mode < MODE_7k4 || mode == MODE_10k2) { - const float smoothing_factor = av_clipf(4.0 * diff - 1.6, 0.0, 1.0); - const float fixed_gain_mean = (p->fixed_gain[0] + p->fixed_gain[1] + - p->fixed_gain[2] + p->fixed_gain[3] + - p->fixed_gain[4]) * 0.2; - return smoothing_factor * p->fixed_gain[4] + - (1.0 - smoothing_factor) * fixed_gain_mean; - } - return p->fixed_gain[4]; -} - -/** - * Decode pitch gain and fixed gain factor (part of section 6.1.3). - * - * @param p the context - * @param amr_subframe unpacked amr subframe - * @param mode mode of the current frame - * @param subframe current subframe number - * @param fixed_gain_factor decoded gain correction factor - */ -static void decode_gains(AMRContext *p, const AMRNBSubframe *amr_subframe, - const enum Mode mode, const int subframe, - float *fixed_gain_factor) -{ - if (mode == MODE_12k2 || mode == MODE_7k95) { - p->pitch_gain[4] = qua_gain_pit [amr_subframe->p_gain ] - * (1.0 / 16384.0); - *fixed_gain_factor = qua_gain_code[amr_subframe->fixed_gain] - * (1.0 / 2048.0); - } else { - const uint16_t *gains; - - if (mode >= MODE_6k7) { - gains = gains_high[amr_subframe->p_gain]; - } else if (mode >= MODE_5k15) { - gains = gains_low [amr_subframe->p_gain]; - } else { - // gain index is only coded in subframes 0,2 for MODE_4k75 - gains = gains_MODE_4k75[(p->frame.subframe[subframe & 2].p_gain << 1) + (subframe & 1)]; - } - - p->pitch_gain[4] = gains[0] * (1.0 / 16384.0); - *fixed_gain_factor = gains[1] * (1.0 / 4096.0); - } -} - -/// @} - - -/// @defgroup amr_pre_processing AMR pre-processing functions -/// @{ - -/** - * Circularly convolve a sparse fixed vector with a phase dispersion impulse - * response filter (D.6.2 of G.729 and 6.1.5 of AMR). - * - * @param out vector with filter applied - * @param in source vector - * @param filter phase filter coefficients - * - * out[n] = sum(i,0,len-1){ in[i] * filter[(len + n - i)%len] } - */ -static void apply_ir_filter(float *out, const AMRFixed *in, - const float *filter) -{ - float filter1[AMR_SUBFRAME_SIZE], //!< filters at pitch lag*1 and *2 - filter2[AMR_SUBFRAME_SIZE]; - int lag = in->pitch_lag; - float fac = in->pitch_fac; - int i; - - if (lag < AMR_SUBFRAME_SIZE) { - ff_celp_circ_addf(filter1, filter, filter, lag, fac, - AMR_SUBFRAME_SIZE); - - if (lag < AMR_SUBFRAME_SIZE >> 1) - ff_celp_circ_addf(filter2, filter, filter1, lag, fac, - AMR_SUBFRAME_SIZE); - } - - memset(out, 0, sizeof(float) * AMR_SUBFRAME_SIZE); - for (i = 0; i < in->n; i++) { - int x = in->x[i]; - float y = in->y[i]; - const float *filterp; - - if (x >= AMR_SUBFRAME_SIZE - lag) { - filterp = filter; - } else if (x >= AMR_SUBFRAME_SIZE - (lag << 1)) { - filterp = filter1; - } else - filterp = filter2; - - ff_celp_circ_addf(out, out, filterp, x, y, AMR_SUBFRAME_SIZE); - } -} - -/** - * Reduce fixed vector sparseness by smoothing with one of three IR filters. - * Also know as "adaptive phase dispersion". - * - * This implements 3GPP TS 26.090 section 6.1(5). - * - * @param p the context - * @param fixed_sparse algebraic codebook vector - * @param fixed_vector unfiltered fixed vector - * @param fixed_gain smoothed gain - * @param out space for modified vector if necessary - */ -static const float *anti_sparseness(AMRContext *p, AMRFixed *fixed_sparse, - const float *fixed_vector, - float fixed_gain, float *out) -{ - int ir_filter_nr; - - if (p->pitch_gain[4] < 0.6) { - ir_filter_nr = 0; // strong filtering - } else if (p->pitch_gain[4] < 0.9) { - ir_filter_nr = 1; // medium filtering - } else - ir_filter_nr = 2; // no filtering - - // detect 'onset' - if (fixed_gain > 2.0 * p->prev_sparse_fixed_gain) { - p->ir_filter_onset = 2; - } else if (p->ir_filter_onset) - p->ir_filter_onset--; - - if (!p->ir_filter_onset) { - int i, count = 0; - - for (i = 0; i < 5; i++) - if (p->pitch_gain[i] < 0.6) - count++; - if (count > 2) - ir_filter_nr = 0; - - if (ir_filter_nr > p->prev_ir_filter_nr + 1) - ir_filter_nr--; - } else if (ir_filter_nr < 2) - ir_filter_nr++; - - // Disable filtering for very low level of fixed_gain. - // Note this step is not specified in the technical description but is in - // the reference source in the function Ph_disp. - if (fixed_gain < 5.0) - ir_filter_nr = 2; - - if (p->cur_frame_mode != MODE_7k4 && p->cur_frame_mode < MODE_10k2 - && ir_filter_nr < 2) { - apply_ir_filter(out, fixed_sparse, - (p->cur_frame_mode == MODE_7k95 ? - ir_filters_lookup_MODE_7k95 : - ir_filters_lookup)[ir_filter_nr]); - fixed_vector = out; - } - - // update ir filter strength history - p->prev_ir_filter_nr = ir_filter_nr; - p->prev_sparse_fixed_gain = fixed_gain; - - return fixed_vector; -} - -/// @} - - -/// @defgroup amr_synthesis AMR synthesis functions -/// @{ - -/** - * Conduct 10th order linear predictive coding synthesis. - * - * @param p pointer to the AMRContext - * @param lpc pointer to the LPC coefficients - * @param fixed_gain fixed codebook gain for synthesis - * @param fixed_vector algebraic codebook vector - * @param samples pointer to the output speech samples - * @param overflow 16-bit overflow flag - */ -static int synthesis(AMRContext *p, float *lpc, - float fixed_gain, const float *fixed_vector, - float *samples, uint8_t overflow) -{ - int i; - float excitation[AMR_SUBFRAME_SIZE]; - - // if an overflow has been detected, the pitch vector is scaled down by a - // factor of 4 - if (overflow) - for (i = 0; i < AMR_SUBFRAME_SIZE; i++) - p->pitch_vector[i] *= 0.25; - - ff_weighted_vector_sumf(excitation, p->pitch_vector, fixed_vector, - p->pitch_gain[4], fixed_gain, AMR_SUBFRAME_SIZE); - - // emphasize pitch vector contribution - if (p->pitch_gain[4] > 0.5 && !overflow) { - float energy = ff_dot_productf(excitation, excitation, - AMR_SUBFRAME_SIZE); - float pitch_factor = - p->pitch_gain[4] * - (p->cur_frame_mode == MODE_12k2 ? - 0.25 * FFMIN(p->pitch_gain[4], 1.0) : - 0.5 * FFMIN(p->pitch_gain[4], SHARP_MAX)); - - for (i = 0; i < AMR_SUBFRAME_SIZE; i++) - excitation[i] += pitch_factor * p->pitch_vector[i]; - - ff_scale_vector_to_given_sum_of_squares(excitation, excitation, energy, - AMR_SUBFRAME_SIZE); - } - - ff_celp_lp_synthesis_filterf(samples, lpc, excitation, AMR_SUBFRAME_SIZE, - LP_FILTER_ORDER); - - // detect overflow - for (i = 0; i < AMR_SUBFRAME_SIZE; i++) - if (fabsf(samples[i]) > AMR_SAMPLE_BOUND) { - return 1; - } - - return 0; -} - -/// @} - - -/// @defgroup amr_update AMR update functions -/// @{ - -/** - * Update buffers and history at the end of decoding a subframe. - * - * @param p pointer to the AMRContext - */ -static void update_state(AMRContext *p) -{ - memcpy(p->prev_lsp_sub4, p->lsp[3], LP_FILTER_ORDER * sizeof(p->lsp[3][0])); - - memmove(&p->excitation_buf[0], &p->excitation_buf[AMR_SUBFRAME_SIZE], - (PITCH_DELAY_MAX + LP_FILTER_ORDER + 1) * sizeof(float)); - - memmove(&p->pitch_gain[0], &p->pitch_gain[1], 4 * sizeof(float)); - memmove(&p->fixed_gain[0], &p->fixed_gain[1], 4 * sizeof(float)); - - memmove(&p->samples_in[0], &p->samples_in[AMR_SUBFRAME_SIZE], - LP_FILTER_ORDER * sizeof(float)); -} - -/// @} - - -/// @defgroup amr_postproc AMR Post processing functions -/// @{ - -/** - * Get the tilt factor of a formant filter from its transfer function - * - * @param lpc_n LP_FILTER_ORDER coefficients of the numerator - * @param lpc_d LP_FILTER_ORDER coefficients of the denominator - */ -static float tilt_factor(float *lpc_n, float *lpc_d) -{ - float rh0, rh1; // autocorrelation at lag 0 and 1 - - // LP_FILTER_ORDER prior zeros are needed for ff_celp_lp_synthesis_filterf - float impulse_buffer[LP_FILTER_ORDER + AMR_TILT_RESPONSE] = { 0 }; - float *hf = impulse_buffer + LP_FILTER_ORDER; // start of impulse response - - hf[0] = 1.0; - memcpy(hf + 1, lpc_n, sizeof(float) * LP_FILTER_ORDER); - ff_celp_lp_synthesis_filterf(hf, lpc_d, hf, AMR_TILT_RESPONSE, - LP_FILTER_ORDER); - - rh0 = ff_dot_productf(hf, hf, AMR_TILT_RESPONSE); - rh1 = ff_dot_productf(hf, hf + 1, AMR_TILT_RESPONSE - 1); - - // The spec only specifies this check for 12.2 and 10.2 kbit/s - // modes. But in the ref source the tilt is always non-negative. - return rh1 >= 0.0 ? rh1 / rh0 * AMR_TILT_GAMMA_T : 0.0; -} - -/** - * Perform adaptive post-filtering to enhance the quality of the speech. - * See section 6.2.1. - * - * @param p pointer to the AMRContext - * @param lpc interpolated LP coefficients for this subframe - * @param buf_out output of the filter - */ -static void postfilter(AMRContext *p, float *lpc, float *buf_out) -{ - int i; - float *samples = p->samples_in + LP_FILTER_ORDER; // Start of input - - float speech_gain = ff_dot_productf(samples, samples, - AMR_SUBFRAME_SIZE); - - float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER]; // Output of pole filter - const float *gamma_n, *gamma_d; // Formant filter factor table - float lpc_n[LP_FILTER_ORDER], lpc_d[LP_FILTER_ORDER]; // Transfer function coefficients - - if (p->cur_frame_mode == MODE_12k2 || p->cur_frame_mode == MODE_10k2) { - gamma_n = ff_pow_0_7; - gamma_d = ff_pow_0_75; - } else { - gamma_n = ff_pow_0_55; - gamma_d = ff_pow_0_7; - } - - for (i = 0; i < LP_FILTER_ORDER; i++) { - lpc_n[i] = lpc[i] * gamma_n[i]; - lpc_d[i] = lpc[i] * gamma_d[i]; - } - - memcpy(pole_out, p->postfilter_mem, sizeof(float) * LP_FILTER_ORDER); - ff_celp_lp_synthesis_filterf(pole_out + LP_FILTER_ORDER, lpc_d, samples, - AMR_SUBFRAME_SIZE, LP_FILTER_ORDER); - memcpy(p->postfilter_mem, pole_out + AMR_SUBFRAME_SIZE, - sizeof(float) * LP_FILTER_ORDER); - - ff_celp_lp_zero_synthesis_filterf(buf_out, lpc_n, - pole_out + LP_FILTER_ORDER, - AMR_SUBFRAME_SIZE, LP_FILTER_ORDER); - - ff_tilt_compensation(&p->tilt_mem, tilt_factor(lpc_n, lpc_d), buf_out, - AMR_SUBFRAME_SIZE); - - ff_adaptive_gain_control(buf_out, buf_out, speech_gain, AMR_SUBFRAME_SIZE, - AMR_AGC_ALPHA, &p->postfilter_agc); -} - -/// @} - -static int amrnb_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - - AMRContext *p = avctx->priv_data; // pointer to private data - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - float *buf_out = data; // pointer to the output data buffer - int i, subframe; - float fixed_gain_factor; - AMRFixed fixed_sparse = {0}; // fixed vector up to anti-sparseness processing - float spare_vector[AMR_SUBFRAME_SIZE]; // extra stack space to hold result from anti-sparseness processing - float synth_fixed_gain; // the fixed gain that synthesis should use - const float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use - - p->cur_frame_mode = unpack_bitstream(p, buf, buf_size); - if (p->cur_frame_mode == MODE_DTX) { - av_log_missing_feature(avctx, "dtx mode", 1); - return -1; - } - - if (p->cur_frame_mode == MODE_12k2) { - lsf2lsp_5(p); - } else - lsf2lsp_3(p); - - for (i = 0; i < 4; i++) - ff_acelp_lspd2lpc(p->lsp[i], p->lpc[i], 5); - - for (subframe = 0; subframe < 4; subframe++) { - const AMRNBSubframe *amr_subframe = &p->frame.subframe[subframe]; - - decode_pitch_vector(p, amr_subframe, subframe); - - decode_fixed_sparse(&fixed_sparse, amr_subframe->pulses, - p->cur_frame_mode, subframe); - - // The fixed gain (section 6.1.3) depends on the fixed vector - // (section 6.1.2), but the fixed vector calculation uses - // pitch sharpening based on the on the pitch gain (section 6.1.3). - // So the correct order is: pitch gain, pitch sharpening, fixed gain. - decode_gains(p, amr_subframe, p->cur_frame_mode, subframe, - &fixed_gain_factor); - - pitch_sharpening(p, subframe, p->cur_frame_mode, &fixed_sparse); - - ff_set_fixed_vector(p->fixed_vector, &fixed_sparse, 1.0, - AMR_SUBFRAME_SIZE); - - p->fixed_gain[4] = - ff_amr_set_fixed_gain(fixed_gain_factor, - ff_dot_productf(p->fixed_vector, p->fixed_vector, - AMR_SUBFRAME_SIZE)/AMR_SUBFRAME_SIZE, - p->prediction_error, - energy_mean[p->cur_frame_mode], energy_pred_fac); - - // The excitation feedback is calculated without any processing such - // as fixed gain smoothing. This isn't mentioned in the specification. - for (i = 0; i < AMR_SUBFRAME_SIZE; i++) - p->excitation[i] *= p->pitch_gain[4]; - ff_set_fixed_vector(p->excitation, &fixed_sparse, p->fixed_gain[4], - AMR_SUBFRAME_SIZE); - - // In the ref decoder, excitation is stored with no fractional bits. - // This step prevents buzz in silent periods. The ref encoder can - // emit long sequences with pitch factor greater than one. This - // creates unwanted feedback if the excitation vector is nonzero. - // (e.g. test sequence T19_795.COD in 3GPP TS 26.074) - for (i = 0; i < AMR_SUBFRAME_SIZE; i++) - p->excitation[i] = truncf(p->excitation[i]); - - // Smooth fixed gain. - // The specification is ambiguous, but in the reference source, the - // smoothed value is NOT fed back into later fixed gain smoothing. - synth_fixed_gain = fixed_gain_smooth(p, p->lsf_q[subframe], - p->lsf_avg, p->cur_frame_mode); - - synth_fixed_vector = anti_sparseness(p, &fixed_sparse, p->fixed_vector, - synth_fixed_gain, spare_vector); - - if (synthesis(p, p->lpc[subframe], synth_fixed_gain, - synth_fixed_vector, &p->samples_in[LP_FILTER_ORDER], 0)) - // overflow detected -> rerun synthesis scaling pitch vector down - // by a factor of 4, skipping pitch vector contribution emphasis - // and adaptive gain control - synthesis(p, p->lpc[subframe], synth_fixed_gain, - synth_fixed_vector, &p->samples_in[LP_FILTER_ORDER], 1); - - postfilter(p, p->lpc[subframe], buf_out + subframe * AMR_SUBFRAME_SIZE); - - // update buffers and history - ff_clear_fixed_vector(p->fixed_vector, &fixed_sparse, AMR_SUBFRAME_SIZE); - update_state(p); - } - - ff_acelp_apply_order_2_transfer_function(buf_out, buf_out, highpass_zeros, - highpass_poles, - highpass_gain * AMR_SAMPLE_SCALE, - p->high_pass_mem, AMR_BLOCK_SIZE); - - /* Update averaged lsf vector (used for fixed gain smoothing). - * - * Note that lsf_avg should not incorporate the current frame's LSFs - * for fixed_gain_smooth. - * The specification has an incorrect formula: the reference decoder uses - * qbar(n-1) rather than qbar(n) in section 6.1(4) equation 71. */ - ff_weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3], - 0.84, 0.16, LP_FILTER_ORDER); - - /* report how many samples we got */ - *data_size = AMR_BLOCK_SIZE * sizeof(float); - - /* return the amount of bytes consumed if everything was OK */ - return frame_sizes_nb[p->cur_frame_mode] + 1; // +7 for rounding and +8 for TOC -} - - -AVCodec amrnb_decoder = { - .name = "amrnb", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_AMR_NB, - .priv_data_size = sizeof(AMRContext), - .init = amrnb_decode_init, - .decode = amrnb_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Adaptive Multi-Rate NarrowBand"), - .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_FLT,SAMPLE_FMT_NONE}, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/anm.c b/tizen/distrib/ffmpeg/libavcodec/anm.c deleted file mode 100644 index f384861..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/anm.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Deluxe Paint Animation decoder - * Copyright (c) 2009 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Deluxe Paint Animation decoder - */ - -#include "avcodec.h" -#include "bytestream.h" - -typedef struct AnmContext { - AVFrame frame; - int x; ///< x coordinate position -} AnmContext; - -static av_cold int decode_init(AVCodecContext *avctx) -{ - AnmContext *s = avctx->priv_data; - const uint8_t *buf; - int i; - - avctx->pix_fmt = PIX_FMT_PAL8; - - if (avctx->extradata_size != 16*8 + 4*256) - return -1; - - s->frame.reference = 1; - if (avctx->get_buffer(avctx, &s->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - buf = avctx->extradata + 16*8; - for (i = 0; i < 256; i++) - ((uint32_t*)s->frame.data[1])[i] = bytestream_get_le32(&buf); - - return 0; -} - -/** - * Perform decode operation - * @param dst, dst_end Destination image buffer - * @param buf, buf_end Source buffer (optional, see below) - * @param pixel Fill color (optional, see below) - * @param count Pixel count - * @param x Pointer to x-axis counter - * @param width Image width - * @param linesize Destination image buffer linesize - * @return non-zero if destination buffer is exhausted - * - * a copy operation is achieved when 'buf' is set - * a fill operation is acheived when 'buf' is null and pixel is >= 0 - * a skip operation is acheived when 'buf' is null and pixel is < 0 - */ -static inline int op(uint8_t **dst, const uint8_t *dst_end, - const uint8_t **buf, const uint8_t *buf_end, - int pixel, int count, - int *x, int width, int linesize) -{ - int remaining = width - *x; - while(count > 0) { - int striplen = FFMIN(count, remaining); - if (buf) { - striplen = FFMIN(striplen, buf_end - *buf); - memcpy(*dst, *buf, striplen); - *buf += striplen; - } else if (pixel >= 0) - memset(*dst, pixel, striplen); - *dst += striplen; - remaining -= striplen; - count -= striplen; - if (remaining <= 0) { - *dst += linesize - width; - remaining = width; - } - if (linesize > 0) { - if (*dst >= dst_end) goto exhausted; - } else { - if (*dst <= dst_end) goto exhausted; - } - } - *x = width - remaining; - return 0; - -exhausted: - *x = width - remaining; - return 1; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - AnmContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - const int buf_size = avpkt->size; - const uint8_t *buf_end = buf + buf_size; - uint8_t *dst, *dst_end; - int count; - - if(avctx->reget_buffer(avctx, &s->frame) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - dst = s->frame.data[0]; - dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height; - - if (buf[0] != 0x42) { - av_log_ask_for_sample(avctx, "unknown record type\n"); - return buf_size; - } - if (buf[1]) { - av_log_ask_for_sample(avctx, "padding bytes not supported\n"); - return buf_size; - } - buf += 4; - - s->x = 0; - do { - /* if statements are ordered by probability */ -#define OP(buf, pixel, count) \ - op(&dst, dst_end, (buf), buf_end, (pixel), (count), &s->x, avctx->width, s->frame.linesize[0]) - - int type = bytestream_get_byte(&buf); - count = type & 0x7F; - type >>= 7; - if (count) { - if (OP(type ? NULL : &buf, -1, count)) break; - } else if (!type) { - int pixel; - count = bytestream_get_byte(&buf); /* count==0 gives nop */ - pixel = bytestream_get_byte(&buf); - if (OP(NULL, pixel, count)) break; - } else { - int pixel; - type = bytestream_get_le16(&buf); - count = type & 0x3FFF; - type >>= 14; - if (!count) { - if (type == 0) - break; // stop - if (type == 2) { - av_log_ask_for_sample(avctx, "unknown opcode"); - return AVERROR_INVALIDDATA; - } - continue; - } - pixel = type == 3 ? bytestream_get_byte(&buf) : -1; - if (type == 1) count += 0x4000; - if (OP(type == 2 ? &buf : NULL, pixel, count)) break; - } - } while (buf + 1 < buf_end); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - return buf_size; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - AnmContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - return 0; -} - -AVCodec anm_decoder = { - "anm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ANM, - sizeof(AnmContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/apedec.c b/tizen/distrib/ffmpeg/libavcodec/apedec.c deleted file mode 100644 index a90a07f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/apedec.c +++ /dev/null @@ -1,891 +0,0 @@ -/* - * Monkey's Audio lossless audio decoder - * Copyright (c) 2007 Benjamin Zores - * based upon libdemac from Dave Chapman. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" -#include "bytestream.h" - -/** - * @file - * Monkey's Audio lossless audio decoder - */ - -#define BLOCKS_PER_LOOP 4608 -#define MAX_CHANNELS 2 -#define MAX_BYTESPERSAMPLE 3 - -#define APE_FRAMECODE_MONO_SILENCE 1 -#define APE_FRAMECODE_STEREO_SILENCE 3 -#define APE_FRAMECODE_PSEUDO_STEREO 4 - -#define HISTORY_SIZE 512 -#define PREDICTOR_ORDER 8 -/** Total size of all predictor histories */ -#define PREDICTOR_SIZE 50 - -#define YDELAYA (18 + PREDICTOR_ORDER*4) -#define YDELAYB (18 + PREDICTOR_ORDER*3) -#define XDELAYA (18 + PREDICTOR_ORDER*2) -#define XDELAYB (18 + PREDICTOR_ORDER) - -#define YADAPTCOEFFSA 18 -#define XADAPTCOEFFSA 14 -#define YADAPTCOEFFSB 10 -#define XADAPTCOEFFSB 5 - -/** - * Possible compression levels - * @{ - */ -enum APECompressionLevel { - COMPRESSION_LEVEL_FAST = 1000, - COMPRESSION_LEVEL_NORMAL = 2000, - COMPRESSION_LEVEL_HIGH = 3000, - COMPRESSION_LEVEL_EXTRA_HIGH = 4000, - COMPRESSION_LEVEL_INSANE = 5000 -}; -/** @} */ - -#define APE_FILTER_LEVELS 3 - -/** Filter orders depending on compression level */ -static const uint16_t ape_filter_orders[5][APE_FILTER_LEVELS] = { - { 0, 0, 0 }, - { 16, 0, 0 }, - { 64, 0, 0 }, - { 32, 256, 0 }, - { 16, 256, 1280 } -}; - -/** Filter fraction bits depending on compression level */ -static const uint8_t ape_filter_fracbits[5][APE_FILTER_LEVELS] = { - { 0, 0, 0 }, - { 11, 0, 0 }, - { 11, 0, 0 }, - { 10, 13, 0 }, - { 11, 13, 15 } -}; - - -/** Filters applied to the decoded data */ -typedef struct APEFilter { - int16_t *coeffs; ///< actual coefficients used in filtering - int16_t *adaptcoeffs; ///< adaptive filter coefficients used for correcting of actual filter coefficients - int16_t *historybuffer; ///< filter memory - int16_t *delay; ///< filtered values - - int avg; -} APEFilter; - -typedef struct APERice { - uint32_t k; - uint32_t ksum; -} APERice; - -typedef struct APERangecoder { - uint32_t low; ///< low end of interval - uint32_t range; ///< length of interval - uint32_t help; ///< bytes_to_follow resp. intermediate value - unsigned int buffer; ///< buffer for input/output -} APERangecoder; - -/** Filter histories */ -typedef struct APEPredictor { - int32_t *buf; - - int32_t lastA[2]; - - int32_t filterA[2]; - int32_t filterB[2]; - - int32_t coeffsA[2][4]; ///< adaption coefficients - int32_t coeffsB[2][5]; ///< adaption coefficients - int32_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE]; -} APEPredictor; - -/** Decoder context */ -typedef struct APEContext { - AVCodecContext *avctx; - DSPContext dsp; - int channels; - int samples; ///< samples left to decode in current frame - - int fileversion; ///< codec version, very important in decoding process - int compression_level; ///< compression levels - int fset; ///< which filter set to use (calculated from compression level) - int flags; ///< global decoder flags - - uint32_t CRC; ///< frame CRC - int frameflags; ///< frame flags - int currentframeblocks; ///< samples (per channel) in current frame - int blocksdecoded; ///< count of decoded samples in current frame - APEPredictor predictor; ///< predictor used for final reconstruction - - int32_t decoded0[BLOCKS_PER_LOOP]; ///< decoded data for the first channel - int32_t decoded1[BLOCKS_PER_LOOP]; ///< decoded data for the second channel - - int16_t* filterbuf[APE_FILTER_LEVELS]; ///< filter memory - - APERangecoder rc; ///< rangecoder used to decode actual values - APERice riceX; ///< rice code parameters for the second channel - APERice riceY; ///< rice code parameters for the first channel - APEFilter filters[APE_FILTER_LEVELS][2]; ///< filters used for reconstruction - - uint8_t *data; ///< current frame data - uint8_t *data_end; ///< frame data end - const uint8_t *ptr; ///< current position in frame data - const uint8_t *last_ptr; ///< position where last 4608-sample block ended - - int error; -} APEContext; - -// TODO: dsputilize - -static av_cold int ape_decode_init(AVCodecContext * avctx) -{ - APEContext *s = avctx->priv_data; - int i; - - if (avctx->extradata_size != 6) { - av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n"); - return -1; - } - if (avctx->bits_per_coded_sample != 16) { - av_log(avctx, AV_LOG_ERROR, "Only 16-bit samples are supported\n"); - return -1; - } - if (avctx->channels > 2) { - av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n"); - return -1; - } - s->avctx = avctx; - s->channels = avctx->channels; - s->fileversion = AV_RL16(avctx->extradata); - s->compression_level = AV_RL16(avctx->extradata + 2); - s->flags = AV_RL16(avctx->extradata + 4); - - av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags); - if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) { - av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level); - return -1; - } - s->fset = s->compression_level / 1000 - 1; - for (i = 0; i < APE_FILTER_LEVELS; i++) { - if (!ape_filter_orders[s->fset][i]) - break; - s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4); - } - - dsputil_init(&s->dsp, avctx); - avctx->sample_fmt = SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; - return 0; -} - -static av_cold int ape_decode_close(AVCodecContext * avctx) -{ - APEContext *s = avctx->priv_data; - int i; - - for (i = 0; i < APE_FILTER_LEVELS; i++) - av_freep(&s->filterbuf[i]); - - av_freep(&s->data); - return 0; -} - -/** - * @defgroup rangecoder APE range decoder - * @{ - */ - -#define CODE_BITS 32 -#define TOP_VALUE ((unsigned int)1 << (CODE_BITS-1)) -#define SHIFT_BITS (CODE_BITS - 9) -#define EXTRA_BITS ((CODE_BITS-2) % 8 + 1) -#define BOTTOM_VALUE (TOP_VALUE >> 8) - -/** Start the decoder */ -static inline void range_start_decoding(APEContext * ctx) -{ - ctx->rc.buffer = bytestream_get_byte(&ctx->ptr); - ctx->rc.low = ctx->rc.buffer >> (8 - EXTRA_BITS); - ctx->rc.range = (uint32_t) 1 << EXTRA_BITS; -} - -/** Perform normalization */ -static inline void range_dec_normalize(APEContext * ctx) -{ - while (ctx->rc.range <= BOTTOM_VALUE) { - ctx->rc.buffer <<= 8; - if(ctx->ptr < ctx->data_end) - ctx->rc.buffer += *ctx->ptr; - ctx->ptr++; - ctx->rc.low = (ctx->rc.low << 8) | ((ctx->rc.buffer >> 1) & 0xFF); - ctx->rc.range <<= 8; - } -} - -/** - * Calculate culmulative frequency for next symbol. Does NO update! - * @param ctx decoder context - * @param tot_f is the total frequency or (code_value)1<rc.help = ctx->rc.range / tot_f; - return ctx->rc.low / ctx->rc.help; -} - -/** - * Decode value with given size in bits - * @param ctx decoder context - * @param shift number of bits to decode - */ -static inline int range_decode_culshift(APEContext * ctx, int shift) -{ - range_dec_normalize(ctx); - ctx->rc.help = ctx->rc.range >> shift; - return ctx->rc.low / ctx->rc.help; -} - - -/** - * Update decoding state - * @param ctx decoder context - * @param sy_f the interval length (frequency of the symbol) - * @param lt_f the lower end (frequency sum of < symbols) - */ -static inline void range_decode_update(APEContext * ctx, int sy_f, int lt_f) -{ - ctx->rc.low -= ctx->rc.help * lt_f; - ctx->rc.range = ctx->rc.help * sy_f; -} - -/** Decode n bits (n <= 16) without modelling */ -static inline int range_decode_bits(APEContext * ctx, int n) -{ - int sym = range_decode_culshift(ctx, n); - range_decode_update(ctx, 1, sym); - return sym; -} - - -#define MODEL_ELEMENTS 64 - -/** - * Fixed probabilities for symbols in Monkey Audio version 3.97 - */ -static const uint16_t counts_3970[22] = { - 0, 14824, 28224, 39348, 47855, 53994, 58171, 60926, - 62682, 63786, 64463, 64878, 65126, 65276, 65365, 65419, - 65450, 65469, 65480, 65487, 65491, 65493, -}; - -/** - * Probability ranges for symbols in Monkey Audio version 3.97 - */ -static const uint16_t counts_diff_3970[21] = { - 14824, 13400, 11124, 8507, 6139, 4177, 2755, 1756, - 1104, 677, 415, 248, 150, 89, 54, 31, - 19, 11, 7, 4, 2, -}; - -/** - * Fixed probabilities for symbols in Monkey Audio version 3.98 - */ -static const uint16_t counts_3980[22] = { - 0, 19578, 36160, 48417, 56323, 60899, 63265, 64435, - 64971, 65232, 65351, 65416, 65447, 65466, 65476, 65482, - 65485, 65488, 65490, 65491, 65492, 65493, -}; - -/** - * Probability ranges for symbols in Monkey Audio version 3.98 - */ -static const uint16_t counts_diff_3980[21] = { - 19578, 16582, 12257, 7906, 4576, 2366, 1170, 536, - 261, 119, 65, 31, 19, 10, 6, 3, - 3, 2, 1, 1, 1, -}; - -/** - * Decode symbol - * @param ctx decoder context - * @param counts probability range start position - * @param counts_diff probability range widths - */ -static inline int range_get_symbol(APEContext * ctx, - const uint16_t counts[], - const uint16_t counts_diff[]) -{ - int symbol, cf; - - cf = range_decode_culshift(ctx, 16); - - if(cf > 65492){ - symbol= cf - 65535 + 63; - range_decode_update(ctx, 1, cf); - if(cf > 65535) - ctx->error=1; - return symbol; - } - /* figure out the symbol inefficiently; a binary search would be much better */ - for (symbol = 0; counts[symbol + 1] <= cf; symbol++); - - range_decode_update(ctx, counts_diff[symbol], counts[symbol]); - - return symbol; -} -/** @} */ // group rangecoder - -static inline void update_rice(APERice *rice, int x) -{ - int lim = rice->k ? (1 << (rice->k + 4)) : 0; - rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5); - - if (rice->ksum < lim) - rice->k--; - else if (rice->ksum >= (1 << (rice->k + 5))) - rice->k++; -} - -static inline int ape_decode_value(APEContext * ctx, APERice *rice) -{ - int x, overflow; - - if (ctx->fileversion < 3990) { - int tmpk; - - overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970); - - if (overflow == (MODEL_ELEMENTS - 1)) { - tmpk = range_decode_bits(ctx, 5); - overflow = 0; - } else - tmpk = (rice->k < 1) ? 0 : rice->k - 1; - - if (tmpk <= 16) - x = range_decode_bits(ctx, tmpk); - else { - x = range_decode_bits(ctx, 16); - x |= (range_decode_bits(ctx, tmpk - 16) << 16); - } - x += overflow << tmpk; - } else { - int base, pivot; - - pivot = rice->ksum >> 5; - if (pivot == 0) - pivot = 1; - - overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980); - - if (overflow == (MODEL_ELEMENTS - 1)) { - overflow = range_decode_bits(ctx, 16) << 16; - overflow |= range_decode_bits(ctx, 16); - } - - if (pivot < 0x10000) { - base = range_decode_culfreq(ctx, pivot); - range_decode_update(ctx, 1, base); - } else { - int base_hi = pivot, base_lo; - int bbits = 0; - - while (base_hi & ~0xFFFF) { - base_hi >>= 1; - bbits++; - } - base_hi = range_decode_culfreq(ctx, base_hi + 1); - range_decode_update(ctx, 1, base_hi); - base_lo = range_decode_culfreq(ctx, 1 << bbits); - range_decode_update(ctx, 1, base_lo); - - base = (base_hi << bbits) + base_lo; - } - - x = base + overflow * pivot; - } - - update_rice(rice, x); - - /* Convert to signed */ - if (x & 1) - return (x >> 1) + 1; - else - return -(x >> 1); -} - -static void entropy_decode(APEContext * ctx, int blockstodecode, int stereo) -{ - int32_t *decoded0 = ctx->decoded0; - int32_t *decoded1 = ctx->decoded1; - - ctx->blocksdecoded = blockstodecode; - - if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { - /* We are pure silence, just memset the output buffer. */ - memset(decoded0, 0, blockstodecode * sizeof(int32_t)); - memset(decoded1, 0, blockstodecode * sizeof(int32_t)); - } else { - while (blockstodecode--) { - *decoded0++ = ape_decode_value(ctx, &ctx->riceY); - if (stereo) - *decoded1++ = ape_decode_value(ctx, &ctx->riceX); - } - } - - if (ctx->blocksdecoded == ctx->currentframeblocks) - range_dec_normalize(ctx); /* normalize to use up all bytes */ -} - -static void init_entropy_decoder(APEContext * ctx) -{ - /* Read the CRC */ - ctx->CRC = bytestream_get_be32(&ctx->ptr); - - /* Read the frame flags if they exist */ - ctx->frameflags = 0; - if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) { - ctx->CRC &= ~0x80000000; - - ctx->frameflags = bytestream_get_be32(&ctx->ptr); - } - - /* Keep a count of the blocks decoded in this frame */ - ctx->blocksdecoded = 0; - - /* Initialize the rice structs */ - ctx->riceX.k = 10; - ctx->riceX.ksum = (1 << ctx->riceX.k) * 16; - ctx->riceY.k = 10; - ctx->riceY.ksum = (1 << ctx->riceY.k) * 16; - - /* The first 8 bits of input are ignored. */ - ctx->ptr++; - - range_start_decoding(ctx); -} - -static const int32_t initial_coeffs[4] = { - 360, 317, -109, 98 -}; - -static void init_predictor_decoder(APEContext * ctx) -{ - APEPredictor *p = &ctx->predictor; - - /* Zero the history buffers */ - memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(int32_t)); - p->buf = p->historybuffer; - - /* Initialize and zero the coefficients */ - memcpy(p->coeffsA[0], initial_coeffs, sizeof(initial_coeffs)); - memcpy(p->coeffsA[1], initial_coeffs, sizeof(initial_coeffs)); - memset(p->coeffsB, 0, sizeof(p->coeffsB)); - - p->filterA[0] = p->filterA[1] = 0; - p->filterB[0] = p->filterB[1] = 0; - p->lastA[0] = p->lastA[1] = 0; -} - -/** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */ -static inline int APESIGN(int32_t x) { - return (x < 0) - (x > 0); -} - -static av_always_inline int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB) -{ - int32_t predictionA, predictionB, sign; - - p->buf[delayA] = p->lastA[filter]; - p->buf[adaptA] = APESIGN(p->buf[delayA]); - p->buf[delayA - 1] = p->buf[delayA] - p->buf[delayA - 1]; - p->buf[adaptA - 1] = APESIGN(p->buf[delayA - 1]); - - predictionA = p->buf[delayA ] * p->coeffsA[filter][0] + - p->buf[delayA - 1] * p->coeffsA[filter][1] + - p->buf[delayA - 2] * p->coeffsA[filter][2] + - p->buf[delayA - 3] * p->coeffsA[filter][3]; - - /* Apply a scaled first-order filter compression */ - p->buf[delayB] = p->filterA[filter ^ 1] - ((p->filterB[filter] * 31) >> 5); - p->buf[adaptB] = APESIGN(p->buf[delayB]); - p->buf[delayB - 1] = p->buf[delayB] - p->buf[delayB - 1]; - p->buf[adaptB - 1] = APESIGN(p->buf[delayB - 1]); - p->filterB[filter] = p->filterA[filter ^ 1]; - - predictionB = p->buf[delayB ] * p->coeffsB[filter][0] + - p->buf[delayB - 1] * p->coeffsB[filter][1] + - p->buf[delayB - 2] * p->coeffsB[filter][2] + - p->buf[delayB - 3] * p->coeffsB[filter][3] + - p->buf[delayB - 4] * p->coeffsB[filter][4]; - - p->lastA[filter] = decoded + ((predictionA + (predictionB >> 1)) >> 10); - p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5); - - sign = APESIGN(decoded); - p->coeffsA[filter][0] += p->buf[adaptA ] * sign; - p->coeffsA[filter][1] += p->buf[adaptA - 1] * sign; - p->coeffsA[filter][2] += p->buf[adaptA - 2] * sign; - p->coeffsA[filter][3] += p->buf[adaptA - 3] * sign; - p->coeffsB[filter][0] += p->buf[adaptB ] * sign; - p->coeffsB[filter][1] += p->buf[adaptB - 1] * sign; - p->coeffsB[filter][2] += p->buf[adaptB - 2] * sign; - p->coeffsB[filter][3] += p->buf[adaptB - 3] * sign; - p->coeffsB[filter][4] += p->buf[adaptB - 4] * sign; - - return p->filterA[filter]; -} - -static void predictor_decode_stereo(APEContext * ctx, int count) -{ - APEPredictor *p = &ctx->predictor; - int32_t *decoded0 = ctx->decoded0; - int32_t *decoded1 = ctx->decoded1; - - while (count--) { - /* Predictor Y */ - *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB); - decoded0++; - *decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB); - decoded1++; - - /* Combined */ - p->buf++; - - /* Have we filled the history buffer? */ - if (p->buf == p->historybuffer + HISTORY_SIZE) { - memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t)); - p->buf = p->historybuffer; - } - } -} - -static void predictor_decode_mono(APEContext * ctx, int count) -{ - APEPredictor *p = &ctx->predictor; - int32_t *decoded0 = ctx->decoded0; - int32_t predictionA, currentA, A, sign; - - currentA = p->lastA[0]; - - while (count--) { - A = *decoded0; - - p->buf[YDELAYA] = currentA; - p->buf[YDELAYA - 1] = p->buf[YDELAYA] - p->buf[YDELAYA - 1]; - - predictionA = p->buf[YDELAYA ] * p->coeffsA[0][0] + - p->buf[YDELAYA - 1] * p->coeffsA[0][1] + - p->buf[YDELAYA - 2] * p->coeffsA[0][2] + - p->buf[YDELAYA - 3] * p->coeffsA[0][3]; - - currentA = A + (predictionA >> 10); - - p->buf[YADAPTCOEFFSA] = APESIGN(p->buf[YDELAYA ]); - p->buf[YADAPTCOEFFSA - 1] = APESIGN(p->buf[YDELAYA - 1]); - - sign = APESIGN(A); - p->coeffsA[0][0] += p->buf[YADAPTCOEFFSA ] * sign; - p->coeffsA[0][1] += p->buf[YADAPTCOEFFSA - 1] * sign; - p->coeffsA[0][2] += p->buf[YADAPTCOEFFSA - 2] * sign; - p->coeffsA[0][3] += p->buf[YADAPTCOEFFSA - 3] * sign; - - p->buf++; - - /* Have we filled the history buffer? */ - if (p->buf == p->historybuffer + HISTORY_SIZE) { - memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t)); - p->buf = p->historybuffer; - } - - p->filterA[0] = currentA + ((p->filterA[0] * 31) >> 5); - *(decoded0++) = p->filterA[0]; - } - - p->lastA[0] = currentA; -} - -static void do_init_filter(APEFilter *f, int16_t * buf, int order) -{ - f->coeffs = buf; - f->historybuffer = buf + order; - f->delay = f->historybuffer + order * 2; - f->adaptcoeffs = f->historybuffer + order; - - memset(f->historybuffer, 0, (order * 2) * sizeof(int16_t)); - memset(f->coeffs, 0, order * sizeof(int16_t)); - f->avg = 0; -} - -static void init_filter(APEContext * ctx, APEFilter *f, int16_t * buf, int order) -{ - do_init_filter(&f[0], buf, order); - do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order); -} - -static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits) -{ - int res; - int absres; - - while (count--) { - /* round fixedpoint scalar product */ - res = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data)); - res = (res + (1 << (fracbits - 1))) >> fracbits; - res += *data; - *data++ = res; - - /* Update the output history */ - *f->delay++ = av_clip_int16(res); - - if (version < 3980) { - /* Version ??? to < 3.98 files (untested) */ - f->adaptcoeffs[0] = (res == 0) ? 0 : ((res >> 28) & 8) - 4; - f->adaptcoeffs[-4] >>= 1; - f->adaptcoeffs[-8] >>= 1; - } else { - /* Version 3.98 and later files */ - - /* Update the adaption coefficients */ - absres = FFABS(res); - if (absres) - *f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3)); - else - *f->adaptcoeffs = 0; - - f->avg += (absres - f->avg) / 16; - - f->adaptcoeffs[-1] >>= 1; - f->adaptcoeffs[-2] >>= 1; - f->adaptcoeffs[-8] >>= 1; - } - - f->adaptcoeffs++; - - /* Have we filled the history buffer? */ - if (f->delay == f->historybuffer + HISTORY_SIZE + (order * 2)) { - memmove(f->historybuffer, f->delay - (order * 2), - (order * 2) * sizeof(int16_t)); - f->delay = f->historybuffer + order * 2; - f->adaptcoeffs = f->historybuffer + order; - } - } -} - -static void apply_filter(APEContext * ctx, APEFilter *f, - int32_t * data0, int32_t * data1, - int count, int order, int fracbits) -{ - do_apply_filter(ctx, ctx->fileversion, &f[0], data0, count, order, fracbits); - if (data1) - do_apply_filter(ctx, ctx->fileversion, &f[1], data1, count, order, fracbits); -} - -static void ape_apply_filters(APEContext * ctx, int32_t * decoded0, - int32_t * decoded1, int count) -{ - int i; - - for (i = 0; i < APE_FILTER_LEVELS; i++) { - if (!ape_filter_orders[ctx->fset][i]) - break; - apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, ape_filter_orders[ctx->fset][i], ape_filter_fracbits[ctx->fset][i]); - } -} - -static void init_frame_decoder(APEContext * ctx) -{ - int i; - init_entropy_decoder(ctx); - init_predictor_decoder(ctx); - - for (i = 0; i < APE_FILTER_LEVELS; i++) { - if (!ape_filter_orders[ctx->fset][i]) - break; - init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], ape_filter_orders[ctx->fset][i]); - } -} - -static void ape_unpack_mono(APEContext * ctx, int count) -{ - int32_t left; - int32_t *decoded0 = ctx->decoded0; - int32_t *decoded1 = ctx->decoded1; - - if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { - entropy_decode(ctx, count, 0); - /* We are pure silence, so we're done. */ - av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence mono\n"); - return; - } - - entropy_decode(ctx, count, 0); - ape_apply_filters(ctx, decoded0, NULL, count); - - /* Now apply the predictor decoding */ - predictor_decode_mono(ctx, count); - - /* Pseudo-stereo - just copy left channel to right channel */ - if (ctx->channels == 2) { - while (count--) { - left = *decoded0; - *(decoded1++) = *(decoded0++) = left; - } - } -} - -static void ape_unpack_stereo(APEContext * ctx, int count) -{ - int32_t left, right; - int32_t *decoded0 = ctx->decoded0; - int32_t *decoded1 = ctx->decoded1; - - if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { - /* We are pure silence, so we're done. */ - av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence stereo\n"); - return; - } - - entropy_decode(ctx, count, 1); - ape_apply_filters(ctx, decoded0, decoded1, count); - - /* Now apply the predictor decoding */ - predictor_decode_stereo(ctx, count); - - /* Decorrelate and scale to output depth */ - while (count--) { - left = *decoded1 - (*decoded0 / 2); - right = left + *decoded0; - - *(decoded0++) = left; - *(decoded1++) = right; - } -} - -static int ape_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - APEContext *s = avctx->priv_data; - int16_t *samples = data; - int nblocks; - int i, n; - int blockstodecode; - int bytes_used; - - if (buf_size == 0 && !s->samples) { - *data_size = 0; - return 0; - } - - /* should not happen but who knows */ - if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) { - av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc! (max is %d where you have %d)\n", *data_size, s->samples * 2 * avctx->channels); - return -1; - } - - if(!s->samples){ - s->data = av_realloc(s->data, (buf_size + 3) & ~3); - s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2); - s->ptr = s->last_ptr = s->data; - s->data_end = s->data + buf_size; - - nblocks = s->samples = bytestream_get_be32(&s->ptr); - n = bytestream_get_be32(&s->ptr); - if(n < 0 || n > 3){ - av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); - s->data = NULL; - return -1; - } - s->ptr += n; - - s->currentframeblocks = nblocks; - buf += 4; - if (s->samples <= 0) { - *data_size = 0; - return buf_size; - } - - memset(s->decoded0, 0, sizeof(s->decoded0)); - memset(s->decoded1, 0, sizeof(s->decoded1)); - - /* Initialize the frame decoder */ - init_frame_decoder(s); - } - - if (!s->data) { - *data_size = 0; - return buf_size; - } - - nblocks = s->samples; - blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks); - - s->error=0; - - if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO)) - ape_unpack_mono(s, blockstodecode); - else - ape_unpack_stereo(s, blockstodecode); - emms_c(); - - if(s->error || s->ptr > s->data_end){ - s->samples=0; - av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); - return -1; - } - - for (i = 0; i < blockstodecode; i++) { - *samples++ = s->decoded0[i]; - if(s->channels == 2) - *samples++ = s->decoded1[i]; - } - - s->samples -= blockstodecode; - - *data_size = blockstodecode * 2 * s->channels; - bytes_used = s->samples ? s->ptr - s->last_ptr : buf_size; - s->last_ptr = s->ptr; - return bytes_used; -} - -AVCodec ape_decoder = { - "ape", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_APE, - sizeof(APEContext), - ape_decode_init, - NULL, - ape_decode_close, - ape_decode_frame, - .capabilities = CODEC_CAP_SUBFRAMES, - .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/api-example.c b/tizen/distrib/ffmpeg/libavcodec/api-example.c deleted file mode 100644 index f34075e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/api-example.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 - -#ifdef HAVE_AV_CONFIG_H -#undef HAVE_AV_CONFIG_H -#endif - -#include "libavcodec/avcodec.h" -#include "libavutil/mathematics.h" - -#define INBUF_SIZE 4096 -#define AUDIO_INBUF_SIZE 20480 -#define AUDIO_REFILL_THRESH 4096 - -/* - * Audio encoding example - */ -static 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) { - out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; - len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt); - 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); - } - avpkt.size -= len; - avpkt.data += len; - if (avpkt.size < AUDIO_REFILL_THRESH) { - /* Refill the input buffer, to avoid trying to decode - * incomplete frames. Instead of this, one could also use - * a parser, or use a proper container format through - * libavformat. */ - memmove(inbuf, avpkt.data, avpkt.size); - avpkt.data = inbuf; - len = fread(avpkt.data + avpkt.size, 1, - AUDIO_INBUF_SIZE - avpkt.size, f); - if (len > 0) - avpkt.size += len; - } - } - - fclose(outfile); - fclose(f); - free(outbuf); - - avcodec_close(c); - av_free(c); -} - -/* - * Video encoding example - */ -static 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); - } - - 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 - */ - -static 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 do not send complete frames */ - - /* For some codecs, such as msmpeg4 and mpeg4, width and height - MUST be initialized there because this information is 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(;;) { - avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); - if (avpkt.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 */ - avpkt.data = inbuf; - while (avpkt.size > 0) { - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - 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++; - } - avpkt.size -= len; - avpkt.data += 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 */ - avpkt.data = NULL; - avpkt.size = 0; - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - 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 */ - 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/tizen/distrib/ffmpeg/libavcodec/arm/Makefile b/tizen/distrib/ffmpeg/libavcodec/arm/Makefile deleted file mode 100644 index 46bfc75c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o \ - -OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_init_arm.o -OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_init_arm.o - -OBJS-$(CONFIG_H264DSP) += arm/h264dsp_init_arm.o \ - arm/h264pred_init_arm.o \ - -OBJS += arm/dsputil_init_arm.o \ - arm/dsputil_arm.o \ - arm/fft_init_arm.o \ - arm/jrevdct_arm.o \ - arm/mpegvideo_arm.o \ - arm/simple_idct_arm.o \ - -OBJS-$(HAVE_ARMV5TE) += arm/dsputil_init_armv5te.o \ - arm/mpegvideo_armv5te.o \ - arm/mpegvideo_armv5te_s.o \ - arm/simple_idct_armv5te.o \ - -OBJS-$(HAVE_ARMV6) += arm/dsputil_init_armv6.o \ - arm/dsputil_armv6.o \ - arm/simple_idct_armv6.o \ - -OBJS-$(HAVE_ARMVFP) += arm/dsputil_vfp.o \ - arm/dsputil_init_vfp.o \ - -OBJS-$(HAVE_IWMMXT) += arm/dsputil_iwmmxt.o \ - arm/mpegvideo_iwmmxt.o \ - -NEON-OBJS-$(CONFIG_FFT) += arm/fft_neon.o \ - -NEON-OBJS-$(CONFIG_MDCT) += arm/mdct_neon.o \ - -NEON-OBJS-$(CONFIG_RDFT) += arm/rdft_neon.o \ - -NEON-OBJS-$(CONFIG_H264DSP) += arm/h264dsp_neon.o \ - arm/h264idct_neon.o \ - arm/h264pred_neon.o \ - -NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \ - arm/synth_filter_neon.o \ - -NEON-OBJS-$(CONFIG_VP3_DECODER) += arm/vp3dsp_neon.o - -NEON-OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_neon.o -NEON-OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_neon.o - -OBJS-$(HAVE_NEON) += arm/dsputil_init_neon.o \ - arm/dsputil_neon.o \ - arm/int_neon.o \ - arm/simple_idct_neon.o \ - $(NEON-OBJS-yes) diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/aac.h b/tizen/distrib/ffmpeg/libavcodec/arm/aac.h deleted file mode 100644 index 390cdbf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/aac.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ARM_AAC_H -#define AVCODEC_ARM_AAC_H - -#include "config.h" - -#if HAVE_NEON && HAVE_INLINE_ASM - -#define VMUL2 VMUL2 -static inline float *VMUL2(float *dst, const float *v, unsigned idx, - const float *scale) -{ - unsigned v0, v1; - __asm__ volatile ("ubfx %0, %4, #0, #4 \n\t" - "ubfx %1, %4, #4, #4 \n\t" - "ldr %0, [%3, %0, lsl #2] \n\t" - "ldr %1, [%3, %1, lsl #2] \n\t" - "vld1.32 {d1[]}, [%5,:32] \n\t" - "vmov d0, %0, %1 \n\t" - "vmul.f32 d0, d0, d1 \n\t" - "vst1.32 {d0}, [%2,:64]! \n\t" - : "=&r"(v0), "=&r"(v1), "+r"(dst) - : "r"(v), "r"(idx), "r"(scale) - : "d0", "d1"); - return dst; -} - -#define VMUL4 VMUL4 -static inline float *VMUL4(float *dst, const float *v, unsigned idx, - const float *scale) -{ - unsigned v0, v1, v2, v3; - __asm__ volatile ("ubfx %0, %6, #0, #2 \n\t" - "ubfx %1, %6, #2, #2 \n\t" - "ldr %0, [%5, %0, lsl #2] \n\t" - "ubfx %2, %6, #4, #2 \n\t" - "ldr %1, [%5, %1, lsl #2] \n\t" - "ubfx %3, %6, #6, #2 \n\t" - "ldr %2, [%5, %2, lsl #2] \n\t" - "vmov d0, %0, %1 \n\t" - "ldr %3, [%5, %3, lsl #2] \n\t" - "vld1.32 {d2[],d3[]},[%7,:32] \n\t" - "vmov d1, %2, %3 \n\t" - "vmul.f32 q0, q0, q1 \n\t" - "vst1.32 {q0}, [%4,:128]! \n\t" - : "=&r"(v0), "=&r"(v1), "=&r"(v2), "=&r"(v3), "+r"(dst) - : "r"(v), "r"(idx), "r"(scale) - : "d0", "d1", "d2", "d3"); - return dst; -} - -#define VMUL2S VMUL2S -static inline float *VMUL2S(float *dst, const float *v, unsigned idx, - unsigned sign, const float *scale) -{ - unsigned v0, v1, v2, v3; - __asm__ volatile ("ubfx %0, %6, #0, #4 \n\t" - "ubfx %1, %6, #4, #4 \n\t" - "ldr %0, [%5, %0, lsl #2] \n\t" - "lsl %2, %8, #30 \n\t" - "ldr %1, [%5, %1, lsl #2] \n\t" - "lsl %3, %8, #31 \n\t" - "vmov d0, %0, %1 \n\t" - "bic %2, %2, #1<<30 \n\t" - "vld1.32 {d1[]}, [%7,:32] \n\t" - "vmov d2, %2, %3 \n\t" - "veor d0, d0, d2 \n\t" - "vmul.f32 d0, d0, d1 \n\t" - "vst1.32 {d0}, [%4,:64]! \n\t" - : "=&r"(v0), "=&r"(v1), "=&r"(v2), "=&r"(v3), "+r"(dst) - : "r"(v), "r"(idx), "r"(scale), "r"(sign) - : "d0", "d1", "d2"); - return dst; -} - -#define VMUL4S VMUL4S -static inline float *VMUL4S(float *dst, const float *v, unsigned idx, - unsigned sign, const float *scale) -{ - unsigned v0, v1, v2, v3, nz; - __asm__ volatile ("vld1.32 {d2[],d3[]},[%9,:32] \n\t" - "ubfx %0, %8, #0, #2 \n\t" - "ubfx %1, %8, #2, #2 \n\t" - "ldr %0, [%7, %0, lsl #2] \n\t" - "ubfx %2, %8, #4, #2 \n\t" - "ldr %1, [%7, %1, lsl #2] \n\t" - "ubfx %3, %8, #6, #2 \n\t" - "ldr %2, [%7, %2, lsl #2] \n\t" - "vmov d0, %0, %1 \n\t" - "ldr %3, [%7, %3, lsl #2] \n\t" - "lsr %6, %8, #12 \n\t" - "rbit %6, %6 \n\t" - "vmov d1, %2, %3 \n\t" - "lsls %6, %6, #1 \n\t" - "and %0, %5, #1<<31 \n\t" - "lslcs %5, %5, #1 \n\t" - "lsls %6, %6, #1 \n\t" - "and %1, %5, #1<<31 \n\t" - "lslcs %5, %5, #1 \n\t" - "lsls %6, %6, #1 \n\t" - "and %2, %5, #1<<31 \n\t" - "lslcs %5, %5, #1 \n\t" - "vmov d4, %0, %1 \n\t" - "and %3, %5, #1<<31 \n\t" - "vmov d5, %2, %3 \n\t" - "veor q0, q0, q2 \n\t" - "vmul.f32 q0, q0, q1 \n\t" - "vst1.32 {q0}, [%4,:128]! \n\t" - : "=&r"(v0), "=&r"(v1), "=&r"(v2), "=&r"(v3), "+r"(dst), - "+r"(sign), "=r"(nz) - : "r"(v), "r"(idx), "r"(scale) - : "d0", "d1", "d2", "d3", "d4", "d5"); - return dst; -} - -#endif /* HAVE_NEON && HAVE_INLINE_ASM */ - -#endif /* AVCODEC_ARM_AAC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/asm.S b/tizen/distrib/ffmpeg/libavcodec/arm/asm.S deleted file mode 100644 index 17139b4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/asm.S +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2008 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#ifdef __ELF__ -# define ELF -#else -# define ELF @ -#endif - - .macro require8, val=1 -ELF .eabi_attribute 24, \val - .endm - - .macro preserve8, val=1 -ELF .eabi_attribute 25, \val - .endm - - .macro function name, export=0 - .macro endfunc -ELF .size \name, . - \name - .endfunc - .purgem endfunc - .endm -.if \export - .global EXTERN_ASM\name -EXTERN_ASM\name: -.endif -ELF .type \name, %function - .func \name -\name: - .endm - - .macro movrel rd, val -#if HAVE_ARMV6T2 && !CONFIG_PIC - movw \rd, #:lower16:\val - movt \rd, #:upper16:\val -#else - ldr \rd, =\val -#endif - .endm - -#if HAVE_VFP_ARGS - .eabi_attribute 28, 1 -# define VFP -# define NOVFP @ -#else -# define VFP @ -# define NOVFP -#endif - -#define GLUE(a, b) a ## b -#define JOIN(a, b) GLUE(a, b) -#define X(s) JOIN(EXTERN_ASM, s) diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_init_arm.c b/tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_init_arm.c deleted file mode 100644 index 816718d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_init_arm.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "libavutil/attributes.h" -#include "libavcodec/dcadsp.h" - -void ff_dca_lfe_fir_neon(float *out, const float *in, const float *coefs, - int decifactor, float scale, float bias); - -void av_cold ff_dcadsp_init_arm(DCADSPContext *s) -{ - if (HAVE_NEON) - s->lfe_fir = ff_dca_lfe_fir_neon; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_neon.S deleted file mode 100644 index 19960ab..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dcadsp_neon.S +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -function ff_dca_lfe_fir_neon, export=1 - push {r4-r6,lr} - - add r4, r0, r3, lsl #2 @ out2 - add r5, r2, #256*4-16 @ cf1 - sub r1, r1, #12 - cmp r3, #32 - moveq r6, #256/32 - movne r6, #256/64 -NOVFP vldr d0, [sp, #16] @ scale, bias - mov lr, #-16 -1: - vmov.f32 q2, #0.0 @ v0 - vmov.f32 q3, #0.0 @ v1 - mov r12, r6 -2: - vld1.32 {q8}, [r2,:128]! @ cf0 - vld1.32 {q9}, [r5,:128], lr @ cf1 - vld1.32 {q1}, [r1], lr @ in - subs r12, r12, #4 - vrev64.32 q10, q8 - vmla.f32 q3, q1, q9 - vmla.f32 d4, d2, d21 - vmla.f32 d5, d3, d20 - bne 2b - - add r1, r1, r6, lsl #2 - subs r3, r3, #1 - vadd.f32 d4, d4, d5 - vadd.f32 d6, d6, d7 - vpadd.f32 d4, d4, d6 - vdup.32 d5, d0[1] - vmla.f32 d5, d4, d0[0] - vst1.32 {d5[0]}, [r0,:32]! - vst1.32 {d5[1]}, [r4,:32]! - bne 1b - - pop {r4-r6,pc} -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.S b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.S deleted file mode 100644 index 7ee85e8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.S +++ /dev/null @@ -1,712 +0,0 @@ -@ -@ ARMv4 optimized DSP utils -@ Copyright (c) 2004 AGAWA Koji -@ -@ This file is part of FFmpeg. -@ -@ FFmpeg 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.1 of the License, or (at your option) any later version. -@ -@ FFmpeg 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 FFmpeg; if not, write to the Free Software -@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -@ - -#include "config.h" -#include "asm.S" - - preserve8 - -#if !HAVE_PLD -.macro pld reg -.endm -#endif - -#if HAVE_ARMV5TE -function ff_prefetch_arm, export=1 - subs r2, r2, #1 - pld [r0] - add r0, r0, r1 - bne ff_prefetch_arm - bx lr -endfunc -#endif - -.macro ALIGN_QWORD_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 ALIGN_DWORD 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 ALIGN_DWORD_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 - -.macro JMP_ALIGN tmp, reg - ands \tmp, \reg, #3 - bic \reg, \reg, #3 - beq 1f - subs \tmp, \tmp, #1 - beq 2f - subs \tmp, \tmp, #1 - beq 3f - b 4f -.endm - -@ ---------------------------------------------------------------- - .align 5 -function ff_put_pixels16_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r11, lr} - JMP_ALIGN r5, r1 -1: - ldm r1, {r4-r7} - add r1, r1, r2 - stm r0, {r4-r7} - pld [r1] - subs r3, r3, #1 - add r0, r0, r2 - bne 1b - pop {r4-r11, pc} - .align 5 -2: - ldm r1, {r4-r8} - add r1, r1, r2 - ALIGN_QWORD_D 1, r9, r10, r11, r12, r4, r5, r6, r7, r8 - pld [r1] - subs r3, r3, #1 - stm r0, {r9-r12} - add r0, r0, r2 - bne 2b - pop {r4-r11, pc} - .align 5 -3: - ldm r1, {r4-r8} - add r1, r1, r2 - ALIGN_QWORD_D 2, r9, r10, r11, r12, r4, r5, r6, r7, r8 - pld [r1] - subs r3, r3, #1 - stm r0, {r9-r12} - add r0, r0, r2 - bne 3b - pop {r4-r11, pc} - .align 5 -4: - ldm r1, {r4-r8} - add r1, r1, r2 - ALIGN_QWORD_D 3, r9, r10, r11, r12, r4, r5, r6, r7, r8 - pld [r1] - subs r3, r3, #1 - stm r0, {r9-r12} - add r0, r0, r2 - bne 4b - pop {r4-r11,pc} -endfunc - -@ ---------------------------------------------------------------- - .align 5 -function ff_put_pixels8_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r5,lr} - JMP_ALIGN r5, r1 -1: - ldm r1, {r4-r5} - add r1, r1, r2 - subs r3, r3, #1 - pld [r1] - stm r0, {r4-r5} - add r0, r0, r2 - bne 1b - pop {r4-r5,pc} - .align 5 -2: - ldm r1, {r4-r5, r12} - add r1, r1, r2 - ALIGN_DWORD 1, r4, r5, r12 - pld [r1] - subs r3, r3, #1 - stm r0, {r4-r5} - add r0, r0, r2 - bne 2b - pop {r4-r5,pc} - .align 5 -3: - ldm r1, {r4-r5, r12} - add r1, r1, r2 - ALIGN_DWORD 2, r4, r5, r12 - pld [r1] - subs r3, r3, #1 - stm r0, {r4-r5} - add r0, r0, r2 - bne 3b - pop {r4-r5,pc} - .align 5 -4: - ldm r1, {r4-r5, r12} - add r1, r1, r2 - ALIGN_DWORD 3, r4, r5, r12 - pld [r1] - subs r3, r3, #1 - stm r0, {r4-r5} - add r0, r0, r2 - bne 4b - pop {r4-r5,pc} -endfunc - -@ ---------------------------------------------------------------- - .align 5 -function ff_put_pixels8_x2_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r10,lr} - ldr r12, =0xfefefefe - JMP_ALIGN r5, r1 -1: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 1, r6, r7, r4, r5, r10 - pld [r1] - RND_AVG32 r8, r9, r4, r5, r6, r7, r12 - subs r3, r3, #1 - stm r0, {r8-r9} - add r0, r0, r2 - bne 1b - pop {r4-r10,pc} - .align 5 -2: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 1, r6, r7, r4, r5, r10 - ALIGN_DWORD_D 2, r8, r9, r4, r5, r10 - pld [r1] - RND_AVG32 r4, r5, r6, r7, r8, r9, r12 - subs r3, r3, #1 - stm r0, {r4-r5} - add r0, r0, r2 - bne 2b - pop {r4-r10,pc} - .align 5 -3: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 2, r6, r7, r4, r5, r10 - ALIGN_DWORD_D 3, r8, r9, r4, r5, r10 - pld [r1] - RND_AVG32 r4, r5, r6, r7, r8, r9, r12 - subs r3, r3, #1 - stm r0, {r4-r5} - add r0, r0, r2 - bne 3b - pop {r4-r10,pc} - .align 5 -4: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 3, r6, r7, r4, r5, r10 - pld [r1] - RND_AVG32 r8, r9, r6, r7, r5, r10, r12 - subs r3, r3, #1 - stm r0, {r8-r9} - add r0, r0, r2 - bne 4b - pop {r4-r10,pc} -endfunc - - .align 5 -function ff_put_no_rnd_pixels8_x2_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r10,lr} - ldr r12, =0xfefefefe - JMP_ALIGN r5, r1 -1: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 1, r6, r7, r4, r5, r10 - pld [r1] - NO_RND_AVG32 r8, r9, r4, r5, r6, r7, r12 - subs r3, r3, #1 - stm r0, {r8-r9} - add r0, r0, r2 - bne 1b - pop {r4-r10,pc} - .align 5 -2: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 1, r6, r7, r4, r5, r10 - ALIGN_DWORD_D 2, r8, r9, r4, r5, r10 - pld [r1] - NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 - subs r3, r3, #1 - stm r0, {r4-r5} - add r0, r0, r2 - bne 2b - pop {r4-r10,pc} - .align 5 -3: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 2, r6, r7, r4, r5, r10 - ALIGN_DWORD_D 3, r8, r9, r4, r5, r10 - pld [r1] - NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 - subs r3, r3, #1 - stm r0, {r4-r5} - add r0, r0, r2 - bne 3b - pop {r4-r10,pc} - .align 5 -4: - ldm r1, {r4-r5, r10} - add r1, r1, r2 - ALIGN_DWORD_D 3, r6, r7, r4, r5, r10 - pld [r1] - NO_RND_AVG32 r8, r9, r6, r7, r5, r10, r12 - subs r3, r3, #1 - stm r0, {r8-r9} - add r0, r0, r2 - bne 4b - pop {r4-r10,pc} -endfunc - - -@ ---------------------------------------------------------------- - .align 5 -function ff_put_pixels8_y2_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r11,lr} - mov r3, r3, lsr #1 - ldr r12, =0xfefefefe - JMP_ALIGN r5, r1 -1: - ldm r1, {r4-r5} - add r1, r1, r2 -6: ldm r1, {r6-r7} - add r1, r1, r2 - pld [r1] - RND_AVG32 r8, r9, r4, r5, r6, r7, r12 - ldm r1, {r4-r5} - add r1, r1, r2 - stm r0, {r8-r9} - add r0, r0, r2 - pld [r1] - RND_AVG32 r8, r9, r6, r7, r4, r5, r12 - subs r3, r3, #1 - stm r0, {r8-r9} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} - .align 5 -2: - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 1, r4, r5, r6 -6: ldm r1, {r7-r9} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 1, r7, r8, r9 - RND_AVG32 r10, r11, r4, r5, r7, r8, r12 - stm r0, {r10-r11} - add r0, r0, r2 - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 1, r4, r5, r6 - subs r3, r3, #1 - RND_AVG32 r10, r11, r7, r8, r4, r5, r12 - stm r0, {r10-r11} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} - .align 5 -3: - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 2, r4, r5, r6 -6: ldm r1, {r7-r9} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 2, r7, r8, r9 - RND_AVG32 r10, r11, r4, r5, r7, r8, r12 - stm r0, {r10-r11} - add r0, r0, r2 - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 2, r4, r5, r6 - subs r3, r3, #1 - RND_AVG32 r10, r11, r7, r8, r4, r5, r12 - stm r0, {r10-r11} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} - .align 5 -4: - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 3, r4, r5, r6 -6: ldm r1, {r7-r9} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 3, r7, r8, r9 - RND_AVG32 r10, r11, r4, r5, r7, r8, r12 - stm r0, {r10-r11} - add r0, r0, r2 - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 3, r4, r5, r6 - subs r3, r3, #1 - RND_AVG32 r10, r11, r7, r8, r4, r5, r12 - stm r0, {r10-r11} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} -endfunc - - .align 5 -function ff_put_no_rnd_pixels8_y2_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r11,lr} - mov r3, r3, lsr #1 - ldr r12, =0xfefefefe - JMP_ALIGN r5, r1 -1: - ldm r1, {r4-r5} - add r1, r1, r2 -6: ldm r1, {r6-r7} - add r1, r1, r2 - pld [r1] - NO_RND_AVG32 r8, r9, r4, r5, r6, r7, r12 - ldm r1, {r4-r5} - add r1, r1, r2 - stm r0, {r8-r9} - add r0, r0, r2 - pld [r1] - NO_RND_AVG32 r8, r9, r6, r7, r4, r5, r12 - subs r3, r3, #1 - stm r0, {r8-r9} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} - .align 5 -2: - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 1, r4, r5, r6 -6: ldm r1, {r7-r9} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 1, r7, r8, r9 - NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 - stm r0, {r10-r11} - add r0, r0, r2 - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 1, r4, r5, r6 - subs r3, r3, #1 - NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 - stm r0, {r10-r11} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} - .align 5 -3: - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 2, r4, r5, r6 -6: ldm r1, {r7-r9} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 2, r7, r8, r9 - NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 - stm r0, {r10-r11} - add r0, r0, r2 - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 2, r4, r5, r6 - subs r3, r3, #1 - NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 - stm r0, {r10-r11} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} - .align 5 -4: - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 3, r4, r5, r6 -6: ldm r1, {r7-r9} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 3, r7, r8, r9 - NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 - stm r0, {r10-r11} - add r0, r0, r2 - ldm r1, {r4-r6} - add r1, r1, r2 - pld [r1] - ALIGN_DWORD 3, r4, r5, r6 - subs r3, r3, #1 - NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 - stm r0, {r10-r11} - add r0, r0, r2 - bne 6b - pop {r4-r11,pc} -endfunc - - .ltorg - -@ ---------------------------------------------------------------- -.macro RND_XY2_IT align, rnd - @ l1= (a & 0x03030303) + (b & 0x03030303) ?(+ 0x02020202) - @ h1= ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2) -.if \align == 0 - ldm r1, {r6-r8} -.elseif \align == 3 - ldm r1, {r5-r7} -.else - ldm r1, {r8-r10} -.endif - add r1, r1, r2 - pld [r1] -.if \align == 0 - ALIGN_DWORD_D 1, r4, r5, r6, r7, r8 -.elseif \align == 1 - ALIGN_DWORD_D 1, r4, r5, r8, r9, r10 - ALIGN_DWORD_D 2, r6, r7, r8, r9, r10 -.elseif \align == 2 - ALIGN_DWORD_D 2, r4, r5, r8, r9, r10 - ALIGN_DWORD_D 3, r6, r7, r8, r9, r10 -.elseif \align == 3 - ALIGN_DWORD_D 3, r4, r5, r5, r6, r7 -.endif - ldr r14, =0x03030303 - tst r3, #1 - and r8, r4, r14 - and r9, r5, r14 - and r10, r6, r14 - and r11, r7, r14 - andeq r14, r14, r14, \rnd #1 - add r8, r8, r10 - add r9, r9, r11 - ldr r12, =0xfcfcfcfc >> 2 - addeq r8, r8, r14 - addeq r9, r9, r14 - and r4, r12, r4, lsr #2 - and r5, r12, r5, lsr #2 - and r6, r12, r6, lsr #2 - and r7, r12, r7, lsr #2 - add r10, r4, r6 - add r11, r5, r7 - subs r3, r3, #1 -.endm - -.macro RND_XY2_EXPAND align, rnd - RND_XY2_IT \align, \rnd -6: push {r8-r11} - RND_XY2_IT \align, \rnd - pop {r4-r7} - add r4, r4, r8 - add r5, r5, r9 - ldr r14, =0x0f0f0f0f - add r6, r6, r10 - add r7, r7, r11 - and r4, r14, r4, lsr #2 - and r5, r14, r5, lsr #2 - add r4, r4, r6 - add r5, r5, r7 - stm r0, {r4-r5} - add r0, r0, r2 - bge 6b - pop {r4-r11,pc} -.endm - - .align 5 -function ff_put_pixels8_xy2_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r11,lr} @ R14 is also called LR - JMP_ALIGN r5, r1 -1: RND_XY2_EXPAND 0, lsl - .align 5 -2: RND_XY2_EXPAND 1, lsl - .align 5 -3: RND_XY2_EXPAND 2, lsl - .align 5 -4: RND_XY2_EXPAND 3, lsl -endfunc - - .align 5 -function ff_put_no_rnd_pixels8_xy2_arm, export=1 - @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) - @ block = word aligned, pixles = unaligned - pld [r1] - push {r4-r11,lr} - JMP_ALIGN r5, r1 -1: RND_XY2_EXPAND 0, lsr - .align 5 -2: RND_XY2_EXPAND 1, lsr - .align 5 -3: RND_XY2_EXPAND 2, lsr - .align 5 -4: RND_XY2_EXPAND 3, lsr -endfunc - - .align 5 -@ void ff_add_pixels_clamped_arm(int16_t *block, uint8_t *dest, int stride) -function ff_add_pixels_clamped_arm, export=1 - push {r4-r10} - mov r10, #8 -1: - ldr r4, [r1] /* load dest */ - /* block[0] and block[1]*/ - ldrsh r5, [r0] - ldrsh r7, [r0, #2] - and r6, r4, #0xFF - and r8, r4, #0xFF00 - add r6, r5, r6 - add r8, r7, r8, lsr #8 - mvn r5, r5 - mvn r7, r7 - tst r6, #0x100 - movne r6, r5, lsr #24 - tst r8, #0x100 - movne r8, r7, lsr #24 - mov r9, r6 - ldrsh r5, [r0, #4] /* moved form [A] */ - orr r9, r9, r8, lsl #8 - /* block[2] and block[3] */ - /* [A] */ - ldrsh r7, [r0, #6] - and r6, r4, #0xFF0000 - and r8, r4, #0xFF000000 - add r6, r5, r6, lsr #16 - add r8, r7, r8, lsr #24 - mvn r5, r5 - mvn r7, r7 - tst r6, #0x100 - movne r6, r5, lsr #24 - tst r8, #0x100 - movne r8, r7, lsr #24 - orr r9, r9, r6, lsl #16 - ldr r4, [r1, #4] /* moved form [B] */ - orr r9, r9, r8, lsl #24 - /* store dest */ - ldrsh r5, [r0, #8] /* moved form [C] */ - str r9, [r1] - - /* load dest */ - /* [B] */ - /* block[4] and block[5] */ - /* [C] */ - ldrsh r7, [r0, #10] - and r6, r4, #0xFF - and r8, r4, #0xFF00 - add r6, r5, r6 - add r8, r7, r8, lsr #8 - mvn r5, r5 - mvn r7, r7 - tst r6, #0x100 - movne r6, r5, lsr #24 - tst r8, #0x100 - movne r8, r7, lsr #24 - mov r9, r6 - ldrsh r5, [r0, #12] /* moved from [D] */ - orr r9, r9, r8, lsl #8 - /* block[6] and block[7] */ - /* [D] */ - ldrsh r7, [r0, #14] - and r6, r4, #0xFF0000 - and r8, r4, #0xFF000000 - add r6, r5, r6, lsr #16 - add r8, r7, r8, lsr #24 - mvn r5, r5 - mvn r7, r7 - tst r6, #0x100 - movne r6, r5, lsr #24 - tst r8, #0x100 - movne r8, r7, lsr #24 - orr r9, r9, r6, lsl #16 - add r0, r0, #16 /* moved from [E] */ - orr r9, r9, r8, lsl #24 - subs r10, r10, #1 /* moved from [F] */ - /* store dest */ - str r9, [r1, #4] - - /* [E] */ - /* [F] */ - add r1, r1, r2 - bne 1b - - pop {r4-r10} - bx lr -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.h b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.h deleted file mode 100644 index 7f8579d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_arm.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ARM_DSPUTIL_H -#define AVCODEC_ARM_DSPUTIL_H - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" - -void ff_dsputil_init_armv5te(DSPContext* c, AVCodecContext *avctx); -void ff_dsputil_init_armv6(DSPContext* c, AVCodecContext *avctx); -void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx); -void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx); -void ff_dsputil_init_iwmmxt(DSPContext* c, AVCodecContext *avctx); - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_armv6.S b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_armv6.S deleted file mode 100644 index 214d947..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_armv6.S +++ /dev/null @@ -1,623 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - preserve8 - - .text - -.macro call_2x_pixels type, subp -function ff_\type\()_pixels16\subp\()_armv6, export=1 - push {r0-r3, lr} - bl ff_\type\()_pixels8\subp\()_armv6 - pop {r0-r3, lr} - add r0, r0, #8 - add r1, r1, #8 - b ff_\type\()_pixels8\subp\()_armv6 -endfunc -.endm - -call_2x_pixels avg -call_2x_pixels put, _x2 -call_2x_pixels put, _y2 -call_2x_pixels put, _x2_no_rnd -call_2x_pixels put, _y2_no_rnd - -function ff_put_pixels16_armv6, export=1 - push {r4-r11} -1: - ldr r5, [r1, #4] - ldr r6, [r1, #8] - ldr r7, [r1, #12] - ldr r4, [r1], r2 - strd r6, r7, [r0, #8] - ldr r9, [r1, #4] - strd r4, r5, [r0], r2 - ldr r10, [r1, #8] - ldr r11, [r1, #12] - ldr r8, [r1], r2 - strd r10, r11, [r0, #8] - subs r3, r3, #2 - strd r8, r9, [r0], r2 - bne 1b - - pop {r4-r11} - bx lr -endfunc - -function ff_put_pixels8_armv6, export=1 - push {r4-r7} -1: - ldr r5, [r1, #4] - ldr r4, [r1], r2 - ldr r7, [r1, #4] - strd r4, r5, [r0], r2 - ldr r6, [r1], r2 - subs r3, r3, #2 - strd r6, r7, [r0], r2 - bne 1b - - pop {r4-r7} - bx lr -endfunc - -function ff_put_pixels8_x2_armv6, export=1 - push {r4-r11, lr} - mov r12, #1 - orr r12, r12, r12, lsl #8 - orr r12, r12, r12, lsl #16 -1: - ldr r4, [r1] - subs r3, r3, #2 - ldr r5, [r1, #4] - ldr r7, [r1, #5] - lsr r6, r4, #8 - ldr r8, [r1, r2]! - orr r6, r6, r5, lsl #24 - ldr r9, [r1, #4] - ldr r11, [r1, #5] - lsr r10, r8, #8 - add r1, r1, r2 - orr r10, r10, r9, lsl #24 - eor r14, r4, r6 - uhadd8 r4, r4, r6 - eor r6, r5, r7 - uhadd8 r5, r5, r7 - and r14, r14, r12 - and r6, r6, r12 - uadd8 r4, r4, r14 - eor r14, r8, r10 - uadd8 r5, r5, r6 - eor r6, r9, r11 - uhadd8 r8, r8, r10 - and r14, r14, r12 - uhadd8 r9, r9, r11 - and r6, r6, r12 - uadd8 r8, r8, r14 - strd r4, r5, [r0], r2 - uadd8 r9, r9, r6 - strd r8, r9, [r0], r2 - bne 1b - - pop {r4-r11, pc} -endfunc - -function ff_put_pixels8_y2_armv6, export=1 - push {r4-r11} - mov r12, #1 - orr r12, r12, r12, lsl #8 - orr r12, r12, r12, lsl #16 - ldr r4, [r1] - ldr r5, [r1, #4] - ldr r6, [r1, r2]! - ldr r7, [r1, #4] -1: - subs r3, r3, #2 - uhadd8 r8, r4, r6 - eor r10, r4, r6 - uhadd8 r9, r5, r7 - eor r11, r5, r7 - and r10, r10, r12 - ldr r4, [r1, r2]! - uadd8 r8, r8, r10 - and r11, r11, r12 - uadd8 r9, r9, r11 - ldr r5, [r1, #4] - uhadd8 r10, r4, r6 - eor r6, r4, r6 - uhadd8 r11, r5, r7 - and r6, r6, r12 - eor r7, r5, r7 - uadd8 r10, r10, r6 - and r7, r7, r12 - ldr r6, [r1, r2]! - uadd8 r11, r11, r7 - strd r8, r9, [r0], r2 - ldr r7, [r1, #4] - strd r10, r11, [r0], r2 - bne 1b - - pop {r4-r11} - bx lr -endfunc - -function ff_put_pixels8_x2_no_rnd_armv6, export=1 - push {r4-r9, lr} -1: - subs r3, r3, #2 - ldr r4, [r1] - ldr r5, [r1, #4] - ldr r7, [r1, #5] - ldr r8, [r1, r2]! - ldr r9, [r1, #4] - ldr r14, [r1, #5] - add r1, r1, r2 - lsr r6, r4, #8 - orr r6, r6, r5, lsl #24 - lsr r12, r8, #8 - orr r12, r12, r9, lsl #24 - uhadd8 r4, r4, r6 - uhadd8 r5, r5, r7 - uhadd8 r8, r8, r12 - uhadd8 r9, r9, r14 - stm r0, {r4,r5} - add r0, r0, r2 - stm r0, {r8,r9} - add r0, r0, r2 - bne 1b - - pop {r4-r9, pc} -endfunc - -function ff_put_pixels8_y2_no_rnd_armv6, export=1 - push {r4-r9, lr} - ldr r4, [r1] - ldr r5, [r1, #4] - ldr r6, [r1, r2]! - ldr r7, [r1, #4] -1: - subs r3, r3, #2 - uhadd8 r8, r4, r6 - ldr r4, [r1, r2]! - uhadd8 r9, r5, r7 - ldr r5, [r1, #4] - uhadd8 r12, r4, r6 - ldr r6, [r1, r2]! - uhadd8 r14, r5, r7 - ldr r7, [r1, #4] - stm r0, {r8,r9} - add r0, r0, r2 - stm r0, {r12,r14} - add r0, r0, r2 - bne 1b - - pop {r4-r9, pc} -endfunc - -function ff_avg_pixels8_armv6, export=1 - pld [r1, r2] - push {r4-r10, lr} - mov lr, #1 - orr lr, lr, lr, lsl #8 - orr lr, lr, lr, lsl #16 - ldrd r4, r5, [r0] - ldr r10, [r1, #4] - ldr r9, [r1], r2 - subs r3, r3, #2 -1: - pld [r1, r2] - eor r8, r4, r9 - uhadd8 r4, r4, r9 - eor r12, r5, r10 - ldrd r6, r7, [r0, r2] - uhadd8 r5, r5, r10 - and r8, r8, lr - ldr r10, [r1, #4] - and r12, r12, lr - uadd8 r4, r4, r8 - ldr r9, [r1], r2 - eor r8, r6, r9 - uadd8 r5, r5, r12 - pld [r1, r2, lsl #1] - eor r12, r7, r10 - uhadd8 r6, r6, r9 - strd r4, r5, [r0], r2 - uhadd8 r7, r7, r10 - beq 2f - and r8, r8, lr - ldrd r4, r5, [r0, r2] - uadd8 r6, r6, r8 - ldr r10, [r1, #4] - and r12, r12, lr - subs r3, r3, #2 - uadd8 r7, r7, r12 - ldr r9, [r1], r2 - strd r6, r7, [r0], r2 - b 1b -2: - and r8, r8, lr - and r12, r12, lr - uadd8 r6, r6, r8 - uadd8 r7, r7, r12 - strd r6, r7, [r0], r2 - - pop {r4-r10, pc} -endfunc - -function ff_add_pixels_clamped_armv6, export=1 - push {r4-r8,lr} - mov r3, #8 -1: - ldm r0!, {r4,r5,r12,lr} - ldrd r6, r7, [r1] - pkhbt r8, r4, r5, lsl #16 - pkhtb r5, r5, r4, asr #16 - pkhbt r4, r12, lr, lsl #16 - pkhtb lr, lr, r12, asr #16 - pld [r1, r2] - uxtab16 r8, r8, r6 - uxtab16 r5, r5, r6, ror #8 - uxtab16 r4, r4, r7 - uxtab16 lr, lr, r7, ror #8 - usat16 r8, #8, r8 - usat16 r5, #8, r5 - usat16 r4, #8, r4 - usat16 lr, #8, lr - orr r6, r8, r5, lsl #8 - orr r7, r4, lr, lsl #8 - subs r3, r3, #1 - strd r6, r7, [r1], r2 - bgt 1b - pop {r4-r8,pc} -endfunc - -function ff_get_pixels_armv6, export=1 - pld [r1, r2] - push {r4-r8, lr} - mov lr, #8 -1: - ldrd r4, r5, [r1], r2 - subs lr, lr, #1 - uxtb16 r6, r4 - uxtb16 r4, r4, ror #8 - uxtb16 r12, r5 - uxtb16 r8, r5, ror #8 - pld [r1, r2] - pkhbt r5, r6, r4, lsl #16 - pkhtb r6, r4, r6, asr #16 - pkhbt r7, r12, r8, lsl #16 - pkhtb r12, r8, r12, asr #16 - stm r0!, {r5,r6,r7,r12} - bgt 1b - - pop {r4-r8, pc} -endfunc - -function ff_diff_pixels_armv6, export=1 - pld [r1, r3] - pld [r2, r3] - push {r4-r9, lr} - mov lr, #8 -1: - ldrd r4, r5, [r1], r3 - ldrd r6, r7, [r2], r3 - uxtb16 r8, r4 - uxtb16 r4, r4, ror #8 - uxtb16 r9, r6 - uxtb16 r6, r6, ror #8 - pld [r1, r3] - ssub16 r9, r8, r9 - ssub16 r6, r4, r6 - uxtb16 r8, r5 - uxtb16 r5, r5, ror #8 - pld [r2, r3] - pkhbt r4, r9, r6, lsl #16 - pkhtb r6, r6, r9, asr #16 - uxtb16 r9, r7 - uxtb16 r7, r7, ror #8 - ssub16 r9, r8, r9 - ssub16 r5, r5, r7 - subs lr, lr, #1 - pkhbt r8, r9, r5, lsl #16 - pkhtb r9, r5, r9, asr #16 - stm r0!, {r4,r6,r8,r9} - bgt 1b - - pop {r4-r9, pc} -endfunc - -function ff_pix_abs16_armv6, export=1 - ldr r0, [sp] - push {r4-r9, lr} - mov r12, #0 - mov lr, #0 - ldm r1, {r4-r7} - ldr r8, [r2] -1: - ldr r9, [r2, #4] - pld [r1, r3] - usada8 r12, r4, r8, r12 - ldr r8, [r2, #8] - pld [r2, r3] - usada8 lr, r5, r9, lr - ldr r9, [r2, #12] - usada8 r12, r6, r8, r12 - subs r0, r0, #1 - usada8 lr, r7, r9, lr - beq 2f - add r1, r1, r3 - ldm r1, {r4-r7} - add r2, r2, r3 - ldr r8, [r2] - b 1b -2: - add r0, r12, lr - pop {r4-r9, pc} -endfunc - -function ff_pix_abs16_x2_armv6, export=1 - ldr r12, [sp] - push {r4-r11, lr} - mov r0, #0 - mov lr, #1 - orr lr, lr, lr, lsl #8 - orr lr, lr, lr, lsl #16 -1: - ldr r8, [r2] - ldr r9, [r2, #4] - lsr r10, r8, #8 - ldr r4, [r1] - lsr r6, r9, #8 - orr r10, r10, r9, lsl #24 - ldr r5, [r2, #8] - eor r11, r8, r10 - uhadd8 r7, r8, r10 - orr r6, r6, r5, lsl #24 - and r11, r11, lr - uadd8 r7, r7, r11 - ldr r8, [r1, #4] - usada8 r0, r4, r7, r0 - eor r7, r9, r6 - lsr r10, r5, #8 - and r7, r7, lr - uhadd8 r4, r9, r6 - ldr r6, [r2, #12] - uadd8 r4, r4, r7 - pld [r1, r3] - orr r10, r10, r6, lsl #24 - usada8 r0, r8, r4, r0 - ldr r4, [r1, #8] - eor r11, r5, r10 - ldrb r7, [r2, #16] - and r11, r11, lr - uhadd8 r8, r5, r10 - ldr r5, [r1, #12] - uadd8 r8, r8, r11 - pld [r2, r3] - lsr r10, r6, #8 - usada8 r0, r4, r8, r0 - orr r10, r10, r7, lsl #24 - subs r12, r12, #1 - eor r11, r6, r10 - add r1, r1, r3 - uhadd8 r9, r6, r10 - and r11, r11, lr - uadd8 r9, r9, r11 - add r2, r2, r3 - usada8 r0, r5, r9, r0 - bgt 1b - - pop {r4-r11, pc} -endfunc - -.macro usad_y2 p0, p1, p2, p3, n0, n1, n2, n3 - ldr \n0, [r2] - eor \n1, \p0, \n0 - uhadd8 \p0, \p0, \n0 - and \n1, \n1, lr - ldr \n2, [r1] - uadd8 \p0, \p0, \n1 - ldr \n1, [r2, #4] - usada8 r0, \p0, \n2, r0 - pld [r1, r3] - eor \n3, \p1, \n1 - uhadd8 \p1, \p1, \n1 - and \n3, \n3, lr - ldr \p0, [r1, #4] - uadd8 \p1, \p1, \n3 - ldr \n2, [r2, #8] - usada8 r0, \p1, \p0, r0 - pld [r2, r3] - eor \p0, \p2, \n2 - uhadd8 \p2, \p2, \n2 - and \p0, \p0, lr - ldr \p1, [r1, #8] - uadd8 \p2, \p2, \p0 - ldr \n3, [r2, #12] - usada8 r0, \p2, \p1, r0 - eor \p1, \p3, \n3 - uhadd8 \p3, \p3, \n3 - and \p1, \p1, lr - ldr \p0, [r1, #12] - uadd8 \p3, \p3, \p1 - add r1, r1, r3 - usada8 r0, \p3, \p0, r0 - add r2, r2, r3 -.endm - -function ff_pix_abs16_y2_armv6, export=1 - pld [r1] - pld [r2] - ldr r12, [sp] - push {r4-r11, lr} - mov r0, #0 - mov lr, #1 - orr lr, lr, lr, lsl #8 - orr lr, lr, lr, lsl #16 - ldr r4, [r2] - ldr r5, [r2, #4] - ldr r6, [r2, #8] - ldr r7, [r2, #12] - add r2, r2, r3 -1: - usad_y2 r4, r5, r6, r7, r8, r9, r10, r11 - subs r12, r12, #2 - usad_y2 r8, r9, r10, r11, r4, r5, r6, r7 - bgt 1b - - pop {r4-r11, pc} -endfunc - -function ff_pix_abs8_armv6, export=1 - pld [r2, r3] - ldr r12, [sp] - push {r4-r9, lr} - mov r0, #0 - mov lr, #0 - ldrd r4, r5, [r1], r3 -1: - subs r12, r12, #2 - ldr r7, [r2, #4] - ldr r6, [r2], r3 - ldrd r8, r9, [r1], r3 - usada8 r0, r4, r6, r0 - pld [r2, r3] - usada8 lr, r5, r7, lr - ldr r7, [r2, #4] - ldr r6, [r2], r3 - beq 2f - ldrd r4, r5, [r1], r3 - usada8 r0, r8, r6, r0 - pld [r2, r3] - usada8 lr, r9, r7, lr - b 1b -2: - usada8 r0, r8, r6, r0 - usada8 lr, r9, r7, lr - add r0, r0, lr - pop {r4-r9, pc} -endfunc - -function ff_sse16_armv6, export=1 - ldr r12, [sp] - push {r4-r9, lr} - mov r0, #0 -1: - ldrd r4, r5, [r1] - ldr r8, [r2] - uxtb16 lr, r4 - uxtb16 r4, r4, ror #8 - uxtb16 r9, r8 - uxtb16 r8, r8, ror #8 - ldr r7, [r2, #4] - usub16 lr, lr, r9 - usub16 r4, r4, r8 - smlad r0, lr, lr, r0 - uxtb16 r6, r5 - uxtb16 lr, r5, ror #8 - uxtb16 r8, r7 - uxtb16 r9, r7, ror #8 - smlad r0, r4, r4, r0 - ldrd r4, r5, [r1, #8] - usub16 r6, r6, r8 - usub16 r8, lr, r9 - ldr r7, [r2, #8] - smlad r0, r6, r6, r0 - uxtb16 lr, r4 - uxtb16 r4, r4, ror #8 - uxtb16 r9, r7 - uxtb16 r7, r7, ror #8 - smlad r0, r8, r8, r0 - ldr r8, [r2, #12] - usub16 lr, lr, r9 - usub16 r4, r4, r7 - smlad r0, lr, lr, r0 - uxtb16 r6, r5 - uxtb16 r5, r5, ror #8 - uxtb16 r9, r8 - uxtb16 r8, r8, ror #8 - smlad r0, r4, r4, r0 - usub16 r6, r6, r9 - usub16 r5, r5, r8 - smlad r0, r6, r6, r0 - add r1, r1, r3 - add r2, r2, r3 - subs r12, r12, #1 - smlad r0, r5, r5, r0 - bgt 1b - - pop {r4-r9, pc} -endfunc - -function ff_pix_norm1_armv6, export=1 - push {r4-r6, lr} - mov r12, #16 - mov lr, #0 -1: - ldm r0, {r2-r5} - uxtb16 r6, r2 - uxtb16 r2, r2, ror #8 - smlad lr, r6, r6, lr - uxtb16 r6, r3 - smlad lr, r2, r2, lr - uxtb16 r3, r3, ror #8 - smlad lr, r6, r6, lr - uxtb16 r6, r4 - smlad lr, r3, r3, lr - uxtb16 r4, r4, ror #8 - smlad lr, r6, r6, lr - uxtb16 r6, r5 - smlad lr, r4, r4, lr - uxtb16 r5, r5, ror #8 - smlad lr, r6, r6, lr - subs r12, r12, #1 - add r0, r0, r1 - smlad lr, r5, r5, lr - bgt 1b - - mov r0, lr - pop {r4-r6, pc} -endfunc - -function ff_pix_sum_armv6, export=1 - push {r4-r7, lr} - mov r12, #16 - mov r2, #0 - mov r3, #0 - mov lr, #0 - ldr r4, [r0] -1: - subs r12, r12, #1 - ldr r5, [r0, #4] - usada8 r2, r4, lr, r2 - ldr r6, [r0, #8] - usada8 r3, r5, lr, r3 - ldr r7, [r0, #12] - usada8 r2, r6, lr, r2 - beq 2f - ldr r4, [r0, r1]! - usada8 r3, r7, lr, r3 - bgt 1b -2: - usada8 r3, r7, lr, r3 - add r0, r2, r3 - pop {r4-r7, pc} -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_arm.c b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_arm.c deleted file mode 100644 index c9c3351..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_arm.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * ARM optimized DSP utils - * Copyright (c) 2001 Lionel Ulmer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_arm.h" - -void ff_j_rev_dct_arm(DCTELEM *data); -void ff_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 ff_put_pixels8_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); -void ff_put_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); -void ff_put_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); -void ff_put_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); - -void ff_put_no_rnd_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); -void ff_put_no_rnd_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); -void ff_put_no_rnd_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); - -void ff_put_pixels16_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); - -CALL_2X_PIXELS(ff_put_pixels16_x2_arm, ff_put_pixels8_x2_arm, 8) -CALL_2X_PIXELS(ff_put_pixels16_y2_arm, ff_put_pixels8_y2_arm, 8) -CALL_2X_PIXELS(ff_put_pixels16_xy2_arm, ff_put_pixels8_xy2_arm, 8) -CALL_2X_PIXELS(ff_put_no_rnd_pixels16_x2_arm, ff_put_no_rnd_pixels8_x2_arm, 8) -CALL_2X_PIXELS(ff_put_no_rnd_pixels16_y2_arm, ff_put_no_rnd_pixels8_y2_arm, 8) -CALL_2X_PIXELS(ff_put_no_rnd_pixels16_xy2_arm, ff_put_no_rnd_pixels8_xy2_arm,8) - -void ff_add_pixels_clamped_arm(const DCTELEM *block, uint8_t *dest, - int line_size); - -/* 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) -{ - ff_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) -{ - ff_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) -{ - ff_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) -{ - ff_simple_idct_arm (block); - ff_add_pixels_clamped(block, dest, line_size); -} - -int mm_support(void) -{ - return HAVE_IWMMXT * FF_MM_IWMMXT; -} - -void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx) -{ - ff_put_pixels_clamped = c->put_pixels_clamped; - ff_add_pixels_clamped = c->add_pixels_clamped; - - if (!avctx->lowres) { - if(avctx->idct_algo == FF_IDCT_AUTO || - avctx->idct_algo == FF_IDCT_ARM){ - c->idct_put = j_rev_dct_arm_put; - c->idct_add = j_rev_dct_arm_add; - c->idct = ff_j_rev_dct_arm; - c->idct_permutation_type = FF_LIBMPEG2_IDCT_PERM; - } else if (avctx->idct_algo == FF_IDCT_SIMPLEARM){ - c->idct_put = simple_idct_arm_put; - c->idct_add = simple_idct_arm_add; - c->idct = ff_simple_idct_arm; - c->idct_permutation_type = FF_NO_IDCT_PERM; - } - } - - c->add_pixels_clamped = ff_add_pixels_clamped_arm; - - c->put_pixels_tab[0][0] = ff_put_pixels16_arm; - c->put_pixels_tab[0][1] = ff_put_pixels16_x2_arm; - c->put_pixels_tab[0][2] = ff_put_pixels16_y2_arm; - c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_arm; - c->put_pixels_tab[1][0] = ff_put_pixels8_arm; - c->put_pixels_tab[1][1] = ff_put_pixels8_x2_arm; - c->put_pixels_tab[1][2] = ff_put_pixels8_y2_arm; - c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_arm; - - c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_arm; - c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_arm; - c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_arm; - c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_arm; - c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_arm; - c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_arm; - c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_arm; - c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_arm; - - if (HAVE_ARMV5TE) ff_dsputil_init_armv5te(c, avctx); - if (HAVE_ARMV6) ff_dsputil_init_armv6(c, avctx); - if (HAVE_IWMMXT) ff_dsputil_init_iwmmxt(c, avctx); - if (HAVE_ARMVFP) ff_dsputil_init_vfp(c, avctx); - if (HAVE_NEON) ff_dsputil_init_neon(c, avctx); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv5te.c b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv5te.c deleted file mode 100644 index 750e514..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv5te.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_arm.h" - -void ff_simple_idct_armv5te(DCTELEM *data); -void ff_simple_idct_put_armv5te(uint8_t *dest, int line_size, DCTELEM *data); -void ff_simple_idct_add_armv5te(uint8_t *dest, int line_size, DCTELEM *data); - -void ff_prefetch_arm(void *mem, int stride, int h); - -void av_cold ff_dsputil_init_armv5te(DSPContext* c, AVCodecContext *avctx) -{ - if (!avctx->lowres && (avctx->idct_algo == FF_IDCT_AUTO || - avctx->idct_algo == FF_IDCT_SIMPLEARMV5TE)) { - c->idct_put = ff_simple_idct_put_armv5te; - c->idct_add = ff_simple_idct_add_armv5te; - c->idct = ff_simple_idct_armv5te; - c->idct_permutation_type = FF_NO_IDCT_PERM; - } - - c->prefetch = ff_prefetch_arm; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv6.c b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv6.c deleted file mode 100644 index 3209062..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_armv6.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "dsputil_arm.h" - -void ff_simple_idct_armv6(DCTELEM *data); -void ff_simple_idct_put_armv6(uint8_t *dest, int line_size, DCTELEM *data); -void ff_simple_idct_add_armv6(uint8_t *dest, int line_size, DCTELEM *data); - -void ff_put_pixels16_armv6(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_x2_armv6(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_y2_armv6(uint8_t *, const uint8_t *, int, int); - -void ff_put_pixels16_x2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_y2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int); - -void ff_avg_pixels16_armv6(uint8_t *, const uint8_t *, int, int); - -void ff_put_pixels8_armv6(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_x2_armv6(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_y2_armv6(uint8_t *, const uint8_t *, int, int); - -void ff_put_pixels8_x2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_y2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int); - -void ff_avg_pixels8_armv6(uint8_t *, const uint8_t *, int, int); - -void ff_add_pixels_clamped_armv6(const DCTELEM *block, - uint8_t *restrict pixels, - int line_size); - -void ff_get_pixels_armv6(DCTELEM *block, const uint8_t *pixels, int stride); -void ff_diff_pixels_armv6(DCTELEM *block, const uint8_t *s1, - const uint8_t *s2, int stride); - -int ff_pix_abs16_armv6(void *s, uint8_t *blk1, uint8_t *blk2, - int line_size, int h); -int ff_pix_abs16_x2_armv6(void *s, uint8_t *blk1, uint8_t *blk2, - int line_size, int h); -int ff_pix_abs16_y2_armv6(void *s, uint8_t *blk1, uint8_t *blk2, - int line_size, int h); - -int ff_pix_abs8_armv6(void *s, uint8_t *blk1, uint8_t *blk2, - int line_size, int h); - -int ff_sse16_armv6(void *s, uint8_t *blk1, uint8_t *blk2, - int line_size, int h); - -int ff_pix_norm1_armv6(uint8_t *pix, int line_size); -int ff_pix_sum_armv6(uint8_t *pix, int line_size); - -void av_cold ff_dsputil_init_armv6(DSPContext* c, AVCodecContext *avctx) -{ - if (!avctx->lowres && (avctx->idct_algo == FF_IDCT_AUTO || - avctx->idct_algo == FF_IDCT_SIMPLEARMV6)) { - c->idct_put = ff_simple_idct_put_armv6; - c->idct_add = ff_simple_idct_add_armv6; - c->idct = ff_simple_idct_armv6; - c->idct_permutation_type = FF_LIBMPEG2_IDCT_PERM; - } - - c->put_pixels_tab[0][0] = ff_put_pixels16_armv6; - c->put_pixels_tab[0][1] = ff_put_pixels16_x2_armv6; - c->put_pixels_tab[0][2] = ff_put_pixels16_y2_armv6; -/* c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_armv6; */ - c->put_pixels_tab[1][0] = ff_put_pixels8_armv6; - c->put_pixels_tab[1][1] = ff_put_pixels8_x2_armv6; - c->put_pixels_tab[1][2] = ff_put_pixels8_y2_armv6; -/* c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_armv6; */ - - c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_armv6; - c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_armv6; - c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_armv6; -/* c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_armv6; */ - c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_armv6; - c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_armv6; - c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_armv6; -/* c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_armv6; */ - - c->avg_pixels_tab[0][0] = ff_avg_pixels16_armv6; - c->avg_pixels_tab[1][0] = ff_avg_pixels8_armv6; - - c->add_pixels_clamped = ff_add_pixels_clamped_armv6; - c->get_pixels = ff_get_pixels_armv6; - c->diff_pixels = ff_diff_pixels_armv6; - - c->pix_abs[0][0] = ff_pix_abs16_armv6; - c->pix_abs[0][1] = ff_pix_abs16_x2_armv6; - c->pix_abs[0][2] = ff_pix_abs16_y2_armv6; - - c->pix_abs[1][0] = ff_pix_abs8_armv6; - - c->sad[0] = ff_pix_abs16_armv6; - c->sad[1] = ff_pix_abs8_armv6; - - c->sse[0] = ff_sse16_armv6; - - c->pix_norm1 = ff_pix_norm1_armv6; - c->pix_sum = ff_pix_sum_armv6; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_neon.c b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_neon.c deleted file mode 100644 index 0e44160..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_neon.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * ARM NEON optimised DSP functions - * Copyright (c) 2008 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "dsputil_arm.h" - -void ff_simple_idct_neon(DCTELEM *data); -void ff_simple_idct_put_neon(uint8_t *dest, int line_size, DCTELEM *data); -void ff_simple_idct_add_neon(uint8_t *dest, int line_size, DCTELEM *data); - -void ff_vp3_idct_neon(DCTELEM *data); -void ff_vp3_idct_put_neon(uint8_t *dest, int line_size, DCTELEM *data); -void ff_vp3_idct_add_neon(uint8_t *dest, int line_size, DCTELEM *data); -void ff_vp3_idct_dc_add_neon(uint8_t *dest, int line_size, const DCTELEM *data); - -void ff_put_pixels16_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_x2_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_y2_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_xy2_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_x2_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_y2_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_xy2_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int); -void ff_put_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int); - -void ff_avg_pixels16_neon(uint8_t *, const uint8_t *, int, int); -void ff_avg_pixels8_neon(uint8_t *, const uint8_t *, int, int); - -void ff_add_pixels_clamped_neon(const DCTELEM *, uint8_t *, int); -void ff_put_pixels_clamped_neon(const DCTELEM *, uint8_t *, int); -void ff_put_signed_pixels_clamped_neon(const DCTELEM *, uint8_t *, int); - -void ff_put_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int); - -void ff_put_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int); -void ff_put_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int); - -void ff_avg_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int); - -void ff_avg_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int); -void ff_avg_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int); - -void ff_put_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_put_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_put_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int); - -void ff_avg_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_avg_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int); -void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int); - -void ff_vp3_v_loop_filter_neon(uint8_t *, int, int *); -void ff_vp3_h_loop_filter_neon(uint8_t *, int, int *); - -void ff_vector_fmul_neon(float *dst, const float *src, int len); -void ff_vector_fmul_window_neon(float *dst, const float *src0, - const float *src1, const float *win, - float add_bias, int len); -void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, - int len); -void ff_vector_fmul_sv_scalar_2_neon(float *dst, const float *src, - const float **vp, float mul, int len); -void ff_vector_fmul_sv_scalar_4_neon(float *dst, const float *src, - const float **vp, float mul, int len); -void ff_sv_fmul_scalar_2_neon(float *dst, const float **vp, float mul, - int len); -void ff_sv_fmul_scalar_4_neon(float *dst, const float **vp, float mul, - int len); -void ff_butterflies_float_neon(float *v1, float *v2, int len); -float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); -void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src, - float mul, int len); -void ff_vector_fmul_reverse_neon(float *dst, const float *src0, - const float *src1, int len); -void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, - const float *src2, int len); - -void ff_vector_clipf_neon(float *dst, const float *src, float min, float max, - int len); -void ff_float_to_int16_neon(int16_t *, const float *, long); -void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int); - -void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, int blocksize); - -int32_t ff_scalarproduct_int16_neon(int16_t *v1, int16_t *v2, int len, - int shift); -int32_t ff_scalarproduct_and_madd_int16_neon(int16_t *v1, int16_t *v2, - int16_t *v3, int len, int mul); - -void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) -{ - if (!avctx->lowres) { - if (avctx->idct_algo == FF_IDCT_AUTO || - avctx->idct_algo == FF_IDCT_SIMPLENEON) { - c->idct_put = ff_simple_idct_put_neon; - c->idct_add = ff_simple_idct_add_neon; - c->idct = ff_simple_idct_neon; - c->idct_permutation_type = FF_PARTTRANS_IDCT_PERM; - } else if ((CONFIG_VP3_DECODER || CONFIG_VP5_DECODER || - CONFIG_VP6_DECODER) && - avctx->idct_algo == FF_IDCT_VP3) { - c->idct_put = ff_vp3_idct_put_neon; - c->idct_add = ff_vp3_idct_add_neon; - c->idct = ff_vp3_idct_neon; - c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; - } - } - - c->put_pixels_tab[0][0] = ff_put_pixels16_neon; - c->put_pixels_tab[0][1] = ff_put_pixels16_x2_neon; - c->put_pixels_tab[0][2] = ff_put_pixels16_y2_neon; - c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_neon; - c->put_pixels_tab[1][0] = ff_put_pixels8_neon; - c->put_pixels_tab[1][1] = ff_put_pixels8_x2_neon; - c->put_pixels_tab[1][2] = ff_put_pixels8_y2_neon; - c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_neon; - - c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_neon; - c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_neon; - c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_neon; - c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_neon; - c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_neon; - c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_neon; - c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_neon; - c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_neon; - - c->avg_pixels_tab[0][0] = ff_avg_pixels16_neon; - c->avg_pixels_tab[1][0] = ff_avg_pixels8_neon; - - c->add_pixels_clamped = ff_add_pixels_clamped_neon; - c->put_pixels_clamped = ff_put_pixels_clamped_neon; - c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon; - - if (CONFIG_H264_DECODER) { - c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon; - c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon; - c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_neon; - - c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_neon; - c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_neon; - c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_neon; - - c->put_h264_qpel_pixels_tab[0][ 0] = ff_put_h264_qpel16_mc00_neon; - c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon; - c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon; - c->put_h264_qpel_pixels_tab[0][ 3] = ff_put_h264_qpel16_mc30_neon; - c->put_h264_qpel_pixels_tab[0][ 4] = ff_put_h264_qpel16_mc01_neon; - c->put_h264_qpel_pixels_tab[0][ 5] = ff_put_h264_qpel16_mc11_neon; - c->put_h264_qpel_pixels_tab[0][ 6] = ff_put_h264_qpel16_mc21_neon; - c->put_h264_qpel_pixels_tab[0][ 7] = ff_put_h264_qpel16_mc31_neon; - c->put_h264_qpel_pixels_tab[0][ 8] = ff_put_h264_qpel16_mc02_neon; - c->put_h264_qpel_pixels_tab[0][ 9] = ff_put_h264_qpel16_mc12_neon; - c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_neon; - c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_neon; - c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_neon; - c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_neon; - c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_neon; - c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon; - - c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon; - c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon; - c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_neon; - c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon; - c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon; - c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon; - c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon; - c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon; - c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon; - c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon; - c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon; - c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon; - c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon; - c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon; - c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon; - c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon; - - c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon; - c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon; - c->avg_h264_qpel_pixels_tab[0][ 2] = ff_avg_h264_qpel16_mc20_neon; - c->avg_h264_qpel_pixels_tab[0][ 3] = ff_avg_h264_qpel16_mc30_neon; - c->avg_h264_qpel_pixels_tab[0][ 4] = ff_avg_h264_qpel16_mc01_neon; - c->avg_h264_qpel_pixels_tab[0][ 5] = ff_avg_h264_qpel16_mc11_neon; - c->avg_h264_qpel_pixels_tab[0][ 6] = ff_avg_h264_qpel16_mc21_neon; - c->avg_h264_qpel_pixels_tab[0][ 7] = ff_avg_h264_qpel16_mc31_neon; - c->avg_h264_qpel_pixels_tab[0][ 8] = ff_avg_h264_qpel16_mc02_neon; - c->avg_h264_qpel_pixels_tab[0][ 9] = ff_avg_h264_qpel16_mc12_neon; - c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_neon; - c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_neon; - c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_neon; - c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_neon; - c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_neon; - c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon; - - c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon; - c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon; - c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon; - c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon; - c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon; - c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon; - c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon; - c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon; - c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon; - c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon; - c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon; - c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon; - c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon; - c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon; - c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon; - c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon; - } - - if (CONFIG_VP3_DECODER) { - c->vp3_v_loop_filter = ff_vp3_v_loop_filter_neon; - c->vp3_h_loop_filter = ff_vp3_h_loop_filter_neon; - c->vp3_idct_dc_add = ff_vp3_idct_dc_add_neon; - } - - c->vector_fmul = ff_vector_fmul_neon; - c->vector_fmul_window = ff_vector_fmul_window_neon; - c->vector_fmul_scalar = ff_vector_fmul_scalar_neon; - c->butterflies_float = ff_butterflies_float_neon; - c->scalarproduct_float = ff_scalarproduct_float_neon; - c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_neon; - c->vector_fmul_reverse = ff_vector_fmul_reverse_neon; - c->vector_fmul_add = ff_vector_fmul_add_neon; - c->vector_clipf = ff_vector_clipf_neon; - - c->vector_fmul_sv_scalar[0] = ff_vector_fmul_sv_scalar_2_neon; - c->vector_fmul_sv_scalar[1] = ff_vector_fmul_sv_scalar_4_neon; - - c->sv_fmul_scalar[0] = ff_sv_fmul_scalar_2_neon; - c->sv_fmul_scalar[1] = ff_sv_fmul_scalar_4_neon; - - if (!(avctx->flags & CODEC_FLAG_BITEXACT)) { - c->float_to_int16 = ff_float_to_int16_neon; - c->float_to_int16_interleave = ff_float_to_int16_interleave_neon; - } - - if (CONFIG_VORBIS_DECODER) - c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon; - - c->scalarproduct_int16 = ff_scalarproduct_int16_neon; - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_neon; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_vfp.c b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_vfp.c deleted file mode 100644 index 9f8c1b7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_init_vfp.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2008 Siarhei Siamashka - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_arm.h" - -void ff_vector_fmul_vfp(float *dst, const float *src, int len); -void ff_vector_fmul_reverse_vfp(float *dst, const float *src0, - const float *src1, int len); -void ff_float_to_int16_vfp(int16_t *dst, const float *src, long len); - -void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx) -{ - c->vector_fmul = ff_vector_fmul_vfp; - c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp; -#if HAVE_ARMV6 - c->float_to_int16 = ff_float_to_int16_vfp; -#endif -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt.c b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt.c deleted file mode 100644 index 6a23732..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * iWMMXt optimized DSP utils - * Copyright (c) 2004 AGAWA Koji - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/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_template.c" -#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_template.c" -#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 clear_blocks_iwmmxt(DCTELEM *blocks) -{ - __asm__ volatile( - "wzero wr0 \n\t" - "mov r1, #(128 * 6 / 32) \n\t" - "1: \n\t" - "wstrd wr0, [%0] \n\t" - "wstrd wr0, [%0, #8] \n\t" - "wstrd wr0, [%0, #16] \n\t" - "wstrd wr0, [%0, #24] \n\t" - "subs r1, r1, #1 \n\t" - "add %0, %0, #32 \n\t" - "bne 1b \n\t" - : "+r"(blocks) - : - : "r1" - ); -} - -static void nop(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - return; -} - -/* A run time test is not simple. If this file is compiled in - * then we should install the functions - */ -int mm_flags = FF_MM_IWMMXT; /* multimedia extension flags */ - -void ff_dsputil_init_iwmmxt(DSPContext* c, AVCodecContext *avctx) -{ - 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 & FF_MM_IWMMXT)) return; - - c->add_pixels_clamped = add_pixels_clamped_iwmmxt; - - c->clear_blocks = clear_blocks_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/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt_rnd_template.c b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt_rnd_template.c deleted file mode 100644 index 35a5a9b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_iwmmxt_rnd_template.c +++ /dev/null @@ -1,1114 +0,0 @@ -/* - * iWMMXt optimized DSP utils - * copyright (c) 2004 AGAWA Koji - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -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/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_neon.S deleted file mode 100644 index 722ed78..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_neon.S +++ /dev/null @@ -1,1146 +0,0 @@ -/* - * ARM NEON optimised DSP functions - * Copyright (c) 2008 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "asm.S" - - preserve8 - .text - - .macro pixels16 avg=0 -.if \avg - mov ip, r0 -.endif -1: vld1.64 {d0, d1}, [r1], r2 - vld1.64 {d2, d3}, [r1], r2 - vld1.64 {d4, d5}, [r1], r2 - pld [r1, r2, lsl #2] - vld1.64 {d6, d7}, [r1], r2 - pld [r1] - pld [r1, r2] - pld [r1, r2, lsl #1] -.if \avg - vld1.64 {d16,d17}, [ip,:128], r2 - vrhadd.u8 q0, q0, q8 - vld1.64 {d18,d19}, [ip,:128], r2 - vrhadd.u8 q1, q1, q9 - vld1.64 {d20,d21}, [ip,:128], r2 - vrhadd.u8 q2, q2, q10 - vld1.64 {d22,d23}, [ip,:128], r2 - vrhadd.u8 q3, q3, q11 -.endif - subs r3, r3, #4 - vst1.64 {d0, d1}, [r0,:128], r2 - vst1.64 {d2, d3}, [r0,:128], r2 - vst1.64 {d4, d5}, [r0,:128], r2 - vst1.64 {d6, d7}, [r0,:128], r2 - bne 1b - bx lr - .endm - - .macro pixels16_x2 vhadd=vrhadd.u8 -1: vld1.64 {d0-d2}, [r1], r2 - vld1.64 {d4-d6}, [r1], r2 - pld [r1] - pld [r1, r2] - subs r3, r3, #2 - vext.8 q1, q0, q1, #1 - \vhadd q0, q0, q1 - vext.8 q3, q2, q3, #1 - \vhadd q2, q2, q3 - vst1.64 {d0, d1}, [r0,:128], r2 - vst1.64 {d4, d5}, [r0,:128], r2 - bne 1b - bx lr - .endm - - .macro pixels16_y2 vhadd=vrhadd.u8 - vld1.64 {d0, d1}, [r1], r2 - vld1.64 {d2, d3}, [r1], r2 -1: subs r3, r3, #2 - \vhadd q2, q0, q1 - vld1.64 {d0, d1}, [r1], r2 - \vhadd q3, q0, q1 - vld1.64 {d2, d3}, [r1], r2 - pld [r1] - pld [r1, r2] - vst1.64 {d4, d5}, [r0,:128], r2 - vst1.64 {d6, d7}, [r0,:128], r2 - bne 1b - bx lr - .endm - - .macro pixels16_xy2 vshrn=vrshrn.u16 no_rnd=0 - vld1.64 {d0-d2}, [r1], r2 - vld1.64 {d4-d6}, [r1], r2 -.if \no_rnd - vmov.i16 q13, #1 -.endif - pld [r1] - pld [r1, r2] - vext.8 q1, q0, q1, #1 - vext.8 q3, q2, q3, #1 - vaddl.u8 q8, d0, d2 - vaddl.u8 q10, d1, d3 - vaddl.u8 q9, d4, d6 - vaddl.u8 q11, d5, d7 -1: subs r3, r3, #2 - vld1.64 {d0-d2}, [r1], r2 - vadd.u16 q12, q8, q9 - pld [r1] -.if \no_rnd - vadd.u16 q12, q12, q13 -.endif - vext.8 q15, q0, q1, #1 - vadd.u16 q1 , q10, q11 - \vshrn d28, q12, #2 -.if \no_rnd - vadd.u16 q1, q1, q13 -.endif - \vshrn d29, q1, #2 - vaddl.u8 q8, d0, d30 - vld1.64 {d2-d4}, [r1], r2 - vaddl.u8 q10, d1, d31 - vst1.64 {d28,d29}, [r0,:128], r2 - vadd.u16 q12, q8, q9 - pld [r1, r2] -.if \no_rnd - vadd.u16 q12, q12, q13 -.endif - vext.8 q2, q1, q2, #1 - vadd.u16 q0, q10, q11 - \vshrn d30, q12, #2 -.if \no_rnd - vadd.u16 q0, q0, q13 -.endif - \vshrn d31, q0, #2 - vaddl.u8 q9, d2, d4 - vaddl.u8 q11, d3, d5 - vst1.64 {d30,d31}, [r0,:128], r2 - bgt 1b - bx lr - .endm - - .macro pixels8 avg=0 -1: vld1.64 {d0}, [r1], r2 - vld1.64 {d1}, [r1], r2 - vld1.64 {d2}, [r1], r2 - pld [r1, r2, lsl #2] - vld1.64 {d3}, [r1], r2 - pld [r1] - pld [r1, r2] - pld [r1, r2, lsl #1] -.if \avg - vld1.64 {d4}, [r0,:64], r2 - vrhadd.u8 d0, d0, d4 - vld1.64 {d5}, [r0,:64], r2 - vrhadd.u8 d1, d1, d5 - vld1.64 {d6}, [r0,:64], r2 - vrhadd.u8 d2, d2, d6 - vld1.64 {d7}, [r0,:64], r2 - vrhadd.u8 d3, d3, d7 - sub r0, r0, r2, lsl #2 -.endif - subs r3, r3, #4 - vst1.64 {d0}, [r0,:64], r2 - vst1.64 {d1}, [r0,:64], r2 - vst1.64 {d2}, [r0,:64], r2 - vst1.64 {d3}, [r0,:64], r2 - bne 1b - bx lr - .endm - - .macro pixels8_x2 vhadd=vrhadd.u8 -1: vld1.64 {d0, d1}, [r1], r2 - vext.8 d1, d0, d1, #1 - vld1.64 {d2, d3}, [r1], r2 - vext.8 d3, d2, d3, #1 - pld [r1] - pld [r1, r2] - subs r3, r3, #2 - vswp d1, d2 - \vhadd q0, q0, q1 - vst1.64 {d0}, [r0,:64], r2 - vst1.64 {d1}, [r0,:64], r2 - bne 1b - bx lr - .endm - - .macro pixels8_y2 vhadd=vrhadd.u8 - vld1.64 {d0}, [r1], r2 - vld1.64 {d1}, [r1], r2 -1: subs r3, r3, #2 - \vhadd d4, d0, d1 - vld1.64 {d0}, [r1], r2 - \vhadd d5, d0, d1 - vld1.64 {d1}, [r1], r2 - pld [r1] - pld [r1, r2] - vst1.64 {d4}, [r0,:64], r2 - vst1.64 {d5}, [r0,:64], r2 - bne 1b - bx lr - .endm - - .macro pixels8_xy2 vshrn=vrshrn.u16 no_rnd=0 - vld1.64 {d0, d1}, [r1], r2 - vld1.64 {d2, d3}, [r1], r2 -.if \no_rnd - vmov.i16 q11, #1 -.endif - pld [r1] - pld [r1, r2] - vext.8 d4, d0, d1, #1 - vext.8 d6, d2, d3, #1 - vaddl.u8 q8, d0, d4 - vaddl.u8 q9, d2, d6 -1: subs r3, r3, #2 - vld1.64 {d0, d1}, [r1], r2 - pld [r1] - vadd.u16 q10, q8, q9 - vext.8 d4, d0, d1, #1 -.if \no_rnd - vadd.u16 q10, q10, q11 -.endif - vaddl.u8 q8, d0, d4 - \vshrn d5, q10, #2 - vld1.64 {d2, d3}, [r1], r2 - vadd.u16 q10, q8, q9 - pld [r1, r2] -.if \no_rnd - vadd.u16 q10, q10, q11 -.endif - vst1.64 {d5}, [r0,:64], r2 - \vshrn d7, q10, #2 - vext.8 d6, d2, d3, #1 - vaddl.u8 q9, d2, d6 - vst1.64 {d7}, [r0,:64], r2 - bgt 1b - bx lr - .endm - - .macro pixfunc pfx name suf rnd_op args:vararg -function ff_\pfx\name\suf\()_neon, export=1 - \name \rnd_op \args -endfunc - .endm - - .macro pixfunc2 pfx name args:vararg - pixfunc \pfx \name - pixfunc \pfx \name \args - .endm - -function ff_put_h264_qpel16_mc00_neon, export=1 - mov r3, #16 -endfunc - - pixfunc put_ pixels16 - pixfunc2 put_ pixels16_x2, _no_rnd, vhadd.u8 - pixfunc2 put_ pixels16_y2, _no_rnd, vhadd.u8 - pixfunc2 put_ pixels16_xy2, _no_rnd, vshrn.u16, 1 - -function ff_avg_h264_qpel16_mc00_neon, export=1 - mov r3, #16 -endfunc - - pixfunc avg_ pixels16,, 1 - -function ff_put_h264_qpel8_mc00_neon, export=1 - mov r3, #8 -endfunc - - pixfunc put_ pixels8 - pixfunc2 put_ pixels8_x2, _no_rnd, vhadd.u8 - pixfunc2 put_ pixels8_y2, _no_rnd, vhadd.u8 - pixfunc2 put_ pixels8_xy2, _no_rnd, vshrn.u16, 1 - -function ff_avg_h264_qpel8_mc00_neon, export=1 - mov r3, #8 -endfunc - - pixfunc avg_ pixels8,, 1 - -function ff_put_pixels_clamped_neon, export=1 - vld1.64 {d16-d19}, [r0,:128]! - vqmovun.s16 d0, q8 - vld1.64 {d20-d23}, [r0,:128]! - vqmovun.s16 d1, q9 - vld1.64 {d24-d27}, [r0,:128]! - vqmovun.s16 d2, q10 - vld1.64 {d28-d31}, [r0,:128]! - vqmovun.s16 d3, q11 - vst1.64 {d0}, [r1,:64], r2 - vqmovun.s16 d4, q12 - vst1.64 {d1}, [r1,:64], r2 - vqmovun.s16 d5, q13 - vst1.64 {d2}, [r1,:64], r2 - vqmovun.s16 d6, q14 - vst1.64 {d3}, [r1,:64], r2 - vqmovun.s16 d7, q15 - vst1.64 {d4}, [r1,:64], r2 - vst1.64 {d5}, [r1,:64], r2 - vst1.64 {d6}, [r1,:64], r2 - vst1.64 {d7}, [r1,:64], r2 - bx lr -endfunc - -function ff_put_signed_pixels_clamped_neon, export=1 - vmov.u8 d31, #128 - vld1.64 {d16-d17}, [r0,:128]! - vqmovn.s16 d0, q8 - vld1.64 {d18-d19}, [r0,:128]! - vqmovn.s16 d1, q9 - vld1.64 {d16-d17}, [r0,:128]! - vqmovn.s16 d2, q8 - vld1.64 {d18-d19}, [r0,:128]! - vadd.u8 d0, d0, d31 - vld1.64 {d20-d21}, [r0,:128]! - vadd.u8 d1, d1, d31 - vld1.64 {d22-d23}, [r0,:128]! - vadd.u8 d2, d2, d31 - vst1.64 {d0}, [r1,:64], r2 - vqmovn.s16 d3, q9 - vst1.64 {d1}, [r1,:64], r2 - vqmovn.s16 d4, q10 - vst1.64 {d2}, [r1,:64], r2 - vqmovn.s16 d5, q11 - vld1.64 {d24-d25}, [r0,:128]! - vadd.u8 d3, d3, d31 - vld1.64 {d26-d27}, [r0,:128]! - vadd.u8 d4, d4, d31 - vadd.u8 d5, d5, d31 - vst1.64 {d3}, [r1,:64], r2 - vqmovn.s16 d6, q12 - vst1.64 {d4}, [r1,:64], r2 - vqmovn.s16 d7, q13 - vst1.64 {d5}, [r1,:64], r2 - vadd.u8 d6, d6, d31 - vadd.u8 d7, d7, d31 - vst1.64 {d6}, [r1,:64], r2 - vst1.64 {d7}, [r1,:64], r2 - bx lr -endfunc - -function ff_add_pixels_clamped_neon, export=1 - mov r3, r1 - vld1.64 {d16}, [r1,:64], r2 - vld1.64 {d0-d1}, [r0,:128]! - vaddw.u8 q0, q0, d16 - vld1.64 {d17}, [r1,:64], r2 - vld1.64 {d2-d3}, [r0,:128]! - vqmovun.s16 d0, q0 - vld1.64 {d18}, [r1,:64], r2 - vaddw.u8 q1, q1, d17 - vld1.64 {d4-d5}, [r0,:128]! - vaddw.u8 q2, q2, d18 - vst1.64 {d0}, [r3,:64], r2 - vqmovun.s16 d2, q1 - vld1.64 {d19}, [r1,:64], r2 - vld1.64 {d6-d7}, [r0,:128]! - vaddw.u8 q3, q3, d19 - vqmovun.s16 d4, q2 - vst1.64 {d2}, [r3,:64], r2 - vld1.64 {d16}, [r1,:64], r2 - vqmovun.s16 d6, q3 - vld1.64 {d0-d1}, [r0,:128]! - vaddw.u8 q0, q0, d16 - vst1.64 {d4}, [r3,:64], r2 - vld1.64 {d17}, [r1,:64], r2 - vld1.64 {d2-d3}, [r0,:128]! - vaddw.u8 q1, q1, d17 - vst1.64 {d6}, [r3,:64], r2 - vqmovun.s16 d0, q0 - vld1.64 {d18}, [r1,:64], r2 - vld1.64 {d4-d5}, [r0,:128]! - vaddw.u8 q2, q2, d18 - vst1.64 {d0}, [r3,:64], r2 - vqmovun.s16 d2, q1 - vld1.64 {d19}, [r1,:64], r2 - vqmovun.s16 d4, q2 - vld1.64 {d6-d7}, [r0,:128]! - vaddw.u8 q3, q3, d19 - vst1.64 {d2}, [r3,:64], r2 - vqmovun.s16 d6, q3 - vst1.64 {d4}, [r3,:64], r2 - vst1.64 {d6}, [r3,:64], r2 - bx lr -endfunc - -function ff_float_to_int16_neon, export=1 - subs r2, r2, #8 - vld1.64 {d0-d1}, [r1,:128]! - vcvt.s32.f32 q8, q0, #16 - vld1.64 {d2-d3}, [r1,:128]! - vcvt.s32.f32 q9, q1, #16 - beq 3f - bics ip, r2, #15 - beq 2f -1: subs ip, ip, #16 - vshrn.s32 d4, q8, #16 - vld1.64 {d0-d1}, [r1,:128]! - vcvt.s32.f32 q0, q0, #16 - vshrn.s32 d5, q9, #16 - vld1.64 {d2-d3}, [r1,:128]! - vcvt.s32.f32 q1, q1, #16 - vshrn.s32 d6, q0, #16 - vst1.64 {d4-d5}, [r0,:128]! - vshrn.s32 d7, q1, #16 - vld1.64 {d16-d17},[r1,:128]! - vcvt.s32.f32 q8, q8, #16 - vld1.64 {d18-d19},[r1,:128]! - vcvt.s32.f32 q9, q9, #16 - vst1.64 {d6-d7}, [r0,:128]! - bne 1b - ands r2, r2, #15 - beq 3f -2: vld1.64 {d0-d1}, [r1,:128]! - vshrn.s32 d4, q8, #16 - vcvt.s32.f32 q0, q0, #16 - vld1.64 {d2-d3}, [r1,:128]! - vshrn.s32 d5, q9, #16 - vcvt.s32.f32 q1, q1, #16 - vshrn.s32 d6, q0, #16 - vst1.64 {d4-d5}, [r0,:128]! - vshrn.s32 d7, q1, #16 - vst1.64 {d6-d7}, [r0,:128]! - bx lr -3: vshrn.s32 d4, q8, #16 - vshrn.s32 d5, q9, #16 - vst1.64 {d4-d5}, [r0,:128]! - bx lr -endfunc - -function ff_float_to_int16_interleave_neon, export=1 - cmp r3, #2 - ldrlt r1, [r1] - blt ff_float_to_int16_neon - bne 4f - - ldr r3, [r1] - ldr r1, [r1, #4] - - subs r2, r2, #8 - vld1.64 {d0-d1}, [r3,:128]! - vcvt.s32.f32 q8, q0, #16 - vld1.64 {d2-d3}, [r3,:128]! - vcvt.s32.f32 q9, q1, #16 - vld1.64 {d20-d21},[r1,:128]! - vcvt.s32.f32 q10, q10, #16 - vld1.64 {d22-d23},[r1,:128]! - vcvt.s32.f32 q11, q11, #16 - beq 3f - bics ip, r2, #15 - beq 2f -1: subs ip, ip, #16 - vld1.64 {d0-d1}, [r3,:128]! - vcvt.s32.f32 q0, q0, #16 - vsri.32 q10, q8, #16 - vld1.64 {d2-d3}, [r3,:128]! - vcvt.s32.f32 q1, q1, #16 - vld1.64 {d24-d25},[r1,:128]! - vcvt.s32.f32 q12, q12, #16 - vld1.64 {d26-d27},[r1,:128]! - vsri.32 q11, q9, #16 - vst1.64 {d20-d21},[r0,:128]! - vcvt.s32.f32 q13, q13, #16 - vst1.64 {d22-d23},[r0,:128]! - vsri.32 q12, q0, #16 - vld1.64 {d16-d17},[r3,:128]! - vsri.32 q13, q1, #16 - vst1.64 {d24-d25},[r0,:128]! - vcvt.s32.f32 q8, q8, #16 - vld1.64 {d18-d19},[r3,:128]! - vcvt.s32.f32 q9, q9, #16 - vld1.64 {d20-d21},[r1,:128]! - vcvt.s32.f32 q10, q10, #16 - vld1.64 {d22-d23},[r1,:128]! - vcvt.s32.f32 q11, q11, #16 - vst1.64 {d26-d27},[r0,:128]! - bne 1b - ands r2, r2, #15 - beq 3f -2: vsri.32 q10, q8, #16 - vld1.64 {d0-d1}, [r3,:128]! - vcvt.s32.f32 q0, q0, #16 - vld1.64 {d2-d3}, [r3,:128]! - vcvt.s32.f32 q1, q1, #16 - vld1.64 {d24-d25},[r1,:128]! - vcvt.s32.f32 q12, q12, #16 - vsri.32 q11, q9, #16 - vld1.64 {d26-d27},[r1,:128]! - vcvt.s32.f32 q13, q13, #16 - vst1.64 {d20-d21},[r0,:128]! - vsri.32 q12, q0, #16 - vst1.64 {d22-d23},[r0,:128]! - vsri.32 q13, q1, #16 - vst1.64 {d24-d27},[r0,:128]! - bx lr -3: vsri.32 q10, q8, #16 - vsri.32 q11, q9, #16 - vst1.64 {d20-d23},[r0,:128]! - bx lr - -4: push {r4-r8,lr} - cmp r3, #4 - lsl ip, r3, #1 - blt 4f - - @ 4 channels -5: ldmia r1!, {r4-r7} - mov lr, r2 - mov r8, r0 - vld1.64 {d16-d17},[r4,:128]! - vcvt.s32.f32 q8, q8, #16 - vld1.64 {d18-d19},[r5,:128]! - vcvt.s32.f32 q9, q9, #16 - vld1.64 {d20-d21},[r6,:128]! - vcvt.s32.f32 q10, q10, #16 - vld1.64 {d22-d23},[r7,:128]! - vcvt.s32.f32 q11, q11, #16 -6: subs lr, lr, #8 - vld1.64 {d0-d1}, [r4,:128]! - vcvt.s32.f32 q0, q0, #16 - vsri.32 q9, q8, #16 - vld1.64 {d2-d3}, [r5,:128]! - vcvt.s32.f32 q1, q1, #16 - vsri.32 q11, q10, #16 - vld1.64 {d4-d5}, [r6,:128]! - vcvt.s32.f32 q2, q2, #16 - vzip.32 d18, d22 - vld1.64 {d6-d7}, [r7,:128]! - vcvt.s32.f32 q3, q3, #16 - vzip.32 d19, d23 - vst1.64 {d18}, [r8], ip - vsri.32 q1, q0, #16 - vst1.64 {d22}, [r8], ip - vsri.32 q3, q2, #16 - vst1.64 {d19}, [r8], ip - vzip.32 d2, d6 - vst1.64 {d23}, [r8], ip - vzip.32 d3, d7 - beq 7f - vld1.64 {d16-d17},[r4,:128]! - vcvt.s32.f32 q8, q8, #16 - vst1.64 {d2}, [r8], ip - vld1.64 {d18-d19},[r5,:128]! - vcvt.s32.f32 q9, q9, #16 - vst1.64 {d6}, [r8], ip - vld1.64 {d20-d21},[r6,:128]! - vcvt.s32.f32 q10, q10, #16 - vst1.64 {d3}, [r8], ip - vld1.64 {d22-d23},[r7,:128]! - vcvt.s32.f32 q11, q11, #16 - vst1.64 {d7}, [r8], ip - b 6b -7: vst1.64 {d2}, [r8], ip - vst1.64 {d6}, [r8], ip - vst1.64 {d3}, [r8], ip - vst1.64 {d7}, [r8], ip - subs r3, r3, #4 - popeq {r4-r8,pc} - cmp r3, #4 - add r0, r0, #8 - bge 5b - - @ 2 channels -4: cmp r3, #2 - blt 4f - ldmia r1!, {r4-r5} - mov lr, r2 - mov r8, r0 - tst lr, #8 - vld1.64 {d16-d17},[r4,:128]! - vcvt.s32.f32 q8, q8, #16 - vld1.64 {d18-d19},[r5,:128]! - vcvt.s32.f32 q9, q9, #16 - vld1.64 {d20-d21},[r4,:128]! - vcvt.s32.f32 q10, q10, #16 - vld1.64 {d22-d23},[r5,:128]! - vcvt.s32.f32 q11, q11, #16 - beq 6f - subs lr, lr, #8 - beq 7f - vsri.32 d18, d16, #16 - vsri.32 d19, d17, #16 - vld1.64 {d16-d17},[r4,:128]! - vcvt.s32.f32 q8, q8, #16 - vst1.32 {d18[0]}, [r8], ip - vsri.32 d22, d20, #16 - vst1.32 {d18[1]}, [r8], ip - vsri.32 d23, d21, #16 - vst1.32 {d19[0]}, [r8], ip - vst1.32 {d19[1]}, [r8], ip - vld1.64 {d18-d19},[r5,:128]! - vcvt.s32.f32 q9, q9, #16 - vst1.32 {d22[0]}, [r8], ip - vst1.32 {d22[1]}, [r8], ip - vld1.64 {d20-d21},[r4,:128]! - vcvt.s32.f32 q10, q10, #16 - vst1.32 {d23[0]}, [r8], ip - vst1.32 {d23[1]}, [r8], ip - vld1.64 {d22-d23},[r5,:128]! - vcvt.s32.f32 q11, q11, #16 -6: subs lr, lr, #16 - vld1.64 {d0-d1}, [r4,:128]! - vcvt.s32.f32 q0, q0, #16 - vsri.32 d18, d16, #16 - vld1.64 {d2-d3}, [r5,:128]! - vcvt.s32.f32 q1, q1, #16 - vsri.32 d19, d17, #16 - vld1.64 {d4-d5}, [r4,:128]! - vcvt.s32.f32 q2, q2, #16 - vld1.64 {d6-d7}, [r5,:128]! - vcvt.s32.f32 q3, q3, #16 - vst1.32 {d18[0]}, [r8], ip - vsri.32 d22, d20, #16 - vst1.32 {d18[1]}, [r8], ip - vsri.32 d23, d21, #16 - vst1.32 {d19[0]}, [r8], ip - vsri.32 d2, d0, #16 - vst1.32 {d19[1]}, [r8], ip - vsri.32 d3, d1, #16 - vst1.32 {d22[0]}, [r8], ip - vsri.32 d6, d4, #16 - vst1.32 {d22[1]}, [r8], ip - vsri.32 d7, d5, #16 - vst1.32 {d23[0]}, [r8], ip - vst1.32 {d23[1]}, [r8], ip - beq 6f - vld1.64 {d16-d17},[r4,:128]! - vcvt.s32.f32 q8, q8, #16 - vst1.32 {d2[0]}, [r8], ip - vst1.32 {d2[1]}, [r8], ip - vld1.64 {d18-d19},[r5,:128]! - vcvt.s32.f32 q9, q9, #16 - vst1.32 {d3[0]}, [r8], ip - vst1.32 {d3[1]}, [r8], ip - vld1.64 {d20-d21},[r4,:128]! - vcvt.s32.f32 q10, q10, #16 - vst1.32 {d6[0]}, [r8], ip - vst1.32 {d6[1]}, [r8], ip - vld1.64 {d22-d23},[r5,:128]! - vcvt.s32.f32 q11, q11, #16 - vst1.32 {d7[0]}, [r8], ip - vst1.32 {d7[1]}, [r8], ip - bgt 6b -6: vst1.32 {d2[0]}, [r8], ip - vst1.32 {d2[1]}, [r8], ip - vst1.32 {d3[0]}, [r8], ip - vst1.32 {d3[1]}, [r8], ip - vst1.32 {d6[0]}, [r8], ip - vst1.32 {d6[1]}, [r8], ip - vst1.32 {d7[0]}, [r8], ip - vst1.32 {d7[1]}, [r8], ip - b 8f -7: vsri.32 d18, d16, #16 - vsri.32 d19, d17, #16 - vst1.32 {d18[0]}, [r8], ip - vsri.32 d22, d20, #16 - vst1.32 {d18[1]}, [r8], ip - vsri.32 d23, d21, #16 - vst1.32 {d19[0]}, [r8], ip - vst1.32 {d19[1]}, [r8], ip - vst1.32 {d22[0]}, [r8], ip - vst1.32 {d22[1]}, [r8], ip - vst1.32 {d23[0]}, [r8], ip - vst1.32 {d23[1]}, [r8], ip -8: subs r3, r3, #2 - add r0, r0, #4 - popeq {r4-r8,pc} - - @ 1 channel -4: ldr r4, [r1],#4 - tst r2, #8 - mov lr, r2 - mov r5, r0 - vld1.64 {d0-d1}, [r4,:128]! - vcvt.s32.f32 q0, q0, #16 - vld1.64 {d2-d3}, [r4,:128]! - vcvt.s32.f32 q1, q1, #16 - bne 8f -6: subs lr, lr, #16 - vld1.64 {d4-d5}, [r4,:128]! - vcvt.s32.f32 q2, q2, #16 - vld1.64 {d6-d7}, [r4,:128]! - vcvt.s32.f32 q3, q3, #16 - vst1.16 {d0[1]}, [r5,:16], ip - vst1.16 {d0[3]}, [r5,:16], ip - vst1.16 {d1[1]}, [r5,:16], ip - vst1.16 {d1[3]}, [r5,:16], ip - vst1.16 {d2[1]}, [r5,:16], ip - vst1.16 {d2[3]}, [r5,:16], ip - vst1.16 {d3[1]}, [r5,:16], ip - vst1.16 {d3[3]}, [r5,:16], ip - beq 7f - vld1.64 {d0-d1}, [r4,:128]! - vcvt.s32.f32 q0, q0, #16 - vld1.64 {d2-d3}, [r4,:128]! - vcvt.s32.f32 q1, q1, #16 -7: vst1.16 {d4[1]}, [r5,:16], ip - vst1.16 {d4[3]}, [r5,:16], ip - vst1.16 {d5[1]}, [r5,:16], ip - vst1.16 {d5[3]}, [r5,:16], ip - vst1.16 {d6[1]}, [r5,:16], ip - vst1.16 {d6[3]}, [r5,:16], ip - vst1.16 {d7[1]}, [r5,:16], ip - vst1.16 {d7[3]}, [r5,:16], ip - bgt 6b - pop {r4-r8,pc} -8: subs lr, lr, #8 - vst1.16 {d0[1]}, [r5,:16], ip - vst1.16 {d0[3]}, [r5,:16], ip - vst1.16 {d1[1]}, [r5,:16], ip - vst1.16 {d1[3]}, [r5,:16], ip - vst1.16 {d2[1]}, [r5,:16], ip - vst1.16 {d2[3]}, [r5,:16], ip - vst1.16 {d3[1]}, [r5,:16], ip - vst1.16 {d3[3]}, [r5,:16], ip - popeq {r4-r8,pc} - vld1.64 {d0-d1}, [r4,:128]! - vcvt.s32.f32 q0, q0, #16 - vld1.64 {d2-d3}, [r4,:128]! - vcvt.s32.f32 q1, q1, #16 - b 6b -endfunc - -function ff_vector_fmul_neon, export=1 - mov r3, r0 - subs r2, r2, #8 - vld1.64 {d0-d3}, [r0,:128]! - vld1.64 {d4-d7}, [r1,:128]! - vmul.f32 q8, q0, q2 - vmul.f32 q9, q1, q3 - beq 3f - bics ip, r2, #15 - beq 2f -1: subs ip, ip, #16 - vld1.64 {d0-d1}, [r0,:128]! - vld1.64 {d4-d5}, [r1,:128]! - vmul.f32 q10, q0, q2 - vld1.64 {d2-d3}, [r0,:128]! - vld1.64 {d6-d7}, [r1,:128]! - vmul.f32 q11, q1, q3 - vst1.64 {d16-d19},[r3,:128]! - vld1.64 {d0-d1}, [r0,:128]! - vld1.64 {d4-d5}, [r1,:128]! - vmul.f32 q8, q0, q2 - vld1.64 {d2-d3}, [r0,:128]! - vld1.64 {d6-d7}, [r1,:128]! - vmul.f32 q9, q1, q3 - vst1.64 {d20-d23},[r3,:128]! - bne 1b - ands r2, r2, #15 - beq 3f -2: vld1.64 {d0-d1}, [r0,:128]! - vld1.64 {d4-d5}, [r1,:128]! - vst1.64 {d16-d17},[r3,:128]! - vmul.f32 q8, q0, q2 - vld1.64 {d2-d3}, [r0,:128]! - vld1.64 {d6-d7}, [r1,:128]! - vst1.64 {d18-d19},[r3,:128]! - vmul.f32 q9, q1, q3 -3: vst1.64 {d16-d19},[r3,:128]! - bx lr -endfunc - -function ff_vector_fmul_window_neon, export=1 -VFP vdup.32 q8, d0[0] -NOVFP vld1.32 {d16[],d17[]}, [sp,:32] - push {r4,r5,lr} -VFP ldr lr, [sp, #12] -NOVFP ldr lr, [sp, #16] - sub r2, r2, #8 - sub r5, lr, #2 - add r2, r2, r5, lsl #2 - add r4, r3, r5, lsl #3 - add ip, r0, r5, lsl #3 - mov r5, #-16 - vld1.64 {d0,d1}, [r1,:128]! - vld1.64 {d2,d3}, [r2,:128], r5 - vld1.64 {d4,d5}, [r3,:128]! - vld1.64 {d6,d7}, [r4,:128], r5 -1: subs lr, lr, #4 - vmov q11, q8 - vmla.f32 d22, d0, d4 - vmov q10, q8 - vmla.f32 d23, d1, d5 - vrev64.32 q3, q3 - vmla.f32 d20, d0, d7 - vrev64.32 q1, q1 - vmla.f32 d21, d1, d6 - beq 2f - vmla.f32 d22, d3, d7 - vld1.64 {d0,d1}, [r1,:128]! - vmla.f32 d23, d2, d6 - vld1.64 {d18,d19},[r2,:128], r5 - vmls.f32 d20, d3, d4 - vld1.64 {d24,d25},[r3,:128]! - vmls.f32 d21, d2, d5 - vld1.64 {d6,d7}, [r4,:128], r5 - vmov q1, q9 - vrev64.32 q11, q11 - vmov q2, q12 - vswp d22, d23 - vst1.64 {d20,d21},[r0,:128]! - vst1.64 {d22,d23},[ip,:128], r5 - b 1b -2: vmla.f32 d22, d3, d7 - vmla.f32 d23, d2, d6 - vmls.f32 d20, d3, d4 - vmls.f32 d21, d2, d5 - vrev64.32 q11, q11 - vswp d22, d23 - vst1.64 {d20,d21},[r0,:128]! - vst1.64 {d22,d23},[ip,:128], r5 - pop {r4,r5,pc} -endfunc - -#if CONFIG_VORBIS_DECODER -function ff_vorbis_inverse_coupling_neon, export=1 - vmov.i32 q10, #1<<31 - subs r2, r2, #4 - mov r3, r0 - mov r12, r1 - beq 3f - - vld1.32 {d24-d25},[r1,:128]! - vld1.32 {d22-d23},[r0,:128]! - vcle.s32 q8, q12, #0 - vand q9, q11, q10 - veor q12, q12, q9 - vand q2, q12, q8 - vbic q3, q12, q8 - vadd.f32 q12, q11, q2 - vsub.f32 q11, q11, q3 -1: vld1.32 {d2-d3}, [r1,:128]! - vld1.32 {d0-d1}, [r0,:128]! - vcle.s32 q8, q1, #0 - vand q9, q0, q10 - veor q1, q1, q9 - vst1.32 {d24-d25},[r3, :128]! - vst1.32 {d22-d23},[r12,:128]! - vand q2, q1, q8 - vbic q3, q1, q8 - vadd.f32 q1, q0, q2 - vsub.f32 q0, q0, q3 - subs r2, r2, #8 - ble 2f - vld1.32 {d24-d25},[r1,:128]! - vld1.32 {d22-d23},[r0,:128]! - vcle.s32 q8, q12, #0 - vand q9, q11, q10 - veor q12, q12, q9 - vst1.32 {d2-d3}, [r3, :128]! - vst1.32 {d0-d1}, [r12,:128]! - vand q2, q12, q8 - vbic q3, q12, q8 - vadd.f32 q12, q11, q2 - vsub.f32 q11, q11, q3 - b 1b - -2: vst1.32 {d2-d3}, [r3, :128]! - vst1.32 {d0-d1}, [r12,:128]! - bxlt lr - -3: vld1.32 {d2-d3}, [r1,:128] - vld1.32 {d0-d1}, [r0,:128] - vcle.s32 q8, q1, #0 - vand q9, q0, q10 - veor q1, q1, q9 - vand q2, q1, q8 - vbic q3, q1, q8 - vadd.f32 q1, q0, q2 - vsub.f32 q0, q0, q3 - vst1.32 {d2-d3}, [r0,:128]! - vst1.32 {d0-d1}, [r1,:128]! - bx lr -endfunc -#endif - -function ff_vector_fmul_scalar_neon, export=1 -VFP len .req r2 -NOVFP len .req r3 -VFP vdup.32 q8, d0[0] -NOVFP vdup.32 q8, r2 - bics r12, len, #15 - beq 3f - vld1.32 {q0},[r1,:128]! - vld1.32 {q1},[r1,:128]! -1: vmul.f32 q0, q0, q8 - vld1.32 {q2},[r1,:128]! - vmul.f32 q1, q1, q8 - vld1.32 {q3},[r1,:128]! - vmul.f32 q2, q2, q8 - vst1.32 {q0},[r0,:128]! - vmul.f32 q3, q3, q8 - vst1.32 {q1},[r0,:128]! - subs r12, r12, #16 - beq 2f - vld1.32 {q0},[r1,:128]! - vst1.32 {q2},[r0,:128]! - vld1.32 {q1},[r1,:128]! - vst1.32 {q3},[r0,:128]! - b 1b -2: vst1.32 {q2},[r0,:128]! - vst1.32 {q3},[r0,:128]! - ands len, len, #15 - bxeq lr -3: vld1.32 {q0},[r1,:128]! - vmul.f32 q0, q0, q8 - vst1.32 {q0},[r0,:128]! - subs len, len, #4 - bgt 3b - bx lr - .unreq len -endfunc - -function ff_vector_fmul_sv_scalar_2_neon, export=1 -VFP vdup.32 d16, d0[0] -NOVFP vdup.32 d16, r3 -NOVFP ldr r3, [sp] - vld1.32 {d0},[r1,:64]! - vld1.32 {d1},[r1,:64]! -1: subs r3, r3, #4 - vmul.f32 d4, d0, d16 - vmul.f32 d5, d1, d16 - ldr r12, [r2], #4 - vld1.32 {d2},[r12,:64] - ldr r12, [r2], #4 - vld1.32 {d3},[r12,:64] - vmul.f32 d4, d4, d2 - vmul.f32 d5, d5, d3 - beq 2f - vld1.32 {d0},[r1,:64]! - vld1.32 {d1},[r1,:64]! - vst1.32 {d4},[r0,:64]! - vst1.32 {d5},[r0,:64]! - b 1b -2: vst1.32 {d4},[r0,:64]! - vst1.32 {d5},[r0,:64]! - bx lr -endfunc - -function ff_vector_fmul_sv_scalar_4_neon, export=1 -VFP vdup.32 q10, d0[0] -NOVFP vdup.32 q10, r3 -NOVFP ldr r3, [sp] - push {lr} - bics lr, r3, #7 - beq 3f - vld1.32 {q0},[r1,:128]! - vld1.32 {q2},[r1,:128]! -1: ldr r12, [r2], #4 - vld1.32 {q1},[r12,:128] - ldr r12, [r2], #4 - vld1.32 {q3},[r12,:128] - vmul.f32 q8, q0, q10 - vmul.f32 q8, q8, q1 - vmul.f32 q9, q2, q10 - vmul.f32 q9, q9, q3 - subs lr, lr, #8 - beq 2f - vld1.32 {q0},[r1,:128]! - vld1.32 {q2},[r1,:128]! - vst1.32 {q8},[r0,:128]! - vst1.32 {q9},[r0,:128]! - b 1b -2: vst1.32 {q8},[r0,:128]! - vst1.32 {q9},[r0,:128]! - ands r3, r3, #7 - popeq {pc} -3: vld1.32 {q0},[r1,:128]! - ldr r12, [r2], #4 - vld1.32 {q1},[r12,:128] - vmul.f32 q0, q0, q10 - vmul.f32 q0, q0, q1 - vst1.32 {q0},[r0,:128]! - subs r3, r3, #4 - bgt 3b - pop {pc} -endfunc - -function ff_sv_fmul_scalar_2_neon, export=1 -VFP len .req r2 -NOVFP len .req r3 -VFP vdup.32 q8, d0[0] -NOVFP vdup.32 q8, r2 - ldr r12, [r1], #4 - vld1.32 {d0},[r12,:64] - ldr r12, [r1], #4 - vld1.32 {d1},[r12,:64] -1: vmul.f32 q1, q0, q8 - subs len, len, #4 - beq 2f - ldr r12, [r1], #4 - vld1.32 {d0},[r12,:64] - ldr r12, [r1], #4 - vld1.32 {d1},[r12,:64] - vst1.32 {q1},[r0,:128]! - b 1b -2: vst1.32 {q1},[r0,:128]! - bx lr - .unreq len -endfunc - -function ff_sv_fmul_scalar_4_neon, export=1 -VFP len .req r2 -NOVFP len .req r3 -VFP vdup.32 q8, d0[0] -NOVFP vdup.32 q8, r2 -1: ldr r12, [r1], #4 - vld1.32 {q0},[r12,:128] - vmul.f32 q0, q0, q8 - vst1.32 {q0},[r0,:128]! - subs len, len, #4 - bgt 1b - bx lr - .unreq len -endfunc - -function ff_butterflies_float_neon, export=1 -1: vld1.32 {q0},[r0,:128] - vld1.32 {q1},[r1,:128] - vsub.f32 q2, q0, q1 - vadd.f32 q1, q0, q1 - vst1.32 {q2},[r1,:128]! - vst1.32 {q1},[r0,:128]! - subs r2, r2, #4 - bgt 1b - bx lr -endfunc - -function ff_scalarproduct_float_neon, export=1 - vmov.f32 q2, #0.0 -1: vld1.32 {q0},[r0,:128]! - vld1.32 {q1},[r1,:128]! - vmla.f32 q2, q0, q1 - subs r2, r2, #4 - bgt 1b - vadd.f32 d0, d4, d5 - vpadd.f32 d0, d0, d0 -NOVFP vmov.32 r0, d0[0] - bx lr -endfunc - -function ff_int32_to_float_fmul_scalar_neon, export=1 -VFP vdup.32 q0, d0[0] -VFP len .req r2 -NOVFP vdup.32 q0, r2 -NOVFP len .req r3 - - vld1.32 {q1},[r1,:128]! - vcvt.f32.s32 q3, q1 - vld1.32 {q2},[r1,:128]! - vcvt.f32.s32 q8, q2 -1: subs len, len, #8 - pld [r1, #16] - vmul.f32 q9, q3, q0 - vmul.f32 q10, q8, q0 - beq 2f - vld1.32 {q1},[r1,:128]! - vcvt.f32.s32 q3, q1 - vld1.32 {q2},[r1,:128]! - vcvt.f32.s32 q8, q2 - vst1.32 {q9}, [r0,:128]! - vst1.32 {q10},[r0,:128]! - b 1b -2: vst1.32 {q9}, [r0,:128]! - vst1.32 {q10},[r0,:128]! - bx lr - .unreq len -endfunc - -function ff_vector_fmul_reverse_neon, export=1 - add r2, r2, r3, lsl #2 - sub r2, r2, #32 - mov r12, #-32 - vld1.32 {q0-q1}, [r1,:128]! - vld1.32 {q2-q3}, [r2,:128], r12 -1: pld [r1, #32] - vrev64.32 q3, q3 - vmul.f32 d16, d0, d7 - vmul.f32 d17, d1, d6 - pld [r2, #-32] - vrev64.32 q2, q2 - vmul.f32 d18, d2, d5 - vmul.f32 d19, d3, d4 - subs r3, r3, #8 - beq 2f - vld1.32 {q0-q1}, [r1,:128]! - vld1.32 {q2-q3}, [r2,:128], r12 - vst1.32 {q8-q9}, [r0,:128]! - b 1b -2: vst1.32 {q8-q9}, [r0,:128]! - bx lr -endfunc - -function ff_vector_fmul_add_neon, export=1 - ldr r12, [sp] - vld1.32 {q0-q1}, [r1,:128]! - vld1.32 {q8-q9}, [r2,:128]! - vld1.32 {q2-q3}, [r3,:128]! - vmul.f32 q10, q0, q8 - vmul.f32 q11, q1, q9 -1: vadd.f32 q12, q2, q10 - vadd.f32 q13, q3, q11 - pld [r1, #16] - pld [r2, #16] - pld [r3, #16] - subs r12, r12, #8 - beq 2f - vld1.32 {q0}, [r1,:128]! - vld1.32 {q8}, [r2,:128]! - vmul.f32 q10, q0, q8 - vld1.32 {q1}, [r1,:128]! - vld1.32 {q9}, [r2,:128]! - vmul.f32 q11, q1, q9 - vld1.32 {q2-q3}, [r3,:128]! - vst1.32 {q12-q13},[r0,:128]! - b 1b -2: vst1.32 {q12-q13},[r0,:128]! - bx lr -endfunc - -function ff_vector_clipf_neon, export=1 -VFP vdup.32 q1, d0[1] -VFP vdup.32 q0, d0[0] -NOVFP vdup.32 q0, r2 -NOVFP vdup.32 q1, r3 -NOVFP ldr r2, [sp] - vld1.f32 {q2},[r1,:128]! - vmin.f32 q10, q2, q1 - vld1.f32 {q3},[r1,:128]! - vmin.f32 q11, q3, q1 -1: vmax.f32 q8, q10, q0 - vmax.f32 q9, q11, q0 - subs r2, r2, #8 - beq 2f - vld1.f32 {q2},[r1,:128]! - vmin.f32 q10, q2, q1 - vld1.f32 {q3},[r1,:128]! - vmin.f32 q11, q3, q1 - vst1.f32 {q8},[r0,:128]! - vst1.f32 {q9},[r0,:128]! - b 1b -2: vst1.f32 {q8},[r0,:128]! - vst1.f32 {q9},[r0,:128]! - bx lr -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_vfp.S b/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_vfp.S deleted file mode 100644 index b704ba9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/dsputil_vfp.S +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2008 Siarhei Siamashka - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "asm.S" - - .syntax unified -/* - * VFP is a floating point coprocessor used in some ARM cores. VFP11 has 1 cycle - * throughput for almost all the instructions (except for double precision - * arithmetics), but rather high latency. Latency is 4 cycles for loads and 8 cycles - * for arithmetic operations. Scheduling code to avoid pipeline stalls is very - * important for performance. One more interesting feature is that VFP has - * independent load/store and arithmetics pipelines, so it is possible to make - * them work simultaneously and get more than 1 operation per cycle. Load/store - * pipeline can process 2 single precision floating point values per cycle and - * supports bulk loads and stores for large sets of registers. Arithmetic operations - * can be done on vectors, which allows to keep the arithmetics pipeline busy, - * while the processor may issue and execute other instructions. Detailed - * optimization manuals can be found at http://www.arm.com - */ - -/** - * ARM VFP optimized implementation of 'vector_fmul_c' function. - * Assume that len is a positive number and is multiple of 8 - */ -@ void ff_vector_fmul_vfp(float *dst, const float *src, int len) -function ff_vector_fmul_vfp, export=1 - vpush {d8-d15} - mov r3, r0 - fmrx r12, fpscr - orr r12, r12, #(3 << 16) /* set vector size to 4 */ - fmxr fpscr, r12 - - vldmia r3!, {s0-s3} - vldmia r1!, {s8-s11} - vldmia r3!, {s4-s7} - vldmia r1!, {s12-s15} - vmul.f32 s8, s0, s8 -1: - subs r2, r2, #16 - vmul.f32 s12, s4, s12 - vldmiage r3!, {s16-s19} - vldmiage r1!, {s24-s27} - vldmiage r3!, {s20-s23} - vldmiage r1!, {s28-s31} - vmulge.f32 s24, s16, s24 - vstmia r0!, {s8-s11} - vstmia r0!, {s12-s15} - vmulge.f32 s28, s20, s28 - vldmiagt r3!, {s0-s3} - vldmiagt r1!, {s8-s11} - vldmiagt r3!, {s4-s7} - vldmiagt r1!, {s12-s15} - vmulge.f32 s8, s0, s8 - vstmiage r0!, {s24-s27} - vstmiage r0!, {s28-s31} - bgt 1b - - bic r12, r12, #(7 << 16) /* set vector size back to 1 */ - fmxr fpscr, r12 - vpop {d8-d15} - bx lr -endfunc - -/** - * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function. - * Assume that len is a positive number and is multiple of 8 - */ -@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0, -@ const float *src1, int len) -function ff_vector_fmul_reverse_vfp, export=1 - vpush {d8-d15} - add r2, r2, r3, lsl #2 - vldmdb r2!, {s0-s3} - vldmia r1!, {s8-s11} - vldmdb r2!, {s4-s7} - vldmia r1!, {s12-s15} - vmul.f32 s8, s3, s8 - vmul.f32 s9, s2, s9 - vmul.f32 s10, s1, s10 - vmul.f32 s11, s0, s11 -1: - subs r3, r3, #16 - vldmdbge r2!, {s16-s19} - vmul.f32 s12, s7, s12 - vldmiage r1!, {s24-s27} - vmul.f32 s13, s6, s13 - vldmdbge r2!, {s20-s23} - vmul.f32 s14, s5, s14 - vldmiage r1!, {s28-s31} - vmul.f32 s15, s4, s15 - vmulge.f32 s24, s19, s24 - vldmdbgt r2!, {s0-s3} - vmulge.f32 s25, s18, s25 - vstmia r0!, {s8-s13} - vmulge.f32 s26, s17, s26 - vldmiagt r1!, {s8-s11} - vmulge.f32 s27, s16, s27 - vmulge.f32 s28, s23, s28 - vldmdbgt r2!, {s4-s7} - vmulge.f32 s29, s22, s29 - vstmia r0!, {s14-s15} - vmulge.f32 s30, s21, s30 - vmulge.f32 s31, s20, s31 - vmulge.f32 s8, s3, s8 - vldmiagt r1!, {s12-s15} - vmulge.f32 s9, s2, s9 - vmulge.f32 s10, s1, s10 - vstmiage r0!, {s24-s27} - vmulge.f32 s11, s0, s11 - vstmiage r0!, {s28-s31} - bgt 1b - - vpop {d8-d15} - bx lr -endfunc - -#if HAVE_ARMV6 -/** - * ARM VFP optimized float to int16 conversion. - * Assume that len is a positive number and is multiple of 8, destination - * buffer is at least 4 bytes aligned (8 bytes alignment is better for - * performance), little endian byte sex - */ -@ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len) -function ff_float_to_int16_vfp, export=1 - push {r4-r8,lr} - vpush {d8-d11} - vldmia r1!, {s16-s23} - vcvt.s32.f32 s0, s16 - vcvt.s32.f32 s1, s17 - vcvt.s32.f32 s2, s18 - vcvt.s32.f32 s3, s19 - vcvt.s32.f32 s4, s20 - vcvt.s32.f32 s5, s21 - vcvt.s32.f32 s6, s22 - vcvt.s32.f32 s7, s23 -1: - subs r2, r2, #8 - vmov r3, r4, s0, s1 - vmov r5, r6, s2, s3 - vmov r7, r8, s4, s5 - vmov ip, lr, s6, s7 - vldmiagt r1!, {s16-s23} - ssat r4, #16, r4 - ssat r3, #16, r3 - ssat r6, #16, r6 - ssat r5, #16, r5 - pkhbt r3, r3, r4, lsl #16 - pkhbt r4, r5, r6, lsl #16 - vcvtgt.s32.f32 s0, s16 - vcvtgt.s32.f32 s1, s17 - vcvtgt.s32.f32 s2, s18 - vcvtgt.s32.f32 s3, s19 - vcvtgt.s32.f32 s4, s20 - vcvtgt.s32.f32 s5, s21 - vcvtgt.s32.f32 s6, s22 - vcvtgt.s32.f32 s7, s23 - ssat r8, #16, r8 - ssat r7, #16, r7 - ssat lr, #16, lr - ssat ip, #16, ip - pkhbt r5, r7, r8, lsl #16 - pkhbt r6, ip, lr, lsl #16 - stmia r0!, {r3-r6} - bgt 1b - - vpop {d8-d11} - pop {r4-r8,pc} -endfunc -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/fft_init_arm.c b/tizen/distrib/ffmpeg/libavcodec/arm/fft_init_arm.c deleted file mode 100644 index bde1240..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/fft_init_arm.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/fft.h" -#include "libavcodec/synth_filter.h" - -void ff_fft_permute_neon(FFTContext *s, FFTComplex *z); -void ff_fft_calc_neon(FFTContext *s, FFTComplex *z); - -void ff_imdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_imdct_half_neon(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_mdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input); - -void ff_rdft_calc_neon(struct RDFTContext *s, FFTSample *z); - -void ff_synth_filter_float_neon(FFTContext *imdct, - float *synth_buf_ptr, int *synth_buf_offset, - float synth_buf2[32], const float window[512], - float out[32], const float in[32], - float scale, float bias); - -av_cold void ff_fft_init_arm(FFTContext *s) -{ - if (HAVE_NEON) { - s->fft_permute = ff_fft_permute_neon; - s->fft_calc = ff_fft_calc_neon; - s->imdct_calc = ff_imdct_calc_neon; - s->imdct_half = ff_imdct_half_neon; - s->mdct_calc = ff_mdct_calc_neon; - s->permutation = FF_MDCT_PERM_INTERLEAVE; - } -} - -#if CONFIG_RDFT -av_cold void ff_rdft_init_arm(RDFTContext *s) -{ - if (HAVE_NEON) - s->rdft_calc = ff_rdft_calc_neon; -} -#endif - -#if CONFIG_DCA_DECODER -av_cold void ff_synth_filter_init_arm(SynthFilterContext *s) -{ - if (HAVE_NEON) - s->synth_filter_float = ff_synth_filter_float_neon; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/fft_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/fft_neon.S deleted file mode 100644 index 08589db..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/fft_neon.S +++ /dev/null @@ -1,371 +0,0 @@ -/* - * ARM NEON optimised FFT - * - * Copyright (c) 2009 Mans Rullgard - * Copyright (c) 2009 Naotoshi Nojiri - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -#define M_SQRT1_2 0.70710678118654752440 - - .text - -function fft4_neon - vld1.32 {d0-d3}, [r0,:128] - - vext.32 q8, q1, q1, #1 @ i2,r3 d3=i3,r2 - vsub.f32 d6, d0, d1 @ r0-r1,i0-i1 - vsub.f32 d7, d16, d17 @ r3-r2,i2-i3 - vadd.f32 d4, d0, d1 @ r0+r1,i0+i1 - vadd.f32 d5, d2, d3 @ i2+i3,r2+r3 - vadd.f32 d1, d6, d7 - vsub.f32 d3, d6, d7 - vadd.f32 d0, d4, d5 - vsub.f32 d2, d4, d5 - - vst1.32 {d0-d3}, [r0,:128] - - bx lr -endfunc - -function fft8_neon - mov r1, r0 - vld1.32 {d0-d3}, [r1,:128]! - vld1.32 {d16-d19}, [r1,:128] - - movw r2, #0x04f3 @ sqrt(1/2) - movt r2, #0x3f35 - eor r3, r2, #1<<31 - vdup.32 d31, r2 - - vext.32 q11, q1, q1, #1 @ i2,r3,i3,r2 - vadd.f32 d4, d16, d17 @ r4+r5,i4+i5 - vmov d28, r3, r2 - vadd.f32 d5, d18, d19 @ r6+r7,i6+i7 - vsub.f32 d17, d16, d17 @ r4-r5,i4-i5 - vsub.f32 d19, d18, d19 @ r6-r7,i6-i7 - vrev64.32 d29, d28 - vadd.f32 d20, d0, d1 @ r0+r1,i0+i1 - vadd.f32 d21, d2, d3 @ r2+r3,i2+i3 - vmul.f32 d26, d17, d28 @ -a2r*w,a2i*w - vext.32 q3, q2, q2, #1 - vmul.f32 d27, d19, d29 @ a3r*w,-a3i*w - vsub.f32 d23, d22, d23 @ i2-i3,r3-r2 - vsub.f32 d22, d0, d1 @ r0-r1,i0-i1 - vmul.f32 d24, d17, d31 @ a2r*w,a2i*w - vmul.f32 d25, d19, d31 @ a3r*w,a3i*w - vadd.f32 d0, d20, d21 - vsub.f32 d2, d20, d21 - vadd.f32 d1, d22, d23 - vrev64.32 q13, q13 - vsub.f32 d3, d22, d23 - vsub.f32 d6, d6, d7 - vadd.f32 d24, d24, d26 @ a2r+a2i,a2i-a2r t1,t2 - vadd.f32 d25, d25, d27 @ a3r-a3i,a3i+a3r t5,t6 - vadd.f32 d7, d4, d5 - vsub.f32 d18, d2, d6 - vext.32 q13, q12, q12, #1 - vadd.f32 d2, d2, d6 - vsub.f32 d16, d0, d7 - vadd.f32 d5, d25, d24 - vsub.f32 d4, d26, d27 - vadd.f32 d0, d0, d7 - vsub.f32 d17, d1, d5 - vsub.f32 d19, d3, d4 - vadd.f32 d3, d3, d4 - vadd.f32 d1, d1, d5 - - vst1.32 {d16-d19}, [r1,:128] - vst1.32 {d0-d3}, [r0,:128] - - bx lr -endfunc - -function fft16_neon - movrel r1, mppm - vld1.32 {d16-d19}, [r0,:128]! @ q8{r0,i0,r1,i1} q9{r2,i2,r3,i3} - pld [r0, #32] - vld1.32 {d2-d3}, [r1,:128] - vext.32 q13, q9, q9, #1 - vld1.32 {d22-d25}, [r0,:128]! @ q11{r4,i4,r5,i5} q12{r6,i5,r7,i7} - vadd.f32 d4, d16, d17 - vsub.f32 d5, d16, d17 - vadd.f32 d18, d18, d19 - vsub.f32 d19, d26, d27 - - vadd.f32 d20, d22, d23 - vsub.f32 d22, d22, d23 - vsub.f32 d23, d24, d25 - vadd.f32 q8, q2, q9 @ {r0,i0,r1,i1} - vadd.f32 d21, d24, d25 - vmul.f32 d24, d22, d2 - vsub.f32 q9, q2, q9 @ {r2,i2,r3,i3} - vmul.f32 d25, d23, d3 - vuzp.32 d16, d17 @ {r0,r1,i0,i1} - vmul.f32 q1, q11, d2[1] - vuzp.32 d18, d19 @ {r2,r3,i2,i3} - vrev64.32 q12, q12 - vadd.f32 q11, q12, q1 @ {t1a,t2a,t5,t6} - vld1.32 {d24-d27}, [r0,:128]! @ q12{r8,i8,r9,i9} q13{r10,i10,r11,i11} - vzip.32 q10, q11 - vld1.32 {d28-d31}, [r0,:128] @ q14{r12,i12,r13,i13} q15{r14,i14,r15,i15} - vadd.f32 d0, d22, d20 - vadd.f32 d1, d21, d23 - vsub.f32 d2, d21, d23 - vsub.f32 d3, d22, d20 - sub r0, r0, #96 - vext.32 q13, q13, q13, #1 - vsub.f32 q10, q8, q0 @ {r4,r5,i4,i5} - vadd.f32 q8, q8, q0 @ {r0,r1,i0,i1} - vext.32 q15, q15, q15, #1 - vsub.f32 q11, q9, q1 @ {r6,r7,i6,i7} - vswp d25, d26 @ q12{r8,i8,i10,r11} q13{r9,i9,i11,r10} - vadd.f32 q9, q9, q1 @ {r2,r3,i2,i3} - vswp d29, d30 @ q14{r12,i12,i14,r15} q15{r13,i13,i15,r14} - vadd.f32 q0, q12, q13 @ {t1,t2,t5,t6} - vadd.f32 q1, q14, q15 @ {t1a,t2a,t5a,t6a} - movrel r2, X(ff_cos_16) - vsub.f32 q13, q12, q13 @ {t3,t4,t7,t8} - vrev64.32 d1, d1 - vsub.f32 q15, q14, q15 @ {t3a,t4a,t7a,t8a} - vrev64.32 d3, d3 - movrel r3, pmmp - vswp d1, d26 @ q0{t1,t2,t3,t4} q13{t6,t5,t7,t8} - vswp d3, d30 @ q1{t1a,t2a,t3a,t4a} q15{t6a,t5a,t7a,t8a} - vadd.f32 q12, q0, q13 @ {r8,i8,r9,i9} - vadd.f32 q14, q1, q15 @ {r12,i12,r13,i13} - vld1.32 {d4-d5}, [r2,:64] - vsub.f32 q13, q0, q13 @ {r10,i10,r11,i11} - vsub.f32 q15, q1, q15 @ {r14,i14,r15,i15} - vswp d25, d28 @ q12{r8,i8,r12,i12} q14{r9,i9,r13,i13} - vld1.32 {d6-d7}, [r3,:128] - vrev64.32 q1, q14 - vmul.f32 q14, q14, d4[1] - vmul.f32 q1, q1, q3 - vmla.f32 q14, q1, d5[1] @ {t1a,t2a,t5a,t6a} - vswp d27, d30 @ q13{r10,i10,r14,i14} q15{r11,i11,r15,i15} - vzip.32 q12, q14 - vadd.f32 d0, d28, d24 - vadd.f32 d1, d25, d29 - vsub.f32 d2, d25, d29 - vsub.f32 d3, d28, d24 - vsub.f32 q12, q8, q0 @ {r8,r9,i8,i9} - vadd.f32 q8, q8, q0 @ {r0,r1,i0,i1} - vsub.f32 q14, q10, q1 @ {r12,r13,i12,i13} - mov r1, #32 - vadd.f32 q10, q10, q1 @ {r4,r5,i4,i5} - vrev64.32 q0, q13 - vmul.f32 q13, q13, d5[0] - vrev64.32 q1, q15 - vmul.f32 q15, q15, d5[1] - vst2.32 {d16-d17},[r0,:128], r1 - vmul.f32 q0, q0, q3 - vst2.32 {d20-d21},[r0,:128], r1 - vmul.f32 q1, q1, q3 - vmla.f32 q13, q0, d5[0] @ {t1,t2,t5,t6} - vmla.f32 q15, q1, d4[1] @ {t1a,t2a,t5a,t6a} - vst2.32 {d24-d25},[r0,:128], r1 - vst2.32 {d28-d29},[r0,:128] - vzip.32 q13, q15 - sub r0, r0, #80 - vadd.f32 d0, d30, d26 - vadd.f32 d1, d27, d31 - vsub.f32 d2, d27, d31 - vsub.f32 d3, d30, d26 - vsub.f32 q13, q9, q0 @ {r10,r11,i10,i11} - vadd.f32 q9, q9, q0 @ {r2,r3,i2,i3} - vsub.f32 q15, q11, q1 @ {r14,r15,i14,i15} - vadd.f32 q11, q11, q1 @ {r6,r7,i6,i7} - vst2.32 {d18-d19},[r0,:128], r1 - vst2.32 {d22-d23},[r0,:128], r1 - vst2.32 {d26-d27},[r0,:128], r1 - vst2.32 {d30-d31},[r0,:128] - bx lr -endfunc - -function fft_pass_neon - push {r4-r6,lr} - mov r6, r2 @ n - lsl r5, r2, #3 @ 2 * n * sizeof FFTSample - lsl r4, r2, #4 @ 2 * n * sizeof FFTComplex - lsl r2, r2, #5 @ 4 * n * sizeof FFTComplex - add r3, r2, r4 - add r4, r4, r0 @ &z[o1] - add r2, r2, r0 @ &z[o2] - add r3, r3, r0 @ &z[o3] - vld1.32 {d20-d21},[r2,:128] @ {z[o2],z[o2+1]} - movrel r12, pmmp - vld1.32 {d22-d23},[r3,:128] @ {z[o3],z[o3+1]} - add r5, r5, r1 @ wim - vld1.32 {d6-d7}, [r12,:128] @ pmmp - vswp d21, d22 - vld1.32 {d4}, [r1,:64]! @ {wre[0],wre[1]} - sub r5, r5, #4 @ wim-- - vrev64.32 q1, q11 - vmul.f32 q11, q11, d4[1] - vmul.f32 q1, q1, q3 - vld1.32 {d5[0]}, [r5,:32] @ d5[0] = wim[-1] - vmla.f32 q11, q1, d5[0] @ {t1a,t2a,t5a,t6a} - vld2.32 {d16-d17},[r0,:128] @ {z[0],z[1]} - sub r6, r6, #1 @ n-- - vld2.32 {d18-d19},[r4,:128] @ {z[o1],z[o1+1]} - vzip.32 q10, q11 - vadd.f32 d0, d22, d20 - vadd.f32 d1, d21, d23 - vsub.f32 d2, d21, d23 - vsub.f32 d3, d22, d20 - vsub.f32 q10, q8, q0 - vadd.f32 q8, q8, q0 - vsub.f32 q11, q9, q1 - vadd.f32 q9, q9, q1 - vst2.32 {d20-d21},[r2,:128]! @ {z[o2],z[o2+1]} - vst2.32 {d16-d17},[r0,:128]! @ {z[0],z[1]} - vst2.32 {d22-d23},[r3,:128]! @ {z[o3],z[o3+1]} - vst2.32 {d18-d19},[r4,:128]! @ {z[o1],z[o1+1]} - sub r5, r5, #8 @ wim -= 2 -1: - vld1.32 {d20-d21},[r2,:128] @ {z[o2],z[o2+1]} - vld1.32 {d22-d23},[r3,:128] @ {z[o3],z[o3+1]} - vswp d21, d22 - vld1.32 {d4}, [r1]! @ {wre[0],wre[1]} - vrev64.32 q0, q10 - vmul.f32 q10, q10, d4[0] - vrev64.32 q1, q11 - vmul.f32 q11, q11, d4[1] - vld1.32 {d5}, [r5] @ {wim[-1],wim[0]} - vmul.f32 q0, q0, q3 - sub r5, r5, #8 @ wim -= 2 - vmul.f32 q1, q1, q3 - vmla.f32 q10, q0, d5[1] @ {t1,t2,t5,t6} - vmla.f32 q11, q1, d5[0] @ {t1a,t2a,t5a,t6a} - vld2.32 {d16-d17},[r0,:128] @ {z[0],z[1]} - subs r6, r6, #1 @ n-- - vld2.32 {d18-d19},[r4,:128] @ {z[o1],z[o1+1]} - vzip.32 q10, q11 - vadd.f32 d0, d22, d20 - vadd.f32 d1, d21, d23 - vsub.f32 d2, d21, d23 - vsub.f32 d3, d22, d20 - vsub.f32 q10, q8, q0 - vadd.f32 q8, q8, q0 - vsub.f32 q11, q9, q1 - vadd.f32 q9, q9, q1 - vst2.32 {d20-d21}, [r2,:128]! @ {z[o2],z[o2+1]} - vst2.32 {d16-d17}, [r0,:128]! @ {z[0],z[1]} - vst2.32 {d22-d23}, [r3,:128]! @ {z[o3],z[o3+1]} - vst2.32 {d18-d19}, [r4,:128]! @ {z[o1],z[o1+1]} - bne 1b - - pop {r4-r6,pc} -endfunc - -.macro def_fft n, n2, n4 - .align 6 -function fft\n\()_neon - push {r4, lr} - mov r4, r0 - bl fft\n2\()_neon - add r0, r4, #\n4*2*8 - bl fft\n4\()_neon - add r0, r4, #\n4*3*8 - bl fft\n4\()_neon - mov r0, r4 - pop {r4, lr} - movrel r1, X(ff_cos_\n) - mov r2, #\n4/2 - b fft_pass_neon -endfunc -.endm - - def_fft 32, 16, 8 - def_fft 64, 32, 16 - def_fft 128, 64, 32 - def_fft 256, 128, 64 - def_fft 512, 256, 128 - def_fft 1024, 512, 256 - def_fft 2048, 1024, 512 - def_fft 4096, 2048, 1024 - def_fft 8192, 4096, 2048 - def_fft 16384, 8192, 4096 - def_fft 32768, 16384, 8192 - def_fft 65536, 32768, 16384 - -function ff_fft_calc_neon, export=1 - ldr r2, [r0] - sub r2, r2, #2 - movrel r3, fft_tab_neon - ldr r3, [r3, r2, lsl #2] - mov r0, r1 - bx r3 -endfunc - -function ff_fft_permute_neon, export=1 - push {r4,lr} - mov r12, #1 - ldr r2, [r0] @ nbits - ldr r3, [r0, #20] @ tmp_buf - ldr r0, [r0, #8] @ revtab - lsl r12, r12, r2 - mov r2, r12 -1: - vld1.32 {d0-d1}, [r1,:128]! - ldr r4, [r0], #4 - uxth lr, r4 - uxth r4, r4, ror #16 - add lr, r3, lr, lsl #3 - add r4, r3, r4, lsl #3 - vst1.32 {d0}, [lr,:64] - vst1.32 {d1}, [r4,:64] - subs r12, r12, #2 - bgt 1b - - sub r1, r1, r2, lsl #3 -1: - vld1.32 {d0-d3}, [r3,:128]! - vst1.32 {d0-d3}, [r1,:128]! - subs r2, r2, #4 - bgt 1b - - pop {r4,pc} -endfunc - - .section .rodata - .align 4 -fft_tab_neon: - .word fft4_neon - .word fft8_neon - .word fft16_neon - .word fft32_neon - .word fft64_neon - .word fft128_neon - .word fft256_neon - .word fft512_neon - .word fft1024_neon - .word fft2048_neon - .word fft4096_neon - .word fft8192_neon - .word fft16384_neon - .word fft32768_neon - .word fft65536_neon - .size fft_tab_neon, . - fft_tab_neon - - .align 4 -pmmp: .float +1.0, -1.0, -1.0, +1.0 -mppm: .float -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2 diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_init_arm.c b/tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_init_arm.c deleted file mode 100644 index c06c3d0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_init_arm.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavcodec/dsputil.h" -#include "libavcodec/h264dsp.h" - -void ff_h264_v_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha, - int beta, int8_t *tc0); -void ff_h264_h_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha, - int beta, int8_t *tc0); -void ff_h264_v_loop_filter_chroma_neon(uint8_t *pix, int stride, int alpha, - int beta, int8_t *tc0); -void ff_h264_h_loop_filter_chroma_neon(uint8_t *pix, int stride, int alpha, - int beta, int8_t *tc0); - -void ff_weight_h264_pixels_16x16_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); -void ff_weight_h264_pixels_16x8_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); -void ff_weight_h264_pixels_8x16_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); -void ff_weight_h264_pixels_8x8_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); -void ff_weight_h264_pixels_8x4_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); -void ff_weight_h264_pixels_4x8_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); -void ff_weight_h264_pixels_4x4_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); -void ff_weight_h264_pixels_4x2_neon(uint8_t *ds, int stride, int log2_den, - int weight, int offset); - -void ff_biweight_h264_pixels_16x16_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); -void ff_biweight_h264_pixels_16x8_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); -void ff_biweight_h264_pixels_8x16_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); -void ff_biweight_h264_pixels_8x8_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); -void ff_biweight_h264_pixels_8x4_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); -void ff_biweight_h264_pixels_4x8_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); -void ff_biweight_h264_pixels_4x4_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); -void ff_biweight_h264_pixels_4x2_neon(uint8_t *dst, uint8_t *src, int stride, - int log2_den, int weightd, int weights, - int offset); - -void ff_h264_idct_add_neon(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct_dc_add_neon(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset, - DCTELEM *block, int stride, - const uint8_t nnzc[6*8]); -void ff_h264_idct_add16intra_neon(uint8_t *dst, const int *block_offset, - DCTELEM *block, int stride, - const uint8_t nnzc[6*8]); -void ff_h264_idct_add8_neon(uint8_t **dest, const int *block_offset, - DCTELEM *block, int stride, - const uint8_t nnzc[6*8]); - -#if HAVE_NEON -static void ff_h264dsp_init_neon(H264DSPContext *c) -{ - c->h264_v_loop_filter_luma = ff_h264_v_loop_filter_luma_neon; - c->h264_h_loop_filter_luma = ff_h264_h_loop_filter_luma_neon; - c->h264_v_loop_filter_chroma = ff_h264_v_loop_filter_chroma_neon; - c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma_neon; - - c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16x16_neon; - c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels_16x8_neon; - c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels_8x16_neon; - c->weight_h264_pixels_tab[3] = ff_weight_h264_pixels_8x8_neon; - c->weight_h264_pixels_tab[4] = ff_weight_h264_pixels_8x4_neon; - c->weight_h264_pixels_tab[5] = ff_weight_h264_pixels_4x8_neon; - c->weight_h264_pixels_tab[6] = ff_weight_h264_pixels_4x4_neon; - c->weight_h264_pixels_tab[7] = ff_weight_h264_pixels_4x2_neon; - - c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels_16x16_neon; - c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels_16x8_neon; - c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels_8x16_neon; - c->biweight_h264_pixels_tab[3] = ff_biweight_h264_pixels_8x8_neon; - c->biweight_h264_pixels_tab[4] = ff_biweight_h264_pixels_8x4_neon; - c->biweight_h264_pixels_tab[5] = ff_biweight_h264_pixels_4x8_neon; - c->biweight_h264_pixels_tab[6] = ff_biweight_h264_pixels_4x4_neon; - c->biweight_h264_pixels_tab[7] = ff_biweight_h264_pixels_4x2_neon; - - c->h264_idct_add = ff_h264_idct_add_neon; - c->h264_idct_dc_add = ff_h264_idct_dc_add_neon; - c->h264_idct_add16 = ff_h264_idct_add16_neon; - c->h264_idct_add16intra = ff_h264_idct_add16intra_neon; - c->h264_idct_add8 = ff_h264_idct_add8_neon; -} -#endif - -void ff_h264dsp_init_arm(H264DSPContext *c) -{ - if (HAVE_NEON) ff_h264dsp_init_neon(c); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_neon.S deleted file mode 100644 index d9cdad8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/h264dsp_neon.S +++ /dev/null @@ -1,1883 +0,0 @@ -/* - * Copyright (c) 2008 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - .macro transpose_8x8 r0 r1 r2 r3 r4 r5 r6 r7 - vtrn.32 \r0, \r4 - vtrn.32 \r1, \r5 - vtrn.32 \r2, \r6 - vtrn.32 \r3, \r7 - vtrn.16 \r0, \r2 - vtrn.16 \r1, \r3 - vtrn.16 \r4, \r6 - vtrn.16 \r5, \r7 - vtrn.8 \r0, \r1 - vtrn.8 \r2, \r3 - vtrn.8 \r4, \r5 - vtrn.8 \r6, \r7 - .endm - - .macro transpose_4x4 r0 r1 r2 r3 - vtrn.16 \r0, \r2 - vtrn.16 \r1, \r3 - vtrn.8 \r0, \r1 - vtrn.8 \r2, \r3 - .endm - - .macro swap4 r0 r1 r2 r3 r4 r5 r6 r7 - vswp \r0, \r4 - vswp \r1, \r5 - vswp \r2, \r6 - vswp \r3, \r7 - .endm - - .macro transpose16_4x4 r0 r1 r2 r3 r4 r5 r6 r7 - vtrn.32 \r0, \r2 - vtrn.32 \r1, \r3 - vtrn.32 \r4, \r6 - vtrn.32 \r5, \r7 - vtrn.16 \r0, \r1 - vtrn.16 \r2, \r3 - vtrn.16 \r4, \r5 - vtrn.16 \r6, \r7 - .endm - -/* chroma_mc8(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */ - .macro h264_chroma_mc8 type -function ff_\type\()_h264_chroma_mc8_neon, export=1 - push {r4-r7, lr} - ldrd r4, [sp, #20] -.ifc \type,avg - mov lr, r0 -.endif - pld [r1] - pld [r1, r2] - - muls r7, r4, r5 - rsb r6, r7, r5, lsl #3 - rsb ip, r7, r4, lsl #3 - sub r4, r7, r4, lsl #3 - sub r4, r4, r5, lsl #3 - add r4, r4, #64 - - beq 2f - - add r5, r1, r2 - - vdup.8 d0, r4 - lsl r4, r2, #1 - vdup.8 d1, ip - vld1.64 {d4, d5}, [r1], r4 - vdup.8 d2, r6 - vld1.64 {d6, d7}, [r5], r4 - vdup.8 d3, r7 - - vext.8 d5, d4, d5, #1 - vext.8 d7, d6, d7, #1 - -1: pld [r5] - vmull.u8 q8, d4, d0 - vmlal.u8 q8, d5, d1 - vld1.64 {d4, d5}, [r1], r4 - vmlal.u8 q8, d6, d2 - vext.8 d5, d4, d5, #1 - vmlal.u8 q8, d7, d3 - vmull.u8 q9, d6, d0 - subs r3, r3, #2 - vmlal.u8 q9, d7, d1 - vmlal.u8 q9, d4, d2 - vmlal.u8 q9, d5, d3 - vrshrn.u16 d16, q8, #6 - vld1.64 {d6, d7}, [r5], r4 - pld [r1] - vrshrn.u16 d17, q9, #6 -.ifc \type,avg - vld1.64 {d20}, [lr,:64], r2 - vld1.64 {d21}, [lr,:64], r2 - vrhadd.u8 q8, q8, q10 -.endif - vext.8 d7, d6, d7, #1 - vst1.64 {d16}, [r0,:64], r2 - vst1.64 {d17}, [r0,:64], r2 - bgt 1b - - pop {r4-r7, pc} - -2: tst r6, r6 - add ip, ip, r6 - vdup.8 d0, r4 - vdup.8 d1, ip - - beq 4f - - add r5, r1, r2 - lsl r4, r2, #1 - vld1.64 {d4}, [r1], r4 - vld1.64 {d6}, [r5], r4 - -3: pld [r5] - vmull.u8 q8, d4, d0 - vmlal.u8 q8, d6, d1 - vld1.64 {d4}, [r1], r4 - vmull.u8 q9, d6, d0 - vmlal.u8 q9, d4, d1 - vld1.64 {d6}, [r5], r4 - vrshrn.u16 d16, q8, #6 - vrshrn.u16 d17, q9, #6 -.ifc \type,avg - vld1.64 {d20}, [lr,:64], r2 - vld1.64 {d21}, [lr,:64], r2 - vrhadd.u8 q8, q8, q10 -.endif - subs r3, r3, #2 - pld [r1] - vst1.64 {d16}, [r0,:64], r2 - vst1.64 {d17}, [r0,:64], r2 - bgt 3b - - pop {r4-r7, pc} - -4: vld1.64 {d4, d5}, [r1], r2 - vld1.64 {d6, d7}, [r1], r2 - vext.8 d5, d4, d5, #1 - vext.8 d7, d6, d7, #1 - -5: pld [r1] - subs r3, r3, #2 - vmull.u8 q8, d4, d0 - vmlal.u8 q8, d5, d1 - vld1.64 {d4, d5}, [r1], r2 - vmull.u8 q9, d6, d0 - vmlal.u8 q9, d7, d1 - pld [r1] - vext.8 d5, d4, d5, #1 - vrshrn.u16 d16, q8, #6 - vrshrn.u16 d17, q9, #6 -.ifc \type,avg - vld1.64 {d20}, [lr,:64], r2 - vld1.64 {d21}, [lr,:64], r2 - vrhadd.u8 q8, q8, q10 -.endif - vld1.64 {d6, d7}, [r1], r2 - vext.8 d7, d6, d7, #1 - vst1.64 {d16}, [r0,:64], r2 - vst1.64 {d17}, [r0,:64], r2 - bgt 5b - - pop {r4-r7, pc} -endfunc - .endm - -/* chroma_mc4(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */ - .macro h264_chroma_mc4 type -function ff_\type\()_h264_chroma_mc4_neon, export=1 - push {r4-r7, lr} - ldrd r4, [sp, #20] -.ifc \type,avg - mov lr, r0 -.endif - pld [r1] - pld [r1, r2] - - muls r7, r4, r5 - rsb r6, r7, r5, lsl #3 - rsb ip, r7, r4, lsl #3 - sub r4, r7, r4, lsl #3 - sub r4, r4, r5, lsl #3 - add r4, r4, #64 - - beq 2f - - add r5, r1, r2 - - vdup.8 d0, r4 - lsl r4, r2, #1 - vdup.8 d1, ip - vld1.64 {d4}, [r1], r4 - vdup.8 d2, r6 - vld1.64 {d6}, [r5], r4 - vdup.8 d3, r7 - - vext.8 d5, d4, d5, #1 - vext.8 d7, d6, d7, #1 - vtrn.32 d4, d5 - vtrn.32 d6, d7 - - vtrn.32 d0, d1 - vtrn.32 d2, d3 - -1: pld [r5] - vmull.u8 q8, d4, d0 - vmlal.u8 q8, d6, d2 - vld1.64 {d4}, [r1], r4 - vext.8 d5, d4, d5, #1 - vtrn.32 d4, d5 - vmull.u8 q9, d6, d0 - vmlal.u8 q9, d4, d2 - vld1.64 {d6}, [r5], r4 - vadd.i16 d16, d16, d17 - vadd.i16 d17, d18, d19 - vrshrn.u16 d16, q8, #6 - subs r3, r3, #2 - pld [r1] -.ifc \type,avg - vld1.32 {d20[0]}, [lr,:32], r2 - vld1.32 {d20[1]}, [lr,:32], r2 - vrhadd.u8 d16, d16, d20 -.endif - vext.8 d7, d6, d7, #1 - vtrn.32 d6, d7 - vst1.32 {d16[0]}, [r0,:32], r2 - vst1.32 {d16[1]}, [r0,:32], r2 - bgt 1b - - pop {r4-r7, pc} - -2: tst r6, r6 - add ip, ip, r6 - vdup.8 d0, r4 - vdup.8 d1, ip - vtrn.32 d0, d1 - - beq 4f - - vext.32 d1, d0, d1, #1 - add r5, r1, r2 - lsl r4, r2, #1 - vld1.32 {d4[0]}, [r1], r4 - vld1.32 {d4[1]}, [r5], r4 - -3: pld [r5] - vmull.u8 q8, d4, d0 - vld1.32 {d4[0]}, [r1], r4 - vmull.u8 q9, d4, d1 - vld1.32 {d4[1]}, [r5], r4 - vadd.i16 d16, d16, d17 - vadd.i16 d17, d18, d19 - vrshrn.u16 d16, q8, #6 -.ifc \type,avg - vld1.32 {d20[0]}, [lr,:32], r2 - vld1.32 {d20[1]}, [lr,:32], r2 - vrhadd.u8 d16, d16, d20 -.endif - subs r3, r3, #2 - pld [r1] - vst1.32 {d16[0]}, [r0,:32], r2 - vst1.32 {d16[1]}, [r0,:32], r2 - bgt 3b - - pop {r4-r7, pc} - -4: vld1.64 {d4}, [r1], r2 - vld1.64 {d6}, [r1], r2 - vext.8 d5, d4, d5, #1 - vext.8 d7, d6, d7, #1 - vtrn.32 d4, d5 - vtrn.32 d6, d7 - -5: vmull.u8 q8, d4, d0 - vmull.u8 q9, d6, d0 - subs r3, r3, #2 - vld1.64 {d4}, [r1], r2 - vext.8 d5, d4, d5, #1 - vtrn.32 d4, d5 - vadd.i16 d16, d16, d17 - vadd.i16 d17, d18, d19 - pld [r1] - vrshrn.u16 d16, q8, #6 -.ifc \type,avg - vld1.32 {d20[0]}, [lr,:32], r2 - vld1.32 {d20[1]}, [lr,:32], r2 - vrhadd.u8 d16, d16, d20 -.endif - vld1.64 {d6}, [r1], r2 - vext.8 d7, d6, d7, #1 - vtrn.32 d6, d7 - pld [r1] - vst1.32 {d16[0]}, [r0,:32], r2 - vst1.32 {d16[1]}, [r0,:32], r2 - bgt 5b - - pop {r4-r7, pc} -endfunc - .endm - - .macro h264_chroma_mc2 type -function ff_\type\()_h264_chroma_mc2_neon, export=1 - push {r4-r6, lr} - ldr r4, [sp, #16] - ldr lr, [sp, #20] - pld [r1] - pld [r1, r2] - orrs r5, r4, lr - beq 2f - - mul r5, r4, lr - rsb r6, r5, lr, lsl #3 - rsb r12, r5, r4, lsl #3 - sub r4, r5, r4, lsl #3 - sub r4, r4, lr, lsl #3 - add r4, r4, #64 - vdup.8 d0, r4 - vdup.8 d2, r12 - vdup.8 d1, r6 - vdup.8 d3, r5 - vtrn.16 q0, q1 -1: - vld1.32 {d4[0]}, [r1], r2 - vld1.32 {d4[1]}, [r1], r2 - vrev64.32 d5, d4 - vld1.32 {d5[1]}, [r1] - vext.8 q3, q2, q2, #1 - vtrn.16 q2, q3 - vmull.u8 q8, d4, d0 - vmlal.u8 q8, d5, d1 -.ifc \type,avg - vld1.16 {d18[0]}, [r0,:16], r2 - vld1.16 {d18[1]}, [r0,:16] - sub r0, r0, r2 -.endif - vtrn.32 d16, d17 - vadd.i16 d16, d16, d17 - vrshrn.u16 d16, q8, #6 -.ifc \type,avg - vrhadd.u8 d16, d16, d18 -.endif - vst1.16 {d16[0]}, [r0,:16], r2 - vst1.16 {d16[1]}, [r0,:16], r2 - subs r3, r3, #2 - bgt 1b - pop {r4-r6, pc} -2: -.ifc \type,put - ldrh r5, [r1], r2 - strh r5, [r0], r2 - ldrh r6, [r1], r2 - strh r6, [r0], r2 -.else - vld1.16 {d16[0]}, [r1], r2 - vld1.16 {d16[1]}, [r1], r2 - vld1.16 {d18[0]}, [r0,:16], r2 - vld1.16 {d18[1]}, [r0,:16] - sub r0, r0, r2 - vrhadd.u8 d16, d16, d18 - vst1.16 {d16[0]}, [r0,:16], r2 - vst1.16 {d16[1]}, [r0,:16], r2 -.endif - subs r3, r3, #2 - bgt 2b - pop {r4-r6, pc} -endfunc -.endm - - .text - .align - - h264_chroma_mc8 put - h264_chroma_mc8 avg - h264_chroma_mc4 put - h264_chroma_mc4 avg - h264_chroma_mc2 put - h264_chroma_mc2 avg - - /* H.264 loop filter */ - - .macro h264_loop_filter_start - ldr ip, [sp] - tst r2, r2 - ldr ip, [ip] - tstne r3, r3 - vmov.32 d24[0], ip - and ip, ip, ip, lsl #16 - bxeq lr - ands ip, ip, ip, lsl #8 - bxlt lr - .endm - - .macro align_push_regs - and ip, sp, #15 - add ip, ip, #32 - sub sp, sp, ip - vst1.64 {d12-d15}, [sp,:128] - sub sp, sp, #32 - vst1.64 {d8-d11}, [sp,:128] - .endm - - .macro align_pop_regs - vld1.64 {d8-d11}, [sp,:128]! - vld1.64 {d12-d15}, [sp,:128], ip - .endm - - .macro h264_loop_filter_luma - vdup.8 q11, r2 @ alpha - vmovl.u8 q12, d24 - vabd.u8 q6, q8, q0 @ abs(p0 - q0) - vmovl.u16 q12, d24 - vabd.u8 q14, q9, q8 @ abs(p1 - p0) - vsli.16 q12, q12, #8 - vabd.u8 q15, q1, q0 @ abs(q1 - q0) - vsli.32 q12, q12, #16 - vclt.u8 q6, q6, q11 @ < alpha - vdup.8 q11, r3 @ beta - vclt.s8 q7, q12, #0 - vclt.u8 q14, q14, q11 @ < beta - vclt.u8 q15, q15, q11 @ < beta - vbic q6, q6, q7 - vabd.u8 q4, q10, q8 @ abs(p2 - p0) - vand q6, q6, q14 - vabd.u8 q5, q2, q0 @ abs(q2 - q0) - vclt.u8 q4, q4, q11 @ < beta - vand q6, q6, q15 - vclt.u8 q5, q5, q11 @ < beta - vand q4, q4, q6 - vand q5, q5, q6 - vand q12, q12, q6 - vrhadd.u8 q14, q8, q0 - vsub.i8 q6, q12, q4 - vqadd.u8 q7, q9, q12 - vhadd.u8 q10, q10, q14 - vsub.i8 q6, q6, q5 - vhadd.u8 q14, q2, q14 - vmin.u8 q7, q7, q10 - vqsub.u8 q11, q9, q12 - vqadd.u8 q2, q1, q12 - vmax.u8 q7, q7, q11 - vqsub.u8 q11, q1, q12 - vmin.u8 q14, q2, q14 - vmovl.u8 q2, d0 - vmax.u8 q14, q14, q11 - vmovl.u8 q10, d1 - vsubw.u8 q2, q2, d16 - vsubw.u8 q10, q10, d17 - vshl.i16 q2, q2, #2 - vshl.i16 q10, q10, #2 - vaddw.u8 q2, q2, d18 - vaddw.u8 q10, q10, d19 - vsubw.u8 q2, q2, d2 - vsubw.u8 q10, q10, d3 - vrshrn.i16 d4, q2, #3 - vrshrn.i16 d5, q10, #3 - vbsl q4, q7, q9 - vbsl q5, q14, q1 - vneg.s8 q7, q6 - vmovl.u8 q14, d16 - vmin.s8 q2, q2, q6 - vmovl.u8 q6, d17 - vmax.s8 q2, q2, q7 - vmovl.u8 q11, d0 - vmovl.u8 q12, d1 - vaddw.s8 q14, q14, d4 - vaddw.s8 q6, q6, d5 - vsubw.s8 q11, q11, d4 - vsubw.s8 q12, q12, d5 - vqmovun.s16 d16, q14 - vqmovun.s16 d17, q6 - vqmovun.s16 d0, q11 - vqmovun.s16 d1, q12 - .endm - -function ff_h264_v_loop_filter_luma_neon, export=1 - h264_loop_filter_start - - vld1.64 {d0, d1}, [r0,:128], r1 - vld1.64 {d2, d3}, [r0,:128], r1 - vld1.64 {d4, d5}, [r0,:128], r1 - sub r0, r0, r1, lsl #2 - sub r0, r0, r1, lsl #1 - vld1.64 {d20,d21}, [r0,:128], r1 - vld1.64 {d18,d19}, [r0,:128], r1 - vld1.64 {d16,d17}, [r0,:128], r1 - - align_push_regs - - h264_loop_filter_luma - - sub r0, r0, r1, lsl #1 - vst1.64 {d8, d9}, [r0,:128], r1 - vst1.64 {d16,d17}, [r0,:128], r1 - vst1.64 {d0, d1}, [r0,:128], r1 - vst1.64 {d10,d11}, [r0,:128] - - align_pop_regs - bx lr -endfunc - -function ff_h264_h_loop_filter_luma_neon, export=1 - h264_loop_filter_start - - sub r0, r0, #4 - vld1.64 {d6}, [r0], r1 - vld1.64 {d20}, [r0], r1 - vld1.64 {d18}, [r0], r1 - vld1.64 {d16}, [r0], r1 - vld1.64 {d0}, [r0], r1 - vld1.64 {d2}, [r0], r1 - vld1.64 {d4}, [r0], r1 - vld1.64 {d26}, [r0], r1 - vld1.64 {d7}, [r0], r1 - vld1.64 {d21}, [r0], r1 - vld1.64 {d19}, [r0], r1 - vld1.64 {d17}, [r0], r1 - vld1.64 {d1}, [r0], r1 - vld1.64 {d3}, [r0], r1 - vld1.64 {d5}, [r0], r1 - vld1.64 {d27}, [r0], r1 - - transpose_8x8 q3, q10, q9, q8, q0, q1, q2, q13 - - align_push_regs - - h264_loop_filter_luma - - transpose_4x4 q4, q8, q0, q5 - - sub r0, r0, r1, lsl #4 - add r0, r0, #2 - vst1.32 {d8[0]}, [r0], r1 - vst1.32 {d16[0]}, [r0], r1 - vst1.32 {d0[0]}, [r0], r1 - vst1.32 {d10[0]}, [r0], r1 - vst1.32 {d8[1]}, [r0], r1 - vst1.32 {d16[1]}, [r0], r1 - vst1.32 {d0[1]}, [r0], r1 - vst1.32 {d10[1]}, [r0], r1 - vst1.32 {d9[0]}, [r0], r1 - vst1.32 {d17[0]}, [r0], r1 - vst1.32 {d1[0]}, [r0], r1 - vst1.32 {d11[0]}, [r0], r1 - vst1.32 {d9[1]}, [r0], r1 - vst1.32 {d17[1]}, [r0], r1 - vst1.32 {d1[1]}, [r0], r1 - vst1.32 {d11[1]}, [r0], r1 - - align_pop_regs - bx lr -endfunc - - .macro h264_loop_filter_chroma - vdup.8 d22, r2 @ alpha - vmovl.u8 q12, d24 - vabd.u8 d26, d16, d0 @ abs(p0 - q0) - vmovl.u8 q2, d0 - vabd.u8 d28, d18, d16 @ abs(p1 - p0) - vsubw.u8 q2, q2, d16 - vsli.16 d24, d24, #8 - vshl.i16 q2, q2, #2 - vabd.u8 d30, d2, d0 @ abs(q1 - q0) - vaddw.u8 q2, q2, d18 - vclt.u8 d26, d26, d22 @ < alpha - vsubw.u8 q2, q2, d2 - vdup.8 d22, r3 @ beta - vclt.s8 d25, d24, #0 - vrshrn.i16 d4, q2, #3 - vclt.u8 d28, d28, d22 @ < beta - vbic d26, d26, d25 - vclt.u8 d30, d30, d22 @ < beta - vand d26, d26, d28 - vneg.s8 d25, d24 - vand d26, d26, d30 - vmin.s8 d4, d4, d24 - vmovl.u8 q14, d16 - vand d4, d4, d26 - vmax.s8 d4, d4, d25 - vmovl.u8 q11, d0 - vaddw.s8 q14, q14, d4 - vsubw.s8 q11, q11, d4 - vqmovun.s16 d16, q14 - vqmovun.s16 d0, q11 - .endm - -function ff_h264_v_loop_filter_chroma_neon, export=1 - h264_loop_filter_start - - sub r0, r0, r1, lsl #1 - vld1.64 {d18}, [r0,:64], r1 - vld1.64 {d16}, [r0,:64], r1 - vld1.64 {d0}, [r0,:64], r1 - vld1.64 {d2}, [r0,:64] - - h264_loop_filter_chroma - - sub r0, r0, r1, lsl #1 - vst1.64 {d16}, [r0,:64], r1 - vst1.64 {d0}, [r0,:64], r1 - - bx lr -endfunc - -function ff_h264_h_loop_filter_chroma_neon, export=1 - h264_loop_filter_start - - sub r0, r0, #2 - vld1.32 {d18[0]}, [r0], r1 - vld1.32 {d16[0]}, [r0], r1 - vld1.32 {d0[0]}, [r0], r1 - vld1.32 {d2[0]}, [r0], r1 - vld1.32 {d18[1]}, [r0], r1 - vld1.32 {d16[1]}, [r0], r1 - vld1.32 {d0[1]}, [r0], r1 - vld1.32 {d2[1]}, [r0], r1 - - vtrn.16 d18, d0 - vtrn.16 d16, d2 - vtrn.8 d18, d16 - vtrn.8 d0, d2 - - h264_loop_filter_chroma - - vtrn.16 d18, d0 - vtrn.16 d16, d2 - vtrn.8 d18, d16 - vtrn.8 d0, d2 - - sub r0, r0, r1, lsl #3 - vst1.32 {d18[0]}, [r0], r1 - vst1.32 {d16[0]}, [r0], r1 - vst1.32 {d0[0]}, [r0], r1 - vst1.32 {d2[0]}, [r0], r1 - vst1.32 {d18[1]}, [r0], r1 - vst1.32 {d16[1]}, [r0], r1 - vst1.32 {d0[1]}, [r0], r1 - vst1.32 {d2[1]}, [r0], r1 - - bx lr -endfunc - - /* H.264 qpel MC */ - - .macro lowpass_const r - movw \r, #5 - movt \r, #20 - vmov.32 d6[0], \r - .endm - - .macro lowpass_8 r0, r1, r2, r3, d0, d1, narrow=1 -.if \narrow - t0 .req q0 - t1 .req q8 -.else - t0 .req \d0 - t1 .req \d1 -.endif - vext.8 d2, \r0, \r1, #2 - vext.8 d3, \r0, \r1, #3 - vaddl.u8 q1, d2, d3 - vext.8 d4, \r0, \r1, #1 - vext.8 d5, \r0, \r1, #4 - vaddl.u8 q2, d4, d5 - vext.8 d30, \r0, \r1, #5 - vaddl.u8 t0, \r0, d30 - vext.8 d18, \r2, \r3, #2 - vmla.i16 t0, q1, d6[1] - vext.8 d19, \r2, \r3, #3 - vaddl.u8 q9, d18, d19 - vext.8 d20, \r2, \r3, #1 - vmls.i16 t0, q2, d6[0] - vext.8 d21, \r2, \r3, #4 - vaddl.u8 q10, d20, d21 - vext.8 d31, \r2, \r3, #5 - vaddl.u8 t1, \r2, d31 - vmla.i16 t1, q9, d6[1] - vmls.i16 t1, q10, d6[0] -.if \narrow - vqrshrun.s16 \d0, t0, #5 - vqrshrun.s16 \d1, t1, #5 -.endif - .unreq t0 - .unreq t1 - .endm - - .macro lowpass_8_1 r0, r1, d0, narrow=1 -.if \narrow - t0 .req q0 -.else - t0 .req \d0 -.endif - vext.8 d2, \r0, \r1, #2 - vext.8 d3, \r0, \r1, #3 - vaddl.u8 q1, d2, d3 - vext.8 d4, \r0, \r1, #1 - vext.8 d5, \r0, \r1, #4 - vaddl.u8 q2, d4, d5 - vext.8 d30, \r0, \r1, #5 - vaddl.u8 t0, \r0, d30 - vmla.i16 t0, q1, d6[1] - vmls.i16 t0, q2, d6[0] -.if \narrow - vqrshrun.s16 \d0, t0, #5 -.endif - .unreq t0 - .endm - - .macro lowpass_8.16 r0, r1, l0, h0, l1, h1, d - vext.16 q1, \r0, \r1, #2 - vext.16 q0, \r0, \r1, #3 - vaddl.s16 q9, d2, d0 - vext.16 q2, \r0, \r1, #1 - vaddl.s16 q1, d3, d1 - vext.16 q3, \r0, \r1, #4 - vaddl.s16 q10, d4, d6 - vext.16 \r1, \r0, \r1, #5 - vaddl.s16 q2, d5, d7 - vaddl.s16 q0, \h0, \h1 - vaddl.s16 q8, \l0, \l1 - - vshl.i32 q3, q9, #4 - vshl.i32 q9, q9, #2 - vshl.i32 q15, q10, #2 - vadd.i32 q9, q9, q3 - vadd.i32 q10, q10, q15 - - vshl.i32 q3, q1, #4 - vshl.i32 q1, q1, #2 - vshl.i32 q15, q2, #2 - vadd.i32 q1, q1, q3 - vadd.i32 q2, q2, q15 - - vadd.i32 q9, q9, q8 - vsub.i32 q9, q9, q10 - - vadd.i32 q1, q1, q0 - vsub.i32 q1, q1, q2 - - vrshrn.s32 d18, q9, #10 - vrshrn.s32 d19, q1, #10 - - vqmovun.s16 \d, q9 - .endm - -function put_h264_qpel16_h_lowpass_neon_packed - mov r4, lr - mov ip, #16 - mov r3, #8 - bl put_h264_qpel8_h_lowpass_neon - sub r1, r1, r2, lsl #4 - add r1, r1, #8 - mov ip, #16 - mov lr, r4 - b put_h264_qpel8_h_lowpass_neon -endfunc - - .macro h264_qpel_h_lowpass type -function \type\()_h264_qpel16_h_lowpass_neon - push {lr} - mov ip, #16 - bl \type\()_h264_qpel8_h_lowpass_neon - sub r0, r0, r3, lsl #4 - sub r1, r1, r2, lsl #4 - add r0, r0, #8 - add r1, r1, #8 - mov ip, #16 - pop {lr} -endfunc - -function \type\()_h264_qpel8_h_lowpass_neon -1: vld1.64 {d0, d1}, [r1], r2 - vld1.64 {d16,d17}, [r1], r2 - subs ip, ip, #2 - lowpass_8 d0, d1, d16, d17, d0, d16 -.ifc \type,avg - vld1.8 {d2}, [r0,:64], r3 - vrhadd.u8 d0, d0, d2 - vld1.8 {d3}, [r0,:64] - vrhadd.u8 d16, d16, d3 - sub r0, r0, r3 -.endif - vst1.64 {d0}, [r0,:64], r3 - vst1.64 {d16}, [r0,:64], r3 - bne 1b - bx lr -endfunc - .endm - - h264_qpel_h_lowpass put - h264_qpel_h_lowpass avg - - .macro h264_qpel_h_lowpass_l2 type -function \type\()_h264_qpel16_h_lowpass_l2_neon - push {lr} - mov ip, #16 - bl \type\()_h264_qpel8_h_lowpass_l2_neon - sub r0, r0, r2, lsl #4 - sub r1, r1, r2, lsl #4 - sub r3, r3, r2, lsl #4 - add r0, r0, #8 - add r1, r1, #8 - add r3, r3, #8 - mov ip, #16 - pop {lr} -endfunc - -function \type\()_h264_qpel8_h_lowpass_l2_neon -1: vld1.64 {d0, d1}, [r1], r2 - vld1.64 {d16,d17}, [r1], r2 - vld1.64 {d28}, [r3], r2 - vld1.64 {d29}, [r3], r2 - subs ip, ip, #2 - lowpass_8 d0, d1, d16, d17, d0, d1 - vrhadd.u8 q0, q0, q14 -.ifc \type,avg - vld1.8 {d2}, [r0,:64], r2 - vrhadd.u8 d0, d0, d2 - vld1.8 {d3}, [r0,:64] - vrhadd.u8 d1, d1, d3 - sub r0, r0, r2 -.endif - vst1.64 {d0}, [r0,:64], r2 - vst1.64 {d1}, [r0,:64], r2 - bne 1b - bx lr -endfunc - .endm - - h264_qpel_h_lowpass_l2 put - h264_qpel_h_lowpass_l2 avg - -function put_h264_qpel16_v_lowpass_neon_packed - mov r4, lr - mov r2, #8 - bl put_h264_qpel8_v_lowpass_neon - sub r1, r1, r3, lsl #2 - bl put_h264_qpel8_v_lowpass_neon - sub r1, r1, r3, lsl #4 - sub r1, r1, r3, lsl #2 - add r1, r1, #8 - bl put_h264_qpel8_v_lowpass_neon - sub r1, r1, r3, lsl #2 - mov lr, r4 - b put_h264_qpel8_v_lowpass_neon -endfunc - - .macro h264_qpel_v_lowpass type -function \type\()_h264_qpel16_v_lowpass_neon - mov r4, lr - bl \type\()_h264_qpel8_v_lowpass_neon - sub r1, r1, r3, lsl #2 - bl \type\()_h264_qpel8_v_lowpass_neon - sub r0, r0, r2, lsl #4 - add r0, r0, #8 - sub r1, r1, r3, lsl #4 - sub r1, r1, r3, lsl #2 - add r1, r1, #8 - bl \type\()_h264_qpel8_v_lowpass_neon - sub r1, r1, r3, lsl #2 - mov lr, r4 -endfunc - -function \type\()_h264_qpel8_v_lowpass_neon - vld1.64 {d8}, [r1], r3 - vld1.64 {d10}, [r1], r3 - vld1.64 {d12}, [r1], r3 - vld1.64 {d14}, [r1], r3 - vld1.64 {d22}, [r1], r3 - vld1.64 {d24}, [r1], r3 - vld1.64 {d26}, [r1], r3 - vld1.64 {d28}, [r1], r3 - vld1.64 {d9}, [r1], r3 - vld1.64 {d11}, [r1], r3 - vld1.64 {d13}, [r1], r3 - vld1.64 {d15}, [r1], r3 - vld1.64 {d23}, [r1] - - transpose_8x8 q4, q5, q6, q7, q11, q12, q13, q14 - lowpass_8 d8, d9, d10, d11, d8, d10 - lowpass_8 d12, d13, d14, d15, d12, d14 - lowpass_8 d22, d23, d24, d25, d22, d24 - lowpass_8 d26, d27, d28, d29, d26, d28 - transpose_8x8 d8, d10, d12, d14, d22, d24, d26, d28 - -.ifc \type,avg - vld1.8 {d9}, [r0,:64], r2 - vrhadd.u8 d8, d8, d9 - vld1.8 {d11}, [r0,:64], r2 - vrhadd.u8 d10, d10, d11 - vld1.8 {d13}, [r0,:64], r2 - vrhadd.u8 d12, d12, d13 - vld1.8 {d15}, [r0,:64], r2 - vrhadd.u8 d14, d14, d15 - vld1.8 {d23}, [r0,:64], r2 - vrhadd.u8 d22, d22, d23 - vld1.8 {d25}, [r0,:64], r2 - vrhadd.u8 d24, d24, d25 - vld1.8 {d27}, [r0,:64], r2 - vrhadd.u8 d26, d26, d27 - vld1.8 {d29}, [r0,:64], r2 - vrhadd.u8 d28, d28, d29 - sub r0, r0, r2, lsl #3 -.endif - - vst1.64 {d8}, [r0,:64], r2 - vst1.64 {d10}, [r0,:64], r2 - vst1.64 {d12}, [r0,:64], r2 - vst1.64 {d14}, [r0,:64], r2 - vst1.64 {d22}, [r0,:64], r2 - vst1.64 {d24}, [r0,:64], r2 - vst1.64 {d26}, [r0,:64], r2 - vst1.64 {d28}, [r0,:64], r2 - - bx lr -endfunc - .endm - - h264_qpel_v_lowpass put - h264_qpel_v_lowpass avg - - .macro h264_qpel_v_lowpass_l2 type -function \type\()_h264_qpel16_v_lowpass_l2_neon - mov r4, lr - bl \type\()_h264_qpel8_v_lowpass_l2_neon - sub r1, r1, r3, lsl #2 - bl \type\()_h264_qpel8_v_lowpass_l2_neon - sub r0, r0, r3, lsl #4 - sub ip, ip, r2, lsl #4 - add r0, r0, #8 - add ip, ip, #8 - sub r1, r1, r3, lsl #4 - sub r1, r1, r3, lsl #2 - add r1, r1, #8 - bl \type\()_h264_qpel8_v_lowpass_l2_neon - sub r1, r1, r3, lsl #2 - mov lr, r4 -endfunc - -function \type\()_h264_qpel8_v_lowpass_l2_neon - vld1.64 {d8}, [r1], r3 - vld1.64 {d10}, [r1], r3 - vld1.64 {d12}, [r1], r3 - vld1.64 {d14}, [r1], r3 - vld1.64 {d22}, [r1], r3 - vld1.64 {d24}, [r1], r3 - vld1.64 {d26}, [r1], r3 - vld1.64 {d28}, [r1], r3 - vld1.64 {d9}, [r1], r3 - vld1.64 {d11}, [r1], r3 - vld1.64 {d13}, [r1], r3 - vld1.64 {d15}, [r1], r3 - vld1.64 {d23}, [r1] - - transpose_8x8 q4, q5, q6, q7, q11, q12, q13, q14 - lowpass_8 d8, d9, d10, d11, d8, d9 - lowpass_8 d12, d13, d14, d15, d12, d13 - lowpass_8 d22, d23, d24, d25, d22, d23 - lowpass_8 d26, d27, d28, d29, d26, d27 - transpose_8x8 d8, d9, d12, d13, d22, d23, d26, d27 - - vld1.64 {d0}, [ip], r2 - vld1.64 {d1}, [ip], r2 - vld1.64 {d2}, [ip], r2 - vld1.64 {d3}, [ip], r2 - vld1.64 {d4}, [ip], r2 - vrhadd.u8 q0, q0, q4 - vld1.64 {d5}, [ip], r2 - vrhadd.u8 q1, q1, q6 - vld1.64 {d10}, [ip], r2 - vrhadd.u8 q2, q2, q11 - vld1.64 {d11}, [ip], r2 - vrhadd.u8 q5, q5, q13 - -.ifc \type,avg - vld1.8 {d16}, [r0,:64], r3 - vrhadd.u8 d0, d0, d16 - vld1.8 {d17}, [r0,:64], r3 - vrhadd.u8 d1, d1, d17 - vld1.8 {d16}, [r0,:64], r3 - vrhadd.u8 d2, d2, d16 - vld1.8 {d17}, [r0,:64], r3 - vrhadd.u8 d3, d3, d17 - vld1.8 {d16}, [r0,:64], r3 - vrhadd.u8 d4, d4, d16 - vld1.8 {d17}, [r0,:64], r3 - vrhadd.u8 d5, d5, d17 - vld1.8 {d16}, [r0,:64], r3 - vrhadd.u8 d10, d10, d16 - vld1.8 {d17}, [r0,:64], r3 - vrhadd.u8 d11, d11, d17 - sub r0, r0, r3, lsl #3 -.endif - - vst1.64 {d0}, [r0,:64], r3 - vst1.64 {d1}, [r0,:64], r3 - vst1.64 {d2}, [r0,:64], r3 - vst1.64 {d3}, [r0,:64], r3 - vst1.64 {d4}, [r0,:64], r3 - vst1.64 {d5}, [r0,:64], r3 - vst1.64 {d10}, [r0,:64], r3 - vst1.64 {d11}, [r0,:64], r3 - - bx lr -endfunc - .endm - - h264_qpel_v_lowpass_l2 put - h264_qpel_v_lowpass_l2 avg - -function put_h264_qpel8_hv_lowpass_neon_top - lowpass_const ip - mov ip, #12 -1: vld1.64 {d0, d1}, [r1], r3 - vld1.64 {d16,d17}, [r1], r3 - subs ip, ip, #2 - lowpass_8 d0, d1, d16, d17, q11, q12, narrow=0 - vst1.64 {d22-d25}, [r4,:128]! - bne 1b - - vld1.64 {d0, d1}, [r1] - lowpass_8_1 d0, d1, q12, narrow=0 - - mov ip, #-16 - add r4, r4, ip - vld1.64 {d30,d31}, [r4,:128], ip - vld1.64 {d20,d21}, [r4,:128], ip - vld1.64 {d18,d19}, [r4,:128], ip - vld1.64 {d16,d17}, [r4,:128], ip - vld1.64 {d14,d15}, [r4,:128], ip - vld1.64 {d12,d13}, [r4,:128], ip - vld1.64 {d10,d11}, [r4,:128], ip - vld1.64 {d8, d9}, [r4,:128], ip - vld1.64 {d6, d7}, [r4,:128], ip - vld1.64 {d4, d5}, [r4,:128], ip - vld1.64 {d2, d3}, [r4,:128], ip - vld1.64 {d0, d1}, [r4,:128] - - swap4 d1, d3, d5, d7, d8, d10, d12, d14 - transpose16_4x4 q0, q1, q2, q3, q4, q5, q6, q7 - - swap4 d17, d19, d21, d31, d24, d26, d28, d22 - transpose16_4x4 q8, q9, q10, q15, q12, q13, q14, q11 - - vst1.64 {d30,d31}, [r4,:128]! - vst1.64 {d6, d7}, [r4,:128]! - vst1.64 {d20,d21}, [r4,:128]! - vst1.64 {d4, d5}, [r4,:128]! - vst1.64 {d18,d19}, [r4,:128]! - vst1.64 {d2, d3}, [r4,:128]! - vst1.64 {d16,d17}, [r4,:128]! - vst1.64 {d0, d1}, [r4,:128] - - lowpass_8.16 q4, q12, d8, d9, d24, d25, d8 - lowpass_8.16 q5, q13, d10, d11, d26, d27, d9 - lowpass_8.16 q6, q14, d12, d13, d28, d29, d10 - lowpass_8.16 q7, q11, d14, d15, d22, d23, d11 - - vld1.64 {d16,d17}, [r4,:128], ip - vld1.64 {d30,d31}, [r4,:128], ip - lowpass_8.16 q8, q15, d16, d17, d30, d31, d12 - vld1.64 {d16,d17}, [r4,:128], ip - vld1.64 {d30,d31}, [r4,:128], ip - lowpass_8.16 q8, q15, d16, d17, d30, d31, d13 - vld1.64 {d16,d17}, [r4,:128], ip - vld1.64 {d30,d31}, [r4,:128], ip - lowpass_8.16 q8, q15, d16, d17, d30, d31, d14 - vld1.64 {d16,d17}, [r4,:128], ip - vld1.64 {d30,d31}, [r4,:128] - lowpass_8.16 q8, q15, d16, d17, d30, d31, d15 - - transpose_8x8 d12, d13, d14, d15, d8, d9, d10, d11 - - bx lr -endfunc - - .macro h264_qpel8_hv_lowpass type -function \type\()_h264_qpel8_hv_lowpass_neon - mov r10, lr - bl put_h264_qpel8_hv_lowpass_neon_top -.ifc \type,avg - vld1.8 {d0}, [r0,:64], r2 - vrhadd.u8 d12, d12, d0 - vld1.8 {d1}, [r0,:64], r2 - vrhadd.u8 d13, d13, d1 - vld1.8 {d2}, [r0,:64], r2 - vrhadd.u8 d14, d14, d2 - vld1.8 {d3}, [r0,:64], r2 - vrhadd.u8 d15, d15, d3 - vld1.8 {d4}, [r0,:64], r2 - vrhadd.u8 d8, d8, d4 - vld1.8 {d5}, [r0,:64], r2 - vrhadd.u8 d9, d9, d5 - vld1.8 {d6}, [r0,:64], r2 - vrhadd.u8 d10, d10, d6 - vld1.8 {d7}, [r0,:64], r2 - vrhadd.u8 d11, d11, d7 - sub r0, r0, r2, lsl #3 -.endif - vst1.64 {d12}, [r0,:64], r2 - vst1.64 {d13}, [r0,:64], r2 - vst1.64 {d14}, [r0,:64], r2 - vst1.64 {d15}, [r0,:64], r2 - vst1.64 {d8}, [r0,:64], r2 - vst1.64 {d9}, [r0,:64], r2 - vst1.64 {d10}, [r0,:64], r2 - vst1.64 {d11}, [r0,:64], r2 - - mov lr, r10 - bx lr -endfunc - .endm - - h264_qpel8_hv_lowpass put - h264_qpel8_hv_lowpass avg - - .macro h264_qpel8_hv_lowpass_l2 type -function \type\()_h264_qpel8_hv_lowpass_l2_neon - mov r10, lr - bl put_h264_qpel8_hv_lowpass_neon_top - - vld1.64 {d0, d1}, [r2,:128]! - vld1.64 {d2, d3}, [r2,:128]! - vrhadd.u8 q0, q0, q6 - vld1.64 {d4, d5}, [r2,:128]! - vrhadd.u8 q1, q1, q7 - vld1.64 {d6, d7}, [r2,:128]! - vrhadd.u8 q2, q2, q4 - vrhadd.u8 q3, q3, q5 -.ifc \type,avg - vld1.8 {d16}, [r0,:64], r3 - vrhadd.u8 d0, d0, d16 - vld1.8 {d17}, [r0,:64], r3 - vrhadd.u8 d1, d1, d17 - vld1.8 {d18}, [r0,:64], r3 - vrhadd.u8 d2, d2, d18 - vld1.8 {d19}, [r0,:64], r3 - vrhadd.u8 d3, d3, d19 - vld1.8 {d20}, [r0,:64], r3 - vrhadd.u8 d4, d4, d20 - vld1.8 {d21}, [r0,:64], r3 - vrhadd.u8 d5, d5, d21 - vld1.8 {d22}, [r0,:64], r3 - vrhadd.u8 d6, d6, d22 - vld1.8 {d23}, [r0,:64], r3 - vrhadd.u8 d7, d7, d23 - sub r0, r0, r3, lsl #3 -.endif - vst1.64 {d0}, [r0,:64], r3 - vst1.64 {d1}, [r0,:64], r3 - vst1.64 {d2}, [r0,:64], r3 - vst1.64 {d3}, [r0,:64], r3 - vst1.64 {d4}, [r0,:64], r3 - vst1.64 {d5}, [r0,:64], r3 - vst1.64 {d6}, [r0,:64], r3 - vst1.64 {d7}, [r0,:64], r3 - - mov lr, r10 - bx lr -endfunc - .endm - - h264_qpel8_hv_lowpass_l2 put - h264_qpel8_hv_lowpass_l2 avg - - .macro h264_qpel16_hv type -function \type\()_h264_qpel16_hv_lowpass_neon - mov r9, lr - bl \type\()_h264_qpel8_hv_lowpass_neon - sub r1, r1, r3, lsl #2 - bl \type\()_h264_qpel8_hv_lowpass_neon - sub r1, r1, r3, lsl #4 - sub r1, r1, r3, lsl #2 - add r1, r1, #8 - sub r0, r0, r2, lsl #4 - add r0, r0, #8 - bl \type\()_h264_qpel8_hv_lowpass_neon - sub r1, r1, r3, lsl #2 - mov lr, r9 - b \type\()_h264_qpel8_hv_lowpass_neon -endfunc - -function \type\()_h264_qpel16_hv_lowpass_l2_neon - mov r9, lr - sub r2, r4, #256 - bl \type\()_h264_qpel8_hv_lowpass_l2_neon - sub r1, r1, r3, lsl #2 - bl \type\()_h264_qpel8_hv_lowpass_l2_neon - sub r1, r1, r3, lsl #4 - sub r1, r1, r3, lsl #2 - add r1, r1, #8 - sub r0, r0, r3, lsl #4 - add r0, r0, #8 - bl \type\()_h264_qpel8_hv_lowpass_l2_neon - sub r1, r1, r3, lsl #2 - mov lr, r9 - b \type\()_h264_qpel8_hv_lowpass_l2_neon -endfunc - .endm - - h264_qpel16_hv put - h264_qpel16_hv avg - - .macro h264_qpel8 type -function ff_\type\()_h264_qpel8_mc10_neon, export=1 - lowpass_const r3 - mov r3, r1 - sub r1, r1, #2 - mov ip, #8 - b \type\()_h264_qpel8_h_lowpass_l2_neon -endfunc - -function ff_\type\()_h264_qpel8_mc20_neon, export=1 - lowpass_const r3 - sub r1, r1, #2 - mov r3, r2 - mov ip, #8 - b \type\()_h264_qpel8_h_lowpass_neon -endfunc - -function ff_\type\()_h264_qpel8_mc30_neon, export=1 - lowpass_const r3 - add r3, r1, #1 - sub r1, r1, #2 - mov ip, #8 - b \type\()_h264_qpel8_h_lowpass_l2_neon -endfunc - -function ff_\type\()_h264_qpel8_mc01_neon, export=1 - push {lr} - mov ip, r1 -\type\()_h264_qpel8_mc01: - lowpass_const r3 - mov r3, r2 - sub r1, r1, r2, lsl #1 - vpush {d8-d15} - bl \type\()_h264_qpel8_v_lowpass_l2_neon - vpop {d8-d15} - pop {pc} -endfunc - -function ff_\type\()_h264_qpel8_mc11_neon, export=1 - push {r0, r1, r11, lr} -\type\()_h264_qpel8_mc11: - lowpass_const r3 - mov r11, sp - bic sp, sp, #15 - sub sp, sp, #64 - mov r0, sp - sub r1, r1, #2 - mov r3, #8 - mov ip, #8 - vpush {d8-d15} - bl put_h264_qpel8_h_lowpass_neon - ldrd r0, [r11] - mov r3, r2 - add ip, sp, #64 - sub r1, r1, r2, lsl #1 - mov r2, #8 - bl \type\()_h264_qpel8_v_lowpass_l2_neon - vpop {d8-d15} - add sp, r11, #8 - pop {r11, pc} -endfunc - -function ff_\type\()_h264_qpel8_mc21_neon, export=1 - push {r0, r1, r4, r10, r11, lr} -\type\()_h264_qpel8_mc21: - lowpass_const r3 - mov r11, sp - bic sp, sp, #15 - sub sp, sp, #(8*8+16*12) - sub r1, r1, #2 - mov r3, #8 - mov r0, sp - mov ip, #8 - vpush {d8-d15} - bl put_h264_qpel8_h_lowpass_neon - mov r4, r0 - ldrd r0, [r11] - sub r1, r1, r2, lsl #1 - sub r1, r1, #2 - mov r3, r2 - sub r2, r4, #64 - bl \type\()_h264_qpel8_hv_lowpass_l2_neon - vpop {d8-d15} - add sp, r11, #8 - pop {r4, r10, r11, pc} -endfunc - -function ff_\type\()_h264_qpel8_mc31_neon, export=1 - add r1, r1, #1 - push {r0, r1, r11, lr} - sub r1, r1, #1 - b \type\()_h264_qpel8_mc11 -endfunc - -function ff_\type\()_h264_qpel8_mc02_neon, export=1 - push {lr} - lowpass_const r3 - sub r1, r1, r2, lsl #1 - mov r3, r2 - vpush {d8-d15} - bl \type\()_h264_qpel8_v_lowpass_neon - vpop {d8-d15} - pop {pc} -endfunc - -function ff_\type\()_h264_qpel8_mc12_neon, export=1 - push {r0, r1, r4, r10, r11, lr} -\type\()_h264_qpel8_mc12: - lowpass_const r3 - mov r11, sp - bic sp, sp, #15 - sub sp, sp, #(8*8+16*12) - sub r1, r1, r2, lsl #1 - mov r3, r2 - mov r2, #8 - mov r0, sp - vpush {d8-d15} - bl put_h264_qpel8_v_lowpass_neon - mov r4, r0 - ldrd r0, [r11] - sub r1, r1, r3, lsl #1 - sub r1, r1, #2 - sub r2, r4, #64 - bl \type\()_h264_qpel8_hv_lowpass_l2_neon - vpop {d8-d15} - add sp, r11, #8 - pop {r4, r10, r11, pc} -endfunc - -function ff_\type\()_h264_qpel8_mc22_neon, export=1 - push {r4, r10, r11, lr} - mov r11, sp - bic sp, sp, #15 - sub r1, r1, r2, lsl #1 - sub r1, r1, #2 - mov r3, r2 - sub sp, sp, #(16*12) - mov r4, sp - vpush {d8-d15} - bl \type\()_h264_qpel8_hv_lowpass_neon - vpop {d8-d15} - mov sp, r11 - pop {r4, r10, r11, pc} -endfunc - -function ff_\type\()_h264_qpel8_mc32_neon, export=1 - push {r0, r1, r4, r10, r11, lr} - add r1, r1, #1 - b \type\()_h264_qpel8_mc12 -endfunc - -function ff_\type\()_h264_qpel8_mc03_neon, export=1 - push {lr} - add ip, r1, r2 - b \type\()_h264_qpel8_mc01 -endfunc - -function ff_\type\()_h264_qpel8_mc13_neon, export=1 - push {r0, r1, r11, lr} - add r1, r1, r2 - b \type\()_h264_qpel8_mc11 -endfunc - -function ff_\type\()_h264_qpel8_mc23_neon, export=1 - push {r0, r1, r4, r10, r11, lr} - add r1, r1, r2 - b \type\()_h264_qpel8_mc21 -endfunc - -function ff_\type\()_h264_qpel8_mc33_neon, export=1 - add r1, r1, #1 - push {r0, r1, r11, lr} - add r1, r1, r2 - sub r1, r1, #1 - b \type\()_h264_qpel8_mc11 -endfunc - .endm - - h264_qpel8 put - h264_qpel8 avg - - .macro h264_qpel16 type -function ff_\type\()_h264_qpel16_mc10_neon, export=1 - lowpass_const r3 - mov r3, r1 - sub r1, r1, #2 - b \type\()_h264_qpel16_h_lowpass_l2_neon -endfunc - -function ff_\type\()_h264_qpel16_mc20_neon, export=1 - lowpass_const r3 - sub r1, r1, #2 - mov r3, r2 - b \type\()_h264_qpel16_h_lowpass_neon -endfunc - -function ff_\type\()_h264_qpel16_mc30_neon, export=1 - lowpass_const r3 - add r3, r1, #1 - sub r1, r1, #2 - b \type\()_h264_qpel16_h_lowpass_l2_neon -endfunc - -function ff_\type\()_h264_qpel16_mc01_neon, export=1 - push {r4, lr} - mov ip, r1 -\type\()_h264_qpel16_mc01: - lowpass_const r3 - mov r3, r2 - sub r1, r1, r2, lsl #1 - vpush {d8-d15} - bl \type\()_h264_qpel16_v_lowpass_l2_neon - vpop {d8-d15} - pop {r4, pc} -endfunc - -function ff_\type\()_h264_qpel16_mc11_neon, export=1 - push {r0, r1, r4, r11, lr} -\type\()_h264_qpel16_mc11: - lowpass_const r3 - mov r11, sp - bic sp, sp, #15 - sub sp, sp, #256 - mov r0, sp - sub r1, r1, #2 - mov r3, #16 - vpush {d8-d15} - bl put_h264_qpel16_h_lowpass_neon - ldrd r0, [r11] - mov r3, r2 - add ip, sp, #64 - sub r1, r1, r2, lsl #1 - mov r2, #16 - bl \type\()_h264_qpel16_v_lowpass_l2_neon - vpop {d8-d15} - add sp, r11, #8 - pop {r4, r11, pc} -endfunc - -function ff_\type\()_h264_qpel16_mc21_neon, export=1 - push {r0, r1, r4-r5, r9-r11, lr} -\type\()_h264_qpel16_mc21: - lowpass_const r3 - mov r11, sp - bic sp, sp, #15 - sub sp, sp, #(16*16+16*12) - sub r1, r1, #2 - mov r0, sp - vpush {d8-d15} - bl put_h264_qpel16_h_lowpass_neon_packed - mov r4, r0 - ldrd r0, [r11] - sub r1, r1, r2, lsl #1 - sub r1, r1, #2 - mov r3, r2 - bl \type\()_h264_qpel16_hv_lowpass_l2_neon - vpop {d8-d15} - add sp, r11, #8 - pop {r4-r5, r9-r11, pc} -endfunc - -function ff_\type\()_h264_qpel16_mc31_neon, export=1 - add r1, r1, #1 - push {r0, r1, r4, r11, lr} - sub r1, r1, #1 - b \type\()_h264_qpel16_mc11 -endfunc - -function ff_\type\()_h264_qpel16_mc02_neon, export=1 - push {r4, lr} - lowpass_const r3 - sub r1, r1, r2, lsl #1 - mov r3, r2 - vpush {d8-d15} - bl \type\()_h264_qpel16_v_lowpass_neon - vpop {d8-d15} - pop {r4, pc} -endfunc - -function ff_\type\()_h264_qpel16_mc12_neon, export=1 - push {r0, r1, r4-r5, r9-r11, lr} -\type\()_h264_qpel16_mc12: - lowpass_const r3 - mov r11, sp - bic sp, sp, #15 - sub sp, sp, #(16*16+16*12) - sub r1, r1, r2, lsl #1 - mov r0, sp - mov r3, r2 - vpush {d8-d15} - bl put_h264_qpel16_v_lowpass_neon_packed - mov r4, r0 - ldrd r0, [r11] - sub r1, r1, r3, lsl #1 - sub r1, r1, #2 - mov r2, r3 - bl \type\()_h264_qpel16_hv_lowpass_l2_neon - vpop {d8-d15} - add sp, r11, #8 - pop {r4-r5, r9-r11, pc} -endfunc - -function ff_\type\()_h264_qpel16_mc22_neon, export=1 - push {r4, r9-r11, lr} - lowpass_const r3 - mov r11, sp - bic sp, sp, #15 - sub r1, r1, r2, lsl #1 - sub r1, r1, #2 - mov r3, r2 - sub sp, sp, #(16*12) - mov r4, sp - vpush {d8-d15} - bl \type\()_h264_qpel16_hv_lowpass_neon - vpop {d8-d15} - mov sp, r11 - pop {r4, r9-r11, pc} -endfunc - -function ff_\type\()_h264_qpel16_mc32_neon, export=1 - push {r0, r1, r4-r5, r9-r11, lr} - add r1, r1, #1 - b \type\()_h264_qpel16_mc12 -endfunc - -function ff_\type\()_h264_qpel16_mc03_neon, export=1 - push {r4, lr} - add ip, r1, r2 - b \type\()_h264_qpel16_mc01 -endfunc - -function ff_\type\()_h264_qpel16_mc13_neon, export=1 - push {r0, r1, r4, r11, lr} - add r1, r1, r2 - b \type\()_h264_qpel16_mc11 -endfunc - -function ff_\type\()_h264_qpel16_mc23_neon, export=1 - push {r0, r1, r4-r5, r9-r11, lr} - add r1, r1, r2 - b \type\()_h264_qpel16_mc21 -endfunc - -function ff_\type\()_h264_qpel16_mc33_neon, export=1 - add r1, r1, #1 - push {r0, r1, r4, r11, lr} - add r1, r1, r2 - sub r1, r1, #1 - b \type\()_h264_qpel16_mc11 -endfunc - .endm - - h264_qpel16 put - h264_qpel16 avg - -@ Biweighted prediction - - .macro biweight_16 macs, macd - vdup.8 d0, r4 - vdup.8 d1, r5 - vmov q2, q8 - vmov q3, q8 -1: subs ip, ip, #2 - vld1.8 {d20-d21},[r0,:128], r2 - \macd q2, d0, d20 - pld [r0] - \macd q3, d0, d21 - vld1.8 {d22-d23},[r1,:128], r2 - \macs q2, d1, d22 - pld [r1] - \macs q3, d1, d23 - vmov q12, q8 - vld1.8 {d28-d29},[r0,:128], r2 - vmov q13, q8 - \macd q12, d0, d28 - pld [r0] - \macd q13, d0, d29 - vld1.8 {d30-d31},[r1,:128], r2 - \macs q12, d1, d30 - pld [r1] - \macs q13, d1, d31 - vshl.s16 q2, q2, q9 - vshl.s16 q3, q3, q9 - vqmovun.s16 d4, q2 - vqmovun.s16 d5, q3 - vshl.s16 q12, q12, q9 - vshl.s16 q13, q13, q9 - vqmovun.s16 d24, q12 - vqmovun.s16 d25, q13 - vmov q3, q8 - vst1.8 {d4- d5}, [r6,:128], r2 - vmov q2, q8 - vst1.8 {d24-d25},[r6,:128], r2 - bne 1b - pop {r4-r6, pc} - .endm - - .macro biweight_8 macs, macd - vdup.8 d0, r4 - vdup.8 d1, r5 - vmov q1, q8 - vmov q10, q8 -1: subs ip, ip, #2 - vld1.8 {d4},[r0,:64], r2 - \macd q1, d0, d4 - pld [r0] - vld1.8 {d5},[r1,:64], r2 - \macs q1, d1, d5 - pld [r1] - vld1.8 {d6},[r0,:64], r2 - \macd q10, d0, d6 - pld [r0] - vld1.8 {d7},[r1,:64], r2 - \macs q10, d1, d7 - pld [r1] - vshl.s16 q1, q1, q9 - vqmovun.s16 d2, q1 - vshl.s16 q10, q10, q9 - vqmovun.s16 d4, q10 - vmov q10, q8 - vst1.8 {d2},[r6,:64], r2 - vmov q1, q8 - vst1.8 {d4},[r6,:64], r2 - bne 1b - pop {r4-r6, pc} - .endm - - .macro biweight_4 macs, macd - vdup.8 d0, r4 - vdup.8 d1, r5 - vmov q1, q8 - vmov q10, q8 -1: subs ip, ip, #4 - vld1.32 {d4[0]},[r0,:32], r2 - vld1.32 {d4[1]},[r0,:32], r2 - \macd q1, d0, d4 - pld [r0] - vld1.32 {d5[0]},[r1,:32], r2 - vld1.32 {d5[1]},[r1,:32], r2 - \macs q1, d1, d5 - pld [r1] - blt 2f - vld1.32 {d6[0]},[r0,:32], r2 - vld1.32 {d6[1]},[r0,:32], r2 - \macd q10, d0, d6 - pld [r0] - vld1.32 {d7[0]},[r1,:32], r2 - vld1.32 {d7[1]},[r1,:32], r2 - \macs q10, d1, d7 - pld [r1] - vshl.s16 q1, q1, q9 - vqmovun.s16 d2, q1 - vshl.s16 q10, q10, q9 - vqmovun.s16 d4, q10 - vmov q10, q8 - vst1.32 {d2[0]},[r6,:32], r2 - vst1.32 {d2[1]},[r6,:32], r2 - vmov q1, q8 - vst1.32 {d4[0]},[r6,:32], r2 - vst1.32 {d4[1]},[r6,:32], r2 - bne 1b - pop {r4-r6, pc} -2: vshl.s16 q1, q1, q9 - vqmovun.s16 d2, q1 - vst1.32 {d2[0]},[r6,:32], r2 - vst1.32 {d2[1]},[r6,:32], r2 - pop {r4-r6, pc} - .endm - - .macro biweight_func w -function biweight_h264_pixels_\w\()_neon - push {r4-r6, lr} - add r4, sp, #16 - ldm r4, {r4-r6} - lsr lr, r4, #31 - add r6, r6, #1 - eors lr, lr, r5, lsr #30 - orr r6, r6, #1 - vdup.16 q9, r3 - lsl r6, r6, r3 - vmvn q9, q9 - vdup.16 q8, r6 - mov r6, r0 - beq 10f - subs lr, lr, #1 - beq 20f - subs lr, lr, #1 - beq 30f - b 40f -10: biweight_\w vmlal.u8, vmlal.u8 -20: rsb r4, r4, #0 - biweight_\w vmlal.u8, vmlsl.u8 -30: rsb r4, r4, #0 - rsb r5, r5, #0 - biweight_\w vmlsl.u8, vmlsl.u8 -40: rsb r5, r5, #0 - biweight_\w vmlsl.u8, vmlal.u8 -endfunc - .endm - - .macro biweight_entry w, h, b=1 -function ff_biweight_h264_pixels_\w\()x\h\()_neon, export=1 - mov ip, #\h -.if \b - b biweight_h264_pixels_\w\()_neon -.endif -endfunc - .endm - - biweight_entry 16, 8 - biweight_entry 16, 16, b=0 - biweight_func 16 - - biweight_entry 8, 16 - biweight_entry 8, 4 - biweight_entry 8, 8, b=0 - biweight_func 8 - - biweight_entry 4, 8 - biweight_entry 4, 2 - biweight_entry 4, 4, b=0 - biweight_func 4 - -@ Weighted prediction - - .macro weight_16 add - vdup.8 d0, r3 -1: subs ip, ip, #2 - vld1.8 {d20-d21},[r0,:128], r1 - vmull.u8 q2, d0, d20 - pld [r0] - vmull.u8 q3, d0, d21 - vld1.8 {d28-d29},[r0,:128], r1 - vmull.u8 q12, d0, d28 - pld [r0] - vmull.u8 q13, d0, d29 - \add q2, q8, q2 - vrshl.s16 q2, q2, q9 - \add q3, q8, q3 - vrshl.s16 q3, q3, q9 - vqmovun.s16 d4, q2 - vqmovun.s16 d5, q3 - \add q12, q8, q12 - vrshl.s16 q12, q12, q9 - \add q13, q8, q13 - vrshl.s16 q13, q13, q9 - vqmovun.s16 d24, q12 - vqmovun.s16 d25, q13 - vst1.8 {d4- d5}, [r4,:128], r1 - vst1.8 {d24-d25},[r4,:128], r1 - bne 1b - pop {r4, pc} - .endm - - .macro weight_8 add - vdup.8 d0, r3 -1: subs ip, ip, #2 - vld1.8 {d4},[r0,:64], r1 - vmull.u8 q1, d0, d4 - pld [r0] - vld1.8 {d6},[r0,:64], r1 - vmull.u8 q10, d0, d6 - \add q1, q8, q1 - pld [r0] - vrshl.s16 q1, q1, q9 - vqmovun.s16 d2, q1 - \add q10, q8, q10 - vrshl.s16 q10, q10, q9 - vqmovun.s16 d4, q10 - vst1.8 {d2},[r4,:64], r1 - vst1.8 {d4},[r4,:64], r1 - bne 1b - pop {r4, pc} - .endm - - .macro weight_4 add - vdup.8 d0, r3 - vmov q1, q8 - vmov q10, q8 -1: subs ip, ip, #4 - vld1.32 {d4[0]},[r0,:32], r1 - vld1.32 {d4[1]},[r0,:32], r1 - vmull.u8 q1, d0, d4 - pld [r0] - blt 2f - vld1.32 {d6[0]},[r0,:32], r1 - vld1.32 {d6[1]},[r0,:32], r1 - vmull.u8 q10, d0, d6 - pld [r0] - \add q1, q8, q1 - vrshl.s16 q1, q1, q9 - vqmovun.s16 d2, q1 - \add q10, q8, q10 - vrshl.s16 q10, q10, q9 - vqmovun.s16 d4, q10 - vmov q10, q8 - vst1.32 {d2[0]},[r4,:32], r1 - vst1.32 {d2[1]},[r4,:32], r1 - vmov q1, q8 - vst1.32 {d4[0]},[r4,:32], r1 - vst1.32 {d4[1]},[r4,:32], r1 - bne 1b - pop {r4, pc} -2: \add q1, q8, q1 - vrshl.s16 q1, q1, q9 - vqmovun.s16 d2, q1 - vst1.32 {d2[0]},[r4,:32], r1 - vst1.32 {d2[1]},[r4,:32], r1 - pop {r4, pc} - .endm - - .macro weight_func w -function weight_h264_pixels_\w\()_neon - push {r4, lr} - ldr r4, [sp, #8] - cmp r2, #1 - lsl r4, r4, r2 - vdup.16 q8, r4 - mov r4, r0 - ble 20f - rsb lr, r2, #1 - vdup.16 q9, lr - cmp r3, #0 - blt 10f - weight_\w vhadd.s16 -10: rsb r3, r3, #0 - weight_\w vhsub.s16 -20: rsb lr, r2, #0 - vdup.16 q9, lr - cmp r3, #0 - blt 10f - weight_\w vadd.s16 -10: rsb r3, r3, #0 - weight_\w vsub.s16 -endfunc - .endm - - .macro weight_entry w, h, b=1 -function ff_weight_h264_pixels_\w\()x\h\()_neon, export=1 - mov ip, #\h -.if \b - b weight_h264_pixels_\w\()_neon -.endif -endfunc - .endm - - weight_entry 16, 8 - weight_entry 16, 16, b=0 - weight_func 16 - - weight_entry 8, 16 - weight_entry 8, 4 - weight_entry 8, 8, b=0 - weight_func 8 - - weight_entry 4, 8 - weight_entry 4, 2 - weight_entry 4, 4, b=0 - weight_func 4 diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/h264idct_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/h264idct_neon.S deleted file mode 100644 index 0ba4880..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/h264idct_neon.S +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2008 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - preserve8 - .text - -function ff_h264_idct_add_neon, export=1 - vld1.64 {d0-d3}, [r1,:128] - - vswp d1, d2 - vadd.i16 d4, d0, d1 - vshr.s16 q8, q1, #1 - vsub.i16 d5, d0, d1 - vadd.i16 d6, d2, d17 - vsub.i16 d7, d16, d3 - vadd.i16 q0, q2, q3 - vsub.i16 q1, q2, q3 - - vtrn.16 d0, d1 - vtrn.16 d3, d2 - vtrn.32 d0, d3 - vtrn.32 d1, d2 - - vadd.i16 d4, d0, d3 - vld1.32 {d18[0]}, [r0,:32], r2 - vswp d1, d3 - vshr.s16 q8, q1, #1 - vld1.32 {d19[1]}, [r0,:32], r2 - vsub.i16 d5, d0, d1 - vld1.32 {d18[1]}, [r0,:32], r2 - vadd.i16 d6, d16, d3 - vld1.32 {d19[0]}, [r0,:32], r2 - vsub.i16 d7, d2, d17 - sub r0, r0, r2, lsl #2 - vadd.i16 q0, q2, q3 - vsub.i16 q1, q2, q3 - - vrshr.s16 q0, q0, #6 - vrshr.s16 q1, q1, #6 - - vaddw.u8 q0, q0, d18 - vaddw.u8 q1, q1, d19 - - vqmovun.s16 d0, q0 - vqmovun.s16 d1, q1 - - vst1.32 {d0[0]}, [r0,:32], r2 - vst1.32 {d1[1]}, [r0,:32], r2 - vst1.32 {d0[1]}, [r0,:32], r2 - vst1.32 {d1[0]}, [r0,:32], r2 - - bx lr -endfunc - -function ff_h264_idct_dc_add_neon, export=1 - vld1.16 {d2[],d3[]}, [r1,:16] - vrshr.s16 q1, q1, #6 - vld1.32 {d0[0]}, [r0,:32], r2 - vld1.32 {d0[1]}, [r0,:32], r2 - vaddw.u8 q2, q1, d0 - vld1.32 {d1[0]}, [r0,:32], r2 - vld1.32 {d1[1]}, [r0,:32], r2 - vaddw.u8 q1, q1, d1 - vqmovun.s16 d0, q2 - vqmovun.s16 d1, q1 - sub r0, r0, r2, lsl #2 - vst1.32 {d0[0]}, [r0,:32], r2 - vst1.32 {d0[1]}, [r0,:32], r2 - vst1.32 {d1[0]}, [r0,:32], r2 - vst1.32 {d1[1]}, [r0,:32], r2 - bx lr -endfunc - -function ff_h264_idct_add16_neon, export=1 - push {r4-r8,lr} - mov r4, r0 - mov r5, r1 - mov r1, r2 - mov r2, r3 - ldr r6, [sp, #24] - movrel r7, scan8 - mov ip, #16 -1: ldrb r8, [r7], #1 - ldr r0, [r5], #4 - ldrb r8, [r6, r8] - subs r8, r8, #1 - blt 2f - ldrsh lr, [r1] - add r0, r0, r4 - movne lr, #0 - cmp lr, #0 - adrne lr, ff_h264_idct_dc_add_neon - adreq lr, ff_h264_idct_add_neon - blx lr -2: subs ip, ip, #1 - add r1, r1, #32 - bne 1b - pop {r4-r8,pc} -endfunc - -function ff_h264_idct_add16intra_neon, export=1 - push {r4-r8,lr} - mov r4, r0 - mov r5, r1 - mov r1, r2 - mov r2, r3 - ldr r6, [sp, #24] - movrel r7, scan8 - mov ip, #16 -1: ldrb r8, [r7], #1 - ldr r0, [r5], #4 - ldrb r8, [r6, r8] - add r0, r0, r4 - cmp r8, #0 - ldrsh r8, [r1] - adrne lr, ff_h264_idct_add_neon - adreq lr, ff_h264_idct_dc_add_neon - cmpeq r8, #0 - blxne lr - subs ip, ip, #1 - add r1, r1, #32 - bne 1b - pop {r4-r8,pc} -endfunc - -function ff_h264_idct_add8_neon, export=1 - push {r4-r10,lr} - ldm r0, {r4,r9} - add r5, r1, #16*4 - add r1, r2, #16*32 - mov r2, r3 - ldr r6, [sp, #32] - movrel r7, scan8+16 - mov ip, #8 -1: ldrb r8, [r7], #1 - ldr r0, [r5], #4 - ldrb r8, [r6, r8] - tst ip, #4 - addeq r0, r0, r4 - addne r0, r0, r9 - cmp r8, #0 - ldrsh r8, [r1] - adrne lr, ff_h264_idct_add_neon - adreq lr, ff_h264_idct_dc_add_neon - cmpeq r8, #0 - blxne lr - subs ip, ip, #1 - add r1, r1, #32 - bne 1b - pop {r4-r10,pc} -endfunc - - .section .rodata -scan8: .byte 4+1*8, 5+1*8, 4+2*8, 5+2*8 - .byte 6+1*8, 7+1*8, 6+2*8, 7+2*8 - .byte 4+3*8, 5+3*8, 4+4*8, 5+4*8 - .byte 6+3*8, 7+3*8, 6+4*8, 7+4*8 - .byte 1+1*8, 2+1*8 - .byte 1+2*8, 2+2*8 - .byte 1+4*8, 2+4*8 - .byte 1+5*8, 2+5*8 diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/h264pred_init_arm.c b/tizen/distrib/ffmpeg/libavcodec/arm/h264pred_init_arm.c deleted file mode 100644 index a7d9960..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/h264pred_init_arm.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavcodec/h264pred.h" - -void ff_pred16x16_vert_neon(uint8_t *src, int stride); -void ff_pred16x16_hor_neon(uint8_t *src, int stride); -void ff_pred16x16_plane_neon(uint8_t *src, int stride); -void ff_pred16x16_dc_neon(uint8_t *src, int stride); -void ff_pred16x16_128_dc_neon(uint8_t *src, int stride); -void ff_pred16x16_left_dc_neon(uint8_t *src, int stride); -void ff_pred16x16_top_dc_neon(uint8_t *src, int stride); - -void ff_pred8x8_vert_neon(uint8_t *src, int stride); -void ff_pred8x8_hor_neon(uint8_t *src, int stride); -void ff_pred8x8_plane_neon(uint8_t *src, int stride); -void ff_pred8x8_dc_neon(uint8_t *src, int stride); -void ff_pred8x8_128_dc_neon(uint8_t *src, int stride); -void ff_pred8x8_left_dc_neon(uint8_t *src, int stride); -void ff_pred8x8_top_dc_neon(uint8_t *src, int stride); -void ff_pred8x8_l0t_dc_neon(uint8_t *src, int stride); -void ff_pred8x8_0lt_dc_neon(uint8_t *src, int stride); -void ff_pred8x8_l00_dc_neon(uint8_t *src, int stride); -void ff_pred8x8_0l0_dc_neon(uint8_t *src, int stride); - -#if HAVE_NEON -static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id) -{ - h->pred8x8[VERT_PRED8x8 ] = ff_pred8x8_vert_neon; - h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_hor_neon; - h->pred8x8[PLANE_PRED8x8 ] = ff_pred8x8_plane_neon; - h->pred8x8[DC_128_PRED8x8 ] = ff_pred8x8_128_dc_neon; - if (codec_id != CODEC_ID_RV40) { - h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_neon; - h->pred8x8[LEFT_DC_PRED8x8] = ff_pred8x8_left_dc_neon; - h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_neon; - h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8] = ff_pred8x8_l0t_dc_neon; - h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8] = ff_pred8x8_0lt_dc_neon; - h->pred8x8[ALZHEIMER_DC_L00_PRED8x8] = ff_pred8x8_l00_dc_neon; - h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8] = ff_pred8x8_0l0_dc_neon; - } - - h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_neon; - h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vert_neon; - h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_hor_neon; - h->pred16x16[LEFT_DC_PRED8x8] = ff_pred16x16_left_dc_neon; - h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_neon; - h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_neon; - if (codec_id != CODEC_ID_SVQ3 && codec_id != CODEC_ID_RV40) - h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_neon; -} -#endif - -void ff_h264_pred_init_arm(H264PredContext *h, int codec_id) -{ - if (HAVE_NEON) ff_h264_pred_init_neon(h, codec_id); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/h264pred_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/h264pred_neon.S deleted file mode 100644 index e2c69e1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/h264pred_neon.S +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - .macro ldcol.8 rd, rs, rt, n=8, hi=0 -.if \n == 8 || \hi == 0 - vld1.8 {\rd[0]}, [\rs], \rt - vld1.8 {\rd[1]}, [\rs], \rt - vld1.8 {\rd[2]}, [\rs], \rt - vld1.8 {\rd[3]}, [\rs], \rt -.endif -.if \n == 8 || \hi == 1 - vld1.8 {\rd[4]}, [\rs], \rt - vld1.8 {\rd[5]}, [\rs], \rt - vld1.8 {\rd[6]}, [\rs], \rt - vld1.8 {\rd[7]}, [\rs], \rt -.endif - .endm - - .macro add16x8 dq, dl, dh, rl, rh - vaddl.u8 \dq, \rl, \rh - vadd.u16 \dl, \dl, \dh - vpadd.u16 \dl, \dl, \dl - vpadd.u16 \dl, \dl, \dl - .endm - -function ff_pred16x16_128_dc_neon, export=1 - vmov.i8 q0, #128 - b .L_pred16x16_dc_end -endfunc - -function ff_pred16x16_top_dc_neon, export=1 - sub r2, r0, r1 - vld1.8 {q0}, [r2,:128] - add16x8 q0, d0, d1, d0, d1 - vrshrn.u16 d0, q0, #4 - vdup.8 q0, d0[0] - b .L_pred16x16_dc_end -endfunc - -function ff_pred16x16_left_dc_neon, export=1 - sub r2, r0, #1 - ldcol.8 d0, r2, r1 - ldcol.8 d1, r2, r1 - add16x8 q0, d0, d1, d0, d1 - vrshrn.u16 d0, q0, #4 - vdup.8 q0, d0[0] - b .L_pred16x16_dc_end -endfunc - -function ff_pred16x16_dc_neon, export=1 - sub r2, r0, r1 - vld1.8 {q0}, [r2,:128] - sub r2, r0, #1 - ldcol.8 d2, r2, r1 - ldcol.8 d3, r2, r1 - vaddl.u8 q0, d0, d1 - vaddl.u8 q1, d2, d3 - vadd.u16 q0, q0, q1 - vadd.u16 d0, d0, d1 - vpadd.u16 d0, d0, d0 - vpadd.u16 d0, d0, d0 - vrshrn.u16 d0, q0, #5 - vdup.8 q0, d0[0] -.L_pred16x16_dc_end: - mov r3, #8 -6: vst1.8 {q0}, [r0,:128], r1 - vst1.8 {q0}, [r0,:128], r1 - subs r3, r3, #1 - bne 6b - bx lr -endfunc - -function ff_pred16x16_hor_neon, export=1 - sub r2, r0, #1 - mov r3, #16 -1: vld1.8 {d0[],d1[]},[r2], r1 - vst1.8 {q0}, [r0,:128], r1 - subs r3, r3, #1 - bne 1b - bx lr -endfunc - -function ff_pred16x16_vert_neon, export=1 - sub r0, r0, r1 - vld1.8 {q0}, [r0,:128], r1 - mov r3, #8 -1: vst1.8 {q0}, [r0,:128], r1 - vst1.8 {q0}, [r0,:128], r1 - subs r3, r3, #1 - bne 1b - bx lr -endfunc - -function ff_pred16x16_plane_neon, export=1 - sub r3, r0, r1 - add r2, r3, #8 - sub r3, r3, #1 - vld1.8 {d0}, [r3] - vld1.8 {d2}, [r2,:64], r1 - ldcol.8 d1, r3, r1 - add r3, r3, r1 - ldcol.8 d3, r3, r1 - vrev64.8 q0, q0 - vaddl.u8 q8, d2, d3 - vsubl.u8 q2, d2, d0 - vsubl.u8 q3, d3, d1 - movrel r3, p16weight - vld1.8 {q0}, [r3,:128] - vmul.s16 q2, q2, q0 - vmul.s16 q3, q3, q0 - vadd.i16 d4, d4, d5 - vadd.i16 d5, d6, d7 - vpadd.i16 d4, d4, d5 - vpadd.i16 d4, d4, d4 - vshl.i16 d5, d4, #2 - vaddl.s16 q2, d4, d5 - vrshrn.s32 d4, q2, #6 - mov r3, #0 - vtrn.16 d4, d5 - vadd.i16 d2, d4, d5 - vshl.i16 d3, d2, #3 - vrev64.16 d16, d17 - vsub.i16 d3, d3, d2 - vadd.i16 d16, d16, d0 - vshl.i16 d2, d16, #4 - vsub.i16 d2, d2, d3 - vshl.i16 d3, d4, #4 - vext.16 q0, q0, q0, #7 - vsub.i16 d6, d5, d3 - vmov.16 d0[0], r3 - vmul.i16 q0, q0, d4[0] - vdup.16 q1, d2[0] - vdup.16 q2, d4[0] - vdup.16 q3, d6[0] - vshl.i16 q2, q2, #3 - vadd.i16 q1, q1, q0 - vadd.i16 q3, q3, q2 - mov r3, #16 -1: - vqshrun.s16 d0, q1, #5 - vadd.i16 q1, q1, q2 - vqshrun.s16 d1, q1, #5 - vadd.i16 q1, q1, q3 - vst1.8 {q0}, [r0,:128], r1 - subs r3, r3, #1 - bne 1b - bx lr -endfunc - - .section .rodata - .align 4 -p16weight: - .short 1,2,3,4,5,6,7,8 - - .text - -function ff_pred8x8_hor_neon, export=1 - sub r2, r0, #1 - mov r3, #8 -1: vld1.8 {d0[]}, [r2], r1 - vst1.8 {d0}, [r0,:64], r1 - subs r3, r3, #1 - bne 1b - bx lr -endfunc - -function ff_pred8x8_vert_neon, export=1 - sub r0, r0, r1 - vld1.8 {d0}, [r0,:64], r1 - mov r3, #4 -1: vst1.8 {d0}, [r0,:64], r1 - vst1.8 {d0}, [r0,:64], r1 - subs r3, r3, #1 - bne 1b - bx lr -endfunc - -function ff_pred8x8_plane_neon, export=1 - sub r3, r0, r1 - add r2, r3, #4 - sub r3, r3, #1 - vld1.32 {d0[0]}, [r3] - vld1.32 {d2[0]}, [r2,:32], r1 - ldcol.8 d0, r3, r1, 4, hi=1 - add r3, r3, r1 - ldcol.8 d3, r3, r1, 4 - vaddl.u8 q8, d2, d3 - vrev32.8 d0, d0 - vtrn.32 d2, d3 - vsubl.u8 q2, d2, d0 - movrel r3, p16weight - vld1.16 {q0}, [r3,:128] - vmul.s16 d4, d4, d0 - vmul.s16 d5, d5, d0 - vpadd.i16 d4, d4, d5 - vpaddl.s16 d4, d4 - vshl.i32 d5, d4, #4 - vadd.s32 d4, d4, d5 - vrshrn.s32 d4, q2, #5 - mov r3, #0 - vtrn.16 d4, d5 - vadd.i16 d2, d4, d5 - vshl.i16 d3, d2, #2 - vrev64.16 d16, d16 - vsub.i16 d3, d3, d2 - vadd.i16 d16, d16, d0 - vshl.i16 d2, d16, #4 - vsub.i16 d2, d2, d3 - vshl.i16 d3, d4, #3 - vext.16 q0, q0, q0, #7 - vsub.i16 d6, d5, d3 - vmov.16 d0[0], r3 - vmul.i16 q0, q0, d4[0] - vdup.16 q1, d2[0] - vdup.16 q2, d4[0] - vdup.16 q3, d6[0] - vshl.i16 q2, q2, #3 - vadd.i16 q1, q1, q0 - vadd.i16 q3, q3, q2 - mov r3, #8 -1: - vqshrun.s16 d0, q1, #5 - vadd.i16 q1, q1, q3 - vst1.8 {d0}, [r0,:64], r1 - subs r3, r3, #1 - bne 1b - bx lr -endfunc - -function ff_pred8x8_128_dc_neon, export=1 - vmov.i8 q0, #128 - b .L_pred8x8_dc_end -endfunc - -function ff_pred8x8_top_dc_neon, export=1 - sub r2, r0, r1 - vld1.8 {d0}, [r2,:64] - vpaddl.u8 d0, d0 - vpadd.u16 d0, d0, d0 - vrshrn.u16 d0, q0, #2 - vdup.8 d1, d0[1] - vdup.8 d0, d0[0] - vtrn.32 d0, d1 - b .L_pred8x8_dc_end -endfunc - -function ff_pred8x8_left_dc_neon, export=1 - sub r2, r0, #1 - ldcol.8 d0, r2, r1 - vpaddl.u8 d0, d0 - vpadd.u16 d0, d0, d0 - vrshrn.u16 d0, q0, #2 - vdup.8 d1, d0[1] - vdup.8 d0, d0[0] - b .L_pred8x8_dc_end -endfunc - -function ff_pred8x8_dc_neon, export=1 - sub r2, r0, r1 - vld1.8 {d0}, [r2,:64] - sub r2, r0, #1 - ldcol.8 d1, r2, r1 - vtrn.32 d0, d1 - vpaddl.u8 q0, q0 - vpadd.u16 d0, d0, d1 - vpadd.u16 d1, d0, d0 - vrshrn.u16 d2, q0, #3 - vrshrn.u16 d3, q0, #2 - vdup.8 d0, d2[4] - vdup.8 d1, d3[3] - vdup.8 d4, d3[2] - vdup.8 d5, d2[5] - vtrn.32 q0, q2 -.L_pred8x8_dc_end: - mov r3, #4 - add r2, r0, r1, lsl #2 -6: vst1.8 {d0}, [r0,:64], r1 - vst1.8 {d1}, [r2,:64], r1 - subs r3, r3, #1 - bne 6b - bx lr -endfunc - -function ff_pred8x8_l0t_dc_neon, export=1 - sub r2, r0, r1 - vld1.8 {d0}, [r2,:64] - sub r2, r0, #1 - ldcol.8 d1, r2, r1, 4 - vtrn.32 d0, d1 - vpaddl.u8 q0, q0 - vpadd.u16 d0, d0, d1 - vpadd.u16 d1, d0, d0 - vrshrn.u16 d2, q0, #3 - vrshrn.u16 d3, q0, #2 - vdup.8 d0, d2[4] - vdup.8 d1, d3[0] - vdup.8 q2, d3[2] - vtrn.32 q0, q2 - b .L_pred8x8_dc_end -endfunc - -function ff_pred8x8_l00_dc_neon, export=1 - sub r2, r0, #1 - ldcol.8 d0, r2, r1, 4 - vpaddl.u8 d0, d0 - vpadd.u16 d0, d0, d0 - vrshrn.u16 d0, q0, #2 - vmov.i8 d1, #128 - vdup.8 d0, d0[0] - b .L_pred8x8_dc_end -endfunc - -function ff_pred8x8_0lt_dc_neon, export=1 - sub r2, r0, r1 - vld1.8 {d0}, [r2,:64] - add r2, r0, r1, lsl #2 - sub r2, r2, #1 - ldcol.8 d1, r2, r1, 4, hi=1 - vtrn.32 d0, d1 - vpaddl.u8 q0, q0 - vpadd.u16 d0, d0, d1 - vpadd.u16 d1, d0, d0 - vrshrn.u16 d3, q0, #2 - vrshrn.u16 d2, q0, #3 - vdup.8 d0, d3[0] - vdup.8 d1, d3[3] - vdup.8 d4, d3[2] - vdup.8 d5, d2[5] - vtrn.32 q0, q2 - b .L_pred8x8_dc_end -endfunc - -function ff_pred8x8_0l0_dc_neon, export=1 - add r2, r0, r1, lsl #2 - sub r2, r2, #1 - ldcol.8 d1, r2, r1, 4 - vpaddl.u8 d2, d1 - vpadd.u16 d2, d2, d2 - vrshrn.u16 d1, q1, #2 - vmov.i8 d0, #128 - vdup.8 d1, d1[0] - b .L_pred8x8_dc_end -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/int_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/int_neon.S deleted file mode 100644 index e8023e0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/int_neon.S +++ /dev/null @@ -1,118 +0,0 @@ -/* - * ARM NEON optimised integer operations - * Copyright (c) 2009 Kostya Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - preserve8 - .fpu neon - .text - -function ff_scalarproduct_int16_neon, export=1 - vmov.i16 q0, #0 - vmov.i16 q1, #0 - vmov.i16 q2, #0 - vmov.i16 q3, #0 - negs r3, r3 - beq 2f - - vdup.s32 q12, r3 -1: vld1.16 {d16-d17}, [r0]! - vld1.16 {d20-d21}, [r1,:128]! - vmull.s16 q12, d16, d20 - vld1.16 {d18-d19}, [r0]! - vmull.s16 q13, d17, d21 - vld1.16 {d22-d23}, [r1,:128]! - vmull.s16 q14, d18, d22 - vmull.s16 q15, d19, d23 - vshl.s32 q8, q12, q12 - vshl.s32 q9, q13, q12 - vadd.s32 q0, q0, q8 - vshl.s32 q10, q14, q12 - vadd.s32 q1, q1, q9 - vshl.s32 q11, q15, q12 - vadd.s32 q2, q2, q10 - vadd.s32 q3, q3, q11 - subs r2, r2, #16 - bne 1b - b 3f - -2: vld1.16 {d16-d17}, [r0]! - vld1.16 {d20-d21}, [r1,:128]! - vmlal.s16 q0, d16, d20 - vld1.16 {d18-d19}, [r0]! - vmlal.s16 q1, d17, d21 - vld1.16 {d22-d23}, [r1,:128]! - vmlal.s16 q2, d18, d22 - vmlal.s16 q3, d19, d23 - subs r2, r2, #16 - bne 2b - -3: vpadd.s32 d16, d0, d1 - vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 - vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 - vpadd.s32 d2, d0, d1 - vpaddl.s32 d3, d2 - vmov.32 r0, d3[0] - bx lr -endfunc - -@ scalarproduct_and_madd_int16(/*aligned*/v0,v1,v2,order,mul) -function ff_scalarproduct_and_madd_int16_neon, export=1 - vld1.16 {d28[],d29[]}, [sp] - vmov.i16 q0, #0 - vmov.i16 q1, #0 - vmov.i16 q2, #0 - vmov.i16 q3, #0 - mov r12, r0 - -1: vld1.16 {d16-d17}, [r0,:128]! - vld1.16 {d18-d19}, [r1]! - vld1.16 {d20-d21}, [r2]! - vld1.16 {d22-d23}, [r0,:128]! - vld1.16 {d24-d25}, [r1]! - vld1.16 {d26-d27}, [r2]! - vmul.s16 q10, q10, q14 - vmul.s16 q13, q13, q14 - vmlal.s16 q0, d16, d18 - vmlal.s16 q1, d17, d19 - vadd.s16 q10, q8, q10 - vadd.s16 q13, q11, q13 - vmlal.s16 q2, d22, d24 - vmlal.s16 q3, d23, d25 - vst1.16 {q10}, [r12,:128]! - subs r3, r3, #16 - vst1.16 {q13}, [r12,:128]! - bne 1b - - vpadd.s32 d16, d0, d1 - vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 - vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 - vpadd.s32 d2, d0, d1 - vpaddl.s32 d3, d2 - vmov.32 r0, d3[0] - bx lr -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/jrevdct_arm.S b/tizen/distrib/ffmpeg/libavcodec/arm/jrevdct_arm.S deleted file mode 100644 index 4fcf351..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/jrevdct_arm.S +++ /dev/null @@ -1,388 +0,0 @@ -/* - 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. - -*/ - -#include "asm.S" - -#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 - -function ff_j_rev_dct_arm, export=1 - 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 - adr r11, const_array @ r11 = base pointer to the constants array -row_loop: - ldrsh r0, [lr, # 0] @ r0 = 'd0' - ldrsh r2, [lr, # 2] @ r2 = 'd2' - - @ 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 r6, [lr, # 4] - ldr r3, [lr, # 8] - ldr r4, [lr, #12] - orr r3, r3, r4 - orr r3, r3, r6 - orrs r5, r3, r5 - beq end_of_row_loop @ nothing to be done as ALL of them are '0' - orrs r3, r3, r2 - beq empty_row - - ldrsh r1, [lr, # 8] @ r1 = 'd1' - 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/tizen/distrib/ffmpeg/libavcodec/arm/mathops.h b/tizen/distrib/ffmpeg/libavcodec/arm/mathops.h deleted file mode 100644 index 2244fa1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/mathops.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * simple math operations - * Copyright (c) 2006 Michael Niedermayer et al - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ARM_MATHOPS_H -#define AVCODEC_ARM_MATHOPS_H - -#include -#include "config.h" -#include "libavutil/common.h" - -#if HAVE_INLINE_ASM - -# define MULL MULL -static inline av_const int MULL(int a, int b, unsigned shift) -{ - int lo, hi; - __asm__("smull %0, %1, %2, %3 \n\t" - "mov %0, %0, lsr %4 \n\t" - "add %1, %0, %1, lsl %5 \n\t" - : "=&r"(lo), "=&r"(hi) - : "r"(b), "r"(a), "ir"(shift), "ir"(32-shift)); - return hi; -} - -#define MULH MULH -#if HAVE_ARMV6 -static inline av_const int MULH(int a, int b) -{ - int r; - __asm__ ("smmul %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); - return r; -} -#else -static inline av_const int MULH(int a, int b) -{ - int lo, hi; - __asm__ ("smull %0, %1, %2, %3" : "=&r"(lo), "=&r"(hi) : "r"(b), "r"(a)); - return hi; -} -#endif - -static inline av_const int64_t MUL64(int a, int b) -{ - union { uint64_t x; unsigned hl[2]; } x; - __asm__ ("smull %0, %1, %2, %3" - : "=r"(x.hl[0]), "=r"(x.hl[1]) : "r"(a), "r"(b)); - return x.x; -} -#define MUL64 MUL64 - -static inline av_const int64_t MAC64(int64_t d, int a, int b) -{ - union { uint64_t x; unsigned hl[2]; } x = { d }; - __asm__ ("smlal %0, %1, %2, %3" - : "+r"(x.hl[0]), "+r"(x.hl[1]) : "r"(a), "r"(b)); - return x.x; -} -#define MAC64(d, a, b) ((d) = MAC64(d, a, b)) -#define MLS64(d, a, b) MAC64(d, -(a), b) - -#if HAVE_ARMV5TE - -/* signed 16x16 -> 32 multiply add accumulate */ -# define MAC16(rt, ra, rb) \ - __asm__ ("smlabb %0, %1, %2, %0" : "+r"(rt) : "r"(ra), "r"(rb)); - -/* signed 16x16 -> 32 multiply */ -# define MUL16 MUL16 -static inline av_const int MUL16(int ra, int rb) -{ - int rt; - __asm__ ("smulbb %0, %1, %2" : "=r"(rt) : "r"(ra), "r"(rb)); - return rt; -} - -#endif - -#define mid_pred mid_pred -static inline av_const int mid_pred(int a, int b, int c) -{ - int m; - __asm__ volatile ( - "mov %0, %2 \n\t" - "cmp %1, %2 \n\t" - "movgt %0, %1 \n\t" - "movgt %1, %2 \n\t" - "cmp %1, %3 \n\t" - "movle %1, %3 \n\t" - "cmp %0, %1 \n\t" - "movgt %0, %1 \n\t" - : "=&r"(m), "+r"(a) - : "r"(b), "r"(c)); - return m; -} - -#endif /* HAVE_INLINE_ASM */ - -#endif /* AVCODEC_ARM_MATHOPS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/mdct_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/mdct_neon.S deleted file mode 100644 index fac75be..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/mdct_neon.S +++ /dev/null @@ -1,303 +0,0 @@ -/* - * ARM NEON optimised MDCT - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - preserve8 - - .text - -#define ff_fft_calc_neon X(ff_fft_calc_neon) - -function ff_imdct_half_neon, export=1 - push {r4-r8,lr} - - mov r12, #1 - ldr lr, [r0, #28] @ mdct_bits - ldr r4, [r0, #32] @ tcos - ldr r3, [r0, #8] @ revtab - lsl r12, r12, lr @ n = 1 << nbits - lsr lr, r12, #2 @ n4 = n >> 2 - add r7, r2, r12, lsl #1 - mov r12, #-16 - sub r7, r7, #16 - - vld2.32 {d16-d17},[r7,:128],r12 @ d16=x,n1 d17=x,n0 - vld2.32 {d0-d1}, [r2,:128]! @ d0 =m0,x d1 =m1,x - vrev64.32 d17, d17 - vld2.32 {d2,d3}, [r4,:128]! @ d2=c0,c1 d3=s0,s2 - vmul.f32 d6, d17, d2 - vmul.f32 d7, d0, d2 -1: - subs lr, lr, #2 - ldr r6, [r3], #4 - vmul.f32 d4, d0, d3 - vmul.f32 d5, d17, d3 - vsub.f32 d4, d6, d4 - vadd.f32 d5, d5, d7 - uxth r8, r6, ror #16 - uxth r6, r6 - add r8, r1, r8, lsl #3 - add r6, r1, r6, lsl #3 - beq 1f - vld2.32 {d16-d17},[r7,:128],r12 - vld2.32 {d0-d1}, [r2,:128]! - vrev64.32 d17, d17 - vld2.32 {d2,d3}, [r4,:128]! @ d2=c0,c1 d3=s0,s2 - vmul.f32 d6, d17, d2 - vmul.f32 d7, d0, d2 - vst2.32 {d4[0],d5[0]}, [r6,:64] - vst2.32 {d4[1],d5[1]}, [r8,:64] - b 1b -1: - vst2.32 {d4[0],d5[0]}, [r6,:64] - vst2.32 {d4[1],d5[1]}, [r8,:64] - - mov r4, r0 - mov r6, r1 - bl ff_fft_calc_neon - - mov r12, #1 - ldr lr, [r4, #28] @ mdct_bits - ldr r4, [r4, #32] @ tcos - lsl r12, r12, lr @ n = 1 << nbits - lsr lr, r12, #3 @ n8 = n >> 3 - - add r4, r4, lr, lsl #3 - add r6, r6, lr, lsl #3 - sub r1, r4, #16 - sub r3, r6, #16 - - mov r7, #-16 - mov r8, r6 - mov r0, r3 - - vld2.32 {d0-d1}, [r3,:128], r7 @ d0 =i1,r1 d1 =i0,r0 - vld2.32 {d20-d21},[r6,:128]! @ d20=i2,r2 d21=i3,r3 - vld2.32 {d16,d18},[r1,:128], r7 @ d16=c1,c0 d18=s1,s0 -1: - subs lr, lr, #2 - vmul.f32 d7, d0, d18 - vld2.32 {d17,d19},[r4,:128]! @ d17=c2,c3 d19=s2,s3 - vmul.f32 d4, d1, d18 - vmul.f32 d5, d21, d19 - vmul.f32 d6, d20, d19 - vmul.f32 d22, d1, d16 - vmul.f32 d23, d21, d17 - vmul.f32 d24, d0, d16 - vmul.f32 d25, d20, d17 - vadd.f32 d7, d7, d22 - vadd.f32 d6, d6, d23 - vsub.f32 d4, d4, d24 - vsub.f32 d5, d5, d25 - beq 1f - vld2.32 {d0-d1}, [r3,:128], r7 - vld2.32 {d20-d21},[r6,:128]! - vld2.32 {d16,d18},[r1,:128], r7 @ d16=c1,c0 d18=s1,s0 - vrev64.32 q3, q3 - vst2.32 {d4,d6}, [r0,:128], r7 - vst2.32 {d5,d7}, [r8,:128]! - b 1b -1: - vrev64.32 q3, q3 - vst2.32 {d4,d6}, [r0,:128] - vst2.32 {d5,d7}, [r8,:128] - - pop {r4-r8,pc} -endfunc - -function ff_imdct_calc_neon, export=1 - push {r4-r6,lr} - - ldr r3, [r0, #28] - mov r4, #1 - mov r5, r1 - lsl r4, r4, r3 - add r1, r1, r4 - - bl ff_imdct_half_neon - - add r0, r5, r4, lsl #2 - add r1, r5, r4, lsl #1 - sub r0, r0, #8 - sub r2, r1, #16 - mov r3, #-16 - mov r6, #-8 - vmov.i32 d30, #1<<31 -1: - vld1.32 {d0-d1}, [r2,:128], r3 - pld [r0, #-16] - vrev64.32 q0, q0 - vld1.32 {d2-d3}, [r1,:128]! - veor d4, d1, d30 - pld [r2, #-16] - vrev64.32 q1, q1 - veor d5, d0, d30 - vst1.32 {d2}, [r0,:64], r6 - vst1.32 {d3}, [r0,:64], r6 - vst1.32 {d4-d5}, [r5,:128]! - subs r4, r4, #16 - bgt 1b - - pop {r4-r6,pc} -endfunc - -function ff_mdct_calc_neon, export=1 - push {r4-r10,lr} - - mov r12, #1 - ldr lr, [r0, #28] @ mdct_bits - ldr r4, [r0, #32] @ tcos - ldr r3, [r0, #8] @ revtab - lsl lr, r12, lr @ n = 1 << nbits - add r7, r2, lr @ in4u - sub r9, r7, #16 @ in4d - add r2, r7, lr, lsl #1 @ in3u - add r8, r9, lr, lsl #1 @ in3d - add r5, r4, lr, lsl #1 - sub r5, r5, #16 - sub r3, r3, #4 - mov r12, #-16 - - vld2.32 {d16,d18},[r9,:128],r12 @ in0u0,in0u1 in4d1,in4d0 - vld2.32 {d17,d19},[r8,:128],r12 @ in2u0,in2u1 in3d1,in3d0 - vld2.32 {d0, d2}, [r7,:128]! @ in4u0,in4u1 in2d1,in2d0 - vrev64.32 q9, q9 @ in4d0,in4d1 in3d0,in3d1 - vld2.32 {d1, d3}, [r2,:128]! @ in3u0,in3u1 in1d1,in1d0 - vsub.f32 d0, d18, d0 @ in4d-in4u I - vld2.32 {d20,d21},[r4,:128]! @ c0,c1 s0,s1 - vrev64.32 q1, q1 @ in2d0,in2d1 in1d0,in1d1 - vld2.32 {d30,d31},[r5,:128],r12 @ c2,c3 s2,s3 - vadd.f32 d1, d1, d19 @ in3u+in3d -R - vsub.f32 d16, d16, d2 @ in0u-in2d R - vadd.f32 d17, d17, d3 @ in2u+in1d -I -1: - vmul.f32 d7, d0, d21 @ I*s - ldr r10, [r3, lr, lsr #1] - vmul.f32 d6, d1, d20 @ -R*c - ldr r6, [r3, #4]! - vmul.f32 d4, d1, d21 @ -R*s - vmul.f32 d5, d0, d20 @ I*c - vmul.f32 d24, d16, d30 @ R*c - vmul.f32 d25, d17, d31 @ -I*s - vmul.f32 d22, d16, d31 @ R*s - vmul.f32 d23, d17, d30 @ I*c - subs lr, lr, #16 - vsub.f32 d6, d6, d7 @ -R*c-I*s - vadd.f32 d7, d4, d5 @ -R*s+I*c - vsub.f32 d24, d25, d24 @ I*s-R*c - vadd.f32 d25, d22, d23 @ R*s-I*c - beq 1f - mov r12, #-16 - vld2.32 {d16,d18},[r9,:128],r12 @ in0u0,in0u1 in4d1,in4d0 - vld2.32 {d17,d19},[r8,:128],r12 @ in2u0,in2u1 in3d1,in3d0 - vneg.f32 d7, d7 @ R*s-I*c - vld2.32 {d0, d2}, [r7,:128]! @ in4u0,in4u1 in2d1,in2d0 - vrev64.32 q9, q9 @ in4d0,in4d1 in3d0,in3d1 - vld2.32 {d1, d3}, [r2,:128]! @ in3u0,in3u1 in1d1,in1d0 - vsub.f32 d0, d18, d0 @ in4d-in4u I - vld2.32 {d20,d21},[r4,:128]! @ c0,c1 s0,s1 - vrev64.32 q1, q1 @ in2d0,in2d1 in1d0,in1d1 - vld2.32 {d30,d31},[r5,:128],r12 @ c2,c3 s2,s3 - vadd.f32 d1, d1, d19 @ in3u+in3d -R - vsub.f32 d16, d16, d2 @ in0u-in2d R - vadd.f32 d17, d17, d3 @ in2u+in1d -I - uxth r12, r6, ror #16 - uxth r6, r6 - add r12, r1, r12, lsl #3 - add r6, r1, r6, lsl #3 - vst2.32 {d6[0],d7[0]}, [r6,:64] - vst2.32 {d6[1],d7[1]}, [r12,:64] - uxth r6, r10, ror #16 - uxth r10, r10 - add r6 , r1, r6, lsl #3 - add r10, r1, r10, lsl #3 - vst2.32 {d24[0],d25[0]},[r10,:64] - vst2.32 {d24[1],d25[1]},[r6,:64] - b 1b -1: - vneg.f32 d7, d7 @ R*s-I*c - uxth r12, r6, ror #16 - uxth r6, r6 - add r12, r1, r12, lsl #3 - add r6, r1, r6, lsl #3 - vst2.32 {d6[0],d7[0]}, [r6,:64] - vst2.32 {d6[1],d7[1]}, [r12,:64] - uxth r6, r10, ror #16 - uxth r10, r10 - add r6 , r1, r6, lsl #3 - add r10, r1, r10, lsl #3 - vst2.32 {d24[0],d25[0]},[r10,:64] - vst2.32 {d24[1],d25[1]},[r6,:64] - - mov r4, r0 - mov r6, r1 - bl ff_fft_calc_neon - - mov r12, #1 - ldr lr, [r4, #28] @ mdct_bits - ldr r4, [r4, #32] @ tcos - lsl r12, r12, lr @ n = 1 << nbits - lsr lr, r12, #3 @ n8 = n >> 3 - - add r4, r4, lr, lsl #3 - add r6, r6, lr, lsl #3 - sub r1, r4, #16 - sub r3, r6, #16 - - mov r7, #-16 - mov r8, r6 - mov r0, r3 - - vld2.32 {d0-d1}, [r3,:128], r7 @ d0 =r1,i1 d1 =r0,i0 - vld2.32 {d20-d21},[r6,:128]! @ d20=r2,i2 d21=r3,i3 - vld2.32 {d16,d18},[r1,:128], r7 @ c1,c0 s1,s0 -1: - subs lr, lr, #2 - vmul.f32 d7, d0, d18 @ r1*s1,r0*s0 - vld2.32 {d17,d19},[r4,:128]! @ c2,c3 s2,s3 - vmul.f32 d4, d1, d18 @ i1*s1,i0*s0 - vmul.f32 d5, d21, d19 @ i2*s2,i3*s3 - vmul.f32 d6, d20, d19 @ r2*s2,r3*s3 - vmul.f32 d24, d0, d16 @ r1*c1,r0*c0 - vmul.f32 d25, d20, d17 @ r2*c2,r3*c3 - vmul.f32 d22, d21, d17 @ i2*c2,i3*c3 - vmul.f32 d23, d1, d16 @ i1*c1,i0*c0 - vadd.f32 d4, d4, d24 @ i1*s1+r1*c1,i0*s0+r0*c0 - vadd.f32 d5, d5, d25 @ i2*s2+r2*c2,i3*s3+r3*c3 - vsub.f32 d6, d22, d6 @ i2*c2-r2*s2,i3*c3-r3*s3 - vsub.f32 d7, d23, d7 @ i1*c1-r1*s1,i0*c0-r0*s0 - vneg.f32 q2, q2 - beq 1f - vld2.32 {d0-d1}, [r3,:128], r7 - vld2.32 {d20-d21},[r6,:128]! - vld2.32 {d16,d18},[r1,:128], r7 @ c1,c0 s1,s0 - vrev64.32 q3, q3 - vst2.32 {d4,d6}, [r0,:128], r7 - vst2.32 {d5,d7}, [r8,:128]! - b 1b -1: - vrev64.32 q3, q3 - vst2.32 {d4,d6}, [r0,:128] - vst2.32 {d5,d7}, [r8,:128] - - pop {r4-r10,pc} -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.c b/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.c deleted file mode 100644 index 06eacdf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" -#include "mpegvideo_arm.h" - -void MPV_common_init_arm(MpegEncContext *s) -{ - /* IWMMXT support is a superset of armv5te, so - * allow optimized functions for armv5te unless - * a better iwmmxt function exists - */ -#if HAVE_ARMV5TE - MPV_common_init_armv5te(s); -#endif -#if HAVE_IWMMXT - MPV_common_init_iwmmxt(s); -#endif -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.h b/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.h deleted file mode 100644 index 4cc25fd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_arm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ARM_MPEGVIDEO_H -#define AVCODEC_ARM_MPEGVIDEO_H - -#include "libavcodec/mpegvideo.h" - -void MPV_common_init_iwmmxt(MpegEncContext *s); -void MPV_common_init_armv5te(MpegEncContext *s); - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te.c b/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te.c deleted file mode 100644 index 1d383ca..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Optimization of some functions from mpegvideo.c for armv5te - * Copyright (c) 2007 Siarhei Siamashka - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" -#include "mpegvideo_arm.h" - -void ff_dct_unquantize_h263_armv5te(DCTELEM *block, int qmul, int qadd, int count); - -#ifdef ENABLE_ARM_TESTS -/** - * h263 dequantizer supplementary function, it is performance critical and needs to - * have optimized implementations for each architecture. Is also used as a reference - * implementation in regression tests - */ -static inline void dct_unquantize_h263_helper_c(DCTELEM *block, int qmul, int qadd, int count) -{ - int i, level; - for (i = 0; i < count; i++) { - level = block[i]; - if (level) { - if (level < 0) { - level = level * qmul - qadd; - } else { - level = level * qmul + qadd; - } - block[i] = level; - } - } -} -#endif - -static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int level, qmul, qadd; - int nCoeffs; - - 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] ]; - - ff_dct_unquantize_h263_armv5te(block, qmul, qadd, nCoeffs + 1); - block[0] = level; -} - -static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int qmul, qadd; - int nCoeffs; - - assert(s->block_last_index[n]>=0); - - qadd = (qscale - 1) | 1; - qmul = qscale << 1; - - nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; - - ff_dct_unquantize_h263_armv5te(block, qmul, qadd, nCoeffs + 1); -} - -void MPV_common_init_armv5te(MpegEncContext *s) -{ - s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_armv5te; - s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_armv5te; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te_s.S b/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te_s.S deleted file mode 100644 index c8cb2c6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_armv5te_s.S +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Optimization of some functions from mpegvideo.c for armv5te - * Copyright (c) 2007 Siarhei Siamashka - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "asm.S" - -/* - * Special optimized version of dct_unquantize_h263_helper_c, it - * requires the block to be at least 8 bytes aligned, and may process - * more elements than requested. But it is guaranteed to never - * process more than 64 elements provided that count argument is <= 64, - * so it is safe. This function is optimized for a common distribution - * of values for nCoeffs (they are mostly multiple of 8 plus one or - * two extra elements). So this function processes data as 8 elements - * per loop iteration and contains optional 2 elements processing in - * the end. - * - * Inner loop should take 6 cycles per element on arm926ej-s (Nokia 770) - */ -function ff_dct_unquantize_h263_armv5te, export=1 - push {r4-r9,lr} - mov ip, #0 - subs r3, r3, #2 - ble 2f - ldrd r4, [r0, #0] -1: - ldrd r6, [r0, #8] - - rsbs r9, ip, r4, asr #16 - addgt r9, r2, #0 - rsblt r9, r2, #0 - smlatbne r9, r4, r1, r9 - - rsbs lr, ip, r5, asr #16 - addgt lr, r2, #0 - rsblt lr, r2, #0 - smlatbne lr, r5, r1, lr - - rsbs r8, ip, r4, asl #16 - addgt r8, r2, #0 - rsblt r8, r2, #0 - smlabbne r4, r4, r1, r8 - - rsbs r8, ip, r5, asl #16 - addgt r8, r2, #0 - rsblt r8, r2, #0 - smlabbne r5, r5, r1, r8 - - strh r4, [r0], #2 - strh r9, [r0], #2 - strh r5, [r0], #2 - strh lr, [r0], #2 - - rsbs r9, ip, r6, asr #16 - addgt r9, r2, #0 - rsblt r9, r2, #0 - smlatbne r9, r6, r1, r9 - - rsbs lr, ip, r7, asr #16 - addgt lr, r2, #0 - rsblt lr, r2, #0 - smlatbne lr, r7, r1, lr - - rsbs r8, ip, r6, asl #16 - addgt r8, r2, #0 - rsblt r8, r2, #0 - smlabbne r6, r6, r1, r8 - - rsbs r8, ip, r7, asl #16 - addgt r8, r2, #0 - rsblt r8, r2, #0 - smlabbne r7, r7, r1, r8 - - strh r6, [r0], #2 - strh r9, [r0], #2 - strh r7, [r0], #2 - strh lr, [r0], #2 - - subs r3, r3, #8 - ldrgtd r4, [r0, #0] /* load data early to avoid load/use pipeline stall */ - bgt 1b - - adds r3, r3, #2 - pople {r4-r9,pc} -2: - ldrsh r9, [r0, #0] - ldrsh lr, [r0, #2] - mov r8, r2 - cmp r9, #0 - rsblt r8, r2, #0 - smlabbne r9, r9, r1, r8 - mov r8, r2 - cmp lr, #0 - rsblt r8, r2, #0 - smlabbne lr, lr, r1, r8 - strh r9, [r0], #2 - strh lr, [r0], #2 - pop {r4-r9,pc} -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_iwmmxt.c b/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_iwmmxt.c deleted file mode 100644 index 9e3878f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/mpegvideo_iwmmxt.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * copyright (c) 2004 AGAWA Koji - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" -#include "mpegvideo_arm.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 & FF_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/tizen/distrib/ffmpeg/libavcodec/arm/rdft_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/rdft_neon.S deleted file mode 100644 index 4f8a103..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/rdft_neon.S +++ /dev/null @@ -1,151 +0,0 @@ -/* - * ARM NEON optimised RDFT - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - preserve8 - -function ff_rdft_calc_neon, export=1 - push {r4-r8,lr} - - ldr r6, [r0, #4] @ inverse - mov r4, r0 - mov r5, r1 - - lsls r6, r6, #31 - bne 1f - add r0, r4, #20 - bl X(ff_fft_permute_neon) - add r0, r4, #20 - mov r1, r5 - bl X(ff_fft_calc_neon) -1: - ldr r12, [r4, #0] @ nbits - mov r2, #1 - lsl r12, r2, r12 - add r0, r5, #8 - add r1, r5, r12, lsl #2 - lsr r12, r12, #2 - ldr r2, [r4, #12] @ tcos - sub r12, r12, #2 - ldr r3, [r4, #16] @ tsin - mov r7, r0 - sub r1, r1, #8 - mov lr, r1 - mov r8, #-8 - vld1.32 {d0}, [r0,:64]! @ d1[0,1] - vld1.32 {d1}, [r1,:64], r8 @ d2[0,1] - vld1.32 {d4}, [r2,:64]! @ tcos[i] - vld1.32 {d5}, [r3,:64]! @ tsin[i] - vmov.f32 d18, #0.5 @ k1 - vdup.32 d19, r6 - pld [r0, #32] - veor d19, d18, d19 @ k2 - vmov.i32 d16, #0 - vmov.i32 d17, #1<<31 - pld [r1, #-32] - vtrn.32 d16, d17 - pld [r2, #32] - vrev64.32 d16, d16 @ d16=1,0 d17=0,1 - pld [r3, #32] -2: - veor q1, q0, q8 @ -d1[0],d1[1], d2[0],-d2[1] - vld1.32 {d24}, [r0,:64]! @ d1[0,1] - vadd.f32 d0, d0, d3 @ d1[0]+d2[0], d1[1]-d2[1] - vld1.32 {d25}, [r1,:64], r8 @ d2[0,1] - vadd.f32 d1, d2, d1 @ -d1[0]+d2[0], d1[1]+d2[1] - veor q3, q12, q8 @ -d1[0],d1[1], d2[0],-d2[1] - pld [r0, #32] - vmul.f32 q10, q0, q9 @ ev.re, ev.im, od.im, od.re - pld [r1, #-32] - vadd.f32 d0, d24, d7 @ d1[0]+d2[0], d1[1]-d2[1] - vadd.f32 d1, d6, d25 @ -d1[0]+d2[0], d1[1]+d2[1] - vmul.f32 q11, q0, q9 @ ev.re, ev.im, od.im, od.re - veor d7, d21, d16 @ -od.im, od.re - vrev64.32 d3, d21 @ od.re, od.im - veor d6, d20, d17 @ ev.re,-ev.im - veor d2, d3, d16 @ -od.re, od.im - vmla.f32 d20, d3, d4[1] - vmla.f32 d20, d7, d5[1] - vmla.f32 d6, d2, d4[1] - vmla.f32 d6, d21, d5[1] - vld1.32 {d4}, [r2,:64]! @ tcos[i] - veor d7, d23, d16 @ -od.im, od.re - vld1.32 {d5}, [r3,:64]! @ tsin[i] - veor d24, d22, d17 @ ev.re,-ev.im - vrev64.32 d3, d23 @ od.re, od.im - pld [r2, #32] - veor d2, d3, d16 @ -od.re, od.im - pld [r3, #32] - vmla.f32 d22, d3, d4[0] - vmla.f32 d22, d7, d5[0] - vmla.f32 d24, d2, d4[0] - vmla.f32 d24, d23, d5[0] - vld1.32 {d0}, [r0,:64]! @ d1[0,1] - vld1.32 {d1}, [r1,:64], r8 @ d2[0,1] - vst1.32 {d20}, [r7,:64]! - vst1.32 {d6}, [lr,:64], r8 - vst1.32 {d22}, [r7,:64]! - vst1.32 {d24}, [lr,:64], r8 - subs r12, r12, #2 - bgt 2b - - veor q1, q0, q8 @ -d1[0],d1[1], d2[0],-d2[1] - vadd.f32 d0, d0, d3 @ d1[0]+d2[0], d1[1]-d2[1] - vadd.f32 d1, d2, d1 @ -d1[0]+d2[0], d1[1]+d2[1] - ldr r2, [r4, #8] @ sign_convention - vmul.f32 q10, q0, q9 @ ev.re, ev.im, od.im, od.re - add r0, r0, #4 - bfc r2, #0, #31 - vld1.32 {d0[0]}, [r0,:32] - veor d7, d21, d16 @ -od.im, od.re - vrev64.32 d3, d21 @ od.re, od.im - veor d6, d20, d17 @ ev.re,-ev.im - vld1.32 {d22}, [r5,:64] - vdup.32 d1, r2 - vmov d23, d22 - veor d2, d3, d16 @ -od.re, od.im - vtrn.32 d22, d23 - veor d0, d0, d1 - veor d23, d23, d17 - vmla.f32 d20, d3, d4[1] - vmla.f32 d20, d7, d5[1] - vmla.f32 d6, d2, d4[1] - vmla.f32 d6, d21, d5[1] - vadd.f32 d22, d22, d23 - vst1.32 {d20}, [r7,:64] - vst1.32 {d6}, [lr,:64] - vst1.32 {d0[0]}, [r0,:32] - vst1.32 {d22}, [r5,:64] - - cmp r6, #0 - popeq {r4-r8,pc} - - vmul.f32 d22, d22, d18 - vst1.32 {d22}, [r5,:64] - add r0, r4, #20 - mov r1, r5 - bl X(ff_fft_permute_neon) - add r0, r4, #20 - mov r1, r5 - pop {r4-r8,lr} - b X(ff_fft_calc_neon) -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_arm.S b/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_arm.S deleted file mode 100644 index ecb83d2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_arm.S +++ /dev/null @@ -1,486 +0,0 @@ -/* - * simple_idct_arm.S - * Copyright (C) 2002 Frederic 'dilb' Boulay - * - * Author: Frederic Boulay - * - * The function defined in this file is derived from the simple_idct function - * from the libavcodec library part of the FFmpeg project. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -/* 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 - -function ff_simple_idct_arm, export=1 - @@ 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. - adr r12, __constant_ptr__ @ 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 optimize 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 optimization 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/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv5te.S b/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv5te.S deleted file mode 100644 index 27aeca4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv5te.S +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Simple IDCT - * - * Copyright (c) 2001 Michael Niedermayer - * Copyright (c) 2006 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -#define W1 22725 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W2 21407 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W3 19266 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W4 16383 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W5 12873 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W6 8867 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W7 4520 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define ROW_SHIFT 11 -#define COL_SHIFT 20 - -#define W13 (W1 | (W3 << 16)) -#define W26 (W2 | (W6 << 16)) -#define W57 (W5 | (W7 << 16)) - - .text - .align -w13: .long W13 -w26: .long W26 -w57: .long W57 - -function idct_row_armv5te - str lr, [sp, #-4]! - - ldrd v1, [a1, #8] - ldrd a3, [a1] /* a3 = row[1:0], a4 = row[3:2] */ - orrs v1, v1, v2 - cmpeq v1, a4 - cmpeq v1, a3, lsr #16 - beq row_dc_only - - mov v1, #(1<<(ROW_SHIFT-1)) - mov ip, #16384 - sub ip, ip, #1 /* ip = W4 */ - smlabb v1, ip, a3, v1 /* v1 = W4*row[0]+(1<<(RS-1)) */ - ldr ip, w26 /* ip = W2 | (W6 << 16) */ - smultb a2, ip, a4 - smulbb lr, ip, a4 - add v2, v1, a2 - sub v3, v1, a2 - sub v4, v1, lr - add v1, v1, lr - - ldr ip, w13 /* ip = W1 | (W3 << 16) */ - ldr lr, w57 /* lr = W5 | (W7 << 16) */ - smulbt v5, ip, a3 - smultt v6, lr, a4 - smlatt v5, ip, a4, v5 - smultt a2, ip, a3 - smulbt v7, lr, a3 - sub v6, v6, a2 - smulbt a2, ip, a4 - smultt fp, lr, a3 - sub v7, v7, a2 - smulbt a2, lr, a4 - ldrd a3, [a1, #8] /* a3=row[5:4] a4=row[7:6] */ - sub fp, fp, a2 - - orrs a2, a3, a4 - beq 1f - - smlabt v5, lr, a3, v5 - smlabt v6, ip, a3, v6 - smlatt v5, lr, a4, v5 - smlabt v6, lr, a4, v6 - smlatt v7, lr, a3, v7 - smlatt fp, ip, a3, fp - smulbt a2, ip, a4 - smlatt v7, ip, a4, v7 - sub fp, fp, a2 - - ldr ip, w26 /* ip = W2 | (W6 << 16) */ - mov a2, #16384 - sub a2, a2, #1 /* a2 = W4 */ - smulbb a2, a2, a3 /* a2 = W4*row[4] */ - smultb lr, ip, a4 /* lr = W6*row[6] */ - add v1, v1, a2 /* v1 += W4*row[4] */ - add v1, v1, lr /* v1 += W6*row[6] */ - add v4, v4, a2 /* v4 += W4*row[4] */ - sub v4, v4, lr /* v4 -= W6*row[6] */ - smulbb lr, ip, a4 /* lr = W2*row[6] */ - sub v2, v2, a2 /* v2 -= W4*row[4] */ - sub v2, v2, lr /* v2 -= W2*row[6] */ - sub v3, v3, a2 /* v3 -= W4*row[4] */ - add v3, v3, lr /* v3 += W2*row[6] */ - -1: add a2, v1, v5 - mov a3, a2, lsr #11 - bic a3, a3, #0x1f0000 - sub a2, v2, v6 - mov a2, a2, lsr #11 - add a3, a3, a2, lsl #16 - add a2, v3, v7 - mov a4, a2, lsr #11 - bic a4, a4, #0x1f0000 - add a2, v4, fp - mov a2, a2, lsr #11 - add a4, a4, a2, lsl #16 - strd a3, [a1] - - sub a2, v4, fp - mov a3, a2, lsr #11 - bic a3, a3, #0x1f0000 - sub a2, v3, v7 - mov a2, a2, lsr #11 - add a3, a3, a2, lsl #16 - add a2, v2, v6 - mov a4, a2, lsr #11 - bic a4, a4, #0x1f0000 - sub a2, v1, v5 - mov a2, a2, lsr #11 - add a4, a4, a2, lsl #16 - strd a3, [a1, #8] - - ldr pc, [sp], #4 - -row_dc_only: - orr a3, a3, a3, lsl #16 - bic a3, a3, #0xe000 - mov a3, a3, lsl #3 - mov a4, a3 - strd a3, [a1] - strd a3, [a1, #8] - - ldr pc, [sp], #4 -endfunc - - .macro idct_col - ldr a4, [a1] /* a4 = col[1:0] */ - mov ip, #16384 - sub ip, ip, #1 /* ip = W4 */ -#if 0 - mov v1, #(1<<(COL_SHIFT-1)) - smlabt v2, ip, a4, v1 /* v2 = W4*col[1] + (1<<(COL_SHIFT-1)) */ - smlabb v1, ip, a4, v1 /* v1 = W4*col[0] + (1<<(COL_SHIFT-1)) */ - ldr a4, [a1, #(16*4)] -#else - mov v1, #((1<<(COL_SHIFT-1))/W4) /* this matches the C version */ - add v2, v1, a4, asr #16 - rsb v2, v2, v2, lsl #14 - mov a4, a4, lsl #16 - add v1, v1, a4, asr #16 - ldr a4, [a1, #(16*4)] - rsb v1, v1, v1, lsl #14 -#endif - - smulbb lr, ip, a4 - smulbt a3, ip, a4 - sub v3, v1, lr - sub v5, v1, lr - add v7, v1, lr - add v1, v1, lr - sub v4, v2, a3 - sub v6, v2, a3 - add fp, v2, a3 - ldr ip, w26 - ldr a4, [a1, #(16*2)] - add v2, v2, a3 - - smulbb lr, ip, a4 - smultb a3, ip, a4 - add v1, v1, lr - sub v7, v7, lr - add v3, v3, a3 - sub v5, v5, a3 - smulbt lr, ip, a4 - smultt a3, ip, a4 - add v2, v2, lr - sub fp, fp, lr - add v4, v4, a3 - ldr a4, [a1, #(16*6)] - sub v6, v6, a3 - - smultb lr, ip, a4 - smulbb a3, ip, a4 - add v1, v1, lr - sub v7, v7, lr - sub v3, v3, a3 - add v5, v5, a3 - smultt lr, ip, a4 - smulbt a3, ip, a4 - add v2, v2, lr - sub fp, fp, lr - sub v4, v4, a3 - add v6, v6, a3 - - stmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp} - - ldr ip, w13 - ldr a4, [a1, #(16*1)] - ldr lr, w57 - smulbb v1, ip, a4 - smultb v3, ip, a4 - smulbb v5, lr, a4 - smultb v7, lr, a4 - smulbt v2, ip, a4 - smultt v4, ip, a4 - smulbt v6, lr, a4 - smultt fp, lr, a4 - rsb v4, v4, #0 - ldr a4, [a1, #(16*3)] - rsb v3, v3, #0 - - smlatb v1, ip, a4, v1 - smlatb v3, lr, a4, v3 - smulbb a3, ip, a4 - smulbb a2, lr, a4 - sub v5, v5, a3 - sub v7, v7, a2 - smlatt v2, ip, a4, v2 - smlatt v4, lr, a4, v4 - smulbt a3, ip, a4 - smulbt a2, lr, a4 - sub v6, v6, a3 - ldr a4, [a1, #(16*5)] - sub fp, fp, a2 - - smlabb v1, lr, a4, v1 - smlabb v3, ip, a4, v3 - smlatb v5, lr, a4, v5 - smlatb v7, ip, a4, v7 - smlabt v2, lr, a4, v2 - smlabt v4, ip, a4, v4 - smlatt v6, lr, a4, v6 - ldr a3, [a1, #(16*7)] - smlatt fp, ip, a4, fp - - smlatb v1, lr, a3, v1 - smlabb v3, lr, a3, v3 - smlatb v5, ip, a3, v5 - smulbb a4, ip, a3 - smlatt v2, lr, a3, v2 - sub v7, v7, a4 - smlabt v4, lr, a3, v4 - smulbt a4, ip, a3 - smlatt v6, ip, a3, v6 - sub fp, fp, a4 - .endm - -function idct_col_armv5te - str lr, [sp, #-4]! - - idct_col - - ldmfd sp!, {a3, a4} - adds a2, a3, v1 - mov a2, a2, lsr #20 - orrmi a2, a2, #0xf000 - add ip, a4, v2 - mov ip, ip, asr #20 - orr a2, a2, ip, lsl #16 - str a2, [a1] - subs a3, a3, v1 - mov a2, a3, lsr #20 - orrmi a2, a2, #0xf000 - sub a4, a4, v2 - mov a4, a4, asr #20 - orr a2, a2, a4, lsl #16 - ldmfd sp!, {a3, a4} - str a2, [a1, #(16*7)] - - subs a2, a3, v3 - mov a2, a2, lsr #20 - orrmi a2, a2, #0xf000 - sub ip, a4, v4 - mov ip, ip, asr #20 - orr a2, a2, ip, lsl #16 - str a2, [a1, #(16*1)] - adds a3, a3, v3 - mov a2, a3, lsr #20 - orrmi a2, a2, #0xf000 - add a4, a4, v4 - mov a4, a4, asr #20 - orr a2, a2, a4, lsl #16 - ldmfd sp!, {a3, a4} - str a2, [a1, #(16*6)] - - adds a2, a3, v5 - mov a2, a2, lsr #20 - orrmi a2, a2, #0xf000 - add ip, a4, v6 - mov ip, ip, asr #20 - orr a2, a2, ip, lsl #16 - str a2, [a1, #(16*2)] - subs a3, a3, v5 - mov a2, a3, lsr #20 - orrmi a2, a2, #0xf000 - sub a4, a4, v6 - mov a4, a4, asr #20 - orr a2, a2, a4, lsl #16 - ldmfd sp!, {a3, a4} - str a2, [a1, #(16*5)] - - adds a2, a3, v7 - mov a2, a2, lsr #20 - orrmi a2, a2, #0xf000 - add ip, a4, fp - mov ip, ip, asr #20 - orr a2, a2, ip, lsl #16 - str a2, [a1, #(16*3)] - subs a3, a3, v7 - mov a2, a3, lsr #20 - orrmi a2, a2, #0xf000 - sub a4, a4, fp - mov a4, a4, asr #20 - orr a2, a2, a4, lsl #16 - str a2, [a1, #(16*4)] - - ldr pc, [sp], #4 -endfunc - -function idct_col_put_armv5te - str lr, [sp, #-4]! - - idct_col - - ldmfd sp!, {a3, a4} - ldr lr, [sp, #32] - add a2, a3, v1 - movs a2, a2, asr #20 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - add ip, a4, v2 - movs ip, ip, asr #20 - movmi ip, #0 - cmp ip, #255 - movgt ip, #255 - orr a2, a2, ip, lsl #8 - sub a3, a3, v1 - movs a3, a3, asr #20 - movmi a3, #0 - cmp a3, #255 - movgt a3, #255 - sub a4, a4, v2 - movs a4, a4, asr #20 - movmi a4, #0 - cmp a4, #255 - ldr v1, [sp, #28] - movgt a4, #255 - strh a2, [v1] - add a2, v1, #2 - str a2, [sp, #28] - orr a2, a3, a4, lsl #8 - rsb v2, lr, lr, lsl #3 - ldmfd sp!, {a3, a4} - strh a2, [v2, v1]! - - sub a2, a3, v3 - movs a2, a2, asr #20 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - sub ip, a4, v4 - movs ip, ip, asr #20 - movmi ip, #0 - cmp ip, #255 - movgt ip, #255 - orr a2, a2, ip, lsl #8 - strh a2, [v1, lr]! - add a3, a3, v3 - movs a2, a3, asr #20 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - add a4, a4, v4 - movs a4, a4, asr #20 - movmi a4, #0 - cmp a4, #255 - movgt a4, #255 - orr a2, a2, a4, lsl #8 - ldmfd sp!, {a3, a4} - strh a2, [v2, -lr]! - - add a2, a3, v5 - movs a2, a2, asr #20 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - add ip, a4, v6 - movs ip, ip, asr #20 - movmi ip, #0 - cmp ip, #255 - movgt ip, #255 - orr a2, a2, ip, lsl #8 - strh a2, [v1, lr]! - sub a3, a3, v5 - movs a2, a3, asr #20 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - sub a4, a4, v6 - movs a4, a4, asr #20 - movmi a4, #0 - cmp a4, #255 - movgt a4, #255 - orr a2, a2, a4, lsl #8 - ldmfd sp!, {a3, a4} - strh a2, [v2, -lr]! - - add a2, a3, v7 - movs a2, a2, asr #20 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - add ip, a4, fp - movs ip, ip, asr #20 - movmi ip, #0 - cmp ip, #255 - movgt ip, #255 - orr a2, a2, ip, lsl #8 - strh a2, [v1, lr] - sub a3, a3, v7 - movs a2, a3, asr #20 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - sub a4, a4, fp - movs a4, a4, asr #20 - movmi a4, #0 - cmp a4, #255 - movgt a4, #255 - orr a2, a2, a4, lsl #8 - strh a2, [v2, -lr] - - ldr pc, [sp], #4 -endfunc - -function idct_col_add_armv5te - str lr, [sp, #-4]! - - idct_col - - ldr lr, [sp, #36] - - ldmfd sp!, {a3, a4} - ldrh ip, [lr] - add a2, a3, v1 - mov a2, a2, asr #20 - sub a3, a3, v1 - and v1, ip, #255 - adds a2, a2, v1 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - add v1, a4, v2 - mov v1, v1, asr #20 - adds v1, v1, ip, lsr #8 - movmi v1, #0 - cmp v1, #255 - movgt v1, #255 - orr a2, a2, v1, lsl #8 - ldr v1, [sp, #32] - sub a4, a4, v2 - rsb v2, v1, v1, lsl #3 - ldrh ip, [v2, lr]! - strh a2, [lr] - mov a3, a3, asr #20 - and a2, ip, #255 - adds a3, a3, a2 - movmi a3, #0 - cmp a3, #255 - movgt a3, #255 - mov a4, a4, asr #20 - adds a4, a4, ip, lsr #8 - movmi a4, #0 - cmp a4, #255 - movgt a4, #255 - add a2, lr, #2 - str a2, [sp, #28] - orr a2, a3, a4, lsl #8 - strh a2, [v2] - - ldmfd sp!, {a3, a4} - ldrh ip, [lr, v1]! - sub a2, a3, v3 - mov a2, a2, asr #20 - add a3, a3, v3 - and v3, ip, #255 - adds a2, a2, v3 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - sub v3, a4, v4 - mov v3, v3, asr #20 - adds v3, v3, ip, lsr #8 - movmi v3, #0 - cmp v3, #255 - movgt v3, #255 - orr a2, a2, v3, lsl #8 - add a4, a4, v4 - ldrh ip, [v2, -v1]! - strh a2, [lr] - mov a3, a3, asr #20 - and a2, ip, #255 - adds a3, a3, a2 - movmi a3, #0 - cmp a3, #255 - movgt a3, #255 - mov a4, a4, asr #20 - adds a4, a4, ip, lsr #8 - movmi a4, #0 - cmp a4, #255 - movgt a4, #255 - orr a2, a3, a4, lsl #8 - strh a2, [v2] - - ldmfd sp!, {a3, a4} - ldrh ip, [lr, v1]! - add a2, a3, v5 - mov a2, a2, asr #20 - sub a3, a3, v5 - and v3, ip, #255 - adds a2, a2, v3 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - add v3, a4, v6 - mov v3, v3, asr #20 - adds v3, v3, ip, lsr #8 - movmi v3, #0 - cmp v3, #255 - movgt v3, #255 - orr a2, a2, v3, lsl #8 - sub a4, a4, v6 - ldrh ip, [v2, -v1]! - strh a2, [lr] - mov a3, a3, asr #20 - and a2, ip, #255 - adds a3, a3, a2 - movmi a3, #0 - cmp a3, #255 - movgt a3, #255 - mov a4, a4, asr #20 - adds a4, a4, ip, lsr #8 - movmi a4, #0 - cmp a4, #255 - movgt a4, #255 - orr a2, a3, a4, lsl #8 - strh a2, [v2] - - ldmfd sp!, {a3, a4} - ldrh ip, [lr, v1]! - add a2, a3, v7 - mov a2, a2, asr #20 - sub a3, a3, v7 - and v3, ip, #255 - adds a2, a2, v3 - movmi a2, #0 - cmp a2, #255 - movgt a2, #255 - add v3, a4, fp - mov v3, v3, asr #20 - adds v3, v3, ip, lsr #8 - movmi v3, #0 - cmp v3, #255 - movgt v3, #255 - orr a2, a2, v3, lsl #8 - sub a4, a4, fp - ldrh ip, [v2, -v1]! - strh a2, [lr] - mov a3, a3, asr #20 - and a2, ip, #255 - adds a3, a3, a2 - movmi a3, #0 - cmp a3, #255 - movgt a3, #255 - mov a4, a4, asr #20 - adds a4, a4, ip, lsr #8 - movmi a4, #0 - cmp a4, #255 - movgt a4, #255 - orr a2, a3, a4, lsl #8 - strh a2, [v2] - - ldr pc, [sp], #4 -endfunc - -function ff_simple_idct_armv5te, export=1 - stmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, lr} - - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - - sub a1, a1, #(16*7) - - bl idct_col_armv5te - add a1, a1, #4 - bl idct_col_armv5te - add a1, a1, #4 - bl idct_col_armv5te - add a1, a1, #4 - bl idct_col_armv5te - - ldmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, pc} -endfunc - -function ff_simple_idct_add_armv5te, export=1 - stmfd sp!, {a1, a2, v1, v2, v3, v4, v5, v6, v7, fp, lr} - - mov a1, a3 - - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - - sub a1, a1, #(16*7) - - bl idct_col_add_armv5te - add a1, a1, #4 - bl idct_col_add_armv5te - add a1, a1, #4 - bl idct_col_add_armv5te - add a1, a1, #4 - bl idct_col_add_armv5te - - add sp, sp, #8 - ldmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, pc} -endfunc - -function ff_simple_idct_put_armv5te, export=1 - stmfd sp!, {a1, a2, v1, v2, v3, v4, v5, v6, v7, fp, lr} - - mov a1, a3 - - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - add a1, a1, #16 - bl idct_row_armv5te - - sub a1, a1, #(16*7) - - bl idct_col_put_armv5te - add a1, a1, #4 - bl idct_col_put_armv5te - add a1, a1, #4 - bl idct_col_put_armv5te - add a1, a1, #4 - bl idct_col_put_armv5te - - add sp, sp, #8 - ldmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, pc} -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv6.S b/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv6.S deleted file mode 100644 index d61c1fd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_armv6.S +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Simple IDCT - * - * Copyright (c) 2001 Michael Niedermayer - * Copyright (c) 2007 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -#define W1 22725 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W2 21407 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W3 19266 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W4 16383 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W5 12873 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W6 8867 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define W7 4520 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ -#define ROW_SHIFT 11 -#define COL_SHIFT 20 - -#define W13 (W1 | (W3 << 16)) -#define W26 (W2 | (W6 << 16)) -#define W42 (W4 | (W2 << 16)) -#define W42n (-W4&0xffff | (-W2 << 16)) -#define W46 (W4 | (W6 << 16)) -#define W57 (W5 | (W7 << 16)) - - .text - .align -w13: .long W13 -w26: .long W26 -w42: .long W42 -w42n: .long W42n -w46: .long W46 -w57: .long W57 - -/* - Compute partial IDCT of single row. - shift = left-shift amount - r0 = source address - r2 = row[2,0] <= 2 cycles - r3 = row[3,1] - ip = w42 <= 2 cycles - - Output in registers r4--r11 -*/ - .macro idct_row shift - ldr lr, w46 /* lr = W4 | (W6 << 16) */ - mov r1, #(1<<(\shift-1)) - smlad r4, r2, ip, r1 - smlsd r7, r2, ip, r1 - ldr ip, w13 /* ip = W1 | (W3 << 16) */ - ldr r10,w57 /* r10 = W5 | (W7 << 16) */ - smlad r5, r2, lr, r1 - smlsd r6, r2, lr, r1 - - smuad r8, r3, ip /* r8 = B0 = W1*row[1] + W3*row[3] */ - smusdx r11,r3, r10 /* r11 = B3 = W7*row[1] - W5*row[3] */ - ldr lr, [r0, #12] /* lr = row[7,5] */ - pkhtb r2, ip, r10,asr #16 /* r3 = W7 | (W3 << 16) */ - pkhbt r1, ip, r10,lsl #16 /* r1 = W1 | (W5 << 16) */ - smusdx r9, r2, r3 /* r9 = -B1 = W7*row[3] - W3*row[1] */ - smlad r8, lr, r10,r8 /* B0 += W5*row[5] + W7*row[7] */ - smusdx r10,r3, r1 /* r10 = B2 = W5*row[1] - W1*row[3] */ - - ldr r3, w42n /* r3 = -W4 | (-W2 << 16) */ - smlad r10,lr, r2, r10 /* B2 += W7*row[5] + W3*row[7] */ - ldr r2, [r0, #4] /* r2 = row[6,4] */ - smlsdx r11,lr, ip, r11 /* B3 += W3*row[5] - W1*row[7] */ - ldr ip, w46 /* ip = W4 | (W6 << 16) */ - smlad r9, lr, r1, r9 /* B1 -= W1*row[5] + W5*row[7] */ - - smlad r5, r2, r3, r5 /* A1 += -W4*row[4] - W2*row[6] */ - smlsd r6, r2, r3, r6 /* A2 += -W4*row[4] + W2*row[6] */ - smlad r4, r2, ip, r4 /* A0 += W4*row[4] + W6*row[6] */ - smlsd r7, r2, ip, r7 /* A3 += W4*row[4] - W6*row[6] */ - .endm - -/* - Compute partial IDCT of half row. - shift = left-shift amount - r2 = row[2,0] - r3 = row[3,1] - ip = w42 - - Output in registers r4--r11 -*/ - .macro idct_row4 shift - ldr lr, w46 /* lr = W4 | (W6 << 16) */ - ldr r10,w57 /* r10 = W5 | (W7 << 16) */ - mov r1, #(1<<(\shift-1)) - smlad r4, r2, ip, r1 - smlsd r7, r2, ip, r1 - ldr ip, w13 /* ip = W1 | (W3 << 16) */ - smlad r5, r2, lr, r1 - smlsd r6, r2, lr, r1 - smusdx r11,r3, r10 /* r11 = B3 = W7*row[1] - W5*row[3] */ - smuad r8, r3, ip /* r8 = B0 = W1*row[1] + W3*row[3] */ - pkhtb r2, ip, r10,asr #16 /* r3 = W7 | (W3 << 16) */ - pkhbt r1, ip, r10,lsl #16 /* r1 = W1 | (W5 << 16) */ - smusdx r9, r2, r3 /* r9 = -B1 = W7*row[3] - W3*row[1] */ - smusdx r10,r3, r1 /* r10 = B2 = W5*row[1] - W1*row[3] */ - .endm - -/* - Compute final part of IDCT single row without shift. - Input in registers r4--r11 - Output in registers ip, r4--r6, lr, r8--r10 -*/ - .macro idct_finish - add ip, r4, r8 /* r1 = A0 + B0 */ - sub lr, r4, r8 /* r2 = A0 - B0 */ - sub r4, r5, r9 /* r2 = A1 + B1 */ - add r8, r5, r9 /* r2 = A1 - B1 */ - add r5, r6, r10 /* r1 = A2 + B2 */ - sub r9, r6, r10 /* r1 = A2 - B2 */ - add r6, r7, r11 /* r2 = A3 + B3 */ - sub r10,r7, r11 /* r2 = A3 - B3 */ - .endm - -/* - Compute final part of IDCT single row. - shift = right-shift amount - Input/output in registers r4--r11 -*/ - .macro idct_finish_shift shift - add r3, r4, r8 /* r3 = A0 + B0 */ - sub r2, r4, r8 /* r2 = A0 - B0 */ - mov r4, r3, asr #\shift - mov r8, r2, asr #\shift - - sub r3, r5, r9 /* r3 = A1 + B1 */ - add r2, r5, r9 /* r2 = A1 - B1 */ - mov r5, r3, asr #\shift - mov r9, r2, asr #\shift - - add r3, r6, r10 /* r3 = A2 + B2 */ - sub r2, r6, r10 /* r2 = A2 - B2 */ - mov r6, r3, asr #\shift - mov r10,r2, asr #\shift - - add r3, r7, r11 /* r3 = A3 + B3 */ - sub r2, r7, r11 /* r2 = A3 - B3 */ - mov r7, r3, asr #\shift - mov r11,r2, asr #\shift - .endm - -/* - Compute final part of IDCT single row, saturating results at 8 bits. - shift = right-shift amount - Input/output in registers r4--r11 -*/ - .macro idct_finish_shift_sat shift - add r3, r4, r8 /* r3 = A0 + B0 */ - sub ip, r4, r8 /* ip = A0 - B0 */ - usat r4, #8, r3, asr #\shift - usat r8, #8, ip, asr #\shift - - sub r3, r5, r9 /* r3 = A1 + B1 */ - add ip, r5, r9 /* ip = A1 - B1 */ - usat r5, #8, r3, asr #\shift - usat r9, #8, ip, asr #\shift - - add r3, r6, r10 /* r3 = A2 + B2 */ - sub ip, r6, r10 /* ip = A2 - B2 */ - usat r6, #8, r3, asr #\shift - usat r10,#8, ip, asr #\shift - - add r3, r7, r11 /* r3 = A3 + B3 */ - sub ip, r7, r11 /* ip = A3 - B3 */ - usat r7, #8, r3, asr #\shift - usat r11,#8, ip, asr #\shift - .endm - -/* - Compute IDCT of single row, storing as column. - r0 = source - r1 = dest -*/ -function idct_row_armv6 - push {lr} - - ldr lr, [r0, #12] /* lr = row[7,5] */ - ldr ip, [r0, #4] /* ip = row[6,4] */ - ldr r3, [r0, #8] /* r3 = row[3,1] */ - ldr r2, [r0] /* r2 = row[2,0] */ - orrs lr, lr, ip - cmpeq lr, r3 - cmpeq lr, r2, lsr #16 - beq 1f - push {r1} - ldr ip, w42 /* ip = W4 | (W2 << 16) */ - cmp lr, #0 - beq 2f - - idct_row ROW_SHIFT - b 3f - -2: idct_row4 ROW_SHIFT - -3: pop {r1} - idct_finish_shift ROW_SHIFT - - strh r4, [r1] - strh r5, [r1, #(16*2)] - strh r6, [r1, #(16*4)] - strh r7, [r1, #(16*6)] - strh r11,[r1, #(16*1)] - strh r10,[r1, #(16*3)] - strh r9, [r1, #(16*5)] - strh r8, [r1, #(16*7)] - - pop {pc} - -1: mov r2, r2, lsl #3 - strh r2, [r1] - strh r2, [r1, #(16*2)] - strh r2, [r1, #(16*4)] - strh r2, [r1, #(16*6)] - strh r2, [r1, #(16*1)] - strh r2, [r1, #(16*3)] - strh r2, [r1, #(16*5)] - strh r2, [r1, #(16*7)] - pop {pc} -endfunc - -/* - Compute IDCT of single column, read as row. - r0 = source - r1 = dest -*/ -function idct_col_armv6 - push {r1, lr} - - ldr r2, [r0] /* r2 = row[2,0] */ - ldr ip, w42 /* ip = W4 | (W2 << 16) */ - ldr r3, [r0, #8] /* r3 = row[3,1] */ - idct_row COL_SHIFT - pop {r1} - idct_finish_shift COL_SHIFT - - strh r4, [r1] - strh r5, [r1, #(16*1)] - strh r6, [r1, #(16*2)] - strh r7, [r1, #(16*3)] - strh r11,[r1, #(16*4)] - strh r10,[r1, #(16*5)] - strh r9, [r1, #(16*6)] - strh r8, [r1, #(16*7)] - - pop {pc} -endfunc - -/* - Compute IDCT of single column, read as row, store saturated 8-bit. - r0 = source - r1 = dest - r2 = line size -*/ -function idct_col_put_armv6 - push {r1, r2, lr} - - ldr r2, [r0] /* r2 = row[2,0] */ - ldr ip, w42 /* ip = W4 | (W2 << 16) */ - ldr r3, [r0, #8] /* r3 = row[3,1] */ - idct_row COL_SHIFT - pop {r1, r2} - idct_finish_shift_sat COL_SHIFT - - strb r4, [r1], r2 - strb r5, [r1], r2 - strb r6, [r1], r2 - strb r7, [r1], r2 - strb r11,[r1], r2 - strb r10,[r1], r2 - strb r9, [r1], r2 - strb r8, [r1], r2 - - sub r1, r1, r2, lsl #3 - - pop {pc} -endfunc - -/* - Compute IDCT of single column, read as row, add/store saturated 8-bit. - r0 = source - r1 = dest - r2 = line size -*/ -function idct_col_add_armv6 - push {r1, r2, lr} - - ldr r2, [r0] /* r2 = row[2,0] */ - ldr ip, w42 /* ip = W4 | (W2 << 16) */ - ldr r3, [r0, #8] /* r3 = row[3,1] */ - idct_row COL_SHIFT - pop {r1, r2} - idct_finish - - ldrb r3, [r1] - ldrb r7, [r1, r2] - ldrb r11,[r1, r2, lsl #2] - add ip, r3, ip, asr #COL_SHIFT - usat ip, #8, ip - add r4, r7, r4, asr #COL_SHIFT - strb ip, [r1], r2 - ldrb ip, [r1, r2] - usat r4, #8, r4 - ldrb r11,[r1, r2, lsl #2] - add r5, ip, r5, asr #COL_SHIFT - usat r5, #8, r5 - strb r4, [r1], r2 - ldrb r3, [r1, r2] - ldrb ip, [r1, r2, lsl #2] - strb r5, [r1], r2 - ldrb r7, [r1, r2] - ldrb r4, [r1, r2, lsl #2] - add r6, r3, r6, asr #COL_SHIFT - usat r6, #8, r6 - add r10,r7, r10,asr #COL_SHIFT - usat r10,#8, r10 - add r9, r11,r9, asr #COL_SHIFT - usat r9, #8, r9 - add r8, ip, r8, asr #COL_SHIFT - usat r8, #8, r8 - add lr, r4, lr, asr #COL_SHIFT - usat lr, #8, lr - strb r6, [r1], r2 - strb r10,[r1], r2 - strb r9, [r1], r2 - strb r8, [r1], r2 - strb lr, [r1], r2 - - sub r1, r1, r2, lsl #3 - - pop {pc} -endfunc - -/* - Compute 8 IDCT row transforms. - func = IDCT row->col function - width = width of columns in bytes -*/ - .macro idct_rows func width - bl \func - add r0, r0, #(16*2) - add r1, r1, #\width - bl \func - add r0, r0, #(16*2) - add r1, r1, #\width - bl \func - add r0, r0, #(16*2) - add r1, r1, #\width - bl \func - sub r0, r0, #(16*5) - add r1, r1, #\width - bl \func - add r0, r0, #(16*2) - add r1, r1, #\width - bl \func - add r0, r0, #(16*2) - add r1, r1, #\width - bl \func - add r0, r0, #(16*2) - add r1, r1, #\width - bl \func - - sub r0, r0, #(16*7) - .endm - -/* void ff_simple_idct_armv6(DCTELEM *data); */ -function ff_simple_idct_armv6, export=1 - push {r4-r11, lr} - sub sp, sp, #128 - - mov r1, sp - idct_rows idct_row_armv6, 2 - mov r1, r0 - mov r0, sp - idct_rows idct_col_armv6, 2 - - add sp, sp, #128 - pop {r4-r11, pc} -endfunc - -/* ff_simple_idct_add_armv6(uint8_t *dest, int line_size, DCTELEM *data); */ -function ff_simple_idct_add_armv6, export=1 - push {r0, r1, r4-r11, lr} - sub sp, sp, #128 - - mov r0, r2 - mov r1, sp - idct_rows idct_row_armv6, 2 - mov r0, sp - ldr r1, [sp, #128] - ldr r2, [sp, #(128+4)] - idct_rows idct_col_add_armv6, 1 - - add sp, sp, #(128+8) - pop {r4-r11, pc} -endfunc - -/* ff_simple_idct_put_armv6(uint8_t *dest, int line_size, DCTELEM *data); */ -function ff_simple_idct_put_armv6, export=1 - push {r0, r1, r4-r11, lr} - sub sp, sp, #128 - - mov r0, r2 - mov r1, sp - idct_rows idct_row_armv6, 2 - mov r0, sp - ldr r1, [sp, #128] - ldr r2, [sp, #(128+4)] - idct_rows idct_col_put_armv6, 1 - - add sp, sp, #(128+8) - pop {r4-r11, pc} -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_neon.S deleted file mode 100644 index f27208e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/simple_idct_neon.S +++ /dev/null @@ -1,373 +0,0 @@ -/* - * ARM NEON IDCT - * - * Copyright (c) 2008 Mans Rullgard - * - * Based on Simple IDCT - * Copyright (c) 2001 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W4c ((1<<(COL_SHIFT-1))/W4) -#define ROW_SHIFT 11 -#define COL_SHIFT 20 - -#define w1 d0[0] -#define w2 d0[1] -#define w3 d0[2] -#define w4 d0[3] -#define w5 d1[0] -#define w6 d1[1] -#define w7 d1[2] -#define w4c d1[3] - - .macro idct_col4_top - vmull.s16 q7, d6, w2 /* q9 = W2 * col[2] */ - vmull.s16 q8, d6, w6 /* q10 = W6 * col[2] */ - vmull.s16 q9, d4, w1 /* q9 = W1 * col[1] */ - vadd.i32 q11, q15, q7 - vmull.s16 q10, d4, w3 /* q10 = W3 * col[1] */ - vadd.i32 q12, q15, q8 - vmull.s16 q5, d4, w5 /* q5 = W5 * col[1] */ - vsub.i32 q13, q15, q8 - vmull.s16 q6, d4, w7 /* q6 = W7 * col[1] */ - vsub.i32 q14, q15, q7 - - vmlal.s16 q9, d8, w3 /* q9 += W3 * col[3] */ - vmlsl.s16 q10, d8, w7 /* q10 -= W7 * col[3] */ - vmlsl.s16 q5, d8, w1 /* q5 -= W1 * col[3] */ - vmlsl.s16 q6, d8, w5 /* q6 -= W5 * col[3] */ - .endm - - .text - .align 6 - -function idct_row4_pld_neon - pld [r0] - add r3, r0, r1, lsl #2 - pld [r0, r1] - pld [r0, r1, lsl #1] - pld [r3, -r1] - pld [r3] - pld [r3, r1] - add r3, r3, r1, lsl #1 - pld [r3] - pld [r3, r1] -endfunc - -function idct_row4_neon - vmov.i32 q15, #(1<<(ROW_SHIFT-1)) - vld1.64 {d2-d5}, [r2,:128]! - vmlal.s16 q15, d2, w4 /* q15 += W4 * col[0] */ - vld1.64 {d6,d7}, [r2,:128]! - vorr d10, d3, d5 - vld1.64 {d8,d9}, [r2,:128]! - add r2, r2, #-64 - - vorr d11, d7, d9 - vorr d10, d10, d11 - vmov r3, r4, d10 - - idct_col4_top - - orrs r3, r3, r4 - beq 1f - - vmull.s16 q7, d3, w4 /* q7 = W4 * col[4] */ - vmlal.s16 q9, d5, w5 /* q9 += W5 * col[5] */ - vmlsl.s16 q10, d5, w1 /* q10 -= W1 * col[5] */ - vmull.s16 q8, d7, w2 /* q8 = W2 * col[6] */ - vmlal.s16 q5, d5, w7 /* q5 += W7 * col[5] */ - vadd.i32 q11, q11, q7 - vsub.i32 q12, q12, q7 - vsub.i32 q13, q13, q7 - vadd.i32 q14, q14, q7 - vmlal.s16 q6, d5, w3 /* q6 += W3 * col[5] */ - vmull.s16 q7, d7, w6 /* q7 = W6 * col[6] */ - vmlal.s16 q9, d9, w7 - vmlsl.s16 q10, d9, w5 - vmlal.s16 q5, d9, w3 - vmlsl.s16 q6, d9, w1 - vadd.i32 q11, q11, q7 - vsub.i32 q12, q12, q8 - vadd.i32 q13, q13, q8 - vsub.i32 q14, q14, q7 - -1: vadd.i32 q3, q11, q9 - vadd.i32 q4, q12, q10 - vshrn.i32 d2, q3, #ROW_SHIFT - vshrn.i32 d4, q4, #ROW_SHIFT - vadd.i32 q7, q13, q5 - vadd.i32 q8, q14, q6 - vtrn.16 d2, d4 - vshrn.i32 d6, q7, #ROW_SHIFT - vshrn.i32 d8, q8, #ROW_SHIFT - vsub.i32 q14, q14, q6 - vsub.i32 q11, q11, q9 - vtrn.16 d6, d8 - vsub.i32 q13, q13, q5 - vshrn.i32 d3, q14, #ROW_SHIFT - vtrn.32 d2, d6 - vsub.i32 q12, q12, q10 - vtrn.32 d4, d8 - vshrn.i32 d5, q13, #ROW_SHIFT - vshrn.i32 d7, q12, #ROW_SHIFT - vshrn.i32 d9, q11, #ROW_SHIFT - - vtrn.16 d3, d5 - vtrn.16 d7, d9 - vtrn.32 d3, d7 - vtrn.32 d5, d9 - - vst1.64 {d2-d5}, [r2,:128]! - vst1.64 {d6-d9}, [r2,:128]! - - bx lr -endfunc - -function idct_col4_neon - mov ip, #16 - vld1.64 {d2}, [r2,:64], ip /* d2 = col[0] */ - vdup.16 d30, w4c - vld1.64 {d4}, [r2,:64], ip /* d3 = col[1] */ - vadd.i16 d30, d30, d2 - vld1.64 {d6}, [r2,:64], ip /* d4 = col[2] */ - vmull.s16 q15, d30, w4 /* q15 = W4*(col[0]+(1< - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - - preserve8 - -function ff_synth_filter_float_neon, export=1 - push {r3-r11,lr} - - ldr r4, [r2] @ synth_buf_offset - add r1, r1, r4, lsl #2 @ synth_buf - sub r12, r4, #32 - bfc r12, #9, #23 - bic r4, r4, #63 - str r12, [r2] - - ldr r2, [sp, #12*4] @ in - mov r9, r1 @ synth_buf - -VFP vpush {d0} - bl ff_imdct_half_neon -VFP vpop {d0} - pop {r3} - - ldr r5, [sp, #9*4] @ window - ldr r2, [sp, #10*4] @ out -NOVFP vldr d0, [sp, #12*4] @ scale, bias - add r8, r9, #12*4 - - mov lr, #64*4 - mov r1, #4 -1: - add r10, r9, #16*4 @ synth_buf - add r11, r8, #16*4 - add r0, r5, #16*4 @ window - add r6, r5, #32*4 - add r7, r5, #48*4 - - vld1.32 {q10}, [r3,:128] @ a - add r3, r3, #16*4 - vld1.32 {q1}, [r3,:128] @ b - vmov.f32 q2, #0.0 @ c - vmov.f32 q3, #0.0 @ d - - mov r12, #512 -2: - vld1.32 {q9}, [r8, :128], lr - vrev64.32 q9, q9 - vld1.32 {q8}, [r5, :128], lr - vmls.f32 d20, d16, d19 - vld1.32 {q11}, [r0, :128], lr - vmls.f32 d21, d17, d18 - vld1.32 {q12}, [r9, :128], lr - vmla.f32 d2, d22, d24 - vld1.32 {q8}, [r6, :128], lr - vmla.f32 d3, d23, d25 - vld1.32 {q9}, [r10,:128], lr - vmla.f32 d4, d16, d18 - vld1.32 {q12}, [r11,:128], lr - vmla.f32 d5, d17, d19 - vrev64.32 q12, q12 - vld1.32 {q11}, [r7, :128], lr - vmla.f32 d6, d22, d25 - vmla.f32 d7, d23, d24 - subs r12, r12, #64 - beq 3f - cmp r12, r4 - bne 2b - sub r8, r8, #512*4 - sub r9, r9, #512*4 - sub r10, r10, #512*4 - sub r11, r11, #512*4 - b 2b -3: - vdup.32 q8, d0[1] - vdup.32 q9, d0[1] - vmla.f32 q8, q10, d0[0] - vmla.f32 q9, q1, d0[0] - vst1.32 {q3}, [r3,:128] - sub r3, r3, #16*4 - vst1.32 {q2}, [r3,:128] - vst1.32 {q8}, [r2,:128] - add r2, r2, #16*4 - vst1.32 {q9}, [r2,:128] - - subs r1, r1, #1 - popeq {r4-r11,pc} - - cmp r4, #0 - subeq r8, r8, #512*4 - subeq r9, r9, #512*4 - sub r5, r5, #512*4 - sub r2, r2, #12*4 @ out - add r3, r3, #4*4 @ synth_buf2 - add r5, r5, #4*4 @ window - add r9, r9, #4*4 @ synth_buf - sub r8, r8, #4*4 @ synth_buf - b 1b -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/vp3dsp_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/vp3dsp_neon.S deleted file mode 100644 index ade1998..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/vp3dsp_neon.S +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (c) 2009 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -.section .rodata -.align 4 - -vp3_idct_constants: -.short 64277, 60547, 54491, 46341, 36410, 25080, 12785 - -#define xC1S7 d0[0] -#define xC2S6 d0[1] -#define xC3S5 d0[2] -#define xC4S4 d0[3] -#define xC5S3 d1[0] -#define xC6S2 d1[1] -#define xC7S1 d1[2] - -.text - -.macro vp3_loop_filter - vsubl.u8 q3, d18, d17 - vsubl.u8 q2, d16, d19 - vadd.i16 q1, q3, q3 - vadd.i16 q2, q2, q3 - vadd.i16 q0, q1, q2 - vrshr.s16 q0, q0, #3 - vmovl.u8 q9, d18 - vdup.u16 q15, r2 - - vabs.s16 q1, q0 - vshr.s16 q0, q0, #15 - vqsub.u16 q2, q15, q1 - vqsub.u16 q3, q2, q1 - vsub.i16 q1, q2, q3 - veor q1, q1, q0 - vsub.i16 q0, q1, q0 - - vaddw.u8 q2, q0, d17 - vsub.i16 q3, q9, q0 - vqmovun.s16 d0, q2 - vqmovun.s16 d1, q3 -.endm - -function ff_vp3_v_loop_filter_neon, export=1 - sub ip, r0, r1 - sub r0, r0, r1, lsl #1 - vld1.64 {d16}, [r0,:64], r1 - vld1.64 {d17}, [r0,:64], r1 - vld1.64 {d18}, [r0,:64], r1 - vld1.64 {d19}, [r0,:64], r1 - ldrb r2, [r2, #129*4] - - vp3_loop_filter - - vst1.64 {d0}, [ip,:64], r1 - vst1.64 {d1}, [ip,:64], r1 - bx lr -endfunc - -function ff_vp3_h_loop_filter_neon, export=1 - sub ip, r0, #1 - sub r0, r0, #2 - vld1.32 {d16[]}, [r0], r1 - vld1.32 {d17[]}, [r0], r1 - vld1.32 {d18[]}, [r0], r1 - vld1.32 {d19[]}, [r0], r1 - vld1.32 {d16[1]}, [r0], r1 - vld1.32 {d17[1]}, [r0], r1 - vld1.32 {d18[1]}, [r0], r1 - vld1.32 {d19[1]}, [r0], r1 - ldrb r2, [r2, #129*4] - - vtrn.8 d16, d17 - vtrn.8 d18, d19 - vtrn.16 d16, d18 - vtrn.16 d17, d19 - - vp3_loop_filter - - vtrn.8 d0, d1 - - vst1.16 {d0[0]}, [ip], r1 - vst1.16 {d1[0]}, [ip], r1 - vst1.16 {d0[1]}, [ip], r1 - vst1.16 {d1[1]}, [ip], r1 - vst1.16 {d0[2]}, [ip], r1 - vst1.16 {d1[2]}, [ip], r1 - vst1.16 {d0[3]}, [ip], r1 - vst1.16 {d1[3]}, [ip], r1 - bx lr -endfunc - - -function vp3_idct_start_neon - vpush {d8-d15} - movrel r3, vp3_idct_constants - vld1.64 {d0-d1}, [r3,:128] - vld1.64 {d16-d19}, [r2,:128]! - vld1.64 {d20-d23}, [r2,:128]! - vld1.64 {d24-d27}, [r2,:128]! - vadd.s16 q1, q8, q12 - vsub.s16 q8, q8, q12 - vld1.64 {d28-d31}, [r2,:128]! -endfunc - -function vp3_idct_core_neon - vmull.s16 q2, d18, xC1S7 // (ip[1] * C1) << 16 - vmull.s16 q3, d19, xC1S7 - vmull.s16 q4, d2, xC4S4 // ((ip[0] + ip[4]) * C4) << 16 - vmull.s16 q5, d3, xC4S4 - vmull.s16 q6, d16, xC4S4 // ((ip[0] - ip[4]) * C4) << 16 - vmull.s16 q7, d17, xC4S4 - vshrn.s32 d4, q2, #16 - vshrn.s32 d5, q3, #16 - vshrn.s32 d6, q4, #16 - vshrn.s32 d7, q5, #16 - vshrn.s32 d8, q6, #16 - vshrn.s32 d9, q7, #16 - vadd.s16 q12, q1, q3 // E = (ip[0] + ip[4]) * C4 - vadd.s16 q8, q8, q4 // F = (ip[0] - ip[4]) * C4 - vadd.s16 q1, q2, q9 // ip[1] * C1 - - vmull.s16 q2, d30, xC1S7 // (ip[7] * C1) << 16 - vmull.s16 q3, d31, xC1S7 - vmull.s16 q4, d30, xC7S1 // (ip[7] * C7) << 16 - vmull.s16 q5, d31, xC7S1 - vmull.s16 q6, d18, xC7S1 // (ip[1] * C7) << 16 - vmull.s16 q7, d19, xC7S1 - vshrn.s32 d4, q2, #16 - vshrn.s32 d5, q3, #16 - vshrn.s32 d6, q4, #16 // ip[7] * C7 - vshrn.s32 d7, q5, #16 - vshrn.s32 d8, q6, #16 // ip[1] * C7 - vshrn.s32 d9, q7, #16 - vadd.s16 q2, q2, q15 // ip[7] * C1 - vadd.s16 q9, q1, q3 // A = ip[1] * C1 + ip[7] * C7 - vsub.s16 q15, q4, q2 // B = ip[1] * C7 - ip[7] * C1 - - vmull.s16 q2, d22, xC5S3 // (ip[3] * C5) << 16 - vmull.s16 q3, d23, xC5S3 - vmull.s16 q4, d22, xC3S5 // (ip[3] * C3) << 16 - vmull.s16 q5, d23, xC3S5 - vmull.s16 q6, d26, xC5S3 // (ip[5] * C5) << 16 - vmull.s16 q7, d27, xC5S3 - vshrn.s32 d4, q2, #16 - vshrn.s32 d5, q3, #16 - vshrn.s32 d6, q4, #16 - vshrn.s32 d7, q5, #16 - vshrn.s32 d8, q6, #16 - vshrn.s32 d9, q7, #16 - vadd.s16 q3, q3, q11 // ip[3] * C3 - vadd.s16 q4, q4, q13 // ip[5] * C5 - vadd.s16 q1, q2, q11 // ip[3] * C5 - vadd.s16 q11, q3, q4 // C = ip[3] * C3 + ip[5] * C5 - - vmull.s16 q2, d26, xC3S5 // (ip[5] * C3) << 16 - vmull.s16 q3, d27, xC3S5 - vmull.s16 q4, d20, xC2S6 // (ip[2] * C2) << 16 - vmull.s16 q5, d21, xC2S6 - vmull.s16 q6, d28, xC6S2 // (ip[6] * C6) << 16 - vmull.s16 q7, d29, xC6S2 - vshrn.s32 d4, q2, #16 - vshrn.s32 d5, q3, #16 - vshrn.s32 d6, q4, #16 - vshrn.s32 d7, q5, #16 - vshrn.s32 d8, q6, #16 // ip[6] * C6 - vshrn.s32 d9, q7, #16 - vadd.s16 q2, q2, q13 // ip[5] * C3 - vadd.s16 q3, q3, q10 // ip[2] * C2 - vsub.s16 q13, q2, q1 // D = ip[5] * C3 - ip[3] * C5 - vsub.s16 q1, q9, q11 // (A - C) - vadd.s16 q11, q9, q11 // Cd = A + C - vsub.s16 q9, q15, q13 // (B - D) - vadd.s16 q13, q15, q13 // Dd = B + D - vadd.s16 q15, q3, q4 // G = ip[2] * C2 + ip[6] * C6 - - vmull.s16 q2, d2, xC4S4 // ((A - C) * C4) << 16 - vmull.s16 q3, d3, xC4S4 - vmull.s16 q4, d28, xC2S6 // (ip[6] * C2) << 16 - vmull.s16 q5, d29, xC2S6 - vmull.s16 q6, d20, xC6S2 // (ip[2] * C6) << 16 - vmull.s16 q7, d21, xC6S2 - vshrn.s32 d4, q2, #16 - vshrn.s32 d5, q3, #16 - vshrn.s32 d6, q4, #16 - vshrn.s32 d7, q5, #16 - vshrn.s32 d8, q6, #16 // ip[2] * C6 - vmull.s16 q5, d18, xC4S4 // ((B - D) * C4) << 16 - vmull.s16 q6, d19, xC4S4 - vshrn.s32 d9, q7, #16 - vadd.s16 q3, q3, q14 // ip[6] * C2 - vadd.s16 q10, q1, q2 // Ad = (A - C) * C4 - vsub.s16 q14, q4, q3 // H = ip[2] * C6 - ip[6] * C2 - bx lr -endfunc - -.macro VP3_IDCT_END type -function vp3_idct_end_\type\()_neon -.ifc \type, col - vdup.16 q0, r3 - vadd.s16 q12, q12, q0 - vadd.s16 q8, q8, q0 -.endif - - vshrn.s32 d2, q5, #16 - vshrn.s32 d3, q6, #16 - vadd.s16 q2, q12, q15 // Gd = E + G - vadd.s16 q9, q1, q9 // (B - D) * C4 - vsub.s16 q12, q12, q15 // Ed = E - G - vsub.s16 q3, q8, q10 // Fd = F - Ad - vadd.s16 q10, q8, q10 // Add = F + Ad - vadd.s16 q4, q9, q14 // Hd = Bd + H - vsub.s16 q14, q9, q14 // Bdd = Bd - H - vadd.s16 q8, q2, q11 // [0] = Gd + Cd - vsub.s16 q15, q2, q11 // [7] = Gd - Cd - vadd.s16 q9, q10, q4 // [1] = Add + Hd - vsub.s16 q10, q10, q4 // [2] = Add - Hd - vadd.s16 q11, q12, q13 // [3] = Ed + Dd - vsub.s16 q12, q12, q13 // [4] = Ed - Dd -.ifc \type, row - vtrn.16 q8, q9 -.endif - vadd.s16 q13, q3, q14 // [5] = Fd + Bdd - vsub.s16 q14, q3, q14 // [6] = Fd - Bdd - -.ifc \type, row - // 8x8 transpose - vtrn.16 q10, q11 - vtrn.16 q12, q13 - vtrn.16 q14, q15 - vtrn.32 q8, q10 - vtrn.32 q9, q11 - vtrn.32 q12, q14 - vtrn.32 q13, q15 - vswp d17, d24 - vswp d19, d26 - vadd.s16 q1, q8, q12 - vswp d21, d28 - vsub.s16 q8, q8, q12 - vswp d23, d30 -.endif - bx lr -endfunc -.endm - -VP3_IDCT_END row -VP3_IDCT_END col - -function ff_vp3_idct_neon, export=1 - mov ip, lr - mov r2, r0 - bl vp3_idct_start_neon - bl vp3_idct_end_row_neon - mov r3, #8 - bl vp3_idct_core_neon - bl vp3_idct_end_col_neon - mov lr, ip - vpop {d8-d15} - - vshr.s16 q8, q8, #4 - vshr.s16 q9, q9, #4 - vshr.s16 q10, q10, #4 - vshr.s16 q11, q11, #4 - vshr.s16 q12, q12, #4 - vst1.64 {d16-d19}, [r0,:128]! - vshr.s16 q13, q13, #4 - vshr.s16 q14, q14, #4 - vst1.64 {d20-d23}, [r0,:128]! - vshr.s16 q15, q15, #4 - vst1.64 {d24-d27}, [r0,:128]! - vst1.64 {d28-d31}, [r0,:128]! - bx lr -endfunc - -function ff_vp3_idct_put_neon, export=1 - mov ip, lr - bl vp3_idct_start_neon - bl vp3_idct_end_row_neon - mov r3, #8 - add r3, r3, #2048 // convert signed pixel to unsigned - bl vp3_idct_core_neon - bl vp3_idct_end_col_neon - mov lr, ip - vpop {d8-d15} - - vqshrun.s16 d0, q8, #4 - vqshrun.s16 d1, q9, #4 - vqshrun.s16 d2, q10, #4 - vqshrun.s16 d3, q11, #4 - vst1.64 {d0}, [r0,:64], r1 - vqshrun.s16 d4, q12, #4 - vst1.64 {d1}, [r0,:64], r1 - vqshrun.s16 d5, q13, #4 - vst1.64 {d2}, [r0,:64], r1 - vqshrun.s16 d6, q14, #4 - vst1.64 {d3}, [r0,:64], r1 - vqshrun.s16 d7, q15, #4 - vst1.64 {d4}, [r0,:64], r1 - vst1.64 {d5}, [r0,:64], r1 - vst1.64 {d6}, [r0,:64], r1 - vst1.64 {d7}, [r0,:64], r1 - bx lr -endfunc - -function ff_vp3_idct_add_neon, export=1 - mov ip, lr - bl vp3_idct_start_neon - bl vp3_idct_end_row_neon - mov r3, #8 - bl vp3_idct_core_neon - bl vp3_idct_end_col_neon - mov lr, ip - vpop {d8-d15} - mov r2, r0 - - vld1.64 {d0}, [r0,:64], r1 - vshr.s16 q8, q8, #4 - vld1.64 {d1}, [r0,:64], r1 - vshr.s16 q9, q9, #4 - vld1.64 {d2}, [r0,:64], r1 - vaddw.u8 q8, q8, d0 - vld1.64 {d3}, [r0,:64], r1 - vaddw.u8 q9, q9, d1 - vld1.64 {d4}, [r0,:64], r1 - vshr.s16 q10, q10, #4 - vld1.64 {d5}, [r0,:64], r1 - vshr.s16 q11, q11, #4 - vld1.64 {d6}, [r0,:64], r1 - vqmovun.s16 d0, q8 - vld1.64 {d7}, [r0,:64], r1 - vqmovun.s16 d1, q9 - vaddw.u8 q10, q10, d2 - vaddw.u8 q11, q11, d3 - vshr.s16 q12, q12, #4 - vshr.s16 q13, q13, #4 - vqmovun.s16 d2, q10 - vqmovun.s16 d3, q11 - vaddw.u8 q12, q12, d4 - vaddw.u8 q13, q13, d5 - vshr.s16 q14, q14, #4 - vshr.s16 q15, q15, #4 - vst1.64 {d0}, [r2,:64], r1 - vqmovun.s16 d4, q12 - vst1.64 {d1}, [r2,:64], r1 - vqmovun.s16 d5, q13 - vst1.64 {d2}, [r2,:64], r1 - vaddw.u8 q14, q14, d6 - vst1.64 {d3}, [r2,:64], r1 - vaddw.u8 q15, q15, d7 - vst1.64 {d4}, [r2,:64], r1 - vqmovun.s16 d6, q14 - vst1.64 {d5}, [r2,:64], r1 - vqmovun.s16 d7, q15 - vst1.64 {d6}, [r2,:64], r1 - vst1.64 {d7}, [r2,:64], r1 - bx lr -endfunc - -function ff_vp3_idct_dc_add_neon, export=1 - ldrsh r2, [r2] - movw r3, #46341 - mul r2, r3, r2 - smulwt r2, r3, r2 - mov r3, r0 - vdup.16 q15, r2 - vrshr.s16 q15, q15, #4 - - vld1.8 {d0}, [r0,:64], r1 - vld1.8 {d1}, [r0,:64], r1 - vld1.8 {d2}, [r0,:64], r1 - vaddw.u8 q8, q15, d0 - vld1.8 {d3}, [r0,:64], r1 - vaddw.u8 q9, q15, d1 - vld1.8 {d4}, [r0,:64], r1 - vaddw.u8 q10, q15, d2 - vld1.8 {d5}, [r0,:64], r1 - vaddw.u8 q11, q15, d3 - vld1.8 {d6}, [r0,:64], r1 - vaddw.u8 q12, q15, d4 - vld1.8 {d7}, [r0,:64], r1 - vaddw.u8 q13, q15, d5 - vqmovun.s16 d0, q8 - vaddw.u8 q14, q15, d6 - vqmovun.s16 d1, q9 - vaddw.u8 q15, q15, d7 - vqmovun.s16 d2, q10 - vst1.8 {d0}, [r3,:64], r1 - vqmovun.s16 d3, q11 - vst1.8 {d1}, [r3,:64], r1 - vqmovun.s16 d4, q12 - vst1.8 {d2}, [r3,:64], r1 - vqmovun.s16 d5, q13 - vst1.8 {d3}, [r3,:64], r1 - vqmovun.s16 d6, q14 - vst1.8 {d4}, [r3,:64], r1 - vqmovun.s16 d7, q15 - vst1.8 {d5}, [r3,:64], r1 - vst1.8 {d6}, [r3,:64], r1 - vst1.8 {d7}, [r3,:64], r1 - bx lr -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_init_arm.c b/tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_init_arm.c deleted file mode 100644 index ceab9a8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_init_arm.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "libavcodec/avcodec.h" -#include "libavcodec/vp56dsp.h" - -void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, int stride, int t); -void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, int stride, int t); - -void ff_vp56dsp_init_arm(VP56DSPContext *s, enum CodecID codec) -{ - if (codec != CODEC_ID_VP5 && HAVE_NEON) { - s->edge_filter_hor = ff_vp6_edge_filter_hor_neon; - s->edge_filter_ver = ff_vp6_edge_filter_ver_neon; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_neon.S b/tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_neon.S deleted file mode 100644 index 0353661..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/arm/vp56dsp_neon.S +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asm.S" - -.macro vp6_edge_filter - vdup.16 q3, r2 @ t - vmov.i16 q13, #1 - vsubl.u8 q0, d20, d18 @ p[ 0] - p[-s] - vsubl.u8 q1, d16, d22 @ p[-2*s] - p[ s] - vsubl.u8 q14, d21, d19 - vsubl.u8 q15, d17, d23 - vadd.i16 q2, q0, q0 @ 2*(p[0]-p[-s]) - vadd.i16 d29, d28, d28 - vadd.i16 q0, q0, q1 @ p[0]-p[-s] + p[-2*s]-p[s] - vadd.i16 d28, d28, d30 - vadd.i16 q0, q0, q2 @ 3*(p[0]-p[-s]) + p[-2*s]-p[s] - vadd.i16 d28, d28, d29 - vrshr.s16 q0, q0, #3 @ v - vrshr.s16 d28, d28, #3 - vsub.i16 q8, q3, q13 @ t-1 - vabs.s16 q1, q0 @ V - vshr.s16 q2, q0, #15 @ s - vabs.s16 d30, d28 - vshr.s16 d29, d28, #15 - vsub.i16 q12, q1, q3 @ V-t - vsub.i16 d31, d30, d6 - vsub.i16 q12, q12, q13 @ V-t-1 - vsub.i16 d31, d31, d26 - vcge.u16 q12, q12, q8 @ V-t-1 >= t-1 - vcge.u16 d31, d31, d16 - vadd.i16 q13, q3, q3 @ 2*t - vadd.i16 d16, d6, d6 - vsub.i16 q13, q13, q1 @ 2*t - V - vsub.i16 d16, d16, d30 - vadd.i16 q13, q13, q2 @ += s - vadd.i16 d16, d16, d29 - veor q13, q13, q2 @ ^= s - veor d16, d16, d29 - vbif q0, q13, q12 - vbif d28, d16, d31 - vmovl.u8 q1, d20 - vmovl.u8 q15, d21 - vaddw.u8 q2, q0, d18 - vaddw.u8 q3, q14, d19 - vsub.i16 q1, q1, q0 - vsub.i16 d30, d30, d28 - vqmovun.s16 d18, q2 - vqmovun.s16 d19, q3 - vqmovun.s16 d20, q1 - vqmovun.s16 d21, q15 -.endm - -function ff_vp6_edge_filter_ver_neon, export=1 - sub r0, r0, r1, lsl #1 - vld1.8 {q8}, [r0], r1 @ p[-2*s] - vld1.8 {q9}, [r0], r1 @ p[-s] - vld1.8 {q10}, [r0], r1 @ p[0] - vld1.8 {q11}, [r0] @ p[s] - vp6_edge_filter - sub r0, r0, r1, lsl #1 - sub r1, r1, #8 - vst1.8 {d18}, [r0]! - vst1.32 {d19[0]}, [r0], r1 - vst1.8 {d20}, [r0]! - vst1.32 {d21[0]}, [r0] - bx lr -endfunc - -function ff_vp6_edge_filter_hor_neon, export=1 - sub r3, r0, #1 - sub r0, r0, #2 - vld1.32 {d16[0]}, [r0], r1 - vld1.32 {d18[0]}, [r0], r1 - vld1.32 {d20[0]}, [r0], r1 - vld1.32 {d22[0]}, [r0], r1 - vld1.32 {d16[1]}, [r0], r1 - vld1.32 {d18[1]}, [r0], r1 - vld1.32 {d20[1]}, [r0], r1 - vld1.32 {d22[1]}, [r0], r1 - vld1.32 {d17[0]}, [r0], r1 - vld1.32 {d19[0]}, [r0], r1 - vld1.32 {d21[0]}, [r0], r1 - vld1.32 {d23[0]}, [r0], r1 - vtrn.8 q8, q9 - vtrn.8 q10, q11 - vtrn.16 q8, q10 - vtrn.16 q9, q11 - vp6_edge_filter - vtrn.8 q9, q10 - vst1.16 {d18[0]}, [r3], r1 - vst1.16 {d20[0]}, [r3], r1 - vst1.16 {d18[1]}, [r3], r1 - vst1.16 {d20[1]}, [r3], r1 - vst1.16 {d18[2]}, [r3], r1 - vst1.16 {d20[2]}, [r3], r1 - vst1.16 {d18[3]}, [r3], r1 - vst1.16 {d20[3]}, [r3], r1 - vst1.16 {d19[0]}, [r3], r1 - vst1.16 {d21[0]}, [r3], r1 - vst1.16 {d19[1]}, [r3], r1 - vst1.16 {d21[1]}, [r3], r1 - bx lr -endfunc diff --git a/tizen/distrib/ffmpeg/libavcodec/asv1.c b/tizen/distrib/ffmpeg/libavcodec/asv1.c deleted file mode 100644 index 211a13f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/asv1.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * ASUS V1/V2 codec - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * ASUS V1/V2 codec. - */ - -#include "avcodec.h" -#include "libavutil/common.h" -#include "put_bits.h" -#include "dsputil.h" -#include "mpeg12data.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(16, DCTELEM, block)[6][64]; - uint16_t intra_matrix[64]; - 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 av_cold void init_vlcs(ASV1Context *a){ - static int done = 0; - - if (!done) { - done = 1; - - INIT_VLC_STATIC(&ccp_vlc, VLC_BITS, 17, - &ccp_tab[0][1], 2, 1, - &ccp_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&dc_ccp_vlc, VLC_BITS, 8, - &dc_ccp_tab[0][1], 2, 1, - &dc_ccp_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&ac_ccp_vlc, VLC_BITS, 16, - &ac_ccp_tab[0][1], 2, 1, - &ac_ccp_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&level_vlc, VLC_BITS, 7, - &level_tab[0][1], 2, 1, - &level_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, - &asv2_level_tab[0][1], 2, 1, - &asv2_level_tab[0][0], 2, 1, 1024); - } -} - -//FIXME write a reversed bitstream reader to avoid the double reverse -static inline int asv2_get_bits(GetBitContext *gb, int n){ - return av_reverse[ get_bits(gb, n) << (8-n) ]; -} - -static inline void asv2_put_bits(PutBitContext *pb, int n, int v){ - put_bits(pb, n, av_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_sbits(pb, 8, level); - } -} - -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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - ASV1Context * const a = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= &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= FF_I_TYPE; - p->key_frame= 1; - - av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!a->bitstream_buffer) - return AVERROR(ENOMEM); - - if(avctx->codec_id == CODEC_ID_ASV1) - a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4); - else{ - int i; - for(i=0; ibitstream_buffer[i]= av_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; -} - -#if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER -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= &a->picture; - int size; - int mb_x, mb_y; - - init_put_bits(&a->pb, buf, buf_size); - - *p = *pict; - p->pict_type= FF_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]= av_reverse[ buf[i] ]; - } - - return size*4; -} -#endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */ - -static av_cold 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= &a->picture; - a->avctx= avctx; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - ASV1Context * const a = avctx->priv_data; - AVFrame *p= &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= 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; -} - -#if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER -static av_cold 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(AV_RL32("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; -} -#endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */ - -static av_cold 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; - - if(a->picture.data[0]) - avctx->release_buffer(avctx, &a->picture); - - return 0; -} - -AVCodec asv1_decoder = { - "asv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ASV1, - sizeof(ASV1Context), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("ASUS V1"), -}; - -AVCodec asv2_decoder = { - "asv2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ASV2, - sizeof(ASV1Context), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("ASUS V2"), -}; - -#if CONFIG_ASV1_ENCODER -AVCodec asv1_encoder = { - "asv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ASV1, - sizeof(ASV1Context), - encode_init, - encode_frame, - //encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("ASUS V1"), -}; -#endif - -#if CONFIG_ASV2_ENCODER -AVCodec asv2_encoder = { - "asv2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ASV2, - sizeof(ASV1Context), - encode_init, - encode_frame, - //encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("ASUS V2"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/atrac.c b/tizen/distrib/ffmpeg/libavcodec/atrac.c deleted file mode 100644 index e398cee..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/atrac.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Atrac common functions - * Copyright (c) 2006-2008 Maxim Poliakovski - * Copyright (c) 2006-2008 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - */ - -#include -#include -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "atrac.h" - -float sf_table[64]; -float qmf_window[48]; - -static const float qmf_48tap_half[24] = { - -0.00001461907, -0.00009205479,-0.000056157569,0.00030117269, - 0.0002422519, -0.00085293897,-0.0005205574, 0.0020340169, - 0.00078333891, -0.0042153862, -0.00075614988, 0.0078402944, - -0.000061169922,-0.01344162, 0.0024626821, 0.021736089, - -0.007801671, -0.034090221, 0.01880949, 0.054326009, - -0.043596379, -0.099384367, 0.13207909, 0.46424159 -}; - -/** - * Generate common tables - */ - -void atrac_generate_tables(void) -{ - int i; - float s; - - /* Generate scale factors */ - if (!sf_table[63]) - for (i=0 ; i<64 ; i++) - sf_table[i] = pow(2.0, (i - 15) / 3.0); - - /* Generate the QMF window. */ - if (!qmf_window[47]) - for (i=0 ; i<24; i++) { - s = qmf_48tap_half[i] * 2.0; - qmf_window[i] = qmf_window[47 - i] = s; - } -} - - -/** - * Quadrature mirror synthesis filter. - * - * @param inlo lower part of spectrum - * @param inhi higher part of spectrum - * @param nIn size of spectrum buffer - * @param pOut out buffer - * @param delayBuf delayBuf buffer - * @param temp temp buffer - */ - - -void atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp) -{ - int i, j; - float *p1, *p3; - - memcpy(temp, delayBuf, 46*sizeof(float)); - - p3 = temp + 46; - - /* loop1 */ - for(i=0; i -#include -#include - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" - -#include "atrac.h" -#include "atrac1data.h" - -#define AT1_MAX_BFU 52 ///< max number of block floating units in a sound unit -#define AT1_SU_SIZE 212 ///< number of bytes in a sound unit -#define AT1_SU_SAMPLES 512 ///< number of samples in a sound unit -#define AT1_FRAME_SIZE AT1_SU_SIZE * 2 -#define AT1_SU_MAX_BITS AT1_SU_SIZE * 8 -#define AT1_MAX_CHANNELS 2 - -#define AT1_QMF_BANDS 3 -#define IDX_LOW_BAND 0 -#define IDX_MID_BAND 1 -#define IDX_HIGH_BAND 2 - -/** - * Sound unit struct, one unit is used per channel - */ -typedef struct { - int log2_block_count[AT1_QMF_BANDS]; ///< log2 number of blocks in a band - int num_bfus; ///< number of Block Floating Units - float* spectrum[2]; - DECLARE_ALIGNED(16, float, spec1)[AT1_SU_SAMPLES]; ///< mdct buffer - DECLARE_ALIGNED(16, float, spec2)[AT1_SU_SAMPLES]; ///< mdct buffer - DECLARE_ALIGNED(16, float, fst_qmf_delay)[46]; ///< delay line for the 1st stacked QMF filter - DECLARE_ALIGNED(16, float, snd_qmf_delay)[46]; ///< delay line for the 2nd stacked QMF filter - DECLARE_ALIGNED(16, float, last_qmf_delay)[256+23]; ///< delay line for the last stacked QMF filter -} AT1SUCtx; - -/** - * The atrac1 context, holds all needed parameters for decoding - */ -typedef struct { - AT1SUCtx SUs[AT1_MAX_CHANNELS]; ///< channel sound unit - DECLARE_ALIGNED(16, float, spec)[AT1_SU_SAMPLES]; ///< the mdct spectrum buffer - - DECLARE_ALIGNED(16, float, low)[256]; - DECLARE_ALIGNED(16, float, mid)[256]; - DECLARE_ALIGNED(16, float, high)[512]; - float* bands[3]; - DECLARE_ALIGNED(16, float, out_samples)[AT1_MAX_CHANNELS][AT1_SU_SAMPLES]; - FFTContext mdct_ctx[3]; - int channels; - DSPContext dsp; -} AT1Ctx; - -/** size of the transform in samples in the long mode for each QMF band */ -static const uint16_t samples_per_band[3] = {128, 128, 256}; -static const uint8_t mdct_long_nbits[3] = {7, 7, 8}; - - -static void at1_imdct(AT1Ctx *q, float *spec, float *out, int nbits, - int rev_spec) -{ - FFTContext* mdct_context = &q->mdct_ctx[nbits - 5 - (nbits > 6)]; - int transf_size = 1 << nbits; - - if (rev_spec) { - int i; - for (i = 0; i < transf_size / 2; i++) - FFSWAP(float, spec[i], spec[transf_size - 1 - i]); - } - ff_imdct_half(mdct_context, out, spec); -} - - -static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q) -{ - int band_num, band_samples, log2_block_count, nbits, num_blocks, block_size; - unsigned int start_pos, ref_pos = 0, pos = 0; - - for (band_num = 0; band_num < AT1_QMF_BANDS; band_num++) { - float *prev_buf; - int j; - - band_samples = samples_per_band[band_num]; - log2_block_count = su->log2_block_count[band_num]; - - /* number of mdct blocks in the current QMF band: 1 - for long mode */ - /* 4 for short mode(low/middle bands) and 8 for short mode(high band)*/ - num_blocks = 1 << log2_block_count; - - if (num_blocks == 1) { - /* mdct block size in samples: 128 (long mode, low & mid bands), */ - /* 256 (long mode, high band) and 32 (short mode, all bands) */ - block_size = band_samples >> log2_block_count; - - /* calc transform size in bits according to the block_size_mode */ - nbits = mdct_long_nbits[band_num] - log2_block_count; - - if (nbits != 5 && nbits != 7 && nbits != 8) - return -1; - } else { - block_size = 32; - nbits = 5; - } - - start_pos = 0; - prev_buf = &su->spectrum[1][ref_pos + band_samples - 16]; - for (j=0; j < num_blocks; j++) { - at1_imdct(q, &q->spec[pos], &su->spectrum[0][ref_pos + start_pos], nbits, band_num); - - /* overlap and window */ - q->dsp.vector_fmul_window(&q->bands[band_num][start_pos], prev_buf, - &su->spectrum[0][ref_pos + start_pos], ff_sine_32, 0, 16); - - prev_buf = &su->spectrum[0][ref_pos+start_pos + 16]; - start_pos += block_size; - pos += block_size; - } - - if (num_blocks == 1) - memcpy(q->bands[band_num] + 32, &su->spectrum[0][ref_pos + 16], 240 * sizeof(float)); - - ref_pos += band_samples; - } - - /* Swap buffers so the mdct overlap works */ - FFSWAP(float*, su->spectrum[0], su->spectrum[1]); - - return 0; -} - -/** - * Parse the block size mode byte - */ - -static int at1_parse_bsm(GetBitContext* gb, int log2_block_cnt[AT1_QMF_BANDS]) -{ - int log2_block_count_tmp, i; - - for (i = 0; i < 2; i++) { - /* low and mid band */ - log2_block_count_tmp = get_bits(gb, 2); - if (log2_block_count_tmp & 1) - return -1; - log2_block_cnt[i] = 2 - log2_block_count_tmp; - } - - /* high band */ - log2_block_count_tmp = get_bits(gb, 2); - if (log2_block_count_tmp != 0 && log2_block_count_tmp != 3) - return -1; - log2_block_cnt[IDX_HIGH_BAND] = 3 - log2_block_count_tmp; - - skip_bits(gb, 2); - return 0; -} - - -static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su, - float spec[AT1_SU_SAMPLES]) -{ - int bits_used, band_num, bfu_num, i; - uint8_t idwls[AT1_MAX_BFU]; ///< the word length indexes for each BFU - uint8_t idsfs[AT1_MAX_BFU]; ///< the scalefactor indexes for each BFU - - /* parse the info byte (2nd byte) telling how much BFUs were coded */ - su->num_bfus = bfu_amount_tab1[get_bits(gb, 3)]; - - /* calc number of consumed bits: - num_BFUs * (idwl(4bits) + idsf(6bits)) + log2_block_count(8bits) + info_byte(8bits) - + info_byte_copy(8bits) + log2_block_count_copy(8bits) */ - bits_used = su->num_bfus * 10 + 32 + - bfu_amount_tab2[get_bits(gb, 2)] + - (bfu_amount_tab3[get_bits(gb, 3)] << 1); - - /* get word length index (idwl) for each BFU */ - for (i = 0; i < su->num_bfus; i++) - idwls[i] = get_bits(gb, 4); - - /* get scalefactor index (idsf) for each BFU */ - for (i = 0; i < su->num_bfus; i++) - idsfs[i] = get_bits(gb, 6); - - /* zero idwl/idsf for empty BFUs */ - for (i = su->num_bfus; i < AT1_MAX_BFU; i++) - idwls[i] = idsfs[i] = 0; - - /* read in the spectral data and reconstruct MDCT spectrum of this channel */ - for (band_num = 0; band_num < AT1_QMF_BANDS; band_num++) { - for (bfu_num = bfu_bands_t[band_num]; bfu_num < bfu_bands_t[band_num+1]; bfu_num++) { - int pos; - - int num_specs = specs_per_bfu[bfu_num]; - int word_len = !!idwls[bfu_num] + idwls[bfu_num]; - float scale_factor = sf_table[idsfs[bfu_num]]; - bits_used += word_len * num_specs; /* add number of bits consumed by current BFU */ - - /* check for bitstream overflow */ - if (bits_used > AT1_SU_MAX_BITS) - return -1; - - /* get the position of the 1st spec according to the block size mode */ - pos = su->log2_block_count[band_num] ? bfu_start_short[bfu_num] : bfu_start_long[bfu_num]; - - if (word_len) { - float max_quant = 1.0 / (float)((1 << (word_len - 1)) - 1); - - for (i = 0; i < num_specs; i++) { - /* read in a quantized spec and convert it to - * signed int and then inverse quantization - */ - spec[pos+i] = get_sbits(gb, word_len) * scale_factor * max_quant; - } - } else { /* word_len = 0 -> empty BFU, zero all specs in the emty BFU */ - memset(&spec[pos], 0, num_specs * sizeof(float)); - } - } - } - - return 0; -} - - -static void at1_subband_synthesis(AT1Ctx *q, AT1SUCtx* su, float *pOut) -{ - float temp[256]; - float iqmf_temp[512 + 46]; - - /* combine low and middle bands */ - atrac_iqmf(q->bands[0], q->bands[1], 128, temp, su->fst_qmf_delay, iqmf_temp); - - /* delay the signal of the high band by 23 samples */ - memcpy( su->last_qmf_delay, &su->last_qmf_delay[256], sizeof(float) * 23); - memcpy(&su->last_qmf_delay[23], q->bands[2], sizeof(float) * 256); - - /* combine (low + middle) and high bands */ - atrac_iqmf(temp, su->last_qmf_delay, 256, pOut, su->snd_qmf_delay, iqmf_temp); -} - - -static int atrac1_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AT1Ctx *q = avctx->priv_data; - int ch, ret, i; - GetBitContext gb; - float* samples = data; - - - if (buf_size < 212 * q->channels) { - av_log(q,AV_LOG_ERROR,"Not enought data to decode!\n"); - return -1; - } - - for (ch = 0; ch < q->channels; ch++) { - AT1SUCtx* su = &q->SUs[ch]; - - init_get_bits(&gb, &buf[212 * ch], 212 * 8); - - /* parse block_size_mode, 1st byte */ - ret = at1_parse_bsm(&gb, su->log2_block_count); - if (ret < 0) - return ret; - - ret = at1_unpack_dequant(&gb, su, q->spec); - if (ret < 0) - return ret; - - ret = at1_imdct_block(su, q); - if (ret < 0) - return ret; - at1_subband_synthesis(q, su, q->out_samples[ch]); - } - - /* interleave; FIXME, should create/use a DSP function */ - if (q->channels == 1) { - /* mono */ - memcpy(samples, q->out_samples[0], AT1_SU_SAMPLES * 4); - } else { - /* stereo */ - for (i = 0; i < AT1_SU_SAMPLES; i++) { - samples[i * 2] = q->out_samples[0][i]; - samples[i * 2 + 1] = q->out_samples[1][i]; - } - } - - *data_size = q->channels * AT1_SU_SAMPLES * sizeof(*samples); - return avctx->block_align; -} - - -static av_cold int atrac1_decode_init(AVCodecContext *avctx) -{ - AT1Ctx *q = avctx->priv_data; - - avctx->sample_fmt = SAMPLE_FMT_FLT; - - q->channels = avctx->channels; - - /* Init the mdct transforms */ - ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15)); - ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15)); - ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15)); - - ff_init_ff_sine_windows(5); - - atrac_generate_tables(); - - dsputil_init(&q->dsp, avctx); - - q->bands[0] = q->low; - q->bands[1] = q->mid; - q->bands[2] = q->high; - - /* Prepare the mdct overlap buffers */ - q->SUs[0].spectrum[0] = q->SUs[0].spec1; - q->SUs[0].spectrum[1] = q->SUs[0].spec2; - q->SUs[1].spectrum[0] = q->SUs[1].spec1; - q->SUs[1].spectrum[1] = q->SUs[1].spec2; - - return 0; -} - - -static av_cold int atrac1_decode_end(AVCodecContext * avctx) { - AT1Ctx *q = avctx->priv_data; - - ff_mdct_end(&q->mdct_ctx[0]); - ff_mdct_end(&q->mdct_ctx[1]); - ff_mdct_end(&q->mdct_ctx[2]); - return 0; -} - - -AVCodec atrac1_decoder = { - .name = "atrac1", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_ATRAC1, - .priv_data_size = sizeof(AT1Ctx), - .init = atrac1_decode_init, - .close = atrac1_decode_end, - .decode = atrac1_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/atrac1data.h b/tizen/distrib/ffmpeg/libavcodec/atrac1data.h deleted file mode 100644 index ebebe4b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/atrac1data.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Atrac 1 compatible decoder data - * Copyright (c) 2009 Maxim Poliakovski - * Copyright (c) 2009 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Atrac 1 compatible decoder data - */ - -#ifndef AVCODEC_ATRAC1DATA_H -#define AVCODEC_ATRAC1DATA_H - -#include - -static const uint8_t bfu_amount_tab1[8] = {20, 28, 32, 36, 40, 44, 48, 52}; -static const uint8_t bfu_amount_tab2[4] = { 0, 112, 176, 208}; -static const uint8_t bfu_amount_tab3[8] = { 0, 24, 36, 48, 72, 108, 132, 156}; - -/** number of BFUs in each QMF band */ -static const uint8_t bfu_bands_t[4] = {0, 20, 36, 52}; - -/** number of spectral lines in each BFU - * block floating unit = group of spectral frequencies having the - * same quantization parameters like word length and scale factor - */ -static const uint8_t specs_per_bfu[52] = { - 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, // low band - 6, 6, 6, 6, 7, 7, 7, 7, 9, 9, 9, 9, 10, 10, 10, 10, // midle band - 12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, 20 // high band -}; - -/** start position of each BFU in the MDCT spectrum for the long mode */ -static const uint16_t bfu_start_long[52] = { - 0, 8, 16, 24, 32, 36, 40, 44, 48, 56, 64, 72, 80, 86, 92, 98, 104, 110, 116, 122, - 128, 134, 140, 146, 152, 159, 166, 173, 180, 189, 198, 207, 216, 226, 236, 246, - 256, 268, 280, 292, 304, 316, 328, 340, 352, 372, 392, 412, 432, 452, 472, 492, -}; - -/** start position of each BFU in the MDCT spectrum for the short mode */ -static const uint16_t bfu_start_short[52] = { - 0, 32, 64, 96, 8, 40, 72, 104, 12, 44, 76, 108, 20, 52, 84, 116, 26, 58, 90, 122, - 128, 160, 192, 224, 134, 166, 198, 230, 141, 173, 205, 237, 150, 182, 214, 246, - 256, 288, 320, 352, 384, 416, 448, 480, 268, 300, 332, 364, 396, 428, 460, 492 -}; - -#endif /* AVCODEC_ATRAC1DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/atrac3.c b/tizen/distrib/ffmpeg/libavcodec/atrac3.c deleted file mode 100644 index 5179c34..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/atrac3.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * Atrac 3 compatible decoder - * Copyright (c) 2006-2008 Maxim Poliakovski - * Copyright (c) 2006-2008 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Atrac 3 compatible decoder. - * This decoder handles Sony's ATRAC3 data. - * - * Container formats used to store atrac 3 data: - * RealMedia (.rm), RIFF WAV (.wav, .at3), Sony OpenMG (.oma, .aa3). - * - * To use this decoder, a calling application must supply the extradata - * bytes provided in the containers above. - */ - -#include -#include -#include - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "bytestream.h" -#include "fft.h" - -#include "atrac.h" -#include "atrac3data.h" - -#define JOINT_STEREO 0x12 -#define STEREO 0x2 - - -/* These structures are needed to store the parsed gain control data. */ -typedef struct { - int num_gain_data; - int levcode[8]; - int loccode[8]; -} gain_info; - -typedef struct { - gain_info gBlock[4]; -} gain_block; - -typedef struct { - int pos; - int numCoefs; - float coef[8]; -} tonal_component; - -typedef struct { - int bandsCoded; - int numComponents; - tonal_component components[64]; - float prevFrame[1024]; - int gcBlkSwitch; - gain_block gainBlock[2]; - - DECLARE_ALIGNED(16, float, spectrum)[1024]; - DECLARE_ALIGNED(16, float, IMDCT_buf)[1024]; - - float delayBuf1[46]; ///> (off*8)) | (0x537F6103 << (32-(off*8)))); - bytes += 3 + off; - for (i = 0; i < bytes/4; i++) - obuf[i] = c ^ buf[i]; - - if (off) - av_log(NULL,AV_LOG_DEBUG,"Offset of %d not handled, post sample on ffmpeg-dev.\n",off); - - return off; -} - - -static av_cold void init_atrac3_transforms(ATRAC3Context *q) { - float enc_window[256]; - int i; - - /* Generate the mdct window, for details see - * http://wiki.multimedia.cx/index.php?title=RealAudio_atrc#Windows */ - for (i=0 ; i<256; i++) - enc_window[i] = (sin(((i + 0.5) / 256.0 - 0.5) * M_PI) + 1.0) * 0.5; - - if (!mdct_window[0]) - for (i=0 ; i<256; i++) { - mdct_window[i] = enc_window[i]/(enc_window[i]*enc_window[i] + enc_window[255-i]*enc_window[255-i]); - mdct_window[511-i] = mdct_window[i]; - } - - /* Initialize the MDCT transform. */ - ff_mdct_init(&mdct_ctx, 9, 1, 1.0); -} - -/** - * Atrac3 uninit, free all allocated memory - */ - -static av_cold int atrac3_decode_close(AVCodecContext *avctx) -{ - ATRAC3Context *q = avctx->priv_data; - - av_free(q->pUnits); - av_free(q->decoded_bytes_buffer); - - return 0; -} - -/** -/ * Mantissa decoding - * - * @param gb the GetBit context - * @param selector what table is the output values coded with - * @param codingFlag constant length coding or variable length coding - * @param mantissas mantissa output table - * @param numCodes amount of values to get - */ - -static void readQuantSpectralCoeffs (GetBitContext *gb, int selector, int codingFlag, int* mantissas, int numCodes) -{ - int numBits, cnt, code, huffSymb; - - if (selector == 1) - numCodes /= 2; - - if (codingFlag != 0) { - /* constant length coding (CLC) */ - numBits = CLCLengthTab[selector]; - - if (selector > 1) { - for (cnt = 0; cnt < numCodes; cnt++) { - if (numBits) - code = get_sbits(gb, numBits); - else - code = 0; - mantissas[cnt] = code; - } - } else { - for (cnt = 0; cnt < numCodes; cnt++) { - if (numBits) - code = get_bits(gb, numBits); //numBits is always 4 in this case - else - code = 0; - mantissas[cnt*2] = seTab_0[code >> 2]; - mantissas[cnt*2+1] = seTab_0[code & 3]; - } - } - } else { - /* variable length coding (VLC) */ - if (selector != 1) { - for (cnt = 0; cnt < numCodes; cnt++) { - huffSymb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, spectral_coeff_tab[selector-1].bits, 3); - huffSymb += 1; - code = huffSymb >> 1; - if (huffSymb & 1) - code = -code; - mantissas[cnt] = code; - } - } else { - for (cnt = 0; cnt < numCodes; cnt++) { - huffSymb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, spectral_coeff_tab[selector-1].bits, 3); - mantissas[cnt*2] = decTable1[huffSymb*2]; - mantissas[cnt*2+1] = decTable1[huffSymb*2+1]; - } - } - } -} - -/** - * Restore the quantized band spectrum coefficients - * - * @param gb the GetBit context - * @param pOut decoded band spectrum - * @return outSubbands subband counter, fix for broken specification/files - */ - -static int decodeSpectrum (GetBitContext *gb, float *pOut) -{ - int numSubbands, codingMode, cnt, first, last, subbWidth, *pIn; - int subband_vlc_index[32], SF_idxs[32]; - int mantissas[128]; - float SF; - - numSubbands = get_bits(gb, 5); // number of coded subbands - codingMode = get_bits1(gb); // coding Mode: 0 - VLC/ 1-CLC - - /* Get the VLC selector table for the subbands, 0 means not coded. */ - for (cnt = 0; cnt <= numSubbands; cnt++) - subband_vlc_index[cnt] = get_bits(gb, 3); - - /* Read the scale factor indexes from the stream. */ - for (cnt = 0; cnt <= numSubbands; cnt++) { - if (subband_vlc_index[cnt] != 0) - SF_idxs[cnt] = get_bits(gb, 6); - } - - for (cnt = 0; cnt <= numSubbands; cnt++) { - first = subbandTab[cnt]; - last = subbandTab[cnt+1]; - - subbWidth = last - first; - - if (subband_vlc_index[cnt] != 0) { - /* Decode spectral coefficients for this subband. */ - /* TODO: This can be done faster is several blocks share the - * same VLC selector (subband_vlc_index) */ - readQuantSpectralCoeffs (gb, subband_vlc_index[cnt], codingMode, mantissas, subbWidth); - - /* Decode the scale factor for this subband. */ - SF = sf_table[SF_idxs[cnt]] * iMaxQuant[subband_vlc_index[cnt]]; - - /* Inverse quantize the coefficients. */ - for (pIn=mantissas ; first> 2] == 0) - continue; - - coded_components = get_bits(gb,3); - - for (k=0; kgBlock; - - for (i=0 ; i<=numBands; i++) - { - numData = get_bits(gb,3); - pGain[i].num_gain_data = numData; - pLevel = pGain[i].levcode; - pLoc = pGain[i].loccode; - - for (cf = 0; cf < numData; cf++){ - pLevel[cf]= get_bits(gb,4); - pLoc [cf]= get_bits(gb,5); - if(cf && pLoc[cf] <= pLoc[cf-1]) - return -1; - } - } - - /* Clear the unused blocks. */ - for (; i<4 ; i++) - pGain[i].num_gain_data = 0; - - return 0; -} - -/** - * Apply gain parameters and perform the MDCT overlapping part - * - * @param pIn input float buffer - * @param pPrev previous float buffer to perform overlap against - * @param pOut output float buffer - * @param pGain1 current band gain info - * @param pGain2 next band gain info - */ - -static void gainCompensateAndOverlap (float *pIn, float *pPrev, float *pOut, gain_info *pGain1, gain_info *pGain2) -{ - /* gain compensation function */ - float gain1, gain2, gain_inc; - int cnt, numdata, nsample, startLoc, endLoc; - - - if (pGain2->num_gain_data == 0) - gain1 = 1.0; - else - gain1 = gain_tab1[pGain2->levcode[0]]; - - if (pGain1->num_gain_data == 0) { - for (cnt = 0; cnt < 256; cnt++) - pOut[cnt] = pIn[cnt] * gain1 + pPrev[cnt]; - } else { - numdata = pGain1->num_gain_data; - pGain1->loccode[numdata] = 32; - pGain1->levcode[numdata] = 4; - - nsample = 0; // current sample = 0 - - for (cnt = 0; cnt < numdata; cnt++) { - startLoc = pGain1->loccode[cnt] * 8; - endLoc = startLoc + 8; - - gain2 = gain_tab1[pGain1->levcode[cnt]]; - gain_inc = gain_tab2[(pGain1->levcode[cnt+1] - pGain1->levcode[cnt])+15]; - - /* interpolate */ - for (; nsample < startLoc; nsample++) - pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; - - /* interpolation is done over eight samples */ - for (; nsample < endLoc; nsample++) { - pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; - gain2 *= gain_inc; - } - } - - for (; nsample < 256; nsample++) - pOut[nsample] = (pIn[nsample] * gain1) + pPrev[nsample]; - } - - /* Delay for the overlapping part. */ - memcpy(pPrev, &pIn[256], 256*sizeof(float)); -} - -/** - * Combine the tonal band spectrum and regular band spectrum - * Return position of the last tonal coefficient - * - * @param pSpectrum output spectrum buffer - * @param numComponents amount of tonal components - * @param pComponent tonal components for this band - */ - -static int addTonalComponents (float *pSpectrum, int numComponents, tonal_component *pComponent) -{ - int cnt, i, lastPos = -1; - float *pIn, *pOut; - - for (cnt = 0; cnt < numComponents; cnt++){ - lastPos = FFMAX(pComponent[cnt].pos + pComponent[cnt].numCoefs, lastPos); - pIn = pComponent[cnt].coef; - pOut = &(pSpectrum[pComponent[cnt].pos]); - - for (i=0 ; ibandsCoded = get_bits(gb,2); - - result = decodeGainControl (gb, &(pSnd->gainBlock[pSnd->gcBlkSwitch]), pSnd->bandsCoded); - if (result) return result; - - pSnd->numComponents = decodeTonalComponents (gb, pSnd->components, pSnd->bandsCoded); - if (pSnd->numComponents == -1) return -1; - - numSubbands = decodeSpectrum (gb, pSnd->spectrum); - - /* Merge the decoded spectrum and tonal components. */ - lastTonal = addTonalComponents (pSnd->spectrum, pSnd->numComponents, pSnd->components); - - - /* calculate number of used MLT/QMF bands according to the amount of coded spectral lines */ - numBands = (subbandTab[numSubbands] - 1) >> 8; - if (lastTonal >= 0) - numBands = FFMAX((lastTonal + 256) >> 8, numBands); - - - /* Reconstruct time domain samples. */ - for (band=0; band<4; band++) { - /* Perform the IMDCT step without overlapping. */ - if (band <= numBands) { - IMLT(&(pSnd->spectrum[band*256]), pSnd->IMDCT_buf, band&1); - } else - memset(pSnd->IMDCT_buf, 0, 512 * sizeof(float)); - - /* gain compensation and overlapping */ - gainCompensateAndOverlap (pSnd->IMDCT_buf, &(pSnd->prevFrame[band*256]), &(pOut[band*256]), - &((pSnd->gainBlock[1 - (pSnd->gcBlkSwitch)]).gBlock[band]), - &((pSnd->gainBlock[pSnd->gcBlkSwitch]).gBlock[band])); - } - - /* Swap the gain control buffers for the next frame. */ - pSnd->gcBlkSwitch ^= 1; - - return 0; -} - -/** - * Frame handling - * - * @param q Atrac3 private context - * @param databuf the input data - */ - -static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) -{ - int result, i; - float *p1, *p2, *p3, *p4; - uint8_t *ptr1; - - if (q->codingMode == JOINT_STEREO) { - - /* channel coupling mode */ - /* decode Sound Unit 1 */ - init_get_bits(&q->gb,databuf,q->bits_per_frame); - - result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, q->outSamples, 0, JOINT_STEREO); - if (result != 0) - return (result); - - /* Framedata of the su2 in the joint-stereo mode is encoded in - * reverse byte order so we need to swap it first. */ - if (databuf == q->decoded_bytes_buffer) { - uint8_t *ptr2 = q->decoded_bytes_buffer+q->bytes_per_frame-1; - ptr1 = q->decoded_bytes_buffer; - for (i = 0; i < (q->bytes_per_frame/2); i++, ptr1++, ptr2--) { - FFSWAP(uint8_t,*ptr1,*ptr2); - } - } else { - const uint8_t *ptr2 = databuf+q->bytes_per_frame-1; - for (i = 0; i < q->bytes_per_frame; i++) - q->decoded_bytes_buffer[i] = *ptr2--; - } - - /* Skip the sync codes (0xF8). */ - ptr1 = q->decoded_bytes_buffer; - for (i = 4; *ptr1 == 0xF8; i++, ptr1++) { - if (i >= q->bytes_per_frame) - return -1; - } - - - /* set the bitstream reader at the start of the second Sound Unit*/ - init_get_bits(&q->gb,ptr1,q->bits_per_frame); - - /* Fill the Weighting coeffs delay buffer */ - memmove(q->weighting_delay,&(q->weighting_delay[2]),4*sizeof(int)); - q->weighting_delay[4] = get_bits1(&q->gb); - q->weighting_delay[5] = get_bits(&q->gb,3); - - for (i = 0; i < 4; i++) { - q->matrix_coeff_index_prev[i] = q->matrix_coeff_index_now[i]; - q->matrix_coeff_index_now[i] = q->matrix_coeff_index_next[i]; - q->matrix_coeff_index_next[i] = get_bits(&q->gb,2); - } - - /* Decode Sound Unit 2. */ - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], &q->outSamples[1024], 1, JOINT_STEREO); - if (result != 0) - return (result); - - /* Reconstruct the channel coefficients. */ - reverseMatrixing(q->outSamples, &q->outSamples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); - - channelWeighting(q->outSamples, &q->outSamples[1024], q->weighting_delay); - - } else { - /* normal stereo mode or mono */ - /* Decode the channel sound units. */ - for (i=0 ; ichannels ; i++) { - - /* Set the bitstream reader at the start of a channel sound unit. */ - init_get_bits(&q->gb, databuf+((i*q->bytes_per_frame)/q->channels), (q->bits_per_frame)/q->channels); - - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], &q->outSamples[i*1024], i, q->codingMode); - if (result != 0) - return (result); - } - } - - /* Apply the iQMF synthesis filter. */ - p1= q->outSamples; - for (i=0 ; ichannels ; i++) { - p2= p1+256; - p3= p2+256; - p4= p3+256; - atrac_iqmf (p1, p2, 256, p1, q->pUnits[i].delayBuf1, q->tempBuf); - atrac_iqmf (p4, p3, 256, p3, q->pUnits[i].delayBuf2, q->tempBuf); - atrac_iqmf (p1, p3, 512, p1, q->pUnits[i].delayBuf3, q->tempBuf); - p1 +=1024; - } - - return 0; -} - - -/** - * Atrac frame decoding - * - * @param avctx pointer to the AVCodecContext - */ - -static int atrac3_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - ATRAC3Context *q = avctx->priv_data; - int result = 0, i; - const uint8_t* databuf; - int16_t* samples = data; - - if (buf_size < avctx->block_align) - return buf_size; - - /* Check if we need to descramble and what buffer to pass on. */ - if (q->scrambled_stream) { - decode_bytes(buf, q->decoded_bytes_buffer, avctx->block_align); - databuf = q->decoded_bytes_buffer; - } else { - databuf = buf; - } - - result = decodeFrame(q, databuf); - - if (result != 0) { - av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); - return -1; - } - - if (q->channels == 1) { - /* mono */ - for (i = 0; i<1024; i++) - samples[i] = av_clip_int16(round(q->outSamples[i])); - *data_size = 1024 * sizeof(int16_t); - } else { - /* stereo */ - for (i = 0; i < 1024; i++) { - samples[i*2] = av_clip_int16(round(q->outSamples[i])); - samples[i*2+1] = av_clip_int16(round(q->outSamples[1024+i])); - } - *data_size = 2048 * sizeof(int16_t); - } - - return avctx->block_align; -} - - -/** - * Atrac3 initialization - * - * @param avctx pointer to the AVCodecContext - */ - -static av_cold int atrac3_decode_init(AVCodecContext *avctx) -{ - int i; - const uint8_t *edata_ptr = avctx->extradata; - ATRAC3Context *q = avctx->priv_data; - static VLC_TYPE atrac3_vlc_table[4096][2]; - static int vlcs_initialized = 0; - - /* Take data from the AVCodecContext (RM container). */ - q->sample_rate = avctx->sample_rate; - q->channels = avctx->channels; - q->bit_rate = avctx->bit_rate; - q->bits_per_frame = avctx->block_align * 8; - q->bytes_per_frame = avctx->block_align; - - /* Take care of the codec-specific extradata. */ - if (avctx->extradata_size == 14) { - /* Parse the extradata, WAV format */ - av_log(avctx,AV_LOG_DEBUG,"[0-1] %d\n",bytestream_get_le16(&edata_ptr)); //Unknown value always 1 - q->samples_per_channel = bytestream_get_le32(&edata_ptr); - q->codingMode = bytestream_get_le16(&edata_ptr); - av_log(avctx,AV_LOG_DEBUG,"[8-9] %d\n",bytestream_get_le16(&edata_ptr)); //Dupe of coding mode - q->frame_factor = bytestream_get_le16(&edata_ptr); //Unknown always 1 - av_log(avctx,AV_LOG_DEBUG,"[12-13] %d\n",bytestream_get_le16(&edata_ptr)); //Unknown always 0 - - /* setup */ - q->samples_per_frame = 1024 * q->channels; - q->atrac3version = 4; - q->delay = 0x88E; - if (q->codingMode) - q->codingMode = JOINT_STEREO; - else - q->codingMode = STEREO; - - q->scrambled_stream = 0; - - if ((q->bytes_per_frame == 96*q->channels*q->frame_factor) || (q->bytes_per_frame == 152*q->channels*q->frame_factor) || (q->bytes_per_frame == 192*q->channels*q->frame_factor)) { - } else { - av_log(avctx,AV_LOG_ERROR,"Unknown frame/channel/frame_factor configuration %d/%d/%d\n", q->bytes_per_frame, q->channels, q->frame_factor); - return -1; - } - - } else if (avctx->extradata_size == 10) { - /* Parse the extradata, RM format. */ - q->atrac3version = bytestream_get_be32(&edata_ptr); - q->samples_per_frame = bytestream_get_be16(&edata_ptr); - q->delay = bytestream_get_be16(&edata_ptr); - q->codingMode = bytestream_get_be16(&edata_ptr); - - q->samples_per_channel = q->samples_per_frame / q->channels; - q->scrambled_stream = 1; - - } else { - av_log(NULL,AV_LOG_ERROR,"Unknown extradata size %d.\n",avctx->extradata_size); - } - /* Check the extradata. */ - - if (q->atrac3version != 4) { - av_log(avctx,AV_LOG_ERROR,"Version %d != 4.\n",q->atrac3version); - return -1; - } - - if (q->samples_per_frame != 1024 && q->samples_per_frame != 2048) { - av_log(avctx,AV_LOG_ERROR,"Unknown amount of samples per frame %d.\n",q->samples_per_frame); - return -1; - } - - if (q->delay != 0x88E) { - av_log(avctx,AV_LOG_ERROR,"Unknown amount of delay %x != 0x88E.\n",q->delay); - return -1; - } - - if (q->codingMode == STEREO) { - av_log(avctx,AV_LOG_DEBUG,"Normal stereo detected.\n"); - } else if (q->codingMode == JOINT_STEREO) { - av_log(avctx,AV_LOG_DEBUG,"Joint stereo detected.\n"); - } else { - av_log(avctx,AV_LOG_ERROR,"Unknown channel coding mode %x!\n",q->codingMode); - return -1; - } - - if (avctx->channels <= 0 || avctx->channels > 2 /*|| ((avctx->channels * 1024) != q->samples_per_frame)*/) { - av_log(avctx,AV_LOG_ERROR,"Channel configuration error!\n"); - return -1; - } - - - if(avctx->block_align >= UINT_MAX/2) - return -1; - - /* Pad the data buffer with FF_INPUT_BUFFER_PADDING_SIZE, - * this is for the bitstream reader. */ - if ((q->decoded_bytes_buffer = av_mallocz((avctx->block_align+(4-avctx->block_align%4) + FF_INPUT_BUFFER_PADDING_SIZE))) == NULL) - return AVERROR(ENOMEM); - - - /* Initialize the VLC tables. */ - if (!vlcs_initialized) { - for (i=0 ; i<7 ; i++) { - spectral_coeff_tab[i].table = &atrac3_vlc_table[atrac3_vlc_offs[i]]; - spectral_coeff_tab[i].table_allocated = atrac3_vlc_offs[i + 1] - atrac3_vlc_offs[i]; - init_vlc (&spectral_coeff_tab[i], 9, huff_tab_sizes[i], - huff_bits[i], 1, 1, - huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - vlcs_initialized = 1; - } - - init_atrac3_transforms(q); - - atrac_generate_tables(); - - /* Generate gain tables. */ - for (i=0 ; i<16 ; i++) - gain_tab1[i] = powf (2.0, (4 - i)); - - for (i=-15 ; i<16 ; i++) - gain_tab2[i+15] = powf (2.0, i * -0.125); - - /* init the joint-stereo decoding data */ - q->weighting_delay[0] = 0; - q->weighting_delay[1] = 7; - q->weighting_delay[2] = 0; - q->weighting_delay[3] = 7; - q->weighting_delay[4] = 0; - q->weighting_delay[5] = 7; - - for (i=0; i<4; i++) { - q->matrix_coeff_index_prev[i] = 3; - q->matrix_coeff_index_now[i] = 3; - q->matrix_coeff_index_next[i] = 3; - } - - dsputil_init(&dsp, avctx); - - q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels); - if (!q->pUnits) { - av_free(q->decoded_bytes_buffer); - return AVERROR(ENOMEM); - } - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - - -AVCodec atrac3_decoder = -{ - .name = "atrac3", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_ATRAC3, - .priv_data_size = sizeof(ATRAC3Context), - .init = atrac3_decode_init, - .close = atrac3_decode_close, - .decode = atrac3_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/atrac3data.h b/tizen/distrib/ffmpeg/libavcodec/atrac3data.h deleted file mode 100644 index b5aa71f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/atrac3data.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Atrac 3 compatible decoder data - * Copyright (c) 2006-2007 Maxim Poliakovski - * Copyright (c) 2006-2007 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Atrac 3 AKA RealAudio 8 compatible decoder data - */ - -#ifndef AVCODEC_ATRAC3DATA_H -#define AVCODEC_ATRAC3DATA_H - -#include - -/* VLC tables */ - -static const uint8_t huffcode1[9] = { - 0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F, -}; - -static const uint8_t huffbits1[9] = { - 1,3,3,4,4,5,5,5,5, -}; - -static const uint8_t huffcode2[5] = { - 0x0,0x4,0x5,0x6,0x7, -}; - -static const uint8_t huffbits2[5] = { - 1,3,3,3,3, -}; - -static const uint8_t huffcode3[7] = { -0x0,0x4,0x5,0xC,0xD,0xE,0xF, -}; - -static const uint8_t huffbits3[7] = { - 1,3,3,4,4,4,4, -}; - -static const uint8_t huffcode4[9] = { - 0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F, -}; - -static const uint8_t huffbits4[9] = { - 1,3,3,4,4,5,5,5,5, -}; - -static const uint8_t huffcode5[15] = { - 0x0,0x2,0x3,0x8,0x9,0xA,0xB,0x1C,0x1D,0x3C,0x3D,0x3E,0x3F,0xC,0xD, -}; - -static const uint8_t huffbits5[15] = { - 2,3,3,4,4,4,4,5,5,6,6,6,6,4,4 -}; - -static const uint8_t huffcode6[31] = { - 0x0,0x2,0x3,0x4,0x5,0x6,0x7,0x14,0x15,0x16,0x17,0x18,0x19,0x34,0x35, - 0x36,0x37,0x38,0x39,0x3A,0x3B,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x8,0x9, -}; - -static const uint8_t huffbits6[31] = { - 3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,4,4 -}; - -static const uint8_t huffcode7[63] = { - 0x0,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,0x10,0x11,0x24,0x25,0x26,0x27,0x28, - 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x68,0x69,0x6A,0x6B,0x6C, - 0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2, - 0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x2,0x3, -}; - -static const uint8_t huffbits7[63] = { - 3,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,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,4 -}; - -static const uint8_t huff_tab_sizes[7] = { - 9, 5, 7, 9, 15, 31, 63, -}; - -static const uint8_t* const huff_codes[7] = { - huffcode1,huffcode2,huffcode3,huffcode4,huffcode5,huffcode6,huffcode7, -}; - -static const uint8_t* const huff_bits[7] = { - huffbits1,huffbits2,huffbits3,huffbits4,huffbits5,huffbits6,huffbits7, -}; - -static const uint16_t atrac3_vlc_offs[] = { - 0,512,1024,1536,2048,2560,3072,3584,4096 -}; - -/* selector tables */ - -static const uint8_t CLCLengthTab[8] = {0, 4, 3, 3, 4, 4, 5, 6}; -static const int8_t seTab_0[4] = {0, 1, -2, -1}; -static const int8_t decTable1[18] = {0,0, 0,1, 0,-1, 1,0, -1,0, 1,1, 1,-1, -1,1, -1,-1}; - - -/* tables for the scalefactor decoding */ - -static const float iMaxQuant[8] = { - 0.0, 1.0/1.5, 1.0/2.5, 1.0/3.5, 1.0/4.5, 1.0/7.5, 1.0/15.5, 1.0/31.5 -}; - -static const uint16_t subbandTab[33] = { - 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, - 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024 -}; - -/* joint stereo related tables */ -static const float matrixCoeffs[8] = {0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0}; - -#endif /* AVCODEC_ATRAC3DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/audioconvert.c b/tizen/distrib/ffmpeg/libavcodec/audioconvert.c deleted file mode 100644 index d022bc9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/audioconvert.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * audio conversion - * Copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio conversion - * @author Michael Niedermayer - */ - -#include "libavutil/avstring.h" -#include "libavutil/libm.h" -#include "avcodec.h" -#include "audioconvert.h" - -typedef struct SampleFmtInfo { - const char *name; - int bits; -} SampleFmtInfo; - -/** this table gives more information about formats */ -static const SampleFmtInfo sample_fmt_info[SAMPLE_FMT_NB] = { - [SAMPLE_FMT_U8] = { .name = "u8", .bits = 8 }, - [SAMPLE_FMT_S16] = { .name = "s16", .bits = 16 }, - [SAMPLE_FMT_S32] = { .name = "s32", .bits = 32 }, - [SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32 }, - [SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64 }, -}; - -const char *avcodec_get_sample_fmt_name(int sample_fmt) -{ - if (sample_fmt < 0 || sample_fmt >= SAMPLE_FMT_NB) - return NULL; - return sample_fmt_info[sample_fmt].name; -} - -enum SampleFormat avcodec_get_sample_fmt(const char* name) -{ - int i; - - for (i=0; i < SAMPLE_FMT_NB; i++) - if (!strcmp(sample_fmt_info[i].name, name)) - return i; - return SAMPLE_FMT_NONE; -} - -void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt) -{ - /* print header */ - if (sample_fmt < 0) - snprintf (buf, buf_size, "name " " depth"); - else if (sample_fmt < SAMPLE_FMT_NB) { - SampleFmtInfo info= sample_fmt_info[sample_fmt]; - snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits); - } -} - -static const char* const channel_names[]={ - "FL", "FR", "FC", "LFE", "BL", "BR", "FLC", "FRC", - "BC", "SL", "SR", "TC", "TFL", "TFC", "TFR", "TBL", - "TBC", "TBR", - [29] = "DL", - [30] = "DR", -}; - -static const char *get_channel_name(int channel_id) -{ - if (channel_id<0 || channel_id>=FF_ARRAY_ELEMS(channel_names)) - return NULL; - return channel_names[channel_id]; -} - -int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name) -{ - switch(nb_channels) { - case 1: return CH_LAYOUT_MONO; - case 2: return CH_LAYOUT_STEREO; - case 3: return CH_LAYOUT_SURROUND; - case 4: return CH_LAYOUT_QUAD; - case 5: return CH_LAYOUT_5POINT0; - case 6: return CH_LAYOUT_5POINT1; - case 8: return CH_LAYOUT_7POINT1; - default: return 0; - } -} - -static const struct { - const char *name; - int nb_channels; - int64_t layout; -} channel_layout_map[] = { - { "mono", 1, CH_LAYOUT_MONO }, - { "stereo", 2, CH_LAYOUT_STEREO }, - { "4.0", 4, CH_LAYOUT_4POINT0 }, - { "quad", 4, CH_LAYOUT_QUAD }, - { "5.0", 5, CH_LAYOUT_5POINT0 }, - { "5.0", 5, CH_LAYOUT_5POINT0_BACK }, - { "5.1", 6, CH_LAYOUT_5POINT1 }, - { "5.1", 6, CH_LAYOUT_5POINT1_BACK }, - { "5.1+downmix", 8, CH_LAYOUT_5POINT1|CH_LAYOUT_STEREO_DOWNMIX, }, - { "7.1", 8, CH_LAYOUT_7POINT1 }, - { "7.1(wide)", 8, CH_LAYOUT_7POINT1_WIDE }, - { "7.1+downmix", 10, CH_LAYOUT_7POINT1|CH_LAYOUT_STEREO_DOWNMIX, }, - { 0 } -}; - -void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout) -{ - int i; - - for (i=0; channel_layout_map[i].name; i++) - if (nb_channels == channel_layout_map[i].nb_channels && - channel_layout == channel_layout_map[i].layout) { - av_strlcpy(buf, channel_layout_map[i].name, buf_size); - return; - } - - snprintf(buf, buf_size, "%d channels", nb_channels); - if (channel_layout) { - int i,ch; - av_strlcat(buf, " (", buf_size); - for(i=0,ch=0; i<64; i++) { - if ((channel_layout & (1L<0) av_strlcat(buf, "|", buf_size); - av_strlcat(buf, name, buf_size); - } - ch++; - } - } - av_strlcat(buf, ")", buf_size); - } -} - -int avcodec_channel_layout_num_channels(int64_t channel_layout) -{ - int count; - uint64_t x = channel_layout; - for (count = 0; x; count++) - x &= x-1; // unset lowest set bit - return count; -} - -struct AVAudioConvert { - int in_channels, out_channels; - int fmt_pair; -}; - -AVAudioConvert *av_audio_convert_alloc(enum SampleFormat out_fmt, int out_channels, - enum SampleFormat in_fmt, int in_channels, - const float *matrix, int flags) -{ - AVAudioConvert *ctx; - if (in_channels!=out_channels) - return NULL; /* FIXME: not supported */ - ctx = av_malloc(sizeof(AVAudioConvert)); - if (!ctx) - return NULL; - ctx->in_channels = in_channels; - ctx->out_channels = out_channels; - ctx->fmt_pair = out_fmt + SAMPLE_FMT_NB*in_fmt; - return ctx; -} - -void av_audio_convert_free(AVAudioConvert *ctx) -{ - av_free(ctx); -} - -int av_audio_convert(AVAudioConvert *ctx, - void * const out[6], const int out_stride[6], - const void * const in[6], const int in_stride[6], int len) -{ - int ch; - - //FIXME optimize common cases - - for(ch=0; chout_channels; ch++){ - const int is= in_stride[ch]; - const int os= out_stride[ch]; - const uint8_t *pi= in[ch]; - uint8_t *po= out[ch]; - uint8_t *end= po + os*len; - if(!out[ch]) - continue; - -#define CONV(ofmt, otype, ifmt, expr)\ -if(ctx->fmt_pair == ofmt + SAMPLE_FMT_NB*ifmt){\ - do{\ - *(otype*)po = expr; pi += is; po += os;\ - }while(po < end);\ -} - -//FIXME put things below under ifdefs so we do not waste space for cases no codec will need -//FIXME rounding ? - - CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_U8 , *(const uint8_t*)pi) - else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8) - else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24) - else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) - else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) - else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) - else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S16, *(const int16_t*)pi) - else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S16, *(const int16_t*)pi<<16) - else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) - else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) - else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80) - else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S32, *(const int32_t*)pi>>16) - else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S32, *(const int32_t*)pi) - else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31))) - else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31))) - else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80)) - else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15)))) - else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31)))) - else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_FLT, *(const float*)pi) - else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_FLT, *(const float*)pi) - else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80)) - else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15)))) - else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31)))) - else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_DBL, *(const double*)pi) - else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_DBL, *(const double*)pi) - else return -1; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/audioconvert.h b/tizen/distrib/ffmpeg/libavcodec/audioconvert.h deleted file mode 100644 index 81b6cde..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/audioconvert.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * audio conversion - * Copyright (c) 2006 Michael Niedermayer - * Copyright (c) 2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AUDIOCONVERT_H -#define AVCODEC_AUDIOCONVERT_H - -/** - * @file - * Audio format conversion routines - */ - - -#include "avcodec.h" - - -/** - * Generate string corresponding to the sample format with - * number sample_fmt, or a header if sample_fmt is negative. - * - * @param[in] buf the buffer where to write the string - * @param[in] buf_size the size of buf - * @param[in] sample_fmt the number of the sample format to print the corresponding info string, or - * a negative value to print the corresponding header. - * Meaningful values for obtaining a sample format info vary from 0 to SAMPLE_FMT_NB -1. - */ -void avcodec_sample_fmt_string(char *buf, int buf_size, int sample_fmt); - -/** - * @return NULL on error - */ -const char *avcodec_get_sample_fmt_name(int sample_fmt); - -/** - * @return SAMPLE_FMT_NONE on error - */ -enum SampleFormat avcodec_get_sample_fmt(const char* name); - -/** - * @return NULL on error - */ -const char *avcodec_get_channel_name(int channel_id); - -/** - * Return description of channel layout - */ -void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout); - -/** - * Guess the channel layout - * @param nb_channels - * @param codec_id Codec identifier, or CODEC_ID_NONE if unknown - * @param fmt_name Format name, or NULL if unknown - * @return Channel layout mask - */ -int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name); - -/** - * @return the number of channels in the channel layout. - */ -int avcodec_channel_layout_num_channels(int64_t channel_layout); - -struct AVAudioConvert; -typedef struct AVAudioConvert AVAudioConvert; - -/** - * Create an audio sample format converter context - * @param out_fmt Output sample format - * @param out_channels Number of output channels - * @param in_fmt Input sample format - * @param in_channels Number of input channels - * @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore. - * @param flags See FF_MM_xx - * @return NULL on error - */ -AVAudioConvert *av_audio_convert_alloc(enum SampleFormat out_fmt, int out_channels, - enum SampleFormat in_fmt, int in_channels, - const float *matrix, int flags); - -/** - * Free audio sample format converter context - */ -void av_audio_convert_free(AVAudioConvert *ctx); - -/** - * Convert between audio sample formats - * @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel. - * @param[in] out_stride distance between consecutive output samples (measured in bytes) - * @param[in] in array of input buffers for each channel - * @param[in] in_stride distance between consecutive input samples (measured in bytes) - * @param len length of audio frame size (measured in samples) - */ -int av_audio_convert(AVAudioConvert *ctx, - void * const out[6], const int out_stride[6], - const void * const in[6], const int in_stride[6], int len); - -#endif /* AVCODEC_AUDIOCONVERT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/aura.c b/tizen/distrib/ffmpeg/libavcodec/aura.c deleted file mode 100644 index 8942cdd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/aura.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Aura 2 decoder - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Aura 2 decoder - */ - -#include "avcodec.h" - -typedef struct AuraDecodeContext { - AVCodecContext *avctx; - AVFrame frame; -} AuraDecodeContext; - -static av_cold int aura_decode_init(AVCodecContext *avctx) -{ - AuraDecodeContext *s = avctx->priv_data; - - s->avctx = avctx; - /* width needs to be divisible by 4 for this codec to work */ - if (avctx->width & 0x3) - return -1; - avctx->pix_fmt = PIX_FMT_YUV422P; - - return 0; -} - -static int aura_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *pkt) -{ - AuraDecodeContext *s=avctx->priv_data; - - uint8_t *Y, *U, *V; - uint8_t val; - int x, y; - const uint8_t *buf = pkt->data; - - /* prediction error tables (make it clear that they are signed values) */ - const int8_t *delta_table = (const int8_t*)buf + 16; - - if (pkt->size != 48 + avctx->height * avctx->width) { - av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n", - pkt->size, 48 + avctx->height * avctx->width); - return -1; - } - - /* pixel data starts 48 bytes in, after 3x16-byte tables */ - buf += 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 = s->frame.data[0]; - U = s->frame.data[1]; - V = s->frame.data[2]; - - /* iterate through each line in the height */ - for (y = 0; y < avctx->height; y++) { - /* reset predictors */ - val = *buf++; - U[0] = val & 0xF0; - Y[0] = val << 4; - val = *buf++; - V[0] = val & 0xF0; - Y[1] = Y[0] + delta_table[val & 0xF]; - Y += 2; U++; V++; - - /* iterate through the remaining pixel groups (4 pixels/group) */ - for (x = 1; x < (avctx->width >> 1); x++) { - val = *buf++; - U[0] = U[-1] + delta_table[val >> 4]; - Y[0] = Y[-1] + delta_table[val & 0xF]; - val = *buf++; - V[0] = V[-1] + delta_table[val >> 4]; - Y[1] = Y[ 0] + delta_table[val & 0xF]; - Y += 2; U++; V++; - } - Y += s->frame.linesize[0] - avctx->width; - U += s->frame.linesize[1] - (avctx->width >> 1); - V += s->frame.linesize[2] - (avctx->width >> 1); - } - - *data_size=sizeof(AVFrame); - *(AVFrame*)data= s->frame; - - return pkt->size; -} - -static av_cold int aura_decode_end(AVCodecContext *avctx) -{ - AuraDecodeContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec aura2_decoder = { - "aura2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_AURA2, - sizeof(AuraDecodeContext), - aura_decode_init, - NULL, - aura_decode_end, - aura_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/avcodec.h b/tizen/distrib/ffmpeg/libavcodec/avcodec.h deleted file mode 100644 index 71a6a13..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/avcodec.h +++ /dev/null @@ -1,4021 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AVCODEC_H -#define AVCODEC_AVCODEC_H - -/** - * @file - * external API header - */ - -#include -#include "libavutil/avutil.h" - -#define LIBAVCODEC_VERSION_MAJOR 52 -#define LIBAVCODEC_VERSION_MINOR 72 -#define LIBAVCODEC_VERSION_MICRO 2 - -#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, \ - LIBAVCODEC_VERSION_MICRO) -#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ - LIBAVCODEC_VERSION_MINOR, \ - LIBAVCODEC_VERSION_MICRO) -#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT - -#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) - -#define AV_NOPTS_VALUE INT64_C(0x8000000000000000) -#define AV_TIME_BASE 1000000 -#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} - -/** - * Identifies the syntax and semantics of the bitstream. - * The principle is roughly: - * Two decoders with the same ID can decode the same streams. - * Two encoders with the same ID can encode compatible streams. - * There may be slight deviations from the principle due to implementation - * details. - * - * If you add a codec ID to this list, add it so that - * 1. no value of a existing codec ID changes (that would break ABI), - * 2. it is as close as possible to similar codecs. - */ -enum CodecID { - CODEC_ID_NONE, - - /* video codecs */ - CODEC_ID_MPEG1VIDEO, - CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video 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, -#if LIBAVCODEC_VERSION_MAJOR < 53 - CODEC_ID_XVID, -#endif - 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_VC1, - 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, - CODEC_ID_FLASHSV, - CODEC_ID_CAVS, - CODEC_ID_JPEG2000, - CODEC_ID_VMNC, - CODEC_ID_VP5, - CODEC_ID_VP6, - CODEC_ID_VP6F, - CODEC_ID_TARGA, - CODEC_ID_DSICINVIDEO, - CODEC_ID_TIERTEXSEQVIDEO, - CODEC_ID_TIFF, - CODEC_ID_GIF, - CODEC_ID_FFH264, - CODEC_ID_DXA, - CODEC_ID_DNXHD, - CODEC_ID_THP, - CODEC_ID_SGI, - CODEC_ID_C93, - CODEC_ID_BETHSOFTVID, - CODEC_ID_PTX, - CODEC_ID_TXD, - CODEC_ID_VP6A, - CODEC_ID_AMV, - CODEC_ID_VB, - CODEC_ID_PCX, - CODEC_ID_SUNRAST, - CODEC_ID_INDEO4, - CODEC_ID_INDEO5, - CODEC_ID_MIMIC, - CODEC_ID_RL2, - CODEC_ID_8SVX_EXP, - CODEC_ID_8SVX_FIB, - CODEC_ID_ESCAPE124, - CODEC_ID_DIRAC, - CODEC_ID_BFI, - CODEC_ID_CMV, - CODEC_ID_MOTIONPIXELS, - CODEC_ID_TGV, - CODEC_ID_TGQ, - CODEC_ID_TQI, - CODEC_ID_AURA, - CODEC_ID_AURA2, - CODEC_ID_V210X, - CODEC_ID_TMV, - CODEC_ID_V210, - CODEC_ID_DPX, - CODEC_ID_MAD, - CODEC_ID_FRWU, - CODEC_ID_FLASHSV2, - CODEC_ID_CDGRAPHICS, - CODEC_ID_R210, - CODEC_ID_ANM, - CODEC_ID_BINKVIDEO, - CODEC_ID_IFF_ILBM, - CODEC_ID_IFF_BYTERUN1, - CODEC_ID_KGV1, - CODEC_ID_YOP, - CODEC_ID_VP8, - - /* 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, - CODEC_ID_PCM_ZORK, - CODEC_ID_PCM_S16LE_PLANAR, - CODEC_ID_PCM_DVD, - CODEC_ID_PCM_F32BE, - CODEC_ID_PCM_F32LE, - CODEC_ID_PCM_F64BE, - CODEC_ID_PCM_F64LE, - CODEC_ID_PCM_BLURAY, - - /* 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, - CODEC_ID_ADPCM_THP, - CODEC_ID_ADPCM_IMA_AMV, - CODEC_ID_ADPCM_EA_R1, - CODEC_ID_ADPCM_EA_R3, - CODEC_ID_ADPCM_EA_R2, - CODEC_ID_ADPCM_IMA_EA_SEAD, - CODEC_ID_ADPCM_IMA_EA_EACS, - CODEC_ID_ADPCM_EA_XAS, - CODEC_ID_ADPCM_EA_MAXIS_XA, - CODEC_ID_ADPCM_IMA_ISS, - - /* 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, - - /* audio codecs */ - CODEC_ID_MP2= 0x15000, - CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 - CODEC_ID_AAC, - 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, ///< as in Berlin toast format - CODEC_ID_QDM2, - CODEC_ID_COOK, - CODEC_ID_TRUESPEECH, - CODEC_ID_TTA, - CODEC_ID_SMACKAUDIO, - CODEC_ID_QCELP, - CODEC_ID_WAVPACK, - CODEC_ID_DSICINAUDIO, - CODEC_ID_IMC, - CODEC_ID_MUSEPACK7, - CODEC_ID_MLP, - CODEC_ID_GSM_MS, /* as found in WAV */ - CODEC_ID_ATRAC3, - CODEC_ID_VOXWARE, - CODEC_ID_APE, - CODEC_ID_NELLYMOSER, - CODEC_ID_MUSEPACK8, - CODEC_ID_SPEEX, - CODEC_ID_WMAVOICE, - CODEC_ID_WMAPRO, - CODEC_ID_WMALOSSLESS, - CODEC_ID_ATRAC3P, - CODEC_ID_EAC3, - CODEC_ID_SIPR, - CODEC_ID_MP1, - CODEC_ID_TWINVQ, - CODEC_ID_TRUEHD, - CODEC_ID_MP4ALS, - CODEC_ID_ATRAC1, - CODEC_ID_BINKAUDIO_RDFT, - CODEC_ID_BINKAUDIO_DCT, - - /* subtitle codecs */ - CODEC_ID_DVD_SUBTITLE= 0x17000, - CODEC_ID_DVB_SUBTITLE, - CODEC_ID_TEXT, ///< raw UTF-8 text - CODEC_ID_XSUB, - CODEC_ID_SSA, - CODEC_ID_MOV_TEXT, - CODEC_ID_HDMV_PGS_SUBTITLE, - CODEC_ID_DVB_TELETEXT, - - /* other specific kind of codecs (generally used for attachments) */ - CODEC_ID_TTF= 0x18000, - - CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it - - CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS - * stream (only used by libavformat) */ -}; - -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define CodecType AVMediaType - -#define CODEC_TYPE_UNKNOWN AVMEDIA_TYPE_UNKNOWN -#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO -#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO -#define CODEC_TYPE_DATA AVMEDIA_TYPE_DATA -#define CODEC_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE -#define CODEC_TYPE_ATTACHMENT AVMEDIA_TYPE_ATTACHMENT -#define CODEC_TYPE_NB AVMEDIA_TYPE_NB -#endif - -/** - * all in native-endian format - */ -enum SampleFormat { - SAMPLE_FMT_NONE = -1, - SAMPLE_FMT_U8, ///< unsigned 8 bits - SAMPLE_FMT_S16, ///< signed 16 bits - SAMPLE_FMT_S32, ///< signed 32 bits - SAMPLE_FMT_FLT, ///< float - SAMPLE_FMT_DBL, ///< double - SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec -}; - -/* Audio channel masks */ -#define CH_FRONT_LEFT 0x00000001 -#define CH_FRONT_RIGHT 0x00000002 -#define CH_FRONT_CENTER 0x00000004 -#define CH_LOW_FREQUENCY 0x00000008 -#define CH_BACK_LEFT 0x00000010 -#define CH_BACK_RIGHT 0x00000020 -#define CH_FRONT_LEFT_OF_CENTER 0x00000040 -#define CH_FRONT_RIGHT_OF_CENTER 0x00000080 -#define CH_BACK_CENTER 0x00000100 -#define CH_SIDE_LEFT 0x00000200 -#define CH_SIDE_RIGHT 0x00000400 -#define CH_TOP_CENTER 0x00000800 -#define CH_TOP_FRONT_LEFT 0x00001000 -#define CH_TOP_FRONT_CENTER 0x00002000 -#define CH_TOP_FRONT_RIGHT 0x00004000 -#define CH_TOP_BACK_LEFT 0x00008000 -#define CH_TOP_BACK_CENTER 0x00010000 -#define CH_TOP_BACK_RIGHT 0x00020000 -#define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. -#define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT. - -/** Channel mask value used for AVCodecContext.request_channel_layout - to indicate that the user requests the channel order of the decoder output - to be the native codec channel order. */ -#define CH_LAYOUT_NATIVE 0x8000000000000000LL - -/* Audio channel convenience macros */ -#define CH_LAYOUT_MONO (CH_FRONT_CENTER) -#define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT) -#define CH_LAYOUT_2_1 (CH_LAYOUT_STEREO|CH_BACK_CENTER) -#define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER) -#define CH_LAYOUT_4POINT0 (CH_LAYOUT_SURROUND|CH_BACK_CENTER) -#define CH_LAYOUT_2_2 (CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT) -#define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT) -#define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY) -#define CH_LAYOUT_5POINT0_BACK (CH_LAYOUT_SURROUND|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_5POINT1_BACK (CH_LAYOUT_5POINT0_BACK|CH_LOW_FREQUENCY) -#define CH_LAYOUT_7POINT0 (CH_LAYOUT_5POINT0|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT) -#define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_5POINT1_BACK|\ - CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER) -#define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT) - -/* 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. - */ -enum Motion_Est_ID { - ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed - ME_FULL, - ME_LOG, - ME_PHODS, - ME_EPZS, ///< enhanced predictive zonal search - ME_X1, ///< reserved for experiments - ME_HEX, ///< hexagon based search - ME_UMH, ///< uneven multi-hexagon search - ME_ITER, ///< iterative search - ME_TESA, ///< transformed exhaustive search algorithm -}; - -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 -}; - -enum AVColorPrimaries{ - AVCOL_PRI_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B - AVCOL_PRI_UNSPECIFIED=2, - AVCOL_PRI_BT470M =4, - AVCOL_PRI_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM - AVCOL_PRI_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC - AVCOL_PRI_SMPTE240M =7, ///< functionally identical to above - AVCOL_PRI_FILM =8, - AVCOL_PRI_NB , ///< Not part of ABI -}; - -enum AVColorTransferCharacteristic{ - AVCOL_TRC_BT709 =1, ///< also ITU-R BT1361 - AVCOL_TRC_UNSPECIFIED=2, - AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM - AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG - AVCOL_TRC_NB , ///< Not part of ABI -}; - -enum AVColorSpace{ - AVCOL_SPC_RGB =0, - AVCOL_SPC_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B - AVCOL_SPC_UNSPECIFIED=2, - AVCOL_SPC_FCC =4, - AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 - AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above - AVCOL_SPC_SMPTE240M =7, - AVCOL_SPC_NB , ///< Not part of ABI -}; - -enum AVColorRange{ - AVCOL_RANGE_UNSPECIFIED=0, - AVCOL_RANGE_MPEG =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges - AVCOL_RANGE_JPEG =2, ///< the normal 2^n-1 "JPEG" YUV ranges - AVCOL_RANGE_NB , ///< Not part of ABI -}; - -/** - * X X 3 4 X X are luma samples, - * 1 2 1-6 are possible chroma positions - * X X 5 6 X 0 is undefined/unknown position - */ -enum AVChromaLocation{ - AVCHROMA_LOC_UNSPECIFIED=0, - AVCHROMA_LOC_LEFT =1, ///< mpeg2/4, h264 default - AVCHROMA_LOC_CENTER =2, ///< mpeg1, jpeg, h263 - AVCHROMA_LOC_TOPLEFT =3, ///< DV - AVCHROMA_LOC_TOP =4, - AVCHROMA_LOC_BOTTOMLEFT =5, - AVCHROMA_LOC_BOTTOM =6, - AVCHROMA_LOC_NB , ///< Not part of ABI -}; - -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; - -#define FF_MAX_B_FRAMES 16 - -/* encoding support - These flags can be passed in AVCodecContext.flags before initialization. - 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 H.263. -#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. -/** - * The parent program guarantees that the input for B-frames containing - * streams is not written to for at least s->max_b_frames+1 frames, if - * this is not set 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_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_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 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 ///< H.263 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 one reference per partition, as opposed to one reference per macroblock -#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 -#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table. -#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). -#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. -#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping -#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. -#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer. -#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible -#define CODEC_FLAG2_MBTREE 0x00040000 ///< Use macroblock tree ratecontrol (x264 only) -#define CODEC_FLAG2_PSY 0x00080000 ///< Use psycho visual optimizations. -#define CODEC_FLAG2_SSIM 0x00100000 ///< Compute SSIM during encoding, error[] values are undefined. - -/* Unsupported options : - * Syntax Arithmetic coding (SAC) - * Reference Picture Selection - * Independent 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 and supports custom allocators. - * If not set, it might not use get_buffer() at all or use operations that - * assume the buffer was allocated by avcodec_default_get_buffer. - */ -#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 nonzero delay and needs to be fed with NULL at the end to get the delayed data. - * If this is not set, the codec is guaranteed to never be fed with NULL data. - */ -#define CODEC_CAP_DELAY 0x0020 -/** - * Codec can be fed a final frame with a smaller size. - * This can be used to prevent truncation of the last audio samples. - */ -#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 -/** - * Codec can export data for HW decoding (VDPAU). - */ -#define CODEC_CAP_HWACCEL_VDPAU 0x0080 -/** - * Codec can output multiple frames per AVPacket - * Normally demuxers return one frame at a time, demuxers which do not do - * are connected to a parser to split what they return into proper frames. - * This flag is reserved to the very rare category of codecs which have a - * bitstream that cannot be split into frames without timeconsuming - * operations like full decoding. Demuxers carring such bitstreams thus - * may return multiple frames in a packet. This has many disadvantages like - * prohibiting stream copy in many cases thus it should only be considered - * as a last resort. - */ -#define CODEC_CAP_SUBFRAMES 0x0100 -/** - * Codec is experimental and is thus avoided in favor of non experimental - * encoders - */ -#define CODEC_CAP_EXPERIMENTAL 0x0200 - -//The following defines may change, don't expect compatibility if you use them. -#define MB_TYPE_INTRA4x4 0x0001 -#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific -#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-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 libavcodec. - */ - int id; - - /** - * width and height in 1/16 pel - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - 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 libavcodec. - */ - 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 libavcodec unless the default get/release_buffer() is used.\ - * - encoding: \ - * - decoding: \ - */\ - uint8_t *base[4];\ - /**\ - * 1 -> keyframe, 0-> not\ - * - encoding: Set by libavcodec.\ - * - decoding: Set by libavcodec.\ - */\ - int key_frame;\ -\ - /**\ - * Picture type of the frame, see ?_TYPE below.\ - * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ - * - decoding: Set by libavcodec.\ - */\ - 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 libavcodec.\ - */\ - int64_t pts;\ -\ - /**\ - * picture number in bitstream order\ - * - encoding: set by\ - * - decoding: Set by libavcodec.\ - */\ - int coded_picture_number;\ - /**\ - * picture number in display order\ - * - encoding: set by\ - * - decoding: Set by libavcodec.\ - */\ - int display_picture_number;\ -\ - /**\ - * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ - * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ - * - decoding: Set by libavcodec.\ - */\ - 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\ - * The values for this are the same as the MpegEncContext.picture_structure\ - * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\ - * Set to 4 for delayed, non-reference frames.\ - * - encoding: unused\ - * - decoding: Set by libavcodec. (before get_buffer() call)).\ - */\ - int reference;\ -\ - /**\ - * QP table\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - int8_t *qscale_table;\ - /**\ - * QP store stride\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - int qstride;\ -\ - /**\ - * mbskip_table[mb]>=1 if MB didn't change\ - * stride= mb_width = (width+15)>>4\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - 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 libavcodec.\ - */\ - int16_t (*motion_val[2])[2];\ -\ - /**\ - * macroblock type table\ - * mb_type_base + mb_width + 2\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - 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 libavcodec.\ - */\ - uint8_t motion_subsample_log2;\ -\ - /**\ - * for some private data of the user\ - * - encoding: unused\ - * - decoding: Set by user.\ - */\ - void *opaque;\ -\ - /* - * dummy variable for tizen in Windows. - */\ - int dummy_a;\ -\ - /**\ - * error\ - * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\ - * - decoding: unused\ - */\ - uint64_t error[4];\ -\ - /**\ - * type of the buffer (to keep track of who has to deallocate data[*])\ - * - encoding: Set by the one who allocates it.\ - * - decoding: Set by the one who allocates it.\ - * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\ - */\ - int type;\ - \ - /**\ - * When decoding, this signals how much the picture must be delayed.\ - * extra_delay = repeat_pict / (2*fps)\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - int repeat_pict;\ - \ - /**\ - * \ - */\ - int qscale_type;\ - \ - /**\ - * The content of the picture is interlaced.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec. (default 0)\ - */\ - int interlaced_frame;\ - \ - /**\ - * If the content is interlaced, is top field displayed first.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - int top_field_first;\ - \ - /**\ - * Pan scan.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - AVPanScan *pan_scan;\ - \ - /**\ - * Tell user application that palette has changed from previous frame.\ - * - encoding: ??? (no palette-enabled encoder yet)\ - * - decoding: Set by libavcodec. (default 0).\ - */\ - int palette_has_changed;\ - \ - /**\ - * codec suggestion on buffer type if != 0\ - * - encoding: unused\ - * - decoding: Set by libavcodec. (before get_buffer() call)).\ - */\ - int buffer_hints;\ -\ - /**\ - * DCT coefficients\ - * - encoding: unused\ - * - decoding: Set by libavcodec.\ - */\ - short *dct_coeff;\ -\ - /**\ - * motion reference frame index\ - * the order in which these are stored can depend on the codec.\ - * - encoding: Set by user.\ - * - decoding: Set by libavcodec.\ - */\ - int8_t *ref_index[2];\ -\ - /* - * dummy variable for tizen in Windows. - */\ - int dummy_b;\ -\ - /**\ - * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\ - * output in AVFrame.reordered_opaque\ - * - encoding: unused\ - * - decoding: Read by user.\ - */\ - int64_t reordered_opaque;\ -\ - /**\ - * hardware accelerator private data (FFmpeg allocated)\ - * - encoding: unused\ - * - decoding: Set by libavcodec\ - */\ - void *hwaccel_picture_private;\ -\ - /* - * dummy variable for tizen in Windows. - */\ - int dummy_c;\ - - -#define FF_QSCALE_TYPE_MPEG1 0 -#define FF_QSCALE_TYPE_MPEG2 1 -#define FF_QSCALE_TYPE_H264 2 -#define FF_QSCALE_TYPE_VP56 3 - -#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 deallocate 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 deallocate 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 ///< Switching Intra -#define FF_SP_TYPE 6 ///< Switching Predicted -#define FF_BI_TYPE 7 - -#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). - -typedef struct AVPacket { - /** - * Presentation timestamp in AVStream->time_base units; the time at which - * the decompressed packet will be presented to the user. - * Can be AV_NOPTS_VALUE if it is not stored in the file. - * pts MUST be larger or equal to dts as presentation cannot happen before - * decompression, unless one wants to view hex dumps. Some formats misuse - * the terms dts and pts/cts to mean something different. Such timestamps - * must be converted to true pts/dts before they are stored in AVPacket. - */ - int64_t pts; - /** - * Decompression timestamp in AVStream->time_base units; the time at which - * the packet is decompressed. - * Can be AV_NOPTS_VALUE if it is not stored in the file. - */ - int64_t dts; - uint8_t *data; - int size; - int stream_index; - int flags; - /** - * Duration of this packet in AVStream->time_base units, 0 if unknown. - * Equals next_pts - this_pts in presentation order. - */ - int duration; - void (*destruct)(struct AVPacket *); - void *priv; - int64_t pos; ///< byte position in stream, -1 if unknown - /* because of tizen */ - int is_mux; - - /** - * Time difference in AVStream->time_base units from the pts of this - * packet to the point at which the output from the decoder has converged - * independent from the availability of previous frames. That is, the - * frames are virtually identical no matter if decoding started from - * the very first frame or from this keyframe. - * Is AV_NOPTS_VALUE if unknown. - * This field is not the display duration of the current packet. - * - * The purpose of this field is to allow seeking in streams that have no - * keyframes in the conventional sense. It corresponds to the - * recovery point SEI in H.264 and match_time_delta in NUT. It is also - * essential for some types of subtitle streams to ensure that all - * subtitles are correctly displayed after seeking. - */ - int64_t convergence_duration; -} AVPacket; -#define AV_PKT_FLAG_KEY 0x0001 -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define PKT_FLAG_KEY AV_PKT_FLAG_KEY -#endif - -/** - * Audio Video Frame. - * New fields can be added to the end of FF_COMMON_FRAME with minor version - * bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. No fields should be added into AVFrame before or after - * FF_COMMON_FRAME! - * sizeof(AVFrame) must not be used outside libav*. - */ -typedef struct AVFrame { - FF_COMMON_FRAME -} AVFrame; - -/** - * main external API structure. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVCodecContext) must not be used outside libav*. - */ -typedef struct AVCodecContext { - /** - * information on struct for av_log - * - set by avcodec_alloc_context - */ - const AVClass *av_class; - /** - * the average bitrate - * - encoding: Set by user; unused for constant quantizer encoding. - * - decoding: Set by libavcodec. 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 need additional format info. It is stored here. - * If any muxer uses this then ALL demuxers/parsers AND encoders for the - * specific codec MUST set it correctly otherwise stream copy breaks. - * In general use of this field by muxers is not recommanded. - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. (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), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific] - * - encoding: MUST be set by user. - * - decoding: unused - */ - int me_method; - - /** - * some codecs need / can use extradata 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 - * than extradata_size to avoid prolems if it is read with the bitstream reader. - * The bytewise contents of extradata must not depend on the architecture or CPU endianness. - * - encoding: Set/allocated/freed by libavcodec. - * - decoding: Set/allocated/freed by user. - */ - uint8_t *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 libavcodec. - */ - AVRational time_base; - - /* video only */ - /** - * picture width / height. - * - encoding: MUST be set by user. - * - decoding: Set by libavcodec. - * Note: For compatibility it is 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 pictures, 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 libavcodec. - */ - enum PixelFormat pix_fmt; - - /** - * Frame rate emulation. If not zero, the 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 a horizontal band. It improves cache usage. Not - * all codecs can do that. You must check the codec capabilities - * beforehand. - * The function is also used by hardware acceleration APIs. - * It is called at least once during frame decoding to pass - * the data needed for hardware render. - * In that mode instead of pixel data, AVFrame points to - * a structure specific to the acceleration API. The application - * reads the structure and can change some fields to indicate progress - * or mark state. - * - 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 second - int channels; ///< number of audio channels - - /** - * audio sample format - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - enum SampleFormat sample_fmt; ///< sample format - - /* 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 - - /* add i_frame_number and stts_count because of tizen emulator */ - int i_frame_number; - int stts_count; - -#if LIBAVCODEC_VERSION_MAJOR < 53 - int real_pict_num; ///< Returns the real picture number of previous encoded frame. -#endif - - /** - * Number of frames the decoded output will be delayed relative to - * the encoded input. - * - encoding: Set by libavcodec. - * - 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 between 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 - * 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_factor; - - /** obsolete FIXME remove */ - int rc_strategy; -#define FF_RC_STRATEGY_XVID 1 - - int b_frame_strategy; - - /** - * hurry up amount - * - encoding: unused - * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header - * @deprecated Deprecated in favor of skip_idct and skip_frame. - */ - int hurry_up; - - struct AVCodec *codec; - - void *priv_data; - - int rtp_payload_size; /* The size of the RTP payload: the coder will */ - /* do its 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 transmitted RTP payload. */ - - - /* The RTP callback: This function is called */ - /* every time the encoder has a packet to send. */ - /* It 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 libavcodec. - * - 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 AVMediaType codec_type; /* see AVMEDIA_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 work around some encoder bugs. - * A demuxer should set this to what is stored in the field used to identify the codec. - * If there are multiple such fields in a container then the demuxer should choose the one - * which maximizes the information about the used codec. - * If the codec tag field in a container is larger then 32 bits then the demuxer should - * remap the longer ID to 32 bits with a table or other structure. Alternatively a new - * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated - * first. - * - encoding: Set by user, if not then the default based on codec_id will be used. - * - decoding: Set by user, will be converted to uppercase by libavcodec during init. - */ - unsigned int codec_tag; - - /** - * Work around 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 ///< Work around various bugs in Microsoft's broken decoders. -#define FF_BUG_TRUNCATED 16384 -//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%. - - /** - * luma single coefficient 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 standard (MPEG4, ...). - * - encoding: Set by user. - * - decoding: Set by user. - * Setting this to STRICT or higher means the encoder and decoder will - * generally do stupid things. While setting it to inofficial or lower - * will mean the encoder might use things that are not supported by all - * spec compliant decoders. Decoders make no difference between normal, - * inofficial and experimental, that is they always try to decode things - * when they can unless they are explicitly asked to behave stupid - * (=strictly conform to the specs) - */ - 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 nonstandardized experimental things. - - /** - * qscale offset between IP and B-frames - * - encoding: Set by user. - * - decoding: unused - */ - float b_quant_offset; - - /** - * Error recognization; higher values will detect more errors but may - * misdetect some more or less valid parts as errors. - * - encoding: unused - * - decoding: Set by user. - */ - int error_recognition; -#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 libavcodec. - * avcodec_align_dimensions2() should be used to find the required width and - * height, as they normally need to be rounded up to the next multiple of 16. - * if CODEC_CAP_DR1 is not set then get_buffer() must call - * avcodec_default_get_buffer() instead of providing buffers allocated by - * some other means. - * - encoding: unused - * - decoding: Set by libavcodec., user can override. - */ - int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); - - /** - * Called to release buffers which were 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 libavcodec., user can override. - */ - void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); - - /** - * Size of the frame reordering buffer in the decoder. - * For MPEG-2 it is 1 IPB or 0 low delay IP. - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. - */ - 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 libavcodec. - * - 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 - */ - const 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; - - /** - * 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 -#define FF_IDCT_CAVS 15 -#define FF_IDCT_SIMPLEARMV5TE 16 -#define FF_IDCT_SIMPLEARMV6 17 -#define FF_IDCT_SIMPLEVIS 18 -#define FF_IDCT_WMV2 19 -#define FF_IDCT_FAAN 20 -#define FF_IDCT_EA 21 -#define FF_IDCT_SIMPLENEON 22 -#define FF_IDCT_SIMPLEALPHA 23 -#define FF_IDCT_BINK 24 - - /** - * slice count - * - encoding: Set by libavcodec. - * - decoding: Set by user (or 0). - */ - int slice_count; - /** - * slice offsets in the frame in bytes - * - encoding: Set/allocated by libavcodec. - * - 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 the 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 */ -#define FF_MM_MMX 0x0001 ///< standard MMX -#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext -#endif -#define FF_MM_MMX2 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 -#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions -#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions -#define FF_MM_SSE4 0x0100 ///< Penryn SSE4.1 functions -#define FF_MM_SSE42 0x0200 ///< Nehalem SSE4.2 functions -#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT -#define FF_MM_ALTIVEC 0x0001 ///< standard AltiVec - - /** - * bits per sample/pixel from the demuxer (needed for huffyuv). - * - encoding: Set by libavcodec. - * - decoding: Set by user. - */ - int bits_per_coded_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) - * That is the width of a pixel divided by the height of the pixel. - * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - AVRational sample_aspect_ratio; - - /** - * the picture in the bitstream - * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. - */ - 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 -#define FF_DEBUG_BUFFERS 0x00008000 - - /** - * 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 - - /* - * dummy variable for tizen in Windows. - */ - int dummy_a; - - /** - * error - * - encoding: Set by libavcodec 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 comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_cmp; - /** - * subpixel motion estimation comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_sub_cmp; - /** - * macroblock comparison function (not supported yet) - * - encoding: Set by user. - * - decoding: unused - */ - int mb_cmp; - /** - * interlaced DCT comparison 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; - - /** - * prepass for motion estimation - * - encoding: Set by user. - * - decoding: unused - */ - int pre_me; - - /** - * motion estimation prepass comparison function - * - encoding: Set by user. - * - decoding: unused - */ - int me_pre_cmp; - - /** - * ME prepass 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, - * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. - * The first is always the native one. - * @return the chosen format - * - encoding: unused - * - decoding: Set by user, if not set the native format will be chosen. - */ - enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); - - /** - * DTG active format information (additional aspect ratio - * information only used in DVB MPEG-2 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. - * Tables have to be stored somewhere. FIXME - */ - int color_table_id; - - /** - * internal_buffer count - * Don't touch, used by libavcodec default_get_buffer(). - */ - int internal_buffer_count; - - /** - * internal_buffers - * Don't touch, used by libavcodec 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 work around some encoder bugs. - * - encoding: unused - * - decoding: Set by user, will be converted to uppercase by libavcodec 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. libavcodec won't check it. - * libavcodec 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(). - * if CODEC_CAP_DR1 is not set then reget_buffer() must call - * avcodec_default_reget_buffer() instead of providing buffers allocated by - * some other means. - * - encoding: unused - * - decoding: Set by libavcodec., 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 independent 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 independent 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 libavcodec, user can override. - * - decoding: Set by libavcodec, user can override. - */ - int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); - - /** - * 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 below 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 below 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 libavcodec. - */ - int profile; -#define FF_PROFILE_UNKNOWN -99 - -#define FF_PROFILE_AAC_MAIN 0 -#define FF_PROFILE_AAC_LOW 1 -#define FF_PROFILE_AAC_SSR 2 -#define FF_PROFILE_AAC_LTP 3 - -#define FF_PROFILE_H264_BASELINE 66 -#define FF_PROFILE_H264_MAIN 77 -#define FF_PROFILE_H264_EXTENDED 88 -#define FF_PROFILE_H264_HIGH 100 -#define FF_PROFILE_H264_HIGH_10 110 -#define FF_PROFILE_H264_HIGH_422 122 -#define FF_PROFILE_H264_HIGH_444 244 -#define FF_PROFILE_H264_CAVLC_444 44 - - /** - * level - * - encoding: Set by user. - * - decoding: Set by libavcodec. - */ - 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; - - /** - * Bitstream 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 comparison 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 - */ - float 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: Set by lavc. - */ - 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 /* Analyze i4x4 */ -#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ -#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ -#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */ -#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */ - - /** - * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto) - * - encoding: Set by user. - * - decoding: unused - */ - int directpred; - - /** - * Audio cutoff bandwidth (0 means "automatic") - * - 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; - - /** - * - * Note: Value depends upon the compare function used for fullpel ME. - * - encoding: Set by user. - * - decoding: unused - */ - int mv0_threshold; - - /** - * Adjusts sensitivity of b_frame_strategy 1. - * - encoding: Set by user. - * - decoding: unused - */ - int b_sensitivity; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int compression_level; -#define FF_COMPRESSION_DEFAULT -1 - - /** - * Sets whether to use LPC mode - used by FLAC encoder. - * - encoding: Set by user. - * - decoding: unused - */ - int use_lpc; - - /** - * LPC coefficient precision - used by FLAC encoder - * - encoding: Set by user. - * - decoding: unused - */ - int lpc_coeff_precision; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int min_prediction_order; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int max_prediction_order; - - /** - * search method for selecting prediction order - * - encoding: Set by user. - * - decoding: unused - */ - int prediction_order_method; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int min_partition_order; - - /** - * - encoding: Set by user. - * - decoding: unused - */ - int max_partition_order; - - /** - * GOP timecode frame start number, in non drop frame format - * - encoding: Set by user. - * - decoding: unused - */ - int64_t timecode_frame_start; - -#if LIBAVCODEC_VERSION_MAJOR < 53 - /** - * Decoder should decode to this many channels if it can (0 for default) - * - encoding: unused - * - decoding: Set by user. - * @deprecated Deprecated in favor of request_channel_layout. - */ - int request_channels; -#endif - - /** - * Percentage of dynamic range compression to be applied by the decoder. - * The default value is 1.0, corresponding to full compression. - * - encoding: unused - * - decoding: Set by user. - */ - float drc_scale; - - /** - * opaque 64bit number (generally a PTS) that will be reordered and - * output in AVFrame.reordered_opaque - * - encoding: unused - * - decoding: Set by user. - */ - int64_t reordered_opaque; - - /** - * Bits per sample/pixel of internal libavcodec pixel/sample format. - * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. - * - encoding: set by user. - * - decoding: set by libavcodec. - */ - int bits_per_raw_sample; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_b; - - /** - * Audio channel layout. - * - encoding: set by user. - * - decoding: set by libavcodec. - */ - int64_t channel_layout; - - /** - * Request decoder to use this channel layout if it can (0 for default) - * - encoding: unused - * - decoding: Set by user. - */ - int64_t request_channel_layout; - - /** - * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. - * - encoding: Set by user. - * - decoding: unused. - */ - float rc_max_available_vbv_use; - - /** - * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. - * - encoding: Set by user. - * - decoding: unused. - */ - float rc_min_vbv_overflow_use; - - /** - * Hardware accelerator in use - * - encoding: unused. - * - decoding: Set by libavcodec - */ - struct AVHWAccel *hwaccel; - - /** - * For some codecs, the time base is closer to the field rate than the frame rate. - * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration - * if no telecine is used ... - * - * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. - */ - int ticks_per_frame; - - /** - * Hardware accelerator context. - * For some hardware accelerators, a global context needs to be - * provided by the user. In that case, this holds display-dependent - * data FFmpeg cannot instantiate itself. Please refer to the - * FFmpeg HW accelerator documentation to know how to fill this - * is. e.g. for VA API, this is a struct vaapi_context. - * - encoding: unused - * - decoding: Set by user - */ - void *hwaccel_context; - - /** - * Chromaticity coordinates of the source primaries. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorPrimaries color_primaries; - - /** - * Color Transfer Characteristic. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorTransferCharacteristic color_trc; - - /** - * YUV colorspace type. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorSpace colorspace; - - /** - * MPEG vs JPEG YUV range. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVColorRange color_range; - - /** - * This defines the location of chroma samples. - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - enum AVChromaLocation chroma_sample_location; - - /** - * The codec may call this to execute several independent 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. - * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. - * @param c context passed also to func - * @param count the number of things to execute - * @param arg2 argument passed unchanged to func - * @param ret return values of executed functions, must have space for "count" values. May be NULL. - * @param func function that will be called count times, with jobnr from 0 to count-1. - * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no - * two instances of func executing at the same time will have the same threadnr. - * @return always 0 currently, but code should handle a future improvement where when any call to func - * returns < 0 no further calls to func may be done and < 0 is returned. - * - encoding: Set by libavcodec, user can override. - * - decoding: Set by libavcodec, user can override. - */ - int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); - - /** - * explicit P-frame weighted prediction analysis method - * 0: off - * 1: fast blind weighting (one reference duplicate with -1 offset) - * 2: smart weighting (full fade detection analysis) - * - encoding: Set by user. - * - decoding: unused - */ - int weighted_p_pred; - - /** - * AQ mode - * 0: Disabled - * 1: Variance AQ (complexity mask) - * 2: Auto-variance AQ (experimental) - * - encoding: Set by user - * - decoding: unused - */ - int aq_mode; - - /** - * AQ strength - * Reduces blocking and blurring in flat and textured areas. - * - encoding: Set by user - * - decoding: unused - */ - float aq_strength; - - /** - * PSY RD - * Strength of psychovisual optimization - * - encoding: Set by user - * - decoding: unused - */ - float psy_rd; - - /** - * PSY trellis - * Strength of psychovisual optimization - * - encoding: Set by user - * - decoding: unused - */ - float psy_trellis; - - /** - * RC lookahead - * Number of frames for frametype and ratecontrol lookahead - * - encoding: Set by user - * - decoding: unused - */ - int rc_lookahead; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_c; -} AVCodecContext; - -/** - * AVCodec. - */ -typedef struct AVCodec { - /** - * Name of the codec implementation. - * The name is globally unique among encoders and among decoders (but an - * encoder and a decoder can share the same name). - * This is the primary way to find a codec from the user perspective. - */ - const char *name; - enum AVMediaType 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, AVPacket *avpkt); - /** - * Codec capabilities. - * see CODEC_CAP_* - */ - int capabilities; - struct AVCodec *next; - /** - * Flush buffers. - * Will be called when seeking - */ - 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 terminated by -1 - /** - * Descriptive name for the codec, meant to be more human readable than name. - * You should use the NULL_IF_CONFIG_SMALL() macro to define it. - */ - const char *long_name; - const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 - const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 - const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 -} AVCodec; - -/** - * AVHWAccel. - */ -typedef struct AVHWAccel { - /** - * Name of the hardware accelerated codec. - * The name is globally unique among encoders and among decoders (but an - * encoder and a decoder can share the same name). - */ - const char *name; - - /** - * Type of codec implemented by the hardware accelerator. - * - * See AVMEDIA_TYPE_xxx - */ - enum AVMediaType type; - - /** - * Codec implemented by the hardware accelerator. - * - * See CODEC_ID_xxx - */ - enum CodecID id; - - /** - * Supported pixel format. - * - * Only hardware accelerated formats are supported here. - */ - enum PixelFormat pix_fmt; - - /** - * Hardware accelerated codec capabilities. - * see FF_HWACCEL_CODEC_CAP_* - */ - int capabilities; - - struct AVHWAccel *next; - - /** - * Called at the beginning of each frame or field picture. - * - * Meaningful frame information (codec specific) is guaranteed to - * be parsed at this point. This function is mandatory. - * - * Note that buf can be NULL along with buf_size set to 0. - * Otherwise, this means the whole frame is available at this point. - * - * @param avctx the codec context - * @param buf the frame data buffer base - * @param buf_size the size of the frame in bytes - * @return zero if successful, a negative value otherwise - */ - int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); - - /** - * Callback for each slice. - * - * Meaningful slice information (codec specific) is guaranteed to - * be parsed at this point. This function is mandatory. - * - * @param avctx the codec context - * @param buf the slice data buffer base - * @param buf_size the size of the slice in bytes - * @return zero if successful, a negative value otherwise - */ - int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); - - /** - * Called at the end of each frame or field picture. - * - * The whole picture is parsed at this point and can now be sent - * to the hardware accelerator. This function is mandatory. - * - * @param avctx the codec context - * @return zero if successful, a negative value otherwise - */ - int (*end_frame)(AVCodecContext *avctx); - - /** - * Size of HW accelerator private data. - * - * Private data is allocated with av_mallocz() before - * AVCodecContext.get_buffer() and deallocated after - * AVCodecContext.release_buffer(). - */ - int priv_data_size; -} AVHWAccel; - -/** - * 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; - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * AVPaletteControl - * This structure defines a method for communicating palette changes - * between and demuxer and a decoder. - * - * @deprecated Use AVPacket to send palette changes instead. - * This is totally broken. - */ -#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 an IBM VGA native format, the component - * data is probably 6 bits in size and needs to be scaled. */ - unsigned int palette[AVPALETTE_COUNT]; - -} AVPaletteControl attribute_deprecated; -#endif - -enum AVSubtitleType { - SUBTITLE_NONE, - - SUBTITLE_BITMAP, ///< A bitmap, pict will be set - - /** - * Plain text, the text field must be set by the decoder and is - * authoritative. ass and pict fields may contain approximations. - */ - SUBTITLE_TEXT, - - /** - * Formatted text, the ass field must be set by the decoder and is - * authoritative. pict and text fields may contain approximations. - */ - SUBTITLE_ASS, -}; - -typedef struct AVSubtitleRect { - int x; ///< top left corner of pict, undefined when pict is not set - int y; ///< top left corner of pict, undefined when pict is not set - int w; ///< width of pict, undefined when pict is not set - int h; ///< height of pict, undefined when pict is not set - int nb_colors; ///< number of colors in pict, undefined when pict is not set - - /** - * data+linesize for the bitmap of this subtitle. - * can be set for text/ass as well once they where rendered - */ - AVPicture pict; - enum AVSubtitleType type; - - char *text; ///< 0 terminated plain UTF-8 text - - /** - * 0 terminated ASS/SSA compatible event line. - * The pressentation of this is unaffected by the other values in this - * struct. - */ - char *ass; -} 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 */ - unsigned num_rects; - AVSubtitleRect **rects; - int64_t pts; ///< Same as packet pts, in AV_TIME_BASE -} AVSubtitle; - -/* packet functions */ - -/** - * @deprecated use NULL instead - */ -attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt); - -/** - * Default packet destructor. - */ -void av_destruct_packet(AVPacket *pkt); - -/** - * Initialize optional fields of a packet with default values. - * - * @param pkt packet - */ -void av_init_packet(AVPacket *pkt); - -/** - * Allocate the payload of a packet and initialize its fields with - * default values. - * - * @param pkt packet - * @param size wanted payload size - * @return 0 if OK, AVERROR_xxx otherwise - */ -int av_new_packet(AVPacket *pkt, int size); - -/** - * Reduce packet size, correctly zeroing padding - * - * @param pkt packet - * @param size new size - */ -void av_shrink_packet(AVPacket *pkt, int size); - -/** - * @warning This is a hack - the packet memory allocation stuff is broken. The - * packet is allocated if it was not really allocated. - */ -int av_dup_packet(AVPacket *pkt); - -/** - * Free a packet. - * - * @param pkt packet to free - */ -void av_free_packet(AVPacket *pkt); - -/* resample.c */ - -struct ReSampleContext; -struct AVResampleContext; - -typedef struct ReSampleContext ReSampleContext; - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * @deprecated Use av_audio_resample_init() instead. - */ -attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels, - int output_rate, int input_rate); -#endif -/** - * Initializes audio resampling context - * - * @param output_channels number of output channels - * @param input_channels number of input channels - * @param output_rate output sample rate - * @param input_rate input sample rate - * @param sample_fmt_out requested output sample format - * @param sample_fmt_in input sample format - * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq - * @param log2_phase_count log2 of the number of entries in the polyphase filterbank - * @param linear If 1 then the used FIR filter will be linearly interpolated - between the 2 closest, if 0 the closest will be used - * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate - * @return allocated ReSampleContext, NULL if error occured - */ -ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, - int output_rate, int input_rate, - enum SampleFormat sample_fmt_out, - enum SampleFormat sample_fmt_in, - int filter_length, int log2_phase_count, - int linear, double cutoff); - -int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); -void audio_resample_close(ReSampleContext *s); - - -/** - * Initializes an audio resampler. - * Note, if either rate is not an integer then simply scale both rates up so they are. - * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq - * @param log2_phase_count log2 of the number of entries in the polyphase filterbank - * @param linear If 1 then the used FIR filter will be linearly interpolated - between the 2 closest, if 0 the closest will be used - * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate - */ -struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); - -/** - * resamples. - * @param src an array of unconsumed samples - * @param consumed the number of samples of src which have been consumed are returned here - * @param src_size the number of unconsumed samples available - * @param dst_size the amount of space in samples available in dst - * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context. - * @return the number of samples written in dst or -1 if an error occurred - */ -int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); - - -/** - * Compensates samplerate/timestamp drift. The compensation is done by changing - * the resampler parameters, so no audible clicks or similar distortions occur - * @param compensation_distance distance in output samples over which the compensation should be performed - * @param sample_delta number of output samples which should be output less - * - * example: av_resample_compensate(c, 10, 500) - * here instead of 510 samples only 500 samples would be output - * - * note, due to rounding the actual compensation might be slightly different, - * especially if the compensation_distance is large and the in_rate used during init is small - */ -void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); -void av_resample_close(struct AVResampleContext *c); - -/** - * 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 zero if successful, a negative value if not - */ -int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int height); - -/** - * Free a picture previously allocated by avpicture_alloc(). - * - * @param picture the AVPicture to be freed - */ -void avpicture_free(AVPicture *picture); - -/** - * Fill in the AVPicture fields. - * The fields of the given AVPicture are filled in by using the 'ptr' address - * which points to the image data buffer. Depending on the specified picture - * format, one or multiple image data pointers and line sizes will be set. - * If a planar format is specified, several pointers will be set pointing to - * the different picture planes and the line sizes of the different planes - * will be stored in the lines_sizes array. - * Call with ptr == NULL to get the required size for the ptr buffer. - * - * @param picture AVPicture whose fields are to be filled in - * @param ptr Buffer which will contain or contains the actual image data - * @param pix_fmt The format in which the picture data is stored. - * @param width the width of the image in pixels - * @param height the height of the image in pixels - * @return size of the image data in bytes - */ -int avpicture_fill(AVPicture *picture, uint8_t *ptr, - enum PixelFormat pix_fmt, int width, int height); -int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, - unsigned char *dest, int dest_size); - -/** - * Calculate the size in bytes that a picture of the given width and height - * would occupy if stored in the given picture format. - * Note that this returns the size of a compact representation as generated - * by avpicture_layout, which can be smaller than the size required for e.g. - * avpicture_fill. - * - * @param pix_fmt the given picture format - * @param width the width of the image - * @param height the height of the image - * @return Image data size in bytes or -1 on error (e.g. too large dimensions). - */ -int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height); -void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift); -const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt); -void avcodec_set_dimensions(AVCodecContext *s, int width, int height); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * Returns the pixel format corresponding to the name name. - * - * If there is no pixel format with name name, then looks for a - * pixel format with the name corresponding to the native endian - * format of name. - * For example in a little-endian system, first looks for "gray16", - * then for "gray16le". - * - * Finally if no pixel format has been found, returns PIX_FMT_NONE. - * - * @deprecated Deprecated in favor of av_get_pix_fmt(). - */ -attribute_deprecated enum PixelFormat avcodec_get_pix_fmt(const char* name); -#endif - -/** - * Returns a value representing the fourCC code associated to the - * pixel format pix_fmt, or 0 if no associated fourCC code can be - * found. - */ -unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat pix_fmt); - -#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) */ - -/** - * Computes what kind of losses will occur when converting from one specific - * pixel format to another. - * When converting from one pixel format to another, information loss may occur. - * For example, when converting from RGB24 to GRAY, the color information will - * be lost. Similarly, other losses occur when converting from some formats to - * other formats. These losses can involve loss of chroma, but also loss of - * resolution, loss of color depth, loss due to the color space conversion, loss - * of the alpha bits or loss due to color quantization. - * avcodec_get_fix_fmt_loss() informs you about the various types of losses - * which will occur when converting from one pixel format to another. - * - * @param[in] dst_pix_fmt destination pixel format - * @param[in] src_pix_fmt source pixel format - * @param[in] has_alpha Whether the source pixel format alpha channel is used. - * @return Combination of flags informing you what kind of losses will occur. - */ -int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, - int has_alpha); - -/** - * Finds the best pixel format to convert to given a certain source pixel - * format. When converting from one pixel format to another, information loss - * may occur. For example, when converting from RGB24 to GRAY, the color - * information will be lost. Similarly, other losses occur when converting from - * some formats to other formats. avcodec_find_best_pix_fmt() searches which of - * the given pixel formats should be used to suffer the least amount of loss. - * The pixel formats from which it chooses one, are determined by the - * pix_fmt_mask parameter. - * - * @code - * src_pix_fmt = PIX_FMT_YUV420P; - * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24); - * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); - * @endcode - * - * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from - * @param[in] src_pix_fmt source pixel format - * @param[in] has_alpha Whether the source pixel format alpha channel is used. - * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. - * @return The best pixel format to convert to or -1 if none was found. - */ -enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, - int has_alpha, int *loss_ptr); - - -/** - * Print in buf the string corresponding to the pixel format with - * number pix_fmt, or an header if pix_fmt is negative. - * - * @param[in] buf the buffer where to write the string - * @param[in] buf_size the size of buf - * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or - * a negative value to print the corresponding header. - * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1. - */ -void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt); - -#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ -#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ - -/** - * 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, - enum PixelFormat pix_fmt, int width, int height); - -/* deinterlace a picture */ -/* deinterlace - if not supported return -1 */ -int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height); - -/* external high level API */ - -/** - * If c is NULL, returns the first registered codec, - * if c is non-NULL, returns the next registered codec after c, - * or NULL if c is the last one. - */ -AVCodec *av_codec_next(AVCodec *c); - -/** - * Returns the LIBAVCODEC_VERSION_INT constant. - */ -unsigned avcodec_version(void); - -/** - * Returns the libavcodec build-time configuration. - */ -const char *avcodec_configuration(void); - -/** - * Returns the libavcodec license. - */ -const char *avcodec_license(void); - -/** - * Initializes libavcodec. - * - * @warning This function must be called before any other libavcodec - * function. - */ -void avcodec_init(void); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * @deprecated Deprecated in favor of avcodec_register(). - */ -attribute_deprecated void register_avcodec(AVCodec *codec); -#endif - -/** - * Register the codec codec and initialize libavcodec. - * - * @see avcodec_init() - */ -void avcodec_register(AVCodec *codec); - -/** - * Finds a registered encoder with a matching codec ID. - * - * @param id CodecID of the requested encoder - * @return An encoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_encoder(enum CodecID id); - -/** - * Finds a registered encoder with the specified name. - * - * @param name name of the requested encoder - * @return An encoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_encoder_by_name(const char *name); - -/** - * Finds a registered decoder with a matching codec ID. - * - * @param id CodecID of the requested decoder - * @return A decoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_decoder(enum CodecID id); - -/** - * Finds a registered decoder with the specified name. - * - * @param name name of the requested decoder - * @return A decoder if one was found, NULL otherwise. - */ -AVCodec *avcodec_find_decoder_by_name(const char *name); -void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); - -/** - * Sets the fields of the given AVCodecContext to default values. - * - * @param s The AVCodecContext of which the fields should be set to default values. - */ -void avcodec_get_context_defaults(AVCodecContext *s); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); - -/** - * Allocates an AVCodecContext and sets its fields to default values. The - * resulting struct can be deallocated by simply calling av_free(). - * - * @return An AVCodecContext filled with default values or NULL on failure. - * @see avcodec_get_context_defaults - */ -AVCodecContext *avcodec_alloc_context(void); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -AVCodecContext *avcodec_alloc_context2(enum AVMediaType); - -/** - * Copy the settings of the source AVCodecContext into the destination - * AVCodecContext. The resulting destination codec context will be - * unopened, i.e. you are required to call avcodec_open() before you - * can use this AVCodecContext to decode/encode video/audio data. - * - * @param dest target codec context, should be initialized with - * avcodec_alloc_context(), but otherwise uninitialized - * @param src source codec context - * @return AVERROR() on error (e.g. memory allocation error), 0 on success - */ -int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); - -/** - * Sets the fields of the given AVFrame to default values. - * - * @param pic The AVFrame of which the fields should be set to default values. - */ -void avcodec_get_frame_defaults(AVFrame *pic); - -/** - * Allocates an AVFrame and sets its fields to default values. The resulting - * struct can be deallocated by simply calling av_free(). - * - * @return An AVFrame filled with default values or NULL on failure. - * @see avcodec_get_frame_defaults - */ -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); - -/** - * Returns the amount of padding in pixels which the get_buffer callback must - * provide around the edge of the image for codecs which do not have the - * CODEC_FLAG_EMU_EDGE flag. - * - * @return Required padding in pixels. - */ -unsigned avcodec_get_edge_width(void); -/** - * Modifies width and height values so that they will result in a memory - * buffer that is acceptable for the codec if you do not use any horizontal - * padding. - * - * May only be used if a codec with CODEC_CAP_DR1 has been opened. - * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased - * according to avcodec_get_edge_width() before. - */ -void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); -/** - * Modifies width and height values so that they will result in a memory - * buffer that is acceptable for the codec if you also ensure that all - * line sizes are a multiple of the respective linesize_align[i]. - * - * May only be used if a codec with CODEC_CAP_DR1 has been opened. - * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased - * according to avcodec_get_edge_width() before. - */ -void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, - int linesize_align[4]); - -/** - * Checks if the given dimension of a picture is valid, meaning that all - * bytes of the picture can be addressed with a signed int. - * - * @param[in] w Width of the picture. - * @param[in] h Height of the picture. - * @return Zero if valid, a negative value if invalid. - */ -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_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); -int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); -//FIXME func typedef - -/** - * Initializes the AVCodecContext to use the given AVCodec. Prior to using this - * function the context has to be allocated. - * - * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), - * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for - * retrieving a codec. - * - * @warning This function is not thread safe! - * - * @code - * avcodec_register_all(); - * codec = avcodec_find_decoder(CODEC_ID_H264); - * if (!codec) - * exit(1); - * - * context = avcodec_alloc_context(); - * - * if (avcodec_open(context, codec) < 0) - * exit(1); - * @endcode - * - * @param avctx The context which will be set up to use the given codec. - * @param codec The codec to use within the context. - * @return zero on success, a negative value on error - * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder - */ -int avcodec_open(AVCodecContext *avctx, AVCodec *codec); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * Decodes an audio frame from buf into samples. - * Wrapper function which calls avcodec_decode_audio3. - * - * @deprecated Use avcodec_decode_audio3 instead. - * @param avctx the codec context - * @param[out] samples the output buffer - * @param[in,out] frame_size_ptr the output buffer size in bytes - * @param[in] buf the input buffer - * @param[in] buf_size the input buffer size in bytes - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. - */ -attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - const uint8_t *buf, int buf_size); -#endif - -/** - * Decodes the audio frame of size avpkt->size from avpkt->data into samples. - * Some decoders may support multiple frames in a single AVPacket, such - * decoders would then just decode the first frame. In this case, - * avcodec_decode_audio3 has to be called again with an AVPacket that contains - * the remaining data in order to decode the second frame etc. - * If no frame - * could be outputted, frame_size_ptr is zero. Otherwise, it is the - * decompressed frame size in bytes. - * - * @warning You must set frame_size_ptr to the allocated size of the - * output buffer before calling avcodec_decode_audio3(). - * - * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than - * the actual read bytes because some optimized bitstream readers read 32 or 64 - * bits at once and could read over the end. - * - * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that - * no overreading happens for damaged MPEG streams. - * - * @note You might have to align the input buffer avpkt->data and output buffer - * samples. The alignment requirements depend on the CPU: On some CPUs it isn't - * necessary at all, on others it won't work at all if not aligned and on others - * it will work but it will have an impact on performance. - * - * In practice, avpkt->data should have 4 byte alignment at minimum and - * samples should be 16 byte aligned unless the CPU doesn't need it - * (AltiVec and SSE do). - * - * @param avctx the codec context - * @param[out] samples the output buffer, sample type in avctx->sample_fmt - * @param[in,out] frame_size_ptr the output buffer size in bytes - * @param[in] avpkt The input AVPacket containing the input buffer. - * You can create such packet with av_init_packet() and by then setting - * data and size, some decoders might in addition need other fields. - * All decoders are designed to use the least fields possible though. - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame data was decompressed (used) from the input AVPacket. - */ -int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - AVPacket *avpkt); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * Decodes a video frame from buf into picture. - * Wrapper function which calls avcodec_decode_video2. - * - * @deprecated Use avcodec_decode_video2 instead. - * @param avctx the codec context - * @param[out] picture The AVFrame in which the decoded video frame will be stored. - * @param[in] buf the input buffer - * @param[in] buf_size the size of the input buffer in bytes - * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. - */ -attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - const uint8_t *buf, int buf_size); -#endif - -/** - * Decodes the video frame of size avpkt->size from avpkt->data into picture. - * Some decoders may support multiple frames in a single AVPacket, such - * decoders would then just decode the first frame. - * - * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than - * the actual read bytes because some optimized bitstream readers read 32 or 64 - * bits at once and could read over the end. - * - * @warning The end of the input buffer buf should be set to 0 to ensure that - * no overreading happens for damaged MPEG streams. - * - * @note You might have to align the input buffer avpkt->data. - * The alignment requirements depend on the CPU: on some CPUs it isn't - * necessary at all, on others it won't work at all if not aligned and on others - * it will work but it will have an impact on performance. - * - * In practice, avpkt->data should have 4 byte alignment at minimum. - * - * @note Some codecs have a delay between input and output, these need to be - * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames. - * - * @param avctx the codec context - * @param[out] picture The AVFrame in which the decoded video frame will be stored. - * Use avcodec_alloc_frame to get an AVFrame, the codec will - * allocate memory for the actual bitmap. - * @param[in] avpkt The input AVpacket containing the input buffer. - * You can create such packet with av_init_packet() and by then setting - * data and size, some decoders might in addition need other fields like - * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least - * fields possible. - * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. - * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. - */ -int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - AVPacket *avpkt); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/* Decode a subtitle message. Return -1 if error, otherwise return the - * number of bytes used. If no subtitle could be decompressed, - * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ -attribute_deprecated int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - const uint8_t *buf, int buf_size); -#endif - -/** - * Decodes a subtitle message. - * Returns a negative value on error, otherwise returns the number of bytes used. - * If no subtitle could be decompressed, got_sub_ptr is zero. - * Otherwise, the subtitle is stored in *sub. - * - * @param avctx the codec context - * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored. - * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. - * @param[in] avpkt The input AVPacket containing the input buffer. - */ -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt); -int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, - int *data_size_ptr, - uint8_t *buf, int buf_size); - -/** - * Encodes an audio frame from samples into buf. - * - * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large. - * However, for PCM audio the user will know how much space is needed - * because it depends on the value passed in buf_size as described - * below. In that case a lower value can be used. - * - * @param avctx the codec context - * @param[out] buf the output buffer - * @param[in] buf_size the output buffer size - * @param[in] samples the input buffer containing the samples - * The number of samples read from this buffer is frame_size*channels, - * both of which are defined in avctx. - * For PCM audio the number of samples read from samples is equal to - * buf_size * input_sample_size / output_sample_size. - * @return On error a negative value is returned, on success zero or the number - * of bytes used to encode the data read from the input buffer. - */ -int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const short *samples); - -/** - * Encodes a video frame from pict into buf. - * The input picture should be - * stored using a specific format, namely avctx.pix_fmt. - * - * @param avctx the codec context - * @param[out] buf the output buffer for the bitstream of encoded frame - * @param[in] buf_size the size of the output buffer in bytes - * @param[in] pict the input picture to encode - * @return On error a negative value is returned, on success zero or the number - * of bytes used from the output buffer. - */ -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); - -/** - * Register all the codecs, parsers and bitstream filters which were enabled at - * configuration time. If you do not call this function you can select exactly - * which formats you want to support, by using the individual registration - * functions. - * - * @see avcodec_register - * @see av_register_codec_parser - * @see av_register_bitstream_filter - */ -void avcodec_register_all(void); - -/** - * Flush buffers, should be called when seeking or when switching to a different stream. - */ -void avcodec_flush_buffers(AVCodecContext *avctx); - -void avcodec_default_free_buffers(AVCodecContext *s); - -/* misc useful functions */ - -/** - * Returns a single letter to describe the given picture type pict_type. - * - * @param[in] pict_type the picture type - * @return A single character representing the picture type. - */ -char av_get_pict_type_char(int pict_type); - -/** - * Returns codec bits per sample. - * - * @param[in] codec_id the codec - * @return Number of bits per sample or zero if unknown for the given codec. - */ -int av_get_bits_per_sample(enum CodecID codec_id); - -/** - * Returns sample format bits per sample. - * - * @param[in] sample_fmt the sample format - * @return Number of bits per sample or zero if unknown for the given sample format. - */ -int av_get_bits_per_sample_format(enum SampleFormat sample_fmt); - -/* 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 next_frame_offset; /* offset of the next frame */ - /* video info */ - int pict_type; /* XXX: Put it back in AVCodecContext. */ - /** - * This field is used for proper frame duration computation in lavf. - * It signals, how much longer the frame duration of the current frame - * is compared to normal frame duration. - * - * frame_duration = (1 + repeat_pict) * time_base - * - * It is used by codecs like H.264 to display telecined material. - */ - 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 - - int64_t offset; ///< byte offset from starting packet start - - /* - * dummy variable for tizen in Windows. - */ - int dummy_a; - - int64_t cur_frame_end[AV_PARSER_PTS_NB]; - - /*! - * Set by parser to 1 for key frames and 0 for non-key frames. - * It is initialized to -1, so if the parser doesn't set this flag, - * old-style fallback using FF_I_TYPE picture type as key frames - * will be used. - */ - int key_frame; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_b; - - /** - * Time difference in stream time base units from the pts of this - * packet to the point at which the output from the decoder has converged - * independent from the availability of previous frames. That is, the - * frames are virtually identical no matter if decoding started from - * the very first frame or from this keyframe. - * Is AV_NOPTS_VALUE if unknown. - * This field is not the display duration of the current frame. - * - * The purpose of this field is to allow seeking in streams that have no - * keyframes in the conventional sense. It corresponds to the - * recovery point SEI in H.264 and match_time_delta in NUT. It is also - * essential for some types of subtitle streams to ensure that all - * subtitles are correctly displayed after seeking. - */ - int64_t convergence_duration; - - // Timestamp generation support: - /** - * Synchronization point for start of timestamp generation. - * - * Set to >0 for sync point, 0 for no sync point and <0 for undefined - * (default). - * - * For example, this corresponds to presence of H.264 buffering period - * SEI message. - */ - int dts_sync_point; - - /** - * Offset of the current timestamp against last timestamp sync point in - * units of AVCodecContext.time_base. - * - * Set to INT_MIN when dts_sync_point unused. Otherwise, it must - * contain a valid timestamp offset. - * - * Note that the timestamp of sync point has usually a nonzero - * dts_ref_dts_delta, which refers to the previous sync point. Offset of - * the next frame after timestamp sync point will be usually 1. - * - * For example, this corresponds to H.264 cpb_removal_delay. - */ - int dts_ref_dts_delta; - - /** - * Presentation delay of current frame in units of AVCodecContext.time_base. - * - * Set to INT_MIN when dts_sync_point unused. Otherwise, it must - * contain valid non-negative timestamp delta (presentation time of a frame - * must not lie in the past). - * - * This delay represents the difference between decoding and presentation - * time of the frame. - * - * For example, this corresponds to H.264 dpb_output_delay. - */ - int pts_dts_delta; - - /* - * dummy variable for tizen in Windows. - */ - int dummy_c; - - /** - * Position of the packet in file. - * - * Analogous to cur_frame_pts/dts - */ - int64_t cur_frame_pos[AV_PARSER_PTS_NB]; - - /** - * Byte position of currently parsed frame in stream. - */ - int64_t pos; - - /** - * Previous frame byte position. - */ - int64_t last_pos; -} 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, - const 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; - -AVCodecParser *av_parser_next(AVCodecParser *c); - -void av_register_codec_parser(AVCodecParser *parser); -AVCodecParserContext *av_parser_init(int codec_id); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -attribute_deprecated -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); -#endif - -/** - * Parse a packet. - * - * @param s parser context. - * @param avctx codec context. - * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. - * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. - * @param buf input buffer. - * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output). - * @param pts input presentation timestamp. - * @param dts input decoding timestamp. - * @param pos input byte position in stream. - * @return the number of bytes of the input bitstream used. - * - * Example: - * @code - * while(in_len){ - * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, - * in_data, in_len, - * pts, dts, pos); - * in_data += len; - * in_len -= len; - * - * if(size) - * decode_frame(data, size); - * } - * @endcode - */ -int av_parser_parse2(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, - int64_t pts, int64_t dts, - int64_t pos); - -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); - - -typedef struct AVBitStreamFilterContext { - void *priv_data; - struct AVBitStreamFilter *filter; - AVCodecParserContext *parser; - struct AVBitStreamFilterContext *next; -} AVBitStreamFilterContext; - - -typedef struct AVBitStreamFilter { - const char *name; - int priv_data_size; - int (*filter)(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); - void (*close)(AVBitStreamFilterContext *bsfc); - struct AVBitStreamFilter *next; -} AVBitStreamFilter; - -void av_register_bitstream_filter(AVBitStreamFilter *bsf); -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); -int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); -void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); - -AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); - -/* memory */ - -/** - * Reallocates the given block if it is not large enough, otherwise it - * does nothing. - * - * @see av_realloc - */ -void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); - -/** - * Allocates a buffer, reusing the given one if large enough. - * - * Contrary to av_fast_realloc the current buffer contents might not be - * preserved and on error the old buffer is freed, thus no special - * handling to avoid memleaks is necessary. - * - * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer - * @param size size of the buffer *ptr points to - * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and - * *size 0 if an error occurred. - */ -void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size); - -/** - * Copy image 'src' to 'dst'. - */ -void av_picture_copy(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height); - -/** - * Crop image top and left side. - */ -int av_picture_crop(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int top_band, int left_band); - -/** - * Pad image. - */ -int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum PixelFormat pix_fmt, - int padtop, int padbottom, int padleft, int padright, int *color); - -/** - * Encodes extradata length to a buffer. Used by xiph codecs. - * - * @param s buffer to write to; must be at least (v/255+1) bytes long - * @param v size of extradata in bytes - * @return number of bytes written to the buffer. - */ -unsigned int av_xiphlacing(unsigned char *s, unsigned int v); - -/** - * Parses str and put in width_ptr and height_ptr the detected values. - * - * @return 0 in case of a successful parsing, a negative value otherwise - * @param[in] str the string to parse: it has to be a string in the format - * x or a valid video frame size abbreviation. - * @param[in,out] width_ptr pointer to the variable which will contain the detected - * frame width value - * @param[in,out] height_ptr pointer to the variable which will contain the detected - * frame height value - */ -int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); - -/** - * Parses str and put in frame_rate the detected values. - * - * @return 0 in case of a successful parsing, a negative value otherwise - * @param[in] str the string to parse: it has to be a string in the format - * /, a float number or a valid video rate abbreviation - * @param[in,out] frame_rate pointer to the AVRational which will contain the detected - * frame rate - */ -int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); - -/** - * Logs a generic warning message about a missing feature. This function is - * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) - * only, and would normally not be used by applications. - * @param[in] avc a pointer to an arbitrary struct of which the first field is - * a pointer to an AVClass struct - * @param[in] feature string containing the name of the missing feature - * @param[in] want_sample indicates if samples are wanted which exhibit this feature. - * If want_sample is non-zero, additional verbage will be added to the log - * message which tells the user how to report samples to the development - * mailing list. - */ -void av_log_missing_feature(void *avc, const char *feature, int want_sample); - -/** - * Logs a generic warning message asking for a sample. This function is - * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) - * only, and would normally not be used by applications. - * @param[in] avc a pointer to an arbitrary struct of which the first field is - * a pointer to an AVClass struct - * @param[in] msg string containing an optional message, or NULL if no message - */ -void av_log_ask_for_sample(void *avc, const char *msg); - -/** - * Registers the hardware accelerator hwaccel. - */ -void av_register_hwaccel(AVHWAccel *hwaccel); - -/** - * If hwaccel is NULL, returns the first registered hardware accelerator, - * if hwaccel is non-NULL, returns the next registered hardware accelerator - * after hwaccel, or NULL if hwaccel is the last one. - */ -AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel); - - -/** - * Lock operation used by lockmgr - */ -enum AVLockOp { - AV_LOCK_CREATE, ///< Create a mutex - AV_LOCK_OBTAIN, ///< Lock the mutex - AV_LOCK_RELEASE, ///< Unlock the mutex - AV_LOCK_DESTROY, ///< Free mutex resources -}; - -/** - * Register a user provided lock manager supporting the operations - * specified by AVLockOp. mutex points to a (void *) where the - * lockmgr should store/get a pointer to a user allocated mutex. It's - * NULL upon AV_LOCK_CREATE and != NULL for all other ops. - * - * @param cb User defined callback. Note: FFmpeg may invoke calls to this - * callback during the call to av_lockmgr_register(). - * Thus, the application must be prepared to handle that. - * If cb is set to NULL the lockmgr will be unregistered. - * Also note that during unregistration the previously registered - * lockmgr callback may also be invoked. - */ -int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); - -#endif /* AVCODEC_AVCODEC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/avfft.c b/tizen/distrib/ffmpeg/libavcodec/avfft.c deleted file mode 100644 index 25fc4e0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/avfft.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/mem.h" -#include "avfft.h" -#include "fft.h" - -/* FFT */ - -FFTContext *av_fft_init(int nbits, int inverse) -{ - FFTContext *s = av_malloc(sizeof(*s)); - - if (s) - ff_fft_init(s, nbits, inverse); - - return s; -} - -void av_fft_permute(FFTContext *s, FFTComplex *z) -{ - s->fft_permute(s, z); -} - -void av_fft_calc(FFTContext *s, FFTComplex *z) -{ - s->fft_calc(s, z); -} - -void av_fft_end(FFTContext *s) -{ - if (s) { - ff_fft_end(s); - av_free(s); - } -} - -#if CONFIG_MDCT - -FFTContext *av_mdct_init(int nbits, int inverse, double scale) -{ - FFTContext *s = av_malloc(sizeof(*s)); - - if (s) - ff_mdct_init(s, nbits, inverse, scale); - - return s; -} - -void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - s->imdct_calc(s, output, input); -} - -void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - s->imdct_half(s, output, input); -} - -void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - s->mdct_calc(s, output, input); -} - -void av_mdct_end(FFTContext *s) -{ - if (s) { - ff_mdct_end(s); - av_free(s); - } -} - -#endif /* CONFIG_MDCT */ - -#if CONFIG_RDFT - -RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans) -{ - RDFTContext *s = av_malloc(sizeof(*s)); - - if (s) - ff_rdft_init(s, nbits, trans); - - return s; -} - -void av_rdft_calc(RDFTContext *s, FFTSample *data) -{ - ff_rdft_calc(s, data); -} - -void av_rdft_end(RDFTContext *s) -{ - if (s) { - ff_rdft_end(s); - av_free(s); - } -} - -#endif /* CONFIG_RDFT */ - -#if CONFIG_DCT - -DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse) -{ - DCTContext *s = av_malloc(sizeof(*s)); - - if (s) - ff_dct_init(s, nbits, inverse); - - return s; -} - -void av_dct_calc(DCTContext *s, FFTSample *data) -{ - ff_dct_calc(s, data); -} - -void av_dct_end(DCTContext *s) -{ - if (s) { - ff_dct_end(s); - av_free(s); - } -} - -#endif /* CONFIG_DCT */ diff --git a/tizen/distrib/ffmpeg/libavcodec/avfft.h b/tizen/distrib/ffmpeg/libavcodec/avfft.h deleted file mode 100644 index 623f0a3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/avfft.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AVFFT_H -#define AVCODEC_AVFFT_H - -typedef float FFTSample; - -typedef struct FFTComplex { - FFTSample re, im; -} FFTComplex; - -typedef struct FFTContext FFTContext; - -/** - * Set up a complex FFT. - * @param nbits log2 of the length of the input array - * @param inverse if 0 perform the forward transform, if 1 perform the inverse - */ -FFTContext *av_fft_init(int nbits, int inverse); - -/** - * Do the permutation needed BEFORE calling ff_fft_calc(). - */ -void av_fft_permute(FFTContext *s, FFTComplex *z); - -/** - * Do a complex FFT with the parameters defined in av_fft_init(). The - * input data must be permuted before. No 1.0/sqrt(n) normalization is done. - */ -void av_fft_calc(FFTContext *s, FFTComplex *z); - -void av_fft_end(FFTContext *s); - -FFTContext *av_mdct_init(int nbits, int inverse, double scale); -void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); -void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input); -void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input); -void av_mdct_end(FFTContext *s); - -/* Real Discrete Fourier Transform */ - -enum RDFTransformType { - DFT_R2C, - IDFT_C2R, - IDFT_R2C, - DFT_C2R, -}; - -typedef struct RDFTContext RDFTContext; - -/** - * Set up a real FFT. - * @param nbits log2 of the length of the input array - * @param trans the type of transform - */ -RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans); -void av_rdft_calc(RDFTContext *s, FFTSample *data); -void av_rdft_end(RDFTContext *s); - -/* Discrete Cosine Transform */ - -typedef struct DCTContext DCTContext; - -enum DCTTransformType { - DCT_II = 0, - DCT_III, - DCT_I, - DST_I, -}; - -/** - * Sets up DCT. - * @param nbits size of the input array: - * (1 << nbits) for DCT-II, DCT-III and DST-I - * (1 << nbits) + 1 for DCT-I - * - * @note the first element of the input of DST-I is ignored - */ -DCTContext *av_dct_init(int nbits, enum DCTTransformType type); -void av_dct_calc(DCTContext *s, FFTSample *data); -void av_dct_end (DCTContext *s); - -#endif /* AVCODEC_AVFFT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/avpacket.c b/tizen/distrib/ffmpeg/libavcodec/avpacket.c deleted file mode 100644 index c51260f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/avpacket.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * AVPacket functions for libavcodec - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" - - -void av_destruct_packet_nofree(AVPacket *pkt) -{ - pkt->data = NULL; pkt->size = 0; -} - -void av_destruct_packet(AVPacket *pkt) -{ - av_free(pkt->data); - pkt->data = NULL; pkt->size = 0; -} - -void av_init_packet(AVPacket *pkt) -{ - pkt->pts = AV_NOPTS_VALUE; - pkt->dts = AV_NOPTS_VALUE; - pkt->pos = -1; - pkt->duration = 0; - pkt->convergence_duration = 0; - pkt->flags = 0; - pkt->stream_index = 0; - pkt->destruct= NULL; -} - -int av_new_packet(AVPacket *pkt, int size) -{ - uint8_t *data= NULL; - if((unsigned)size < (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE) - data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (data){ - memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - }else - size=0; - - av_init_packet(pkt); - pkt->data = data; - pkt->size = size; - pkt->destruct = av_destruct_packet; - if(!data) - return AVERROR(ENOMEM); - return 0; -} - -void av_shrink_packet(AVPacket *pkt, int size) -{ - if (pkt->size <= size) return; - pkt->size = size; - memset(pkt->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); -} - -int av_dup_packet(AVPacket *pkt) -{ - if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) { - uint8_t *data; - /* We duplicate the packet and don't forget to add the padding again. */ - if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE) - return AVERROR(ENOMEM); - data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!data) { - return AVERROR(ENOMEM); - } - memcpy(data, pkt->data, pkt->size); - memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - pkt->data = data; - pkt->destruct = av_destruct_packet; - } - return 0; -} - -void av_free_packet(AVPacket *pkt) -{ - if (pkt) { - if (pkt->destruct) pkt->destruct(pkt); - pkt->data = NULL; pkt->size = 0; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/avr32/mathops.h b/tizen/distrib/ffmpeg/libavcodec/avr32/mathops.h deleted file mode 100644 index 85f42b59..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/avr32/mathops.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Simple math operations - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_AVR32_MATHOPS_H -#define AVCODEC_AVR32_MATHOPS_H - -#include -#include "config.h" -#include "libavutil/common.h" - -#if HAVE_INLINE_ASM - -#define MULL MULL -static inline av_const int MULL(int a, int b, unsigned shift) -{ - union { int64_t x; int hl[2]; } x; - __asm__ ("muls.d %0, %1, %2 \n\t" - "lsr %0, %3 \n\t" - "or %0, %0, %m0<<%4 \n\t" - : "=r"(x) : "r"(b), "r"(a), "i"(shift), "i"(32-shift)); - return x.hl[1]; -} - -#define MULH MULH -static inline av_const int MULH(int a, int b) -{ - union { int64_t x; int hl[2]; } x; - __asm__ ("muls.d %0, %1, %2" : "=r"(x.x) : "r"(a), "r"(b)); - return x.hl[0]; -} - -#define MUL64 MUL64 -static inline av_const int64_t MUL64(int a, int b) -{ - int64_t x; - __asm__ ("muls.d %0, %1, %2" : "=r"(x) : "r"(a), "r"(b)); - return x; -} - -static inline av_const int64_t MAC64(int64_t d, int a, int b) -{ - __asm__ ("macs.d %0, %1, %2" : "+r"(d) : "r"(a), "r"(b)); - return d; -} -#define MAC64(d, a, b) ((d) = MAC64(d, a, b)) -#define MLS64(d, a, b) MAC64(d, -(a), b) - -static inline av_const int MAC16(int d, int a, int b) -{ - __asm__ ("machh.w %0, %1:b, %2:b" : "+r"(d) : "r"(a), "r"(b)); - return d; -} -#define MAC16(d, a, b) ((d) = MAC16(d, a, b)) -#define MLS16(d, a, b) MAC16(d, -(a), b) - -#define MUL16 MUL16 -static inline av_const int MUL16(int a, int b) -{ - int d; - __asm__ ("mulhh.w %0, %1:b, %2:b" : "=r"(d) : "r"(a), "r"(b)); - return d; -} - -#define mid_pred mid_pred -static inline av_const int mid_pred(int a, int b, int c) -{ - int m; - __asm__ ("mov %0, %2 \n\t" - "cp.w %1, %2 \n\t" - "movgt %0, %1 \n\t" - "movgt %1, %2 \n\t" - "cp.w %1, %3 \n\t" - "movle %1, %3 \n\t" - "cp.w %0, %1 \n\t" - "movgt %0, %1 \n\t" - : "=&r"(m), "+r"(a) - : "r"(b), "r"(c)); - return m; -} - -#endif /* HAVE_INLINE_ASM */ - -#endif /* AVCODEC_AVR32_MATHOPS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/avs.c b/tizen/distrib/ffmpeg/libavcodec/avs.c deleted file mode 100644 index f65a25a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/avs.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * AVS video decoder. - * Copyright (c) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "get_bits.h" - - -typedef struct { - AVFrame picture; -} AvsContext; - -typedef enum { - AVS_VIDEO = 0x01, - AVS_AUDIO = 0x02, - AVS_PALETTE = 0x03, - AVS_GAME_DATA = 0x04, -} AvsBlockType; - -typedef enum { - AVS_I_FRAME = 0x00, - AVS_P_FRAME_3X3 = 0x01, - AVS_P_FRAME_2X2 = 0x02, - AVS_P_FRAME_2X3 = 0x03, -} AvsVideoSubType; - - -static int -avs_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AvsContext *const avs = avctx->priv_data; - AVFrame *picture = data; - AVFrame *const p = (AVFrame *) & avs->picture; - const uint8_t *table, *vect; - uint8_t *out; - int i, j, x, y, stride, vect_w = 3, vect_h = 3; - AvsVideoSubType sub_type; - AvsBlockType 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 = AV_RL16(buf); - last = first + AV_RL16(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 av_cold int avs_decode_init(AVCodecContext * avctx) -{ - avctx->pix_fmt = PIX_FMT_PAL8; - return 0; -} - -AVCodec avs_decoder = { - "avs", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_AVS, - sizeof(AvsContext), - avs_decode_init, - NULL, - NULL, - avs_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/beosthread.c b/tizen/distrib/ffmpeg/libavcodec/beosthread.c deleted file mode 100644 index 44fe492..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/beosthread.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2004 François Revol - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 - -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 do not 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); -} - -static int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size){ - 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; - - if (thread_count <= 1) - return 0; - - 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/tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.c b/tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.c deleted file mode 100644 index 0ba39e6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Bethesda VID video decoder - * Copyright (C) 2007 Nicholas Tung - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Bethesda Softworks VID Video Decoder - * @author Nicholas Tung [ntung (at. ntung com] (2007-03) - * @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID - * @sa http://www.svatopluk.com/andux/docs/dfvid.html - */ - -#include "libavutil/common.h" -#include "dsputil.h" -#include "bethsoftvideo.h" -#include "bytestream.h" - -typedef struct BethsoftvidContext { - AVFrame frame; -} BethsoftvidContext; - -static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx) -{ - BethsoftvidContext *vid = avctx->priv_data; - vid->frame.reference = 1; - vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - avctx->pix_fmt = PIX_FMT_PAL8; - return 0; -} - -static void set_palette(AVFrame * frame, const uint8_t * palette_buffer) -{ - uint32_t * palette = (uint32_t *)frame->data[1]; - int a; - for(a = 0; a < 256; a++){ - palette[a] = AV_RB24(&palette_buffer[a * 3]) * 4; - } - frame->palette_has_changed = 1; -} - -static int bethsoftvid_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - BethsoftvidContext * vid = avctx->priv_data; - char block_type; - uint8_t * dst; - uint8_t * frame_end; - int remaining = avctx->width; // number of bytes remaining on a line - const int wrap_to_next_line = vid->frame.linesize[0] - avctx->width; - int code; - int yoffset; - - if (avctx->reget_buffer(avctx, &vid->frame)) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - dst = vid->frame.data[0]; - frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height; - - switch(block_type = *buf++){ - case PALETTE_BLOCK: - set_palette(&vid->frame, buf); - return 0; - case VIDEO_YOFF_P_FRAME: - yoffset = bytestream_get_le16(&buf); - if(yoffset >= avctx->height) - return -1; - dst += vid->frame.linesize[0] * yoffset; - } - - // main code - while((code = *buf++)){ - int length = code & 0x7f; - - // copy any bytes starting at the current position, and ending at the frame width - while(length > remaining){ - if(code < 0x80) - bytestream_get_buffer(&buf, dst, remaining); - else if(block_type == VIDEO_I_FRAME) - memset(dst, buf[0], remaining); - length -= remaining; // decrement the number of bytes to be copied - dst += remaining + wrap_to_next_line; // skip over extra bytes at end of frame - remaining = avctx->width; - if(dst == frame_end) - goto end; - } - - // copy any remaining bytes after / if line overflows - if(code < 0x80) - bytestream_get_buffer(&buf, dst, length); - else if(block_type == VIDEO_I_FRAME) - memset(dst, *buf++, length); - remaining -= length; - dst += length; - } - end: - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = vid->frame; - - return buf_size; -} - -static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx) -{ - BethsoftvidContext * vid = avctx->priv_data; - if(vid->frame.data[0]) - avctx->release_buffer(avctx, &vid->frame); - return 0; -} - -AVCodec bethsoftvid_decoder = { - .name = "bethsoftvid", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_BETHSOFTVID, - .priv_data_size = sizeof(BethsoftvidContext), - .init = bethsoftvid_decode_init, - .close = bethsoftvid_decode_end, - .decode = bethsoftvid_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Bethesda VID video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.h b/tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.h deleted file mode 100644 index d5b5d0a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bethsoftvideo.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Bethesda VID video decoder - * Copyright (C) 2007 Nicholas Tung - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_BETHSOFTVIDEO_H -#define AVCODEC_BETHSOFTVIDEO_H - -enum BethsoftVidBlockType -{ - PALETTE_BLOCK = 0x02, - FIRST_AUDIO_BLOCK = 0x7c, - AUDIO_BLOCK = 0x7d, - VIDEO_I_FRAME = 0x03, - VIDEO_P_FRAME = 0x01, - VIDEO_YOFF_P_FRAME = 0x04, - EOF_BLOCK = 0x14, -}; - -#endif /* AVCODEC_BETHSOFTVIDEO_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/bfi.c b/tizen/distrib/ffmpeg/libavcodec/bfi.c deleted file mode 100644 index 91c8f6d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfi.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Brute Force & Ignorance (BFI) video decoder - * Copyright (c) 2008 Sisir Koppaka - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Brute Force & Ignorance (.bfi) video decoder - * @author Sisir Koppaka ( sisir.koppaka at gmail dot com ) - * @sa http://wiki.multimedia.cx/index.php?title=BFI - */ - -#include "libavutil/common.h" -#include "avcodec.h" -#include "bytestream.h" - -typedef struct BFIContext { - AVCodecContext *avctx; - AVFrame frame; - uint8_t *dst; -} BFIContext; - -static av_cold int bfi_decode_init(AVCodecContext * avctx) -{ - BFIContext *bfi = avctx->priv_data; - avctx->pix_fmt = PIX_FMT_PAL8; - bfi->dst = av_mallocz(avctx->width * avctx->height); - return 0; -} - -static int bfi_decode_frame(AVCodecContext * avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - BFIContext *bfi = avctx->priv_data; - uint8_t *dst = bfi->dst; - uint8_t *src, *dst_offset, colour1, colour2; - uint8_t *frame_end = bfi->dst + avctx->width * avctx->height; - uint32_t *pal; - int i, j, height = avctx->height; - - if (bfi->frame.data[0]) - avctx->release_buffer(avctx, &bfi->frame); - - bfi->frame.reference = 1; - - if (avctx->get_buffer(avctx, &bfi->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - /* Set frame parameters and palette, if necessary */ - if (!avctx->frame_number) { - bfi->frame.pict_type = FF_I_TYPE; - bfi->frame.key_frame = 1; - /* Setting the palette */ - if(avctx->extradata_size>768) { - av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n"); - return -1; - } - pal = (uint32_t *) bfi->frame.data[1]; - for (i = 0; i < avctx->extradata_size / 3; i++) { - int shift = 16; - *pal = 0; - for (j = 0; j < 3; j++, shift -= 8) - *pal += - ((avctx->extradata[i * 3 + j] << 2) | - (avctx->extradata[i * 3 + j] >> 4)) << shift; - pal++; - } - bfi->frame.palette_has_changed = 1; - } else { - bfi->frame.pict_type = FF_P_TYPE; - bfi->frame.key_frame = 0; - } - - buf += 4; //Unpacked size, not required. - - while (dst != frame_end) { - static const uint8_t lentab[4]={0,2,0,1}; - unsigned int byte = *buf++, av_uninit(offset); - unsigned int code = byte >> 6; - unsigned int length = byte & ~0xC0; - - /* Get length and offset(if required) */ - if (length == 0) { - if (code == 1) { - length = bytestream_get_byte(&buf); - offset = bytestream_get_le16(&buf); - } else { - length = bytestream_get_le16(&buf); - if (code == 2 && length == 0) - break; - } - } else { - if (code == 1) - offset = bytestream_get_byte(&buf); - } - - /* Do boundary check */ - if (dst + (length< frame_end) - break; - - switch (code) { - - case 0: //Normal Chain - bytestream_get_buffer(&buf, dst, length); - dst += length; - break; - - case 1: //Back Chain - dst_offset = dst - offset; - length *= 4; //Convert dwords to bytes. - if (dst_offset < bfi->dst) - break; - while (length--) - *dst++ = *dst_offset++; - break; - - case 2: //Skip Chain - dst += length; - break; - - case 3: //Fill Chain - colour1 = bytestream_get_byte(&buf); - colour2 = bytestream_get_byte(&buf); - while (length--) { - *dst++ = colour1; - *dst++ = colour2; - } - break; - - } - } - - src = bfi->dst; - dst = bfi->frame.data[0]; - while (height--) { - memcpy(dst, src, avctx->width); - src += avctx->width; - dst += bfi->frame.linesize[0]; - } - *data_size = sizeof(AVFrame); - *(AVFrame *) data = bfi->frame; - return buf_size; -} - -static av_cold int bfi_decode_close(AVCodecContext * avctx) -{ - BFIContext *bfi = avctx->priv_data; - if (bfi->frame.data[0]) - avctx->release_buffer(avctx, &bfi->frame); - av_free(bfi->dst); - return 0; -} - -AVCodec bfi_decoder = { - .name = "bfi", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_BFI, - .priv_data_size = sizeof(BFIContext), - .init = bfi_decode_init, - .close = bfi_decode_close, - .decode = bfi_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/Makefile b/tizen/distrib/ffmpeg/libavcodec/bfin/Makefile deleted file mode 100644 index e50e3cd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -OBJS += bfin/dsputil_bfin.o \ - bfin/fdct_bfin.o \ - bfin/idct_bfin.o \ - bfin/mpegvideo_bfin.o \ - bfin/pixels_bfin.o \ - bfin/vp3_bfin.o \ - bfin/vp3_idct_bfin.o \ diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/config_bfin.h b/tizen/distrib/ffmpeg/libavcodec/bfin/config_bfin.h deleted file mode 100644 index f3a2c6e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/config_bfin.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - low level assembler interface wrapper - -DEFUN(put_pixels_clamped,mL1, - (DCTELEM *block, uint8_t *dest, int line_size)): - - body - - rts; -*/ - -#ifndef AVCODEC_BFIN_CONFIG_BFIN_H -#define AVCODEC_BFIN_CONFIG_BFIN_H - -#include "config.h" - -#ifndef DEFUN - -#define mL3 .text -#ifndef mL1 -#if defined(__FDPIC__) && CONFIG_SRAM -#define mL1 .l1.text -#else -#define mL1 mL3 -#endif -#endif - -#define DEFUN(fname,where,interface) \ - .section where; \ - .global _ff_bfin_ ## fname ; \ - .type _ff_bfin_ ## fname, STT_FUNC; \ - .align 8; \ - _ff_bfin_ ## fname - -#define DEFUN_END(fname) \ - .size _ff_bfin_ ## fname, . - _ff_bfin_ ## fname - -#ifdef __FDPIC__ -#define RELOC(reg,got,obj) reg = [got + obj@GOT17M4] -#else -#define RELOC(reg,got,obj) reg.L = obj; reg.H = obj -#endif - -#endif - -#endif /* AVCODEC_BFIN_CONFIG_BFIN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c b/tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c deleted file mode 100644 index 161d2da..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * BlackFin DSPUTILS - * - * Copyright (C) 2007 Marc Hoffman - * Copyright (c) 2006 Michael Benjamin - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "dsputil_bfin.h" - -int off; - -static void bfin_idct_add (uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_bfin_idct (block); - ff_bfin_add_pixels_clamped (block, dest, line_size); -} - -static void bfin_idct_put (uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_bfin_idct (block); - ff_bfin_put_pixels_clamped (block, dest, line_size); -} - - -static void bfin_clear_blocks (DCTELEM *blocks) -{ - // This is just a simple memset. - // - __asm__("P0=192; " - "I0=%0; " - "R0=0; " - "LSETUP(clear_blocks_blkfn_lab,clear_blocks_blkfn_lab)LC0=P0;" - "clear_blocks_blkfn_lab:" - "[I0++]=R0;" - ::"a" (blocks):"P0","I0","R0"); -} - - - -static void bfin_put_pixels8 (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels8uc (block, pixels, pixels, line_size, line_size, h); -} - -static void bfin_put_pixels8_x2(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels8uc (block, pixels, pixels+1, line_size, line_size, h); -} - -static void bfin_put_pixels8_y2 (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels8uc (block, pixels, pixels+line_size, line_size, line_size, h); -} - -static void bfin_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, int line_size, int h) -{ - ff_bfin_z_put_pixels8_xy2 (block,s0,line_size, line_size, h); -} - -static void bfin_put_pixels16 (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels16uc (block, pixels, pixels, line_size, line_size, h); -} - -static void bfin_put_pixels16_x2 (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels16uc (block, pixels, pixels+1, line_size, line_size, h); -} - -static void bfin_put_pixels16_y2 (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels16uc (block, pixels, pixels+line_size, line_size, line_size, h); -} - -static void bfin_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, int line_size, int h) -{ - ff_bfin_z_put_pixels16_xy2 (block,s0,line_size, line_size, h); -} - -static void bfin_put_pixels8_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels8uc_nornd (block, pixels, pixels, line_size, h); -} - -static void bfin_put_pixels8_x2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+1, line_size, h); -} - -static void bfin_put_pixels8_y2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+line_size, line_size, h); -} - - -static void bfin_put_pixels16_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels16uc_nornd (block, pixels, pixels, line_size, h); -} - -static void bfin_put_pixels16_x2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+1, line_size, h); -} - -static void bfin_put_pixels16_y2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+line_size, line_size, h); -} - -static int bfin_pix_abs16 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - return ff_bfin_z_sad16x16 (blk1,blk2,line_size,line_size,h); -} - -static int bfin_vsad_intra16 (void *c, uint8_t *blk1, uint8_t *dummy, int stride, int h) { - return ff_bfin_z_sad16x16 (blk1,blk1+stride,stride<<1,stride<<1,h); -} - -static int bfin_vsad (void *c, uint8_t *blk1, uint8_t *blk2, int stride, int h) { - return ff_bfin_z_sad16x16 (blk1,blk1+stride,stride<<1,stride<<1,h) - + ff_bfin_z_sad16x16 (blk2,blk2+stride,stride<<1,stride<<1,h); -} - -static uint8_t vtmp_blk[256] attribute_l1_data_b; - -static int bfin_pix_abs16_x2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - ff_bfin_put_pixels16uc (vtmp_blk, blk2, blk2+1, 16, line_size, h); - return ff_bfin_z_sad16x16 (blk1, vtmp_blk, line_size, 16, h); -} - -static int bfin_pix_abs16_y2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - ff_bfin_put_pixels16uc (vtmp_blk, blk2, blk2+line_size, 16, line_size, h); - return ff_bfin_z_sad16x16 (blk1, vtmp_blk, line_size, 16, h); -} - -static int bfin_pix_abs16_xy2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - ff_bfin_z_put_pixels16_xy2 (vtmp_blk, blk2, 16, line_size, h); - return ff_bfin_z_sad16x16 (blk1, vtmp_blk, line_size, 16, h); -} - -static int bfin_pix_abs8 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - return ff_bfin_z_sad8x8 (blk1,blk2,line_size,line_size, h); -} - -static int bfin_pix_abs8_x2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - ff_bfin_put_pixels8uc (vtmp_blk, blk2, blk2+1, 8, line_size, h); - return ff_bfin_z_sad8x8 (blk1, vtmp_blk, line_size, 8, h); -} - -static int bfin_pix_abs8_y2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - ff_bfin_put_pixels8uc (vtmp_blk, blk2, blk2+line_size, 8, line_size, h); - return ff_bfin_z_sad8x8 (blk1, vtmp_blk, line_size, 8, h); -} - -static int bfin_pix_abs8_xy2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) -{ - ff_bfin_z_put_pixels8_xy2 (vtmp_blk, blk2, 8, line_size, h); - return ff_bfin_z_sad8x8 (blk1, vtmp_blk, line_size, 8, h); -} - - -/* - decoder optimization - start on 2/11 100 frames of 352x240@25 compiled with no optimization -g debugging - 9.824s ~ 2.44x off - 6.360s ~ 1.58x off with -O2 - 5.740s ~ 1.43x off with idcts - - 2.64s 2/20 same sman.mp4 decode only - -*/ - -void dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx ) -{ - c->get_pixels = ff_bfin_get_pixels; - c->diff_pixels = ff_bfin_diff_pixels; - c->put_pixels_clamped = ff_bfin_put_pixels_clamped; - c->add_pixels_clamped = ff_bfin_add_pixels_clamped; - - c->clear_blocks = bfin_clear_blocks; - c->pix_sum = ff_bfin_pix_sum; - c->pix_norm1 = ff_bfin_pix_norm1; - - c->sad[0] = bfin_pix_abs16; - c->sad[1] = bfin_pix_abs8; - -/* c->vsad[0] = bfin_vsad; */ -/* c->vsad[4] = bfin_vsad_intra16; */ - - /* TODO [0] 16 [1] 8 */ - c->pix_abs[0][0] = bfin_pix_abs16; - c->pix_abs[0][1] = bfin_pix_abs16_x2; - c->pix_abs[0][2] = bfin_pix_abs16_y2; - c->pix_abs[0][3] = bfin_pix_abs16_xy2; - - c->pix_abs[1][0] = bfin_pix_abs8; - c->pix_abs[1][1] = bfin_pix_abs8_x2; - c->pix_abs[1][2] = bfin_pix_abs8_y2; - c->pix_abs[1][3] = bfin_pix_abs8_xy2; - - - c->sse[0] = ff_bfin_sse16; - c->sse[1] = ff_bfin_sse8; - c->sse[2] = ff_bfin_sse4; - - - /** - * 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 where the result is stored - * @param pixels source - * @param line_size number of bytes in a horizontal line of block - * @param h height - */ - - c->put_pixels_tab[0][0] = bfin_put_pixels16; - c->put_pixels_tab[0][1] = bfin_put_pixels16_x2; - c->put_pixels_tab[0][2] = bfin_put_pixels16_y2; - c->put_pixels_tab[0][3] = bfin_put_pixels16_xy2; - - c->put_pixels_tab[1][0] = bfin_put_pixels8; - c->put_pixels_tab[1][1] = bfin_put_pixels8_x2; - c->put_pixels_tab[1][2] = bfin_put_pixels8_y2; - c->put_pixels_tab[1][3] = bfin_put_pixels8_xy2; - - c->put_no_rnd_pixels_tab[1][0] = bfin_put_pixels8_nornd; - c->put_no_rnd_pixels_tab[1][1] = bfin_put_pixels8_x2_nornd; - c->put_no_rnd_pixels_tab[1][2] = bfin_put_pixels8_y2_nornd; -/* c->put_no_rnd_pixels_tab[1][3] = ff_bfin_put_pixels8_xy2_nornd; */ - - c->put_no_rnd_pixels_tab[0][0] = bfin_put_pixels16_nornd; - c->put_no_rnd_pixels_tab[0][1] = bfin_put_pixels16_x2_nornd; - c->put_no_rnd_pixels_tab[0][2] = bfin_put_pixels16_y2_nornd; -/* c->put_no_rnd_pixels_tab[0][3] = ff_bfin_put_pixels16_xy2_nornd; */ - - if (avctx->dct_algo == FF_DCT_AUTO) - c->fdct = ff_bfin_fdct; - - if (avctx->idct_algo==FF_IDCT_VP3) { - c->idct_permutation_type = FF_NO_IDCT_PERM; - c->idct = ff_bfin_vp3_idct; - c->idct_add = ff_bfin_vp3_idct_add; - c->idct_put = ff_bfin_vp3_idct_put; - } else if (avctx->idct_algo == FF_IDCT_AUTO) { - c->idct_permutation_type = FF_NO_IDCT_PERM; - c->idct = ff_bfin_idct; - c->idct_add = bfin_idct_add; - c->idct_put = bfin_idct_put; - } -} - - - diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h b/tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h deleted file mode 100644 index 7edcf97..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * BlackFin DSPUTILS COMMON OPTIMIZATIONS HEADER - * - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef AVCODEC_BFIN_DSPUTIL_BFIN_H -#define AVCODEC_BFIN_DSPUTIL_BFIN_H - -#include "config.h" -#include "libavcodec/dsputil.h" - -#if defined(__FDPIC__) && CONFIG_SRAM -#define attribute_l1_text __attribute__ ((l1_text)) -#define attribute_l1_data_b __attribute__((l1_data_B)) -#else -#define attribute_l1_text -#define attribute_l1_data_b -#endif - -void ff_bfin_idct (DCTELEM *block) attribute_l1_text; -void ff_bfin_fdct (DCTELEM *block) attribute_l1_text; -void ff_bfin_vp3_idct (DCTELEM *block); -void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block); -void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block); -void ff_bfin_add_pixels_clamped (const DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text; -void ff_bfin_put_pixels_clamped (const DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text; -void ff_bfin_diff_pixels (DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride) attribute_l1_text; -void ff_bfin_get_pixels (DCTELEM *restrict block, const uint8_t *pixels, int line_size) attribute_l1_text; -int ff_bfin_pix_norm1 (uint8_t * pix, int line_size) attribute_l1_text; -int ff_bfin_z_sad8x8 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text; -int ff_bfin_z_sad16x16 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text; - -void ff_bfin_z_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text; -void ff_bfin_z_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text; -void ff_bfin_put_pixels16_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text; -void ff_bfin_put_pixels8_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text; - - -int ff_bfin_pix_sum (uint8_t *p, int stride) attribute_l1_text; - -void ff_bfin_put_pixels8uc (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text; -void ff_bfin_put_pixels16uc (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text; -void ff_bfin_put_pixels8uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text; -void ff_bfin_put_pixels16uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text; - -int ff_bfin_sse4 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text; -int ff_bfin_sse8 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text; -int ff_bfin_sse16 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text; - - -#ifdef BFIN_PROFILE - -static double Telem[16]; -static char *TelemNames[16]; -static int TelemCnt; - -#define PROF(lab,e) { int xx_e = e; char*xx_lab = lab; uint64_t xx_t0 = read_time(); -#define EPROF() xx_t0 = read_time()-xx_t0; Telem[xx_e] = Telem[xx_e] + xx_t0; TelemNames[xx_e] = xx_lab; } - -static void prof_report (void) -{ - int i; - double s = 0; - for (i=0;i<16;i++) { - double v; - if (TelemNames[i]) { - v = Telem[i]/TelemCnt; - av_log (NULL,AV_LOG_DEBUG,"%-20s: %12.4f\t%12.4f\n", TelemNames[i],v,v/64); - s = s + Telem[i]; - } - } - av_log (NULL,AV_LOG_DEBUG,"%-20s: %12.4f\t%12.4f\n%20.4f\t%d\n", - "total",s/TelemCnt,s/TelemCnt/64,s,TelemCnt); -} - -static void bfprof (void) -{ - static int init; - if (!init) atexit (prof_report); - init=1; - TelemCnt++; -} - -#else -#define PROF(a,b) -#define EPROF() -#define bfprof() -#endif - -#endif /* AVCODEC_BFIN_DSPUTIL_BFIN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/fdct_bfin.S b/tizen/distrib/ffmpeg/libavcodec/bfin/fdct_bfin.S deleted file mode 100644 index 0eac7a3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/fdct_bfin.S +++ /dev/null @@ -1,333 +0,0 @@ -/* - * fdct BlackFin - * - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - void ff_bfin_fdct (DCTELEM *buf); - - This implementation works only for 8x8 input. The range of input - must be -256 to 255 i.e. 8bit input represented in a 16bit data - word. The original data must be sign extended into the 16bit data - words. - - - Chen factorization of - - 8 - X(m) = sum (x(n) * cos ((2n+1)*m*pi/16)) - n=0 - - C4 - 0 --*-------------*0+7---*-----*0+3-------*-*-------------------> 0 - \ / \ / X S4,S4 - 1 --*-\---------/-*1+6---*-\-/-*1+2-------*-*-------------------> 4 - \ / \ -C4 C3 - 2 --*---\-----/---*2+5---*-/-\-*1-2---------------*-*-----------> 2 - \ / / \ X S3,-S3 - 3 --*-----\-/-----*3+4---*-----*0-3---------------*-*-----------> 6 - / C7 C3 - 4 --*-----/-\-----*3-4------------*-*4+5--*-----*---------------> 1 - / \ -C4 X \ /S7 C3 - 5 --*---/-----\---*2-5---*-*------*=*4-5----\-/------*-*--------> 5 - / \ X S4,S4 / X S3,-S3 - 6 --*-/---------\-*1-6---*-*------*=*7-6----/-\------*-*--------> 3 - / \ C4 X / \-S7 C3 - --*-------------*0-7------------*-*7+6--*-----*---------------> 7 - C7 - -Notation - Cn = cos(n*pi/8) used throughout the code. - - - Registers used: - R0, R1, R2, R3, R4, R5, R6,R7, P0, P1, P2, P3, P4, P5, A0, A1. - Other registers used: - I0, I1, I2, I3, B0, B2, B3, M0, M1, L3 registers and LC0. - - Input - r0 - pointer to start of DCTELEM *block - - Output - The DCT output coefficients in the DCTELEM *block - - Register constraint: - This code is called from jpeg_encode. - R6, R5, R4 if modified should be stored and restored. - - - Performance: (Timer version 0.6.33) - Code Size : 240 Bytes. - Memory Required : - Input Matrix : 8 * 8 * 2 Bytes. - Coefficients : 16 Bytes - Temporary matrix: 8 * 8 * 2 Bytes. - Cycle Count :26+{18+8*(14+2S)}*2 where S -> Stalls - (7.45 c/pel) - ----------------------------------------- - | Size | Forward DCT | Inverse DCT | - ----------------------------------------- - | 8x8 | 284 Cycles | 311 Cycles | - ----------------------------------------- - -Ck = int16(cos(k/16*pi)*32767+.5)/2 -#define C4 23170 -#define C3 13623 -#define C6 6270 -#define C7 3196 - -Sk = int16(sin(k/16*pi)*32767+.5)/2 -#define S4 11585 -#define S3 9102 -#define S6 15137 -#define S7 16069 - -the coefficients are ordered as follows: -short dct_coef[] - C4,S4, - C6,S6, - C7,S7, - S3,C3, - ------------------------------------------------------------ -FFMPEG conformance testing results ------------------------------------------------------------ -dct-test: modified with the following - dct_error("BFINfdct", 0, ff_bfin_fdct, fdct, test); -produces the following output: - -root:/u/ffmpeg/bhead/libavcodec> ./dct-test -ffmpeg DCT/IDCT test - - 2 -131 -6 -48 -36 33 -83 24 - 34 52 -24 -15 5 92 57 143 - -67 -43 -1 74 -16 5 -71 32 - -78 106 92 -34 -38 81 20 -18 - 7 -62 40 2 -15 90 -62 -83 - -83 1 -104 -13 43 -19 7 11 - -63 31 12 -29 83 72 21 10 - -17 -63 -15 73 50 -91 159 -14 -DCT BFINfdct: err_inf=2 err2=0.16425938 syserr=0.00795000 maxout=2098 blockSumErr=27 -DCT BFINfdct: 92.1 kdct/s -root:/u/ffmpeg/bhead/libavcodec> - -*/ - -#include "config.h" -#include "config_bfin.h" - -#if defined(__FDPIC__) && CONFIG_SRAM -.section .l1.data.B,"aw",@progbits -#else -.data -#endif -.align 4; -dct_coeff: -.short 0x5a82, 0x2d41, 0x187e, 0x3b21, 0x0c7c, 0x3ec5, 0x238e, 0x3537; - -#if defined(__FDPIC__) && CONFIG_SRAM -.section .l1.data.A,"aw",@progbits -#endif -.align 4 -vtmp: .space 128 - -.text -DEFUN(fdct,mL1, - (DCTELEM *block)): - [--SP] = (R7:4, P5:3); // Push the registers onto the stack. - - b0 = r0; - RELOC(r0, P3, dct_coeff); - b3 = r0; - RELOC(r0, P3, vtmp); - b2 = r0; - - L3 = 16; // L3 is set to 16 to make the coefficient - // array Circular. - - -//---------------------------------------------------------------------------- - -/* - * I0, I1, and I2 registers are used to read the input data. I3 register is used - * to read the coefficients. P0 and P1 registers are used for writing the output - * data. - */ - M0 = 12 (X); // All these initializations are used in the - M1 = 16 (X); // modification of address offsets. - - M2 = 128 (X); - - P2 = 16; - P3 = 32 (X); - P4 = -110 (X); - P5 = -62 (X); - P0 = 2(X); - - - // Prescale the input to get the correct precision. - i0=b0; - i1=b0; - - lsetup (.0, .1) LC0 = P3; - r0=[i0++]; -.0: r1=r0<<3 (v) || r0=[i0++] ; -.1: [i1++]=r1; - - /* - * B0 points to the "in" buffer. - * B2 points to "temp" buffer in the first iteration. - */ - - lsetup (.2, .3) LC0 = P0; -.2: - I0 = B0; // I0 points to Input Element (0, 0). - I1 = B0; // Element 1 and 0 is read in R0. - I1 += M0 || R0 = [I0++]; // I1 points to Input Element (0, 6). - I2 = I1; // Element 6 is read into R3.H. - I2 -= 4 || R3.H = W[I1++]; // I2 points to Input Element (0, 4). - - I3 = B3; // I3 points to Coefficients. - P0 = B2; // P0 points to temporary array Element - // (0, 0). - P1 = B2; // P1 points to temporary array. - R7 = [P1++P2] || R2 = [I2++]; // P1 points to temporary array - // Element (1, 0). - // R7 is a dummy read. X4,X5 - // are read into R2. - R3.L = W[I1--]; // X7 is read into R3.L. - R1.H = W[I0++]; // X2 is read into R1.H. - - - /* - * X0 = (X0 + X7) / 2. - * X1 = (X1 + X6) / 2. - * X6 = (X1 - X6) / 2. - * X7 = (X0 - X7) / 2. - * It reads the data 3 in R1.L. - */ - - R0 = R0 +|+ R3, R3 = R0 -|- R3 || R1.L = W[I0++] || NOP; - - /* - * X2 = (X2 + X5) / 2. - * X3 = (X3 + X4) / 2. - * X4 = (X3 - X4) / 2. - * X5 = (X2 - X5) / 2. - * R7 = C4 = cos(4*pi/16) - */ - - R1 = R1 +|+ R2, R2 = R1 -|- R2 (CO) || NOP || R7 = [I3++]; - - /* - * At the end of stage 1 R0 has (1,0), R1 has (2,3), R2 has (4, 5) and - * R3 has (6,7). - * Where the notation (x, y) represents uper/lower half pairs. - */ - - /* - * X0 = X0 + X3. - * X1 = X1 + X2. - * X2 = X1 - X2. - * X3 = X0 - X3. - */ - R0 = R0 +|+ R1, R1 = R0 -|- R1; - - lsetup (.row0, .row1) LC1 = P2 >> 1; // 1d dct, loops 8x -.row0: - - /* - * This is part 2 computation continued..... - * A1 = X6 * cos(pi/4) - * A0 = X6 * cos(pi/4) - * A1 = A1 - X5 * cos(pi/4) - * A0 = A0 + X5 * cos(pi/4). - * The instruction W[I0] = R3.L is used for packing it to R2.L. - */ - - A1=R3.H*R7.l, A0=R3.H*R7.l || I1+=M1 || W[I0] = R3.L; - R4.H=(A1-=R2.L*R7.l), R4.L=(A0+=R2.L*R7.l) || I2+=M0 || NOP; - - /* R0 = (X1,X0) R1 = (X2,X3) R4 = (X5, X6). */ - - /* - * A1 = X0 * cos(pi/4) - * A0 = X0 * cos(pi/4) - * A1 = A1 - X1 * cos(pi/4) - * A0 = A0 + X1 * cos(pi/4) - * R7 = (C2,C6) - */ - A1=R0.L*R7.h, A0=R0.L*R7.h || NOP || R3.H=W[I1++]; - R5.H=(A1-=R0.H*R7.h),R5.L=(A0+=R0.H*R7.h) || R7=[I3++] || NOP; - - /* - * A1 = X2 * cos(3pi/8) - * A0 = X3 * cos(3pi/8) - * A1 = A1 + X3 * cos(pi/8) - * A0 = A0 - X2 * cos(pi/8) - * R3 = cos(pi/4) - * R7 = (cos(7pi/8),cos(pi/8)) - * X4 = X4 + X5. - * X5 = X4 - X5. - * X6 = X7 - X6. - * X7 = X7 + X6. - */ - A1=R1.H*R7.L, A0=R1.L*R7.L || W[P0++P3]=R5.L || R2.L=W[I0]; - R2=R2+|+R4, R4=R2-|-R4 || I0+=4 || R3.L=W[I1--]; - R6.H=(A1+=R1.L*R7.H),R6.L=(A0 -= R1.H * R7.H) || I0+=4 || R7=[I3++]; - - /* R2 = (X4, X7) R4 = (X5,X6) R5 = (X1, X0) R6 = (X2,X3). */ - - /* - * A1 = X4 * cos(7pi/16) - * A0 = X7 * cos(7pi/16) - * A1 = A1 + X7 * cos(pi/16) - * A0 = A0 - X4 * cos(pi/16) - */ - - A1=R2.H*R7.L, A0=R2.L*R7.L || W[P0++P3]=R6.H || R0=[I0++]; - R2.H=(A1+=R2.L*R7.H),R2.L=(A0-=R2.H*R7.H) || W[P0++P3]=R5.H || R7=[I3++]; - - /* - * A1 = X5 * cos(3pi/16) - * A0 = X6 * cos(3pi/16) - * A1 = A1 + X6 * cos(5pi/16) - * A0 = A0 - X5 * cos(5pi/16) - * The output values are written. - */ - - A1=R4.H*R7.H, A0=R4.L*R7.H || W[P0++P2]=R6.L || R1.H=W[I0++]; - R4.H=(A1+=R4.L*R7.L),R4.L=(A0-=R4.H*R7.L) || W[P0++P4]=R2.L || R1.L=W[I0++]; - - - /* Beginning of next stage, **pipelined** + drain and store the - rest of the column store. */ - - R0=R0+|+R3,R3=R0-|-R3 || W[P1++P3]=R2.H || R2=[I2++]; - R1=R1+|+R2,R2=R1-|-R2 (CO) || W[P1++P3]=R4.L || R7=[I3++]; -.row1: R0=R0+|+R1,R1=R0-|-R1 || W[P1++P5]=R4.H || NOP; - - // Exchange input with output. - B1 = B0; - B0 = B2; -.3: B2 = B1; - - L3=0; - (r7:4,p5:3) = [sp++]; - RTS; -DEFUN_END(fdct) - diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/idct_bfin.S b/tizen/distrib/ffmpeg/libavcodec/bfin/idct_bfin.S deleted file mode 100644 index 04f9159..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/idct_bfin.S +++ /dev/null @@ -1,306 +0,0 @@ -/* - * idct BlackFin - * - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - This blackfin DSP code implements an 8x8 inverse type II DCT. - -Prototype : void ff_bfin_idct(DCTELEM *in) - -Registers Used : A0, A1, R0-R7, I0-I3, B0, B2, B3, M0-M2, L0-L3, P0-P5, LC0. - -Performance : - Code Size : 498 Bytes. - Cycle Count : 417 Cycles - - ------------------------------------------------------------ -FFMPEG conformance testing results ------------------------------------------------------------ - -dct-test: modified with the following - dct_error("BFINidct", 1, ff_bfin_idct, idct, test); -produces the following output - -root:/u/ffmpeg/bhead/libavcodec> ./dct-test -i -ffmpeg DCT/IDCT test - - 8 15 -2 21 24 17 0 10 - 2 -10 -5 -5 -3 7 -14 -3 - 2 -13 -10 -19 18 -6 6 -2 - 9 4 16 -3 9 12 10 15 - 15 -9 -2 10 1 16 0 -15 - -15 5 7 3 13 0 13 20 - -6 -15 24 9 -18 1 9 -22 - -8 25 23 2 -7 0 30 13 -IDCT BFINidct: err_inf=1 err2=0.01002344 syserr=0.00150000 maxout=266 blockSumErr=64 -IDCT BFINidct: 88.3 kdct/s - -*/ - -#include "config.h" -#include "config_bfin.h" - -#if defined(__FDPIC__) && CONFIG_SRAM -.section .l1.data.B,"aw",@progbits -#else -.data -#endif - -.align 4; -coefs: -.short 0x5a82; // C4 -.short 0x5a82; // C4 -.short 0x30FC; //cos(3pi/8) C6 -.short 0x7642; //cos(pi/8) C2 -.short 0x18F9; //cos(7pi/16) -.short 0x7D8A; //cos(pi/16) -.short 0x471D; //cos(5pi/16) -.short 0x6A6E; //cos(3pi/16) -.short 0x18F9; //cos(7pi/16) -.short 0x7D8A; //cos(pi/16) - -#if defined(__FDPIC__) && CONFIG_SRAM -.section .l1.data.A,"aw",@progbits -#endif - -vtmp: .space 256 - -#define TMP0 FP-8 -#define TMP1 FP-12 -#define TMP2 FP-16 - - -.text -DEFUN(idct,mL1, - (DCTELEM *block)): - -/********************** Function Prologue *********************************/ - link 16; - [--SP] = (R7:4, P5:3); // Push the registers onto the stack. - B0 = R0; // Pointer to Input matrix - RELOC(R1, P3, coefs); // Pointer to Coefficients - RELOC(R2, P3, vtmp); // Pointer to Temporary matrix - B3 = R1; - B2 = R2; - L3 = 20; // L3 is used for making the coefficient array - // circular. - // MUST BE RESTORED TO ZERO at function exit. - M1 = 16 (X); // All these registers are initialized for - M3 = 8(X); // modifying address offsets. - - I0 = B0; // I0 points to Input Element (0, 0). - I2 = B0; // I2 points to Input Element (0, 0). - I2 += M3 || R0.H = W[I0]; - // Element 0 is read into R0.H - I1 = I2; // I1 points to input Element (0, 6). - I1 += 4 || R0.L = W[I2++]; - // I2 points to input Element (0, 4). - // Element 4 is read into R0.L. - P2 = 8 (X); - P3 = 32 (X); - P4 = -32 (X); - P5 = 98 (X); - R7 = 0x8000(Z); - I3 = B3; // I3 points to Coefficients - P0 = B2; // P0 points to array Element (0, 0) of temp - P1 = B2; - R7 = [I3++] || [TMP2]=R7; // Coefficient C4 is read into R7.H and R7.L. - MNOP; - NOP; - - /* - * A1 = Y0 * cos(pi/4) - * A0 = Y0 * cos(pi/4) - * A1 = A1 + Y4 * cos(pi/4) - * A0 = A0 - Y4 * cos(pi/4) - * load: - * R1=(Y2,Y6) - * R7=(C2,C6) - * res: - * R3=Y0, R2=Y4 - */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || I0+= 4 || R1.L=W[I1++]; - R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || R1.H=W[I0--] || R7=[I3++]; - - LSETUP (.0, .1) LC0 = P2; // perform 8 1d idcts - - P2 = 112 (X); - P1 = P1 + P2; // P1 points to element (7, 0) of temp buffer. - P2 = -94(X); - -.0: - /* - * A1 = Y2 * cos(3pi/8) - * A0 = Y2 * cos(pi/8) - * A1 = A1 - Y6 * cos(pi/8) - * A0 = A0 + Y6 * cos(3pi/8) - * R5 = (Y1,Y7) - * R7 = (C1,C7) - * res: - * R1=Y2, R0=Y6 - */ - A1=R7.L*R1.H, A0=R7.H*R1.H (IS) || I0+=4 || R5.H=W[I0]; - R1=(A1-=R7.H*R1.L), R0=(A0+=R7.L*R1.L) (IS) || R5.L=W[I1--] || R7=[I3++]; - /* - * Y0 = Y0 + Y6. - * Y4 = Y4 + Y2. - * Y2 = Y4 - Y2. - * Y6 = Y0 - Y6. - * R3 is saved - * R6.l=Y3 - * note: R3: Y0, R2: Y4, R1: Y2, R0: Y6 - */ - R3=R3+R0, R0=R3-R0; - R2=R2+R1, R1=R2-R1 || [TMP0]=R3 || R6.L=W[I0--]; - /* - * Compute the odd portion (1,3,5,7) even is done. - * - * Y1 = C7 * Y1 - C1 * Y7 + C3 * Y5 - C5 * Y3. - * Y7 = C1 * Y1 + C7 * Y7 + C5 * Y5 + C3 * Y3. - * Y5 = C5 * Y1 + C3 * Y7 + C7 * Y5 - C1 * Y3. - * Y3 = C3 * Y1 - C5 * Y7 - C1 * Y5 - C7 * Y3. - */ - // R5=(Y1,Y7) R6=(Y5,Y3) // R7=(C1,C7) - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || [TMP1]=R2 || R6.H=W[I2--]; - A1-=R7.H*R5.L, A0+=R7.L*R5.L (IS) || I0-=4 || R7=[I3++]; - A1+=R7.H*R6.H, A0+=R7.L*R6.H (IS) || I0+=M1; // R7=(C3,C5) - R3 =(A1-=R7.L*R6.L), R2 =(A0+=R7.H*R6.L) (IS); - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || R4=[TMP0]; - A1+=R7.H*R5.L, A0-=R7.L*R5.L (IS) || I1+=M1 || R7=[I3++]; // R7=(C1,C7) - A1+=R7.L*R6.H, A0-=R7.H*R6.H (IS); - R7 =(A1-=R7.H*R6.L), R6 =(A0-=R7.L*R6.L) (IS) || I2+=M1; - // R3=Y1, R2=Y7, R7=Y5, R6=Y3 - - /* Transpose write column. */ - R5.H=R4+R2 (RND12); // Y0=Y0+Y7 - R5.L=R4-R2 (RND12) || R4 = [TMP1]; // Y7=Y7-Y0 - R2.H=R1+R7 (RND12) || W[P0++P3]=R5.H; // Y2=Y2+Y5 st Y0 - R2.L=R1-R7 (RND12) || W[P1++P4]=R5.L || R7=[I3++]; // Y5=Y2-Y5 st Y7 - R5.H=R0-R3 (RND12) || W[P0++P3]=R2.H || R1.L=W[I1++]; // Y1=Y6-Y1 st Y2 - R5.L=R0+R3 (RND12) || W[P1++P4]=R2.L || R0.H=W[I0++]; // Y6=Y6+Y1 st Y5 - R3.H=R4-R6 (RND12) || W[P0++P3]=R5.H || R0.L=W[I2++]; // Y3=Y3-Y4 st Y1 - R3.L=R4+R6 (RND12) || W[P1++P4]=R5.L || R1.H=W[I0++]; // Y4=Y3+Y4 st Y6 - - /* pipeline loop start, + drain Y3, Y4 */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || W[P0++P2]= R3.H || R1.H = W[I0--]; -.1: R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || W[P1++P5]= R3.L || R7 = [I3++]; - - - - I0 = B2; // I0 points to Input Element (0, 0) - I2 = B2; // I2 points to Input Element (0, 0) - I2 += M3 || R0.H = W[I0]; - // Y0 is read in R0.H - I1 = I2; // I1 points to input Element (0, 6) - I1 += 4 || R0.L = W[I2++]; - // I2 points to input Element (0, 4) - // Y4 is read in R0.L - P2 = 8 (X); - I3 = B3; // I3 points to Coefficients - P0 = B0; // P0 points to array Element (0, 0) for writing - // output - P1 = B0; - R7 = [I3++]; // R7.H = C4 and R7.L = C4 - NOP; - - /* - * A1 = Y0 * cos(pi/4) - * A0 = Y0 * cos(pi/4) - * A1 = A1 + Y4 * cos(pi/4) - * A0 = A0 - Y4 * cos(pi/4) - * load: - * R1=(Y2,Y6) - * R7=(C2,C6) - * res: - * R3=Y0, R2=Y4 - */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || I0+=4 || R1.L=W[I1++]; - R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || R1.H=W[I0--] || R7=[I3++]; - - LSETUP (.2, .3) LC0 = P2; // peform 8 1d idcts - P2 = 112 (X); - P1 = P1 + P2; - P2 = -94(X); - -.2: - /* - * A1 = Y2 * cos(3pi/8) - * A0 = Y2 * cos(pi/8) - * A1 = A1 - Y6 * cos(pi/8) - * A0 = A0 + Y6 * cos(3pi/8) - * R5 = (Y1,Y7) - * R7 = (C1,C7) - * res: - * R1=Y2, R0=Y6 - */ - A1=R7.L*R1.H, A0=R7.H*R1.H (IS) || I0+=4 || R5.H=W[I0]; - R1=(A1-=R7.H*R1.L), R0=(A0+=R7.L*R1.L) (IS) || R5.L=W[I1--] || R7=[I3++]; - /* - * Y0 = Y0 + Y6. - * Y4 = Y4 + Y2. - * Y2 = Y4 - Y2. - * Y6 = Y0 - Y6. - * R3 is saved - * R6.l=Y3 - * note: R3: Y0, R2: Y4, R1: Y2, R0: Y6 - */ - R3=R3+R0, R0=R3-R0; - R2=R2+R1, R1=R2-R1 || [TMP0]=R3 || R6.L=W[I0--]; - /* - * Compute the odd portion (1,3,5,7) even is done. - * - * Y1 = C7 * Y1 - C1 * Y7 + C3 * Y5 - C5 * Y3. - * Y7 = C1 * Y1 + C7 * Y7 + C5 * Y5 + C3 * Y3. - * Y5 = C5 * Y1 + C3 * Y7 + C7 * Y5 - C1 * Y3. - * Y3 = C3 * Y1 - C5 * Y7 - C1 * Y5 - C7 * Y3. - */ - // R5=(Y1,Y7) R6=(Y5,Y3) // R7=(C1,C7) - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || [TMP1]=R2 || R6.H=W[I2--]; - A1-=R7.H*R5.L, A0+=R7.L*R5.L (IS) || I0-=4 || R7=[I3++]; - A1+=R7.H*R6.H, A0+=R7.L*R6.H (IS) || I0+=M1; // R7=(C3,C5) - R3 =(A1-=R7.L*R6.L), R2 =(A0+=R7.H*R6.L) (IS); - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || R4=[TMP0]; - A1+=R7.H*R5.L, A0-=R7.L*R5.L (IS) || I1+=M1 || R7=[I3++]; // R7=(C1,C7) - A1+=R7.L*R6.H, A0-=R7.H*R6.H (IS); - R7 =(A1-=R7.H*R6.L), R6 =(A0-=R7.L*R6.L) (IS) || I2+=M1; - // R3=Y1, R2=Y7, R7=Y5, R6=Y3 - - /* Transpose write column. */ - R5.H=R4+R2 (RND20); // Y0=Y0+Y7 - R5.L=R4-R2 (RND20) || R4 = [TMP1]; // Y7=Y7-Y0 - R2.H=R1+R7 (RND20) || W[P0++P3]=R5.H; // Y2=Y2+Y5 st Y0 - R2.L=R1-R7 (RND20) || W[P1++P4]=R5.L || R7=[I3++]; // Y5=Y2-Y5 st Y7 - R5.H=R0-R3 (RND20) || W[P0++P3]=R2.H || R1.L=W[I1++]; // Y1=Y6-Y1 st Y2 - R5.L=R0+R3 (RND20) || W[P1++P4]=R2.L || R0.H=W[I0++]; // Y6=Y6+Y1 st Y5 - R3.H=R4-R6 (RND20) || W[P0++P3]=R5.H || R0.L=W[I2++]; // Y3=Y3-Y4 st Y1 - R3.L=R4+R6 (RND20) || W[P1++P4]=R5.L || R1.H=W[I0++]; // Y4=Y3+Y4 st Y6 - - /* pipeline loop start, + drain Y3, Y4 */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || W[P0++P2]= R3.H || R1.H = W[I0--]; -.3: R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || W[P1++P5]= R3.L || R7 = [I3++]; - - L3 = 0; - (R7:4,P5:3)=[SP++]; - unlink; - RTS; -DEFUN_END(idct) - - diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/mathops.h b/tizen/distrib/ffmpeg/libavcodec/bfin/mathops.h deleted file mode 100644 index a0e808c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/mathops.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * simple math operations - * - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVCODEC_BFIN_MATHOPS_H -#define AVCODEC_BFIN_MATHOPS_H - -#include "config.h" - -#if CONFIG_MPEGAUDIO_HP -#define MULH(X,Y) ({ int xxo; \ - __asm__ ( \ - "a1 = %2.L * %1.L (FU);\n\t" \ - "a1 = a1 >> 16;\n\t" \ - "a1 += %2.H * %1.L (IS,M);\n\t" \ - "a0 = %1.H * %2.H, a1+= %1.H * %2.L (IS,M);\n\t"\ - "a1 = a1 >>> 16;\n\t" \ - "%0 = (a0 += a1);\n\t" \ - : "=d" (xxo) : "d" (X), "d" (Y) : "A0","A1"); xxo; }) -#else -#define MULH(X,Y) ({ int xxo; \ - __asm__ ( \ - "a1 = %2.H * %1.L (IS,M);\n\t" \ - "a0 = %1.H * %2.H, a1+= %1.H * %2.L (IS,M);\n\t"\ - "a1 = a1 >>> 16;\n\t" \ - "%0 = (a0 += a1);\n\t" \ - : "=d" (xxo) : "d" (X), "d" (Y) : "A0","A1"); xxo; }) -#endif - -/* signed 16x16 -> 32 multiply */ -#define MUL16(a, b) ({ int xxo; \ - __asm__ ( \ - "%0 = %1.l*%2.l (is);\n\t" \ - : "=W" (xxo) : "d" (a), "d" (b) : "A1"); \ - xxo; }) - -#endif /* AVCODEC_BFIN_MATHOPS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/mpegvideo_bfin.c b/tizen/distrib/ffmpeg/libavcodec/bfin/mpegvideo_bfin.c deleted file mode 100644 index 0373e22..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/mpegvideo_bfin.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * BlackFin MPEGVIDEO OPTIMIZATIONS - * - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" -#include "dsputil_bfin.h" - -static int dct_quantize_bfin (MpegEncContext *s, - DCTELEM *block, int n, - int qscale, int *overflow) -{ - int last_non_zero, q, start_i; - const short *qmat; - short *bias; - const uint8_t *scantable= s->intra_scantable.scantable; - short dc; - int max=0; - - PROF("fdct",0); - s->dsp.fdct(block); - EPROF(); - - PROF("denoise",1); - if(s->dct_error_sum) - s->denoise_dct(s, block); - EPROF(); - - PROF("quant-init",2); - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - q = q << 3; - } else - /* For AIC we skip quant/dequant of INTRADC */ - q = 1 << 3; - - /* note: block[0] is assumed to be positive */ - dc = block[0] = (block[0] + (q >> 1)) / q; - start_i = 1; - last_non_zero = 0; - bias = s->q_intra_matrix16[qscale][1]; - qmat = s->q_intra_matrix16[qscale][0]; - - } else { - start_i = 0; - last_non_zero = -1; - bias = s->q_inter_matrix16[qscale][1]; - qmat = s->q_inter_matrix16[qscale][0]; - - } - EPROF(); - - PROF("quantize",4); - - /* for(i=start_i; i<64; i++) { */ - /* sign = (block[i]>>15)|1; */ - /* level = ((abs(block[i])+bias[0])*qmat[i])>>16; */ - /* if (level < 0) level = 0; */ - /* max |= level; */ - /* level = level * sign; */ - /* block[i] = level; */ - /* } */ - - __asm__ volatile - ("i2=%1;\n\t" - "r1=[%1++]; \n\t" - "r0=r1>>>15 (v); \n\t" - "lsetup (0f,1f) lc0=%3; \n\t" - "0: r0=r0|%4; \n\t" - " r1=abs r1 (v) || r2=[%2++];\n\t" - " r1=r1+|+%5; \n\t" - " r1=max(r1,%6) (v); \n\t" - " r1.h=(a1 =r1.h*r2.h), r1.l=(a0 =r1.l*r2.l) (tfu); \n\t" - " %0=%0|r1; \n\t" - " r0.h=(a1 =r1.h*r0.h), r0.l=(a0 =r1.l*r0.l) (is) || r1=[%1++];\n\t" - "1: r0=r1>>>15 (v) || [i2++]=r0;\n\t" - "r1=%0>>16; \n\t" - "%0=%0|r1; \n\t" - "%0.h=0; \n\t" - : "=&d" (max) - : "b" (block), "b" (qmat), "a" (32), "d" (0x00010001), "d" (bias[0]*0x10001), "d" (0) - : "R0","R1","R2", "I2"); - if (start_i == 1) block[0] = dc; - - EPROF(); - - - PROF("zzscan",5); - - __asm__ volatile - ("r0=b[%1--] (x); \n\t" - "lsetup (0f,1f) lc0=%3; \n\t" /* for(i=63; i>=start_i; i--) { */ - "0: p0=r0; \n\t" /* j = scantable[i]; */ - " p0=%2+(p0<<1); \n\t" /* if (block[j]) { */ - " r0=w[p0]; \n\t" /* last_non_zero = i; */ - " cc=r0==0; \n\t" /* break; */ - " if !cc jump 2f; \n\t" /* } */ - "1: r0=b[%1--] (x); \n\t" /* } */ - " %0=%4; \n\t" - " jump 3f; \n\t" - "2: %0=lc0; \n\t" - "3:\n\t" - - : "=d" (last_non_zero) - : "a" (scantable+63), "a" (block), "a" (63), "d" (last_non_zero) - : "P0","R0"); - - EPROF(); - - *overflow= s->max_qcoeff < max; //overflow might have happened - - bfprof(); - - /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ - if (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM) - ff_block_permute(block, s->dsp.idct_permutation, scantable, last_non_zero); - - return last_non_zero; -} - -void MPV_common_init_bfin (MpegEncContext *s) -{ -/* s->dct_quantize= dct_quantize_bfin; */ -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/pixels_bfin.S b/tizen/distrib/ffmpeg/libavcodec/bfin/pixels_bfin.S deleted file mode 100644 index 69b493b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/pixels_bfin.S +++ /dev/null @@ -1,741 +0,0 @@ -/* - * Blackfin Pixel Operations - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "config_bfin.h" - -DEFUN(put_pixels_clamped,mL1, - (DCTELEM *block, uint8_t *dest, int line_size)): - [--SP] = (R7:4); - R4 = 0; - R5.l = 0x00ff; - R5.h = 0x00ff; - I0 = R0; // block - I1 = R1; // dest - R2 += -4; // line_size - M1 = R2; - P0 = 8; - R0 = [I0++]; - R1 = [I0++]; - R2 = MAX(R0, R4) (V); - LSETUP (ppc$0,ppc$1) LC0=P0; -ppc$0: R2 = MIN(R2, R5) (V); - R3 = MAX(R1, R4) (V); - R3 = MIN(R3, R5) (V) || R0 = [I0++]; - R6 = BYTEPACK (R2,R3) || R1 = [I0++]; - R2 = MAX(R0, R4) (V) || [I1++] = R6; - R2 = MIN(R2, R5) (V); - R3 = MAX(R1, R4) (V); - R3 = MIN(R3, R5) (V) || R0 = [I0++]; - R6 = BYTEPACK (R2,R3) || R1 = [I0++]; -ppc$1: R2 = Max(R0, R4) (V) || [I1++M1] = R6; - - (R7:4) = [SP++]; - RTS; -DEFUN_END(put_pixels_clamped) - -DEFUN(add_pixels_clamped,mL1, - (DCTELEM *block, uint8_t *dest, int line_size)): - [-- SP] = (R7:4); - R4 = 0; - I0 = 0; - R2 += -4; // line_size - M0 = R2; - I1 = R1; // dest - I3 = R0; // block - I2 = R1; // dest - P0 = 8; - M3 = 2; - R0 = [I3++] || R2 = [I1]; - R2 = R2 << 8 || R0.H = W[I3--] || R3 = [I1++]; - R3 = R3 >> 8 || R1.L = W[I3] || I3 += 4; - R6 = BYTEOP3P(R1:0, R3:2) (LO) || R1.H = W[I3++] || R2 = [I1]; - - LSETUP(apc$2,apc$3) LC1 = P0; -apc$2: R7 = BYTEOP3P(R1:0, R3:2) (HI, R) || R0 = [I3++] || R3 = [I1++M0]; - R2 = R2 << 8 || R0.H = W[I3--]; - R3 = R3 >> 8 || R1.L = W[I3] || I3 += 4; - R6 = R6 + R7 (S) || R1.H = W[I3]; - R6 = BYTEOP3P(R1:0, R3:2) (LO) || I3+=M3 || [I2++]=R6; - R7 = BYTEOP3P(R1:0, R3:2) (HI, R) || R0 = [I3++] || R2 = [I1]; - R2 = R2 << 8 || R0.H = W[I3--] || R3 = [I1++]; - R3 = R3 >> 8 || R1.L = W[I3] || I3 += 4; - R6 = R6 + R7 (S) || R1.H = W[I3++]; -apc$3: R6 = BYTEOP3P(R1:0, R3:2) (LO) || [I2++M0] = R6 || R2 = [I1]; - - (R7:4) = [SP++]; - RTS; -DEFUN_END(add_pixels_clamped) - - -/* - motion compensation - primitives - - * 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 - -*/ - -DEFUN(put_pixels8uc,mL1, - (uint8_t *block, const uint8_t *s0, const uint8_t *s1, - int dest_size, int line_size, int h)): - i3=r0; // dest - i0=r1; // src0 - i1=r2; // src1 - r0=[sp+12]; // dest_size - r2=[sp+16]; // line_size - p0=[sp+20]; // h - [--sp] = (r7:6); - r0+=-4; - m3=r0; - r2+=-8; - m0=r2; - LSETUP(pp8$0,pp8$1) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -pp8$0: DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R6 = BYTEOP1P(R1:0,R3:2) || R0 = [I0++M0]|| R2 =[I1++M0]; - R7 = BYTEOP1P(R1:0,R3:2)(R) || R0 = [I0++] || [I3++] = R6 ; -pp8$1: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; - - (r7:6) = [sp++]; - RTS; -DEFUN_END(put_pixels8uc) - -DEFUN(put_pixels16uc,mL1, - (uint8_t *block, const uint8_t *s0, const uint8_t *s1, - int dest_size, int line_size, int h)): - link 0; - [--sp] = (r7:6); - i3=r0; // dest - i0=r1; // src0 - i1=r2; // src1 - r0=[fp+20]; // dest_size - r2=[fp+24]; // line_size - p0=[fp+28]; // h - - - r0+=-12; - m3=r0; // line_size - r2+=-16; - m0=r2; - - LSETUP(pp16$0,pp16$1) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -pp16$0: DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R6 = BYTEOP1P(R1:0,R3:2) || R0 = [I0++] || R2 =[I1++]; - R7 = BYTEOP1P(R1:0,R3:2)(R) || R1 = [I0++] || R3 =[I1++]; - [I3++] = R6; - R6 = BYTEOP1P(R1:0,R3:2) || R0 = [I0++M0] || R2 =[I1++M0]; - R7 = BYTEOP1P(R1:0,R3:2)(R) || R0 = [I0++] || [I3++] = R7 ; - [I3++] = R6; -pp16$1: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; - - (r7:6) = [sp++]; - unlink; - RTS; -DEFUN_END(put_pixels16uc) - - - - - - -DEFUN(put_pixels8uc_nornd,mL1, - (uint8_t *block, const uint8_t *s0, const uint8_t *s1, - int line_size, int h)): - i3=r0; // dest - i0=r1; // src0 - i1=r2; // src1 - r2=[sp+12]; // line_size - p0=[sp+16]; // h - [--sp] = (r7:6); - r2+=-4; - m3=r2; - r2+=-4; - m0=r2; - LSETUP(pp8$2,pp8$3) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -pp8$2: DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R6 = BYTEOP1P(R1:0,R3:2)(T) || R0 = [I0++M0]|| R2 =[I1++M0]; - R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R0 = [I0++] || [I3++] = R6 ; -pp8$3: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; - - (r7:6) = [sp++]; - RTS; -DEFUN_END(put_pixels8uc_nornd) - -DEFUN(put_pixels16uc_nornd,mL1, - (uint8_t *block, const uint8_t *s0, const uint8_t *s1, - int line_size, int h)): - i3=r0; // dest - i0=r1; // src0 - i1=r2; // src1 - r2=[sp+12]; // line_size - p0=[sp+16]; // h - - [--sp] = (r7:6); - r2+=-12; - m3=r2; // line_size - r2+=-4; - m0=r2; - - LSETUP(pp16$2,pp16$3) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -pp16$2: - DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R6 = BYTEOP1P(R1:0,R3:2)(T) || R0 = [I0++] || R2 =[I1++]; - R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R1 = [I0++] || R3 =[I1++]; - [I3++] = R6; - - R6 = BYTEOP1P(R1:0,R3:2)(T) || R0 = [I0++M0] || R2 =[I1++M0]; - R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R0 = [I0++] || [I3++] = R7 ; - [I3++] = R6; -pp16$3: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; - - (r7:6) = [sp++]; - - RTS; -DEFUN_END(put_pixels16uc_nornd) - -DEFUN(z_put_pixels16_xy2,mL1, - (uint8_t *block, const uint8_t *s0, - int dest_size, int line_size, int h)): - link 0; - [--sp] = (r7:4); - i3=r0; // dest - i0=r1; // src0--> pixels - i1=r1; // src1--> pixels + line_size - r2+=-12; - m2=r2; // m2=dest_width-4 - r2=[fp+20]; - m3=r2; // line_size - p0=[fp+24]; // h - r2+=-16; - i1+=m3; /* src1 + line_size */ - m0=r2; /* line-size - 20 */ - - B0 = I0; - B1 = I1; - B3 = I3; - - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - - LSETUP(LS$16E,LE$16E) LC0=P0; -LS$16E: DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (RNDL) || R0 = [I0++] || R2 =[I1++]; - R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R1 = [I0++] || [I3++] = R4 ; - DISALGNEXCPT || R3 = [I1++] || [I3++] = R5; - R4 = BYTEOP2P (R3:2,R1:0) (RNDL) || R0 = [I0++M0]|| R2 = [I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R0 = [I0++] || [I3++] = R4 ; -LE$16E: DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; - - M1 = 1; - I3 = B3; - I1 = B1; - I0 = B0; - - I0 += M1; - I1 += M1; - - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - LSETUP(LS$16O,LE$16O) LC0=P0; -LS$16O: DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (RNDH) || R0 = [I0++] || R2 =[I1++]; - R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R1 = [I0++] || R6 =[I3++]; - R4 = R4 +|+ R6 || R7 = [I3--]; - R5 = R5 +|+ R7 || [I3++] = R4; - DISALGNEXCPT || R3 =[I1++] || [I3++] = R5; - R4 = BYTEOP2P (R3:2,R1:0) (RNDH) || R0 = [I0++M0]|| R2 = [I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R0 = [I0++] || R6 = [I3++]; - R4 = R4 +|+ R6 || R7 = [I3--]; - R5 = R5 +|+ R7 || [I3++] = R4; -LE$16O: DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; - - (r7:4) = [sp++]; - unlink; - rts; -DEFUN_END(z_put_pixels16_xy2) - -DEFUN(put_pixels16_xy2_nornd,mL1, - (uint8_t *block, const uint8_t *s0, - int line_size, int h)): - link 0; - [--sp] = (r7:4); - i3=r0; // dest - i0=r1; // src0--> pixels - i1=r1; // src1--> pixels + line_size - m3=r2; - r2+=-12; - m2=r2; - r2+=-4; - i1+=m3; /* src1 + line_size */ - m0=r2; /* line-size - 20 */ - p0=[fp+20]; // h - - B0=I0; - B1=I1; - B3=I3; - - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - - LSETUP(LS$16ET,LE$16ET) LC0=P0; -LS$16ET:DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (TL) || R0 = [I0++] || R2 =[I1++]; - R5 = BYTEOP2P (R3:2,R1:0) (TL,R) || R1 = [I0++] || [I3++] = R4 ; - DISALGNEXCPT || R3 = [I1++] || [I3++] = R5; - R4 = BYTEOP2P (R3:2,R1:0) (TL) || R0 = [I0++M0]|| R2 = [I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (TL,R) || R0 = [I0++] || [I3++] = R4 ; -LE$16ET:DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; - - M1 = 1; - I3=B3; - I1=B1; - I0=B0; - - I0 += M1; - I1 += M1; - - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - LSETUP(LS$16OT,LE$16OT) LC0=P0; -LS$16OT:DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (TH) || R0 = [I0++] || R2 =[I1++]; - R5 = BYTEOP2P (R3:2,R1:0) (TH,R) || R1 = [I0++] || R6 =[I3++]; - R4 = R4 +|+ R6 || R7 = [I3--]; - R5 = R5 +|+ R7 || [I3++] = R4; - DISALGNEXCPT || R3 =[I1++] || [I3++] = R5; - R4 = BYTEOP2P (R3:2,R1:0) (TH) || R0 = [I0++M0]|| R2 = [I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (TH,R) || R0 = [I0++] || R6 = [I3++]; - R4 = R4 +|+ R6 || R7 = [I3--]; - R5 = R5 +|+ R7 || [I3++] = R4; -LE$16OT:DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; - - (r7:4) = [sp++]; - unlink; - rts; -DEFUN_END(put_pixels16_xy2_nornd) - -DEFUN(z_put_pixels8_xy2,mL1, - (uint8_t *block, const uint8_t *s0, - int dest_size, int line_size, int h)): - link 0; - [--sp] = (r7:4); - i3=r0; // dest - i0=r1; // src0--> pixels - i1=r1; // src1--> pixels + line_size - r2+=-4; - m2=r2; // m2=dest_width-4 - r2=[fp+20]; - m3=r2; // line_size - p0=[fp+24]; // h - r2+=-8; - i1+=m3; /* src1 + line_size */ - m0=r2; /* line-size - 20 */ - - b0 = I0; - b1 = I1; - b3 = I3; - - LSETUP(LS$8E,LE$8E) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; -LS$8E: DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (RNDL) || R0 = [I0++M0] || R2 =[I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R0 = [I0++] || [I3++] = R4 ; -LE$8E: DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; - - M1 = 1; - I3 = b3; - I1 = b1; - I0 = b0; - - I0 += M1; - I1 += M1; - - LSETUP(LS$8O,LE$8O) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; -LS$8O: DISALGNEXCPT || R1 = [I0++] || R3 =[I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (RNDH) || R0 = [I0++M0] || R2 =[I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R0 = [I0++] || R6 =[I3++]; - R4 = R4 +|+ R6 || R7 = [I3--]; - R5 = R5 +|+ R7 || [I3++] = R4; -LE$8O: DISALGNEXCPT || R2 =[I1++] || [I3++M2] = R5; - - (r7:4) = [sp++]; - unlink; - rts; -DEFUN_END(z_put_pixels8_xy2) - -DEFUN(put_pixels8_xy2_nornd,mL1, - (uint8_t *block, const uint8_t *s0, int line_size, int h)): - link 0; - [--sp] = (r7:4); - i3=r0; // dest - i0=r1; // src0--> pixels - i1=r1; // src1--> pixels + line_size - m3=r2; - r2+=-4; - m2=r2; - r2+=-4; - i1+=m3; /* src1 + line_size */ - m0=r2; /* line-size - 20 */ - p0=[fp+20]; // h - - - b0 = I0; - b1 = I1; - b3 = I3; - - LSETUP(LS$8ET,LE$8ET) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -LS$8ET: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (TL) || R0 = [I0++M0] || R2 = [I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (TL,R) || R0 = [I0++] || [I3++] = R4 ; -LE$8ET: DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; - - M1 = 1; - I3 = b3; - I1 = b1; - I0 = b0; - - I0 += M1; - I1 += M1; - - LSETUP(LS$8OT,LE$8OT) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 = [I1++]; - -LS$8OT: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - R4 = BYTEOP2P (R3:2,R1:0) (TH) || R0 = [I0++M0] || R2 = [I1++M0]; - R5 = BYTEOP2P (R3:2,R1:0) (TH,R) || R0 = [I0++] || R6 = [I3++]; - R4 = R4 +|+ R6 || R7 = [I3--]; - R5 = R5 +|+ R7 || [I3++] = R4; -LE$8OT: DISALGNEXCPT || R2 =[I1++] || [I3++M2] = R5; - - (r7:4) = [sp++]; - unlink; - rts; - -DEFUN(diff_pixels,mL1, - (DCTELEM *block, uint8_t *s1, uint8_t *s2, int stride)): - link 0; - [--sp] = (r7:4); - p0=8; - i3=r0; // block - i0=r1; // s1 - i1=r2; // s2 - r2=[fp+20]; // stride - r2+=-8; - m0=r2; - - - LSETUP(.LS0,.LE0) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -.LS0: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - (R5,R4) = BYTEOP16M (R1:0,R3:2) || R0 = [I0++M0] || R2 = [I1++M0]; - (R7,R6) = BYTEOP16M (R1:0,R3:2) (R)|| R0 = [I0++] || [I3++] = R4; - DISALGNEXCPT || R2 = [I1++] || [I3++] = R5; - [i3++]=r6; -.LE0: [i3++]=r7; - - (r7:4) = [sp++]; - unlink; - rts; -DEFUN_END(put_pixels8_xy2_nornd) - -/* - for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j++) { - sum += pix[j]; - } - pix += line_size; - } -*/ -DEFUN(pix_sum,mL1, - (uint8_t *p, int stride)): - link 0; - [--sp] = (r7:4); - p0=8; - i0=r0; // s1 - i1=r0; - m1=r1; - r1=r1+r1; - r1+=-16; // stride - m0=r1; - i1+=m1; - - r6=0; - - LSETUP(LS$PS,LE$PS) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -LS$PS: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - (R5,R4) = BYTEOP16P (R3:2,R1:0) || R0 = [I0++] || R2 = [I1++]; - r6=r6+|+r5; - r6=r6+|+r4; - (R5,R4) = BYTEOP16P (R3:2,R1:0) (R)|| R1 = [I0++] || R3 = [I1++]; - r6=r6+|+r5; - r6=r6+|+r4; - (R5,R4) = BYTEOP16P (R3:2,R1:0) || R0 = [I0++m0] || R2 = [I1++m0]; - r6=r6+|+r5; - r6=r6+|+r4; - (R5,R4) = BYTEOP16P (R3:2,R1:0) (R)|| R0 = [I0++] || R2 = [I1++]; - r6=r6+|+r5; -LE$PS: r6=r6+|+r4; - r0.l=r6.l+r6.h; - r0.h=0; - - (r7:4) = [sp++]; - unlink; - rts; -DEFUN_END(pix_sum) - - -DEFUN(get_pixels,mL1, - (DCTELEM *restrict block, const uint8_t *pixels, int line_size)): - [--sp] = (r7:4); - i3=r0; // dest - i0=r1; // src0 - p0=8; - r2+=-8; - m0=r2; - LSETUP(gp8$0,gp8$1) LC0=P0; - - DISALGNEXCPT || R0 = [I0++]; - DISALGNEXCPT || R1 = [I0++]; - -gp8$0: (R7,R6) = byteunpack R1:0 || R0 = [I0++M0]; - (R5,R4) = byteunpack R1:0 (R) || R0 = [I0++] || [I3++]=R6; - DISALGNEXCPT || R1 = [I0++] || [I3++]=R7; - [I3++]=R4; -gp8$1: [I3++]=R5 - - - (r7:4) = [sp++]; - RTS; -DEFUN_END(get_pixels) - - -/* sad = sad16x16 (ubyte *mb, ubyte *refwin, srcwidth, refwinwidth, h) */ -/* 91 cycles */ -DEFUN(z_sad16x16,mL1, - (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h)): - link 0; - I0 = R0; - I1 = R1; - - A1 = A0 = 0; - R0 = [sp+20]; // rwidth - P2 = [sp+24]; // height - R3 = 16; - R0 = R0 - R3; - R3 = R2 - R3; - M1 = R0; - M0 = R3; - - DISALGNEXCPT || R0 = [I0++] || R2 = [I1++]; - LSETUP (s$16, e$16) LC0=P2; -s$16: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - SAA (R1:0,R3:2) || R0 = [I0++] || R2 = [I1++]; - SAA (R1:0,R3:2) (R) || R1 = [I0++] || R3 = [I1++]; - SAA (R1:0,R3:2) || R0 = [I0++M0] || R2 = [I1++M1]; -e$16: SAA (R1:0,R3:2) (R) || R0 = [I0++] || R2 = [I1++]; - - R3=A1.L+A1.H, R2=A0.L+A0.H ; - R0 = R2 + R3 ; - unlink; - RTS; -DEFUN_END(z_sad16x16) - -/* sad = sad8x8 (ubyte *mb, ubyte *refwin, int srcwidth, int refwinwidth, int h) */ -/* 36 cycles */ -DEFUN(z_sad8x8,mL1, - (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h)): - I0 = R0; - I1 = R1; - - A1 = A0 = 0; - r0 = [sp+12]; // rwidth - P2 = [sp+16]; //height - R3 = 8; - R0 = R0 - R3; - R3 = R2 - R3; - M0 = R3; - M1 = R0; - - LSETUP (s$8, e$8) LC0=P2; - DISALGNEXCPT || R0 = [I0++] || R2 = [I1++]; - DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; -s$8: SAA (R1:0,R3:2) || R0 = [I0++M0] || R2 = [I1++M1]; - SAA (R1:0,R3:2) (R) || R0 = [I0++] || R2 = [I1++]; -e$8: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - - R3=A1.L+A1.H, R2=A0.L+A0.H ; - R0 = R2 + R3 ; - RTS; -DEFUN_END(z_sad8x8) - -DEFUN(pix_norm1,mL1, - (uint8_t * pix, int line_size)): - [--SP]=(R7:4,P5:3); - - // Fetch the input arguments. - P1 = R0; // pix - P0 = R1; // line_size - P5 = 16; // loop ctr. - P0 -= P5; - M0 = P0; // M0 = line_size-16; - // Now for the real work. - A1 = A0 = 0; - lsetup(_pix_norm1_blkfn_loopStart, _pix_norm1_blkfn_loopEnd) LC1 = P5; - I0 = P1; - DISALGNEXCPT || r0 = [i0++]; - -_pix_norm1_blkfn_loopStart: - // following unpacks pix1[0..15] pix1+line_size[0..15] - DISALGNEXCPT || r1 = [i0++]; - - (r5, r4) = byteunpack r1:0 || r0 = [i0++]; - a1 += r5.h * r5.h, a0 += r5.l * r5.l (is); - a1 += r4.h * r4.h, a0 += r4.l * r4.l (is); - (r5, r4) = byteunpack r1:0(r) || r1 = [i0++]; - a1 += r5.h * r5.h, a0 += r5.l * r5.l (is); - a1 += r4.h * r4.h, a0 += r4.l * r4.l (is); - (r5, r4) = byteunpack r1:0 || r0 = [i0++M0]; - a1 += r5.h * r5.h, a0 += r5.l * r5.l (is); - a1 += r4.h * r4.h, a0 += r4.l * r4.l (is); - (r5, r4) = byteunpack r1:0(r) || r0 = [i0++]; - a1 += r5.h * r5.h, a0 += r5.l * r5.l (is); -_pix_norm1_blkfn_loopEnd: - a1 += r4.h * r4.h, a0 += r4.l * r4.l (is); - - -// Clean up at the end: - R2 = A0, R3 = A1; - R0 = R2 + R3 (S); - - (R7:4,P5:3)=[SP++]; - - RTS; -DEFUN_END(pix_norm1) - -DEFUN(sse4,mL1, - (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)): - link 0; - [--sp] = (r7:6); - p0=[fp+24]; // h - i0=r1; // pix1 - i1=r2; // pix2 - r2=[fp+20]; // line_size - r2+=-4; - m0=r2; - - a0=a1=0; - LSETUP(.S40,.E40) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -.S40: DISALGNEXCPT || R1 = [I0++M0] || R3 = [I1++M0]; - (R7,R6) = BYTEOP16M (R1:0,R3:2); - a0 += r7.l * r7.l, a1 += r7.h * r7.h (is); -.E40: a0 += r6.l * r6.l, a1 += r6.h * r6.h (is); - a0 += a1; - r0 = a0; - - (r7:6) = [sp++]; - unlink; - rts; -DEFUN_END(sse4) - -DEFUN(sse8,mL1, - (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)): - link 0; - [--sp] = (r7:6); - p0=[fp+24]; // h - i0=r1; // pix1 - i1=r2; // pix2 - r2=[fp+20]; // line_size - r2+=-8; - m0=r2; - - a0=a1=0; - LSETUP(.S80,.E80) LC0=P0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - -.S80: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - (R7,R6) = BYTEOP16M (R1:0,R3:2) || R0 = [I0++M0] || R2 = [I1++M0]; - a0 += r7.l * r7.l, a1 += r7.h * r7.h (is); - a0 += r6.l * r6.l, a1 += r6.h * r6.h (is); - (R7,R6) = BYTEOP16M (R1:0,R3:2) (R)|| R0 = [I0++] || R2 = [I1++]; - a0 += r7.l * r7.l, a1 += r7.h * r7.h (is); -.E80: a0 += r6.l * r6.l, a1 += r6.h * r6.h (is); - a0 += a1; - r0 = a0; - - (r7:6) = [sp++]; - unlink; - rts; -DEFUN_END(sse8) - -DEFUN(sse16,mL1, - (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)): - link 0; - [--sp] = (r7:6); - p0=[fp+24]; // h - i0=r1; // pix1 - i1=r2; // pix2 - r2=[fp+20]; // line_size - r2+=-16; - m0=r2; - - a0=a1=0; - DISALGNEXCPT || R0 = [I0++] || R2 =[I1++]; - LSETUP(.S160,.E160) LC0=P0; - -.S160: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; - (R7,R6) = BYTEOP16M (R1:0,R3:2) || R0 = [I0++] || R2 = [I1++]; - a0 += r7.l * r7.l, a1 += r7.h * r7.h (is); - a0 += r6.l * r6.l, a1 += r6.h * r6.h (is); - (R7,R6) = BYTEOP16M (R1:0,R3:2) (R)|| R1 = [I0++] || R3 = [I1++]; - a0 += r7.l * r7.l, a1 += r7.h * r7.h (is); - a0 += r6.l * r6.l, a1 += r6.h * r6.h (is); - (R7,R6) = BYTEOP16M (R1:0,R3:2) || R0 = [I0++M0] || R2 = [I1++M0]; - a0 += r7.l * r7.l, a1 += r7.h * r7.h (is); - a0 += r6.l * r6.l, a1 += r6.h * r6.h (is); - (R7,R6) = BYTEOP16M (R1:0,R3:2) (R)|| R0 = [I0++] || R2 = [I1++]; - a0 += r7.l * r7.l, a1 += r7.h * r7.h (is); -.E160: a0 += r6.l * r6.l, a1 += r6.h * r6.h (is); - a0 += a1; - r0 = a0; - - (r7:6) = [sp++]; - unlink; - rts; -DEFUN_END(sse16) - - diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/vp3_bfin.c b/tizen/distrib/ffmpeg/libavcodec/bfin/vp3_bfin.c deleted file mode 100644 index b010178..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/vp3_bfin.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "dsputil_bfin.h" - -/* Intra iDCT offset 128 */ -void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block) -{ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int i,j; - - ff_bfin_vp3_idct (block); - - for (i=0;i<8;i++) - for (j=0;j<8;j++) - dest[line_size*i+j]=cm[128+block[i*8+j]]; -} - -/* Inter iDCT */ -void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_bfin_vp3_idct (block); - ff_bfin_add_pixels_clamped (block, dest, line_size); -} - - diff --git a/tizen/distrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S b/tizen/distrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S deleted file mode 100644 index 21f732c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S +++ /dev/null @@ -1,282 +0,0 @@ -/* - * vp3_idct BlackFin - * - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - This blackfin DSP code implements an 8x8 inverse type II DCT. - -Prototype : void ff_bfin_vp3_idct(DCTELEM *in) - -Registers Used : A0, A1, R0-R7, I0-I3, B0, B2, B3, M0-M2, L0-L3, P0-P5, LC0. - -*/ - -#include "config.h" -#include "config_bfin.h" - -#if defined(__FDPIC__) && CONFIG_SRAM -.section .l1.data.B,"aw",@progbits -#else -.data -#endif - -.align 4; -coefs: -.short 0x5a82; // C4 -.short 0x5a82; // C4 -.short 0x30FC; //cos(3pi/8) C6 -.short 0x7642; //cos(pi/8) C2 -.short 0x18F9; //cos(7pi/16) -.short 0x7D8A; //cos(pi/16) -.short 0x471D; //cos(5pi/16) -.short 0x6A6E; //cos(3pi/16) -.short 0x18F9; //cos(7pi/16) -.short 0x7D8A; //cos(pi/16) - -#if defined(__FDPIC__) && CONFIG_SRAM -.section .l1.data.A -#endif - -vtmp: .space 256 - -#define TMP0 FP-8 -#define TMP1 FP-12 -#define TMP2 FP-16 - - -.text -DEFUN(vp3_idct,mL1, - (DCTELEM *block)): - -/********************** Function Prologue *********************************/ - link 16; - [--SP] = (R7:4, P5:3); // Push the registers onto the stack. - B0 = R0; // Pointer to Input matrix - RELOC(R1, P3, coefs); // Pointer to Coefficients - RELOC(R2, P3, vtmp); // Pointer to Temporary matrix - B3 = R1; - B2 = R2; - L3 = 20; // L3 is used for making the coefficient array - // circular. - // MUST BE RESTORED TO ZERO at function exit. - M1 = 16 (X); // All these registers are initialized for - M3 = 8(X); // modifying address offsets. - - I0 = B0; // I0 points to Input Element (0, 0). - I2 = B0; // I2 points to Input Element (0, 0). - I2 += M3 || R0.H = W[I0]; - // Element 0 is read into R0.H - I1 = I2; // I1 points to input Element (0, 6). - I1 += 4 || R0.L = W[I2++]; - // I2 points to input Element (0, 4). - // Element 4 is read into R0.L. - P2 = 8 (X); - P3 = 32 (X); - P4 = -32 (X); - P5 = 98 (X); - R7 = 0x8000(Z); - I3 = B3; // I3 points to Coefficients - P0 = B2; // P0 points to array Element (0, 0) of temp - P1 = B2; - R7 = [I3++] || [TMP2]=R7; // Coefficient C4 is read into R7.H and R7.L. - MNOP; - NOP; - - /* - * A1 = Y0 * cos(pi/4) - * A0 = Y0 * cos(pi/4) - * A1 = A1 + Y4 * cos(pi/4) - * A0 = A0 - Y4 * cos(pi/4) - * load: - * R1=(Y2,Y6) - * R7=(C2,C6) - * res: - * R3=Y0, R2=Y4 - */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || I0+= 4 || R1.L=W[I1++]; - R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || R1.H=W[I0--] || R7=[I3++]; - - LSETUP (.0, .1) LC0 = P2; // perform 8 1d idcts - - P2 = 112 (X); - P1 = P1 + P2; // P1 points to element (7, 0) of temp buffer. - P2 = -94(X); - -.0: - /* - * A1 = Y2 * cos(3pi/8) - * A0 = Y2 * cos(pi/8) - * A1 = A1 - Y6 * cos(pi/8) - * A0 = A0 + Y6 * cos(3pi/8) - * R5 = (Y1,Y7) - * R7 = (C1,C7) - * res: - * R1=Y2, R0=Y6 - */ - A1=R7.L*R1.H, A0=R7.H*R1.H (IS) || I0+=4 || R5.H=W[I0]; - R1=(A1-=R7.H*R1.L), R0=(A0+=R7.L*R1.L) (IS) || R5.L=W[I1--] || R7=[I3++]; - /* - * Y0 = Y0 + Y6. - * Y4 = Y4 + Y2. - * Y2 = Y4 - Y2. - * Y6 = Y0 - Y6. - * R3 is saved - * R6.l=Y3 - * note: R3: Y0, R2: Y4, R1: Y2, R0: Y6 - */ - R3=R3+R0, R0=R3-R0; - R2=R2+R1, R1=R2-R1 || [TMP0]=R3 || R6.L=W[I0--]; - /* - * Compute the odd portion (1,3,5,7) even is done. - * - * Y1 = C7 * Y1 - C1 * Y7 + C3 * Y5 - C5 * Y3. - * Y7 = C1 * Y1 + C7 * Y7 + C5 * Y5 + C3 * Y3. - * Y5 = C5 * Y1 + C3 * Y7 + C7 * Y5 - C1 * Y3. - * Y3 = C3 * Y1 - C5 * Y7 - C1 * Y5 - C7 * Y3. - */ - // R5=(Y1,Y7) R6=(Y5,Y3) // R7=(C1,C7) - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || [TMP1]=R2 || R6.H=W[I2--]; - A1-=R7.H*R5.L, A0+=R7.L*R5.L (IS) || I0-=4 || R7=[I3++]; - A1+=R7.H*R6.H, A0+=R7.L*R6.H (IS) || I0+=M1; // R7=(C3,C5) - R3 =(A1-=R7.L*R6.L), R2 =(A0+=R7.H*R6.L) (IS); - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || R4=[TMP0]; - A1+=R7.H*R5.L, A0-=R7.L*R5.L (IS) || I1+=M1 || R7=[I3++]; // R7=(C1,C7) - A1+=R7.L*R6.H, A0-=R7.H*R6.H (IS); - R7 =(A1-=R7.H*R6.L), R6 =(A0-=R7.L*R6.L) (IS) || I2+=M1; - // R3=Y1, R2=Y7, R7=Y5, R6=Y3 - - /* Transpose write column. */ - R5.H=R4+R2 (RND12); // Y0=Y0+Y7 - R5.L=R4-R2 (RND12) || R4 = [TMP1]; // Y7=Y7-Y0 - R2.H=R1+R7 (RND12) || W[P0++P3]=R5.H; // Y2=Y2+Y5 st Y0 - R2.L=R1-R7 (RND12) || W[P1++P4]=R5.L || R7=[I3++]; // Y5=Y2-Y5 st Y7 - R5.H=R0-R3 (RND12) || W[P0++P3]=R2.H || R1.L=W[I1++]; // Y1=Y6-Y1 st Y2 - R5.L=R0+R3 (RND12) || W[P1++P4]=R2.L || R0.H=W[I0++]; // Y6=Y6+Y1 st Y5 - R3.H=R4-R6 (RND12) || W[P0++P3]=R5.H || R0.L=W[I2++]; // Y3=Y3-Y4 st Y1 - R3.L=R4+R6 (RND12) || W[P1++P4]=R5.L || R1.H=W[I0++]; // Y4=Y3+Y4 st Y6 - - /* pipeline loop start, + drain Y3, Y4 */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || W[P0++P2]= R3.H || R1.H = W[I0--]; -.1: R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || W[P1++P5]= R3.L || R7 = [I3++]; - - - - I0 = B2; // I0 points to Input Element (0, 0) - I2 = B2; // I2 points to Input Element (0, 0) - I2 += M3 || R0.H = W[I0]; - // Y0 is read in R0.H - I1 = I2; // I1 points to input Element (0, 6) - I1 += 4 || R0.L = W[I2++]; - // I2 points to input Element (0, 4) - // Y4 is read in R0.L - P2 = 8 (X); - I3 = B3; // I3 points to Coefficients - P0 = B0; // P0 points to array Element (0, 0) for writing - // output - P1 = B0; - R7 = [I3++]; // R7.H = C4 and R7.L = C4 - NOP; - - /* - * A1 = Y0 * cos(pi/4) - * A0 = Y0 * cos(pi/4) - * A1 = A1 + Y4 * cos(pi/4) - * A0 = A0 - Y4 * cos(pi/4) - * load: - * R1=(Y2,Y6) - * R7=(C2,C6) - * res: - * R3=Y0, R2=Y4 - */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || I0+=4 || R1.L=W[I1++]; - R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || R1.H=W[I0--] || R7=[I3++]; - - LSETUP (.2, .3) LC0 = P2; // peform 8 1d idcts - P2 = 112 (X); - P1 = P1 + P2; - P2 = -94(X); - -.2: - /* - * A1 = Y2 * cos(3pi/8) - * A0 = Y2 * cos(pi/8) - * A1 = A1 - Y6 * cos(pi/8) - * A0 = A0 + Y6 * cos(3pi/8) - * R5 = (Y1,Y7) - * R7 = (C1,C7) - * res: - * R1=Y2, R0=Y6 - */ - A1=R7.L*R1.H, A0=R7.H*R1.H (IS) || I0+=4 || R5.H=W[I0]; - R1=(A1-=R7.H*R1.L), R0=(A0+=R7.L*R1.L) (IS) || R5.L=W[I1--] || R7=[I3++]; - /* - * Y0 = Y0 + Y6. - * Y4 = Y4 + Y2. - * Y2 = Y4 - Y2. - * Y6 = Y0 - Y6. - * R3 is saved - * R6.l=Y3 - * note: R3: Y0, R2: Y4, R1: Y2, R0: Y6 - */ - R3=R3+R0, R0=R3-R0; - R2=R2+R1, R1=R2-R1 || [TMP0]=R3 || R6.L=W[I0--]; - /* - * Compute the odd portion (1,3,5,7) even is done. - * - * Y1 = C7 * Y1 - C1 * Y7 + C3 * Y5 - C5 * Y3. - * Y7 = C1 * Y1 + C7 * Y7 + C5 * Y5 + C3 * Y3. - * Y5 = C5 * Y1 + C3 * Y7 + C7 * Y5 - C1 * Y3. - * Y3 = C3 * Y1 - C5 * Y7 - C1 * Y5 - C7 * Y3. - */ - // R5=(Y1,Y7) R6=(Y5,Y3) // R7=(C1,C7) - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || [TMP1]=R2 || R6.H=W[I2--]; - A1-=R7.H*R5.L, A0+=R7.L*R5.L (IS) || I0-=4 || R7=[I3++]; - A1+=R7.H*R6.H, A0+=R7.L*R6.H (IS) || I0+=M1; // R7=(C3,C5) - R3 =(A1-=R7.L*R6.L), R2 =(A0+=R7.H*R6.L) (IS); - A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || R4=[TMP0]; - A1+=R7.H*R5.L, A0-=R7.L*R5.L (IS) || I1+=M1 || R7=[I3++]; // R7=(C1,C7) - A1+=R7.L*R6.H, A0-=R7.H*R6.H (IS); - R7 =(A1-=R7.H*R6.L), R6 =(A0-=R7.L*R6.L) (IS) || I2+=M1; - // R3=Y1, R2=Y7, R7=Y5, R6=Y3 - - /* Transpose write column. */ - R5.H=R4+R2 (RND20); // Y0=Y0+Y7 - R5.L=R4-R2 (RND20) || R4 = [TMP1]; // Y7=Y7-Y0 - R5=R5>>>2(v); - R2.H=R1+R7 (RND20) || W[P0++P3]=R5.H; // Y2=Y2+Y5 st Y0 - R2.L=R1-R7 (RND20) || W[P1++P4]=R5.L || R7=[I3++]; // Y5=Y2-Y5 st Y7 - R2=R2>>>2(v); - R5.H=R0-R3 (RND20) || W[P0++P3]=R2.H || R1.L=W[I1++]; // Y1=Y6-Y1 st Y2 - R5.L=R0+R3 (RND20) || W[P1++P4]=R2.L || R0.H=W[I0++]; // Y6=Y6+Y1 st Y5 - R5=R5>>>2(v); - R3.H=R4-R6 (RND20) || W[P0++P3]=R5.H || R0.L=W[I2++]; // Y3=Y3-Y4 st Y1 - R3.L=R4+R6 (RND20) || W[P1++P4]=R5.L || R1.H=W[I0++]; // Y4=Y3+Y4 st Y6 - R3=R3>>>2(v); - /* pipeline loop start, + drain Y3, Y4 */ - A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || W[P0++P2]= R3.H || R1.H = W[I0--]; -.3: R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || W[P1++P5]= R3.L || R7 = [I3++]; - - L3 = 0; - (R7:4,P5:3)=[SP++]; - unlink; - RTS; -DEFUN_END(vp3_idct) - - diff --git a/tizen/distrib/ffmpeg/libavcodec/bgmc.c b/tizen/distrib/ffmpeg/libavcodec/bgmc.c deleted file mode 100644 index 86b807b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bgmc.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Block Gilbert-Moore decoder - * Copyright (c) 2010 Thilo Borgmann - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Block Gilbert-Moore decoder as used by MPEG-4 ALS - * @author Thilo Borgmann - */ - - -#include "bgmc.h" - - -#define FREQ_BITS 14 // bits used by frequency counters -#define VALUE_BITS 18 // bits used to represent the values -#define TOP_VALUE ((1 << VALUE_BITS) - 1) // maximum value -#define FIRST_QTR (TOP_VALUE / 4 + 1) // first quarter of values maximum value -#define HALF (2 * FIRST_QTR) // first half of values maximum value -#define THIRD_QTR (3 * FIRST_QTR) // third quarter of values maximum value - -#define LUT_BITS (FREQ_BITS - 8) // number of bits used to index lookup tables -#define LUT_SIZE (1 << LUT_BITS) // size of the lookup tables -#define LUT_BUFF 4 // number of buffered lookup tables - - -/** Cumulative frequency tables for block Gilbert-Moore coding. - */ -static const uint16_t cf_tables_1[3][129] = { - { - 16384, 16066, 15748, 15431, 15114, 14799, 14485, 14173, 13861, 13552, - 13243, 12939, 12635, 12336, 12038, 11745, 11452, 11161, 10870, 10586, - 10303, 10027, 9751, 9483, 9215, 8953, 8692, 8440, 8189, 7946, - 7704, 7472, 7240, 7008, 6776, 6554, 6333, 6122, 5912, 5711, - 5512, 5320, 5128, 4947, 4766, 4595, 4425, 4264, 4104, 3946, - 3788, 3640, 3493, 3355, 3218, 3090, 2963, 2842, 2721, 2609, - 2498, 2395, 2292, 2196, 2100, 2004, 1908, 1820, 1732, 1651, - 1570, 1497, 1424, 1355, 1287, 1223, 1161, 1100, 1044, 988, - 938, 888, 839, 790, 746, 702, 662, 623, 588, 553, - 520, 488, 459, 431, 405, 380, 357, 334, 311, 288, - 268, 248, 230, 213, 197, 182, 168, 154, 142, 130, - 119, 108, 99, 90, 81, 72, 64, 56, 49, 42, - 36, 30, 25, 20, 15, 11, 7, 3, 0 - }, - { - 16384, 16080, 15776, 15473, 15170, 14868, 14567, 14268, 13970, 13674, - 13378, 13086, 12794, 12505, 12218, 11936, 11654, 11373, 11092, 10818, - 10544, 10276, 10008, 9749, 9490, 9236, 8982, 8737, 8492, 8256, - 8020, 7792, 7564, 7336, 7108, 6888, 6669, 6459, 6249, 6050, - 5852, 5660, 5468, 5286, 5104, 4931, 4760, 4598, 4436, 4275, - 4115, 3965, 3816, 3674, 3534, 3403, 3272, 3147, 3023, 2907, - 2792, 2684, 2577, 2476, 2375, 2274, 2173, 2079, 1986, 1897, - 1810, 1724, 1645, 1567, 1493, 1419, 1351, 1284, 1222, 1161, - 1105, 1050, 995, 941, 891, 842, 797, 753, 713, 673, - 636, 599, 566, 533, 503, 473, 446, 419, 392, 365, - 340, 316, 294, 272, 253, 234, 216, 199, 184, 169, - 155, 142, 130, 118, 106, 95, 85, 75, 66, 57, - 49, 41, 34, 27, 21, 15, 10, 5, 0 - }, - { - 16384, 16092, 15801, 15510, 15219, 14930, 14641, 14355, 14069, 13785, - 13501, 13219, 12938, 12661, 12384, 12112, 11841, 11571, 11301, 11037, - 10773, 10514, 10256, 10005, 9754, 9508, 9263, 9025, 8787, 8557, - 8327, 8103, 7879, 7655, 7431, 7215, 7000, 6792, 6585, 6387, - 6190, 5998, 5807, 5625, 5445, 5272, 5100, 4937, 4774, 4613, - 4452, 4301, 4150, 4007, 3865, 3731, 3597, 3469, 3341, 3218, - 3099, 2981, 2869, 2758, 2652, 2546, 2440, 2334, 2234, 2134, - 2041, 1949, 1864, 1779, 1699, 1620, 1547, 1474, 1407, 1340, - 1278, 1217, 1157, 1097, 1043, 989, 940, 891, 846, 801, - 759, 718, 680, 643, 609, 575, 543, 511, 479, 447, - 418, 389, 363, 337, 314, 291, 270, 249, 230, 212, - 195, 179, 164, 149, 135, 121, 108, 96, 85, 74, - 64, 54, 45, 36, 28, 20, 13, 6, 0 - } -}; - - -static const uint16_t cf_tables_2[8][193] = { - { - 16384, 16104, 15825, 15546, 15268, 14991, 14714, 14439, 14164, 13891, - 13620, 13350, 13081, 12815, 12549, 12287, 12025, 11765, 11505, 11250, - 10996, 10746, 10497, 10254, 10011, 9772, 9534, 9303, 9072, 8848, - 8624, 8406, 8188, 7970, 7752, 7539, 7327, 7123, 6919, 6724, - 6529, 6339, 6150, 5970, 5790, 5618, 5446, 5282, 5119, 4957, - 4795, 4642, 4490, 4345, 4201, 4065, 3929, 3798, 3669, 3547, - 3425, 3310, 3196, 3086, 2976, 2866, 2756, 2650, 2545, 2447, - 2350, 2260, 2170, 2085, 2000, 1921, 1843, 1770, 1698, 1632, - 1566, 1501, 1436, 1376, 1316, 1261, 1207, 1157, 1108, 1061, - 1015, 973, 931, 893, 855, 819, 783, 747, 711, 677, - 644, 614, 584, 557, 530, 505, 480, 458, 436, 416, - 396, 378, 360, 343, 326, 310, 295, 281, 267, 255, - 243, 232, 221, 211, 201, 192, 183, 174, 166, 158, - 150, 142, 134, 126, 119, 112, 106, 100, 95, 90, - 85, 80, 76, 72, 69, 66, 63, 60, 57, 54, - 51, 48, 46, 44, 42, 40, 38, 36, 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, 0 - }, - { - 16384, 16116, 15849, 15582, 15316, 15050, 14785, 14521, 14257, 13995, - 13734, 13476, 13218, 12963, 12708, 12457, 12206, 11956, 11706, 11460, - 11215, 10975, 10735, 10500, 10265, 10034, 9803, 9579, 9355, 9136, - 8917, 8703, 8489, 8275, 8061, 7853, 7645, 7444, 7244, 7051, - 6858, 6671, 6484, 6305, 6127, 5956, 5785, 5622, 5459, 5298, - 5137, 4983, 4830, 4684, 4539, 4401, 4263, 4131, 3999, 3874, - 3750, 3632, 3515, 3401, 3287, 3173, 3059, 2949, 2840, 2737, - 2635, 2539, 2444, 2354, 2264, 2181, 2098, 2020, 1943, 1872, - 1801, 1731, 1661, 1596, 1532, 1472, 1412, 1357, 1303, 1251, - 1200, 1153, 1106, 1063, 1020, 979, 938, 897, 856, 818, - 780, 746, 712, 681, 650, 621, 592, 566, 540, 517, - 494, 473, 452, 431, 410, 391, 373, 356, 340, 325, - 310, 296, 282, 270, 258, 247, 236, 225, 214, 203, - 192, 182, 172, 162, 153, 144, 136, 128, 121, 114, - 108, 102, 97, 92, 87, 82, 77, 73, 69, 65, - 62, 59, 56, 53, 50, 47, 45, 43, 41, 39, - 37, 35, 33, 31, 29, 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, 0 - }, - { - 16384, 16128, 15872, 15617, 15362, 15107, 14853, 14600, 14347, 14096, - 13846, 13597, 13350, 13105, 12860, 12618, 12376, 12135, 11894, 11657, - 11421, 11189, 10957, 10730, 10503, 10279, 10056, 9838, 9620, 9407, - 9195, 8987, 8779, 8571, 8363, 8159, 7955, 7758, 7561, 7371, - 7182, 6997, 6812, 6635, 6459, 6289, 6120, 5957, 5795, 5634, - 5473, 5319, 5165, 5018, 4871, 4732, 4593, 4458, 4324, 4197, - 4071, 3951, 3831, 3714, 3597, 3480, 3363, 3250, 3138, 3032, - 2927, 2828, 2729, 2635, 2541, 2453, 2366, 2284, 2202, 2126, - 2050, 1975, 1900, 1830, 1761, 1697, 1633, 1574, 1515, 1459, - 1403, 1351, 1300, 1252, 1205, 1160, 1115, 1070, 1025, 982, - 939, 899, 860, 824, 789, 756, 723, 693, 663, 636, - 609, 584, 559, 535, 511, 489, 467, 447, 427, 409, - 391, 374, 358, 343, 328, 313, 300, 287, 274, 261, - 248, 235, 223, 211, 200, 189, 179, 169, 160, 151, - 143, 135, 128, 121, 115, 109, 103, 97, 92, 87, - 82, 77, 73, 69, 65, 61, 58, 55, 52, 49, - 46, 43, 40, 37, 35, 33, 31, 29, 27, 25, - 23, 21, 20, 19, 18, 17, 16, 15, 14, 13, - 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, - 2, 1, 0 - }, - { - 16384, 16139, 15894, 15649, 15405, 15162, 14919, 14677, 14435, 14195, - 13955, 13717, 13479, 13243, 13008, 12775, 12542, 12310, 12079, 11851, - 11623, 11399, 11176, 10956, 10737, 10521, 10305, 10094, 9883, 9677, - 9471, 9268, 9065, 8862, 8659, 8459, 8260, 8067, 7874, 7688, - 7502, 7321, 7140, 6965, 6790, 6621, 6452, 6290, 6128, 5968, - 5808, 5655, 5503, 5356, 5209, 5069, 4929, 4794, 4660, 4532, - 4404, 4282, 4160, 4041, 3922, 3803, 3684, 3568, 3452, 3343, - 3234, 3131, 3029, 2931, 2833, 2741, 2649, 2563, 2477, 2396, - 2316, 2236, 2157, 2083, 2009, 1940, 1871, 1807, 1743, 1683, - 1623, 1567, 1511, 1459, 1407, 1357, 1307, 1257, 1207, 1159, - 1111, 1067, 1023, 983, 943, 905, 868, 834, 800, 769, - 738, 709, 681, 653, 625, 600, 575, 552, 529, 508, - 487, 466, 447, 428, 410, 392, 376, 360, 344, 328, - 313, 298, 283, 268, 255, 242, 230, 218, 207, 196, - 186, 176, 167, 158, 150, 142, 135, 128, 121, 114, - 108, 102, 97, 92, 87, 82, 78, 74, 70, 66, - 62, 58, 54, 50, 47, 44, 41, 38, 35, 32, - 30, 28, 26, 24, 22, 20, 18, 16, 14, 13, - 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, - 2, 1, 0 - }, - { - 16384, 16149, 15915, 15681, 15447, 15214, 14981, 14749, 14517, 14286, - 14055, 13827, 13599, 13373, 13147, 12923, 12699, 12476, 12253, 12034, - 11815, 11599, 11383, 11171, 10959, 10750, 10541, 10337, 10133, 9933, - 9733, 9536, 9339, 9142, 8945, 8751, 8557, 8369, 8181, 7998, - 7816, 7638, 7460, 7288, 7116, 6950, 6785, 6625, 6465, 6306, - 6147, 5995, 5843, 5697, 5551, 5411, 5271, 5135, 5000, 4871, - 4742, 4618, 4495, 4374, 4253, 4132, 4011, 3893, 3775, 3663, - 3552, 3446, 3340, 3239, 3138, 3043, 2948, 2858, 2768, 2684, - 2600, 2516, 2433, 2355, 2278, 2205, 2133, 2065, 1997, 1932, - 1867, 1807, 1747, 1690, 1634, 1580, 1526, 1472, 1418, 1366, - 1314, 1266, 1218, 1174, 1130, 1088, 1047, 1009, 971, 936, - 901, 868, 836, 804, 772, 743, 714, 685, 658, 631, - 606, 582, 559, 536, 515, 494, 475, 456, 437, 418, - 399, 380, 362, 344, 328, 312, 297, 283, 270, 257, - 245, 233, 222, 211, 201, 191, 181, 172, 163, 155, - 147, 139, 132, 125, 119, 113, 107, 101, 96, 91, - 86, 81, 76, 71, 66, 62, 58, 54, 50, 46, - 43, 40, 37, 34, 31, 28, 26, 24, 22, 20, - 18, 16, 14, 12, 10, 8, 6, 5, 4, 3, - 2, 1, 0 - }, - { - 16384, 16159, 15934, 15709, 15485, 15261, 15038, 14816, 14594, 14373, - 14152, 13933, 13714, 13497, 13280, 13065, 12850, 12636, 12422, 12211, - 12000, 11791, 11583, 11378, 11173, 10971, 10769, 10571, 10373, 10179, - 9985, 9793, 9601, 9409, 9217, 9029, 8842, 8658, 8475, 8297, - 8120, 7946, 7773, 7604, 7435, 7271, 7108, 6950, 6792, 6634, - 6477, 6326, 6175, 6029, 5883, 5742, 5602, 5466, 5330, 5199, - 5068, 4943, 4818, 4696, 4574, 4452, 4330, 4211, 4093, 3979, - 3866, 3759, 3652, 3549, 3446, 3348, 3250, 3157, 3065, 2977, - 2889, 2802, 2716, 2634, 2553, 2476, 2399, 2326, 2254, 2185, - 2117, 2052, 1987, 1926, 1866, 1808, 1750, 1692, 1634, 1578, - 1522, 1470, 1418, 1369, 1321, 1275, 1229, 1187, 1145, 1105, - 1066, 1027, 991, 955, 919, 883, 850, 817, 786, 756, - 728, 700, 674, 648, 624, 600, 578, 556, 534, 512, - 490, 468, 447, 426, 407, 388, 371, 354, 338, 322, - 307, 293, 280, 267, 255, 243, 231, 219, 209, 199, - 189, 179, 170, 161, 153, 145, 138, 131, 124, 117, - 111, 105, 99, 93, 87, 81, 76, 71, 66, 61, - 57, 53, 49, 45, 42, 39, 36, 33, 30, 27, - 24, 21, 19, 17, 15, 13, 11, 9, 7, 5, - 3, 1, 0 - }, - { - 16384, 16169, 15954, 15739, 15524, 15310, 15096, 14883, 14670, 14458, - 14246, 14035, 13824, 13614, 13405, 13198, 12991, 12785, 12579, 12376, - 12173, 11972, 11772, 11574, 11377, 11182, 10987, 10795, 10603, 10414, - 10226, 10040, 9854, 9668, 9482, 9299, 9116, 8937, 8759, 8585, - 8411, 8241, 8071, 7906, 7741, 7580, 7419, 7263, 7107, 6952, - 6797, 6647, 6497, 6353, 6209, 6070, 5931, 5796, 5661, 5531, - 5401, 5275, 5150, 5027, 4904, 4781, 4658, 4538, 4419, 4304, - 4190, 4081, 3972, 3867, 3762, 3662, 3562, 3467, 3372, 3281, - 3191, 3101, 3012, 2928, 2844, 2764, 2684, 2608, 2533, 2460, - 2387, 2318, 2250, 2185, 2121, 2059, 1997, 1935, 1873, 1813, - 1754, 1698, 1642, 1588, 1535, 1483, 1433, 1384, 1338, 1292, - 1249, 1206, 1165, 1125, 1085, 1045, 1008, 971, 937, 903, - 871, 840, 810, 780, 752, 724, 698, 672, 647, 622, - 597, 572, 548, 524, 502, 480, 460, 440, 421, 403, - 386, 369, 353, 337, 323, 309, 295, 281, 268, 255, - 243, 231, 220, 209, 199, 189, 180, 171, 163, 155, - 147, 139, 131, 123, 116, 109, 102, 95, 89, 83, - 77, 72, 67, 62, 57, 52, 48, 44, 40, 36, - 32, 28, 25, 22, 19, 16, 13, 10, 8, 6, - 4, 2, 0 - }, - { - 16384, 16177, 15970, 15764, 15558, 15353, 15148, 14944, 14740, 14537, - 14334, 14132, 13930, 13729, 13529, 13330, 13131, 12933, 12735, 12539, - 12343, 12150, 11957, 11766, 11576, 11388, 11200, 11015, 10830, 10647, - 10465, 10285, 10105, 9925, 9745, 9568, 9391, 9218, 9045, 8876, - 8707, 8541, 8375, 8213, 8051, 7894, 7737, 7583, 7429, 7277, - 7125, 6977, 6830, 6687, 6544, 6406, 6268, 6133, 5998, 5868, - 5738, 5612, 5487, 5364, 5241, 5118, 4995, 4875, 4755, 4640, - 4525, 4414, 4304, 4198, 4092, 3990, 3888, 3790, 3693, 3600, - 3507, 3415, 3323, 3235, 3147, 3064, 2981, 2902, 2823, 2746, - 2670, 2594, 2522, 2450, 2382, 2314, 2248, 2182, 2116, 2050, - 1987, 1924, 1864, 1804, 1748, 1692, 1638, 1585, 1534, 1484, - 1437, 1390, 1346, 1302, 1258, 1215, 1174, 1133, 1095, 1057, - 1021, 986, 952, 918, 887, 856, 827, 798, 770, 742, - 714, 686, 659, 632, 607, 582, 559, 536, 514, 492, - 472, 452, 433, 415, 398, 381, 364, 348, 333, 318, - 304, 290, 277, 264, 252, 240, 229, 218, 208, 198, - 188, 178, 168, 158, 149, 140, 132, 124, 116, 108, - 101, 94, 87, 81, 75, 69, 64, 59, 54, 49, - 44, 39, 35, 31, 27, 23, 19, 15, 12, 9, - 6, 3, 0 - } -}; - - -static const uint16_t cf_tables_3[5][257] = { - { - 16384, 16187, 15990, 15793, 15597, 15401, 15205, 15009, 14813, 14618, - 14423, 14230, 14037, 13845, 13653, 13463, 13273, 13083, 12894, 12706, - 12518, 12332, 12146, 11962, 11778, 11597, 11416, 11237, 11059, 10882, - 10706, 10532, 10358, 10184, 10010, 9838, 9666, 9497, 9328, 9163, - 8999, 8837, 8675, 8517, 8359, 8205, 8051, 7901, 7751, 7602, - 7453, 7308, 7163, 7022, 6882, 6745, 6609, 6476, 6343, 6214, - 6085, 5960, 5835, 5712, 5589, 5466, 5343, 5223, 5103, 4987, - 4872, 4761, 4650, 4542, 4435, 4332, 4229, 4130, 4031, 3936, - 3841, 3747, 3653, 3563, 3473, 3387, 3302, 3220, 3138, 3059, - 2980, 2905, 2830, 2759, 2688, 2619, 2550, 2481, 2412, 2345, - 2278, 2215, 2152, 2092, 2032, 1974, 1917, 1863, 1809, 1758, - 1707, 1659, 1611, 1564, 1517, 1473, 1429, 1387, 1346, 1307, - 1268, 1230, 1193, 1158, 1123, 1090, 1058, 1026, 994, 962, - 930, 899, 869, 841, 813, 786, 760, 735, 710, 687, - 664, 643, 622, 602, 582, 562, 543, 525, 507, 490, - 473, 457, 442, 427, 412, 398, 385, 373, 361, 349, - 337, 325, 313, 301, 290, 279, 269, 259, 249, 240, - 231, 222, 214, 206, 199, 192, 185, 178, 171, 165, - 159, 153, 148, 143, 138, 133, 128, 123, 119, 115, - 111, 107, 103, 99, 95, 91, 87, 83, 80, 77, - 74, 71, 68, 65, 63, 61, 59, 57, 55, 53, - 51, 49, 47, 45, 43, 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, 0 - }, - { - 16384, 16195, 16006, 15817, 15629, 15441, 15253, 15065, 14878, 14692, - 14506, 14321, 14136, 13952, 13768, 13585, 13402, 13219, 13037, 12857, - 12677, 12499, 12321, 12144, 11967, 11792, 11617, 11444, 11271, 11100, - 10930, 10762, 10594, 10426, 10258, 10091, 9925, 9761, 9598, 9438, - 9278, 9120, 8963, 8809, 8655, 8504, 8354, 8207, 8060, 7914, - 7769, 7627, 7485, 7347, 7209, 7074, 6939, 6807, 6676, 6548, - 6420, 6296, 6172, 6050, 5928, 5806, 5684, 5564, 5444, 5328, - 5212, 5100, 4988, 4879, 4771, 4667, 4563, 4462, 4362, 4265, - 4169, 4073, 3978, 3886, 3795, 3707, 3619, 3535, 3451, 3369, - 3288, 3210, 3133, 3059, 2985, 2913, 2841, 2769, 2697, 2627, - 2557, 2490, 2424, 2360, 2297, 2237, 2177, 2119, 2062, 2007, - 1953, 1901, 1849, 1798, 1748, 1700, 1652, 1607, 1562, 1519, - 1476, 1435, 1394, 1355, 1317, 1281, 1245, 1210, 1175, 1140, - 1105, 1071, 1037, 1005, 973, 943, 913, 885, 857, 830, - 804, 779, 754, 731, 708, 685, 663, 642, 621, 601, - 581, 563, 545, 528, 511, 495, 479, 463, 448, 433, - 419, 405, 391, 377, 364, 351, 338, 326, 314, 302, - 291, 280, 270, 260, 251, 242, 234, 226, 218, 210, - 202, 195, 188, 181, 174, 168, 162, 156, 150, 144, - 139, 134, 129, 124, 119, 114, 109, 104, 100, 96, - 92, 88, 84, 80, 77, 74, 71, 68, 65, 62, - 59, 56, 54, 52, 50, 48, 46, 44, 42, 40, - 38, 36, 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, 0 - }, - { - 16384, 16203, 16022, 15842, 15662, 15482, 15302, 15122, 14942, 14763, - 14584, 14406, 14228, 14051, 13874, 13698, 13522, 13347, 13172, 12998, - 12824, 12652, 12480, 12310, 12140, 11971, 11803, 11637, 11471, 11307, - 11143, 10980, 10817, 10654, 10491, 10330, 10169, 10011, 9853, 9697, - 9542, 9389, 9236, 9086, 8936, 8789, 8642, 8498, 8355, 8212, - 8070, 7931, 7792, 7656, 7520, 7388, 7256, 7126, 6996, 6870, - 6744, 6621, 6498, 6377, 6256, 6135, 6014, 5895, 5776, 5660, - 5545, 5433, 5321, 5212, 5104, 4999, 4895, 4793, 4692, 4594, - 4496, 4400, 4304, 4211, 4118, 4028, 3939, 3853, 3767, 3684, - 3601, 3521, 3441, 3364, 3287, 3212, 3137, 3062, 2987, 2915, - 2843, 2773, 2704, 2638, 2572, 2508, 2445, 2384, 2324, 2266, - 2208, 2153, 2098, 2044, 1990, 1939, 1888, 1839, 1791, 1745, - 1699, 1655, 1611, 1569, 1527, 1487, 1448, 1409, 1370, 1331, - 1292, 1255, 1218, 1183, 1148, 1115, 1082, 1051, 1020, 990, - 960, 932, 904, 878, 852, 826, 801, 777, 753, 731, - 709, 687, 666, 645, 625, 605, 586, 567, 550, 533, - 516, 499, 482, 465, 449, 433, 418, 403, 389, 375, - 362, 349, 337, 325, 314, 303, 293, 283, 273, 263, - 254, 245, 236, 227, 219, 211, 204, 197, 190, 183, - 177, 171, 165, 159, 153, 147, 141, 135, 130, 125, - 120, 115, 110, 105, 101, 97, 93, 89, 85, 81, - 77, 74, 71, 68, 65, 62, 59, 56, 53, 51, - 49, 47, 45, 43, 41, 39, 37, 35, 33, 31, - 29, 27, 25, 23, 22, 21, 20, 19, 18, 17, - 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, - 6, 5, 4, 3, 2, 1, 0 - }, - { - 16384, 16210, 16036, 15863, 15690, 15517, 15344, 15172, 15000, 14828, - 14656, 14485, 14314, 14145, 13976, 13808, 13640, 13472, 13304, 13137, - 12970, 12804, 12639, 12475, 12312, 12149, 11987, 11827, 11667, 11508, - 11349, 11192, 11035, 10878, 10721, 10565, 10410, 10257, 10104, 9953, - 9802, 9654, 9506, 9359, 9213, 9070, 8927, 8787, 8647, 8508, - 8369, 8233, 8097, 7964, 7831, 7700, 7570, 7442, 7315, 7190, - 7065, 6943, 6821, 6701, 6581, 6461, 6341, 6223, 6105, 5990, - 5876, 5764, 5653, 5545, 5437, 5331, 5226, 5124, 5022, 4924, - 4826, 4729, 4632, 4538, 4444, 4353, 4262, 4174, 4087, 4002, - 3917, 3835, 3753, 3674, 3595, 3518, 3441, 3364, 3287, 3212, - 3138, 3066, 2995, 2926, 2858, 2792, 2726, 2662, 2599, 2538, - 2478, 2420, 2362, 2305, 2249, 2195, 2141, 2089, 2037, 1988, - 1939, 1891, 1844, 1799, 1754, 1711, 1668, 1626, 1584, 1542, - 1500, 1459, 1418, 1380, 1342, 1305, 1269, 1234, 1199, 1166, - 1133, 1102, 1071, 1041, 1012, 983, 954, 926, 899, 872, - 847, 822, 798, 774, 751, 728, 707, 686, 666, 646, - 627, 608, 589, 570, 552, 534, 517, 500, 484, 468, - 453, 438, 424, 410, 397, 384, 372, 360, 348, 336, - 325, 314, 303, 293, 283, 273, 264, 255, 246, 237, - 229, 221, 213, 205, 197, 189, 181, 174, 167, 160, - 154, 148, 142, 136, 131, 126, 121, 116, 111, 106, - 101, 97, 93, 89, 85, 81, 77, 73, 70, 67, - 64, 61, 58, 55, 52, 49, 46, 43, 40, 37, - 35, 33, 31, 29, 27, 25, 23, 21, 19, 17, - 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, - 6, 5, 4, 3, 2, 1, 0 - }, - { - 16384, 16218, 16052, 15886, 15720, 15554, 15389, 15224, 15059, 14895, - 14731, 14567, 14403, 14240, 14077, 13915, 13753, 13591, 13429, 13269, - 13109, 12950, 12791, 12633, 12476, 12320, 12164, 12009, 11854, 11701, - 11548, 11396, 11244, 11092, 10940, 10790, 10640, 10492, 10344, 10198, - 10052, 9908, 9764, 9622, 9481, 9342, 9203, 9066, 8929, 8793, - 8657, 8524, 8391, 8261, 8131, 8003, 7875, 7749, 7624, 7502, - 7380, 7260, 7140, 7022, 6904, 6786, 6668, 6551, 6435, 6322, - 6209, 6099, 5989, 5881, 5773, 5668, 5563, 5461, 5359, 5260, - 5161, 5063, 4965, 4871, 4777, 4686, 4595, 4506, 4417, 4331, - 4245, 4162, 4079, 3999, 3919, 3841, 3763, 3685, 3607, 3530, - 3454, 3380, 3307, 3236, 3166, 3097, 3029, 2963, 2897, 2834, - 2771, 2710, 2650, 2591, 2532, 2475, 2418, 2363, 2309, 2257, - 2205, 2155, 2105, 2057, 2009, 1963, 1918, 1873, 1828, 1783, - 1738, 1694, 1650, 1607, 1565, 1524, 1484, 1445, 1407, 1369, - 1333, 1297, 1263, 1229, 1197, 1165, 1134, 1103, 1073, 1043, - 1015, 987, 960, 933, 907, 882, 858, 834, 811, 788, - 766, 744, 722, 700, 679, 658, 638, 618, 599, 581, - 563, 545, 528, 511, 495, 480, 465, 451, 437, 423, - 410, 397, 384, 372, 360, 348, 337, 326, 315, 305, - 295, 285, 275, 265, 255, 245, 236, 227, 219, 211, - 203, 195, 188, 181, 174, 167, 161, 155, 149, 143, - 137, 131, 126, 121, 116, 111, 106, 101, 97, 93, - 89, 85, 81, 77, 73, 69, 65, 61, 58, 55, - 52, 49, 46, 43, 40, 37, 34, 32, 30, 28, - 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, - 6, 5, 4, 3, 2, 1, 0 - } -}; - - -static const uint16_t * const cf_table[16] = { - cf_tables_1[0], cf_tables_1[1], cf_tables_1[2], cf_tables_2[0], - cf_tables_2[1], cf_tables_2[2], cf_tables_2[3], cf_tables_2[4], - cf_tables_2[5], cf_tables_2[6], cf_tables_2[7], cf_tables_3[0], - cf_tables_3[1], cf_tables_3[2], cf_tables_3[3], cf_tables_3[4] -}; - - -/** Initializes a given lookup table using a given delta - */ -static void bgmc_lut_fillp(uint8_t *lut, unsigned int *lut_status, - unsigned int delta) -{ - unsigned int sx, i; - - for (sx = 0; sx < 16; sx++) - for (i = 0; i < LUT_SIZE; i++) { - unsigned int target = (i + 1) << (FREQ_BITS - LUT_BITS); - unsigned int symbol = 1 << delta; - - while (cf_table[sx][symbol] > target) - symbol += 1 << delta; - - *lut++ = symbol >> delta; - } - - *lut_status = delta; -} - - -/** Retunes the index of a suitable lookup table for a given delta - */ -static uint8_t* bgmc_lut_getp(uint8_t *lut, unsigned int *lut_status, - unsigned int delta) -{ - unsigned int i = av_clip(delta, 0, LUT_BUFF - 1); - - lut += (i * LUT_SIZE) << 4; - - if (lut_status[i] != delta) - bgmc_lut_fillp(lut, &lut_status[i], delta); - - return lut; -} - - -/** Initializes the lookup table arrays - */ -int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, unsigned int **cf_lut_status) -{ - *cf_lut = av_malloc(sizeof(*cf_lut ) * LUT_BUFF * 16 * LUT_SIZE); - *cf_lut_status = av_malloc(sizeof(*cf_lut_status) * LUT_BUFF); - - if (!cf_lut || !cf_lut_status) { - ff_bgmc_end(cf_lut, cf_lut_status); - av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - return AVERROR(ENOMEM); - } - - return 0; -} - - -/** Releases the lookup table arrays - */ -void ff_bgmc_end(uint8_t **cf_lut, unsigned int **cf_lut_status) -{ - av_freep(cf_lut); - av_freep(cf_lut_status); -} - - -/** Initializes decoding and reads the first value - */ -void ff_bgmc_decode_init(GetBitContext *gb, - unsigned int *h, unsigned int *l, unsigned int *v) -{ - *h = TOP_VALUE; - *l = 0; - *v = get_bits_long(gb, VALUE_BITS); -} - - -/** Finish decoding - */ -void ff_bgmc_decode_end(GetBitContext *gb) -{ - skip_bits_long(gb, -(VALUE_BITS - 2)); -} - - -/** Reads and decodes a block Gilbert-Moore coded symbol - */ -void ff_bgmc_decode(GetBitContext *gb, unsigned int num, int32_t *dst, - unsigned int delta, unsigned int sx, - unsigned int *h, unsigned int *l, unsigned int *v, - uint8_t *cf_lut, unsigned int *cf_lut_status) -{ - unsigned int i; - uint8_t *lut = bgmc_lut_getp(cf_lut, cf_lut_status, delta); - - // read current state - unsigned int high = *h; - unsigned int low = *l; - unsigned int value = *v; - - lut += sx * LUT_SIZE; - - // decode num samples - for (i = 0; i < num; i++) { - unsigned int range = high - low + 1; - unsigned int target = (((value - low + 1) << FREQ_BITS) - 1) / range; - unsigned int symbol = lut[target >> (FREQ_BITS - LUT_BITS)] << delta; - - while (cf_table[sx][symbol] > target) - symbol += 1 << delta; - - symbol = (symbol >> delta) - 1; - - high = low + ((range * cf_table[sx][(symbol ) << delta] - (1 << FREQ_BITS)) >> FREQ_BITS); - low = low + ((range * cf_table[sx][(symbol + 1) << delta] ) >> FREQ_BITS); - - while (1) { - if (high >= HALF) { - if (low >= HALF) { - value -= HALF; - low -= HALF; - high -= HALF; - } else if (low >= FIRST_QTR && high < THIRD_QTR) { - value -= FIRST_QTR; - low -= FIRST_QTR; - high -= FIRST_QTR; - } else break; - } - - low *= 2; - high = 2 * high + 1; - value = 2 * value + get_bits1(gb); - } - - *dst++ = symbol; - } - - // save current state - *h = high; - *l = low; - *v = value; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/bgmc.h b/tizen/distrib/ffmpeg/libavcodec/bgmc.h deleted file mode 100644 index eab413b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bgmc.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Block Gilbert-Moore decoder - * Copyright (c) 2010 Thilo Borgmann - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Block Gilbert-Moore decoder header - * @author Thilo Borgmann - */ - - -#ifndef AVCODEC_BGMC_H -#define AVCODEC_BGMC_H - - -#include "avcodec.h" -#include "get_bits.h" - - -int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, unsigned int **cf_lut_status); - - -void ff_bgmc_end(uint8_t **cf_lut, unsigned int **cf_lut_status); - - -void ff_bgmc_decode_init(GetBitContext *gb, - unsigned int *h, unsigned int *l, unsigned int *v); - - -void ff_bgmc_decode_end(GetBitContext *gb); - - -void ff_bgmc_decode(GetBitContext *gb, unsigned int num, int32_t *dst, - unsigned int delta, unsigned int sx, - unsigned int *h, unsigned int *l, unsigned int *v, - uint8_t *cf_lut, unsigned int *cf_lut_status); - - -#endif /* AVCODEC_BGMC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/bink.c b/tizen/distrib/ffmpeg/libavcodec/bink.c deleted file mode 100644 index a988a34..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bink.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * Bink video decoder - * Copyright (c) 2009 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "binkdata.h" -#include "mathops.h" - -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" - -#define BINK_FLAG_ALPHA 0x00100000 -#define BINK_FLAG_GRAY 0x00020000 - -static VLC bink_trees[16]; - -/** - * IDs for different data types used in Bink video codec - */ -enum Sources { - BINK_SRC_BLOCK_TYPES = 0, ///< 8x8 block types - BINK_SRC_SUB_BLOCK_TYPES, ///< 16x16 block types (a subset of 8x8 block types) - BINK_SRC_COLORS, ///< pixel values used for different block types - BINK_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill - BINK_SRC_X_OFF, ///< X components of motion value - BINK_SRC_Y_OFF, ///< Y components of motion value - BINK_SRC_INTRA_DC, ///< DC values for intrablocks with DCT - BINK_SRC_INTER_DC, ///< DC values for interblocks with DCT - BINK_SRC_RUN, ///< run lengths for special fill block - - BINK_NB_SRC -}; - -/** - * data needed to decode 4-bit Huffman-coded value - */ -typedef struct Tree { - int vlc_num; ///< tree number (in bink_trees[]) - uint8_t syms[16]; ///< leaf value to symbol mapping -} Tree; - -#define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\ - bink_trees[(tree).vlc_num].bits, 1)] - -/** - * data structure used for decoding single Bink data type - */ -typedef struct Bundle { - int len; ///< length of number of entries to decode (in bits) - Tree tree; ///< Huffman tree-related data - uint8_t *data; ///< buffer for decoded symbols - uint8_t *data_end; ///< buffer end - uint8_t *cur_dec; ///< pointer to the not yet decoded part of the buffer - uint8_t *cur_ptr; ///< pointer to the data that is not read from buffer yet -} Bundle; - -/* - * Decoder context - */ -typedef struct BinkContext { - AVCodecContext *avctx; - DSPContext dsp; - AVFrame pic, last; - int version; ///< internal Bink file version - int has_alpha; - int swap_planes; - ScanTable scantable; ///< permutated scantable for DCT coeffs decoding - - Bundle bundle[BINK_NB_SRC]; ///< bundles for decoding all data types - Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type - int col_lastval; ///< value of last decoded high nibble in "colours" data type -} BinkContext; - -/** - * Bink video block types - */ -enum BlockTypes { - SKIP_BLOCK = 0, ///< skipped block - SCALED_BLOCK, ///< block has size 16x16 - MOTION_BLOCK, ///< block is copied from previous frame with some offset - RUN_BLOCK, ///< block is composed from runs of colours with custom scan order - RESIDUE_BLOCK, ///< motion block with some difference added - INTRA_BLOCK, ///< intra DCT block - FILL_BLOCK, ///< block is filled with single colour - INTER_BLOCK, ///< motion block with DCT applied to the difference - PATTERN_BLOCK, ///< block is filled with two colours following custom pattern - RAW_BLOCK, ///< uncoded 8x8 block -}; - -/** - * Initializes length length in all bundles. - * - * @param c decoder context - * @param width plane width - * @param bw plane width in 8x8 blocks - */ -static void init_lengths(BinkContext *c, int width, int bw) -{ - c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1; - - c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1; - - c->bundle[BINK_SRC_COLORS].len = av_log2((width >> 3)*64 + 511) + 1; - - c->bundle[BINK_SRC_INTRA_DC].len = - c->bundle[BINK_SRC_INTER_DC].len = - c->bundle[BINK_SRC_X_OFF].len = - c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1; - - c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1; - - c->bundle[BINK_SRC_RUN].len = av_log2((width >> 3)*48 + 511) + 1; -} - -/** - * Allocates memory for bundles. - * - * @param c decoder context - */ -static av_cold void init_bundles(BinkContext *c) -{ - int bw, bh, blocks; - int i; - - bw = (c->avctx->width + 7) >> 3; - bh = (c->avctx->height + 7) >> 3; - blocks = bw * bh; - - for (i = 0; i < BINK_NB_SRC; i++) { - c->bundle[i].data = av_malloc(blocks * 64); - c->bundle[i].data_end = c->bundle[i].data + blocks * 64; - } -} - -/** - * Frees memory used by bundles. - * - * @param c decoder context - */ -static av_cold void free_bundles(BinkContext *c) -{ - int i; - for (i = 0; i < BINK_NB_SRC; i++) - av_freep(&c->bundle[i].data); -} - -/** - * Merges two consequent lists of equal size depending on bits read. - * - * @param gb context for reading bits - * @param dst buffer where merged list will be written to - * @param src pointer to the head of the first list (the second lists starts at src+size) - * @param size input lists size - */ -static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size) -{ - uint8_t *src2 = src + size; - int size2 = size; - - do { - if (!get_bits1(gb)) { - *dst++ = *src++; - size--; - } else { - *dst++ = *src2++; - size2--; - } - } while (size && size2); - - while (size--) - *dst++ = *src++; - while (size2--) - *dst++ = *src2++; -} - -/** - * Reads information about Huffman tree used to decode data. - * - * @param gb context for reading bits - * @param tree pointer for storing tree data - */ -static void read_tree(GetBitContext *gb, Tree *tree) -{ - uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2; - int i, t, len; - - tree->vlc_num = get_bits(gb, 4); - if (!tree->vlc_num) { - for (i = 0; i < 16; i++) - tree->syms[i] = i; - return; - } - if (get_bits1(gb)) { - len = get_bits(gb, 3); - memset(tmp1, 0, sizeof(tmp1)); - for (i = 0; i <= len; i++) { - tree->syms[i] = get_bits(gb, 4); - tmp1[tree->syms[i]] = 1; - } - for (i = 0; i < 16; i++) - if (!tmp1[i]) - tree->syms[++len] = i; - } else { - len = get_bits(gb, 2); - for (i = 0; i < 16; i++) - in[i] = i; - for (i = 0; i <= len; i++) { - int size = 1 << i; - for (t = 0; t < 16; t += size << 1) - merge(gb, out + t, in + t, size); - FFSWAP(uint8_t*, in, out); - } - memcpy(tree->syms, in, 16); - } -} - -/** - * Prepares bundle for decoding data. - * - * @param gb context for reading bits - * @param c decoder context - * @param bundle_num number of the bundle to initialize - */ -static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num) -{ - int i; - - if (bundle_num == BINK_SRC_COLORS) { - for (i = 0; i < 16; i++) - read_tree(gb, &c->col_high[i]); - c->col_lastval = 0; - } - if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC) - read_tree(gb, &c->bundle[bundle_num].tree); - c->bundle[bundle_num].cur_dec = - c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; -} - -/** - * common check before starting decoding bundle data - * - * @param gb context for reading bits - * @param b bundle - * @param t variable where number of elements to decode will be stored - */ -#define CHECK_READ_VAL(gb, b, t) \ - if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \ - return 0; \ - t = get_bits(gb, b->len); \ - if (!t) { \ - b->cur_dec = NULL; \ - return 0; \ - } \ - -static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) -{ - int t, v; - const uint8_t *dec_end; - - CHECK_READ_VAL(gb, b, t); - dec_end = b->cur_dec + t; - if (dec_end > b->data_end) { - av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n"); - return -1; - } - if (get_bits1(gb)) { - v = get_bits(gb, 4); - memset(b->cur_dec, v, t); - b->cur_dec += t; - } else { - while (b->cur_dec < dec_end) - *b->cur_dec++ = GET_HUFF(gb, b->tree); - } - return 0; -} - -static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) -{ - int t, sign, v; - const uint8_t *dec_end; - - CHECK_READ_VAL(gb, b, t); - dec_end = b->cur_dec + t; - if (dec_end > b->data_end) { - av_log(avctx, AV_LOG_ERROR, "Too many motion values\n"); - return -1; - } - if (get_bits1(gb)) { - v = get_bits(gb, 4); - if (v) { - sign = -get_bits1(gb); - v = (v ^ sign) - sign; - } - memset(b->cur_dec, v, t); - b->cur_dec += t; - } else { - do { - v = GET_HUFF(gb, b->tree); - if (v) { - sign = -get_bits1(gb); - v = (v ^ sign) - sign; - } - *b->cur_dec++ = v; - } while (b->cur_dec < dec_end); - } - return 0; -} - -const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 }; - -static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) -{ - int t, v; - int last = 0; - const uint8_t *dec_end; - - CHECK_READ_VAL(gb, b, t); - dec_end = b->cur_dec + t; - if (dec_end > b->data_end) { - av_log(avctx, AV_LOG_ERROR, "Too many block type values\n"); - return -1; - } - if (get_bits1(gb)) { - v = get_bits(gb, 4); - memset(b->cur_dec, v, t); - b->cur_dec += t; - } else { - do { - v = GET_HUFF(gb, b->tree); - if (v < 12) { - last = v; - *b->cur_dec++ = v; - } else { - int run = bink_rlelens[v - 12]; - - memset(b->cur_dec, last, run); - b->cur_dec += run; - } - } while (b->cur_dec < dec_end); - } - return 0; -} - -static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) -{ - int t, v; - const uint8_t *dec_end; - - CHECK_READ_VAL(gb, b, t); - dec_end = b->cur_dec + t; - if (dec_end > b->data_end) { - av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n"); - return -1; - } - while (b->cur_dec < dec_end) { - v = GET_HUFF(gb, b->tree); - v |= GET_HUFF(gb, b->tree) << 4; - *b->cur_dec++ = v; - } - - return 0; -} - -static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) -{ - int t, sign, v; - const uint8_t *dec_end; - - CHECK_READ_VAL(gb, b, t); - dec_end = b->cur_dec + t; - if (dec_end > b->data_end) { - av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n"); - return -1; - } - if (get_bits1(gb)) { - c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); - v = GET_HUFF(gb, b->tree); - v = (c->col_lastval << 4) | v; - if (c->version < 'i') { - sign = ((int8_t) v) >> 7; - v = ((v & 0x7F) ^ sign) - sign; - v += 0x80; - } - memset(b->cur_dec, v, t); - b->cur_dec += t; - } else { - while (b->cur_dec < dec_end) { - c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); - v = GET_HUFF(gb, b->tree); - v = (c->col_lastval << 4) | v; - if (c->version < 'i') { - sign = ((int8_t) v) >> 7; - v = ((v & 0x7F) ^ sign) - sign; - v += 0x80; - } - *b->cur_dec++ = v; - } - } - return 0; -} - -/** number of bits used to store first DC value in bundle */ -#define DC_START_BITS 11 - -static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, - int start_bits, int has_sign) -{ - int i, j, len, len2, bsize, sign, v, v2; - int16_t *dst = (int16_t*)b->cur_dec; - - CHECK_READ_VAL(gb, b, len); - v = get_bits(gb, start_bits - has_sign); - if (v && has_sign) { - sign = -get_bits1(gb); - v = (v ^ sign) - sign; - } - *dst++ = v; - len--; - for (i = 0; i < len; i += 8) { - len2 = FFMIN(len - i, 8); - bsize = get_bits(gb, 4); - if (bsize) { - for (j = 0; j < len2; j++) { - v2 = get_bits(gb, bsize); - if (v2) { - sign = -get_bits1(gb); - v2 = (v2 ^ sign) - sign; - } - v += v2; - *dst++ = v; - if (v < -32768 || v > 32767) { - av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v); - return -1; - } - } - } else { - for (j = 0; j < len2; j++) - *dst++ = v; - } - } - - b->cur_dec = (uint8_t*)dst; - return 0; -} - -/** - * Retrieves next value from bundle. - * - * @param c decoder context - * @param bundle bundle number - */ -static inline int get_value(BinkContext *c, int bundle) -{ - int16_t ret; - - if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN) - return *c->bundle[bundle].cur_ptr++; - if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF) - return (int8_t)*c->bundle[bundle].cur_ptr++; - ret = *(int16_t*)c->bundle[bundle].cur_ptr; - c->bundle[bundle].cur_ptr += 2; - return ret; -} - -/** - * Reads 8x8 block of DCT coefficients. - * - * @param gb context for reading bits - * @param block place for storing coefficients - * @param scan scan order table - * @param is_intra tells what set of quantizer matrices to use - * @return 0 for success, negative value in other cases - */ -static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan, - int is_intra) -{ - int coef_list[128]; - int mode_list[128]; - int i, t, mask, bits, ccoef, mode, sign; - int list_start = 64, list_end = 64, list_pos; - int coef_count = 0; - int coef_idx[64]; - int quant_idx; - const uint32_t *quant; - - coef_list[list_end] = 4; mode_list[list_end++] = 0; - coef_list[list_end] = 24; mode_list[list_end++] = 0; - coef_list[list_end] = 44; mode_list[list_end++] = 0; - coef_list[list_end] = 1; mode_list[list_end++] = 3; - coef_list[list_end] = 2; mode_list[list_end++] = 3; - coef_list[list_end] = 3; mode_list[list_end++] = 3; - - bits = get_bits(gb, 4) - 1; - for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) { - list_pos = list_start; - while (list_pos < list_end) { - if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) { - list_pos++; - continue; - } - ccoef = coef_list[list_pos]; - mode = mode_list[list_pos]; - switch (mode) { - case 0: - coef_list[list_pos] = ccoef + 4; - mode_list[list_pos] = 1; - case 2: - if (mode == 2) { - coef_list[list_pos] = 0; - mode_list[list_pos++] = 0; - } - for (i = 0; i < 4; i++, ccoef++) { - if (get_bits1(gb)) { - coef_list[--list_start] = ccoef; - mode_list[ list_start] = 3; - } else { - int t; - if (!bits) { - t = 1 - (get_bits1(gb) << 1); - } else { - t = get_bits(gb, bits) | mask; - sign = -get_bits1(gb); - t = (t ^ sign) - sign; - } - block[scan[ccoef]] = t; - coef_idx[coef_count++] = ccoef; - } - } - break; - case 1: - mode_list[list_pos] = 2; - for (i = 0; i < 3; i++) { - ccoef += 4; - coef_list[list_end] = ccoef; - mode_list[list_end++] = 2; - } - break; - case 3: - if (!bits) { - t = 1 - (get_bits1(gb) << 1); - } else { - t = get_bits(gb, bits) | mask; - sign = -get_bits1(gb); - t = (t ^ sign) - sign; - } - block[scan[ccoef]] = t; - coef_idx[coef_count++] = ccoef; - coef_list[list_pos] = 0; - mode_list[list_pos++] = 0; - break; - } - } - } - - quant_idx = get_bits(gb, 4); - quant = is_intra ? bink_intra_quant[quant_idx] - : bink_inter_quant[quant_idx]; - block[0] = (block[0] * quant[0]) >> 11; - for (i = 0; i < coef_count; i++) { - int idx = coef_idx[i]; - block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11; - } - - return 0; -} - -/** - * Reads 8x8 block with residue after motion compensation. - * - * @param gb context for reading bits - * @param block place to store read data - * @param masks_count number of masks to decode - * @return 0 on success, negative value in other cases - */ -static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count) -{ - int coef_list[128]; - int mode_list[128]; - int i, sign, mask, ccoef, mode; - int list_start = 64, list_end = 64, list_pos; - int nz_coeff[64]; - int nz_coeff_count = 0; - - coef_list[list_end] = 4; mode_list[list_end++] = 0; - coef_list[list_end] = 24; mode_list[list_end++] = 0; - coef_list[list_end] = 44; mode_list[list_end++] = 0; - coef_list[list_end] = 0; mode_list[list_end++] = 2; - - for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) { - for (i = 0; i < nz_coeff_count; i++) { - if (!get_bits1(gb)) - continue; - if (block[nz_coeff[i]] < 0) - block[nz_coeff[i]] -= mask; - else - block[nz_coeff[i]] += mask; - masks_count--; - if (masks_count < 0) - return 0; - } - list_pos = list_start; - while (list_pos < list_end) { - if (!(coef_list[list_pos] | mode_list[list_pos]) || !get_bits1(gb)) { - list_pos++; - continue; - } - ccoef = coef_list[list_pos]; - mode = mode_list[list_pos]; - switch (mode) { - case 0: - coef_list[list_pos] = ccoef + 4; - mode_list[list_pos] = 1; - case 2: - if (mode == 2) { - coef_list[list_pos] = 0; - mode_list[list_pos++] = 0; - } - for (i = 0; i < 4; i++, ccoef++) { - if (get_bits1(gb)) { - coef_list[--list_start] = ccoef; - mode_list[ list_start] = 3; - } else { - nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; - sign = -get_bits1(gb); - block[bink_scan[ccoef]] = (mask ^ sign) - sign; - masks_count--; - if (masks_count < 0) - return 0; - } - } - break; - case 1: - mode_list[list_pos] = 2; - for (i = 0; i < 3; i++) { - ccoef += 4; - coef_list[list_end] = ccoef; - mode_list[list_end++] = 2; - } - break; - case 3: - nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; - sign = -get_bits1(gb); - block[bink_scan[ccoef]] = (mask ^ sign) - sign; - coef_list[list_pos] = 0; - mode_list[list_pos++] = 0; - masks_count--; - if (masks_count < 0) - return 0; - break; - } - } - } - - return 0; -} - -static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, - int is_chroma) -{ - int blk; - int i, j, bx, by; - uint8_t *dst, *prev, *ref, *ref_start, *ref_end; - int v, col[2]; - const uint8_t *scan; - int xoff, yoff; - DECLARE_ALIGNED(16, DCTELEM, block[64]); - DECLARE_ALIGNED(16, uint8_t, ublock[64]); - int coordmap[64]; - - const int stride = c->pic.linesize[plane_idx]; - int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; - int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; - int width = c->avctx->width >> is_chroma; - - init_lengths(c, FFMAX(width, 8), bw); - for (i = 0; i < BINK_NB_SRC; i++) - read_bundle(gb, c, i); - - ref_start = c->last.data[plane_idx]; - ref_end = c->last.data[plane_idx] - + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; - - for (i = 0; i < 64; i++) - coordmap[i] = (i & 7) + (i >> 3) * stride; - - for (by = 0; by < bh; by++) { - if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) - return -1; - if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) - return -1; - if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0) - return -1; - if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0) - return -1; - if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0) - return -1; - if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) - return -1; - if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) - return -1; - if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) - return -1; - if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0) - return -1; - - if (by == bh) - break; - dst = c->pic.data[plane_idx] + 8*by*stride; - prev = c->last.data[plane_idx] + 8*by*stride; - for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { - blk = get_value(c, BINK_SRC_BLOCK_TYPES); - // 16x16 block type on odd line means part of the already decoded block, so skip it - if ((by & 1) && blk == SCALED_BLOCK) { - bx++; - dst += 8; - prev += 8; - continue; - } - switch (blk) { - case SKIP_BLOCK: - c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8); - break; - case SCALED_BLOCK: - blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); - switch (blk) { - case RUN_BLOCK: - scan = bink_patterns[get_bits(gb, 4)]; - i = 0; - do { - int run = get_value(c, BINK_SRC_RUN) + 1; - - i += run; - if (i > 64) { - av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - if (get_bits1(gb)) { - v = get_value(c, BINK_SRC_COLORS); - for (j = 0; j < run; j++) - ublock[*scan++] = v; - } else { - for (j = 0; j < run; j++) - ublock[*scan++] = get_value(c, BINK_SRC_COLORS); - } - } while (i < 63); - if (i == 63) - ublock[*scan++] = get_value(c, BINK_SRC_COLORS); - break; - case INTRA_BLOCK: - c->dsp.clear_block(block); - block[0] = get_value(c, BINK_SRC_INTRA_DC); - read_dct_coeffs(gb, block, c->scantable.permutated, 1); - c->dsp.idct(block); - c->dsp.put_pixels_nonclamped(block, ublock, 8); - break; - case FILL_BLOCK: - v = get_value(c, BINK_SRC_COLORS); - c->dsp.fill_block_tab[0](dst, v, stride, 16); - break; - case PATTERN_BLOCK: - for (i = 0; i < 2; i++) - col[i] = get_value(c, BINK_SRC_COLORS); - for (j = 0; j < 8; j++) { - v = get_value(c, BINK_SRC_PATTERN); - for (i = 0; i < 8; i++, v >>= 1) - ublock[i + j*8] = col[v & 1]; - } - break; - case RAW_BLOCK: - for (j = 0; j < 8; j++) - for (i = 0; i < 8; i++) - ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); - break; - default: - av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); - return -1; - } - if (blk != FILL_BLOCK) - c->dsp.scale_block(ublock, dst, stride); - bx++; - dst += 8; - prev += 8; - break; - case MOTION_BLOCK: - xoff = get_value(c, BINK_SRC_X_OFF); - yoff = get_value(c, BINK_SRC_Y_OFF); - ref = prev + xoff + yoff * stride; - if (ref < ref_start || ref > ref_end) { - av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", - bx*8 + xoff, by*8 + yoff); - return -1; - } - c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); - break; - case RUN_BLOCK: - scan = bink_patterns[get_bits(gb, 4)]; - i = 0; - do { - int run = get_value(c, BINK_SRC_RUN) + 1; - - i += run; - if (i > 64) { - av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - if (get_bits1(gb)) { - v = get_value(c, BINK_SRC_COLORS); - for (j = 0; j < run; j++) - dst[coordmap[*scan++]] = v; - } else { - for (j = 0; j < run; j++) - dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); - } - } while (i < 63); - if (i == 63) - dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); - break; - case RESIDUE_BLOCK: - xoff = get_value(c, BINK_SRC_X_OFF); - yoff = get_value(c, BINK_SRC_Y_OFF); - ref = prev + xoff + yoff * stride; - if (ref < ref_start || ref > ref_end) { - av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", - bx*8 + xoff, by*8 + yoff); - return -1; - } - c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); - c->dsp.clear_block(block); - v = get_bits(gb, 7); - read_residue(gb, block, v); - c->dsp.add_pixels8(dst, block, stride); - break; - case INTRA_BLOCK: - c->dsp.clear_block(block); - block[0] = get_value(c, BINK_SRC_INTRA_DC); - read_dct_coeffs(gb, block, c->scantable.permutated, 1); - c->dsp.idct_put(dst, stride, block); - break; - case FILL_BLOCK: - v = get_value(c, BINK_SRC_COLORS); - c->dsp.fill_block_tab[1](dst, v, stride, 8); - break; - case INTER_BLOCK: - xoff = get_value(c, BINK_SRC_X_OFF); - yoff = get_value(c, BINK_SRC_Y_OFF); - ref = prev + xoff + yoff * stride; - c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); - c->dsp.clear_block(block); - block[0] = get_value(c, BINK_SRC_INTER_DC); - read_dct_coeffs(gb, block, c->scantable.permutated, 0); - c->dsp.idct_add(dst, stride, block); - break; - case PATTERN_BLOCK: - for (i = 0; i < 2; i++) - col[i] = get_value(c, BINK_SRC_COLORS); - for (i = 0; i < 8; i++) { - v = get_value(c, BINK_SRC_PATTERN); - for (j = 0; j < 8; j++, v >>= 1) - dst[i*stride + j] = col[v & 1]; - } - break; - case RAW_BLOCK: - for (i = 0; i < 8; i++) - memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8); - c->bundle[BINK_SRC_COLORS].cur_ptr += 64; - break; - default: - av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); - return -1; - } - } - } - if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary - skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) -{ - BinkContext * const c = avctx->priv_data; - GetBitContext gb; - int plane, plane_idx; - int bits_count = pkt->size << 3; - - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - if(avctx->get_buffer(avctx, &c->pic) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - init_get_bits(&gb, pkt->data, bits_count); - if (c->has_alpha) { - if (c->version >= 'i') - skip_bits_long(&gb, 32); - if (bink_decode_plane(c, &gb, 3, 0) < 0) - return -1; - } - if (c->version >= 'i') - skip_bits_long(&gb, 32); - - for (plane = 0; plane < 3; plane++) { - plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); - - if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0) - return -1; - if (get_bits_count(&gb) >= bits_count) - break; - } - emms_c(); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - FFSWAP(AVFrame, c->pic, c->last); - - /* always report that the buffer was completely consumed */ - return pkt->size; -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - BinkContext * const c = avctx->priv_data; - static VLC_TYPE table[16 * 128][2]; - int i; - int flags; - - c->version = avctx->codec_tag >> 24; - if (c->version < 'c') { - av_log(avctx, AV_LOG_ERROR, "Too old version '%c'\n", c->version); - return -1; - } - if (avctx->extradata_size < 4) { - av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n"); - return -1; - } - flags = AV_RL32(avctx->extradata); - c->has_alpha = flags & BINK_FLAG_ALPHA; - c->swap_planes = c->version >= 'h'; - if (!bink_trees[15].table) { - for (i = 0; i < 16; i++) { - const int maxbits = bink_tree_lens[i][15]; - bink_trees[i].table = table + i*128; - bink_trees[i].table_allocated = 1 << maxbits; - init_vlc(&bink_trees[i], maxbits, 16, - bink_tree_lens[i], 1, 1, - bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - } - } - c->avctx = avctx; - - c->pic.data[0] = NULL; - - if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { - return 1; - } - - avctx->pix_fmt = c->has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; - - avctx->idct_algo = FF_IDCT_BINK; - dsputil_init(&c->dsp, avctx); - ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan); - - init_bundles(c); - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - BinkContext * const c = avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - if (c->last.data[0]) - avctx->release_buffer(avctx, &c->last); - - free_bundles(c); - return 0; -} - -AVCodec bink_decoder = { - "binkvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_BINKVIDEO, - sizeof(BinkContext), - decode_init, - NULL, - decode_end, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Bink video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/binkaudio.c b/tizen/distrib/ffmpeg/libavcodec/binkaudio.c deleted file mode 100644 index 295b351..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/binkaudio.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Bink Audio decoder - * Copyright (c) 2007-2010 Peter Ross (pross@xvid.org) - * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Bink Audio decoder - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Bink_Audio - */ - -#include "avcodec.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" - -extern const uint16_t ff_wma_critical_freqs[25]; - -#define MAX_CHANNELS 2 -#define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11) - -typedef struct { - AVCodecContext *avctx; - GetBitContext gb; - DSPContext dsp; - int first; - int channels; - int frame_len; ///< transform size (samples) - int overlap_len; ///< overlap size (samples) - int block_size; - int num_bands; - unsigned int *bands; - float root; - DECLARE_ALIGNED(16, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; - DECLARE_ALIGNED(16, short, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block - float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave - union { - RDFTContext rdft; - DCTContext dct; - } trans; -} BinkAudioContext; - - -static av_cold int decode_init(AVCodecContext *avctx) -{ - BinkAudioContext *s = avctx->priv_data; - int sample_rate = avctx->sample_rate; - int sample_rate_half; - int i; - int frame_len_bits; - - s->avctx = avctx; - dsputil_init(&s->dsp, avctx); - - /* determine frame length */ - if (avctx->sample_rate < 22050) { - frame_len_bits = 9; - } else if (avctx->sample_rate < 44100) { - frame_len_bits = 10; - } else { - frame_len_bits = 11; - } - s->frame_len = 1 << frame_len_bits; - - if (s->channels > MAX_CHANNELS) { - av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); - return -1; - } - - if (avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) { - // audio is already interleaved for the RDFT format variant - sample_rate *= avctx->channels; - s->frame_len *= avctx->channels; - s->channels = 1; - if (avctx->channels == 2) - frame_len_bits++; - } else { - s->channels = avctx->channels; - } - - s->overlap_len = s->frame_len / 16; - s->block_size = (s->frame_len - s->overlap_len) * s->channels; - sample_rate_half = (sample_rate + 1) / 2; - s->root = 2.0 / sqrt(s->frame_len); - - /* calculate number of bands */ - for (s->num_bands = 1; s->num_bands < 25; s->num_bands++) - if (sample_rate_half <= ff_wma_critical_freqs[s->num_bands - 1]) - break; - - s->bands = av_malloc((s->num_bands + 1) * sizeof(*s->bands)); - if (!s->bands) - return AVERROR(ENOMEM); - - /* populate bands data */ - s->bands[0] = 1; - for (i = 1; i < s->num_bands; i++) - s->bands[i] = ff_wma_critical_freqs[i - 1] * (s->frame_len / 2) / sample_rate_half; - s->bands[s->num_bands] = s->frame_len / 2; - - s->first = 1; - avctx->sample_fmt = SAMPLE_FMT_S16; - - for (i = 0; i < s->channels; i++) - s->coeffs_ptr[i] = s->coeffs + i * s->frame_len; - - if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) - ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); - else if (CONFIG_BINKAUDIO_DCT_DECODER) - ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III); - else - return -1; - - return 0; -} - -static float get_float(GetBitContext *gb) -{ - int power = get_bits(gb, 5); - float f = ldexpf(get_bits_long(gb, 23), power - 23); - if (get_bits1(gb)) - f = -f; - return f; -} - -static const uint8_t rle_length_tab[16] = { - 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 -}; - -/** - * Decode Bink Audio block - * @param[out] out Output buffer (must contain s->block_size elements) - */ -static void decode_block(BinkAudioContext *s, short *out, int use_dct) -{ - int ch, i, j, k; - float q, quant[25]; - int width, coeff; - GetBitContext *gb = &s->gb; - - if (use_dct) - skip_bits(gb, 2); - - for (ch = 0; ch < s->channels; ch++) { - FFTSample *coeffs = s->coeffs_ptr[ch]; - q = 0.0f; - coeffs[0] = get_float(gb) * s->root; - coeffs[1] = get_float(gb) * s->root; - - for (i = 0; i < s->num_bands; i++) { - /* constant is result of 0.066399999/log10(M_E) */ - int value = get_bits(gb, 8); - quant[i] = expf(FFMIN(value, 95) * 0.15289164787221953823f) * s->root; - } - - // find band (k) - for (k = 0; s->bands[k] < 1; k++) { - q = quant[k]; - } - - // parse coefficients - i = 2; - while (i < s->frame_len) { - if (get_bits1(gb)) { - j = i + rle_length_tab[get_bits(gb, 4)] * 8; - } else { - j = i + 8; - } - - j = FFMIN(j, s->frame_len); - - width = get_bits(gb, 4); - if (width == 0) { - memset(coeffs + i, 0, (j - i) * sizeof(*coeffs)); - i = j; - while (s->bands[k] * 2 < i) - q = quant[k++]; - } else { - while (i < j) { - if (s->bands[k] * 2 == i) - q = quant[k++]; - coeff = get_bits(gb, width); - if (coeff) { - if (get_bits1(gb)) - coeffs[i] = -q * coeff; - else - coeffs[i] = q * coeff; - } else { - coeffs[i] = 0.0f; - } - i++; - } - } - } - - if (CONFIG_BINKAUDIO_DCT_DECODER && use_dct) { - coeffs[0] /= 0.5; - ff_dct_calc (&s->trans.dct, coeffs); - s->dsp.vector_fmul_scalar(coeffs, coeffs, s->frame_len / 2, s->frame_len); - } - else if (CONFIG_BINKAUDIO_RDFT_DECODER) - ff_rdft_calc(&s->trans.rdft, coeffs); - } - - if (s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { - for (i = 0; i < s->channels; i++) - for (j = 0; j < s->frame_len; j++) - s->coeffs_ptr[i][j] = 385.0 + s->coeffs_ptr[i][j]*(1.0/32767.0); - } - s->dsp.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, s->frame_len, s->channels); - - if (!s->first) { - int count = s->overlap_len * s->channels; - int shift = av_log2(count); - for (i = 0; i < count; i++) { - out[i] = (s->previous[i] * (count - i) + out[i] * i) >> shift; - } - } - - memcpy(s->previous, out + s->block_size, - s->overlap_len * s->channels * sizeof(*out)); - - s->first = 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - BinkAudioContext * s = avctx->priv_data; - av_freep(&s->bands); - if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) - ff_rdft_end(&s->trans.rdft); - else if (CONFIG_BINKAUDIO_DCT_DECODER) - ff_dct_end(&s->trans.dct); - return 0; -} - -static void get_bits_align32(GetBitContext *s) -{ - int n = (-get_bits_count(s)) & 31; - if (n) skip_bits(s, n); -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - BinkAudioContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - short *samples = data; - short *samples_end = (short*)((uint8_t*)data + *data_size); - int reported_size; - GetBitContext *gb = &s->gb; - - init_get_bits(gb, buf, buf_size * 8); - - reported_size = get_bits_long(gb, 32); - while (get_bits_count(gb) / 8 < buf_size && - samples + s->block_size <= samples_end) { - decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT); - samples += s->block_size; - get_bits_align32(gb); - } - - *data_size = FFMIN(reported_size, (uint8_t*)samples - (uint8_t*)data); - return buf_size; -} - -AVCodec binkaudio_rdft_decoder = { - "binkaudio_rdft", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_BINKAUDIO_RDFT, - sizeof(BinkAudioContext), - decode_init, - NULL, - decode_end, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)") -}; - -AVCodec binkaudio_dct_decoder = { - "binkaudio_dct", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_BINKAUDIO_DCT, - sizeof(BinkAudioContext), - decode_init, - NULL, - decode_end, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)") -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/binkdata.h b/tizen/distrib/ffmpeg/libavcodec/binkdata.h deleted file mode 100644 index 1ca34a6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/binkdata.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Bink video decoder - * Copyright (C) 2009 Kostya Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_BINKDATA_H -#define AVCODEC_BINKDATA_H - -#include - -/** Bink DCT and residue 8x8 block scan order */ -static const uint8_t bink_scan[64] = { - 0, 1, 8, 9, 2, 3, 10, 11, - 4, 5, 12, 13, 6, 7, 14, 15, - 20, 21, 28, 29, 22, 23, 30, 31, - 16, 17, 24, 25, 32, 33, 40, 41, - 34, 35, 42, 43, 48, 49, 56, 57, - 50, 51, 58, 59, 18, 19, 26, 27, - 36, 37, 44, 45, 38, 39, 46, 47, - 52, 53, 60, 61, 54, 55, 62, 63 -}; - -static const uint8_t bink_tree_bits[16][16] = { - { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - }, - { - 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, - 0x0F, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F, - }, - { - 0x00, 0x02, 0x01, 0x09, 0x05, 0x15, 0x0D, 0x1D, - 0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F, - }, - { - 0x00, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D, 0x1D, - 0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F, - }, - { - 0x00, 0x04, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D, - 0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F, - }, - { - 0x00, 0x04, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, - 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x17, 0x0F, 0x1F, - }, - { - 0x00, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, - 0x0D, 0x03, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F, - }, - { - 0x00, 0x01, 0x05, 0x03, 0x13, 0x0B, 0x1B, 0x3B, - 0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F, - }, - { - 0x00, 0x01, 0x03, 0x13, 0x0B, 0x2B, 0x1B, 0x3B, - 0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F, - }, - { - 0x00, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B, 0x1B, - 0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F, - }, - { - 0x00, 0x02, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B, - 0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F, - }, - { - 0x00, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x13, 0x0B, - 0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F, - }, - { - 0x00, 0x02, 0x01, 0x03, 0x13, 0x0B, 0x1B, 0x3B, - 0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F, - }, - { - 0x00, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17, 0x37, - 0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F, - }, - { - 0x00, 0x01, 0x05, 0x03, 0x07, 0x17, 0x37, 0x77, - 0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F, - }, - { - 0x00, 0x02, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17, - 0x37, 0x0F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F, - }, -}; - -static const uint8_t bink_tree_lens[16][16] = { - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, - { 1, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }, - { 2, 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }, - { 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }, - { 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 }, - { 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 }, - { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5 }, - { 1, 3, 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, - { 1, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, - { 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6 }, - { 2, 2, 3, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 }, - { 1, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 }, - { 2, 2, 2, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, - { 1, 3, 3, 3, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7 }, - { 1, 3, 3, 3, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }, - { 2, 2, 3, 3, 3, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 }, -}; - -static const uint8_t bink_patterns[16][64] = { - { - 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, - 0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01, - 0x02, 0x0A, 0x12, 0x1A, 0x22, 0x2A, 0x32, 0x3A, - 0x3B, 0x33, 0x2B, 0x23, 0x1B, 0x13, 0x0B, 0x03, - 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C, - 0x3D, 0x35, 0x2D, 0x25, 0x1D, 0x15, 0x0D, 0x05, - 0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x36, 0x3E, - 0x3F, 0x37, 0x2F, 0x27, 0x1F, 0x17, 0x0F, 0x07, - }, - { - 0x3B, 0x3A, 0x39, 0x38, 0x30, 0x31, 0x32, 0x33, - 0x2B, 0x2A, 0x29, 0x28, 0x20, 0x21, 0x22, 0x23, - 0x1B, 0x1A, 0x19, 0x18, 0x10, 0x11, 0x12, 0x13, - 0x0B, 0x0A, 0x09, 0x08, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x0C, - 0x14, 0x15, 0x16, 0x17, 0x1F, 0x1E, 0x1D, 0x1C, - 0x24, 0x25, 0x26, 0x27, 0x2F, 0x2E, 0x2D, 0x2C, - 0x34, 0x35, 0x36, 0x37, 0x3F, 0x3E, 0x3D, 0x3C, - }, - { - 0x19, 0x11, 0x12, 0x1A, 0x1B, 0x13, 0x0B, 0x03, - 0x02, 0x0A, 0x09, 0x01, 0x00, 0x08, 0x10, 0x18, - 0x20, 0x28, 0x30, 0x38, 0x39, 0x31, 0x29, 0x2A, - 0x32, 0x3A, 0x3B, 0x33, 0x2B, 0x23, 0x22, 0x21, - 0x1D, 0x15, 0x16, 0x1E, 0x1F, 0x17, 0x0F, 0x07, - 0x06, 0x0E, 0x0D, 0x05, 0x04, 0x0C, 0x14, 0x1C, - 0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x35, 0x2D, 0x2E, - 0x36, 0x3E, 0x3F, 0x37, 0x2F, 0x27, 0x26, 0x25, - }, - { - 0x03, 0x0B, 0x02, 0x0A, 0x01, 0x09, 0x00, 0x08, - 0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B, - 0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28, - 0x30, 0x38, 0x31, 0x39, 0x32, 0x3A, 0x33, 0x3B, - 0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37, - 0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24, - 0x1C, 0x14, 0x1D, 0x15, 0x1E, 0x16, 0x1F, 0x17, - 0x0F, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04, - }, - { - 0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01, - 0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B, - 0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05, - 0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F, - 0x27, 0x26, 0x2F, 0x2E, 0x37, 0x36, 0x3F, 0x3E, - 0x3D, 0x3C, 0x35, 0x34, 0x2D, 0x2C, 0x25, 0x24, - 0x23, 0x22, 0x2B, 0x2A, 0x33, 0x32, 0x3B, 0x3A, - 0x39, 0x38, 0x31, 0x30, 0x29, 0x28, 0x21, 0x20, - }, - { - 0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, - 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B, - 0x20, 0x21, 0x22, 0x23, 0x28, 0x29, 0x2A, 0x2B, - 0x30, 0x31, 0x32, 0x33, 0x38, 0x39, 0x3A, 0x3B, - 0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, - 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F, - 0x24, 0x25, 0x26, 0x27, 0x2C, 0x2D, 0x2E, 0x2F, - 0x34, 0x35, 0x36, 0x37, 0x3C, 0x3D, 0x3E, 0x3F, - }, - { - 0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x05, 0x0C, 0x04, - 0x03, 0x0B, 0x02, 0x0A, 0x09, 0x01, 0x00, 0x08, - 0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B, - 0x14, 0x1C, 0x15, 0x1D, 0x16, 0x1E, 0x17, 0x1F, - 0x27, 0x2F, 0x26, 0x2E, 0x25, 0x2D, 0x24, 0x2C, - 0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28, - 0x31, 0x30, 0x38, 0x39, 0x3A, 0x32, 0x3B, 0x33, - 0x3C, 0x34, 0x3D, 0x35, 0x36, 0x37, 0x3F, 0x3E, - }, - { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, - }, - { - 0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A, - 0x12, 0x13, 0x1B, 0x1A, 0x19, 0x11, 0x10, 0x18, - 0x20, 0x28, 0x29, 0x21, 0x22, 0x23, 0x2B, 0x2A, - 0x32, 0x31, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33, - 0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37, 0x36, 0x35, - 0x2D, 0x2C, 0x24, 0x25, 0x26, 0x2E, 0x2F, 0x27, - 0x1F, 0x17, 0x16, 0x1E, 0x1D, 0x1C, 0x14, 0x15, - 0x0D, 0x0C, 0x04, 0x05, 0x06, 0x0E, 0x0F, 0x07, - }, - { - 0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01, - 0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B, - 0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05, - 0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F, - 0x26, 0x27, 0x2E, 0x2F, 0x36, 0x37, 0x3E, 0x3F, - 0x3C, 0x3D, 0x34, 0x35, 0x2C, 0x2D, 0x24, 0x25, - 0x22, 0x23, 0x2A, 0x2B, 0x32, 0x33, 0x3A, 0x3B, - 0x38, 0x39, 0x30, 0x31, 0x28, 0x29, 0x20, 0x21, - }, - { - 0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B, - 0x13, 0x1B, 0x12, 0x1A, 0x11, 0x19, 0x10, 0x18, - 0x20, 0x28, 0x21, 0x29, 0x22, 0x2A, 0x23, 0x2B, - 0x33, 0x3B, 0x32, 0x3A, 0x31, 0x39, 0x30, 0x38, - 0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37, - 0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24, - 0x1F, 0x17, 0x1E, 0x16, 0x1D, 0x15, 0x1C, 0x14, - 0x0C, 0x04, 0x0D, 0x05, 0x0E, 0x06, 0x0F, 0x07, - }, - { - 0x00, 0x08, 0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13, - 0x0B, 0x03, 0x02, 0x01, 0x09, 0x11, 0x12, 0x0A, - 0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F, 0x17, - 0x0F, 0x07, 0x06, 0x05, 0x0D, 0x15, 0x16, 0x0E, - 0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37, - 0x2F, 0x27, 0x26, 0x25, 0x2D, 0x35, 0x36, 0x2E, - 0x20, 0x28, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33, - 0x2B, 0x23, 0x22, 0x21, 0x29, 0x31, 0x32, 0x2A, - }, - { - 0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A, - 0x13, 0x1B, 0x1A, 0x12, 0x11, 0x10, 0x18, 0x19, - 0x21, 0x20, 0x28, 0x29, 0x2A, 0x22, 0x23, 0x2B, - 0x33, 0x3B, 0x3A, 0x32, 0x31, 0x39, 0x38, 0x30, - 0x34, 0x3C, 0x3D, 0x35, 0x36, 0x3E, 0x3F, 0x37, - 0x2F, 0x27, 0x26, 0x2E, 0x2D, 0x2C, 0x24, 0x25, - 0x1D, 0x1C, 0x14, 0x15, 0x16, 0x1E, 0x1F, 0x17, - 0x0E, 0x0F, 0x07, 0x06, 0x05, 0x0D, 0x0C, 0x04, - }, - { - 0x18, 0x10, 0x08, 0x00, 0x01, 0x02, 0x03, 0x0B, - 0x13, 0x1B, 0x1A, 0x19, 0x11, 0x0A, 0x09, 0x12, - 0x1C, 0x14, 0x0C, 0x04, 0x05, 0x06, 0x07, 0x0F, - 0x17, 0x1F, 0x1E, 0x1D, 0x15, 0x0E, 0x0D, 0x16, - 0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27, 0x2F, - 0x37, 0x3F, 0x3E, 0x3D, 0x35, 0x2E, 0x2D, 0x36, - 0x38, 0x30, 0x28, 0x20, 0x21, 0x22, 0x23, 0x2B, - 0x33, 0x3B, 0x3A, 0x39, 0x31, 0x2A, 0x29, 0x32, - }, - { - 0x00, 0x08, 0x09, 0x01, 0x02, 0x0A, 0x12, 0x11, - 0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13, 0x0B, 0x03, - 0x07, 0x06, 0x0E, 0x0F, 0x17, 0x16, 0x15, 0x0D, - 0x05, 0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F, - 0x3F, 0x3E, 0x36, 0x37, 0x2F, 0x2E, 0x2D, 0x35, - 0x3D, 0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27, - 0x38, 0x30, 0x31, 0x39, 0x3A, 0x32, 0x2A, 0x29, - 0x28, 0x20, 0x21, 0x22, 0x23, 0x2B, 0x33, 0x3B, - }, - { - 0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19, - 0x20, 0x21, 0x28, 0x29, 0x30, 0x31, 0x38, 0x39, - 0x3A, 0x3B, 0x32, 0x33, 0x2A, 0x2B, 0x22, 0x23, - 0x1A, 0x1B, 0x12, 0x13, 0x0A, 0x0B, 0x02, 0x03, - 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, - 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x3C, 0x3D, - 0x3E, 0x3F, 0x36, 0x37, 0x2E, 0x2F, 0x26, 0x27, - 0x1E, 0x1F, 0x16, 0x17, 0x0E, 0x0F, 0x06, 0x07, - } -}; - -static const uint32_t bink_intra_quant[16][64] = { -{ - 0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C, - 0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552, - 0x021F88, 0x01DC53, 0x027FAD, 0x01F697, 0x014819, 0x00A743, 0x015A31, 0x009688, - 0x02346F, 0x030EE5, 0x01FBFA, 0x02C096, 0x01D000, 0x028396, 0x019247, 0x01F9AA, - 0x02346F, 0x01FBFA, 0x01DC53, 0x0231B8, 0x012F12, 0x01E06C, 0x00CB10, 0x0119A8, - 0x01C48C, 0x019748, 0x014E86, 0x0122AF, 0x02C628, 0x027F20, 0x0297B5, 0x023F32, - 0x025000, 0x01AB6B, 0x01D122, 0x0159B3, 0x012669, 0x008D43, 0x00EE1F, 0x0075ED, - 0x01490C, 0x010288, 0x00F735, 0x00EF51, 0x00E0F1, 0x0072AD, 0x00A4D8, 0x006517, -}, -{ - 0x015555, 0x01D971, 0x028AFC, 0x0386F1, 0x01BDF9, 0x01DC9F, 0x03ED33, 0x034311, - 0x015555, 0x013E78, 0x030158, 0x01FF7A, 0x00FE00, 0x00817D, 0x01604F, 0x00DC6D, - 0x02D4B5, 0x027B19, 0x0354E7, 0x029E1F, 0x01B577, 0x00DF04, 0x01CD96, 0x00C8B6, - 0x02F095, 0x0413DC, 0x02A54E, 0x03AB73, 0x026AAB, 0x035A1E, 0x02185E, 0x02A238, - 0x02F095, 0x02A54E, 0x027B19, 0x02ECF5, 0x019418, 0x028090, 0x010EC0, 0x01778A, - 0x025B66, 0x021F0B, 0x01BE09, 0x018394, 0x03B2E0, 0x03542A, 0x0374F1, 0x02FEEE, - 0x031555, 0x0239E4, 0x026C2D, 0x01CCEE, 0x01888C, 0x00BC59, 0x013D7E, 0x009D3C, - 0x01B6BB, 0x0158B5, 0x01499C, 0x013F17, 0x012BEC, 0x0098E6, 0x00DBCB, 0x0086C9, -}, -{ - 0x01AAAB, 0x024FCE, 0x032DBB, 0x0468AD, 0x022D78, 0x0253C7, 0x04E87F, 0x0413D5, - 0x01AAAB, 0x018E16, 0x03C1AE, 0x027F58, 0x013D80, 0x00A1DC, 0x01B863, 0x011388, - 0x0389E2, 0x0319DF, 0x042A21, 0x0345A7, 0x0222D4, 0x0116C5, 0x0240FC, 0x00FAE3, - 0x03ACBA, 0x0518D3, 0x034EA1, 0x04964F, 0x030555, 0x0430A5, 0x029E76, 0x034AC5, - 0x03ACBA, 0x034EA1, 0x0319DF, 0x03A833, 0x01F91E, 0x0320B4, 0x015270, 0x01D56D, - 0x02F23F, 0x02A6CE, 0x022D8B, 0x01E479, 0x049F98, 0x042935, 0x04522D, 0x03BEA9, - 0x03DAAB, 0x02C85D, 0x030738, 0x02402A, 0x01EAAF, 0x00EB6F, 0x018CDE, 0x00C48A, - 0x022469, 0x01AEE2, 0x019C02, 0x018EDD, 0x0176E7, 0x00BF20, 0x0112BE, 0x00A87B, -}, -{ - 0x020000, 0x02C62A, 0x03D07A, 0x054A69, 0x029CF6, 0x02CAEF, 0x05E3CC, 0x04E499, - 0x020000, 0x01DDB4, 0x048204, 0x02FF36, 0x017D01, 0x00C23C, 0x021077, 0x014AA3, - 0x043F0F, 0x03B8A6, 0x04FF5A, 0x03ED2E, 0x029032, 0x014E86, 0x02B461, 0x012D11, - 0x0468DF, 0x061DCA, 0x03F7F5, 0x05812C, 0x03A000, 0x05072C, 0x03248D, 0x03F353, - 0x0468DF, 0x03F7F5, 0x03B8A6, 0x046370, 0x025E24, 0x03C0D8, 0x019620, 0x02334F, - 0x038919, 0x032E91, 0x029D0D, 0x02455E, 0x058C50, 0x04FE3F, 0x052F69, 0x047E65, - 0x04A000, 0x0356D6, 0x03A243, 0x02B365, 0x024CD2, 0x011A85, 0x01DC3E, 0x00EBD9, - 0x029218, 0x020510, 0x01EE69, 0x01DEA2, 0x01C1E2, 0x00E559, 0x0149B0, 0x00CA2D, -}, -{ - 0x02AAAB, 0x03B2E3, 0x0515F8, 0x070DE2, 0x037BF2, 0x03B93E, 0x07DA65, 0x068621, - 0x02AAAB, 0x027CF0, 0x0602B1, 0x03FEF3, 0x01FC01, 0x0102FA, 0x02C09F, 0x01B8DA, - 0x05A96A, 0x04F632, 0x06A9CE, 0x053C3E, 0x036AED, 0x01BE09, 0x039B2D, 0x01916B, - 0x05E129, 0x0827B8, 0x054A9C, 0x0756E5, 0x04D555, 0x06B43B, 0x0430BC, 0x05446F, - 0x05E129, 0x054A9C, 0x04F632, 0x05D9EB, 0x032830, 0x050121, 0x021D80, 0x02EF14, - 0x04B6CC, 0x043E16, 0x037C11, 0x030728, 0x0765C0, 0x06A855, 0x06E9E2, 0x05FDDB, - 0x062AAB, 0x0473C8, 0x04D85A, 0x0399DC, 0x031118, 0x0178B2, 0x027AFD, 0x013A77, - 0x036D76, 0x02B16A, 0x029337, 0x027E2E, 0x0257D8, 0x0131CC, 0x01B796, 0x010D91, -}, -{ - 0x038000, 0x04DACA, 0x06ACD5, 0x094238, 0x0492AE, 0x04E322, 0x0A4EA5, 0x08900C, - 0x038000, 0x0343FB, 0x07E388, 0x053E9F, 0x029AC1, 0x0153E8, 0x039CD0, 0x02429E, - 0x076E5B, 0x068322, 0x08BEDE, 0x06DF11, 0x047C57, 0x02496B, 0x04BBAB, 0x020EDD, - 0x07B786, 0x0AB421, 0x06F1ED, 0x09A20D, 0x065800, 0x08CC8E, 0x057FF7, 0x06E9D2, - 0x07B786, 0x06F1ED, 0x068322, 0x07AE04, 0x0424BF, 0x06917B, 0x02C6B8, 0x03D9CB, - 0x062FEB, 0x05917D, 0x0492D7, 0x03F964, 0x09B58C, 0x08BCEF, 0x0912F8, 0x07DD30, - 0x081800, 0x05D7F7, 0x065BF6, 0x04B9F1, 0x040670, 0x01EE69, 0x03416C, 0x019CBC, - 0x047FAA, 0x0388DC, 0x036138, 0x03459C, 0x03134C, 0x01915C, 0x0240F5, 0x0161CF, -}, -{ - 0x040000, 0x058C54, 0x07A0F4, 0x0A94D3, 0x0539EC, 0x0595DD, 0x0BC798, 0x09C932, - 0x040000, 0x03BB68, 0x090409, 0x05FE6D, 0x02FA01, 0x018477, 0x0420EE, 0x029547, - 0x087E1F, 0x07714C, 0x09FEB5, 0x07DA5D, 0x052064, 0x029D0D, 0x0568C3, 0x025A21, - 0x08D1BE, 0x0C3B94, 0x07EFEA, 0x0B0258, 0x074000, 0x0A0E59, 0x06491A, 0x07E6A7, - 0x08D1BE, 0x07EFEA, 0x07714C, 0x08C6E0, 0x04BC48, 0x0781B1, 0x032C3F, 0x04669F, - 0x071232, 0x065D22, 0x053A1A, 0x048ABC, 0x0B18A0, 0x09FC7F, 0x0A5ED3, 0x08FCC9, - 0x094000, 0x06ADAC, 0x074487, 0x0566CA, 0x0499A5, 0x02350B, 0x03B87B, 0x01D7B3, - 0x052430, 0x040A20, 0x03DCD3, 0x03BD45, 0x0383C5, 0x01CAB3, 0x029361, 0x01945A, -}, -{ - 0x050000, 0x06EF69, 0x098931, 0x0D3A07, 0x068867, 0x06FB55, 0x0EB97E, 0x0C3B7E, - 0x050000, 0x04AA42, 0x0B450B, 0x077E08, 0x03B881, 0x01E595, 0x05292A, 0x033A99, - 0x0A9DA7, 0x094D9F, 0x0C7E62, 0x09D0F4, 0x06687D, 0x034450, 0x06C2F4, 0x02F0AA, - 0x0B062D, 0x0F4A78, 0x09EBE4, 0x0DC2EE, 0x091000, 0x0C91EF, 0x07DB61, 0x09E050, - 0x0B062D, 0x09EBE4, 0x094D9F, 0x0AF898, 0x05EB59, 0x09621D, 0x03F74F, 0x058046, - 0x08D6BE, 0x07F46A, 0x0688A0, 0x05AD6B, 0x0DDEC8, 0x0C7B9F, 0x0CF687, 0x0B3BFB, - 0x0B9000, 0x085917, 0x0915A8, 0x06C07D, 0x05C00E, 0x02C24D, 0x04A69A, 0x024D9F, - 0x066D3C, 0x050CA7, 0x04D407, 0x04AC96, 0x0464B6, 0x023D5F, 0x033839, 0x01F971, -}, -{ - 0x060000, 0x08527E, 0x0B716E, 0x0FDF3C, 0x07D6E1, 0x0860CC, 0x11AB63, 0x0EADCB, - 0x060000, 0x05991C, 0x0D860D, 0x08FDA3, 0x047702, 0x0246B3, 0x063165, 0x03DFEA, - 0x0CBD2E, 0x0B29F1, 0x0EFE0F, 0x0BC78B, 0x07B096, 0x03EB93, 0x081D24, 0x038732, - 0x0D3A9C, 0x12595D, 0x0BE7DF, 0x108384, 0x0AE000, 0x0F1585, 0x096DA8, 0x0BD9FA, - 0x0D3A9C, 0x0BE7DF, 0x0B29F1, 0x0D2A50, 0x071A6B, 0x0B4289, 0x04C25F, 0x0699EE, - 0x0A9B4A, 0x098BB2, 0x07D727, 0x06D01A, 0x10A4F0, 0x0EFABE, 0x0F8E3C, 0x0D7B2E, - 0x0DE000, 0x0A0482, 0x0AE6CA, 0x081A2F, 0x06E677, 0x034F90, 0x0594B9, 0x02C38C, - 0x07B649, 0x060F2F, 0x05CB3C, 0x059BE7, 0x0545A7, 0x02B00C, 0x03DD11, 0x025E87, -}, -{ - 0x080000, 0x0B18A8, 0x0F41E8, 0x1529A5, 0x0A73D7, 0x0B2BBB, 0x178F2F, 0x139264, - 0x080000, 0x0776CF, 0x120812, 0x0BFCD9, 0x05F402, 0x0308EF, 0x0841DC, 0x052A8E, - 0x10FC3E, 0x0EE297, 0x13FD69, 0x0FB4B9, 0x0A40C8, 0x053A1A, 0x0AD186, 0x04B442, - 0x11A37B, 0x187727, 0x0FDFD4, 0x1604B0, 0x0E8000, 0x141CB1, 0x0C9235, 0x0FCD4D, - 0x11A37B, 0x0FDFD4, 0x0EE297, 0x118DC0, 0x09788F, 0x0F0362, 0x06587F, 0x08CD3D, - 0x0E2463, 0x0CBA43, 0x0A7434, 0x091577, 0x163140, 0x13F8FE, 0x14BDA5, 0x11F992, - 0x128000, 0x0D5B58, 0x0E890D, 0x0ACD94, 0x093349, 0x046A15, 0x0770F7, 0x03AF65, - 0x0A4861, 0x08143F, 0x07B9A6, 0x077A89, 0x070789, 0x039565, 0x0526C2, 0x0328B4, -}, -{ - 0x0C0000, 0x10A4FD, 0x16E2DB, 0x1FBE78, 0x0FADC3, 0x10C198, 0x2356C7, 0x1D5B96, - 0x0C0000, 0x0B3237, 0x1B0C1A, 0x11FB46, 0x08EE03, 0x048D66, 0x0C62CA, 0x07BFD5, - 0x197A5D, 0x1653E3, 0x1DFC1E, 0x178F16, 0x0F612C, 0x07D727, 0x103A49, 0x070E64, - 0x1A7539, 0x24B2BB, 0x17CFBD, 0x210709, 0x15C000, 0x1E2B0A, 0x12DB4F, 0x17B3F4, - 0x1A7539, 0x17CFBD, 0x1653E3, 0x1A54A0, 0x0E34D7, 0x168513, 0x0984BE, 0x0D33DC, - 0x153695, 0x131765, 0x0FAE4E, 0x0DA033, 0x2149E1, 0x1DF57D, 0x1F1C78, 0x1AF65B, - 0x1BC000, 0x140904, 0x15CD94, 0x10345E, 0x0DCCEE, 0x069F20, 0x0B2972, 0x058718, - 0x0F6C91, 0x0C1E5E, 0x0B9678, 0x0B37CE, 0x0A8B4E, 0x056018, 0x07BA22, 0x04BD0E, -}, -{ - 0x110000, 0x179466, 0x206C0C, 0x2CF87F, 0x16362A, 0x17BCED, 0x321044, 0x299714, - 0x110000, 0x0FDC79, 0x265125, 0x19794E, 0x0CA685, 0x0672FB, 0x118BF4, 0x0AFA6D, - 0x241804, 0x1FA181, 0x2A7A80, 0x21600A, 0x15C9A9, 0x0B1B77, 0x16FD3C, 0x09FF0D, - 0x257B66, 0x33FD33, 0x21BBA2, 0x2EC9F7, 0x1ED000, 0x2ABCF9, 0x1AB6B0, 0x219444, - 0x257B66, 0x21BBA2, 0x1FA181, 0x254D38, 0x142030, 0x1FE730, 0x0D7C0E, 0x12B423, - 0x1E0D52, 0x1B0BCF, 0x1636EE, 0x134D9E, 0x2F28A9, 0x2A711B, 0x2C12FF, 0x263256, - 0x275000, 0x1C621B, 0x1EE33C, 0x16F4DB, 0x138CFB, 0x09616E, 0x0FD00C, 0x07D4B7, - 0x15D9CE, 0x112B06, 0x106A80, 0x0FE464, 0x0EF004, 0x079D77, 0x0AF25B, 0x06B67F, -}, -{ - 0x160000, 0x1E83CF, 0x29F53D, 0x3A3286, 0x1CBE90, 0x1EB842, 0x40C9C2, 0x35D293, - 0x160000, 0x1486BA, 0x319630, 0x20F756, 0x105F06, 0x085891, 0x16B51E, 0x0E3506, - 0x2EB5AA, 0x28EF20, 0x36F8E1, 0x2B30FE, 0x1C3225, 0x0E5FC7, 0x1DC030, 0x0CEFB7, - 0x308193, 0x4347AC, 0x2BA786, 0x3C8CE5, 0x27E000, 0x374EE7, 0x229212, 0x2B7494, - 0x308193, 0x2BA786, 0x28EF20, 0x3045D0, 0x1A0B89, 0x29494D, 0x11735D, 0x183469, - 0x26E410, 0x230039, 0x1CBF8F, 0x18FB09, 0x3D0771, 0x36ECBA, 0x390986, 0x316E52, - 0x32E000, 0x24BB33, 0x27F8E4, 0x1DB557, 0x194D09, 0x0C23BB, 0x1476A6, 0x0A2256, - 0x1C470A, 0x1637AD, 0x153E87, 0x1490FA, 0x1354B9, 0x09DAD6, 0x0E2A94, 0x08AFF0, -}, -{ - 0x1C0000, 0x26D64D, 0x3566AA, 0x4A11C2, 0x249572, 0x27190E, 0x527525, 0x44805E, - 0x1C0000, 0x1A1FD6, 0x3F1C3E, 0x29F4F9, 0x14D607, 0x0A9F44, 0x1CE683, 0x1214F0, - 0x3B72D9, 0x341911, 0x45F6F0, 0x36F889, 0x23E2BB, 0x124B5B, 0x25DD54, 0x1076E9, - 0x3DBC30, 0x55A109, 0x378F64, 0x4D1069, 0x32C000, 0x46646C, 0x2BFFB9, 0x374E8E, - 0x3DBC30, 0x378F64, 0x341911, 0x3D7020, 0x2125F5, 0x348BD6, 0x1635BC, 0x1ECE57, - 0x317F5B, 0x2C8BEB, 0x2496B6, 0x1FCB22, 0x4DAC61, 0x45E778, 0x4897C2, 0x3EE97F, - 0x40C000, 0x2EBFB5, 0x32DFAE, 0x25CF86, 0x203380, 0x0F734B, 0x1A0B5F, 0x0CE5E2, - 0x23FD53, 0x1C46DC, 0x1B09C4, 0x1A2CE1, 0x189A60, 0x0C8AE2, 0x1207A5, 0x0B0E77, -}, -{ - 0x220000, 0x2F28CC, 0x40D818, 0x59F0FE, 0x2C6C53, 0x2F79DA, 0x642089, 0x532E29, - 0x220000, 0x1FB8F1, 0x4CA24B, 0x32F29C, 0x194D09, 0x0CE5F7, 0x2317E8, 0x15F4DB, - 0x483007, 0x3F4303, 0x54F4FF, 0x42C014, 0x2B9351, 0x1636EE, 0x2DFA79, 0x13FE1A, - 0x4AF6CC, 0x67FA67, 0x437743, 0x5D93EE, 0x3DA000, 0x5579F1, 0x356D61, 0x432888, - 0x4AF6CC, 0x437743, 0x3F4303, 0x4A9A70, 0x284060, 0x3FCE60, 0x1AF81B, 0x256845, - 0x3C1AA5, 0x36179D, 0x2C6DDD, 0x269B3C, 0x5E5152, 0x54E237, 0x5825FE, 0x4C64AD, - 0x4EA000, 0x38C437, 0x3DC678, 0x2DE9B5, 0x2719F7, 0x12C2DB, 0x1FA018, 0x0FA96E, - 0x2BB39B, 0x22560C, 0x20D500, 0x1FC8C8, 0x1DE007, 0x0F3AEE, 0x15E4B7, 0x0D6CFE, -}, -{ - 0x2C0000, 0x3D079E, 0x53EA79, 0x74650C, 0x397D20, 0x3D7083, 0x819383, 0x6BA525, - 0x2C0000, 0x290D75, 0x632C61, 0x41EEAC, 0x20BE0C, 0x10B121, 0x2D6A3B, 0x1C6A0C, - 0x5D6B54, 0x51DE40, 0x6DF1C2, 0x5661FB, 0x38644B, 0x1CBF8F, 0x3B8060, 0x19DF6D, - 0x610326, 0x868F57, 0x574F0B, 0x7919CA, 0x4FC000, 0x6E9DCE, 0x452423, 0x56E928, - 0x610326, 0x574F0B, 0x51DE40, 0x608BA0, 0x341713, 0x52929A, 0x22E6BA, 0x3068D2, - 0x4DC821, 0x460071, 0x397F1E, 0x31F611, 0x7A0EE2, 0x6DD974, 0x72130C, 0x62DCA3, - 0x65C000, 0x497665, 0x4FF1C9, 0x3B6AAE, 0x329A12, 0x184776, 0x28ED4D, 0x1444AC, - 0x388E14, 0x2C6F5A, 0x2A7D0F, 0x2921F4, 0x26A973, 0x13B5AD, 0x1C5528, 0x115FDF, -}, -}; - -static const uint32_t bink_inter_quant[16][64] = { -{ - 0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA, - 0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095, - 0x01B701, 0x016959, 0x01B0B9, 0x0153FD, 0x00F8E7, 0x007EE4, 0x00EA30, 0x007763, - 0x01B701, 0x0260EB, 0x019DE9, 0x023E1B, 0x017000, 0x01FE6E, 0x012DB5, 0x01A27B, - 0x01E0D1, 0x01B0B9, 0x018A33, 0x01718D, 0x00D87A, 0x014449, 0x007B9A, 0x00AB71, - 0x013178, 0x0112EA, 0x00AD08, 0x009BB9, 0x023D97, 0x020437, 0x021CCC, 0x01E6B4, - 0x018000, 0x012DB5, 0x0146D9, 0x0100CE, 0x00CFD2, 0x006E5C, 0x00B0E4, 0x005A2D, - 0x00E9CC, 0x00B7B1, 0x00846F, 0x006B85, 0x008337, 0x0042E5, 0x004A10, 0x002831, -}, -{ - 0x015555, 0x01F708, 0x023237, 0x030BD0, 0x01D9D9, 0x01C389, 0x03053B, 0x02B7E3, - 0x018000, 0x012DB5, 0x024FCE, 0x01D0FA, 0x00DB5D, 0x006FD5, 0x014048, 0x00AB71, - 0x024957, 0x01E1CC, 0x0240F7, 0x01C551, 0x014BDE, 0x00A92F, 0x013840, 0x009F2F, - 0x024957, 0x032BE4, 0x0227E1, 0x02FD7A, 0x01EAAB, 0x02A893, 0x019247, 0x022DF9, - 0x028116, 0x0240F7, 0x020D99, 0x01ECBC, 0x0120A3, 0x01B061, 0x00A4CE, 0x00E497, - 0x01974B, 0x016E8E, 0x00E6B5, 0x00CFA2, 0x02FCC9, 0x02B04A, 0x02D110, 0x0288F1, - 0x020000, 0x019247, 0x01B3CC, 0x015668, 0x011518, 0x009325, 0x00EBDA, 0x00783D, - 0x0137BB, 0x00F4ED, 0x00B093, 0x008F5C, 0x00AEF4, 0x005931, 0x0062BF, 0x003597, -}, -{ - 0x01AAAB, 0x0274CB, 0x02BEC4, 0x03CEC4, 0x02504F, 0x02346C, 0x03C689, 0x0365DC, - 0x01E000, 0x017922, 0x02E3C1, 0x024539, 0x011235, 0x008BCA, 0x01905A, 0x00D64D, - 0x02DBAD, 0x025A40, 0x02D134, 0x0236A5, 0x019ED6, 0x00D37B, 0x018650, 0x00C6FB, - 0x02DBAD, 0x03F6DD, 0x02B1D9, 0x03BCD8, 0x026555, 0x0352B8, 0x01F6D8, 0x02B977, - 0x03215C, 0x02D134, 0x029100, 0x0267EB, 0x0168CC, 0x021C7A, 0x00CE01, 0x011DBD, - 0x01FD1E, 0x01CA31, 0x012062, 0x01038A, 0x03BBFB, 0x035C5C, 0x038554, 0x032B2D, - 0x028000, 0x01F6D8, 0x0220C0, 0x01AC02, 0x015A5E, 0x00B7EF, 0x0126D1, 0x00964C, - 0x0185A9, 0x013228, 0x00DCB8, 0x00B333, 0x00DAB2, 0x006F7D, 0x007B6F, 0x0042FC, -}, -{ - 0x020000, 0x02F28D, 0x034B52, 0x0491B8, 0x02C6C5, 0x02A54E, 0x0487D8, 0x0413D5, - 0x024000, 0x01C48F, 0x0377B5, 0x02B977, 0x01490C, 0x00A7BF, 0x01E06C, 0x01012A, - 0x036E03, 0x02D2B3, 0x036172, 0x02A7FA, 0x01F1CE, 0x00FDC7, 0x01D460, 0x00EEC7, - 0x036E03, 0x04C1D6, 0x033BD1, 0x047C37, 0x02E000, 0x03FCDD, 0x025B6A, 0x0344F5, - 0x03C1A1, 0x036172, 0x031466, 0x02E31B, 0x01B0F5, 0x028892, 0x00F735, 0x0156E2, - 0x0262F1, 0x0225D5, 0x015A10, 0x013772, 0x047B2D, 0x04086E, 0x043998, 0x03CD69, - 0x030000, 0x025B6A, 0x028DB3, 0x02019B, 0x019FA3, 0x00DCB8, 0x0161C7, 0x00B45B, - 0x01D398, 0x016F63, 0x0108DD, 0x00D70A, 0x01066F, 0x0085C9, 0x00941F, 0x005062, -}, -{ - 0x02AAAB, 0x03EE11, 0x04646D, 0x0617A0, 0x03B3B2, 0x038713, 0x060A75, 0x056FC6, - 0x030000, 0x025B6A, 0x049F9B, 0x03A1F4, 0x01B6BB, 0x00DFAA, 0x028090, 0x0156E2, - 0x0492AE, 0x03C399, 0x0481ED, 0x038AA2, 0x0297BD, 0x01525F, 0x027080, 0x013E5E, - 0x0492AE, 0x0657C8, 0x044FC1, 0x05FAF4, 0x03D555, 0x055126, 0x03248D, 0x045BF2, - 0x05022D, 0x0481ED, 0x041B33, 0x03D979, 0x024147, 0x0360C3, 0x01499C, 0x01C92E, - 0x032E96, 0x02DD1C, 0x01CD6A, 0x019F43, 0x05F991, 0x056093, 0x05A220, 0x0511E1, - 0x040000, 0x03248D, 0x036799, 0x02ACCF, 0x022A2F, 0x01264B, 0x01D7B5, 0x00F079, - 0x026F75, 0x01E9D9, 0x016127, 0x011EB8, 0x015DE9, 0x00B262, 0x00C57F, 0x006B2D, -}, -{ - 0x038000, 0x052876, 0x05C3CF, 0x07FF02, 0x04DBD9, 0x04A148, 0x07EDBA, 0x0722B4, - 0x03F000, 0x0317FB, 0x06117C, 0x04C491, 0x023FD5, 0x01258F, 0x0348BD, 0x01C209, - 0x060085, 0x04F0B9, 0x05EA87, 0x04A5F5, 0x036728, 0x01BC1C, 0x0333A8, 0x01A1DB, - 0x060085, 0x085336, 0x05A8AE, 0x07D960, 0x050800, 0x06FA82, 0x041FF9, 0x05B8AE, - 0x0692DA, 0x05EA87, 0x0563B2, 0x050D6E, 0x02F5AD, 0x046F00, 0x01B09C, 0x02580C, - 0x042D25, 0x03C235, 0x025D9B, 0x022108, 0x07D78F, 0x070EC1, 0x0764CA, 0x06A777, - 0x054000, 0x041FF9, 0x0477F9, 0x0382D0, 0x02D75E, 0x018242, 0x026B1D, 0x013B9F, - 0x03324A, 0x0282ED, 0x01CF83, 0x017851, 0x01CB42, 0x00EA21, 0x010336, 0x008CAC, -}, -{ - 0x040000, 0x05E519, 0x0696A4, 0x092370, 0x058D8A, 0x054A9C, 0x090FB0, 0x0827AA, - 0x048000, 0x03891F, 0x06EF69, 0x0572EE, 0x029218, 0x014F7E, 0x03C0D8, 0x020254, - 0x06DC05, 0x05A565, 0x06C2E4, 0x054FF3, 0x03E39B, 0x01FB8E, 0x03A8C0, 0x01DD8D, - 0x06DC05, 0x0983AC, 0x0677A2, 0x08F86E, 0x05C000, 0x07F9B9, 0x04B6D4, 0x0689EB, - 0x078343, 0x06C2E4, 0x0628CC, 0x05C635, 0x0361EA, 0x051124, 0x01EE69, 0x02ADC5, - 0x04C5E1, 0x044BAA, 0x02B41F, 0x026EE5, 0x08F65A, 0x0810DD, 0x087330, 0x079AD1, - 0x060000, 0x04B6D4, 0x051B65, 0x040337, 0x033F47, 0x01B970, 0x02C38F, 0x0168B6, - 0x03A730, 0x02DEC6, 0x0211BA, 0x01AE14, 0x020CDD, 0x010B93, 0x01283E, 0x00A0C4, -}, -{ - 0x050000, 0x075E60, 0x083C4D, 0x0B6C4C, 0x06F0ED, 0x069D43, 0x0B539C, 0x0A3194, - 0x05A000, 0x046B67, 0x08AB44, 0x06CFAA, 0x03369E, 0x01A35E, 0x04B10F, 0x0282E8, - 0x089307, 0x070EBF, 0x08739C, 0x06A3F0, 0x04DC82, 0x027A72, 0x0492F0, 0x0254F0, - 0x089307, 0x0BE497, 0x08158B, 0x0B3689, 0x073000, 0x09F827, 0x05E489, 0x082C66, - 0x096413, 0x08739C, 0x07B2FF, 0x0737C2, 0x043A64, 0x06556D, 0x026A04, 0x035936, - 0x05F75A, 0x055E94, 0x036127, 0x030A9E, 0x0B33F1, 0x0A1514, 0x0A8FFC, 0x098186, - 0x078000, 0x05E489, 0x06623F, 0x050405, 0x040F19, 0x0227CC, 0x037473, 0x01C2E3, - 0x0490FC, 0x039677, 0x029629, 0x021999, 0x029015, 0x014E78, 0x01724E, 0x00C8F5, -}, -{ - 0x060000, 0x08D7A6, 0x09E1F6, 0x0DB528, 0x085450, 0x07EFEA, 0x0D9788, 0x0C3B7E, - 0x06C000, 0x054DAE, 0x0A671E, 0x082C66, 0x03DB24, 0x01F73E, 0x05A145, 0x03037D, - 0x0A4A08, 0x087818, 0x0A2455, 0x07F7ED, 0x05D569, 0x02F955, 0x057D20, 0x02CC54, - 0x0A4A08, 0x0E4582, 0x09B373, 0x0D74A5, 0x08A000, 0x0BF696, 0x07123E, 0x09CEE0, - 0x0B44E4, 0x0A2455, 0x093D32, 0x08A950, 0x0512DF, 0x0799B6, 0x02E59E, 0x0404A7, - 0x0728D2, 0x06717F, 0x040E2F, 0x03A657, 0x0D7187, 0x0C194B, 0x0CACC8, 0x0B683A, - 0x090000, 0x07123E, 0x07A918, 0x0604D2, 0x04DEEA, 0x029629, 0x042556, 0x021D11, - 0x057AC8, 0x044E28, 0x031A97, 0x02851E, 0x03134C, 0x01915C, 0x01BC5D, 0x00F126, -}, -{ - 0x080000, 0x0BCA33, 0x0D2D48, 0x1246E0, 0x0B1B15, 0x0A9538, 0x121F5F, 0x104F53, - 0x090000, 0x07123E, 0x0DDED2, 0x0AE5DD, 0x052430, 0x029EFD, 0x0781B1, 0x0404A7, - 0x0DB80B, 0x0B4ACB, 0x0D85C7, 0x0A9FE7, 0x07C736, 0x03F71D, 0x075180, 0x03BB1A, - 0x0DB80B, 0x130757, 0x0CEF44, 0x11F0DC, 0x0B8000, 0x0FF372, 0x096DA8, 0x0D13D6, - 0x0F0686, 0x0D85C7, 0x0C5198, 0x0B8C6A, 0x06C3D4, 0x0A2248, 0x03DCD3, 0x055B8A, - 0x098BC3, 0x089754, 0x05683E, 0x04DDC9, 0x11ECB4, 0x1021B9, 0x10E661, 0x0F35A3, - 0x0C0000, 0x096DA8, 0x0A36CB, 0x08066E, 0x067E8E, 0x0372E1, 0x05871E, 0x02D16B, - 0x074E60, 0x05BD8B, 0x042374, 0x035C28, 0x0419BB, 0x021726, 0x02507C, 0x014188, -}, -{ - 0x0C0000, 0x11AF4C, 0x13C3EC, 0x1B6A50, 0x10A89F, 0x0FDFD4, 0x1B2F0F, 0x1876FD, - 0x0D8000, 0x0A9B5D, 0x14CE3C, 0x1058CB, 0x07B649, 0x03EE7B, 0x0B4289, 0x0606FB, - 0x149410, 0x10F030, 0x1448AB, 0x0FEFDA, 0x0BAAD2, 0x05F2AB, 0x0AFA40, 0x0598A7, - 0x149410, 0x1C8B03, 0x1366E6, 0x1AE949, 0x114000, 0x17ED2B, 0x0E247C, 0x139DC1, - 0x1689C8, 0x1448AB, 0x127A63, 0x11529F, 0x0A25BE, 0x0F336D, 0x05CB3C, 0x08094E, - 0x0E51A4, 0x0CE2FE, 0x081C5D, 0x074CAE, 0x1AE30E, 0x183296, 0x195991, 0x16D074, - 0x120000, 0x0E247C, 0x0F5230, 0x0C09A5, 0x09BDD5, 0x052C51, 0x084AAC, 0x043A21, - 0x0AF590, 0x089C51, 0x06352E, 0x050A3B, 0x062698, 0x0322B9, 0x0378BA, 0x01E24D, -}, -{ - 0x110000, 0x190DAC, 0x1C0039, 0x26D69C, 0x17998C, 0x167D16, 0x2682AB, 0x22A891, - 0x132000, 0x0F06C3, 0x1D797F, 0x172876, 0x0AECE7, 0x0591D9, 0x0FF398, 0x0889E3, - 0x1D2717, 0x17FEEF, 0x1CBC47, 0x1693CA, 0x108754, 0x086D1D, 0x0F8D30, 0x07ED98, - 0x1D2717, 0x286F9A, 0x1B7C71, 0x261FD3, 0x187000, 0x21E552, 0x140904, 0x1BCA27, - 0x1FEDDC, 0x1CBC47, 0x1A2D62, 0x188A62, 0x0E6022, 0x1588DA, 0x083540, 0x0B6284, - 0x1448FE, 0x124192, 0x0B7D84, 0x0A574B, 0x2616FF, 0x2247AA, 0x23E98D, 0x2051FA, - 0x198000, 0x140904, 0x15B46F, 0x110DAA, 0x0DCCEE, 0x07541E, 0x0BBF1F, 0x05FD04, - 0x0F868B, 0x0C32C8, 0x08CB57, 0x0723D4, 0x08B6AD, 0x047130, 0x04EB08, 0x02AB42, -}, -{ - 0x160000, 0x206C0C, 0x243C86, 0x3242E8, 0x1E8A79, 0x1D1A59, 0x31D646, 0x2CDA25, - 0x18C000, 0x13722A, 0x2624C3, 0x1DF820, 0x0E2385, 0x073537, 0x14A4A7, 0x0B0CCC, - 0x25BA1D, 0x1F0DAE, 0x252FE4, 0x1D37BB, 0x1563D6, 0x0AE78E, 0x142021, 0x0A4288, - 0x25BA1D, 0x345430, 0x2391FB, 0x31565C, 0x1FA000, 0x2BDD7A, 0x19ED8D, 0x23F68C, - 0x2951EF, 0x252FE4, 0x21E061, 0x1FC224, 0x129A87, 0x1BDE47, 0x0A9F44, 0x0EBBBA, - 0x1A4058, 0x17A026, 0x0EDEAB, 0x0D61E9, 0x314AEF, 0x2C5CBE, 0x2E798A, 0x29D380, - 0x210000, 0x19ED8D, 0x1C16AE, 0x1611AE, 0x11DC06, 0x097BEA, 0x0F3391, 0x07BFE7, - 0x141787, 0x0FC93E, 0x0B617F, 0x093D6D, 0x0B46C1, 0x05BFA8, 0x065D55, 0x037437, -}, -{ - 0x1C0000, 0x2943B2, 0x2E1E7C, 0x3FF810, 0x26DEC9, 0x250A43, 0x3F6DCE, 0x3915A3, - 0x1F8000, 0x18BFD8, 0x308BE1, 0x262485, 0x11FEA9, 0x092C75, 0x1A45EB, 0x0E1049, - 0x300425, 0x2785C6, 0x2F5439, 0x252FA8, 0x1B393F, 0x0DE0E4, 0x199D41, 0x0D0EDC, - 0x300425, 0x4299B2, 0x2D456E, 0x3ECB00, 0x284000, 0x37D40F, 0x20FFCB, 0x2DC56D, - 0x3496D3, 0x2F5439, 0x2B1D93, 0x286B74, 0x17AD66, 0x2377FE, 0x0D84E2, 0x12C062, - 0x21692A, 0x1E11A5, 0x12ECDA, 0x110840, 0x3EBC76, 0x387608, 0x3B2652, 0x353BBA, - 0x2A0000, 0x20FFCB, 0x23BFC6, 0x1C1681, 0x16BAF1, 0x0C1213, 0x1358E8, 0x09DCF8, - 0x19924F, 0x141767, 0x0E7C16, 0x0BC28A, 0x0E5A0D, 0x075104, 0x0819B2, 0x04655D, -}, -{ - 0x220000, 0x321B58, 0x380072, 0x4DAD38, 0x2F3318, 0x2CFA2D, 0x4D0556, 0x455122, - 0x264000, 0x1E0D86, 0x3AF2FE, 0x2E50EB, 0x15D9CE, 0x0B23B2, 0x1FE730, 0x1113C7, - 0x3A4E2D, 0x2FFDDF, 0x39788E, 0x2D2795, 0x210EA8, 0x10DA39, 0x1F1A61, 0x0FDB2F, - 0x3A4E2D, 0x50DF33, 0x36F8E1, 0x4C3FA5, 0x30E000, 0x43CAA5, 0x281209, 0x37944D, - 0x3FDBB7, 0x39788E, 0x345AC4, 0x3114C3, 0x1CC044, 0x2B11B4, 0x106A80, 0x16C509, - 0x2891FC, 0x248324, 0x16FB08, 0x14AE97, 0x4C2DFD, 0x448F54, 0x47D31B, 0x40A3F5, - 0x330000, 0x281209, 0x2B68DF, 0x221B53, 0x1B99DB, 0x0EA83B, 0x177E3E, 0x0BFA09, - 0x1F0D17, 0x18658F, 0x1196AE, 0x0E47A8, 0x116D5A, 0x08E260, 0x09D60F, 0x055684, -}, -{ - 0x2C0000, 0x40D818, 0x48790C, 0x6485D0, 0x3D14F2, 0x3A34B2, 0x63AC8D, 0x59B44A, - 0x318000, 0x26E454, 0x4C4986, 0x3BF03F, 0x1C470A, 0x0E6A6E, 0x29494D, 0x161998, - 0x4B743A, 0x3E1B5C, 0x4A5FC7, 0x3A6F75, 0x2AC7AC, 0x15CF1D, 0x284041, 0x148510, - 0x4B743A, 0x68A861, 0x4723F6, 0x62ACB8, 0x3F4000, 0x57BAF3, 0x33DB1A, 0x47ED19, - 0x52A3DE, 0x4A5FC7, 0x43C0C2, 0x3F8448, 0x25350D, 0x37BC8E, 0x153E87, 0x1D7775, - 0x3480B0, 0x2F404C, 0x1DBD56, 0x1AC3D2, 0x6295DE, 0x58B97B, 0x5CF313, 0x53A701, - 0x420000, 0x33DB1A, 0x382D5C, 0x2C235D, 0x23B80D, 0x12F7D4, 0x1E6723, 0x0F7FCF, - 0x282F0E, 0x1F927D, 0x16C2FF, 0x127AD9, 0x168D83, 0x0B7F50, 0x0CBAAA, 0x06E86E, -}, -}; - -#endif /* AVCODEC_BINKDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/binkidct.c b/tizen/distrib/ffmpeg/libavcodec/binkidct.c deleted file mode 100644 index 160926e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/binkidct.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Bink IDCT algorithm - * Copyright (c) 2009 Kostya Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Bink IDCT algorithm - */ - -#include "dsputil.h" - -#define A1 2896 /* (1/sqrt(2))<<12 */ -#define A2 2217 -#define A3 3784 -#define A4 -5352 - -#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\ - const int a0 = (src)[s0] + (src)[s4]; \ - const int a1 = (src)[s0] - (src)[s4]; \ - const int a2 = (src)[s2] + (src)[s6]; \ - const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \ - const int a4 = (src)[s5] + (src)[s3]; \ - const int a5 = (src)[s5] - (src)[s3]; \ - const int a6 = (src)[s1] + (src)[s7]; \ - const int a7 = (src)[s1] - (src)[s7]; \ - const int b0 = a4 + a6; \ - const int b1 = (A3*(a5 + a7)) >> 11; \ - const int b2 = ((A4*a5) >> 11) - b0 + b1; \ - const int b3 = (A1*(a6 - a4) >> 11) - b2; \ - const int b4 = ((A2*a7) >> 11) + b3 - b1; \ - (dest)[d0] = munge(a0+a2 +b0); \ - (dest)[d1] = munge(a1+a3-a2+b2); \ - (dest)[d2] = munge(a1-a3+a2+b3); \ - (dest)[d3] = munge(a0-a2 -b4); \ - (dest)[d4] = munge(a0-a2 +b4); \ - (dest)[d5] = munge(a1-a3+a2-b3); \ - (dest)[d6] = munge(a1+a3-a2-b2); \ - (dest)[d7] = munge(a0+a2 -b0); \ -} -/* end IDCT_TRANSFORM macro */ - -#define MUNGE_NONE(x) (x) -#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src) - -#define MUNGE_ROW(x) (((x) + 0x7F)>>8) -#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src) - -static inline void bink_idct_col(DCTELEM *dest, const DCTELEM *src) -{ - if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) { - dest[0] = - dest[8] = - dest[16] = - dest[24] = - dest[32] = - dest[40] = - dest[48] = - dest[56] = src[0]; - } else { - IDCT_COL(dest, src); - } -} - -void ff_bink_idct_c(DCTELEM *block) -{ - int i; - DCTELEM temp[64]; - - for (i = 0; i < 8; i++) - bink_idct_col(&temp[i], &block[i]); - for (i = 0; i < 8; i++) { - IDCT_ROW( (&block[8*i]), (&temp[8*i]) ); - } -} - -void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i, j; - - ff_bink_idct_c(block); - for (i = 0; i < 8; i++, dest += linesize, block += 8) - for (j = 0; j < 8; j++) - dest[j] += block[j]; -} - -void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - DCTELEM temp[64]; - for (i = 0; i < 8; i++) - bink_idct_col(&temp[i], &block[i]); - for (i = 0; i < 8; i++) { - IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) ); - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/bitstream.c b/tizen/distrib/ffmpeg/libavcodec/bitstream.c deleted file mode 100644 index 0d7a2db..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bitstream.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Common bit i/o utils - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * Copyright (c) 2010 Loren Merritt - * - * alternative bitstream reader & writer by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * bitstream api. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "put_bits.h" - -const uint8_t ff_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 -}; - -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 *pb, const char *string, int terminate_string) -{ - while(*string){ - put_bits(pb, 8, *string); - string++; - } - if(terminate_string) - put_bits(pb, 8, 0); -} - -void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length) -{ - int words= length>>4; - int bits= length&15; - int i; - - if(length==0) return; - - if(CONFIG_SMALL || words < 16 || put_bits_count(pb)&7){ - for(i=0; i>(16-bits)); -} - -/* 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) { - if(use_static) - abort(); //cant do anything, init_vlc() is used with too little memory - vlc->table_allocated += (1 << vlc->bits); - vlc->table = av_realloc(vlc->table, - sizeof(VLC_TYPE) * 2 * vlc->table_allocated); - if (!vlc->table) - return -1; - } - return index; -} - -static av_always_inline uint32_t bitswap_32(uint32_t x) { - return av_reverse[x&0xFF]<<24 - | av_reverse[(x>>8)&0xFF]<<16 - | av_reverse[(x>>16)&0xFF]<<8 - | av_reverse[x>>24]; -} - -typedef struct { - uint8_t bits; - uint16_t symbol; - /** codeword, with the first bit-to-be-read in the msb - * (even if intended for a little-endian bitstream reader) */ - uint32_t code; -} VLCcode; - -static int compare_vlcspec(const void *a, const void *b) -{ - const VLCcode *sa=a, *sb=b; - return (sa->code >> 1) - (sb->code >> 1); -} - -/** - * Build VLC decoding tables suitable for use with get_vlc(). - * - * @param vlc the context to be initted - * - * @param table_nb_bits max length of vlc codes to store directly in this table - * (Longer codes are delegated to subtables.) - * - * @param nb_codes number of elements in codes[] - * - * @param codes descriptions of the vlc codes - * These must be ordered such that codes going into the same subtable are contiguous. - * Sorting by VLCcode.code is sufficient, though not necessary. - */ -static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, - VLCcode *codes, int flags) -{ - int table_size, table_index, index, code_prefix, symbol, subtable_bits; - int i, j, k, n, nb, inc; - uint32_t code; - VLC_TYPE (*table)[2]; - - table_size = 1 << table_nb_bits; - table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC); -#ifdef DEBUG_VLC - av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d\n", - table_index, table_size); -#endif - if (table_index < 0) - return -1; - table = &vlc->table[table_index]; - - for (i = 0; i < table_size; i++) { - table[i][1] = 0; //bits - table[i][0] = -1; //codes - } - - /* first pass: map codes and compute auxillary table sizes */ - for (i = 0; i < nb_codes; i++) { - n = codes[i].bits; - code = codes[i].code; - symbol = codes[i].symbol; -#if defined(DEBUG_VLC) && 0 - av_log(NULL,AV_LOG_DEBUG,"i=%d n=%d code=0x%x\n", i, n, code); -#endif - if (n <= table_nb_bits) { - /* no need to add another table */ - j = code >> (32 - table_nb_bits); - nb = 1 << (table_nb_bits - n); - inc = 1; - if (flags & INIT_VLC_LE) { - j = bitswap_32(code); - inc = 1 << n; - } - for (k = 0; k < nb; k++) { -#ifdef DEBUG_VLC - av_log(NULL, AV_LOG_DEBUG, "%4x: code=%d n=%d\n", - j, i, n); -#endif - if (table[j][1] /*bits*/ != 0) { - av_log(NULL, AV_LOG_ERROR, "incorrect codes\n"); - return -1; - } - table[j][1] = n; //bits - table[j][0] = symbol; - j += inc; - } - } else { - /* fill auxiliary table recursively */ - n -= table_nb_bits; - code_prefix = code >> (32 - table_nb_bits); - subtable_bits = n; - codes[i].bits = n; - codes[i].code = code << table_nb_bits; - for (k = i+1; k < nb_codes; k++) { - n = codes[k].bits - table_nb_bits; - if (n <= 0) - break; - code = codes[k].code; - if (code >> (32 - table_nb_bits) != code_prefix) - break; - codes[k].bits = n; - codes[k].code = code << table_nb_bits; - subtable_bits = FFMAX(subtable_bits, n); - } - subtable_bits = FFMIN(subtable_bits, table_nb_bits); - j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix; - table[j][1] = -subtable_bits; -#ifdef DEBUG_VLC - av_log(NULL,AV_LOG_DEBUG,"%4x: n=%d (subtable)\n", - j, codes[i].bits + table_nb_bits); -#endif - index = build_table(vlc, subtable_bits, k-i, codes+i, flags); - if (index < 0) - return -1; - /* note: realloc has been done, so reload tables */ - table = &vlc->table[table_index]; - table[j][0] = index; //code - i = k-1; - } - } - 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. - - 'symbols' : table which gives the values to be returned from get_vlc(). - - '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', 'codes', and 'symbols' 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_sparse(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, - const void *symbols, int symbols_wrap, int symbols_size, - int flags) -{ - VLCcode buf[nb_codes]; - int i, j; - - vlc->bits = nb_bits; - if(flags & INIT_VLC_USE_NEW_STATIC){ - if(vlc->table_size && vlc->table_size == vlc->table_allocated){ - return 0; - }else if(vlc->table_size){ - abort(); // fatal error, we are called on a partially initialized table - } - }else { - vlc->table = NULL; - vlc->table_allocated = 0; - vlc->table_size = 0; - } - -#ifdef DEBUG_VLC - av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes); -#endif - - assert(symbols_size <= 2 || !symbols); - j = 0; -#define COPY(condition)\ - for (i = 0; i < nb_codes; i++) {\ - GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);\ - if (!(condition))\ - continue;\ - GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);\ - if (flags & INIT_VLC_LE)\ - buf[j].code = bitswap_32(buf[j].code);\ - else\ - buf[j].code <<= 32 - buf[j].bits;\ - if (symbols)\ - GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size)\ - else\ - buf[j].symbol = i;\ - j++;\ - } - COPY(buf[j].bits > nb_bits); - // qsort is the slowest part of init_vlc, and could probably be improved or avoided - qsort(buf, j, sizeof(VLCcode), compare_vlcspec); - COPY(buf[j].bits && buf[j].bits <= nb_bits); - nb_codes = j; - - if (build_table(vlc, nb_bits, nb_codes, buf, flags) < 0) { - av_freep(&vlc->table); - return -1; - } - if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated) - av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated); - return 0; -} - - -void free_vlc(VLC *vlc) -{ - av_freep(&vlc->table); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/bitstream_filter.c b/tizen/distrib/ffmpeg/libavcodec/bitstream_filter.c deleted file mode 100644 index 1a6ba39..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bitstream_filter.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" - -static AVBitStreamFilter *first_bitstream_filter= NULL; - -AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f){ - if(f) return f->next; - else return first_bitstream_filter; -} - -void av_register_bitstream_filter(AVBitStreamFilter *bsf){ - bsf->next = first_bitstream_filter; - first_bitstream_filter= bsf; -} - -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name){ - AVBitStreamFilter *bsf= first_bitstream_filter; - - while(bsf){ - if(!strcmp(name, bsf->name)){ - AVBitStreamFilterContext *bsfc= av_mallocz(sizeof(AVBitStreamFilterContext)); - bsfc->filter= bsf; - bsfc->priv_data= av_mallocz(bsf->priv_data_size); - return bsfc; - } - bsf= bsf->next; - } - return NULL; -} - -void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){ - if(bsfc->filter->close) - bsfc->filter->close(bsfc); - av_freep(&bsfc->priv_data); - av_parser_close(bsfc->parser); - av_free(bsfc); -} - -int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/bmp.c b/tizen/distrib/ffmpeg/libavcodec/bmp.c deleted file mode 100644 index da7bb78..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bmp.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * BMP image format decoder - * Copyright (c) 2005 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "bmp.h" -#include "msrledec.h" - -static av_cold 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - BMPContext *s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p = &s->picture; - unsigned int fsize, hsize; - int width, height; - unsigned int depth; - BiCompression comp; - unsigned int ihsize; - int i, j, n, linesize; - uint32_t rgb[3]; - uint8_t *ptr; - int dsize; - const uint8_t *buf0 = buf; - - if(buf_size < 14){ - av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); - return -1; - } - - if(bytestream_get_byte(&buf) != 'B' || - bytestream_get_byte(&buf) != 'M') { - av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); - return -1; - } - - fsize = bytestream_get_le32(&buf); - if(buf_size < fsize){ - av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n", - buf_size, fsize); - fsize = buf_size; - } - - buf += 2; /* reserved1 */ - buf += 2; /* reserved2 */ - - hsize = bytestream_get_le32(&buf); /* header size */ - ihsize = bytestream_get_le32(&buf); /* more header size */ - if(ihsize + 14 > hsize){ - av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize); - return -1; - } - - /* sometimes file size is set to some headers size, set a real size in that case */ - if(fsize == 14 || fsize == ihsize + 14) - fsize = buf_size - 2; - - if(fsize <= hsize){ - av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n", - fsize, hsize); - return -1; - } - - switch(ihsize){ - case 40: // windib v3 - case 64: // OS/2 v2 - case 108: // windib v4 - case 124: // windib v5 - width = bytestream_get_le32(&buf); - height = bytestream_get_le32(&buf); - break; - case 12: // OS/2 v1 - width = bytestream_get_le16(&buf); - height = bytestream_get_le16(&buf); - break; - default: - av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n"); - return -1; - } - - if(bytestream_get_le16(&buf) != 1){ /* planes */ - av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n"); - return -1; - } - - depth = bytestream_get_le16(&buf); - - if(ihsize == 40) - comp = bytestream_get_le32(&buf); - else - comp = BMP_RGB; - - if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){ - av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); - return -1; - } - - if(comp == BMP_BITFIELDS){ - buf += 20; - rgb[0] = bytestream_get_le32(&buf); - rgb[1] = bytestream_get_le32(&buf); - rgb[2] = bytestream_get_le32(&buf); - } - - 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; - if(comp == BMP_BITFIELDS) - avctx->pix_fmt = rgb[1] == 0x07E0 ? PIX_FMT_RGB565 : PIX_FMT_RGB555; - break; - case 8: - if(hsize - ihsize - 14 > 0) - avctx->pix_fmt = PIX_FMT_PAL8; - else - avctx->pix_fmt = PIX_FMT_GRAY8; - break; - case 4: - if(hsize - ihsize - 14 > 0){ - avctx->pix_fmt = PIX_FMT_PAL8; - }else{ - av_log(avctx, AV_LOG_ERROR, "Unknown palette for 16-colour BMP\n"); - return -1; - } - break; - case 1: - avctx->pix_fmt = PIX_FMT_MONOBLACK; - 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; - } - - 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 = FF_I_TYPE; - p->key_frame = 1; - - buf = buf0 + hsize; - dsize = buf_size - hsize; - - /* Line size in file multiple of 4 */ - n = ((avctx->width * depth) / 8 + 3) & ~3; - - if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){ - av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", - dsize, n * avctx->height); - return -1; - } - - // RLE may skip decoding some picture areas, so blank picture before decoding - if(comp == BMP_RLE4 || comp == BMP_RLE8) - memset(p->data[0], 0, avctx->height * p->linesize[0]); - - if(depth == 4 || depth == 8) - memset(p->data[1], 0, 1024); - - 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]; - } - - if(avctx->pix_fmt == PIX_FMT_PAL8){ - int colors = 1 << depth; - if(ihsize >= 36){ - int t; - buf = buf0 + 46; - t = bytestream_get_le32(&buf); - if(t < 0 || t > (1 << depth)){ - av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth); - }else if(t){ - colors = t; - } - } - buf = buf0 + 14 + ihsize; //palette location - if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per palette entry - for(i = 0; i < colors; i++) - ((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf); - }else{ - for(i = 0; i < colors; i++) - ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf); - } - buf = buf0 + hsize; - } - if(comp == BMP_RLE4 || comp == BMP_RLE8){ - if(height < 0){ - p->data[0] += p->linesize[0] * (avctx->height - 1); - p->linesize[0] = -p->linesize[0]; - } - ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize); - if(height < 0){ - p->data[0] += p->linesize[0] * (avctx->height - 1); - p->linesize[0] = -p->linesize[0]; - } - }else{ - switch(depth){ - case 1: - case 8: - case 24: - for(i = 0; i < avctx->height; i++){ - memcpy(ptr, buf, n); - buf += n; - ptr += linesize; - } - break; - case 4: - for(i = 0; i < avctx->height; i++){ - int j; - for(j = 0; j < n; j++){ - ptr[j*2+0] = (buf[j] >> 4) & 0xF; - ptr[j*2+1] = buf[j] & 0xF; - } - buf += n; - ptr += linesize; - } - break; - case 16: - for(i = 0; i < avctx->height; i++){ - const uint16_t *src = (const 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++){ - const 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; -} - -static av_cold int bmp_decode_end(AVCodecContext *avctx) -{ - BMPContext* c = avctx->priv_data; - - if (c->picture.data[0]) - avctx->release_buffer(avctx, &c->picture); - - return 0; -} - -AVCodec bmp_decoder = { - "bmp", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_BMP, - sizeof(BMPContext), - bmp_decode_init, - NULL, - bmp_decode_end, - bmp_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("BMP image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/bmp.h b/tizen/distrib/ffmpeg/libavcodec/bmp.h deleted file mode 100644 index b24a1fa..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bmp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * internals for BMP codecs - * Copyright (c) 2005 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_BMP_H -#define AVCODEC_BMP_H - -#include "avcodec.h" - -typedef struct BMPContext { - AVFrame picture; -} BMPContext; - -typedef enum { - BMP_RGB =0, - BMP_RLE8 =1, - BMP_RLE4 =2, - BMP_BITFIELDS =3, -} BiCompression; - -#endif /* AVCODEC_BMP_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/bmpenc.c b/tizen/distrib/ffmpeg/libavcodec/bmpenc.c deleted file mode 100644 index ee85f3c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bmpenc.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * BMP image format encoder - * Copyright (c) 2006, 2007 Michel Bardiaux - * Copyright (c) 2009 Daniel Verkamp - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "bmp.h" - -static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF }; -static const uint32_t rgb565_masks[] = { 0xF800, 0x07E0, 0x001F }; - -static av_cold int bmp_encode_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_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - BMPContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; - int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize; - const uint32_t *pal = NULL; - int pad_bytes_per_row, bit_count, pal_entries = 0, compression = BMP_RGB; - uint8_t *ptr; - unsigned char* buf0 = buf; - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - switch (avctx->pix_fmt) { - case PIX_FMT_BGR24: - bit_count = 24; - break; - case PIX_FMT_RGB555: - bit_count = 16; - break; - case PIX_FMT_RGB565: - bit_count = 16; - compression = BMP_BITFIELDS; - pal = rgb565_masks; // abuse pal to hold color masks - pal_entries = 3; - break; - case PIX_FMT_RGB8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB4_BYTE: - case PIX_FMT_BGR4_BYTE: - case PIX_FMT_GRAY8: - case PIX_FMT_PAL8: - bit_count = 8; - pal = (uint32_t *)p->data[1]; - break; - case PIX_FMT_MONOBLACK: - bit_count = 1; - pal = monoblack_pal; - break; - default: - return -1; - } - if (pal && !pal_entries) pal_entries = 1 << bit_count; - n_bytes_per_row = ((int64_t)avctx->width * (int64_t)bit_count + 7LL) >> 3LL; - pad_bytes_per_row = (4 - n_bytes_per_row) & 3; - n_bytes_image = avctx->height * (n_bytes_per_row + pad_bytes_per_row); - - // STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER - // and related pages. -#define SIZE_BITMAPFILEHEADER 14 -#define SIZE_BITMAPINFOHEADER 40 - hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER + (pal_entries << 2); - n_bytes = n_bytes_image + hsize; - if(n_bytes>buf_size) { - av_log(avctx, AV_LOG_ERROR, "buf size too small (need %d, got %d)\n", n_bytes, buf_size); - return -1; - } - bytestream_put_byte(&buf, 'B'); // BITMAPFILEHEADER.bfType - bytestream_put_byte(&buf, 'M'); // do. - bytestream_put_le32(&buf, n_bytes); // BITMAPFILEHEADER.bfSize - bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved1 - bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved2 - bytestream_put_le32(&buf, hsize); // BITMAPFILEHEADER.bfOffBits - bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize - bytestream_put_le32(&buf, avctx->width); // BITMAPINFOHEADER.biWidth - bytestream_put_le32(&buf, avctx->height); // BITMAPINFOHEADER.biHeight - bytestream_put_le16(&buf, 1); // BITMAPINFOHEADER.biPlanes - bytestream_put_le16(&buf, bit_count); // BITMAPINFOHEADER.biBitCount - bytestream_put_le32(&buf, compression); // BITMAPINFOHEADER.biCompression - bytestream_put_le32(&buf, n_bytes_image); // BITMAPINFOHEADER.biSizeImage - bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biXPelsPerMeter - bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biYPelsPerMeter - bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrUsed - bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrImportant - for (i = 0; i < pal_entries; i++) - bytestream_put_le32(&buf, pal[i] & 0xFFFFFF); - // BMP files are bottom-to-top so we start from the end... - ptr = p->data[0] + (avctx->height - 1) * p->linesize[0]; - buf = buf0 + hsize; - for(i = 0; i < avctx->height; i++) { - if (bit_count == 16) { - const uint16_t *src = (const uint16_t *) ptr; - uint16_t *dst = (uint16_t *) buf; - for(n = 0; n < avctx->width; n++) - AV_WL16(dst + n, src[n]); - } else { - memcpy(buf, ptr, n_bytes_per_row); - } - buf += n_bytes_per_row; - memset(buf, 0, pad_bytes_per_row); - buf += pad_bytes_per_row; - ptr -= p->linesize[0]; // ... and go back - } - return n_bytes; -} - -AVCodec bmp_encoder = { - "bmp", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_BMP, - sizeof(BMPContext), - bmp_encode_init, - bmp_encode_frame, - NULL, //encode_end, - .pix_fmts = (const enum PixelFormat[]){ - PIX_FMT_BGR24, - PIX_FMT_RGB555, PIX_FMT_RGB565, - PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8, - PIX_FMT_MONOBLACK, - PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("BMP image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/bytestream.h b/tizen/distrib/ffmpeg/libavcodec/bytestream.h deleted file mode 100644 index b56f6ce..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/bytestream.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Bytestream functions - * copyright (c) 2006 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_BYTESTREAM_H -#define AVCODEC_BYTESTREAM_H - -#include -#include "libavutil/common.h" -#include "libavutil/intreadwrite.h" - -#define DEF_T(type, name, bytes, read, write) \ -static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\ - (*b) += bytes;\ - return read(*b - bytes);\ -}\ -static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type value){\ - write(*b, value);\ - (*b) += bytes;\ -} - -#define DEF(name, bytes, read, write) \ - DEF_T(unsigned int, name, bytes, read, write) -#define DEF64(name, bytes, read, write) \ - DEF_T(uint64_t, name, bytes, read, write) - -DEF64(le64, 8, AV_RL64, AV_WL64) -DEF (le32, 4, AV_RL32, AV_WL32) -DEF (le24, 3, AV_RL24, AV_WL24) -DEF (le16, 2, AV_RL16, AV_WL16) -DEF64(be64, 8, AV_RB64, AV_WB64) -DEF (be32, 4, AV_RB32, AV_WB32) -DEF (be24, 3, AV_RB24, AV_WB24) -DEF (be16, 2, AV_RB16, AV_WB16) -DEF (byte, 1, AV_RB8 , AV_WB8 ) - -#undef DEF -#undef DEF64 -#undef DEF_T - -static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size) -{ - memcpy(dst, *b, size); - (*b) += size; - return size; -} - -static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size) -{ - memcpy(*b, src, size); - (*b) += size; -} - -#endif /* AVCODEC_BYTESTREAM_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/c93.c b/tizen/distrib/ffmpeg/libavcodec/c93.c deleted file mode 100644 index d713ff8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/c93.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Interplay C93 video decoder - * Copyright (c) 2007 Anssi Hannula - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" - -typedef struct { - AVFrame pictures[2]; - int currentpic; -} C93DecoderContext; - -typedef enum { - C93_8X8_FROM_PREV = 0x02, - C93_4X4_FROM_PREV = 0x06, - C93_4X4_FROM_CURR = 0x07, - C93_8X8_2COLOR = 0x08, - C93_4X4_2COLOR = 0x0A, - C93_4X4_4COLOR_GRP = 0x0B, - C93_4X4_4COLOR = 0x0D, - C93_NOOP = 0x0E, - C93_8X8_INTRA = 0x0F, -} C93BlockType; - -#define WIDTH 320 -#define HEIGHT 192 - -#define C93_HAS_PALETTE 0x01 -#define C93_FIRST_FRAME 0x02 - -static av_cold int decode_init(AVCodecContext *avctx) -{ - avctx->pix_fmt = PIX_FMT_PAL8; - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - C93DecoderContext * const c93 = avctx->priv_data; - - if (c93->pictures[0].data[0]) - avctx->release_buffer(avctx, &c93->pictures[0]); - if (c93->pictures[1].data[0]) - avctx->release_buffer(avctx, &c93->pictures[1]); - return 0; -} - -static inline int copy_block(AVCodecContext *avctx, uint8_t *to, - uint8_t *from, int offset, int height, int stride) -{ - int i; - int width = height; - int from_x = offset % WIDTH; - int from_y = offset / WIDTH; - int overflow = from_x + width - WIDTH; - - if (!from) { - /* silently ignoring predictive blocks in first frame */ - return 0; - } - - if (from_y + height > HEIGHT) { - av_log(avctx, AV_LOG_ERROR, "invalid offset %d during C93 decoding\n", - offset); - return -1; - } - - if (overflow > 0) { - width -= overflow; - for (i = 0; i < height; i++) { - memcpy(&to[i*stride+width], &from[(from_y+i)*stride], overflow); - } - } - - for (i = 0; i < height; i++) { - memcpy(&to[i*stride], &from[(from_y+i)*stride+from_x], width); - } - - return 0; -} - -static inline void draw_n_color(uint8_t *out, int stride, int width, - int height, int bpp, uint8_t cols[4], uint8_t grps[4], uint32_t col) -{ - int x, y; - for (y = 0; y < height; y++) { - if (grps) - cols[0] = grps[3 * (y >> 1)]; - for (x = 0; x < width; x++) { - if (grps) - cols[1]= grps[(x >> 1) + 1]; - out[x + y*stride] = cols[col & ((1 << bpp) - 1)]; - col >>= bpp; - } - } -} - -static int decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - C93DecoderContext * const c93 = avctx->priv_data; - AVFrame * const newpic = &c93->pictures[c93->currentpic]; - AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; - AVFrame *picture = data; - uint8_t *out; - int stride, i, x, y, bt = 0; - - c93->currentpic ^= 1; - - newpic->reference = 1; - newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; - if (avctx->reget_buffer(avctx, newpic)) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - - stride = newpic->linesize[0]; - - if (buf[0] & C93_FIRST_FRAME) { - newpic->pict_type = FF_I_TYPE; - newpic->key_frame = 1; - } else { - newpic->pict_type = FF_P_TYPE; - newpic->key_frame = 0; - } - - if (*buf++ & C93_HAS_PALETTE) { - uint32_t *palette = (uint32_t *) newpic->data[1]; - const uint8_t *palbuf = buf + buf_size - 768 - 1; - for (i = 0; i < 256; i++) { - palette[i] = bytestream_get_be24(&palbuf); - } - } else { - if (oldpic->data[1]) - memcpy(newpic->data[1], oldpic->data[1], 256 * 4); - } - - for (y = 0; y < HEIGHT; y += 8) { - out = newpic->data[0] + y * stride; - for (x = 0; x < WIDTH; x += 8) { - uint8_t *copy_from = oldpic->data[0]; - unsigned int offset, j; - uint8_t cols[4], grps[4]; - C93BlockType block_type; - - if (!bt) - bt = *buf++; - - block_type= bt & 0x0F; - switch (block_type) { - case C93_8X8_FROM_PREV: - offset = bytestream_get_le16(&buf); - if (copy_block(avctx, out, copy_from, offset, 8, stride)) - return -1; - break; - - case C93_4X4_FROM_CURR: - copy_from = newpic->data[0]; - case C93_4X4_FROM_PREV: - for (j = 0; j < 8; j += 4) { - for (i = 0; i < 8; i += 4) { - offset = bytestream_get_le16(&buf); - if (copy_block(avctx, &out[j*stride+i], - copy_from, offset, 4, stride)) - return -1; - } - } - break; - - case C93_8X8_2COLOR: - bytestream_get_buffer(&buf, cols, 2); - for (i = 0; i < 8; i++) { - draw_n_color(out + i*stride, stride, 8, 1, 1, cols, - NULL, *buf++); - } - - break; - - case C93_4X4_2COLOR: - case C93_4X4_4COLOR: - case C93_4X4_4COLOR_GRP: - for (j = 0; j < 8; j += 4) { - for (i = 0; i < 8; i += 4) { - if (block_type == C93_4X4_2COLOR) { - bytestream_get_buffer(&buf, cols, 2); - draw_n_color(out + i + j*stride, stride, 4, 4, - 1, cols, NULL, bytestream_get_le16(&buf)); - } else if (block_type == C93_4X4_4COLOR) { - bytestream_get_buffer(&buf, cols, 4); - draw_n_color(out + i + j*stride, stride, 4, 4, - 2, cols, NULL, bytestream_get_le32(&buf)); - } else { - bytestream_get_buffer(&buf, grps, 4); - draw_n_color(out + i + j*stride, stride, 4, 4, - 1, cols, grps, bytestream_get_le16(&buf)); - } - } - } - break; - - case C93_NOOP: - break; - - case C93_8X8_INTRA: - for (j = 0; j < 8; j++) - bytestream_get_buffer(&buf, out + j*stride, 8); - break; - - default: - av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", - block_type, x, y); - return -1; - } - bt >>= 4; - out += 8; - } - } - - *picture = *newpic; - *data_size = sizeof(AVFrame); - - return buf_size; -} - -AVCodec c93_decoder = { - "c93", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_C93, - sizeof(C93DecoderContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Interplay C93"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/cabac.c b/tizen/distrib/ffmpeg/libavcodec/cabac.c deleted file mode 100644 index 7b5e5b1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cabac.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Context Adaptive Binary Arithmetic Coder. - */ - -#include - -#include "libavutil/common.h" -#include "get_bits.h" -#include "cabac.h" - -static const uint8_t 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}, -}; - -uint8_t ff_h264_mlps_state[4*64]; -uint8_t ff_h264_lps_range[4*2*64]; -uint8_t ff_h264_lps_state[2*64]; -uint8_t ff_h264_mps_state[2*64]; - -static const uint8_t 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, -}; - -static const uint8_t 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, -}; -#if 0 -const uint8_t ff_h264_norm_shift_old[128]= { - 7,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3, - 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,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -}; -#endif -const uint8_t ff_h264_norm_shift[512]= { - 9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5, - 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,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,2,2,2,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, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,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, -}; - -/** - * - * @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; -} - -void ff_init_cabac_states(CABACContext *c){ - int i, j; - - for(i=0; i<64; i++){ - for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save - ff_h264_lps_range[j*2*64+2*i+0]= - ff_h264_lps_range[j*2*64+2*i+1]= lps_range[i][j]; - } - - ff_h264_mlps_state[128+2*i+0]= - ff_h264_mps_state[2*i+0]= 2*mps_state[i]+0; - ff_h264_mlps_state[128+2*i+1]= - ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1; - - if( i ){ -#ifdef BRANCHLESS_CABAC_DECODER - ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0; - ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1; - }else{ - ff_h264_mlps_state[128-2*i-1]= 1; - ff_h264_mlps_state[128-2*i-2]= 0; -#else - ff_h264_lps_state[2*i+0]= 2*lps_state[i]+0; - ff_h264_lps_state[2*i+1]= 2*lps_state[i]+1; - }else{ - ff_h264_lps_state[2*i+0]= 1; - ff_h264_lps_state[2*i+1]= 0; -#endif - } - } -} - -#ifdef TEST -#define SIZE 10240 - -#include "libavutil/lfg.h" -#include "avcodec.h" -#include "cabac.h" - -int main(void){ - CABACContext c; - uint8_t b[9*SIZE]; - uint8_t r[9*SIZE]; - int i; - uint8_t state[10]= {0}; - AVLFG prng; - - av_lfg_init(&prng, 1); - ff_init_cabac_encoder(&c, b, SIZE); - ff_init_cabac_states(&c); - - for(i=0; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Context Adaptive Binary Arithmetic Coder. - */ - -#ifndef AVCODEC_CABAC_H -#define AVCODEC_CABAC_H - -#include "put_bits.h" - -//#undef NDEBUG -#include -#include "libavutil/x86_cpu.h" - -#define CABAC_BITS 16 -#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; - } -} - -#ifdef TEST -static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ - int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state]; - - if(bit == ((*state)&1)){ - c->range -= RangeLPS; - *state= ff_h264_mps_state[*state]; - }else{ - c->low += c->range - RangeLPS; - c->range = RangeLPS; - *state= ff_h264_lps_state[*state]; - } - - renorm_cabac_encoder(c); - -#ifdef STRICT_LIMITS - c->symCount++; -#endif -} - -static 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 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 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 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); - } -} -#endif /* TEST */ - -static void refill(CABACContext *c){ -#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 ! ( ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) ) -static void refill2(CABACContext *c){ - int i, x; - - x= c->low ^ (c->low-1); - i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; - - x= -CABAC_MASK; - -#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 < 0x100){ - c->range+= c->range; - c->low+= c->low; - if(!(c->low & CABAC_MASK)) - refill(c); - } -} - -static inline void renorm_cabac_decoder_once(CABACContext *c){ -#ifdef ARCH_X86_DISABLED - int temp; -#if 0 - //P3:683 athlon:475 - __asm__( - "lea -0x100(%0), %2 \n\t" - "shr $31, %2 \n\t" //FIXME 31->63 for x86-64 - "shl %%cl, %0 \n\t" - "shl %%cl, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+c"(temp) - ); -#elif 0 - //P3:680 athlon:474 - __asm__( - "cmp $0x100, %0 \n\t" - "setb %%cl \n\t" //FIXME 31->63 for x86-64 - "shl %%cl, %0 \n\t" - "shl %%cl, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+c"(temp) - ); -#elif 1 - int temp2; - //P3:665 athlon:517 - __asm__( - "lea -0x100(%0), %%eax \n\t" - "cltd \n\t" - "mov %0, %%eax \n\t" - "and %%edx, %0 \n\t" - "and %1, %%edx \n\t" - "add %%eax, %0 \n\t" - "add %%edx, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) - ); -#elif 0 - int temp2; - //P3:673 athlon:509 - __asm__( - "cmp $0x100, %0 \n\t" - "sbb %%edx, %%edx \n\t" - "mov %0, %%eax \n\t" - "and %%edx, %0 \n\t" - "and %1, %%edx \n\t" - "add %%eax, %0 \n\t" - "add %%edx, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) - ); -#else - int temp2; - //P3:677 athlon:511 - __asm__( - "cmp $0x100, %0 \n\t" - "lea (%0, %0), %%eax \n\t" - "lea (%1, %1), %%edx \n\t" - "cmovb %%eax, %0 \n\t" - "cmovb %%edx, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) - ); -#endif -#else - //P3:675 athlon:476 - int shift= (uint32_t)(c->range - 0x100)>>31; - c->range<<= shift; - c->low <<= shift; -#endif - if(!(c->low & CABAC_MASK)) - refill(c); -} - -static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ - //FIXME gcc generates duplicate load/stores for c->low and c->range -#define LOW "0" -#define RANGE "4" -#if ARCH_X86_64 -#define BYTESTART "16" -#define BYTE "24" -#define BYTEEND "32" -#else -#define BYTESTART "12" -#define BYTE "16" -#define BYTEEND "20" -#endif -#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) - int bit; - -#ifndef BRANCHLESS_CABAC_DECODER - __asm__ volatile( - "movzbl (%1), %0 \n\t" - "movl "RANGE "(%2), %%ebx \n\t" - "movl "RANGE "(%2), %%edx \n\t" - "andl $0xC0, %%ebx \n\t" - "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t" - "movl "LOW "(%2), %%ebx \n\t" -//eax:state ebx:low, edx:range, esi:RangeLPS - "subl %%esi, %%edx \n\t" - "movl %%edx, %%ecx \n\t" - "shll $17, %%ecx \n\t" - "cmpl %%ecx, %%ebx \n\t" - " ja 1f \n\t" - -#if 1 - //athlon:4067 P3:4110 - "lea -0x100(%%edx), %%ecx \n\t" - "shr $31, %%ecx \n\t" - "shl %%cl, %%edx \n\t" - "shl %%cl, %%ebx \n\t" -#else - //athlon:4057 P3:4130 - "cmp $0x100, %%edx \n\t" //FIXME avoidable - "setb %%cl \n\t" - "shl %%cl, %%edx \n\t" - "shl %%cl, %%ebx \n\t" -#endif - "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx \n\t" - "movb %%cl, (%1) \n\t" -//eax:state ebx:low, edx:range, esi:RangeLPS - "test %%bx, %%bx \n\t" - " jnz 2f \n\t" - "mov "BYTE "(%2), %%"REG_S" \n\t" - "subl $0xFFFF, %%ebx \n\t" - "movzwl (%%"REG_S"), %%ecx \n\t" - "bswap %%ecx \n\t" - "shrl $15, %%ecx \n\t" - "add $2, %%"REG_S" \n\t" - "addl %%ecx, %%ebx \n\t" - "mov %%"REG_S", "BYTE "(%2) \n\t" - "jmp 2f \n\t" - "1: \n\t" -//eax:state ebx:low, edx:range, esi:RangeLPS - "subl %%ecx, %%ebx \n\t" - "movl %%esi, %%edx \n\t" - "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx \n\t" - "shll %%cl, %%ebx \n\t" - "shll %%cl, %%edx \n\t" - "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx \n\t" - "movb %%cl, (%1) \n\t" - "add $1, %0 \n\t" - "test %%bx, %%bx \n\t" - " jnz 2f \n\t" - - "mov "BYTE "(%2), %%"REG_c" \n\t" - "movzwl (%%"REG_c"), %%esi \n\t" - "bswap %%esi \n\t" - "shrl $15, %%esi \n\t" - "subl $0xFFFF, %%esi \n\t" - "add $2, %%"REG_c" \n\t" - "mov %%"REG_c", "BYTE "(%2) \n\t" - - "leal -1(%%ebx), %%ecx \n\t" - "xorl %%ebx, %%ecx \n\t" - "shrl $15, %%ecx \n\t" - "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t" - "neg %%ecx \n\t" - "add $7, %%ecx \n\t" - - "shll %%cl , %%esi \n\t" - "addl %%esi, %%ebx \n\t" - "2: \n\t" - "movl %%edx, "RANGE "(%2) \n\t" - "movl %%ebx, "LOW "(%2) \n\t" - :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or miscompiles it (for example if "+a"(bit) or "+m"(*state) is used - :"r"(state), "r"(c) - : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory" - ); - bit&=1; -#else /* BRANCHLESS_CABAC_DECODER */ - - -#if HAVE_FAST_CMOV -#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ - "mov "tmp" , %%ecx \n\t"\ - "shl $17 , "tmp" \n\t"\ - "cmp "low" , "tmp" \n\t"\ - "cmova %%ecx , "range" \n\t"\ - "sbb %%ecx , %%ecx \n\t"\ - "and %%ecx , "tmp" \n\t"\ - "sub "tmp" , "low" \n\t"\ - "xor %%ecx , "ret" \n\t" -#else /* HAVE_FAST_CMOV */ -#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ - "mov "tmp" , %%ecx \n\t"\ - "shl $17 , "tmp" \n\t"\ - "sub "low" , "tmp" \n\t"\ - "sar $31 , "tmp" \n\t" /*lps_mask*/\ - "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\ - "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\ - "add %%ecx , "range" \n\t" /*new range*/\ - "shl $17 , %%ecx \n\t"\ - "and "tmp" , %%ecx \n\t"\ - "sub %%ecx , "low" \n\t"\ - "xor "tmp" , "ret" \n\t" -#endif /* HAVE_FAST_CMOV */ - - -#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ - "movzbl "statep" , "ret" \n\t"\ - "mov "range" , "tmp" \n\t"\ - "and $0xC0 , "range" \n\t"\ - "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\ - "sub "range" , "tmp" \n\t"\ - BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ - "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\ - "shl %%cl , "range" \n\t"\ - "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\ - "mov "tmpbyte" , "statep" \n\t"\ - "shl %%cl , "low" \n\t"\ - "test "lowword" , "lowword" \n\t"\ - " jnz 1f \n\t"\ - "mov "BYTE"("cabac"), %%"REG_c" \n\t"\ - "movzwl (%%"REG_c") , "tmp" \n\t"\ - "bswap "tmp" \n\t"\ - "shr $15 , "tmp" \n\t"\ - "sub $0xFFFF , "tmp" \n\t"\ - "add $2 , %%"REG_c" \n\t"\ - "mov %%"REG_c" , "BYTE "("cabac") \n\t"\ - "lea -1("low") , %%ecx \n\t"\ - "xor "low" , %%ecx \n\t"\ - "shr $15 , %%ecx \n\t"\ - "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\ - "neg %%ecx \n\t"\ - "add $7 , %%ecx \n\t"\ - "shl %%cl , "tmp" \n\t"\ - "add "tmp" , "low" \n\t"\ - "1: \n\t" - - __asm__ volatile( - "movl "RANGE "(%2), %%esi \n\t" - "movl "LOW "(%2), %%ebx \n\t" - BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl") - "movl %%esi, "RANGE "(%2) \n\t" - "movl %%ebx, "LOW "(%2) \n\t" - - :"=&a"(bit) - :"r"(state), "r"(c) - : "%"REG_c, "%ebx", "%edx", "%esi", "memory" - ); - bit&=1; -#endif /* BRANCHLESS_CABAC_DECODER */ -#else /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ - int s = *state; - int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; - int bit, lps_mask av_unused; - - c->range -= RangeLPS; -#ifndef BRANCHLESS_CABAC_DECODER - if(c->low < (c->range<<(CABAC_BITS+1))){ - bit= s&1; - *state= ff_h264_mps_state[s]; - renorm_cabac_decoder_once(c); - }else{ - bit= ff_h264_norm_shift[RangeLPS]; - c->low -= (c->range<<(CABAC_BITS+1)); - *state= ff_h264_lps_state[s]; - c->range = RangeLPS<low <<= bit; - bit= (s&1)^1; - - if(!(c->low & CABAC_MASK)){ - refill2(c); - } - } -#else /* BRANCHLESS_CABAC_DECODER */ - lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; - - c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; - c->range += (RangeLPS - c->range) & lps_mask; - - s^=lps_mask; - *state= (ff_h264_mlps_state+128)[s]; - bit= s&1; - - lps_mask= ff_h264_norm_shift[c->range]; - c->range<<= lps_mask; - c->low <<= lps_mask; - if(!(c->low & CABAC_MASK)) - refill2(c); -#endif /* BRANCHLESS_CABAC_DECODER */ -#endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ - return bit; -} - -static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ - return get_cabac_inline(c,state); -} - -static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ - return get_cabac_inline(c,state); -} - -static int av_unused get_cabac_bypass(CABACContext *c){ -#if 0 //not faster - int bit; - __asm__ volatile( - "movl "RANGE "(%1), %%ebx \n\t" - "movl "LOW "(%1), %%eax \n\t" - "shl $17, %%ebx \n\t" - "add %%eax, %%eax \n\t" - "sub %%ebx, %%eax \n\t" - "cltd \n\t" - "and %%edx, %%ebx \n\t" - "add %%ebx, %%eax \n\t" - "test %%ax, %%ax \n\t" - " jnz 1f \n\t" - "movl "BYTE "(%1), %%"REG_b" \n\t" - "subl $0xFFFF, %%eax \n\t" - "movzwl (%%"REG_b"), %%ecx \n\t" - "bswap %%ecx \n\t" - "shrl $15, %%ecx \n\t" - "addl $2, %%"REG_b" \n\t" - "addl %%ecx, %%eax \n\t" - "movl %%"REG_b", "BYTE "(%1) \n\t" - "1: \n\t" - "movl %%eax, "LOW "(%1) \n\t" - - :"=&d"(bit) - :"r"(c) - : "%eax", "%"REG_b, "%ecx", "memory" - ); - return bit+1; -#else - int range; - c->low += c->low; - - if(!(c->low & CABAC_MASK)) - refill(c); - - range= c->range<<(CABAC_BITS+1); - if(c->low < range){ - return 0; - }else{ - c->low -= range; - return 1; - } -#endif -} - - -static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ -#if ARCH_X86 && HAVE_EBX_AVAILABLE - __asm__ volatile( - "movl "RANGE "(%1), %%ebx \n\t" - "movl "LOW "(%1), %%eax \n\t" - "shl $17, %%ebx \n\t" - "add %%eax, %%eax \n\t" - "sub %%ebx, %%eax \n\t" - "cltd \n\t" - "and %%edx, %%ebx \n\t" - "add %%ebx, %%eax \n\t" - "xor %%edx, %%ecx \n\t" - "sub %%edx, %%ecx \n\t" - "test %%ax, %%ax \n\t" - " jnz 1f \n\t" - "mov "BYTE "(%1), %%"REG_b" \n\t" - "subl $0xFFFF, %%eax \n\t" - "movzwl (%%"REG_b"), %%edx \n\t" - "bswap %%edx \n\t" - "shrl $15, %%edx \n\t" - "add $2, %%"REG_b" \n\t" - "addl %%edx, %%eax \n\t" - "mov %%"REG_b", "BYTE "(%1) \n\t" - "1: \n\t" - "movl %%eax, "LOW "(%1) \n\t" - - :"+c"(val) - :"r"(c) - : "%eax", "%"REG_b, "%edx", "memory" - ); - return val; -#else - int range, mask; - c->low += c->low; - - if(!(c->low & CABAC_MASK)) - refill(c); - - range= c->range<<(CABAC_BITS+1); - c->low -= range; - mask= c->low >> 31; - range &= mask; - c->low += range; - return (val^mask)-mask; -#endif -} - -/** - * - * @return the number of bytes read or 0 if no end - */ -static int av_unused get_cabac_terminate(CABACContext *c){ - c->range -= 2; - if(c->low < c->range<<(CABAC_BITS+1)){ - renorm_cabac_decoder_once(c); - return 0; - }else{ - return c->bytestream - c->bytestream_start; - } -} - -#if 0 -/** - * Get (truncated) unary binarization. - */ -static 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; -} -#endif /* 0 */ - -#endif /* AVCODEC_CABAC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/cavs.c b/tizen/distrib/ffmpeg/libavcodec/cavs.c deleted file mode 100644 index ff6c869..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cavs.c +++ /dev/null @@ -1,715 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder - * @author Stefan Gehrer - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "golomb.h" -#include "mathops.h" -#include "cavs.h" -#include "cavsdata.h" - -/***************************************************************************** - * - * in-loop deblocking filter - * - ****************************************************************************/ - -static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b) { - if((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA)) - return 2; - if( (abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4) ) - return 1; - if(b){ - mvP += MV_BWD_OFFS; - mvQ += MV_BWD_OFFS; - if( (abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4) ) - return 1; - }else{ - if(mvP->ref != mvQ->ref) - return 1; - } - return 0; -} - -#define SET_PARAMS \ - alpha = alpha_tab[av_clip(qp_avg + h->alpha_offset,0,63)]; \ - beta = beta_tab[av_clip(qp_avg + h->beta_offset, 0,63)]; \ - tc = tc_tab[av_clip(qp_avg + h->alpha_offset,0,63)]; - -/** - * in-loop deblocking filter for a single macroblock - * - * boundary strength (bs) mapping: - * - * --4---5-- - * 0 2 | - * | 6 | 7 | - * 1 3 | - * --------- - * - */ -void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type) { - uint8_t bs[8]; - int qp_avg, alpha, beta, tc; - int i; - - /* save un-deblocked lines */ - h->topleft_border_y = h->top_border_y[h->mbx*16+15]; - h->topleft_border_u = h->top_border_u[h->mbx*10+8]; - h->topleft_border_v = h->top_border_v[h->mbx*10+8]; - memcpy(&h->top_border_y[h->mbx*16], h->cy + 15* h->l_stride,16); - memcpy(&h->top_border_u[h->mbx*10+1], h->cu + 7* h->c_stride,8); - memcpy(&h->top_border_v[h->mbx*10+1], h->cv + 7* h->c_stride,8); - for(i=0;i<8;i++) { - h->left_border_y[i*2+1] = *(h->cy + 15 + (i*2+0)*h->l_stride); - h->left_border_y[i*2+2] = *(h->cy + 15 + (i*2+1)*h->l_stride); - h->left_border_u[i+1] = *(h->cu + 7 + i*h->c_stride); - h->left_border_v[i+1] = *(h->cv + 7 + i*h->c_stride); - } - if(!h->loop_filter_disable) { - /* determine bs */ - if(mb_type == I_8X8) - memset(bs,2,8); - else{ - memset(bs,0,8); - if(ff_cavs_partition_flags[mb_type] & SPLITV){ - bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8); - bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8); - } - if(ff_cavs_partition_flags[mb_type] & SPLITH){ - bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8); - bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8); - } - bs[0] = get_bs(&h->mv[MV_FWD_A1], &h->mv[MV_FWD_X0], mb_type > P_8X8); - bs[1] = get_bs(&h->mv[MV_FWD_A3], &h->mv[MV_FWD_X2], mb_type > P_8X8); - bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8); - bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8); - } - if(AV_RN64(bs)) { - if(h->flags & A_AVAIL) { - qp_avg = (h->qp + h->left_qp + 1) >> 1; - SET_PARAMS; - h->s.dsp.cavs_filter_lv(h->cy,h->l_stride,alpha,beta,tc,bs[0],bs[1]); - h->s.dsp.cavs_filter_cv(h->cu,h->c_stride,alpha,beta,tc,bs[0],bs[1]); - h->s.dsp.cavs_filter_cv(h->cv,h->c_stride,alpha,beta,tc,bs[0],bs[1]); - } - qp_avg = h->qp; - SET_PARAMS; - h->s.dsp.cavs_filter_lv(h->cy + 8,h->l_stride,alpha,beta,tc,bs[2],bs[3]); - h->s.dsp.cavs_filter_lh(h->cy + 8*h->l_stride,h->l_stride,alpha,beta,tc, - bs[6],bs[7]); - - if(h->flags & B_AVAIL) { - qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1; - SET_PARAMS; - h->s.dsp.cavs_filter_lh(h->cy,h->l_stride,alpha,beta,tc,bs[4],bs[5]); - h->s.dsp.cavs_filter_ch(h->cu,h->c_stride,alpha,beta,tc,bs[4],bs[5]); - h->s.dsp.cavs_filter_ch(h->cv,h->c_stride,alpha,beta,tc,bs[4],bs[5]); - } - } - } - h->left_qp = h->qp; - h->top_qp[h->mbx] = h->qp; -} - -#undef SET_PARAMS - -/***************************************************************************** - * - * spatial intra prediction - * - ****************************************************************************/ - -void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top, - uint8_t **left, int block) { - int i; - - switch(block) { - case 0: - *left = h->left_border_y; - h->left_border_y[0] = h->left_border_y[1]; - memset(&h->left_border_y[17],h->left_border_y[16],9); - memcpy(&top[1],&h->top_border_y[h->mbx*16],16); - top[17] = top[16]; - top[0] = top[1]; - if((h->flags & A_AVAIL) && (h->flags & B_AVAIL)) - h->left_border_y[0] = top[0] = h->topleft_border_y; - break; - case 1: - *left = h->intern_border_y; - for(i=0;i<8;i++) - h->intern_border_y[i+1] = *(h->cy + 7 + i*h->l_stride); - memset(&h->intern_border_y[9],h->intern_border_y[8],9); - h->intern_border_y[0] = h->intern_border_y[1]; - memcpy(&top[1],&h->top_border_y[h->mbx*16+8],8); - if(h->flags & C_AVAIL) - memcpy(&top[9],&h->top_border_y[(h->mbx + 1)*16],8); - else - memset(&top[9],top[8],9); - top[17] = top[16]; - top[0] = top[1]; - if(h->flags & B_AVAIL) - h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx*16+7]; - break; - case 2: - *left = &h->left_border_y[8]; - memcpy(&top[1],h->cy + 7*h->l_stride,16); - top[17] = top[16]; - top[0] = top[1]; - if(h->flags & A_AVAIL) - top[0] = h->left_border_y[8]; - break; - case 3: - *left = &h->intern_border_y[8]; - for(i=0;i<8;i++) - h->intern_border_y[i+9] = *(h->cy + 7 + (i+8)*h->l_stride); - memset(&h->intern_border_y[17],h->intern_border_y[16],9); - memcpy(&top[0],h->cy + 7 + 7*h->l_stride,9); - memset(&top[9],top[8],9); - break; - } -} - -void ff_cavs_load_intra_pred_chroma(AVSContext *h) { - /* extend borders by one pixel */ - h->left_border_u[9] = h->left_border_u[8]; - h->left_border_v[9] = h->left_border_v[8]; - h->top_border_u[h->mbx*10+9] = h->top_border_u[h->mbx*10+8]; - h->top_border_v[h->mbx*10+9] = h->top_border_v[h->mbx*10+8]; - if(h->mbx && h->mby) { - h->top_border_u[h->mbx*10] = h->left_border_u[0] = h->topleft_border_u; - h->top_border_v[h->mbx*10] = h->left_border_v[0] = h->topleft_border_v; - } else { - h->left_border_u[0] = h->left_border_u[1]; - h->left_border_v[0] = h->left_border_v[1]; - h->top_border_u[h->mbx*10] = h->top_border_u[h->mbx*10+1]; - h->top_border_v[h->mbx*10] = h->top_border_v[h->mbx*10+1]; - } -} - -static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int y; - uint64_t a = AV_RN64(&top[1]); - for(y=0;y<8;y++) { - *((uint64_t *)(d+y*stride)) = a; - } -} - -static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int y; - uint64_t a; - for(y=0;y<8;y++) { - a = left[y+1] * 0x0101010101010101ULL; - *((uint64_t *)(d+y*stride)) = a; - } -} - -static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int y; - uint64_t a = 0x8080808080808080ULL; - for(y=0;y<8;y++) - *((uint64_t *)(d+y*stride)) = a; -} - -static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y,ia; - int ih = 0; - int iv = 0; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - for(x=0; x<4; x++) { - ih += (x+1)*(top[5+x]-top[3-x]); - iv += (x+1)*(left[5+x]-left[3-x]); - } - ia = (top[8]+left[8])<<4; - ih = (17*ih+16)>>5; - iv = (17*iv+16)>>5; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = cm[(ia+(x-3)*ih+(y-3)*iv+16)>>5]; -} - -#define LOWPASS(ARRAY,INDEX) \ - (( ARRAY[(INDEX)-1] + 2*ARRAY[(INDEX)] + ARRAY[(INDEX)+1] + 2) >> 2) - -static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = (LOWPASS(top,x+1) + LOWPASS(left,y+1)) >> 1; -} - -static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = (LOWPASS(top,x+y+2) + LOWPASS(left,x+y+2)) >> 1; -} - -static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - if(x==y) - d[y*stride+x] = (left[1]+2*top[0]+top[1]+2)>>2; - else if(x>y) - d[y*stride+x] = LOWPASS(top,x-y); - else - d[y*stride+x] = LOWPASS(left,y-x); -} - -static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = LOWPASS(left,y+1); -} - -static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = LOWPASS(top,x+1); -} - -#undef LOWPASS - -void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) { - /* save pred modes before they get modified */ - h->pred_mode_Y[3] = h->pred_mode_Y[5]; - h->pred_mode_Y[6] = h->pred_mode_Y[8]; - h->top_pred_Y[h->mbx*2+0] = h->pred_mode_Y[7]; - h->top_pred_Y[h->mbx*2+1] = h->pred_mode_Y[8]; - - /* modify pred modes according to availability of neighbour samples */ - if(!(h->flags & A_AVAIL)) { - modify_pred(ff_left_modifier_l, &h->pred_mode_Y[4] ); - modify_pred(ff_left_modifier_l, &h->pred_mode_Y[7] ); - modify_pred(ff_left_modifier_c, pred_mode_uv ); - } - if(!(h->flags & B_AVAIL)) { - modify_pred(ff_top_modifier_l, &h->pred_mode_Y[4] ); - modify_pred(ff_top_modifier_l, &h->pred_mode_Y[5] ); - modify_pred(ff_top_modifier_c, pred_mode_uv ); - } -} - -/***************************************************************************** - * - * motion compensation - * - ****************************************************************************/ - -static inline void mc_dir_part(AVSContext *h,Picture *pic,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,cavs_vector *mv){ - MpegEncContext * const s = &h->s; - const int mx= mv->x + src_x_offset*8; - const int my= mv->y + src_y_offset*8; - const int luma_xy= (mx&3) + ((my&3)<<2); - uint8_t * src_y = pic->data[0] + (mx>>2) + (my>>2)*h->l_stride; - uint8_t * src_cb= pic->data[1] + (mx>>3) + (my>>3)*h->c_stride; - uint8_t * src_cr= pic->data[2] + (mx>>3) + (my>>3)*h->c_stride; - int extra_width= 0; //(s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; - 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*h->mb_width; - const int pic_height = 16*h->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*h->l_stride, h->l_stride, - 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height); - src_y= s->edge_emu_buffer + 2 + 2*h->l_stride; - emu=1; - } - - qpix_op[luma_xy](dest_y, src_y, h->l_stride); //FIXME try variable height perhaps? - if(!square){ - qpix_op[luma_xy](dest_y + delta, src_y + delta, h->l_stride); - } - - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, h->c_stride, - 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, h->c_stride, chroma_height, mx&7, my&7); - - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, h->c_stride, - 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, h->c_stride, chroma_height, mx&7, my&7); -} - -static inline void mc_part_std(AVSContext *h,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, cavs_vector *mv){ - qpel_mc_func *qpix_op= qpix_put; - h264_chroma_mc_func chroma_op= chroma_put; - - dest_y += 2*x_offset + 2*y_offset*h->l_stride; - dest_cb += x_offset + y_offset*h->c_stride; - dest_cr += x_offset + y_offset*h->c_stride; - x_offset += 8*h->mbx; - y_offset += 8*h->mby; - - if(mv->ref >= 0){ - Picture *ref= &h->DPB[mv->ref]; - mc_dir_part(h, ref, square, chroma_height, delta, 0, - dest_y, dest_cb, dest_cr, x_offset, y_offset, - qpix_op, chroma_op, mv); - - qpix_op= qpix_avg; - chroma_op= chroma_avg; - } - - if((mv+MV_BWD_OFFS)->ref >= 0){ - Picture *ref= &h->DPB[0]; - mc_dir_part(h, ref, square, chroma_height, delta, 1, - dest_y, dest_cb, dest_cr, x_offset, y_offset, - qpix_op, chroma_op, mv+MV_BWD_OFFS); - } -} - -void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) { - if(ff_cavs_partition_flags[mb_type] == 0){ // 16x16 - mc_part_std(h, 1, 8, 0, h->cy, h->cu, h->cv, 0, 0, - h->s.dsp.put_cavs_qpel_pixels_tab[0], - h->s.dsp.put_h264_chroma_pixels_tab[0], - h->s.dsp.avg_cavs_qpel_pixels_tab[0], - h->s.dsp.avg_h264_chroma_pixels_tab[0],&h->mv[MV_FWD_X0]); - }else{ - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 0, 0, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X0]); - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 4, 0, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X1]); - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 0, 4, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X2]); - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 4, 4, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X3]); - } -} - -/***************************************************************************** - * - * motion vector prediction - * - ****************************************************************************/ - -static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, cavs_vector *src, int distp) { - int den = h->scale_den[src->ref]; - - *d_x = (src->x*distp*den + 256 + (src->x>>31)) >> 9; - *d_y = (src->y*distp*den + 256 + (src->y>>31)) >> 9; -} - -static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP, - cavs_vector *mvA, cavs_vector *mvB, cavs_vector *mvC) { - int ax, ay, bx, by, cx, cy; - int len_ab, len_bc, len_ca, len_mid; - - /* scale candidates according to their temporal span */ - scale_mv(h, &ax, &ay, mvA, mvP->dist); - scale_mv(h, &bx, &by, mvB, mvP->dist); - scale_mv(h, &cx, &cy, mvC, mvP->dist); - /* find the geometrical median of the three candidates */ - len_ab = abs(ax - bx) + abs(ay - by); - len_bc = abs(bx - cx) + abs(by - cy); - len_ca = abs(cx - ax) + abs(cy - ay); - len_mid = mid_pred(len_ab, len_bc, len_ca); - if(len_mid == len_ab) { - mvP->x = cx; - mvP->y = cy; - } else if(len_mid == len_bc) { - mvP->x = ax; - mvP->y = ay; - } else { - mvP->x = bx; - mvP->y = by; - } -} - -void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC, - enum cavs_mv_pred mode, enum cavs_block size, int ref) { - cavs_vector *mvP = &h->mv[nP]; - cavs_vector *mvA = &h->mv[nP-1]; - cavs_vector *mvB = &h->mv[nP-4]; - cavs_vector *mvC = &h->mv[nC]; - const cavs_vector *mvP2 = NULL; - - mvP->ref = ref; - mvP->dist = h->dist[mvP->ref]; - if(mvC->ref == NOT_AVAIL) - mvC = &h->mv[nP-5]; // set to top-left (mvD) - if((mode == MV_PRED_PSKIP) && - ((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) || - ((mvA->x | mvA->y | mvA->ref) == 0) || - ((mvB->x | mvB->y | mvB->ref) == 0) )) { - mvP2 = &ff_cavs_un_mv; - /* if there is only one suitable candidate, take it */ - } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) { - mvP2= mvA; - } else if((mvA->ref < 0) && (mvB->ref >= 0) && (mvC->ref < 0)) { - mvP2= mvB; - } else if((mvA->ref < 0) && (mvB->ref < 0) && (mvC->ref >= 0)) { - mvP2= mvC; - } else if(mode == MV_PRED_LEFT && mvA->ref == ref){ - mvP2= mvA; - } else if(mode == MV_PRED_TOP && mvB->ref == ref){ - mvP2= mvB; - } else if(mode == MV_PRED_TOPRIGHT && mvC->ref == ref){ - mvP2= mvC; - } - if(mvP2){ - mvP->x = mvP2->x; - mvP->y = mvP2->y; - }else - mv_pred_median(h, mvP, mvA, mvB, mvC); - - if(mode < MV_PRED_PSKIP) { - mvP->x += get_se_golomb(&h->s.gb); - mvP->y += get_se_golomb(&h->s.gb); - } - set_mvs(mvP,size); -} - -/***************************************************************************** - * - * macroblock level - * - ****************************************************************************/ - -/** - * initialise predictors for motion vectors and intra prediction - */ -void ff_cavs_init_mb(AVSContext *h) { - int i; - - /* copy predictors from top line (MB B and C) into cache */ - for(i=0;i<3;i++) { - h->mv[MV_FWD_B2+i] = h->top_mv[0][h->mbx*2+i]; - h->mv[MV_BWD_B2+i] = h->top_mv[1][h->mbx*2+i]; - } - h->pred_mode_Y[1] = h->top_pred_Y[h->mbx*2+0]; - h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1]; - /* clear top predictors if MB B is not available */ - if(!(h->flags & B_AVAIL)) { - h->mv[MV_FWD_B2] = ff_cavs_un_mv; - h->mv[MV_FWD_B3] = ff_cavs_un_mv; - h->mv[MV_BWD_B2] = ff_cavs_un_mv; - h->mv[MV_BWD_B3] = ff_cavs_un_mv; - h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL; - h->flags &= ~(C_AVAIL|D_AVAIL); - } else if(h->mbx) { - h->flags |= D_AVAIL; - } - if(h->mbx == h->mb_width-1) //MB C not available - h->flags &= ~C_AVAIL; - /* clear top-right predictors if MB C is not available */ - if(!(h->flags & C_AVAIL)) { - h->mv[MV_FWD_C2] = ff_cavs_un_mv; - h->mv[MV_BWD_C2] = ff_cavs_un_mv; - } - /* clear top-left predictors if MB D is not available */ - if(!(h->flags & D_AVAIL)) { - h->mv[MV_FWD_D3] = ff_cavs_un_mv; - h->mv[MV_BWD_D3] = ff_cavs_un_mv; - } -} - -/** - * save predictors for later macroblocks and increase - * macroblock address - * @return 0 if end of frame is reached, 1 otherwise - */ -int ff_cavs_next_mb(AVSContext *h) { - int i; - - h->flags |= A_AVAIL; - h->cy += 16; - h->cu += 8; - h->cv += 8; - /* copy mvs as predictors to the left */ - for(i=0;i<=20;i+=4) - h->mv[i] = h->mv[i+2]; - /* copy bottom mvs from cache to top line */ - h->top_mv[0][h->mbx*2+0] = h->mv[MV_FWD_X2]; - h->top_mv[0][h->mbx*2+1] = h->mv[MV_FWD_X3]; - h->top_mv[1][h->mbx*2+0] = h->mv[MV_BWD_X2]; - h->top_mv[1][h->mbx*2+1] = h->mv[MV_BWD_X3]; - /* next MB address */ - h->mbidx++; - h->mbx++; - if(h->mbx == h->mb_width) { //new mb line - h->flags = B_AVAIL|C_AVAIL; - /* clear left pred_modes */ - h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL; - /* clear left mv predictors */ - for(i=0;i<=20;i+=4) - h->mv[i] = ff_cavs_un_mv; - h->mbx = 0; - h->mby++; - /* re-calculate sample pointers */ - h->cy = h->picture.data[0] + h->mby*16*h->l_stride; - h->cu = h->picture.data[1] + h->mby*8*h->c_stride; - h->cv = h->picture.data[2] + h->mby*8*h->c_stride; - if(h->mby == h->mb_height) { //frame end - return 0; - } - } - return 1; -} - -/***************************************************************************** - * - * frame level - * - ****************************************************************************/ - -void ff_cavs_init_pic(AVSContext *h) { - int i; - - /* clear some predictors */ - for(i=0;i<=20;i+=4) - h->mv[i] = ff_cavs_un_mv; - h->mv[MV_BWD_X0] = ff_cavs_dir_mv; - set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); - h->mv[MV_FWD_X0] = ff_cavs_dir_mv; - set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); - h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL; - h->cy = h->picture.data[0]; - h->cu = h->picture.data[1]; - h->cv = h->picture.data[2]; - h->l_stride = h->picture.linesize[0]; - h->c_stride = h->picture.linesize[1]; - h->luma_scan[2] = 8*h->l_stride; - h->luma_scan[3] = 8*h->l_stride+8; - h->mbx = h->mby = h->mbidx = 0; - h->flags = 0; -} - -/***************************************************************************** - * - * headers and interface - * - ****************************************************************************/ - -/** - * some predictions require data from the top-neighbouring macroblock. - * this data has to be stored for one complete row of macroblocks - * and this storage space is allocated here - */ -void ff_cavs_init_top_lines(AVSContext *h) { - /* alloc top line of predictors */ - h->top_qp = av_malloc( h->mb_width); - h->top_mv[0] = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector)); - h->top_mv[1] = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector)); - h->top_pred_Y = av_malloc( h->mb_width*2*sizeof(*h->top_pred_Y)); - h->top_border_y = av_malloc((h->mb_width+1)*16); - h->top_border_u = av_malloc((h->mb_width)*10); - h->top_border_v = av_malloc((h->mb_width)*10); - - /* alloc space for co-located MVs and types */ - h->col_mv = av_malloc( h->mb_width*h->mb_height*4*sizeof(cavs_vector)); - h->col_type_base = av_malloc(h->mb_width*h->mb_height); - h->block = av_mallocz(64*sizeof(DCTELEM)); -} - -av_cold int ff_cavs_init(AVCodecContext *avctx) { - AVSContext *h = avctx->priv_data; - MpegEncContext * const s = &h->s; - - MPV_decode_defaults(s); - s->avctx = avctx; - - avctx->pix_fmt= PIX_FMT_YUV420P; - - h->luma_scan[0] = 0; - h->luma_scan[1] = 8; - h->intra_pred_l[ INTRA_L_VERT] = intra_pred_vert; - h->intra_pred_l[ INTRA_L_HORIZ] = intra_pred_horiz; - h->intra_pred_l[ INTRA_L_LP] = intra_pred_lp; - h->intra_pred_l[ INTRA_L_DOWN_LEFT] = intra_pred_down_left; - h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right; - h->intra_pred_l[ INTRA_L_LP_LEFT] = intra_pred_lp_left; - h->intra_pred_l[ INTRA_L_LP_TOP] = intra_pred_lp_top; - h->intra_pred_l[ INTRA_L_DC_128] = intra_pred_dc_128; - h->intra_pred_c[ INTRA_C_LP] = intra_pred_lp; - h->intra_pred_c[ INTRA_C_HORIZ] = intra_pred_horiz; - h->intra_pred_c[ INTRA_C_VERT] = intra_pred_vert; - h->intra_pred_c[ INTRA_C_PLANE] = intra_pred_plane; - h->intra_pred_c[ INTRA_C_LP_LEFT] = intra_pred_lp_left; - h->intra_pred_c[ INTRA_C_LP_TOP] = intra_pred_lp_top; - h->intra_pred_c[ INTRA_C_DC_128] = intra_pred_dc_128; - h->mv[ 7] = ff_cavs_un_mv; - h->mv[19] = ff_cavs_un_mv; - return 0; -} - -av_cold int ff_cavs_end(AVCodecContext *avctx) { - AVSContext *h = avctx->priv_data; - - av_free(h->top_qp); - av_free(h->top_mv[0]); - av_free(h->top_mv[1]); - av_free(h->top_pred_Y); - av_free(h->top_border_y); - av_free(h->top_border_u); - av_free(h->top_border_v); - av_free(h->col_mv); - av_free(h->col_type_base); - av_free(h->block); - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/cavs.h b/tizen/distrib/ffmpeg/libavcodec/cavs.h deleted file mode 100644 index 729c83e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cavs.h +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CAVS_H -#define AVCODEC_CAVS_H - -#include "dsputil.h" -#include "mpegvideo.h" - -#define SLICE_MAX_START_CODE 0x000001af -#define EXT_START_CODE 0x000001b5 -#define USER_START_CODE 0x000001b2 -#define CAVS_START_CODE 0x000001b0 -#define PIC_I_START_CODE 0x000001b3 -#define PIC_PB_START_CODE 0x000001b6 - -#define A_AVAIL 1 -#define B_AVAIL 2 -#define C_AVAIL 4 -#define D_AVAIL 8 -#define NOT_AVAIL -1 -#define REF_INTRA -2 -#define REF_DIR -3 - -#define ESCAPE_CODE 59 - -#define FWD0 0x01 -#define FWD1 0x02 -#define BWD0 0x04 -#define BWD1 0x08 -#define SYM0 0x10 -#define SYM1 0x20 -#define SPLITH 0x40 -#define SPLITV 0x80 - -#define MV_BWD_OFFS 12 -#define MV_STRIDE 4 - -enum cavs_mb { - I_8X8 = 0, - P_SKIP, - P_16X16, - P_16X8, - P_8X16, - P_8X8, - B_SKIP, - B_DIRECT, - B_FWD_16X16, - B_BWD_16X16, - B_SYM_16X16, - B_8X8 = 29 -}; - -enum cavs_sub_mb { - B_SUB_DIRECT, - B_SUB_FWD, - B_SUB_BWD, - B_SUB_SYM -}; - -enum cavs_intra_luma { - INTRA_L_VERT, - INTRA_L_HORIZ, - INTRA_L_LP, - INTRA_L_DOWN_LEFT, - INTRA_L_DOWN_RIGHT, - INTRA_L_LP_LEFT, - INTRA_L_LP_TOP, - INTRA_L_DC_128 -}; - -enum cavs_intra_chroma { - INTRA_C_LP, - INTRA_C_HORIZ, - INTRA_C_VERT, - INTRA_C_PLANE, - INTRA_C_LP_LEFT, - INTRA_C_LP_TOP, - INTRA_C_DC_128, -}; - -enum cavs_mv_pred { - MV_PRED_MEDIAN, - MV_PRED_LEFT, - MV_PRED_TOP, - MV_PRED_TOPRIGHT, - MV_PRED_PSKIP, - MV_PRED_BSKIP -}; - -enum cavs_block { - BLK_16X16, - BLK_16X8, - BLK_8X16, - BLK_8X8 -}; - -enum cavs_mv_loc { - MV_FWD_D3 = 0, - MV_FWD_B2, - MV_FWD_B3, - MV_FWD_C2, - MV_FWD_A1, - MV_FWD_X0, - MV_FWD_X1, - MV_FWD_A3 = 8, - MV_FWD_X2, - MV_FWD_X3, - MV_BWD_D3 = MV_BWD_OFFS, - MV_BWD_B2, - MV_BWD_B3, - MV_BWD_C2, - MV_BWD_A1, - MV_BWD_X0, - MV_BWD_X1, - MV_BWD_A3 = MV_BWD_OFFS+8, - MV_BWD_X2, - MV_BWD_X3 -}; - -DECLARE_ALIGNED(8, typedef, struct) { - int16_t x; - int16_t y; - int16_t dist; - int16_t ref; -} cavs_vector; - -struct dec_2dvlc { - int8_t rltab[59][3]; - int8_t level_add[27]; - int8_t golomb_order; - int inc_limit; - int8_t max_run; -}; - -typedef struct { - MpegEncContext s; - Picture picture; ///< currently decoded frame - Picture DPB[2]; ///< reference frames - int dist[2]; ///< temporal distances from current frame to ref frames - int profile, level; - int aspect_ratio; - int mb_width, mb_height; - int pic_type; - int stream_revision; ///<0 for samples from 2006, 1 for rm52j encoder - int progressive; - int pic_structure; - int skip_mode_flag; ///< select between skip_count or one skip_flag per MB - int loop_filter_disable; - int alpha_offset, beta_offset; - int ref_flag; - int mbx, mby, mbidx; ///< macroblock coordinates - int flags; ///< availability flags of neighbouring macroblocks - int stc; ///< last start code - uint8_t *cy, *cu, *cv; ///< current MB sample pointers - int left_qp; - uint8_t *top_qp; - - /** mv motion vector cache - 0: D3 B2 B3 C2 - 4: A1 X0 X1 - - 8: A3 X2 X3 - - - X are the vectors in the current macroblock (5,6,9,10) - A is the macroblock to the left (4,8) - B is the macroblock to the top (1,2) - C is the macroblock to the top-right (3) - D is the macroblock to the top-left (0) - - the same is repeated for backward motion vectors */ - cavs_vector mv[2*4*3]; - cavs_vector *top_mv[2]; - cavs_vector *col_mv; - - /** luma pred mode cache - 0: -- B2 B3 - 3: A1 X0 X1 - 6: A3 X2 X3 */ - int pred_mode_Y[3*3]; - int *top_pred_Y; - int l_stride, c_stride; - int luma_scan[4]; - int qp; - int qp_fixed; - int cbp; - ScanTable scantable; - - /** intra prediction is done with un-deblocked samples - they are saved here before deblocking the MB */ - uint8_t *top_border_y, *top_border_u, *top_border_v; - uint8_t left_border_y[26], left_border_u[10], left_border_v[10]; - uint8_t intern_border_y[26]; - uint8_t topleft_border_y, topleft_border_u, topleft_border_v; - - void (*intra_pred_l[8])(uint8_t *d,uint8_t *top,uint8_t *left,int stride); - void (*intra_pred_c[7])(uint8_t *d,uint8_t *top,uint8_t *left,int stride); - uint8_t *col_type_base; - - /* scaling factors for MV prediction */ - int sym_factor; ///< for scaling in symmetrical B block - int direct_den[2]; ///< for scaling in direct B block - int scale_den[2]; ///< for scaling neighbouring MVs - - int got_keyframe; - DCTELEM *block; -} AVSContext; - -extern const uint8_t ff_cavs_dequant_shift[64]; -extern const uint16_t ff_cavs_dequant_mul[64]; -extern const struct dec_2dvlc ff_cavs_intra_dec[7]; -extern const struct dec_2dvlc ff_cavs_inter_dec[7]; -extern const struct dec_2dvlc ff_cavs_chroma_dec[5]; -extern const uint8_t ff_cavs_chroma_qp[64]; -extern const uint8_t ff_cavs_scan3x3[4]; -extern const uint8_t ff_cavs_partition_flags[30]; -extern const int_fast8_t ff_left_modifier_l[8]; -extern const int_fast8_t ff_top_modifier_l[8]; -extern const int_fast8_t ff_left_modifier_c[7]; -extern const int_fast8_t ff_top_modifier_c[7]; -extern const cavs_vector ff_cavs_intra_mv; -extern const cavs_vector ff_cavs_un_mv; -extern const cavs_vector ff_cavs_dir_mv; - -static inline void modify_pred(const int_fast8_t *mod_table, int *mode) { - *mode = mod_table[*mode]; - if(*mode < 0) { - av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n"); - *mode = 0; - } -} - -static inline void set_intra_mode_default(AVSContext *h) { - if(h->stream_revision > 0) { - h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL; - h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = NOT_AVAIL; - } else { - h->pred_mode_Y[3] = h->pred_mode_Y[6] = INTRA_L_LP; - h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = INTRA_L_LP; - } -} - -static inline void set_mvs(cavs_vector *mv, enum cavs_block size) { - switch(size) { - case BLK_16X16: - mv[MV_STRIDE ] = mv[0]; - mv[MV_STRIDE+1] = mv[0]; - case BLK_16X8: - mv[1] = mv[0]; - break; - case BLK_8X16: - mv[MV_STRIDE] = mv[0]; - break; - } -} - -static inline void set_mv_intra(AVSContext *h) { - h->mv[MV_FWD_X0] = ff_cavs_intra_mv; - set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); - h->mv[MV_BWD_X0] = ff_cavs_intra_mv; - set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); - if(h->pic_type != FF_B_TYPE) - h->col_type_base[h->mbidx] = I_8X8; -} - -static inline int dequant(AVSContext *h, DCTELEM *level_buf, uint8_t *run_buf, - DCTELEM *dst, int mul, int shift, int coeff_num) { - int round = 1 << (shift - 1); - int pos = -1; - const uint8_t *scantab = h->scantable.permutated; - - /* inverse scan and dequantization */ - while(--coeff_num >= 0){ - pos += run_buf[coeff_num]; - if(pos > 63) { - av_log(h->s.avctx, AV_LOG_ERROR, - "position out of block bounds at pic %d MB(%d,%d)\n", - h->picture.poc, h->mbx, h->mby); - return -1; - } - dst[scantab[pos]] = (level_buf[coeff_num]*mul + round) >> shift; - } - return 0; -} - -void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type); -void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top, uint8_t **left, - int block); -void ff_cavs_load_intra_pred_chroma(AVSContext *h); -void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv); -void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type); -void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC, - enum cavs_mv_pred mode, enum cavs_block size, int ref); -void ff_cavs_init_mb(AVSContext *h); -int ff_cavs_next_mb(AVSContext *h); -void ff_cavs_init_pic(AVSContext *h); -void ff_cavs_init_top_lines(AVSContext *h); -int ff_cavs_init(AVCodecContext *avctx); -int ff_cavs_end (AVCodecContext *avctx); - -#endif /* AVCODEC_CAVS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/cavs_parser.c b/tizen/distrib/ffmpeg/libavcodec/cavs_parser.c deleted file mode 100644 index 8e9c35b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cavs_parser.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) parser. - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Chinese AVS video (AVS1-P2, JiZhun profile) parser - * @author Stefan Gehrer - */ - -#include "parser.h" -#include "cavs.h" - - -/** - * 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 cavs_find_frame_end(ParseContext *pc, const uint8_t *buf, - int buf_size) { - int pic_found, i; - uint32_t state; - - pic_found= pc->frame_start_found; - state= pc->state; - - i=0; - if(!pic_found){ - for(i=0; i SLICE_MAX_START_CODE){ - pc->frame_start_found=0; - pc->state=-1; - return i-3; - } - } - } - } - pc->frame_start_found= pic_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int cavsvideo_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= cavs_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser cavsvideo_parser = { - { CODEC_ID_CAVS }, - sizeof(ParseContext1), - NULL, - cavsvideo_parse, - ff_parse1_close, - ff_mpeg4video_split, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/cavsdata.h b/tizen/distrib/ffmpeg/libavcodec/cavsdata.h deleted file mode 100644 index b597da1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cavsdata.h +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CAVSDATA_H -#define AVCODEC_CAVSDATA_H - -#include "cavs.h" - -const uint8_t ff_cavs_partition_flags[30] = { - 0, //I_8X8 - 0, //P_SKIP - 0, //P_16X16 - SPLITH, //P_16X8 - SPLITV, //P_8X16 - SPLITH|SPLITV, //P_8X8 - SPLITH|SPLITV, //B_SKIP - SPLITH|SPLITV, //B_DIRECT - 0, //B_FWD_16X16 - 0, //B_BWD_16X16 - 0, //B_SYM_16X16 - FWD0|FWD1 |SPLITH, - FWD0|FWD1 |SPLITV, - BWD0|BWD1 |SPLITH, - BWD0|BWD1 |SPLITV, - FWD0|BWD1 |SPLITH, - FWD0|BWD1 |SPLITV, - BWD0|FWD1 |SPLITH, - BWD0|FWD1 |SPLITV, - FWD0|FWD1 |SYM1|SPLITH, - FWD0|FWD1 |SYM1 |SPLITV, - BWD0|FWD1 |SYM1|SPLITH, - BWD0|FWD1 |SYM1 |SPLITV, - FWD0|FWD1|SYM0 |SPLITH, - FWD0|FWD1|SYM0 |SPLITV, - FWD0|BWD1|SYM0 |SPLITH, - FWD0|BWD1|SYM0 |SPLITV, - FWD0|FWD1|SYM0|SYM1|SPLITH, - FWD0|FWD1|SYM0|SYM1 |SPLITV, - SPLITH|SPLITV, //B_8X8 = 29 -}; - -const uint8_t ff_cavs_scan3x3[4] = {4,5,7,8}; - -const uint8_t ff_cavs_chroma_qp[64] = { - 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,42,43,43,44,44, - 45,45,46,46,47,47,48,48,48,49,49,49,50,50,50,51 -}; - -const uint8_t ff_cavs_dequant_shift[64] = { - 14,14,14,14,14,14,14,14, - 13,13,13,13,13,13,13,13, - 13,12,12,12,12,12,12,12, - 11,11,11,11,11,11,11,11, - 11,10,10,10,10,10,10,10, - 10, 9, 9, 9, 9, 9, 9, 9, - 9, 8, 8, 8, 8, 8, 8, 8, - 7, 7, 7, 7, 7, 7, 7, 7 -}; - -const uint16_t ff_cavs_dequant_mul[64] = { - 32768,36061,38968,42495,46341,50535,55437,60424, - 32932,35734,38968,42495,46177,50535,55109,59933, - 65535,35734,38968,42577,46341,50617,55027,60097, - 32809,35734,38968,42454,46382,50576,55109,60056, - 65535,35734,38968,42495,46320,50515,55109,60076, - 65535,35744,38968,42495,46341,50535,55099,60087, - 65535,35734,38973,42500,46341,50535,55109,60097, - 32771,35734,38965,42497,46341,50535,55109,60099 -}; - -/** marks block as unavailable, i.e. out of picture - or not yet decoded */ -const cavs_vector ff_cavs_un_mv = {0,0,1,NOT_AVAIL}; - -/** marks block as "no prediction from this direction" - e.g. forward motion vector in BWD partition */ -const cavs_vector ff_cavs_dir_mv = {0,0,1,REF_DIR}; - -/** marks block as using intra prediction */ -const cavs_vector ff_cavs_intra_mv = {0,0,1,REF_INTRA}; - -#define EOB 0,0,0 - -const struct dec_2dvlc ff_cavs_intra_dec[7] = { - { - { //level / run / table_inc - { 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},{ 1, 3, 1},{ -1, 3, 1}, - { 1, 4, 1},{ -1, 4, 1},{ 1, 5, 1},{ -1, 5, 1},{ 1, 6, 1},{ -1, 6, 1}, - { 1, 7, 1},{ -1, 7, 1},{ 1, 8, 1},{ -1, 8, 1},{ 1, 9, 1},{ -1, 9, 1}, - { 1,10, 1},{ -1,10, 1},{ 1,11, 1},{ -1,11, 1},{ 2, 1, 2},{ -2, 1, 2}, - { 1,12, 1},{ -1,12, 1},{ 1,13, 1},{ -1,13, 1},{ 1,14, 1},{ -1,14, 1}, - { 1,15, 1},{ -1,15, 1},{ 2, 2, 2},{ -2, 2, 2},{ 1,16, 1},{ -1,16, 1}, - { 1,17, 1},{ -1,17, 1},{ 3, 1, 3},{ -3, 1, 3},{ 1,18, 1},{ -1,18, 1}, - { 1,19, 1},{ -1,19, 1},{ 2, 3, 2},{ -2, 3, 2},{ 1,20, 1},{ -1,20, 1}, - { 1,21, 1},{ -1,21, 1},{ 2, 4, 2},{ -2, 4, 2},{ 1,22, 1},{ -1,22, 1}, - { 2, 5, 2},{ -2, 5, 2},{ 1,23, 1},{ -1,23, 1},{ EOB } - }, - //level_add - { 0, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2,-1,-1,-1}, - 2, //golomb_order - 0, //inc_limit - 23, //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 2, 1, 1},{ -2, 1, 1}, - { 1, 3, 0},{ -1, 3, 0},{ EOB },{ 1, 4, 0},{ -1, 4, 0},{ 1, 5, 0}, - { -1, 5, 0},{ 1, 6, 0},{ -1, 6, 0},{ 3, 1, 2},{ -3, 1, 2},{ 2, 2, 1}, - { -2, 2, 1},{ 1, 7, 0},{ -1, 7, 0},{ 1, 8, 0},{ -1, 8, 0},{ 1, 9, 0}, - { -1, 9, 0},{ 2, 3, 1},{ -2, 3, 1},{ 4, 1, 2},{ -4, 1, 2},{ 1,10, 0}, - { -1,10, 0},{ 1,11, 0},{ -1,11, 0},{ 2, 4, 1},{ -2, 4, 1},{ 3, 2, 2}, - { -3, 2, 2},{ 1,12, 0},{ -1,12, 0},{ 2, 5, 1},{ -2, 5, 1},{ 5, 1, 3}, - { -5, 1, 3},{ 1,13, 0},{ -1,13, 0},{ 2, 6, 1},{ -2, 6, 1},{ 1,14, 0}, - { -1,14, 0},{ 2, 7, 1},{ -2, 7, 1},{ 2, 8, 1},{ -2, 8, 1},{ 3, 3, 2}, - { -3, 3, 2},{ 6, 1, 3},{ -6, 1, 3},{ 1,15, 0},{ -1,15, 0} - }, - //level_add - { 0, 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 1, //inc_limit - 15, //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 1, 2, 0},{ -1, 2, 0}, - { 3, 1, 1},{ -3, 1, 1},{ EOB },{ 1, 3, 0},{ -1, 3, 0},{ 2, 2, 0}, - { -2, 2, 0},{ 4, 1, 1},{ -4, 1, 1},{ 1, 4, 0},{ -1, 4, 0},{ 5, 1, 2}, - { -5, 1, 2},{ 1, 5, 0},{ -1, 5, 0},{ 3, 2, 1},{ -3, 2, 1},{ 2, 3, 0}, - { -2, 3, 0},{ 1, 6, 0},{ -1, 6, 0},{ 6, 1, 2},{ -6, 1, 2},{ 2, 4, 0}, - { -2, 4, 0},{ 1, 7, 0},{ -1, 7, 0},{ 4, 2, 1},{ -4, 2, 1},{ 7, 1, 2}, - { -7, 1, 2},{ 3, 3, 1},{ -3, 3, 1},{ 2, 5, 0},{ -2, 5, 0},{ 1, 8, 0}, - { -1, 8, 0},{ 2, 6, 0},{ -2, 6, 0},{ 8, 1, 3},{ -8, 1, 3},{ 1, 9, 0}, - { -1, 9, 0},{ 5, 2, 2},{ -5, 2, 2},{ 3, 4, 1},{ -3, 4, 1},{ 2, 7, 0}, - { -2, 7, 0},{ 9, 1, 3},{ -9, 1, 3},{ 1,10, 0},{ -1,10, 0} - }, - //level_add - { 0,10, 6, 4, 4, 3, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 2, //inc_limit - 10, //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0},{ -3, 1, 0}, - { 1, 2, 0},{ -1, 2, 0},{ EOB },{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 1}, - { -5, 1, 1},{ 2, 2, 0},{ -2, 2, 0},{ 1, 3, 0},{ -1, 3, 0},{ 6, 1, 1}, - { -6, 1, 1},{ 3, 2, 0},{ -3, 2, 0},{ 7, 1, 1},{ -7, 1, 1},{ 1, 4, 0}, - { -1, 4, 0},{ 8, 1, 2},{ -8, 1, 2},{ 2, 3, 0},{ -2, 3, 0},{ 4, 2, 0}, - { -4, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 9, 1, 2},{ -9, 1, 2},{ 5, 2, 1}, - { -5, 2, 1},{ 2, 4, 0},{ -2, 4, 0},{ 10, 1, 2},{-10, 1, 2},{ 3, 3, 0}, - { -3, 3, 0},{ 1, 6, 0},{ -1, 6, 0},{ 11, 1, 3},{-11, 1, 3},{ 6, 2, 1}, - { -6, 2, 1},{ 1, 7, 0},{ -1, 7, 0},{ 2, 5, 0},{ -2, 5, 0},{ 3, 4, 0}, - { -3, 4, 0},{ 12, 1, 3},{-12, 1, 3},{ 4, 3, 0},{ -4, 3, 0} - }, - //level_add - { 0,13, 7, 5, 4, 3, 2, 2,-1,-1,-1 -1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 4, //inc_limit - 7, //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0},{ -3, 1, 0}, - { EOB },{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 0},{ -5, 1, 0},{ 6, 1, 0}, - { -6, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 7, 1, 0},{ -7, 1, 0},{ 8, 1, 1}, - { -8, 1, 1},{ 2, 2, 0},{ -2, 2, 0},{ 9, 1, 1},{ -9, 1, 1},{ 10, 1, 1}, - {-10, 1, 1},{ 1, 3, 0},{ -1, 3, 0},{ 3, 2, 0},{ -3, 2, 0},{ 11, 1, 2}, - {-11, 1, 2},{ 4, 2, 0},{ -4, 2, 0},{ 12, 1, 2},{-12, 1, 2},{ 13, 1, 2}, - {-13, 1, 2},{ 5, 2, 0},{ -5, 2, 0},{ 1, 4, 0},{ -1, 4, 0},{ 2, 3, 0}, - { -2, 3, 0},{ 14, 1, 2},{-14, 1, 2},{ 6, 2, 0},{ -6, 2, 0},{ 15, 1, 2}, - {-15, 1, 2},{ 16, 1, 2},{-16, 1, 2},{ 3, 3, 0},{ -3, 3, 0},{ 1, 5, 0}, - { -1, 5, 0},{ 7, 2, 0},{ -7, 2, 0},{ 17, 1, 2},{-17, 1, 2} - }, - //level_add - { 0,18, 8, 4, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 7, //inc_limit - 5, //max_run - },{ - { //level / run - { EOB },{ 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0}, - { -3, 1, 0},{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 0},{ -5, 1, 0},{ 6, 1, 0}, - { -6, 1, 0},{ 7, 1, 0},{ -7, 1, 0},{ 8, 1, 0},{ -8, 1, 0},{ 9, 1, 0}, - { -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 11, 1, 1}, - {-11, 1, 1},{ 12, 1, 1},{-12, 1, 1},{ 13, 1, 1},{-13, 1, 1},{ 2, 2, 0}, - { -2, 2, 0},{ 14, 1, 1},{-14, 1, 1},{ 15, 1, 1},{-15, 1, 1},{ 3, 2, 0}, - { -3, 2, 0},{ 16, 1, 1},{-16, 1, 1},{ 1, 3, 0},{ -1, 3, 0},{ 17, 1, 1}, - {-17, 1, 1},{ 4, 2, 0},{ -4, 2, 0},{ 18, 1, 1},{-18, 1, 1},{ 5, 2, 0}, - { -5, 2, 0},{ 19, 1, 1},{-19, 1, 1},{ 20, 1, 1},{-20, 1, 1},{ 6, 2, 0}, - { -6, 2, 0},{ 21, 1, 1},{-21, 1, 1},{ 2, 3, 0},{ -2, 3, 0} - }, - //level_add - { 0,22, 7, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 10, //inc_limit - 3, //max_run - },{ - { //level / run - { EOB },{ 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0}, - { -3, 1, 0},{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 0},{ -5, 1, 0},{ 6, 1, 0}, - { -6, 1, 0},{ 7, 1, 0},{ -7, 1, 0},{ 8, 1, 0},{ -8, 1, 0},{ 9, 1, 0}, - { -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0},{-11, 1, 0},{ 12, 1, 0}, - {-12, 1, 0},{ 13, 1, 0},{-13, 1, 0},{ 14, 1, 0},{-14, 1, 0},{ 15, 1, 0}, - {-15, 1, 0},{ 16, 1, 0},{-16, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 17, 1, 0}, - {-17, 1, 0},{ 18, 1, 0},{-18, 1, 0},{ 19, 1, 0},{-19, 1, 0},{ 20, 1, 0}, - {-20, 1, 0},{ 21, 1, 0},{-21, 1, 0},{ 2, 2, 0},{ -2, 2, 0},{ 22, 1, 0}, - {-22, 1, 0},{ 23, 1, 0},{-23, 1, 0},{ 24, 1, 0},{-24, 1, 0},{ 25, 1, 0}, - {-25, 1, 0},{ 3, 2, 0},{ -3, 2, 0},{ 26, 1, 0},{-26, 1, 0} - }, - //level_add - { 0,27, 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}, - 2, //golomb_order - INT_MAX, //inc_limit - 2, //max_run - } -}; - -const struct dec_2dvlc ff_cavs_inter_dec[7] = { - { - { //level / run - { 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},{ 1, 3, 1},{ -1, 3, 1}, - { 1, 4, 1},{ -1, 4, 1},{ 1, 5, 1},{ -1, 5, 1},{ 1, 6, 1},{ -1, 6, 1}, - { 1, 7, 1},{ -1, 7, 1},{ 1, 8, 1},{ -1, 8, 1},{ 1, 9, 1},{ -1, 9, 1}, - { 1,10, 1},{ -1,10, 1},{ 1,11, 1},{ -1,11, 1},{ 1,12, 1},{ -1,12, 1}, - { 1,13, 1},{ -1,13, 1},{ 2, 1, 2},{ -2, 1, 2},{ 1,14, 1},{ -1,14, 1}, - { 1,15, 1},{ -1,15, 1},{ 1,16, 1},{ -1,16, 1},{ 1,17, 1},{ -1,17, 1}, - { 1,18, 1},{ -1,18, 1},{ 1,19, 1},{ -1,19, 1},{ 3, 1, 3},{ -3, 1, 3}, - { 1,20, 1},{ -1,20, 1},{ 1,21, 1},{ -1,21, 1},{ 2, 2, 2},{ -2, 2, 2}, - { 1,22, 1},{ -1,22, 1},{ 1,23, 1},{ -1,23, 1},{ 1,24, 1},{ -1,24, 1}, - { 1,25, 1},{ -1,25, 1},{ 1,26, 1},{ -1,26, 1},{ EOB } - }, - //level_add - { 0, 4, 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}, - 3, //golomb_order - 0, //inc_limit - 26 //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ EOB },{ 1, 2, 0},{ -1, 2, 0},{ 1, 3, 0}, - { -1, 3, 0},{ 1, 4, 0},{ -1, 4, 0},{ 1, 5, 0},{ -1, 5, 0},{ 1, 6, 0}, - { -1, 6, 0},{ 2, 1, 1},{ -2, 1, 1},{ 1, 7, 0},{ -1, 7, 0},{ 1, 8, 0}, - { -1, 8, 0},{ 1, 9, 0},{ -1, 9, 0},{ 1,10, 0},{ -1,10, 0},{ 2, 2, 1}, - { -2, 2, 1},{ 1,11, 0},{ -1,11, 0},{ 1,12, 0},{ -1,12, 0},{ 3, 1, 2}, - { -3, 1, 2},{ 1,13, 0},{ -1,13, 0},{ 1,14, 0},{ -1,14, 0},{ 2, 3, 1}, - { -2, 3, 1},{ 1,15, 0},{ -1,15, 0},{ 2, 4, 1},{ -2, 4, 1},{ 1,16, 0}, - { -1,16, 0},{ 2, 5, 1},{ -2, 5, 1},{ 1,17, 0},{ -1,17, 0},{ 4, 1, 3}, - { -4, 1, 3},{ 2, 6, 1},{ -2, 6, 1},{ 1,18, 0},{ -1,18, 0},{ 1,19, 0}, - { -1,19, 0},{ 2, 7, 1},{ -2, 7, 1},{ 3, 2, 2},{ -3, 2, 2} - }, - //level_add - { 0, 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 1, //inc_limit - 19 //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ EOB },{ 1, 2, 0},{ -1, 2, 0},{ 2, 1, 0}, - { -2, 1, 0},{ 1, 3, 0},{ -1, 3, 0},{ 1, 4, 0},{ -1, 4, 0},{ 3, 1, 1}, - { -3, 1, 1},{ 2, 2, 0},{ -2, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 1, 6, 0}, - { -1, 6, 0},{ 1, 7, 0},{ -1, 7, 0},{ 2, 3, 0},{ -2, 3, 0},{ 4, 1, 2}, - { -4, 1, 2},{ 1, 8, 0},{ -1, 8, 0},{ 3, 2, 1},{ -3, 2, 1},{ 2, 4, 0}, - { -2, 4, 0},{ 1, 9, 0},{ -1, 9, 0},{ 1,10, 0},{ -1,10, 0},{ 5, 1, 2}, - { -5, 1, 2},{ 2, 5, 0},{ -2, 5, 0},{ 1,11, 0},{ -1,11, 0},{ 2, 6, 0}, - { -2, 6, 0},{ 1,12, 0},{ -1,12, 0},{ 3, 3, 1},{ -3, 3, 1},{ 6, 1, 2}, - { -6, 1, 2},{ 4, 2, 2},{ -4, 2, 2},{ 1,13, 0},{ -1,13, 0},{ 2, 7, 0}, - { -2, 7, 0},{ 3, 4, 1},{ -3, 4, 1},{ 1,14, 0},{ -1,14, 0} - }, - //level_add - { 0, 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 2, //inc_limit - 14 //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ EOB },{ 2, 1, 0},{ -2, 1, 0},{ 1, 2, 0}, - { -1, 2, 0},{ 3, 1, 0},{ -3, 1, 0},{ 1, 3, 0},{ -1, 3, 0},{ 2, 2, 0}, - { -2, 2, 0},{ 4, 1, 1},{ -4, 1, 1},{ 1, 4, 0},{ -1, 4, 0},{ 5, 1, 1}, - { -5, 1, 1},{ 1, 5, 0},{ -1, 5, 0},{ 3, 2, 0},{ -3, 2, 0},{ 2, 3, 0}, - { -2, 3, 0},{ 1, 6, 0},{ -1, 6, 0},{ 6, 1, 1},{ -6, 1, 1},{ 2, 4, 0}, - { -2, 4, 0},{ 1, 7, 0},{ -1, 7, 0},{ 4, 2, 1},{ -4, 2, 1},{ 7, 1, 2}, - { -7, 1, 2},{ 3, 3, 0},{ -3, 3, 0},{ 1, 8, 0},{ -1, 8, 0},{ 2, 5, 0}, - { -2, 5, 0},{ 8, 1, 2},{ -8, 1, 2},{ 1, 9, 0},{ -1, 9, 0},{ 3, 4, 0}, - { -3, 4, 0},{ 2, 6, 0},{ -2, 6, 0},{ 5, 2, 1},{ -5, 2, 1},{ 1,10, 0}, - { -1,10, 0},{ 9, 1, 2},{ -9, 1, 2},{ 4, 3, 1},{ -4, 3, 1} - }, - //level_add - { 0,10, 6, 5, 4, 3, 3, 2, 2, 2, 2,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 3, //inc_limit - 10 //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ EOB },{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0}, - { -3, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 0}, - { -5, 1, 0},{ 2, 2, 0},{ -2, 2, 0},{ 1, 3, 0},{ -1, 3, 0},{ 6, 1, 0}, - { -6, 1, 0},{ 3, 2, 0},{ -3, 2, 0},{ 7, 1, 1},{ -7, 1, 1},{ 1, 4, 0}, - { -1, 4, 0},{ 8, 1, 1},{ -8, 1, 1},{ 2, 3, 0},{ -2, 3, 0},{ 4, 2, 0}, - { -4, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 9, 1, 1},{ -9, 1, 1},{ 5, 2, 0}, - { -5, 2, 0},{ 2, 4, 0},{ -2, 4, 0},{ 1, 6, 0},{ -1, 6, 0},{ 10, 1, 2}, - {-10, 1, 2},{ 3, 3, 0},{ -3, 3, 0},{ 11, 1, 2},{-11, 1, 2},{ 1, 7, 0}, - { -1, 7, 0},{ 6, 2, 0},{ -6, 2, 0},{ 3, 4, 0},{ -3, 4, 0},{ 2, 5, 0}, - { -2, 5, 0},{ 12, 1, 2},{-12, 1, 2},{ 4, 3, 0},{ -4, 3, 0} - }, - //level_add - { 0,13, 7, 5, 4, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 6, //inc_limit - 7 //max_run - },{ - { //level / run - { EOB },{ 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0}, - { -3, 1, 0},{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 0},{ -5, 1, 0},{ 1, 2, 0}, - { -1, 2, 0},{ 6, 1, 0},{ -6, 1, 0},{ 7, 1, 0},{ -7, 1, 0},{ 8, 1, 0}, - { -8, 1, 0},{ 2, 2, 0},{ -2, 2, 0},{ 9, 1, 0},{ -9, 1, 0},{ 1, 3, 0}, - { -1, 3, 0},{ 10, 1, 1},{-10, 1, 1},{ 3, 2, 0},{ -3, 2, 0},{ 11, 1, 1}, - {-11, 1, 1},{ 4, 2, 0},{ -4, 2, 0},{ 12, 1, 1},{-12, 1, 1},{ 1, 4, 0}, - { -1, 4, 0},{ 2, 3, 0},{ -2, 3, 0},{ 13, 1, 1},{-13, 1, 1},{ 5, 2, 0}, - { -5, 2, 0},{ 14, 1, 1},{-14, 1, 1},{ 6, 2, 0},{ -6, 2, 0},{ 1, 5, 0}, - { -1, 5, 0},{ 15, 1, 1},{-15, 1, 1},{ 3, 3, 0},{ -3, 3, 0},{ 16, 1, 1}, - {-16, 1, 1},{ 2, 4, 0},{ -2, 4, 0},{ 7, 2, 0},{ -7, 2, 0} - }, - //level_add - { 0,17, 8, 4, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - 9, //inc_limit - 5 //max_run - },{ - { //level / run - { EOB },{ 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0}, - { -3, 1, 0},{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 0},{ -5, 1, 0},{ 6, 1, 0}, - { -6, 1, 0},{ 7, 1, 0},{ -7, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 8, 1, 0}, - { -8, 1, 0},{ 9, 1, 0},{ -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0}, - {-11, 1, 0},{ 12, 1, 0},{-12, 1, 0},{ 2, 2, 0},{ -2, 2, 0},{ 13, 1, 0}, - {-13, 1, 0},{ 1, 3, 0},{ -1, 3, 0},{ 14, 1, 0},{-14, 1, 0},{ 15, 1, 0}, - {-15, 1, 0},{ 3, 2, 0},{ -3, 2, 0},{ 16, 1, 0},{-16, 1, 0},{ 17, 1, 0}, - {-17, 1, 0},{ 18, 1, 0},{-18, 1, 0},{ 4, 2, 0},{ -4, 2, 0},{ 19, 1, 0}, - {-19, 1, 0},{ 20, 1, 0},{-20, 1, 0},{ 2, 3, 0},{ -2, 3, 0},{ 1, 4, 0}, - { -1, 4, 0},{ 5, 2, 0},{ -5, 2, 0},{ 21, 1, 0},{-21, 1, 0} - }, - //level_add - { 0,22, 6, 3, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 2, //golomb_order - INT_MAX, //inc_limit - 4 //max_run - } -}; - -const struct dec_2dvlc ff_cavs_chroma_dec[5] = { - { - { //level / run - { 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},{ 1, 3, 1},{ -1, 3, 1}, - { 1, 4, 1},{ -1, 4, 1},{ 1, 5, 1},{ -1, 5, 1},{ 1, 6, 1},{ -1, 6, 1}, - { 1, 7, 1},{ -1, 7, 1},{ 2, 1, 2},{ -2, 1, 2},{ 1, 8, 1},{ -1, 8, 1}, - { 1, 9, 1},{ -1, 9, 1},{ 1,10, 1},{ -1,10, 1},{ 1,11, 1},{ -1,11, 1}, - { 1,12, 1},{ -1,12, 1},{ 1,13, 1},{ -1,13, 1},{ 1,14, 1},{ -1,14, 1}, - { 1,15, 1},{ -1,15, 1},{ 3, 1, 3},{ -3, 1, 3},{ 1,16, 1},{ -1,16, 1}, - { 1,17, 1},{ -1,17, 1},{ 1,18, 1},{ -1,18, 1},{ 1,19, 1},{ -1,19, 1}, - { 1,20, 1},{ -1,20, 1},{ 1,21, 1},{ -1,21, 1},{ 1,22, 1},{ -1,22, 1}, - { 2, 2, 2},{ -2, 2, 2},{ 1,23, 1},{ -1,23, 1},{ 1,24, 1},{ -1,24, 1}, - { 1,25, 1},{ -1,25, 1},{ 4, 1, 3},{ -4, 1, 3},{ EOB } - }, - //level_add - { 0, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2,-1}, - 2, //golomb_order - 0, //inc_limit - 25 //max_run - },{ - { //level / run - { EOB },{ 1, 1, 0},{ -1, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 2, 1, 1}, - { -2, 1, 1},{ 1, 3, 0},{ -1, 3, 0},{ 1, 4, 0},{ -1, 4, 0},{ 1, 5, 0}, - { -1, 5, 0},{ 1, 6, 0},{ -1, 6, 0},{ 3, 1, 2},{ -3, 1, 2},{ 1, 7, 0}, - { -1, 7, 0},{ 1, 8, 0},{ -1, 8, 0},{ 2, 2, 1},{ -2, 2, 1},{ 1, 9, 0}, - { -1, 9, 0},{ 1,10, 0},{ -1,10, 0},{ 1,11, 0},{ -1,11, 0},{ 4, 1, 2}, - { -4, 1, 2},{ 1,12, 0},{ -1,12, 0},{ 1,13, 0},{ -1,13, 0},{ 1,14, 0}, - { -1,14, 0},{ 2, 3, 1},{ -2, 3, 1},{ 1,15, 0},{ -1,15, 0},{ 2, 4, 1}, - { -2, 4, 1},{ 5, 1, 3},{ -5, 1, 3},{ 3, 2, 2},{ -3, 2, 2},{ 1,16, 0}, - { -1,16, 0},{ 1,17, 0},{ -1,17, 0},{ 1,18, 0},{ -1,18, 0},{ 2, 5, 1}, - { -2, 5, 1},{ 1,19, 0},{ -1,19, 0},{ 1,20, 0},{ -1,20, 0} - }, - //level_add - { 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2,-1,-1,-1,-1,-1,-1}, - 0, //golomb_order - 1, //inc_limit - 20 //max_run - },{ - { //level / run - { 1, 1, 0},{ -1, 1, 0},{ EOB },{ 2, 1, 0},{ -2, 1, 0},{ 1, 2, 0}, - { -1, 2, 0},{ 3, 1, 1},{ -3, 1, 1},{ 1, 3, 0},{ -1, 3, 0},{ 4, 1, 1}, - { -4, 1, 1},{ 2, 2, 0},{ -2, 2, 0},{ 1, 4, 0},{ -1, 4, 0},{ 5, 1, 2}, - { -5, 1, 2},{ 1, 5, 0},{ -1, 5, 0},{ 3, 2, 1},{ -3, 2, 1},{ 2, 3, 0}, - { -2, 3, 0},{ 1, 6, 0},{ -1, 6, 0},{ 6, 1, 2},{ -6, 1, 2},{ 1, 7, 0}, - { -1, 7, 0},{ 2, 4, 0},{ -2, 4, 0},{ 7, 1, 2},{ -7, 1, 2},{ 1, 8, 0}, - { -1, 8, 0},{ 4, 2, 1},{ -4, 2, 1},{ 1, 9, 0},{ -1, 9, 0},{ 3, 3, 1}, - { -3, 3, 1},{ 2, 5, 0},{ -2, 5, 0},{ 2, 6, 0},{ -2, 6, 0},{ 8, 1, 2}, - { -8, 1, 2},{ 1,10, 0},{ -1,10, 0},{ 1,11, 0},{ -1,11, 0},{ 9, 1, 2}, - { -9, 1, 2},{ 5, 2, 2},{ -5, 2, 2},{ 3, 4, 1},{ -3, 4, 1}, - }, - //level_add - { 0,10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 1, //golomb_order - 2, //inc_limit - 11 //max_run - },{ - { //level / run - { EOB },{ 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0}, - { -3, 1, 0},{ 4, 1, 0},{ -4, 1, 0},{ 1, 2, 0},{ -1, 2, 0},{ 5, 1, 1}, - { -5, 1, 1},{ 2, 2, 0},{ -2, 2, 0},{ 6, 1, 1},{ -6, 1, 1},{ 1, 3, 0}, - { -1, 3, 0},{ 7, 1, 1},{ -7, 1, 1},{ 3, 2, 0},{ -3, 2, 0},{ 8, 1, 1}, - { -8, 1, 1},{ 1, 4, 0},{ -1, 4, 0},{ 2, 3, 0},{ -2, 3, 0},{ 9, 1, 1}, - { -9, 1, 1},{ 4, 2, 0},{ -4, 2, 0},{ 1, 5, 0},{ -1, 5, 0},{ 10, 1, 1}, - {-10, 1, 1},{ 3, 3, 0},{ -3, 3, 0},{ 5, 2, 1},{ -5, 2, 1},{ 2, 4, 0}, - { -2, 4, 0},{ 11, 1, 1},{-11, 1, 1},{ 1, 6, 0},{ -1, 6, 0},{ 12, 1, 1}, - {-12, 1, 1},{ 1, 7, 0},{ -1, 7, 0},{ 6, 2, 1},{ -6, 2, 1},{ 13, 1, 1}, - {-13, 1, 1},{ 2, 5, 0},{ -2, 5, 0},{ 1, 8, 0},{ -1, 8, 0}, - }, - //level_add - { 0,14, 7, 4, 3, 3, 2, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 1, //golomb_order - 4, //inc_limit - 8 //max_run - },{ - { //level / run - { EOB },{ 1, 1, 0},{ -1, 1, 0},{ 2, 1, 0},{ -2, 1, 0},{ 3, 1, 0}, - { -3, 1, 0},{ 4, 1, 0},{ -4, 1, 0},{ 5, 1, 0},{ -5, 1, 0},{ 6, 1, 0}, - { -6, 1, 0},{ 7, 1, 0},{ -7, 1, 0},{ 8, 1, 0},{ -8, 1, 0},{ 1, 2, 0}, - { -1, 2, 0},{ 9, 1, 0},{ -9, 1, 0},{ 10, 1, 0},{-10, 1, 0},{ 11, 1, 0}, - {-11, 1, 0},{ 2, 2, 0},{ -2, 2, 0},{ 12, 1, 0},{-12, 1, 0},{ 13, 1, 0}, - {-13, 1, 0},{ 3, 2, 0},{ -3, 2, 0},{ 14, 1, 0},{-14, 1, 0},{ 1, 3, 0}, - { -1, 3, 0},{ 15, 1, 0},{-15, 1, 0},{ 4, 2, 0},{ -4, 2, 0},{ 16, 1, 0}, - {-16, 1, 0},{ 17, 1, 0},{-17, 1, 0},{ 5, 2, 0},{ -5, 2, 0},{ 1, 4, 0}, - { -1, 4, 0},{ 2, 3, 0},{ -2, 3, 0},{ 18, 1, 0},{-18, 1, 0},{ 6, 2, 0}, - { -6, 2, 0},{ 19, 1, 0},{-19, 1, 0},{ 1, 5, 0},{ -1, 5, 0}, - }, - //level_add - { 0,20, 7, 3, 2, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - 0, //golomb_order - INT_MAX, //inc_limit - 5, //max_run - } -}; - -#undef EOB - -static const uint8_t alpha_tab[64] = { - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20, - 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44, - 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 -}; - -static const uint8_t beta_tab[64] = { - 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, 4, 5, 5, 5, 5, 6, 6, - 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27 -}; - -static const uint8_t tc_tab[64] = { - 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, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, - 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9 -}; - -const int_fast8_t ff_left_modifier_l[8] = { 0,-1, 6,-1,-1, 7, 6, 7}; -const int_fast8_t ff_top_modifier_l[8] = {-1, 1, 5,-1,-1, 5, 7, 7}; -const int_fast8_t ff_left_modifier_c[7] = { 5,-1, 2,-1, 6, 5, 6}; -const int_fast8_t ff_top_modifier_c[7] = { 4, 1,-1,-1, 4, 6, 6}; - -#endif /* AVCODEC_CAVSDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/cavsdec.c b/tizen/distrib/ffmpeg/libavcodec/cavsdec.c deleted file mode 100644 index 9d6307c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cavsdec.c +++ /dev/null @@ -1,724 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder - * @author Stefan Gehrer - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "golomb.h" -#include "cavs.h" - -static const uint8_t mv_scan[4] = { - MV_FWD_X0,MV_FWD_X1, - MV_FWD_X2,MV_FWD_X3 -}; - -static const uint8_t cbp_tab[64][2] = { - {63, 0},{15,15},{31,63},{47,31},{ 0,16},{14,32},{13,47},{11,13}, - { 7,14},{ 5,11},{10,12},{ 8, 5},{12,10},{61, 7},{ 4,48},{55, 3}, - { 1, 2},{ 2, 8},{59, 4},{ 3, 1},{62,61},{ 9,55},{ 6,59},{29,62}, - {45,29},{51,27},{23,23},{39,19},{27,30},{46,28},{53, 9},{30, 6}, - {43,60},{37,21},{60,44},{16,26},{21,51},{28,35},{19,18},{35,20}, - {42,24},{26,53},{44,17},{32,37},{58,39},{24,45},{20,58},{17,43}, - {18,42},{48,46},{22,36},{33,33},{25,34},{49,40},{40,52},{36,49}, - {34,50},{50,56},{52,25},{54,22},{41,54},{56,57},{38,41},{57,38} -}; - -/***************************************************************************** - * - * motion vector prediction - * - ****************************************************************************/ - -static inline void store_mvs(AVSContext *h) { - h->col_mv[h->mbidx*4 + 0] = h->mv[MV_FWD_X0]; - h->col_mv[h->mbidx*4 + 1] = h->mv[MV_FWD_X1]; - h->col_mv[h->mbidx*4 + 2] = h->mv[MV_FWD_X2]; - h->col_mv[h->mbidx*4 + 3] = h->mv[MV_FWD_X3]; -} - -static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw, - cavs_vector *col_mv) { - cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS; - int den = h->direct_den[col_mv->ref]; - int m = col_mv->x >> 31; - - pmv_fw->dist = h->dist[1]; - pmv_bw->dist = h->dist[0]; - pmv_fw->ref = 1; - pmv_bw->ref = 0; - /* scale the co-located motion vector according to its temporal span */ - pmv_fw->x = (((den+(den*col_mv->x*pmv_fw->dist^m)-m-1)>>14)^m)-m; - pmv_bw->x = m-(((den+(den*col_mv->x*pmv_bw->dist^m)-m-1)>>14)^m); - m = col_mv->y >> 31; - pmv_fw->y = (((den+(den*col_mv->y*pmv_fw->dist^m)-m-1)>>14)^m)-m; - pmv_bw->y = m-(((den+(den*col_mv->y*pmv_bw->dist^m)-m-1)>>14)^m); -} - -static inline void mv_pred_sym(AVSContext *h, cavs_vector *src, enum cavs_block size) { - cavs_vector *dst = src + MV_BWD_OFFS; - - /* backward mv is the scaled and negated forward mv */ - dst->x = -((src->x * h->sym_factor + 256) >> 9); - dst->y = -((src->y * h->sym_factor + 256) >> 9); - dst->ref = 0; - dst->dist = h->dist[0]; - set_mvs(dst, size); -} - -/***************************************************************************** - * - * residual data decoding - * - ****************************************************************************/ - -/** kth-order exponential golomb code */ -static inline int get_ue_code(GetBitContext *gb, int order) { - if(order) { - int ret = get_ue_golomb(gb) << order; - return ret + get_bits(gb,order); - } - return get_ue_golomb(gb); -} - -/** - * decode coefficients from one 8x8 block, dequantize, inverse transform - * and add them to sample block - * @param r pointer to 2D VLC table - * @param esc_golomb_order escape codes are k-golomb with this order k - * @param qp quantizer - * @param dst location of sample block - * @param stride line stride in frame buffer - */ -static int decode_residual_block(AVSContext *h, GetBitContext *gb, - const struct dec_2dvlc *r, int esc_golomb_order, - int qp, uint8_t *dst, int stride) { - int i, level_code, esc_code, level, run, mask; - DCTELEM level_buf[65]; - uint8_t run_buf[65]; - DCTELEM *block = h->block; - - for(i=0;i<65;i++) { - level_code = get_ue_code(gb,r->golomb_order); - if(level_code >= ESCAPE_CODE) { - run = ((level_code - ESCAPE_CODE) >> 1) + 1; - esc_code = get_ue_code(gb,esc_golomb_order); - level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); - while(level > r->inc_limit) - r++; - mask = -(level_code & 1); - level = (level^mask) - mask; - } else { - level = r->rltab[level_code][0]; - if(!level) //end of block signal - break; - run = r->rltab[level_code][1]; - r += r->rltab[level_code][2]; - } - level_buf[i] = level; - run_buf[i] = run; - } - if(dequant(h,level_buf, run_buf, block, ff_cavs_dequant_mul[qp], - ff_cavs_dequant_shift[qp], i)) - return -1; - h->s.dsp.cavs_idct8_add(dst,block,stride); - h->s.dsp.clear_block(block); - return 0; -} - - -static inline void decode_residual_chroma(AVSContext *h) { - if(h->cbp & (1<<4)) - decode_residual_block(h,&h->s.gb,ff_cavs_chroma_dec,0, - ff_cavs_chroma_qp[h->qp],h->cu,h->c_stride); - if(h->cbp & (1<<5)) - decode_residual_block(h,&h->s.gb,ff_cavs_chroma_dec,0, - ff_cavs_chroma_qp[h->qp],h->cv,h->c_stride); -} - -static inline int decode_residual_inter(AVSContext *h) { - int block; - - /* get coded block pattern */ - int cbp= get_ue_golomb(&h->s.gb); - if(cbp > 63){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n"); - return -1; - } - h->cbp = cbp_tab[cbp][1]; - - /* get quantizer */ - if(h->cbp && !h->qp_fixed) - h->qp = (h->qp + get_se_golomb(&h->s.gb)) & 63; - for(block=0;block<4;block++) - if(h->cbp & (1<s.gb,ff_cavs_inter_dec,0,h->qp, - h->cy + h->luma_scan[block], h->l_stride); - decode_residual_chroma(h); - - return 0; -} - -/***************************************************************************** - * - * macroblock level - * - ****************************************************************************/ - -static int decode_mb_i(AVSContext *h, int cbp_code) { - GetBitContext *gb = &h->s.gb; - int block, pred_mode_uv; - uint8_t top[18]; - uint8_t *left = NULL; - uint8_t *d; - - ff_cavs_init_mb(h); - - /* get intra prediction modes from stream */ - for(block=0;block<4;block++) { - int nA,nB,predpred; - int pos = ff_cavs_scan3x3[block]; - - nA = h->pred_mode_Y[pos-1]; - nB = h->pred_mode_Y[pos-3]; - predpred = FFMIN(nA,nB); - if(predpred == NOT_AVAIL) // if either is not available - predpred = INTRA_L_LP; - if(!get_bits1(gb)){ - int rem_mode= get_bits(gb, 2); - predpred = rem_mode + (rem_mode >= predpred); - } - h->pred_mode_Y[pos] = predpred; - } - pred_mode_uv = get_ue_golomb(gb); - if(pred_mode_uv > 6) { - av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n"); - return -1; - } - ff_cavs_modify_mb_i(h, &pred_mode_uv); - - /* get coded block pattern */ - if(h->pic_type == FF_I_TYPE) - cbp_code = get_ue_golomb(gb); - if(cbp_code > 63){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n"); - return -1; - } - h->cbp = cbp_tab[cbp_code][0]; - if(h->cbp && !h->qp_fixed) - h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta - - /* luma intra prediction interleaved with residual decode/transform/add */ - for(block=0;block<4;block++) { - d = h->cy + h->luma_scan[block]; - ff_cavs_load_intra_pred_luma(h, top, &left, block); - h->intra_pred_l[h->pred_mode_Y[ff_cavs_scan3x3[block]]] - (d, top, left, h->l_stride); - if(h->cbp & (1<qp,d,h->l_stride); - } - - /* chroma intra prediction */ - ff_cavs_load_intra_pred_chroma(h); - h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx*10], - h->left_border_u, h->c_stride); - h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx*10], - h->left_border_v, h->c_stride); - - decode_residual_chroma(h); - ff_cavs_filter(h,I_8X8); - set_mv_intra(h); - return 0; -} - -static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type) { - GetBitContext *gb = &h->s.gb; - int ref[4]; - - ff_cavs_init_mb(h); - switch(mb_type) { - case P_SKIP: - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_PSKIP, BLK_16X16, 0); - break; - case P_16X16: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16,ref[0]); - break; - case P_16X8: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[2] = h->ref_flag ? 0 : get_bits1(gb); - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, ref[0]); - ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, ref[2]); - break; - case P_8X16: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[1] = h->ref_flag ? 0 : get_bits1(gb); - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, ref[0]); - ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT,BLK_8X16, ref[1]); - break; - case P_8X8: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[1] = h->ref_flag ? 0 : get_bits1(gb); - ref[2] = h->ref_flag ? 0 : get_bits1(gb); - ref[3] = h->ref_flag ? 0 : get_bits1(gb); - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_MEDIAN, BLK_8X8, ref[0]); - ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_MEDIAN, BLK_8X8, ref[1]); - ff_cavs_mv(h, MV_FWD_X2, MV_FWD_X1, MV_PRED_MEDIAN, BLK_8X8, ref[2]); - ff_cavs_mv(h, MV_FWD_X3, MV_FWD_X0, MV_PRED_MEDIAN, BLK_8X8, ref[3]); - } - ff_cavs_inter(h, mb_type); - set_intra_mode_default(h); - store_mvs(h); - if(mb_type != P_SKIP) - decode_residual_inter(h); - ff_cavs_filter(h,mb_type); - h->col_type_base[h->mbidx] = mb_type; -} - -static void decode_mb_b(AVSContext *h, enum cavs_mb mb_type) { - int block; - enum cavs_sub_mb sub_type[4]; - int flags; - - ff_cavs_init_mb(h); - - /* reset all MVs */ - h->mv[MV_FWD_X0] = ff_cavs_dir_mv; - set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); - h->mv[MV_BWD_X0] = ff_cavs_dir_mv; - set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); - switch(mb_type) { - case B_SKIP: - case B_DIRECT: - if(!h->col_type_base[h->mbidx]) { - /* intra MB at co-location, do in-plane prediction */ - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_BSKIP, BLK_16X16, 1); - ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_BSKIP, BLK_16X16, 0); - } else - /* direct prediction from co-located P MB, block-wise */ - for(block=0;block<4;block++) - mv_pred_direct(h,&h->mv[mv_scan[block]], - &h->col_mv[h->mbidx*4 + block]); - break; - case B_FWD_16X16: - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1); - break; - case B_SYM_16X16: - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1); - mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X16); - break; - case B_BWD_16X16: - ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_MEDIAN, BLK_16X16, 0); - break; - case B_8X8: - for(block=0;block<4;block++) - sub_type[block] = get_bits(&h->s.gb,2); - for(block=0;block<4;block++) { - switch(sub_type[block]) { - case B_SUB_DIRECT: - if(!h->col_type_base[h->mbidx]) { - /* intra MB at co-location, do in-plane prediction */ - ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3, - MV_PRED_BSKIP, BLK_8X8, 1); - ff_cavs_mv(h, mv_scan[block]+MV_BWD_OFFS, - mv_scan[block]-3+MV_BWD_OFFS, - MV_PRED_BSKIP, BLK_8X8, 0); - } else - mv_pred_direct(h,&h->mv[mv_scan[block]], - &h->col_mv[h->mbidx*4 + block]); - break; - case B_SUB_FWD: - ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3, - MV_PRED_MEDIAN, BLK_8X8, 1); - break; - case B_SUB_SYM: - ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3, - MV_PRED_MEDIAN, BLK_8X8, 1); - mv_pred_sym(h, &h->mv[mv_scan[block]], BLK_8X8); - break; - } - } - for(block=0;block<4;block++) { - if(sub_type[block] == B_SUB_BWD) - ff_cavs_mv(h, mv_scan[block]+MV_BWD_OFFS, - mv_scan[block]+MV_BWD_OFFS-3, - MV_PRED_MEDIAN, BLK_8X8, 0); - } - break; - default: - assert((mb_type > B_SYM_16X16) && (mb_type < B_8X8)); - flags = ff_cavs_partition_flags[mb_type]; - if(mb_type & 1) { /* 16x8 macroblock types */ - if(flags & FWD0) - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, 1); - if(flags & SYM0) - mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X8); - if(flags & FWD1) - ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, 1); - if(flags & SYM1) - mv_pred_sym(h, &h->mv[MV_FWD_X2], BLK_16X8); - if(flags & BWD0) - ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_TOP, BLK_16X8, 0); - if(flags & BWD1) - ff_cavs_mv(h, MV_BWD_X2, MV_BWD_A1, MV_PRED_LEFT, BLK_16X8, 0); - } else { /* 8x16 macroblock types */ - if(flags & FWD0) - ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, 1); - if(flags & SYM0) - mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_8X16); - if(flags & FWD1) - ff_cavs_mv(h,MV_FWD_X1,MV_FWD_C2,MV_PRED_TOPRIGHT,BLK_8X16,1); - if(flags & SYM1) - mv_pred_sym(h, &h->mv[MV_FWD_X1], BLK_8X16); - if(flags & BWD0) - ff_cavs_mv(h, MV_BWD_X0, MV_BWD_B3, MV_PRED_LEFT, BLK_8X16, 0); - if(flags & BWD1) - ff_cavs_mv(h,MV_BWD_X1,MV_BWD_C2,MV_PRED_TOPRIGHT,BLK_8X16,0); - } - } - ff_cavs_inter(h, mb_type); - set_intra_mode_default(h); - if(mb_type != B_SKIP) - decode_residual_inter(h); - ff_cavs_filter(h,mb_type); -} - -/***************************************************************************** - * - * slice level - * - ****************************************************************************/ - -static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) { - if(h->stc > 0xAF) - av_log(h->s.avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc); - h->mby = h->stc; - h->mbidx = h->mby*h->mb_width; - - /* mark top macroblocks as unavailable */ - h->flags &= ~(B_AVAIL|C_AVAIL); - if((h->mby == 0) && (!h->qp_fixed)){ - h->qp_fixed = get_bits1(gb); - h->qp = get_bits(gb,6); - } - /* inter frame or second slice can have weighting params */ - if((h->pic_type != FF_I_TYPE) || (!h->pic_structure && h->mby >= h->mb_width/2)) - if(get_bits1(gb)) { //slice_weighting_flag - av_log(h->s.avctx, AV_LOG_ERROR, - "weighted prediction not yet supported\n"); - } - return 0; -} - -static inline int check_for_slice(AVSContext *h) { - GetBitContext *gb = &h->s.gb; - int align; - - if(h->mbx) - return 0; - align = (-get_bits_count(gb)) & 7; - /* check for stuffing byte */ - if(!align && (show_bits(gb,8) == 0x80)) - align = 8; - if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) { - skip_bits_long(gb,24+align); - h->stc = get_bits(gb,8); - decode_slice_header(h,gb); - return 1; - } - return 0; -} - -/***************************************************************************** - * - * frame level - * - ****************************************************************************/ - -static int decode_pic(AVSContext *h) { - MpegEncContext *s = &h->s; - int skip_count = -1; - enum cavs_mb mb_type; - - if (!s->context_initialized) { - s->avctx->idct_algo = FF_IDCT_CAVS; - if (MPV_common_init(s) < 0) - return -1; - ff_init_scantable(s->dsp.idct_permutation,&h->scantable,ff_zigzag_direct); - } - skip_bits(&s->gb,16);//bbv_dwlay - if(h->stc == PIC_PB_START_CODE) { - h->pic_type = get_bits(&s->gb,2) + FF_I_TYPE; - if(h->pic_type > FF_B_TYPE) { - av_log(s->avctx, AV_LOG_ERROR, "illegal picture type\n"); - return -1; - } - /* make sure we have the reference frames we need */ - if(!h->DPB[0].data[0] || - (!h->DPB[1].data[0] && h->pic_type == FF_B_TYPE)) - return -1; - } else { - h->pic_type = FF_I_TYPE; - if(get_bits1(&s->gb)) - skip_bits(&s->gb,24);//time_code - /* old sample clips were all progressive and no low_delay, - bump stream revision if detected otherwise */ - if((s->low_delay) || !(show_bits(&s->gb,9) & 1)) - h->stream_revision = 1; - /* similarly test top_field_first and repeat_first_field */ - else if(show_bits(&s->gb,11) & 3) - h->stream_revision = 1; - if(h->stream_revision > 0) - skip_bits(&s->gb,1); //marker_bit - } - /* release last B frame */ - if(h->picture.data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->picture); - - s->avctx->get_buffer(s->avctx, (AVFrame *)&h->picture); - ff_cavs_init_pic(h); - h->picture.poc = get_bits(&s->gb,8)*2; - - /* get temporal distances and MV scaling factors */ - if(h->pic_type != FF_B_TYPE) { - h->dist[0] = (h->picture.poc - h->DPB[0].poc + 512) % 512; - } else { - h->dist[0] = (h->DPB[0].poc - h->picture.poc + 512) % 512; - } - h->dist[1] = (h->picture.poc - h->DPB[1].poc + 512) % 512; - h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0; - h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0; - if(h->pic_type == FF_B_TYPE) { - h->sym_factor = h->dist[0]*h->scale_den[1]; - } else { - h->direct_den[0] = h->dist[0] ? 16384/h->dist[0] : 0; - h->direct_den[1] = h->dist[1] ? 16384/h->dist[1] : 0; - } - - if(s->low_delay) - get_ue_golomb(&s->gb); //bbv_check_times - h->progressive = get_bits1(&s->gb); - h->pic_structure = 1; - if(!h->progressive) - h->pic_structure = get_bits1(&s->gb); - if(!h->pic_structure && h->stc == PIC_PB_START_CODE) - skip_bits1(&s->gb); //advanced_pred_mode_disable - skip_bits1(&s->gb); //top_field_first - skip_bits1(&s->gb); //repeat_first_field - h->qp_fixed = get_bits1(&s->gb); - h->qp = get_bits(&s->gb,6); - if(h->pic_type == FF_I_TYPE) { - if(!h->progressive && !h->pic_structure) - skip_bits1(&s->gb);//what is this? - skip_bits(&s->gb,4); //reserved bits - } else { - if(!(h->pic_type == FF_B_TYPE && h->pic_structure == 1)) - h->ref_flag = get_bits1(&s->gb); - skip_bits(&s->gb,4); //reserved bits - h->skip_mode_flag = get_bits1(&s->gb); - } - h->loop_filter_disable = get_bits1(&s->gb); - if(!h->loop_filter_disable && get_bits1(&s->gb)) { - h->alpha_offset = get_se_golomb(&s->gb); - h->beta_offset = get_se_golomb(&s->gb); - } else { - h->alpha_offset = h->beta_offset = 0; - } - if(h->pic_type == FF_I_TYPE) { - do { - check_for_slice(h); - decode_mb_i(h, 0); - } while(ff_cavs_next_mb(h)); - } else if(h->pic_type == FF_P_TYPE) { - do { - if(check_for_slice(h)) - skip_count = -1; - if(h->skip_mode_flag && (skip_count < 0)) - skip_count = get_ue_golomb(&s->gb); - if(h->skip_mode_flag && skip_count--) { - decode_mb_p(h,P_SKIP); - } else { - mb_type = get_ue_golomb(&s->gb) + P_SKIP + h->skip_mode_flag; - if(mb_type > P_8X8) - decode_mb_i(h, mb_type - P_8X8 - 1); - else - decode_mb_p(h,mb_type); - } - } while(ff_cavs_next_mb(h)); - } else { /* FF_B_TYPE */ - do { - if(check_for_slice(h)) - skip_count = -1; - if(h->skip_mode_flag && (skip_count < 0)) - skip_count = get_ue_golomb(&s->gb); - if(h->skip_mode_flag && skip_count--) { - decode_mb_b(h,B_SKIP); - } else { - mb_type = get_ue_golomb(&s->gb) + B_SKIP + h->skip_mode_flag; - if(mb_type > B_8X8) - decode_mb_i(h, mb_type - B_8X8 - 1); - else - decode_mb_b(h,mb_type); - } - } while(ff_cavs_next_mb(h)); - } - if(h->pic_type != FF_B_TYPE) { - if(h->DPB[1].data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->DPB[1]); - h->DPB[1] = h->DPB[0]; - h->DPB[0] = h->picture; - memset(&h->picture,0,sizeof(Picture)); - } - return 0; -} - -/***************************************************************************** - * - * headers and interface - * - ****************************************************************************/ - -static int decode_seq_header(AVSContext *h) { - MpegEncContext *s = &h->s; - int frame_rate_code; - - h->profile = get_bits(&s->gb,8); - h->level = get_bits(&s->gb,8); - skip_bits1(&s->gb); //progressive sequence - s->width = get_bits(&s->gb,14); - s->height = get_bits(&s->gb,14); - skip_bits(&s->gb,2); //chroma format - skip_bits(&s->gb,3); //sample_precision - h->aspect_ratio = get_bits(&s->gb,4); - frame_rate_code = get_bits(&s->gb,4); - skip_bits(&s->gb,18);//bit_rate_lower - skip_bits1(&s->gb); //marker_bit - skip_bits(&s->gb,12);//bit_rate_upper - s->low_delay = get_bits1(&s->gb); - h->mb_width = (s->width + 15) >> 4; - h->mb_height = (s->height + 15) >> 4; - h->s.avctx->time_base.den = ff_frame_rate_tab[frame_rate_code].num; - h->s.avctx->time_base.num = ff_frame_rate_tab[frame_rate_code].den; - h->s.avctx->width = s->width; - h->s.avctx->height = s->height; - if(!h->top_qp) - ff_cavs_init_top_lines(h); - return 0; -} - -static void cavs_flush(AVCodecContext * avctx) { - AVSContext *h = avctx->priv_data; - h->got_keyframe = 0; -} - -static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AVSContext *h = avctx->priv_data; - MpegEncContext *s = &h->s; - int input_size; - const uint8_t *buf_end; - const uint8_t *buf_ptr; - AVFrame *picture = data; - uint32_t stc = -1; - - s->avctx = avctx; - - if (buf_size == 0) { - if(!s->low_delay && h->DPB[0].data[0]) { - *data_size = sizeof(AVPicture); - *picture = *(AVFrame *) &h->DPB[0]; - } - return 0; - } - - buf_ptr = buf; - buf_end = buf + buf_size; - for(;;) { - buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc); - if(stc & 0xFFFFFE00) - return FFMAX(0, buf_ptr - buf - s->parse_context.last_index); - input_size = (buf_end - buf_ptr)*8; - switch(stc) { - case CAVS_START_CODE: - init_get_bits(&s->gb, buf_ptr, input_size); - decode_seq_header(h); - break; - case PIC_I_START_CODE: - if(!h->got_keyframe) { - if(h->DPB[0].data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[0]); - if(h->DPB[1].data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[1]); - h->got_keyframe = 1; - } - case PIC_PB_START_CODE: - *data_size = 0; - if(!h->got_keyframe) - break; - init_get_bits(&s->gb, buf_ptr, input_size); - h->stc = stc; - if(decode_pic(h)) - break; - *data_size = sizeof(AVPicture); - if(h->pic_type != FF_B_TYPE) { - if(h->DPB[1].data[0]) { - *picture = *(AVFrame *) &h->DPB[1]; - } else { - *data_size = 0; - } - } else - *picture = *(AVFrame *) &h->picture; - break; - case EXT_START_CODE: - //mpeg_decode_extension(avctx,buf_ptr, input_size); - break; - case USER_START_CODE: - //mpeg_decode_user_data(avctx,buf_ptr, input_size); - break; - default: - if (stc <= SLICE_MAX_START_CODE) { - init_get_bits(&s->gb, buf_ptr, input_size); - decode_slice_header(h, &s->gb); - } - break; - } - } -} - -AVCodec cavs_decoder = { - "cavs", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CAVS, - sizeof(AVSContext), - ff_cavs_init, - NULL, - ff_cavs_end, - cavs_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .flush= cavs_flush, - .long_name= NULL_IF_CONFIG_SMALL("Chinese AVS video (AVS1-P2, JiZhun profile)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/cavsdsp.c b/tizen/distrib/ffmpeg/libavcodec/cavsdsp.c deleted file mode 100644 index 808f62b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cavsdsp.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * - * DSP functions - * - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "dsputil.h" - -/***************************************************************************** - * - * in-loop deblocking filter - * - ****************************************************************************/ - -#define P2 p0_p[-3*stride] -#define P1 p0_p[-2*stride] -#define P0 p0_p[-1*stride] -#define Q0 p0_p[ 0*stride] -#define Q1 p0_p[ 1*stride] -#define Q2 p0_p[ 2*stride] - -static inline void loop_filter_l2(uint8_t *p0_p,int stride,int alpha, int beta) { - int p0 = P0; - int q0 = Q0; - - if(abs(p0-q0)>2) + 2; - if(abs(P2-p0) < beta && abs(p0-q0) < alpha) { - P0 = (P1 + p0 + s) >> 2; - P1 = (2*P1 + s) >> 2; - } else - P0 = (2*P1 + s) >> 2; - if(abs(Q2-q0) < beta && abs(q0-p0) < alpha) { - Q0 = (Q1 + q0 + s) >> 2; - Q1 = (2*Q1 + s) >> 2; - } else - Q0 = (2*Q1 + s) >> 2; - } -} - -static inline void loop_filter_l1(uint8_t *p0_p, int stride, int alpha, int beta, int tc) { - int p0 = P0; - int q0 = Q0; - - if(abs(p0-q0)>3,-tc, tc); - P0 = av_clip_uint8(p0+delta); - Q0 = av_clip_uint8(q0-delta); - if(abs(P2-p0)>3, -tc, tc); - P1 = av_clip_uint8(P1+delta); - } - if(abs(Q2-q0)>3, -tc, tc); - Q1 = av_clip_uint8(Q1-delta); - } - } -} - -static inline void loop_filter_c2(uint8_t *p0_p,int stride,int alpha, int beta) { - int p0 = P0; - int q0 = Q0; - - if(abs(p0-q0)>2) + 2; - if(abs(P2-p0) < beta && abs(p0-q0) < alpha) { - P0 = (P1 + p0 + s) >> 2; - } else - P0 = (2*P1 + s) >> 2; - if(abs(Q2-q0) < beta && abs(q0-p0) < alpha) { - Q0 = (Q1 + q0 + s) >> 2; - } else - Q0 = (2*Q1 + s) >> 2; - } -} - -static inline void loop_filter_c1(uint8_t *p0_p,int stride,int alpha, int beta, - int tc) { - if(abs(P0-Q0)>3, -tc, tc); - P0 = av_clip_uint8(P0+delta); - Q0 = av_clip_uint8(Q0-delta); - } -} - -#undef P0 -#undef P1 -#undef P2 -#undef Q0 -#undef Q1 -#undef Q2 - -static void cavs_filter_lv_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<16;i++) - loop_filter_l2(d + i*stride,1,alpha,beta); - else { - if(bs1) - for(i=0;i<8;i++) - loop_filter_l1(d + i*stride,1,alpha,beta,tc); - if (bs2) - for(i=8;i<16;i++) - loop_filter_l1(d + i*stride,1,alpha,beta,tc); - } -} - -static void cavs_filter_lh_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<16;i++) - loop_filter_l2(d + i,stride,alpha,beta); - else { - if(bs1) - for(i=0;i<8;i++) - loop_filter_l1(d + i,stride,alpha,beta,tc); - if (bs2) - for(i=8;i<16;i++) - loop_filter_l1(d + i,stride,alpha,beta,tc); - } -} - -static void cavs_filter_cv_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<8;i++) - loop_filter_c2(d + i*stride,1,alpha,beta); - else { - if(bs1) - for(i=0;i<4;i++) - loop_filter_c1(d + i*stride,1,alpha,beta,tc); - if (bs2) - for(i=4;i<8;i++) - loop_filter_c1(d + i*stride,1,alpha,beta,tc); - } -} - -static void cavs_filter_ch_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<8;i++) - loop_filter_c2(d + i,stride,alpha,beta); - else { - if(bs1) - for(i=0;i<4;i++) - loop_filter_c1(d + i,stride,alpha,beta,tc); - if (bs2) - for(i=4;i<8;i++) - loop_filter_c1(d + i,stride,alpha,beta,tc); - } -} - -/***************************************************************************** - * - * inverse transform - * - ****************************************************************************/ - -static void cavs_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride) { - int i; - DCTELEM (*src)[8] = (DCTELEM(*)[8])block; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - src[0][0] += 8; - - for( i = 0; i < 8; i++ ) { - const int a0 = 3*src[i][1] - (src[i][7]<<1); - const int a1 = 3*src[i][3] + (src[i][5]<<1); - const int a2 = (src[i][3]<<1) - 3*src[i][5]; - const int a3 = (src[i][1]<<1) + 3*src[i][7]; - - const int b4 = ((a0 + a1 + a3)<<1) + a1; - const int b5 = ((a0 - a1 + a2)<<1) + a0; - const int b6 = ((a3 - a2 - a1)<<1) + a3; - const int b7 = ((a0 - a2 - a3)<<1) - a2; - - const int a7 = (src[i][2]<<2) - 10*src[i][6]; - const int a6 = (src[i][6]<<2) + 10*src[i][2]; - const int a5 = ((src[i][0] - src[i][4]) << 3) + 4; - const int a4 = ((src[i][0] + src[i][4]) << 3) + 4; - - const int b0 = a4 + a6; - const int b1 = a5 + a7; - const int b2 = a5 - a7; - const int b3 = a4 - a6; - - src[i][0] = (b0 + b4) >> 3; - src[i][1] = (b1 + b5) >> 3; - src[i][2] = (b2 + b6) >> 3; - src[i][3] = (b3 + b7) >> 3; - src[i][4] = (b3 - b7) >> 3; - src[i][5] = (b2 - b6) >> 3; - src[i][6] = (b1 - b5) >> 3; - src[i][7] = (b0 - b4) >> 3; - } - for( i = 0; i < 8; i++ ) { - const int a0 = 3*src[1][i] - (src[7][i]<<1); - const int a1 = 3*src[3][i] + (src[5][i]<<1); - const int a2 = (src[3][i]<<1) - 3*src[5][i]; - const int a3 = (src[1][i]<<1) + 3*src[7][i]; - - const int b4 = ((a0 + a1 + a3)<<1) + a1; - const int b5 = ((a0 - a1 + a2)<<1) + a0; - const int b6 = ((a3 - a2 - a1)<<1) + a3; - const int b7 = ((a0 - a2 - a3)<<1) - a2; - - const int a7 = (src[2][i]<<2) - 10*src[6][i]; - const int a6 = (src[6][i]<<2) + 10*src[2][i]; - const int a5 = (src[0][i] - src[4][i]) << 3; - const int a4 = (src[0][i] + src[4][i]) << 3; - - const int b0 = a4 + a6; - const int b1 = a5 + a7; - const int b2 = a5 - a7; - const int b3 = a4 - a6; - - dst[i + 0*stride] = cm[ dst[i + 0*stride] + ((b0 + b4) >> 7)]; - dst[i + 1*stride] = cm[ dst[i + 1*stride] + ((b1 + b5) >> 7)]; - dst[i + 2*stride] = cm[ dst[i + 2*stride] + ((b2 + b6) >> 7)]; - dst[i + 3*stride] = cm[ dst[i + 3*stride] + ((b3 + b7) >> 7)]; - dst[i + 4*stride] = cm[ dst[i + 4*stride] + ((b3 - b7) >> 7)]; - dst[i + 5*stride] = cm[ dst[i + 5*stride] + ((b2 - b6) >> 7)]; - dst[i + 6*stride] = cm[ dst[i + 6*stride] + ((b1 - b5) >> 7)]; - dst[i + 7*stride] = cm[ dst[i + 7*stride] + ((b0 - b4) >> 7)]; - } -} - -/***************************************************************************** - * - * motion compensation - * - ****************************************************************************/ - -#define CAVS_SUBPIX(OPNAME, OP, NAME, A, B, C, D, E, F) \ -static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int h=8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i;\ - for(i=0; i>3] -#define op_put2(a, b) a = cm[((b)+64)>>7] -#define op_put3(a, b) a = cm[((b)+32)>>6] -#define op_put4(a, b) a = cm[((b)+512)>>10] -#define op_avg1(a, b) a = ((a)+cm[((b)+4)>>3] +1)>>1 -#define op_avg2(a, b) a = ((a)+cm[((b)+64)>>7] +1)>>1 -#define op_avg3(a, b) a = ((a)+cm[((b)+32)>>6] +1)>>1 -#define op_avg4(a, b) a = ((a)+cm[((b)+512)>>10]+1)>>1 -CAVS_SUBPIX(put_ , op_put1, hpel, 0, -1, 5, 5, -1, 0) -CAVS_SUBPIX(put_ , op_put2, qpel_l, -1, -2, 96, 42, -7, 0) -CAVS_SUBPIX(put_ , op_put2, qpel_r, 0, -7, 42, 96, -2, -1) -CAVS_SUBPIX_HV(put_, op_put3, jj, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, ff, 0, -1, 5, 5, -1, 0, -1, -2, 96, 42, -7, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, ii, -1, -2, 96, 42, -7, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, kk, 0, -7, 42, 96, -2, -1, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, qq, 0, -1, 5, 5, -1, 0, 0, -7, 42, 96, -2,-1, 0) -CAVS_SUBPIX_HV(put_, op_put2, egpr, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 1) -CAVS_SUBPIX(avg_ , op_avg1, hpel, 0, -1, 5, 5, -1, 0) -CAVS_SUBPIX(avg_ , op_avg2, qpel_l, -1, -2, 96, 42, -7, 0) -CAVS_SUBPIX(avg_ , op_avg2, qpel_r, 0, -7, 42, 96, -2, -1) -CAVS_SUBPIX_HV(avg_, op_avg3, jj, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, ff, 0, -1, 5, 5, -1, 0, -1, -2, 96, 42, -7, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, ii, -1, -2, 96, 42, -7, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, kk, 0, -7, 42, 96, -2, -1, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, qq, 0, -1, 5, 5, -1, 0, 0, -7, 42, 96, -2,-1, 0) -CAVS_SUBPIX_HV(avg_, op_avg2, egpr, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 1) -CAVS_MC(put_, 8) -CAVS_MC(put_, 16) -CAVS_MC(avg_, 8) -CAVS_MC(avg_, 16) - -av_cold void ff_cavsdsp_init(DSPContext* c, AVCodecContext *avctx) { -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_c; \ - c->PFX ## _pixels_tab[IDX][ 1] = ff_ ## PFX ## NUM ## _mc10_c; \ - c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_c; \ - c->PFX ## _pixels_tab[IDX][ 3] = ff_ ## PFX ## NUM ## _mc30_c; \ - c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_c; \ - c->PFX ## _pixels_tab[IDX][ 5] = ff_ ## PFX ## NUM ## _mc11_c; \ - c->PFX ## _pixels_tab[IDX][ 6] = ff_ ## PFX ## NUM ## _mc21_c; \ - c->PFX ## _pixels_tab[IDX][ 7] = ff_ ## PFX ## NUM ## _mc31_c; \ - c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_c; \ - c->PFX ## _pixels_tab[IDX][ 9] = ff_ ## PFX ## NUM ## _mc12_c; \ - c->PFX ## _pixels_tab[IDX][10] = ff_ ## PFX ## NUM ## _mc22_c; \ - c->PFX ## _pixels_tab[IDX][11] = ff_ ## PFX ## NUM ## _mc32_c; \ - c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_c; \ - c->PFX ## _pixels_tab[IDX][13] = ff_ ## PFX ## NUM ## _mc13_c; \ - c->PFX ## _pixels_tab[IDX][14] = ff_ ## PFX ## NUM ## _mc23_c; \ - c->PFX ## _pixels_tab[IDX][15] = ff_ ## PFX ## NUM ## _mc33_c - dspfunc(put_cavs_qpel, 0, 16); - dspfunc(put_cavs_qpel, 1, 8); - dspfunc(avg_cavs_qpel, 0, 16); - dspfunc(avg_cavs_qpel, 1, 8); - c->cavs_filter_lv = cavs_filter_lv_c; - c->cavs_filter_lh = cavs_filter_lh_c; - c->cavs_filter_cv = cavs_filter_cv_c; - c->cavs_filter_ch = cavs_filter_ch_c; - c->cavs_idct8_add = cavs_idct8_add_c; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.c b/tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.c deleted file mode 100644 index dbbd632..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Generate a header file for hardcoded AAC cube-root table - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#define CONFIG_HARDCODED_TABLES 0 -#include "cbrt_tablegen.h" -#include "tableprint.h" - -int main(void) -{ - cbrt_tableinit(); - - write_fileheader(); - - printf("static const uint32_t cbrt_tab[1<<13] = {\n"); - write_uint32_array(cbrt_tab, 1 << 13); - printf("};\n"); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.h b/tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.h deleted file mode 100644 index 930e513..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cbrt_tablegen.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Header file for hardcoded AAC cube-root table - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef CBRT_TABLEGEN_H -#define CBRT_TABLEGEN_H - -#include -#include - -#if CONFIG_HARDCODED_TABLES -#define cbrt_tableinit() -#include "libavcodec/cbrt_tables.h" -#else -static uint32_t cbrt_tab[1 << 13]; - -static void cbrt_tableinit(void) -{ - if (!cbrt_tab[(1<<13) - 1]) { - int i; - for (i = 0; i < 1<<13; i++) { - union { - float f; - uint32_t i; - } f; - f.f = cbrtf(i) * i; - cbrt_tab[i] = f.i; - } - } -} -#endif /* CONFIG_HARDCODED_TABLES */ - -#endif /* CBRT_TABLEGEN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/cdgraphics.c b/tizen/distrib/ffmpeg/libavcodec/cdgraphics.c deleted file mode 100644 index c174aa9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cdgraphics.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * CD Graphics Video Decoder - * Copyright (c) 2009 Michael Tison - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" - -/** - * @file - * @brief CD Graphics Video Decoder - * @author Michael Tison - * @sa http://wiki.multimedia.cx/index.php?title=CD_Graphics - * @sa http://www.ccs.neu.edu/home/bchafy/cdb/info/cdg - */ - -/// default screen sizes -#define CDG_FULL_WIDTH 300 -#define CDG_FULL_HEIGHT 216 -#define CDG_DISPLAY_WIDTH 294 -#define CDG_DISPLAY_HEIGHT 204 -#define CDG_BORDER_WIDTH 6 -#define CDG_BORDER_HEIGHT 12 - -/// masks -#define CDG_COMMAND 0x09 -#define CDG_MASK 0x3F - -/// instruction codes -#define CDG_INST_MEMORY_PRESET 1 -#define CDG_INST_BORDER_PRESET 2 -#define CDG_INST_TILE_BLOCK 6 -#define CDG_INST_SCROLL_PRESET 20 -#define CDG_INST_SCROLL_COPY 24 -#define CDG_INST_LOAD_PAL_LO 30 -#define CDG_INST_LOAD_PAL_HIGH 31 -#define CDG_INST_TILE_BLOCK_XOR 38 - -/// data sizes -#define CDG_PACKET_SIZE 24 -#define CDG_DATA_SIZE 16 -#define CDG_TILE_HEIGHT 12 -#define CDG_TILE_WIDTH 6 -#define CDG_MINIMUM_PKT_SIZE 6 -#define CDG_MINIMUM_SCROLL_SIZE 3 -#define CDG_HEADER_SIZE 8 -#define CDG_PALETTE_SIZE 16 - -typedef struct CDGraphicsContext { - AVFrame frame; - int hscroll; - int vscroll; -} CDGraphicsContext; - -static void cdg_init_frame(AVFrame *frame) -{ - avcodec_get_frame_defaults(frame); - frame->reference = 3; - frame->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; -} - -static av_cold int cdg_decode_init(AVCodecContext *avctx) -{ - CDGraphicsContext *cc = avctx->priv_data; - - cdg_init_frame(&cc->frame); - - avctx->width = CDG_FULL_WIDTH; - avctx->height = CDG_FULL_HEIGHT; - avctx->pix_fmt = PIX_FMT_PAL8; - - return 0; -} - -static void cdg_border_preset(CDGraphicsContext *cc, uint8_t *data) -{ - int y; - int lsize = cc->frame.linesize[0]; - uint8_t *buf = cc->frame.data[0]; - int color = data[0] & 0x0F; - - if (!(data[1] & 0x0F)) { - /// fill the top and bottom borders - memset(buf, color, CDG_BORDER_HEIGHT * lsize); - memset(buf + (CDG_FULL_HEIGHT - CDG_BORDER_HEIGHT) * lsize, - color, CDG_BORDER_HEIGHT * lsize); - - /// fill the side borders - for (y = CDG_BORDER_HEIGHT; y < CDG_FULL_HEIGHT - CDG_BORDER_HEIGHT; y++) { - memset(buf + y * lsize, color, CDG_BORDER_WIDTH); - memset(buf + CDG_FULL_WIDTH - CDG_BORDER_WIDTH + y * lsize, - color, CDG_BORDER_WIDTH); - } - } -} - -static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low) -{ - uint8_t r, g, b; - uint16_t color; - int i; - int array_offset = low ? 0 : 8; - uint32_t *palette = (uint32_t *) cc->frame.data[1]; - - for (i = 0; i < 8; i++) { - color = (data[2 * i] << 6) + (data[2 * i + 1] & 0x3F); - r = ((color >> 8) & 0x000F) * 17; - g = ((color >> 4) & 0x000F) * 17; - b = ((color ) & 0x000F) * 17; - palette[i + array_offset] = r << 16 | g << 8 | b; - } - cc->frame.palette_has_changed = 1; -} - -static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b) -{ - unsigned ci, ri; - int color; - int x, y; - int ai; - int stride = cc->frame.linesize[0]; - uint8_t *buf = cc->frame.data[0]; - - ri = (data[2] & 0x1F) * CDG_TILE_HEIGHT + cc->vscroll; - ci = (data[3] & 0x3F) * CDG_TILE_WIDTH + cc->hscroll; - - if (ri > (CDG_FULL_HEIGHT - CDG_TILE_HEIGHT)) - return AVERROR(EINVAL); - if (ci > (CDG_FULL_WIDTH - CDG_TILE_WIDTH)) - return AVERROR(EINVAL); - - for (y = 0; y < CDG_TILE_HEIGHT; y++) { - for (x = 0; x < CDG_TILE_WIDTH; x++) { - if (!((data[4 + y] >> (5 - x)) & 0x01)) - color = data[0] & 0x0F; - else - color = data[1] & 0x0F; - - ai = ci + x + (stride * (ri + y)); - if (b) - color ^= buf[ai]; - buf[ai] = color; - } - } - - return 0; -} - -#define UP 2 -#define DOWN 1 -#define LEFT 2 -#define RIGHT 1 - -static void cdg_copy_rect_buf(int out_tl_x, int out_tl_y, uint8_t *out, - int in_tl_x, int in_tl_y, uint8_t *in, - int w, int h, int stride) -{ - int y; - - in += in_tl_x + in_tl_y * stride; - out += out_tl_x + out_tl_y * stride; - for (y = 0; y < h; y++) - memcpy(out + y * stride, in + y * stride, w); -} - -static void cdg_fill_rect_preset(int tl_x, int tl_y, uint8_t *out, - int color, int w, int h, int stride) -{ - int y; - - for (y = tl_y; y < tl_y + h; y++) - memset(out + tl_x + y * stride, color, w); -} - -static void cdg_fill_wrapper(int out_tl_x, int out_tl_y, uint8_t *out, - int in_tl_x, int in_tl_y, uint8_t *in, - int color, int w, int h, int stride, int roll) -{ - if (roll) { - cdg_copy_rect_buf(out_tl_x, out_tl_y, out, in_tl_x, in_tl_y, - in, w, h, stride); - } else { - cdg_fill_rect_preset(out_tl_x, out_tl_y, out, color, w, h, stride); - } -} - -static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, - AVFrame *new_frame, int roll_over) -{ - int color; - int hscmd, h_off, hinc, vscmd, v_off, vinc; - int y; - int stride = cc->frame.linesize[0]; - uint8_t *in = cc->frame.data[0]; - uint8_t *out = new_frame->data[0]; - - color = data[0] & 0x0F; - hscmd = (data[1] & 0x30) >> 4; - vscmd = (data[2] & 0x30) >> 4; - - h_off = FFMIN(data[1] & 0x07, CDG_BORDER_WIDTH - 1); - v_off = FFMIN(data[2] & 0x07, CDG_BORDER_HEIGHT - 1); - - /// find the difference and save the offset for cdg_tile_block usage - hinc = h_off - cc->hscroll; - vinc = v_off - cc->vscroll; - cc->hscroll = h_off; - cc->vscroll = v_off; - - if (vscmd == UP) - vinc -= 12; - if (vscmd == DOWN) - vinc += 12; - if (hscmd == LEFT) - hinc -= 6; - if (hscmd == RIGHT) - hinc += 6; - - if (!hinc && !vinc) - return; - - memcpy(new_frame->data[1], cc->frame.data[1], CDG_PALETTE_SIZE * 4); - - for (y = FFMAX(0, vinc); y < FFMIN(CDG_FULL_HEIGHT + vinc, CDG_FULL_HEIGHT); y++) - memcpy(out + FFMAX(0, hinc) + stride * y, - in + FFMAX(0, hinc) - hinc + (y - vinc) * stride, - FFMIN(stride + hinc, stride)); - - if (vinc > 0) - cdg_fill_wrapper(0, 0, out, - 0, CDG_FULL_HEIGHT - vinc, in, color, - stride, vinc, stride, roll_over); - else if (vinc < 0) - cdg_fill_wrapper(0, CDG_FULL_HEIGHT + vinc, out, - 0, 0, in, color, - stride, -1 * vinc, stride, roll_over); - - if (hinc > 0) - cdg_fill_wrapper(0, 0, out, - CDG_FULL_WIDTH - hinc, 0, in, color, - hinc, CDG_FULL_HEIGHT, stride, roll_over); - else if (hinc < 0) - cdg_fill_wrapper(CDG_FULL_WIDTH + hinc, 0, out, - 0, 0, in, color, - -1 * hinc, CDG_FULL_HEIGHT, stride, roll_over); - -} - -static int cdg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - int ret; - uint8_t command, inst; - uint8_t cdg_data[CDG_DATA_SIZE]; - AVFrame new_frame; - CDGraphicsContext *cc = avctx->priv_data; - - if (buf_size < CDG_MINIMUM_PKT_SIZE) { - av_log(avctx, AV_LOG_ERROR, "buffer too small for decoder\n"); - return AVERROR(EINVAL); - } - - ret = avctx->reget_buffer(avctx, &cc->frame); - if (ret) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return ret; - } - - command = bytestream_get_byte(&buf); - inst = bytestream_get_byte(&buf); - inst &= CDG_MASK; - buf += 2; /// skipping 2 unneeded bytes - bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE); - - if ((command & CDG_MASK) == CDG_COMMAND) { - switch (inst) { - case CDG_INST_MEMORY_PRESET: - if (!(cdg_data[1] & 0x0F)) - memset(cc->frame.data[0], cdg_data[0] & 0x0F, - cc->frame.linesize[0] * CDG_FULL_HEIGHT); - break; - case CDG_INST_LOAD_PAL_LO: - case CDG_INST_LOAD_PAL_HIGH: - if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) { - av_log(avctx, AV_LOG_ERROR, "buffer too small for loading palette\n"); - return AVERROR(EINVAL); - } - - cdg_load_palette(cc, cdg_data, inst == CDG_INST_LOAD_PAL_LO); - break; - case CDG_INST_BORDER_PRESET: - cdg_border_preset(cc, cdg_data); - break; - case CDG_INST_TILE_BLOCK_XOR: - case CDG_INST_TILE_BLOCK: - if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) { - av_log(avctx, AV_LOG_ERROR, "buffer too small for drawing tile\n"); - return AVERROR(EINVAL); - } - - ret = cdg_tile_block(cc, cdg_data, inst == CDG_INST_TILE_BLOCK_XOR); - if (ret) { - av_log(avctx, AV_LOG_ERROR, "tile is out of range\n"); - return ret; - } - break; - case CDG_INST_SCROLL_PRESET: - case CDG_INST_SCROLL_COPY: - if (buf_size - CDG_HEADER_SIZE < CDG_MINIMUM_SCROLL_SIZE) { - av_log(avctx, AV_LOG_ERROR, "buffer too small for scrolling\n"); - return AVERROR(EINVAL); - } - - cdg_init_frame(&new_frame); - ret = avctx->get_buffer(avctx, &new_frame); - if (ret) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return ret; - } - - cdg_scroll(cc, cdg_data, &new_frame, inst == CDG_INST_SCROLL_COPY); - avctx->release_buffer(avctx, &cc->frame); - cc->frame = new_frame; - break; - default: - break; - } - - *data_size = sizeof(AVFrame); - } else { - *data_size = 0; - buf_size = 0; - } - - *(AVFrame *) data = cc->frame; - return buf_size; -} - -static av_cold int cdg_decode_end(AVCodecContext *avctx) -{ - CDGraphicsContext *cc = avctx->priv_data; - - if (cc->frame.data[0]) - avctx->release_buffer(avctx, &cc->frame); - - return 0; -} - -AVCodec cdgraphics_decoder = { - "cdgraphics", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CDGRAPHICS, - sizeof(CDGraphicsContext), - cdg_decode_init, - NULL, - cdg_decode_end, - cdg_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("CD Graphics video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/celp_filters.c b/tizen/distrib/ffmpeg/libavcodec/celp_filters.c deleted file mode 100644 index 26a62ee..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/celp_filters.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * various filters for ACELP-based codecs - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "avcodec.h" -#include "celp_filters.h" - -void ff_celp_convolve_circ(int16_t* fc_out, const int16_t* fc_in, - const int16_t* filter, int len) -{ - int i, k; - - memset(fc_out, 0, len * sizeof(int16_t)); - - /* Since there are few pulses over an entire subframe (i.e. almost - all fc_in[i] are zero) it is faster to loop over fc_in first. */ - for (i = 0; i < len; i++) { - if (fc_in[i]) { - for (k = 0; k < i; k++) - fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15; - - for (k = i; k < len; k++) - fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15; - } - } -} - -void ff_celp_circ_addf(float *out, const float *in, - const float *lagged, int lag, float fac, int n) -{ - int k; - for (k = 0; k < lag; k++) - out[k] = in[k] + fac * lagged[n + k - lag]; - for (; k < n; k++) - out[k] = in[k] + fac * lagged[ k - lag]; -} - -int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs, - const int16_t *in, int buffer_length, - int filter_length, int stop_on_overflow, - int rounder) -{ - int i,n; - - for (n = 0; n < buffer_length; n++) { - int sum = rounder; - for (i = 1; i <= filter_length; i++) - sum -= filter_coeffs[i-1] * out[n-i]; - - sum = (sum >> 12) + in[n]; - - if (sum + 0x8000 > 0xFFFFU) { - if (stop_on_overflow) - return 1; - sum = (sum >> 31) ^ 32767; - } - out[n] = sum; - } - - return 0; -} - -void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, - const float* in, int buffer_length, - int filter_length) -{ - int i,n; - -#if 0 // Unoptimized code path for improved readability - for (n = 0; n < buffer_length; n++) { - out[n] = in[n]; - for (i = 1; i <= filter_length; i++) - out[n] -= filter_coeffs[i-1] * out[n-i]; - } -#else - float out0, out1, out2, out3; - float old_out0, old_out1, old_out2, old_out3; - float a,b,c; - - a = filter_coeffs[0]; - b = filter_coeffs[1]; - c = filter_coeffs[2]; - b -= filter_coeffs[0] * filter_coeffs[0]; - c -= filter_coeffs[1] * filter_coeffs[0]; - c -= filter_coeffs[0] * b; - - old_out0 = out[-4]; - old_out1 = out[-3]; - old_out2 = out[-2]; - old_out3 = out[-1]; - for (n = 0; n <= buffer_length - 4; n+=4) { - float tmp0,tmp1,tmp2,tmp3; - float val; - - out0 = in[0]; - out1 = in[1]; - out2 = in[2]; - out3 = in[3]; - - out0 -= filter_coeffs[2] * old_out1; - out1 -= filter_coeffs[2] * old_out2; - out2 -= filter_coeffs[2] * old_out3; - - out0 -= filter_coeffs[1] * old_out2; - out1 -= filter_coeffs[1] * old_out3; - - out0 -= filter_coeffs[0] * old_out3; - - val = filter_coeffs[3]; - - out0 -= val * old_out0; - out1 -= val * old_out1; - out2 -= val * old_out2; - out3 -= val * old_out3; - - old_out3 = out[-5]; - - for (i = 5; i <= filter_length; i += 2) { - val = filter_coeffs[i-1]; - - out0 -= val * old_out3; - out1 -= val * old_out0; - out2 -= val * old_out1; - out3 -= val * old_out2; - - old_out2 = out[-i-1]; - - val = filter_coeffs[i]; - - out0 -= val * old_out2; - out1 -= val * old_out3; - out2 -= val * old_out0; - out3 -= val * old_out1; - - FFSWAP(float, old_out0, old_out2); - old_out1 = old_out3; - old_out3 = out[-i-2]; - } - - tmp0 = out0; - tmp1 = out1; - tmp2 = out2; - tmp3 = out3; - - out3 -= a * tmp2; - out2 -= a * tmp1; - out1 -= a * tmp0; - - out3 -= b * tmp1; - out2 -= b * tmp0; - - out3 -= c * tmp0; - - - out[0] = out0; - out[1] = out1; - out[2] = out2; - out[3] = out3; - - old_out0 = out0; - old_out1 = out1; - old_out2 = out2; - old_out3 = out3; - - out += 4; - in += 4; - } - - out -= n; - in -= n; - for (; n < buffer_length; n++) { - out[n] = in[n]; - for (i = 1; i <= filter_length; i++) - out[n] -= filter_coeffs[i-1] * out[n-i]; - } -#endif -} - -void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs, - const float *in, int buffer_length, - int filter_length) -{ - int i,n; - - for (n = 0; n < buffer_length; n++) { - out[n] = in[n]; - for (i = 1; i <= filter_length; i++) - out[n] += filter_coeffs[i-1] * in[n-i]; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/celp_filters.h b/tizen/distrib/ffmpeg/libavcodec/celp_filters.h deleted file mode 100644 index 7b64fc0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/celp_filters.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * various filters for CELP-based codecs - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CELP_FILTERS_H -#define AVCODEC_CELP_FILTERS_H - -#include - -/** - * Circularly convolve fixed vector with a phase dispersion impulse - * response filter (D.6.2 of G.729 and 6.1.5 of AMR). - * @param fc_out vector with filter applied - * @param fc_in source vector - * @param filter phase filter coefficients - * - * fc_out[n] = sum(i,0,len-1){ fc_in[i] * filter[(len + n - i)%len] } - * - * \note fc_in and fc_out should not overlap! - */ -void ff_celp_convolve_circ(int16_t *fc_out, const int16_t *fc_in, - const int16_t *filter, int len); - -/** - * Add an array to a rotated array. - * - * out[k] = in[k] + fac * lagged[k-lag] with wrap-around - * - * @param out result vector - * @param in samples to be added unfiltered - * @param lagged samples to be rotated, multiplied and added - * @param lag lagged vector delay in the range [0, n] - * @param fac scalefactor for lagged samples - * @param n number of samples - */ -void ff_celp_circ_addf(float *out, const float *in, - const float *lagged, int lag, float fac, int n); - -/** - * LP synthesis filter. - * @param out [out] pointer to output buffer - * @param filter_coeffs filter coefficients (-0x8000 <= (3.12) < 0x8000) - * @param in input signal - * @param buffer_length amount of data to process - * @param filter_length filter length (10 for 10th order LP filter) - * @param stop_on_overflow 1 - return immediately if overflow occurs - * 0 - ignore overflows - * @param rounder the amount to add for rounding (usually 0x800 or 0xfff) - * - * @return 1 if overflow occurred, 0 - otherwise - * - * @note Output buffer must contain filter_length samples of past - * speech data before pointer. - * - * Routine applies 1/A(z) filter to given speech data. - */ -int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs, - const int16_t *in, int buffer_length, - int filter_length, int stop_on_overflow, - int rounder); - -/** - * LP synthesis filter. - * @param out [out] pointer to output buffer - * - the array out[-filter_length, -1] must - * contain the previous result of this filter - * @param filter_coeffs filter coefficients. - * @param in input signal - * @param buffer_length amount of data to process - * @param filter_length filter length (10 for 10th order LP filter). Must be - * greater than 4 and even. - * - * @note Output buffer must contain filter_length samples of past - * speech data before pointer. - * - * Routine applies 1/A(z) filter to given speech data. - */ -void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, - const float *in, int buffer_length, - int filter_length); - -/** - * LP zero synthesis filter. - * @param out [out] pointer to output buffer - * @param filter_coeffs filter coefficients. - * @param in input signal - * - the array in[-filter_length, -1] must - * contain the previous input of this filter - * @param buffer_length amount of data to process - * @param filter_length filter length (10 for 10th order LP filter) - * - * @note Output buffer must contain filter_length samples of past - * speech data before pointer. - * - * Routine applies A(z) filter to given speech data. - */ -void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs, - const float *in, int buffer_length, - int filter_length); - -#endif /* AVCODEC_CELP_FILTERS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/celp_math.c b/tizen/distrib/ffmpeg/libavcodec/celp_math.c deleted file mode 100644 index 09111da..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/celp_math.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Various fixed-point math operations - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include "avcodec.h" -#include "celp_math.h" - -#ifdef G729_BITEXACT -/** - * Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64) - */ -static const int16_t base_cos[64] = -{ - 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, - 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, - 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, - 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, - 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, - -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, - -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, - -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729 -}; - -/** - * Slope used to compute cos(x) - * - * cos(ind*64+offset) = base_cos[ind]+offset*slope_cos[ind] - * values multiplied by 1<<19 - */ -static const int16_t slope_cos[64] = -{ - -632, -1893, -3150, -4399, -5638, -6863, -8072, -9261, - -10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744, - -18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526, - -24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726, - -25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009, - -23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637, - -17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428, - -9261, -8072, -6863, -5638, -4399, -3150, -1893, -632 -}; - -/** - * Table used to compute exp2(x) - * - * tab_exp2[i] = (1<<14) * exp2(i/32) = 2^(i/32) i=0..32 - */ -static const uint16_t tab_exp2[33] = -{ - 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911, - 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726, - 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706, - 31379, 32066, 32767 -}; - -int16_t ff_cos(uint16_t arg) -{ - uint8_t offset= arg; - uint8_t ind = arg >> 8; - - assert(arg < 0x4000); - - return FFMAX(base_cos[ind] + ((slope_cos[ind] * offset) >> 12), -0x8000); -} - -int ff_exp2(uint16_t power) -{ - uint16_t frac_x0; - uint16_t frac_dx; - int result; - - assert(power <= 0x7fff); - - frac_x0 = power >> 10; - frac_dx = (power & 0x03ff) << 5; - - result = tab_exp2[frac_x0] << 15; - result += frac_dx * (tab_exp2[frac_x0+1] - tab_exp2[frac_x0]); - - return result >> 10; -} - -#else // G729_BITEXACT - -/** - * Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64) - */ -static const int16_t tab_cos[65] = -{ - 32767, 32738, 32617, 32421, 32145, 31793, 31364, 30860, - 30280, 29629, 28905, 28113, 27252, 26326, 25336, 24285, - 23176, 22011, 20793, 19525, 18210, 16851, 15451, 14014, - 12543, 11043, 9515, 7965, 6395, 4810, 3214, 1609, - 1, -1607, -3211, -4808, -6393, -7962, -9513, -11040, - -12541, -14012, -15449, -16848, -18207, -19523, -20791, -22009, - -23174, -24283, -25334, -26324, -27250, -28111, -28904, -29627, - -30279, -30858, -31363, -31792, -32144, -32419, -32616, -32736, -32768, -}; - -static const uint16_t exp2a[]= -{ - 0, 1435, 2901, 4400, 5931, 7496, 9096, 10730, - 12400, 14106, 15850, 17632, 19454, 21315, 23216, 25160, - 27146, 29175, 31249, 33368, 35534, 37747, 40009, 42320, - 44682, 47095, 49562, 52082, 54657, 57289, 59979, 62727, -}; - -static const uint16_t exp2b[]= -{ - 3, 712, 1424, 2134, 2845, 3557, 4270, 4982, - 5696, 6409, 7124, 7839, 8554, 9270, 9986, 10704, - 11421, 12138, 12857, 13576, 14295, 15014, 15734, 16455, - 17176, 17898, 18620, 19343, 20066, 20790, 21514, 22238, -}; - -int16_t ff_cos(uint16_t arg) -{ - uint8_t offset= arg; - uint8_t ind = arg >> 8; - - assert(arg <= 0x3fff); - - return tab_cos[ind] + (offset * (tab_cos[ind+1] - tab_cos[ind]) >> 8); -} - -int ff_exp2(uint16_t power) -{ - unsigned int result= exp2a[power>>10] + 0x10000; - - assert(power <= 0x7fff); - - result= (result<<3) + ((result*exp2b[(power>>5)&31])>>17); - return result + ((result*(power&31)*89)>>22); -} - -#endif // else G729_BITEXACT - -/** - * Table used to compute log2(x) - * - * tab_log2[i] = (1<<15) * log2(1 + i/32), i=0..32 - */ -static const uint16_t tab_log2[33] = -{ -#ifdef G729_BITEXACT - 0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, - 10549, 11716, 12855, 13967, 15054, 16117, 17156, 18172, - 19167, 20142, 21097, 22033, 22951, 23852, 24735, 25603, - 26455, 27291, 28113, 28922, 29716, 30497, 31266, 32023, 32767, -#else - 4, 1459, 2870, 4240, 5572, 6867, 8127, 9355, - 10552, 11719, 12858, 13971, 15057, 16120, 17158, 18175, - 19170, 20145, 21100, 22036, 22954, 23854, 24738, 25605, - 26457, 27294, 28116, 28924, 29719, 30500, 31269, 32025, 32769, -#endif -}; - -int ff_log2(uint32_t value) -{ - uint8_t power_int; - uint8_t frac_x0; - uint16_t frac_dx; - - // Stripping zeros from beginning - power_int = av_log2(value); - value <<= (31 - power_int); - - // b31 is always non-zero now - frac_x0 = (value & 0x7c000000) >> 26; // b26-b31 and [32..63] -> [0..31] - frac_dx = (value & 0x03fff800) >> 11; - - value = tab_log2[frac_x0]; - value += (frac_dx * (tab_log2[frac_x0+1] - tab_log2[frac_x0])) >> 15; - - return (power_int << 15) + value; -} - -float ff_dot_productf(const float* a, const float* b, int length) -{ - float sum = 0; - int i; - - for(i=0; i - -/** - * fixed-point implementation of cosine in [0; PI) domain. - * @param arg fixed-point cosine argument, 0 <= arg < 0x4000 - * - * @return value of (1<<15) * cos(arg * PI / (1<<14)), -0x8000 <= result <= 0x7fff - */ -int16_t ff_cos(uint16_t arg); - -/** - * fixed-point implementation of exp2(x) in [0; 1] domain. - * @param power argument to exp2, 0 <= power <= 0x7fff - * - * @return value of (1<<20) * exp2(power / (1<<15)) - * 0x8000c <= result <= 0xfffea - */ -int ff_exp2(uint16_t power); - -/** - * Calculates log2(x). - * @param value function argument, 0 < value <= 7fff ffff - * - * @return value of (1<<15) * log2(value) - */ -int ff_log2(uint32_t value); - -/** - * Shift value left or right depending on sign of offset parameter. - * @param value value to shift - * @param offset shift offset - * - * @return value << offset, if offset>=0; value >> -offset - otherwise - */ -static inline int bidir_sal(int value, int offset) -{ - if(offset < 0) return value >> -offset; - else return value << offset; -} - -/** - * returns the dot product. - * @param a input data array - * @param b input data array - * @param length number of elements - * - * @return dot product = sum of elementwise products - */ -float ff_dot_productf(const float* a, const float* b, int length); - -#endif /* AVCODEC_CELP_MATH_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/cga_data.c b/tizen/distrib/ffmpeg/libavcodec/cga_data.c deleted file mode 100644 index 2d1f89c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cga_data.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * CGA ROM data - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -const uint8_t ff_cga_font[2048] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, - 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, - 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, - 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, - 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, - 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, - 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, - 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, - 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, - 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, - 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, - 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, - 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, - 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, - 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, - 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, - 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, - 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, - 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, - 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, - 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, - 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, - 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, - 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, - 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, - 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, - 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, - 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, - 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, - 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, - 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, - 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, - 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, - 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, - 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, - 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, - 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, - 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, - 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, - 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, - 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, - 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, - 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, - 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, - 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const uint32_t ff_cga_palette[16] = { - 0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA, - 0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/cga_data.h b/tizen/distrib/ffmpeg/libavcodec/cga_data.h deleted file mode 100644 index c3f69f1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cga_data.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * CGA ROM data - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CGA_DATA_H -#define AVCODEC_CGA_DATA_H - -#include - -extern const uint8_t ff_cga_font[2048]; -extern const uint32_t ff_cga_palette[16]; - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/cinepak.c b/tizen/distrib/ffmpeg/libavcodec/cinepak.c deleted file mode 100644 index 8e7aa5a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cinepak.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Cinepak Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Cinepak video decoder - * by Ewald Snel - * For more information on the Cinepak algorithm, visit: - * http://www.csse.monash.edu.au/~timf/ - * For more information on the quirky data inside Sega FILM/CPK files, visit: - * http://wiki.multimedia.cx/index.php?title=Sega_FILM - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - - -typedef struct { - uint8_t y0, y1, y2, y3; - uint8_t u, v; -} cvid_codebook; - -#define MAX_STRIPS 32 - -typedef struct { - uint16_t id; - uint16_t x1, y1; - uint16_t x2, y2; - cvid_codebook v4_codebook[256]; - cvid_codebook v1_codebook[256]; -} cvid_strip; - -typedef struct CinepakContext { - - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *data; - int size; - - int width, height; - - int palette_video; - cvid_strip strips[MAX_STRIPS]; - - int sega_film_skip_bytes; - -} CinepakContext; - -static void cinepak_decode_codebook (cvid_codebook *codebook, - int chunk_id, int size, const uint8_t *data) -{ - const 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 & 0x04) ? 4 : 6; - flag = 0; - mask = 0; - - for (i=0; i < 256; i++) { - if ((chunk_id & 0x01) && !(mask >>= 1)) { - if ((data + 4) > eod) - break; - - flag = AV_RB32 (data); - data += 4; - mask = 0x80000000; - } - - if (!(chunk_id & 0x01) || (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 *strip, - int chunk_id, int size, const uint8_t *data) -{ - const uint8_t *eod = (data + size); - uint32_t flag, mask; - cvid_codebook *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 & 0x01) && !(mask >>= 1)) { - if ((data + 4) > eod) - return -1; - - flag = AV_RB32 (data); - data += 4; - mask = 0x80000000; - } - - if (!(chunk_id & 0x01) || (flag & mask)) { - if (!(chunk_id & 0x02) && !(mask >>= 1)) { - if ((data + 4) > eod) - return -1; - - flag = AV_RB32 (data); - data += 4; - mask = 0x80000000; - } - - if ((chunk_id & 0x02) || (~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 *strip, const uint8_t *data, int size) -{ - const 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 = data[0]; - chunk_size = AV_RB24 (&data[1]) - 4; - if(chunk_size < 0) - return -1; - - data += 4; - chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size; - - switch (chunk_id) { - - case 0x20: - case 0x21: - case 0x24: - case 0x25: - cinepak_decode_codebook (strip->v4_codebook, chunk_id, - chunk_size, data); - break; - - case 0x22: - case 0x23: - case 0x26: - case 0x27: - cinepak_decode_codebook (strip->v1_codebook, chunk_id, - chunk_size, data); - break; - - case 0x30: - case 0x31: - case 0x32: - return cinepak_decode_vectors (s, strip, chunk_id, - chunk_size, data); - } - - data += chunk_size; - } - - return -1; -} - -static int cinepak_decode (CinepakContext *s) -{ - const uint8_t *eod = (s->data + s->size); - int i, result, strip_size, frame_flags, num_strips; - int y0 = 0; - int encoded_buf_size; - - if (s->size < 10) - return -1; - - frame_flags = s->data[0]; - num_strips = AV_RB16 (&s->data[8]); - encoded_buf_size = ((s->data[1] << 16) | AV_RB16 (&s->data[2])); - - /* if this is the first frame, check for deviant Sega FILM data */ - if (s->sega_film_skip_bytes == -1) { - if (encoded_buf_size != s->size) { - /* If the encoded frame size differs from the frame size as indicated - * by the container file, this data likely comes from a Sega FILM/CPK file. - * If the frame header is followed by the bytes FE 00 00 06 00 00 then - * this is probably one of the two known files that have 6 extra bytes - * after the frame header. Else, assume 2 extra bytes. */ - if ((s->data[10] == 0xFE) && - (s->data[11] == 0x00) && - (s->data[12] == 0x00) && - (s->data[13] == 0x06) && - (s->data[14] == 0x00) && - (s->data[15] == 0x00)) - s->sega_film_skip_bytes = 6; - else - s->sega_film_skip_bytes = 2; - } else - s->sega_film_skip_bytes = 0; - } - - s->data += 10 + s->sega_film_skip_bytes; - - 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 = s->data[0]; - s->strips[i].y1 = y0; - s->strips[i].x1 = 0; - s->strips[i].y2 = y0 + AV_RB16 (&s->data[8]); - s->strips[i].x2 = s->avctx->width; - - strip_size = AV_RB24 (&s->data[1]) - 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 av_cold int cinepak_decode_init(AVCodecContext *avctx) -{ - CinepakContext *s = avctx->priv_data; - - s->avctx = avctx; - s->width = (avctx->width + 3) & ~3; - s->height = (avctx->height + 3) & ~3; - s->sega_film_skip_bytes = -1; /* uninitialized state */ - - // check for paletted data - if ((avctx->palctrl == NULL) || (avctx->bits_per_coded_sample == 40)) { - s->palette_video = 0; - avctx->pix_fmt = PIX_FMT_YUV420P; - } else { - s->palette_video = 1; - avctx->pix_fmt = PIX_FMT_PAL8; - } - - s->frame.data[0] = NULL; - - return 0; -} - -static int cinepak_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - CinepakContext *s = 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 av_cold int cinepak_decode_end(AVCodecContext *avctx) -{ - CinepakContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec cinepak_decoder = { - "cinepak", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CINEPAK, - sizeof(CinepakContext), - cinepak_decode_init, - NULL, - cinepak_decode_end, - cinepak_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Cinepak"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/cljr.c b/tizen/distrib/ffmpeg/libavcodec/cljr.c deleted file mode 100644 index 47809c0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cljr.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Cirrus Logic AccuPak (CLJR) codec - * Copyright (c) 2003 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Cirrus Logic AccuPak codec. - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" - -/* Disable the encoder. */ -#undef CONFIG_CLJR_ENCODER -#define CONFIG_CLJR_ENCODER 0 - -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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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= FF_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 CONFIG_CLJR_ENCODER -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; - - *p = *pict; - p->pict_type= FF_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 av_cold void common_init(AVCodecContext *avctx){ - CLJRContext * const a = avctx->priv_data; - - avctx->coded_frame= (AVFrame*)&a->picture; - a->avctx= avctx; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - - common_init(avctx); - - avctx->pix_fmt= PIX_FMT_YUV411P; - - return 0; -} - -#if CONFIG_CLJR_ENCODER -static av_cold int encode_init(AVCodecContext *avctx){ - - common_init(avctx); - - return 0; -} -#endif - -AVCodec cljr_decoder = { - "cljr", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CLJR, - sizeof(CLJRContext), - decode_init, - NULL, - NULL, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), -}; - -#if CONFIG_CLJR_ENCODER -AVCodec cljr_encoder = { - "cljr", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CLJR, - sizeof(CLJRContext), - encode_init, - encode_frame, - //encode_end, - .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/colorspace.h b/tizen/distrib/ffmpeg/libavcodec/colorspace.h deleted file mode 100644 index 4ec081e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/colorspace.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Colorspace conversion defines - * Copyright (c) 2001, 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Various defines for YUV<->RGB conversion - */ - -#ifndef AVCODEC_COLORSPACE_H -#define AVCODEC_COLORSPACE_H - -#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) - -#endif /* AVCODEC_COLORSPACE_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/cook.c b/tizen/distrib/ffmpeg/libavcodec/cook.c deleted file mode 100644 index e406e65..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cook.c +++ /dev/null @@ -1,1298 +0,0 @@ -/* - * COOK compatible decoder - * Copyright (c) 2003 Sascha Sommer - * Copyright (c) 2005 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Cook compatible decoder. Bastardization of the G.722.1 standard. - * 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 - -#include "libavutil/lfg.h" -#include "libavutil/random_seed.h" -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "bytestream.h" -#include "fft.h" - -#include "cookdata.h" - -/* the different Cook versions */ -#define MONO 0x1000001 -#define STEREO 0x1000002 -#define JOINT_STEREO 0x1000003 -#define MC_COOK 0x2000000 //multichannel Cook, not supported - -#define SUBBAND_SIZE 20 -#define MAX_SUBPACKETS 5 -//#define COOKDEBUG - -typedef struct { - int *now; - int *previous; -} cook_gains; - -typedef struct { - int ch_idx; - int size; - int num_channels; - int cookversion; - int samples_per_frame; - int subbands; - int js_subband_start; - int js_vlc_bits; - int samples_per_channel; - int log2_numvector_size; - unsigned int channel_mask; - VLC ccpl; ///< channel coupling - int joint_stereo; - int bits_per_subpacket; - int bits_per_subpdiv; - int total_subbands; - int numvector_size; ///< 1 << log2_numvector_size; - - float mono_previous_buffer1[1024]; - float mono_previous_buffer2[1024]; - /** gain buffers */ - cook_gains gains1; - cook_gains gains2; - int gain_1[9]; - int gain_2[9]; - int gain_3[9]; - int gain_4[9]; -} COOKSubpacket; - -typedef struct cook { - /* - * The following 5 functions provide the lowlevel arithmetic on - * the internal audio buffers. - */ - void (* scalar_dequant)(struct cook *q, int index, int quant_index, - int* subband_coef_index, int* subband_coef_sign, - float* mlt_p); - - void (* decouple) (struct cook *q, - COOKSubpacket *p, - int subband, - float f1, float f2, - float *decode_buffer, - float *mlt_buffer1, float *mlt_buffer2); - - void (* imlt_window) (struct cook *q, float *buffer1, - cook_gains *gains_ptr, float *previous_buffer); - - void (* interpolate) (struct cook *q, float* buffer, - int gain_index, int gain_index_next); - - void (* saturate_output) (struct cook *q, int chan, int16_t *out); - - AVCodecContext* avctx; - GetBitContext gb; - /* stream data */ - int nb_channels; - int bit_rate; - int sample_rate; - int num_vectors; - int samples_per_channel; - /* states */ - AVLFG random_state; - - /* transform data */ - FFTContext mdct_ctx; - float* mlt_window; - - /* VLC data */ - VLC envelope_quant_index[13]; - VLC sqvh[7]; //scalar quantization - - /* generatable tables and related variables */ - int gain_size_factor; - float gain_table[23]; - - /* data buffers */ - - uint8_t* decoded_bytes_buffer; - DECLARE_ALIGNED(16, float,mono_mdct_output)[2048]; - float decode_buffer_1[1024]; - float decode_buffer_2[1024]; - float decode_buffer_0[1060]; /* static allocation for joint decode */ - - const float *cplscales[5]; - int num_subpackets; - COOKSubpacket subpacket[MAX_SUBPACKETS]; -} COOKContext; - -static float pow2tab[127]; -static float rootpow2tab[127]; - -/* 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 ; igain_size_factor = q->samples_per_channel/8; - for (i=0 ; i<23 ; i++) { - q->gain_table[i] = pow(pow2tab[i+52] , - (1.0/(double)q->gain_size_factor)); - } -} - - -static av_cold 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(q->avctx,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); - } - - for(i=0;inum_subpackets;i++){ - if (q->subpacket[i].joint_stereo==1){ - result |= init_vlc (&q->subpacket[i].ccpl, 6, (1<subpacket[i].js_vlc_bits)-1, - ccpl_huffbits[q->subpacket[i].js_vlc_bits-2], 1, 1, - ccpl_huffcodes[q->subpacket[i].js_vlc_bits-2], 2, 2, 0); - av_log(q->avctx,AV_LOG_DEBUG,"subpacket %i Joint-stereo VLC used.\n",i); - } - } - - av_log(q->avctx,AV_LOG_DEBUG,"VLC tables initialized.\n"); - return result; -} - -static av_cold int init_cook_mlt(COOKContext *q) { - int j; - int mlt_size = q->samples_per_channel; - - if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0) - return -1; - - /* Initialize the MLT window: simple sine window. */ - ff_sine_window_init(q->mlt_window, mlt_size); - for(j=0 ; jmlt_window[j] *= sqrt(2.0 / q->samples_per_channel); - - /* Initialize the MDCT. */ - if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1, 1.0)) { - av_free(q->mlt_window); - return -1; - } - av_log(q->avctx,AV_LOG_DEBUG,"MDCT initialized, order = %d.\n", - av_log2(mlt_size)+1); - - return 0; -} - -static const float *maybe_reformat_buffer32 (COOKContext *q, const float *ptr, int n) -{ - if (1) - return ptr; -} - -static av_cold void init_cplscales_table (COOKContext *q) { - int i; - for (i=0;i<5;i++) - q->cplscales[i] = maybe_reformat_buffer32 (q, cplscales[i], (1<<(i+2))-1); -} - -/*************** init functions end ***********/ - -/** - * Cook indata decoding, every 32 bits are XORed with 0x37c511f2. - * Why? No idea, some checksum/error detection method maybe. - * - * Out buffer size: extra bytes are needed to cope with - * padding/misalignment. - * Subpackets passed to the decoder can contain two, consecutive - * half-subpackets, of identical but arbitrary size. - * 1234 1234 1234 1234 extraA extraB - * Case 1: AAAA BBBB 0 0 - * Case 2: AAAA ABBB BB-- 3 3 - * Case 3: AAAA AABB BBBB 2 2 - * Case 4: AAAA AAAB BBBB BB-- 1 5 - * - * Nice way to waste CPU cycles. - * - * @param inbuffer pointer to byte array of indata - * @param out pointer to byte array of outdata - * @param bytes number of bytes - */ -#define DECODE_BYTES_PAD1(bytes) (3 - ((bytes)+3) % 4) -#define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) - -static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ - int i, off; - uint32_t c; - const uint32_t* buf; - 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 ; i> (off*8)) | (0x37c511f2 << (32-(off*8)))); - bytes += 3 + off; - for (i = 0; i < bytes/4; i++) - obuf[i] = c ^ buf[i]; - - return off; -} - -/** - * Cook uninit - */ - -static av_cold int cook_decode_close(AVCodecContext *avctx) -{ - int i; - COOKContext *q = avctx->priv_data; - av_log(avctx,AV_LOG_DEBUG, "Deallocating memory.\n"); - - /* Free allocated memory buffers. */ - av_free(q->mlt_window); - av_free(q->decoded_bytes_buffer); - - /* Free the transform. */ - ff_mdct_end(&q->mdct_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]); - } - for (i=0 ; inum_subpackets ; i++) { - free_vlc(&q->subpacket[i].ccpl); - } - - av_log(avctx,AV_LOG_DEBUG,"Memory deallocated.\n"); - - return 0; -} - -/** - * Fill the gain array for the timedomain quantization. - * - * @param q pointer to the COOKContext - * @param gaininfo[9] array of gain indexes - */ - -static void decode_gain_info(GetBitContext *gb, int *gaininfo) -{ - int i, n; - - while (get_bits1(gb)) {} - n = get_bits_count(gb) - 1; //amount of elements*2 to update - - i = 0; - while (n--) { - int index = get_bits(gb, 3); - int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1; - - while (i <= index) gaininfo[i++] = gain; - } - while (i <= 8) gaininfo[i++] = 0; -} - -/** - * 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, COOKSubpacket *p, int* quant_index_table) { - int i,j, vlc_index; - - quant_index_table[0]= get_bits(&q->gb,6) - 6; //This is used later in categorize - - for (i=1 ; i < p->total_subbands ; i++){ - vlc_index=i; - if (i >= p->js_subband_start * 2) { - vlc_index-=p->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 - } -} - -/** - * 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, COOKSubpacket *p, int* quant_index_table, - int* category, int* category_index){ - int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j; - int exp_index2[102]; - int exp_index1[102]; - - int tmp_categorize_array[128*2]; - int tmp_categorize_array1_idx=p->numvector_size; - int tmp_categorize_array2_idx=p->numvector_size; - - bits_left = p->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(q->avctx, 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_array,0,128*2*sizeof(int)); - - bias=-32; - - /* Estimate bias. */ - for (i=32 ; i>0 ; i=i/2){ - num_bits = 0; - index = 0; - for (j=p->total_subbands ; j>0 ; j--){ - exp_idx = av_clip((i - quant_index_table[index] + bias) / 2, 0, 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 = av_clip((bias - quant_index_table[i]) / 2, 0, 7); - num_bits += expbits_tab[exp_idx]; - exp_index1[i] = exp_idx; - exp_index2[i] = exp_idx; - } - tmpbias1 = tmpbias2 = num_bits; - - for (j = 1 ; j < p->numvector_size ; j++) { - if (tmpbias1 + tmpbias2 > 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] + bias; - if ( v >= max) { - max = v; - index = i; - } - } - } - if(index==-1)break; - tmp_categorize_array[tmp_categorize_array1_idx++] = index; - tmpbias1 -= 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]+bias; - if ( v < min) { - min = v; - index = i; - } - } - } - if(index == -1)break; - tmp_categorize_array[--tmp_categorize_array2_idx] = index; - tmpbias2 -= 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]; - - for(i=0 ; inumvector_size-1 ; i++) - category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++]; - -} - - -/** - * 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 inline void 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 quant_index quantisation index - * @param subband_coef_index array of indexes to quant_centroid_tab - * @param subband_coef_sign signs of coefficients - * @param mlt_p pointer into the mlt buffer - */ - -static void scalar_dequant_float(COOKContext *q, int index, int quant_index, - int* subband_coef_index, int* subband_coef_sign, - float* mlt_p){ - int i; - float f1; - - for(i=0 ; irandom_state) < 0x80000000) f1 = -f1; - } - mlt_p[i] = f1 * rootpow2tab[quant_index+63]; - } -} -/** - * Unpack the subband_coef_index and subband_coef_sign 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_sign signs of coefficients - */ - -static int unpack_SQVH(COOKContext *q, COOKSubpacket *p, int category, int* subband_coef_index, - int* subband_coef_sign) { - int i,j; - int vlc, vd ,tmp, result; - - vd = vd_tab[category]; - result = 0; - for(i=0 ; igb, q->sqvh[category].table, q->sqvh[category].bits, 3); - if (p->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) < p->bits_per_subpacket){ - subband_coef_sign[i*vd+j] = get_bits1(&q->gb); - } else { - result=1; - subband_coef_sign[i*vd+j]=0; - } - } else { - subband_coef_sign[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_index_table pointer to the array - * @param mlt_buffer pointer to mlt coefficients - */ - - -static void decode_vectors(COOKContext* q, COOKSubpacket* p, int* category, - int *quant_index_table, float* mlt_buffer){ - /* A zero in this table means that the subband coefficient is - random noise coded. */ - int subband_coef_index[SUBBAND_SIZE]; - /* A zero in this table means that the subband coefficient is a - positive multiplicator. */ - int subband_coef_sign[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, p, category[band], subband_coef_index, subband_coef_sign)){ - 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_sign, 0, sizeof(subband_coef_sign)); - } - q->scalar_dequant(q, index, quant_index_table[band], - subband_coef_index, subband_coef_sign, - &mlt_buffer[band * SUBBAND_SIZE]); - } - - if(p->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){ - return; - } /* FIXME: should this be removed, or moved into loop above? */ -} - - -/** - * function for decoding mono data - * - * @param q pointer to the COOKContext - * @param mlt_buffer pointer to mlt coefficients - */ - -static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) { - - int category_index[128]; - int quant_index_table[102]; - int category[128]; - - memset(&category, 0, 128*sizeof(int)); - memset(&category_index, 0, 128*sizeof(int)); - - decode_envelope(q, p, quant_index_table); - q->num_vectors = get_bits(&q->gb,p->log2_numvector_size); - categorize(q, p, quant_index_table, category, category_index); - expand_category(q, category, category_index); - decode_vectors(q, p, category, quant_index_table, mlt_buffer); -} - - -/** - * 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_float(COOKContext *q, float* buffer, - int gain_index, int gain_index_next){ - int i; - float fc1, fc2; - fc1 = 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; - } -} - -/** - * Apply transform window, overlap buffers. - * - * @param q pointer to the COOKContext - * @param inbuffer pointer to the mltcoefficients - * @param gains_ptr current and previous gains - * @param previous_buffer pointer to the previous buffer to be used for overlapping - */ - -static void imlt_window_float (COOKContext *q, float *buffer1, - cook_gains *gains_ptr, float *previous_buffer) -{ - const float fc = pow2tab[gains_ptr->previous[0] + 63]; - int i; - /* The weird thing here, is that the two halves of the time domain - * buffer are swapped. Also, the newest data, that we save away for - * next frame, has the wrong sign. Hence the subtraction below. - * Almost sounds like a complex conjugate/reverse data/FFT effect. - */ - - /* Apply window and overlap */ - for(i = 0; i < q->samples_per_channel; i++){ - buffer1[i] = buffer1[i] * fc * q->mlt_window[i] - - previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i]; - } -} - -/** - * The modulated lapped transform, this takes transform coefficients - * and transforms them into timedomain samples. - * Apply transform window, overlap buffers, apply gain profile - * and buffer management. - * - * @param q pointer to the COOKContext - * @param inbuffer pointer to the mltcoefficients - * @param gains_ptr current and previous gains - * @param previous_buffer pointer to the previous buffer to be used for overlapping - */ - -static void imlt_gain(COOKContext *q, float *inbuffer, - cook_gains *gains_ptr, float* previous_buffer) -{ - float *buffer0 = q->mono_mdct_output; - float *buffer1 = q->mono_mdct_output + q->samples_per_channel; - int i; - - /* Inverse modified discrete cosine transform */ - ff_imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer); - - q->imlt_window (q, buffer1, gains_ptr, previous_buffer); - - /* Apply gain profile */ - for (i = 0; i < 8; i++) { - if (gains_ptr->now[i] || gains_ptr->now[i + 1]) - q->interpolate(q, &buffer1[q->gain_size_factor * i], - gains_ptr->now[i], gains_ptr->now[i + 1]); - } - - /* Save away the current to be previous block. */ - memcpy(previous_buffer, buffer0, 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, COOKSubpacket *p, int* decouple_tab){ - int length, i; - - if(get_bits1(&q->gb)) { - if(cplband[p->js_subband_start] > cplband[p->subbands-1]) return; - - length = cplband[p->subbands-1] - cplband[p->js_subband_start] + 1; - for (i=0 ; ijs_subband_start] + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2); - } - return; - } - - if(cplband[p->js_subband_start] > cplband[p->subbands-1]) return; - - length = cplband[p->subbands-1] - cplband[p->js_subband_start] + 1; - for (i=0 ; ijs_subband_start] + i] = get_bits(&q->gb, p->js_vlc_bits); - } - return; -} - -/* - * function decouples a pair of signals from a single signal via multiplication. - * - * @param q pointer to the COOKContext - * @param subband index of the current subband - * @param f1 multiplier for channel 1 extraction - * @param f2 multiplier for channel 2 extraction - * @param decode_buffer input buffer - * @param mlt_buffer1 pointer to left channel mlt coefficients - * @param mlt_buffer2 pointer to right channel mlt coefficients - */ -static void decouple_float (COOKContext *q, - COOKSubpacket *p, - int subband, - float f1, float f2, - float *decode_buffer, - float *mlt_buffer1, float *mlt_buffer2) -{ - int j, tmp_idx; - for (j=0 ; jjs_subband_start + subband)*SUBBAND_SIZE)+j; - mlt_buffer1[SUBBAND_SIZE*subband + j] = f1 * decode_buffer[tmp_idx]; - mlt_buffer2[SUBBAND_SIZE*subband + j] = f2 * decode_buffer[tmp_idx]; - } -} - -/** - * 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, COOKSubpacket *p, float* mlt_buffer1, - float* mlt_buffer2) { - int i,j; - int decouple_tab[SUBBAND_SIZE]; - float *decode_buffer = q->decode_buffer_0; - int idx, cpl_tmp; - float f1,f2; - const 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, p, decouple_tab); - mono_decode(q, p, 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=p->js_subband_start ; isubbands ; i++) { - cpl_tmp = cplband[i]; - idx -=decouple_tab[cpl_tmp]; - cplscale = q->cplscales[p->js_vlc_bits-2]; //choose decoupler table - f1 = cplscale[decouple_tab[cpl_tmp]]; - f2 = cplscale[idx-1]; - q->decouple (q, p, i, f1, f2, decode_buffer, mlt_buffer1, mlt_buffer2); - idx = (1 << p->js_vlc_bits) - 1; - } -} - -/** - * First part of subpacket decoding: - * decode raw stream bytes and read gain info. - * - * @param q pointer to the COOKContext - * @param inbuffer pointer to raw stream data - * @param gain_ptr array of current/prev gain pointers - */ - -static inline void -decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, const uint8_t *inbuffer, - cook_gains *gains_ptr) -{ - int offset; - - offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, - p->bits_per_subpacket/8); - init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, - p->bits_per_subpacket); - decode_gain_info(&q->gb, gains_ptr->now); - - /* Swap current and previous gains */ - FFSWAP(int *, gains_ptr->now, gains_ptr->previous); -} - - /** - * Saturate the output signal to signed 16bit integers. - * - * @param q pointer to the COOKContext - * @param chan channel to saturate - * @param out pointer to the output vector - */ -static void -saturate_output_float (COOKContext *q, int chan, int16_t *out) -{ - int j; - float *output = q->mono_mdct_output + q->samples_per_channel; - /* Clip and convert floats to 16 bits. - */ - for (j = 0; j < q->samples_per_channel; j++) { - out[chan + q->nb_channels * j] = - av_clip_int16(lrintf(output[j])); - } -} - -/** - * Final part of subpacket decoding: - * Apply modulated lapped transform, gain compensation, - * clip and convert to integer. - * - * @param q pointer to the COOKContext - * @param decode_buffer pointer to the mlt coefficients - * @param gain_ptr array of current/prev gain pointers - * @param previous_buffer pointer to the previous buffer to be used for overlapping - * @param out pointer to the output buffer - * @param chan 0: left or single channel, 1: right channel - */ - -static inline void -mlt_compensate_output(COOKContext *q, float *decode_buffer, - cook_gains *gains, float *previous_buffer, - int16_t *out, int chan) -{ - imlt_gain(q, decode_buffer, gains, previous_buffer); - q->saturate_output (q, chan, out); -} - - -/** - * 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 void decode_subpacket(COOKContext *q, COOKSubpacket* p, const uint8_t *inbuffer, int16_t *outbuffer) { - int sub_packet_size = p->size; - /* packet dump */ -// for (i=0 ; iavctx, AV_LOG_ERROR, "%02x", inbuffer[i]); -// } -// av_log(q->avctx, AV_LOG_ERROR, "\n"); - memset(q->decode_buffer_1,0,sizeof(q->decode_buffer_1)); - decode_bytes_and_gain(q, p, inbuffer, &p->gains1); - - if (p->joint_stereo) { - joint_decode(q, p, q->decode_buffer_1, q->decode_buffer_2); - } else { - mono_decode(q, p, q->decode_buffer_1); - - if (p->num_channels == 2) { - decode_bytes_and_gain(q, p, inbuffer + sub_packet_size/2, &p->gains2); - mono_decode(q, p, q->decode_buffer_2); - } - } - - mlt_compensate_output(q, q->decode_buffer_1, &p->gains1, - p->mono_previous_buffer1, outbuffer, p->ch_idx); - - if (p->num_channels == 2) { - if (p->joint_stereo) { - mlt_compensate_output(q, q->decode_buffer_2, &p->gains1, - p->mono_previous_buffer2, outbuffer, p->ch_idx + 1); - } else { - mlt_compensate_output(q, q->decode_buffer_2, &p->gains2, - p->mono_previous_buffer2, outbuffer, p->ch_idx + 1); - } - } - -} - - -/** - * Cook frame decoding - * - * @param avctx pointer to the AVCodecContext - */ - -static int cook_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - COOKContext *q = avctx->priv_data; - int i; - int offset = 0; - int chidx = 0; - - if (buf_size < avctx->block_align) - return buf_size; - - /* estimate subpacket sizes */ - q->subpacket[0].size = avctx->block_align; - - for(i=1;inum_subpackets;i++){ - q->subpacket[i].size = 2 * buf[avctx->block_align - q->num_subpackets + i]; - q->subpacket[0].size -= q->subpacket[i].size + 1; - if (q->subpacket[0].size < 0) { - av_log(avctx,AV_LOG_DEBUG,"frame subpacket size total > avctx->block_align!\n"); - return -1; - } - } - - /* decode supbackets */ - *data_size = 0; - for(i=0;inum_subpackets;i++){ - q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size*8)>>q->subpacket[i].bits_per_subpdiv; - q->subpacket[i].ch_idx = chidx; - av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] size %i js %i %i block_align %i\n",i,q->subpacket[i].size,q->subpacket[i].joint_stereo,offset,avctx->block_align); - decode_subpacket(q, &q->subpacket[i], buf + offset, (int16_t*)data); - offset += q->subpacket[i].size; - chidx += q->subpacket[i].num_channels; - av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] %i %i\n",i,q->subpacket[i].size * 8,get_bits_count(&q->gb)); - } - *data_size = sizeof(int16_t) * q->nb_channels * q->samples_per_channel; - - /* Discard the first two frames: no valid audio. */ - if (avctx->frame_number < 2) *data_size = 0; - - return avctx->block_align; -} - -#ifdef COOKDEBUG -static void dump_cook_context(COOKContext *q) -{ - //int i=0; -#define PRINT(a,b) av_log(q->avctx,AV_LOG_ERROR," %s = %d\n", a, b); - av_log(q->avctx,AV_LOG_ERROR,"COOKextradata\n"); - av_log(q->avctx,AV_LOG_ERROR,"cookversion=%x\n",q->subpacket[0].cookversion); - if (q->subpacket[0].cookversion > STEREO) { - PRINT("js_subband_start",q->subpacket[0].js_subband_start); - PRINT("js_vlc_bits",q->subpacket[0].js_vlc_bits); - } - av_log(q->avctx,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->subpacket[0].samples_per_channel); - PRINT("samples_per_frame",q->subpacket[0].samples_per_frame); - PRINT("subbands",q->subpacket[0].subbands); - PRINT("random_state",q->random_state); - PRINT("js_subband_start",q->subpacket[0].js_subband_start); - PRINT("log2_numvector_size",q->subpacket[0].log2_numvector_size); - PRINT("numvector_size",q->subpacket[0].numvector_size); - PRINT("total_subbands",q->subpacket[0].total_subbands); -} -#endif - -static av_cold int cook_count_channels(unsigned int mask){ - int i; - int channels = 0; - for(i = 0;i<32;i++){ - if(mask & (1<priv_data; - const uint8_t *edata_ptr = avctx->extradata; - const uint8_t *edata_ptr_end = edata_ptr + avctx->extradata_size; - int extradata_size = avctx->extradata_size; - int s = 0; - unsigned int channel_mask = 0; - q->avctx = avctx; - - /* Take care of the codec specific extradata. */ - if (extradata_size <= 0) { - av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n"); - return -1; - } - av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size); - - /* 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 RNG. */ - av_lfg_init(&q->random_state, 0); - - while(edata_ptr < edata_ptr_end){ - /* 8 for mono, 16 for stereo, ? for multichannel - Swap to right endianness so we don't need to care later on. */ - if (extradata_size >= 8){ - q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr); - q->subpacket[s].samples_per_frame = bytestream_get_be16(&edata_ptr); - q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr); - extradata_size -= 8; - } - if (avctx->extradata_size >= 8){ - bytestream_get_be32(&edata_ptr); //Unknown unused - q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr); - q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr); - extradata_size -= 8; - } - - /* Initialize extradata related variables. */ - q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame / q->nb_channels; - q->subpacket[s].bits_per_subpacket = avctx->block_align * 8; - - /* Initialize default data states. */ - q->subpacket[s].log2_numvector_size = 5; - q->subpacket[s].total_subbands = q->subpacket[s].subbands; - q->subpacket[s].num_channels = 1; - - /* Initialize version-dependent variables */ - - av_log(avctx,AV_LOG_DEBUG,"subpacket[%i].cookversion=%x\n",s,q->subpacket[s].cookversion); - q->subpacket[s].joint_stereo = 0; - switch (q->subpacket[s].cookversion) { - case MONO: - if (q->nb_channels != 1) { - av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n"); - return -1; - } - av_log(avctx,AV_LOG_DEBUG,"MONO\n"); - break; - case STEREO: - if (q->nb_channels != 1) { - q->subpacket[s].bits_per_subpdiv = 1; - q->subpacket[s].num_channels = 2; - } - av_log(avctx,AV_LOG_DEBUG,"STEREO\n"); - break; - case JOINT_STEREO: - if (q->nb_channels != 2) { - av_log(avctx,AV_LOG_ERROR,"Container channels != 2, report sample!\n"); - return -1; - } - av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n"); - if (avctx->extradata_size >= 16){ - q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start; - q->subpacket[s].joint_stereo = 1; - q->subpacket[s].num_channels = 2; - } - if (q->subpacket[s].samples_per_channel > 256) { - q->subpacket[s].log2_numvector_size = 6; - } - if (q->subpacket[s].samples_per_channel > 512) { - q->subpacket[s].log2_numvector_size = 7; - } - break; - case MC_COOK: - av_log(avctx,AV_LOG_DEBUG,"MULTI_CHANNEL\n"); - if(extradata_size >= 4) - channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr); - - if(cook_count_channels(q->subpacket[s].channel_mask) > 1){ - q->subpacket[s].total_subbands = q->subpacket[s].subbands + q->subpacket[s].js_subband_start; - q->subpacket[s].joint_stereo = 1; - q->subpacket[s].num_channels = 2; - q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame >> 1; - - if (q->subpacket[s].samples_per_channel > 256) { - q->subpacket[s].log2_numvector_size = 6; - } - if (q->subpacket[s].samples_per_channel > 512) { - q->subpacket[s].log2_numvector_size = 7; - } - }else - q->subpacket[s].samples_per_channel = q->subpacket[s].samples_per_frame; - - break; - default: - av_log(avctx,AV_LOG_ERROR,"Unknown Cook version, report sample!\n"); - return -1; - break; - } - - if(s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) { - av_log(avctx,AV_LOG_ERROR,"different number of samples per channel!\n"); - return -1; - } else - q->samples_per_channel = q->subpacket[0].samples_per_channel; - - - /* Initialize variable relations */ - q->subpacket[s].numvector_size = (1 << q->subpacket[s].log2_numvector_size); - - /* Try to catch some obviously faulty streams, othervise it might be exploitable */ - if (q->subpacket[s].total_subbands > 53) { - av_log(avctx,AV_LOG_ERROR,"total_subbands > 53, report sample!\n"); - return -1; - } - - if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 0)) { - av_log(avctx,AV_LOG_ERROR,"js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->subpacket[s].js_vlc_bits); - return -1; - } - - if (q->subpacket[s].subbands > 50) { - av_log(avctx,AV_LOG_ERROR,"subbands > 50, report sample!\n"); - return -1; - } - q->subpacket[s].gains1.now = q->subpacket[s].gain_1; - q->subpacket[s].gains1.previous = q->subpacket[s].gain_2; - q->subpacket[s].gains2.now = q->subpacket[s].gain_3; - q->subpacket[s].gains2.previous = q->subpacket[s].gain_4; - - q->num_subpackets++; - s++; - if (s > MAX_SUBPACKETS) { - av_log(avctx,AV_LOG_ERROR,"Too many subpackets > 5, report file!\n"); - return -1; - } - } - /* Generate tables */ - init_pow2table(); - init_gain_table(q); - init_cplscales_table(q); - - if (init_cook_vlc_tables(q) != 0) - return -1; - - - if(avctx->block_align >= UINT_MAX/2) - return -1; - - /* Pad the databuffer with: - DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(), - FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */ - q->decoded_bytes_buffer = - av_mallocz(avctx->block_align - + DECODE_BYTES_PAD1(avctx->block_align) - + FF_INPUT_BUFFER_PADDING_SIZE); - if (q->decoded_bytes_buffer == NULL) - return -1; - - /* Initialize transform. */ - if ( init_cook_mlt(q) != 0 ) - return -1; - - /* Initialize COOK signal arithmetic handling */ - if (1) { - q->scalar_dequant = scalar_dequant_float; - q->decouple = decouple_float; - q->imlt_window = imlt_window_float; - q->interpolate = interpolate_float; - q->saturate_output = saturate_output_float; - } - - /* Try to catch some obviously faulty streams, othervise it might be exploitable */ - if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) { - } else { - av_log(avctx,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel); - return -1; - } - - avctx->sample_fmt = SAMPLE_FMT_S16; - if (channel_mask) - avctx->channel_layout = channel_mask; - else - avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; - -#ifdef COOKDEBUG - dump_cook_context(q); -#endif - return 0; -} - - -AVCodec cook_decoder = -{ - .name = "cook", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_COOK, - .priv_data_size = sizeof(COOKContext), - .init = cook_decode_init, - .close = cook_decode_close, - .decode = cook_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("COOK"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/cookdata.h b/tizen/distrib/ffmpeg/libavcodec/cookdata.h deleted file mode 100644 index 15e8e95..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cookdata.h +++ /dev/null @@ -1,563 +0,0 @@ -/* - * COOK compatible decoder data - * Copyright (c) 2003 Sascha Sommer - * Copyright (c) 2005 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Cook AKA RealAudio G2 compatible decoderdata - */ - -#ifndef AVCODEC_COOKDATA_H -#define AVCODEC_COOKDATA_H - -#include - -/* 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 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* const cvh_huffcodes[7] = { - cvh_huffcodes0, cvh_huffcodes1, cvh_huffcodes2, cvh_huffcodes3, - cvh_huffcodes4, cvh_huffcodes5, cvh_huffcodes6, -}; - -static const uint8_t* const 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* const ccpl_huffcodes[5] = { - ccpl_huffcodes2,ccpl_huffcodes3, - ccpl_huffcodes4,ccpl_huffcodes5,ccpl_huffcodes6 -}; - -static const uint8_t* const 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* const cplscales[5] = { - cplscale2, cplscale3, cplscale4, cplscale5, cplscale6, -}; - -#endif /* AVCODEC_COOKDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/costablegen.c b/tizen/distrib/ffmpeg/libavcodec/costablegen.c deleted file mode 100644 index bfcd635..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/costablegen.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Generate a header file for hardcoded ff_cos_* tables - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -#define BITS 16 -#define FLOATFMT "%.18e" - -int main(int argc, char *argv[]) -{ - int i, j; - int do_sin = argc == 2 && !strcmp(argv[1], "sin"); - double (*func)(double) = do_sin ? sin : cos; - - printf("/* This file was generated by libavcodec/costablegen */\n"); - printf("#include \"libavcodec/fft.h\"\n"); - for (i = 4; i <= BITS; i++) { - int m = 1 << i; - double freq = 2*M_PI/m; - printf("%s(%i) = {\n ", do_sin ? "SINTABLE" : "COSTABLE", m); - for (j = 0; j < m/2 - 1; j++) { - int idx = j > m/4 ? m/2 - j : j; - if (do_sin && j >= m/4) - idx = m/4 - j; - printf(" "FLOATFMT",", func(idx*freq)); - if ((j & 3) == 3) - printf("\n "); - } - printf(" "FLOATFMT"\n};\n", func(do_sin ? -(m/4 - 1)*freq : freq)); - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/cscd.c b/tizen/distrib/ffmpeg/libavcodec/cscd.c deleted file mode 100644 index e4f4b8f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cscd.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * CamStudio decoder - * Copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include - -#include "avcodec.h" - -#if CONFIG_ZLIB -#include -#endif -#include "libavutil/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, const 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, const 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; - } -} - -#if !HAVE_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, const 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, const 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, const 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, const 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, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - CamStudioContext *c = 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 (av_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 -#if 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 av_cold int decode_init(AVCodecContext *avctx) { - CamStudioContext *c = avctx->priv_data; - switch (avctx->bits_per_coded_sample) { - case 16: avctx->pix_fmt = PIX_FMT_RGB555; break; - case 24: avctx->pix_fmt = PIX_FMT_BGR24; break; - case 32: avctx->pix_fmt = PIX_FMT_RGB32; break; - default: - av_log(avctx, AV_LOG_ERROR, - "CamStudio codec error: invalid depth %i bpp\n", - avctx->bits_per_coded_sample); - return 1; - } - c->bpp = avctx->bits_per_coded_sample; - c->pic.data[0] = NULL; - c->linelen = avctx->width * avctx->bits_per_coded_sample / 8; - c->height = avctx->height; - c->decomp_size = c->height * c->linelen; - c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); - if (!c->decomp_buf) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; - } - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) { - CamStudioContext *c = 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", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CSCD, - sizeof(CamStudioContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("CamStudio"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/cyuv.c b/tizen/distrib/ffmpeg/libavcodec/cyuv.c deleted file mode 100644 index db7e690..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/cyuv.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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 - * - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Creative YUV (CYUV) Video Decoder. - */ - -#include -#include -#include - -#include "avcodec.h" -#include "dsputil.h" - - -typedef struct CyuvDecodeContext { - AVCodecContext *avctx; - int width, height; - AVFrame frame; -} CyuvDecodeContext; - -static av_cold 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; - - return 0; -} - -static int cyuv_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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) */ - const signed char *y_table = (const signed char*)buf + 0; - const signed char *u_table = (const signed char*)buf + 16; - const signed char *v_table = (const signed char*)buf + 32; - - unsigned char y_pred, u_pred, v_pred; - int stream_ptr; - unsigned char cur_byte; - int pixel_groups; - - if (avctx->codec_id == CODEC_ID_AURA) { - y_table = u_table; - u_table = v_table; - } - /* 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, "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 av_cold int cyuv_decode_end(AVCodecContext *avctx) -{ - CyuvDecodeContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -#if CONFIG_AURA_DECODER -AVCodec aura_decoder = { - "aura", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_AURA, - sizeof(CyuvDecodeContext), - cyuv_decode_init, - NULL, - cyuv_decode_end, - cyuv_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Auravision AURA"), -}; -#endif - -#if CONFIG_CYUV_DECODER -AVCodec cyuv_decoder = { - "cyuv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CYUV, - sizeof(CyuvDecodeContext), - cyuv_decode_init, - NULL, - cyuv_decode_end, - cyuv_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/dca.c b/tizen/distrib/ffmpeg/libavcodec/dca.c deleted file mode 100644 index 10bc956..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dca.c +++ /dev/null @@ -1,1333 +0,0 @@ -/* - * DCA compatible decoder - * Copyright (C) 2004 Gildas Bazin - * Copyright (C) 2004 Benjamin Zores - * Copyright (C) 2006 Benjamin Larsson - * Copyright (C) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include "libavutil/intmath.h" -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "dsputil.h" -#include "fft.h" -#include "get_bits.h" -#include "put_bits.h" -#include "dcadata.h" -#include "dcahuff.h" -#include "dca.h" -#include "synth_filter.h" -#include "dcadsp.h" - -//#define TRACE - -#define DCA_PRIM_CHANNELS_MAX (5) -#define DCA_SUBBANDS (32) -#define DCA_ABITS_MAX (32) /* Should be 28 */ -#define DCA_SUBSUBFAMES_MAX (4) -#define DCA_LFE_MAX (3) - -enum DCAMode { - DCA_MONO = 0, - DCA_CHANNEL, - DCA_STEREO, - DCA_STEREO_SUMDIFF, - DCA_STEREO_TOTAL, - DCA_3F, - DCA_2F1R, - DCA_3F1R, - DCA_2F2R, - DCA_3F2R, - DCA_4F2R -}; - -/* Tables for mapping dts channel configurations to libavcodec multichannel api. - * Some compromises have been made for special configurations. Most configurations - * are never used so complete accuracy is not needed. - * - * L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead. - * S -> side, when both rear and back are configured move one of them to the side channel - * OV -> center back - * All 2 channel configurations -> CH_LAYOUT_STEREO - */ - -static const int64_t dca_core_channel_layout[] = { - CH_FRONT_CENTER, ///< 1, A - CH_LAYOUT_STEREO, ///< 2, A + B (dual mono) - CH_LAYOUT_STEREO, ///< 2, L + R (stereo) - CH_LAYOUT_STEREO, ///< 2, (L+R) + (L-R) (sum-difference) - CH_LAYOUT_STEREO, ///< 2, LT +RT (left and right total) - CH_LAYOUT_STEREO|CH_FRONT_CENTER, ///< 3, C+L+R - CH_LAYOUT_STEREO|CH_BACK_CENTER, ///< 3, L+R+S - CH_LAYOUT_STEREO|CH_FRONT_CENTER|CH_BACK_CENTER, ///< 4, C + L + R+ S - CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT, ///< 4, L + R +SL+ SR - CH_LAYOUT_STEREO|CH_FRONT_CENTER|CH_SIDE_LEFT|CH_SIDE_RIGHT, ///< 5, C + L + R+ SL+SR - CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT|CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER, ///< 6, CL + CR + L + R + SL + SR - CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT|CH_FRONT_CENTER|CH_BACK_CENTER, ///< 6, C + L + R+ LR + RR + OV - CH_FRONT_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_FRONT_LEFT_OF_CENTER|CH_BACK_CENTER|CH_BACK_LEFT|CH_BACK_RIGHT, ///< 6, CF+ CR+LF+ RF+LR + RR - CH_FRONT_LEFT_OF_CENTER|CH_FRONT_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT, ///< 7, CL + C + CR + L + R + SL + SR - CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT|CH_BACK_LEFT|CH_BACK_RIGHT, ///< 8, CL + CR + L + R + SL1 + SL2+ SR1 + SR2 - CH_FRONT_LEFT_OF_CENTER|CH_FRONT_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_BACK_CENTER|CH_SIDE_RIGHT, ///< 8, CL + C+ CR + L + R + SL + S+ SR -}; - -static const int8_t dca_lfe_index[] = { - 1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3 -}; - -static const int8_t dca_channel_reorder_lfe[][8] = { - { 0, -1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 2, 0, 1, -1, -1, -1, -1, -1}, - { 0, 1, 3, -1, -1, -1, -1, -1}, - { 2, 0, 1, 4, -1, -1, -1, -1}, - { 0, 1, 3, 4, -1, -1, -1, -1}, - { 2, 0, 1, 4, 5, -1, -1, -1}, - { 3, 4, 0, 1, 5, 6, -1, -1}, - { 2, 0, 1, 4, 5, 6, -1, -1}, - { 0, 6, 4, 5, 2, 3, -1, -1}, - { 4, 2, 5, 0, 1, 6, 7, -1}, - { 5, 6, 0, 1, 7, 3, 8, 4}, - { 4, 2, 5, 0, 1, 6, 8, 7}, -}; - -static const int8_t dca_channel_reorder_nolfe[][8] = { - { 0, -1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 0, 1, -1, -1, -1, -1, -1, -1}, - { 2, 0, 1, -1, -1, -1, -1, -1}, - { 0, 1, 2, -1, -1, -1, -1, -1}, - { 2, 0, 1, 3, -1, -1, -1, -1}, - { 0, 1, 2, 3, -1, -1, -1, -1}, - { 2, 0, 1, 3, 4, -1, -1, -1}, - { 2, 3, 0, 1, 4, 5, -1, -1}, - { 2, 0, 1, 3, 4, 5, -1, -1}, - { 0, 5, 3, 4, 1, 2, -1, -1}, - { 3, 2, 4, 0, 1, 5, 6, -1}, - { 4, 5, 0, 1, 6, 2, 7, 3}, - { 3, 2, 4, 0, 1, 5, 7, 6}, -}; - - -#define DCA_DOLBY 101 /* FIXME */ - -#define DCA_CHANNEL_BITS 6 -#define DCA_CHANNEL_MASK 0x3F - -#define DCA_LFE 0x80 - -#define HEADER_SIZE 14 - -#define DCA_MAX_FRAME_SIZE 16384 - -/** Bit allocation */ -typedef struct { - int offset; ///< code values offset - int maxbits[8]; ///< max bits in VLC - int wrap; ///< wrap for get_vlc2() - VLC vlc[8]; ///< actual codes -} BitAlloc; - -static BitAlloc dca_bitalloc_index; ///< indexes for samples VLC select -static BitAlloc dca_tmode; ///< transition mode VLCs -static BitAlloc dca_scalefactor; ///< scalefactor VLCs -static BitAlloc dca_smpl_bitalloc[11]; ///< samples VLCs - -static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, int idx) -{ - return get_vlc2(gb, ba->vlc[idx].table, ba->vlc[idx].bits, ba->wrap) + ba->offset; -} - -typedef struct { - AVCodecContext *avctx; - /* Frame header */ - int frame_type; ///< type of the current frame - int samples_deficit; ///< deficit sample count - int crc_present; ///< crc is present in the bitstream - int sample_blocks; ///< number of PCM sample blocks - int frame_size; ///< primary frame byte size - int amode; ///< audio channels arrangement - int sample_rate; ///< audio sampling rate - int bit_rate; ///< transmission bit rate - int bit_rate_index; ///< transmission bit rate index - - int downmix; ///< embedded downmix enabled - int dynrange; ///< embedded dynamic range flag - int timestamp; ///< embedded time stamp flag - int aux_data; ///< auxiliary data flag - int hdcd; ///< source material is mastered in HDCD - int ext_descr; ///< extension audio descriptor flag - int ext_coding; ///< extended coding flag - int aspf; ///< audio sync word insertion flag - int lfe; ///< low frequency effects flag - int predictor_history; ///< predictor history flag - int header_crc; ///< header crc check bytes - int multirate_inter; ///< multirate interpolator switch - int version; ///< encoder software revision - int copy_history; ///< copy history - int source_pcm_res; ///< source pcm resolution - int front_sum; ///< front sum/difference flag - int surround_sum; ///< surround sum/difference flag - int dialog_norm; ///< dialog normalisation parameter - - /* Primary audio coding header */ - int subframes; ///< number of subframes - int total_channels; ///< number of channels including extensions - int prim_channels; ///< number of primary audio channels - int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count - int vq_start_subband[DCA_PRIM_CHANNELS_MAX]; ///< high frequency vq start subband - int joint_intensity[DCA_PRIM_CHANNELS_MAX]; ///< joint intensity coding index - int transient_huffman[DCA_PRIM_CHANNELS_MAX]; ///< transient mode code book - int scalefactor_huffman[DCA_PRIM_CHANNELS_MAX]; ///< scale factor code book - int bitalloc_huffman[DCA_PRIM_CHANNELS_MAX]; ///< bit allocation quantizer select - int quant_index_huffman[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< quantization index codebook select - float scalefactor_adj[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< scale factor adjustment - - /* Primary audio coding side information */ - int subsubframes; ///< number of subsubframes - int partial_samples; ///< partial subsubframe samples count - int prediction_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction mode (ADPCM used or not) - int prediction_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction VQ coefs - int bitalloc[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< bit allocation index - int transition_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< transition mode (transients) - int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient) - int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook - int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors - int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients - int dynrange_coef; ///< dynamic range coefficient - - int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands - - float lfe_data[2 * DCA_SUBSUBFAMES_MAX * DCA_LFE_MAX * - 2 /*history */ ]; ///< Low frequency effect data - int lfe_scale_factor; - - /* Subband samples history (for ADPCM) */ - float subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4]; - DECLARE_ALIGNED(16, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512]; - DECLARE_ALIGNED(16, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32]; - int hist_index[DCA_PRIM_CHANNELS_MAX]; - DECLARE_ALIGNED(16, float, raXin)[32]; - - int output; ///< type of output - float add_bias; ///< output bias - float scale_bias; ///< output scale - - DECLARE_ALIGNED(16, float, samples)[1536]; /* 6 * 256 = 1536, might only need 5 */ - const float *samples_chanptr[6]; - - uint8_t dca_buffer[DCA_MAX_FRAME_SIZE]; - int dca_buffer_size; ///< how much data is in the dca_buffer - - const int8_t* channel_order_tab; ///< channel reordering table, lfe and non lfe - GetBitContext gb; - /* Current position in DCA frame */ - int current_subframe; - int current_subsubframe; - - int debug_flag; ///< used for suppressing repeated error messages output - DSPContext dsp; - FFTContext imdct; - SynthFilterContext synth; - DCADSPContext dcadsp; -} DCAContext; - -static const uint16_t dca_vlc_offs[] = { - 0, 512, 640, 768, 1282, 1794, 2436, 3080, 3770, 4454, 5364, - 5372, 5380, 5388, 5392, 5396, 5412, 5420, 5428, 5460, 5492, 5508, - 5572, 5604, 5668, 5796, 5860, 5892, 6412, 6668, 6796, 7308, 7564, - 7820, 8076, 8620, 9132, 9388, 9910, 10166, 10680, 11196, 11726, 12240, - 12752, 13298, 13810, 14326, 14840, 15500, 16022, 16540, 17158, 17678, 18264, - 18796, 19352, 19926, 20468, 21472, 22398, 23014, 23622, -}; - -static av_cold void dca_init_vlcs(void) -{ - static int vlcs_initialized = 0; - int i, j, c = 14; - static VLC_TYPE dca_table[23622][2]; - - if (vlcs_initialized) - return; - - dca_bitalloc_index.offset = 1; - dca_bitalloc_index.wrap = 2; - for (i = 0; i < 5; i++) { - dca_bitalloc_index.vlc[i].table = &dca_table[dca_vlc_offs[i]]; - dca_bitalloc_index.vlc[i].table_allocated = dca_vlc_offs[i + 1] - dca_vlc_offs[i]; - init_vlc(&dca_bitalloc_index.vlc[i], bitalloc_12_vlc_bits[i], 12, - bitalloc_12_bits[i], 1, 1, - bitalloc_12_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - dca_scalefactor.offset = -64; - dca_scalefactor.wrap = 2; - for (i = 0; i < 5; i++) { - dca_scalefactor.vlc[i].table = &dca_table[dca_vlc_offs[i + 5]]; - dca_scalefactor.vlc[i].table_allocated = dca_vlc_offs[i + 6] - dca_vlc_offs[i + 5]; - init_vlc(&dca_scalefactor.vlc[i], SCALES_VLC_BITS, 129, - scales_bits[i], 1, 1, - scales_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - dca_tmode.offset = 0; - dca_tmode.wrap = 1; - for (i = 0; i < 4; i++) { - dca_tmode.vlc[i].table = &dca_table[dca_vlc_offs[i + 10]]; - dca_tmode.vlc[i].table_allocated = dca_vlc_offs[i + 11] - dca_vlc_offs[i + 10]; - init_vlc(&dca_tmode.vlc[i], tmode_vlc_bits[i], 4, - tmode_bits[i], 1, 1, - tmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - - for(i = 0; i < 10; i++) - for(j = 0; j < 7; j++){ - if(!bitalloc_codes[i][j]) break; - dca_smpl_bitalloc[i+1].offset = bitalloc_offsets[i]; - dca_smpl_bitalloc[i+1].wrap = 1 + (j > 4); - dca_smpl_bitalloc[i+1].vlc[j].table = &dca_table[dca_vlc_offs[c]]; - dca_smpl_bitalloc[i+1].vlc[j].table_allocated = dca_vlc_offs[c + 1] - dca_vlc_offs[c]; - init_vlc(&dca_smpl_bitalloc[i+1].vlc[j], bitalloc_maxbits[i][j], - bitalloc_sizes[i], - bitalloc_bits[i][j], 1, 1, - bitalloc_codes[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC); - c++; - } - vlcs_initialized = 1; -} - -static inline void get_array(GetBitContext *gb, int *dst, int len, int bits) -{ - while(len--) - *dst++ = get_bits(gb, bits); -} - -static int dca_parse_frame_header(DCAContext * s) -{ - int i, j; - static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 }; - static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; - static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; - - init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); - - /* Sync code */ - get_bits(&s->gb, 32); - - /* Frame header */ - s->frame_type = get_bits(&s->gb, 1); - s->samples_deficit = get_bits(&s->gb, 5) + 1; - s->crc_present = get_bits(&s->gb, 1); - s->sample_blocks = get_bits(&s->gb, 7) + 1; - s->frame_size = get_bits(&s->gb, 14) + 1; - if (s->frame_size < 95) - return -1; - s->amode = get_bits(&s->gb, 6); - s->sample_rate = dca_sample_rates[get_bits(&s->gb, 4)]; - if (!s->sample_rate) - return -1; - s->bit_rate_index = get_bits(&s->gb, 5); - s->bit_rate = dca_bit_rates[s->bit_rate_index]; - if (!s->bit_rate) - return -1; - - s->downmix = get_bits(&s->gb, 1); - s->dynrange = get_bits(&s->gb, 1); - s->timestamp = get_bits(&s->gb, 1); - s->aux_data = get_bits(&s->gb, 1); - s->hdcd = get_bits(&s->gb, 1); - s->ext_descr = get_bits(&s->gb, 3); - s->ext_coding = get_bits(&s->gb, 1); - s->aspf = get_bits(&s->gb, 1); - s->lfe = get_bits(&s->gb, 2); - s->predictor_history = get_bits(&s->gb, 1); - - /* TODO: check CRC */ - if (s->crc_present) - s->header_crc = get_bits(&s->gb, 16); - - s->multirate_inter = get_bits(&s->gb, 1); - s->version = get_bits(&s->gb, 4); - s->copy_history = get_bits(&s->gb, 2); - s->source_pcm_res = get_bits(&s->gb, 3); - s->front_sum = get_bits(&s->gb, 1); - s->surround_sum = get_bits(&s->gb, 1); - s->dialog_norm = get_bits(&s->gb, 4); - - /* FIXME: channels mixing levels */ - s->output = s->amode; - if(s->lfe) s->output |= DCA_LFE; - -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "frame type: %i\n", s->frame_type); - av_log(s->avctx, AV_LOG_DEBUG, "samples deficit: %i\n", s->samples_deficit); - av_log(s->avctx, AV_LOG_DEBUG, "crc present: %i\n", s->crc_present); - av_log(s->avctx, AV_LOG_DEBUG, "sample blocks: %i (%i samples)\n", - s->sample_blocks, s->sample_blocks * 32); - av_log(s->avctx, AV_LOG_DEBUG, "frame size: %i bytes\n", s->frame_size); - av_log(s->avctx, AV_LOG_DEBUG, "amode: %i (%i channels)\n", - s->amode, dca_channels[s->amode]); - av_log(s->avctx, AV_LOG_DEBUG, "sample rate: %i Hz\n", - s->sample_rate); - av_log(s->avctx, AV_LOG_DEBUG, "bit rate: %i bits/s\n", - s->bit_rate); - av_log(s->avctx, AV_LOG_DEBUG, "downmix: %i\n", s->downmix); - av_log(s->avctx, AV_LOG_DEBUG, "dynrange: %i\n", s->dynrange); - av_log(s->avctx, AV_LOG_DEBUG, "timestamp: %i\n", s->timestamp); - av_log(s->avctx, AV_LOG_DEBUG, "aux_data: %i\n", s->aux_data); - av_log(s->avctx, AV_LOG_DEBUG, "hdcd: %i\n", s->hdcd); - av_log(s->avctx, AV_LOG_DEBUG, "ext descr: %i\n", s->ext_descr); - av_log(s->avctx, AV_LOG_DEBUG, "ext coding: %i\n", s->ext_coding); - av_log(s->avctx, AV_LOG_DEBUG, "aspf: %i\n", s->aspf); - av_log(s->avctx, AV_LOG_DEBUG, "lfe: %i\n", s->lfe); - av_log(s->avctx, AV_LOG_DEBUG, "predictor history: %i\n", - s->predictor_history); - av_log(s->avctx, AV_LOG_DEBUG, "header crc: %i\n", s->header_crc); - av_log(s->avctx, AV_LOG_DEBUG, "multirate inter: %i\n", - s->multirate_inter); - av_log(s->avctx, AV_LOG_DEBUG, "version number: %i\n", s->version); - av_log(s->avctx, AV_LOG_DEBUG, "copy history: %i\n", s->copy_history); - av_log(s->avctx, AV_LOG_DEBUG, - "source pcm resolution: %i (%i bits/sample)\n", - s->source_pcm_res, dca_bits_per_sample[s->source_pcm_res]); - av_log(s->avctx, AV_LOG_DEBUG, "front sum: %i\n", s->front_sum); - av_log(s->avctx, AV_LOG_DEBUG, "surround sum: %i\n", s->surround_sum); - av_log(s->avctx, AV_LOG_DEBUG, "dialog norm: %i\n", s->dialog_norm); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); -#endif - - /* Primary audio coding header */ - s->subframes = get_bits(&s->gb, 4) + 1; - s->total_channels = get_bits(&s->gb, 3) + 1; - s->prim_channels = s->total_channels; - if (s->prim_channels > DCA_PRIM_CHANNELS_MAX) - s->prim_channels = DCA_PRIM_CHANNELS_MAX; /* We only support DTS core */ - - - for (i = 0; i < s->prim_channels; i++) { - s->subband_activity[i] = get_bits(&s->gb, 5) + 2; - if (s->subband_activity[i] > DCA_SUBBANDS) - s->subband_activity[i] = DCA_SUBBANDS; - } - for (i = 0; i < s->prim_channels; i++) { - s->vq_start_subband[i] = get_bits(&s->gb, 5) + 1; - if (s->vq_start_subband[i] > DCA_SUBBANDS) - s->vq_start_subband[i] = DCA_SUBBANDS; - } - get_array(&s->gb, s->joint_intensity, s->prim_channels, 3); - get_array(&s->gb, s->transient_huffman, s->prim_channels, 2); - get_array(&s->gb, s->scalefactor_huffman, s->prim_channels, 3); - get_array(&s->gb, s->bitalloc_huffman, s->prim_channels, 3); - - /* Get codebooks quantization indexes */ - memset(s->quant_index_huffman, 0, sizeof(s->quant_index_huffman)); - for (j = 1; j < 11; j++) - for (i = 0; i < s->prim_channels; i++) - s->quant_index_huffman[i][j] = get_bits(&s->gb, bitlen[j]); - - /* Get scale factor adjustment */ - for (j = 0; j < 11; j++) - for (i = 0; i < s->prim_channels; i++) - s->scalefactor_adj[i][j] = 1; - - for (j = 1; j < 11; j++) - for (i = 0; i < s->prim_channels; i++) - if (s->quant_index_huffman[i][j] < thr[j]) - s->scalefactor_adj[i][j] = adj_table[get_bits(&s->gb, 2)]; - - if (s->crc_present) { - /* Audio header CRC check */ - get_bits(&s->gb, 16); - } - - s->current_subframe = 0; - s->current_subsubframe = 0; - -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "subframes: %i\n", s->subframes); - av_log(s->avctx, AV_LOG_DEBUG, "prim channels: %i\n", s->prim_channels); - for(i = 0; i < s->prim_channels; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "subband activity: %i\n", s->subband_activity[i]); - av_log(s->avctx, AV_LOG_DEBUG, "vq start subband: %i\n", s->vq_start_subband[i]); - av_log(s->avctx, AV_LOG_DEBUG, "joint intensity: %i\n", s->joint_intensity[i]); - av_log(s->avctx, AV_LOG_DEBUG, "transient mode codebook: %i\n", s->transient_huffman[i]); - av_log(s->avctx, AV_LOG_DEBUG, "scale factor codebook: %i\n", s->scalefactor_huffman[i]); - av_log(s->avctx, AV_LOG_DEBUG, "bit allocation quantizer: %i\n", s->bitalloc_huffman[i]); - av_log(s->avctx, AV_LOG_DEBUG, "quant index huff:"); - for (j = 0; j < 11; j++) - av_log(s->avctx, AV_LOG_DEBUG, " %i", - s->quant_index_huffman[i][j]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - av_log(s->avctx, AV_LOG_DEBUG, "scalefac adj:"); - for (j = 0; j < 11; j++) - av_log(s->avctx, AV_LOG_DEBUG, " %1.3f", s->scalefactor_adj[i][j]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } -#endif - - return 0; -} - - -static inline int get_scale(GetBitContext *gb, int level, int value) -{ - if (level < 5) { - /* huffman encoded */ - value += get_bitalloc(gb, &dca_scalefactor, level); - } else if(level < 8) - value = get_bits(gb, level + 1); - return value; -} - -static int dca_subframe_header(DCAContext * s) -{ - /* Primary audio coding side information */ - int j, k; - - s->subsubframes = get_bits(&s->gb, 2) + 1; - s->partial_samples = get_bits(&s->gb, 3); - for (j = 0; j < s->prim_channels; j++) { - for (k = 0; k < s->subband_activity[j]; k++) - s->prediction_mode[j][k] = get_bits(&s->gb, 1); - } - - /* Get prediction codebook */ - for (j = 0; j < s->prim_channels; j++) { - for (k = 0; k < s->subband_activity[j]; k++) { - if (s->prediction_mode[j][k] > 0) { - /* (Prediction coefficient VQ address) */ - s->prediction_vq[j][k] = get_bits(&s->gb, 12); - } - } - } - - /* Bit allocation index */ - for (j = 0; j < s->prim_channels; j++) { - for (k = 0; k < s->vq_start_subband[j]; k++) { - if (s->bitalloc_huffman[j] == 6) - s->bitalloc[j][k] = get_bits(&s->gb, 5); - else if (s->bitalloc_huffman[j] == 5) - s->bitalloc[j][k] = get_bits(&s->gb, 4); - else if (s->bitalloc_huffman[j] == 7) { - av_log(s->avctx, AV_LOG_ERROR, - "Invalid bit allocation index\n"); - return -1; - } else { - s->bitalloc[j][k] = - get_bitalloc(&s->gb, &dca_bitalloc_index, s->bitalloc_huffman[j]); - } - - if (s->bitalloc[j][k] > 26) { -// av_log(s->avctx,AV_LOG_DEBUG,"bitalloc index [%i][%i] too big (%i)\n", -// j, k, s->bitalloc[j][k]); - return -1; - } - } - } - - /* Transition mode */ - for (j = 0; j < s->prim_channels; j++) { - for (k = 0; k < s->subband_activity[j]; k++) { - s->transition_mode[j][k] = 0; - if (s->subsubframes > 1 && - k < s->vq_start_subband[j] && s->bitalloc[j][k] > 0) { - s->transition_mode[j][k] = - get_bitalloc(&s->gb, &dca_tmode, s->transient_huffman[j]); - } - } - } - - for (j = 0; j < s->prim_channels; j++) { - const uint32_t *scale_table; - int scale_sum; - - memset(s->scale_factor[j], 0, s->subband_activity[j] * sizeof(s->scale_factor[0][0][0]) * 2); - - if (s->scalefactor_huffman[j] == 6) - scale_table = scale_factor_quant7; - else - scale_table = scale_factor_quant6; - - /* When huffman coded, only the difference is encoded */ - scale_sum = 0; - - for (k = 0; k < s->subband_activity[j]; k++) { - if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) { - scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); - s->scale_factor[j][k][0] = scale_table[scale_sum]; - } - - if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) { - /* Get second scale factor */ - scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); - s->scale_factor[j][k][1] = scale_table[scale_sum]; - } - } - } - - /* Joint subband scale factor codebook select */ - for (j = 0; j < s->prim_channels; j++) { - /* Transmitted only if joint subband coding enabled */ - if (s->joint_intensity[j] > 0) - s->joint_huff[j] = get_bits(&s->gb, 3); - } - - /* Scale factors for joint subband coding */ - for (j = 0; j < s->prim_channels; j++) { - int source_channel; - - /* Transmitted only if joint subband coding enabled */ - if (s->joint_intensity[j] > 0) { - int scale = 0; - source_channel = s->joint_intensity[j] - 1; - - /* When huffman coded, only the difference is encoded - * (is this valid as well for joint scales ???) */ - - for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) { - scale = get_scale(&s->gb, s->joint_huff[j], 0); - scale += 64; /* bias */ - s->joint_scale_factor[j][k] = scale; /*joint_scale_table[scale]; */ - } - - if (!(s->debug_flag & 0x02)) { - av_log(s->avctx, AV_LOG_DEBUG, - "Joint stereo coding not supported\n"); - s->debug_flag |= 0x02; - } - } - } - - /* Stereo downmix coefficients */ - if (s->prim_channels > 2) { - if(s->downmix) { - for (j = 0; j < s->prim_channels; j++) { - s->downmix_coef[j][0] = get_bits(&s->gb, 7); - s->downmix_coef[j][1] = get_bits(&s->gb, 7); - } - } else { - int am = s->amode & DCA_CHANNEL_MASK; - for (j = 0; j < s->prim_channels; j++) { - s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; - s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; - } - } - } - - /* Dynamic range coefficient */ - if (s->dynrange) - s->dynrange_coef = get_bits(&s->gb, 8); - - /* Side information CRC check word */ - if (s->crc_present) { - get_bits(&s->gb, 16); - } - - /* - * Primary audio data arrays - */ - - /* VQ encoded high frequency subbands */ - for (j = 0; j < s->prim_channels; j++) - for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) - /* 1 vector -> 32 samples */ - s->high_freq_vq[j][k] = get_bits(&s->gb, 10); - - /* Low frequency effect data */ - if (s->lfe) { - /* LFE samples */ - int lfe_samples = 2 * s->lfe * s->subsubframes; - float lfe_scale; - - for (j = lfe_samples; j < lfe_samples * 2; j++) { - /* Signed 8 bits int */ - s->lfe_data[j] = get_sbits(&s->gb, 8); - } - - /* Scale factor index */ - s->lfe_scale_factor = scale_factor_quant7[get_bits(&s->gb, 8)]; - - /* Quantization step size * scale factor */ - lfe_scale = 0.035 * s->lfe_scale_factor; - - for (j = lfe_samples; j < lfe_samples * 2; j++) - s->lfe_data[j] *= lfe_scale; - } - -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "subsubframes: %i\n", s->subsubframes); - av_log(s->avctx, AV_LOG_DEBUG, "partial samples: %i\n", - s->partial_samples); - for (j = 0; j < s->prim_channels; j++) { - av_log(s->avctx, AV_LOG_DEBUG, "prediction mode:"); - for (k = 0; k < s->subband_activity[j]; k++) - av_log(s->avctx, AV_LOG_DEBUG, " %i", s->prediction_mode[j][k]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } - for (j = 0; j < s->prim_channels; j++) { - for (k = 0; k < s->subband_activity[j]; k++) - av_log(s->avctx, AV_LOG_DEBUG, - "prediction coefs: %f, %f, %f, %f\n", - (float) adpcm_vb[s->prediction_vq[j][k]][0] / 8192, - (float) adpcm_vb[s->prediction_vq[j][k]][1] / 8192, - (float) adpcm_vb[s->prediction_vq[j][k]][2] / 8192, - (float) adpcm_vb[s->prediction_vq[j][k]][3] / 8192); - } - for (j = 0; j < s->prim_channels; j++) { - av_log(s->avctx, AV_LOG_DEBUG, "bitalloc index: "); - for (k = 0; k < s->vq_start_subband[j]; k++) - av_log(s->avctx, AV_LOG_DEBUG, "%2.2i ", s->bitalloc[j][k]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } - for (j = 0; j < s->prim_channels; j++) { - av_log(s->avctx, AV_LOG_DEBUG, "Transition mode:"); - for (k = 0; k < s->subband_activity[j]; k++) - av_log(s->avctx, AV_LOG_DEBUG, " %i", s->transition_mode[j][k]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } - for (j = 0; j < s->prim_channels; j++) { - av_log(s->avctx, AV_LOG_DEBUG, "Scale factor:"); - for (k = 0; k < s->subband_activity[j]; k++) { - if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) - av_log(s->avctx, AV_LOG_DEBUG, " %i", s->scale_factor[j][k][0]); - if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) - av_log(s->avctx, AV_LOG_DEBUG, " %i(t)", s->scale_factor[j][k][1]); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } - for (j = 0; j < s->prim_channels; j++) { - if (s->joint_intensity[j] > 0) { - int source_channel = s->joint_intensity[j] - 1; - av_log(s->avctx, AV_LOG_DEBUG, "Joint scale factor index:\n"); - for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) - av_log(s->avctx, AV_LOG_DEBUG, " %i", s->joint_scale_factor[j][k]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } - } - if (s->prim_channels > 2 && s->downmix) { - av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n"); - for (j = 0; j < s->prim_channels; j++) { - av_log(s->avctx, AV_LOG_DEBUG, "Channel 0,%d = %f\n", j, dca_downmix_coeffs[s->downmix_coef[j][0]]); - av_log(s->avctx, AV_LOG_DEBUG, "Channel 1,%d = %f\n", j, dca_downmix_coeffs[s->downmix_coef[j][1]]); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } - for (j = 0; j < s->prim_channels; j++) - for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) - av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); - if(s->lfe){ - int lfe_samples = 2 * s->lfe * s->subsubframes; - av_log(s->avctx, AV_LOG_DEBUG, "LFE samples:\n"); - for (j = lfe_samples; j < lfe_samples * 2; j++) - av_log(s->avctx, AV_LOG_DEBUG, " %f", s->lfe_data[j]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } -#endif - - return 0; -} - -static void qmf_32_subbands(DCAContext * s, int chans, - float samples_in[32][8], float *samples_out, - float scale, float bias) -{ - const float *prCoeff; - int i; - - int sb_act = s->subband_activity[chans]; - int subindex; - - scale *= sqrt(1/8.0); - - /* Select filter */ - if (!s->multirate_inter) /* Non-perfect reconstruction */ - prCoeff = fir_32bands_nonperfect; - else /* Perfect reconstruction */ - prCoeff = fir_32bands_perfect; - - /* Reconstructed channel sample index */ - for (subindex = 0; subindex < 8; subindex++) { - /* Load in one sample from each subband and clear inactive subbands */ - for (i = 0; i < sb_act; i++){ - uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ ((i-1)&2)<<30; - AV_WN32A(&s->raXin[i], v); - } - for (; i < 32; i++) - s->raXin[i] = 0.0; - - s->synth.synth_filter_float(&s->imdct, - s->subband_fir_hist[chans], &s->hist_index[chans], - s->subband_fir_noidea[chans], prCoeff, - samples_out, s->raXin, scale, bias); - samples_out+= 32; - - } -} - -static void lfe_interpolation_fir(DCAContext *s, int decimation_select, - int num_deci_sample, float *samples_in, - float *samples_out, float scale, - float bias) -{ - /* samples_in: An array holding decimated samples. - * Samples in current subframe starts from samples_in[0], - * while samples_in[-1], samples_in[-2], ..., stores samples - * from last subframe as history. - * - * samples_out: An array holding interpolated samples - */ - - int decifactor; - const float *prCoeff; - int deciindex; - - /* Select decimation filter */ - if (decimation_select == 1) { - decifactor = 64; - prCoeff = lfe_fir_128; - } else { - decifactor = 32; - prCoeff = lfe_fir_64; - } - /* Interpolation */ - for (deciindex = 0; deciindex < num_deci_sample; deciindex++) { - s->dcadsp.lfe_fir(samples_out, samples_in, prCoeff, decifactor, - scale, bias); - samples_in++; - samples_out += 2 * decifactor; - } -} - -/* downmixing routines */ -#define MIX_REAR1(samples, si1, rs, coef) \ - samples[i] += samples[si1] * coef[rs][0]; \ - samples[i+256] += samples[si1] * coef[rs][1]; - -#define MIX_REAR2(samples, si1, si2, rs, coef) \ - samples[i] += samples[si1] * coef[rs][0] + samples[si2] * coef[rs+1][0]; \ - samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs+1][1]; - -#define MIX_FRONT3(samples, coef) \ - t = samples[i]; \ - samples[i] = t * coef[0][0] + samples[i+256] * coef[1][0] + samples[i+512] * coef[2][0]; \ - samples[i+256] = t * coef[0][1] + samples[i+256] * coef[1][1] + samples[i+512] * coef[2][1]; - -#define DOWNMIX_TO_STEREO(op1, op2) \ - for(i = 0; i < 256; i++){ \ - op1 \ - op2 \ - } - -static void dca_downmix(float *samples, int srcfmt, - int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]) -{ - int i; - float t; - float coef[DCA_PRIM_CHANNELS_MAX][2]; - - for(i=0; i> 1; - - for (i = 0; i < 4; i++) { - int div = FASTDIV(code, levels); - values[i] = code - offset - div*levels; - code = div; - } - - if (code == 0) - return 0; - else { - av_log(NULL, AV_LOG_ERROR, "ERROR: block code look-up failed\n"); - return -1; - } -} - -static const uint8_t abits_sizes[7] = { 7, 10, 12, 13, 15, 17, 19 }; -static const uint8_t abits_levels[7] = { 3, 5, 7, 9, 13, 17, 25 }; - -static int dca_subsubframe(DCAContext * s) -{ - int k, l; - int subsubframe = s->current_subsubframe; - - const float *quant_step_table; - - /* FIXME */ - LOCAL_ALIGNED_16(float, subband_samples, [DCA_PRIM_CHANNELS_MAX], [DCA_SUBBANDS][8]); - LOCAL_ALIGNED_16(int, block, [8]); - - /* - * Audio data - */ - - /* Select quantization step size table */ - if (s->bit_rate_index == 0x1f) - quant_step_table = lossless_quant_d; - else - quant_step_table = lossy_quant_d; - - for (k = 0; k < s->prim_channels; k++) { - for (l = 0; l < s->vq_start_subband[k]; l++) { - int m; - - /* Select the mid-tread linear quantizer */ - int abits = s->bitalloc[k][l]; - - float quant_step_size = quant_step_table[abits]; - - /* - * Determine quantization index code book and its type - */ - - /* Select quantization index code book */ - int sel = s->quant_index_huffman[k][abits]; - - /* - * Extract bits from the bit stream - */ - if(!abits){ - memset(subband_samples[k][l], 0, 8 * sizeof(subband_samples[0][0][0])); - } else { - /* Deal with transients */ - int sfi = s->transition_mode[k][l] && subsubframe >= s->transition_mode[k][l]; - float rscale = quant_step_size * s->scale_factor[k][l][sfi] * s->scalefactor_adj[k][sel]; - - if(abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table){ - if(abits <= 7){ - /* Block code */ - int block_code1, block_code2, size, levels; - - size = abits_sizes[abits-1]; - levels = abits_levels[abits-1]; - - block_code1 = get_bits(&s->gb, size); - /* FIXME Should test return value */ - decode_blockcode(block_code1, levels, block); - block_code2 = get_bits(&s->gb, size); - decode_blockcode(block_code2, levels, &block[4]); - }else{ - /* no coding */ - for (m = 0; m < 8; m++) - block[m] = get_sbits(&s->gb, abits - 3); - } - }else{ - /* Huffman coded */ - for (m = 0; m < 8; m++) - block[m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel); - } - - s->dsp.int32_to_float_fmul_scalar(subband_samples[k][l], - block, rscale, 8); - } - - /* - * Inverse ADPCM if in prediction mode - */ - if (s->prediction_mode[k][l]) { - int n; - for (m = 0; m < 8; m++) { - for (n = 1; n <= 4; n++) - if (m >= n) - subband_samples[k][l][m] += - (adpcm_vb[s->prediction_vq[k][l]][n - 1] * - subband_samples[k][l][m - n] / 8192); - else if (s->predictor_history) - subband_samples[k][l][m] += - (adpcm_vb[s->prediction_vq[k][l]][n - 1] * - s->subband_samples_hist[k][l][m - n + - 4] / 8192); - } - } - } - - /* - * Decode VQ encoded high frequencies - */ - for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) { - /* 1 vector -> 32 samples but we only need the 8 samples - * for this subsubframe. */ - int m; - - if (!s->debug_flag & 0x01) { - av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n"); - s->debug_flag |= 0x01; - } - - for (m = 0; m < 8; m++) { - subband_samples[k][l][m] = - high_freq_vq[s->high_freq_vq[k][l]][subsubframe * 8 + - m] - * (float) s->scale_factor[k][l][0] / 16.0; - } - } - } - - /* Check for DSYNC after subsubframe */ - if (s->aspf || subsubframe == s->subsubframes - 1) { - if (0xFFFF == get_bits(&s->gb, 16)) { /* 0xFFFF */ -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "Got subframe DSYNC\n"); -#endif - } else { - av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n"); - } - } - - /* Backup predictor history for adpcm */ - for (k = 0; k < s->prim_channels; k++) - for (l = 0; l < s->vq_start_subband[k]; l++) - memcpy(s->subband_samples_hist[k][l], &subband_samples[k][l][4], - 4 * sizeof(subband_samples[0][0][0])); - - /* 32 subbands QMF */ - for (k = 0; k < s->prim_channels; k++) { -/* static float pcm_to_double[8] = - {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/ - qmf_32_subbands(s, k, subband_samples[k], &s->samples[256 * s->channel_order_tab[k]], - M_SQRT1_2*s->scale_bias /*pcm_to_double[s->source_pcm_res] */ , - s->add_bias ); - } - - /* Down mixing */ - - if (s->prim_channels > dca_channels[s->output & DCA_CHANNEL_MASK]) { - dca_downmix(s->samples, s->amode, s->downmix_coef); - } - - /* Generate LFE samples for this subsubframe FIXME!!! */ - if (s->output & DCA_LFE) { - int lfe_samples = 2 * s->lfe * s->subsubframes; - - lfe_interpolation_fir(s, s->lfe, 2 * s->lfe, - s->lfe_data + lfe_samples + - 2 * s->lfe * subsubframe, - &s->samples[256 * dca_lfe_index[s->amode]], - (1.0/256.0)*s->scale_bias, s->add_bias); - /* Outputs 20bits pcm samples */ - } - - return 0; -} - - -static int dca_subframe_footer(DCAContext * s) -{ - int aux_data_count = 0, i; - int lfe_samples; - - /* - * Unpack optional information - */ - - if (s->timestamp) - get_bits(&s->gb, 32); - - if (s->aux_data) - aux_data_count = get_bits(&s->gb, 6); - - for (i = 0; i < aux_data_count; i++) - get_bits(&s->gb, 8); - - if (s->crc_present && (s->downmix || s->dynrange)) - get_bits(&s->gb, 16); - - lfe_samples = 2 * s->lfe * s->subsubframes; - for (i = 0; i < lfe_samples; i++) { - s->lfe_data[i] = s->lfe_data[i + lfe_samples]; - } - - return 0; -} - -/** - * Decode a dca frame block - * - * @param s pointer to the DCAContext - */ - -static int dca_decode_block(DCAContext * s) -{ - - /* Sanity check */ - if (s->current_subframe >= s->subframes) { - av_log(s->avctx, AV_LOG_DEBUG, "check failed: %i>%i", - s->current_subframe, s->subframes); - return -1; - } - - if (!s->current_subsubframe) { -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_header\n"); -#endif - /* Read subframe header */ - if (dca_subframe_header(s)) - return -1; - } - - /* Read subsubframe */ -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n"); -#endif - if (dca_subsubframe(s)) - return -1; - - /* Update state */ - s->current_subsubframe++; - if (s->current_subsubframe >= s->subsubframes) { - s->current_subsubframe = 0; - s->current_subframe++; - } - if (s->current_subframe >= s->subframes) { -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_footer\n"); -#endif - /* Read subframe footer */ - if (dca_subframe_footer(s)) - return -1; - } - - return 0; -} - -/** - * Convert bitstream to one representation based on sync marker - */ -static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * dst, - int max_size) -{ - uint32_t mrk; - int i, tmp; - const uint16_t *ssrc = (const uint16_t *) src; - uint16_t *sdst = (uint16_t *) dst; - PutBitContext pb; - - if((unsigned)src_size > (unsigned)max_size) { -// av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n"); -// return -1; - src_size = max_size; - } - - mrk = AV_RB32(src); - switch (mrk) { - case DCA_MARKER_RAW_BE: - memcpy(dst, src, src_size); - return src_size; - case DCA_MARKER_RAW_LE: - for (i = 0; i < (src_size + 1) >> 1; i++) - *sdst++ = bswap_16(*ssrc++); - return src_size; - case DCA_MARKER_14B_BE: - case DCA_MARKER_14B_LE: - init_put_bits(&pb, dst, max_size); - for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) { - tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF; - put_bits(&pb, 14, tmp); - } - flush_put_bits(&pb); - return (put_bits_count(&pb) + 7) >> 3; - default: - return -1; - } -} - -/** - * Main frame decoding function - * FIXME add arguments - */ -static int dca_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - - int i; - int16_t *samples = data; - DCAContext *s = avctx->priv_data; - int channels; - - - s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE); - if (s->dca_buffer_size == -1) { - av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); - return -1; - } - - init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); - if (dca_parse_frame_header(s) < 0) { - //seems like the frame is corrupt, try with the next one - *data_size=0; - return buf_size; - } - //set AVCodec values with parsed data - avctx->sample_rate = s->sample_rate; - avctx->bit_rate = s->bit_rate; - - channels = s->prim_channels + !!s->lfe; - - if (s->amode<16) { - avctx->channel_layout = dca_core_channel_layout[s->amode]; - - if (s->lfe) { - avctx->channel_layout |= CH_LOW_FREQUENCY; - s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; - } else - s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; - - if (s->prim_channels > 0 && - s->channel_order_tab[s->prim_channels - 1] < 0) - return -1; - - if(avctx->request_channels == 2 && s->prim_channels > 2) { - channels = 2; - s->output = DCA_STEREO; - avctx->channel_layout = CH_LAYOUT_STEREO; - } - } else { - av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n",s->amode); - return -1; - } - - - /* There is nothing that prevents a dts frame to change channel configuration - but FFmpeg doesn't support that so only set the channels if it is previously - unset. Ideally during the first probe for channels the crc should be checked - and only set avctx->channels when the crc is ok. Right now the decoder could - set the channels based on a broken first frame.*/ - if (!avctx->channels) - avctx->channels = channels; - - if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) - return -1; - *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels; - for (i = 0; i < (s->sample_blocks / 8); i++) { - dca_decode_block(s); - s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels); - samples += 256 * channels; - } - - return buf_size; -} - - - -/** - * DCA initialization - * - * @param avctx pointer to the AVCodecContext - */ - -static av_cold int dca_decode_init(AVCodecContext * avctx) -{ - DCAContext *s = avctx->priv_data; - int i; - - s->avctx = avctx; - dca_init_vlcs(); - - dsputil_init(&s->dsp, avctx); - ff_mdct_init(&s->imdct, 6, 1, 1.0); - ff_synth_filter_init(&s->synth); - ff_dcadsp_init(&s->dcadsp); - - for(i = 0; i < 6; i++) - s->samples_chanptr[i] = s->samples + i * 256; - avctx->sample_fmt = SAMPLE_FMT_S16; - - if(s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { - s->add_bias = 385.0f; - s->scale_bias = 1.0 / 32768.0; - } else { - s->add_bias = 0.0f; - s->scale_bias = 1.0; - - /* allow downmixing to stereo */ - if (avctx->channels > 0 && avctx->request_channels < avctx->channels && - avctx->request_channels == 2) { - avctx->channels = avctx->request_channels; - } - } - - - return 0; -} - -static av_cold int dca_decode_end(AVCodecContext * avctx) -{ - DCAContext *s = avctx->priv_data; - ff_mdct_end(&s->imdct); - return 0; -} - -AVCodec dca_decoder = { - .name = "dca", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_DTS, - .priv_data_size = sizeof(DCAContext), - .init = dca_decode_init, - .decode = dca_decode_frame, - .close = dca_decode_end, - .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dca.h b/tizen/distrib/ffmpeg/libavcodec/dca.h deleted file mode 100644 index 02c0a51..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dca.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * DCA compatible decoder - * Copyright (C) 2004 Gildas Bazin - * Copyright (C) 2004 Benjamin Zores - * Copyright (C) 2006 Benjamin Larsson - * Copyright (C) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DCA_H -#define AVCODEC_DCA_H - -/** DCA syncwords, also used for bitstream type detection */ -#define DCA_MARKER_RAW_BE 0x7FFE8001 -#define DCA_MARKER_RAW_LE 0xFE7F0180 -#define DCA_MARKER_14B_BE 0x1FFFE800 -#define DCA_MARKER_14B_LE 0xFF1F00E8 - -/** DCA-HD specific block starts with this marker. */ -#define DCA_HD_MARKER 0x64582025 - -#endif /* AVCODEC_DCA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dca_parser.c b/tizen/distrib/ffmpeg/libavcodec/dca_parser.c deleted file mode 100644 index 01c5597..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dca_parser.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * DCA parser - * Copyright (C) 2004 Gildas Bazin - * Copyright (C) 2004 Benjamin Zores - * Copyright (C) 2006 Benjamin Larsson - * Copyright (C) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" -#include "dca.h" - -typedef struct DCAParseContext { - ParseContext pc; - uint32_t lastmarker; - int size; - int framesize; - int hd_pos; -} DCAParseContext; - -#define IS_MARKER(state, i, buf, buf_size) \ - ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \ - || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \ - || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE) - -/** - * 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 dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, - int buf_size) -{ - int start_found, i; - uint32_t state; - ParseContext *pc = &pc1->pc; - - start_found = pc->frame_start_found; - state = pc->state; - - i = 0; - if (!start_found) { - for (i = 0; i < buf_size; i++) { - state = (state << 8) | buf[i]; - if (IS_MARKER(state, i, buf, buf_size)) { - if (pc1->lastmarker && state == pc1->lastmarker) { - start_found = 1; - break; - } else if (!pc1->lastmarker) { - start_found = 1; - pc1->lastmarker = state; - break; - } - } - } - } - if (start_found) { - for (; i < buf_size; i++) { - pc1->size++; - state = (state << 8) | buf[i]; - if (state == DCA_HD_MARKER && !pc1->hd_pos) - pc1->hd_pos = pc1->size; - if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size)) { - if(pc1->framesize > pc1->size) - continue; - if(!pc1->framesize){ - pc1->framesize = pc1->hd_pos ? pc1->hd_pos : pc1->size; - } - pc->frame_start_found = 0; - pc->state = -1; - pc1->size = 0; - return i - 3; - } - } - } - pc->frame_start_found = start_found; - pc->state = state; - return END_NOT_FOUND; -} - -static av_cold int dca_parse_init(AVCodecParserContext * s) -{ - DCAParseContext *pc1 = s->priv_data; - - pc1->lastmarker = 0; - return 0; -} - -static int dca_parse(AVCodecParserContext * s, - AVCodecContext * avctx, - const uint8_t ** poutbuf, int *poutbuf_size, - const uint8_t * buf, int buf_size) -{ - DCAParseContext *pc1 = s->priv_data; - ParseContext *pc = &pc1->pc; - int next; - - if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { - next = buf_size; - } else { - next = dca_find_frame_end(pc1, buf, buf_size); - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser dca_parser = { - {CODEC_ID_DTS}, - sizeof(DCAParseContext), - dca_parse_init, - dca_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dcadata.h b/tizen/distrib/ffmpeg/libavcodec/dcadata.h deleted file mode 100644 index fbd22ab..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dcadata.h +++ /dev/null @@ -1,7636 +0,0 @@ -/* - * DCA compatible decoder data - * Copyright (C) 2004 Gildas Bazin - * Copyright (c) 2006 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DCADATA_H -#define AVCODEC_DCADATA_H - -#include -#include "libavutil/mem.h" - -/* Generic tables */ - -static const uint32_t dca_sample_rates[16] = -{ - 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, - 12000, 24000, 48000, 96000, 192000 -}; - -static const uint32_t dca_bit_rates[32] = -{ - 32000, 56000, 64000, 96000, 112000, 128000, - 192000, 224000, 256000, 320000, 384000, - 448000, 512000, 576000, 640000, 768000, - 896000, 1024000, 1152000, 1280000, 1344000, - 1408000, 1411200, 1472000, 1536000, 1920000, - 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/ -}; - -static const uint8_t dca_channels[16] = -{ - 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8 -}; - -static const uint8_t dca_bits_per_sample[7] = -{ - 16, 16, 20, 20, 0, 24, 24 -}; - - -/* Adpcm data */ - -/* 16bits signed fractional Q13 binary codes */ -static const int16_t adpcm_vb[4096][4] = -{ - { 9928, -2618, -1093, -1263 }, - { 11077, -2876, -1747, -308 }, - { 10503, -1082, -1426, -1167 }, - { 9337, -2403, -1495, 274 }, - { 10698, -2529, -532, -1122 }, - { 10368, -3974, -1264, -750 }, - { 10070, -3667, 346, 863 }, - { 10278, -3093, 311, -576 }, - { 9894, -1330, -1428, -860 }, - { 10544, -1923, -1058, -971 }, - { 10996, -1632, -841, -1404 }, - { 11832, -3465, 1658, -1990 }, - { 10852, -688, -2658, -499 }, - { 10546, -1749, -147, -1733 }, - { 10801, -1004, -708, -1453 }, - { 10588, -441, -2113, -952 }, - { 10141, -3331, -582, -1432 }, - { 9608, -2590, 383, 258 }, - { 11422, -3265, 229, -1544 }, - { 10460, -1338, -713, -1568 }, - { 10306, -1721, -1660, -603 }, - { 9580, -1812, -1235, -1061 }, - { 11471, -2285, -1617, -607 }, - { 10081, -2225, -1408, -868 }, - { 10715, -2624, -1367, -704 }, - { 10616, -1871, -2770, -35 }, - { 9352, -2340, -1024, -1566 }, - { 11065, -1458, -1926, -735 }, - { 11334, -2056, -1041, -1144 }, - { 9825, -2048, -794, -1536 }, - { 11850, -2695, -1123, -867 }, - { 10654, -2226, -1891, -373 }, - { 10024, -1557, -808, -1069 }, - { 11142, -1266, -3238, 128 }, - { 11729, -3282, -514, -1011 }, - { 11402, -2094, -2335, -189 }, - { 10195, -3658, 181, -1875 }, - { 11431, -2626, -404, -1377 }, - { 11001, -3868, -619, -1077 }, - { 10894, -2559, 274, -1758 }, - { 9633, -1482, -2253, -773 }, - { 11245, -3321, 830, -1972 }, - { 9768, -2701, -199, -1859 }, - { 10500, -2042, 525, -2043 }, - { 11669, -4069, 293, -1468 }, - { 9192, -1991, -583, -61 }, - { 10057, -3220, -2015, -473 }, - { 9497, -2315, -2490, -467 }, - { 10455, -3069, -1194, -1007 }, - { 9994, -1936, -60, -1225 }, - { 9295, -2156, -1761, -1134 }, - { 10085, -3748, -1026, 197 }, - { 9334, -2360, 804, -351 }, - { 11561, -2553, 1352, -2313 }, - { 12837, -3998, 1195, -1958 }, - { 10114, -1100, -2414, -394 }, - { 9341, -2530, 315, 755 }, - { 10131, -3164, 1411, -674 }, - { 9535, -905, -1551, 579 }, - { 11717, -1519, -3051, 91 }, - { 9824, -2911, -2775, 192 }, - { 9662, -2934, -561, 1450 }, - { 11085, -3392, -1298, -659 }, - { 8955, -2102, -1899, 703 }, - { 8607, -1742, -4348, 814 }, - { 7640, -2063, -3617, 52 }, - { 7074, -826, -4325, 4375 }, - { 7714, 584, -4238, 1927 }, - { 6355, -952, -4912, 3127 }, - { 7069, -660, -6413, 4087 }, - { 8313, -132, -2964, -876 }, - { 6952, -1422, -3962, -24 }, - { 9299, -734, -3088, -263 }, - { 9484, -574, -4513, 466 }, - { 7246, -91, -3735, -704 }, - { 8325, -1417, -3090, -530 }, - { 6469, -1226, -4757, 829 }, - { 6652, -368, -5682, 1393 }, - { 7971, -1278, -2284, 1205 }, - { 7229, -699, -3556, 1840 }, - { 7994, 1284, -2729, 732 }, - { 9005, -698, -4522, 2189 }, - { 6963, 197, -2727, 380 }, - { 8527, 135, -3991, -213 }, - { 8840, 934, -3014, -567 }, - { 10125, 418, -3284, -371 }, - { 6367, 361, -2318, 2554 }, - { 7892, 172, -5247, 4673 }, - { 6674, 387, -5424, 4398 }, - { 6240, 684, -4047, 1219 }, - { 11170, -794, -5081, 1195 }, - { 11765, -648, -6265, 2052 }, - { 10845, -775, -3837, 366 }, - { 12496, -689, -8260, 3562 }, - { 7893, -1166, -4972, 988 }, - { 8592, 1052, -5986, 3087 }, - { 7277, 1874, -5685, 3579 }, - { 6900, 2016, -4809, 3491 }, - { 8530, -2405, -3250, 1986 }, - { 9426, 494, -7067, 5038 }, - { 10285, 564, -8210, 5370 }, - { 8749, -2207, -3980, 2852 }, - { 9653, -2686, -4300, 1400 }, - { 9770, -2286, -5663, 4233 }, - { 8490, -4, -7048, 4496 }, - { 7697, -1209, -5328, 3183 }, - { 6451, 801, -4324, -554 }, - { 7387, 1806, -5265, 545 }, - { 7450, -2302, -4445, 1418 }, - { 8817, -1370, -5827, 2168 }, - { 10324, -2406, -5629, 2579 }, - { 8863, -2578, -3537, 467 }, - { 6901, -1624, -3169, 3392 }, - { 7846, 156, -6948, 3381 }, - { 7928, -1115, -5972, 4816 }, - { 6089, -599, -4368, -320 }, - { 7833, 1246, -3960, -621 }, - { 8931, 2521, -6768, 2052 }, - { 8900, 1944, -4126, 40 }, - { 7661, -34, -2855, 2480 }, - { 5873, 474, -3262, 3712 }, - { 7535, -234, -4699, 216 }, - { 5856, 143, -5142, 73 }, - { 8944, -106, -5874, 3663 }, - { 7134, 426, -5879, 2895 }, - { 10199, 1011, -4762, 369 }, - { 8454, 264, -5971, 1291 }, - { 7822, -2449, -4333, 4540 }, - { 6200, -2758, -2632, 1497 }, - { 6070, -4315, -2699, 414 }, - { 7047, -3739, -3210, 1060 }, - { 5675, -3801, -2717, -407 }, - { 4789, -4063, -2628, -744 }, - { 4023, -3366, -3133, -726 }, - { 4296, -2407, -3381, -513 }, - { 4388, -2931, -2820, 1512 }, - { 4559, -4233, -1941, 1976 }, - { 6702, -3208, -1755, 1680 }, - { 4416, -3521, -1052, 2984 }, - { 7154, -4266, -1203, 3732 }, - { 3625, -4242, -3244, 1395 }, - { 6518, -2856, -1304, 2887 }, - { 6170, -1949, -3014, 3973 }, - { 5189, -2451, -4020, 3477 }, - { 6218, -2988, -1921, 3844 }, - { 4827, -3688, -1928, 3343 }, - { 6668, -3991, -2805, 3095 }, - { 5297, -3115, -3684, 2390 }, - { 5354, -4614, -2662, 1504 }, - { 4196, -3091, -4147, 1135 }, - { 3540, -2893, -4007, 100 }, - { 5569, -1602, -4007, 1909 }, - { 4341, -2091, -4272, 252 }, - { 5559, -2878, -3832, 498 }, - { 4548, -4479, -2898, -27 }, - { 5176, -2494, -4635, 1476 }, - { 3294, -3485, -3738, 716 }, - { 4920, -1229, -4195, -365 }, - { 3257, -3518, -3349, 2862 }, - { 5286, -1948, -3485, -778 }, - { 6502, -3051, -152, 2854 }, - { 5864, -4192, -1076, 3451 }, - { 4656, -3122, -3448, 179 }, - { 5907, -754, -1596, 3116 }, - { 7229, -3680, -1590, 2892 }, - { 5107, -3888, -3364, 806 }, - { 6764, -2635, -3450, 134 }, - { 5258, -2827, -2844, -1052 }, - { 5798, -1725, -4305, 205 }, - { 5404, -1213, -3362, 449 }, - { 6224, -2738, -3046, -581 }, - { 4223, -2438, -2725, 3745 }, - { 4751, -3411, -2123, 116 }, - { 3868, -3000, -3954, 2297 }, - { 6819, -2899, -4277, 2825 }, - { 4207, -4754, -2808, 865 }, - { 4804, -1494, -1997, 4688 }, - { 5282, -2213, -548, 3559 }, - { 5580, -1912, -566, 4370 }, - { 6168, -2857, -672, 4053 }, - { 6583, -4515, -2850, 1670 }, - { 6511, -3093, -3988, 1421 }, - { 4646, -1790, -1443, 3650 }, - { 5915, -924, -2020, 896 }, - { 7814, -4181, -3152, 2007 }, - { 6190, -2238, -4817, 2279 }, - { 4737, -4034, -3288, 1835 }, - { 8161, -3633, -3423, 3137 }, - { 7415, -2351, -2088, 4290 }, - { 4106, -2517, -62, 2905 }, - { 4909, -3145, -614, 4112 }, - { 4938, -3281, -397, 1100 }, - { -173, 919, 1589, -5363 }, - { -13, 796, -295, -6655 }, - { -1860, -829, 1141, -4555 }, - { 2298, -838, -664, -5005 }, - { -884, -1097, 2074, -4613 }, - { -101, 281, 2846, -4535 }, - { 1166, 453, 2429, -5910 }, - { 879, -664, 2370, -5452 }, - { 1415, -370, -1699, -4727 }, - { -1413, 1277, -669, -6649 }, - { 2133, 304, -968, -4624 }, - { 380, 586, -2087, -4892 }, - { 1336, 275, -82, -5789 }, - { -2459, 1057, -34, -5416 }, - { 2278, -1758, 866, -5653 }, - { 1945, -2295, -149, -5302 }, - { 1287, -3525, 996, -5255 }, - { 2297, 803, 1177, -6067 }, - { 187, -180, -619, -6202 }, - { -793, -2537, 1554, -5057 }, - { -2703, -204, -629, -5853 }, - { -1007, -146, 313, -5582 }, - { 830, 357, 869, -6363 }, - { -228, -575, -3177, -4433 }, - { -1001, -1553, -142, -5708 }, - { -1644, 1683, 1721, -4533 }, - { 893, 1924, -15, -5791 }, - { 2195, 2061, -262, -5471 }, - { 3031, 270, 311, -5096 }, - { 1912, 1638, -1523, -4677 }, - { -3142, -55, 253, -4914 }, - { 356, -1680, 343, -6123 }, - { -2241, -1734, -976, -5939 }, - { -2196, -2893, 547, -4938 }, - { -1245, 126, -1916, -5419 }, - { -249, -3755, -1422, -5594 }, - { 575, -2683, -1926, -4566 }, - { -762, 1885, 192, -5880 }, - { -811, -2562, -1068, -6013 }, - { -2264, -3086, -976, -4775 }, - { 70, -1215, 2880, -4410 }, - { 714, -3760, 2916, -4691 }, - { -244, -3404, 1740, -4493 }, - { 684, -5137, -328, -5608 }, - { -529, -3825, -1786, -4535 }, - { -713, -4743, -1118, -5546 }, - { 2718, -3788, 1798, -5708 }, - { -1639, -3679, -1564, -6095 }, - { 1693, -2642, -1389, -4539 }, - { 505, -1573, -1651, -4878 }, - { -835, -2256, -1941, -5352 }, - { 1464, -411, 1993, -6441 }, - { 493, -3184, -145, -6148 }, - { -1413, 499, -1617, -6479 }, - { -294, 1722, -1419, -5725 }, - { -2937, -1528, -175, -4624 }, - { -594, -5911, -56, -6146 }, - { -300, -4275, 1156, -5947 }, - { 552, -2643, 2669, -3959 }, - { 905, -4158, 1789, -5809 }, - { 1336, -2009, 2108, -5903 }, - { 1555, -3600, 1110, -6759 }, - { -1294, -3464, 77, -6084 }, - { -1139, -4006, -1270, -4181 }, - { -5094, -3296, 1092, -2847 }, - { -5503, -2883, 1984, -2067 }, - { -4671, -4218, -1417, -4132 }, - { -3763, -3818, 1262, -3082 }, - { -5132, -3430, 2928, -728 }, - { -5957, -2877, 1251, -2446 }, - { -4425, -2319, -212, -4276 }, - { -6201, -1993, 1774, -2182 }, - { -5500, -3836, 2201, -1396 }, - { -6934, -2334, 2366, -1293 }, - { -6124, -4140, 1337, -1977 }, - { -6553, -4186, 1756, -1325 }, - { -5126, -1258, 744, -3656 }, - { -5167, -1390, 1581, -2895 }, - { -4525, -3398, 2429, -1865 }, - { -4076, -3183, 2027, -2510 }, - { -6191, -3274, 1838, -1814 }, - { -4454, -2753, 2723, -1185 }, - { -6655, -4797, 251, -2595 }, - { -6332, -2232, 1832, 217 }, - { -5869, -1698, 134, 340 }, - { -6614, -1045, 2126, -1932 }, - { -4859, -2107, 2010, -2435 }, - { -6274, -1622, 2808, -1374 }, - { -3119, -3209, 521, -3988 }, - { -5676, -2082, -420, -2711 }, - { -7073, -3623, 696, -2343 }, - { -5986, -4224, 572, -2454 }, - { -4340, -4521, 882, -2771 }, - { -6178, -1933, 535, -1444 }, - { -4923, -4163, 1744, -2066 }, - { -6410, -1519, 1058, -2683 }, - { -5077, -1185, 856, -2216 }, - { -7091, -2444, 687, -2597 }, - { -5284, -2165, 3239, -993 }, - { -4763, -1497, 197, -3179 }, - { -4128, -4958, -396, -3578 }, - { -5054, -3878, -647, -2672 }, - { -7005, -3348, 1679, -1579 }, - { -5767, -1017, 2582, -1915 }, - { -7069, -2787, 1331, -2070 }, - { -5532, -2296, 706, -2950 }, - { -5059, -3543, -821, -3637 }, - { -6639, -1835, 1016, -696 }, - { -5611, -5220, -694, -3371 }, - { -5994, -2803, 2933, -729 }, - { -5948, -619, 1596, -2676 }, - { -5486, -4419, 153, -3265 }, - { -4329, -3440, 1646, -1439 }, - { -4083, -3978, 177, -3569 }, - { -4289, -2599, 1224, -3075 }, - { -5707, -3253, 1912, -759 }, - { -6606, -3437, 2562, -571 }, - { -5254, -2444, 769, -352 }, - { -6545, -3154, 582, -1103 }, - { -5328, -2241, 2566, -1775 }, - { -7216, -1936, 1538, -1983 }, - { -3730, -2451, 426, -3869 }, - { -5110, -1385, 2031, -1169 }, - { -6470, -2715, 269, -3123 }, - { -5806, -2480, -97, -3832 }, - { -3683, -4916, -490, -4330 }, - { -6341, -2083, -669, -115 }, - { -4913, -4079, -837, -4673 }, - { -3274, -2497, 2334, -2652 }, - { -1286, -1731, 2550, -3756 }, - { -3375, -877, 926, -3977 }, - { -2525, -2079, 2879, -2625 }, - { -5308, -504, 3111, -1607 }, - { -4904, 460, 4093, -1232 }, - { -1993, 1616, 4656, -1913 }, - { -3481, -1176, 3119, -2236 }, - { -4132, -1502, 2339, -2545 }, - { -2542, 1151, 3569, -2550 }, - { -4381, 430, 3147, -2082 }, - { -3888, 867, 3899, -1657 }, - { -2861, 1290, 4202, -1979 }, - { -3893, -253, 2363, -2764 }, - { -1705, 688, 3827, -2923 }, - { -2223, 2312, 3700, -3148 }, - { -1986, -720, 5021, -795 }, - { -3177, 242, 1952, -3352 }, - { -1854, 1509, 2528, -3815 }, - { -3173, 97, 5019, -706 }, - { -2689, -145, 1375, -3915 }, - { -4838, -385, 2488, -2427 }, - { -4557, -355, 1603, -3060 }, - { -3522, 1832, 3292, -2674 }, - { -3769, 780, 2378, -2704 }, - { -4323, -1932, 3414, -1169 }, - { -2740, 1158, 2729, -3273 }, - { -3647, 210, 1464, -2892 }, - { -2342, -2097, 1513, -3727 }, - { -4422, -1242, 3130, -1833 }, - { -1308, -1039, 4290, -1875 }, - { -1754, -2535, 3298, -2314 }, - { -4102, -186, 4037, -1094 }, - { -1008, 1570, 3290, 171 }, - { -3322, -2621, 2791, -1536 }, - { -2539, -2597, 3442, -1672 }, - { -3411, -2015, 3670, -1174 }, - { -2097, 730, 5581, -1399 }, - { -1510, -74, 4820, -2004 }, - { -4086, -868, 4425, -771 }, - { -956, -986, 3640, -2925 }, - { -2087, -1250, 3464, -2458 }, - { -3308, -2411, 1334, -3667 }, - { -2264, -389, 4004, -1854 }, - { -680, 239, 4058, -3388 }, - { -1357, 30, 2993, -3658 }, - { -3601, -552, 1177, -1136 }, - { -2641, 442, 4374, -1625 }, - { -2525, 770, 1640, -3895 }, - { -3172, -891, 3893, -1608 }, - { -2996, 13, 3277, -2414 }, - { -899, 1055, 4470, -2501 }, - { -422, -584, 3475, -3787 }, - { -1978, -593, 2566, -3415 }, - { -3150, -1280, 2362, -3047 }, - { -3592, 224, 1026, -3932 }, - { -4840, -1189, 3633, -879 }, - { -3952, -2255, 2916, -1826 }, - { -1695, 28, 1810, -349 }, - { -745, -2484, 3308, -3293 }, - { -1016, 1563, 5365, -1823 }, - { -2172, -1787, 4266, -1287 }, - { -1241, -1951, 3982, -2413 }, - { -2009, -2639, 2330, -3480 }, - { 5105, -1618, -2588, -2015 }, - { 6497, -1523, -3218, -910 }, - { 6526, -2305, -2029, -1790 }, - { 5289, -99, -3436, -400 }, - { 5781, -1623, -1577, -2617 }, - { 5259, -670, -3125, -1700 }, - { 6343, -1256, -331, -3222 }, - { 7967, -678, -2195, -1462 }, - { 6119, -695, -2988, -1538 }, - { 6108, 494, -3359, -1548 }, - { 5067, 969, -2328, -2707 }, - { 7595, -435, -1497, -2056 }, - { 6929, -719, -2420, -1665 }, - { 5190, 584, -2982, -2103 }, - { 6106, -444, -1411, -2739 }, - { 5584, 289, -1804, -2803 }, - { 5276, 227, -1180, -3361 }, - { 7544, -1525, -1834, -1725 }, - { 5986, -1470, -2606, -1701 }, - { 5096, -765, -1712, -3006 }, - { 5423, -149, -3933, -1157 }, - { 7651, 26, -2445, -1507 }, - { 4745, -464, -1735, -2362 }, - { 5352, -1011, -1094, -1999 }, - { 6300, -672, -542, -1950 }, - { 6675, -1020, -1318, -1059 }, - { 7218, -2036, -603, -2462 }, - { 7755, -1514, -2430, -1229 }, - { 5041, 449, -1056, -2405 }, - { 6710, -2277, -1344, -2284 }, - { 6824, -1347, -2254, 251 }, - { 6068, -1857, -983, -1316 }, - { 5603, -2177, -2730, -1477 }, - { 5838, -1059, -3604, -970 }, - { 5076, -789, -335, -2413 }, - { 6191, -1634, -2000, -2129 }, - { 5092, -1292, -2543, -1034 }, - { 5305, 435, -1710, -1850 }, - { 6140, 561, -2176, -2380 }, - { 6752, 348, -2496, -1890 }, - { 6405, 273, -1098, -2778 }, - { 6942, -1340, -496, -1381 }, - { 5238, -687, -2454, -2349 }, - { 6959, -882, -1833, -2061 }, - { 6292, -253, -2125, -2199 }, - { 5838, -574, -759, -3215 }, - { 6954, -1484, -640, -2771 }, - { 7498, -1706, -1210, -2154 }, - { 6772, -1003, -1235, -2532 }, - { 6014, 228, -2154, -1108 }, - { 6943, -2178, -2644, -1122 }, - { 7262, -763, -3056, -1090 }, - { 6273, -1478, -1072, 177 }, - { 4734, 425, -2912, 357 }, - { 7129, 168, -1537, -2327 }, - { 7204, -434, -746, -2660 }, - { 6879, 57, -3087, -1310 }, - { 4623, -610, -718, -3459 }, - { 6565, -543, -1998, -339 }, - { 4752, -277, -2066, -1405 }, - { 7435, -1416, -1904, -505 }, - { 4076, 150, -1222, -3556 }, - { 7082, -28, -1456, -1174 }, - { 5941, -446, -1326, -1158 }, - { 3870, -1648, -2474, -2589 }, - { 858, 37, -3387, -3721 }, - { 3557, -1503, -1664, -3383 }, - { 3336, -1972, -3079, -2216 }, - { 3186, 60, -4185, -863 }, - { 3456, -773, -3066, -2457 }, - { 4131, -913, -2060, -2601 }, - { 4431, -691, -4114, -972 }, - { 3461, -334, -3680, -1751 }, - { 2006, -459, -2214, -3827 }, - { 1322, 32, -2816, -3203 }, - { 4425, -1897, -2791, -1946 }, - { 4504, 23, -3421, -1909 }, - { 3090, -885, -2366, -3264 }, - { 3209, -2363, -3730, -834 }, - { 3312, -1471, -3641, -1579 }, - { 4184, -1669, -3323, -1248 }, - { 2190, -931, -3302, -2944 }, - { 2947, -229, -4791, -1195 }, - { 2020, -1626, -2700, -3125 }, - { 2214, -326, -4352, -1683 }, - { 3286, -2619, -2412, -2458 }, - { 1000, -2571, -4129, -2158 }, - { 2496, -2627, -3611, -1433 }, - { 2043, -2191, -2167, -3827 }, - { 2571, -2544, -1915, -3222 }, - { 2022, -1501, -3856, -2165 }, - { 2685, -1180, -1461, -4038 }, - { 1610, -2313, -4391, -1173 }, - { 2340, -2490, -4215, -516 }, - { 1742, -2615, -3632, -2146 }, - { 523, -1293, -4246, -2442 }, - { 3725, -2723, -3014, -1576 }, - { 3554, -1381, -4200, -824 }, - { 1291, -1594, -4777, -1430 }, - { 1452, 515, -2960, -3830 }, - { 4264, -894, -3305, -1826 }, - { 2606, -1452, -4522, -966 }, - { 1196, -830, -4807, -1816 }, - { 1054, -775, -2616, -4071 }, - { 4206, 415, -4344, -1132 }, - { 3044, 491, -4126, -1934 }, - { 988, -901, -3353, -3443 }, - { 1729, -3063, -2267, -3370 }, - { 3915, 912, -2989, -2387 }, - { 3781, 300, -2457, -3050 }, - { 2712, 924, -1350, -1206 }, - { 4230, 405, -2343, 665 }, - { 1878, -873, -225, -29 }, - { 3510, 56, -1334, -3420 }, - { 2850, 1447, -2651, -3150 }, - { 1510, -706, -4125, -2483 }, - { 3115, 793, -1692, -3894 }, - { 2667, 213, -2973, -2786 }, - { 1184, -2384, -3051, -3173 }, - { 2139, 796, -2079, -3697 }, - { 1464, -1483, -3726, -2754 }, - { 2407, -1148, -3915, -1569 }, - { 2612, -1779, -3217, -2271 }, - { 2406, -2870, -2937, -2496 }, - { 2140, 126, -3646, -2758 }, - { 2952, -1036, 268, -1423 }, - { 93, -1931, -3841, -3535 }, - { 389, -2953, -3383, -3343 }, - { 8652, -5511, -1662, 565 }, - { 7427, -2791, -2535, -842 }, - { 8541, -4253, -1407, -988 }, - { 8018, -3203, -2998, 105 }, - { 7231, -3926, -958, 1308 }, - { 7331, -3690, -363, 2586 }, - { 6803, -3646, -2226, -903 }, - { 8163, -2811, -477, -2235 }, - { 9356, -3818, -1685, -684 }, - { 8466, -2854, -302, -698 }, - { 8458, -3224, 517, 279 }, - { 8074, -2619, -1326, 2596 }, - { 8779, -2761, -2527, -441 }, - { 6533, -2887, -899, -696 }, - { 7394, -2305, -1642, -120 }, - { 8281, -3780, -22, 1305 }, - { 9158, -4413, -779, 901 }, - { 9031, -5240, -1109, 1678 }, - { 8717, -3650, 410, -1075 }, - { 7317, -3197, -818, -2264 }, - { 7934, -2385, -1214, -1886 }, - { 8256, -4441, -291, -587 }, - { 7358, -3395, 1090, -270 }, - { 9446, -4910, -1343, -473 }, - { 8187, -4726, -808, 1166 }, - { 7504, -3845, -47, 267 }, - { 8029, -2146, -1283, -383 }, - { 7461, -2705, -853, 783 }, - { 9367, -3636, -645, -354 }, - { 8955, -3473, -308, -1947 }, - { 8676, -2683, -2099, 1485 }, - { 7481, -3003, -871, -444 }, - { 8015, -2839, -1673, 1175 }, - { 6947, -4643, -1527, -1047 }, - { 7622, -2575, -137, -960 }, - { 9388, -4279, -707, -1322 }, - { 8382, -5259, -1283, -565 }, - { 6856, -4138, -1030, 630 }, - { 8659, -2571, -1124, -1666 }, - { 8763, -3807, -537, 2543 }, - { 8049, -3578, -2186, -604 }, - { 8272, -2351, -1985, -1214 }, - { 6855, -3796, -1527, -1631 }, - { 7178, -2896, -1600, -1756 }, - { 7040, -2888, -89, -1586 }, - { 6261, -3403, -264, 998 }, - { 7756, -4699, -1543, -834 }, - { 7682, -4622, -758, -1721 }, - { 8839, -4232, -2932, 1959 }, - { 9363, -4679, -1956, 39 }, - { 7883, -3616, -1414, -1432 }, - { 8828, -3188, -1356, -1312 }, - { 7746, -3987, -121, -2424 }, - { 9262, -3256, -693, 818 }, - { 7670, -3420, -148, 3504 }, - { 7344, -3183, 608, 1595 }, - { 8976, -4139, -1848, 1304 }, - { 6708, -4131, 33, -852 }, - { 7840, -4429, -2275, 79 }, - { 8980, -3858, -2838, 453 }, - { 7815, -4604, -2563, 944 }, - { 8372, -4422, -1783, 3071 }, - { 8623, -5128, -1754, 2888 }, - { 7462, -3281, 889, 920 }, - { 8416, -59, -1320, -1825 }, - { 7928, -1488, -414, -2499 }, - { 8110, -977, -1047, -2042 }, - { 8278, -687, -1597, -1550 }, - { 7988, -174, -977, -2106 }, - { 8609, -1547, -1628, -1527 }, - { 9000, -1798, -946, -1761 }, - { 8954, -872, -1404, -1594 }, - { 8939, 466, -748, -1212 }, - { 9549, -329, -177, -1360 }, - { 9411, -18, -1126, -1568 }, - { 8859, -782, -488, -1338 }, - { 8955, -218, -43, -1209 }, - { 9131, -69, -453, -1001 }, - { 9069, -1519, -1091, -1199 }, - { 9247, -1309, -566, -1146 }, - { 8528, -1617, -287, -1313 }, - { 7763, -745, -149, -2040 }, - { 8294, -343, 257, -2633 }, - { 10149, -893, -552, -1649 }, - { 9398, -915, 218, -2042 }, - { 9703, -1194, -675, -1592 }, - { 9586, -700, -427, -1710 }, - { 8930, 497, -1445, -1218 }, - { 9285, -1323, -163, -1552 }, - { 8431, -1289, -985, -1404 }, - { 8965, -655, 653, -1483 }, - { 9542, -1001, -951, -1128 }, - { 9205, -647, -37, -882 }, - { 8603, -56, 514, -1793 }, - { 9300, -12, -1324, -567 }, - { 8773, 238, -184, -1456 }, - { 9941, -1306, -69, -1792 }, - { 9360, 279, -376, -1919 }, - { 9180, -285, 95, -2170 }, - { 9922, -501, -970, -1570 }, - { 8341, -1493, -856, -2092 }, - { 8780, -981, -850, -1014 }, - { 9721, -548, -1504, -1094 }, - { 9973, -1493, 482, -2105 }, - { 8707, -333, -1027, -1087 }, - { 9098, -469, -315, -1723 }, - { 8879, -1050, -661, -2020 }, - { 8857, 602, -866, -1918 }, - { 8945, -1025, -2154, -1071 }, - { 8484, -1930, -468, -2179 }, - { 9177, -1903, -224, -2112 }, - { 8652, -137, -2097, -1214 }, - { 9063, -973, -1405, -772 }, - { 9328, -456, 662, -2469 }, - { 10101, -697, 127, -2113 }, - { 9685, 811, -2359, -1024 }, - { 8586, -94, -460, -1982 }, - { 7924, -141, -509, -2513 }, - { 7773, -669, -107, -2835 }, - { 8636, -1064, -46, -2409 }, - { 9748, 596, -1815, -1349 }, - { 8924, 304, 547, -2614 }, - { 9442, 746, -1153, -1679 }, - { 9454, -278, -529, -1976 }, - { 8488, 561, -32, -2160 }, - { 10083, -63, -1544, -1364 }, - { 9390, -1278, 568, -1131 }, - { 9740, -49, -2253, -910 }, - { 3636, -2391, -1115, -3614 }, - { 6014, -3204, -1902, -1808 }, - { 5787, -3497, -1116, -2590 }, - { 4365, -3046, -1632, -2668 }, - { 4733, -2192, -2029, -2468 }, - { 5412, -2753, -1633, -2464 }, - { 4455, -3375, -767, -3399 }, - { 4456, -1644, -983, -2841 }, - { 4039, -2523, 38, -3967 }, - { 3406, -2662, 72, -4757 }, - { 4279, -2005, 1055, -4399 }, - { 4321, -1377, -860, -3786 }, - { 3743, -5739, -651, -3047 }, - { 3528, -5510, 361, -4060 }, - { 6496, -4886, -136, -2689 }, - { 4513, -5254, 551, -4010 }, - { 6557, -3413, -92, -3063 }, - { 4186, -2059, 187, 47 }, - { 6210, -4117, -1256, -1985 }, - { 6038, -4343, 351, -2124 }, - { 4305, -4780, -2077, -1897 }, - { 4480, -3815, -2228, -1533 }, - { 5582, -3689, 1221, -3429 }, - { 5532, -4874, 1195, -2765 }, - { 6518, -2853, -905, -2568 }, - { 5467, -2192, 470, -4115 }, - { 4139, -1577, 240, -3493 }, - { 5281, -1926, -729, -3340 }, - { 5214, -2870, 1359, -4289 }, - { 3046, -3510, -1536, -3214 }, - { 5433, -2881, -1230, -1184 }, - { 4861, -3932, -1071, -2791 }, - { 5693, -4234, -1906, -1502 }, - { 4004, -3935, -1804, -2383 }, - { 3728, -3792, 681, -4773 }, - { 3621, -3030, -1951, -2598 }, - { 5133, -3903, 44, -3700 }, - { 3561, -3451, 1183, -5301 }, - { 5026, -2762, -2341, -1780 }, - { 5841, -2492, -467, -3210 }, - { 5591, -1791, 497, -2472 }, - { 5054, -3898, -1822, -2097 }, - { 5813, -2792, 83, -1469 }, - { 4432, -4497, 1670, -5193 }, - { 5338, -4653, -1109, -2200 }, - { 3239, -4401, -648, -3655 }, - { 2147, -3598, -1200, -4242 }, - { 4417, -2271, -1552, -3210 }, - { 6494, -4360, 852, -3565 }, - { 2393, -6358, -856, -4524 }, - { 4959, -4196, -847, -1403 }, - { 4924, -5438, -226, -3026 }, - { 4254, -5303, -1306, -2424 }, - { 4121, -3126, -2334, -1981 }, - { 3437, -4443, -1464, -2953 }, - { 3203, -3459, -529, -4339 }, - { 5896, -5945, 543, -3246 }, - { 1987, -4733, -220, -4863 }, - { 4358, -4431, -514, -3081 }, - { 4583, -2416, -492, -2287 }, - { 2943, -5035, 419, -4927 }, - { 5358, -5129, 987, -4309 }, - { 4460, -3392, 1752, -5634 }, - { 3415, -4633, 1507, -5945 }, - { 811, -4692, -445, 2333 }, - { 1009, -5613, -1857, 1360 }, - { 1338, -2712, -2720, 3036 }, - { 1002, -3754, -2582, 2344 }, - { 750, -4608, -2334, 714 }, - { 2043, -3207, -2822, 2173 }, - { -140, -4654, -2953, 357 }, - { -54, -4026, -2376, 2695 }, - { 1858, -5022, -717, 2287 }, - { 2064, -3894, -722, 3255 }, - { 2727, -4558, -332, 2603 }, - { 1810, -5378, 283, 1826 }, - { 3935, -4326, 762, 3383 }, - { -767, -4697, -2510, 1922 }, - { 2146, -4312, -3090, 1641 }, - { 54, -5881, -2114, 921 }, - { 1992, -5766, -640, 1574 }, - { 1200, -5371, -1114, 1828 }, - { 2973, -5337, 34, 2266 }, - { 1531, -5018, -2817, 1192 }, - { 3078, -4570, 117, 1990 }, - { 924, -4286, -1388, 2713 }, - { 142, -5058, -2848, 1487 }, - { -106, -6180, -881, 842 }, - { 673, -5433, -229, 1596 }, - { 783, -5710, -2784, 562 }, - { 1935, -5729, -2009, 856 }, - { -410, -3375, -3326, 2734 }, - { 234, -3000, -2628, 3260 }, - { 733, -3405, -3806, 1589 }, - { 771, -4285, -3544, 1314 }, - { 1192, -3563, -3960, 2178 }, - { 206, -5555, -1250, 1546 }, - { -130, -3815, -1210, 3041 }, - { 646, -3940, -393, 2992 }, - { -184, -4931, -1767, 1925 }, - { 2746, -5120, -2275, 1464 }, - { 2440, -3731, -3352, 2729 }, - { -490, -4942, -3779, 997 }, - { 68, -2636, -4167, 3778 }, - { 48, -3986, -4118, 2106 }, - { -978, -5486, -1336, 1390 }, - { 1126, -5297, -855, 640 }, - { -472, -3975, -3622, 1557 }, - { 2456, -5344, -1523, 1648 }, - { -774, -5652, -2417, 1147 }, - { 995, -6122, -812, 1132 }, - { 3282, -4571, -1763, 2175 }, - { 3655, -3862, -676, 3568 }, - { 3038, -3647, -1672, 3381 }, - { 2595, -2964, -2772, 3263 }, - { 4176, -3353, -1148, 4354 }, - { 1603, -3442, -1500, 3444 }, - { 828, -6226, -1783, 678 }, - { 1421, -3333, -3080, 3403 }, - { 1121, -4727, -1924, 1984 }, - { -186, -5083, -682, 1796 }, - { 819, -2778, -3488, 530 }, - { 421, -2873, -3832, 2596 }, - { 2164, -4263, -1605, 2282 }, - { 585, -4437, -682, -491 }, - { -644, -4452, -1157, 2325 }, - { 1991, -4299, 210, 2834 }, - { 2135, -3632, -2113, 665 }, - { -7482, -2724, -2662, -1380 }, - { -6983, -2166, -3756, -3509 }, - { -7085, -1439, -2397, -3112 }, - { -7760, -3049, -3319, -2822 }, - { -8413, -2760, -4406, -3298 }, - { -5995, -3943, -1260, -3750 }, - { -7879, -1554, -3464, -2606 }, - { -6314, -2034, -3878, -1681 }, - { -8849, -2084, -1399, -1231 }, - { -7153, -2602, -1384, -817 }, - { -8041, -2571, -407, -2785 }, - { -7246, -2233, -1578, 260 }, - { -7336, -3883, -4061, -1342 }, - { -7619, -3908, -2342, 382 }, - { -8684, -3724, -1662, -727 }, - { -7850, -2922, -1770, -3449 }, - { -6766, -2034, -1293, -1988 }, - { -6895, -2116, -968, -3744 }, - { -7136, -5147, -2618, -2809 }, - { -8224, -3724, -2519, -1589 }, - { -6711, -2750, -3021, -219 }, - { -8059, -1638, -1102, -3175 }, - { -8710, -4839, -3963, -3143 }, - { -9363, -4965, -3257, -1002 }, - { -6099, -1751, -3157, -395 }, - { -6453, -3216, -4597, -483 }, - { -7879, -5477, -839, -2638 }, - { -7202, -4038, -526, -2856 }, - { -8022, -1228, -1910, -1646 }, - { -9117, -1393, -1582, -2535 }, - { -9095, -2693, -636, -2605 }, - { -9076, -2580, -3481, -2519 }, - { -8327, -4859, -2422, 83 }, - { -8368, -2129, -2324, -2173 }, - { -8554, -4563, -3842, -2007 }, - { -10462, -4261, -1934, -2084 }, - { -9717, -3187, -2294, -1896 }, - { -9625, -3889, -3020, -3224 }, - { -9857, -4955, -4239, -2184 }, - { -9752, -2351, -2277, -3129 }, - { -7219, -1302, -2639, -1603 }, - { -7477, -4360, -3718, -559 }, - { -5680, -2033, -2326, -3078 }, - { -10190, -5548, -4643, -3601 }, - { -9431, -4121, -879, -2479 }, - { -8365, -5450, -2020, -1439 }, - { -6289, -5178, -1605, -3845 }, - { -8319, -3866, -687, -2792 }, - { -8131, -1031, -3608, -3947 }, - { -10510, -2560, -1199, -2082 }, - { -11015, -3640, -2748, -3041 }, - { -8762, -5022, -5231, -1162 }, - { -10153, -2715, -4648, -4859 }, - { -7930, -5205, -1900, -3600 }, - { -9561, -3548, -4812, -3722 }, - { -7663, -4709, -1180, -1475 }, - { -9073, -5707, -1815, -2980 }, - { -8602, -2363, -2675, -3770 }, - { -9967, -5614, -3575, -3838 }, - { -8324, -1005, -2131, -3254 }, - { -10331, -5737, -2550, -2940 }, - { -8234, -3354, -3361, -4479 }, - { -8140, -1951, -4526, -4545 }, - { -6679, -2662, -2284, -4182 }, - { -1122, -1514, -6427, -212 }, - { 54, -1660, -5424, -1404 }, - { 254, -2778, -5222, 846 }, - { -267, -1661, -6577, 814 }, - { -305, -2021, -5759, 1484 }, - { -1791, -2446, -6867, -86 }, - { -2929, -3158, -6603, -1799 }, - { -1391, -3189, -5557, -1053 }, - { -1602, -884, -6767, -1213 }, - { -361, -318, -6219, -44 }, - { -4078, -2635, -5523, -433 }, - { -956, 478, -4382, 1470 }, - { -3300, -2462, -6021, -2721 }, - { 708, -2434, -5085, -540 }, - { -2435, -3607, -5647, -2110 }, - { -491, -1134, -4681, -2886 }, - { 87, -3435, -4641, -1194 }, - { -586, -2927, -4784, 366 }, - { -1394, -2326, -6021, 350 }, - { 97, -2519, -4678, -2120 }, - { -1547, -1907, -5069, -2993 }, - { 268, -3724, -4719, 127 }, - { -827, -1190, -5912, 1144 }, - { -3959, -2322, -6898, -1974 }, - { -2728, -2228, -6426, -562 }, - { -456, -666, -5785, -1609 }, - { 531, -1096, -5731, -656 }, - { -3569, -688, -3915, 110 }, - { -4752, -1725, -4393, -377 }, - { -3210, -3315, -6960, -840 }, - { -688, -3416, -4971, 1221 }, - { -1833, 77, -6491, -2434 }, - { -239, -255, -6850, -886 }, - { -2112, -1490, -6291, -2689 }, - { -1544, -4579, -5198, -1261 }, - { -2771, -4014, -5520, 683 }, - { -1635, -2829, -5512, 1214 }, - { -958, -2582, -4823, 2360 }, - { -2077, -4566, -4642, 365 }, - { -3112, -4214, -5960, -823 }, - { -2467, -2510, -4858, 1467 }, - { -1561, -3399, -5822, 211 }, - { -775, -1081, -4424, 2636 }, - { -1263, 25, -6378, -1392 }, - { -3476, -366, -5417, -1393 }, - { -3176, -1476, -4149, 1466 }, - { -2479, 518, -4448, -257 }, - { -2992, 158, -4660, -1279 }, - { -1320, -3872, -4479, 1147 }, - { -1475, -312, -5318, 539 }, - { -3527, -1679, -5860, -1681 }, - { -3397, -3438, -5593, 1866 }, - { -4089, -2439, -4763, 1275 }, - { -748, -4513, -4687, -48 }, - { -2166, -4531, -4691, -2856 }, - { -2385, -853, -6035, -627 }, - { -1194, -4091, -4472, -1963 }, - { -682, -3234, -4084, -3033 }, - { -3255, -5015, -5328, -12 }, - { -2313, -3436, -4601, -155 }, - { -2792, -1038, -6947, -2019 }, - { -1244, -1526, -5771, -1882 }, - { -4679, -3731, -5506, 283 }, - { -3062, -66, -3558, -758 }, - { -4895, -1187, 4751, 3728 }, - { -7600, -2752, 3320, 4613 }, - { -5703, -2975, 3944, 2659 }, - { -4972, -1257, -246, 2952 }, - { -4221, -2487, 1702, 4295 }, - { -2900, -1529, 2458, 4935 }, - { -5061, 407, 2416, 4050 }, - { -6931, -3478, 2761, 2213 }, - { -6037, -3921, 3192, 1866 }, - { -6113, -811, 2407, 3782 }, - { -5878, -1716, 1207, 3478 }, - { -5953, -2853, 2207, 2712 }, - { -6807, -3223, 2749, 3595 }, - { -3272, -3157, 1389, 3788 }, - { -5368, -1904, 1980, 5077 }, - { -7235, -1398, 3075, 4548 }, - { -4765, -3487, 2755, 2796 }, - { -7658, -4435, 2694, 2582 }, - { -6997, -4282, 456, 3832 }, - { -5563, -3115, -63, 3713 }, - { -4244, -4220, 1450, 2767 }, - { -3801, -2194, 190, 4303 }, - { -5458, -4119, 1958, 2274 }, - { -7300, -3469, 3514, 3193 }, - { -4594, -2067, 775, 4752 }, - { -3389, -1654, 1464, 5412 }, - { -4845, -3483, 964, 3437 }, - { -6007, -2818, 1666, 4659 }, - { -8709, -5007, 1757, 3287 }, - { -5833, -4389, 1025, 3171 }, - { -5788, -1780, 3944, 3661 }, - { -4430, -920, 1938, 4753 }, - { -7066, -1857, 4591, 4538 }, - { -3549, -513, 1427, 5317 }, - { -7517, -1220, 2883, 3049 }, - { -7605, -2687, 1874, 2735 }, - { -8718, -4035, 2676, 3730 }, - { -7990, -3907, 1185, 2607 }, - { -6058, -1744, 3349, 5157 }, - { -5954, 565, 3161, 3250 }, - { -6478, -612, 1930, 2271 }, - { -6535, -1445, -2, 1618 }, - { -8963, -4151, 1192, 4044 }, - { -7227, -3570, 1600, 4234 }, - { -4674, 79, 595, 3015 }, - { -3974, 430, 2727, 5137 }, - { -5299, 9, 3714, 4779 }, - { -6779, -2699, -8, 2436 }, - { -7016, -1145, 1293, 2310 }, - { -6955, -3312, 1534, 1801 }, - { -4025, 740, 1850, 4054 }, - { -9589, -3460, 4154, 5270 }, - { -4404, -1181, 4298, 5173 }, - { -7356, -4583, -18, 2644 }, - { -6516, -1235, 4439, 6234 }, - { -3453, -301, 4344, 4464 }, - { -4643, 1530, 3315, 4340 }, - { -4575, -2557, 3754, 3682 }, - { -3643, -3501, 2051, 2997 }, - { -5412, -2475, 2301, 1579 }, - { -5846, 259, 1360, 2348 }, - { -5258, -1358, 1050, 838 }, - { -5542, -219, 6377, 5750 }, - { -5713, -2952, 922, 899 }, - { -2049, -1135, 5206, 1033 }, - { -1693, -1886, 4835, -106 }, - { -2344, -3504, 4232, -13 }, - { -2475, -2334, 5043, 1126 }, - { -787, -2549, 3880, 2138 }, - { -3159, -2341, 4830, 2887 }, - { -1780, -1009, 6240, 2061 }, - { -4327, -3363, 2818, 886 }, - { -3376, -2743, 4104, 207 }, - { -3250, -4640, 2718, 1498 }, - { -382, -1075, 4382, 3460 }, - { -2416, -4168, 3530, 816 }, - { -1756, -2708, 4861, 622 }, - { -1879, -2097, 5156, 2889 }, - { -2496, -2418, 3722, 2671 }, - { -2717, -3252, 3341, 1944 }, - { -4063, -4091, 3306, 267 }, - { -3549, -3808, 3747, 842 }, - { -2635, 546, 5794, 1894 }, - { -1857, -1121, 4383, 3964 }, - { -2226, -2166, 3489, 3678 }, - { -3492, -660, 5323, 1063 }, - { -3033, -3130, 4382, 1828 }, - { -2703, -625, 6369, 2851 }, - { -1656, -2842, 4584, -528 }, - { -4781, -2622, 4390, 2097 }, - { -413, -2045, 5081, 3035 }, - { -3810, -2662, 4532, 1095 }, - { -3144, -1858, 5215, 1880 }, - { -3562, -1795, 4928, 670 }, - { -4800, -1509, 5189, 1859 }, - { -1085, -3832, 4169, 900 }, - { -1969, -3270, 2857, 2878 }, - { -4267, -4140, 3176, 1805 }, - { -5145, -3727, 3524, 1168 }, - { -1346, -1876, 5501, 1748 }, - { -4998, -2945, 3699, 338 }, - { -3458, -3096, 3406, -635 }, - { -1751, -3209, 3508, 395 }, - { -2507, 170, 5987, 705 }, - { -3756, -1072, 5647, 3536 }, - { -2870, -1439, 5026, 3212 }, - { -3913, -3225, 3669, 2144 }, - { -3739, 226, 5747, 764 }, - { -2052, -820, 5266, 3093 }, - { -3214, -3820, 2409, 2391 }, - { -4398, -2588, 3501, -218 }, - { -4484, -1763, 4180, -198 }, - { -3368, -1525, 4362, -134 }, - { -2407, 224, 4905, 3533 }, - { -1369, -2937, 4728, 1788 }, - { -4848, -1707, 4159, 851 }, - { -3454, -1749, 4281, 3230 }, - { -1990, -3853, 3487, 1735 }, - { -3117, 92, 6155, 4075 }, - { -2676, -2472, 4078, -589 }, - { -1547, -2012, 2626, 1835 }, - { -4275, -588, 4824, 725 }, - { -601, -2249, 3736, 3548 }, - { -4060, -61, 5333, 3097 }, - { -4303, 7, 6551, 3054 }, - { -5003, -1029, 5786, 3319 }, - { -2810, -728, 5392, 199 }, - { -1232, -200, 5228, 3121 }, - { 2621, 165, -6255, 298 }, - { 3669, 537, -6844, 1564 }, - { 1598, -1190, -6235, 2523 }, - { 2164, -32, -6894, 1383 }, - { 853, -1597, -6069, 1449 }, - { 1377, -1661, -5266, 108 }, - { 2660, 48, -5172, -517 }, - { 1903, -391, -5677, 1010 }, - { 3792, 206, -5274, -11 }, - { 1239, 2776, -2929, 2721 }, - { 4071, 149, -7259, 3125 }, - { 1436, -480, -6156, -196 }, - { 1373, -1960, -5005, 3122 }, - { 3413, -1271, -5176, 3283 }, - { 3060, -68, -6495, 2238 }, - { 2700, -2075, -4681, 91 }, - { 2928, -1728, -5168, 1858 }, - { 4424, 828, -4471, 88 }, - { 2672, -2604, -4038, 2753 }, - { 5223, -123, -6749, 2295 }, - { 4237, -420, -5538, 1353 }, - { 4744, -1281, -4097, 4708 }, - { 1103, -2764, -4751, 2024 }, - { 3747, -1913, -3911, 3960 }, - { 2470, -1416, -5542, 615 }, - { 4847, -1354, -5334, 1733 }, - { 5336, 88, -7593, 4007 }, - { 2388, -2880, -4807, 1037 }, - { 4495, 1391, -5685, -139 }, - { 5253, 1637, -6450, 1533 }, - { 1199, 795, -5515, 1261 }, - { 1397, -1259, -4252, 3838 }, - { 746, 70, -6640, 604 }, - { 1584, 166, -4972, 3072 }, - { 380, -999, -5397, 2267 }, - { 2974, 1707, -3242, 5360 }, - { 5202, -403, -5453, 2832 }, - { 3718, -1731, -4760, 714 }, - { 4150, -975, -4792, 61 }, - { 2925, -818, -4841, 15 }, - { 5301, 577, -4006, 3259 }, - { 5265, 1986, -5679, 3028 }, - { 3752, 1928, -4509, 3729 }, - { 3278, 1925, -6370, 1247 }, - { 5107, 1721, -4853, 3127 }, - { 3279, 2982, -2515, 4005 }, - { 4622, 668, -6204, 759 }, - { 6034, 317, -5763, 4818 }, - { -558, 57, -3785, 2817 }, - { 4476, 1616, -3965, 4536 }, - { 5953, 2056, -8215, 2715 }, - { 4387, 2613, -7463, 868 }, - { 5834, 1088, -4736, 4924 }, - { 6473, -856, -6991, 4172 }, - { 4959, -293, -5162, 76 }, - { 2731, -843, -6119, 3847 }, - { 3245, 1202, -6833, 616 }, - { 2553, 1383, -3829, 3859 }, - { 4332, 2099, -3480, 3622 }, - { 2110, 2683, -2728, 3990 }, - { 876, 1167, -3290, 3466 }, - { 3991, 1709, -2410, 4077 }, - { 5105, 939, -2584, 3256 }, - { 4719, 688, -1566, 3040 }, - { -3632, 4335, 1266, -3303 }, - { -4956, 3207, 1312, -2806 }, - { -4669, 2627, 2663, -2435 }, - { -4282, 3708, 2303, -3038 }, - { -4536, 2297, -175, -3350 }, - { -5234, 2503, -139, -880 }, - { -3978, 1512, 1092, -3619 }, - { -4519, 4649, 1363, -2455 }, - { -5118, 3132, 1961, -1577 }, - { -5196, 3379, -182, -1378 }, - { -6420, 4486, 2397, -1993 }, - { -5030, 5046, 1292, -1118 }, - { -4559, 2573, -927, -1406 }, - { -3501, 3730, 691, -4930 }, - { -4364, 2758, 1007, -3909 }, - { -4026, 2839, -1559, -2340 }, - { -5037, 4053, 836, -1571 }, - { -4727, 5136, 1110, -3588 }, - { -5245, 2799, -999, -2164 }, - { -4954, 1501, 422, -3963 }, - { -5994, 2726, 1462, -2833 }, - { -5621, 5159, 2038, -2512 }, - { -4991, 2291, 1917, -3151 }, - { -5469, 4382, -148, -2978 }, - { -5858, 1983, 807, -2720 }, - { -4709, 3556, 952, -467 }, - { -2489, 2362, 1714, -4230 }, - { -4717, 5004, -1180, -3672 }, - { -5914, 3653, 1359, -1317 }, - { -5506, 2995, 780, -1059 }, - { -5287, 3945, 2480, -2293 }, - { -3849, 4358, 322, -1770 }, - { -3911, 3570, 252, -3185 }, - { -3660, 5128, 158, -3719 }, - { -4599, 3277, -503, -2727 }, - { -3673, 3760, -1252, -3339 }, - { -5161, 2337, 388, -1943 }, - { -3529, 2216, 2156, -3080 }, - { -4309, 4331, 1808, -1460 }, - { -4782, 3820, 480, -2504 }, - { -4166, 3544, -378, -1567 }, - { -5572, 2466, -418, -2909 }, - { -6096, 2930, 119, -1878 }, - { -5963, 3554, 1011, -2233 }, - { -6433, 4335, 935, -2930 }, - { -5004, 3314, -1352, -3430 }, - { -6042, 3463, -1008, -3940 }, - { -4671, 2214, -640, -5040 }, - { -2795, 3759, 1412, -3803 }, - { -3647, 4436, 729, -515 }, - { -3594, 1033, 56, -4148 }, - { -2908, 3027, 2889, -3485 }, - { -3338, 2234, 313, -4285 }, - { -3825, 4497, -561, -2634 }, - { -6167, 3012, -48, -3149 }, - { -4828, 3515, -969, -4475 }, - { -5789, 2757, -539, -4173 }, - { -2452, 3067, 564, -4249 }, - { -4921, 1358, 1331, -2889 }, - { -3127, 4239, -1045, -1523 }, - { -4780, 2326, -1118, -3446 }, - { -3908, 5546, 152, -2622 }, - { -6972, 2976, 337, -2809 }, - { -4839, 4613, -35, -4077 }, - { -1408, 4822, -1149, -4997 }, - { -981, 4979, -912, -6304 }, - { -2098, 5689, -888, -2878 }, - { -3343, 4814, -657, -4434 }, - { -2461, 3601, -967, -4869 }, - { -2652, 3944, 87, -5520 }, - { -1104, 6076, 174, -6407 }, - { 355, 5370, -1721, -5869 }, - { 1242, 4497, -1107, -5091 }, - { -89, 4002, -1491, -5182 }, - { 1059, 5693, -1591, -4905 }, - { 1323, 4682, -2078, -4768 }, - { 818, 3996, -549, -5468 }, - { -287, 4529, 929, -5543 }, - { -919, 5519, -2791, -2844 }, - { -1407, 5679, -3289, -3974 }, - { -189, 6530, -3547, -4002 }, - { -900, 7039, -3371, -4855 }, - { -2983, 7211, -363, -4835 }, - { -814, 6503, -104, -5106 }, - { -2386, 6896, 809, -4919 }, - { 845, 4492, 352, -6621 }, - { -1998, 7237, -1646, -4231 }, - { -3380, 6251, 471, -4577 }, - { -1908, 7059, 84, -5726 }, - { -340, 6346, -803, -6265 }, - { -2279, 5834, -47, -4633 }, - { -1532, 5286, -1748, -1901 }, - { -2757, 6188, -453, -3415 }, - { -1255, 6405, -2043, -6357 }, - { 918, 5581, -121, -5667 }, - { 1840, 5336, -821, -5034 }, - { -2475, 4992, -1825, -3104 }, - { -2413, 5606, -1789, -4298 }, - { 132, 5128, -2389, -4442 }, - { 223, 6400, -2653, -4742 }, - { -673, 5012, 680, -4582 }, - { -1657, 6624, -349, -3596 }, - { -755, 6289, -1860, -3978 }, - { -572, 6894, -1946, -5207 }, - { -1141, 4756, -2665, -5586 }, - { -1073, 4269, -431, -4030 }, - { 186, 5761, 916, -5868 }, - { -1907, 4836, 1017, -5106 }, - { -963, 3363, -1248, -6348 }, - { -3262, 4774, -1818, -5858 }, - { 847, 3812, -2538, -4302 }, - { -1223, 5903, 1360, -5479 }, - { -1094, 6923, -1244, -2381 }, - { 267, 6276, -709, -2846 }, - { -157, 5840, 1124, -4266 }, - { 889, 3206, -910, -5305 }, - { -1736, 3344, 582, -4838 }, - { -2357, 5676, -2695, -6277 }, - { -1916, 6901, -986, -5397 }, - { -3062, 6028, -695, -5687 }, - { 1836, 3566, -1357, -5226 }, - { -2176, 4938, 646, -3872 }, - { -2199, 3055, -208, -6124 }, - { -236, 3032, -821, -5325 }, - { -3989, 7277, -565, -3899 }, - { -595, 4362, 74, -5975 }, - { 684, 5874, -841, -4424 }, - { -2731, 6305, -2389, -5465 }, - { -5775, 1325, -56, -2528 }, - { -7029, -534, -1890, -3278 }, - { -5798, -15, -2734, -2210 }, - { -5504, -1198, -353, -3659 }, - { -5079, 960, -894, -4336 }, - { -6073, -36, -133, -3014 }, - { -5782, -259, -1025, -3986 }, - { -6843, 1262, -807, -1639 }, - { -5263, -918, -3290, -579 }, - { -4840, 461, -2158, -533 }, - { -6014, -50, -620, 504 }, - { -5843, 241, -1359, -282 }, - { -5898, 577, 769, -3271 }, - { -6833, -946, -466, -3347 }, - { -6026, 1459, -512, -729 }, - { -7361, 747, -388, -1110 }, - { -6391, 2142, -1160, -2513 }, - { -6995, 304, 498, -2673 }, - { -6757, 679, -386, -433 }, - { -5222, 1688, -1093, -1032 }, - { -5019, 575, 184, -3627 }, - { -4237, 628, -3507, -1243 }, - { -7479, -456, -1722, -1486 }, - { -6464, 713, -1273, -1153 }, - { -6255, 1682, -606, -3607 }, - { -7033, 1497, -71, -1955 }, - { -6694, 1556, -1721, -3214 }, - { -6114, -356, 813, -2575 }, - { -5308, 632, -1851, -1636 }, - { -5742, -911, -1733, 383 }, - { -6083, -387, -2313, -879 }, - { -6535, -530, -1505, -2083 }, - { -4896, 1223, -2750, -1816 }, - { -6392, -463, -3247, -2093 }, - { -5373, 1264, -2706, -3042 }, - { -3894, -1390, -1020, -891 }, - { -6179, 1168, -1966, -1922 }, - { -5162, 1668, -1617, -1916 }, - { -6453, 920, -1169, -2432 }, - { -6130, 2005, -536, -1519 }, - { -6552, -98, -518, -1938 }, - { -7528, 355, -1101, -1772 }, - { -5745, 610, -247, -1360 }, - { -7003, 177, -2064, -1958 }, - { -6956, -570, -2220, -4225 }, - { -7830, 791, -1394, -2774 }, - { -7634, 480, -3171, -4224 }, - { -7913, 1154, -350, -2381 }, - { -5063, 1704, -1804, -2977 }, - { -4887, -524, -2703, 188 }, - { -5551, 406, -1620, -3063 }, - { -7109, 1342, 381, -3021 }, - { -6846, 631, -458, -3398 }, - { -4606, -605, 11, -3930 }, - { -8134, -225, -1738, -2648 }, - { -7043, 402, -2734, -3059 }, - { -7417, 1825, -2545, -4389 }, - { -6971, -236, -1031, -665 }, - { -5752, 2111, -1632, -3808 }, - { -7660, -78, -624, -3135 }, - { -6358, 619, -1951, -3911 }, - { -8134, 408, -1935, -3695 }, - { -6335, 1911, -2368, -4505 }, - { -7116, 2163, -344, -2753 }, - { 2357, 4488, 2220, -5682 }, - { 1385, 3206, 2300, -5305 }, - { 1419, 2557, 5203, -3516 }, - { 262, 4315, 3920, -1847 }, - { 3316, 3187, 1612, -5609 }, - { 1729, 2350, 1673, -6068 }, - { 1603, 6126, 1467, -2839 }, - { -1339, 3316, 3691, -3530 }, - { -563, 4618, 3180, -4548 }, - { 463, 4624, 3111, -5614 }, - { 1246, 5455, 3356, -5720 }, - { 480, 2149, 5422, -2893 }, - { 1768, 4827, 913, -5579 }, - { -149, 5381, 4366, -3297 }, - { 985, 3672, 2644, -92 }, - { -258, 2911, 5817, -2213 }, - { 3428, 3289, 3351, -3541 }, - { -666, 3295, 4727, -2869 }, - { 35, 6641, 4160, -4052 }, - { 623, 6787, 3156, -4560 }, - { 2654, 4360, 4676, -4632 }, - { 1386, 5246, 4834, -4497 }, - { 3488, 4574, 3856, -5946 }, - { 383, 4481, 4168, -4110 }, - { 1753, 3652, 4288, -3326 }, - { 1344, 4905, 2508, -4660 }, - { 1580, 4106, 3104, -2224 }, - { 2027, 5038, 1683, -1554 }, - { 446, 3699, 5872, -3013 }, - { 4637, 4087, 3578, -5018 }, - { 2629, 3560, 5331, -4900 }, - { 1527, 6674, 2523, -4131 }, - { -1437, 2804, 2528, -4464 }, - { -229, 3355, 2016, -5537 }, - { 3666, 3418, 4374, -4581 }, - { 1192, 3799, 923, -6596 }, - { 2040, 2956, 448, -5322 }, - { 2468, 5768, 4029, -5869 }, - { 3438, 6516, 3529, -6667 }, - { 2737, 5495, 680, -5535 }, - { 3896, 5727, 1801, -4958 }, - { 4988, 4957, 3592, -6518 }, - { -542, 4416, 5794, -2787 }, - { 4136, 4354, 2064, -4696 }, - { 3067, 5936, 1207, -3396 }, - { 2789, 4966, 2405, -3854 }, - { 1731, 3270, 3251, -1063 }, - { 1767, 5537, 2084, -2349 }, - { 465, 3116, 4532, -837 }, - { 1499, 2627, 4610, -2212 }, - { 122, 3095, 3642, -3552 }, - { 2542, 2866, 2705, -6402 }, - { 3134, 4323, 698, -4785 }, - { 731, 1859, 3112, -5242 }, - { 2553, 2980, 3241, -4846 }, - { 1329, 5310, 1607, -6624 }, - { 2468, 1858, 3476, -1034 }, - { -172, 4996, 2000, -5562 }, - { 2621, 4220, 1574, -3386 }, - { -333, 1832, 3362, -4117 }, - { 2169, 6762, 3065, -6225 }, - { 2844, 5528, 3223, -4765 }, - { 526, 5175, 1644, -4267 }, - { 2922, 4426, 2414, -2610 }, - { 452, 1399, -4516, -2636 }, - { 2872, 1720, -4667, -1435 }, - { 1279, 702, -5424, -1984 }, - { 2187, 870, -5021, -1341 }, - { 583, -144, -4628, -2464 }, - { 3, 2237, -5284, -2827 }, - { -19, 1005, -5460, -1819 }, - { 2897, 2084, -5885, -515 }, - { -400, 3370, -5527, -2947 }, - { 1505, 2593, -5518, -1802 }, - { 1341, 4534, -5094, -1899 }, - { 3241, 3670, -5493, -1252 }, - { -1287, 921, -5994, -1675 }, - { 627, 408, -6652, -364 }, - { -260, 1127, -4849, -3247 }, - { 371, 3400, -5976, -2285 }, - { 1533, 1566, -6373, -610 }, - { 2462, 4274, -6184, -1254 }, - { 1782, 3363, -6222, -1381 }, - { 572, 4650, -5673, -2754 }, - { 2674, 3414, -4460, -2154 }, - { 3614, 3820, -6883, -398 }, - { 1136, -1, -5511, -1112 }, - { -1773, 1137, -5647, -2377 }, - { -753, 2104, -6085, -2565 }, - { -204, 3025, -4731, -1418 }, - { -1486, 1438, -4380, -216 }, - { 302, 858, -5786, -264 }, - { 3486, 1495, -5234, -783 }, - { 888, 2327, -3423, -3720 }, - { -259, 772, -6596, -1311 }, - { -1197, 2073, -5174, -1826 }, - { 1500, 3470, -4462, -2645 }, - { 3072, 1960, -3277, -2264 }, - { 1841, 952, -4324, -2340 }, - { 1994, 2200, -3940, -2923 }, - { -1782, 1699, -4667, -1075 }, - { -1464, 2906, -3468, -375 }, - { 366, 2380, -3747, 1467 }, - { -545, 1645, -4619, 376 }, - { 1724, 2350, -2374, -3512 }, - { 3184, 2628, -2996, -3275 }, - { 734, 2010, -6239, -1479 }, - { 524, 3756, -4496, -3263 }, - { 1492, 3570, -3494, -3600 }, - { -932, 618, -5389, -2894 }, - { -133, 2161, -4083, -3267 }, - { 786, 774, -3279, -3731 }, - { 1078, 803, -3843, -3007 }, - { -332, 3405, -3347, 40 }, - { -17, 6, -4005, -3690 }, - { -189, 4372, -4488, -2561 }, - { -450, 3846, -3790, -1370 }, - { 362, 2212, -5272, -15 }, - { -1529, 791, -6802, -2296 }, - { 2145, 4241, -4474, 376 }, - { 1813, 2426, -2932, -2726 }, - { -542, 4557, -3140, -1080 }, - { 1192, 3784, -4371, -20 }, - { 2784, 5188, -6399, -1394 }, - { 431, 4561, -3673, -1398 }, - { 1382, 3096, -4083, 1253 }, - { 1209, 4224, -2930, 1500 }, - { 2798, 2684, -6676, -606 }, - { -2396, 1510, -5381, -2713 }, - { -2625, 2542, -4032, -2880 }, - { -1231, 3967, -4098, -2886 }, - { -1393, 2374, -3862, -4525 }, - { -2495, 1665, -1637, -5445 }, - { -3854, 1759, -1750, -4944 }, - { -2373, 1668, -2856, -6251 }, - { -2668, 1981, -886, -4557 }, - { -2927, 4427, -3451, -6172 }, - { -1925, 2596, -4696, -2527 }, - { -3202, 2847, -3928, -5896 }, - { -3332, 1665, -5025, -3412 }, - { -3212, 3115, -4155, -4062 }, - { -1013, 3205, -5133, -3751 }, - { -2022, 4595, -3947, -5611 }, - { -3556, 1755, -3715, -2300 }, - { -1784, 4114, -2723, -1773 }, - { -3586, 4081, -2733, -4942 }, - { -1608, 3685, -4154, -4573 }, - { -3368, 4042, -4452, -6227 }, - { -1407, 3881, -5729, -3719 }, - { -2751, 3281, -5077, -4999 }, - { -3791, 2410, -4906, -5288 }, - { -730, 2303, -4217, -3755 }, - { -1812, 2311, -5492, -3709 }, - { -610, 4336, -3915, -3783 }, - { -2841, 4337, -4278, -4430 }, - { -1662, 4666, -4661, -3964 }, - { -589, 5209, -4923, -3682 }, - { -4155, 2234, -4076, -4218 }, - { -3951, 2770, -2665, -2805 }, - { -2302, 3228, -3717, -1908 }, - { -3129, 4373, -2264, -2851 }, - { -447, 1363, -3578, -4323 }, - { -2648, 4237, -3159, -3071 }, - { -4072, 3241, -3541, -4605 }, - { -4507, 3458, -2339, -3838 }, - { -1646, 997, -4926, -3970 }, - { -3025, 1614, -3940, -1242 }, - { -1337, 1756, -3163, -5529 }, - { -3203, 1865, -3282, -4354 }, - { -1646, 2118, -2203, -6018 }, - { 174, 1871, -2707, -4639 }, - { -2607, 1485, -4778, -4750 }, - { -2199, 3991, -3134, -4879 }, - { -2962, 3323, -2816, -2419 }, - { -5286, 2495, -4548, -5395 }, - { -2810, 3710, -2274, -4211 }, - { -330, 3006, -2993, -4678 }, - { -1187, 2411, -2743, -5196 }, - { -664, 4033, -3101, -5641 }, - { -1458, 3602, -2816, -5371 }, - { -4116, 4923, -3321, -5630 }, - { -4165, 2528, -2592, -4798 }, - { -2759, 3080, -2333, -5719 }, - { -5157, 3011, -5526, -6348 }, - { -3095, 2126, -5881, -4234 }, - { -4377, 3849, -3600, -6099 }, - { -1994, 4947, -5235, -4753 }, - { -1067, 600, -3258, -5133 }, - { -4992, 3302, -2208, -5051 }, - { -3377, 2981, -1655, -4815 }, - { -3325, 2446, -1787, -6116 }, - { -2341, 2737, -3240, -6347 }, - { -2258, -3732, 3710, -1235 }, - { -1558, -3849, 2694, -3012 }, - { -599, -4837, 3050, -2951 }, - { -2246, -5433, 2798, -1910 }, - { -2255, -4989, 3260, 270 }, - { -3026, -5353, 2693, -1036 }, - { -1151, -6097, 1097, -3782 }, - { -3391, -6012, 2130, -1303 }, - { -2850, -4422, 3375, -480 }, - { -1138, -3779, 1491, -4162 }, - { -551, -3892, 3787, -2082 }, - { -3221, -3676, 3144, -1202 }, - { -3023, -5196, 2650, 605 }, - { -1756, -5729, 2646, 321 }, - { -2693, -4409, 494, -4797 }, - { -1913, -4573, 3372, -1730 }, - { -1277, -3604, 4061, -993 }, - { -420, -4993, 1351, -4796 }, - { -3052, -5333, 1435, -1242 }, - { -602, -5034, 3869, -1141 }, - { -2436, -4680, 1665, -3019 }, - { -2657, -3658, 1459, -3391 }, - { -1220, -6246, 2749, -525 }, - { -3838, -4844, 2265, -1735 }, - { -1247, -5679, 3356, -1417 }, - { -917, -5448, 3342, 105 }, - { -1756, -6839, 2276, -2350 }, - { -412, -5206, 1764, -3539 }, - { -1439, -6915, 1442, -3750 }, - { -1381, -4439, 3863, -282 }, - { -3482, -4953, 2726, -336 }, - { -1376, -5931, 1714, -1987 }, - { -1716, -4405, 2608, 105 }, - { -1590, -5191, 2652, -2704 }, - { -2149, -6442, 2453, -1263 }, - { -3426, -3832, 2334, -1829 }, - { -2747, -5948, 2362, -173 }, - { -2435, -3267, 2966, -1710 }, - { -3979, -4282, 2705, -775 }, - { -356, -4238, 2544, -4343 }, - { -1363, -6471, 2817, -1836 }, - { -2878, -5117, 218, -3149 }, - { -3539, -5196, 1710, -2356 }, - { -2888, -4537, 2746, -1701 }, - { -1870, -4439, 1496, -4121 }, - { -1486, -3388, 3349, -2145 }, - { -3333, -4138, 1467, -2876 }, - { -345, -5340, 1012, -1190 }, - { -1672, -4992, 2289, -1029 }, - { -2146, -5528, 3038, -635 }, - { -316, -3656, 3426, -3152 }, - { -2695, -5812, 2336, -2050 }, - { -2067, -6052, 737, -3258 }, - { -2664, -4205, -350, -1266 }, - { -617, -5406, 80, -4853 }, - { -2418, -3825, 1853, -1326 }, - { -1961, -4339, 583, -4315 }, - { -1495, -5141, -133, -5205 }, - { -3208, -6440, 1691, -2069 }, - { -2632, -3633, 2325, -2761 }, - { -2624, -5670, 1252, -3676 }, - { -3687, -5608, 687, -2833 }, - { -3320, -5707, 16, -3877 }, - { -2738, -6112, 84, -5135 }, - { 2277, -5661, 3076, 843 }, - { 1555, -5769, 2821, -5236 }, - { 536, -6381, 603, -4910 }, - { 734, -4609, 3314, -4092 }, - { 1836, -4547, 3267, -4322 }, - { -13, -5976, 3752, -1607 }, - { 1423, -6318, 2336, 398 }, - { 365, -7779, 1498, -534 }, - { 2104, -8366, 2946, -1345 }, - { 143, -5545, 1898, -3756 }, - { 655, -6852, 1430, 148 }, - { 4, -6653, 2397, -59 }, - { 2346, -5996, 4562, -934 }, - { 1229, -7104, 2963, -598 }, - { -528, -7048, 2887, -1790 }, - { 1451, -6857, 3900, -1637 }, - { 554, -6018, 3336, 9 }, - { 3278, -5758, 4034, 129 }, - { 3541, -7145, 4905, -1575 }, - { 2339, -6907, 3464, -301 }, - { 2775, -7301, 1667, -3894 }, - { 539, -7887, 991, -4156 }, - { 2115, -7421, 3131, -3075 }, - { 2803, -8546, 2564, -5836 }, - { 2869, -5833, 1620, -4561 }, - { 2591, -7281, 3215, -4719 }, - { -1228, -8477, 706, -4782 }, - { 1967, -5243, 4813, -1940 }, - { 701, -7010, 2273, -3893 }, - { 915, -8470, 1918, -5620 }, - { -94, -6715, 156, -3873 }, - { 1074, -5607, 4389, -1017 }, - { 2739, -6551, 1227, -3521 }, - { 725, -7835, 2701, -1291 }, - { -493, -7475, 2263, -1075 }, - { -412, -6508, 2984, -744 }, - { 665, -5451, 3725, -2692 }, - { 1499, -8129, 3564, -2072 }, - { 2870, -6333, 4487, -2108 }, - { 706, -5007, 3911, -152 }, - { -482, -8660, 1483, -2900 }, - { 2481, -6596, 2518, -1715 }, - { 1403, -6414, 1398, -5387 }, - { 652, -6267, 583, -5942 }, - { 694, -7540, 646, -6272 }, - { 2275, -7614, 256, -5015 }, - { 1416, -9727, 1900, -3153 }, - { 2760, -6433, 3875, -3771 }, - { 2325, -11196, 2182, -5155 }, - { 1223, -11061, 1377, -5097 }, - { 108, -10603, 307, -4952 }, - { -118, -8268, 1650, -1572 }, - { 1839, -7943, 1755, -612 }, - { 2501, -9056, 981, -2969 }, - { 2902, -8476, 1491, -5780 }, - { 1995, -11175, 1585, -3643 }, - { 696, -8212, 828, -2474 }, - { 1526, -8649, 1380, -1210 }, - { 461, -7253, 3222, -2229 }, - { 2966, -8641, 4121, -3271 }, - { 833, -6039, 2361, -1086 }, - { 3565, -7312, 1980, -5427 }, - { 2850, -8671, 3760, -1846 }, - { 2643, -7281, 2163, -173 }, - { 3463, -3706, -3132, -923 }, - { 1315, -3825, -3443, 2 }, - { 2594, -4083, -3815, 670 }, - { 1826, -4291, -2741, -155 }, - { 868, -3749, -4175, -298 }, - { 2008, -4237, -3897, -517 }, - { 1242, -3493, -4335, -1335 }, - { -88, -4142, -3390, -1529 }, - { 2176, -3488, -3822, -975 }, - { 1706, -5188, -3415, -637 }, - { 2717, -6159, -2333, -882 }, - { 1276, -3978, -4361, 537 }, - { 2471, -5556, -2866, -208 }, - { 799, -4673, -4086, 56 }, - { 1901, -4786, -3533, 270 }, - { 3036, -3902, -3606, -333 }, - { 2249, -3317, -4319, -144 }, - { 2594, -4207, -2105, -2930 }, - { 4008, -4774, -2626, -902 }, - { 1038, -3659, -3496, -2454 }, - { 2725, -3597, -3298, -1535 }, - { 1662, -5803, -2813, 175 }, - { 705, -3757, -3441, -1484 }, - { 1860, -5987, -2821, -886 }, - { 3786, -4918, -2199, -1929 }, - { 3683, -4235, -2547, -1287 }, - { 2531, -4896, -2956, -1593 }, - { 1005, -5585, -3324, -180 }, - { 1625, -5229, -1756, -3642 }, - { 1494, -5041, -2989, -2685 }, - { 2718, -4655, -3224, -867 }, - { 2374, -6640, -1745, -2975 }, - { 2133, -6436, -2477, -1499 }, - { 1833, -4418, -3523, -1512 }, - { 1128, -4910, -2658, -1106 }, - { 689, -4777, -2831, -2085 }, - { 3593, -5280, -2627, -315 }, - { 3264, -3771, -2673, -1861 }, - { 3202, -5602, -2409, 402 }, - { 552, -4618, -2221, -3002 }, - { 3095, -5356, -2666, -1083 }, - { 3401, -4609, -3146, 45 }, - { 3051, -4662, -2192, -2232 }, - { 2798, -5552, -2462, -1941 }, - { 2354, -5815, -2223, -2619 }, - { 192, -3708, -2807, -2658 }, - { 1886, -4226, -1862, -3529 }, - { 2526, -3976, -2819, -2332 }, - { 1577, -3870, -2711, -2806 }, - { 1288, -5588, -3382, -1403 }, - { 2711, -5399, -1564, -3253 }, - { 1459, -5492, -2222, -322 }, - { 2823, -5091, -2886, 776 }, - { 3559, -5821, -2109, -1360 }, - { 1587, -6331, -2760, -1909 }, - { 2139, -5213, -2874, -2120 }, - { 1318, -4337, -3695, -2098 }, - { 821, -4471, -1849, -565 }, - { 3329, -4782, -1725, -89 }, - { 582, -4914, -4105, -1119 }, - { 417, -4144, -4072, -2529 }, - { -199, -3803, -2765, -4042 }, - { 2731, -4283, -2143, 1 }, - { 2911, -6187, -1951, -2116 }, - { 1573, -6094, -493, -2838 }, - { 2081, -6927, -864, -3211 }, - { 1058, -7826, 79, -364 }, - { 3147, -5570, -684, -978 }, - { 3572, -5856, 1060, 1824 }, - { 1143, -6702, -1478, 338 }, - { 2341, -7220, -88, 260 }, - { 3639, -6861, 668, 815 }, - { 2227, -6268, -1706, 446 }, - { 3390, -6082, -353, 1302 }, - { 1123, -7556, -1237, -430 }, - { 1729, -7742, 729, -218 }, - { 1457, -6774, 587, 579 }, - { 505, -6919, -569, 371 }, - { 1106, -7245, 78, 158 }, - { 2755, -6745, -1122, 338 }, - { 3069, -6040, -1415, 986 }, - { 2174, -7064, -1430, -283 }, - { 1390, -8626, -446, -3031 }, - { 3534, -6890, -431, 547 }, - { 2267, -9618, 475, -2994 }, - { 3672, -7673, 75, -115 }, - { 2131, -7560, -1206, -750 }, - { 2972, -7477, -685, -262 }, - { 1604, -6637, -672, 699 }, - { 1666, -7577, -577, -240 }, - { 1591, -6554, -2158, -94 }, - { 2348, -6286, -353, 1123 }, - { 2017, -8810, -412, -1805 }, - { 2892, -6713, -1765, -554 }, - { 2500, -6828, -1995, -1197 }, - { 3877, -6639, -224, -1655 }, - { 2392, -7872, -91, -333 }, - { 3562, -7370, -532, -2836 }, - { 2552, -7614, 164, -1805 }, - { 990, -6104, 218, 438 }, - { 910, -7861, 312, -1195 }, - { 1472, -6327, 372, -640 }, - { 1576, -7143, -1983, -843 }, - { 422, -7625, -457, -278 }, - { 1797, -8532, 405, -1011 }, - { 1088, -7396, -238, -2277 }, - { 3209, -6753, -1431, -2072 }, - { 2617, -6839, 100, -2573 }, - { 2575, -8573, -387, -3188 }, - { 3618, -6971, -1190, -321 }, - { 2205, -7361, -1695, -2008 }, - { 2985, -6297, 1464, 1179 }, - { 2804, -7310, 1053, 338 }, - { 1362, -6074, -1163, -840 }, - { 3336, -6325, -1794, 21 }, - { 2836, -8109, 818, -329 }, - { 2791, -5879, 560, 1546 }, - { 2392, -6064, 135, 100 }, - { 1838, -6194, 596, 1085 }, - { 1926, -7515, -414, -4901 }, - { 3225, -7298, -1202, -1189 }, - { 3960, -7558, -659, -719 }, - { 3442, -6647, -1692, -1095 }, - { 3381, -6441, 262, -886 }, - { 1431, -8150, -1186, -1406 }, - { 340, -8498, -150, -899 }, - { 3004, -8149, -260, -953 }, - { 2749, -6611, 563, 873 }, - { -6647, -1325, -4517, -4691 }, - { -6005, -1657, -4089, -3797 }, - { -3157, 588, -5213, -3068 }, - { -3311, -1425, -6329, -3726 }, - { -5866, -819, -3857, -2744 }, - { -5001, -1799, -1075, -4621 }, - { -5330, -2650, -2672, -4664 }, - { -4930, -539, -2363, -4010 }, - { -2984, 10, -3863, -5749 }, - { -1055, -2106, -3713, -4267 }, - { -5476, -502, -4279, -6504 }, - { -5231, -1543, -5018, -6425 }, - { -5134, -363, -3165, -5109 }, - { -3953, -771, -4107, -6393 }, - { -2159, -563, -3652, -5342 }, - { -3888, -2321, -919, -5057 }, - { -1236, -597, -4235, -4193 }, - { -4053, 675, -3083, -6174 }, - { -2793, -1089, -5396, -3460 }, - { -3000, -44, -2209, -6575 }, - { -3336, -1531, -4313, -5160 }, - { -2127, 128, -4851, -3692 }, - { -3321, 136, -2067, -5660 }, - { -5215, 1404, -4374, -4356 }, - { -2747, 400, -6340, -3691 }, - { -3926, -599, -5361, -5006 }, - { -2875, -2592, -5143, -4092 }, - { -4991, -1958, -5322, -4891 }, - { -4965, -1318, -6652, -5333 }, - { -4920, -1691, -3388, -5561 }, - { -3644, -3354, -2688, -5982 }, - { -5076, -919, -4563, -2984 }, - { -6114, 250, -3884, -3915 }, - { -4014, 744, -3973, -1924 }, - { -5543, -1041, -5557, -3847 }, - { -4711, -1352, -5649, -2603 }, - { -3362, 775, -5305, -4879 }, - { -5001, 107, -3554, -2888 }, - { -6258, -1651, -6356, -6566 }, - { -4529, 407, -5003, -3865 }, - { -5154, 550, -5278, -5465 }, - { -4195, -467, -1894, -3129 }, - { -5022, 1127, -3349, -3314 }, - { -6075, 1250, -4313, -5641 }, - { -2677, -2283, -2312, -5903 }, - { -4113, 193, -1195, -4833 }, - { -3940, -1048, -1389, -5079 }, - { -3703, 917, -4043, -4451 }, - { -3366, -4231, -1534, -5488 }, - { -3326, -3583, -2091, -4903 }, - { -5144, 1254, -2532, -4949 }, - { -5982, -870, -2545, -4555 }, - { -3925, -157, -5367, -2281 }, - { -6419, -746, -5668, -4371 }, - { -5787, 518, -7096, -5805 }, - { -4258, 954, -6453, -4321 }, - { -4771, -695, -4158, -1639 }, - { -7078, -760, -5195, -5877 }, - { -7348, 83, -4101, -4586 }, - { -2430, 184, -2874, -1679 }, - { -2284, -3943, -2924, -5034 }, - { -1804, -1785, -3002, -4710 }, - { -4399, -2772, -1815, -4637 }, - { -6340, -2626, -2824, -5191 }, - { -4998, -5168, -3480, 1905 }, - { -3958, -5492, -1599, 1579 }, - { -2471, -3755, -276, 3182 }, - { -3033, -5779, -1063, 1554 }, - { -2936, -4829, -1290, 2386 }, - { -1835, -5073, -3051, 1299 }, - { -1724, -3771, -3935, 2324 }, - { -5070, -2550, -3692, 768 }, - { -4326, -5333, -297, 1878 }, - { -3472, -5619, -3094, 992 }, - { -3027, -4384, -3038, 2265 }, - { -3201, -5332, 67, 2200 }, - { -1681, -4373, -1947, 2461 }, - { -3221, -3329, -4238, 2564 }, - { -1262, -2968, -2915, 3227 }, - { -3419, -1878, -3373, 2110 }, - { -2244, -5583, -2012, 1288 }, - { -1971, -5266, -990, 1812 }, - { -2975, -2778, -452, 4063 }, - { -2198, -1165, -3298, 2965 }, - { -4782, -4894, -4767, 664 }, - { -6002, -3950, -2806, 2025 }, - { -3142, -3162, -2859, 3295 }, - { -3262, -3340, -4123, 1596 }, - { -4014, -3918, -1955, 3361 }, - { -1700, -3463, -1346, 3449 }, - { -4245, -4445, -4743, 1644 }, - { -4180, -3969, -401, 3281 }, - { -2782, -5240, -4117, 1156 }, - { -5744, -4040, -1439, 3470 }, - { -5063, -4663, -323, 3172 }, - { -4531, -3319, -844, 3988 }, - { -6226, -5125, -2064, 2976 }, - { -3115, -3267, -1531, 3898 }, - { -4628, -4421, -2864, 2808 }, - { -4559, -2989, -3442, 2024 }, - { -1775, -4487, -656, 2477 }, - { -2664, -1865, -1884, 4081 }, - { -1828, -2575, -3894, 3378 }, - { -6441, -3677, -2025, 1677 }, - { -4141, -2156, -1191, 3474 }, - { -4802, -1623, -1727, 2160 }, - { -5474, -2745, -1475, 2498 }, - { -3664, -1056, -1975, 2491 }, - { -4672, -3062, -2235, 2933 }, - { -4205, -5960, -2849, 1517 }, - { -4995, -5708, -1739, 1805 }, - { -4892, -6080, -4793, 872 }, - { -4270, -4172, -4263, 2185 }, - { -4687, -1470, -2905, 1023 }, - { -6446, -5017, -3919, 1000 }, - { -6046, -5538, -3943, 2006 }, - { -6028, -3750, -3953, 771 }, - { -5959, -4582, -5024, 824 }, - { -5818, -2576, -2249, 1326 }, - { -5659, -5345, -1119, 2500 }, - { -3346, -4155, 606, 2749 }, - { -5680, -4827, -2501, 1838 }, - { -6193, -2543, -1295, 840 }, - { -6871, -4925, -3512, 1801 }, - { -5605, -1788, -1895, 779 }, - { -3922, -5712, -4644, 510 }, - { -4745, -3869, -4533, 99 }, - { -2984, -4907, -399, 1497 }, - { 1847, -478, 3061, -5812 }, - { 4450, -1116, 3609, -6570 }, - { 3139, 99, 3007, -5532 }, - { 2590, -3782, 3138, -4770 }, - { 1881, 1204, 5778, -3404 }, - { 3631, 2060, 5566, -5038 }, - { 3461, 1961, 5167, -3800 }, - { 2947, 273, 4536, -4389 }, - { 4453, -1730, 5788, -4370 }, - { 4032, 1805, 2666, -4534 }, - { 3487, -944, 2313, -6028 }, - { 1313, 34, 4210, -4067 }, - { 5632, -1502, 5825, -5855 }, - { 7736, -547, 4879, -5476 }, - { 4906, -1512, 4760, -5760 }, - { 3843, 447, 1091, -4958 }, - { 2982, -1135, 5442, -4386 }, - { 3579, 271, 3031, -6770 }, - { 3932, -211, 4688, -5507 }, - { 4411, 1720, 2387, -5584 }, - { 5379, -479, 4575, -6280 }, - { 3613, -362, 2012, -4885 }, - { 3744, -2013, 4493, -5073 }, - { 5693, 109, 4379, -3362 }, - { 5475, -621, 5317, -3985 }, - { 6411, -673, 5708, -4752 }, - { 4933, -796, 7262, -4290 }, - { 2804, 444, 6276, -3655 }, - { 4120, -517, 6078, -4531 }, - { 5119, 841, 3486, -3910 }, - { 4738, 1539, 3525, -2970 }, - { 5086, 370, 5895, -5640 }, - { 4235, 2716, 4589, -5044 }, - { 3691, 682, 6199, -4700 }, - { 6111, -570, 6271, -6528 }, - { 2611, 1277, 3756, -4802 }, - { 4395, 970, 3807, -5879 }, - { 5225, 2299, 3242, -4333 }, - { 5144, 1778, 4946, -5545 }, - { 2989, -3016, 3247, -5495 }, - { 2983, 920, 2071, -6059 }, - { 5270, -903, 4434, -2350 }, - { 6415, -585, 3970, -3554 }, - { 3866, -197, 5216, -2884 }, - { 3767, -1298, 6702, -3315 }, - { 6299, 2620, 5284, -6824 }, - { 6654, 646, 3653, -4927 }, - { 4770, 3047, 5160, -6287 }, - { 5364, 434, 2919, -5207 }, - { 2998, 1344, 4801, -2456 }, - { 3896, 1013, 3773, -1864 }, - { 2115, 655, 2999, -6344 }, - { 5170, -981, 2849, -4464 }, - { 2735, -2159, 2717, -5776 }, - { 2430, -1952, 4392, -4559 }, - { 6143, -1180, 3659, -4746 }, - { 4978, -1483, 1726, -4875 }, - { 3486, -2383, 3306, -4301 }, - { 1434, -1372, 4171, -4770 }, - { 3354, -2627, 1525, -5093 }, - { 6790, 2386, 3995, -5909 }, - { 1475, -2674, 3451, -4204 }, - { 1999, -3494, 3693, -5556 }, - { 4764, -2848, 2856, -5589 }, - { -3677, 5131, 2827, -2934 }, - { -2844, 7078, 2852, -3580 }, - { -3902, 6434, 4118, -1911 }, - { -1769, 7530, 3492, -3541 }, - { -1937, 5679, -447, -1127 }, - { -2456, 4680, 4196, -2407 }, - { -2778, 8241, 1698, -4288 }, - { -2876, 6104, 5182, -2387 }, - { -2802, 7341, 4463, -2938 }, - { -1025, 6267, 4752, -3201 }, - { -2349, 5413, 2041, -3794 }, - { -2252, 8225, 2856, -4269 }, - { -1465, 4967, 4976, -2500 }, - { -636, 7565, 3517, -4233 }, - { -1905, 5618, 3904, -2942 }, - { -302, 6816, 3343, -3316 }, - { -2210, 4156, 2817, -3511 }, - { -717, 6568, 1863, -2951 }, - { -3873, 5682, 2164, -575 }, - { -2878, 5835, 440, -2597 }, - { -3228, 7701, 2610, -2514 }, - { -3608, 8888, 3377, -2468 }, - { -2582, 9717, 2519, -3126 }, - { -5238, 6202, 2866, -2831 }, - { -3428, 7370, 3056, -335 }, - { -1681, 8836, 1210, -2010 }, - { -3276, 6724, 1156, -3930 }, - { -894, 8149, 827, -1258 }, - { -2965, 8631, 2549, -1320 }, - { -3961, 6902, 3581, 55 }, - { -1894, 7745, 1750, -841 }, - { -821, 6844, 850, -676 }, - { -608, 6948, -4, -1376 }, - { 615, 6524, 1089, -1147 }, - { -2972, 5668, 1091, -489 }, - { -157, 4649, 2904, -413 }, - { 673, 5121, 1498, -66 }, - { -390, 5902, 1611, -245 }, - { -2349, 5478, 4772, -1320 }, - { 88, 6798, 1972, -1859 }, - { -1213, 5120, 2991, 200 }, - { -2347, 6040, 2839, 376 }, - { -578, 5976, 3364, -1796 }, - { -1391, 5872, 3002, -965 }, - { -564, 4496, 3946, -1186 }, - { -2299, 6386, 3135, -2176 }, - { -2131, 5641, 2011, 1223 }, - { -772, 5807, 1124, 895 }, - { -2837, 6758, 2297, -740 }, - { -3091, 6298, 1415, -2126 }, - { -4197, 6036, 1843, -3022 }, - { -41, 6459, 92, 344 }, - { -2241, 6860, 2095, -4396 }, - { -1931, 7088, 2117, -2135 }, - { -2375, 4422, 1688, -3169 }, - { -1742, 6674, 1538, -119 }, - { -4818, 7749, 4192, -1577 }, - { -2004, 5672, 193, -430 }, - { -3825, 6042, 2128, -1898 }, - { -1108, 8033, 2119, -3013 }, - { -2370, 5453, 1721, 266 }, - { -1570, 7134, 614, -2638 }, - { -1519, 8752, 3503, -4330 }, - { -2050, 3845, 2907, -1126 }, - { 5085, 4412, -335, -1923 }, - { 3618, 1423, -613, -4012 }, - { 4481, 3729, 589, -4631 }, - { 4270, 3216, -1763, -3168 }, - { 4241, 1796, -1701, -2796 }, - { 4787, 2338, -487, -3639 }, - { 2915, 3429, -621, -4753 }, - { 5175, 1660, -1265, -3223 }, - { 4280, 4057, -684, -4079 }, - { 4980, 4419, -1455, -2719 }, - { 5436, 2464, 387, -4197 }, - { 4507, 4018, 1121, -3314 }, - { 6020, 2401, -413, -3201 }, - { 4200, 3789, -333, -2813 }, - { 5229, 2493, -1194, -1878 }, - { 5851, 2695, -492, -2292 }, - { 5743, 3288, -697, -1221 }, - { 5692, 2612, 979, -2227 }, - { 5085, 2067, 1046, -1214 }, - { 3163, 2240, -2098, -3435 }, - { 5228, 1898, 145, -2397 }, - { 5860, 3976, -418, -2872 }, - { 6008, 3399, 1027, -3506 }, - { 4126, 2035, 1865, -893 }, - { 5375, 3596, 511, -2362 }, - { 1937, 1493, -852, -122 }, - { 3473, 4849, 547, -2603 }, - { 4631, 2977, 1141, -1768 }, - { 6149, 3050, -71, -1886 }, - { 4069, 4353, -289, -1429 }, - { 2884, 1225, -1388, 365 }, - { 5485, 2518, -235, -571 }, - { 1216, 4375, 1443, 398 }, - { 4988, 3106, 107, -1435 }, - { 4511, 2801, 307, -444 }, - { 3235, 4386, 327, -676 }, - { 2055, 3708, 1657, -305 }, - { 5839, 2374, 290, -1385 }, - { 5110, 3305, 1936, -4206 }, - { 6416, 2920, 338, -2736 }, - { 3350, 2824, -1269, -3881 }, - { 4840, 1815, 464, 186 }, - { 2399, 3332, 238, 1238 }, - { 3516, 1363, 1582, 688 }, - { 3582, 1874, 154, -4770 }, - { 3261, 2878, 886, 283 }, - { 3877, 2658, -327, 884 }, - { 4151, 3436, 2173, -2923 }, - { 3592, 3674, 1281, -1295 }, - { 4561, 3730, -1114, -1747 }, - { 4595, 3625, -558, -575 }, - { 2577, 2348, 2267, 120 }, - { 5242, 3299, 32, -3412 }, - { 4264, 3637, 709, -2320 }, - { 6556, 3570, -838, -2472 }, - { 5745, 4014, -940, -1973 }, - { 5629, 4475, 477, -3328 }, - { 5269, 3199, 1682, -3085 }, - { 4432, 2416, 1145, -3299 }, - { 4465, 2505, 2162, -2186 }, - { 4643, 4941, -88, -2885 }, - { 4568, 5231, 552, -3915 }, - { 5667, 3075, -1406, -2963 }, - { 5418, 5259, -771, -2818 }, - { -256, -7875, 511, -471 }, - { -1813, -7971, -424, -396 }, - { -306, -7006, 862, 282 }, - { -2306, -6422, -1440, 508 }, - { -245, -6787, 375, -100 }, - { -1309, -6065, -20, 779 }, - { -1656, -6047, -641, 1307 }, - { -1496, -6522, 964, 726 }, - { -2291, -6588, -202, 795 }, - { -762, -7522, 1454, -558 }, - { -2270, -7004, -834, -580 }, - { -1139, -7078, 259, 362 }, - { -2535, -7568, -1040, 49 }, - { -3786, -7280, 934, -476 }, - { -3336, -6368, 606, 1056 }, - { -3602, -6924, 52, 714 }, - { -2278, -6550, 1674, 204 }, - { -2855, -5765, 930, 1530 }, - { -2889, -7325, -215, 305 }, - { -2749, -6080, -237, 1452 }, - { -985, -6667, 1577, 400 }, - { -2036, -6083, 380, 1267 }, - { -2077, -7460, 380, -30 }, - { -1775, -7175, 1540, -386 }, - { -3065, -6927, 989, 168 }, - { -2836, -7602, 117, -3392 }, - { -1058, -6396, 593, -3078 }, - { -844, -6062, 999, -236 }, - { -3261, -6951, 1491, -720 }, - { -2186, -8484, 75, -1287 }, - { -2882, -7756, 456, -510 }, - { -1800, -6879, 960, -1183 }, - { -2554, -7241, 1614, -1474 }, - { -2608, -5305, 392, 851 }, - { -2973, -6562, -859, 858 }, - { -2640, -5989, 1031, -416 }, - { -977, -8366, 705, -1434 }, - { -1213, -7409, -77, -1390 }, - { -1335, -6657, 2125, -123 }, - { -2544, -6862, 1852, -737 }, - { -3235, -6422, 1752, -103 }, - { -1300, -7557, 939, -348 }, - { -3476, -7579, 202, -109 }, - { -2482, -6572, 753, 619 }, - { -2554, -8136, -648, -429 }, - { -1012, -7870, -3, -421 }, - { -3604, -6247, 32, -3102 }, - { -1486, -7271, 2013, -1021 }, - { -578, -6799, -523, 405 }, - { -2841, -5948, 1644, 911 }, - { -2411, -7473, 1084, -484 }, - { -2238, -6033, 294, -1059 }, - { -3459, -6470, -201, -790 }, - { -2027, -6009, 1833, 805 }, - { -1433, -8047, 1531, -1754 }, - { -3258, -7884, 763, -1422 }, - { -1544, -6928, -729, 478 }, - { -2314, -8415, 74, -3757 }, - { -3201, -5684, 95, -2214 }, - { -2423, -8694, 725, -3631 }, - { -3545, -7071, 1162, -1798 }, - { -294, -9662, 403, -2274 }, - { -2290, -5460, 1196, 402 }, - { -1603, -6713, 903, -2363 }, - { 4121, 2491, -3142, -2482 }, - { 4500, 3305, -3671, -1567 }, - { 5973, 3172, -1348, -534 }, - { 4830, 3379, -1549, 643 }, - { 5214, 3938, -2641, -2302 }, - { 4639, 4826, -5532, -847 }, - { 5639, 2731, -2170, -963 }, - { 6084, 3487, -3525, -1346 }, - { 5971, 3154, -2190, -2316 }, - { 5618, 4865, -6927, 116 }, - { 5345, 3568, -7391, 709 }, - { 5429, 5078, -3811, -1524 }, - { 6960, 2037, -3515, -1096 }, - { 7092, 2531, -4557, -588 }, - { 6061, 4247, -5651, -478 }, - { 4595, 3684, -4907, -827 }, - { 7497, 3213, -3048, -424 }, - { 5996, 2137, -3098, -1745 }, - { 6198, 5199, -2223, -2274 }, - { 6888, 2851, -2768, -1675 }, - { 6114, 4210, -2316, -954 }, - { 7127, 4242, -3041, -1408 }, - { 6126, 3668, -1517, -1427 }, - { 6245, 6129, -4225, -1186 }, - { 6816, 3213, -2101, -964 }, - { 5345, 5276, -2643, -847 }, - { 6592, 4665, -4338, 484 }, - { 6746, 3751, -3443, 124 }, - { 5453, 1980, -2738, 2606 }, - { 4662, 2179, -4226, -1059 }, - { 5571, 3208, -3554, 174 }, - { 5256, 4447, -1815, -1481 }, - { 5400, 2570, -1210, 235 }, - { 7056, 2549, -2674, 318 }, - { 4574, 4340, -2892, -130 }, - { 6203, 4587, -3273, -305 }, - { 5103, 1925, -2715, -2137 }, - { 3905, 4296, -1700, 247 }, - { 4421, 4605, -3299, 811 }, - { 5671, 1273, -3870, -924 }, - { 5486, 1805, -4901, 133 }, - { 6437, 2578, -1828, -106 }, - { 5530, 5253, -5058, 1223 }, - { 4816, 2025, -1215, 1443 }, - { 3457, 3525, -2456, 3217 }, - { 3316, 2595, -1108, 2459 }, - { 3068, 3810, -2207, 1926 }, - { 6351, 5436, -6470, 600 }, - { 6324, 4240, -5365, 2416 }, - { 4851, 4774, -4075, 1878 }, - { 4900, 3679, -5198, 1078 }, - { 8347, 3633, -4565, -171 }, - { 5244, 5718, -3853, 173 }, - { 3960, 3492, -2939, 2105 }, - { 6070, 3473, -2351, 161 }, - { 8228, 3034, -3360, -901 }, - { 7006, 3985, -1940, -1926 }, - { 7123, 4681, -4301, -878 }, - { 5122, 4097, -1851, -449 }, - { 6200, 2060, -2251, 1049 }, - { 7106, 3844, -7209, 2625 }, - { 7108, 3370, -6734, 533 }, - { 6859, 2849, -3992, 1360 }, - { 5458, 2278, -3253, 1131 }, - { -1072, -2109, 4783, -1073 }, - { -319, -2604, 4257, -2418 }, - { 2466, 1300, 3476, -314 }, - { 2847, -1502, 5296, -141 }, - { 1667, -1273, 5559, -2725 }, - { 2877, -3402, 6434, 204 }, - { 53, -2637, 5275, -1181 }, - { 1091, -2215, 5803, -1549 }, - { 2397, -922, 4327, 1182 }, - { 219, -3747, 4647, -1564 }, - { -29, -2705, 4812, 1277 }, - { 1499, -2608, 5648, 1407 }, - { 2139, -2399, 4202, 2791 }, - { -426, -2064, 5528, 151 }, - { 2560, -2803, 6179, -2806 }, - { 4537, -2479, 3797, 1095 }, - { 888, -3357, 5341, -415 }, - { 4460, -1814, 5388, -1227 }, - { 3920, -3268, 6364, -703 }, - { 3343, -4698, 4410, 784 }, - { 309, -1897, 6306, 1223 }, - { 958, -3318, 4254, -3167 }, - { -99, 1596, 6018, -1983 }, - { -429, -853, 6407, 878 }, - { 1170, -1322, 6290, -417 }, - { 2288, -505, 6303, -1999 }, - { 3312, -1674, 6749, -2494 }, - { -415, -3401, 4721, -371 }, - { -189, -1210, 4844, -2002 }, - { 888, -4142, 4377, 130 }, - { 2469, -4381, 5398, -2492 }, - { 2879, -2912, 5094, -2598 }, - { -717, -617, 5650, -685 }, - { 1470, -3863, 5352, -1684 }, - { 3935, -96, 3823, -730 }, - { 3769, -430, 3168, 694 }, - { 2556, 385, 3539, 512 }, - { 77, -1415, 5111, 2655 }, - { 2724, -2158, 6715, -822 }, - { 1832, 1001, 5385, -1900 }, - { 900, 2198, 4464, -559 }, - { 441, 69, 5921, -1743 }, - { -1161, 738, 6732, -308 }, - { 257, 2035, 4091, 736 }, - { 1607, 1288, 4355, -23 }, - { -13, 1316, 4180, 1672 }, - { 1511, 1336, 3057, 1435 }, - { 2189, -3813, 4530, 939 }, - { 3632, -706, 2646, 1375 }, - { 4266, -3761, 4241, 1077 }, - { 3101, -427, 5273, -1202 }, - { 2293, 276, 4810, -313 }, - { 3430, -1851, 3101, 2045 }, - { 3453, -2979, 5142, 942 }, - { 1683, -3281, 4802, 2002 }, - { 3954, -4715, 5611, 578 }, - { 1272, -155, 5085, 454 }, - { 128, -194, 5095, 1409 }, - { 820, 880, 5797, -2658 }, - { -1095, 656, 5774, 1095 }, - { 813, -1669, 4320, -3251 }, - { -119, 518, 6372, -651 }, - { 2922, -4299, 6115, -877 }, - { 4205, -4273, 4004, 2642 }, - { -1211, -3892, 224, 3127 }, - { -34, -4371, 1321, 2318 }, - { 77, -6326, 1201, 828 }, - { 3995, -3775, 1958, 3233 }, - { 178, -3301, 1985, 3318 }, - { 2330, -3801, 1033, 3195 }, - { 1413, -5536, 826, 1709 }, - { 2468, -3499, 3653, 3631 }, - { 741, -4617, 1723, 2008 }, - { 1246, -3043, 2978, 3949 }, - { -343, -4308, 2258, 2189 }, - { -682, -4640, 454, 2272 }, - { 1236, -4829, 2491, 1642 }, - { -512, -3766, 1182, 3052 }, - { 119, -3939, 3712, 971 }, - { -1145, -4624, 1360, 2281 }, - { 101, -4746, 2866, 1255 }, - { -1500, -5455, 539, 1637 }, - { -969, -5909, 1414, 1128 }, - { -1261, -4939, -231, 2022 }, - { -226, -5345, 1207, 705 }, - { 2712, -5109, 3205, 1866 }, - { -476, -5913, 273, 1208 }, - { -2039, -4464, 624, 2545 }, - { -2351, -3930, 2019, 2673 }, - { -2675, -4849, 1522, 1990 }, - { -1524, -3461, 1446, 3204 }, - { 477, -5314, 1710, 1577 }, - { 656, -3729, 2346, 2511 }, - { 550, -5917, 1975, 1040 }, - { 1728, -4704, 3067, 1058 }, - { -9, -5247, 506, 1760 }, - { -574, -5135, 1675, 1672 }, - { 2129, -3781, 3444, 2313 }, - { 1144, -4439, 2214, 2529 }, - { 1292, -4160, 3185, 1833 }, - { 2445, -3262, 2534, 3227 }, - { 2266, -4401, 2023, 2400 }, - { -587, -3602, 3408, 2067 }, - { -885, -4951, 3228, 1174 }, - { -728, -2711, 2807, 3552 }, - { 1019, -3043, 3195, 2954 }, - { 1888, -4615, 1140, 2454 }, - { 660, -5616, 754, 800 }, - { -1975, -5371, 1649, 1585 }, - { -1544, -5436, 2422, 1081 }, - { -422, -5882, 2390, 750 }, - { 1336, -5557, 2441, 1230 }, - { 136, -4001, 267, 2854 }, - { -522, -3289, 2226, 2728 }, - { -971, -4580, 2471, 708 }, - { 704, -5306, 3300, 1001 }, - { 325, -3464, 3555, 2398 }, - { 794, -3686, 848, 3169 }, - { 660, -3017, 4584, 3242 }, - { -1486, -3978, 2170, 1644 }, - { -1615, -4650, 2688, 1844 }, - { 750, -4578, 538, 2239 }, - { 1668, -5849, 1455, 1031 }, - { 3486, -4681, 2030, 2183 }, - { 2642, -5429, 1696, 1761 }, - { 4491, -4502, 3538, 2767 }, - { 3545, -4528, 3514, 2982 }, - { 3269, -3676, 2758, 3966 }, - { 5572, 1146, 209, -3379 }, - { 7459, 1053, 593, -1896 }, - { 4480, 200, -310, -4259 }, - { 5577, -939, 242, -3992 }, - { 8142, 442, 1257, -3083 }, - { 5442, 1261, 1424, -3236 }, - { 6260, -183, 3125, -2532 }, - { 7179, 889, 1618, -2548 }, - { 6416, 932, 2379, -2487 }, - { 7094, 2560, 961, -3392 }, - { 7322, 463, 2732, -3735 }, - { 6632, 1577, 1912, -3272 }, - { 6312, 1349, 3028, -3460 }, - { 6105, 386, 1213, -977 }, - { 5478, 1158, 1114, -486 }, - { 6493, 410, 1686, -2180 }, - { 6378, 1881, 1333, -2240 }, - { 5711, 812, 1958, -1300 }, - { 6844, 877, 730, -1189 }, - { 6824, -245, 2249, -2000 }, - { 7515, 1521, 1251, -3058 }, - { 6697, 1051, 1300, -1749 }, - { 6476, 1425, 811, -2773 }, - { 7350, 465, -76, -2849 }, - { 6975, 2095, 567, -2492 }, - { 4691, 1736, 2660, -2289 }, - { 7837, 1456, 340, -2767 }, - { 7930, 507, 838, -2074 }, - { 6106, 1502, 766, -1110 }, - { 4891, -659, 835, -3954 }, - { 7250, 141, 1369, -1523 }, - { 7651, 67, 1651, -2298 }, - { 7364, -305, 601, -3132 }, - { 7179, 193, 2491, -2871 }, - { 6504, -272, 2167, -1322 }, - { 4456, 983, 2300, -421 }, - { 4817, 457, 1695, 371 }, - { 6914, 555, 850, -3159 }, - { 5904, 1030, 202, -1959 }, - { 6258, 880, 2233, -4503 }, - { 6029, 10, 2130, -3600 }, - { 6449, 985, 1129, -3963 }, - { 6616, -18, -111, -3285 }, - { 4496, 775, 817, -4276 }, - { 6134, 2338, 1470, -2973 }, - { 6911, 152, 430, -1946 }, - { 4053, 991, 3218, -1193 }, - { 5435, 1285, 3124, -2412 }, - { 5507, 1836, 1935, -1988 }, - { 5240, 689, 2189, -2670 }, - { 6638, 1719, 606, -1799 }, - { 5556, -180, 129, -2595 }, - { 5644, 1918, 1281, -4316 }, - { 6410, 1088, -282, -3117 }, - { 6503, 1841, 312, -3514 }, - { 6947, 20, 1358, -3886 }, - { 5464, 2109, 2398, -3194 }, - { 5616, -407, 2140, -498 }, - { 6121, 2707, 2379, -4096 }, - { 7303, 1846, 2266, -4095 }, - { 5444, 470, 2718, -1553 }, - { 5817, -645, 3285, -1349 }, - { 5625, 1427, 1103, -1991 }, - { 6041, -806, 1196, -2943 }, - { 3050, -5722, 4070, -5460 }, - { 3420, -4386, 4078, -5155 }, - { 6020, -3982, 7268, -2689 }, - { 7502, -4317, 7894, -3973 }, - { 4156, -3558, 5247, -4316 }, - { 4725, -4401, 7290, -1540 }, - { 6688, -5122, 8216, -3210 }, - { 9176, -6576, 9276, -4963 }, - { 8706, -5708, 7987, -4621 }, - { 7060, -3535, 6532, -3308 }, - { 5600, -2719, 5363, -1568 }, - { 4661, -2803, 6263, -4716 }, - { 3673, -3636, 6147, -3433 }, - { 5305, -2585, 6073, -2638 }, - { 7614, -1962, 6079, -5266 }, - { 6760, -3366, 7382, -4322 }, - { 6385, -3883, 4797, -1353 }, - { 8182, -5120, 4298, -4641 }, - { 9130, -6198, 4975, -3063 }, - { 7421, -5436, 5576, -3713 }, - { 3483, -4898, 5443, -2745 }, - { 4907, -5643, 6390, -4105 }, - { 8119, -7008, 7992, -6764 }, - { 6528, -6122, 6967, -5590 }, - { 5890, -4190, 6624, -5688 }, - { 6815, -7934, 7275, -5456 }, - { 5434, -4306, 5169, -5378 }, - { 4364, -6436, 5376, -2604 }, - { 8152, -3404, 5913, -5048 }, - { 7983, -4863, 4262, -2461 }, - { 8023, -6188, 6238, -5062 }, - { 6753, -3692, 3935, -3723 }, - { 6826, -4760, 3284, -4051 }, - { 7224, -7423, 4492, -3875 }, - { 6904, -2590, 6587, -6248 }, - { 6106, -1944, 7345, -5506 }, - { 4956, -2990, 7808, -3146 }, - { 6908, -6885, 5949, -1288 }, - { 7162, -6058, 3419, -3401 }, - { 7015, -7080, 6907, -3018 }, - { 6971, -6832, 5646, -3273 }, - { 8014, -5546, 5471, -1544 }, - { 6792, -2220, 5105, -2879 }, - { 8494, -3974, 4408, -3999 }, - { 9591, -4866, 6027, -4558 }, - { 5264, -5161, 6101, -738 }, - { 5803, -6141, 5197, -5231 }, - { 4657, -6822, 3232, -5189 }, - { 4791, -5135, 3809, -4665 }, - { 6108, -5103, 2379, -3873 }, - { 4680, -3909, 3234, -5093 }, - { 5802, -3853, 3795, -4984 }, - { 4360, -7483, 4802, -3877 }, - { 5429, -7517, 5911, -3717 }, - { 6866, -2280, 4880, -4634 }, - { 10131, -4628, 4414, -4092 }, - { 10811, -5189, 7746, -5337 }, - { 5663, -8941, 5287, -5680 }, - { 8023, -5991, 7403, -2796 }, - { 9669, -6919, 6525, -4932 }, - { 7275, -3796, 4962, -2547 }, - { 8848, -4806, 5677, -3080 }, - { 8128, -4308, 7749, -6569 }, - { 4032, -5196, 2282, -6239 }, - { 6593, 700, -229, 304 }, - { 8260, 539, -66, -1259 }, - { 6605, 176, -814, -109 }, - { 8057, 0, -1, -136 }, - { 7382, -38, -484, -1129 }, - { 8373, -929, 682, -454 }, - { 7674, 690, -1278, 546 }, - { 7326, -517, 406, -1283 }, - { 7612, -1715, -1167, 1175 }, - { 8590, 441, -782, -710 }, - { 8572, -1202, -291, 260 }, - { 7308, -147, -1785, 414 }, - { 6787, -353, -672, 934 }, - { 5177, -133, 179, 82 }, - { 4161, -34, 447, 1497 }, - { 5997, -902, 1533, -121 }, - { 5727, -871, -1370, 945 }, - { 8386, -252, 293, -823 }, - { 6573, -1354, 682, 616 }, - { 7650, -2096, 725, 457 }, - { 8122, 78, 636, -1400 }, - { 8421, 428, -1620, 131 }, - { 7341, -1292, -717, 186 }, - { 7998, -49, -720, 266 }, - { 5987, -351, 669, 844 }, - { 7314, -1620, 250, -603 }, - { 7219, -1562, -572, 1994 }, - { 8682, -358, -290, -388 }, - { 5810, 155, -178, 1199 }, - { 7246, -12, 1042, -786 }, - { 7357, -923, 1468, -475 }, - { 7801, 621, -212, -724 }, - { 5346, -514, 1210, 1356 }, - { 8459, 36, -127, -779 }, - { 6878, -2429, 854, 1750 }, - { 7280, -1401, -1353, 2845 }, - { 7579, -2148, -1463, 2087 }, - { 6637, 946, -872, 750 }, - { 4807, -1100, 1289, 2602 }, - { 4495, 219, 1551, 1128 }, - { 7639, 506, 446, -1107 }, - { 6359, 188, 1009, -115 }, - { 6641, -1820, 1655, 723 }, - { 5394, -2382, 1604, 2542 }, - { 6021, -2644, 2396, 1407 }, - { 4698, 882, 245, 1525 }, - { 8103, 573, -798, -349 }, - { 8045, -519, 997, -1092 }, - { 7571, -122, 227, -338 }, - { 5347, -1200, 630, 1718 }, - { 7070, 790, 218, -544 }, - { 7440, 728, -527, -20 }, - { 6402, -355, 197, -736 }, - { 4031, 771, 866, 1895 }, - { 6009, 896, 445, -31 }, - { 5160, 1098, -856, 1784 }, - { 7980, -886, -1293, 1396 }, - { 6318, -1361, 2423, 252 }, - { 7547, -699, 133, 506 }, - { 8562, -2344, 940, 264 }, - { 5890, 1187, -1425, 2194 }, - { 6558, -645, -1311, 2621 }, - { 4634, -1671, 2075, 1623 }, - { 5614, 105, -816, 2376 }, - { 6646, 1558, -1365, 630 }, - { 6998, 1150, -2117, -990 }, - { 6555, 2311, -1093, -1783 }, - { 6682, 1430, -2391, -1940 }, - { 7861, 1555, -2977, -1188 }, - { 6745, 1723, -459, -2085 }, - { 7504, 1229, -1666, -2060 }, - { 7937, 671, -2128, -1529 }, - { 7139, 991, -735, -2632 }, - { 6867, 1592, -1303, -2324 }, - { 6401, 2230, -1732, -2508 }, - { 7201, 2184, -2169, -1988 }, - { 6636, 2190, -995, -2840 }, - { 7620, 2306, -2089, -651 }, - { 7584, 1875, -1438, -631 }, - { 9214, 1561, -2464, -1139 }, - { 6154, 1318, -1237, -2917 }, - { 7917, 2847, -1797, -1599 }, - { 8309, 2029, -2555, -465 }, - { 8204, 1282, -584, -2405 }, - { 8440, 1035, -1147, -1137 }, - { 7107, 1858, -60, -1568 }, - { 6781, 2912, -873, -1463 }, - { 7603, 1316, -319, -1249 }, - { 7833, 1335, -78, -1849 }, - { 7930, 1141, -1016, -695 }, - { 7883, 1610, -1017, -1314 }, - { 8069, 1409, -1811, -196 }, - { 8319, 1031, -582, -1590 }, - { 5948, 1537, -2153, -2373 }, - { 8684, 1171, -1871, -850 }, - { 8357, 2484, -2411, -1292 }, - { 6516, 2092, -193, -1167 }, - { 6112, 1697, 22, -525 }, - { 7161, 703, -602, -1879 }, - { 6047, 2351, -807, -219 }, - { 8072, 1854, -1817, -1553 }, - { 6956, 1304, 76, -1011 }, - { 6607, 1481, -544, -162 }, - { 6958, 2541, -265, -1938 }, - { 6416, 2514, -777, -850 }, - { 7272, 2110, -899, -1171 }, - { 7741, 2153, -283, -2614 }, - { 6482, 2041, -1758, -1221 }, - { 6762, 940, -1862, -2281 }, - { 5610, 1194, -1691, -1561 }, - { 7833, 2164, -823, -1952 }, - { 5460, 1438, -848, 1189 }, - { 6011, 1377, -771, -1557 }, - { 7679, 544, -1134, -2214 }, - { 7209, 1292, -2714, -1564 }, - { 5567, 1200, -404, -169 }, - { 5853, 1461, -1465, -518 }, - { 6782, 689, -844, -860 }, - { 7330, 1337, -1152, -71 }, - { 7189, 1506, -653, -685 }, - { 6860, 2116, -1403, -240 }, - { 8804, 1516, -1391, -1760 }, - { 7210, 2689, -1498, -989 }, - { 7030, 3022, -1441, -2083 }, - { 5649, 1836, -407, 525 }, - { 7451, 3099, -717, -2464 }, - { 7384, 1656, -2007, 398 }, - { 6504, 707, -1919, -134 }, - { -1851, 3639, -2279, -695 }, - { -4037, 1644, -77, 1329 }, - { -4025, 1960, -1565, -567 }, - { -3430, 2495, -795, 368 }, - { -4771, 2480, 993, 756 }, - { -3431, 2058, -2539, -971 }, - { -3802, 3418, 380, 217 }, - { -3074, 3350, -1652, -1056 }, - { -3705, 326, -1650, 1535 }, - { -3122, 1281, -1192, 1607 }, - { -4601, 1367, -968, 53 }, - { -3808, 958, 44, 2560 }, - { -2079, 2530, -1485, 1166 }, - { -3707, 343, -2889, 180 }, - { -5249, 1431, -31, 688 }, - { -4990, 125, -704, 1270 }, - { -2771, 1334, -2446, 746 }, - { -2292, 994, -1527, 2630 }, - { -1261, 3070, -2519, 268 }, - { -2544, 3890, -1057, -552 }, - { -4421, 255, -1980, 530 }, - { -2951, 454, -13, 3643 }, - { -2262, 1815, -370, 2880 }, - { -2383, 3657, -649, 576 }, - { -3541, -161, -1389, 2550 }, - { -4241, 1575, 1325, 2561 }, - { -2767, 4037, 1221, 1578 }, - { -3748, 2697, 1148, 1801 }, - { -4686, 2385, -220, 0 }, - { -1531, 1645, -2751, 1327 }, - { -45, 4032, -799, 2298 }, - { -2915, 2280, 709, 2495 }, - { -1199, 3278, -406, 2346 }, - { -2471, 116, -2706, 2060 }, - { -2440, 2173, -2894, -344 }, - { -3375, 2287, 1781, 3226 }, - { -2153, 3568, 1827, 2918 }, - { -862, 2267, -1626, 2527 }, - { -2698, 1135, 301, 4239 }, - { -2364, 2123, 1010, 3710 }, - { -2447, 3281, -81, 1408 }, - { -2660, 4735, 472, 258 }, - { -1053, 3097, 2682, 2398 }, - { -3366, -1037, -1152, -868 }, - { -643, 4242, 2212, 1259 }, - { 971, 3991, 934, 643 }, - { -1617, 2002, 2139, 2195 }, - { -4897, 972, 784, 1719 }, - { -1275, 2992, 1039, 3821 }, - { -392, 4973, -209, 1821 }, - { -1028, 4718, -1479, -137 }, - { 50, 3914, 553, 2210 }, - { 678, 4364, 359, 1303 }, - { -582, 4911, 514, 1671 }, - { 1276, 3914, -1252, 2934 }, - { -1496, 3984, 857, 2330 }, - { 772, 4744, -655, 2332 }, - { -799, 5283, -439, 624 }, - { 1341, 2937, 650, 2027 }, - { -1739, 4892, 1275, 1702 }, - { -892, 2596, -151, 3951 }, - { -3532, 1090, 1292, 32 }, - { 321, 3146, 2647, 1475 }, - { 264, 4199, -1591, 1317 }, - { -452, -2357, 2266, 4192 }, - { 3022, -1033, -2389, 5678 }, - { -1162, -1342, 3543, 4990 }, - { -474, -1477, -1223, 5016 }, - { -699, -2857, 900, 3835 }, - { -461, -2255, -117, 4626 }, - { 1204, -2062, -1211, 4403 }, - { 2192, -3035, -337, 3966 }, - { 108, -831, 279, 5643 }, - { 1457, -620, -2908, 5276 }, - { -2527, -78, 1085, 5460 }, - { -1978, -1918, -949, 4733 }, - { 32, 367, -1904, 5166 }, - { 1890, -1665, 440, 4752 }, - { -518, -348, 2816, 4891 }, - { 3695, -2490, -1374, 4603 }, - { 246, -1965, 3549, 3969 }, - { 1100, -3111, 656, 3737 }, - { -1379, 870, -414, 4575 }, - { 628, -357, -1227, 6179 }, - { -1129, -1318, -2457, 4576 }, - { -425, -98, -73, 6336 }, - { 367, -887, 2990, 4207 }, - { 2091, -1251, 2444, 3557 }, - { -1759, -1610, 2046, 5273 }, - { 3210, 1414, -20, 2616 }, - { 3303, -2636, 1005, 4237 }, - { -327, -3107, -640, 3687 }, - { -197, 764, 572, 5486 }, - { 646, -767, 1388, 5464 }, - { 104, 2742, -228, 3907 }, - { -236, 1829, -579, 4585 }, - { -2150, -474, -1525, 4006 }, - { -23, -2632, -2400, 3892 }, - { -12, -1739, -2910, 4867 }, - { -2310, -368, -102, 4583 }, - { -1991, -2061, 533, 4531 }, - { 3884, -1446, -153, 4393 }, - { 1568, 14, -289, 5268 }, - { -1376, -253, -2797, 3417 }, - { 3193, -2577, 2475, 3566 }, - { 3418, 617, 1350, 1857 }, - { 3792, -24, -272, 3370 }, - { 153, 1159, 2906, 2877 }, - { 511, 2162, 1548, 2741 }, - { 262, 819, -2791, 3734 }, - { 4232, -2015, 1486, 3477 }, - { 2943, -1110, -1014, 5480 }, - { 2842, 369, 703, 3476 }, - { 3011, 1634, -933, 3553 }, - { 4412, -1548, -942, 5021 }, - { -1405, 593, 2372, 5267 }, - { 2093, 2129, 896, 2365 }, - { 4845, -1980, 0, 3823 }, - { -2140, 81, 3278, 5637 }, - { 1484, 2665, -324, 3653 }, - { 10, 192, 1620, 5291 }, - { 2152, 738, -2269, 5000 }, - { 2102, 2748, -1652, 4707 }, - { 2855, -2131, -387, 5188 }, - { 1173, 676, 1338, 3277 }, - { 2340, -2329, -2064, 4095 }, - { 861, -2024, 1296, 5055 }, - { 2189, 3225, -695, 2626 }, - { 6196, -7079, 1943, -822 }, - { 4547, -4813, 3261, 1856 }, - { 4243, -6904, 3443, 448 }, - { 4581, -7503, 946, 506 }, - { 6626, -7754, 3427, 470 }, - { 3407, -9088, 3269, -1496 }, - { 4079, -6464, 2304, 777 }, - { 5621, -9336, 2684, -768 }, - { 5351, -6464, 5238, -214 }, - { 5961, -8007, 1724, -3091 }, - { 4213, -8067, 603, -246 }, - { 7208, -7403, 3168, -1738 }, - { 6098, -7700, 329, -1379 }, - { 6525, -6735, 4248, -1072 }, - { 6073, -6241, 2167, -2378 }, - { 4609, -9218, 3051, -1033 }, - { 6813, -7283, 1581, -1897 }, - { 6126, -6275, 2789, 681 }, - { 4423, -6538, 1621, -1692 }, - { 6272, -8298, 3167, -1855 }, - { 6172, -8558, 4498, -1169 }, - { 4844, -8588, 1647, -366 }, - { 6209, -8807, 1581, -369 }, - { 5389, -8059, 550, -192 }, - { 6654, -9775, 2504, -1063 }, - { 7103, -7998, 806, 530 }, - { 5662, -6736, 1565, -3620 }, - { 4165, -9564, 4191, -2131 }, - { 4526, -7181, 576, -2875 }, - { 4633, -8623, 2807, -4742 }, - { 3709, -7794, 1815, 34 }, - { 3634, -8622, 2313, -826 }, - { 6991, -8447, 2063, -3198 }, - { 7757, -9486, 2255, -558 }, - { 4149, -7778, 4728, -1696 }, - { 5767, -7427, 1113, 707 }, - { 4592, -6261, 2329, 1864 }, - { 3159, -10498, 1677, -4273 }, - { 3534, -9010, 2437, -3565 }, - { 4479, -10821, 2715, -4942 }, - { 3207, -9805, 3054, -3886 }, - { 4627, -8189, 3018, -2354 }, - { 5527, -10566, 3244, -2749 }, - { 4346, -10127, 3335, -3084 }, - { 6132, -10085, 3316, -1308 }, - { 5629, -9704, 2178, -3058 }, - { 3603, -8538, 1246, -624 }, - { 3737, -8488, 395, -3167 }, - { 5465, -11414, 2810, -4640 }, - { 5306, -7745, 2721, -3988 }, - { 7000, -9111, 1695, -1409 }, - { 6663, -7741, 2466, -4079 }, - { 4083, -7175, 1836, -4831 }, - { 3613, -9926, 1342, -3455 }, - { 6588, -8033, 457, -258 }, - { 4720, -8102, 17, -1209 }, - { 7414, -8709, 1294, -344 }, - { 5437, -10030, 4043, -1704 }, - { 4862, -9281, 1558, -1431 }, - { 6800, -6403, 5113, 862 }, - { 4623, -8242, 2667, -228 }, - { 5919, -5083, 3348, 2135 }, - { 5985, -8889, 2733, -5105 }, - { 5029, -5767, 4407, 719 }, - { 354, -6158, -838, -3001 }, - { 351, -5943, -2104, -1534 }, - { -633, -7190, -25, -4798 }, - { -1595, -7235, -3812, -1400 }, - { 103, -6197, -2933, -78 }, - { -1722, -5020, -3441, -4333 }, - { -1963, -5644, -4365, -270 }, - { -846, -5743, -3477, 196 }, - { -191, -5348, -4054, -469 }, - { -2515, -7754, -3495, -818 }, - { -2090, -6710, -2701, 117 }, - { -546, -7036, -1398, 163 }, - { -278, -7091, -2662, -536 }, - { -622, -7962, -2731, -1464 }, - { -1555, -8118, -3612, -2057 }, - { -1094, -6280, -2314, 505 }, - { -2556, -8538, -4024, -2247 }, - { 109, -7134, -3107, -1823 }, - { -900, -6954, -3340, -717 }, - { -605, -7113, -3656, -2154 }, - { 837, -6263, -3211, -2177 }, - { -417, -5810, -3871, -1469 }, - { -1318, -5649, -4207, -3198 }, - { 413, -6765, -2082, -33 }, - { -3101, -6450, -4362, -766 }, - { 755, -6489, -2967, -846 }, - { 1117, -7106, -2452, -1352 }, - { -1202, -8387, -3072, -2897 }, - { -365, -4894, -3561, -2937 }, - { -2372, -8776, -265, -4441 }, - { -1224, -8678, -896, -5074 }, - { -755, -10096, -600, -6623 }, - { 300, -8206, -225, -4568 }, - { -1176, -6824, -2633, -3527 }, - { -2006, -5443, -1526, -5849 }, - { -1115, -5540, -2363, -4785 }, - { 1059, -6812, -2543, -2654 }, - { -1976, -6861, -3062, -5508 }, - { -379, -5328, -2321, -3624 }, - { -2108, -5860, -4518, -1915 }, - { -379, -7885, -1329, -594 }, - { 774, -5389, -581, -5213 }, - { -2601, -5083, -1849, -4921 }, - { -176, -5580, 74, -5075 }, - { -204, -6780, -190, -6232 }, - { 418, -7594, -1987, -820 }, - { -1873, -8529, -2926, -1609 }, - { 1340, -6362, -919, -4975 }, - { 577, -7990, -2044, -1873 }, - { -2572, -7413, -1745, -2224 }, - { -2037, -7030, -1461, -7138 }, - { -2559, -8756, -2039, -5836 }, - { -2079, -6764, -1209, -5669 }, - { -1613, -7801, -2006, -685 }, - { -1865, -6583, -722, -3529 }, - { -589, -6358, -1377, -1003 }, - { -540, -7514, -1331, -3542 }, - { 419, -6192, -1677, -4927 }, - { -2786, -8763, -2966, -5065 }, - { -2172, -8411, -1726, -4675 }, - { -3382, -9833, -3497, -5722 }, - { -2433, -10169, -2077, -5775 }, - { -424, -9451, -1096, -3658 }, - { -537, -8522, -910, -1897 }, - { -5550, 2807, 1683, -693 }, - { -6395, 635, 3573, -1246 }, - { -7544, 2280, 2140, 44 }, - { -8751, 1136, 2951, -794 }, - { -5605, 2709, 2052, 916 }, - { -7650, 654, 869, 135 }, - { -6939, 967, 1409, 870 }, - { -7834, 2123, 3310, 974 }, - { -6935, 2818, 1274, -1678 }, - { -5605, 2233, 1013, 471 }, - { -7095, 1849, 1648, 198 }, - { -6636, 1634, 712, -37 }, - { -7279, 978, 296, -315 }, - { -7664, 3504, 3292, -216 }, - { -7836, 1209, 1221, -257 }, - { -7913, 2201, 1765, -1529 }, - { -7077, 3783, 2632, -1407 }, - { -5565, 1645, 1410, -622 }, - { -6494, 2879, 1181, -759 }, - { -7073, 3137, 3010, 550 }, - { -7249, 1839, 847, -805 }, - { -6630, 2197, 282, -1096 }, - { -8836, 1573, 1988, -1090 }, - { -7809, 1274, 836, -1198 }, - { -7895, 2970, 3511, -1097 }, - { -6960, 1664, 1356, -2442 }, - { -6582, 2866, 2273, 307 }, - { -7221, 821, 2851, -1435 }, - { -6015, 1703, 2001, -2367 }, - { -8082, 1034, 2103, 239 }, - { -5952, 1912, 301, -465 }, - { -6099, 841, 379, 567 }, - { -6343, 50, 494, 658 }, - { -6586, 983, 591, -893 }, - { -5500, 869, 2187, -2479 }, - { -6482, 60, 1545, -979 }, - { -6705, 515, 1974, -53 }, - { -6460, 1755, 1325, -1275 }, - { -6093, 2617, 2465, -623 }, - { -7330, 2161, 594, -2115 }, - { -7324, 762, 1593, -2004 }, - { -6385, 679, 1510, -2514 }, - { -6159, 241, 2976, -1631 }, - { -8583, 3030, 4045, -162 }, - { -6299, 66, 2209, -2103 }, - { -5428, 1279, 3267, -1846 }, - { -6438, 1335, 2728, -1631 }, - { -8012, 1070, 2428, -1151 }, - { -6201, 2781, 2349, -1918 }, - { -5918, 1139, 3121, -148 }, - { -6314, 2481, 3137, -1808 }, - { -7180, 1722, 2435, -1602 }, - { -6750, 1829, 3763, -1145 }, - { -6713, 1777, 2221, 1212 }, - { -7479, 1835, 3627, -479 }, - { -7299, 10, 2406, -1593 }, - { -8249, 3129, 996, -2870 }, - { -8374, 1534, 1333, -1882 }, - { -7507, 3353, 1598, -2299 }, - { -7379, 2701, 2326, -1167 }, - { -8440, 2276, 2796, -542 }, - { -10348, 1527, 2649, -1165 }, - { -8184, 3614, 2574, -1738 }, - { -5539, 1574, 1733, 1138 }, - { 9404, -7652, 67, 79 }, - { 8654, -3972, 1358, -60 }, - { 8617, -4794, 117, 2318 }, - { 7886, -4505, 1784, 1200 }, - { 8636, -6125, 3879, -1003 }, - { 9654, -6836, 1816, 205 }, - { 9374, -6553, 913, 1875 }, - { 8020, -6150, 1134, 2390 }, - { 7786, -4970, 2078, -1857 }, - { 8691, -6119, 711, 708 }, - { 9039, -5568, 2944, -1902 }, - { 9955, -5048, 1433, -601 }, - { 8089, -6927, 3093, -2846 }, - { 8487, -7024, 2415, 19 }, - { 9388, -5287, 3577, -2655 }, - { 8591, -7371, 2300, -996 }, - { 9104, -4763, 1453, -2558 }, - { 7615, -5457, 596, 164 }, - { 9860, -7047, 3433, -614 }, - { 8756, -4404, 2235, -964 }, - { 9462, -4660, 299, -1822 }, - { 10119, -5550, 2689, -1273 }, - { 10915, -7471, 2705, -1007 }, - { 11433, -7090, 1410, -1198 }, - { 9882, -7431, 2965, -1895 }, - { 7628, -5219, 769, -2661 }, - { 8169, -5318, 2262, 70 }, - { 8846, -6320, 1939, -754 }, - { 7147, -5593, 1248, -971 }, - { 10652, -5485, 935, 137 }, - { 7778, -6533, 2564, -1932 }, - { 8878, -5173, 1214, -361 }, - { 9828, -4943, 282, 510 }, - { 10042, -6134, 3895, -1914 }, - { 7965, -6630, 3566, -433 }, - { 8573, -4502, 3574, -1209 }, - { 8398, -4801, 1031, -1347 }, - { 10136, -7772, 2612, 1547 }, - { 9890, -7280, 1768, -1083 }, - { 8407, -6585, -706, -58 }, - { 7976, -7582, 229, -131 }, - { 10481, -8866, 1166, -147 }, - { 10914, -4342, 3189, -2412 }, - { 10440, -5198, -104, -1109 }, - { 11227, -6530, 2381, -2449 }, - { 8487, -8064, 1086, 230 }, - { 9975, -6123, -857, -134 }, - { 8339, -6498, 1232, -2337 }, - { 11042, -4506, 1119, -2098 }, - { 12563, -5592, 1837, -2062 }, - { 11801, -5590, 632, -1296 }, - { 10152, -5617, 1511, -1917 }, - { 7800, -6473, 51, -1337 }, - { 7941, -5560, 2438, -3270 }, - { 6554, -3834, 2100, 1476 }, - { 9065, -5520, -226, -1120 }, - { 10794, -7120, -243, 122 }, - { 10429, -6968, 272, -806 }, - { 8942, -8914, 1442, -392 }, - { 9969, -5051, 2033, -2953 }, - { 7275, -4152, 3058, -64 }, - { 11127, -5488, 4589, -3227 }, - { 9626, -6666, 2739, -2958 }, - { 6943, -5362, 4470, 1008 }, - { -7456, -967, 2936, -1002 }, - { -8622, -333, 6962, 2606 }, - { -7486, -3392, 3668, 1287 }, - { -8053, -827, 5148, 1097 }, - { -6610, 454, 4952, 96 }, - { -7701, -1982, 3161, -468 }, - { -7307, -1132, 4071, -36 }, - { -8125, -271, 5199, 3862 }, - { -9182, -1950, 2813, 1878 }, - { -9855, -952, 4794, 3010 }, - { -7241, 1431, 4202, 2468 }, - { -9646, 157, 4766, 1046 }, - { -9371, 1230, 6009, 2958 }, - { -11514, -64, 8630, 5248 }, - { -6766, 565, 2766, 2140 }, - { -8426, -9, 2852, 1271 }, - { -11291, -1113, 5087, 2937 }, - { -8297, 2092, 4495, 1264 }, - { -9983, 735, 3809, -51 }, - { -9048, -1000, 3191, -308 }, - { -7331, -1987, 2655, 1391 }, - { -7144, -21, 4333, 2161 }, - { -6032, -1540, 3543, 896 }, - { -7987, -1036, 1985, 1529 }, - { -9264, 2004, 5194, 290 }, - { -11308, -840, 5754, 1654 }, - { -9130, -2398, 4292, 2973 }, - { -6248, 838, 3563, 1223 }, - { -6819, -2760, 3511, 119 }, - { -7213, -2006, 4364, 762 }, - { -5431, -1047, 4533, 166 }, - { -7098, -641, 2021, 639 }, - { -8628, -2249, 3588, 399 }, - { -6352, -1498, 3560, -648 }, - { -7033, -2190, 4870, 2562 }, - { -7405, -46, 3772, -581 }, - { -6104, 796, 5143, 1965 }, - { -5787, 943, 5784, 3030 }, - { -8367, 1465, 7192, 4097 }, - { -8259, 789, 5694, 1963 }, - { -10614, -1899, 5748, 2645 }, - { -8258, -805, 3698, 2275 }, - { -6877, -972, 6431, 3160 }, - { -6483, 363, 7018, 3129 }, - { -6283, -1358, 5191, 1524 }, - { -8853, -3157, 4119, 1741 }, - { -6086, -267, 3883, -835 }, - { -7254, 1032, 6613, 4017 }, - { -11470, -3350, 4649, 3426 }, - { -6743, 481, 6148, 1239 }, - { -5394, -166, 5309, 3165 }, - { -7958, 1068, 4268, -240 }, - { -10520, 2256, 7916, 2828 }, - { -5132, -4, 5739, 1176 }, - { -8643, 120, 3255, -629 }, - { -9631, 1974, 8870, 4362 }, - { -10663, -1221, 3733, 589 }, - { -8224, -1843, 5806, 2655 }, - { -8282, 1255, 8647, 3478 }, - { -12311, -1505, 9043, 6256 }, - { -11312, -856, 7136, 4681 }, - { -11944, -722, 7941, 3309 }, - { -7868, -463, 6846, 4196 }, - { -8679, -241, 7410, 5347 }, - { 6759, -4680, -508, 1220 }, - { 5176, -6111, 944, 121 }, - { 6843, -5667, -1368, -533 }, - { 5616, -5884, -1471, -695 }, - { 6030, -5089, -1808, -940 }, - { 7444, -5463, -52, 1881 }, - { 4207, -6079, -506, 1571 }, - { 6785, -4410, -649, 3084 }, - { 4838, -5214, 2026, 2998 }, - { 4201, -5790, 645, 1811 }, - { 6930, -5129, -1940, 1698 }, - { 6332, -4627, 692, 3027 }, - { 6285, -4314, -106, 3644 }, - { 6255, -5450, -1975, 742 }, - { 4199, -4676, -459, 1796 }, - { 5592, -5500, 1345, 1300 }, - { 4358, -5556, -2236, 114 }, - { 4620, -5875, -1563, 888 }, - { 4892, -7550, -327, -419 }, - { 4734, -7085, 7, 613 }, - { 3883, -5562, -1969, 1080 }, - { 5610, -4990, -204, 834 }, - { 4117, -6482, -1271, 341 }, - { 6585, -5107, 892, 1169 }, - { 6632, -3683, 302, 3002 }, - { 6326, -5351, -983, -1250 }, - { 4382, -7192, -730, -158 }, - { 5227, -6540, -451, 1123 }, - { 5468, -6472, -870, -1471 }, - { 5191, -6402, -1365, -127 }, - { 7407, -6317, -973, -336 }, - { 4611, -6530, -820, -1980 }, - { 4963, -5159, -2050, -966 }, - { 4414, -5691, -211, -998 }, - { 5954, -5873, 750, -1749 }, - { 4394, -4796, -1268, 254 }, - { 7161, -6214, -1010, 689 }, - { 4965, -3598, 2372, 1711 }, - { 6248, -6180, 981, 864 }, - { 6473, -5336, 525, -600 }, - { 4591, -6864, -1131, -900 }, - { 6314, -6440, -1021, -375 }, - { 5838, -6209, -1199, 944 }, - { 5308, -5283, -2100, 1267 }, - { 4342, -5860, -1637, -1356 }, - { 5680, -4388, -1227, -104 }, - { 4900, -4098, 1449, 4046 }, - { 4677, -4284, -106, 3190 }, - { 7574, -6173, -848, 1859 }, - { 6493, -7207, -131, 726 }, - { 5513, -5261, -2117, 4 }, - { 6191, -7352, -193, -505 }, - { 5885, -4333, 324, -134 }, - { 6162, -6081, -312, -2044 }, - { 4216, -6200, -1810, -572 }, - { 5652, -7035, -696, -197 }, - { 7131, -7189, -366, -60 }, - { 5032, -4803, -1514, 2832 }, - { 7386, -4610, -606, 3489 }, - { 4211, -5031, 1221, 3047 }, - { 4050, -4653, 1584, 1469 }, - { 6852, -5302, -1861, 206 }, - { 7736, -4816, -1794, 3359 }, - { 6290, -3439, 1522, 2454 }, - { 1768, 5990, -5560, -2594 }, - { 3903, 5326, -1530, -1501 }, - { 2472, 3738, -2117, -4240 }, - { 3260, 5448, -904, -4733 }, - { 1435, 7297, -3676, -4102 }, - { 4096, 5951, -656, -3312 }, - { 2178, 6009, -3146, -3724 }, - { 3787, 5493, -5473, -1633 }, - { 2998, 7286, -3334, -3571 }, - { 2894, 6576, -4708, -2804 }, - { 830, 6163, -4286, -3348 }, - { 4755, 5569, -1730, -2739 }, - { 4604, 6065, -3562, -2605 }, - { 2749, 5141, -3986, -2775 }, - { 3942, 4875, -2143, -3340 }, - { 2819, 8517, -2004, -2724 }, - { 2146, 6298, -689, -3093 }, - { 5196, 6504, -3393, -1475 }, - { 1851, 8386, -1748, -1420 }, - { 3474, 8572, -3534, -2688 }, - { 4503, 7560, -3561, -2245 }, - { 4433, 6219, -2393, -1575 }, - { 3506, 7248, -2275, -1977 }, - { 3490, 7409, -3147, -604 }, - { 4214, 6447, -3520, 516 }, - { 619, 7034, -829, -1705 }, - { 1732, 7395, -356, -2208 }, - { 1226, 5204, -3294, -3732 }, - { 2027, 5619, -1813, -4146 }, - { 3078, 5877, 47, -2651 }, - { 1654, 5458, 424, -682 }, - { 3163, 5464, -2026, -270 }, - { 2884, 5375, -685, -530 }, - { 2950, 7286, -35, -2967 }, - { 1986, 5066, -597, 482 }, - { 3459, 4308, -3845, -2333 }, - { 3155, 7037, -1346, -4345 }, - { 2193, 6696, -717, -1319 }, - { 3677, 5089, -3892, -487 }, - { 2186, 5136, -4186, -1492 }, - { 773, 5796, -917, 817 }, - { 2489, 6546, -3570, -2117 }, - { 1223, 6469, -1362, -33 }, - { 271, 6061, -1466, -1725 }, - { 2540, 5171, -1847, 1032 }, - { 2548, 5251, -2697, 1677 }, - { 771, 7600, -768, -632 }, - { 4710, 6647, -4736, -1275 }, - { 1369, 5917, -2971, -1056 }, - { 163, 5239, -3499, -2275 }, - { 2104, 4285, -3211, -3286 }, - { 1107, 7411, -1972, -1671 }, - { 2196, 7262, -2310, -1926 }, - { -244, 6439, -1745, -839 }, - { 3293, 3832, -2890, -3000 }, - { 419, 6443, -379, -407 }, - { 3077, 4930, -1156, -2869 }, - { 2131, 5874, -2330, 224 }, - { 690, 6538, -2212, -2841 }, - { 1602, 4421, -2515, 1542 }, - { 3318, 9373, -3032, -3477 }, - { 5646, 7462, -5153, -1463 }, - { 4139, 7137, -1539, -3321 }, - { 3481, 9077, -1645, -3653 }, - { -7747, 375, -106, -543 }, - { -8587, -1379, -586, -461 }, - { -10146, -892, 2094, 694 }, - { -8103, 382, 504, -325 }, - { -8548, -92, 94, -656 }, - { -7460, 38, 152, 388 }, - { -8266, -271, -459, -883 }, - { -7935, -664, -1026, -802 }, - { -8341, -109, 853, 161 }, - { -8802, -1355, 1099, 630 }, - { -8957, -6, 1108, -669 }, - { -7260, -1520, -43, -407 }, - { -7555, -174, 668, -2562 }, - { -9014, -126, 227, -1191 }, - { -8184, 769, 290, -1375 }, - { -9476, 55, 962, -1528 }, - { -8679, 541, 755, -1030 }, - { -9842, -1626, 838, -1588 }, - { -8513, -702, 788, -1998 }, - { -10101, -1558, -366, -1841 }, - { -8135, 78, 1479, -1813 }, - { -9128, -454, 313, -1786 }, - { -7554, -1084, 831, -2442 }, - { -7576, -701, 2068, -1665 }, - { -7791, -1481, 1587, -1808 }, - { -6701, -596, -97, 802 }, - { -7418, -15, 684, -963 }, - { -7127, -477, -139, -426 }, - { -8097, -110, -36, -264 }, - { -7620, -1922, -590, -101 }, - { -7647, -1201, 279, 660 }, - { -7856, -1974, 758, -2271 }, - { -8496, -167, 2232, -1143 }, - { -8506, -1359, 624, -740 }, - { -7274, -1052, 1062, -139 }, - { -7800, -217, 91, -1794 }, - { -7030, -1694, -955, 615 }, - { -9020, -1864, 101, -2182 }, - { -9400, -740, 598, -667 }, - { -8448, -1184, 2024, -1272 }, - { -8812, -570, -897, -2384 }, - { -10559, -1286, 538, -1536 }, - { -8728, -888, -1089, -1397 }, - { -7080, -1185, 636, -1252 }, - { -9880, 233, 2344, -782 }, - { -7952, -1326, -378, -1947 }, - { -7207, -378, 1408, -2237 }, - { -8467, -1545, 902, -1987 }, - { -9163, -1474, 924, -1739 }, - { -8159, -992, -77, -2744 }, - { -8343, 148, -423, -1573 }, - { -9105, -649, -254, -1214 }, - { -8939, 456, 281, -1905 }, - { -8837, 179, -394, -2634 }, - { -9145, 757, 1547, -1319 }, - { -9775, -723, 441, -1680 }, - { -8910, -686, 1529, -1525 }, - { -9492, -1134, 2064, -938 }, - { -6111, -943, 677, -31 }, - { -7411, -613, -814, 46 }, - { -9479, -922, -430, -2061 }, - { -11298, -1268, 1318, -1117 }, - { -8190, 832, 671, -2214 }, - { -10453, -550, 1672, -886 }, - { 1044, 9353, -1651, -5423 }, - { 1034, 8149, -455, -6166 }, - { 761, 8293, -3214, -4838 }, - { 938, 8077, 164, -5130 }, - { 1295, 8673, 2582, -5490 }, - { -314, 7973, -2395, -5231 }, - { -507, 9012, -2497, -5775 }, - { 2396, 8314, -1022, -4673 }, - { -1516, 8501, 1950, -4969 }, - { -308, 7401, 1549, -4866 }, - { -112, 8340, 3003, -4920 }, - { -50, 9315, 1371, -5666 }, - { -659, 9449, 2496, -5547 }, - { 2573, 9148, -2270, -4783 }, - { 830, 7104, -438, -3907 }, - { 522, 10672, -677, -6483 }, - { -1190, 10108, -510, -6518 }, - { -427, 8271, -579, -6315 }, - { 1602, 8113, -1927, -4418 }, - { -2266, 8180, 448, -5190 }, - { -1633, 8816, -226, -5771 }, - { 759, 9481, -105, -5813 }, - { 2254, 6679, -466, -5662 }, - { -88, 6946, 895, -5958 }, - { -1705, 10009, 1394, -5574 }, - { 748, 7943, 540, -6692 }, - { 1411, 7009, 232, -6145 }, - { 697, 7290, -1221, -5342 }, - { -1764, 10580, 1944, -3981 }, - { -1334, 9124, 1195, -3903 }, - { -905, 10067, 635, -5039 }, - { 664, 10680, 49, -4625 }, - { 1374, 9536, -777, -3591 }, - { 252, 9698, -597, -2931 }, - { 824, 9164, -1014, -2144 }, - { 2438, 10569, -2289, -4424 }, - { 2101, 7102, 507, -3614 }, - { 294, 8051, -432, -1518 }, - { -665, 10337, 547, -2852 }, - { 1168, 11989, -492, -5427 }, - { 1344, 6416, 302, -5061 }, - { -1727, 12264, 1507, -4543 }, - { 674, 10889, -902, -3605 }, - { -582, 9504, 300, -3618 }, - { 641, 7654, 689, -2109 }, - { 2065, 9243, 508, -4367 }, - { 1055, 8373, 688, -3144 }, - { -641, 8185, 986, -3307 }, - { 1120, 7426, 1785, -3757 }, - { 1660, 8070, -593, -3104 }, - { 2002, 9467, -1722, -3475 }, - { 2361, 8368, 100, -3709 }, - { -772, 7845, -613, -4988 }, - { 1485, 7430, 1896, -6127 }, - { -432, 7823, -947, -2882 }, - { 313, 11122, -760, -4871 }, - { 412, 8412, -283, -4231 }, - { 1585, 10402, -1884, -3267 }, - { 321, 6952, 773, -3016 }, - { -105, 9014, 121, -2249 }, - { 1585, 10313, -977, -4812 }, - { 1619, 11869, 1306, -6876 }, - { -1168, 8886, -81, -2500 }, - { -395, 10886, 733, -6490 }, - { -4949, 4274, 3992, -1054 }, - { -4241, 5299, 4262, -1584 }, - { -2710, 3862, 4552, -1673 }, - { -4608, 2472, 3672, -1715 }, - { -2843, 2816, 4003, -2326 }, - { -5229, 2964, 5636, 90 }, - { -4924, 3442, 5015, -1096 }, - { -1281, 3313, 5537, -2066 }, - { -3808, 1939, 4351, -919 }, - { -1915, 2585, 4939, -1614 }, - { -3470, 1843, 5562, -682 }, - { -3800, 870, 5827, 144 }, - { -4985, 1452, 4728, -709 }, - { -3745, 2750, 7220, 259 }, - { -1875, 1900, 6514, -826 }, - { -4329, 1574, 7192, 1304 }, - { -5408, 1444, 6208, 631 }, - { -3327, 5312, 5707, -1541 }, - { -6966, 3334, 4034, 1028 }, - { -7484, 4245, 4218, -212 }, - { -6567, 5839, 4539, -512 }, - { -5715, 5935, 3747, -1186 }, - { -6410, 4881, 3356, -1610 }, - { -5146, 2590, 2850, 2172 }, - { -5196, 4095, 2569, -373 }, - { -5043, 6025, 4318, 692 }, - { -5525, 4884, 3513, 370 }, - { -6804, 7533, 5812, -488 }, - { -5657, 2480, 4061, 1234 }, - { -3155, 1472, 6071, 1188 }, - { -3427, 5217, 3442, 858 }, - { -4698, 3013, 5517, 2586 }, - { -4449, 2226, 5418, 3580 }, - { -6395, 3547, 5487, 2028 }, - { -3500, 5019, 4787, 1 }, - { -4038, 2578, 3073, 3151 }, - { -2750, 1955, 4469, 3856 }, - { -5696, 1659, 6118, 2469 }, - { -4350, 1241, 6840, 3126 }, - { -5565, 5058, 5196, 1314 }, - { -1642, 4190, 3948, 607 }, - { -1233, 4108, 4850, -640 }, - { -997, 3428, 3239, 1378 }, - { -6488, 2741, 6926, 2792 }, - { -4188, 3763, 4235, 2018 }, - { -3210, 3224, 5646, 1427 }, - { -5526, 6909, 5070, -627 }, - { -2815, 3994, 3425, 1903 }, - { -2163, 2734, 5423, 145 }, - { -4149, 4247, 2355, 734 }, - { -410, 2521, 4138, -16 }, - { -2411, 2385, 4927, 2105 }, - { -6077, 3591, 3114, 594 }, - { -4186, 4834, 5926, -1004 }, - { -7315, 3369, 5966, 448 }, - { -7042, 5721, 5771, 238 }, - { -4466, 3907, 3535, -1751 }, - { -2116, 3970, 6163, -1392 }, - { -7239, 2143, 8407, 3630 }, - { -5431, 4486, 6486, -42 }, - { -1874, 1617, 6333, 519 }, - { -6478, 2629, 4634, -505 }, - { -7784, 2342, 7216, 1365 }, - { -1154, 1432, 4831, 1544 }, - { -4964, -5801, 1797, 506 }, - { -4436, -6905, 1059, -1237 }, - { -5400, -6886, 884, -290 }, - { -6259, -7103, 523, -227 }, - { -4819, -6450, 1412, -450 }, - { -4056, -6213, 1725, -943 }, - { -5642, -6091, 1357, 605 }, - { -4196, -5678, 2187, -173 }, - { -4726, -5126, 2470, 321 }, - { -6642, -5091, 1507, -1005 }, - { -5304, -5250, 1944, 1579 }, - { -7179, -5520, 1468, -425 }, - { -6033, -4895, 1876, -955 }, - { -6595, -5143, 2207, 1291 }, - { -4224, -4943, 1846, 1792 }, - { -7128, -6950, 539, 724 }, - { -4369, -4901, 2590, 1103 }, - { -7413, -5696, 1712, 1440 }, - { -5885, -6821, 418, 871 }, - { -6828, -5599, 710, -1563 }, - { -6123, -5817, 1358, 1631 }, - { -5291, -5622, 578, 2138 }, - { -7171, -6004, 347, 2208 }, - { -6083, -5251, 2132, 425 }, - { -4329, -5721, 407, -2993 }, - { -5326, -5056, 1119, -1837 }, - { -5485, -5856, 185, -2389 }, - { -6529, -5178, 403, -697 }, - { -6719, -4412, 2726, 871 }, - { -5126, -5629, 1835, -771 }, - { -5622, -4361, 2973, 858 }, - { -5282, -5895, 45, -335 }, - { -4357, -5656, 1696, -1558 }, - { -7139, -6659, 627, -409 }, - { -4415, -6328, 35, 1306 }, - { -7639, -6110, 1134, 197 }, - { -3626, -5592, 2019, 901 }, - { -3547, -5064, 1176, 1738 }, - { -5075, -3899, 2087, 266 }, - { -4086, -6311, 1479, 360 }, - { -6210, -5220, -199, -1477 }, - { -3910, -5063, 1356, -15 }, - { -7616, -4977, 461, 2401 }, - { -6118, -6131, 1258, -563 }, - { -6127, -4968, 1286, -27 }, - { -4121, -5852, 1113, 1476 }, - { -5157, -4881, 1162, -662 }, - { -4637, -5031, 1179, 709 }, - { -5509, -5452, -397, 1224 }, - { -4597, -6861, 646, 467 }, - { -6247, -4043, 468, 278 }, - { -5336, -6465, 874, -1472 }, - { -6998, -6346, 78, -1798 }, - { -4915, -4530, 2756, -203 }, - { -6048, -4373, 1468, 1052 }, - { -4273, -7100, 942, -323 }, - { -6552, -4287, 2351, 69 }, - { -6954, -4613, 722, 1521 }, - { -4201, -5361, 763, -1562 }, - { -6881, -5596, -748, 669 }, - { -6695, -3547, -34, 1299 }, - { -3981, -5728, 84, 111 }, - { -4663, -4809, 2173, -1031 }, - { -6599, -6077, 1303, 256 }, - { -7596, -4265, -5791, -4140 }, - { -6610, -2758, -5288, -3936 }, - { -5880, -3865, -6563, -3088 }, - { -7228, -5510, -7677, -3912 }, - { -8854, -6553, -8318, -5361 }, - { -9362, -5249, -6413, -4319 }, - { -4418, -3110, -6368, -4358 }, - { -5544, -4203, -6863, -5013 }, - { -3056, -4316, -5567, -3181 }, - { -3078, -5999, -5051, -2657 }, - { -5884, -6292, -5756, -4013 }, - { -4825, -4549, -5535, -4053 }, - { -4443, -6126, -5316, -1368 }, - { -3972, -6341, -6098, -2686 }, - { -5751, -2781, -5398, -6230 }, - { -4466, -6135, -5570, -3679 }, - { -4291, -5992, -3564, -5189 }, - { -7189, -4429, -7279, -6082 }, - { -5076, -4433, -2748, -5366 }, - { -6225, -2825, -6833, -5663 }, - { -2989, -4792, -3960, -4492 }, - { -7836, -7773, -7722, -5741 }, - { -6559, -5703, -5844, -5589 }, - { -7612, -5438, -4136, -3774 }, - { -4218, -4176, -6591, -2333 }, - { -4837, -5063, -6581, 322 }, - { -6590, -5990, -2980, -3847 }, - { -5558, -2971, -5489, -1932 }, - { -7001, -5323, -4975, -1697 }, - { -4694, -2688, -6904, -3044 }, - { -8511, -5379, -5767, -2549 }, - { -7548, -5412, -6522, -2572 }, - { -6597, -4973, -6423, -1274 }, - { -6415, -4022, -5168, -1072 }, - { -5528, -5530, -7218, -2345 }, - { -4845, -4805, -5943, -1227 }, - { -6049, -7150, -6744, -2161 }, - { -9061, -7299, -8542, -4375 }, - { -5010, -5546, -5416, -82 }, - { -4135, -4205, -5109, -3373 }, - { -3311, -5869, -4007, -5061 }, - { -5993, -6472, -3962, -4718 }, - { -2966, -5832, -2821, -6305 }, - { -4851, -5152, -2067, -3930 }, - { -3620, -4441, -3362, -5836 }, - { -4469, -5221, -4534, -5592 }, - { -4022, -6335, -4321, -6107 }, - { -4899, -4503, -3084, -3725 }, - { -4490, -8276, -4620, -6236 }, - { -6591, -4342, -7365, -4063 }, - { -6498, -5057, -5553, 485 }, - { -6060, -2714, -7093, -4144 }, - { -6199, -7774, -7094, -4057 }, - { -7536, -6424, -6415, -4265 }, - { -7439, -2454, -6348, -4827 }, - { -5333, -7565, -4417, -4639 }, - { -4353, -7103, -4197, -2689 }, - { -5229, -6549, -5129, -6804 }, - { -6129, -7701, -5236, -4836 }, - { -6797, -3983, -3884, -4406 }, - { -6624, -4467, -4745, -5052 }, - { -3324, -7596, -2720, -6553 }, - { -5473, -6284, -1704, -4511 }, - { -4131, -7263, -3180, -5196 }, - { -7116, -5565, -3469, 685 }, - { -6002, -6021, -3858, 576 }, - { -3144, -8203, -1291, -434 }, - { -6096, -7027, -4004, 1353 }, - { -3943, -7709, -2344, -36 }, - { -4510, -6767, -2642, 631 }, - { -3657, -11541, -2570, -3984 }, - { -5959, -8854, -1333, -867 }, - { -6699, -8866, -1606, -344 }, - { -3836, -7961, -2334, -2028 }, - { -3430, -8045, -3037, -672 }, - { -3868, -9184, -3635, -1819 }, - { -4258, -9060, -2621, -1008 }, - { -3595, -8693, -2022, -752 }, - { -4573, -8048, -3166, -2622 }, - { -4852, -7903, -1405, 256 }, - { -4591, -7057, -1560, 965 }, - { -6963, -7655, -980, 808 }, - { -5179, -6641, -3356, 1196 }, - { -7102, -6941, -2798, 2123 }, - { -6867, -5834, -3320, -770 }, - { -5977, -7369, -2500, -778 }, - { -6160, -6400, -934, -2543 }, - { -6741, -7608, -355, -1289 }, - { -6856, -6466, -1433, -1643 }, - { -4786, -6292, -4970, 376 }, - { -5407, -8866, -2255, -400 }, - { -3814, -6506, -1387, -3620 }, - { -4998, -6137, -1200, -4092 }, - { -5123, -9557, -2849, -1306 }, - { -4259, -6444, -4395, -338 }, - { -5221, -6810, -883, 1225 }, - { -6137, -6215, -2165, 554 }, - { -3895, -6557, -3176, -1829 }, - { -3886, -8188, -87, -954 }, - { -7243, -6707, -2216, -316 }, - { -5592, -7606, 85, -432 }, - { -3957, -7945, -504, -144 }, - { -4617, -7624, 218, -312 }, - { -4797, -8737, -844, -1051 }, - { -4478, -8516, -1401, -454 }, - { -4557, -7058, -302, -2332 }, - { -6623, -7736, -271, -50 }, - { -3157, -7532, -1111, -2207 }, - { -3590, -7300, -1271, 517 }, - { -4442, -7306, -507, 590 }, - { -6458, -7524, -2807, 666 }, - { -4991, -8466, -3363, -785 }, - { -7474, -7541, -1056, -1839 }, - { -7501, -8316, -938, -180 }, - { -5329, -7739, -579, -2341 }, - { -4549, -7063, -176, -3539 }, - { -5191, -8612, -1504, -4250 }, - { -3083, -7058, -2251, 32 }, - { -4003, -7043, -1093, -791 }, - { -5523, -8093, -678, -114 }, - { -3022, -10265, -2070, -3109 }, - { -3905, -6274, -182, -3652 }, - { -3269, -9217, -551, -2650 }, - { -3138, -9314, -1726, -1704 }, - { -4420, -10339, -1744, -3459 }, - { -4163, -8609, -2298, -4113 }, - { -5566, -6505, -1241, -463 }, - { -3130, -9746, -2352, -4884 }, - { -7825, -3439, 1451, -1468 }, - { -8451, -3318, 2360, -435 }, - { -8462, -4130, 1438, -1024 }, - { -9425, -4564, 1328, -689 }, - { -11014, -3202, 2278, 2080 }, - { -8269, -2761, -146, -440 }, - { -7497, -2618, -166, 413 }, - { -8250, -3060, 522, -2133 }, - { -8365, -5366, 1347, -451 }, - { -8589, -3979, 2943, 714 }, - { -8111, -2572, 1272, -1748 }, - { -7830, -5193, 605, -1484 }, - { -8119, -4736, 2141, 256 }, - { -7724, -4769, 1463, -812 }, - { -7363, -3911, 2540, 4 }, - { -7974, -3397, 2363, 1366 }, - { -7359, -4204, 1752, -958 }, - { -7622, -3505, 660, 916 }, - { -9934, -3665, 3165, 828 }, - { -8721, -4162, 62, 1718 }, - { -9433, -4768, 2722, 1234 }, - { -7960, -4496, 138, 1528 }, - { -8198, -3454, -443, 631 }, - { -7756, -2246, 655, 1137 }, - { -8841, -3145, 1113, 829 }, - { -7817, -3298, 1251, 230 }, - { -9413, -2733, 323, -1862 }, - { -9408, -4168, 1270, 1549 }, - { -9037, -3892, -942, 283 }, - { -8255, -3849, 1301, 1762 }, - { -9057, -3987, -41, -682 }, - { -9441, -4187, 2019, -111 }, - { -9740, -3178, 1602, -871 }, - { -8344, -2474, 1461, 1506 }, - { -9752, -2925, 1996, 1243 }, - { -9199, -3796, 180, 537 }, - { -9060, -2405, 1140, -1562 }, - { -9348, -2376, 309, -162 }, - { -10786, -3182, -5, -1500 }, - { -8142, -4540, -434, -826 }, - { -7528, -2341, 1104, -73 }, - { -9360, -2658, 3062, 56 }, - { -8267, -2335, 2000, -1193 }, - { -12169, -3154, 1287, -640 }, - { -11398, -2120, 946, -1163 }, - { -8940, -4559, 328, -1696 }, - { -11025, -4213, 2813, 840 }, - { -9224, -3581, 2224, 2039 }, - { -8943, -3337, 1248, -1298 }, - { -7900, -4042, 485, -2080 }, - { -9221, -1947, 2191, -880 }, - { -10762, -1800, 2516, -324 }, - { -10095, -2238, 981, -1335 }, - { -11908, -2808, 3255, 645 }, - { -10640, -4105, 1283, -595 }, - { -7663, -2863, 2467, -797 }, - { -10712, -3854, 3710, 1538 }, - { -10823, -2893, 1408, -801 }, - { -9874, -3832, 256, -1638 }, - { -10394, -3391, 2315, -94 }, - { -11525, -4079, 4153, 2122 }, - { -9546, -2088, 1541, 481 }, - { -8731, -2433, 1042, 2160 }, - { -7852, -3977, -1370, 1677 }, - { 7072, -3420, 1398, -1741 }, - { 6180, -1976, 1280, -3557 }, - { 7692, -1793, 2844, -1700 }, - { 8363, -1773, 3104, -2679 }, - { 9213, -3266, 3756, -3542 }, - { 9650, -2644, 1426, -1318 }, - { 7712, -2796, 3686, -1975 }, - { 7316, -3517, 2821, -622 }, - { 7434, -2594, 2305, -2264 }, - { 7237, -1797, 255, -3114 }, - { 8663, -1983, 1338, -3056 }, - { 6616, -952, 4059, -2652 }, - { 8823, -1327, 1362, -1356 }, - { 9938, -1722, 1287, -2362 }, - { 7207, -1057, 1913, -1315 }, - { 7508, -1585, 870, -1982 }, - { 8217, -3680, 1417, -3170 }, - { 8329, -2541, 1684, -585 }, - { 8062, -2335, 252, -2800 }, - { 8204, -4108, 3097, -2569 }, - { 7701, -3367, 576, -3008 }, - { 7350, -786, 2414, -2129 }, - { 6948, -2568, 1607, -225 }, - { 7684, -2387, 1308, -3449 }, - { 8306, -3458, 2394, -1454 }, - { 8438, -2781, 1043, -1362 }, - { 9175, -2076, 2144, -1987 }, - { 8347, -2709, 3489, -4301 }, - { 5696, -2377, 2870, 851 }, - { 8825, -1243, 2219, -2603 }, - { 8801, -1614, 584, -2513 }, - { 8413, -384, 1421, -2244 }, - { 9228, -3050, 3279, -2164 }, - { 6342, -2698, 3547, -107 }, - { 10053, -2476, 2837, -3168 }, - { 7439, -604, 3177, -3991 }, - { 7749, -1064, 4329, -4855 }, - { 8655, -2177, 2252, -3519 }, - { 8490, -228, 1958, -3233 }, - { 10513, -2968, 1911, -2340 }, - { 8146, -862, 1884, -1723 }, - { 7788, -666, 3004, -2891 }, - { 7785, -1620, 4133, -3417 }, - { 10262, -3731, 3455, -2971 }, - { 8570, -905, 4519, -4649 }, - { 9129, -2562, 463, -2465 }, - { 9451, -3587, 1904, -3056 }, - { 6549, -2236, 3010, -4523 }, - { 7175, -2684, 2967, -3458 }, - { 9872, -3278, 1054, -2472 }, - { 9153, -931, 1217, -2565 }, - { 8789, -3469, 753, -2568 }, - { 6683, -3791, 1797, -3968 }, - { 6801, -1977, 2311, -452 }, - { 6336, -1572, 2612, -3264 }, - { 7996, -1008, 730, -2964 }, - { 7521, -1059, 1573, -3694 }, - { 8148, -3973, 2600, -3572 }, - { 7765, -1532, 2528, -3856 }, - { 7404, -3918, 4472, -143 }, - { 8894, -1398, 3299, -3685 }, - { 5768, -2041, 1487, -637 }, - { 5131, -2865, 2463, -811 }, - { 6439, -1568, 3500, -1550 }, - { -8878, -6798, -5319, -1452 }, - { -6332, -9713, -3112, -990 }, - { -8444, -6316, -3694, -687 }, - { -6123, -10840, -3637, -4358 }, - { -4784, -9580, -4577, -2581 }, - { -6108, -10515, -4859, -2524 }, - { -7605, -7518, -2327, -2797 }, - { -9662, -8775, -2467, -2010 }, - { -6494, -7523, -4715, -118 }, - { -8290, -8982, -1672, -317 }, - { -8798, -11051, -3888, -1426 }, - { -6273, -6623, -6791, -142 }, - { -8313, -7668, -2141, -1275 }, - { -6453, -8412, -3589, -4102 }, - { -6747, -7750, -5690, -2498 }, - { -7814, -6693, -3174, -2446 }, - { -10383, -10130, -3931, -2364 }, - { -10606, -8467, -5539, -2772 }, - { -9475, -6671, -3305, -2271 }, - { -8982, -9457, -5635, -4005 }, - { -10111, -7965, -6515, -4180 }, - { -7301, -6479, -5364, 720 }, - { -9543, -8999, -7921, -912 }, - { -9534, -8562, -3469, -384 }, - { -7601, -10344, -3205, -1127 }, - { -8088, -8620, -4954, -2888 }, - { -8202, -8406, -7038, -3775 }, - { -7312, -8324, -3334, -1775 }, - { -8566, -9262, -8071, -4174 }, - { -7068, -11300, -5573, -2907 }, - { -8295, -8952, -4366, -1544 }, - { -11104, -10210, -2285, -384 }, - { -5213, -7520, -5008, -1339 }, - { -5889, -7940, -5987, -1385 }, - { -10816, -8201, -4153, -1485 }, - { -10277, -8919, -6315, -1652 }, - { -5888, -10320, -3821, -1733 }, - { -10497, -7181, -6083, -3032 }, - { -7721, -9724, -6591, -5336 }, - { -5688, -7894, -3486, -2552 }, - { -10014, -10500, -3247, -820 }, - { -6301, -8765, -4506, -2923 }, - { -8261, -7847, -6213, -1552 }, - { -10212, -7481, -8113, -3954 }, - { -6938, -10874, -6074, -4703 }, - { -7183, -10968, -4446, -1773 }, - { -7120, -9193, -1966, -2509 }, - { -6234, -9263, -2313, -4284 }, - { -8503, -9857, -2429, -608 }, - { -9372, -7844, -8391, -2120 }, - { -7951, -7157, -6535, -11 }, - { -7256, -9473, -2172, -660 }, - { -10063, -9612, -2515, -15 }, - { -6684, -9134, -6109, -4206 }, - { -8204, -11932, -5220, -2306 }, - { -9710, -6706, -4115, -3275 }, - { -6855, -7078, -2409, -4447 }, - { -7344, -7673, -4479, -4116 }, - { -8851, -6842, -4927, -2948 }, - { -8927, -10452, -5633, -2194 }, - { -8627, -9002, -7176, -1575 }, - { -8209, -9722, -7021, -3324 }, - { -3770, -10249, -3623, -4816 }, - { -8183, -7465, -4090, 646 }, - { -8163, -7149, 200, 498 }, - { -8289, -6266, 686, -206 }, - { -10030, -6241, -1032, -1864 }, - { -8793, -8327, -773, -169 }, - { -9149, -6215, 969, -15 }, - { -8303, -5859, -7, 2006 }, - { -9682, -7283, 255, 1322 }, - { -9293, -7227, 71, -231 }, - { -8525, -6215, 287, -837 }, - { -10477, -5379, 1159, 1449 }, - { -10726, -7856, -130, 102 }, - { -8694, -7461, -1210, 690 }, - { -9367, -5324, 1103, 3170 }, - { -10686, -8055, -831, 1633 }, - { -9201, -6873, -2704, 2258 }, - { -8421, -5358, -1405, 226 }, - { -9066, -5830, -307, -1571 }, - { -11150, -7381, -2746, -900 }, - { -9978, -5925, -2006, -437 }, - { -9464, -4741, -273, 1061 }, - { -10543, -6684, -1113, 1660 }, - { -10073, -5576, 1083, -269 }, - { -8826, -5763, 1600, 1486 }, - { -10445, -9071, -1253, -64 }, - { -12085, -5799, 2, 769 }, - { -12939, -6663, 1650, 1437 }, - { -10932, -6434, -1252, -649 }, - { -11650, -7826, -2053, 710 }, - { -12122, -6733, -1889, -731 }, - { -9093, -6095, -2463, -842 }, - { -10977, -4364, 469, 420 }, - { -11488, -6908, -521, 893 }, - { -9669, -5478, -842, 337 }, - { -10606, -5203, -632, -1361 }, - { -10198, -6284, 1662, 1277 }, - { -10135, -5292, 2435, 3493 }, - { -11027, -6561, 655, 56 }, - { -10977, -5030, 1127, -358 }, - { -12766, -3986, 1348, -335 }, - { -14244, -7731, 264, 317 }, - { -15124, -10309, -508, 1447 }, - { -12821, -8638, -608, 137 }, - { -13076, -8693, -2852, -431 }, - { -11156, -5546, -2252, -1600 }, - { -8692, -7366, -819, -1223 }, - { -12507, -9816, -1714, -121 }, - { -10712, -6666, 544, 3349 }, - { -12462, -5890, -2491, -2318 }, - { -12468, -7226, 437, 232 }, - { -11300, -5226, 2068, 687 }, - { -11994, -8320, -626, 2728 }, - { -12222, -5476, 1142, 18 }, - { -10277, -8122, -2418, 2003 }, - { -13418, -6115, -3563, -2802 }, - { -14759, -9834, -1243, 21 }, - { -13699, -5665, 1525, 507 }, - { -16269, -9476, -701, 163 }, - { -12677, -5437, -247, -1019 }, - { -11827, -4295, -181, -1243 }, - { -12847, -4496, 2984, 1123 }, - { -13860, -7915, -1166, -547 }, - { -12276, -8145, -2290, -1527 }, - { -11417, -4830, 2983, 1854 }, - { -11793, -6002, 1163, 1940 }, - { 11443, -4920, -3235, 3151 }, - { 11300, -6616, -1506, 1175 }, - { 9198, -4628, -2060, 2390 }, - { 10532, -4027, -643, 912 }, - { 9902, -3573, -1606, 1327 }, - { 9653, -3536, -2240, 1869 }, - { 9948, -5171, -423, 2662 }, - { 12316, -4004, -1989, 281 }, - { 12125, -4800, -1265, -163 }, - { 10650, -2617, -2337, 1462 }, - { 9909, -4968, -2376, 916 }, - { 12944, -4647, -1958, 460 }, - { 12988, -5283, -1141, 41 }, - { 12321, -2915, -3621, 1025 }, - { 11449, -2894, -2728, 351 }, - { 12087, -3041, -2002, -32 }, - { 11558, -4031, -1343, -399 }, - { 12983, -3740, -3516, 1245 }, - { 12099, -2515, -2752, 225 }, - { 12515, -3465, -2701, 550 }, - { 14683, -5022, -5272, 2996 }, - { 12260, -3383, -1215, -528 }, - { 13810, -5422, -2443, 1166 }, - { 13421, -5378, -1886, 721 }, - { 12961, -4259, -2594, 796 }, - { 12266, -2104, -4768, 1591 }, - { 13523, -4710, -3045, 1342 }, - { 12437, -2099, -5610, 2117 }, - { 11850, -2183, -3497, 661 }, - { 12275, -3936, -597, -697 }, - { 12459, -5253, -517, -544 }, - { 12835, -4094, -1322, -168 }, - { 14360, -5677, -3305, 1859 }, - { 13905, -4552, -4309, 2117 }, - { 11559, -3412, -1847, -81 }, - { 13379, -3167, -5764, 2746 }, - { 11910, -1634, -4342, 1052 }, - { 12662, -4742, 71, -974 }, - { 13057, -3254, -4424, 1705 }, - { 15046, -5706, -4851, 3019 }, - { 14162, -4142, -5514, 2843 }, - { 12764, -1845, -6684, 2888 }, - { 13714, -2374, -7838, 3857 }, - { 13295, -1663, -8293, 4073 }, - { 10032, -4152, -3403, 1421 }, - { 10942, -5386, -2222, 950 }, - { 10532, -6385, -1750, 1925 }, - { 10273, -5972, -1534, 643 }, - { 10605, -4782, -1695, 27 }, - { 10988, -5153, -1123, -341 }, - { 11629, -5884, -1060, 48 }, - { 10441, -4045, -2431, 311 }, - { 10788, -3595, -4171, 1807 }, - { 12110, -5686, -2127, 976 }, - { 11746, -4773, -2639, 891 }, - { 11541, -5299, -3031, 1732 }, - { 11416, -2559, -5359, 2198 }, - { 11583, -5376, -704, 677 }, - { 10416, -3214, -3516, 872 }, - { 9651, -5435, -1618, 3255 }, - { 9973, -5133, -996, 3923 }, - { 11707, -4643, -430, -796 }, - { 10994, -2709, -3587, 2302 }, - { 10716, -5118, -645, 270 }, - { 14100, -10314, 1095, 1531 }, - { 12944, -8049, 1105, -741 }, - { 13276, -7035, -511, 274 }, - { 14008, -7254, -283, 139 }, - { 11594, -6536, -91, 1671 }, - { 11732, -8645, 746, 15 }, - { 14613, -7085, -1578, 1183 }, - { 13083, -6224, -750, -4 }, - { 13988, -6256, -1592, 820 }, - { 14678, -8683, 441, 126 }, - { 15571, -8872, -521, 1139 }, - { 15642, -9533, 341, 697 }, - { 15960, -9586, -168, 1121 }, - { 15464, -10239, 1433, -1 }, - { 14934, -7887, -1046, 1080 }, - { 15252, -7630, -1899, 1628 }, - { 15485, -8384, -1234, 1484 }, - { 15962, -8638, -1815, 1931 }, - { 16501, -10664, 398, 1167 }, - { 16146, -10145, 411, 918 }, - { 14573, -7475, -697, 601 }, - { 14302, -7996, 28, 257 }, - { 14769, -6792, -2286, 1574 }, - { 14144, -6137, -2169, 1257 }, - { 14770, -6271, -3111, 1933 }, - { 14110, -8312, 1083, -531 }, - { 15235, -6991, -2993, 2174 }, - { 13222, -5805, 547, -891 }, - { 14796, -8762, 1254, -246 }, - { 16040, -9181, -1005, 1551 }, - { 16487, -10086, -373, 1420 }, - { 15077, -9479, 966, 51 }, - { 13026, -6468, 932, -1080 }, - { 12703, -6152, -33, -573 }, - { 15641, -6810, -4128, 2874 }, - { 13282, -7673, 1583, -1283 }, - { 12373, -7150, 1512, -917 }, - { 12992, -7751, -678, 783 }, - { 10907, -6858, -313, 2597 }, - { 13026, -8963, 125, 2152 }, - { 12770, -9946, 1957, -505 }, - { 12482, -6849, -1268, 833 }, - { 13790, -6181, -138, -279 }, - { 12709, -8382, 2044, 227 }, - { 12244, -6630, 203, -457 }, - { 14209, -6816, -1032, 632 }, - { 15134, -8267, -288, 640 }, - { 13619, -6157, -1090, 356 }, - { 14044, -7413, 725, -484 }, - { 12958, -7753, 2585, -1980 }, - { 13188, -8396, 2306, -1558 }, - { 14379, -9980, 2132, -688 }, - { 14275, -9857, 1162, 179 }, - { 13690, -8648, 1621, -889 }, - { 11770, -6829, -746, 278 }, - { 12732, -8202, 286, 90 }, - { 13630, -10146, 1867, -207 }, - { 12072, -8740, 1299, -645 }, - { 12852, -9492, 1226, 62 }, - { 11792, -7382, -54, -116 }, - { 13779, -9014, 487, 351 }, - { 11951, -7729, 121, 834 }, - { 11970, -9781, 2276, -4 }, - { 12680, -7984, 2787, -787 }, - { 13300, -14488, 6408, -1927 }, - { 13635, -15355, 9153, -3073 }, - { 12804, -13566, 5517, -1625 }, - { 16624, -10854, 1690, 28 }, - { 20387, -18532, 6162, -261 }, - { 16515, -12642, 3392, -519 }, - { 15800, -11095, 2151, -202 }, - { 16824, -11790, 1651, 599 }, - { 17604, -13213, 2563, 538 }, - { 17892, -14177, 3562, 147 }, - { 16987, -11399, 869, 1052 }, - { 17003, -12456, 2442, 265 }, - { 21657, -21806, 9198, -1250 }, - { 16825, -13341, 3980, -686 }, - { 17525, -12714, 1887, 805 }, - { 16419, -11034, 1216, 617 }, - { 20931, -19939, 7469, -684 }, - { 18452, -15390, 4573, -191 }, - { 14778, -10077, 2841, -1209 }, - { 17402, -13319, 3042, 160 }, - { 19365, -17922, 7087, -1061 }, - { 16298, -11941, 2810, -351 }, - { 19087, -16176, 4775, -84 }, - { 17666, -12289, 938, 1224 }, - { 18581, -15894, 5132, -430 }, - { 19823, -16717, 4142, 545 }, - { 19960, -19423, 8400, -1492 }, - { 18973, -16817, 5906, -594 }, - { 19079, -15431, 3528, 503 }, - { 16667, -12485, 4467, -1302 }, - { 19791, -17797, 6196, -529 }, - { 20005, -17606, 5354, -20 }, - { 20123, -18599, 6886, -728 }, - { 19068, -14805, 2394, 1105 }, - { 14443, -13723, 5631, -2029 }, - { 14730, -14231, 5631, -1450 }, - { 16089, -15959, 7271, -2029 }, - { 13473, -11200, 3236, -924 }, - { 14413, -10902, 2347, -267 }, - { 17666, -18662, 11381, -3496 }, - { 14749, -11042, 3305, -275 }, - { 15304, -10486, 1869, -240 }, - { 14809, -12126, 3369, -616 }, - { 16896, -16561, 7307, -1845 }, - { 15782, -14336, 5380, -1264 }, - { 16395, -15520, 6415, -1588 }, - { 13681, -11114, 2584, -320 }, - { 14244, -12326, 4480, -1632 }, - { 15247, -13119, 4265, -898 }, - { 13987, -12091, 3469, -597 }, - { 13941, -12770, 4240, -839 }, - { 13771, -13627, 5252, -1384 }, - { 15010, -16074, 7592, -2249 }, - { 15852, -17226, 8619, -2655 }, - { 18921, -16916, 6875, -1501 }, - { 14909, -11678, 2768, -295 }, - { 18988, -18353, 8424, -2070 }, - { 15457, -15080, 6218, -1513 }, - { 14916, -15512, 6949, -1883 }, - { 18108, -14702, 4681, -701 }, - { 17600, -15733, 5616, -775 }, - { 14070, -13683, 6472, -2626 }, - { 13832, -11914, 5201, -2232 }, - { 18846, -19009, 9192, -1961 }, - { -11981, -10994, -6324, -2264 }, - { -10976, -9047, -6546, -3828 }, - { -11288, -10532, -7014, -4191 }, - { -10139, -10189, -7799, -2688 }, - { -10555, -9988, -9181, -2040 }, - { -11596, -11339, -10022, -2707 }, - { -13400, -13395, -11306, -4206 }, - { -9774, -12281, -7466, -4133 }, - { -10842, -13125, -8777, -4956 }, - { -11964, -15082, -9779, -5095 }, - { -9382, -10188, -9053, -4927 }, - { -11562, -11296, -3651, -985 }, - { -9287, -10083, -7918, -4069 }, - { -12821, -16556, -11410, -6195 }, - { -12628, -8959, -4521, -1113 }, - { -13845, -11581, -3649, -681 }, - { -12685, -10269, -5483, -1275 }, - { -14988, -12874, -5107, -1189 }, - { -13761, -11367, -6202, -1804 }, - { -13225, -11249, -7820, -3354 }, - { -14809, -11992, -3202, -312 }, - { -15620, -15519, -10210, -3433 }, - { -12954, -10200, -3139, -611 }, - { -11536, -9981, -5284, -923 }, - { -13034, -12417, -4612, -1098 }, - { -16911, -15505, -6123, -1352 }, - { -17396, -17685, -8330, -2171 }, - { -14120, -10764, -2265, -99 }, - { -12598, -7367, -5406, -3530 }, - { -14143, -12793, -10909, -5226 }, - { -14692, -16871, -11626, -5554 }, - { -12581, -11197, -9194, -3837 }, - { -16752, -16726, -9746, -2808 }, - { -10600, -10358, -6560, -1227 }, - { -14573, -13312, -8957, -3393 }, - { -10172, -8463, -8579, -3387 }, - { -11418, -12421, -5522, -1842 }, - { -11855, -14204, -6669, -2625 }, - { -13308, -8191, -3941, -2194 }, - { -10007, -12266, -5022, -1811 }, - { -13532, -15771, -9497, -3175 }, - { -11760, -11148, -10339, -5529 }, - { -12149, -12763, -11198, -3697 }, - { -12029, -12119, -8555, -1792 }, - { -16995, -19957, -11447, -3471 }, - { -13144, -14504, -9988, -3191 }, - { -9938, -11064, -6139, -3162 }, - { -8873, -11550, -8294, -6550 }, - { -9303, -13010, -6150, -2711 }, - { -15463, -10469, -1766, -170 }, - { -15985, -11693, -3007, -650 }, - { -17142, -10671, -1434, 47 }, - { -16063, -13858, -4817, -1058 }, - { -19446, -19599, -9594, -2464 }, - { -20076, -18744, -8313, -1889 }, - { -15047, -16085, -7590, -2250 }, - { -13481, -16195, -8552, -2998 }, - { -13829, -14869, -6704, -1932 }, - { -16357, -18484, -9802, -2959 }, - { -10551, -8393, -9303, -5070 }, - { -11345, -9156, -5641, -3107 }, - { -13217, -13449, -9270, -4541 }, - { -11988, -13732, -9995, -6374 }, - { -11007, -9519, -5168, -4107 }, - { 9930, -7858, 8061, -4375 }, - { 8274, -7867, 5992, -2096 }, - { 9692, -9675, 7621, -3670 }, - { 9589, -8110, 6509, -3010 }, - { 12617, -11976, 10122, -5360 }, - { 11867, -8895, 7948, -5323 }, - { 10388, -10482, 9234, -4324 }, - { 8188, -8220, 7810, -2737 }, - { 10407, -8787, 4806, -1930 }, - { 10348, -8845, 9233, -6614 }, - { 9422, -7091, 4820, -2878 }, - { 9758, -9796, 5584, -2256 }, - { 10188, -7994, 5347, -3343 }, - { 11133, -7455, 4015, -2306 }, - { 10676, -10744, 6093, -2629 }, - { 11522, -12184, 7848, -3375 }, - { 8805, -9883, 5317, -3071 }, - { 9498, -9654, 6555, -3592 }, - { 10488, -8008, 4066, -1252 }, - { 11261, -8930, 6068, -2738 }, - { 12180, -10397, 5027, -1531 }, - { 9138, -8531, 3601, -1959 }, - { 8107, -8380, 4970, -2061 }, - { 9737, -13248, 6438, -2617 }, - { 11178, -10423, 2622, -522 }, - { 9572, -12372, 5199, -2019 }, - { 12057, -12144, 4147, -1099 }, - { 9047, -9925, 2516, -665 }, - { 10790, -8030, 5882, -4386 }, - { 7199, -8426, 6337, -2841 }, - { 7778, -8285, 3529, -3442 }, - { 7559, -10569, 3484, -1332 }, - { 9404, -8115, 7484, -5541 }, - { 7792, -11976, 5546, -2573 }, - { 9313, -10264, 7661, -5195 }, - { 6701, -10725, 4370, -1784 }, - { 4918, -11361, 4507, -4527 }, - { 5147, -12305, 3978, -5556 }, - { 6525, -9899, 4481, -3129 }, - { 7538, -12855, 6060, -4826 }, - { 8659, -12111, 7159, -4430 }, - { 8440, -11304, 4547, -1747 }, - { 9216, -10918, 3507, -1195 }, - { 6165, -9254, 4771, -4677 }, - { 9163, -11019, 5637, -4935 }, - { 13441, -11509, 6676, -2434 }, - { 7912, -9398, 6663, -4048 }, - { 11723, -13745, 8131, -4148 }, - { 6065, -10257, 5005, -6327 }, - { 11618, -12417, 5336, -1894 }, - { 8891, -13924, 8407, -6131 }, - { 9622, -12563, 7908, -5109 }, - { 11479, -10315, 8349, -3991 }, - { 11676, -14103, 6611, -2330 }, - { 11951, -8953, 3829, -1550 }, - { 10486, -8044, 10493, -5920 }, - { 11801, -10769, 9763, -5305 }, - { 6109, -8676, 5827, -1346 }, - { 7030, -9611, 5624, -5761 }, - { 12808, -12886, 8683, -4148 }, - { 13213, -10464, 6381, -3189 }, - { 11796, -13681, 10703, -6075 }, - { 9639, -7949, 9625, -3944 }, - { 8538, -6997, 5309, 453 } -}; - -/* quantization tables */ - -static const uint32_t scale_factor_quant6[64] = { - 1, 2, 2, 3, 3, 4, 6, 7, - 10, 12, 16, 20, 26, 34, 44, 56, - 72, 93, 120, 155, 200, 257, 331, 427, - 550, 708, 912, 1175, 1514, 1950, 2512, 3236, - 4169, 5370, 6918, 8913, 11482, 14791, 19055, 24547, - 31623, 40738, 52481, 67608, 87096, 112202, 144544, 186209, - 239883, 309030, 398107, 512861, 660693, 851138, 1096478, 1412538, - 1819701, 2344229, 3019952, 3890451, 5011872, 6456542, 8317638, 0 -}; - -static const uint32_t scale_factor_quant7[128] = { - 1, 1, 2, 2, 2, 2, 3, 3, - 3, 4, 4, 5, 6, 7, 7, 8, - 10, 11, 12, 14, 16, 18, 20, 23, - 26, 30, 34, 38, 44, 50, 56, 64, - 72, 82, 93, 106, 120, 136, 155, 176, - 200, 226, 257, 292, 331, 376, 427, 484, - 550, 624, 708, 804, 912, 1035, 1175, 1334, - 1514, 1718, 1950, 2213, 2512, 2851, 3236, 3673, - 4169, 4732, 5370, 6095, 6918, 7852, 8913, 10116, - 11482, 13032, 14791, 16788, 19055, 21627, 24547, 27861, - 31623, 35892, 40738, 46238, 52481, 59566, 67608, 76736, - 87096, 98855, 112202, 127350, 144544, 164059, 186209, 211349, - 239883, 272270, 309030, 350752, 398107, 451856, 512861, 582103, - 660693, 749894, 851138, 966051, 1096478, 1244515, 1412538, 1603245, - 1819701, 2065380, 2344229, 2660725, 3019952, 3427678, 3890451, 4415704, - 5011872, 5688529, 6456542, 7328245, 8317638, 0, 0, 0 -}; - -/* 20bits unsigned fractional binary codes */ -static const uint32_t lossy_quant[32] = { - 0, 6710886, 4194304, 3355443, 2474639, 2097152, 1761608, 1426063, - 796918, 461373, 251658, 146801, 79692, 46137, 27263, 16777, - 10486, 5872, 3355, 1887, 1258, 713, 336, 168, - 84, 42, 21, 0, 0, 0, 0, 0 -}; - -static const float lossy_quant_d[32] = { - 0, 1.6, 1.0, 0.8, 0.59, 0.50, 0.42, 0.34, - 0.19, 0.11, 0.06, 0.035, 0.019, 0.011, 0.0065, 0.0040, - 0.0025, 0.0014, 0.0008, 0.00045, 0.00030, 0.00017, 0.00008, 0.00004, - 0.00002, 0.00001, 0.000005, 0, 0, 0, 0, 0 -}; - -/* 20bits unsigned fractional binary codes */ -static const uint32_t lossless_quant[32] = { - 0, 4194304, 2097152, 1384120, 1048576, 696254, 524288, 348127, - 262144, 131072, 65431, 33026, 16450, 8208, 4100, 2049, - 1024, 512, 256, 128, 64, 32, 16, 8, - 4, 2, 1, 0, 0, 0, 0, 0 -}; - -static const float lossless_quant_d[32] = { - 0, 1.0, 0.5, 0.33, 0.25, 0.166, 0.125, - 0.083, 0.0625, 0.03125, 0.0156, 7.874E-3, 3.922E-3, 1.957E-3, - 9.775E-4, 4.885E-4, 2.442E-4, 1.221E-4, 6.104E-5, 3.052E-5, 1.526E-5, - 7.629E-6, 3.815E-6, 1.907E-6, 9.537E-7, 4.768E-7, 2.384E-7, 0, - 0, 0, 0, 0 -}; - - -/* Vector quantization tables */ - -static const int8_t high_freq_vq[1024][32] = -{ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { -4, -2, 2, 1, -16, -10, 1, 3, 1, 0, 6, 1, -3, 7, 1, -22, - 2, -4, -3, 11, 14, 6, -1, 1, -13, 29, -28, 10, 10, -8, 0, -9 }, - { -8, 8, -7, 10, -3, -12, -5, -8, 1, -2, 9, -2, -5, -18, 1, 9, - -8, -8, 3, 41, 7, -9, -9, 22, -42, -29, 14, -18, -14, -32, 1, -15 }, - { -16, 8, 15, 16, -16, 5, 2, 7, -6, -16, -7, 1, 1, -3, -2, 0, - 8, 20, -26, -11, 2, -17, 0, -3, -34, -37, 10, 44, -2, 22, 2, -4 }, - { 7, 14, 5, 6, 15, -1, 3, -3, -9, -23, -5, -14, 8, -1, -14, -6, - -5, -8, 54, 31, -6, 18, 2, -19, -2, -11, -30, -6, -19, 2, -2, -14 }, - { 1, 2, -2, -1, -3, -3, 1, -5, 1, -3, -4, -8, 5, -4, 0, 1, - 3, 7, -5, -4, -3, -12, 3, -2, -3, 12, -53, -51, 6, -1, 6, 8 }, - { 0, -1, 5, 1, -6, -8, 7, 5, -18, -4, -1, 1, 0, -3, -3, -14, - -1, -6, 0, -14, -1, -1, 5, -3, -11, 1, -20, 10, 2, 19, -2, -2 }, - { 2, 4, 3, 0, 5, 0, 3, 1, -2, 0, -6, -3, -4, -5, -3, -3, - -7, 0, -34, 4, -43, 17, 0, -53, -13, -7, 24, 14, 5, -18, 9, -20 }, - { 1, 0, -3, 2, 3, -5, -2, 7, -21, 5, -25, 23, 11, -28, 2, 1, - -11, 9, 13, -6, -12, 5, 7, 2, 4, -11, -6, -1, 8, 0, 1, -2 }, - { 2, -4, -6, -4, 0, -5, -29, 13, -6, -22, -3, -43, 12, -41, 5, 24, - 18, -9, -36, -6, 4, -7, -4, 13, 4, -15, -1, -5, 1, 2, -5, 4 }, - { 0, -1, 13, -6, -5, 1, 0, -3, 1, -5, 19, -22, 31, -27, 4, -15, - -6, 15, 9, -13, 1, -9, 10, -17, 4, -1, -1, 4, 2, 0, -3, -5 }, - { -7, 3, -8, 13, 19, -12, 8, -19, -3, -2, -24, 31, 14, 0, 7, -13, - -18, 0, 3, 6, 13, -2, 1, -12, -21, 9, -2, 30, 21, -14, 2, -14 }, - { -3, -7, 8, -1, -2, -9, 6, 1, -7, 7, 13, 3, -1, -10, 30, 4, - -10, 12, 5, 6, -13, -7, -4, -2, -2, 7, -3, -6, 3, 4, 1, 2 }, - { -8, 9, 2, -3, -5, 2, 0, 9, 3, 7, -4, -16, -13, 3, 23, -27, - 18, 46, -38, 6, 4, 43, -1, 0, 8, -7, -4, -1, 11, -7, 6, -3 }, - { 1, 1, 18, -8, -6, 0, 3, 4, 22, -3, -4, -2, -4, -11, 40, -7, - -3, -13, -14, -7, -10, 14, 7, 5, -14, 11, -5, 7, 21, -2, 9, -3 }, - { 0, 0, -2, 4, -2, 0, 2, 0, -1, 2, -1, 0, 0, 2, 2, 2, - -1, 1, -3, -1, -15, -2, -63, -27, -21, -47, -14, 1, -14, 10, 0, 2 }, - { 1, 0, -4, 0, -3, -9, 4, 2, 6, -6, 0, -5, 11, -7, -15, 6, - -7, -6, 3, 7, -15, -5, 23, -13, -6, 12, -8, 9, 2, -3, 3, 4 }, - { 6, 0, 3, 0, -2, -4, 2, 1, 1, -1, 1, -2, -1, -4, -22, -15, - -46, -66, 10, 20, 2, -17, 12, -6, 1, -2, -2, 0, 1, -5, 1, 2 }, - { -1, 0, 0, 1, 0, -4, 0, 1, -10, -3, -8, 5, 7, -11, 2, -11, - 29, -25, 11, 10, 0, -1, 5, -7, -2, -5, -2, 4, 4, -3, 5, -2 }, - { 1, -1, -1, -3, -2, 1, -8, -3, 2, -2, 4, -5, -1, -7, -2, 1, - -14, -7, 3, -30, -15, -14, 3, -4, -1, 3, -13, -1, -3, 1, 2, 3 }, - { -1, -2, -3, 2, 2, -3, 3, 1, -3, 2, 0, -4, 6, 5, -5, 10, - -57, 3, 22, -50, 1, -2, -5, -6, -1, 5, 1, 2, 2, 1, -2, 2 }, - { 2, 0, -1, -7, 2, 1, 3, 2, 0, 4, 3, -2, 3, -3, 4, -4, - 24, -35, -3, 38, -6, -5, 15, 20, 3, 16, -7, -5, 0, -4, -5, 0 }, - { 0, 1, 0, 0, 0, -1, -1, 1, 1, -1, 1, -2, 0, 0, 0, 0, - 0, -1, -2, -1, -5, -2, -43, -3, 46, -52, -10, 7, -8, 11, -2, -1 }, - { 0, 0, -1, 0, -1, 2, -41, 33, -44, -48, -15, -26, -9, 6, 3, 3, - -3, 2, 2, 2, 2, -1, -1, -2, 1, 3, 0, 0, 5, 2, 3, 1 }, - { -4, 1, 6, 1, -6, -1, -2, 1, -14, -4, 0, -5, -2, 2, -2, 0, - -6, 1, 0, 8, -21, 32, -3, -36, -6, -2, -1, -7, 3, 0, 1, -6 }, - { -3, -2, 3, 0, 2, 2, 8, -4, -4, 6, 2, 1, 3, -6, 4, 3, - 13, 0, -12, -1, 25, -20, -2, -23, -15, 7, -3, -11, -3, 6, -1, 0 }, - { 0, 0, -3, -1, 0, 0, -2, -1, -2, -2, 1, -1, 0, 0, 10, 3, - -2, 3, 3, -7, -6, -5, 0, -4, -60, -16, -6, 38, 5, 6, -5, 0 }, - { 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 0, 0, 1, - 0, 0, -1, 0, -8, 2, -9, 10, 40, 31, -56, -21, 4, 20, -4, 7 }, - { -2, -2, 0, 4, -3, -1, 7, 3, 1, 3, -8, 0, 3, 1, 2, 5, - 1, -2, 14, 5, 4, 5, 5, 5, -5, 9, -66, 0, -20, -2, -8, 4 }, - { -2, -1, 4, -1, -8, -2, -4, -1, -3, -3, 2, -7, -3, 5, 7, -2, - 45, 31, -17, -16, -2, -2, -1, -22, 1, -1, -3, 3, 5, -3, 5, -1 }, - { -4, 0, 7, 5, 8, 7, 2, 9, -9, -9, -7, -11, -3, -8, 17, -4, - 34, 32, 18, 22, 1, 2, 1, -7, -5, 6, -1, 6, 4, 10, -2, -7 }, - { 6, 0, 14, 9, 6, -1, -2, -3, 4, -6, -8, 4, 7, -1, 28, 38, - 15, -1, 16, -11, 5, 8, 4, -10, 3, -10, -17, 5, 3, 3, 3, 1 }, - { 1, 1, 2, -1, 2, 1, 0, 0, -1, 0, 0, -2, 1, -3, 0, 1, - 2, -2, -4, -2, 0, -1, 1, -3, 1, 1, 1, -1, 8, 8, 66, 33 }, - { -5, 2, -3, -7, 2, -8, -4, 10, 17, -18, -7, 4, -4, -7, -6, -6, - -5, 5, -12, 2, 0, 6, 8, -2, 1, 4, -11, 2, 1, 8, 31, 19 }, - { 6, 9, 16, -6, -6, -1, -2, -3, -11, -2, 7, 7, 17, 3, 4, 10, - 2, 5, -13, 8, 7, 1, 4, 5, 7, 6, 7, -8, 9, -8, 33, 6 }, - { 3, -1, 1, 0, -7, -5, 0, 14, -7, 1, -7, 1, 2, -4, 7, 10, - -16, 12, 1, -6, 3, 8, -1, 10, -13, -6, -12, -23, 12, -3, 30, 14 }, - { -2, -15, 0, 8, 3, -19, 5, -3, 2, 3, 13, 7, 14, -3, -10, 0, - 8, 5, -6, -16, -8, -8, 14, 2, -1, 1, -9, -11, 11, -5, 27, 9 }, - { -8, 6, -4, 4, -4, -1, 5, 4, 1, -7, -5, -4, -15, 1, 9, 0, - 8, 4, 1, -17, 11, -2, -19, -1, -6, -8, 3, -12, 3, -17, 33, -10 }, - { -3, -1, 2, 7, 7, -2, 9, 8, -18, -1, -13, -10, -3, -3, 11, 8, - -2, -12, -8, 1, 4, 9, 14, 10, -3, 0, 2, 1, -2, 3, 31, 10 }, - { -3, -10, 8, -1, -5, -11, 7, -5, 3, 6, 1, 4, -16, 10, 5, -4, - -2, -10, -1, 13, 6, -5, -7, 12, 7, -3, -17, 1, 12, -4, 29, 8 }, - { 1, 2, 5, 2, -6, -7, 0, -1, 6, -1, 10, 6, -4, 5, 2, 2, - -2, -8, -6, -11, 14, -13, 27, 3, -2, -12, 5, -16, 2, -26, 20, 15 }, - { -1, -3, -5, -3, -3, 6, -1, 3, -5, 1, 7, 2, 1, 0, -1, -1, - 0, -1, 9, 7, -6, -3, 4, -5, -4, 8, -8, -25, -8, -4, 34, 23 }, - { -1, -2, 1, 1, -1, -2, -1, 1, -1, 0, 0, 0, 0, -2, -1, 1, - 0, 2, 1, -1, 4, 0, 0, 1, -1, 0, 5, 3, 12, -9, 68, -16 }, - { 10, 0, -8, 14, -6, 1, -12, 0, 0, -3, -5, -11, -6, 12, 9, -10, - -3, 5, 0, 7, 11, 2, 4, -3, -8, -3, 7, 4, 3, -3, 34, 4 }, - { -12, 13, -5, 7, -11, -2, -1, 1, -4, -14, -21, 3, -3, -3, -4, -7, - -9, -4, 3, -17, -2, -13, 10, -2, 12, -4, 0, -9, 1, -5, 31, 10 }, - { -10, 6, 5, 6, 4, -7, 10, 0, -28, -3, 0, -11, -1, -5, 16, -10, - -16, 7, 20, 2, -4, 2, -5, 0, 15, 6, 5, -10, 7, -9, 20, 4 }, - { 1, -7, -2, -7, 4, -3, -2, -7, -1, -14, 6, -16, 4, -5, -4, -6, - -5, 0, -2, 2, -6, 9, -5, 4, -18, 8, -10, 8, 15, 0, 32, 1 }, - { -5, 7, -3, 7, 15, -4, 0, -16, 9, 5, -5, 5, 4, -3, -12, -9, - -18, 10, 2, 2, -3, 7, 3, -1, 6, -9, -10, 3, 15, -4, 35, -7 }, - { -1, -10, 2, 2, -4, -2, 10, 2, -1, 2, -2, 1, -1, -14, -11, 3, - -8, 5, -8, -2, 6, -1, -7, 1, 7, 5, 7, 8, 30, -4, 30, 14 }, - { 2, -2, 1, 2, 3, -8, 3, 0, -2, 0, -9, 2, 1, 4, -6, -1, - -2, 5, 0, 1, -2, 12, 6, -3, 9, -3, 4, -12, 21, -39, 24, -2 }, - { 3, 5, 1, -2, -2, -2, -3, 6, -8, -2, -11, -8, -1, 4, 2, 2, - -4, -10, 12, -5, -11, 1, -15, -34, -11, -7, -11, -1, 7, -14, 38, -1 }, - { -4, 4, 8, 9, 8, 1, -5, -9, 4, -2, 15, -4, 11, -15, 20, -1, - -1, -3, 4, -9, -2, -2, -2, 8, 6, 12, -5, 0, 11, -12, 27, -4 }, - { 0, 8, -4, 3, -11, 6, -11, 2, 3, 0, 5, -8, -7, -6, -9, -21, - 4, -11, -1, -16, -7, 16, -3, 7, -7, 4, -5, 0, 11, -7, 31, 3 }, - { 1, 3, 4, 11, -11, -2, -3, -6, 6, 5, 0, 3, -9, -6, 4, -4, - 0, 4, -8, 13, -6, -13, -1, -5, -1, 4, 0, 0, 9, -22, 24, 18 }, - { -7, 3, 10, -13, -6, 6, -6, 6, 22, 1, 0, -14, 2, 3, 7, -1, - 8, 20, -1, 5, -4, 13, 9, -9, -9, 6, 0, -4, 0, -8, 31, -4 }, - { -3, -4, 0, 1, 7, 3, -7, 0, 5, -2, 1, 3, 3, 1, -5, -2, - 5, 2, -11, 4, 0, -1, 12, 0, -3, -13, 15, 8, -6, -27, 34, 0 }, - { -3, -3, 10, -4, 2, -1, -3, 0, -1, -1, -4, 2, 6, -2, 12, 1, - 3, -6, -7, -6, -5, 4, -19, -6, -8, -34, -4, -8, 10, -7, 23, 10 }, - { -7, 0, -1, -6, 8, 4, -4, 2, -5, -8, -7, -9, -8, 5, 9, 7, - -6, 1, -12, -12, -1, -16, 5, 0, 16, 3, -7, -8, 27, -4, 23, 15 }, - { -8, 4, 8, 5, 6, 11, -3, 5, 3, -1, -11, 6, -5, 0, 2, -6, - -3, -6, 4, -1, 5, -5, -12, -6, 7, -5, 9, 3, 6, -7, 29, 1 }, - { 1, 3, -2, -2, -6, -2, 1, 6, -6, -3, 1, 2, 3, 4, 1, 5, - -1, 0, 4, 2, 11, 6, 2, -3, 13, -9, -19, 18, -15, -10, 36, 21 }, - { -3, -3, 2, -1, -7, 6, -4, 1, -3, -1, -2, 2, 3, -7, -3, 0, - -2, 0, -2, 6, -19, 3, -8, 2, -6, 7, -1, 0, 29, -6, 28, -10 }, - { -5, 1, -3, -7, -12, -4, 1, 1, -1, 13, -10, -1, -9, -5, -13, 6, - 13, 3, -4, 2, 3, 11, 2, 6, -25, -16, -6, 0, 14, -1, 27, 16 }, - { -6, -1, -7, -5, -2, -5, -5, -1, 9, 1, 0, 3, -8, -12, -6, 5, - -6, 5, 3, -9, 1, 4, -7, -10, -9, -7, -17, -5, -15, -23, 25, 3 }, - { -8, -2, 9, -3, -4, 3, -1, 8, -7, -7, -5, -4, -2, 9, 4, -1, - -7, -4, -5, -16, 3, -6, 18, -13, -9, 16, -15, 8, 15, -10, 24, 5 }, - { 1, -38, 2, 34, 9, 10, 11, 2, 2, -6, 3, 2, -2, 5, 4, -7, - -1, 1, 4, 0, 3, 1, -8, -1, -6, 5, 4, 2, -4, 5, 2, -1 }, - { 1, -22, 15, 18, -2, 10, -16, -9, -8, -11, 8, 4, 0, 7, -14, -5, - -1, -7, 12, 17, 9, 5, -7, -4, -12, -6, 7, 0, 7, 2, -2, 1 }, - { -11, -29, 7, 10, 19, -1, -8, -9, 7, 1, 9, 6, 8, -7, -14, 8, - -3, -11, -13, 0, -7, -23, -2, -8, 12, 9, 2, 14, 19, 1, -1, 5 }, - { -24, -27, -11, 36, 2, 6, -3, 4, -6, 8, 0, 12, -1, -4, -6, 3, - 4, -1, 2, -3, -2, 3, 2, -1, -2, -4, 0, -1, -2, 7, 2, 3 }, - { -9, -24, 11, 13, -10, -12, 12, -2, 7, 4, 8, 13, -3, -3, 2, 9, - -3, -4, 4, 13, 5, 13, -6, -3, 1, 15, 7, -3, 0, 19, -2, -9 }, - { -8, -15, 7, 14, -4, -5, 2, -18, -19, -2, 2, 17, 16, 6, -10, 10, - -9, 14, -1, -5, -1, -6, -7, 2, 9, 11, 13, 6, -5, -12, 3, 2 }, - { -10, -37, 13, 1, 3, -14, 0, -20, 4, -3, 8, 2, -2, -3, -9, -5, - -3, -17, -1, 13, -11, 2, -6, 4, 4, 0, 3, 1, -9, -4, -5, -4 }, - { -2, -22, -5, 46, -8, 5, 9, -11, 8, 7, 7, -1, -1, -2, -7, 2, - -3, 3, -1, -2, 7, 0, 2, -1, 1, -2, -2, -3, 6, 0, -4, -6 }, - { -16, -27, 15, 16, -4, 14, -7, -26, 2, -2, 6, 5, -3, 11, 0, 2, - 3, 9, -7, -1, 2, -4, -4, -1, 6, 10, 1, 1, -3, -2, 3, 0 }, - { -3, -22, 10, 26, 1, 2, -3, 3, 17, -3, -7, 9, 1, -21, -4, 5, - 3, 0, -7, -6, 3, 3, -8, -7, -9, 3, 7, 1, -8, 12, 6, -7 }, - { -9, -25, 3, 18, 9, -6, -11, 0, -5, -12, 9, -8, -7, -6, -6, 22, - 2, -6, -3, 15, 3, 2, -2, 9, 14, -10, -7, 15, 13, 6, -2, 11 }, - { 5, -20, -5, 28, 11, 10, -4, -4, 0, -7, 3, 5, 2, -5, -8, 2, - 6, 10, 9, -9, -18, 3, 14, 1, 3, -3, -1, -6, 7, 7, 2, -1 }, - { -8, -30, 7, 12, 10, 8, 7, -13, -16, 0, 1, -1, -6, -11, -15, 4, - 1, -2, 10, -15, 1, 11, -2, 8, 9, -7, -7, 9, -5, 2, 7, -18 }, - { -10, -32, 10, 11, 3, -1, 3, -5, 5, 2, 14, -6, 3, 1, 5, -15, - -11, 6, 20, 4, 0, -12, -7, 3, 1, -1, 10, 6, -1, -9, -4, -1 }, - { 1, -25, -14, 12, -11, 9, 9, -16, -24, -17, 22, -9, 11, -30, -3, -4, - 6, -7, 9, 2, -1, -5, -6, 2, -1, -1, 10, 1, -3, 3, 4, 8 }, - { -14, -26, -6, 9, 8, 17, -11, -24, -7, -4, -8, -2, 10, 2, 2, -1, - 2, 13, 12, -7, 4, -6, -10, 6, 6, -13, -11, -7, -16, 0, -2, 5 }, - { -4, -30, -13, 12, 16, -6, 12, -16, -13, 5, 15, -2, -2, -10, -7, 7, - 11, -1, -4, -2, -4, 7, 4, -8, 1, 3, 0, 11, 3, -2, -5, 4 }, - { -4, -21, 20, 22, 2, 20, -8, 1, -12, -5, -9, 4, -10, -17, -3, -8, - -3, 3, -12, 1, -3, 0, 7, 4, 7, 7, -3, 7, 5, 3, 1, -5 }, - { -12, -20, 2, 29, 11, -6, 9, -7, -6, -4, 0, 6, 17, -13, -2, -10, - -17, -1, -18, 2, 0, 14, -6, 1, 0, 3, 2, -10, 1, -5, -2, 5 }, - { 16, -37, -1, 26, -2, -14, 1, -5, -14, 2, 2, 3, 6, 1, 1, 4, - 0, -1, 0, -2, -2, 4, 9, -6, 0, -2, 10, -7, -2, 4, 1, 0 }, - { -9, -24, -12, 5, 5, 3, -17, -14, 4, 3, 2, -4, 10, -22, -8, -3, - 6, 1, 12, -8, 4, 1, 9, -1, 18, -3, 6, 5, 3, -5, 9, -5 }, - { -14, -33, -2, 20, -13, -10, 2, -7, -1, 11, -9, -8, 18, -3, 1, 8, - 0, -2, 10, 7, -2, -13, 9, -3, -4, 5, -2, -2, -1, -5, 1, -7 }, - { -10, -23, 8, 14, 1, 7, 1, -3, -7, 4, 1, 1, 8, -7, 15, -14, - 13, 14, 2, 5, -13, -5, -8, -1, 6, 3, 6, 9, 6, 15, 14, 5 }, - { -13, -25, -10, 13, -17, -24, -7, -13, -6, -10, -8, 2, 0, -13, -10, -4, - -8, 4, -9, 9, -4, 4, -3, -3, 3, 3, -5, -9, 1, -2, 11, 2 }, - { -12, -23, 1, 18, -11, -2, 5, 9, -5, 5, 14, -9, -3, -2, -6, 2, - -2, 11, -13, 1, -3, 11, -9, -4, -2, -6, 8, 10, 1, 4, 2, 1 }, - { -5, -18, 16, 22, 2, 0, 8, -6, -9, -7, 10, -16, 23, 10, -11, -1, - 7, 2, 7, 2, 1, -5, 6, 1, 0, -4, 9, 2, -3, 1, 0, -4 }, - { -3, -26, 14, 11, 2, -9, 17, -2, -1, -5, -16, -9, -5, 10, -13, 1, - 6, 12, 10, 11, 0, 0, -3, -14, 6, -2, 0, 4, -5, -1, -7, -1 }, - { -10, -33, 1, 8, 11, -5, 1, -6, 7, 4, 5, 6, 1, -2, -10, -5, - -6, 12, -11, 5, -10, 4, 12, -1, -1, -3, 4, -1, 9, 0, 16, -17 }, - { -14, -37, 7, 7, -2, 5, -8, -11, 2, -13, 4, -19, 1, 8, 8, 4, - -9, 2, -4, 3, 12, 2, 4, -4, -8, 8, 1, 4, 8, -1, 6, -2 }, - { -6, -30, 18, 17, 1, -22, -3, 4, -7, -10, 7, 0, -8, 8, -1, 4, - 2, 8, 6, -2, 2, 7, 4, 4, 3, -6, 2, 1, -3, 1, -1, -5 }, - { -17, -18, -3, 22, -8, 1, 9, -2, -17, 20, -5, -5, -12, -5, 4, -5, - -9, 8, -2, 16, -3, 0, 19, -8, 8, 1, 2, -4, 0, 11, 0, -3 }, - { -9, -23, 3, 10, 4, 4, -3, -2, -2, -2, 1, -22, 11, 0, -2, 5, - -2, 14, -9, -11, -4, 7, 5, 32, 1, -3, -7, 0, 21, -9, 7, -6 }, - { 0, 0, 0, 2, -1, 1, 0, 1, 3, 0, 0, 1, 0, 1, 0, 1, - -3, 0, -1, -2, 0, -1, -1, -3, -1, 1, -4, 1, -1, -5, -69, -19 }, - { -3, -5, -8, -12, 4, -3, -19, -11, -5, 0, -14, 7, 18, -6, 7, 22, - 8, 14, 15, 10, 3, -1, -3, 5, -1, 7, -7, 1, -6, 3, -26, -11 }, - { -1, -6, 4, -4, -5, -16, 0, -6, -3, 11, 1, 0, 9, 5, 16, 3, - -4, -33, -4, 4, -7, 0, 1, 6, -11, -2, -13, -2, -18, 20, -25, -16 }, - { 4, 0, -1, 0, -5, 1, 0, 2, 0, 11, -10, 4, -10, 7, 16, 2, - 16, 15, 2, -1, 2, 9, 2, 8, -3, -5, -2, 0, -3, 0, -33, -2 }, - { -3, -15, 10, 10, -9, -1, 7, 3, 5, -5, -8, -8, -3, 15, -9, 4, - 12, 13, -13, -14, 10, -6, 9, 22, -27, 23, -1, 5, -24, 2, -30, 5 }, - { 0, -2, 7, -5, -5, 3, 5, 3, -3, -5, 2, 1, -4, 3, -3, -1, - 1, -2, 10, 22, -3, -4, -2, -2, -7, 3, 8, 1, 14, 4, -37, 9 }, - { -3, -4, -1, 1, -4, 0, 6, 2, 6, -7, -10, -10, -1, -4, 11, -3, - 7, -6, 4, -12, -1, 5, 1, -7, 10, -6, 17, -4, 8, 3, -40, 13 }, - { 2, 12, 4, -7, 14, -3, 16, -2, 18, 2, 13, 5, 5, 1, 11, -1, - 0, 9, 2, -6, -1, 2, -6, 2, -5, 3, 5, 1, -1, 1, -32, -7 }, - { -16, 11, 7, -4, 2, -5, -9, 9, 11, 11, 15, -13, -11, 11, 9, 4, - 3, -8, -10, 12, 12, 0, 0, -16, -9, 13, 2, 9, 4, -13, -33, 3 }, - { 6, 4, 5, 4, 3, -1, 5, 6, 4, 2, -11, -1, -15, -11, -1, 1, - 11, -3, -2, 24, -4, -6, -25, -10, -15, -8, 0, 0, -5, 4, -30, 2 }, - { 10, -3, -6, 1, -9, -5, 6, 9, -10, -3, 8, -1, 4, -1, 11, -11, - 3, 9, 11, -3, 6, -17, 5, -8, -33, 9, -13, 19, -2, 9, -25, 2 }, - { 0, 0, -1, -3, 0, -2, 1, 0, 0, 2, 1, 0, -2, 0, -1, 2, - 0, -1, 4, -1, 2, -3, 4, -2, 3, 3, 1, 0, -15, 12, -63, 27 }, - { -2, 14, 9, -1, 3, 0, 1, 1, -19, 15, 3, 4, 0, -10, 1, -5, - 3, 0, -5, -10, 2, -16, -4, 8, -12, -6, 7, -5, -10, -1, -33, -4 }, - { 0, 3, 1, 3, 1, 2, 4, 4, 9, -6, -8, -5, 1, -12, 3, 8, - -10, 6, -1, 1, 13, -5, -5, 2, -4, 13, -18, -10, -7, -9, -33, 10 }, - { -6, -3, -12, 5, -1, 11, -6, 0, -2, 1, 2, -7, 3, 1, 3, -2, - 1, 8, -10, 7, -1, -3, 3, 0, 13, 1, 6, 7, -16, -7, -39, 8 }, - { -6, -1, 11, 6, -3, 8, 3, -5, 3, 0, -5, -2, -6, -3, -4, 2, - -3, 13, -11, 1, 7, 5, 19, -5, -3, -15, -1, 7, -1, 6, -33, 8 }, - { -7, 3, -4, -3, -4, 1, 6, -5, -5, 6, -8, -1, -7, 4, -1, -6, - -2, 1, 7, 0, 1, 1, -5, 2, -2, 0, -13, -2, -31, -14, -39, -12 }, - { -10, 9, 0, -3, 1, -1, -1, 0, 1, -5, -1, -4, -2, 5, 2, -7, - 18, -8, -2, -19, -7, -7, -12, -14, -11, -1, -9, -13, -7, -12, -31, -9 }, - { -3, -16, 10, 9, 1, -10, -12, 2, -2, 2, 7, -3, -3, 1, -4, -5, - -9, 5, 7, 3, -1, 4, -11, -8, 4, 13, -10, 13, 10, -4, -36, 1 }, - { -7, -12, 4, -20, -7, -7, 2, 11, -1, -2, 3, -12, 1, 0, -6, -7, - 6, 4, 13, 3, -3, 4, 3, -6, -12, 5, -5, -22, -13, -8, -37, -6 }, - { -7, 5, 3, 5, 7, 9, -14, -3, 10, 17, -1, 1, -12, 5, -6, 0, - -4, -9, 0, -11, -14, 3, 13, 6, -25, -8, -12, 4, -10, 18, -30, -1 }, - { -10, 6, -10, 6, 6, 1, -10, 0, -7, 5, -2, 17, -18, -4, 0, -3, - -16, -6, -3, -8, 5, 1, -4, 6, -7, 16, 6, 10, -1, 0, -32, -11 }, - { -1, 9, 9, -5, 4, 9, 6, 9, -4, -2, 7, 11, 4, 2, -5, -4, - -6, 0, 2, -3, -1, 5, 10, 0, 12, -10, -18, -3, -1, 14, -33, 2 }, - { 4, -8, -18, -4, -5, -11, 4, -10, -4, 9, 13, -12, 1, -6, 1, 2, - 4, -9, 8, 3, -6, 21, 13, -1, -2, 1, -2, 6, -7, 0, -30, 1 }, - { 6, -1, 2, -3, -1, -4, 6, -4, 0, 4, 2, 2, -9, 2, 6, 3, - -2, 4, -1, 9, -6, 0, 7, -8, 5, 19, -2, 9, -5, 2, -33, -8 }, - { 2, 1, 12, -5, -8, 8, 3, -2, -4, 1, -2, 5, -4, -9, -8, -8, - 7, -11, -4, 6, -10, 7, -1, -1, -2, -1, 16, 32, -7, 20, -33, -6 }, - { -18, 2, 6, 13, 9, 9, -1, 3, -17, 24, -2, -6, 28, 8, -2, 6, - 3, -10, -34, -16, -13, -4, -15, -11, -12, -3, -10, 4, -8, 4, -31, -4 }, - { -11, 0, 18, 2, -16, -9, -13, -2, -2, -12, -3, -22, 30, 0, 8, 3, - 9, -4, -16, 1, 0, -11, 15, -2, -4, 6, -5, 6, 1, 2, -25, -12 }, - { 14, -1, 5, 7, 3, -15, -8, 1, 5, -2, 12, 13, 11, -25, 3, 1, - 0, -2, -4, -16, -23, 0, -5, -17, 7, 5, -9, 6, -5, 2, -32, -7 }, - { 3, -1, 6, 14, 2, -12, -9, -9, 4, 7, 4, 6, 5, -8, 4, 2, - 4, 5, -2, 8, 8, -6, 0, 10, -20, -1, 3, -1, 8, 23, -33, -5 }, - { -3, 11, -6, 3, -4, 5, 7, 3, 4, 5, -2, 3, -1, 30, 6, 1, - 8, -6, 0, 0, -9, 6, -9, 4, 2, 9, -6, 1, -12, 0, -34, 18 }, - { -17, 13, 0, 1, 9, -4, -11, 0, 7, 0, -10, -4, -1, 6, -6, 4, - 1, 6, -9, 3, -5, -6, -11, 2, -4, 14, 23, -3, 2, 5, -30, 12 }, - { -14, 5, -27, 2, 0, 7, 1, 4, 30, 8, 7, 5, 1, -1, 0, 5, - 8, -10, 48, -11, 12, 33, 6, 8, -15, 20, -2, -5, 32, 5, -19, 10 }, - { -16, -4, -12, -7, -2, 0, 8, -6, -20, -18, 16, -3, 0, 31, -2, 11, - 2, -9, 49, -19, -12, -23, 10, 26, 16, -2, 4, -21, -14, 13, -11, -9 }, - { -5, -9, -1, 3, -5, -21, 2, 10, 0, 0, 10, -21, -7, 7, -26, -9, - 22, 32, 58, 11, -3, 11, -5, -8, -13, 6, -5, -9, 1, 10, 14, -8 }, - { 7, 7, 10, 3, -2, -1, -11, -11, -6, -43, -3, 14, -19, -18, 19, 18, - -32, 10, 45, -6, 6, 21, -20, -12, 2, 4, 6, 6, -4, 3, 3, 1 }, - { 21, 22, -3, -2, -11, -6, -1, -2, 8, 8, 32, -21, 7, 28, -4, -6, - -3, -2, 50, 2, 2, 27, -5, -8, 12, 7, -5, -1, -4, -17, 27, 6 }, - { 13, 7, 2, -6, -12, 2, -10, -5, -17, 11, 4, 17, -12, -2, 5, -17, - 37, -16, 48, -14, -18, 29, 8, 24, 11, -5, -9, 11, -1, 1, -13, -3 }, - { 1, 1, -1, 2, 0, 0, 0, -1, 1, -1, 7, 2, -3, 3, 0, 6, - 2, 10, 54, -25, 7, 54, -5, -6, -1, -15, 9, 13, -24, -15, -12, 3 }, - { 21, 5, 8, 3, -3, -4, -2, -4, 3, -11, -5, -8, 9, 16, 8, -9, - -10, -3, 46, -46, 2, 1, -10, 10, 17, 11, -20, -36, 10, 14, 0, -5 }, - { 7, -13, -6, -9, -24, 45, 2, 8, 8, 0, 17, 20, 12, -24, 1, -7, - -15, -3, 46, -13, -2, 20, 1, -13, -11, -13, 2, 15, 1, 10, -1, 3 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, -1, - -16, -9, 31, -69, -34, 26, 7, 17, -1, -6, -1, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, - -5, -20, 18, -82, 22, 3, -7, 9, 4, 6, 2, -4, -1, 0, -2, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, -1, - 15, -5, 62, -36, 4, 52, -7, 5, 0, 6, 1, 2, 1, 1, -1, 0 }, - { 3, -19, 19, -20, 13, -4, -11, 8, 8, -16, 10, 1, -14, 30, 1, -33, - 10, -11, 45, -30, 3, -4, -3, -13, 7, 12, 3, -22, 3, -2, -4, -2 }, - { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, - 11, 8, 70, 48, -10, 21, 4, 9, -9, -9, -4, -6, 0, -1, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, - 2, -1, 80, 2, -15, -36, -10, -5, -2, 8, -2, 2, 0, 0, 0, 0 }, - { 10, 8, -8, -8, -24, 12, -1, 0, 20, 9, -1, -2, 2, -2, 12, -10, - -2, -13, 35, -43, 44, 15, -10, -25, 4, 10, -3, -5, -5, 7, -1, 3 }, - { 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, -1, - -18, 9, 49, -72, 7, -8, 7, -5, 2, 3, 2, -2, 1, -2, -3, 1 }, - { -1, 4, -3, 10, 19, 4, 3, 20, 6, -24, 6, 9, 8, 15, 18, 18, - -36, 19, 57, -11, 4, -3, 8, 7, 2, -3, -2, -9, -15, -2, 12, -4 }, - { 20, 3, 11, -9, -4, 22, 42, -25, 1, 5, -10, -19, 0, 9, -16, 5, - 2, 10, 44, -29, 17, -3, -9, -2, -1, 8, 14, -7, -1, 16, -5, 1 }, - { -7, 16, -11, 12, 6, 33, -15, 14, -23, 2, -26, 8, 2, 10, 0, -5, - 8, -8, 38, -38, -4, 5, 5, 5, 1, 22, -15, 7, 6, 0, 4, 28 }, - { -1, -12, 2, 10, -2, 0, 7, 17, 12, 22, -4, 10, 25, 29, 5, 18, - 4, 1, 27, -39, 31, 17, 2, 2, 22, -23, 13, 16, 1, -7, -4, -5 }, - { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, 0, -14, 0, - -7, -11, 49, -22, -4, 19, 17, -39, 4, -29, 10, 2, 36, -4, 23, -1 }, - { -2, -2, -2, -2, 1, 15, -5, -7, -16, -8, -19, 16, -3, -20, 36, -9, - -3, 20, 39, -20, 0, 2, 27, -16, 10, 10, -14, -22, -16, -3, 13, -8 }, - { 5, -9, 6, -25, 7, 37, 13, -10, -5, 3, -5, 7, 18, -22, -7, 9, - -5, -4, 50, -11, -4, -5, -5, 8, -4, -2, -4, -27, 14, 20, 7, -9 }, - { 0, -14, -10, -27, -14, -17, -6, 26, 10, 2, 14, -12, -5, 0, 8, 9, - 0, -28, 55, -7, -12, -7, 4, -10, 10, 7, -12, 11, 3, 5, 9, -8 }, - { 2, 23, 4, -2, -1, -20, -2, 14, 10, -9, -9, -24, 10, 0, 11, -12, - 12, 11, 49, -25, -2, 29, 7, -13, 21, -10, 11, -17, 3, 1, -8, 5 }, - { 3, 0, -14, -6, 18, -2, 17, -9, -19, 9, -5, 9, 14, 6, 19, -3, - 27, 1, 41, -21, 20, -15, 33, 0, 26, 14, 7, 10, 3, 20, -3, -12 }, - { -1, 16, 15, -8, 3, -8, -8, 21, -5, -16, -29, 4, 1, -6, -4, -28, - 2, 31, 37, -26, -2, 13, 24, 8, -9, -6, -29, 10, 7, 2, 7, 8 }, - { -10, -10, 11, 13, -32, 2, 16, 9, 14, 23, -15, -13, 24, 13, 4, -27, - 14, 12, 31, -18, 17, 23, -2, -7, -14, 9, -17, -6, -10, 20, 9, 6 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, - 5, 1, 89, 8, 10, -6, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, - 4, -7, 64, -50, 7, 37, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, - { -2, 5, 3, -4, -4, -3, 2, -3, 3, -3, 5, 4, 1, -6, -1, 1, - 6, -2, 50, -35, -7, 43, 7, -7, -5, -26, 24, 21, 3, -15, 5, 6 }, - { -8, 21, -19, 33, -8, 22, -11, 17, 3, 0, 0, -2, 1, -3, 6, -1, - 10, -8, 4, -11, -4, -5, 0, 8, -4, 3, 1, -4, 4, 2, 8, 4 }, - { -7, 5, -20, 9, -22, 3, -14, 1, 6, 13, 23, -2, -4, -7, 2, 0, - 11, 4, 6, 3, -7, -11, -7, 4, 5, 5, -12, 8, 2, 4, 7, -3 }, - { -7, 6, -4, 20, -20, 16, -2, 7, 6, 16, 11, 12, -7, -7, 5, 3, - -9, -4, 1, 2, 5, 2, 1, -9, -2, -17, -4, 6, -10, 7, -7, -6 }, - { -9, 18, -17, 12, -24, 1, -1, 4, 14, 9, 4, 3, 2, 8, -12, -14, - 4, -8, -4, 7, 7, 6, -1, 13, -9, -4, -1, 1, 0, -4, 15, 8 }, - { -25, 2, -11, 6, -5, 24, -28, -5, 8, 12, -2, 6, 8, -3, 8, -9, - -1, -5, -1, -5, 6, -1, -1, -1, -4, 8, -12, -2, -13, 7, 2, 1 }, - { -14, 14, -18, 20, -10, 12, -2, 9, 1, 0, 12, -2, 15, -10, 26, -17, - 16, -11, 10, -10, 9, -2, 4, -8, 2, -3, 4, 4, 2, -3, -5, 1 }, - { -18, 12, -18, 21, -6, 12, -6, 13, -25, 18, 1, 11, -9, -5, 0, 10, - -5, 3, -3, 8, -9, 7, 4, 2, -9, 0, 5, 0, 2, -3, 9, -8 }, - { -4, 16, 1, 18, -30, 9, 1, 6, -8, 13, 13, -12, -6, -1, 13, 7, - 6, 2, -15, -3, 5, 5, 1, -6, 1, -5, 0, 2, -16, 0, 3, -4 }, - { -21, 1, -2, 6, -43, 18, -1, 5, -1, 4, 6, -2, -1, -3, -1, -3, - 0, 1, 2, -9, 0, -1, 0, -2, 0, -1, -1, -2, 6, 0, 1, -2 }, - { -23, 10, 4, 7, -32, -11, -18, 2, -2, -7, -6, -3, -3, -12, 19, 3, - -5, -6, 16, -6, 16, 2, 16, 16, 8, -2, 13, 8, -15, -11, 2, 10 }, - { -8, 2, -13, 2, -29, 24, -20, 19, 1, 10, -4, 10, 1, 2, -9, 11, - -1, -2, 9, -5, 19, -7, 16, -9, -2, -18, 11, 1, 1, 0, 7, -3 }, - { -6, 3, 4, 13, -26, 10, -10, 28, -7, 28, 1, 7, 0, -14, 5, 7, - 4, -4, 3, -2, 3, 3, -11, 7, 6, 4, 0, -1, 2, -1, -3, 2 }, - { -6, 16, -31, 13, -10, 17, -6, 4, -14, 4, 4, -1, -10, 12, -5, 1, - -14, 15, 0, -8, 1, -5, 3, 3, 9, -5, 7, -20, 7, 4, 11, -5 }, - { -19, 3, -17, 14, -12, 16, -22, 18, 14, 8, -2, 4, 10, 12, -14, 4, - -3, 2, 3, 7, -7, 7, -6, 2, -2, -4, -5, 0, -5, -2, 2, 1 }, - { -9, -7, -11, 24, -36, -9, -11, 5, 7, -12, -13, 18, -2, 20, 1, -4, - -1, -10, 15, -6, 14, 1, 0, 2, 1, 2, -9, -16, -11, 7, 13, 0 }, - { -24, 24, -18, 18, -22, 14, -11, 13, -12, 11, -10, 11, -7, 11, -5, -4, - -1, 1, 5, 2, 3, -1, 1, -5, 7, -4, 5, -6, 8, -7, 8, -6 }, - { -6, 18, -22, 22, 5, 11, -1, 6, 19, 22, 8, 4, -8, 20, -2, 15, - -6, -18, 0, -33, -9, -12, -1, 6, 5, 2, 5, 5, -5, -17, -3, -3 }, - { 1, 11, -16, 9, -18, 11, -4, 18, 20, 26, -10, 8, 1, -11, 8, -4, - 0, 7, 3, 5, 2, 2, 10, -2, -4, 4, -4, -2, 1, -4, -5, -1 }, - { -10, 6, -1, 18, -17, 27, -3, 10, -2, 12, -7, -9, 1, 1, -1, 7, - -12, -1, -7, -6, -1, 8, 3, -15, 8, 9, 3, -7, 4, -1, 1, -1 }, - { -14, 6, -16, 22, 2, 5, 0, 5, -18, 11, 6, -3, 22, -20, -9, -3, - 6, -6, -7, -15, 1, 15, -8, 11, 8, -3, -8, 1, -8, 2, 6, -2 }, - { -21, 5, -19, 19, -7, 4, -7, 0, -8, 6, 12, 5, -3, -22, -13, -6, - -1, -3, -2, -14, 6, -3, 1, -8, -7, -5, -6, 11, -3, -10, -5, 2 }, - { -1, 9, -12, 15, -6, 6, -19, 14, -9, 11, 3, 12, -17, -3, 8, -4, - -3, -4, 1, -5, 4, 5, -7, -15, -7, 15, -6, -5, 1, -5, -3, 1 }, - { -12, 20, -15, 20, -14, 3, -14, 9, -6, 33, -13, 6, -2, 8, -6, 7, - -5, -6, -3, -3, 0, 8, -3, -3, 1, -2, 2, 2, 6, -5, -5, -2 }, - { -7, 12, -18, 12, -18, 10, -4, 8, 2, 4, 8, 9, 0, 3, -8, 3, - 6, -12, -4, 1, 25, -5, -9, 6, -7, 0, -9, -7, 3, -5, -4, -4 }, - { -18, 12, -10, 11, -22, 0, -15, 5, -2, 2, -3, 6, -4, -4, -3, -15, - -2, -3, 21, 6, -12, -11, 19, 3, 3, -14, 7, 0, -11, -22, -10, 0 }, - { -15, 2, -30, 15, -17, 13, -16, 8, -7, 10, -8, 2, 11, 3, 10, -7, - 7, -22, 12, -10, 3, -12, 6, -10, 12, -10, 7, -8, 5, 2, 9, 1 }, - { -9, 11, -14, 6, -10, 21, 5, 12, -5, 5, 7, 21, 6, 2, -2, -1, - -1, 4, 2, -20, -18, -1, -14, 3, -1, 4, -7, 10, 1, 11, 4, -4 }, - { -22, 8, -30, 13, -21, -4, 4, -1, 12, 9, -2, -3, 2, -6, 4, -13, - -2, 8, 8, 1, -7, 3, -4, -5, -1, -7, -2, 8, 8, 7, 8, 0 }, - { -6, -4, -35, 16, -13, 15, -11, 14, -7, 9, -1, 11, 7, 0, 13, 10, - -1, 8, 1, 1, -2, 8, -1, 2, 2, 3, -10, -1, 7, -13, -3, -7 }, - { -15, 7, -16, 14, -18, 17, -6, 14, 3, 4, 7, -3, 10, -22, 5, -15, - 4, -4, -11, 15, -15, 11, -11, 20, 1, 0, 2, 1, 11, -3, 11, -7 }, - { -12, 3, 5, 16, -37, -1, 15, 15, -15, 10, 3, -10, 1, 15, 7, -15, - -13, 8, 9, -3, 2, 12, -8, 2, -5, 0, -3, 4, 5, -9, -4, 5 }, - { -16, 26, -4, 14, -22, 26, 6, -3, -8, 4, 21, 6, 16, -4, -11, 7, - -10, 3, 3, 7, -4, 2, -9, 8, -2, 2, 5, -2, -4, -2, 7, -1 }, - { -7, -10, 4, 3, 2, -4, -12, -10, -4, -5, 16, 19, -16, 1, 2, -9, - -10, 0, 9, 7, -8, 3, 12, 8, -6, -11, -13, -1, -3, -20, 6, -5 }, - { -14, -17, 3, -5, 14, -12, -12, 8, -6, -25, 21, 21, 10, -8, -12, 4, - 10, -4, 3, -9, 11, 9, 0, 4, 2, -15, 1, -14, 4, 1, 0, -4 }, - { -4, -9, -3, -1, 6, 3, -6, 6, -10, -4, 14, 8, 2, -3, -12, -19, - 0, 11, -20, 1, 6, -2, -27, -6, 10, -17, -14, -17, -9, 8, -8, 3 }, - { -12, -13, 16, -4, -2, 12, -7, -11, 2, -13, 3, 7, -16, -18, -1, -12, - -2, 1, -12, -9, -2, -6, 2, 9, -22, -3, -4, -14, -7, 7, -1, 2 }, - { -7, -8, -8, 15, 15, 18, 15, 16, -4, -37, 11, 15, -12, -1, -3, 3, - 6, 6, 0, -5, -3, -5, 9, 1, 1, -11, -1, -8, -6, 2, 3, 0 }, - { -6, 7, -5, -12, 13, 10, -18, -4, -3, -21, 6, 16, -15, -7, -12, -9, - 1, -12, -1, 10, -2, -1, -3, 4, -4, 1, -16, -1, 12, -9, 5, 9 }, - { -14, -5, 9, 3, 4, 26, -28, 3, -6, -24, 4, 5, 3, 13, 5, -1, - 3, -1, 3, 1, 1, -5, 3, 0, -7, -8, -7, -3, 3, -5, 4, 0 }, - { -4, 2, -10, -6, 25, 26, -6, 10, -6, -8, 15, 11, -6, -3, 2, -7, - 5, 14, 9, -1, 0, -12, 4, -4, -10, 1, -3, 3, -2, -2, -6, -1 }, - { -10, 8, -15, -10, 19, 17, -8, 0, -3, -7, 7, 5, -13, -1, 7, -7, - 1, 13, -12, -13, 17, -12, 1, 26, -18, -3, -5, -6, 4, 5, 8, 1 }, - { 2, -5, 3, 0, 0, 0, 2, -3, -2, -5, 7, 13, -4, 9, 0, -5, - 4, -1, -11, -8, -4, 0, -13, 2, -47, -23, -8, -11, -4, 4, -2, -3 }, - { -18, -4, 4, 5, -1, 17, -12, -8, 1, -12, 7, 20, -12, 3, -2, -11, - 16, 12, -6, 1, -13, -16, -6, -3, -3, -5, 4, -12, -5, -9, 10, 1 }, - { -11, 0, 4, 7, 7, 8, 3, -1, 3, -19, 32, 8, -19, -8, 2, 4, - -12, 15, -16, 3, 1, 9, -2, 1, -2, 8, 5, 6, -4, -1, 11, -8 }, - { 3, -1, 4, -2, 14, 32, -9, -23, -10, -12, 22, 15, -1, -2, 10, 0, - 4, 6, -8, 4, -15, -2, -1, -4, 0, -8, 4, 1, -8, 3, 4, 1 }, - { -17, -12, 6, -8, 16, 13, -20, -8, -1, -16, 10, 21, -19, 11, -9, -5, - 7, 18, -6, 7, -7, -18, 13, 2, -2, 8, -12, -9, 2, 4, -5, 16 }, - { 4, 0, 17, -11, 12, 7, -12, 5, -1, -25, 30, -8, -7, -6, -4, -7, - 9, 8, 7, 3, 3, -16, 8, 0, -2, -2, -18, -3, -4, -5, 1, 4 }, - { -3, -6, 6, -16, 17, 6, -3, 2, -9, -17, 12, 11, 11, 2, -20, 8, - 1, 1, 0, 2, -2, -6, -21, -13, -9, -15, -1, -8, -6, -8, 0, -2 }, - { -11, -7, 6, -9, 3, 6, 8, 16, 4, -5, 23, 26, -10, -3, 4, 0, - 2, 2, -4, 4, -2, -12, 12, 10, -11, 0, -10, -16, 3, 0, 0, -10 }, - { -5, -16, 10, -6, 27, 13, -3, 4, -2, -13, 15, 5, 2, 5, 3, -4, - 13, 12, -11, -7, 0, 1, 11, 12, 2, 13, -15, -8, 9, -2, 3, 8 }, - { -5, -8, 4, 3, 9, 3, -11, 10, 14, -25, 14, 8, -2, 5, -12, -21, - 2, 10, -7, 2, -3, 2, 0, 2, -1, -3, -5, -6, -1, -16, 2, 8 }, - { -1, 5, 1, -11, 5, 9, -7, 8, -13, -12, 4, 12, -4, 1, -1, -1, - 27, 29, 10, 15, 2, -6, -3, 4, -21, 10, -9, -11, -6, -1, -9, -3 }, - { -6, -3, -1, -6, 11, -5, 0, -2, -5, -31, 11, 3, -1, 5, -3, 4, - 5, 7, -10, 5, -10, -13, 4, 12, -15, -2, 2, -7, 1, -9, -3, -10 }, - { -3, -7, 17, -8, -5, 36, 8, -7, -8, -20, 12, 8, 1, -1, 3, 0, - 1, 4, -10, 3, 1, 4, -2, -3, -2, -3, -10, 4, -1, -7, 3, 2 }, - { -13, -3, -5, 9, 22, 6, -23, 3, -10, -7, 17, 17, 18, -14, -8, -8, - 2, 4, -8, 2, -3, -8, 6, 4, -1, 7, 0, 0, -3, 0, -12, -3 }, - { -3, -10, -15, -3, 9, 3, -23, -9, -13, -18, 12, 13, -2, 0, 1, 8, - -1, 2, -7, -12, -5, 14, 2, 1, -22, 6, -10, -8, -9, 28, -7, -14 }, - { -3, 1, 2, -1, 13, 7, -2, -7, 1, -3, 6, 9, -3, -2, 4, -2, - 2, 1, -10, -2, -2, -22, -2, -7, -10, -5, -11, -27, -12, -16, 4, -7 }, - { 2, -6, -3, 1, 8, 0, -2, 12, -3, -4, 58, 15, -10, -4, -2, 2, - -2, 0, -2, -6, 2, 4, -1, 1, -4, 1, -1, -5, -4, -3, 3, 1 }, - { 10, -1, 0, 5, 21, 7, -14, 6, -3, -16, 15, 17, -16, 13, 3, -6, - -4, 6, -12, -5, 1, -4, -7, -8, 2, 3, -6, 6, -1, -8, 5, 4 }, - { -6, -2, -8, -11, 15, 10, 0, 8, -6, -15, 33, 8, -2, 18, -15, -11, - 5, -1, 0, 15, -15, -4, -4, -1, 10, 7, -13, 4, -4, 0, 8, 3 }, - { -7, -2, 0, -2, 0, -2, -4, -5, -14, -16, 12, 38, 7, 12, 6, -4, - 0, -1, 0, 3, -2, -6, 0, 2, -9, 1, 0, -1, 0, -2, 4, 1 }, - { -8, -4, 18, 1, 14, 5, -12, -3, 20, -17, 5, 19, -11, -8, 11, -3, - 3, 9, -7, -8, 9, -17, 2, 15, -10, -11, 5, -5, 7, 15, -6, -2 }, - { -7, 2, 38, 5, 19, 16, -5, 4, -13, -20, 0, 4, -4, 6, 4, 2, - -7, 6, -8, -2, -5, -7, 6, 3, -4, -3, -2, -3, 7, -6, -4, 0 }, - { -11, -12, 8, -15, -3, 14, -7, -22, -11, 2, 22, 14, -19, 2, -19, -6, - 1, 3, -18, 14, 2, -6, -2, -8, -3, -6, 5, -7, -8, -4, 1, 1 }, - { 8, 7, 25, -21, 12, -6, -5, -4, -10, 6, 0, 10, 1, -12, 18, -5, - -15, 4, 1, 14, -1, 5, 8, -7, 1, -7, -3, 9, 10, 1, -1, 0 }, - { 9, 10, 32, -15, 8, 2, 11, -7, -18, -8, 2, -6, -9, -16, -3, 3, - -1, 3, 1, -5, 4, -2, 1, -8, 0, -6, -3, -11, 1, 5, 0, 0 }, - { 14, 0, 23, -25, 22, 3, 7, 10, 0, -2, 7, 8, 0, 10, 0, 0, - 3, 2, 3, -10, 0, 10, 0, -7, 0, 10, -1, -5, -7, 1, -1, 2 }, - { 12, 0, 25, -18, -5, -4, 13, -10, 3, -6, 7, 21, 0, -16, 3, -10, - -6, 5, -7, -3, 2, 5, 3, -6, 4, 9, -8, 12, -2, 3, 2, 4 }, - { 31, 15, 27, -20, 10, -7, 15, -10, 9, -8, 4, -5, 3, -3, 5, 6, - 11, -2, -12, -2, 6, -2, 1, 2, -1, -1, 1, 1, 3, 1, 1, 2 }, - { 12, -4, 13, -23, 12, -6, 2, 4, -3, 13, 6, -7, 5, -19, -7, 18, - 1, -7, 7, 1, 16, -7, 3, 0, 3, 0, -12, 8, -11, 9, 4, 7 }, - { 29, 1, 3, -22, -5, 6, 0, 12, -14, 11, 1, 6, -3, 4, 6, -2, - 4, -13, 12, 1, 1, 3, -11, 9, -10, -1, -7, 16, -11, -1, 3, 9 }, - { 4, 4, 36, -23, -5, -8, -15, 1, -6, 3, 13, -1, -5, -7, 4, 9, - 2, -11, -3, 5, 1, 3, -6, -1, -4, -4, -2, 2, 3, -1, -5, -2 }, - { 19, 10, 6, -17, 2, -4, -2, -4, -3, 13, 2, 2, -13, -7, -3, -11, - 9, -6, 1, -9, -5, 4, -5, -9, -18, -7, -11, 9, 4, -11, 8, 4 }, - { 16, -3, 9, -16, 18, -2, -12, -16, -11, 11, -18, 16, -13, 6, 2, 8, - 3, 8, -4, -16, 10, -11, -1, -3, -8, 5, -9, -4, 9, -4, 0, -3 }, - { 14, 15, 3, -23, -5, 7, -8, -6, 2, 17, 2, 12, -8, -12, 13, -1, - -9, 3, 1, 1, 19, 15, 4, -1, 1, 2, -3, 2, -3, 1, 5, 3 }, - { 32, 5, -10, -47, -5, -1, 4, 11, -7, 0, 2, -2, 1, -7, 6, -4, - 6, 2, -4, -2, 2, -2, 0, -4, 1, -6, -5, 2, -2, -1, -3, -4 }, - { 20, 8, 10, -21, -7, -9, -16, 12, 1, 4, 6, -5, 9, -11, -7, 4, - -11, 28, -3, 2, 4, -6, 10, -8, -5, -5, -9, 9, -2, -1, 6, -5 }, - { 38, 3, 23, -25, -6, -18, 3, -10, -8, 6, -10, 1, -10, 2, 2, 0, - -7, 2, -4, 5, -1, 8, -3, 0, 3, 3, -1, 1, 0, -4, -4, 0 }, - { 20, 5, 16, -22, 24, -18, 2, -12, -14, -7, -3, 10, 2, 7, -10, 2, - -8, 1, 8, -1, 4, 1, 4, -2, 5, -9, -18, -8, -13, 5, -11, 10 }, - { 14, 8, -12, -16, 9, -11, -3, -6, -25, -7, 6, 5, -7, -16, 10, 2, - -7, -1, -9, -3, 16, 4, 3, 3, -3, -3, -15, 13, -3, 4, 13, -7 }, - { 16, -9, 19, -23, 7, -19, -3, -5, -15, 11, -21, 21, -16, 18, -1, 6, - 10, -10, 18, -14, 16, -15, 6, -5, -9, 5, -17, 13, -10, 13, 0, 10 }, - { 8, -4, 4, -24, 8, -21, -18, 9, -11, 4, -6, 17, 5, -9, -2, -2, - 2, 15, -2, -3, -2, 1, 7, -13, 15, -10, -8, -11, 3, 3, -1, -1 }, - { 14, 17, 6, -32, 5, -17, -2, 0, 15, -1, -5, 16, 1, -5, -2, 9, - -3, 8, 4, -2, -2, -4, -3, 1, 0, 7, -3, 4, -5, 0, -7, 2 }, - { 24, 6, 22, -12, 8, 3, -14, 4, -7, 8, 6, 5, 6, 1, 6, -12, - 15, 10, 4, 11, 9, 6, -7, -4, 10, -9, 2, -1, -5, 11, 15, 3 }, - { 17, 12, 3, -23, 5, -1, -2, 1, -9, -1, -3, 1, 8, 1, -5, 17, - 11, 0, -2, -11, 7, 4, 0, -27, -7, 1, 2, -8, 9, 7, 5, 3 }, - { 12, 10, 12, -10, -4, 5, -1, 2, -24, 5, -8, 2, 6, -17, 19, 5, - 12, -2, 16, -7, -6, -14, 4, 1, -3, 13, -16, 5, -1, 4, 1, 1 }, - { 31, 9, 11, -17, 10, -3, -7, 7, 1, 2, 2, 4, -3, -1, 11, 4, - -5, -8, 1, 4, 15, -6, -28, 1, 8, 3, -6, 5, 17, -2, 2, -4 }, - { 11, 19, 16, -26, 0, -7, -7, 2, -13, -15, -12, 9, -3, 27, 8, 4, - -6, 1, 4, -6, 11, -1, -6, -7, -3, 0, -6, 4, -6, -7, -3, -1 }, - { 10, 18, 16, -32, 19, -9, -4, -3, -7, 8, 8, -3, -11, -2, -6, -16, - 13, 13, -6, -1, 10, -2, -2, -9, 0, -3, 9, 4, 11, -2, -6, 6 }, - { 9, 4, 19, -33, 4, 7, -12, 36, -3, -1, 8, -2, 2, -8, -9, -4, - -8, 0, 1, -1, 0, -4, -4, 3, 0, 3, 6, 0, -6, 2, 0, -2 }, - { 25, 7, 15, -12, 2, -24, -1, 24, -4, 4, 9, 0, -2, -9, 4, 6, - 3, 13, -3, 1, 5, -1, -3, -5, -1, 7, -2, 3, 4, 4, 1, 0 }, - { 19, 6, 8, -20, 9, -9, 5, -4, -13, 7, 11, -3, 5, -13, -9, 6, - -11, -1, 0, 4, 11, 26, 3, 6, -7, 12, 6, -3, 1, -9, 7, 1 }, - { 15, 6, 19, -23, -3, -9, 3, 16, -6, -4, 6, -5, -10, 1, 16, -14, - 2, 0, 2, -13, -3, 8, -6, 3, 1, 1, 2, -5, 12, -4, -8, -3 }, - { 14, 4, 16, -20, 1, 12, 0, 6, -3, 9, 4, 16, 10, -16, 5, 7, - 5, -4, -4, -18, -3, -11, -4, 4, -7, 3, 13, 7, 3, 3, 2, -7 }, - { 22, 3, -1, -30, 18, -3, -9, 9, -2, 11, -16, -2, -14, 12, 0, 4, - -5, 4, -1, 3, -20, 12, 4, -10, -2, -2, -12, -12, 10, 6, 11, -3 }, - { 15, 7, 2, -21, 5, 4, 9, -9, -33, 7, 7, 3, -6, -14, -8, 10, - 12, 0, 2, -1, 5, 4, -2, 0, -7, 0, 2, 4, 0, 1, -3, 8 }, - { -7, 0, 12, 3, 0, -6, 8, -4, 0, 2, 14, -15, 2, -7, -31, -3, - 14, 0, 14, -15, -1, -4, -15, 10, 1, -3, 1, 2, 5, 2, -8, 1 }, - { -2, 5, 1, 0, -3, 3, 3, -6, -1, 2, -4, 1, -19, 0, -11, 18, - 11, 10, 21, 5, 6, 2, 10, 3, -6, 0, -2, 13, 5, -1, -2, 9 }, - { -9, 1, -5, 0, 0, -15, 8, 4, 8, 3, 8, 12, -13, -2, -39, -2, - 4, -4, 5, -3, -4, 3, -3, 3, 10, 5, 3, 2, -3, 5, -2, 8 }, - { -9, 6, 6, -8, 12, -12, 23, -18, 4, -15, -5, 2, -20, 13, -7, 7, - 7, -12, 14, -12, 6, 1, 1, -3, -8, 9, 0, 1, -7, 3, 7, -6 }, - { -18, 13, 4, 3, -10, -30, -10, -6, -14, 1, -7, -4, -35, 5, -25, 11, - 9, 8, 19, -4, -7, -3, -18, -8, 1, 5, 10, -4, -14, -9, 3, -4 }, - { -6, -1, 4, -9, -9, 4, 20, 0, 0, 3, 11, 7, -16, -17, -20, 11, - -6, -14, 1, 4, 19, 2, -8, 6, -15, 3, 6, -5, -14, 3, 7, 2 }, - { 1, 6, -2, -8, -5, -3, 3, -8, 21, 1, 3, 16, -14, -2, -9, -4, - 13, -2, 18, 14, 14, 19, -13, 5, -10, 2, -3, 3, 5, 5, 1, -1 }, - { -1, -5, -6, -2, -11, -7, 5, -4, 5, -1, 0, 3, -3, 2, -19, 18, - 16, 4, 14, -22, -2, -11, -22, 1, -1, 11, 1, 2, 11, -10, 7, -12 }, - { 1, 4, 5, -1, -9, -5, 1, 12, 5, 6, 12, 9, -24, 23, 1, 20, - 14, -11, 13, 5, -2, -2, 5, 6, 2, 1, -9, 6, 10, 5, -4, 11 }, - { -1, -1, 1, 7, -3, -4, 8, -16, 15, -1, -7, 9, -22, -11, -11, 10, - 16, 9, -2, 4, 13, 10, 6, 16, 4, 7, 1, -8, -7, -14, -7, 4 }, - { 1, 3, -6, 0, 15, -9, -4, 0, 4, 6, 12, 9, -6, -5, -22, 17, - 7, -11, 15, -5, 1, 3, -19, 0, -15, -3, 16, 5, 5, -7, -11, 12 }, - { -2, -1, 13, 2, 4, -24, 37, -5, -2, -6, 12, 7, -2, -23, -4, 9, - 2, -3, 3, 2, 3, 3, -14, 11, 0, -4, -2, -2, 3, 10, -10, 4 }, - { 2, 9, 8, -6, -28, 14, 28, -11, 18, -11, 0, 2, -2, 4, -12, 3, - 6, 0, 7, -7, -6, 2, 5, -1, -1, -1, 5, 2, 3, 0, -3, 9 }, - { -7, 14, 5, -10, -3, 7, 4, -5, 7, -8, -7, 4, -12, 14, -16, 25, - 3, 0, 1, -5, 12, -10, 0, -10, 0, 12, 12, 17, 12, 10, -1, 0 }, - { -4, -2, 5, -2, -17, -3, 5, -5, 7, -17, 1, 5, -4, 4, -20, 0, - 11, -15, 13, -8, 10, 1, 1, 5, -12, 9, -8, 0, 6, -1, -11, 4 }, - { -3, 12, 13, -15, -7, -7, 0, 5, 33, 3, 3, -6, -13, -7, -15, 10, - 3, 3, 3, -5, 2, 7, -1, 0, -12, 2, 11, -6, -9, 0, 5, 11 }, - { -8, 5, 10, -7, -14, -4, 13, 0, 18, -3, -6, 7, 1, -6, 0, 21, - 8, -7, 10, -8, -3, 17, -9, 0, -5, 1, 4, 8, -3, 11, -5, 0 }, - { -8, 8, -3, -8, 8, -11, 16, -16, 17, 0, 8, 16, -17, 10, -16, 10, - -8, 6, 11, 0, 10, 7, 4, 5, 7, -5, -5, -6, -7, -5, -1, 16 }, - { -6, 0, 6, 1, -8, -8, 8, -7, -5, -10, -11, 8, -19, 6, -7, 13, - 5, -3, 4, -8, 7, -1, -18, 9, 0, -5, 6, 26, 3, 8, 2, 4 }, - { -2, -2, 23, -2, -20, 2, 7, -7, -6, -15, 3, 9, -19, -2, -10, 7, - -2, 7, 9, 11, 0, 4, -4, 6, 9, -2, 4, -3, 4, 3, 2, 8 }, - { -6, 12, 10, -10, -7, 4, 17, 11, -6, 1, 12, 11, -18, 8, -12, 4, - 1, 13, 6, -13, 23, 9, -5, 8, -2, -5, 1, 3, 0, -2, -4, 4 }, - { 7, 1, 7, -17, -8, 8, -1, -7, 5, -6, 4, -3, -16, 9, -24, 18, - -3, 10, 13, -11, -6, -11, -4, 10, 0, 11, 8, 2, 6, -5, -11, 4 }, - { -4, 1, -5, -10, 0, -3, 9, -2, 4, -1, 1, 5, -41, -10, -7, 4, - -3, 3, 1, 0, -12, 4, -3, 0, 2, -1, -2, -5, 3, 2, -7, 5 }, - { -2, 1, 4, 4, -3, -6, 1, 0, 12, -5, 11, 0, -17, -3, -1, 11, - 4, 1, 27, -12, 0, -14, 2, -15, -3, -9, 0, -7, -3, 15, -8, 6 }, - { -6, 4, 9, 2, 4, 3, 7, -10, 28, 1, -2, 48, 7, 0, -10, 10, - 1, -9, 2, -1, 0, 3, -5, 5, -4, -2, 7, 7, 1, 3, 2, 5 }, - { -3, 3, -1, 3, -9, 0, -1, 3, 2, -6, 39, -14, -12, 5, -19, 21, - 7, -6, 4, -1, -4, 0, -4, 1, 0, -9, 1, 10, 0, -2, 0, 7 }, - { 4, 2, -29, 12, 5, -3, 16, -6, 15, -13, -4, -1, -13, 22, -16, 17, - 16, 4, 9, -4, 4, -6, -4, 11, -8, 7, 8, 4, 3, -3, -7, -13 }, - { 0, 3, 3, -6, -4, 0, 9, 0, 5, 0, 10, 10, 4, -13, -12, 16, - 23, -4, -12, -6, -4, 20, 2, 0, -4, 23, 1, 8, 11, -4, -5, 15 }, - { -6, 4, -15, -9, -1, -19, 12, -30, -17, -4, 1, -13, -13, 4, -3, 26, - 5, -25, 11, -14, -6, -13, 0, -7, 9, 2, 8, -1, -8, 1, -8, 13 }, - { 1, 6, 1, -4, -4, 1, 2, 0, -3, 2, 10, 6, -6, -2, -11, 4, - 32, 15, 15, -47, -8, 3, -12, 4, -5, 4, -1, 0, -5, 5, 1, -7 }, - { 2, -1, 0, 0, -1, -6, 0, -6, 4, -4, 5, 9, -5, 1, -3, 51, - 4, -5, 4, -14, -1, -4, -3, 1, -4, -1, 0, 2, -8, 0, 1, 2 }, - { 0, 4, -2, -7, -2, -9, 6, -8, 11, -3, -6, 3, -11, -8, -12, 8, - 11, 5, 19, 3, -24, 19, -14, 11, -5, -18, -8, -12, -5, -4, -1, 4 }, - { 16, 9, 10, 14, -18, -2, -18, -27, 10, -5, 12, 14, 4, 0, -2, -6, - -12, -7, -1, 3, 4, 7, 11, 10, 5, -5, -7, -16, -3, -6, 6, 9 }, - { 7, 15, -9, 10, -19, 4, -5, -37, -2, -4, 8, 2, 4, -1, 1, 9, - -5, -5, -12, 1, -1, -8, 3, -3, 4, 6, 9, 3, 3, -1, 2, 4 }, - { 13, 17, 3, 9, -7, -7, -15, -17, -8, -13, -4, -8, 19, 2, 16, 25, - 7, 15, 2, 16, -5, -6, -10, -9, -7, -6, -2, -7, 7, 2, 4, 5 }, - { 24, 7, 9, 8, -13, -2, 0, -4, 1, -13, 3, 6, 7, 10, -4, 15, - 5, 7, -4, 5, -5, 3, 13, -7, 5, 15, -11, -2, 7, 5, 8, 6 }, - { 17, 6, -15, 23, -2, -1, -6, -2, 0, -4, 11, -3, 12, 15, 6, -8, - -15, 10, -9, 7, -1, -11, 2, -8, -4, 3, 4, -10, 4, 4, 11, 1 }, - { 21, 12, -3, 6, -8, 8, -11, -8, -5, -5, 3, 7, -1, -5, 12, 15, - -10, -11, 3, 15, 8, 4, 2, -15, 0, 14, 1, -8, -1, 3, 10, -7 }, - { 16, 12, 5, 13, -6, 15, -23, 0, -17, -9, 0, 4, -9, 13, 6, 18, - 0, 0, -4, -1, 0, 14, 5, -1, 8, -4, -8, -6, 5, -2, -2, 0 }, - { 14, 16, -1, 12, -15, -9, -6, -20, 4, 6, 8, 9, 3, 1, -9, -4, - -1, -11, 9, 11, -12, 1, -14, -7, 2, -8, 11, 9, -4, 10, 4, -16 }, - { 13, 10, 3, 7, 0, -8, -33, -6, 4, -4, 19, -2, 14, 6, 5, 7, - 6, -3, -1, -10, -10, -9, 4, -3, 5, 9, 2, 2, 10, 9, -2, -3 }, - { 11, 10, 25, 18, -1, -6, -21, -21, -11, -16, 6, 5, 14, 4, 8, 7, - 0, -10, -7, -9, -5, -4, 3, -1, 1, 6, -1, 6, -2, 2, -3, -9 }, - { 15, 9, 5, 22, -17, 15, -9, 7, 7, -9, 13, 9, 10, -1, 8, -3, - -2, 6, 1, 17, 8, -14, 7, -3, 12, 9, 1, 0, 1, -5, 17, -18 }, - { 25, 19, -17, 12, -4, -10, 1, -13, -19, -7, -3, 9, 6, -2, 3, 1, - 4, -2, -11, -14, -1, -7, -5, -9, 7, -1, -3, 4, -5, 1, 0, -1 }, - { 20, 8, -3, -10, -24, 3, -6, -2, 0, -12, 14, 6, 7, 11, 4, 7, - -12, -5, -8, -10, 5, -1, -4, 4, 16, 7, -14, 6, -1, -2, -7, -11 }, - { 16, 18, 17, 1, -15, -6, -5, -3, -1, -19, 8, -2, 2, 8, 12, -19, - -12, 8, 0, -3, -1, -1, 4, -14, 9, -1, -12, -1, -7, 10, -3, 5 }, - { 18, 12, -7, 7, 0, -3, -13, 0, -1, -4, 9, -2, 6, -1, 0, 1, - 15, -21, 1, -8, 25, -19, 13, -9, 2, 12, 5, -7, -3, -1, -3, 1 }, - { 13, 16, -4, 9, -2, 2, -1, -19, -7, -4, 18, -6, 14, 18, -5, 4, - -6, -3, -19, -14, -1, -12, 10, 6, 7, 17, -12, -13, -10, -4, 5, 4 }, - { 27, 17, 4, 14, -9, -2, -4, -8, 0, -6, 14, -11, -7, 2, -3, -3, - -2, -3, -13, 12, 16, 1, -5, -9, -10, -11, -2, 3, -7, 5, 11, -7 }, - { 7, 17, -16, -2, -14, -28, -7, -8, 15, -10, 7, 15, 8, 17, 13, -1, - 4, -7, -12, -11, 0, 0, 2, 3, -3, 7, -6, 6, 1, -16, 1, -2 }, - { 23, 11, -9, 15, -23, -4, -6, -4, 2, -9, -7, 9, -8, 3, -13, -4, - 8, 18, -6, -2, 1, -5, 6, -14, -5, -2, -6, -5, -3, -2, 4, -5 }, - { 12, 13, 18, 18, -35, 2, 7, -17, 3, -11, 6, 9, -3, -2, 10, -4, - 3, 3, -2, -7, 0, 2, -4, 0, -4, 0, -6, 5, 10, 4, -3, -1 }, - { 19, 11, 1, 20, -14, 4, -9, -13, -2, 11, 0, 17, -1, -1, -1, -1, - -5, -8, 0, 5, -1, -8, 5, -1, 3, 2, -12, 21, -2, -24, 5, 7 }, - { 15, 15, -15, 17, -14, -22, 3, -4, -11, -3, -7, 1, 18, 10, 1, 10, - -6, -3, 8, 2, -7, 0, -2, 1, 1, 2, -9, -2, 1, 2, -3, 4 }, - { 45, 13, 8, 17, -5, 2, -16, 2, 8, -2, 8, -15, 4, 5, -1, 7, - -6, -2, -6, 2, -3, 0, 0, -9, -1, 7, 2, 3, -3, -3, -1, 5 }, - { 1, 18, -8, 18, -12, -10, 3, 4, -22, -12, 20, 8, -3, 9, 2, 10, - -10, -3, 9, 3, 6, -3, 10, -1, -3, 2, -2, 4, 2, 3, -3, -18 }, - { 9, 10, -5, 9, -35, -21, -18, -16, -1, -12, -6, -7, -15, -19, 12, 4, - 4, 9, -7, 2, 14, 1, 4, 0, -1, 6, -7, 2, 1, 1, -4, 4 }, - { 31, 8, -17, 35, -8, 1, -5, -6, -7, -6, 10, -2, -3, 6, 9, 3, - -6, -2, 3, 3, 5, -3, 0, 6, 0, 1, -5, -3, -2, -4, -1, 0 }, - { 18, 4, -8, 7, -8, -15, -1, -16, 12, 18, 3, 19, 2, 4, 8, 8, - 0, -5, -8, -12, 10, -5, 0, 1, 0, 4, -3, 16, 11, 11, -2, -6 }, - { 27, 15, -17, -10, -23, -22, -1, -14, -4, -7, 20, -2, -7, 6, 15, -5, - 32, 4, 9, -11, -3, -8, 11, -4, -1, -4, -8, -6, -4, -5, -2, -7 }, - { 22, 4, -7, 2, -15, -11, -17, -10, 2, 0, 15, 11, 7, 12, -8, 6, - -10, -18, -6, -12, 7, 3, 22, 3, -7, 14, -5, -2, -13, -7, -1, -7 }, - { 18, 13, 9, 24, -4, -19, -9, -11, 13, 8, 2, 4, -1, 8, 14, 10, - -12, 0, 0, 5, 10, 5, 4, -1, 5, 1, -1, 11, 2, -4, 0, -9 }, - { 15, 19, -5, 1, -4, -10, -8, -27, 6, 8, 5, 10, 4, 11, 5, -5, - -11, 0, -11, -14, -4, -9, -8, -8, 6, -9, 4, -5, -1, 1, 5, -4 }, - { 18, 1, -13, 14, -14, 9, -15, -7, 12, 1, 13, -4, -20, 12, 10, 12, - -12, 7, 1, -13, 10, -6, 5, -3, 4, 8, 10, -13, -3, -6, 9, -3 }, - { 19, -14, 5, -8, -6, 2, -5, 5, -3, -1, -28, 11, 18, -6, -4, -2, - 11, 14, -43, -42, 9, 2, 20, -23, 6, 32, 0, 5, 0, 6, 9, 5 }, - { 8, 11, -14, -1, 7, 12, -7, 2, -16, 2, 10, -3, -1, -7, -7, -1, - 1, -10, -60, -23, -18, 42, -13, 9, 18, -11, 0, 1, 0, 2, -5, 1 }, - { -5, -1, 2, 0, 3, -3, 3, -2, -6, 0, -3, -3, 7, 2, 0, -2, - -2, 3, -34, -15, 37, 47, 10, 20, 9, 1, 3, -21, -25, -33, -14, 8 }, - { 5, 6, 2, -2, -2, -2, 6, 5, -5, 7, -3, 1, -5, -13, 9, 3, - -17, -19, -2, -79, -12, -7, -8, -6, -2, -2, -1, -1, -7, -13, 6, -1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, - 0, 3, 4, -87, 6, -11, 16, -9, -1, 8, 0, 5, 0, 1, 2, 1 }, - { -5, 6, 2, -24, 5, -9, -7, 0, 7, 3, -3, 16, -14, -16, 0, 18, - 15, -9, -14, -28, -17, 53, 14, -6, -28, -1, -3, -10, -7, -14, 19, -15 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, - -13, 0, -53, 3, -22, 63, 19, 16, 1, -11, 0, -3, 0, -3, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, - -1, -6, -43, -43, -2, 65, -13, -4, 9, 1, 1, 2, 1, 0, 0, 1 }, - { 0, 1, 0, 0, -1, 0, 1, 1, 0, 0, 1, 2, -1, -1, -3, -1, - -23, 1, -61, -55, 3, -28, -6, -4, -4, 8, 2, 1, 1, -1, 0, 0 }, - { 0, 1, -1, 1, -1, 0, -1, 0, 1, -1, 0, 1, -1, 0, -9, -4, - -48, -19, -52, -46, 11, -12, 5, -14, 0, -10, 0, 0, -1, -2, -1, 0 }, - { 0, -3, -1, -4, 2, -1, -7, 3, 1, 3, -1, 1, -3, 0, -7, 0, - 3, -7, -61, -51, -4, -21, -16, -21, -11, 14, -7, 8, 3, -5, 1, 2 }, - { 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 9, -3, - 56, -11, -6, -67, -1, 13, 0, 7, 1, -9, -1, -1, 0, 0, 1, 0 }, - { 14, 9, -2, 14, -10, -10, 9, -5, 1, -8, -23, 30, 8, -7, 23, 8, - 2, 10, -1, -27, -17, 57, 22, 4, -5, 2, -12, -6, 2, -7, -4, -9 }, - { 1, 5, 12, -2, -2, -3, 2, -3, 6, 0, 4, -2, -8, -6, 0, 16, - -15, 29, -55, -29, -24, 29, 3, 10, 6, 13, 10, -5, 21, 11, -14, 5 }, - { 4, 2, 26, -6, 10, 11, -23, -10, -27, -20, 3, -24, -11, -10, -13, 25, - -10, 5, -9, -36, -7, 43, 3, -13, 6, 13, -2, 0, 1, 3, -3, -4 }, - { -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, -1, 0, 0, 0, -1, 1, - -12, 12, -26, -64, -15, 29, 37, -7, -3, -12, -5, 14, 8, -8, -10, -2 }, - { 19, -4, -11, -16, 8, 14, 5, 19, 3, 22, -11, -21, -1, -6, -11, 11, - 10, -24, -23, -40, -8, 20, 17, 5, 13, -6, 3, 14, -20, -8, 3, 28 }, - { 2, -12, 10, -14, -18, 26, -22, 4, -2, 5, -21, 8, 3, 1, 19, 0, - -12, 24, -14, -40, 15, 29, -15, 6, 15, 1, -19, 2, 4, 7, -12, -3 }, - { 0, 17, 13, 7, -5, -11, 2, -19, 3, 38, -21, -3, -6, -4, 7, 1, - 1, -5, -40, -10, -2, 35, 8, 8, -10, -8, -9, 33, 4, 4, 0, -2 }, - { -2, -12, 7, 29, -24, 2, 16, -1, -7, 16, 10, -2, -2, -2, 13, -2, - -37, 15, -22, -40, -11, 33, 10, -1, 8, 10, 6, 8, 9, 0, -12, 2 }, - { 15, -8, -9, -2, 7, -17, 7, 19, 14, 4, 12, 27, 11, 10, 4, 11, - -15, 14, -13, -48, 5, 18, 0, -9, -36, -11, 2, 4, 5, 5, -15, -12 }, - { -12, 0, 3, 4, 7, -5, 5, -14, -24, -18, -6, -15, -8, -20, 1, -7, - -33, -28, -40, -38, -18, -10, -5, 17, -12, 4, 3, -5, 5, -13, 4, -7 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, - -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, - -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, - 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, - 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, - -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, - -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, - 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, - 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, - { -8, 2, 1, 22, -31, -6, -25, -3, -3, 1, -15, -11, -2, -3, 4, -13, - -9, 15, -18, 37, -7, -37, 12, -13, -11, -25, -10, -11, -22, 7, 16, 7 }, - { 14, 10, 4, -10, -1, -5, -7, -3, 16, 13, -5, -15, 5, 11, -1, 8, - -27, 7, -12, 49, 17, -22, 9, -2, -9, -1, 2, -15, -1, 41, -18, -17 }, - { -4, -9, -15, -3, 3, 4, 4, 2, 7, -3, -7, -8, -5, 17, -19, -7, - 36, -9, -38, 17, 1, -48, 11, -18, -13, -2, -8, 4, -10, -5, 21, 11 }, - { 15, -13, 4, 2, 1, -5, -2, 1, -10, 7, -1, 3, -6, 0, 11, -11, - 8, 20, -17, 51, -17, -41, 2, 15, 4, 8, -2, 16, -32, -1, 17, 6 }, - { -8, 8, -18, -5, 4, 6, -3, 8, 0, -4, 2, 0, -1, -4, 5, 8, - 30, 30, -8, 70, 2, 8, 2, 0, 7, 1, 13, -1, -6, -7, -11, 2 }, - { -8, -7, 9, -10, -13, 6, -11, -14, 13, 25, -26, 5, 2, -5, -5, 5, - -8, 4, 0, 33, 12, -38, -4, 6, 13, 6, 25, 34, -1, 25, -19, -5 }, - { 18, 3, -17, 4, -8, 7, 20, 1, -1, 5, -5, -2, -8, 8, -35, 15, - 24, 43, -5, 51, 5, -12, -3, 1, -2, 3, -3, -3, -9, 8, -9, 2 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 2, 10, 24, 76, -2, -22, 11, -1, 4, 33, 4, 1, -1, 1, 2, 0 }, - { 0, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 2, 0, - 24, 13, 32, 70, 26, 5, -21, -9, -6, -15, 2, -2, 2, 4, 1, 1 }, - { 5, -4, -11, 4, -4, 22, 10, -2, 13, -11, -4, -21, -17, 0, -7, 4, - 10, -34, 11, 52, 2, -46, -5, 0, 0, -1, 2, 4, -9, 1, 1, -7 }, - { 0, 1, 1, 0, -1, 0, 1, 0, 1, 1, 0, 1, 0, 0, -3, 1, - -8, 9, -1, 64, -13, -61, -3, 3, -5, 10, 1, 3, -1, -1, -1, -1 }, - { 0, 1, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 1, - 10, -2, -31, 79, -10, 27, 0, -1, 3, 8, 1, 1, 0, -1, 0, -1 }, - { 3, 12, 10, 26, -19, 10, -9, 6, -4, -15, 10, 3, -16, 6, 11, -19, - 3, 10, 18, 44, 5, -30, 5, -9, 21, 4, 20, 10, 14, -25, 8, -17 }, - { 0, 0, 0, 1, -1, 0, -1, 0, 1, 0, 1, 1, 0, 0, -6, -2, - 8, -8, 13, 69, 26, -19, -25, -17, 16, 6, -12, 22, 2, -6, 9, 5 }, - { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, - -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, - { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, - -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, - { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, - -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, - { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, - 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, - { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, - 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, - { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, - -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - -1, 10, -18, 70, -2, -52, -1, -7, 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, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, - 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, - { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, - -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, - { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, - -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, - { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, - -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, - { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, - 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, - { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, - 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, - { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, - -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - -1, 10, -18, 70, -2, -52, -1, -7, 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, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, - 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, - { 16, -18, 7, -4, 31, -15, -9, -13, 20, -12, -6, 0, 12, -6, -2, 4, - 3, -3, -1, 0, 1, 3, 3, -2, 1, 6, 4, 0, -3, 2, -5, 1 }, - { 38, -5, -13, -4, 8, -15, 11, 1, 2, -4, -1, 9, 13, 4, -12, -7, - 0, -2, 7, 2, -6, -2, -3, -2, 3, -4, 6, 15, 1, 1, -11, -2 }, - { 47, -22, 9, -26, 3, -5, 2, -7, 4, -2, 2, -2, 3, 0, 3, -4, - 3, -3, 2, -3, 7, -3, -1, 1, 1, -5, 5, 0, 2, -5, -3, -2 }, - { 14, -16, 2, -6, 7, -2, -7, -4, -4, -7, 14, -3, 7, -19, -14, -17, - -29, 6, 26, 16, -5, 13, -4, -1, 21, 14, 1, 3, -6, 0, -7, -1 }, - { 29, -11, 5, -3, 4, 11, 4, -10, 1, -22, -3, -10, 5, 4, 2, 8, - -2, -7, -12, -12, -8, -3, -18, -2, -9, -5, -1, -3, 2, -14, -14, 7 }, - { 28, -12, 5, 3, 9, -7, 0, -2, 2, 1, 4, 0, -7, -3, -2, 4, - 4, 14, 8, -1, -4, 14, -7, 17, -2, -2, -9, 2, 19, -7, 9, -8 }, - { 31, -18, -22, 8, 15, -5, -10, -15, 1, 10, 6, 7, 6, -8, 2, -1, - 12, -3, 3, -1, 1, 5, -6, -4, 0, 1, 7, -10, -2, 4, -3, -4 }, - { 53, -30, -4, 12, 2, 3, -3, -3, 0, 1, 6, 5, -5, -4, -7, 1, - 0, 2, 1, 3, 1, 5, 0, 2, 2, -1, 0, 4, 2, 0, -2, 0 }, - { 27, -18, -3, -2, 4, -8, 3, -2, -11, 2, 10, -8, -8, -4, 0, -2, - 8, 0, 9, 0, -16, 11, 1, -6, 13, -3, -10, -13, -15, 25, 1, 0 }, - { 35, -5, -1, -8, 23, 11, -14, -3, 2, -2, 8, -6, 17, -2, 7, 0, - -2, 10, -17, 13, -2, -2, 11, 11, -14, 2, -2, -3, -8, -1, -12, -5 }, - { 29, -9, 7, 3, 2, -10, 0, 3, 9, 0, -3, 5, 1, -10, 10, -5, - 3, 6, -20, -9, -6, -4, 1, 0, 12, 17, -8, 9, 3, -1, -9, 0 }, - { 15, -16, 18, -19, 16, -15, 17, -18, 13, -16, 17, -14, 15, -9, 13, -17, - 9, -7, 4, -5, 3, -4, -3, 0, -6, 7, -9, 7, -2, 7, -9, 9 }, - { 21, -10, 7, -2, 12, -7, 13, -17, 11, -2, 20, 3, 5, -11, -6, -6, - -15, 0, -9, 5, -11, 7, -1, 7, 8, -10, -9, 3, -5, 9, -8, -2 }, - { 23, -22, 15, -5, 16, -4, -3, -12, 9, 3, -1, -2, -8, 2, -2, -16, - 3, 4, -2, -6, -7, 12, -8, 2, -14, 2, -7, 11, -2, 6, -4, -1 }, - { 34, -17, -4, 8, 4, -6, 1, 8, 4, 16, 3, 6, 12, -1, -1, -15, - 6, 4, -7, -6, 6, 0, 2, 1, -2, 2, 3, 3, -3, -2, 8, -6 }, - { 18, -18, 2, -2, 10, 1, 18, -23, -3, -10, 0, 4, 20, -19, -3, -4, - 2, 8, 6, 1, -3, 1, 1, 3, 5, -1, -11, 3, -7, 5, -1, 1 }, - { 15, -14, 2, 3, 10, -8, 12, -13, 13, -15, 6, -8, -4, -10, 14, -9, - 24, 2, -7, -18, 13, -11, 8, 14, -6, -2, 3, -1, -4, 7, -7, -4 }, - { 20, -12, 13, 5, -1, -10, 15, -6, 8, -1, -3, -10, 17, 0, -6, -19, - 2, -1, 8, -3, -16, 0, -3, 2, -2, 0, 8, -9, 0, 1, -10, -9 }, - { 32, 0, -9, -5, -1, 5, 13, -11, 8, 3, 11, -11, 0, -8, -2, -14, - 7, 10, 6, -5, 1, 10, 2, 12, -10, 4, 4, 6, 4, 0, -7, -10 }, - { 16, -14, 10, -7, 11, -11, 11, -11, 18, -13, 8, -15, 16, -11, 13, -9, - 8, -7, 12, -11, 7, -6, 3, -5, 9, -5, 4, -1, 7, -4, 8, -3 }, - { 24, -27, -1, 5, 8, -5, 12, 7, 4, -3, 3, -1, -9, -11, -13, -5, - 10, 0, -13, 7, 1, -5, 4, -9, 7, -3, 13, 2, -5, -3, -17, -2 }, - { 23, -19, 15, 1, -10, -18, -12, -6, 8, -3, 12, 0, -12, -10, -4, -4, - 8, -10, 4, 2, -2, -8, 13, -3, -2, -6, 2, -3, 5, -2, 2, 11 }, - { 25, -12, 4, 2, 24, -3, 3, -6, 14, 11, 0, -21, -3, -3, 1, -8, - 7, 0, 0, 3, 3, -6, -7, 6, 2, 1, -4, 5, -1, 10, -2, 9 }, - { 24, -8, -6, 7, 16, -12, 13, -1, 11, -21, 2, -6, 3, -12, 0, 9, - 4, 11, -7, 1, 4, 1, -8, 3, 3, -6, 3, 3, 0, -8, 8, 4 }, - { 25, -21, 13, 14, 13, -18, 4, -3, 0, -5, -4, 5, -3, 0, 4, 12, - 7, 3, 5, -5, 2, -2, 3, -10, 2, -9, -15, 6, 1, 7, -5, 1 }, - { 23, -16, -2, 10, 4, -1, 3, 1, 32, 3, -5, -2, 9, 10, -1, -4, - -6, 2, 9, -1, 14, 12, -6, -1, -17, -2, -4, -9, -7, -6, -8, 3 }, - { 50, -8, 5, 2, -11, 10, 0, 0, 6, -3, 7, 0, -3, -2, -3, 0, - 6, -4, 2, -5, -9, 0, 3, 10, 1, -7, -2, -3, -6, -9, 1, -2 }, - { 28, -17, 0, -2, 2, -9, 1, 5, -4, -1, 0, 0, 19, -27, 5, -12, - 7, -14, -3, -6, 10, -2, -4, -2, 4, -5, -2, -7, 1, 7, -9, 4 }, - { 22, -19, -6, -6, 3, -22, 3, 5, 20, -8, -14, -5, 1, 1, 20, 2, - 16, 6, 3, 14, 4, 3, 5, 1, 5, -7, -10, -6, 3, -6, 1, -14 }, - { 29, -14, -8, 13, 8, -10, -6, 4, 4, -6, 5, -7, 1, 12, 14, 11, - -7, 1, 2, -9, -11, -9, 0, 4, -1, 7, 10, 4, 4, 20, -1, -11 }, - { 18, -9, 4, 1, 7, -29, 12, 1, -1, -9, -2, -1, -2, 2, 9, -8, - -13, 5, 4, -13, -4, 2, -5, -7, -6, 14, -10, -34, -3, 1, -3, -13 }, - { 38, -9, 24, 8, 11, 4, -6, -11, -2, -12, 1, 1, -11, -8, -5, -2, - -15, -8, 8, 0, 1, -7, 5, 4, -1, 8, -2, 11, -3, -1, -5, -5 }, - { -20, 11, -4, 24, -11, 1, 15, 4, 0, -28, -10, -1, 10, 10, -6, 5, - -6, 2, 7, -2, 1, -2, -6, -3, -7, 1, 2, 12, -1, 7, 0, -2 }, - { -9, 10, -23, 27, -4, -17, 20, -6, 14, -17, 5, -1, 5, -9, -7, 5, - -6, 4, -2, 9, 0, 8, 0, 1, -3, -3, -5, -8, 5, -2, -2, 12 }, - { -10, 19, 4, 9, 1, -16, 17, -2, 9, -29, -16, -11, -4, 7, -5, 4, - -1, -3, 3, 2, 3, -4, 5, -12, -2, 6, 5, -4, 4, 1, 4, 10 }, - { -20, 10, -24, 14, -5, 11, 9, 0, 16, -20, 10, -5, -6, -6, -1, 2, - -4, 5, -16, 8, -2, 5, 5, -11, 9, -11, 4, -11, -1, -1, 4, 3 }, - { -9, 11, 3, 19, 24, 4, 5, -14, 30, -17, -4, -2, -17, 7, 2, 3, - 1, 3, -7, -4, 2, -3, 1, 4, -1, -1, 3, -12, -2, 3, -3, 10 }, - { -19, 18, 11, 19, 19, 19, 10, 4, 13, 6, 5, 4, 8, 3, -2, 12, - -6, -2, 7, -6, 15, 12, 16, 16, 18, -3, -4, -20, 0, 10, -9, -3 }, - { -21, 9, 20, 12, 0, -3, 5, -9, 15, -13, 5, -5, -6, 24, 2, 9, - -5, 2, -7, 2, 5, 7, -5, 2, 15, 3, 1, -1, -4, -2, 7, 0 }, - { -18, 16, 13, 15, 2, -10, 14, -11, 4, -11, 5, 12, 12, 20, 8, 30, - 2, 11, -9, 7, 0, -3, -16, -5, -6, 5, -4, -21, 0, 5, 6, 1 }, - { -26, 8, -13, 9, 6, -10, 2, -11, 7, -4, 6, -19, -11, -6, -12, 16, - 0, 5, -7, 8, 5, 6, 17, -9, 10, -10, 5, -3, -11, 2, 4, 10 }, - { -11, 17, -3, 22, -5, 18, 3, 1, 4, -5, 14, -27, 5, -7, -4, -5, - -10, 11, 1, 15, 1, 1, -6, -5, 10, -22, -7, -7, -15, 13, -4, 5 }, - { -17, 14, -7, 13, 3, 0, 13, -6, 9, -14, -22, -1, 1, 19, 14, -3, - 4, -13, -13, 2, -4, 8, -2, -2, 13, -12, 13, -12, -7, -5, -3, 6 }, - { -17, 17, -1, 33, 6, 3, 9, -16, 3, -14, -8, 6, -17, 8, 3, 13, - 8, -6, 3, 1, -2, 0, -2, 8, 4, 9, 13, -10, 4, -17, 0, -6 }, - { -20, 7, 7, 21, 1, -3, 7, -3, -2, -12, 9, -7, 2, -3, 14, 1, - -1, -7, 12, -10, 5, -20, 11, -2, 0, -24, -17, 6, 6, -4, 3, -1 }, - { -8, 10, 6, 7, -1, -6, 28, -6, 10, -33, 1, -20, 0, -12, 10, 1, - -6, 8, -3, -1, -10, 8, 5, 0, 10, -2, 8, 16, -5, -3, -7, 4 }, - { -17, 13, 3, 15, 1, -5, 27, -5, 6, -6, 12, 2, -4, 8, -1, -3, - -2, 12, -15, 3, 4, 1, 2, -9, 0, -16, -21, 2, -4, 16, -7, 4 }, - { -15, 20, 8, 17, 5, -14, 15, -11, 21, -11, 13, -13, 2, -15, -13, 1, - -5, 5, 2, 10, -9, 4, -1, 3, 2, -4, 13, -5, 1, -4, 5, -3 }, - { -21, 8, 2, 16, -1, 2, 15, -16, 13, -12, -12, -7, -8, 2, -7, 11, - -8, 5, 2, -7, 16, -4, 1, -7, 3, -15, 6, -5, -8, 2, -8, 5 }, - { -15, 17, -6, 3, -3, 3, 9, -7, 14, -23, 11, 1, -1, 4, 7, 6, - -1, -14, 7, 6, -8, 5, 1, -15, 10, -9, 2, -3, -1, 4, -10, -4 }, - { -10, 18, 3, 11, 1, 4, 14, -14, 7, -4, 15, -10, 10, -11, 10, -4, - 5, -14, 10, 4, 15, -12, 15, -13, 20, -15, 14, -15, 8, -11, 4, -6 }, - { -7, 23, 2, 20, 7, 8, 19, -5, 9, -16, -8, -17, -5, 1, 5, -6, - -8, 1, -6, -4, 10, 6, 6, 2, -11, -4, 0, 2, 4, 7, 9, -4 }, - { -15, 20, -5, 22, 11, -8, 9, -5, 10, -13, -8, 8, 2, -2, -3, 7, - 6, 10, 1, 2, -5, -9, 1, 10, 16, -22, -7, 0, 7, 7, 6, 1 }, - { -26, 19, -5, 3, 5, 25, 18, -5, 9, -14, -8, -6, -2, -6, 2, 3, - -8, -2, -7, 7, -3, 7, 3, 4, -8, 0, 1, -8, -4, -2, -2, 1 }, - { -20, 14, -10, 6, -3, 7, 8, -32, -2, -7, -2, -10, 16, -12, -9, 15, - -2, -5, -6, 2, -7, 5, 9, 1, 6, -7, -1, 0, -2, -4, -7, 3 }, - { -14, 16, 4, 11, -8, 1, 23, -4, 17, -13, -10, 1, 12, 9, 12, -4, - 7, -1, -1, 5, -8, -6, 3, 3, -6, -3, -18, 0, 18, 20, 4, -2 }, - { -33, 19, -10, 30, 15, 2, -3, -1, -4, -14, 7, -7, -1, 7, -8, 9, - -1, -3, -5, 2, 2, 4, 0, 5, 0, 0, 2, 3, 3, -3, -3, 4 }, - { -6, 20, 0, 5, 17, -10, 18, -17, 9, -16, 4, -13, -6, 2, -14, 14, - -28, 9, -12, 25, -4, 7, 7, -8, 6, -6, -2, -10, 2, -11, -1, 2 }, - { -12, 14, 12, 52, -3, 5, -5, 4, 8, -13, 2, -5, -4, 2, -2, -1, - -2, 3, 3, 5, 2, 3, 0, 1, -5, 2, -4, -3, 1, -5, -2, 0 }, - { -13, 6, 9, 24, 0, 8, 14, -15, 18, -9, -11, -8, 3, 15, -2, -4, - -9, 4, -3, 12, 14, -13, 11, -4, 2, -4, 0, -6, -6, -6, -14, -1 }, - { -10, 28, 3, 12, 9, 3, 11, -28, 6, -11, -7, 4, 0, 7, 8, -9, - 0, -6, 0, -16, 4, 7, 4, 4, 7, 3, 4, -7, 0, -3, -10, 6 }, - { -11, 14, -2, 19, -1, -1, 7, 9, -2, -27, 10, -14, 15, -4, 12, -4, - 2, -2, -6, 12, -6, 0, -5, -4, -5, 1, 3, -11, 5, -9, 3, -8 }, - { -18, 7, 13, 16, -4, 3, 9, -10, 10, -10, -3, -22, -4, -12, 3, -16, - 0, -3, -16, 8, -11, 1, 10, -7, 15, 3, 0, -1, -13, 8, 1, 6 }, - { -20, 10, -10, 10, 8, -1, 6, 0, 16, -12, 9, -10, -1, -5, -4, -13, - 13, 16, -8, 12, -2, 14, 18, 13, 0, -16, 2, -5, -5, -5, -4, 3 }, - { -14, 5, -7, -17, 5, -13, 23, 20, -4, -1, 1, -6, 13, 5, -1, 4, - -14, -2, -7, 8, 3, 2, 2, -7, 2, -1, 4, 7, 3, -9, -1, -5 }, - { -19, 3, -24, -28, -9, -7, 19, 3, 2, 19, 7, 5, -13, 8, -15, -17, - 3, -11, 4, 13, 3, 2, -1, -3, -4, -4, 2, 0, -5, -6, 6, 2 }, - { -17, 18, -30, -20, -2, -3, 1, 15, -1, -11, 6, -4, 11, 11, -4, -5, - -10, 0, 0, 1, 3, -7, 8, 2, 5, 1, 5, -5, 1, 6, 4, 1 }, - { -6, 1, -30, -25, -1, -8, -2, -9, -17, 16, 3, -1, -2, -9, -6, -7, - -3, 12, 6, -4, -10, 0, 10, -8, -6, -5, -3, -11, -4, 0, -1, -3 }, - { -1, -1, -34, -28, 1, -10, 2, 9, 4, 16, 2, 6, 14, 17, 0, 7, - -4, 4, 4, 4, 0, 1, -1, -5, 8, 1, -4, 1, -9, -2, 5, 6 }, - { -11, 14, 1, -31, -7, -24, 9, 7, 6, 5, -13, 1, -1, 3, 4, -1, - -2, -8, -6, 3, 5, -4, -6, 7, -2, 5, 3, 3, 0, 0, -5, 2 }, - { -25, 8, -11, -18, 1, -4, 8, -3, -4, 15, 6, -5, 8, 2, 3, 4, - -4, 5, 6, 8, -7, 6, 1, -11, -15, -13, 9, -4, -14, 10, 12, 7 }, - { -20, 11, -15, -25, 3, 4, 18, 13, -4, -5, -9, -1, -5, -2, -2, -7, - 16, 5, -4, -5, -7, -2, -3, -9, 11, -2, 0, -7, -17, -6, -11, 6 }, - { -11, 18, -5, -20, -15, -3, 9, 11, -20, 12, 5, 5, 11, -3, 7, 1, - 10, -6, -3, -3, 3, 3, 14, -7, 10, -17, 9, -11, -2, -6, 7, -12 }, - { -20, 8, -14, -17, -9, -13, -3, 0, -27, -14, -3, -14, 4, 3, 6, -6, - 7, 4, 23, 9, 11, 9, 3, -4, 9, 2, 4, -1, -6, 1, -8, -11 }, - { -9, 14, 2, -37, -7, 13, 6, -11, -6, 9, 18, -11, -6, 2, 12, 4, - -1, 3, 1, -2, -2, 1, -9, -4, -2, -3, 3, 5, -6, 0, -2, -8 }, - { -29, 8, -1, -13, -2, 8, 23, 2, -10, 7, 13, -6, -5, 11, 13, 0, - -10, -13, 11, -12, -10, 6, 4, 6, 4, 3, 6, -5, -9, -2, -1, 3 }, - { -18, 6, -10, -55, -4, -11, -2, 0, 1, -3, -9, -6, 3, -2, -1, 6, - 3, -1, 3, 1, -4, -7, -2, 6, 3, -2, -1, -3, -2, 0, 4, 1 }, - { -14, 5, 3, -21, -8, -16, -4, -2, -11, 27, 15, -20, 3, 0, 1, 1, - 2, -5, -5, 4, 1, -9, 5, -3, 3, 0, -4, -2, -11, -4, -3, 7 }, - { -17, -1, -9, -17, -8, -18, 12, -13, -9, 13, -3, 3, 3, -3, 1, -2, - 0, 16, -9, 6, 12, 9, 5, 11, 2, -15, 1, -4, -16, 7, -4, -12 }, - { -18, 8, -6, -11, -8, -7, 13, 7, 1, 6, 8, -1, 21, -4, 14, 15, - 18, -4, -3, 15, 0, 9, 4, 7, 3, -1, 9, -2, 0, 7, -8, 2 }, - { -10, 7, -18, -29, 3, 12, 12, 9, 11, 4, -1, -15, 1, -1, 8, -2, - -2, 10, -15, -1, 0, 6, 12, -6, -1, 10, -6, -3, -11, -4, 9, -6 }, - { -14, 14, -9, -21, -12, -2, -1, -7, -5, -10, 5, -8, 0, 6, 9, -11, - 11, -3, -5, 3, 8, 15, -2, -4, -22, 4, -6, 12, 2, 13, 6, -7 }, - { -12, 11, -5, -29, -25, 4, 12, -13, -11, -7, 4, 2, 2, -5, 5, 8, - 7, -5, -5, 6, 3, -10, 1, -6, 6, -6, -5, -1, -2, -4, 7, 6 }, - { -15, 11, -5, -16, 0, -13, 26, -23, -6, -3, 5, -2, -2, 21, -6, -3, - -5, -1, 6, -1, 0, -13, 2, -3, -9, -1, -4, -3, 5, -4, 12, -16 }, - { -9, 9, -1, -17, -3, -6, 12, 6, -18, -2, 11, -14, -6, 3, 14, -12, - -11, -5, 14, 2, 5, -8, -4, -11, 2, -5, 16, 6, -7, -4, 8, 13 }, - { -13, 5, 3, -28, -14, 0, 6, 23, 5, 4, -1, -17, 1, -3, 0, 0, - 5, 4, 0, -18, 14, 10, 4, 2, 5, -2, 4, -3, 2, 0, 2, 0 }, - { -15, 4, -13, -16, -3, -12, -2, 2, 7, 10, 9, 3, 11, 4, 23, 14, - 9, 16, 4, 1, -12, -3, 4, -7, -15, -7, -10, -14, -6, -8, -1, -6 }, - { -7, 10, -5, -10, -3, -13, 16, -1, -12, 7, -3, -12, 2, 13, 13, 2, - 17, 15, -13, 1, -5, -2, 3, -1, 1, -3, 6, -3, -12, -16, 7, -7 }, - { -11, -5, -12, -30, -6, -22, 1, 4, -6, -3, 12, 6, 7, 0, 16, 6, - -2, 0, -22, -2, -9, 2, -13, 8, 6, -8, 4, -7, -1, -6, 4, 6 }, - { -14, 5, 1, -27, -4, 2, 1, 14, -11, -7, -8, -4, 1, 8, 0, -6, - -13, 11, -12, -7, -5, 1, 10, 7, 3, -2, 0, 6, -8, 2, 10, -1 }, - { -10, 10, -25, -13, -20, -4, 19, 3, 13, 5, 5, 7, -8, 2, 4, 2, - 3, -1, -1, -9, 14, 10, 9, 14, 3, 3, -6, 0, -5, 4, 1, -1 }, - { -9, 15, -18, -17, 4, -11, 6, 7, -12, 8, -1, -11, 2, 3, 7, 16, - -3, -9, 7, -12, 23, 0, 6, 7, -14, -9, 8, 1, -2, 6, -2, -1 }, - { -6, 9, -16, -26, -14, -11, 9, -6, 5, -2, 13, 17, 21, 7, 18, -19, - 6, -23, -2, -15, -2, 2, -10, -8, 2, 1, -2, 4, -3, -4, -5, -4 }, - { 0, 6, -5, -28, -17, -32, 2, -10, 11, 3, -5, 9, 10, 3, 11, 11, - -3, 12, -2, 2, 4, -6, 9, -4, -4, -4, -4, -9, 2, 0, 2, 4 }, - { 0, -8, -18, -34, -9, -7, -4, -11, 10, 15, 11, -1, -8, 15, 6, -13, - 9, 2, -4, -12, 0, -1, 19, 12, 6, 5, 0, -3, -10, -12, 3, -5 }, - { -10, 6, -9, -17, -12, -11, 9, -6, 11, 11, 18, -7, 0, 16, 4, 2, - -6, 3, -12, -1, 0, 1, -5, -22, -2, -12, 0, 6, 17, 5, 5, 6 }, - { 12, -5, 7, 1, -5, -2, -1, 2, 2, -4, -3, -3, -3, -2, -29, 11, - 5, -13, -73, 24, 12, 4, -14, -10, 5, 1, 0, -11, -7, -7, 7, 3 }, - { 10, -3, -1, -3, 4, -11, -5, -2, -8, 7, 9, 2, -8, -6, 6, 7, - 21, 17, -54, 47, -14, -10, 14, 19, 13, 21, -4, 3, 1, 2, -4, 2 }, - { -12, 4, -16, -12, 5, -9, -4, 19, -7, -22, -22, -17, 3, 0, -6, 8, - 23, -4, -55, -28, 2, -26, 2, 1, 4, 0, -13, 6, 0, 10, -7, -11 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, - 35, -1, -67, -35, -24, -24, -6, 2, 2, -2, 1, 3, 2, 0, -1, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0, - 41, -4, -73, -15, 18, 4, 17, 8, -1, -16, -1, -2, 1, 0, 0, 0 }, - { -4, -4, 4, 6, -1, 2, -16, -10, -15, -10, 21, -2, -6, -2, 14, -7, - 10, -5, -55, 34, -12, 11, -13, -2, 2, 28, -26, 0, 7, 4, 21, -7 }, - { 2, 1, 15, -22, 10, -3, 14, -6, -2, 15, -2, -7, 20, 6, -15, -7, - 23, 10, -60, 8, -4, 29, -22, 2, -13, 9, -10, 12, -1, -3, 4, 7 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -2, 11, -5, - -21, -11, -60, -27, -17, -39, 6, 36, 0, -8, 2, 2, 0, 0, -2, 3 }, - { 2, -5, 9, -17, -1, 2, -3, -6, 8, 12, 7, -6, -33, -11, -14, -40, - 10, 36, -46, 0, -19, 5, 0, -10, 3, 12, -6, -8, 6, -12, -7, 1 }, - { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, -2, 0, - 4, -2, -87, -3, -2, 2, -2, 20, 2, 6, -1, 6, 0, 0, 2, -1 }, - { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, - 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, - { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, - -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, - { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, - -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, - { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, - 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, - { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, - -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, - 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, - { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, - 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, - { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, - -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, - { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, - 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, - -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, - -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, - 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, - { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, - -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, - { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, - -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, - { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, - 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, - { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, - -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, - 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, - { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, - 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, - { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, - -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, - { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, - 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, - -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, - -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 16, 65, -2, -2, 4, 3, 0, -7, 3, 1, 3, 1, 0, 5, 1, -5, - 0, 2, -1, 3, 0, 0, -1, -2, 6, 0, -2, 0, 0, -1, 1, 1 }, - { 5, 37, -4, 8, -4, -1, 9, 17, 6, -7, 5, -1, 11, 6, -4, 7, - -2, 4, 1, -3, 11, 3, 3, -9, 6, 0, -2, -4, -5, 4, -12, -11 }, - { 15, 24, -14, 2, 6, 17, 26, 5, 8, 11, -9, -7, -6, -8, 3, -5, - 9, 10, -3, 10, 0, 1, 4, -9, 4, 9, 3, 0, 4, 0, -5, 3 }, - { 9, 36, -9, -8, 7, 7, 4, 3, -1, -16, -2, 7, -5, -6, 6, 12, - -11, -12, 9, -1, -3, -9, 12, 6, -6, 2, 2, 5, 0, 5, 6, -6 }, - { 25, 39, -5, 24, 3, 10, 3, -6, 13, -8, 3, -7, 2, -10, -5, 2, - -2, 3, 5, -2, 1, 5, -2, 3, -4, 1, -5, -4, 0, 1, -2, 0 }, - { 16, 27, -1, 0, -14, 6, 4, -5, 7, -2, -6, 0, -3, -5, 2, -1, - -1, -19, 5, -8, 0, 11, 12, 5, 0, 3, 10, 6, -14, 14, -13, -15 }, - { 12, 23, -14, 2, 1, 4, -3, 16, 7, -8, 2, -8, 8, 6, -8, -7, - -3, 0, 2, 8, -13, 7, 13, -6, -4, 6, -13, -16, 14, 11, -7, 5 }, - { 16, 28, -7, -1, 6, -3, 9, 0, -7, 3, 0, 3, -12, 20, 8, 9, - 8, 23, 8, -13, -2, 4, 9, 3, -5, 13, 5, -2, 12, 14, 5, -1 }, - { 19, 37, 19, 5, 7, 5, 10, 5, 19, 10, 14, 0, 2, 5, 1, -4, - -4, 2, 2, -5, -2, -1, 2, -6, -4, -4, -5, -3, 2, -2, -2, -2 }, - { 24, 21, 1, -11, -10, 17, -14, 14, 6, -1, -6, -1, 0, -13, -1, -12, - -2, -5, 6, -4, -12, 14, 5, -2, -8, -8, 15, -7, -30, -12, 4, 0 }, - { 11, 26, -3, 3, 5, -1, -2, 3, -2, 10, 15, -4, 10, -28, 10, -17, - -8, 1, 2, -7, -1, -6, -15, -1, 4, 5, -7, 9, 0, -5, -4, 4 }, - { 18, 32, 1, 2, -7, 4, 15, 2, -9, -2, 12, -11, 7, 11, 13, 2, - 0, 5, 9, -10, 16, 3, -3, 5, -9, -23, 2, -2, -1, 5, 2, 11 }, - { 35, 24, -20, 2, 4, -1, 5, 14, -10, -9, 8, -7, 0, 5, -7, -7, - 11, 1, 5, 3, 2, 0, -2, 3, 0, 1, 4, 0, -2, -8, 0, -4 }, - { 9, 35, -1, 2, -1, -19, -3, 12, -1, 8, 8, -13, -1, -2, 2, 5, - -8, -1, 13, -2, 11, 1, 0, -10, 0, -3, -7, 2, 1, -12, 3, 12 }, - { 20, 27, -12, -12, 7, 4, -1, -13, -1, -9, 2, 13, -11, 5, 7, -9, - 9, 1, 1, 8, -9, 0, -6, 7, 4, 2, -2, 7, 3, -2, 1, -9 }, - { 8, 37, -20, -5, 0, -21, 10, -8, 3, 19, -9, 7, -3, -8, 10, -2, - 0, 5, 6, -4, -2, -1, 0, -7, 6, 1, 0, 4, -5, 6, -8, 2 }, - { 8, 27, 1, -3, -5, 1, 6, 0, 15, 2, 17, -1, 3, -17, 10, 5, - 5, -6, -6, 6, -10, 18, -5, 0, 0, 13, 7, 10, -5, -6, -2, -4 }, - { 14, 29, -20, -4, -3, 1, -5, -1, 2, 12, -10, -3, 4, -18, 4, 14, - -4, -1, -9, 15, -2, 2, -5, -3, 2, 9, -2, -14, -3, 4, -4, -7 }, - { 23, 23, -23, -11, 27, 4, 4, -1, 7, 0, -5, 9, 2, -11, 3, 7, - -2, -5, 2, -7, -7, 13, -3, -6, 2, 3, 3, -4, -1, -8, 5, -2 }, - { 16, 26, -6, 8, -9, -1, -2, -1, -8, 4, -2, 0, -12, 9, -1, 0, - -17, -9, 30, -5, -15, -16, -13, 0, 10, -11, -7, -3, -1, 0, -11, -2 }, - { 12, 32, -4, -5, 10, 19, -10, 4, -12, 5, -6, 9, -12, -6, -6, -8, - 4, 1, 3, 0, 8, 0, -3, -4, -7, -4, 10, 8, 6, 5, -1, 4 }, - { 46, 42, -3, -14, -2, -6, 6, -2, -5, -1, -3, -3, 1, -1, 3, 1, - 1, 4, -1, 2, 3, 1, -2, 6, 0, -1, -2, 4, -2, -1, 2, 2 }, - { 9, 33, -13, 4, -11, 3, -8, 22, 12, -2, 4, 0, -16, 5, 4, -1, - 7, -6, -9, 1, 7, 5, 0, -5, 5, -1, 10, 3, -2, -1, 3, -2 }, - { 9, 30, 6, -3, 6, 1, -7, 5, 11, 14, 7, 1, 0, 2, 2, -1, - 8, 7, -6, -13, -10, -2, 1, -6, 10, 7, 6, 5, -2, -5, -1, -16 }, - { 9, 28, -11, -10, 9, -10, 15, 8, 4, 9, -4, -7, 0, -5, 9, 8, - -7, 2, -15, -23, 4, -4, 4, 16, -8, -3, 0, -8, 14, 5, -3, 15 }, - { 17, 26, -5, -5, -1, -8, 20, 18, -7, -2, 4, -7, -8, -5, -4, 16, - 0, 0, -7, -2, -13, -5, -2, 3, 12, 1, 3, -5, 2, 2, 0, -1 }, - { 11, 37, 7, -23, 6, -1, 15, 13, 4, -9, 7, 5, 3, -3, -5, -8, - -2, 3, -5, -1, -8, 7, 2, 13, 1, 3, 0, -3, -1, 2, 0, -2 }, - { 21, 33, 7, 20, 21, -10, 6, -5, -5, -6, -9, 2, 10, 0, 8, -4, - 10, 2, -2, -2, 0, -10, -6, -2, 0, -5, 3, -11, 3, -9, -3, 1 }, - { 6, 30, -15, -8, 16, 1, 4, 6, 4, 5, 8, -3, 8, -9, -1, -6, - 8, 2, -2, 4, -2, 5, 11, -21, 3, -10, 16, -11, 24, 10, 14, -6 }, - { 15, 36, -3, -9, -20, 12, 0, -7, -18, -4, -8, -9, 9, -7, -3, -1, - 2, 7, -5, -8, 6, 2, 2, -1, 7, 1, 1, -3, 3, -4, -8, 1 }, - { 16, 34, 21, 3, -9, 10, 7, 9, -7, 1, -4, -9, -4, -5, -5, 3, - 3, -19, 1, 5, 4, -2, -6, -5, -10, -11, -8, -2, 2, -5, -8, -7 }, - { 28, 29, -3, 18, -2, 0, -6, 12, -2, 10, -11, -4, -13, -12, -6, -4, - 0, 4, -1, -8, 6, 4, 12, 11, 10, 10, -3, -6, 1, 2, 1, 7 }, - { 3, 8, 22, -8, 3, 36, -8, -1, 9, 6, -13, -14, 8, -1, 1, 2, - -2, -8, 0, 3, 1, 2, -1, 5, -1, -8, 0, -2, 2, 2, -1, 1 }, - { 0, 6, 0, 0, 4, 13, -7, -16, -6, 15, -14, -21, -9, -10, -10, -6, - -21, 5, 4, 2, 12, 4, 12, 11, -4, -6, -6, -10, -7, -18, 1, 4 }, - { -1, 3, 10, 1, -1, 15, 4, -7, -16, 3, 0, -22, 10, 2, -3, -2, - 13, 5, -8, 16, -5, 4, 0, -11, -10, -22, 0, -4, -17, 5, 2, 1 }, - { 12, 8, -4, -9, 14, 40, -21, 0, 1, -15, -10, -12, 12, 6, -10, 2, - 8, 6, -12, -10, -11, 1, 0, -11, 2, 1, 13, 0, 6, 3, 8, 4 }, - { -10, 3, 5, -4, -3, 3, 0, -9, 2, 8, -22, -23, 17, 8, -17, -3, - 14, -8, -4, 1, -8, 3, 0, 5, -1, -3, -2, -4, 1, -10, 0, -2 }, - { 0, -1, 5, -7, 4, 12, -2, 0, -7, 2, -16, -15, 12, 21, -7, -4, - 7, -7, -11, -15, -7, -9, -5, -8, 0, -6, 8, -3, -8, 22, -7, -9 }, - { 7, 19, 4, -9, 24, 22, 2, -6, 8, 13, -14, -20, -4, 11, 8, -4, - -1, 2, 0, -7, 5, -17, -3, 3, -6, 5, 3, 4, -5, -7, -3, 14 }, - { -2, 6, 2, 8, -2, 5, -4, -2, -10, 3, -45, -30, -3, -3, -12, -4, - -3, -3, -1, 9, -6, -6, 5, -4, 0, 5, -1, -2, -1, 0, -6, -1 }, - { -3, 14, -16, -10, 10, 0, -2, -40, -9, 12, 2, -19, 15, -4, 4, 3, - 3, -4, 7, 1, -4, -5, 0, 4, -1, 0, -9, -2, -4, -1, -2, 0 }, - { 7, 16, 2, -7, 8, 2, 0, 1, 5, 21, -10, -26, 7, 2, -9, -7, - -3, -16, 8, 5, 5, -6, 10, 4, -14, -6, 5, 3, -2, -2, -4, 1 }, - { -9, 14, -1, 3, 3, 11, 1, -5, -3, 13, -16, -18, 20, 6, -5, 0, - -3, 2, 8, 4, -19, -9, 12, 0, -8, 2, 2, 1, 6, 13, -7, -11 }, - { 2, 5, 16, -4, 19, 15, 4, 0, -11, 7, -10, -10, -16, 18, -11, -12, - -9, -4, 7, -4, -4, -17, 1, 1, -8, -3, -3, 5, -2, -6, -11, -5 }, - { 2, 12, 0, -9, -10, 14, 6, 2, -3, 2, -12, -28, 12, 1, -1, 2, - 0, -3, -4, 7, 16, 5, -7, 8, -4, -3, -1, 3, -12, 4, -17, -5 }, - { -4, 7, 11, 6, 1, 14, -4, -6, 5, 5, -6, -24, 23, -9, -15, 13, - -7, -9, -15, 10, -1, 8, -5, 1, 12, 6, 2, 0, 4, -2, 9, -10 }, - { 1, 5, 11, 3, 6, 12, -3, 8, -21, 5, -7, -20, 12, -2, -9, -3, - 17, -7, -8, -9, -14, 3, -13, 18, -8, 9, 2, -8, 4, -8, -5, -2 }, - { -3, -3, -1, 5, -2, 15, 3, 2, 1, -8, 1, -39, -6, 13, -13, 0, - -2, -5, -6, -3, 0, -5, -2, 15, -9, 5, -3, -6, -2, 7, 0, -13 }, - { 2, 8, 5, -12, -13, 22, 8, -16, 11, 5, -2, -32, -2, -4, 11, 5, - 5, -6, 1, 3, 1, 5, 3, 6, -5, 4, 4, -8, 8, 4, 1, 3 }, - { 13, 9, 5, -4, 9, 18, -11, 2, -1, 15, -10, -19, -2, 14, 0, -10, - 1, 1, -18, 3, 2, -6, -8, 20, 7, -8, 16, 9, 9, -13, -3, -2 }, - { -13, 11, 11, -9, -10, 13, -3, -18, 2, 10, 5, -21, 6, 15, -11, -21, - 3, 14, 0, -12, 9, -1, -2, -4, 3, -3, -9, -8, -5, -2, -8, 2 }, - { 3, 3, 11, 4, 0, 13, 1, -8, 10, 13, -6, -26, 2, 12, -3, -5, - 12, -2, 1, 8, -7, -17, -19, 5, 10, 7, -3, 2, -3, 0, 5, 0 }, - { 5, 0, 3, -3, -9, 5, -15, -5, -5, 17, -5, -31, 0, 13, 13, 5, - -1, -6, -14, 7, -8, 9, -14, -2, -16, -4, -4, -6, 6, -6, -10, 6 }, - { 13, 3, 1, 7, -3, 4, -1, -2, -1, 4, -8, -32, -1, -4, 0, 3, - -10, 7, 10, -10, 4, -1, 6, 2, -16, -9, 4, 3, 13, -23, -3, -4 }, - { 4, 11, -4, -9, 4, 11, -12, -12, -12, 6, 1, -28, -3, 14, 18, -2, - -12, 7, 15, -3, -5, -7, -3, 2, -6, 4, 4, -2, -5, -3, 2, -13 }, - { 8, 7, -7, 0, 13, 7, -8, -7, 8, 36, -10, -22, 3, 23, -3, -10, - -3, 11, 1, -7, 3, 3, -1, -7, -4, 2, 3, 2, 5, 3, -4, -1 }, - { -1, 1, 13, 1, -6, -1, -6, -9, -18, 17, -5, -37, -1, -1, -6, -4, - 1, -6, -15, 2, 17, -9, 0, -3, 0, 4, 0, -5, 0, 4, 1, -5 }, - { 0, 14, 5, 0, -7, 2, -6, 17, -6, -9, 7, -16, -5, 23, -14, -13, - 8, -15, 11, 10, -11, -13, -33, -5, -2, 1, 6, 8, 0, -13, -9, 5 }, - { 11, 7, -2, -8, 9, 11, 25, -14, 7, 3, -1, -33, 14, 8, -6, -19, - 3, 3, 2, -1, -3, -1, -2, -10, -3, 1, 2, 1, 4, 2, -3, 4 }, - { -2, 8, 4, -2, 9, 13, -4, -2, -15, -3, 19, -37, 9, 25, -9, 2, - -5, -2, -2, -4, 4, 2, 2, 0, 3, 3, 3, 5, -2, -3, -4, -3 }, - { 10, 13, -1, -15, 4, 6, -18, -4, 25, 1, -23, -17, 15, 13, -8, -8, - 7, 4, -5, 3, 6, 9, -7, 6, 0, -5, 8, 0, -6, -1, -2, -2 }, - { 1, 3, 9, -5, 27, 15, -9, -31, -1, 23, -2, -9, 1, 8, -1, -7, - -2, -8, -4, -4, -2, -1, 3, 5, 0, 0, -1, 1, -7, 7, -3, -3 }, - { -8, 7, 3, -6, 8, 3, -11, -2, 36, 14, 1, -30, 6, 10, -12, -6, - -6, -2, -4, -3, -5, 0, 9, 4, -5, -5, -8, 12, 4, -3, 1, -8 }, - { -2, 9, 33, 0, 12, -3, -7, -4, -4, -1, 6, -25, 11, -6, -9, -11, - -2, -4, -2, 6, -1, -3, -6, 15, -6, 3, 10, -4, 1, 0, 5, 8 }, - { -22, -21, -9, -19, -5, -7, -12, -15, -8, 9, -19, 14, -7, -4, 5, -8, - -2, 7, 1, -3, 4, -4, 6, 11, 2, 6, -3, -5, 2, -2, 0, -3 }, - { -32, -13, 3, -24, 3, -8, 4, 1, -10, 14, -15, 0, 4, 6, -1, 6, - 7, -1, 6, 4, -3, -17, 1, 4, -6, -1, 1, 0, 3, 3, -7, -4 }, - { -32, -11, 7, -8, -12, 13, -5, -22, -4, 12, -16, 2, 0, 4, 0, 1, - 0, 6, -5, -8, 2, 6, 5, 0, -3, -6, 5, 6, 5, 5, 13, -4 }, - { -44, -33, 6, -4, 2, 0, -9, 10, 3, 4, 7, 0, -1, 7, 5, 1, - 1, -3, 1, 6, -1, 0, 2, 3, -4, 0, 0, 1, 0, -1, -2, -1 }, - { -30, -18, -24, -8, 5, 0, -2, 14, 7, 0, 1, 12, 6, 4, -9, 7, - 5, 7, -11, -5, 1, -8, -1, 2, 2, -9, 7, -1, 7, 5, 6, 6 }, - { -22, -20, -13, -9, 20, -3, 10, -8, 6, -4, 2, -7, 10, 8, 0, -1, - 2, -3, 6, -19, 2, 4, 3, 3, -7, 2, -1, -6, 1, 1, 6, -2 }, - { -27, -8, -1, 3, -1, -11, 24, 4, -1, 1, -8, 8, 5, -11, 15, -3, - -15, -1, -1, -13, -1, 1, -5, 5, 2, 3, -9, 0, 4, 3, -7, 6 }, - { -33, -16, -1, -8, 10, -23, 6, 13, -1, -3, -9, 0, 5, -7, -5, -12, - -2, 3, 3, 6, -2, -3, 2, -3, 9, -6, -3, -2, 0, 5, -3, -4 }, - { -22, -17, 11, -3, 3, 1, -1, -5, 17, 2, -15, -2, 10, -9, 6, 14, - -16, -12, 20, -1, -7, 6, -3, -12, 1, 10, -10, -1, 7, -3, -1, 10 }, - { -28, -13, 1, -3, -1, -1, 0, 3, 3, 5, 1, 10, -10, -3, 7, 2, - 4, 19, -1, -1, 10, 5, -8, 1, 11, -15, -4, -3, -5, 4, -13, 3 }, - { -22, -13, 42, -20, 5, -13, 7, -11, 1, 1, -1, 1, 6, 3, 6, -11, - 3, 3, -2, 0, -4, 4, -3, -1, -5, 2, 0, 0, -9, -1, 4, 4 }, - { -26, -15, -2, -6, -4, -2, 16, 8, 21, 8, 1, -3, -10, 7, -8, -12, - -5, 12, -9, 3, -2, -3, 18, 1, -12, -15, -4, 5, -3, 0, 12, 7 }, - { -26, -16, 5, 6, 14, -3, 15, 6, 1, -7, -13, 16, -15, 5, 11, -2, - 9, -7, -4, -2, 0, 0, -2, 7, -8, -6, -5, 2, 7, -3, 2, 12 }, - { -31, -17, -8, -30, 4, 14, 6, -6, 6, -11, 0, 3, -4, 0, 0, -4, - 0, -4, 1, 4, 3, 4, 0, -5, 3, 2, 2, 0, 2, 1, 3, 5 }, - { -61, -10, 4, 10, 4, 7, 0, -3, 0, 1, 0, -3, 0, 1, 0, -2, - -1, 1, 2, -2, 4, -3, 1, 1, -1, 1, -2, -4, -4, 4, 0, 0 }, - { -28, -13, -8, -4, 3, -3, 2, 1, 11, 14, 3, 9, 1, 13, 3, 5, - -3, -2, -2, -12, -14, -9, -11, -15, -12, -5, -4, -12, 3, -3, 0, -5 }, - { -41, 0, 12, -24, 13, 4, 5, 16, -5, -4, 0, 0, 13, -4, 1, -9, - 9, -6, -1, 6, -2, 5, 2, 9, 6, -9, -8, 8, -2, -3, -6, -4 }, - { -26, -19, -2, -15, 4, -14, 6, 0, 26, 20, 8, 9, 9, 3, -4, -5, - -8, 1, 0, -1, 5, 9, 3, 4, 4, 7, 1, 3, -2, -2, -10, 0 }, - { -29, -18, 9, -4, 1, -5, -14, -12, 5, -10, -5, 4, -5, 0, -1, -1, - 4, -5, 7, -16, -11, 2, 7, -15, 2, -4, 6, -4, -6, 7, -3, 7 }, - { -27, -16, 9, -14, 3, -8, 9, 0, 7, -4, -3, -7, 0, -10, -1, 2, - 1, -2, 15, -10, 14, 7, 6, 17, 3, -4, 3, -10, 8, -8, 3, 11 }, - { -21, -20, -8, -8, 4, 5, -3, -2, 0, -5, 14, -10, 11, -4, 13, 0, - 5, -11, 19, -18, 18, 3, -5, -3, -4, -8, 11, -10, 10, 3, 4, -9 }, - { -35, -15, 13, -12, 4, 0, -2, -4, -12, -3, -8, -24, -7, 1, 7, 8, - -3, 0, -2, -1, 3, -2, -2, -6, 8, 1, 0, 1, -6, -1, 2, -6 }, - { -19, -14, 13, -10, 9, -1, 1, 3, -12, 5, -16, 7, 13, 9, 4, -4, - 6, -5, 4, 9, -3, 17, -4, 12, -11, -6, -5, -6, 13, 2, 7, -9 }, - { -34, -8, -4, 1, 2, -1, 3, 6, -20, -11, 8, -1, 4, 2, -9, 4, - -4, -5, 16, 10, -4, 14, -13, 1, -6, 0, 2, -10, 0, -3, -3, 7 }, - { -36, -10, -8, -3, 2, -2, 14, -4, -1, -7, -4, 10, -1, -3, 15, -11, - 0, 2, 3, -1, 4, 0, 8, -1, 0, 18, -11, -5, 15, -5, 13, -12 }, - { -22, -13, 14, -20, 15, 25, 16, 10, 8, -2, -10, -5, -1, -8, 11, 8, - -1, -2, -4, 1, 2, -1, -7, 0, 0, 0, -3, 0, 2, -1, 0, 2 }, - { -31, -22, 7, 6, -2, 5, -20, 14, -6, 7, 0, 14, 3, -7, 3, -6, - -2, 1, -3, -5, 1, -10, 1, -24, 6, -2, 3, -7, 1, -7, 8, 7 }, - { -25, -20, -3, -9, 10, 6, 12, 7, 5, 4, -3, 6, -1, -5, -6, -8, - 3, 5, 6, 5, -10, 10, -4, -15, -15, -2, -9, 2, 18, 1, 8, 12 }, - { -24, -19, -2, -4, -7, 11, 6, 9, 16, 2, -7, 18, 6, -7, 6, 6, - -2, -9, 3, 12, -2, 3, -1, 6, 7, 8, 0, 8, -11, 8, 4, 2 }, - { -26, -20, -12, -12, -2, -3, 1, -5, -1, -2, 0, 3, 7, 9, -2, 2, - 9, 22, 13, 4, -4, -1, -2, -14, 5, 15, -8, -5, -7, -11, -14, -6 }, - { -21, -18, -1, -4, 0, 3, 7, -2, 10, 8, -8, -1, 15, 1, -9, 3, - 1, 3, -5, -2, 2, 4, 0, -1, 10, 2, -19, -8, 8, 30, -7, 8 }, - { -25, -6, 26, 4, -8, 4, -2, 21, 5, -4, -16, 5, 13, 4, -10, -1, - -6, -2, 2, -10, -13, 1, 3, -3, -6, -8, 2, 11, 1, -7, 0, 5 }, - { 0, -1, -2, 19, -12, -48, -6, 11, 8, -2, -4, -2, -7, 5, -3, 2, - -2, -1, -1, -7, 0, -3, -3, -4, -4, 4, 1, 3, -3, -1, -2, -5 }, - { -11, -8, -28, 18, 16, -24, -8, 19, 4, 8, -12, 9, -4, -2, 4, -7, - 6, 2, 3, 3, -4, 0, 1, -6, -4, -2, 2, 6, 0, -3, 1, -16 }, - { -9, -5, -26, 7, -3, -37, -16, -2, 2, -7, 4, -13, 0, -4, -6, -5, - -6, -4, 0, 3, 4, -3, -4, -4, 4, -3, 9, -4, -2, 2, 7, -4 }, - { 2, 9, -18, 7, 29, -24, -1, 7, 14, 10, 3, -3, -2, -5, 6, -10, - -6, -3, -8, 0, 5, 1, 4, 3, -12, 2, 6, 1, 3, 4, 1, -3 }, - { -20, 2, 8, 20, -9, -24, -4, 18, 3, 11, -1, -11, 6, 9, -1, -3, - 1, -1, -15, 3, 15, 9, 3, 2, -13, 2, -8, 8, 1, -1, 1, -8 }, - { -12, 5, -11, 6, 19, -26, -17, -6, 4, 14, 6, -8, 9, 5, -6, -5, - 2, -1, 20, 1, -11, -10, -18, 20, -7, 0, -3, 4, 2, 0, 10, 4 }, - { -15, 1, -2, 13, -8, -21, -22, 4, 4, 3, 3, -7, -31, 4, -10, -14, - 0, 8, 4, 5, 8, 11, 2, -8, 6, 7, 0, -2, 6, 8, 8, 7 }, - { -13, -10, -9, 12, 19, -16, -3, -2, 9, 2, 11, -29, -1, 9, 4, -3, - 1, -10, -10, 16, 1, 7, -7, -6, -4, -1, -5, 3, 6, 0, 3, 1 }, - { -17, -1, -5, 19, 12, -9, -21, -5, 2, 12, -7, -7, -3, 8, 7, -2, - 6, -9, -9, 1, -4, 1, 1, 3, -14, 2, -8, 0, 10, 1, -12, -6 }, - { -13, -5, 8, 15, 0, -20, -2, 20, 8, -8, 8, -19, 12, 10, 2, -11, - 0, 12, 1, -11, 0, -11, -15, 5, -11, 2, 4, -4, -11, 5, -4, -5 }, - { 3, -11, -7, 8, 0, -17, -26, 15, 19, -7, 10, -9, -5, -5, 14, -25, - 0, -8, 2, -9, -3, 9, 1, -6, 4, -4, 3, -9, -1, 6, 2, 2 }, - { -12, 5, 5, 9, 14, -18, -19, 4, 2, 16, 14, -21, -15, -9, -1, 16, - 12, -11, -10, -5, -7, 4, 15, -8, -5, -1, 1, 14, 13, -7, -1, -4 }, - { -10, -5, -1, 8, 7, -23, -10, 14, 6, 11, 10, -16, -3, 16, 6, 0, - 0, 9, 6, -2, -7, 1, 22, 5, 3, -8, 0, 3, -2, -10, 3, 0 }, - { -2, -14, 2, 16, 15, -17, -17, 6, 19, 4, -10, -15, -1, 15, 11, -14, - -8, 5, 8, 8, -2, -8, -11, 10, 10, -8, -14, 2, 13, 4, -2, -12 }, - { -10, 3, 6, 4, 19, -23, -19, 1, 4, -9, -30, 3, -6, 18, 0, 2, - 0, -11, 0, 3, 7, -2, 8, 5, 2, -3, 6, -9, 1, -4, 7, -6 }, - { 9, 5, -2, 21, 20, -33, -13, 7, -10, 8, 8, -15, -6, -4, 1, 5, - 3, 7, -2, -9, -1, 4, -6, 1, 0, 9, -1, -5, 2, 1, -3, 3 }, - { -9, -3, 3, 15, -3, -30, -7, -7, -25, 6, 2, -6, 1, 19, 1, -12, - 1, -8, -13, 9, 13, 1, 8, 2, 5, 15, -2, 3, -9, 0, -4, 4 }, - { -6, -12, -17, 25, 22, -13, -10, 9, 2, 11, -7, -16, 4, 6, 1, 0, - 0, 18, -4, -5, 4, -2, -1, -5, 0, -4, 6, 1, 6, -1, 7, 0 }, - { -1, 0, -10, 8, 8, -27, 0, -2, 29, 16, -2, -4, 9, -1, 2, 0, - 6, 10, 6, 4, 2, -7, 9, -18, 3, 3, 3, -10, 17, 10, 9, -6 }, - { -3, -12, -6, 11, 20, -32, 5, 21, 3, -4, -9, 2, -10, 1, 7, -4, - 5, 0, 0, -1, -8, -9, -7, 4, -10, 5, 0, 2, -5, 4, 9, 1 }, - { -5, -1, -5, 1, 2, -19, -13, 1, 6, 12, 2, -16, -17, 11, 10, 13, - 16, -12, -11, 3, -6, 0, 6, 4, -3, 1, 8, 2, 5, -11, 3, -14 }, - { -19, 5, 10, 11, 2, -23, -9, 16, -2, 7, 0, -11, -7, 10, 6, -7, - 26, -15, -4, 8, 6, -4, 7, -9, -15, 1, 8, -4, 4, 2, -12, 16 }, - { -11, 1, 11, -4, 1, -31, -13, -1, 8, 5, 4, -2, 0, 13, 7, -17, - 7, -10, -6, 1, 4, -1, 2, -9, -4, 9, 3, 3, -4, -5, 3, 4 }, - { -3, 1, 10, -1, 0, -15, -22, 4, 40, -11, -4, -3, -14, 9, 11, -1, - 9, -1, -6, 6, 3, -6, 0, 0, -12, 7, -2, 0, 9, 3, 1, 3 }, - { -1, -1, -1, 14, 8, -24, -14, -8, 5, 8, 5, -12, -17, 8, 2, 7, - 10, -8, 0, 4, -6, -6, -10, 8, 4, -12, 3, -9, -12, 5, 4, -3 }, - { -5, 1, -11, 8, 9, -24, 0, 2, 2, 14, -12, -13, 1, 6, 7, 0, - 7, -6, 9, 26, 11, -14, 8, 10, 1, 9, 0, 11, -2, 6, 2, -10 }, - { -13, 1, 4, 34, 19, -17, -15, 0, 3, -2, -7, -1, 0, -3, -3, -1, - 1, -1, -10, 8, 5, 0, -8, 4, -17, 9, -2, 0, 0, 6, 2, -3 }, - { -6, -4, 1, 2, 2, -14, -29, 0, 9, 34, -3, -5, -14, 6, -10, -9, - -5, -1, 0, 3, 3, 0, 1, -1, -2, -1, -1, -3, -3, -4, 3, -3 }, - { -4, 6, 3, 14, 14, -8, -29, 31, 11, 14, -4, -5, -6, 10, 6, -9, - -1, -11, -7, 1, 7, 4, 1, -6, 4, 0, 10, -7, -5, -1, 2, 4 }, - { -4, -4, -2, 14, 6, -32, -6, -14, 14, -5, -11, 10, -18, -4, 6, -8, - 9, 5, -4, 1, -4, 5, -2, -9, 3, 5, 2, -10, -6, -17, 3, 17 }, - { -16, 9, 21, 19, 4, -20, -17, 14, 9, 15, -6, -17, -1, 1, 6, -3, - 1, 1, 8, -3, -6, 6, 9, 4, 9, -9, -5, 1, -1, 0, -1, 2 }, - { -7, -5, 3, 19, 1, -20, -9, 14, 21, -7, -18, -9, 26, -7, -17, -7, - 12, 6, 0, -9, -6, 14, 9, -9, -8, 4, 15, -7, -9, -1, 9, 1 }, - { -20, 30, -6, 11, 24, -4, 0, -6, -2, 8, -4, 12, -8, -17, 0, 5, - -4, 1, -1, 3, -3, 5, 3, 3, 7, -2, -3, -2, 4, 0, 0, -1 }, - { -35, 17, 6, 1, -9, -1, -16, 3, -20, -13, 8, 7, -4, -7, -4, -20, - 7, 12, -5, 5, -5, -11, 12, -1, 15, -9, -6, 16, -4, -9, -13, 4 }, - { -21, 36, -19, 9, 0, -7, -8, 9, -4, -3, 3, 0, 7, -8, -2, -2, - -11, 13, -1, 5, -3, 7, 2, 3, -1, -2, -5, 1, -1, -2, -5, -3 }, - { -12, 33, -4, 1, -12, -9, 0, -13, -1, 2, -8, 4, -10, 6, -16, -7, - -1, -4, -10, 15, -1, 0, -5, -8, 5, 5, -3, 0, 2, -7, 1, -7 }, - { -14, 32, 5, -7, -15, 3, -5, 8, 14, 5, 9, 13, 3, 18, -3, 7, - 4, -10, -10, 10, -1, 2, 0, -2, -11, 5, -3, -4, 2, 2, 7, 4 }, - { -14, 34, 1, 20, -1, -12, 0, -3, -7, -4, 7, 18, 9, -3, 14, -7, - -9, -20, -7, -4, -13, 12, 1, 12, 5, -6, 2, -4, 0, -15, 1, 3 }, - { -21, 23, 7, -8, 3, -13, -3, 0, -6, -2, -7, 6, -12, 9, -6, -2, - -2, -4, -1, 6, 9, 5, -9, 15, 0, 8, -8, 7, 6, -15, 3, -5 }, - { -27, 32, -1, -4, -2, 4, -10, 12, -3, 8, 13, 7, 0, -15, 4, -2, - 3, 5, 7, -4, 9, -12, -1, -2, -1, -4, 0, -4, 2, -5, 6, -6 }, - { -17, 29, 15, 0, -1, -4, -10, 13, 12, -1, -8, -10, -10, 4, 7, -2, - 6, -5, -13, 19, 6, 1, -7, 2, -9, -2, 12, -4, -8, -3, 2, 4 }, - { -38, 27, 16, -15, -6, 3, -7, -4, 0, -1, 6, -2, -3, -6, 6, -6, - -3, 0, 2, 0, -4, 6, 1, -1, 0, 4, -1, 3, 4, 1, -2, 5 }, - { -33, 40, -4, 2, 1, 0, 0, -10, -14, 0, -7, 4, -1, 3, -2, 5, - 7, 6, -1, 4, 1, 3, 1, -7, 1, -4, 5, 7, 0, 4, 3, -4 }, - { -20, 25, 12, -4, 16, -4, 2, 2, -14, -2, -3, 29, -1, 1, 3, 1, - 9, -5, 2, -8, -3, 1, -7, -2, -7, 1, 0, 4, 16, -2, -1, -1 }, - { -10, 30, 17, 3, -5, -2, 0, -5, -22, 4, 5, 5, -3, -18, -6, 10, - -5, -7, 2, 8, 7, -7, -11, -2, 0, -3, 3, 2, 11, -4, 4, -4 }, - { -11, 30, 11, 4, -3, -8, 1, -2, 4, 18, 3, 1, -1, 0, -8, -4, - -3, 10, 13, 14, 5, -5, 1, 1, -10, 2, 15, 4, 9, -1, -5, -3 }, - { -17, 32, 18, -18, -3, -5, 6, 10, 1, -15, -5, 9, 8, -12, -10, -6, - 11, 9, -5, -8, -7, 10, 5, -10, -14, -4, -3, 1, 9, -11, 2, 1 }, - { -13, 28, -11, -1, 2, -16, -2, 7, -24, 0, 3, 6, 3, -1, -8, -7, - -12, 2, 2, -20, 10, 4, 0, -13, -2, -2, 1, 8, -14, 0, 4, 1 }, - { -14, 23, 12, 8, 8, -26, 2, -4, -14, 13, -14, 15, 3, -9, -1, -13, - -10, -2, -10, 6, -16, 12, 8, 0, 9, -10, -7, -4, -4, 7, -8, 8 }, - { -20, 45, 10, -14, 4, 16, 8, -9, 1, -8, 10, 5, -7, -2, 2, -5, - -1, 0, -5, 4, -6, -2, 4, 1, 3, 4, -4, 2, -2, -2, 5, 1 }, - { -20, 26, -4, 1, 7, 4, -8, 1, -5, -13, 2, 13, -7, -3, 6, -6, - 22, 0, 5, 11, -4, -11, 8, -9, 2, -2, -4, -2, 2, -13, -4, -8 }, - { -28, 18, 17, 3, -8, -23, -16, -6, 5, -10, 14, 10, 5, -1, -8, 4, - -2, 13, -3, -2, 3, 4, 3, -2, -3, -4, 0, 1, 3, 4, 0, 4 }, - { -12, 32, -6, -16, 18, 12, -16, 0, 7, 13, -4, 5, -8, -1, -3, 4, - 6, -2, -1, -13, 4, -1, 3, 12, -3, -10, 1, 6, 8, -11, -2, 4 }, - { -18, 26, 2, 5, 0, -9, -17, 14, 5, 1, 7, -3, -8, -3, 11, 7, - -5, -12, -8, 7, 0, -7, 2, -12, -9, 13, -11, 9, 6, -11, -5, 11 }, - { -24, 22, -15, -9, 8, 1, -7, -12, -9, 3, 11, 15, 14, -11, 12, -15, - -5, 7, -2, 0, -8, 3, 3, -1, 2, 11, -11, 14, -6, 13, 1, -6 }, - { -20, 28, 18, -4, -6, -5, 12, 14, 2, 10, -13, -6, -8, -6, -13, -1, - -26, 22, -3, -14, 6, 0, 10, -15, -13, -9, 6, -7, 1, -5, -4, -1 }, - { -19, 26, -8, -3, -14, -6, -9, -4, -8, 15, -8, 3, -12, -4, -2, -7, - -5, 3, 13, -3, -4, -25, 4, -1, 5, -12, -1, -13, 5, 2, 0, 6 }, - { -18, 43, 14, -8, 1, -23, -2, -2, 1, 3, -7, 0, 0, 8, -1, -3, - -5, 1, 5, 2, 0, -2, -2, -2, 1, -1, -1, -7, 0, 3, -3, 9 }, - { -11, 30, 10, -14, 3, 1, 10, -11, 1, -7, -4, 14, 2, 1, -9, 1, - -11, -2, -7, 5, -11, 1, 3, 14, 1, -16, -8, 3, -5, 7, -4, 4 }, - { -18, 24, 6, 3, 8, 7, -22, -7, -7, 3, -8, 4, 23, 9, 3, -1, - 3, 6, 7, -1, -7, 6, 4, 1, -3, 1, -6, -1, 2, -7, 3, 3 }, - { -15, 38, -7, -1, -11, 2, -17, -24, 24, 8, 7, -4, -5, 2, 2, -7, - 1, 4, 0, -9, 5, 0, -1, 1, -1, -5, -6, 3, 0, 7, 8, -3 }, - { -14, 22, 1, -5, 9, -12, -9, -5, -6, 5, 7, 8, -1, -4, -9, -3, - -33, -16, -9, -1, 12, -11, 17, -7, -3, -1, -7, 3, 2, -3, 16, -4 }, - { -14, 20, 6, 4, -10, -4, -4, -4, 1, -7, 2, 6, 8, -12, 4, 1, - -1, 12, 10, 3, -14, -10, -3, 18, -2, 33, -5, -17, 17, -5, 9, 7 }, - { -12, 23, 13, 0, -11, -8, -11, 12, -5, -9, -16, 11, 6, 4, 12, -5, - 5, -13, 7, -12, -3, 1, 2, 12, 1, -4, -1, 5, 4, 11, -12, -3 }, - { 15, 2, 14, 7, 1, 2, 1, 12, 10, 23, 4, 6, -20, -10, 4, 26, - -6, 13, 4, 3, 2, -11, 5, -7, -10, 4, 9, 1, 10, -4, 11, 4 }, - { 17, 15, 31, 17, 18, 16, 11, 24, 2, 4, 2, 3, -8, -3, 7, -3, - -5, -7, -2, -6, -4, -5, -4, -1, -4, -2, -5, -6, 2, -1, 4, -2 }, - { 16, 8, 15, 14, 3, 7, 21, 9, 8, 15, 21, 6, 8, 12, 5, -5, - 7, -3, 10, 2, -3, 8, 6, 0, 5, 5, 6, -3, 2, 4, 0, -5 }, - { 5, -4, 6, 12, 6, 13, 24, 17, -5, 17, -1, -6, -7, -10, -8, -18, - 3, -2, 2, 7, -15, -11, 12, -3, -2, -2, -4, -7, 2, 0, 5, 5 }, - { 10, -6, 8, 11, 12, 20, 22, -11, -3, 15, -3, 15, -2, -2, 0, 2, - 5, -8, 4, -5, -9, -4, -1, 2, -1, -3, 1, 3, 13, -1, 9, 7 }, - { -5, 8, 5, 11, 14, -5, 14, -9, 2, 35, 8, 15, 1, -2, 2, -2, - 4, -9, -3, -14, -12, -2, -2, -4, -2, -8, -3, 1, -6, 3, 10, 0 }, - { 16, 0, -6, 15, -3, 4, 4, 3, 3, 20, 5, -4, 10, 9, -9, -3, - -10, -2, -7, 11, -11, -10, 17, -1, 3, -15, 2, 9, -15, -10, 16, 10 }, - { 14, 4, -7, 19, 3, 0, 19, 8, 16, 34, -9, 6, -13, -1, 6, 5, - -1, -2, 4, 3, 2, 1, 1, -1, 0, -7, 2, -1, 1, 0, 6, -1 }, - { 1, 6, 9, 13, 9, 10, 15, 16, 10, 18, 13, 17, 3, -1, -7, 2, - -15, -11, -10, -4, -13, -6, -17, -13, -6, -14, 1, -10, 6, 4, -1, -1 }, - { 13, 1, 7, 10, 14, 13, -7, 5, 5, 28, 14, 14, -2, 2, 3, -3, - -13, -4, 10, -9, 19, -4, -3, 4, -5, -5, 0, 5, -5, 0, 3, -4 }, - { 1, 0, 6, 22, 9, 18, 18, -3, 5, 10, 12, -2, 1, -3, -8, -12, - 9, -10, -7, 1, -1, 19, 0, 2, -8, -11, -10, 9, 6, 11, 0, 3 }, - { 10, 11, 19, 44, 0, 14, 1, -7, 6, 22, 2, -1, 9, 2, 0, -4, - 4, 0, -6, -6, 3, 0, 0, -2, 2, -5, 1, -2, 0, 1, 1, 1 }, - { 5, 7, 0, 32, 30, 26, 5, 4, -7, -3, 15, -6, 3, -10, 7, 6, - -8, -7, 2, -13, -5, -1, -3, 7, 3, -2, -8, 0, 6, 4, 5, 0 }, - { 9, 8, -2, 4, 2, 11, 4, 29, -5, 14, 8, -5, -14, 8, 0, 9, - 8, -10, 5, -15, -6, -9, 9, -1, 18, -16, 9, -21, -3, -13, -2, 8 }, - { 25, 7, -9, 23, 20, 18, 6, 16, -9, 8, 8, -5, 11, 13, -8, 7, - 4, 10, -2, -1, -7, -9, -7, -9, -4, 1, 1, -5, -10, 8, 4, -5 }, - { 9, 2, 16, 14, -5, 14, 1, 0, -21, 17, -1, 9, 12, -3, -3, 4, - -4, 14, 10, 3, 0, -10, 7, 4, 4, -11, 2, 4, -1, -3, 9, -1 }, - { 17, 8, 11, 26, 15, -3, 14, -1, 12, 9, 10, -8, 8, -18, -11, -3, - -14, -7, 7, -3, -3, -4, 1, -7, -3, 2, -3, 16, 10, 0, 9, 6 }, - { 9, 8, 3, 8, 18, 14, 11, 1, 10, 6, 1, -4, -16, -2, 14, -2, - 1, 8, 12, 14, 3, -3, 8, 8, 12, -15, 3, -3, 3, -2, 14, 10 }, - { 22, -3, -11, 13, -7, 11, 4, 11, 3, 14, 0, -6, -2, -9, 4, 2, - -2, 0, -5, -27, -10, 3, -1, 5, 8, -24, -3, -11, -3, 2, 11, -1 }, - { 19, 2, 8, 36, 5, -6, 3, 15, -3, -4, -5, 14, -10, 1, -12, -10, - -3, -4, 3, -2, 1, -8, 4, 3, 5, -3, 0, 4, 8, -2, 8, 4 }, - { 8, 14, 15, 9, -4, 10, 5, 11, 9, 10, 8, 9, -15, 15, 6, -8, - -10, -13, 5, -8, -20, -13, -6, -11, -1, -3, -6, -4, -1, 0, 13, 15 }, - { -2, -1, 9, 12, 2, 2, 13, 3, -23, 33, 15, 2, -4, -1, 3, 8, - 8, 6, 6, -7, 8, 6, 9, -1, 3, -8, 0, -4, 1, -8, 11, -1 }, - { 6, 5, -6, 16, 2, -3, 31, 21, -9, 12, 0, -1, -4, 1, -12, 3, - -13, -18, 2, -11, -9, 2, -8, -6, 11, -3, -1, 0, -1, 0, 13, 5 }, - { 5, -1, 2, 0, 25, 5, 10, 16, -5, 21, 14, 12, 13, 2, -5, 5, - 5, -3, -2, -14, 0, -12, 7, 11, -1, -7, 19, -1, -1, -1, 8, -1 }, - { 10, 7, 3, 11, 0, 8, 22, 3, 3, 19, -4, 12, 15, 9, 5, 15, - 2, 1, 2, -10, -10, 0, 2, -1, 0, 1, -12, -1, 21, 16, 9, -7 }, - { 11, -4, -5, 24, -7, 11, 20, 11, -15, 18, 5, -13, -15, 0, -5, 9, - 1, 0, -1, -9, 4, -8, 6, -8, 1, -2, -7, 20, 9, 3, 9, 3 }, - { 20, 0, -12, -6, 9, 31, 9, 12, 8, 27, 15, 7, -16, 5, -3, -7, - -1, -9, -2, -7, -3, 4, -8, -3, 3, -6, -2, -2, -3, -6, -1, 2 }, - { 6, -6, 48, 8, -3, 19, 12, 11, -7, 2, 3, 0, -1, 1, 8, -4, - 4, -6, 0, -4, -4, -3, 3, 6, 3, -13, -8, 5, -3, -7, 8, 5 }, - { 7, -2, 6, 11, 12, 2, 14, 4, -5, 12, 2, 9, 4, 2, 0, -1, - 2, 0, -15, -9, -16, -2, 8, -17, -5, -22, -19, -5, -1, -10, 1, -2 }, - { 11, -9, 3, 12, 6, 6, 1, 17, -6, 19, 14, 7, -7, -1, -1, -9, - 9, -11, -17, 0, -6, 16, 0, 1, 9, -24, 3, 3, -9, -3, 3, -2 }, - { 9, 0, 1, 8, 1, 7, 2, -5, -3, 8, -1, 7, 2, 6, -3, -6, - 5, -2, 6, -2, -4, -3, 0, -3, 13, -50, 1, -2, 2, 4, 4, 3 }, - { 7, 0, 26, 21, -4, 2, 17, 8, 7, 11, -7, 1, -1, -15, -1, -15, - -11, -4, -17, -4, 1, -7, 3, 6, 3, -9, 2, 3, 6, 10, 6, 12 }, - { 1, -2, 2, -1, -10, -4, 6, -3, -5, -2, -8, 2, 2, 2, 8, 0, - 1, 1, 6, 0, 11, 13, 3, 4, 0, -12, 11, -5, 19, 20, 2, 5 }, - { 5, 3, -13, -2, 1, -12, 11, -7, -12, 7, 10, 0, 7, 0, -2, 4, - -6, -9, -11, -12, -23, 12, 10, -3, 0, 6, 19, -1, 24, 18, 9, 12 }, - { 6, -3, 2, 5, 2, 2, -2, -5, -8, -11, -4, 3, -8, -4, 5, -3, - -16, -4, 3, -12, -4, 3, 32, 7, 2, 8, 32, -18, -1, 12, 1, 7 }, - { 0, -8, -1, 0, -8, 7, -8, -1, -1, 4, -12, -1, 3, 0, 1, -18, - 8, 8, -14, -10, -11, 19, 9, 5, -7, 6, 8, -4, 26, 12, -1, 6 }, - { 3, 5, -14, 7, 14, 8, 20, -13, -16, -10, -2, 17, -7, 4, -8, -9, - 14, -5, 3, -4, -12, 7, 14, -10, -19, -20, 35, 8, 13, 14, -2, 9 }, - { -2, -4, -1, 1, -3, 0, -1, 1, 2, 2, 6, 0, 0, 4, 5, -2, - 3, 3, 3, -2, -7, -3, -3, -1, 6, -2, 29, 22, 13, 34, 0, 14 }, - { -3, -9, 3, 1, 5, -4, 2, 0, 7, -9, 0, 2, -5, -3, 0, 6, - -1, -1, -1, 2, 2, 4, 8, 7, 20, -6, 7, 16, 33, 20, 6, -1 }, - { -11, 1, -3, -3, -11, 3, -9, -25, -1, -16, 4, -8, 15, 1, -2, 7, - 8, 23, 2, 18, -13, 16, 3, -7, 6, 3, 16, -8, 12, 16, 3, 4 }, - { 0, 5, 5, -5, 1, -1, 2, -3, -2, 1, -13, 2, 2, 10, 6, 7, - 18, 18, 7, 9, 8, 9, 21, 14, 7, 12, 15, 14, 15, 12, 11, 5 }, - { 1, -5, 11, -2, 17, 8, 3, 0, -1, 6, 11, -7, 6, 6, 7, 5, - -15, 14, 1, 11, 4, 10, 12, 1, 2, 4, 30, 1, 11, 1, 6, 13 }, - { 2, 4, 3, -7, 5, 8, -11, 7, -5, 9, -10, 6, 8, -10, -3, 10, - 1, -29, -4, -26, 5, -8, 13, 4, 3, 6, 35, 1, 3, 6, 3, 0 }, - { -2, 1, 0, 0, -1, -3, -7, -3, -9, -3, -1, -6, 3, 4, 4, 0, - 5, -1, -2, -2, -1, -4, -10, 8, 0, -6, 10, -4, 46, 12, 2, 28 }, - { 4, -1, 4, 1, 0, 4, -2, -2, -2, -1, 2, -4, 1, 5, 0, -3, - 1, 1, -2, 0, 1, -2, -1, -1, 3, -6, 35, -11, 13, 53, -3, -1 }, - { -5, -2, 0, -13, -16, 5, -12, -11, 1, -30, 3, -18, -24, -8, -5, -19, - 1, -3, -8, 7, -7, -8, 15, -19, 4, 10, 30, 24, 6, 1, -9, 10 }, - { -4, 8, -7, -4, -6, 12, -1, -9, -4, 2, -9, 3, 2, -2, 4, 2, - 22, 9, 4, -5, 0, 5, -2, -9, -3, 1, 18, -12, 18, 16, 4, 16 }, - { -5, -8, -3, -5, -3, 6, -7, -3, -2, -5, -3, 1, 2, 2, 4, -6, - 10, 3, 12, -3, 20, 0, 27, -4, 16, 5, 18, -3, 23, 4, 12, 11 }, - { 0, 1, 0, 1, -2, 1, 2, 1, -1, 0, -2, 2, -2, -4, 1, -2, - -2, -1, -5, -2, 0, 0, -2, 2, 9, 7, 63, 5, 12, -1, 1, 0 }, - { 4, -3, -7, -5, -11, -5, -12, -10, -10, -12, -15, -12, -14, -14, 1, 1, - 10, -10, 16, 6, 2, 9, 11, 9, 9, 8, 12, -1, 13, 12, 6, 3 }, - { 7, -3, -2, 4, 6, -8, 2, -3, -12, -5, -9, -8, -10, 15, -2, -4, - 8, 9, 7, -13, -18, 34, -5, 7, 12, 22, 16, -11, 13, 25, -15, -11 }, - { -3, -2, 0, -4, 1, 0, -3, -13, -7, 13, 12, -7, -10, 13, 19, 6, - 16, 15, -12, -15, -3, 34, 1, 5, 1, -9, 11, 21, 8, 17, -5, -6 }, - { 3, -5, 0, -4, 0, 4, -11, 4, -7, -3, -1, -8, 3, -2, 2, 1, - 11, 5, 6, 14, -3, 2, -4, -7, 0, 31, 15, -2, 24, 11, 5, 4 }, - { -1, -4, -9, 5, -8, -18, -4, -9, -20, -18, 7, -14, -16, 3, 8, -3, - 29, 11, -13, -13, 7, 1, 17, 6, 6, 21, 11, 1, 14, -8, 2, 5 }, - { -3, 8, -10, -6, 12, 2, 1, 3, 3, 3, 3, -6, -8, -14, 15, -5, - 16, 4, 16, 0, 7, -1, 0, 16, 2, 1, 22, 4, 19, 13, -11, 1 }, - { 2, -3, 10, 20, -4, -1, -8, 5, -8, -9, -6, -2, -4, -7, 8, -10, - 0, 8, -6, 1, -8, 14, 13, 5, 17, -6, 26, -1, 7, -1, 0, 12 }, - { -4, -7, -31, -2, -7, -1, 5, -5, -5, -12, 4, -7, -6, 3, 15, -2, - 5, -2, 7, -1, 10, 7, 8, -1, 14, 20, 14, 9, 16, 16, 8, 24 }, - { -7, 0, -3, -6, 1, 3, -13, -6, -4, -4, -5, -9, -1, -10, -4, -8, - 2, 0, -1, 1, 24, 24, 21, 31, 5, 2, 11, 12, 7, 4, 3, 6 }, - { -3, -5, 6, -4, -3, -1, 2, -1, -2, 1, 0, -8, -1, 2, 0, -4, - 6, 22, -1, -5, 8, 12, -1, -2, 28, 27, 20, -27, 14, 1, 2, -3 }, - { 1, -5, -2, -2, 6, -2, 9, 1, -2, -5, 3, 4, 11, 5, 2, 8, - -3, -1, 1, -2, -3, -5, 5, 8, 49, 12, 8, -3, 9, 20, 12, 17 }, - { -6, 0, 1, 7, 0, 9, -2, -4, 8, 0, -2, -10, 0, 7, 21, -1, - 0, 1, 17, -7, -5, 2, 4, 16, -2, 17, 14, -20, 15, 14, 4, 15 }, - { 0, 3, -4, 9, -4, 0, 6, 4, -6, -6, -5, -7, 2, -9, -10, -2, - -5, 0, -3, -21, 9, 14, -11, 13, 29, 2, 25, 4, 22, -1, 2, -3 }, - { 2, 12, -11, 2, 16, 9, -4, 7, 1, -10, -15, 11, -4, 3, -2, 4, - 4, -5, -10, 1, 4, 19, -15, 6, -4, -2, 30, -7, 11, 21, -12, 5 }, - { -2, -3, -2, 4, -1, -5, -3, -7, -5, 1, 0, -6, 1, -6, 7, 0, - 8, -7, -3, -2, 2, 14, 2, -3, -26, -1, 26, 22, 32, 1, -2, 6 }, - { 1, -38, -1, -20, -2, -3, -6, -4, 2, 2, 7, 0, 3, 5, 3, 10, - 6, 1, -3, -5, 7, 5, -5, -4, 8, 3, 1, -14, -1, -9, -5, -4 }, - { -5, -26, -7, -19, -10, -5, -11, 5, -11, -25, -8, -14, -9, -16, -8, -6, - -17, -14, -1, -1, 6, 2, 2, 2, 3, 0, 2, 8, -8, 3, 0, -3 }, - { 17, -49, -3, -23, -1, 11, 7, 3, 4, -4, 0, 0, -1, 4, 2, 4, - -2, -4, 2, -2, -1, -2, 2, 0, 0, -1, 0, 0, 1, 2, 0, 0 }, - { 4, -34, -6, -9, 1, 21, -7, 3, -2, -1, -3, 18, 2, -16, 7, -3, - 8, 7, -5, 7, 2, 4, 8, -6, -7, -2, -5, -1, 4, 1, 2, -4 }, - { 5, -29, 13, -2, -14, 3, 1, 18, -15, 4, -8, 8, -10, 8, 2, 1, - -8, 15, 3, -10, -4, -4, -2, 0, -3, -4, 2, -3, -4, -3, 12, -6 }, - { 13, -20, 3, -18, -17, 4, -14, 13, 28, 11, -8, -6, 16, 6, 0, 10, - 3, 4, -9, 13, 5, -7, 12, -5, 0, -7, 5, 1, 3, 3, 2, 1 }, - { 3, -27, -5, -11, -21, -11, -12, 0, -5, 7, -22, 1, 3, 5, 0, -5, - 8, 7, 1, -5, -7, 2, -5, 4, 1, 3, -8, -2, 0, 4, -2, 6 }, - { 31, -45, 0, -1, -12, 1, 2, -6, 4, 3, -1, 3, 3, 0, 5, 3, - -5, 12, 4, 6, 2, 1, -2, 1, 3, 2, 5, 2, 2, 2, 3, -1 }, - { 9, -45, 6, 5, -1, -17, -2, 18, -3, 2, 0, 1, 0, -1, 10, 8, - -7, -2, -5, -8, 6, -1, 0, 4, 6, -3, 12, -1, -2, 0, 5, -7 }, - { 3, -26, -2, -12, -12, 2, -10, 16, -3, 12, 4, 5, 11, 8, -16, -17, - -2, -3, -3, 2, 5, -9, 13, 1, 10, 11, 3, 5, -2, 2, 2, -7 }, - { 8, -26, 32, -7, -5, 22, 2, 14, -10, -8, -7, 3, 3, 7, 0, -5, - 0, -1, -3, 0, 8, 4, -5, -7, 6, -1, 4, 8, 1, 1, 7, -6 }, - { 4, -31, 2, -14, 2, 0, 1, 8, -6, -1, 17, -3, 13, -6, 5, -10, - -2, -10, -2, -10, -3, 7, 1, 5, -8, 8, -14, -3, -15, 7, -10, -6 }, - { 16, -27, 13, -4, -23, 7, -9, 6, -7, 5, 4, 2, -1, -3, 23, -18, - 7, 0, -3, 4, -3, 9, -6, -2, -1, 8, -6, 2, 6, -3, 2, -2 }, - { -1, -35, -2, -8, 11, -1, -7, -3, -2, 11, 7, 6, -6, -10, 9, 6, - -3, -5, -6, -3, 9, 16, -16, -9, -20, 12, 3, 5, -3, 1, -9, 4 }, - { 2, -24, 1, -12, -16, 5, -4, 3, -4, -1, -11, -11, -8, -14, 14, 10, - -8, 20, 8, -3, -11, 1, 1, -4, -4, -7, -3, 15, 2, -6, -2, 7 }, - { 9, -21, 2, -19, -7, -5, -8, 25, 3, 17, 5, -3, 9, -12, 8, 2, - -4, 3, 3, 1, 11, -9, -4, -3, 4, 3, -22, 6, 4, 6, 11, -5 }, - { 16, -23, 13, -17, -21, -12, 5, 9, -20, 7, 6, -6, 0, 2, -9, 6, - -6, -13, -7, -1, 5, -3, 5, -7, -10, 1, 0, 8, -9, 11, 0, -8 }, - { 10, -26, -9, -7, -19, -4, 6, 16, -7, 5, -4, 4, 8, 0, 4, -1, - 6, -7, 1, -8, -11, 10, -14, 0, -16, 6, -3, 5, -1, 14, 12, 1 }, - { 8, -27, 12, -14, -1, -1, -19, 10, -11, 21, -14, 9, -8, -3, 8, -1, - 12, -13, 3, -4, -2, 0, -9, 0, -7, 2, -3, 12, 1, -3, 3, 1 }, - { 18, -20, -14, -14, -16, -3, -24, 6, -17, 2, -3, -11, 2, -3, 12, 10, - 10, 1, 10, 7, 8, 5, 5, 4, -1, 7, 2, 2, 0, 4, 7, 0 }, - { 0, -30, 9, -16, -18, 15, 12, -3, 4, -4, -5, -11, -4, -12, -10, 0, - 2, -2, -4, -1, 2, 0, -1, -6, 2, -3, 4, -5, 7, 3, 5, 7 }, - { 25, -24, -1, -6, -9, 6, -13, -2, 3, 15, -3, 11, 4, -8, -11, 2, - 0, -9, -2, 7, 4, 8, 5, -8, 5, 6, -1, -11, -15, -5, 0, 11 }, - { 0, -34, -7, -11, -7, 9, -3, 19, 4, -8, 3, -11, 11, -3, -9, 12, - 9, 9, 2, 1, -7, 1, -3, 0, -6, -2, -1, 3, 0, -7, -2, -5 }, - { 6, -34, -4, -5, -3, -9, 2, 9, -1, 9, -5, -3, -26, -12, 8, -6, - -7, 11, -8, 4, 4, 1, -1, 0, 8, 9, -4, 7, -1, 1, -3, -1 }, - { 3, -30, 5, 6, -10, 3, -7, 6, 3, 3, -26, -19, -3, 1, 7, 5, - -4, -5, 6, 10, 13, -10, 4, -7, -4, 5, -3, 9, -6, 3, 9, 5 }, - { 4, -24, 9, -19, 2, -4, -5, 8, -3, 2, 0, -15, -1, 9, -4, 22, - 6, 9, 3, 7, 11, -9, 0, -3, 4, 5, -5, 10, -8, 5, -7, -3 }, - { 8, -27, 7, -3, -1, 2, -9, 13, 7, 12, -4, -6, -6, 5, 0, 7, - 5, 1, 15, -3, -4, 0, -5, -2, 7, -5, -7, 1, -2, 13, -8, 13 }, - { 17, -22, -15, -11, -8, 16, -14, 18, 2, -1, 14, -7, 14, -6, -6, -7, - -8, 17, 6, 4, 4, -7, -5, -9, -14, -6, -1, 9, -3, 1, 6, -5 }, - { 25, -30, 2, -12, -13, 18, -18, 16, 8, -3, 10, -8, -3, -1, -6, 3, - -5, -7, 4, 6, 7, 1, 1, -11, -5, 6, 2, -4, 9, -1, -5, -2 }, - { 7, -23, 7, -15, -1, -3, -1, 0, -10, 12, 2, 5, -4, 0, 4, 6, - -1, 5, -9, -1, -1, -7, 1, 17, 9, -17, -16, 8, 4, -14, 11, 14 }, - { 0, -31, 7, -13, 3, -11, -7, 6, 1, -11, 8, -7, 15, -3, 16, -11, - -1, -15, 16, -3, 5, 0, -2, -2, -6, 11, 5, 6, 5, -5, 6, 3 }, - { 13, -24, -2, -20, -10, 7, -3, -1, 15, 2, 6, -5, -7, -10, -20, 1, - -4, 14, 8, -2, 3, -13, -3, 1, -4, 1, -3, 2, 8, -7, 16, -4 }, - { 1, -2, -2, -3, -4, -7, 0, 3, 6, 7, 3, 2, 1, -2, -1, 0, - -6, 4, 2, -4, -3, -4, 5, 9, 5, 0, -3, -3, -4, -7, -31, -50 }, - { -1, -3, 7, 2, -1, 2, 4, 6, 0, 10, -2, 0, -20, -6, -3, 9, - -20, -22, -1, -1, 15, 9, -12, 10, -13, -20, 12, 3, 5, 6, -7, -26 }, - { 0, 4, -2, -14, -12, 6, -13, 11, -10, 3, 22, 6, 16, -2, -5, 1, - -3, -11, 0, -7, 5, -5, 0, 1, -1, -6, 8, 8, 10, 9, -5, -27 }, - { -5, 10, -2, 7, 9, -9, 5, -9, 5, 4, -15, 14, 1, 3, -10, 5, - 0, -2, 7, 3, -13, 6, 9, -6, 5, -14, -17, -1, 11, 14, -2, -26 }, - { 0, 6, -3, 0, -8, 6, 0, 1, 4, -8, 2, -5, 4, 7, 15, 11, - 9, 19, -2, 14, -8, 7, -1, 3, -3, -3, -10, -2, 12, -2, -12, -29 }, - { -12, -5, 0, -3, -2, 6, 3, -3, 2, -2, 1, 11, 2, -7, 5, 1, - 2, -2, -14, 0, -1, -5, 3, 8, -28, -26, 6, -6, 3, 8, -10, -27 }, - { -1, -3, 6, 2, 4, 15, 1, 0, 2, -2, -2, 13, 3, 6, 0, 6, - -1, -4, -1, -5, 8, -1, 5, -5, -15, 11, -8, -5, 14, -6, -14, -29 }, - { -5, -6, 0, 1, 0, 6, -3, 2, -5, -1, 5, -3, 2, -10, 3, 4, - 3, 0, 13, -3, -1, 4, -4, -6, 2, 9, 8, 2, -3, 28, -11, -31 }, - { 1, -4, -10, -9, -4, -3, -15, -6, 1, 5, -3, -6, 5, -6, -22, 27, - -13, 5, 3, -7, -4, 20, -7, -12, -1, -24, -4, -13, -8, -11, -15, -21 }, - { -6, -4, 19, -6, 2, 11, -6, 1, -3, -10, 9, -9, 12, -10, 2, 1, - -9, 1, 15, 7, -5, 5, -29, -35, 4, -30, 9, 9, 19, 17, 2, -17 }, - { -3, 3, -3, 1, 2, 5, -1, 5, -2, -3, 1, -3, -8, 3, -4, -2, - -4, -1, 12, 0, 2, -8, -6, -4, 16, -1, -14, -2, 25, -6, -15, -36 }, - { 0, -1, 3, -4, -4, -1, 7, -4, 8, 0, 10, 9, -4, 1, 10, -1, - -3, -13, -5, -4, -1, -4, 8, 11, 14, -7, -5, 16, 12, 13, -1, -28 }, - { 1, -2, 2, -3, -8, 10, 4, 9, 12, 3, 5, 0, 8, -3, -6, 2, - 16, -11, 11, 0, 1, 6, 1, 18, -10, -16, -1, -4, 5, -14, -15, -20 }, - { 1, -12, 5, 4, -7, 8, -1, -17, -2, -9, -14, -11, 6, -9, 5, -4, - 3, -2, 7, 18, -5, 5, 6, -1, -11, -2, -10, -3, 8, -3, -2, -32 }, - { -12, 5, 20, -5, -6, -11, -6, -6, -13, 4, -6, 19, -8, 2, 3, -9, - -4, -4, -1, 9, -1, 21, -1, 7, 15, -10, -1, -3, 9, -3, 2, -24 }, - { 0, -3, 2, -6, 4, -1, -9, -2, -1, -3, 6, -1, -5, -6, -5, -8, - 0, -2, -6, 9, -4, 3, 2, -13, 1, -7, 23, -13, 4, -3, -15, -33 }, - { -7, 2, -15, 11, -10, 14, 0, -11, 3, -1, 12, -4, -4, 9, 11, -13, - -13, -3, -14, 1, 3, 6, -5, 8, 0, 5, 5, -10, 4, 5, -6, -30 }, - { -6, 4, 0, -5, 4, 1, -1, -1, 3, 6, 5, -2, -5, 0, -2, 5, - -4, -2, -4, -2, 4, 7, -7, -1, 1, -4, -3, -19, 37, 12, 10, -40 }, - { -7, 2, -7, -12, 17, 11, -7, 2, 2, 3, 1, -1, 3, 4, -2, -5, - 9, -9, 6, 4, 9, 12, 11, -5, 2, -1, 0, 9, 5, -7, -2, -24 }, - { -7, 6, 1, 3, 1, 0, 6, 0, 4, -12, -2, -2, 1, -9, 10, -2, - 11, -1, 21, -12, 15, -5, 10, -5, 5, -5, 14, -6, 5, -7, -3, -29 }, - { -2, 0, -5, -2, -3, 1, -3, 0, 4, 2, 3, 0, 2, -2, 7, -2, - 3, -5, 2, -1, 6, -4, 0, -3, 8, -11, 19, -8, 22, -34, 13, -35 }, - { -1, -3, -1, 9, 11, -3, -3, -1, 7, 18, 11, -5, 2, -12, -11, 18, - 9, -5, 1, -6, -9, 12, 1, -3, -3, -9, -14, 9, 9, 8, -6, -26 }, - { 0, 5, -5, -1, -1, -2, 4, 6, 8, 2, -1, -2, 5, 1, -5, -4, - 1, 1, 18, 1, 7, -10, 3, -2, 12, -1, -15, 9, 12, -14, 13, -38 }, - { 3, 0, -8, -1, 0, 8, -9, -3, -8, 16, 3, 16, -5, -9, 0, -1, - -7, -1, -4, 13, 7, 0, 1, 2, -1, -16, 0, -2, 1, 8, -8, -28 }, - { 7, 9, -5, -3, -2, 2, 0, 3, 11, -6, -4, -2, -2, -5, 28, -18, - -6, 2, 15, -10, -15, -10, -2, 0, -2, -2, 4, -3, 7, 11, 5, -30 }, - { 9, 0, -7, -1, -4, -7, 2, 2, 9, -2, 2, 3, -8, -6, -6, 3, - -10, 4, 10, 5, 21, -4, 14, -18, 1, 3, -10, -2, 6, 14, -8, -26 }, - { -14, -1, 2, 3, -3, 7, 1, -22, -1, -1, 0, 1, 12, -14, 3, -5, - 0, 10, -3, 1, -5, 12, -3, 10, -8, -22, -11, -13, -7, -10, -13, -25 }, - { -2, -5, -4, -4, -9, -18, 9, -3, -5, 17, 13, 5, 6, 11, 3, 8, - 20, 4, 2, 9, 8, 5, 6, 1, 7, -7, -6, -2, -7, 0, -17, -23 }, - { -5, -5, 2, 0, 6, 2, -2, 2, -3, 4, 4, 0, -5, -2, -4, 6, - 8, 10, -1, 1, -5, 5, -14, -2, -11, 8, 6, 25, 7, -1, 0, -43 }, - { -4, 0, 4, -2, 7, 0, 3, 17, 5, 2, -5, 1, 21, 3, -2, -10, - -16, -9, 7, -12, 9, -8, 2, 5, -5, -10, -2, -11, -5, -1, -9, -30 }, - { -2, 3, 1, -4, -1, 0, 8, 1, 12, 4, -1, -1, 3, -17, 13, 9, - 0, 7, -6, -5, 9, 1, 5, 4, -10, -18, 0, 14, 11, -4, -16, -28 }, - { -1, 0, 2, -1, 4, 1, -1, 1, -1, -2, -1, -2, 3, 0, 0, -1, - -1, 1, 2, -2, 3, 3, -2, 4, -2, -1, -6, 1, -1, -1, 6, -70 }, - { 7, 3, -11, -1, 12, -4, -14, 4, 4, -4, 4, -2, 2, -12, -4, 15, - -17, -4, -3, 6, 8, -5, 22, -22, 5, -11, 15, -4, 4, -1, -21, -1 }, - { 10, -2, -13, 11, 4, 14, 4, 9, 8, 8, 19, 15, 14, 15, 5, 10, - 8, 15, -5, 4, 14, -8, 1, 1, 2, 1, -1, -3, 21, 8, -29, 13 }, - { -6, 0, -6, 6, -1, 2, 8, -4, -5, 4, -4, -5, 0, -2, -4, 0, - 9, -2, 1, -2, 26, -19, 21, -10, 4, 1, -8, 5, 22, -10, -13, 15 }, - { 11, -5, 1, 0, 6, 3, 7, -2, -2, -3, -5, -1, -2, -6, 1, 1, - -8, -5, -13, 13, -2, -3, -1, -9, -28, 4, 2, -11, 18, -20, -24, 9 }, - { 7, 4, -3, 6, 6, -6, -7, -5, -7, -4, -4, 0, -7, -5, -6, -5, - 2, -13, -12, 2, 0, 5, 18, 15, -13, -7, 13, -20, 16, -10, -19, 6 }, - { 5, -8, -1, 5, 10, 2, -1, -10, -11, 23, 8, -5, -8, 4, -5, -4, - -5, -5, -11, -8, 5, 1, 7, -9, -9, -6, 12, 14, 17, -12, -22, 3 }, - { -5, -8, -3, 3, 12, -1, 0, -4, -5, 1, 1, 6, 1, 5, -5, 7, - -2, 7, 1, 6, 6, 2, 0, -5, 17, -4, -5, -24, 13, -20, -27, 14 }, - { -1, 2, -3, 1, -3, 1, -3, 0, -2, 3, -2, 1, 2, -1, -2, -1, - -2, -5, 5, -2, 0, -7, 1, -6, 8, 8, 11, -5, 24, -43, -13, 2 }, - { -2, 4, 7, -3, -4, 4, 13, -4, 0, 0, -2, 9, 0, -3, -6, 1, - -7, 1, -1, 10, 0, 5, -1, -24, 25, -15, 7, 2, 22, -10, -21, 0 }, - { -5, 2, 6, -2, 13, 3, 5, -12, -11, 16, 6, 10, -5, 0, -3, 6, - 5, -5, -5, 10, 12, 10, 11, -7, 8, -14, 2, -15, 13, -14, -8, -3 }, - { 5, 6, -7, -5, 5, 2, 9, 5, 0, -1, -4, 2, 8, 0, 3, 5, - -12, 3, -3, -6, 2, -1, -5, 14, 11, -20, -21, -25, 24, -1, -10, 6 }, - { -5, 5, -2, 9, 4, -4, -1, -6, 11, -6, 5, 0, 2, -3, 6, -1, - -17, -18, -4, -13, 9, -1, 9, -7, -4, -8, 2, -3, 12, -31, -18, 5 }, - { -7, -11, 6, -8, 4, -3, -12, 0, -1, -6, -3, 0, 5, 9, 7, 2, - 1, -8, -6, 8, 2, -5, 7, -1, 16, -10, 16, -12, 18, -1, -25, -12 }, - { 3, -12, 1, 2, -2, -18, -8, -15, -10, -9, 2, -7, 11, -11, 2, -1, - -1, -1, -9, -6, 3, -14, -2, -1, 2, -13, -7, -9, 19, -5, -17, 2 }, - { 7, 1, -8, 7, 17, -13, -10, 5, 7, 1, -6, 4, 9, -4, 0, 3, - 8, 1, -14, -9, 4, 7, -9, 0, 6, -5, -12, -2, 25, -2, -19, 1 }, - { 7, -3, 6, -3, 1, 6, -7, 0, 10, 0, 4, -5, -17, -4, 4, -1, - 0, -3, -7, 19, 24, -1, 21, 8, 10, 9, 8, -1, 23, -2, -18, -2 }, - { 3, -3, 0, 5, 8, -2, -9, 2, 9, 6, 19, 8, 2, 6, -9, -2, - -4, -3, -8, 7, -7, -8, 5, 4, 26, -6, 7, 18, 24, 0, -13, 4 }, - { 0, -13, -11, -1, 3, -9, 5, 4, -7, 3, 0, 2, -1, 4, -5, 2, - 9, -2, -11, 15, 1, -21, 1, -1, 0, 4, -14, -4, 24, -16, -13, 1 }, - { 1, -9, -8, 0, 0, -4, 11, -1, 14, 16, 0, 17, -2, -9, -12, 0, - -1, -14, -9, -14, 0, -2, 19, 4, 6, 4, 4, -11, 8, -17, -19, -5 }, - { -3, 1, 2, 12, -4, -18, -1, -4, -7, 14, -3, 2, 0, -7, -8, 12, - -5, -9, 14, 12, -9, -2, 4, -6, 4, 18, -1, -25, 22, 2, -23, -5 }, - { -2, 0, 0, 0, 1, 3, 5, -1, 5, -2, -2, 2, -3, 0, 1, 2, - 0, -1, 2, -1, -9, -6, -7, -4, -2, 4, -7, -5, 64, -3, -25, 4 }, - { 12, -2, -3, 0, 8, -9, 13, -7, 6, -3, -12, 12, 15, -9, -4, 2, - 9, -4, -12, 3, 14, 1, 7, -15, 15, 0, -6, -12, 0, -3, -20, 6 }, - { 2, -1, -4, 5, 9, 6, -7, 2, -2, -7, -2, 0, -1, -18, -4, -6, - -15, -5, 11, 5, -10, -1, 2, 7, 12, -19, -7, 8, 21, -4, -15, 4 }, - { 4, 2, 5, 5, -5, 1, 3, 2, -8, 13, 0, -5, -2, -14, -11, 6, - 2, 17, 8, -13, 26, -2, 5, -15, -4, -14, 12, -9, 13, -21, -23, -4 }, - { 2, -3, -2, -3, 3, -2, 6, 9, -9, 13, 4, 2, 12, -3, -3, 1, - -17, -22, -3, 4, 3, -2, 1, -9, 1, -6, 11, -13, 14, 0, -15, 6 }, - { -16, -4, 17, -2, -20, -11, 11, 10, 5, -8, 16, 2, -17, -14, 11, 11, - -6, -11, -7, 12, 12, -10, -6, 5, 8, -4, -2, -5, 28, 3, -13, 4 }, - { 0, -3, 3, -7, 6, 8, -12, 20, -19, 18, -11, 10, -5, 0, -9, 11, - 3, 0, -2, 9, -7, -5, 18, 3, -2, -16, 1, 6, 12, -7, -16, 1 }, - { 4, 1, 5, -5, 15, 2, -8, 3, 5, -11, 15, -3, 8, -8, -1, 7, - 4, 7, -2, 6, -9, 5, 12, 2, 33, -2, -6, -18, 4, 0, -18, 11 }, - { 3, -1, 1, -1, 0, 1, 4, -1, -5, 0, 1, 0, 4, 2, -1, 4, - -3, 2, 0, -2, 4, 6, -1, 6, 42, 19, -4, -37, 19, 1, -15, -4 }, - { 2, 0, -5, 0, 10, 0, 0, -5, 3, 0, 0, -3, -3, 0, 2, -4, - -10, 2, -6, 4, 4, 1, 27, -7, 17, -34, 5, -9, 15, -16, -7, -5 }, - { -2, 7, 7, -2, 9, -2, -15, 11, 11, 7, 5, 1, 15, 1, -9, 31, - 2, -15, 2, 4, 3, 4, -1, -8, 2, -7, 6, -17, 11, -14, -11, 2 }, - { 1, 1, -11, 9, 9, -6, -14, -11, -10, 8, -3, 11, 16, -9, -8, -13, - -8, 9, 0, 6, 6, -2, 13, -8, -2, 3, 13, -3, 10, -6, -17, 4 }, - { 14, 5, 4, -6, -12, 10, -7, 8, 21, -8, -30, 15, -2, 1, 11, -9, - -5, 1, 0, -1, -1, -6, -2, 3, -5, 7, 9, 5, -5, 2, 0, 1 }, - { -1, 2, 20, -17, -15, 3, 3, 7, 11, -17, -13, -6, -3, 18, 17, -15, - -4, -4, -5, 22, 14, -14, -2, -10, -7, 11, 8, -7, -3, 0, -7, 11 }, - { 7, -11, -7, -8, -14, 22, 5, 2, 6, 13, -12, -2, 10, 3, 0, -21, - -4, 20, 3, 10, 21, -10, -12, 8, 11, 2, -5, 2, 1, 3, -1, 15 }, - { -1, -2, -1, -2, -13, 8, -4, 0, 7, -2, -17, 8, 18, 5, 3, 8, - -8, -2, 3, -4, 14, -18, -13, 14, 15, -13, -1, -2, 4, 11, 1, 12 }, - { 13, -6, -4, -16, -17, 16, 21, -2, 5, -11, -9, 19, 21, -17, -3, -17, - 3, 12, 8, -12, -6, 1, -7, 9, 9, -7, -5, -1, -3, 5, -6, -4 }, - { 11, 5, 12, -20, -6, 10, 4, 12, 8, -5, -10, 15, 13, 14, 10, -15, - -13, 1, 6, 14, 15, -17, -13, 4, -5, 10, 7, -6, -8, -3, -4, 12 }, - { 25, -1, 7, -5, -7, 11, 1, 17, 13, -15, -14, -4, 5, 3, 8, -3, - -2, 2, 0, 6, 16, -12, -6, -4, 4, -3, 7, -10, -3, -7, -13, 7 }, - { -8, 10, -3, -13, 5, 2, 4, 9, 9, -17, -13, 2, 11, 1, 6, -4, - 8, -10, 4, 1, 19, -15, -4, 12, 31, 7, -5, -17, -4, 9, -2, 7 }, - { 14, -6, -6, -6, -14, 13, 17, -5, 4, -14, -9, 7, 7, -9, 3, -16, - -15, 11, 11, 6, 4, -11, -19, 3, 5, 8, 13, -14, -14, 3, -4, 12 }, - { -2, -4, 10, -4, -7, -1, 27, 5, 2, -16, -18, 4, 12, -2, -3, -2, - -1, 1, -8, -12, 3, -4, 8, 15, 2, 4, 9, -13, -14, 9, -7, 5 }, - { 4, 2, -10, -5, -7, 2, 1, 4, -1, -6, -15, 6, 1, 10, 5, -10, - -9, -1, 13, -3, 5, -21, -11, 8, 8, 5, 27, -21, -18, -5, -1, 15 }, - { 11, 1, -16, -8, -11, 0, 5, -8, -12, -13, -17, 22, 4, -6, -1, -18, - -10, 0, 19, 2, -2, -8, -7, -3, 2, -2, -9, -17, -5, 4, 4, 10 }, - { 8, -6, -19, -5, -4, 12, 14, 15, 10, -9, -1, -9, 19, 12, 0, -1, - 2, 4, 7, 9, 16, -16, -14, 9, -4, 3, 1, 0, -2, 10, -1, -1 }, - { 12, -8, 12, -9, 0, 25, 7, 9, 2, -31, -9, -4, 15, 4, -5, 1, - -10, 11, 8, 10, 0, -6, 5, 11, -1, -6, 4, -10, -9, 6, 4, 5 }, - { 14, 6, -17, -2, 17, 12, -9, 2, 0, -25, -14, 5, 20, 14, 8, -20, - 5, 2, -2, -3, 9, -13, -3, -1, -6, 3, 7, -6, 0, 2, 3, 1 }, - { 8, 4, -15, -3, 10, 18, -4, 13, 8, -22, -10, 9, 19, -15, 7, -5, - -13, 12, -4, 9, 2, -9, -6, 0, 2, 1, -9, -6, 6, 1, -1, 11 }, - { 4, 1, 4, -5, -10, 18, 7, 2, -4, -9, -11, 0, 32, -7, 4, -16, - -1, 0, 6, 3, 6, -3, -14, 16, 9, -2, 7, -1, 0, -5, 5, -3 }, - { -3, 2, 3, -8, -6, 4, 6, 2, 4, -12, -15, 2, 8, 8, 9, -3, - -18, 6, 34, 11, 12, -15, -1, 2, 9, 2, -4, -4, 2, 4, 2, -3 }, - { 18, -6, -12, -8, -1, 15, 20, -4, -1, -11, -5, 6, 6, -11, -15, -7, - 3, 7, 10, 2, 8, -10, -5, 8, 15, -5, 5, -17, -13, 13, 11, 7 }, - { 8, -4, -6, -1, -14, -3, 6, -2, 1, -5, -1, 10, 10, -15, 5, 0, - -10, -4, -3, 7, -4, -19, -15, 27, 11, 18, 3, -19, -2, 6, 0, 12 }, - { 12, 0, -5, 0, 4, -5, 1, 5, 10, -7, -11, 21, 29, 1, -2, 1, - -4, -11, -1, 13, 11, -20, -1, 4, 4, 4, -5, 6, -13, -2, 11, 9 }, - { 2, -7, -7, -3, -10, -1, 20, 12, 1, -19, -19, -1, 5, 4, -7, -25, - 14, 1, -3, 2, 12, -4, -3, -3, -2, 6, 1, 0, 3, 2, 5, -1 }, - { 12, -8, 3, -12, -10, 10, 13, 0, 23, -14, -18, 10, 0, 15, 3, -12, - -3, -5, 5, -4, 2, -14, -10, 8, 2, 9, -1, -11, -3, 5, 13, 2 }, - { 9, -6, 7, -7, -30, 17, 6, 13, 1, -14, 0, -1, 6, -9, 8, 3, - -4, 0, -1, -7, -5, -13, -19, -3, -4, 4, -6, -2, -13, 1, -2, 3 }, - { 10, 1, 3, -18, -26, 17, 4, -16, 4, -3, -13, -4, -6, -11, -4, -21, - 7, 8, 2, 5, 13, -6, 1, 5, 8, 7, 9, -6, -6, 1, -1, 2 }, - { -3, -1, 0, -2, -2, 0, -1, 3, 4, -14, -8, -9, 13, 2, 50, -23, - -8, 8, 7, 11, 16, 3, -7, 0, -2, 6, 5, -1, 1, -2, 4, 3 }, - { 1, 3, 1, 1, -6, 3, 6, 6, 2, -2, -3, 10, 2, -8, -5, -5, - 5, 4, 4, -2, 10, -8, -40, -1, 21, 8, 3, -4, -1, 13, 4, 7 }, - { 2, 0, -4, -8, 5, 2, 7, -5, 5, -8, -4, -1, 12, 2, 12, -13, - -9, 0, 1, -12, 9, -43, 1, -5, 12, 1, 3, 6, 1, -1, 3, -2 }, - { 6, -2, -1, 1, 0, 4, 8, 14, 4, -7, -23, -5, 23, -17, -6, -15, - -8, 7, 10, -1, 7, -16, 4, -6, 2, 3, -3, -3, -1, 8, -1, 4 }, - { 10, 4, -4, 1, 7, -3, 2, 11, 4, -6, -3, 8, 5, 4, 1, -45, - -6, -4, 4, 2, 1, -14, -10, 1, 1, 6, 2, -8, -1, -3, 3, 3 }, - { 1, -1, 2, -3, -8, 9, 3, 3, -2, -5, -8, 8, 7, -7, -4, -6, - 5, -9, 11, -2, 46, -5, -1, 9, -2, 0, 3, -5, -3, -5, 7, 0 }, - { -4, 1, -2, -1, -11, 11, 8, -3, -2, -10, 0, 4, 9, 9, -17, -17, - -34, -4, -5, -7, -3, -12, -3, 11, 18, 3, -2, -5, -18, -5, -3, 6 }, - { 7, -5, -3, 1, -4, -3, -5, -1, 2, 5, -2, 3, -10, 12, -18, -5, - -10, 12, -9, 4, -6, 2, 0, 16, -17, 15, 14, -12, -10, -2, -9, -1 }, - { 4, -5, -3, -5, -3, -1, 7, 18, -7, 12, 3, 5, -8, -4, -20, 1, - -25, 1, -8, 13, -10, 8, -19, -1, -8, 10, 6, -9, -1, 0, 12, 4 }, - { -4, 5, 0, -1, 2, 5, -8, -2, -6, 4, -8, 9, 3, 2, -7, 4, - -25, 13, -23, 10, 14, 15, -11, 3, -18, 4, 16, -4, 1, -10, -10, 3 }, - { 5, -3, -1, -3, 4, 1, -3, -4, -5, 1, -12, 14, -7, 11, -15, 6, - -6, 24, -4, 13, -1, 15, -13, 8, 3, 7, -5, 2, 2, 0, 3, -7 }, - { -3, 1, 0, 8, 6, -1, 6, 5, -5, -2, -12, 4, 0, -2, -3, 5, - -6, 0, -8, 9, -10, 4, -28, 12, -20, 11, -13, 7, -18, 1, -11, 1 }, - { 1, -4, -15, 5, 0, -13, -5, 13, -11, 4, -4, -5, 5, -14, -16, 0, - -14, 5, -20, 12, 10, -7, -5, 6, 6, 22, 6, -4, -2, 3, 8, 11 }, - { 13, -11, -2, 16, 16, -7, 0, 20, -7, -1, 0, 5, -9, 12, -2, -5, - -22, 5, -10, 12, -6, 11, 9, 21, -8, 15, 4, 0, -8, -4, -4, 10 }, - { 18, -4, -13, 0, 1, -15, -1, -3, 2, 10, -1, 6, 1, -4, -20, -5, - -8, 6, -8, 17, -5, 5, -10, 8, -22, 6, -5, -2, 8, -17, 8, 2 }, - { 1, -2, -9, 6, -31, -8, -8, 8, 0, 5, -9, -4, 2, 3, -12, 11, - -18, 10, -5, 3, -11, 13, -6, 11, -3, 12, -7, 3, -9, -1, 2, 11 }, - { -9, -6, 21, -8, -15, 4, -11, 12, -11, 17, -1, 2, -6, 0, -15, 13, - -12, 19, 0, 2, -6, -3, -9, 10, 3, 17, -2, 5, -10, -3, 0, 1 }, - { 4, -6, 5, -10, 1, -5, 1, 0, 0, 0, 2, 7, -2, 2, -2, 0, - -4, 3, -4, 1, -12, 6, -49, 16, -10, 13, 0, -2, 8, 6, 1, 8 }, - { 5, -8, -7, 9, 13, -5, 7, 0, 10, 11, -4, -3, -1, 13, -14, 6, - -15, -6, -14, 16, 15, 1, -18, -4, -20, 20, -7, -1, -9, -2, -10, 10 }, - { -12, 4, 0, 10, 0, 3, 8, 4, -27, -1, -2, 19, -4, 2, -13, 3, - 1, 9, -12, 1, -22, 19, -5, 4, -9, 12, 2, -9, -8, 11, -3, 7 }, - { 4, -5, 11, -6, 17, -17, 5, -4, -2, -6, 1, -5, 2, 4, -14, 6, - -20, 19, -20, 12, -21, 5, -14, 13, -2, 11, 4, -3, 0, -10, -4, -2 }, - { -2, -1, -3, 8, -9, -7, -22, -3, -24, 13, -2, 10, -15, 5, -9, 4, - -7, 0, -5, 15, -8, 11, -13, 6, -4, 19, -8, 12, -4, 6, 9, 7 }, - { 2, -3, 2, -1, 0, 3, 1, 2, 1, -4, -2, -3, 1, 5, -12, 6, - -16, 14, -23, 10, -14, 17, -15, 16, -2, 9, -25, 9, -10, 16, 4, 9 }, - { -3, 7, -8, -3, 2, 2, -4, -8, -9, 10, 3, -11, 25, -10, -28, 27, - -9, 7, -13, 9, -2, 4, -12, -8, -14, 6, 7, -10, 3, 3, -3, 5 }, - { -8, -3, 1, -10, 8, -3, -9, -4, 13, 7, 2, 4, -10, 4, 3, 7, - -18, 2, -22, 15, 4, 20, -7, 5, -6, 13, -1, 4, -7, -6, 6, 13 }, - { -2, 3, 0, 2, -4, -2, 0, 0, 1, 2, -2, -5, 0, 1, -4, 0, - -2, -3, 1, 2, -1, 2, -8, -1, -24, 68, -3, 8, 3, 3, -1, -1 }, - { -15, -2, -9, -7, -1, 8, -14, 8, 3, 6, 0, -1, -8, 8, -23, 2, - -14, 17, -15, 8, -4, 7, -18, 0, -8, -3, -1, -4, -10, 4, -1, 4 }, - { 8, 0, 2, -7, 0, 5, 1, 3, -11, 4, -8, 14, 3, 20, 1, 26, - -11, 13, -13, 20, -2, 0, -8, 2, -6, 6, -1, 9, 3, -6, -3, 10 }, - { 5, 0, -1, -7, 10, 1, -3, 5, 4, 7, -5, -1, -3, -1, 12, -3, - -15, 7, -9, 22, -19, 8, -9, 4, -23, 13, -14, 6, -6, -14, -4, 7 }, - { 14, -5, -8, -10, 25, 3, -23, -7, -28, 0, -1, -9, 4, 1, -13, 20, - -8, 10, -16, 8, 12, -13, -21, 5, -13, 11, -2, 1, 12, -7, 2, -10 }, - { -5, -4, 9, 5, -6, 35, -7, 8, 15, 2, -1, -9, -6, 2, -18, 7, - -15, 6, -3, 2, 8, 12, -30, 7, -4, 20, 2, 6, 13, -6, -4, 0 }, - { 1, 8, -9, 9, -5, 12, -9, 16, -9, 16, -17, 14, -13, 15, -18, 14, - -15, 17, -12, 14, -13, 7, -16, 13, -9, 5, -11, 10, -9, 6, -12, 13 }, - { -10, -4, 5, 3, 1, 6, 8, -14, -5, 15, 7, 4, 8, 7, -22, 8, - -7, -8, -15, 26, 1, 13, -3, 17, -5, 9, -2, 4, -6, 3, -8, 9 }, - { 8, -3, 2, 3, 3, 1, -2, -1, -11, 8, -4, 0, -6, -5, -1, 13, - -37, 9, 1, -6, -10, -2, -10, 11, 8, 13, -3, -2, -6, 8, -4, 13 }, - { 3, 2, -3, -4, -4, 7, -8, 9, -8, 9, -20, 12, -19, 15, -18, 17, - -15, 7, -1, 20, -11, 6, -6, 3, 1, 9, 2, -14, -2, -2, 2, 1 }, - { -7, 1, -1, -3, -6, 4, 4, -3, 3, -1, 5, -4, 3, 2, -1, 9, - -59, 5, -4, 30, 3, 3, -2, -3, -1, 2, 2, 1, -1, -1, -2, 1 }, - { 0, -3, 2, 0, -1, -8, 0, 2, -3, 4, -4, 1, 10, 6, -6, 8, - -7, 4, 10, 11, -41, 27, -20, 3, -3, 8, 1, 11, -5, -8, 0, 4 }, - { 5, 1, 4, -2, 1, 2, -1, 6, -7, 2, 11, 4, 0, 0, -8, 7, - -10, 0, 0, 8, 2, 10, -1, 1, -2, 44, -2, -21, -12, -3, -1, 2 }, - { -4, 4, -2, -2, 6, -8, 2, 1, -10, 14, 8, 6, 5, 1, -2, 4, - -13, 4, 2, 5, 10, -2, -21, 32, -3, 18, 9, -6, -9, -9, 10, 2 }, - { 9, -16, -6, -2, 1, 4, 22, 2, -2, 1, -3, -2, -9, 3, 16, 19, - -24, -6, -6, -5, -8, -7, 8, -7, -1, -12, 5, -3, 0, 4, 2, -3 }, - { 10, 3, -16, -4, -1, 13, 4, 4, 1, -3, 1, -6, -14, 18, 3, 8, - -8, -28, -16, 4, 4, 2, 12, 7, 9, -4, -4, 5, -1, -1, 2, 2 }, - { -5, -13, -22, -3, -8, 21, -2, -9, 21, -4, -9, 5, -8, 15, 5, 1, - -5, -9, -7, -2, -5, -5, -1, -5, -5, -5, 3, 10, -4, 0, -7, -2 }, - { 5, -10, -18, 2, 20, 4, 13, -10, 8, -15, -11, -3, -1, 16, 10, 9, - -8, 6, 7, -5, 6, 11, 5, 17, -4, 7, -11, 5, -3, -6, 2, 1 }, - { 3, -5, -19, 1, 1, -3, -2, -25, -11, -17, 0, -13, -4, 10, 10, 2, - -5, 4, 0, 3, -3, -5, -10, -2, 13, -22, 0, 3, -11, -5, 7, -1 }, - { 12, -14, -29, 6, -1, 10, 7, -17, -12, 14, 3, 9, -9, 9, 7, 6, - -3, -13, 0, 5, 3, -1, -6, -1, 0, 2, 4, -12, -5, -1, 2, 11 }, - { 12, -15, -7, -2, -12, 17, 20, -16, -2, -12, -6, 15, -6, 12, 11, 9, - 7, -6, 7, -4, -19, 6, 2, 2, 3, -11, -10, -4, -5, -3, 3, 2 }, - { 11, -22, -6, 0, 8, 18, 3, -11, -4, -7, -15, -17, -12, 6, 16, 4, - -9, 4, -5, 3, 6, -16, 10, -7, -7, -3, 5, 0, 1, -15, -4, 5 }, - { 12, -22, -16, 5, -6, 8, 12, -4, -9, -17, -11, 3, 5, 8, -17, 0, - 11, -4, -13, -6, 2, -1, -1, 3, 3, -11, -12, -1, 1, 1, 12, -2 }, - { 8, -10, -33, -5, -3, -6, 1, -7, -8, -4, -6, -1, 5, -4, -6, -12, - -16, -8, 11, 8, -14, 7, 12, 11, 4, -14, -3, 6, -7, -5, -3, 3 }, - { 0, -8, -7, 2, -4, 24, 2, -9, -11, -3, -7, 11, -12, 17, 1, -1, - 3, -5, -7, 12, 4, 11, 0, 3, 2, -18, -3, 4, 7, -6, 3, 15 }, - { 10, -15, -16, -2, -4, -9, 7, -15, -6, 2, -16, 13, -8, 7, 19, -21, - -4, -12, -9, -3, -3, 6, 11, -3, -1, -19, 3, -7, -9, -4, 3, -6 }, - { -5, -10, -21, 0, -3, -7, 18, -21, 15, -5, -12, -4, -13, 2, 6, -9, - -9, -11, -4, 13, -3, 6, 4, -1, 7, -9, -4, 9, 5, 2, 6, 3 }, - { 15, -1, -27, -2, 10, 3, 7, -8, 9, -2, 7, 1, -2, -5, 18, 9, - -11, -17, -2, 7, -9, 11, 10, 0, -8, 6, -16, -3, 2, -7, 3, 11 }, - { 4, -9, -39, 19, 6, -13, 13, -5, -5, -15, -2, 9, 0, 4, 14, 6, - -10, -4, -5, 2, -4, -2, 5, -11, 3, 3, -2, -2, -7, 9, 7, -10 }, - { 5, -11, -8, 10, -2, 12, 16, 0, 12, -2, -6, 8, 14, 8, 7, 1, - 18, -30, 4, 10, -4, -6, 2, -11, 9, -10, -8, 5, 0, 0, -7, 6 }, - { -1, -16, -10, 11, 0, 13, 12, -4, -4, -5, -21, 12, 4, 13, 14, -7, - 6, -16, -13, 8, 2, 9, 15, -12, 1, -9, -22, 10, -9, 9, 9, -7 }, - { 4, -12, -27, 1, -2, 11, 15, 3, 14, -14, -9, 0, -9, 16, 22, 10, - 16, -10, 5, -5, -9, 1, 1, 6, 6, -4, 2, -17, -5, -6, -15, -1 }, - { 7, -12, -17, 1, -9, 5, 20, -7, 3, 23, -8, -8, -8, -1, 13, 17, - -7, -13, 4, -4, 7, 14, 8, 11, -3, -3, 4, 0, 4, 6, -1, -9 }, - { 7, -15, -15, -4, 10, 12, 3, -13, 6, 14, 9, -8, -15, 14, 23, -5, - -10, -5, 1, 15, -10, -7, 1, 9, 4, -13, -10, 10, 7, -3, 2, 3 }, - { 4, -10, -14, 0, 3, 4, 0, -9, -3, -4, -11, 2, -17, 8, 2, 15, - 6, -12, -12, 15, -5, 17, 18, 3, -3, -3, -4, -6, -8, 13, 4, 10 }, - { -2, -18, -26, 10, -4, 10, 13, 4, -4, -16, -7, -17, -3, 5, -4, 2, - -15, -10, -1, -8, -7, -3, 2, 2, 8, -10, -7, 2, 2, -4, 4, -1 }, - { 4, -19, -5, -1, -1, -6, 2, -8, 10, -16, -28, -6, 8, -1, 11, 28, - 2, -10, -4, 6, -6, 6, 11, 15, -4, -2, 7, 3, 7, -7, 4, 1 }, - { -3, -6, -10, -5, 13, 18, 10, -15, -5, -3, -13, 5, 1, 2, 18, -5, - -10, -10, -7, 4, 2, 1, 5, 4, 2, 5, 4, 8, -9, -17, 7, 7 }, - { 20, -12, -2, -4, 5, 14, 7, -11, -1, -16, -6, -4, -11, 17, 14, 0, - -8, -10, -8, 10, 3, 5, 10, -16, 3, -8, -14, 10, 3, 9, 0, 3 }, - { 12, -10, -36, 0, 7, 15, 2, -16, 2, -1, 0, -1, 5, 4, 5, -3, - 1, -10, 5, -1, -15, -3, -12, 12, 2, 5, -1, 5, 6, -3, -2, 2 }, - { 17, -15, -31, 23, -4, 15, -2, -3, 6, -7, -5, 1, -12, 4, 6, 8, - -10, 8, 3, 5, -4, 1, 5, 3, -1, -4, -3, 1, 10, -4, -2, -2 }, - { 6, -18, -5, 12, 10, 12, 14, -11, 15, 2, -9, -6, -5, -2, -9, 4, - -5, -28, -4, 14, 0, -16, 9, 14, -1, 3, -4, -4, 2, 1, 0, 4 }, - { -5, -14, -31, 8, 16, 7, 13, -13, 5, 6, -16, 10, -5, 2, -2, 2, - 14, -5, 8, -5, 7, -16, 6, -13, -5, 0, -5, 8, -3, -1, 4, 3 }, - { 1, -2, -1, 0, 6, 5, 2, -4, -3, -1, 0, 1, 4, 2, 43, 28, - -12, -35, -2, -2, -7, -1, 0, 2, -1, -2, -2, 1, -4, 0, -2, 3 }, - { 2, -9, -22, 12, 3, 3, -7, -4, -19, -22, -14, -4, -1, 21, 9, -3, - -15, -16, -13, 1, -11, 4, -9, 1, -7, -1, -1, 0, -2, 9, -13, -3 }, - { -1, -3, -23, 0, 2, 12, 3, -9, -4, 7, 3, 9, -10, 1, 27, 28, - 0, 9, -15, -2, -2, 1, 6, 8, -8, 7, -3, 20, 0, 0, -1, -6 }, - { -1, 11, 8, -2, 1, 5, -6, -1, 4, 2, -4, 0, -1, -5, 4, -6, - -10, -12, 19, 1, -7, 9, -8, -9, -16, -11, -2, 12, 14, 4, 4, 34 }, - { 17, 7, -6, 1, 4, -10, -5, 4, -11, 3, -18, 4, 14, -13, -3, 1, - 0, 0, -11, 0, 7, -17, -4, 4, -11, -6, -8, 18, 0, 0, 0, 26 }, - { -6, -7, -1, -1, 11, -8, 1, 3, 2, 11, -6, -6, 10, -3, 1, -3, - 7, 4, -12, -8, 0, -9, 8, -22, -5, 0, -6, 22, -2, 11, -13, 24 }, - { -3, 4, 0, 3, 9, 10, -1, 3, -9, -12, 1, -5, 18, 0, -3, 8, - 25, 15, -8, 2, 2, -2, 4, 8, 9, -1, -5, 10, -3, 1, -1, 23 }, - { -5, 2, -9, -1, -3, 0, 3, -1, -10, -4, 0, -13, 16, 9, -1, -14, - 2, 6, -2, -6, -5, -2, -7, 7, 5, 3, 11, -2, -14, 0, -9, 30 }, - { 4, 6, 6, 5, -3, -1, 4, 5, 10, 0, 5, -4, 7, -11, 14, 14, - 7, 34, -9, 0, -10, 22, -7, -1, 7, -9, 2, -8, 0, -7, -5, 29 }, - { -4, 3, -1, -4, -3, 5, 1, -4, 0, 2, 4, 2, 1, -1, -10, 1, - 6, -6, -4, 1, 4, -3, -3, -5, 0, 3, 7, -12, 0, -2, -10, 55 }, - { 5, 9, -1, 0, 4, 9, -21, -9, 4, 2, 6, -7, 11, -7, 1, -5, - 0, -4, 2, -3, -13, -8, 0, -9, -4, 2, 16, -2, -15, -7, -11, 31 }, - { 8, 2, -1, 0, 3, -5, -5, 5, 1, -1, -9, 1, 0, -6, -2, -1, - 5, 2, 0, 0, 12, 20, -19, 1, 8, -12, -11, 0, 6, -5, 2, 31 }, - { -1, -1, -2, 1, -1, 3, -9, -5, 8, -2, 5, -1, 0, -2, 4, -2, - -3, -12, 0, -2, 3, 0, 9, 4, -1, 21, -8, 3, -4, 9, -6, 30 }, - { -4, 0, -7, 17, 10, -12, -2, -10, -12, -3, 10, 0, 11, -4, -13, -3, - 5, 6, 10, 7, -8, 0, -7, -13, 1, 0, -2, 7, -12, 4, -3, 24 }, - { -13, 9, 4, -2, 2, -4, -14, -1, -3, -5, -10, 4, 13, -2, 5, 13, - 8, 3, -2, 1, 5, -6, 7, -18, -10, 1, -1, 5, 4, 1, 0, 25 }, - { -5, -1, 18, 12, 8, 8, -16, -1, 1, 1, 1, -4, -5, 3, 3, 4, - 4, -11, -12, -16, -6, 2, 12, -13, 0, 9, 7, 9, -9, 0, -10, 24 }, - { -4, 1, -3, 0, 2, -4, 4, 1, 5, 0, -3, 2, -3, -2, 2, -1, - 1, 4, -1, -2, -2, 1, -1, -1, -4, -1, -4, -2, -6, 6, 12, 69 }, - { 8, 5, 11, 0, -15, -4, 13, 6, 0, -4, 9, 1, -5, -3, 15, 0, - 1, 6, -5, 0, 1, 6, 5, 8, 0, 7, 1, -1, -4, -11, -9, 41 }, - { -4, -9, 32, -6, 0, 7, -4, 6, -6, 1, -6, -2, 4, -8, -5, -3, - -16, -1, -2, -6, 1, 15, 0, 21, 3, -3, -4, 3, -12, 16, 2, 27 }, - { -6, -5, 1, -9, -5, 3, 7, -3, 5, 5, 14, 13, 20, -7, -1, 12, - -1, 10, -11, -11, -7, -4, -14, 7, -14, 13, 22, 18, -1, 0, 14, 28 }, - { -8, 3, -2, 0, 5, 6, -1, -4, 1, 3, -7, 3, 1, -15, 4, -9, - 22, -10, -9, -4, 1, 8, -4, 9, -15, 2, -6, -4, -16, 12, -10, 23 }, - { 0, 0, 2, 0, -1, 3, -3, -1, 3, -5, 7, 1, 5, -5, -8, 1, - 13, -15, -5, -7, 12, -6, -2, 3, 10, -5, -8, 17, -5, -11, -14, 23 }, - { -7, -4, 6, -4, 5, -6, -5, 2, -4, 11, 9, -4, 2, -2, -4, 6, - 15, 3, -3, 18, -15, -2, -6, 3, 3, -20, 17, 11, -4, 2, 3, 29 }, - { 6, 1, -6, 2, 3, 0, 0, -3, 3, 3, -1, 3, -4, -6, -6, -7, - -3, -2, -7, -2, -4, 5, 3, -5, -20, -13, -4, 10, -14, -29, 14, 37 }, - { 3, 4, 3, -6, -4, 5, 0, 3, 2, 3, 0, -2, 4, 0, -3, -5, - -4, 4, -4, 4, 4, 3, 1, -4, -4, -9, -14, 20, -30, 3, -18, 33 }, - { 0, 2, 5, -2, -4, -2, -1, 2, -6, -3, -2, -2, 2, -5, -1, 4, - 3, 2, -3, 0, -1, -1, -10, -7, 2, -4, -18, 2, -37, -1, 12, 40 }, - { -7, 2, -1, 0, -2, 4, -8, 1, -4, 12, 7, 4, 15, -7, 1, -9, - 18, 0, 12, -17, -3, -1, 0, 0, 0, 2, -6, 0, -4, -3, -1, 26 }, - { -6, 4, 8, -5, -6, -2, 2, -1, 1, -1, -15, 8, 7, -1, -17, -4, - 1, 5, 6, -11, -6, 14, 17, -5, -15, 11, 8, 0, -3, -15, -6, 28 }, - { -1, 0, 0, 0, 1, 0, -1, 0, 1, 3, 2, -2, 3, -1, -1, 2, - 2, -1, -1, -7, 1, 2, -9, 0, -1, -4, -18, 7, -10, 49, -13, 32 }, - { -1, -3, 4, 1, 2, -5, 1, -7, -1, 5, -9, 4, 4, 25, 1, -1, - 2, -5, 2, -7, 17, -2, 10, -5, 0, 2, -15, 3, -9, 7, -9, 30 }, - { -5, -1, 0, 2, 1, -1, 2, 5, -33, 3, -5, 14, 11, 7, 5, -3, - 2, -8, -4, -2, -7, -6, 4, -8, -1, -8, 2, -2, -8, -1, -4, 27 }, - { -1, 0, -1, -2, 1, -1, -2, -1, 2, 0, 1, 2, 2, 4, 1, 3, - 4, 2, 1, -7, -4, 1, -3, -4, -35, -25, 17, 10, -3, -26, -7, 32 }, - { -5, 1, 6, -2, 6, 6, -9, 3, -1, -4, 5, -4, -2, -2, -9, 2, - -5, 2, 2, 4, 3, 5, -5, -16, -31, -12, -11, 2, -19, 20, -2, 21 }, - { -5, 2, 7, -7, -7, 5, -7, 2, 0, 0, -4, 3, -1, 0, -1, -2, - 0, -3, 5, -11, -8, -3, -7, -7, 28, -11, -7, 0, -16, -11, -4, 29 }, - { 2, 1, -3, -2, -1, 3, 4, 0, 1, 0, -1, -5, 4, -5, -12, 2, - -2, -5, -22, -2, -1, 11, 8, -7, -12, 0, -34, 6, -5, 11, -8, 19 }, - { -1, -3, 5, 11, 18, -2, -2, -5, -2, 4, -1, 8, 5, -6, 1, -1, - 2, 8, 4, -5, -8, -2, 5, -18, 7, 12, 7, 19, -18, 2, -6, -13 }, - { 9, 0, 0, 5, 4, 3, -6, 4, 1, -4, 5, -1, -4, 8, 8, 6, - -8, -6, 0, 6, -3, 3, 5, -3, 17, 31, 16, 10, -13, 0, -9, -19 }, - { 12, -10, 2, -2, -2, -1, -3, 6, -12, -5, -2, 14, -16, 4, 12, 12, - 17, 4, 7, -16, 7, -6, 11, 7, 7, 2, -25, 23, -24, 5, -7, -9 }, - { 10, 4, 13, 10, 10, 3, -6, 3, 3, 2, -1, -6, 8, 4, 10, 0, - 1, 2, -4, 2, -3, -8, 0, -1, 9, 9, -10, -3, -29, 1, -1, -27 }, - { 2, 2, 0, 7, 9, -2, -10, -1, -1, 1, -9, -5, 8, 4, 1, 2, - -10, 1, 13, 12, -3, 15, -9, 2, -7, 1, -10, 23, -20, -18, -9, -15 }, - { -3, -5, -1, 8, 0, -5, -1, 4, 7, -1, -7, 2, -8, -5, 11, 7, - -6, 3, -3, -9, 7, 9, -22, 1, 6, -4, 14, 27, -25, -14, 3, -5 }, - { 1, 3, 8, 4, 7, 6, 12, -17, -15, 1, -8, -10, 7, -14, -8, 6, - -2, -2, -11, -11, -7, 13, -2, -2, 4, 5, -5, 13, -23, -6, -17, -8 }, - { -5, 4, -14, -5, -4, -5, 6, 5, -8, -5, -2, -11, -7, -12, 3, -11, - 2, -6, 4, -10, -5, -7, 14, 5, 23, 11, 7, 12, -16, -6, -4, -16 }, - { 5, 6, 2, 5, -2, -5, -5, -6, -5, -19, -13, -1, -3, -13, 5, 0, - 6, -2, -2, -6, -7, -7, -1, -9, 4, 14, 17, -12, -27, 3, 0, -1 }, - { 7, -1, 9, -10, 8, 2, -7, -2, 5, 2, -3, -7, 3, 0, 6, 4, - 12, 5, 11, 14, -13, -1, 8, 1, 13, 9, 12, 12, -18, -14, -11, -16 }, - { -7, -5, -6, -5, 0, -1, -3, 2, 2, 1, 4, 9, 2, 3, 5, -2, - 2, 1, 8, 0, 3, 0, -2, 2, 1, 7, 29, 0, -36, -5, -9, -21 }, - { 14, -6, -9, 0, -1, -8, -8, -11, 2, 2, -9, -12, 12, -4, 5, 3, - -5, -9, 11, -1, -3, 12, -21, -3, 12, 5, 3, 11, -18, -15, 1, -2 }, - { -1, 3, -9, -3, 7, -7, -18, 2, 4, 12, -10, 2, 8, -3, -14, 13, - 17, -5, 5, -9, 13, -3, -7, -18, 17, -2, 5, 7, -20, -3, -6, -11 }, - { -3, 3, 3, -1, 1, -6, -5, 1, 5, -3, -14, -6, -5, -8, 14, -6, - 7, -1, 5, 1, 15, -1, -7, -4, 6, -11, 9, -2, -37, 16, -7, -3 }, - { -1, 0, 6, 1, -3, -9, 0, 11, -8, 2, -2, 0, 5, 2, 12, -10, - 10, 13, 2, 7, -6, 2, -10, -10, 21, -5, 5, 5, -12, -23, 3, -14 }, - { 6, 0, -2, 1, 0, 1, 0, -4, 1, 1, 8, -2, 2, -5, -2, 1, - 8, -4, -1, -1, 4, -1, 2, 6, 32, 1, -5, -20, -40, -4, -18, -14 }, - { 2, 2, -7, -2, 4, 4, -1, 2, 0, -2, -4, -7, 3, 5, 0, -5, - 1, 2, -6, 4, -1, -2, -1, -15, 8, 3, 9, 46, -7, -18, 6, -11 }, - { 5, 5, 16, 21, 3, -11, -4, 11, -12, 2, 4, -12, -1, 11, 8, 1, - -4, 11, -11, -21, 1, 1, -11, 3, 13, 1, 5, 12, -25, 1, -3, -2 }, - { 1, 6, -7, 4, 2, 3, 1, -5, 8, 9, -15, 3, -3, -14, 17, 4, - -8, 14, -2, -8, -4, 5, 8, -7, 8, 9, 7, 6, -29, -17, 8, 4 }, - { -7, -7, 4, 0, 13, 1, 0, 4, 4, -16, -10, -7, 5, 9, -15, -10, - -10, 8, -4, -1, -11, -1, -10, -15, 3, 3, 14, 10, -19, 2, -18, -12 }, - { -4, 0, 2, 0, 5, -2, -9, 0, 4, -4, 2, -1, -2, 2, -4, 9, - 2, -6, -4, -2, -1, -3, -3, -1, 2, 5, -1, 11, -24, -44, -9, -15 }, - { -1, -10, 6, 21, 11, 15, -7, 10, -14, -9, -8, -8, 4, 6, 19, 1, - -6, 1, -5, -17, -8, -10, 9, 5, 11, 18, -1, 10, -16, -7, -9, -8 }, - { 3, -5, 0, 0, -2, -2, -6, 4, -4, 1, -1, 0, 7, -3, 4, -4, - -7, 7, 17, -20, 6, 4, 1, -6, -12, 31, 13, 19, -14, -10, -7, -2 }, - { -2, 6, -10, 3, 9, 6, -14, 15, 2, -5, 2, -11, 9, -8, 4, 6, - 20, -15, -3, -3, -1, 32, -21, 6, 1, 9, 11, 17, -19, 6, -1, -3 }, - { 8, 10, -2, 0, -8, -16, 7, 7, 6, 10, 4, -14, 7, -6, 21, -7, - 10, 5, 5, 0, -7, 2, -6, 0, -7, 11, -9, 15, -20, -7, -11, 2 }, - { 0, -7, 5, 2, 0, -3, -6, -4, -2, -1, -4, -5, -13, -1, 27, -9, - -6, -11, -7, 1, 11, -4, -4, -14, -2, 11, 6, 10, -19, -6, -15, 2 }, - { 0, 7, -1, 2, -7, -15, -2, -3, 13, -5, -5, 12, 3, 0, 5, -5, - -22, 2, 7, 22, 13, 0, -1, 2, 3, 2, -7, 7, -27, -4, -4, -12 }, - { 11, 1, -16, 6, -15, 1, 3, 2, 0, 2, -3, 2, 5, -2, -5, 9, - 5, -3, 3, -2, -11, 3, 9, 6, 9, 3, -1, 12, -41, 8, -6, 9 }, - { 3, -7, 3, 2, 5, 5, 0, -1, 1, 3, -5, -2, -13, 7, -1, -2, - -2, -6, 4, -6, 0, 2, -2, 2, 4, 1, -4, 1, -47, -21, 7, -6 }, - { 3, 16, -7, 13, -4, -2, 10, -3, -1, 18, -13, 7, -13, -4, 8, 4, - 8, 9, -5, 13, 8, -5, 3, -6, 7, 18, -8, 10, -25, -3, -12, -12 }, - { 1, -1, -1, 0, 2, 5, -5, -3, 0, -5, -1, 0, -4, -8, -2, 3, - 2, -2, -17, -6, -4, 1, 33, -6, -20, -6, 8, 31, -26, -8, -1, -4 }, - { 3, -3, -3, 5, -3, -2, 1, 7, 0, 3, 6, 3, 6, -2, 9, 15, - -10, -3, -15, -5, -3, -4, -6, -30, 17, -8, -2, 2, -20, 0, -8, -2 }, - { -2, -1, -1, -1, 3, -5, -2, -3, 4, -2, 0, 5, 8, -3, 1, -4, - 1, 1, -3, 4, 4, -14, 3, 11, -5, 3, -3, 7, -3, 13, 23, -16 }, - { 2, -6, 1, -3, 5, 0, -6, -11, -7, -4, -1, 2, -7, -1, -1, 7, - 1, -2, 6, 12, -6, 8, -13, 17, 25, -23, -19, -7, -12, 9, 16, -17 }, - { 9, 4, 4, 4, -3, -1, 6, -2, -3, 0, 13, -4, -7, 14, 1, -7, - 0, -5, 3, -19, -3, 5, 3, 9, -1, 9, -13, 13, -17, 4, 21, -26 }, - { 0, -5, 0, 0, -4, -5, 2, -6, -4, 5, -7, 10, 0, 2, 0, -2, - -2, 0, 4, -6, 7, -2, 6, 5, -5, 2, -12, 1, -29, 29, 27, 12 }, - { 9, -10, -22, 6, -1, -1, 9, -14, -12, -2, 1, -1, 10, -11, -16, 0, - 3, 11, 13, -14, -9, -2, -1, 6, 4, -14, 0, -10, -2, 16, 17, -11 }, - { 2, 0, -1, -2, 4, 3, -6, -2, 1, -1, 1, 3, -4, 1, 3, -4, - -1, -1, 4, -1, 1, 0, 1, 6, -5, -7, 2, 1, -47, -3, 50, -17 }, - { 8, -4, -11, -7, 11, 11, 14, -7, 12, -7, 6, 2, 13, -6, -3, -2, - -14, 6, 6, 6, 0, 2, -1, 5, -20, 2, -1, 4, -5, 6, 21, -11 }, - { -2, -9, 3, 0, -6, 7, 8, -8, 1, -3, 4, 1, 5, -2, -3, -7, - 4, 7, -12, -9, -2, 10, -6, 13, 6, 5, 20, 2, -15, 9, 28, -7 }, - { 0, -5, -6, -6, -6, 1, -6, 6, -2, 4, 8, -3, 12, -1, -4, -2, - 6, 16, -14, 9, -14, -2, -8, -27, -3, 18, -1, -7, -3, 8, 23, -23 }, - { 1, 4, -9, -1, -5, 10, -2, 1, -11, 1, -9, 4, 7, 14, -9, -2, - -3, 2, -5, -1, -6, -10, -7, 11, 20, 2, 3, -19, 3, 15, 30, -9 }, - { 7, 2, -14, -4, 0, -2, 5, 2, 5, -2, 8, -3, -7, 6, 6, -11, - -14, 1, 10, -1, -7, -8, 1, 10, 3, -6, -15, -12, -17, 4, 30, -6 }, - { 4, 2, 1, -2, 3, 0, 1, 0, 2, 0, 1, 6, -7, 0, 3, 4, - 4, -4, -2, -5, -2, 2, -1, -2, 0, -2, -11, -7, -3, 42, 24, -14 }, - { 4, 1, 3, 2, 0, -2, -3, -2, 2, -1, 4, 11, -2, 2, 3, -4, - -5, 9, 2, -4, -9, 5, 8, -1, -7, 1, 24, -13, -28, 20, 15, -22 }, - { -3, 7, 6, 3, -2, -5, -10, -2, -2, -1, -6, -6, -2, -14, -16, -6, - -5, 0, 18, 0, 9, 1, 7, -13, -5, -6, -9, 11, -15, 9, 22, -11 }, - { 9, -2, 6, 5, 2, 9, -10, 1, 1, 5, -4, 12, 2, 2, -10, -7, - -4, -6, 7, 9, 6, 15, 6, 6, -10, 10, 5, -13, -5, 6, 24, -12 }, - { 1, 3, -3, -3, 8, 1, -6, 2, -5, -3, 7, 2, 14, 6, 9, -6, - -5, -4, 27, 7, -3, 8, -6, 3, -8, 8, 22, -5, -6, -2, 22, -17 }, - { -2, -2, 3, 10, 9, 9, 12, -15, -1, -11, -13, 3, -2, 1, -3, -11, - 7, 9, 16, -3, -10, -5, -5, 1, 8, -3, 9, 9, -5, 3, 31, -12 }, - { 7, -5, 10, -4, -8, 2, 16, -2, 10, 10, -3, -2, 3, -8, -3, 3, - -13, -6, 15, 20, -9, -3, -12, 1, -2, -16, 8, 8, -1, 16, 22, -5 }, - { 5, -3, -15, -2, 12, -8, 8, -5, 2, -8, 20, -18, 14, -4, 3, 3, - 7, -13, -16, 1, -10, 7, 16, 7, 4, -14, -4, -5, -9, 8, 23, -6 }, - { 5, -4, -5, -4, 1, 8, 4, -7, -5, 8, 10, 6, -6, -10, -2, 6, - 9, -17, -14, 11, 12, -3, -13, -7, 2, 18, 3, -25, -16, 18, 22, -5 }, - { 5, 6, -7, -20, -4, 2, 8, 4, -24, -4, 1, 4, -5, -2, 1, -10, - -2, 9, 3, -4, -3, -4, -4, -4, 10, 10, 3, 0, -6, 25, 21, -11 }, - { 0, 7, -1, 14, -6, -4, -10, 5, 4, 4, 4, -5, 3, 4, -1, -7, - 8, -19, 0, 6, 2, 3, -18, -3, -6, 2, 8, 14, -26, 22, 27, -13 }, - { -2, -6, 7, -5, 12, -7, 8, -1, 3, -2, 4, 1, 8, -2, 0, 14, - 6, -5, 6, -4, -7, 7, -21, 8, 1, 8, -9, -4, -3, 11, 25, -13 }, - { 4, 4, -1, -6, 4, 9, -8, 1, -3, -10, -2, 0, 15, -9, -16, 11, - 1, 1, 6, 3, -9, -5, 16, 26, 1, -14, 1, -3, -14, 7, 15, -9 }, - { -12, -2, -9, -13, 2, 6, 14, 0, 1, 0, -1, -13, 0, 10, -1, 6, - 9, -7, 8, 8, 19, 6, -1, 9, 10, -4, 1, -7, -22, -2, 29, -7 }, - { 2, 4, 13, -12, -8, -4, -5, 13, 12, -5, -3, -3, -4, 1, -1, 10, - 15, -6, -1, -11, -30, 4, 15, -1, 9, -7, 0, -2, -7, 10, 25, -16 }, - { 7, -15, -7, -7, -1, -5, -5, -11, -20, 10, 3, -10, -3, 5, 20, -4, - 0, -2, -2, 17, 2, 0, -3, 3, 6, 5, -1, -12, -3, 15, 22, -16 }, - { 4, -1, 3, 4, -5, 0, -1, -5, -24, -29, 4, -9, 1, -3, 0, 0, - 0, -4, 7, -4, -4, -4, 3, 1, -6, 5, -3, -5, -10, 3, 25, -10 }, - { -2, -1, -1, 4, 4, -1, 2, 0, -4, -4, 2, -1, -3, -1, -2, -2, - 1, -3, -5, -1, 2, -3, -4, -4, -3, 5, -9, 1, -11, 7, 46, -46 }, - { 0, -9, 3, 4, 4, 3, -5, -6, 5, -4, 4, -2, 1, 7, -4, -10, - 13, 1, 3, -6, 4, -4, 7, 2, -19, -25, -3, -16, -12, 16, 20, -1 }, - { 18, 6, 4, -12, 0, -14, 9, -6, -1, -4, -5, 2, 1, 12, 4, 2, - 7, 0, 2, 5, -11, -5, -2, 2, -4, 10, 0, -9, -7, 9, 25, -8 }, - { 5, 0, -6, 5, 6, 3, 3, -10, -5, 1, -1, 4, 3, -11, -8, 5, - 4, -5, 5, -5, -7, -5, 11, 5, 20, -8, -16, 21, -4, 27, 23, -5 } -}; - - -/* FIR filter coefficients, they can be cut on half and maybe use float instead of double*/ - -DECLARE_ALIGNED(16, static const float, fir_32bands_perfect)[] = -{ -+1.135985195E-010, -+7.018770981E-011, --1.608403011E-008, --5.083275667E-008, --1.543309907E-007, --3.961981463E-007, --7.342250683E-007, --3.970030775E-007, --4.741137047E-007, --6.022448247E-007, --6.628192182E-007, --6.982898526E-007, --7.020648809E-007, --6.767839409E-007, --6.262345096E-007, --5.564140224E-007, -+7.003467317E-007, -+8.419976893E-007, -+9.742954035E-007, -+1.085227950E-006, -+1.162929266E-006, -+1.194632091E-006, -+1.179182050E-006, -+1.033426656E-006, -+9.451737242E-007, -+1.975324267E-006, -+1.190443072E-006, -+5.234479659E-007, -+2.014677420E-007, -+7.834767501E-008, --6.702406963E-010, --1.613285505E-009, --2.682709610E-009, --3.399493131E-009, -+1.314406006E-008, -+7.506701927E-009, -+2.788728892E-008, -+1.444918922E-007, -+3.132386439E-007, -+1.399798180E-006, -+2.032118118E-006, -+2.715013807E-006, -+3.453840463E-006, -+4.195037945E-006, -+4.896494374E-006, -+5.516381407E-006, -+6.015239251E-006, -+6.361419310E-006, -+8.006985809E-006, -+8.087732567E-006, -+7.941360309E-006, -+7.568834008E-006, -+6.986399967E-006, -+6.225028756E-006, -+5.315936960E-006, -+4.429412002E-006, -+3.332600045E-006, -+8.427224429E-007, -+4.341498823E-007, -+9.458596395E-008, -+2.975164826E-008, -+6.402664354E-008, --3.246264413E-008, --3.809887872E-008, -+8.434094667E-008, -+6.437721822E-008, -+1.189317118E-006, -+2.497214155E-006, -+3.617151151E-006, -+3.157242645E-006, -+2.319611212E-006, -+7.869333785E-006, -+9.826449968E-006, -+1.177108606E-005, -+1.379448349E-005, -+1.571428584E-005, -+1.743183020E-005, -+1.884208177E-005, -+1.987093310E-005, -+2.042970118E-005, --3.144468428E-005, --3.334947178E-005, --3.460439257E-005, --3.515914432E-005, --3.495384954E-005, --3.397853652E-005, --3.225446198E-005, --2.978993689E-005, --2.677291741E-005, --1.806914770E-005, --1.776598037E-005, --1.661818715E-005, --1.207003334E-005, --6.993315310E-006, --5.633860383E-007, --9.984935332E-007, --1.470520488E-006, --1.853591357E-006, -+7.198007665E-007, -+3.086857760E-006, -+6.084746474E-006, -+9.561075785E-006, -+1.309637537E-005, -+2.263354872E-005, -+2.847247197E-005, -+3.415624451E-005, -+3.946387005E-005, -+4.425736552E-005, -+4.839275425E-005, -+5.176846025E-005, -+5.429694284E-005, -+5.595519906E-005, -+4.916387297E-006, -+9.299508747E-006, -+1.356193479E-005, -+1.751866148E-005, -+2.093936746E-005, -+2.362549276E-005, -+2.537086584E-005, -+2.618136386E-005, -+2.554462844E-005, -+3.018750249E-005, -+2.570833203E-005, -+1.985177369E-005, -+1.191342653E-005, -+2.525620175E-006, --1.521241393E-005, --1.617751332E-005, -+1.992636317E-005, -+1.774702469E-005, -+4.624524081E-005, -+5.610509834E-005, -+6.568001118E-005, -+7.513730816E-005, -+8.413690375E-005, -+8.757545584E-005, -+9.517164290E-005, -+1.020687996E-004, -+1.084438481E-004, -+1.140582463E-004, -+1.187910311E-004, -+1.224978914E-004, -+1.250260248E-004, -+1.262027217E-004, -+1.226499153E-004, -+1.213575742E-004, -+1.180980107E-004, -+1.126275165E-004, -+1.047207043E-004, -+9.417100227E-005, -+8.078388782E-005, -+6.447290798E-005, -+4.491530854E-005, -+2.470704203E-005, --1.714242217E-006, --3.193307566E-005, --6.541742187E-005, --1.024175072E-004, --1.312203676E-004, --1.774113771E-004, --2.233728592E-004, --2.682086197E-004, --3.347633174E-004, --3.906481725E-004, --4.490280990E-004, --5.099929986E-004, --5.729619297E-004, --6.358824321E-004, --7.021900383E-004, --7.698345580E-004, --8.385353722E-004, --9.078957955E-004, --9.775133803E-004, --1.046945457E-003, --1.115717343E-003, --1.183370827E-003, --1.252829796E-003, --1.316190348E-003, --1.376571832E-003, --1.433344092E-003, --1.485876855E-003, --1.533520175E-003, --1.575609902E-003, --1.611457788E-003, --1.640390139E-003, --1.661288203E-003, --1.674512983E-003, --1.678415807E-003, --1.672798418E-003, --1.656501088E-003, --1.633993932E-003, --1.593449386E-003, -+1.542080659E-003, -+1.479332102E-003, -+1.395521569E-003, -+1.303116791E-003, -+1.196175464E-003, -+1.073757303E-003, -+9.358961834E-004, -+7.817269652E-004, -+6.114174030E-004, -+4.244441516E-004, -+2.206075296E-004, --2.719412748E-007, --2.382978710E-004, --4.935106263E-004, --7.658848190E-004, --1.055365428E-003, --1.361547387E-003, --1.684492454E-003, --2.023874084E-003, --2.379294252E-003, --2.750317100E-003, --3.136433195E-003, --3.537061159E-003, --3.951539751E-003, --4.379155114E-003, --4.819062538E-003, --5.270531867E-003, --5.732392892E-003, --6.203945260E-003, --6.683901884E-003, --7.170005701E-003, --7.664063945E-003, --8.162760176E-003, --8.665001951E-003, --9.170533158E-003, --9.676489048E-003, --1.018219907E-002, --1.068630442E-002, --1.118756086E-002, --1.168460958E-002, --1.217562053E-002, --1.265939046E-002, --1.313448418E-002, --1.359948888E-002, --1.405300573E-002, --1.449365262E-002, --1.492007636E-002, --1.533095632E-002, --1.572482102E-002, --1.610082202E-002, --1.645756140E-002, --1.679391414E-002, --1.710879989E-002, --1.740120351E-002, --1.767017506E-002, --1.791484281E-002, --1.813439466E-002, --1.832821220E-002, --1.849545911E-002, --1.863567345E-002, --1.874836907E-002, --1.883326657E-002, --1.889026538E-002, --1.891860925E-002, -+1.891860925E-002, -+1.889026538E-002, -+1.883326657E-002, -+1.874836907E-002, -+1.863567345E-002, -+1.849545911E-002, -+1.832821220E-002, -+1.813439466E-002, -+1.791484281E-002, -+1.767017506E-002, -+1.740120351E-002, -+1.710879989E-002, -+1.679391414E-002, -+1.645756140E-002, -+1.610082202E-002, -+1.572482102E-002, -+1.533095632E-002, -+1.492007636E-002, -+1.449365262E-002, -+1.405300573E-002, -+1.359948888E-002, -+1.313448418E-002, -+1.265939046E-002, -+1.217562053E-002, -+1.168460958E-002, -+1.118756086E-002, -+1.068630442E-002, -+1.018219907E-002, -+9.676489048E-003, -+9.170533158E-003, -+8.665001951E-003, -+8.162760176E-003, -+7.664063945E-003, -+7.170005701E-003, -+6.683901884E-003, -+6.203945260E-003, -+5.732392892E-003, -+5.270531867E-003, -+4.819062538E-003, -+4.379155114E-003, -+3.951539751E-003, -+3.537061159E-003, -+3.136433195E-003, -+2.750317100E-003, -+2.379294252E-003, -+2.023874084E-003, -+1.684492454E-003, -+1.361547387E-003, -+1.055365428E-003, -+7.658848190E-004, -+4.935106263E-004, -+2.382978710E-004, -+2.719412748E-007, --2.206075296E-004, --4.244441516E-004, --6.114174030E-004, --7.817269652E-004, --9.358961834E-004, --1.073757303E-003, --1.196175464E-003, --1.303116791E-003, --1.395521569E-003, --1.479332102E-003, --1.542080659E-003, -+1.593449386E-003, -+1.633993932E-003, -+1.656501088E-003, -+1.672798418E-003, -+1.678415807E-003, -+1.674512983E-003, -+1.661288203E-003, -+1.640390139E-003, -+1.611457788E-003, -+1.575609902E-003, -+1.533520175E-003, -+1.485876855E-003, -+1.433344092E-003, -+1.376571832E-003, -+1.316190348E-003, -+1.252829796E-003, -+1.183370827E-003, -+1.115717343E-003, -+1.046945457E-003, -+9.775133803E-004, -+9.078957955E-004, -+8.385353722E-004, -+7.698345580E-004, -+7.021900383E-004, -+6.358824321E-004, -+5.729619297E-004, -+5.099929986E-004, -+4.490280990E-004, -+3.906481725E-004, -+3.347633174E-004, -+2.682086197E-004, -+2.233728592E-004, -+1.774113771E-004, -+1.312203676E-004, -+1.024175072E-004, -+6.541742187E-005, -+3.193307566E-005, -+1.714242217E-006, --2.470704203E-005, --4.491530854E-005, --6.447290798E-005, --8.078388782E-005, --9.417100227E-005, --1.047207043E-004, --1.126275165E-004, --1.180980107E-004, --1.213575742E-004, --1.226499153E-004, --1.262027217E-004, --1.250260248E-004, --1.224978914E-004, --1.187910311E-004, --1.140582463E-004, --1.084438481E-004, --1.020687996E-004, --9.517164290E-005, --8.757545584E-005, --8.413690375E-005, --7.513730816E-005, --6.568001118E-005, --5.610509834E-005, --4.624524081E-005, --1.774702469E-005, --1.992636317E-005, -+1.617751332E-005, -+1.521241393E-005, --2.525620175E-006, --1.191342653E-005, --1.985177369E-005, --2.570833203E-005, --3.018750249E-005, --2.554462844E-005, --2.618136386E-005, --2.537086584E-005, --2.362549276E-005, --2.093936746E-005, --1.751866148E-005, --1.356193479E-005, --9.299508747E-006, --4.916387297E-006, --5.595519906E-005, --5.429694284E-005, --5.176846025E-005, --4.839275425E-005, --4.425736552E-005, --3.946387005E-005, --3.415624451E-005, --2.847247197E-005, --2.263354872E-005, --1.309637537E-005, --9.561075785E-006, --6.084746474E-006, --3.086857760E-006, --7.198007665E-007, -+1.853591357E-006, -+1.470520488E-006, -+9.984935332E-007, -+5.633860383E-007, -+6.993315310E-006, -+1.207003334E-005, -+1.661818715E-005, -+1.776598037E-005, -+1.806914770E-005, -+2.677291741E-005, -+2.978993689E-005, -+3.225446198E-005, -+3.397853652E-005, -+3.495384954E-005, -+3.515914432E-005, -+3.460439257E-005, -+3.334947178E-005, -+3.144468428E-005, --2.042970118E-005, --1.987093310E-005, --1.884208177E-005, --1.743183020E-005, --1.571428584E-005, --1.379448349E-005, --1.177108606E-005, --9.826449968E-006, --7.869333785E-006, --2.319611212E-006, --3.157242645E-006, --3.617151151E-006, --2.497214155E-006, --1.189317118E-006, --6.437721822E-008, --8.434094667E-008, -+3.809887872E-008, -+3.246264413E-008, --6.402664354E-008, --2.975164826E-008, --9.458596395E-008, --4.341498823E-007, --8.427224429E-007, --3.332600045E-006, --4.429412002E-006, --5.315936960E-006, --6.225028756E-006, --6.986399967E-006, --7.568834008E-006, --7.941360309E-006, --8.087732567E-006, --8.006985809E-006, --6.361419310E-006, --6.015239251E-006, --5.516381407E-006, --4.896494374E-006, --4.195037945E-006, --3.453840463E-006, --2.715013807E-006, --2.032118118E-006, --1.399798180E-006, --3.132386439E-007, --1.444918922E-007, --2.788728892E-008, --7.506701927E-009, --1.314406006E-008, -+3.399493131E-009, -+2.682709610E-009, -+1.613285505E-009, -+6.702406963E-010, --7.834767501E-008, --2.014677420E-007, --5.234479659E-007, --1.190443072E-006, --1.975324267E-006, --9.451737242E-007, --1.033426656E-006, --1.179182050E-006, --1.194632091E-006, --1.162929266E-006, --1.085227950E-006, --9.742954035E-007, --8.419976893E-007, --7.003467317E-007, -+5.564140224E-007, -+6.262345096E-007, -+6.767839409E-007, -+7.020648809E-007, -+6.982898526E-007, -+6.628192182E-007, -+6.022448247E-007, -+4.741137047E-007, -+3.970030775E-007, -+7.342250683E-007, -+3.961981463E-007, -+1.543309907E-007, -+5.083275667E-008, -+1.608403011E-008, --7.018770981E-011, --1.135985195E-010 -}; - -DECLARE_ALIGNED(16, static const float, fir_32bands_nonperfect)[] = -{ --1.390191784E-007, --1.693738625E-007, --2.030677564E-007, --2.404238444E-007, --2.818143514E-007, --3.276689142E-007, --3.784752209E-007, --4.347855338E-007, --4.972276315E-007, --5.665120852E-007, --6.434325428E-007, --7.288739425E-007, --8.238164355E-007, --9.293416952E-007, --1.046637067E-006, --1.176999604E-006, --1.321840614E-006, --1.482681114E-006, --1.661159786E-006, --1.859034001E-006, --2.078171747E-006, --2.320550948E-006, --2.588257530E-006, --2.883470643E-006, --3.208459020E-006, --3.565570978E-006, --3.957220997E-006, --4.385879038E-006, --4.854050530E-006, --5.364252502E-006, --5.918994248E-006, --6.520755960E-006, --7.171964626E-006, --7.874960829E-006, --8.631964192E-006, --9.445050637E-006, --1.031611009E-005, --1.124680875E-005, --1.223855270E-005, --1.329243969E-005, --1.440921824E-005, --1.558924305E-005, --1.683242772E-005, --1.813820381E-005, --1.950545993E-005, --2.093250441E-005, --2.241701623E-005, --2.395598858E-005, --2.554569073E-005, --2.718161704E-005, --2.885844333E-005, --3.056998685E-005, --3.230916263E-005, --3.406793985E-005, --3.583733633E-005, --3.760734762E-005, --3.936696885E-005, --4.110412556E-005, --4.280570283E-005, --4.445751256E-005, --4.604430433E-005, --4.754976908E-005, --4.895655002E-005, --5.024627535E-005, -+5.139957648E-005, -+5.239612074E-005, -+5.321469871E-005, -+5.383323878E-005, -+5.422891263E-005, -+5.437819709E-005, -+5.425697600E-005, -+5.384063843E-005, -+5.310418419E-005, -+5.202236207E-005, -+5.056979353E-005, -+4.872112549E-005, -+4.645117951E-005, -+4.373511547E-005, -+4.054862075E-005, -+3.686808850E-005, -+3.267079956E-005, -+2.793515523E-005, -+2.264085742E-005, -+1.676913780E-005, -+1.030297699E-005, -+3.227306706E-006, --4.470633485E-006, --1.280130618E-005, --2.177240640E-005, --3.138873581E-005, --4.165195787E-005, --5.256036457E-005, --6.410864444E-005, --7.628766616E-005, --8.908427117E-005, --1.024810626E-004, --1.164562127E-004, --1.309833024E-004, --1.460311323E-004, --1.615635992E-004, --1.775395358E-004, --1.939126523E-004, --2.106313768E-004, --2.276388550E-004, --2.448728774E-004, --2.622658503E-004, --2.797449124E-004, --2.972317743E-004, --3.146430245E-004, --3.318900708E-004, --3.488793736E-004, --3.655125911E-004, --3.816867538E-004, --3.972945851E-004, --4.122247046E-004, --4.263620067E-004, --4.395879805E-004, --4.517810594E-004, --4.628172028E-004, --4.725702747E-004, --4.809123348E-004, --4.877146275E-004, --4.928477574E-004, --4.961824161E-004, --4.975944757E-004, --4.969481961E-004, --4.941228544E-004, --4.889960401E-004, -+4.814492422E-004, -+4.713678791E-004, -+4.586426076E-004, -+4.431701091E-004, -+4.248536134E-004, -+4.036037717E-004, -+3.793396754E-004, -+3.519894381E-004, -+3.214911267E-004, -+2.877934603E-004, -+2.508567995E-004, -+2.106537577E-004, -+1.671699720E-004, -+1.204049113E-004, -+7.037253090E-005, -+1.710198012E-005, --3.936182839E-005, --9.895755647E-005, --1.616069785E-004, --2.272142592E-004, --2.956659591E-004, --3.668301215E-004, --4.405563814E-004, --5.166754709E-004, --5.949990009E-004, --6.753197522E-004, --7.574109477E-004, --8.410271257E-004, --9.259034996E-004, --1.011756598E-003, --1.098284614E-003, --1.185167348E-003, --1.272067428E-003, --1.358630019E-003, --1.444484224E-003, --1.529243193E-003, --1.612505526E-003, --1.693855622E-003, --1.772865304E-003, --1.849094522E-003, --1.922092517E-003, --1.991399564E-003, --2.056547208E-003, --2.117061289E-003, --2.172462177E-003, --2.222266514E-003, --2.265989315E-003, --2.303145360E-003, --2.333251061E-003, --2.355825622E-003, --2.370394068E-003, --2.376487479E-003, --2.373647178E-003, --2.361423569E-003, --2.339380793E-003, --2.307097195E-003, --2.264167881E-003, --2.210205887E-003, --2.144844970E-003, --2.067740774E-003, --1.978572691E-003, --1.877046190E-003, --1.762894331E-003, --1.635878929E-003, -+1.495792647E-003, -+1.342460280E-003, -+1.175740734E-003, -+9.955273708E-004, -+8.017504588E-004, -+5.943773431E-004, -+3.734139318E-004, -+1.389056415E-004, --1.090620208E-004, --3.703625989E-004, --6.448282511E-004, --9.322494152E-004, --1.232374110E-003, --1.544908970E-003, --1.869517611E-003, --2.205822384E-003, --2.553403843E-003, --2.911801683E-003, --3.280514618E-003, --3.659002949E-003, --4.046686925E-003, --4.442950245E-003, --4.847140983E-003, --5.258570891E-003, --5.676518660E-003, --6.100233644E-003, --6.528933067E-003, --6.961807609E-003, --7.398022339E-003, --7.836719044E-003, --8.277016692E-003, --8.718019351E-003, --9.158811532E-003, --9.598465636E-003, --1.003604382E-002, --1.047059800E-002, --1.090117730E-002, --1.132682897E-002, --1.174659748E-002, --1.215953380E-002, --1.256469358E-002, --1.296114177E-002, --1.334795821E-002, --1.372423489E-002, --1.408908330E-002, --1.444163360E-002, --1.478104480E-002, --1.510649733E-002, --1.541720331E-002, --1.571240649E-002, --1.599138230E-002, --1.625344716E-002, --1.649795473E-002, --1.672429405E-002, --1.693190821E-002, --1.712027565E-002, --1.728892699E-002, --1.743743755E-002, --1.756543480E-002, --1.767260395E-002, --1.775865816E-002, --1.782339066E-002, --1.786663756E-002, --1.788828894E-002, -+1.788828894E-002, -+1.786663756E-002, -+1.782339066E-002, -+1.775865816E-002, -+1.767260395E-002, -+1.756543480E-002, -+1.743743755E-002, -+1.728892699E-002, -+1.712027565E-002, -+1.693190821E-002, -+1.672429405E-002, -+1.649795473E-002, -+1.625344716E-002, -+1.599138230E-002, -+1.571240649E-002, -+1.541720331E-002, -+1.510649733E-002, -+1.478104480E-002, -+1.444163360E-002, -+1.408908330E-002, -+1.372423489E-002, -+1.334795821E-002, -+1.296114177E-002, -+1.256469358E-002, -+1.215953380E-002, -+1.174659748E-002, -+1.132682897E-002, -+1.090117730E-002, -+1.047059800E-002, -+1.003604382E-002, -+9.598465636E-003, -+9.158811532E-003, -+8.718019351E-003, -+8.277016692E-003, -+7.836719044E-003, -+7.398022339E-003, -+6.961807609E-003, -+6.528933067E-003, -+6.100233644E-003, -+5.676518660E-003, -+5.258570891E-003, -+4.847140983E-003, -+4.442950245E-003, -+4.046686925E-003, -+3.659002949E-003, -+3.280514618E-003, -+2.911801683E-003, -+2.553403843E-003, -+2.205822384E-003, -+1.869517611E-003, -+1.544908970E-003, -+1.232374110E-003, -+9.322494152E-004, -+6.448282511E-004, -+3.703625989E-004, -+1.090620208E-004, --1.389056415E-004, --3.734139318E-004, --5.943773431E-004, --8.017504588E-004, --9.955273708E-004, --1.175740734E-003, --1.342460280E-003, --1.495792647E-003, -+1.635878929E-003, -+1.762894331E-003, -+1.877046190E-003, -+1.978572691E-003, -+2.067740774E-003, -+2.144844970E-003, -+2.210205887E-003, -+2.264167881E-003, -+2.307097195E-003, -+2.339380793E-003, -+2.361423569E-003, -+2.373647178E-003, -+2.376487479E-003, -+2.370394068E-003, -+2.355825622E-003, -+2.333251061E-003, -+2.303145360E-003, -+2.265989315E-003, -+2.222266514E-003, -+2.172462177E-003, -+2.117061289E-003, -+2.056547208E-003, -+1.991399564E-003, -+1.922092517E-003, -+1.849094522E-003, -+1.772865304E-003, -+1.693855622E-003, -+1.612505526E-003, -+1.529243193E-003, -+1.444484224E-003, -+1.358630019E-003, -+1.272067428E-003, -+1.185167348E-003, -+1.098284614E-003, -+1.011756598E-003, -+9.259034996E-004, -+8.410271257E-004, -+7.574109477E-004, -+6.753197522E-004, -+5.949990009E-004, -+5.166754709E-004, -+4.405563814E-004, -+3.668301215E-004, -+2.956659591E-004, -+2.272142592E-004, -+1.616069785E-004, -+9.895755647E-005, -+3.936182839E-005, --1.710198012E-005, --7.037253090E-005, --1.204049113E-004, --1.671699720E-004, --2.106537577E-004, --2.508567995E-004, --2.877934603E-004, --3.214911267E-004, --3.519894381E-004, --3.793396754E-004, --4.036037717E-004, --4.248536134E-004, --4.431701091E-004, --4.586426076E-004, --4.713678791E-004, --4.814492422E-004, -+4.889960401E-004, -+4.941228544E-004, -+4.969481961E-004, -+4.975944757E-004, -+4.961824161E-004, -+4.928477574E-004, -+4.877146275E-004, -+4.809123348E-004, -+4.725702747E-004, -+4.628172028E-004, -+4.517810594E-004, -+4.395879805E-004, -+4.263620067E-004, -+4.122247046E-004, -+3.972945851E-004, -+3.816867538E-004, -+3.655125911E-004, -+3.488793736E-004, -+3.318900708E-004, -+3.146430245E-004, -+2.972317743E-004, -+2.797449124E-004, -+2.622658503E-004, -+2.448728774E-004, -+2.276388550E-004, -+2.106313768E-004, -+1.939126523E-004, -+1.775395358E-004, -+1.615635992E-004, -+1.460311323E-004, -+1.309833024E-004, -+1.164562127E-004, -+1.024810626E-004, -+8.908427117E-005, -+7.628766616E-005, -+6.410864444E-005, -+5.256036457E-005, -+4.165195787E-005, -+3.138873581E-005, -+2.177240640E-005, -+1.280130618E-005, -+4.470633485E-006, --3.227306706E-006, --1.030297699E-005, --1.676913780E-005, --2.264085742E-005, --2.793515523E-005, --3.267079956E-005, --3.686808850E-005, --4.054862075E-005, --4.373511547E-005, --4.645117951E-005, --4.872112549E-005, --5.056979353E-005, --5.202236207E-005, --5.310418419E-005, --5.384063843E-005, --5.425697600E-005, --5.437819709E-005, --5.422891263E-005, --5.383323878E-005, --5.321469871E-005, --5.239612074E-005, --5.139957648E-005, -+5.024627535E-005, -+4.895655002E-005, -+4.754976908E-005, -+4.604430433E-005, -+4.445751256E-005, -+4.280570283E-005, -+4.110412556E-005, -+3.936696885E-005, -+3.760734762E-005, -+3.583733633E-005, -+3.406793985E-005, -+3.230916263E-005, -+3.056998685E-005, -+2.885844333E-005, -+2.718161704E-005, -+2.554569073E-005, -+2.395598858E-005, -+2.241701623E-005, -+2.093250441E-005, -+1.950545993E-005, -+1.813820381E-005, -+1.683242772E-005, -+1.558924305E-005, -+1.440921824E-005, -+1.329243969E-005, -+1.223855270E-005, -+1.124680875E-005, -+1.031611009E-005, -+9.445050637E-006, -+8.631964192E-006, -+7.874960829E-006, -+7.171964626E-006, -+6.520755960E-006, -+5.918994248E-006, -+5.364252502E-006, -+4.854050530E-006, -+4.385879038E-006, -+3.957220997E-006, -+3.565570978E-006, -+3.208459020E-006, -+2.883470643E-006, -+2.588257530E-006, -+2.320550948E-006, -+2.078171747E-006, -+1.859034001E-006, -+1.661159786E-006, -+1.482681114E-006, -+1.321840614E-006, -+1.176999604E-006, -+1.046637067E-006, -+9.293416952E-007, -+8.238164355E-007, -+7.288739425E-007, -+6.434325428E-007, -+5.665120852E-007, -+4.972276315E-007, -+4.347855338E-007, -+3.784752209E-007, -+3.276689142E-007, -+2.818143514E-007, -+2.404238444E-007, -+2.030677564E-007, -+1.693738625E-007, -+1.390191784E-007 -}; - -DECLARE_ALIGNED(16, static const float, lfe_fir_64)[] = -{ - 2.658434386830777e-4, 9.029330685734748e-3, - 7.939263433218002e-2, 2.425158768892288e-1, - 3.430179357528686e-1, 2.398228943347931e-1, - 7.746443897485733e-2, 8.622321300208569e-3, - 8.179365249816328e-5, 9.450953453779220e-3, - 8.134882897138596e-2, 2.451938837766648e-1, - 3.429597318172455e-1, 2.371159791946411e-1, - 7.556436210870743e-2, 8.229630999267101e-3, - 9.439323912374676e-5, 9.887560270726680e-3, - 8.333285897970200e-2, 2.478559017181396e-1, - 3.428434133529663e-1, 2.343961596488952e-1, - 7.369252294301987e-2, 7.850865833461285e-3, - 1.082170274457894e-4, 1.033949479460716e-2, - 8.534456789493561e-2, 2.505008876323700e-1, - 3.426689505577088e-1, 2.316644787788391e-1, - 7.184901088476181e-2, 7.485736627131701e-3, - 1.233371440321207e-4, 1.080708485096693e-2, - 8.738376945257187e-2, 2.531278133392334e-1, - 3.424364924430847e-1, 2.289219647645950e-1, - 7.003392279148102e-2, 7.133882027119398e-3, - 1.397485757479444e-4, 1.129068247973919e-2, - 8.945026248693466e-2, 2.557355761528015e-1, - 3.421461284160614e-1, 2.261696159839630e-1, - 6.824731826782227e-2, 6.794991903007030e-3, - 1.575958012836054e-4, 1.179065089672804e-2, - 9.154383838176728e-2, 2.583232223987580e-1, - 3.417979776859284e-1, 2.234084606170654e-1, - 6.648923456668854e-2, 6.468691397458315e-3, - 1.769922382663936e-4, 1.230732165277004e-2, - 9.366425126791000e-2, 2.608896791934967e-1, - 3.413922190666198e-1, 2.206395119428635e-1, - 6.475970894098282e-2, 6.154712289571762e-3, - 1.981738605536520e-4, 1.284105982631445e-2, - 9.581124037504196e-2, 2.634339034557342e-1, - 3.409290313720703e-1, 2.178637981414795e-1, - 6.305878609418869e-2, 5.852684378623962e-3, - 2.211847313446924e-4, 1.339218579232693e-2, - 9.798453748226166e-2, 2.659549415111542e-1, - 3.404086530208588e-1, 2.150822728872299e-1, - 6.138643622398376e-2, 5.562345497310162e-3, - 2.460231189616024e-4, 1.396108977496624e-2, - 1.001838669180870e-1, 2.684516608715058e-1, - 3.398312926292420e-1, 2.122959494590759e-1, - 5.974265560507774e-2, 5.283284001052380e-3, - 2.726115926634520e-4, 1.454808749258518e-2, - 1.024089083075523e-1, 2.709231376647949e-1, - 3.391972482204438e-1, 2.095058411359787e-1, - 5.812742188572884e-2, 5.015311297029257e-3, - 3.013863170053810e-4, 1.515355054289102e-2, - 1.046593263745308e-1, 2.733682692050934e-1, - 3.385068178176880e-1, 2.067128717899322e-1, - 5.654069408774376e-2, 4.758012015372515e-3, - 3.328395541757345e-4, 1.577781140804291e-2, - 1.069347932934761e-1, 2.757860720157624e-1, - 3.377602994441986e-1, 2.039180546998978e-1, - 5.498242005705833e-2, 4.511159844696522e-3, - 3.658991190604866e-4, 1.642123050987720e-2, - 1.092349365353584e-1, 2.781755328178406e-1, - 3.369580209255218e-1, 2.011223286390304e-1, - 5.345252528786659e-2, 4.274417180567980e-3, - 4.018281470052898e-4, 1.708412915468216e-2, - 1.115593686699867e-1, 2.805356979370117e-1, - 3.361004292964936e-1, 1.983266174793244e-1, - 5.195093154907227e-2, 4.047499038279056e-3, - 4.401875485200435e-4, 1.776690222322941e-2, - 1.139076948165894e-1, 2.828655838966370e-1, - 3.351879119873047e-1, 1.955319195985794e-1, - 5.047753453254700e-2, 3.830091329291463e-3, - 4.812776169274002e-4, 1.846982724964619e-2, - 1.162794977426529e-1, 2.851640880107880e-1, - 3.342207968235016e-1, 1.927391141653061e-1, - 4.903224110603333e-2, 3.621967276558280e-3, - 5.252459668554366e-4, 1.919330470263958e-2, - 1.186743453145027e-1, 2.874303460121155e-1, - 3.331996202468872e-1, 1.899491697549820e-1, - 4.761491715908051e-2, 3.422776935622096e-3, - 5.721592460758984e-4, 1.993762329220772e-2, - 1.210917681455612e-1, 2.896633744239807e-1, - 3.321248590946198e-1, 1.871629506349564e-1, - 4.622544348239899e-2, 3.232272574678064e-3, - 6.222130032256246e-4, 2.070316113531590e-2, - 1.235313042998314e-1, 2.918621897697448e-1, - 3.309969604015350e-1, 1.843813359737396e-1, - 4.486365616321564e-2, 3.050152910873294e-3, - 6.755515350960195e-4, 2.149021252989769e-2, - 1.259924471378326e-1, 2.940258979797364e-1, - 3.298164308071136e-1, 1.816052496433258e-1, - 4.352942481637001e-2, 2.876190468668938e-3, - 7.324148900806904e-4, 2.229913882911205e-2, - 1.284746825695038e-1, 2.961534857749939e-1, - 3.285838961601258e-1, 1.788355410099030e-1, - 4.222255200147629e-2, 2.710093278437853e-3, - 7.928516715764999e-4, 2.313023805618286e-2, - 1.309774816036224e-1, 2.982441186904907e-1, - 3.272998929023742e-1, 1.760730892419815e-1, - 4.094288870692253e-2, 2.551567042246461e-3, - 8.570110658183694e-4, 2.398385666310787e-2, - 1.335003077983856e-1, 3.002967536449432e-1, - 3.259649574756622e-1, 1.733186990022659e-1, - 3.969023004174232e-2, 2.400433411821723e-3, - 9.251192095689476e-4, 2.486028522253036e-2, - 1.360425949096680e-1, 3.023106753826142e-1, - 3.245797157287598e-1, 1.705732345581055e-1, - 3.846437484025955e-2, 2.256359672173858e-3, - 9.974770946428180e-4, 2.575986087322235e-2, - 1.386037617921829e-1, 3.042849004268646e-1, - 3.231448531150818e-1, 1.678375005722046e-1, - 3.726511076092720e-2, 2.119151875376701e-3, - 1.073930296115577e-3, 2.668286114931106e-2, - 1.411831974983215e-1, 3.062185347080230e-1, - 3.216609656810760e-1, 1.651122719049454e-1, - 3.609224036335945e-2, 1.988604199141264e-3, - 1.155023579485714e-3, 2.762960828840732e-2, - 1.437802612781525e-1, 3.081108033657074e-1, - 3.201287388801574e-1, 1.623983532190323e-1, - 3.494550660252571e-2, 1.864377525635064e-3, - 1.240676851011813e-3, 2.860039286315441e-2, - 1.463943719863892e-1, 3.099608123302460e-1, - 3.185488879680634e-1, 1.596965193748474e-1, - 3.382468968629837e-2, 1.746327499859035e-3, - 1.331258914433420e-3, 2.959549613296986e-2, - 1.490248143672943e-1, 3.117676973342896e-1, - 3.169221282005310e-1, 1.570075154304504e-1, - 3.272953629493714e-2, 1.634211512282491e-3, - 1.426893868483603e-3, 3.061520494520664e-2, - 1.516709625720978e-1, 3.135308027267456e-1, - 3.152491748332978e-1, 1.543320864439010e-1, - 3.165979683399200e-2, 1.527829794213176e-3, -}; - -DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] = -{ - 0.00053168571, 0.15878495574, 0.68603444099, 0.15492856503, - 0.00016358691, 0.16269733012, 0.68591803312, 0.15112841129, - 0.00018878609, 0.16666537523, 0.68568539619, 0.14738474786, - 0.00021643363, 0.17068879306, 0.68533653021, 0.14369773865, - 0.00024667382, 0.17476719618, 0.68487155437, 0.14006754756, - 0.00027949660, 0.17890018225, 0.68429082632, 0.13649433851, - 0.00031519096, 0.18308731914, 0.68359452486, 0.13297818601, - 0.00035398375, 0.18732811511, 0.68278300762, 0.12951917946, - 0.00039634691, 0.19162209332, 0.68185669184, 0.12611730397, - 0.00044236859, 0.19596865773, 0.68081587553, 0.12277261168, - 0.00049204525, 0.20036731660, 0.67966115475, 0.11948505789, - 0.00054522208, 0.20481738448, 0.67839306593, 0.11625462025, - 0.00060277141, 0.20931822062, 0.67701220512, 0.11308115721, - 0.00066567765, 0.21386915445, 0.67551922798, 0.10996460915, - 0.00073179678, 0.21846942604, 0.67391467094, 0.10690483451, - 0.00080365466, 0.22311829031, 0.67219948769, 0.10390164703, - 0.00088037323, 0.22781492770, 0.67037439346, 0.10095486045, - 0.00096255314, 0.23255851865, 0.66844022274, 0.09806428105, - 0.00105048984, 0.23734821379, 0.66639786959, 0.09522963315, - 0.00114431616, 0.24218304455, 0.66424828768, 0.09245070815, - 0.00124442333, 0.24706205726, 0.66199249029, 0.08972713351, - 0.00135110028, 0.25198432803, 0.65963155031, 0.08705867827, - 0.00146482687, 0.25694879889, 0.65716648102, 0.08444493264, - 0.00158570008, 0.26195442677, 0.65459835529, 0.08188561350, - 0.00171401864, 0.26700007915, 0.65192854404, 0.07938029617, - 0.00185023469, 0.27208462358, 0.64915806055, 0.07692859322, - 0.00199495023, 0.27720692754, 0.64628833532, 0.07453006506, - 0.00214785640, 0.28236576915, 0.64332056046, 0.07218432426, - 0.00231004250, 0.28755992651, 0.64025616646, 0.06989086419, - 0.00248134881, 0.29278811812, 0.63709646463, 0.06764923781, - 0.00266251224, 0.29804900289, 0.63384294510, 0.06545893103, - 0.00285378192, 0.30334126949, 0.63049703836, 0.06331945211, - 0.00305565330, 0.30866351724, 0.62706029415, 0.06123027951, - 0.00326841651, 0.31401440501, 0.62353414297, 0.05919086933, - 0.00349264755, 0.31939238310, 0.61992025375, 0.05720067024, - 0.00372874714, 0.32479602098, 0.61622029543, 0.05525910854, - 0.00397720048, 0.33022382855, 0.61243581772, 0.05336561054, - 0.00423829490, 0.33567428589, 0.60856848955, 0.05151961371, - 0.00451271003, 0.34114575386, 0.60462015867, 0.04972046614, - 0.00480085658, 0.34663668275, 0.60059231520, 0.04796761274, - 0.00510312291, 0.35214546323, 0.59648692608, 0.04626038298, - 0.00542017492, 0.35767036676, 0.59230577946, 0.04459818453, - 0.00575236930, 0.36320972443, 0.58805054426, 0.04298033938, - 0.00610029325, 0.36876192689, 0.58372318745, 0.04140623659, - 0.00646453211, 0.37432509661, 0.57932555676, 0.03987516090, - 0.00684553990, 0.37989753485, 0.57485944033, 0.03838652745, - 0.00724391919, 0.38547745347, 0.57032698393, 0.03693958372, - 0.00766016589, 0.39106300473, 0.56572991610, 0.03553372994, - 0.00809498038, 0.39665243030, 0.56107026339, 0.03416819125, - 0.00854881573, 0.40224379301, 0.55634999275, 0.03284239396, - 0.00902230106, 0.40783521533, 0.55157101154, 0.03155555204, - 0.00951600447, 0.41342487931, 0.54673534632, 0.03030703776, - 0.01003060210, 0.41901078820, 0.54184508324, 0.02909611352, - 0.01056654565, 0.42459106445, 0.53690224886, 0.02792212367, - 0.01112466771, 0.43016362190, 0.53190881014, 0.02678431384, - 0.01170534454, 0.43572667241, 0.52686679363, 0.02568206564, - 0.01230939943, 0.44127810001, 0.52177828550, 0.02461459488, - 0.01293735672, 0.44681602716, 0.51664537191, 0.02358125709, - 0.01358995494, 0.45233830810, 0.51147013903, 0.02258131653, - 0.01426773332, 0.45784294605, 0.50625455379, 0.02161412500, - 0.01497144438, 0.46332800388, 0.50100076199, 0.02067894675, - 0.01570170000, 0.46879136562, 0.49571081996, 0.01977507770, - 0.01645922661, 0.47423094511, 0.49038675427, 0.01890186779, - 0.01724460535, 0.47964480519, 0.48503074050, 0.01805862412, -}; - -/* 10^-(dB/20), with dB being a list of dB values ranging from 0 to -72 */ -/* do a 20*log10(dca_downmix_coeffs) to reconvert the values */ - -static const float dca_downmix_coeffs[65] = { - 1.000000000000000, 0.988553094656939, 0.971627951577106, 0.944060876285923, 0.917275935389780, 0.891250938133746, - 0.865964323360065, 0.841395141645195, 0.817523037943650, 0.794328234724281, 0.771791515585012, 0.749894209332456, - 0.728618174513228, 0.707945784384138, 0.687859912308808, 0.668343917568615, 0.649381631576211, 0.630957344480193, - 0.613055792149821, 0.595662143529010, 0.578761988349121, 0.562341325190349, 0.546386549881854, 0.530884444230988, - 0.515822165072306, 0.501187233627272, 0.446683592150963, 0.398107170553497, 0.354813389233575, 0.316227766016838, - 0.281838293126445, 0.251188643150958, 0.223872113856834, 0.199526231496888, 0.177827941003892, 0.158489319246111, - 0.141253754462275, 0.125892541179417, 0.112201845430196, 0.100000000000000, 0.089125093813374, 0.079432823472428, - 0.070794578438414, 0.063095734448019, 0.053088444423099, 0.044668359215096, 0.037583740428844, 0.031622776601684, - 0.026607250597988, 0.022387211385683, 0.018836490894898, 0.015848931924611, 0.013335214321633, 0.011220184543020, - 0.009440608762859, 0.007943282347243, 0.005623413251903, 0.003981071705535, 0.002818382931264, 0.001995262314969, - 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, -}; - -static const uint8_t dca_default_coeffs[16][5][2] = { - { { 13, 13 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, }, - { { 0, 25 }, { 25, 0 }, { 13, 13 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 13, 13 }, }, - { { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, -}; - -/* downmix coeffs - - TABLE 9 -______________________________________ -Down-mix coefficients for 8-channel source -audio (5 + 3 format) - lt - cen- rt lt ctr rt -lt ter ctr center - rt srd srd srd -______________________________________ -1 0.71 0.74 1.0 0.71 0.71 0.58 0.58 0.58 -2 left 1.0 0.89 0.71 0.46 0.71 0.50 - rt 0.45 0.71 0.89 1.0 0.50 0.71 -3 lt 1.0 0.89 0.71 0.45 - rt 0.45 0.71 0.89 1.0 - srd 0.71 0.71 0.71 -4 lt 1.0 0.89 0.71 0.45 - rt 0.45 0.71 0.89 1.0 - lt srd 1.0 0.71 - rt srd 0.71 0.71 -4 lt 1.0 0.5 - ctr 0.87 1.0 0.87 - rt 0.5 1.0 - srd 0.71 0.71 0.71 -5 lt 1.0 0.5 - ctr 0.87 1.0 0.87 - rt 0.5 1.0 - lt srd 1.0 0.71 - rt srd 0.71 1.0 -6 lt 1.0 0.5 - lt ctr 0.87 0.71 - rt ctr 0.71 0.87 - rt 0.5 1.0 - lt srd 1.0 0.71 - rt srd 0.71 1.0 -6 lt 1.0 0.5 - ctr 0.86 1.0 0.86 - rt 0.5 1.0 - lt srd 1.0 - ctr srd 1.0 - rt srd 1.0 -7 lt 1.0 - lt ctr 1.0 - ctr 1.0 - rt ctr 1.0 - rt 1.0 - lt srd 1.0 0.71 - rt srd 0.71 1.0 -7 lt 1.0 0.5 - lt ctr 0.87 0.71 - rt ctr 0.71 0.87 - rt 0.5 1.0 - lt srd 1.0 - ctr srd 1.0 - rt srd 1.0 -8 lt 1.0 0.5 - lt ctr 0.87 0.71 - rt ctr 0.71 0.87 - rt 0.5 1.0 - lt 1 srd 0.87 0.35 - lt 2 srd 0.5 0.61 - rt 2 srd 0.61 0.50 - rt 2 srd 0.35 0.87 - - Generation of Lt Rt - -In the case when the playback system has analog or digital surround multi-channel capability, a down matrix from 5, 4, or 3 channel to Lt Rt may be desirable. In the case when the number of decoded audio channels exceeds 5, 4 or 3 respectively a first stage down mix to 5, 4 or 3 chs should be used as described above. - -The down matrixing equations for 5-channel source audio to a two-channel Lt Rt playback system are given by: - -Left left+0.7*center-0.7*(lt surround+rt surround) - -Right=right+0.7*center+0.7*(lt surround+rt surround) - -Embedded mixing to 2-channel - -One concern arising from the proliferation of multi-channel audio systems is that most home systems presently have only two channel playback capability. To accommodate this a fixed 2-channel down matrix processes is commonly used following the multi-channel decoding stage. However, for music only applications the image quality etc. of the down matrixed signal may not match that of an equivalent stereo recording found on CD. - -The concept of embedded mixing is to allow the producer to dynamically specify the matrixing coefficients within the audio frame itself. In this way the stereo down mix at the decoder may be better matched to a 2-channel playback environment. - -CHS*2, 7-bit down mix indexes (MCOEFFS) are transmitted along with the multi-channel audio once in every frame. The indexes are converted to attenuation factors using a 7 bit LUT. The 2-ch down mix equations are as follows, - -Left Ch=sum (MCOEFF[n]*Ch[n]) for n=1, CHS - -Right Ch sum (MCOEFF[n+CHS]*Ch[n]) for n=1, CHS - -where Ch(n) represents the subband samples in the (n)th audio channel. - - -*/ - -#endif /* AVCODEC_DCADATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dcadsp.c b/tizen/distrib/ffmpeg/libavcodec/dcadsp.c deleted file mode 100644 index af48e3c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dcadsp.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004 Gildas Bazin - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "dcadsp.h" - -static void dca_lfe_fir_c(float *out, const float *in, const float *coefs, - int decifactor, float scale, float bias) -{ - float *out2 = out + decifactor; - const float *cf0 = coefs; - const float *cf1 = coefs + 256; - int j, k; - - /* One decimated sample generates 2*decifactor interpolated ones */ - for (k = 0; k < decifactor; k++) { - float v0 = 0.0; - float v1 = 0.0; - for (j = 0; j < 256 / decifactor; j++) { - float s = in[-j]; - v0 += s * *cf0++; - v1 += s * *--cf1; - } - *out++ = (v0 * scale) + bias; - *out2++ = (v1 * scale) + bias; - } -} - -void ff_dcadsp_init(DCADSPContext *s) -{ - s->lfe_fir = dca_lfe_fir_c; - if (ARCH_ARM) ff_dcadsp_init_arm(s); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/dcadsp.h b/tizen/distrib/ffmpeg/libavcodec/dcadsp.h deleted file mode 100644 index 20020ae..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dcadsp.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DCADSP_H -#define AVCODEC_DCADSP_H - -typedef struct DCADSPContext { - void (*lfe_fir)(float *out, const float *in, const float *coefs, - int decifactor, float scale, float bias); -} DCADSPContext; - -void ff_dcadsp_init(DCADSPContext *s); -void ff_dcadsp_init_arm(DCADSPContext *s); - -#endif /* AVCODEC_DCADSP_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dcahuff.h b/tizen/distrib/ffmpeg/libavcodec/dcahuff.h deleted file mode 100644 index cbc8429..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dcahuff.h +++ /dev/null @@ -1,1076 +0,0 @@ -/* - * DCA compatible decoder - huffman tables - * Copyright (C) 2004 Gildas Bazin - * Copyright (C) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DCAHUFF_H -#define AVCODEC_DCAHUFF_H - -#include -#include - -#define TMODE_COUNT 4 -static const uint8_t tmode_vlc_bits[TMODE_COUNT] = { 3, 3, 3, 2 }; -static const uint16_t tmode_codes[TMODE_COUNT][4] = { - { 0x0000, 0x0002, 0x0006, 0x0007 }, - { 0x0002, 0x0006, 0x0007, 0x0000 }, - { 0x0006, 0x0007, 0x0000, 0x0002 }, - { 0x0000, 0x0001, 0x0002, 0x0003 } -}; -static const uint8_t tmode_bits[TMODE_COUNT][4] = { - { 1, 2, 3, 3 }, - { 2, 3, 3, 1 }, - { 3, 3, 1, 2 }, - { 2, 2, 2, 2 } -}; - - -#define BITALLOC_12_COUNT 5 -#define BITALLOC_12_VLC_BITS 9 -static const uint8_t bitalloc_12_vlc_bits[BITALLOC_12_COUNT] = { - 9, 7, 7, 9, 9 -}; -static const uint16_t bitalloc_12_codes[BITALLOC_12_COUNT][12] = { - { - 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, 0x00FF, 0x00FE, - 0x01FB, 0x01FA, 0x01F9, 0x01F8, - }, - { - 0x0001, 0x0000, 0x0002, 0x000F, 0x000C, 0x001D, 0x0039, 0x0038, - 0x0037, 0x0036, 0x0035, 0x0034, - }, - { - 0x0000, 0x0007, 0x0005, 0x0004, 0x0002, 0x000D, 0x000C, 0x0006, - 0x000F, 0x001D, 0x0039, 0x0038, - }, - { - 0x0003, 0x0002, 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, - 0x007E, 0x00FE, 0x01FF, 0x01FE, - }, - { - 0x0001, 0x0000, 0x0002, 0x0006, 0x000E, 0x003F, 0x003D, 0x007C, - 0x0079, 0x0078, 0x00FB, 0x00FA, - } -}; -static const uint8_t bitalloc_12_bits[BITALLOC_12_COUNT][12] = { - { 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 9, 9 }, - { 1, 2, 3, 5, 5, 6, 7, 7, 7, 7, 7, 7 }, - { 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 7, 7 }, - { 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10 }, - { 1, 2, 3, 4, 5, 7, 7, 8, 8, 8, 9, 9 } -}; - - -#define SCALES_COUNT 5 -#define SCALES_VLC_BITS 9 -static const uint16_t scales_codes[SCALES_COUNT][129] = { - { - 0x3AB0, 0x3AB2, 0x3AB4, 0x3AB6, 0x3AB8, 0x3ABA, 0x3ABC, 0x3ABE, - 0x3AC0, 0x3AC2, 0x3AC4, 0x3AC6, 0x3AC8, 0x3ACA, 0x3ACC, 0x3ACE, - 0x3AD0, 0x3AD2, 0x3AD4, 0x3AD6, 0x3AD8, 0x3ADA, 0x3ADC, 0x3ADE, - 0x3AE0, 0x3AE2, 0x3AE4, 0x3AE6, 0x3AE8, 0x3AEA, 0x3AEC, 0x3AEE, - 0x3AF0, 0x3AF2, 0x3AF4, 0x3AF6, 0x3AF8, 0x3AFA, 0x3AFC, 0x3AFE, - 0x0540, 0x0542, 0x0544, 0x0546, 0x0548, 0x054A, 0x054C, 0x054E, - 0x0558, 0x055E, 0x02AD, 0x0154, 0x0754, 0x03A8, 0x0056, 0x0028, - 0x00E8, 0x004A, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005, - 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x004B, - 0x00E9, 0x0029, 0x0057, 0x03A9, 0x0755, 0x0155, 0x02AE, 0x055F, - 0x0559, 0x054F, 0x054D, 0x054B, 0x0549, 0x0547, 0x0545, 0x0543, - 0x0541, 0x3AFF, 0x3AFD, 0x3AFB, 0x3AF9, 0x3AF7, 0x3AF5, 0x3AF3, - 0x3AF1, 0x3AEF, 0x3AED, 0x3AEB, 0x3AE9, 0x3AE7, 0x3AE5, 0x3AE3, - 0x3AE1, 0x3ADF, 0x3ADD, 0x3ADB, 0x3AD9, 0x3AD7, 0x3AD5, 0x3AD3, - 0x3AD1, 0x3ACF, 0x3ACD, 0x3ACB, 0x3AC9, 0x3AC7, 0x3AC5, 0x3AC3, - 0x3AC1, 0x3ABF, 0x3ABD, 0x3ABB, 0x3AB9, 0x3AB7, 0x3AB5, 0x3AB3, - 0x3AB1, - }, - { - 0x0F60, 0x0F62, 0x0F64, 0x0F66, 0x0F68, 0x0F6A, 0x0F6C, 0x0F6E, - 0x0F70, 0x0F72, 0x0F74, 0x0F76, 0x0F78, 0x0F7A, 0x0F7C, 0x0F7E, - 0x0F80, 0x0F82, 0x0F84, 0x0F86, 0x0F88, 0x0F8A, 0x0F8C, 0x0F8E, - 0x0F90, 0x0F92, 0x0F94, 0x0F96, 0x0F98, 0x0F9A, 0x0F9C, 0x0F9E, - 0x0FA0, 0x0FA2, 0x0FA4, 0x0FA6, 0x0FA8, 0x0FAA, 0x0FAC, 0x0FAE, - 0x0FB0, 0x0FB2, 0x0FB4, 0x0FB6, 0x0FB8, 0x0FBA, 0x0FBC, 0x0FBE, - 0x07A0, 0x07A2, 0x03D2, 0x01EA, 0x00FC, 0x007F, 0x001C, 0x000C, - 0x0004, 0x0034, 0x0010, 0x001B, 0x0009, 0x000B, 0x000E, 0x0001, - 0x0003, 0x0002, 0x000F, 0x000C, 0x000A, 0x0000, 0x0011, 0x0035, - 0x0005, 0x000D, 0x001D, 0x003C, 0x00FD, 0x01EB, 0x03D3, 0x07A3, - 0x07A1, 0x0FBF, 0x0FBD, 0x0FBB, 0x0FB9, 0x0FB7, 0x0FB5, 0x0FB3, - 0x0FB1, 0x0FAF, 0x0FAD, 0x0FAB, 0x0FA9, 0x0FA7, 0x0FA5, 0x0FA3, - 0x0FA1, 0x0F9F, 0x0F9D, 0x0F9B, 0x0F99, 0x0F97, 0x0F95, 0x0F93, - 0x0F91, 0x0F8F, 0x0F8D, 0x0F8B, 0x0F89, 0x0F87, 0x0F85, 0x0F83, - 0x0F81, 0x0F7F, 0x0F7D, 0x0F7B, 0x0F79, 0x0F77, 0x0F75, 0x0F73, - 0x0F71, 0x0F6F, 0x0F6D, 0x0F6B, 0x0F69, 0x0F67, 0x0F65, 0x0F63, - 0x0F61, - }, - { - 0x51D0, 0x51D2, 0x51D4, 0x51D6, 0x51D8, 0x51DA, 0x51DC, 0x51DE, - 0x51E0, 0x51E2, 0x51E4, 0x51E6, 0x51E8, 0x51EA, 0x51EC, 0x51EE, - 0x51F0, 0x51F2, 0x51F4, 0x51F6, 0x51F8, 0x51FA, 0x51FC, 0x51FE, - 0x70C0, 0x70C2, 0x70C4, 0x70C6, 0x70C8, 0x70CA, 0x70CC, 0x70CE, - 0x70EC, 0x10EA, 0x3868, 0x3877, 0x0876, 0x1C35, 0x0434, 0x0A34, - 0x0E1B, 0x021B, 0x051B, 0x070F, 0x010F, 0x0380, 0x0080, 0x0140, - 0x01C1, 0x0041, 0x00A1, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012, - 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000, - 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B, - 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A2, 0x0042, - 0x01C2, 0x0141, 0x0081, 0x0381, 0x028C, 0x010C, 0x051C, 0x021C, - 0x0E1C, 0x0A35, 0x0435, 0x1C3A, 0x0877, 0x0874, 0x3869, 0x10EB, - 0x70ED, 0x70CF, 0x70CD, 0x70CB, 0x70C9, 0x70C7, 0x70C5, 0x70C3, - 0x70C1, 0x51FF, 0x51FD, 0x51FB, 0x51F9, 0x51F7, 0x51F5, 0x51F3, - 0x51F1, 0x51EF, 0x51ED, 0x51EB, 0x51E9, 0x51E7, 0x51E5, 0x51E3, - 0x51E1, 0x51DF, 0x51DD, 0x51DB, 0x51D9, 0x51D7, 0x51D5, 0x51D3, - 0x51D1, - }, - { - 0x6F64, 0x6F66, 0x6F68, 0x6F6A, 0x6F6C, 0x6F6E, 0x6F70, 0x6F72, - 0x6F74, 0x6F76, 0x6F78, 0x6F7A, 0x6F7C, 0x6F7E, 0x6F80, 0x6F82, - 0x6F84, 0x6F86, 0x6F88, 0x6F8A, 0x6F8C, 0x6F8E, 0x6F90, 0x6F92, - 0x6F94, 0x6F96, 0x6F98, 0x6F9A, 0x6F9C, 0x6F9E, 0x6FA0, 0x6FA2, - 0x6FA4, 0x6FA6, 0x6FA8, 0x6FAA, 0x6FAC, 0x6FAE, 0x6FB0, 0x6FB2, - 0x6FB4, 0x6FB6, 0x17B4, 0x37DC, 0x0BDB, 0x1BEF, 0x05EE, 0x0DF8, - 0x02F8, 0x06FD, 0x017D, 0x037F, 0x00BF, 0x0040, 0x00C0, 0x0021, - 0x0061, 0x0011, 0x0031, 0x0009, 0x0019, 0x0006, 0x000E, 0x0004, - 0x0000, 0x0005, 0x000F, 0x0007, 0x001A, 0x000A, 0x0036, 0x0016, - 0x006E, 0x002E, 0x00C1, 0x0041, 0x01BC, 0x00BC, 0x037A, 0x017A, - 0x02F9, 0x0DF9, 0x05EF, 0x05EC, 0x1BD8, 0x37DD, 0x17B5, 0x6FB7, - 0x6FB5, 0x6FB3, 0x6FB1, 0x6FAF, 0x6FAD, 0x6FAB, 0x6FA9, 0x6FA7, - 0x6FA5, 0x6FA3, 0x6FA1, 0x6F9F, 0x6F9D, 0x6F9B, 0x6F99, 0x6F97, - 0x6F95, 0x6F93, 0x6F91, 0x6F8F, 0x6F8D, 0x6F8B, 0x6F89, 0x6F87, - 0x6F85, 0x6F83, 0x6F81, 0x6F7F, 0x6F7D, 0x6F7B, 0x6F79, 0x6F77, - 0x6F75, 0x6F73, 0x6F71, 0x6F6F, 0x6F6D, 0x6F6B, 0x6F69, 0x6F67, - 0x6F65, - }, - { - 0xDF54, 0xDF56, 0xDFC8, 0xDFCA, 0xDFCC, 0xDFCE, 0xDFD0, 0xDFD2, - 0xDFD4, 0xDFD6, 0xDFD8, 0xDFDA, 0xDFDC, 0xDFDE, 0xDFE0, 0xDFE2, - 0x0FE8, 0x2FEA, 0x6FA8, 0x6FF6, 0x07F5, 0x07F7, 0x37D2, 0x37F9, - 0x03F8, 0x0BF8, 0x0BFB, 0x1BEB, 0x01FA, 0x05FA, 0x09FA, 0x0DFA, - 0x0DFF, 0x00FF, 0x02FF, 0x06FB, 0x007C, 0x017C, 0x027C, 0x027F, - 0x003C, 0x00BC, 0x013C, 0x01BC, 0x001C, 0x005C, 0x009C, 0x00DC, - 0x000C, 0x002C, 0x004C, 0x006C, 0x0004, 0x0014, 0x0024, 0x0034, - 0x0000, 0x0008, 0x0010, 0x0018, 0x001E, 0x0002, 0x0006, 0x000A, - 0x000E, 0x000B, 0x0007, 0x0003, 0x001F, 0x0019, 0x0011, 0x0009, - 0x0001, 0x0035, 0x0025, 0x0015, 0x0005, 0x006D, 0x004D, 0x002D, - 0x000D, 0x00DD, 0x009D, 0x005D, 0x001D, 0x01BD, 0x013D, 0x00BD, - 0x003D, 0x037C, 0x027D, 0x017D, 0x007D, 0x06FC, 0x04FC, 0x02FC, - 0x00FC, 0x0DFB, 0x09FB, 0x05FB, 0x01FB, 0x1BF8, 0x1BE8, 0x0BF9, - 0x03F9, 0x37FA, 0x37D3, 0x17F4, 0x07F6, 0x6FF7, 0x6FA9, 0x2FEB, - 0x0FE9, 0xDFE3, 0xDFE1, 0xDFDF, 0xDFDD, 0xDFDB, 0xDFD9, 0xDFD7, - 0xDFD5, 0xDFD3, 0xDFD1, 0xDFCF, 0xDFCD, 0xDFCB, 0xDFC9, 0xDF57, - 0xDF55, - } -}; - -static const uint8_t scales_bits[SCALES_COUNT][129] = { - { - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 12, 11, 11, 10, 9, 8, - 8, 7, 6, 6, 5, 4, 4, 3, - 2, 3, 3, 4, 5, 5, 6, 7, - 8, 8, 9, 10, 11, 11, 12, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, - }, - { - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 14, 14, 13, 12, 11, 10, 8, 7, - 6, 6, 5, 5, 4, 4, 4, 3, - 3, 3, 4, 4, 4, 4, 5, 6, - 6, 7, 8, 9, 11, 12, 13, 14, - 14, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, - }, - { - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 14, 14, 14, 13, 13, 12, 12, - 12, 11, 11, 11, 10, 10, 9, 9, - 9, 8, 8, 8, 7, 7, 7, 6, - 6, 6, 5, 5, 5, 4, 4, 3, - 3, 3, 4, 4, 5, 5, 5, 6, - 6, 6, 7, 7, 7, 8, 8, 8, - 9, 9, 9, 10, 10, 10, 11, 11, - 12, 12, 12, 13, 13, 13, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, - }, - { - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 14, 14, 13, 13, 12, 12, - 11, 11, 10, 10, 9, 8, 8, 7, - 7, 6, 6, 5, 5, 4, 4, 3, - 2, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, - 11, 12, 12, 12, 13, 14, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, - }, - { - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 15, 15, 15, 15, 14, 14, 14, 14, - 13, 13, 13, 13, 12, 12, 12, 12, - 12, 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, 5, 4, 4, 4, - 4, 4, 4, 4, 5, 5, 5, 5, - 5, 6, 6, 6, 6, 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, 15, 15, 15, - 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, - } -}; - -static const uint16_t bitalloc_3_codes[3] = -{ - 0x0003, 0x0000, 0x0002, -}; -static const uint8_t bitalloc_3_bits[3] = -{ - 2, 1, 2, -}; - -static const uint16_t bitalloc_5_codes_a[5] = -{ - 0x000F, 0x0006, 0x0000, 0x0002, 0x000E, -}; -static const uint16_t bitalloc_5_codes_b[5] = -{ - 0x0007, 0x0001, 0x0002, 0x0000, 0x0006, -}; -static const uint16_t bitalloc_5_codes_c[5] = -{ - 0x0007, 0x0005, 0x0000, 0x0004, 0x0006, -}; -static const uint8_t bitalloc_5_bits_a[5] = -{ - 4, 3, 1, 2, 4, -}; -static const uint8_t bitalloc_5_bits_b[5] = -{ - 3, 2, 2, 2, 3, -}; -static const uint8_t bitalloc_5_bits_c[5] = -{ - 3, 3, 1, 3, 3, -}; - -static const uint16_t bitalloc_7_codes_a[7] = -{ - 0x001E, 0x000E, 0x0005, 0x0000, 0x0006, 0x0004, 0x001F, -}; -static const uint16_t bitalloc_7_codes_b[7] = -{ - 0x0014, 0x000B, 0x0000, 0x0003, 0x0001, 0x0004, 0x0015, -}; -static const uint16_t bitalloc_7_codes_c[7] = -{ - 0x0000, 0x0002, 0x0001, 0x0003, 0x0002, 0x0003, 0x0001, -}; -static const uint8_t bitalloc_7_bits_a[7] = -{ - 5, 4, 3, 1, 3, 3, 5, -}; -static const uint8_t bitalloc_7_bits_b[7] = -{ - 5, 4, 2, 2, 2, 3, 5, -}; -static const uint8_t bitalloc_7_bits_c[7] = -{ - 4, 4, 2, 2, 2, 4, 4, -}; - -static const uint16_t bitalloc_9_codes_a[9] = -{ - 0x0030, 0x0019, 0x0009, 0x0005, 0x0000, 0x0007, 0x000D, 0x0008, - 0x0031, -}; -static const uint16_t bitalloc_9_codes_b[9] = -{ - 0x0018, 0x001A, 0x0002, 0x0007, 0x0002, 0x0000, 0x0003, 0x001B, - 0x0019, -}; -static const uint16_t bitalloc_9_codes_c[9] = -{ - 0x001C, 0x000F, 0x0002, 0x0007, 0x0002, 0x0000, 0x0006, 0x0006, - 0x001D, -}; -static const uint8_t bitalloc_9_bits_a[9] = -{ - 6, 5, 4, 3, 1, 3, 4, 4, 6, -}; -static const uint8_t bitalloc_9_bits_b[9] = -{ - 5, 5, 3, 3, 2, 2, 3, 5, 5, -}; -static const uint8_t bitalloc_9_bits_c[9] = -{ - 6, 5, 3, 3, 2, 2, 3, 4, 6, -}; - -static const uint16_t bitalloc_13_codes_a[13] = -{ - 0x0070, 0x002E, 0x0039, 0x001D, 0x000C, 0x000F, 0x0000, 0x0004, - 0x000D, 0x000A, 0x0016, 0x002F, 0x0071, -}; -static const uint16_t bitalloc_13_codes_b[13] = -{ - 0x0038, 0x0010, 0x001D, 0x0007, 0x000F, 0x0005, 0x0000, 0x0006, - 0x0002, 0x0009, 0x0006, 0x0011, 0x0039, -}; -static const uint16_t bitalloc_13_codes_c[13] = -{ - 0x0004, 0x001A, 0x0003, 0x000E, 0x0000, 0x0003, 0x0005, 0x0004, - 0x0002, 0x000F, 0x000C, 0x001B, 0x0005, -}; -static const uint8_t bitalloc_13_bits_a[13] = -{ - 7, 6, 6, 5, 4, 4, 1, 3, 4, 4, 5, 6, 7, -}; -static const uint8_t bitalloc_13_bits_b[13] = -{ - 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 4, 5, 6, -}; -static const uint8_t bitalloc_13_bits_c[13] = -{ - 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5, -}; - -static const uint16_t bitalloc_17_codes_a[17] = -{ - 0x0154, 0x00AB, 0x002B, 0x000B, 0x0003, 0x000A, 0x0001, 0x0006, - 0x0001, 0x0007, 0x0004, 0x000B, 0x0000, 0x0004, 0x0014, 0x0054, - 0x0155, -}; -static const uint16_t bitalloc_17_codes_b[17] = -{ - 0x007C, 0x003F, 0x0019, 0x000D, 0x001C, 0x0008, 0x000F, 0x0005, - 0x0000, 0x0006, 0x0002, 0x0009, 0x001D, 0x000E, 0x001E, 0x0018, - 0x007D, -}; -static const uint16_t bitalloc_17_codes_c[17] = -{ - 0x002C, 0x0017, 0x0005, 0x001C, 0x0003, 0x000A, 0x000F, 0x0003, - 0x0006, 0x0004, 0x0000, 0x000B, 0x0004, 0x001D, 0x000A, 0x0004, - 0x002D, -}; -static const uint16_t bitalloc_17_codes_d[17] = -{ - 0x0100, 0x0102, 0x0082, 0x0042, 0x0022, 0x0012, 0x000A, 0x0006, - 0x0000, 0x0007, 0x000B, 0x0013, 0x0023, 0x0043, 0x0083, 0x0103, - 0x0101, -}; -static const uint16_t bitalloc_17_codes_e[17] = -{ - 0x00E8, 0x00F6, 0x0075, 0x0034, 0x003B, 0x001B, 0x001F, 0x0004, - 0x0000, 0x0005, 0x000C, 0x001C, 0x003C, 0x0035, 0x007A, 0x00F7, - 0x00E9, -}; -static const uint16_t bitalloc_17_codes_f[17] = -{ - 0x0004, 0x0003, 0x001E, 0x0001, 0x0001, 0x000E, 0x0001, 0x0004, - 0x0006, 0x0005, 0x0002, 0x000F, 0x0006, 0x000E, 0x001F, 0x0000, - 0x0005, -}; -static const uint16_t bitalloc_17_codes_g[17] = -{ - 0x0060, 0x007E, 0x0031, 0x0019, 0x000D, 0x0004, 0x0000, 0x0006, - 0x0002, 0x0007, 0x0001, 0x0005, 0x000E, 0x001E, 0x003E, 0x007F, - 0x0061, -}; -static const uint8_t bitalloc_17_bits_a[17] = -{ - 12, 11, 9, 7, 5, 4, 3, 3, 2, 3, 3, 4, 4, 6, 8, 10, - 12, -}; -static const uint8_t bitalloc_17_bits_b[17] = -{ - 8, 7, 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 5, 5, 6, 6, - 8, -}; -static const uint8_t bitalloc_17_bits_c[17] = -{ - 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 5, 5, - 7, -}; -static const uint8_t bitalloc_17_bits_d[17] = -{ - 9, 9, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, 8, 9, - 9, -}; -static const uint8_t bitalloc_17_bits_e[17] = -{ - 8, 8, 7, 6, 6, 5, 5, 3, 1, 3, 4, 5, 6, 6, 7, 8, - 8, -}; -static const uint8_t bitalloc_17_bits_f[17] = -{ - 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, - 8, -}; -static const uint8_t bitalloc_17_bits_g[17] = -{ - 8, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, - 8, -}; - -static const uint16_t bitalloc_25_codes_a[25] = -{ - 0x2854, 0x142B, 0x050B, 0x0143, 0x00A2, 0x0052, 0x002E, 0x0015, - 0x0004, 0x000E, 0x0000, 0x0003, 0x0006, 0x0004, 0x0001, 0x000F, - 0x0005, 0x0016, 0x002F, 0x0053, 0x00A3, 0x00A0, 0x0284, 0x0A14, - 0x2855, -}; -static const uint16_t bitalloc_25_codes_b[25] = -{ - 0x001C, 0x000F, 0x0005, 0x0000, 0x0030, 0x0036, 0x000E, 0x0019, - 0x0001, 0x0008, 0x000E, 0x0001, 0x0005, 0x0002, 0x000F, 0x0009, - 0x0006, 0x001A, 0x000F, 0x0037, 0x0031, 0x0001, 0x0006, 0x0004, - 0x001D, -}; -static const uint16_t bitalloc_25_codes_c[25] = -{ - 0x004C, 0x0027, 0x006D, 0x0028, 0x0037, 0x000E, 0x0015, 0x0000, - 0x0005, 0x0008, 0x000B, 0x000E, 0x0001, 0x000F, 0x000C, 0x0009, - 0x0006, 0x0001, 0x001A, 0x000F, 0x0008, 0x0029, 0x0012, 0x006C, - 0x004D, -}; -static const uint16_t bitalloc_25_codes_d[25] = -{ - 0x0780, 0x0782, 0x03C2, 0x01E2, 0x00FE, 0x0079, 0x003D, 0x001C, - 0x000C, 0x0004, 0x0000, 0x0006, 0x0002, 0x0007, 0x0001, 0x0005, - 0x000D, 0x001D, 0x003E, 0x007E, 0x00FF, 0x01E3, 0x03C3, 0x0783, - 0x0781, -}; -static const uint16_t bitalloc_25_codes_e[25] = -{ - 0x003C, 0x0092, 0x0018, 0x001F, 0x004E, 0x000D, 0x0025, 0x0004, - 0x0010, 0x0000, 0x000A, 0x0002, 0x0003, 0x0003, 0x000B, 0x0001, - 0x0011, 0x0005, 0x0026, 0x000E, 0x004F, 0x0048, 0x0019, 0x0093, - 0x003D, -}; -static const uint16_t bitalloc_25_codes_f[25] = -{ - 0x0324, 0x0193, 0x00CE, 0x0065, 0x0024, 0x000C, 0x0013, 0x0004, - 0x0007, 0x000A, 0x000D, 0x000F, 0x0001, 0x0000, 0x000E, 0x000B, - 0x0008, 0x0005, 0x0018, 0x000D, 0x0025, 0x0066, 0x00CF, 0x00C8, - 0x0325, -}; -static const uint16_t bitalloc_25_codes_g[25] = -{ - 0x03A8, 0x03AE, 0x01D5, 0x0094, 0x0014, 0x004B, 0x000B, 0x003B, - 0x0013, 0x0003, 0x000F, 0x0005, 0x0001, 0x0006, 0x0000, 0x0008, - 0x001C, 0x0004, 0x0024, 0x0074, 0x0015, 0x0095, 0x01D6, 0x03AF, - 0x03A9, -}; -static const uint8_t bitalloc_25_bits_a[25] = -{ - 14, 13, 11, 9, 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4, - 4, 5, 6, 7, 8, 8, 10, 12, 14, -}; -static const uint8_t bitalloc_25_bits_b[25] = -{ - 9, 8, 7, 6, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 4, 4, - 4, 5, 5, 6, 6, 6, 7, 7, 9, -}; -static const uint8_t bitalloc_25_bits_c[25] = -{ - 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 4, 4, 3, 4, 4, 4, - 4, 4, 5, 5, 5, 6, 6, 7, 8, -}; -static const uint8_t bitalloc_25_bits_d[25] = -{ - 12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 12, -}; -static const uint8_t bitalloc_25_bits_e[25] = -{ - 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 7, 8, 8, -}; -static const uint8_t bitalloc_25_bits_f[25] = -{ - 10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 4, 4, 3, 3, 4, 4, - 4, 4, 5, 5, 6, 7, 8, 8, 10, -}; -static const uint8_t bitalloc_25_bits_g[25] = -{ - 10, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 3, 3, 4, - 5, 5, 6, 7, 7, 8, 9, 10, 10, -}; - -static const uint16_t bitalloc_33_codes_a[33] = -{ - 0x1580, 0x1582, 0x0AC2, 0x0562, 0x02B2, 0x015E, 0x00AD, 0x0054, - 0x001C, 0x003C, 0x000F, 0x001F, 0x0008, 0x000B, 0x000D, 0x0000, - 0x0002, 0x0001, 0x000E, 0x000C, 0x0009, 0x0006, 0x0014, 0x003D, - 0x001D, 0x0055, 0x00AE, 0x015F, 0x02B3, 0x0563, 0x0AC3, 0x1583, - 0x1581, -}; -static const uint16_t bitalloc_33_codes_b[33] = -{ - 0x030C, 0x0187, 0x006D, 0x0028, 0x0037, 0x0066, 0x0015, 0x0031, - 0x0000, 0x000B, 0x0012, 0x001A, 0x0001, 0x0007, 0x000A, 0x000E, - 0x0001, 0x000F, 0x000B, 0x0008, 0x0004, 0x001B, 0x0013, 0x000C, - 0x0001, 0x0032, 0x001A, 0x0067, 0x0060, 0x0029, 0x00C2, 0x006C, - 0x030D, -}; -static const uint16_t bitalloc_33_codes_c[33] = -{ - 0x00CC, 0x0067, 0x0005, 0x0070, 0x0003, 0x001A, 0x0039, 0x003F, - 0x000A, 0x0012, 0x0018, 0x001D, 0x0001, 0x0003, 0x0007, 0x000A, - 0x000D, 0x000B, 0x0008, 0x0004, 0x0002, 0x001E, 0x0019, 0x0013, - 0x000B, 0x0000, 0x003E, 0x001B, 0x0018, 0x0071, 0x0032, 0x0004, - 0x00CD, -}; -static const uint16_t bitalloc_33_codes_d[33] = -{ - 0x3AF8, 0x3AFA, 0x1D7E, 0x0EBC, 0x075C, 0x03AC, 0x01D4, 0x0094, - 0x0014, 0x004B, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005, - 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x0074, - 0x0015, 0x0095, 0x01D5, 0x03AD, 0x075D, 0x0EBD, 0x1D7F, 0x3AFB, - 0x3AF9, -}; -static const uint16_t bitalloc_33_codes_e[33] = -{ - 0x01C8, 0x01E6, 0x0064, 0x00E2, 0x00E5, 0x0030, 0x0033, 0x0073, - 0x007A, 0x001A, 0x003A, 0x0002, 0x001A, 0x001F, 0x0007, 0x0001, - 0x0002, 0x0002, 0x000C, 0x0000, 0x001B, 0x0003, 0x003B, 0x001B, - 0x007B, 0x0078, 0x0070, 0x0031, 0x00F2, 0x00E3, 0x0065, 0x01E7, - 0x01C9, -}; -static const uint16_t bitalloc_33_codes_f[33] = -{ - 0x0724, 0x0393, 0x01CE, 0x00E5, 0x002C, 0x0008, 0x0017, 0x003E, - 0x0005, 0x0014, 0x001D, 0x0000, 0x0003, 0x0006, 0x0008, 0x000B, - 0x000D, 0x000C, 0x0009, 0x0007, 0x0004, 0x0001, 0x001E, 0x0015, - 0x000A, 0x003F, 0x0038, 0x0009, 0x002D, 0x00E6, 0x01CF, 0x01C8, - 0x0725, -}; -static const uint16_t bitalloc_33_codes_g[33] = -{ - 0x0284, 0x0042, 0x0140, 0x0143, 0x003E, 0x00BE, 0x0011, 0x0051, - 0x0009, 0x0029, 0x0005, 0x0015, 0x0000, 0x0008, 0x000E, 0x0002, - 0x0006, 0x0003, 0x000F, 0x0009, 0x0001, 0x0016, 0x0006, 0x002E, - 0x000E, 0x005E, 0x001E, 0x00BF, 0x003F, 0x0020, 0x0141, 0x0043, - 0x0285, -}; -static const uint8_t bitalloc_33_bits_a[33] = -{ - 13, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, - 3, 3, 4, 4, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, - 13, -}; -static const uint8_t bitalloc_33_bits_b[33] = -{ - 10, 9, 8, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, - 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, - 10, -}; -static const uint8_t bitalloc_33_bits_c[33] = -{ - 9, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, - 9, -}; -static const uint8_t bitalloc_33_bits_d[33] = -{ - 14, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3, - 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, - 14, -}; -static const uint8_t bitalloc_33_bits_e[33] = -{ - 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 3, - 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, - 9, -}; -static const uint8_t bitalloc_33_bits_f[33] = -{ - 11, 10, 9, 8, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, - 11, -}; -static const uint8_t bitalloc_33_bits_g[33] = -{ - 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3, - 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, - 10, -}; - -static const uint16_t bitalloc_65_codes_a[65] = -{ - 0x9E5C, 0x9E5E, 0x4F2C, 0x2794, 0x13C4, 0x1E44, 0x09E3, 0x0F23, - 0x04F3, 0x0792, 0x027E, 0x03CE, 0x013D, 0x01E5, 0x009C, 0x00CC, - 0x0040, 0x0058, 0x0067, 0x001E, 0x0021, 0x002D, 0x003D, 0x0007, - 0x0011, 0x0014, 0x0017, 0x001A, 0x001C, 0x001F, 0x0001, 0x0004, - 0x0006, 0x0005, 0x0002, 0x0000, 0x001D, 0x001B, 0x0018, 0x0015, - 0x0012, 0x000E, 0x0006, 0x0032, 0x0026, 0x001F, 0x0078, 0x0059, - 0x0041, 0x00CD, 0x009D, 0x01E6, 0x013E, 0x03CF, 0x027F, 0x0793, - 0x0790, 0x04F0, 0x09E4, 0x1E45, 0x13C5, 0x2795, 0x4F2D, 0x9E5F, - 0x9E5D, -}; -static const uint16_t bitalloc_65_codes_b[65] = -{ - 0x0A8C, 0x0547, 0x01B5, 0x0008, 0x00DB, 0x0152, 0x0005, 0x000B, - 0x008E, 0x00AE, 0x00E4, 0x0003, 0x0037, 0x0039, 0x0055, 0x006C, - 0x0073, 0x0003, 0x0015, 0x001D, 0x0028, 0x0030, 0x0037, 0x003E, - 0x0006, 0x000B, 0x000F, 0x0012, 0x0016, 0x0019, 0x001D, 0x0001, - 0x0004, 0x0002, 0x001E, 0x001A, 0x0017, 0x0013, 0x0010, 0x000C, - 0x0007, 0x003F, 0x0038, 0x0031, 0x0029, 0x0022, 0x001A, 0x0014, - 0x0000, 0x006D, 0x0056, 0x0046, 0x0038, 0x0004, 0x00E5, 0x00AF, - 0x008F, 0x006C, 0x000A, 0x0153, 0x0150, 0x0009, 0x02A2, 0x01B4, - 0x0A8D, -}; -static const uint16_t bitalloc_65_codes_c[65] = -{ - 0x045C, 0x022F, 0x03F5, 0x01BC, 0x01FB, 0x0059, 0x00D0, 0x00DF, - 0x000A, 0x002D, 0x002F, 0x0052, 0x0069, 0x0078, 0x007F, 0x000A, - 0x0010, 0x001C, 0x0023, 0x002A, 0x0035, 0x003A, 0x003D, 0x0000, - 0x0003, 0x0006, 0x0009, 0x000C, 0x000F, 0x0012, 0x0016, 0x0018, - 0x001C, 0x0019, 0x0017, 0x0013, 0x0010, 0x000D, 0x000A, 0x0007, - 0x0004, 0x0001, 0x003E, 0x003B, 0x0036, 0x002B, 0x0028, 0x001D, - 0x0011, 0x000B, 0x0004, 0x0079, 0x006E, 0x0053, 0x0044, 0x002E, - 0x000B, 0x00FC, 0x00D1, 0x008A, 0x0058, 0x01BD, 0x0116, 0x03F4, - 0x045D, -}; -static const uint16_t bitalloc_65_codes_d[65] = -{ - 0x70B0, 0x70B2, 0x70B4, 0x2852, 0x385B, 0x142E, 0x1C2E, 0x0A15, - 0x0E14, 0x0214, 0x0704, 0x0104, 0x010B, 0x0383, 0x0083, 0x0143, - 0x01C3, 0x0043, 0x00A2, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012, - 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000, - 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B, - 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A3, 0x00A0, - 0x0040, 0x01C0, 0x0084, 0x0384, 0x0284, 0x0105, 0x0705, 0x0215, - 0x0E15, 0x0A16, 0x1C2F, 0x142F, 0x1428, 0x2853, 0x70B5, 0x70B3, - 0x70B1, -}; -static const uint16_t bitalloc_65_codes_e[65] = -{ - 0x032C, 0x0332, 0x0378, 0x037E, 0x008C, 0x014A, 0x0188, 0x0197, - 0x019E, 0x01BD, 0x0044, 0x0047, 0x00AA, 0x00C5, 0x00CD, 0x00DC, - 0x001C, 0x002C, 0x0053, 0x0063, 0x0068, 0x0008, 0x000F, 0x0017, - 0x002B, 0x0035, 0x0005, 0x0009, 0x0016, 0x001C, 0x0006, 0x000F, - 0x0004, 0x0000, 0x0007, 0x001D, 0x0017, 0x000A, 0x0006, 0x0036, - 0x0030, 0x0028, 0x0010, 0x0009, 0x0069, 0x0064, 0x0054, 0x002D, - 0x001D, 0x00DD, 0x00CE, 0x00CA, 0x00AB, 0x00A4, 0x0045, 0x01BE, - 0x019F, 0x0198, 0x0189, 0x014B, 0x008D, 0x037F, 0x0379, 0x0333, - 0x032D, -}; -static const uint16_t bitalloc_65_codes_f[65] = -{ - 0x0FE0, 0x0FE2, 0x0FE8, 0x0FEA, 0x0FEC, 0x0FEE, 0x0FF0, 0x0FF2, - 0x0FF4, 0x2FF2, 0x07F2, 0x07FB, 0x03F6, 0x0BFA, 0x0BFD, 0x01FF, - 0x05FF, 0x02FC, 0x007C, 0x017C, 0x003C, 0x00BC, 0x001C, 0x005C, - 0x000C, 0x002C, 0x0004, 0x0014, 0x0000, 0x0008, 0x000E, 0x0002, - 0x0006, 0x0003, 0x000F, 0x0009, 0x0001, 0x0015, 0x0005, 0x002D, - 0x000D, 0x005D, 0x001D, 0x00BD, 0x003D, 0x017D, 0x007D, 0x02FD, - 0x00FC, 0x05FC, 0x01FA, 0x0BFB, 0x03F7, 0x17F8, 0x07F3, 0x2FF3, - 0x0FF5, 0x0FF3, 0x0FF1, 0x0FEF, 0x0FED, 0x0FEB, 0x0FE9, 0x0FE3, - 0x0FE1, -}; -static const uint16_t bitalloc_65_codes_g[65] = -{ - 0x010C, 0x038A, 0x0608, 0x0786, 0x0084, 0x0087, 0x0302, 0x0305, - 0x0040, 0x00E0, 0x00E3, 0x0183, 0x001E, 0x005E, 0x009E, 0x00DE, - 0x00F1, 0x0011, 0x0039, 0x0061, 0x0079, 0x0009, 0x001D, 0x0031, - 0x003D, 0x0005, 0x000F, 0x0019, 0x001F, 0x0003, 0x0006, 0x000A, - 0x000E, 0x000B, 0x0008, 0x0004, 0x0000, 0x001A, 0x0012, 0x000A, - 0x0002, 0x0036, 0x0026, 0x0016, 0x0006, 0x006E, 0x004E, 0x002E, - 0x000E, 0x00DF, 0x009F, 0x005F, 0x001F, 0x01E0, 0x0180, 0x00E1, - 0x0041, 0x03C2, 0x0303, 0x01C4, 0x0085, 0x0787, 0x0609, 0x038B, - 0x010D, -}; -static const uint8_t bitalloc_65_bits_a[65] = -{ - 16, 16, 15, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, - 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, - 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, - 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 13, 13, 14, 15, 16, - 16, -}; -static const uint8_t bitalloc_65_bits_b[65] = -{ - 12, 11, 10, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, - 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, - 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, - 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10, - 12, -}; -static const uint8_t bitalloc_65_bits_c[65] = -{ - 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 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, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, - 11, -}; -static const uint8_t bitalloc_65_bits_d[65] = -{ - 15, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 10, 9, 9, - 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 3, - 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, - 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 15, 15, - 15, -}; -static const uint8_t bitalloc_65_bits_e[65] = -{ - 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, - 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, - 3, 3, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, - 10, -}; -static const uint8_t bitalloc_65_bits_f[65] = -{ - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 11, - 11, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3, - 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, -}; -static const uint8_t bitalloc_65_bits_g[65] = -{ - 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, - 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, - 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, - 11, -}; - -static const uint16_t bitalloc_129_codes_a[129] = -{ - 0x0660, 0x0666, 0x06EC, 0x0722, 0x0760, 0x076E, 0x004C, 0x004E, - 0x00F4, 0x010A, 0x0148, 0x0156, 0x01D4, 0x01F2, 0x0331, 0x0370, - 0x0377, 0x0396, 0x03B1, 0x0024, 0x0064, 0x007B, 0x008A, 0x00A5, - 0x00D4, 0x00EB, 0x00FA, 0x019A, 0x01B9, 0x01C9, 0x01D9, 0x0010, - 0x0030, 0x0033, 0x0043, 0x0053, 0x006B, 0x007A, 0x00CA, 0x00D2, - 0x00DE, 0x00E6, 0x00F6, 0x000E, 0x001F, 0x0023, 0x002B, 0x003B, - 0x003F, 0x0067, 0x0070, 0x0077, 0x0005, 0x000D, 0x0012, 0x001B, - 0x002C, 0x0035, 0x003A, 0x0004, 0x000B, 0x0017, 0x001F, 0x0009, - 0x0008, 0x000A, 0x0000, 0x0018, 0x000C, 0x0005, 0x003C, 0x0036, - 0x002D, 0x001C, 0x0013, 0x000E, 0x0006, 0x007A, 0x0071, 0x0068, - 0x0064, 0x003C, 0x0034, 0x0028, 0x0020, 0x000F, 0x00F7, 0x00E7, - 0x00DF, 0x00D3, 0x00CB, 0x007B, 0x0074, 0x0054, 0x0044, 0x003C, - 0x0031, 0x0011, 0x01DA, 0x01CA, 0x01BA, 0x019B, 0x00FB, 0x00F8, - 0x00D5, 0x00AA, 0x008B, 0x0084, 0x0065, 0x0025, 0x03B6, 0x0397, - 0x0390, 0x0371, 0x0332, 0x01F3, 0x01D5, 0x0157, 0x0149, 0x010B, - 0x00F5, 0x004F, 0x004D, 0x076F, 0x0761, 0x0723, 0x06ED, 0x0667, - 0x0661, -}; -static const uint16_t bitalloc_129_codes_b[129] = -{ - 0x29DC, 0x14EF, 0x0455, 0x0E9C, 0x022B, 0x0489, 0x0740, 0x074F, - 0x0172, 0x0245, 0x0247, 0x030A, 0x03A1, 0x001C, 0x008B, 0x00D6, - 0x010C, 0x0148, 0x014F, 0x0186, 0x01D1, 0x0008, 0x000F, 0x0046, - 0x005D, 0x0078, 0x0087, 0x0096, 0x00A5, 0x00BC, 0x00D8, 0x00DE, - 0x00F6, 0x0005, 0x0014, 0x0024, 0x002F, 0x003A, 0x003D, 0x0049, - 0x0050, 0x0058, 0x005F, 0x0066, 0x006D, 0x0075, 0x007C, 0x0004, - 0x000B, 0x0013, 0x0018, 0x001B, 0x001F, 0x0022, 0x0026, 0x002A, - 0x002D, 0x0031, 0x0034, 0x0038, 0x003B, 0x003F, 0x0003, 0x0006, - 0x000A, 0x0007, 0x0004, 0x0000, 0x003C, 0x0039, 0x0035, 0x0032, - 0x002E, 0x002B, 0x0027, 0x0023, 0x0020, 0x001C, 0x0019, 0x0016, - 0x0010, 0x0005, 0x007D, 0x007A, 0x006E, 0x0067, 0x0060, 0x0059, - 0x0051, 0x004A, 0x0042, 0x003B, 0x0034, 0x0025, 0x0015, 0x0006, - 0x00F7, 0x00DF, 0x00D9, 0x00BD, 0x00A6, 0x0097, 0x0090, 0x0079, - 0x006A, 0x0047, 0x0044, 0x0009, 0x01D2, 0x0187, 0x0184, 0x0149, - 0x010D, 0x00D7, 0x00B8, 0x001D, 0x03A6, 0x030B, 0x029C, 0x0246, - 0x0173, 0x0114, 0x0741, 0x053A, 0x0488, 0x0E9D, 0x0A76, 0x0454, - 0x29DD, -}; -static const uint16_t bitalloc_129_codes_c[129] = -{ - 0x0E5C, 0x072F, 0x001D, 0x0724, 0x000F, 0x010D, 0x0324, 0x0393, - 0x03E9, 0x0080, 0x0087, 0x00FA, 0x0164, 0x0193, 0x01DE, 0x01F5, - 0x0010, 0x002A, 0x0041, 0x0064, 0x0073, 0x008E, 0x00A4, 0x00B3, - 0x00D6, 0x00E5, 0x00F4, 0x00FB, 0x0002, 0x0009, 0x0013, 0x001E, - 0x0026, 0x002C, 0x0033, 0x003F, 0x0041, 0x004C, 0x0053, 0x005E, - 0x0065, 0x0070, 0x0073, 0x0078, 0x007B, 0x007E, 0x0002, 0x0005, - 0x0007, 0x000B, 0x000D, 0x0011, 0x0014, 0x0017, 0x001A, 0x001D, - 0x0021, 0x0024, 0x0027, 0x002A, 0x002D, 0x0030, 0x0033, 0x0036, - 0x003A, 0x0037, 0x0034, 0x0031, 0x002E, 0x002B, 0x0028, 0x0025, - 0x0022, 0x001E, 0x001B, 0x0018, 0x0015, 0x0012, 0x000E, 0x000C, - 0x0008, 0x0006, 0x0003, 0x007F, 0x007C, 0x0079, 0x0076, 0x0071, - 0x006A, 0x005F, 0x0058, 0x004D, 0x0046, 0x0040, 0x0038, 0x002D, - 0x0027, 0x001F, 0x0014, 0x0012, 0x0003, 0x0000, 0x00F5, 0x00EE, - 0x00D7, 0x00C8, 0x00A5, 0x008F, 0x007C, 0x0065, 0x0042, 0x002B, - 0x0011, 0x0002, 0x01DF, 0x01C8, 0x0165, 0x00FB, 0x00E4, 0x0081, - 0x0006, 0x03E8, 0x0325, 0x01CA, 0x010C, 0x0725, 0x0396, 0x001C, - 0x0E5D, -}; -static const uint16_t bitalloc_129_codes_d[129] = -{ - 0xA598, 0xA59A, 0xA59C, 0xA59E, 0xC598, 0xE586, 0x3ACC, 0x52CA, - 0x62CD, 0x0D48, 0x1D67, 0x2978, 0x3167, 0x3966, 0x06A5, 0x0EBC, - 0x14BD, 0x1CB1, 0x0350, 0x0353, 0x075F, 0x0A5F, 0x0C5E, 0x0E5E, - 0x01AE, 0x03AD, 0x052D, 0x062D, 0x072D, 0x00D5, 0x01D4, 0x0294, - 0x0314, 0x0394, 0x0014, 0x0094, 0x0114, 0x0174, 0x01B4, 0x01F4, - 0x000B, 0x004B, 0x008B, 0x00BB, 0x00DB, 0x00FB, 0x001B, 0x003B, - 0x0053, 0x0063, 0x0073, 0x0003, 0x0013, 0x0023, 0x002F, 0x0037, - 0x003F, 0x0007, 0x000F, 0x0015, 0x0019, 0x001D, 0x0001, 0x0005, - 0x0009, 0x0006, 0x0002, 0x001E, 0x001A, 0x0016, 0x0010, 0x0008, - 0x0000, 0x0038, 0x0030, 0x0028, 0x001C, 0x000C, 0x007C, 0x006C, - 0x005C, 0x0044, 0x0024, 0x0004, 0x00E4, 0x00C4, 0x00A4, 0x0074, - 0x0034, 0x01F5, 0x01B5, 0x0175, 0x0115, 0x0095, 0x0015, 0x0395, - 0x0315, 0x0295, 0x01D5, 0x00D6, 0x072E, 0x062E, 0x052E, 0x03AE, - 0x01AF, 0x0E5F, 0x0C5F, 0x0C58, 0x0A58, 0x0758, 0x0351, 0x1CB2, - 0x18B2, 0x0EBD, 0x0EB2, 0x3967, 0x3960, 0x2979, 0x2964, 0x0D49, - 0x72C2, 0x52CB, 0x3ACD, 0xE587, 0xC599, 0xA59F, 0xA59D, 0xA59B, - 0xA599, -}; -static const uint16_t bitalloc_129_codes_e[129] = -{ - 0xA13C, 0xC720, 0xA13F, 0xA13E, 0xA13D, 0xE722, 0x5090, 0x6393, - 0x7392, 0x2849, 0x31CE, 0x39CE, 0x1425, 0x18E5, 0x1CE5, 0x0844, - 0x0A1C, 0x0C7C, 0x036C, 0x0423, 0x050F, 0x063F, 0x01B7, 0x0216, - 0x0285, 0x031D, 0x039D, 0x0109, 0x0140, 0x0180, 0x01C8, 0x01CF, - 0x007A, 0x008A, 0x00A2, 0x00C1, 0x00E5, 0x0014, 0x0037, 0x0043, - 0x004E, 0x0056, 0x0061, 0x006C, 0x007C, 0x000B, 0x001C, 0x001F, - 0x0023, 0x0025, 0x0029, 0x002C, 0x002E, 0x0032, 0x0034, 0x0037, - 0x003A, 0x003C, 0x003F, 0x0001, 0x0003, 0x0006, 0x0008, 0x000A, - 0x000C, 0x000B, 0x0009, 0x0007, 0x0004, 0x0002, 0x0000, 0x003D, - 0x003B, 0x0038, 0x0035, 0x0033, 0x002F, 0x002D, 0x002A, 0x0026, - 0x0024, 0x0020, 0x001D, 0x001A, 0x007D, 0x006D, 0x0062, 0x0057, - 0x004F, 0x0044, 0x003C, 0x0015, 0x00E6, 0x00C6, 0x00A3, 0x008B, - 0x007B, 0x006C, 0x01C9, 0x0181, 0x0141, 0x010A, 0x00DA, 0x031E, - 0x0286, 0x0217, 0x0210, 0x0738, 0x0638, 0x0508, 0x036D, 0x0C7D, - 0x0A1D, 0x0845, 0x1CE6, 0x18E6, 0x1426, 0x39CF, 0x31CF, 0x284E, - 0x7393, 0x7390, 0x5091, 0xE723, 0xC724, 0xC725, 0xC722, 0xC723, - 0xC721, -}; -static const uint16_t bitalloc_129_codes_f[129] = -{ - 0x762C, 0x3B17, 0x1555, 0x0608, 0x0AAB, 0x0FF2, 0x0305, 0x0307, - 0x0763, 0x0046, 0x010C, 0x01BC, 0x02AB, 0x03B6, 0x03FD, 0x0080, - 0x0087, 0x00DF, 0x0156, 0x01D9, 0x01F8, 0x01FF, 0x002A, 0x0041, - 0x0061, 0x0094, 0x00D4, 0x00EA, 0x00F2, 0x00FD, 0x0009, 0x000B, - 0x001A, 0x0026, 0x0031, 0x0040, 0x004B, 0x006B, 0x0073, 0x0077, - 0x007A, 0x007C, 0x0000, 0x0002, 0x0006, 0x0008, 0x000B, 0x000E, - 0x0011, 0x0014, 0x0016, 0x0019, 0x001C, 0x001E, 0x0021, 0x0023, - 0x0026, 0x0028, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0036, - 0x0038, 0x0037, 0x0034, 0x0032, 0x0030, 0x002E, 0x002C, 0x0029, - 0x0027, 0x0024, 0x0022, 0x001F, 0x001D, 0x001A, 0x0017, 0x0015, - 0x0012, 0x000F, 0x000C, 0x0009, 0x0007, 0x0003, 0x0001, 0x007D, - 0x007B, 0x0078, 0x0074, 0x0072, 0x0054, 0x0041, 0x0036, 0x0027, - 0x001B, 0x0014, 0x000A, 0x00FE, 0x00F3, 0x00EB, 0x00D5, 0x0095, - 0x006E, 0x0042, 0x002B, 0x0010, 0x01F9, 0x01DA, 0x0157, 0x0154, - 0x00C0, 0x0081, 0x0022, 0x03B7, 0x03B0, 0x01BD, 0x010D, 0x0047, - 0x07F8, 0x0554, 0x0306, 0x0FF3, 0x0EC4, 0x0609, 0x1D8A, 0x1554, - 0x762D, -}; -static const uint16_t bitalloc_129_codes_g[129] = -{ - 0x1E20, 0x1E5E, 0x031C, 0x051A, 0x0718, 0x0916, 0x0B14, 0x0D12, - 0x0F11, 0x0090, 0x018F, 0x028E, 0x038D, 0x048C, 0x058B, 0x068A, - 0x0789, 0x0049, 0x00C8, 0x0148, 0x01C7, 0x0247, 0x02C6, 0x0346, - 0x03C5, 0x0025, 0x0065, 0x00A5, 0x00E4, 0x0124, 0x0164, 0x01A4, - 0x01E3, 0x0013, 0x0033, 0x0053, 0x0073, 0x0093, 0x00B3, 0x00D3, - 0x00F3, 0x000A, 0x001A, 0x002A, 0x003A, 0x004A, 0x005A, 0x006A, - 0x007A, 0x0006, 0x000E, 0x0016, 0x001E, 0x0026, 0x002E, 0x0036, - 0x003E, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, - 0x0000, 0x001D, 0x0019, 0x0015, 0x0011, 0x000D, 0x0009, 0x0005, - 0x003F, 0x0037, 0x002F, 0x0027, 0x001F, 0x0017, 0x000F, 0x0007, - 0x007B, 0x006B, 0x005B, 0x004B, 0x003B, 0x002B, 0x001B, 0x000B, - 0x0008, 0x00F0, 0x00D0, 0x00B0, 0x0090, 0x0070, 0x0050, 0x0030, - 0x01E4, 0x01A5, 0x0165, 0x0125, 0x00E5, 0x00E2, 0x00A2, 0x0062, - 0x03CA, 0x0347, 0x02C7, 0x02C4, 0x0244, 0x0149, 0x00C9, 0x00C6, - 0x0796, 0x068B, 0x0688, 0x048D, 0x048A, 0x028F, 0x028C, 0x0091, - 0x0F2E, 0x0D13, 0x0B15, 0x0917, 0x0719, 0x051B, 0x031D, 0x1E5F, - 0x1E21, -}; -static const uint8_t bitalloc_129_bits_a[129] = -{ - 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, - 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, - 11, -}; -static const uint8_t bitalloc_129_bits_b[129] = -{ - 14, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, - 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, - 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, - 14, -}; -static const uint8_t bitalloc_129_bits_c[129] = -{ - 13, 12, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, - 13, -}; -static const uint8_t bitalloc_129_bits_d[129] = -{ - 16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, - 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 10, 10, 10, - 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, - 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, - 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, - 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, - 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, - 16, -}; -static const uint8_t bitalloc_129_bits_e[129] = -{ - 16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, - 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, - 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 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, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, - 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, - 16, -}; -static const uint8_t bitalloc_129_bits_f[129] = -{ - 15, 14, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 10, 10, 9, - 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, - 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, - 15, -}; -static const uint8_t bitalloc_129_bits_g[129] = -{ - 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, - 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, - 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, - 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, - 13, -}; - -static const uint8_t bitalloc_sizes[10] = { 3, 5, 7, 9, 13, 17, 25, 33, 65, 129 }; - -static const int8_t bitalloc_offsets[10] = - { -1, -2, -3, -4, -6, -8, -12, -16, -32, -64 }; - -static const uint8_t bitalloc_maxbits[10][7] = { - { 2 }, - { 4, 3, 3 }, - { 5, 5, 4 }, - { 6, 5, 6 }, - { 7, 6, 5 }, - { 9, 8, 7, 9, 8, 8, 8 }, - { 9, 9, 8, 9, 8, 9, 9 }, - { 9, 9, 9, 9, 9, 9, 9 }, - { 9, 9, 9, 9, 9, 9, 9 }, - { 9, 9, 9, 9, 9, 9, 9 } -}; - -static const uint16_t* const bitalloc_codes[10][8] = { - { bitalloc_3_codes, NULL }, - { bitalloc_5_codes_a, bitalloc_5_codes_b, bitalloc_5_codes_c, NULL }, - { bitalloc_7_codes_a, bitalloc_7_codes_b, bitalloc_7_codes_c, NULL }, - { bitalloc_9_codes_a, bitalloc_9_codes_b, bitalloc_9_codes_c, NULL }, - { bitalloc_13_codes_a, bitalloc_13_codes_b, bitalloc_13_codes_c, NULL }, - { bitalloc_17_codes_a, bitalloc_17_codes_b, bitalloc_17_codes_c, bitalloc_17_codes_d, - bitalloc_17_codes_e, bitalloc_17_codes_f, bitalloc_17_codes_g, NULL }, - { bitalloc_25_codes_a, bitalloc_25_codes_b, bitalloc_25_codes_c, bitalloc_25_codes_d, - bitalloc_25_codes_e, bitalloc_25_codes_f, bitalloc_25_codes_g, NULL }, - { bitalloc_33_codes_a, bitalloc_33_codes_b, bitalloc_33_codes_c, bitalloc_33_codes_d, - bitalloc_33_codes_e, bitalloc_33_codes_f, bitalloc_33_codes_g, NULL }, - { bitalloc_65_codes_a, bitalloc_65_codes_b, bitalloc_65_codes_c, bitalloc_65_codes_d, - bitalloc_65_codes_e, bitalloc_65_codes_f, bitalloc_65_codes_g, NULL }, - { bitalloc_129_codes_a, bitalloc_129_codes_b, bitalloc_129_codes_c, bitalloc_129_codes_d, - bitalloc_129_codes_e, bitalloc_129_codes_f, bitalloc_129_codes_g, NULL } -}; - -static const uint8_t* const bitalloc_bits[10][8] = { - { bitalloc_3_bits, NULL }, - { bitalloc_5_bits_a, bitalloc_5_bits_b, bitalloc_5_bits_c, NULL }, - { bitalloc_7_bits_a, bitalloc_7_bits_b, bitalloc_7_bits_c, NULL }, - { bitalloc_9_bits_a, bitalloc_9_bits_b, bitalloc_9_bits_c, NULL }, - { bitalloc_13_bits_a, bitalloc_13_bits_b, bitalloc_13_bits_c, NULL }, - { bitalloc_17_bits_a, bitalloc_17_bits_b, bitalloc_17_bits_c, bitalloc_17_bits_d, - bitalloc_17_bits_e, bitalloc_17_bits_f, bitalloc_17_bits_g, NULL }, - { bitalloc_25_bits_a, bitalloc_25_bits_b, bitalloc_25_bits_c, bitalloc_25_bits_d, - bitalloc_25_bits_e, bitalloc_25_bits_f, bitalloc_25_bits_g, NULL }, - { bitalloc_33_bits_a, bitalloc_33_bits_b, bitalloc_33_bits_c, bitalloc_33_bits_d, - bitalloc_33_bits_e, bitalloc_33_bits_f, bitalloc_33_bits_g, NULL }, - { bitalloc_65_bits_a, bitalloc_65_bits_b, bitalloc_65_bits_c, bitalloc_65_bits_d, - bitalloc_65_bits_e, bitalloc_65_bits_f, bitalloc_65_bits_g, NULL }, - { bitalloc_129_bits_a, bitalloc_129_bits_b, bitalloc_129_bits_c, bitalloc_129_bits_d, - bitalloc_129_bits_e, bitalloc_129_bits_f, bitalloc_129_bits_g, NULL } -}; - -#endif /* AVCODEC_DCAHUFF_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dct-test.c b/tizen/distrib/ffmpeg/libavcodec/dct-test.c deleted file mode 100644 index 4f0a0c6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dct-test.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * (c) 2001 Fabrice Bellard - * 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * DCT test (c) 2001 Fabrice Bellard - * Started from sample code by Juan J. Sierralta P. - */ - -#include -#include -#include -#include -#include -#include - -#include "libavutil/common.h" -#include "libavutil/lfg.h" - -#include "simple_idct.h" -#include "aandcttab.h" -#include "faandct.h" -#include "faanidct.h" -#include "x86/idct_xvid.h" -#include "dctref.h" - -#undef printf - -void ff_mmx_idct(DCTELEM *data); -void ff_mmxext_idct(DCTELEM *data); - -void odivx_idct_c(short *block); - -// BFIN -void ff_bfin_idct(DCTELEM *block); -void ff_bfin_fdct(DCTELEM *block); - -// ALTIVEC -void fdct_altivec(DCTELEM *block); -//void idct_altivec(DCTELEM *block);?? no routine - -// ARM -void ff_j_rev_dct_arm(DCTELEM *data); -void ff_simple_idct_arm(DCTELEM *data); -void ff_simple_idct_armv5te(DCTELEM *data); -void ff_simple_idct_armv6(DCTELEM *data); -void ff_simple_idct_neon(DCTELEM *data); - -void ff_simple_idct_axp(DCTELEM *data); - -struct algo { - const char *name; - enum { FDCT, IDCT } is_idct; - void (* func) (DCTELEM *block); - void (* ref) (DCTELEM *block); - enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM, PARTTRANS_PERM } format; - int mm_support; -}; - -#ifndef FAAN_POSTSCALE -#define FAAN_SCALE SCALE_PERM -#else -#define FAAN_SCALE NO_PERM -#endif - -static int cpu_flags; - -struct algo algos[] = { - {"REF-DBL", 0, ff_ref_fdct, ff_ref_fdct, NO_PERM}, - {"FAAN", 0, ff_faandct, ff_ref_fdct, FAAN_SCALE}, - {"FAANI", 1, ff_faanidct, ff_ref_idct, NO_PERM}, - {"IJG-AAN-INT", 0, fdct_ifast, ff_ref_fdct, SCALE_PERM}, - {"IJG-LLM-INT", 0, ff_jpeg_fdct_islow, ff_ref_fdct, NO_PERM}, - {"REF-DBL", 1, ff_ref_idct, ff_ref_idct, NO_PERM}, - {"INT", 1, j_rev_dct, ff_ref_idct, MMX_PERM}, - {"SIMPLE-C", 1, ff_simple_idct, ff_ref_idct, NO_PERM}, - -#if HAVE_MMX - {"MMX", 0, ff_fdct_mmx, ff_ref_fdct, NO_PERM, FF_MM_MMX}, -#if HAVE_MMX2 - {"MMX2", 0, ff_fdct_mmx2, ff_ref_fdct, NO_PERM, FF_MM_MMX2}, - {"SSE2", 0, ff_fdct_sse2, ff_ref_fdct, NO_PERM, FF_MM_SSE2}, -#endif - -#if CONFIG_GPL - {"LIBMPEG2-MMX", 1, ff_mmx_idct, ff_ref_idct, MMX_PERM, FF_MM_MMX}, - {"LIBMPEG2-MMX2", 1, ff_mmxext_idct, ff_ref_idct, MMX_PERM, FF_MM_MMX2}, -#endif - {"SIMPLE-MMX", 1, ff_simple_idct_mmx, ff_ref_idct, MMX_SIMPLE_PERM, FF_MM_MMX}, - {"XVID-MMX", 1, ff_idct_xvid_mmx, ff_ref_idct, NO_PERM, FF_MM_MMX}, - {"XVID-MMX2", 1, ff_idct_xvid_mmx2, ff_ref_idct, NO_PERM, FF_MM_MMX2}, - {"XVID-SSE2", 1, ff_idct_xvid_sse2, ff_ref_idct, SSE2_PERM, FF_MM_SSE2}, -#endif - -#if HAVE_ALTIVEC - {"altivecfdct", 0, fdct_altivec, ff_ref_fdct, NO_PERM, FF_MM_ALTIVEC}, -#endif - -#if ARCH_BFIN - {"BFINfdct", 0, ff_bfin_fdct, ff_ref_fdct, NO_PERM}, - {"BFINidct", 1, ff_bfin_idct, ff_ref_idct, NO_PERM}, -#endif - -#if ARCH_ARM - {"SIMPLE-ARM", 1, ff_simple_idct_arm, ff_ref_idct, NO_PERM }, - {"INT-ARM", 1, ff_j_rev_dct_arm, ff_ref_idct, MMX_PERM }, -#if HAVE_ARMV5TE - {"SIMPLE-ARMV5TE", 1, ff_simple_idct_armv5te, ff_ref_idct, NO_PERM }, -#endif -#if HAVE_ARMV6 - {"SIMPLE-ARMV6", 1, ff_simple_idct_armv6, ff_ref_idct, MMX_PERM }, -#endif -#if HAVE_NEON - {"SIMPLE-NEON", 1, ff_simple_idct_neon, ff_ref_idct, PARTTRANS_PERM }, -#endif -#endif /* ARCH_ARM */ - -#if ARCH_ALPHA - {"SIMPLE-ALPHA", 1, ff_simple_idct_axp, ff_ref_idct, NO_PERM }, -#endif - - { 0 } -}; - -#define AANSCALE_BITS 12 - -uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; - -static 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, -}; - -static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7}; - -static 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); - } -} - -DECLARE_ALIGNED(16, static DCTELEM, block)[64]; -DECLARE_ALIGNED(8, static DCTELEM, block1)[64]; -DECLARE_ALIGNED(8, static DCTELEM, block_org)[64]; - -static inline void mmx_emms(void) -{ -#if HAVE_MMX - if (cpu_flags & FF_MM_MMX) - __asm__ volatile ("emms\n\t"); -#endif -} - -static void dct_error(const char *name, int is_idct, - void (*fdct_func)(DCTELEM *block), - void (*fdct_ref)(DCTELEM *block), int form, 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; - AVLFG prng; - - av_lfg_init(&prng, 1); - - err_inf = 0; - err2 = 0; - for(i=0; i<64; i++) sysErr[i]=0; - for(it=0;it>=3; - } - break; - case 1:{ - int num = av_lfg_get(&prng) % 10 + 1; - for(i=0;i>3)&3)] = block1[i]; - } else { - for(i=0; i<64; i++) - block[i]= block1[i]; - } -#if 0 // simulate mismatch control for tested IDCT but not the ref -{ int sum=0; - for(i=0;i<64;i++) - sum+=block[i]; - - if((sum&1)==0) block[63]^=1; -} -#endif - - fdct_func(block); - mmx_emms(); - - if (form == SCALE_PERM) { - for(i=0; i<64; i++) { - scale = 8*(1 << (AANSCALE_BITS + 11)) / ff_aanscales[i]; - block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> 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= FFMAX(sysErrMax, FFABS(sysErr[i])); - -#if 1 // dump systematic errors - for(i=0; i<64; i++){ - if(i%8==0) printf("\n"); - printf("%7d ", (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] = av_lfg_get(&prng) % 512 -256; - if (is_idct){ - ff_ref_fdct(block1); - - for(i=0;i<64;i++) - block1[i]>>=3; - } - break; - case 1:{ - case 2: - block1[0] = av_lfg_get(&prng) % 512 -256; - block1[1] = av_lfg_get(&prng) % 512 -256; - block1[2] = av_lfg_get(&prng) % 512 -256; - block1[3] = av_lfg_get(&prng) % 512 -256; - }break; - } - - if (form == MMX_PERM) { - for(i=0;i<64;i++) - block[idct_mmx_perm[i]] = block1[i]; - } else if(form == MMX_SIMPLE_PERM) { - 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); - } - } -} - -static 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; - - AVLFG prng; - - av_lfg_init(&prng, 1); - - /* 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"); -} - -int main(int argc, char **argv) -{ - int test_idct = 0, test_248_dct = 0; - int c,i; - int test=1; - cpu_flags = mm_support(); - - ff_ref_dct_init(); - idct_mmx_init(); - - for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; - for(i=0;i - * Copyright (c) 2010 Alex Converse - * Copyright (c) 2010 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * (Inverse) Discrete Cosine Transforms. These are also known as the - * type II and type III DCTs respectively. - */ - -#include -#include "libavutil/mathematics.h" -#include "fft.h" - -/* sin((M_PI * x / (2*n)) */ -#define SIN(s,n,x) (s->costab[(n) - (x)]) - -/* cos((M_PI * x / (2*n)) */ -#define COS(s,n,x) (s->costab[x]) - -static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data) -{ - int n = 1 << ctx->nbits; - int i; - - data[0] = 0; - for(i = 1; i < n/2; i++) { - float tmp1 = data[i ]; - float tmp2 = data[n - i]; - float s = SIN(ctx, n, 2*i); - - s *= tmp1 + tmp2; - tmp1 = (tmp1 - tmp2) * 0.5f; - data[i ] = s + tmp1; - data[n - i] = s - tmp1; - } - - data[n/2] *= 2; - ff_rdft_calc(&ctx->rdft, data); - - data[0] *= 0.5f; - - for(i = 1; i < n-2; i += 2) { - data[i + 1] += data[i - 1]; - data[i ] = -data[i + 2]; - } - - data[n-1] = 0; -} - -static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data) -{ - int n = 1 << ctx->nbits; - int i; - float next = -0.5f * (data[0] - data[n]); - - for(i = 0; i < n/2; i++) { - float tmp1 = data[i ]; - float tmp2 = data[n - i]; - float s = SIN(ctx, n, 2*i); - float c = COS(ctx, n, 2*i); - - c *= tmp1 - tmp2; - s *= tmp1 - tmp2; - - next += c; - - tmp1 = (tmp1 + tmp2) * 0.5f; - data[i ] = tmp1 - s; - data[n - i] = tmp1 + s; - } - - ff_rdft_calc(&ctx->rdft, data); - data[n] = data[1]; - data[1] = next; - - for(i = 3; i <= n; i += 2) - data[i] = data[i - 2] - data[i]; -} - -static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data) -{ - int n = 1 << ctx->nbits; - int i; - - float next = data[n - 1]; - float inv_n = 1.0f / n; - - for (i = n - 2; i >= 2; i -= 2) { - float val1 = data[i ]; - float val2 = data[i - 1] - data[i + 1]; - float c = COS(ctx, n, i); - float s = SIN(ctx, n, i); - - data[i ] = c * val1 + s * val2; - data[i + 1] = s * val1 - c * val2; - } - - data[1] = 2 * next; - - ff_rdft_calc(&ctx->rdft, data); - - for (i = 0; i < n / 2; i++) { - float tmp1 = data[i ] * inv_n; - float tmp2 = data[n - i - 1] * inv_n; - float csc = ctx->csc2[i] * (tmp1 - tmp2); - - tmp1 += tmp2; - data[i ] = tmp1 + csc; - data[n - i - 1] = tmp1 - csc; - } -} - -static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data) -{ - int n = 1 << ctx->nbits; - int i; - float next; - - for (i=0; i < n/2; i++) { - float tmp1 = data[i ]; - float tmp2 = data[n - i - 1]; - float s = SIN(ctx, n, 2*i + 1); - - s *= tmp1 - tmp2; - tmp1 = (tmp1 + tmp2) * 0.5f; - - data[i ] = tmp1 + s; - data[n-i-1] = tmp1 - s; - } - - ff_rdft_calc(&ctx->rdft, data); - - next = data[1] * 0.5; - data[1] *= -1; - - for (i = n - 2; i >= 0; i -= 2) { - float inr = data[i ]; - float ini = data[i + 1]; - float c = COS(ctx, n, i); - float s = SIN(ctx, n, i); - - data[i ] = c * inr + s * ini; - - data[i+1] = next; - - next += s * inr - c * ini; - } -} - -void ff_dct_calc(DCTContext *s, FFTSample *data) -{ - s->dct_calc(s, data); -} - -av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse) -{ - int n = 1 << nbits; - int i; - - s->nbits = nbits; - s->inverse = inverse; - - ff_init_ff_cos_tabs(nbits+2); - - s->costab = ff_cos_tabs[nbits+2]; - - s->csc2 = av_malloc(n/2 * sizeof(FFTSample)); - - if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) { - av_free(s->csc2); - return -1; - } - - for (i = 0; i < n/2; i++) - s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1))); - - switch(inverse) { - case DCT_I : s->dct_calc = ff_dct_calc_I_c; break; - case DCT_II : s->dct_calc = ff_dct_calc_II_c ; break; - case DCT_III: s->dct_calc = ff_dct_calc_III_c; break; - case DST_I : s->dct_calc = ff_dst_calc_I_c; break; - } - return 0; -} - -av_cold void ff_dct_end(DCTContext *s) -{ - ff_rdft_end(&s->rdft); - av_free(s->csc2); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/dctref.c b/tizen/distrib/ffmpeg/libavcodec/dctref.c deleted file mode 100644 index 851014b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dctref.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * reference discrete cosine transform (double precision) - * Copyright (C) 2009 Dylan Yudaken - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * reference discrete cosine transform (double precision) - * - * @author Dylan Yudaken (dyudaken at gmail) - * - * @note This file could be optimized a lot, but is for - * reference and so readability is better. - */ - -#include "libavutil/mathematics.h" -#include "dctref.h" - -static double coefficients[8 * 8]; - -/** - * Initialize the double precision discrete cosine transform - * functions fdct & idct. - */ -av_cold void ff_ref_dct_init(void) -{ - unsigned int i, j; - - for (j = 0; j < 8; ++j) { - coefficients[j] = sqrt(0.125); - for (i = 8; i < 64; i += 8) { - coefficients[i + j] = 0.5 * cos(i * (j + 0.5) * M_PI / 64.0); - } - } -} - -/** - * Transform 8x8 block of data with a double precision forward DCT
- * This is a reference implementation. - * - * @param block pointer to 8x8 block of data to transform - */ -void ff_ref_fdct(short *block) -{ - /* implement the equation: block = coefficients * block * coefficients' */ - - unsigned int i, j, k; - double out[8 * 8]; - - /* out = coefficients * block */ - for (i = 0; i < 64; i += 8) { - for (j = 0; j < 8; ++j) { - double tmp = 0; - for (k = 0; k < 8; ++k) { - tmp += coefficients[i + k] * block[k * 8 + j]; - } - out[i + j] = tmp * 8; - } - } - - /* block = out * (coefficients') */ - for (j = 0; j < 8; ++j) { - for (i = 0; i < 64; i += 8) { - double tmp = 0; - for (k = 0; k < 8; ++k) { - tmp += out[i + k] * coefficients[j * 8 + k]; - } - block[i + j] = floor(tmp + 0.499999999999); - } - } -} - -/** - * Transform 8x8 block of data with a double precision inverse DCT
- * This is a reference implementation. - * - * @param block pointer to 8x8 block of data to transform - */ -void ff_ref_idct(short *block) -{ - /* implement the equation: block = (coefficients') * block * coefficients */ - - unsigned int i, j, k; - double out[8 * 8]; - - /* out = block * coefficients */ - for (i = 0; i < 64; i += 8) { - for (j = 0; j < 8; ++j) { - double tmp = 0; - for (k = 0; k < 8; ++k) { - tmp += block[i + k] * coefficients[k * 8 + j]; - } - out[i + j] = tmp; - } - } - - /* block = (coefficients') * out */ - for (i = 0; i < 8; ++i) { - for (j = 0; j < 8; ++j) { - double tmp = 0; - for (k = 0; k < 64; k += 8) { - tmp += coefficients[k + i] * out[k + j]; - } - block[i * 8 + j] = floor(tmp + 0.5); - } - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/dctref.h b/tizen/distrib/ffmpeg/libavcodec/dctref.h deleted file mode 100644 index adbaf68..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dctref.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * reference discrete cosine transform (double precision) - * Copyright (C) 2009 Dylan Yudaken - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DCTREF_H -#define AVCODEC_DCTREF_H - -#include "dsputil.h" - -void ff_ref_fdct(DCTELEM *block); -void ff_ref_idct(DCTELEM *block); -void ff_ref_dct_init(void); - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/dirac.c b/tizen/distrib/ffmpeg/libavcodec/dirac.c deleted file mode 100644 index c65a51f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dirac.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2007 Marco Gerards - * Copyright (C) 2009 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Dirac Decoder - * @author Marco Gerards - */ - -#include "dirac.h" -#include "avcodec.h" -#include "golomb.h" -#include "mpeg12data.h" - -// defaults for source parameters -static const dirac_source_params dirac_source_parameters_defaults[] = { - { 640, 480, 2, 0, 0, 1, 1, 640, 480, 0, 0, 1, 0 }, - { 176, 120, 2, 0, 0, 9, 2, 176, 120, 0, 0, 1, 1 }, - { 176, 144, 2, 0, 1, 10, 3, 176, 144, 0, 0, 1, 2 }, - { 352, 240, 2, 0, 0, 9, 2, 352, 240, 0, 0, 1, 1 }, - { 352, 288, 2, 0, 1, 10, 3, 352, 288, 0, 0, 1, 2 }, - { 704, 480, 2, 0, 0, 9, 2, 704, 480, 0, 0, 1, 1 }, - { 704, 576, 2, 0, 1, 10, 3, 704, 576, 0, 0, 1, 2 }, - { 720, 480, 1, 1, 0, 4, 2, 704, 480, 8, 0, 3, 1 }, - { 720, 576, 1, 1, 1, 3, 3, 704, 576, 8, 0, 3, 2 }, - - { 1280, 720, 1, 0, 1, 7, 1, 1280, 720, 0, 0, 3, 3 }, - { 1280, 720, 1, 0, 1, 6, 1, 1280, 720, 0, 0, 3, 3 }, - { 1920, 1080, 1, 1, 1, 4, 1, 1920, 1080, 0, 0, 3, 3 }, - { 1920, 1080, 1, 1, 1, 3, 1, 1920, 1080, 0, 0, 3, 3 }, - { 1920, 1080, 1, 0, 1, 7, 1, 1920, 1080, 0, 0, 3, 3 }, - { 1920, 1080, 1, 0, 1, 6, 1, 1920, 1080, 0, 0, 3, 3 }, - { 2048, 1080, 0, 0, 1, 2, 1, 2048, 1080, 0, 0, 4, 4 }, - { 4096, 2160, 0, 0, 1, 2, 1, 4096, 2160, 0, 0, 4, 4 }, - - { 3840, 2160, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 }, - { 3840, 2160, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 }, - { 7680, 4320, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 }, - { 7680, 4320, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 }, -}; - -static const AVRational dirac_preset_aspect_ratios[] = { - {1, 1}, - {10, 11}, - {12, 11}, - {40, 33}, - {16, 11}, - {4, 3}, -}; - -static const AVRational dirac_frame_rate[] = { - {15000, 1001}, - {25, 2}, -}; - -static const struct { - uint8_t bitdepth; - enum AVColorRange color_range; -} pixel_range_presets[] = { - {8, AVCOL_RANGE_JPEG}, - {8, AVCOL_RANGE_MPEG}, - {10, AVCOL_RANGE_MPEG}, - {12, AVCOL_RANGE_MPEG}, -}; - -static const enum AVColorPrimaries dirac_primaries[] = { - AVCOL_PRI_BT709, - AVCOL_PRI_SMPTE170M, - AVCOL_PRI_BT470BG, -}; - -static const struct { - enum AVColorPrimaries color_primaries; - enum AVColorSpace colorspace; - enum AVColorTransferCharacteristic color_trc; -} dirac_color_presets[] = { - { AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_BT709 }, - { AVCOL_PRI_SMPTE170M, AVCOL_SPC_BT470BG, AVCOL_TRC_BT709 }, - { AVCOL_PRI_BT470BG, AVCOL_SPC_BT470BG, AVCOL_TRC_BT709 }, - { AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_BT709 }, - { AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_UNSPECIFIED /* DCinema */ }, -}; - -static const enum PixelFormat dirac_pix_fmt[2][3] = { - { PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P }, - { PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P }, -}; - -static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, - dirac_source_params *source) -{ - AVRational frame_rate = (AVRational){0,0}; - unsigned luma_depth = 8, luma_offset = 16; - int idx; - - if (get_bits1(gb)) { - source->width = svq3_get_ue_golomb(gb); - source->height = svq3_get_ue_golomb(gb); - } - - // chroma subsampling - if (get_bits1(gb)) - source->chroma_format = svq3_get_ue_golomb(gb); - if (source->chroma_format > 2) { - av_log(avctx, AV_LOG_ERROR, "Unknown chroma format %d\n", - source->chroma_format); - return -1; - } - - if (get_bits1(gb)) - source->interlaced = svq3_get_ue_golomb(gb); - if (source->interlaced > 1) - return -1; - - // frame rate - if (get_bits1(gb)) { - source->frame_rate_index = svq3_get_ue_golomb(gb); - - if (source->frame_rate_index > 10) - return -1; - - if (!source->frame_rate_index) { - frame_rate.num = svq3_get_ue_golomb(gb); - frame_rate.den = svq3_get_ue_golomb(gb); - } - } - if (source->frame_rate_index > 0) { - if (source->frame_rate_index <= 8) - frame_rate = ff_frame_rate_tab[source->frame_rate_index]; - else - frame_rate = dirac_frame_rate[source->frame_rate_index-9]; - } - av_reduce(&avctx->time_base.num, &avctx->time_base.den, - frame_rate.den, frame_rate.num, 1<<30); - - // aspect ratio - if (get_bits1(gb)) { - source->aspect_ratio_index = svq3_get_ue_golomb(gb); - - if (source->aspect_ratio_index > 6) - return -1; - - if (!source->aspect_ratio_index) { - avctx->sample_aspect_ratio.num = svq3_get_ue_golomb(gb); - avctx->sample_aspect_ratio.den = svq3_get_ue_golomb(gb); - } - } - if (source->aspect_ratio_index > 0) - avctx->sample_aspect_ratio = - dirac_preset_aspect_ratios[source->aspect_ratio_index-1]; - - if (get_bits1(gb)) { - source->clean_width = svq3_get_ue_golomb(gb); - source->clean_height = svq3_get_ue_golomb(gb); - source->clean_left_offset = svq3_get_ue_golomb(gb); - source->clean_right_offset = svq3_get_ue_golomb(gb); - } - - // Override signal range. - if (get_bits1(gb)) { - source->pixel_range_index = svq3_get_ue_golomb(gb); - - if (source->pixel_range_index > 4) - return -1; - - // This assumes either fullrange or MPEG levels only - if (!source->pixel_range_index) { - luma_offset = svq3_get_ue_golomb(gb); - luma_depth = av_log2(svq3_get_ue_golomb(gb))+1; - svq3_get_ue_golomb(gb); // chroma offset - svq3_get_ue_golomb(gb); // chroma excursion - - avctx->color_range = luma_offset ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; - } - } - if (source->pixel_range_index > 0) { - idx = source->pixel_range_index-1; - luma_depth = pixel_range_presets[idx].bitdepth; - avctx->color_range = pixel_range_presets[idx].color_range; - } - - if (luma_depth > 8) - av_log(avctx, AV_LOG_WARNING, "Bitdepth greater than 8"); - - avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format]; - - // color spec - if (get_bits1(gb)) { - idx = source->color_spec_index = svq3_get_ue_golomb(gb); - - if (source->color_spec_index > 4) - return -1; - - avctx->color_primaries = dirac_color_presets[idx].color_primaries; - avctx->colorspace = dirac_color_presets[idx].colorspace; - avctx->color_trc = dirac_color_presets[idx].color_trc; - - if (!source->color_spec_index) { - if (get_bits1(gb)) { - idx = svq3_get_ue_golomb(gb); - if (idx < 3) - avctx->color_primaries = dirac_primaries[idx]; - } - - if (get_bits1(gb)) { - idx = svq3_get_ue_golomb(gb); - if (!idx) - avctx->colorspace = AVCOL_SPC_BT709; - else if (idx == 1) - avctx->colorspace = AVCOL_SPC_BT470BG; - } - - if (get_bits1(gb) && !svq3_get_ue_golomb(gb)) - avctx->color_trc = AVCOL_TRC_BT709; - } - } else { - idx = source->color_spec_index; - avctx->color_primaries = dirac_color_presets[idx].color_primaries; - avctx->colorspace = dirac_color_presets[idx].colorspace; - avctx->color_trc = dirac_color_presets[idx].color_trc; - } - - return 0; -} - -int ff_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, - dirac_source_params *source) -{ - unsigned version_major, version_minor; - unsigned video_format, picture_coding_mode; - - version_major = svq3_get_ue_golomb(gb); - version_minor = svq3_get_ue_golomb(gb); - avctx->profile = svq3_get_ue_golomb(gb); - avctx->level = svq3_get_ue_golomb(gb); - video_format = svq3_get_ue_golomb(gb); - - if (version_major < 2) - av_log(avctx, AV_LOG_WARNING, "Stream is old and may not work\n"); - else if (version_major > 2) - av_log(avctx, AV_LOG_WARNING, "Stream may have unhandled features\n"); - - if (video_format > 20) - return -1; - - // Fill in defaults for the source parameters. - *source = dirac_source_parameters_defaults[video_format]; - - // Override the defaults. - if (parse_source_parameters(avctx, gb, source)) - return -1; - - if (avcodec_check_dimensions(avctx, source->width, source->height)) - return -1; - - avcodec_set_dimensions(avctx, source->width, source->height); - - // currently only used to signal field coding - picture_coding_mode = svq3_get_ue_golomb(gb); - if (picture_coding_mode != 0) { - av_log(avctx, AV_LOG_ERROR, "Unsupported picture coding mode %d", - picture_coding_mode); - return -1; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/dirac.h b/tizen/distrib/ffmpeg/libavcodec/dirac.h deleted file mode 100644 index 09c5581..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dirac.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2007 Marco Gerards - * Copyright (C) 2009 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DIRAC_H -#define AVCODEC_DIRAC_H - -/** - * @file - * Interfaces to Dirac Decoder/Encoder - * @author Marco Gerards - */ - -#include "avcodec.h" -#include "get_bits.h" - -typedef struct { - unsigned width; - unsigned height; - uint8_t chroma_format; ///< 0: 444 1: 422 2: 420 - - uint8_t interlaced; - uint8_t top_field_first; - - uint8_t frame_rate_index; ///< index into dirac_frame_rate[] - uint8_t aspect_ratio_index; ///< index into dirac_aspect_ratio[] - - uint16_t clean_width; - uint16_t clean_height; - uint16_t clean_left_offset; - uint16_t clean_right_offset; - - uint8_t pixel_range_index; ///< index into dirac_pixel_range_presets[] - uint8_t color_spec_index; ///< index into dirac_color_spec_presets[] -} dirac_source_params; - -int ff_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, - dirac_source_params *source); - -#endif /* AVCODEC_DIRAC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dirac_parser.c b/tizen/distrib/ffmpeg/libavcodec/dirac_parser.c deleted file mode 100644 index c82f0e6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dirac_parser.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Dirac parser - * - * Copyright (c) 2007-2008 Marco Gerards - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Dirac Parser - * @author Marco Gerards - */ - -#include "libavutil/intreadwrite.h" -#include "parser.h" - -#define DIRAC_PARSE_INFO_PREFIX 0x42424344 - -/** - * Finds the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame or -1 - */ -typedef struct DiracParseContext { - int state; - int is_synced; - int sync_offset; - int header_bytes_needed; - int overread_index; - int buffer_size; - int index; - uint8_t *buffer; - int dirac_unit_size; - uint8_t *dirac_unit; -} DiracParseContext; - -static int find_frame_end(DiracParseContext *pc, - const uint8_t *buf, int buf_size) -{ - uint32_t state = pc->state; - int i = 0; - - if (!pc->is_synced) { - for (i = 0; i < buf_size; i++) { - state = (state << 8) | buf[i]; - if (state == DIRAC_PARSE_INFO_PREFIX) { - state = -1; - pc->is_synced = 1; - pc->header_bytes_needed = 9; - pc->sync_offset = i; - break; - } - } - } - - if (pc->is_synced) { - pc->sync_offset = 0; - for (; i < buf_size; i++) { - if (state == DIRAC_PARSE_INFO_PREFIX) { - if ((buf_size-i) >= pc->header_bytes_needed) { - pc->state = -1; - return i + pc->header_bytes_needed; - } else { - pc->header_bytes_needed = 9-(buf_size-i); - break; - } - } else - state = (state << 8) | buf[i]; - } - } - pc->state = state; - return -1; -} - -typedef struct DiracParseUnit -{ - int next_pu_offset; - int prev_pu_offset; - uint8_t pu_type; -} DiracParseUnit; - -static int unpack_parse_unit(DiracParseUnit *pu, DiracParseContext *pc, - int offset) -{ - uint8_t *start = pc->buffer + offset; - uint8_t *end = pc->buffer + pc->index; - if (start < pc->buffer || (start+13 > end)) - return 0; - pu->pu_type = start[4]; - - pu->next_pu_offset = AV_RB32(start+5); - pu->prev_pu_offset = AV_RB32(start+9); - - if (pu->pu_type == 0x10 && pu->next_pu_offset == 0) - pu->next_pu_offset = 13; - - return 1; -} - -static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, - int next, const uint8_t **buf, int *buf_size) -{ - int parse_timing_info = (s->pts == AV_NOPTS_VALUE && - s->dts == AV_NOPTS_VALUE); - DiracParseContext *pc = s->priv_data; - - if (pc->overread_index) { - memcpy(pc->buffer, pc->buffer + pc->overread_index, - pc->index - pc->overread_index); - pc->index -= pc->overread_index; - pc->overread_index = 0; - if (*buf_size == 0 && pc->buffer[4] == 0x10) { - *buf = pc->buffer; - *buf_size = pc->index; - return 0; - } - } - - if ( next == -1) { - /* Found a possible frame start but not a frame end */ - void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, - pc->index + (*buf_size - - pc->sync_offset)); - pc->buffer = new_buffer; - memcpy(pc->buffer+pc->index, (*buf + pc->sync_offset), - *buf_size - pc->sync_offset); - pc->index += *buf_size - pc->sync_offset; - return -1; - } else { - /* Found a possible frame start and a possible frame end */ - DiracParseUnit pu1, pu; - void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, - pc->index + next); - pc->buffer = new_buffer; - memcpy(pc->buffer + pc->index, *buf, next); - pc->index += next; - - /* Need to check if we have a valid Parse Unit. We can't go by the - * sync pattern 'BBCD' alone because arithmetic coding of the residual - * and motion data can cause the pattern triggering a false start of - * frame. So check if the previous parse offset of the next parse unit - * is equal to the next parse offset of the current parse unit then - * we can be pretty sure that we have a valid parse unit */ - if (!unpack_parse_unit(&pu1, pc, pc->index - 13) || - !unpack_parse_unit(&pu, pc, pc->index - 13 - pu1.prev_pu_offset) || - pu.next_pu_offset != pu1.prev_pu_offset) { - pc->index -= 9; - *buf_size = next-9; - pc->header_bytes_needed = 9; - return -1; - } - - /* All non-frame data must be accompanied by frame data. This is to - * ensure that pts is set correctly. So if the current parse unit is - * not frame data, wait for frame data to come along */ - - pc->dirac_unit = pc->buffer + pc->index - 13 - - pu1.prev_pu_offset - pc->dirac_unit_size; - - pc->dirac_unit_size += pu.next_pu_offset; - - if ((pu.pu_type&0x08) != 0x08) { - pc->header_bytes_needed = 9; - *buf_size = next; - return -1; - } - - /* Get the picture number to set the pts and dts*/ - if (parse_timing_info) { - uint8_t *cur_pu = pc->buffer + - pc->index - 13 - pu1.prev_pu_offset; - int pts = AV_RB32(cur_pu + 13); - if (s->last_pts == 0 && s->last_dts == 0) - s->dts = pts - 1; - else - s->dts = s->last_dts+1; - s->pts = pts; - if (!avctx->has_b_frames && (cur_pu[4] & 0x03)) - avctx->has_b_frames = 1; - } - if (avctx->has_b_frames && s->pts == s->dts) - s->pict_type = FF_B_TYPE; - - /* Finally have a complete Dirac data unit */ - *buf = pc->dirac_unit; - *buf_size = pc->dirac_unit_size; - - pc->dirac_unit_size = 0; - pc->overread_index = pc->index-13; - pc->header_bytes_needed = 9; - } - return next; -} - -static int dirac_parse(AVCodecParserContext *s, AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - DiracParseContext *pc = s->priv_data; - int next; - - *poutbuf = NULL; - *poutbuf_size = 0; - - if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { - next = buf_size; - *poutbuf = buf; - *poutbuf_size = buf_size; - /* Assume that data has been packetized into an encapsulation unit. */ - } else { - next = find_frame_end(pc, buf, buf_size); - if (!pc->is_synced && next == -1) { - /* No frame start found yet. So throw away the entire buffer. */ - return buf_size; - } - - if (dirac_combine_frame(s, avctx, next, &buf, &buf_size) < 0) { - return buf_size; - } - } - - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -static void dirac_parse_close(AVCodecParserContext *s) -{ - DiracParseContext *pc = s->priv_data; - - if (pc->buffer_size > 0) - av_free(pc->buffer); -} - -AVCodecParser dirac_parser = { - { CODEC_ID_DIRAC }, - sizeof(DiracParseContext), - NULL, - dirac_parse, - dirac_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dnxhd_parser.c b/tizen/distrib/ffmpeg/libavcodec/dnxhd_parser.c deleted file mode 100644 index 6149a2d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dnxhd_parser.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * DNxHD/VC-3 parser - * Copyright (c) 2008 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * DNxHD/VC-3 parser - */ - -#include "parser.h" - -#define DNXHD_HEADER_PREFIX 0x0000028001 - -static int dnxhd_find_frame_end(ParseContext *pc, - const uint8_t *buf, int buf_size) -{ - uint64_t state = pc->state64; - int pic_found = pc->frame_start_found; - int i = 0; - - if (!pic_found) { - for (i = 0; i < buf_size; i++) { - state = (state<<8) | buf[i]; - if ((state & 0xffffffffffLL) == DNXHD_HEADER_PREFIX) { - i++; - pic_found = 1; - break; - } - } - } - - if (pic_found) { - if (!buf_size) /* EOF considered as end of frame */ - return 0; - for (; i < buf_size; i++) { - state = (state<<8) | buf[i]; - if ((state & 0xffffffffffLL) == DNXHD_HEADER_PREFIX) { - pc->frame_start_found = 0; - pc->state64 = -1; - return i-4; - } - } - } - pc->frame_start_found = pic_found; - pc->state64 = state; - return END_NOT_FOUND; -} - -static int dnxhd_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { - next = buf_size; - } else { - next = dnxhd_find_frame_end(pc, buf, buf_size); - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser dnxhd_parser = { - { CODEC_ID_DNXHD }, - sizeof(ParseContext), - NULL, - dnxhd_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dnxhddata.c b/tizen/distrib/ffmpeg/libavcodec/dnxhddata.c deleted file mode 100644 index 2625a9b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dnxhddata.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * VC3/DNxHD data. - * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "dnxhddata.h" - -static const uint8_t dnxhd_1237_luma_weight[] = { - 0, 32, 33, 34, 34, 36, 37, 36, - 36, 37, 38, 38, 38, 39, 41, 44, - 43, 41, 40, 41, 46, 49, 47, 46, - 47, 49, 51, 54, 60, 62, 59, 55, - 54, 56, 58, 61, 65, 66, 64, 63, - 66, 73, 78, 79, 80, 79, 78, 78, - 82, 87, 89, 90, 93, 95, 96, 97, - 97, 100, 104, 102, 98, 98, 99, 99, -}; - -static const uint8_t dnxhd_1237_chroma_weight[] = { - 0, 32, 36, 39, 39, 38, 39, 41, - 45, 51, 57, 58, 53, 48, 47, 51, - 55, 58, 66, 75, 81, 83, 82, 78, - 73, 72, 74, 77, 83, 85, 83, 82, - 89, 99, 96, 90, 94, 97, 99, 105, - 109, 105, 95, 89, 92, 95, 94, 93, - 92, 88, 89, 90, 93, 95, 96, 97, - 97, 100, 104, 102, 98, 98, 99, 99, -}; - -static const uint8_t dnxhd_1238_luma_weight[] = { - 0, 32, 32, 33, 34, 33, 33, 33, - 33, 33, 33, 33, 33, 35, 37, 37, - 36, 36, 35, 36, 38, 38, 36, 35, - 36, 37, 38, 41, 42, 41, 39, 38, - 38, 38, 39, 41, 42, 41, 39, 39, - 40, 41, 43, 44, 44, 44, 44, 44, - 45, 47, 47, 47, 49, 50, 51, 51, - 51, 53, 55, 57, 58, 59, 57, 57, -}; - -static const uint8_t dnxhd_1238_chroma_weight[] = { - 0, 32, 35, 35, 35, 34, 34, 35, - 39, 43, 45, 45, 41, 39, 40, 41, - 42, 44, 48, 55, 59, 63, 65, 59, - 53, 52, 52, 55, 61, 62, 58, 58, - 63, 66, 66, 65, 70, 74, 70, 66, - 65, 68, 75, 77, 74, 74, 77, 76, - 73, 73, 73, 73, 76, 80, 89, 90, - 82, 77, 80, 86, 84, 82, 82, 82, -}; - -static const uint8_t dnxhd_1241_luma_weight[] = { - 0, 32, 33, 34, 34, 35, 36, 37, - 36, 37, 38, 38, 38, 39, 39, 40, - 40, 38, 38, 39, 38, 37, 39, 41, - 41, 42, 43, 45, 45, 46, 47, 46, - 45, 43, 39, 37, 37, 40, 44, 45, - 45, 46, 46, 46, 47, 47, 46, 44, - 42, 43, 45, 47, 48, 49, 50, 49, - 48, 46, 47, 48, 48, 49, 49, 49, -}; - -static const uint8_t dnxhd_1241_chroma_weight[] = { - 0, 32, 36, 38, 37, 37, 40, 41, - 40, 40, 42, 42, 41, 41, 41, 41, - 42, 43, 44, 44, 45, 46, 46, 45, - 44, 45, 45, 45, 45, 46, 47, 46, - 45, 44, 42, 41, 43, 45, 45, 47, - 48, 48, 48, 46, 47, 47, 46, 47, - 46, 45, 45, 47, 48, 49, 50, 49, - 48, 46, 48, 49, 48, 49, 49, 49, -}; - -static const uint8_t dnxhd_1242_luma_weight[] = { - 0, 32, 33, 33, 34, 35, 36, 35, - 33, 33, 35, 36, 37, 37, 38, 37, - 37, 37, 36, 37, 37, 37, 38, 39, - 37, 36, 37, 40, 42, 45, 46, 44, - 41, 42, 44, 45, 47, 49, 50, 48, - 46, 48, 49, 50, 52, 52, 50, 49, - 47, 48, 50, 50, 51, 51, 50, 49, - 49, 51, 52, 51, 49, 47, 47, 47, -}; - -static const uint8_t dnxhd_1242_chroma_weight[] = { - 0, 32, 37, 42, 45, 45, 45, 44, - 38, 37, 40, 42, 44, 49, 51, 47, - 41, 40, 43, 44, 46, 48, 51, 54, - 51, 47, 47, 45, 47, 50, 51, 49, - 46, 47, 49, 47, 50, 55, 55, 51, - 48, 49, 51, 51, 52, 52, 54, 54, - 49, 49, 52, 53, 54, 54, 53, 53, - 55, 59, 63, 62, 60, 60, 60, 60, - }; - -static const uint8_t dnxhd_1243_luma_weight[] = { - 0, 32, 32, 33, 33, 35, 35, 35, - 35, 35, 35, 35, 34, 35, 38, 40, - 39, 37, 37, 37, 36, 35, 36, 38, - 40, 41, 42, 44, 45, 44, 42, 41, - 40, 38, 36, 36, 37, 38, 40, 43, - 44, 45, 45, 45, 45, 45, 45, 41, - 39, 41, 45, 47, 47, 48, 48, 48, - 46, 44, 45, 47, 47, 48, 47, 47, -}; - -static const uint8_t dnxhd_1243_chroma_weight[] = { - 0, 32, 36, 37, 36, 37, 39, 39, - 41, 43, 43, 42, 41, 41, 41, 42, - 43, 43, 43, 44, 44, 44, 46, 47, - 46, 45, 45, 45, 45, 46, 44, 44, - 45, 44, 42, 41, 43, 46, 45, 44, - 45, 45, 45, 46, 46, 46, 45, 44, - 45, 44, 45, 47, 47, 48, 49, 48, - 46, 45, 46, 47, 47, 48, 47, 47, -}; - -static const uint8_t dnxhd_1251_luma_weight[] = { - 0, 32, 32, 34, 34, 34, 34, 35, - 35, 35, 36, 37, 36, 36, 35, 36, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 39, 41, 44, 43, 41, 40, - 40, 40, 40, 39, 40, 41, 40, 39, - 40, 43, 46, 46, 44, 44, 44, 42, - 41, 43, 46, 48, 50, 55, 58, 53, - 48, 50, 55, 58, 61, 62, 62, 62, -}; - -static const uint8_t dnxhd_1251_chroma_weight[] = { - 0, 32, 35, 36, 36, 35, 36, 39, - 41, 43, 45, 44, 41, 39, 40, 42, - 43, 43, 45, 48, 48, 48, 50, 50, - 50, 51, 51, 51, 51, 52, 53, 54, - 51, 49, 51, 52, 52, 56, 57, 55, - 54, 54, 55, 56, 55, 58, 58, 58, - 60, 61, 62, 62, 59, 57, 58, 58, - 61, 59, 59, 59, 61, 62, 62, 62, -}; - -static const uint8_t dnxhd_1252_luma_weight[] = { - 0, 32, 34, 35, 36, 36, 36, 37, - 36, 37, 39, 40, 41, 40, 40, 40, - 41, 41, 42, 41, 41, 43, 44, 44, - 45, 46, 48, 55, 60, 57, 52, 50, - 49, 49, 52, 52, 53, 55, 58, 62, - 65, 73, 82, 82, 80, 78, 73, 68, - 71, 82, 90, 90, 88, 87, 90, 95, - 100, 107, 103, 97, 95, 93, 99, 99, -}; -static const uint8_t dnxhd_1252_chroma_weight[] = { - 0, 32, 35, 36, 37, 37, 38, 40, - 42, 46, 49, 50, 50, 49, 49, 53, - 56, 56, 57, 58, 60, 62, 64, 65, - 63, 64, 64, 65, 66, 65, 67, 71, - 72, 74, 74, 74, 74, 77, 81, 78, - 72, 73, 82, 85, 89, 88, 84, 80, - 90, 100, 90, 90, 88, 87, 90, 95, - 114, 128, 125, 129, 134, 125, 116, 116, -}; - -static const uint8_t dnxhd_1237_dc_codes[12] = { - 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, -}; - -static const uint8_t dnxhd_1237_dc_bits[12] = { - 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, -}; - -static const uint16_t dnxhd_1237_ac_codes[257] = { - 0, 1, 4, 5, 12, 26, 27, 56, 57, 58, 59, 120, 121, 244, 245, 246, 247, 248, 498, 499, 500, 501, 502, 1006, 1007, 1008, 1009, 1010, 1011, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 32668, 32669, 32670, 32671, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 65370, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, -}; - -static const uint8_t dnxhd_1237_ac_bits[257] = { - 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 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, -}; - -static const uint8_t dnxhd_1237_ac_level[257] = { - 1, 1, 2, 0, 3, 4, 2, 5, 6, 7, 3, 8, 9, 10, 11, 12, 4, 5, 13, 14, 15, 16, 6, 17, 18, 19, 20, 21, 7, 22, 23, 24, 25, 26, 27, 8, 9, 28, 29, 30, 31, 32, 33, 34, 10, 11, 12, 35, 36, 37, 38, 39, 40, 41, 13, 14, 15, 16, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 17, 18, 19, 20, 21, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 1, 22, 23, 24, 25, 26, 27, 62, 63, 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, 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, 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, -}; - -static const uint8_t dnxhd_1237_ac_run_flag[257] = { - 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint8_t dnxhd_1237_ac_index_flag[257] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint16_t dnxhd_1237_run_codes[62] = { - 0, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 58, 118, 119, 240, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, -}; - -static const uint8_t dnxhd_1237_run_bits[62] = { - 1, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -}; - -static const uint8_t dnxhd_1237_run[62] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 53, 57, 58, 59, 60, 61, 62, 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, 54, 55, 56, -}; - -static const uint8_t dnxhd_1238_dc_codes[12] = { - 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, -}; - -static const uint8_t dnxhd_1238_dc_bits[12] = { - 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, -}; - -static const uint16_t dnxhd_1238_ac_codes[257] = { - 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 499, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, -}; - -static const uint8_t dnxhd_1238_ac_bits[257] = { - 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 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, -}; - -static const uint8_t dnxhd_1238_ac_level[257] = { - 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 7, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 10, 11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25, 26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 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, -}; /* 0 is EOB */ - -static const uint8_t dnxhd_1238_ac_run_flag[257] = { - 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 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, 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, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint8_t dnxhd_1238_ac_index_flag[257] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint16_t dnxhd_1238_run_codes[62] = { - 0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, -}; - -static const uint8_t dnxhd_1238_run_bits[62] = { - 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -}; - -static const uint8_t dnxhd_1238_run[62] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 21, 17, 18, 19, 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, -}; - -static const uint8_t dnxhd_1241_dc_codes[14] = { - 10, 62, 11, 12, 13, 0, 1, 2, 3, 4, 14, 30, 126, 127, -}; - -static const uint8_t dnxhd_1241_dc_bits[14] = { - 4, 6, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 7, 7, -}; -static const uint16_t dnxhd_1241_ac_codes[257] = { - 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, -}; - -static const uint8_t dnxhd_1241_ac_bits[257] = { - 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 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, -}; - -static const uint8_t dnxhd_1241_ac_level[257] = { - 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 38, 10, 11, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, 13, 14, 15, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1, 16, 17, 18, 19, 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 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, 25, 26, 27, 28, 29, 30, 31, 32, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 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, -}; - -static const uint8_t dnxhd_1241_ac_run_flag[257] = { - 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint8_t dnxhd_1241_ac_index_flag[257] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint8_t dnxhd_1241_run[62] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 17, 19, 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, -}; - -static const uint8_t dnxhd_1251_dc_codes[12] = { - 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, -}; -static const uint8_t dnxhd_1251_dc_bits[12] = { - 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, -}; -static const uint16_t dnxhd_1251_ac_codes[257] = { - 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 8134, 8135, 8136, 8137, 8138, 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 16339, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 32709, 32710, 32711, 32712, 32713, 32714, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, -}; -static const uint8_t dnxhd_1251_ac_bits[257] = { - 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -}; -static const uint8_t dnxhd_1251_ac_level[257] = { - 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 22, 23, 24, 25, 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 9, 10, 11, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 12, 13, 14, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 20, 21, 22, 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, 23, 24, 25, 26, 27, 28, 59, 60, 61, 62, 63, 64, 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, 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, -}; -static const uint8_t dnxhd_1251_ac_run_flag[257] = { - 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 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, 0, 0, 0, 0, 0, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; -static const uint8_t dnxhd_1251_ac_index_flag[257] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 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, 1, 1, 1, 1, 1, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; -static const uint16_t dnxhd_1251_run_codes[62] = { - 0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, -}; -static const uint8_t dnxhd_1251_run_bits[62] = { - 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -}; -static const uint8_t dnxhd_1251_run[62] = { - 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, -}; - -static const uint8_t dnxhd_1252_dc_codes[12] = { - 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, -}; -static const uint8_t dnxhd_1252_dc_bits[12] = { - 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, -}; -static const uint16_t dnxhd_1252_ac_codes[257] = { - 0, 1, 4, 10, 11, 12, 26, 27, 56, 57, 58, 118, 119, 120, 242, 243, 244, 245, 246, 247, 496, 497, 498, 499, 500, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, -}; -static const uint8_t dnxhd_1252_ac_bits[257] = { - 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 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, -}; -static const uint8_t dnxhd_1252_ac_level[257] = { - 1, 1, 2, 3, 2, 0, 4, 5, 6, 7, 3, 8, 9, 10, 11, 12, 13, 14, 4, 5, 15, 16, 17, 18, 6, 19, 20, 21, 22, 23, 24, 7, 8, 25, 26, 27, 28, 29, 30, 31, 32, 9, 10, 33, 34, 35, 36, 37, 38, 39, 40, 41, 11, 12, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 14, 15, 16, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 17, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 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, 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, 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, -}; -static const uint8_t dnxhd_1252_ac_run_flag[257] = { - 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; -static const uint8_t dnxhd_1252_ac_index_flag[257] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 CIDEntry ff_dnxhd_cid_table[] = { - { 1237, 1920, 1080, 0, 606208, 606208, 4, 8, - dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight, - dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, - dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, - dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, - dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, - { 115, 120, 145, 240, 290 } }, - { 1238, 1920, 1080, 0, 917504, 917504, 4, 8, - dnxhd_1238_luma_weight, dnxhd_1238_chroma_weight, - dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, - dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, - dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, - dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run, - { 175, 185, 220, 365, 440 } }, - { 1241, 1920, 1080, 1, 917504, 458752, 6, 10, - dnxhd_1241_luma_weight, dnxhd_1241_chroma_weight, - dnxhd_1241_dc_codes, dnxhd_1241_dc_bits, - dnxhd_1241_ac_codes, dnxhd_1241_ac_bits, dnxhd_1241_ac_level, - dnxhd_1241_ac_run_flag, dnxhd_1241_ac_index_flag, - dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1241_run, - { 185, 220 } }, - { 1242, 1920, 1080, 1, 606208, 303104, 4, 8, - dnxhd_1242_luma_weight, dnxhd_1242_chroma_weight, - dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, - dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, - dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, - dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, - { 120, 145 } }, - { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, - dnxhd_1243_luma_weight, dnxhd_1243_chroma_weight, - dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, - dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, - dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, - dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run, - { 185, 220 } }, - { 1251, 1280, 720, 0, 458752, 458752, 4, 8, - dnxhd_1251_luma_weight, dnxhd_1251_chroma_weight, - dnxhd_1251_dc_codes, dnxhd_1251_dc_bits, - dnxhd_1251_ac_codes, dnxhd_1251_ac_bits, dnxhd_1251_ac_level, - dnxhd_1251_ac_run_flag, dnxhd_1251_ac_index_flag, - dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run, - { 90, 110, 175, 220 } }, - { 1252, 1280, 720, 0, 303104, 303104, 4, 8, - dnxhd_1252_luma_weight, dnxhd_1252_chroma_weight, - dnxhd_1252_dc_codes, dnxhd_1252_dc_bits, - dnxhd_1252_ac_codes, dnxhd_1252_ac_bits, dnxhd_1252_ac_level, - dnxhd_1252_ac_run_flag, dnxhd_1252_ac_index_flag, - dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run, - { 60, 75, 115, 145 } }, - { 1253, 1920, 1080, 0, 188416, 188416, 4, 8, - dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight, - dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, - dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, - dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, - dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, - { 36, 45, 75, 90 } }, -}; - -int ff_dnxhd_get_cid_table(int cid) -{ - int i; - for (i = 0; i < FF_ARRAY_ELEMS(ff_dnxhd_cid_table); i++) - if (ff_dnxhd_cid_table[i].cid == cid) - return i; - return -1; -} - -int ff_dnxhd_find_cid(AVCodecContext *avctx) -{ - int i, j; - int mbs = avctx->bit_rate/1000000; - if (!mbs) - return 0; - for (i = 0; i < FF_ARRAY_ELEMS(ff_dnxhd_cid_table); i++) { - const CIDEntry *cid = &ff_dnxhd_cid_table[i]; - if (cid->width == avctx->width && cid->height == avctx->height && - cid->interlaced == !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT) && - cid->bit_depth == 8) { // until 10 bit is supported - for (j = 0; j < sizeof(cid->bit_rates); j++) { - if (cid->bit_rates[j] == mbs) - return cid->cid; - } - } - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/dnxhddata.h b/tizen/distrib/ffmpeg/libavcodec/dnxhddata.h deleted file mode 100644 index 32c77db..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dnxhddata.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * VC3/DNxHD decoder. - * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DNXHDDATA_H -#define AVCODEC_DNXHDDATA_H - -#include -#include "avcodec.h" - -typedef struct { - int cid; - unsigned int width, height; - int interlaced; - unsigned int frame_size; - unsigned int coding_unit_size; - int index_bits; - int bit_depth; - const uint8_t *luma_weight, *chroma_weight; - const uint8_t *dc_codes, *dc_bits; - const uint16_t *ac_codes; - const uint8_t *ac_bits, *ac_level; - const uint8_t *ac_run_flag, *ac_index_flag; - const uint16_t *run_codes; - const uint8_t *run_bits, *run; - int bit_rates[5]; ///< Helpher to choose variants, rounded to nearest 5Mb/s -} CIDEntry; - -extern const CIDEntry ff_dnxhd_cid_table[]; - -int ff_dnxhd_get_cid_table(int cid); -int ff_dnxhd_find_cid(AVCodecContext *avctx); - -#endif /* AVCODEC_DNXHDDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dnxhddec.c b/tizen/distrib/ffmpeg/libavcodec/dnxhddec.c deleted file mode 100644 index 8b7c343..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dnxhddec.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * VC3/DNxHD decoder. - * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//#define TRACE -//#define DEBUG - -#include "avcodec.h" -#include "get_bits.h" -#include "dnxhddata.h" -#include "dsputil.h" - -typedef struct { - AVCodecContext *avctx; - AVFrame picture; - GetBitContext gb; - int cid; ///< compression id - unsigned int width, height; - unsigned int mb_width, mb_height; - uint32_t mb_scan_index[68]; /* max for 1080p */ - int cur_field; ///< current interlaced field - VLC ac_vlc, dc_vlc, run_vlc; - int last_dc[3]; - DSPContext dsp; - DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64]; - ScanTable scantable; - const CIDEntry *cid_table; -} DNXHDContext; - -#define DNXHD_VLC_BITS 9 -#define DNXHD_DC_VLC_BITS 7 - -static av_cold int dnxhd_decode_init(AVCodecContext *avctx) -{ - DNXHDContext *ctx = avctx->priv_data; - - ctx->avctx = avctx; - dsputil_init(&ctx->dsp, avctx); - avctx->coded_frame = &ctx->picture; - ctx->picture.type = FF_I_TYPE; - return 0; -} - -static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) -{ - if (!ctx->cid_table) { - int index; - - if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { - av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid); - return -1; - } - ctx->cid_table = &ff_dnxhd_cid_table[index]; - init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, - ctx->cid_table->ac_bits, 1, 1, - ctx->cid_table->ac_codes, 2, 2, 0); - init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->cid_table->bit_depth+4, - ctx->cid_table->dc_bits, 1, 1, - ctx->cid_table->dc_codes, 1, 1, 0); - init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62, - ctx->cid_table->run_bits, 1, 1, - ctx->cid_table->run_codes, 2, 2, 0); - - ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); - } - return 0; -} - -static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field) -{ - static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; - int i; - - if (buf_size < 0x280) - return -1; - - if (memcmp(buf, header_prefix, 5)) { - av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); - return -1; - } - if (buf[5] & 2) { /* interlaced */ - ctx->cur_field = buf[5] & 1; - ctx->picture.interlaced_frame = 1; - ctx->picture.top_field_first = first_field ^ ctx->cur_field; - av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); - } - - ctx->height = AV_RB16(buf + 0x18); - ctx->width = AV_RB16(buf + 0x1a); - - dprintf(ctx->avctx, "width %d, heigth %d\n", ctx->width, ctx->height); - - if (buf[0x21] & 0x40) { - av_log(ctx->avctx, AV_LOG_ERROR, "10 bit per component\n"); - return -1; - } - - ctx->cid = AV_RB32(buf + 0x28); - dprintf(ctx->avctx, "compression id %d\n", ctx->cid); - - if (dnxhd_init_vlc(ctx, ctx->cid) < 0) - return -1; - - if (buf_size < ctx->cid_table->coding_unit_size) { - av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size\n"); - return -1; - } - - ctx->mb_width = ctx->width>>4; - ctx->mb_height = buf[0x16d]; - - dprintf(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height); - - if ((ctx->height+15)>>4 == ctx->mb_height && ctx->picture.interlaced_frame) - ctx->height <<= 1; - - if (ctx->mb_height > 68 || - (ctx->mb_height<picture.interlaced_frame) > (ctx->height+15)>>4) { - av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big: %d\n", ctx->mb_height); - return -1; - } - - for (i = 0; i < ctx->mb_height; i++) { - ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i<<2)); - dprintf(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]); - if (buf_size < ctx->mb_scan_index[i] + 0x280) { - av_log(ctx->avctx, AV_LOG_ERROR, "invalid mb scan index\n"); - return -1; - } - } - - return 0; -} - -static int dnxhd_decode_dc(DNXHDContext *ctx) -{ - int len; - - len = get_vlc2(&ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1); - return len ? get_xbits(&ctx->gb, len) : 0; -} - -static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int qscale) -{ - int i, j, index, index2; - int level, component, sign; - const uint8_t *weigth_matrix; - - if (n&2) { - component = 1 + (n&1); - weigth_matrix = ctx->cid_table->chroma_weight; - } else { - component = 0; - weigth_matrix = ctx->cid_table->luma_weight; - } - - ctx->last_dc[component] += dnxhd_decode_dc(ctx); - block[0] = ctx->last_dc[component]; - //av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]); - for (i = 1; ; i++) { - index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2); - //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index); - level = ctx->cid_table->ac_level[index]; - if (!level) { /* EOB */ - //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n"); - return; - } - sign = get_sbits(&ctx->gb, 1); - - if (ctx->cid_table->ac_index_flag[index]) { - level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6; - } - - if (ctx->cid_table->ac_run_flag[index]) { - index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2); - i += ctx->cid_table->run[index2]; - } - - if (i > 63) { - av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i); - return; - } - - j = ctx->scantable.permutated[i]; - //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j); - //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]); - level = (2*level+1) * qscale * weigth_matrix[i]; - if (ctx->cid_table->bit_depth == 10) { - if (weigth_matrix[i] != 8) - level += 8; - level >>= 4; - } else { - if (weigth_matrix[i] != 32) - level += 32; - level >>= 6; - } - //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level); - block[j] = (level^sign) - sign; - } -} - -static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) -{ - int dct_linesize_luma = ctx->picture.linesize[0]; - int dct_linesize_chroma = ctx->picture.linesize[1]; - uint8_t *dest_y, *dest_u, *dest_v; - int dct_offset; - int qscale, i; - - qscale = get_bits(&ctx->gb, 11); - skip_bits1(&ctx->gb); - //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); - - for (i = 0; i < 8; i++) { - ctx->dsp.clear_block(ctx->blocks[i]); - dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); - } - - if (ctx->picture.interlaced_frame) { - dct_linesize_luma <<= 1; - dct_linesize_chroma <<= 1; - } - - dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); - dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); - dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); - - if (ctx->cur_field) { - dest_y += ctx->picture.linesize[0]; - dest_u += ctx->picture.linesize[1]; - dest_v += ctx->picture.linesize[2]; - } - - dct_offset = dct_linesize_luma << 3; - ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); - ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); - ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]); - ctx->dsp.idct_put(dest_y + dct_offset + 8, dct_linesize_luma, ctx->blocks[5]); - - if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { - dct_offset = dct_linesize_chroma << 3; - ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); - ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); - ctx->dsp.idct_put(dest_u + dct_offset, dct_linesize_chroma, ctx->blocks[6]); - ctx->dsp.idct_put(dest_v + dct_offset, dct_linesize_chroma, ctx->blocks[7]); - } - - return 0; -} - -static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size) -{ - int x, y; - for (y = 0; y < ctx->mb_height; y++) { - ctx->last_dc[0] = - ctx->last_dc[1] = - ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1) - init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3); - for (x = 0; x < ctx->mb_width; x++) { - //START_TIMER; - dnxhd_decode_macroblock(ctx, x, y); - //STOP_TIMER("decode macroblock"); - } - } - return 0; -} - -static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - DNXHDContext *ctx = avctx->priv_data; - AVFrame *picture = data; - int first_field = 1; - - dprintf(avctx, "frame size %d\n", buf_size); - - decode_coding_unit: - if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) - return -1; - - if ((avctx->width || avctx->height) && - (ctx->width != avctx->width || ctx->height != avctx->height)) { - av_log(avctx, AV_LOG_WARNING, "frame size changed: %dx%d -> %dx%d\n", - avctx->width, avctx->height, ctx->width, ctx->height); - first_field = 1; - } - - avctx->pix_fmt = PIX_FMT_YUV422P; - if (avcodec_check_dimensions(avctx, ctx->width, ctx->height)) - return -1; - avcodec_set_dimensions(avctx, ctx->width, ctx->height); - - if (first_field) { - if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); - if (avctx->get_buffer(avctx, &ctx->picture) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - } - - dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); - - if (first_field && ctx->picture.interlaced_frame) { - buf += ctx->cid_table->coding_unit_size; - buf_size -= ctx->cid_table->coding_unit_size; - first_field = 0; - goto decode_coding_unit; - } - - *picture = ctx->picture; - *data_size = sizeof(AVPicture); - return buf_size; -} - -static av_cold int dnxhd_decode_close(AVCodecContext *avctx) -{ - DNXHDContext *ctx = avctx->priv_data; - - if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); - free_vlc(&ctx->ac_vlc); - free_vlc(&ctx->dc_vlc); - free_vlc(&ctx->run_vlc); - return 0; -} - -AVCodec dnxhd_decoder = { - "dnxhd", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DNXHD, - sizeof(DNXHDContext), - dnxhd_decode_init, - NULL, - dnxhd_decode_close, - dnxhd_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dnxhdenc.c b/tizen/distrib/ffmpeg/libavcodec/dnxhdenc.c deleted file mode 100644 index 6b08929..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dnxhdenc.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * VC3/DNxHD encoder - * Copyright (c) 2007 Baptiste Coudurier - * - * VC-3 encoder funded by the British Broadcasting Corporation - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//#define DEBUG -#define RC_VARIANCE 1 // use variance or ssd for fast rc - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "dnxhdenc.h" - -int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); - -#define LAMBDA_FRAC_BITS 10 - -static av_always_inline void dnxhd_get_pixels_8x4(DCTELEM *restrict block, const uint8_t *pixels, int line_size) -{ - int i; - for (i = 0; i < 4; 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; - } - memcpy(block , block- 8, sizeof(*block)*8); - memcpy(block+ 8, block-16, sizeof(*block)*8); - memcpy(block+16, block-24, sizeof(*block)*8); - memcpy(block+24, block-32, sizeof(*block)*8); -} - -static int dnxhd_init_vlc(DNXHDEncContext *ctx) -{ - int i, j, level, run; - int max_level = 1<<(ctx->cid_table->bit_depth+2); - - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_codes, max_level*4*sizeof(*ctx->vlc_codes), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->vlc_bits , max_level*4*sizeof(*ctx->vlc_bits ), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes, 63*2 , fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits , 63 , fail); - - ctx->vlc_codes += max_level*2; - ctx->vlc_bits += max_level*2; - for (level = -max_level; level < max_level; level++) { - for (run = 0; run < 2; run++) { - int index = (level<<1)|run; - int sign, offset = 0, alevel = level; - - MASK_ABS(sign, alevel); - if (alevel > 64) { - offset = (alevel-1)>>6; - alevel -= offset<<6; - } - for (j = 0; j < 257; j++) { - if (ctx->cid_table->ac_level[j] == alevel && - (!offset || (ctx->cid_table->ac_index_flag[j] && offset)) && - (!run || (ctx->cid_table->ac_run_flag [j] && run))) { - assert(!ctx->vlc_codes[index]); - if (alevel) { - ctx->vlc_codes[index] = (ctx->cid_table->ac_codes[j]<<1)|(sign&1); - ctx->vlc_bits [index] = ctx->cid_table->ac_bits[j]+1; - } else { - ctx->vlc_codes[index] = ctx->cid_table->ac_codes[j]; - ctx->vlc_bits [index] = ctx->cid_table->ac_bits [j]; - } - break; - } - } - assert(!alevel || j < 257); - if (offset) { - ctx->vlc_codes[index] = (ctx->vlc_codes[index]<cid_table->index_bits)|offset; - ctx->vlc_bits [index]+= ctx->cid_table->index_bits; - } - } - } - for (i = 0; i < 62; i++) { - int run = ctx->cid_table->run[i]; - assert(run < 63); - ctx->run_codes[run] = ctx->cid_table->run_codes[i]; - ctx->run_bits [run] = ctx->cid_table->run_bits[i]; - } - return 0; - fail: - return -1; -} - -static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) -{ - // init first elem to 1 to avoid div by 0 in convert_matrix - uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t* - int qscale, i; - - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int) , fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int) , fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t), fail); - - for (i = 1; i < 64; i++) { - int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; - weight_matrix[j] = ctx->cid_table->luma_weight[i]; - } - ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix, - ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); - for (i = 1; i < 64; i++) { - int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; - weight_matrix[j] = ctx->cid_table->chroma_weight[i]; - } - ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix, - ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); - for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { - for (i = 0; i < 64; i++) { - ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2; - ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2; - ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2; - } - } - return 0; - fail: - return -1; -} - -static int dnxhd_init_rc(DNXHDEncContext *ctx) -{ - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail); - if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry), fail); - - ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4) * 8; - ctx->qscale = 1; - ctx->lambda = 2<priv_data; - int i, index; - - ctx->cid = ff_dnxhd_find_cid(avctx); - if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) { - av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n"); - return -1; - } - av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid); - - index = ff_dnxhd_get_cid_table(ctx->cid); - ctx->cid_table = &ff_dnxhd_cid_table[index]; - - ctx->m.avctx = avctx; - ctx->m.mb_intra = 1; - ctx->m.h263_aic = 1; - - ctx->get_pixels_8x4_sym = dnxhd_get_pixels_8x4; - - dsputil_init(&ctx->m.dsp, avctx); - ff_dct_common_init(&ctx->m); -#if HAVE_MMX - ff_dnxhd_init_mmx(ctx); -#endif - if (!ctx->m.dct_quantize) - ctx->m.dct_quantize = dct_quantize_c; - - ctx->m.mb_height = (avctx->height + 15) / 16; - ctx->m.mb_width = (avctx->width + 15) / 16; - - if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { - ctx->interlaced = 1; - ctx->m.mb_height /= 2; - } - - ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width; - - if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) - ctx->m.intra_quant_bias = avctx->intra_quant_bias; - if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias - return -1; - - if (dnxhd_init_vlc(ctx) < 0) - return -1; - if (dnxhd_init_rc(ctx) < 0) - return -1; - - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs, ctx->m.mb_height*sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t) , fail); - - ctx->frame.key_frame = 1; - ctx->frame.pict_type = FF_I_TYPE; - ctx->m.avctx->coded_frame = &ctx->frame; - - if (avctx->thread_count > MAX_THREADS) { - av_log(avctx, AV_LOG_ERROR, "too many threads\n"); - return -1; - } - - ctx->thread[0] = ctx; - for (i = 1; i < avctx->thread_count; i++) { - ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); - memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); - } - - return 0; - fail: //for FF_ALLOCZ_OR_GOTO - return -1; -} - -static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) -{ - DNXHDEncContext *ctx = avctx->priv_data; - const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 }; - - memset(buf, 0, 640); - - memcpy(buf, header_prefix, 5); - buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01; - buf[6] = 0x80; // crc flag off - buf[7] = 0xa0; // reserved - AV_WB16(buf + 0x18, avctx->height); // ALPF - AV_WB16(buf + 0x1a, avctx->width); // SPL - AV_WB16(buf + 0x1d, avctx->height); // NAL - - buf[0x21] = 0x38; // FIXME 8 bit per comp - buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2); - AV_WB32(buf + 0x28, ctx->cid); // CID - buf[0x2c] = ctx->interlaced ? 0 : 0x80; - - buf[0x5f] = 0x01; // UDL - - buf[0x167] = 0x02; // reserved - AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS - buf[0x16d] = ctx->m.mb_height; // Ns - buf[0x16f] = 0x10; // reserved - - ctx->msip = buf + 0x170; - return 0; -} - -static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff) -{ - int nbits; - if (diff < 0) { - nbits = av_log2_16bit(-2*diff); - diff--; - } else { - nbits = av_log2_16bit(2*diff); - } - put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits, - (ctx->cid_table->dc_codes[nbits]<m.last_dc[n]); - ctx->m.last_dc[n] = block[0]; - - for (i = 1; i <= last_index; i++) { - j = ctx->m.intra_scantable.permutated[i]; - slevel = block[j]; - if (slevel) { - int run_level = i - last_non_zero - 1; - int rlevel = (slevel<<1)|!!run_level; - put_bits(&ctx->m.pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]); - if (run_level) - put_bits(&ctx->m.pb, ctx->run_bits[run_level], ctx->run_codes[run_level]); - last_non_zero = i; - } - } - put_bits(&ctx->m.pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB -} - -static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index) -{ - const uint8_t *weight_matrix; - int level; - int i; - - weight_matrix = (n&2) ? ctx->cid_table->chroma_weight : ctx->cid_table->luma_weight; - - for (i = 1; i <= last_index; i++) { - int j = ctx->m.intra_scantable.permutated[i]; - level = block[j]; - if (level) { - if (level < 0) { - level = (1-2*level) * qscale * weight_matrix[i]; - if (weight_matrix[i] != 32) - level += 32; - level >>= 6; - level = -level; - } else { - level = (2*level+1) * qscale * weight_matrix[i]; - if (weight_matrix[i] != 32) - level += 32; - level >>= 6; - } - block[j] = level; - } - } -} - -static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block) -{ - int score = 0; - int i; - for (i = 0; i < 64; i++) - score += (block[i]-qblock[i])*(block[i]-qblock[i]); - return score; -} - -static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index) -{ - int last_non_zero = 0; - int bits = 0; - int i, j, level; - for (i = 1; i <= last_index; i++) { - j = ctx->m.intra_scantable.permutated[i]; - level = block[j]; - if (level) { - int run_level = i - last_non_zero - 1; - bits += ctx->vlc_bits[(level<<1)|!!run_level]+ctx->run_bits[run_level]; - last_non_zero = i; - } - } - return bits; -} - -static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) -{ - const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << 4); - const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3); - const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3); - DSPContext *dsp = &ctx->m.dsp; - - dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize); - dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize); - dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize); - dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize); - - if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) { - if (ctx->interlaced) { - ctx->get_pixels_8x4_sym(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize); - ctx->get_pixels_8x4_sym(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize); - ctx->get_pixels_8x4_sym(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize); - ctx->get_pixels_8x4_sym(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize); - } else { - dsp->clear_block(ctx->blocks[4]); dsp->clear_block(ctx->blocks[5]); - dsp->clear_block(ctx->blocks[6]); dsp->clear_block(ctx->blocks[7]); - } - } else { - dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize); - dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize); - dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize); - dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize); - } -} - -static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i) -{ - if (i&2) { - ctx->m.q_intra_matrix16 = ctx->qmatrix_c16; - ctx->m.q_intra_matrix = ctx->qmatrix_c; - return 1 + (i&1); - } else { - ctx->m.q_intra_matrix16 = ctx->qmatrix_l16; - ctx->m.q_intra_matrix = ctx->qmatrix_l; - return 0; - } -} - -static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) -{ - DNXHDEncContext *ctx = avctx->priv_data; - int mb_y = jobnr, mb_x; - int qscale = ctx->qscale; - LOCAL_ALIGNED_16(DCTELEM, block, [64]); - ctx = ctx->thread[threadnr]; - - ctx->m.last_dc[0] = - ctx->m.last_dc[1] = - ctx->m.last_dc[2] = 1024; - - for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { - unsigned mb = mb_y * ctx->m.mb_width + mb_x; - int ssd = 0; - int ac_bits = 0; - int dc_bits = 0; - int i; - - dnxhd_get_blocks(ctx, mb_x, mb_y); - - for (i = 0; i < 8; i++) { - DCTELEM *src_block = ctx->blocks[i]; - int overflow, nbits, diff, last_index; - int n = dnxhd_switch_matrix(ctx, i); - - memcpy(block, src_block, 64*sizeof(*block)); - last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow); - ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index); - - diff = block[0] - ctx->m.last_dc[n]; - if (diff < 0) nbits = av_log2_16bit(-2*diff); - else nbits = av_log2_16bit( 2*diff); - dc_bits += ctx->cid_table->dc_bits[nbits] + nbits; - - ctx->m.last_dc[n] = block[0]; - - if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) { - dnxhd_unquantize_c(ctx, block, i, qscale, last_index); - ctx->m.dsp.idct(block); - ssd += dnxhd_ssd_block(block, src_block); - } - } - ctx->mb_rc[qscale][mb].ssd = ssd; - ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->vlc_bits[0]; - } - return 0; -} - -static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) -{ - DNXHDEncContext *ctx = avctx->priv_data; - int mb_y = jobnr, mb_x; - ctx = ctx->thread[threadnr]; - init_put_bits(&ctx->m.pb, (uint8_t *)arg + 640 + ctx->slice_offs[jobnr], ctx->slice_size[jobnr]); - - ctx->m.last_dc[0] = - ctx->m.last_dc[1] = - ctx->m.last_dc[2] = 1024; - for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { - unsigned mb = mb_y * ctx->m.mb_width + mb_x; - int qscale = ctx->mb_qscale[mb]; - int i; - - put_bits(&ctx->m.pb, 12, qscale<<1); - - dnxhd_get_blocks(ctx, mb_x, mb_y); - - for (i = 0; i < 8; i++) { - DCTELEM *block = ctx->blocks[i]; - int last_index, overflow; - int n = dnxhd_switch_matrix(ctx, i); - last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow); - //START_TIMER; - dnxhd_encode_block(ctx, block, last_index, n); - //STOP_TIMER("encode_block"); - } - } - if (put_bits_count(&ctx->m.pb)&31) - put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0); - flush_put_bits(&ctx->m.pb); - return 0; -} - -static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx) -{ - int mb_y, mb_x; - int offset = 0; - for (mb_y = 0; mb_y < ctx->m.mb_height; mb_y++) { - int thread_size; - ctx->slice_offs[mb_y] = offset; - ctx->slice_size[mb_y] = 0; - for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { - unsigned mb = mb_y * ctx->m.mb_width + mb_x; - ctx->slice_size[mb_y] += ctx->mb_bits[mb]; - } - ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31; - ctx->slice_size[mb_y] >>= 3; - thread_size = ctx->slice_size[mb_y]; - offset += thread_size; - } -} - -static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) -{ - DNXHDEncContext *ctx = avctx->priv_data; - int mb_y = jobnr, mb_x; - ctx = ctx->thread[threadnr]; - for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { - unsigned mb = mb_y * ctx->m.mb_width + mb_x; - uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize) + (mb_x<<4); - int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); - int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8; - ctx->mb_cmp[mb].value = varc; - ctx->mb_cmp[mb].mb = mb; - } - return 0; -} - -static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) -{ - int lambda, up_step, down_step; - int last_lower = INT_MAX, last_higher = 0; - int x, y, q; - - for (q = 1; q < avctx->qmax; q++) { - ctx->qscale = q; - avctx->execute2(avctx, dnxhd_calc_bits_thread, NULL, NULL, ctx->m.mb_height); - } - up_step = down_step = 2<lambda; - - for (;;) { - int bits = 0; - int end = 0; - if (lambda == last_higher) { - lambda++; - end = 1; // need to set final qscales/bits - } - for (y = 0; y < ctx->m.mb_height; y++) { - for (x = 0; x < ctx->m.mb_width; x++) { - unsigned min = UINT_MAX; - int qscale = 1; - int mb = y*ctx->m.mb_width+x; - for (q = 1; q < avctx->qmax; q++) { - unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<mb_rc[qscale][mb].bits; - ctx->mb_qscale[mb] = qscale; - ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits; - } - bits = (bits+31)&~31; // padding - if (bits > ctx->frame_bits) - break; - } - //dprintf(ctx->m.avctx, "lambda %d, up %u, down %u, bits %d, frame %d\n", - // lambda, last_higher, last_lower, bits, ctx->frame_bits); - if (end) { - if (bits > ctx->frame_bits) - return -1; - break; - } - if (bits < ctx->frame_bits) { - last_lower = FFMIN(lambda, last_lower); - if (last_higher != 0) - lambda = (lambda+last_higher)>>1; - else - lambda -= down_step; - down_step *= 5; // XXX tune ? - up_step = 1<>1; - else if ((int64_t)lambda + up_step > INT_MAX) - return -1; - else - lambda += up_step; - up_step = FFMIN((int64_t)up_step*5, INT_MAX); - down_step = 1<m.avctx, "out lambda %d\n", lambda); - ctx->lambda = lambda; - return 0; -} - -static int dnxhd_find_qscale(DNXHDEncContext *ctx) -{ - int bits = 0; - int up_step = 1; - int down_step = 1; - int last_higher = 0; - int last_lower = INT_MAX; - int qscale; - int x, y; - - qscale = ctx->qscale; - for (;;) { - bits = 0; - ctx->qscale = qscale; - // XXX avoid recalculating bits - ctx->m.avctx->execute2(ctx->m.avctx, dnxhd_calc_bits_thread, NULL, NULL, ctx->m.mb_height); - for (y = 0; y < ctx->m.mb_height; y++) { - for (x = 0; x < ctx->m.mb_width; x++) - bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits; - bits = (bits+31)&~31; // padding - if (bits > ctx->frame_bits) - break; - } - //dprintf(ctx->m.avctx, "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n", - // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower); - if (bits < ctx->frame_bits) { - if (qscale == 1) - return 1; - if (last_higher == qscale - 1) { - qscale = last_higher; - break; - } - last_lower = FFMIN(qscale, last_lower); - if (last_higher != 0) - qscale = (qscale+last_higher)>>1; - else - qscale -= down_step++; - if (qscale < 1) - qscale = 1; - up_step = 1; - } else { - if (last_lower == qscale + 1) - break; - last_higher = FFMAX(qscale, last_higher); - if (last_lower != INT_MAX) - qscale = (qscale+last_lower)>>1; - else - qscale += up_step++; - down_step = 1; - if (qscale >= ctx->m.avctx->qmax) - return -1; - } - } - //dprintf(ctx->m.avctx, "out qscale %d\n", qscale); - ctx->qscale = qscale; - return 0; -} - -#define BUCKET_BITS 8 -#define RADIX_PASSES 4 -#define NBUCKETS (1 << BUCKET_BITS) - -static inline int get_bucket(int value, int shift) -{ - value >>= shift; - value &= NBUCKETS - 1; - return NBUCKETS - 1 - value; -} - -static void radix_count(const RCCMPEntry *data, int size, int buckets[RADIX_PASSES][NBUCKETS]) -{ - int i, j; - memset(buckets, 0, sizeof(buckets[0][0]) * RADIX_PASSES * NBUCKETS); - for (i = 0; i < size; i++) { - int v = data[i].value; - for (j = 0; j < RADIX_PASSES; j++) { - buckets[j][get_bucket(v, 0)]++; - v >>= BUCKET_BITS; - } - assert(!v); - } - for (j = 0; j < RADIX_PASSES; j++) { - int offset = size; - for (i = NBUCKETS - 1; i >= 0; i--) - buckets[j][i] = offset -= buckets[j][i]; - assert(!buckets[j][0]); - } -} - -static void radix_sort_pass(RCCMPEntry *dst, const RCCMPEntry *data, int size, int buckets[NBUCKETS], int pass) -{ - int shift = pass * BUCKET_BITS; - int i; - for (i = 0; i < size; i++) { - int v = get_bucket(data[i].value, shift); - int pos = buckets[v]++; - dst[pos] = data[i]; - } -} - -static void radix_sort(RCCMPEntry *data, int size) -{ - int buckets[RADIX_PASSES][NBUCKETS]; - RCCMPEntry *tmp = av_malloc(sizeof(*tmp) * size); - radix_count(data, size, buckets); - radix_sort_pass(tmp, data, size, buckets[0], 0); - radix_sort_pass(data, tmp, size, buckets[1], 1); - if (buckets[2][NBUCKETS - 1] || buckets[3][NBUCKETS - 1]) { - radix_sort_pass(tmp, data, size, buckets[2], 2); - radix_sort_pass(data, tmp, size, buckets[3], 3); - } - av_free(tmp); -} - -static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx) -{ - int max_bits = 0; - int ret, x, y; - if ((ret = dnxhd_find_qscale(ctx)) < 0) - return -1; - for (y = 0; y < ctx->m.mb_height; y++) { - for (x = 0; x < ctx->m.mb_width; x++) { - int mb = y*ctx->m.mb_width+x; - int delta_bits; - ctx->mb_qscale[mb] = ctx->qscale; - ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits; - max_bits += ctx->mb_rc[ctx->qscale][mb].bits; - if (!RC_VARIANCE) { - delta_bits = ctx->mb_rc[ctx->qscale][mb].bits-ctx->mb_rc[ctx->qscale+1][mb].bits; - ctx->mb_cmp[mb].mb = mb; - ctx->mb_cmp[mb].value = delta_bits ? - ((ctx->mb_rc[ctx->qscale][mb].ssd-ctx->mb_rc[ctx->qscale+1][mb].ssd)*100)/delta_bits - : INT_MIN; //avoid increasing qscale - } - } - max_bits += 31; //worst padding - } - if (!ret) { - if (RC_VARIANCE) - avctx->execute2(avctx, dnxhd_mb_var_thread, NULL, NULL, ctx->m.mb_height); - radix_sort(ctx->mb_cmp, ctx->m.mb_num); - for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) { - int mb = ctx->mb_cmp[x].mb; - max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits; - ctx->mb_qscale[mb] = ctx->qscale+1; - ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits; - } - } - return 0; -} - -static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) -{ - int i; - - for (i = 0; i < 3; i++) { - ctx->frame.data[i] = frame->data[i]; - ctx->frame.linesize[i] = frame->linesize[i]; - } - - for (i = 0; i < ctx->m.avctx->thread_count; i++) { - ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<interlaced; - ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<interlaced; - ctx->thread[i]->dct_y_offset = ctx->m.linesize *8; - ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8; - } - - ctx->frame.interlaced_frame = frame->interlaced_frame; - ctx->cur_field = frame->interlaced_frame && !frame->top_field_first; -} - -static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) -{ - DNXHDEncContext *ctx = avctx->priv_data; - int first_field = 1; - int offset, i, ret; - - if (buf_size < ctx->cid_table->frame_size) { - av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n"); - return -1; - } - - dnxhd_load_picture(ctx, data); - - encode_coding_unit: - for (i = 0; i < 3; i++) { - ctx->src[i] = ctx->frame.data[i]; - if (ctx->interlaced && ctx->cur_field) - ctx->src[i] += ctx->frame.linesize[i]; - } - - dnxhd_write_header(avctx, buf); - - if (avctx->mb_decision == FF_MB_DECISION_RD) - ret = dnxhd_encode_rdo(avctx, ctx); - else - ret = dnxhd_encode_fast(avctx, ctx); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, - "picture could not fit ratecontrol constraints, increase qmax\n"); - return -1; - } - - dnxhd_setup_threads_slices(ctx); - - offset = 0; - for (i = 0; i < ctx->m.mb_height; i++) { - AV_WB32(ctx->msip + i * 4, offset); - offset += ctx->slice_size[i]; - assert(!(ctx->slice_size[i] & 3)); - } - - avctx->execute2(avctx, dnxhd_encode_thread, buf, NULL, ctx->m.mb_height); - - assert(640 + offset + 4 <= ctx->cid_table->coding_unit_size); - memset(buf + 640 + offset, 0, ctx->cid_table->coding_unit_size - 4 - offset - 640); - - AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF - - if (ctx->interlaced && first_field) { - first_field = 0; - ctx->cur_field ^= 1; - buf += ctx->cid_table->coding_unit_size; - buf_size -= ctx->cid_table->coding_unit_size; - goto encode_coding_unit; - } - - ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA; - - return ctx->cid_table->frame_size; -} - -static int dnxhd_encode_end(AVCodecContext *avctx) -{ - DNXHDEncContext *ctx = avctx->priv_data; - int max_level = 1<<(ctx->cid_table->bit_depth+2); - int i; - - av_free(ctx->vlc_codes-max_level*2); - av_free(ctx->vlc_bits -max_level*2); - av_freep(&ctx->run_codes); - av_freep(&ctx->run_bits); - - av_freep(&ctx->mb_bits); - av_freep(&ctx->mb_qscale); - av_freep(&ctx->mb_rc); - av_freep(&ctx->mb_cmp); - av_freep(&ctx->slice_size); - av_freep(&ctx->slice_offs); - - av_freep(&ctx->qmatrix_c); - av_freep(&ctx->qmatrix_l); - av_freep(&ctx->qmatrix_c16); - av_freep(&ctx->qmatrix_l16); - - for (i = 1; i < avctx->thread_count; i++) - av_freep(&ctx->thread[i]); - - return 0; -} - -AVCodec dnxhd_encoder = { - "dnxhd", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DNXHD, - sizeof(DNXHDEncContext), - dnxhd_encode_init, - dnxhd_encode_picture, - dnxhd_encode_end, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dnxhdenc.h b/tizen/distrib/ffmpeg/libavcodec/dnxhdenc.h deleted file mode 100644 index eaf33d5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dnxhdenc.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * VC3/DNxHD encoder structure definitions and prototypes - * Copyright (c) 2007 Baptiste Coudurier - * - * VC-3 encoder funded by the British Broadcasting Corporation - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DNXHDENC_H -#define AVCODEC_DNXHDENC_H - -#include -#include "libavcodec/mpegvideo.h" -#include "libavcodec/dnxhddata.h" - -typedef struct { - uint16_t mb; - int value; -} RCCMPEntry; - -typedef struct { - int ssd; - int bits; -} RCEntry; - -typedef struct DNXHDEncContext { - MpegEncContext m; ///< Used for quantization dsp functions - - AVFrame frame; - int cid; - const CIDEntry *cid_table; - uint8_t *msip; ///< Macroblock Scan Indexes Payload - uint32_t *slice_size; - uint32_t *slice_offs; - - struct DNXHDEncContext *thread[MAX_THREADS]; - - unsigned dct_y_offset; - unsigned dct_uv_offset; - int interlaced; - int cur_field; - - DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64]; - - int (*qmatrix_c) [64]; - int (*qmatrix_l) [64]; - uint16_t (*qmatrix_l16)[2][64]; - uint16_t (*qmatrix_c16)[2][64]; - - unsigned frame_bits; - uint8_t *src[3]; - - uint32_t *vlc_codes; - uint8_t *vlc_bits; - uint16_t *run_codes; - uint8_t *run_bits; - - /** Rate control */ - unsigned slice_bits; - unsigned qscale; - unsigned lambda; - - unsigned thread_size; - - uint16_t *mb_bits; - uint8_t *mb_qscale; - - RCCMPEntry *mb_cmp; - RCEntry (*mb_rc)[8160]; - - void (*get_pixels_8x4_sym)(DCTELEM */*align 16*/, const uint8_t *, int); -} DNXHDEncContext; - -void ff_dnxhd_init_mmx(DNXHDEncContext *ctx); - -#endif /* AVCODEC_DNXHDENC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dpcm.c b/tizen/distrib/ffmpeg/libavcodec/dpcm.c deleted file mode 100644 index 7c53516..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dpcm.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Assorted DPCM codecs - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file: dpcm.c - * Assorted DPCM (differential pulse code modulation) audio codecs - * by Mike Melanson (melanson@pcisys.net) - * Xan DPCM decoder by Mario Brito (mbrito@student.dei.uc.pt) - * for more information on the specific data formats, visit: - * http://www.pcisys.net/~melanson/codecs/simpleaudio.html - * SOL DPCMs implemented by Konstantin Shishkov - * - * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files - * found in the Wing Commander IV computer game. These AVI files contain - * WAVEFORMAT headers which report the audio format as 0x01: raw PCM. - * Clearly incorrect. To detect Xan DPCM, you will probably have to - * special-case your AVI demuxer to use Xan DPCM if the file uses 'Xxan' - * (Xan video) for its video codec. Alternately, such AVI files also contain - * the fourcc 'Axan' in the 'auds' chunk of the AVI header. - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct DPCMContext { - int channels; - short roq_square_array[256]; - long sample[2];//for SOL_DPCM - const int *sol_table;//for SOL_DPCM -} DPCMContext; - -#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; - -static const 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 const int sol_table_old[16] = - { 0x0, 0x1, 0x2 , 0x3, 0x6, 0xA, 0xF, 0x15, - -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0}; - -static const int sol_table_new[16] = - { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, - 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15}; - -static const 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 av_cold 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; - } - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -static int dpcm_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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; - - // almost every DPCM variant expands one byte of data into two - if(*data_size/2 < buf_size) - return -1; - - switch(avctx->codec->id) { - - case CODEC_ID_ROQ_DPCM: - if (s->channels == 1) - predictor[0] = AV_RL16(&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]]; - predictor[channel_number] = av_clip_int16(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] = AV_RL16(&buf[in]); - in += 2; - SE_16BIT(predictor[0]) - output_samples[out++] = predictor[0]; - if (s->channels == 2) { - predictor[1] = AV_RL16(&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++]]; - predictor[channel_number] = av_clip_int16(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] = AV_RL16(&buf[in]); - in += 2; - SE_16BIT(predictor[0]); - if (s->channels == 2) { - predictor[1] = AV_RL16(&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; - - predictor[channel_number] = av_clip_int16(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) { - if(*data_size/4 < buf_size) - return -1; - 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]; - s->sample[channel_number] = av_clip_int16(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; -} - -#define DPCM_DECODER(id, name, long_name_) \ -AVCodec name ## _decoder = { \ - #name, \ - AVMEDIA_TYPE_AUDIO, \ - id, \ - sizeof(DPCMContext), \ - dpcm_decode_init, \ - NULL, \ - NULL, \ - dpcm_decode_frame, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ -}; - -DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay"); -DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ"); -DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol"); -DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan"); diff --git a/tizen/distrib/ffmpeg/libavcodec/dpx.c b/tizen/distrib/ffmpeg/libavcodec/dpx.c deleted file mode 100644 index 94a9181..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dpx.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * DPX (.dpx) image decoder - * Copyright (c) 2009 Jimmy Christensen - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "bytestream.h" -#include "avcodec.h" - -typedef struct DPXContext { - AVFrame picture; -} DPXContext; - - -static unsigned int read32(const uint8_t **ptr, int is_big) -{ - unsigned int temp; - if (is_big) { - temp = AV_RB32(*ptr); - } else { - temp = AV_RL32(*ptr); - } - *ptr += 4; - return temp; -} - -static inline unsigned make_16bit(unsigned value) -{ - // mask away invalid bits - value &= 0xFFC0; - // correctly expand to 16 bits - return value + (value >> 10); -} - -static int decode_frame(AVCodecContext *avctx, - void *data, - int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - DPXContext *const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *const p = &s->picture; - uint8_t *ptr; - - int magic_num, offset, endian; - int x, y; - int w, h, stride, bits_per_color, descriptor, elements, target_packet_size, source_packet_size; - - unsigned int rgbBuffer; - - magic_num = AV_RB32(buf); - buf += 4; - - /* Check if the files "magic number" is "SDPX" which means it uses - * big-endian or XPDS which is for little-endian files */ - if (magic_num == AV_RL32("SDPX")) { - endian = 0; - } else if (magic_num == AV_RB32("SDPX")) { - endian = 1; - } else { - av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n"); - return -1; - } - - offset = read32(&buf, endian); - // Need to end in 0x304 offset from start of file - buf = avpkt->data + 0x304; - w = read32(&buf, endian); - h = read32(&buf, endian); - - // Need to end in 0x320 to read the descriptor - buf += 20; - descriptor = buf[0]; - - // Need to end in 0x323 to read the bits per color - buf += 3; - avctx->bits_per_raw_sample = - bits_per_color = buf[0]; - - switch (descriptor) { - case 51: // RGBA - elements = 4; - break; - case 50: // RGB - elements = 3; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported descriptor %d\n", descriptor); - return -1; - } - - switch (bits_per_color) { - case 8: - if (elements == 4) { - avctx->pix_fmt = PIX_FMT_RGBA; - } else { - avctx->pix_fmt = PIX_FMT_RGB24; - } - source_packet_size = elements; - target_packet_size = elements; - break; - case 10: - avctx->pix_fmt = PIX_FMT_RGB48; - target_packet_size = 6; - source_packet_size = elements * 2; - break; - case 12: - case 16: - if (endian) { - avctx->pix_fmt = PIX_FMT_RGB48BE; - } else { - avctx->pix_fmt = PIX_FMT_RGB48LE; - } - target_packet_size = 6; - source_packet_size = elements * 2; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color); - return -1; - } - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - if (avcodec_check_dimensions(avctx, w, h)) - return -1; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - if (avctx->get_buffer(avctx, p) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - // Move pointer to offset from start of file - buf = avpkt->data + offset; - - ptr = p->data[0]; - stride = p->linesize[0]; - - switch (bits_per_color) { - case 10: - for (x = 0; x < avctx->height; x++) { - uint16_t *dst = (uint16_t*)ptr; - for (y = 0; y < avctx->width; y++) { - rgbBuffer = read32(&buf, endian); - // Read out the 10-bit colors and convert to 16-bit - *dst++ = make_16bit(rgbBuffer >> 16); - *dst++ = make_16bit(rgbBuffer >> 6); - *dst++ = make_16bit(rgbBuffer << 4); - } - ptr += stride; - } - break; - case 8: - case 12: // Treat 12-bit as 16-bit - case 16: - if (source_packet_size == target_packet_size) { - for (x = 0; x < avctx->height; x++) { - memcpy(ptr, buf, target_packet_size*avctx->width); - ptr += stride; - buf += source_packet_size*avctx->width; - } - } else { - for (x = 0; x < avctx->height; x++) { - uint8_t *dst = ptr; - for (y = 0; y < avctx->width; y++) { - memcpy(dst, buf, target_packet_size); - dst += target_packet_size; - buf += source_packet_size; - } - ptr += stride; - } - } - break; - } - - *picture = s->picture; - *data_size = sizeof(AVPicture); - - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - DPXContext *s = avctx->priv_data; - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - DPXContext *s = avctx->priv_data; - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec dpx_decoder = { - "dpx", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DPX, - sizeof(DPXContext), - decode_init, - NULL, - decode_end, - decode_frame, - 0, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("DPX image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dsicinav.c b/tizen/distrib/ffmpeg/libavcodec/dsicinav.c deleted file mode 100644 index 895b623..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dsicinav.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Delphine Software International CIN Audio/Video Decoders - * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Delphine Software International CIN audio/video decoders - */ - -#include "avcodec.h" -#include "bytestream.h" - - -typedef enum CinVideoBitmapIndex { - CIN_CUR_BMP = 0, /* current */ - CIN_PRE_BMP = 1, /* previous */ - CIN_INT_BMP = 2 /* intermediate */ -} CinVideoBitmapIndex; - -typedef struct CinVideoContext { - AVCodecContext *avctx; - AVFrame frame; - unsigned int bitmap_size; - uint32_t palette[256]; - uint8_t *bitmap_table[3]; -} CinVideoContext; - -typedef struct CinAudioContext { - AVCodecContext *avctx; - int initial_decode_frame; - int delta; -} CinAudioContext; - - -/* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */ -static const int16_t cinaudio_delta16_table[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -30210, -27853, -25680, -23677, -21829, - -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398, - -10508, -9689, -8933, -8236, -7593, -7001, -6455, -5951, - -5487, -5059, -4664, -4300, -3964, -3655, -3370, -3107, - -2865, -2641, -2435, -2245, -2070, -1908, -1759, -1622, - -1495, -1379, -1271, -1172, -1080, -996, -918, -847, - -781, -720, -663, -612, -564, -520, -479, -442, - -407, -376, -346, -319, -294, -271, -250, -230, - -212, -196, -181, -166, -153, -141, -130, -120, - -111, -102, -94, -87, -80, -74, -68, -62, - -58, -53, -49, -45, -41, -38, -35, -32, - -30, -27, -25, -23, -21, -20, -18, -17, - -15, -14, -13, -12, -11, -10, -9, -8, - -7, -6, -5, -4, -3, -2, -1, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 17, 18, 20, 21, 23, 25, 27, 30, - 32, 35, 38, 41, 45, 49, 53, 58, - 62, 68, 74, 80, 87, 94, 102, 111, - 120, 130, 141, 153, 166, 181, 196, 212, - 230, 250, 271, 294, 319, 346, 376, 407, - 442, 479, 520, 564, 612, 663, 720, 781, - 847, 918, 996, 1080, 1172, 1271, 1379, 1495, - 1622, 1759, 1908, 2070, 2245, 2435, 2641, 2865, - 3107, 3370, 3655, 3964, 4300, 4664, 5059, 5487, - 5951, 6455, 7001, 7593, 8236, 8933, 9689, 10508, - 11398, 12362, 13408, 14543, 15774, 17108, 18556, 20126, - 21829, 23677, 25680, 27853, 30210, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - - -static av_cold int cinvideo_decode_init(AVCodecContext *avctx) -{ - CinVideoContext *cin = avctx->priv_data; - unsigned int i; - - cin->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - cin->frame.data[0] = NULL; - - cin->bitmap_size = avctx->width * avctx->height; - for (i = 0; i < 3; ++i) { - cin->bitmap_table[i] = av_mallocz(cin->bitmap_size); - if (!cin->bitmap_table[i]) - av_log(avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n"); - } - - return 0; -} - -static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size) -{ - while (size--) - *dst++ += *src++; -} - -static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) -{ - int b, huff_code = 0; - unsigned char huff_code_table[15]; - unsigned char *dst_cur = dst; - unsigned char *dst_end = dst + dst_size; - const unsigned char *src_end = src + src_size; - - memcpy(huff_code_table, src, 15); src += 15; src_size -= 15; - - while (src < src_end) { - huff_code = *src++; - if ((huff_code >> 4) == 15) { - b = huff_code << 4; - huff_code = *src++; - *dst_cur++ = b | (huff_code >> 4); - } else - *dst_cur++ = huff_code_table[huff_code >> 4]; - if (dst_cur >= dst_end) - break; - - huff_code &= 15; - if (huff_code == 15) { - *dst_cur++ = *src++; - } else - *dst_cur++ = huff_code_table[huff_code]; - if (dst_cur >= dst_end) - break; - } - - return dst_cur - dst; -} - -static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) -{ - uint16_t cmd; - int i, sz, offset, code; - unsigned char *dst_end = dst + dst_size; - const unsigned char *src_end = src + src_size; - - while (src < src_end && dst < dst_end) { - code = *src++; - for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) { - if (code & (1 << i)) { - *dst++ = *src++; - } else { - cmd = AV_RL16(src); src += 2; - offset = cmd >> 4; - sz = (cmd & 0xF) + 2; - /* don't use memcpy/memmove here as the decoding routine (ab)uses */ - /* buffer overlappings to repeat bytes in the destination */ - sz = FFMIN(sz, dst_end - dst); - while (sz--) { - *dst = *(dst - offset - 1); - ++dst; - } - } - } - } -} - -static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) -{ - int len, code; - unsigned char *dst_end = dst + dst_size; - const unsigned char *src_end = src + src_size; - - while (src < src_end && dst < dst_end) { - code = *src++; - if (code & 0x80) { - len = code - 0x7F; - memset(dst, *src++, FFMIN(len, dst_end - dst)); - } else { - len = code + 1; - memcpy(dst, src, FFMIN(len, dst_end - dst)); - src += len; - } - dst += len; - } -} - -static int cinvideo_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - CinVideoContext *cin = avctx->priv_data; - int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size; - - cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &cin->frame)) { - av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); - return -1; - } - - palette_type = buf[0]; - palette_colors_count = AV_RL16(buf+1); - bitmap_frame_type = buf[3]; - buf += 4; - - bitmap_frame_size = buf_size - 4; - - /* handle palette */ - if (palette_type == 0) { - for (i = 0; i < palette_colors_count; ++i) { - cin->palette[i] = bytestream_get_le24(&buf); - bitmap_frame_size -= 3; - } - } else { - for (i = 0; i < palette_colors_count; ++i) { - cin->palette[buf[0]] = AV_RL24(buf+1); - buf += 4; - bitmap_frame_size -= 4; - } - } - memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); - cin->frame.palette_has_changed = 1; - - /* note: the decoding routines below assumes that surface.width = surface.pitch */ - switch (bitmap_frame_type) { - case 9: - cin_decode_rle(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - break; - case 34: - cin_decode_rle(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - break; - case 35: - cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); - cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - break; - case 36: - bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); - cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - break; - case 37: - cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - break; - case 38: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - break; - case 39: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); - break; - } - - for (y = 0; y < cin->avctx->height; ++y) - memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0], - cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, - cin->avctx->width); - - FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]); - - *data_size = sizeof(AVFrame); - *(AVFrame *)data = cin->frame; - - return buf_size; -} - -static av_cold int cinvideo_decode_end(AVCodecContext *avctx) -{ - CinVideoContext *cin = avctx->priv_data; - int i; - - if (cin->frame.data[0]) - avctx->release_buffer(avctx, &cin->frame); - - for (i = 0; i < 3; ++i) - av_free(cin->bitmap_table[i]); - - return 0; -} - -static av_cold int cinaudio_decode_init(AVCodecContext *avctx) -{ - CinAudioContext *cin = avctx->priv_data; - - cin->avctx = avctx; - cin->initial_decode_frame = 1; - cin->delta = 0; - avctx->sample_fmt = SAMPLE_FMT_S16; - - return 0; -} - -static int cinaudio_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - CinAudioContext *cin = avctx->priv_data; - const uint8_t *src = buf; - int16_t *samples = (int16_t *)data; - - buf_size = FFMIN(buf_size, *data_size/2); - - if (cin->initial_decode_frame) { - cin->initial_decode_frame = 0; - cin->delta = (int16_t)AV_RL16(src); src += 2; - *samples++ = cin->delta; - buf_size -= 2; - } - while (buf_size > 0) { - cin->delta += cinaudio_delta16_table[*src++]; - cin->delta = av_clip_int16(cin->delta); - *samples++ = cin->delta; - --buf_size; - } - - *data_size = (uint8_t *)samples - (uint8_t *)data; - - return src - buf; -} - - -AVCodec dsicinvideo_decoder = { - "dsicinvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DSICINVIDEO, - sizeof(CinVideoContext), - cinvideo_decode_init, - NULL, - cinvideo_decode_end, - cinvideo_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"), -}; - -AVCodec dsicinaudio_decoder = { - "dsicinaudio", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_DSICINAUDIO, - sizeof(CinAudioContext), - cinaudio_decode_init, - NULL, - NULL, - cinaudio_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dsputil.c b/tizen/distrib/ffmpeg/libavcodec/dsputil.c deleted file mode 100644 index 0701324..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dsputil.c +++ /dev/null @@ -1,4566 +0,0 @@ -/* - * DSP utils - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * DSP utils - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "simple_idct.h" -#include "faandct.h" -#include "faanidct.h" -#include "mathops.h" -#include "mpegvideo.h" -#include "config.h" -#include "lpc.h" -#include "ac3dec.h" -#include "vorbis.h" -#include "png.h" - -uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; -uint32_t ff_squareTbl[512] = {0, }; - -// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size -#define pb_7f (~0UL/255 * 0x7f) -#define pb_80 (~0UL/255 * 0x80) - -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(16, uint16_t, inv_zigzag_direct16)[64]; - -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<=16909558 && 2<=b<=256 - * for a>16909558, is an overestimate by less than 1 part in 1<<24 */ -const uint32_t ff_inverse[257]={ - 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, - 16777216 -}; - -/* 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 const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7}; - -void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){ - int i; - int end; - - st->scantable= src_scantable; - - for(i=0; i<64; i++){ - int j; - j = src_scantable[i]; - st->permutated[i] = permutation[j]; -#if ARCH_PPC - st->inverse[j] = i; -#endif - } - - end=-1; - for(i=0; i<64; i++){ - int j; - j = st->permutated[i]; - if(j>end) end=j; - st->raster_end[i]= end; - } -} - -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 = ff_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, const 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= h){ - src+= (h-1-src_y)*linesize; - src_y=h-1; - }else if(src_y<=-block_h){ - src+= (1-block_h-src_y)*linesize; - src_y=1-block_h; - } - if(src_x>= w){ - src+= (w-1-src_x); - src_x=w-1; - }else if(src_x<=-block_w){ - src+= (1-block_w-src_x); - src_x=1-block_w; - } - - start_y= FFMAX(0, -src_y); - start_x= FFMAX(0, -src_x); - end_y= FFMIN(block_h, h-src_y); - end_x= FFMIN(block_w, w-src_x); - - // copy existing part - for(y=start_y; y 127) - *pixels = 255; - else - *pixels = (uint8_t)(*block + 128); - block++; - pixels++; - } - pixels += (line_size - 8); - } -} - -static void put_pixels_nonclamped_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) -{ - int i; - - /* read the pixels */ - 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_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) -{ - int i; - uint8_t *cm = ff_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 = ff_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 = ff_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; - } -} - -static int sum_abs_dctelem_c(DCTELEM *block) -{ - int sum=0, i; - for(i=0; i<64; i++) - sum+= FFABS(block[i]); - return sum; -} - -static void fill_block16_c(uint8_t *block, uint8_t value, int line_size, int h) -{ - int i; - - for (i = 0; i < h; i++) { - memset(block, value, 16); - block += line_size; - } -} - -static void fill_block8_c(uint8_t *block, uint8_t value, int line_size, int h) -{ - int i; - - for (i = 0; i < h; i++) { - memset(block, value, 8); - block += line_size; - } -} - -static void scale_block_c(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize) -{ - int i, j; - uint16_t *dst1 = (uint16_t *) dst; - uint16_t *dst2 = (uint16_t *)(dst + linesize); - - for (j = 0; j < 8; j++) { - for (i = 0; i < 8; i++) { - dst1[i] = dst2[i] = src[i] * 0x0101; - } - src += 8; - dst1 += linesize; - dst2 += linesize; - } -} - -#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= AV_RN64(pixels );\ - const uint64_t b= AV_RN64(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= AV_RN64(pixels );\ - b= AV_RN64(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= AV_RN64(pixels );\ - const uint64_t b= AV_RN64(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= AV_RN64(pixels );\ - b= AV_RN64(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= AV_RN32(&src1[i*src_stride1+4]);\ - b= AV_RN32(&src2[i*src_stride2+4]);\ - c= AV_RN32(&src3[i*src_stride3+4]);\ - d= AV_RN32(&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= AV_RN32(&src1[i*src_stride1+4]);\ - b= AV_RN32(&src2[i*src_stride2+4]);\ - c= AV_RN32(&src3[i*src_stride3+4]);\ - d= AV_RN32(&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= AV_RN32(pixels );\ - const uint32_t b= AV_RN32(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= AV_RN32(pixels );\ - b= AV_RN32(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= AV_RN32(pixels );\ - const uint32_t b= AV_RN32(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= AV_RN32(pixels );\ - b= AV_RN32(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= AV_RN32(pixels );\ - const uint32_t b= AV_RN32(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= AV_RN32(pixels );\ - b= AV_RN32(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 + av_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= av_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= av_clip(src_x, 0, width) + av_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);\ -\ - if(D){\ - for(i=0; i=0 && y>=0);\ -\ - if(D){\ - for(i=0; i=0 && y>=0);\ -\ - if(D){\ - 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 void put_no_rnd_vc1_chroma_mc8_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> 6; - dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6; - dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6; - dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6; - dst[4] = (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + 32 - 4) >> 6; - dst[5] = (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + 32 - 4) >> 6; - dst[6] = (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + 32 - 4) >> 6; - dst[7] = (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + 32 - 4) >> 6; - dst+= stride; - src+= stride; - } -} - -static void avg_no_rnd_vc1_chroma_mc8_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> 6)); - dst[1] = avg2(dst[1], ((A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6)); - dst[2] = avg2(dst[2], ((A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6)); - dst[3] = avg2(dst[3], ((A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6)); - dst[4] = avg2(dst[4], ((A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + 32 - 4) >> 6)); - dst[5] = avg2(dst[5], ((A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + 32 - 4) >> 6)); - dst[6] = avg2(dst[6], ((A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + 32 - 4) >> 6)); - dst[7] = avg2(dst[7], ((A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + 32 - 4) >> 6)); - dst+= stride; - src+= stride; - } -} - -#define QPEL_MC(r, OPNAME, RND, OP) \ -static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - 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 av_unused void OPNAME ## h264_qpel2_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int h=2;\ - uint8_t *cm = ff_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 - -static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int i; - - for(i=0; i>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; - } -} - -#if CONFIG_CAVS_DECODER -/* AVS specific */ -void ff_put_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - put_pixels8_c(dst, src, stride, 8); -} -void ff_avg_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - avg_pixels8_c(dst, src, stride, 8); -} -void ff_put_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - put_pixels16_c(dst, src, stride, 16); -} -void ff_avg_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - avg_pixels16_c(dst, src, stride, 16); -} -#endif /* CONFIG_CAVS_DECODER */ - -#if CONFIG_VC1_DECODER -/* VC-1 specific */ -void ff_put_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - put_pixels8_c(dst, src, stride, 8); -} -void ff_avg_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - avg_pixels8_c(dst, src, stride, 8); -} -#endif /* CONFIG_VC1_DECODER */ - -#if CONFIG_RV40_DECODER -static void put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){ - put_pixels16_xy2_c(dst, src, stride, 16); -} -static void avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){ - avg_pixels16_xy2_c(dst, src, stride, 16); -} -static void put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){ - put_pixels8_xy2_c(dst, src, stride, 8); -} -static void avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){ - avg_pixels8_xy2_c(dst, src, stride, 8); -} -#endif /* CONFIG_RV40_DECODER */ - -static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ - uint8_t *cm = ff_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){ - if(CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { - 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= FFABS(d1)>>1; - - d2= av_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){ - if(CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { - 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= FFABS(d1)>>1; - - d2= av_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 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 + FFABS(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 + FFABS(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 it is ok but not clean and might fail for some permutations - - 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*)*6); - - for(i=0; i<6; 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; -#if CONFIG_DWT - case FF_CMP_W53: - cmp[i]= c->w53[i]; - break; - case FF_CMP_W97: - cmp[i]= c->w97[i]; - break; -#endif - default: - av_log(NULL, AV_LOG_ERROR,"internal error in cmp function selection\n"); - } - } -} - -static void clear_block_c(DCTELEM *block) -{ - memset(block, 0, sizeof(DCTELEM)*64); -} - -/** - * 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){ - long i; - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ - long a = *(long*)(src+i); - long b = *(long*)(dst+i); - *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); - } - for(; imaxi){ - 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 -= FFABS(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; - LOCAL_ALIGNED_16(DCTELEM, temp, [64]); - - assert(h==8); - - s->dsp.diff_pixels(temp, src1, src2, stride); - s->dsp.fdct(temp); - return s->dsp.sum_abs_dctelem(temp); -} - -#if 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; - DCTELEM dct[8][8]; - int i; - int sum=0; - - s->dsp.diff_pixels(dct[0], 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 += FFABS(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; - LOCAL_ALIGNED_16(DCTELEM, temp, [64]); - 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, FFABS(temp[i])); - - return sum; -} - -static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ - MpegEncContext * const s= (MpegEncContext *)c; - LOCAL_ALIGNED_16(DCTELEM, temp, [64*2]); - DCTELEM * const bak = 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); - ff_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; - LOCAL_ALIGNED_16(DCTELEM, temp, [64]); - LOCAL_ALIGNED_16(uint8_t, lsrc1, [64]); - LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]); - int i, last, run, bits, level, distortion, start_i; - const int esc_length= s->ac_esc_length; - uint8_t * length; - uint8_t * last_length; - - assert(h==8); - - copy_block8(lsrc1, src1, 8, stride, 8); - copy_block8(lsrc2, src2, 8, stride, 8); - - s->dsp.diff_pixels(temp, lsrc1, lsrc2, 8); - - 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(lsrc2, 8, temp); - - distortion= s->dsp.sse[1](NULL, lsrc2, lsrc1, 8, 8); - - return distortion + ((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; - LOCAL_ALIGNED_16(DCTELEM, temp, [64]); - 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 mini) return mini; - else if((a^(1<<31)) > maxisign) return maxi; - else return a; -} - -static void vector_clipf_c_opposite_sign(float *dst, const float *src, float *min, float *max, int len){ - int i; - uint32_t mini = *(uint32_t*)min; - uint32_t maxi = *(uint32_t*)max; - uint32_t maxisign = maxi ^ (1<<31); - uint32_t *dsti = (uint32_t*)dst; - const uint32_t *srci = (const uint32_t*)src; - for(i=0; i 0) { - vector_clipf_c_opposite_sign(dst, src, &min, &max, len); - } else { - for(i=0; i < len; i+=8) { - dst[i ] = av_clipf(src[i ], min, max); - dst[i + 1] = av_clipf(src[i + 1], min, max); - dst[i + 2] = av_clipf(src[i + 2], min, max); - dst[i + 3] = av_clipf(src[i + 3], min, max); - dst[i + 4] = av_clipf(src[i + 4], min, max); - dst[i + 5] = av_clipf(src[i + 5], min, max); - dst[i + 6] = av_clipf(src[i + 6], min, max); - dst[i + 7] = av_clipf(src[i + 7], min, max); - } - } -} - -static av_always_inline int float_to_int16_one(const float *src){ - int_fast32_t tmp = *(const int32_t*)src; - if(tmp & 0xf0000){ - tmp = (0x43c0ffff - tmp)>>31; - // is this faster on some gcc/cpu combinations? -// if(tmp > 0x43c0ffff) tmp = 0xFFFF; -// else tmp = 0; - } - return tmp - 0x8000; -} - -void ff_float_to_int16_c(int16_t *dst, const float *src, long len){ - int i; - for(i=0; i> shift; - - return res; -} - -static int32_t scalarproduct_and_madd_int16_c(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul) -{ - int res = 0; - while (order--) { - res += *v1 * *v2++; - *v1++ += mul * *v3++; - } - return res; -} - -#define W0 2048 -#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ -#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ -#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ -#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */ -#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ -#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ -#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ - -static void wmv2_idct_row(short * b) -{ - int s1,s2; - int a0,a1,a2,a3,a4,a5,a6,a7; - /*step 1*/ - a1 = W1*b[1]+W7*b[7]; - a7 = W7*b[1]-W1*b[7]; - a5 = W5*b[5]+W3*b[3]; - a3 = W3*b[5]-W5*b[3]; - a2 = W2*b[2]+W6*b[6]; - a6 = W6*b[2]-W2*b[6]; - a0 = W0*b[0]+W0*b[4]; - a4 = W0*b[0]-W0*b[4]; - /*step 2*/ - s1 = (181*(a1-a5+a7-a3)+128)>>8;//1,3,5,7, - s2 = (181*(a1-a5-a7+a3)+128)>>8; - /*step 3*/ - b[0] = (a0+a2+a1+a5 + (1<<7))>>8; - b[1] = (a4+a6 +s1 + (1<<7))>>8; - b[2] = (a4-a6 +s2 + (1<<7))>>8; - b[3] = (a0-a2+a7+a3 + (1<<7))>>8; - b[4] = (a0-a2-a7-a3 + (1<<7))>>8; - b[5] = (a4-a6 -s2 + (1<<7))>>8; - b[6] = (a4+a6 -s1 + (1<<7))>>8; - b[7] = (a0+a2-a1-a5 + (1<<7))>>8; -} -static void wmv2_idct_col(short * b) -{ - int s1,s2; - int a0,a1,a2,a3,a4,a5,a6,a7; - /*step 1, with extended precision*/ - a1 = (W1*b[8*1]+W7*b[8*7] + 4)>>3; - a7 = (W7*b[8*1]-W1*b[8*7] + 4)>>3; - a5 = (W5*b[8*5]+W3*b[8*3] + 4)>>3; - a3 = (W3*b[8*5]-W5*b[8*3] + 4)>>3; - a2 = (W2*b[8*2]+W6*b[8*6] + 4)>>3; - a6 = (W6*b[8*2]-W2*b[8*6] + 4)>>3; - a0 = (W0*b[8*0]+W0*b[8*4] )>>3; - a4 = (W0*b[8*0]-W0*b[8*4] )>>3; - /*step 2*/ - s1 = (181*(a1-a5+a7-a3)+128)>>8; - s2 = (181*(a1-a5-a7+a3)+128)>>8; - /*step 3*/ - b[8*0] = (a0+a2+a1+a5 + (1<<13))>>14; - b[8*1] = (a4+a6 +s1 + (1<<13))>>14; - b[8*2] = (a4-a6 +s2 + (1<<13))>>14; - b[8*3] = (a0-a2+a7+a3 + (1<<13))>>14; - - b[8*4] = (a0-a2-a7-a3 + (1<<13))>>14; - b[8*5] = (a4-a6 -s2 + (1<<13))>>14; - b[8*6] = (a4+a6 -s1 + (1<<13))>>14; - b[8*7] = (a0+a2-a1-a5 + (1<<13))>>14; -} -void ff_wmv2_idct_c(short * block){ - int i; - - for(i=0;i<64;i+=8){ - wmv2_idct_row(block+i); - } - for(i=0;i<8;i++){ - wmv2_idct_col(block+i); - } -} -/* XXX: those functions should be suppressed ASAP when all IDCTs are - converted */ -static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_wmv2_idct_c(block); - put_pixels_clamped_c(block, dest, line_size); -} -static void ff_wmv2_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_wmv2_idct_c(block); - add_pixels_clamped_c(block, dest, line_size); -} -static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct (block); - put_pixels_clamped_c(block, dest, line_size); -} -static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct (block); - add_pixels_clamped_c(block, dest, line_size); -} - -static void ff_jref_idct4_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct4 (block); - put_pixels_clamped4_c(block, dest, line_size); -} -static void ff_jref_idct4_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct4 (block); - add_pixels_clamped4_c(block, dest, line_size); -} - -static void ff_jref_idct2_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct2 (block); - put_pixels_clamped2_c(block, dest, line_size); -} -static void ff_jref_idct2_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct2 (block); - add_pixels_clamped2_c(block, dest, line_size); -} - -static void ff_jref_idct1_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - dest[0] = cm[(block[0] + 4)>>3]; -} -static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - dest[0] = cm[dest[0] + ((block[0] + 4)>>3)]; -} - -static void just_return(void *mem av_unused, int stride av_unused, int h av_unused) { return; } - -/* init static data */ -av_cold void dsputil_static_init(void) -{ - int i; - - for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i; - for(i=0;i= 4.2.\n" - "Do not report crashes to FFmpeg developers.\n"); -#endif - did_fail=1; - } - return -1; - } - return 0; -} - -av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) -{ - int i; - - ff_check_alignment(); - -#if CONFIG_ENCODERS - if(avctx->dct_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 || !CONFIG_H264_DECODER){ - 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((CONFIG_VP3_DECODER || CONFIG_VP5_DECODER || CONFIG_VP6_DECODER ) && - 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 if(avctx->idct_algo==FF_IDCT_WMV2){ - c->idct_put= ff_wmv2_idct_put_c; - c->idct_add= ff_wmv2_idct_add_c; - c->idct = ff_wmv2_idct_c; - c->idct_permutation_type= FF_NO_IDCT_PERM; - }else if(avctx->idct_algo==FF_IDCT_FAAN){ - c->idct_put= ff_faanidct_put; - c->idct_add= ff_faanidct_add; - c->idct = ff_faanidct; - c->idct_permutation_type= FF_NO_IDCT_PERM; - }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) { - c->idct_put= ff_ea_idct_put_c; - c->idct_permutation_type= FF_NO_IDCT_PERM; - }else if(CONFIG_BINK_DECODER && avctx->idct_algo==FF_IDCT_BINK) { - c->idct = ff_bink_idct_c; - c->idct_add = ff_bink_idct_add_c; - c->idct_put = ff_bink_idct_put_c; - c->idct_permutation_type = FF_NO_IDCT_PERM; - }else{ //accurate/default - c->idct_put= ff_simple_idct_put; - c->idct_add= ff_simple_idct_add; - c->idct = ff_simple_idct; - c->idct_permutation_type= FF_NO_IDCT_PERM; - } - } - - 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->put_pixels_nonclamped = put_pixels_nonclamped_c; - c->add_pixels_clamped = add_pixels_clamped_c; - c->add_pixels8 = add_pixels8_c; - c->add_pixels4 = add_pixels4_c; - c->sum_abs_dctelem = sum_abs_dctelem_c; - c->gmc1 = gmc1_c; - c->gmc = ff_gmc_c; - c->clear_block = clear_block_c; - c->clear_blocks = clear_blocks_c; - c->pix_sum = pix_sum_c; - c->pix_norm1 = pix_norm1_c; - - c->fill_block_tab[0] = fill_block16_c; - c->fill_block_tab[1] = fill_block8_c; - c->scale_block = scale_block_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->put_no_rnd_vc1_chroma_pixels_tab[0]= put_no_rnd_vc1_chroma_mc8_c; - c->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_no_rnd_vc1_chroma_mc8_c; - - c->draw_edges = draw_edges_c; - -#if CONFIG_CAVS_DECODER - ff_cavsdsp_init(c,avctx); -#endif - -#if CONFIG_MLP_DECODER || CONFIG_TRUEHD_DECODER - ff_mlp_init(c, avctx); -#endif -#if CONFIG_VC1_DECODER - ff_vc1dsp_init(c,avctx); -#endif -#if CONFIG_WMV2_DECODER || CONFIG_VC1_DECODER - ff_intrax8dsp_init(c,avctx); -#endif -#if CONFIG_RV30_DECODER - ff_rv30dsp_init(c,avctx); -#endif -#if CONFIG_RV40_DECODER - ff_rv40dsp_init(c,avctx); - c->put_rv40_qpel_pixels_tab[0][15] = put_rv40_qpel16_mc33_c; - c->avg_rv40_qpel_pixels_tab[0][15] = avg_rv40_qpel16_mc33_c; - c->put_rv40_qpel_pixels_tab[1][15] = put_rv40_qpel8_mc33_c; - c->avg_rv40_qpel_pixels_tab[1][15] = avg_rv40_qpel8_mc33_c; -#endif - - 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; - c->hadamard8_diff[5]= hadamard8_intra8x8_c; - SET_CMP_FUNC(dct_sad) - SET_CMP_FUNC(dct_max) -#if 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->vsad[5]= vsad_intra8_c; - c->vsse[0]= vsse16_c; - c->vsse[4]= vsse_intra16_c; - c->vsse[5]= vsse_intra8_c; - c->nsse[0]= nsse16_c; - c->nsse[1]= nsse8_c; -#if CONFIG_DWT - ff_dsputil_init_dwt(c); -#endif - - c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; - - c->add_bytes= add_bytes_c; - c->add_bytes_l2= add_bytes_l2_c; - c->diff_bytes= diff_bytes_c; - c->add_hfyu_median_prediction= add_hfyu_median_prediction_c; - c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; - c->add_hfyu_left_prediction = add_hfyu_left_prediction_c; - c->add_hfyu_left_prediction_bgr32 = add_hfyu_left_prediction_bgr32_c; - c->bswap_buf= bswap_buf; -#if CONFIG_PNG_DECODER - c->add_png_paeth_prediction= ff_add_png_paeth_prediction; -#endif - - if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { - c->h263_h_loop_filter= h263_h_loop_filter_c; - c->h263_v_loop_filter= h263_v_loop_filter_c; - } - - if (CONFIG_VP3_DECODER) { - c->vp3_h_loop_filter= ff_vp3_h_loop_filter_c; - c->vp3_v_loop_filter= ff_vp3_v_loop_filter_c; - c->vp3_idct_dc_add= ff_vp3_idct_dc_add_c; - } - if (CONFIG_VP6_DECODER) { - c->vp6_filter_diag4= ff_vp6_filter_diag4_c; - } - - c->h261_loop_filter= h261_loop_filter_c; - - c->try_8x8basis= try_8x8basis_c; - c->add_8x8basis= add_8x8basis_c; - -#if CONFIG_VORBIS_DECODER - c->vorbis_inverse_coupling = vorbis_inverse_coupling; -#endif -#if CONFIG_AC3_DECODER - c->ac3_downmix = ff_ac3_downmix_c; -#endif -#if CONFIG_LPC - c->lpc_compute_autocorr = ff_lpc_compute_autocorr; -#endif - c->vector_fmul = vector_fmul_c; - c->vector_fmul_reverse = vector_fmul_reverse_c; - c->vector_fmul_add = vector_fmul_add_c; - c->vector_fmul_window = ff_vector_fmul_window_c; - c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c; - c->vector_clipf = vector_clipf_c; - c->float_to_int16 = ff_float_to_int16_c; - c->float_to_int16_interleave = ff_float_to_int16_interleave_c; - c->scalarproduct_int16 = scalarproduct_int16_c; - c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c; - c->scalarproduct_float = scalarproduct_float_c; - c->butterflies_float = butterflies_float_c; - c->vector_fmul_scalar = vector_fmul_scalar_c; - - c->vector_fmul_sv_scalar[0] = vector_fmul_sv_scalar_2_c; - c->vector_fmul_sv_scalar[1] = vector_fmul_sv_scalar_4_c; - - c->sv_fmul_scalar[0] = sv_fmul_scalar_2_c; - c->sv_fmul_scalar[1] = sv_fmul_scalar_4_c; - - 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; - - memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab)); - memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab)); - - if (HAVE_MMX) dsputil_init_mmx (c, avctx); - if (ARCH_ARM) dsputil_init_arm (c, avctx); - if (CONFIG_MLIB) dsputil_init_mlib (c, avctx); - if (HAVE_VIS) dsputil_init_vis (c, avctx); - if (ARCH_ALPHA) dsputil_init_alpha (c, avctx); - if (ARCH_PPC) dsputil_init_ppc (c, avctx); - if (HAVE_MMI) dsputil_init_mmi (c, avctx); - if (ARCH_SH4) dsputil_init_sh4 (c, avctx); - if (ARCH_BFIN) dsputil_init_bfin (c, avctx); - - for(i=0; i<64; i++){ - if(!c->put_2tap_qpel_pixels_tab[0][i]) - c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i]; - if(!c->avg_2tap_qpel_pixels_tab[0][i]) - c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i]; - } - - 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; - case FF_SSE2_IDCT_PERM: - for(i=0; i<64; i++) - c->idct_permutation[i]= (i&0x38) | idct_sse2_row_perm[i&7]; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Internal error, IDCT permutation not set\n"); - } -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/dsputil.h b/tizen/distrib/ffmpeg/libavcodec/dsputil.h deleted file mode 100644 index fd2d07f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dsputil.h +++ /dev/null @@ -1,810 +0,0 @@ -/* - * DSP utils - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 AVCODEC_DSPUTIL_H -#define AVCODEC_DSPUTIL_H - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - - -//#define DEBUG -/* dct code */ -typedef short DCTELEM; - -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_wmv2_idct_c(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); -void ff_h264_idct_add16_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); -void ff_h264_idct_add16intra_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); -void ff_h264_idct8_add4_c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); -void ff_h264_idct_add8_c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]); - -void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, - const float *win, float add_bias, int len); -void ff_float_to_int16_c(int16_t *dst, const float *src, long len); -void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels); - -/* 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 ff_squareTbl[512]; -extern uint8_t ff_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*/); -void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/); - -void ff_vp3_v_loop_filter_c(uint8_t *src, int stride, int *bounding_values); -void ff_vp3_h_loop_filter_c(uint8_t *src, int stride, int *bounding_values); - -/* VP6 DSP functions */ -void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights, const int16_t *v_weights); - -/* Bink functions */ -void ff_bink_idct_c (DCTELEM *block); -void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block); -void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); - -/* CAVS functions */ -void ff_put_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride); -void ff_put_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride); - -/* VC1 functions */ -void ff_put_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd); -void ff_avg_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd); - -/* EA functions */ -void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block); - -/* 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 you 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-devel mailing list, ... - -!warning These alignments might not match reality, (missing attribute((align)) -stuff somewhere possible). -I (Michael) did not check them, these are just the alignments 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 (*op_fill_func)(uint8_t *block/*align width (8 or 16)*/, uint8_t value, int line_size, int h); - -#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 -// although currently h<4 is not used as functions with width <8 are neither used nor 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))*/; - -/** - * Scantable. - */ -typedef struct ScanTable{ - const uint8_t *scantable; - uint8_t permutated[64]; - uint8_t raster_end[64]; -#if ARCH_PPC - /** Used by dct_quantize_altivec to find last-non-zero */ - DECLARE_ALIGNED(16, uint8_t, inverse)[64]; -#endif -} ScanTable; - -void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable); - -void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, - int block_w, int block_h, - int src_x, int src_y, int w, int h); - -/** - * 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 (*put_pixels_nonclamped)(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); - int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/); - /** - * 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_block)(DCTELEM *block/*align 16*/); - 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[6]; /* identical to pix_absAxA except additional void * */ - me_cmp_func sse[6]; - me_cmp_func hadamard8_diff[6]; - me_cmp_func dct_sad[6]; - me_cmp_func quant_psnr[6]; - me_cmp_func bit[6]; - me_cmp_func rd[6]; - me_cmp_func vsad[6]; - me_cmp_func vsse[6]; - me_cmp_func nsse[6]; - me_cmp_func w53[6]; - me_cmp_func w97[6]; - me_cmp_func dct_max[6]; - me_cmp_func dct264_sad[6]; - - me_cmp_func me_pre_cmp[6]; - me_cmp_func me_cmp[6]; - me_cmp_func me_sub_cmp[6]; - me_cmp_func mb_cmp[6]; - me_cmp_func ildct_cmp[6]; //only width 16 used - me_cmp_func frame_skip_cmp[6]; //only width 8 used - - int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2, - int size); - - /** - * 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 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 functions 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 functions 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 functions for the 9 thirdpe - * 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 Chroma MC - */ - h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; - h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; - /* This is really one func used in VC-1 decoding */ - h264_chroma_mc_func put_no_rnd_vc1_chroma_pixels_tab[3]; - h264_chroma_mc_func avg_no_rnd_vc1_chroma_pixels_tab[3]; - - qpel_mc_func put_h264_qpel_pixels_tab[4][16]; - qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; - - qpel_mc_func put_2tap_qpel_pixels_tab[4][16]; - qpel_mc_func avg_2tap_qpel_pixels_tab[4][16]; - - /* AVS specific */ - qpel_mc_func put_cavs_qpel_pixels_tab[2][16]; - qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]; - void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); - - 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 (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*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, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top); - void (*add_hfyu_median_prediction)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top); - int (*add_hfyu_left_prediction)(uint8_t *dst, const uint8_t *src, int w, int left); - void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha); - /* this might write to dst[w] */ - void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); - void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); - - 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); - - void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale); - void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale); - - void (*vp3_idct_dc_add)(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/); - void (*vp3_v_loop_filter)(uint8_t *src, int stride, int *bounding_values); - void (*vp3_h_loop_filter)(uint8_t *src, int stride, int *bounding_values); - - void (*vp6_filter_diag4)(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights,const int16_t *v_weights); - - /* assume len is a multiple of 4, and arrays are 16-byte aligned */ - void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); - void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); - /* no alignment needed */ - void (*lpc_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc); - /* assume len is a multiple of 8, and arrays are 16-byte aligned */ - void (*vector_fmul)(float *dst, const float *src, int len); - void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); - /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ - void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, const float *src2, int len); - /* assume len is a multiple of 4, and arrays are 16-byte aligned */ - void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len); - /* assume len is a multiple of 8, and arrays are 16-byte aligned */ - void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len); - void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */); - /** - * Multiply a vector of floats by a scalar float. Source and - * destination vectors must overlap exactly or not at all. - * @param dst result vector, 16-byte aligned - * @param src input vector, 16-byte aligned - * @param mul scalar value - * @param len length of vector, multiple of 4 - */ - void (*vector_fmul_scalar)(float *dst, const float *src, float mul, - int len); - /** - * Multiply a vector of floats by concatenated short vectors of - * floats and by a scalar float. Source and destination vectors - * must overlap exactly or not at all. - * [0]: short vectors of length 2, 8-byte aligned - * [1]: short vectors of length 4, 16-byte aligned - * @param dst output vector, 16-byte aligned - * @param src input vector, 16-byte aligned - * @param sv array of pointers to short vectors - * @param mul scalar value - * @param len number of elements in src and dst, multiple of 4 - */ - void (*vector_fmul_sv_scalar[2])(float *dst, const float *src, - const float **sv, float mul, int len); - /** - * Multiply short vectors of floats by a scalar float, store - * concatenated result. - * [0]: short vectors of length 2, 8-byte aligned - * [1]: short vectors of length 4, 16-byte aligned - * @param dst output vector, 16-byte aligned - * @param sv array of pointers to short vectors - * @param mul scalar value - * @param len number of output elements, multiple of 4 - */ - void (*sv_fmul_scalar[2])(float *dst, const float **sv, - float mul, int len); - /** - * Calculate the scalar product of two vectors of floats. - * @param v1 first vector, 16-byte aligned - * @param v2 second vector, 16-byte aligned - * @param len length of vectors, multiple of 4 - */ - float (*scalarproduct_float)(const float *v1, const float *v2, int len); - /** - * Calculate the sum and difference of two vectors of floats. - * @param v1 first input vector, sum output, 16-byte aligned - * @param v2 second input vector, difference output, 16-byte aligned - * @param len length of vectors, multiple of 4 - */ - void (*butterflies_float)(float *restrict v1, float *restrict v2, int len); - - /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] - * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ - void (*float_to_int16)(int16_t *dst, const float *src, long len); - void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); - - /* (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 horizontal 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 horizontal 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 -#define FF_SSE2_IDCT_PERM 6 - - 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 (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w); -#define EDGE_WIDTH 16 - - 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); - - /* mlp/truehd functions */ - void (*mlp_filter_channel)(int32_t *state, const int32_t *coeff, - int firorder, int iirorder, - unsigned int filter_shift, int32_t mask, int blocksize, - int32_t *sample_buffer); - - /* vc1 functions */ - void (*vc1_inv_trans_8x8)(DCTELEM *b); - void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, DCTELEM *block); - void (*vc1_v_overlap)(uint8_t* src, int stride); - void (*vc1_h_overlap)(uint8_t* src, int stride); - void (*vc1_v_loop_filter4)(uint8_t *src, int stride, int pq); - void (*vc1_h_loop_filter4)(uint8_t *src, int stride, int pq); - void (*vc1_v_loop_filter8)(uint8_t *src, int stride, int pq); - void (*vc1_h_loop_filter8)(uint8_t *src, int stride, int pq); - void (*vc1_v_loop_filter16)(uint8_t *src, int stride, int pq); - void (*vc1_h_loop_filter16)(uint8_t *src, int stride, int pq); - /* put 8x8 block with bicubic interpolation and quarterpel precision - * last argument is actually round value instead of height - */ - op_pixels_func put_vc1_mspel_pixels_tab[16]; - op_pixels_func avg_vc1_mspel_pixels_tab[16]; - - /* intrax8 functions */ - void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize); - void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, - int * range, int * sum, int edges); - - /** - * Calculate scalar product of two vectors. - * @param len length of vectors, should be multiple of 16 - * @param shift number of bits to discard from product - */ - int32_t (*scalarproduct_int16)(int16_t *v1, int16_t *v2/*align 16*/, int len, int shift); - /* ape functions */ - /** - * Calculate scalar product of v1 and v2, - * and v1[i] += v3[i] * mul - * @param len length of vectors, should be multiple of 16 - */ - int32_t (*scalarproduct_and_madd_int16)(int16_t *v1/*align 16*/, int16_t *v2, int16_t *v3, int len, int mul); - - /* rv30 functions */ - qpel_mc_func put_rv30_tpel_pixels_tab[4][16]; - qpel_mc_func avg_rv30_tpel_pixels_tab[4][16]; - - /* rv40 functions */ - qpel_mc_func put_rv40_qpel_pixels_tab[4][16]; - qpel_mc_func avg_rv40_qpel_pixels_tab[4][16]; - h264_chroma_mc_func put_rv40_chroma_pixels_tab[3]; - h264_chroma_mc_func avg_rv40_chroma_pixels_tab[3]; - - /* bink functions */ - op_fill_func fill_block_tab[2]; - void (*scale_block)(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align 8*/, int linesize); -} DSPContext; - -void dsputil_static_init(void); -void dsputil_init(DSPContext* p, AVCodecContext *avctx); - -int ff_check_alignment(void); - -/** - * 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); -extern int mm_flags; - -void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); - -void ff_dsputil_init_dwt(DSPContext *c); -void ff_cavsdsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_rv40dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_vc1dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); -void ff_mlp_init(DSPContext* c, AVCodecContext *avctx); -void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx); - -#if HAVE_MMX - -#undef emms_c - -static inline void emms(void) -{ - __asm__ volatile ("emms;":::"memory"); -} - - -#define emms_c() \ -{\ - if (mm_flags & FF_MM_MMX)\ - emms();\ -} - -#elif ARCH_ARM - -#if HAVE_NEON -# define STRIDE_ALIGN 16 -#endif - -#elif ARCH_PPC - -#define STRIDE_ALIGN 16 - -#elif HAVE_MMI - -#define STRIDE_ALIGN 16 - -#else - -#define mm_flags 0 -#define mm_support() 0 - -#endif - -#ifndef STRIDE_ALIGN -# define STRIDE_ALIGN 8 -#endif - -#define LOCAL_ALIGNED(a, t, v, s, ...) \ - uint8_t la_##v[sizeof(t s __VA_ARGS__) + (a)]; \ - t (*v) __VA_ARGS__ = (void *)FFALIGN((uintptr_t)la_##v, a) - -#if HAVE_LOCAL_ALIGNED_8 -# define LOCAL_ALIGNED_8(t, v, s, ...) DECLARE_ALIGNED(8, t, v) s __VA_ARGS__ -#else -# define LOCAL_ALIGNED_8(t, v, s, ...) LOCAL_ALIGNED(8, t, v, s, __VA_ARGS__) -#endif - -#if HAVE_LOCAL_ALIGNED_16 -# define LOCAL_ALIGNED_16(t, v, s, ...) DECLARE_ALIGNED(16, t, v) s __VA_ARGS__ -#else -# define LOCAL_ALIGNED_16(t, v, s, ...) LOCAL_ALIGNED(16, t, v, s, __VA_ARGS__) -#endif - -/* PSNR */ -void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], - int orig_linesize[3], int coded_linesize, - AVCodecContext *avctx); - -#define WRAPPER8_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 WRAPPER8_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;\ -} - - -static inline void copy_block2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h) -{ - int i; - for(i=0; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" - - -static int dump_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - int cmd= args ? *args : 0; - /* cast to avoid warning about discarding qualifiers */ - if(avctx->extradata){ - if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER) && cmd=='a') - ||(keyframe && (cmd=='k' || !cmd)) - ||(cmd=='e') - /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ - int size= buf_size + avctx->extradata_size; - *poutbuf_size= size; - *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - - memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); - memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - return 1; - } - } - return 0; -} - -AVBitStreamFilter dump_extradata_bsf={ - "dump_extra", - 0, - dump_extradata, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dv.c b/tizen/distrib/ffmpeg/libavcodec/dv.c deleted file mode 100644 index ea1f661..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dv.c +++ /dev/null @@ -1,1309 +0,0 @@ -/* - * 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 - * - * 100 Mbps (DVCPRO HD) support - * Initial code by Daniel Maas (funded by BBC R&D) - * Final code by Roman Shaposhnik - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * DV codec. - */ -#define ALT_BITSTREAM_READER -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" -#include "put_bits.h" -#include "simple_idct.h" -#include "dvdata.h" -#include "dv_tablegen.h" - -//#undef NDEBUG -//#include - -typedef struct DVVideoContext { - const DVprofile *sys; - AVFrame picture; - AVCodecContext *avctx; - uint8_t *buf; - - uint8_t dv_zigzag[2][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); - me_cmp_func ildct_cmp; -} DVVideoContext; - -#define TEX_VLC_BITS 9 - -/* XXX: also include quantization */ -static RL_VLC_ELEM dv_rl_vlc[1184]; - -static inline int dv_work_pool_size(const DVprofile *d) -{ - int size = d->n_difchan*d->difseg_size*27; - if (DV_PROFILE_IS_1080i50(d)) - size -= 3*27; - if (DV_PROFILE_IS_720p50(d)) - size -= 4*27; - return size; -} - -static inline void dv_calc_mb_coordinates(const DVprofile *d, int chan, int seq, int slot, - uint16_t *tbl) -{ - static const uint8_t off[] = { 2, 6, 8, 0, 4 }; - static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 }; - static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 }; - static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 }; - - static const uint8_t l_start[] = {0, 4, 9, 13, 18, 22, 27, 31, 36, 40}; - static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 }; - - static const uint8_t serpent1[] = {0, 1, 2, 2, 1, 0, - 0, 1, 2, 2, 1, 0, - 0, 1, 2, 2, 1, 0, - 0, 1, 2, 2, 1, 0, - 0, 1, 2}; - static const uint8_t serpent2[] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, - 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, - 0, 1, 2, 3, 4, 5}; - - static const uint8_t remap[][2] = {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, /* dummy */ - { 0, 0}, { 0, 1}, { 0, 2}, { 0, 3}, {10, 0}, - {10, 1}, {10, 2}, {10, 3}, {20, 0}, {20, 1}, - {20, 2}, {20, 3}, {30, 0}, {30, 1}, {30, 2}, - {30, 3}, {40, 0}, {40, 1}, {40, 2}, {40, 3}, - {50, 0}, {50, 1}, {50, 2}, {50, 3}, {60, 0}, - {60, 1}, {60, 2}, {60, 3}, {70, 0}, {70, 1}, - {70, 2}, {70, 3}, { 0,64}, { 0,65}, { 0,66}, - {10,64}, {10,65}, {10,66}, {20,64}, {20,65}, - {20,66}, {30,64}, {30,65}, {30,66}, {40,64}, - {40,65}, {40,66}, {50,64}, {50,65}, {50,66}, - {60,64}, {60,65}, {60,66}, {70,64}, {70,65}, - {70,66}, { 0,67}, {20,67}, {40,67}, {60,67}}; - - int i, k, m; - int x, y, blk; - - for (m=0; m<5; m++) { - switch (d->width) { - case 1440: - blk = (chan*11+seq)*27+slot; - - if (chan == 0 && seq == 11) { - x = m*27+slot; - if (x<90) { - y = 0; - } else { - x = (x - 90)*2; - y = 67; - } - } else { - i = (4*chan + blk + off[m])%11; - k = (blk/11)%27; - - x = shuf1[m] + (chan&1)*9 + k%9; - y = (i*3+k/9)*2 + (chan>>1) + 1; - } - tbl[m] = (x<<1)|(y<<9); - break; - case 1280: - blk = (chan*10+seq)*27+slot; - - i = (4*chan + (seq/5) + 2*blk + off[m])%10; - k = (blk/5)%27; - - x = shuf1[m]+(chan&1)*9 + k%9; - y = (i*3+k/9)*2 + (chan>>1) + 4; - - if (x >= 80) { - x = remap[y][0]+((x-80)<<(y>59)); - y = remap[y][1]; - } - tbl[m] = (x<<1)|(y<<9); - break; - case 960: - blk = (chan*10+seq)*27+slot; - - i = (4*chan + (seq/5) + 2*blk + off[m])%10; - k = (blk/5)%27 + (i&1)*3; - - x = shuf2[m] + k%6 + 6*(chan&1); - y = l_start[i] + k/6 + 45*(chan>>1); - tbl[m] = (x<<1)|(y<<9); - break; - case 720: - switch (d->pix_fmt) { - case PIX_FMT_YUV422P: - x = shuf3[m] + slot/3; - y = serpent1[slot] + - ((((seq + off[m]) % d->difseg_size)<<1) + chan)*3; - tbl[m] = (x<<1)|(y<<8); - break; - case PIX_FMT_YUV420P: - x = shuf3[m] + slot/3; - y = serpent1[slot] + - ((seq + off[m]) % d->difseg_size)*3; - tbl[m] = (x<<1)|(y<<9); - break; - case PIX_FMT_YUV411P: - i = (seq + off[m]) % d->difseg_size; - k = slot + ((m==1||m==2)?3:0); - - x = l_start_shuffled[m] + k/6; - y = serpent2[k] + i*6; - if (x>21) - y = y*2 - i*6; - tbl[m] = (x<<2)|(y<<8); - break; - } - default: - break; - } - } -} - -static int dv_init_dynamic_tables(const DVprofile *d) -{ - int j,i,c,s,p; - uint32_t *factor1, *factor2; - const int *iweight1, *iweight2; - - if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) { - p = i = 0; - for (c=0; cn_difchan; c++) { - for (s=0; sdifseg_size; s++) { - p += 6; - for (j=0; j<27; j++) { - p += !(j%3); - if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) && - !(DV_PROFILE_IS_720p50(d) && s > 9)) { - dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]); - d->work_chunks[i++].buf_offset = p; - } - p += 5; - } - } - } - } - - if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) { - factor1 = &d->idct_factor[0]; - factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816]; - if (d->height == 720) { - iweight1 = &dv_iweight_720_y[0]; - iweight2 = &dv_iweight_720_c[0]; - } else { - iweight1 = &dv_iweight_1080_y[0]; - iweight2 = &dv_iweight_1080_c[0]; - } - if (DV_PROFILE_IS_HD(d)) { - for (c = 0; c < 4; c++) { - for (s = 0; s < 16; s++) { - for (i = 0; i < 64; i++) { - *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i]; - *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i]; - } - } - } - } else { - iweight1 = &dv_iweight_88[0]; - for (j = 0; j < 2; j++, iweight1 = &dv_iweight_248[0]) { - for (s = 0; s < 22; s++) { - for (i = c = 0; c < 4; c++) { - for (; i < dv_quant_areas[c]; i++) { - *factor1 = iweight1[i] << (dv_quant_shifts[s][c] + 1); - *factor2++ = (*factor1++) << 1; - } - } - } - } - } - } - - return 0; -} - -static av_cold 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; - - /* it's faster to include sign bit in a generic VLC parsing scheme */ - for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) { - new_dv_vlc_bits[j] = dv_vlc_bits[i]; - new_dv_vlc_len[j] = dv_vlc_len[i]; - new_dv_vlc_run[j] = dv_vlc_run[i]; - new_dv_vlc_level[j] = dv_vlc_level[i]; - - if (dv_vlc_level[i]) { - new_dv_vlc_bits[j] <<= 1; - new_dv_vlc_len[j]++; - - j++; - new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1; - new_dv_vlc_len[j] = dv_vlc_len[i] + 1; - new_dv_vlc_run[j] = dv_vlc_run[i]; - new_dv_vlc_level[j] = -dv_vlc_level[i]; - } - } - - /* NOTE: as a trick, we use the fact the no codes are unused - to accelerate the parsing of partial codes */ - init_vlc(&dv_vlc, TEX_VLC_BITS, j, - new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0); - assert(dv_vlc.table_size == 1184); - - for (i = 0; i < dv_vlc.table_size; i++){ - int code = dv_vlc.table[i][0]; - int len = dv_vlc.table[i][1]; - int level, run; - - if (len < 0){ //more bits needed - run = 0; - level = code; - } else { - run = new_dv_vlc_run [code] + 1; - level = new_dv_vlc_level[code]; - } - dv_rl_vlc[i].len = len; - dv_rl_vlc[i].level = level; - dv_rl_vlc[i].run = run; - } - free_vlc(&dv_vlc); - - dv_vlc_map_tableinit(); - } - - /* Generic DSP setup */ - dsputil_init(&dsp, avctx); - ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp); - s->get_pixels = dsp.get_pixels; - s->ildct_cmp = dsp.ildct_cmp[5]; - - /* 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] = ff_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); - - avctx->coded_frame = &s->picture; - s->avctx = avctx; - avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; - - return 0; -} - -static av_cold int dvvideo_init_encoder(AVCodecContext *avctx) -{ - if (!ff_dv_codec_profile(avctx)) { - av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n", - avctx->width, avctx->height, avcodec_get_pix_fmt_name(avctx->pix_fmt)); - return -1; - } - - return dvvideo_init(avctx); -} - -// #define VLC_DEBUG -// #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__) - -typedef struct BlockInfo { - const uint32_t *factor_table; - const uint8_t *scan_table; - uint8_t pos; /* position in block */ - void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); - uint8_t partial_bit_count; - uint16_t partial_bit_buffer; - int shift_offset; -} BlockInfo; - -/* 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 }; - -static inline int put_bits_left(PutBitContext* s) -{ - return (s->buf_end - s->buf) * 8 - put_bits_count(s); -} - -/* decode ac coefficients */ -static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) -{ - int last_index = gb->size_in_bits; - const uint8_t *scan_table = mb->scan_table; - const uint32_t *factor_table = mb->factor_table; - int pos = mb->pos; - int partial_bit_count = mb->partial_bit_count; - int level, 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; - - level = (level * factor_table[pos] + (1 << (dv_iweight_bits - 1))) >> dv_iweight_bits; - block[scan_table[pos]] = 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)); - } -} - -static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y) -{ - *mb_x = work_chunk->mb_coordinates[m] & 0xff; - *mb_y = work_chunk->mb_coordinates[m] >> 8; - - /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */ - if (s->sys->height == 720 && !(s->buf[1]&0x0C)) { - *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */ - } -} - -/* mb_x and mb_y are in units of 8 pixels */ -static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) -{ - DVVideoContext *s = avctx->priv_data; - DVwork_chunk *work_chunk = arg; - int quant, dc, dct_mode, class1, j; - int mb_index, mb_x, mb_y, last_index; - int y_stride, linesize; - DCTELEM *block, *block1; - int c_offset; - uint8_t *y_ptr; - const uint8_t *buf_ptr; - PutBitContext pb, vs_pb; - GetBitContext gb; - BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1; - LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]); - LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [80 + 4]); /* allow some slack */ - LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5 * 80 + 4]); /* allow some slack */ - const int log2_blocksize = 3-s->avctx->lowres; - int is_field_mode[5]; - - assert((((int)mb_bit_buffer) & 7) == 0); - assert((((int)vs_bit_buffer) & 7) == 0); - - memset(sblock, 0, 5*DV_MAX_BPM*sizeof(*sblock)); - - /* pass 1 : read DC and AC coefficients in blocks */ - buf_ptr = &s->buf[work_chunk->buf_offset*80]; - 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 += s->sys->bpm, block1 += s->sys->bpm * 64) { - /* skip header */ - quant = buf_ptr[3] & 0x0f; - buf_ptr += 4; - init_put_bits(&pb, mb_bit_buffer, 80); - mb = mb1; - block = block1; - is_field_mode[mb_index] = 0; - for (j = 0; j < s->sys->bpm; j++) { - last_index = s->sys->block_sizes[j]; - init_get_bits(&gb, buf_ptr, last_index); - - /* get the dc */ - dc = get_sbits(&gb, 9); - dct_mode = get_bits1(&gb); - class1 = get_bits(&gb, 2); - if (DV_PROFILE_IS_HD(s->sys)) { - mb->idct_put = s->idct_put[0]; - mb->scan_table = s->dv_zigzag[0]; - mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64]; - is_field_mode[mb_index] |= !j && dct_mode; - } else { - mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3]; - mb->scan_table = s->dv_zigzag[dct_mode]; - mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 + - (quant + dv_quant_offset[class1])*64]; - } - 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 < s->sys->bpm; 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 >= s->sys->bpm) - 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 < s->sys->bpm; 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(avctx, 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++) { - dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y); - - /* idct_put'ting luminance */ - if ((s->sys->pix_fmt == PIX_FMT_YUV420P) || - (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) || - (s->sys->height >= 720 && mb_y != 134)) { - y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize)); - } else { - y_stride = (2 << log2_blocksize); - } - y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize); - linesize = s->picture.linesize[0] << is_field_mode[mb_index]; - mb[0] .idct_put(y_ptr , linesize, block + 0*64); - if (s->sys->video_stype == 4) { /* SD 422 */ - mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64); - } else { - mb[1].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 1*64); - mb[2].idct_put(y_ptr + y_stride, linesize, block + 2*64); - mb[3].idct_put(y_ptr + (1 << log2_blocksize) + y_stride, linesize, block + 3*64); - } - mb += 4; - block += 4*64; - - /* idct_put'ting chrominance */ - c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] + - (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize); - for (j = 2; j; j--) { - uint8_t *c_ptr = s->picture.data[j] + c_offset; - 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_ptr1, *ptr1; - int x, y; - mb->idct_put(pixels, 8, block); - for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) { - ptr1 = pixels + (1 << (log2_blocksize - 1)); - c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize); - for (x = 0; x < (1 << (log2_blocksize - 1)); x++) { - c_ptr[x] = pixels[x]; - c_ptr1[x] = ptr1[x]; - } - } - block += 64; mb++; - } else { - y_stride = (mb_y == 134) ? (1 << log2_blocksize) : - s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize); - linesize = s->picture.linesize[j] << is_field_mode[mb_index]; - (mb++)-> idct_put(c_ptr , linesize, block); block += 64; - if (s->sys->bpm == 8) { - (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64; - } - } - } - } - return 0; -} - -#if CONFIG_SMALL -/* Converts run and level (where level != 0) pair into vlc, returning bit size */ -static av_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 av_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 av_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 av_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 av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, - PutBitContext* pb_pool, - PutBitContext* pb_end) -{ - int prev, 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 << size) - 1); - } - if (pb + 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 av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) { - if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) { - int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400; - if (ps > 0) { - int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) + - s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4); - return (ps > is); - } - } - - return 0; -} - -static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias) -{ - const int *weight; - const uint8_t* zigzag_scan; - LOCAL_ALIGNED_16(DCTELEM, blk, [64]); - 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; - - assert((((int)blk) & 15) == 0); - - bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0; - bi->partial_bit_count = 0; - bi->partial_bit_buffer = 0; - bi->cur_ac = 0; - if (data) { - bi->dct_mode = dv_guess_dct_mode(s, data, linesize); - s->get_pixels(blk, data, linesize); - s->fdct[bi->dct_mode](blk); - } else { - /* 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(blk, 0, 64*sizeof(*blk)); - bi->dct_mode = 0; - } - bi->mb[0] = blk[0]; - - zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct; - weight = bi->dct_mode ? dv_weight_248 : dv_weight_88; - - 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 < mb_area_start[area+1]; i++) { - int level = blk[zigzag_scan[i]]; - - if (level + 15 > 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 = (FFABS(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 (; i < mb_area_start[area+1]; i = bi->next[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; - } - - return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3]; -} - -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] ; k < mb_area_start[a+1]; k = b->next[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 int dv_encode_video_segment(AVCodecContext *avctx, void *arg) -{ - DVVideoContext *s = avctx->priv_data; - DVwork_chunk *work_chunk = arg; - int mb_index, i, j; - int mb_x, mb_y, c_offset, linesize, y_stride; - uint8_t* y_ptr; - uint8_t* dif; - uint8_t scratch[64]; - EncBlockInfo enc_blks[5*DV_MAX_BPM]; - PutBitContext pbs[5*DV_MAX_BPM]; - PutBitContext* pb; - EncBlockInfo* enc_blk; - int vs_bit_size = 0; - int qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */ - int* qnosp = &qnos[0]; - - dif = &s->buf[work_chunk->buf_offset*80]; - enc_blk = &enc_blks[0]; - for (mb_index = 0; mb_index < 5; mb_index++) { - dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y); - - /* initializing luminance blocks */ - if ((s->sys->pix_fmt == PIX_FMT_YUV420P) || - (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) || - (s->sys->height >= 720 && mb_y != 134)) { - y_stride = s->picture.linesize[0] << 3; - } else { - y_stride = 16; - } - y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3); - linesize = s->picture.linesize[0]; - - if (s->sys->video_stype == 4) { /* SD 422 */ - vs_bit_size += - dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) + - dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) + - dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) + - dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0); - } else { - vs_bit_size += - dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) + - dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) + - dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) + - dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0); - } - enc_blk += 4; - - /* initializing chrominance blocks */ - c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] + - (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3); - for (j = 2; j; j--) { - uint8_t *c_ptr = s->picture.data[j] + c_offset; - linesize = s->picture.linesize[j]; - y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3); - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { - uint8_t* d; - uint8_t* b = scratch; - for (i = 0; i < 8; i++) { - d = c_ptr + (linesize << 3); - b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3]; - b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3]; - c_ptr += linesize; - b += 8; - } - c_ptr = scratch; - linesize = 8; - } - - vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1); - if (s->sys->bpm == 8) { - vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1); - } - } - } - - if (vs_total_ac_bits < vs_bit_size) - dv_guess_qnos(&enc_blks[0], qnosp); - - /* DIF encoding process */ - for (j=0; j<5*s->sys->bpm;) { - int start_mb = j; - - dif[3] = *qnosp++; - dif += 4; - - /* First pass over individual cells only */ - for (i=0; isys->bpm; i++, j++) { - int sz = s->sys->block_sizes[i]>>3; - - init_put_bits(&pbs[j], dif, sz); - put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2); - put_bits(&pbs[j], 1, enc_blks[j].dct_mode); - put_bits(&pbs[j], 2, enc_blks[j].cno); - - dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]); - dif += sz; - } - - /* Second pass over each MB space */ - pb = &pbs[start_mb]; - for (i=0; isys->bpm; i++) { - if (enc_blks[start_mb+i].partial_bit_count) - pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]); - } - } - - /* Third and final pass over the whole video segment space */ - pb = &pbs[0]; - for (j=0; j<5*s->sys->bpm; j++) { - if (enc_blks[j].partial_bit_count) - pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]); - if (enc_blks[j].partial_bit_count) - av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n"); - } - - for (j=0; j<5*s->sys->bpm; j++) { - int pos; - int size = pbs[j].size_in_bits >> 3; - flush_put_bits(&pbs[j]); - pos = put_bits_count(&pbs[j]) >> 3; - if (pos > size) { - av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n"); - return -1; - } - memset(pbs[j].buf + pos, 0xff, size - pos); - } - - return 0; -} - -#if CONFIG_DVVIDEO_DECODER -/* 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - DVVideoContext *s = avctx->priv_data; - - s->sys = ff_dv_frame_profile(s->sys, buf, buf_size); - if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) { - av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n"); - 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; - avctx->time_base = s->sys->time_base; - 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_video_segment, s->sys->work_chunks, NULL, - dv_work_pool_size(s->sys), sizeof(DVwork_chunk)); - - emms_c(); - - /* return image */ - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->picture; - - return s->sys->frame_size; -} -#endif /* CONFIG_DVVIDEO_DECODER */ - - -static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c, - uint8_t* buf) -{ - /* - * Here's what SMPTE314M says about these two: - * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical - * as track application IDs (APTn = 001, AP1n = - * 001, AP2n = 001, AP3n = 001), if the source signal - * comes from a digital VCR. If the signal source is - * unknown, all bits for these data shall be set to 1. - * (page 12) STYPE: STYPE defines a signal type of video signal - * 00000b = 4:1:1 compression - * 00100b = 4:2:2 compression - * XXXXXX = Reserved - * Now, I've got two problems with these statements: - * 1. it looks like APT == 111b should be a safe bet, but it isn't. - * It seems that for PAL as defined in IEC 61834 we have to set - * APT to 000 and for SMPTE314M to 001. - * 2. It is not at all clear what STYPE is used for 4:2:0 PAL - * compression scheme (if any). - */ - int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1); - - uint8_t aspect = 0; - if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */ - aspect = 0x02; - - buf[0] = (uint8_t)pack_id; - switch (pack_id) { - case dv_header525: /* I can't imagine why these two weren't defined as real */ - case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */ - buf[1] = 0xf8 | /* reserved -- always 1 */ - (apt & 0x07); /* APT: Track application ID */ - buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP1: Audio application ID */ - buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP2: Video application ID */ - buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP3: Subcode application ID */ - break; - case dv_video_source: - buf[1] = 0xff; /* reserved -- always 1 */ - buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */ - (1 << 6) | /* following CLF is valid - 0, invalid - 1 */ - (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */ - 0xf; /* reserved -- always 1 */ - buf[3] = (3 << 6) | /* reserved -- always 1 */ - (c->sys->dsf << 5) | /* system: 60fields/50fields */ - c->sys->video_stype; /* signal type video compression */ - buf[4] = 0xff; /* VISC: 0xff -- no information */ - break; - case dv_video_control: - buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */ - 0x3f; /* reserved -- always 1 */ - buf[2] = 0xc8 | /* reserved -- always b11001xxx */ - aspect; - buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */ - (1 << 6) | /* first/second field flag 0 -- field 2, 1 -- field 1 */ - (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */ - (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */ - 0xc; /* reserved -- always b1100 */ - buf[4] = 0xff; /* reserved -- always 1 */ - break; - default: - buf[1] = buf[2] = buf[3] = buf[4] = 0xff; - } - return 5; -} - -#if CONFIG_DVVIDEO_ENCODER -static void dv_format_frame(DVVideoContext* c, uint8_t* buf) -{ - int chan, i, j, k; - - for (chan = 0; chan < c->sys->n_difchan; chan++) { - for (i = 0; i < c->sys->difseg_size; i++) { - memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */ - - /* DV header: 1DIF */ - buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf); - buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf); - buf += 72; /* unused bytes */ - - /* DV subcode: 2DIFs */ - for (j = 0; j < 2; j++) { - buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf); - for (k = 0; k < 6; k++) - buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5; - buf += 29; /* unused bytes */ - } - - /* DV VAUX: 3DIFS */ - for (j = 0; j < 3; j++) { - buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf); - buf += dv_write_pack(dv_video_source, c, buf); - buf += dv_write_pack(dv_video_control, c, buf); - buf += 7*5; - buf += dv_write_pack(dv_video_source, c, buf); - buf += dv_write_pack(dv_video_control, c, buf); - buf += 4*5 + 2; /* unused bytes */ - } - - /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */ - for (j = 0; j < 135; j++) { - if (j%15 == 0) { - memset(buf, 0xff, 80); - buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf); - buf += 77; /* audio control & shuffled PCM audio */ - } - buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf); - buf += 77; /* 1 video macroblock: 1 bytes control - 4 * 14 bytes Y 8x8 data - 10 bytes Cr 8x8 data - 10 bytes Cb 8x8 data */ - } - } - } -} - - -static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, - void *data) -{ - DVVideoContext *s = c->priv_data; - - s->sys = ff_dv_codec_profile(c); - if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) - 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_video_segment, s->sys->work_chunks, NULL, - dv_work_pool_size(s->sys), sizeof(DVwork_chunk)); - - emms_c(); - - dv_format_frame(s, buf); - - return s->sys->frame_size; -} -#endif - -static int dvvideo_close(AVCodecContext *c) -{ - DVVideoContext *s = c->priv_data; - - if (s->picture.data[0]) - c->release_buffer(c, &s->picture); - - return 0; -} - - -#if CONFIG_DVVIDEO_ENCODER -AVCodec dvvideo_encoder = { - "dvvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DVVIDEO, - sizeof(DVVideoContext), - dvvideo_init_encoder, - dvvideo_encode_frame, - .pix_fmts = (const enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), -}; -#endif // CONFIG_DVVIDEO_ENCODER - -#if CONFIG_DVVIDEO_DECODER -AVCodec dvvideo_decoder = { - "dvvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DVVIDEO, - sizeof(DVVideoContext), - dvvideo_init, - NULL, - dvvideo_close, - dvvideo_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/dv_tablegen.c b/tizen/distrib/ffmpeg/libavcodec/dv_tablegen.c deleted file mode 100644 index 0e2b39d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dv_tablegen.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Generate a header file for hardcoded DV tables - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#define CONFIG_HARDCODED_TABLES 0 -#ifndef CONFIG_SMALL -#error CONFIG_SMALL must be defined to generate tables -#endif -#include "dv_tablegen.h" -#include "tableprint.h" -#include - -WRITE_1D_FUNC_ARGV(vlc_pair, struct dv_vlc_pair, 7, - "{0x%"PRIx32", %"PRId8"}", data[i].vlc, data[i].size) -WRITE_2D_FUNC(vlc_pair, struct dv_vlc_pair) - -int main(void) -{ - dv_vlc_map_tableinit(); - - write_fileheader(); - - printf("static const struct dv_vlc_pair dv_vlc_map[DV_VLC_MAP_RUN_SIZE][DV_VLC_MAP_LEV_SIZE] = {\n"); - write_vlc_pair_2d_array(dv_vlc_map, DV_VLC_MAP_RUN_SIZE, DV_VLC_MAP_LEV_SIZE); - printf("};\n"); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/dv_tablegen.h b/tizen/distrib/ffmpeg/libavcodec/dv_tablegen.h deleted file mode 100644 index ee6e822..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dv_tablegen.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Header file for hardcoded DV tables - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DV_TABLEGEN_H -#define DV_TABLEGEN_H - -#include -#include "dv_vlc_data.h" - -#if CONFIG_SMALL -#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 - -/* VLC encoding lookup table */ -struct dv_vlc_pair { - uint32_t vlc; - uint32_t size; -}; - -#if CONFIG_HARDCODED_TABLES -#define dv_vlc_map_tableinit() -#include "libavcodec/dv_tables.h" -#else -static struct dv_vlc_pair dv_vlc_map[DV_VLC_MAP_RUN_SIZE][DV_VLC_MAP_LEV_SIZE]; - -static void dv_vlc_map_tableinit(void) -{ - int i, j; - for (i = 0; i < NB_DV_VLC - 1; i++) { - if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE) - continue; -#if CONFIG_SMALL - 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++) { -#if CONFIG_SMALL - 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 - } -} -#endif /* CONFIG_HARDCODED_TABLES */ - -#endif /* DV_TABLEGEN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dv_vlc_data.h b/tizen/distrib/ffmpeg/libavcodec/dv_vlc_data.h deleted file mode 100644 index c23c564..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dv_vlc_data.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * VLC constants for DV codec - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VLC constants for DV codec. - */ - -#ifndef AVCODEC_DV_VLC_DATA_H -#define AVCODEC_DV_VLC_DATA_H - -#include - -#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, -}; - -#endif /* AVCODEC_DV_VLC_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dvbsub.c b/tizen/distrib/ffmpeg/libavcodec/dvbsub.c deleted file mode 100644 index 0f09826..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvbsub.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * DVB subtitle encoding for ffmpeg - * Copyright (c) 2005 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "bytestream.h" -#include "colorspace.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; -} - -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 */ - bytestream_put_be16(&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 */ - bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */ - bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */ - } - - bytestream_put_be16(&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 */ - bytestream_put_be16(&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; - uint32_t x= ((uint32_t*)h->rects[clut_id]->pict.data[1])[i]; - a = (x >> 24) & 0xff; - r = (x >> 16) & 0xff; - g = (x >> 8) & 0xff; - b = (x >> 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; - } - } - - bytestream_put_be16(&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 */ - bytestream_put_be16(&q, page_id); - pseg_len = q; - q += 2; /* segment length */ - *q++ = region_id; - *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ - bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */ - bytestream_put_be16(&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) { - bytestream_put_be16(&q, region_id); /* object_id == region_id */ - *q++ = (0 << 6) | (0 << 4); - *q++ = 0; - *q++ = 0xf0; - *q++ = 0; - } - - bytestream_put_be16(&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; - bytestream_put_be16(&q, page_id); - pseg_len = q; - q += 2; /* segment length */ - - bytestream_put_be16(&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]->pict.data[0], 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]->pict.data[0] + h->rects[object_id]->w, - h->rects[object_id]->w * 2, h->rects[object_id]->w, - h->rects[object_id]->h >> 1); - - bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr); - bytestream_put_be16(&pbottom_field_len, q - bottom_ptr); - } - - bytestream_put_be16(&pseg_len, q - pseg_len - 2); - } - } - - /* end of display set segment */ - - *q++ = 0x0f; /* sync_byte */ - *q++ = 0x80; /* segment_type */ - bytestream_put_be16(&q, page_id); - pseg_len = q; - q += 2; /* segment length */ - - bytestream_put_be16(&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_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", - AVMEDIA_TYPE_SUBTITLE, - CODEC_ID_DVB_SUBTITLE, - sizeof(DVBSubtitleContext), - NULL, - dvbsub_encode, - .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dvbsub_parser.c b/tizen/distrib/ffmpeg/libavcodec/dvbsub_parser.c deleted file mode 100644 index c9ccfd0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvbsub_parser.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * DVB subtitle parser for FFmpeg - * Copyright (c) 2005 Ian Caulfield - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "get_bits.h" - -//#define DEBUG -//#define DEBUG_PACKET_CONTENTS - -/* 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 av_cold 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, - const 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; - - dprintf(avctx, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n", - s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]); - -#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->pts != AV_NOPTS_VALUE) /* Start of a new packet */ - { - if (pc->packet_index != pc->packet_start) - { - dprintf(avctx, "Discarding %d bytes\n", - pc->packet_index - pc->packet_start); - } - - pc->packet_start = 0; - pc->packet_index = 0; - - if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) { - dprintf(avctx, "Bad packet header\n"); - 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 = AV_RB16(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) - { - dprintf(avctx, "Junk at end of packet\n"); - } - 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->pts == AV_NOPTS_VALUE) - s->pts = s->last_pts; - - return buf_size; -} - -static av_cold 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/tizen/distrib/ffmpeg/libavcodec/dvbsubdec.c b/tizen/distrib/ffmpeg/libavcodec/dvbsubdec.c deleted file mode 100644 index 54c74b5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvbsubdec.c +++ /dev/null @@ -1,1424 +0,0 @@ -/* - * DVB subtitle decoding for ffmpeg - * Copyright (c) 2005 Ian Caulfield - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "get_bits.h" -#include "colorspace.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 - -#define cm (ff_cropTbl + MAX_NEG_CROP) - -#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, sizeof(fname), "%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, sizeof(fname2), "%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, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); - system(command); - - snprintf(command, sizeof(command), "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 fgcolor; - int bgcolor; - - 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 bgcolor; - - 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 && 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 && 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 && 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) { - display = region->display_list; - - object = get_object(ctx, display->object_id); - - if (object) { - obj_disp_ptr = &object->display_list; - obj_disp = *obj_disp_ptr; - - while (obj_disp && obj_disp != display) { - obj_disp_ptr = &obj_disp->object_list_next; - obj_disp = *obj_disp_ptr; - } - - if (obj_disp) { - *obj_disp_ptr = obj_disp->object_list_next; - - if (!object->display_list) { - obj2_ptr = &ctx->object_list; - obj2 = *obj2_ptr; - - while (obj2 != object) { - assert(obj2); - obj2_ptr = &obj2->next; - obj2 = *obj2_ptr; - } - - *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) { - region = ctx->region_list; - - ctx->region_list = region->next; - - delete_region_display_list(ctx, region); - if (region->pbuf) - av_free(region->pbuf); - - av_free(region); - } - - while (ctx->clut_list) { - clut = ctx->clut_list; - - ctx->clut_list = clut->next; - - av_free(clut); - } - - /* Should already be null */ - if (ctx->object_list) - av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); -} - -static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) -{ - int i, r, g, b, a = 0; - DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - - 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 av_cold int dvbsub_close_decoder(AVCodecContext *avctx) -{ - DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - DVBSubRegionDisplay *display; - - delete_state(ctx); - - while (ctx->display_list) { - 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, - const 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 << 3); - - while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) { - bits = get_bits(&gb, 2); - - if (bits) { - if (non_mod != 1 || bits != 1) { - if (map_table) - *destbuf++ = map_table[bits]; - else - *destbuf++ = bits; - } - pixels_read++; - } else { - bits = get_bits1(&gb); - 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) - bits = map_table[bits]; - while (run_length-- > 0 && pixels_read < dbuf_len) { - *destbuf++ = bits; - pixels_read++; - } - } - } else { - bits = get_bits1(&gb); - 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) - 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) - 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) - 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) - bits = map_table[0]; - else - bits = 0; - *destbuf++ = bits; - pixels_read++; - } - } - } - } - - if (get_bits(&gb, 6)) - 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, - const 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 << 3); - - while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) { - bits = get_bits(&gb, 4); - - if (bits) { - if (non_mod != 1 || bits != 1) { - if (map_table) - *destbuf++ = map_table[bits]; - else - *destbuf++ = bits; - } - pixels_read++; - } else { - bits = get_bits1(&gb); - 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) - bits = map_table[0]; - else - bits = 0; - - while (run_length-- > 0 && pixels_read < dbuf_len) { - *destbuf++ = bits; - pixels_read++; - } - } else { - bits = get_bits1(&gb); - 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) - 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) - 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) - 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) - bits = map_table[0]; - else - bits = 0; - if (pixels_read <= dbuf_len) { - *destbuf++ = bits; - *destbuf++ = bits; - } - } else { - if (map_table) - bits = map_table[0]; - else - bits = 0; - *destbuf++ = bits; - pixels_read ++; - } - } - } - } - } - - if (get_bits(&gb, 8)) - 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, - const uint8_t **srcbuf, int buf_size, - int non_mod, uint8_t *map_table) -{ - const 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) { - if (non_mod != 1 || bits != 1) { - if (map_table) - *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) - 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) - bits = map_table[bits]; - else while (run_length-- > 0 && pixels_read < dbuf_len) { - *destbuf++ = bits; - pixels_read++; - } - } - } - } - - if (*(*srcbuf)++) - 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, - const 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); - const 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; - - dprintf(avctx, "DVB pixel block size %d, %s field:\n", buf_size, - top_bottom ? "bottom" : "top"); - -#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) - 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, - const uint8_t *buf, int buf_size) -{ - DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - - const uint8_t *buf_end = buf + buf_size; - const uint8_t *block; - int object_id; - DVBSubObject *object; - DVBSubObjectDisplay *display; - int top_field_len, bottom_field_len; - - int coding_method, non_modifying_color; - - object_id = AV_RB16(buf); - buf += 2; - - object = get_object(ctx, object_id); - - if (!object) - return; - - coding_method = ((*buf) >> 2) & 3; - non_modifying_color = ((*buf++) >> 1) & 1; - - if (coding_method == 0) { - top_field_len = AV_RB16(buf); - buf += 2; - bottom_field_len = AV_RB16(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; display = display->object_list_next) { - block = buf; - - dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0, - non_modifying_color); - - 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_color); - } - -/* } else if (coding_method == 1) {*/ - - } else { - av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method); - } - -} - -static void dvbsub_parse_clut_segment(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - - const 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) - av_log(avctx, AV_LOG_INFO, "\n"); - -#endif - - clut_id = *buf++; - buf += 1; - - clut = get_clut(ctx, clut_id); - - if (!clut) { - 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); - - dprintf(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); - - 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, - const uint8_t *buf, int buf_size) -{ - DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - - const 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) { - region = av_mallocz(sizeof(DVBSubRegion)); - - region->id = region_id; - - region->next = ctx->region_list; - ctx->region_list = region; - } - - fill = ((*buf++) >> 3) & 1; - - region->width = AV_RB16(buf); - buf += 2; - region->height = AV_RB16(buf); - buf += 2; - - if (region->width * region->height != region->buf_size) { - if (region->pbuf) - 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); - if(region->depth<2 || region->depth>8){ - av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth); - region->depth= 4; - } - region->clut = *buf++; - - if (region->depth == 8) - region->bgcolor = *buf++; - else { - buf += 1; - - if (region->depth == 4) - region->bgcolor = (((*buf++) >> 4) & 15); - else - region->bgcolor = (((*buf++) >> 2) & 3); - } - - dprintf(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height); - - if (fill) { - memset(region->pbuf, region->bgcolor, region->buf_size); - dprintf(avctx, "Fill region (%d)\n", region->bgcolor); - } - - delete_region_display_list(ctx, region); - - while (buf + 5 < buf_end) { - object_id = AV_RB16(buf); - buf += 2; - - object = get_object(ctx, object_id); - - if (!object) { - 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 = AV_RB16(buf) & 0xfff; - buf += 2; - display->y_pos = AV_RB16(buf) & 0xfff; - buf += 2; - - if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) { - display->fgcolor = *buf++; - display->bgcolor = *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, - const uint8_t *buf, int buf_size) -{ - DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - DVBSubRegionDisplay *display; - DVBSubRegionDisplay *tmp_display_list, **tmp_ptr; - - const 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; - - dprintf(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state); - - 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 && display->region_id != region_id) { - tmp_ptr = &display->next; - display = display->next; - } - - if (!display) - display = av_mallocz(sizeof(DVBSubRegionDisplay)); - - display->region_id = region_id; - - display->x_pos = AV_RB16(buf); - buf += 2; - display->y_pos = AV_RB16(buf); - buf += 2; - - *tmp_ptr = display->next; - - display->next = ctx->display_list; - ctx->display_list = display; - ctx->display_list_size++; - - dprintf(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos); - } - - while (tmp_display_list) { - 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; 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; 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, sizeof(filename), "dvbs.%d", fileno_index); - - png_save2(filename, pbuf, width, height); - - av_free(pbuf); - } - - fileno_index++; -} -#endif - -static int dvbsub_display_end_segment(AVCodecContext *avctx, const 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(*sub->rects) * sub->num_rects); - for(i=0; inum_rects; i++) - sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); - } - - i = 0; - - for (display = ctx->display_list; display; display = display->next) { - region = get_region(ctx, display->region_id); - rect = sub->rects[i]; - - if (!region) - continue; - - rect->x = display->x_pos; - rect->y = display->y_pos; - rect->w = region->width; - rect->h = region->height; - rect->nb_colors = 16; - rect->type = SUBTITLE_BITMAP; - rect->pict.linesize[0] = region->width; - - clut = get_clut(ctx, region->clut); - - if (!clut) - 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->pict.data[1] = av_mallocz(AVPALETTE_SIZE); - memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t)); - - rect->pict.data[0] = av_malloc(region->buf_size); - memcpy(rect->pict.data[0], 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - AVSubtitle *sub = (AVSubtitle*) data; - const 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) - 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 = AV_RB16(p); - p += 2; - segment_length = AV_RB16(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: - dprintf(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n", - segment_type, page_id, segment_length); - break; - } - } - - p += segment_length; - } - - if (p != p_end) { - dprintf(avctx, "Junk at end of packet\n"); - return -1; - } - - return buf_size; -} - - -AVCodec dvbsub_decoder = { - "dvbsub", - AVMEDIA_TYPE_SUBTITLE, - CODEC_ID_DVB_SUBTITLE, - sizeof(DVBSubContext), - dvbsub_init_decoder, - NULL, - dvbsub_close_decoder, - dvbsub_decode, - .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dvdata.c b/tizen/distrib/ffmpeg/libavcodec/dvdata.c deleted file mode 100644 index 7232baf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvdata.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Constants for DV codec - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Constants for DV codec. - */ - -#include "libavutil/rational.h" -#include "avcodec.h" -#include "dvdata.h" - -static DVwork_chunk work_chunks_dv25pal [1*12*27]; -static DVwork_chunk work_chunks_dv25pal411[1*12*27]; -static DVwork_chunk work_chunks_dv25ntsc [1*10*27]; -static DVwork_chunk work_chunks_dv50pal [2*12*27]; -static DVwork_chunk work_chunks_dv50ntsc [2*10*27]; -static DVwork_chunk work_chunks_dv100palp [2*12*27]; -static DVwork_chunk work_chunks_dv100ntscp[2*10*27]; -static DVwork_chunk work_chunks_dv100pali [4*12*27]; -static DVwork_chunk work_chunks_dv100ntsci[4*10*27]; - -static uint32_t dv_idct_factor_sd [2*2*22*64]; -static uint32_t dv_idct_factor_hd1080[2*4*16*64]; -static uint32_t dv_idct_factor_hd720 [2*4*16*64]; - -static const DVprofile dv_profiles[] = { - { .dsf = 0, - .video_stype = 0x0, - .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */ - .difseg_size = 10, - .n_difchan = 1, - .time_base = { 1001, 30000 }, - .ltc_divisor = 30, - .height = 480, - .width = 720, - .sar = {{10, 11}, {40, 33}}, - .work_chunks = &work_chunks_dv25ntsc[0], - .idct_factor = &dv_idct_factor_sd[0], - .pix_fmt = PIX_FMT_YUV411P, - .bpm = 6, - .block_sizes = block_sizes_dv2550, - .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, - .video_stype = 0x0, - .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */ - .difseg_size = 12, - .n_difchan = 1, - .time_base = { 1, 25 }, - .ltc_divisor = 25, - .height = 576, - .width = 720, - .sar = {{59, 54}, {118, 81}}, - .work_chunks = &work_chunks_dv25pal[0], - .idct_factor = &dv_idct_factor_sd[0], - .pix_fmt = PIX_FMT_YUV420P, - .bpm = 6, - .block_sizes = block_sizes_dv2550, - .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, - .video_stype = 0x0, - .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */ - .difseg_size = 12, - .n_difchan = 1, - .time_base = { 1, 25 }, - .ltc_divisor = 25, - .height = 576, - .width = 720, - .sar = {{59, 54}, {118, 81}}, - .work_chunks = &work_chunks_dv25pal411[0], - .idct_factor = &dv_idct_factor_sd[0], - .pix_fmt = PIX_FMT_YUV411P, - .bpm = 6, - .block_sizes = block_sizes_dv2550, - .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, - .video_stype = 0x4, - .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */ - .difseg_size = 10, /* also known as "DVCPRO50" */ - .n_difchan = 2, - .time_base = { 1001, 30000 }, - .ltc_divisor = 30, - .height = 480, - .width = 720, - .sar = {{10, 11}, {40, 33}}, - .work_chunks = &work_chunks_dv50ntsc[0], - .idct_factor = &dv_idct_factor_sd[0], - .pix_fmt = PIX_FMT_YUV422P, - .bpm = 6, - .block_sizes = block_sizes_dv2550, - .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, - .video_stype = 0x4, - .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */ - .difseg_size = 12, /* also known as "DVCPRO50" */ - .n_difchan = 2, - .time_base = { 1, 25 }, - .ltc_divisor = 25, - .height = 576, - .width = 720, - .sar = {{59, 54}, {118, 81}}, - .work_chunks = &work_chunks_dv50pal[0], - .idct_factor = &dv_idct_factor_sd[0], - .pix_fmt = PIX_FMT_YUV422P, - .bpm = 6, - .block_sizes = block_sizes_dv2550, - .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, - .video_stype = 0x14, - .frame_size = 480000, /* SMPTE-370M - 1080i60 100 Mbps */ - .difseg_size = 10, /* also known as "DVCPRO HD" */ - .n_difchan = 4, - .time_base = { 1001, 30000 }, - .ltc_divisor = 30, - .height = 1080, - .width = 1280, - .sar = {{1, 1}, {3, 2}}, - .work_chunks = &work_chunks_dv100ntsci[0], - .idct_factor = &dv_idct_factor_hd1080[0], - .pix_fmt = PIX_FMT_YUV422P, - .bpm = 8, - .block_sizes = block_sizes_dv100, - .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, - .video_stype = 0x14, - .frame_size = 576000, /* SMPTE-370M - 1080i50 100 Mbps */ - .difseg_size = 12, /* also known as "DVCPRO HD" */ - .n_difchan = 4, - .time_base = { 1, 25 }, - .ltc_divisor = 25, - .height = 1080, - .width = 1440, - .sar = {{1, 1}, {4, 3}}, - .work_chunks = &work_chunks_dv100pali[0], - .idct_factor = &dv_idct_factor_hd1080[0], - .pix_fmt = PIX_FMT_YUV422P, - .bpm = 8, - .block_sizes = block_sizes_dv100, - .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, - .video_stype = 0x18, - .frame_size = 240000, /* SMPTE-370M - 720p60 100 Mbps */ - .difseg_size = 10, /* also known as "DVCPRO HD" */ - .n_difchan = 2, - .time_base = { 1001, 60000 }, - .ltc_divisor = 60, - .height = 720, - .width = 960, - .sar = {{1, 1}, {4, 3}}, - .work_chunks = &work_chunks_dv100ntscp[0], - .idct_factor = &dv_idct_factor_hd720[0], - .pix_fmt = PIX_FMT_YUV422P, - .bpm = 8, - .block_sizes = block_sizes_dv100, - .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, - .video_stype = 0x18, - .frame_size = 288000, /* SMPTE-370M - 720p50 100 Mbps */ - .difseg_size = 12, /* also known as "DVCPRO HD" */ - .n_difchan = 2, - .time_base = { 1, 50 }, - .ltc_divisor = 50, - .height = 720, - .width = 960, - .sar = {{1, 1}, {4, 3}}, - .work_chunks = &work_chunks_dv100palp[0], - .idct_factor = &dv_idct_factor_hd720[0], - .pix_fmt = PIX_FMT_YUV422P, - .bpm = 8, - .block_sizes = block_sizes_dv100, - .audio_stride = 90, - .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, - .video_stype = 0x1, - .frame_size = 144000, /* IEC 61883-5 - 625/50 (PAL) */ - .difseg_size = 12, - .n_difchan = 1, - .time_base = { 1, 25 }, - .ltc_divisor = 25, - .height = 576, - .width = 720, - .sar = {{59, 54}, {118, 81}}, - .work_chunks = &work_chunks_dv25pal[0], - .idct_factor = &dv_idct_factor_sd[0], - .pix_fmt = PIX_FMT_YUV420P, - .bpm = 6, - .block_sizes = block_sizes_dv2550, - .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, - } -}; - -const DVprofile* ff_dv_frame_profile(const DVprofile *sys, - const uint8_t* frame, unsigned buf_size) -{ - int i; - - int dsf = (frame[3] & 0x80) >> 7; - - int stype = frame[80*5 + 48 + 3] & 0x1f; - - /* 576i50 25Mbps 4:1:1 is a special case */ - if (dsf == 1 && stype == 0 && frame[5] & 0x07) { - return &dv_profiles[2]; - } - - for (i=0; iframe_size) - return sys; - - return NULL; -} - -const DVprofile* ff_dv_codec_profile(AVCodecContext* codec) -{ - int i; - - for (i=0; iheight == dv_profiles[i].height && - codec->pix_fmt == dv_profiles[i].pix_fmt && - codec->width == dv_profiles[i].width) - return &dv_profiles[i]; - - return NULL; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/dvdata.h b/tizen/distrib/ffmpeg/libavcodec/dvdata.h deleted file mode 100644 index 90f4059..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvdata.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Constants for DV codec - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Constants for DV codec. - */ - -#ifndef AVCODEC_DVDATA_H -#define AVCODEC_DVDATA_H - -#include "libavutil/rational.h" -#include "avcodec.h" - -typedef struct DVwork_chunk { - uint16_t buf_offset; - uint16_t mb_coordinates[5]; -} DVwork_chunk; - -/* - * 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 video_stype; /* stype for VAUX source pack */ - 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 */ - AVRational time_base; /* 1/framerate */ - 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 */ - DVwork_chunk *work_chunks; /* each thread gets its own chunk of frame to work on */ - uint32_t *idct_factor; /* set of iDCT factor tables */ - enum PixelFormat pix_fmt; /* picture pixel format */ - int bpm; /* blocks per macroblock */ - const uint8_t *block_sizes; /* AC block sizes, in bits */ - int audio_stride; /* size of audio_shuffle table */ - int audio_min_samples[3]; /* min amount 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 uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */ -} DVprofile; - -/* unquant tables (not used directly) */ -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 }; -static const uint8_t dv_quant_areas[4] = { 6, 21, 43, 64 }; - -/* quantization quanta by QNO for DV100 */ -static const uint8_t dv100_qstep[16] = { - 1, /* QNO = 0 and 1 both have no quantization */ - 1, - 2, 3, 4, 5, 6, 7, 8, 16, 18, 20, 22, 24, 28, 52 -}; - -/* 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, -}; - -/** - * The "inverse" DV100 weights are actually just the spec weights (zig-zagged). - */ -static const int dv_iweight_1080_y[64] = { - 128, 16, 16, 17, 17, 17, 18, 18, - 18, 18, 18, 18, 19, 18, 18, 19, - 19, 19, 19, 19, 19, 42, 38, 40, - 40, 40, 38, 42, 44, 43, 41, 41, - 41, 41, 43, 44, 45, 45, 42, 42, - 42, 45, 45, 48, 46, 43, 43, 46, - 48, 49, 48, 44, 48, 49, 101, 98, - 98, 101, 104, 109, 104, 116, 116, 123, -}; -static const int dv_iweight_1080_c[64] = { - 128, 16, 16, 17, 17, 17, 25, 25, - 25, 25, 26, 25, 26, 25, 26, 26, - 26, 27, 27, 26, 26, 42, 38, 40, - 40, 40, 38, 42, 44, 43, 41, 41, - 41, 41, 43, 44, 91, 91, 84, 84, - 84, 91, 91, 96, 93, 86, 86, 93, - 96, 197, 191, 177, 191, 197, 203, 197, - 197, 203, 209, 219, 209, 232, 232, 246, -}; -static const int dv_iweight_720_y[64] = { - 128, 16, 16, 17, 17, 17, 18, 18, - 18, 18, 18, 18, 19, 18, 18, 19, - 19, 19, 19, 19, 19, 42, 38, 40, - 40, 40, 38, 42, 44, 43, 41, 41, - 41, 41, 43, 44, 68, 68, 63, 63, - 63, 68, 68, 96, 92, 86, 86, 92, - 96, 98, 96, 88, 96, 98, 202, 196, - 196, 202, 208, 218, 208, 232, 232, 246, -}; -static const int dv_iweight_720_c[64] = { - 128, 24, 24, 26, 26, 26, 36, 36, - 36, 36, 36, 36, 38, 36, 36, 38, - 38, 38, 38, 38, 38, 84, 76, 80, - 80, 80, 76, 84, 88, 86, 82, 82, - 82, 82, 86, 88, 182, 182, 168, 168, - 168, 182, 182, 192, 186, 192, 172, 186, - 192, 394, 382, 354, 382, 394, 406, 394, - 394, 406, 418, 438, 418, 464, 464, 492, -}; - -static const uint8_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 uint8_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 av_unused int dv_audio_frequency[3] = { - 48000, 44100, 32000, -}; - -/* macroblock bit budgets */ -static const uint8_t block_sizes_dv2550[8] = { - 112, 112, 112, 112, 80, 80, 0, 0, -}; - -static const uint8_t block_sizes_dv100[8] = { - 80, 80, 80, 80, 80, 80, 64, 64, -}; - -enum dv_section_type { - dv_sect_header = 0x1f, - dv_sect_subcode = 0x3f, - dv_sect_vaux = 0x56, - dv_sect_audio = 0x76, - dv_sect_video = 0x96, -}; - -enum dv_pack_type { - dv_header525 = 0x3f, /* see dv_write_pack for important details on */ - dv_header625 = 0xbf, /* these two packs */ - dv_timecode = 0x13, - dv_audio_source = 0x50, - dv_audio_control = 0x51, - dv_audio_recdate = 0x52, - dv_audio_rectime = 0x53, - dv_video_source = 0x60, - dv_video_control = 0x61, - dv_video_recdate = 0x62, - dv_video_rectime = 0x63, - dv_unknown_pack = 0xff, -}; - -#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10) -#define DV_PROFILE_IS_1080i50(p) (((p)->video_stype == 0x14) && ((p)->dsf == 1)) -#define DV_PROFILE_IS_720p50(p) (((p)->video_stype == 0x18) && ((p)->dsf == 1)) - -/* 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 (1080i50) - */ -#define DV_MAX_FRAME_SIZE 576000 - -/** - * maximum number of blocks per macroblock in any DV format - */ -#define DV_MAX_BPM 8 - -const DVprofile* ff_dv_frame_profile(const DVprofile *sys, - const uint8_t* frame, unsigned buf_size); -const DVprofile* ff_dv_codec_profile(AVCodecContext* codec); - -static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num, - uint8_t seq_num, uint8_t dif_num, - uint8_t* buf) -{ - buf[0] = (uint8_t)t; /* Section type */ - buf[1] = (seq_num << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */ - (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */ - 7; /* reserved -- always 1 */ - buf[2] = dif_num; /* DIF block number Video: 0-134, Audio: 0-8 */ - return 3; -} - - -static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf) -{ - if (syb_num == 0 || syb_num == 6) { - buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */ - (0 << 4) | /* AP3 (Subcode application ID) */ - 0x0f; /* reserved -- always 1 */ - } - else if (syb_num == 11) { - buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */ - 0x7f; /* reserved -- always 1 */ - } - else { - buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */ - (0 << 4) | /* APT (Track application ID) */ - 0x0f; /* reserved -- always 1 */ - } - buf[1] = 0xf0 | /* reserved -- always 1 */ - (syb_num & 0x0f); /* SSYB number 0 - 11 */ - buf[2] = 0xff; /* reserved -- always 1 */ - return 3; -} - -#endif /* AVCODEC_DVDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dvdsub_parser.c b/tizen/distrib/ffmpeg/libavcodec/dvdsub_parser.c deleted file mode 100644 index 8f1b8d0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvdsub_parser.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * DVD subtitle decoding for ffmpeg - * Copyright (c) 2005 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -/* parser definition */ -typedef struct DVDSubParseContext { - uint8_t *packet; - int packet_len; - int packet_index; -} DVDSubParseContext; - -static av_cold int dvdsub_parse_init(AVCodecParserContext *s) -{ - return 0; -} - -static int dvdsub_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const 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 = AV_RB16(buf); - if (pc->packet_len == 0) /* HD-DVD subpicture packet */ - pc->packet_len = AV_RB32(buf+2); - 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 av_cold 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/tizen/distrib/ffmpeg/libavcodec/dvdsubdec.c b/tizen/distrib/ffmpeg/libavcodec/dvdsubdec.c deleted file mode 100644 index 75b5256..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvdsubdec.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * DVD subtitle decoding for ffmpeg - * Copyright (c) 2005 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "get_bits.h" -#include "colorspace.h" -#include "dsputil.h" - -//#define DEBUG - -static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values) -{ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - uint8_t r, g, b; - int i, y, cb, cr; - int r_add, g_add, b_add; - - for (i = num_values; i > 0; i--) { - y = *ycbcr++; - cb = *ycbcr++; - cr = *ycbcr++; - YUV_TO_RGB1_CCIR(cb, cr); - YUV_TO_RGB2_CCIR(r, g, b, y); - *rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b; - } -} - -static int decode_run_2bit(GetBitContext *gb, int *color) -{ - unsigned int v, t; - - v = 0; - for (t = 1; v < t && t <= 0x40; t <<= 2) - v = (v << 4) | get_bits(gb, 4); - *color = v & 3; - if (v < 4) { /* Code for fill rest of line */ - return INT_MAX; - } - return v >> 2; -} - -static int decode_run_8bit(GetBitContext *gb, int *color) -{ - int len; - int has_run = get_bits1(gb); - if (get_bits1(gb)) - *color = get_bits(gb, 8); - else - *color = get_bits(gb, 2); - if (has_run) { - if (get_bits1(gb)) { - len = get_bits(gb, 7); - if (len == 0) - len = INT_MAX; - else - len += 9; - } else - len = get_bits(gb, 3) + 2; - } else - len = 1; - return len; -} - -static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, - const uint8_t *buf, int start, int buf_size, int is_8bit) -{ - GetBitContext gb; - int bit_len; - int x, y, len, color; - uint8_t *d; - - bit_len = (buf_size - start) * 8; - init_get_bits(&gb, buf + start, bit_len); - - x = 0; - y = 0; - d = bitmap; - for(;;) { - if (get_bits_count(&gb) > bit_len) - return -1; - if (is_8bit) - len = decode_run_8bit(&gb, &color); - else - len = decode_run_2bit(&gb, &color); - len = FFMIN(len, w - x); - memset(d + x, color, len); - x += len; - if (x >= w) { - y++; - if (y >= h) - break; - d += linesize; - x = 0; - /* byte align */ - align_get_bits(&gb); - } - } - return 0; -} - -static void guess_palette(uint32_t *rgba_palette, - uint8_t *colormap, - 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[colormap[i]]) { - color_used[colormap[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[colormap[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[colormap[i]] = (i + 1); - j--; - } else { - rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) | - ((alpha[i] * 17) << 24); - } - } - } -} - -#define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) - -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; - int big_offsets, offset_size, is_8bit = 0; - const uint8_t *yuv_palette = 0; - uint8_t colormap[4], alpha[256]; - int date; - int i; - int is_menu = 0; - - if (buf_size < 10) - return -1; - memset(sub_header, 0, sizeof(*sub_header)); - - if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */ - big_offsets = 1; - offset_size = 4; - cmd_pos = 6; - } else { - big_offsets = 0; - offset_size = 2; - cmd_pos = 2; - } - - cmd_pos = READ_OFFSET(buf + cmd_pos); - - while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) { - date = AV_RB16(buf + cmd_pos); - next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2); - dprintf(NULL, "cmd_pos=0x%04x next=0x%04x date=%d\n", - cmd_pos, next_cmd_pos, date); - pos = cmd_pos + 2 + offset_size; - offset1 = -1; - offset2 = -1; - x1 = y1 = x2 = y2 = 0; - while (pos < buf_size) { - cmd = buf[pos++]; - dprintf(NULL, "cmd=%02x\n", cmd); - 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 colormap */ - if ((buf_size - pos) < 2) - goto fail; - colormap[3] = buf[pos] >> 4; - colormap[2] = buf[pos] & 0x0f; - colormap[1] = buf[pos + 1] >> 4; - colormap[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; - dprintf(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]); - break; - case 0x05: - case 0x85: - 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]; - if (cmd & 0x80) - is_8bit = 1; - dprintf(NULL, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2); - pos += 6; - break; - case 0x06: - if ((buf_size - pos) < 4) - goto fail; - offset1 = AV_RB16(buf + pos); - offset2 = AV_RB16(buf + pos + 2); - dprintf(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); - pos += 4; - break; - case 0x86: - if ((buf_size - pos) < 8) - goto fail; - offset1 = AV_RB32(buf + pos); - offset2 = AV_RB32(buf + pos + 4); - dprintf(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); - pos += 8; - break; - - case 0x83: - /* HD set palette */ - if ((buf_size - pos) < 768) - goto fail; - yuv_palette = buf + pos; - pos += 768; - break; - case 0x84: - /* HD set contrast (alpha) */ - if ((buf_size - pos) < 256) - goto fail; - for (i = 0; i < 256; i++) - alpha[i] = 0xFF - buf[pos+i]; - pos += 256; - break; - - case 0xff: - goto the_end; - default: - dprintf(NULL, "unrecognised subpicture command 0x%x\n", cmd); - 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_freep(&sub_header->rects[i]->pict.data[0]); - av_freep(&sub_header->rects[i]->pict.data[1]); - av_freep(&sub_header->rects[i]); - } - av_freep(&sub_header->rects); - sub_header->num_rects = 0; - } - - bitmap = av_malloc(w * h); - sub_header->rects = av_mallocz(sizeof(*sub_header->rects)); - sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect)); - sub_header->num_rects = 1; - sub_header->rects[0]->pict.data[0] = bitmap; - decode_rle(bitmap, w * 2, w, (h + 1) / 2, - buf, offset1, buf_size, is_8bit); - decode_rle(bitmap + w, w * 2, w, h / 2, - buf, offset2, buf_size, is_8bit); - sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); - if (is_8bit) { - if (yuv_palette == 0) - goto fail; - sub_header->rects[0]->nb_colors = 256; - yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256); - } else { - sub_header->rects[0]->nb_colors = 4; - guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1], - colormap, 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]->type = SUBTITLE_BITMAP; - sub_header->rects[0]->pict.linesize[0] = w; - } - } - if (next_cmd_pos == cmd_pos) - break; - cmd_pos = next_cmd_pos; - } - if (sub_header->num_rects > 0) - return is_menu; - fail: - if (sub_header->rects != NULL) { - for (i = 0; i < sub_header->num_rects; i++) { - av_freep(&sub_header->rects[i]->pict.data[0]); - av_freep(&sub_header->rects[i]->pict.data[1]); - av_freep(&sub_header->rects[i]); - } - av_freep(&sub_header->rects); - sub_header->num_rects = 0; - } - 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 ((((uint32_t*)s->rects[0]->pict.data[1])[i] >> 24) == 0) - transp_color[i] = 1; - } - y1 = 0; - while (y1 < s->rects[0]->h && is_transp(s->rects[0]->pict.data[0] + y1 * s->rects[0]->pict.linesize[0], - 1, s->rects[0]->w, transp_color)) - y1++; - if (y1 == s->rects[0]->h) { - av_freep(&s->rects[0]->pict.data[0]); - 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]->pict.data[0] + y2 * s->rects[0]->pict.linesize[0], 1, - s->rects[0]->w, transp_color)) - y2--; - x1 = 0; - while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->pict.data[0] + x1, s->rects[0]->pict.linesize[0], - s->rects[0]->h, transp_color)) - x1++; - x2 = s->rects[0]->w - 1; - while (x2 > 0 && is_transp(s->rects[0]->pict.data[0] + x2, s->rects[0]->pict.linesize[0], 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]->pict.data[0] + x1 + (y1 + y) * s->rects[0]->pict.linesize[0], w); - } - av_freep(&s->rects[0]->pict.data[0]); - s->rects[0]->pict.data[0] = bitmap; - s->rects[0]->pict.linesize[0] = w; - s->rects[0]->w = w; - s->rects[0]->h = h; - s->rects[0]->x += x1; - s->rects[0]->y += y1; - return 1; -} - -#ifdef DEBUG -#undef fprintf -#undef perror -#undef exit -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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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) - dprintf(NULL, "start=%d ms end =%d ms\n", - sub->start_display_time, - sub->end_display_time); - ppm_save("/tmp/a.ppm", sub->rects[0]->pict.data[0], - sub->rects[0]->w, sub->rects[0]->h, sub->rects[0]->pict.data[1]); -#endif - - *data_size = 1; - return buf_size; -} - -AVCodec dvdsub_decoder = { - "dvdsub", - AVMEDIA_TYPE_SUBTITLE, - CODEC_ID_DVD_SUBTITLE, - 0, - NULL, - NULL, - NULL, - dvdsub_decode, - .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dvdsubenc.c b/tizen/distrib/ffmpeg/libavcodec/dvdsubenc.c deleted file mode 100644 index 4ee0f37..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dvdsubenc.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * DVD subtitle encoding for ffmpeg - * Copyright (c) 2005 Wolfram Gloger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "bytestream.h" - -#undef NDEBUG -#include - -// 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 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]->pict.data[0][i]; - // only count non-transparent pixels - alpha = ((uint32_t*)h->rects[object_id]->pict.data[1])[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]->pict.data[0], - 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]->pict.data[0] + 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; - bytestream_put_be16(&qq, q - outbuf); - - // send start display command - bytestream_put_be16(&q, (h->start_display_time*90) >> 10); - bytestream_put_be16(&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 - bytestream_put_be16(&q, offset1[object_id]); - bytestream_put_be16(&q, offset2[object_id]); - } - *q++ = 0x01; // start command - *q++ = 0xff; // terminating command - - // send stop display command last - bytestream_put_be16(&q, (h->end_display_time*90) >> 10); - bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/); - *q++ = 0x02; // set end - *q++ = 0xff; // terminating command - - qq = outbuf; - bytestream_put_be16(&qq, q - outbuf); - - av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf); - return q - outbuf; -} - -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", - AVMEDIA_TYPE_SUBTITLE, - CODEC_ID_DVD_SUBTITLE, - 0, - NULL, - dvdsub_encode, - .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/dwt.c b/tizen/distrib/ffmpeg/libavcodec/dwt.c deleted file mode 100644 index 2ecb04a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dwt.c +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Copyright (C) 2004-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/attributes.h" -#include "dsputil.h" -#include "dwt.h" - -void ff_slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * base_buffer) -{ - int i; - - buf->base_buffer = base_buffer; - buf->line_count = line_count; - buf->line_width = line_width; - buf->data_count = max_allocated_lines; - buf->line = av_mallocz (sizeof(IDWTELEM *) * line_count); - buf->data_stack = av_malloc (sizeof(IDWTELEM *) * max_allocated_lines); - - for(i = 0; i < max_allocated_lines; i++){ - buf->data_stack[i] = av_malloc (sizeof(IDWTELEM) * line_width); - } - - buf->data_stack_top = max_allocated_lines - 1; -} - -IDWTELEM * ff_slice_buffer_load_line(slice_buffer * buf, int line) -{ - IDWTELEM * buffer; - - assert(buf->data_stack_top >= 0); -// assert(!buf->line[line]); - if (buf->line[line]) - return buf->line[line]; - - buffer = buf->data_stack[buf->data_stack_top]; - buf->data_stack_top--; - buf->line[line] = buffer; - - return buffer; -} - -void ff_slice_buffer_release(slice_buffer * buf, int line) -{ - IDWTELEM * buffer; - - assert(line >= 0 && line < buf->line_count); - assert(buf->line[line]); - - buffer = buf->line[line]; - buf->data_stack_top++; - buf->data_stack[buf->data_stack_top] = buffer; - buf->line[line] = NULL; -} - -void ff_slice_buffer_flush(slice_buffer * buf) -{ - int i; - for(i = 0; i < buf->line_count; i++){ - if (buf->line[i]) - ff_slice_buffer_release(buf, i); - } -} - -void ff_slice_buffer_destroy(slice_buffer * buf) -{ - int i; - ff_slice_buffer_flush(buf); - - for(i = buf->data_count - 1; i >= 0; i--){ - av_freep(&buf->data_stack[i]); - } - av_freep(&buf->data_stack); - av_freep(&buf->line); -} - -static inline int mirror(int v, int m){ - while((unsigned)v > (unsigned)m){ - v=-v; - if(v<0) v+= 2*m; - } - return v; -} - -static av_always_inline void -lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, - int dst_step, int src_step, int ref_step, - int width, int mul, int add, int shift, - int highpass, int inverse){ - const int mirror_left= !highpass; - const int mirror_right= (width&1) ^ highpass; - const int w= (width>>1) - 1 + (highpass & width); - int i; - -#define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref))) - if(mirror_left){ - dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse); - dst += dst_step; - src += src_step; - } - - for(i=0; i>shift), - inverse); - } - - if(mirror_right){ - dst[w*dst_step] = - LIFT(src[w*src_step], - ((mul*2*ref[w*ref_step]+add)>>shift), - inverse); - } -} - -static av_always_inline void -inv_lift(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref, - int dst_step, int src_step, int ref_step, - int width, int mul, int add, int shift, - int highpass, int inverse){ - const int mirror_left= !highpass; - const int mirror_right= (width&1) ^ highpass; - const int w= (width>>1) - 1 + (highpass & width); - int i; - -#define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref))) - if(mirror_left){ - dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse); - dst += dst_step; - src += src_step; - } - - for(i=0; i>shift), - inverse); - } - - if(mirror_right){ - dst[w*dst_step] = - LIFT(src[w*src_step], - ((mul*2*ref[w*ref_step]+add)>>shift), - inverse); - } -} - -#ifndef liftS -static av_always_inline void -liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, - int dst_step, int src_step, int ref_step, - int width, int mul, int add, int shift, - int highpass, int inverse){ - const int mirror_left= !highpass; - const int mirror_right= (width&1) ^ highpass; - const int w= (width>>1) - 1 + (highpass & width); - int i; - - assert(shift == 4); -#define LIFTS(src, ref, inv) \ - ((inv) ? \ - (src) + (((ref) + 4*(src))>>shift): \ - -((-16*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (1<<23))) - if(mirror_left){ - dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse); - dst += dst_step; - src += src_step; - } - - for(i=0; i>1) - 1 + (highpass & width); - int i; - - assert(shift == 4); -#define LIFTS(src, ref, inv) \ - ((inv) ? \ - (src) + (((ref) + 4*(src))>>shift): \ - -((-16*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (1<<23))) - if(mirror_left){ - dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse); - dst += dst_step; - src += src_step; - } - - for(i=0; i>1; - int x; - const int w2= (width+1)>>1; - - for(x=0; x>1; - A4 += (A1 + 1)>>1; - b[0+width2] = A1; - b[0 ] = A4; - for(x=1; x+1>1; - A2 += (A1 + A3 + 2)>>2; - b[x+width2] = A3; - b[x ] = A2; - - A1= temp[x+1+width2]; - A2= temp[x+2 ]; - A1 -= (A2 + A4)>>1; - A4 += (A1 + A3 + 2)>>2; - b[x+1+width2] = A1; - b[x+1 ] = A4; - } - A3= temp[width-1]; - A3 -= A2; - A2 += (A1 + A3 + 2)>>2; - b[width -1] = A3; - b[width2-1] = A2; - } -#else - lift(b+w2, temp+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0); - lift(b , temp , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 0); -#endif /* 0 */ -} - -static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ - int i; - - for(i=0; i>1; - } -} - -static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ - int i; - - for(i=0; i>2; - } -} - -static void spatial_decompose53i(DWTELEM *buffer, int width, int height, int stride){ - int y; - DWTELEM *b0= buffer + mirror(-2-1, height-1)*stride; - DWTELEM *b1= buffer + mirror(-2 , height-1)*stride; - - for(y=-2; y>1; - - lift (temp+w2, b +1, b , 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1); - liftS(temp , b , temp+w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0); - lift (b +w2, temp+w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0); - lift (b , temp , b +w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0); -} - - -static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ - int i; - - for(i=0; i>W_AS; - } -} - -static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ - int i; - - for(i=0; i>W_CS; - } -} - -static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ - int i; - - for(i=0; i>W_BS; -#else - b1[i] = (16*4*b1[i] - 4*(b0[i] + b2[i]) + W_BO*5 + (5<<27)) / (5*16) - (1<<23); -#endif - } -} - -static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ - int i; - - for(i=0; i>W_DS; - } -} - -static void spatial_decompose97i(DWTELEM *buffer, int width, int height, int stride){ - int y; - DWTELEM *b0= buffer + mirror(-4-1, height-1)*stride; - DWTELEM *b1= buffer + mirror(-4 , height-1)*stride; - DWTELEM *b2= buffer + mirror(-4+1, height-1)*stride; - DWTELEM *b3= buffer + mirror(-4+2, height-1)*stride; - - for(y=-4; y>level, height>>level, stride<>level, height>>level, stride<>1; - const int w2= (width+1)>>1; - int x; - - for(x=0; x>1); - for(x=2; x>2); - b[x-1] = temp[x-1] + ((b [x-2] + b [x ]+1)>>1); - } - if(width&1){ - b[x ] = temp[x ] - ((temp[x-1]+1)>>1); - b[x-1] = temp[x-1] + ((b [x-2] + b [x ]+1)>>1); - }else - b[x-1] = temp[x-1] + b[x-2]; -} - -static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ - int i; - - for(i=0; i>1; - } -} - -static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ - int i; - - for(i=0; i>2; - } -} - -static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer * sb, int height, int stride_line){ - cs->b0 = slice_buffer_get_line(sb, mirror(-1-1, height-1) * stride_line); - cs->b1 = slice_buffer_get_line(sb, mirror(-1 , height-1) * stride_line); - cs->y = -1; -} - -static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride){ - cs->b0 = buffer + mirror(-1-1, height-1)*stride; - cs->b1 = buffer + mirror(-1 , height-1)*stride; - cs->y = -1; -} - -static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line){ - int y= cs->y; - - IDWTELEM *b0= cs->b0; - IDWTELEM *b1= cs->b1; - IDWTELEM *b2= slice_buffer_get_line(sb, mirror(y+1, height-1) * stride_line); - IDWTELEM *b3= slice_buffer_get_line(sb, mirror(y+2, height-1) * stride_line); - - if(y+1<(unsigned)height && y<(unsigned)height){ - int x; - - for(x=0; x>2; - b1[x] += (b0[x] + b2[x])>>1; - } - }else{ - if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width); - if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width); - } - - if(y-1<(unsigned)height) horizontal_compose53i(b0, width); - if(y+0<(unsigned)height) horizontal_compose53i(b1, width); - - cs->b0 = b2; - cs->b1 = b3; - cs->y += 2; -} - -static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride){ - int y= cs->y; - IDWTELEM *b0= cs->b0; - IDWTELEM *b1= cs->b1; - IDWTELEM *b2= buffer + mirror(y+1, height-1)*stride; - IDWTELEM *b3= buffer + mirror(y+2, height-1)*stride; - - if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width); - if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width); - - if(y-1<(unsigned)height) horizontal_compose53i(b0, width); - if(y+0<(unsigned)height) horizontal_compose53i(b1, width); - - cs->b0 = b2; - cs->b1 = b3; - cs->y += 2; -} - -static void av_unused spatial_compose53i(IDWTELEM *buffer, int width, int height, int stride){ - DWTCompose cs; - spatial_compose53i_init(&cs, buffer, height, stride); - while(cs.y <= height) - spatial_compose53i_dy(&cs, buffer, width, height, stride); -} - - -void ff_snow_horizontal_compose97i(IDWTELEM *b, int width){ - IDWTELEM temp[width]; - const int w2= (width+1)>>1; - -#if 0 //maybe more understadable but slower - inv_lift (temp , b , b +w2, 2, 1, 1, width, W_DM, W_DO, W_DS, 0, 1); - inv_lift (temp+1 , b +w2, temp , 2, 1, 2, width, W_CM, W_CO, W_CS, 1, 1); - - inv_liftS(b , temp , temp+1 , 2, 2, 2, width, W_BM, W_BO, W_BS, 0, 1); - inv_lift (b+1 , temp+1 , b , 2, 2, 2, width, W_AM, W_AO, W_AS, 1, 0); -#else - int x; - temp[0] = b[0] - ((3*b[w2]+2)>>2); - for(x=1; x<(width>>1); x++){ - temp[2*x ] = b[x ] - ((3*(b [x+w2-1] + b[x+w2])+4)>>3); - temp[2*x-1] = b[x+w2-1] - temp[2*x-2] - temp[2*x]; - } - if(width&1){ - temp[2*x ] = b[x ] - ((3*b [x+w2-1]+2)>>2); - temp[2*x-1] = b[x+w2-1] - temp[2*x-2] - temp[2*x]; - }else - temp[2*x-1] = b[x+w2-1] - 2*temp[2*x-2]; - - b[0] = temp[0] + ((2*temp[0] + temp[1]+4)>>3); - for(x=2; x>4); - b[x-1] = temp[x-1] + ((3*(b [x-2] + b [x ] ))>>1); - } - if(width&1){ - b[x ] = temp[x ] + ((2*temp[x ] + temp[x-1]+4)>>3); - b[x-1] = temp[x-1] + ((3*(b [x-2] + b [x ] ))>>1); - }else - b[x-1] = temp[x-1] + 3*b [x-2]; -#endif -} - -static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ - int i; - - for(i=0; i>W_AS; - } -} - -static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ - int i; - - for(i=0; i>W_CS; - } -} - -static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ - int i; - - for(i=0; i>W_BS; -#else - b1[i] += (W_BM*(b0[i] + b2[i])+4*b1[i]+W_BO)>>W_BS; -#endif - } -} - -static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ - int i; - - for(i=0; i>W_DS; - } -} - -void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ - int i; - - for(i=0; i>W_DS; - b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; -#ifdef liftS - b2[i] += (W_BM*(b1[i] + b3[i])+W_BO)>>W_BS; -#else - b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; -#endif - b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; - } -} - -static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer * sb, int height, int stride_line){ - cs->b0 = slice_buffer_get_line(sb, mirror(-3-1, height-1) * stride_line); - cs->b1 = slice_buffer_get_line(sb, mirror(-3 , height-1) * stride_line); - cs->b2 = slice_buffer_get_line(sb, mirror(-3+1, height-1) * stride_line); - cs->b3 = slice_buffer_get_line(sb, mirror(-3+2, height-1) * stride_line); - cs->y = -3; -} - -static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride){ - cs->b0 = buffer + mirror(-3-1, height-1)*stride; - cs->b1 = buffer + mirror(-3 , height-1)*stride; - cs->b2 = buffer + mirror(-3+1, height-1)*stride; - cs->b3 = buffer + mirror(-3+2, height-1)*stride; - cs->y = -3; -} - -static void spatial_compose97i_dy_buffered(DWTContext *dsp, DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line){ - int y = cs->y; - - IDWTELEM *b0= cs->b0; - IDWTELEM *b1= cs->b1; - IDWTELEM *b2= cs->b2; - IDWTELEM *b3= cs->b3; - IDWTELEM *b4= slice_buffer_get_line(sb, mirror(y + 3, height - 1) * stride_line); - IDWTELEM *b5= slice_buffer_get_line(sb, mirror(y + 4, height - 1) * stride_line); - - if(y>0 && y+4vertical_compose97i(b0, b1, b2, b3, b4, b5, width); - }else{ - if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width); - if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width); - if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width); - if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width); - } - - if(y-1<(unsigned)height) dsp->horizontal_compose97i(b0, width); - if(y+0<(unsigned)height) dsp->horizontal_compose97i(b1, width); - - cs->b0=b2; - cs->b1=b3; - cs->b2=b4; - cs->b3=b5; - cs->y += 2; -} - -static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride){ - int y = cs->y; - IDWTELEM *b0= cs->b0; - IDWTELEM *b1= cs->b1; - IDWTELEM *b2= cs->b2; - IDWTELEM *b3= cs->b3; - IDWTELEM *b4= buffer + mirror(y+3, height-1)*stride; - IDWTELEM *b5= buffer + mirror(y+4, height-1)*stride; - - if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width); - if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width); - if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width); - if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width); - - if(y-1<(unsigned)height) ff_snow_horizontal_compose97i(b0, width); - if(y+0<(unsigned)height) ff_snow_horizontal_compose97i(b1, width); - - cs->b0=b2; - cs->b1=b3; - cs->b2=b4; - cs->b3=b5; - cs->y += 2; -} - -static void av_unused spatial_compose97i(IDWTELEM *buffer, int width, int height, int stride){ - DWTCompose cs; - spatial_compose97i_init(&cs, buffer, height, stride); - while(cs.y <= height) - spatial_compose97i_dy(&cs, buffer, width, height, stride); -} - -void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line, int type, int decomposition_count){ - int level; - for(level=decomposition_count-1; level>=0; level--){ - switch(type){ - case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<>level, stride_line<=0; level--){ - while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){ - switch(type){ - case DWT_97: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<>level, height>>level, stride_line<=0; level--){ - switch(type){ - case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<>level, stride<=0; level--){ - while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){ - switch(type){ - case DWT_97: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<>level, height>>level, stride<>(dec_count-level); - int sx= (ori&1) ? size : 0; - int stride= 32<<(dec_count-level); - int sy= (ori&2) ? stride>>1 : 0; - - for(i=0; i=0); - return s>>9; -} - -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); -} - -int ff_w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 32, h, 1); -} - -int ff_w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 32, h, 0); -} - -void ff_dsputil_init_dwt(DSPContext *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; -} - -void ff_dwt_init(DWTContext *c) -{ - c->vertical_compose97i = ff_snow_vertical_compose97i; - c->horizontal_compose97i = ff_snow_horizontal_compose97i; - c->inner_add_yblock = ff_snow_inner_add_yblock; - - if (HAVE_MMX) ff_dwt_init_x86(c); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/dwt.h b/tizen/distrib/ffmpeg/libavcodec/dwt.h deleted file mode 100644 index 8c3aa20..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dwt.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2004-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DWT_H -#define AVCODEC_DWT_H - -#include - -typedef int DWTELEM; -typedef short IDWTELEM; - -typedef struct { - IDWTELEM *b0; - IDWTELEM *b1; - IDWTELEM *b2; - IDWTELEM *b3; - int y; -} DWTCompose; - -/** Used to minimize the amount of memory used in order to optimize cache performance. **/ -typedef struct slice_buffer_s { - IDWTELEM * * line; ///< For use by idwt and predict_slices. - IDWTELEM * * data_stack; ///< Used for internal purposes. - int data_stack_top; - int line_count; - int line_width; - int data_count; - IDWTELEM * base_buffer; ///< Buffer that this structure is caching. -} slice_buffer; - -typedef struct DWTContext { - void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); - void (*horizontal_compose97i)(IDWTELEM *b, int width); - void (*inner_add_yblock)(const 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); -} DWTContext; - -#define MAX_DECOMPOSITIONS 8 - -#define DWT_97 0 -#define DWT_53 1 - -#define liftS lift -#if 1 -#define W_AM 3 -#define W_AO 0 -#define W_AS 1 - -#undef liftS -#define W_BM 1 -#define W_BO 8 -#define W_BS 4 - -#define W_CM 1 -#define W_CO 0 -#define W_CS 0 - -#define W_DM 3 -#define W_DO 4 -#define W_DS 3 -#elif 0 -#define W_AM 55 -#define W_AO 16 -#define W_AS 5 - -#define W_BM 3 -#define W_BO 32 -#define W_BS 6 - -#define W_CM 127 -#define W_CO 64 -#define W_CS 7 - -#define W_DM 7 -#define W_DO 8 -#define W_DS 4 -#elif 0 -#define W_AM 97 -#define W_AO 32 -#define W_AS 6 - -#define W_BM 63 -#define W_BO 512 -#define W_BS 10 - -#define W_CM 13 -#define W_CO 8 -#define W_CS 4 - -#define W_DM 15 -#define W_DO 16 -#define W_DS 5 - -#else - -#define W_AM 203 -#define W_AO 64 -#define W_AS 7 - -#define W_BM 217 -#define W_BO 2048 -#define W_BS 12 - -#define W_CM 113 -#define W_CO 64 -#define W_CS 7 - -#define W_DM 227 -#define W_DO 128 -#define W_DS 9 -#endif - -#define slice_buffer_get_line(slice_buf, line_num) ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num] : ff_slice_buffer_load_line((slice_buf), (line_num))) -//#define slice_buffer_get_line(slice_buf, line_num) (ff_slice_buffer_load_line((slice_buf), (line_num))) - -void ff_slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * base_buffer); -void ff_slice_buffer_release(slice_buffer * buf, int line); -void ff_slice_buffer_flush(slice_buffer * buf); -void ff_slice_buffer_destroy(slice_buffer * buf); -IDWTELEM * ff_slice_buffer_load_line(slice_buffer * buf, int line); - -void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); -void ff_snow_horizontal_compose97i(IDWTELEM *b, int width); -void ff_snow_inner_add_yblock(const 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); - -int ff_w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h); -int ff_w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h); - -void ff_spatial_dwt(int *buffer, int width, int height, int stride, int type, int decomposition_count); - -void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line, int type, int decomposition_count); -void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs, slice_buffer * slice_buf, int width, int height, int stride_line, int type, int decomposition_count, int y); -void ff_spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count); -void ff_spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count, int y); -void ff_spatial_idwt(IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count); - -void ff_dwt_init(DWTContext *c); -void ff_dwt_init_x86(DWTContext *c); - -#endif /* AVCODEC_DWT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dxa.c b/tizen/distrib/ffmpeg/libavcodec/dxa.c deleted file mode 100644 index 62e4e0a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dxa.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Feeble Files/ScummVM DXA decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * DXA Video decoder - */ - -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#include - -/* - * Decoder context - */ -typedef struct DxaDecContext { - AVCodecContext *avctx; - AVFrame pic, prev; - - int dsize; - uint8_t *decomp_buf; - uint32_t pal[256]; -} DxaDecContext; - -static const int shift1[6] = { 0, 8, 8, 8, 4, 4 }; -static const int shift2[6] = { 0, 0, 8, 4, 0, 4 }; - -static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref) -{ - uint8_t *code, *data, *mv, *msk, *tmp, *tmp2; - int i, j, k; - int type, x, y, d, d2; - int stride = c->pic.linesize[0]; - uint32_t mask; - - code = src + 12; - data = code + ((avctx->width * avctx->height) >> 4); - mv = data + AV_RB32(src + 0); - msk = mv + AV_RB32(src + 4); - - for(j = 0; j < avctx->height; j += 4){ - for(i = 0; i < avctx->width; i += 4){ - tmp = dst + i; - tmp2 = ref + i; - type = *code++; - switch(type){ - case 4: // motion compensation - x = (*mv) >> 4; if(x & 8) x = 8 - x; - y = (*mv++) & 0xF; if(y & 8) y = 8 - y; - tmp2 += x + y*stride; - case 0: // skip - case 5: // skip in method 12 - for(y = 0; y < 4; y++){ - memcpy(tmp, tmp2, 4); - tmp += stride; - tmp2 += stride; - } - break; - case 1: // masked change - case 10: // masked change with only half of pixels changed - case 11: // cases 10-15 are for method 12 only - case 12: - case 13: - case 14: - case 15: - if(type == 1){ - mask = AV_RB16(msk); - msk += 2; - }else{ - type -= 10; - mask = ((msk[0] & 0xF0) << shift1[type]) | ((msk[0] & 0xF) << shift2[type]); - msk++; - } - for(y = 0; y < 4; y++){ - for(x = 0; x < 4; x++){ - tmp[x] = (mask & 0x8000) ? *data++ : tmp2[x]; - mask <<= 1; - } - tmp += stride; - tmp2 += stride; - } - break; - case 2: // fill block - for(y = 0; y < 4; y++){ - memset(tmp, data[0], 4); - tmp += stride; - } - data++; - break; - case 3: // raw block - for(y = 0; y < 4; y++){ - memcpy(tmp, data, 4); - data += 4; - tmp += stride; - } - break; - case 8: // subblocks - method 13 only - mask = *msk++; - for(k = 0; k < 4; k++){ - d = ((k & 1) << 1) + ((k & 2) * stride); - d2 = ((k & 1) << 1) + ((k & 2) * stride); - tmp2 = ref + i + d2; - switch(mask & 0xC0){ - case 0x80: // motion compensation - x = (*mv) >> 4; if(x & 8) x = 8 - x; - y = (*mv++) & 0xF; if(y & 8) y = 8 - y; - tmp2 += x + y*stride; - case 0x00: // skip - tmp[d + 0 ] = tmp2[0]; - tmp[d + 1 ] = tmp2[1]; - tmp[d + 0 + stride] = tmp2[0 + stride]; - tmp[d + 1 + stride] = tmp2[1 + stride]; - break; - case 0x40: // fill - tmp[d + 0 ] = data[0]; - tmp[d + 1 ] = data[0]; - tmp[d + 0 + stride] = data[0]; - tmp[d + 1 + stride] = data[0]; - data++; - break; - case 0xC0: // raw - tmp[d + 0 ] = *data++; - tmp[d + 1 ] = *data++; - tmp[d + 0 + stride] = *data++; - tmp[d + 1 + stride] = *data++; - break; - } - mask <<= 2; - } - break; - case 32: // vector quantization - 2 colors - mask = AV_RB16(msk); - msk += 2; - for(y = 0; y < 4; y++){ - for(x = 0; x < 4; x++){ - tmp[x] = data[mask & 1]; - mask >>= 1; - } - tmp += stride; - tmp2 += stride; - } - data += 2; - break; - case 33: // vector quantization - 3 or 4 colors - case 34: - mask = AV_RB32(msk); - msk += 4; - for(y = 0; y < 4; y++){ - for(x = 0; x < 4; x++){ - tmp[x] = data[mask & 3]; - mask >>= 2; - } - tmp += stride; - tmp2 += stride; - } - data += type - 30; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type); - return -1; - } - } - dst += stride * 4; - ref += stride * 4; - } - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - DxaDecContext * const c = avctx->priv_data; - uint8_t *outptr, *srcptr, *tmpptr; - unsigned long dsize; - int i, j, compr; - int stride; - int orig_buf_size = buf_size; - int pc = 0; - - /* make the palette available on the way out */ - if(buf[0]=='C' && buf[1]=='M' && buf[2]=='A' && buf[3]=='P'){ - int r, g, b; - - buf += 4; - for(i = 0; i < 256; i++){ - r = *buf++; - g = *buf++; - b = *buf++; - c->pal[i] = (r << 16) | (g << 8) | b; - } - pc = 1; - buf_size -= 768+4; - } - - if(avctx->get_buffer(avctx, &c->pic) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); - c->pic.palette_has_changed = pc; - - outptr = c->pic.data[0]; - srcptr = c->decomp_buf; - tmpptr = c->prev.data[0]; - stride = c->pic.linesize[0]; - - if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L') - compr = -1; - else - compr = buf[4]; - - dsize = c->dsize; - if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize, buf + 9, buf_size - 9) != Z_OK){ - av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n"); - return -1; - } - switch(compr){ - case -1: - c->pic.key_frame = 0; - c->pic.pict_type = FF_P_TYPE; - if(c->prev.data[0]) - memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height); - else{ // Should happen only when first frame is 'NULL' - memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height); - c->pic.key_frame = 1; - c->pic.pict_type = FF_I_TYPE; - } - break; - case 2: - case 3: - case 4: - case 5: - c->pic.key_frame = !(compr & 1); - c->pic.pict_type = (compr & 1) ? FF_P_TYPE : FF_I_TYPE; - for(j = 0; j < avctx->height; j++){ - if(compr & 1){ - for(i = 0; i < avctx->width; i++) - outptr[i] = srcptr[i] ^ tmpptr[i]; - tmpptr += stride; - }else - memcpy(outptr, srcptr, avctx->width); - outptr += stride; - srcptr += avctx->width; - } - break; - case 12: // ScummVM coding - case 13: - c->pic.key_frame = 0; - c->pic.pict_type = FF_P_TYPE; - decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]); - return -1; - } - - FFSWAP(AVFrame, c->pic, c->prev); - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->prev; - - /* always report that the buffer was completely consumed */ - return orig_buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - DxaDecContext * const c = avctx->priv_data; - - c->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - c->dsize = avctx->width * avctx->height * 2; - if((c->decomp_buf = av_malloc(c->dsize)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return -1; - } - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - DxaDecContext * const c = avctx->priv_data; - - av_freep(&c->decomp_buf); - if(c->prev.data[0]) - avctx->release_buffer(avctx, &c->prev); - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - -AVCodec dxa_decoder = { - "dxa", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DXA, - sizeof(DxaDecContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/dxva2.c b/tizen/distrib/ffmpeg/libavcodec/dxva2.c deleted file mode 100644 index 3f14311..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dxva2.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * DXVA2 HW acceleration. - * - * copyright (c) 2010 Laurent Aimar - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dxva2_internal.h" - -void *ff_dxva2_get_surface(const Picture *picture) -{ - return picture->data[3]; -} - -unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx, - const Picture *picture) -{ - void *surface = ff_dxva2_get_surface(picture); - unsigned i; - - for (i = 0; i < ctx->surface_count; i++) - if (ctx->surface[i] == surface) - return i; - - assert(0); - return 0; -} - -int ff_dxva2_commit_buffer(AVCodecContext *avctx, - struct dxva_context *ctx, - DXVA2_DecodeBufferDesc *dsc, - unsigned type, const void *data, unsigned size, - unsigned mb_count) -{ - void *dxva_data; - unsigned dxva_size; - int result; - - if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, type, - &dxva_data, &dxva_size))) { - av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %d\n", type); - return -1; - } - if (size <= dxva_size) { - memcpy(dxva_data, data, size); - - memset(dsc, 0, sizeof(*dsc)); - dsc->CompressedBufferType = type; - dsc->DataSize = size; - dsc->NumMBsInBuffer = mb_count; - - result = 0; - } else { - av_log(avctx, AV_LOG_ERROR, "Buffer for type %d was too small\n", type); - result = -1; - } - if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type))) { - av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %d\n", type); - result = -1; - } - return result; -} - -int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s, - const void *pp, unsigned pp_size, - const void *qm, unsigned qm_size, - int (*commit_bs_si)(AVCodecContext *, - DXVA2_DecodeBufferDesc *bs, - DXVA2_DecodeBufferDesc *slice)) -{ - struct dxva_context *ctx = avctx->hwaccel_context; - unsigned buffer_count = 0; - DXVA2_DecodeBufferDesc buffer[4]; - DXVA2_DecodeExecuteParams exec; - int result; - - if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder, - ff_dxva2_get_surface(s->current_picture_ptr), - NULL))) { - av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n"); - return -1; - } - - result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count], - DXVA2_PictureParametersBufferType, - pp, pp_size, 0); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Failed to add picture parameter buffer\n"); - goto end; - } - buffer_count++; - - if (qm_size > 0) { - result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count], - DXVA2_InverseQuantizationMatrixBufferType, - qm, qm_size, 0); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Failed to add inverse quantization matrix buffer\n"); - goto end; - } - buffer_count++; - } - - result = commit_bs_si(avctx, - &buffer[buffer_count + 0], - &buffer[buffer_count + 1]); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Failed to add bitstream or slice control buffer\n"); - goto end; - } - buffer_count += 2; - - /* TODO Film Grain when possible */ - - assert(buffer_count == 1 + (qm_size > 0) + 2); - - memset(&exec, 0, sizeof(exec)); - exec.NumCompBuffers = buffer_count; - exec.pCompressedBuffers = buffer; - exec.pExtensionData = NULL; - if (FAILED(IDirectXVideoDecoder_Execute(ctx->decoder, &exec))) { - av_log(avctx, AV_LOG_ERROR, "Failed to execute\n"); - result = -1; - } - -end: - if (FAILED(IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL))) { - av_log(avctx, AV_LOG_ERROR, "Failed to end frame\n"); - result = -1; - } - - if (!result) - ff_draw_horiz_band(s, 0, s->avctx->height); - return result; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/dxva2.h b/tizen/distrib/ffmpeg/libavcodec/dxva2.h deleted file mode 100644 index 5c5fe21..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dxva2.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * DXVA2 HW acceleration - * - * copyright (c) 2009 Laurent Aimar - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DXVA_H -#define AVCODEC_DXVA_H - -#include - -#include - -/** - * This structure is used to provides the necessary configurations and data - * to the DXVA2 FFmpeg HWAccel implementation. - * - * The application must make it available as AVCodecContext.hwaccel_context. - */ -struct dxva_context { - /** - * DXVA2 decoder object - */ - IDirectXVideoDecoder *decoder; - - /** - * DXVA2 configuration used to create the decoder - */ - const DXVA2_ConfigPictureDecode *cfg; - - /** - * The number of surface in the surface array - */ - unsigned surface_count; - - /** - * The array of Direct3D surfaces used to create the decoder - */ - LPDIRECT3DSURFACE9 *surface; - - /** - * A bit field configuring the workarounds needed for using the decoder - */ - uint64_t workaround; - - /** - * Private to the FFmpeg AVHWAccel implementation - */ - unsigned report_id; -}; - -#endif /* AVCODEC_DXVA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dxva2_h264.c b/tizen/distrib/ffmpeg/libavcodec/dxva2_h264.c deleted file mode 100644 index 22c76df..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dxva2_h264.c +++ /dev/null @@ -1,437 +0,0 @@ -/* - * DXVA2 H264 HW acceleration. - * - * copyright (c) 2009 Laurent Aimar - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dxva2_internal.h" -#include "h264.h" -#include "h264data.h" - -struct dxva2_picture_context { - DXVA_PicParams_H264 pp; - DXVA_Qmatrix_H264 qm; - unsigned slice_count; - DXVA_Slice_H264_Short slice_short[MAX_SLICES]; - DXVA_Slice_H264_Long slice_long[MAX_SLICES]; - const uint8_t *bitstream; - unsigned bitstream_size; -}; - -static void fill_picture_entry(DXVA_PicEntry_H264 *pic, - unsigned index, unsigned flag) -{ - assert((index&0x7f) == index && (flag&0x01) == flag); - pic->bPicEntry = index | (flag << 7); -} - -static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h, - DXVA_PicParams_H264 *pp) -{ - const MpegEncContext *s = &h->s; - const Picture *current_picture = s->current_picture_ptr; - int i; - - memset(pp, 0, sizeof(*pp)); - /* Configure current picture */ - fill_picture_entry(&pp->CurrPic, - ff_dxva2_get_surface_index(ctx, current_picture), - s->picture_structure == PICT_BOTTOM_FIELD); - /* Configure the set of references */ - pp->UsedForReferenceFlags = 0; - pp->NonExistingFrameFlags = 0; - for (i = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) { - if (i < h->short_ref_count + h->long_ref_count) { - const Picture *r; - if (i < h->short_ref_count) { - r = h->short_ref[i]; - assert(!r->long_ref); - } else { - r = h->long_ref[i - h->short_ref_count]; - assert(r->long_ref); - } - fill_picture_entry(&pp->RefFrameList[i], - ff_dxva2_get_surface_index(ctx, r), - r->long_ref != 0); - - if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX) - pp->FieldOrderCntList[i][0] = r->field_poc[0]; - if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX) - pp->FieldOrderCntList[i][1] = r->field_poc[1]; - - pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num; - if (r->reference & PICT_TOP_FIELD) - pp->UsedForReferenceFlags |= 1 << (2*i + 0); - if (r->reference & PICT_BOTTOM_FIELD) - pp->UsedForReferenceFlags |= 1 << (2*i + 1); - } else { - pp->RefFrameList[i].bPicEntry = 0xff; - pp->FieldOrderCntList[i][0] = 0; - pp->FieldOrderCntList[i][1] = 0; - pp->FrameNumList[i] = 0; - } - } - - pp->wFrameWidthInMbsMinus1 = s->mb_width - 1; - pp->wFrameHeightInMbsMinus1 = s->mb_height - 1; - pp->num_ref_frames = h->sps.ref_frame_count; - - pp->wBitFields = ((s->picture_structure != PICT_FRAME) << 0) | - (h->sps.mb_aff << 1) | - (h->sps.residual_color_transform_flag << 2) | - /* sp_for_switch_flag (not implemented by FFmpeg) */ - (0 << 3) | - (h->sps.chroma_format_idc << 4) | - ((h->nal_ref_idc != 0) << 6) | - (h->pps.constrained_intra_pred << 7) | - (h->pps.weighted_pred << 8) | - (h->pps.weighted_bipred_idc << 9) | - /* MbsConsecutiveFlag */ - (1 << 11) | - (h->sps.frame_mbs_only_flag << 12) | - (h->pps.transform_8x8_mode << 13) | - ((h->sps.level_idc >= 31) << 14) | - /* IntraPicFlag (Modified if we detect a non - * intra slice in decode_slice) */ - (1 << 15); - - pp->bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8; - pp->bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; - pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */ - pp->StatusReportFeedbackNumber = 1 + ctx->report_id++; - pp->CurrFieldOrderCnt[0] = 0; - if ((s->picture_structure & PICT_TOP_FIELD) && - current_picture->field_poc[0] != INT_MAX) - pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0]; - pp->CurrFieldOrderCnt[1] = 0; - if ((s->picture_structure & PICT_BOTTOM_FIELD) && - current_picture->field_poc[1] != INT_MAX) - pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1]; - pp->pic_init_qs_minus26 = h->pps.init_qs - 26; - pp->chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0]; - pp->second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1]; - pp->ContinuationFlag = 1; - pp->pic_init_qp_minus26 = h->pps.init_qp - 26; - pp->num_ref_idx_l0_active_minus1 = h->pps.ref_count[0] - 1; - pp->num_ref_idx_l1_active_minus1 = h->pps.ref_count[1] - 1; - pp->Reserved8BitsA = 0; - pp->frame_num = h->frame_num; - pp->log2_max_frame_num_minus4 = h->sps.log2_max_frame_num - 4; - pp->pic_order_cnt_type = h->sps.poc_type; - if (h->sps.poc_type == 0) - pp->log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4; - else if (h->sps.poc_type == 1) - pp->delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag; - pp->direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag; - pp->entropy_coding_mode_flag = h->pps.cabac; - pp->pic_order_present_flag = h->pps.pic_order_present; - pp->num_slice_groups_minus1 = h->pps.slice_group_count - 1; - pp->slice_group_map_type = h->pps.mb_slice_group_map_type; - pp->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; - pp->redundant_pic_cnt_present_flag= h->pps.redundant_pic_cnt_present; - pp->Reserved8BitsB = 0; - pp->slice_group_change_rate_minus1= 0; /* XXX not implemented by FFmpeg */ - //pp->SliceGroupMap[810]; /* XXX not implemented by FFmpeg */ -} - -static void fill_scaling_lists(const H264Context *h, DXVA_Qmatrix_H264 *qm) -{ - unsigned i, j; - memset(qm, 0, sizeof(*qm)); - for (i = 0; i < 6; i++) - for (j = 0; j < 16; j++) - qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][zigzag_scan[j]]; - - for (i = 0; i < 2; i++) - for (j = 0; j < 64; j++) - qm->bScalingLists8x8[i][j] = h->pps.scaling_matrix8[i][ff_zigzag_direct[j]]; -} - -static int is_slice_short(struct dxva_context *ctx) -{ - assert(ctx->cfg->ConfigBitstreamRaw == 1 || - ctx->cfg->ConfigBitstreamRaw == 2); - return ctx->cfg->ConfigBitstreamRaw == 2; -} - -static void fill_slice_short(DXVA_Slice_H264_Short *slice, - unsigned position, unsigned size) -{ - memset(slice, 0, sizeof(*slice)); - slice->BSNALunitDataLocation = position; - slice->SliceBytesInBuffer = size; - slice->wBadSliceChopping = 0; -} - -static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, - unsigned position, unsigned size) -{ - const H264Context *h = avctx->priv_data; - struct dxva_context *ctx = avctx->hwaccel_context; - const MpegEncContext *s = &h->s; - unsigned list; - - memset(slice, 0, sizeof(*slice)); - slice->BSNALunitDataLocation = position; - slice->SliceBytesInBuffer = size; - slice->wBadSliceChopping = 0; - - slice->first_mb_in_slice = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x; - slice->NumMbsForSlice = 0; /* XXX it is set once we have all slices */ - slice->BitOffsetToSliceData = get_bits_count(&s->gb) + 8; - slice->slice_type = ff_h264_get_slice_type(h); - if (h->slice_type_fixed) - slice->slice_type += 5; - slice->luma_log2_weight_denom = h->luma_log2_weight_denom; - slice->chroma_log2_weight_denom = h->chroma_log2_weight_denom; - if (h->list_count > 0) - slice->num_ref_idx_l0_active_minus1 = h->ref_count[0] - 1; - if (h->list_count > 1) - slice->num_ref_idx_l1_active_minus1 = h->ref_count[1] - 1; - slice->slice_alpha_c0_offset_div2 = h->slice_alpha_c0_offset / 2 - 26; - slice->slice_beta_offset_div2 = h->slice_beta_offset / 2 - 26; - slice->Reserved8Bits = 0; - - for (list = 0; list < 2; list++) { - unsigned i; - for (i = 0; i < FF_ARRAY_ELEMS(slice->RefPicList[list]); i++) { - if (list < h->list_count && i < h->ref_count[list]) { - const Picture *r = &h->ref_list[list][i]; - unsigned plane; - fill_picture_entry(&slice->RefPicList[list][i], - ff_dxva2_get_surface_index(ctx, r), - r->reference == PICT_BOTTOM_FIELD); - for (plane = 0; plane < 3; plane++) { - int w, o; - if (plane == 0 && h->luma_weight_flag[list]) { - w = h->luma_weight[i][list][0]; - o = h->luma_weight[i][list][1]; - } else if (plane >= 1 && h->chroma_weight_flag[list]) { - w = h->chroma_weight[i][list][plane-1][0]; - o = h->chroma_weight[i][list][plane-1][1]; - } else { - w = 1 << (plane == 0 ? h->luma_log2_weight_denom : - h->chroma_log2_weight_denom); - o = 0; - } - slice->Weights[list][i][plane][0] = w; - slice->Weights[list][i][plane][1] = o; - } - } else { - unsigned plane; - slice->RefPicList[list][i].bPicEntry = 0xff; - for (plane = 0; plane < 3; plane++) { - slice->Weights[list][i][plane][0] = 0; - slice->Weights[list][i][plane][1] = 0; - } - } - } - } - slice->slice_qs_delta = 0; /* XXX not implemented by FFmpeg */ - slice->slice_qp_delta = s->qscale - h->pps.init_qp; - slice->redundant_pic_cnt = h->redundant_pic_count; - if (h->slice_type == FF_B_TYPE) - slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred; - slice->cabac_init_idc = h->pps.cabac ? h->cabac_init_idc : 0; - if (h->deblocking_filter < 2) - slice->disable_deblocking_filter_idc = 1 - h->deblocking_filter; - else - slice->disable_deblocking_filter_idc = h->deblocking_filter; - slice->slice_id = h->current_slice - 1; -} - -static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, - DXVA2_DecodeBufferDesc *bs, - DXVA2_DecodeBufferDesc *sc) -{ - const H264Context *h = avctx->priv_data; - const MpegEncContext *s = &h->s; - const unsigned mb_count = s->mb_width * s->mb_height; - struct dxva_context *ctx = avctx->hwaccel_context; - const Picture *current_picture = h->s.current_picture_ptr; - struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; - DXVA_Slice_H264_Short *slice = NULL; - uint8_t *dxva_data, *current, *end; - unsigned dxva_size; - void *slice_data; - unsigned slice_size; - unsigned padding; - unsigned i; - - /* Create an annex B bitstream buffer with only slice NAL and finalize slice */ - if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, - DXVA2_BitStreamDateBufferType, - &dxva_data, &dxva_size))) - return -1; - current = dxva_data; - end = dxva_data + dxva_size; - - for (i = 0; i < ctx_pic->slice_count; i++) { - static const uint8_t start_code[] = { 0, 0, 1 }; - static const unsigned start_code_size = sizeof(start_code); - unsigned position, size; - - assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) == - offsetof(DXVA_Slice_H264_Long, BSNALunitDataLocation)); - assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) == - offsetof(DXVA_Slice_H264_Long, SliceBytesInBuffer)); - - if (is_slice_short(ctx)) - slice = &ctx_pic->slice_short[i]; - else - slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i]; - - position = slice->BSNALunitDataLocation; - size = slice->SliceBytesInBuffer; - if (start_code_size + size > end - current) { - av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream"); - break; - } - - slice->BSNALunitDataLocation = current - dxva_data; - slice->SliceBytesInBuffer = start_code_size + size; - - if (!is_slice_short(ctx)) { - DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice; - if (i < ctx_pic->slice_count - 1) - slice_long->NumMbsForSlice = - slice_long[1].first_mb_in_slice - slice_long[0].first_mb_in_slice; - else - slice_long->NumMbsForSlice = mb_count - slice_long->first_mb_in_slice; - } - - memcpy(current, start_code, start_code_size); - current += start_code_size; - - memcpy(current, &ctx_pic->bitstream[position], size); - current += size; - } - padding = FFMIN(128 - ((current - dxva_data) & 127), end - current); - if (slice && padding > 0) { - memset(current, 0, padding); - current += padding; - - slice->SliceBytesInBuffer += padding; - } - if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, - DXVA2_BitStreamDateBufferType))) - return -1; - if (i < ctx_pic->slice_count) - return -1; - - memset(bs, 0, sizeof(*bs)); - bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; - bs->DataSize = current - dxva_data; - bs->NumMBsInBuffer = mb_count; - - if (is_slice_short(ctx)) { - slice_data = ctx_pic->slice_short; - slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short); - } else { - slice_data = ctx_pic->slice_long; - slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_long); - } - assert((bs->DataSize & 127) == 0); - return ff_dxva2_commit_buffer(avctx, ctx, sc, - DXVA2_SliceControlBufferType, - slice_data, slice_size, mb_count); -} - - -static int start_frame(AVCodecContext *avctx, - av_unused const uint8_t *buffer, - av_unused uint32_t size) -{ - const H264Context *h = avctx->priv_data; - struct dxva_context *ctx = avctx->hwaccel_context; - struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->hwaccel_picture_private; - - if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0) - return -1; - assert(ctx_pic); - - /* Fill up DXVA_PicParams_H264 */ - fill_picture_parameters(ctx, h, &ctx_pic->pp); - - /* Fill up DXVA_Qmatrix_H264 */ - fill_scaling_lists(h, &ctx_pic->qm); - - ctx_pic->slice_count = 0; - ctx_pic->bitstream_size = 0; - ctx_pic->bitstream = NULL; - return 0; -} - -static int decode_slice(AVCodecContext *avctx, - const uint8_t *buffer, uint32_t size) -{ - const H264Context *h = avctx->priv_data; - struct dxva_context *ctx = avctx->hwaccel_context; - const Picture *current_picture = h->s.current_picture_ptr; - struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; - unsigned position; - - if (ctx_pic->slice_count >= MAX_SLICES) - return -1; - - if (!ctx_pic->bitstream) - ctx_pic->bitstream = buffer; - ctx_pic->bitstream_size += size; - - position = buffer - ctx_pic->bitstream; - if (is_slice_short(ctx)) - fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count], - position, size); - else - fill_slice_long(avctx, &ctx_pic->slice_long[ctx_pic->slice_count], - position, size); - ctx_pic->slice_count++; - - if (h->slice_type != FF_I_TYPE && h->slice_type != FF_SI_TYPE) - ctx_pic->pp.wBitFields &= ~(1 << 15); /* Set IntraPicFlag to 0 */ - return 0; -} - -static int end_frame(AVCodecContext *avctx) -{ - H264Context *h = avctx->priv_data; - MpegEncContext *s = &h->s; - struct dxva2_picture_context *ctx_pic = - h->s.current_picture_ptr->hwaccel_picture_private; - - if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0) - return -1; - return ff_dxva2_common_end_frame(avctx, s, - &ctx_pic->pp, sizeof(ctx_pic->pp), - &ctx_pic->qm, sizeof(ctx_pic->qm), - commit_bitstream_and_slice_buffer); -} - -AVHWAccel h264_dxva2_hwaccel = { - .name = "h264_dxva2", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_H264, - .pix_fmt = PIX_FMT_DXVA2_VLD, - .capabilities = 0, - .start_frame = start_frame, - .decode_slice = decode_slice, - .end_frame = end_frame, - .priv_data_size = sizeof(struct dxva2_picture_context), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/dxva2_internal.h b/tizen/distrib/ffmpeg/libavcodec/dxva2_internal.h deleted file mode 100644 index a9be7a0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dxva2_internal.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * DXVA2 HW acceleration - * - * copyright (c) 2010 Laurent Aimar - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DXVA_INTERNAL_H -#define AVCODEC_DXVA_INTERNAL_H - -#include "dxva2.h" -#include "avcodec.h" -#include "mpegvideo.h" - -void *ff_dxva2_get_surface(const Picture *picture); - -unsigned ff_dxva2_get_surface_index(const struct dxva_context *, - const Picture *picture); - -int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *, - DXVA2_DecodeBufferDesc *, - unsigned type, const void *data, unsigned size, - unsigned mb_count); - - -int ff_dxva2_common_end_frame(AVCodecContext *, MpegEncContext *, - const void *pp, unsigned pp_size, - const void *qm, unsigned qm_size, - int (*commit_bs_si)(AVCodecContext *, - DXVA2_DecodeBufferDesc *bs, - DXVA2_DecodeBufferDesc *slice)); - -#endif /* AVCODEC_DXVA_INTERNAL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/dxva2_vc1.c b/tizen/distrib/ffmpeg/libavcodec/dxva2_vc1.c deleted file mode 100644 index a111213..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/dxva2_vc1.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * DXVA2 WMV3/VC-1 HW acceleration. - * - * copyright (c) 2010 Laurent Aimar - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dxva2_internal.h" -#include "vc1.h" -#include "vc1data.h" - -struct dxva2_picture_context { - DXVA_PictureParameters pp; - DXVA_SliceInfo si; - - const uint8_t *bitstream; - unsigned bitstream_size; -}; - -static void fill_picture_parameters(AVCodecContext *avctx, - struct dxva_context *ctx, const VC1Context *v, - DXVA_PictureParameters *pp) -{ - const MpegEncContext *s = &v->s; - const Picture *current_picture = s->current_picture_ptr; - - memset(pp, 0, sizeof(*pp)); - pp->wDecodedPictureIndex = - pp->wDeblockedPictureIndex = ff_dxva2_get_surface_index(ctx, current_picture); - if (s->pict_type != FF_I_TYPE) - pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->last_picture); - else - pp->wForwardRefPictureIndex = 0xffff; - if (s->pict_type == FF_B_TYPE) - pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, &s->next_picture); - else - pp->wBackwardRefPictureIndex = 0xffff; - if (v->profile == PROFILE_ADVANCED) { - /* It is the cropped width/height -1 of the frame */ - pp->wPicWidthInMBminus1 = avctx->width - 1; - pp->wPicHeightInMBminus1= avctx->height - 1; - } else { - /* It is the coded width/height in macroblock -1 of the frame */ - pp->wPicWidthInMBminus1 = s->mb_width - 1; - pp->wPicHeightInMBminus1= s->mb_height - 1; - } - pp->bMacroblockWidthMinus1 = 15; - pp->bMacroblockHeightMinus1 = 15; - pp->bBlockWidthMinus1 = 7; - pp->bBlockHeightMinus1 = 7; - pp->bBPPminus1 = 7; - if (s->picture_structure & PICT_TOP_FIELD) - pp->bPicStructure |= 0x01; - if (s->picture_structure & PICT_BOTTOM_FIELD) - pp->bPicStructure |= 0x02; - pp->bSecondField = v->interlace && v->fcm != 0x03 && !s->first_field; - pp->bPicIntra = s->pict_type == FF_I_TYPE; - pp->bPicBackwardPrediction = s->pict_type == FF_B_TYPE; - pp->bBidirectionalAveragingMode = (1 << 7) | - ((ctx->cfg->ConfigIntraResidUnsigned != 0) << 6) | - ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) | - ((v->lumscale != 32 || v->lumshift != 0) << 4) | - ((v->profile == PROFILE_ADVANCED) << 3); - pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) | - (1 << 2) | - (0 << 1) | - (!s->quarter_sample ); - pp->bChromaFormat = v->chromaformat; - ctx->report_id++; - if (ctx->report_id >= (1 << 16)) - ctx->report_id = 1; - pp->bPicScanFixed = ctx->report_id >> 8; - pp->bPicScanMethod = ctx->report_id & 0xff; - pp->bPicReadbackRequests = 0; - pp->bRcontrol = v->rnd; - pp->bPicSpatialResid8 = (v->panscanflag << 7) | - (v->refdist_flag << 6) | - (s->loop_filter << 5) | - (v->fastuvmc << 4) | - (v->extended_mv << 3) | - (v->dquant << 1) | - (v->vstransform ); - pp->bPicOverflowBlocks = (v->quantizer_mode << 6) | - (v->multires << 5) | - (s->resync_marker << 4) | - (v->rangered << 3) | - (s->max_b_frames ); - pp->bPicExtrapolation = (!v->interlace || v->fcm == 0x00) ? 1 : 2; - pp->bPicDeblocked = ((v->profile != PROFILE_ADVANCED && v->rangeredfrm) << 5) | - (s->loop_filter << 1); - pp->bPicDeblockConfined = (v->postprocflag << 7) | - (v->broadcast << 6) | - (v->interlace << 5) | - (v->tfcntrflag << 4) | - (v->finterpflag << 3) | - ((s->pict_type != FF_B_TYPE) << 2) | - (v->psf << 1) | - (v->extended_dmv ); - if (s->pict_type != FF_I_TYPE) - pp->bPic4MVallowed = v->mv_mode == MV_PMODE_MIXED_MV || - (v->mv_mode == MV_PMODE_INTENSITY_COMP && - v->mv_mode2 == MV_PMODE_MIXED_MV); - if (v->profile == PROFILE_ADVANCED) - pp->bPicOBMC = (v->range_mapy_flag << 7) | - (v->range_mapy << 4) | - (v->range_mapuv_flag << 3) | - (v->range_mapuv ); - pp->bPicBinPB = 0; - pp->bMV_RPS = 0; - pp->bReservedBits = 0; - if (s->picture_structure == PICT_FRAME) { - pp->wBitstreamFcodes = v->lumscale; - pp->wBitstreamPCEelements = v->lumshift; - } else { - /* Syntax: (top_field_param << 8) | bottom_field_param */ - pp->wBitstreamFcodes = (v->lumscale << 8) | v->lumscale; - pp->wBitstreamPCEelements = (v->lumshift << 8) | v->lumshift; - } - pp->bBitstreamConcealmentNeed = 0; - pp->bBitstreamConcealmentMethod = 0; -} - -static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice, - unsigned position, unsigned size) -{ - const VC1Context *v = avctx->priv_data; - const MpegEncContext *s = &v->s; - - memset(slice, 0, sizeof(*slice)); - slice->wHorizontalPosition = 0; - slice->wVerticalPosition = s->mb_y; - slice->dwSliceBitsInBuffer = 8 * size; - slice->dwSliceDataLocation = position; - slice->bStartCodeBitOffset = 0; - slice->bReservedBits = 0; - slice->wMBbitOffset = get_bits_count(&s->gb); - slice->wNumberMBsInSlice = s->mb_width * s->mb_height; /* XXX We assume 1 slice */ - slice->wQuantizerScaleCode = v->pq; - slice->wBadSliceChopping = 0; -} - -static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, - DXVA2_DecodeBufferDesc *bs, - DXVA2_DecodeBufferDesc *sc) -{ - const VC1Context *v = avctx->priv_data; - struct dxva_context *ctx = avctx->hwaccel_context; - const MpegEncContext *s = &v->s; - struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private; - - DXVA_SliceInfo *slice = &ctx_pic->si; - - static const uint8_t start_code[] = { 0, 0, 1, 0x0d }; - const unsigned start_code_size = avctx->codec_id == CODEC_ID_VC1 ? sizeof(start_code) : 0; - const unsigned slice_size = slice->dwSliceBitsInBuffer / 8; - const unsigned padding = 128 - ((start_code_size + slice_size) & 127); - const unsigned data_size = start_code_size + slice_size + padding; - - uint8_t *dxva_data; - unsigned dxva_size; - int result; - - if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, - DXVA2_BitStreamDateBufferType, - &dxva_data, &dxva_size))) - return -1; - - result = data_size <= dxva_size ? 0 : -1; - if (!result) { - if (start_code_size > 0) - memcpy(dxva_data, start_code, start_code_size); - memcpy(dxva_data + start_code_size, - ctx_pic->bitstream + slice->dwSliceDataLocation, slice_size); - if (padding > 0) - memset(dxva_data + start_code_size + slice_size, 0, padding); - slice->dwSliceBitsInBuffer = 8 * data_size; - } - if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, - DXVA2_BitStreamDateBufferType))) - return -1; - if (result) - return result; - - memset(bs, 0, sizeof(*bs)); - bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; - bs->DataSize = data_size; - bs->NumMBsInBuffer = s->mb_width * s->mb_height; - assert((bs->DataSize & 127) == 0); - - return ff_dxva2_commit_buffer(avctx, ctx, sc, - DXVA2_SliceControlBufferType, - slice, sizeof(*slice), bs->NumMBsInBuffer); -} - -static int start_frame(AVCodecContext *avctx, - av_unused const uint8_t *buffer, - av_unused uint32_t size) -{ - const VC1Context *v = avctx->priv_data; - struct dxva_context *ctx = avctx->hwaccel_context; - struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private; - - if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0) - return -1; - assert(ctx_pic); - - fill_picture_parameters(avctx, ctx, v, &ctx_pic->pp); - - ctx_pic->bitstream_size = 0; - ctx_pic->bitstream = NULL; - return 0; -} - -static int decode_slice(AVCodecContext *avctx, - const uint8_t *buffer, uint32_t size) -{ - const VC1Context *v = avctx->priv_data; - const Picture *current_picture = v->s.current_picture_ptr; - struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; - - if (ctx_pic->bitstream_size > 0) - return -1; - - if (avctx->codec_id == CODEC_ID_VC1 && - size >= 4 && IS_MARKER(AV_RB32(buffer))) { - buffer += 4; - size -= 4; - } - - ctx_pic->bitstream_size = size; - ctx_pic->bitstream = buffer; - - fill_slice(avctx, &ctx_pic->si, 0, size); - return 0; -} - -static int end_frame(AVCodecContext *avctx) -{ - VC1Context *v = avctx->priv_data; - struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private; - - if (ctx_pic->bitstream_size <= 0) - return -1; - - return ff_dxva2_common_end_frame(avctx, &v->s, - &ctx_pic->pp, sizeof(ctx_pic->pp), - NULL, 0, - commit_bitstream_and_slice_buffer); -} - -#if CONFIG_WMV3_DXVA2_HWACCEL -AVHWAccel wmv3_dxva2_hwaccel = { - .name = "wmv3_dxva2", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_WMV3, - .pix_fmt = PIX_FMT_DXVA2_VLD, - .capabilities = 0, - .start_frame = start_frame, - .decode_slice = decode_slice, - .end_frame = end_frame, - .priv_data_size = sizeof(struct dxva2_picture_context), -}; -#endif - -AVHWAccel vc1_dxva2_hwaccel = { - .name = "vc1_dxva2", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_VC1, - .pix_fmt = PIX_FMT_DXVA2_VLD, - .capabilities = 0, - .start_frame = start_frame, - .decode_slice = decode_slice, - .end_frame = end_frame, - .priv_data_size = sizeof(struct dxva2_picture_context), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/eac3dec.c b/tizen/distrib/ffmpeg/libavcodec/eac3dec.c deleted file mode 100644 index 52d15c8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eac3dec.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * E-AC-3 decoder - * Copyright (c) 2007 Bartlomiej Wolowiec - * Copyright (c) 2008 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * There are several features of E-AC-3 that this decoder does not yet support. - * - * Enhanced Coupling - * No known samples exist. If any ever surface, this feature should not be - * too difficult to implement. - * - * Reduced Sample Rates - * No known samples exist. The spec also does not give clear information - * on how this is to be implemented. - * - * Dependent Streams - * Only the independent stream is currently decoded. Any dependent - * streams are skipped. We have only come across two examples of this, and - * they are both just test streams, one for HD-DVD and the other for - * Blu-ray. - * - * Transient Pre-noise Processing - * This is side information which a decoder should use to reduce artifacts - * caused by transients. There are samples which are known to have this - * information, but this decoder currently ignores it. - */ - - -#include "avcodec.h" -#include "internal.h" -#include "aac_ac3_parser.h" -#include "ac3.h" -#include "ac3_parser.h" -#include "ac3dec.h" -#include "ac3dec_data.h" -#include "eac3dec_data.h" - -/** gain adaptive quantization mode */ -typedef enum { - EAC3_GAQ_NO =0, - EAC3_GAQ_12, - EAC3_GAQ_14, - EAC3_GAQ_124 -} EAC3GaqMode; - -#define EAC3_SR_CODE_REDUCED 3 - -void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) -{ - int bin, bnd, ch, i; - uint8_t wrapflag[SPX_MAX_BANDS]={1,0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS]; - float rms_energy[SPX_MAX_BANDS]; - - /* Set copy index mapping table. Set wrap flags to apply a notch filter at - wrap points later on. */ - bin = s->spx_dst_start_freq; - num_copy_sections = 0; - for (bnd = 0; bnd < s->num_spx_bands; bnd++) { - int copysize; - int bandsize = s->spx_band_sizes[bnd]; - if (bin + bandsize > s->spx_src_start_freq) { - copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq; - bin = s->spx_dst_start_freq; - wrapflag[bnd] = 1; - } - for (i = 0; i < bandsize; i += copysize) { - if (bin == s->spx_src_start_freq) { - copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq; - bin = s->spx_dst_start_freq; - } - copysize = FFMIN(bandsize - i, s->spx_src_start_freq - bin); - bin += copysize; - } - } - copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq; - - for (ch = 1; ch <= s->fbw_channels; ch++) { - if (!s->channel_uses_spx[ch]) - continue; - - /* Copy coeffs from normal bands to extension bands */ - bin = s->spx_src_start_freq; - for (i = 0; i < num_copy_sections; i++) { - memcpy(&s->transform_coeffs[ch][bin], - &s->transform_coeffs[ch][s->spx_dst_start_freq], - copy_sizes[i]*sizeof(float)); - bin += copy_sizes[i]; - } - - /* Calculate RMS energy for each SPX band. */ - bin = s->spx_src_start_freq; - for (bnd = 0; bnd < s->num_spx_bands; bnd++) { - int bandsize = s->spx_band_sizes[bnd]; - float accum = 0.0f; - for (i = 0; i < bandsize; i++) { - float coeff = s->transform_coeffs[ch][bin++]; - accum += coeff * coeff; - } - rms_energy[bnd] = sqrtf(accum / bandsize); - } - - /* Apply a notch filter at transitions between normal and extension - bands and at all wrap points. */ - if (s->spx_atten_code[ch] >= 0) { - const float *atten_tab = ff_eac3_spx_atten_tab[s->spx_atten_code[ch]]; - bin = s->spx_src_start_freq - 2; - for (bnd = 0; bnd < s->num_spx_bands; bnd++) { - if (wrapflag[bnd]) { - float *coeffs = &s->transform_coeffs[ch][bin]; - coeffs[0] *= atten_tab[0]; - coeffs[1] *= atten_tab[1]; - coeffs[2] *= atten_tab[2]; - coeffs[3] *= atten_tab[1]; - coeffs[4] *= atten_tab[0]; - } - bin += s->spx_band_sizes[bnd]; - } - } - - /* Apply noise-blended coefficient scaling based on previously - calculated RMS energy, blending factors, and SPX coordinates for - each band. */ - bin = s->spx_src_start_freq; - for (bnd = 0; bnd < s->num_spx_bands; bnd++) { - float nscale = s->spx_noise_blend[ch][bnd] * rms_energy[bnd] * (1.0f/(1<<31)); - float sscale = s->spx_signal_blend[ch][bnd]; - for (i = 0; i < s->spx_band_sizes[bnd]; i++) { - float noise = nscale * (int32_t)av_lfg_get(&s->dith_state); - s->transform_coeffs[ch][bin] *= sscale; - s->transform_coeffs[ch][bin++] += noise; - } - } - } -} - - -/** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */ -#define COEFF_0 10273905LL - -/** lrint(M_SQRT2*cos(0*M_PI/12)*(1<<23)) = lrint(M_SQRT2*(1<<23)) */ -#define COEFF_1 11863283LL - -/** lrint(M_SQRT2*cos(5*M_PI/12)*(1<<23)) */ -#define COEFF_2 3070444LL - -/** - * Calculate 6-point IDCT of the pre-mantissas. - * All calculations are 24-bit fixed-point. - */ -static void idct6(int pre_mant[6]) -{ - int tmp; - int even0, even1, even2, odd0, odd1, odd2; - - odd1 = pre_mant[1] - pre_mant[3] - pre_mant[5]; - - even2 = ( pre_mant[2] * COEFF_0) >> 23; - tmp = ( pre_mant[4] * COEFF_1) >> 23; - odd0 = ((pre_mant[1] + pre_mant[5]) * COEFF_2) >> 23; - - even0 = pre_mant[0] + (tmp >> 1); - even1 = pre_mant[0] - tmp; - - tmp = even0; - even0 = tmp + even2; - even2 = tmp - even2; - - tmp = odd0; - odd0 = tmp + pre_mant[1] + pre_mant[3]; - odd2 = tmp + pre_mant[5] - pre_mant[3]; - - pre_mant[0] = even0 + odd0; - pre_mant[1] = even1 + odd1; - pre_mant[2] = even2 + odd2; - pre_mant[3] = even2 - odd2; - pre_mant[4] = even1 - odd1; - pre_mant[5] = even0 - odd0; -} - -void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch) -{ - int bin, blk, gs; - int end_bap, gaq_mode; - GetBitContext *gbc = &s->gbc; - int gaq_gain[AC3_MAX_COEFS]; - - gaq_mode = get_bits(gbc, 2); - end_bap = (gaq_mode < 2) ? 12 : 17; - - /* if GAQ gain is used, decode gain codes for bins with hebap between - 8 and end_bap */ - gs = 0; - if (gaq_mode == EAC3_GAQ_12 || gaq_mode == EAC3_GAQ_14) { - /* read 1-bit GAQ gain codes */ - for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { - if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < end_bap) - gaq_gain[gs++] = get_bits1(gbc) << (gaq_mode-1); - } - } else if (gaq_mode == EAC3_GAQ_124) { - /* read 1.67-bit GAQ gain codes (3 codes in 5 bits) */ - int gc = 2; - for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { - if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < 17) { - if (gc++ == 2) { - int group_code = get_bits(gbc, 5); - if (group_code > 26) { - av_log(s->avctx, AV_LOG_WARNING, "GAQ gain group code out-of-range\n"); - group_code = 26; - } - gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][0]; - gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][1]; - gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][2]; - gc = 0; - } - } - } - } - - gs=0; - for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { - int hebap = s->bap[ch][bin]; - int bits = ff_eac3_bits_vs_hebap[hebap]; - if (!hebap) { - /* zero-mantissa dithering */ - for (blk = 0; blk < 6; blk++) { - s->pre_mantissa[ch][bin][blk] = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000; - } - } else if (hebap < 8) { - /* Vector Quantization */ - int v = get_bits(gbc, bits); - for (blk = 0; blk < 6; blk++) { - s->pre_mantissa[ch][bin][blk] = ff_eac3_mantissa_vq[hebap][v][blk] << 8; - } - } else { - /* Gain Adaptive Quantization */ - int gbits, log_gain; - if (gaq_mode != EAC3_GAQ_NO && hebap < end_bap) { - log_gain = gaq_gain[gs++]; - } else { - log_gain = 0; - } - gbits = bits - log_gain; - - for (blk = 0; blk < 6; blk++) { - int mant = get_sbits(gbc, gbits); - if (log_gain && mant == -(1 << (gbits-1))) { - /* large mantissa */ - int b; - int mbits = bits - (2 - log_gain); - mant = get_sbits(gbc, mbits); - mant <<= (23 - (mbits - 1)); - /* remap mantissa value to correct for asymmetric quantization */ - if (mant >= 0) - b = 1 << (23 - log_gain); - else - b = ff_eac3_gaq_remap_2_4_b[hebap-8][log_gain-1] << 8; - mant += ((ff_eac3_gaq_remap_2_4_a[hebap-8][log_gain-1] * (int64_t)mant) >> 15) + b; - } else { - /* small mantissa, no GAQ, or Gk=1 */ - mant <<= 24 - bits; - if (!log_gain) { - /* remap mantissa value for no GAQ or Gk=1 */ - mant += (ff_eac3_gaq_remap_1[hebap-8] * (int64_t)mant) >> 15; - } - } - s->pre_mantissa[ch][bin][blk] = mant; - } - } - idct6(s->pre_mantissa[ch][bin]); - } -} - -int ff_eac3_parse_header(AC3DecodeContext *s) -{ - int i, blk, ch; - int ac3_exponent_strategy, parse_aht_info, parse_spx_atten_data; - int parse_transient_proc_info; - int num_cpl_blocks; - GetBitContext *gbc = &s->gbc; - - /* An E-AC-3 stream can have multiple independent streams which the - application can select from. each independent stream can also contain - dependent streams which are used to add or replace channels. */ - if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { - av_log_missing_feature(s->avctx, "Dependent substream decoding", 1); - return AAC_AC3_PARSE_ERROR_FRAME_TYPE; - } else if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) { - av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n"); - return AAC_AC3_PARSE_ERROR_FRAME_TYPE; - } - - /* The substream id indicates which substream this frame belongs to. each - independent stream has its own substream id, and the dependent streams - associated to an independent stream have matching substream id's. */ - if (s->substreamid) { - /* only decode substream with id=0. skip any additional substreams. */ - av_log_missing_feature(s->avctx, "Additional substreams", 1); - return AAC_AC3_PARSE_ERROR_FRAME_TYPE; - } - - if (s->bit_alloc_params.sr_code == EAC3_SR_CODE_REDUCED) { - /* The E-AC-3 specification does not tell how to handle reduced sample - rates in bit allocation. The best assumption would be that it is - handled like AC-3 DolbyNet, but we cannot be sure until we have a - sample which utilizes this feature. */ - av_log_missing_feature(s->avctx, "Reduced sampling rates", 1); - return -1; - } - skip_bits(gbc, 5); // skip bitstream id - - /* volume control params */ - for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { - skip_bits(gbc, 5); // skip dialog normalization - if (get_bits1(gbc)) { - skip_bits(gbc, 8); // skip compression gain word - } - } - - /* dependent stream channel map */ - if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { - if (get_bits1(gbc)) { - skip_bits(gbc, 16); // skip custom channel map - } - } - - /* mixing metadata */ - if (get_bits1(gbc)) { - /* center and surround mix levels */ - if (s->channel_mode > AC3_CHMODE_STEREO) { - skip_bits(gbc, 2); // skip preferred stereo downmix mode - if (s->channel_mode & 1) { - /* if three front channels exist */ - skip_bits(gbc, 3); //skip Lt/Rt center mix level - s->center_mix_level = get_bits(gbc, 3); - } - if (s->channel_mode & 4) { - /* if a surround channel exists */ - skip_bits(gbc, 3); //skip Lt/Rt surround mix level - s->surround_mix_level = get_bits(gbc, 3); - } - } - - /* lfe mix level */ - if (s->lfe_on && get_bits1(gbc)) { - // TODO: use LFE mix level - skip_bits(gbc, 5); // skip LFE mix level code - } - - /* info for mixing with other streams and substreams */ - if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) { - for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { - // TODO: apply program scale factor - if (get_bits1(gbc)) { - skip_bits(gbc, 6); // skip program scale factor - } - } - if (get_bits1(gbc)) { - skip_bits(gbc, 6); // skip external program scale factor - } - /* skip mixing parameter data */ - switch(get_bits(gbc, 2)) { - case 1: skip_bits(gbc, 5); break; - case 2: skip_bits(gbc, 12); break; - case 3: { - int mix_data_size = (get_bits(gbc, 5) + 2) << 3; - skip_bits_long(gbc, mix_data_size); - break; - } - } - /* skip pan information for mono or dual mono source */ - if (s->channel_mode < AC3_CHMODE_STEREO) { - for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { - if (get_bits1(gbc)) { - /* note: this is not in the ATSC A/52B specification - reference: ETSI TS 102 366 V1.1.1 - section: E.1.3.1.25 */ - skip_bits(gbc, 8); // skip pan mean direction index - skip_bits(gbc, 6); // skip reserved paninfo bits - } - } - } - /* skip mixing configuration information */ - if (get_bits1(gbc)) { - for (blk = 0; blk < s->num_blocks; blk++) { - if (s->num_blocks == 1 || get_bits1(gbc)) { - skip_bits(gbc, 5); - } - } - } - } - } - - /* informational metadata */ - if (get_bits1(gbc)) { - skip_bits(gbc, 3); // skip bit stream mode - skip_bits(gbc, 2); // skip copyright bit and original bitstream bit - if (s->channel_mode == AC3_CHMODE_STEREO) { - skip_bits(gbc, 4); // skip Dolby surround and headphone mode - } - if (s->channel_mode >= AC3_CHMODE_2F2R) { - skip_bits(gbc, 2); // skip Dolby surround EX mode - } - for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { - if (get_bits1(gbc)) { - skip_bits(gbc, 8); // skip mix level, room type, and A/D converter type - } - } - if (s->bit_alloc_params.sr_code != EAC3_SR_CODE_REDUCED) { - skip_bits1(gbc); // skip source sample rate code - } - } - - /* converter synchronization flag - If frames are less than six blocks, this bit should be turned on - once every 6 blocks to indicate the start of a frame set. - reference: RFC 4598, Section 2.1.3 Frame Sets */ - if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && s->num_blocks != 6) { - skip_bits1(gbc); // skip converter synchronization flag - } - - /* original frame size code if this stream was converted from AC-3 */ - if (s->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT && - (s->num_blocks == 6 || get_bits1(gbc))) { - skip_bits(gbc, 6); // skip frame size code - } - - /* additional bitstream info */ - if (get_bits1(gbc)) { - int addbsil = get_bits(gbc, 6); - for (i = 0; i < addbsil + 1; i++) { - skip_bits(gbc, 8); // skip additional bit stream info - } - } - - /* audio frame syntax flags, strategy data, and per-frame data */ - - if (s->num_blocks == 6) { - ac3_exponent_strategy = get_bits1(gbc); - parse_aht_info = get_bits1(gbc); - } else { - /* less than 6 blocks, so use AC-3-style exponent strategy syntax, and - do not use AHT */ - ac3_exponent_strategy = 1; - parse_aht_info = 0; - } - - s->snr_offset_strategy = get_bits(gbc, 2); - parse_transient_proc_info = get_bits1(gbc); - - s->block_switch_syntax = get_bits1(gbc); - if (!s->block_switch_syntax) - memset(s->block_switch, 0, sizeof(s->block_switch)); - - s->dither_flag_syntax = get_bits1(gbc); - if (!s->dither_flag_syntax) { - for (ch = 1; ch <= s->fbw_channels; ch++) - s->dither_flag[ch] = 1; - } - s->dither_flag[CPL_CH] = s->dither_flag[s->lfe_ch] = 0; - - s->bit_allocation_syntax = get_bits1(gbc); - if (!s->bit_allocation_syntax) { - /* set default bit allocation parameters */ - s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[2]; - s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[1]; - s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab [1]; - s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[2]; - s->bit_alloc_params.floor = ff_ac3_floor_tab [7]; - } - - s->fast_gain_syntax = get_bits1(gbc); - s->dba_syntax = get_bits1(gbc); - s->skip_syntax = get_bits1(gbc); - parse_spx_atten_data = get_bits1(gbc); - - /* coupling strategy occurance and coupling use per block */ - num_cpl_blocks = 0; - if (s->channel_mode > 1) { - for (blk = 0; blk < s->num_blocks; blk++) { - s->cpl_strategy_exists[blk] = (!blk || get_bits1(gbc)); - if (s->cpl_strategy_exists[blk]) { - s->cpl_in_use[blk] = get_bits1(gbc); - } else { - s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; - } - num_cpl_blocks += s->cpl_in_use[blk]; - } - } else { - memset(s->cpl_in_use, 0, sizeof(s->cpl_in_use)); - } - - /* exponent strategy data */ - if (ac3_exponent_strategy) { - /* AC-3-style exponent strategy syntax */ - for (blk = 0; blk < s->num_blocks; blk++) { - for (ch = !s->cpl_in_use[blk]; ch <= s->fbw_channels; ch++) { - s->exp_strategy[blk][ch] = get_bits(gbc, 2); - } - } - } else { - /* LUT-based exponent strategy syntax */ - for (ch = !((s->channel_mode > 1) && num_cpl_blocks); ch <= s->fbw_channels; ch++) { - int frmchexpstr = get_bits(gbc, 5); - for (blk = 0; blk < 6; blk++) { - s->exp_strategy[blk][ch] = ff_eac3_frm_expstr[frmchexpstr][blk]; - } - } - } - /* LFE exponent strategy */ - if (s->lfe_on) { - for (blk = 0; blk < s->num_blocks; blk++) { - s->exp_strategy[blk][s->lfe_ch] = get_bits1(gbc); - } - } - /* original exponent strategies if this stream was converted from AC-3 */ - if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && - (s->num_blocks == 6 || get_bits1(gbc))) { - skip_bits(gbc, 5 * s->fbw_channels); // skip converter channel exponent strategy - } - - /* determine which channels use AHT */ - if (parse_aht_info) { - /* For AHT to be used, all non-zero blocks must reuse exponents from - the first block. Furthermore, for AHT to be used in the coupling - channel, all blocks must use coupling and use the same coupling - strategy. */ - s->channel_uses_aht[CPL_CH]=0; - for (ch = (num_cpl_blocks != 6); ch <= s->channels; ch++) { - int use_aht = 1; - for (blk = 1; blk < 6; blk++) { - if ((s->exp_strategy[blk][ch] != EXP_REUSE) || - (!ch && s->cpl_strategy_exists[blk])) { - use_aht = 0; - break; - } - } - s->channel_uses_aht[ch] = use_aht && get_bits1(gbc); - } - } else { - memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht)); - } - - /* per-frame SNR offset */ - if (!s->snr_offset_strategy) { - int csnroffst = (get_bits(gbc, 6) - 15) << 4; - int snroffst = (csnroffst + get_bits(gbc, 4)) << 2; - for (ch = 0; ch <= s->channels; ch++) - s->snr_offset[ch] = snroffst; - } - - /* transient pre-noise processing data */ - if (parse_transient_proc_info) { - for (ch = 1; ch <= s->fbw_channels; ch++) { - if (get_bits1(gbc)) { // channel in transient processing - skip_bits(gbc, 10); // skip transient processing location - skip_bits(gbc, 8); // skip transient processing length - } - } - } - - /* spectral extension attenuation data */ - for (ch = 1; ch <= s->fbw_channels; ch++) { - if (parse_spx_atten_data && get_bits1(gbc)) { - s->spx_atten_code[ch] = get_bits(gbc, 5); - } else { - s->spx_atten_code[ch] = -1; - } - } - - /* block start information */ - if (s->num_blocks > 1 && get_bits1(gbc)) { - /* reference: Section E2.3.2.27 - nblkstrtbits = (numblks - 1) * (4 + ceiling(log2(words_per_frame))) - The spec does not say what this data is or what it's used for. - It is likely the offset of each block within the frame. */ - int block_start_bits = (s->num_blocks-1) * (4 + av_log2(s->frame_size-2)); - skip_bits_long(gbc, block_start_bits); - av_log_missing_feature(s->avctx, "Block start info", 1); - } - - /* syntax state initialization */ - for (ch = 1; ch <= s->fbw_channels; ch++) { - s->first_spx_coords[ch] = 1; - s->first_cpl_coords[ch] = 1; - } - s->first_cpl_leak = 1; - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/eac3dec_data.c b/tizen/distrib/ffmpeg/libavcodec/eac3dec_data.c deleted file mode 100644 index 031702e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eac3dec_data.c +++ /dev/null @@ -1,1134 +0,0 @@ -/* - * E-AC-3 decoder tables - * Copyright (c) 2007 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Tables taken directly from the E-AC-3 spec. - */ - -#include "eac3dec_data.h" -#include "ac3.h" - -const uint8_t ff_eac3_bits_vs_hebap[20] = { - 0, 2, 3, 4, 5, 7, 8, 9, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, -}; - -/** - * Table E3.6, Gk=1 - * No gain (Gk=1) inverse quantization, remapping scale factors - * ff_eac3_gaq_remap[hebap+8] - */ -const int16_t ff_eac3_gaq_remap_1[12] = { - 4681, 2185, 1057, 520, 258, 129, 64, 32, 16, 8, 2, 0 -}; - -/** - * Table E3.6, Gk=2 & Gk=4, A - * Large mantissa inverse quantization, remapping scale factors - * ff_eac3_gaq_remap_2_4_a[hebap-8][Gk=2,4] - */ -const int16_t ff_eac3_gaq_remap_2_4_a[9][2] = { - { -10923, -4681 }, - { -14043, -6554 }, - { -15292, -7399 }, - { -15855, -7802 }, - { -16124, -7998 }, - { -16255, -8096 }, - { -16320, -8144 }, - { -16352, -8168 }, - { -16368, -8180 } -}; - -/** - * Table E3.6, Gk=2 & Gk=4, B - * Large mantissa inverse quantization, negative mantissa remapping offsets - * ff_eac3_gaq_remap_3_4_b[hebap-8][Gk=2,4] - */ -const int16_t ff_eac3_gaq_remap_2_4_b[9][2] = { - { -5461, -1170 }, - { -11703, -4915 }, - { -14199, -6606 }, - { -15327, -7412 }, - { -15864, -7805 }, - { -16126, -7999 }, - { -16255, -8096 }, - { -16320, -8144 }, - { -16352, -8168 } -}; - -static const int16_t vq_hebap1[4][6] = { -{ 7167, 4739, 1106, 4269, 10412, 4820}, -{ -5702, -3187, -14483, -1392, -2027, 849}, -{ 633, 6199, 7009, -12779, -2306, -2636}, -{ -1468, -7031, 7592, 10617, -5946, -3062}, -}; -static const int16_t vq_hebap2[8][6] = { -{ -12073, 608, -7019, 590, 4000, 869}, -{ 6692, 15689, -6178, -9239, -74, 133}, -{ 1855, -989, 20596, -2920, -4475, 225}, -{ -1194, -3901, -821, -6566, -875, -20298}, -{ -2762, -3181, -4094, -5623, -16945, 9765}, -{ 1547, 6839, 1980, 20233, -1071, -4986}, -{ 6221, -17915, -5516, 6266, 358, 1162}, -{ 3753, -1066, 4283, -3227, 15928, 10186}, -}; -static const int16_t vq_hebap3[16][6] = { -{ -10028, 20779, 10982, -4560, 798, -68}, -{ 11050, 20490, -6617, -5342, -1797, -1631}, -{ 3977, -542, 7118, -1166, 18844, 14678}, -{ -4320, -96, -7295, -492, -22050, -4277}, -{ 2692, 5856, 5530, 21862, -7212, -5325}, -{ -135, -23391, 962, 8115, -644, 382}, -{ -1563, 3400, -3299, 4693, -6892, 22398}, -{ 3535, 3030, 7296, 6214, 20476, -12099}, -{ 57, -6823, 1848, -22349, -5919, 6823}, -{ -821, -3655, -387, -6253, -1735, -22373}, -{ -6046, 1586, -18890, -14392, 9214, 705}, -{ -5716, 264, -17964, 14618, 7921, -337}, -{ -110, 108, 8, 74, -89, -50}, -{ 6612, -1517, 21687, -1658, -7949, -246}, -{ 21667, -6335, -8290, -101, -1349, -22}, -{ -22003, -6476, 7974, 648, 2054, -331}, -}; -static const int16_t vq_hebap4[32][6] = { -{ 6636, -4593, 14173, -17297, -16523, 864}, -{ 3658, 22540, 104, -1763, -84, 6}, -{ 21580, -17815, -7282, -1575, -2078, -320}, -{ -2233, 10017, -2728, 14938, -13640, -17659}, -{ -1564, -17738, -19161, 13735, 2757, 2951}, -{ 4520, 5510, 7393, 10799, 19231, -13770}, -{ 399, 2976, -1099, 5013, -1159, 22095}, -{ 3624, -2359, 4680, -2238, 22702, 3765}, -{ -4201, -8285, -6810, -12390, -18414, 15382}, -{ -5198, -6869, -10047, -8364, -16022, -20562}, -{ -142, -22671, -368, 4391, -464, -13}, -{ 814, -1118, -1089, -22019, 74, 1553}, -{ -1618, 19222, -17642, -13490, 842, -2309}, -{ 4689, 16490, 20813, -15387, -4164, -3968}, -{ -3308, 11214, -13542, 13599, -19473, 13770}, -{ 1817, 854, 21225, -966, -1643, -268}, -{ -2587, -107, -20154, 376, 1174, -304}, -{ -2919, 453, -5390, 750, -22034, -978}, -{ -19012, 16839, 10000, -3580, 2211, 1459}, -{ 1363, -2658, -33, -4067, 1165, -21985}, -{ -8592, -2760, -17520, -15985, 14897, 1323}, -{ 652, -9331, 3253, -14622, 12181, 19692}, -{ -6361, 5773, -15395, 17291, 16590, -2922}, -{ -661, -601, 1609, 22610, 992, -1045}, -{ 4961, 9107, 11225, 7829, 16320, 18627}, -{ -21872, -1433, 138, 1470, -1891, -196}, -{ -19499, -18203, 11056, -516, 2543, -2249}, -{ -1196, -17574, 20150, 11462, -401, 2619}, -{ 4638, -8154, 11891, -15759, 17615, -14955}, -{ -83, 278, 323, 55, -154, 232}, -{ 7788, 1462, 18395, 15296, -15763, -1131}, -}; -static const int16_t vq_hebap5[128][6] = { -{ -3394, -19730, 2963, 9590, 4660, 19673}, -{ -15665, -6405, 17671, 3860, -8232, -19429}, -{ 4467, 412, -17873, -8037, 691, -17307}, -{ 3580, 2363, 6886, 3763, 6379, -20522}, -{ -17230, -14133, -1396, -23939, 8373, -12537}, -{ -8073, -21469, -15638, 3214, 8105, -5965}, -{ 4343, 5169, 2683, -16822, -5146, -16558}, -{ 6348, -10668, 12995, -25500, -22090, 4091}, -{ -2880, -8366, -5968, -17158, -2638, 23132}, -{ -5095, -14281, -22371, 21741, 3689, 2961}, -{ -2443, -17739, 25155, 2707, 1594, 7}, -{ -18379, 9010, 4270, 731, -426, -640}, -{ -23695, 24732, 5642, 612, -308, -964}, -{ -767, 1268, 225, 1635, 173, 916}, -{ 5455, 6493, 4902, 10560, 23041, -17140}, -{ 17219, -21054, -18716, 4936, -3420, 3357}, -{ -1390, 15488, -21946, -14611, 1339, 542}, -{ -6866, -2254, -12070, -3075, -19981, -20622}, -{ -1803, 11775, 1343, 8917, 693, 24497}, -{ -21610, 9462, 4681, 9254, -7815, 15904}, -{ -5559, -3018, -9169, -1347, -22547, 12868}, -{ -366, 5076, -1727, 20427, -283, -2923}, -{ -1886, -6313, -939, -2081, -1399, 3513}, -{ -3161, -537, -5075, 11268, 19396, 989}, -{ 2345, 4153, 5769, -4273, 233, -399}, -{ -21894, -1138, -16474, 5902, 5488, -3211}, -{ 10007, -12530, 18829, 20932, -1158, 1790}, -{ -1165, 5014, -1199, 6415, -8418, -21038}, -{ 1892, -3534, 3815, -5846, 16427, 20288}, -{ -2664, -11627, -4147, -18311, -22710, 14848}, -{ 17256, 10419, 7764, 12040, 18956, 2525}, -{ -21419, -18685, -10897, 4368, -7051, 4539}, -{ -1574, 2050, 5760, 24756, 15983, 17678}, -{ -538, -22867, 11067, 10301, 385, 528}, -{ -8465, -3025, -16357, -23237, 16491, 3654}, -{ 5840, 575, 11890, 1947, 25157, 6653}, -{ 6625, -3516, -1964, 3850, -390, -116}, -{ 18005, 20900, 14323, -7621, -10922, 11802}, -{ -4857, -2932, -13334, -7815, 21622, 2267}, -{ -579, -9431, -748, -21321, 12367, 8265}, -{ -8317, 1375, -17847, 2921, 9062, 22046}, -{ 18398, 8635, -1503, -2418, -18295, -14734}, -{ -2987, 15129, -3331, 22300, 13878, -13639}, -{ 5874, -19026, 15587, 11350, -20738, 1971}, -{ 1581, -6955, -21440, 2455, 65, 414}, -{ 515, -4468, -665, -4672, 125, -19222}, -{ 21495, -20301, -1872, -1926, -211, -1022}, -{ 5189, -12250, -1775, -23550, -4546, 5813}, -{ 321, -6331, 14646, 6975, -1773, 867}, -{ -13814, 3180, 7927, 444, 19552, 3146}, -{ -6660, 12252, -1972, 17408, -24280, -12956}, -{ -745, 14356, -1107, 23742, -9631, -18344}, -{ 18284, -7909, -7531, 19118, 7721, -12659}, -{ 1926, 15101, -12848, 2153, 21631, 1864}, -{ -2130, 23416, 17056, -15597, -1544, 87}, -{ 8314, -11824, 14581, -20591, 7891, -2099}, -{ 19600, 22814, -17304, -2040, 285, -3863}, -{ -8214, -18322, 10724, -13744, -13469, -1666}, -{ 14351, 4880, -20034, 964, -4221, -180}, -{ -24598, -16635, 19724, 5925, 4777, 4414}, -{ -2495, 23493, -16141, 2918, -1038, -2010}, -{ 18974, -2540, 13343, 1405, -6194, -1136}, -{ 2489, 13670, 22638, -7311, -129, -2792}, -{ -13962, 16775, 23012, 728, 3397, 162}, -{ 3038, 993, 8774, -21969, -6609, 910}, -{ -12444, -22386, -2626, -5295, 19520, 9872}, -{ -1911, -18274, -18506, -14962, 4760, 7119}, -{ 8298, -2978, 25886, 7660, -7897, 1020}, -{ 6132, 15127, 18757, -24370, -6529, -6627}, -{ 7924, 12125, -9459, -23962, 5502, 937}, -{ -17056, -5373, 2522, 327, 1129, -390}, -{ 15774, 19955, -10380, 11172, -3107, 14853}, -{ -11904, -8091, -17928, -22287, -17237, -6803}, -{ -12862, -2172, -6509, 5927, 12458, -22355}, -{ -497, 322, 1038, -6643, -5404, 20311}, -{ 1083, -22984, -8494, 12130, -762, 2623}, -{ 5067, 19712, -1901, -30, -325, 85}, -{ 987, -5830, 4212, -9030, 9121, -25038}, -{ -7868, 7284, -12292, 12914, -21592, 20941}, -{ -1630, -7694, -2187, -8525, -5604, -25196}, -{ -6668, 388, -22535, 1526, 9082, 193}, -{ -7867, -22308, 5163, 362, 944, -259}, -{ 3824, -11850, 7591, -23176, 25342, 23771}, -{ -10504, 4123, -21111, 21173, 22439, -838}, -{ -4723, 21795, 6184, -122, 1642, -717}, -{ 24504, 19887, -2043, 986, 7, -55}, -{ -27313, -135, 2437, 259, 89, 307}, -{ 24446, -3873, -5391, -820, -2387, 361}, -{ 5529, 5784, 18682, 242, -21896, -4003}, -{ 22304, 4483, 722, -12242, 7570, 15448}, -{ 8673, 3009, 20437, 21108, -21100, -3080}, -{ -1132, 2705, -1825, 5420, -785, 18532}, -{ 16932, -13517, -16509, -14858, -20327, -14221}, -{ 2219, 1380, 21474, -1128, 327, 83}, -{ -2177, 21517, -3856, -14180, -204, -2191}, -{ 953, -9426, 15874, -10710, -3231, 21030}, -{ -421, -1377, 640, -8239, -20976, 2174}, -{ 4309, 18514, -9100, -18319, -15518, 3704}, -{ -5943, 449, -8387, 1075, -22210, -4992}, -{ 2953, 12788, 18285, 1430, 14937, 21731}, -{ -2913, 401, -4739, -20105, 1699, -1147}, -{ 3449, 5241, 8853, 22134, -7547, 1451}, -{ -2154, 8584, 18120, -15614, 19319, -5991}, -{ 3501, 2841, 5897, 6397, 8630, 23018}, -{ 2467, 2956, 379, 5703, -22047, -2189}, -{ -16963, -594, 18822, -5295, 1640, 774}, -{ 2896, -1424, 3586, -2292, 19910, -1822}, -{ -18575, 21219, -14001, -12573, 16466, 635}, -{ -1998, -19314, -16527, 12208, -16576, -7854}, -{ -9674, 1012, -21645, 2883, -12712, 2321}, -{ -1005, 471, -3629, 8045, -11087, 25533}, -{ 4141, -21472, -2673, 756, -663, -523}, -{ 6490, 8531, 19289, 18949, 6092, -9347}, -{ 16965, 24599, 14024, 10072, -536, -10438}, -{ -8147, 2145, -23028, -17073, 5451, -4401}, -{ -14873, 20520, -18303, -9717, -11885, -17831}, -{ -2290, -14120, 2070, 22467, 1671, 725}, -{ -8538, 14629, 3521, -20577, 6673, 8200}, -{ 20248, 4410, -1366, -585, 1229, -2449}, -{ 7467, -7148, 13667, -8246, 22392, -17320}, -{ -1932, 3875, -9064, -3812, 958, 265}, -{ -4399, 2959, -15911, 19598, 4954, -1105}, -{ 18009, -9923, -18137, -3862, 11178, 5821}, -{ -14596, -1227, 9660, 21619, 11228, -11721}, -{ -721, -1700, 109, -2142, 61, -6772}, -{ -24619, -22520, 5608, -1957, -1761, -1012}, -{ -23728, -4451, -2688, -14679, -4266, 9919}, -{ 8495, -894, 20438, -13820, -17267, 139}, -}; -static const int16_t vq_hebap6[256][6] = { -{ 10154, 7365, 16861, 18681, -22893, -3636}, -{ -2619, -3788, -5529, -5192, -9009, -20298}, -{ -5583, -22800, 21297, 7012, 745, 720}, -{ 428, -1459, 109, -3082, 361, -8403}, -{ 8161, 22401, 241, 1755, -874, -2824}, -{ 1140, 12643, 2306, 22263, -25146, -17557}, -{ -2609, 3379, 10337, -19730, -15468, -23944}, -{ -4040, -12796, -25772, 13096, 3905, 1315}, -{ 4624, -23799, 13608, 25317, -1175, 2173}, -{ -97, 13747, -5122, 23255, 4214, -22145}, -{ 6878, -322, 18264, -854, -11916, -733}, -{ 17280, -12669, -9693, 23563, -16240, -1309}, -{ 5802, -4968, 19526, -21194, -24622, -183}, -{ 5851, -16137, 15229, -9496, -1538, 377}, -{ 14096, 25057, 13419, 8290, 23320, 16818}, -{ -7261, 118, -15867, 19097, 9781, -277}, -{ -4288, 21589, -13288, -16259, 16633, -4862}, -{ 4909, -19217, 23411, 14705, -722, 125}, -{ 19462, -4732, -1928, -11527, 20770, 5425}, -{ -27562, -2881, -4331, 384, -2103, 1367}, -{ -266, -9175, 5441, 26333, -1924, 4221}, -{ -2970, -20170, -21816, 5450, -7426, 5344}, -{ -221, -6696, 603, -9140, 1308, -27506}, -{ 9621, -8380, -1967, 9403, -1651, 22817}, -{ 7566, -5250, -4165, 1385, -990, 560}, -{ -1262, 24738, -19057, 10741, 7585, -7098}, -{ 451, 20130, -9949, -6015, -2188, -1458}, -{ 22249, 9380, 9096, 10959, -2365, -3724}, -{ 18668, -650, -1234, 11092, 7678, 5969}, -{ 19207, -1485, -1076, -731, -684, 43}, -{ -4973, 13430, 20139, 60, 476, -935}, -{ -20029, 8710, 2499, 1016, -1158, 335}, -{ -26413, 18598, -2201, -669, 3409, 793}, -{ -4726, 8875, -24607, -9646, 3643, -283}, -{ 13303, -21404, -3691, -1184, -1970, 1612}, -{ 173, 60, 919, 1229, 6942, -665}, -{ 16377, 16991, 5341, -14015, -2304, -20390}, -{ 25334, -10609, 11947, -7653, -6363, 14058}, -{ 23929, -13259, -7226, -937, 234, -187}, -{ 6311, -1877, 12506, -1879, 18751, -23341}, -{ 621, 6445, 3354, -24274, 8406, 5315}, -{ -3297, -5034, -4704, -5080, -25730, 5347}, -{ -1275, -13295, -965, -23318, 1214, 26259}, -{ -6252, 10035, -20105, 15301, -16073, 5136}, -{ 9562, -3911, -19510, 4745, 22270, -4171}, -{ 7978, -19600, 14024, -5745, -20855, 8939}, -{ 7, -4039, 991, -6065, 52, -19423}, -{ 3485, 2969, 7732, 7786, 25312, 6206}, -{ -959, -12812, -1840, -22743, 7324, 10830}, -{ -4686, 1678, -10172, -5205, 4294, -1271}, -{ 3889, 1302, 7450, 638, 20374, -3133}, -{ -12496, -9123, 18463, -12343, -7238, 18552}, -{ -6185, 8649, -6903, -895, 17109, 16604}, -{ -9896, 28579, 2845, 1640, 2925, -298}, -{ 14968, -25988, 14878, -24012, 1815, -6474}, -{ 26107, 5166, 21225, 15873, 21617, 14825}, -{ -21684, 16438, 20504, -14346, -7114, -4162}, -{ 28647, 90, -1572, 789, -902, -75}, -{ -1479, 2471, -4061, 3612, -2240, 10914}, -{ 8616, 17491, 17255, -17456, 17022, -16357}, -{ -20722, -18597, 25274, 17720, -3573, 1695}, -{ -997, 6129, -6303, 11250, -11359, -19739}, -{ -74, -4001, -1584, 13384, 162, -144}, -{ -529, 21068, 7923, -11396, 422, -26}, -{ 7102, -13531, -20055, 2629, -178, -429}, -{ 9201, 1368, -22238, 2623, -20499, 24889}, -{ -432, 6675, -266, 8723, 80, 28024}, -{ 19493, -3108, -9261, 1910, -21777, 5345}, -{ 14079, -11489, 12604, 6079, 19877, 1315}, -{ 10947, 9837, -18612, 15742, 4792, 605}, -{ -1777, 3758, -4087, 21696, 6024, -576}, -{ 3567, -3578, 16379, 2680, -1752, 716}, -{ -5049, -1399, -4550, -652, -17721, -3366}, -{ -3635, -4372, -6522, -22152, 7382, 1458}, -{ 12242, 19190, 5646, -7815, -20289, 21344}, -{ -7508, 19952, 23542, -9753, 5669, -1990}, -{ -2275, 15438, 10907, -17879, 6497, 13582}, -{ -15894, -15646, -4716, 6019, 24250, -6179}, -{ -2049, -6856, -1208, 918, 17735, -69}, -{ -3721, 9099, -16065, -23621, 5981, -2344}, -{ 7862, -8918, 24033, 25508, -11033, -741}, -{ -12588, 19468, 14649, 15451, -21226, 1171}, -{ 2102, 1147, 2789, 4096, 2179, 8750}, -{ -18214, -17758, -10366, -5203, -1066, -3541}, -{ -2819, -19958, -11921, 6032, 8315, 10374}, -{ -9078, -2100, 19431, -17, 732, -689}, -{ -14512, -19224, -7095, 18727, 1870, 22906}, -{ 3912, 659, 25597, -4006, 9619, 877}, -{ 2616, 22695, -5770, 17920, 3812, 20220}, -{ 2561, 26847, -5245, -10908, 2256, -517}, -{ -4974, 198, -21983, -3608, 22174, -18924}, -{ 21308, -1211, 19144, 16691, -1588, 11390}, -{ -1790, 3959, -3488, 7003, -7107, 20877}, -{ -6108, -17955, -18722, 24763, 16508, 3211}, -{ 20462, -24987, -20361, 4484, -5111, -478}, -{ -6378, -1998, -10229, -561, -22039, -22339}, -{ 3047, -18850, 7586, 14743, -19862, 6351}, -{ -5047, 1405, -9672, 1055, -21881, 11170}, -{ 3481, -9699, 6526, -16655, 22813, 21907}, -{ -18570, 17501, 14664, 1291, 5026, 19676}, -{ 16134, -19810, -16956, -17939, -16933, 5800}, -{ -8224, 4908, 8935, 2272, -1140, -23217}, -{ 1572, 2753, -1598, 2143, -3346, -21926}, -{ -9832, -1060, -27818, 1214, 7289, 150}, -{ 98, 1538, 535, 17429, -23198, -901}, -{ 21340, -20146, 3297, -1744, -8207, -21462}, -{ -4166, -4633, -17902, 5478, 1285, 136}, -{ 18713, 21003, 24818, 11421, 1282, -4618}, -{ -3535, 7636, -265, 2141, -829, -2035}, -{ -3184, 19713, 2775, -2, 1090, 104}, -{ -6771, -20185, 2938, -2125, -36, 1268}, -{ 9560, 9430, 9586, 22100, 13827, 6296}, -{ -535, -20018, 4276, -1868, -448, -17183}, -{ -24352, 14244, -13647, -21040, 2271, 11555}, -{ -2646, 15437, -4589, 18638, -4299, -622}, -{ -20064, 4169, 18115, -1404, 13722, -1825}, -{ -16359, 9080, 744, 22021, 125, 10794}, -{ 9644, -14607, -18479, -14714, 11174, -20754}, -{ -326, -23762, 6144, 7909, 602, 1540}, -{ -6650, 6634, -12683, 21396, 20785, -6839}, -{ 4252, -21043, 5628, 18687, 23860, 8328}, -{ 17986, 5704, -5245, -18093, -555, 3219}, -{ 6091, 14232, -5117, -17456, -19452, -11649}, -{ -21586, 11302, 15434, 25590, 6777, -26683}, -{ 21355, -8244, 5877, -3540, 6079, -2567}, -{ 2603, -2455, 5421, -12286, -19100, 5574}, -{ -1721, -26393, -23664, 22904, -349, 3787}, -{ 2189, -1203, 5340, 3249, -22617, 104}, -{ -1664, -11020, -2857, -20723, -24049, 19900}, -{ 22873, -7345, -18481, -14616, -8400, -12965}, -{ 3777, 3958, 8239, 20494, -6991, -1201}, -{ -160, -1613, -793, -8681, 573, 776}, -{ 4297, -3786, 20373, 6082, -5321, -18400}, -{ 18745, 2463, 12546, -7749, -7734, -2183}, -{ 11074, -4720, 22119, 1825, -24351, 4080}, -{ 1503, -19178, -1569, 13, -313, 375}, -{ 318, -575, 2544, 178, 102, 40}, -{ -15996, -26897, 5008, 3320, 686, 1159}, -{ 25755, 26886, 574, -5930, -3916, 1407}, -{ -9148, -7665, -2875, -8384, -18663, 26400}, -{ -7445, -18040, -18396, 8802, -2252, -21886}, -{ 7851, 11773, 27485, -12847, -1410, 19590}, -{ 2240, 5947, 11247, 15980, -6499, 24280}, -{ 21673, -18515, 9771, 6550, -2730, 334}, -{ -4149, 1576, -11010, 89, -24429, -5710}, -{ 7720, 1478, 21412, -25025, -8385, 9}, -{ -2448, 10218, -12756, -16079, 1161, -21284}, -{ -8757, -14429, -22918, -14812, 2629, 13844}, -{ -7252, 2843, -9639, 2882, -14625, 24497}, -{ -674, -6530, 414, -23333, -21343, 454}, -{ 2104, -6312, 10887, 18087, -1199, 175}, -{ -493, -562, -2739, 118, -1074, 93}, -{ -10011, -4075, -28071, 22180, 15077, -636}, -{ -4637, -16408, -9003, -20418, -11608, -20932}, -{ 4815, 15892, 24238, -13634, -3074, -1059}, -{ -6724, 4610, -18772, -15283, -16685, 23988}, -{ 15349, -674, -3682, 21679, 4475, -12088}, -{ 4756, 2593, 5354, 6001, 15063, 26490}, -{ -23815, -17251, 6944, 378, 694, 670}, -{ 23392, -8839, -14713, 7544, -876, 11088}, -{ 3640, 3336, 22593, -3495, -2328, -113}, -{ 284, 6914, 3097, 10171, 6638, -18621}, -{ 2472, 5976, 11054, -11936, -603, -663}, -{ 16175, 16441, 13164, -4043, 4667, 7431}, -{ 19338, 15534, -6533, 1681, -4857, 17048}, -{ 17027, 532, -19064, -1441, -5130, 1085}, -{ -12617, -17609, 2062, -25332, 19009, -16121}, -{ 10056, -21000, -13634, -2949, 15367, 19934}, -{ -648, -1605, 10046, -1592, 13296, 19808}, -{ -1054, 10744, 538, 24938, 9630, -9052}, -{ -10099, 3042, -25076, -24052, 13971, 100}, -{ 6547, 6907, 7031, 10348, 23775, -17886}, -{ -22793, -1984, -1393, -3330, 9267, 14317}, -{ -14346, -3967, 3042, 16254, -17303, 9646}, -{ -21393, 23628, 16773, 716, 2663, 114}, -{ -19016, -3038, 1574, -245, 1463, -793}, -{ 22410, 23441, -14637, -530, 17310, 13617}, -{ -11582, 7935, -13954, 23465, -24628, 26550}, -{ -1045, 3679, -2218, 10572, 20999, -3702}, -{ -15513, 197, 16718, -24603, 4945, 5}, -{ 10781, 4335, 26790, -9059, -16152, -2840}, -{ 16075, -24100, -3933, -6833, 12645, -7029}, -{ 2096, -25572, -8370, 6814, 11, 1178}, -{ -11848, -583, -8889, -20543, -10471, -380}, -{ -2487, 24777, -21639, -19341, 1660, -732}, -{ 2313, 13679, 4085, 24549, 24691, -21179}, -{ -2366, -504, -4130, -10570, 23668, 1961}, -{ 20379, 17809, -9506, 3733, -18954, -6292}, -{ -3856, 16802, -929, -20310, -17739, 6797}, -{ 12431, 6078, -11272, -14450, 6913, 23476}, -{ 7636, -1655, 23017, 10719, -8292, 838}, -{ -8559, -1235, -18096, 3897, 16093, 1490}, -{ -3586, 8276, 15165, -3791, -21149, 1741}, -{ -4497, 21739, 2366, -278, -4792, 15549}, -{ -23122, -13708, 7668, 16232, 24120, 15025}, -{ -20043, 12821, -20160, 16691, -11655, -16081}, -{ -12601, 20239, 3496, -2549, -6745, -11850}, -{ 4441, 7812, 20783, 17080, 11523, -9643}, -{ 24766, 8494, -23298, -3262, 11101, -7120}, -{ -10107, -7623, -22152, -18303, 26645, 9550}, -{ -25549, 477, 7874, -1538, 1123, -168}, -{ 470, 9834, -347, 23945, -10381, -9467}, -{ -4096, -9702, -6856, -21544, 20845, 7174}, -{ 5370, 9748, -23765, -1190, 512, -1538}, -{ -1006, -10046, -12649, 19234, -1790, -890}, -{ 15108, 23620, -15646, -2522, -1203, -1325}, -{ -7406, -2605, 1095, -247, -473, 177}, -{ 8089, 4, 12424, -22284, 10405, -7728}, -{ 22196, 10775, -5043, 690, 534, -212}, -{ -3153, -1418, -16835, 18426, 15821, 22956}, -{ 5681, -2229, 3196, -3414, -21817, -14807}, -{ 19, 787, 1032, 170, -8295, -645}, -{ -882, -2319, -27105, 432, -4392, 1499}, -{ -1354, -11819, -76, -20380, -10293, 11328}, -{ 211, -4753, -4675, -6933, -13538, 14479}, -{ 6043, 5260, -459, -462, 143, -65}, -{ -2572, 7256, -3317, 9212, -23184, -9990}, -{ -24882, -9532, 18874, 6101, 2429, -14482}, -{ 8314, 2277, 14192, 3512, 25881, 22000}, -{ 208, 20218, -281, -24778, -63, -1183}, -{ 1095, -6034, 2706, -21935, -2655, 563}, -{ 23, -5930, 243, -8989, 5345, 20558}, -{ -15466, 12699, 4160, 11087, 20621, -10416}, -{ 20995, -85, -8468, 194, 1003, -9515}, -{ -19637, -3335, -14081, 3574, -23381, -667}, -{ -2076, 3489, -3192, -19367, 539, -1530}, -{ 7352, -15213, 22596, 19369, 1043, 16627}, -{ -1872, -413, 1235, -5276, -3550, 21903}, -{ 7931, -2008, 16968, -6799, 29393, -2475}, -{ -13589, 8389, -23636, -22091, -14178, -14297}, -{ -11575, -20090, 16056, -1848, 15721, 4500}, -{ 3849, -16581, 20161, -21155, 7778, 11864}, -{ -6547, -1273, -18837, -11218, 11636, 1044}, -{ 2528, -6691, -17917, -11362, -4894, -1008}, -{ 1241, 4260, 2319, 6111, 3485, 20209}, -{ 3014, -3048, 5316, -4539, 20831, 8702}, -{ -1790, -14683, 278, 13956, -10065, -10547}, -{ -22732, -7957, -1154, 13821, -1484, -1247}, -{ -7317, -615, 13094, 18927, 9897, 1452}, -{ 2552, -2338, 3424, -4630, 11124, -19584}, -{ -11125, -20553, -10855, -10783, -20767, 6833}, -{ 984, -15095, 5775, 25125, 5377, -19799}, -{ 517, 13272, -7458, -1711, 20612, -6013}, -{ -21417, 13251, -20795, 13449, 17281, 13104}, -{ -15811, -16248, 23093, -4037, -8195, 871}, -{ 582, 12571, -21129, -14766, -9187, 5685}, -{ 4318, -1776, 11425, -17763, -9921, 577}, -{ 6013, 16830, 17655, -25766, -4400, -3550}, -{ -13744, -16541, 3636, -3330, -21091, -15886}, -{ 6565, -11147, 8649, -13114, 23345, -13565}, -{ -2542, -9046, -7558, 29240, 3701, -383}, -{ -10612, 24995, 1893, -8210, 20920, -16210}, -{ 5276, 16726, 10659, 19940, -4799, -19324}, -{ -532, -9300, 27856, 4965, -241, 536}, -{ -765, -20706, -3412, 18870, 2765, 1420}, -{ -3059, 2708, -19022, -331, 3537, 116}, -}; -static const int16_t vq_hebap7[512][6] = { -{ -21173, 21893, 10390, 13646, 10718, -9177}, -{ -22519, -8193, 18328, -6629, 25518, -10848}, -{ 6800, -13758, -13278, 22418, 14667, -20938}, -{ 2347, 10516, 1125, -3455, 5569, 27136}, -{ -6617, 11851, -24524, 22937, 20362, -6019}, -{ -21768, 10681, -19615, -15021, -8478, -2081}, -{ -2745, 8684, -4895, 27739, 7554, -11961}, -{ -1020, 2460, -954, 4754, -627, -16368}, -{ -19702, 23097, 75, -13684, -2644, 2108}, -{ 4049, -2872, 5851, -4459, 22150, 12560}, -{ -21304, -17129, -730, 7419, -11658, -10523}, -{ 11332, 1792, 26666, 23518, -19561, -491}, -{ -17827, -16777, -13606, -14389, -22029, -2464}, -{ 1091, -5967, -7975, -16977, -20432, -21931}, -{ 18388, -1103, 1933, 13342, -17463, 18114}, -{ 22646, 17345, -9966, 17919, 18274, 698}, -{ 1484, 20297, -5754, -26515, 4941, -22263}, -{ -2603, 4587, -5842, 18464, 8767, -2568}, -{ -2797, -1602, 21713, 3099, -25683, 3224}, -{ -19027, 4693, -5007, 6060, 1972, -15095}, -{ -2189, 9516, -530, 20669, -4662, -8301}, -{ -22325, -8887, 2529, -11352, 5476, 998}, -{ 22100, -5052, 1651, -2657, 4615, 2319}, -{ 20855, -3078, -3330, 4105, 13470, 3069}, -{ 85, 17289, 10264, -14752, 214, 90}, -{ -26365, -18849, -19352, 19244, -10218, 9909}, -{ -9739, 20497, -6579, -6983, 2891, -738}, -{ 20575, -15860, -22913, 6870, 76, 327}, -{ 8744, -12877, -22945, -2372, -19424, -9771}, -{ -12886, 16183, 21084, 3821, 749, -13792}, -{ -15995, 18399, 2391, -17661, 19484, -6018}, -{ 1423, 11734, 4051, 19290, 6857, -19681}, -{ -5200, 9766, 18246, 2463, 18764, -4852}, -{ -597, 19498, 1323, -9096, -308, -1104}, -{ -3099, -25731, -15665, 25332, 4634, 2635}, -{ 19623, -2384, -7913, 11796, -9333, -14084}, -{ 2642, 26453, -21091, -10354, -1693, -1711}, -{ 22031, 21625, 11580, -22915, -4141, 129}, -{ -6122, 3542, 915, -261, -17, -383}, -{ 1696, 6704, -1425, 20838, 857, -4416}, -{ 1423, -15280, -8550, -9667, 5210, 5687}, -{ -4520, -613, -11683, 5618, 4230, 619}, -{ 937, -4963, -14102, -17104, -6906, -5952}, -{ -15068, -481, -7237, -14894, 18876, 21673}, -{ -25658, 2910, 1143, -327, -458, -995}, -{ -9656, -819, -24900, 2804, 20225, 1083}, -{ -1111, -3682, -1788, -19492, 966, 821}, -{ 7293, -21759, 10790, -7059, -23293, -1723}, -{ -282, -11093, 170, -20950, -28926, 12615}, -{ 17938, 3713, -1563, 885, 5, 564}, -{ 6116, 22696, 2242, -6951, 9975, -6132}, -{ 4338, 26808, -3705, 1976, -1079, -2570}, -{ -661, -7901, -2668, -15194, 17722, 4375}, -{ -4174, -11053, 717, -22506, 1562, 12252}, -{ -6405, 18334, 6103, 6983, 5956, 18195}, -{ 9851, 5370, 23604, -6861, -6569, -62}, -{ 21964, 13359, -683, 3785, 2168, 209}, -{ -3569, -1127, -19724, -1544, 1308, -803}, -{ -3083, 16049, -13791, -3077, 4294, 23713}, -{ -9999, 9943, -15872, 12934, -23631, 21699}, -{ 9722, 22837, 12192, 15091, 5533, 4837}, -{ 2243, 2099, 1243, 4089, 4748, 12956}, -{ 4007, -2468, 3353, -3092, 8843, 17024}, -{ 4330, 6127, 5549, 9249, 11226, 28592}, -{ -9586, -8825, 236, 1009, 455, -964}, -{ 6829, 19290, -1018, 200, 1821, 578}, -{ 5196, 957, 10372, 3330, -12800, -127}, -{ -3022, -8193, -14557, 22061, 5920, 1053}, -{ 10982, 25942, -24546, -23278, -11905, -6789}, -{ 22667, -11010, 5736, 2567, 23705, -10253}, -{ -3343, -4233, -5458, 20667, -10843, -3605}, -{ -4131, -3612, 4575, -829, -350, -847}, -{ -3303, 3451, -7398, -11604, 3023, 455}, -{ 3200, -9547, 3202, -22893, 11184, -26466}, -{ -14093, -4117, 15382, 14295, -10915, -20377}, -{ 3807, -11016, 22052, 14370, -15328, -7733}, -{ -6291, -17719, -1560, 12048, -19805, -443}, -{ -6147, -4234, -160, 8363, 22638, 11911}, -{ 19197, 1175, 7422, -9875, -4136, 4704}, -{ -72, -7652, -112, -11955, -3230, 27175}, -{ 3274, 5963, 7501, -17019, 866, -25452}, -{ 737, 1861, 1833, 2022, 2384, 4755}, -{ -5217, 7512, 3323, 2715, 3065, -1606}, -{ 4247, 565, 5629, 2497, 18019, -4920}, -{ -2833, -17920, -8062, 15738, -1018, 2136}, -{ 3050, -19483, 16930, 29835, -10222, 15153}, -{ -11346, 118, -25796, -13761, 15320, -468}, -{ -4824, 4960, -4263, 1575, -10593, 19561}, -{ -8203, -1409, -763, -1139, -607, 1408}, -{ -2203, -11415, 2021, -6388, -2600, 711}, -{ -413, -2511, -216, -3519, -28267, 1719}, -{ -14446, 17050, 13917, 13499, -25762, -16121}, -{ 19228, 7341, -12301, 682, -3791, -199}, -{ -4193, 20746, -15651, 11349, 5860, -824}, -{ -21490, -3546, -3, -1705, -3959, 9213}, -{ 15445, -1876, 2012, -19627, 16228, -4845}, -{ -2867, -3733, -7354, -175, -20119, 11174}, -{ -3571, -24587, 19700, 6654, 979, -654}, -{ 21820, -7430, -6639, -10767, -8362, 15543}, -{ 14827, 17977, -7204, -3409, 1906, -17288}, -{ 3525, -3947, -1415, -2798, 17648, 2082}, -{ -6580, -15255, -17913, 1337, 15338, 21158}, -{ 6210, 9698, 15155, -24666, -22507, -3999}, -{ -1740, -593, 1095, -7779, 25058, 5601}, -{ 21415, -432, -1658, -6898, -1438, -14454}, -{ -6943, 700, -12139, -745, -24187, 22466}, -{ 6287, 3283, 11006, 3844, 19184, 14781}, -{ -22502, 15274, 5443, -2808, -970, -3343}, -{ 3257, -3708, 4744, -8301, 22814, -10208}, -{ 24346, -20970, 19846, 987, -11958, -6277}, -{ 3906, -19701, 13060, -1609, 18641, 7466}, -{ -26409, -22549, 16305, 2014, 10975, 18032}, -{ -7039, 4655, -14818, 18739, 15789, 1296}, -{ 9310, -1681, 14667, -3326, 26535, -11853}, -{ 5728, 5917, 13400, 10020, -2236, -24704}, -{ 1741, -6727, 12695, -22009, 4080, 5450}, -{ -2621, 9393, 21143, -25938, -3162, -2529}, -{ 20672, 18894, -13939, 6990, -8260, 15811}, -{ -23818, 11183, -13639, 11868, 16045, 2630}, -{ 18361, -10220, 829, 856, -1010, 157}, -{ 14400, -4678, 5153, -13290, -27434, -11028}, -{ 21613, 11256, 17453, 7604, 13130, -484}, -{ 7, 1236, 573, 4214, 5576, -3081}, -{ 916, -9092, 1285, -8958, 1185, -28699}, -{ 21587, 23695, 19116, -2885, -14282, -8438}, -{ 23414, -6161, 12978, 3061, -9351, 2236}, -{ -3070, -7344, -20140, 5788, 582, -551}, -{ -3993, 315, -7773, 8224, -28082, -12465}, -{ 13766, -15357, 19205, -20624, 13043, -19247}, -{ 3777, -177, 8029, -1001, 17812, 5162}, -{ -7308, -4327, -18096, -620, -1350, 14932}, -{ 14756, -1221, -12819, -14922, -547, 27125}, -{ 2234, 1708, 2764, 5416, 7986, -25163}, -{ 2873, 3636, 3992, 5344, 10142, 21259}, -{ 1158, 5379, 508, -10514, 290, -1615}, -{ 1114, 24789, 16575, -25168, -298, -2832}, -{ -1107, -6144, -1918, -7791, -2971, -23276}, -{ 4016, 10793, 17317, -4342, -20982, -3383}, -{ -4494, -207, -9951, -3575, 7947, 1154}, -{ -7576, 8117, -14047, 16982, -26457, -27540}, -{ -15164, 16096, -16844, -8886, -23720, 15906}, -{ 24922, 5680, -1874, 420, 132, 117}, -{ -506, -19310, -198, 412, -311, 752}, -{ -1906, 3981, -7688, 16566, -19291, -14722}, -{ -399, -729, -3807, -4196, -12395, 7639}, -{ 3368, 2330, 9092, 23686, -10290, -1705}, -{ -3148, 2596, -7986, 14602, -4807, 16627}, -{ 8057, 1481, 49, 17205, 24869, 7474}, -{ -19304, -513, 11905, 2346, 5588, 3365}, -{ -5063, -21812, 11370, 10896, 4881, 261}, -{ 4794, 20577, 5109, -6025, -8049, -1521}, -{ 8125, -14756, 20639, -14918, 23941, -3650}, -{ 12451, 1381, 3613, 8687, -24002, 4848}, -{ 6726, 10643, 10086, 25217, -25159, -1065}, -{ 6561, 13977, 2911, 21737, 16465, -26050}, -{ -1776, 2575, -19606, -16800, 3032, 6679}, -{ 15012, -17910, -8438, -21554, -27111, 11808}, -{ 3448, -924, -15913, -1135, 5126, -20613}, -{ 7720, 2226, 17463, 5434, 28942, 17552}, -{ 1246, 15614, -11743, 24618, -17539, 3272}, -{ 3215, 17950, 2783, -722, -22672, 5979}, -{ -5678, -3184, -26087, 26034, 6583, 3302}, -{ 20310, -3555, -2715, -444, -1487, 1526}, -{ -20640, -21970, -12207, -25793, 8863, -1036}, -{ 17888, 570, -16102, 8329, -2553, 15275}, -{ -2677, 9950, -1879, 16477, -12762, -29007}, -{ -120, -2221, 219, 97, 365, 35}, -{ 1270, -718, 1480, -2689, 1930, -7527}, -{ 1896, 8750, 1906, 18235, -12692, -6174}, -{ -3733, 13713, -9882, -15960, -1376, -7146}, -{ -10600, 8496, 15967, -8792, 7532, 20439}, -{ 3041, -13457, 1032, -26952, 5787, 24984}, -{ -4590, -8220, -9322, -6112, -17243, 25745}, -{ -17808, 6970, 3752, 626, -114, 2178}, -{ 4449, -4862, 7054, -5404, 4738, -2827}, -{ 4922, -651, 18939, -9866, 848, 1886}, -{ -336, -5410, 7234, 20444, -9583, -600}, -{ 781, -19474, -12648, 6634, 1414, 450}, -{ -3399, -16770, 11107, 13200, -5498, 21663}, -{ -3265, 4859, -5961, 7530, -10837, 28086}, -{ 10350, -12901, 25699, 25640, -639, 351}, -{ 1163, 18763, -5466, -15087, -145, -1377}, -{ -14477, 27229, -31383, -32653, 21439, -2894}, -{ 15420, 18823, 22128, 19398, 22583, 13587}, -{ -10674, 10710, 5089, -4756, 909, -20760}, -{ -12948, -20660, 7410, 2722, 3427, 11585}, -{ -1105, 18374, 19731, -9650, 22442, 19634}, -{ -296, -6798, -14677, 21603, 19796, 21399}, -{ -19350, -7501, 25446, 13144, 8588, -25298}, -{ 3092, -10618, 20896, 9249, -3326, 1796}, -{ -811, 1449, 3106, 4748, 12073, -14262}, -{ -20720, 14275, -4332, -25838, -5781, -21149}, -{ -5132, 10554, -14020, -22150, 2840, -554}, -{ 25533, 17648, 14886, -21074, 2459, 25142}, -{ -9370, -1788, -12862, -5870, -25811, -11023}, -{ 6698, 819, 10313, 166, 27581, 523}, -{ 101, -19388, 3413, 9638, 64, 806}, -{ -2742, -17931, -2576, 22818, 8553, 1126}, -{ 2972, 15203, 1792, 25434, -5728, -17265}, -{ -1419, 1604, 4398, 11452, 1731, 23787}, -{ -5136, 4625, -10653, 27981, 9897, -2510}, -{ -10528, -28033, 2999, -1530, -832, -830}, -{ -11133, -12511, 22206, -7243, -23578, -21698}, -{ 16935, -21892, 1861, -9606, 9432, 19026}, -{ 10277, 9516, 26815, 2010, -4943, -9080}, -{ 5547, -2210, 14270, -15300, -19316, 1822}, -{ -4850, -783, -8959, -3076, -20056, -3197}, -{ 8232, -2794, -17752, 13308, 3229, -991}, -{ -12237, -6581, 10315, -9552, 2260, -20648}, -{ -7000, 5529, -7553, -7490, -10342, -10266}, -{ 3641, 19479, -5972, -19097, -18570, 12805}, -{ 1283, -4164, 4198, -28473, -2498, 1866}, -{ 16047, 26826, -13053, -6316, 985, -1597}, -{ -403, 13680, 6457, 25070, 27124, -20710}, -{ -18070, -1790, -24986, 5953, -954, 26600}, -{ -24224, -15383, 24788, 1953, -1136, 187}, -{ -2289, 12505, -20738, -904, 18324, 21258}, -{ 2658, -6140, 16179, 22276, -556, 2154}, -{ -6087, 13950, -25682, -27713, 4049, -4795}, -{ -21452, 26473, 19435, -9124, 895, 303}, -{ -22200, -26177, -6026, 24729, -22926, -9030}, -{ -14276, -15982, 23732, -22851, 9268, -3841}, -{ 29482, 21923, -6213, 1679, -2059, -1120}, -{ -435, 9802, -3891, 12359, -4288, -18971}, -{ 19768, -86, 2467, 1990, -1021, -5354}, -{ 20986, -8783, -5329, -23562, -4730, 2673}, -{ -5095, 5605, -4629, 19150, 26037, -12259}, -{ 972, 6858, 4551, 27949, -4025, -2272}, -{ 6075, -3260, -4989, -373, -1571, -3730}, -{ -7256, -12992, -8820, -5109, 23054, 5054}, -{ 920, 2615, 7912, -7353, -4905, 20186}, -{ -250, 5454, 3140, 6928, -18723, -2051}, -{ -10299, -4372, 19608, 4879, -661, -1885}, -{ 14816, -8603, -19815, 6135, -21210, 14108}, -{ -11945, -2223, 5018, 11892, 22741, 406}, -{ -13184, -2613, -13256, -22433, -12482, -8380}, -{ 17066, 25267, -2273, 5056, -342, 145}, -{ 8401, -17683, 19112, 10615, -19453, 17083}, -{ 20821, -5700, 12298, -25598, 10391, 7692}, -{ 4550, 15779, 17338, -19379, -4768, 1206}, -{ -7723, 10836, -27164, -11439, 6835, -1776}, -{ 2542, 3199, 4442, 17513, -3711, -914}, -{ 20960, -16774, -5814, 11087, -70, 22961}, -{ 3305, 2919, 6256, -4800, -20966, -3230}, -{ 5924, -16547, 2183, 2733, 3446, -23306}, -{ -6061, -194, -13852, -10971, 19488, 1029}, -{ 4467, -5964, -19004, 1519, -359, 855}, -{ -1581, -7607, 22070, -11580, -10032, 17102}, -{ -12412, 2553, 4324, 22500, 5751, 12170}, -{ -25127, 17996, -6384, 1180, 1182, 9622}, -{ 23462, -8471, -4392, -2669, 7638, -16835}, -{ -5511, -2887, -10757, -20883, 7246, 1053}, -{ 2703, -20602, -7554, 7516, -7740, 5868}, -{ 20670, 21901, 457, 14969, -17657, -11921}, -{ 3603, -1595, -2177, -157, -43, 605}, -{ 2513, 8954, 10527, 22559, -16100, -16041}, -{ 6002, 4951, 6795, -4862, -22400, 18849}, -{ 7590, -1693, -24688, -3404, 14169, 1214}, -{ -4398, -6663, -6870, -10083, -24596, 9253}, -{ 10468, 17751, -7748, 147, -6314, 4419}, -{ 16187, -16557, -4119, 4302, 7625, 5409}, -{ 3303, 2735, 7458, -19902, -2254, -3702}, -{ -2077, 21609, 14870, 12545, -6081, -1764}, -{ 4678, 11740, 2859, 6953, 1919, -3871}, -{ 3522, -21853, -2469, -10453, 18893, -10742}, -{ 3759, -10191, -4866, -2659, -17831, -1242}, -{ 14991, 9351, 11870, -1573, -4848, 22549}, -{ 9509, -27152, 10734, 20851, -26185, -17878}, -{ -7170, -1392, -19495, 12746, 8198, -1988}, -{ 1883, 28158, -846, -7235, 249, 233}, -{ -7200, 669, -371, -2948, 23234, -5635}, -{ 3141, 288, 3223, -1258, -98, -27607}, -{ 17373, -23235, 5110, -11199, -2574, -11487}, -{ -4928, 1518, -5456, 670, -18278, 1951}, -{ 10334, -19865, -4649, 361, -160, -923}, -{ 18732, 14264, -3155, -7485, -3328, 5959}, -{ -3614, 21077, 7276, 3536, 8121, -1528}, -{ -8422, 500, -19182, 18929, 26392, -1039}, -{ 15639, 25668, 8375, 1903, 1945, -11979}, -{ -2716, 3389, 26850, -4587, 1803, 22}, -{ 1177, -655, 1233, -2128, 7844, 1767}, -{ -761, 8209, -19290, -4593, 1923, -343}, -{ -689, -3530, -3267, -3804, -2753, 18566}, -{ -2110, 1962, -1353, 16643, 2765, -23102}, -{ -433, 4905, 302, 13016, 15933, -5905}, -{ 3203, 4126, 11181, -5496, -2529, -1160}, -{ -1091, -6469, -1415, 5682, -268, 583}, -{ -9405, -19572, 6216, 1658, 993, -75}, -{ -1695, -4504, -2289, -4088, -6556, -16577}, -{ 4760, -892, -10902, 6516, 24199, -6011}, -{ -253, 1000, 63, -81, -115, -382}, -{ -1333, 24224, -698, -4667, -2801, -19144}, -{ -876, -28866, -21873, 12677, -6344, 3235}, -{ 16847, 21145, -26172, -3183, -396, 230}, -{ 18296, -7790, -12857, -679, -1473, 5}, -{ -10488, 11429, 25805, -1122, 1401, -438}, -{ 3782, -7429, 26720, 17567, 19257, 12542}, -{ 6332, -746, 12789, 9316, -22542, -5354}, -{ 3418, -22728, 26978, 18303, 1076, 956}, -{ -27315, -2988, 920, 235, 2233, 81}, -{ 6199, 5296, 16093, 14768, -8429, -1112}, -{ -6432, 19244, 9921, -3253, 1278, -954}, -{ 24213, 2049, -22931, 2585, -2410, -4216}, -{ 9286, 14282, -19735, -3985, -2344, 1028}, -{ -20128, 17993, -9458, 23012, -16983, 8625}, -{ -6896, -20730, 3762, 17415, 22341, 19024}, -{ 842, 24181, 25062, -5839, -78, 937}, -{ -621, 19722, -24204, -1962, -14854, -56}, -{ 22766, -5119, 17365, 23868, -19480, -6558}, -{ -2158, 17490, -21435, 3340, -12819, -20295}, -{ -9621, 17325, 715, 2265, -4123, -492}, -{ 9156, 12947, 27303, -21175, -6072, -9457}, -{ -13164, -23269, -14006, -4184, 6978, 2}, -{ 938, -13381, 3520, -24297, 22902, 19589}, -{ -4911, -19774, 19764, -9310, -12650, 3819}, -{ -5462, -4249, -6987, -6260, -13943, -25150}, -{ 9341, 10369, -13862, -6704, 22556, -519}, -{ 6651, 18768, -4855, 12570, 14730, -10209}, -{ -823, 18119, 398, -1582, -116, -363}, -{ -6935, -12694, -28392, 8552, 6961, -239}, -{ -2602, -4704, -1021, 2015, 5129, 23670}, -{ -12559, -8190, -25028, 18544, 14179, 1663}, -{ 3813, 21036, -9620, -5051, -1800, -1087}, -{ -22057, 16675, 14960, 9459, 2786, 16991}, -{ -26040, -19318, -6414, 1104, 5798, -18039}, -{ -1737, 24825, 10417, -11087, 896, -5273}, -{ -1855, 11661, -2803, 24809, -21435, -19792}, -{ -23473, -16729, -5782, 5643, 2636, 4940}, -{ -1724, 4388, -26673, -13695, 10570, -25895}, -{ 15358, -19496, 26242, -18493, 1736, 8054}, -{ 5684, 20890, 4091, -19100, -14588, -10468}, -{ 17260, -16291, 14859, -17711, -19174, 12435}, -{ -27185, -12573, 6743, -562, 976, -257}, -{ 12395, -8618, -22248, -19843, 11013, 7762}, -{ 3799, 11853, -27622, -8473, 1089, -1495}, -{ 4141, -2182, -26720, -735, -774, 1469}, -{ 3125, 13762, 4606, 29257, 18771, -9958}, -{ -17465, -9445, -17562, -2530, -6435, -3726}, -{ -1742, 4351, -6841, -19773, 9627, -10654}, -{ 7251, 3525, 10835, 5601, 25198, -23348}, -{ -10300, -17830, 631, 11640, 2044, -20878}, -{ -873, -8502, -1063, -15674, -10693, 14934}, -{ -15957, 28137, 5268, 477, -1053, 1158}, -{ -1495, -8814, -5764, -24965, 25988, 7907}, -{ -1038, -114, -2308, -1319, -6480, 1472}, -{ 4895, -17897, -25850, 5301, -188, 1581}, -{ 3200, 17225, 4346, 22101, -18543, 22028}, -{ -10250, 545, -10932, 2276, -28070, 8118}, -{ 15343, 2329, 9316, 20537, 14908, 21021}, -{ 6329, 6130, -24508, 837, -8637, -5844}, -{ 7386, -501, 10503, 20131, 11435, -4755}, -{ -2745, 24174, -9274, 15273, -8389, -5835}, -{ 2992, -2864, 6048, -7473, 11687, -19996}, -{ -883, -11954, -9976, -21829, -4436, -27178}, -{ 3458, 19626, 1280, 2597, 19849, 5255}, -{ -5315, 19133, -14518, -8946, 13749, -1352}, -{ 18642, 17655, 11001, 6817, -18418, 6336}, -{ -1697, 2244, -4640, 3948, -12890, -5273}, -{ 20428, 10542, 4170, -1012, 19439, 21691}, -{ -2943, -19735, -4208, 1320, 909, -8897}, -{ 9351, -8066, -2618, -12933, 26582, 3507}, -{ 9705, -22628, 8311, 8167, -13293, 5608}, -{ 3222, 3749, -1508, 165, -52, -196}, -{ 102, -22744, -8832, 903, -11421, -14662}, -{ -120, 5998, 19765, 13401, 3628, 5197}, -{ 8528, 5827, -1066, 774, -39, -166}, -{ 9411, -9476, 9581, -13004, 24456, 24900}, -{ 17878, 2235, -21639, 20478, 4716, -7190}, -{ -2482, 9511, 1611, -21943, 14230, -1289}, -{ 9288, -2291, 23215, -3452, -10842, 11}, -{ 9496, 3041, 5130, -3890, -21219, -22589}, -{ 14262, -9838, 20195, 14019, 91, -17200}, -{ -18591, 980, 17, 821, 120, -574}, -{ 12285, -19269, 13742, 16373, -161, 6025}, -{ -3364, 1530, -4005, 2454, -10872, -23839}, -{ 105, 5085, -260, 5790, -588, 19170}, -{ 4121, 4169, 13439, 14644, 20899, 7434}, -{ -175, 13101, -3704, 23233, 3907, 10106}, -{ -6101, 23467, 5204, -1341, 1599, 13174}, -{ -3217, -3494, 15117, -8387, -11762, -4750}, -{ 1146, 4675, -19378, 14917, -5091, 249}, -{ -21506, 10136, -16473, -13305, 18382, -8601}, -{ 628, 2447, 3344, 3130, -5115, 119}, -{ 17900, -22422, -17633, 21967, -16293, -7676}, -{ 16863, 24214, 5612, -3858, -809, 3822}, -{ -2291, 10091, -2360, -25109, -1226, 312}, -{ 2957, 11256, 26745, -13266, -3455, -1128}, -{ -19762, -2708, 4604, 6355, 1638, 25501}, -{ -19593, -7753, 3159, -85, -489, -1855}, -{ 814, 12510, 19077, -4681, -2610, -1474}, -{ -23408, -19027, 8137, 19878, 7912, -282}, -{ 839, -19652, 11927, 27278, -3211, 2266}, -{ 4020, -1110, 8226, -1274, 20922, 25060}, -{ 26576, 325, -8693, -232, -2218, -699}, -{ -11293, -4200, 1805, -6673, -22940, -1339}, -{ -2005, -15886, -1047, -27687, -13235, 14370}, -{ -22073, 1949, 13175, -15656, -1846, 8055}, -{ 3039, 12025, 7132, -24632, 413, -2347}, -{ -24048, -206, 12459, -6654, -417, -10091}, -{ 18179, -23688, -20515, -16396, 7230, 763}, -{ 5659, -5085, 13878, -23729, -11077, -19587}, -{ 11340, 501, 25040, 7616, -19658, 1605}, -{ -26650, 8878, 10544, 417, 1299, 261}, -{ 14460, 11369, -3263, 9990, 8194, 18111}, -{ 1355, -20838, -9196, -16060, -8559, -730}, -{ -1918, -20937, -18293, -2461, -2651, 4316}, -{ -2810, 24521, -10996, -25721, 308, -1234}, -{ -9075, -17280, -1833, -29342, -24213, -16631}, -{ -2843, 10165, -5339, -2888, 21858, -21340}, -{ -15832, 14849, -23780, 5184, 10113, -20639}, -{ -19535, -11361, 8413, 1486, -23658, -5759}, -{ -7512, 1027, -20794, 13732, 19892, -21934}, -{ -12132, -7022, -19175, -8840, 22125, -16490}, -{ 1937, 5210, -6318, -23788, 13141, 11082}, -{ -205, 6036, -380, 8658, -233, 28020}, -{ -5523, 7477, 7635, 23595, 9763, -2590}, -{ 21658, -28313, -3086, -300, -1032, 1744}, -{ -22352, 16646, 208, 6665, -17400, -3028}, -{ 18482, 9336, -2737, -19372, 407, -4389}, -{ -4913, -17370, 18819, -17654, 13416, 15232}, -{ 7749, 6368, 23135, -18174, 7584, -4248}, -{ -1489, -6523, 586, -10157, 14964, 25568}, -{ 3844, -6156, 4897, -13045, -22526, 5647}, -{ -8491, -2105, -24774, 905, -9326, 1456}, -{ -3040, -1476, 1166, -4428, 11236, 9204}, -{ 3397, -1451, 13598, -15841, 24540, 5819}, -{ 8483, -2993, 21547, -16916, 7741, 24018}, -{ -14932, -23758, -5332, -6664, -4497, 13267}, -{ 19379, 12916, -2142, -737, 21100, -22101}, -{ 3393, -4629, 5735, -18913, -6969, 2687}, -{ 1148, -16147, -21433, -28095, -630, -14449}, -{ 7300, 672, 18530, -17452, -10149, 351}, -{ 11356, -10974, 17212, 4624, 145, 17791}, -{ -711, -3479, -2238, 15887, 2027, 0}, -{ -28048, 1794, -593, -2758, -21852, 11535}, -{ -19683, 4937, 22004, 21523, -3148, 1790}, -{ 813, 8231, 2633, 11981, -3043, 22201}, -{ 8952, -24760, -690, 14873, -2366, -5372}, -{ 8406, -5439, -274, -642, -145, 778}, -{ -6605, 7258, 20780, -23507, -18625, 22782}, -{ -22896, -25488, 10020, -1614, 1508, -1393}, -{ 7607, 407, -24678, -16385, -1804, -4699}, -{ -10592, -19139, 10462, -3747, 8721, -6919}, -{ 13010, 5292, -6230, -4884, -20904, -1797}, -{ 16891, -13770, -465, 19343, -10741, -12959}, -{ 25193, -14799, -5681, -521, -321, -1211}, -{ 6917, -3093, 20183, -26903, -12026, 1295}, -{ 305, 1992, 19457, -985, 25, -521}, -{ 6707, -3698, 8365, -8687, 21921, -27166}, -{ 4668, 5997, 7117, 11696, 24401, -10794}, -{ 744, -9416, 19893, 1963, 7922, -9824}, -{ 3430, 21282, -1736, 10844, 8821, 27015}, -{ -8813, 1521, -24038, 1651, 7838, -1208}, -{ 3911, -11221, 3273, -12541, 7168, 18402}, -{ 21642, 9117, -11536, -5256, 7077, 2382}, -{ 100, 3817, -6713, 1244, 1518, -321}, -{ 7946, -18670, 10667, -4866, 727, 776}, -{ -15883, -8150, -2087, 22739, 1567, -3482}, -{ 4380, -2735, 8469, -7025, -11424, 1317}, -{ 26970, 4393, 7665, 17561, -714, 650}, -{ -16191, -835, 8365, 1795, -14314, 16297}, -{ 4504, -10048, 7662, -26690, -17428, 2580}, -{ 48, -3984, 564, -5871, 2658, -18658}, -{ 12579, -26016, -15642, 2672, -1347, -887}, -{ -4950, 4208, -6811, 2569, -20621, -8658}, -{ -1836, -14818, -5571, -23322, -14800, 25867}, -{ 5434, -28139, -2357, -2883, -570, 2431}, -{ 13096, -2771, 24994, -12496, -24723, -1025}, -{ -5676, -4339, 1908, 18628, -21323, 17366}, -{ 27660, -27897, -15409, 1436, -7112, -2241}, -{ 8019, 3847, 24568, -469, 9674, 10683}, -{ -903, -10149, 1801, -21260, 4795, -8751}, -{ 1122, -9582, 2625, 22791, 956, 882}, -{ 7876, 19075, -9900, -24266, 7496, 9277}, -{ 980, -26764, -5386, 5396, 1086, 1648}, -{ 28838, -1270, -447, 5, -429, -20}, -{ -15283, 6132, 22812, 1252, -9963, 511}, -{ 851, 7925, -457, -12210, 4261, 7579}, -{ -4530, 8452, -1246, 14501, -24951, -5760}, -{ -17814, -10727, 9887, -23929, -13432, 1878}, -{ -15049, 10165, 16491, -14603, -11712, -21156}, -{ -3317, 840, -5683, 22413, 1994, 586}, -{ 23158, -5788, -15043, -10372, -9271, -13523}, -{ -773, -9509, -3993, -24264, 8463, 5804}, -{ -8545, -703, -12440, -3985, -25122, -28147}, -{ -16659, 16001, 2746, 1611, 5097, -1043}, -{ 41, -7181, 19903, 31555, -32237, 13927}, -{ -5658, 845, -12774, 5705, 16695, -86}, -{ 5282, 14875, 27026, 21124, 15776, -10477}, -{ 14712, 19648, -11487, -13361, -20196, -15229}, -{ 8597, -9138, -626, 10891, -6015, 6346}, -{ -1488, -1272, -1479, -1303, -3704, -5485}, -{ -3370, 17871, -6604, 24930, 25886, -3127}, -{ 8416, 27783, -1385, 5350, -4260, 19993}, -{ 5688, 362, 17246, 3809, -3246, 1088}, -{ -105, -29607, 2747, 15223, -167, 3722}, -{ 3502, -3195, 8602, 7772, -1566, -915}, -{ -491, 3257, -2423, 5522, 20606, -100}, -{ -13948, -11368, -15375, -21866, -8520, 12221}, -{ -616, 2424, -2023, 4398, -3805, 8108}, -{ -7204, 21043, 21211, -9395, -19391, 896}, -{ -5737, -15160, -21298, 17066, -1006, -366}, -{ 6261, 3240, -11937, -16213, -15820, 6581}, -{ -3155, 24796, 2733, -1257, -875, -1597}, -{ -20469, 11094, 24071, -8987, 14136, 2220}, -{ -14106, 11959, -22495, 4135, -1055, -5420}, -{ 801, -2655, 60, -5324, -790, 5937}, -{ -7372, -1764, -22433, -26060, 21707, 4178}, -{ -5715, -6648, -14908, 1325, -24044, 1493}, -{ -6024, -12488, 23930, 2950, 1601, 1173}, -{ 19067, 17630, 17929, -10654, 10928, -4958}, -{ 3231, -3284, 27336, 4174, -1683, 497}, -}; - -const int16_t (* const ff_eac3_mantissa_vq[8])[6] = { - NULL, - vq_hebap1, - vq_hebap2, - vq_hebap3, - vq_hebap4, - vq_hebap5, - vq_hebap6, - vq_hebap7, -}; - -/** - * Table E2.14 Frame Exponent Strategy Combinations - */ -const uint8_t ff_eac3_frm_expstr[32][6] = { -{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE}, -{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45}, -{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE}, -{ EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45}, -{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE}, -{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45}, -{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE}, -{ EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45}, -{ EXP_D25, EXP_REUSE, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE}, -{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45}, -{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE}, -{ EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45}, -{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE}, -{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45}, -{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE}, -{ EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45, EXP_D45}, -{ EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_REUSE}, -{ EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE, EXP_D45}, -{ EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D25, EXP_REUSE}, -{ EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45, EXP_D45}, -{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_REUSE}, -{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE, EXP_D45}, -{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D25, EXP_REUSE}, -{ EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45, EXP_D45}, -{ EXP_D45, EXP_D45, EXP_D15, EXP_REUSE, EXP_REUSE, EXP_REUSE}, -{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE, EXP_D45}, -{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D25, EXP_REUSE}, -{ EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45, EXP_D45}, -{ EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_REUSE}, -{ EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE, EXP_D45}, -{ EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE}, -{ EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45}, -}; - -/** - * Table E.25: Spectral Extension Attenuation Table - * ff_eac3_spx_atten_tab[code][bin]=pow(2.0,(bin+1)*(code+1)/-15.0); - */ -const float ff_eac3_spx_atten_tab[32][3] = { - { 0.954841603910416503f, 0.911722488558216804f, 0.870550563296124125f }, - { 0.911722488558216804f, 0.831237896142787758f, 0.757858283255198995f }, - { 0.870550563296124125f, 0.757858283255198995f, 0.659753955386447100f }, - { 0.831237896142787758f, 0.690956439983888004f, 0.574349177498517438f }, - { 0.793700525984099792f, 0.629960524947436595f, 0.500000000000000000f }, - { 0.757858283255198995f, 0.574349177498517438f, 0.435275281648062062f }, - { 0.723634618720189082f, 0.523647061410313364f, 0.378929141627599553f }, - { 0.690956439983888004f, 0.477420801955208307f, 0.329876977693223550f }, - { 0.659753955386447100f, 0.435275281648062062f, 0.287174588749258719f }, - { 0.629960524947436595f, 0.396850262992049896f, 0.250000000000000000f }, - { 0.601512518041058319f, 0.361817309360094541f, 0.217637640824031003f }, - { 0.574349177498517438f, 0.329876977693223550f, 0.189464570813799776f }, - { 0.548412489847312945f, 0.300756259020529160f, 0.164938488846611775f }, - { 0.523647061410313364f, 0.274206244923656473f, 0.143587294374629387f }, - { 0.500000000000000000f, 0.250000000000000000f, 0.125000000000000000f }, - { 0.477420801955208307f, 0.227930622139554201f, 0.108818820412015502f }, - { 0.455861244279108402f, 0.207809474035696939f, 0.094732285406899888f }, - { 0.435275281648062062f, 0.189464570813799776f, 0.082469244423305887f }, - { 0.415618948071393879f, 0.172739109995972029f, 0.071793647187314694f }, - { 0.396850262992049896f, 0.157490131236859149f, 0.062500000000000000f }, - { 0.378929141627599553f, 0.143587294374629387f, 0.054409410206007751f }, - { 0.361817309360094541f, 0.130911765352578369f, 0.047366142703449930f }, - { 0.345478219991944002f, 0.119355200488802049f, 0.041234622211652958f }, - { 0.329876977693223550f, 0.108818820412015502f, 0.035896823593657347f }, - { 0.314980262473718298f, 0.099212565748012460f, 0.031250000000000000f }, - { 0.300756259020529160f, 0.090454327340023621f, 0.027204705103003875f }, - { 0.287174588749258719f, 0.082469244423305887f, 0.023683071351724965f }, - { 0.274206244923656473f, 0.075189064755132290f, 0.020617311105826479f }, - { 0.261823530705156682f, 0.068551561230914118f, 0.017948411796828673f }, - { 0.250000000000000000f, 0.062500000000000000f, 0.015625000000000000f }, - { 0.238710400977604098f, 0.056982655534888536f, 0.013602352551501938f }, - { 0.227930622139554201f, 0.051952368508924235f, 0.011841535675862483f } -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/eac3dec_data.h b/tizen/distrib/ffmpeg/libavcodec/eac3dec_data.h deleted file mode 100644 index 1331833..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eac3dec_data.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * E-AC-3 decoder tables - * Copyright (c) 2007 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_EAC3DEC_DATA_H -#define AVCODEC_EAC3DEC_DATA_H - -#include - -extern const uint8_t ff_eac3_bits_vs_hebap[20]; -extern const int16_t ff_eac3_gaq_remap_1[12]; -extern const int16_t ff_eac3_gaq_remap_2_4_a[9][2]; -extern const int16_t ff_eac3_gaq_remap_2_4_b[9][2]; - -extern const int16_t (* const ff_eac3_mantissa_vq[8])[6]; -extern const uint8_t ff_eac3_frm_expstr[32][6]; -extern const float ff_eac3_spx_atten_tab[32][3]; - -#endif /* AVCODEC_EAC3DEC_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/eacmv.c b/tizen/distrib/ffmpeg/libavcodec/eacmv.c deleted file mode 100644 index 517b307..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eacmv.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Electronic Arts CMV Video Decoder - * Copyright (c) 2007-2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts CMV Video Decoder - * by Peter Ross (pross@xvid.org) - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_CMV - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct CmvContext { - AVCodecContext *avctx; - AVFrame frame; ///< current - AVFrame last_frame; ///< last - AVFrame last2_frame; ///< second-last - int width, height; - unsigned int palette[AVPALETTE_COUNT]; -} CmvContext; - -static av_cold int cmv_decode_init(AVCodecContext *avctx){ - CmvContext *s = avctx->priv_data; - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - return 0; -} - -static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){ - unsigned char *dst = s->frame.data[0]; - int i; - - for (i=0; i < s->avctx->height && buf+s->avctx->width<=buf_end; i++) { - memcpy(dst, buf, s->avctx->width); - dst += s->frame.linesize[0]; - buf += s->avctx->width; - } -} - -static void cmv_motcomp(unsigned char *dst, int dst_stride, - const unsigned char *src, int src_stride, - int x, int y, - int xoffset, int yoffset, - int width, int height){ - int i,j; - - for(j=y;j=0 && i+xoffset=0 && j+yoffsetavctx->width*s->avctx->height/16); - int x,y,i; - - i = 0; - for(y=0; yavctx->height/4; y++) - for(x=0; xavctx->width/4 && buf+iframe.data[0] + (y*4)*s->frame.linesize[0] + x*4; - if (raw+16frame.linesize[0], raw+4, 4); - memcpy(dst+2*s->frame.linesize[0], raw+8, 4); - memcpy(dst+3*s->frame.linesize[0], raw+12, 4); - raw+=16; - }else if(raw> 4)) - 7; - cmv_motcomp(s->frame.data[0], s->frame.linesize[0], - s->last2_frame.data[0], s->last2_frame.linesize[0], - x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); - raw++; - } - }else{ /* inter using last frame as reference */ - int xoffset = (buf[i] & 0xF) - 7; - int yoffset = ((buf[i] >> 4)) - 7; - cmv_motcomp(s->frame.data[0], s->frame.linesize[0], - s->last_frame.data[0], s->last_frame.linesize[0], - x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); - } - i++; - } -} - -static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end) -{ - int pal_start, pal_count, i; - - if(buf+16>=buf_end) { - av_log(s->avctx, AV_LOG_WARNING, "truncated header\n"); - return; - } - - s->width = AV_RL16(&buf[4]); - s->height = AV_RL16(&buf[6]); - if (s->avctx->width!=s->width || s->avctx->height!=s->height) - avcodec_set_dimensions(s->avctx, s->width, s->height); - - s->avctx->time_base.num = 1; - s->avctx->time_base.den = AV_RL16(&buf[10]); - - pal_start = AV_RL16(&buf[12]); - pal_count = AV_RL16(&buf[14]); - - buf += 16; - for (i=pal_start; ipalette[i] = AV_RB24(buf); - buf += 3; - } -} - -#define EA_PREAMBLE_SIZE 8 -#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') - -static int cmv_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - CmvContext *s = avctx->priv_data; - const uint8_t *buf_end = buf + buf_size; - - if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { - cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); - return buf_size; - } - - if (avcodec_check_dimensions(s->avctx, s->width, s->height)) - return -1; - - /* shuffle */ - if (s->last2_frame.data[0]) - avctx->release_buffer(avctx, &s->last2_frame); - FFSWAP(AVFrame, s->last_frame, s->last2_frame); - FFSWAP(AVFrame, s->frame, s->last_frame); - - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - if (avctx->get_buffer(avctx, &s->frame)<0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); - - buf += EA_PREAMBLE_SIZE; - if ((buf[0]&1)) { // subtype - cmv_decode_inter(s, buf+2, buf_end); - s->frame.key_frame = 0; - s->frame.pict_type = FF_P_TYPE; - }else{ - s->frame.key_frame = 1; - s->frame.pict_type = FF_I_TYPE; - cmv_decode_intra(s, buf+2, buf_end); - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - return buf_size; -} - -static av_cold int cmv_decode_end(AVCodecContext *avctx){ - CmvContext *s = avctx->priv_data; - if (s->frame.data[0]) - s->avctx->release_buffer(avctx, &s->frame); - if (s->last_frame.data[0]) - s->avctx->release_buffer(avctx, &s->last_frame); - if (s->last2_frame.data[0]) - s->avctx->release_buffer(avctx, &s->last2_frame); - - return 0; -} - -AVCodec eacmv_decoder = { - "eacmv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_CMV, - sizeof(CmvContext), - cmv_decode_init, - NULL, - cmv_decode_end, - cmv_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/eaidct.c b/tizen/distrib/ffmpeg/libavcodec/eaidct.c deleted file mode 100644 index 9972e42..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eaidct.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Electronic Arts TGQ/TQI/MAD IDCT algorithm - * Copyright (c) 2007-2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts TGQ/TQI/MAD IDCT algorithm - * @author Peter Ross - */ - -#include "dsputil.h" - -#define ASQRT 181 /* (1/sqrt(2))<<8 */ -#define A4 669 /* cos(pi/8)*sqrt(2)<<9 */ -#define A2 277 /* sin(pi/8)*sqrt(2)<<9 */ -#define A5 196 /* sin(pi/8)<<9 */ - -#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\ - const int a1 = (src)[s1] + (src)[s7]; \ - const int a7 = (src)[s1] - (src)[s7]; \ - const int a5 = (src)[s5] + (src)[s3]; \ - const int a3 = (src)[s5] - (src)[s3]; \ - const int a2 = (src)[s2] + (src)[s6]; \ - const int a6 = (ASQRT*((src)[s2] - (src)[s6]))>>8; \ - const int a0 = (src)[s0] + (src)[s4]; \ - const int a4 = (src)[s0] - (src)[s4]; \ - const int b0 = (((A4-A5)*a7 - A5*a3)>>9) + a1+a5; \ - const int b1 = (((A4-A5)*a7 - A5*a3)>>9) + ((ASQRT*(a1-a5))>>8); \ - const int b2 = (((A2+A5)*a3 + A5*a7)>>9) + ((ASQRT*(a1-a5))>>8); \ - const int b3 = ((A2+A5)*a3 + A5*a7)>>9; \ - (dest)[d0] = munge(a0+a2+a6+b0); \ - (dest)[d1] = munge(a4+a6 +b1); \ - (dest)[d2] = munge(a4-a6 +b2); \ - (dest)[d3] = munge(a0-a2-a6+b3); \ - (dest)[d4] = munge(a0-a2-a6-b3); \ - (dest)[d5] = munge(a4-a6 -b2); \ - (dest)[d6] = munge(a4+a6 -b1); \ - (dest)[d7] = munge(a0+a2+a6-b0); \ -} -/* end IDCT_TRANSFORM macro */ - -#define MUNGE_NONE(x) (x) -#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src) - -#define MUNGE_8BIT(x) av_clip_uint8((x)>>4) -#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_8BIT,src) - -static inline void ea_idct_col(DCTELEM *dest, const DCTELEM *src) { - if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) { - dest[0] = - dest[8] = - dest[16] = - dest[24] = - dest[32] = - dest[40] = - dest[48] = - dest[56] = src[0]; - }else - IDCT_COL(dest, src); -} - -void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) { - int i; - DCTELEM temp[64]; - block[0] += 4; - for (i=0; i<8; i++) - ea_idct_col(&temp[i], &block[i]); - for (i=0; i<8; i++) - IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) ); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/eamad.c b/tizen/distrib/ffmpeg/libavcodec/eamad.c deleted file mode 100644 index 8fc5ef1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eamad.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Electronic Arts Madcow Video Decoder - * Copyright (c) 2007-2009 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts Madcow Video Decoder - * by Peter Ross - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_MAD - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "aandcttab.h" -#include "mpeg12.h" -#include "mpeg12data.h" - -#define EA_PREAMBLE_SIZE 8 -#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */ -#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD p-frame */ -#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */ - -typedef struct MadContext { - MpegEncContext s; - AVFrame frame; - AVFrame last_frame; - void *bitstream_buf; - unsigned int bitstream_buf_size; - DECLARE_ALIGNED(16, DCTELEM, block)[64]; -} MadContext; - -static void bswap16_buf(uint16_t *dst, const uint16_t *src, int count) -{ - int i; - for (i=0; ipriv_data; - MpegEncContext *s = &t->s; - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_YUV420P; - if (avctx->idct_algo == FF_IDCT_AUTO) - avctx->idct_algo = FF_IDCT_EA; - dsputil_init(&s->dsp, avctx); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); - ff_mpeg12_init_vlcs(); - return 0; -} - -static inline void comp(unsigned char *dst, int dst_stride, - unsigned char *src, int src_stride, int add) -{ - int j, i; - for (j=0; j<8; j++) - for (i=0; i<8; i++) - dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add); -} - -static inline void comp_block(MadContext *t, int mb_x, int mb_y, - int j, int mv_x, int mv_y, int add) -{ - MpegEncContext *s = &t->s; - if (j < 4) { - comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), - t->frame.linesize[0], - t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x, - t->last_frame.linesize[0], add); - } else if (!(s->avctx->flags & CODEC_FLAG_GRAY)) { - int index = j - 3; - comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8, - t->frame.linesize[index], - t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2), - t->last_frame.linesize[index], add); - } -} - -static inline void idct_put(MadContext *t, DCTELEM *block, int mb_x, int mb_y, int j) -{ - MpegEncContext *s = &t->s; - if (j < 4) { - s->dsp.idct_put( - t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), - t->frame.linesize[0], block); - } else if (!(s->avctx->flags & CODEC_FLAG_GRAY)) { - int index = j - 3; - s->dsp.idct_put( - t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x*8, - t->frame.linesize[index], block); - } -} - -static inline void decode_block_intra(MadContext * t, DCTELEM * block) -{ - MpegEncContext *s = &t->s; - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - const uint8_t *scantable = s->intra_scantable.permutated; - int16_t *quant_matrix = s->intra_matrix; - - block[0] = (128 + get_sbits(&s->gb, 8)) * quant_matrix[0]; - - /* The RL decoder is derived from mpeg1_decode_block_intra; - Escaped level and run values a decoded differently */ - i = 0; - { - OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefficients */ - for (;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if (level == 127) { - break; - } else if (level != 0) { - i += run; - j = scantable[i]; - level = (level*quant_matrix[j]) >> 4; - level = (level-1)|1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 10); SKIP_BITS(re, &s->gb, 10); - - UPDATE_CACHE(re, &s->gb); - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - - i += run; - j = scantable[i]; - if (level < 0) { - level = -level; - level = (level*quant_matrix[j]) >> 4; - level = (level-1)|1; - level = -level; - } else { - level = (level*quant_matrix[j]) >> 4; - level = (level-1)|1; - } - } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return; - } - - block[j] = level; - } - CLOSE_READER(re, &s->gb); - } -} - -static int decode_motion(GetBitContext *gb) -{ - int value = 0; - if (get_bits1(gb)) { - if (get_bits1(gb)) - value = -17; - value += get_bits(gb, 4) + 1; - } - return value; -} - -static void decode_mb(MadContext *t, int inter) -{ - MpegEncContext *s = &t->s; - int mv_map = 0; - int mv_x, mv_y; - int j; - - if (inter) { - int v = decode210(&s->gb); - if (v < 2) { - mv_map = v ? get_bits(&s->gb, 6) : 63; - mv_x = decode_motion(&s->gb); - mv_y = decode_motion(&s->gb); - } else { - mv_map = 0; - } - } - - for (j=0; j<6; j++) { - if (mv_map & (1<gb); - comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add); - } else { - s->dsp.clear_block(t->block); - decode_block_intra(t, t->block); - idct_put(t, t->block, s->mb_x, s->mb_y, j); - } - } -} - -static void calc_intra_matrix(MadContext *t, int qscale) -{ - MpegEncContext *s = &t->s; - int i; - - if (s->avctx->idct_algo == FF_IDCT_EA) { - s->intra_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0]) >> 11; - for (i=1; i<64; i++) - s->intra_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32) >> 10; - } else { - s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0]; - for (i=1; i<64; i++) - s->intra_matrix[i] = (ff_mpeg1_default_intra_matrix[i]*qscale) << 1; - } -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - const uint8_t *buf_end = buf+buf_size; - MadContext *t = avctx->priv_data; - MpegEncContext *s = &t->s; - int chunk_type; - int inter; - - if (buf_size < 17) { - av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n"); - *data_size = 0; - return -1; - } - - chunk_type = AV_RL32(&buf[0]); - inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG); - buf += 8; - - av_reduce(&avctx->time_base.num, &avctx->time_base.den, - AV_RL16(&buf[6]), 1000, 1<<30); - - s->width = AV_RL16(&buf[8]); - s->height = AV_RL16(&buf[10]); - calc_intra_matrix(t, buf[13]); - buf += 16; - - if (avctx->width != s->width || avctx->height != s->height) { - if (avcodec_check_dimensions(avctx, s->width, s->height) < 0) - return -1; - avcodec_set_dimensions(avctx, s->width, s->height); - if (t->frame.data[0]) - avctx->release_buffer(avctx, &t->frame); - } - - t->frame.reference = 1; - if (!t->frame.data[0]) { - if (avctx->get_buffer(avctx, &t->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - } - - av_fast_malloc(&t->bitstream_buf, &t->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE); - if (!t->bitstream_buf) - return AVERROR(ENOMEM); - bswap16_buf(t->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2); - init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf)); - - for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++) - for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++) - decode_mb(t, inter); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = t->frame; - - if (chunk_type != MADe_TAG) - FFSWAP(AVFrame, t->frame, t->last_frame); - - return buf_size; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - MadContext *t = avctx->priv_data; - if (t->frame.data[0]) - avctx->release_buffer(avctx, &t->frame); - if (t->last_frame.data[0]) - avctx->release_buffer(avctx, &t->last_frame); - av_free(t->bitstream_buf); - return 0; -} - -AVCodec eamad_decoder = { - "eamad", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MAD, - sizeof(MadContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video") -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/eatgq.c b/tizen/distrib/ffmpeg/libavcodec/eatgq.c deleted file mode 100644 index 7a98505..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eatgq.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Electronic Arts TGQ Video Decoder - * Copyright (c) 2007-2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts TGQ Video Decoder - * @author Peter Ross - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGQ - */ - -#include "avcodec.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" -#include "bytestream.h" -#include "dsputil.h" -#include "aandcttab.h" - -typedef struct TgqContext { - AVCodecContext *avctx; - DSPContext dsp; - AVFrame frame; - int width,height; - ScanTable scantable; - int qtable[64]; - DECLARE_ALIGNED(16, DCTELEM, block)[6][64]; -} TgqContext; - -static av_cold int tgq_decode_init(AVCodecContext *avctx){ - TgqContext *s = avctx->priv_data; - s->avctx = avctx; - if(avctx->idct_algo==FF_IDCT_AUTO) - avctx->idct_algo=FF_IDCT_EA; - dsputil_init(&s->dsp, avctx); - ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); - avctx->time_base = (AVRational){1, 15}; - avctx->pix_fmt = PIX_FMT_YUV420P; - return 0; -} - -static void tgq_decode_block(TgqContext *s, DCTELEM block[64], GetBitContext *gb){ - uint8_t *perm = s->scantable.permutated; - int i,j,value; - block[0] = get_sbits(gb,8) * s->qtable[0]; - for(i=1; i<64; ) { - switch(show_bits(gb,3)) { - case 4: - block[perm[i++]] = 0; - case 0: - block[perm[i++]] = 0; - skip_bits(gb,3); - break; - case 5: - case 1: - skip_bits(gb,2); - value = get_bits(gb,6); - for(j=0; jqtable[perm[i]]; - i++; - break; - case 2: - skip_bits(gb,3); - block[perm[i]] = s->qtable[perm[i]]; - i++; - break; - case 7: // 111b - case 3: // 011b - skip_bits(gb,2); - if (show_bits(gb,6)==0x3F) { - skip_bits(gb, 6); - block[perm[i]] = get_sbits(gb,8)*s->qtable[perm[i]]; - }else{ - block[perm[i]] = get_sbits(gb,6)*s->qtable[perm[i]]; - } - i++; - break; - } - } - block[0] += 128<<4; -} - -static void tgq_idct_put_mb(TgqContext *s, DCTELEM (*block)[64], int mb_x, int mb_y){ - int linesize= s->frame.linesize[0]; - uint8_t *dest_y = s->frame.data[0] + (mb_y * 16* linesize ) + mb_x * 16; - uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8; - uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8; - - s->dsp.idct_put(dest_y , linesize, block[0]); - s->dsp.idct_put(dest_y + 8, linesize, block[1]); - s->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); - s->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); - if(!(s->avctx->flags&CODEC_FLAG_GRAY)){ - s->dsp.idct_put(dest_cb, s->frame.linesize[1], block[4]); - s->dsp.idct_put(dest_cr, s->frame.linesize[2], block[5]); - } -} - -static inline void tgq_dconly(TgqContext *s, unsigned char *dst, int dst_stride, int dc){ - int level = av_clip_uint8((dc*s->qtable[0] + 2056)>>4); - int j; - for(j=0;j<8;j++) - memset(dst+j*dst_stride, level, 8); -} - -static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8_t *dc) -{ - int linesize= s->frame.linesize[0]; - uint8_t *dest_y = s->frame.data[0] + (mb_y * 16* linesize ) + mb_x * 16; - uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8; - uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8; - tgq_dconly(s,dest_y , linesize, dc[0]); - tgq_dconly(s,dest_y + 8, linesize, dc[1]); - tgq_dconly(s,dest_y + 8*linesize , linesize, dc[2]); - tgq_dconly(s,dest_y + 8*linesize + 8, linesize, dc[3]); - if(!(s->avctx->flags&CODEC_FLAG_GRAY)) { - tgq_dconly(s,dest_cb, s->frame.linesize[1], dc[4]); - tgq_dconly(s,dest_cr, s->frame.linesize[2], dc[5]); - } -} - -static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x, const uint8_t **bs, const uint8_t *buf_end){ - int mode; - int i; - int8_t dc[6]; - - mode = bytestream_get_byte(bs); - if (mode>buf_end-*bs) { - av_log(s->avctx, AV_LOG_ERROR, "truncated macroblock\n"); - return; - } - - if (mode>12) { - GetBitContext gb; - init_get_bits(&gb, *bs, mode*8); - for(i=0; i<6; i++) - tgq_decode_block(s, s->block[i], &gb); - tgq_idct_put_mb(s, s->block, mb_x, mb_y); - }else{ - if (mode==3) { - memset(dc, (*bs)[0], 4); - dc[4] = (*bs)[1]; - dc[5] = (*bs)[2]; - }else if (mode==6) { - memcpy(dc, *bs, 6); - }else if (mode==12) { - for(i=0; i<6; i++) - dc[i] = (*bs)[i*2]; - }else{ - av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode); - } - tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc); - } - *bs += mode; -} - -static void tgq_calculate_qtable(TgqContext *s, int quant){ - int i,j; - const int a = (14*(100-quant))/100 + 1; - const int b = (11*(100-quant))/100 + 4; - for(j=0;j<8;j++) - for(i=0;i<8;i++) - if (s->avctx->idct_algo==FF_IDCT_EA) - s->qtable[j*8+i] = ((a*(j+i)/(7+7) + b)*ff_inv_aanscales[j*8+i])>>(14-4); - else - s->qtable[j*8+i] = (a*(j+i)/(7+7) + b)<<3; -} - -static int tgq_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt){ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - const uint8_t *buf_start = buf; - const uint8_t *buf_end = buf + buf_size; - TgqContext *s = avctx->priv_data; - int x,y; - - int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF; - buf += 8; - - if(8>buf_end-buf) { - av_log(avctx, AV_LOG_WARNING, "truncated header\n"); - return -1; - } - s->width = big_endian ? AV_RB16(&buf[0]) : AV_RL16(&buf[0]); - s->height = big_endian ? AV_RB16(&buf[2]) : AV_RL16(&buf[2]); - - if (s->avctx->width!=s->width || s->avctx->height!=s->height) { - avcodec_set_dimensions(s->avctx, s->width, s->height); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - } - tgq_calculate_qtable(s, buf[4]); - buf += 8; - - if (!s->frame.data[0]) { - s->frame.key_frame = 1; - s->frame.pict_type = FF_I_TYPE; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - if (avctx->get_buffer(avctx, &s->frame)) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - } - - for (y=0; y<(avctx->height+15)/16; y++) - for (x=0; x<(avctx->width+15)/16; x++) - tgq_decode_mb(s, y, x, &buf, buf_end); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - return buf-buf_start; -} - -static av_cold int tgq_decode_end(AVCodecContext *avctx){ - TgqContext *s = avctx->priv_data; - if (s->frame.data[0]) - s->avctx->release_buffer(avctx, &s->frame); - return 0; -} - -AVCodec eatgq_decoder = { - "eatgq", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TGQ, - sizeof(TgqContext), - tgq_decode_init, - NULL, - tgq_decode_end, - tgq_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/eatgv.c b/tizen/distrib/ffmpeg/libavcodec/eatgv.c deleted file mode 100644 index 8c6a654..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eatgv.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Electronic Arts TGV Video Decoder - * Copyright (c) 2007-2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts TGV Video Decoder - * by Peter Ross (pross@xvid.org) - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TGV - */ - -#include "avcodec.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" -#include "libavutil/lzo.h" - -#define EA_PREAMBLE_SIZE 8 -#define kVGT_TAG MKTAG('k', 'V', 'G', 'T') - -typedef struct TgvContext { - AVCodecContext *avctx; - AVFrame frame; - AVFrame last_frame; - int width,height; - unsigned int palette[AVPALETTE_COUNT]; - - int (*mv_codebook)[2]; - unsigned char (*block_codebook)[16]; - int num_mvs; ///< current length of mv_codebook - int num_blocks_packed; ///< current length of block_codebook -} TgvContext; - -static av_cold int tgv_decode_init(AVCodecContext *avctx){ - TgvContext *s = avctx->priv_data; - s->avctx = avctx; - avctx->time_base = (AVRational){1, 15}; - avctx->pix_fmt = PIX_FMT_PAL8; - return 0; -} - -/** - * Unpack buffer - * @return 0 on success, -1 on critical buffer underflow - */ -static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst, int width, int height) { - unsigned char *dst_end = dst + width*height; - int size, size1, size2, av_uninit(offset), run; - unsigned char *dst_start = dst; - - if (src[0] & 0x01) - src += 5; - else - src += 2; - - if (src+3>src_end) - return -1; - size = AV_RB24(src); - src += 3; - - while(size>0 && src> 6 ); - offset = (AV_RB16(&src[1]) & 0x3FFF) + 1; - size2 = (src[0] & 0x3F) + 4; - src += 3; - } - } else { // 0 - offset = ((src[0] & 0x60) << 3) + src[1] + 1; - size2 = ((src[0] & 0x1C) >> 2) + 3; - src += 2; - } - - - /* fetch strip from src */ - if (size1>src_end-src) - break; - - if (size1>0) { - size -= size1; - run = FFMIN(size1, dst_end-dst); - memcpy(dst, src, run); - dst += run; - src += run; - } - - if (size2>0) { - if (dst-dst_startlast_frame.data[0] + s->avctx->width*s->last_frame.linesize[0]; - int num_mvs; - int num_blocks_raw; - int num_blocks_packed; - int vector_bits; - int i,j,x,y; - GetBitContext gb; - int mvbits; - const unsigned char *blocks_raw; - - if(buf+12>buf_end) - return -1; - - num_mvs = AV_RL16(&buf[0]); - num_blocks_raw = AV_RL16(&buf[2]); - num_blocks_packed = AV_RL16(&buf[4]); - vector_bits = AV_RL16(&buf[6]); - buf += 12; - - /* allocate codebook buffers as neccessary */ - if (num_mvs > s->num_mvs) { - s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int)); - s->num_mvs = num_mvs; - } - - if (num_blocks_packed > s->num_blocks_packed) { - s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16*sizeof(unsigned char)); - s->num_blocks_packed = num_blocks_packed; - } - - /* read motion vectors */ - mvbits = (num_mvs*2*10+31) & ~31; - - if (buf+(mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed>buf_end) - return -1; - - init_get_bits(&gb, buf, mvbits); - for (i=0; imv_codebook[i][0] = get_sbits(&gb, 10); - s->mv_codebook[i][1] = get_sbits(&gb, 10); - } - buf += mvbits>>3; - - /* note ptr to uncompressed blocks */ - blocks_raw = buf; - buf += num_blocks_raw*16; - - /* read compressed blocks */ - init_get_bits(&gb, buf, (buf_end-buf)<<3); - for (i=0; iblock_codebook[i][15-j] = tmp[get_bits(&gb, 2)]; - } - - if (get_bits_left(&gb) < vector_bits * - (s->avctx->height/4) * (s->avctx->width/4)) - return -1; - - /* read vectors and build frame */ - for(y=0; yavctx->height/4; y++) - for(x=0; xavctx->width/4; x++) { - unsigned int vector = get_bits(&gb, vector_bits); - const unsigned char *src; - int src_stride; - - if (vector < num_mvs) { - src = s->last_frame.data[0] + - (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] + - x*4 + s->mv_codebook[vector][0]; - src_stride = s->last_frame.linesize[0]; - if (src+3*src_stride+3>=frame0_end) - continue; - }else{ - int offset = vector - num_mvs; - if (offsetblock_codebook[offset-num_blocks_raw]; - else - continue; - src_stride = 4; - } - - for(j=0; j<4; j++) - for(i=0; i<4; i++) - s->frame.data[0][ (y*4+j)*s->frame.linesize[0] + (x*4+i) ] = - src[j*src_stride + i]; - } - - return 0; -} - -/** release AVFrame buffers if allocated */ -static void cond_release_buffer(AVFrame *pic) -{ - if (pic->data[0]) { - av_freep(&pic->data[0]); - av_free(pic->data[1]); - } -} - -static int tgv_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TgvContext *s = avctx->priv_data; - const uint8_t *buf_end = buf + buf_size; - int chunk_type; - - chunk_type = AV_RL32(&buf[0]); - buf += EA_PREAMBLE_SIZE; - - if (chunk_type==kVGT_TAG) { - int pal_count, i; - if(buf+12>buf_end) { - av_log(avctx, AV_LOG_WARNING, "truncated header\n"); - return -1; - } - - s->width = AV_RL16(&buf[0]); - s->height = AV_RL16(&buf[2]); - if (s->avctx->width!=s->width || s->avctx->height!=s->height) { - avcodec_set_dimensions(s->avctx, s->width, s->height); - cond_release_buffer(&s->frame); - cond_release_buffer(&s->last_frame); - } - - pal_count = AV_RL16(&buf[6]); - buf += 12; - for(i=0; ipalette[i] = AV_RB24(buf); - buf += 3; - } - } - - if (avcodec_check_dimensions(avctx, s->width, s->height)) - return -1; - - /* shuffle */ - FFSWAP(AVFrame, s->frame, s->last_frame); - if (!s->frame.data[0]) { - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - s->frame.linesize[0] = s->width; - - /* allocate additional 12 bytes to accomodate av_memcpy_backptr() OUTBUF_PADDED optimisation */ - s->frame.data[0] = av_malloc(s->width*s->height + 12); - if (!s->frame.data[0]) - return AVERROR(ENOMEM); - s->frame.data[1] = av_malloc(AVPALETTE_SIZE); - if (!s->frame.data[1]) { - av_freep(&s->frame.data[0]); - return AVERROR(ENOMEM); - } - } - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); - - if(chunk_type==kVGT_TAG) { - s->frame.key_frame = 1; - s->frame.pict_type = FF_I_TYPE; - if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width, s->avctx->height)<0) { - av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n"); - return -1; - } - }else{ - if (!s->last_frame.data[0]) { - av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n"); - return buf_size; - } - s->frame.key_frame = 0; - s->frame.pict_type = FF_P_TYPE; - if (tgv_decode_inter(s, buf, buf_end)<0) { - av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n"); - return -1; - } - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - return buf_size; -} - -static av_cold int tgv_decode_end(AVCodecContext *avctx) -{ - TgvContext *s = avctx->priv_data; - cond_release_buffer(&s->frame); - cond_release_buffer(&s->last_frame); - av_free(s->mv_codebook); - av_free(s->block_codebook); - return 0; -} - -AVCodec eatgv_decoder = { - "eatgv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TGV, - sizeof(TgvContext), - tgv_decode_init, - NULL, - tgv_decode_end, - tgv_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/eatqi.c b/tizen/distrib/ffmpeg/libavcodec/eatqi.c deleted file mode 100644 index 7f1901d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eatqi.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Electronic Arts TQI Video Decoder - * Copyright (c) 2007-2009 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts TQI Video Decoder - * by Peter Ross - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "aandcttab.h" -#include "mpeg12.h" -#include "mpegvideo.h" - -typedef struct TqiContext { - MpegEncContext s; - AVFrame frame; - void *bitstream_buf; - unsigned int bitstream_buf_size; - DECLARE_ALIGNED(16, DCTELEM, block)[6][64]; -} TqiContext; - -static av_cold int tqi_decode_init(AVCodecContext *avctx) -{ - TqiContext *t = avctx->priv_data; - MpegEncContext *s = &t->s; - s->avctx = avctx; - if(avctx->idct_algo==FF_IDCT_AUTO) - avctx->idct_algo=FF_IDCT_EA; - dsputil_init(&s->dsp, avctx); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); - s->qscale = 1; - avctx->time_base = (AVRational){1, 15}; - avctx->pix_fmt = PIX_FMT_YUV420P; - ff_mpeg12_init_vlcs(); - return 0; -} - -static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) -{ - int n; - s->dsp.clear_blocks(block[0]); - for (n=0; n<6; n++) - ff_mpeg1_decode_block_intra(s, block[n], n); -} - -static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64]) -{ - MpegEncContext *s = &t->s; - int linesize= t->frame.linesize[0]; - uint8_t *dest_y = t->frame.data[0] + (s->mb_y * 16* linesize ) + s->mb_x * 16; - uint8_t *dest_cb = t->frame.data[1] + (s->mb_y * 8 * t->frame.linesize[1]) + s->mb_x * 8; - uint8_t *dest_cr = t->frame.data[2] + (s->mb_y * 8 * t->frame.linesize[2]) + s->mb_x * 8; - - s->dsp.idct_put(dest_y , linesize, block[0]); - s->dsp.idct_put(dest_y + 8, linesize, block[1]); - s->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); - s->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); - if(!(s->avctx->flags&CODEC_FLAG_GRAY)) { - s->dsp.idct_put(dest_cb, t->frame.linesize[1], block[4]); - s->dsp.idct_put(dest_cr, t->frame.linesize[2], block[5]); - } -} - -static void tqi_calculate_qtable(MpegEncContext *s, int quant) -{ - const int qscale = (215 - 2*quant)*5; - int i; - if (s->avctx->idct_algo==FF_IDCT_EA) { - s->intra_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0])>>11; - for(i=1; i<64; i++) - s->intra_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>14; - }else{ - s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0]; - for(i=1; i<64; i++) - s->intra_matrix[i] = (ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>3; - } -} - -static int tqi_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - const uint8_t *buf_end = buf+buf_size; - TqiContext *t = avctx->priv_data; - MpegEncContext *s = &t->s; - - s->width = AV_RL16(&buf[0]); - s->height = AV_RL16(&buf[2]); - tqi_calculate_qtable(s, buf[4]); - buf += 8; - - if (t->frame.data[0]) - avctx->release_buffer(avctx, &t->frame); - - if (s->avctx->width!=s->width || s->avctx->height!=s->height) - avcodec_set_dimensions(s->avctx, s->width, s->height); - - if(avctx->get_buffer(avctx, &t->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - av_fast_malloc(&t->bitstream_buf, &t->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE); - if (!t->bitstream_buf) - return AVERROR(ENOMEM); - s->dsp.bswap_buf(t->bitstream_buf, (const uint32_t*)buf, (buf_end-buf)/4); - init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf)); - - s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 0; - for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++) - for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++) - { - tqi_decode_mb(s, t->block); - tqi_idct_put(t, t->block); - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = t->frame; - return buf_size; -} - -static av_cold int tqi_decode_end(AVCodecContext *avctx) -{ - TqiContext *t = avctx->priv_data; - if(t->frame.data[0]) - avctx->release_buffer(avctx, &t->frame); - av_free(t->bitstream_buf); - return 0; -} - -AVCodec eatqi_decoder = { - "eatqi", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TQI, - sizeof(TqiContext), - tqi_decode_init, - NULL, - tqi_decode_end, - tqi_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/elbg.c b/tizen/distrib/ffmpeg/libavcodec/elbg.c deleted file mode 100644 index d6a4ce7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/elbg.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (C) 2007 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Codebook Generator using the ELBG algorithm - */ - -#include - -#include "libavutil/lfg.h" -#include "elbg.h" -#include "avcodec.h" - -#define DELTA_ERR_MAX 0.1 ///< Precision of the ELBG algorithm (as percentual error) - -/** - * In the ELBG jargon, a cell is the set of points that are closest to a - * codebook entry. Not to be confused with a RoQ Video cell. */ -typedef struct cell_s { - int index; - struct cell_s *next; -} cell; - -/** - * ELBG internal data - */ -typedef struct{ - int error; - int dim; - int numCB; - int *codebook; - cell **cells; - int *utility; - int *utility_inc; - int *nearest_cb; - int *points; - AVLFG *rand_state; -} elbg_data; - -static inline int distance_limited(int *a, int *b, int dim, int limit) -{ - int i, dist=0; - for (i=0; i limit) - return INT_MAX; - } - - return dist; -} - -static inline void vect_division(int *res, int *vect, int div, int dim) -{ - int i; - if (div > 1) - for (i=0; inext) - error += distance_limited(centroid, elbg->points + cells->index*elbg->dim, elbg->dim, INT_MAX); - - return error; -} - -static int get_closest_codebook(elbg_data *elbg, int index) -{ - int i, pick=0, diff, diff_min = INT_MAX; - for (i=0; inumCB; i++) - if (i != index) { - diff = distance_limited(elbg->codebook + i*elbg->dim, elbg->codebook + index*elbg->dim, elbg->dim, diff_min); - if (diff < diff_min) { - pick = i; - diff_min = diff; - } - } - return pick; -} - -static int get_high_utility_cell(elbg_data *elbg) -{ - int i=0; - /* Using linear search, do binary if it ever turns to be speed critical */ - int r = av_lfg_get(elbg->rand_state)%elbg->utility_inc[elbg->numCB-1] + 1; - while (elbg->utility_inc[i] < r) - i++; - - assert(!elbg->cells[i]); - - return i; -} - -/** - * Implementation of the simple LBG algorithm for just two codebooks - */ -static int simple_lbg(int dim, - int *centroid[3], - int newutility[3], - int *points, - cell *cells) -{ - int i, idx; - int numpoints[2] = {0,0}; - int newcentroid[2][dim]; - cell *tempcell; - - memset(newcentroid, 0, sizeof(newcentroid)); - - newutility[0] = - newutility[1] = 0; - - for (tempcell = cells; tempcell; tempcell=tempcell->next) { - idx = distance_limited(centroid[0], points + tempcell->index*dim, dim, INT_MAX)>= - distance_limited(centroid[1], points + tempcell->index*dim, dim, INT_MAX); - numpoints[idx]++; - for (i=0; iindex*dim + i]; - } - - vect_division(centroid[0], newcentroid[0], numpoints[0], dim); - vect_division(centroid[1], newcentroid[1], numpoints[1], dim); - - for (tempcell = cells; tempcell; tempcell=tempcell->next) { - int dist[2] = {distance_limited(centroid[0], points + tempcell->index*dim, dim, INT_MAX), - distance_limited(centroid[1], points + tempcell->index*dim, dim, INT_MAX)}; - int idx = dist[0] > dist[1]; - newutility[idx] += dist[idx]; - } - - return newutility[0] + newutility[1]; -} - -static void get_new_centroids(elbg_data *elbg, int huc, int *newcentroid_i, - int *newcentroid_p) -{ - cell *tempcell; - int min[elbg->dim]; - int max[elbg->dim]; - int i; - - for (i=0; i< elbg->dim; i++) { - min[i]=INT_MAX; - max[i]=0; - } - - for (tempcell = elbg->cells[huc]; tempcell; tempcell = tempcell->next) - for(i=0; idim; i++) { - min[i]=FFMIN(min[i], elbg->points[tempcell->index*elbg->dim + i]); - max[i]=FFMAX(max[i], elbg->points[tempcell->index*elbg->dim + i]); - } - - for (i=0; idim; i++) { - newcentroid_i[i] = min[i] + (max[i] - min[i])/3; - newcentroid_p[i] = min[i] + (2*(max[i] - min[i]))/3; - } -} - -/** - * Add the points in the low utility cell to its closest cell. Split the high - * utility cell, putting the separed points in the (now empty) low utility - * cell. - * - * @param elbg Internal elbg data - * @param indexes {luc, huc, cluc} - * @param newcentroid A vector with the position of the new centroids - */ -static void shift_codebook(elbg_data *elbg, int *indexes, - int *newcentroid[3]) -{ - cell *tempdata; - cell **pp = &elbg->cells[indexes[2]]; - - while(*pp) - pp= &(*pp)->next; - - *pp = elbg->cells[indexes[0]]; - - elbg->cells[indexes[0]] = NULL; - tempdata = elbg->cells[indexes[1]]; - elbg->cells[indexes[1]] = NULL; - - while(tempdata) { - cell *tempcell2 = tempdata->next; - int idx = distance_limited(elbg->points + tempdata->index*elbg->dim, - newcentroid[0], elbg->dim, INT_MAX) > - distance_limited(elbg->points + tempdata->index*elbg->dim, - newcentroid[1], elbg->dim, INT_MAX); - - tempdata->next = elbg->cells[indexes[idx]]; - elbg->cells[indexes[idx]] = tempdata; - tempdata = tempcell2; - } -} - -static void evaluate_utility_inc(elbg_data *elbg) -{ - int i, inc=0; - - for (i=0; i < elbg->numCB; i++) { - if (elbg->numCB*elbg->utility[i] > elbg->error) - inc += elbg->utility[i]; - elbg->utility_inc[i] = inc; - } -} - - -static void update_utility_and_n_cb(elbg_data *elbg, int idx, int newutility) -{ - cell *tempcell; - - elbg->utility[idx] = newutility; - for (tempcell=elbg->cells[idx]; tempcell; tempcell=tempcell->next) - elbg->nearest_cb[tempcell->index] = idx; -} - -/** - * Evaluate if a shift lower the error. If it does, call shift_codebooks - * and update elbg->error, elbg->utility and elbg->nearest_cb. - * - * @param elbg Internal elbg data - * @param indexes {luc (low utility cell, huc (high utility cell), cluc (closest cell to low utility cell)} - */ -static void try_shift_candidate(elbg_data *elbg, int idx[3]) -{ - int j, k, olderror=0, newerror, cont=0; - int newutility[3]; - int newcentroid[3][elbg->dim]; - int *newcentroid_ptrs[3]; - cell *tempcell; - - newcentroid_ptrs[0] = newcentroid[0]; - newcentroid_ptrs[1] = newcentroid[1]; - newcentroid_ptrs[2] = newcentroid[2]; - - for (j=0; j<3; j++) - olderror += elbg->utility[idx[j]]; - - memset(newcentroid[2], 0, elbg->dim*sizeof(int)); - - for (k=0; k<2; k++) - for (tempcell=elbg->cells[idx[2*k]]; tempcell; tempcell=tempcell->next) { - cont++; - for (j=0; jdim; j++) - newcentroid[2][j] += elbg->points[tempcell->index*elbg->dim + j]; - } - - vect_division(newcentroid[2], newcentroid[2], cont, elbg->dim); - - get_new_centroids(elbg, idx[1], newcentroid[0], newcentroid[1]); - - newutility[2] = eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[0]]); - newutility[2] += eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[2]]); - - newerror = newutility[2]; - - newerror += simple_lbg(elbg->dim, newcentroid_ptrs, newutility, elbg->points, - elbg->cells[idx[1]]); - - if (olderror > newerror) { - shift_codebook(elbg, idx, newcentroid_ptrs); - - elbg->error += newerror - olderror; - - for (j=0; j<3; j++) - update_utility_and_n_cb(elbg, idx[j], newutility[j]); - - evaluate_utility_inc(elbg); - } - } - -/** - * Implementation of the ELBG block - */ -static void do_shiftings(elbg_data *elbg) -{ - int idx[3]; - - evaluate_utility_inc(elbg); - - for (idx[0]=0; idx[0] < elbg->numCB; idx[0]++) - if (elbg->numCB*elbg->utility[idx[0]] < elbg->error) { - if (elbg->utility_inc[elbg->numCB-1] == 0) - return; - - idx[1] = get_high_utility_cell(elbg); - idx[2] = get_closest_codebook(elbg, idx[0]); - - if (idx[1] != idx[0] && idx[1] != idx[2]) - try_shift_candidate(elbg, idx); - } -} - -#define BIG_PRIME 433494437LL - -void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, - int numCB, int max_steps, int *closest_cb, - AVLFG *rand_state) -{ - int i, k; - - if (numpoints > 24*numCB) { - /* ELBG is very costly for a big number of points. So if we have a lot - of them, get a good initial codebook to save on iterations */ - int *temp_points = av_malloc(dim*(numpoints/8)*sizeof(int)); - for (i=0; ierror = INT_MAX; - elbg->dim = dim; - elbg->numCB = numCB; - elbg->codebook = codebook; - elbg->cells = av_malloc(numCB*sizeof(cell *)); - elbg->utility = av_malloc(numCB*sizeof(int)); - elbg->nearest_cb = closest_cb; - elbg->points = points; - elbg->utility_inc = av_malloc(numCB*sizeof(int)); - - elbg->rand_state = rand_state; - - do { - free_cells = list_buffer; - last_error = elbg->error; - steps++; - memset(elbg->utility, 0, numCB*sizeof(int)); - memset(elbg->cells, 0, numCB*sizeof(cell *)); - - elbg->error = 0; - - /* This loop evaluate the actual Voronoi partition. It is the most - costly part of the algorithm. */ - for (i=0; i < numpoints; i++) { - best_dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + best_idx*elbg->dim, dim, INT_MAX); - for (k=0; k < elbg->numCB; k++) { - dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, best_dist); - if (dist < best_dist) { - best_dist = dist; - best_idx = k; - } - } - elbg->nearest_cb[i] = best_idx; - dist_cb[i] = best_dist; - elbg->error += dist_cb[i]; - elbg->utility[elbg->nearest_cb[i]] += dist_cb[i]; - free_cells->index = i; - free_cells->next = elbg->cells[elbg->nearest_cb[i]]; - elbg->cells[elbg->nearest_cb[i]] = free_cells; - free_cells++; - } - - do_shiftings(elbg); - - memset(size_part, 0, numCB*sizeof(int)); - - memset(elbg->codebook, 0, elbg->numCB*dim*sizeof(int)); - - for (i=0; i < numpoints; i++) { - size_part[elbg->nearest_cb[i]]++; - for (j=0; j < elbg->dim; j++) - elbg->codebook[elbg->nearest_cb[i]*elbg->dim + j] += - elbg->points[i*elbg->dim + j]; - } - - for (i=0; i < elbg->numCB; i++) - vect_division(elbg->codebook + i*elbg->dim, - elbg->codebook + i*elbg->dim, size_part[i], elbg->dim); - - } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) && - (steps < max_steps)); - - av_free(dist_cb); - av_free(size_part); - av_free(elbg->utility); - av_free(list_buffer); - av_free(elbg->cells); - av_free(elbg->utility_inc); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/elbg.h b/tizen/distrib/ffmpeg/libavcodec/elbg.h deleted file mode 100644 index e6f577e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/elbg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2007 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ELBG_H -#define AVCODEC_ELBG_H - -#include "libavutil/lfg.h" - -/** - * Implementation of the Enhanced LBG Algorithm - * Based on the paper "Neural Networks 14:1219-1237" that can be found in - * http://citeseer.ist.psu.edu/patan01enhanced.html . - * - * @param points Input points. - * @param dim Dimension of the points. - * @param numpoints Num of points in **points. - * @param codebook Pointer to the output codebook. Must be allocated. - * @param numCB Number of points in the codebook. - * @param num_steps The maximum number of steps. One step is already a good compromise between time and quality. - * @param closest_cb Return the closest codebook to each point. Must be allocated. - * @param rand_state A random number generator state. Should be already initialized by av_lfg_init(). - */ -void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, - int numCB, int num_steps, int *closest_cb, - AVLFG *rand_state); - -/** - * Initialize the **codebook vector for the elbg algorithm. If you have already - * a codebook and you want to refine it, you shouldn't call this function. - * If numpoints < 8*numCB this function fills **codebook with random numbers. - * If not, it calls ff_do_elbg for a (smaller) random sample of the points in - * **points. Get the same parameters as ff_do_elbg. - */ -void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, - int numCB, int num_steps, int *closest_cb, - AVLFG *rand_state); - -#endif /* AVCODEC_ELBG_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/error_resilience.c b/tizen/distrib/ffmpeg/libavcodec/error_resilience.c deleted file mode 100644 index dc015b9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/error_resilience.c +++ /dev/null @@ -1,1122 +0,0 @@ -/* - * Error resilience / concealment - * - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Error resilience / concealment. - */ - -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "h264.h" -#include "rectangle.h" - -/* - * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264) - * but error concealment must support both h264 and h263 thus we must undo this - */ -#undef mb_intra - -static void decode_mb(MpegEncContext *s, int ref){ - 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 * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift); - s->dest[2] = s->current_picture.data[2] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift); - - if(CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264){ - H264Context *h= (void*)s; - h->mb_xy= s->mb_x + s->mb_y*s->mb_stride; - memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache)); - assert(ref>=0); - if(ref >= h->ref_count[0]) //FIXME it is posible albeit uncommon that slice references differ between slices, we take the easy approuch and ignore it for now. If this turns out to have any relevance in practice then correct remapping should be added - ref=0; - fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1); - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); - fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4); - assert(!FRAME_MBAFF); - ff_h264_hl_decode_mb(h); - }else{ - assert(ref==0); - MPV_decode_mb(s, s->block); - } -} - -/** - * @param stride the number of MVs to get to the next row - * @param mv_step the number of MVs per row or column in a macroblock - */ -static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){ - if(s->codec_id == CODEC_ID_H264){ - H264Context *h= (void*)s; - assert(s->quarter_sample); - *mv_step= 4; - *stride= h->b_stride; - }else{ - *mv_step= 2; - *stride= s->b8_stride; - } -} - -/** - * 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 do not have an 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, mvx_stride, mvy_stride; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - set_mv_strides(s, &mvx_stride, &mvy_stride); - mvx_stride >>= is_luma; - mvy_stride *= mvx_stride; - - 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][mvy_stride*b_y + mvx_stride* b_x ]; - int16_t *right_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)]; - - if(!(left_damage||right_damage)) continue; // both undamaged - - if( (!left_intra) && (!right_intra) - && FFABS(left_mv[0]-right_mv[0]) + FFABS(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= FFABS(b) - ((FFABS(a) + FFABS(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, mvx_stride, mvy_stride; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - set_mv_strides(s, &mvx_stride, &mvy_stride); - mvx_stride >>= is_luma; - mvy_stride *= mvx_stride; - - 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][mvy_stride* b_y + mvx_stride*b_x]; - int16_t *bottom_mv= s->current_picture.motion_val[0][mvy_stride*(b_y+1) + mvx_stride*b_x]; - - if(!(top_damage||bottom_damage)) continue; // both undamaged - - if( (!top_intra) && (!bottom_intra) - && FFABS(top_mv[0]-bottom_mv[0]) + FFABS(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= FFABS(b) - ((FFABS(a) + FFABS(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, mot_step, mot_stride; - - set_mv_strides(s, &mot_step, &mot_stride); - - 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 = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD; - 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, 0); - } - } - 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 ref[8]={0}; - int pred_count=0; - int j; - int best_score=256*256*256*64; - int best_pred=0; - const int mot_index= (mb_x + mb_y*mot_stride) * mot_step; - 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 - mot_step][0]; - mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1]; - ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-1)]; - pred_count++; - } - if(mb_x+1current_picture.motion_val[0][mot_index + mot_step][0]; - mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1]; - ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+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*mot_step][0]; - mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1]; - ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)]; - pred_count++; - } - if(mb_y+1current_picture.motion_val[0][mot_index + mot_stride*mot_step][0]; - mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1]; - ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)]; - pred_count++; - } - if(pred_count==0) continue; - - if(pred_count>1){ - int sum_x=0, sum_y=0, sum_r=0; - int max_x, max_y, min_x, min_y, max_r, min_r; - - for(j=0; j=3){ - min_y= min_x= min_r= 99999; - max_y= max_x= max_r=-99999; - }else{ - min_x=min_y=max_x=max_y=min_r=max_r=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]; - ref [pred_count] = s->current_picture.ref_index[0][4*mb_xy]; - 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]; - - if(ref[j]<0) //predictor intra or otherwise not available - continue; - - decode_mb(s, ref[j]); - - if(mb_x>0 && fixed[mb_xy-1]){ - int k; - for(k=0; k<16; k++) - score += FFABS(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 += FFABS(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; - s->mv[0][0][0]= mv_predictor[best_pred][0]; - s->mv[0][0][1]= mv_predictor[best_pred][1]; - - for(i=0; icurrent_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0]; - s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1]; - } - - decode_mb(s, ref[best_pred]); - - - 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 || !s->last_picture_ptr->data[0]) 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(s->codec_id == CODEC_ID_H264){ - H264Context *h= (void*)s; - if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0]) - return 1; - } - - if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction - - //prevent dsp.sad() check, that requires access to the image - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == FF_I_TYPE) - return 1; - - 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==FF_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_recognition) 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 occurred - */ -void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){ - const int start_i= av_clip(startx + starty * s->mb_width , 0, s->mb_num-1); - const int end_i = av_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->avctx->hwaccel) - return; - - if(start_i > end_i || start_xy > end_xy){ - av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n"); - return; - } - - if(!s->error_recognition) 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_recognition || s->error_count==0 || s->avctx->lowres || - s->avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || - s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled - 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(s->mb_stride * s->mb_height * 4 * 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; - } - - 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_recognition>=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 & uninit - 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; - } - - // change inter to intra blocks if no reference frames are available - if (!s->last_picture.data[0] && !s->next_picture.data[0]) - for(i=0; imb_num; i++){ - const int mb_xy= s->mb_index2xy[i]; - if(!IS_INTRA(s->current_picture.mb_type[mb_xy])) - s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4; - } - - /* 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]; - int dir = !s->last_picture.data[0]; - 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 = dir ? MV_DIR_BACKWARD : 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[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0]; - s->mv[0][j][1] = s->current_picture.motion_val[dir][ 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[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0]; - s->mv[0][0][1] = s->current_picture.motion_val[dir][ 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, 0/*FIXME h264 partitioned slices need this set*/); - } - } - - /* guess MVs */ - if(s->pict_type==FF_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; - if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD; - if(!s->next_picture.data[0]) s->mv_dir &= ~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, 0); - } - } - }else - guess_mv(s); - - /* the filters below are not XvMC compatible, skip them */ - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) - goto ec_clean; - /* 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); - } - -ec_clean: - /* 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!=FF_B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){ - s->mbskip_table[mb_xy]=0; - } - s->mbintra_table[mb_xy]=1; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/escape124.c b/tizen/distrib/ffmpeg/libavcodec/escape124.c deleted file mode 100644 index b51206a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/escape124.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Escape 124 Video Decoder - * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" - -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" - -typedef union MacroBlock { - uint16_t pixels[4]; - uint32_t pixels32[2]; -} MacroBlock; - -typedef union SuperBlock { - uint16_t pixels[64]; - uint32_t pixels32[32]; -} SuperBlock; - -typedef struct CodeBook { - unsigned depth; - unsigned size; - MacroBlock* blocks; -} CodeBook; - -typedef struct Escape124Context { - AVFrame frame; - - unsigned num_superblocks; - - CodeBook codebooks[3]; -} Escape124Context; - -static int can_safely_read(GetBitContext* gb, int bits) { - return get_bits_count(gb) + bits <= gb->size_in_bits; -} - -/** - * Initialize the decoder - * @param avctx decoder context - * @return 0 success, negative on error - */ -static av_cold int escape124_decode_init(AVCodecContext *avctx) -{ - Escape124Context *s = avctx->priv_data; - - avctx->pix_fmt = PIX_FMT_RGB555; - - s->num_superblocks = ((unsigned)avctx->width / 8) * - ((unsigned)avctx->height / 8); - - return 0; -} - -static av_cold int escape124_decode_close(AVCodecContext *avctx) -{ - unsigned i; - Escape124Context *s = avctx->priv_data; - - for (i = 0; i < 3; i++) - av_free(s->codebooks[i].blocks); - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, - unsigned size) -{ - unsigned i, j; - CodeBook cb = { 0 }; - - if (!can_safely_read(gb, size * 34)) - return cb; - - if (size >= INT_MAX / sizeof(MacroBlock)) - return cb; - cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1); - if (!cb.blocks) - return cb; - - cb.depth = depth; - cb.size = size; - for (i = 0; i < size; i++) { - unsigned mask_bits = get_bits(gb, 4); - unsigned color0 = get_bits(gb, 15); - unsigned color1 = get_bits(gb, 15); - - for (j = 0; j < 4; j++) { - if (mask_bits & (1 << j)) - cb.blocks[i].pixels[j] = color1; - else - cb.blocks[i].pixels[j] = color0; - } - } - return cb; -} - -static unsigned decode_skip_count(GetBitContext* gb) -{ - unsigned value; - // This function reads a maximum of 23 bits, - // which is within the padding space - if (!can_safely_read(gb, 1)) - return -1; - value = get_bits1(gb); - if (!value) - return value; - - value += get_bits(gb, 3); - if (value != (1 + ((1 << 3) - 1))) - return value; - - value += get_bits(gb, 7); - if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1)) - return value; - - return value + get_bits(gb, 12); -} - -static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, - int* codebook_index, int superblock_index) -{ - // This function reads a maximum of 22 bits; the callers - // guard this function appropriately - unsigned block_index, depth; - - if (get_bits1(gb)) { - static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} }; - *codebook_index = transitions[*codebook_index][get_bits1(gb)]; - } - - depth = s->codebooks[*codebook_index].depth; - - // depth = 0 means that this shouldn't read any bits; - // in theory, this is the same as get_bits(gb, 0), but - // that doesn't actually work. - block_index = depth ? get_bits(gb, depth) : 0; - - if (*codebook_index == 1) { - block_index += superblock_index << s->codebooks[1].depth; - } - - // This condition can occur with invalid bitstreams and - // *codebook_index == 2 - if (block_index >= s->codebooks[*codebook_index].size) - return (MacroBlock) { { 0 } }; - - return s->codebooks[*codebook_index].blocks[block_index]; -} - -static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) { - // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2 - uint32_t *dst = sb->pixels32 + index + (index & -4); - - // This technically violates C99 aliasing rules, but it should be safe. - dst[0] = mb.pixels32[0]; - dst[4] = mb.pixels32[1]; -} - -static void copy_superblock(uint16_t* dest, unsigned dest_stride, - uint16_t* src, unsigned src_stride) -{ - unsigned y; - if (src) - for (y = 0; y < 8; y++) - memcpy(dest + y * dest_stride, src + y * src_stride, - sizeof(uint16_t) * 8); - else - for (y = 0; y < 8; y++) - memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8); -} - -static const uint16_t mask_matrix[] = {0x1, 0x2, 0x10, 0x20, - 0x4, 0x8, 0x40, 0x80, - 0x100, 0x200, 0x1000, 0x2000, - 0x400, 0x800, 0x4000, 0x8000}; - -/** - * Decode a single frame - * @param avctx decoder context - * @param data decoded frame - * @param data_size size of the decoded frame - * @param buf input buffer - * @param buf_size input buffer size - * @return 0 success, -1 on error - */ -static int escape124_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - Escape124Context *s = avctx->priv_data; - - GetBitContext gb; - unsigned frame_flags, frame_size; - unsigned i; - - unsigned superblock_index, cb_index = 1, - superblock_col_index = 0, - superblocks_per_row = avctx->width / 8, skip = -1; - - uint16_t* old_frame_data, *new_frame_data; - unsigned old_stride, new_stride; - - AVFrame new_frame = { { 0 } }; - - init_get_bits(&gb, buf, buf_size * 8); - - // This call also guards the potential depth reads for the - // codebook unpacking. - if (!can_safely_read(&gb, 64)) - return -1; - - frame_flags = get_bits_long(&gb, 32); - frame_size = get_bits_long(&gb, 32); - - // Leave last frame unchanged - // FIXME: Is this necessary? I haven't seen it in any real samples - if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { - av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n"); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - return frame_size; - } - - for (i = 0; i < 3; i++) { - if (frame_flags & (1 << (17 + i))) { - unsigned cb_depth, cb_size; - if (i == 2) { - // This codebook can be cut off at places other than - // powers of 2, leaving some of the entries undefined. - cb_size = get_bits_long(&gb, 20); - cb_depth = av_log2(cb_size - 1) + 1; - } else { - cb_depth = get_bits(&gb, 4); - if (i == 0) { - // This is the most basic codebook: pow(2,depth) entries - // for a depth-length key - cb_size = 1 << cb_depth; - } else { - // This codebook varies per superblock - // FIXME: I don't think this handles integer overflow - // properly - cb_size = s->num_superblocks << cb_depth; - } - } - av_free(s->codebooks[i].blocks); - s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); - if (!s->codebooks[i].blocks) - return -1; - } - } - - new_frame.reference = 3; - if (avctx->get_buffer(avctx, &new_frame)) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - new_frame_data = (uint16_t*)new_frame.data[0]; - new_stride = new_frame.linesize[0] / 2; - old_frame_data = (uint16_t*)s->frame.data[0]; - old_stride = s->frame.linesize[0] / 2; - - for (superblock_index = 0; superblock_index < s->num_superblocks; - superblock_index++) { - MacroBlock mb; - SuperBlock sb; - unsigned multi_mask = 0; - - if (skip == -1) { - // Note that this call will make us skip the rest of the blocks - // if the frame prematurely ends - skip = decode_skip_count(&gb); - } - - if (skip) { - copy_superblock(new_frame_data, new_stride, - old_frame_data, old_stride); - } else { - copy_superblock(sb.pixels, 8, - old_frame_data, old_stride); - - while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { - unsigned mask; - mb = decode_macroblock(s, &gb, &cb_index, superblock_index); - mask = get_bits(&gb, 16); - multi_mask |= mask; - for (i = 0; i < 16; i++) { - if (mask & mask_matrix[i]) { - insert_mb_into_sb(&sb, mb, i); - } - } - } - - if (can_safely_read(&gb, 1) && !get_bits1(&gb)) { - unsigned inv_mask = get_bits(&gb, 4); - for (i = 0; i < 4; i++) { - if (inv_mask & (1 << i)) { - multi_mask ^= 0xF << i*4; - } else { - multi_mask ^= get_bits(&gb, 4) << i*4; - } - } - - for (i = 0; i < 16; i++) { - if (multi_mask & mask_matrix[i]) { - if (!can_safely_read(&gb, 1)) - break; - mb = decode_macroblock(s, &gb, &cb_index, - superblock_index); - insert_mb_into_sb(&sb, mb, i); - } - } - } else if (frame_flags & (1 << 16)) { - while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { - mb = decode_macroblock(s, &gb, &cb_index, superblock_index); - insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); - } - } - - copy_superblock(new_frame_data, new_stride, sb.pixels, 8); - } - - superblock_col_index++; - new_frame_data += 8; - if (old_frame_data) - old_frame_data += 8; - if (superblock_col_index == superblocks_per_row) { - new_frame_data += new_stride * 8 - superblocks_per_row * 8; - if (old_frame_data) - old_frame_data += old_stride * 8 - superblocks_per_row * 8; - superblock_col_index = 0; - } - skip--; - } - - av_log(NULL, AV_LOG_DEBUG, - "Escape sizes: %i, %i, %i\n", - frame_size, buf_size, get_bits_count(&gb) / 8); - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - *(AVFrame*)data = s->frame = new_frame; - *data_size = sizeof(AVFrame); - - return frame_size; -} - - -AVCodec escape124_decoder = { - "escape124", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ESCAPE124, - sizeof(Escape124Context), - escape124_decode_init, - NULL, - escape124_decode_close, - escape124_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Escape 124"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/eval.c b/tizen/distrib/ffmpeg/libavcodec/eval.c deleted file mode 100644 index ce4d0f5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eval.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (c) 2002-2006 Michael Niedermayer - * Copyright (c) 2006 Oded Shimon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * simple arithmetic expression evaluator. - * - * see http://joe.hotchkiss.com/programming/eval/eval.html - */ - -#include "libavutil/avutil.h" -#include "eval.h" - -typedef struct Parser{ - int stack_index; - char *s; - const double *const_value; - const char * const *const_name; // NULL terminated - double (* const *func1)(void *, double a); // NULL terminated - const char * const *func1_name; // NULL terminated - double (* const *func2)(void *, double a, double b); // NULL terminated - const char * const *func2_name; // NULL terminated - void *opaque; - const char **error; -#define VARS 10 - double var[VARS]; -} Parser; - -static const int8_t si_prefixes['z' - 'E' + 1]={ - ['y'-'E']= -24, - ['z'-'E']= -21, - ['a'-'E']= -18, - ['f'-'E']= -15, - ['p'-'E']= -12, - ['n'-'E']= - 9, - ['u'-'E']= - 6, - ['m'-'E']= - 3, - ['c'-'E']= - 2, - ['d'-'E']= - 1, - ['h'-'E']= 2, - ['k'-'E']= 3, - ['K'-'E']= 3, - ['M'-'E']= 6, - ['G'-'E']= 9, - ['T'-'E']= 12, - ['P'-'E']= 15, - ['E'-'E']= 18, - ['Z'-'E']= 21, - ['Y'-'E']= 24, -}; - -double av_strtod(const char *numstr, char **tail) { - double d; - char *next; - d = strtod(numstr, &next); - /* if parsing succeeded, check for and interpret postfixes */ - if (next!=numstr) { - - if(*next >= 'E' && *next <= 'z'){ - int e= si_prefixes[*next - 'E']; - if(e){ - if(next[1] == 'i'){ - d*= pow( 2, e/0.3); - next+=2; - }else{ - d*= pow(10, e); - next++; - } - } - } - - if(*next=='B') { - d*=8; - next++; - } - } - /* if requested, fill in tail with the position after the last parsed - character */ - if (tail) - *tail = next; - return d; -} - -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; -} - -struct AVExpr { - enum { - e_value, e_const, e_func0, e_func1, e_func2, - e_squish, e_gauss, e_ld, - e_mod, e_max, e_min, e_eq, e_gt, e_gte, - e_pow, e_mul, e_div, e_add, - e_last, e_st, e_while, - } type; - double value; // is sign in other types - union { - int const_index; - double (*func0)(double); - double (*func1)(void *, double); - double (*func2)(void *, double, double); - } a; - struct AVExpr *param[2]; -}; - -static double eval_expr(Parser * p, AVExpr * e) { - switch (e->type) { - case e_value: return e->value; - case e_const: return e->value * p->const_value[e->a.const_index]; - case e_func0: return e->value * e->a.func0(eval_expr(p, e->param[0])); - case e_func1: return e->value * e->a.func1(p->opaque, eval_expr(p, e->param[0])); - case e_func2: return e->value * e->a.func2(p->opaque, eval_expr(p, e->param[0]), eval_expr(p, e->param[1])); - case e_squish: return 1/(1+exp(4*eval_expr(p, e->param[0]))); - case e_gauss: { double d = eval_expr(p, e->param[0]); return exp(-d*d/2)/sqrt(2*M_PI); } - case e_ld: return e->value * p->var[av_clip(eval_expr(p, e->param[0]), 0, VARS-1)]; - case e_while: { - double d = NAN; - while(eval_expr(p, e->param[0])) - d=eval_expr(p, e->param[1]); - return d; - } - default: { - double d = eval_expr(p, e->param[0]); - double d2 = eval_expr(p, e->param[1]); - switch (e->type) { - case e_mod: return e->value * (d - floor(d/d2)*d2); - case e_max: return e->value * (d > d2 ? d : d2); - case e_min: return e->value * (d < d2 ? d : d2); - case e_eq: return e->value * (d == d2 ? 1.0 : 0.0); - case e_gt: return e->value * (d > d2 ? 1.0 : 0.0); - case e_gte: return e->value * (d >= d2 ? 1.0 : 0.0); - case e_pow: return e->value * pow(d, d2); - case e_mul: return e->value * (d * d2); - case e_div: return e->value * (d / d2); - case e_add: return e->value * (d + d2); - case e_last:return e->value * d2; - case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2); - } - } - } - return NAN; -} - -static AVExpr * parse_expr(Parser *p); - -void ff_free_expr(AVExpr * e) { - if (!e) return; - ff_free_expr(e->param[0]); - ff_free_expr(e->param[1]); - av_freep(&e); -} - -static AVExpr * parse_primary(Parser *p) { - AVExpr * d = av_mallocz(sizeof(AVExpr)); - char *next= p->s; - int i; - - if (!d) - return NULL; - - /* number */ - d->value = av_strtod(p->s, &next); - if(next != p->s){ - d->type = e_value; - p->s= next; - return d; - } - d->value = 1; - - /* 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]); - d->type = e_const; - d->a.const_index = i; - return d; - } - } - - p->s= strchr(p->s, '('); - if(p->s==NULL){ - *p->error = "undefined constant or missing ("; - p->s= next; - ff_free_expr(d); - return NULL; - } - p->s++; // "(" - if (*next == '(') { // special case do-nothing - av_freep(&d); - d = parse_expr(p); - if(p->s[0] != ')'){ - *p->error = "missing )"; - ff_free_expr(d); - return NULL; - } - p->s++; // ")" - return d; - } - d->param[0] = parse_expr(p); - if(p->s[0]== ','){ - p->s++; // "," - d->param[1] = parse_expr(p); - } - if(p->s[0] != ')'){ - *p->error = "missing )"; - ff_free_expr(d); - return NULL; - } - p->s++; // ")" - - d->type = e_func0; - if( strmatch(next, "sinh" ) ) d->a.func0 = sinh; - else if( strmatch(next, "cosh" ) ) d->a.func0 = cosh; - else if( strmatch(next, "tanh" ) ) d->a.func0 = tanh; - else if( strmatch(next, "sin" ) ) d->a.func0 = sin; - else if( strmatch(next, "cos" ) ) d->a.func0 = cos; - else if( strmatch(next, "tan" ) ) d->a.func0 = tan; - else if( strmatch(next, "atan" ) ) d->a.func0 = atan; - else if( strmatch(next, "asin" ) ) d->a.func0 = asin; - else if( strmatch(next, "acos" ) ) d->a.func0 = acos; - else if( strmatch(next, "exp" ) ) d->a.func0 = exp; - else if( strmatch(next, "log" ) ) d->a.func0 = log; - else if( strmatch(next, "abs" ) ) d->a.func0 = fabs; - else if( strmatch(next, "squish") ) d->type = e_squish; - else if( strmatch(next, "gauss" ) ) d->type = e_gauss; - else if( strmatch(next, "mod" ) ) d->type = e_mod; - else if( strmatch(next, "max" ) ) d->type = e_max; - else if( strmatch(next, "min" ) ) d->type = e_min; - else if( strmatch(next, "eq" ) ) d->type = e_eq; - else if( strmatch(next, "gte" ) ) d->type = e_gte; - else if( strmatch(next, "gt" ) ) d->type = e_gt; - else if( strmatch(next, "lte" ) ) { AVExpr * tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gt; } - else if( strmatch(next, "lt" ) ) { AVExpr * tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; } - else if( strmatch(next, "ld" ) ) d->type = e_ld; - else if( strmatch(next, "st" ) ) d->type = e_st; - else if( strmatch(next, "while" ) ) d->type = e_while; - else { - for(i=0; p->func1_name && p->func1_name[i]; i++){ - if(strmatch(next, p->func1_name[i])){ - d->a.func1 = p->func1[i]; - d->type = e_func1; - return d; - } - } - - for(i=0; p->func2_name && p->func2_name[i]; i++){ - if(strmatch(next, p->func2_name[i])){ - d->a.func2 = p->func2[i]; - d->type = e_func2; - return d; - } - } - - *p->error = "unknown function"; - ff_free_expr(d); - return NULL; - } - - return d; -} - -static AVExpr * new_eval_expr(int type, int value, AVExpr *p0, AVExpr *p1){ - AVExpr * e = av_mallocz(sizeof(AVExpr)); - if (!e) - return NULL; - e->type =type ; - e->value =value ; - e->param[0] =p0 ; - e->param[1] =p1 ; - return e; -} - -static AVExpr * parse_pow(Parser *p, int *sign){ - *sign= (*p->s == '+') - (*p->s == '-'); - p->s += *sign&1; - return parse_primary(p); -} - -static AVExpr * parse_factor(Parser *p){ - int sign, sign2; - AVExpr * e = parse_pow(p, &sign); - while(p->s[0]=='^'){ - p->s++; - e= new_eval_expr(e_pow, 1, e, parse_pow(p, &sign2)); - if (!e) - return NULL; - if (e->param[1]) e->param[1]->value *= (sign2|1); - } - if (e) e->value *= (sign|1); - return e; -} - -static AVExpr * parse_term(Parser *p){ - AVExpr * e = parse_factor(p); - while(p->s[0]=='*' || p->s[0]=='/'){ - int c= *p->s++; - e= new_eval_expr(c == '*' ? e_mul : e_div, 1, e, parse_factor(p)); - if (!e) - return NULL; - } - return e; -} - -static AVExpr * parse_subexpr(Parser *p) { - AVExpr * e = parse_term(p); - while(*p->s == '+' || *p->s == '-') { - e= new_eval_expr(e_add, 1, e, parse_term(p)); - if (!e) - return NULL; - }; - - return e; -} - -static AVExpr * parse_expr(Parser *p) { - AVExpr * e; - - if(p->stack_index <= 0) //protect against stack overflows - return NULL; - p->stack_index--; - - e = parse_subexpr(p); - - while(*p->s == ';') { - p->s++; - e= new_eval_expr(e_last, 1, e, parse_subexpr(p)); - if (!e) - return NULL; - }; - - p->stack_index++; - - return e; -} - -static int verify_expr(AVExpr * e) { - if (!e) return 0; - switch (e->type) { - case e_value: - case e_const: return 1; - case e_func0: - case e_func1: - case e_squish: - case e_ld: - case e_gauss: return verify_expr(e->param[0]); - default: return verify_expr(e->param[0]) && verify_expr(e->param[1]); - } -} - -AVExpr *ff_parse_expr(const char *s, const char * const *const_name, - double (* const *func1)(void *, double), const char * const *func1_name, - double (* const *func2)(void *, double, double), const char * const *func2_name, - const char **error){ - Parser p; - AVExpr *e = NULL; - char *w = av_malloc(strlen(s) + 1); - char *wp = w; - - if (!w) - goto end; - - while (*s) - if (!isspace(*s++)) *wp++ = s[-1]; - *wp++ = 0; - - p.stack_index=100; - p.s= w; - p.const_name = const_name; - p.func1 = func1; - p.func1_name = func1_name; - p.func2 = func2; - p.func2_name = func2_name; - p.error= error; - - e = parse_expr(&p); - if (!verify_expr(e)) { - ff_free_expr(e); - e = NULL; - } -end: - av_free(w); - return e; -} - -double ff_eval_expr(AVExpr * e, const double *const_value, void *opaque) { - Parser p; - - p.const_value= const_value; - p.opaque = opaque; - return eval_expr(&p, e); -} - -double ff_parse_and_eval_expr(const char *s, const double *const_value, const char * const *const_name, - double (* const *func1)(void *, double), const char * const *func1_name, - double (* const *func2)(void *, double, double), const char * const *func2_name, - void *opaque, const char **error){ - AVExpr * e = ff_parse_expr(s, const_name, func1, func1_name, func2, func2_name, error); - double d; - if (!e) return NAN; - d = ff_eval_expr(e, const_value, opaque); - ff_free_expr(e); - return d; -} - -#ifdef TEST -#undef printf -static double const_values[]={ - M_PI, - M_E, - 0 -}; -static const char *const_names[]={ - "PI", - "E", - 0 -}; -int main(void){ - int i; - printf("%f == 12.7\n", ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL, NULL)); - printf("%f == 0.931322575\n", ff_parse_and_eval_expr("80G/80Gi", const_values, const_names, NULL, NULL, NULL, NULL, NULL, NULL)); - - for(i=0; i<1050; i++){ - START_TIMER - ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL, NULL); - STOP_TIMER("ff_parse_and_eval_expr") - } - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/eval.h b/tizen/distrib/ffmpeg/libavcodec/eval.h deleted file mode 100644 index 50c16af..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/eval.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * simple arithmetic expression evaluator - */ - -#ifndef AVCODEC_EVAL_H -#define AVCODEC_EVAL_H - -typedef struct AVExpr AVExpr; - -/** - * Parses and evaluates an expression. - * Note, this is significantly slower than ff_eval_expr(). - * - * @param s expression as a zero terminated string for example "1+2^3+5*5+sin(2/3)" - * @param func1 NULL terminated array of function pointers for functions which take 1 argument - * @param func2 NULL terminated array of function pointers for functions which take 2 arguments - * @param const_name NULL terminated array of zero terminated strings of constant identifers for example {"PI", "E", 0} - * @param func1_name NULL terminated array of zero terminated strings of func1 identifers - * @param func2_name NULL terminated array of zero terminated strings of func2 identifers - * @param error pointer to a char* which is set to an error message if something goes wrong - * @param const_value a zero terminated array of values for the identifers from const_name - * @param opaque a pointer which will be passed to all functions from func1 and func2 - * @return the value of the expression - */ -double ff_parse_and_eval_expr(const char *s, const double *const_value, const char * const *const_name, - double (* const *func1)(void *, double), const char * const *func1_name, - double (* const *func2)(void *, double, double), const char * const *func2_name, - void *opaque, const char **error); - -/** - * Parses an expression. - * - * @param s expression as a zero terminated string for example "1+2^3+5*5+sin(2/3)" - * @param func1 NULL terminated array of function pointers for functions which take 1 argument - * @param func2 NULL terminated array of function pointers for functions which take 2 arguments - * @param const_name NULL terminated array of zero terminated strings of constant identifers for example {"PI", "E", 0} - * @param func1_name NULL terminated array of zero terminated strings of func1 identifers - * @param func2_name NULL terminated array of zero terminated strings of func2 identifers - * @param error pointer to a char* which is set to an error message if something goes wrong - * @return AVExpr which must be freed with ff_free_expr() by the user when it is not needed anymore - * NULL if anything went wrong - */ -AVExpr *ff_parse_expr(const char *s, const char * const *const_name, - double (* const *func1)(void *, double), const char * const *func1_name, - double (* const *func2)(void *, double, double), const char * const *func2_name, - const char **error); - -/** - * Evaluates a previously parsed expression. - * - * @param const_value a zero terminated array of values for the identifers from ff_parse const_name - * @param opaque a pointer which will be passed to all functions from func1 and func2 - * @return the value of the expression - */ -double ff_eval_expr(AVExpr * e, const double *const_value, void *opaque); - -/** - * Frees a parsed expression previously created with ff_parse(). - */ -void ff_free_expr(AVExpr *e); - -/** - * Parses the string in numstr and returns its value as a double. If - * the string is empty, contains only whitespaces, or does not contain - * an initial substring that has the expected syntax for a - * floating-point number, no conversion is performed. In this case, - * returns a value of zero and the value returned in tail is the value - * of numstr. - * - * @param numstr a string representing a number, may contain one of - * the International System number postfixes, for example 'K', 'M', - * 'G'. If 'i' is appended after the postfix, powers of 2 are used - * instead of powers of 10. The 'B' postfix multiplies the value for - * 8, and can be appended after another postfix or used alone. This - * allows using for example 'KB', 'MiB', 'G' and 'B' as postfix. - * @param tail if non-NULL puts here the pointer to the char next - * after the last parsed character - */ -double av_strtod(const char *numstr, char **tail); - -#endif /* AVCODEC_EVAL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/faandct.c b/tizen/distrib/ffmpeg/libavcodec/faandct.c deleted file mode 100644 index a986f65..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/faandct.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Floating point AAN DCT - * this implementation is based upon the IJG integer AAN DCT (see jfdctfst.c) - * - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2003 Roman Shaposhnik - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/** - * @file - * @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 const 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 av_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 z2, z4, z11, z13; - FLOAT av_unused z5; - 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; - - tmp12 += tmp13; - tmp12 *= A1; - temp[2 + i]= tmp13 + tmp12; - temp[6 + i]= tmp13 - tmp12; - - tmp4 += tmp5; - tmp5 += tmp6; - tmp6 += tmp7; - -#if 0 - z5= (tmp4 - tmp6) * A5; - z2= tmp4*A2 + z5; - z4= tmp6*A4 + z5; -#else - z2= tmp4*(A2+A5) - tmp6*A5; - z4= tmp6*(A4-A5) + tmp4*A5; -#endif - tmp5*=A1; - - z11= tmp7 + tmp5; - z13= tmp7 - tmp5; - - 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 z2, z4, z11, z13; - FLOAT av_unused z5; - 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)); - - tmp12 += tmp13; - tmp12 *= A1; - data[8*2 + i]= lrintf(SCALE(8*2 + i) * (tmp13 + tmp12)); - data[8*6 + i]= lrintf(SCALE(8*6 + i) * (tmp13 - tmp12)); - - tmp4 += tmp5; - tmp5 += tmp6; - tmp6 += tmp7; - -#if 0 - z5= (tmp4 - tmp6) * A5; - z2= tmp4*A2 + z5; - z4= tmp6*A4 + z5; -#else - z2= tmp4*(A2+A5) - tmp6*A5; - z4= tmp6*(A4-A5) + tmp4*A5; -#endif - tmp5*=A1; - - z11= tmp7 + tmp5; - z13= tmp7 - tmp5; - - 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 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)); - - tmp12 += tmp13; - tmp12 *= A1; - data[8*2 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + tmp12)); - data[8*6 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - tmp12)); - - 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)); - - tmp12 += tmp13; - tmp12 *= A1; - data[8*3 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + tmp12)); - data[8*7 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - tmp12)); - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/faandct.h b/tizen/distrib/ffmpeg/libavcodec/faandct.h deleted file mode 100644 index f43b62f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/faandct.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Floating point AAN DCT - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief - * Floating point AAN DCT - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_FAANDCT_H -#define AVCODEC_FAANDCT_H - -#include "dsputil.h" - -#define FAAN_POSTSCALE - -void ff_faandct(DCTELEM * data); -void ff_faandct248(DCTELEM * data); - -#endif /* AVCODEC_FAANDCT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/faanidct.c b/tizen/distrib/ffmpeg/libavcodec/faanidct.c deleted file mode 100644 index dc3d8fb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/faanidct.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Floating point AAN IDCT - * Copyright (c) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "faanidct.h" - -/* To allow switching to double. */ -#define FLOAT float - -#define B0 1.0000000000000000000000 -#define B1 1.3870398453221474618216 // cos(pi*1/16)sqrt(2) -#define B2 1.3065629648763765278566 // cos(pi*2/16)sqrt(2) -#define B3 1.1758756024193587169745 // cos(pi*3/16)sqrt(2) -#define B4 1.0000000000000000000000 // cos(pi*4/16)sqrt(2) -#define B5 0.7856949583871021812779 // cos(pi*5/16)sqrt(2) -#define B6 0.5411961001461969843997 // cos(pi*6/16)sqrt(2) -#define B7 0.2758993792829430123360 // cos(pi*7/16)sqrt(2) - -#define A4 0.70710678118654752438 // cos(pi*4/16) -#define A2 0.92387953251128675613 // cos(pi*2/16) - -static const FLOAT prescale[64]={ -B0*B0/8, B0*B1/8, B0*B2/8, B0*B3/8, B0*B4/8, B0*B5/8, B0*B6/8, B0*B7/8, -B1*B0/8, B1*B1/8, B1*B2/8, B1*B3/8, B1*B4/8, B1*B5/8, B1*B6/8, B1*B7/8, -B2*B0/8, B2*B1/8, B2*B2/8, B2*B3/8, B2*B4/8, B2*B5/8, B2*B6/8, B2*B7/8, -B3*B0/8, B3*B1/8, B3*B2/8, B3*B3/8, B3*B4/8, B3*B5/8, B3*B6/8, B3*B7/8, -B4*B0/8, B4*B1/8, B4*B2/8, B4*B3/8, B4*B4/8, B4*B5/8, B4*B6/8, B4*B7/8, -B5*B0/8, B5*B1/8, B5*B2/8, B5*B3/8, B5*B4/8, B5*B5/8, B5*B6/8, B5*B7/8, -B6*B0/8, B6*B1/8, B6*B2/8, B6*B3/8, B6*B4/8, B6*B5/8, B6*B6/8, B6*B7/8, -B7*B0/8, B7*B1/8, B7*B2/8, B7*B3/8, B7*B4/8, B7*B5/8, B7*B6/8, B7*B7/8, -}; - -static inline void p8idct(DCTELEM data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){ - int i; - FLOAT av_unused tmp0; - FLOAT s04, d04, s17, d17, s26, d26, s53, d53; - FLOAT os07, os16, os25, os34; - FLOAT od07, od16, od25, od34; - - for(i=0; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_FAANIDCT_H -#define AVCODEC_FAANIDCT_H - -#include -#include "dsputil.h" - -void ff_faanidct(DCTELEM block[64]); -void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]); -void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]); - -#endif /* AVCODEC_FAANIDCT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/faxcompr.c b/tizen/distrib/ffmpeg/libavcodec/faxcompr.c deleted file mode 100644 index 34aa576..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/faxcompr.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * CCITT Fax Group 3 and 4 decompression - * Copyright (c) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * CCITT Fax Group 3 and 4 decompression - * @file - * @author Konstantin Shishkov - */ -#include "avcodec.h" -#include "get_bits.h" -#include "put_bits.h" -#include "faxcompr.h" - -#define CCITT_SYMS 104 - -static const uint16_t ccitt_syms[CCITT_SYMS] = { - 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, - 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, - 960, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, - 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560 -}; - -static const uint8_t ccitt_codes_bits[2][CCITT_SYMS] = -{ - { - 0x35, 0x07, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, 0x13, 0x14, 0x07, 0x08, 0x08, - 0x03, 0x34, 0x35, 0x2A, 0x2B, 0x27, 0x0C, 0x08, 0x17, 0x03, 0x04, 0x28, 0x2B, - 0x13, 0x24, 0x18, 0x02, 0x03, 0x1A, 0x1B, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x04, 0x05, 0x0A, 0x0B, 0x52, 0x53, 0x54, - 0x55, 0x24, 0x25, 0x58, 0x59, 0x5A, 0x5B, 0x4A, 0x4B, 0x32, 0x33, 0x34, 0x1B, - 0x12, 0x17, 0x37, 0x36, 0x37, 0x64, 0x65, 0x68, 0x67, 0xCC, 0xCD, 0xD2, 0xD3, - 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0x98, 0x99, 0x9A, 0x18, 0x9B, - 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F - }, - { - 0x37, 0x02, 0x03, 0x02, 0x03, 0x03, 0x02, 0x03, 0x05, 0x04, 0x04, 0x05, 0x07, - 0x04, 0x07, 0x18, 0x17, 0x18, 0x08, 0x67, 0x68, 0x6C, 0x37, 0x28, 0x17, 0x18, - 0xCA, 0xCB, 0xCC, 0xCD, 0x68, 0x69, 0x6A, 0x6B, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, - 0xD7, 0x6C, 0x6D, 0xDA, 0xDB, 0x54, 0x55, 0x56, 0x57, 0x64, 0x65, 0x52, 0x53, - 0x24, 0x37, 0x38, 0x27, 0x28, 0x58, 0x59, 0x2B, 0x2C, 0x5A, 0x66, 0x67, 0x0F, - 0xC8, 0xC9, 0x5B, 0x33, 0x34, 0x35, 0x6C, 0x6D, 0x4A, 0x4B, 0x4C, 0x4D, 0x72, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x52, 0x53, 0x54, 0x55, 0x5A, 0x5B, 0x64, 0x65, - 0x08, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F - } -}; - -static const uint8_t ccitt_codes_lens[2][CCITT_SYMS] = -{ - { - 8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 11, 11, 11, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12 - }, - { - 10, 3, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 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, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 10, 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, 11, 11, 11, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12 - } -}; - -static const uint8_t ccitt_group3_2d_bits[11] = { - 1, 1, 2, 2, 2, 1, 3, 3, 3, 1, 1 -}; - -static const uint8_t ccitt_group3_2d_lens[11] = { - 4, 3, 7, 6, 3, 1, 3, 6, 7, 7, 9 -}; - -static VLC ccitt_vlc[2], ccitt_group3_2d_vlc; - -av_cold void ff_ccitt_unpack_init(void) -{ - static VLC_TYPE code_table1[528][2]; - static VLC_TYPE code_table2[648][2]; - int i; - static int initialized = 0; - - if(initialized) - return; - ccitt_vlc[0].table = code_table1; - ccitt_vlc[0].table_allocated = 528; - ccitt_vlc[1].table = code_table2; - ccitt_vlc[1].table_allocated = 648; - for(i = 0; i < 2; i++){ - init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS, - ccitt_codes_lens[i], 1, 1, - ccitt_codes_bits[i], 1, 1, - ccitt_syms, 2, 2, - INIT_VLC_USE_NEW_STATIC); - } - INIT_VLC_STATIC(&ccitt_group3_2d_vlc, 9, 11, - ccitt_group3_2d_lens, 1, 1, - ccitt_group3_2d_bits, 1, 1, 512); - initialized = 1; -} - - -static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, - unsigned int pix_left, int *runs, const int *runend) -{ - int mode = 0; - unsigned int run=0; - unsigned int t; - for(;;){ - t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); - run += t; - if(t < 64){ - *runs++ = run; - if(runs >= runend){ - av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); - return -1; - } - if(pix_left <= run){ - if(pix_left == run) - break; - av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - pix_left -= run; - run = 0; - mode = !mode; - }else if((int)t == -1){ - av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); - return -1; - } - } - *runs++ = 0; - return 0; -} - -static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, - unsigned int width, int *runs, const int *runend, const int *ref) -{ - int mode = 0, saved_run = 0, t; - int run_off = *ref++; - unsigned int offs=0, run= 0; - - runend--; // for the last written 0 - - while(offs < width){ - int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); - if(cmode == -1){ - av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n"); - return -1; - } - if(!cmode){//pass mode - run_off += *ref++; - run = run_off - offs; - offs= run_off; - run_off += *ref++; - if(offs > width){ - av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - saved_run += run; - }else if(cmode == 1){//horizontal mode - int k; - for(k = 0; k < 2; k++){ - run = 0; - for(;;){ - t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); - if(t == -1){ - av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); - return -1; - } - run += t; - if(t < 64) - break; - } - *runs++ = run + saved_run; - if(runs >= runend){ - av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); - return -1; - } - saved_run = 0; - offs += run; - if(offs > width || run > width){ - av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - mode = !mode; - } - }else if(cmode == 9 || cmode == 10){ - av_log(avctx, AV_LOG_ERROR, "Special modes are not supported (yet)\n"); - return -1; - }else{//vertical mode - run = run_off - offs + (cmode - 5); - run_off -= *--ref; - offs += run; - if(offs > width || run > width){ - av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - *runs++ = run + saved_run; - if(runs >= runend){ - av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); - return -1; - } - saved_run = 0; - mode = !mode; - } - //sync line pointers - while(run_off <= offs){ - run_off += *ref++; - run_off += *ref++; - } - } - *runs++ = saved_run; - *runs++ = 0; - return 0; -} - -static void put_line(uint8_t *dst, int size, int width, const int *runs) -{ - PutBitContext pb; - int run, mode = ~0, pix_left = width, run_idx = 0; - - init_put_bits(&pb, dst, size*8); - while(pix_left > 0){ - run = runs[run_idx++]; - mode = ~mode; - pix_left -= run; - for(; run > 16; run -= 16) - put_sbits(&pb, 16, mode); - if(run) - put_sbits(&pb, run, mode); - } - flush_put_bits(&pb); -} - -static int find_group3_syncmarker(GetBitContext *gb, int srcsize) -{ - unsigned int state = -1; - srcsize -= get_bits_count(gb); - while(srcsize-- > 0){ - state+= state + get_bits1(gb); - if((state & 0xFFF) == 1) - return 0; - } - return -1; -} - -int ff_ccitt_unpack(AVCodecContext *avctx, - const uint8_t *src, int srcsize, - uint8_t *dst, int height, int stride, - enum TiffCompr compr, int opts) -{ - int j; - GetBitContext gb; - int *runs, *ref, *runend; - int ret; - int runsize= avctx->width + 2; - - runs = av_malloc(runsize * sizeof(runs[0])); - ref = av_malloc(runsize * sizeof(ref[0])); - ref[0] = avctx->width; - ref[1] = 0; - ref[2] = 0; - init_get_bits(&gb, src, srcsize*8); - for(j = 0; j < height; j++){ - runend = runs + runsize; - if(compr == TIFF_G4){ - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); - if(ret < 0){ - av_free(runs); - av_free(ref); - return -1; - } - }else{ - int g3d1 = (compr == TIFF_G3) && !(opts & 1); - if(compr!=TIFF_CCITT_RLE && find_group3_syncmarker(&gb, srcsize*8) < 0) - break; - if(compr==TIFF_CCITT_RLE || g3d1 || get_bits1(&gb)) - ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend); - else - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); - if(compr==TIFF_CCITT_RLE) - align_get_bits(&gb); - } - if(ret < 0){ - put_line(dst, stride, avctx->width, ref); - }else{ - put_line(dst, stride, avctx->width, runs); - FFSWAP(int*, runs, ref); - } - dst += stride; - } - av_free(runs); - av_free(ref); - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/faxcompr.h b/tizen/distrib/ffmpeg/libavcodec/faxcompr.h deleted file mode 100644 index 62f591c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/faxcompr.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * CCITT Fax Group 3 and 4 decompression - * Copyright (c) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * CCITT Fax Group 3 and 4 decompression - * @file - * @author Konstantin Shishkov - */ -#ifndef AVCODEC_FAXCOMPR_H -#define AVCODEC_FAXCOMPR_H - -#include "avcodec.h" -#include "tiff.h" - -/** - * initialize upacker code - */ -void ff_ccitt_unpack_init(void); - -/** - * unpack data compressed with CCITT Group 3 1/2-D or Group 4 method - */ -int ff_ccitt_unpack(AVCodecContext *avctx, - const uint8_t *src, int srcsize, - uint8_t *dst, int height, int stride, - enum TiffCompr compr, int opts); - -#endif /* AVCODEC_FAXCOMPR_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/fft-test.c b/tizen/distrib/ffmpeg/libavcodec/fft-test.c deleted file mode 100644 index ae43602..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/fft-test.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * FFT and MDCT tests. - */ - -#include "libavutil/mathematics.h" -#include "libavutil/lfg.h" -#include "libavutil/log.h" -#include "fft.h" -#include -#include -#include -#include -#include - -#undef exit - -/* 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; - -static void fft_ref_init(int nbits, int inverse) -{ - int n, i; - double 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; - } -} - -static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits) -{ - int n, i, j, k, n2; - double tmp_re, tmp_im, s, c; - FFTComplex *q; - - n = 1 << nbits; - n2 = n >> 1; - for (i = 0; i < n; i++) { - tmp_re = 0; - tmp_im = 0; - q = tab; - for (j = 0; j < n; j++) { - k = (i * j) & (n - 1); - if (k >= 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; - } -} - -static void imdct_ref(float *out, float *in, int nbits) -{ - int n = 1<= 1e-3) { - av_log(NULL, AV_LOG_ERROR, "ERROR %d: %f %f\n", - i, tab1[i], tab2[i]); - } - error+= e*e; - if(e>max) max= e; - } - av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error)/n); -} - - -static 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" - "-d (I)DCT test\n" - "-r (I)RDFT test\n" - "-i inverse transform test\n" - "-n b set the transform size to 2^b\n" - "-f x set scale factor for output data of (I)MDCT to x\n" - ); - exit(1); -} - -enum tf_transform { - TRANSFORM_FFT, - TRANSFORM_MDCT, - TRANSFORM_RDFT, - TRANSFORM_DCT, -}; - -int main(int argc, char **argv) -{ - FFTComplex *tab, *tab1, *tab_ref; - FFTSample *tab2; - int it, i, c; - int do_speed = 0; - enum tf_transform transform = TRANSFORM_FFT; - int do_inverse = 0; - FFTContext s1, *s = &s1; - FFTContext m1, *m = &m1; - RDFTContext r1, *r = &r1; - DCTContext d1, *d = &d1; - int fft_nbits, fft_size, fft_size_2; - double scale = 1.0; - AVLFG prng; - av_lfg_init(&prng, 1); - - fft_nbits = 9; - for(;;) { - c = getopt(argc, argv, "hsimrdn:f:"); - if (c == -1) - break; - switch(c) { - case 'h': - help(); - break; - case 's': - do_speed = 1; - break; - case 'i': - do_inverse = 1; - break; - case 'm': - transform = TRANSFORM_MDCT; - break; - case 'r': - transform = TRANSFORM_RDFT; - break; - case 'd': - transform = TRANSFORM_DCT; - break; - case 'n': - fft_nbits = atoi(optarg); - break; - case 'f': - scale = atof(optarg); - break; - } - } - - fft_size = 1 << fft_nbits; - fft_size_2 = fft_size >> 1; - tab = av_malloc(fft_size * sizeof(FFTComplex)); - tab1 = av_malloc(fft_size * sizeof(FFTComplex)); - tab_ref = av_malloc(fft_size * sizeof(FFTComplex)); - tab2 = av_malloc(fft_size * sizeof(FFTSample)); - - switch (transform) { - case TRANSFORM_MDCT: - av_log(NULL, AV_LOG_INFO,"Scale factor is set to %f\n", scale); - 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, scale); - break; - case TRANSFORM_FFT: - 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); - break; - case TRANSFORM_RDFT: - if (do_inverse) - av_log(NULL, AV_LOG_INFO,"IDFT_C2R"); - else - av_log(NULL, AV_LOG_INFO,"DFT_R2C"); - ff_rdft_init(r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C); - fft_ref_init(fft_nbits, do_inverse); - break; - case TRANSFORM_DCT: - if (do_inverse) - av_log(NULL, AV_LOG_INFO,"DCT_III"); - else - av_log(NULL, AV_LOG_INFO,"DCT_II"); - ff_dct_init(d, fft_nbits, do_inverse ? DCT_III : DCT_II); - break; - } - av_log(NULL, AV_LOG_INFO," %d test\n", fft_size); - - /* generate random data */ - - for (i = 0; i < fft_size; i++) { - tab1[i].re = frandom(&prng); - tab1[i].im = frandom(&prng); - } - - /* checking result */ - av_log(NULL, AV_LOG_INFO,"Checking...\n"); - - switch (transform) { - case TRANSFORM_MDCT: - if (do_inverse) { - imdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); - ff_imdct_calc(m, tab2, (float *)tab1); - check_diff((float *)tab_ref, tab2, fft_size, scale); - } else { - mdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); - - ff_mdct_calc(m, tab2, (float *)tab1); - - check_diff((float *)tab_ref, tab2, fft_size / 2, scale); - } - break; - case TRANSFORM_FFT: - memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); - ff_fft_permute(s, tab); - ff_fft_calc(s, tab); - - fft_ref(tab_ref, tab1, fft_nbits); - check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 1.0); - break; - case TRANSFORM_RDFT: - if (do_inverse) { - tab1[ 0].im = 0; - tab1[fft_size_2].im = 0; - for (i = 1; i < fft_size_2; i++) { - tab1[fft_size_2+i].re = tab1[fft_size_2-i].re; - tab1[fft_size_2+i].im = -tab1[fft_size_2-i].im; - } - - memcpy(tab2, tab1, fft_size * sizeof(FFTSample)); - tab2[1] = tab1[fft_size_2].re; - - ff_rdft_calc(r, tab2); - fft_ref(tab_ref, tab1, fft_nbits); - for (i = 0; i < fft_size; i++) { - tab[i].re = tab2[i]; - tab[i].im = 0; - } - check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 0.5); - } else { - for (i = 0; i < fft_size; i++) { - tab2[i] = tab1[i].re; - tab1[i].im = 0; - } - ff_rdft_calc(r, tab2); - fft_ref(tab_ref, tab1, fft_nbits); - tab_ref[0].im = tab_ref[fft_size_2].re; - check_diff((float *)tab_ref, (float *)tab2, fft_size, 1.0); - } - break; - case TRANSFORM_DCT: - memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); - ff_dct_calc(d, tab); - if (do_inverse) { - idct_ref(tab_ref, tab1, fft_nbits); - } else { - dct_ref(tab_ref, tab1, fft_nbits); - } - check_diff((float *)tab_ref, (float *)tab, fft_size, 1.0); - break; - } - - /* do a speed test */ - - if (do_speed) { - int64_t time_start, duration; - int nb_its; - - av_log(NULL, AV_LOG_INFO,"Speed test...\n"); - /* we measure during about 1 seconds */ - nb_its = 1; - for(;;) { - time_start = gettime(); - for (it = 0; it < nb_its; it++) { - switch (transform) { - case TRANSFORM_MDCT: - if (do_inverse) { - ff_imdct_calc(m, (float *)tab, (float *)tab1); - } else { - ff_mdct_calc(m, (float *)tab, (float *)tab1); - } - break; - case TRANSFORM_FFT: - memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); - ff_fft_calc(s, tab); - break; - case TRANSFORM_RDFT: - memcpy(tab2, tab1, fft_size * sizeof(FFTSample)); - ff_rdft_calc(r, tab2); - break; - case TRANSFORM_DCT: - memcpy(tab2, tab1, fft_size * sizeof(FFTSample)); - ff_dct_calc(d, tab2); - break; - } - } - duration = gettime() - time_start; - if (duration >= 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); - } - - switch (transform) { - case TRANSFORM_MDCT: - ff_mdct_end(m); - break; - case TRANSFORM_FFT: - ff_fft_end(s); - break; - case TRANSFORM_RDFT: - ff_rdft_end(r); - break; - case TRANSFORM_DCT: - ff_dct_end(d); - break; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/fft.c b/tizen/distrib/ffmpeg/libavcodec/fft.c deleted file mode 100644 index bf240bf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/fft.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * FFT/IFFT transforms - * Copyright (c) 2008 Loren Merritt - * Copyright (c) 2002 Fabrice Bellard - * Partly based on libdjbfft by D. J. Bernstein - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * FFT/IFFT transforms. - */ - -#include -#include -#include "libavutil/mathematics.h" -#include "fft.h" - -/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */ -#if !CONFIG_HARDCODED_TABLES -COSTABLE(16); -COSTABLE(32); -COSTABLE(64); -COSTABLE(128); -COSTABLE(256); -COSTABLE(512); -COSTABLE(1024); -COSTABLE(2048); -COSTABLE(4096); -COSTABLE(8192); -COSTABLE(16384); -COSTABLE(32768); -COSTABLE(65536); -#endif -COSTABLE_CONST FFTSample * const ff_cos_tabs[] = { - NULL, NULL, NULL, NULL, - ff_cos_16, ff_cos_32, ff_cos_64, ff_cos_128, ff_cos_256, ff_cos_512, ff_cos_1024, - ff_cos_2048, ff_cos_4096, ff_cos_8192, ff_cos_16384, ff_cos_32768, ff_cos_65536, -}; - -static int split_radix_permutation(int i, int n, int inverse) -{ - int m; - if(n <= 2) return i&1; - m = n >> 1; - if(!(i&m)) return split_radix_permutation(i, m, inverse)*2; - m >>= 1; - if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1; - else return split_radix_permutation(i, m, inverse)*4 - 1; -} - -av_cold void ff_init_ff_cos_tabs(int index) -{ -#if !CONFIG_HARDCODED_TABLES - int i; - int m = 1< 16) - goto fail; - s->nbits = nbits; - n = 1 << nbits; - - s->tmp_buf = NULL; - 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; - - s->fft_permute = ff_fft_permute_c; - s->fft_calc = ff_fft_calc_c; -#if CONFIG_MDCT - s->imdct_calc = ff_imdct_calc_c; - s->imdct_half = ff_imdct_half_c; - s->mdct_calc = ff_mdct_calc_c; -#endif - s->exptab1 = NULL; - s->split_radix = 1; - - if (ARCH_ARM) ff_fft_init_arm(s); - if (HAVE_ALTIVEC) ff_fft_init_altivec(s); - if (HAVE_MMX) ff_fft_init_mmx(s); - - if (s->split_radix) { - for(j=4; j<=nbits; j++) { - ff_init_ff_cos_tabs(j); - } - for(i=0; irevtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = i; - s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); - } else { - int np, nblocks, np2, l; - FFTComplex *q; - - 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; - } - - 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); - - /* 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); - av_freep(&s->tmp_buf); - return -1; -} - -void ff_fft_permute_c(FFTContext *s, FFTComplex *z) -{ - int j, k, np; - FFTComplex tmp; - const uint16_t *revtab = s->revtab; - np = 1 << s->nbits; - - if (s->tmp_buf) { - /* TODO: handle split-radix permute in a more optimal way, probably in-place */ - for(j=0;jtmp_buf[revtab[j]] = z[j]; - memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); - return; - } - - /* reverse */ - for(j=0;jrevtab); - av_freep(&s->exptab); - av_freep(&s->exptab1); - av_freep(&s->tmp_buf); -} - -#define sqrthalf (float)M_SQRT1_2 - -#define BF(x,y,a,b) {\ - x = a - b;\ - y = a + b;\ -} - -#define BUTTERFLIES(a0,a1,a2,a3) {\ - BF(t3, t5, t5, t1);\ - BF(a2.re, a0.re, a0.re, t5);\ - BF(a3.im, a1.im, a1.im, t3);\ - BF(t4, t6, t2, t6);\ - BF(a3.re, a1.re, a1.re, t4);\ - BF(a2.im, a0.im, a0.im, t6);\ -} - -// force loading all the inputs before storing any. -// this is slightly slower for small data, but avoids store->load aliasing -// for addresses separated by large powers of 2. -#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\ - FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\ - BF(t3, t5, t5, t1);\ - BF(a2.re, a0.re, r0, t5);\ - BF(a3.im, a1.im, i1, t3);\ - BF(t4, t6, t2, t6);\ - BF(a3.re, a1.re, r1, t4);\ - BF(a2.im, a0.im, i0, t6);\ -} - -#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\ - t1 = a2.re * wre + a2.im * wim;\ - t2 = a2.im * wre - a2.re * wim;\ - t5 = a3.re * wre - a3.im * wim;\ - t6 = a3.im * wre + a3.re * wim;\ - BUTTERFLIES(a0,a1,a2,a3)\ -} - -#define TRANSFORM_ZERO(a0,a1,a2,a3) {\ - t1 = a2.re;\ - t2 = a2.im;\ - t5 = a3.re;\ - t6 = a3.im;\ - BUTTERFLIES(a0,a1,a2,a3)\ -} - -/* z[0...8n-1], w[1...2n-1] */ -#define PASS(name)\ -static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\ -{\ - FFTSample t1, t2, t3, t4, t5, t6;\ - int o1 = 2*n;\ - int o2 = 4*n;\ - int o3 = 6*n;\ - const FFTSample *wim = wre+o1;\ - n--;\ -\ - TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\ - TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ - do {\ - z += 2;\ - wre += 2;\ - wim -= 2;\ - TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\ - TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\ - } while(--n);\ -} - -PASS(pass) -#undef BUTTERFLIES -#define BUTTERFLIES BUTTERFLIES_BIG -PASS(pass_big) - -#define DECL_FFT(n,n2,n4)\ -static void fft##n(FFTComplex *z)\ -{\ - fft##n2(z);\ - fft##n4(z+n4*2);\ - fft##n4(z+n4*3);\ - pass(z,ff_cos_##n,n4/2);\ -} - -static void fft4(FFTComplex *z) -{ - FFTSample t1, t2, t3, t4, t5, t6, t7, t8; - - BF(t3, t1, z[0].re, z[1].re); - BF(t8, t6, z[3].re, z[2].re); - BF(z[2].re, z[0].re, t1, t6); - BF(t4, t2, z[0].im, z[1].im); - BF(t7, t5, z[2].im, z[3].im); - BF(z[3].im, z[1].im, t4, t8); - BF(z[3].re, z[1].re, t3, t7); - BF(z[2].im, z[0].im, t2, t5); -} - -static void fft8(FFTComplex *z) -{ - FFTSample t1, t2, t3, t4, t5, t6, t7, t8; - - fft4(z); - - BF(t1, z[5].re, z[4].re, -z[5].re); - BF(t2, z[5].im, z[4].im, -z[5].im); - BF(t3, z[7].re, z[6].re, -z[7].re); - BF(t4, z[7].im, z[6].im, -z[7].im); - BF(t8, t1, t3, t1); - BF(t7, t2, t2, t4); - BF(z[4].re, z[0].re, z[0].re, t1); - BF(z[4].im, z[0].im, z[0].im, t2); - BF(z[6].re, z[2].re, z[2].re, t7); - BF(z[6].im, z[2].im, z[2].im, t8); - - TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf); -} - -#if !CONFIG_SMALL -static void fft16(FFTComplex *z) -{ - FFTSample t1, t2, t3, t4, t5, t6; - - fft8(z); - fft4(z+8); - fft4(z+12); - - TRANSFORM_ZERO(z[0],z[4],z[8],z[12]); - TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf); - TRANSFORM(z[1],z[5],z[9],z[13],ff_cos_16[1],ff_cos_16[3]); - TRANSFORM(z[3],z[7],z[11],z[15],ff_cos_16[3],ff_cos_16[1]); -} -#else -DECL_FFT(16,8,4) -#endif -DECL_FFT(32,16,8) -DECL_FFT(64,32,16) -DECL_FFT(128,64,32) -DECL_FFT(256,128,64) -DECL_FFT(512,256,128) -#if !CONFIG_SMALL -#define pass pass_big -#endif -DECL_FFT(1024,512,256) -DECL_FFT(2048,1024,512) -DECL_FFT(4096,2048,1024) -DECL_FFT(8192,4096,2048) -DECL_FFT(16384,8192,4096) -DECL_FFT(32768,16384,8192) -DECL_FFT(65536,32768,16384) - -static void (* const fft_dispatch[])(FFTComplex*) = { - fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, - fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, -}; - -void ff_fft_calc_c(FFTContext *s, FFTComplex *z) -{ - fft_dispatch[s->nbits-2](z); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/fft.h b/tizen/distrib/ffmpeg/libavcodec/fft.h deleted file mode 100644 index 1f5b2e8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/fft.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_FFT_H -#define AVCODEC_FFT_H - -#include -#include "config.h" -#include "libavutil/mem.h" -#include "avfft.h" - -/* FFT computation */ - -struct FFTContext { - int nbits; - int inverse; - uint16_t *revtab; - FFTComplex *exptab; - FFTComplex *exptab1; /* only used by SSE code */ - FFTComplex *tmp_buf; - int mdct_size; /* size of MDCT (i.e. number of input data * 2) */ - int mdct_bits; /* n = 2^nbits */ - /* pre/post rotation tables */ - FFTSample *tcos; - FFTSample *tsin; - void (*fft_permute)(struct FFTContext *s, FFTComplex *z); - void (*fft_calc)(struct FFTContext *s, FFTComplex *z); - void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); - void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input); - void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); - int split_radix; - int permutation; -#define FF_MDCT_PERM_NONE 0 -#define FF_MDCT_PERM_INTERLEAVE 1 -}; - -#if CONFIG_HARDCODED_TABLES -#define COSTABLE_CONST const -#define SINTABLE_CONST const -#define SINETABLE_CONST const -#else -#define COSTABLE_CONST -#define SINTABLE_CONST -#define SINETABLE_CONST -#endif - -#define COSTABLE(size) \ - COSTABLE_CONST DECLARE_ALIGNED(16, FFTSample, ff_cos_##size)[size/2] -#define SINTABLE(size) \ - SINTABLE_CONST DECLARE_ALIGNED(16, FFTSample, ff_sin_##size)[size/2] -#define SINETABLE(size) \ - SINETABLE_CONST DECLARE_ALIGNED(16, float, ff_sine_##size)[size] -extern COSTABLE(16); -extern COSTABLE(32); -extern COSTABLE(64); -extern COSTABLE(128); -extern COSTABLE(256); -extern COSTABLE(512); -extern COSTABLE(1024); -extern COSTABLE(2048); -extern COSTABLE(4096); -extern COSTABLE(8192); -extern COSTABLE(16384); -extern COSTABLE(32768); -extern COSTABLE(65536); -extern COSTABLE_CONST FFTSample* const ff_cos_tabs[17]; - -/** - * Initializes the cosine table in ff_cos_tabs[index] - * \param index index in ff_cos_tabs array of the table to initialize - */ -void ff_init_ff_cos_tabs(int index); - -extern SINTABLE(16); -extern SINTABLE(32); -extern SINTABLE(64); -extern SINTABLE(128); -extern SINTABLE(256); -extern SINTABLE(512); -extern SINTABLE(1024); -extern SINTABLE(2048); -extern SINTABLE(4096); -extern SINTABLE(8192); -extern SINTABLE(16384); -extern SINTABLE(32768); -extern SINTABLE(65536); - -/** - * Sets up a complex FFT. - * @param nbits log2 of the length of the input array - * @param inverse if 0 perform the forward transform, if 1 perform the inverse - */ -int ff_fft_init(FFTContext *s, int nbits, int inverse); -void ff_fft_permute_c(FFTContext *s, FFTComplex *z); -void ff_fft_calc_c(FFTContext *s, FFTComplex *z); - -void ff_fft_init_altivec(FFTContext *s); -void ff_fft_init_mmx(FFTContext *s); -void ff_fft_init_arm(FFTContext *s); - -/** - * Do the permutation needed BEFORE calling ff_fft_calc(). - */ -static inline void ff_fft_permute(FFTContext *s, FFTComplex *z) -{ - s->fft_permute(s, z); -} -/** - * Do a complex FFT with the parameters defined in ff_fft_init(). The - * input data must be permuted before. No 1.0/sqrt(n) normalization is done. - */ -static inline void ff_fft_calc(FFTContext *s, FFTComplex *z) -{ - s->fft_calc(s, z); -} -void ff_fft_end(FFTContext *s); - -/* MDCT computation */ - -static inline void ff_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - s->imdct_calc(s, output, input); -} -static inline void ff_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - s->imdct_half(s, output, input); -} - -static inline void ff_mdct_calc(FFTContext *s, FFTSample *output, - const FFTSample *input) -{ - s->mdct_calc(s, output, input); -} - -/** - * Generate a Kaiser-Bessel Derived Window. - * @param window pointer to half window - * @param alpha determines window shape - * @param n size of half window - */ -void ff_kbd_window_init(float *window, float alpha, int n); - -/** - * Generate a sine window. - * @param window pointer to half window - * @param n size of half window - */ -void ff_sine_window_init(float *window, int n); - -/** - * initialize the specified entry of ff_sine_windows - */ -void ff_init_ff_sine_windows(int index); -extern SINETABLE( 32); -extern SINETABLE( 64); -extern SINETABLE( 128); -extern SINETABLE( 256); -extern SINETABLE( 512); -extern SINETABLE(1024); -extern SINETABLE(2048); -extern SINETABLE(4096); -extern SINETABLE_CONST float * const ff_sine_windows[13]; - -int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale); -void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_mdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_mdct_end(FFTContext *s); - -/* Real Discrete Fourier Transform */ - -struct RDFTContext { - int nbits; - int inverse; - int sign_convention; - - /* pre/post rotation tables */ - const FFTSample *tcos; - SINTABLE_CONST FFTSample *tsin; - FFTContext fft; - void (*rdft_calc)(struct RDFTContext *s, FFTSample *z); -}; - -/** - * Sets up a real FFT. - * @param nbits log2 of the length of the input array - * @param trans the type of transform - */ -int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans); -void ff_rdft_end(RDFTContext *s); - -void ff_rdft_init_arm(RDFTContext *s); - -static av_always_inline void ff_rdft_calc(RDFTContext *s, FFTSample *data) -{ - s->rdft_calc(s, data); -} - -/* Discrete Cosine Transform */ - -struct DCTContext { - int nbits; - int inverse; - RDFTContext rdft; - const float *costab; - FFTSample *csc2; - void (*dct_calc)(struct DCTContext *s, FFTSample *data); -}; - -/** - * Sets up DCT. - * @param nbits size of the input array: - * (1 << nbits) for DCT-II, DCT-III and DST-I - * (1 << nbits) + 1 for DCT-I - * - * @note the first element of the input of DST-I is ignored - */ -int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType type); -void ff_dct_calc(DCTContext *s, FFTSample *data); -void ff_dct_end (DCTContext *s); - -#endif /* AVCODEC_FFT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ffv1.c b/tizen/distrib/ffmpeg/libavcodec/ffv1.c deleted file mode 100644 index 12056e1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ffv1.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* - * FFV1 codec for libavcodec - * - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * FF Video Codec 1 (a lossless codec) - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "put_bits.h" -#include "dsputil.h" -#include "rangecoder.h" -#include "golomb.h" -#include "mathops.h" - -#define MAX_PLANES 4 -#define CONTEXT_SIZE 32 - -extern const uint8_t ff_log2_run[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_10bit[256]={ - 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, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, --2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, --2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, --2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, --2,-2,-2,-2,-2,-2,-2,-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,-0,-0,-0,-0,-0,-0,-0,-0,-0,-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 quant9_10bit[256]={ - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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,-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,-1,-1,-1,-1,-1,-1,-1,-1,-0,-0,-0,-0, -}; - -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 ver2_state[256]= { - 0, 10, 10, 10, 10, 16, 16, 16, 28, 16, 16, 29, 42, 49, 20, 49, - 59, 25, 26, 26, 27, 31, 33, 33, 33, 34, 34, 37, 67, 38, 39, 39, - 40, 40, 41, 79, 43, 44, 45, 45, 48, 48, 64, 50, 51, 52, 88, 52, - 53, 74, 55, 57, 58, 58, 74, 60, 101, 61, 62, 84, 66, 66, 68, 69, - 87, 82, 71, 97, 73, 73, 82, 75, 111, 77, 94, 78, 87, 81, 83, 97, - 85, 83, 94, 86, 99, 89, 90, 99, 111, 92, 93, 134, 95, 98, 105, 98, - 105, 110, 102, 108, 102, 118, 103, 106, 106, 113, 109, 112, 114, 112, 116, 125, - 115, 116, 117, 117, 126, 119, 125, 121, 121, 123, 145, 124, 126, 131, 127, 129, - 165, 130, 132, 138, 133, 135, 145, 136, 137, 139, 146, 141, 143, 142, 144, 148, - 147, 155, 151, 149, 151, 150, 152, 157, 153, 154, 156, 168, 158, 162, 161, 160, - 172, 163, 169, 164, 166, 184, 167, 170, 177, 174, 171, 173, 182, 176, 180, 178, - 175, 189, 179, 181, 186, 183, 192, 185, 200, 187, 191, 188, 190, 197, 193, 196, - 197, 194, 195, 196, 198, 202, 199, 201, 210, 203, 207, 204, 205, 206, 208, 214, - 209, 211, 221, 212, 213, 215, 224, 216, 217, 218, 219, 220, 222, 228, 223, 225, - 226, 224, 227, 229, 240, 230, 231, 232, 233, 234, 235, 236, 238, 239, 237, 242, - 241, 243, 242, 244, 245, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 255, -}; - -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=range coder <-> 0=golomb rice - PlaneContext plane[MAX_PLANES]; - int16_t quant_table[5][256]; - uint8_t state_transition[256]; - int run_index; - int colorspace; - - DSPContext dsp; -}FFV1Context; - -static av_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_inline(RangeCoder *c, uint8_t *state, int v, int is_signed){ - int i; - - if(v){ - const int a= FFABS(v); - const int e= av_log2(a); - put_rac(c, state+0, 0); - if(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{ - for(i=0; i=0; i--){ - put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 - } - - if(is_signed) - put_rac(c, state+11 + 10, v < 0); //11..21 - } - }else{ - put_rac(c, state+0, 1); - } -} - -static void av_noinline put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ - put_symbol_inline(c, state, v, is_signed); -} - -static inline av_flatten int get_symbol_inline(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 + FFMIN(e,9))){ //1..10 - e++; - } - - a= 1; - for(i=e-1; i>=0; i--){ - a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 - } - - e= -(is_signed && get_rac(c, state+11 + FFMIN(e, 10))); //11..21 - return (a^e)-e; - } -} - -static int av_noinline get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ - return get_symbol_inline(c, state, is_signed); -} - -static inline void update_vlc_state(VlcState * const state, const int v){ - int drift= state->drift; - int count= state->count; - state->error_sum += FFABS(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; -} - -#if CONFIG_FFV1_ENCODER -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_inline(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 + ff_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->bits_per_raw_sample<=8){ - for(x=0; x> (16 - s->avctx->bits_per_raw_sample); - } - encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); - } -//STOP_TIMER("encode line")} - } -} - -static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ - int x, y, p, i; - const int ring_size= s->avctx->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->ac, 0); - if(f->ac>1){ - for(i=1; i<256; i++){ - f->state_transition[i]=ver2_state[i]; - put_symbol(c, state, ver2_state[i] - c->one_state[i], 1); - } - } - put_symbol(c, state, f->colorspace, 0); //YUV cs type - if(f->version>0) - put_symbol(c, state, f->avctx->bits_per_raw_sample, 0); - 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]); -} -#endif /* CONFIG_FFV1_ENCODER */ - -static av_cold int common_init(AVCodecContext *avctx){ - FFV1Context *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 && s->height); - - return 0; -} - -#if CONFIG_FFV1_ENCODER -static av_cold int encode_init(AVCodecContext *avctx) -{ - FFV1Context *s = avctx->priv_data; - int i; - - common_init(avctx); - - s->version=0; - s->ac= avctx->coder_type ? 2:0; - - s->plane_count=2; - for(i=0; i<256; i++){ - if(avctx->bits_per_raw_sample <=8){ - 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]; - } - }else{ - s->quant_table[0][i]= quant9_10bit[i]; - s->quant_table[1][i]= 11*quant9_10bit[i]; - if(avctx->context_model==0){ - s->quant_table[2][i]= 11*11*quant9_10bit[i]; - s->quant_table[3][i]= - s->quant_table[4][i]=0; - }else{ - s->quant_table[2][i]= 11*11*quant5_10bit[i]; - s->quant_table[3][i]= 5*11*11*quant5_10bit[i]; - s->quant_table[4][i]= 5*5*11*11*quant5_10bit[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_YUV444P16: - case PIX_FMT_YUV422P16: - case PIX_FMT_YUV420P16: - if(avctx->bits_per_raw_sample <=8){ - av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n"); - return -1; - } - if(!s->ac){ - av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n"); - return -1; - } - s->version= 1; - 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_RGB32: - 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; -} -#endif /* CONFIG_FFV1_ENCODER */ - - -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; - } - } - } -} - -#if CONFIG_FFV1_ENCODER -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_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); - }else if (f->ac>1){ - int i; - for(i=1; i<256; i++){ - c->one_state[i]= f->state_transition[i]; - c->zero_state[256-i]= 256-c->one_state[i]; - } - } - - 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; - } -} -#endif /* CONFIG_FFV1_ENCODER */ - -static av_cold int common_end(AVCodecContext *avctx){ - FFV1Context *s = avctx->priv_data; - int i; - - for(i=0; iplane_count; i++){ - PlaneContext *p= &s->plane[i]; - - av_freep(&p->state); - av_freep(&p->vlc_state); - } - - return 0; -} - -static av_always_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_inline(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, ff_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[0]=sample_buffer[0]+3; - sample[1]=sample_buffer[1]+3; - - s->run_index=0; - - memset(sample_buffer, 0, sizeof(sample_buffer)); - - for(y=0; yavctx->bits_per_raw_sample <= 8){ - decode_line(s, w, sample, plane_index, 8); - for(x=0; xavctx->bits_per_raw_sample); - for(x=0; xavctx->bits_per_raw_sample); - } - } -//STOP_TIMER("decode-line")} - } -} - -static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ - int x, y, p; - int_fast16_t sample_buffer[3][2][w+6]; - int_fast16_t *sample[3][2]; - for(x=0; x<3; x++){ - sample[x][0] = sample_buffer[x][0]+3; - sample[x][1] = sample_buffer[x][1]+3; - } - - s->run_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); - if(f->ac>1){ - for(i=1; i<256; i++){ - f->state_transition[i]= get_symbol(c, state, 1) + c->one_state[i]; - } - } - f->colorspace= get_symbol(c, state, 0); //YUV cs type - if(f->version>0) - f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); - 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){ - if(f->avctx->bits_per_raw_sample<=8){ - 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{ - switch(16*f->chroma_h_shift + f->chroma_v_shift){ - case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break; - case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break; - case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P16; 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_RGB32; - }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 av_cold 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, AVPacket *avpkt){ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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->ac>1){ - int i; - for(i=1; i<256; i++){ - c->one_state[i]= f->state_transition[i]; - c->zero_state[256-i]= 256-c->one_state[i]; - } - } - - 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", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FFV1, - sizeof(FFV1Context), - decode_init, - NULL, - common_end, - decode_frame, - CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, - NULL, - .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), -}; - -#if CONFIG_FFV1_ENCODER -AVCodec ffv1_encoder = { - "ffv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FFV1, - sizeof(FFV1Context), - encode_init, - encode_frame, - common_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/flac.c b/tizen/distrib/ffmpeg/libavcodec/flac.c deleted file mode 100644 index a649e08..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flac.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * FLAC common code - * Copyright (c) 2009 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "flac.h" - -int ff_flac_get_max_frame_size(int blocksize, int ch, int bps) -{ - /* Technically, there is no limit to FLAC frame size, but an encoder - should not write a frame that is larger than if verbatim encoding mode - were to be used. */ - - int count; - - count = 16; /* frame header */ - count += ch * ((7+bps+7)/8); /* subframe headers */ - if (ch == 2) { - /* for stereo, need to account for using decorrelation */ - count += (( 2*bps+1) * blocksize + 7) / 8; - } else { - count += ( ch*bps * blocksize + 7) / 8; - } - count += 2; /* frame footer */ - - return count; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/flac.h b/tizen/distrib/ffmpeg/libavcodec/flac.h deleted file mode 100644 index 1b11463..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flac.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * FLAC (Free Lossless Audio Codec) decoder/demuxer common functions - * Copyright (c) 2008 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * FLAC (Free Lossless Audio Codec) decoder/demuxer common functions - */ - -#ifndef AVCODEC_FLAC_H -#define AVCODEC_FLAC_H - -#include "avcodec.h" - -#define FLAC_STREAMINFO_SIZE 34 -#define FLAC_MAX_CHANNELS 8 -#define FLAC_MIN_BLOCKSIZE 16 -#define FLAC_MAX_BLOCKSIZE 65535 - -enum { - FLAC_CHMODE_INDEPENDENT = 0, - FLAC_CHMODE_LEFT_SIDE = 8, - FLAC_CHMODE_RIGHT_SIDE = 9, - FLAC_CHMODE_MID_SIDE = 10, -}; - -enum { - FLAC_METADATA_TYPE_STREAMINFO = 0, - FLAC_METADATA_TYPE_PADDING, - FLAC_METADATA_TYPE_APPLICATION, - FLAC_METADATA_TYPE_SEEKTABLE, - FLAC_METADATA_TYPE_VORBIS_COMMENT, - FLAC_METADATA_TYPE_CUESHEET, - FLAC_METADATA_TYPE_PICTURE, - FLAC_METADATA_TYPE_INVALID = 127 -}; - -enum FLACExtradataFormat { - FLAC_EXTRADATA_FORMAT_STREAMINFO = 0, - FLAC_EXTRADATA_FORMAT_FULL_HEADER = 1 -}; - -#define FLACCOMMONINFO \ - int samplerate; /**< sample rate */\ - int channels; /**< number of channels */\ - int bps; /**< bits-per-sample */\ - -/** - * Data needed from the Streaminfo header for use by the raw FLAC demuxer - * and/or the FLAC decoder. - */ -#define FLACSTREAMINFO \ - FLACCOMMONINFO \ - int max_blocksize; /**< maximum block size, in samples */\ - int max_framesize; /**< maximum frame size, in bytes */\ - int64_t samples; /**< total number of samples */\ - -typedef struct FLACStreaminfo { - FLACSTREAMINFO -} FLACStreaminfo; - -typedef struct FLACFrameInfo { - FLACCOMMONINFO - int blocksize; /**< block size of the frame */ - int ch_mode; /**< channel decorrelation mode */ -} FLACFrameInfo; - -/** - * Parse the Streaminfo metadata block - * @param[out] avctx codec context to set basic stream parameters - * @param[out] s where parsed information is stored - * @param[in] buffer pointer to start of 34-byte streaminfo data - */ -void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, - const uint8_t *buffer); - -/** - * Validate the FLAC extradata. - * @param[in] avctx codec context containing the extradata. - * @param[out] format extradata format. - * @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data. - * @return 1 if valid, 0 if not valid. - */ -int ff_flac_is_extradata_valid(AVCodecContext *avctx, - enum FLACExtradataFormat *format, - uint8_t **streaminfo_start); - -/** - * Parse the metadata block parameters from the header. - * @param[in] block_header header data, at least 4 bytes - * @param[out] last indicator for last metadata block - * @param[out] type metadata block type - * @param[out] size metadata block size - */ -void ff_flac_parse_block_header(const uint8_t *block_header, - int *last, int *type, int *size); - -/** - * Calculate an estimate for the maximum frame size based on verbatim mode. - * @param blocksize block size, in samples - * @param ch number of channels - * @param bps bits-per-sample - */ -int ff_flac_get_max_frame_size(int blocksize, int ch, int bps); - -#endif /* AVCODEC_FLAC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/flacdata.c b/tizen/distrib/ffmpeg/libavcodec/flacdata.c deleted file mode 100644 index 6fcbe39..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flacdata.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * FLAC data - * Copyright (c) 2003 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "internal.h" - -const int ff_flac_sample_rate_table[16] = -{ 0, - 88200, 176400, 192000, - 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, - 0, 0, 0, 0 }; - -const int16_t ff_flac_blocksize_table[16] = { - 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 -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/flacdata.h b/tizen/distrib/ffmpeg/libavcodec/flacdata.h deleted file mode 100644 index 96a50b9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flacdata.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * FLAC data header - * Copyright (c) 2003 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_FLACDATA_H -#define AVCODEC_FLACDATA_H - -#include "internal.h" - -extern const int ff_flac_sample_rate_table[16]; - -extern const int16_t ff_flac_blocksize_table[16]; - -#endif /* AVCODEC_FLACDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/flacdec.c b/tizen/distrib/ffmpeg/libavcodec/flacdec.c deleted file mode 100644 index 07acf6e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flacdec.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * FLAC (Free Lossless Audio Codec) decoder - * Copyright (c) 2003 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 "libavutil/crc.h" -#include "avcodec.h" -#include "internal.h" -#include "get_bits.h" -#include "bytestream.h" -#include "golomb.h" -#include "flac.h" -#include "flacdata.h" - -#undef NDEBUG -#include - -typedef struct FLACContext { - FLACSTREAMINFO - - AVCodecContext *avctx; ///< parent AVCodecContext - GetBitContext gb; ///< GetBitContext initialized to start at the current frame - - int blocksize; ///< number of samples in the current frame - int curr_bps; ///< bps for current subframe, adjusted for channel correlation and wasted bits - int sample_shift; ///< shift required to make output samples 16-bit or 32-bit - int is32; ///< flag to indicate if output should be 32-bit instead of 16-bit - int ch_mode; ///< channel decorrelation type in the current frame - int got_streaminfo; ///< indicates if the STREAMINFO has been read - - int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples - uint8_t *bitstream; - unsigned int bitstream_size; - unsigned int bitstream_index; - unsigned int allocated_bitstream_size; -} FLACContext; - -static const int sample_size_table[] = -{ 0, 8, 12, 0, 16, 20, 24, 0 }; - -static int64_t get_utf8(GetBitContext *gb) -{ - int64_t val; - GET_UTF8(val, get_bits(gb, 8), return -1;) - return val; -} - -static void allocate_buffers(FLACContext *s); - -int ff_flac_is_extradata_valid(AVCodecContext *avctx, - enum FLACExtradataFormat *format, - uint8_t **streaminfo_start) -{ - if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) { - av_log(avctx, AV_LOG_ERROR, "extradata NULL or too small.\n"); - return 0; - } - if (AV_RL32(avctx->extradata) != MKTAG('f','L','a','C')) { - /* extradata contains STREAMINFO only */ - if (avctx->extradata_size != FLAC_STREAMINFO_SIZE) { - av_log(avctx, AV_LOG_WARNING, "extradata contains %d bytes too many.\n", - FLAC_STREAMINFO_SIZE-avctx->extradata_size); - } - *format = FLAC_EXTRADATA_FORMAT_STREAMINFO; - *streaminfo_start = avctx->extradata; - } else { - if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) { - av_log(avctx, AV_LOG_ERROR, "extradata too small.\n"); - return 0; - } - *format = FLAC_EXTRADATA_FORMAT_FULL_HEADER; - *streaminfo_start = &avctx->extradata[8]; - } - return 1; -} - -static av_cold int flac_decode_init(AVCodecContext *avctx) -{ - enum FLACExtradataFormat format; - uint8_t *streaminfo; - FLACContext *s = avctx->priv_data; - s->avctx = avctx; - - avctx->sample_fmt = SAMPLE_FMT_S16; - - /* for now, the raw FLAC header is allowed to be passed to the decoder as - frame data instead of extradata. */ - if (!avctx->extradata) - return 0; - - if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo)) - return -1; - - /* initialize based on the demuxer-supplied streamdata header */ - ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); - if (s->bps > 16) - avctx->sample_fmt = SAMPLE_FMT_S32; - else - avctx->sample_fmt = SAMPLE_FMT_S16; - allocate_buffers(s); - s->got_streaminfo = 1; - - return 0; -} - -static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s) -{ - av_log(avctx, AV_LOG_DEBUG, " Max Blocksize: %d\n", s->max_blocksize); - av_log(avctx, AV_LOG_DEBUG, " Max Framesize: %d\n", s->max_framesize); - av_log(avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate); - av_log(avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels); - av_log(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 = ff_flac_get_max_frame_size(s->max_blocksize, - s->channels, s->bps); - } - - for (i = 0; i < s->channels; i++) { - s->decoded[i] = av_realloc(s->decoded[i], - sizeof(int32_t)*s->max_blocksize); - } - - if (s->allocated_bitstream_size < s->max_framesize) - s->bitstream= av_fast_realloc(s->bitstream, - &s->allocated_bitstream_size, - s->max_framesize); -} - -void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, - const uint8_t *buffer) -{ - GetBitContext gb; - init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8); - - skip_bits(&gb, 16); /* skip min blocksize */ - s->max_blocksize = get_bits(&gb, 16); - if (s->max_blocksize < FLAC_MIN_BLOCKSIZE) { - av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n", - s->max_blocksize); - s->max_blocksize = 16; - } - - skip_bits(&gb, 24); /* skip min frame size */ - s->max_framesize = get_bits_long(&gb, 24); - - s->samplerate = get_bits_long(&gb, 20); - s->channels = get_bits(&gb, 3) + 1; - s->bps = get_bits(&gb, 5) + 1; - - avctx->channels = s->channels; - avctx->sample_rate = s->samplerate; - avctx->bits_per_raw_sample = s->bps; - - s->samples = get_bits_long(&gb, 32) << 4; - s->samples |= get_bits(&gb, 4); - - skip_bits_long(&gb, 64); /* md5 sum */ - skip_bits_long(&gb, 64); /* md5 sum */ - - dump_headers(avctx, s); -} - -void ff_flac_parse_block_header(const uint8_t *block_header, - int *last, int *type, int *size) -{ - int tmp = bytestream_get_byte(&block_header); - if (last) - *last = tmp & 0x80; - if (type) - *type = tmp & 0x7F; - if (size) - *size = bytestream_get_be24(&block_header); -} - -/** - * Parse the STREAMINFO from an inline header. - * @param s the flac decoding context - * @param buf input buffer, starting with the "fLaC" marker - * @param buf_size buffer size - * @return non-zero if metadata is invalid - */ -static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) -{ - int metadata_type, metadata_size; - - if (buf_size < FLAC_STREAMINFO_SIZE+8) { - /* need more data */ - return 0; - } - ff_flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size); - if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO || - metadata_size != FLAC_STREAMINFO_SIZE) { - return AVERROR_INVALIDDATA; - } - ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); - allocate_buffers(s); - s->got_streaminfo = 1; - - return 0; -} - -/** - * Determine the size of an inline header. - * @param buf input buffer, starting with the "fLaC" marker - * @param buf_size buffer size - * @return number of bytes in the header, or 0 if more data is needed - */ -static int get_metadata_size(const uint8_t *buf, int buf_size) -{ - int metadata_last, metadata_size; - const uint8_t *buf_end = buf + buf_size; - - buf += 4; - do { - ff_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size); - buf += 4; - if (buf + metadata_size > buf_end) { - /* need more data in order to read the complete header */ - return 0; - } - buf += metadata_size; - } while (!metadata_last); - - return buf_size - (buf_end - buf); -} - -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 > 1) { - av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n", - method_type); - return -1; - } - - rice_order = get_bits(&s->gb, 4); - - samples= s->blocksize >> rice_order; - if (pred_order > samples) { - av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n", - pred_order, samples); - return -1; - } - - sample= - i= pred_order; - for (partition = 0; partition < (1 << rice_order); partition++) { - tmp = get_bits(&s->gb, method_type == 0 ? 4 : 5); - if (tmp == (method_type == 0 ? 15 : 31)) { - tmp = get_bits(&s->gb, 5); - for (; i < samples; i++, sample++) - s->decoded[channel][sample] = get_sbits_long(&s->gb, tmp); - } else { - for (; i < samples; i++, sample++) { - s->decoded[channel][sample] = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0); - } - } - i= 0; - } - - return 0; -} - -static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) -{ - const int blocksize = s->blocksize; - int32_t *decoded = s->decoded[channel]; - int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; - - /* warm up samples */ - for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits_long(&s->gb, s->curr_bps); - } - - if (decode_residuals(s, channel, pred_order) < 0) - return -1; - - if (pred_order > 0) - a = decoded[pred_order-1]; - if (pred_order > 1) - b = a - decoded[pred_order-2]; - if (pred_order > 2) - c = b - decoded[pred_order-2] + decoded[pred_order-3]; - if (pred_order > 3) - d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4]; - - switch (pred_order) { - case 0: - break; - case 1: - for (i = pred_order; i < blocksize; i++) - decoded[i] = a += decoded[i]; - break; - case 2: - for (i = pred_order; i < blocksize; i++) - decoded[i] = a += b += decoded[i]; - break; - case 3: - for (i = pred_order; i < blocksize; i++) - decoded[i] = a += b += c += decoded[i]; - break; - case 4: - for (i = pred_order; i < blocksize; i++) - decoded[i] = a += b += c += d += decoded[i]; - 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 i, j; - int coeff_prec, qlevel; - int coeffs[32]; - int32_t *decoded = s->decoded[channel]; - - /* warm up samples */ - for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits_long(&s->gb, s->curr_bps); - } - - coeff_prec = get_bits(&s->gb, 4) + 1; - if (coeff_prec == 16) { - av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n"); - return -1; - } - qlevel = get_sbits(&s->gb, 5); - if (qlevel < 0) { - av_log(s->avctx, AV_LOG_ERROR, "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); - } - - if (decode_residuals(s, channel, pred_order) < 0) - return -1; - - if (s->bps > 16) { - int64_t sum; - for (i = pred_order; i < s->blocksize; i++) { - sum = 0; - for (j = 0; j < pred_order; j++) - sum += (int64_t)coeffs[j] * decoded[i-j-1]; - decoded[i] += sum >> qlevel; - } - } else { - for (i = pred_order; i < s->blocksize-1; i += 2) { - int c; - int d = decoded[i-pred_order]; - int s0 = 0, s1 = 0; - for (j = pred_order-1; j > 0; j--) { - c = coeffs[j]; - s0 += c*d; - d = decoded[i-j]; - s1 += c*d; - } - c = coeffs[0]; - s0 += c*d; - d = decoded[i] += s0 >> qlevel; - s1 += c*d; - decoded[i+1] += s1 >> qlevel; - } - if (i < s->blocksize) { - int sum = 0; - for (j = 0; j < pred_order; j++) - sum += coeffs[j] * decoded[i-j-1]; - decoded[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->ch_mode == FLAC_CHMODE_RIGHT_SIDE) - s->curr_bps++; - } else { - if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_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); - - if (get_bits1(&s->gb)) { - wasted = 1; - while (!get_bits1(&s->gb)) - wasted++; - s->curr_bps -= wasted; - } - if (s->curr_bps > 32) { - av_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0); - return -1; - } - -//FIXME use av_log2 for types - if (type == 0) { - tmp = get_sbits_long(&s->gb, s->curr_bps); - for (i = 0; i < s->blocksize; i++) - s->decoded[channel][i] = tmp; - } else if (type == 1) { - for (i = 0; i < s->blocksize; i++) - s->decoded[channel][i] = get_sbits_long(&s->gb, s->curr_bps); - } else if ((type >= 8) && (type <= 12)) { - if (decode_subframe_fixed(s, channel, type & ~0x8) < 0) - return -1; - } else if (type >= 32) { - 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; -} - -/** - * Validate and decode a frame header. - * @param avctx AVCodecContext to use as av_log() context - * @param gb GetBitContext from which to read frame header - * @param[out] fi frame information - * @return non-zero on error, 0 if ok - */ -static int decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, - FLACFrameInfo *fi) -{ - int bs_code, sr_code, bps_code; - - /* frame sync code */ - skip_bits(gb, 16); - - /* block size and sample rate codes */ - bs_code = get_bits(gb, 4); - sr_code = get_bits(gb, 4); - - /* channels and decorrelation */ - fi->ch_mode = get_bits(gb, 4); - if (fi->ch_mode < FLAC_MAX_CHANNELS) { - fi->channels = fi->ch_mode + 1; - fi->ch_mode = FLAC_CHMODE_INDEPENDENT; - } else if (fi->ch_mode <= FLAC_CHMODE_MID_SIDE) { - fi->channels = 2; - } else { - av_log(avctx, AV_LOG_ERROR, "invalid channel mode: %d\n", fi->ch_mode); - return -1; - } - - /* bits per sample */ - bps_code = get_bits(gb, 3); - if (bps_code == 3 || bps_code == 7) { - av_log(avctx, AV_LOG_ERROR, "invalid sample size code (%d)\n", - bps_code); - return -1; - } - fi->bps = sample_size_table[bps_code]; - - /* reserved bit */ - if (get_bits1(gb)) { - av_log(avctx, AV_LOG_ERROR, "broken stream, invalid padding\n"); - return -1; - } - - /* sample or frame count */ - if (get_utf8(gb) < 0) { - av_log(avctx, AV_LOG_ERROR, "utf8 fscked\n"); - return -1; - } - - /* blocksize */ - if (bs_code == 0) { - av_log(avctx, AV_LOG_ERROR, "reserved blocksize code: 0\n"); - return -1; - } else if (bs_code == 6) { - fi->blocksize = get_bits(gb, 8) + 1; - } else if (bs_code == 7) { - fi->blocksize = get_bits(gb, 16) + 1; - } else { - fi->blocksize = ff_flac_blocksize_table[bs_code]; - } - - /* sample rate */ - if (sr_code < 12) { - fi->samplerate = ff_flac_sample_rate_table[sr_code]; - } else if (sr_code == 12) { - fi->samplerate = get_bits(gb, 8) * 1000; - } else if (sr_code == 13) { - fi->samplerate = get_bits(gb, 16); - } else if (sr_code == 14) { - fi->samplerate = get_bits(gb, 16) * 10; - } else { - av_log(avctx, AV_LOG_ERROR, "illegal sample rate code %d\n", - sr_code); - return -1; - } - - /* header CRC-8 check */ - skip_bits(gb, 8); - if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer, - get_bits_count(gb)/8)) { - av_log(avctx, AV_LOG_ERROR, "header crc mismatch\n"); - return -1; - } - - return 0; -} - -static int decode_frame(FLACContext *s) -{ - int i; - GetBitContext *gb = &s->gb; - FLACFrameInfo fi; - - if (decode_frame_header(s->avctx, gb, &fi)) { - av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n"); - return -1; - } - - if (fi.channels != s->channels) { - av_log(s->avctx, AV_LOG_ERROR, "switching channel layout mid-stream " - "is not supported\n"); - return -1; - } - s->ch_mode = fi.ch_mode; - - if (fi.bps && fi.bps != s->bps) { - av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not " - "supported\n"); - return -1; - } - if (s->bps > 16) { - s->avctx->sample_fmt = SAMPLE_FMT_S32; - s->sample_shift = 32 - s->bps; - s->is32 = 1; - } else { - s->avctx->sample_fmt = SAMPLE_FMT_S16; - s->sample_shift = 16 - s->bps; - s->is32 = 0; - } - - if (fi.blocksize > s->max_blocksize) { - av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize, - s->max_blocksize); - return -1; - } - s->blocksize = fi.blocksize; - - if (fi.samplerate == 0) { - fi.samplerate = s->samplerate; - } else if (fi.samplerate != s->samplerate) { - av_log(s->avctx, AV_LOG_WARNING, "sample rate changed from %d to %d\n", - s->samplerate, fi.samplerate); - } - s->samplerate = s->avctx->sample_rate = fi.samplerate; - -// dump_headers(s->avctx, (FLACStreaminfo *)s); - - /* subframes */ - for (i = 0; i < s->channels; i++) { - if (decode_subframe(s, i) < 0) - return -1; - } - - align_get_bits(gb); - - /* frame footer */ - skip_bits(gb, 16); /* data crc */ - - return 0; -} - -static int flac_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - FLACContext *s = avctx->priv_data; - int i, j = 0, input_buf_size = 0, bytes_read = 0; - int16_t *samples_16 = data; - int32_t *samples_32 = data; - int alloc_data_size= *data_size; - int output_size; - - *data_size=0; - - if (s->max_framesize == 0) { - s->max_framesize= FFMAX(4, buf_size); // 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 - if (s->bitstream_size < 4 || AV_RL32(s->bitstream) != MKTAG('f','L','a','C')) - buf_size= FFMIN(buf_size, s->max_framesize - FFMIN(s->bitstream_size, s->max_framesize)); - input_buf_size= buf_size; - - if (s->bitstream_size + buf_size < buf_size || s->bitstream_index + s->bitstream_size + buf_size < s->bitstream_index) - return -1; - - if (s->allocated_bitstream_size < s->bitstream_size + buf_size) - s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->bitstream_size + buf_size); - - if (s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size) { - 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 && input_buf_size) { - return input_buf_size; - } - } - - /* check that there is at least the smallest decodable amount of data. - this amount corresponds to the smallest valid FLAC frame possible. - FF F8 69 02 00 00 9A 00 00 34 46 */ - if (buf_size < 11) - goto end; - - /* check for inline header */ - if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { - if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { - av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); - return -1; - } - bytes_read = get_metadata_size(buf, buf_size); - goto end; - } - - /* check for frame sync code and resync stream if necessary */ - if ((AV_RB16(buf) & 0xFFFE) != 0xFFF8) { - const uint8_t *buf_end = buf + buf_size; - av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); - while (buf+2 < buf_end && (AV_RB16(buf) & 0xFFFE) != 0xFFF8) - buf++; - bytes_read = buf_size - (buf_end - buf); - goto end; // we may not have enough bits left to decode a frame, so try next time - } - - /* decode frame */ - init_get_bits(&s->gb, buf, buf_size*8); - 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; - } - bytes_read = (get_bits_count(&s->gb)+7)/8; - - /* check if allocated data size is large enough for output */ - output_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); - if (output_size > alloc_data_size) { - av_log(s->avctx, AV_LOG_ERROR, "output data size is larger than " - "allocated data size\n"); - goto end; - } - *data_size = output_size; - -#define DECORRELATE(left, right)\ - assert(s->channels == 2);\ - for (i = 0; i < s->blocksize; i++) {\ - int a= s->decoded[0][i];\ - int b= s->decoded[1][i];\ - if (s->is32) {\ - *samples_32++ = (left) << s->sample_shift;\ - *samples_32++ = (right) << s->sample_shift;\ - } else {\ - *samples_16++ = (left) << s->sample_shift;\ - *samples_16++ = (right) << s->sample_shift;\ - }\ - }\ - break; - - switch (s->ch_mode) { - case FLAC_CHMODE_INDEPENDENT: - for (j = 0; j < s->blocksize; j++) { - for (i = 0; i < s->channels; i++) { - if (s->is32) - *samples_32++ = s->decoded[i][j] << s->sample_shift; - else - *samples_16++ = s->decoded[i][j] << s->sample_shift; - } - } - break; - case FLAC_CHMODE_LEFT_SIDE: - DECORRELATE(a,a-b) - case FLAC_CHMODE_RIGHT_SIDE: - DECORRELATE(a+b,b) - case FLAC_CHMODE_MID_SIDE: - DECORRELATE( (a-=b>>1) + b, a) - } - -end: - if (bytes_read > buf_size) { - av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); - s->bitstream_size=0; - s->bitstream_index=0; - return -1; - } - - if (s->bitstream_size) { - s->bitstream_index += bytes_read; - s->bitstream_size -= bytes_read; - return input_buf_size; - } else - return bytes_read; -} - -static av_cold 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", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_FLAC, - sizeof(FLACContext), - flac_decode_init, - NULL, - flac_decode_close, - flac_decode_frame, - CODEC_CAP_DELAY | CODEC_CAP_SUBFRAMES, /* FIXME: add a FLAC parser so that - we will not need to use either - of these capabilities */ - .flush= flac_flush, - .long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/flacenc.c b/tizen/distrib/ffmpeg/libavcodec/flacenc.c deleted file mode 100644 index 89d40d5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flacenc.c +++ /dev/null @@ -1,1266 +0,0 @@ -/** - * FLAC audio encoder - * Copyright (c) 2006 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/crc.h" -#include "libavutil/md5.h" -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "golomb.h" -#include "lpc.h" -#include "flac.h" -#include "flacdata.h" - -#define FLAC_SUBFRAME_CONSTANT 0 -#define FLAC_SUBFRAME_VERBATIM 1 -#define FLAC_SUBFRAME_FIXED 8 -#define FLAC_SUBFRAME_LPC 32 - -#define MAX_FIXED_ORDER 4 -#define MAX_PARTITION_ORDER 8 -#define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER) -#define MAX_LPC_PRECISION 15 -#define MAX_LPC_SHIFT 15 -#define MAX_RICE_PARAM 14 - -typedef struct CompressionOptions { - int compression_level; - int block_time_ms; - int use_lpc; - int lpc_coeff_precision; - int min_prediction_order; - int max_prediction_order; - int prediction_order_method; - int min_partition_order; - int max_partition_order; -} CompressionOptions; - -typedef struct RiceContext { - int porder; - int params[MAX_PARTITIONS]; -} RiceContext; - -typedef struct FlacSubframe { - int type; - int type_code; - int obits; - int order; - int32_t coefs[MAX_LPC_ORDER]; - int shift; - RiceContext rc; - int32_t samples[FLAC_MAX_BLOCKSIZE]; - int32_t residual[FLAC_MAX_BLOCKSIZE+1]; -} FlacSubframe; - -typedef struct FlacFrame { - FlacSubframe subframes[FLAC_MAX_CHANNELS]; - int blocksize; - int bs_code[2]; - uint8_t crc8; - int ch_mode; -} FlacFrame; - -typedef struct FlacEncodeContext { - PutBitContext pb; - int channels; - int samplerate; - int sr_code[2]; - int max_blocksize; - int min_framesize; - int max_framesize; - int max_encoded_framesize; - uint32_t frame_count; - uint64_t sample_count; - uint8_t md5sum[16]; - FlacFrame frame; - CompressionOptions options; - AVCodecContext *avctx; - DSPContext dsp; - struct AVMD5 *md5ctx; -} FlacEncodeContext; - -/** - * Writes streaminfo metadata block to byte array - */ -static void write_streaminfo(FlacEncodeContext *s, uint8_t *header) -{ - PutBitContext pb; - - memset(header, 0, FLAC_STREAMINFO_SIZE); - init_put_bits(&pb, header, FLAC_STREAMINFO_SIZE); - - /* streaminfo metadata block */ - put_bits(&pb, 16, s->max_blocksize); - put_bits(&pb, 16, s->max_blocksize); - put_bits(&pb, 24, s->min_framesize); - put_bits(&pb, 24, s->max_framesize); - put_bits(&pb, 20, s->samplerate); - put_bits(&pb, 3, s->channels-1); - put_bits(&pb, 5, 15); /* bits per sample - 1 */ - /* write 36-bit sample count in 2 put_bits() calls */ - put_bits(&pb, 24, (s->sample_count & 0xFFFFFF000LL) >> 12); - put_bits(&pb, 12, s->sample_count & 0x000000FFFLL); - flush_put_bits(&pb); - memcpy(&header[18], s->md5sum, 16); -} - -/** - * Sets blocksize based on samplerate - * Chooses the closest predefined blocksize >= BLOCK_TIME_MS milliseconds - */ -static int select_blocksize(int samplerate, int block_time_ms) -{ - int i; - int target; - int blocksize; - - assert(samplerate > 0); - blocksize = ff_flac_blocksize_table[1]; - target = (samplerate * block_time_ms) / 1000; - for(i=0; i<16; i++) { - if(target >= ff_flac_blocksize_table[i] && ff_flac_blocksize_table[i] > blocksize) { - blocksize = ff_flac_blocksize_table[i]; - } - } - return blocksize; -} - -static av_cold int flac_encode_init(AVCodecContext *avctx) -{ - int freq = avctx->sample_rate; - int channels = avctx->channels; - FlacEncodeContext *s = avctx->priv_data; - int i, level; - uint8_t *streaminfo; - - s->avctx = avctx; - - dsputil_init(&s->dsp, avctx); - - if(avctx->sample_fmt != SAMPLE_FMT_S16) { - return -1; - } - - if(channels < 1 || channels > FLAC_MAX_CHANNELS) { - return -1; - } - s->channels = channels; - - /* find samplerate in table */ - if(freq < 1) - return -1; - for(i=4; i<12; i++) { - if(freq == ff_flac_sample_rate_table[i]) { - s->samplerate = ff_flac_sample_rate_table[i]; - s->sr_code[0] = i; - s->sr_code[1] = 0; - break; - } - } - /* if not in table, samplerate is non-standard */ - if(i == 12) { - if(freq % 1000 == 0 && freq < 255000) { - s->sr_code[0] = 12; - s->sr_code[1] = freq / 1000; - } else if(freq % 10 == 0 && freq < 655350) { - s->sr_code[0] = 14; - s->sr_code[1] = freq / 10; - } else if(freq < 65535) { - s->sr_code[0] = 13; - s->sr_code[1] = freq; - } else { - return -1; - } - s->samplerate = freq; - } - - /* set compression option defaults based on avctx->compression_level */ - if(avctx->compression_level < 0) { - s->options.compression_level = 5; - } else { - s->options.compression_level = avctx->compression_level; - } - av_log(avctx, AV_LOG_DEBUG, " compression: %d\n", s->options.compression_level); - - level= s->options.compression_level; - if(level > 12) { - av_log(avctx, AV_LOG_ERROR, "invalid compression level: %d\n", - s->options.compression_level); - return -1; - } - - s->options.block_time_ms = ((int[]){ 27, 27, 27,105,105,105,105,105,105,105,105,105,105})[level]; - s->options.use_lpc = ((int[]){ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})[level]; - s->options.min_prediction_order= ((int[]){ 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})[level]; - s->options.max_prediction_order= ((int[]){ 3, 4, 4, 6, 8, 8, 8, 8, 12, 12, 12, 32, 32})[level]; - s->options.prediction_order_method = ((int[]){ ORDER_METHOD_EST, ORDER_METHOD_EST, ORDER_METHOD_EST, - ORDER_METHOD_EST, ORDER_METHOD_EST, ORDER_METHOD_EST, - ORDER_METHOD_4LEVEL, ORDER_METHOD_LOG, ORDER_METHOD_4LEVEL, - ORDER_METHOD_LOG, ORDER_METHOD_SEARCH, ORDER_METHOD_LOG, - ORDER_METHOD_SEARCH})[level]; - s->options.min_partition_order = ((int[]){ 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})[level]; - s->options.max_partition_order = ((int[]){ 2, 2, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8})[level]; - - /* set compression option overrides from AVCodecContext */ - if(avctx->use_lpc >= 0) { - s->options.use_lpc = av_clip(avctx->use_lpc, 0, 11); - } - if(s->options.use_lpc == 1) - av_log(avctx, AV_LOG_DEBUG, " use lpc: Levinson-Durbin recursion with Welch window\n"); - else if(s->options.use_lpc > 1) - av_log(avctx, AV_LOG_DEBUG, " use lpc: Cholesky factorization\n"); - - if(avctx->min_prediction_order >= 0) { - if(s->options.use_lpc) { - if(avctx->min_prediction_order < MIN_LPC_ORDER || - avctx->min_prediction_order > MAX_LPC_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n", - avctx->min_prediction_order); - return -1; - } - } else { - if(avctx->min_prediction_order > MAX_FIXED_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n", - avctx->min_prediction_order); - return -1; - } - } - s->options.min_prediction_order = avctx->min_prediction_order; - } - if(avctx->max_prediction_order >= 0) { - if(s->options.use_lpc) { - if(avctx->max_prediction_order < MIN_LPC_ORDER || - avctx->max_prediction_order > MAX_LPC_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n", - avctx->max_prediction_order); - return -1; - } - } else { - if(avctx->max_prediction_order > MAX_FIXED_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n", - avctx->max_prediction_order); - return -1; - } - } - s->options.max_prediction_order = avctx->max_prediction_order; - } - if(s->options.max_prediction_order < s->options.min_prediction_order) { - av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n", - s->options.min_prediction_order, s->options.max_prediction_order); - return -1; - } - av_log(avctx, AV_LOG_DEBUG, " prediction order: %d, %d\n", - s->options.min_prediction_order, s->options.max_prediction_order); - - if(avctx->prediction_order_method >= 0) { - if(avctx->prediction_order_method > ORDER_METHOD_LOG) { - av_log(avctx, AV_LOG_ERROR, "invalid prediction order method: %d\n", - avctx->prediction_order_method); - return -1; - } - s->options.prediction_order_method = avctx->prediction_order_method; - } - switch(s->options.prediction_order_method) { - case ORDER_METHOD_EST: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", - "estimate"); break; - case ORDER_METHOD_2LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", - "2-level"); break; - case ORDER_METHOD_4LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", - "4-level"); break; - case ORDER_METHOD_8LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", - "8-level"); break; - case ORDER_METHOD_SEARCH: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", - "full search"); break; - case ORDER_METHOD_LOG: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", - "log search"); break; - } - - if(avctx->min_partition_order >= 0) { - if(avctx->min_partition_order > MAX_PARTITION_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid min partition order: %d\n", - avctx->min_partition_order); - return -1; - } - s->options.min_partition_order = avctx->min_partition_order; - } - if(avctx->max_partition_order >= 0) { - if(avctx->max_partition_order > MAX_PARTITION_ORDER) { - av_log(avctx, AV_LOG_ERROR, "invalid max partition order: %d\n", - avctx->max_partition_order); - return -1; - } - s->options.max_partition_order = avctx->max_partition_order; - } - if(s->options.max_partition_order < s->options.min_partition_order) { - av_log(avctx, AV_LOG_ERROR, "invalid partition orders: min=%d max=%d\n", - s->options.min_partition_order, s->options.max_partition_order); - return -1; - } - av_log(avctx, AV_LOG_DEBUG, " partition order: %d, %d\n", - s->options.min_partition_order, s->options.max_partition_order); - - if(avctx->frame_size > 0) { - if(avctx->frame_size < FLAC_MIN_BLOCKSIZE || - avctx->frame_size > FLAC_MAX_BLOCKSIZE) { - av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n", - avctx->frame_size); - return -1; - } - } else { - s->avctx->frame_size = select_blocksize(s->samplerate, s->options.block_time_ms); - } - s->max_blocksize = s->avctx->frame_size; - av_log(avctx, AV_LOG_DEBUG, " block size: %d\n", s->avctx->frame_size); - - /* set LPC precision */ - if(avctx->lpc_coeff_precision > 0) { - if(avctx->lpc_coeff_precision > MAX_LPC_PRECISION) { - av_log(avctx, AV_LOG_ERROR, "invalid lpc coeff precision: %d\n", - avctx->lpc_coeff_precision); - return -1; - } - s->options.lpc_coeff_precision = avctx->lpc_coeff_precision; - } else { - /* default LPC precision */ - s->options.lpc_coeff_precision = 15; - } - av_log(avctx, AV_LOG_DEBUG, " lpc precision: %d\n", - s->options.lpc_coeff_precision); - - /* set maximum encoded frame size in verbatim mode */ - s->max_framesize = ff_flac_get_max_frame_size(s->avctx->frame_size, - s->channels, 16); - - /* initialize MD5 context */ - s->md5ctx = av_malloc(av_md5_size); - if(!s->md5ctx) - return AVERROR(ENOMEM); - av_md5_init(s->md5ctx); - - streaminfo = av_malloc(FLAC_STREAMINFO_SIZE); - write_streaminfo(s, streaminfo); - avctx->extradata = streaminfo; - avctx->extradata_size = FLAC_STREAMINFO_SIZE; - - s->frame_count = 0; - s->min_framesize = s->max_framesize; - - avctx->coded_frame = avcodec_alloc_frame(); - avctx->coded_frame->key_frame = 1; - - return 0; -} - -static void init_frame(FlacEncodeContext *s) -{ - int i, ch; - FlacFrame *frame; - - frame = &s->frame; - - for(i=0; i<16; i++) { - if(s->avctx->frame_size == ff_flac_blocksize_table[i]) { - frame->blocksize = ff_flac_blocksize_table[i]; - frame->bs_code[0] = i; - frame->bs_code[1] = 0; - break; - } - } - if(i == 16) { - frame->blocksize = s->avctx->frame_size; - if(frame->blocksize <= 256) { - frame->bs_code[0] = 6; - frame->bs_code[1] = frame->blocksize-1; - } else { - frame->bs_code[0] = 7; - frame->bs_code[1] = frame->blocksize-1; - } - } - - for(ch=0; chchannels; ch++) { - frame->subframes[ch].obits = 16; - } -} - -/** - * Copy channel-interleaved input samples into separate subframes - */ -static void copy_samples(FlacEncodeContext *s, int16_t *samples) -{ - int i, j, ch; - FlacFrame *frame; - - frame = &s->frame; - for(i=0,j=0; iblocksize; i++) { - for(ch=0; chchannels; ch++,j++) { - frame->subframes[ch].samples[i] = samples[j]; - } - } -} - - -#define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k))) - -/** - * Solve for d/dk(rice_encode_count) = n-((sum-(n>>1))>>(k+1)) = 0 - */ -static int find_optimal_param(uint32_t sum, int n) -{ - int k; - uint32_t sum2; - - if(sum <= n>>1) - return 0; - sum2 = sum-(n>>1); - k = av_log2(n<256 ? FASTDIV(sum2,n) : sum2/n); - return FFMIN(k, MAX_RICE_PARAM); -} - -static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder, - uint32_t *sums, int n, int pred_order) -{ - int i; - int k, cnt, part; - uint32_t all_bits; - - part = (1 << porder); - all_bits = 4 * part; - - cnt = (n >> porder) - pred_order; - for(i=0; iparams[i] = k; - all_bits += rice_encode_count(sums[i], cnt, k); - cnt = n >> porder; - } - - rc->porder = porder; - - return all_bits; -} - -static void calc_sums(int pmin, int pmax, uint32_t *data, int n, int pred_order, - uint32_t sums[][MAX_PARTITIONS]) -{ - int i, j; - int parts; - uint32_t *res, *res_end; - - /* sums for highest level */ - parts = (1 << pmax); - res = &data[pred_order]; - res_end = &data[n >> pmax]; - for(i=0; i> pmax; - } - /* sums for lower levels */ - for(i=pmax-1; i>=pmin; i--) { - parts = (1 << i); - for(j=0; j= 0 && pmin <= MAX_PARTITION_ORDER); - assert(pmax >= 0 && pmax <= MAX_PARTITION_ORDER); - assert(pmin <= pmax); - - udata = av_malloc(n * sizeof(uint32_t)); - for(i=0; i>31); - } - - calc_sums(pmin, pmax, udata, n, pred_order, sums); - - opt_porder = pmin; - bits[pmin] = UINT32_MAX; - for(i=pmin; i<=pmax; i++) { - bits[i] = calc_optimal_rice_params(&tmp_rc, i, sums[i], n, pred_order); - if(bits[i] <= bits[opt_porder]) { - opt_porder = i; - *rc= tmp_rc; - } - } - - av_freep(&udata); - return bits[opt_porder]; -} - -static int get_max_p_order(int max_porder, int n, int order) -{ - int porder = FFMIN(max_porder, av_log2(n^(n-1))); - if(order > 0) - porder = FFMIN(porder, av_log2(n/order)); - return porder; -} - -static uint32_t calc_rice_params_fixed(RiceContext *rc, int pmin, int pmax, - int32_t *data, int n, int pred_order, - int bps) -{ - uint32_t bits; - pmin = get_max_p_order(pmin, n, pred_order); - pmax = get_max_p_order(pmax, n, pred_order); - bits = pred_order*bps + 6; - bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order); - return bits; -} - -static uint32_t calc_rice_params_lpc(RiceContext *rc, int pmin, int pmax, - int32_t *data, int n, int pred_order, - int bps, int precision) -{ - uint32_t bits; - pmin = get_max_p_order(pmin, n, pred_order); - pmax = get_max_p_order(pmax, n, pred_order); - bits = pred_order*bps + 4 + 5 + pred_order*precision + 6; - bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order); - return bits; -} - -static void encode_residual_verbatim(int32_t *res, int32_t *smp, int n) -{ - assert(n > 0); - memcpy(res, smp, n * sizeof(int32_t)); -} - -static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n, - int order) -{ - int i; - - for(i=0; i> shift); - res[i+1] = smp[i+1] - (p1 >> shift); - } -} - -static void encode_residual_lpc(int32_t *res, const int32_t *smp, int n, - int order, const int32_t *coefs, int shift) -{ - int i; - for(i=0; i> shift); - res[i+1] = smp[i+1] - (p1 >> shift); - } -#else - switch(order) { - case 1: encode_residual_lpc_unrolled(res, smp, n, 1, coefs, shift, 0); break; - case 2: encode_residual_lpc_unrolled(res, smp, n, 2, coefs, shift, 0); break; - case 3: encode_residual_lpc_unrolled(res, smp, n, 3, coefs, shift, 0); break; - case 4: encode_residual_lpc_unrolled(res, smp, n, 4, coefs, shift, 0); break; - case 5: encode_residual_lpc_unrolled(res, smp, n, 5, coefs, shift, 0); break; - case 6: encode_residual_lpc_unrolled(res, smp, n, 6, coefs, shift, 0); break; - case 7: encode_residual_lpc_unrolled(res, smp, n, 7, coefs, shift, 0); break; - case 8: encode_residual_lpc_unrolled(res, smp, n, 8, coefs, shift, 0); break; - default: encode_residual_lpc_unrolled(res, smp, n, order, coefs, shift, 1); break; - } -#endif -} - -static int encode_residual(FlacEncodeContext *ctx, int ch) -{ - int i, n; - int min_order, max_order, opt_order, precision, omethod; - int min_porder, max_porder; - FlacFrame *frame; - FlacSubframe *sub; - int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER]; - int shift[MAX_LPC_ORDER]; - int32_t *res, *smp; - - frame = &ctx->frame; - sub = &frame->subframes[ch]; - res = sub->residual; - smp = sub->samples; - n = frame->blocksize; - - /* CONSTANT */ - for(i=1; itype = sub->type_code = FLAC_SUBFRAME_CONSTANT; - res[0] = smp[0]; - return sub->obits; - } - - /* VERBATIM */ - if(n < 5) { - sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; - encode_residual_verbatim(res, smp, n); - return sub->obits * n; - } - - min_order = ctx->options.min_prediction_order; - max_order = ctx->options.max_prediction_order; - min_porder = ctx->options.min_partition_order; - max_porder = ctx->options.max_partition_order; - precision = ctx->options.lpc_coeff_precision; - omethod = ctx->options.prediction_order_method; - - /* FIXED */ - if(!ctx->options.use_lpc || max_order == 0 || (n <= max_order)) { - uint32_t bits[MAX_FIXED_ORDER+1]; - if(max_order > MAX_FIXED_ORDER) max_order = MAX_FIXED_ORDER; - opt_order = 0; - bits[0] = UINT32_MAX; - for(i=min_order; i<=max_order; i++) { - encode_residual_fixed(res, smp, n, i); - bits[i] = calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res, - n, i, sub->obits); - if(bits[i] < bits[opt_order]) { - opt_order = i; - } - } - sub->order = opt_order; - sub->type = FLAC_SUBFRAME_FIXED; - sub->type_code = sub->type | sub->order; - if(sub->order != max_order) { - encode_residual_fixed(res, smp, n, sub->order); - return calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res, n, - sub->order, sub->obits); - } - return bits[sub->order]; - } - - /* LPC */ - opt_order = ff_lpc_calc_coefs(&ctx->dsp, smp, n, min_order, max_order, - precision, coefs, shift, ctx->options.use_lpc, - omethod, MAX_LPC_SHIFT, 0); - - if(omethod == ORDER_METHOD_2LEVEL || - omethod == ORDER_METHOD_4LEVEL || - omethod == ORDER_METHOD_8LEVEL) { - int levels = 1 << omethod; - uint32_t bits[levels]; - int order; - int opt_index = levels-1; - opt_order = max_order-1; - bits[opt_index] = UINT32_MAX; - for(i=levels-1; i>=0; i--) { - order = min_order + (((max_order-min_order+1) * (i+1)) / levels)-1; - if(order < 0) order = 0; - encode_residual_lpc(res, smp, n, order+1, coefs[order], shift[order]); - bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder, - res, n, order+1, sub->obits, precision); - if(bits[i] < bits[opt_index]) { - opt_index = i; - opt_order = order; - } - } - opt_order++; - } else if(omethod == ORDER_METHOD_SEARCH) { - // brute-force optimal order search - uint32_t bits[MAX_LPC_ORDER]; - opt_order = 0; - bits[0] = UINT32_MAX; - for(i=min_order-1; irc, min_porder, max_porder, - res, n, i+1, sub->obits, precision); - if(bits[i] < bits[opt_order]) { - opt_order = i; - } - } - opt_order++; - } else if(omethod == ORDER_METHOD_LOG) { - uint32_t bits[MAX_LPC_ORDER]; - int step; - - opt_order= min_order - 1 + (max_order-min_order)/3; - memset(bits, -1, sizeof(bits)); - - for(step=16 ;step; step>>=1){ - int last= opt_order; - for(i=last-step; i<=last+step; i+= step){ - if(i=max_order || bits[i] < UINT32_MAX) - continue; - encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]); - bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder, - res, n, i+1, sub->obits, precision); - if(bits[i] < bits[opt_order]) - opt_order= i; - } - } - opt_order++; - } - - sub->order = opt_order; - sub->type = FLAC_SUBFRAME_LPC; - sub->type_code = sub->type | (sub->order-1); - sub->shift = shift[sub->order-1]; - for(i=0; iorder; i++) { - sub->coefs[i] = coefs[sub->order-1][i]; - } - encode_residual_lpc(res, smp, n, sub->order, sub->coefs, sub->shift); - return calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n, sub->order, - sub->obits, precision); -} - -static int encode_residual_v(FlacEncodeContext *ctx, int ch) -{ - int i, n; - FlacFrame *frame; - FlacSubframe *sub; - int32_t *res, *smp; - - frame = &ctx->frame; - sub = &frame->subframes[ch]; - res = sub->residual; - smp = sub->samples; - n = frame->blocksize; - - /* CONSTANT */ - for(i=1; itype = sub->type_code = FLAC_SUBFRAME_CONSTANT; - res[0] = smp[0]; - return sub->obits; - } - - /* VERBATIM */ - sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; - encode_residual_verbatim(res, smp, n); - return sub->obits * n; -} - -static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) -{ - int i, best; - int32_t lt, rt; - uint64_t sum[4]; - uint64_t score[4]; - int k; - - /* calculate sum of 2nd order residual for each channel */ - sum[0] = sum[1] = sum[2] = sum[3] = 0; - for(i=2; i> 1); - sum[3] += FFABS(lt - rt); - sum[0] += FFABS(lt); - sum[1] += FFABS(rt); - } - /* estimate bit counts */ - for(i=0; i<4; i++) { - k = find_optimal_param(2*sum[i], n); - sum[i] = rice_encode_count(2*sum[i], n, k); - } - - /* calculate score for each mode */ - score[0] = sum[0] + sum[1]; - score[1] = sum[0] + sum[3]; - score[2] = sum[1] + sum[3]; - score[3] = sum[2] + sum[3]; - - /* return mode with lowest score */ - best = 0; - for(i=1; i<4; i++) { - if(score[i] < score[best]) { - best = i; - } - } - if(best == 0) { - return FLAC_CHMODE_INDEPENDENT; - } else if(best == 1) { - return FLAC_CHMODE_LEFT_SIDE; - } else if(best == 2) { - return FLAC_CHMODE_RIGHT_SIDE; - } else { - return FLAC_CHMODE_MID_SIDE; - } -} - -/** - * Perform stereo channel decorrelation - */ -static void channel_decorrelation(FlacEncodeContext *ctx) -{ - FlacFrame *frame; - int32_t *left, *right; - int i, n; - - frame = &ctx->frame; - n = frame->blocksize; - left = frame->subframes[0].samples; - right = frame->subframes[1].samples; - - if(ctx->channels != 2) { - frame->ch_mode = FLAC_CHMODE_INDEPENDENT; - return; - } - - frame->ch_mode = estimate_stereo_mode(left, right, n); - - /* perform decorrelation and adjust bits-per-sample */ - if(frame->ch_mode == FLAC_CHMODE_INDEPENDENT) { - return; - } - if(frame->ch_mode == FLAC_CHMODE_MID_SIDE) { - int32_t tmp; - for(i=0; i> 1; - right[i] = tmp - right[i]; - } - frame->subframes[1].obits++; - } else if(frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) { - for(i=0; isubframes[1].obits++; - } else { - for(i=0; isubframes[0].obits++; - } -} - -static void write_utf8(PutBitContext *pb, uint32_t val) -{ - uint8_t tmp; - PUT_UTF8(val, tmp, put_bits(pb, 8, tmp);) -} - -static void output_frame_header(FlacEncodeContext *s) -{ - FlacFrame *frame; - int crc; - - frame = &s->frame; - - put_bits(&s->pb, 16, 0xFFF8); - put_bits(&s->pb, 4, frame->bs_code[0]); - put_bits(&s->pb, 4, s->sr_code[0]); - if(frame->ch_mode == FLAC_CHMODE_INDEPENDENT) { - put_bits(&s->pb, 4, s->channels-1); - } else { - put_bits(&s->pb, 4, frame->ch_mode); - } - put_bits(&s->pb, 3, 4); /* bits-per-sample code */ - put_bits(&s->pb, 1, 0); - write_utf8(&s->pb, s->frame_count); - if(frame->bs_code[0] == 6) { - put_bits(&s->pb, 8, frame->bs_code[1]); - } else if(frame->bs_code[0] == 7) { - put_bits(&s->pb, 16, frame->bs_code[1]); - } - if(s->sr_code[0] == 12) { - put_bits(&s->pb, 8, s->sr_code[1]); - } else if(s->sr_code[0] > 12) { - put_bits(&s->pb, 16, s->sr_code[1]); - } - flush_put_bits(&s->pb); - crc = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, - s->pb.buf, put_bits_count(&s->pb)>>3); - put_bits(&s->pb, 8, crc); -} - -static void output_subframe_constant(FlacEncodeContext *s, int ch) -{ - FlacSubframe *sub; - int32_t res; - - sub = &s->frame.subframes[ch]; - res = sub->residual[0]; - put_sbits(&s->pb, sub->obits, res); -} - -static void output_subframe_verbatim(FlacEncodeContext *s, int ch) -{ - int i; - FlacFrame *frame; - FlacSubframe *sub; - int32_t res; - - frame = &s->frame; - sub = &frame->subframes[ch]; - - for(i=0; iblocksize; i++) { - res = sub->residual[i]; - put_sbits(&s->pb, sub->obits, res); - } -} - -static void output_residual(FlacEncodeContext *ctx, int ch) -{ - int i, j, p, n, parts; - int k, porder, psize, res_cnt; - FlacFrame *frame; - FlacSubframe *sub; - int32_t *res; - - frame = &ctx->frame; - sub = &frame->subframes[ch]; - res = sub->residual; - n = frame->blocksize; - - /* rice-encoded block */ - put_bits(&ctx->pb, 2, 0); - - /* partition order */ - porder = sub->rc.porder; - psize = n >> porder; - parts = (1 << porder); - put_bits(&ctx->pb, 4, porder); - res_cnt = psize - sub->order; - - /* residual */ - j = sub->order; - for(p=0; prc.params[p]; - put_bits(&ctx->pb, 4, k); - if(p == 1) res_cnt = psize; - for(i=0; ipb, res[j], k, INT32_MAX, 0); - } - } -} - -static void output_subframe_fixed(FlacEncodeContext *ctx, int ch) -{ - int i; - FlacFrame *frame; - FlacSubframe *sub; - - frame = &ctx->frame; - sub = &frame->subframes[ch]; - - /* warm-up samples */ - for(i=0; iorder; i++) { - put_sbits(&ctx->pb, sub->obits, sub->residual[i]); - } - - /* residual */ - output_residual(ctx, ch); -} - -static void output_subframe_lpc(FlacEncodeContext *ctx, int ch) -{ - int i, cbits; - FlacFrame *frame; - FlacSubframe *sub; - - frame = &ctx->frame; - sub = &frame->subframes[ch]; - - /* warm-up samples */ - for(i=0; iorder; i++) { - put_sbits(&ctx->pb, sub->obits, sub->residual[i]); - } - - /* LPC coefficients */ - cbits = ctx->options.lpc_coeff_precision; - put_bits(&ctx->pb, 4, cbits-1); - put_sbits(&ctx->pb, 5, sub->shift); - for(i=0; iorder; i++) { - put_sbits(&ctx->pb, cbits, sub->coefs[i]); - } - - /* residual */ - output_residual(ctx, ch); -} - -static void output_subframes(FlacEncodeContext *s) -{ - FlacFrame *frame; - FlacSubframe *sub; - int ch; - - frame = &s->frame; - - for(ch=0; chchannels; ch++) { - sub = &frame->subframes[ch]; - - /* subframe header */ - put_bits(&s->pb, 1, 0); - put_bits(&s->pb, 6, sub->type_code); - put_bits(&s->pb, 1, 0); /* no wasted bits */ - - /* subframe */ - if(sub->type == FLAC_SUBFRAME_CONSTANT) { - output_subframe_constant(s, ch); - } else if(sub->type == FLAC_SUBFRAME_VERBATIM) { - output_subframe_verbatim(s, ch); - } else if(sub->type == FLAC_SUBFRAME_FIXED) { - output_subframe_fixed(s, ch); - } else if(sub->type == FLAC_SUBFRAME_LPC) { - output_subframe_lpc(s, ch); - } - } -} - -static void output_frame_footer(FlacEncodeContext *s) -{ - int crc; - flush_put_bits(&s->pb); - crc = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, - s->pb.buf, put_bits_count(&s->pb)>>3)); - put_bits(&s->pb, 16, crc); - flush_put_bits(&s->pb); -} - -static void update_md5_sum(FlacEncodeContext *s, int16_t *samples) -{ -#if HAVE_BIGENDIAN - int i; - for(i = 0; i < s->frame.blocksize*s->channels; i++) { - int16_t smp = le2me_16(samples[i]); - av_md5_update(s->md5ctx, (uint8_t *)&smp, 2); - } -#else - av_md5_update(s->md5ctx, (uint8_t *)samples, s->frame.blocksize*s->channels*2); -#endif -} - -static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, - int buf_size, void *data) -{ - int ch; - FlacEncodeContext *s; - int16_t *samples = data; - int out_bytes; - int reencoded=0; - - s = avctx->priv_data; - - if(buf_size < s->max_framesize*2) { - av_log(avctx, AV_LOG_ERROR, "output buffer too small\n"); - return 0; - } - - /* when the last block is reached, update the header in extradata */ - if (!data) { - s->max_framesize = s->max_encoded_framesize; - av_md5_final(s->md5ctx, s->md5sum); - write_streaminfo(s, avctx->extradata); - return 0; - } - - init_frame(s); - - copy_samples(s, samples); - - channel_decorrelation(s); - - for(ch=0; chchannels; ch++) { - encode_residual(s, ch); - } - -write_frame: - init_put_bits(&s->pb, frame, buf_size); - output_frame_header(s); - output_subframes(s); - output_frame_footer(s); - out_bytes = put_bits_count(&s->pb) >> 3; - - if(out_bytes > s->max_framesize) { - if(reencoded) { - /* still too large. must be an error. */ - av_log(avctx, AV_LOG_ERROR, "error encoding frame\n"); - return -1; - } - - /* frame too large. use verbatim mode */ - for(ch=0; chchannels; ch++) { - encode_residual_v(s, ch); - } - reencoded = 1; - goto write_frame; - } - - s->frame_count++; - s->sample_count += avctx->frame_size; - update_md5_sum(s, samples); - if (out_bytes > s->max_encoded_framesize) - s->max_encoded_framesize = out_bytes; - if (out_bytes < s->min_framesize) - s->min_framesize = out_bytes; - - return out_bytes; -} - -static av_cold int flac_encode_close(AVCodecContext *avctx) -{ - if (avctx->priv_data) { - FlacEncodeContext *s = avctx->priv_data; - av_freep(&s->md5ctx); - } - av_freep(&avctx->extradata); - avctx->extradata_size = 0; - av_freep(&avctx->coded_frame); - return 0; -} - -AVCodec flac_encoder = { - "flac", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_FLAC, - sizeof(FlacEncodeContext), - flac_encode_init, - flac_encode_frame, - flac_encode_close, - NULL, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/flashsv.c b/tizen/distrib/ffmpeg/libavcodec/flashsv.c deleted file mode 100644 index 394ac0f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flashsv.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Flash Screen Video decoder - * Copyright (C) 2004 Alex Beregszaszi - * Copyright (C) 2006 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Flash Screen Video decoder - * @author Alex Beregszaszi - * @author Benjamin Larsson - */ - -/* Bitstream description - * The picture is divided into blocks that are zlib compressed. - * - * The decoder is fed complete frames, the frameheader contains: - * 4bits of block width - * 12bits of frame width - * 4bits of block height - * 12bits of frame height - * - * Directly after the header are the compressed blocks. The blocks - * have their compressed size represented with 16bits in the beginnig. - * If the size = 0 then the block is unchanged from the previous frame. - * All blocks are decompressed until the buffer is consumed. - * - * Encoding ideas, a basic encoder would just use a fixed block size. - * Block sizes can be multipels of 16, from 16 to 256. The blocks don't - * have to be quadratic. A brute force search with a set of diffrent - * block sizes should give a better result then to just use a fixed size. - */ - -#include -#include - -#include "avcodec.h" -#include "get_bits.h" - -#include - -typedef struct FlashSVContext { - AVCodecContext *avctx; - AVFrame frame; - int image_width, image_height; - int block_width, block_height; - uint8_t* tmpblock; - int block_size; - z_stream zstream; -} FlashSVContext; - - -static void copy_region(uint8_t *sptr, uint8_t *dptr, - int dx, int dy, int h, int w, int stride) -{ - int i; - - for (i = dx+h; i > dx; i--) - { - memcpy(dptr+(i*stride)+dy*3, sptr, w*3); - sptr += w*3; - } -} - - -static av_cold int flashsv_decode_init(AVCodecContext *avctx) -{ - FlashSVContext *s = avctx->priv_data; - int zret; // Zlib return code - - s->avctx = avctx; - s->zstream.zalloc = Z_NULL; - s->zstream.zfree = Z_NULL; - s->zstream.opaque = Z_NULL; - zret = inflateInit(&(s->zstream)); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); - return 1; - } - avctx->pix_fmt = PIX_FMT_BGR24; - s->frame.data[0] = NULL; - - return 0; -} - - -static int flashsv_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - FlashSVContext *s = avctx->priv_data; - int h_blocks, v_blocks, h_part, v_part, i, j; - GetBitContext gb; - - /* no supplementary picture */ - if (buf_size == 0) - return 0; - if (buf_size < 4) - return -1; - - init_get_bits(&gb, buf, buf_size * 8); - - /* start to parse the bitstream */ - s->block_width = 16* (get_bits(&gb, 4)+1); - s->image_width = get_bits(&gb,12); - s->block_height= 16* (get_bits(&gb, 4)+1); - s->image_height= get_bits(&gb,12); - - /* calculate amount of blocks and the size of the border blocks */ - h_blocks = s->image_width / s->block_width; - h_part = s->image_width % s->block_width; - v_blocks = s->image_height / s->block_height; - v_part = s->image_height % s->block_height; - - /* the block size could change between frames, make sure the buffer - * is large enough, if not, get a larger one */ - if(s->block_size < s->block_width*s->block_height) { - if (s->tmpblock != NULL) - av_free(s->tmpblock); - if ((s->tmpblock = av_malloc(3*s->block_width*s->block_height)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return -1; - } - } - s->block_size = s->block_width*s->block_height; - - /* init the image size once */ - if((avctx->width==0) && (avctx->height==0)){ - avctx->width = s->image_width; - avctx->height = s->image_height; - } - - /* check for changes of image width and image height */ - if ((avctx->width != s->image_width) || (avctx->height != s->image_height)) { - av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frames!\n"); - av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n",avctx->height, - avctx->width,s->image_height,s->image_width); - return -1; - } - - av_log(avctx, AV_LOG_DEBUG, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n", - s->image_width, s->image_height, s->block_width, s->block_height, - h_blocks, v_blocks, h_part, v_part); - - 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; - } - - /* loop over all block columns */ - for (j = 0; j < v_blocks + (v_part?1:0); j++) - { - - int hp = j*s->block_height; // horiz position in frame - int hs = (jblock_height:v_part; // size of block - - - /* loop over all block rows */ - for (i = 0; i < h_blocks + (h_part?1:0); i++) - { - int wp = i*s->block_width; // vert position in frame - int ws = (iblock_width:h_part; // size of block - - /* get the size of the compressed zlib chunk */ - int size = get_bits(&gb, 16); - if (8 * size > get_bits_left(&gb)) { - avctx->release_buffer(avctx, &s->frame); - s->frame.data[0] = NULL; - return -1; - } - - if (size == 0) { - /* no change, don't do anything */ - } else { - /* decompress block */ - int ret = inflateReset(&(s->zstream)); - if (ret != Z_OK) - { - av_log(avctx, AV_LOG_ERROR, "error in decompression (reset) of block %dx%d\n", i, j); - /* return -1; */ - } - s->zstream.next_in = buf+(get_bits_count(&gb)/8); - s->zstream.avail_in = size; - s->zstream.next_out = s->tmpblock; - s->zstream.avail_out = s->block_size*3; - ret = inflate(&(s->zstream), Z_FINISH); - if (ret == Z_DATA_ERROR) - { - av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n"); - inflateSync(&(s->zstream)); - ret = inflate(&(s->zstream), Z_FINISH); - } - - if ((ret != Z_OK) && (ret != Z_STREAM_END)) - { - av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d: %d\n", i, j, ret); - /* return -1; */ - } - copy_region(s->tmpblock, s->frame.data[0], s->image_height-(hp+hs+1), wp, hs, ws, s->frame.linesize[0]); - skip_bits_long(&gb, 8*size); /* skip the consumed bits */ - } - } - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - if ((get_bits_count(&gb)/8) != buf_size) - av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n", - buf_size, (get_bits_count(&gb)/8)); - - /* report that the buffer was completely consumed */ - return buf_size; -} - - -static av_cold int flashsv_decode_end(AVCodecContext *avctx) -{ - FlashSVContext *s = avctx->priv_data; - inflateEnd(&(s->zstream)); - /* release the frame if needed */ - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - /* free the tmpblock */ - if (s->tmpblock != NULL) - av_free(s->tmpblock); - - return 0; -} - - -AVCodec flashsv_decoder = { - "flashsv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FLASHSV, - sizeof(FlashSVContext), - flashsv_decode_init, - NULL, - flashsv_decode_end, - flashsv_decode_frame, - CODEC_CAP_DR1, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/flashsvenc.c b/tizen/distrib/ffmpeg/libavcodec/flashsvenc.c deleted file mode 100644 index ff917e9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flashsvenc.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Flash Screen Video encoder - * Copyright (C) 2004 Alex Beregszaszi - * Copyright (C) 2006 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Encoding development sponsored by http://fh-campuswien.ac.at */ - -/** - * @file - * Flash Screen Video encoder - * @author Alex Beregszaszi - * @author Benjamin Larsson - */ - -/* Bitstream description - * The picture is divided into blocks that are zlib-compressed. - * - * The decoder is fed complete frames, the frameheader contains: - * 4bits of block width - * 12bits of frame width - * 4bits of block height - * 12bits of frame height - * - * Directly after the header are the compressed blocks. The blocks - * have their compressed size represented with 16bits in the beginig. - * If the size = 0 then the block is unchanged from the previous frame. - * All blocks are decompressed until the buffer is consumed. - * - * Encoding ideas, a basic encoder would just use a fixed block size. - * Block sizes can be multipels of 16, from 16 to 256. The blocks don't - * have to be quadratic. A brute force search with a set of different - * block sizes should give a better result than to just use a fixed size. - */ - -/* TODO: - * Don't reencode the frame in brute force mode if the frame is a dupe. Speed up. - * Make the difference check faster. - */ - -#include -#include -#include - -#include "avcodec.h" -#include "put_bits.h" -#include "bytestream.h" - - -typedef struct FlashSVContext { - AVCodecContext *avctx; - uint8_t *previous_frame; - AVFrame frame; - int image_width, image_height; - int block_width, block_height; - uint8_t* tmpblock; - uint8_t* encbuffer; - int block_size; - z_stream zstream; - int last_key_frame; -} FlashSVContext; - -static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, - int dx, int dy, int h, int w, int stride, uint8_t *pfptr) { - int i,j; - uint8_t *nsptr; - uint8_t *npfptr; - int diff = 0; - - for (i = dx+h; i > dx; i--) { - nsptr = sptr+(i*stride)+dy*3; - npfptr = pfptr+(i*stride)+dy*3; - for (j=0 ; jpriv_data; - - s->avctx = avctx; - - if ((avctx->width > 4095) || (avctx->height > 4095)) { - av_log(avctx, AV_LOG_ERROR, "Input dimensions too large, input must be max 4096x4096 !\n"); - return -1; - } - - // Needed if zlib unused or init aborted before deflateInit - memset(&(s->zstream), 0, sizeof(z_stream)); - - s->last_key_frame=0; - - s->image_width = avctx->width; - s->image_height = avctx->height; - - s->tmpblock = av_mallocz(3*256*256); - s->encbuffer = av_mallocz(s->image_width*s->image_height*3); - - if (!s->tmpblock || !s->encbuffer) { - av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); - return -1; - } - - return 0; -} - - -static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, int buf_size, - int block_width, int block_height, uint8_t *previous_frame, int* I_frame) { - - PutBitContext pb; - int h_blocks, v_blocks, h_part, v_part, i, j; - int buf_pos, res; - int pred_blocks = 0; - - init_put_bits(&pb, buf, buf_size*8); - - put_bits(&pb, 4, (block_width/16)-1); - put_bits(&pb, 12, s->image_width); - put_bits(&pb, 4, (block_height/16)-1); - put_bits(&pb, 12, s->image_height); - flush_put_bits(&pb); - buf_pos=4; - - h_blocks = s->image_width / block_width; - h_part = s->image_width % block_width; - v_blocks = s->image_height / block_height; - v_part = s->image_height % block_height; - - /* loop over all block columns */ - for (j = 0; j < v_blocks + (v_part?1:0); j++) - { - - int hp = j*block_height; // horiz position in frame - int hs = (jdata[0], s->tmpblock, s->image_height-(hp+hs+1), wp, hs, ws, p->linesize[0], previous_frame); - - if (res || *I_frame) { - unsigned long zsize; - zsize = 3*block_width*block_height; - ret = compress2(ptr+2, &zsize, s->tmpblock, 3*ws*hs, 9); - - - //ret = deflateReset(&(s->zstream)); - if (ret != Z_OK) - av_log(s->avctx, AV_LOG_ERROR, "error while compressing block %dx%d\n", i, j); - - bytestream_put_be16(&ptr,(unsigned int)zsize); - buf_pos += zsize+2; - //av_log(avctx, AV_LOG_ERROR, "buf_pos = %d\n", buf_pos); - } else { - pred_blocks++; - bytestream_put_be16(&ptr,0); - buf_pos += 2; - } - } - } - - if (pred_blocks) - *I_frame = 0; - else - *I_frame = 1; - - return buf_pos; -} - - -static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) -{ - FlashSVContext * const s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p = &s->frame; - uint8_t *pfptr; - int res; - int I_frame = 0; - int opt_w, opt_h; - - *p = *pict; - - /* First frame needs to be a keyframe */ - if (avctx->frame_number == 0) { - s->previous_frame = av_mallocz(FFABS(p->linesize[0])*s->image_height); - if (!s->previous_frame) { - av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); - return -1; - } - I_frame = 1; - } - - if (p->linesize[0] < 0) - pfptr = s->previous_frame - ((s->image_height-1) * p->linesize[0]); - else - pfptr = s->previous_frame; - - /* Check the placement of keyframes */ - if (avctx->gop_size > 0) { - if (avctx->frame_number >= s->last_key_frame + avctx->gop_size) { - I_frame = 1; - } - } - - opt_w=4; - opt_h=4; - - if (buf_size < s->image_width*s->image_height*3) { - //Conservative upper bound check for compressed data - av_log(avctx, AV_LOG_ERROR, "buf_size %d < %d\n", buf_size, s->image_width*s->image_height*3); - return -1; - } - - res = encode_bitstream(s, p, buf, buf_size, opt_w*16, opt_h*16, pfptr, &I_frame); - - //save the current frame - if(p->linesize[0] > 0) - memcpy(s->previous_frame, p->data[0], s->image_height*p->linesize[0]); - else - memcpy(s->previous_frame, p->data[0] + p->linesize[0] * (s->image_height-1), s->image_height*FFABS(p->linesize[0])); - - //mark the frame type so the muxer can mux it correctly - if (I_frame) { - p->pict_type = FF_I_TYPE; - p->key_frame = 1; - s->last_key_frame = avctx->frame_number; - av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n",avctx->frame_number); - } else { - p->pict_type = FF_P_TYPE; - p->key_frame = 0; - } - - avctx->coded_frame = p; - - return res; -} - -static av_cold int flashsv_encode_end(AVCodecContext *avctx) -{ - FlashSVContext *s = avctx->priv_data; - - deflateEnd(&(s->zstream)); - - av_free(s->encbuffer); - av_free(s->previous_frame); - av_free(s->tmpblock); - - return 0; -} - -AVCodec flashsv_encoder = { - "flashsv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FLASHSV, - sizeof(FlashSVContext), - flashsv_encode_init, - flashsv_encode_frame, - flashsv_encode_end, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/flicvideo.c b/tizen/distrib/ffmpeg/libavcodec/flicvideo.c deleted file mode 100644 index 429ded5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flicvideo.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - * FLI/FLC Animation Video Decoder - * Copyright (C) 2003, 2004 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 "libavutil/intreadwrite.h" -#include "avcodec.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 av_cold int flic_decode_init(AVCodecContext *avctx) -{ - FlicDecodeContext *s = avctx->priv_data; - unsigned char *fli_header = (unsigned char *)avctx->extradata; - int depth; - - s->avctx = avctx; - - s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */ - - depth = 0; - if (s->avctx->extradata_size == 12) { - /* special case for magic carpet FLIs */ - s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE; - depth = 8; - } else if (s->avctx->extradata_size != 128) { - av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n"); - return -1; - } else { - depth = AV_RL16(&fli_header[12]); - } - - if (depth == 0) { - depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */ - } - - 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, "Unknown 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, - const uint8_t *buf, int buf_size) -{ - FlicDecodeContext *s = 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; - int 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 = AV_RL32(&buf[stream_ptr]); - stream_ptr += 6; /* skip the magic number */ - num_chunks = AV_RL16(&buf[stream_ptr]); - stream_ptr += 10; /* skip padding */ - - frame_size -= 16; - - /* iterate through the chunks */ - while ((frame_size > 0) && (num_chunks > 0)) { - chunk_size = AV_RL32(&buf[stream_ptr]); - stream_ptr += 4; - chunk_type = AV_RL16(&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; - - /* 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 = AV_RL16(&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++) { - unsigned int entry; - - /* 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; - entry = (r << 16) | (g << 8) | b; - if (s->palette[palette_ptr] != entry) - s->new_palette = 1; - s->palette[palette_ptr++] = entry; - } - } - - /* 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 = AV_RL16(&buf[stream_ptr]); - stream_ptr += 2; - while (compressed_lines > 0) { - line_packets = AV_RL16(&buf[stream_ptr]); - stream_ptr += 2; - if ((line_packets & 0xC000) == 0xC000) { - // line skip opcode - line_packets = -line_packets; - y_ptr += line_packets * s->frame.linesize[0]; - } else if ((line_packets & 0xC000) == 0x4000) { - av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); - } else if ((line_packets & 0xC000) == 0x8000) { - // "last byte" opcode - pixels[y_ptr + s->frame.linesize[0] - 1] = line_packets & 0xff; - } 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 = (signed char)(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 = AV_RL16(&buf[stream_ptr]); - stream_ptr += 2; - y_ptr = 0; - y_ptr += starting_line * s->frame.linesize[0]; - - compressed_lines = AV_RL16(&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 = (signed char)(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 if (byte_run < 0) { - 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 = (signed char)(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) at line %d\n", - pixel_countdown, lines); - } - } 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) at line %d\n", - pixel_countdown, lines); - } - } - } - - 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 */ - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); - if (s->new_palette) { - 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, - const 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 = 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; - int 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 = AV_RL32(&buf[stream_ptr]); - stream_ptr += 6; /* skip the magic number */ - num_chunks = AV_RL16(&buf[stream_ptr]); - stream_ptr += 10; /* skip padding */ - - frame_size -= 16; - - /* iterate through the chunks */ - while ((frame_size > 0) && (num_chunks > 0)) { - chunk_size = AV_RL32(&buf[stream_ptr]); - stream_ptr += 4; - chunk_type = AV_RL16(&buf[stream_ptr]); - stream_ptr += 2; - - switch (chunk_type) { - case FLI_256_COLOR: - case FLI_COLOR: - /* For some reason, it seems that non-palettized 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 = AV_RL16(&buf[stream_ptr]); - stream_ptr += 2; - while (compressed_lines > 0) { - line_packets = AV_RL16(&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 = (signed char)(buf[stream_ptr++]); - if (byte_run < 0) { - byte_run = -byte_run; - pixel = AV_RL16(&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])) = AV_RL16(&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 black in both 15Bpp and 16Bpp modes. */ - memset(pixels, 0x0000, - s->frame.linesize[0] * s->avctx->height); - 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 = (signed char)(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) (linea%d)\n", - pixel_countdown, lines); - } - } 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) at line %d\n", - pixel_countdown, lines); - } - } - } - - /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed. - * This does not give us any good oportunity to perform word endian conversion - * during decompression. So if it is required (i.e., this is not a LE target, we do - * a second pass over the line here, swapping the bytes. - */ -#if HAVE_BIGENDIAN - pixel_ptr = y_ptr; - pixel_countdown = s->avctx->width; - while (pixel_countdown > 0) { - *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]); - pixel_ptr += 2; - } -#endif - 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 = (signed char)(buf[stream_ptr++]); - if (byte_run > 0) { - pixel = AV_RL16(&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])) = AV_RL16(&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])) = AV_RL16(&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, - const 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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); - } - - /* Should not 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 FLC format, my science cannot explain how this happened.\n"); - return -1; -} - - -static av_cold 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", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FLIC, - sizeof(FlicDecodeContext), - flic_decode_init, - NULL, - flic_decode_end, - flic_decode_frame, - CODEC_CAP_DR1, - NULL, - NULL, - NULL, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/flv.h b/tizen/distrib/ffmpeg/libavcodec/flv.h deleted file mode 100644 index eb10f22..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flv.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * FLV specific private header. - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_FLV_H -#define AVCODEC_FLV_H - -#include "mpegvideo.h" -#include "get_bits.h" -#include "put_bits.h" - -void ff_flv_encode_picture_header(MpegEncContext * s, int picture_number); -void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run, int last); - -int ff_flv_decode_picture_header(MpegEncContext *s); -void ff_flv2_decode_ac_esc(GetBitContext *gb, int *level, int *run, int *last); - -#endif - diff --git a/tizen/distrib/ffmpeg/libavcodec/flvdec.c b/tizen/distrib/ffmpeg/libavcodec/flvdec.c deleted file mode 100644 index cf9661c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flvdec.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * FLV decoding. - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mpegvideo.h" -#include "h263.h" -#include "flv.h" - -void ff_flv2_decode_ac_esc(GetBitContext *gb, int *level, int *run, int *last){ - int is11 = get_bits1(gb); - *last = get_bits1(gb); - *run = get_bits(gb, 6); - if(is11){ - *level = get_sbits(gb, 11); - } else { - *level = get_sbits(gb, 7); - } -} - -int ff_flv_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 = FF_I_TYPE + get_bits(&s->gb, 2); - s->dropable= s->pict_type > FF_P_TYPE; - if (s->dropable) - s->pict_type = FF_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; -} - -AVCodec flv_decoder = { - "flv", - AVMEDIA_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, - .long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"), - .pix_fmts= ff_pixfmt_list_420, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/flvenc.c b/tizen/distrib/ffmpeg/libavcodec/flvenc.c deleted file mode 100644 index bf320f2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/flvenc.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * FLV Encoding specific code. - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mpegvideo.h" -#include "h263.h" -#include "flv.h" - -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 == FF_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 ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level, int run, int last){ - if(level < 64) { // 7-bit level - put_bits(pb, 1, 0); - put_bits(pb, 1, last); - put_bits(pb, 6, run); - - put_sbits(pb, 7, slevel); - } else { - /* 11-bit level */ - put_bits(pb, 1, 1); - put_bits(pb, 1, last); - put_bits(pb, 6, run); - - put_sbits(pb, 11, slevel); - } -} - -AVCodec flv_encoder = { - "flv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FLV1, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/fraps.c b/tizen/distrib/ffmpeg/libavcodec/fraps.c deleted file mode 100644 index 959ce92..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/fraps.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Fraps FPS1 decoder - * Copyright (c) 2005 Roine Gustafsson - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Lossless Fraps 'FPS1' decoder - * @author Roine Gustafsson - * @author Konstantin Shishkov - * - * Codec algorithm for version 0 is taken from Transcode - * - * Version 2 files support by Konstantin Shishkov - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "huffman.h" -#include "bytestream.h" -#include "dsputil.h" - -#define FPS_TAG MKTAG('F', 'P', 'S', 'x') - -/** - * local variable storage - */ -typedef struct FrapsContext{ - AVCodecContext *avctx; - AVFrame frame; - uint8_t *tmpbuf; - DSPContext dsp; -} FrapsContext; - - -/** - * initializes decoder - * @param avctx codec context - * @return 0 on success or negative if fails - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - FrapsContext * const s = avctx->priv_data; - - avctx->coded_frame = (AVFrame*)&s->frame; - avctx->pix_fmt= PIX_FMT_NONE; /* set in decode_frame */ - - s->avctx = avctx; - s->tmpbuf = NULL; - - dsputil_init(&s->dsp, avctx); - - return 0; -} - -/** - * Comparator - our nodes should ascend by count - * but with preserved symbol order - */ -static int huff_cmp(const void *va, const void *vb){ - const Node *a = va, *b = vb; - return (a->count - b->count)*256 + a->sym - b->sym; -} - -/** - * decode Fraps v2 packed plane - */ -static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, - int h, const uint8_t *src, int size, int Uoff, - const int step) -{ - int i, j; - GetBitContext gb; - VLC vlc; - Node nodes[512]; - - for(i = 0; i < 256; i++) - nodes[i].count = bytestream_get_le32(&src); - size -= 1024; - if (ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp, - FF_HUFFMAN_FLAG_ZERO_COUNT) < 0) - return -1; - /* we have built Huffman table and are ready to decode plane */ - - /* convert bits so they may be used by standard bitreader */ - s->dsp.bswap_buf((uint32_t *)s->tmpbuf, (const uint32_t *)src, size >> 2); - - init_get_bits(&gb, s->tmpbuf, size * 8); - for(j = 0; j < h; j++){ - for(i = 0; i < w*step; i += step){ - dst[i] = get_vlc2(&gb, vlc.table, 9, 3); - /* lines are stored as deltas between previous lines - * and we need to add 0x80 to the first lines of chroma planes - */ - if(j) dst[i] += dst[i - stride]; - else if(Uoff) dst[i] += 0x80; - } - dst += stride; - } - free_vlc(&vlc); - 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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; - const uint32_t *buf32; - uint32_t *luma1,*luma2,*cb,*cr; - uint32_t offs[4]; - int i, j, is_chroma, planes; - - - header = AV_RL32(buf); - version = header & 0xff; - header_size = (header & (1<<30))? 8 : 4; /* bit 30 means pad to 8 bytes */ - - if (version > 5) { - av_log(avctx, AV_LOG_ERROR, - "This file is encoded with Fraps version %d. " \ - "This codec can only decode versions <= 5.\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=(const 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], - 3*avctx->width); - } - break; - - case 2: - case 4: - /** - * Fraps v2 is Huffman-coded YUV420 planes - * Fraps v4 is virtually the same - */ - avctx->pix_fmt = PIX_FMT_YUV420P; - planes = 3; - 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; - } - /* skip frame */ - if(buf_size == 8) { - f->pict_type = FF_P_TYPE; - f->key_frame = 0; - break; - } - f->pict_type = FF_I_TYPE; - f->key_frame = 1; - if ((AV_RL32(buf) != FPS_TAG)||(buf_size < (planes*1024 + 24))) { - av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n"); - return -1; - } - for(i = 0; i < planes; i++) { - offs[i] = AV_RL32(buf + 4 + i * 4); - if(offs[i] >= buf_size || (i && offs[i] <= offs[i - 1] + 1024)) { - av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i); - return -1; - } - } - offs[planes] = buf_size; - for(i = 0; i < planes; i++){ - is_chroma = !!i; - s->tmpbuf = av_realloc(s->tmpbuf, offs[i + 1] - offs[i] - 1024 + FF_INPUT_BUFFER_PADDING_SIZE); - if(fraps2_decode_plane(s, f->data[i], f->linesize[i], avctx->width >> is_chroma, - avctx->height >> is_chroma, buf + offs[i], offs[i + 1] - offs[i], is_chroma, 1) < 0) { - av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i); - return -1; - } - } - break; - case 3: - case 5: - /* Virtually the same as version 4, but is for RGB24 */ - avctx->pix_fmt = PIX_FMT_BGR24; - planes = 3; - 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; - } - /* skip frame */ - if(buf_size == 8) { - f->pict_type = FF_P_TYPE; - f->key_frame = 0; - break; - } - f->pict_type = FF_I_TYPE; - f->key_frame = 1; - if ((AV_RL32(buf) != FPS_TAG)||(buf_size < (planes*1024 + 24))) { - av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n"); - return -1; - } - for(i = 0; i < planes; i++) { - offs[i] = AV_RL32(buf + 4 + i * 4); - if(offs[i] >= buf_size || (i && offs[i] <= offs[i - 1] + 1024)) { - av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i); - return -1; - } - } - offs[planes] = buf_size; - for(i = 0; i < planes; i++){ - s->tmpbuf = av_realloc(s->tmpbuf, offs[i + 1] - offs[i] - 1024 + FF_INPUT_BUFFER_PADDING_SIZE); - if(fraps2_decode_plane(s, f->data[0] + i + (f->linesize[0] * (avctx->height - 1)), -f->linesize[0], - avctx->width, avctx->height, buf + offs[i], offs[i + 1] - offs[i], 0, 3) < 0) { - av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i); - return -1; - } - } - // convert pseudo-YUV into real RGB - for(j = 0; j < avctx->height; j++){ - for(i = 0; i < avctx->width; i++){ - f->data[0][0 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]]; - f->data[0][2 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]]; - } - } - 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 av_cold int decode_end(AVCodecContext *avctx) -{ - FrapsContext *s = (FrapsContext*)avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - av_freep(&s->tmpbuf); - return 0; -} - - -AVCodec fraps_decoder = { - "fraps", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FRAPS, - sizeof(FrapsContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Fraps"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/frwu.c b/tizen/distrib/ffmpeg/libavcodec/frwu.c deleted file mode 100644 index b685248..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/frwu.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Forward Uncompressed - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "libavutil/intreadwrite.h" - -static av_cold int decode_init(AVCodecContext *avctx) -{ - if (avctx->width & 1) { - av_log(avctx, AV_LOG_ERROR, "FRWU needs even width\n"); - return -1; - } - avctx->pix_fmt = PIX_FMT_UYVY422; - - avctx->coded_frame = avcodec_alloc_frame(); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - int field; - AVFrame *pic = avctx->coded_frame; - const uint8_t *buf = avpkt->data; - const uint8_t *buf_end = buf + avpkt->size; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - if (avpkt->size < avctx->width * 2 * avctx->height + 4 + 2*8) { - av_log(avctx, AV_LOG_ERROR, "Packet is too small.\n"); - return -1; - } - if (bytestream_get_le32(&buf) != AV_RL32("FRW1")) { - av_log(avctx, AV_LOG_ERROR, "incorrect marker\n"); - return -1; - } - - pic->reference = 0; - if (avctx->get_buffer(avctx, pic) < 0) - return -1; - - pic->pict_type = FF_I_TYPE; - pic->key_frame = 1; - pic->interlaced_frame = 1; - pic->top_field_first = 1; - - for (field = 0; field < 2; field++) { - int i; - int field_h = (avctx->height + !field) >> 1; - int field_size, min_field_size = avctx->width * 2 * field_h; - uint8_t *dst = pic->data[0]; - if (buf_end - buf < 8) - return -1; - buf += 4; // flags? 0x80 == bottom field maybe? - field_size = bytestream_get_le32(&buf); - if (field_size < min_field_size) { - av_log(avctx, AV_LOG_ERROR, "Field size %i is too small (required %i)\n", field_size, min_field_size); - return -1; - } - if (buf_end - buf < field_size) { - av_log(avctx, AV_LOG_ERROR, "Packet is too small, need %i, have %i\n", field_size, (int)(buf_end - buf)); - return -1; - } - if (field) - dst += pic->linesize[0]; - for (i = 0; i < field_h; i++) { - memcpy(dst, buf, avctx->width * 2); - buf += avctx->width * 2; - dst += pic->linesize[0] << 1; - } - buf += field_size - min_field_size; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = *pic; - - return avpkt->size; -} - -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - -AVCodec frwu_decoder = { - "FRWU", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FRWU, - 0, - decode_init, - NULL, - decode_close, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Forward Uncompressed"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/g726.c b/tizen/distrib/ffmpeg/libavcodec/g726.c deleted file mode 100644 index 5e00511..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/g726.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * 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 file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include "avcodec.h" -#include "get_bits.h" -#include "put_bits.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 { - uint8_t sign; /**< 1bit sign */ - uint8_t exp; /**< 4bit exponent */ - uint8_t mant; /**< 6bit mantissa */ -} Float11; - -static inline Float11* i2f(int 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); - res = exp > 19 ? res << (exp - 19) : res >> (19 - exp); - return (f1->sign ^ f2->sign) ? -res : res; -} - -static inline int sgn(int value) -{ - return (value < 0) ? -1 : 1; -} - -typedef struct G726Tables { - const int* quant; /**< quantization table */ - const int16_t* iquant; /**< inverse quantization table */ - const int16_t* W; /**< special table #1 ;-) */ - const uint8_t* 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 */ - int code_size; -} G726Context; - -static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ - { 260, INT_MAX }; -static const int16_t iquant_tbl16[] = - { 116, 365, 365, 116 }; -static const int16_t W_tbl16[] = - { -22, 439, 439, -22 }; -static const uint8_t F_tbl16[] = - { 0, 7, 7, 0 }; - -static const int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ - { 7, 217, 330, INT_MAX }; -static const int16_t iquant_tbl24[] = - { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN }; -static const int16_t W_tbl24[] = - { -4, 30, 137, 582, 582, 137, 30, -4 }; -static const uint8_t F_tbl24[] = - { 0, 1, 2, 7, 7, 2, 1, 0 }; - -static const int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ - { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; -static const int16_t iquant_tbl32[] = - { INT16_MIN, 4, 135, 213, 273, 323, 373, 425, - 425, 373, 323, 273, 213, 135, 4, INT16_MIN }; -static const int16_t W_tbl32[] = - { -12, 18, 41, 64, 112, 198, 355, 1122, - 1122, 355, 198, 112, 64, 41, 18, -12}; -static const uint8_t F_tbl32[] = - { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; - -static const 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 const int16_t iquant_tbl40[] = - { INT16_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, INT16_MIN }; -static const int16_t 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 const uint8_t 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 const G726Tables G726Tables_pool[] = - {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, - { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, - { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, - { 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->code_size != 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); -} - -static int16_t g726_decode(G726Context* c, int I) -{ - int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0; - Float11 f; - int I_sig= I >> (c->code_size - 1); - - dq = inverse_quant(c, I); - - /* Transition detect */ - ylint = (c->yl >> 15); - ylfrac = (c->yl >> 10) & 0x1f; - thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint; - tr= (c->td == 1 && dq > ((3*thr2)>>2)); - - if (I_sig) /* get the sign */ - dq = -dq; - re_signal = c->se + dq; - - /* 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 = av_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] = av_clip(c->a[1], -12288, 12288); - c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8); - c->a[0] = av_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_sig; /* Isn't it crazy ?!?! */ - - c->td = c->a[1] < -11776; - - /* Update Ap */ - c->dms += (c->tbls.F[I]<<4) + ((- c->dms) >> 5); - c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7); - if (tr) - c->ap = 256; - else { - c->ap += (-c->ap) >> 4; - if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3)) - c->ap += 0x20; - } - - /* Update Yu and Yl */ - c->yu = av_clip(c->y + c->tbls.W[I] + ((-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 av_clip(re_signal << 2, -0xffff, 0xffff); -} - -static av_cold int g726_reset(G726Context* c, int index) -{ - int i; - - c->tbls = G726Tables_pool[index]; - for (i=0; i<2; i++) { - c->sr[i].mant = 1<<5; - c->pk[i] = 1; - } - for (i=0; i<6; i++) { - c->dq[i].mant = 1<<5; - } - c->yu = 544; - c->yl = 34816; - - c->y = 544; - - return 0; -} - -#if CONFIG_ADPCM_G726_ENCODER -static int16_t g726_encode(G726Context* c, int16_t sig) -{ - uint8_t i; - - i = quant(c, sig/4 - c->se) & ((1<code_size) - 1); - g726_decode(c, i); - return i; -} -#endif - -/* Interfacing to the libavcodec */ - -static av_cold int g726_init(AVCodecContext * avctx) -{ - G726Context* c = avctx->priv_data; - unsigned int index; - - if (avctx->sample_rate <= 0) { - av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n"); - return -1; - } - - index = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2; - - if (avctx->bit_rate % avctx->sample_rate && avctx->codec->encode) { - av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n"); - return -1; - } - if(avctx->channels != 1){ - av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); - return -1; - } - if(index>3){ - av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2); - return -1; - } - g726_reset(c, index); - c->code_size = index+2; - - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - avctx->coded_frame->key_frame = 1; - - if (avctx->codec->decode) - avctx->sample_fmt = SAMPLE_FMT_S16; - - return 0; -} - -static av_cold int g726_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - return 0; -} - -#if CONFIG_ADPCM_G726_ENCODER -static int g726_encode_frame(AVCodecContext *avctx, - uint8_t *dst, int buf_size, void *data) -{ - G726Context *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, *samples++)); - - flush_put_bits(&pb); - - return put_bits_count(&pb)>>3; -} -#endif - -static int g726_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - G726Context *c = avctx->priv_data; - short *samples = data; - GetBitContext gb; - - init_get_bits(&gb, buf, buf_size * 8); - - while (get_bits_count(&gb) + c->code_size <= buf_size*8) - *samples++ = g726_decode(c, get_bits(&gb, c->code_size)); - - if(buf_size*8 != get_bits_count(&gb)) - av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n"); - - *data_size = (uint8_t*)samples - (uint8_t*)data; - return buf_size; -} - -#if CONFIG_ADPCM_G726_ENCODER -AVCodec adpcm_g726_encoder = { - "g726", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_ADPCM_G726, - sizeof(G726Context), - g726_init, - g726_encode_frame, - g726_close, - NULL, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), -}; -#endif - -AVCodec adpcm_g726_decoder = { - "g726", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_ADPCM_G726, - sizeof(G726Context), - g726_init, - NULL, - g726_close, - g726_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/g729.h b/tizen/distrib/ffmpeg/libavcodec/g729.h deleted file mode 100644 index 462cf8f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/g729.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * G.729 decoder - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVCODEC_G729_H -#define AVCODEC_G729_H - -/** - * subframe size - */ -#define SUBFRAME_SIZE 40 - -#endif // AVCODEC_G729_H diff --git a/tizen/distrib/ffmpeg/libavcodec/g729data.h b/tizen/distrib/ffmpeg/libavcodec/g729data.h deleted file mode 100644 index 1d64553..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/g729data.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * data for G.729 decoder - * Copyright (c) 2007 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_G729DATA_H -#define AVCODEC_G729DATA_H - -#include - -#define MA_NP 4 ///< Moving Average (MA) prediction order - -#define VQ_1ST_BITS 7 ///< first stage vector of quantizer (size in bits) -#define VQ_2ND_BITS 5 ///< second stage vector of quantizer (size in bits) - -#define GC_1ST_IDX_BITS_8K 3 ///< gain codebook (first stage) index, 8k mode (size in bits) -#define GC_2ND_IDX_BITS_8K 4 ///< gain codebook (second stage) index, 8k mode (size in bits) - -#define GC_1ST_IDX_BITS_6K4 3 ///< gain codebook (first stage) index, 6.4k mode (size in bits) -#define GC_2ND_IDX_BITS_6K4 3 ///< gain codebook (second stage) index, 6.4k mode (size in bits) - -/** - * first stage LSP codebook - * (10-dimensional, with 128 entries (3.24 of G.729) - */ -static const int16_t cb_lsp_1st[1< -#include -#include -#include -#include -#include -#include - -#include "avcodec.h" -#include "libavutil/avutil.h" -#include "get_bits.h" - -#include "g729.h" -#include "lsp.h" -#include "celp_math.h" -#include "acelp_filters.h" -#include "acelp_pitch_delay.h" -#include "acelp_vectors.h" -#include "g729data.h" - -/** - * minimum quantized LSF value (3.2.4) - * 0.005 in Q13 - */ -#define LSFQ_MIN 40 - -/** - * maximum quantized LSF value (3.2.4) - * 3.135 in Q13 - */ -#define LSFQ_MAX 25681 - -/** - * minimum LSF distance (3.2.4) - * 0.0391 in Q13 - */ -#define LSFQ_DIFF_MIN 321 - -/** - * minimum gain pitch value (3.8, Equation 47) - * 0.2 in (1.14) - */ -#define SHARP_MIN 3277 - -/** - * maximum gain pitch value (3.8, Equation 47) - * (EE) This does not comply with the specification. - * Specification says about 0.8, which should be - * 13107 in (1.14), but reference C code uses - * 13017 (equals to 0.7945) instead of it. - */ -#define SHARP_MAX 13017 - -typedef struct { - uint8_t ac_index_bits[2]; ///< adaptive codebook index for second subframe (size in bits) - uint8_t parity_bit; ///< parity bit for pitch delay - uint8_t gc_1st_index_bits; ///< gain codebook (first stage) index (size in bits) - uint8_t gc_2nd_index_bits; ///< gain codebook (second stage) index (size in bits) - uint8_t fc_signs_bits; ///< number of pulses in fixed-codebook vector - uint8_t fc_indexes_bits; ///< size (in bits) of fixed-codebook index entry -} G729FormatDescription; - -typedef struct { - int pitch_delay_int_prev; ///< integer part of previous subframe's pitch delay (4.1.3) - - /// (2.13) LSP quantizer outputs - int16_t past_quantizer_output_buf[MA_NP + 1][10]; - int16_t* past_quantizer_outputs[MA_NP + 1]; - - int16_t lsfq[10]; ///< (2.13) quantized LSF coefficients from previous frame - int16_t lsp_buf[2][10]; ///< (0.15) LSP coefficients (previous and current frames) (3.2.5) - int16_t *lsp[2]; ///< pointers to lsp_buf -} G729Context; - -static const G729FormatDescription format_g729_8k = { - .ac_index_bits = {8,5}, - .parity_bit = 1, - .gc_1st_index_bits = GC_1ST_IDX_BITS_8K, - .gc_2nd_index_bits = GC_2ND_IDX_BITS_8K, - .fc_signs_bits = 4, - .fc_indexes_bits = 13, -}; - -static const G729FormatDescription format_g729d_6k4 = { - .ac_index_bits = {8,4}, - .parity_bit = 0, - .gc_1st_index_bits = GC_1ST_IDX_BITS_6K4, - .gc_2nd_index_bits = GC_2ND_IDX_BITS_6K4, - .fc_signs_bits = 2, - .fc_indexes_bits = 9, -}; - -/** - * \brief pseudo random number generator - */ -static inline uint16_t g729_prng(uint16_t value) -{ - return 31821 * value + 13849; -} - -/** - * Get parity bit of bit 2..7 - */ -static inline int get_parity(uint8_t value) -{ - return (0x6996966996696996ULL >> (value >> 2)) & 1; -} - -static void lsf_decode(int16_t* lsfq, int16_t* past_quantizer_outputs[MA_NP + 1], - int16_t ma_predictor, - int16_t vq_1st, int16_t vq_2nd_low, int16_t vq_2nd_high) -{ - int i,j; - static const uint8_t min_distance[2]={10, 5}; //(2.13) - int16_t* quantizer_output = past_quantizer_outputs[MA_NP]; - - for (i = 0; i < 5; i++) { - quantizer_output[i] = cb_lsp_1st[vq_1st][i ] + cb_lsp_2nd[vq_2nd_low ][i ]; - quantizer_output[i + 5] = cb_lsp_1st[vq_1st][i + 5] + cb_lsp_2nd[vq_2nd_high][i + 5]; - } - - for (j = 0; j < 2; j++) { - for (i = 1; i < 10; i++) { - int diff = (quantizer_output[i - 1] - quantizer_output[i] + min_distance[j]) >> 1; - if (diff > 0) { - quantizer_output[i - 1] -= diff; - quantizer_output[i ] += diff; - } - } - } - - for (i = 0; i < 10; i++) { - int sum = quantizer_output[i] * cb_ma_predictor_sum[ma_predictor][i]; - for (j = 0; j < MA_NP; j++) - sum += past_quantizer_outputs[j][i] * cb_ma_predictor[ma_predictor][j][i]; - - lsfq[i] = sum >> 15; - } - - /* Rotate past_quantizer_outputs. */ - memmove(past_quantizer_outputs + 1, past_quantizer_outputs, MA_NP * sizeof(int16_t*)); - past_quantizer_outputs[0] = quantizer_output; - - ff_acelp_reorder_lsf(lsfq, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX, 10); -} - -static av_cold int decoder_init(AVCodecContext * avctx) -{ - G729Context* ctx = avctx->priv_data; - int i,k; - - if (avctx->channels != 1) { - av_log(avctx, AV_LOG_ERROR, "Only mono sound is supported (requested channels: %d).\n", avctx->channels); - return AVERROR(EINVAL); - } - - /* Both 8kbit/s and 6.4kbit/s modes uses two subframes per frame. */ - avctx->frame_size = SUBFRAME_SIZE << 1; - - for (k = 0; k < MA_NP + 1; k++) { - ctx->past_quantizer_outputs[k] = ctx->past_quantizer_output_buf[k]; - for (i = 1; i < 11; i++) - ctx->past_quantizer_outputs[k][i - 1] = (18717 * i) >> 3; - } - - ctx->lsp[0] = ctx->lsp_buf[0]; - ctx->lsp[1] = ctx->lsp_buf[1]; - memcpy(ctx->lsp[0], lsp_init, 10 * sizeof(int16_t)); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - int16_t *out_frame = data; - GetBitContext gb; - G729FormatDescription format; - int frame_erasure = 0; ///< frame erasure detected during decoding - int bad_pitch = 0; ///< parity check failed - int i; - G729Context *ctx = avctx->priv_data; - int16_t lp[2][11]; // (3.12) - uint8_t ma_predictor; ///< switched MA predictor of LSP quantizer - uint8_t quantizer_1st; ///< first stage vector of quantizer - uint8_t quantizer_2nd_lo; ///< second stage lower vector of quantizer (size in bits) - uint8_t quantizer_2nd_hi; ///< second stage higher vector of quantizer (size in bits) - - int pitch_delay_int; // pitch delay, integer part - int pitch_delay_3x; // pitch delay, multiplied by 3 - - if (*data_size < SUBFRAME_SIZE << 2) { - av_log(avctx, AV_LOG_ERROR, "Error processing packet: output buffer too small\n"); - return AVERROR(EIO); - } - - if (buf_size == 10) { - format = format_g729_8k; - av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729 @ 8kbit/s"); - } else if (buf_size == 8) { - format = format_g729d_6k4; - av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729D @ 6.4kbit/s"); - } else { - av_log(avctx, AV_LOG_ERROR, "Packet size %d is unknown.\n", buf_size); - return AVERROR_INVALIDDATA; - } - - for (i=0; i < buf_size; i++) - frame_erasure |= buf[i]; - frame_erasure = !frame_erasure; - - init_get_bits(&gb, buf, buf_size); - - ma_predictor = get_bits(&gb, 1); - quantizer_1st = get_bits(&gb, VQ_1ST_BITS); - quantizer_2nd_lo = get_bits(&gb, VQ_2ND_BITS); - quantizer_2nd_hi = get_bits(&gb, VQ_2ND_BITS); - - lsf_decode(ctx->lsfq, ctx->past_quantizer_outputs, - ma_predictor, - quantizer_1st, quantizer_2nd_lo, quantizer_2nd_hi); - - ff_acelp_lsf2lsp(ctx->lsp[1], ctx->lsfq, 10); - - ff_acelp_lp_decode(&lp[0][0], &lp[1][0], ctx->lsp[1], ctx->lsp[0], 10); - - FFSWAP(int16_t*, ctx->lsp[1], ctx->lsp[0]); - - for (i = 0; i < 2; i++) { - uint8_t ac_index; ///< adaptive codebook index - uint8_t pulses_signs; ///< fixed-codebook vector pulse signs - int fc_indexes; ///< fixed-codebook indexes - uint8_t gc_1st_index; ///< gain codebook (first stage) index - uint8_t gc_2nd_index; ///< gain codebook (second stage) index - - ac_index = get_bits(&gb, format.ac_index_bits[i]); - if(!i && format.parity_bit) - bad_pitch = get_parity(ac_index) == get_bits1(&gb); - fc_indexes = get_bits(&gb, format.fc_indexes_bits); - pulses_signs = get_bits(&gb, format.fc_signs_bits); - gc_1st_index = get_bits(&gb, format.gc_1st_index_bits); - gc_2nd_index = get_bits(&gb, format.gc_2nd_index_bits); - - if(!i) { - if (bad_pitch) - pitch_delay_3x = 3 * ctx->pitch_delay_int_prev; - else - pitch_delay_3x = ff_acelp_decode_8bit_to_1st_delay3(ac_index); - } else { - int pitch_delay_min = av_clip(ctx->pitch_delay_int_prev - 5, - PITCH_DELAY_MIN, PITCH_DELAY_MAX - 9); - - if(packet_type == FORMAT_G729D_6K4) - pitch_delay_3x = ff_acelp_decode_4bit_to_2nd_delay3(ac_index, pitch_delay_min); - else - pitch_delay_3x = ff_acelp_decode_5_6_bit_to_2nd_delay3(ac_index, pitch_delay_min); - } - - /* Round pitch delay to nearest (used everywhere except ff_acelp_interpolate). */ - pitch_delay_int = (pitch_delay_3x + 1) / 3; - - ff_acelp_weighted_vector_sum(fc + pitch_delay_int, - fc + pitch_delay_int, - fc, 1 << 14, - av_clip(ctx->gain_pitch, SHARP_MIN, SHARP_MAX), - 0, 14, - SUBFRAME_SIZE - pitch_delay_int); - - if (frame_erasure) { - ctx->gain_pitch = (29491 * ctx->gain_pitch) >> 15; // 0.90 (0.15) - ctx->gain_code = ( 2007 * ctx->gain_code ) >> 11; // 0.98 (0.11) - - gain_corr_factor = 0; - } else { - ctx->gain_pitch = cb_gain_1st_8k[gc_1st_index][0] + - cb_gain_2nd_8k[gc_2nd_index][0]; - gain_corr_factor = cb_gain_1st_8k[gc_1st_index][1] + - cb_gain_2nd_8k[gc_2nd_index][1]; - - ff_acelp_weighted_vector_sum(ctx->exc + i * SUBFRAME_SIZE, - ctx->exc + i * SUBFRAME_SIZE, fc, - (!voicing && frame_erasure) ? 0 : ctx->gain_pitch, - ( voicing && frame_erasure) ? 0 : ctx->gain_code, - 1 << 13, 14, SUBFRAME_SIZE); - - ctx->pitch_delay_int_prev = pitch_delay_int; - } - - *data_size = SUBFRAME_SIZE << 2; - return buf_size; -} - -AVCodec g729_decoder = -{ - "g729", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_G729, - sizeof(G729Context), - decoder_init, - NULL, - NULL, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("G.729"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/get_bits.h b/tizen/distrib/ffmpeg/libavcodec/get_bits.h deleted file mode 100644 index 556f542..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/get_bits.h +++ /dev/null @@ -1,691 +0,0 @@ -/* - * copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * bitstream reader API header. - */ - -#ifndef AVCODEC_GET_BITS_H -#define AVCODEC_GET_BITS_H - -#include -#include -#include -#include "libavutil/bswap.h" -#include "libavutil/common.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/log.h" -#include "mathops.h" - -#if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER) -# define ALT_BITSTREAM_READER -#endif - -#if !defined(LIBMPEG2_BITSTREAM_READER) && !defined(A32_BITSTREAM_READER) && !defined(ALT_BITSTREAM_READER) -# if ARCH_ARM && !HAVE_FAST_UNALIGNED -# define A32_BITSTREAM_READER -# else -# define ALT_BITSTREAM_READER -//#define LIBMPEG2_BITSTREAM_READER -//#define A32_BITSTREAM_READER -# endif -#endif - -/* 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; - -/* Bitstream reader API docs: -name - arbitrary 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 LAST_SKIP_CACHE; SKIP_COUNTER - -for examples see get_bits, show_bits, skip_bits, get_vlc -*/ - -#ifdef ALT_BITSTREAM_READER -# define MIN_CACHE_BITS 25 - -# define OPEN_READER(name, gb)\ - unsigned 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= AV_RL32( ((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= AV_RB32( ((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)\ - zero_extend(name##_cache, num) - -# define SHOW_SBITS(name, gb, num)\ - sign_extend(name##_cache, num) -# else -# define SHOW_UBITS(name, gb, num)\ - NEG_USR32(name##_cache, num) - -# define SHOW_SBITS(name, gb, num)\ - NEG_SSR32(name##_cache, num) -# endif - -# define GET_CACHE(name, gb)\ - ((uint32_t)name##_cache) - -static inline int get_bits_count(const GetBitContext *s){ - return s->index; -} - -static inline void skip_bits_long(GetBitContext *s, int n){ - s->index += n; -} - -#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;\ - -# define UPDATE_CACHE(name, gb)\ - if(name##_bit_count >= 0){\ - name##_cache+= AV_RB16(name##_buffer_ptr) << name##_bit_count; \ - name##_buffer_ptr+=2;\ - name##_bit_count-= 16;\ - }\ - -# 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(const GetBitContext *s){ - return (s->buffer_ptr - s->buffer)*8 - 16 + s->bit_count; -} - -static inline void skip_bits_long(GetBitContext *s, int n){ - OPEN_READER(re, s) - re_bit_count += n; - re_buffer_ptr += 2*(re_bit_count>>4); - re_bit_count &= 15; - re_cache = ((re_buffer_ptr[-2]<<8) + re_buffer_ptr[-1]) << (16+re_bit_count); - UPDATE_CACHE(re, s) - CLOSE_READER(re, s) -} - -#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; -} - -static inline void skip_bits_long(GetBitContext *s, int n){ - OPEN_READER(re, s) - re_bit_count += n; - re_buffer_ptr += re_bit_count>>5; - re_bit_count &= 31; - re_cache0 = be2me_32( re_buffer_ptr[-1] ) << re_bit_count; - re_cache1 = 0; - UPDATE_CACHE(re, s) - CLOSE_READER(re, s) -} - -#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 1-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; -} - -/** - * shows 1-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; -} - -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 - unsigned 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); -} - -/** - * reads 0-32 bits. - */ -static inline unsigned int get_bits_long(GetBitContext *s, int n){ - if(n<=MIN_CACHE_BITS) return get_bits(s, n); - else{ -#ifdef ALT_BITSTREAM_READER_LE - int ret= get_bits(s, 16); - return ret | (get_bits(s, n-16) << 16); -#else - int ret= get_bits(s, 16) << (n-16); - return ret | get_bits(s, n-16); -#endif - } -} - -/** - * reads 0-32 bits as a signed integer. - */ -static inline int get_sbits_long(GetBitContext *s, int n) { - return sign_extend(get_bits_long(s, n), n); -} - -/** - * shows 0-32 bits. - */ -static inline unsigned int show_bits_long(GetBitContext *s, int n){ - if(n<=MIN_CACHE_BITS) return show_bits(s, n); - else{ - GetBitContext gb= *s; - return get_bits_long(&gb, n); - } -} - -static inline 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; -} - -/** - * 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 - * - * While GetBitContext stores the buffer size, for performance reasons you are - * responsible for checking for the buffer end yourself (take advantage of the padding)! - */ -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 - s->buffer_ptr = (uint8_t*)((intptr_t)buffer&(~1)); - s->bit_count = 16 + 8*((intptr_t)buffer&1); - skip_bits_long(s, 0); -#elif defined A32_BITSTREAM_READER - s->buffer_ptr = (uint32_t*)((intptr_t)buffer&(~3)); - s->bit_count = 32 + 8*((intptr_t)buffer&3); - skip_bits_long(s, 0); -#endif -} - -static inline void align_get_bits(GetBitContext *s) -{ - int n= (-get_bits_count(s)) & 7; - if(n) skip_bits(s, n); -} - -#define init_vlc(vlc, nb_bits, nb_codes,\ - bits, bits_wrap, bits_size,\ - codes, codes_wrap, codes_size,\ - flags)\ - init_vlc_sparse(vlc, nb_bits, nb_codes,\ - bits, bits_wrap, bits_size,\ - codes, codes_wrap, codes_size,\ - NULL, 0, 0, flags) - -int init_vlc_sparse(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, - const void *symbols, int symbols_wrap, int symbols_size, - int flags); -#define INIT_VLC_LE 2 -#define INIT_VLC_USE_NEW_STATIC 4 -void free_vlc(VLC *vlc); - -#define INIT_VLC_STATIC(vlc, bits, a,b,c,d,e,f,g, static_size)\ -{\ - static VLC_TYPE table[static_size][2];\ - (vlc)->table= table;\ - (vlc)->table_allocated= static_size;\ - init_vlc(vlc, bits, a,b,c,d,e,f,g, INIT_VLC_USE_NEW_STATIC);\ -} - - -/** - * - * If the vlc code is invalid and max_depth=1, then no bits will be removed. - * If the vlc code is invalid and max_depth>1, then the number of bits removed - * is undefined. - */ -#define GET_VLC(code, name, gb, table, bits, max_depth)\ -{\ - int n, nb_bits;\ - unsigned int index;\ -\ - 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, nb_bits;\ - unsigned int index;\ -\ - 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 read to completely - * read the longest vlc code - * = (max_vlc_length + bits - 1) / bits - */ -static av_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 -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(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__) - -#else //TRACE -#define tprintf(p, ...) {} -#endif - -static inline int decode012(GetBitContext *gb){ - int n; - n = get_bits1(gb); - if (n == 0) - return 0; - else - return get_bits1(gb) + 1; -} - -static inline int decode210(GetBitContext *gb){ - if (get_bits1(gb)) - return 0; - else - return 2 - get_bits1(gb); -} - -static inline int get_bits_left(GetBitContext *gb) -{ - return gb->size_in_bits - get_bits_count(gb); -} - -#endif /* AVCODEC_GET_BITS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/gif.c b/tizen/distrib/ffmpeg/libavcodec/gif.c deleted file mode 100644 index 5114b89..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/gif.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * GIF encoder. - * Copyright (c) 2000 Fabrice Bellard - * Copyright (c) 2002 Francois Revol - * Copyright (c) 2006 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * First version by Francois Revol revol@free.fr - * - * Features and limitations: - * - currently no compression is performed, - * in fact the size of the data is 9/8 the size of the image in 8bpp - * - uses only a global standard palette - * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS). - * - * Reference documents: - * http://www.goice.co.jp/member/mo/formats/gif.html - * http://astronomy.swin.edu.au/pbourke/dataformats/gif/ - * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt - * - * this url claims to have an LZW algorithm not covered by Unisys patent: - * http://www.msg.net/utility/whirlgif/gifencod.html - * could help reduce the size of the files _a lot_... - * some sites mentions an RLE type compression also. - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "lzw.h" - -/* The GIF format uses reversed order for bitstreams... */ -/* at least they don't use PDP_ENDIAN :) */ -#define BITSTREAM_WRITER_LE - -#include "put_bits.h" - -typedef struct { - AVFrame picture; - LZWState *lzw; - uint8_t *buf; -} GIFContext; - -/* GIF header */ -static int gif_image_write_header(AVCodecContext *avctx, - uint8_t **bytestream, uint32_t *palette) -{ - int i; - unsigned int v; - - bytestream_put_buffer(bytestream, "GIF", 3); - bytestream_put_buffer(bytestream, "89a", 3); - bytestream_put_le16(bytestream, avctx->width); - bytestream_put_le16(bytestream, avctx->height); - - bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */ - bytestream_put_byte(bytestream, 0x1f); /* background color index */ - bytestream_put_byte(bytestream, 0); /* aspect ratio */ - - /* the global palette */ - for(i=0;i<256;i++) { - v = palette[i]; - bytestream_put_be24(bytestream, v); - } - - return 0; -} - -static int gif_image_write_image(AVCodecContext *avctx, - uint8_t **bytestream, uint8_t *end, - const uint8_t *buf, int linesize) -{ - GIFContext *s = avctx->priv_data; - int len, height; - const uint8_t *ptr; - /* image block */ - - bytestream_put_byte(bytestream, 0x2c); - bytestream_put_le16(bytestream, 0); - bytestream_put_le16(bytestream, 0); - bytestream_put_le16(bytestream, avctx->width); - bytestream_put_le16(bytestream, avctx->height); - bytestream_put_byte(bytestream, 0x00); /* flags */ - /* no local clut */ - - bytestream_put_byte(bytestream, 0x08); - - ff_lzw_encode_init(s->lzw, s->buf, avctx->width*avctx->height, - 12, FF_LZW_GIF, put_bits); - - ptr = buf; - for (height = avctx->height; height--;) { - len += ff_lzw_encode(s->lzw, ptr, avctx->width); - ptr += linesize; - } - len += ff_lzw_encode_flush(s->lzw, flush_put_bits); - - ptr = s->buf; - while (len > 0) { - int size = FFMIN(255, len); - bytestream_put_byte(bytestream, size); - if (end - *bytestream < size) - return -1; - bytestream_put_buffer(bytestream, ptr, size); - ptr += size; - len -= size; - } - bytestream_put_byte(bytestream, 0x00); /* end of image block */ - bytestream_put_byte(bytestream, 0x3b); - return 0; -} - -static av_cold int gif_encode_init(AVCodecContext *avctx) -{ - GIFContext *s = avctx->priv_data; - - avctx->coded_frame = &s->picture; - s->lzw = av_mallocz(ff_lzw_encode_state_size); - if (!s->lzw) - return AVERROR(ENOMEM); - s->buf = av_malloc(avctx->width*avctx->height*2); - if (!s->buf) - return AVERROR(ENOMEM); - return 0; -} - -/* better than nothing gif encoder */ -static int gif_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data) -{ - GIFContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame *const p = (AVFrame *)&s->picture; - uint8_t *outbuf_ptr = outbuf; - uint8_t *end = outbuf + buf_size; - - *p = *pict; - p->pict_type = FF_I_TYPE; - p->key_frame = 1; - gif_image_write_header(avctx, &outbuf_ptr, (uint32_t *)pict->data[1]); - gif_image_write_image(avctx, &outbuf_ptr, end, pict->data[0], pict->linesize[0]); - return outbuf_ptr - outbuf; -} - -static int gif_encode_close(AVCodecContext *avctx) -{ - GIFContext *s = avctx->priv_data; - - av_freep(&s->lzw); - av_freep(&s->buf); - return 0; -} - -AVCodec gif_encoder = { - "gif", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_GIF, - sizeof(GIFContext), - gif_encode_init, - gif_encode_frame, - gif_encode_close, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/gifdec.c b/tizen/distrib/ffmpeg/libavcodec/gifdec.c deleted file mode 100644 index 1daf1b7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/gifdec.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * GIF decoder - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2006 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "bytestream.h" -#include "lzw.h" - -#define GCE_DISPOSAL_NONE 0 -#define GCE_DISPOSAL_INPLACE 1 -#define GCE_DISPOSAL_BACKGROUND 2 -#define GCE_DISPOSAL_RESTORE 3 - -typedef struct GifState { - AVFrame picture; - int screen_width; - int screen_height; - int bits_per_pixel; - int background_color_index; - int transparent_color_index; - int color_resolution; - uint32_t *image_palette; - - /* after the frame is displayed, the disposal method is used */ - int gce_disposal; - /* delay during which the frame is shown */ - int gce_delay; - - /* LZW compatible decoder */ - const uint8_t *bytestream; - const uint8_t *bytestream_end; - LZWState *lzw; - - /* aux buffers */ - uint8_t global_palette[256 * 3]; - uint8_t local_palette[256 * 3]; - - AVCodecContext* avctx; -} GifState; - -static const uint8_t gif87a_sig[6] = "GIF87a"; -static const uint8_t gif89a_sig[6] = "GIF89a"; - -static int gif_read_image(GifState *s) -{ - int left, top, width, height, bits_per_pixel, code_size, flags; - int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i; - uint8_t *ptr, *spal, *palette, *ptr1; - - left = bytestream_get_le16(&s->bytestream); - top = bytestream_get_le16(&s->bytestream); - width = bytestream_get_le16(&s->bytestream); - height = bytestream_get_le16(&s->bytestream); - flags = bytestream_get_byte(&s->bytestream); - is_interleaved = flags & 0x40; - has_local_palette = flags & 0x80; - bits_per_pixel = (flags & 0x07) + 1; -#ifdef DEBUG - dprintf(s->avctx, "gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height); -#endif - - if (has_local_palette) { - bytestream_get_buffer(&s->bytestream, s->local_palette, 3 * (1 << bits_per_pixel)); - palette = s->local_palette; - } else { - palette = s->global_palette; - bits_per_pixel = s->bits_per_pixel; - } - - /* verify that all the image is inside the screen dimensions */ - if (left + width > s->screen_width || - top + height > s->screen_height) - return AVERROR(EINVAL); - - /* build the palette */ - n = (1 << bits_per_pixel); - spal = palette; - for(i = 0; i < n; i++) { - s->image_palette[i] = (0xff << 24) | AV_RB24(spal); - spal += 3; - } - for(; i < 256; i++) - s->image_palette[i] = (0xff << 24); - /* handle transparency */ - if (s->transparent_color_index >= 0) - s->image_palette[s->transparent_color_index] = 0; - - /* now get the image data */ - code_size = bytestream_get_byte(&s->bytestream); - ff_lzw_decode_init(s->lzw, code_size, s->bytestream, - s->bytestream_end - s->bytestream, FF_LZW_GIF); - - /* read all the image */ - linesize = s->picture.linesize[0]; - ptr1 = s->picture.data[0] + top * linesize + left; - ptr = ptr1; - pass = 0; - y1 = 0; - for (y = 0; y < height; y++) { - ff_lzw_decode(s->lzw, ptr, width); - if (is_interleaved) { - switch(pass) { - default: - case 0: - case 1: - y1 += 8; - ptr += linesize * 8; - if (y1 >= height) { - y1 = pass ? 2 : 4; - ptr = ptr1 + linesize * y1; - pass++; - } - break; - case 2: - y1 += 4; - ptr += linesize * 4; - if (y1 >= height) { - y1 = 1; - ptr = ptr1 + linesize; - pass++; - } - break; - case 3: - y1 += 2; - ptr += linesize * 2; - break; - } - } else { - ptr += linesize; - } - } - /* read the garbage data until end marker is found */ - ff_lzw_decode_tail(s->lzw); - s->bytestream = ff_lzw_cur_ptr(s->lzw); - return 0; -} - -static int gif_read_extension(GifState *s) -{ - int ext_code, ext_len, i, gce_flags, gce_transparent_index; - - /* extension */ - ext_code = bytestream_get_byte(&s->bytestream); - ext_len = bytestream_get_byte(&s->bytestream); -#ifdef DEBUG - dprintf(s->avctx, "gif: ext_code=0x%x len=%d\n", ext_code, ext_len); -#endif - switch(ext_code) { - case 0xf9: - if (ext_len != 4) - goto discard_ext; - s->transparent_color_index = -1; - gce_flags = bytestream_get_byte(&s->bytestream); - s->gce_delay = bytestream_get_le16(&s->bytestream); - gce_transparent_index = bytestream_get_byte(&s->bytestream); - if (gce_flags & 0x01) - s->transparent_color_index = gce_transparent_index; - else - s->transparent_color_index = -1; - s->gce_disposal = (gce_flags >> 2) & 0x7; -#ifdef DEBUG - dprintf(s->avctx, "gif: gce_flags=%x delay=%d tcolor=%d disposal=%d\n", - gce_flags, s->gce_delay, - s->transparent_color_index, s->gce_disposal); -#endif - ext_len = bytestream_get_byte(&s->bytestream); - break; - } - - /* NOTE: many extension blocks can come after */ - discard_ext: - while (ext_len != 0) { - for (i = 0; i < ext_len; i++) - bytestream_get_byte(&s->bytestream); - ext_len = bytestream_get_byte(&s->bytestream); -#ifdef DEBUG - dprintf(s->avctx, "gif: ext_len1=%d\n", ext_len); -#endif - } - return 0; -} - -static int gif_read_header1(GifState *s) -{ - uint8_t sig[6]; - int v, n; - int has_global_palette; - - if (s->bytestream_end < s->bytestream + 13) - return -1; - - /* read gif signature */ - bytestream_get_buffer(&s->bytestream, sig, 6); - if (memcmp(sig, gif87a_sig, 6) != 0 && - memcmp(sig, gif89a_sig, 6) != 0) - return -1; - - /* read screen header */ - s->transparent_color_index = -1; - s->screen_width = bytestream_get_le16(&s->bytestream); - s->screen_height = bytestream_get_le16(&s->bytestream); - if( (unsigned)s->screen_width > 32767 - || (unsigned)s->screen_height > 32767){ - av_log(NULL, AV_LOG_ERROR, "picture size too large\n"); - return -1; - } - - v = bytestream_get_byte(&s->bytestream); - s->color_resolution = ((v & 0x70) >> 4) + 1; - has_global_palette = (v & 0x80); - s->bits_per_pixel = (v & 0x07) + 1; - s->background_color_index = bytestream_get_byte(&s->bytestream); - bytestream_get_byte(&s->bytestream); /* ignored */ -#ifdef DEBUG - dprintf(s->avctx, "gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n", - s->screen_width, s->screen_height, s->bits_per_pixel, - has_global_palette); -#endif - if (has_global_palette) { - n = 1 << s->bits_per_pixel; - if (s->bytestream_end < s->bytestream + n * 3) - return -1; - bytestream_get_buffer(&s->bytestream, s->global_palette, n * 3); - } - return 0; -} - -static int gif_parse_next_image(GifState *s) -{ - while (s->bytestream < s->bytestream_end) { - int code = bytestream_get_byte(&s->bytestream); -#ifdef DEBUG - dprintf(s->avctx, "gif: code=%02x '%c'\n", code, code); -#endif - switch (code) { - case ',': - return gif_read_image(s); - case '!': - if (gif_read_extension(s) < 0) - return -1; - break; - case ';': - /* end of image */ - default: - /* error or erroneous EOF */ - return -1; - } - } - return -1; -} - -static av_cold int gif_decode_init(AVCodecContext *avctx) -{ - GifState *s = avctx->priv_data; - - s->avctx = avctx; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - s->picture.data[0] = NULL; - ff_lzw_decode_open(&s->lzw); - return 0; -} - -static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - GifState *s = avctx->priv_data; - AVFrame *picture = data; - int ret; - - s->bytestream = buf; - s->bytestream_end = buf + buf_size; - if (gif_read_header1(s) < 0) - return -1; - - avctx->pix_fmt = PIX_FMT_PAL8; - if (avcodec_check_dimensions(avctx, s->screen_width, s->screen_height)) - return -1; - avcodec_set_dimensions(avctx, s->screen_width, s->screen_height); - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - if (avctx->get_buffer(avctx, &s->picture) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - s->image_palette = (uint32_t *)s->picture.data[1]; - ret = gif_parse_next_image(s); - if (ret < 0) - return ret; - - *picture = s->picture; - *data_size = sizeof(AVPicture); - return s->bytestream - buf; -} - -static av_cold int gif_decode_close(AVCodecContext *avctx) -{ - GifState *s = avctx->priv_data; - - ff_lzw_decode_close(&s->lzw); - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - return 0; -} - -AVCodec gif_decoder = { - "gif", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_GIF, - sizeof(GifState), - gif_decode_init, - NULL, - gif_decode_close, - gif_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/golomb.c b/tizen/distrib/ffmpeg/libavcodec/golomb.c deleted file mode 100644 index 611598c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/golomb.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * exp golomb vlc stuff - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief - * exp golomb vlc stuff - * @author Michael Niedermayer - */ - -#include "libavutil/common.h" - -const uint8_t ff_golomb_vlc_len[512]={ -14,13,12,12,11,11,11,11,10,10,10,10,10,10,10,10,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]={ -31,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,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]={ - 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, -}; - -const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]={ -0, 1, 0, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -4, 5, 2, 2, 6, 7, 3, 3, 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, -8, 9, 4, 4, 10,11,5, 5, 2, 2, 2, 2, 2, 2, 2, 2, -12,13,6, 6, 14,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/tizen/distrib/ffmpeg/libavcodec/golomb.h b/tizen/distrib/ffmpeg/libavcodec/golomb.h deleted file mode 100644 index 90eeb30..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/golomb.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * exp golomb vlc stuff - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2004 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief - * exp golomb vlc stuff - * @author Michael Niedermayer and Alex Beregszaszi - */ - -#ifndef AVCODEC_GOLOMB_H -#define AVCODEC_GOLOMB_H - -#include -#include "get_bits.h" -#include "put_bits.h" - -#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]; -extern const uint8_t ff_interleaved_dirac_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; - } -} - - /** - * read unsigned exp golomb code, constraint to a max of 31. - * the return value is undefined if the stored value exceeds 31. - */ -static inline int get_ue_golomb_31(GetBitContext *gb){ - unsigned int buf; - - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); - - buf >>= 32 - 9; - LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); - CLOSE_READER(re, gb); - - return ff_ue_golomb_vlc_code[buf]; -} - -static inline int svq3_get_ue_golomb(GetBitContext *gb){ - uint32_t buf; - - 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{ - int ret = 1; - - while (1) { - buf >>= 32 - 8; - LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); - - if (ff_interleaved_golomb_vlc_len[buf] != 9){ - ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; - ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; - break; - } - ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; - UPDATE_CACHE(re, gb); - buf = GET_CACHE(re, gb); - } - - CLOSE_READER(re, gb); - return ret - 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; - } -} - -static inline int dirac_get_se_golomb(GetBitContext *gb){ - uint32_t buf; - uint32_t ret; - - ret = svq3_get_ue_golomb(gb); - - if (ret) { - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf = SHOW_SBITS(re, gb, 1); - LAST_SKIP_BITS(re, gb, 1); - ret = (ret ^ buf) - buf; - CLOSE_READER(re, gb); - } - - return ret; -} - -/** - * 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-MIN_CACHE_BITS+(MIN_CACHE_BITS==32) && 32-log < limit){ - 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) { - put_bits(pb, 31, 0); - e -= 31; - } - put_bits(pb, e, 1); - if(k) - put_sbits(pb, k, i); - }else{ - while(limit > 31) { - put_bits(pb, 31, 0); - limit -= 31; - } - put_bits(pb, limit , 1); - put_bits(pb, esc_len, i - 1); - } -} - -/** - * write signed golomb rice code (ffv1). - */ -static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ - int v; - - v = -2*i-1; - v ^= (v>>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); -} - -#endif /* AVCODEC_GOLOMB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h261.c b/tizen/distrib/ffmpeg/libavcodec/h261.c deleted file mode 100644 index 562a151..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h261.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * H261 common code - * Copyright (c) 2002-2004 Michael Niedermayer - * Copyright (c) 2004 Maarten Daniels - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * h261codec. - */ - -#include "dsputil.h" -#include "avcodec.h" -#include "h261.h" - -#define IS_FIL(a) ((a)&MB_TYPE_H261_FIL) - -uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; - -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); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/h261.h b/tizen/distrib/ffmpeg/libavcodec/h261.h deleted file mode 100644 index 5b60dd6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h261.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * H261 decoder - * Copyright (c) 2002-2004 Michael Niedermayer - * Copyright (c) 2004 Maarten Daniels - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * h261codec. - */ - -#ifndef AVCODEC_H261_H -#define AVCODEC_H261_H - -#include "mpegvideo.h" - -/** - * 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; - -#define MB_TYPE_H261_FIL 0x800000 - -#endif /* AVCODEC_H261_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h261_parser.c b/tizen/distrib/ffmpeg/libavcodec/h261_parser.c deleted file mode 100644 index c32300d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h261_parser.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * H261 parser - * Copyright (c) 2002-2004 Michael Niedermayer - * Copyright (c) 2004 Maarten Daniels - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * h261codec. - */ - -#include "parser.h" - - -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)&0xFFFFF0) == 0x000100){ - vop_found=1; - break; - } - } - } - if(vop_found){ - for(; i>j)&0xFFFFF0) == 0x000100){ - pc->frame_start_found=0; - pc->state= (state>>(3*8))+0xFF00; - return i-2; - } - } - } - } - - pc->frame_start_found= vop_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int h261_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const 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, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser h261_parser = { - { CODEC_ID_H261 }, - sizeof(ParseContext), - NULL, - h261_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/h261data.h b/tizen/distrib/ffmpeg/libavcodec/h261data.h deleted file mode 100644 index 82bae16..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h261data.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * copyright (c) 2002-2004 Michael Niedermayer - * copyright (c) 2004 Maarten Daniels - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.261 tables. - */ - -#ifndef AVCODEC_H261DATA_H -#define AVCODEC_H261DATA_H - -#include -#include "h261.h" - -// H.261 VLC table for macroblock addressing -static 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) -}; - -static 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 -static const uint8_t h261_mtype_code[10] = { - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1 -}; - -static 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 -static 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 -static 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 -static 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 -}; - -static 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 -}; - -static 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, -}; - -#endif /* AVCODEC_H261DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h261dec.c b/tizen/distrib/ffmpeg/libavcodec/h261dec.c deleted file mode 100644 index bb5f27d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h261dec.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * H261 decoder - * Copyright (c) 2002-2004 Michael Niedermayer - * Copyright (c) 2004 Maarten Daniels - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.261 decoder. - */ - -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h263.h" -#include "h261.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 - -extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; - -static VLC h261_mba_vlc; -static VLC h261_mtype_vlc; -static VLC h261_mv_vlc; -static VLC h261_cbp_vlc; - -static int h261_decode_block(H261Context * h, DCTELEM * block, int n, int coded); - -static av_cold void h261_decode_init_vlc(H261Context *h){ - static int done = 0; - - if(!done){ - done = 1; - INIT_VLC_STATIC(&h261_mba_vlc, H261_MBA_VLC_BITS, 35, - h261_mba_bits, 1, 1, - h261_mba_code, 1, 1, 662); - INIT_VLC_STATIC(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10, - h261_mtype_bits, 1, 1, - h261_mtype_code, 1, 1, 80); - INIT_VLC_STATIC(&h261_mv_vlc, H261_MV_VLC_BITS, 17, - &h261_mv_tab[0][1], 2, 1, - &h261_mv_tab[0][0], 2, 1, 144); - INIT_VLC_STATIC(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63, - &h261_cbp_tab[0][1], 2, 1, - &h261_cbp_tab[0][0], 2, 1, 512); - init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); - INIT_VLC_RL(h261_rl_tcoeff, 552); - } -} - -static av_cold 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 occurred - */ -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) { - av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n"); - if (s->avctx->error_recognition >= FF_ER_COMPLIANT) - 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, it is not where it is supposed to be ... - s->gb= s->last_resync_gb; - align_get_bits(&s->gb); - left= get_bits_left(&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 occurred - */ -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= get_bits_left(&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 */ - i= get_bits(&s->gb, 5); /* picture timestamp */ - if(i < (s->picture_number&31)) - i += 32; - s->picture_number = (s->picture_number&~31) + i; - - s->avctx->time_base= (AVRational){1001, 30000}; - s->current_picture.pts= s->picture_number; - - - /* 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 FF_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 = FF_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; -} - -/** - * 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 that is 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - H261Context *h= avctx->priv_data; - MpegEncContext *s = &h->s; - int ret; - AVFrame *pict = data; - - dprintf(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); - dprintf(avctx, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); - 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 cannot 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 this demuxing hack to libavformat - 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 == FF_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==FF_B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_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); - - *data_size = sizeof(AVFrame); - - return get_consumed_bytes(s, buf_size); -} - -static av_cold int h261_decode_end(AVCodecContext *avctx) -{ - H261Context *h= avctx->priv_data; - MpegEncContext *s = &h->s; - - MPV_common_end(s); - return 0; -} - -AVCodec h261_decoder = { - "h261", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_H261, - sizeof(H261Context), - h261_decode_init, - NULL, - h261_decode_end, - h261_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("H.261"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/h261enc.c b/tizen/distrib/ffmpeg/libavcodec/h261enc.c deleted file mode 100644 index d3f2219..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h261enc.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * H261 encoder - * Copyright (c) 2002-2004 Michael Niedermayer - * Copyright (c) 2004 Maarten Daniels - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.261 encoder. - */ - -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h263.h" -#include "h261.h" -#include "h261data.h" - -extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; - -static void h261_encode_block(H261Context * h, DCTELEM * block, - int n); - -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; -} - -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 = put_bits_ptr(&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_sbits(&s->pb, 5, temp_ref); /* 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)){ - assert(cbp>0); - 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, ff_h261_rl_table_store); - } - - 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, 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; - 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_sbits(&s->pb, 8, slevel); - } 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 - } -} - -AVCodec h261_encoder = { - "h261", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_H261, - sizeof(H261Context), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("H.261"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/h263.c b/tizen/distrib/ffmpeg/libavcodec/h263.c deleted file mode 100644 index 50ea6ce..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h263.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * 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 file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * h263/mpeg4 codec. - */ - -//#define DEBUG -#include - -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h263.h" -#include "h263data.h" -#include "mathops.h" -#include "unary.h" -#include "flv.h" -#include "mpeg4video.h" - -//#undef NDEBUG -//#include - -uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; - - -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][4*mb_xy ]= - s->current_picture.ref_index[0][4*mb_xy + 1]= s->field_select[0][0]; - s->current_picture.ref_index[0][4*mb_xy + 2]= - s->current_picture.ref_index[0][4*mb_xy + 3]= 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; - } -} - -int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr) -{ - int x, y, wrap, a, c, pred_dc; - 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]; - } else { - x = s->mb_x; - y = s->mb_y; - wrap = s->mb_stride; - dc_val = s->dc_val[n - 4 + 1]; - } - /* 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; - } - /* 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 */ - *dc_val_ptr = &dc_val[x + y * wrap]; - return pred_dc; -} - -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==FF_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_tt, qp_tc; - - if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride])) - qp_tt=0; - else - qp_tt= s->current_picture.qscale_table[xy-s->mb_stride]; - - if(qp_c) - qp_tc= qp_c; - else - qp_tc= qp_tt; - - 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_tt) - s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt); - - if(s->mb_x){ - if(qp_tt || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride])) - qp_dt= qp_tt; - 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); - } - } - } -} - -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; -} - - -/** - * 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; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h263.h b/tizen/distrib/ffmpeg/libavcodec/h263.h deleted file mode 100644 index 678588a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h263.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * H263 internal header - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVCODEC_H263_H -#define AVCODEC_H263_H - -#include -#include "libavutil/rational.h" -#include "get_bits.h" -#include "mpegvideo.h" -#include "rl.h" - -// The defines below define the number of bits that are read at once for -// reading vlc values. Changing these may improve speed and data cache needs -// be aware though that decreasing them may need the number of stages that is -// passed to get_vlc* to be increased. -#define INTRA_MCBPC_VLC_BITS 6 -#define INTER_MCBPC_VLC_BITS 7 -#define CBPY_VLC_BITS 6 -#define TEX_VLC_BITS 9 - -extern const AVRational ff_h263_pixel_aspect[16]; -extern const uint8_t ff_h263_cbpy_tab[16][2]; - -extern const uint8_t cbpc_b_tab[4][2]; - -extern const uint8_t mvtab[33][2]; - -extern const uint8_t ff_h263_intra_MCBPC_code[9]; -extern const uint8_t ff_h263_intra_MCBPC_bits[9]; - -extern const uint8_t ff_h263_inter_MCBPC_code[28]; -extern const uint8_t ff_h263_inter_MCBPC_bits[28]; -extern const uint8_t h263_mbtype_b_tab[15][2]; - -extern VLC ff_h263_intra_MCBPC_vlc; -extern VLC ff_h263_inter_MCBPC_vlc; -extern VLC ff_h263_cbpy_vlc; - -extern RLTable ff_h263_rl_inter; - -extern RLTable rl_intra_aic; - -extern const uint16_t h263_format[8][2]; -extern const uint8_t modified_quant_tab[2][32]; -extern uint16_t ff_mba_max[6]; -extern uint8_t ff_mba_length[7]; - -extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; - - -int h263_decode_motion(MpegEncContext * s, int pred, int f_code); -av_const int ff_h263_aspect_to_info(AVRational aspect); -int ff_h263_decode_init(AVCodecContext *avctx); -int ff_h263_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt); -int ff_h263_decode_end(AVCodecContext *avctx); -void h263_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void h263_encode_picture_header(MpegEncContext *s, int picture_number); -void h263_encode_gob_header(MpegEncContext * s, int mb_line); -int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, - int *px, int *py); -void h263_encode_init(MpegEncContext *s); -void h263_decode_init_vlc(MpegEncContext *s); -int h263_decode_picture_header(MpegEncContext *s); -int ff_h263_decode_gob_header(MpegEncContext *s); -void ff_h263_update_motion_val(MpegEncContext * s); -void ff_h263_loop_filter(MpegEncContext * s); -int ff_h263_decode_mba(MpegEncContext *s); -void ff_h263_encode_mba(MpegEncContext *s); -void ff_init_qscale_tab(MpegEncContext *s); -int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr); -void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n); - - -/** - * Prints picture info if FF_DEBUG_PICT_INFO is set. - */ -void ff_h263_show_pict_info(MpegEncContext *s); - -int ff_intel_h263_decode_picture_header(MpegEncContext *s); -int ff_h263_decode_mb(MpegEncContext *s, - DCTELEM block[6][64]); - -/** - * Returns the value of the 3bit "source format" syntax element. - * that represents some standard picture dimensions or indicates that - * width&height are explicitly stored later. - */ -int av_const h263_get_picture_format(int width, int height); - -void ff_clean_h263_qscales(MpegEncContext *s); -int ff_h263_resync(MpegEncContext *s); -const uint8_t *ff_h263_find_resync_marker(const uint8_t *p, const uint8_t *end); -int ff_h263_get_gob_height(MpegEncContext *s); -void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code); - - -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= ff_h263_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= ff_h263_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; - s->dsp.clear_block(s->block[i]); - } - } - }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; - s->dsp.clear_block(s->block[i]); - } - } - }else{ - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } - } - return cbp; -} - -static inline void memsetw(short *tab, int val, int n) -{ - int i; - for(i=0;i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.263 parser - */ - -#include "parser.h" -#include "h263_parser.h" - -int ff_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, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - next= ff_h263_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser h263_parser = { - { CODEC_ID_H263 }, - sizeof(ParseContext), - NULL, - h263_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/h263_parser.h b/tizen/distrib/ffmpeg/libavcodec/h263_parser.h deleted file mode 100644 index 565a222..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h263_parser.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * H.263 parser - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_H263_PARSER_H -#define AVCODEC_H263_PARSER_H - -#include "parser.h" - -int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); - -#endif /* AVCODEC_H263_PARSER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h263data.h b/tizen/distrib/ffmpeg/libavcodec/h263data.h deleted file mode 100644 index 81e3ddd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h263data.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * copyright (c) 2000,2001 Fabrice Bellard - * H263+ support - * copyright (c) 2001 Juan J. Sierralta P - * copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.263 tables. - */ - -#ifndef AVCODEC_H263DATA_H -#define AVCODEC_H263DATA_H - -#include -#include "mpegvideo.h" - -/* intra MCBPC, mb_type = (intra), then (intraq) */ -const uint8_t ff_h263_intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 }; -const uint8_t ff_h263_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 ff_h263_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 ff_h263_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*/ -}; - -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}, -}; - -const uint8_t cbpc_b_tab[4][2] = { -{0, 1}, -{2, 2}, -{7, 3}, -{6, 3}, -}; - -const uint8_t ff_h263_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, -}; - -RLTable ff_h263_rl_inter = { - 102, - 58, - inter_vlc, - inter_run, - inter_level, -}; - -static 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 }, -}; - -static 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, -}; - -static 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, -}; - -RLTable rl_intra_aic = { - 102, - 58, - intra_vlc_aic, - intra_run_aic, - intra_level_aic, -}; - -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 -}; - -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 -}; - -uint16_t ff_mba_max[6]={ - 47, 98, 395,1583,6335,9215 -}; - -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 -}; - -const AVRational ff_h263_pixel_aspect[16]={ - {0, 1}, - {1, 1}, - {12, 11}, - {10, 11}, - {16, 11}, - {40, 33}, - {0, 1}, - {0, 1}, - {0, 1}, - {0, 1}, - {0, 1}, - {0, 1}, - {0, 1}, - {0, 1}, - {0, 1}, - {0, 1}, -}; - -#endif /* AVCODEC_H263DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h263dec.c b/tizen/distrib/ffmpeg/libavcodec/h263dec.c deleted file mode 100644 index c80cfcf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h263dec.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * H.263 decoder - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.263 decoder. - */ - -#include "internal.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "h263.h" -#include "h263_parser.h" -#include "mpeg4video_parser.h" -#include "msmpeg4.h" -#include "vdpau_internal.h" -#include "flv.h" -#include "mpeg4video.h" - -//#define DEBUG -//#define PRINT_FRAME_TIME - -av_cold 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= avctx->get_format(avctx, avctx->codec->pix_fmts); - s->unrestricted_mv= 1; - - /* select sub codec */ - switch(avctx->codec->id) { - case CODEC_ID_H263: - s->unrestricted_mv= 0; - avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; - break; - case CODEC_ID_MPEG4: - 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_VC1: - case CODEC_ID_WMV3: - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->msmpeg4_version=6; - avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; - break; - case CODEC_ID_H263I: - break; - case CODEC_ID_FLV1: - s->h263_flv = 1; - break; - default: - return -1; - } - s->codec_id= avctx->codec->id; - avctx->hwaccel= ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); - - /* 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; - - h263_decode_init_vlc(s); - - return 0; -} - -av_cold 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 || s->avctx->hwaccel){ - //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 that is 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->avctx->hwaccel) { - const uint8_t *start= s->gb.buffer + get_bits_count(&s->gb)/8; - const uint8_t *end = ff_h263_find_resync_marker(start + 1, s->gb.buffer_end); - skip_bits_long(&s->gb, 8*(end - start)); - return s->avctx->hwaccel->decode_slice(s->avctx, start, end - start); - } - - if(s->partitioned_frame){ - const int qscale= s->qscale; - - if(CONFIG_MPEG4_DECODER && 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!=FF_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) - && get_bits_left(&s->gb) >=0 - && get_bits_left(&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>=0 || !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= get_bits_left(&s->gb); - int max_extra=7; - - /* no markers in M$ crap */ - if(s->msmpeg4_version && s->pict_type==FF_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_recognition>=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", - get_bits_left(&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; -} - -int ff_h263_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MpegEncContext *s = avctx->priv_data; - int ret; - AVFrame *pict = data; - -#ifdef PRINT_FRAME_TIME -uint64_t time= rdtsc(); -#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(CONFIG_MPEG4_DECODER && s->codec_id==CODEC_ID_MPEG4){ - next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size); - }else if(CONFIG_H263_DECODER && s->codec_id==CODEC_ID_H263){ - next= ff_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, (const uint8_t **)&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 cannot store anyting in 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 (CONFIG_WMV2_DECODER && s->msmpeg4_version==5) { - ret= ff_wmv2_decode_picture_header(s); - } else if (CONFIG_MSMPEG4_DECODER && s->msmpeg4_version) { - ret = msmpeg4_decode_picture_header(s); - } else if (CONFIG_MPEG4_DECODER && 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); - } else if (CONFIG_H263I_DECODER && s->codec_id == CODEC_ID_H263I) { - ret = ff_intel_h263_decode_picture_header(s); - } else if (CONFIG_FLV_DECODER && s->h263_flv) { - ret = ff_flv_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==-1 && s->divx_version==-1 && s->lavc_build==-1){ - if(s->stream_codec_tag == AV_RL32("XVID") || - s->codec_tag == AV_RL32("XVID") || s->codec_tag == AV_RL32("XVIX") || - s->codec_tag == AV_RL32("RMP4") || - s->codec_tag == AV_RL32("SIPP") - ) - s->xvid_build= 0; -#if 0 - if(s->codec_tag == AV_RL32("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= 0; -#endif - } - - if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){ - if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==0) - s->divx_version= 400; //divx 4 - } - - if(s->xvid_build>=0 && s->divx_version>=0){ - s->divx_version= - s->divx_build= -1; - } - - if(s->workaround_bugs&FF_BUG_AUTODETECT){ - if(s->codec_tag == AV_RL32("XVIX")) - s->workaround_bugs|= FF_BUG_XVID_ILACE; - - if(s->codec_tag == AV_RL32("UMP4")){ - s->workaround_bugs|= FF_BUG_UMP4; - } - - if(s->divx_version>=500 && s->divx_build<1814){ - s->workaround_bugs|= FF_BUG_QPEL_CHROMA; - } - - if(s->divx_version>502 && s->divx_build<1814){ - s->workaround_bugs|= FF_BUG_QPEL_CHROMA2; - } - - if(s->xvid_build<=3U) - s->padding_bug_score= 256*256*256*64; - - if(s->xvid_build<=1U) - s->workaround_bugs|= FF_BUG_QPEL_CHROMA; - - if(s->xvid_build<=12U) - s->workaround_bugs|= FF_BUG_EDGE; - - if(s->xvid_build<=32U) - 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<4653U) - s->workaround_bugs|= FF_BUG_STD_QPEL; - - if(s->lavc_build<4655U) - s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE; - - if(s->lavc_build<4670U){ - s->workaround_bugs|= FF_BUG_EDGE; - } - - if(s->lavc_build<=4712U) - s->workaround_bugs|= FF_BUG_DC_CLIP; - - if(s->divx_version>=0) - 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<500U){ - s->workaround_bugs|= FF_BUG_EDGE; - } - - if(s->divx_version>=0) - 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 - * Let us hope this at least works. - */ - if( s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==-1 - && s->codec_id==CODEC_ID_MPEG4 && s->vo_type==0) - s->workaround_bugs|= FF_BUG_NO_PADDING; - - if(s->lavc_build<4609U) //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 HAVE_MMX - if(s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (mm_flags & FF_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->codec_id == CODEC_ID_H263I)) - 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 == FF_I_TYPE; - - /* skip B-frames if we don't have reference frames */ - if(s->last_picture_ptr==NULL && (s->pict_type==FF_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==FF_B_TYPE) return get_consumed_bytes(s, buf_size); - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE) - || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_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==FF_B_TYPE) - return get_consumed_bytes(s, buf_size); - else - s->next_p_frame_damaged=0; - } - - if((s->avctx->flags2 & CODEC_FLAG2_FAST) && s->pict_type==FF_B_TYPE){ - s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab; - }else if((!s->no_rounding) || s->pict_type==FF_B_TYPE){ - s->me.qpel_put= s->dsp.put_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; - }else{ - s->me.qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; - } - - if(MPV_frame_start(s, avctx) < 0) - return -1; - - if (CONFIG_MPEG4_VDPAU_DECODER && (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) { - ff_vdpau_mpeg4_decode_picture(s, s->gb.buffer, s->gb.buffer_end - s->gb.buffer); - goto frame_end; - } - - if (avctx->hwaccel) { - if (avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer) < 0) - return -1; - } - - 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 is not available before MPV_frame_start() - if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5){ - ret = ff_wmv2_decode_secondary_picture_header(s); - if(ret<0) return ret; - if(ret==1) goto intrax8_decoded; - } - - /* 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->slice_height==0 || 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==FF_I_TYPE) - if(!CONFIG_MSMPEG4_DECODER || msmpeg4_decode_ext_header(s, buf_size) < 0){ - s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR; - } - - assert(s->bitstream_buffer_size==0); -frame_end: - /* divx 5.01+ bistream reorder stuff */ - if(s->codec_id==CODEC_ID_MPEG4 && 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>7 && s->xvid_build>=0){ //xvid style - startcode_found=1; - current_pos=0; - } - - if(startcode_found){ - av_fast_malloc( - &s->bitstream_buffer, - &s->allocated_bitstream_buffer_size, - buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE); - if (!s->bitstream_buffer) - return AVERROR(ENOMEM); - memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos); - s->bitstream_buffer_size= buf_size - current_pos; - } - } - -intrax8_decoded: - ff_er_frame_end(s); - - if (avctx->hwaccel) { - if (avctx->hwaccel->end_frame(avctx) < 0) - return -1; - } - - 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 == FF_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); - } - -#ifdef PRINT_FRAME_TIME -av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time); -#endif - - return get_consumed_bytes(s, buf_size); -} - -AVCodec h263_decoder = { - "h263", - AVMEDIA_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, - .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"), - .pix_fmts= ff_hwaccel_pixfmt_list_420, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/h264.c b/tizen/distrib/ffmpeg/libavcodec/h264.c deleted file mode 100644 index e4654f0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264.c +++ /dev/null @@ -1,3392 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 codec. - * @author Michael Niedermayer - */ - -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h264.h" -#include "h264data.h" -#include "h264_mvpred.h" -#include "h264_parser.h" -#include "golomb.h" -#include "mathops.h" -#include "rectangle.h" -#include "vdpau_internal.h" - -#include "cabac.h" - -//#undef NDEBUG -#include - -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, -}; - -void ff_h264_write_back_intra_pred_mode(H264Context *h){ - int8_t *mode= h->intra4x4_pred_mode + h->mb2br_xy[h->mb_xy]; - - AV_COPY32(mode, h->intra4x4_pred_mode_cache + 4 + 8*4); - mode[4]= h->intra4x4_pred_mode_cache[7+8*3]; - mode[5]= h->intra4x4_pred_mode_cache[7+8*2]; - mode[6]= h->intra4x4_pred_mode_cache[7+8*1]; -} - -/** - * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. - */ -int ff_h264_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&0x8888)!=0x8888){ - static const int mask[4]={0x8000,0x2000,0x80,0x20}; - for(i=0; i<4; i++){ - if(!(h->left_samples_available&mask[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 ff_h264_check_intra_pred_mode - -/** - * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. - */ -int ff_h264_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 > 6U) { - 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&0x8080) != 0x8080){ - mode= left[ mode ]; - if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred - mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8); - } - 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; -} - -const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){ - int i, si, di; - uint8_t *dst; - int bufidx; - -// 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]) i--; - while(src[i]) i++; -#else -# define RS 0 - for(i=0; i+10 && src[i-1]==0) i--; -#endif - if(i+2=length-1){ //no escaped 0 - *dst_length= length; - *consumed= length+1; //+1 for the header - return src; - } - - bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data - av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE); - dst= h->rbsp_buffer[bufidx]; - - if (dst == NULL){ - return NULL; - } - -//printf("decoding esc\n"); - memcpy(dst, src, i); - si=di=i; - while(si+23){ - dst[di++]= src[si++]; - dst[di++]= src[si++]; - }else if(src[si]==0 && src[si+1]==0){ - if(src[si+2]==3){ //escape - dst[di++]= 0; - dst[di++]= 0; - si+=3; - continue; - }else //next start code - goto nsc; - } - - dst[di++]= src[si++]; - } - while(sis.avctx, "rbsp trailing %X\n", v); - - for(r=1; r<9; r++){ - if(v&1) return r; - v>>=1; - } - return 0; -} - -/** - * IDCT transforms the 16 dc values and dequantizes 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_residual - 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 transforms 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 - -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; - 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)*h->mb_linesize; - uint8_t * src_cb, * src_cr; - int extra_width= h->emu_edge_width; - int extra_height= h->emu_edge_height; - 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 >> MB_FIELD; - - 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*h->mb_linesize, h->mb_linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height); - src_y= s->edge_emu_buffer + 2 + 2*h->mb_linesize; - emu=1; - } - - qpix_op[luma_xy](dest_y, src_y, h->mb_linesize); //FIXME try variable height perhaps? - if(!square){ - qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize); - } - - if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return; - - if(MB_FIELD){ - // chroma offset when predicting from a field of opposite parity - my += 2 * ((s->mb_y & 1) - (pic->reference - 1)); - emu |= (my>>3) < 0 || (my>>3) + 8 >= (pic_height>>1); - } - src_cb= pic->data[1] + (mx>>3) + (my>>3)*h->mb_uvlinesize; - src_cr= pic->data[2] + (mx>>3) + (my>>3)*h->mb_uvlinesize; - - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, h->mb_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, h->mb_uvlinesize, chroma_height, mx&7, my&7); - - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, h->mb_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, h->mb_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*h-> mb_linesize; - dest_cb += x_offset + y_offset*h->mb_uvlinesize; - dest_cr += x_offset + y_offset*h->mb_uvlinesize; - x_offset += 8*s->mb_x; - y_offset += 8*(s->mb_y >> MB_FIELD); - - 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*h-> mb_linesize; - dest_cb += x_offset + y_offset*h->mb_uvlinesize; - dest_cr += x_offset + y_offset*h->mb_uvlinesize; - x_offset += 8*s->mb_x; - y_offset += 8*(s->mb_y >> MB_FIELD); - - 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 = s->obmc_scratchpad + 8; - uint8_t *tmp_y = s->obmc_scratchpad + 8*h->mb_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][s->mb_y&1]; - int weight1 = 64 - weight0; - luma_weight_avg( dest_y, tmp_y, h-> mb_linesize, 5, weight0, weight1, 0); - chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, 5, weight0, weight1, 0); - chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, 5, weight0, weight1, 0); - }else{ - luma_weight_avg(dest_y, tmp_y, h->mb_linesize, h->luma_log2_weight_denom, - h->luma_weight[refn0][0][0] , h->luma_weight[refn1][1][0], - h->luma_weight[refn0][0][1] + h->luma_weight[refn1][1][1]); - chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, h->chroma_log2_weight_denom, - h->chroma_weight[refn0][0][0][0] , h->chroma_weight[refn1][1][0][0], - h->chroma_weight[refn0][0][0][1] + h->chroma_weight[refn1][1][0][1]); - chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, h->chroma_log2_weight_denom, - h->chroma_weight[refn0][0][1][0] , h->chroma_weight[refn1][1][1][0], - h->chroma_weight[refn0][0][1][1] + h->chroma_weight[refn1][1][1][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, h->mb_linesize, h->luma_log2_weight_denom, - h->luma_weight[refn][list][0], h->luma_weight[refn][list][1]); - if(h->use_weight_chroma){ - chroma_weight_op(dest_cb, h->mb_uvlinesize, h->chroma_log2_weight_denom, - h->chroma_weight[refn][list][0][0], h->chroma_weight[refn][list][0][1]); - chroma_weight_op(dest_cr, h->mb_uvlinesize, h->chroma_log2_weight_denom, - h->chroma_weight[refn][list][1][0], h->chroma_weight[refn][list][1][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]] ][h->s.mb_y&1] != 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)*h->mb_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= h->mb_xy; - 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, weight_avg, - 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*h->mb_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*h->mb_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*h->mb_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*h->mb_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 free_tables(H264Context *h){ - int i; - H264Context *hx; - 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); - h->slice_table= NULL; - av_freep(&h->list_counts); - - av_freep(&h->mb2b_xy); - av_freep(&h->mb2br_xy); - - for(i = 0; i < MAX_THREADS; i++) { - hx = h->thread_context[i]; - if(!hx) continue; - av_freep(&hx->top_borders[1]); - av_freep(&hx->top_borders[0]); - av_freep(&hx->s.obmc_scratchpad); - av_freep(&hx->rbsp_buffer[1]); - av_freep(&hx->rbsp_buffer[0]); - hx->rbsp_buffer_size[0] = 0; - hx->rbsp_buffer_size[1] = 0; - if (i) av_freep(&h->thread_context[i]); - } -} - -static void init_dequant8_coeff_table(H264Context *h){ - int i,q,x; - const int transpose = (h->h264dsp.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->h264dsp.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; - } -} - - -int ff_h264_alloc_tables(H264Context *h){ - MpegEncContext * const s = &h->s; - const int big_mb_num= s->mb_stride * (s->mb_height+1); - const int row_mb_num= 2*s->mb_stride*s->avctx->thread_count; - int x,y; - - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode, row_mb_num * 8 * sizeof(uint8_t), fail) - - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count , big_mb_num * 32 * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base), fail) - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table, big_mb_num * sizeof(uint16_t), fail) - - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0], 16*row_mb_num * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1], 16*row_mb_num * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table, 4*big_mb_num * sizeof(uint8_t) , fail); - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->list_counts, big_mb_num * sizeof(uint8_t), fail) - - memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base)); - h->slice_table= h->slice_table_base + s->mb_stride*2 + 1; - - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b_xy , big_mb_num * sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2br_xy , big_mb_num * sizeof(uint32_t), fail); - 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; - - h->mb2b_xy [mb_xy]= b_xy; - h->mb2br_xy[mb_xy]= 8*(FMO ? mb_xy : (mb_xy % (2*s->mb_stride))); - } - } - - s->obmc_scratchpad = NULL; - - if(!h->dequant4_coeff[0]) - init_dequant_tables(h); - - return 0; -fail: - free_tables(h); - return -1; -} - -/** - * Mimic alloc_tables(), but for every context thread. - */ -static void clone_tables(H264Context *dst, H264Context *src, int i){ - MpegEncContext * const s = &src->s; - dst->intra4x4_pred_mode = src->intra4x4_pred_mode + i*8*2*s->mb_stride; - dst->non_zero_count = src->non_zero_count; - dst->slice_table = src->slice_table; - dst->cbp_table = src->cbp_table; - dst->mb2b_xy = src->mb2b_xy; - dst->mb2br_xy = src->mb2br_xy; - dst->chroma_pred_mode_table = src->chroma_pred_mode_table; - dst->mvd_table[0] = src->mvd_table[0] + i*8*2*s->mb_stride; - dst->mvd_table[1] = src->mvd_table[1] + i*8*2*s->mb_stride; - dst->direct_table = src->direct_table; - dst->list_counts = src->list_counts; - - dst->s.obmc_scratchpad = NULL; - ff_h264_pred_init(&dst->hpc, src->s.codec_id); -} - -/** - * Init context - * Allocate buffers which are not shared amongst multiple threads. - */ -static int context_init(H264Context *h){ - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[0], h->s.mb_width * (16+8+8) * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[1], h->s.mb_width * (16+8+8) * sizeof(uint8_t), fail) - - h->ref_cache[0][scan8[5 ]+1] = h->ref_cache[0][scan8[7 ]+1] = h->ref_cache[0][scan8[13]+1] = - h->ref_cache[1][scan8[5 ]+1] = h->ref_cache[1][scan8[7 ]+1] = h->ref_cache[1][scan8[13]+1] = PART_NOT_AVAILABLE; - - return 0; -fail: - return -1; // free_tables will clean up for us -} - -static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size); - -static av_cold 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; - - ff_h264dsp_init(&h->h264dsp); - ff_h264_pred_init(&h->hpc, s->codec_id); - - h->dequant_coeff_pps= -1; - s->unrestricted_mv=1; - s->decode=1; //FIXME - - dsputil_init(&s->dsp, s->avctx); // needed so that idct permutation is known early - - memset(h->pps.scaling_matrix4, 16, 6*16*sizeof(uint8_t)); - memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t)); -} - -av_cold int ff_h264_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->quarter_sample = 1; - if(!avctx->has_b_frames) - s->low_delay= 1; - - avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; - - ff_h264_decode_init_vlc(); - - h->thread_context[0] = h; - h->outputed_poc = INT_MIN; - h->prev_poc_msb= 1<<16; - h->x264_build = -1; - ff_h264_reset_sei(h); - if(avctx->codec_id == CODEC_ID_H264){ - if(avctx->ticks_per_frame == 1){ - s->avctx->time_base.den *=2; - } - avctx->ticks_per_frame = 2; - } - - if(avctx->extradata_size > 0 && avctx->extradata && *(char *)avctx->extradata == 1){ - int i, cnt, nalsize; - unsigned char *p = avctx->extradata; - - h->is_avc = 1; - - if(avctx->extradata_size < 7) { - av_log(avctx, AV_LOG_ERROR, "avcC too short\n"); - 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 = AV_RB16(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 = AV_RB16(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; - } else { - h->is_avc = 0; - if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0) - return -1; - } - 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; - } - - return 0; -} - -int ff_h264_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); - /* - * MPV_frame_start uses pict_type to derive key_frame. - * This is incorrect for H.264; IDR markings must be used. - * Zero here; IDR markings per slice in frame or fields are ORed in later. - * See decode_nal_units(). - */ - s->current_picture_ptr->key_frame= 0; - s->current_picture_ptr->mmco_reset= 0; - - 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? */ - for(i = 0; i < s->avctx->thread_count; i++) - if(!h->thread_context[i]->s.obmc_scratchpad) - h->thread_context[i]->s.obmc_scratchpad = av_malloc(16*2*s->linesize + 8*2*s->uvlinesize); - - /* some macroblocks can be accessed before they're available in case of lost slices, mbaff or threading*/ - memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(*h->slice_table)); - -// s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1; - - // We mark the current picture as non-reference after allocating it, so - // that if we break out due to an error it can be released automatically - // in the next MPV_frame_start(). - // SVQ3 as well as most other codecs have only last/next/current and thus - // get released even with set reference, besides SVQ3 and others do not - // mark frames as reference later "naturally". - if(s->codec_id != CODEC_ID_SVQ3) - s->current_picture_ptr->reference= 0; - - s->current_picture_ptr->field_poc[0]= - s->current_picture_ptr->field_poc[1]= INT_MAX; - assert(s->current_picture_ptr->long_ref==0); - - 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, int simple){ - MpegEncContext * const s = &h->s; - uint8_t *top_border; - int top_idx = 1; - - src_y -= linesize; - src_cb -= uvlinesize; - src_cr -= uvlinesize; - - if(!simple && FRAME_MBAFF){ - if(s->mb_y&1){ - if(!MB_MBAFF){ - top_border = h->top_borders[0][s->mb_x]; - AV_COPY128(top_border, src_y + 15*linesize); - if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - AV_COPY64(top_border+16, src_cb+7*uvlinesize); - AV_COPY64(top_border+24, src_cr+7*uvlinesize); - } - } - }else if(MB_MBAFF){ - top_idx = 0; - }else - return; - } - - top_border = h->top_borders[top_idx][s->mb_x]; - // There are two lines saved, the line above the the top macroblock of a pair, - // and the line above the bottom macroblock - AV_COPY128(top_border, src_y + 16*linesize); - - if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - AV_COPY64(top_border+16, src_cb+8*uvlinesize); - AV_COPY64(top_border+24, 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, int simple){ - MpegEncContext * const s = &h->s; - int deblock_left; - int deblock_top; - int top_idx = 1; - uint8_t *top_border_m1; - uint8_t *top_border; - - if(!simple && FRAME_MBAFF){ - if(s->mb_y&1){ - if(!MB_MBAFF) - return; - }else{ - top_idx = MB_MBAFF ? 0 : 1; - } - } - - if(h->deblocking_filter == 2) { - deblock_left = h->left_type[0]; - deblock_top = h->top_type; - } else { - deblock_left = (s->mb_x > 0); - deblock_top = (s->mb_y > !!MB_FIELD); - } - - src_y -= linesize + 1; - src_cb -= uvlinesize + 1; - src_cr -= uvlinesize + 1; - - top_border_m1 = h->top_borders[top_idx][s->mb_x-1]; - top_border = h->top_borders[top_idx][s->mb_x]; - -#define XCHG(a,b,xchg)\ -if (xchg) AV_SWAP64(b,a);\ -else AV_COPY64(b,a); - - if(deblock_top){ - if(deblock_left){ - XCHG(top_border_m1+8, src_y -7, 1); - } - XCHG(top_border+0, src_y +1, xchg); - XCHG(top_border+8, src_y +9, 1); - if(s->mb_x+1 < s->mb_width){ - XCHG(h->top_borders[top_idx][s->mb_x+1], src_y +17, 1); - } - } - - if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - if(deblock_top){ - if(deblock_left){ - XCHG(top_border_m1+16, src_cb -7, 1); - XCHG(top_border_m1+24, src_cr -7, 1); - } - XCHG(top_border+16, src_cb+1, 1); - XCHG(top_border+24, src_cr+1, 1); - } - } -} - -static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ - MpegEncContext * const s = &h->s; - const int mb_x= s->mb_x; - const int mb_y= s->mb_y; - const int mb_xy= h->mb_xy; - 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 int transform_bypass = !simple && (s->qscale == 0 && h->sps.transform_bypass); - /* is_h264 should always be true if SVQ3 is disabled. */ - const int is_h264 = !CONFIG_SVQ3_DECODER || simple || s->codec_id == CODEC_ID_H264; - void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride); - void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride); - - dest_y = s->current_picture.data[0] + (mb_x + mb_y * s->linesize ) * 16; - dest_cb = s->current_picture.data[1] + (mb_x + mb_y * s->uvlinesize) * 8; - dest_cr = s->current_picture.data[2] + (mb_x + mb_y * s->uvlinesize) * 8; - - s->dsp.prefetch(dest_y + (s->mb_x&3)*4*s->linesize + 64, s->linesize, 4); - s->dsp.prefetch(dest_cb + (s->mb_x&7)*s->uvlinesize + 64, dest_cr - dest_cb, 2); - - h->list_counts[mb_xy]= h->list_count; - - if (!simple && MB_FIELD) { - linesize = h->mb_linesize = s->linesize * 2; - uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2; - block_offset = &h->block_offset[24]; - if(mb_y&1){ //FIXME move out of this function? - dest_y -= s->linesize*15; - dest_cb-= s->uvlinesize*7; - dest_cr-= s->uvlinesize*7; - } - if(FRAME_MBAFF) { - int list; - for(list=0; listlist_count; list++){ - if(!USES_LIST(mb_type, list)) - continue; - if(IS_16X16(mb_type)){ - int8_t *ref = &h->ref_cache[list][scan8[0]]; - fill_rectangle(ref, 4, 4, 8, (16+*ref)^(s->mb_y&1), 1); - }else{ - for(i=0; i<16; i+=4){ - int ref = h->ref_cache[list][scan8[i]]; - if(ref >= 0) - fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, 8, (16+ref)^(s->mb_y&1), 1); - } - } - } - } - } else { - linesize = h->mb_linesize = s->linesize; - uvlinesize = h->mb_uvlinesize = s->uvlinesize; -// dct_offset = s->linesize * 16; - } - - if (!simple && IS_INTRA_PCM(mb_type)) { - for (i=0; i<16; i++) { - memcpy(dest_y + i* linesize, h->mb + i*8, 16); - } - for (i=0; i<8; i++) { - memcpy(dest_cb+ i*uvlinesize, h->mb + 128 + i*4, 8); - memcpy(dest_cr+ i*uvlinesize, h->mb + 160 + i*4, 8); - } - } else { - if(IS_INTRA(mb_type)){ - if(h->deblocking_filter) - xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1, simple); - - if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cb, uvlinesize); - h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cr, uvlinesize); - } - - if(IS_INTRA4x4(mb_type)){ - if(simple || !s->encoding){ - if(IS_8x8DCT(mb_type)){ - if(transform_bypass){ - idct_dc_add = - idct_add = s->dsp.add_pixels8; - }else{ - idct_dc_add = h->h264dsp.h264_idct8_dc_add; - idct_add = h->h264dsp.h264_idct8_add; - } - 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] ]; - if(transform_bypass && h->sps.profile_idc==244 && dir<=1){ - h->hpc.pred8x8l_add[dir](ptr, h->mb + i*16, linesize); - }else{ - const int nnz = h->non_zero_count_cache[ scan8[i] ]; - h->hpc.pred8x8l[ dir ](ptr, (h->topleft_samples_available<topright_samples_available<mb[i*16]) - idct_dc_add(ptr, h->mb + i*16, linesize); - else - idct_add (ptr, h->mb + i*16, linesize); - } - } - } - }else{ - if(transform_bypass){ - idct_dc_add = - idct_add = s->dsp.add_pixels4; - }else{ - idct_dc_add = h->h264dsp.h264_idct_dc_add; - idct_add = h->h264dsp.h264_idct_add; - } - for(i=0; i<16; i++){ - uint8_t * const ptr= dest_y + block_offset[i]; - const int dir= h->intra4x4_pred_mode_cache[ scan8[i] ]; - - if(transform_bypass && h->sps.profile_idc==244 && dir<=1){ - h->hpc.pred4x4_add[dir](ptr, h->mb + i*16, linesize); - }else{ - uint8_t *topright; - int nnz, tr; - if(dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED){ - const int topright_avail= (h->topright_samples_available<hpc.pred4x4[ dir ](ptr, topright, linesize); - nnz = h->non_zero_count_cache[ scan8[i] ]; - if(nnz){ - if(is_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 - ff_svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0); - } - } - } - } - } - }else{ - h->hpc.pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize); - if(is_h264){ - if(!transform_bypass) - h264_luma_dc_dequant_idct_c(h->mb, s->qscale, h->dequant4_coeff[0][s->qscale][0]); - }else - ff_svq3_luma_dc_dequant_idct_c(h->mb, s->qscale); - } - if(h->deblocking_filter) - xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple); - }else if(is_h264){ - hl_motion(h, dest_y, dest_cb, dest_cr, - s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab, - s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab, - h->h264dsp.weight_h264_pixels_tab, h->h264dsp.biweight_h264_pixels_tab); - } - - - if(!IS_INTRA4x4(mb_type)){ - if(is_h264){ - if(IS_INTRA16x16(mb_type)){ - if(transform_bypass){ - if(h->sps.profile_idc==244 && (h->intra16x16_pred_mode==VERT_PRED8x8 || h->intra16x16_pred_mode==HOR_PRED8x8)){ - h->hpc.pred16x16_add[h->intra16x16_pred_mode](dest_y, block_offset, h->mb, linesize); - }else{ - for(i=0; i<16; i++){ - if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]) - s->dsp.add_pixels4(dest_y + block_offset[i], h->mb + i*16, linesize); - } - } - }else{ - h->h264dsp.h264_idct_add16intra(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache); - } - }else if(h->cbp&15){ - if(transform_bypass){ - const int di = IS_8x8DCT(mb_type) ? 4 : 1; - idct_add= IS_8x8DCT(mb_type) ? s->dsp.add_pixels8 : s->dsp.add_pixels4; - for(i=0; i<16; i+=di){ - if(h->non_zero_count_cache[ scan8[i] ]){ - idct_add(dest_y + block_offset[i], h->mb + i*16, linesize); - } - } - }else{ - if(IS_8x8DCT(mb_type)){ - h->h264dsp.h264_idct8_add4(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache); - }else{ - h->h264dsp.h264_idct_add16(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache); - } - } - } - }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]; - ff_svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0); - } - } - } - } - - if((simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) && (h->cbp&0x30)){ - uint8_t *dest[2] = {dest_cb, dest_cr}; - if(transform_bypass){ - if(IS_INTRA(mb_type) && h->sps.profile_idc==244 && (h->chroma_pred_mode==VERT_PRED8x8 || h->chroma_pred_mode==HOR_PRED8x8)){ - h->hpc.pred8x8_add[h->chroma_pred_mode](dest[0], block_offset + 16, h->mb + 16*16, uvlinesize); - h->hpc.pred8x8_add[h->chroma_pred_mode](dest[1], block_offset + 20, h->mb + 20*16, uvlinesize); - }else{ - idct_add = s->dsp.add_pixels4; - for(i=16; i<16+8; i++){ - if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]) - idct_add (dest[(i&4)>>2] + block_offset[i], h->mb + i*16, uvlinesize); - } - } - }else{ - chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp[0], h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]); - chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp[1], h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]); - if(is_h264){ - idct_add = h->h264dsp.h264_idct_add; - idct_dc_add = h->h264dsp.h264_idct_dc_add; - 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]; - ff_svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, ff_h264_chroma_qp[s->qscale + 12] - 12, 2); - } - } - } - } - } - } - if(h->cbp || IS_INTRA(mb_type)) - s->dsp.clear_blocks(h->mb); -} - -/** - * Process a macroblock; this case avoids checks for expensive uncommon cases. - */ -static void hl_decode_mb_simple(H264Context *h){ - hl_decode_mb_internal(h, 1); -} - -/** - * Process a macroblock; this handles edge cases, such as interlacing. - */ -static void av_noinline hl_decode_mb_complex(H264Context *h){ - hl_decode_mb_internal(h, 0); -} - -void ff_h264_hl_decode_mb(H264Context *h){ - MpegEncContext * const s = &h->s; - const int mb_xy= h->mb_xy; - const int mb_type= s->current_picture.mb_type[mb_xy]; - int is_complex = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0; - - if (is_complex) - hl_decode_mb_complex(h); - else hl_decode_mb_simple(h); -} - -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++){ - h->luma_weight_flag[list] = 0; - h->chroma_weight_flag[list] = 0; - 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[i][list][0]= get_se_golomb(&s->gb); - h->luma_weight[i][list][1]= get_se_golomb(&s->gb); - if( h->luma_weight[i][list][0] != luma_def - || h->luma_weight[i][list][1] != 0) { - h->use_weight= 1; - h->luma_weight_flag[list]= 1; - } - }else{ - h->luma_weight[i][list][0]= luma_def; - h->luma_weight[i][list][1]= 0; - } - - if(CHROMA){ - chroma_weight_flag= get_bits1(&s->gb); - if(chroma_weight_flag){ - int j; - for(j=0; j<2; j++){ - h->chroma_weight[i][list][j][0]= get_se_golomb(&s->gb); - h->chroma_weight[i][list][j][1]= get_se_golomb(&s->gb); - if( h->chroma_weight[i][list][j][0] != chroma_def - || h->chroma_weight[i][list][j][1] != 0) { - h->use_weight_chroma= 1; - h->chroma_weight_flag[list]= 1; - } - } - }else{ - int j; - for(j=0; j<2; j++){ - h->chroma_weight[i][list][j][0]= chroma_def; - h->chroma_weight[i][list][j][1]= 0; - } - } - } - } - if(h->slice_type_nos != FF_B_TYPE) break; - } - h->use_weight= h->use_weight || h->use_weight_chroma; - return 0; -} - -/** - * Initialize implicit_weight table. - * @param field, 0/1 initialize the weight for interlaced MBAFF - * -1 initializes the rest - */ -static void implicit_weight_table(H264Context *h, int field){ - MpegEncContext * const s = &h->s; - int ref0, ref1, i, cur_poc, ref_start, ref_count0, ref_count1; - - for (i = 0; i < 2; i++) { - h->luma_weight_flag[i] = 0; - h->chroma_weight_flag[i] = 0; - } - - if(field < 0){ - cur_poc = s->current_picture_ptr->poc; - if( h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF - && 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; - } - ref_start= 0; - ref_count0= h->ref_count[0]; - ref_count1= h->ref_count[1]; - }else{ - cur_poc = s->current_picture_ptr->field_poc[field]; - ref_start= 16; - ref_count0= 16+2*h->ref_count[0]; - ref_count1= 16+2*h->ref_count[1]; - } - - h->use_weight= 2; - h->use_weight_chroma= 2; - h->luma_log2_weight_denom= 5; - h->chroma_log2_weight_denom= 5; - - for(ref0=ref_start; ref0 < ref_count0; ref0++){ - int poc0 = h->ref_list[0][ref0].poc; - for(ref1=ref_start; ref1 < ref_count1; ref1++){ - int poc1 = h->ref_list[1][ref1].poc; - int td = av_clip(poc1 - poc0, -128, 127); - int w= 32; - if(td){ - int tb = av_clip(cur_poc - poc0, -128, 127); - int tx = (16384 + (FFABS(td) >> 1)) / td; - int dist_scale_factor = (tb*tx + 32) >> 8; - if(dist_scale_factor >= -64 && dist_scale_factor <= 128) - w = 64 - dist_scale_factor; - } - if(field<0){ - h->implicit_weight[ref0][ref1][0]= - h->implicit_weight[ref0][ref1][1]= w; - }else{ - h->implicit_weight[ref0][ref1][field]=w; - } - } - } -} - -/** - * instantaneous decoder refresh. - */ -static void idr(H264Context *h){ - ff_h264_remove_all_refs(h); - h->prev_frame_num= 0; - h->prev_frame_num_offset= 0; - h->prev_poc_msb= - h->prev_poc_lsb= 0; -} - -/* forget old pics after a seek */ -static void flush_dpb(AVCodecContext *avctx){ - H264Context *h= avctx->priv_data; - int i; - for(i=0; idelayed_pic[i]) - h->delayed_pic[i]->reference= 0; - h->delayed_pic[i]= NULL; - } - h->outputed_poc= INT_MIN; - h->prev_interlaced_frame = 1; - idr(h); - if(h->s.current_picture_ptr) - h->s.current_picture_ptr->reference= 0; - h->s.first_field= 0; - ff_h264_reset_sei(h); - ff_mpeg_flush(avctx); -} - -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]; - Picture *cur = s->current_picture_ptr; - - h->frame_num_offset= h->prev_frame_num_offset; - if(h->frame_num < h->prev_frame_num) - h->frame_num_offset += max_frame_num; - - if(h->sps.poc_type==0){ - const int max_poc_lsb= 1<sps.log2_max_poc_lsb; - - 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= 2*(h->frame_num_offset + h->frame_num); - - if(!h->nal_ref_idc) - poc--; - - 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]; - cur->poc= FFMIN(cur->field_poc[0], cur->field_poc[1]); - - return 0; -} - - -/** - * initialize scan tables - */ -static void init_scan_tables(H264Context *h){ - int i; - if(h->h264dsp.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{ - 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(h->h264dsp.h264_idct8_add == ff_h264_idct8_add_c){ - memcpy(h->zigzag_scan8x8, ff_zigzag_direct, 64*sizeof(uint8_t)); - memcpy(h->zigzag_scan8x8_cavlc, zigzag_scan8x8_cavlc, 64*sizeof(uint8_t)); - memcpy(h->field_scan8x8, field_scan8x8, 64*sizeof(uint8_t)); - memcpy(h->field_scan8x8_cavlc, field_scan8x8_cavlc, 64*sizeof(uint8_t)); - }else{ - for(i=0; i<64; i++){ -#define T(x) (x>>3) | ((x&7)<<3) - h->zigzag_scan8x8[i] = T(ff_zigzag_direct[i]); - h->zigzag_scan8x8_cavlc[i] = T(zigzag_scan8x8_cavlc[i]); - h->field_scan8x8[i] = T(field_scan8x8[i]); - h->field_scan8x8_cavlc[i] = T(field_scan8x8_cavlc[i]); -#undef T - } - } - if(h->sps.transform_bypass){ //FIXME same ugly - h->zigzag_scan_q0 = zigzag_scan; - h->zigzag_scan8x8_q0 = ff_zigzag_direct; - h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc; - h->field_scan_q0 = field_scan; - h->field_scan8x8_q0 = field_scan8x8; - h->field_scan8x8_cavlc_q0 = field_scan8x8_cavlc; - }else{ - h->zigzag_scan_q0 = h->zigzag_scan; - h->zigzag_scan8x8_q0 = h->zigzag_scan8x8; - h->zigzag_scan8x8_cavlc_q0 = h->zigzag_scan8x8_cavlc; - h->field_scan_q0 = h->field_scan; - h->field_scan8x8_q0 = h->field_scan8x8; - h->field_scan8x8_cavlc_q0 = h->field_scan8x8_cavlc; - } -} - -static void field_end(H264Context *h){ - MpegEncContext * const s = &h->s; - AVCodecContext * const avctx= s->avctx; - s->mb_y= 0; - - s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264; - s->current_picture_ptr->pict_type= s->pict_type; - - if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_h264_set_reference_frames(s); - - if(!s->dropable) { - ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index); - h->prev_poc_msb= h->poc_msb; - h->prev_poc_lsb= h->poc_lsb; - } - h->prev_frame_num_offset= h->frame_num_offset; - h->prev_frame_num= h->frame_num; - - if (avctx->hwaccel) { - if (avctx->hwaccel->end_frame(avctx) < 0) - av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n"); - } - - if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_h264_picture_complete(s); - - /* - * FIXME: Error handling code does not seem to support interlaced - * when slices span multiple rows - * The ff_er_add_slice calls don't work right for bottom - * fields; they cause massive erroneous error concealing - * Error marking covers both fields (top and bottom). - * This causes a mismatched s->error_count - * and a bad error table. Further, the error count goes to - * INT_MAX when called for bottom field, because mb_y is - * past end by one (callers fault) and resync_mb_y != 0 - * causes problems for the first MB line, too. - */ - if (!FIELD_PICTURE) - ff_er_frame_end(s); - - MPV_frame_end(s); - - h->current_slice=0; -} - -/** - * Replicates H264 "master" context to thread contexts. - */ -static void clone_slice(H264Context *dst, H264Context *src) -{ - memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset)); - dst->s.current_picture_ptr = src->s.current_picture_ptr; - dst->s.current_picture = src->s.current_picture; - dst->s.linesize = src->s.linesize; - dst->s.uvlinesize = src->s.uvlinesize; - dst->s.first_field = src->s.first_field; - - dst->prev_poc_msb = src->prev_poc_msb; - dst->prev_poc_lsb = src->prev_poc_lsb; - dst->prev_frame_num_offset = src->prev_frame_num_offset; - dst->prev_frame_num = src->prev_frame_num; - dst->short_ref_count = src->short_ref_count; - - memcpy(dst->short_ref, src->short_ref, sizeof(dst->short_ref)); - memcpy(dst->long_ref, src->long_ref, sizeof(dst->long_ref)); - memcpy(dst->default_ref_list, src->default_ref_list, sizeof(dst->default_ref_list)); - memcpy(dst->ref_list, src->ref_list, sizeof(dst->ref_list)); - - memcpy(dst->dequant4_coeff, src->dequant4_coeff, sizeof(src->dequant4_coeff)); - memcpy(dst->dequant8_coeff, src->dequant8_coeff, sizeof(src->dequant8_coeff)); -} - -/** - * decodes a slice header. - * This will also call MPV_common_init() and frame_start() as needed. - * - * @param h h264context - * @param h0 h264 master context (differs from 'h' when doing sliced based parallel decoding) - * - * @return 0 if okay, <0 if an error occurred, 1 if decoding must not be multithreaded - */ -static int decode_slice_header(H264Context *h, H264Context *h0){ - MpegEncContext * const s = &h->s; - MpegEncContext * const s0 = &h0->s; - unsigned int first_mb_in_slice; - unsigned int pps_id; - int num_ref_idx_active_override_flag; - unsigned int slice_type, tmp, i, j; - int default_ref_list_done = 0; - int last_pic_structure; - - s->dropable= h->nal_ref_idc == 0; - - if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc){ - s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab; - }else{ - s->me.qpel_put= s->dsp.put_h264_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_h264_qpel_pixels_tab; - } - - first_mb_in_slice= get_ue_golomb(&s->gb); - - if(first_mb_in_slice == 0){ //FIXME better field boundary detection - if(h0->current_slice && FIELD_PICTURE){ - field_end(h); - } - - h0->current_slice = 0; - if (!s0->first_field) - s->current_picture_ptr= NULL; - } - - slice_type= get_ue_golomb_31(&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= golomb_to_pict_type[ slice_type ]; - if (slice_type == FF_I_TYPE - || (h0->current_slice != 0 && slice_type == h0->last_slice_type) ) { - default_ref_list_done = 1; - } - h->slice_type= slice_type; - h->slice_type_nos= slice_type & 3; - - s->pict_type= h->slice_type; // to make a few old functions happy, it's wrong though - - pps_id= get_ue_golomb(&s->gb); - if(pps_id>=MAX_PPS_COUNT){ - av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); - return -1; - } - if(!h0->pps_buffers[pps_id]) { - av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS %u referenced\n", pps_id); - return -1; - } - h->pps= *h0->pps_buffers[pps_id]; - - if(!h0->sps_buffers[h->pps.sps_id]) { - av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->pps.sps_id); - return -1; - } - h->sps = *h0->sps_buffers[h->pps.sps_id]; - - s->avctx->profile = h->sps.profile_idc; - s->avctx->level = h->sps.level_idc; - s->avctx->refs = h->sps.ref_frame_count; - - if(h == h0 && 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; - - s->width = 16*s->mb_width - 2*FFMIN(h->sps.crop_right, 7); - if(h->sps.frame_mbs_only_flag) - s->height= 16*s->mb_height - 2*FFMIN(h->sps.crop_bottom, 7); - else - s->height= 16*s->mb_height - 4*FFMIN(h->sps.crop_bottom, 3); - - if (s->context_initialized - && ( s->width != s->avctx->width || s->height != s->avctx->height - || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) { - if(h != h0) - return -1; // width / height changed during parallelized decoding - free_tables(h); - flush_dpb(s->avctx); - MPV_common_end(s); - } - if (!s->context_initialized) { - if(h != h0) - return -1; // we cant (re-)initialize context during parallel decoding - - avcodec_set_dimensions(s->avctx, s->width, 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.video_signal_type_present_flag){ - s->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; - if(h->sps.colour_description_present_flag){ - s->avctx->color_primaries = h->sps.color_primaries; - s->avctx->color_trc = h->sps.color_trc; - s->avctx->colorspace = h->sps.colorspace; - } - } - - if(h->sps.timing_info_present_flag){ - int64_t den= h->sps.time_scale; - if(h->x264_build < 44U) - den *= 2; - av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den, - h->sps.num_units_in_tick, den, 1<<30); - } - s->avctx->pix_fmt = s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts); - s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt); - - if (MPV_common_init(s) < 0) - return -1; - s->first_field = 0; - h->prev_interlaced_frame = 1; - - init_scan_tables(h); - ff_h264_alloc_tables(h); - - for(i = 1; i < s->avctx->thread_count; i++) { - H264Context *c; - c = h->thread_context[i] = av_malloc(sizeof(H264Context)); - memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext)); - memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext)); - c->h264dsp = h->h264dsp; - c->sps = h->sps; - c->pps = h->pps; - init_scan_tables(c); - clone_tables(c, h, i); - } - - for(i = 0; i < s->avctx->thread_count; i++) - if(context_init(h->thread_context[i]) < 0) - return -1; - } - - h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num); - - h->mb_mbaff = 0; - h->mb_aff_frame = 0; - last_pic_structure = s0->picture_structure; - 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; - h->mb_aff_frame = h->sps.mb_aff; - } - } - h->mb_field_decoding_flag= s->picture_structure != PICT_FRAME; - - if(h0->current_slice == 0){ - while(h->frame_num != h->prev_frame_num && - h->frame_num != (h->prev_frame_num+1)%(1<sps.log2_max_frame_num)){ - av_log(NULL, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num); - if (ff_h264_frame_start(h) < 0) - return -1; - h->prev_frame_num++; - h->prev_frame_num %= 1<sps.log2_max_frame_num; - s->current_picture_ptr->frame_num= h->prev_frame_num; - ff_h264_execute_ref_pic_marking(h, NULL, 0); - } - - /* See if we have a decoded first field looking for a pair... */ - if (s0->first_field) { - assert(s0->current_picture_ptr); - assert(s0->current_picture_ptr->data[0]); - assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF); - - /* figure out if we have a complementary field pair */ - if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) { - /* - * Previous field is unmatched. Don't display it, but let it - * remain for reference if marked as such. - */ - s0->current_picture_ptr = NULL; - s0->first_field = FIELD_PICTURE; - - } else { - if (h->nal_ref_idc && - s0->current_picture_ptr->reference && - s0->current_picture_ptr->frame_num != h->frame_num) { - /* - * This and previous field were reference, but had - * different frame_nums. Consider this field first in - * pair. Throw away previous field except for reference - * purposes. - */ - s0->first_field = 1; - s0->current_picture_ptr = NULL; - - } else { - /* Second field in complementary pair */ - s0->first_field = 0; - } - } - - } else { - /* Frame or first field in a potentially complementary pair */ - assert(!s0->current_picture_ptr); - s0->first_field = FIELD_PICTURE; - } - - if((!FIELD_PICTURE || s0->first_field) && ff_h264_frame_start(h) < 0) { - s0->first_field = 0; - return -1; - } - } - if(h != h0) - clone_slice(h, h0); - - s->current_picture_ptr->frame_num= h->frame_num; //FIXME frame_num cleanup - - assert(s->mb_num == s->mb_width * s->mb_height); - if(first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= s->mb_num || - first_mb_in_slice >= s->mb_num){ - av_log(h->s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n"); - return -1; - } - 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) << FIELD_OR_MBAFF_PICTURE; - if (s->picture_structure == PICT_BOTTOM_FIELD) - s->resync_mb_y = s->mb_y = s->mb_y + 1; - assert(s->mb_y < s->mb_height); - - 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 + 1; - 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 overridden a few lines later - h->ref_count[0]= h->pps.ref_count[0]; - h->ref_count[1]= h->pps.ref_count[1]; - - if(h->slice_type_nos != FF_I_TYPE){ - if(h->slice_type_nos == FF_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_nos==FF_B_TYPE) - h->ref_count[1]= get_ue_golomb(&s->gb) + 1; - - if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){ - av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); - h->ref_count[0]= h->ref_count[1]= 1; - return -1; - } - } - if(h->slice_type_nos == FF_B_TYPE) - h->list_count= 2; - else - h->list_count= 1; - }else - h->list_count= 0; - - if(!default_ref_list_done){ - ff_h264_fill_default_ref_list(h); - } - - if(h->slice_type_nos!=FF_I_TYPE && ff_h264_decode_ref_pic_list_reordering(h) < 0) - return -1; - - if(h->slice_type_nos!=FF_I_TYPE){ - s->last_picture_ptr= &h->ref_list[0][0]; - ff_copy_picture(&s->last_picture, s->last_picture_ptr); - } - if(h->slice_type_nos==FF_B_TYPE){ - s->next_picture_ptr= &h->ref_list[1][0]; - ff_copy_picture(&s->next_picture, s->next_picture_ptr); - } - - if( (h->pps.weighted_pred && h->slice_type_nos == FF_P_TYPE ) - || (h->pps.weighted_bipred_idc==1 && h->slice_type_nos== FF_B_TYPE ) ) - pred_weight_table(h); - else if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE){ - implicit_weight_table(h, -1); - }else { - h->use_weight = 0; - for (i = 0; i < 2; i++) { - h->luma_weight_flag[i] = 0; - h->chroma_weight_flag[i] = 0; - } - } - - if(h->nal_ref_idc) - ff_h264_decode_ref_pic_marking(h0, &s->gb); - - if(FRAME_MBAFF){ - ff_h264_fill_mbaff_ref_list(h); - - if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE){ - implicit_weight_table(h, 0); - implicit_weight_table(h, 1); - } - } - - if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred) - ff_h264_direct_dist_scale_factor(h); - ff_h264_direct_ref_list_init(h); - - if( h->slice_type_nos != FF_I_TYPE && h->pps.cabac ){ - tmp = get_ue_golomb_31(&s->gb); - if(tmp > 2){ - av_log(s->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n"); - return -1; - } - h->cabac_init_idc= tmp; - } - - h->last_qscale_diff = 0; - tmp = h->pps.init_qp + get_se_golomb(&s->gb); - if(tmp>51){ - av_log(s->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp); - return -1; - } - s->qscale= tmp; - h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale); - h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale); - //FIXME qscale / qp ... stuff - if(h->slice_type == FF_SP_TYPE){ - get_bits1(&s->gb); /* sp_for_switch_flag */ - } - if(h->slice_type==FF_SP_TYPE || h->slice_type == FF_SI_TYPE){ - get_se_golomb(&s->gb); /* slice_qs_delta */ - } - - h->deblocking_filter = 1; - h->slice_alpha_c0_offset = 52; - h->slice_beta_offset = 52; - if( h->pps.deblocking_filter_parameters_present ) { - tmp= get_ue_golomb_31(&s->gb); - if(tmp > 2){ - av_log(s->avctx, AV_LOG_ERROR, "deblocking_filter_idc %u out of range\n", tmp); - return -1; - } - h->deblocking_filter= tmp; - 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( h->slice_alpha_c0_offset > 104U - || h->slice_beta_offset > 104U){ - av_log(s->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h->slice_alpha_c0_offset, h->slice_beta_offset); - return -1; - } - } - } - - if( s->avctx->skip_loop_filter >= AVDISCARD_ALL - ||(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && h->slice_type_nos != FF_I_TYPE) - ||(s->avctx->skip_loop_filter >= AVDISCARD_BIDIR && h->slice_type_nos == FF_B_TYPE) - ||(s->avctx->skip_loop_filter >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) - h->deblocking_filter= 0; - - if(h->deblocking_filter == 1 && h0->max_contexts > 1) { - if(s->avctx->flags2 & CODEC_FLAG2_FAST) { - /* Cheat slightly for speed: - Do not bother to deblock across slices. */ - h->deblocking_filter = 2; - } else { - h0->max_contexts = 1; - if(!h0->single_decode_warning) { - av_log(s->avctx, AV_LOG_INFO, "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n"); - h0->single_decode_warning = 1; - } - if(h != h0) - return 1; // deblocking switched inside frame - } - } - h->qp_thresh= 15 + 52 - FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) - FFMAX3(0, h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1]); - -#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 - - h0->last_slice_type = slice_type; - h->slice_num = ++h0->current_slice; - if(h->slice_num >= MAX_SLICES){ - av_log(s->avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n"); - } - - for(j=0; j<2; j++){ - int id_list[16]; - int *ref2frm= h->ref2frm[h->slice_num&(MAX_SLICES-1)][j]; - for(i=0; i<16; i++){ - id_list[i]= 60; - if(h->ref_list[j][i].data[0]){ - int k; - uint8_t *base= h->ref_list[j][i].base[0]; - for(k=0; kshort_ref_count; k++) - if(h->short_ref[k]->base[0] == base){ - id_list[i]= k; - break; - } - for(k=0; klong_ref_count; k++) - if(h->long_ref[k] && h->long_ref[k]->base[0] == base){ - id_list[i]= h->short_ref_count + k; - break; - } - } - } - - ref2frm[0]= - ref2frm[1]= -1; - for(i=0; i<16; i++) - ref2frm[i+2]= 4*id_list[i] - +(h->ref_list[j][i].reference&3); - ref2frm[18+0]= - ref2frm[18+1]= -1; - for(i=16; i<48; i++) - ref2frm[i+4]= 4*id_list[(i-16)>>1] - +(h->ref_list[j][i].reference&3); - } - - h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; - h->emu_edge_height= (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %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), h->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "", - 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-26, h->slice_beta_offset/2-26, - h->use_weight, - h->use_weight==1 && h->use_weight_chroma ? "c" : "", - h->slice_type == FF_B_TYPE ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : "" - ); - } - - return 0; -} - -int ff_h264_get_slice_type(const H264Context *h) -{ - switch (h->slice_type) { - case FF_P_TYPE: return 0; - case FF_B_TYPE: return 1; - case FF_I_TYPE: return 2; - case FF_SP_TYPE: return 3; - case FF_SI_TYPE: return 4; - default: return -1; - } -} - -/** - * - * @return non zero if the loop filter can be skiped - */ -static int fill_filter_caches(H264Context *h, int mb_type){ - MpegEncContext * const s = &h->s; - const int mb_xy= h->mb_xy; - int top_xy, left_xy[2]; - int top_type, left_type[2]; - - top_xy = mb_xy - (s->mb_stride << MB_FIELD); - - //FIXME deblocking could skip the intra and nnz parts. - - /* Wow, what a mess, why didn't they simplify the interlacing & intra - * stuff, I can't imagine that these complex rules are worth it. */ - - left_xy[1] = left_xy[0] = mb_xy-1; - if(FRAME_MBAFF){ - const int left_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[mb_xy-1]); - const int curr_mb_field_flag = IS_INTERLACED(mb_type); - if(s->mb_y&1){ - if (left_mb_field_flag != curr_mb_field_flag) { - left_xy[0] -= s->mb_stride; - } - }else{ - if(curr_mb_field_flag){ - top_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy ]>>7)&1)-1); - } - if (left_mb_field_flag != curr_mb_field_flag) { - left_xy[1] += s->mb_stride; - } - } - } - - h->top_mb_xy = top_xy; - h->left_mb_xy[0] = left_xy[0]; - h->left_mb_xy[1] = left_xy[1]; - { - //for sufficiently low qp, filtering wouldn't do anything - //this is a conservative estimate: could also check beta_offset and more accurate chroma_qp - int qp_thresh = h->qp_thresh; //FIXME strictly we should store qp_thresh for each mb of a slice - int qp = s->current_picture.qscale_table[mb_xy]; - if(qp <= qp_thresh - && (left_xy[0]<0 || ((qp + s->current_picture.qscale_table[left_xy[0]] + 1)>>1) <= qp_thresh) - && (top_xy < 0 || ((qp + s->current_picture.qscale_table[top_xy ] + 1)>>1) <= qp_thresh)){ - if(!FRAME_MBAFF) - return 1; - if( (left_xy[0]< 0 || ((qp + s->current_picture.qscale_table[left_xy[1] ] + 1)>>1) <= qp_thresh) - && (top_xy < s->mb_stride || ((qp + s->current_picture.qscale_table[top_xy -s->mb_stride] + 1)>>1) <= qp_thresh)) - return 1; - } - } - - top_type = s->current_picture.mb_type[top_xy] ; - left_type[0] = s->current_picture.mb_type[left_xy[0]]; - left_type[1] = s->current_picture.mb_type[left_xy[1]]; - if(h->deblocking_filter == 2){ - if(h->slice_table[top_xy ] != h->slice_num) top_type= 0; - if(h->slice_table[left_xy[0] ] != h->slice_num) left_type[0]= left_type[1]= 0; - }else{ - if(h->slice_table[top_xy ] == 0xFFFF) top_type= 0; - if(h->slice_table[left_xy[0] ] == 0xFFFF) left_type[0]= left_type[1] =0; - } - h->top_type = top_type ; - h->left_type[0]= left_type[0]; - h->left_type[1]= left_type[1]; - - if(IS_INTRA(mb_type)) - return 0; - - AV_COPY64(&h->non_zero_count_cache[0+8*1], &h->non_zero_count[mb_xy][ 0]); - AV_COPY64(&h->non_zero_count_cache[0+8*2], &h->non_zero_count[mb_xy][ 8]); - AV_COPY32(&h->non_zero_count_cache[0+8*5], &h->non_zero_count[mb_xy][16]); - AV_COPY32(&h->non_zero_count_cache[4+8*3], &h->non_zero_count[mb_xy][20]); - AV_COPY64(&h->non_zero_count_cache[0+8*4], &h->non_zero_count[mb_xy][24]); - - h->cbp= h->cbp_table[mb_xy]; - - { - int list; - for(list=0; listlist_count; list++){ - int8_t *ref; - int y, b_stride; - int16_t (*mv_dst)[2]; - int16_t (*mv_src)[2]; - - if(!USES_LIST(mb_type, list)){ - fill_rectangle( h->mv_cache[list][scan8[0]], 4, 4, 8, pack16to32(0,0), 4); - AV_WN32A(&h->ref_cache[list][scan8[ 0]], ((LIST_NOT_USED)&0xFF)*0x01010101u); - AV_WN32A(&h->ref_cache[list][scan8[ 2]], ((LIST_NOT_USED)&0xFF)*0x01010101u); - AV_WN32A(&h->ref_cache[list][scan8[ 8]], ((LIST_NOT_USED)&0xFF)*0x01010101u); - AV_WN32A(&h->ref_cache[list][scan8[10]], ((LIST_NOT_USED)&0xFF)*0x01010101u); - continue; - } - - ref = &s->current_picture.ref_index[list][4*mb_xy]; - { - int (*ref2frm)[64] = h->ref2frm[ h->slice_num&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2); - AV_WN32A(&h->ref_cache[list][scan8[ 0]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101); - AV_WN32A(&h->ref_cache[list][scan8[ 2]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101); - ref += 2; - AV_WN32A(&h->ref_cache[list][scan8[ 8]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101); - AV_WN32A(&h->ref_cache[list][scan8[10]], (pack16to32(ref2frm[list][ref[0]],ref2frm[list][ref[1]])&0x00FF00FF)*0x0101); - } - - b_stride = h->b_stride; - mv_dst = &h->mv_cache[list][scan8[0]]; - mv_src = &s->current_picture.motion_val[list][4*s->mb_x + 4*s->mb_y*b_stride]; - for(y=0; y<4; y++){ - AV_COPY128(mv_dst + 8*y, mv_src + y*b_stride); - } - - } - } - - -/* -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 (let us hope this is just a typo in the spec) - if(top_type){ - AV_COPY32(&h->non_zero_count_cache[4+8*0], &h->non_zero_count[top_xy][4+3*8]); - } - - if(left_type[0]){ - h->non_zero_count_cache[3+8*1]= h->non_zero_count[left_xy[0]][7+0*8]; - h->non_zero_count_cache[3+8*2]= h->non_zero_count[left_xy[0]][7+1*8]; - h->non_zero_count_cache[3+8*3]= h->non_zero_count[left_xy[0]][7+2*8]; - h->non_zero_count_cache[3+8*4]= h->non_zero_count[left_xy[0]][7+3*8]; - } - - // CAVLC 8x8dct requires NNZ values for residual decoding that differ from what the loop filter needs - if(!CABAC && h->pps.transform_8x8_mode){ - if(IS_8x8DCT(top_type)){ - h->non_zero_count_cache[4+8*0]= - h->non_zero_count_cache[5+8*0]= h->cbp_table[top_xy] & 4; - h->non_zero_count_cache[6+8*0]= - h->non_zero_count_cache[7+8*0]= h->cbp_table[top_xy] & 8; - } - if(IS_8x8DCT(left_type[0])){ - h->non_zero_count_cache[3+8*1]= - h->non_zero_count_cache[3+8*2]= h->cbp_table[left_xy[0]]&2; //FIXME check MBAFF - } - if(IS_8x8DCT(left_type[1])){ - h->non_zero_count_cache[3+8*3]= - h->non_zero_count_cache[3+8*4]= h->cbp_table[left_xy[1]]&8; //FIXME check MBAFF - } - - if(IS_8x8DCT(mb_type)){ - h->non_zero_count_cache[scan8[0 ]]= h->non_zero_count_cache[scan8[1 ]]= - h->non_zero_count_cache[scan8[2 ]]= h->non_zero_count_cache[scan8[3 ]]= h->cbp & 1; - - h->non_zero_count_cache[scan8[0+ 4]]= h->non_zero_count_cache[scan8[1+ 4]]= - h->non_zero_count_cache[scan8[2+ 4]]= h->non_zero_count_cache[scan8[3+ 4]]= h->cbp & 2; - - h->non_zero_count_cache[scan8[0+ 8]]= h->non_zero_count_cache[scan8[1+ 8]]= - h->non_zero_count_cache[scan8[2+ 8]]= h->non_zero_count_cache[scan8[3+ 8]]= h->cbp & 4; - - h->non_zero_count_cache[scan8[0+12]]= h->non_zero_count_cache[scan8[1+12]]= - h->non_zero_count_cache[scan8[2+12]]= h->non_zero_count_cache[scan8[3+12]]= h->cbp & 8; - } - } - - if(IS_INTER(mb_type) || IS_DIRECT(mb_type)){ - int list; - for(list=0; listlist_count; list++){ - if(USES_LIST(top_type, list)){ - const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride; - const int b8_xy= 4*top_xy + 2; - int (*ref2frm)[64] = h->ref2frm[ h->slice_table[top_xy]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2); - AV_COPY128(h->mv_cache[list][scan8[0] + 0 - 1*8], s->current_picture.motion_val[list][b_xy + 0]); - h->ref_cache[list][scan8[0] + 0 - 1*8]= - h->ref_cache[list][scan8[0] + 1 - 1*8]= ref2frm[list][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]= ref2frm[list][s->current_picture.ref_index[list][b8_xy + 1]]; - }else{ - AV_ZERO128(h->mv_cache[list][scan8[0] + 0 - 1*8]); - AV_WN32A(&h->ref_cache[list][scan8[0] + 0 - 1*8], ((LIST_NOT_USED)&0xFF)*0x01010101u); - } - - if(!IS_INTERLACED(mb_type^left_type[0])){ - if(USES_LIST(left_type[0], list)){ - const int b_xy= h->mb2b_xy[left_xy[0]] + 3; - const int b8_xy= 4*left_xy[0] + 1; - int (*ref2frm)[64] = h->ref2frm[ h->slice_table[left_xy[0]]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2); - AV_COPY32(h->mv_cache[list][scan8[0] - 1 + 0 ], s->current_picture.motion_val[list][b_xy + h->b_stride*0]); - AV_COPY32(h->mv_cache[list][scan8[0] - 1 + 8 ], s->current_picture.motion_val[list][b_xy + h->b_stride*1]); - AV_COPY32(h->mv_cache[list][scan8[0] - 1 +16 ], s->current_picture.motion_val[list][b_xy + h->b_stride*2]); - AV_COPY32(h->mv_cache[list][scan8[0] - 1 +24 ], s->current_picture.motion_val[list][b_xy + h->b_stride*3]); - h->ref_cache[list][scan8[0] - 1 + 0 ]= - h->ref_cache[list][scan8[0] - 1 + 8 ]= ref2frm[list][s->current_picture.ref_index[list][b8_xy + 2*0]]; - h->ref_cache[list][scan8[0] - 1 +16 ]= - h->ref_cache[list][scan8[0] - 1 +24 ]= ref2frm[list][s->current_picture.ref_index[list][b8_xy + 2*1]]; - }else{ - AV_ZERO32(h->mv_cache [list][scan8[0] - 1 + 0 ]); - AV_ZERO32(h->mv_cache [list][scan8[0] - 1 + 8 ]); - AV_ZERO32(h->mv_cache [list][scan8[0] - 1 +16 ]); - AV_ZERO32(h->mv_cache [list][scan8[0] - 1 +24 ]); - h->ref_cache[list][scan8[0] - 1 + 0 ]= - h->ref_cache[list][scan8[0] - 1 + 8 ]= - h->ref_cache[list][scan8[0] - 1 + 16 ]= - h->ref_cache[list][scan8[0] - 1 + 24 ]= LIST_NOT_USED; - } - } - } - } - - return 0; -} - -static void loop_filter(H264Context *h){ - MpegEncContext * const s = &h->s; - uint8_t *dest_y, *dest_cb, *dest_cr; - int linesize, uvlinesize, mb_x, mb_y; - const int end_mb_y= s->mb_y + FRAME_MBAFF; - const int old_slice_type= h->slice_type; - - if(h->deblocking_filter) { - for(mb_x= 0; mb_xmb_width; mb_x++){ - for(mb_y=end_mb_y - FRAME_MBAFF; mb_y<= end_mb_y; mb_y++){ - int mb_xy, mb_type; - mb_xy = h->mb_xy = mb_x + mb_y*s->mb_stride; - h->slice_num= h->slice_table[mb_xy]; - mb_type= s->current_picture.mb_type[mb_xy]; - h->list_count= h->list_counts[mb_xy]; - - if(FRAME_MBAFF) - h->mb_mbaff = h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type); - - s->mb_x= mb_x; - s->mb_y= mb_y; - dest_y = s->current_picture.data[0] + (mb_x + mb_y * s->linesize ) * 16; - dest_cb = s->current_picture.data[1] + (mb_x + mb_y * s->uvlinesize) * 8; - dest_cr = s->current_picture.data[2] + (mb_x + mb_y * s->uvlinesize) * 8; - //FIXME simplify above - - if (MB_FIELD) { - linesize = h->mb_linesize = s->linesize * 2; - uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2; - if(mb_y&1){ //FIXME move out of this function? - dest_y -= s->linesize*15; - dest_cb-= s->uvlinesize*7; - dest_cr-= s->uvlinesize*7; - } - } else { - linesize = h->mb_linesize = s->linesize; - uvlinesize = h->mb_uvlinesize = s->uvlinesize; - } - backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0); - if(fill_filter_caches(h, mb_type)) - continue; - h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]); - h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]); - - if (FRAME_MBAFF) { - ff_h264_filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); - } else { - ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); - } - } - } - } - h->slice_type= old_slice_type; - s->mb_x= 0; - s->mb_y= end_mb_y - FRAME_MBAFF; - h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale); - h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale); -} - -static void predict_field_decoding_flag(H264Context *h){ - MpegEncContext * const s = &h->s; - const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; - int mb_type = (h->slice_table[mb_xy-1] == h->slice_num) - ? s->current_picture.mb_type[mb_xy-1] - : (h->slice_table[mb_xy-s->mb_stride] == h->slice_num) - ? s->current_picture.mb_type[mb_xy-s->mb_stride] - : 0; - h->mb_mbaff = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0; -} - -static int decode_slice(struct AVCodecContext *avctx, void *arg){ - H264Context *h = *(void**)arg; - MpegEncContext * const s = &h->s; - const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F; - - s->mb_skip_run= -1; - - h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME || s->codec_id != CODEC_ID_H264 || - (CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY)); - - if( h->pps.cabac ) { - /* realign */ - align_get_bits( &s->gb ); - - /* init cabac */ - ff_init_cabac_states( &h->cabac); - ff_init_cabac_decoder( &h->cabac, - s->gb.buffer + get_bits_count(&s->gb)/8, - (get_bits_left(&s->gb) + 7)/8); - - ff_h264_init_cabac_states(h); - - for(;;){ -//START_TIMER - int ret = ff_h264_decode_mb_cabac(h); - int eos; -//STOP_TIMER("decode_mb_cabac") - - if(ret>=0) ff_h264_hl_decode_mb(h); - - if( ret >= 0 && FRAME_MBAFF ) { //FIXME optimal? or let mb_decode decode 16x32 ? - s->mb_y++; - - ret = ff_h264_decode_mb_cabac(h); - - if(ret>=0) ff_h264_hl_decode_mb(h); - s->mb_y--; - } - eos = get_cabac_terminate( &h->cabac ); - - if((s->workaround_bugs & FF_BUG_TRUNCATED) && h->cabac.bytestream > h->cabac.bytestream_end + 2){ - 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; - } - if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) { - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream); - 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; - loop_filter(h); - ff_draw_horiz_band(s, 16*s->mb_y, 16); - ++s->mb_y; - if(FIELD_OR_MBAFF_PICTURE) { - ++s->mb_y; - if(FRAME_MBAFF && s->mb_y < s->mb_height) - predict_field_decoding_flag(h); - } - } - - if( eos || s->mb_y >= s->mb_height ) { - tprintf(s->avctx, "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 = ff_h264_decode_mb_cavlc(h); - - if(ret>=0) ff_h264_hl_decode_mb(h); - - if(ret>=0 && FRAME_MBAFF){ //FIXME optimal? or let mb_decode decode 16x32 ? - s->mb_y++; - ret = ff_h264_decode_mb_cavlc(h); - - if(ret>=0) ff_h264_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; - loop_filter(h); - ff_draw_horiz_band(s, 16*s->mb_y, 16); - ++s->mb_y; - if(FIELD_OR_MBAFF_PICTURE) { - ++s->mb_y; - if(FRAME_MBAFF && s->mb_y < s->mb_height) - predict_field_decoding_flag(h); - } - if(s->mb_y >= s->mb_height){ - tprintf(s->avctx, "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(s->avctx, "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); - - ff_h264_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 -} - -/** - * Call decode_slice() for each context. - * - * @param h h264 master context - * @param context_count number of contexts to execute - */ -static void execute_decode_slices(H264Context *h, int context_count){ - MpegEncContext * const s = &h->s; - AVCodecContext * const avctx= s->avctx; - H264Context *hx; - int i; - - if (s->avctx->hwaccel) - return; - if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - return; - if(context_count == 1) { - decode_slice(avctx, &h); - } else { - for(i = 1; i < context_count; i++) { - hx = h->thread_context[i]; - hx->s.error_recognition = avctx->error_recognition; - hx->s.error_count = 0; - } - - avctx->execute(avctx, (void *)decode_slice, - h->thread_context, NULL, context_count, sizeof(void*)); - - /* pull back stuff from slices to master context */ - hx = h->thread_context[context_count - 1]; - s->mb_x = hx->s.mb_x; - s->mb_y = hx->s.mb_y; - s->dropable = hx->s.dropable; - s->picture_structure = hx->s.picture_structure; - for(i = 1; i < context_count; i++) - h->s.error_count += h->thread_context[i]->s.error_count; - } -} - - -static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ - MpegEncContext * const s = &h->s; - AVCodecContext * const avctx= s->avctx; - int buf_index=0; - H264Context *hx; ///< thread context - int context_count = 0; - int next_avc= h->is_avc ? 0 : buf_size; - - h->max_contexts = avctx->thread_count; -#if 0 - int i; - for(i=0; i<50; i++){ - av_log(NULL, AV_LOG_ERROR,"%02X ", buf[i]); - } -#endif - if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){ - h->current_slice = 0; - if (!s->first_field) - s->current_picture_ptr= NULL; - ff_h264_reset_sei(h); - } - - for(;;){ - int consumed; - int dst_length; - int bit_length; - const uint8_t *ptr; - int i, nalsize = 0; - int err; - - if(buf_index >= next_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 || nalsize > buf_size - buf_index){ - if(nalsize == 1){ - buf_index++; - continue; - }else{ - av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); - break; - } - } - next_avc= buf_index + nalsize; - } else { - // start code prefix search - for(; buf_index + 3 < next_avc; buf_index++){ - // This should always 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; - if(buf_index >= next_avc) continue; - } - - hx = h->thread_context[context_count]; - - ptr= ff_h264_decode_nal(hx, buf + buf_index, &dst_length, &consumed, next_avc - buf_index); - if (ptr==NULL || dst_length < 0){ - return -1; - } - i= buf_index + consumed; - if((s->workaround_bugs & FF_BUG_AUTODETECT) && i+3workaround_bugs |= FF_BUG_TRUNCATED; - - if(!(s->workaround_bugs & FF_BUG_TRUNCATED)){ - while(ptr[dst_length - 1] == 0 && dst_length > 0) - dst_length--; - } - bit_length= !dst_length ? 0 : (8*dst_length - ff_h264_decode_rbsp_trailing(h, 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", hx->nal_unit_type, buf_index, buf_size, dst_length); - } - - if (h->is_avc && (nalsize != consumed) && nalsize){ - av_log(h->s.avctx, AV_LOG_DEBUG, "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 do not discard SEI id - ||(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) - continue; - - again: - err = 0; - switch(hx->nal_unit_type){ - case NAL_IDR_SLICE: - if (h->nal_unit_type != NAL_IDR_SLICE) { - av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices"); - return -1; - } - idr(h); //FIXME ensure we don't loose some frames if there is reordering - case NAL_SLICE: - init_get_bits(&hx->s.gb, ptr, bit_length); - hx->intra_gb_ptr= - hx->inter_gb_ptr= &hx->s.gb; - hx->s.data_partitioning = 0; - - if((err = decode_slice_header(hx, h))) - break; - - if (h->current_slice == 1) { - if (s->avctx->hwaccel && s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0) - return -1; - if(CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_h264_picture_start(s); - } - - s->current_picture_ptr->key_frame |= - (hx->nal_unit_type == NAL_IDR_SLICE) || - (h->sei_recovery_frame_cnt >= 0); - if(hx->redundant_pic_count==0 && hx->s.hurry_up < 5 - && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) - && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=FF_B_TYPE) - && (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type_nos==FF_I_TYPE) - && avctx->skip_frame < AVDISCARD_ALL){ - if(avctx->hwaccel) { - if (avctx->hwaccel->decode_slice(avctx, &buf[buf_index - consumed], consumed) < 0) - return -1; - }else - if(CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){ - static const uint8_t start_code[] = {0x00, 0x00, 0x01}; - ff_vdpau_add_data_chunk(s, start_code, sizeof(start_code)); - ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed], consumed ); - }else - context_count++; - } - break; - case NAL_DPA: - init_get_bits(&hx->s.gb, ptr, bit_length); - hx->intra_gb_ptr= - hx->inter_gb_ptr= NULL; - - if ((err = decode_slice_header(hx, h)) < 0) - break; - - hx->s.data_partitioning = 1; - - break; - case NAL_DPB: - init_get_bits(&hx->intra_gb, ptr, bit_length); - hx->intra_gb_ptr= &hx->intra_gb; - break; - case NAL_DPC: - init_get_bits(&hx->inter_gb, ptr, bit_length); - hx->inter_gb_ptr= &hx->inter_gb; - - if(hx->redundant_pic_count==0 && hx->intra_gb_ptr && hx->s.data_partitioning - && s->context_initialized - && s->hurry_up < 5 - && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) - && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=FF_B_TYPE) - && (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type_nos==FF_I_TYPE) - && avctx->skip_frame < AVDISCARD_ALL) - context_count++; - break; - case NAL_SEI: - init_get_bits(&s->gb, ptr, bit_length); - ff_h264_decode_sei(h); - break; - case NAL_SPS: - init_get_bits(&s->gb, ptr, bit_length); - ff_h264_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); - - ff_h264_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_DEBUG, "Unknown NAL code: %d (%d bits)\n", hx->nal_unit_type, bit_length); - } - - if(context_count == h->max_contexts) { - execute_decode_slices(h, context_count); - context_count = 0; - } - - if (err < 0) - av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); - else if(err == 1) { - /* Slice could not be decoded in parallel mode, copy down - * NAL unit stuff to context 0 and restart. Note that - * rbsp_buffer is not transferred, but since we no longer - * run in parallel mode this should not be an issue. */ - h->nal_unit_type = hx->nal_unit_type; - h->nal_ref_idc = hx->nal_ref_idc; - hx = h; - goto again; - } - } - if(context_count) - execute_decode_slices(h, context_count); - 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(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...) - if(pos+10>buf_size) pos=buf_size; // oops ;) - - return pos; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - H264Context *h = avctx->priv_data; - MpegEncContext *s = &h->s; - AVFrame *pict = data; - int buf_index; - - s->flags= avctx->flags; - s->flags2= avctx->flags2; - - /* end of stream, output what is still in the buffers */ - if (buf_size == 0) { - Picture *out; - int i, out_idx; - -//FIXME factorize this with the output code below - out = h->delayed_pic[0]; - out_idx = 0; - for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame && !h->delayed_pic[i]->mmco_reset; i++) - if(h->delayed_pic[i]->poc < out->poc){ - out = h->delayed_pic[i]; - out_idx = i; - } - - for(i=out_idx; h->delayed_pic[i]; i++) - h->delayed_pic[i] = h->delayed_pic[i+1]; - - if(out){ - *data_size = sizeof(AVFrame); - *pict= *(AVFrame*)out; - } - - return 0; - } - - buf_index=decode_nal_units(h, buf, buf_size); - if(buf_index < 0) - return -1; - - if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){ - if (avctx->skip_frame >= AVDISCARD_NONREF || s->hurry_up) return 0; - av_log(avctx, AV_LOG_ERROR, "no frame!\n"); - return -1; - } - - if(!(s->flags2 & CODEC_FLAG2_CHUNKS) || (s->mb_y >= s->mb_height && s->mb_height)){ - Picture *out = s->current_picture_ptr; - Picture *cur = s->current_picture_ptr; - int i, pics, out_of_order, out_idx; - - field_end(h); - - if (cur->field_poc[0]==INT_MAX || cur->field_poc[1]==INT_MAX) { - /* Wait for second field. */ - *data_size = 0; - - } else { - cur->interlaced_frame = 0; - cur->repeat_pict = 0; - - /* Signal interlacing information externally. */ - /* Prioritize picture timing SEI information over used decoding process if it exists. */ - - if(h->sps.pic_struct_present_flag){ - switch (h->sei_pic_struct) - { - case SEI_PIC_STRUCT_FRAME: - break; - case SEI_PIC_STRUCT_TOP_FIELD: - case SEI_PIC_STRUCT_BOTTOM_FIELD: - cur->interlaced_frame = 1; - break; - case SEI_PIC_STRUCT_TOP_BOTTOM: - case SEI_PIC_STRUCT_BOTTOM_TOP: - if (FIELD_OR_MBAFF_PICTURE) - cur->interlaced_frame = 1; - else - // try to flag soft telecine progressive - cur->interlaced_frame = h->prev_interlaced_frame; - break; - case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: - case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: - // Signal the possibility of telecined film externally (pic_struct 5,6) - // From these hints, let the applications decide if they apply deinterlacing. - cur->repeat_pict = 1; - break; - case SEI_PIC_STRUCT_FRAME_DOUBLING: - // Force progressive here, as doubling interlaced frame is a bad idea. - cur->repeat_pict = 2; - break; - case SEI_PIC_STRUCT_FRAME_TRIPLING: - cur->repeat_pict = 4; - break; - } - - if ((h->sei_ct_type & 3) && h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP) - cur->interlaced_frame = (h->sei_ct_type & (1<<1)) != 0; - }else{ - /* Derive interlacing flag from used decoding process. */ - cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE; - } - h->prev_interlaced_frame = cur->interlaced_frame; - - if (cur->field_poc[0] != cur->field_poc[1]){ - /* Derive top_field_first from field pocs. */ - cur->top_field_first = cur->field_poc[0] < cur->field_poc[1]; - }else{ - if(cur->interlaced_frame || h->sps.pic_struct_present_flag){ - /* Use picture timing SEI information. Even if it is a information of a past frame, better than nothing. */ - if(h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM - || h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP) - cur->top_field_first = 1; - else - cur->top_field_first = 0; - }else{ - /* Most likely progressive */ - cur->top_field_first = 0; - } - } - - //FIXME do something with unavailable reference frames - - /* Sort B-frames into display order */ - - 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; - } - - if( s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT - && !h->sps.bitstream_restriction_flag){ - s->avctx->has_b_frames= MAX_DELAYED_PIC_COUNT; - s->low_delay= 0; - } - - pics = 0; - while(h->delayed_pic[pics]) pics++; - - assert(pics <= MAX_DELAYED_PIC_COUNT); - - h->delayed_pic[pics++] = cur; - if(cur->reference == 0) - cur->reference = DELAYED_PIC_REF; - - out = h->delayed_pic[0]; - out_idx = 0; - for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame && !h->delayed_pic[i]->mmco_reset; i++) - if(h->delayed_pic[i]->poc < out->poc){ - out = h->delayed_pic[i]; - out_idx = i; - } - if(s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->key_frame || h->delayed_pic[0]->mmco_reset)) - h->outputed_poc= INT_MIN; - out_of_order = out->poc < h->outputed_poc; - - if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames) - { } - else if((out_of_order && pics-1 == s->avctx->has_b_frames && s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) - || (s->low_delay && - ((h->outputed_poc != INT_MIN && out->poc > h->outputed_poc + 2) - || cur->pict_type == FF_B_TYPE))) - { - s->low_delay = 0; - s->avctx->has_b_frames++; - } - - if(out_of_order || pics > s->avctx->has_b_frames){ - out->reference &= ~DELAYED_PIC_REF; - for(i=out_idx; h->delayed_pic[i]; i++) - h->delayed_pic[i] = h->delayed_pic[i+1]; - } - if(!out_of_order && pics > s->avctx->has_b_frames){ - *data_size = sizeof(AVFrame); - - if(out_idx==0 && h->delayed_pic[0] && (h->delayed_pic[0]->key_frame || h->delayed_pic[0]->mmco_reset)) { - h->outputed_poc = INT_MIN; - } else - h->outputed_poc = out->poc; - *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]); - - 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 - -#ifdef TEST -#undef printf -#undef random -#define COUNT 8000 -#define SIZE (COUNT*40) -int main(void){ - 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; ih264dsp.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= FFABS(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 ); - printf("testing quantizer\n"); - for(qp=0; qp<52; qp++){ - for(i=0; i<16; i++) - src1_block[i]= src2_block[i]= random()%255; - - } - printf("Testing NAL layer\n"); - - uint8_t bitstream[COUNT]; - uint8_t nal[COUNT*2]; - H264Context h; - memset(&h, 0, sizeof(H264Context)); - - for(i=0; isps_buffers + i); - - for(i = 0; i < MAX_PPS_COUNT; i++) - av_freep(h->pps_buffers + i); -} - -av_cold int ff_h264_decode_end(AVCodecContext *avctx) -{ - H264Context *h = avctx->priv_data; - MpegEncContext *s = &h->s; - - ff_h264_free_context(h); - - MPV_common_end(s); - -// memset(h, 0, sizeof(H264Context)); - - return 0; -} - - -AVCodec h264_decoder = { - "h264", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_H264, - sizeof(H264Context), - ff_h264_decode_init, - NULL, - ff_h264_decode_end, - decode_frame, - /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .flush= flush_dpb, - .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), - .pix_fmts= ff_hwaccel_pixfmt_list_420, -}; - -#if CONFIG_H264_VDPAU_DECODER -AVCodec h264_vdpau_decoder = { - "h264_vdpau", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_H264, - sizeof(H264Context), - ff_h264_decode_init, - NULL, - ff_h264_decode_end, - decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - .flush= flush_dpb, - .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"), - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_H264, PIX_FMT_NONE}, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/h264.h b/tizen/distrib/ffmpeg/libavcodec/h264.h deleted file mode 100644 index c6563af..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264.h +++ /dev/null @@ -1,1299 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 codec. - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_H264_H -#define AVCODEC_H264_H - -#include "libavutil/intreadwrite.h" -#include "dsputil.h" -#include "cabac.h" -#include "mpegvideo.h" -#include "h264dsp.h" -#include "h264pred.h" -#include "rectangle.h" - -#define interlaced_dct interlaced_dct_is_a_bad_name -#define mb_intra mb_intra_is_not_initialized_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 - -#define MAX_DELAYED_PIC_COUNT 16 - -/* Compiling in interlaced support reduces the speed - * of progressive decoding by about 2%. */ -#define ALLOW_INTERLACE - -#define ALLOW_NOCHROMA - -#define FMO 0 - -/** - * The maximum number of slices supported by the decoder. - * must be a power of 2 - */ -#define MAX_SLICES 16 - -#ifdef ALLOW_INTERLACE -#define MB_MBAFF h->mb_mbaff -#define MB_FIELD h->mb_field_decoding_flag -#define FRAME_MBAFF h->mb_aff_frame -#define FIELD_PICTURE (s->picture_structure != PICT_FRAME) -#else -#define MB_MBAFF 0 -#define MB_FIELD 0 -#define FRAME_MBAFF 0 -#define FIELD_PICTURE 0 -#undef IS_INTERLACED -#define IS_INTERLACED(mb_type) 0 -#endif -#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE) - -#ifdef ALLOW_NOCHROMA -#define CHROMA h->sps.chroma_format_idc -#else -#define CHROMA 1 -#endif - -#ifndef CABAC -#define CABAC h->pps.cabac -#endif - -#define EXTENDED_SAR 255 - -#define MB_TYPE_REF0 MB_TYPE_ACPRED //dirty but it fits in 16 bit -#define MB_TYPE_8x8DCT 0x01000000 -#define IS_REF0(a) ((a) & MB_TYPE_REF0) -#define IS_8x8DCT(a) ((a) & MB_TYPE_8x8DCT) - -/** - * Value of Picture.reference when Picture is not a reference picture, but - * is held for delayed output. - */ -#define DELAYED_PIC_REF 4 - - -/* NAL unit types */ -enum { - NAL_SLICE=1, - NAL_DPA, - NAL_DPB, - NAL_DPC, - NAL_IDR_SLICE, - NAL_SEI, - NAL_SPS, - NAL_PPS, - NAL_AUD, - NAL_END_SEQUENCE, - NAL_END_STREAM, - NAL_FILLER_DATA, - NAL_SPS_EXT, - NAL_AUXILIARY_SLICE=19 -}; - -/** - * SEI message types - */ -typedef enum { - SEI_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1) - SEI_TYPE_PIC_TIMING = 1, ///< picture timing - SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data - SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync) -} SEI_Type; - -/** - * pic_struct in picture timing SEI message - */ -typedef enum { - SEI_PIC_STRUCT_FRAME = 0, ///< 0: %frame - SEI_PIC_STRUCT_TOP_FIELD = 1, ///< 1: top field - SEI_PIC_STRUCT_BOTTOM_FIELD = 2, ///< 2: bottom field - SEI_PIC_STRUCT_TOP_BOTTOM = 3, ///< 3: top field, bottom field, in that order - SEI_PIC_STRUCT_BOTTOM_TOP = 4, ///< 4: bottom field, top field, in that order - SEI_PIC_STRUCT_TOP_BOTTOM_TOP = 5, ///< 5: top field, bottom field, top field repeated, in that order - SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6, ///< 6: bottom field, top field, bottom field repeated, in that order - SEI_PIC_STRUCT_FRAME_DOUBLING = 7, ///< 7: %frame doubling - SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling -} SEI_PicStructType; - -/** - * Sequence parameter set - */ -typedef struct SPS{ - - int profile_idc; - int level_idc; - int chroma_format_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; ///< pic_width_in_mbs_minus1 + 1 - int mb_height; ///< pic_height_in_map_units_minus1 + 1 - int frame_mbs_only_flag; - int mb_aff; ///b4_stride - - int mb_linesize; ///< may be equal to s->linesize or s->linesize*2, for mbaff - int mb_uvlinesize; - - int emu_edge_width; - int emu_edge_height; - - SPS sps; ///< current sps - - /** - * current pps - */ - PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? - - uint32_t dequant4_buffer[6][52][16]; //FIXME should these be moved down? - uint32_t dequant8_buffer[2][52][64]; - uint32_t (*dequant4_coeff[6])[16]; - uint32_t (*dequant8_coeff[2])[64]; - - int slice_num; - uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 - int slice_type; - int slice_type_nos; ///< S free slice type (SI/SP are remapped to I/P) - int slice_type_fixed; - - //interlacing specific flags - int mb_aff_frame; - int mb_field_decoding_flag; - int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag - - DECLARE_ALIGNED(8, uint16_t, sub_mb_type)[4]; - - //Weighted pred stuff - int use_weight; - int use_weight_chroma; - int luma_log2_weight_denom; - int chroma_log2_weight_denom; - //The following 2 can be changed to int8_t but that causes 10cpu cycles speedloss - int luma_weight[48][2][2]; - int chroma_weight[48][2][2][2]; - int implicit_weight[48][48][2]; - - int direct_spatial_mv_pred; - int col_parity; - int col_fieldoff; - int dist_scale_factor[16]; - int dist_scale_factor_field[2][32]; - int map_col_to_list0[2][16+32]; - int map_col_to_list0_field[2][2][16+32]; - - /** - * num_ref_idx_l0/1_active_minus1 + 1 - */ - unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode - unsigned int list_count; - uint8_t *list_counts; ///< Array of list_count per MB specifying the slice type - Picture ref_list[2][48]; /**< 0..15: frame refs, 16..47: mbaff field refs. - Reordered version of default_ref_list - according to picture reordering in slice header */ - int ref2frm[MAX_SLICES][2][64]; ///< reference to frame number lists, used in the loop filter, the first 2 are for -2,-1 - - //data partitioning - GetBitContext intra_gb; - GetBitContext inter_gb; - GetBitContext *intra_gb_ptr; - GetBitContext *inter_gb_ptr; - - DECLARE_ALIGNED(16, DCTELEM, mb)[16*24]; - DCTELEM mb_padding[256]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb - - /** - * Cabac - */ - CABACContext cabac; - uint8_t cabac_state[460]; - - /* 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 cbp; - 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; - uint8_t (*mvd_table[2])[2]; - DECLARE_ALIGNED(16, uint8_t, mvd_cache)[2][5*8][2]; - uint8_t *direct_table; - uint8_t direct_cache[5*8]; - - uint8_t zigzag_scan[16]; - uint8_t zigzag_scan8x8[64]; - uint8_t zigzag_scan8x8_cavlc[64]; - uint8_t field_scan[16]; - uint8_t field_scan8x8[64]; - uint8_t field_scan8x8_cavlc[64]; - const uint8_t *zigzag_scan_q0; - const uint8_t *zigzag_scan8x8_q0; - const uint8_t *zigzag_scan8x8_cavlc_q0; - const uint8_t *field_scan_q0; - const uint8_t *field_scan8x8_q0; - const uint8_t *field_scan8x8_cavlc_q0; - - int x264_build; - - int mb_xy; - - int is_complex; - - //deblock - int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0 - int slice_alpha_c0_offset; - int slice_beta_offset; - -//============================================================= - //Things below are not used in the MB or more inner code - - int nal_ref_idc; - int nal_unit_type; - uint8_t *rbsp_buffer[2]; - unsigned int rbsp_buffer_size[2]; - - /** - * Used to parse AVC variant of h264 - */ - int is_avc; ///< this flag is != 0 if codec is avc1 - int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4) - - SPS *sps_buffers[MAX_SPS_COUNT]; - PPS *pps_buffers[MAX_PPS_COUNT]; - - int dequant_coeff_pps; ///< reinit tables when pps changes - - uint16_t *slice_table_base; - - - //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+1 for field pics. - */ - int curr_pic_num; - - /** - * max_frame_num or 2*max_frame_num for field pics. - */ - int max_pic_num; - - int redundant_pic_count; - - Picture *short_ref[32]; - Picture *long_ref[32]; - Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture - Picture *delayed_pic[MAX_DELAYED_PIC_COUNT+2]; //FIXME size? - int outputed_poc; - - /** - * 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 - - int cabac_init_idc; - - /** - * @defgroup multithreading Members for slice based multithreading - * @{ - */ - struct H264Context *thread_context[MAX_THREADS]; - - /** - * current slice number, used to initalize slice_num of each thread/context - */ - int current_slice; - - /** - * Max number of threads / contexts. - * This is equal to AVCodecContext.thread_count unless - * multithreaded decoding is impossible, in which case it is - * reduced to 1. - */ - int max_contexts; - - /** - * 1 if the single thread fallback warning has already been - * displayed, 0 otherwise. - */ - int single_decode_warning; - - int last_slice_type; - /** @} */ - - /** - * pic_struct in picture timing SEI message - */ - SEI_PicStructType sei_pic_struct; - - /** - * Complement sei_pic_struct - * SEI_PIC_STRUCT_TOP_BOTTOM and SEI_PIC_STRUCT_BOTTOM_TOP indicate interlaced frames. - * However, soft telecined frames may have these values. - * This is used in an attempt to flag soft telecine progressive. - */ - int prev_interlaced_frame; - - /** - * Bit set of clock types for fields/frames in picture timing SEI message. - * For each found ct_type, appropriate bit is set (e.g., bit 1 for - * interlaced). - */ - int sei_ct_type; - - /** - * dpb_output_delay in picture timing SEI message, see H.264 C.2.2 - */ - int sei_dpb_output_delay; - - /** - * cpb_removal_delay in picture timing SEI message, see H.264 C.1.2 - */ - int sei_cpb_removal_delay; - - /** - * recovery_frame_cnt from SEI message - * - * Set to -1 if no recovery point SEI message found or to number of frames - * before playback synchronizes. Frames having recovery point are key - * frames. - */ - int sei_recovery_frame_cnt; - - int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag - int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag - - // Timestamp stuff - int sei_buffering_period_present; ///< Buffering period SEI flag - int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs - - //SVQ3 specific fields - int halfpel_flag; - int thirdpel_flag; - int unknown_svq3_flag; - int next_slice_index; - uint32_t svq3_watermark_key; -}H264Context; - - -extern const uint8_t ff_h264_chroma_qp[52]; - -void ff_svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp); - -void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc); - -/** - * Decode SEI - */ -int ff_h264_decode_sei(H264Context *h); - -/** - * Decode SPS - */ -int ff_h264_decode_seq_parameter_set(H264Context *h); - -/** - * Decode PPS - */ -int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length); - -/** - * 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? - * @return decoded bytes, might be src+1 if no escapes - */ -const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length); - -/** - * identifies the exact end of the bitstream - * @return the length of the trailing, or 0 if damaged - */ -int ff_h264_decode_rbsp_trailing(H264Context *h, const uint8_t *src); - -/** - * frees any data that may have been allocated in the H264 context like SPS, PPS etc. - */ -av_cold void ff_h264_free_context(H264Context *h); - -/** - * reconstructs bitstream slice_type. - */ -int ff_h264_get_slice_type(const H264Context *h); - -/** - * allocates tables. - * needs width/height - */ -int ff_h264_alloc_tables(H264Context *h); - -/** - * fills the default_ref_list. - */ -int ff_h264_fill_default_ref_list(H264Context *h); - -int ff_h264_decode_ref_pic_list_reordering(H264Context *h); -void ff_h264_fill_mbaff_ref_list(H264Context *h); -void ff_h264_remove_all_refs(H264Context *h); - -/** - * Executes the reference picture marking (memory management control operations). - */ -int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count); - -int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb); - - -/** - * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra4x4_pred_mode(H264Context *h); - -/** - * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode); - -void ff_h264_write_back_intra_pred_mode(H264Context *h); -void ff_h264_hl_decode_mb(H264Context *h); -int ff_h264_frame_start(H264Context *h); -av_cold int ff_h264_decode_init(AVCodecContext *avctx); -av_cold int ff_h264_decode_end(AVCodecContext *avctx); -av_cold void ff_h264_decode_init_vlc(void); - -/** - * decodes a macroblock - * @return 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed - */ -int ff_h264_decode_mb_cavlc(H264Context *h); - -/** - * decodes a CABAC coded macroblock - * @return 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed - */ -int ff_h264_decode_mb_cabac(H264Context *h); - -void ff_h264_init_cabac_states(H264Context *h); - -void ff_h264_direct_dist_scale_factor(H264Context * const h); -void ff_h264_direct_ref_list_init(H264Context * const h); -void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type); - -void ff_h264_filter_mb_fast( 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); -void ff_h264_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); - -/** - * Reset SEI values at the beginning of the frame. - * - * @param h H.264 context. - */ -void ff_h264_reset_sei(H264Context *h); - - -/* -o-o o-o - / / / -o-o o-o - ,---' -o-o o-o - / / / -o-o o-o -*/ -//This table must be here because scan8[constant] must be known at compiletime -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 av_always_inline uint32_t pack16to32(int a, int b){ -#if HAVE_BIGENDIAN - return (b&0xFFFF) + (a<<16); -#else - return (a&0xFFFF) + (b<<16); -#endif -} - -static av_always_inline uint16_t pack8to16(int a, int b){ -#if HAVE_BIGENDIAN - return (b&0xFF) + (a<<8); -#else - return (a&0xFF) + (b<<8); -#endif -} - -/** - * gets the chroma qp. - */ -static inline int get_chroma_qp(H264Context *h, int t, int qscale){ - return h->pps.chroma_qp_table[t][qscale]; -} - -static inline void pred_pskip_motion(H264Context * const h, int * const mx, int * const my); - -static void fill_decode_neighbors(H264Context *h, int mb_type){ - MpegEncContext * const s = &h->s; - const int mb_xy= h->mb_xy; - int topleft_xy, top_xy, topright_xy, left_xy[2]; - static const uint8_t left_block_options[4][16]={ - {0,1,2,3,7,10,8,11,7+0*8, 7+1*8, 7+2*8, 7+3*8, 2+0*8, 2+3*8, 2+1*8, 2+2*8}, - {2,2,3,3,8,11,8,11,7+2*8, 7+2*8, 7+3*8, 7+3*8, 2+1*8, 2+2*8, 2+1*8, 2+2*8}, - {0,0,1,1,7,10,7,10,7+0*8, 7+0*8, 7+1*8, 7+1*8, 2+0*8, 2+3*8, 2+0*8, 2+3*8}, - {0,2,0,2,7,10,7,10,7+0*8, 7+2*8, 7+0*8, 7+2*8, 2+0*8, 2+3*8, 2+0*8, 2+3*8} - }; - - h->topleft_partition= -1; - - top_xy = mb_xy - (s->mb_stride << MB_FIELD); - - /* Wow, what a mess, why didn't they simplify the interlacing & intra - * stuff, I can't imagine that these complex rules are worth it. */ - - topleft_xy = top_xy - 1; - topright_xy= top_xy + 1; - left_xy[1] = left_xy[0] = mb_xy-1; - h->left_block = left_block_options[0]; - if(FRAME_MBAFF){ - const int left_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[mb_xy-1]); - const int curr_mb_field_flag = IS_INTERLACED(mb_type); - if(s->mb_y&1){ - if (left_mb_field_flag != curr_mb_field_flag) { - left_xy[1] = left_xy[0] = mb_xy - s->mb_stride - 1; - if (curr_mb_field_flag) { - left_xy[1] += s->mb_stride; - h->left_block = left_block_options[3]; - } else { - topleft_xy += s->mb_stride; - // take top left mv from the middle of the mb, as opposed to all other modes which use the bottom right partition - h->topleft_partition = 0; - h->left_block = left_block_options[1]; - } - } - }else{ - if(curr_mb_field_flag){ - topleft_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy - 1]>>7)&1)-1); - topright_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy + 1]>>7)&1)-1); - top_xy += s->mb_stride & (((s->current_picture.mb_type[top_xy ]>>7)&1)-1); - } - if (left_mb_field_flag != curr_mb_field_flag) { - if (curr_mb_field_flag) { - left_xy[1] += s->mb_stride; - h->left_block = left_block_options[3]; - } else { - h->left_block = left_block_options[2]; - } - } - } - } - - h->topleft_mb_xy = topleft_xy; - h->top_mb_xy = top_xy; - h->topright_mb_xy= topright_xy; - h->left_mb_xy[0] = left_xy[0]; - h->left_mb_xy[1] = left_xy[1]; - //FIXME do we need all in the context? - - h->topleft_type = s->current_picture.mb_type[topleft_xy] ; - h->top_type = s->current_picture.mb_type[top_xy] ; - h->topright_type= s->current_picture.mb_type[topright_xy]; - h->left_type[0] = s->current_picture.mb_type[left_xy[0]] ; - h->left_type[1] = s->current_picture.mb_type[left_xy[1]] ; - - if(FMO){ - if(h->slice_table[topleft_xy ] != h->slice_num) h->topleft_type = 0; - if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0; - if(h->slice_table[left_xy[0] ] != h->slice_num) h->left_type[0] = h->left_type[1] = 0; - }else{ - if(h->slice_table[topleft_xy ] != h->slice_num){ - h->topleft_type = 0; - if(h->slice_table[top_xy ] != h->slice_num) h->top_type = 0; - if(h->slice_table[left_xy[0] ] != h->slice_num) h->left_type[0] = h->left_type[1] = 0; - } - } - if(h->slice_table[topright_xy] != h->slice_num) h->topright_type= 0; -} - -static void fill_decode_caches(H264Context *h, int mb_type){ - MpegEncContext * const s = &h->s; - int topleft_xy, top_xy, topright_xy, left_xy[2]; - int topleft_type, top_type, topright_type, left_type[2]; - const uint8_t * left_block= h->left_block; - int i; - - topleft_xy = h->topleft_mb_xy ; - top_xy = h->top_mb_xy ; - topright_xy = h->topright_mb_xy; - left_xy[0] = h->left_mb_xy[0] ; - left_xy[1] = h->left_mb_xy[1] ; - topleft_type = h->topleft_type ; - top_type = h->top_type ; - topright_type= h->topright_type ; - left_type[0] = h->left_type[0] ; - left_type[1] = h->left_type[1] ; - - if(!IS_SKIP(mb_type)){ - if(IS_INTRA(mb_type)){ - int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1; - h->topleft_samples_available= - h->top_samples_available= - h->left_samples_available= 0xFFFF; - h->topright_samples_available= 0xEEEA; - - if(!(top_type & type_mask)){ - h->topleft_samples_available= 0xB3FF; - h->top_samples_available= 0x33FF; - h->topright_samples_available= 0x26EA; - } - if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){ - if(IS_INTERLACED(mb_type)){ - if(!(left_type[0] & type_mask)){ - h->topleft_samples_available&= 0xDFFF; - h->left_samples_available&= 0x5FFF; - } - if(!(left_type[1] & type_mask)){ - h->topleft_samples_available&= 0xFF5F; - h->left_samples_available&= 0xFF5F; - } - }else{ - int left_typei = s->current_picture.mb_type[left_xy[0] + s->mb_stride]; - - assert(left_xy[0] == left_xy[1]); - if(!((left_typei & type_mask) && (left_type[0] & type_mask))){ - h->topleft_samples_available&= 0xDF5F; - h->left_samples_available&= 0x5F5F; - } - } - }else{ - if(!(left_type[0] & type_mask)){ - h->topleft_samples_available&= 0xDF5F; - h->left_samples_available&= 0x5F5F; - } - } - - if(!(topleft_type & type_mask)) - h->topleft_samples_available&= 0x7FFF; - - if(!(topright_type & type_mask)) - h->topright_samples_available&= 0xFBFF; - - if(IS_INTRA4x4(mb_type)){ - if(IS_INTRA4x4(top_type)){ - AV_COPY32(h->intra4x4_pred_mode_cache+4+8*0, h->intra4x4_pred_mode + h->mb2br_xy[top_xy]); - }else{ - 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]= 2 - 3*!(top_type & type_mask); - } - for(i=0; i<2; i++){ - if(IS_INTRA4x4(left_type[i])){ - int8_t *mode= h->intra4x4_pred_mode + h->mb2br_xy[left_xy[i]]; - h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= mode[6-left_block[0+2*i]]; - h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= mode[6-left_block[1+2*i]]; - }else{ - h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= - h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= 2 - 3*!(left_type[i] & type_mask); - } - } - } - } - - -/* -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 (let us hope this is just a typo in the spec) - if(top_type){ - AV_COPY32(&h->non_zero_count_cache[4+8*0], &h->non_zero_count[top_xy][4+3*8]); - h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][1+1*8]; - h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][2+1*8]; - - h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][1+2*8]; - h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][2+2*8]; - }else { - 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]= - AV_WN32A(&h->non_zero_count_cache[4+8*0], CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040); - } - - 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[8+0+2*i]]; - h->non_zero_count_cache[3+8*2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]]; - h->non_zero_count_cache[0+8*1 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+4+2*i]]; - h->non_zero_count_cache[0+8*4 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+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]= CABAC && !IS_INTRA(mb_type) ? 0 : 64; - } - } - - if( CABAC ) { - // top_cbp - if(top_type) { - h->top_cbp = h->cbp_table[top_xy]; - } else { - h->top_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F; - } - // left_cbp - if (left_type[0]) { - h->left_cbp = (h->cbp_table[left_xy[0]] & 0x1f0) - | ((h->cbp_table[left_xy[0]]>>(left_block[0]&(~1)))&2) - | (((h->cbp_table[left_xy[1]]>>(left_block[2]&(~1)))&2) << 2); - } else { - h->left_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F; - } - } - } - -#if 1 - if(IS_INTER(mb_type) || (IS_DIRECT(mb_type) && h->direct_spatial_mv_pred)){ - int list; - for(list=0; listlist_count; list++){ - if(!USES_LIST(mb_type, list)){ - /*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; - } - assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)); - - 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; - AV_COPY128(h->mv_cache[list][scan8[0] + 0 - 1*8], s->current_picture.motion_val[list][b_xy + 0]); - h->ref_cache[list][scan8[0] + 0 - 1*8]= - h->ref_cache[list][scan8[0] + 1 - 1*8]= s->current_picture.ref_index[list][4*top_xy + 2]; - h->ref_cache[list][scan8[0] + 2 - 1*8]= - h->ref_cache[list][scan8[0] + 3 - 1*8]= s->current_picture.ref_index[list][4*top_xy + 3]; - }else{ - AV_ZERO128(h->mv_cache[list][scan8[0] + 0 - 1*8]); - AV_WN32A(&h->ref_cache[list][scan8[0] + 0 - 1*8], ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101); - } - - if(mb_type & (MB_TYPE_16x8|MB_TYPE_8x8)){ - for(i=0; i<2; i++){ - int cache_idx = scan8[0] - 1 + i*2*8; - if(USES_LIST(left_type[i], list)){ - const int b_xy= h->mb2b_xy[left_xy[i]] + 3; - const int b8_xy= 4*left_xy[i] + 1; - AV_COPY32(h->mv_cache[list][cache_idx ], s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0+i*2]]); - AV_COPY32(h->mv_cache[list][cache_idx+8], s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[1+i*2]]); - h->ref_cache[list][cache_idx ]= s->current_picture.ref_index[list][b8_xy + (left_block[0+i*2]&~1)]; - h->ref_cache[list][cache_idx+8]= s->current_picture.ref_index[list][b8_xy + (left_block[1+i*2]&~1)]; - }else{ - AV_ZERO32(h->mv_cache [list][cache_idx ]); - AV_ZERO32(h->mv_cache [list][cache_idx+8]); - h->ref_cache[list][cache_idx ]= - h->ref_cache[list][cache_idx+8]= (left_type[i]) ? LIST_NOT_USED : PART_NOT_AVAILABLE; - } - } - }else{ - if(USES_LIST(left_type[0], list)){ - const int b_xy= h->mb2b_xy[left_xy[0]] + 3; - const int b8_xy= 4*left_xy[0] + 1; - AV_COPY32(h->mv_cache[list][scan8[0] - 1], s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0]]); - h->ref_cache[list][scan8[0] - 1]= s->current_picture.ref_index[list][b8_xy + (left_block[0]&~1)]; - }else{ - AV_ZERO32(h->mv_cache [list][scan8[0] - 1]); - h->ref_cache[list][scan8[0] - 1]= left_type[0] ? 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; - AV_COPY32(h->mv_cache[list][scan8[0] + 4 - 1*8], s->current_picture.motion_val[list][b_xy]); - h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][4*topright_xy + 2]; - }else{ - AV_ZERO32(h->mv_cache [list][scan8[0] + 4 - 1*8]); - h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; - } - if(h->ref_cache[list][scan8[0] + 4 - 1*8] < 0){ - if(USES_LIST(topleft_type, list)){ - const int b_xy = h->mb2b_xy [topleft_xy] + 3 + h->b_stride + (h->topleft_partition & 2*h->b_stride); - const int b8_xy= 4*topleft_xy + 1 + (h->topleft_partition & 2); - AV_COPY32(h->mv_cache[list][scan8[0] - 1 - 1*8], 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{ - AV_ZERO32(h->mv_cache[list][scan8[0] - 1 - 1*8]); - h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; - } - } - - if((mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2)) && !FRAME_MBAFF) - continue; - - if(!(mb_type&(MB_TYPE_SKIP|MB_TYPE_DIRECT2))) { - h->ref_cache[list][scan8[4 ]] = - h->ref_cache[list][scan8[12]] = PART_NOT_AVAILABLE; - AV_ZERO32(h->mv_cache [list][scan8[4 ]]); - AV_ZERO32(h->mv_cache [list][scan8[12]]); - - if( CABAC ) { - /* XXX beurk, Load mvd */ - if(USES_LIST(top_type, list)){ - const int b_xy= h->mb2br_xy[top_xy]; - AV_COPY64(h->mvd_cache[list][scan8[0] + 0 - 1*8], h->mvd_table[list][b_xy + 0]); - }else{ - AV_ZERO64(h->mvd_cache[list][scan8[0] + 0 - 1*8]); - } - if(USES_LIST(left_type[0], list)){ - const int b_xy= h->mb2br_xy[left_xy[0]] + 6; - AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 0*8], h->mvd_table[list][b_xy - left_block[0]]); - AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 1*8], h->mvd_table[list][b_xy - left_block[1]]); - }else{ - AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 0*8]); - AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 1*8]); - } - if(USES_LIST(left_type[1], list)){ - const int b_xy= h->mb2br_xy[left_xy[1]] + 6; - AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 2*8], h->mvd_table[list][b_xy - left_block[2]]); - AV_COPY16(h->mvd_cache[list][scan8[0] - 1 + 3*8], h->mvd_table[list][b_xy - left_block[3]]); - }else{ - AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 2*8]); - AV_ZERO16(h->mvd_cache [list][scan8[0] - 1 + 3*8]); - } - AV_ZERO16(h->mvd_cache [list][scan8[4 ]]); - AV_ZERO16(h->mvd_cache [list][scan8[12]]); - if(h->slice_type_nos == FF_B_TYPE){ - fill_rectangle(&h->direct_cache[scan8[0]], 4, 4, 8, MB_TYPE_16x16>>1, 1); - - if(IS_DIRECT(top_type)){ - AV_WN32A(&h->direct_cache[scan8[0] - 1*8], 0x01010101u*(MB_TYPE_DIRECT2>>1)); - }else if(IS_8X8(top_type)){ - int b8_xy = 4*top_xy; - h->direct_cache[scan8[0] + 0 - 1*8]= h->direct_table[b8_xy + 2]; - h->direct_cache[scan8[0] + 2 - 1*8]= h->direct_table[b8_xy + 3]; - }else{ - AV_WN32A(&h->direct_cache[scan8[0] - 1*8], 0x01010101*(MB_TYPE_16x16>>1)); - } - - if(IS_DIRECT(left_type[0])) - h->direct_cache[scan8[0] - 1 + 0*8]= MB_TYPE_DIRECT2>>1; - else if(IS_8X8(left_type[0])) - h->direct_cache[scan8[0] - 1 + 0*8]= h->direct_table[4*left_xy[0] + 1 + (left_block[0]&~1)]; - else - h->direct_cache[scan8[0] - 1 + 0*8]= MB_TYPE_16x16>>1; - - if(IS_DIRECT(left_type[1])) - h->direct_cache[scan8[0] - 1 + 2*8]= MB_TYPE_DIRECT2>>1; - else if(IS_8X8(left_type[1])) - h->direct_cache[scan8[0] - 1 + 2*8]= h->direct_table[4*left_xy[1] + 1 + (left_block[2]&~1)]; - else - h->direct_cache[scan8[0] - 1 + 2*8]= MB_TYPE_16x16>>1; - } - } - } - if(FRAME_MBAFF){ -#define MAP_MVS\ - MAP_F2F(scan8[0] - 1 - 1*8, topleft_type)\ - MAP_F2F(scan8[0] + 0 - 1*8, top_type)\ - MAP_F2F(scan8[0] + 1 - 1*8, top_type)\ - MAP_F2F(scan8[0] + 2 - 1*8, top_type)\ - MAP_F2F(scan8[0] + 3 - 1*8, top_type)\ - MAP_F2F(scan8[0] + 4 - 1*8, topright_type)\ - MAP_F2F(scan8[0] - 1 + 0*8, left_type[0])\ - MAP_F2F(scan8[0] - 1 + 1*8, left_type[0])\ - MAP_F2F(scan8[0] - 1 + 2*8, left_type[1])\ - MAP_F2F(scan8[0] - 1 + 3*8, left_type[1]) - if(MB_FIELD){ -#define MAP_F2F(idx, mb_type)\ - if(!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\ - h->ref_cache[list][idx] <<= 1;\ - h->mv_cache[list][idx][1] /= 2;\ - h->mvd_cache[list][idx][1] >>=1;\ - } - MAP_MVS -#undef MAP_F2F - }else{ -#define MAP_F2F(idx, mb_type)\ - if(IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\ - h->ref_cache[list][idx] >>= 1;\ - h->mv_cache[list][idx][1] <<= 1;\ - h->mvd_cache[list][idx][1] <<= 1;\ - } - MAP_MVS -#undef MAP_F2F - } - } - } - } -#endif - - h->neighbor_transform_size= !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[0]); -} - -/** - * 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(h->s.avctx, "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){ - const int mb_xy= h->mb_xy; - - AV_COPY64(&h->non_zero_count[mb_xy][ 0], &h->non_zero_count_cache[0+8*1]); - AV_COPY64(&h->non_zero_count[mb_xy][ 8], &h->non_zero_count_cache[0+8*2]); - AV_COPY32(&h->non_zero_count[mb_xy][16], &h->non_zero_count_cache[0+8*5]); - AV_COPY32(&h->non_zero_count[mb_xy][20], &h->non_zero_count_cache[4+8*3]); - AV_COPY64(&h->non_zero_count[mb_xy][24], &h->non_zero_count_cache[0+8*4]); -} - -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; //try mb2b(8)_xy - const int b8_xy= 4*h->mb_xy; - int list; - - if(!USES_LIST(mb_type, 0)) - fill_rectangle(&s->current_picture.ref_index[0][b8_xy], 2, 2, 2, (uint8_t)LIST_NOT_USED, 1); - - for(list=0; listlist_count; list++){ - int y, b_stride; - int16_t (*mv_dst)[2]; - int16_t (*mv_src)[2]; - - if(!USES_LIST(mb_type, list)) - continue; - - b_stride = h->b_stride; - mv_dst = &s->current_picture.motion_val[list][b_xy]; - mv_src = &h->mv_cache[list][scan8[0]]; - for(y=0; y<4; y++){ - AV_COPY128(mv_dst + y*b_stride, mv_src + 8*y); - } - if( CABAC ) { - uint8_t (*mvd_dst)[2] = &h->mvd_table[list][FMO ? 8*h->mb_xy : h->mb2br_xy[h->mb_xy]]; - uint8_t (*mvd_src)[2] = &h->mvd_cache[list][scan8[0]]; - if(IS_SKIP(mb_type)) - AV_ZERO128(mvd_dst); - else{ - AV_COPY64(mvd_dst, mvd_src + 8*3); - AV_COPY16(mvd_dst + 3 + 3, mvd_src + 3 + 8*0); - AV_COPY16(mvd_dst + 3 + 2, mvd_src + 3 + 8*1); - AV_COPY16(mvd_dst + 3 + 1, mvd_src + 3 + 8*2); - } - } - - { - int8_t *ref_index = &s->current_picture.ref_index[list][b8_xy]; - ref_index[0+0*2]= h->ref_cache[list][scan8[0]]; - ref_index[1+0*2]= h->ref_cache[list][scan8[4]]; - ref_index[0+1*2]= h->ref_cache[list][scan8[8]]; - ref_index[1+1*2]= h->ref_cache[list][scan8[12]]; - } - } - - if(h->slice_type_nos == FF_B_TYPE && CABAC){ - if(IS_8X8(mb_type)){ - uint8_t *direct_table = &h->direct_table[4*h->mb_xy]; - direct_table[1] = h->sub_mb_type[1]>>1; - direct_table[2] = h->sub_mb_type[2]>>1; - direct_table[3] = h->sub_mb_type[3]>>1; - } - } -} - -static inline int get_dct8x8_allowed(H264Context *h){ - if(h->sps.direct_8x8_inference_flag) - return !(AV_RN64A(h->sub_mb_type) & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8 )*0x0001000100010001ULL)); - else - return !(AV_RN64A(h->sub_mb_type) & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8|MB_TYPE_DIRECT2)*0x0001000100010001ULL)); -} - -/** - * decodes a P_SKIP or B_SKIP macroblock - */ -static void decode_mb_skip(H264Context *h){ - MpegEncContext * const s = &h->s; - const int mb_xy= h->mb_xy; - int mb_type=0; - - memset(h->non_zero_count[mb_xy], 0, 32); - memset(h->non_zero_count_cache + 8, 0, 8*5); //FIXME ugly, remove pfui - - if(MB_FIELD) - mb_type|= MB_TYPE_INTERLACED; - - if( h->slice_type_nos == FF_B_TYPE ) - { - // just for fill_caches. pred_direct_motion will set the real mb_type - mb_type|= MB_TYPE_L0L1|MB_TYPE_DIRECT2|MB_TYPE_SKIP; - if(h->direct_spatial_mv_pred){ - fill_decode_neighbors(h, mb_type); - fill_decode_caches(h, mb_type); //FIXME check what is needed and what not ... - } - ff_h264_pred_direct_motion(h, &mb_type); - mb_type|= MB_TYPE_SKIP; - } - else - { - int mx, my; - mb_type|= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_SKIP; - - fill_decode_neighbors(h, mb_type); - fill_decode_caches(h, mb_type); //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); - } - - write_back_motion(h, mb_type); - s->current_picture.mb_type[mb_xy]= mb_type; - s->current_picture.qscale_table[mb_xy]= s->qscale; - h->slice_table[ mb_xy ]= h->slice_num; - h->prev_mb_skipped= 1; -} - -#include "h264_mvpred.h" //For pred_pskip_motion() - -#endif /* AVCODEC_H264_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_cabac.c b/tizen/distrib/ffmpeg/libavcodec/h264_cabac.c deleted file mode 100644 index 4858378..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_cabac.c +++ /dev/null @@ -1,1720 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... cabac decoding - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 cabac decoding. - * @author Michael Niedermayer - */ - -#define CABAC 1 - -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "h264.h" -#include "h264data.h" -#include "h264_mvpred.h" -#include "golomb.h" - -#include "cabac.h" -#if ARCH_X86 -#include "x86/h264_i386.h" -#endif - -//#undef NDEBUG -#include - -/* Cabac pre state table */ - -static const int8_t 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 int8_t 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 }, - } -}; - -void ff_h264_init_cabac_states(H264Context *h) { - MpegEncContext * const s = &h->s; - int i; - const int8_t (*tab)[2]; - - if( h->slice_type_nos == FF_I_TYPE ) tab = cabac_context_init_I; - else tab = cabac_context_init_PB[h->cabac_init_idc]; - - /* calculate pre-state */ - for( i= 0; i < 460; i++ ) { - int pre = 2*(((tab[i][0] * s->qscale) >>4 ) + tab[i][1]) - 127; - - pre^= pre>>31; - if(pre > 124) - pre= 124 + (pre&1); - - h->cabac_state[i] = pre; - } -} - -static int decode_cabac_field_decoding_flag(H264Context *h) { - MpegEncContext * const s = &h->s; - const long mbb_xy = h->mb_xy - 2L*s->mb_stride; - - unsigned long ctx = 0; - - ctx += h->mb_field_decoding_flag & !!s->mb_x; //for FMO:(s->current_picture.mb_type[mba_xy]>>7)&(h->slice_table[mba_xy] == h->slice_num); - ctx += (s->current_picture.mb_type[mbb_xy]>>7)&(h->slice_table[mbb_xy] == h->slice_num); - - return get_cabac_noinline( &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){ - int ctx=0; - if( h->left_type[0] & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)) - ctx++; - if( h->top_type & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)) - ctx++; - if( get_cabac_noinline( &h->cabac, &state[ctx] ) == 0 ) - return 0; /* I4x4 */ - state += 2; - }else{ - if( get_cabac_noinline( &h->cabac, state ) == 0 ) - return 0; /* I4x4 */ - } - - if( get_cabac_terminate( &h->cabac ) ) - return 25; /* PCM */ - - mb_type = 1; /* I16x16 */ - mb_type += 12 * get_cabac_noinline( &h->cabac, &state[1] ); /* cbp_luma != 0 */ - if( get_cabac_noinline( &h->cabac, &state[2] ) ) /* cbp_chroma */ - mb_type += 4 + 4 * get_cabac_noinline( &h->cabac, &state[2+intra_slice] ); - mb_type += 2 * get_cabac_noinline( &h->cabac, &state[3+intra_slice] ); - mb_type += 1 * get_cabac_noinline( &h->cabac, &state[3+2*intra_slice] ); - return mb_type; -} - -static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) { - MpegEncContext * const s = &h->s; - int mba_xy, mbb_xy; - int ctx = 0; - - if(FRAME_MBAFF){ //FIXME merge with the stuff in fill_caches? - int mb_xy = mb_x + (mb_y&~1)*s->mb_stride; - mba_xy = mb_xy - 1; - if( (mb_y&1) - && h->slice_table[mba_xy] == h->slice_num - && MB_FIELD == !!IS_INTERLACED( s->current_picture.mb_type[mba_xy] ) ) - mba_xy += s->mb_stride; - if( MB_FIELD ){ - mbb_xy = mb_xy - s->mb_stride; - if( !(mb_y&1) - && h->slice_table[mbb_xy] == h->slice_num - && IS_INTERLACED( s->current_picture.mb_type[mbb_xy] ) ) - mbb_xy -= s->mb_stride; - }else - mbb_xy = mb_x + (mb_y-1)*s->mb_stride; - }else{ - int mb_xy = h->mb_xy; - mba_xy = mb_xy - 1; - mbb_xy = mb_xy - (s->mb_stride << FIELD_PICTURE); - } - - 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_nos == FF_B_TYPE ) - ctx += 13; - return get_cabac_noinline( &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] ); - - return mode + ( mode >= pred_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->left_type[0] && h->chroma_pred_mode_table[mba_xy] != 0 ) - ctx++; - - if( h->top_type && h->chroma_pred_mode_table[mbb_xy] != 0 ) - ctx++; - - if( get_cabac_noinline( &h->cabac, &h->cabac_state[64+ctx] ) == 0 ) - return 0; - - if( get_cabac_noinline( &h->cabac, &h->cabac_state[64+3] ) == 0 ) - return 1; - if( get_cabac_noinline( &h->cabac, &h->cabac_state[64+3] ) == 0 ) - return 2; - else - return 3; -} - -static int decode_cabac_mb_cbp_luma( H264Context *h) { - int cbp_b, cbp_a, ctx, cbp = 0; - - cbp_a = h->left_cbp; - cbp_b = h->top_cbp; - - ctx = !(cbp_a & 0x02) + 2 * !(cbp_b & 0x04); - cbp += get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]); - ctx = !(cbp & 0x01) + 2 * !(cbp_b & 0x08); - cbp += get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 1; - ctx = !(cbp_a & 0x08) + 2 * !(cbp & 0x01); - cbp += get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 2; - ctx = !(cbp & 0x04) + 2 * !(cbp & 0x02); - cbp += get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 3; - 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_noinline( &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_noinline( &h->cabac, &h->cabac_state[77 + ctx] ); -} - -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 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_nos == FF_B_TYPE) { - if( refa > 0 && !(h->direct_cache[scan8[n] - 1]&(MB_TYPE_DIRECT2>>1)) ) - ctx++; - if( refb > 0 && !(h->direct_cache[scan8[n] - 8]&(MB_TYPE_DIRECT2>>1)) ) - ctx += 2; - } else { - if( refa > 0 ) - ctx++; - if( refb > 0 ) - ctx += 2; - } - - while( get_cabac( &h->cabac, &h->cabac_state[54+ctx] ) ) { - ref++; - ctx = (ctx>>2)+4; - if(ref >= 32 /*h->ref_list[list]*/){ - return -1; - } - } - return ref; -} - -static int decode_cabac_mb_mvd( H264Context *h, int ctxbase, int amvd, int *mvda) { - int mvd; - - if(!get_cabac(&h->cabac, &h->cabac_state[ctxbase+((amvd-3)>>(INT_BIT-1))+((amvd-33)>>(INT_BIT-1))+2])){ -// if(!get_cabac(&h->cabac, &h->cabac_state[ctxbase+(amvd>2)+(amvd>32)])){ - *mvda= 0; - return 0; - } - - mvd= 1; - ctxbase+= 3; - while( mvd < 9 && get_cabac( &h->cabac, &h->cabac_state[ctxbase] ) ) { - if( mvd < 4 ) - ctxbase++; - mvd++; - } - - if( mvd >= 9 ) { - int k = 3; - while( get_cabac_bypass( &h->cabac ) ) { - mvd += 1 << k; - k++; - if(k>24){ - av_log(h->s.avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n"); - return INT_MIN; - } - } - while( k-- ) { - mvd += get_cabac_bypass( &h->cabac )<cabac, -mvd ); -} - -#define DECODE_CABAC_MB_MVD( h, list, n )\ -{\ - int amvd0 = h->mvd_cache[list][scan8[n] - 1][0] +\ - h->mvd_cache[list][scan8[n] - 8][0];\ - int amvd1 = h->mvd_cache[list][scan8[n] - 1][1] +\ - h->mvd_cache[list][scan8[n] - 8][1];\ -\ - mx += decode_cabac_mb_mvd( h, 40, amvd0, &mpx );\ - my += decode_cabac_mb_mvd( h, 47, amvd1, &mpy );\ -} - -static av_always_inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx, int is_dc ) { - int nza, nzb; - int ctx = 0; - - if( is_dc ) { - if( cat == 0 ) { - nza = h->left_cbp&0x100; - nzb = h-> top_cbp&0x100; - } else { - nza = (h->left_cbp>>(6+idx))&0x01; - nzb = (h-> top_cbp>>(6+idx))&0x01; - } - } else { - assert(cat == 1 || cat == 2 || cat == 4); - nza = h->non_zero_count_cache[scan8[idx] - 1]; - nzb = h->non_zero_count_cache[scan8[idx] - 8]; - } - - if( nza > 0 ) - ctx++; - - if( nzb > 0 ) - ctx += 2; - - return ctx + 4 * cat; -} - -DECLARE_ASM_CONST(1, uint8_t, 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 -}; - -static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff, int is_dc ) { - static const int significant_coeff_flag_offset[2][6] = { - { 105+0, 105+15, 105+29, 105+44, 105+47, 402 }, - { 277+0, 277+15, 277+29, 277+44, 277+47, 436 } - }; - static const int last_coeff_flag_offset[2][6] = { - { 166+0, 166+15, 166+29, 166+44, 166+47, 417 }, - { 338+0, 338+15, 338+29, 338+44, 338+47, 451 } - }; - static const int coeff_abs_level_m1_offset[6] = { - 227+0, 227+10, 227+20, 227+30, 227+39, 426 - }; - static const uint8_t significant_coeff_flag_offset_8x8[2][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 }, - { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5, - 6, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,11,12,11, - 9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9, - 9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14 } - }; - /* node ctx: 0..3: abslevel1 (with abslevelgt1 == 0). - * 4..7: abslevelgt1 + 3 (and abslevel1 doesn't matter). - * map node ctx => cabac ctx for level=1 */ - static const uint8_t coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 }; - /* map node ctx => cabac ctx for level>1 */ - static const uint8_t coeff_abs_levelgt1_ctx[8] = { 5, 5, 5, 5, 6, 7, 8, 9 }; - static const uint8_t coeff_abs_level_transition[2][8] = { - /* update node ctx after decoding a level=1 */ - { 1, 2, 3, 3, 4, 5, 6, 7 }, - /* update node ctx after decoding a level>1 */ - { 4, 4, 4, 4, 5, 6, 7, 7 } - }; - - int index[64]; - - int av_unused last; - int coeff_count = 0; - int node_ctx = 0; - - uint8_t *significant_coeff_ctx_base; - uint8_t *last_coeff_ctx_base; - uint8_t *abs_level_m1_ctx_base; - -#if !ARCH_X86 -#define CABAC_ON_STACK -#endif -#ifdef CABAC_ON_STACK -#define CC &cc - CABACContext cc; - cc.range = h->cabac.range; - cc.low = h->cabac.low; - cc.bytestream= h->cabac.bytestream; -#else -#define CC &h->cabac -#endif - - - /* cat: 0-> DC 16x16 n = 0 - * 1-> AC 16x16 n = luma4x4idx - * 2-> Luma4x4 n = luma4x4idx - * 3-> DC Chroma n = iCbCr - * 4-> AC Chroma n = 16 + 4 * iCbCr + chroma4x4idx - * 5-> Luma8x8 n = 4 * luma8x8idx - */ - - /* read coded block flag */ - if( is_dc || cat != 5 ) { - if( get_cabac( CC, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n, is_dc ) ] ) == 0 ) { - if( !is_dc ) - h->non_zero_count_cache[scan8[n]] = 0; - -#ifdef CABAC_ON_STACK - h->cabac.range = cc.range ; - h->cabac.low = cc.low ; - h->cabac.bytestream= cc.bytestream; -#endif - return; - } - } - - significant_coeff_ctx_base = h->cabac_state - + significant_coeff_flag_offset[MB_FIELD][cat]; - last_coeff_ctx_base = h->cabac_state - + last_coeff_flag_offset[MB_FIELD][cat]; - abs_level_m1_ctx_base = h->cabac_state - + coeff_abs_level_m1_offset[cat]; - - if( !is_dc && 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( CC, sig_ctx )) { \ - uint8_t *last_ctx = last_coeff_ctx_base + last_off; \ - index[coeff_count++] = last; \ - if( get_cabac( CC, last_ctx ) ) { \ - last= max_coeff; \ - break; \ - } \ - } \ - }\ - if( last == max_coeff -1 ) {\ - index[coeff_count++] = last;\ - } - const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD]; -#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) - coeff_count= decode_significance_8x8_x86(CC, significant_coeff_ctx_base, index, sig_off); - } else { - coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index); -#else - DECODE_SIGNIFICANCE( 63, sig_off[last], last_coeff_flag_offset_8x8[last] ); - } else { - DECODE_SIGNIFICANCE( max_coeff - 1, last, last ); -#endif - } - assert(coeff_count > 0); - - if( is_dc ) { - if( cat == 0 ) - h->cbp_table[h->mb_xy] |= 0x100; - else - h->cbp_table[h->mb_xy] |= 0x40 << n; - } else { - if( cat == 5 ) - fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1); - else { - assert( cat == 1 || cat == 2 || cat == 4 ); - h->non_zero_count_cache[scan8[n]] = coeff_count; - } - } - - do { - uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; - - int j= scantable[index[--coeff_count]]; - - if( get_cabac( CC, ctx ) == 0 ) { - node_ctx = coeff_abs_level_transition[0][node_ctx]; - if( is_dc ) { - block[j] = get_cabac_bypass_sign( CC, -1); - }else{ - block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; - } - } else { - int coeff_abs = 2; - ctx = coeff_abs_levelgt1_ctx[node_ctx] + abs_level_m1_ctx_base; - node_ctx = coeff_abs_level_transition[1][node_ctx]; - - while( coeff_abs < 15 && get_cabac( CC, ctx ) ) { - coeff_abs++; - } - - if( coeff_abs >= 15 ) { - int j = 0; - while( get_cabac_bypass( CC ) ) { - j++; - } - - coeff_abs=1; - while( j-- ) { - coeff_abs += coeff_abs + get_cabac_bypass( CC ); - } - coeff_abs+= 14; - } - - if( is_dc ) { - block[j] = get_cabac_bypass_sign( CC, -coeff_abs ); - }else{ - block[j] = (get_cabac_bypass_sign( CC, -coeff_abs ) * qmul[j] + 32) >> 6; - } - } - } while( coeff_count ); -#ifdef CABAC_ON_STACK - h->cabac.range = cc.range ; - h->cabac.low = cc.low ; - h->cabac.bytestream= cc.bytestream; -#endif - -} - -static void decode_cabac_residual_dc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, int max_coeff ) { - decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1); -} - -static void decode_cabac_residual_nondc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) { - decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0); -} - -/** - * decodes a macroblock - * @return 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed - */ -int ff_h264_decode_mb_cabac(H264Context *h) { - MpegEncContext * const s = &h->s; - int mb_xy; - int mb_type, partition_count, cbp = 0; - int dct8x8_allowed= h->pps.transform_8x8_mode; - - mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; - - tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); - if( h->slice_type_nos != FF_I_TYPE ) { - int skip; - /* a skipped mb needs the aff flag from the following mb */ - if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped ) - skip = h->next_mb_skipped; - else - skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y ); - /* read skip flags */ - if( skip ) { - if( FRAME_MBAFF && (s->mb_y&1)==0 ){ - s->current_picture.mb_type[mb_xy] = MB_TYPE_SKIP; - h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 ); - if(!h->next_mb_skipped) - h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(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(FRAME_MBAFF){ - if( (s->mb_y&1) == 0 ) - h->mb_mbaff = - h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h); - } - - h->prev_mb_skipped = 0; - - fill_decode_neighbors(h, -(MB_FIELD)); - - if( h->slice_type_nos == FF_B_TYPE ) { - int ctx = 0; - assert(h->slice_type_nos == FF_B_TYPE); - - if( !IS_DIRECT( h->left_type[0]-1 ) ) - ctx++; - if( !IS_DIRECT( h->top_type-1 ) ) - ctx++; - - if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+ctx] ) ){ - mb_type= 0; /* B_Direct_16x16 */ - }else if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+3] ) ) { - mb_type= 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ); /* B_L[01]_16x16 */ - }else{ - int bits; - bits = get_cabac_noinline( &h->cabac, &h->cabac_state[27+4] ) << 3; - bits+= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 2; - bits+= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 1; - bits+= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ); - if( bits < 8 ){ - mb_type= bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */ - }else if( bits == 13 ){ - mb_type= decode_cabac_intra_mb_type(h, 32, 0); - goto decode_intra_mb; - }else if( bits == 14 ){ - mb_type= 11; /* B_L1_L0_8x16 */ - }else if( bits == 15 ){ - mb_type= 22; /* B_8x8 */ - }else{ - bits= ( bits<<1 ) + get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ); - mb_type= bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */ - } - } - partition_count= b_mb_type_info[mb_type].partition_count; - mb_type= b_mb_type_info[mb_type].type; - } else if( h->slice_type_nos == FF_P_TYPE ) { - if( get_cabac_noinline( &h->cabac, &h->cabac_state[14] ) == 0 ) { - /* P-type */ - if( get_cabac_noinline( &h->cabac, &h->cabac_state[15] ) == 0 ) { - /* P_L0_D16x16, P_8x8 */ - mb_type= 3 * get_cabac_noinline( &h->cabac, &h->cabac_state[16] ); - } else { - /* P_L0_D8x16, P_L0_D16x8 */ - mb_type= 2 - get_cabac_noinline( &h->cabac, &h->cabac_state[17] ); - } - partition_count= p_mb_type_info[mb_type].partition_count; - mb_type= p_mb_type_info[mb_type].type; - } else { - mb_type= decode_cabac_intra_mb_type(h, 17, 0); - goto decode_intra_mb; - } - } else { - mb_type= decode_cabac_intra_mb_type(h, 3, 1); - if(h->slice_type == FF_SI_TYPE && mb_type) - mb_type--; - assert(h->slice_type_nos == FF_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(MB_FIELD) - mb_type |= MB_TYPE_INTERLACED; - - h->slice_table[ mb_xy ]= h->slice_num; - - if(IS_INTRA_PCM(mb_type)) { - const uint8_t *ptr; - - // We assume these blocks are very rare so we do not 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--; - if(CABAC_BITS==16){ - if(h->cabac.low&0x1FF) ptr--; - } - - // The pixels are stored in the same order as levels in h->mb array. - memcpy(h->mb, ptr, 256); ptr+=256; - if(CHROMA){ - memcpy(h->mb+128, ptr, 128); ptr+=128; - } - - 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; - // All coeffs are present - memset(h->non_zero_count[mb_xy], 16, 32); - s->current_picture.mb_type[mb_xy]= mb_type; - h->last_qscale_diff = 0; - return 0; - } - - if(MB_MBAFF){ - h->ref_count[0] <<= 1; - h->ref_count[1] <<= 1; - } - - fill_decode_caches(h, mb_type); - - if( IS_INTRA( mb_type ) ) { - int i, pred_mode; - if( IS_INTRA4x4( mb_type ) ) { - if( dct8x8_allowed && get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] ) ) { - 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] ] ); - } - } - ff_h264_write_back_intra_pred_mode(h); - if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1; - } else { - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode ); - if( h->intra16x16_pred_mode < 0 ) return -1; - } - if(CHROMA){ - h->chroma_pred_mode_table[mb_xy] = - pred_mode = decode_cabac_mb_chroma_pre_mode( h ); - - pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode ); - if( pred_mode < 0 ) return -1; - h->chroma_pred_mode= pred_mode; - } - } else if( partition_count == 4 ) { - int i, j, sub_partition_count[4], list, ref[2][4]; - - if( h->slice_type_nos == FF_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] | h->sub_mb_type[1] | - h->sub_mb_type[2] | h->sub_mb_type[3]) ) { - ff_h264_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; - for( i = 0; i < 4; i++ ) - fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, (h->sub_mb_type[i]>>1)&0xFF, 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 < h->list_count; list++ ) { - 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 ); - if(ref[list][i] >= (unsigned)h->ref_count[list]){ - av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], h->ref_count[list]); - return -1; - } - }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; listlist_count; list++){ - for(i=0; i<4; i++){ - h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]; - if(IS_DIRECT(h->sub_mb_type[i])){ - fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 2); - continue; - } - - 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] ]; - uint8_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ]; - pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my); - DECODE_CABAC_MB_MVD( h, list, index) - tprintf(s->avctx, "final mv:%d %d\n", mx, my); - - if(IS_SUB_8X8(sub_mb_type)){ - mv_cache[ 1 ][0]= - mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx; - mv_cache[ 1 ][1]= - mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my; - - mvd_cache[ 1 ][0]= - mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mpx; - mvd_cache[ 1 ][1]= - mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= mpy; - }else if(IS_SUB_8X4(sub_mb_type)){ - mv_cache[ 1 ][0]= mx; - mv_cache[ 1 ][1]= my; - - mvd_cache[ 1 ][0]= mpx; - mvd_cache[ 1 ][1]= mpy; - }else if(IS_SUB_4X8(sub_mb_type)){ - mv_cache[ 8 ][0]= mx; - mv_cache[ 8 ][1]= my; - - mvd_cache[ 8 ][0]= mpx; - mvd_cache[ 8 ][1]= mpy; - } - mv_cache[ 0 ][0]= mx; - mv_cache[ 0 ][1]= my; - - mvd_cache[ 0 ][0]= mpx; - mvd_cache[ 0 ][1]= mpy; - } - }else{ - fill_rectangle(h->mv_cache [list][ scan8[4*i] ], 2, 2, 8, 0, 4); - fill_rectangle(h->mvd_cache[list][ scan8[4*i] ], 2, 2, 8, 0, 2); - } - } - } - } else if( IS_DIRECT(mb_type) ) { - ff_h264_pred_direct_motion(h, &mb_type); - fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 2); - fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 2); - dct8x8_allowed &= h->sps.direct_8x8_inference_flag; - } else { - int list, i; - if(IS_16X16(mb_type)){ - for(list=0; listlist_count; list++){ - if(IS_DIR(mb_type, 0, list)){ - int ref; - if(h->ref_count[list] > 1){ - ref= decode_cabac_mb_ref(h, list, 0); - if(ref >= (unsigned)h->ref_count[list]){ - av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]); - return -1; - } - }else - ref=0; - fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1); - } - } - for(list=0; listlist_count; list++){ - if(IS_DIR(mb_type, 0, list)){ - int mx,my,mpx,mpy; - pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my); - DECODE_CABAC_MB_MVD( h, list, 0) - tprintf(s->avctx, "final mv:%d %d\n", mx, my); - - fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2); - fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); - } - } - } - else if(IS_16X8(mb_type)){ - for(list=0; listlist_count; list++){ - for(i=0; i<2; i++){ - if(IS_DIR(mb_type, i, list)){ - int ref; - if(h->ref_count[list] > 1){ - ref= decode_cabac_mb_ref( h, list, 8*i ); - if(ref >= (unsigned)h->ref_count[list]){ - av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]); - return -1; - } - }else - ref=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; listlist_count; list++){ - for(i=0; i<2; i++){ - if(IS_DIR(mb_type, i, list)){ - int mx,my,mpx,mpy; - pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my); - DECODE_CABAC_MB_MVD( h, list, 8*i) - tprintf(s->avctx, "final mv:%d %d\n", mx, my); - - fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2); - 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, 2); - fill_rectangle(h-> mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4); - } - } - } - }else{ - assert(IS_8X16(mb_type)); - for(list=0; listlist_count; list++){ - for(i=0; i<2; i++){ - if(IS_DIR(mb_type, i, list)){ //FIXME optimize - int ref; - if(h->ref_count[list] > 1){ - ref= decode_cabac_mb_ref( h, list, 4*i ); - if(ref >= (unsigned)h->ref_count[list]){ - av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]); - return -1; - } - }else - ref=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; listlist_count; list++){ - for(i=0; i<2; i++){ - if(IS_DIR(mb_type, i, list)){ - int mx,my,mpx,mpy; - pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my); - DECODE_CABAC_MB_MVD( h, list, 4*i) - - tprintf(s->avctx, "final mv:%d %d\n", mx, my); - fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2); - 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, 2); - 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 ); - if(CHROMA) - cbp |= decode_cabac_mb_cbp_chroma( h ) << 4; - } - - h->cbp_table[mb_xy] = h->cbp = cbp; - - if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) { - mb_type |= MB_TYPE_8x8DCT * get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] ); - } - s->current_picture.mb_type[mb_xy]= mb_type; - - if( cbp || IS_INTRA16x16( mb_type ) ) { - const uint8_t *scan, *scan8x8, *dc_scan; - const uint32_t *qmul; - - if(IS_INTERLACED(mb_type)){ - scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0; - scan= s->qscale ? h->field_scan : h->field_scan_q0; - dc_scan= luma_dc_field_scan; - }else{ - scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0; - scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0; - dc_scan= luma_dc_zigzag_scan; - } - - // decode_cabac_mb_dqp - if(get_cabac_noinline( &h->cabac, &h->cabac_state[60 + (h->last_qscale_diff != 0)])){ - int val = 1; - int ctx= 2; - - while( get_cabac_noinline( &h->cabac, &h->cabac_state[60 + ctx] ) ) { - ctx= 3; - val++; - if(val > 102){ //prevent infinite loop - 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; - } - } - - if( val&0x01 ) - val= (val + 1)>>1 ; - else - val= -((val + 1)>>1); - h->last_qscale_diff = val; - s->qscale += val; - if(((unsigned)s->qscale) > 51){ - if(s->qscale<0) s->qscale+= 52; - else s->qscale-= 52; - } - h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale); - h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale); - }else - h->last_qscale_diff=0; - - if( IS_INTRA16x16( mb_type ) ) { - int i; - //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" ); - decode_cabac_residual_dc( h, h->mb, 0, 0, dc_scan, 16); - - if( cbp&15 ) { - qmul = h->dequant4_coeff[0][s->qscale]; - for( i = 0; i < 16; i++ ) { - //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 AC:%d\n", i ); - decode_cabac_residual_nondc(h, h->mb + 16*i, 1, i, scan + 1, qmul, 15); - } - } 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); - } else { - qmul = h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale]; - for( i4x4 = 0; i4x4 < 4; i4x4++ ) { - const int index = 4*i8x8 + i4x4; - //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index ); -//START_TIMER - decode_cabac_residual_nondc(h, h->mb + 16*index, 2, index, scan, qmul, 16); -//STOP_TIMER("decode_residual") - } - } - } 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 ); - decode_cabac_residual_dc(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, 4); - } - } - - if( cbp&0x20 ) { - int c, i; - for( c = 0; c < 2; c++ ) { - qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[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 ); - decode_cabac_residual_nondc(h, h->mb + 16*index, 4, index, scan + 1, qmul, 15); - } - } - } 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; - h->last_qscale_diff = 0; - } - - s->current_picture.qscale_table[mb_xy]= s->qscale; - write_back_non_zero_count(h); - - if(MB_MBAFF){ - h->ref_count[0] >>= 1; - h->ref_count[1] >>= 1; - } - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_cavlc.c b/tizen/distrib/ffmpeg/libavcodec/h264_cavlc.c deleted file mode 100644 index 0475e94..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_cavlc.c +++ /dev/null @@ -1,1030 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... cavlc bitstream decoding - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 cavlc bitstream decoding. - * @author Michael Niedermayer - */ - -#define CABAC 0 - -#include "internal.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h264.h" -#include "h264data.h" // FIXME FIXME FIXME -#include "h264_mvpred.h" -#include "golomb.h" - -//#undef NDEBUG -#include - -static const uint8_t golomb_to_inter_cbp_gray[16]={ - 0, 1, 2, 4, 8, 3, 5,10,12,15, 7,11,13,14, 6, 9, -}; - -static const uint8_t golomb_to_intra4x4_cbp_gray[16]={ -15, 0, 7,11,13,14, 3, 5,10,12, 1, 2, 4, 8, 6, 9, -}; - -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}, -}; - -static VLC coeff_token_vlc[4]; -static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2]; -static const int coeff_token_vlc_tables_size[4]={520,332,280,256}; - -static VLC chroma_dc_coeff_token_vlc; -static VLC_TYPE chroma_dc_coeff_token_vlc_table[256][2]; -static const int chroma_dc_coeff_token_vlc_table_size = 256; - -static VLC total_zeros_vlc[15]; -static VLC_TYPE total_zeros_vlc_tables[15][512][2]; -static const int total_zeros_vlc_tables_size = 512; - -static VLC chroma_dc_total_zeros_vlc[3]; -static VLC_TYPE chroma_dc_total_zeros_vlc_tables[3][8][2]; -static const int chroma_dc_total_zeros_vlc_tables_size = 8; - -static VLC run_vlc[6]; -static VLC_TYPE run_vlc_tables[6][8][2]; -static const int run_vlc_tables_size = 8; - -static VLC run7_vlc; -static VLC_TYPE run7_vlc_table[96][2]; -static const int run7_vlc_table_size = 96; - -#define LEVEL_TAB_BITS 8 -static int8_t cavlc_level_tab[7][1<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(h->s.avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31); - - return i&31; -} - -static av_cold void init_cavlc_level_tab(void){ - int suffix_length, mask; - unsigned int i; - - for(suffix_length=0; suffix_length<7; suffix_length++){ - for(i=0; i<(1<>(LEVEL_TAB_BITS-prefix-1-suffix_length)) - (1<>1) ^ mask) - mask; - if(prefix + 1 + suffix_length <= LEVEL_TAB_BITS){ - cavlc_level_tab[suffix_length][i][0]= level_code; - cavlc_level_tab[suffix_length][i][1]= prefix + 1 + suffix_length; - }else if(prefix + 1 <= LEVEL_TAB_BITS){ - cavlc_level_tab[suffix_length][i][0]= prefix+100; - cavlc_level_tab[suffix_length][i][1]= prefix + 1; - }else{ - cavlc_level_tab[suffix_length][i][0]= LEVEL_TAB_BITS+100; - cavlc_level_tab[suffix_length][i][1]= LEVEL_TAB_BITS; - } - } - } -} - -av_cold void ff_h264_decode_init_vlc(void){ - static int done = 0; - - if (!done) { - int i; - int offset; - done = 1; - - chroma_dc_coeff_token_vlc.table = chroma_dc_coeff_token_vlc_table; - chroma_dc_coeff_token_vlc.table_allocated = chroma_dc_coeff_token_vlc_table_size; - 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, - INIT_VLC_USE_NEW_STATIC); - - offset = 0; - for(i=0; i<4; i++){ - coeff_token_vlc[i].table = coeff_token_vlc_tables+offset; - coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[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, - INIT_VLC_USE_NEW_STATIC); - offset += coeff_token_vlc_tables_size[i]; - } - /* - * This is a one time safety check to make sure that - * the packed static coeff_token_vlc table sizes - * were initialized correctly. - */ - assert(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables)); - - for(i=0; i<3; i++){ - chroma_dc_total_zeros_vlc[i].table = chroma_dc_total_zeros_vlc_tables[i]; - chroma_dc_total_zeros_vlc[i].table_allocated = chroma_dc_total_zeros_vlc_tables_size; - 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, - INIT_VLC_USE_NEW_STATIC); - } - for(i=0; i<15; i++){ - total_zeros_vlc[i].table = total_zeros_vlc_tables[i]; - total_zeros_vlc[i].table_allocated = total_zeros_vlc_tables_size; - 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, - INIT_VLC_USE_NEW_STATIC); - } - - for(i=0; i<6; i++){ - run_vlc[i].table = run_vlc_tables[i]; - run_vlc[i].table_allocated = run_vlc_tables_size; - init_vlc(&run_vlc[i], - RUN_VLC_BITS, 7, - &run_len [i][0], 1, 1, - &run_bits[i][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - } - run7_vlc.table = run7_vlc_table, - run7_vlc.table_allocated = run7_vlc_table_size; - init_vlc(&run7_vlc, RUN7_VLC_BITS, 16, - &run_len [6][0], 1, 1, - &run_bits[6][0], 1, 1, - INIT_VLC_USE_NEW_STATIC); - - init_cavlc_level_tab(); - } -} - -/** - * - */ -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; -} - -/** - * 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 occurred - */ -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; - if(total_coeff > (unsigned)max_coeff) { - av_log(h->s.avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", s->mb_x, s->mb_y, total_coeff); - return -1; - } - - trailing_ones= coeff_token&3; - tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff); - assert(total_coeff<=16); - - i = show_bits(gb, 3); - skip_bits(gb, trailing_ones); - level[0] = 1-((i&4)>>1); - level[1] = 1-((i&2) ); - level[2] = 1-((i&1)<<1); - - if(trailing_ones 10 & trailing_ones < 3; - int bitsi= show_bits(gb, LEVEL_TAB_BITS); - int level_code= cavlc_level_tab[suffix_length][bitsi][0]; - - skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]); - if(level_code >= 100){ - prefix= level_code - 100; - if(prefix == LEVEL_TAB_BITS) - 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<<1) + get_bits1(gb); //part - else - level_code= prefix; //part - }else if(prefix==14){ - if(suffix_length) - level_code= (prefix<<1) + get_bits1(gb); //part - else - level_code= prefix + get_bits(gb, 4); //part - }else{ - level_code= 30 + get_bits(gb, prefix-3); //part - if(prefix>=16){ - if(prefix > 25+3){ - av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n"); - return -1; - } - level_code += (1<<(prefix-3))-4096; - } - } - - if(trailing_ones < 3) level_code += 2; - - suffix_length = 2; - mask= -(level_code&1); - level[trailing_ones]= (((2+level_code)>>1) ^ mask) - mask; - }else{ - level_code += ((level_code>>31)|1) & -(trailing_ones < 3); - - suffix_length = 1 + (level_code + 3U > 6U); - level[trailing_ones]= level_code; - } - - //remaining coefficients have suffix_length > 0 - for(i=trailing_ones+1;i= 100){ - prefix= level_code - 100; - if(prefix == LEVEL_TAB_BITS){ - prefix += get_level_prefix(gb); - } - if(prefix<15){ - level_code = (prefix<=16) - level_code += (1<<(prefix-3))-4096; - } - mask= -(level_code&1); - level_code= (((2+level_code)>>1) ^ mask) - mask; - } - level[i]= level_code; - suffix_length+= suffix_limit[suffix_length] + level_code > 2U*suffix_limit[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-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1); - else - zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].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; -} - -int ff_h264_decode_mb_cavlc(H264Context *h){ - MpegEncContext * const s = &h->s; - int mb_xy; - int partition_count; - unsigned int mb_type, cbp; - int dct8x8_allowed= h->pps.transform_8x8_mode; - - mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; - - tprintf(s->avctx, "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_nos != FF_I_TYPE){ - if(s->mb_skip_run==-1) - s->mb_skip_run= get_ue_golomb(&s->gb); - - if (s->mb_skip_run--) { - if(FRAME_MBAFF && (s->mb_y&1) == 0){ - if(s->mb_skip_run==0) - h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb); - } - decode_mb_skip(h); - return 0; - } - } - if(FRAME_MBAFF){ - if( (s->mb_y&1) == 0 ) - h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb); - } - - h->prev_mb_skipped= 0; - - mb_type= get_ue_golomb(&s->gb); - if(h->slice_type_nos == FF_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_nos == FF_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_nos == FF_I_TYPE); - if(h->slice_type == FF_SI_TYPE && mb_type) - mb_type--; -decode_intra_mb: - if(mb_type > 25){ - av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too 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(MB_FIELD) - mb_type |= MB_TYPE_INTERLACED; - - h->slice_table[ mb_xy ]= h->slice_num; - - if(IS_INTRA_PCM(mb_type)){ - unsigned int x; - - // We assume these blocks are very rare so we do not optimize it. - align_get_bits(&s->gb); - - // The pixels are stored in the same order as levels in h->mb array. - for(x=0; x < (CHROMA ? 384 : 256); x++){ - ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8); - } - - // In deblocking, the quantizer is 0 - s->current_picture.qscale_table[mb_xy]= 0; - // All coeffs are present - memset(h->non_zero_count[mb_xy], 16, 32); - - s->current_picture.mb_type[mb_xy]= mb_type; - return 0; - } - - if(MB_MBAFF){ - h->ref_count[0] <<= 1; - h->ref_count[1] <<= 1; - } - - fill_decode_neighbors(h, mb_type); - fill_decode_caches(h, mb_type); - - //mb_pred - if(IS_INTRA(mb_type)){ - int pred_mode; -// 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){ - int mode= pred_intra_mode(h, i); - - if(!get_bits1(&s->gb)){ - const int rem_mode= get_bits(&s->gb, 3); - mode = rem_mode + (rem_mode >= mode); - } - - if(di==4) - fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 ); - else - h->intra4x4_pred_mode_cache[ scan8[i] ] = mode; - } - ff_h264_write_back_intra_pred_mode(h); - if( ff_h264_check_intra4x4_pred_mode(h) < 0) - return -1; - }else{ - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode); - if(h->intra16x16_pred_mode < 0) - return -1; - } - if(CHROMA){ - pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); - if(pred_mode < 0) - return -1; - h->chroma_pred_mode= pred_mode; - } - }else if(partition_count==4){ - int i, j, sub_partition_count[4], list, ref[2][4]; - - if(h->slice_type_nos == FF_B_TYPE){ - for(i=0; i<4; i++){ - h->sub_mb_type[i]= get_ue_golomb_31(&s->gb); - if(h->sub_mb_type[i] >=13){ - av_log(h->s.avctx, AV_LOG_ERROR, "B sub_mb_type %u 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]|h->sub_mb_type[1]|h->sub_mb_type[2]|h->sub_mb_type[3])) { - ff_h264_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_nos == FF_P_TYPE); //FIXME SP correct ? - for(i=0; i<4; i++){ - h->sub_mb_type[i]= get_ue_golomb_31(&s->gb); - if(h->sub_mb_type[i] >=4){ - av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %u 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; listlist_count; list++){ - int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list]; - 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)){ - unsigned int tmp; - if(ref_count == 1){ - tmp= 0; - }else if(ref_count == 2){ - tmp= get_bits1(&s->gb)^1; - }else{ - tmp= get_ue_golomb_31(&s->gb); - if(tmp>=ref_count){ - av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp); - return -1; - } - } - ref[list][i]= tmp; - }else{ - //FIXME - ref[list][i] = -1; - } - } - } - - if(dct8x8_allowed) - dct8x8_allowed = get_dct8x8_allowed(h); - - for(list=0; listlist_count; list++){ - 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(s->avctx, "final mv:%d %d\n", mx, my); - - if(IS_SUB_8X8(sub_mb_type)){ - mv_cache[ 1 ][0]= - mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx; - mv_cache[ 1 ][1]= - mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my; - }else if(IS_SUB_8X4(sub_mb_type)){ - mv_cache[ 1 ][0]= mx; - mv_cache[ 1 ][1]= my; - }else if(IS_SUB_4X8(sub_mb_type)){ - mv_cache[ 8 ][0]= mx; - mv_cache[ 8 ][1]= my; - } - 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)){ - ff_h264_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; listlist_count; list++){ - unsigned int val; - if(IS_DIR(mb_type, 0, list)){ - if(h->ref_count[list]==1){ - val= 0; - }else if(h->ref_count[list]==2){ - val= get_bits1(&s->gb)^1; - }else{ - val= get_ue_golomb_31(&s->gb); - if(val >= h->ref_count[list]){ - av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val); - return -1; - } - } - fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1); - } - } - for(list=0; listlist_count; 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(s->avctx, "final mv:%d %d\n", mx, my); - - fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); - } - } - } - else if(IS_16X8(mb_type)){ - for(list=0; listlist_count; list++){ - for(i=0; i<2; i++){ - unsigned int val; - if(IS_DIR(mb_type, i, list)){ - if(h->ref_count[list] == 1){ - val= 0; - }else if(h->ref_count[list] == 2){ - val= get_bits1(&s->gb)^1; - }else{ - val= get_ue_golomb_31(&s->gb); - if(val >= h->ref_count[list]){ - av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val); - return -1; - } - } - }else - val= LIST_NOT_USED&0xFF; - fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1); - } - } - for(list=0; listlist_count; list++){ - for(i=0; i<2; i++){ - unsigned int val; - 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(s->avctx, "final mv:%d %d\n", mx, my); - - val= pack16to32(mx,my); - }else - val=0; - fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4); - } - } - }else{ - assert(IS_8X16(mb_type)); - for(list=0; listlist_count; list++){ - for(i=0; i<2; i++){ - unsigned int val; - if(IS_DIR(mb_type, i, list)){ //FIXME optimize - if(h->ref_count[list]==1){ - val= 0; - }else if(h->ref_count[list]==2){ - val= get_bits1(&s->gb)^1; - }else{ - val= get_ue_golomb_31(&s->gb); - if(val >= h->ref_count[list]){ - av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val); - return -1; - } - } - }else - val= LIST_NOT_USED&0xFF; - fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1); - } - } - for(list=0; listlist_count; list++){ - for(i=0; i<2; i++){ - unsigned int val; - 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(s->avctx, "final mv:%d %d\n", mx, my); - - val= pack16to32(mx,my); - }else - val=0; - fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 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 (%u) at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; - } - - if(CHROMA){ - if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp]; - else cbp= golomb_to_inter_cbp [cbp]; - }else{ - if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp]; - else cbp= golomb_to_inter_cbp_gray[cbp]; - } - } - - if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){ - mb_type |= MB_TYPE_8x8DCT*get_bits1(&s->gb); - } - h->cbp= - h->cbp_table[mb_xy]= cbp; - s->current_picture.mb_type[mb_xy]= mb_type; - - if(cbp || IS_INTRA16x16(mb_type)){ - int i8x8, i4x4, chroma_idx; - int dquant; - GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; - const uint8_t *scan, *scan8x8, *dc_scan; - - if(IS_INTERLACED(mb_type)){ - scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0; - scan= s->qscale ? h->field_scan : h->field_scan_q0; - dc_scan= luma_dc_field_scan; - }else{ - scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0; - scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0; - dc_scan= luma_dc_zigzag_scan; - } - - dquant= get_se_golomb(&s->gb); - - s->qscale += dquant; - - if(((unsigned)s->qscale) > 51){ - if(s->qscale<0) s->qscale+= 52; - else s->qscale-= 52; - if(((unsigned)s->qscale) > 51){ - 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; - } - } - - h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale); - h->chroma_qp[1]= get_chroma_qp(h, 1, 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++){ - const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[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, qmul, 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); - - if(MB_MBAFF){ - h->ref_count[0] >>= 1; - h->ref_count[1] >>= 1; - } - - return 0; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_direct.c b/tizen/distrib/ffmpeg/libavcodec/h264_direct.c deleted file mode 100644 index d22780d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_direct.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 direct mb/block decoding. - * @author Michael Niedermayer - */ - -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h264.h" -#include "rectangle.h" - -//#undef NDEBUG -#include - - -static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){ - int poc0 = h->ref_list[0][i].poc; - int td = av_clip(poc1 - poc0, -128, 127); - if(td == 0 || h->ref_list[0][i].long_ref){ - return 256; - }else{ - int tb = av_clip(poc - poc0, -128, 127); - int tx = (16384 + (FFABS(td) >> 1)) / td; - return av_clip((tb*tx + 32) >> 6, -1024, 1023); - } -} - -void ff_h264_direct_dist_scale_factor(H264Context * const h){ - MpegEncContext * const s = &h->s; - const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; - const int poc1 = h->ref_list[1][0].poc; - int i, field; - for(field=0; field<2; field++){ - const int poc = h->s.current_picture_ptr->field_poc[field]; - const int poc1 = h->ref_list[1][0].field_poc[field]; - for(i=0; i < 2*h->ref_count[0]; i++) - h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16); - } - - for(i=0; iref_count[0]; i++){ - h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); - } -} - -static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){ - MpegEncContext * const s = &h->s; - Picture * const ref1 = &h->ref_list[1][0]; - int j, old_ref, rfield; - int start= mbafi ? 16 : 0; - int end = mbafi ? 16+2*h->ref_count[0] : h->ref_count[0]; - int interl= mbafi || s->picture_structure != PICT_FRAME; - - /* bogus; fills in for missing frames */ - memset(map[list], 0, sizeof(map[list])); - - for(rfield=0; rfield<2; rfield++){ - for(old_ref=0; old_refref_count[colfield][list]; old_ref++){ - int poc = ref1->ref_poc[colfield][list][old_ref]; - - if (!interl) - poc |= 3; - else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed - poc= (poc&~3) + rfield + 1; - - for(j=start; jref_list[0][j].frame_num + (h->ref_list[0][j].reference&3) == poc){ - int cur_ref= mbafi ? (j-16)^field : j; - map[list][2*old_ref + (rfield^field) + 16] = cur_ref; - if(rfield == field || !interl) - map[list][old_ref] = cur_ref; - break; - } - } - } - } -} - -void ff_h264_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, j, field; - int sidx= (s->picture_structure&1)^1; - int ref1sidx= (ref1->reference&1)^1; - - for(list=0; list<2; list++){ - cur->ref_count[sidx][list] = h->ref_count[list]; - for(j=0; jref_count[list]; j++) - cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3); - } - - if(s->picture_structure == PICT_FRAME){ - memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); - memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0])); - } - - cur->mbaff= FRAME_MBAFF; - - h->col_fieldoff= 0; - if(s->picture_structure == PICT_FRAME){ - int cur_poc = s->current_picture_ptr->poc; - int *col_poc = h->ref_list[1]->field_poc; - h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc)); - ref1sidx=sidx= h->col_parity; - }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff){ // FL -> FL & differ parity - h->col_fieldoff= s->mb_stride*(2*(h->ref_list[1][0].reference) - 3); - } - - if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) - return; - - for(list=0; list<2; list++){ - fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0); - if(FRAME_MBAFF) - for(field=0; field<2; field++) - fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1); - } -} - -static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ - MpegEncContext * const s = &h->s; - int b8_stride = 2; - int b4_stride = h->b_stride; - int mb_xy = h->mb_xy; - int mb_type_col[2]; - const int16_t (*l1mv0)[2], (*l1mv1)[2]; - const int8_t *l1ref0, *l1ref1; - const int is_b8x8 = IS_8X8(*mb_type); - unsigned int sub_mb_type= MB_TYPE_L0L1; - int i8, i4; - int ref[2]; - int mv[2]; - int list; - - assert(h->ref_list[1][0].reference&3); - -#define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM) - - - /* ref = min(neighbors) */ - for(list=0; list<2; list++){ - int left_ref = h->ref_cache[list][scan8[0] - 1]; - int top_ref = h->ref_cache[list][scan8[0] - 8]; - int refc = h->ref_cache[list][scan8[0] - 8 + 4]; - const int16_t *C= h->mv_cache[list][ scan8[0] - 8 + 4]; - if(refc == PART_NOT_AVAILABLE){ - refc = h->ref_cache[list][scan8[0] - 8 - 1]; - C = h-> mv_cache[list][scan8[0] - 8 - 1]; - } - ref[list] = FFMIN3((unsigned)left_ref, (unsigned)top_ref, (unsigned)refc); - if(ref[list] >= 0){ - //this is just pred_motion() but with the cases removed that cannot happen for direct blocks - const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ]; - const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ]; - - int match_count= (left_ref==ref[list]) + (top_ref==ref[list]) + (refc==ref[list]); - if(match_count > 1){ //most common - mv[list]= pack16to32(mid_pred(A[0], B[0], C[0]), - mid_pred(A[1], B[1], C[1]) ); - }else { - assert(match_count==1); - if(left_ref==ref[list]){ - mv[list]= AV_RN32A(A); - }else if(top_ref==ref[list]){ - mv[list]= AV_RN32A(B); - }else{ - mv[list]= AV_RN32A(C); - } - } - }else{ - int mask= ~(MB_TYPE_L0 << (2*list)); - mv[list] = 0; - ref[list] = -1; - if(!is_b8x8) - *mb_type &= mask; - sub_mb_type &= mask; - } - } - if(ref[0] < 0 && ref[1] < 0){ - ref[0] = ref[1] = 0; - if(!is_b8x8) - *mb_type |= MB_TYPE_L0L1; - sub_mb_type |= MB_TYPE_L0L1; - } - - if(!(is_b8x8|mv[0]|mv[1])){ - 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); - 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); - *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; - return; - } - - if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL - if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL - mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; - b8_stride = 0; - }else{ - mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity - } - goto single_col; - }else{ // AFL/AFR/FR/FL -> AFR/FR - if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR - mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; - mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; - mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; - b8_stride = 2+4*s->mb_stride; - b4_stride *= 6; - - sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ - if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) - && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) - && !is_b8x8){ - *mb_type |= MB_TYPE_16x8 |MB_TYPE_DIRECT2; /* B_16x8 */ - }else{ - *mb_type |= MB_TYPE_8x8; - } - }else{ // AFR/FR -> AFR/FR -single_col: - mb_type_col[0] = - mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; - - sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ - if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ - *mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_16x16 */ - }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){ - *mb_type |= MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)); - }else{ - if(!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_16x16); /* B_SUB_4x4 */ - } - *mb_type |= MB_TYPE_8x8; - } - } - } - - l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; - l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; - l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy]; - l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy]; - if(!b8_stride){ - if(s->mb_y&1){ - l1ref0 += 2; - l1ref1 += 2; - l1mv0 += 2*b4_stride; - l1mv1 += 2*b4_stride; - } - } - - - if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ - int n=0; - for(i8=0; i8<4; i8++){ - int x8 = i8&1; - int y8 = i8>>1; - int xy8 = x8+y8*b8_stride; - int xy4 = 3*x8+y8*b4_stride; - int a,b; - - if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) - continue; - h->sub_mb_type[i8] = sub_mb_type; - - 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); - if(!IS_INTRA(mb_type_col[y8]) && !h->ref_list[1][0].long_ref - && ( (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFABS(l1mv0[xy4][1]) <= 1) - || (l1ref0[xy8] < 0 && l1ref1[xy8] == 0 && FFABS(l1mv1[xy4][0]) <= 1 && FFABS(l1mv1[xy4][1]) <= 1))){ - a=b=0; - if(ref[0] > 0) - a= mv[0]; - if(ref[1] > 0) - b= mv[1]; - n++; - }else{ - a= mv[0]; - b= mv[1]; - } - fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4); - fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4); - } - if(!is_b8x8 && !(n&3)) - *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; - }else if(IS_16X16(*mb_type)){ - int a,b; - - 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[0]) && !h->ref_list[1][0].long_ref - && ( (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[0][1]) <= 1) - || (l1ref0[0] < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <= 1 && FFABS(l1mv1[0][1]) <= 1 - && h->x264_build>33U))){ - a=b=0; - if(ref[0] > 0) - a= mv[0]; - if(ref[1] > 0) - b= mv[1]; - }else{ - a= mv[0]; - b= mv[1]; - } - fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4); - fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4); - }else{ - int n=0; - 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, mv[0], 4); - fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, mv[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); - - assert(b8_stride==2); - /* col_zero_flag */ - if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref && ( l1ref0[i8] == 0 - || (l1ref0[i8] < 0 && l1ref1[i8] == 0 - && h->x264_build>33U))){ - const int16_t (*l1mv)[2]= l1ref0[i8] == 0 ? l1mv0 : l1mv1; - if(IS_SUB_8X8(sub_mb_type)){ - const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; - if(FFABS(mv_col[0]) <= 1 && FFABS(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); - n+=4; - } - }else{ - int m=0; - for(i4=0; i4<4; i4++){ - const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride]; - if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){ - if(ref[0] == 0) - AV_ZERO32(h->mv_cache[0][scan8[i8*4+i4]]); - if(ref[1] == 0) - AV_ZERO32(h->mv_cache[1][scan8[i8*4+i4]]); - m++; - } - } - if(!(m&3)) - h->sub_mb_type[i8]+= MB_TYPE_16x16 - MB_TYPE_8x8; - n+=m; - } - } - } - if(!is_b8x8 && !(n&15)) - *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; - } -} - -static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ - MpegEncContext * const s = &h->s; - int b8_stride = 2; - int b4_stride = h->b_stride; - int mb_xy = h->mb_xy; - int mb_type_col[2]; - const int16_t (*l1mv0)[2], (*l1mv1)[2]; - const int8_t *l1ref0, *l1ref1; - const int is_b8x8 = IS_8X8(*mb_type); - unsigned int sub_mb_type; - int i8, i4; - - assert(h->ref_list[1][0].reference&3); - - if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL - if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL - mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; - b8_stride = 0; - }else{ - mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity - } - goto single_col; - }else{ // AFL/AFR/FR/FL -> AFR/FR - if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR - mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; - mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; - mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; - b8_stride = 2+4*s->mb_stride; - b4_stride *= 6; - - sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ - - if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) - && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) - && !is_b8x8){ - *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */ - }else{ - *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; - } - }else{ // AFR/FR -> AFR/FR -single_col: - mb_type_col[0] = - mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; - - sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ - if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ - *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */ - }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){ - *mb_type |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)); - }else{ - if(!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; - } - } - } - - l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; - l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; - l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy]; - l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy]; - if(!b8_stride){ - if(s->mb_y&1){ - l1ref0 += 2; - l1ref1 += 2; - l1mv0 += 2*b4_stride; - l1mv1 += 2*b4_stride; - } - } - - { - const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; - const int *dist_scale_factor = h->dist_scale_factor; - int ref_offset; - - if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ - map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; - map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; - dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; - } - ref_offset = (h->ref_list[1][0].mbaff<<4) & (mb_type_col[0]>>3); //if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0 - - if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ - int y_shift = 2*!IS_INTERLACED(*mb_type); - assert(h->sps.direct_8x8_inference_flag); - - for(i8=0; i8<4; i8++){ - const int x8 = i8&1; - const int y8 = i8>>1; - int ref0, scale; - 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; - - fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); - if(IS_INTRA(mb_type_col[y8])){ - fill_rectangle(&h->ref_cache[0][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*b8_stride]; - if(ref0 >= 0) - ref0 = map_col_to_list0[0][ref0 + ref_offset]; - else{ - ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; - l1mv= l1mv1; - } - scale = dist_scale_factor[ref0]; - fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); - - { - const int16_t *mv_col = l1mv[x8*3 + y8*b4_stride]; - int my_col = (mv_col[1]<> 8; - int my = (scale * my_col + 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-my_col), 4); - } - } - return; - } - - /* one-to-one mv scaling */ - - if(IS_16X16(*mb_type)){ - int ref, mv0, mv1; - - fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); - if(IS_INTRA(mb_type_col[0])){ - ref=mv0=mv1=0; - }else{ - const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset] - : map_col_to_list0[1][l1ref1[0] + ref_offset]; - const int scale = dist_scale_factor[ref0]; - const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; - int mv_l0[2]; - mv_l0[0] = (scale * mv_col[0] + 128) >> 8; - mv_l0[1] = (scale * mv_col[1] + 128) >> 8; - ref= ref0; - mv0= pack16to32(mv_l0[0],mv_l0[1]); - mv1= pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); - } - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); - fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4); - fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4); - }else{ - for(i8=0; i8<4; i8++){ - const int x8 = i8&1; - const int y8 = i8>>1; - int ref0, scale; - 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; - fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); - if(IS_INTRA(mb_type_col[0])){ - fill_rectangle(&h->ref_cache[0][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; - } - - assert(b8_stride == 2); - ref0 = l1ref0[i8]; - if(ref0 >= 0) - ref0 = map_col_to_list0[0][ref0 + ref_offset]; - else{ - ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset]; - l1mv= l1mv1; - } - scale = dist_scale_factor[ref0]; - - fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); - if(IS_SUB_8X8(sub_mb_type)){ - const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride]; - int mx = (scale * mv_col[0] + 128) >> 8; - int my = (scale * 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))*b4_stride]; - int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; - mv_l0[0] = (scale * mv_col[0] + 128) >> 8; - mv_l0[1] = (scale * mv_col[1] + 128) >> 8; - AV_WN32A(h->mv_cache[1][scan8[i8*4+i4]], - pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1])); - } - } - } - } -} - -void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){ - if(h->direct_spatial_mv_pred){ - pred_spatial_direct_motion(h, mb_type); - }else{ - pred_temp_direct_motion(h, mb_type); - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_loopfilter.c b/tizen/distrib/ffmpeg/libavcodec/h264_loopfilter.c deleted file mode 100644 index 710e037..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_loopfilter.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... loop filter - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 loop filter. - * @author Michael Niedermayer - */ - -#include "libavutil/intreadwrite.h" -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h264.h" -#include "mathops.h" -#include "rectangle.h" - -//#undef NDEBUG -#include - -/* Deblocking filter (p153) */ -static const uint8_t alpha_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, 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, - 255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255, -}; -static const uint8_t beta_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, 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, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, -}; -static const uint8_t tc0_table[52*3][4] = { - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, - {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 0 }, {-1, 0, 0, 1 }, - {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 0, 1 }, {-1, 0, 1, 1 }, {-1, 0, 1, 1 }, {-1, 1, 1, 1 }, - {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 1 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, {-1, 1, 1, 2 }, - {-1, 1, 1, 2 }, {-1, 1, 2, 3 }, {-1, 1, 2, 3 }, {-1, 2, 2, 3 }, {-1, 2, 2, 4 }, {-1, 2, 3, 4 }, - {-1, 2, 3, 4 }, {-1, 3, 3, 5 }, {-1, 3, 4, 6 }, {-1, 3, 4, 6 }, {-1, 4, 5, 7 }, {-1, 4, 5, 8 }, - {-1, 4, 6, 9 }, {-1, 5, 7,10 }, {-1, 6, 8,11 }, {-1, 6, 8,13 }, {-1, 7,10,14 }, {-1, 8,11,16 }, - {-1, 9,12,18 }, {-1,10,13,20 }, {-1,11,15,23 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, - {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, {-1,13,17,25 }, -}; - -static void av_always_inline filter_mb_edgev( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h) { - const unsigned int index_a = qp + h->slice_alpha_c0_offset; - const int alpha = alpha_table[index_a]; - const int beta = beta_table[qp + h->slice_beta_offset]; - if (alpha ==0 || beta == 0) return; - - if( bS[0] < 4 ) { - int8_t tc[4]; - tc[0] = tc0_table[index_a][bS[0]]; - tc[1] = tc0_table[index_a][bS[1]]; - tc[2] = tc0_table[index_a][bS[2]]; - tc[3] = tc0_table[index_a][bS[3]]; - h->h264dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc); - } else { - h->h264dsp.h264_h_loop_filter_luma_intra(pix, stride, alpha, beta); - } -} -static void av_always_inline filter_mb_edgecv( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) { - const unsigned int index_a = qp + h->slice_alpha_c0_offset; - const int alpha = alpha_table[index_a]; - const int beta = beta_table[qp + h->slice_beta_offset]; - if (alpha ==0 || beta == 0) return; - - if( bS[0] < 4 ) { - int8_t tc[4]; - tc[0] = tc0_table[index_a][bS[0]]+1; - tc[1] = tc0_table[index_a][bS[1]]+1; - tc[2] = tc0_table[index_a][bS[2]]+1; - tc[3] = tc0_table[index_a][bS[3]]+1; - h->h264dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc); - } else { - h->h264dsp.h264_h_loop_filter_chroma_intra(pix, stride, alpha, beta); - } -} - -static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int bsi, int qp ) { - int i; - int index_a = qp + h->slice_alpha_c0_offset; - int alpha = alpha_table[index_a]; - int beta = beta_table[qp + h->slice_beta_offset]; - for( i = 0; i < 8; i++, pix += stride) { - const int bS_index = (i >> 1) * bsi; - - if( bS[bS_index] == 0 ) { - continue; - } - - if( bS[bS_index] < 4 ) { - const int tc0 = tc0_table[index_a][bS[bS_index]]; - 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( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - int tc = tc0; - int i_delta; - - if( FFABS( p2 - p0 ) < beta ) { - if(tc0) - pix[-2] = p1 + av_clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 ); - tc++; - } - if( FFABS( q2 - q0 ) < beta ) { - if(tc0) - pix[1] = q1 + av_clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 ); - tc++; - } - - i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - pix[-1] = av_clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */ - tprintf(h->s.avctx, "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{ - 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( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - - if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){ - if( FFABS( 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( FFABS( 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(h->s.avctx, "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, int16_t bS[4], int bsi, int qp ) { - int i; - int index_a = qp + h->slice_alpha_c0_offset; - int alpha = alpha_table[index_a]; - int beta = beta_table[qp + h->slice_beta_offset]; - for( i = 0; i < 4; i++, pix += stride) { - const int bS_index = i*bsi; - - if( bS[bS_index] == 0 ) { - continue; - } - - if( bS[bS_index] < 4 ) { - const int tc = tc0_table[index_a][bS[bS_index]] + 1; - const int p0 = pix[-1]; - const int p1 = pix[-2]; - const int q0 = pix[0]; - const int q1 = pix[1]; - - if( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - const int i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - - pix[-1] = av_clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */ - tprintf(h->s.avctx, "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( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - - pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ - pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ - tprintf(h->s.avctx, "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 av_always_inline filter_mb_edgeh( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) { - const unsigned int index_a = qp + h->slice_alpha_c0_offset; - const int alpha = alpha_table[index_a]; - const int beta = beta_table[qp + h->slice_beta_offset]; - if (alpha ==0 || beta == 0) return; - - if( bS[0] < 4 ) { - int8_t tc[4]; - tc[0] = tc0_table[index_a][bS[0]]; - tc[1] = tc0_table[index_a][bS[1]]; - tc[2] = tc0_table[index_a][bS[2]]; - tc[3] = tc0_table[index_a][bS[3]]; - h->h264dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc); - } else { - h->h264dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta); - } -} - -static void av_always_inline filter_mb_edgech( uint8_t *pix, int stride, int16_t bS[4], unsigned int qp, H264Context *h ) { - const unsigned int index_a = qp + h->slice_alpha_c0_offset; - const int alpha = alpha_table[index_a]; - const int beta = beta_table[qp + h->slice_beta_offset]; - if (alpha ==0 || beta == 0) return; - - if( bS[0] < 4 ) { - int8_t tc[4]; - tc[0] = tc0_table[index_a][bS[0]]+1; - tc[1] = tc0_table[index_a][bS[1]]+1; - tc[2] = tc0_table[index_a][bS[2]]+1; - tc[3] = tc0_table[index_a][bS[3]]+1; - h->h264dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc); - } else { - h->h264dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta); - } -} - -void ff_h264_filter_mb_fast( 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; - int mb_xy; - int mb_type, left_type; - int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh; - - mb_xy = h->mb_xy; - - if(!h->top_type || !h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) { - ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize); - return; - } - assert(!FRAME_MBAFF); - left_type= h->left_type[0]; - - mb_type = s->current_picture.mb_type[mb_xy]; - qp = s->current_picture.qscale_table[mb_xy]; - qp0 = s->current_picture.qscale_table[mb_xy-1]; - qp1 = s->current_picture.qscale_table[h->top_mb_xy]; - qpc = get_chroma_qp( h, 0, qp ); - qpc0 = get_chroma_qp( h, 0, qp0 ); - qpc1 = get_chroma_qp( h, 0, qp1 ); - qp0 = (qp + qp0 + 1) >> 1; - qp1 = (qp + qp1 + 1) >> 1; - qpc0 = (qpc + qpc0 + 1) >> 1; - qpc1 = (qpc + qpc1 + 1) >> 1; - qp_thresh = 15+52 - h->slice_alpha_c0_offset; - if(qp <= qp_thresh && qp0 <= qp_thresh && qp1 <= qp_thresh && - qpc <= qp_thresh && qpc0 <= qp_thresh && qpc1 <= qp_thresh) - return; - - if( IS_INTRA(mb_type) ) { - int16_t bS4[4] = {4,4,4,4}; - int16_t bS3[4] = {3,3,3,3}; - int16_t *bSH = FIELD_PICTURE ? bS3 : bS4; - if(left_type) - filter_mb_edgev( &img_y[4*0], linesize, bS4, qp0, h); - if( IS_8x8DCT(mb_type) ) { - filter_mb_edgev( &img_y[4*2], linesize, bS3, qp, h); - filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, h); - filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h); - } else { - filter_mb_edgev( &img_y[4*1], linesize, bS3, qp, h); - filter_mb_edgev( &img_y[4*2], linesize, bS3, qp, h); - filter_mb_edgev( &img_y[4*3], linesize, bS3, qp, h); - filter_mb_edgeh( &img_y[4*0*linesize], linesize, bSH, qp1, h); - filter_mb_edgeh( &img_y[4*1*linesize], linesize, bS3, qp, h); - filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h); - filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, h); - } - if(left_type){ - filter_mb_edgecv( &img_cb[2*0], uvlinesize, bS4, qpc0, h); - filter_mb_edgecv( &img_cr[2*0], uvlinesize, bS4, qpc0, h); - } - filter_mb_edgecv( &img_cb[2*2], uvlinesize, bS3, qpc, h); - filter_mb_edgecv( &img_cr[2*2], uvlinesize, bS3, qpc, h); - filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, h); - filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, h); - filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, h); - filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, h); - return; - } else { - LOCAL_ALIGNED_8(int16_t, bS, [2], [4][4]); - int edges; - if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 ) { - edges = 4; - AV_WN64A(bS[0][0], 0x0002000200020002ULL); - AV_WN64A(bS[0][2], 0x0002000200020002ULL); - AV_WN64A(bS[1][0], 0x0002000200020002ULL); - AV_WN64A(bS[1][2], 0x0002000200020002ULL); - } else { - int mask_edge1 = (3*(((5*mb_type)>>5)&1)) | (mb_type>>4); //(mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : (mb_type & MB_TYPE_16x8) ? 1 : 0; - int mask_edge0 = 3*((mask_edge1>>1) & ((5*left_type)>>5)&1); // (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) && (h->left_type[0] & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : 0; - int step = 1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1; - edges = 4 - 3*((mb_type>>3) & !(h->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4; - h->h264dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache, - h->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE); - } - if( IS_INTRA(left_type) ) - AV_WN64A(bS[0][0], 0x0004000400040004ULL); - if( IS_INTRA(h->top_type) ) - AV_WN64A(bS[1][0], FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL); - -#define FILTER(hv,dir,edge)\ - if(AV_RN64A(bS[dir][edge])) { \ - filter_mb_edge##hv( &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir, h );\ - if(!(edge&1)) {\ - filter_mb_edgec##hv( &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\ - filter_mb_edgec##hv( &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\ - }\ - } - if(left_type) - FILTER(v,0,0); - if( edges == 1 ) { - FILTER(h,1,0); - } else if( IS_8x8DCT(mb_type) ) { - FILTER(v,0,2); - FILTER(h,1,0); - FILTER(h,1,2); - } else { - FILTER(v,0,1); - FILTER(v,0,2); - FILTER(v,0,3); - FILTER(h,1,0); - FILTER(h,1,1); - FILTER(h,1,2); - FILTER(h,1,3); - } -#undef FILTER - } -} - -static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){ - int v; - - v= h->ref_cache[0][b_idx] != h->ref_cache[0][bn_idx]; - if(!v && h->ref_cache[0][b_idx]!=-1) - v= h->mv_cache[0][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit; - - if(h->list_count==2){ - if(!v) - v = h->ref_cache[1][b_idx] != h->ref_cache[1][bn_idx] | - h->mv_cache[1][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit; - - if(v){ - if(h->ref_cache[0][b_idx] != h->ref_cache[1][bn_idx] | - h->ref_cache[1][b_idx] != h->ref_cache[0][bn_idx]) - return 1; - return - h->mv_cache[0][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit | - h->mv_cache[1][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit; - } - } - - return v; -} - -static av_always_inline void filter_mb_dir(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, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int dir) { - MpegEncContext * const s = &h->s; - int edge; - const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; - const int mbm_type = dir == 0 ? h->left_type[0] : h->top_type; - - // how often to recheck mv-based bS when iterating between edges - static const uint8_t mask_edge_tab[2][8]={{0,3,3,3,1,1,1,1}, - {0,3,1,1,3,3,3,3}}; - const int mask_edge = mask_edge_tab[dir][(mb_type>>3)&7]; - const int edges = mask_edge== 3 && !(h->cbp&15) ? 1 : 4; - - // 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(mbm_type && !first_vertical_edge_done){ - - if (FRAME_MBAFF && (dir == 1) && ((mb_y&1) == 0) - && IS_INTERLACED(mbm_type&~mb_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 j; - - for(j=0; j<2; j++, mbn_xy += s->mb_stride){ - DECLARE_ALIGNED(8, int16_t, bS)[4]; - int qp; - if( IS_INTRA(mb_type|s->current_picture.mb_type[mbn_xy]) ) { - AV_WN64A(bS, 0x0003000300030003ULL); - } else { - if(!CABAC && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])){ - bS[0]= 1+((h->cbp_table[mbn_xy] & 4)||h->non_zero_count_cache[scan8[0]+0]); - bS[1]= 1+((h->cbp_table[mbn_xy] & 4)||h->non_zero_count_cache[scan8[0]+1]); - bS[2]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+2]); - bS[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]); - }else{ - const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 4+3*8; - int i; - for( i = 0; i < 4; i++ ) { - bS[i] = 1 + !!(h->non_zero_count_cache[scan8[0]+i] | mbn_nnz[i]); - } - } - } - // 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(s->avctx, "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(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } - filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, h ); - filter_mb_edgech( &img_cb[j*uvlinesize], tmp_uvlinesize, bS, - ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h); - filter_mb_edgech( &img_cr[j*uvlinesize], tmp_uvlinesize, bS, - ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h); - } - }else{ - DECLARE_ALIGNED(8, int16_t, bS)[4]; - int qp; - - if( IS_INTRA(mb_type|mbm_type)) { - AV_WN64A(bS, 0x0003000300030003ULL); - if ( (!IS_INTERLACED(mb_type|mbm_type)) - || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0)) - ) - AV_WN64A(bS, 0x0004000400040004ULL); - } else { - int i; - int mv_done; - - if( dir && FRAME_MBAFF && IS_INTERLACED(mb_type ^ mbm_type)) { - AV_WN64A(bS, 0x0001000100010001ULL); - mv_done = 1; - } - else if( mask_par0 && ((mbm_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)))) ) { - int b_idx= 8 + 4; - int bn_idx= b_idx - (dir ? 8:1); - - bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, 8 + 4, bn_idx, mvy_limit); - mv_done = 1; - } - else - mv_done = 0; - - for( i = 0; i < 4; i++ ) { - int x = dir == 0 ? 0 : i; - int y = dir == 0 ? i : 0; - int b_idx= 8 + 4 + x + 8*y; - int bn_idx= b_idx - (dir ? 8:1); - - if( h->non_zero_count_cache[b_idx] | - h->non_zero_count_cache[bn_idx] ) { - bS[i] = 2; - } - else if(!mv_done) - { - bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit); - } - } - } - - /* Filter edge */ - // Do not use s->qscale as luma quantizer because it has not the same - // value in IPCM macroblocks. - if(bS[0]+bS[1]+bS[2]+bS[3]){ - qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbm_xy] + 1 ) >> 1; - //tprintf(s->avctx, "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[0], s->current_picture.qscale_table[mbn_xy]); - tprintf(s->avctx, "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(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } - if( dir == 0 ) { - filter_mb_edgev( &img_y[0], linesize, bS, qp, h ); - { - int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; - filter_mb_edgecv( &img_cb[0], uvlinesize, bS, qp, h); - if(h->pps.chroma_qp_diff) - qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; - filter_mb_edgecv( &img_cr[0], uvlinesize, bS, qp, h); - } - } else { - filter_mb_edgeh( &img_y[0], linesize, bS, qp, h ); - { - int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; - filter_mb_edgech( &img_cb[0], uvlinesize, bS, qp, h); - if(h->pps.chroma_qp_diff) - qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; - filter_mb_edgech( &img_cr[0], uvlinesize, bS, qp, h); - } - } - } - } - } - - /* Calculate bS */ - for( edge = 1; edge < edges; edge++ ) { - DECLARE_ALIGNED(8, int16_t, bS)[4]; - int qp; - - if( IS_8x8DCT(mb_type & (edge<<24)) ) // (edge&1) && IS_8x8DCT(mb_type) - continue; - - if( IS_INTRA(mb_type)) { - AV_WN64A(bS, 0x0003000300030003ULL); - } else { - int i; - int mv_done; - - if( edge & mask_edge ) { - AV_ZERO64(bS); - mv_done = 1; - } - else if( mask_par0 ) { - int b_idx= 8 + 4 + edge * (dir ? 8:1); - int bn_idx= b_idx - (dir ? 8:1); - - bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, b_idx, bn_idx, mvy_limit); - 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] | - h->non_zero_count_cache[bn_idx] ) { - bS[i] = 2; - } - else if(!mv_done) - { - bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit); - } - } - - 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]; - //tprintf(s->avctx, "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[0], s->current_picture.qscale_table[mbn_xy]); - tprintf(s->avctx, "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(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } - if( dir == 0 ) { - filter_mb_edgev( &img_y[4*edge], linesize, bS, qp, h ); - if( (edge&1) == 0 ) { - filter_mb_edgecv( &img_cb[2*edge], uvlinesize, bS, h->chroma_qp[0], h); - filter_mb_edgecv( &img_cr[2*edge], uvlinesize, bS, h->chroma_qp[1], h); - } - } else { - filter_mb_edgeh( &img_y[4*edge*linesize], linesize, bS, qp, h ); - if( (edge&1) == 0 ) { - filter_mb_edgech( &img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h); - filter_mb_edgech( &img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h); - } - } - } -} - -void ff_h264_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; - const int mb_type = s->current_picture.mb_type[mb_xy]; - const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4; - int first_vertical_edge_done = 0; - av_unused int dir; - - if (FRAME_MBAFF - // and current and left pair do not have the same interlaced type - && IS_INTERLACED(mb_type^h->left_type[0]) - // and left mb is in available to us - && h->left_type[0]) { - /* First vertical edge is different in MBAFF frames - * There are 8 different bS to compute and 2 different Qp - */ - DECLARE_ALIGNED(8, int16_t, bS)[8]; - int qp[2]; - int bqp[2]; - int rqp[2]; - int mb_qp, mbn0_qp, mbn1_qp; - int i; - first_vertical_edge_done = 1; - - if( IS_INTRA(mb_type) ) { - AV_WN64A(&bS[0], 0x0004000400040004ULL); - AV_WN64A(&bS[4], 0x0004000400040004ULL); - } else { - static const uint8_t offset[2][2][8]={ - { - {7+8*0, 7+8*0, 7+8*0, 7+8*0, 7+8*1, 7+8*1, 7+8*1, 7+8*1}, - {7+8*2, 7+8*2, 7+8*2, 7+8*2, 7+8*3, 7+8*3, 7+8*3, 7+8*3}, - },{ - {7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3}, - {7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3}, - } - }; - const uint8_t *off= offset[MB_FIELD][mb_y&1]; - for( i = 0; i < 8; i++ ) { - int j= MB_FIELD ? i>>2 : i&1; - int mbn_xy = h->left_mb_xy[j]; - int mbn_type= h->left_type[j]; - - if( IS_INTRA( mbn_type ) ) - bS[i] = 4; - else{ - bS[i] = 1 + !!(h->non_zero_count_cache[12+8*(i>>1)] | - ((!h->pps.cabac && IS_8x8DCT(mbn_type)) ? - (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2)) - : - h->non_zero_count[mbn_xy][ off[i] ])); - } - } - } - - mb_qp = s->current_picture.qscale_table[mb_xy]; - mbn0_qp = s->current_picture.qscale_table[h->left_mb_xy[0]]; - mbn1_qp = s->current_picture.qscale_table[h->left_mb_xy[1]]; - qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1; - bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) + - get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1; - rqp[0] = ( get_chroma_qp( h, 1, mb_qp ) + - get_chroma_qp( h, 1, mbn0_qp ) + 1 ) >> 1; - qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1; - bqp[1] = ( get_chroma_qp( h, 0, mb_qp ) + - get_chroma_qp( h, 0, mbn1_qp ) + 1 ) >> 1; - rqp[1] = ( get_chroma_qp( h, 1, mb_qp ) + - get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1; - - /* Filter edge */ - tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize); - { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } - if(MB_FIELD){ - filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0] ); - filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1] ); - filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0] ); - filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] ); - filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0] ); - filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] ); - }else{ - filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0] ); - filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1] ); - filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] ); - filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] ); - filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] ); - filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] ); - } - } - -#if CONFIG_SMALL - for( dir = 0; dir < 2; dir++ ) - filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, dir); -#else - filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, 0); - filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, 1); -#endif -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c b/tizen/distrib/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c deleted file mode 100644 index 0c92b36..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * H.264 MP4 to Annex B byte stream format filter - * Copyright (c) 2007 Benoit Fouet - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct H264BSFContext { - uint8_t length_size; - uint8_t first_idr; - uint8_t *sps_pps_data; - uint32_t size; -} H264BSFContext; - -static void alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *sps_pps, uint32_t sps_pps_size, - const uint8_t *in, uint32_t in_size) { - uint32_t offset = *poutbuf_size; - uint8_t nal_header_size = offset ? 3 : 4; - - *poutbuf_size += sps_pps_size+in_size+nal_header_size; - *poutbuf = av_realloc(*poutbuf, *poutbuf_size); - if (sps_pps) - memcpy(*poutbuf+offset, sps_pps, sps_pps_size); - memcpy(*poutbuf+sps_pps_size+nal_header_size+offset, in, in_size); - if (!offset) - AV_WB32(*poutbuf+sps_pps_size, 1); - else { - (*poutbuf+offset+sps_pps_size)[0] = (*poutbuf+offset+sps_pps_size)[1] = 0; - (*poutbuf+offset+sps_pps_size)[2] = 1; - } -} - -static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, - int keyframe) { - H264BSFContext *ctx = bsfc->priv_data; - uint8_t unit_type; - int32_t nal_size; - uint32_t cumul_size = 0; - const uint8_t *buf_end = buf + buf_size; - - /* nothing to filter */ - if (!avctx->extradata || avctx->extradata_size < 6) { - *poutbuf = (uint8_t*) buf; - *poutbuf_size = buf_size; - return 0; - } - - /* retrieve sps and pps NAL units from extradata */ - if (!ctx->sps_pps_data) { - uint16_t unit_size; - uint32_t total_size = 0; - uint8_t *out = NULL, unit_nb, sps_done = 0; - const uint8_t *extradata = avctx->extradata+4; - static const uint8_t nalu_header[4] = {0, 0, 0, 1}; - - /* retrieve length coded size */ - ctx->length_size = (*extradata++ & 0x3) + 1; - if (ctx->length_size == 3) - return AVERROR(EINVAL); - - /* retrieve sps and pps unit(s) */ - unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */ - if (!unit_nb) { - unit_nb = *extradata++; /* number of pps unit(s) */ - sps_done++; - } - while (unit_nb--) { - unit_size = AV_RB16(extradata); - total_size += unit_size+4; - if (extradata+2+unit_size > avctx->extradata+avctx->extradata_size) { - av_free(out); - return AVERROR(EINVAL); - } - out = av_realloc(out, total_size); - if (!out) - return AVERROR(ENOMEM); - memcpy(out+total_size-unit_size-4, nalu_header, 4); - memcpy(out+total_size-unit_size, extradata+2, unit_size); - extradata += 2+unit_size; - - if (!unit_nb && !sps_done++) - unit_nb = *extradata++; /* number of pps unit(s) */ - } - - ctx->sps_pps_data = out; - ctx->size = total_size; - ctx->first_idr = 1; - } - - *poutbuf_size = 0; - *poutbuf = NULL; - do { - if (buf + ctx->length_size > buf_end) - goto fail; - - if (ctx->length_size == 1) - nal_size = buf[0]; - else if (ctx->length_size == 2) - nal_size = AV_RB16(buf); - else - nal_size = AV_RB32(buf); - - buf += ctx->length_size; - unit_type = *buf & 0x1f; - - if (buf + nal_size > buf_end || nal_size < 0) - goto fail; - - /* prepend only to the first type 5 NAL unit of an IDR picture */ - if (ctx->first_idr && unit_type == 5) { - alloc_and_copy(poutbuf, poutbuf_size, - ctx->sps_pps_data, ctx->size, - buf, nal_size); - ctx->first_idr = 0; - } - else { - alloc_and_copy(poutbuf, poutbuf_size, - NULL, 0, - buf, nal_size); - if (!ctx->first_idr && unit_type == 1) - ctx->first_idr = 1; - } - - buf += nal_size; - cumul_size += nal_size + ctx->length_size; - } while (cumul_size < buf_size); - - return 1; - -fail: - av_freep(poutbuf); - *poutbuf_size = 0; - return AVERROR(EINVAL); -} - -static void h264_mp4toannexb_close(AVBitStreamFilterContext *bsfc) -{ - H264BSFContext *ctx = bsfc->priv_data; - av_freep(&ctx->sps_pps_data); -} - -AVBitStreamFilter h264_mp4toannexb_bsf = { - "h264_mp4toannexb", - sizeof(H264BSFContext), - h264_mp4toannexb_filter, - h264_mp4toannexb_close, -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_mvpred.h b/tizen/distrib/ffmpeg/libavcodec/h264_mvpred.h deleted file mode 100644 index 661ef6c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_mvpred.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... motion vector predicion - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 motion vector predicion. - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_H264_MVPRED_H -#define AVCODEC_H264_MVPRED_H - -#include "internal.h" -#include "avcodec.h" -#include "h264.h" - -//#undef NDEBUG -#include - -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 ]; - MpegEncContext *s = &h->s; - - /* there is no consistent mapping of mvs to neighboring locations that will - * make mbaff happy, so we can't move all this logic to fill_caches */ - if(FRAME_MBAFF){ - -#define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4)\ - const int xy = XY, y4 = Y4;\ - const int mb_type = mb_types[xy+(y4>>2)*s->mb_stride];\ - if(!USES_LIST(mb_type,list))\ - return LIST_NOT_USED;\ - mv = s->current_picture_ptr->motion_val[list][h->mb2b_xy[xy]+3 + y4*h->b_stride];\ - h->mv_cache[list][scan8[0]-2][0] = mv[0];\ - h->mv_cache[list][scan8[0]-2][1] = mv[1] MV_OP;\ - return s->current_picture_ptr->ref_index[list][4*xy+1 + (y4&~1)] REF_OP; - - if(topright_ref == PART_NOT_AVAILABLE - && i >= scan8[0]+8 && (i&7)==4 - && h->ref_cache[list][scan8[0]-1] != PART_NOT_AVAILABLE){ - const uint32_t *mb_types = s->current_picture_ptr->mb_type; - const int16_t *mv; - AV_ZERO32(h->mv_cache[list][scan8[0]-2]); - *C = h->mv_cache[list][scan8[0]-2]; - - if(!MB_FIELD - && IS_INTERLACED(h->left_type[0])){ - SET_DIAG_MV(*2, >>1, h->left_mb_xy[0]+s->mb_stride, (s->mb_y&1)*2+(i>>5)); - assert(h->left_mb_xy[0] == h->left_mb_xy[1]); - } - if(MB_FIELD - && !IS_INTERLACED(h->left_type[0])){ - // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK. - SET_DIAG_MV(/2, <<1, h->left_mb_xy[i>=36], ((i>>2))&3); - } - } -#undef SET_DIAG_MV - } - - if(topright_ref != PART_NOT_AVAILABLE){ - *C= h->mv_cache[list][ i - 8 + part_width ]; - return topright_ref; - }else{ - tprintf(s->avctx, "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(h->s.avctx, "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(h->s.avctx, "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(h->s.avctx, "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(h->s.avctx, "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(h->s.avctx, "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(h->s.avctx, "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(h->s.avctx, "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 | AV_RN32A(h->mv_cache[0][ scan8[0] - 8 ])) - || !(left_ref | AV_RN32A(h->mv_cache[0][ scan8[0] - 1 ]))){ - - *mx = *my = 0; - return; - } - - pred_motion(h, 0, 4, 0, 0, mx, my); - - return; -} - -#endif /* AVCODEC_H264_MVPRED_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_parser.c b/tizen/distrib/ffmpeg/libavcodec/h264_parser.c deleted file mode 100644 index a3cbe3b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_parser.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... parser - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 parser. - * @author Michael Niedermayer - */ - -#include "parser.h" -#include "h264_parser.h" -#include "h264data.h" -#include "golomb.h" - -#include - - -int ff_h264_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; - if(state>13) - state= 7; - - for(i=0; i7, 1->4, 0->5 - else if(buf[i]) state = 7; - else state>>=1; //2->1, 1->0, 0->0 - }else if(state<=5){ - int v= buf[i] & 0x1F; - if(v==6 || v==7 || v==8 || v==9){ - if(pc->frame_start_found){ - i++; - goto found; - } - }else if(v==1 || v==2 || v==5){ - if(pc->frame_start_found){ - state+=8; - continue; - }else - pc->frame_start_found = 1; - } - state= 7; - }else{ - if(buf[i] & 0x80) - goto found; - state= 7; - } - } - pc->state= state; - return END_NOT_FOUND; - -found: - pc->state=7; - pc->frame_start_found= 0; - return i-(state&5); -} - -/*! - * Parse NAL units of found picture and decode some basic information. - * - * @param s parser context. - * @param avctx codec context. - * @param buf buffer with field/frame data. - * @param buf_size size of the buffer. - */ -static inline int parse_nal_units(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - H264Context *h = s->priv_data; - const uint8_t *buf_end = buf + buf_size; - unsigned int pps_id; - unsigned int slice_type; - int state = -1; - const uint8_t *ptr; - - /* set some sane default values */ - s->pict_type = FF_I_TYPE; - s->key_frame = 0; - - h->s.avctx= avctx; - h->sei_recovery_frame_cnt = -1; - h->sei_dpb_output_delay = 0; - h->sei_cpb_removal_delay = -1; - h->sei_buffering_period_present = 0; - - for(;;) { - int src_length, dst_length, consumed; - buf = ff_find_start_code(buf, buf_end, &state); - if(buf >= buf_end) - break; - --buf; - src_length = buf_end - buf; - switch (state & 0x1f) { - case NAL_SLICE: - case NAL_IDR_SLICE: - // Do not walk the whole buffer just to decode slice header - if (src_length > 20) - src_length = 20; - break; - } - ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); - if (ptr==NULL || dst_length < 0) - break; - - init_get_bits(&h->s.gb, ptr, 8*dst_length); - switch(h->nal_unit_type) { - case NAL_SPS: - ff_h264_decode_seq_parameter_set(h); - break; - case NAL_PPS: - ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits); - break; - case NAL_SEI: - ff_h264_decode_sei(h); - break; - case NAL_IDR_SLICE: - s->key_frame = 1; - /* fall through */ - case NAL_SLICE: - get_ue_golomb(&h->s.gb); // skip first_mb_in_slice - slice_type = get_ue_golomb_31(&h->s.gb); - s->pict_type = golomb_to_pict_type[slice_type % 5]; - if (h->sei_recovery_frame_cnt >= 0) { - /* key frame, since recovery_frame_cnt is set */ - s->key_frame = 1; - } - pps_id= get_ue_golomb(&h->s.gb); - if(pps_id>=MAX_PPS_COUNT) { - av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); - return -1; - } - if(!h->pps_buffers[pps_id]) { - av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n"); - return -1; - } - h->pps= *h->pps_buffers[pps_id]; - if(!h->sps_buffers[h->pps.sps_id]) { - av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n"); - return -1; - } - h->sps = *h->sps_buffers[h->pps.sps_id]; - h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num); - - avctx->profile = h->sps.profile_idc; - avctx->level = h->sps.level_idc; - - if(h->sps.frame_mbs_only_flag){ - h->s.picture_structure= PICT_FRAME; - }else{ - if(get_bits1(&h->s.gb)) { //field_pic_flag - h->s.picture_structure= PICT_TOP_FIELD + get_bits1(&h->s.gb); //bottom_field_flag - } else { - h->s.picture_structure= PICT_FRAME; - } - } - - if(h->sps.pic_struct_present_flag) { - switch (h->sei_pic_struct) { - case SEI_PIC_STRUCT_TOP_FIELD: - case SEI_PIC_STRUCT_BOTTOM_FIELD: - s->repeat_pict = 0; - break; - case SEI_PIC_STRUCT_FRAME: - case SEI_PIC_STRUCT_TOP_BOTTOM: - case SEI_PIC_STRUCT_BOTTOM_TOP: - s->repeat_pict = 1; - break; - case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: - case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: - s->repeat_pict = 2; - break; - case SEI_PIC_STRUCT_FRAME_DOUBLING: - s->repeat_pict = 3; - break; - case SEI_PIC_STRUCT_FRAME_TRIPLING: - s->repeat_pict = 5; - break; - default: - s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; - break; - } - } else { - s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; - } - - return 0; /* no need to evaluate the rest */ - } - buf += consumed; - } - /* didn't find a picture! */ - av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n"); - return -1; -} - -static int h264_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const 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; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= ff_h264_find_frame_end(h, buf, buf_size); - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - if(next<0 && next != END_NOT_FOUND){ - assert(pc->last_index + next >= 0 ); - ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state - } - - parse_nal_units(s, avctx, buf, buf_size); - - if (h->sei_cpb_removal_delay >= 0) { - s->dts_sync_point = h->sei_buffering_period_present; - s->dts_ref_dts_delta = h->sei_cpb_removal_delay; - s->pts_dts_delta = h->sei_dpb_output_delay; - } else { - s->dts_sync_point = INT_MIN; - s->dts_ref_dts_delta = INT_MIN; - s->pts_dts_delta = INT_MIN; - } - } - - *poutbuf = 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 (ipriv_data; - ParseContext *pc = &h->s.parse_context; - - av_free(pc->buffer); - ff_h264_free_context(h); -} - -static int init(AVCodecParserContext *s) -{ - H264Context *h = s->priv_data; - h->thread_context[0] = h; - return 0; -} - -AVCodecParser h264_parser = { - { CODEC_ID_H264 }, - sizeof(H264Context), - init, - h264_parse, - close, - h264_split, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_parser.h b/tizen/distrib/ffmpeg/libavcodec/h264_parser.h deleted file mode 100644 index 149f49a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_parser.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... parser - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 parser. - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_H264_PARSER_H -#define AVCODEC_H264_PARSER_H - -#include "h264.h" - -/** - * 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_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size); - -#endif /* AVCODEC_H264_PARSER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_ps.c b/tizen/distrib/ffmpeg/libavcodec/h264_ps.c deleted file mode 100644 index 7648e2c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_ps.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... parameter set decoding - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 parameter set decoding. - * @author Michael Niedermayer - */ - -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "h264.h" -#include "h264data.h" //FIXME FIXME FIXME (just for zigzag_scan) -#include "golomb.h" - - -//#undef NDEBUG -#include - -static const AVRational pixel_aspect[17]={ - {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}, - {4, 3}, - {3, 2}, - {2, 1}, -}; - -const uint8_t ff_h264_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 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 inline int decode_hrd_parameters(H264Context *h, SPS *sps){ - MpegEncContext * const s = &h->s; - int cpb_count, i; - cpb_count = get_ue_golomb_31(&s->gb) + 1; - - if(cpb_count > 32U){ - av_log(h->s.avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count); - return -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 */ - } - sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1; - sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1; - sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1; - sps->time_offset_length = get_bits(&s->gb, 5); - sps->cpb_cnt = cpb_count; - return 0; -} - -static inline int decode_vui_parameters(H264Context *h, SPS *sps){ - MpegEncContext * const s = &h->s; - int aspect_ratio_info_present_flag; - unsigned int aspect_ratio_idc; - - 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 < FF_ARRAY_ELEMS(pixel_aspect)){ - 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 */ - } - - sps->video_signal_type_present_flag = get_bits1(&s->gb); - if(sps->video_signal_type_present_flag){ - get_bits(&s->gb, 3); /* video_format */ - sps->full_range = get_bits1(&s->gb); /* video_full_range_flag */ - - sps->colour_description_present_flag = get_bits1(&s->gb); - if(sps->colour_description_present_flag){ - sps->color_primaries = get_bits(&s->gb, 8); /* colour_primaries */ - sps->color_trc = get_bits(&s->gb, 8); /* transfer_characteristics */ - sps->colorspace = get_bits(&s->gb, 8); /* matrix_coefficients */ - if (sps->color_primaries >= AVCOL_PRI_NB) - sps->color_primaries = AVCOL_PRI_UNSPECIFIED; - if (sps->color_trc >= AVCOL_TRC_NB) - sps->color_trc = AVCOL_TRC_UNSPECIFIED; - if (sps->colorspace >= AVCOL_SPC_NB) - sps->colorspace = AVCOL_SPC_UNSPECIFIED; - } - } - - if(get_bits1(&s->gb)){ /* chroma_location_info_present_flag */ - s->avctx->chroma_sample_location = get_ue_golomb(&s->gb)+1; /* 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); - if(!sps->num_units_in_tick || !sps->time_scale){ - av_log(h->s.avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick); - return -1; - } - sps->fixed_frame_rate_flag = get_bits1(&s->gb); - } - - sps->nal_hrd_parameters_present_flag = get_bits1(&s->gb); - if(sps->nal_hrd_parameters_present_flag) - if(decode_hrd_parameters(h, sps) < 0) - return -1; - sps->vcl_hrd_parameters_present_flag = get_bits1(&s->gb); - if(sps->vcl_hrd_parameters_present_flag) - if(decode_hrd_parameters(h, sps) < 0) - return -1; - if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) - get_bits1(&s->gb); /* low_delay_hrd_flag */ - sps->pic_struct_present_flag = get_bits1(&s->gb); - - 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*/ - - if(s->gb.size_in_bits < get_bits_count(&s->gb)){ - av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", get_bits_count(&s->gb) - s->gb.size_in_bits); - sps->num_reorder_frames=0; - sps->bitstream_restriction_flag= 0; - } - - if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames); - return -1; - } - } - - 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 : ff_zigzag_direct; - 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 - } - } -} - -int ff_h264_decode_seq_parameter_set(H264Context *h){ - MpegEncContext * const s = &h->s; - int profile_idc, level_idc; - unsigned int sps_id; - int 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_31(&s->gb); - - if(sps_id >= MAX_SPS_COUNT) { - av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id); - return -1; - } - sps= av_mallocz(sizeof(SPS)); - if(sps == NULL) - return -1; - - sps->profile_idc= profile_idc; - sps->level_idc= level_idc; - - memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4)); - memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8)); - sps->scaling_matrix_present = 0; - - if(sps->profile_idc >= 100){ //high profile - sps->chroma_format_idc= get_ue_golomb_31(&s->gb); - if(sps->chroma_format_idc == 3) - sps->residual_color_transform_flag = get_bits1(&s->gb); - sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; - sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; - sps->transform_bypass = get_bits1(&s->gb); - decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); - }else{ - sps->chroma_format_idc= 1; - sps->bit_depth_luma = 8; - sps->bit_depth_chroma = 8; - } - - sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4; - sps->poc_type= get_ue_golomb_31(&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); - - if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){ - av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length); - goto fail; - } - - for(i=0; ipoc_cycle_length; i++) - sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb); - }else if(sps->poc_type != 2){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type); - goto fail; - } - - sps->ref_frame_count= get_ue_golomb_31(&s->gb); - if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){ - av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); - goto fail; - } - 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)){ - av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n"); - goto fail; - } - - 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); - if(!sps->frame_mbs_only_flag && !sps->direct_8x8_inference_flag){ - av_log(h->s.avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n"); - goto fail; - } - -#ifndef ALLOW_INTERLACE - if(sps->mb_aff) - av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n"); -#endif - 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"); - } - if(sps->crop_right >= 8 || sps->crop_bottom >= (8>> !sps->frame_mbs_only_flag)){ - av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not 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 ) - if (decode_vui_parameters(h, sps) < 0) - goto fail; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d\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" : "", - ((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc], - sps->timing_info_present_flag ? sps->num_units_in_tick : 0, - sps->timing_info_present_flag ? sps->time_scale : 0 - ); - } - - av_free(h->sps_buffers[sps_id]); - h->sps_buffers[sps_id]= sps; - h->sps = *sps; - return 0; -fail: - av_free(sps); - return -1; -} - -static void -build_qp_table(PPS *pps, int t, int index) -{ - int i; - for(i = 0; i < 52; i++) - pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[av_clip(i + index, 0, 51)]; -} - -int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ - MpegEncContext * const s = &h->s; - unsigned int pps_id= get_ue_golomb(&s->gb); - PPS *pps; - - if(pps_id >= MAX_PPS_COUNT) { - av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id); - return -1; - } - - pps= av_mallocz(sizeof(PPS)); - if(pps == NULL) - return -1; - pps->sps_id= get_ue_golomb_31(&s->gb); - if((unsigned)pps->sps_id>=MAX_SPS_COUNT || h->sps_buffers[pps->sps_id] == NULL){ - av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n"); - goto fail; - } - - 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]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){ - av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n"); - goto fail; - } - - 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[0]= 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); - - pps->transform_8x8_mode= 0; - h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit - memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4)); - memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8)); - - if(get_bits_count(&s->gb) < bit_length){ - pps->transform_8x8_mode= get_bits1(&s->gb); - decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); - pps->chroma_qp_index_offset[1]= get_se_golomb(&s->gb); //second_chroma_qp_index_offset - } else { - pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0]; - } - - build_qp_table(pps, 0, pps->chroma_qp_index_offset[0]); - build_qp_table(pps, 1, pps->chroma_qp_index_offset[1]); - if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1]) - pps->chroma_qp_diff= 1; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%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[0], pps->chroma_qp_index_offset[1], - pps->deblocking_filter_parameters_present ? "LPAR" : "", - pps->constrained_intra_pred ? "CONSTR" : "", - pps->redundant_pic_cnt_present ? "REDU" : "", - pps->transform_8x8_mode ? "8x8DCT" : "" - ); - } - - av_free(h->pps_buffers[pps_id]); - h->pps_buffers[pps_id]= pps; - return 0; -fail: - av_free(pps); - return -1; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_refs.c b/tizen/distrib/ffmpeg/libavcodec/h264_refs.c deleted file mode 100644 index ed715c6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_refs.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... reference picture handling - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 reference picture handling. - * @author Michael Niedermayer - */ - -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "h264.h" -#include "golomb.h" - -//#undef NDEBUG -#include - - -static void pic_as_field(Picture *pic, const int parity){ - int i; - for (i = 0; i < 4; ++i) { - if (parity == PICT_BOTTOM_FIELD) - pic->data[i] += pic->linesize[i]; - pic->reference = parity; - pic->linesize[i] *= 2; - } - pic->poc= pic->field_poc[parity == PICT_BOTTOM_FIELD]; -} - -static int split_field_copy(Picture *dest, Picture *src, - int parity, int id_add){ - int match = !!(src->reference & parity); - - if (match) { - *dest = *src; - if(parity != PICT_FRAME){ - pic_as_field(dest, parity); - dest->pic_id *= 2; - dest->pic_id += id_add; - } - } - - return match; -} - -static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel){ - int i[2]={0}; - int index=0; - - while(i[0]reference & sel))) - i[0]++; - while(i[1]reference & (sel^3)))) - i[1]++; - if(i[0] < len){ - in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num; - split_field_copy(&def[index++], in[ i[0]++ ], sel , 1); - } - if(i[1] < len){ - in[ i[1] ]->pic_id= is_long ? i[1] : in[ i[1] ]->frame_num; - split_field_copy(&def[index++], in[ i[1]++ ], sel^3, 0); - } - } - - return index; -} - -static int add_sorted(Picture **sorted, Picture **src, int len, int limit, int dir){ - int i, best_poc; - int out_i= 0; - - for(;;){ - best_poc= dir ? INT_MIN : INT_MAX; - - for(i=0; ipoc; - if(((poc > limit) ^ dir) && ((poc < best_poc) ^ dir)){ - best_poc= poc; - sorted[out_i]= src[i]; - } - } - if(best_poc == (dir ? INT_MIN : INT_MAX)) - break; - limit= sorted[out_i++]->poc - dir; - } - return out_i; -} - -int ff_h264_fill_default_ref_list(H264Context *h){ - MpegEncContext * const s = &h->s; - int i, len; - - if(h->slice_type_nos==FF_B_TYPE){ - Picture *sorted[32]; - int cur_poc, list; - int lens[2]; - - if(FIELD_PICTURE) - cur_poc= s->current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; - else - cur_poc= s->current_picture_ptr->poc; - - for(list= 0; list<2; list++){ - len= add_sorted(sorted , h->short_ref, h->short_ref_count, cur_poc, 1^list); - len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list); - assert(len<=32); - len= build_def_list(h->default_ref_list[list] , sorted , len, 0, s->picture_structure); - len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure); - assert(len<=32); - - if(len < h->ref_count[list]) - memset(&h->default_ref_list[list][len], 0, sizeof(Picture)*(h->ref_count[list] - len)); - lens[list]= len; - } - - if(lens[0] == lens[1] && lens[1] > 1){ - for(i=0; h->default_ref_list[0][i].data[0] == h->default_ref_list[1][i].data[0] && idefault_ref_list[1][0], h->default_ref_list[1][1]); - } - }else{ - len = build_def_list(h->default_ref_list[0] , h->short_ref, h->short_ref_count, 0, s->picture_structure); - len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16 , 1, s->picture_structure); - assert(len <= 32); - if(len < h->ref_count[0]) - memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len)); - } -#ifdef TRACE - for (i=0; iref_count[0]; i++) { - tprintf(h->s.avctx, "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_nos==FF_B_TYPE){ - for (i=0; iref_count[1]; i++) { - tprintf(h->s.avctx, "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[1][i].data[0]); - } - } -#endif - return 0; -} - -static void print_short_term(H264Context *h); -static void print_long_term(H264Context *h); - -/** - * Extract structure information about the picture described by pic_num in - * the current decoding context (frame or field). Note that pic_num is - * picture number without wrapping (so, 0<=pic_nums; - - *structure = s->picture_structure; - if(FIELD_PICTURE){ - if (!(pic_num & 1)) - /* opposite field */ - *structure ^= PICT_FRAME; - pic_num >>= 1; - } - - return pic_num; -} - -int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ - MpegEncContext * const s = &h->s; - int list, index, pic_structure; - - print_short_term(h); - print_long_term(h); - - for(list=0; listlist_count; 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++){ - unsigned int reordering_of_pic_nums_idc= get_ue_golomb_31(&s->gb); - unsigned 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 unsigned int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1; - int frame_num; - - 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; - - frame_num = pic_num_extract(h, pred, &pic_structure); - - for(i= h->short_ref_count-1; i>=0; i--){ - ref = h->short_ref[i]; - assert(ref->reference); - assert(!ref->long_ref); - if( - ref->frame_num == frame_num && - (ref->reference & pic_structure) - ) - break; - } - if(i>=0) - ref->pic_id= pred; - }else{ - int long_idx; - pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx - - long_idx= pic_num_extract(h, pic_id, &pic_structure); - - if(long_idx>31){ - av_log(h->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); - return -1; - } - ref = h->long_ref[long_idx]; - assert(!(ref && !ref->reference)); - if(ref && (ref->reference & pic_structure)){ - ref->pic_id= pic_id; - assert(ref->long_ref); - i=0; - }else{ - i=-1; - } - } - - 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; - if (FIELD_PICTURE){ - pic_as_field(&h->ref_list[list][index], pic_structure); - } - } - }else{ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); - return -1; - } - } - } - } - for(list=0; listlist_count; list++){ - for(index= 0; index < h->ref_count[list]; index++){ - if(!h->ref_list[list][index].data[0]){ - av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture\n"); - if(h->default_ref_list[list][0].data[0]) - h->ref_list[list][index]= h->default_ref_list[list][0]; - else - return -1; - } - } - } - - return 0; -} - -void ff_h264_fill_mbaff_ref_list(H264Context *h){ - int list, i, j; - for(list=0; list<2; list++){ //FIXME try list_count - for(i=0; iref_count[list]; i++){ - Picture *frame = &h->ref_list[list][i]; - Picture *field = &h->ref_list[list][16+2*i]; - field[0] = *frame; - for(j=0; j<3; j++) - field[0].linesize[j] <<= 1; - field[0].reference = PICT_TOP_FIELD; - field[0].poc= field[0].field_poc[0]; - field[1] = field[0]; - for(j=0; j<3; j++) - field[1].data[j] += frame->linesize[j]; - field[1].reference = PICT_BOTTOM_FIELD; - field[1].poc= field[1].field_poc[1]; - - h->luma_weight[16+2*i][list][0] = h->luma_weight[16+2*i+1][list][0] = h->luma_weight[i][list][0]; - h->luma_weight[16+2*i][list][1] = h->luma_weight[16+2*i+1][list][1] = h->luma_weight[i][list][1]; - for(j=0; j<2; j++){ - h->chroma_weight[16+2*i][list][j][0] = h->chroma_weight[16+2*i+1][list][j][0] = h->chroma_weight[i][list][j][0]; - h->chroma_weight[16+2*i][list][j][1] = h->chroma_weight[16+2*i+1][list][j][1] = h->chroma_weight[i][list][j][1]; - } - } - } -} - -/** - * Mark a picture as no longer needed for reference. The refmask - * argument allows unreferencing of individual fields or the whole frame. - * If the picture becomes entirely unreferenced, but is being held for - * display purposes, it is marked as such. - * @param refmask mask of fields to unreference; the mask is bitwise - * anded with the reference marking of pic - * @return non-zero if pic becomes entirely unreferenced (except possibly - * for display purposes) zero if one of the fields remains in - * reference - */ -static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){ - int i; - if (pic->reference &= refmask) { - return 0; - } else { - for(i = 0; h->delayed_pic[i]; i++) - if(pic == h->delayed_pic[i]){ - pic->reference=DELAYED_PIC_REF; - break; - } - return 1; - } -} - -/** - * Find a Picture in the short term reference list by frame number. - * @param frame_num frame number to search for - * @param idx the index into h->short_ref where returned picture is found - * undefined if no picture found. - * @return pointer to the found picture, or NULL if no pic with the provided - * frame number is found - */ -static Picture * find_short(H264Context *h, int frame_num, int *idx){ - MpegEncContext * const s = &h->s; - int i; - - 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) { - *idx = i; - return pic; - } - } - return NULL; -} - -/** - * Remove a picture from the short term reference list by its index in - * that list. This does no checking on the provided index; it is assumed - * to be valid. Other list entries are shifted down. - * @param i index into h->short_ref of picture to remove. - */ -static void remove_short_at_index(H264Context *h, int i){ - assert(i >= 0 && i < h->short_ref_count); - h->short_ref[i]= NULL; - if (--h->short_ref_count) - memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i)*sizeof(Picture*)); -} - -/** - * - * @return the removed picture or NULL if an error occurs - */ -static Picture * remove_short(H264Context *h, int frame_num, int ref_mask){ - MpegEncContext * const s = &h->s; - Picture *pic; - 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); - - pic = find_short(h, frame_num, &i); - if (pic){ - if(unreference_pic(h, pic, ref_mask)) - remove_short_at_index(h, i); - } - - return pic; -} - -/** - * Remove a picture from the long term reference list by its index in - * that list. - * @return the removed picture or NULL if an error occurs - */ -static Picture * remove_long(H264Context *h, int i, int ref_mask){ - Picture *pic; - - pic= h->long_ref[i]; - if (pic){ - if(unreference_pic(h, pic, ref_mask)){ - assert(h->long_ref[i]->long_ref == 1); - h->long_ref[i]->long_ref= 0; - h->long_ref[i]= NULL; - h->long_ref_count--; - } - } - - return pic; -} - -void ff_h264_remove_all_refs(H264Context *h){ - int i; - - for(i=0; i<16; i++){ - remove_long(h, i, 0); - } - assert(h->long_ref_count==0); - - for(i=0; ishort_ref_count; i++){ - unreference_pic(h, h->short_ref[i], 0); - h->short_ref[i]= NULL; - } - h->short_ref_count=0; -} - -/** - * 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]); - } - } - } -} - -int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ - MpegEncContext * const s = &h->s; - int i, av_uninit(j); - int current_ref_assigned=0; - Picture *av_uninit(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_pic_num, h->mmco[i].long_arg); - - if( mmco[i].opcode == MMCO_SHORT2UNUSED - || mmco[i].opcode == MMCO_SHORT2LONG){ - frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure); - pic = find_short(h, frame_num, &j); - if(!pic){ - if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] - || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) - av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); - continue; - } - } - - switch(mmco[i].opcode){ - case MMCO_SHORT2UNUSED: - if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count); - remove_short(h, frame_num, structure ^ PICT_FRAME); - break; - case MMCO_SHORT2LONG: - if (h->long_ref[mmco[i].long_arg] != pic) - remove_long(h, mmco[i].long_arg, 0); - - remove_short_at_index(h, j); - h->long_ref[ mmco[i].long_arg ]= pic; - if (h->long_ref[ mmco[i].long_arg ]){ - h->long_ref[ mmco[i].long_arg ]->long_ref=1; - h->long_ref_count++; - } - break; - case MMCO_LONG2UNUSED: - j = pic_num_extract(h, mmco[i].long_arg, &structure); - pic = h->long_ref[j]; - if (pic) { - remove_long(h, j, structure ^ PICT_FRAME); - } else if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); - break; - case MMCO_LONG: - // Comment below left from previous code as it is an interresting note. - /* First field in pair is in short term list or - * at a different long term index. - * This is not allowed; see 7.4.3.3, notes 2 and 3. - * Report the problem and keep the pair where it is, - * and mark this field valid. - */ - - if (h->long_ref[mmco[i].long_arg] != s->current_picture_ptr) { - remove_long(h, mmco[i].long_arg, 0); - - h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr; - h->long_ref[ mmco[i].long_arg ]->long_ref=1; - h->long_ref_count++; - } - - s->current_picture_ptr->reference |= s->picture_structure; - current_ref_assigned=1; - break; - case MMCO_SET_MAX_LONG: - assert(mmco[i].long_arg <= 16); - // just remove the long term which index is greater than new max - for(j = mmco[i].long_arg; j<16; j++){ - remove_long(h, j, 0); - } - break; - case MMCO_RESET: - while(h->short_ref_count){ - remove_short(h, h->short_ref[0]->frame_num, 0); - } - for(j = 0; j < 16; j++) { - remove_long(h, j, 0); - } - s->current_picture_ptr->poc= - s->current_picture_ptr->field_poc[0]= - s->current_picture_ptr->field_poc[1]= - h->poc_lsb= - h->poc_msb= - h->frame_num= - s->current_picture_ptr->frame_num= 0; - s->current_picture_ptr->mmco_reset=1; - break; - default: assert(0); - } - } - - if (!current_ref_assigned) { - /* Second field of complementary field pair; the first field of - * which is already referenced. If short referenced, it - * should be first entry in short_ref. If not, it must exist - * in long_ref; trying to put it on the short list here is an - * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3). - */ - if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) { - /* Just mark the second field valid */ - s->current_picture_ptr->reference = PICT_FRAME; - } else if (s->current_picture_ptr->long_ref) { - av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference " - "assignment for second field " - "in complementary field pair " - "(first field is long term)\n"); - } else { - pic= remove_short(h, s->current_picture_ptr->frame_num, 0); - if(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_count++; - s->current_picture_ptr->reference |= s->picture_structure; - } - } - - if (h->long_ref_count + h->short_ref_count > h->sps.ref_frame_count){ - - /* We have too many reference frames, probably due to corrupted - * stream. Need to discard one frame. Prevents overrun of the - * short_ref and long_ref buffers. - */ - av_log(h->s.avctx, AV_LOG_ERROR, - "number of reference frames exceeds max (probably " - "corrupt input), discarding one\n"); - - if (h->long_ref_count && !h->short_ref_count) { - for (i = 0; i < 16; ++i) - if (h->long_ref[i]) - break; - - assert(i < 16); - remove_long(h, i, 0); - } else { - pic = h->short_ref[h->short_ref_count - 1]; - remove_short(h, pic->frame_num, 0); - } - } - - print_short_term(h); - print_long_term(h); - return 0; -} - -int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ - MpegEncContext * const s = &h->s; - int i; - - h->mmco_index= 0; - if(h->nal_unit_type == NAL_IDR_SLICE){ //FIXME fields - s->broken_link= get_bits1(gb) -1; - if(get_bits1(gb)){ - h->mmco[0].opcode= MMCO_LONG; - h->mmco[0].long_arg= 0; - h->mmco_index= 1; - } - }else{ - if(get_bits1(gb)){ // adaptive_ref_pic_marking_mode_flag - for(i= 0; immco[i].opcode= opcode; - if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){ - h->mmco[i].short_pic_num= (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); -/* if(h->mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_pic_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){ - unsigned int long_arg= get_ue_golomb_31(gb); - if(long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode); - return -1; - } - h->mmco[i].long_arg= long_arg; - } - - if(opcode > (unsigned)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->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count && - !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->reference)) { - h->mmco[0].opcode= MMCO_SHORT2UNUSED; - h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; - h->mmco_index= 1; - if (FIELD_PICTURE) { - h->mmco[0].short_pic_num *= 2; - h->mmco[1].opcode= MMCO_SHORT2UNUSED; - h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1; - h->mmco_index= 2; - } - } - } - } - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264_sei.c b/tizen/distrib/ffmpeg/libavcodec/h264_sei.c deleted file mode 100644 index 195ea28..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264_sei.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... sei decoding - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 sei decoding. - * @author Michael Niedermayer - */ - -#include "internal.h" -#include "avcodec.h" -#include "h264.h" -#include "golomb.h" - -//#undef NDEBUG -#include - -static const uint8_t sei_num_clock_ts_table[9]={ - 1, 1, 1, 2, 2, 3, 3, 2, 3 -}; - -void ff_h264_reset_sei(H264Context *h) { - h->sei_recovery_frame_cnt = -1; - h->sei_dpb_output_delay = 0; - h->sei_cpb_removal_delay = -1; - h->sei_buffering_period_present = 0; -} - -static int decode_picture_timing(H264Context *h){ - MpegEncContext * const s = &h->s; - if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){ - h->sei_cpb_removal_delay = get_bits(&s->gb, h->sps.cpb_removal_delay_length); - h->sei_dpb_output_delay = get_bits(&s->gb, h->sps.dpb_output_delay_length); - } - if(h->sps.pic_struct_present_flag){ - unsigned int i, num_clock_ts; - h->sei_pic_struct = get_bits(&s->gb, 4); - h->sei_ct_type = 0; - - if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING) - return -1; - - num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct]; - - for (i = 0 ; i < num_clock_ts ; i++){ - if(get_bits(&s->gb, 1)){ /* clock_timestamp_flag */ - unsigned int full_timestamp_flag; - h->sei_ct_type |= 1<gb, 2); - skip_bits(&s->gb, 1); /* nuit_field_based_flag */ - skip_bits(&s->gb, 5); /* counting_type */ - full_timestamp_flag = get_bits(&s->gb, 1); - skip_bits(&s->gb, 1); /* discontinuity_flag */ - skip_bits(&s->gb, 1); /* cnt_dropped_flag */ - skip_bits(&s->gb, 8); /* n_frames */ - if(full_timestamp_flag){ - skip_bits(&s->gb, 6); /* seconds_value 0..59 */ - skip_bits(&s->gb, 6); /* minutes_value 0..59 */ - skip_bits(&s->gb, 5); /* hours_value 0..23 */ - }else{ - if(get_bits(&s->gb, 1)){ /* seconds_flag */ - skip_bits(&s->gb, 6); /* seconds_value range 0..59 */ - if(get_bits(&s->gb, 1)){ /* minutes_flag */ - skip_bits(&s->gb, 6); /* minutes_value 0..59 */ - if(get_bits(&s->gb, 1)) /* hours_flag */ - skip_bits(&s->gb, 5); /* hours_value 0..23 */ - } - } - } - if(h->sps.time_offset_length > 0) - skip_bits(&s->gb, h->sps.time_offset_length); /* time_offset */ - } - } - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", h->sei_ct_type, h->sei_pic_struct); - } - return 0; -} - -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_recovery_point(H264Context *h){ - MpegEncContext * const s = &h->s; - - h->sei_recovery_frame_cnt = get_ue_golomb(&s->gb); - skip_bits(&s->gb, 4); /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */ - - return 0; -} - -static int decode_buffering_period(H264Context *h){ - MpegEncContext * const s = &h->s; - unsigned int sps_id; - int sched_sel_idx; - SPS *sps; - - sps_id = get_ue_golomb_31(&s->gb); - if(sps_id > 31 || !h->sps_buffers[sps_id]) { - av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id); - return -1; - } - sps = h->sps_buffers[sps_id]; - - // NOTE: This is really so duplicated in the standard... See H.264, D.1.1 - if (sps->nal_hrd_parameters_present_flag) { - for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { - h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length); - skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset - } - } - if (sps->vcl_hrd_parameters_present_flag) { - for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { - h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length); - skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset - } - } - - h->sei_buffering_period_present = 1; - return 0; -} - -int ff_h264_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 SEI_TYPE_PIC_TIMING: // Picture timing SEI - if(decode_picture_timing(h) < 0) - return -1; - break; - case SEI_TYPE_USER_DATA_UNREGISTERED: - if(decode_unregistered_user_data(h, size) < 0) - return -1; - break; - case SEI_TYPE_RECOVERY_POINT: - if(decode_recovery_point(h) < 0) - return -1; - break; - case SEI_BUFFERING_PERIOD: - if(decode_buffering_period(h) < 0) - return -1; - break; - default: - skip_bits(&s->gb, 8*size); - } - - //FIXME check bits here - align_get_bits(&s->gb); - } - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264data.h b/tizen/distrib/ffmpeg/libavcodec/h264data.h deleted file mode 100644 index b3631da..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264data.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * H26L/H264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief - * H264 / AVC / MPEG4 part10 codec data table - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_H264DATA_H -#define AVCODEC_H264DATA_H - -#include -#include "libavutil/rational.h" -#include "mpegvideo.h" -#include "h264.h" - - -static const uint8_t golomb_to_pict_type[5]= -{FF_P_TYPE, FF_B_TYPE, FF_I_TYPE, FF_SP_TYPE, FF_SI_TYPE}; - -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 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 -}; - -// 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, -}; - -static const uint8_t field_scan8x8[64]={ - 0+0*8, 0+1*8, 0+2*8, 1+0*8, - 1+1*8, 0+3*8, 0+4*8, 1+2*8, - 2+0*8, 1+3*8, 0+5*8, 0+6*8, - 0+7*8, 1+4*8, 2+1*8, 3+0*8, - 2+2*8, 1+5*8, 1+6*8, 1+7*8, - 2+3*8, 3+1*8, 4+0*8, 3+2*8, - 2+4*8, 2+5*8, 2+6*8, 2+7*8, - 3+3*8, 4+1*8, 5+0*8, 4+2*8, - 3+4*8, 3+5*8, 3+6*8, 3+7*8, - 4+3*8, 5+1*8, 6+0*8, 5+2*8, - 4+4*8, 4+5*8, 4+6*8, 4+7*8, - 5+3*8, 6+1*8, 6+2*8, 5+4*8, - 5+5*8, 5+6*8, 5+7*8, 6+3*8, - 7+0*8, 7+1*8, 6+4*8, 6+5*8, - 6+6*8, 6+7*8, 7+2*8, 7+3*8, - 7+4*8, 7+5*8, 7+6*8, 7+7*8, -}; - -static const uint8_t field_scan8x8_cavlc[64]={ - 0+0*8, 1+1*8, 2+0*8, 0+7*8, - 2+2*8, 2+3*8, 2+4*8, 3+3*8, - 3+4*8, 4+3*8, 4+4*8, 5+3*8, - 5+5*8, 7+0*8, 6+6*8, 7+4*8, - 0+1*8, 0+3*8, 1+3*8, 1+4*8, - 1+5*8, 3+1*8, 2+5*8, 4+1*8, - 3+5*8, 5+1*8, 4+5*8, 6+1*8, - 5+6*8, 7+1*8, 6+7*8, 7+5*8, - 0+2*8, 0+4*8, 0+5*8, 2+1*8, - 1+6*8, 4+0*8, 2+6*8, 5+0*8, - 3+6*8, 6+0*8, 4+6*8, 6+2*8, - 5+7*8, 6+4*8, 7+2*8, 7+6*8, - 1+0*8, 1+2*8, 0+6*8, 3+0*8, - 1+7*8, 3+2*8, 2+7*8, 4+2*8, - 3+7*8, 5+2*8, 4+7*8, 5+4*8, - 6+3*8, 6+5*8, 7+3*8, 7+7*8, -}; - -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|MB_TYPE_L0L1 , 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 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 uint8_t dequant8_coeff_init_scan[16] = { - 0,3,4,3, 3,1,5,1, 4,5,2,5, 3,1,5,1 -}; -static const uint8_t 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}, -}; - -#endif /* AVCODEC_H264DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h264dsp.c b/tizen/distrib/ffmpeg/libavcodec/h264dsp.c deleted file mode 100644 index c01fc77..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264dsp.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 DSP functions. - * @author Michael Niedermayer - */ - -#include -#include "avcodec.h" -#include "h264dsp.h" - -#define op_scale1(x) block[x] = av_clip_uint8( (block[x]*weight + offset) >> log2_denom ) -#define op_scale2(x) dst[x] = av_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> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] ); - tc++; - } - if( FFABS( q2 - q0 ) < beta ) { - if(tc0[i]) - pix[ xstride] = q1 + av_clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] ); - tc++; - } - - i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - pix[-xstride] = av_clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = av_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 av_always_inline av_flatten void h264_loop_filter_luma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta) -{ - int d; - for( d = 0; d < 16; d++ ) { - const int p2 = pix[-3*xstride]; - const int p1 = pix[-2*xstride]; - const int p0 = pix[-1*xstride]; - - const int q0 = pix[ 0*xstride]; - const int q1 = pix[ 1*xstride]; - const int q2 = pix[ 2*xstride]; - - if( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - - if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){ - if( FFABS( p2 - p0 ) < beta) - { - const int p3 = pix[-4*xstride]; - /* p0', p1', p2' */ - pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; - pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; - pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; - } else { - /* p0' */ - pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; - } - if( FFABS( q2 - q0 ) < beta) - { - const int q3 = pix[3*xstride]; - /* q0', q1', q2' */ - pix[0*xstride] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; - pix[1*xstride] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; - pix[2*xstride] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; - } else { - /* q0' */ - pix[0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; - } - }else{ - /* p0', q0' */ - pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; - pix[ 0*xstride] = ( 2*q1 + q0 + p1 + 2 ) >> 2; - } - } - pix += ystride; - } -} -static void h264_v_loop_filter_luma_intra_c(uint8_t *pix, int stride, int alpha, int beta) -{ - h264_loop_filter_luma_intra_c(pix, stride, 1, alpha, beta); -} -static void h264_h_loop_filter_luma_intra_c(uint8_t *pix, int stride, int alpha, int beta) -{ - h264_loop_filter_luma_intra_c(pix, 1, stride, alpha, beta); -} - -static av_always_inline av_flatten 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( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - - int delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - - pix[-xstride] = av_clip_uint8( p0 + delta ); /* p0' */ - pix[0] = av_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 av_always_inline av_flatten 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( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( 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); -} - -void ff_h264dsp_init(H264DSPContext *c) -{ - 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->h264_idct_add16 = ff_h264_idct_add16_c; - c->h264_idct8_add4 = ff_h264_idct8_add4_c; - c->h264_idct_add8 = ff_h264_idct_add8_c; - c->h264_idct_add16intra= ff_h264_idct_add16intra_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->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_luma_intra= h264_v_loop_filter_luma_intra_c; - c->h264_h_loop_filter_luma_intra= h264_h_loop_filter_luma_intra_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->h264_loop_filter_strength= NULL; - - if (ARCH_ARM) ff_h264dsp_init_arm(c); - if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c); - if (HAVE_MMX) ff_h264dsp_init_x86(c); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264dsp.h b/tizen/distrib/ffmpeg/libavcodec/h264dsp.h deleted file mode 100644 index 3d32a9c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264dsp.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2003-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 DSP functions. - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_H264DSP_H -#define AVCODEC_H264DSP_H - -#include -#include "dsputil.h" - -//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); - -/** - * Context for storing H.264 DSP functions - */ -typedef struct H264DSPContext{ - /* weighted MC */ - h264_weight_func weight_h264_pixels_tab[10]; - h264_biweight_func biweight_h264_pixels_tab[10]; - - /* loop filter */ - void (*h264_v_loop_filter_luma)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0); - void (*h264_h_loop_filter_luma)(uint8_t *pix/*align 4 */, int stride, int alpha, int beta, int8_t *tc0); - /* v/h_loop_filter_luma_intra: align 16 */ - void (*h264_v_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta); - void (*h264_h_loop_filter_luma_intra)(uint8_t *pix, int stride, int alpha, int beta); - void (*h264_v_loop_filter_chroma)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta, int8_t *tc0); - void (*h264_h_loop_filter_chroma)(uint8_t *pix/*align 4*/, int stride, int alpha, int beta, int8_t *tc0); - void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); - void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); - // h264_loop_filter_strength: simd only. the C version is inlined in h264.c - void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], - int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field); - - /* IDCT */ - /* NOTE!!! if you implement any of h264_idct8_add, h264_idct8_add4 then you must implement all of them - NOTE!!! if you implement any of h264_idct_add, h264_idct_add16, h264_idct_add16intra, h264_idct_add8 then you must implement all of them - The reason for above, is that no 2 out of one list may use a different permutation. - */ - void (*h264_idct_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); - void (*h264_idct8_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); - void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); - void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); - void (*h264_dct)(DCTELEM block[4][4]); - void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); - void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); - void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); - void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); -}H264DSPContext; - -void ff_h264dsp_init(H264DSPContext *c); -void ff_h264dsp_init_arm(H264DSPContext *c); -void ff_h264dsp_init_ppc(H264DSPContext *c); -void ff_h264dsp_init_x86(H264DSPContext *c); - -#endif /* AVCODEC_H264DSP_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/h264dspenc.c b/tizen/distrib/ffmpeg/libavcodec/h264dspenc.c deleted file mode 100644 index b65a2cc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264dspenc.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * H.264/MPEG-4 Part 10 (Base profile) encoder. - * - * DSP functions - * - * Copyright (c) 2006 Expertisecentrum Digitale Media, UHasselt - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 encoder related DSP utils - * - */ - -#include "dsputil.h" - -#define H264_DCT_PART1(X) \ - a = block[0][X]+block[3][X]; \ - c = block[0][X]-block[3][X]; \ - b = block[1][X]+block[2][X]; \ - d = block[1][X]-block[2][X]; \ - pieces[0][X] = a+b; \ - pieces[2][X] = a-b; \ - pieces[1][X] = (c<<1)+d; \ - pieces[3][X] = c-(d<<1); - -#define H264_DCT_PART2(X) \ - a = pieces[X][0]+pieces[X][3]; \ - c = pieces[X][0]-pieces[X][3]; \ - b = pieces[X][1]+pieces[X][2]; \ - d = pieces[X][1]-pieces[X][2]; \ - block[0][X] = a+b; \ - block[2][X] = a-b; \ - block[1][X] = (c<<1)+d; \ - block[3][X] = c-(d<<1); - -/** - * Transform the provided matrix using the H.264 modified DCT. - * @note - * we'll always work with transposed input blocks, to avoid having to make a - * distinction between C and mmx implementations. - * - * @param block transposed input block - */ -static void h264_dct_c(DCTELEM block[4][4]) -{ - DCTELEM pieces[4][4]; - DCTELEM a, b, c, d; - - H264_DCT_PART1(0); - H264_DCT_PART1(1); - H264_DCT_PART1(2); - H264_DCT_PART1(3); - H264_DCT_PART2(0); - H264_DCT_PART2(1); - H264_DCT_PART2(2); - H264_DCT_PART2(3); -} - -av_cold void ff_h264dspenc_init(DSPContext* c, AVCodecContext *avctx) -{ - c->h264_dct = h264_dct_c; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/h264enc.c b/tizen/distrib/ffmpeg/libavcodec/h264enc.c deleted file mode 100644 index ad874f3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264enc.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * H.264 encoder - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "libavutil/common.h" -#include "get_bits.h" -#include "mpegvideo.h" -#include "h264data.h" - -/** - * Write out the provided data into a NAL unit. - * @param nal_ref_idc NAL reference IDC - * @param nal_unit_type NAL unit payload type - * @param dest the target buffer, dst+1 == src is allowed as a special case - * @param destsize the length of the dst array - * @param b2 the data which should be escaped - * @return pointer to current position in the output buffer or NULL if an error occurred - */ -static uint8_t *h264_write_nal_unit(int nal_ref_idc, int nal_unit_type, uint8_t *dest, int *destsize, - PutBitContext *b2) -{ - PutBitContext b; - int i, destpos, rbsplen, escape_count; - uint8_t *rbsp; - - if (nal_unit_type != NAL_END_STREAM) - put_bits(b2,1,1); // rbsp_stop_bit - - // Align b2 on a byte boundary - align_put_bits(b2); - rbsplen = put_bits_count(b2)/8; - flush_put_bits(b2); - rbsp = b2->buf; - - init_put_bits(&b,dest,*destsize); - - put_bits(&b,16,0); - put_bits(&b,16,0x01); - - put_bits(&b,1,0); // forbidden zero bit - put_bits(&b,2,nal_ref_idc); // nal_ref_idc - put_bits(&b,5,nal_unit_type); // nal_unit_type - - flush_put_bits(&b); - - destpos = 5; - escape_count= 0; - - for (i=0; i0 && rbsp[i-1]==0) - i--; - if (i+2 *destsize) - { - av_log(NULL, AV_LOG_ERROR, "Destination buffer too small!\n"); - return NULL; - } - - // this should be damn rare (hopefully) - for (i = 0 ; i < rbsplen ; i++) - { - if (i + 2 < rbsplen && (rbsp[i] == 0 && rbsp[i+1] == 0 && rbsp[i+2] < 4)) - { - dest[destpos++] = rbsp[i++]; - dest[destpos++] = rbsp[i]; - dest[destpos++] = 0x03; // emulation prevention byte - } - else - dest[destpos++] = rbsp[i]; - } - *destsize -= destpos; - return dest+destpos; -} - -static const uint8_t pict_type_to_golomb[7] = {-1, 2, 0, 1, -1, 4, 3}; - -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 -}; - -#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,}, -}; - -//FIXME need to check that this does not overflow signed 32 bit for low qp, I am not sure, it's very close -//FIXME check that gcc inlines this (and optimizes intra & separate_dc stuff away) -static inline int quantize_c(DCTELEM *block, uint8_t *scantable, int qscale, - int intra, int separate_dc) -{ - int i; - const int * const quant_table = quant_coeff[qscale]; - const int bias = intra ? (1 << QUANT_SHIFT) / 3 : (1 << QUANT_SHIFT) / 6; - const unsigned int threshold1 = (1 << QUANT_SHIFT) - bias - 1; - const unsigned int threshold2 = (threshold1 << 1); - int last_non_zero; - - if (separate_dc) { - if (qscale <= 18) { - //avoid overflows - const int dc_bias = intra ? (1 << (QUANT_SHIFT - 2)) / 3 : (1 << (QUANT_SHIFT - 2)) / 6; - const unsigned int dc_threshold1 = (1 << (QUANT_SHIFT - 2)) - dc_bias - 1; - const unsigned int dc_threshold2 = (dc_threshold1 << 1); - - int level = block[0]*quant_coeff[qscale+18][0]; - if (((unsigned)(level + dc_threshold1)) > 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; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264idct.c b/tizen/distrib/ffmpeg/libavcodec/h264idct.c deleted file mode 100644 index da5c6a5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264idct.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * H.264 IDCT - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 IDCT. - * @author Michael Niedermayer - */ - -#include "dsputil.h" - -static av_always_inline void idct_internal(uint8_t *dst, DCTELEM *block, int stride, int block_stride, int shift, int add){ - int i; - uint8_t *cm = ff_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; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - block[0] += 32; - - for( i = 0; i < 8; i++ ) - { - const int a0 = block[0+i*8] + block[4+i*8]; - const int a2 = block[0+i*8] - block[4+i*8]; - const int a4 = (block[2+i*8]>>1) - block[6+i*8]; - const int a6 = (block[6+i*8]>>1) + block[2+i*8]; - - const int b0 = a0 + a6; - const int b2 = a2 + a4; - const int b4 = a2 - a4; - const int b6 = a0 - a6; - - const int a1 = -block[3+i*8] + block[5+i*8] - block[7+i*8] - (block[7+i*8]>>1); - const int a3 = block[1+i*8] + block[7+i*8] - block[3+i*8] - (block[3+i*8]>>1); - const int a5 = -block[1+i*8] + block[7+i*8] + block[5+i*8] + (block[5+i*8]>>1); - const int a7 = block[3+i*8] + block[5+i*8] + block[1+i*8] + (block[1+i*8]>>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); - - block[0+i*8] = b0 + b7; - block[7+i*8] = b0 - b7; - block[1+i*8] = b2 + b5; - block[6+i*8] = b2 - b5; - block[2+i*8] = b4 + b3; - block[5+i*8] = b4 - b3; - block[3+i*8] = b6 + b1; - block[4+i*8] = b6 - b1; - } - for( i = 0; i < 8; i++ ) - { - const int a0 = block[i+0*8] + block[i+4*8]; - const int a2 = block[i+0*8] - block[i+4*8]; - const int a4 = (block[i+2*8]>>1) - block[i+6*8]; - const int a6 = (block[i+6*8]>>1) + block[i+2*8]; - - const int b0 = a0 + a6; - const int b2 = a2 + a4; - const int b4 = a2 - a4; - const int b6 = a0 - a6; - - const int a1 = -block[i+3*8] + block[i+5*8] - block[i+7*8] - (block[i+7*8]>>1); - const int a3 = block[i+1*8] + block[i+7*8] - block[i+3*8] - (block[i+3*8]>>1); - const int a5 = -block[i+1*8] + block[i+7*8] + block[i+5*8] + (block[i+5*8]>>1); - const int a7 = block[i+3*8] + block[i+5*8] + block[i+1*8] + (block[i+1*8]>>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 = ff_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 = ff_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; - } -} - -//FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split -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, -}; - -void ff_h264_idct_add16_c(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) ff_h264_idct_dc_add_c(dst + block_offset[i], block + i*16, stride); - else idct_internal (dst + block_offset[i], block + i*16, stride, 4, 6, 1); - } - } -} - -void ff_h264_idct_add16intra_c(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - if(nnzc[ scan8[i] ]) idct_internal (dst + block_offset[i], block + i*16, stride, 4, 6, 1); - else if(block[i*16]) ff_h264_idct_dc_add_c(dst + block_offset[i], block + i*16, stride); - } -} - -void ff_h264_idct8_add4_c(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i+=4){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) ff_h264_idct8_dc_add_c(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct8_add_c (dst + block_offset[i], block + i*16, stride); - } - } -} - -void ff_h264_idct_add8_c(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=16; i<16+8; i++){ - if(nnzc[ scan8[i] ]) - ff_h264_idct_add_c (dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - else if(block[i*16]) - ff_h264_idct_dc_add_c(dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264pred.c b/tizen/distrib/ffmpeg/libavcodec/h264pred.c deleted file mode 100644 index 9637b45..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264pred.c +++ /dev/null @@ -1,1177 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 prediction functions. - * @author Michael Niedermayer - */ - -#include "avcodec.h" -#include "mpegvideo.h" -#include "h264pred.h" - -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 av_unused t4= topright[0];\ - const int av_unused t5= topright[1];\ - const int av_unused t6= topright[2];\ - const int av_unused t7= topright[3];\ - -#define LOAD_DOWN_LEFT_EDGE\ - const int av_unused l4= src[-1+4*stride];\ - const int av_unused l5= src[-1+5*stride];\ - const int av_unused l6= src[-1+6*stride];\ - const int av_unused l7= src[-1+7*stride];\ - -#define LOAD_LEFT_EDGE\ - const int av_unused l0= src[-1+0*stride];\ - const int av_unused l1= src[-1+1*stride];\ - const int av_unused l2= src[-1+2*stride];\ - const int av_unused l3= src[-1+3*stride];\ - -#define LOAD_TOP_EDGE\ - const int av_unused t0= src[ 0-1*stride];\ - const int av_unused t1= src[ 1-1*stride];\ - const int av_unused t2= src[ 2-1*stride];\ - const int av_unused 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_down_left_svq3_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_TOP_EDGE - LOAD_LEFT_EDGE - const av_unused int unu0= t0; - const av_unused int unu1= l0; - - src[0+0*stride]=(l1 + t1)>>1; - src[1+0*stride]= - src[0+1*stride]=(l2 + t2)>>1; - src[2+0*stride]= - src[1+1*stride]= - src[0+2*stride]= - src[3+0*stride]= - src[2+1*stride]= - src[1+2*stride]= - src[0+3*stride]= - src[3+1*stride]= - src[2+2*stride]= - src[1+3*stride]= - src[3+2*stride]= - src[2+3*stride]= - src[3+3*stride]=(l3 + t3)>>1; -} - -static void pred4x4_down_left_rv40_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_TOP_EDGE - LOAD_TOP_RIGHT_EDGE - LOAD_LEFT_EDGE - LOAD_DOWN_LEFT_EDGE - - src[0+0*stride]=(t0 + t2 + 2*t1 + 2 + l0 + l2 + 2*l1 + 2)>>3; - src[1+0*stride]= - src[0+1*stride]=(t1 + t3 + 2*t2 + 2 + l1 + l3 + 2*l2 + 2)>>3; - src[2+0*stride]= - src[1+1*stride]= - src[0+2*stride]=(t2 + t4 + 2*t3 + 2 + l2 + l4 + 2*l3 + 2)>>3; - src[3+0*stride]= - src[2+1*stride]= - src[1+2*stride]= - src[0+3*stride]=(t3 + t5 + 2*t4 + 2 + l3 + l5 + 2*l4 + 2)>>3; - src[3+1*stride]= - src[2+2*stride]= - src[1+3*stride]=(t4 + t6 + 2*t5 + 2 + l4 + l6 + 2*l5 + 2)>>3; - src[3+2*stride]= - src[2+3*stride]=(t5 + t7 + 2*t6 + 2 + l5 + l7 + 2*l6 + 2)>>3; - src[3+3*stride]=(t6 + t7 + 1 + l6 + l7 + 1)>>2; -} - -static void pred4x4_down_left_rv40_nodown_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 + l0 + l2 + 2*l1 + 2)>>3; - src[1+0*stride]= - src[0+1*stride]=(t1 + t3 + 2*t2 + 2 + l1 + l3 + 2*l2 + 2)>>3; - src[2+0*stride]= - src[1+1*stride]= - src[0+2*stride]=(t2 + t4 + 2*t3 + 2 + l2 + 3*l3 + 2)>>3; - src[3+0*stride]= - src[2+1*stride]= - src[1+2*stride]= - src[0+3*stride]=(t3 + t5 + 2*t4 + 2 + l3*4 + 2)>>3; - src[3+1*stride]= - src[2+2*stride]= - src[1+3*stride]=(t4 + t6 + 2*t5 + 2 + l3*4 + 2)>>3; - src[3+2*stride]= - src[2+3*stride]=(t5 + t7 + 2*t6 + 2 + l3*4 + 2)>>3; - src[3+3*stride]=(t6 + t7 + 1 + 2*l3 + 1)>>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 - - 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 - - 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_vertical_left_rv40(uint8_t *src, uint8_t *topright, int stride, - const int l0, const int l1, const int l2, const int l3, const int l4){ - LOAD_TOP_EDGE - LOAD_TOP_RIGHT_EDGE - - src[0+0*stride]=(2*t0 + 2*t1 + l1 + 2*l2 + l3 + 4)>>3; - 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 + l2 + 2*l3 + l4 + 4)>>3; - 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_vertical_left_rv40_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_LEFT_EDGE - LOAD_DOWN_LEFT_EDGE - - pred4x4_vertical_left_rv40(src, topright, stride, l0, l1, l2, l3, l4); -} - -static void pred4x4_vertical_left_rv40_nodown_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_LEFT_EDGE - - pred4x4_vertical_left_rv40(src, topright, stride, l0, l1, l2, l3, l3); -} - -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_up_rv40_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_LEFT_EDGE - LOAD_DOWN_LEFT_EDGE - LOAD_TOP_EDGE - LOAD_TOP_RIGHT_EDGE - - src[0+0*stride]=(t1 + 2*t2 + t3 + 2*l0 + 2*l1 + 4)>>3; - src[1+0*stride]=(t2 + 2*t3 + t4 + l0 + 2*l1 + l2 + 4)>>3; - src[2+0*stride]= - src[0+1*stride]=(t3 + 2*t4 + t5 + 2*l1 + 2*l2 + 4)>>3; - src[3+0*stride]= - src[1+1*stride]=(t4 + 2*t5 + t6 + l1 + 2*l2 + l3 + 4)>>3; - src[2+1*stride]= - src[0+2*stride]=(t5 + 2*t6 + t7 + 2*l2 + 2*l3 + 4)>>3; - src[3+1*stride]= - src[1+2*stride]=(t6 + 3*t7 + l2 + 3*l3 + 4)>>3; - src[3+2*stride]= - src[1+3*stride]=(l3 + 2*l4 + l5 + 2)>>2; - src[0+3*stride]= - src[2+2*stride]=(t6 + t7 + l3 + l4 + 2)>>2; - src[2+3*stride]=(l4 + l5 + 1)>>1; - src[3+3*stride]=(l4 + 2*l5 + l6 + 2)>>2; -} - -static void pred4x4_horizontal_up_rv40_nodown_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_LEFT_EDGE - LOAD_TOP_EDGE - LOAD_TOP_RIGHT_EDGE - - src[0+0*stride]=(t1 + 2*t2 + t3 + 2*l0 + 2*l1 + 4)>>3; - src[1+0*stride]=(t2 + 2*t3 + t4 + l0 + 2*l1 + l2 + 4)>>3; - src[2+0*stride]= - src[0+1*stride]=(t3 + 2*t4 + t5 + 2*l1 + 2*l2 + 4)>>3; - src[3+0*stride]= - src[1+1*stride]=(t4 + 2*t5 + t6 + l1 + 2*l2 + l3 + 4)>>3; - src[2+1*stride]= - src[0+2*stride]=(t5 + 2*t6 + t7 + 2*l2 + 2*l3 + 4)>>3; - src[3+1*stride]= - src[1+2*stride]=(t6 + 3*t7 + l2 + 3*l3 + 4)>>3; - src[3+2*stride]= - src[1+3*stride]=l3; - src[0+3*stride]= - src[2+2*stride]=(t6 + t7 + 2*l3 + 2)>>2; - 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 - - 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, const int rv40){ - int i, j, k; - int a; - uint8_t *cm = ff_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 if(rv40){ - H = ( H + (H>>2) ) >> 4; - V = ( V + (V>>2) ) >> 4; - }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, 0); -} - -static void pred16x16_plane_svq3_c(uint8_t *src, int stride){ - pred16x16_plane_compat_c(src, stride, 1, 0); -} - -static void pred16x16_plane_rv40_c(uint8_t *src, int stride){ - pred16x16_plane_compat_c(src, stride, 0, 1); -} - -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_left_dc_rv40_c(uint8_t *src, int stride){ - int i; - int dc0; - - dc0=0; - for(i=0;i<8; i++) - dc0+= src[-1+i*stride]; - dc0= 0x01010101*((dc0 + 4)>>3); - - for(i=0; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= dc0; - } -} - -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_top_dc_rv40_c(uint8_t *src, int stride){ - int i; - int dc0; - - dc0=0; - for(i=0;i<8; i++) - dc0+= src[i-stride]; - dc0= 0x01010101*((dc0 + 4)>>3); - - for(i=0; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= dc0; - } -} - - -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; - } -} - -//the following 4 function should not be optimized! -static void pred8x8_mad_cow_dc_l0t(uint8_t *src, int stride){ - pred8x8_top_dc_c(src, stride); - pred4x4_dc_c(src, NULL, stride); -} - -static void pred8x8_mad_cow_dc_0lt(uint8_t *src, int stride){ - pred8x8_dc_c(src, stride); - pred4x4_top_dc_c(src, NULL, stride); -} - -static void pred8x8_mad_cow_dc_l00(uint8_t *src, int stride){ - pred8x8_left_dc_c(src, stride); - pred4x4_128_dc_c(src + 4*stride , NULL, stride); - pred4x4_128_dc_c(src + 4*stride + 4, NULL, stride); -} - -static void pred8x8_mad_cow_dc_0l0(uint8_t *src, int stride){ - pred8x8_left_dc_c(src, stride); - pred4x4_128_dc_c(src , NULL, stride); - pred4x4_128_dc_c(src + 4, NULL, stride); -} - -static void pred8x8_dc_rv40_c(uint8_t *src, int stride){ - int i; - int dc0=0; - - for(i=0;i<4; i++){ - dc0+= src[-1+i*stride] + src[i-stride]; - dc0+= src[4+i-stride]; - dc0+= src[-1+(i+4)*stride]; - } - dc0= 0x01010101*((dc0 + 8)>>4); - - for(i=0; i<4; i++){ - ((uint32_t*)(src+i*stride))[0]= dc0; - ((uint32_t*)(src+i*stride))[1]= dc0; - } - for(i=4; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= dc0; - ((uint32_t*)(src+i*stride))[1]= dc0; - } -} - -static void pred8x8_plane_c(uint8_t *src, int stride){ - int j, k; - int a; - uint8_t *cm = ff_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 av_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 av_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 void pred4x4_vertical_add_c(uint8_t *pix, const DCTELEM *block, int stride){ - int i; - pix -= stride; - for(i=0; i<4; i++){ - uint8_t v = pix[0]; - pix[1*stride]= v += block[0]; - pix[2*stride]= v += block[4]; - pix[3*stride]= v += block[8]; - pix[4*stride]= v + block[12]; - pix++; - block++; - } -} - -static void pred4x4_horizontal_add_c(uint8_t *pix, const DCTELEM *block, int stride){ - int i; - for(i=0; i<4; i++){ - uint8_t v = pix[-1]; - pix[0]= v += block[0]; - pix[1]= v += block[1]; - pix[2]= v += block[2]; - pix[3]= v + block[3]; - pix+= stride; - block+= 4; - } -} - -static void pred8x8l_vertical_add_c(uint8_t *pix, const DCTELEM *block, int stride){ - int i; - pix -= stride; - for(i=0; i<8; i++){ - uint8_t v = pix[0]; - pix[1*stride]= v += block[0]; - pix[2*stride]= v += block[8]; - pix[3*stride]= v += block[16]; - pix[4*stride]= v += block[24]; - pix[5*stride]= v += block[32]; - pix[6*stride]= v += block[40]; - pix[7*stride]= v += block[48]; - pix[8*stride]= v + block[56]; - pix++; - block++; - } -} - -static void pred8x8l_horizontal_add_c(uint8_t *pix, const DCTELEM *block, int stride){ - int i; - for(i=0; i<8; i++){ - uint8_t v = pix[-1]; - pix[0]= v += block[0]; - pix[1]= v += block[1]; - pix[2]= v += block[2]; - pix[3]= v += block[3]; - pix[4]= v += block[4]; - pix[5]= v += block[5]; - pix[6]= v += block[6]; - pix[7]= v + block[7]; - pix+= stride; - block+= 8; - } -} - -static void pred16x16_vertical_add_c(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){ - int i; - for(i=0; i<16; i++) - pred4x4_vertical_add_c(pix + block_offset[i], block + i*16, stride); -} - -static void pred16x16_horizontal_add_c(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){ - int i; - for(i=0; i<16; i++) - pred4x4_horizontal_add_c(pix + block_offset[i], block + i*16, stride); -} - -static void pred8x8_vertical_add_c(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){ - int i; - for(i=0; i<4; i++) - pred4x4_vertical_add_c(pix + block_offset[i], block + i*16, stride); -} - -static void pred8x8_horizontal_add_c(uint8_t *pix, const int *block_offset, const DCTELEM *block, int stride){ - int i; - for(i=0; i<4; i++) - pred4x4_horizontal_add_c(pix + block_offset[i], block + i*16, stride); -} - - -/** - * Sets the intra prediction function pointers. - */ -void ff_h264_pred_init(H264PredContext *h, int codec_id){ -// MpegEncContext * const s = &h->s; - - if(codec_id != CODEC_ID_RV40){ - h->pred4x4[VERT_PRED ]= pred4x4_vertical_c; - h->pred4x4[HOR_PRED ]= pred4x4_horizontal_c; - h->pred4x4[DC_PRED ]= pred4x4_dc_c; - if(codec_id == CODEC_ID_SVQ3) - h->pred4x4[DIAG_DOWN_LEFT_PRED ]= pred4x4_down_left_svq3_c; - else - 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; - }else{ - 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_rv40_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_rv40_c; - h->pred4x4[HOR_UP_PRED ]= pred4x4_horizontal_up_rv40_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->pred4x4[DIAG_DOWN_LEFT_PRED_RV40_NODOWN]= pred4x4_down_left_rv40_nodown_c; - h->pred4x4[HOR_UP_PRED_RV40_NODOWN]= pred4x4_horizontal_up_rv40_nodown_c; - h->pred4x4[VERT_LEFT_PRED_RV40_NODOWN]= pred4x4_vertical_left_rv40_nodown_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[VERT_PRED8x8 ]= pred8x8_vertical_c; - h->pred8x8[HOR_PRED8x8 ]= pred8x8_horizontal_c; - h->pred8x8[PLANE_PRED8x8 ]= pred8x8_plane_c; - if(codec_id != CODEC_ID_RV40){ - h->pred8x8[DC_PRED8x8 ]= pred8x8_dc_c; - h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_c; - h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_c; - h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= pred8x8_mad_cow_dc_l0t; - h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= pred8x8_mad_cow_dc_0lt; - h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= pred8x8_mad_cow_dc_l00; - h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= pred8x8_mad_cow_dc_0l0; - }else{ - h->pred8x8[DC_PRED8x8 ]= pred8x8_dc_rv40_c; - h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_rv40_c; - h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_rv40_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; - switch(codec_id){ - case CODEC_ID_SVQ3: - h->pred16x16[PLANE_PRED8x8 ]= pred16x16_plane_svq3_c; - break; - case CODEC_ID_RV40: - h->pred16x16[PLANE_PRED8x8 ]= pred16x16_plane_rv40_c; - break; - default: - 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; - - //special lossless h/v prediction for h264 - h->pred4x4_add [VERT_PRED ]= pred4x4_vertical_add_c; - h->pred4x4_add [ HOR_PRED ]= pred4x4_horizontal_add_c; - h->pred8x8l_add [VERT_PRED ]= pred8x8l_vertical_add_c; - h->pred8x8l_add [ HOR_PRED ]= pred8x8l_horizontal_add_c; - h->pred8x8_add [VERT_PRED8x8]= pred8x8_vertical_add_c; - h->pred8x8_add [ HOR_PRED8x8]= pred8x8_horizontal_add_c; - h->pred16x16_add[VERT_PRED8x8]= pred16x16_vertical_add_c; - h->pred16x16_add[ HOR_PRED8x8]= pred16x16_horizontal_add_c; - - if (ARCH_ARM) ff_h264_pred_init_arm(h, codec_id); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/h264pred.h b/tizen/distrib/ffmpeg/libavcodec/h264pred.h deleted file mode 100644 index c52aeaa..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/h264pred.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 prediction functions. - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_H264PRED_H -#define AVCODEC_H264PRED_H - -#include "libavutil/common.h" -#include "dsputil.h" - -/** - * Prediction types - */ -//@{ -#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 DIAG_DOWN_LEFT_PRED_RV40_NODOWN 12 -#define HOR_UP_PRED_RV40_NODOWN 13 -#define VERT_LEFT_PRED_RV40_NODOWN 14 - -#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 ALZHEIMER_DC_L0T_PRED8x8 7 -#define ALZHEIMER_DC_0LT_PRED8x8 8 -#define ALZHEIMER_DC_L00_PRED8x8 9 -#define ALZHEIMER_DC_0L0_PRED8x8 10 -//@} - -/** - * Context for storing H.264 prediction functions - */ -typedef struct H264PredContext{ - void (*pred4x4 [9+3+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp? - void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride); - void (*pred8x8 [4+3+4])(uint8_t *src, int stride); - void (*pred16x16[4+3])(uint8_t *src, int stride); - - void (*pred4x4_add [2])(uint8_t *pix/*align 4*/, const DCTELEM *block/*align 16*/, int stride); - void (*pred8x8l_add [2])(uint8_t *pix/*align 8*/, const DCTELEM *block/*align 16*/, int stride); - void (*pred8x8_add [3])(uint8_t *pix/*align 8*/, const int *block_offset, const DCTELEM *block/*align 16*/, int stride); - void (*pred16x16_add[3])(uint8_t *pix/*align 16*/, const int *block_offset, const DCTELEM *block/*align 16*/, int stride); -}H264PredContext; - -void ff_h264_pred_init(H264PredContext *h, int codec_id); -void ff_h264_pred_init_arm(H264PredContext *h, int codec_id); - -#endif /* AVCODEC_H264PRED_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/huffman.c b/tizen/distrib/ffmpeg/libavcodec/huffman.c deleted file mode 100644 index 853fa64..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/huffman.c +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @file - * huffman tree builder and VLC generator - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "huffman.h" - -/* symbol for Huffman tree node */ -#define HNODE -1 - - -static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos, int no_zero_count) -{ - int s; - - s = nodes[node].sym; - if(s != HNODE || (no_zero_count && !nodes[node].count)){ - bits[*pos] = pfx; - lens[*pos] = pl; - xlat[*pos] = s; - (*pos)++; - }else{ - pfx <<= 1; - pl++; - get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos, - no_zero_count); - pfx |= 1; - get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos, - no_zero_count); - } -} - -static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags) -{ - int no_zero_count = !(flags & FF_HUFFMAN_FLAG_ZERO_COUNT); - uint32_t bits[256]; - int16_t lens[256]; - uint8_t xlat[256]; - int pos = 0; - - get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos, no_zero_count); - return init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); -} - - -/** - * nodes size must be 2*nb_codes - * first nb_codes nodes.count must be set - */ -int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, - Node *nodes, HuffCmp cmp, int flags) -{ - int i, j; - int cur_node; - int64_t sum = 0; - - for(i = 0; i < nb_codes; i++){ - nodes[i].sym = i; - nodes[i].n0 = -2; - sum += nodes[i].count; - } - - if(sum >> 31) { - av_log(avctx, AV_LOG_ERROR, "Too high symbol frequencies. Tree construction is not possible\n"); - return -1; - } - qsort(nodes, nb_codes, sizeof(Node), cmp); - cur_node = nb_codes; - nodes[nb_codes*2-1].count = 0; - for(i = 0; i < nb_codes*2-1; i += 2){ - nodes[cur_node].sym = HNODE; - nodes[cur_node].count = nodes[i].count + nodes[i+1].count; - nodes[cur_node].n0 = i; - for(j = cur_node; j > 0; j--){ - if(nodes[j].count > nodes[j-1].count || - (nodes[j].count == nodes[j-1].count && - (!(flags & FF_HUFFMAN_FLAG_HNODE_FIRST) || - nodes[j].n0==j-1 || nodes[j].n0==j-2 || - (nodes[j].sym!=HNODE && nodes[j-1].sym!=HNODE)))) - break; - FFSWAP(Node, nodes[j], nodes[j-1]); - } - cur_node++; - } - if(build_huff_tree(vlc, nodes, nb_codes*2-2, flags) < 0){ - av_log(avctx, AV_LOG_ERROR, "Error building tree\n"); - return -1; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/huffman.h b/tizen/distrib/ffmpeg/libavcodec/huffman.h deleted file mode 100644 index 3c08e6f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/huffman.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file - * huffman tree builder and VLC generator - * Copyright (C) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_HUFFMAN_H -#define AVCODEC_HUFFMAN_H - -#include "avcodec.h" -#include "get_bits.h" - -typedef struct { - int16_t sym; - int16_t n0; - uint32_t count; -} Node; - -#define FF_HUFFMAN_FLAG_HNODE_FIRST 0x01 -#define FF_HUFFMAN_FLAG_ZERO_COUNT 0x02 - -typedef int (*HuffCmp)(const void *va, const void *vb); -int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, - Node *nodes, HuffCmp cmp, int flags); - -#endif /* AVCODEC_HUFFMAN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/huffyuv.c b/tizen/distrib/ffmpeg/libavcodec/huffyuv.c deleted file mode 100644 index 7764c35..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/huffyuv.c +++ /dev/null @@ -1,1475 +0,0 @@ -/* - * huffyuv codec for libavcodec - * - * Copyright (c) 2002-2003 Michael Niedermayer - * - * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of - * the algorithm used - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * huffyuv codec for libavcodec. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "put_bits.h" -#include "dsputil.h" - -#define VLC_BITS 11 - -#if HAVE_BIGENDIAN -#define B 3 -#define G 2 -#define R 1 -#define A 0 -#else -#define B 0 -#define G 1 -#define R 2 -#define A 3 -#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]; - uint32_t pix_bgr_map[1<dsp.diff_bytes(dst+16, src+16, src+15, w-16); - return src[w-1]; - } -} - -static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){ - int i; - int r,g,b; - r= *red; - g= *green; - b= *blue; - for(i=0; idsp.diff_bytes(dst+16, src+16, src+12, w*4-16); - *red= src[(w-1)*4+R]; - *green= src[(w-1)*4+G]; - *blue= src[(w-1)*4+B]; -} - -static int 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); - if(i+repeat > 256) { - av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n"); - return -1; - } - while (repeat--) - dst[i++] = val; - } - return 0; -} - -static int generate_bits_table(uint32_t *dst, const 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; -} - -#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER -typedef struct { - uint64_t val; - int name; -} HeapElem; - -static void heap_sift(HeapElem *h, int root, int size) -{ - while(root*2+1 < size) { - int child = root*2+1; - if(child < size-1 && h[child].val > h[child+1].val) - child++; - if(h[root].val > h[child].val) { - FFSWAP(HeapElem, h[root], h[child]); - root = child; - } else - break; - } -} - -static void generate_len_table(uint8_t *dst, const uint64_t *stats, int size){ - HeapElem h[size]; - int up[2*size]; - int len[2*size]; - int offset, i, next; - - for(offset=1; ; offset<<=1){ - for(i=0; i=0; i--) - heap_sift(h, i, size); - - for(next=size; next=size; i--) - len[i] = len[up[i]] + 1; - for(i=0; i= 32) break; - } - if(i==size) break; - } -} -#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ - -static void generate_joint_tables(HYuvContext *s){ - uint16_t symbols[1<bitstream_bpp < 24){ - int p, i, y, u; - for(p=0; p<3; p++){ - for(i=y=0; y<256; y++){ - int len0 = s->len[0][y]; - int limit = VLC_BITS - len0; - if(limit <= 0) - continue; - for(u=0; u<256; u++){ - int len1 = s->len[p][u]; - if(len1 > limit) - continue; - len[i] = len0 + len1; - bits[i] = (s->bits[0][y] << len1) + s->bits[p][u]; - symbols[i] = (y<<8) + u; - if(symbols[i] != 0xffff) // reserved to mean "invalid" - i++; - } - } - free_vlc(&s->vlc[3+p]); - init_vlc_sparse(&s->vlc[3+p], VLC_BITS, i, len, 1, 1, bits, 2, 2, symbols, 2, 2, 0); - } - }else{ - uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map; - int i, b, g, r, code; - int p0 = s->decorrelate; - int p1 = !s->decorrelate; - // restrict the range to +/-16 becaues that's pretty much guaranteed to - // cover all the combinations that fit in 11 bits total, and it doesn't - // matter if we miss a few rare codes. - for(i=0, g=-16; g<16; g++){ - int len0 = s->len[p0][g&255]; - int limit0 = VLC_BITS - len0; - if(limit0 < 2) - continue; - for(b=-16; b<16; b++){ - int len1 = s->len[p1][b&255]; - int limit1 = limit0 - len1; - if(limit1 < 1) - continue; - code = (s->bits[p0][g&255] << len1) + s->bits[p1][b&255]; - for(r=-16; r<16; r++){ - int len2 = s->len[2][r&255]; - if(len2 > limit1) - continue; - len[i] = len0 + len1 + len2; - bits[i] = (code << len2) + s->bits[2][r&255]; - if(s->decorrelate){ - map[i][G] = g; - map[i][B] = g+b; - map[i][R] = g+r; - }else{ - map[i][B] = g; - map[i][G] = b; - map[i][R] = r; - } - i++; - } - } - } - free_vlc(&s->vlc[3]); - init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0); - } -} - -static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length){ - GetBitContext gb; - int i; - - init_get_bits(&gb, src, length*8); - - for(i=0; i<3; i++){ - if(read_len_table(s->len[i], &gb)<0) - return -1; - 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); - } - - generate_joint_tables(s); - - 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); - if(read_len_table(s->len[0], &gb)<0) - return -1; - init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8); - if(read_len_table(s->len[1], &gb)<0) - return -1; - - 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); - } - - generate_joint_tables(s); - - return 0; -#else - av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n"); - return -1; -#endif -} - -static av_cold 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_mallocz(4*s->width + 16); - } -} - -static av_cold 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; -} - -#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER -static av_cold 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_coded_sample&7) && avctx->bits_per_coded_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; - - if (avctx->extradata_size < 4) - return -1; - - 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_coded_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-4) < 0) - return -1; - }else{ - switch(avctx->bits_per_coded_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_coded_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_coded_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_YUYV422; - }else{ - avctx->pix_fmt = PIX_FMT_YUV422P; - } - break; - case 24: - case 32: - if(s->bgr32){ - avctx->pix_fmt = PIX_FMT_RGB32; - }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_coded_sample, s->interlaced); - - return 0; -} -#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */ - -#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER -static int store_table(HYuvContext *s, const 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 av_cold 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; - case PIX_FMT_RGB32: - s->bitstream_bpp= 24; - break; - default: - av_log(avctx, AV_LOG_ERROR, "format not supported\n"); - return -1; - } - avctx->bits_per_coded_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"); - } - - if(s->bitstream_bpp>=24 && s->predictor==MEDIAN){ - av_log(avctx, AV_LOG_ERROR, "Error: RGB is incompatible with median predictor\n"); - return -1; - } - - ((uint8_t*)avctx->extradata)[0]= s->predictor | (s->decorrelate << 6); - ((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_coded_sample, s->interlaced); - - alloc_temp(s); - - s->picture_number=0; - - return 0; -} -#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ - -/* TODO instead of restarting the read when the code isn't in the first level - * of the joint table, jump into the 2nd level of the individual table. */ -#define READ_2PIX(dst0, dst1, plane1){\ - uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\ - if(code != 0xffff){\ - dst0 = code>>8;\ - dst1 = code;\ - }else{\ - dst0 = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);\ - dst1 = get_vlc2(&s->gb, s->vlc[plane1].table, VLC_BITS, 3);\ - }\ -} - -static void decode_422_bitstream(HYuvContext *s, int count){ - int i; - - count/=2; - - if(count >= (get_bits_left(&s->gb))/(31*4)){ - for(i=0; igb) < s->gb.size_in_bits; i++){ - READ_2PIX(s->temp[0][2*i ], s->temp[1][i], 1); - READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2); - } - }else{ - for(i=0; itemp[0][2*i ], s->temp[1][i], 1); - READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2); - } - } -} - -static void decode_gray_bitstream(HYuvContext *s, int count){ - int i; - - count/=2; - - if(count >= (get_bits_left(&s->gb))/(31*2)){ - for(i=0; igb) < s->gb.size_in_bits; i++){ - READ_2PIX(s->temp[0][2*i ], s->temp[0][2*i+1], 0); - } - }else{ - for(i=0; itemp[0][2*i ], s->temp[0][2*i+1], 0); - } - } -} - -#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER -static int encode_422_bitstream(HYuvContext *s, int offset, int count){ - int i; - const uint8_t *y = s->temp[0] + offset; - const uint8_t *u = s->temp[1] + offset/2; - const uint8_t *v = s->temp[2] + offset/2; - - 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; - } - -#define LOAD4\ - int y0 = y[2*i];\ - int y1 = y[2*i+1];\ - int u0 = u[i];\ - int v0 = v[i]; - - count/=2; - if(s->flags&CODEC_FLAG_PASS1){ - for(i=0; istats[0][y0]++; - s->stats[1][u0]++; - s->stats[0][y1]++; - s->stats[2][v0]++; - } - } - if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) - return 0; - if(s->context){ - for(i=0; istats[0][y0]++; - put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]); - s->stats[1][u0]++; - put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); - s->stats[0][y1]++; - put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); - s->stats[2][v0]++; - put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); - } - }else{ - for(i=0; ipb, s->len[0][y0], s->bits[0][y0]); - put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); - put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); - put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); - } - } - 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; - } - -#define LOAD2\ - int y0 = s->temp[0][2*i];\ - int y1 = s->temp[0][2*i+1]; -#define STAT2\ - s->stats[0][y0]++;\ - s->stats[0][y1]++; -#define WRITE2\ - put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\ - put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); - - count/=2; - if(s->flags&CODEC_FLAG_PASS1){ - for(i=0; iavctx->flags2&CODEC_FLAG2_NO_OUTPUT) - return 0; - - if(s->context){ - for(i=0; igb, s->vlc[3].table, VLC_BITS, 1); - if(code != -1){ - *(uint32_t*)&s->temp[0][4*i] = s->pix_bgr_map[code]; - }else if(decorrelate){ - s->temp[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{ - s->temp[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); - } - if(alpha) - s->temp[0][4*i+A] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); - } -} - -static void decode_bgr_bitstream(HYuvContext *s, int count){ - if(s->decorrelate){ - if(s->bitstream_bpp==24) - decode_bgr_1(s, count, 1, 0); - else - decode_bgr_1(s, count, 1, 1); - }else{ - if(s->bitstream_bpp==24) - decode_bgr_1(s, count, 0, 0); - else - decode_bgr_1(s, count, 0, 1); - } -} - -static int encode_bgr_bitstream(HYuvContext *s, int count){ - int i; - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3*4*count){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - -#define LOAD3\ - int g= s->temp[0][4*i+G];\ - int b= (s->temp[0][4*i+B] - g) & 0xff;\ - int r= (s->temp[0][4*i+R] - g) & 0xff; -#define STAT3\ - s->stats[0][b]++;\ - s->stats[1][g]++;\ - s->stats[2][r]++; -#define WRITE3\ - put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\ - put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\ - put_bits(&s->pb, s->len[2][r], s->bits[2][r]); - - if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){ - for(i=0; icontext || (s->flags&CODEC_FLAG_PASS1)){ - for(i=0; iavctx->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, AVPacket *avpkt){ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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; - - av_fast_malloc(&s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!s->bitstream_buffer) - return AVERROR(ENOMEM); - - memset(s->bitstream_buffer + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const 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= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); - leftv= s->dsp.add_hfyu_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= s->dsp.add_hfyu_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= s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= s->dsp.add_hfyu_left_prediction(udst, s->temp[1], width2, leftu); - leftv= s->dsp.add_hfyu_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= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); - leftv= s->dsp.add_hfyu_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= s->dsp.add_hfyu_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); - leftv= s->dsp.add_hfyu_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= s->dsp.add_hfyu_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); - leftv= s->dsp.add_hfyu_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); - s->dsp.add_hfyu_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]; - s->dsp.add_hfyu_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); - s->dsp.add_hfyu_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; - s->dsp.add_hfyu_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; - - s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); - if(!(s->flags&CODEC_FLAG_GRAY)){ - s->dsp.add_hfyu_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); - s->dsp.add_hfyu_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); - } - } - - draw_slice(s, height); - break; - } - } - }else{ - int y; - int leftr, leftg, leftb, lefta; - const int last_line= (height-1)*p->linesize[0]; - - if(s->bitstream_bpp==32){ - lefta= p->data[0][last_line+A]= get_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); - lefta= p->data[0][last_line+A]= 255; - skip_bits(&s->gb, 8); - } - - if(s->bgr32){ - switch(s->predictor){ - case LEFT: - case PLANE: - decode_bgr_bitstream(s, width-1); - s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb, &lefta); - - for(y=s->height-2; y>=0; y--){ //Yes it is stored upside down. - decode_bgr_bitstream(s, width); - - s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta); - if(s->predictor == PLANE){ - if(s->bitstream_bpp!=32) lefta=0; - 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; -} -#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */ - -static int common_end(HYuvContext *s){ - int i; - - for(i=0; i<3; i++){ - av_freep(&s->temp[i]); - } - return 0; -} - -#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER -static av_cold int decode_end(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - int i; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - common_end(s); - av_freep(&s->bitstream_buffer); - - for(i=0; i<6; i++){ - free_vlc(&s->vlc[i]); - } - - return 0; -} -#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */ - -#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER -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], width , 0); - leftu= sub_left_prediction(s, s->temp[1], p->data[1], width2, 0); - leftv= sub_left_prediction(s, s->temp[2], p->data[2], width2, 0); - - encode_422_bitstream(s, 2, 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, 0, 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, 0, 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, 0, 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, 0, 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, 0, width); - } - } - }else if(avctx->pix_fmt == PIX_FMT_RGB32){ - uint8_t *data = p->data[0] + (height-1)*p->linesize[0]; - const int stride = -p->linesize[0]; - const int fake_stride = -fake_ystride; - int y; - int leftr, leftg, leftb; - - put_bits(&s->pb, 8, leftr= data[R]); - put_bits(&s->pb, 8, leftg= data[G]); - put_bits(&s->pb, 8, leftb= data[B]); - put_bits(&s->pb, 8, 0); - - sub_left_prediction_bgr32(s, s->temp[0], data+4, width-1, &leftr, &leftg, &leftb); - encode_bgr_bitstream(s, width-1); - - for(y=1; yheight; y++){ - uint8_t *dst = data + y*stride; - if(s->predictor == PLANE && s->interlaced < y){ - s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*4); - sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb); - }else{ - sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb); - } - encode_bgr_bitstream(s, width); - } - }else{ - av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); - } - emms_c(); - - size+= (put_bits_count(&s->pb)+31)/8; - put_bits(&s->pb, 16, 0); - put_bits(&s->pb, 15, 0); - 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++; - } - } else - avctx->stats_out[0] = '\0'; - if(!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)){ - flush_put_bits(&s->pb); - s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); - } - - s->picture_number++; - - return size*4; -} - -static av_cold int encode_end(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - - common_end(s); - - av_freep(&avctx->extradata); - av_freep(&avctx->stats_out); - - return 0; -} -#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ - -#if CONFIG_HUFFYUV_DECODER -AVCodec huffyuv_decoder = { - "huffyuv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_HUFFYUV, - sizeof(HYuvContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), -}; -#endif - -#if CONFIG_FFVHUFF_DECODER -AVCodec ffvhuff_decoder = { - "ffvhuff", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FFVHUFF, - sizeof(HYuvContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), -}; -#endif - -#if CONFIG_HUFFYUV_ENCODER -AVCodec huffyuv_encoder = { - "huffyuv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_HUFFYUV, - sizeof(HYuvContext), - encode_init, - encode_frame, - encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), -}; -#endif - -#if CONFIG_FFVHUFF_ENCODER -AVCodec ffvhuff_encoder = { - "ffvhuff", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_FFVHUFF, - sizeof(HYuvContext), - encode_init, - encode_frame, - encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/idcinvideo.c b/tizen/distrib/ffmpeg/libavcodec/idcinvideo.c deleted file mode 100644 index 203812b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/idcinvideo.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * id Quake II CIN Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 "avcodec.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; - -typedef struct IdcinContext { - - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *buf; - int size; - - hnode 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 *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 av_cold void huff_build_tree(IdcinContext *s, int prev) { - hnode *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 av_cold int idcin_decode_init(AVCodecContext *avctx) -{ - IdcinContext *s = avctx->priv_data; - int i, j, histogram_index = 0; - unsigned char *histograms; - - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - /* 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 *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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - IdcinContext *s = 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 av_cold int idcin_decode_end(AVCodecContext *avctx) -{ - IdcinContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec idcin_decoder = { - "idcinvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_IDCIN, - sizeof(IdcinContext), - idcin_decode_init, - NULL, - idcin_decode_end, - idcin_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/iff.c b/tizen/distrib/ffmpeg/libavcodec/iff.c deleted file mode 100644 index 2989bb0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/iff.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * IFF PBM/ILBM bitmap decoder - * Copyright (c) 2010 Peter Ross - * Copyright (c) 2010 Sebastian Vater - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * IFF PBM/ILBM bitmap decoder - */ - -#include "bytestream.h" -#include "avcodec.h" -#include "get_bits.h" -#include "iff.h" - -typedef struct { - AVFrame frame; - int planesize; - uint8_t * planebuf; -} IffContext; - -/** - * Convert CMAP buffer (stored in extradata) to lavc palette format - */ -int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) -{ - int count, i; - - if (avctx->bits_per_coded_sample > 8) { - av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n"); - return AVERROR_INVALIDDATA; - } - - count = 1 << avctx->bits_per_coded_sample; - if (avctx->extradata_size < count * 3) { - av_log(avctx, AV_LOG_ERROR, "palette data underflow\n"); - return AVERROR_INVALIDDATA; - } - for (i=0; i < count; i++) { - pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 ); - } - return 0; -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - IffContext *s = avctx->priv_data; - int err; - - if (avctx->bits_per_coded_sample <= 8) { - avctx->pix_fmt = PIX_FMT_PAL8; - } else if (avctx->bits_per_coded_sample <= 32) { - avctx->pix_fmt = PIX_FMT_BGR32; - } else { - return AVERROR_INVALIDDATA; - } - - s->planesize = avctx->width >> 3; - s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE); - if (!s->planebuf) - return AVERROR(ENOMEM); - - s->frame.reference = 1; - if ((err = avctx->get_buffer(avctx, &s->frame) < 0)) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return err; - } - - return avctx->bits_per_coded_sample <= 8 ? - ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1]) : 0; -} - -/** - * Decode interleaved plane buffer up to 8bpp - * @param dst Destination buffer - * @param buf Source buffer - * @param buf_size - * @param bps bits_per_coded_sample (must be <= 8) - * @param plane plane number to decode as - */ -static void decodeplane8(uint8_t *dst, const uint8_t *const buf, int buf_size, int bps, int plane) -{ - GetBitContext gb; - int i; - const int b = (buf_size * 8) + bps - 1; - init_get_bits(&gb, buf, buf_size * 8); - for(i = 0; i < b; i++) { - dst[i] |= get_bits1(&gb) << plane; - } -} - -/** - * Decode interleaved plane buffer up to 24bpp - * @param dst Destination buffer - * @param buf Source buffer - * @param buf_size - * @param bps bits_per_coded_sample - * @param plane plane number to decode as - */ -static void decodeplane32(uint32_t *dst, const uint8_t *const buf, int buf_size, int bps, int plane) -{ - GetBitContext gb; - int i; - const int b = (buf_size * 8) + bps - 1; - init_get_bits(&gb, buf, buf_size * 8); - for(i = 0; i < b; i++) { - dst[i] |= get_bits1(&gb) << plane; - } -} - -static int decode_frame_ilbm(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - IffContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - const uint8_t *buf_end = buf+buf_size; - int y, plane; - - if (avctx->reget_buffer(avctx, &s->frame) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if (avctx->pix_fmt == PIX_FMT_PAL8) { - for(y = 0; y < avctx->height; y++ ) { - uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; - memset(row, 0, avctx->width); - for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) { - decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), avctx->bits_per_coded_sample, plane); - buf += s->planesize; - } - } - } else { // PIX_FMT_BGR32 - for(y = 0; y < avctx->height; y++ ) { - uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; - memset(row, 0, avctx->width << 2); - for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) { - decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), avctx->bits_per_coded_sample, plane); - buf += s->planesize; - } - } - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - return buf_size; -} - -static int decode_frame_byterun1(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - IffContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - const uint8_t *buf_end = buf+buf_size; - int y, plane, x; - - if (avctx->reget_buffer(avctx, &s->frame) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved - if (avctx->pix_fmt == PIX_FMT_PAL8) { - for(y = 0; y < avctx->height ; y++ ) { - uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; - memset(row, 0, avctx->width); - for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { - for(x = 0; x < s->planesize && buf < buf_end; ) { - int8_t value = *buf++; - unsigned length; - if (value >= 0) { - length = value + 1; - memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf)); - buf += length; - } else if (value > -128) { - length = -value + 1; - memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x)); - } else { //noop - continue; - } - x += length; - } - decodeplane8(row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane); - } - } - } else { //PIX_FMT_BGR32 - for(y = 0; y < avctx->height ; y++ ) { - uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; - memset(row, 0, avctx->width << 2); - for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { - for(x = 0; x < s->planesize && buf < buf_end; ) { - int8_t value = *buf++; - unsigned length; - if (value >= 0) { - length = value + 1; - memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf)); - buf += length; - } else if (value > -128) { - length = -value + 1; - memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x)); - } else { // noop - continue; - } - x += length; - } - decodeplane32((uint32_t *) row, s->planebuf, s->planesize, avctx->bits_per_coded_sample, plane); - } - } - } - } else { - for(y = 0; y < avctx->height ; y++ ) { - uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; - for(x = 0; x < avctx->width && buf < buf_end; ) { - int8_t value = *buf++; - unsigned length; - if (value >= 0) { - length = value + 1; - memcpy(row + x, buf, FFMIN3(length, buf_end - buf, avctx->width - x)); - buf += length; - } else if (value > -128) { - length = -value + 1; - memset(row + x, *buf++, FFMIN(length, avctx->width - x)); - } else { //noop - continue; - } - x += length; - } - } - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - return buf_size; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - IffContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - av_freep(&s->planebuf); - return 0; -} - -AVCodec iff_ilbm_decoder = { - "iff_ilbm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_IFF_ILBM, - sizeof(IffContext), - decode_init, - NULL, - decode_end, - decode_frame_ilbm, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"), -}; - -AVCodec iff_byterun1_decoder = { - "iff_byterun1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_IFF_BYTERUN1, - sizeof(IffContext), - decode_init, - NULL, - decode_end, - decode_frame_byterun1, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/iff.h b/tizen/distrib/ffmpeg/libavcodec/iff.h deleted file mode 100644 index 76db10b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/iff.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * IFF PBM/ILBM bitmap decoder - * Copyright (c) 2010 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_IFF_H -#define AVCODEC_IFF_H - -#include -#include "avcodec.h" - -int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal); - -#endif /* AVCODEC_IFF_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/iirfilter.c b/tizen/distrib/ffmpeg/libavcodec/iirfilter.c deleted file mode 100644 index 90af431..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/iirfilter.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * IIR filter - * Copyright (c) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * different IIR filters implementation - */ - -#include "iirfilter.h" -#include - -/** - * IIR filter global parameters - */ -typedef struct FFIIRFilterCoeffs{ - int order; - float gain; - int *cx; - float *cy; -}FFIIRFilterCoeffs; - -/** - * IIR filter state - */ -typedef struct FFIIRFilterState{ - float x[1]; -}FFIIRFilterState; - -/// maximum supported filter order -#define MAXORDER 30 - -av_cold struct FFIIRFilterCoeffs* ff_iir_filter_init_coeffs(enum IIRFilterType filt_type, - enum IIRFilterMode filt_mode, - int order, float cutoff_ratio, - float stopband, float ripple) -{ - int i, j; - FFIIRFilterCoeffs *c; - double wa; - double p[MAXORDER + 1][2]; - - if(filt_type != FF_FILTER_TYPE_BUTTERWORTH || filt_mode != FF_FILTER_MODE_LOWPASS) - return NULL; - if(order <= 1 || (order & 1) || order > MAXORDER || cutoff_ratio >= 1.0) - return NULL; - - c = av_malloc(sizeof(FFIIRFilterCoeffs)); - c->cx = av_malloc(sizeof(c->cx[0]) * ((order >> 1) + 1)); - c->cy = av_malloc(sizeof(c->cy[0]) * order); - c->order = order; - - wa = 2 * tan(M_PI * 0.5 * cutoff_ratio); - - c->cx[0] = 1; - for(i = 1; i < (order >> 1) + 1; i++) - c->cx[i] = c->cx[i - 1] * (order - i + 1LL) / i; - - p[0][0] = 1.0; - p[0][1] = 0.0; - for(i = 1; i <= order; i++) - p[i][0] = p[i][1] = 0.0; - for(i = 0; i < order; i++){ - double zp[2]; - double th = (i + (order >> 1) + 0.5) * M_PI / order; - double a_re, a_im, c_re, c_im; - zp[0] = cos(th) * wa; - zp[1] = sin(th) * wa; - a_re = zp[0] + 2.0; - c_re = zp[0] - 2.0; - a_im = - c_im = zp[1]; - zp[0] = (a_re * c_re + a_im * c_im) / (c_re * c_re + c_im * c_im); - zp[1] = (a_im * c_re - a_re * c_im) / (c_re * c_re + c_im * c_im); - - for(j = order; j >= 1; j--) - { - a_re = p[j][0]; - a_im = p[j][1]; - p[j][0] = a_re*zp[0] - a_im*zp[1] + p[j-1][0]; - p[j][1] = a_re*zp[1] + a_im*zp[0] + p[j-1][1]; - } - a_re = p[0][0]*zp[0] - p[0][1]*zp[1]; - p[0][1] = p[0][0]*zp[1] + p[0][1]*zp[0]; - p[0][0] = a_re; - } - c->gain = p[order][0]; - for(i = 0; i < order; i++){ - c->gain += p[i][0]; - c->cy[i] = (-p[i][0] * p[order][0] + -p[i][1] * p[order][1]) / - (p[order][0] * p[order][0] + p[order][1] * p[order][1]); - } - c->gain /= 1 << order; - - return c; -} - -av_cold struct FFIIRFilterState* ff_iir_filter_init_state(int order) -{ - FFIIRFilterState* s = av_mallocz(sizeof(FFIIRFilterState) + sizeof(s->x[0]) * (order - 1)); - return s; -} - -#define FILTER(i0, i1, i2, i3) \ - in = *src * c->gain \ - + c->cy[0]*s->x[i0] + c->cy[1]*s->x[i1] \ - + c->cy[2]*s->x[i2] + c->cy[3]*s->x[i3]; \ - res = (s->x[i0] + in )*1 \ - + (s->x[i1] + s->x[i3])*4 \ - + s->x[i2] *6; \ - *dst = av_clip_int16(lrintf(res)); \ - s->x[i0] = in; \ - src += sstep; \ - dst += dstep; \ - -void ff_iir_filter(const struct FFIIRFilterCoeffs *c, struct FFIIRFilterState *s, int size, const int16_t *src, int sstep, int16_t *dst, int dstep) -{ - int i; - - if(c->order == 4){ - for(i = 0; i < size; i += 4){ - float in, res; - - FILTER(0, 1, 2, 3); - FILTER(1, 2, 3, 0); - FILTER(2, 3, 0, 1); - FILTER(3, 0, 1, 2); - } - }else{ - for(i = 0; i < size; i++){ - int j; - float in, res; - in = *src * c->gain; - for(j = 0; j < c->order; j++) - in += c->cy[j] * s->x[j]; - res = s->x[0] + in + s->x[c->order >> 1] * c->cx[c->order >> 1]; - for(j = 1; j < c->order >> 1; j++) - res += (s->x[j] + s->x[c->order - j]) * c->cx[j]; - for(j = 0; j < c->order - 1; j++) - s->x[j] = s->x[j + 1]; - *dst = av_clip_int16(lrintf(res)); - s->x[c->order - 1] = in; - src += sstep; - dst += sstep; - } - } -} - -av_cold void ff_iir_filter_free_state(struct FFIIRFilterState *state) -{ - av_free(state); -} - -av_cold void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs) -{ - if(coeffs){ - av_free(coeffs->cx); - av_free(coeffs->cy); - } - av_free(coeffs); -} - -#ifdef TEST -#define FILT_ORDER 4 -#define SIZE 1024 -int main(void) -{ - struct FFIIRFilterCoeffs *fcoeffs = NULL; - struct FFIIRFilterState *fstate = NULL; - float cutoff_coeff = 0.4; - int16_t x[SIZE], y[SIZE]; - int i; - FILE* fd; - - fcoeffs = ff_iir_filter_init_coeffs(FF_FILTER_TYPE_BUTTERWORTH, - FF_FILTER_MODE_LOWPASS, FILT_ORDER, - cutoff_coeff, 0.0, 0.0); - fstate = ff_iir_filter_init_state(FILT_ORDER); - - for (i = 0; i < SIZE; i++) { - x[i] = lrint(0.75 * INT16_MAX * sin(0.5*M_PI*i*i/SIZE)); - } - - ff_iir_filter(fcoeffs, fstate, SIZE, x, 1, y, 1); - - fd = fopen("in.bin", "w"); - fwrite(x, sizeof(x[0]), SIZE, fd); - fclose(fd); - - fd = fopen("out.bin", "w"); - fwrite(y, sizeof(y[0]), SIZE, fd); - fclose(fd); - - ff_iir_filter_free_coeffs(fcoeffs); - ff_iir_filter_free_state(fstate); - return 0; -} -#endif /* TEST */ diff --git a/tizen/distrib/ffmpeg/libavcodec/iirfilter.h b/tizen/distrib/ffmpeg/libavcodec/iirfilter.h deleted file mode 100644 index f660955..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/iirfilter.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * IIR filter - * Copyright (c) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * IIR filter interface - */ - -#ifndef AVCODEC_IIRFILTER_H -#define AVCODEC_IIRFILTER_H - -#include "avcodec.h" - -struct FFIIRFilterCoeffs; -struct FFIIRFilterState; - -enum IIRFilterType{ - FF_FILTER_TYPE_BESSEL, - FF_FILTER_TYPE_BUTTERWORTH, - FF_FILTER_TYPE_CHEBYSHEV, - FF_FILTER_TYPE_ELLIPTIC, -}; - -enum IIRFilterMode{ - FF_FILTER_MODE_LOWPASS, - FF_FILTER_MODE_HIGHPASS, - FF_FILTER_MODE_BANDPASS, - FF_FILTER_MODE_BANDSTOP, -}; - -/** - * Initialize filter coefficients. - * - * @param filt_type filter type (e.g. Butterworth) - * @param filt_mode filter mode (e.g. lowpass) - * @param order filter order - * @param cutoff_ratio cutoff to input frequency ratio - * @param stopband stopband to input frequency ratio (used by bandpass and bandstop filter modes) - * @param ripple ripple factor (used only in Chebyshev filters) - * - * @return pointer to filter coefficients structure or NULL if filter cannot be created - */ -struct FFIIRFilterCoeffs* ff_iir_filter_init_coeffs(enum IIRFilterType filt_type, - enum IIRFilterMode filt_mode, - int order, float cutoff_ratio, - float stopband, float ripple); - -/** - * Create new filter state. - * - * @param order filter order - * - * @return pointer to new filter state or NULL if state creation fails - */ -struct FFIIRFilterState* ff_iir_filter_init_state(int order); - -/** - * Free filter coefficients. - * - * @param coeffs pointer allocated with ff_iir_filter_init_coeffs() - */ -void ff_iir_filter_free_coeffs(struct FFIIRFilterCoeffs *coeffs); - -/** - * Free filter state. - * - * @param state pointer allocated with ff_iir_filter_init_state() - */ -void ff_iir_filter_free_state(struct FFIIRFilterState *state); - -/** - * Perform lowpass filtering on input samples. - * - * @param coeffs pointer to filter coefficients - * @param state pointer to filter state - * @param size input length - * @param src source samples - * @param sstep source stride - * @param dst filtered samples (destination may be the same as input) - * @param dstep destination stride - */ -void ff_iir_filter(const struct FFIIRFilterCoeffs *coeffs, struct FFIIRFilterState *state, - int size, const int16_t *src, int sstep, int16_t *dst, int dstep); - -#endif /* AVCODEC_IIRFILTER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/imc.c b/tizen/distrib/ffmpeg/libavcodec/imc.c deleted file mode 100644 index 2a420f5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/imc.c +++ /dev/null @@ -1,834 +0,0 @@ -/* - * IMC compatible decoder - * Copyright (c) 2002-2004 Maxim Poliakovski - * Copyright (c) 2006 Benjamin Larsson - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * IMC - Intel Music Coder - * A mdct based codec using a 256 points large transform - * divied into 32 bands with some mix of scale factors. - * Only mono is supported. - * - */ - - -#include -#include -#include - -#define ALT_BITSTREAM_READER -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" - -#include "imcdata.h" - -#define IMC_BLOCK_SIZE 64 -#define IMC_FRAME_ID 0x21 -#define BANDS 32 -#define COEFFS 256 - -typedef struct { - float old_floor[BANDS]; - float flcoeffs1[BANDS]; - float flcoeffs2[BANDS]; - float flcoeffs3[BANDS]; - float flcoeffs4[BANDS]; - float flcoeffs5[BANDS]; - float flcoeffs6[BANDS]; - float CWdecoded[COEFFS]; - - /** MDCT tables */ - //@{ - float mdct_sine_window[COEFFS]; - float post_cos[COEFFS]; - float post_sin[COEFFS]; - float pre_coef1[COEFFS]; - float pre_coef2[COEFFS]; - float last_fft_im[COEFFS]; - //@} - - int bandWidthT[BANDS]; ///< codewords per band - int bitsBandT[BANDS]; ///< how many bits per codeword in band - int CWlengthT[COEFFS]; ///< how many bits in each codeword - int levlCoeffBuf[BANDS]; - int bandFlagsBuf[BANDS]; ///< flags for each band - int sumLenArr[BANDS]; ///< bits for all coeffs in band - int skipFlagRaw[BANDS]; ///< skip flags are stored in raw form or not - int skipFlagBits[BANDS]; ///< bits used to code skip flags - int skipFlagCount[BANDS]; ///< skipped coeffients per band - int skipFlags[COEFFS]; ///< skip coefficient decoding or not - int codewords[COEFFS]; ///< raw codewords read from bitstream - float sqrt_tab[30]; - GetBitContext gb; - int decoder_reset; - float one_div_log2; - - DSPContext dsp; - FFTContext fft; - DECLARE_ALIGNED(16, FFTComplex, samples)[COEFFS/2]; - DECLARE_ALIGNED(16, float, out_samples)[COEFFS]; -} IMCContext; - -static VLC huffman_vlc[4][4]; - -#define VLC_TABLES_SIZE 9512 - -static const int vlc_offsets[17] = { - 0, 640, 1156, 1732, 2308, 2852, 3396, 3924, - 4452, 5220, 5860, 6628, 7268, 7908, 8424, 8936, VLC_TABLES_SIZE}; - -static VLC_TYPE vlc_tables[VLC_TABLES_SIZE][2]; - -static av_cold int imc_decode_init(AVCodecContext * avctx) -{ - int i, j; - IMCContext *q = avctx->priv_data; - double r1, r2; - - q->decoder_reset = 1; - - for(i = 0; i < BANDS; i++) - q->old_floor[i] = 1.0; - - /* Build mdct window, a simple sine window normalized with sqrt(2) */ - ff_sine_window_init(q->mdct_sine_window, COEFFS); - for(i = 0; i < COEFFS; i++) - q->mdct_sine_window[i] *= sqrt(2.0); - for(i = 0; i < COEFFS/2; i++){ - q->post_cos[i] = cos(i / 256.0 * M_PI); - q->post_sin[i] = sin(i / 256.0 * M_PI); - - r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI); - r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI); - - if (i & 0x1) - { - q->pre_coef1[i] = (r1 + r2) * sqrt(2.0); - q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0); - } - else - { - q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0); - q->pre_coef2[i] = (r1 - r2) * sqrt(2.0); - } - - q->last_fft_im[i] = 0; - } - - /* Generate a square root table */ - - for(i = 0; i < 30; i++) { - q->sqrt_tab[i] = sqrt(i); - } - - /* initialize the VLC tables */ - for(i = 0; i < 4 ; i++) { - for(j = 0; j < 4; j++) { - huffman_vlc[i][j].table = &vlc_tables[vlc_offsets[i * 4 + j]]; - huffman_vlc[i][j].table_allocated = vlc_offsets[i * 4 + j + 1] - vlc_offsets[i * 4 + j]; - init_vlc(&huffman_vlc[i][j], 9, imc_huffman_sizes[i], - imc_huffman_lens[i][j], 1, 1, - imc_huffman_bits[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - } - q->one_div_log2 = 1/log(2); - - ff_fft_init(&q->fft, 7, 1); - dsputil_init(&q->dsp, avctx); - avctx->sample_fmt = SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; - return 0; -} - -static void imc_calculate_coeffs(IMCContext* q, float* flcoeffs1, float* flcoeffs2, int* bandWidthT, - float* flcoeffs3, float* flcoeffs5) -{ - float workT1[BANDS]; - float workT2[BANDS]; - float workT3[BANDS]; - float snr_limit = 1.e-30; - float accum = 0.0; - int i, cnt2; - - for(i = 0; i < BANDS; i++) { - flcoeffs5[i] = workT2[i] = 0.0; - if (bandWidthT[i]){ - workT1[i] = flcoeffs1[i] * flcoeffs1[i]; - flcoeffs3[i] = 2.0 * flcoeffs2[i]; - } else { - workT1[i] = 0.0; - flcoeffs3[i] = -30000.0; - } - workT3[i] = bandWidthT[i] * workT1[i] * 0.01; - if (workT3[i] <= snr_limit) - workT3[i] = 0.0; - } - - for(i = 0; i < BANDS; i++) { - for(cnt2 = i; cnt2 < cyclTab[i]; cnt2++) - flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i]; - workT2[cnt2-1] = workT2[cnt2-1] + workT3[i]; - } - - for(i = 1; i < BANDS; i++) { - accum = (workT2[i-1] + accum) * imc_weights1[i-1]; - flcoeffs5[i] += accum; - } - - for(i = 0; i < BANDS; i++) - workT2[i] = 0.0; - - for(i = 0; i < BANDS; i++) { - for(cnt2 = i-1; cnt2 > cyclTab2[i]; cnt2--) - flcoeffs5[cnt2] += workT3[i]; - workT2[cnt2+1] += workT3[i]; - } - - accum = 0.0; - - for(i = BANDS-2; i >= 0; i--) { - accum = (workT2[i+1] + accum) * imc_weights2[i]; - flcoeffs5[i] += accum; - //there is missing code here, but it seems to never be triggered - } -} - - -static void imc_read_level_coeffs(IMCContext* q, int stream_format_code, int* levlCoeffs) -{ - int i; - VLC *hufftab[4]; - int start = 0; - const uint8_t *cb_sel; - int s; - - s = stream_format_code >> 1; - hufftab[0] = &huffman_vlc[s][0]; - hufftab[1] = &huffman_vlc[s][1]; - hufftab[2] = &huffman_vlc[s][2]; - hufftab[3] = &huffman_vlc[s][3]; - cb_sel = imc_cb_select[s]; - - if(stream_format_code & 4) - start = 1; - if(start) - levlCoeffs[0] = get_bits(&q->gb, 7); - for(i = start; i < BANDS; i++){ - levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table, hufftab[cb_sel[i]]->bits, 2); - if(levlCoeffs[i] == 17) - levlCoeffs[i] += get_bits(&q->gb, 4); - } -} - -static void imc_decode_level_coefficients(IMCContext* q, int* levlCoeffBuf, float* flcoeffs1, - float* flcoeffs2) -{ - int i, level; - float tmp, tmp2; - //maybe some frequency division thingy - - flcoeffs1[0] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125 - flcoeffs2[0] = log(flcoeffs1[0])/log(2); - tmp = flcoeffs1[0]; - tmp2 = flcoeffs2[0]; - - for(i = 1; i < BANDS; i++) { - level = levlCoeffBuf[i]; - if (level == 16) { - flcoeffs1[i] = 1.0; - flcoeffs2[i] = 0.0; - } else { - if (level < 17) - level -=7; - else if (level <= 24) - level -=32; - else - level -=16; - - tmp *= imc_exp_tab[15 + level]; - tmp2 += 0.83048 * level; // 0.83048 = log2(10) * 0.25 - flcoeffs1[i] = tmp; - flcoeffs2[i] = tmp2; - } - } -} - - -static void imc_decode_level_coefficients2(IMCContext* q, int* levlCoeffBuf, float* old_floor, float* flcoeffs1, - float* flcoeffs2) { - int i; - //FIXME maybe flag_buf = noise coding and flcoeffs1 = new scale factors - // and flcoeffs2 old scale factors - // might be incomplete due to a missing table that is in the binary code - for(i = 0; i < BANDS; i++) { - flcoeffs1[i] = 0; - if(levlCoeffBuf[i] < 16) { - flcoeffs1[i] = imc_exp_tab2[levlCoeffBuf[i]] * old_floor[i]; - flcoeffs2[i] = (levlCoeffBuf[i]-7) * 0.83048 + flcoeffs2[i]; // 0.83048 = log2(10) * 0.25 - } else { - flcoeffs1[i] = old_floor[i]; - } - } -} - -/** - * Perform bit allocation depending on bits available - */ -static int bit_allocation (IMCContext* q, int stream_format_code, int freebits, int flag) { - int i, j; - const float limit = -1.e20; - float highest = 0.0; - int indx; - int t1 = 0; - int t2 = 1; - float summa = 0.0; - int iacc = 0; - int summer = 0; - int rres, cwlen; - float lowest = 1.e10; - int low_indx = 0; - float workT[32]; - int flg; - int found_indx = 0; - - for(i = 0; i < BANDS; i++) - highest = FFMAX(highest, q->flcoeffs1[i]); - - for(i = 0; i < BANDS-1; i++) { - q->flcoeffs4[i] = q->flcoeffs3[i] - log(q->flcoeffs5[i])/log(2); - } - q->flcoeffs4[BANDS - 1] = limit; - - highest = highest * 0.25; - - for(i = 0; i < BANDS; i++) { - indx = -1; - if ((band_tab[i+1] - band_tab[i]) == q->bandWidthT[i]) - indx = 0; - - if ((band_tab[i+1] - band_tab[i]) > q->bandWidthT[i]) - indx = 1; - - if (((band_tab[i+1] - band_tab[i])/2) >= q->bandWidthT[i]) - indx = 2; - - if (indx == -1) - return -1; - - q->flcoeffs4[i] = q->flcoeffs4[i] + xTab[(indx*2 + (q->flcoeffs1[i] < highest)) * 2 + flag]; - } - - if (stream_format_code & 0x2) { - q->flcoeffs4[0] = limit; - q->flcoeffs4[1] = limit; - q->flcoeffs4[2] = limit; - q->flcoeffs4[3] = limit; - } - - for(i = (stream_format_code & 0x2)?4:0; i < BANDS-1; i++) { - iacc += q->bandWidthT[i]; - summa += q->bandWidthT[i] * q->flcoeffs4[i]; - } - q->bandWidthT[BANDS-1] = 0; - summa = (summa * 0.5 - freebits) / iacc; - - - for(i = 0; i < BANDS/2; i++) { - rres = summer - freebits; - if((rres >= -8) && (rres <= 8)) break; - - summer = 0; - iacc = 0; - - for(j = (stream_format_code & 0x2)?4:0; j < BANDS; j++) { - cwlen = av_clip((int)((q->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6); - - q->bitsBandT[j] = cwlen; - summer += q->bandWidthT[j] * cwlen; - - if (cwlen > 0) - iacc += q->bandWidthT[j]; - } - - flg = t2; - t2 = 1; - if (freebits < summer) - t2 = -1; - if (i == 0) - flg = t2; - if(flg != t2) - t1++; - - summa = (float)(summer - freebits) / ((t1 + 1) * iacc) + summa; - } - - for(i = (stream_format_code & 0x2)?4:0; i < BANDS; i++) { - for(j = band_tab[i]; j < band_tab[i+1]; j++) - q->CWlengthT[j] = q->bitsBandT[i]; - } - - if (freebits > summer) { - for(i = 0; i < BANDS; i++) { - workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415); - } - - highest = 0.0; - - do{ - if (highest <= -1.e20) - break; - - found_indx = 0; - highest = -1.e20; - - for(i = 0; i < BANDS; i++) { - if (workT[i] > highest) { - highest = workT[i]; - found_indx = i; - } - } - - if (highest > -1.e20) { - workT[found_indx] -= 2.0; - if (++(q->bitsBandT[found_indx]) == 6) - workT[found_indx] = -1.e20; - - for(j = band_tab[found_indx]; j < band_tab[found_indx+1] && (freebits > summer); j++){ - q->CWlengthT[j]++; - summer++; - } - } - }while (freebits > summer); - } - if (freebits < summer) { - for(i = 0; i < BANDS; i++) { - workT[i] = q->bitsBandT[i] ? (q->bitsBandT[i] * -2 + q->flcoeffs4[i] + 1.585) : 1.e20; - } - if (stream_format_code & 0x2) { - workT[0] = 1.e20; - workT[1] = 1.e20; - workT[2] = 1.e20; - workT[3] = 1.e20; - } - while (freebits < summer){ - lowest = 1.e10; - low_indx = 0; - for(i = 0; i < BANDS; i++) { - if (workT[i] < lowest) { - lowest = workT[i]; - low_indx = i; - } - } - //if(lowest >= 1.e10) break; - workT[low_indx] = lowest + 2.0; - - if (!(--q->bitsBandT[low_indx])) - workT[low_indx] = 1.e20; - - for(j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++){ - if(q->CWlengthT[j] > 0){ - q->CWlengthT[j]--; - summer--; - } - } - } - } - return 0; -} - -static void imc_get_skip_coeff(IMCContext* q) { - int i, j; - - memset(q->skipFlagBits, 0, sizeof(q->skipFlagBits)); - memset(q->skipFlagCount, 0, sizeof(q->skipFlagCount)); - for(i = 0; i < BANDS; i++) { - if (!q->bandFlagsBuf[i] || !q->bandWidthT[i]) - continue; - - if (!q->skipFlagRaw[i]) { - q->skipFlagBits[i] = band_tab[i+1] - band_tab[i]; - - for(j = band_tab[i]; j < band_tab[i+1]; j++) { - if ((q->skipFlags[j] = get_bits1(&q->gb))) - q->skipFlagCount[i]++; - } - } else { - for(j = band_tab[i]; j < (band_tab[i+1]-1); j += 2) { - if(!get_bits1(&q->gb)){//0 - q->skipFlagBits[i]++; - q->skipFlags[j]=1; - q->skipFlags[j+1]=1; - q->skipFlagCount[i] += 2; - }else{ - if(get_bits1(&q->gb)){//11 - q->skipFlagBits[i] +=2; - q->skipFlags[j]=0; - q->skipFlags[j+1]=1; - q->skipFlagCount[i]++; - }else{ - q->skipFlagBits[i] +=3; - q->skipFlags[j+1]=0; - if(!get_bits1(&q->gb)){//100 - q->skipFlags[j]=1; - q->skipFlagCount[i]++; - }else{//101 - q->skipFlags[j]=0; - } - } - } - } - - if (j < band_tab[i+1]) { - q->skipFlagBits[i]++; - if ((q->skipFlags[j] = get_bits1(&q->gb))) - q->skipFlagCount[i]++; - } - } - } -} - -/** - * Increase highest' band coefficient sizes as some bits won't be used - */ -static void imc_adjust_bit_allocation (IMCContext* q, int summer) { - float workT[32]; - int corrected = 0; - int i, j; - float highest = 0; - int found_indx=0; - - for(i = 0; i < BANDS; i++) { - workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415); - } - - while (corrected < summer) { - if(highest <= -1.e20) - break; - - highest = -1.e20; - - for(i = 0; i < BANDS; i++) { - if (workT[i] > highest) { - highest = workT[i]; - found_indx = i; - } - } - - if (highest > -1.e20) { - workT[found_indx] -= 2.0; - if (++(q->bitsBandT[found_indx]) == 6) - workT[found_indx] = -1.e20; - - for(j = band_tab[found_indx]; j < band_tab[found_indx+1] && (corrected < summer); j++) { - if (!q->skipFlags[j] && (q->CWlengthT[j] < 6)) { - q->CWlengthT[j]++; - corrected++; - } - } - } - } -} - -static void imc_imdct256(IMCContext *q) { - int i; - float re, im; - - /* prerotation */ - for(i=0; i < COEFFS/2; i++){ - q->samples[i].re = -(q->pre_coef1[i] * q->CWdecoded[COEFFS-1-i*2]) - - (q->pre_coef2[i] * q->CWdecoded[i*2]); - q->samples[i].im = (q->pre_coef2[i] * q->CWdecoded[COEFFS-1-i*2]) - - (q->pre_coef1[i] * q->CWdecoded[i*2]); - } - - /* FFT */ - ff_fft_permute(&q->fft, q->samples); - ff_fft_calc (&q->fft, q->samples); - - /* postrotation, window and reorder */ - for(i = 0; i < COEFFS/2; i++){ - re = (q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]); - im = (-q->samples[i].im * q->post_cos[i]) - (q->samples[i].re * q->post_sin[i]); - q->out_samples[i*2] = (q->mdct_sine_window[COEFFS-1-i*2] * q->last_fft_im[i]) + (q->mdct_sine_window[i*2] * re); - q->out_samples[COEFFS-1-i*2] = (q->mdct_sine_window[i*2] * q->last_fft_im[i]) - (q->mdct_sine_window[COEFFS-1-i*2] * re); - q->last_fft_im[i] = im; - } -} - -static int inverse_quant_coeff (IMCContext* q, int stream_format_code) { - int i, j; - int middle_value, cw_len, max_size; - const float* quantizer; - - for(i = 0; i < BANDS; i++) { - for(j = band_tab[i]; j < band_tab[i+1]; j++) { - q->CWdecoded[j] = 0; - cw_len = q->CWlengthT[j]; - - if (cw_len <= 0 || q->skipFlags[j]) - continue; - - max_size = 1 << cw_len; - middle_value = max_size >> 1; - - if (q->codewords[j] >= max_size || q->codewords[j] < 0) - return -1; - - if (cw_len >= 4){ - quantizer = imc_quantizer2[(stream_format_code & 2) >> 1]; - if (q->codewords[j] >= middle_value) - q->CWdecoded[j] = quantizer[q->codewords[j] - 8] * q->flcoeffs6[i]; - else - q->CWdecoded[j] = -quantizer[max_size - q->codewords[j] - 8 - 1] * q->flcoeffs6[i]; - }else{ - quantizer = imc_quantizer1[((stream_format_code & 2) >> 1) | (q->bandFlagsBuf[i] << 1)]; - if (q->codewords[j] >= middle_value) - q->CWdecoded[j] = quantizer[q->codewords[j] - 1] * q->flcoeffs6[i]; - else - q->CWdecoded[j] = -quantizer[max_size - 2 - q->codewords[j]] * q->flcoeffs6[i]; - } - } - } - return 0; -} - - -static int imc_get_coeffs (IMCContext* q) { - int i, j, cw_len, cw; - - for(i = 0; i < BANDS; i++) { - if(!q->sumLenArr[i]) continue; - if (q->bandFlagsBuf[i] || q->bandWidthT[i]) { - for(j = band_tab[i]; j < band_tab[i+1]; j++) { - cw_len = q->CWlengthT[j]; - cw = 0; - - if (get_bits_count(&q->gb) + cw_len > 512){ -//av_log(NULL,0,"Band %i coeff %i cw_len %i\n",i,j,cw_len); - return -1; - } - - if(cw_len && (!q->bandFlagsBuf[i] || !q->skipFlags[j])) - cw = get_bits(&q->gb, cw_len); - - q->codewords[j] = cw; - } - } - } - return 0; -} - -static int imc_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - - IMCContext *q = avctx->priv_data; - - int stream_format_code; - int imc_hdr, i, j; - int flag; - int bits, summer; - int counter, bitscount; - uint16_t buf16[IMC_BLOCK_SIZE / 2]; - - if (buf_size < IMC_BLOCK_SIZE) { - av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n"); - return -1; - } - for(i = 0; i < IMC_BLOCK_SIZE / 2; i++) - buf16[i] = bswap_16(((const uint16_t*)buf)[i]); - - init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8); - - /* Check the frame header */ - imc_hdr = get_bits(&q->gb, 9); - if (imc_hdr != IMC_FRAME_ID) { - av_log(avctx, AV_LOG_ERROR, "imc frame header check failed!\n"); - av_log(avctx, AV_LOG_ERROR, "got %x instead of 0x21.\n", imc_hdr); - return -1; - } - stream_format_code = get_bits(&q->gb, 3); - - if(stream_format_code & 1){ - av_log(avctx, AV_LOG_ERROR, "Stream code format %X is not supported\n", stream_format_code); - return -1; - } - -// av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code); - - if (stream_format_code & 0x04) - q->decoder_reset = 1; - - if(q->decoder_reset) { - memset(q->out_samples, 0, sizeof(q->out_samples)); - for(i = 0; i < BANDS; i++)q->old_floor[i] = 1.0; - for(i = 0; i < COEFFS; i++)q->CWdecoded[i] = 0; - q->decoder_reset = 0; - } - - flag = get_bits1(&q->gb); - imc_read_level_coeffs(q, stream_format_code, q->levlCoeffBuf); - - if (stream_format_code & 0x4) - imc_decode_level_coefficients(q, q->levlCoeffBuf, q->flcoeffs1, q->flcoeffs2); - else - imc_decode_level_coefficients2(q, q->levlCoeffBuf, q->old_floor, q->flcoeffs1, q->flcoeffs2); - - memcpy(q->old_floor, q->flcoeffs1, 32 * sizeof(float)); - - counter = 0; - for (i=0 ; ilevlCoeffBuf[i] == 16) { - q->bandWidthT[i] = 0; - counter++; - } else - q->bandWidthT[i] = band_tab[i+1] - band_tab[i]; - } - memset(q->bandFlagsBuf, 0, BANDS * sizeof(int)); - for(i = 0; i < BANDS-1; i++) { - if (q->bandWidthT[i]) - q->bandFlagsBuf[i] = get_bits1(&q->gb); - } - - imc_calculate_coeffs(q, q->flcoeffs1, q->flcoeffs2, q->bandWidthT, q->flcoeffs3, q->flcoeffs5); - - bitscount = 0; - /* first 4 bands will be assigned 5 bits per coefficient */ - if (stream_format_code & 0x2) { - bitscount += 15; - - q->bitsBandT[0] = 5; - q->CWlengthT[0] = 5; - q->CWlengthT[1] = 5; - q->CWlengthT[2] = 5; - for(i = 1; i < 4; i++){ - bits = (q->levlCoeffBuf[i] == 16) ? 0 : 5; - q->bitsBandT[i] = bits; - for(j = band_tab[i]; j < band_tab[i+1]; j++) { - q->CWlengthT[j] = bits; - bitscount += bits; - } - } - } - - if(bit_allocation (q, stream_format_code, 512 - bitscount - get_bits_count(&q->gb), flag) < 0) { - av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n"); - q->decoder_reset = 1; - return -1; - } - - for(i = 0; i < BANDS; i++) { - q->sumLenArr[i] = 0; - q->skipFlagRaw[i] = 0; - for(j = band_tab[i]; j < band_tab[i+1]; j++) - q->sumLenArr[i] += q->CWlengthT[j]; - if (q->bandFlagsBuf[i]) - if( (((band_tab[i+1] - band_tab[i]) * 1.5) > q->sumLenArr[i]) && (q->sumLenArr[i] > 0)) - q->skipFlagRaw[i] = 1; - } - - imc_get_skip_coeff(q); - - for(i = 0; i < BANDS; i++) { - q->flcoeffs6[i] = q->flcoeffs1[i]; - /* band has flag set and at least one coded coefficient */ - if (q->bandFlagsBuf[i] && (band_tab[i+1] - band_tab[i]) != q->skipFlagCount[i]){ - q->flcoeffs6[i] *= q->sqrt_tab[band_tab[i+1] - band_tab[i]] / - q->sqrt_tab[(band_tab[i+1] - band_tab[i] - q->skipFlagCount[i])]; - } - } - - /* calculate bits left, bits needed and adjust bit allocation */ - bits = summer = 0; - - for(i = 0; i < BANDS; i++) { - if (q->bandFlagsBuf[i]) { - for(j = band_tab[i]; j < band_tab[i+1]; j++) { - if(q->skipFlags[j]) { - summer += q->CWlengthT[j]; - q->CWlengthT[j] = 0; - } - } - bits += q->skipFlagBits[i]; - summer -= q->skipFlagBits[i]; - } - } - imc_adjust_bit_allocation(q, summer); - - for(i = 0; i < BANDS; i++) { - q->sumLenArr[i] = 0; - - for(j = band_tab[i]; j < band_tab[i+1]; j++) - if (!q->skipFlags[j]) - q->sumLenArr[i] += q->CWlengthT[j]; - } - - memset(q->codewords, 0, sizeof(q->codewords)); - - if(imc_get_coeffs(q) < 0) { - av_log(avctx, AV_LOG_ERROR, "Read coefficients failed\n"); - q->decoder_reset = 1; - return 0; - } - - if(inverse_quant_coeff(q, stream_format_code) < 0) { - av_log(avctx, AV_LOG_ERROR, "Inverse quantization of coefficients failed\n"); - q->decoder_reset = 1; - return 0; - } - - memset(q->skipFlags, 0, sizeof(q->skipFlags)); - - imc_imdct256(q); - - q->dsp.float_to_int16(data, q->out_samples, COEFFS); - - *data_size = COEFFS * sizeof(int16_t); - - return IMC_BLOCK_SIZE; -} - - -static av_cold int imc_decode_close(AVCodecContext * avctx) -{ - IMCContext *q = avctx->priv_data; - - ff_fft_end(&q->fft); - return 0; -} - - -AVCodec imc_decoder = { - .name = "imc", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_IMC, - .priv_data_size = sizeof(IMCContext), - .init = imc_decode_init, - .close = imc_decode_close, - .decode = imc_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/imcdata.h b/tizen/distrib/ffmpeg/libavcodec/imcdata.h deleted file mode 100644 index 64e7c71..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/imcdata.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * IMC compatible decoder - * Copyright (c) 2002-2004 Maxim Poliakovski - * Copyright (c) 2006 Benjamin Larsson - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_IMCDATA_H -#define AVCODEC_IMCDATA_H - -#include - -static const uint16_t band_tab[33] = { - 0, 3, 6, 9, 12, 16, 20, 24, 29, 34, 40, - 46, 53, 60, 68, 76, 84, 93, 102, 111, 121, 131, - 141, 151, 162, 173, 184, 195, 207, 219, 231, 243, 256, -}; - - -static const int8_t cyclTab[32] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, -}; - -static const int8_t cyclTab2[32] = { - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, -23, 24, 25, 26, 27, 28, 29}; - -static const float imc_weights1[31] = { - 0.119595, 0.123124, 0.129192, 9.97377e-2, 8.1923e-2, 9.61153e-2, 8.77885e-2, 8.61174e-2, - 9.00882e-2, 9.91658e-2, 0.112991, 0.131126, 0.152886, 0.177292, 0.221782, 0.244917, 0.267386, - 0.306816, 0.323046, 0.33729, 0.366773, 0.392557, 0.398076, 0.403302, 0.42451, 0.444777, - 0.449188, 0.455445, 0.477853, 0.500669, 0.510395}; - -static const float imc_weights2[31] = { - 3.23466e-3, 3.49886e-3, 3.98413e-3, 1.98116e-3, 1.16465e-3, 1.79283e-3, 1.40372e-3, 1.33274e-3, - 1.50523e-3, 1.95064e-3, 2.77472e-3, 4.14725e-3, 6.2776e-3, 9.36401e-3, 1.71397e-2, 2.24052e-2, - 2.83971e-2, 4.11689e-2, 4.73165e-2, 5.31631e-2, 6.66614e-2, 8.00824e-2, 8.31588e-2, 8.61397e-2, - 9.89229e-2, 0.112197, 0.115227, 0.119613, 0.136174, 0.15445, 0.162685}; - -static const float imc_quantizer1[4][8] = { - { 8.4431201e-1, 4.7358301e-1, 1.448354, 2.7073899e-1, 7.4449003e-1, 1.241991, 1.845484, 0.0}, - { 8.6876702e-1, 4.7659001e-1, 1.478224, 2.5672799e-1, 7.55777e-1, 1.3229851, 2.03438, 0.0}, - { 7.5891501e-1, 6.2272799e-1, 1.271322, 3.47904e-1, 7.5317699e-1, 1.150767, 1.628476, 0.0}, - { 7.65257e-1, 6.44647e-1, 1.263824, 3.4548101e-1, 7.6384902e-1, 1.214466, 1.7638789, 0.0}, -}; - -static const float imc_quantizer2[2][56] = { - { 1.39236e-1, 3.50548e-1, 5.9547901e-1, 8.5772401e-1, 1.121545, 1.3882281, 1.695882, 2.1270809, - 7.2221003e-2, 1.85177e-1, 2.9521701e-1, 4.12568e-1, 5.4068601e-1, 6.7679501e-1, 8.1196898e-1, 9.4765198e-1, - 1.0779999, 1.203415, 1.337265, 1.481871, 1.639982, 1.814766, 2.0701399, 2.449862, - 3.7533998e-2, 1.02722e-1, 1.6021401e-1, 2.16043e-1, 2.7231601e-1, 3.3025399e-1, 3.9022601e-1, 4.52849e-1, - 5.1794899e-1, 5.8529502e-1, 6.53956e-1, 7.2312802e-1, 7.9150802e-1, 8.5891002e-1, 9.28141e-1, 9.9706203e-1, - 1.062153, 1.12564, 1.189834, 1.256122, 1.324469, 1.3955311, 1.468906, 1.545084, - 1.6264729, 1.711524, 1.802705, 1.91023, 2.0533991, 2.22333, 2.4830019, 3.253329 }, - { 1.11654e-1, 3.54469e-1, 6.4232099e-1, 9.6128798e-1, 1.295053, 1.61777, 1.989839, 2.51107, - 5.7721999e-2, 1.69879e-1, 2.97589e-1, 4.3858799e-1, 5.9039903e-1, 7.4934798e-1, 9.1628098e-1, 1.087297, - 1.262751, 1.4288321, 1.6040879, 1.79067, 2.000668, 2.2394669, 2.649332, 5.2760072, - 2.9722e-2, 8.7316997e-2, 1.4445201e-1, 2.04247e-1, 2.6879501e-1, 3.3716801e-1, 4.08811e-1, 4.8306999e-1, - 5.6049401e-1, 6.3955498e-1, 7.2044599e-1, 8.0427998e-1, 8.8933599e-1, 9.7537601e-1, 1.062461, 1.1510431, - 1.240236, 1.326715, 1.412513, 1.500502, 1.591749, 1.686413, 1.785239, 1.891233, - 2.0051291, 2.127681, 2.2709141, 2.475826, 2.7219379, 3.101985, 4.686213, 6.2287788}, -}; - - -static const float xTab[14] = {7.6, 3.6, 4.4, 3.7, 6.1, 5.1, 2.3, 1.6, 6.2, 1.5, 1.8, 1.2, 0, 0}; //10014048 - -/* precomputed table for 10^(i/4), i=-15..16 */ -static const float imc_exp_tab[32] = { - 1.778280e-4, 3.162278e-4, 5.623413e-4, 1.000000e-3, - 1.778280e-3, 3.162278e-3, 5.623413e-3, 1.000000e-2, - 1.778280e-2, 3.162278e-2, 5.623413e-2, 1.000000e-1, - 1.778280e-1, 3.162278e-1, 5.623413e-1, 1.000000e00, - 1.778280e00, 3.162278e00, 5.623413e00, 1.000000e01, - 1.778280e01, 3.162278e01, 5.623413e01, 1.000000e02, - 1.778280e02, 3.162278e02, 5.623413e02, 1.000000e03, - 1.778280e03, 3.162278e03, 5.623413e03, 1.000000e04 -}; -static const float * const imc_exp_tab2 = imc_exp_tab + 8; - - -static const uint8_t imc_cb_select[4][32] = { - { 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 }, - { 0, 2, 0, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 }, - { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -static const uint8_t imc_huffman_sizes[4] = { - 17, 17, 18, 18 -}; - -static const uint8_t imc_huffman_lens[4][4][18] = { - { - { 16, 15, 13, 11, 8, 5, 3, 1, 2, 4, 6, 9, 10, 12, 14, 16, 7, 0 }, - { 10, 8, 7, 6, 4, 4, 3, 2, 2, 3, 4, 6, 7, 9, 11, 11, 7, 0 }, - { 15, 15, 14, 11, 8, 6, 4, 2, 1, 4, 5, 7, 9, 10, 12, 13, 4, 0 }, - { 13, 11, 10, 8, 6, 4, 2, 2, 2, 3, 5, 7, 9, 12, 15, 15, 14, 0 }, - }, - { - { 14, 12, 10, 8, 7, 4, 2, 2, 2, 3, 5, 7, 9, 11, 13, 14, 7, 0 }, - { 14, 13, 11, 8, 6, 4, 3, 2, 2, 3, 5, 7, 9, 10, 12, 14, 3, 0 }, - { 13, 12, 10, 7, 5, 4, 3, 2, 2, 3, 4, 6, 8, 9, 11, 13, 4, 0 }, - { 13, 12, 10, 7, 5, 4, 3, 2, 2, 3, 4, 6, 8, 9, 11, 13, 4, 0 }, - }, - { - { 16, 14, 12, 10, 8, 5, 3, 1, 2, 4, 7, 9, 11, 13, 15, 17, 6, 17 }, - { 15, 13, 11, 8, 6, 4, 2, 2, 2, 3, 5, 7, 10, 12, 14, 16, 9, 16 }, - { 14, 12, 11, 9, 8, 6, 3, 1, 2, 5, 7, 10, 13, 15, 16, 17, 4, 17 }, - { 16, 14, 12, 9, 7, 5, 2, 2, 2, 3, 4, 6, 8, 11, 13, 15, 10, 16 }, - }, - { - { 13, 11, 10, 8, 7, 5, 2, 2, 2, 4, 6, 9, 12, 14, 15, 16, 3, 16 }, - { 11, 11, 10, 9, 8, 7, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 5 }, - { 9, 9, 7, 6, 5, 4, 3, 3, 2, 3, 4, 5, 4, 5, 5, 6, 8, 6 }, - { 13, 12, 10, 8, 5, 3, 3, 2, 2, 3, 4, 7, 9, 11, 14, 15, 6, 15 }, - } -}; - -static const uint16_t imc_huffman_bits[4][4][18] = { - { - { 0xCC32, 0x6618, 0x1987, 0x0660, 0x00CD, 0x0018, 0x0007, 0x0000, 0x0002, 0x000D, 0x0032, 0x0199, 0x0331, 0x0CC2, 0x330D, 0xCC33, 0x0067, 0x0000 }, - { 0x02FE, 0x00BE, 0x005E, 0x002D, 0x000A, 0x0009, 0x0003, 0x0003, 0x0000, 0x0002, 0x0008, 0x002C, 0x005D, 0x017E, 0x05FE, 0x05FF, 0x005C, 0x0000 }, - { 0x5169, 0x5168, 0x28B5, 0x0517, 0x00A3, 0x0029, 0x0008, 0x0003, 0x0000, 0x0009, 0x0015, 0x0050, 0x0144, 0x028A, 0x0A2C, 0x145B, 0x000B, 0x0000 }, - { 0x1231, 0x048D, 0x0247, 0x0090, 0x0025, 0x0008, 0x0001, 0x0003, 0x0000, 0x0005, 0x0013, 0x0049, 0x0122, 0x0919, 0x48C3, 0x48C2, 0x2460, 0x0000 }, - }, - { - { 0x2D1D, 0x0B46, 0x02D0, 0x00B5, 0x0059, 0x000A, 0x0003, 0x0001, 0x0000, 0x0004, 0x0017, 0x005B, 0x0169, 0x05A2, 0x168F, 0x2D1C, 0x0058, 0x0000 }, - { 0x1800, 0x0C01, 0x0301, 0x0061, 0x0019, 0x0007, 0x0004, 0x0003, 0x0000, 0x0005, 0x000D, 0x0031, 0x00C1, 0x0181, 0x0601, 0x1801, 0x0002, 0x0000 }, - { 0x1556, 0x0AAA, 0x02AB, 0x0054, 0x0014, 0x000B, 0x0002, 0x0003, 0x0000, 0x0003, 0x0008, 0x002B, 0x00AB, 0x0154, 0x0554, 0x1557, 0x0009, 0x0000 }, - { 0x1556, 0x0AAA, 0x02AB, 0x0054, 0x0014, 0x000B, 0x0002, 0x0003, 0x0000, 0x0003, 0x0008, 0x002B, 0x00AB, 0x0154, 0x0554, 0x1557, 0x0009, 0x0000 }, - }, - { - { 0x2993, 0x0A65, 0x0298, 0x00A7, 0x0028, 0x0004, 0x0000, 0x0001, 0x0001, 0x0003, 0x0015, 0x0052, 0x014D, 0x0533, 0x14C8, 0x5324, 0x000B, 0x5325 }, - { 0x09B8, 0x026F, 0x009A, 0x0012, 0x0005, 0x0000, 0x0001, 0x0002, 0x0003, 0x0001, 0x0003, 0x0008, 0x004C, 0x0136, 0x04DD, 0x1373, 0x0027, 0x1372 }, - { 0x0787, 0x01E0, 0x00F1, 0x003D, 0x001F, 0x0006, 0x0001, 0x0001, 0x0001, 0x0002, 0x000E, 0x0079, 0x03C2, 0x0F0D, 0x1E19, 0x3C30, 0x0000, 0x3C31 }, - { 0x4B06, 0x12C0, 0x04B1, 0x0097, 0x0024, 0x0008, 0x0002, 0x0003, 0x0000, 0x0003, 0x0005, 0x0013, 0x004A, 0x0259, 0x0961, 0x2582, 0x012D, 0x4B07 }, - }, - { - { 0x0A5A, 0x0297, 0x014A, 0x0053, 0x0028, 0x000B, 0x0003, 0x0000, 0x0002, 0x0004, 0x0015, 0x00A4, 0x052C, 0x14B7, 0x296C, 0x52DB, 0x0003, 0x52DA }, - { 0x0193, 0x0192, 0x00C8, 0x0065, 0x0033, 0x0018, 0x0007, 0x0004, 0x0000, 0x0004, 0x0005, 0x0007, 0x0006, 0x0003, 0x0005, 0x0005, 0x000D, 0x0004 }, - { 0x0012, 0x0013, 0x0005, 0x0003, 0x0000, 0x0003, 0x0005, 0x0004, 0x0003, 0x0003, 0x0005, 0x0005, 0x0004, 0x0004, 0x0003, 0x0005, 0x0008, 0x0004 }, - { 0x0D66, 0x06B2, 0x01AD, 0x006A, 0x000C, 0x0005, 0x0004, 0x0000, 0x0003, 0x0002, 0x0007, 0x0034, 0x00D7, 0x0358, 0x1ACF, 0x359C, 0x001B, 0x359D }, - } -}; - -#endif /* AVCODEC_IMCDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/imgconvert.c b/tizen/distrib/ffmpeg/libavcodec/imgconvert.c deleted file mode 100644 index 8f789c4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/imgconvert.c +++ /dev/null @@ -1,1478 +0,0 @@ -/* - * Misc image conversion routines - * Copyright (c) 2001, 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * misc image conversion 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" -#include "colorspace.h" -#include "internal.h" -#include "imgconvert.h" -#include "libavutil/pixdesc.h" - -#if HAVE_MMX -#include "x86/mmx.h" -#include "x86/dsputil_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 { - 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 depth; /**< bit depth of the color components */ -} PixFmtInfo; - -/* this table gives more information about formats */ -static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { - /* YUV formats */ - [PIX_FMT_YUV420P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUV422P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUV444P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUYV422] = { - .nb_channels = 1, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_UYVY422] = { - .nb_channels = 1, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_YUV410P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUV411P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUV440P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUV420P16LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - [PIX_FMT_YUV422P16LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - [PIX_FMT_YUV444P16LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - [PIX_FMT_YUV420P16BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - [PIX_FMT_YUV422P16BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - [PIX_FMT_YUV444P16BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - - - /* YUV formats with alpha plane */ - [PIX_FMT_YUVA420P] = { - .nb_channels = 4, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - - /* JPEG YUV */ - [PIX_FMT_YUVJ420P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUVJ422P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUVJ444P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_YUVJ440P] = { - .nb_channels = 3, - .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - - /* RGB formats */ - [PIX_FMT_RGB24] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_BGR24] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_ARGB] = { - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_RGB48BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 16, - }, - [PIX_FMT_RGB48LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 16, - }, - [PIX_FMT_RGB565BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_RGB565LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_RGB555BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_RGB555LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_RGB444BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - }, - [PIX_FMT_RGB444LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - }, - - /* gray / mono formats */ - [PIX_FMT_GRAY16BE] = { - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - [PIX_FMT_GRAY16LE] = { - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, - }, - [PIX_FMT_GRAY8] = { - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_MONOWHITE] = { - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 1, - }, - [PIX_FMT_MONOBLACK] = { - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 1, - }, - - /* paletted formats */ - [PIX_FMT_PAL8] = { - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PALETTE, - .depth = 8, - }, - [PIX_FMT_UYYVYY411] = { - .nb_channels = 1, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_ABGR] = { - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_BGR565BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_BGR565LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_BGR555BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_BGR555LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - }, - [PIX_FMT_BGR444BE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - }, - [PIX_FMT_BGR444LE] = { - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - }, - [PIX_FMT_RGB8] = { - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_RGB4] = { - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - }, - [PIX_FMT_RGB4_BYTE] = { - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_BGR8] = { - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_BGR4] = { - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - }, - [PIX_FMT_BGR4_BYTE] = { - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_NV12] = { - .nb_channels = 2, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_NV21] = { - .nb_channels = 2, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - - [PIX_FMT_BGRA] = { - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, - [PIX_FMT_RGBA] = { - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - }, -}; - -void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift) -{ - *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w; - *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h; -} - -const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt) -{ - if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) - return NULL; - else - return av_pix_fmt_descriptors[pix_fmt].name; -} - -#if LIBAVCODEC_VERSION_MAJOR < 53 -enum PixelFormat avcodec_get_pix_fmt(const char *name) -{ - return av_get_pix_fmt(name); -} -#endif - -void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt) -{ - /* print header */ - if (pix_fmt < 0) - snprintf (buf, buf_size, - "name " " nb_channels" " depth" " is_alpha" - ); - else{ - PixFmtInfo info= pix_fmt_info[pix_fmt]; - - char is_alpha_char= info.is_alpha ? 'y' : 'n'; - - snprintf (buf, buf_size, - "%-11s %5d %9d %6c", - av_pix_fmt_descriptors[pix_fmt].name, - info.nb_channels, - info.depth, - is_alpha_char - ); - } -} - -int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt) -{ - return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL; -} - -int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){ - int i; - - for(i=0; i<256; i++){ - int r,g,b; - - switch(pix_fmt) { - case PIX_FMT_RGB8: - r= (i>>5 )*36; - g= ((i>>2)&7)*36; - b= (i&3 )*85; - break; - case PIX_FMT_BGR8: - b= (i>>6 )*85; - g= ((i>>3)&7)*36; - r= (i&7 )*36; - break; - case PIX_FMT_RGB4_BYTE: - r= (i>>3 )*255; - g= ((i>>1)&3)*85; - b= (i&1 )*255; - break; - case PIX_FMT_BGR4_BYTE: - b= (i>>3 )*255; - g= ((i>>1)&3)*85; - r= (i&1 )*255; - break; - case PIX_FMT_GRAY8: - r=b=g= i; - break; - default: - return -1; - } - pal[i] = b + (g<<8) + (r<<16); - } - - return 0; -} - -int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width) -{ - int i; - const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; - int max_plane_step [4]; - int max_plane_step_comp[4]; - - memset(picture->linesize, 0, sizeof(picture->linesize)); - - if (desc->flags & PIX_FMT_HWACCEL) - return -1; - - if (desc->flags & PIX_FMT_BITSTREAM) { - picture->linesize[0] = (width * (desc->comp[0].step_minus1+1) + 7) >> 3; - return 0; - } - - memset(max_plane_step , 0, sizeof(max_plane_step )); - memset(max_plane_step_comp, 0, sizeof(max_plane_step_comp)); - for (i = 0; i < 4; i++) { - const AVComponentDescriptor *comp = &(desc->comp[i]); - if ((comp->step_minus1+1) > max_plane_step[comp->plane]) { - max_plane_step [comp->plane] = comp->step_minus1+1; - max_plane_step_comp[comp->plane] = i; - } - } - - for (i = 0; i < 4; i++) { - int s = (max_plane_step_comp[i] == 1 || max_plane_step_comp[i] == 2) ? desc->log2_chroma_w : 0; - picture->linesize[i] = max_plane_step[i] * (((width + (1 << s) - 1)) >> s); - } - - return 0; -} - -int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, - int height) -{ - int size, h2, size2; - const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; - - size = picture->linesize[0] * 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_YUV440P: - case PIX_FMT_YUVJ420P: - case PIX_FMT_YUVJ422P: - case PIX_FMT_YUVJ444P: - case PIX_FMT_YUVJ440P: - case PIX_FMT_YUV420P16LE: - case PIX_FMT_YUV422P16LE: - case PIX_FMT_YUV444P16LE: - case PIX_FMT_YUV420P16BE: - case PIX_FMT_YUV422P16BE: - case PIX_FMT_YUV444P16BE: - h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h; - size2 = picture->linesize[1] * h2; - picture->data[0] = ptr; - picture->data[1] = picture->data[0] + size; - picture->data[2] = picture->data[1] + size2; - picture->data[3] = NULL; - return size + 2 * size2; - case PIX_FMT_YUVA420P: - h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h; - size2 = picture->linesize[1] * h2; - picture->data[0] = ptr; - picture->data[1] = picture->data[0] + size; - picture->data[2] = picture->data[1] + size2; - picture->data[3] = picture->data[1] + size2 + size2; - return 2 * size + 2 * size2; - case PIX_FMT_NV12: - case PIX_FMT_NV21: - h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h; - size2 = picture->linesize[1] * h2; - picture->data[0] = ptr; - picture->data[1] = picture->data[0] + size; - picture->data[2] = NULL; - picture->data[3] = NULL; - return size + size2; - case PIX_FMT_RGB24: - case PIX_FMT_BGR24: - case PIX_FMT_ARGB: - case PIX_FMT_ABGR: - case PIX_FMT_RGBA: - case PIX_FMT_BGRA: - case PIX_FMT_RGB48BE: - case PIX_FMT_RGB48LE: - case PIX_FMT_GRAY16BE: - case PIX_FMT_GRAY16LE: - case PIX_FMT_BGR444BE: - case PIX_FMT_BGR444LE: - case PIX_FMT_BGR555BE: - case PIX_FMT_BGR555LE: - case PIX_FMT_BGR565BE: - case PIX_FMT_BGR565LE: - case PIX_FMT_RGB444BE: - case PIX_FMT_RGB444LE: - case PIX_FMT_RGB555BE: - case PIX_FMT_RGB555LE: - case PIX_FMT_RGB565BE: - case PIX_FMT_RGB565LE: - case PIX_FMT_YUYV422: - case PIX_FMT_UYVY422: - case PIX_FMT_UYYVYY411: - case PIX_FMT_RGB4: - case PIX_FMT_BGR4: - case PIX_FMT_MONOWHITE: - case PIX_FMT_MONOBLACK: - case PIX_FMT_Y400A: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->data[3] = NULL; - return size; - case PIX_FMT_PAL8: - case PIX_FMT_RGB8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB4_BYTE: - case PIX_FMT_BGR4_BYTE: - case PIX_FMT_GRAY8: - 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->data[3] = NULL; - return size2 + 256 * 4; - default: - picture->data[0] = NULL; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->data[3] = NULL; - return -1; - } -} - -int avpicture_fill(AVPicture *picture, uint8_t *ptr, - enum PixelFormat pix_fmt, int width, int height) -{ - - if(avcodec_check_dimensions(NULL, width, height)) - return -1; - - if (ff_fill_linesize(picture, pix_fmt, width)) - return -1; - - return ff_fill_pointer(picture, ptr, pix_fmt, height); -} - -int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, - unsigned char *dest, int dest_size) -{ - const PixFmtInfo* pf = &pix_fmt_info[pix_fmt]; - const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; - int i, j, w, ow, h, oh, 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_YUYV422 || - pix_fmt == PIX_FMT_UYVY422 || - pix_fmt == PIX_FMT_BGR565BE || - pix_fmt == PIX_FMT_BGR565LE || - pix_fmt == PIX_FMT_BGR555BE || - pix_fmt == PIX_FMT_BGR555LE || - pix_fmt == PIX_FMT_BGR444BE || - pix_fmt == PIX_FMT_BGR444LE || - pix_fmt == PIX_FMT_RGB565BE || - pix_fmt == PIX_FMT_RGB565LE || - pix_fmt == PIX_FMT_RGB555BE || - pix_fmt == PIX_FMT_RGB555LE || - pix_fmt == PIX_FMT_RGB444BE || - pix_fmt == PIX_FMT_RGB444LE) - w = width * 2; - else if (pix_fmt == PIX_FMT_UYYVYY411) - 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; - } - - ow = w; - oh = h; - - for (i=0; i> desc->log2_chroma_w) * pf->depth + 7) / 8; - h = -((-height) >> desc->log2_chroma_h); - if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21) - w <<= 1; - } else if (i == 3) { - w = ow; - h = oh; - } - 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(enum PixelFormat pix_fmt, int width, int height) -{ - AVPicture dummy_pict; - if(avcodec_check_dimensions(NULL, width, height)) - return -1; - switch (pix_fmt) { - case PIX_FMT_RGB8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB4_BYTE: - case PIX_FMT_BGR4_BYTE: - case PIX_FMT_GRAY8: - // do not include palette for these pseudo-paletted formats - return width * height; - } - return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); -} - -int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, - int has_alpha) -{ - const PixFmtInfo *pf, *ps; - const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt]; - const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt]; - int loss; - - ps = &pix_fmt_info[src_pix_fmt]; - - /* compute loss */ - loss = 0; - pf = &pix_fmt_info[dst_pix_fmt]; - if (pf->depth < ps->depth || - ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE || - dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) && - (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE || - src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE))) - loss |= FF_LOSS_DEPTH; - if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w || - dst_desc->log2_chroma_h > src_desc->log2_chroma_h) - 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(enum PixelFormat pix_fmt) -{ - int bits; - const PixFmtInfo *pf; - const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; - - pf = &pix_fmt_info[pix_fmt]; - switch(pf->pixel_type) { - case FF_PIXEL_PACKED: - switch(pix_fmt) { - case PIX_FMT_YUYV422: - case PIX_FMT_UYVY422: - case PIX_FMT_RGB565BE: - case PIX_FMT_RGB565LE: - case PIX_FMT_RGB555BE: - case PIX_FMT_RGB555LE: - case PIX_FMT_RGB444BE: - case PIX_FMT_RGB444LE: - case PIX_FMT_BGR565BE: - case PIX_FMT_BGR565LE: - case PIX_FMT_BGR555BE: - case PIX_FMT_BGR555LE: - case PIX_FMT_BGR444BE: - case PIX_FMT_BGR444LE: - bits = 16; - break; - case PIX_FMT_UYYVYY411: - bits = 12; - break; - default: - bits = pf->depth * pf->nb_channels; - break; - } - break; - case FF_PIXEL_PLANAR: - if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) { - bits = pf->depth * pf->nb_channels; - } else { - bits = pf->depth + ((2 * pf->depth) >> - (desc->log2_chroma_w + desc->log2_chroma_h)); - } - break; - case FF_PIXEL_PALETTE: - bits = 8; - break; - default: - bits = -1; - break; - } - return bits; -} - -static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask, - enum PixelFormat src_pix_fmt, - int has_alpha, - int loss_mask) -{ - int dist, i, loss, min_dist; - enum PixelFormat dst_pix_fmt; - - /* find exact color match with smallest size */ - dst_pix_fmt = PIX_FMT_NONE; - min_dist = 0x7fffffff; - for(i = 0;i < PIX_FMT_NB; i++) { - if (pix_fmt_mask & (1ULL << 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; -} - -enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, - int has_alpha, int *loss_ptr) -{ - enum PixelFormat dst_pix_fmt; - int 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 PIX_FMT_NONE; - 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; - } -} - -int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane) -{ - int bits; - const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; - const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; - - pf = &pix_fmt_info[pix_fmt]; - switch(pf->pixel_type) { - case FF_PIXEL_PACKED: - switch(pix_fmt) { - case PIX_FMT_YUYV422: - case PIX_FMT_UYVY422: - case PIX_FMT_RGB565BE: - case PIX_FMT_RGB565LE: - case PIX_FMT_RGB555BE: - case PIX_FMT_RGB555LE: - case PIX_FMT_RGB444BE: - case PIX_FMT_RGB444LE: - case PIX_FMT_BGR565BE: - case PIX_FMT_BGR565LE: - case PIX_FMT_BGR555BE: - case PIX_FMT_BGR555LE: - case PIX_FMT_BGR444BE: - case PIX_FMT_BGR444LE: - bits = 16; - break; - case PIX_FMT_UYYVYY411: - bits = 12; - break; - default: - bits = pf->depth * pf->nb_channels; - break; - } - return (width * bits + 7) >> 3; - break; - case FF_PIXEL_PLANAR: - if (plane == 1 || plane == 2) - width= -((-width)>>desc->log2_chroma_w); - - return (width * pf->depth + 7) >> 3; - break; - case FF_PIXEL_PALETTE: - if (plane == 0) - return width; - break; - } - - return -1; -} - -void av_picture_copy(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height) -{ - int i; - const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; - const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; - - switch(pf->pixel_type) { - case FF_PIXEL_PACKED: - case FF_PIXEL_PLANAR: - for(i = 0; i < pf->nb_channels; i++) { - int h; - int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i); - h = height; - if (i == 1 || i == 2) { - h= -((-height)>>desc->log2_chroma_h); - } - 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 */ - memcpy(dst->data[1], src->data[1], 4*256); - break; - } -} - -/* 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; - } -} - - -int avpicture_alloc(AVPicture *picture, - enum PixelFormat pix_fmt, int width, int height) -{ - int size; - void *ptr; - - size = avpicture_fill(picture, NULL, 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); - if(picture->data[1] && !picture->data[2]) - ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt); - - 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(const PixFmtInfo *ps) -{ - return (ps->color_type == FF_COLOR_YUV || - ps->color_type == FF_COLOR_YUV_JPEG) && - ps->pixel_type == FF_PIXEL_PLANAR; -} - -int av_picture_crop(AVPicture *dst, const AVPicture *src, - enum PixelFormat 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 = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h; - x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w; - - 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; -} - -int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, - enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright, - int *color) -{ - uint8_t *optr; - 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 ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0; - y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0; - - if (padtop || padleft) { - memset(dst->data[i], color[i], - dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift)); - } - - if (padleft || padright) { - 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); - optr += dst->linesize[i]; - } - } - - if (src) { /* first line */ - uint8_t *iptr = src->data[i]; - optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + - (padleft >> x_shift); - memcpy(optr, iptr, (width - padleft - padright) >> x_shift); - 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); - memcpy(optr + ((padleft + padright) >> x_shift), iptr, - (width - padleft - padright) >> x_shift); - 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; -} - -/* 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; -} - -int img_get_alpha_info(const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height) -{ - const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; - int ret; - - /* no alpha can be represented in format */ - if (!pf->is_alpha) - return 0; - switch(pix_fmt) { - 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; -} - -#if 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) -{ -#if !HAVE_MMX - uint8_t *cm = ff_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 - - { - pxor_r2r(mm7,mm7); - movq_m2r(ff_pw_4,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) -{ -#if !HAVE_MMX - uint8_t *cm = ff_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 - - { - pxor_r2r(mm7,mm7); - movq_m2r(ff_pw_4,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); -} - -int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, - enum PixelFormat 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 && - pix_fmt != PIX_FMT_GRAY8) - 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 (pix_fmt == PIX_FMT_GRAY8) { - 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); - } - } - emms_c(); - return 0; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/imgconvert.h b/tizen/distrib/ffmpeg/libavcodec/imgconvert.h deleted file mode 100644 index 48e2f12..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/imgconvert.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Misc image conversion routines - * most functionality is exported to the public API, see avcodec.h - * - * Copyright (c) 2008 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_IMGCONVERT_H -#define AVCODEC_IMGCONVERT_H - -#include -#include "avcodec.h" - -int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width); - -int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt, int height); - -int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane); - -int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt); - -#endif /* AVCODEC_IMGCONVERT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/imx_dump_header_bsf.c b/tizen/distrib/ffmpeg/libavcodec/imx_dump_header_bsf.c deleted file mode 100644 index 2310185..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/imx_dump_header_bsf.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * imx dump header bitstream filter - * Copyright (c) 2007 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * imx dump header bitstream filter - * modifies bitstream to fit in mov and be decoded by final cut pro decoder - */ - -#include "avcodec.h" -#include "bytestream.h" - - -static int imx_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe) -{ - /* MXF essence element key */ - static const uint8_t imx_header[16] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }; - uint8_t *poutbufp; - - if (avctx->codec_id != CODEC_ID_MPEG2VIDEO) { - av_log(avctx, AV_LOG_ERROR, "imx bitstream filter only applies to mpeg2video codec\n"); - return 0; - } - - *poutbuf = av_malloc(buf_size + 20 + FF_INPUT_BUFFER_PADDING_SIZE); - poutbufp = *poutbuf; - bytestream_put_buffer(&poutbufp, imx_header, 16); - bytestream_put_byte(&poutbufp, 0x83); /* KLV BER long form */ - bytestream_put_be24(&poutbufp, buf_size); - bytestream_put_buffer(&poutbufp, buf, buf_size); - *poutbuf_size = poutbufp - *poutbuf; - return 1; -} - -AVBitStreamFilter imx_dump_header_bsf = { - "imxdump", - 0, - imx_dump_header, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/indeo2.c b/tizen/distrib/ffmpeg/libavcodec/indeo2.c deleted file mode 100644 index a3d6c80..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/indeo2.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Intel Indeo 2 codec - * Copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Intel Indeo 2 decoder. - */ -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "get_bits.h" -#include "indeo2data.h" -#include "libavutil/common.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= av_clip_uint8(t); - dst[out] = t; - out++; - t = dst[out - stride] + (table[(c * 2) + 1] - 128); - t= av_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= av_clip_uint8(t); - dst[out] = t; - out++; - t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2); - t= av_clip_uint8(t); - dst[out] = t; - out++; - } - } - dst += stride; - } - return 0; -} - -static int ir2_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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] = av_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 av_cold int ir2_decode_init(AVCodecContext *avctx){ - Ir2Context * const ic = avctx->priv_data; - static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2]; - - ic->avctx = avctx; - - avctx->pix_fmt= PIX_FMT_YUV410P; - - ir2_vlc.table = vlc_tables; - ir2_vlc.table_allocated = 1 << CODE_VLC_BITS; -#ifdef ALT_BITSTREAM_READER_LE - init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, - &ir2_codes[0][1], 4, 2, - &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); -#else - init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, - &ir2_codes[0][1], 4, 2, - &ir2_codes[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); -#endif - - return 0; -} - -static av_cold int ir2_decode_end(AVCodecContext *avctx){ - Ir2Context * const ic = avctx->priv_data; - AVFrame *pic = &ic->picture; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - -AVCodec indeo2_decoder = { - "indeo2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_INDEO2, - sizeof(Ir2Context), - ir2_decode_init, - NULL, - ir2_decode_end, - ir2_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/indeo2data.h b/tizen/distrib/ffmpeg/libavcodec/indeo2data.h deleted file mode 100644 index b2e0b8a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/indeo2data.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Intel Indeo 2 codec - * copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_INDEO2DATA_H -#define AVCODEC_INDEO2DATA_H - -#include - -#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 -}; - -#endif /* AVCODEC_INDEO2DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/indeo3.c b/tizen/distrib/ffmpeg/libavcodec/indeo3.c deleted file mode 100644 index e5df32c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/indeo3.c +++ /dev/null @@ -1,1151 +0,0 @@ -/* - * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg - * written, produced, and directed by Alan Smithee - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "bytestream.h" - -#include "indeo3data.h" - -typedef struct -{ - uint8_t *Ybuf; - uint8_t *Ubuf; - uint8_t *Vbuf; - unsigned short y_w, y_h; - unsigned short uv_w, uv_h; -} YUVBufs; - -typedef struct Indeo3DecodeContext { - AVCodecContext *avctx; - int width, height; - AVFrame frame; - - uint8_t *buf; - YUVBufs iv_frame[2]; - YUVBufs *cur_frame; - YUVBufs *ref_frame; - - uint8_t *ModPred; - uint8_t *corrector_type; -} Indeo3DecodeContext; - -static const uint8_t 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 const uint8_t corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 }; - -static av_cold int build_modpred(Indeo3DecodeContext *s) -{ - int i, j; - - if (!(s->ModPred = av_malloc(8 * 128))) - return AVERROR(ENOMEM); - - 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)); - } - - if (!(s->corrector_type = av_malloc(24 * 256))) - return AVERROR(ENOMEM); - - 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]; - } - } - - return 0; -} - -static av_cold int iv_alloc_frames(Indeo3DecodeContext *s) -{ - int luma_width = (s->width + 3) & ~3, - luma_height = (s->height + 3) & ~3, - 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, - i; - unsigned int bufsize = luma_pixels * 2 + luma_width * 3 + - (chroma_pixels + chroma_width) * 4; - - av_freep(&s->buf); - if(!(s->buf = av_malloc(bufsize))) - return AVERROR(ENOMEM); - 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].Ybuf = s->buf + luma_width; - i = luma_pixels + luma_width * 2; - s->iv_frame[1].Ybuf = s->buf + i; - i += (luma_pixels + luma_width); - s->iv_frame[0].Ubuf = s->buf + i; - i += (chroma_pixels + chroma_width); - s->iv_frame[1].Ubuf = s->buf + i; - i += (chroma_pixels + chroma_width); - s->iv_frame[0].Vbuf = s->buf + i; - i += (chroma_pixels + chroma_width); - s->iv_frame[1].Vbuf = s->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; - } - - return 0; -} - -static av_cold void iv_free_func(Indeo3DecodeContext *s) -{ - av_freep(&s->buf); - av_freep(&s->ModPred); - av_freep(&s->corrector_type); -} - -struct ustr { - long xpos; - long ypos; - long width; - long height; - long split_flag; - long split_direction; - long usl7; -}; - - -#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, - uint8_t *cur, uint8_t *ref, int width, int height, - const uint8_t *buf1, long cb_offset, const uint8_t *hdr, - const uint8_t *buf2, int min_width_160) -{ - uint8_t bit_buf; - unsigned long bit_pos, lv, lv1, lv2; - long *width_tbl, width_tbl_arr[10]; - const signed char *ref_vectors; - uint8_t *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]; - uint8_t *correction_type_sp[2]; - struct ustr 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++; - if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) { - av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n"); - break; - } - memcpy(strip, strip-1, sizeof(*strip)); - 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++; - if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) { - av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n"); - break; - } - memcpy(strip, strip-1, sizeof(*strip)); - 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 = (const signed char*)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 + cb_offset; - - 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) + cb_offset; - correction_type_sp[0] = s->corrector_type + (lv << 8); - correction_lp[0] = correction + (lv << 8); - lv = (hdr[j] >> 4) + cb_offset; - 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) { -#if HAVE_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; - } - } - - 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 av_cold int indeo3_decode_init(AVCodecContext *avctx) -{ - Indeo3DecodeContext *s = avctx->priv_data; - int ret = 0; - - s->avctx = avctx; - s->width = avctx->width; - s->height = avctx->height; - avctx->pix_fmt = PIX_FMT_YUV410P; - - if (!(ret = build_modpred(s))) - ret = iv_alloc_frames(s); - if (ret) - iv_free_func(s); - - return ret; -} - -static int iv_decode_frame(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - Indeo3DecodeContext *s = avctx->priv_data; - unsigned int image_width, image_height, - chroma_width, chroma_height; - unsigned long flags, cb_offset, data_size, - y_offset, v_offset, u_offset, mc_vector_count; - const uint8_t *hdr_pos, *buf_pos; - - buf_pos = buf; - buf_pos += 18; /* skip OS header (16 bytes) and version number */ - - flags = bytestream_get_le16(&buf_pos); - data_size = bytestream_get_le32(&buf_pos); - cb_offset = *buf_pos++; - buf_pos += 3; /* skip reserved byte and checksum */ - image_height = bytestream_get_le16(&buf_pos); - image_width = bytestream_get_le16(&buf_pos); - - if(avcodec_check_dimensions(avctx, image_width, image_height)) - return -1; - if (image_width != avctx->width || image_height != avctx->height) { - int ret; - avcodec_set_dimensions(avctx, image_width, image_height); - s->width = avctx->width; - s->height = avctx->height; - ret = iv_alloc_frames(s); - if (ret < 0) { - s->width = s->height = 0; - return ret; - } - } - - chroma_height = ((image_height >> 2) + 3) & 0x7ffc; - chroma_width = ((image_width >> 2) + 3) & 0x7ffc; - y_offset = bytestream_get_le32(&buf_pos); - v_offset = bytestream_get_le32(&buf_pos); - u_offset = bytestream_get_le32(&buf_pos); - buf_pos += 4; /* reserved */ - hdr_pos = buf_pos; - if(data_size == 0x80) return 4; - - if(FFMAX3(y_offset, v_offset, u_offset) >= buf_size-16) { - av_log(s->avctx, AV_LOG_ERROR, "y/u/v offset outside buffer\n"); - return -1; - } - - if(flags & 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 + y_offset; - mc_vector_count = bytestream_get_le32(&buf_pos); - if(2LL*mc_vector_count >= buf_size-16-y_offset) { - av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n"); - return -1; - } - - iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width, - image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, - FFMIN(image_width, 160)); - - if (!(s->avctx->flags & CODEC_FLAG_GRAY)) - { - - buf_pos = buf + 16 + v_offset; - mc_vector_count = bytestream_get_le32(&buf_pos); - if(2LL*mc_vector_count >= buf_size-16-v_offset) { - av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n"); - return -1; - } - - iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width, - chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, - FFMIN(chroma_width, 40)); - - buf_pos = buf + 16 + u_offset; - mc_vector_count = bytestream_get_le32(&buf_pos); - if(2LL*mc_vector_count >= buf_size-16-u_offset) { - av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n"); - return -1; - } - - iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width, - chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos, - FFMIN(chroma_width, 40)); - - } - - return 8; -} - -static int indeo3_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - Indeo3DecodeContext *s=avctx->priv_data; - uint8_t *src, *dest; - int y; - - if (iv_decode_frame(avctx, buf, buf_size) < 0) - return -1; - - 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 av_cold int indeo3_decode_end(AVCodecContext *avctx) -{ - Indeo3DecodeContext *s = avctx->priv_data; - - iv_free_func(s); - - return 0; -} - -AVCodec indeo3_decoder = { - "indeo3", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_INDEO3, - sizeof(Indeo3DecodeContext), - indeo3_decode_init, - NULL, - indeo3_decode_end, - indeo3_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/indeo3data.h b/tizen/distrib/ffmpeg/libavcodec/indeo3data.h deleted file mode 100644 index bbc4c95..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/indeo3data.h +++ /dev/null @@ -1,2342 +0,0 @@ -/* - * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg - * written, produced, and directed by Alan Smithee - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_INDEO3DATA_H -#define AVCODEC_INDEO3DATA_H - -#include - -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 -}; - -#endif /* AVCODEC_INDEO3DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/indeo5.c b/tizen/distrib/ffmpeg/libavcodec/indeo5.c deleted file mode 100644 index 2593e55..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/indeo5.c +++ /dev/null @@ -1,827 +0,0 @@ -/* - * Indeo Video Interactive v5 compatible decoder - * Copyright (c) 2009 Maxim Poliakovski - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Indeo Video Interactive version 5 decoder - * - * Indeo5 data is usually transported within .avi or .mov files. - * Known FOURCCs: 'IV50' - */ - -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "ivi_dsp.h" -#include "ivi_common.h" -#include "indeo5data.h" - -/** - * Indeo5 frame types. - */ -enum { - FRAMETYPE_INTRA = 0, - FRAMETYPE_INTER = 1, ///< non-droppable P-frame - FRAMETYPE_INTER_SCAL = 2, ///< droppable P-frame used in the scalability mode - FRAMETYPE_INTER_NOREF = 3, ///< droppable P-frame - FRAMETYPE_NULL = 4 ///< empty frame with no data -}; - -#define IVI5_PIC_SIZE_ESC 15 - -#define IVI5_IS_PROTECTED 0x20 - -typedef struct { - GetBitContext gb; - AVFrame frame; - RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables - IVIPlaneDesc planes[3]; ///< color planes - const uint8_t *frame_data; ///< input frame data pointer - int buf_switch; ///< used to switch between three buffers - int inter_scal; ///< signals a sequence of scalable inter frames - int dst_buf; ///< buffer index for the currently decoded frame - int ref_buf; ///< inter frame reference buffer index - int ref2_buf; ///< temporal storage for switching buffers - uint32_t frame_size; ///< frame size in bytes - int frame_type; - int prev_frame_type; ///< frame type of the previous frame - int frame_num; - uint32_t pic_hdr_size; ///< picture header size in bytes - uint8_t frame_flags; - uint16_t checksum; ///< frame checksum - - IVIHuffTab mb_vlc; ///< vlc table for decoding macroblock data - - uint16_t gop_hdr_size; - uint8_t gop_flags; - int is_scalable; - uint32_t lock_word; - IVIPicConfig pic_conf; -} IVI5DecContext; - - -/** - * Decodes Indeo5 GOP (Group of pictures) header. - * This header is present in key frames only. - * It defines parameters for all frames in a GOP. - * - * @param ctx [in,out] ptr to the decoder context - * @param avctx [in] ptr to the AVCodecContext - * @return result code: 0 = OK, -1 = error - */ -static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) -{ - int result, i, p, tile_size, pic_size_indx, mb_size, blk_size, blk_size_changed = 0; - IVIBandDesc *band, *band1, *band2; - IVIPicConfig pic_conf; - - ctx->gop_flags = get_bits(&ctx->gb, 8); - - ctx->gop_hdr_size = (ctx->gop_flags & 1) ? get_bits(&ctx->gb, 16) : 0; - - if (ctx->gop_flags & IVI5_IS_PROTECTED) - ctx->lock_word = get_bits_long(&ctx->gb, 32); - - tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0; - if (tile_size > 256) { - av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size); - return -1; - } - - /* decode number of wavelet bands */ - /* num_levels * 3 + 1 */ - pic_conf.luma_bands = get_bits(&ctx->gb, 2) * 3 + 1; - pic_conf.chroma_bands = get_bits1(&ctx->gb) * 3 + 1; - ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1; - if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { - av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", - pic_conf.luma_bands, pic_conf.chroma_bands); - return -1; - } - - pic_size_indx = get_bits(&ctx->gb, 4); - if (pic_size_indx == IVI5_PIC_SIZE_ESC) { - pic_conf.pic_height = get_bits(&ctx->gb, 13); - pic_conf.pic_width = get_bits(&ctx->gb, 13); - } else { - pic_conf.pic_height = ivi5_common_pic_sizes[pic_size_indx * 2 + 1] << 2; - pic_conf.pic_width = ivi5_common_pic_sizes[pic_size_indx * 2 ] << 2; - } - - if (ctx->gop_flags & 2) { - av_log(avctx, AV_LOG_ERROR, "YV12 picture format not supported!\n"); - return -1; - } - - pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2; - pic_conf.chroma_width = (pic_conf.pic_width + 3) >> 2; - - if (!tile_size) { - pic_conf.tile_height = pic_conf.pic_height; - pic_conf.tile_width = pic_conf.pic_width; - } else { - pic_conf.tile_height = pic_conf.tile_width = tile_size; - } - - /* check if picture layout was changed and reallocate buffers */ - if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { - result = ff_ivi_init_planes(ctx->planes, &pic_conf); - if (result) { - av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); - return -1; - } - ctx->pic_conf = pic_conf; - blk_size_changed = 1; /* force reallocation of the internal structures */ - } - - for (p = 0; p <= 1; p++) { - for (i = 0; i < (!p ? pic_conf.luma_bands : pic_conf.chroma_bands); i++) { - band = &ctx->planes[p].bands[i]; - - band->is_halfpel = get_bits1(&ctx->gb); - - mb_size = get_bits1(&ctx->gb); - blk_size = 8 >> get_bits1(&ctx->gb); - mb_size = blk_size << !mb_size; - - blk_size_changed = mb_size != band->mb_size || blk_size != band->blk_size; - if (blk_size_changed) { - band->mb_size = mb_size; - band->blk_size = blk_size; - } - - if (get_bits1(&ctx->gb)) { - av_log(avctx, AV_LOG_ERROR, "Extended transform info encountered!\n"); - return -1; - } - - /* select transform function and scan pattern according to plane and band number */ - switch ((p << 2) + i) { - case 0: - band->inv_transform = ff_ivi_inverse_slant_8x8; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ff_zigzag_direct; - break; - - case 1: - band->inv_transform = ff_ivi_row_slant8; - band->dc_transform = ff_ivi_dc_row_slant; - band->scan = ivi5_scans8x8[0]; - break; - - case 2: - band->inv_transform = ff_ivi_col_slant8; - band->dc_transform = ff_ivi_dc_col_slant; - band->scan = ivi5_scans8x8[1]; - break; - - case 3: - band->inv_transform = ff_ivi_put_pixels_8x8; - band->dc_transform = ff_ivi_put_dc_pixel_8x8; - band->scan = ivi5_scans8x8[1]; - break; - - case 4: - band->inv_transform = ff_ivi_inverse_slant_4x4; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ivi5_scan4x4; - break; - } - - band->is_2d_trans = band->inv_transform == ff_ivi_inverse_slant_8x8 || - band->inv_transform == ff_ivi_inverse_slant_4x4; - - /* select dequant matrix according to plane and band number */ - if (!p) { - band->quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0; - } else { - band->quant_mat = 5; - } - - if (get_bits(&ctx->gb, 2)) { - av_log(avctx, AV_LOG_ERROR, "End marker missing!\n"); - return -1; - } - } - } - - /* copy chroma parameters into the 2nd chroma plane */ - for (i = 0; i < pic_conf.chroma_bands; i++) { - band1 = &ctx->planes[1].bands[i]; - band2 = &ctx->planes[2].bands[i]; - - band2->width = band1->width; - band2->height = band1->height; - band2->mb_size = band1->mb_size; - band2->blk_size = band1->blk_size; - band2->is_halfpel = band1->is_halfpel; - band2->quant_mat = band1->quant_mat; - band2->scan = band1->scan; - band2->inv_transform = band1->inv_transform; - band2->dc_transform = band1->dc_transform; - band2->is_2d_trans = band1->is_2d_trans; - } - - /* reallocate internal structures if needed */ - if (blk_size_changed) { - result = ff_ivi_init_tiles(ctx->planes, pic_conf.tile_width, - pic_conf.tile_height); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Couldn't reallocate internal structures!\n"); - return -1; - } - } - - if (ctx->gop_flags & 8) { - if (get_bits(&ctx->gb, 3)) { - av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n"); - return -1; - } - - if (get_bits1(&ctx->gb)) - skip_bits_long(&ctx->gb, 24); /* skip transparency fill color */ - } - - align_get_bits(&ctx->gb); - - skip_bits(&ctx->gb, 23); /* FIXME: unknown meaning */ - - /* skip GOP extension if any */ - if (get_bits1(&ctx->gb)) { - do { - i = get_bits(&ctx->gb, 16); - } while (i & 0x8000); - } - - align_get_bits(&ctx->gb); - - return 0; -} - - -/** - * Skips a header extension. - * - * @param gb [in,out] the GetBit context - */ -static inline void skip_hdr_extension(GetBitContext *gb) -{ - int i, len; - - do { - len = get_bits(gb, 8); - for (i = 0; i < len; i++) skip_bits(gb, 8); - } while(len); -} - - -/** - * Decodes Indeo5 picture header. - * - * @param ctx [in,out] ptr to the decoder context - * @param avctx [in] ptr to the AVCodecContext - * @return result code: 0 = OK, -1 = error - */ -static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx) -{ - if (get_bits(&ctx->gb, 5) != 0x1F) { - av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); - return -1; - } - - ctx->prev_frame_type = ctx->frame_type; - ctx->frame_type = get_bits(&ctx->gb, 3); - if (ctx->frame_type >= 5) { - av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type); - return -1; - } - - ctx->frame_num = get_bits(&ctx->gb, 8); - - if (ctx->frame_type == FRAMETYPE_INTRA) { - if (decode_gop_header(ctx, avctx)) - return -1; - } - - if (ctx->frame_type != FRAMETYPE_NULL) { - ctx->frame_flags = get_bits(&ctx->gb, 8); - - ctx->pic_hdr_size = (ctx->frame_flags & 1) ? get_bits_long(&ctx->gb, 24) : 0; - - ctx->checksum = (ctx->frame_flags & 0x10) ? get_bits(&ctx->gb, 16) : 0; - - /* skip unknown extension if any */ - if (ctx->frame_flags & 0x20) - skip_hdr_extension(&ctx->gb); /* XXX: untested */ - - /* decode macroblock huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, IVI_MB_HUFF, &ctx->mb_vlc, avctx)) - return -1; - - skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */ - } - - align_get_bits(&ctx->gb); - - return 0; -} - - -/** - * Decodes Indeo5 band header. - * - * @param ctx [in,out] ptr to the decoder context - * @param band [in,out] ptr to the band descriptor - * @param avctx [in] ptr to the AVCodecContext - * @return result code: 0 = OK, -1 = error - */ -static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, - AVCodecContext *avctx) -{ - int i; - uint8_t band_flags; - - band_flags = get_bits(&ctx->gb, 8); - - if (band_flags & 1) { - band->is_empty = 1; - return 0; - } - - band->data_size = (ctx->frame_flags & 0x80) ? get_bits_long(&ctx->gb, 24) : 0; - - band->inherit_mv = band_flags & 2; - band->inherit_qdelta = band_flags & 8; - band->qdelta_present = band_flags & 4; - if (!band->qdelta_present) band->inherit_qdelta = 1; - - /* decode rvmap probability corrections if any */ - band->num_corr = 0; /* there are no corrections */ - if (band_flags & 0x10) { - band->num_corr = get_bits(&ctx->gb, 8); /* get number of correction pairs */ - if (band->num_corr > 61) { - av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", - band->num_corr); - return -1; - } - - /* read correction pairs */ - for (i = 0; i < band->num_corr * 2; i++) - band->corr[i] = get_bits(&ctx->gb, 8); - } - - /* select appropriate rvmap table for this band */ - band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8; - - /* decode block huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, &band->blk_vlc, avctx)) - return -1; - - band->checksum_present = get_bits1(&ctx->gb); - if (band->checksum_present) - band->checksum = get_bits(&ctx->gb, 16); - - band->glob_quant = get_bits(&ctx->gb, 5); - - /* skip unknown extension if any */ - if (band_flags & 0x20) { /* XXX: untested */ - align_get_bits(&ctx->gb); - skip_hdr_extension(&ctx->gb); - } - - align_get_bits(&ctx->gb); - - return 0; -} - - -/** - * Decodes info (block type, cbp, quant delta, motion vector) - * for all macroblocks in the current tile. - * - * @param ctx [in,out] ptr to the decoder context - * @param band [in,out] ptr to the band descriptor - * @param tile [in,out] ptr to the tile descriptor - * @param avctx [in] ptr to the AVCodecContext - * @return result code: 0 = OK, -1 = error - */ -static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, - IVITile *tile, AVCodecContext *avctx) -{ - int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, - mv_scale, blks_per_mb; - IVIMbInfo *mb, *ref_mb; - int row_offset = band->mb_size * band->pitch; - - mb = tile->mbs; - ref_mb = tile->ref_mbs; - offs = tile->ypos * band->pitch + tile->xpos; - - /* scale factor for motion vectors */ - mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3); - mv_x = mv_y = 0; - - for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) { - mb_offset = offs; - - for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) { - mb->xpos = x; - mb->ypos = y; - mb->buf_offs = mb_offset; - - if (get_bits1(&ctx->gb)) { - if (ctx->frame_type == FRAMETYPE_INTRA) { - av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n"); - return -1; - } - mb->type = 1; /* empty macroblocks are always INTER */ - mb->cbp = 0; /* all blocks are empty */ - - mb->q_delta = 0; - if (!band->plane && !band->band_num && (ctx->frame_flags & 8)) { - mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); - mb->q_delta = IVI_TOSIGNED(mb->q_delta); - } - - mb->mv_x = mb->mv_y = 0; /* no motion vector coded */ - if (band->inherit_mv){ - /* motion vector inheritance */ - if (mv_scale) { - mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); - mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); - } else { - mb->mv_x = ref_mb->mv_x; - mb->mv_y = ref_mb->mv_y; - } - } - } else { - if (band->inherit_mv) { - mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */ - } else if (ctx->frame_type == FRAMETYPE_INTRA) { - mb->type = 0; /* mb_type is always INTRA for intra-frames */ - } else { - mb->type = get_bits1(&ctx->gb); - } - - blks_per_mb = band->mb_size != band->blk_size ? 4 : 1; - mb->cbp = get_bits(&ctx->gb, blks_per_mb); - - mb->q_delta = 0; - if (band->qdelta_present) { - if (band->inherit_qdelta) { - if (ref_mb) mb->q_delta = ref_mb->q_delta; - } else if (mb->cbp || (!band->plane && !band->band_num && - (ctx->frame_flags & 8))) { - mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); - mb->q_delta = IVI_TOSIGNED(mb->q_delta); - } - } - - if (!mb->type) { - mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */ - } else { - if (band->inherit_mv){ - /* motion vector inheritance */ - if (mv_scale) { - mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); - mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); - } else { - mb->mv_x = ref_mb->mv_x; - mb->mv_y = ref_mb->mv_y; - } - } else { - /* decode motion vector deltas */ - mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); - mv_y += IVI_TOSIGNED(mv_delta); - mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, - IVI_VLC_BITS, 1); - mv_x += IVI_TOSIGNED(mv_delta); - mb->mv_x = mv_x; - mb->mv_y = mv_y; - } - } - } - - mb++; - if (ref_mb) - ref_mb++; - mb_offset += band->mb_size; - } - - offs += row_offset; - } - - align_get_bits(&ctx->gb); - - return 0; -} - - -/** - * Decodes an Indeo5 band. - * - * @param ctx [in,out] ptr to the decoder context - * @param band [in,out] ptr to the band descriptor - * @param avctx [in] ptr to the AVCodecContext - * @return result code: 0 = OK, -1 = error - */ -static int decode_band(IVI5DecContext *ctx, int plane_num, - IVIBandDesc *band, AVCodecContext *avctx) -{ - int result, i, t, idx1, idx2, pos; - IVITile *tile; - - band->buf = band->bufs[ctx->dst_buf]; - band->ref_buf = band->bufs[ctx->ref_buf]; - band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3); - - result = decode_band_hdr(ctx, band, avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n", - result); - return -1; - } - - if (band->is_empty) { - av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n"); - return -1; - } - - if (band->blk_size == 8) { - band->intra_base = &ivi5_base_quant_8x8_intra[band->quant_mat][0]; - band->inter_base = &ivi5_base_quant_8x8_inter[band->quant_mat][0]; - band->intra_scale = &ivi5_scale_quant_8x8_intra[band->quant_mat][0]; - band->inter_scale = &ivi5_scale_quant_8x8_inter[band->quant_mat][0]; - } else { - band->intra_base = ivi5_base_quant_4x4_intra; - band->inter_base = ivi5_base_quant_4x4_inter; - band->intra_scale = ivi5_scale_quant_4x4_intra; - band->inter_scale = ivi5_scale_quant_4x4_inter; - } - - band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel]; - - /* apply corrections to the selected rvmap table if present */ - for (i = 0; i < band->num_corr; i++) { - idx1 = band->corr[i*2]; - idx2 = band->corr[i*2+1]; - FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); - FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); - } - - pos = get_bits_count(&ctx->gb); - - for (t = 0; t < band->num_tiles; t++) { - tile = &band->tiles[t]; - - tile->is_empty = get_bits1(&ctx->gb); - if (tile->is_empty) { - ff_ivi_process_empty_tile(avctx, band, tile, - (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); - } else { - tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); - - result = decode_mb_info(ctx, band, tile, avctx); - if (result < 0) - break; - - result = ff_ivi_decode_blocks(&ctx->gb, band, tile); - if (result < 0 || (get_bits_count(&ctx->gb) - pos) >> 3 != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); - break; - } - pos += tile->data_size << 3; // skip to next tile - } - } - - /* restore the selected rvmap table by applying its corrections in reverse order */ - for (i = band->num_corr-1; i >= 0; i--) { - idx1 = band->corr[i*2]; - idx2 = band->corr[i*2+1]; - FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); - FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); - } - -#if IVI_DEBUG - if (band->checksum_present) { - uint16_t chksum = ivi_calc_band_checksum(band); - if (chksum != band->checksum) { - av_log(avctx, AV_LOG_ERROR, - "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n", - band->plane, band->band_num, band->checksum, chksum); - } - } -#endif - - align_get_bits(&ctx->gb); - - return result; -} - - -/** - * Switches buffers. - * - * @param ctx [in,out] ptr to the decoder context - * @param avctx [in] ptr to the AVCodecContext - */ -static void switch_buffers(IVI5DecContext *ctx, AVCodecContext *avctx) -{ - switch (ctx->prev_frame_type) { - case FRAMETYPE_INTRA: - case FRAMETYPE_INTER: - ctx->buf_switch ^= 1; - ctx->dst_buf = ctx->buf_switch; - ctx->ref_buf = ctx->buf_switch ^ 1; - break; - case FRAMETYPE_INTER_SCAL: - if (!ctx->inter_scal) { - ctx->ref2_buf = 2; - ctx->inter_scal = 1; - } - FFSWAP(int, ctx->dst_buf, ctx->ref2_buf); - ctx->ref_buf = ctx->ref2_buf; - break; - case FRAMETYPE_INTER_NOREF: - break; - } - - switch (ctx->frame_type) { - case FRAMETYPE_INTRA: - ctx->buf_switch = 0; - /* FALLTHROUGH */ - case FRAMETYPE_INTER: - ctx->inter_scal = 0; - ctx->dst_buf = ctx->buf_switch; - ctx->ref_buf = ctx->buf_switch ^ 1; - break; - case FRAMETYPE_INTER_SCAL: - case FRAMETYPE_INTER_NOREF: - case FRAMETYPE_NULL: - break; - } -} - - -/** - * Initializes Indeo5 decoder. - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - IVI5DecContext *ctx = avctx->priv_data; - int result; - - ff_ivi_init_static_vlc(); - - /* copy rvmap tables in our context so we can apply changes to them */ - memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs)); - - /* set the initial picture layout according to the basic profile: - there is only one band per plane (no scalability), only one tile (no local decoding) - and picture format = YVU9 */ - ctx->pic_conf.pic_width = avctx->width; - ctx->pic_conf.pic_height = avctx->height; - ctx->pic_conf.chroma_width = (avctx->width + 3) >> 2; - ctx->pic_conf.chroma_height = (avctx->height + 3) >> 2; - ctx->pic_conf.tile_width = avctx->width; - ctx->pic_conf.tile_height = avctx->height; - ctx->pic_conf.luma_bands = ctx->pic_conf.chroma_bands = 1; - - result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf); - if (result) { - av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n"); - return -1; - } - - ctx->buf_switch = 0; - ctx->inter_scal = 0; - - avctx->pix_fmt = PIX_FMT_YUV410P; - - return 0; -} - - -/** - * main decoder function - */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - IVI5DecContext *ctx = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - int result, p, b; - - init_get_bits(&ctx->gb, buf, buf_size * 8); - ctx->frame_data = buf; - ctx->frame_size = buf_size; - - result = decode_pic_hdr(ctx, avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Error while decoding picture header: %d\n", result); - return -1; - } - - if (ctx->gop_flags & IVI5_IS_PROTECTED) { - av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); - return -1; - } - - switch_buffers(ctx, avctx); - - //START_TIMER; - - if (ctx->frame_type != FRAMETYPE_NULL) { - for (p = 0; p < 3; p++) { - for (b = 0; b < ctx->planes[p].num_bands; b++) { - result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Error while decoding band: %d, plane: %d\n", b, p); - return -1; - } - } - } - } - - //STOP_TIMER("decode_planes"); - - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - - ctx->frame.reference = 0; - if (avctx->get_buffer(avctx, &ctx->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if (ctx->is_scalable) { - ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); - } else { - ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); - } - - ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]); - ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = ctx->frame; - - return buf_size; -} - - -/** - * Closes Indeo5 decoder and cleans up its context. - */ -static av_cold int decode_close(AVCodecContext *avctx) -{ - IVI5DecContext *ctx = avctx->priv_data; - - ff_ivi_free_buffers(&ctx->planes[0]); - - if (ctx->mb_vlc.cust_tab.table) - free_vlc(&ctx->mb_vlc.cust_tab); - - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - - return 0; -} - - -AVCodec indeo5_decoder = { - .name = "indeo5", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_INDEO5, - .priv_data_size = sizeof(IVI5DecContext), - .init = decode_init, - .close = decode_close, - .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/indeo5data.h b/tizen/distrib/ffmpeg/libavcodec/indeo5data.h deleted file mode 100644 index 972e598..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/indeo5data.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Indeo Video Interactive 5 compatible decoder - * Copyright (c) 2009 Maxim Poliakovski - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * This file contains data needed for the Indeo5 decoder. - */ - -#ifndef AVCODEC_INDEO5DATA_H -#define AVCODEC_INDEO5DATA_H - -#include - -/** - * standard picture dimensions (width, height divided by 4) - */ -static const uint8_t ivi5_common_pic_sizes[30] = { - 160, 120, 80, 60, 40, 30, 176, 120, 88, 60, 88, 72, 44, 36, 60, 45, 160, 60, - 176, 60, 20, 15, 22, 18, 0, 0, 0, 0, 0, 0 -}; - -/** - * Indeo5 8x8 scan (zigzag) patterns - */ -static const uint8_t ivi5_scans8x8[2][64] = { - {0, 8, 16, 24, 32, 40, 48, 56, 1, 9, 17, 25, 33, 41, 49, 57, - 2, 10, 18, 26, 34, 42, 50, 58, 3, 11, 19, 27, 35, 43, 51, 59, - 4, 12, 20, 28, 36, 44, 52, 60, 5, 13, 21, 29, 37, 45, 53, 61, - 6, 14, 22, 30, 38, 46, 54, 62, 7, 15, 23, 31, 39, 47, 55, 63 - }, - {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 - } -}; - -/** - * Indeo5 4x4 scan (zigzag) pattern - */ -static const uint8_t ivi5_scan4x4[16] = { - 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 -}; - - -/** - * Indeo5 dequantization matrixes consist of two tables: base table - * and scale table. The base table defines the dequantization matrix - * itself and the scale table tells how this matrix should be scaled - * for a particular quant level (0...24). - * - * ivi5_base_quant_bbb_ttt - base tables for block size 'bbb' of type 'ttt' - * ivi5_scale_quant_bbb_ttt - scale tables for block size 'bbb' of type 'ttt' - */ -static const uint8_t ivi5_base_quant_8x8_inter[5][64] = { - {0x13, 0x1d, 0x1f, 0x23, 0x25, 0x27, 0x29, 0x2d, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2b, 0x2f, - 0x1f, 0x21, 0x23, 0x24, 0x26, 0x29, 0x2d, 0x31, 0x23, 0x23, 0x24, 0x25, 0x27, 0x2b, 0x2f, 0x33, - 0x25, 0x25, 0x26, 0x27, 0x29, 0x2d, 0x31, 0x35, 0x27, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x33, 0x37, - 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x39, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b - }, - {0x13, 0x1d, 0x1f, 0x23, 0x25, 0x27, 0x29, 0x2d, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2b, 0x2f, - 0x1f, 0x21, 0x23, 0x24, 0x26, 0x29, 0x2d, 0x31, 0x23, 0x23, 0x24, 0x25, 0x27, 0x2b, 0x2f, 0x33, - 0x25, 0x25, 0x26, 0x27, 0x29, 0x2d, 0x31, 0x35, 0x27, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x33, 0x37, - 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x39, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b - }, - {0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, - 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, - 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, - 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61 - }, - {0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, - 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, - 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61 - }, - {0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f - } -}; - -static const uint8_t ivi5_base_quant_8x8_intra[5][64] = { - {0x0d, 0x17, 0x1b, 0x21, 0x23, 0x25, 0x27, 0x2d, 0x17, 0x19, 0x1f, 0x21, 0x23, 0x27, 0x2b, 0x35, - 0x1b, 0x1f, 0x1f, 0x22, 0x25, 0x2a, 0x33, 0x39, 0x21, 0x21, 0x22, 0x25, 0x29, 0x31, 0x36, 0x3d, - 0x23, 0x23, 0x25, 0x29, 0x2f, 0x33, 0x39, 0x47, 0x25, 0x27, 0x2a, 0x31, 0x33, 0x37, 0x43, 0x53, - 0x27, 0x2b, 0x33, 0x36, 0x39, 0x43, 0x4d, 0x65, 0x2d, 0x35, 0x39, 0x3d, 0x47, 0x53, 0x65, 0x7f - }, - {0x13, 0x1d, 0x1f, 0x23, 0x25, 0x27, 0x29, 0x2d, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2b, 0x2f, - 0x1f, 0x21, 0x23, 0x24, 0x26, 0x29, 0x2d, 0x31, 0x23, 0x23, 0x24, 0x25, 0x27, 0x2b, 0x2f, 0x33, - 0x25, 0x25, 0x26, 0x27, 0x29, 0x2d, 0x31, 0x35, 0x27, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x33, 0x37, - 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x39, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b - }, - {0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, - 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, - 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, - 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61, 0x27, 0x55, 0x79, 0x6a, 0x6f, 0x61, 0x6b, 0x61 - }, - {0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, - 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, - 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61 - }, - {0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f - } -}; - -static const uint8_t ivi5_base_quant_4x4_inter[16] = { - 0x0f, 0x1f, 0x25, 0x29, 0x1f, 0x25, 0x29, 0x2b, 0x25, 0x29, 0x2b, 0x2f, 0x29, 0x2b, 0x2f, 0x33 -}; - -static const uint8_t ivi5_base_quant_4x4_intra[16] = { - 0x0f, 0x1f, 0x25, 0x29, 0x1f, 0x25, 0x29, 0x2f, 0x25, 0x29, 0x2f, 0x3d, 0x29, 0x2f, 0x3d, 0x49 -}; - - -static const uint8_t ivi5_scale_quant_8x8_inter[5][24] = { - {0x0b, 0x11, 0x13, 0x14, 0x15, 0x16, 0x18, 0x1a, 0x1b, 0x1d, 0x20, 0x22, - 0x23, 0x25, 0x28, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x41, 0x44, 0x4a, - }, - {0x07, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x29, 0x2d, 0x31, 0x35, - 0x3a, 0x3f, 0x44, 0x4a, 0x50, 0x56, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x7e, - }, - {0x15, 0x25, 0x28, 0x2d, 0x30, 0x34, 0x3a, 0x3d, 0x42, 0x48, 0x4c, 0x51, - 0x56, 0x5b, 0x60, 0x65, 0x6b, 0x70, 0x76, 0x7c, 0x82, 0x88, 0x8f, 0x97, - }, - {0x13, 0x1f, 0x20, 0x22, 0x25, 0x28, 0x2b, 0x2d, 0x30, 0x33, 0x36, 0x39, - 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4b, 0x4e, 0x52, 0x56, 0x5a, 0x5e, 0x62, - }, - {0x3c, 0x52, 0x58, 0x5d, 0x63, 0x68, 0x68, 0x6d, 0x73, 0x78, 0x7c, 0x80, - 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa3, 0xa9, 0xad, 0xb1, 0xb5, 0xba, - }, -}; - -static const uint8_t ivi5_scale_quant_8x8_intra[5][24] = { - {0x0b, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x1a, 0x1c, 0x1e, 0x20, - 0x22, 0x24, 0x27, 0x28, 0x2a, 0x2d, 0x2f, 0x31, 0x34, 0x37, 0x39, 0x3c, - }, - {0x01, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1b, 0x1e, 0x22, 0x25, 0x28, 0x2c, - 0x30, 0x34, 0x38, 0x3d, 0x42, 0x47, 0x4c, 0x52, 0x58, 0x5e, 0x65, 0x6c, - }, - {0x13, 0x22, 0x27, 0x2a, 0x2d, 0x33, 0x36, 0x3c, 0x41, 0x45, 0x49, 0x4e, - 0x53, 0x58, 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x7c, 0x82, 0x88, 0x8e, 0x95, - }, - {0x13, 0x1f, 0x21, 0x24, 0x27, 0x29, 0x2d, 0x2f, 0x34, 0x37, 0x3a, 0x3d, - 0x40, 0x44, 0x48, 0x4c, 0x4f, 0x52, 0x56, 0x5a, 0x5e, 0x62, 0x66, 0x6b, - }, - {0x31, 0x42, 0x47, 0x47, 0x4d, 0x52, 0x58, 0x58, 0x5d, 0x63, 0x67, 0x6b, - 0x6f, 0x73, 0x78, 0x7c, 0x80, 0x84, 0x89, 0x8e, 0x93, 0x98, 0x9d, 0xa4, - } -}; - -static const uint8_t ivi5_scale_quant_4x4_inter[24] = { - 0x0b, 0x0d, 0x0d, 0x0e, 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, -}; - -static const uint8_t ivi5_scale_quant_4x4_intra[24] = { - 0x01, 0x0b, 0x0b, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 -}; - - -#endif /* AVCODEC_INDEO5DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/intelh263dec.c b/tizen/distrib/ffmpeg/libavcodec/intelh263dec.c deleted file mode 100644 index 5e45129..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/intelh263dec.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * H.263i decoder - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mpegvideo.h" -#include "h263.h" - -/* don't understand why they choose a different header ! */ -int ff_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 = FF_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 */ - } - s->obmc= get_bits1(&s->gb); - s->pb_frame = get_bits1(&s->gb); - - if(format == 7){ - format = get_bits(&s->gb, 3); - if(format == 0 || format == 7){ - av_log(s->avctx, AV_LOG_ERROR, "Wrong Intel H263 format\n"); - return -1; - } - if(get_bits(&s->gb, 2)) - av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n"); - s->loop_filter = get_bits1(&s->gb); - if(get_bits1(&s->gb)) - av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n"); - if(get_bits1(&s->gb)) - s->pb_frame = 2; - if(get_bits(&s->gb, 5)) - av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n"); - if(get_bits(&s->gb, 5) != 1) - av_log(s->avctx, AV_LOG_ERROR, "Invalid marker\n"); - } - if(format == 6){ - int ar = get_bits(&s->gb, 4); - skip_bits(&s->gb, 9); // display width - skip_bits1(&s->gb); - skip_bits(&s->gb, 9); // display height - if(ar == 15){ - skip_bits(&s->gb, 8); // aspect ratio - width - skip_bits(&s->gb, 8); // aspect ratio - height - } - } - - s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); - skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ - - if(s->pb_frame){ - skip_bits(&s->gb, 3); //temporal reference for B-frame - skip_bits(&s->gb, 2); //dbquant - } - - /* 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; - - ff_h263_show_pict_info(s); - - return 0; -} - -AVCodec h263i_decoder = { - "h263i", - AVMEDIA_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, - .long_name = NULL_IF_CONFIG_SMALL("Intel H.263"), - .pix_fmts= ff_pixfmt_list_420, -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/internal.h b/tizen/distrib/ffmpeg/libavcodec/internal.h deleted file mode 100644 index 97c0dcb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/internal.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * common internal api header. - */ - -#ifndef AVCODEC_INTERNAL_H -#define AVCODEC_INTERNAL_H - -#include -#include "avcodec.h" - -/** - * Determines whether pix_fmt is a hardware accelerated format. - */ -int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt); - -/** - * Returns the hardware accelerated codec for codec codec_id and - * pixel format pix_fmt. - * - * @param codec_id the codec to match - * @param pix_fmt the pixel format to match - * @return the hardware accelerated codec, or NULL if none was found. - */ -AVHWAccel *ff_find_hwaccel(enum CodecID codec_id, enum PixelFormat pix_fmt); - -/** - * Return the index into tab at which {a,b} match elements {[0],[1]} of tab. - * If there is no such matching pair then size is returned. - */ -int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b); - -#endif /* AVCODEC_INTERNAL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/interplayvideo.c b/tizen/distrib/ffmpeg/libavcodec/interplayvideo.c deleted file mode 100644 index b98386f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/interplayvideo.c +++ /dev/null @@ -1,1107 +0,0 @@ -/* - * Interplay MVE Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 "avcodec.h" -#include "bytestream.h" -#include "dsputil.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.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; - const unsigned char *decoding_map; - int decoding_map_size; - - const unsigned char *buf; - int size; - - int is_16bpp; - const unsigned char *stream_ptr; - const unsigned char *stream_end; - const uint8_t *mv_ptr; - const uint8_t *mv_end; - unsigned char *pixel_ptr; - int line_inc; - int stride; - int upper_motion_limit_offset; - -} IpvideoContext; - -#define CHECK_STREAM_PTR(stream_ptr, stream_end, n) \ - if (stream_end - stream_ptr < n) { \ - av_log(s->avctx, AV_LOG_ERROR, "Interplay video warning: stream_ptr out of bounds (%p >= %p)\n", \ - stream_ptr + n, stream_end); \ - return -1; \ - } - -static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y) -{ - int current_offset = s->pixel_ptr - s->current_frame.data[0]; - int motion_offset = current_offset + delta_y * s->current_frame.linesize[0] - + delta_x * (1 + s->is_16bpp); - 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[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset, - s->current_frame.linesize[0], 8); - return 0; -} - -static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s) -{ - return copy_from(s, &s->last_frame, 0, 0); -} - -static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s) -{ - return copy_from(s, &s->second_last_frame, 0, 0); -} - -static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s) -{ - unsigned char B; - int x, y; - - /* copy block from 2 frames ago using a motion vector; need 1 more byte */ - if (!s->is_16bpp) { - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); - B = *s->stream_ptr++; - } else { - CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1); - B = *s->mv_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); - return copy_from(s, &s->second_last_frame, x, y); -} - -static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s) -{ - unsigned char B; - int x, y; - - /* copy 8x8 block from current frame from an up/left block */ - - /* need 1 more byte for motion */ - if (!s->is_16bpp) { - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); - B = *s->stream_ptr++; - } else { - CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1); - B = *s->mv_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); - return copy_from(s, &s->current_frame, x, y); -} - -static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s) -{ - int x, y; - unsigned char B, BL, BH; - - /* copy a block from the previous frame; need 1 more byte */ - if (!s->is_16bpp) { - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); - B = *s->stream_ptr++; - } else { - CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1); - B = *s->mv_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); - return copy_from(s, &s->last_frame, x, y); -} - -static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s) -{ - signed char x, y; - - /* copy a block from the previous frame using an expanded range; - * need 2 more bytes */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); - - x = *s->stream_ptr++; - y = *s->stream_ptr++; - - debug_interplay (" motion bytes = %d, %d\n", x, y); - return copy_from(s, &s->last_frame, x, y); -} - -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 P[2]; - unsigned int flags; - - /* 2-color encoding */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); - - P[0] = *s->stream_ptr++; - P[1] = *s->stream_ptr++; - - if (P[0] <= P[1]) { - - /* need 8 more bytes from the stream */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); - - for (y = 0; y < 8; y++) { - flags = *s->stream_ptr++ | 0x100; - for (; flags != 1; flags >>= 1) - *s->pixel_ptr++ = P[flags & 1]; - s->pixel_ptr += s->line_inc; - } - - } else { - - /* need 2 more bytes from the stream */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); - - flags = bytestream_get_le16(&s->stream_ptr); - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, flags >>= 1) { - s->pixel_ptr[x ] = - s->pixel_ptr[x + 1 ] = - s->pixel_ptr[x + s->stride] = - s->pixel_ptr[x + 1 + s->stride] = P[flags & 1]; - } - 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[2]; - unsigned int flags = 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(s->stream_ptr, s->stream_end, 2); - - P[0] = *s->stream_ptr++; - P[1] = *s->stream_ptr++; - - if (P[0] <= P[1]) { - - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 14); - s->stream_ptr -= 2; - - for (y = 0; y < 16; y++) { - // new values for each 4x4 block - if (!(y & 3)) { - P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++; - flags = bytestream_get_le16(&s->stream_ptr); - } - - for (x = 0; x < 4; x++, flags >>= 1) - *s->pixel_ptr++ = P[flags & 1]; - s->pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) s->pixel_ptr -= 8 * s->stride - 4; - } - - } else { - - /* need 10 more bytes */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 10); - - if (s->stream_ptr[4] <= s->stream_ptr[5]) { - - flags = bytestream_get_le32(&s->stream_ptr); - - /* vertical split; left & right halves are 2-color encoded */ - - for (y = 0; y < 16; y++) { - for (x = 0; x < 4; x++, flags >>= 1) - *s->pixel_ptr++ = P[flags & 1]; - s->pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) { - s->pixel_ptr -= 8 * s->stride - 4; - P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++; - flags = bytestream_get_le32(&s->stream_ptr); - } - } - - } else { - - /* horizontal split; top & bottom halves are 2-color encoded */ - - for (y = 0; y < 8; y++) { - if (y == 4) { - P[0] = *s->stream_ptr++; - P[1] = *s->stream_ptr++; - } - flags = *s->stream_ptr++ | 0x100; - - for (; flags != 1; flags >>= 1) - *s->pixel_ptr++ = P[flags & 1]; - 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]; - - /* 4-color encoding */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); - - memcpy(P, s->stream_ptr, 4); - s->stream_ptr += 4; - - if (P[0] <= P[1]) { - if (P[2] <= P[3]) { - - /* 1 of 4 colors for each pixel, need 16 more bytes */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16); - - for (y = 0; y < 8; y++) { - /* get the next set of 8 2-bit flags */ - int flags = bytestream_get_le16(&s->stream_ptr); - for (x = 0; x < 8; x++, flags >>= 2) - *s->pixel_ptr++ = P[flags & 0x03]; - s->pixel_ptr += s->line_inc; - } - - } else { - uint32_t flags; - - /* 1 of 4 colors for each 2x2 block, need 4 more bytes */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); - - flags = bytestream_get_le32(&s->stream_ptr); - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, flags >>= 2) { - s->pixel_ptr[x ] = - s->pixel_ptr[x + 1 ] = - s->pixel_ptr[x + s->stride] = - s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03]; - } - s->pixel_ptr += s->stride * 2; - } - - } - } else { - uint64_t flags; - - /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); - - flags = bytestream_get_le64(&s->stream_ptr); - if (P[2] <= P[3]) { - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x += 2, flags >>= 2) { - s->pixel_ptr[x ] = - s->pixel_ptr[x + 1] = P[flags & 0x03]; - } - s->pixel_ptr += s->stride; - } - } else { - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x++, flags >>= 2) { - s->pixel_ptr[x ] = - s->pixel_ptr[x + s->stride] = P[flags & 0x03]; - } - 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[4]; - int flags = 0; - - /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on - * either top and bottom or left and right halves */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24); - - if (s->stream_ptr[0] <= s->stream_ptr[1]) { - - /* 4-color encoding for each quadrant; need 32 bytes */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 32); - - for (y = 0; y < 16; y++) { - // new values for each 4x4 block - if (!(y & 3)) { - memcpy(P, s->stream_ptr, 4); - s->stream_ptr += 4; - flags = bytestream_get_le32(&s->stream_ptr); - } - - for (x = 0; x < 4; x++, flags >>= 2) - *s->pixel_ptr++ = P[flags & 0x03]; - - s->pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) s->pixel_ptr -= 8 * s->stride - 4; - } - - } else { - // vertical split? - int vert = s->stream_ptr[12] <= s->stream_ptr[13]; - uint64_t flags = 0; - - /* 4-color encoding for either left and right or top and bottom - * halves */ - - for (y = 0; y < 16; y++) { - // load values for each half - if (!(y & 7)) { - memcpy(P, s->stream_ptr, 4); - s->stream_ptr += 4; - flags = bytestream_get_le64(&s->stream_ptr); - } - - for (x = 0; x < 4; x++, flags >>= 2) - *s->pixel_ptr++ = P[flags & 0x03]; - - if (vert) { - s->pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) s->pixel_ptr -= 8 * s->stride - 4; - } else if (y & 1) s->pixel_ptr += s->line_inc; - } - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s) -{ - int y; - - /* 64-color encoding (each pixel in block is a different color) */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 64); - - for (y = 0; y < 8; y++) { - memcpy(s->pixel_ptr, s->stream_ptr, 8); - s->stream_ptr += 8; - s->pixel_ptr += s->stride; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s) -{ - int x, y; - - /* 16-color block encoding: each 2x2 block is a different color */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16); - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2) { - s->pixel_ptr[x ] = - s->pixel_ptr[x + 1 ] = - s->pixel_ptr[x + s->stride] = - s->pixel_ptr[x + 1 + s->stride] = *s->stream_ptr++; - } - s->pixel_ptr += s->stride * 2; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s) -{ - int y; - unsigned char P[2]; - - /* 4-color block encoding: each 4x4 block is a different color */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); - - for (y = 0; y < 8; y++) { - if (!(y & 3)) { - P[0] = *s->stream_ptr++; - P[1] = *s->stream_ptr++; - } - memset(s->pixel_ptr, P[0], 4); - memset(s->pixel_ptr + 4, P[1], 4); - s->pixel_ptr += s->stride; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s) -{ - int y; - unsigned char pix; - - /* 1-color encoding: the whole block is 1 solid color */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); - pix = *s->stream_ptr++; - - for (y = 0; y < 8; y++) { - memset(s->pixel_ptr, pix, 8); - s->pixel_ptr += s->stride; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s) -{ - int x, y; - unsigned char sample[2]; - - /* dithered encoding */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); - sample[0] = *s->stream_ptr++; - sample[1] = *s->stream_ptr++; - - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x += 2) { - *s->pixel_ptr++ = sample[ y & 1 ]; - *s->pixel_ptr++ = sample[!(y & 1)]; - } - s->pixel_ptr += s->line_inc; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s) -{ - signed char x, y; - - /* copy a block from the second last frame using an expanded range */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); - - x = *s->stream_ptr++; - y = *s->stream_ptr++; - - debug_interplay (" motion bytes = %d, %d\n", x, y); - return copy_from(s, &s->second_last_frame, x, y); -} - -static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s) -{ - int x, y; - uint16_t P[2]; - unsigned int flags; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 2-color encoding */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); - - P[0] = bytestream_get_le16(&s->stream_ptr); - P[1] = bytestream_get_le16(&s->stream_ptr); - - if (!(P[0] & 0x8000)) { - - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); - - for (y = 0; y < 8; y++) { - flags = *s->stream_ptr++ | 0x100; - for (; flags != 1; flags >>= 1) - *pixel_ptr++ = P[flags & 1]; - pixel_ptr += s->line_inc; - } - - } else { - - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); - - flags = bytestream_get_le16(&s->stream_ptr); - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, flags >>= 1) { - pixel_ptr[x ] = - pixel_ptr[x + 1 ] = - pixel_ptr[x + s->stride] = - pixel_ptr[x + 1 + s->stride] = P[flags & 1]; - } - pixel_ptr += s->stride * 2; - } - } - - return 0; -} - -static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s) -{ - int x, y; - uint16_t P[2]; - unsigned int flags = 0; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on - * either top and bottom or left and right halves */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); - - P[0] = bytestream_get_le16(&s->stream_ptr); - P[1] = bytestream_get_le16(&s->stream_ptr); - - if (!(P[0] & 0x8000)) { - - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24); - s->stream_ptr -= 4; - - for (y = 0; y < 16; y++) { - // new values for each 4x4 block - if (!(y & 3)) { - P[0] = bytestream_get_le16(&s->stream_ptr); - P[1] = bytestream_get_le16(&s->stream_ptr); - flags = bytestream_get_le16(&s->stream_ptr); - } - - for (x = 0; x < 4; x++, flags >>= 1) - *pixel_ptr++ = P[flags & 1]; - pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) pixel_ptr -= 8 * s->stride - 4; - } - - } else { - - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 12); - - if (!(AV_RL16(s->stream_ptr + 4) & 0x8000)) { - - flags = bytestream_get_le32(&s->stream_ptr); - - /* vertical split; left & right halves are 2-color encoded */ - - for (y = 0; y < 16; y++) { - for (x = 0; x < 4; x++, flags >>= 1) - *pixel_ptr++ = P[flags & 1]; - pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) { - pixel_ptr -= 8 * s->stride - 4; - P[0] = bytestream_get_le16(&s->stream_ptr); - P[1] = bytestream_get_le16(&s->stream_ptr); - flags = bytestream_get_le32(&s->stream_ptr); - } - } - - } else { - - /* horizontal split; top & bottom halves are 2-color encoded */ - - for (y = 0; y < 8; y++) { - if (y == 4) { - P[0] = bytestream_get_le16(&s->stream_ptr); - P[1] = bytestream_get_le16(&s->stream_ptr); - } - flags = *s->stream_ptr++ | 0x100; - - for (; flags != 1; flags >>= 1) - *pixel_ptr++ = P[flags & 1]; - pixel_ptr += s->line_inc; - } - } - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s) -{ - int x, y; - uint16_t P[4]; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 4-color encoding */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); - - for (x = 0; x < 4; x++) - P[x] = bytestream_get_le16(&s->stream_ptr); - - if (!(P[0] & 0x8000)) { - if (!(P[2] & 0x8000)) { - - /* 1 of 4 colors for each pixel */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16); - - for (y = 0; y < 8; y++) { - /* get the next set of 8 2-bit flags */ - int flags = bytestream_get_le16(&s->stream_ptr); - for (x = 0; x < 8; x++, flags >>= 2) - *pixel_ptr++ = P[flags & 0x03]; - pixel_ptr += s->line_inc; - } - - } else { - uint32_t flags; - - /* 1 of 4 colors for each 2x2 block */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); - - flags = bytestream_get_le32(&s->stream_ptr); - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2, flags >>= 2) { - pixel_ptr[x ] = - pixel_ptr[x + 1 ] = - pixel_ptr[x + s->stride] = - pixel_ptr[x + 1 + s->stride] = P[flags & 0x03]; - } - pixel_ptr += s->stride * 2; - } - - } - } else { - uint64_t flags; - - /* 1 of 4 colors for each 2x1 or 1x2 block */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); - - flags = bytestream_get_le64(&s->stream_ptr); - if (!(P[2] & 0x8000)) { - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x += 2, flags >>= 2) { - pixel_ptr[x ] = - pixel_ptr[x + 1] = P[flags & 0x03]; - } - pixel_ptr += s->stride; - } - } else { - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x++, flags >>= 2) { - pixel_ptr[x ] = - pixel_ptr[x + s->stride] = P[flags & 0x03]; - } - pixel_ptr += s->stride * 2; - } - } - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s) -{ - int x, y; - uint16_t P[4]; - int flags = 0; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on - * either top and bottom or left and right halves */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24); - - if (!(AV_RL16(s->stream_ptr) & 0x8000)) { - - /* 4-color encoding for each quadrant */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 48); - - for (y = 0; y < 16; y++) { - // new values for each 4x4 block - if (!(y & 3)) { - for (x = 0; x < 4; x++) - P[x] = bytestream_get_le16(&s->stream_ptr); - flags = bytestream_get_le32(&s->stream_ptr); - } - - for (x = 0; x < 4; x++, flags >>= 2) - *pixel_ptr++ = P[flags & 0x03]; - - pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) pixel_ptr -= 8 * s->stride - 4; - } - - } else { - // vertical split? - int vert = !(AV_RL16(s->stream_ptr + 16) & 0x8000); - uint64_t flags = 0; - - /* 4-color encoding for either left and right or top and bottom - * halves */ - - for (y = 0; y < 16; y++) { - // load values for each half - if (!(y & 7)) { - for (x = 0; x < 4; x++) - P[x] = bytestream_get_le16(&s->stream_ptr); - flags = bytestream_get_le64(&s->stream_ptr); - } - - for (x = 0; x < 4; x++, flags >>= 2) - *pixel_ptr++ = P[flags & 0x03]; - - if (vert) { - pixel_ptr += s->stride - 4; - // switch to right half - if (y == 7) pixel_ptr -= 8 * s->stride - 4; - } else if (y & 1) pixel_ptr += s->line_inc; - } - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s) -{ - int x, y; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 64-color encoding (each pixel in block is a different color) */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 128); - - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) - pixel_ptr[x] = bytestream_get_le16(&s->stream_ptr); - pixel_ptr += s->stride; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s) -{ - int x, y; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 16-color block encoding: each 2x2 block is a different color */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 32); - - for (y = 0; y < 8; y += 2) { - for (x = 0; x < 8; x += 2) { - pixel_ptr[x ] = - pixel_ptr[x + 1 ] = - pixel_ptr[x + s->stride] = - pixel_ptr[x + 1 + s->stride] = bytestream_get_le16(&s->stream_ptr); - } - pixel_ptr += s->stride * 2; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s) -{ - int x, y; - uint16_t P[2]; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 4-color block encoding: each 4x4 block is a different color */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); - - for (y = 0; y < 8; y++) { - if (!(y & 3)) { - P[0] = bytestream_get_le16(&s->stream_ptr); - P[1] = bytestream_get_le16(&s->stream_ptr); - } - for (x = 0; x < 8; x++) - pixel_ptr[x] = P[x >> 2]; - pixel_ptr += s->stride; - } - - /* report success */ - return 0; -} - -static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s) -{ - int x, y; - uint16_t pix; - uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; - - /* 1-color encoding: the whole block is 1 solid color */ - CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); - pix = bytestream_get_le16(&s->stream_ptr); - - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) - pixel_ptr[x] = pix; - pixel_ptr += s->stride; - } - - /* report success */ - return 0; -} - -static int (* const ipvideo_decode_block[])(IpvideoContext *s) = { - ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1, - ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3, - ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5, - ipvideo_decode_block_opcode_0x6, ipvideo_decode_block_opcode_0x7, - ipvideo_decode_block_opcode_0x8, ipvideo_decode_block_opcode_0x9, - ipvideo_decode_block_opcode_0xA, ipvideo_decode_block_opcode_0xB, - ipvideo_decode_block_opcode_0xC, ipvideo_decode_block_opcode_0xD, - ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF, -}; - -static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = { - ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1, - ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3, - ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5, - ipvideo_decode_block_opcode_0x6_16, ipvideo_decode_block_opcode_0x7_16, - ipvideo_decode_block_opcode_0x8_16, ipvideo_decode_block_opcode_0x9_16, - ipvideo_decode_block_opcode_0xA_16, ipvideo_decode_block_opcode_0xB_16, - ipvideo_decode_block_opcode_0xC_16, ipvideo_decode_block_opcode_0xD_16, - ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1, -}; - -static void ipvideo_decode_opcodes(IpvideoContext *s) -{ - int x, y; - unsigned char opcode; - int ret; - static int frame = 0; - GetBitContext gb; - - debug_interplay("------------------ frame %d\n", frame); - frame++; - - if (!s->is_16bpp) { - /* 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; - } else { - s->stride = s->current_frame.linesize[0] >> 1; - s->stream_ptr = s->buf + 16; - s->stream_end = - s->mv_ptr = s->buf + 14 + AV_RL16(s->buf+14); - s->mv_end = s->buf + s->size; - } - s->line_inc = s->stride - 8; - s->upper_motion_limit_offset = (s->avctx->height - 8) * s->current_frame.linesize[0] - + (s->avctx->width - 8) * (1 + s->is_16bpp); - - init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8); - for (y = 0; y < s->avctx->height; y += 8) { - for (x = 0; x < s->avctx->width; x += 8) { - opcode = get_bits(&gb, 4); - - debug_interplay(" block @ (%3d, %3d): encoding 0x%X, data ptr @ %p\n", - x, y, opcode, s->stream_ptr); - - if (!s->is_16bpp) { - s->pixel_ptr = s->current_frame.data[0] + x - + y*s->current_frame.linesize[0]; - ret = ipvideo_decode_block[opcode](s); - } else { - s->pixel_ptr = s->current_frame.data[0] + x*2 - + y*s->current_frame.linesize[0]; - ret = ipvideo_decode_block16[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); - return; - } - } - } - if (s->stream_end - s->stream_ptr > 1) { - av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode finished with %td bytes left over\n", - s->stream_end - s->stream_ptr); - } -} - -static av_cold int ipvideo_decode_init(AVCodecContext *avctx) -{ - IpvideoContext *s = avctx->priv_data; - - s->avctx = avctx; - - s->is_16bpp = avctx->bits_per_coded_sample == 16; - avctx->pix_fmt = s->is_16bpp ? PIX_FMT_RGB555 : PIX_FMT_PAL8; - if (!s->is_16bpp && s->avctx->palctrl == NULL) { - av_log(avctx, AV_LOG_ERROR, " Interplay video: palette expected.\n"); - return -1; - } - - 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); - - 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, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->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 (!s->is_16bpp && 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 av_cold 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", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_INTERPLAY_VIDEO, - sizeof(IpvideoContext), - ipvideo_decode_init, - NULL, - ipvideo_decode_end, - ipvideo_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/intrax8.c b/tizen/distrib/ffmpeg/libavcodec/intrax8.c deleted file mode 100644 index 75166e8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/intrax8.c +++ /dev/null @@ -1,789 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1 - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "mpegvideo.h" -#include "msmpeg4data.h" -#include "intrax8huf.h" -#include "intrax8.h" - -#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits) - -#define DC_VLC_BITS 9 -#define AC_VLC_BITS 9 -#define OR_VLC_BITS 7 - -#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS) -#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS) -#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS) - -static VLC j_ac_vlc[2][2][8]; //[quant<13],[intra/inter],[select] -static VLC j_dc_vlc[2][8]; //[quant], [select] -static VLC j_orient_vlc[2][4]; //[quant], [select] - -static av_cold void x8_vlc_init(void){ - int i; - int offset = 0; - int sizeidx = 0; - static const uint16_t sizes[8*4 + 8*2 + 2 + 4] = { - 576, 548, 582, 618, 546, 616, 560, 642, - 584, 582, 704, 664, 512, 544, 656, 640, - 512, 648, 582, 566, 532, 614, 596, 648, - 586, 552, 584, 590, 544, 578, 584, 624, - - 528, 528, 526, 528, 536, 528, 526, 544, - 544, 512, 512, 528, 528, 544, 512, 544, - - 128, 128, 128, 128, 128, 128}; - - static VLC_TYPE table[28150][2]; - -#define init_ac_vlc(dst,src) \ - dst.table = &table[offset]; \ - dst.table_allocated = sizes[sizeidx]; \ - offset += sizes[sizeidx++]; \ - init_vlc(&dst, \ - AC_VLC_BITS,77, \ - &src[1],4,2, \ - &src[0],4,2, \ - INIT_VLC_USE_NEW_STATIC) -//set ac tables - for(i=0;i<8;i++){ - init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] ); - init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] ); - init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] ); - init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] ); - } -#undef init_ac_vlc - -//set dc tables -#define init_dc_vlc(dst,src) \ - dst.table = &table[offset]; \ - dst.table_allocated = sizes[sizeidx]; \ - offset += sizes[sizeidx++]; \ - init_vlc(&dst, \ - DC_VLC_BITS,34, \ - &src[1],4,2, \ - &src[0],4,2, \ - INIT_VLC_USE_NEW_STATIC); - for(i=0;i<8;i++){ - init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]); - init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]); - } -#undef init_dc_vlc - -//set orient tables -#define init_or_vlc(dst,src) \ - dst.table = &table[offset]; \ - dst.table_allocated = sizes[sizeidx]; \ - offset += sizes[sizeidx++]; \ - init_vlc(&dst, \ - OR_VLC_BITS,12, \ - &src[1],4,2, \ - &src[0],4,2, \ - INIT_VLC_USE_NEW_STATIC); - for(i=0;i<2;i++){ - init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]); - } - for(i=0;i<4;i++){ - init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0]) - } - if (offset != sizeof(table)/sizeof(VLC_TYPE)/2) - av_log(NULL, AV_LOG_ERROR, "table size %i does not match needed %i\n", (int)(sizeof(table)/sizeof(VLC_TYPE)/2), offset); -} -#undef init_or_vlc - -static void x8_reset_vlc_tables(IntraX8Context * w){ - memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc)); - memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc)); - w->j_orient_vlc=NULL; -} - -static inline void x8_select_ac_table(IntraX8Context * const w , int mode){ - MpegEncContext * const s= w->s; - int table_index; - - assert(mode<4); - - if( w->j_ac_vlc[mode] ) return; - - table_index = get_bits(&s->gb, 3); - w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables - assert(w->j_ac_vlc[mode]); -} - -static inline int x8_get_orient_vlc(IntraX8Context * w){ - MpegEncContext * const s= w->s; - int table_index; - - if(!w->j_orient_vlc ){ - table_index = get_bits(&s->gb, 1+(w->quant<13) ); - w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index]; - } - assert(w->j_orient_vlc); - assert(w->j_orient_vlc->table); - - return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD); -} - -#define extra_bits(eb) (eb) -#define extra_run (0xFF<<8) -#define extra_level (0x00<<8) -#define run_offset(r) ((r)<<16) -#define level_offset(l) ((l)<<24) -static const uint32_t ac_decode_table[]={ - /*46*/ extra_bits(3) | extra_run | run_offset(16) | level_offset( 0), - /*47*/ extra_bits(3) | extra_run | run_offset(24) | level_offset( 0), - /*48*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), - /*49*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), - - /*50*/ extra_bits(5) | extra_run | run_offset(32) | level_offset( 0), - /*51*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), - - /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), - /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8), - /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12), - /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16), - /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24), - - /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), - /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), - - /*59*/ extra_bits(2) | extra_run | run_offset(16) | level_offset( 0), - /*60*/ extra_bits(2) | extra_run | run_offset(20) | level_offset( 0), - /*61*/ extra_bits(2) | extra_run | run_offset(24) | level_offset( 0), - /*62*/ extra_bits(2) | extra_run | run_offset(28) | level_offset( 0), - /*63*/ extra_bits(4) | extra_run | run_offset(32) | level_offset( 0), - /*64*/ extra_bits(4) | extra_run | run_offset(48) | level_offset( 0), - - /*65*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), - /*66*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), - /*67*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), - - /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), - /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8), - /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16), - - /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), - /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), -}; -//extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits; -#undef extra_bits -#undef extra_run -#undef extra_level -#undef run_offset -#undef level_offset - -static void x8_get_ac_rlf(IntraX8Context * const w, const int mode, - int * const run, int * const level, int * const final){ - MpegEncContext * const s= w->s; - int i,e; - -// x8_select_ac_table(w,mode); - i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD); - - if(i<46){ //[0-45] - int t,l; - if(i<0){ - (*level)=(*final)=//prevent 'may be used unilitialized' - (*run)=64;//this would cause error exit in the ac loop - return; - } - - (*final) = t = (i>22); - i-=23*t; -/* - i== 0-15 r=0-15 l=0 ;r=i& %01111 - i==16-19 r=0-3 l=1 ;r=i& %00011 - i==20-21 r=0-1 l=2 ;r=i& %00001 - i==22 r=0 l=3 ;r=i& %00000 -l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 -t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */ - l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/ - t=(0x01030F>>(l<<3)); - - (*run) = i&t; - (*level) = l; - }else if(i<73){//[46-72] - uint32_t sm; - uint32_t mask; - - i-=46; - sm=ac_decode_table[i]; - - e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits - mask=sm&0xff;sm>>=8; //1bit - - (*run) =(sm&0xff) + (e&( mask));//6bits - (*level)=(sm>>8) + (e&(~mask));//5bits - (*final)=i>(58-46); - }else if(i<75){//[73-74] - static const uint8_t crazy_mix_runlevel[32]={ - 0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63, - 0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83, - 0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64, - 0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84}; - - (*final)=!(i&1); - e=get_bits(&s->gb,5);//get the extra bits - (*run) =crazy_mix_runlevel[e]>>4; - (*level)=crazy_mix_runlevel[e]&0x0F; - }else{ - (*level)=get_bits( &s->gb, 7-3*(i&1)); - (*run) =get_bits( &s->gb, 6); - (*final)=get_bits1(&s->gb); - } - return; -} - -//static const uint8_t dc_extra_sbits[] ={0, 1,1, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 }; -static const uint8_t dc_index_offset[] ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193}; - -static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){ - MpegEncContext * const s= w->s; - int i,e,c; - - assert(mode<3); - if( !w->j_dc_vlc[mode] ) { - int table_index; - table_index = get_bits(&s->gb, 3); - //4 modes, same table - w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index]; - } - assert(w->j_dc_vlc); - assert(w->j_dc_vlc[mode]->table); - - i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD); - - /*(i>=17) {i-=17;final=1;}*/ - c= i>16; - (*final)=c; - i-=17*c; - - if(i<=0){ - (*level)=0; - return -i; - } - c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[] - c-=c>1; - - e=get_bits(&s->gb,c);//get the extra bits - i=dc_index_offset[i]+(e>>1); - - e= -(e & 1);//0,0xffffff - (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1) - return 0; -} -//end of huffman - -static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){ - MpegEncContext * const s= w->s; - int range; - int sum; - int quant; - - s->dsp.x8_setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer, - s->current_picture.linesize[chroma>0], - &range, &sum, w->edges); - if(chroma){ - w->orient=w->chroma_orient; - quant=w->quant_dc_chroma; - }else{ - quant=w->quant; - } - - w->flat_dc=0; - if(range < quant || range < 3){ - w->orient=0; - if(range < 3){//yep you read right, a +-1 idct error may break decoding! - w->flat_dc=1; - sum+=9; - w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899 - } - } - if(chroma) - return 0; - - assert(w->orient < 3); - if(range < 2*w->quant){ - if( (w->edges&3) == 0){ - if(w->orient==1) w->orient=11; - if(w->orient==2) w->orient=10; - }else{ - w->orient=0; - } - w->raw_orient=0; - }else{ - static const uint8_t prediction_table[3][12]={ - {0,8,4, 10,11, 2,6,9,1,3,5,7}, - {4,0,8, 11,10, 3,5,2,6,9,1,7}, - {8,0,4, 10,11, 1,7,2,6,9,3,5} - }; - w->raw_orient=x8_get_orient_vlc(w); - if(w->raw_orient<0) return -1; - assert(w->raw_orient < 12 ); - assert(w->orient<3); - w->orient=prediction_table[w->orient][w->raw_orient]; - } - return 0; -} - -static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){ - MpegEncContext * const s= w->s; - - w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8); -/* - y=2n+0 ->//0 2 4 - y=2n+1 ->//1 3 5 -*/ -} -static void x8_get_prediction_chroma(IntraX8Context * const w){ - MpegEncContext * const s= w->s; - - w->edges = 1*( !(s->mb_x>>1) ); - w->edges|= 2*( !(s->mb_y>>1) ); - w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd - - w->raw_orient=0; - if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC - w->chroma_orient=4<<((0xCC>>w->edges)&1); - return; - } - w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)] -} - -static void x8_get_prediction(IntraX8Context * const w){ - MpegEncContext * const s= w->s; - int a,b,c,i; - - w->edges = 1*( !s->mb_x ); - w->edges|= 2*( !s->mb_y ); - w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) ); - - switch(w->edges&3){ - case 0: - break; - case 1: - //take the one from the above block[0][y-1] - w->est_run = w->prediction_table[!(s->mb_y&1)]>>2; - w->orient = 1; - return; - case 2: - //take the one from the previous block[x-1][0] - w->est_run = w->prediction_table[2*s->mb_x-2]>>2; - w->orient = 2; - return; - case 3: - w->est_run = 16; - w->orient = 0; - return; - } - //no edge cases - b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];//block[x ][y-1] - a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];//block[x-1][y ] - c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1] - - w->est_run = FFMIN(b,a); - /* This condition has nothing to do with w->edges, even if it looks - similar it would trigger if e.g. x=3;y=2; - I guess somebody wrote something wrong and it became standard. */ - if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run); - w->est_run>>=2; - - a&=3; - b&=3; - c&=3; - - i=( 0xFFEAF4C4>>(2*b+8*a) )&3; - if(i!=3) w->orient=i; - else w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3; -/* -lut1[b][a]={ -->{0, 1, 0, pad}, - {0, 1, X, pad}, - {2, 2, 2, pad}} - pad 2 2 2; pad X 1 0; pad 0 1 0 <- --> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4 - -lut2[q>12][c]={ - ->{0,2,1,pad}, - {2,2,2,pad}} - pad 2 2 2; pad 1 2 0 <- --> 11 10'10 10 '11 01'10 00=>0xEAD8 -*/ -} - - -static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){ - MpegEncContext * const s= w->s; - int t; -#define B(x,y) s->block[0][s->dsp.idct_permutation[(x)+(y)*8]] -#define T(x) ((x) * dc_level + 0x8000) >> 16; - switch(direction){ - case 0: - t = T(3811);//h - B(1,0) -= t; - B(0,1) -= t; - - t = T(487);//e - B(2,0) -= t; - B(0,2) -= t; - - t = T(506);//f - B(3,0) -= t; - B(0,3) -= t; - - t = T(135);//c - B(4,0) -= t; - B(0,4) -= t; - B(2,1) += t; - B(1,2) += t; - B(3,1) += t; - B(1,3) += t; - - t = T(173);//d - B(5,0) -= t; - B(0,5) -= t; - - t = T(61);//b - B(6,0) -= t; - B(0,6) -= t; - B(5,1) += t; - B(1,5) += t; - - t = T(42); //a - B(7,0) -= t; - B(0,7) -= t; - B(4,1) += t; - B(1,4) += t; - B(4,4) += t; - - t = T(1084);//g - B(1,1) += t; - - s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); - break; - case 1: - B(0,1) -= T(6269); - B(0,3) -= T( 708); - B(0,5) -= T( 172); - B(0,7) -= T( 73); - - s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); - break; - case 2: - B(1,0) -= T(6269); - B(3,0) -= T( 708); - B(5,0) -= T( 172); - B(7,0) -= T( 73); - - s->block_last_index[0] = FFMAX(s->block_last_index[0], 7); - break; - } -#undef B -#undef T -} - -static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){ - int k; - for(k=0;k<8;k++){ - memset(dst,pix,8); - dst+=linesize; - } -} - -static const int16_t quant_table[64] = { - 256, 256, 256, 256, 256, 256, 259, 262, - 265, 269, 272, 275, 278, 282, 285, 288, - 292, 295, 299, 303, 306, 310, 314, 317, - 321, 325, 329, 333, 337, 341, 345, 349, - 353, 358, 362, 366, 371, 375, 379, 384, - 389, 393, 398, 403, 408, 413, 417, 422, - 428, 433, 438, 443, 448, 454, 459, 465, - 470, 476, 482, 488, 493, 499, 505, 511 -}; - -static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){ - MpegEncContext * const s= w->s; - - uint8_t * scantable; - int final,run,level; - int ac_mode,dc_mode,est_run,dc_level; - int pos,n; - int zeros_only; - int use_quant_matrix; - int sign; - - assert(w->orient<12); - s->dsp.clear_block(s->block[0]); - - if(chroma){ - dc_mode=2; - }else{ - dc_mode=!!w->est_run;//0,1 - } - - if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1; - n=0; - zeros_only=0; - if(!final){//decode ac - use_quant_matrix=w->use_quant_matrix; - if(chroma){ - ac_mode = 1; - est_run = 64;//not used - }else{ - if (w->raw_orient < 3){ - use_quant_matrix = 0; - } - if(w->raw_orient > 4){ - ac_mode = 0; - est_run = 64; - }else{ - if(w->est_run > 1){ - ac_mode = 2; - est_run=w->est_run; - }else{ - ac_mode = 3; - est_run = 64; - } - } - } - x8_select_ac_table(w,ac_mode); - /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<- - -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */ - scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated; - pos=0; - do { - n++; - if( n >= est_run ){ - ac_mode=3; - x8_select_ac_table(w,3); - } - - x8_get_ac_rlf(w,ac_mode,&run,&level,&final); - - pos+=run+1; - if(pos>63){ - //this also handles vlc error in x8_get_ac_rlf - return -1; - } - level= (level+1) * w->dquant; - level+= w->qsum; - - sign = - get_bits1(&s->gb); - level = (level ^ sign) - sign; - - if(use_quant_matrix){ - level = (level*quant_table[pos])>>8; - } - s->block[0][ scantable[pos] ]=level; - }while(!final); - - s->block_last_index[0]=pos; - }else{//DC only - s->block_last_index[0]=0; - if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1] - int32_t divide_quant= !chroma ? w->divide_quant_dc_luma: - w->divide_quant_dc_chroma; - int32_t dc_quant = !chroma ? w->quant: - w->quant_dc_chroma; - - //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding - dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13; - - dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3), - s->dest[chroma], s->current_picture.linesize[!!chroma]); - - goto block_placed; - } - zeros_only = (dc_level == 0); - } - if(!chroma){ - s->block[0][0] = dc_level*w->quant; - }else{ - s->block[0][0] = dc_level*w->quant_dc_chroma; - } - - //there is !zero_only check in the original, but dc_level check is enough - if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){ - int direction; - /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<- - -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */ - direction= (0x6A017C>>(w->orient*2))&3; - if (direction != 3){ - x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[] - } - } - - if(w->flat_dc){ - dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]); - }else{ - s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer, - s->dest[chroma], - s->current_picture.linesize[!!chroma] ); - } - if(!zeros_only) - s->dsp.idct_add ( s->dest[chroma], - s->current_picture.linesize[!!chroma], - s->block[0] ); - -block_placed: - - if(!chroma){ - x8_update_predictions(w,w->orient,n); - } - - if(s->loop_filter){ - uint8_t* ptr = s->dest[chroma]; - int linesize = s->current_picture.linesize[!!chroma]; - - if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){ - s->dsp.x8_h_loop_filter(ptr, linesize, w->quant); - } - if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){ - s->dsp.x8_v_loop_filter(ptr, linesize, w->quant); - } - } - return 0; -} - -static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_* -//not s->linesize as this would be wrong for field pics -//not that IntraX8 has interlacing support ;) - const int linesize = s->current_picture.linesize[0]; - const int uvlinesize= s->current_picture.linesize[1]; - - s->dest[0] = s->current_picture.data[0]; - s->dest[1] = s->current_picture.data[1]; - s->dest[2] = s->current_picture.data[2]; - - s->dest[0] += s->mb_y * linesize << 3; - s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows - s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2; -} - -/** - * Initialize IntraX8 frame decoder. - * Requires valid MpegEncContext with valid s->mb_width before calling. - * @param w pointer to IntraX8Context - * @param s pointer to MpegEncContext of the parent codec - */ -av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){ - - w->s=s; - x8_vlc_init(); - assert(s->mb_width>0); - w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb - - ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], wmv1_scantable[0]); - ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], wmv1_scantable[2]); - ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], wmv1_scantable[3]); -} - -/** - * Destroy IntraX8 frame structure. - * @param w pointer to IntraX8Context - */ -av_cold void ff_intrax8_common_end(IntraX8Context * w) -{ - av_freep(&w->prediction_table); -} - -/** - * Decode single IntraX8 frame. - * The parent codec must fill s->loopfilter and s->gb (bitstream). - * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function. - * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function. - * This function does not use MPV_decode_mb(). - * lowres decoding is theoretically impossible. - * @param w pointer to IntraX8Context - * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1. - * @param quant_offset offset away from zero - */ -//FIXME extern uint8_t wmv3_dc_scale_table[32]; -int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){ - MpegEncContext * const s= w->s; - int mb_xy; - assert(s); - w->use_quant_matrix = get_bits1(&s->gb); - - w->dquant = dquant; - w->quant = dquant >> 1; - w->qsum = quant_offset; - - w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant; - if(w->quant < 5){ - w->quant_dc_chroma = w->quant; - w->divide_quant_dc_chroma = w->divide_quant_dc_luma; - }else{ - w->quant_dc_chroma = w->quant+((w->quant+3)>>3); - w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma; - } - x8_reset_vlc_tables(w); - - s->resync_mb_x=0; - s->resync_mb_y=0; - - for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){ - x8_init_block_index(s); - mb_xy=(s->mb_y>>1)*s->mb_stride; - - for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){ - x8_get_prediction(w); - if(x8_setup_spatial_predictor(w,0)) goto error; - if(x8_decode_intra_mb(w,0)) goto error; - - if( s->mb_x & s->mb_y & 1 ){ - x8_get_prediction_chroma(w); - - /*when setting up chroma, no vlc is read, - so no error condition can be reached*/ - x8_setup_spatial_predictor(w,1); - if(x8_decode_intra_mb(w,1)) goto error; - - x8_setup_spatial_predictor(w,2); - if(x8_decode_intra_mb(w,2)) goto error; - - s->dest[1]+= 8; - s->dest[2]+= 8; - - /*emulate MB info in the relevant tables*/ - s->mbskip_table [mb_xy]=0; - s->mbintra_table[mb_xy]=1; - s->current_picture.qscale_table[mb_xy]=w->quant; - mb_xy++; - } - s->dest[0]+= 8; - } - if(s->mb_y&1){ - ff_draw_horiz_band(s, (s->mb_y-1)*8, 16); - } - } - -error: - ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, - (s->mb_x>>1)-1, (s->mb_y>>1)-1, - (AC_END|DC_END|MV_END) ); - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/intrax8.h b/tizen/distrib/ffmpeg/libavcodec/intrax8.h deleted file mode 100644 index 8ce4f8d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/intrax8.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_INTRAX8_H -#define AVCODEC_INTRAX8_H - -#include "get_bits.h" -#include "mpegvideo.h" - -typedef struct{ - VLC * j_ac_vlc[4];//they point to the static j_mb_vlc - VLC * j_orient_vlc; - VLC * j_dc_vlc[3]; - - int use_quant_matrix; -//set by ff_intrax8_common_init - uint8_t * prediction_table;//2*(mb_w*2) - ScanTable scantable[3]; -//set by the caller codec - MpegEncContext * s; - int quant; - int dquant; - int qsum; -//calculated per frame - int quant_dc_chroma; - int divide_quant_dc_luma; - int divide_quant_dc_chroma; -//changed per block - int edges; - int flat_dc; - int predicted_dc; - int raw_orient; - int chroma_orient; - int orient; - int est_run; -} IntraX8Context; - -void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s); -void ff_intrax8_common_end(IntraX8Context * w); -int ff_intrax8_decode_picture(IntraX8Context * w, int quant, int halfpq); - -#endif /* AVCODEC_INTRAX8_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/intrax8dsp.c b/tizen/distrib/ffmpeg/libavcodec/intrax8dsp.c deleted file mode 100644 index 692e1b1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/intrax8dsp.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file - *@brief IntraX8 frame subdecoder image manipulation routines - */ - -#include "dsputil.h" - -/* -area positions, #3 is 1 pixel only, other are 8 pixels - |66666666| - 3|44444444|55555555| -- -+--------+--------+ -1 2|XXXXXXXX| -1 2|XXXXXXXX| -1 2|XXXXXXXX| -1 2|XXXXXXXX| -1 2|XXXXXXXX| -1 2|XXXXXXXX| -1 2|XXXXXXXX| -1 2|XXXXXXXX| -^-start -*/ - -#define area1 (0) -#define area2 (8) -#define area3 (8+8) -#define area4 (8+8+1) -#define area5 (8+8+1+8) -#define area6 (8+8+1+16) - -/** - Collect statistics and prepare the edge pixels required by the other spatial compensation functions. - - * @param src pointer to the beginning of the processed block - * @param dst pointer to emu_edge, edge pixels are stored the way other compensation routines do. - * @param linesize byte offset between 2 vertical pixels in the source image - * @param range pointer to the variable where the edge pixel range is to be stored (max-min values) - * @param psum pointer to the variable where the edge pixel sum is to be stored - * @param edges Informs this routine that the block is on an image border, so it has to interpolate the missing edge pixels. - and some of the edge pixels should be interpolated, the flag has the following meaning: - 1 - mb_x==0 - first block in the row, interpolate area #1,#2,#3; - 2 - mb_y==0 - first row, interpolate area #3,#4,#5,#6; - note: 1|2 - mb_x==mb_y==0 - first block, use 0x80 value for all areas; - 4 - mb_x>= (mb_width-1) last block in the row, interpolate area #5; -*/ -static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, int linesize, - int * range, int * psum, int edges){ - uint8_t * ptr; - int sum; - int i; - int min_pix,max_pix; - uint8_t c; - - if((edges&3)==3){ - *psum=0x80*(8+1+8+2); - *range=0; - memset(dst,0x80,16+1+16+8); - //this triggers flat_dc for sure. - //flat_dc avoids all (other) prediction modes, but requires dc_level decoding. - return; - } - - min_pix=256; - max_pix=-1; - - sum=0; - - if(!(edges&1)){//(mb_x!=0)//there is previous block on this row - ptr=src-1;//left column, area 2 - for(i=7;i>=0;i--){ - c=*(ptr-1);//area1, same mb as area2, no need to check - dst[area1+i]=c; - c=*(ptr); - - sum+=c; - min_pix=FFMIN(min_pix,c); - max_pix=FFMAX(max_pix,c); - dst[area2+i]=c; - - ptr+=linesize; - } - } - - if(!(edges&2)){ //(mb_y!=0)//there is row above - ptr=src-linesize;//top line - for(i=0;i<8;i++){ - c=*(ptr+i); - sum+=c; - min_pix=FFMIN(min_pix, c); - max_pix=FFMAX(max_pix, c); - } - if(edges&4){//last block on the row? - memset(dst+area5,c,8);//set with last pixel fr - memcpy(dst+area4, ptr, 8); - }else{ - memcpy(dst+area4, ptr, 16);//both area4 and 5 - } - memcpy(dst+area6, ptr-linesize, 8);//area6 always present in the above block - } - //now calculate the stuff we need - if(edges&3){//mb_x==0 || mb_y==0){ - int avg=(sum+4)>>3; - if(edges&1){ //(mb_x==0) {//implies mb_y!=0 - memset(dst+area1,avg,8+8+1);//areas 1,2 and 3 are averaged - }else{//implies y==0 x!=0 - memset(dst+area3,avg, 1+16+8);//areas 3, 4,5,6 - } - sum+=avg*9; - }else{ - uint8_t c=*(src-1-linesize);//the edge pixel, in the top line and left column - dst[area3]=c; - sum+=c; - //edge pixel is not part of min/max - } - (*range) = max_pix - min_pix; - sum += *(dst+area5) + *(dst+area5+1); - *psum = sum; -} - - -static const uint16_t zero_prediction_weights[64*2] = { - 640, 640, 669, 480, 708, 354, 748, 257, 792, 198, 760, 143, 808, 101, 772, 72, - 480, 669, 537, 537, 598, 416, 661, 316, 719, 250, 707, 185, 768, 134, 745, 97, - 354, 708, 416, 598, 488, 488, 564, 388, 634, 317, 642, 241, 716, 179, 706, 132, - 257, 748, 316, 661, 388, 564, 469, 469, 543, 395, 571, 311, 655, 238, 660, 180, - 198, 792, 250, 719, 317, 634, 395, 543, 469, 469, 507, 380, 597, 299, 616, 231, - 161, 855, 206, 788, 266, 710, 340, 623, 411, 548, 455, 455, 548, 366, 576, 288, - 122, 972, 159, 914, 211, 842, 276, 758, 341, 682, 389, 584, 483, 483, 520, 390, - 110, 1172, 144, 1107, 193, 1028, 254, 932, 317, 846, 366, 731, 458, 611, 499, 499 -}; - -static void spatial_compensation_0(uint8_t *src , uint8_t *dst, int linesize){ - int i,j; - int x,y; - unsigned int p;//power divided by 2 - int a; - uint16_t left_sum[2][8]; - uint16_t top_sum[2][8]; - memset(left_sum,0,2*8*sizeof(uint16_t)); - memset( top_sum,0,2*8*sizeof(uint16_t)); - - for(i=0;i<8;i++){ - a=src[area2+7-i]<<4; - for(j=0;j<8;j++){ - p=abs(i-j); - left_sum[p&1][j]+= a>>(p>>1); - } - } - - for(i=0;i<8;i++){ - a=src[area4+i]<<4; - for(j=0;j<8;j++){ - p=abs(i-j); - top_sum[p&1][j]+= a>>(p>>1); - } - } - for(;i<10;i++){ - a=src[area4+i]<<4; - for(j=5;j<8;j++){ - p=abs(i-j); - top_sum[p&1][j]+= a>>(p>>1); - } - } - for(;i<12;i++){ - a=src[area4+i]<<4; - for(j=7;j<8;j++){ - p=abs(i-j); - top_sum[p&1][j]+= a>>(p>>1); - } - } - - for(i=0;i<8;i++){ - top_sum [0][i]+=(top_sum [1][i]*181 + 128 )>>8;//181 is sqrt(2)/2 - left_sum[0][i]+=(left_sum[1][i]*181 + 128 )>>8; - } - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x] = ( - (uint32_t)top_sum [0][x]*zero_prediction_weights[y*16+x*2+0] + - (uint32_t)left_sum[0][y]*zero_prediction_weights[y*16+x*2+1] + - 0x8000 - )>>16; - } - dst+=linesize; - } -} -static void spatial_compensation_1(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=src[area4 + FFMIN(2*y+x+2, 15) ]; - } - dst+=linesize; - } -} -static void spatial_compensation_2(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=src[area4 +1+y+x]; - } - dst+=linesize; - } -} -static void spatial_compensation_3(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=src[area4 +((y+1)>>1)+x]; - } - dst+=linesize; - } -} -static void spatial_compensation_4(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=( src[area4+x] + src[area6+x] + 1 )>>1; - } - dst+=linesize; - } -} -static void spatial_compensation_5(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - if(2*x-y<0){ - dst[x]=src[area2+9+2*x-y]; - }else{ - dst[x]=src[area4 +x-((y+1)>>1)]; - } - } - dst+=linesize; - } -} -static void spatial_compensation_6(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=src[area3+x-y]; - } - dst+=linesize; - } -} -static void spatial_compensation_7(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - if(x-2*y>0){ - dst[x]=( src[area3-1+x-2*y] + src[area3+x-2*y] + 1)>>1; - }else{ - dst[x]=src[area2+8-y +(x>>1)]; - } - } - dst+=linesize; - } -} -static void spatial_compensation_8(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=( src[area1+7-y] + src[area2+7-y] + 1 )>>1; - } - dst+=linesize; - } -} -static void spatial_compensation_9(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=src[area2+6-FFMIN(x+y,6)]; - } - dst+=linesize; - } -} -static void spatial_compensation_10(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=(src[area2+7-y]*(8-x)+src[area4+x]*x+4)>>3; - } - dst+=linesize; - } -} -static void spatial_compensation_11(uint8_t *src , uint8_t *dst, int linesize){ - int x,y; - - for(y=0;y<8;y++){ - for(x=0;x<8;x++){ - dst[x]=(src[area2+7-y]*y+src[area4+x]*(8-y)+4)>>3; - } - dst+=linesize; - } -} - -static void x8_loop_filter(uint8_t * ptr, const int a_stride, const int b_stride, int quant){ - int i,t; - int p0,p1,p2,p3,p4,p5,p6,p7,p8,p9; - int ql=(quant+10)>>3; - - for(i=0; i<8; i++,ptr+=b_stride){ - p0=ptr[-5*a_stride]; - p1=ptr[-4*a_stride]; - p2=ptr[-3*a_stride]; - p3=ptr[-2*a_stride]; - p4=ptr[-1*a_stride]; - p5=ptr[ 0 ]; - p6=ptr[ 1*a_stride]; - p7=ptr[ 2*a_stride]; - p8=ptr[ 3*a_stride]; - p9=ptr[ 4*a_stride]; - - t= - (FFABS(p1-p2) <= ql) + - (FFABS(p2-p3) <= ql) + - (FFABS(p3-p4) <= ql) + - (FFABS(p4-p5) <= ql); - if(t>0){//You need at least 1 to be able to reach a total score of 6. - t+= - (FFABS(p5-p6) <= ql) + - (FFABS(p6-p7) <= ql) + - (FFABS(p7-p8) <= ql) + - (FFABS(p8-p9) <= ql) + - (FFABS(p0-p1) <= ql); - if(t>=6){ - int min,max; - - min=max=p1; - min=FFMIN(min,p3); max=FFMAX(max,p3); - min=FFMIN(min,p5); max=FFMAX(max,p5); - min=FFMIN(min,p8); max=FFMAX(max,p8); - if(max-min<2*quant){//early stop - min=FFMIN(min,p2); max=FFMAX(max,p2); - min=FFMIN(min,p4); max=FFMAX(max,p4); - min=FFMIN(min,p6); max=FFMAX(max,p6); - min=FFMIN(min,p7); max=FFMAX(max,p7); - if(max-min<2*quant){ - ptr[-2*a_stride]=(4*p2 + 3*p3 + 1*p7 + 4)>>3; - ptr[-1*a_stride]=(3*p2 + 3*p4 + 2*p7 + 4)>>3; - ptr[ 0 ]=(2*p2 + 3*p5 + 3*p7 + 4)>>3; - ptr[ 1*a_stride]=(1*p2 + 3*p6 + 4*p7 + 4)>>3; - continue; - }; - } - } - } - { - int x,x0,x1,x2; - int m; - - x0 = (2*p3 - 5*p4 + 5*p5 - 2*p6 + 4)>>3; - if(FFABS(x0) < quant){ - x1=(2*p1 - 5*p2 + 5*p3 - 2*p4 + 4)>>3; - x2=(2*p5 - 5*p6 + 5*p7 - 2*p8 + 4)>>3; - - x=FFABS(x0) - FFMIN( FFABS(x1), FFABS(x2) ); - m=p4-p5; - - if( x > 0 && (m^x0) <0){ - int32_t sign; - - sign=m>>31; - m=(m^sign)-sign;//abs(m) - m>>=1; - - x=(5*x)>>3; - - if(x>m) x=m; - - x=(x^sign)-sign; - - ptr[-1*a_stride] -= x; - ptr[ 0] += x; - } - } - } - } -} - -static void x8_h_loop_filter(uint8_t *src, int stride, int qscale){ - x8_loop_filter(src, stride, 1, qscale); -} - -static void x8_v_loop_filter(uint8_t *src, int stride, int qscale){ - x8_loop_filter(src, 1, stride, qscale); -} - -av_cold void ff_intrax8dsp_init(DSPContext* dsp, AVCodecContext *avctx) { - dsp->x8_h_loop_filter=x8_h_loop_filter; - dsp->x8_v_loop_filter=x8_v_loop_filter; - dsp->x8_setup_spatial_compensation=x8_setup_spatial_compensation; - dsp->x8_spatial_compensation[0]=spatial_compensation_0; - dsp->x8_spatial_compensation[1]=spatial_compensation_1; - dsp->x8_spatial_compensation[2]=spatial_compensation_2; - dsp->x8_spatial_compensation[3]=spatial_compensation_3; - dsp->x8_spatial_compensation[4]=spatial_compensation_4; - dsp->x8_spatial_compensation[5]=spatial_compensation_5; - dsp->x8_spatial_compensation[6]=spatial_compensation_6; - dsp->x8_spatial_compensation[7]=spatial_compensation_7; - dsp->x8_spatial_compensation[8]=spatial_compensation_8; - dsp->x8_spatial_compensation[9]=spatial_compensation_9; - dsp->x8_spatial_compensation[10]=spatial_compensation_10; - dsp->x8_spatial_compensation[11]=spatial_compensation_11; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/intrax8huf.h b/tizen/distrib/ffmpeg/libavcodec/intrax8huf.h deleted file mode 100644 index 375906b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/intrax8huf.h +++ /dev/null @@ -1,918 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_INTRAX8HUF_H -#define AVCODEC_INTRAX8HUF_H - -#include - - -static const uint16_t x8_orient_lowquant_table[4][12][2]={ - {//0 - {0x0000, 1}, {0x0004, 3}, {0x0005, 3}, {0x000C, 4}, - {0x000D, 4}, {0x0038, 6}, {0x001D, 5}, {0x0039, 6}, - {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6}, - },{//1 - {0x0000, 5}, {0x0001, 5}, {0x0002, 5}, {0x0001, 2}, - {0x0002, 2}, {0x0002, 4}, {0x0003, 5}, {0x0006, 3}, - {0x0003, 4}, {0x000E, 4}, {0x001E, 5}, {0x001F, 5}, - },{//2 - {0x0000, 2}, {0x0001, 2}, {0x0004, 3}, {0x0005, 3}, - {0x0006, 3}, {0x0038, 6}, {0x0039, 6}, {0x001D, 5}, - {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6}, - },{//3 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0001, 2}, - {0x0002, 2}, {0x0018, 5}, {0x0019, 5}, {0x000D, 4}, - {0x001C, 5}, {0x001D, 5}, {0x001E, 5}, {0x001F, 5}, - } -}; - -static const uint16_t x8_orient_highquant_table[2][12][2]={ - {//0 - {0x0000, 2}, {0x0001, 2}, {0x0004, 3}, {0x0005, 3}, - {0x0006, 3}, {0x0038, 6}, {0x001D, 5}, {0x0039, 6}, - {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6}, - },{//1 - {0x0000, 1}, {0x0002, 2}, {0x0006, 3}, {0x001C, 5}, - {0x001D, 5}, {0x0078, 7}, {0x003D, 6}, {0x0079, 7}, - {0x007C, 7}, {0x007D, 7}, {0x007E, 7}, {0x007F, 7}, - } -}; -#define MAX_OR_VLC_BITS 7 - - -static const uint16_t x8_dc_lowquant_table[8][34][2]={ - {//0 - {0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0004, 5}, - {0x0005, 5}, {0x0006, 5}, {0x000E, 6}, {0x000F, 6}, - {0x0040, 8}, {0x0041, 8}, {0x0840, 13}, {0x0841, 13}, - {0x0842, 13}, {0x0843, 13}, {0x0844, 13}, {0x0845, 13}, - {0x0846, 13}, {0x0002, 2}, {0x0003, 2}, {0x0003, 3}, - {0x0005, 4}, {0x0009, 5}, {0x0011, 6}, {0x0043, 8}, - {0x0085, 9}, {0x0847, 13}, {0x0848, 13}, {0x0849, 13}, - {0x084A, 13}, {0x084B, 13}, {0x084C, 13}, {0x084D, 13}, - {0x084E, 13}, {0x084F, 13}, - },{//1 - {0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4}, - {0x0006, 4}, {0x0004, 3}, {0x0007, 4}, {0x0005, 3}, - {0x000C, 4}, {0x000D, 4}, {0x001C, 5}, {0x003A, 6}, - {0x01D8, 9}, {0x01D9, 9}, {0x1DA0, 13}, {0x1DA1, 13}, - {0x1DA2, 13}, {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, - {0x0077, 7}, {0x01DB, 9}, {0x007E, 7}, {0x00FE, 8}, - {0x01FE, 9}, {0x1DA3, 13}, {0x1DA4, 13}, {0x1DA5, 13}, - {0x0ED3, 12}, {0x0ED4, 12}, {0x01FF, 9}, {0x0ED5, 12}, - {0x0ED6, 12}, {0x0ED7, 12}, - },{//2 - {0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4}, - {0x0006, 4}, {0x0007, 4}, {0x0008, 4}, {0x0009, 4}, - {0x0028, 6}, {0x0029, 6}, {0x0054, 7}, {0x0055, 7}, - {0x0AC0, 12}, {0x0AC1, 12}, {0x0AC2, 12}, {0x0AC3, 12}, - {0x0AC4, 12}, {0x000B, 4}, {0x0006, 3}, {0x000E, 4}, - {0x001E, 5}, {0x003E, 6}, {0x003F, 6}, {0x0057, 7}, - {0x00AD, 8}, {0x0AC5, 12}, {0x0AC6, 12}, {0x0AC7, 12}, - {0x0AC8, 12}, {0x0AC9, 12}, {0x0ACA, 12}, {0x0ACB, 12}, - {0x0566, 11}, {0x0567, 11}, - },{//3 - {0x0000, 4}, {0x0001, 2}, {0x0001, 3}, {0x0004, 3}, - {0x0005, 3}, {0x0006, 3}, {0x0001, 4}, {0x000E, 4}, - {0x003C, 6}, {0x003D, 6}, {0x007C, 7}, {0x00FA, 8}, - {0x3EC0, 14}, {0x3EC1, 14}, {0x3EC2, 14}, {0x3EC3, 14}, - {0x1F62, 13}, {0x01F7, 9}, {0x007E, 7}, {0x00FE, 8}, - {0x00FF, 8}, {0x1F63, 13}, {0x1F64, 13}, {0x1F65, 13}, - {0x1F66, 13}, {0x1F67, 13}, {0x1F68, 13}, {0x1F69, 13}, - {0x1F6A, 13}, {0x1F6B, 13}, {0x1F6C, 13}, {0x1F6D, 13}, - {0x1F6E, 13}, {0x1F6F, 13}, - },{//4 - {0x0000, 7}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7}, - {0x0004, 7}, {0x0005, 7}, {0x0006, 7}, {0x0007, 7}, - {0x0008, 7}, {0x0009, 7}, {0x000A, 7}, {0x000B, 7}, - {0x000C, 7}, {0x000D, 7}, {0x000E, 7}, {0x000F, 7}, - {0x0010, 7}, {0x0001, 1}, {0x0001, 2}, {0x0011, 7}, - {0x0012, 7}, {0x0013, 7}, {0x0014, 7}, {0x0015, 7}, - {0x0016, 7}, {0x0017, 7}, {0x0018, 7}, {0x0019, 7}, - {0x001A, 7}, {0x001B, 7}, {0x001C, 7}, {0x001D, 7}, - {0x001E, 7}, {0x001F, 7}, - },{//5 - {0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0008, 6}, - {0x0009, 6}, {0x000A, 6}, {0x0016, 7}, {0x000C, 6}, - {0x0017, 7}, {0x000D, 6}, {0x0038, 8}, {0x001D, 7}, - {0x0039, 8}, {0x0780, 13}, {0x0781, 13}, {0x0782, 13}, - {0x0783, 13}, {0x0002, 3}, {0x0001, 1}, {0x0003, 3}, - {0x001F, 7}, {0x003D, 8}, {0x0079, 9}, {0x0784, 13}, - {0x0785, 13}, {0x0786, 13}, {0x0787, 13}, {0x0788, 13}, - {0x0789, 13}, {0x078A, 13}, {0x078B, 13}, {0x078C, 13}, - {0x078D, 13}, {0x03C7, 12}, - },{//6 - {0x0000, 4}, {0x0001, 2}, {0x0001, 3}, {0x0004, 3}, - {0x0001, 4}, {0x000A, 4}, {0x0016, 5}, {0x002E, 6}, - {0x005E, 7}, {0x005F, 7}, {0x00C0, 8}, {0x3040, 14}, - {0x3041, 14}, {0x0305, 10}, {0x0183, 9}, {0x3042, 14}, - {0x3043, 14}, {0x000D, 4}, {0x0007, 3}, {0x0019, 5}, - {0x0031, 6}, {0x00C2, 8}, {0x00C3, 8}, {0x3044, 14}, - {0x3045, 14}, {0x3046, 14}, {0x3047, 14}, {0x3048, 14}, - {0x3049, 14}, {0x304A, 14}, {0x304B, 14}, {0x304C, 14}, - {0x304D, 14}, {0x1827, 13}, - },{//7 - {0x0000, 6}, {0x0001, 6}, {0x0002, 6}, {0x0006, 7}, - {0x0007, 7}, {0x0004, 6}, {0x0005, 6}, {0x0006, 6}, - {0x000E, 7}, {0x001E, 8}, {0x001F, 8}, {0x0040, 9}, - {0x0082, 10}, {0x0830, 14}, {0x0831, 14}, {0x0832, 14}, - {0x0833, 14}, {0x0001, 1}, {0x0001, 2}, {0x0003, 4}, - {0x0005, 5}, {0x0009, 6}, {0x0011, 7}, {0x0021, 8}, - {0x0834, 14}, {0x0835, 14}, {0x0836, 14}, {0x0837, 14}, - {0x0838, 14}, {0x0839, 14}, {0x083A, 14}, {0x083B, 14}, - {0x041E, 13}, {0x041F, 13}, - } -}; - -static const uint16_t x8_dc_highquant_table[8][34][2]={ - {//0 - {0x0000, 5}, {0x0001, 4}, {0x0002, 4}, {0x0001, 5}, - {0x0006, 5}, {0x0004, 4}, {0x0007, 5}, {0x000A, 5}, - {0x002C, 7}, {0x002D, 7}, {0x05C0, 12}, {0x05C1, 12}, - {0x05C2, 12}, {0x05C3, 12}, {0x05C4, 12}, {0x05C5, 12}, - {0x05C6, 12}, {0x0003, 3}, {0x0002, 2}, {0x0006, 3}, - {0x000E, 4}, {0x001E, 5}, {0x001F, 5}, {0x002F, 7}, - {0x005D, 8}, {0x05C7, 12}, {0x05C8, 12}, {0x05C9, 12}, - {0x05CA, 12}, {0x05CB, 12}, {0x05CC, 12}, {0x05CD, 12}, - {0x05CE, 12}, {0x05CF, 12}, - },{//1 - {0x0000, 3}, {0x0001, 3}, {0x0002, 3}, {0x0006, 4}, - {0x0007, 4}, {0x0004, 3}, {0x000A, 4}, {0x000B, 4}, - {0x0030, 6}, {0x0062, 7}, {0x0063, 7}, {0x0640, 11}, - {0x0641, 11}, {0x0642, 11}, {0x0643, 11}, {0x0644, 11}, - {0x0645, 11}, {0x0033, 6}, {0x000D, 4}, {0x001C, 5}, - {0x001D, 5}, {0x003C, 6}, {0x001F, 5}, {0x0065, 7}, - {0x007A, 7}, {0x0646, 11}, {0x007B, 7}, {0x0647, 11}, - {0x0648, 11}, {0x0649, 11}, {0x064A, 11}, {0x064B, 11}, - {0x0326, 10}, {0x0327, 10}, - },{//2 - {0x0000, 7}, {0x0001, 7}, {0x0001, 6}, {0x0004, 7}, - {0x0003, 6}, {0x0005, 7}, {0x0010, 8}, {0x0011, 8}, - {0x0240, 13}, {0x0241, 13}, {0x0242, 13}, {0x0243, 13}, - {0x0244, 13}, {0x0245, 13}, {0x0246, 13}, {0x0247, 13}, - {0x0124, 12}, {0x0001, 1}, {0x0001, 2}, {0x0001, 3}, - {0x0003, 5}, {0x0005, 6}, {0x0013, 8}, {0x0125, 12}, - {0x0126, 12}, {0x0127, 12}, {0x0128, 12}, {0x0129, 12}, - {0x012A, 12}, {0x012B, 12}, {0x012C, 12}, {0x012D, 12}, - {0x012E, 12}, {0x012F, 12}, - },{//3 - {0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4}, - {0x0006, 4}, {0x0004, 3}, {0x0005, 3}, {0x0006, 3}, - {0x000E, 5}, {0x000F, 5}, {0x0070, 7}, {0x0710, 11}, - {0x0711, 11}, {0x0712, 11}, {0x0713, 11}, {0x0714, 11}, - {0x0715, 11}, {0x001D, 5}, {0x0072, 7}, {0x003C, 6}, - {0x003D, 6}, {0x0073, 7}, {0x007C, 7}, {0x007D, 7}, - {0x007E, 7}, {0x0716, 11}, {0x0717, 11}, {0x0718, 11}, - {0x007F, 7}, {0x0719, 11}, {0x071A, 11}, {0x071B, 11}, - {0x038E, 10}, {0x038F, 10}, - },{//4 - {0x0000, 8}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7}, - {0x0002, 9}, {0x0008, 8}, {0x0003, 9}, {0x0240, 14}, - {0x0241, 14}, {0x0242, 14}, {0x0243, 14}, {0x0244, 14}, - {0x0245, 14}, {0x0246, 14}, {0x0247, 14}, {0x0124, 13}, - {0x0125, 13}, {0x0001, 2}, {0x0001, 1}, {0x0001, 3}, - {0x0001, 4}, {0x0003, 6}, {0x0005, 7}, {0x0013, 9}, - {0x0126, 13}, {0x0127, 13}, {0x0128, 13}, {0x0129, 13}, - {0x012A, 13}, {0x012B, 13}, {0x012C, 13}, {0x012D, 13}, - {0x012E, 13}, {0x012F, 13}, - },{//5 - {0x0000, 7}, {0x0001, 7}, {0x0001, 6}, {0x0002, 6}, - {0x0003, 6}, {0x0004, 6}, {0x0005, 6}, {0x0006, 6}, - {0x0007, 6}, {0x0008, 6}, {0x0009, 6}, {0x000A, 6}, - {0x000B, 6}, {0x000C, 6}, {0x000D, 6}, {0x000E, 6}, - {0x000F, 6}, {0x0010, 6}, {0x0011, 6}, {0x0012, 6}, - {0x0013, 6}, {0x0014, 6}, {0x0015, 6}, {0x0016, 6}, - {0x0017, 6}, {0x0018, 6}, {0x0019, 6}, {0x0001, 1}, - {0x001A, 6}, {0x001B, 6}, {0x001C, 6}, {0x001D, 6}, - {0x001E, 6}, {0x001F, 6}, - },{//6 - {0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0004, 5}, - {0x000A, 6}, {0x0006, 5}, {0x000B, 6}, {0x000E, 6}, - {0x003C, 8}, {0x003D, 8}, {0x07C0, 13}, {0x07C1, 13}, - {0x07C2, 13}, {0x07C3, 13}, {0x07C4, 13}, {0x07C5, 13}, - {0x07C6, 13}, {0x0001, 2}, {0x0002, 2}, {0x0006, 3}, - {0x000E, 4}, {0x001E, 5}, {0x001F, 5}, {0x003F, 8}, - {0x007D, 9}, {0x07C7, 13}, {0x07C8, 13}, {0x07C9, 13}, - {0x07CA, 13}, {0x07CB, 13}, {0x07CC, 13}, {0x07CD, 13}, - {0x07CE, 13}, {0x07CF, 13}, - },{//7 - {0x0000, 7}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7}, - {0x0004, 7}, {0x0005, 7}, {0x0006, 7}, {0x0007, 7}, - {0x0008, 7}, {0x0009, 7}, {0x000A, 7}, {0x000B, 7}, - {0x000C, 7}, {0x000D, 7}, {0x000E, 7}, {0x000F, 7}, - {0x0010, 7}, {0x0001, 1}, {0x0001, 2}, {0x0011, 7}, - {0x0012, 7}, {0x0013, 7}, {0x0014, 7}, {0x0015, 7}, - {0x0016, 7}, {0x0017, 7}, {0x0018, 7}, {0x0019, 7}, - {0x001A, 7}, {0x001B, 7}, {0x001C, 7}, {0x001D, 7}, - {0x001E, 7}, {0x001F, 7}, - } -}; -#define MAX_DC_VLC_BITS 14 - - -static const uint16_t x8_ac0_lowquant_table[8][77][2]={ - {//0 - {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, - {0x001E, 6}, {0x003E, 7}, {0x003F, 7}, {0x0040, 7}, - {0x0104, 9}, {0x0083, 8}, {0x0084, 8}, {0x0085, 8}, - {0x020A, 10}, {0x020B, 10}, {0x0218, 10}, {0x0219, 10}, - {0x0009, 4}, {0x0044, 7}, {0x010D, 9}, {0x021C, 10}, - {0x0023, 6}, {0x0045, 7}, {0x0050, 7}, {0x000B, 4}, - {0x000C, 4}, {0x0015, 5}, {0x001A, 5}, {0x001B, 5}, - {0x0029, 6}, {0x0038, 6}, {0x0039, 6}, {0x003A, 6}, - {0x0051, 7}, {0x0076, 7}, {0x0077, 7}, {0x0078, 7}, - {0x0079, 7}, {0x007A, 7}, {0x007B, 7}, {0x00F8, 8}, - {0x010F, 9}, {0x021D, 10}, {0x3E40, 14}, {0x3E41, 14}, - {0x3E42, 14}, {0x3E43, 14}, {0x03E5, 10}, {0x3E44, 14}, - {0x01F3, 9}, {0x3E45, 14}, {0x3E46, 14}, {0x3E47, 14}, - {0x00FA, 8}, {0x3E48, 14}, {0x3E49, 14}, {0x3E4A, 14}, - {0x3E4B, 14}, {0x03EC, 10}, {0x3E4C, 14}, {0x007E, 7}, - {0x00FE, 8}, {0x00FF, 8}, {0x01F7, 9}, {0x3E4D, 14}, - {0x3E4E, 14}, {0x3E4F, 14}, {0x3ED0, 14}, {0x3ED1, 14}, - {0x3ED2, 14}, {0x3ED3, 14}, {0x3ED4, 14}, {0x3ED5, 14}, - {0x1F6B, 13}, {0x1F6C, 13}, {0x1F6D, 13}, {0x1F6E, 13}, - {0x1F6F, 13}, - },{//1 - {0x0000, 3}, {0x0004, 5}, {0x0014, 7}, {0x000B, 6}, - {0x000C, 6}, {0x002A, 8}, {0x002B, 8}, {0x0034, 8}, - {0x0D40, 14}, {0x0D41, 14}, {0x001B, 7}, {0x0D42, 14}, - {0x0D43, 14}, {0x0D44, 14}, {0x0D45, 14}, {0x0D46, 14}, - {0x000E, 6}, {0x003C, 8}, {0x0D47, 14}, {0x003D, 8}, - {0x0D48, 14}, {0x0D49, 14}, {0x0D4A, 14}, {0x0001, 2}, - {0x0004, 3}, {0x0014, 5}, {0x000B, 4}, {0x000C, 4}, - {0x000D, 4}, {0x002A, 6}, {0x001F, 7}, {0x0056, 7}, - {0x0057, 7}, {0x0070, 7}, {0x00E2, 8}, {0x0072, 7}, - {0x003A, 6}, {0x003B, 6}, {0x003C, 6}, {0x003D, 6}, - {0x00E3, 8}, {0x0D4B, 14}, {0x00E6, 8}, {0x00E7, 8}, - {0x00F8, 8}, {0x0D4C, 14}, {0x0D4D, 14}, {0x0D4E, 14}, - {0x00F9, 8}, {0x0D4F, 14}, {0x0D50, 14}, {0x0D51, 14}, - {0x06A9, 13}, {0x06AA, 13}, {0x06AB, 13}, {0x06AC, 13}, - {0x06AD, 13}, {0x06AE, 13}, {0x06AF, 13}, {0x003F, 6}, - {0x06B0, 13}, {0x06B1, 13}, {0x06B2, 13}, {0x06B3, 13}, - {0x06B4, 13}, {0x007D, 7}, {0x06B5, 13}, {0x06B6, 13}, - {0x06B7, 13}, {0x06B8, 13}, {0x06B9, 13}, {0x06BA, 13}, - {0x06BB, 13}, {0x06BC, 13}, {0x06BD, 13}, {0x06BE, 13}, - {0x06BF, 13}, - },{//2 - {0x0000, 2}, {0x0002, 3}, {0x0003, 3}, {0x0008, 4}, - {0x0012, 5}, {0x0013, 5}, {0x0028, 6}, {0x0029, 6}, - {0x0054, 7}, {0x0055, 7}, {0x0056, 7}, {0x00AE, 8}, - {0x00AF, 8}, {0x00B0, 8}, {0x0162, 9}, {0x02C6, 10}, - {0x000C, 4}, {0x002D, 6}, {0x00B2, 8}, {0x0166, 9}, - {0x002E, 6}, {0x0167, 9}, {0x00BC, 8}, {0x001A, 5}, - {0x0036, 6}, {0x0037, 6}, {0x0038, 6}, {0x005F, 7}, - {0x0072, 7}, {0x0073, 7}, {0x0074, 7}, {0x0075, 7}, - {0x0076, 7}, {0x0077, 7}, {0x0078, 7}, {0x0079, 7}, - {0x007A, 7}, {0x007B, 7}, {0x00BD, 8}, {0xB1C0, 16}, - {0xB1C1, 16}, {0x58E1, 15}, {0x0B1D, 12}, {0x58E2, 15}, - {0x58E3, 15}, {0x58E4, 15}, {0x00F8, 8}, {0x03E4, 10}, - {0x01F3, 9}, {0x0B1E, 12}, {0x58E5, 15}, {0x58E6, 15}, - {0x00FA, 8}, {0x58E7, 15}, {0x58F8, 15}, {0x58F9, 15}, - {0x58FA, 15}, {0x01F6, 9}, {0x58FB, 15}, {0x007E, 7}, - {0x00FE, 8}, {0x00FF, 8}, {0x07CA, 11}, {0x0F96, 12}, - {0x58FC, 15}, {0x58FD, 15}, {0x58FE, 15}, {0x58FF, 15}, - {0x7CB8, 15}, {0x7CB9, 15}, {0x7CBA, 15}, {0x7CBB, 15}, - {0x7CBC, 15}, {0x01F7, 9}, {0x7CBD, 15}, {0x7CBE, 15}, - {0x7CBF, 15}, - },{//3 - {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, - {0x000F, 5}, {0x0020, 6}, {0x0021, 6}, {0x0044, 7}, - {0x0045, 7}, {0x008C, 8}, {0x008D, 8}, {0x011C, 9}, - {0x011D, 9}, {0x011E, 9}, {0x023E, 10}, {0x023F, 10}, - {0x0005, 3}, {0x0012, 5}, {0x004C, 7}, {0x004D, 7}, - {0x000C, 4}, {0x004E, 7}, {0x001A, 5}, {0x0036, 6}, - {0x004F, 7}, {0x006E, 7}, {0x006F, 7}, {0x00E0, 8}, - {0x00E1, 8}, {0x00E2, 8}, {0x00E3, 8}, {0x00E4, 8}, - {0x00E5, 8}, {0x01CC, 9}, {0x00E7, 8}, {0x00E8, 8}, - {0x00E9, 8}, {0x01CD, 9}, {0x0750, 11}, {0x03A9, 10}, - {0x0751, 11}, {0x7540, 15}, {0x03AB, 10}, {0x7541, 15}, - {0x7542, 15}, {0x7543, 15}, {0x01D6, 9}, {0x0755, 11}, - {0x0076, 7}, {0x0EA9, 12}, {0x7544, 15}, {0x7545, 15}, - {0x001E, 5}, {0x0077, 7}, {0x00F8, 8}, {0x03AE, 10}, - {0x075E, 11}, {0x007D, 7}, {0x03E4, 10}, {0x00FC, 8}, - {0x00FD, 8}, {0x03E5, 10}, {0x03E6, 10}, {0x0EBE, 12}, - {0x7546, 15}, {0x07CE, 11}, {0x7547, 15}, {0x75F8, 15}, - {0x75F9, 15}, {0x75FA, 15}, {0x75FB, 15}, {0x75FC, 15}, - {0x75FD, 15}, {0x007F, 7}, {0x3AFF, 14}, {0x0F9E, 12}, - {0x0F9F, 12}, - },{//4 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, - {0x0012, 6}, {0x0013, 6}, {0x0014, 6}, {0x002A, 7}, - {0x0016, 6}, {0x002B, 7}, {0x005C, 8}, {0x005D, 8}, - {0x005E, 8}, {0x00BE, 9}, {0x00BF, 9}, {0x0060, 8}, - {0x0007, 4}, {0x000D, 5}, {0x0019, 6}, {0x0020, 6}, - {0x0009, 4}, {0x0021, 6}, {0x0011, 5}, {0x0014, 5}, - {0x002A, 6}, {0x002B, 6}, {0x002C, 6}, {0x002D, 6}, - {0x002E, 6}, {0x002F, 6}, {0x0030, 6}, {0x0031, 7}, - {0x0062, 7}, {0x0063, 7}, {0x0064, 7}, {0x0065, 7}, - {0x0066, 7}, {0x0061, 8}, {0x0670, 11}, {0x0068, 7}, - {0x0069, 7}, {0x00CF, 8}, {0x019D, 9}, {0x01A8, 9}, - {0x01A9, 9}, {0x0339, 10}, {0x01AA, 9}, {0x0356, 10}, - {0x0036, 6}, {0x00D6, 8}, {0x6710, 15}, {0x6711, 15}, - {0x000E, 4}, {0x006E, 7}, {0x01AE, 9}, {0x6712, 15}, - {0x6713, 15}, {0x003C, 6}, {0x0357, 10}, {0x006F, 7}, - {0x00F4, 8}, {0x00F5, 8}, {0x035E, 10}, {0x01EC, 9}, - {0x6714, 15}, {0x01ED, 9}, {0x035F, 10}, {0x03DC, 10}, - {0x03DD, 10}, {0x6715, 15}, {0x338B, 14}, {0x338C, 14}, - {0x338D, 14}, {0x001F, 5}, {0x01EF, 9}, {0x338E, 14}, - {0x338F, 14}, - },{//5 - {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, - {0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x006A, 8}, - {0x006B, 8}, {0x006C, 8}, {0x00DA, 9}, {0x036C, 11}, - {0x006E, 8}, {0x01B7, 10}, {0x036D, 11}, {0x3780, 15}, - {0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x003E, 7}, - {0x000A, 4}, {0x002C, 6}, {0x0017, 5}, {0x002D, 6}, - {0x003F, 7}, {0x00C0, 8}, {0x0061, 7}, {0x00C1, 8}, - {0x0062, 7}, {0x00C6, 8}, {0x0064, 7}, {0x00C7, 8}, - {0x00CA, 8}, {0x00DF, 9}, {0x0196, 9}, {0x0197, 9}, - {0x0198, 9}, {0x0199, 9}, {0x0379, 11}, {0x019A, 9}, - {0x01BD, 10}, {0x066C, 11}, {0x3781, 15}, {0x0337, 10}, - {0x066D, 11}, {0x0670, 11}, {0x0339, 10}, {0x0671, 11}, - {0x0034, 6}, {0x00CF, 8}, {0x3782, 15}, {0x3783, 15}, - {0x000E, 4}, {0x001B, 5}, {0x006A, 7}, {0x006B, 7}, - {0x019D, 9}, {0x003C, 6}, {0x00F4, 8}, {0x00F5, 8}, - {0x03D8, 10}, {0x07B2, 11}, {0x3784, 15}, {0x03DA, 10}, - {0x3785, 15}, {0x03DB, 10}, {0x03DC, 10}, {0x3786, 15}, - {0x3787, 15}, {0x1BC4, 14}, {0x1BC5, 14}, {0x1BC6, 14}, - {0x1BC7, 14}, {0x001F, 5}, {0x03DD, 10}, {0x07B3, 11}, - {0x01EF, 9}, - },{//6 - {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6}, - {0x0017, 6}, {0x0060, 8}, {0x00C2, 9}, {0x0186, 10}, - {0x0187, 10}, {0x00C4, 9}, {0x3140, 15}, {0x3141, 15}, - {0x018B, 10}, {0x3142, 15}, {0x018C, 10}, {0x3143, 15}, - {0x0007, 4}, {0x000D, 5}, {0x0064, 8}, {0x0065, 8}, - {0x0010, 5}, {0x00C7, 9}, {0x0066, 8}, {0x0005, 3}, - {0x0006, 3}, {0x0009, 4}, {0x0011, 5}, {0x0038, 6}, - {0x0039, 6}, {0x0074, 7}, {0x0075, 7}, {0x0076, 7}, - {0x0067, 8}, {0x00EE, 8}, {0x01DE, 9}, {0x00F0, 8}, - {0x018D, 10}, {0x3144, 15}, {0x01DF, 9}, {0x003D, 6}, - {0x003E, 6}, {0x01E2, 9}, {0x03C6, 10}, {0x00F2, 8}, - {0x00F3, 8}, {0x03C7, 10}, {0x3145, 15}, {0x3146, 15}, - {0x01F8, 9}, {0x3147, 15}, {0x3148, 15}, {0x3149, 15}, - {0x00FD, 8}, {0x314A, 15}, {0x314B, 15}, {0x314C, 15}, - {0x314D, 15}, {0x01F9, 9}, {0x314E, 15}, {0x01FC, 9}, - {0x314F, 15}, {0x3150, 15}, {0x3151, 15}, {0x3152, 15}, - {0x3153, 15}, {0x03FA, 10}, {0x03FB, 10}, {0x3154, 15}, - {0x3155, 15}, {0x3156, 15}, {0x3157, 15}, {0x3158, 15}, - {0x3159, 15}, {0x00FF, 8}, {0x18AD, 14}, {0x18AE, 14}, - {0x18AF, 14}, - },{//7 - {0x0000, 4}, {0x0080, 11}, {0x0081, 11}, {0x0082, 11}, - {0x0083, 11}, {0x0084, 11}, {0x0085, 11}, {0x0086, 11}, - {0x0087, 11}, {0x0088, 11}, {0x0089, 11}, {0x008A, 11}, - {0x008B, 11}, {0x008C, 11}, {0x008D, 11}, {0x008E, 11}, - {0x008F, 11}, {0x0048, 10}, {0x0049, 10}, {0x004A, 10}, - {0x004B, 10}, {0x004C, 10}, {0x004D, 10}, {0x0001, 1}, - {0x0001, 2}, {0x004E, 10}, {0x0002, 4}, {0x0003, 4}, - {0x004F, 10}, {0x0050, 10}, {0x0051, 10}, {0x0052, 10}, - {0x0053, 10}, {0x0054, 10}, {0x0055, 10}, {0x0056, 10}, - {0x0057, 10}, {0x0058, 10}, {0x0059, 10}, {0x005A, 10}, - {0x005B, 10}, {0x005C, 10}, {0x005D, 10}, {0x005E, 10}, - {0x005F, 10}, {0x0060, 10}, {0x0061, 10}, {0x0062, 10}, - {0x0063, 10}, {0x0064, 10}, {0x0065, 10}, {0x0066, 10}, - {0x0067, 10}, {0x0068, 10}, {0x0069, 10}, {0x006A, 10}, - {0x006B, 10}, {0x006C, 10}, {0x006D, 10}, {0x006E, 10}, - {0x006F, 10}, {0x0070, 10}, {0x0071, 10}, {0x0072, 10}, - {0x0073, 10}, {0x0074, 10}, {0x0075, 10}, {0x0076, 10}, - {0x0077, 10}, {0x0078, 10}, {0x0079, 10}, {0x007A, 10}, - {0x007B, 10}, {0x007C, 10}, {0x007D, 10}, {0x007E, 10}, - {0x007F, 10}, - } -}; - -static const uint16_t x8_ac0_highquant_table[8][77][2]={ - {//0 - {0x0000, 3}, {0x0002, 4}, {0x000C, 6}, {0x000D, 6}, - {0x001C, 7}, {0x000F, 6}, {0x1D00, 15}, {0x003B, 8}, - {0x1D01, 15}, {0x0075, 9}, {0x1D02, 15}, {0x0080, 9}, - {0x1D03, 15}, {0x1D04, 15}, {0x1D05, 15}, {0x0E83, 14}, - {0x0009, 5}, {0x0011, 6}, {0x0081, 9}, {0x0082, 9}, - {0x0021, 7}, {0x0028, 7}, {0x0083, 9}, {0x0002, 2}, - {0x0003, 3}, {0x000C, 4}, {0x000D, 4}, {0x000B, 5}, - {0x0015, 6}, {0x0052, 8}, {0x0070, 7}, {0x0039, 6}, - {0x0071, 7}, {0x0053, 8}, {0x0E84, 14}, {0x0074, 7}, - {0x0075, 7}, {0x0076, 7}, {0x01DC, 9}, {0x001E, 5}, - {0x003E, 6}, {0x01DD, 9}, {0x00EF, 8}, {0x01F8, 9}, - {0x01F9, 9}, {0x0E85, 14}, {0x0E86, 14}, {0x0E87, 14}, - {0x00FD, 8}, {0x0E88, 14}, {0x0E89, 14}, {0x0E8A, 14}, - {0x0E8B, 14}, {0x0E8C, 14}, {0x0E8D, 14}, {0x0E8E, 14}, - {0x0E8F, 14}, {0x0E90, 14}, {0x0E91, 14}, {0x01FC, 9}, - {0x0E92, 14}, {0x0E93, 14}, {0x0E94, 14}, {0x0E95, 14}, - {0x0E96, 14}, {0x0E97, 14}, {0x01FD, 9}, {0x0E98, 14}, - {0x01FE, 9}, {0x0E99, 14}, {0x0E9A, 14}, {0x0E9B, 14}, - {0x0E9C, 14}, {0x01FF, 9}, {0x0E9D, 14}, {0x0E9E, 14}, - {0x0E9F, 14}, - },{//1 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, - {0x0012, 6}, {0x0013, 6}, {0x0014, 6}, {0x0015, 6}, - {0x002C, 7}, {0x005A, 8}, {0x005B, 8}, {0x005C, 8}, - {0x005D, 8}, {0x1780, 14}, {0x0179, 10}, {0x017A, 10}, - {0x0006, 4}, {0x000E, 5}, {0x001E, 6}, {0x003E, 7}, - {0x0010, 5}, {0x0022, 6}, {0x0012, 5}, {0x000A, 4}, - {0x0013, 5}, {0x0016, 5}, {0x0023, 6}, {0x002E, 6}, - {0x002F, 6}, {0x0030, 6}, {0x0031, 6}, {0x003F, 7}, - {0x005F, 8}, {0x00C8, 8}, {0x0065, 7}, {0x0066, 7}, - {0x0067, 7}, {0x0068, 7}, {0x00C9, 8}, {0x0069, 7}, - {0x006A, 7}, {0x00D6, 8}, {0x00D7, 8}, {0x00D8, 8}, - {0x1781, 14}, {0x017B, 10}, {0x01B2, 9}, {0x1782, 14}, - {0x001C, 5}, {0x01B3, 9}, {0x1783, 14}, {0x1784, 14}, - {0x001D, 5}, {0x00DA, 8}, {0x1785, 14}, {0x1786, 14}, - {0x1787, 14}, {0x0037, 6}, {0x00DB, 8}, {0x0078, 7}, - {0x00F2, 8}, {0x01E6, 9}, {0x00F4, 8}, {0x1788, 14}, - {0x1789, 14}, {0x00F5, 8}, {0x01E7, 9}, {0x178A, 14}, - {0x178B, 14}, {0x178C, 14}, {0x178D, 14}, {0x01EC, 9}, - {0x178E, 14}, {0x001F, 5}, {0x00F7, 8}, {0x01ED, 9}, - {0x178F, 14}, - },{//2 - {0x0000, 4}, {0x0002, 5}, {0x0180, 12}, {0x0181, 12}, - {0x0182, 12}, {0x0183, 12}, {0x0184, 12}, {0x0185, 12}, - {0x0186, 12}, {0x0187, 12}, {0x0188, 12}, {0x0189, 12}, - {0x00C5, 11}, {0x00C6, 11}, {0x00C7, 11}, {0x00C8, 11}, - {0x00C9, 11}, {0x00CA, 11}, {0x00CB, 11}, {0x00CC, 11}, - {0x00CD, 11}, {0x00CE, 11}, {0x00CF, 11}, {0x0001, 1}, - {0x0001, 2}, {0x0004, 5}, {0x0005, 5}, {0x0006, 5}, - {0x00D0, 11}, {0x00D1, 11}, {0x00D2, 11}, {0x00D3, 11}, - {0x00D4, 11}, {0x00D5, 11}, {0x00D6, 11}, {0x00D7, 11}, - {0x00D8, 11}, {0x00D9, 11}, {0x00DA, 11}, {0x0007, 5}, - {0x00DB, 11}, {0x00DC, 11}, {0x00DD, 11}, {0x00DE, 11}, - {0x00DF, 11}, {0x00E0, 11}, {0x00E1, 11}, {0x00E2, 11}, - {0x00E3, 11}, {0x00E4, 11}, {0x00E5, 11}, {0x00E6, 11}, - {0x00E7, 11}, {0x00E8, 11}, {0x00E9, 11}, {0x00EA, 11}, - {0x00EB, 11}, {0x00EC, 11}, {0x00ED, 11}, {0x00EE, 11}, - {0x00EF, 11}, {0x00F0, 11}, {0x00F1, 11}, {0x00F2, 11}, - {0x00F3, 11}, {0x00F4, 11}, {0x00F5, 11}, {0x00F6, 11}, - {0x00F7, 11}, {0x00F8, 11}, {0x00F9, 11}, {0x00FA, 11}, - {0x00FB, 11}, {0x00FC, 11}, {0x00FD, 11}, {0x00FE, 11}, - {0x00FF, 11}, - },{//3 - {0x0000, 8}, {0x0001, 8}, {0x0002, 8}, {0x0003, 8}, - {0x0004, 8}, {0x0005, 8}, {0x0006, 8}, {0x0007, 8}, - {0x0008, 8}, {0x0009, 8}, {0x000A, 8}, {0x000B, 8}, - {0x000C, 8}, {0x000D, 8}, {0x000E, 8}, {0x000F, 8}, - {0x0010, 8}, {0x0011, 8}, {0x0012, 8}, {0x0013, 8}, - {0x0014, 8}, {0x0015, 8}, {0x0016, 8}, {0x0001, 1}, - {0x0017, 8}, {0x000C, 7}, {0x000D, 7}, {0x000E, 7}, - {0x000F, 7}, {0x0010, 7}, {0x0011, 7}, {0x0012, 7}, - {0x0013, 7}, {0x0014, 7}, {0x0015, 7}, {0x0016, 7}, - {0x0017, 7}, {0x0018, 7}, {0x0019, 7}, {0x001A, 7}, - {0x001B, 7}, {0x001C, 7}, {0x001D, 7}, {0x001E, 7}, - {0x001F, 7}, {0x0020, 7}, {0x0021, 7}, {0x0022, 7}, - {0x0023, 7}, {0x0024, 7}, {0x0025, 7}, {0x0026, 7}, - {0x0027, 7}, {0x0028, 7}, {0x0029, 7}, {0x002A, 7}, - {0x002B, 7}, {0x002C, 7}, {0x002D, 7}, {0x002E, 7}, - {0x002F, 7}, {0x0030, 7}, {0x0031, 7}, {0x0032, 7}, - {0x0033, 7}, {0x0034, 7}, {0x0035, 7}, {0x0036, 7}, - {0x0037, 7}, {0x0038, 7}, {0x0039, 7}, {0x003A, 7}, - {0x003B, 7}, {0x003C, 7}, {0x003D, 7}, {0x003E, 7}, - {0x003F, 7}, - },{//4 - {0x0000, 9}, {0x0001, 9}, {0x0002, 9}, {0x0003, 9}, - {0x0004, 9}, {0x0005, 9}, {0x0006, 9}, {0x0007, 9}, - {0x0008, 9}, {0x0009, 9}, {0x000A, 9}, {0x000B, 9}, - {0x000C, 9}, {0x000D, 9}, {0x000E, 9}, {0x000F, 9}, - {0x0010, 9}, {0x0011, 9}, {0x0012, 9}, {0x0013, 9}, - {0x0014, 9}, {0x0015, 9}, {0x000B, 8}, {0x0001, 2}, - {0x0001, 1}, {0x000C, 8}, {0x000D, 8}, {0x000E, 8}, - {0x000F, 8}, {0x0010, 8}, {0x0011, 8}, {0x0012, 8}, - {0x0013, 8}, {0x0014, 8}, {0x0015, 8}, {0x0016, 8}, - {0x0017, 8}, {0x0018, 8}, {0x0019, 8}, {0x001A, 8}, - {0x001B, 8}, {0x001C, 8}, {0x001D, 8}, {0x001E, 8}, - {0x001F, 8}, {0x0020, 8}, {0x0021, 8}, {0x0022, 8}, - {0x0023, 8}, {0x0024, 8}, {0x0025, 8}, {0x0026, 8}, - {0x0027, 8}, {0x0028, 8}, {0x0029, 8}, {0x002A, 8}, - {0x002B, 8}, {0x002C, 8}, {0x002D, 8}, {0x002E, 8}, - {0x002F, 8}, {0x0030, 8}, {0x0031, 8}, {0x0032, 8}, - {0x0033, 8}, {0x0034, 8}, {0x0035, 8}, {0x0036, 8}, - {0x0037, 8}, {0x0038, 8}, {0x0039, 8}, {0x003A, 8}, - {0x003B, 8}, {0x003C, 8}, {0x003D, 8}, {0x003E, 8}, - {0x003F, 8}, - },{//5 - {0x0000, 10}, {0x0001, 10}, {0x0002, 10}, {0x0003, 10}, - {0x0004, 10}, {0x0005, 10}, {0x0006, 10}, {0x0007, 10}, - {0x0008, 10}, {0x0009, 10}, {0x000A, 10}, {0x000B, 10}, - {0x000C, 10}, {0x000D, 10}, {0x000E, 10}, {0x000F, 10}, - {0x0010, 10}, {0x0011, 10}, {0x0012, 10}, {0x0013, 10}, - {0x000A, 9}, {0x000B, 9}, {0x000C, 9}, {0x0001, 1}, - {0x0001, 3}, {0x000D, 9}, {0x000E, 9}, {0x0001, 2}, - {0x000F, 9}, {0x0010, 9}, {0x0011, 9}, {0x0012, 9}, - {0x0013, 9}, {0x0014, 9}, {0x0015, 9}, {0x0016, 9}, - {0x0017, 9}, {0x0018, 9}, {0x0019, 9}, {0x001A, 9}, - {0x001B, 9}, {0x001C, 9}, {0x001D, 9}, {0x001E, 9}, - {0x001F, 9}, {0x0020, 9}, {0x0021, 9}, {0x0022, 9}, - {0x0023, 9}, {0x0024, 9}, {0x0025, 9}, {0x0026, 9}, - {0x0027, 9}, {0x0028, 9}, {0x0029, 9}, {0x002A, 9}, - {0x002B, 9}, {0x002C, 9}, {0x002D, 9}, {0x002E, 9}, - {0x002F, 9}, {0x0030, 9}, {0x0031, 9}, {0x0032, 9}, - {0x0033, 9}, {0x0034, 9}, {0x0035, 9}, {0x0036, 9}, - {0x0037, 9}, {0x0038, 9}, {0x0039, 9}, {0x003A, 9}, - {0x003B, 9}, {0x003C, 9}, {0x003D, 9}, {0x003E, 9}, - {0x003F, 9}, - },{//6 - {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, - {0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x006A, 8}, - {0x006B, 8}, {0x006C, 8}, {0x00DA, 9}, {0x00DB, 9}, - {0x01B8, 10}, {0x00DD, 9}, {0x01B9, 10}, {0x3780, 15}, - {0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x001F, 6}, - {0x000A, 4}, {0x0058, 7}, {0x0017, 5}, {0x0018, 5}, - {0x0059, 7}, {0x005A, 7}, {0x005B, 7}, {0x00C8, 8}, - {0x0065, 7}, {0x0066, 7}, {0x00C9, 8}, {0x00CE, 8}, - {0x00CF, 8}, {0x00D0, 8}, {0x00D1, 8}, {0x00D2, 8}, - {0x00D3, 8}, {0x00DF, 9}, {0x00D4, 8}, {0x00D5, 8}, - {0x00D6, 8}, {0x01AE, 9}, {0x3781, 15}, {0x01BD, 10}, - {0x035E, 10}, {0x035F, 10}, {0x3782, 15}, {0x0360, 10}, - {0x0037, 6}, {0x01B1, 9}, {0x3783, 15}, {0x3784, 15}, - {0x000E, 4}, {0x003C, 6}, {0x0361, 10}, {0x3785, 15}, - {0x1BC3, 14}, {0x003D, 6}, {0x00D9, 8}, {0x1BC4, 14}, - {0x0368, 10}, {0x1BC5, 14}, {0x1BC6, 14}, {0x1BC7, 14}, - {0x1BC8, 14}, {0x00DB, 8}, {0x0369, 10}, {0x036A, 10}, - {0x1BC9, 14}, {0x1BCA, 14}, {0x1BCB, 14}, {0x1BCC, 14}, - {0x1BCD, 14}, {0x001F, 5}, {0x036B, 10}, {0x1BCE, 14}, - {0x1BCF, 14}, - },{//7 - {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5}, - {0x0010, 6}, {0x0044, 8}, {0x0023, 7}, {0x0012, 6}, - {0x0026, 7}, {0x08A0, 13}, {0x004E, 8}, {0x004F, 8}, - {0x08A1, 13}, {0x08A2, 13}, {0x08A3, 13}, {0x0050, 8}, - {0x0006, 4}, {0x000B, 5}, {0x0029, 7}, {0x0015, 6}, - {0x001C, 6}, {0x003A, 7}, {0x001E, 6}, {0x0004, 3}, - {0x0014, 5}, {0x0015, 5}, {0x000B, 4}, {0x001F, 6}, - {0x0030, 6}, {0x0031, 6}, {0x0019, 5}, {0x0051, 8}, - {0x0034, 6}, {0x0035, 6}, {0x0036, 6}, {0x0037, 6}, - {0x0076, 8}, {0x0077, 8}, {0x0070, 7}, {0x001D, 5}, - {0x0071, 7}, {0x0072, 7}, {0x08A4, 13}, {0x0073, 7}, - {0x00F0, 8}, {0x08A5, 13}, {0x08A6, 13}, {0x08A7, 13}, - {0x0079, 7}, {0x007A, 7}, {0x08A8, 13}, {0x08A9, 13}, - {0x00F1, 8}, {0x08AA, 13}, {0x08AB, 13}, {0x08AC, 13}, - {0x08AD, 13}, {0x00F6, 8}, {0x08AE, 13}, {0x007C, 7}, - {0x00F7, 8}, {0x08AF, 13}, {0x08B0, 13}, {0x08B1, 13}, - {0x08B2, 13}, {0x00FA, 8}, {0x08B3, 13}, {0x08B4, 13}, - {0x08B5, 13}, {0x08B6, 13}, {0x08B7, 13}, {0x00FB, 8}, - {0x045C, 12}, {0x003F, 6}, {0x045D, 12}, {0x045E, 12}, - {0x045F, 12}, - } -}; - -static const uint16_t x8_ac1_lowquant_table[8][77][2]={ - {//0 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, - {0x0012, 6}, {0x0026, 7}, {0x0014, 6}, {0x004E, 8}, - {0x004F, 8}, {0x00A8, 9}, {0x0152, 10}, {0x00AA, 9}, - {0x00AB, 9}, {0x00AC, 9}, {0x2A60, 15}, {0x02A7, 11}, - {0x0006, 4}, {0x000B, 5}, {0x001C, 6}, {0x003A, 7}, - {0x000F, 5}, {0x003B, 7}, {0x0010, 5}, {0x0005, 3}, - {0x0009, 4}, {0x0011, 5}, {0x0018, 5}, {0x0019, 5}, - {0x001A, 5}, {0x0036, 6}, {0x0037, 6}, {0x0070, 7}, - {0x0057, 8}, {0x00E2, 8}, {0x00E3, 8}, {0x00E4, 8}, - {0x00E5, 8}, {0x00AD, 9}, {0x0398, 10}, {0x003A, 6}, - {0x0076, 7}, {0x00E7, 8}, {0x00EE, 8}, {0x00EF, 8}, - {0x0732, 11}, {0x039A, 10}, {0x0733, 11}, {0x2A61, 15}, - {0x0078, 7}, {0x1531, 14}, {0x1532, 14}, {0x1533, 14}, - {0x003D, 6}, {0x039B, 10}, {0x1534, 14}, {0x1535, 14}, - {0x1536, 14}, {0x0079, 7}, {0x1537, 14}, {0x00F8, 8}, - {0x01F2, 9}, {0x07CC, 11}, {0x03E7, 10}, {0x07CD, 11}, - {0x3E80, 14}, {0x00FB, 8}, {0x03E9, 10}, {0x3E81, 14}, - {0x3E82, 14}, {0x3E83, 14}, {0x3E84, 14}, {0x3E85, 14}, - {0x3E86, 14}, {0x003F, 6}, {0x01F5, 9}, {0x07D1, 11}, - {0x3E87, 14}, - },{//1 - {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, - {0x001E, 6}, {0x001F, 6}, {0x0040, 7}, {0x0082, 8}, - {0x0083, 8}, {0x0084, 8}, {0x010A, 9}, {0x010B, 9}, - {0x0430, 11}, {0x0431, 11}, {0x0432, 11}, {0x0433, 11}, - {0x0005, 3}, {0x0011, 5}, {0x0024, 6}, {0x004A, 7}, - {0x000C, 4}, {0x0026, 6}, {0x000D, 4}, {0x0087, 8}, - {0x010D, 9}, {0x0258, 10}, {0x012D, 9}, {0x0259, 10}, - {0x025C, 10}, {0x0974, 12}, {0x025E, 10}, {0x025F, 10}, - {0x0270, 10}, {0x0271, 10}, {0x04BB, 11}, {0x0975, 12}, - {0x0272, 10}, {0x09CC, 12}, {0x09CD, 12}, {0x4E70, 15}, - {0x4E71, 15}, {0x4E72, 15}, {0x4E73, 15}, {0x273A, 14}, - {0x273B, 14}, {0x273C, 14}, {0x04E8, 11}, {0x04E9, 11}, - {0x009E, 8}, {0x0275, 10}, {0x09D8, 12}, {0x273D, 14}, - {0x000E, 4}, {0x003C, 6}, {0x007A, 7}, {0x009F, 8}, - {0x0277, 10}, {0x003E, 6}, {0x00F6, 8}, {0x04ED, 11}, - {0x03DC, 10}, {0x273E, 14}, {0x07BA, 11}, {0x09D9, 12}, - {0x273F, 14}, {0x3DD8, 14}, {0x3DD9, 14}, {0x3DDA, 14}, - {0x3DDB, 14}, {0x3DDC, 14}, {0x3DDD, 14}, {0x3DDE, 14}, - {0x3DDF, 14}, {0x003F, 6}, {0x07BC, 11}, {0x07BD, 11}, - {0x03DF, 10}, - },{//2 - {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x000E, 6}, - {0x001E, 7}, {0x003E, 8}, {0x003F, 8}, {0x0040, 8}, - {0x0104, 10}, {0x0083, 9}, {0x0105, 10}, {0x0108, 10}, - {0x4240, 16}, {0x010A, 10}, {0x010B, 10}, {0x4241, 16}, - {0x0003, 3}, {0x0009, 5}, {0x0011, 6}, {0x0043, 8}, - {0x0004, 3}, {0x000A, 5}, {0x000A, 4}, {0x002C, 7}, - {0x00B4, 9}, {0x00B5, 9}, {0x00B6, 9}, {0x00B7, 9}, - {0x00B8, 9}, {0x0172, 10}, {0x0173, 10}, {0x0174, 10}, - {0x0175, 10}, {0x0176, 10}, {0x0177, 10}, {0x00BC, 9}, - {0x017A, 10}, {0x0213, 11}, {0x4242, 16}, {0x017B, 10}, - {0x02F8, 11}, {0x017D, 10}, {0x02F9, 11}, {0x017E, 10}, - {0x4243, 16}, {0x02FE, 11}, {0x2122, 15}, {0x2123, 15}, - {0x0058, 7}, {0x0164, 9}, {0x2124, 15}, {0x2125, 15}, - {0x0006, 3}, {0x000E, 4}, {0x002D, 6}, {0x002E, 6}, - {0x00B3, 8}, {0x001E, 5}, {0x005E, 7}, {0x2126, 15}, - {0x2127, 15}, {0x2128, 15}, {0x2129, 15}, {0x02FF, 11}, - {0x212A, 15}, {0x0594, 11}, {0x0595, 11}, {0x0596, 11}, - {0x212B, 15}, {0x212C, 15}, {0x212D, 15}, {0x212E, 15}, - {0x212F, 15}, {0x001F, 5}, {0x0597, 11}, {0x00BE, 8}, - {0x00BF, 8}, - },{//3 - {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x0007, 4}, - {0x0010, 5}, {0x0011, 5}, {0x0024, 6}, {0x0025, 6}, - {0x0026, 6}, {0x0027, 6}, {0x0050, 7}, {0x0051, 7}, - {0x00A4, 8}, {0x00A5, 8}, {0x00A6, 8}, {0x014E, 9}, - {0x000B, 4}, {0x002A, 6}, {0x0056, 7}, {0x014F, 9}, - {0x0030, 6}, {0x00AE, 8}, {0x0062, 7}, {0x0032, 6}, - {0x0033, 6}, {0x0034, 6}, {0x0035, 6}, {0x0036, 6}, - {0x0063, 7}, {0x006E, 7}, {0x006F, 7}, {0x0070, 7}, - {0x0071, 7}, {0x0072, 7}, {0x0073, 7}, {0x0074, 7}, - {0x00AF, 8}, {0x00EA, 8}, {0x01D6, 9}, {0x075C, 11}, - {0x03AF, 10}, {0x75D0, 15}, {0x75D1, 15}, {0x75D2, 15}, - {0x75D3, 15}, {0x75D4, 15}, {0x0076, 7}, {0x00EE, 8}, - {0x00EF, 8}, {0x0EBB, 12}, {0x01E0, 9}, {0x75D5, 15}, - {0x0079, 7}, {0x01E1, 9}, {0x75D6, 15}, {0x75D7, 15}, - {0x7880, 15}, {0x00F4, 8}, {0x0789, 11}, {0x003E, 6}, - {0x007B, 7}, {0x00F5, 8}, {0x00FC, 8}, {0x007F, 7}, - {0x01E3, 9}, {0x078A, 11}, {0x078B, 11}, {0x7881, 15}, - {0x7882, 15}, {0x7883, 15}, {0x3C42, 14}, {0x3C43, 14}, - {0x3C44, 14}, {0x00FD, 8}, {0x3C45, 14}, {0x3C46, 14}, - {0x3C47, 14}, - },{//4 - {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6}, - {0x0017, 6}, {0x0030, 7}, {0x0031, 7}, {0x0064, 8}, - {0x0065, 8}, {0x0066, 8}, {0x00CE, 9}, {0x00CF, 9}, - {0x01A0, 10}, {0x01A1, 10}, {0x1A20, 14}, {0x0689, 12}, - {0x0004, 3}, {0x000E, 5}, {0x001B, 6}, {0x0035, 7}, - {0x000A, 4}, {0x001E, 6}, {0x0016, 5}, {0x0017, 5}, - {0x001F, 6}, {0x0030, 6}, {0x0031, 6}, {0x0064, 7}, - {0x0065, 7}, {0x0069, 8}, {0x0066, 7}, {0x00CE, 8}, - {0x00CF, 8}, {0x00D0, 8}, {0x00D1, 8}, {0x00D2, 8}, - {0x01A6, 9}, {0x01A3, 10}, {0x034E, 10}, {0x006A, 7}, - {0x00D6, 8}, {0x01AE, 9}, {0x01AF, 9}, {0x034F, 10}, - {0x0345, 11}, {0x01B0, 9}, {0x01B1, 9}, {0x0364, 10}, - {0x006D, 7}, {0x00DC, 8}, {0x0D94, 12}, {0x0D95, 12}, - {0x000E, 4}, {0x003C, 6}, {0x00DD, 8}, {0x00DE, 8}, - {0x01B3, 9}, {0x003D, 6}, {0x00DF, 8}, {0x01F0, 9}, - {0x03E2, 10}, {0x03E3, 10}, {0x06CB, 11}, {0x03E4, 10}, - {0x07CA, 11}, {0x01F3, 9}, {0x01F4, 9}, {0x07CB, 11}, - {0x07D4, 11}, {0x1A21, 14}, {0x1A22, 14}, {0x07D5, 11}, - {0x1A23, 14}, {0x003F, 6}, {0x01F6, 9}, {0x01F7, 9}, - {0x03EB, 10}, - },{//5 - {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, - {0x000F, 5}, {0x0020, 6}, {0x0021, 6}, {0x0044, 7}, - {0x0045, 7}, {0x0046, 7}, {0x008E, 8}, {0x008F, 8}, - {0x0090, 8}, {0x0122, 9}, {0x0246, 10}, {0x0124, 9}, - {0x0005, 3}, {0x0013, 5}, {0x004A, 7}, {0x0093, 8}, - {0x0018, 5}, {0x004B, 7}, {0x0032, 6}, {0x001A, 5}, - {0x0033, 6}, {0x006C, 7}, {0x006D, 7}, {0x006E, 7}, - {0x00DE, 8}, {0x00DF, 8}, {0x0070, 7}, {0x00E2, 8}, - {0x00E3, 8}, {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8}, - {0x00E7, 8}, {0x0125, 9}, {0x01D0, 9}, {0x048E, 11}, - {0x091E, 12}, {0x091F, 12}, {0x7440, 15}, {0x1D11, 13}, - {0x7441, 15}, {0x7442, 15}, {0x00E9, 8}, {0x01D4, 9}, - {0x00EB, 8}, {0x03A3, 10}, {0x01D5, 9}, {0x1D12, 13}, - {0x001E, 5}, {0x0076, 7}, {0x01DC, 9}, {0x01DD, 9}, - {0x7443, 15}, {0x007C, 7}, {0x0745, 11}, {0x00EF, 8}, - {0x00FA, 8}, {0x00FB, 8}, {0x01F8, 9}, {0x00FD, 8}, - {0x07E4, 11}, {0x0FCA, 12}, {0x1D13, 13}, {0x7E58, 15}, - {0x7E59, 15}, {0x7E5A, 15}, {0x7E5B, 15}, {0x7E5C, 15}, - {0x7E5D, 15}, {0x007F, 7}, {0x3F2F, 14}, {0x07E6, 11}, - {0x07E7, 11}, - },{//6 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, - {0x0009, 5}, {0x0014, 6}, {0x0015, 6}, {0x002C, 7}, - {0x005A, 8}, {0x005B, 8}, {0x005C, 8}, {0x00BA, 9}, - {0x00BB, 9}, {0x00BC, 9}, {0x02F4, 11}, {0x05EA, 12}, - {0x0003, 3}, {0x0010, 5}, {0x0022, 6}, {0x0046, 7}, - {0x0009, 4}, {0x0028, 6}, {0x0015, 5}, {0x000B, 4}, - {0x0018, 5}, {0x0029, 6}, {0x0032, 6}, {0x0047, 7}, - {0x0066, 7}, {0x0067, 7}, {0x0068, 7}, {0x0069, 7}, - {0x006A, 7}, {0x005F, 8}, {0x00D6, 8}, {0x00D7, 8}, - {0x01B0, 9}, {0x00D9, 8}, {0x017B, 10}, {0x006D, 7}, - {0x00DC, 8}, {0x01B1, 9}, {0x06E8, 11}, {0x01BB, 9}, - {0x0375, 10}, {0x05EB, 12}, {0x01BC, 9}, {0x6E90, 15}, - {0x0038, 6}, {0x0072, 7}, {0x6E91, 15}, {0x6E92, 15}, - {0x001D, 5}, {0x0073, 7}, {0x01BD, 9}, {0x06F8, 11}, - {0x6E93, 15}, {0x003C, 6}, {0x01BF, 9}, {0x00F4, 8}, - {0x01EA, 9}, {0x037D, 10}, {0x03D6, 10}, {0x06F9, 11}, - {0x6E94, 15}, {0x00F6, 8}, {0x01EE, 9}, {0x6E95, 15}, - {0x6E96, 15}, {0x6E97, 15}, {0x374C, 14}, {0x374D, 14}, - {0x374E, 14}, {0x001F, 5}, {0x03D7, 10}, {0x01EF, 9}, - {0x374F, 14}, - },{//7 - {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6}, - {0x002E, 7}, {0x002F, 7}, {0x0060, 8}, {0x0061, 8}, - {0x00C4, 9}, {0x00C5, 9}, {0x00C6, 9}, {0x018E, 10}, - {0x31E0, 15}, {0x31E1, 15}, {0x31E2, 15}, {0x31E3, 15}, - {0x0004, 3}, {0x000D, 5}, {0x0019, 6}, {0x0038, 7}, - {0x000A, 4}, {0x001D, 6}, {0x000B, 4}, {0x0072, 8}, - {0x0073, 8}, {0x00F0, 9}, {0x01E2, 10}, {0x00F2, 9}, - {0x01E3, 10}, {0x00F3, 9}, {0x01E8, 10}, {0x01E9, 10}, - {0x31E4, 15}, {0x01EA, 10}, {0x031F, 11}, {0x03D6, 11}, - {0x31E5, 15}, {0x01EC, 10}, {0x31E6, 15}, {0x00F7, 9}, - {0x03D7, 11}, {0x31E7, 15}, {0x31E8, 15}, {0x03DA, 11}, - {0x03DB, 11}, {0x31E9, 15}, {0x03E0, 11}, {0x31EA, 15}, - {0x003F, 7}, {0x01F1, 10}, {0x31EB, 15}, {0x31EC, 15}, - {0x0006, 3}, {0x001C, 5}, {0x0074, 7}, {0x0075, 7}, - {0x00F9, 9}, {0x001E, 5}, {0x0076, 7}, {0x00FA, 9}, - {0x03E1, 11}, {0x31ED, 15}, {0x18F7, 14}, {0x1F60, 14}, - {0x1F61, 14}, {0x01DC, 9}, {0x01DD, 9}, {0x1F62, 14}, - {0x1F63, 14}, {0x1F64, 14}, {0x1F65, 14}, {0x1F66, 14}, - {0x1F67, 14}, {0x001F, 5}, {0x03ED, 11}, {0x00EF, 8}, - {0x01F7, 10}, - } -}; - -static const uint16_t x8_ac1_highquant_table[8][77][2]={ - {//0 - {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5}, - {0x0008, 5}, {0x0009, 5}, {0x0014, 6}, {0x002A, 7}, - {0x0016, 6}, {0x002B, 7}, {0x005C, 8}, {0x002F, 7}, - {0x0030, 7}, {0x005D, 8}, {0x0062, 8}, {0x00C6, 9}, - {0x0007, 4}, {0x0019, 6}, {0x001A, 6}, {0x0036, 7}, - {0x0010, 5}, {0x006E, 8}, {0x0022, 6}, {0x0009, 4}, - {0x000A, 4}, {0x0016, 5}, {0x0023, 6}, {0x002E, 6}, - {0x002F, 6}, {0x0030, 6}, {0x0062, 7}, {0x0063, 7}, - {0x0064, 7}, {0x0065, 7}, {0x0066, 7}, {0x0067, 7}, - {0x0068, 7}, {0x0069, 7}, {0x006A, 7}, {0x006B, 7}, - {0x006C, 7}, {0x00C7, 9}, {0x00DE, 9}, {0x00DF, 9}, - {0x06D0, 11}, {0x01B5, 9}, {0x0037, 6}, {0x00DB, 8}, - {0x001C, 5}, {0x0074, 7}, {0x01D4, 9}, {0x01D5, 9}, - {0x0076, 7}, {0x0369, 10}, {0x3688, 14}, {0x3689, 14}, - {0x368A, 14}, {0x0077, 7}, {0x03AC, 10}, {0x0078, 7}, - {0x00F2, 8}, {0x01D7, 9}, {0x00F3, 8}, {0x007A, 7}, - {0x368B, 14}, {0x007B, 7}, {0x007C, 7}, {0x03AD, 10}, - {0x03E8, 10}, {0x368C, 14}, {0x368D, 14}, {0x03E9, 10}, - {0x368E, 14}, {0x003F, 6}, {0x01F5, 9}, {0x00FB, 8}, - {0x368F, 14}, - },{//1 - {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, - {0x0018, 6}, {0x0032, 7}, {0x0033, 7}, {0x0034, 7}, - {0x006A, 8}, {0x00D6, 9}, {0x00D7, 9}, {0x00D8, 9}, - {0x00D9, 9}, {0x3680, 15}, {0x01B5, 10}, {0x0369, 11}, - {0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x0037, 7}, - {0x000A, 4}, {0x0016, 5}, {0x000C, 4}, {0x001F, 6}, - {0x005C, 7}, {0x005D, 7}, {0x00BC, 8}, {0x00BD, 8}, - {0x005F, 7}, {0x00D0, 8}, {0x00DB, 9}, {0x00D1, 8}, - {0x01A4, 9}, {0x01A5, 9}, {0x01A6, 9}, {0x01A7, 9}, - {0x0350, 10}, {0x06A2, 11}, {0x06A3, 11}, {0x01A9, 9}, - {0x01AA, 9}, {0x06AC, 11}, {0x3681, 15}, {0x0357, 10}, - {0x3682, 15}, {0x3683, 15}, {0x3684, 15}, {0x3685, 15}, - {0x0036, 6}, {0x00D6, 8}, {0x3686, 15}, {0x3687, 15}, - {0x000E, 4}, {0x006E, 7}, {0x00D7, 8}, {0x06AD, 11}, - {0x3688, 15}, {0x001E, 5}, {0x00DE, 8}, {0x06F8, 11}, - {0x037D, 10}, {0x3689, 15}, {0x368A, 15}, {0x368B, 15}, - {0x368C, 15}, {0x01BF, 9}, {0x368D, 15}, {0x1B47, 14}, - {0x37C8, 14}, {0x37C9, 14}, {0x37CA, 14}, {0x37CB, 14}, - {0x37CC, 14}, {0x001F, 5}, {0x37CD, 14}, {0x37CE, 14}, - {0x37CF, 14}, - },{//2 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, - {0x0012, 6}, {0x0026, 7}, {0x0014, 6}, {0x0027, 7}, - {0x00A8, 9}, {0x00A9, 9}, {0x0055, 8}, {0x2B00, 15}, - {0x00AD, 9}, {0x2B01, 15}, {0x2B02, 15}, {0x2B03, 15}, - {0x0003, 3}, {0x000B, 5}, {0x0040, 7}, {0x0041, 7}, - {0x0009, 4}, {0x0021, 6}, {0x0011, 5}, {0x000A, 4}, - {0x000B, 4}, {0x0018, 5}, {0x0032, 6}, {0x0033, 6}, - {0x0034, 6}, {0x0035, 6}, {0x006C, 7}, {0x0057, 8}, - {0x006D, 7}, {0x00DC, 8}, {0x0159, 10}, {0x00DD, 8}, - {0x01BC, 9}, {0x037A, 10}, {0x037B, 10}, {0x0038, 6}, - {0x0072, 7}, {0x01BE, 9}, {0x01BF, 9}, {0x00E6, 8}, - {0x039C, 10}, {0x01CF, 9}, {0x2B04, 15}, {0x2B05, 15}, - {0x0074, 7}, {0x01D4, 9}, {0x2B06, 15}, {0x2B07, 15}, - {0x001E, 5}, {0x00EB, 8}, {0x1584, 14}, {0x1585, 14}, - {0x1586, 14}, {0x003B, 6}, {0x01D5, 9}, {0x01F0, 9}, - {0x039D, 10}, {0x03E2, 10}, {0x1587, 14}, {0x1588, 14}, - {0x1589, 14}, {0x00F9, 8}, {0x158A, 14}, {0x158B, 14}, - {0x03E3, 10}, {0x158C, 14}, {0x158D, 14}, {0x01F4, 9}, - {0x158E, 14}, {0x003F, 6}, {0x00FB, 8}, {0x01F5, 9}, - {0x158F, 14}, - },{//3 - {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5}, - {0x0010, 6}, {0x0011, 6}, {0x0024, 7}, {0x0025, 7}, - {0x0013, 6}, {0x0014, 6}, {0x002A, 7}, {0x002B, 7}, - {0x00B0, 9}, {0x00B1, 9}, {0x002D, 7}, {0x0059, 8}, - {0x000C, 5}, {0x0017, 6}, {0x00D0, 9}, {0x0035, 7}, - {0x001B, 6}, {0x0038, 7}, {0x0039, 7}, {0x0004, 3}, - {0x0005, 3}, {0x000F, 5}, {0x0018, 5}, {0x001D, 6}, - {0x0032, 6}, {0x0033, 6}, {0x0068, 7}, {0x0069, 7}, - {0x0069, 8}, {0x00D4, 8}, {0x00D5, 8}, {0x00D6, 8}, - {0x006C, 7}, {0x0037, 6}, {0x006D, 7}, {0x0070, 7}, - {0x0039, 6}, {0x00D7, 8}, {0x00D1, 9}, {0x3880, 14}, - {0x3881, 14}, {0x3882, 14}, {0x0074, 7}, {0x01C5, 9}, - {0x0075, 7}, {0x00E3, 8}, {0x3883, 14}, {0x3884, 14}, - {0x00EC, 8}, {0x3885, 14}, {0x1C43, 13}, {0x1C44, 13}, - {0x1C45, 13}, {0x00ED, 8}, {0x1C46, 13}, {0x003C, 6}, - {0x0077, 7}, {0x01E8, 9}, {0x003E, 6}, {0x007B, 7}, - {0x1C47, 13}, {0x007E, 7}, {0x007F, 7}, {0x1C48, 13}, - {0x1C49, 13}, {0x1C4A, 13}, {0x1C4B, 13}, {0x1C4C, 13}, - {0x1C4D, 13}, {0x00F5, 8}, {0x1C4E, 13}, {0x01E9, 9}, - {0x1C4F, 13}, - },{//4 - {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, - {0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x0035, 7}, - {0x0036, 7}, {0x006E, 8}, {0x00DE, 9}, {0x00DF, 9}, - {0x01C0, 10}, {0x01C1, 10}, {0x01C2, 10}, {0x3860, 15}, - {0x0004, 3}, {0x000F, 5}, {0x001D, 6}, {0x0039, 7}, - {0x000A, 4}, {0x002C, 6}, {0x002D, 6}, {0x000C, 4}, - {0x0017, 5}, {0x0034, 6}, {0x0035, 6}, {0x0036, 6}, - {0x006E, 7}, {0x006F, 7}, {0x0070, 7}, {0x0071, 7}, - {0x0071, 8}, {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8}, - {0x00E7, 8}, {0x00E8, 8}, {0x03A4, 10}, {0x0075, 7}, - {0x00EC, 8}, {0x01D3, 9}, {0x01DA, 9}, {0x03A5, 10}, - {0x03B6, 10}, {0x070D, 12}, {0x03B7, 10}, {0x070E, 12}, - {0x003C, 6}, {0x00EE, 8}, {0x3861, 15}, {0x3862, 15}, - {0x003D, 6}, {0x01DE, 9}, {0x3863, 15}, {0x3864, 15}, - {0x3865, 15}, {0x007C, 7}, {0x070F, 12}, {0x03BE, 10}, - {0x03BF, 10}, {0x3866, 15}, {0x0FA0, 12}, {0x07D1, 11}, - {0x3867, 15}, {0x00FB, 8}, {0x01F5, 9}, {0x7D08, 15}, - {0x0FA4, 12}, {0x7D09, 15}, {0x7D0A, 15}, {0x7D0B, 15}, - {0x3E86, 14}, {0x003F, 6}, {0x0FA5, 12}, {0x07D3, 11}, - {0x3E87, 14}, - },{//5 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, - {0x0009, 5}, {0x0014, 6}, {0x002A, 7}, {0x0056, 8}, - {0x02B8, 11}, {0x00AF, 9}, {0x02B9, 11}, {0x015D, 10}, - {0x02C0, 11}, {0x2C10, 15}, {0x2C11, 15}, {0x2C12, 15}, - {0x0006, 4}, {0x000E, 5}, {0x0017, 6}, {0x002D, 7}, - {0x000F, 5}, {0x0040, 7}, {0x0021, 6}, {0x0005, 3}, - {0x0009, 4}, {0x0011, 5}, {0x0018, 5}, {0x0019, 5}, - {0x001A, 5}, {0x0036, 6}, {0x0037, 6}, {0x0041, 7}, - {0x0059, 8}, {0x00E0, 8}, {0x00E1, 8}, {0x0071, 7}, - {0x00E4, 8}, {0x00B1, 9}, {0x02C2, 11}, {0x001D, 5}, - {0x0073, 7}, {0x00E5, 8}, {0x00F0, 8}, {0x0079, 7}, - {0x03C4, 10}, {0x01E3, 9}, {0x01E8, 9}, {0x2C13, 15}, - {0x007B, 7}, {0x2C14, 15}, {0x2C15, 15}, {0x2C16, 15}, - {0x007C, 7}, {0x02C3, 11}, {0x2C17, 15}, {0x160C, 14}, - {0x160D, 14}, {0x007D, 7}, {0x160E, 14}, {0x01E9, 9}, - {0x03C5, 10}, {0x03D4, 10}, {0x01EB, 9}, {0x160F, 14}, - {0x3D50, 14}, {0x00FC, 8}, {0x07AB, 11}, {0x3D51, 14}, - {0x3D52, 14}, {0x3D53, 14}, {0x3D54, 14}, {0x01FA, 9}, - {0x3D55, 14}, {0x007F, 7}, {0x01FB, 9}, {0x3D56, 14}, - {0x3D57, 14}, - },{//6 - {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, - {0x0009, 5}, {0x000A, 5}, {0x000B, 5}, {0x0018, 6}, - {0x0032, 7}, {0x000D, 5}, {0x0033, 7}, {0x0E00, 13}, - {0x0039, 7}, {0x0E01, 13}, {0x003A, 7}, {0x0E02, 13}, - {0x0008, 4}, {0x001E, 6}, {0x003B, 7}, {0x003E, 7}, - {0x0012, 5}, {0x003F, 7}, {0x0013, 5}, {0x0028, 6}, - {0x0029, 6}, {0x0054, 7}, {0x002B, 6}, {0x0055, 7}, - {0x0058, 7}, {0x0E03, 13}, {0x0059, 7}, {0x005A, 7}, - {0x0E04, 13}, {0x0E05, 13}, {0x0703, 12}, {0x005B, 7}, - {0x005C, 7}, {0x0704, 12}, {0x0705, 12}, {0x005D, 7}, - {0x0706, 12}, {0x0707, 12}, {0x0708, 12}, {0x0709, 12}, - {0x070A, 12}, {0x070B, 12}, {0x0018, 5}, {0x002F, 6}, - {0x000D, 4}, {0x0019, 5}, {0x070C, 12}, {0x0070, 7}, - {0x001D, 5}, {0x070D, 12}, {0x070E, 12}, {0x070F, 12}, - {0x0710, 12}, {0x0039, 6}, {0x0711, 12}, {0x003C, 6}, - {0x0712, 12}, {0x0713, 12}, {0x0714, 12}, {0x0715, 12}, - {0x0716, 12}, {0x003D, 6}, {0x0717, 12}, {0x0718, 12}, - {0x0719, 12}, {0x071A, 12}, {0x071B, 12}, {0x071C, 12}, - {0x071D, 12}, {0x001F, 5}, {0x071E, 12}, {0x0071, 7}, - {0x071F, 12}, - },{//7 - {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x000E, 6}, - {0x000F, 6}, {0x0040, 8}, {0x0041, 8}, {0x0042, 8}, - {0x0218, 11}, {0x2190, 15}, {0x2191, 15}, {0x2192, 15}, - {0x2193, 15}, {0x2194, 15}, {0x2195, 15}, {0x2196, 15}, - {0x0005, 4}, {0x0011, 6}, {0x0024, 7}, {0x0087, 9}, - {0x000C, 5}, {0x004A, 8}, {0x004B, 8}, {0x0002, 2}, - {0x0006, 3}, {0x000D, 5}, {0x000E, 5}, {0x000F, 5}, - {0x0013, 6}, {0x0038, 6}, {0x00E4, 8}, {0x00E5, 8}, - {0x01CC, 9}, {0x00E7, 8}, {0x0074, 7}, {0x00EA, 8}, - {0x01CD, 9}, {0x021A, 11}, {0x2197, 15}, {0x001E, 5}, - {0x0076, 7}, {0x00EB, 8}, {0x01DC, 9}, {0x00EF, 8}, - {0x01DD, 9}, {0x01F0, 9}, {0x2198, 15}, {0x2199, 15}, - {0x00F9, 8}, {0x03E2, 10}, {0x219A, 15}, {0x219B, 15}, - {0x00FA, 8}, {0x219C, 15}, {0x219D, 15}, {0x219E, 15}, - {0x219F, 15}, {0x01F6, 9}, {0x21B0, 15}, {0x00FC, 8}, - {0x01F7, 9}, {0x21B1, 15}, {0x21B2, 15}, {0x21B3, 15}, - {0x21B4, 15}, {0x01FA, 9}, {0x21B5, 15}, {0x21B6, 15}, - {0x21B7, 15}, {0x21B8, 15}, {0x21B9, 15}, {0x03E3, 10}, - {0x10DD, 14}, {0x007F, 7}, {0x01FB, 9}, {0x10DE, 14}, - {0x10DF, 14}, - } -}; -#define MAX_AC_VLC_BITS 16 - -#endif /* AVCODEC_INTRAX8HUF_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ituh263dec.c b/tizen/distrib/ffmpeg/libavcodec/ituh263dec.c deleted file mode 100644 index 8b5d939..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ituh263dec.c +++ /dev/null @@ -1,1131 +0,0 @@ -/* - * ITU H263 bitstream decoder - * Copyright (c) 2000,2001 Fabrice Bellard - * H263+ support. - * Copyright (c) 2001 Juan J. Sierralta P - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * h263 decoder. - */ - -//#define DEBUG -#include - -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h263.h" -#include "mathops.h" -#include "unary.h" -#include "flv.h" -#include "mpeg4video.h" - -//#undef NDEBUG -//#include - -// The defines below define the number of bits that are read at once for -// reading vlc values. Changing these may improve speed and data cache needs -// be aware though that decreasing them may need the number of stages that is -// passed to get_vlc* to be increased. -#define MV_VLC_BITS 9 -#define H263_MBTYPE_B_VLC_BITS 6 -#define CBPC_B_VLC_BITS 3 - -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, -}; - -void ff_h263_show_pict_info(MpegEncContext *s){ - 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 - ); - } -} - -/***********************************************/ -/* decoding */ - -VLC ff_h263_intra_MCBPC_vlc; -VLC ff_h263_inter_MCBPC_vlc; -VLC ff_h263_cbpy_vlc; -static VLC mv_vlc; -static VLC h263_mbtype_b_vlc; -static VLC cbpc_b_vlc; - -/* 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_STATIC(&ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9, - ff_h263_intra_MCBPC_bits, 1, 1, - ff_h263_intra_MCBPC_code, 1, 1, 72); - INIT_VLC_STATIC(&ff_h263_inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28, - ff_h263_inter_MCBPC_bits, 1, 1, - ff_h263_inter_MCBPC_code, 1, 1, 198); - INIT_VLC_STATIC(&ff_h263_cbpy_vlc, CBPY_VLC_BITS, 16, - &ff_h263_cbpy_tab[0][1], 2, 1, - &ff_h263_cbpy_tab[0][0], 2, 1, 64); - INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 538); - init_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - init_rl(&rl_intra_aic, ff_h263_static_rl_table_store[1]); - INIT_VLC_RL(ff_h263_rl_inter, 554); - INIT_VLC_RL(rl_intra_aic, 554); - INIT_VLC_STATIC(&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, 80); - INIT_VLC_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4, - &cbpc_b_tab[0][1], 2, 1, - &cbpc_b_tab[0][0], 2, 1, 8); - } -} - -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; -} - -/** - * decodes the group of blocks header or slice header. - * @return <0 if an error occurred - */ -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= get_bits_left(&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; -} - -/** - * finds the next resync_marker - * @param p pointer to buffer to scan - * @param end pointer to the end of the buffer - * @return pointer to the next resync_marker, or end if none was found - */ -const uint8_t *ff_h263_find_resync_marker(const uint8_t *restrict p, const uint8_t * restrict end) -{ - assert(p < end); - - end-=2; - p++; - for(;pcodec_id==CODEC_ID_MPEG4){ - skip_bits1(&s->gb); - align_get_bits(&s->gb); - } - - if(show_bits(&s->gb, 16)==0){ - pos= get_bits_count(&s->gb); - if(CONFIG_MPEG4_DECODER && s->codec_id==CODEC_ID_MPEG4) - ret= mpeg4_decode_video_packet_header(s); - else - ret= h263_decode_gob_header(s); - if(ret>=0) - return pos; - } - //OK, it's not where it is supposed to be ... - s->gb= s->last_resync_gb; - align_get_bits(&s->gb); - left= get_bits_left(&s->gb); - - for(;left>16+1+5+5; left-=8){ - if(show_bits(&s->gb, 16)==0){ - GetBitContext bak= s->gb; - - pos= get_bits_count(&s->gb); - if(CONFIG_MPEG4_DECODER && s->codec_id==CODEC_ID_MPEG4) - ret= mpeg4_decode_video_packet_header(s); - else - ret= h263_decode_gob_header(s); - if(ret>=0) - return pos; - - s->gb= bak; - } - skip_bits(&s->gb, 8); - } - - return -1; -} - -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); - dprintf(s->avctx,"H.263+ UMV Motion = %d\n", code); - return code; - -} - -/** - * 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 == FF_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, ff_h263_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, ff_h263_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); -} - -static int h263_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded) -{ - int code, level, i, j, last, run; - RLTable *rl = &ff_h263_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){ -#if CONFIG_RV10_DECODER - if (s->rv10_version == 3 && s->pict_type == FF_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_recognition >= 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 (CONFIG_FLV_DECODER && s->h263_flv > 1) { - ff_flv2_decode_ac_esc(&s->gb, &level, &run, &last); - } 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 == &ff_h263_rl_inter && !s->mb_intra){ - //Looks like a hack but no, it's the way it is supposed to work ... - rl = &rl_intra_aic; - i = 0; - s->gb= gb; - s->dsp.clear_block(block); - 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; -} - -static int h263_skip_b_part(MpegEncContext *s, int cbp) -{ - LOCAL_ALIGNED_16(DCTELEM, dblock, [64]); - int i, mbi; - - /* we have to set s->mb_intra to zero to decode B-part of PB-frame correctly - * but real value should be restored in order to be used later (in OBMC condition) - */ - mbi = s->mb_intra; - s->mb_intra = 0; - for (i = 0; i < 6; i++) { - if (h263_decode_block(s, dblock, i, cbp&32) < 0) - return -1; - cbp+=cbp; - } - s->mb_intra = mbi; - return 0; -} - -static int h263_get_modb(GetBitContext *gb, int pb_frame, int *cbpb) -{ - int c, mv = 1; - - if (pb_frame < 3) { // h.263 Annex G and i263 PB-frame - c = get_bits1(gb); - if (pb_frame == 2 && c) - mv = !get_bits1(gb); - } else { // h.263 Annex M improved PB-frame - mv = get_unary(gb, 0, 4) + 1; - c = mv & 1; - mv = !!(mv & 2); - } - if(c) - *cbpb = get_bits(gb, 6); - return mv; -} - -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; - int cbpb = 0, pb_mv_count = 0; - - assert(!s->h263_pred); - - if (s->pict_type == FF_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, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); - 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->pb_frame && get_bits1(&s->gb)) - pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb); - cbpy = get_vlc2(&s->gb, ff_h263_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; - } - } - } else if(s->pict_type==FF_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, ff_h263_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; - } else { /* I-Frame */ - do{ - cbpc = get_vlc2(&s->gb, ff_h263_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; - - if(s->pb_frame && get_bits1(&s->gb)) - pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb); - cbpy = get_vlc2(&s->gb, ff_h263_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); - } - - pb_mv_count += !!s->pb_frame; - } - - while(pb_mv_count--){ - h263_decode_motion(s, 0, 1); - h263_decode_motion(s, 0, 1); - } - - /* 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->pb_frame && h263_skip_b_part(s, cbpb) < 0) - return -1; - if(s->obmc && !s->mb_intra){ - if(s->pict_type == FF_P_TYPE && s->mb_x+1mb_width && s->mb_num_left != 1) - preview_obmc(s); - } -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; -} - -/* 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= get_bits_left(&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 = FF_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; - - s->pb_frame = get_bits1(&s->gb); - 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(s->avctx, "ufep=1, format: %d\n", format); - s->custom_pcf= get_bits1(&s->gb); - s->umvplus = get_bits1(&s->gb); /* 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= FF_I_TYPE;break; - case 1: s->pict_type= FF_P_TYPE;break; - case 2: s->pict_type= FF_P_TYPE;s->pb_frame = 3;break; - case 3: s->pict_type= FF_B_TYPE;break; - case 7: s->pict_type= FF_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(s->avctx, "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(s->avctx, "\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= ff_h263_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= av_gcd(s->avctx->time_base.den, s->avctx->time_base.num); - s->avctx->time_base.den /= gcd; - s->avctx->time_base.num /= gcd; - }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; - - if (s->pb_frame) { - skip_bits(&s->gb, 3); /* Temporal reference for B-pictures */ - if (s->custom_pcf) - skip_bits(&s->gb, 2); //extended Temporal reference - skip_bits(&s->gb, 2); /* Quantization information for B-pictures */ - } - - /* 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; - } - - ff_h263_show_pict_info(s); - if (s->pict_type == FF_I_TYPE && s->codec_tag == AV_RL32("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)); - } - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ituh263enc.c b/tizen/distrib/ffmpeg/libavcodec/ituh263enc.c deleted file mode 100644 index f736d7c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ituh263enc.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - * ITU H263 bitstream encoder - * Copyright (c) 2000,2001 Fabrice Bellard - * H263+ support. - * Copyright (c) 2001 Juan J. Sierralta P - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * h263 bitstream encoder. - */ - -//#define DEBUG -#include - -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h263.h" -#include "mathops.h" -#include "unary.h" -#include "flv.h" -#include "mpeg4video.h" -#include "internal.h" - -//#undef NDEBUG -//#include - -/** - * Table of number of bits a motion vector component needs. - */ -static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; - -/** - * Minimal fcode that a motion vector component would need. - */ -static uint8_t fcode_tab[MAX_MV*2+1]; - -/** - * Minimal fcode that a motion vector component would need in umv. - * All entries in this table are 1. - */ -static uint8_t umv_fcode_tab[MAX_MV*2+1]; - -//unified encoding tables for run length encoding of coefficients -//unified in the sense that the specification specifies the encoding in several steps. -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)) - -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 -}; - -/** - * Returns the 4 bit value that specifies the given aspect ratio. - * This may be one of the standard aspect ratios or it specifies - * that the aspect will be stored explicitly later. - */ -av_const int ff_h263_aspect_to_info(AVRational aspect){ - int i; - - if(aspect.num==0) aspect= (AVRational){1,1}; - - for(i=1; i<6; i++){ - if(av_cmp_q(ff_h263_pixel_aspect[i], aspect) == 0){ - return i; - } - } - - return FF_ASPECT_EXTENDED; -} - -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= av_clip(div, 1, 127); - error= FFABS(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 = put_bits_ptr(&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_sbits(&s->pb, 8, temp_ref); /* 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 = ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_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 == FF_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 == FF_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) */ - s->aspect_ratio_info= ff_h263_aspect_to_info(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_sbits(&s->pb, 2, temp_ref>>8); - } - - /* 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 == FF_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 == FF_I_TYPE); /* GFID */ - put_bits(&s->pb, 5, s->qscale); /* GQUANT */ - } -} - -/** - * 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; - - ff_init_qscale_tab(s); - - 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_INTER; - } - } - } -} - -static const int dquant_code[5]= {1,0,9,2,3}; - -/** - * 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 = &ff_h263_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(!CONFIG_FLV_ENCODER || s->h263_flv <= 1){ - put_bits(&s->pb, 1, last); - put_bits(&s->pb, 6, run); - - assert(slevel != 0); - - if(level < 128) - put_sbits(&s->pb, 8, slevel); - else{ - put_bits(&s->pb, 8, 128); - put_sbits(&s->pb, 5, slevel); - put_sbits(&s->pb, 6, slevel>>5); - } - }else{ - ff_flv2_encode_ac_esc(&s->pb, slevel, level, run, last); - } - } else { - put_bits(&s->pb, 1, sign); - } - last_non_zero = i; - } - } -} - -/* 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); - } -} - -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]; - int16_t *dc_ptr[6]; - const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1); - - 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, - ff_h263_inter_MCBPC_bits[cbpc], - ff_h263_inter_MCBPC_code[cbpc]); - - put_bits(&s->pb, ff_h263_cbpy_tab[cbpy][1], ff_h263_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, - ff_h263_inter_MCBPC_bits[cbpc+16], - ff_h263_inter_MCBPC_code[cbpc+16]); - put_bits(&s->pb, ff_h263_cbpy_tab[cbpy][1], ff_h263_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 == FF_I_TYPE) { - if(s->dquant) cbpc+=4; - put_bits(&s->pb, - ff_h263_intra_MCBPC_bits[cbpc], - ff_h263_intra_MCBPC_code[cbpc]); - } else { - if(s->dquant) cbpc+=8; - put_bits(&s->pb, 1, 0); /* mb coded */ - put_bits(&s->pb, - ff_h263_inter_MCBPC_bits[cbpc + 4], - ff_h263_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, ff_h263_cbpy_tab[cbpy][1], ff_h263_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++; - } - } -} - -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); - } - } -} - -static void init_mv_penalty_and_fcode(MpegEncContext *s) -{ - int f_code; - int mv; - - 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, code; - - bit_size = f_code - 1; - - 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<= 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_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - init_rl(&rl_intra_aic, ff_h263_static_rl_table_store[1]); - - init_uni_h263_rl_tab(&rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); - init_uni_h263_rl_tab(&ff_h263_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; - 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; - } -} - -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); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ivi_common.c b/tizen/distrib/ffmpeg/libavcodec/ivi_common.c deleted file mode 100644 index a0596f6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ivi_common.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* - * common functions for Indeo Video Interactive codecs (Indeo4 and Indeo5) - * - * Copyright (c) 2009 Maxim Poliakovski - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * This file contains functions and data shared by both Indeo4 and - * Indeo5 decoders. - */ - -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "get_bits.h" -#include "ivi_common.h" -#include "libavutil/common.h" -#include "ivi_dsp.h" - -extern const IVIHuffDesc ff_ivi_mb_huff_desc[8]; ///< static macroblock huffman tables -extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tables - -VLC ff_ivi_mb_vlc_tabs [8]; -VLC ff_ivi_blk_vlc_tabs[8]; - -/** - * Reverses "nbits" bits of the value "val" and returns the result - * in the least significant bits. - */ -static uint16_t inv_bits(uint16_t val, int nbits) -{ - uint16_t res; - - if (nbits <= 8) { - res = av_reverse[val] >> (8-nbits); - } else - res = ((av_reverse[val & 0xFF] << 8) + (av_reverse[val >> 8])) >> (16-nbits); - - return res; -} - -int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) -{ - int pos, i, j, codes_per_row, prefix, not_last_row; - uint16_t codewords[256]; /* FIXME: move this temporal storage out? */ - uint8_t bits[256]; - - pos = 0; /* current position = 0 */ - - for (i = 0; i < cb->num_rows; i++) { - codes_per_row = 1 << cb->xbits[i]; - not_last_row = (i != cb->num_rows - 1); - prefix = ((1 << i) - 1) << (cb->xbits[i] + not_last_row); - - for (j = 0; j < codes_per_row; j++) { - if (pos >= 256) /* Some Indeo5 codebooks can have more than 256 */ - break; /* elements, but only 256 codes are allowed! */ - - bits[pos] = i + cb->xbits[i] + not_last_row; - if (bits[pos] > IVI_VLC_BITS) - return -1; /* invalid descriptor */ - - codewords[pos] = inv_bits((prefix | j), bits[pos]); - if (!bits[pos]) - bits[pos] = 1; - - pos++; - }//for j - }//for i - - /* number of codewords = pos */ - return init_vlc(vlc, IVI_VLC_BITS, pos, bits, 1, 1, codewords, 2, 2, - (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE); -} - -void ff_ivi_init_static_vlc(void) -{ - int i; - static VLC_TYPE table_data[8192 * 16][2]; - static int initialized_vlcs = 0; - - if (initialized_vlcs) - return; - for (i = 0; i < 8; i++) { - ff_ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192; - ff_ivi_mb_vlc_tabs[i].table_allocated = 8192; - ff_ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &ff_ivi_mb_vlc_tabs[i], 1); - ff_ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192; - ff_ivi_blk_vlc_tabs[i].table_allocated = 8192; - ff_ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ff_ivi_blk_vlc_tabs[i], 1); - } - initialized_vlcs = 1; -} - -int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, - IVIHuffTab *huff_tab, AVCodecContext *avctx) -{ - int i, result; - IVIHuffDesc new_huff; - - if (!desc_coded) { - /* select default table */ - huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[7] - : &ff_ivi_mb_vlc_tabs [7]; - } else { - huff_tab->tab_sel = get_bits(gb, 3); - if (huff_tab->tab_sel == 7) { - /* custom huffman table (explicitly encoded) */ - new_huff.num_rows = get_bits(gb, 4); - - for (i = 0; i < new_huff.num_rows; i++) - new_huff.xbits[i] = get_bits(gb, 4); - - /* Have we got the same custom table? Rebuild if not. */ - if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { - ff_ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); - - if (huff_tab->cust_tab.table) - free_vlc(&huff_tab->cust_tab); - result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc, - &huff_tab->cust_tab, 0); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Error while initializing custom vlc table!\n"); - return -1; - } - } - huff_tab->tab = &huff_tab->cust_tab; - } else { - /* select one of predefined tables */ - huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[huff_tab->tab_sel] - : &ff_ivi_mb_vlc_tabs [huff_tab->tab_sel]; - } - } - - return 0; -} - -int ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2) -{ - return desc1->num_rows != desc2->num_rows - || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); -} - -void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src) -{ - dst->num_rows = src->num_rows; - memcpy(dst->xbits, src->xbits, src->num_rows); -} - -int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) -{ - int p, b; - uint32_t b_width, b_height, align_fac, width_aligned, height_aligned, buf_size; - IVIBandDesc *band; - - ff_ivi_free_buffers(planes); - - /* fill in the descriptor of the luminance plane */ - planes[0].width = cfg->pic_width; - planes[0].height = cfg->pic_height; - planes[0].num_bands = cfg->luma_bands; - - /* fill in the descriptors of the chrominance planes */ - planes[1].width = planes[2].width = (cfg->pic_width + 3) >> 2; - planes[1].height = planes[2].height = (cfg->pic_height + 3) >> 2; - planes[1].num_bands = planes[2].num_bands = cfg->chroma_bands; - - for (p = 0; p < 3; p++) { - planes[p].bands = av_mallocz(planes[p].num_bands * sizeof(IVIBandDesc)); - if (!planes[p].bands) - return AVERROR(ENOMEM); - - /* select band dimensions: if there is only one band then it - * has the full size, if there are several bands each of them - * has only half size */ - b_width = planes[p].num_bands == 1 ? planes[p].width : (planes[p].width + 1) >> 1; - b_height = planes[p].num_bands == 1 ? planes[p].height : (planes[p].height + 1) >> 1; - - /* luma band buffers will be aligned on 16x16 (max macroblock size) */ - /* chroma band buffers will be aligned on 8x8 (max macroblock size) */ - align_fac = p ? 8 : 16; - width_aligned = FFALIGN(b_width , align_fac); - height_aligned = FFALIGN(b_height, align_fac); - buf_size = width_aligned * height_aligned * sizeof(int16_t); - - for (b = 0; b < planes[p].num_bands; b++) { - band = &planes[p].bands[b]; /* select appropriate plane/band */ - band->plane = p; - band->band_num = b; - band->width = b_width; - band->height = b_height; - band->pitch = width_aligned; - band->bufs[0] = av_malloc(buf_size); - band->bufs[1] = av_malloc(buf_size); - if (!band->bufs[0] || !band->bufs[1]) - return AVERROR(ENOMEM); - - /* allocate the 3rd band buffer for scalability mode */ - if (cfg->luma_bands > 1) { - band->bufs[2] = av_malloc(buf_size); - if (!band->bufs[2]) - return AVERROR(ENOMEM); - } - - planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; /* reset custom vlc */ - } - } - - return 0; -} - -void av_cold ff_ivi_free_buffers(IVIPlaneDesc *planes) -{ - int p, b, t; - - for (p = 0; p < 3; p++) { - for (b = 0; b < planes[p].num_bands; b++) { - av_freep(&planes[p].bands[b].bufs[0]); - av_freep(&planes[p].bands[b].bufs[1]); - av_freep(&planes[p].bands[b].bufs[2]); - - if (planes[p].bands[b].blk_vlc.cust_tab.table) - free_vlc(&planes[p].bands[b].blk_vlc.cust_tab); - for (t = 0; t < planes[p].bands[b].num_tiles; t++) - av_freep(&planes[p].bands[b].tiles[t].mbs); - av_freep(&planes[p].bands[b].tiles); - } - av_freep(&planes[p].bands); - } -} - -int av_cold ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height) -{ - int p, b, x, y, x_tiles, y_tiles, t_width, t_height; - IVIBandDesc *band; - IVITile *tile, *ref_tile; - - for (p = 0; p < 3; p++) { - t_width = !p ? tile_width : (tile_width + 3) >> 2; - t_height = !p ? tile_height : (tile_height + 3) >> 2; - - if (!p && planes[0].num_bands == 4) { - t_width >>= 1; - t_height >>= 1; - } - - for (b = 0; b < planes[p].num_bands; b++) { - band = &planes[p].bands[b]; - x_tiles = IVI_NUM_TILES(band->width, t_width); - y_tiles = IVI_NUM_TILES(band->height, t_height); - band->num_tiles = x_tiles * y_tiles; - - av_freep(&band->tiles); - band->tiles = av_mallocz(band->num_tiles * sizeof(IVITile)); - if (!band->tiles) - return AVERROR(ENOMEM); - - tile = band->tiles; - - /* use the first luma band as reference for motion vectors - * and quant */ - ref_tile = planes[0].bands[0].tiles; - - for (y = 0; y < band->height; y += t_height) { - for (x = 0; x < band->width; x += t_width) { - tile->xpos = x; - tile->ypos = y; - tile->width = FFMIN(band->width - x, t_width); - tile->height = FFMIN(band->height - y, t_height); - tile->is_empty = tile->data_size = 0; - /* calculate number of macroblocks */ - tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, - band->mb_size); - - av_freep(&tile->mbs); - tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo)); - if (!tile->mbs) - return AVERROR(ENOMEM); - - tile->ref_mbs = 0; - if (p || b) { - tile->ref_mbs = ref_tile->mbs; - ref_tile++; - } - - tile++; - } - } - - }// for b - }// for p - - return 0; -} - -int ff_ivi_dec_tile_data_size(GetBitContext *gb) -{ - int len; - - len = 0; - if (get_bits1(gb)) { - len = get_bits(gb, 8); - if (len == 255) - len = get_bits_long(gb, 24); - } - - /* align the bitstream reader on the byte boundary */ - align_get_bits(gb); - - return len; -} - -int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) -{ - int mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val, - pos, is_intra, mc_type, mv_x, mv_y, col_mask; - uint8_t col_flags[8]; - int32_t prev_dc, trvec[64]; - uint32_t cbp, sym, lo, hi, quant, buf_offs, q; - IVIMbInfo *mb; - RVMapDesc *rvmap = band->rv_map; - void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - void (*mc_no_delta_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - const uint8_t *base_tab, *scale_tab; - - prev_dc = 0; /* init intra prediction for the DC coefficient */ - - blk_size = band->blk_size; - col_mask = blk_size - 1; /* column mask for tracking non-zero coeffs */ - num_blocks = (band->mb_size != blk_size) ? 4 : 1; /* number of blocks per mb */ - num_coeffs = blk_size * blk_size; - if (blk_size == 8) { - mc_with_delta_func = ff_ivi_mc_8x8_delta; - mc_no_delta_func = ff_ivi_mc_8x8_no_delta; - } else { - mc_with_delta_func = ff_ivi_mc_4x4_delta; - mc_no_delta_func = ff_ivi_mc_4x4_no_delta; - } - - for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) { - is_intra = !mb->type; - cbp = mb->cbp; - buf_offs = mb->buf_offs; - - quant = av_clip(band->glob_quant + mb->q_delta, 0, 23); - - base_tab = is_intra ? band->intra_base : band->inter_base; - scale_tab = is_intra ? band->intra_scale : band->inter_scale; - - if (!is_intra) { - mv_x = mb->mv_x; - mv_y = mb->mv_y; - if (!band->is_halfpel) { - mc_type = 0; /* we have only fullpel vectors */ - } else { - mc_type = ((mv_y & 1) << 1) | (mv_x & 1); - mv_x >>= 1; - mv_y >>= 1; /* convert halfpel vectors into fullpel ones */ - } - } - - for (blk = 0; blk < num_blocks; blk++) { - /* adjust block position in the buffer according to its number */ - if (blk & 1) { - buf_offs += blk_size; - } else if (blk == 2) { - buf_offs -= blk_size; - buf_offs += blk_size * band->pitch; - } - - if (cbp & 1) { /* block coded ? */ - scan_pos = -1; - memset(trvec, 0, num_coeffs*sizeof(trvec[0])); /* zero transform vector */ - memset(col_flags, 0, sizeof(col_flags)); /* zero column flags */ - - while (scan_pos <= num_coeffs) { - sym = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - if (sym == rvmap->eob_sym) - break; /* End of block */ - - if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */ - run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; - lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */ - } else { - run = rvmap->runtab[sym]; - val = rvmap->valtab[sym]; - } - - /* de-zigzag and dequantize */ - scan_pos += run; - if (scan_pos >= num_coeffs) - break; - pos = band->scan[scan_pos]; - - if (IVI_DEBUG && !val) - av_log(NULL, AV_LOG_ERROR, "Val = 0 encountered!\n"); - - q = (base_tab[pos] * scale_tab[quant]) >> 8; - if (q > 1) - val = val * q + FFSIGN(val) * ((q >> 1) - (q & 1)); - trvec[pos] = val; - col_flags[pos & col_mask] |= !!val; /* track columns containing non-zero coeffs */ - }// while - - if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) - return -1; /* corrupt block data */ - - /* undoing DC coeff prediction for intra-blocks */ - if (is_intra && band->is_2d_trans) { - prev_dc += trvec[0]; - trvec[0] = prev_dc; - col_flags[0] |= !!prev_dc; - } - - /* apply inverse transform */ - band->inv_transform(trvec, band->buf + buf_offs, - band->pitch, col_flags); - - /* apply motion compensation */ - if (!is_intra) - mc_with_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); - } else { - /* block not coded */ - /* for intra blocks apply the dc slant transform */ - /* for inter - perform the motion compensation without delta */ - if (is_intra && band->dc_transform) { - band->dc_transform(&prev_dc, band->buf + buf_offs, - band->pitch, blk_size); - } else - mc_no_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); - } - - cbp >>= 1; - }// for blk - }// for mbn - - align_get_bits(gb); - - return 0; -} - -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, - IVITile *tile, int32_t mv_scale) -{ - int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type; - int offs, mb_offset, row_offset; - IVIMbInfo *mb, *ref_mb; - const int16_t *src; - int16_t *dst; - void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, - int mc_type); - - offs = tile->ypos * band->pitch + tile->xpos; - mb = tile->mbs; - ref_mb = tile->ref_mbs; - row_offset = band->mb_size * band->pitch; - need_mc = 0; /* reset the mc tracking flag */ - - for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) { - mb_offset = offs; - - for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) { - mb->xpos = x; - mb->ypos = y; - mb->buf_offs = mb_offset; - - mb->type = 1; /* set the macroblocks type = INTER */ - mb->cbp = 0; /* all blocks are empty */ - - if (!band->qdelta_present && !band->plane && !band->band_num) { - mb->q_delta = band->glob_quant; - mb->mv_x = 0; - mb->mv_y = 0; - } - - if (band->inherit_qdelta && ref_mb) - mb->q_delta = ref_mb->q_delta; - - if (band->inherit_mv) { - /* motion vector inheritance */ - if (mv_scale) { - mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); - mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); - } else { - mb->mv_x = ref_mb->mv_x; - mb->mv_y = ref_mb->mv_y; - } - need_mc |= mb->mv_x || mb->mv_y; /* tracking non-zero motion vectors */ - } - - mb++; - if (ref_mb) - ref_mb++; - mb_offset += band->mb_size; - } // for x - offs += row_offset; - } // for y - - if (band->inherit_mv && need_mc) { /* apply motion compensation if there is at least one non-zero motion vector */ - num_blocks = (band->mb_size != band->blk_size) ? 4 : 1; /* number of blocks per mb */ - mc_no_delta_func = (band->blk_size == 8) ? ff_ivi_mc_8x8_no_delta - : ff_ivi_mc_4x4_no_delta; - - for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) { - mv_x = mb->mv_x; - mv_y = mb->mv_y; - if (!band->is_halfpel) { - mc_type = 0; /* we have only fullpel vectors */ - } else { - mc_type = ((mv_y & 1) << 1) | (mv_x & 1); - mv_x >>= 1; - mv_y >>= 1; /* convert halfpel vectors into fullpel ones */ - } - - for (blk = 0; blk < num_blocks; blk++) { - /* adjust block position in the buffer according with its number */ - offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); - mc_no_delta_func(band->buf + offs, - band->ref_buf + offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); - } - } - } else { - /* copy data from the reference tile into the current one */ - src = band->ref_buf + tile->ypos * band->pitch + tile->xpos; - dst = band->buf + tile->ypos * band->pitch + tile->xpos; - for (y = 0; y < tile->height; y++) { - memcpy(dst, src, tile->width*sizeof(band->buf[0])); - src += band->pitch; - dst += band->pitch; - } - } -} - - -#if IVI_DEBUG -uint16_t ivi_calc_band_checksum (IVIBandDesc *band) -{ - int x, y; - int16_t *src, checksum; - - src = band->buf; - checksum = 0; - - for (y = 0; y < band->height; src += band->pitch, y++) - for (x = 0; x < band->width; x++) - checksum += src[x]; - - return checksum; -} - -int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch) -{ - int x, y, result; - uint8_t t1, t2; - int16_t *src; - - src = band->buf; - result = 0; - - for (y = 0; y < band->height; src += band->pitch, y++) { - for (x = 0; x < band->width; x++) { - t1 = av_clip(src[x] + 128, 0, 255); - t2 = ref[x]; - if (t1 != t2) { - av_log(NULL, AV_LOG_ERROR, "Data mismatch: row %d, column %d\n", - y / band->blk_size, x / band->blk_size); - result = -1; - } - } - ref += pitch; - } - - return result; -} -#endif - -void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch) -{ - int x, y; - const int16_t *src = plane->bands[0].buf; - uint32_t pitch = plane->bands[0].pitch; - - for (y = 0; y < plane->height; y++) { - for (x = 0; x < plane->width; x++) - dst[x] = av_clip_uint8(src[x] + 128); - src += pitch; - dst += dst_pitch; - } -} - - -/** - * These are 2x8 predefined Huffman codebooks for coding macroblock/block - * signals. They are specified using "huffman descriptors" in order to - * avoid huge static tables. The decoding tables will be generated at - * startup from these descriptors. - */ -const IVIHuffDesc ff_ivi_mb_huff_desc[8] = { - {8, {0, 4, 5, 4, 4, 4, 6, 6}}, - {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}}, - {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}}, - {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}}, - {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}}, - {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}}, - {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}}, - {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}} -}; - -const IVIHuffDesc ff_ivi_blk_huff_desc[8] = { - {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}}, - {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}}, - {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}}, - {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}}, - {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}}, - {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}}, - {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}}, - {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}} -}; - - -/** - * Run-value (RLE) tables. - */ -const RVMapDesc ff_ivi_rvmap_tabs[9] = { -{ /* MapTab0 */ - 5, /* eob_sym */ - 2, /* esc_sym */ - /* run table */ - {1, 1, 0, 1, 1, 0, 1, 1, 2, 2, 1, 1, 1, 1, 3, 3, - 1, 1, 2, 2, 1, 1, 4, 4, 1, 1, 1, 1, 2, 2, 5, 5, - 1, 1, 3, 3, 1, 1, 6, 6, 1, 2, 1, 2, 7, 7, 1, 1, - 8, 8, 1, 1, 4, 2, 1, 4, 2, 1, 3, 3, 1, 1, 1, 9, - 9, 1, 2, 1, 2, 1, 5, 5, 1, 1, 10, 10, 1, 1, 3, 3, - 2, 2, 1, 1, 11, 11, 6, 4, 4, 1, 6, 1, 2, 1, 2, 12, - 8, 1, 12, 7, 8, 7, 1, 16, 1, 16, 1, 3, 3, 13, 1, 13, - 2, 2, 1, 15, 1, 5, 14, 15, 1, 5, 14, 1, 17, 8, 17, 8, - 1, 4, 4, 2, 2, 1, 25, 25, 24, 24, 1, 3, 1, 3, 1, 8, - 6, 7, 6, 1, 18, 8, 18, 1, 7, 23, 2, 2, 23, 1, 1, 21, - 22, 9, 9, 22, 19, 1, 21, 5, 19, 5, 1, 33, 20, 33, 20, 8, - 4, 4, 1, 32, 2, 2, 8, 3, 32, 26, 3, 1, 7, 7, 26, 6, - 1, 6, 1, 1, 16, 1, 10, 1, 10, 2, 16, 29, 28, 2, 29, 28, - 1, 27, 5, 8, 5, 27, 1, 8, 3, 7, 3, 31, 41, 31, 1, 41, - 6, 1, 6, 7, 4, 4, 1, 1, 2, 1, 2, 11, 34, 30, 11, 1, - 30, 15, 15, 34, 36, 40, 36, 40, 35, 35, 37, 37, 39, 39, 38, 38}, - - /* value table */ - { 1, -1, 0, 2, -2, 0, 3, -3, 1, -1, 4, -4, 5, -5, 1, -1, - 6, -6, 2, -2, 7, -7, 1, -1, 8, -8, 9, -9, 3, -3, 1, -1, - 10, -10, 2, -2, 11, -11, 1, -1, 12, 4, -12, -4, 1, -1, 13, -13, - 1, -1, 14, -14, 2, 5, 15, -2, -5, -15, -3, 3, 16, -16, 17, 1, - -1, -17, 6, 18, -6, -18, 2, -2, 19, -19, 1, -1, 20, -20, 4, -4, - 7, -7, 21, -21, 1, -1, 2, 3, -3, 22, -2, -22, 8, 23, -8, 1, - 2, -23, -1, 2, -2, -2, 24, 1, -24, -1, 25, 5, -5, 1, -25, -1, - 9, -9, 26, 1, -26, 3, 1, -1, 27, -3, -1, -27, 1, 3, -1, -3, - 28, -4, 4, 10, -10, -28, 1, -1, 1, -1, 29, 6, -29, -6, 30, -4, - 3, 3, -3, -30, 1, 4, -1, 31, -3, 1, 11, -11, -1, -31, 32, -1, - -1, 2, -2, 1, 1, -32, 1, 4, -1, -4, 33, -1, 1, 1, -1, 5, - 5, -5, -33, -1, -12, 12, -5, -7, 1, 1, 7, 34, 4, -4, -1, 4, - -34, -4, 35, 36, -2, -35, -2, -36, 2, 13, 2, -1, 1, -13, 1, -1, - 37, 1, -5, 6, 5, -1, 38, -6, -8, 5, 8, -1, 1, 1, -37, -1, - 5, 39, -5, -5, 6, -6, -38, -39, -14, 40, 14, 2, 1, 1, -2, -40, - -1, -2, 2, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1} -},{ - /* MapTab1 */ - 0, /* eob_sym */ - 38, /* esc_sym */ - /* run table */ - {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 8, 6, 8, 7, - 7, 9, 9, 10, 10, 11, 11, 1, 12, 1, 12, 13, 13, 16, 14, 16, - 14, 15, 15, 17, 17, 18, 0, 18, 19, 20, 21, 19, 22, 21, 20, 22, - 25, 24, 2, 25, 24, 23, 23, 2, 26, 28, 26, 28, 29, 27, 29, 27, - 33, 33, 1, 32, 1, 3, 32, 30, 36, 3, 36, 30, 31, 31, 35, 34, - 37, 41, 34, 35, 37, 4, 41, 4, 49, 8, 8, 49, 40, 38, 5, 38, - 40, 39, 5, 39, 42, 43, 42, 7, 57, 6, 43, 44, 6, 50, 7, 44, - 57, 48, 50, 48, 45, 45, 46, 47, 51, 46, 47, 58, 1, 51, 58, 1, - 52, 59, 53, 9, 52, 55, 55, 59, 53, 56, 54, 56, 54, 9, 64, 64, - 60, 63, 60, 63, 61, 62, 61, 62, 2, 10, 2, 10, 11, 1, 11, 13, - 12, 1, 12, 13, 16, 16, 8, 8, 14, 3, 3, 15, 14, 15, 4, 4, - 1, 17, 17, 5, 1, 7, 7, 5, 6, 1, 2, 2, 6, 22, 1, 25, - 21, 22, 8, 24, 1, 21, 25, 24, 8, 18, 18, 23, 9, 20, 23, 33, - 29, 33, 20, 1, 19, 1, 29, 36, 9, 36, 19, 41, 28, 57, 32, 3, - 28, 3, 1, 27, 49, 49, 1, 32, 26, 26, 2, 4, 4, 7, 57, 41, - 2, 7, 10, 5, 37, 16, 10, 27, 8, 8, 13, 16, 37, 13, 1, 5}, - - /* value table */ - {0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, - -1, 1, -1, 1, -1, 1, -1, 2, 1, -2, -1, 1, -1, 1, 1, -1, - -1, 1, -1, 1, -1, 1, 0, -1, 1, 1, 1, -1, 1, -1, -1, -1, - 1, 1, 2, -1, -1, 1, -1, -2, 1, 1, -1, -1, 1, 1, -1, -1, - 1, -1, 3, 1, -3, 2, -1, 1, 1, -2, -1, -1, -1, 1, 1, 1, - 1, 1, -1, -1, -1, 2, -1, -2, 1, 2, -2, -1, 1, 1, 2, -1, - -1, 1, -2, -1, 1, 1, -1, 2, 1, 2, -1, 1, -2, -1, -2, -1, - -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 4, -1, -1, -4, - 1, 1, 1, 2, -1, -1, 1, -1, -1, 1, -1, -1, 1, -2, 1, -1, - 1, 1, -1, -1, 1, 1, -1, -1, 3, 2, -3, -2, 2, 5, -2, 2, - 2, -5, -2, -2, -2, 2, -3, 3, 2, 3, -3, 2, -2, -2, 3, -3, - 6, 2, -2, 3, -6, 3, -3, -3, 3, 7, -4, 4, -3, 2, -7, 2, - 2, -2, -4, 2, 8, -2, -2, -2, 4, 2, -2, 2, 3, 2, -2, -2, - 2, 2, -2, -8, -2, 9, -2, 2, -3, -2, 2, -2, 2, 2, 2, 4, - -2, -4, 10, 2, 2, -2, -9, -2, 2, -2, 5, 4, -4, 4, -2, 2, - -5, -4, -3, 4, 2, -3, 3, -2, -5, 5, 3, 3, -2, -3, -10, -4} -},{ - /* MapTab2 */ - 2, /* eob_sym */ - 11, /* esc_sym */ - /* run table */ - {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 0, 1, 1, 5, 5, - 2, 2, 6, 6, 7, 7, 1, 8, 1, 8, 3, 3, 9, 9, 1, 2, - 2, 1, 4, 10, 4, 10, 11, 11, 1, 5, 12, 12, 1, 5, 13, 13, - 3, 3, 6, 6, 2, 2, 14, 14, 16, 16, 15, 7, 15, 8, 8, 7, - 1, 1, 17, 17, 4, 4, 1, 1, 18, 18, 2, 2, 5, 5, 25, 3, - 9, 3, 25, 9, 19, 24, 19, 24, 1, 21, 20, 1, 21, 22, 20, 22, - 23, 23, 8, 6, 33, 6, 8, 33, 7, 7, 26, 26, 1, 32, 1, 32, - 28, 4, 28, 10, 29, 27, 27, 10, 41, 4, 29, 2, 2, 41, 36, 31, - 49, 31, 34, 30, 34, 36, 30, 35, 1, 49, 11, 5, 35, 11, 1, 3, - 3, 5, 37, 37, 8, 40, 8, 40, 12, 12, 42, 42, 1, 38, 16, 57, - 1, 6, 16, 39, 38, 6, 7, 7, 13, 13, 39, 43, 2, 43, 57, 2, - 50, 9, 44, 9, 50, 4, 15, 48, 44, 4, 1, 15, 48, 14, 14, 1, - 45, 45, 8, 3, 5, 8, 51, 47, 3, 46, 46, 47, 5, 51, 1, 17, - 17, 58, 1, 58, 2, 52, 52, 2, 53, 7, 59, 6, 6, 56, 53, 55, - 7, 55, 1, 54, 59, 56, 54, 10, 1, 10, 4, 60, 1, 60, 8, 4, - 8, 64, 64, 61, 1, 63, 3, 63, 62, 61, 5, 11, 5, 3, 11, 62}, - - /* value table */ - { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 0, 3, -3, 1, -1, - 2, -2, 1, -1, 1, -1, 4, 1, -4, -1, 2, -2, 1, -1, 5, 3, - -3, -5, 2, 1, -2, -1, 1, -1, 6, 2, 1, -1, -6, -2, 1, -1, - 3, -3, 2, -2, 4, -4, 1, -1, 1, -1, 1, 2, -1, 2, -2, -2, - 7, -7, 1, -1, 3, -3, 8, -8, 1, -1, 5, -5, 3, -3, 1, 4, - 2, -4, -1, -2, 1, 1, -1, -1, 9, 1, 1, -9, -1, 1, -1, -1, - 1, -1, 3, -3, 1, 3, -3, -1, 3, -3, 1, -1, 10, 1, -10, -1, - 1, 4, -1, 2, 1, -1, 1, -2, 1, -4, -1, 6, -6, -1, 1, 1, - 1, -1, 1, 1, -1, -1, -1, 1, 11, -1, -2, 4, -1, 2, -11, 5, - -5, -4, -1, 1, 4, 1, -4, -1, -2, 2, 1, -1, 12, 1, -2, 1, - -12, 4, 2, 1, -1, -4, 4, -4, 2, -2, -1, 1, 7, -1, -1, -7, - -1, -3, 1, 3, 1, 5, 2, 1, -1, -5, 13, -2, -1, 2, -2, -13, - 1, -1, 5, 6, 5, -5, 1, 1, -6, 1, -1, -1, -5, -1, 14, 2, - -2, 1, -14, -1, 8, 1, -1, -8, 1, 5, 1, 5, -5, 1, -1, 1, - -5, -1, 15, 1, -1, -1, -1, 3, -15, -3, 6, 1, 16, -1, 6, -6, - -6, 1, -1, 1, -16, 1, 7, -1, 1, -1, -6, -3, 6, -7, 3, -1} -},{ - /* MapTab3 */ - 0, /* eob_sym */ - 35, /* esc_sym */ - /* run table */ - {0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 5, 5, 6, 6, 7, - 7, 8, 8, 9, 9, 2, 2, 10, 10, 1, 1, 11, 11, 12, 12, 3, - 3, 13, 13, 0, 14, 14, 16, 15, 16, 15, 4, 4, 17, 1, 17, 1, - 5, 5, 18, 18, 2, 2, 6, 6, 8, 19, 7, 8, 7, 19, 20, 20, - 21, 21, 22, 24, 22, 24, 23, 23, 1, 1, 25, 25, 3, 3, 26, 26, - 9, 9, 27, 27, 28, 28, 33, 29, 4, 33, 29, 1, 4, 1, 32, 32, - 2, 2, 31, 10, 30, 10, 30, 31, 34, 34, 5, 5, 36, 36, 35, 41, - 35, 11, 41, 11, 37, 1, 8, 8, 37, 6, 1, 6, 40, 7, 7, 40, - 12, 38, 12, 39, 39, 38, 49, 13, 49, 13, 3, 42, 3, 42, 16, 16, - 43, 43, 14, 14, 1, 1, 44, 15, 44, 15, 2, 2, 57, 48, 50, 48, - 57, 50, 4, 45, 45, 4, 46, 47, 47, 46, 1, 51, 1, 17, 17, 51, - 8, 9, 9, 5, 58, 8, 58, 5, 52, 52, 55, 56, 53, 56, 55, 59, - 59, 53, 54, 1, 6, 54, 7, 7, 6, 1, 2, 3, 2, 3, 64, 60, - 60, 10, 10, 64, 61, 62, 61, 63, 1, 63, 62, 1, 18, 24, 18, 4, - 25, 4, 8, 21, 21, 1, 24, 22, 25, 22, 8, 11, 19, 11, 23, 1, - 20, 23, 19, 20, 5, 12, 5, 1, 16, 2, 12, 13, 2, 13, 1, 16}, - - /* value table */ - { 0, 1, -1, 1, -1, 1, -1, 1, -1, 2, -2, 1, -1, 1, -1, 1, - -1, 1, -1, 1, -1, 2, -2, 1, -1, 3, -3, 1, -1, 1, -1, 2, - -2, 1, -1, 0, 1, -1, 1, 1, -1, -1, 2, -2, 1, 4, -1, -4, - 2, -2, 1, -1, -3, 3, 2, -2, 2, 1, 2, -2, -2, -1, 1, -1, - 1, -1, 1, 1, -1, -1, 1, -1, 5, -5, 1, -1, 3, -3, 1, -1, - 2, -2, 1, -1, 1, -1, 1, 1, 3, -1, -1, 6, -3, -6, -1, 1, - 4, -4, 1, 2, 1, -2, -1, -1, 1, -1, 3, -3, 1, -1, 1, 1, - -1, 2, -1, -2, 1, 7, -3, 3, -1, 3, -7, -3, 1, -3, 3, -1, - 2, 1, -2, 1, -1, -1, 1, 2, -1, -2, -4, -1, 4, 1, 2, -2, - 1, -1, -2, 2, 8, -8, -1, 2, 1, -2, -5, 5, 1, -1, -1, 1, - -1, 1, 4, -1, 1, -4, -1, -1, 1, 1, 9, 1, -9, 2, -2, -1, - -4, 3, -3, -4, -1, 4, 1, 4, 1, -1, 1, -1, 1, 1, -1, 1, - -1, -1, -1, 10, 4, 1, 4, -4, -4, -10, 6, 5, -6, -5, 1, -1, - 1, 3, -3, -1, 1, -1, -1, -1, 11, 1, 1, -11, -2, -2, 2, 5, - -2, -5, -5, 2, -2, 12, 2, -2, 2, 2, 5, -3, -2, 3, -2, -12, - -2, 2, 2, 2, -5, 3, 5, 13, -3, 7, -3, -3, -7, 3, -13, 3} -},{ - /* MapTab4 */ - 0, /* eob_sym */ - 34, /* esc_sym */ - /* run table */ - {0, 1, 1, 1, 2, 2, 1, 3, 3, 1, 1, 1, 4, 4, 1, 5, - 2, 1, 5, 2, 1, 1, 6, 6, 1, 1, 1, 1, 1, 7, 3, 1, - 2, 3, 0, 1, 2, 7, 1, 1, 1, 8, 1, 1, 8, 1, 1, 1, - 9, 1, 9, 1, 2, 1, 1, 2, 1, 1, 10, 4, 1, 10, 1, 4, - 1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 2, 1, 5, 1, 1, 1, - 2, 5, 1, 11, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 6, 1, 6, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 12, - 3, 1, 12, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1, - 4, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 5, - 1, 1, 1, 1, 1, 7, 1, 7, 1, 1, 2, 3, 1, 1, 1, 1, - 5, 1, 1, 1, 1, 1, 1, 2, 13, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 13, 2, 1, 1, 4, 1, 1, 1, - 3, 1, 6, 1, 1, 1, 14, 1, 1, 1, 1, 1, 14, 6, 1, 1, - 1, 1, 15, 2, 4, 1, 2, 3, 15, 1, 1, 1, 8, 1, 1, 8, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1}, - - /* value table */ - { 0, 1, -1, 2, 1, -1, -2, 1, -1, 3, -3, 4, 1, -1, -4, 1, - 2, 5, -1, -2, -5, 6, 1, -1, -6, 7, -7, 8, -8, 1, 2, 9, - 3, -2, 0, -9, -3, -1, 10, -10, 11, 1, -11, 12, -1, -12, 13, -13, - 1, 14, -1, -14, 4, 15, -15, -4, 16, -16, 1, 2, 17, -1, -17, -2, - 18, -18, 19, -19, 20, 3, -20, 21, -21, -3, 5, 22, 2, -22, -23, 23, - -5, -2, 24, 1, -24, -1, 25, -25, 26, -26, -27, 27, 28, 29, -28, -29, - 6, 30, 2, -31, -2, -30, 31, -6, -32, 32, 33, -33, 34, -35, -34, 1, - 4, -36, -1, 35, 37, 36, 7, -37, 38, -4, -38, 39, 41, 40, -40, -39, - 3, 42, -43, -41, -7, -42, 43, -3, 44, -44, 45, -45, 46, 47, 8, -47, - -48, -46, 50, -50, 48, 49, 51, -49, 52, -52, 5, -51, -8, -53, 53, 3, - -56, 56, 55, 54, -54, 2, 60, -2, -55, 58, 9, -5, 59, 57, -57, -63, - -3, -58, -60, -61, 61, -59, -62, -9, 1, 64, 62, 69, -64, 63, 65, -67, - -68, 66, -65, 68, -66, -69, 67, -70, -1, 10, 71, -71, 4, 73, 72, 70, - 6, -76, -3, 74, -78, -74, 1, 78, 80, -72, -75, 76, -1, 3, -73, 79, - 75, 77, 1, 11, -4, -79, -10, -6, -1, -77, -83, -80, 2, 81, -84, -2, - 83, -81, 82, -82, 84, -87, -86, 85, -11, -85, 86, -89, 87, -88, 88, 89} -},{ - /* MapTab5 */ - 2, /* eob_sym */ - 33, /* esc_sym */ - /* run table */ - {1, 1, 0, 2, 1, 2, 1, 3, 3, 1, 1, 4, 4, 2, 2, 1, - 1, 5, 5, 6, 1, 6, 1, 7, 7, 3, 3, 2, 8, 2, 8, 1, - 1, 0, 9, 9, 1, 1, 10, 4, 10, 4, 11, 11, 2, 1, 2, 1, - 12, 12, 3, 3, 1, 1, 13, 5, 5, 13, 14, 1, 1, 14, 2, 2, - 6, 6, 15, 1, 1, 15, 16, 4, 7, 16, 4, 7, 1, 1, 3, 3, - 8, 8, 2, 2, 1, 1, 17, 17, 1, 1, 18, 18, 5, 5, 2, 2, - 1, 1, 9, 19, 9, 19, 20, 3, 3, 20, 1, 10, 21, 1, 10, 4, - 4, 21, 22, 6, 6, 22, 1, 1, 23, 24, 2, 2, 23, 24, 11, 1, - 1, 11, 7, 25, 7, 1, 1, 25, 8, 8, 3, 26, 3, 1, 12, 2, - 2, 26, 1, 12, 5, 5, 27, 4, 1, 4, 1, 27, 28, 1, 28, 13, - 1, 13, 2, 29, 2, 1, 32, 6, 1, 30, 14, 29, 14, 6, 3, 31, - 3, 1, 30, 1, 32, 31, 33, 9, 33, 1, 1, 7, 9, 7, 2, 2, - 1, 1, 4, 36, 34, 4, 5, 10, 10, 5, 34, 1, 1, 35, 8, 8, - 36, 3, 35, 1, 15, 3, 2, 1, 16, 15, 16, 2, 37, 1, 37, 1, - 1, 1, 6, 6, 38, 1, 38, 11, 1, 39, 39, 40, 11, 2, 41, 4, - 40, 1, 2, 4, 1, 1, 1, 41, 3, 1, 3, 1, 5, 7, 5, 7}, - - /* value table */ - { 1, -1, 0, 1, 2, -1, -2, 1, -1, 3, -3, 1, -1, 2, -2, 4, - -4, 1, -1, 1, 5, -1, -5, 1, -1, 2, -2, 3, 1, -3, -1, 6, - -6, 0, 1, -1, 7, -7, 1, 2, -1, -2, 1, -1, 4, 8, -4, -8, - 1, -1, 3, -3, 9, -9, 1, 2, -2, -1, 1, 10, -10, -1, 5, -5, - 2, -2, 1, 11, -11, -1, 1, 3, 2, -1, -3, -2, 12, -12, 4, -4, - 2, -2, -6, 6, 13, -13, 1, -1, 14, -14, 1, -1, 3, -3, 7, -7, - 15, -15, 2, 1, -2, -1, 1, 5, -5, -1, -16, 2, 1, 16, -2, 4, - -4, -1, 1, 3, -3, -1, 17, -17, 1, 1, -8, 8, -1, -1, 2, 18, - -18, -2, 3, 1, -3, 19, -19, -1, 3, -3, 6, 1, -6, 20, 2, 9, - -9, -1, -20, -2, 4, -4, 1, -5, 21, 5, -21, -1, 1, -22, -1, 2, - 22, -2, 10, 1, -10, 23, 1, 4, -23, 1, 2, -1, -2, -4, -7, 1, - 7, -24, -1, 24, -1, -1, 1, 3, -1, -25, 25, 4, -3, -4, 11, -11, - 26, -26, 6, 1, 1, -6, -5, -3, 3, 5, -1, -27, 27, 1, 4, -4, - -1, -8, -1, 28, 2, 8, -12, -28, -2, -2, 2, 12, -1, 29, 1, -29, - 30, -30, 5, -5, 1, -31, -1, 3, 31, -1, 1, 1, -3, -13, 1, -7, - -1, -32, 13, 7, 32, 33, -33, -1, -9, -34, 9, 34, -6, 5, 6, -5} -},{ - /* MapTab6 */ - 2, /* eob_sym */ - 13, /* esc_sym */ - /* run table */ - {1, 1, 0, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 0, 2, 2, - 4, 1, 4, 1, 1, 1, 5, 5, 1, 1, 6, 6, 2, 2, 1, 1, - 3, 3, 7, 7, 1, 1, 8, 8, 1, 1, 2, 2, 1, 9, 1, 9, - 4, 4, 10, 1, 1, 10, 1, 1, 11, 11, 3, 3, 1, 2, 1, 2, - 1, 1, 12, 12, 5, 5, 1, 1, 13, 1, 1, 13, 2, 2, 1, 1, - 6, 6, 1, 1, 4, 14, 4, 14, 3, 1, 3, 1, 1, 1, 15, 7, - 15, 2, 2, 7, 1, 1, 1, 8, 1, 8, 16, 16, 1, 1, 1, 1, - 2, 1, 1, 2, 1, 1, 3, 5, 5, 3, 4, 1, 1, 4, 1, 1, - 17, 17, 9, 1, 1, 9, 2, 2, 1, 1, 10, 10, 1, 6, 1, 1, - 6, 18, 1, 1, 18, 1, 1, 1, 2, 2, 3, 1, 3, 1, 1, 1, - 4, 1, 19, 1, 19, 7, 1, 1, 20, 1, 4, 20, 1, 7, 11, 2, - 1, 11, 21, 2, 8, 5, 1, 8, 1, 5, 21, 1, 1, 1, 22, 1, - 1, 22, 1, 1, 3, 3, 1, 23, 2, 12, 24, 1, 1, 2, 1, 1, - 12, 23, 1, 1, 24, 1, 1, 1, 4, 1, 1, 1, 2, 1, 6, 6, - 4, 2, 1, 1, 1, 1, 1, 1, 1, 14, 13, 3, 1, 25, 9, 25, - 14, 1, 9, 3, 13, 1, 1, 1, 1, 1, 10, 1, 1, 2, 10, 2}, - - /* value table */ - {-20, -1, 0, 2, -2, 1, -1, 3, -3, 1, -1, 4, -4, 0, 2, -2, - 1, 5, -1, -5, 6, -6, 1, -1, 7, -7, 1, -1, 3, -3, 8, -8, - 2, -2, 1, -1, 9, -9, 1, -1, 10, -10, 4, -4, 11, 1, -11, -1, - 2, -2, 1, 12, -12, -1, 13, -13, 1, -1, 3, -3, 14, 5, -14, -5, - -15, 15, -1, 1, 2, -2, 16, -16, 1, 17, -17, -1, 6, -6, 18, -18, - 2, -2, -19, 19, -3, 1, 3, -1, 4, 20, -4, 1, -21, 21, 1, 2, - -1, -7, 7, -2, 22, -22, 23, 2, -23, -2, 1, -1, -24, 24, -25, 25, - -8, -26, 26, 8, -27, 27, 5, 3, -3, -5, -4, 28, -28, 4, 29, -29, - 1, -1, -2, -30, 30, 2, 9, -9, -31, 31, 2, -2, -32, 3, 32, -33, - -3, 1, 33, -34, -1, 34, -35, 35, -10, 10, -6, 36, 6, -36, 37, -37, - -5, 38, 1, -38, -1, 3, 39, -39, -1, 40, 5, 1, -40, -3, 2, -11, - -41, -2, 1, 11, -3, -4, 41, 3, 42, 4, -1, -43, -42, 43, 1, -44, - 45, -1, 44, -45, -7, 7, -46, 1, -12, 2, 1, -47, 46, 12, 47, 48, - -2, -1, -48, 49, -1, -50, -49, 50, -6, -51, 51, 52, -13, 53, -4, 4, - 6, 13, -53, -52, -54, 55, 54, -55, -56, -2, 2, -8, 56, 1, -3, -1, - 2, 58, 3, 8, -2, 57, -58, -60, -59, -57, -3, 60, 59, -14, 3, 14} -},{ - /* MapTab7 */ - 2, /* eob_sym */ - 38, /* esc_sym */ - /* run table */ - {1, 1, 0, 2, 2, 1, 1, 3, 3, 4, 4, 5, 5, 1, 1, 6, - 6, 2, 2, 7, 7, 8, 8, 1, 1, 3, 3, 9, 9, 10, 10, 1, - 1, 2, 2, 4, 4, 11, 0, 11, 12, 12, 13, 13, 1, 1, 5, 5, - 14, 14, 15, 16, 15, 16, 3, 3, 1, 6, 1, 6, 2, 2, 7, 7, - 8, 8, 17, 17, 1, 1, 4, 4, 18, 18, 2, 2, 1, 19, 1, 20, - 19, 20, 21, 21, 3, 3, 22, 22, 5, 5, 24, 1, 1, 23, 9, 23, - 24, 9, 2, 2, 10, 1, 1, 10, 6, 6, 25, 4, 4, 25, 7, 7, - 26, 8, 1, 8, 3, 1, 26, 3, 11, 11, 27, 27, 2, 28, 1, 2, - 28, 1, 12, 12, 5, 5, 29, 13, 13, 29, 32, 1, 1, 33, 31, 30, - 32, 4, 30, 33, 4, 31, 3, 14, 1, 1, 3, 34, 34, 2, 2, 14, - 6, 6, 35, 36, 35, 36, 1, 15, 1, 16, 16, 15, 7, 9, 7, 9, - 37, 8, 8, 37, 1, 1, 39, 2, 38, 39, 2, 40, 5, 38, 40, 5, - 3, 3, 4, 4, 10, 10, 1, 1, 1, 1, 41, 2, 41, 2, 6, 6, - 1, 1, 11, 42, 11, 43, 3, 42, 3, 17, 4, 43, 1, 17, 7, 1, - 8, 44, 4, 7, 44, 5, 8, 2, 5, 1, 2, 48, 45, 1, 12, 45, - 12, 48, 13, 13, 1, 9, 9, 46, 1, 46, 47, 47, 49, 18, 18, 49}, - - /* value table */ - { 1, -1, 0, 1, -1, 2, -2, 1, -1, 1, -1, 1, -1, 3, -3, 1, - -1, -2, 2, 1, -1, 1, -1, 4, -4, -2, 2, 1, -1, 1, -1, 5, - -5, -3, 3, 2, -2, 1, 0, -1, 1, -1, 1, -1, 6, -6, 2, -2, - 1, -1, 1, 1, -1, -1, -3, 3, 7, 2, -7, -2, -4, 4, 2, -2, - 2, -2, 1, -1, 8, -8, 3, -3, 1, -1, -5, 5, 9, 1, -9, 1, - -1, -1, 1, -1, -4, 4, 1, -1, 3, -3, 1, -10, 10, 1, 2, -1, - -1, -2, 6, -6, 2, 11, -11, -2, 3, -3, 1, -4, 4, -1, 3, -3, - 1, 3, 12, -3, -5, -12, -1, 5, 2, -2, 1, -1, -7, 1, 13, 7, - -1, -13, 2, -2, 4, -4, 1, 2, -2, -1, 1, 14, -14, 1, 1, 1, - -1, -5, -1, -1, 5, -1, -6, 2, -15, 15, 6, 1, -1, -8, 8, -2, - -4, 4, 1, 1, -1, -1, 16, 2, -16, -2, 2, -2, 4, 3, -4, -3, - -1, -4, 4, 1, -17, 17, -1, -9, 1, 1, 9, 1, -5, -1, -1, 5, - -7, 7, 6, -6, 3, -3, 18, -18, 19, -19, 1, -10, -1, 10, -5, 5, - 20, -20, -3, 1, 3, 1, 8, -1, -8, 2, 7, -1, -21, -2, 5, 21, - 5, -1, -7, -5, 1, -6, -5, -11, 6, 22, 11, 1, 1, -22, -3, -1, - 3, -1, 3, -3, -23, 4, -4, 1, 23, -1, 1, -1, 1, -2, 2, -1} -},{ - /* MapTab8 */ - 4, /* eob_sym */ - 11, /* esc_sym */ - /* run table */ - {1, 1, 1, 1, 0, 2, 2, 1, 1, 3, 3, 0, 1, 1, 2, 2, - 4, 4, 1, 1, 5, 5, 1, 1, 2, 2, 3, 3, 6, 6, 1, 1, - 7, 7, 8, 1, 8, 2, 2, 1, 4, 4, 1, 3, 1, 3, 9, 9, - 2, 2, 1, 5, 1, 5, 10, 10, 1, 1, 11, 11, 3, 6, 3, 4, - 4, 6, 2, 2, 1, 12, 1, 12, 7, 13, 7, 13, 1, 1, 8, 8, - 2, 2, 14, 14, 16, 15, 16, 5, 5, 1, 3, 15, 1, 3, 4, 4, - 1, 1, 17, 17, 2, 2, 6, 6, 1, 18, 1, 18, 22, 21, 22, 21, - 25, 24, 25, 19, 9, 20, 9, 23, 19, 24, 20, 3, 23, 7, 3, 1, - 1, 7, 28, 26, 29, 5, 28, 26, 5, 8, 29, 4, 8, 27, 2, 2, - 4, 27, 1, 1, 10, 36, 10, 33, 33, 36, 30, 1, 32, 32, 1, 30, - 6, 31, 31, 35, 3, 6, 11, 11, 3, 2, 35, 2, 34, 1, 34, 1, - 37, 37, 12, 7, 12, 5, 41, 5, 4, 7, 1, 8, 13, 4, 1, 41, - 13, 38, 8, 38, 9, 1, 40, 40, 9, 1, 39, 2, 2, 49, 39, 42, - 3, 3, 14, 16, 49, 14, 16, 42, 43, 43, 6, 6, 15, 1, 1, 15, - 44, 44, 1, 1, 50, 48, 4, 5, 4, 7, 5, 2, 10, 10, 48, 7, - 50, 45, 2, 1, 45, 8, 8, 1, 46, 46, 3, 47, 47, 3, 1, 1}, - - /* value table */ - { 1, -1, 2, -2, 0, 1, -1, 3, -3, 1, -1, 0, 4, -4, 2, -2, - 1, -1, 5, -5, 1, -1, 6, -6, 3, -3, 2, -2, 1, -1, 7, -7, - 1, -1, 1, 8, -1, 4, -4, -8, 2, -2, 9, 3, -9, -3, 1, -1, - 5, -5, 10, 2, -10, -2, 1, -1, 11, -11, 1, -1, -4, 2, 4, 3, - -3, -2, 6, -6, 12, 1, -12, -1, 2, 1, -2, -1, 13, -13, 2, -2, - 7, -7, 1, -1, 1, 1, -1, 3, -3, 14, 5, -1, -14, -5, 4, -4, - 15, -15, 1, -1, 8, -8, -3, 3, 16, 1, -16, -1, 1, 1, -1, -1, - 1, 1, -1, 1, 2, 1, -2, 1, -1, -1, -1, 6, -1, 3, -6, 17, - -17, -3, 1, 1, 1, 4, -1, -1, -4, 3, -1, 5, -3, -1, -9, 9, - -5, 1, 18, -18, 2, 1, -2, 1, -1, -1, 1, 19, -1, 1, -19, -1, - 4, 1, -1, 1, 7, -4, -2, 2, -7, 10, -1, -10, 1, 20, -1, -20, - 1, -1, 2, 4, -2, 5, 1, -5, 6, -4, 21, 4, 2, -6, -21, -1, - -2, 1, -4, -1, -3, 22, -1, 1, 3, -22, -1, 11, -11, 1, 1, 1, - 8, -8, 2, 2, -1, -2, -2, -1, 1, -1, -5, 5, 2, 23, -23, -2, - 1, -1, 24, -24, -1, -1, 7, 6, -7, 5, -6, 12, -3, 3, 1, -5, - 1, 1, -12, 25, -1, -5, 5, -25, -1, 1, 9, 1, -1, -9, 26, -26} -} -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ivi_common.h b/tizen/distrib/ffmpeg/libavcodec/ivi_common.h deleted file mode 100644 index 64793e4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ivi_common.h +++ /dev/null @@ -1,342 +0,0 @@ -/* - * common functions for Indeo Video Interactive codecs (Indeo4 and Indeo5) - * - * Copyright (c) 2009 Maxim Poliakovski - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * This file contains structures and macros shared by both Indeo4 and - * Indeo5 decoders. - */ - -#ifndef AVCODEC_IVI_COMMON_H -#define AVCODEC_IVI_COMMON_H - -#include "avcodec.h" -#include "get_bits.h" -#include - -#define IVI_DEBUG 0 - -#define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes - -/** - * huffman codebook descriptor - */ -typedef struct { - int32_t num_rows; - uint8_t xbits[16]; -} IVIHuffDesc; - -/** - * macroblock/block huffman table descriptor - */ -typedef struct { - int32_t tab_sel; /// index of one of the predefined tables - /// or "7" for custom one - VLC *tab; /// pointer to the table associated with tab_sel - - //! the following are used only when tab_sel == 7 - IVIHuffDesc cust_desc; /// custom Huffman codebook descriptor - VLC cust_tab; /// vlc table for custom codebook -} IVIHuffTab; - -enum { - IVI_MB_HUFF = 0, /// Huffman table is used for coding macroblocks - IVI_BLK_HUFF = 1 /// Huffman table is used for coding blocks -}; - -extern VLC ff_ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables -extern VLC ff_ivi_blk_vlc_tabs[8]; ///< static block Huffman tables - - -/** - * run-value (RLE) table descriptor - */ -typedef struct { - uint8_t eob_sym; ///< end of block symbol - uint8_t esc_sym; ///< escape symbol - uint8_t runtab[256]; - int8_t valtab[256]; -} RVMapDesc; - -extern const RVMapDesc ff_ivi_rvmap_tabs[9]; - - -/** - * information for Indeo macroblock (16x16, 8x8 or 4x4) - */ -typedef struct { - int16_t xpos; - int16_t ypos; - uint32_t buf_offs; ///< address in the output buffer for this mb - uint8_t type; ///< macroblock type: 0 - INTRA, 1 - INTER - uint8_t cbp; ///< coded block pattern - int8_t q_delta; ///< quant delta - int8_t mv_x; ///< motion vector (x component) - int8_t mv_y; ///< motion vector (y component) -} IVIMbInfo; - - -/** - * information for Indeo tile - */ -typedef struct { - int xpos; - int ypos; - int width; - int height; - int is_empty; ///< = 1 if this tile doesn't contain any data - int data_size; ///< size of the data in bytes - int num_MBs; ///< number of macroblocks in this tile - IVIMbInfo *mbs; ///< array of macroblock descriptors - IVIMbInfo *ref_mbs; ///< ptr to the macroblock descriptors of the reference tile -} IVITile; - - -/** - * information for Indeo wavelet band - */ -typedef struct { - int plane; ///< plane number this band belongs to - int band_num; ///< band number - int width; - int height; - const uint8_t *data_ptr; ///< ptr to the first byte of the band data - int data_size; ///< size of the band data - int16_t *buf; ///< pointer to the output buffer for this band - int16_t *ref_buf; ///< pointer to the reference frame buffer (for motion compensation) - int16_t *bufs[3]; ///< array of pointers to the band buffers - int pitch; ///< pitch associated with the buffers above - int is_empty; ///< = 1 if this band doesn't contain any data - int mb_size; ///< macroblock size - int blk_size; ///< block size - int is_halfpel; ///< precision of the motion compensation: 0 - fullpel, 1 - halfpel - int inherit_mv; ///< tells if motion vector is inherited from reference macroblock - int inherit_qdelta; ///< tells if quantiser delta is inherited from reference macroblock - int qdelta_present; ///< tells if Qdelta signal is present in the bitstream (Indeo5 only) - int quant_mat; ///< dequant matrix index - int glob_quant; ///< quant base for this band - const uint8_t *scan; ///< ptr to the scan pattern - - IVIHuffTab blk_vlc; ///< vlc table for decoding block data - - uint16_t *dequant_intra; ///< ptr to dequant tables for intra blocks - uint16_t *dequant_inter; ///< ptr dequant tables for inter blocks - int num_corr; ///< number of correction entries - uint8_t corr[61*2]; ///< rvmap correction pairs - int rvmap_sel; ///< rvmap table selector - RVMapDesc *rv_map; ///< ptr to the RLE table for this band - int num_tiles; ///< number of tiles in this band - IVITile *tiles; ///< array of tile descriptors - void (*inv_transform)(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags); ///< inverse transform function pointer - void (*dc_transform) (const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); ///< dc transform function pointer, it may be NULL - int is_2d_trans; ///< 1 indicates that the two-dimensional inverse transform is used - int32_t checksum; ///< for debug purposes - int checksum_present; - int bufsize; ///< band buffer size in bytes - const uint8_t *intra_base; ///< quantization matrix for intra blocks - const uint8_t *inter_base; ///< quantization matrix for inter blocks - const uint8_t *intra_scale; ///< quantization coefficient for intra blocks - const uint8_t *inter_scale; ///< quantization coefficient for inter blocks -} IVIBandDesc; - - -/** - * color plane (luma or chroma) information - */ -typedef struct { - uint16_t width; - uint16_t height; - uint8_t num_bands; ///< number of bands this plane subdivided into - IVIBandDesc *bands; ///< array of band descriptors -} IVIPlaneDesc; - - -typedef struct { - uint16_t pic_width; - uint16_t pic_height; - uint16_t chroma_width; - uint16_t chroma_height; - uint16_t tile_width; - uint16_t tile_height; - uint8_t luma_bands; - uint8_t chroma_bands; -} IVIPicConfig; - -/** compares some properties of two pictures */ -static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2) -{ - return (str1->pic_width != str2->pic_width || str1->pic_height != str2->pic_height || - str1->chroma_width != str2->chroma_width || str1->chroma_height != str2->chroma_height || - str1->tile_width != str2->tile_width || str1->tile_height != str2->tile_height || - str1->luma_bands != str2->luma_bands || str1->chroma_bands != str2->chroma_bands); -} - -/** calculate number of tiles in a stride */ -#define IVI_NUM_TILES(stride, tile_size) (((stride) + (tile_size) - 1) / (tile_size)) - -/** calculate number of macroblocks in a tile */ -#define IVI_MBs_PER_TILE(tile_width, tile_height, mb_size) \ - ((((tile_width) + (mb_size) - 1) / (mb_size)) * (((tile_height) + (mb_size) - 1) / (mb_size))) - -/** convert unsigned values into signed ones (the sign is in the LSB) */ -#define IVI_TOSIGNED(val) (-(((val) >> 1) ^ -((val) & 1))) - -/** scales motion vector */ -static inline int ivi_scale_mv(int mv, int mv_scale) -{ - return (mv + (mv > 0) + (mv_scale - 1)) >> mv_scale; -} - -/** - * Generates a huffman codebook from the given descriptor - * and converts it into the FFmpeg VLC table. - * - * @param cb [in] pointer to codebook descriptor - * @param vlc [out] where to place the generated VLC table - * @param flag [in] flag: 1 - for static or 0 for dynamic tables - * @return result code: 0 - OK, -1 = error (invalid codebook descriptor) - */ -int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag); - -/** - * Initializes static codes used for macroblock and block decoding. - */ -void ff_ivi_init_static_vlc(void); - -/** - * Decodes a huffman codebook descriptor from the bitstream - * and selects specified huffman table. - * - * @param gb [in,out] the GetBit context - * @param desc_coded [in] flag signalling if table descriptor was coded - * @param which_tab [in] codebook purpose (IVI_MB_HUFF or IVI_BLK_HUFF) - * @param huff_tab [out] pointer to the descriptor of the selected table - * @param avctx [in] AVCodecContext pointer - * @return zero on success, negative value otherwise - */ -int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, - IVIHuffTab *huff_tab, AVCodecContext *avctx); - -/** - * Compares two huffman codebook descriptors. - * - * @param desc1 [in] ptr to the 1st descriptor to compare - * @param desc2 [in] ptr to the 2nd descriptor to compare - * @return comparison result: 0 - equal, 1 - not equal - */ -int ff_ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2); - -/** - * Copies huffman codebook descriptors. - * - * @param dst [out] ptr to the destination descriptor - * @param src [in] ptr to the source descriptor - */ -void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src); - -/** - * Initializes planes (prepares descriptors, allocates buffers etc). - * - * @param planes [in,out] pointer to the array of the plane descriptors - * @param cfg [in] pointer to the ivi_pic_config structure describing picture layout - * @return result code: 0 - OK - */ -int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg); - -/** - * Frees planes, bands and macroblocks buffers. - * - * @param planes [in] pointer to the array of the plane descriptors - */ -void ff_ivi_free_buffers(IVIPlaneDesc *planes); - -/** - * Initializes tile and macroblock descriptors. - * - * @param planes [in,out] pointer to the array of the plane descriptors - * @param tile_width [in] tile width - * @param tile_height [in] tile height - * @return result code: 0 - OK - */ -int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height); - -/** - * Decodes size of the tile data. - * The size is stored as a variable-length field having the following format: - * if (tile_data_size < 255) than this field is only one byte long - * if (tile_data_size >= 255) than this field four is byte long: 0xFF X1 X2 X3 - * where X1-X3 is size of the tile data - * - * @param gb [in,out] the GetBit context - * @return size of the tile data in bytes - */ -int ff_ivi_dec_tile_data_size(GetBitContext *gb); - -/** - * Decodes block data: - * extracts huffman-coded transform coefficients from the bitstream, - * dequantizes them, applies inverse transform and motion compensation - * in order to reconstruct the picture. - * - * @param gb [in,out] the GetBit context - * @param band [in] pointer to the band descriptor - * @param tile [in] pointer to the tile descriptor - * @return result code: 0 - OK, -1 = error (corrupted blocks data) - */ -int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile); - -/** - * Handles empty tiles by performing data copying and motion - * compensation respectively. - * - * @param avctx [in] ptr to the AVCodecContext - * @param band [in] pointer to the band descriptor - * @param tile [in] pointer to the tile descriptor - * @param mv_scale [in] scaling factor for motion vectors - */ -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, - IVITile *tile, int32_t mv_scale); - -/** - * Converts and outputs the current plane. - * This conversion is done by adding back the bias value of 128 - * (subtracted in the encoder) and clipping the result. - * - * @param plane [in] pointer to the descriptor of the plane being processed - * @param dst [out] pointer to the buffer receiving converted pixels - * @param dst_pitch [in] pitch for moving to the next y line - */ -void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch); - -#if IVI_DEBUG -/** - * Calculates band checksum from band data. - */ -uint16_t ivi_calc_band_checksum (IVIBandDesc *band); - -/** - * Verifies that band data lies in range. - */ -int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch); -#endif - -#endif /* AVCODEC_IVI_COMMON_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ivi_dsp.c b/tizen/distrib/ffmpeg/libavcodec/ivi_dsp.c deleted file mode 100644 index ccaffd4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ivi_dsp.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5) - * - * Copyright (c) 2009 Maxim Poliakovski - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * DSP functions (inverse transforms, motion compensation, wavelet recompostions) - * for Indeo Video Interactive codecs. - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "dwt.h" -#include "ivi_common.h" -#include "ivi_dsp.h" - -void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, - const int dst_pitch, const int num_bands) -{ - int x, y, indx; - int32_t p0, p1, p2, p3, tmp0, tmp1, tmp2; - int32_t b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6; - int32_t b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9; - int32_t pitch, back_pitch; - const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr; - - /* all bands should have the same pitch */ - pitch = plane->bands[0].pitch; - - /* pixels at the position "y-1" will be set to pixels at the "y" for the 1st iteration */ - back_pitch = 0; - - /* get pointers to the wavelet bands */ - b0_ptr = plane->bands[0].buf; - b1_ptr = plane->bands[1].buf; - b2_ptr = plane->bands[2].buf; - b3_ptr = plane->bands[3].buf; - - for (y = 0; y < plane->height; y += 2) { - /* load storage variables with values */ - if (num_bands > 0) { - b0_1 = b0_ptr[0]; - b0_2 = b0_ptr[pitch]; - } - - if (num_bands > 1) { - b1_1 = b1_ptr[back_pitch]; - b1_2 = b1_ptr[0]; - b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch]; - } - - if (num_bands > 2) { - b2_2 = b2_ptr[0]; // b2[x, y ] - b2_3 = b2_2; // b2[x+1,y ] = b2[x,y] - b2_5 = b2_ptr[pitch]; // b2[x ,y+1] - b2_6 = b2_5; // b2[x+1,y+1] = b2[x,y+1] - } - - if (num_bands > 3) { - b3_2 = b3_ptr[back_pitch]; // b3[x ,y-1] - b3_3 = b3_2; // b3[x+1,y-1] = b3[x ,y-1] - b3_5 = b3_ptr[0]; // b3[x ,y ] - b3_6 = b3_5; // b3[x+1,y ] = b3[x ,y ] - b3_8 = b3_2 - b3_5*6 + b3_ptr[pitch]; - b3_9 = b3_8; - } - - for (x = 0, indx = 0; x < plane->width; x+=2, indx++) { - /* some values calculated in the previous iterations can */ - /* be reused in the next ones, so do appropriate copying */ - b2_1 = b2_2; // b2[x-1,y ] = b2[x, y ] - b2_2 = b2_3; // b2[x ,y ] = b2[x+1,y ] - b2_4 = b2_5; // b2[x-1,y+1] = b2[x ,y+1] - b2_5 = b2_6; // b2[x ,y+1] = b2[x+1,y+1] - b3_1 = b3_2; // b3[x-1,y-1] = b3[x ,y-1] - b3_2 = b3_3; // b3[x ,y-1] = b3[x+1,y-1] - b3_4 = b3_5; // b3[x-1,y ] = b3[x ,y ] - b3_5 = b3_6; // b3[x ,y ] = b3[x+1,y ] - b3_7 = b3_8; // vert_HPF(x-1) - b3_8 = b3_9; // vert_HPF(x ) - - p0 = p1 = p2 = p3 = 0; - - /* process the LL-band by applying LPF both vertically and horizontally */ - if (num_bands > 0) { - tmp0 = b0_1; - tmp2 = b0_2; - b0_1 = b0_ptr[indx+1]; - b0_2 = b0_ptr[pitch+indx+1]; - tmp1 = tmp0 + b0_1; - - p0 = tmp0 << 4; - p1 = tmp1 << 3; - p2 = (tmp0 + tmp2) << 3; - p3 = (tmp1 + tmp2 + b0_2) << 2; - } - - /* process the HL-band by applying HPF vertically and LPF horizontally */ - if (num_bands > 1) { - tmp0 = b1_2; - tmp1 = b1_1; - b1_2 = b1_ptr[indx+1]; - b1_1 = b1_ptr[back_pitch+indx+1]; - - tmp2 = tmp1 - tmp0*6 + b1_3; - b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch+indx+1]; - - p0 += (tmp0 + tmp1) << 3; - p1 += (tmp0 + tmp1 + b1_1 + b1_2) << 2; - p2 += tmp2 << 2; - p3 += (tmp2 + b1_3) << 1; - } - - /* process the LH-band by applying LPF vertically and HPF horizontally */ - if (num_bands > 2) { - b2_3 = b2_ptr[indx+1]; - b2_6 = b2_ptr[pitch+indx+1]; - - tmp0 = b2_1 + b2_2; - tmp1 = b2_1 - b2_2*6 + b2_3; - - p0 += tmp0 << 3; - p1 += tmp1 << 2; - p2 += (tmp0 + b2_4 + b2_5) << 2; - p3 += (tmp1 + b2_4 - b2_5*6 + b2_6) << 1; - } - - /* process the HH-band by applying HPF both vertically and horizontally */ - if (num_bands > 3) { - b3_6 = b3_ptr[indx+1]; // b3[x+1,y ] - b3_3 = b3_ptr[back_pitch+indx+1]; // b3[x+1,y-1] - - tmp0 = b3_1 + b3_4; - tmp1 = b3_2 + b3_5; - tmp2 = b3_3 + b3_6; - - b3_9 = b3_3 - b3_6*6 + b3_ptr[pitch+indx+1]; - - p0 += (tmp0 + tmp1) << 2; - p1 += (tmp0 - tmp1*6 + tmp2) << 1; - p2 += (b3_7 + b3_8) << 1; - p3 += b3_7 - b3_8*6 + b3_9; - } - - /* output four pixels */ - dst[x] = av_clip_uint8((p0 >> 6) + 128); - dst[x+1] = av_clip_uint8((p1 >> 6) + 128); - dst[dst_pitch+x] = av_clip_uint8((p2 >> 6) + 128); - dst[dst_pitch+x+1] = av_clip_uint8((p3 >> 6) + 128); - }// for x - - dst += dst_pitch << 1; - - back_pitch = -pitch; - - b0_ptr += pitch; - b1_ptr += pitch; - b2_ptr += pitch; - b3_ptr += pitch; - } -} - -/** butterfly operation for the inverse slant transform */ -#define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \ - t = s1 - s2;\ - o1 = s1 + s2;\ - o2 = t;\ - -/** This is a reflection a,b = 1/2, 5/4 for the inverse slant transform */ -#define IVI_IREFLECT(s1, s2, o1, o2, t) \ - t = ((s1 + s2*2 + 2) >> 2) + s1;\ - o2 = ((s1*2 - s2 + 2) >> 2) - s2;\ - o1 = t;\ - -/** This is a reflection a,b = 1/2, 7/8 for the inverse slant transform */ -#define IVI_SLANT_PART4(s1, s2, o1, o2, t) \ - t = s2 + ((s1*4 - s2 + 4) >> 3);\ - o2 = s1 + ((-s1 - s2*4 + 4) >> 3);\ - o1 = t;\ - -/** inverse slant8 transform */ -#define IVI_INV_SLANT8(s1, s4, s8, s5, s2, s6, s3, s7,\ - d1, d2, d3, d4, d5, d6, d7, d8,\ - t0, t1, t2, t3, t4, t5, t6, t7, t8) {\ - IVI_SLANT_PART4(s4, s5, t4, t5, t0);\ -\ - IVI_SLANT_BFLY(s1, t5, t1, t5, t0); IVI_SLANT_BFLY(s2, s6, t2, t6, t0);\ - IVI_SLANT_BFLY(s7, s3, t7, t3, t0); IVI_SLANT_BFLY(t4, s8, t4, t8, t0);\ -\ - IVI_SLANT_BFLY(t1, t2, t1, t2, t0); IVI_IREFLECT (t4, t3, t4, t3, t0);\ - IVI_SLANT_BFLY(t5, t6, t5, t6, t0); IVI_IREFLECT (t8, t7, t8, t7, t0);\ - IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\ - IVI_SLANT_BFLY(t5, t8, t5, t8, t0); IVI_SLANT_BFLY(t6, t7, t6, t7, t0);\ - d1 = COMPENSATE(t1);\ - d2 = COMPENSATE(t2);\ - d3 = COMPENSATE(t3);\ - d4 = COMPENSATE(t4);\ - d5 = COMPENSATE(t5);\ - d6 = COMPENSATE(t6);\ - d7 = COMPENSATE(t7);\ - d8 = COMPENSATE(t8);} - -/** inverse slant4 transform */ -#define IVI_INV_SLANT4(s1, s4, s2, s3, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\ - IVI_SLANT_BFLY(s1, s2, t1, t2, t0); IVI_IREFLECT (s4, s3, t4, t3, t0);\ -\ - IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\ - d1 = COMPENSATE(t1);\ - d2 = COMPENSATE(t2);\ - d3 = COMPENSATE(t3);\ - d4 = COMPENSATE(t4);} - -void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) -{ - int i; - const int32_t *src; - int32_t *dst; - int tmp[64]; - int t0, t1, t2, t3, t4, t5, t6, t7, t8; - -#define COMPENSATE(x) (x) - src = in; - dst = tmp; - for (i = 0; i < 8; i++) { - if (flags[i]) { - IVI_INV_SLANT8(src[0], src[8], src[16], src[24], src[32], src[40], src[48], src[56], - dst[0], dst[8], dst[16], dst[24], dst[32], dst[40], dst[48], dst[56], - t0, t1, t2, t3, t4, t5, t6, t7, t8); - } else - dst[0] = dst[8] = dst[16] = dst[24] = dst[32] = dst[40] = dst[48] = dst[56] = 0; - - src++; - dst++; - } -#undef COMPENSATE - -#define COMPENSATE(x) ((x + 1)>>1) - src = tmp; - for (i = 0; i < 8; i++) { - if (!src[0] && !src[1] && !src[2] && !src[3] && !src[4] && !src[5] && !src[6] && !src[7]) { - memset(out, 0, 8*sizeof(out[0])); - } else { - IVI_INV_SLANT8(src[0], src[1], src[2], src[3], src[4], src[5], src[6], src[7], - out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], - t0, t1, t2, t3, t4, t5, t6, t7, t8); - } - src += 8; - out += pitch; - } -#undef COMPENSATE -} - -void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) -{ - int i; - const int32_t *src; - int32_t *dst; - int tmp[16]; - int t0, t1, t2, t3, t4; - -#define COMPENSATE(x) (x) - src = in; - dst = tmp; - for (i = 0; i < 4; i++) { - if (flags[i]) { - IVI_INV_SLANT4(src[0], src[4], src[8], src[12], - dst[0], dst[4], dst[8], dst[12], - t0, t1, t2, t3, t4); - } else - dst[0] = dst[4] = dst[8] = dst[12] = 0; - - src++; - dst++; - } -#undef COMPENSATE - -#define COMPENSATE(x) ((x + 1)>>1) - src = tmp; - for (i = 0; i < 4; i++) { - if (!src[0] && !src[1] && !src[2] && !src[3]) { - out[0] = out[1] = out[2] = out[3] = 0; - } else { - IVI_INV_SLANT4(src[0], src[1], src[2], src[3], - out[0], out[1], out[2], out[3], - t0, t1, t2, t3, t4); - } - src += 4; - out += pitch; - } -#undef COMPENSATE -} - -void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size) -{ - int x, y; - int16_t dc_coeff; - - dc_coeff = (*in + 1) >> 1; - - for (y = 0; y < blk_size; out += pitch, y++) { - for (x = 0; x < blk_size; x++) - out[x] = dc_coeff; - } -} - -void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) -{ - int i; - int t0, t1, t2, t3, t4, t5, t6, t7, t8; - -#define COMPENSATE(x) ((x + 1)>>1) - for (i = 0; i < 8; i++) { - if (!in[0] && !in[1] && !in[2] && !in[3] && !in[4] && !in[5] && !in[6] && !in[7]) { - memset(out, 0, 8*sizeof(out[0])); - } else { - IVI_INV_SLANT8( in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7], - out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], - t0, t1, t2, t3, t4, t5, t6, t7, t8); - } - in += 8; - out += pitch; - } -#undef COMPENSATE -} - -void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size) -{ - int x, y; - int16_t dc_coeff; - - dc_coeff = (*in + 1) >> 1; - - for (x = 0; x < blk_size; x++) - out[x] = dc_coeff; - - out += pitch; - - for (y = 1; y < blk_size; out += pitch, y++) { - for (x = 0; x < blk_size; x++) - out[x] = 0; - } -} - -void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags) -{ - int i, row2, row4, row8; - int t0, t1, t2, t3, t4, t5, t6, t7, t8; - - row2 = pitch << 1; - row4 = pitch << 2; - row8 = pitch << 3; - -#define COMPENSATE(x) ((x + 1)>>1) - for (i = 0; i < 8; i++) { - if (flags[i]) { - IVI_INV_SLANT8(in[0], in[8], in[16], in[24], in[32], in[40], in[48], in[56], - out[0], out[pitch], out[row2], out[row2 + pitch], out[row4], - out[row4 + pitch], out[row4 + row2], out[row8 - pitch], - t0, t1, t2, t3, t4, t5, t6, t7, t8); - } else { - out[0] = out[pitch] = out[row2] = out[row2 + pitch] = out[row4] = - out[row4 + pitch] = out[row4 + row2] = out[row8 - pitch] = 0; - } - - in++; - out++; - } -#undef COMPENSATE -} - -void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size) -{ - int x, y; - int16_t dc_coeff; - - dc_coeff = (*in + 1) >> 1; - - for (y = 0; y < blk_size; out += pitch, y++) { - out[0] = dc_coeff; - for (x = 1; x < blk_size; x++) - out[x] = 0; - } -} - -void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch, - const uint8_t *flags) -{ - int x, y; - - for (y = 0; y < 8; out += pitch, in += 8, y++) - for (x = 0; x < 8; x++) - out[x] = in[x]; -} - -void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch, - int blk_size) -{ - int y; - - out[0] = in[0]; - memset(out + 1, 0, 7*sizeof(out[0])); - out += pitch; - - for (y = 1; y < 8; out += pitch, y++) - memset(out, 0, 8*sizeof(out[0])); -} - -#define IVI_MC_TEMPLATE(size, suffix, OP) \ -void ff_ivi_mc_ ## size ##x## size ## suffix (int16_t *buf, const int16_t *ref_buf, \ - uint32_t pitch, int mc_type) \ -{ \ - int i, j; \ - const int16_t *wptr; \ -\ - switch (mc_type) { \ - case 0: /* fullpel (no interpolation) */ \ - for (i = 0; i < size; i++, buf += pitch, ref_buf += pitch) { \ - for (j = 0; j < size; j++) {\ - OP(buf[j], ref_buf[j]); \ - } \ - } \ - break; \ - case 1: /* horizontal halfpel interpolation */ \ - for (i = 0; i < size; i++, buf += pitch, ref_buf += pitch) \ - for (j = 0; j < size; j++) \ - OP(buf[j], (ref_buf[j] + ref_buf[j+1]) >> 1); \ - break; \ - case 2: /* vertical halfpel interpolation */ \ - wptr = ref_buf + pitch; \ - for (i = 0; i < size; i++, buf += pitch, wptr += pitch, ref_buf += pitch) \ - for (j = 0; j < size; j++) \ - OP(buf[j], (ref_buf[j] + wptr[j]) >> 1); \ - break; \ - case 3: /* vertical and horizontal halfpel interpolation */ \ - wptr = ref_buf + pitch; \ - for (i = 0; i < size; i++, buf += pitch, wptr += pitch, ref_buf += pitch) \ - for (j = 0; j < size; j++) \ - OP(buf[j], (ref_buf[j] + ref_buf[j+1] + wptr[j] + wptr[j+1]) >> 2); \ - break; \ - } \ -} \ - -#define OP_PUT(a, b) (a) = (b) -#define OP_ADD(a, b) (a) += (b) - -IVI_MC_TEMPLATE(8, _no_delta, OP_PUT); -IVI_MC_TEMPLATE(8, _delta, OP_ADD); -IVI_MC_TEMPLATE(4, _no_delta, OP_PUT); -IVI_MC_TEMPLATE(4, _delta, OP_ADD); diff --git a/tizen/distrib/ffmpeg/libavcodec/ivi_dsp.h b/tizen/distrib/ffmpeg/libavcodec/ivi_dsp.h deleted file mode 100644 index bdd9654..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ivi_dsp.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5) - * - * Copyright (c) 2009 Maxim Poliakovski - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * DSP functions (inverse transforms, motion compensations, wavelet recompostion) - * for Indeo Video Interactive codecs. - */ - -#ifndef AVCODEC_IVI_DSP_H -#define AVCODEC_IVI_DSP_H - -#include "avcodec.h" -#include "ivi_common.h" - -/** - * 5/3 wavelet recomposition filter for Indeo5 - * - * @param plane [in] pointer to the descriptor of the plane being processed - * @param dst [out] pointer to the destination buffer - * @param dst_pitch [in] pitch of the destination buffer - * @param num_bands [in] number of wavelet bands to be processed - */ -void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst, - const int dst_pitch, const int num_bands); - -/** - * two-dimensional inverse slant 8x8 transform - * - * @param in [in] pointer to the vector of transform coefficients - * @param out [out] pointer to the output buffer (frame) - * @param pitch [in] pitch to move to the next y line - * @param flags [in] pointer to the array of column flags: - * != 0 - non_empty column, 0 - empty one - * (this array must be filled by caller) - */ -void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, - const uint8_t *flags); - -/** - * two-dimensional inverse slant 4x4 transform - * - * @param in [in] pointer to the vector of transform coefficients - * @param out [out] pointer to the output buffer (frame) - * @param pitch [in] pitch to move to the next y line - * @param flags [in] pointer to the array of column flags: - * != 0 - non_empty column, 0 - empty one - * (this array must be filled by caller) - */ -void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, - const uint8_t *flags); - -/** - * DC-only two-dimensional inverse slant transform. - * Performing the inverse slant transform in this case is equivalent to - * spreading (DC_coeff + 1)/2 over the whole block. - * It works much faster than performing the slant transform on a vector of zeroes. - * - * @param in [in] pointer to the dc coefficient - * @param out [out] pointer to the output buffer (frame) - * @param pitch [in] pitch to move to the next y line - * @param blk_size [in] transform block size - */ -void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); - -/** - * inverse 1D row slant transform - * - * @param in [in] pointer to the vector of transform coefficients - * @param out [out] pointer to the output buffer (frame) - * @param pitch [in] pitch to move to the next y line - * @param flags [in] pointer to the array of column flags (unused here) - */ -void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, - const uint8_t *flags); - -/** - * inverse 1D column slant transform - * - * @param in [in] pointer to the vector of transform coefficients - * @param out [out] pointer to the output buffer (frame) - * @param pitch [in] pitch to move to the next y line - * @param flags [in] pointer to the array of column flags: - * != 0 - non_empty column, 0 - empty one - * (this array must be filled by caller) - */ -void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, - const uint8_t *flags); - -/** - * DC-only inverse row slant transform - */ -void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); - -/** - * DC-only inverse column slant transform - */ -void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); - -/** - * Copies the pixels into the frame buffer. - */ -void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags); - -/** - * Copies the DC coefficient into the first pixel of the block and - * zeroes all others. - */ -void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size); - -/** - * 8x8 block motion compensation with adding delta - * - * @param buf [in,out] pointer to the block in the current frame buffer containing delta - * @param ref_buf [in] pointer to the corresponding block in the reference frame - * @param pitch [in] pitch for moving to the next y line - * @param mc_type [in] interpolation type - */ -void ff_ivi_mc_8x8_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - -/** - * 4x4 block motion compensation with adding delta - * - * @param buf [in,out] pointer to the block in the current frame buffer containing delta - * @param ref_buf [in] pointer to the corresponding block in the reference frame - * @param pitch [in] pitch for moving to the next y line - * @param mc_type [in] interpolation type - */ -void ff_ivi_mc_4x4_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - -/** - * motion compensation without adding delta - * - * @param buf [in,out] pointer to the block in the current frame receiving the result - * @param ref_buf [in] pointer to the corresponding block in the reference frame - * @param pitch [in] pitch for moving to the next y line - * @param mc_type [in] interpolation type - */ -void ff_ivi_mc_8x8_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - -/** - * 4x4 block motion compensation without adding delta - * - * @param buf [in,out] pointer to the block in the current frame receiving the result - * @param ref_buf [in] pointer to the corresponding block in the reference frame - * @param pitch [in] pitch for moving to the next y line - * @param mc_type [in] interpolation type - */ -void ff_ivi_mc_4x4_no_delta(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - -#endif /* AVCODEC_IVI_DSP_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/jfdctfst.c b/tizen/distrib/ffmpeg/libavcodec/jfdctfst.c deleted file mode 100644 index b911909..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jfdctfst.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * jfdctfst.c - * - * This file is part of the Independent JPEG Group's software. - * - * The authors make NO WARRANTY or representation, either express or implied, - * with respect to this software, its quality, accuracy, merchantability, or - * fitness for a particular purpose. This software is provided "AS IS", and - * you, its user, assume the entire risk as to its quality and accuracy. - * - * This software is copyright (C) 1994-1996, Thomas G. Lane. - * All Rights Reserved except as specified below. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * software (or portions thereof) for any purpose, without fee, subject to - * these conditions: - * (1) If any part of the source code for this software is distributed, then - * this README file must be included, with this copyright and no-warranty - * notice unaltered; and any additions, deletions, or changes to the original - * files must be clearly indicated in accompanying documentation. - * (2) If only executable code is distributed, then the accompanying - * documentation must state that "this software is based in part on the work - * of the Independent JPEG Group". - * (3) Permission for use of this software is granted only if the user accepts - * full responsibility for any undesirable consequences; the authors accept - * NO LIABILITY for damages of any kind. - * - * These conditions apply to any software derived from or based on the IJG - * code, not just to the unmodified library. If you use our work, you ought - * to acknowledge us. - * - * Permission is NOT granted for the use of any IJG author's name or company - * name in advertising or publicity relating to this software or products - * derived from it. This software may be referred to only as "the Independent - * JPEG Group's software". - * - * We specifically permit and encourage the use of this software as the basis - * of commercial products, provided that all warranty or liability claims are - * assumed by the product vendor. - * - * 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 - * Independent JPEG Group's fast AAN dct. - */ - -#include -#include -#include "libavutil/common.h" -#include "dsputil.h" - -#define DCTSIZE 8 -#define GLOBAL(x) x -#define RIGHT_SHIFT(x, n) ((x) >> (n)) - -/* - * 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 av_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; - - /* 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; - - 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; - - 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/tizen/distrib/ffmpeg/libavcodec/jfdctint.c b/tizen/distrib/ffmpeg/libavcodec/jfdctint.c deleted file mode 100644 index f6e8c4e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jfdctint.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * jfdctint.c - * - * This file is part of the Independent JPEG Group's software. - * - * The authors make NO WARRANTY or representation, either express or implied, - * with respect to this software, its quality, accuracy, merchantability, or - * fitness for a particular purpose. This software is provided "AS IS", and - * you, its user, assume the entire risk as to its quality and accuracy. - * - * This software is copyright (C) 1991-1996, Thomas G. Lane. - * All Rights Reserved except as specified below. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * software (or portions thereof) for any purpose, without fee, subject to - * these conditions: - * (1) If any part of the source code for this software is distributed, then - * this README file must be included, with this copyright and no-warranty - * notice unaltered; and any additions, deletions, or changes to the original - * files must be clearly indicated in accompanying documentation. - * (2) If only executable code is distributed, then the accompanying - * documentation must state that "this software is based in part on the work - * of the Independent JPEG Group". - * (3) Permission for use of this software is granted only if the user accepts - * full responsibility for any undesirable consequences; the authors accept - * NO LIABILITY for damages of any kind. - * - * These conditions apply to any software derived from or based on the IJG - * code, not just to the unmodified library. If you use our work, you ought - * to acknowledge us. - * - * Permission is NOT granted for the use of any IJG author's name or company - * name in advertising or publicity relating to this software or products - * derived from it. This software may be referred to only as "the Independent - * JPEG Group's software". - * - * We specifically permit and encourage the use of this software as the basis - * of commercial products, provided that all warranty or liability claims are - * assumed by the product vendor. - * - * 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 - * Independent JPEG Group's slow & accurate dct. - */ - -#include -#include -#include "libavutil/common.h" -#include "dsputil.h" - -#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 av_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; - - /* 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; - - 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; - - 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/tizen/distrib/ffmpeg/libavcodec/jpegls.c b/tizen/distrib/ffmpeg/libavcodec/jpegls.c deleted file mode 100644 index c40b929..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jpegls.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * JPEG-LS common code - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * JPEG-LS common code. - */ - -#include "jpegls.h" - -void ff_jpegls_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] = FFMAX((state->range + 32) >> 6, 2); - state->N[i] = 1; - } - -} - -/** - * 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; -} - -void ff_jpegls_reset_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 + 7*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); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/jpegls.h b/tizen/distrib/ffmpeg/libavcodec/jpegls.h deleted file mode 100644 index 28c7524..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jpegls.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * JPEG-LS common code - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * JPEG-LS common code. - */ - -#ifndef AVCODEC_JPEGLS_H -#define AVCODEC_JPEGLS_H - -#include "avcodec.h" - -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; - -extern const uint8_t ff_log2_run[32]; - -/** - * Calculate initial JPEG-LS parameters - */ -void ff_jpegls_init_state(JLSState *state); - -/** - * Calculate quantized gradient value, used for context determination - */ -static inline int ff_jpegls_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; - } -} - -/** - * Calculate JPEG-LS codec values - */ -void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all); - - -static inline void ff_jpegls_downscale_state(JLSState *state, int Q){ - if(state->N[Q] == state->reset){ - state->A[Q] >>=1; - state->B[Q] >>=1; - state->N[Q] >>=1; - } - state->N[Q]++; -} - -static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){ - state->A[Q] += FFABS(err); - err *= state->twonear; - state->B[Q] += err; - - ff_jpegls_downscale_state(state, Q); - - if(state->B[Q] <= -state->N[Q]) { - state->B[Q]= FFMAX(state->B[Q] + state->N[Q], 1-state->N[Q]); - if(state->C[Q] > -128) - state->C[Q]--; - }else if(state->B[Q] > 0){ - state->B[Q]= FFMIN(state->B[Q] - state->N[Q], 0); - if(state->C[Q] < 127) - state->C[Q]++; - } - - return err; -} - -#define R(a, i ) (bits == 8 ? ((uint8_t*)(a))[i] : ((uint16_t*)(a))[i] ) -#define W(a, i, v) (bits == 8 ? (((uint8_t*)(a))[i]=v) : (((uint16_t*)(a))[i]=v)) - -#endif /* AVCODEC_JPEGLS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/jpeglsdec.c b/tizen/distrib/ffmpeg/libavcodec/jpeglsdec.c deleted file mode 100644 index 6b7dd94..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jpeglsdec.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * JPEG-LS decoder - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * JPEG-LS decoder. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "golomb.h" -#include "mathops.h" -#include "mjpeg.h" -#include "mjpegdec.h" -#include "jpegls.h" -#include "jpeglsdec.h" - - -/* -* 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 - - -/** - * Decode LSE block with initialization parameters - */ -int ff_jpegls_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); - -// ff_jpegls_reset_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); - - ret= ff_jpegls_update_state_regular(state, Q, ret); - - 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; - - temp= state->A[Q]; - if(RItype) - temp += 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] += FFABS(ret) - RItype; - ret *= state->twonear; - ff_jpegls_downscale_state(state, Q); - - return ret; -} - -/** - * Decode one line of image - */ -static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){ - int i, x = 0; - int Ra, Rb, Rc, Rd; - int D0, D1, D2; - - while(x < w) { - int err, pred; - - /* compute gradients */ - Ra = x ? R(dst, x - stride) : R(last, x); - Rb = R(last, x); - Rc = x ? R(last, x - stride) : last2; - Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); - D0 = Rd - Rb; - D1 = Rb - Rc; - D2 = Rc - Ra; - /* run mode */ - if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { - int r; - int RItype; - - /* decode full runs while available */ - while(get_bits1(&s->gb)) { - int r; - r = 1 << ff_log2_run[state->run_index[comp]]; - if(x + r * stride > w) { - r = (w - x) / stride; - } - for(i = 0; i < r; i++) { - W(dst, x, Ra); - x += stride; - } - /* if EOL reached, we stop decoding */ - if(r != (1 << ff_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 = ff_log2_run[state->run_index[comp]]; - if(r) - r = get_bits_long(&s->gb, r); - for(i = 0; i < r; i++) { - W(dst, x, Ra); - x += stride; - } - - /* decode run termination value */ - Rb = R(last, x); - RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; - err = ls_get_code_runterm(&s->gb, state, RItype, ff_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; - } - } else { /* regular mode */ - int context, sign; - - context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2); - pred = mid_pred(Ra, Ra + Rb - Rc, Rb); - - if(context < 0){ - context = -context; - sign = 1; - }else{ - sign = 0; - } - - if(sign){ - pred = av_clip(pred - state->C[context], 0, state->maxval); - err = -ls_get_code_regular(&s->gb, state, context); - } else { - pred = av_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 = av_clip(pred, 0, state->maxval); - } - - pred &= state->maxval; - W(dst, x, pred); - x += stride; - } -} - -int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){ - int i, t = 0; - uint8_t *zero, *last, *cur; - JLSState *state; - int off = 0, stride = 1, width, shift; - - 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; - ff_jpegls_reset_coding_parameters(state, 0); - ff_jpegls_init_state(state); - - if(s->bits <= 8) - shift = point_transform + (8 - s->bits); - else - shift = point_transform + (16 - s->bits); - -// 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++) { - if(s->bits <= 8){ - ls_decode_line(state, s, last, cur, t, width, stride, off, 8); - t = last[0]; - }else{ - ls_decode_line(state, s, last, cur, t, width, stride, off, 16); - t = *((uint16_t*)last); - } - 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, 8); - 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"); - av_free(state); - av_free(zero); - return -1; - } - - if(shift){ /* we need to do point transform or normalize samples */ - int x, w; - - w = s->width * s->nb_components; - - if(s->bits <= 8){ - uint8_t *src = s->picture.data[0]; - - for(i = 0; i < s->height; i++){ - for(x = off; x < w; x+= stride){ - src[x] <<= shift; - } - src += s->picture.linesize[0]; - } - }else{ - uint16_t *src = (uint16_t*) s->picture.data[0]; - - for(i = 0; i < s->height; i++){ - for(x = 0; x < w; x++){ - src[x] <<= shift; - } - src += s->picture.linesize[0]/2; - } - } - } - av_free(state); - av_free(zero); - - return 0; -} - - -AVCodec jpegls_decoder = { - "jpegls", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_JPEGLS, - sizeof(MJpegDecodeContext), - ff_mjpeg_decode_init, - NULL, - ff_mjpeg_decode_end, - ff_mjpeg_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/jpeglsdec.h b/tizen/distrib/ffmpeg/libavcodec/jpeglsdec.h deleted file mode 100644 index 5204ecb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jpeglsdec.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * JPEG-LS decoder - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * JPEG-LS decoder. - */ - -#ifndef AVCODEC_JPEGLSDEC_H -#define AVCODEC_JPEGLSDEC_H - -#include "mjpeg.h" -#include "mjpegdec.h" - -/** - * Decode LSE block with initialization parameters - */ -int ff_jpegls_decode_lse(MJpegDecodeContext *s); - -int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv); - -#endif /* AVCODEC_JPEGLSDEC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/jpeglsenc.c b/tizen/distrib/ffmpeg/libavcodec/jpeglsenc.c deleted file mode 100644 index 08ef71f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jpeglsenc.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * JPEG-LS encoder - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * JPEG-LS encoder. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "golomb.h" -#include "mathops.h" -#include "dsputil.h" -#include "mjpeg.h" -#include "jpegls.h" - - -/** - * 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 * FFABS(err) - 1 - map; - } else - val = 2 * err + map; - - set_ur_golomb_jpegls(pb, val, k, state->limit, state->qbpp); - - ff_jpegls_update_state_regular(state, Q, err); -} - -/** - * 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; - - ff_jpegls_downscale_state(state, 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 << ff_log2_run[state->run_index[comp]])){ - put_bits(pb, 1, 1); - run -= 1 << ff_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(ff_log2_run[state->run_index[comp]]) - put_bits(pb, ff_log2_run[state->run_index[comp]], run); - } -} - -/** - * Encode one line of image - */ -static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last, void *cur, int last2, int w, int stride, int comp, int bits){ - int x = 0; - int Ra, Rb, Rc, Rd; - int D0, D1, D2; - - while(x < w) { - int err, pred, sign; - - /* compute gradients */ - Ra = x ? R(cur, x - stride) : R(last, x); - Rb = R(last, x); - Rc = x ? R(last, x - stride) : last2; - Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); - D0 = Rd - Rb; - D1 = Rb - Rc; - D2 = Rc - Ra; - - /* run mode */ - if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { - int RUNval, RItype, run; - - run = 0; - RUNval = Ra; - while(x < w && (FFABS(R(cur, x) - RUNval) <= state->near)){ - run++; - W(cur, x, Ra); - x += stride; - } - ls_encode_run(state, pb, run, comp, x < w); - if(x >= w) - return; - Rb = R(last, x); - RItype = (FFABS(Ra - Rb) <= state->near); - pred = RItype ? Ra : Rb; - err = R(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 = av_clip(pred + err * state->twonear, 0, state->maxval); - else - Ra = av_clip(pred - err * state->twonear, 0, state->maxval); - W(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, ff_log2_run[state->run_index[comp]]); - - if(state->run_index[comp] > 0) - state->run_index[comp]--; - } else { /* regular mode */ - int context; - - context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2); - pred = mid_pred(Ra, Ra + Rb - Rc, Rb); - - if(context < 0){ - context = -context; - sign = 1; - pred = av_clip(pred - state->C[context], 0, state->maxval); - err = pred - R(cur, x); - }else{ - sign = 0; - pred = av_clip(pred + state->C[context], 0, state->maxval); - err = R(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 = av_clip(pred + err * state->twonear, 0, state->maxval); - else - Ra = av_clip(pred - err * state->twonear, 0, state->maxval); - W(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 = state->bpp; - state2.near = state->near; - ff_jpegls_reset_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; - - if(avctx->pix_fmt == PIX_FMT_GRAY8 || avctx->pix_fmt == PIX_FMT_GRAY16) - comps = 1; - else - comps = 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, (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 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 = (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 8; - ff_jpegls_reset_coding_parameters(state, 0); - ff_jpegls_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, 8); - t = last[0]; - last = cur; - cur += p->linesize[0]; - } - }else if(avctx->pix_fmt == PIX_FMT_GRAY16){ - int t = 0; - - for(i = 0; i < avctx->height; i++) { - ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16); - t = *((uint16_t*)last); - 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, 8); - 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, 8); - Rc[j] = last[j]; - } - last = cur; - cur += s->picture.linesize[0]; - } - } - - av_free(zero); - av_free(state); - - // the specification says that after doing 0xff escaping unused bits in the - // last byte must be set to 0, so just append 7 "optional" zero-bits to - // avoid special-casing. - put_bits(&pb2, 7, 0); - size = put_bits_count(&pb2); - flush_put_bits(&pb2); - /* do escape coding */ - init_get_bits(&gb, buf2, size); - size -= 7; - while(get_bits_count(&gb) < size){ - 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 av_cold 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_GRAY16 && 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 should not need them - "jpegls", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_JPEGLS, - sizeof(JpeglsContext), - encode_init_ls, - encode_picture_ls, - NULL, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB24, PIX_FMT_GRAY8, PIX_FMT_GRAY16, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("JPEG-LS"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/jrevdct.c b/tizen/distrib/ffmpeg/libavcodec/jrevdct.c deleted file mode 100644 index 9e28dae..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/jrevdct.c +++ /dev/null @@ -1,1157 +0,0 @@ -/* - * jrevdct.c - * - * This file is part of the Independent JPEG Group's software. - * - * The authors make NO WARRANTY or representation, either express or implied, - * with respect to this software, its quality, accuracy, merchantability, or - * fitness for a particular purpose. This software is provided "AS IS", and - * you, its user, assume the entire risk as to its quality and accuracy. - * - * This software is copyright (C) 1991, 1992, Thomas G. Lane. - * All Rights Reserved except as specified below. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * software (or portions thereof) for any purpose, without fee, subject to - * these conditions: - * (1) If any part of the source code for this software is distributed, then - * this README file must be included, with this copyright and no-warranty - * notice unaltered; and any additions, deletions, or changes to the original - * files must be clearly indicated in accompanying documentation. - * (2) If only executable code is distributed, then the accompanying - * documentation must state that "this software is based in part on the work - * of the Independent JPEG Group". - * (3) Permission for use of this software is granted only if the user accepts - * full responsibility for any undesirable consequences; the authors accept - * NO LIABILITY for damages of any kind. - * - * These conditions apply to any software derived from or based on the IJG - * code, not just to the unmodified library. If you use our work, you ought - * to acknowledge us. - * - * Permission is NOT granted for the use of any IJG author's name or company - * name in advertising or publicity relating to this software or products - * derived from it. This software may be referred to only as "the Independent - * JPEG Group's software". - * - * We specifically permit and encourage the use of this software as the basis - * of commercial products, provided that all warranty or liability claims are - * assumed by the product vendor. - * - * 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 - * Independent JPEG Group's LLM idct. - */ - -#include "libavutil/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 */ - 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; - 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/tizen/distrib/ffmpeg/libavcodec/kgv1dec.c b/tizen/distrib/ffmpeg/libavcodec/kgv1dec.c deleted file mode 100644 index 5af6b3b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/kgv1dec.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Kega Game Video (KGV1) decoder - * Copyright (c) 2010 Daniel Verkamp - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Kega Game Video decoder - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct { - AVCodecContext *avctx; - AVFrame pic; - uint16_t *prev, *cur; -} KgvContext; - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - const uint8_t *buf_end = buf + avpkt->size; - KgvContext * const c = avctx->priv_data; - int offsets[7]; - uint16_t *out, *prev; - int outcnt = 0, maxcnt; - int w, h, i; - - if (avpkt->size < 2) - return -1; - - w = (buf[0] + 1) * 8; - h = (buf[1] + 1) * 8; - buf += 2; - - if (avcodec_check_dimensions(avctx, w, h)) - return -1; - - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - - maxcnt = w * h; - - out = av_realloc(c->cur, w * h * 2); - if (!out) - return -1; - c->cur = out; - - prev = av_realloc(c->prev, w * h * 2); - if (!prev) - return -1; - c->prev = prev; - - for (i = 0; i < 7; i++) - offsets[i] = -1; - - while (outcnt < maxcnt && buf_end - 2 > buf) { - int code = AV_RL16(buf); - buf += 2; - - if (!(code & 0x8000)) { - out[outcnt++] = code; // rgb555 pixel coded directly - } else { - int count; - uint16_t *inp; - - if ((code & 0x6000) == 0x6000) { - // copy from previous frame - int oidx = (code >> 10) & 7; - int start; - - count = (code & 0x3FF) + 3; - - if (offsets[oidx] < 0) { - if (buf_end - 3 < buf) - break; - offsets[oidx] = AV_RL24(buf); - buf += 3; - } - - start = (outcnt + offsets[oidx]) % maxcnt; - - if (maxcnt - start < count) - break; - - inp = prev + start; - } else { - // copy from earlier in this frame - int offset = (code & 0x1FFF) + 1; - - if (!(code & 0x6000)) { - count = 2; - } else if ((code & 0x6000) == 0x2000) { - count = 3; - } else { - if (buf_end - 1 < buf) - break; - count = 4 + *buf++; - } - - if (outcnt < offset) - break; - - inp = out + outcnt - offset; - } - - if (maxcnt - outcnt < count) - break; - - for (i = 0; i < count; i++) - out[outcnt++] = inp[i]; - } - } - - if (outcnt - maxcnt) - av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt); - - c->pic.data[0] = (uint8_t *)c->cur; - c->pic.linesize[0] = w * 2; - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - FFSWAP(uint16_t *, c->cur, c->prev); - - return avpkt->size; -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - KgvContext * const c = avctx->priv_data; - - c->avctx = avctx; - avctx->pix_fmt = PIX_FMT_RGB555; - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - KgvContext * const c = avctx->priv_data; - - av_freep(&c->cur); - av_freep(&c->prev); - - return 0; -} - -AVCodec kgv1_decoder = { - "kgv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_KGV1, - sizeof(KgvContext), - decode_init, - NULL, - decode_end, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/kmvc.c b/tizen/distrib/ffmpeg/libavcodec/kmvc.c deleted file mode 100644 index 3e8dccd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/kmvc.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * KMVC decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Karl Morton's Video Codec decoder - */ - -#include -#include - -#include "avcodec.h" -#include "bytestream.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, const 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, const 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, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - KmvcContext *const ctx = 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++; - - /* blocksize 127 is really palette change event */ - if (buf[0] == 127) { - buf += 3; - for (i = 0; i < 127; i++) { - ctx->pal[i + (header & 0x81)] = AV_RB24(buf); - buf += 4; - } - buf -= 127 * 4 + 3; - } - - 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 palette has been changed, copy it from palctrl */ - if (ctx->avctx->palctrl && ctx->avctx->palctrl->palette_changed) { - memcpy(ctx->pal, ctx->avctx->palctrl->palette, AVPALETTE_SIZE); - ctx->setpal = 1; - ctx->avctx->palctrl->palette_changed = 0; - } - - 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] = bytestream_get_be24(&buf); - } - } - - 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 && blocksize != 127) { - av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize); - return -1; - } - memset(ctx->cur, 0, 320 * 200); - switch (header & KMVC_METHOD) { - case 0: - case 1: // used in palette changed event - memcpy(ctx->cur, ctx->prev, 320 * 200); - break; - 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 av_cold int decode_init(AVCodecContext * avctx) -{ - KmvcContext *const c = avctx->priv_data; - int i; - - c->avctx = avctx; - - 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 = AV_RL16(avctx->extradata + 10); - } - - if (avctx->extradata_size == 1036) { // palette in extradata - uint8_t *src = avctx->extradata + 12; - for (i = 0; i < 256; i++) { - c->pal[i] = AV_RL32(src); - src += 4; - } - c->setpal = 1; - if (c->avctx->palctrl) { - c->avctx->palctrl->palette_changed = 0; - } - } - - avctx->pix_fmt = PIX_FMT_PAL8; - - return 0; -} - - - -/* - * Uninit kmvc decoder - */ -static av_cold int decode_end(AVCodecContext * avctx) -{ - KmvcContext *const c = avctx->priv_data; - - av_freep(&c->frm0); - av_freep(&c->frm1); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - -AVCodec kmvc_decoder = { - "kmvc", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_KMVC, - sizeof(KmvcContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/lcl.h b/tizen/distrib/ffmpeg/libavcodec/lcl.h deleted file mode 100644 index b60c0e9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lcl.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * LCL (LossLess Codec Library) Codec - * Copyright (c) 2002-2004 Roberto Togni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_LCL_H -#define AVCODEC_LCL_H - -#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 - -#endif /* AVCODEC_LCL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/lcldec.c b/tizen/distrib/ffmpeg/libavcodec/lcldec.c deleted file mode 100644 index 2bf448a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lcldec.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * LCL (LossLess Codec Library) Codec - * Copyright (c) 2002-2004 Roberto Togni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 "avcodec.h" -#include "bytestream.h" -#include "lcl.h" -#include "libavutil/lzo.h" - -#if CONFIG_ZLIB_DECODER -#include -#endif - -/* - * Decoder context - */ -typedef struct LclDecContext { - AVFrame pic; - - // Image type - int imgtype; - // Compression type - int compression; - // Flags - int flags; - // Decompressed data size - unsigned int decomp_size; - // Decompression buffer - unsigned char* decomp_buf; -#if CONFIG_ZLIB_DECODER - z_stream zstream; -#endif -} LclDecContext; - - -/** - * \param srcptr compressed source buffer, must be padded with at least 5 extra bytes - * \param destptr must be padded sufficiently for av_memcpy_backptr - */ -static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) -{ - unsigned char *destptr_bak = destptr; - unsigned char *destptr_end = destptr + destsize; - const unsigned char *srcptr_end = srcptr + srclen; - unsigned mask = *srcptr++; - unsigned maskbit = 0x80; - - while (srcptr < srcptr_end && destptr < destptr_end) { - if (!(mask & maskbit)) { - memcpy(destptr, srcptr, 4); - destptr += 4; - srcptr += 4; - } else { - unsigned ofs = bytestream_get_le16(&srcptr); - unsigned cnt = (ofs >> 11) + 1; - ofs &= 0x7ff; - ofs = FFMIN(ofs, destptr - destptr_bak); - cnt *= 4; - cnt = FFMIN(cnt, destptr_end - destptr); - av_memcpy_backptr(destptr, ofs, cnt); - destptr += cnt; - } - maskbit >>= 1; - if (!maskbit) { - mask = *srcptr++; - while (!mask) { - if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break; - memcpy(destptr, srcptr, 32); - destptr += 32; - srcptr += 32; - mask = *srcptr++; - } - maskbit = 0x80; - } - } - - return destptr - destptr_bak; -} - - -/** - * \brief decompress a zlib-compressed data block into decomp_buf - * \param src compressed input buffer - * \param src_len data length in input buffer - * \param offset offset in decomp_buf - * \param expected expected decompressed length - */ -#if CONFIG_ZLIB_DECODER -static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) -{ - LclDecContext *c = avctx->priv_data; - int zret = inflateReset(&c->zstream); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); - return -1; - } - c->zstream.next_in = src; - c->zstream.avail_in = src_len; - c->zstream.next_out = c->decomp_buf + offset; - c->zstream.avail_out = c->decomp_size - offset; - 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 (expected != (unsigned int)c->zstream.total_out) { - av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", - expected, c->zstream.total_out); - return -1; - } - return c->zstream.total_out; -} -#endif - - -/* - * - * Decode a frame - * - */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - LclDecContext * const c = avctx->priv_data; - unsigned char *encoded = (unsigned char *)buf; - unsigned int pixel_ptr; - int row, col; - unsigned char *outptr; - uint8_t *y_out, *u_out, *v_out; - 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; - 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 = AV_RL32(encoded); - mthread_inlen = FFMIN(mthread_inlen, len - 8); - mthread_outlen = AV_RL32(encoded+4); - mthread_outlen = FFMIN(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 - 8 - 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; -#if CONFIG_ZLIB_DECODER - case CODEC_ID_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; - if (c->flags & FLAG_MULTITHREAD) { - int ret; - mthread_inlen = AV_RL32(encoded); - mthread_inlen = FFMIN(mthread_inlen, len - 8); - mthread_outlen = AV_RL32(encoded+4); - mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); - ret = zlib_decomp(avctx, encoded + 8, mthread_inlen, 0, mthread_outlen); - if (ret < 0) return ret; - ret = zlib_decomp(avctx, encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, - mthread_outlen, mthread_outlen); - if (ret < 0) return ret; - } else { - int ret = zlib_decomp(avctx, encoded, len, 0, c->decomp_size); - if (ret < 0) return ret; - } - encoded = c->decomp_buf; - len = c->decomp_size; - break; -#endif - 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 = AV_RL16(encoded+pixel_ptr); - pixel_ptr += 2; - for (col = 1; col < width; col++) { - encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; - uqvq -= AV_RL16(encoded+pixel_ptr+1); - AV_WL16(encoded+pixel_ptr+1, uqvq); - 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 */ - y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0]; - u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1]; - v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2]; - switch (c->imgtype) { - case IMGTYPE_YUV111: - for (row = 0; row < height; row++) { - for (col = 0; col < width; col++) { - y_out[col] = *encoded++; - u_out[col] = *encoded++ + 128; - v_out[col] = *encoded++ + 128; - } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; - } - break; - case IMGTYPE_YUV422: - for (row = 0; row < height; row++) { - for (col = 0; col < width - 3; col += 4) { - memcpy(y_out + col, encoded, 4); - encoded += 4; - u_out[ col >> 1 ] = *encoded++ + 128; - u_out[(col >> 1) + 1] = *encoded++ + 128; - v_out[ col >> 1 ] = *encoded++ + 128; - v_out[(col >> 1) + 1] = *encoded++ + 128; - } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; - } - break; - case IMGTYPE_RGB24: - for (row = height - 1; row >= 0; row--) { - pixel_ptr = row * c->pic.linesize[0]; - memcpy(outptr + pixel_ptr, encoded, 3 * width); - encoded += 3 * width; - } - break; - case IMGTYPE_YUV411: - for (row = 0; row < height; row++) { - for (col = 0; col < width - 3; col += 4) { - memcpy(y_out + col, encoded, 4); - encoded += 4; - u_out[col >> 2] = *encoded++ + 128; - v_out[col >> 2] = *encoded++ + 128; - } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; - } - break; - case IMGTYPE_YUV211: - for (row = 0; row < height; row++) { - for (col = 0; col < width - 1; col += 2) { - memcpy(y_out + col, encoded, 2); - encoded += 2; - u_out[col >> 1] = *encoded++ + 128; - v_out[col >> 1] = *encoded++ + 128; - } - y_out -= c->pic.linesize[0]; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; - } - break; - case IMGTYPE_YUV420: - u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1]; - v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2]; - for (row = 0; row < height - 1; row += 2) { - for (col = 0; col < width - 1; col += 2) { - memcpy(y_out + col, encoded, 2); - encoded += 2; - memcpy(y_out + col - c->pic.linesize[0], encoded, 2); - encoded += 2; - u_out[col >> 1] = *encoded++ + 128; - v_out[col >> 1] = *encoded++ + 128; - } - y_out -= c->pic.linesize[0] << 1; - u_out -= c->pic.linesize[1]; - v_out -= c->pic.linesize[2]; - } - 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; -} - -/* - * - * Init lcl decoder - * - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - LclDecContext * const c = avctx->priv_data; - unsigned int basesize = avctx->width * avctx->height; - unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING; - unsigned int max_decomp_size; - - if (avctx->extradata_size < 8) { - av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); - return 1; - } - - /* Check codec type */ - if ((avctx->codec_id == CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) || - (avctx->codec_id == CODEC_ID_ZLIB && 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 = avctx->extradata[4]) { - case IMGTYPE_YUV111: - c->decomp_size = basesize * 3; - max_decomp_size = max_basesize * 3; - avctx->pix_fmt = PIX_FMT_YUV444P; - av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n"); - break; - case IMGTYPE_YUV422: - c->decomp_size = basesize * 2; - max_decomp_size = max_basesize * 2; - avctx->pix_fmt = PIX_FMT_YUV422P; - av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n"); - break; - case IMGTYPE_RGB24: - c->decomp_size = basesize * 3; - max_decomp_size = max_basesize * 3; - avctx->pix_fmt = PIX_FMT_BGR24; - av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n"); - break; - case IMGTYPE_YUV411: - c->decomp_size = basesize / 2 * 3; - max_decomp_size = max_basesize / 2 * 3; - avctx->pix_fmt = PIX_FMT_YUV411P; - av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n"); - break; - case IMGTYPE_YUV211: - c->decomp_size = basesize * 2; - max_decomp_size = max_basesize * 2; - avctx->pix_fmt = PIX_FMT_YUV422P; - av_log(avctx, AV_LOG_DEBUG, "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; - avctx->pix_fmt = PIX_FMT_YUV420P; - av_log(avctx, AV_LOG_DEBUG, "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 = (int8_t)avctx->extradata[5]; - switch (avctx->codec_id) { - case CODEC_ID_MSZH: - switch (c->compression) { - case COMP_MSZH: - av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n"); - break; - case COMP_MSZH_NOCOMP: - c->decomp_size = 0; - av_log(avctx, AV_LOG_DEBUG, "No compression.\n"); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); - return 1; - } - break; -#if CONFIG_ZLIB_DECODER - case CODEC_ID_ZLIB: - switch (c->compression) { - case COMP_ZLIB_HISPEED: - av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n"); - break; - case COMP_ZLIB_HICOMP: - av_log(avctx, AV_LOG_DEBUG, "High compression.\n"); - break; - case COMP_ZLIB_NORMAL: - av_log(avctx, AV_LOG_DEBUG, "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_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression); - } - break; -#endif - 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 = avctx->extradata[6]; - if (c->flags & FLAG_MULTITHREAD) - av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n"); - if (c->flags & FLAG_NULLFRAME) - av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n"); - if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) - av_log(avctx, AV_LOG_DEBUG, "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 CONFIG_ZLIB_DECODER - if (avctx->codec_id == CODEC_ID_ZLIB) { - int zret; - 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); - av_freep(&c->decomp_buf); - return 1; - } - } -#endif - - return 0; -} - -/* - * - * Uninit lcl decoder - * - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - LclDecContext * const c = avctx->priv_data; - - av_freep(&c->decomp_buf); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); -#if CONFIG_ZLIB_DECODER - if (avctx->codec_id == CODEC_ID_ZLIB) - inflateEnd(&c->zstream); -#endif - - return 0; -} - -#if CONFIG_MSZH_DECODER -AVCodec mszh_decoder = { - "mszh", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSZH, - sizeof(LclDecContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), -}; -#endif - -#if CONFIG_ZLIB_DECODER -AVCodec zlib_decoder = { - "zlib", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ZLIB, - sizeof(LclDecContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/lclenc.c b/tizen/distrib/ffmpeg/libavcodec/lclenc.c deleted file mode 100644 index 8d7c5bf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lclenc.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * LCL (LossLess Codec Library) Codec - * Copyright (c) 2002-2004 Roberto Togni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 "avcodec.h" -#include "lcl.h" - -#include - -/* - * Decoder context - */ -typedef struct LclEncContext { - - AVCodecContext *avctx; - AVFrame pic; - - // Image type - int imgtype; - // Compression type - int compression; - // Flags - int flags; - z_stream zstream; -} LclEncContext; - -/* - * - * Encode a frame - * - */ -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - LclEncContext *c = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p = &c->pic; - int i; - int zret; // Zlib return code - - *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 = buf; - c->zstream.avail_out = buf_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; - } - - return c->zstream.total_out; -} - -/* - * - * Init lcl encoder - * - */ -static av_cold int encode_init(AVCodecContext *avctx) -{ - LclEncContext *c = avctx->priv_data; - int zret; // Zlib return code - - 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; - avctx->bits_per_coded_sample= 24; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Input pixel format %s not supported\n", avcodec_get_pix_fmt_name(avctx->pix_fmt)); - return -1; - } - - avctx->extradata[0]= 4; - avctx->extradata[1]= 0; - avctx->extradata[2]= 0; - avctx->extradata[3]= 0; - avctx->extradata[4]= c->imgtype; - avctx->extradata[5]= c->compression; - avctx->extradata[6]= c->flags; - 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; - } - - return 0; -} - -/* - * - * Uninit lcl encoder - * - */ -static av_cold int encode_end(AVCodecContext *avctx) -{ - LclEncContext *c = avctx->priv_data; - - av_freep(&avctx->extradata); - deflateEnd(&c->zstream); - - return 0; -} - -AVCodec zlib_encoder = { - "zlib", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ZLIB, - sizeof(LclEncContext), - encode_init, - encode_frame, - encode_end, - .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libavcodec.v b/tizen/distrib/ffmpeg/libavcodec/libavcodec.v deleted file mode 100644 index 561a42c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libavcodec.v +++ /dev/null @@ -1,3 +0,0 @@ -LIBAVCODEC_$MAJOR { - global: *; -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libdirac.h b/tizen/distrib/ffmpeg/libavcodec/libdirac.h deleted file mode 100644 index 0dc19ca..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libdirac.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* data structures common to libdiracenc.c and libdiracdec.c -*/ - -#ifndef AVCODEC_LIBDIRAC_H -#define AVCODEC_LIBDIRAC_H - -#include "avcodec.h" -#include - -/** -* Table providing a Dirac chroma format to FFmpeg pixel format mapping. -*/ -static const struct { - enum PixelFormat ff_pix_fmt; - dirac_chroma_t dirac_pix_fmt; -} ffmpeg_dirac_pixel_format_map[] = { - { PIX_FMT_YUV420P, format420 }, - { PIX_FMT_YUV422P, format422 }, - { PIX_FMT_YUV444P, format444 }, -}; - -#endif /* AVCODEC_LIBDIRAC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.c b/tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.c deleted file mode 100644 index aee1858..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* functions common to libdirac and libschroedinger -*/ - -#include "libdirac_libschro.h" - -static const FfmpegDiracSchroVideoFormatInfo ff_dirac_schro_video_format_info[] = { - { 640, 480, 24000, 1001}, - { 176, 120, 15000, 1001}, - { 176, 144, 25, 2 }, - { 352, 240, 15000, 1001}, - { 352, 288, 25, 2 }, - { 704, 480, 15000, 1001}, - { 704, 576, 25, 2 }, - { 720, 480, 30000, 1001}, - { 720, 576, 25, 1 }, - { 1280, 720, 60000, 1001}, - { 1280, 720, 50, 1 }, - { 1920, 1080, 30000, 1001}, - { 1920, 1080, 25, 1 }, - { 1920, 1080, 60000, 1001}, - { 1920, 1080, 50, 1 }, - { 2048, 1080, 24, 1 }, - { 4096, 2160, 24, 1 }, -}; - -unsigned int ff_dirac_schro_get_video_format_idx(AVCodecContext *avccontext) -{ - unsigned int ret_idx = 0; - unsigned int idx; - unsigned int num_formats = sizeof(ff_dirac_schro_video_format_info) / - sizeof(ff_dirac_schro_video_format_info[0]); - - for (idx = 1; idx < num_formats; ++idx) { - const FfmpegDiracSchroVideoFormatInfo *vf = &ff_dirac_schro_video_format_info[idx]; - if (avccontext->width == vf->width && - avccontext->height == vf->height) { - ret_idx = idx; - if (avccontext->time_base.den == vf->frame_rate_num && - avccontext->time_base.num == vf->frame_rate_denom) - return idx; - } - } - return ret_idx; -} - -void ff_dirac_schro_queue_init(FfmpegDiracSchroQueue *queue) -{ - queue->p_head = queue->p_tail = NULL; - queue->size = 0; -} - -void ff_dirac_schro_queue_free(FfmpegDiracSchroQueue *queue, - void (*free_func)(void *)) -{ - while (queue->p_head) - free_func(ff_dirac_schro_queue_pop(queue)); -} - -int ff_dirac_schro_queue_push_back(FfmpegDiracSchroQueue *queue, void *p_data) -{ - FfmpegDiracSchroQueueElement *p_new = av_mallocz(sizeof(FfmpegDiracSchroQueueElement)); - - if (!p_new) - return -1; - - p_new->data = p_data; - - if (!queue->p_head) - queue->p_head = p_new; - else - queue->p_tail->next = p_new; - queue->p_tail = p_new; - - ++queue->size; - return 0; -} - -void *ff_dirac_schro_queue_pop(FfmpegDiracSchroQueue *queue) -{ - FfmpegDiracSchroQueueElement *top = queue->p_head; - - if (top) { - void *data = top->data; - queue->p_head = queue->p_head->next; - --queue->size; - av_freep(&top); - return data; - } - - return NULL; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.h b/tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.h deleted file mode 100644 index 3d63f97..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libdirac_libschro.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* data structures common to libdirac and libschroedinger -*/ - -#ifndef AVCODEC_LIBDIRAC_LIBSCHRO_H -#define AVCODEC_LIBDIRAC_LIBSCHRO_H - -#include "avcodec.h" - -typedef struct { - uint16_t width; - uint16_t height; - uint16_t frame_rate_num; - uint16_t frame_rate_denom; -} FfmpegDiracSchroVideoFormatInfo; - -/** -* Returns the index into the Dirac Schro common video format info table -*/ -unsigned int ff_dirac_schro_get_video_format_idx(AVCodecContext *avccontext); - -/** -* contains a single encoded frame returned from Dirac or Schroedinger -*/ -typedef struct FfmpegDiracSchroEncodedFrame { - /** encoded frame data */ - uint8_t *p_encbuf; - - /** encoded frame size */ - uint32_t size; - - /** encoded frame number. Will be used as pts */ - uint32_t frame_num; - - /** key frame flag. 1 : is key frame , 0 : in not key frame */ - uint16_t key_frame; -} FfmpegDiracSchroEncodedFrame; - -/** -* queue element -*/ -typedef struct FfmpegDiracSchroQueueElement { - /** Data to be stored in queue*/ - void *data; - /** Pointer to next element queue */ - struct FfmpegDiracSchroQueueElement *next; -} FfmpegDiracSchroQueueElement; - - -/** -* A simple queue implementation used in libdirac and libschroedinger -*/ -typedef struct FfmpegDiracSchroQueue { - /** Pointer to head of queue */ - FfmpegDiracSchroQueueElement *p_head; - /** Pointer to tail of queue */ - FfmpegDiracSchroQueueElement *p_tail; - /** Queue size*/ - int size; -} FfmpegDiracSchroQueue; - -/** -* Initialise the queue -*/ -void ff_dirac_schro_queue_init(FfmpegDiracSchroQueue *queue); - -/** -* Add an element to the end of the queue -*/ -int ff_dirac_schro_queue_push_back(FfmpegDiracSchroQueue *queue, void *p_data); - -/** -* Return the first element in the queue -*/ -void *ff_dirac_schro_queue_pop(FfmpegDiracSchroQueue *queue); - -/** -* Free the queue resources. free_func is a function supplied by the caller to -* free any resources allocated by the caller. The data field of the queue -* element is passed to it. -*/ -void ff_dirac_schro_queue_free(FfmpegDiracSchroQueue *queue, - void (*free_func)(void *)); -#endif /* AVCODEC_LIBDIRAC_LIBSCHRO_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/libdiracdec.c b/tizen/distrib/ffmpeg/libavcodec/libdiracdec.c deleted file mode 100644 index d24d3ba..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libdiracdec.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Dirac decoder support via libdirac library - * Copyright (c) 2005 BBC, Andrew Kennedy - * Copyright (c) 2006-2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* Dirac decoder support via libdirac library; more details about the Dirac -* project can be found at http://dirac.sourceforge.net/. -* The libdirac_decoder library implements Dirac specification version 2.2 -* (http://dirac.sourceforge.net/specification.html). -*/ - -#include "libdirac.h" - -#undef NDEBUG -#include - -#include - -/** contains a single frame returned from Dirac */ -typedef struct FfmpegDiracDecoderParams { - /** decoder handle */ - dirac_decoder_t* p_decoder; - - /** buffer to hold decoded frame */ - unsigned char* p_out_frame_buf; -} FfmpegDiracDecoderParams; - - -/** -* returns FFmpeg chroma format -*/ -static enum PixelFormat GetFfmpegChromaFormat(dirac_chroma_t dirac_pix_fmt) -{ - int num_formats = sizeof(ffmpeg_dirac_pixel_format_map) / - sizeof(ffmpeg_dirac_pixel_format_map[0]); - int idx; - - for (idx = 0; idx < num_formats; ++idx) - if (ffmpeg_dirac_pixel_format_map[idx].dirac_pix_fmt == dirac_pix_fmt) - return ffmpeg_dirac_pixel_format_map[idx].ff_pix_fmt; - return PIX_FMT_NONE; -} - -static av_cold int libdirac_decode_init(AVCodecContext *avccontext) -{ - - FfmpegDiracDecoderParams *p_dirac_params = avccontext->priv_data; - p_dirac_params->p_decoder = dirac_decoder_init(avccontext->debug); - - if (!p_dirac_params->p_decoder) - return -1; - - return 0; -} - -static int libdirac_decode_frame(AVCodecContext *avccontext, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - - FfmpegDiracDecoderParams *p_dirac_params = avccontext->priv_data; - AVPicture *picture = data; - AVPicture pic; - int pict_size; - unsigned char *buffer[3]; - - *data_size = 0; - - if (buf_size > 0) { - /* set data to decode into buffer */ - dirac_buffer(p_dirac_params->p_decoder, buf, buf + buf_size); - if ((buf[4] & 0x08) == 0x08 && (buf[4] & 0x03)) - avccontext->has_b_frames = 1; - } - while (1) { - /* parse data and process result */ - DecoderState state = dirac_parse(p_dirac_params->p_decoder); - switch (state) { - case STATE_BUFFER: - return buf_size; - - case STATE_SEQUENCE: - { - /* tell FFmpeg about sequence details */ - dirac_sourceparams_t *src_params = &p_dirac_params->p_decoder->src_params; - - if (avcodec_check_dimensions(avccontext, src_params->width, - src_params->height) < 0) { - av_log(avccontext, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", - src_params->width, src_params->height); - avccontext->height = avccontext->width = 0; - return -1; - } - - avccontext->height = src_params->height; - avccontext->width = src_params->width; - - avccontext->pix_fmt = GetFfmpegChromaFormat(src_params->chroma); - if (avccontext->pix_fmt == PIX_FMT_NONE) { - av_log(avccontext, AV_LOG_ERROR, - "Dirac chroma format %d not supported currently\n", - src_params->chroma); - return -1; - } - - avccontext->time_base.den = src_params->frame_rate.numerator; - avccontext->time_base.num = src_params->frame_rate.denominator; - - /* calculate output dimensions */ - avpicture_fill(&pic, NULL, avccontext->pix_fmt, - avccontext->width, avccontext->height); - - pict_size = avpicture_get_size(avccontext->pix_fmt, - avccontext->width, - avccontext->height); - - /* allocate output buffer */ - if (!p_dirac_params->p_out_frame_buf) - p_dirac_params->p_out_frame_buf = av_malloc(pict_size); - buffer[0] = p_dirac_params->p_out_frame_buf; - buffer[1] = p_dirac_params->p_out_frame_buf + - pic.linesize[0] * avccontext->height; - buffer[2] = buffer[1] + - pic.linesize[1] * src_params->chroma_height; - - /* tell Dirac about output destination */ - dirac_set_buf(p_dirac_params->p_decoder, buffer, NULL); - break; - } - case STATE_SEQUENCE_END: - break; - - case STATE_PICTURE_AVAIL: - /* fill picture with current buffer data from Dirac */ - avpicture_fill(picture, p_dirac_params->p_out_frame_buf, - avccontext->pix_fmt, - avccontext->width, avccontext->height); - *data_size = sizeof(AVPicture); - return buf_size; - - case STATE_INVALID: - return -1; - - default: - break; - } - } - - return buf_size; -} - - -static av_cold int libdirac_decode_close(AVCodecContext *avccontext) -{ - FfmpegDiracDecoderParams *p_dirac_params = avccontext->priv_data; - dirac_decoder_close(p_dirac_params->p_decoder); - - av_freep(&p_dirac_params->p_out_frame_buf); - - return 0; -} - -static void libdirac_flush(AVCodecContext *avccontext) -{ - /* Got a seek request. We will need free memory held in the private - * context and free the current Dirac decoder handle and then open - * a new decoder handle. */ - libdirac_decode_close(avccontext); - libdirac_decode_init(avccontext); - return; -} - - - -AVCodec libdirac_decoder = { - "libdirac", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DIRAC, - sizeof(FfmpegDiracDecoderParams), - libdirac_decode_init, - NULL, - libdirac_decode_close, - libdirac_decode_frame, - CODEC_CAP_DELAY, - .flush = libdirac_flush, - .long_name = NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libdiracenc.c b/tizen/distrib/ffmpeg/libavcodec/libdiracenc.c deleted file mode 100644 index d390aa8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libdiracenc.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Dirac encoding support via libdirac library - * Copyright (c) 2005 BBC, Andrew Kennedy - * Copyright (c) 2006-2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* Dirac encoding support via libdirac library; more details about the -* Dirac project can be found at http://dirac.sourceforge.net/. -* The libdirac_encoder library implements Dirac specification version 2.2 -* (http://dirac.sourceforge.net/specification.html). -*/ - -#include "libdirac_libschro.h" -#include "libdirac.h" - -#undef NDEBUG -#include - - -#include - -/** Dirac encoder private data */ -typedef struct FfmpegDiracEncoderParams { - /** Dirac encoder context */ - dirac_encoder_context_t enc_ctx; - - /** frame being encoded */ - AVFrame picture; - - /** frame size */ - int frame_size; - - /** Dirac encoder handle */ - dirac_encoder_t* p_encoder; - - /** input frame buffer */ - unsigned char *p_in_frame_buf; - - /** buffer to store encoder output before writing it to the frame queue */ - unsigned char *enc_buf; - - /** size of encoder buffer */ - int enc_buf_size; - - /** queue storing encoded frames */ - FfmpegDiracSchroQueue enc_frame_queue; - - /** end of sequence signalled by user, 0 - false, 1 - true */ - int eos_signalled; - - /** end of sequence returned by encoder, 0 - false, 1 - true */ - int eos_pulled; -} FfmpegDiracEncoderParams; - -/** -* Works out Dirac-compatible chroma format. -*/ -static dirac_chroma_t GetDiracChromaFormat(enum PixelFormat ff_pix_fmt) -{ - int num_formats = sizeof(ffmpeg_dirac_pixel_format_map) / - sizeof(ffmpeg_dirac_pixel_format_map[0]); - int idx; - - for (idx = 0; idx < num_formats; ++idx) - if (ffmpeg_dirac_pixel_format_map[idx].ff_pix_fmt == ff_pix_fmt) - return ffmpeg_dirac_pixel_format_map[idx].dirac_pix_fmt; - return formatNK; -} - -/** -* Dirac video preset table. Ensure that this tables matches up correctly -* with the ff_dirac_schro_video_format_info table in libdirac_libschro.c. -*/ -static const VideoFormat ff_dirac_video_formats[]={ - VIDEO_FORMAT_CUSTOM , - VIDEO_FORMAT_QSIF525 , - VIDEO_FORMAT_QCIF , - VIDEO_FORMAT_SIF525 , - VIDEO_FORMAT_CIF , - VIDEO_FORMAT_4SIF525 , - VIDEO_FORMAT_4CIF , - VIDEO_FORMAT_SD_480I60 , - VIDEO_FORMAT_SD_576I50 , - VIDEO_FORMAT_HD_720P60 , - VIDEO_FORMAT_HD_720P50 , - VIDEO_FORMAT_HD_1080I60 , - VIDEO_FORMAT_HD_1080I50 , - VIDEO_FORMAT_HD_1080P60 , - VIDEO_FORMAT_HD_1080P50 , - VIDEO_FORMAT_DIGI_CINEMA_2K24 , - VIDEO_FORMAT_DIGI_CINEMA_4K24 , -}; - -/** -* Returns the video format preset matching the input video dimensions and -* time base. -*/ -static VideoFormat GetDiracVideoFormatPreset(AVCodecContext *avccontext) -{ - unsigned int num_formats = sizeof(ff_dirac_video_formats) / - sizeof(ff_dirac_video_formats[0]); - - unsigned int idx = ff_dirac_schro_get_video_format_idx(avccontext); - - return (idx < num_formats) ? - ff_dirac_video_formats[idx] : VIDEO_FORMAT_CUSTOM; -} - -static av_cold int libdirac_encode_init(AVCodecContext *avccontext) -{ - - FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data; - int no_local = 1; - int verbose = avccontext->debug; - VideoFormat preset; - - /* get Dirac preset */ - preset = GetDiracVideoFormatPreset(avccontext); - - /* initialize the encoder context */ - dirac_encoder_context_init(&(p_dirac_params->enc_ctx), preset); - - p_dirac_params->enc_ctx.src_params.chroma = GetDiracChromaFormat(avccontext->pix_fmt); - - if (p_dirac_params->enc_ctx.src_params.chroma == formatNK) { - av_log(avccontext, AV_LOG_ERROR, - "Unsupported pixel format %d. This codec supports only " - "Planar YUV formats (yuv420p, yuv422p, yuv444p\n", - avccontext->pix_fmt); - return -1; - } - - p_dirac_params->enc_ctx.src_params.frame_rate.numerator = avccontext->time_base.den; - p_dirac_params->enc_ctx.src_params.frame_rate.denominator = avccontext->time_base.num; - - p_dirac_params->enc_ctx.src_params.width = avccontext->width; - p_dirac_params->enc_ctx.src_params.height = avccontext->height; - - p_dirac_params->frame_size = avpicture_get_size(avccontext->pix_fmt, - avccontext->width, - avccontext->height); - - avccontext->coded_frame = &p_dirac_params->picture; - - if (no_local) { - p_dirac_params->enc_ctx.decode_flag = 0; - p_dirac_params->enc_ctx.instr_flag = 0; - } else { - p_dirac_params->enc_ctx.decode_flag = 1; - p_dirac_params->enc_ctx.instr_flag = 1; - } - - /* Intra-only sequence */ - if (!avccontext->gop_size) { - p_dirac_params->enc_ctx.enc_params.num_L1 = 0; - if (avccontext->coder_type == FF_CODER_TYPE_VLC) - p_dirac_params->enc_ctx.enc_params.using_ac = 0; - } else - avccontext->has_b_frames = 1; - - if (avccontext->flags & CODEC_FLAG_QSCALE) { - if (avccontext->global_quality) { - p_dirac_params->enc_ctx.enc_params.qf = avccontext->global_quality - / (FF_QP2LAMBDA * 10.0); - /* if it is not default bitrate then send target rate. */ - if (avccontext->bit_rate >= 1000 && - avccontext->bit_rate != 200000) - p_dirac_params->enc_ctx.enc_params.trate = avccontext->bit_rate - / 1000; - } else - p_dirac_params->enc_ctx.enc_params.lossless = 1; - } else if (avccontext->bit_rate >= 1000) - p_dirac_params->enc_ctx.enc_params.trate = avccontext->bit_rate / 1000; - - if ((preset > VIDEO_FORMAT_QCIF || preset < VIDEO_FORMAT_QSIF525) && - avccontext->bit_rate == 200000) - p_dirac_params->enc_ctx.enc_params.trate = 0; - - if (avccontext->flags & CODEC_FLAG_INTERLACED_ME) - /* all material can be coded as interlaced or progressive - * irrespective of the type of source material */ - p_dirac_params->enc_ctx.enc_params.picture_coding_mode = 1; - - p_dirac_params->p_encoder = dirac_encoder_init(&(p_dirac_params->enc_ctx), - verbose); - - if (!p_dirac_params->p_encoder) { - av_log(avccontext, AV_LOG_ERROR, - "Unrecoverable Error: dirac_encoder_init failed. "); - return EXIT_FAILURE; - } - - /* allocate enough memory for the incoming data */ - p_dirac_params->p_in_frame_buf = av_malloc(p_dirac_params->frame_size); - - /* initialize the encoded frame queue */ - ff_dirac_schro_queue_init(&p_dirac_params->enc_frame_queue); - - return 0; -} - -static void DiracFreeFrame(void *data) -{ - FfmpegDiracSchroEncodedFrame *enc_frame = data; - - av_freep(&(enc_frame->p_encbuf)); - av_free(enc_frame); -} - -static int libdirac_encode_frame(AVCodecContext *avccontext, - unsigned char *frame, - int buf_size, void *data) -{ - int enc_size = 0; - dirac_encoder_state_t state; - FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data; - FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; - FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL; - int go = 1; - int last_frame_in_sequence = 0; - - if (!data) { - /* push end of sequence if not already signalled */ - if (!p_dirac_params->eos_signalled) { - dirac_encoder_end_sequence(p_dirac_params->p_encoder); - p_dirac_params->eos_signalled = 1; - } - } else { - - /* Allocate frame data to Dirac input buffer. - * Input line size may differ from what the codec supports, - * especially when transcoding from one format to another. - * So use avpicture_layout to copy the frame. */ - avpicture_layout((AVPicture *)data, avccontext->pix_fmt, - avccontext->width, avccontext->height, - p_dirac_params->p_in_frame_buf, - p_dirac_params->frame_size); - - /* load next frame */ - if (dirac_encoder_load(p_dirac_params->p_encoder, - p_dirac_params->p_in_frame_buf, - p_dirac_params->frame_size) < 0) { - av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error." - " dirac_encoder_load failed...\n"); - return -1; - } - } - - if (p_dirac_params->eos_pulled) - go = 0; - - while (go) { - p_dirac_params->p_encoder->enc_buf.buffer = frame; - p_dirac_params->p_encoder->enc_buf.size = buf_size; - /* process frame */ - state = dirac_encoder_output(p_dirac_params->p_encoder); - - switch (state) { - case ENC_STATE_AVAIL: - case ENC_STATE_EOS: - assert(p_dirac_params->p_encoder->enc_buf.size > 0); - - /* All non-frame data is prepended to actual frame data to - * be able to set the pts correctly. So we don't write data - * to the frame output queue until we actually have a frame - */ - - p_dirac_params->enc_buf = av_realloc(p_dirac_params->enc_buf, - p_dirac_params->enc_buf_size + - p_dirac_params->p_encoder->enc_buf.size); - memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size, - p_dirac_params->p_encoder->enc_buf.buffer, - p_dirac_params->p_encoder->enc_buf.size); - - p_dirac_params->enc_buf_size += p_dirac_params->p_encoder->enc_buf.size; - - if (state == ENC_STATE_EOS) { - p_dirac_params->eos_pulled = 1; - go = 0; - } - - /* If non-frame data, don't output it until it we get an - * encoded frame back from the encoder. */ - if (p_dirac_params->p_encoder->enc_pparams.pnum == -1) - break; - - /* create output frame */ - p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); - /* set output data */ - p_frame_output->size = p_dirac_params->enc_buf_size; - p_frame_output->p_encbuf = p_dirac_params->enc_buf; - p_frame_output->frame_num = p_dirac_params->p_encoder->enc_pparams.pnum; - - if (p_dirac_params->p_encoder->enc_pparams.ptype == INTRA_PICTURE && - p_dirac_params->p_encoder->enc_pparams.rtype == REFERENCE_PICTURE) - p_frame_output->key_frame = 1; - - ff_dirac_schro_queue_push_back(&p_dirac_params->enc_frame_queue, - p_frame_output); - - p_dirac_params->enc_buf_size = 0; - p_dirac_params->enc_buf = NULL; - break; - - case ENC_STATE_BUFFER: - go = 0; - break; - - case ENC_STATE_INVALID: - av_log(avccontext, AV_LOG_ERROR, - "Unrecoverable Dirac Encoder Error. Quitting...\n"); - return -1; - - default: - av_log(avccontext, AV_LOG_ERROR, "Unknown Dirac Encoder state\n"); - return -1; - } - } - - /* copy 'next' frame in queue */ - - if (p_dirac_params->enc_frame_queue.size == 1 && p_dirac_params->eos_pulled) - last_frame_in_sequence = 1; - - p_next_output_frame = ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue); - - if (!p_next_output_frame) - return 0; - - memcpy(frame, p_next_output_frame->p_encbuf, p_next_output_frame->size); - avccontext->coded_frame->key_frame = p_next_output_frame->key_frame; - /* Use the frame number of the encoded frame as the pts. It is OK to do - * so since Dirac is a constant framerate codec. It expects input to be - * of constant framerate. */ - avccontext->coded_frame->pts = p_next_output_frame->frame_num; - enc_size = p_next_output_frame->size; - - /* Append the end of sequence information to the last frame in the - * sequence. */ - if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0) { - memcpy(frame + enc_size, p_dirac_params->enc_buf, - p_dirac_params->enc_buf_size); - enc_size += p_dirac_params->enc_buf_size; - av_freep(&p_dirac_params->enc_buf); - p_dirac_params->enc_buf_size = 0; - } - - /* free frame */ - DiracFreeFrame(p_next_output_frame); - - return enc_size; -} - -static av_cold int libdirac_encode_close(AVCodecContext *avccontext) -{ - FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data; - - /* close the encoder */ - dirac_encoder_close(p_dirac_params->p_encoder); - - /* free data in the output frame queue */ - ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue, - DiracFreeFrame); - - /* free the encoder buffer */ - if (p_dirac_params->enc_buf_size) - av_freep(&p_dirac_params->enc_buf); - - /* free the input frame buffer */ - av_freep(&p_dirac_params->p_in_frame_buf); - - return 0; -} - - -AVCodec libdirac_encoder = { - "libdirac", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DIRAC, - sizeof(FfmpegDiracEncoderParams), - libdirac_encode_init, - libdirac_encode_frame, - libdirac_encode_close, - .capabilities = CODEC_CAP_DELAY, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libfaac.c b/tizen/distrib/ffmpeg/libavcodec/libfaac.c deleted file mode 100644 index 82fd05b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libfaac.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Interface to libfaac for aac encoding - * Copyright (c) 2002 Gildas Bazin - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Interface to libfaac for aac encoding. - */ - -#include "avcodec.h" -#include - -typedef struct FaacAudioContext { - faacEncHandle faac_handle; -} FaacAudioContext; - -static av_cold 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) { - av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); - 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 */ - switch(avctx->profile) { - case FF_PROFILE_AAC_MAIN: - faac_cfg->aacObjectType = MAIN; - break; - case FF_PROFILE_UNKNOWN: - case FF_PROFILE_AAC_LOW: - faac_cfg->aacObjectType = LOW; - break; - case FF_PROFILE_AAC_SSR: - faac_cfg->aacObjectType = SSR; - break; - case FF_PROFILE_AAC_LTP: - faac_cfg->aacObjectType = LTP; - break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n"); - faacEncClose(s->faac_handle); - return -1; - } - 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 = NULL; - unsigned long decoder_specific_info_size; - - if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer, - &decoder_specific_info_size)) { - avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); - avctx->extradata_size = decoder_specific_info_size; - memcpy(avctx->extradata, buffer, avctx->extradata_size); - faac_cfg->outputFormat = 0; - } -#undef free - free(buffer); -#define free please_use_av_free - } - - 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; -} - -static 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; -} - -static av_cold int Faac_encode_close(AVCodecContext *avctx) -{ - FaacAudioContext *s = avctx->priv_data; - - av_freep(&avctx->coded_frame); - av_freep(&avctx->extradata); - - faacEncClose(s->faac_handle); - return 0; -} - -AVCodec libfaac_encoder = { - "libfaac", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AAC, - sizeof(FaacAudioContext), - Faac_encode_init, - Faac_encode_frame, - Faac_encode_close, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Codec)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libfaad.c b/tizen/distrib/ffmpeg/libavcodec/libfaad.c deleted file mode 100644 index 679729a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libfaad.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Faad decoder - * Copyright (c) 2003 Zdenek Kabelac - * Copyright (c) 2004 Thomas Raivio - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AAC decoder. - * - * still a bit unfinished - but it plays something - */ - -#include "avcodec.h" -#include "faad.h" - -#ifndef FAADAPI -#define FAADAPI -#endif - -/* - * when CONFIG_LIBFAADBIN is true libfaad will be opened at runtime - */ -//#undef CONFIG_LIBFAADBIN -//#define CONFIG_LIBFAADBIN 0 -//#define CONFIG_LIBFAADBIN 1 - -#if CONFIG_LIBFAADBIN -#include -static const char* const libfaadname = "libfaad.so"; -#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 void channel_setup(AVCodecContext *avctx) -{ -#ifdef FAAD2_VERSION - FAACContext *s = avctx->priv_data; - if (avctx->request_channels > 0 && avctx->request_channels == 2 && - avctx->request_channels < avctx->channels) { - faacDecConfigurationPtr faac_cfg; - avctx->channels = 2; - faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); - faac_cfg->downMatrix = 1; - s->faacDecSetConfiguration(s->faac_handle, faac_cfg); - } -#endif -} - -static av_cold int faac_init_mp4(AVCodecContext *avctx) -{ - FAACContext *s = 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; - channel_setup(avctx); - s->init = 1; - } - } - - return r; -} - -static int faac_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - FAACContext *s = 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, "libfaad: codec init failed.\n"); - return -1; - } - avctx->sample_rate = srate; - avctx->channels = channels; - channel_setup(avctx); - 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, "libfaad: frame decoding failed: %s\n", - s->faacDecGetErrorMessage(frame_info.error)); - return -1; - } - if (!avctx->frame_size) - avctx->frame_size = frame_info.samples/avctx->channels; - 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 av_cold int faac_decode_end(AVCodecContext *avctx) -{ - FAACContext *s = avctx->priv_data; - - s->faacDecClose(s->faac_handle); - - dlclose(s->handle); - return 0; -} - -static av_cold int faac_decode_init(AVCodecContext *avctx) -{ - FAACContext *s = avctx->priv_data; - faacDecConfigurationPtr faac_cfg; - -#if CONFIG_LIBFAADBIN - 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) do { \ - const char* n = AV_STRINGIFY(faacDec ## a); \ - if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \ - err = n; \ - } \ - } while(0) -#else /* !CONFIG_LIBFAADBIN */ -#define dfaac(a) s->faacDec ## a = faacDec ## a -#endif /* CONFIG_LIBFAADBIN */ - - // resolve all needed function calls - dfaac(Open); - dfaac(Close); - dfaac(GetCurrentConfiguration); - dfaac(SetConfiguration); - dfaac(Init); - dfaac(Init2); - dfaac(Decode); -#ifdef FAAD2_VERSION - dfaac(GetErrorMessage); -#endif - -#undef dfaac - -#if CONFIG_LIBFAADBIN - 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_coded_sample) { - case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_coded_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); - - if(!s->init && avctx->channels > 0) - channel_setup(avctx); - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -AVCodec libfaad_decoder = { - "libfaad", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AAC, - sizeof(FAACContext), - faac_decode_init, - NULL, - faac_decode_end, - faac_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("libfaad AAC (Advanced Audio Codec)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libgsm.c b/tizen/distrib/ffmpeg/libavcodec/libgsm.c deleted file mode 100644 index 1062099..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libgsm.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Interface to libgsm for gsm encoding/decoding - * Copyright (c) 2005 Alban Bedel - * Copyright (c) 2006, 2007 Michel Bardiaux - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Interface to libgsm for gsm encoding/decoding - */ - -// The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html - -#include "avcodec.h" -#include - -// gsm.h misses some essential constants -#define GSM_BLOCK_SIZE 33 -#define GSM_MS_BLOCK_SIZE 65 -#define GSM_FRAME_SIZE 160 - -static av_cold int libgsm_init(AVCodecContext *avctx) { - if (avctx->channels > 1) { - av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n", - avctx->channels); - return -1; - } - - if(avctx->codec->decode){ - if(!avctx->channels) - avctx->channels= 1; - - if(!avctx->sample_rate) - avctx->sample_rate= 8000; - - avctx->sample_fmt = SAMPLE_FMT_S16; - }else{ - if (avctx->sample_rate != 8000) { - av_log(avctx, AV_LOG_ERROR, "Sample rate 8000Hz required for GSM, got %dHz\n", - avctx->sample_rate); - if(avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL) - return -1; - } - if (avctx->bit_rate != 13000 /* Official */ && - avctx->bit_rate != 13200 /* Very common */ && - avctx->bit_rate != 0 /* Unknown; a.o. mov does not set bitrate when decoding */ ) { - av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %dbps\n", - avctx->bit_rate); - if(avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL) - return -1; - } - } - - avctx->priv_data = gsm_create(); - - switch(avctx->codec_id) { - case CODEC_ID_GSM: - avctx->frame_size = GSM_FRAME_SIZE; - avctx->block_align = GSM_BLOCK_SIZE; - break; - case CODEC_ID_GSM_MS: { - int one = 1; - gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one); - avctx->frame_size = 2*GSM_FRAME_SIZE; - avctx->block_align = GSM_MS_BLOCK_SIZE; - } - } - - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; -} - -static av_cold int libgsm_close(AVCodecContext *avctx) { - av_freep(&avctx->coded_frame); - 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 < avctx->block_align) return 0; - - switch(avctx->codec_id) { - case CODEC_ID_GSM: - gsm_encode(avctx->priv_data,data,frame); - break; - case CODEC_ID_GSM_MS: - gsm_encode(avctx->priv_data,data,frame); - gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32); - } - return avctx->block_align; -} - - -AVCodec libgsm_encoder = { - "libgsm", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_GSM, - 0, - libgsm_init, - libgsm_encode_frame, - libgsm_close, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), -}; - -AVCodec libgsm_ms_encoder = { - "libgsm_ms", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_GSM_MS, - 0, - libgsm_init, - libgsm_encode_frame, - libgsm_close, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), -}; - -static int libgsm_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - *data_size = 0; /* In case of error */ - if(buf_size < avctx->block_align) return -1; - switch(avctx->codec_id) { - case CODEC_ID_GSM: - if(gsm_decode(avctx->priv_data,buf,data)) return -1; - *data_size = GSM_FRAME_SIZE*sizeof(int16_t); - break; - case CODEC_ID_GSM_MS: - if(gsm_decode(avctx->priv_data,buf,data) || - gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; - *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2; - } - return avctx->block_align; -} - -AVCodec libgsm_decoder = { - "libgsm", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_GSM, - 0, - libgsm_init, - NULL, - libgsm_close, - libgsm_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), -}; - -AVCodec libgsm_ms_decoder = { - "libgsm_ms", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_GSM_MS, - 0, - libgsm_init, - NULL, - libgsm_close, - libgsm_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libmp3lame.c b/tizen/distrib/ffmpeg/libavcodec/libmp3lame.c deleted file mode 100644 index 1d74d6d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libmp3lame.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Interface to libmp3lame for mp3 encoding - * Copyright (c) 2002 Lennert Buytenhek - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Interface to libmp3lame for mp3 encoding. - */ - -#include "avcodec.h" -#include "mpegaudio.h" -#include - -#define BUFFER_SIZE (7200 + 2*MPA_FRAME_SIZE + MPA_FRAME_SIZE/4) -typedef struct Mp3AudioContext { - lame_global_flags *gfp; - int stereo; - uint8_t buffer[BUFFER_SIZE]; - int buffer_index; -} Mp3AudioContext; - -static av_cold int MP3lame_encode_init(AVCodecContext *avctx) -{ - Mp3AudioContext *s = avctx->priv_data; - - if (avctx->channels > 2) - return -1; - - s->stereo = avctx->channels > 1 ? 1 : 0; - - if ((s->gfp = lame_init()) == NULL) - goto err; - lame_set_in_samplerate(s->gfp, avctx->sample_rate); - lame_set_out_samplerate(s->gfp, avctx->sample_rate); - lame_set_num_channels(s->gfp, avctx->channels); - if(avctx->compression_level == FF_COMPRESSION_DEFAULT) { - lame_set_quality(s->gfp, 5); - } else { - lame_set_quality(s->gfp, avctx->compression_level); - } - /* lame 3.91 doesn't work in mono */ - lame_set_mode(s->gfp, JOINT_STEREO); - lame_set_brate(s->gfp, avctx->bit_rate/1000); - if(avctx->flags & CODEC_FLAG_QSCALE) { - lame_set_brate(s->gfp, 0); - lame_set_VBR(s->gfp, vbr_default); - lame_set_VBR_q(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA); - } - lame_set_bWriteVbrTag(s->gfp,0); - lame_set_disable_reservoir(s->gfp, avctx->flags2 & CODEC_FLAG2_BIT_RESERVOIR ? 0 : 1); - if (lame_init_params(s->gfp) < 0) - goto err_close; - - avctx->frame_size = lame_get_framesize(s->gfp); - - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; - -err_close: - lame_close(s->gfp); -err: - return -1; -} - -static const int sSampleRates[] = { - 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 -}; - -static const int sBitRates[2][3][15] = { - { { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448}, - { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384}, - { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320} - }, - { { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256}, - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}, - { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160} - }, -}; - -static const int sSamplesPerFrame[2][3] = -{ - { 384, 1152, 1152 }, - { 384, 1152, 576 } -}; - -static const int sBitsPerSlot[3] = { - 32, - 8, - 8 -}; - -static int mp3len(void *data, int *samplesPerFrame, int *sampleRate) -{ - uint32_t header = AV_RB32(data); - int layerID = 3 - ((header >> 17) & 0x03); - int bitRateID = ((header >> 12) & 0x0f); - int sampleRateID = ((header >> 10) & 0x03); - int bitsPerSlot = sBitsPerSlot[layerID]; - int isPadded = ((header >> 9) & 0x01); - static int const mode_tab[4]= {2,3,1,0}; - int mode= mode_tab[(header >> 19) & 0x03]; - int mpeg_id= mode>0; - int temp0, temp1, bitRate; - - if ( (( header >> 21 ) & 0x7ff) != 0x7ff || mode == 3 || layerID==3 || sampleRateID==3) { - return -1; - } - - if(!samplesPerFrame) samplesPerFrame= &temp0; - if(!sampleRate ) sampleRate = &temp1; - -// *isMono = ((header >> 6) & 0x03) == 0x03; - - *sampleRate = sSampleRates[sampleRateID]>>mode; - bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000; - *samplesPerFrame = sSamplesPerFrame[mpeg_id][layerID]; -//av_log(NULL, AV_LOG_DEBUG, "sr:%d br:%d spf:%d l:%d m:%d\n", *sampleRate, bitRate, *samplesPerFrame, layerID, mode); - - return *samplesPerFrame * bitRate / (bitsPerSlot * *sampleRate) + isPadded; -} - -static int MP3lame_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) -{ - Mp3AudioContext *s = avctx->priv_data; - int len; - int lame_result; - - /* lame 3.91 dies on '1-channel interleaved' data */ - - if(data){ - if (s->stereo) { - lame_result = lame_encode_buffer_interleaved( - s->gfp, - data, - avctx->frame_size, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); - } else { - lame_result = lame_encode_buffer( - s->gfp, - data, - data, - avctx->frame_size, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); - } - }else{ - lame_result= lame_encode_flush( - s->gfp, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index - ); - } - - if(lame_result < 0){ - if(lame_result==-1) { - /* output buffer too small */ - av_log(avctx, AV_LOG_ERROR, "lame: output buffer too small (buffer index: %d, free bytes: %d)\n", s->buffer_index, BUFFER_SIZE - s->buffer_index); - } - return -1; - } - - s->buffer_index += lame_result; - - if(s->buffer_index<4) - return 0; - - len= mp3len(s->buffer, NULL, NULL); -//av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len, s->buffer_index); - if(len <= s->buffer_index){ - memcpy(frame, s->buffer, len); - s->buffer_index -= len; - - memmove(s->buffer, s->buffer+len, s->buffer_index); - //FIXME fix the audio codec API, so we do not need the memcpy() -/*for(i=0; ipriv_data; - - av_freep(&avctx->coded_frame); - - lame_close(s->gfp); - return 0; -} - - -AVCodec libmp3lame_encoder = { - "libmp3lame", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP3, - sizeof(Mp3AudioContext), - MP3lame_encode_init, - MP3lame_encode_frame, - MP3lame_encode_close, - .capabilities= CODEC_CAP_DELAY, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .supported_samplerates= sSampleRates, - .long_name= NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libopencore-amr.c b/tizen/distrib/ffmpeg/libavcodec/libopencore-amr.c deleted file mode 100644 index 2661645..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libopencore-amr.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * AMR Audio decoder stub - * Copyright (c) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" - -static void amr_decode_fix_avctx(AVCodecContext *avctx) -{ - const int is_amr_wb = 1 + (avctx->codec_id == CODEC_ID_AMR_WB); - - if (!avctx->sample_rate) - avctx->sample_rate = 8000 * is_amr_wb; - - if (!avctx->channels) - avctx->channels = 1; - - avctx->frame_size = 160 * is_amr_wb; - avctx->sample_fmt = SAMPLE_FMT_S16; -} - -#if CONFIG_LIBOPENCORE_AMRNB - -#include -#include - -static const char nb_bitrate_unsupported[] = - "bitrate not supported: use one of 4.75k, 5.15k, 5.9k, 6.7k, 7.4k, 7.95k, 10.2k or 12.2k\n"; - -/* Common code for fixed and float version*/ -typedef struct AMR_bitrates { - int rate; - enum Mode mode; -} AMR_bitrates; - -/* Match desired bitrate */ -static int getBitrateMode(int bitrate) -{ - /* make the correspondance between bitrate and mode */ - AMR_bitrates rates[] = { { 4750, MR475}, - { 5150, MR515}, - { 5900, MR59}, - { 6700, MR67}, - { 7400, MR74}, - { 7950, MR795}, - {10200, MR102}, - {12200, MR122}, }; - int i; - - for (i = 0; i < 8; i++) - if (rates[i].rate == bitrate) - return rates[i].mode; - /* no bitrate matching, return an error */ - return -1; -} - -typedef struct AMRContext { - int frameCount; - void *decState; - int *enstate; - int enc_bitrate; -} AMRContext; - -static av_cold 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; - } - - amr_decode_fix_avctx(avctx); - - if (avctx->channels > 1) { - av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n"); - return -1; - } - - return 0; -} - -static av_cold int amr_nb_decode_close(AVCodecContext *avctx) -{ - AMRContext *s = avctx->priv_data; - - Decoder_Interface_exit(s->decState); - return 0; -} - -static int amr_nb_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AMRContext *s = avctx->priv_data; - const uint8_t *amrData = buf; - static const uint8_t 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); */ - - 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; -} - -AVCodec libopencore_amrnb_decoder = { - "libopencore_amrnb", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AMR_NB, - sizeof(AMRContext), - amr_nb_decode_init, - NULL, - amr_nb_decode_close, - amr_nb_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"), -}; - -static av_cold int amr_nb_encode_init(AVCodecContext *avctx) -{ - AMRContext *s = avctx->priv_data; - - s->frameCount = 0; - - if (avctx->sample_rate != 8000) { - av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); - return -1; - } - - if (avctx->channels != 1) { - av_log(avctx, AV_LOG_ERROR, "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) { - av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n"); - return -1; - } - - if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) { - av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported); - return -1; - } - - return 0; -} - -static av_cold 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_encode_frame(AVCodecContext *avctx, - unsigned char *frame/*out*/, - int buf_size, void *data/*in*/) -{ - AMRContext *s = avctx->priv_data; - int written; - - if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) { - av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported); - return -1; - } - - 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; -} - -AVCodec libopencore_amrnb_encoder = { - "libopencore_amrnb", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AMR_NB, - sizeof(AMRContext), - amr_nb_encode_init, - amr_nb_encode_frame, - amr_nb_encode_close, - NULL, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"), -}; - -#endif - -/* -----------AMR wideband ------------*/ -#if CONFIG_LIBOPENCORE_AMRWB - -#ifdef _TYPEDEF_H -//To avoid duplicate typedefs from typedef in amr-nb -#define typedef_h -#endif - -#include -#include - -static const char wb_bitrate_unsupported[] = - "bitrate not supported: use one of 6.6k, 8.85k, 12.65k, 14.25k, 15.85k, 18.25k, 19.85k, 23.05k, or 23.85k\n"; - -/* Common code for fixed and float version*/ -typedef struct AMRWB_bitrates { - int rate; - int mode; -} AMRWB_bitrates; - -typedef struct AMRWBContext { - int frameCount; - void *state; - int mode; - Word16 allow_dtx; -} AMRWBContext; - -static av_cold int amr_wb_decode_init(AVCodecContext *avctx) -{ - AMRWBContext *s = avctx->priv_data; - - s->frameCount = 0; - s->state = D_IF_init(); - - amr_decode_fix_avctx(avctx); - - if (avctx->channels > 1) { - av_log(avctx, AV_LOG_ERROR, "amr_wb: multichannel decoding not supported\n"); - return -1; - } - - return 0; -} - -static int amr_wb_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AMRWBContext *s = avctx->priv_data; - const uint8_t *amrData = buf; - int mode; - int packet_size; - static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1}; - - if (!buf_size) - /* 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 = avctx->priv_data; - - D_IF_exit(s->state); - return 0; -} - -AVCodec libopencore_amrwb_decoder = { - "libopencore_amrwb", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AMR_WB, - sizeof(AMRWBContext), - amr_wb_decode_init, - NULL, - amr_wb_decode_close, - amr_wb_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Wide-Band"), -}; - -#endif /* CONFIG_LIBOPENCORE_AMRWB */ diff --git a/tizen/distrib/ffmpeg/libavcodec/libopenjpeg.c b/tizen/distrib/ffmpeg/libavcodec/libopenjpeg.c deleted file mode 100644 index 0956da9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libopenjpeg.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * JPEG 2000 decoding support via OpenJPEG - * Copyright (c) 2009 Jaikrishnan Menon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* JPEG 2000 decoder using libopenjpeg -*/ - -#include "avcodec.h" -#include "libavutil/intreadwrite.h" -#define OPJ_STATIC -#include - -#define JP2_SIG_TYPE 0x6A502020 -#define JP2_SIG_VALUE 0x0D0A870A - -typedef struct { - opj_dparameters_t dec_params; - AVFrame image; -} LibOpenJPEGContext; - -static int check_image_attributes(opj_image_t *image) -{ - return image->comps[0].dx == image->comps[1].dx && - image->comps[1].dx == image->comps[2].dx && - image->comps[0].dy == image->comps[1].dy && - image->comps[1].dy == image->comps[2].dy && - image->comps[0].prec == image->comps[1].prec && - image->comps[1].prec == image->comps[2].prec; -} - -static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) -{ - LibOpenJPEGContext *ctx = avctx->priv_data; - - opj_set_default_decoder_parameters(&ctx->dec_params); - avctx->coded_frame = &ctx->image; - return 0; -} - -static int libopenjpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - LibOpenJPEGContext *ctx = avctx->priv_data; - AVFrame *picture = &ctx->image, *output = data; - opj_dinfo_t *dec; - opj_cio_t *stream; - opj_image_t *image; - int width, height, has_alpha = 0, ret = -1; - int x, y, index; - uint8_t *img_ptr; - int adjust[4]; - - *data_size = 0; - - // Check if input is a raw jpeg2k codestream or in jp2 wrapping - if((AV_RB32(buf) == 12) && - (AV_RB32(buf + 4) == JP2_SIG_TYPE) && - (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { - dec = opj_create_decompress(CODEC_JP2); - } else { - // If the AVPacket contains a jp2c box, then skip to - // the starting byte of the codestream. - if (AV_RB32(buf + 4) == AV_RB32("jp2c")) - buf += 8; - dec = opj_create_decompress(CODEC_J2K); - } - - if(!dec) { - av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); - return -1; - } - opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); - - ctx->dec_params.cp_reduce = avctx->lowres; - // Tie decoder with decoding parameters - opj_setup_decoder(dec, &ctx->dec_params); - stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); - if(!stream) { - av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); - opj_destroy_decompress(dec); - return -1; - } - - // Decode the codestream - image = opj_decode_with_info(dec, stream, NULL); - opj_cio_close(stream); - if(!image) { - av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); - opj_destroy_decompress(dec); - return -1; - } - width = image->comps[0].w << avctx->lowres; - height = image->comps[0].h << avctx->lowres; - if(avcodec_check_dimensions(avctx, width, height) < 0) { - av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); - goto done; - } - avcodec_set_dimensions(avctx, width, height); - - switch(image->numcomps) - { - case 1: avctx->pix_fmt = PIX_FMT_GRAY8; - break; - case 3: if(check_image_attributes(image)) { - avctx->pix_fmt = PIX_FMT_RGB24; - } else { - avctx->pix_fmt = PIX_FMT_GRAY8; - av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); - } - break; - case 4: has_alpha = 1; - avctx->pix_fmt = PIX_FMT_RGBA; - break; - default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); - goto done; - } - - if(picture->data[0]) - avctx->release_buffer(avctx, picture); - - if(avctx->get_buffer(avctx, picture) < 0) { - av_log(avctx, AV_LOG_ERROR, "Couldn't allocate image buffer.\n"); - return -1; - } - - for(x = 0; x < image->numcomps; x++) { - adjust[x] = FFMAX(image->comps[x].prec - 8, 0); - } - - for(y = 0; y < avctx->height; y++) { - index = y*avctx->width; - img_ptr = picture->data[0] + y*picture->linesize[0]; - for(x = 0; x < avctx->width; x++, index++) { - *img_ptr++ = image->comps[0].data[index] >> adjust[0]; - if(image->numcomps > 2 && check_image_attributes(image)) { - *img_ptr++ = image->comps[1].data[index] >> adjust[1]; - *img_ptr++ = image->comps[2].data[index] >> adjust[2]; - if(has_alpha) - *img_ptr++ = image->comps[3].data[index] >> adjust[3]; - } - } - } - - *output = ctx->image; - *data_size = sizeof(AVPicture); - ret = buf_size; - -done: - opj_image_destroy(image); - opj_destroy_decompress(dec); - return ret; -} - -static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) -{ - LibOpenJPEGContext *ctx = avctx->priv_data; - - if(ctx->image.data[0]) - avctx->release_buffer(avctx, &ctx->image); - return 0 ; -} - - -AVCodec libopenjpeg_decoder = { - "libopenjpeg", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_JPEG2000, - sizeof(LibOpenJPEGContext), - libopenjpeg_decode_init, - NULL, - libopenjpeg_decode_close, - libopenjpeg_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), -} ; diff --git a/tizen/distrib/ffmpeg/libavcodec/libschroedinger.c b/tizen/distrib/ffmpeg/libavcodec/libschroedinger.c deleted file mode 100644 index 04c15a2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libschroedinger.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* function definitions common to libschroedingerdec.c and libschroedingerenc.c -*/ - -#include "libdirac_libschro.h" -#include "libschroedinger.h" - -/** -* Schroedinger video preset table. Ensure that this tables matches up correctly -* with the ff_dirac_schro_video_format_info table in libdirac_libschro.c. -*/ -static const SchroVideoFormatEnum ff_schro_video_formats[]={ - SCHRO_VIDEO_FORMAT_CUSTOM , - SCHRO_VIDEO_FORMAT_QSIF , - SCHRO_VIDEO_FORMAT_QCIF , - SCHRO_VIDEO_FORMAT_SIF , - SCHRO_VIDEO_FORMAT_CIF , - SCHRO_VIDEO_FORMAT_4SIF , - SCHRO_VIDEO_FORMAT_4CIF , - SCHRO_VIDEO_FORMAT_SD480I_60 , - SCHRO_VIDEO_FORMAT_SD576I_50 , - SCHRO_VIDEO_FORMAT_HD720P_60 , - SCHRO_VIDEO_FORMAT_HD720P_50 , - SCHRO_VIDEO_FORMAT_HD1080I_60 , - SCHRO_VIDEO_FORMAT_HD1080I_50 , - SCHRO_VIDEO_FORMAT_HD1080P_60 , - SCHRO_VIDEO_FORMAT_HD1080P_50 , - SCHRO_VIDEO_FORMAT_DC2K_24 , - SCHRO_VIDEO_FORMAT_DC4K_24 , -}; - -SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext) -{ - unsigned int num_formats = sizeof(ff_schro_video_formats) / - sizeof(ff_schro_video_formats[0]); - - unsigned int idx = ff_dirac_schro_get_video_format_idx (avccontext); - - return (idx < num_formats) ? ff_schro_video_formats[idx] : - SCHRO_VIDEO_FORMAT_CUSTOM; -} - -int ff_get_schro_frame_format (SchroChromaFormat schro_pix_fmt, - SchroFrameFormat *schro_frame_fmt) -{ - unsigned int num_formats = sizeof(ffmpeg_schro_pixel_format_map) / - sizeof(ffmpeg_schro_pixel_format_map[0]); - - int idx; - - for (idx = 0; idx < num_formats; ++idx) { - if (ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) { - *schro_frame_fmt = ffmpeg_schro_pixel_format_map[idx].schro_frame_fmt; - return 0; - } - } - return -1; -} - -static void FreeSchroFrame(SchroFrame *frame, void *priv) -{ - AVPicture *p_pic = priv; - - if (!p_pic) - return; - - avpicture_free(p_pic); - av_freep(&p_pic); -} - -SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext, - SchroFrameFormat schro_frame_fmt) -{ - AVPicture *p_pic; - SchroFrame *p_frame; - int y_width, uv_width; - int y_height, uv_height; - int i; - - y_width = avccontext->width; - y_height = avccontext->height; - uv_width = y_width >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt)); - uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt)); - - p_pic = av_mallocz(sizeof(AVPicture)); - avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height); - - p_frame = schro_frame_new(); - p_frame->format = schro_frame_fmt; - p_frame->width = y_width; - p_frame->height = y_height; - schro_frame_set_free_callback(p_frame, FreeSchroFrame, (void *)p_pic); - - for (i = 0; i < 3; ++i) { - p_frame->components[i].width = i ? uv_width : y_width; - p_frame->components[i].stride = p_pic->linesize[i]; - p_frame->components[i].height = i ? uv_height : y_height; - p_frame->components[i].length = - p_frame->components[i].stride * p_frame->components[i].height; - p_frame->components[i].data = p_pic->data[i]; - - if (i) { - p_frame->components[i].v_shift = - SCHRO_FRAME_FORMAT_V_SHIFT(p_frame->format); - p_frame->components[i].h_shift = - SCHRO_FRAME_FORMAT_H_SHIFT(p_frame->format); - } - } - - return p_frame; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/libschroedinger.h b/tizen/distrib/ffmpeg/libavcodec/libschroedinger.h deleted file mode 100644 index 65a41e6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libschroedinger.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* data structures common to libschroedingerdec.c and libschroedingerenc.c -*/ - -#ifndef AVCODEC_LIBSCHROEDINGER_H -#define AVCODEC_LIBSCHROEDINGER_H - -#include -#include -#include "avcodec.h" - -static const struct { - enum PixelFormat ff_pix_fmt; - SchroChromaFormat schro_pix_fmt; - SchroFrameFormat schro_frame_fmt; -} ffmpeg_schro_pixel_format_map[] = { - { PIX_FMT_YUV420P, SCHRO_CHROMA_420, SCHRO_FRAME_FORMAT_U8_420 }, - { PIX_FMT_YUV422P, SCHRO_CHROMA_422, SCHRO_FRAME_FORMAT_U8_422 }, - { PIX_FMT_YUV444P, SCHRO_CHROMA_444, SCHRO_FRAME_FORMAT_U8_444 }, -}; - -/** -* Returns the video format preset matching the input video dimensions and -* time base. -*/ -SchroVideoFormatEnum ff_get_schro_video_format_preset (AVCodecContext *avccontext); - -/** -* Sets the Schroedinger frame format corresponding to the Schro chroma format -* passed. Returns 0 on success, -1 on failure. -*/ -int ff_get_schro_frame_format(SchroChromaFormat schro_chroma_fmt, - SchroFrameFormat *schro_frame_fmt); - -/** -* Create a Schro frame based on the dimensions and frame format -* passed. Returns a pointer to a frame on success, NULL on failure. -*/ -SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext, - SchroFrameFormat schro_frame_fmt); - -#endif /* AVCODEC_LIBSCHROEDINGER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/libschroedingerdec.c b/tizen/distrib/ffmpeg/libavcodec/libschroedingerdec.c deleted file mode 100644 index ef20f20..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libschroedingerdec.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Dirac decoder support via Schroedinger libraries - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* Dirac decoder support via libschroedinger-1.0 libraries. More details about -* the Schroedinger project can be found at http://www.diracvideo.org/. -* The library implements Dirac Specification Version 2.2. -* (http://dirac.sourceforge.net/specification.html). -*/ - -#include "avcodec.h" -#include "libdirac_libschro.h" -#include "libschroedinger.h" - -#undef NDEBUG -#include - - -#include -#include -#include - -/** libschroedinger decoder private data */ -typedef struct FfmpegSchroDecoderParams { - /** Schroedinger video format */ - SchroVideoFormat *format; - - /** Schroedinger frame format */ - SchroFrameFormat frame_format; - - /** decoder handle */ - SchroDecoder* decoder; - - /** queue storing decoded frames */ - FfmpegDiracSchroQueue dec_frame_queue; - - /** end of sequence signalled */ - int eos_signalled; - - /** end of sequence pulled */ - int eos_pulled; - - /** decoded picture */ - AVPicture dec_pic; -} FfmpegSchroDecoderParams; - -typedef struct FfmpegSchroParseUnitContext { - const uint8_t *buf; - int buf_size; -} FfmpegSchroParseUnitContext; - - -static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf, - void *priv); - -static void FfmpegSchroParseContextInit(FfmpegSchroParseUnitContext *parse_ctx, - const uint8_t *buf, int buf_size) -{ - parse_ctx->buf = buf; - parse_ctx->buf_size = buf_size; -} - -static SchroBuffer* FfmpegFindNextSchroParseUnit(FfmpegSchroParseUnitContext *parse_ctx) -{ - SchroBuffer *enc_buf = NULL; - int next_pu_offset = 0; - unsigned char *in_buf; - - if (parse_ctx->buf_size < 13 || - parse_ctx->buf[0] != 'B' || - parse_ctx->buf[1] != 'B' || - parse_ctx->buf[2] != 'C' || - parse_ctx->buf[3] != 'D') - return NULL; - - next_pu_offset = (parse_ctx->buf[5] << 24) + - (parse_ctx->buf[6] << 16) + - (parse_ctx->buf[7] << 8) + - parse_ctx->buf[8]; - - if (next_pu_offset == 0 && - SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4])) - next_pu_offset = 13; - - if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset) - return NULL; - - in_buf = av_malloc(next_pu_offset); - memcpy(in_buf, parse_ctx->buf, next_pu_offset); - enc_buf = schro_buffer_new_with_data(in_buf, next_pu_offset); - enc_buf->free = libschroedinger_decode_buffer_free; - enc_buf->priv = in_buf; - - parse_ctx->buf += next_pu_offset; - parse_ctx->buf_size -= next_pu_offset; - - return enc_buf; -} - -/** -* Returns FFmpeg chroma format. -*/ -static enum PixelFormat GetFfmpegChromaFormat(SchroChromaFormat schro_pix_fmt) -{ - int num_formats = sizeof(ffmpeg_schro_pixel_format_map) / - sizeof(ffmpeg_schro_pixel_format_map[0]); - int idx; - - for (idx = 0; idx < num_formats; ++idx) - if (ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) - return ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt; - return PIX_FMT_NONE; -} - -static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext) -{ - - FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data; - /* First of all, initialize our supporting libraries. */ - schro_init(); - - schro_debug_set_level(avccontext->debug); - p_schro_params->decoder = schro_decoder_new(); - schro_decoder_set_skip_ratio(p_schro_params->decoder, 1); - - if (!p_schro_params->decoder) - return -1; - - /* Initialize the decoded frame queue. */ - ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue); - return 0; -} - -static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf, - void *priv) -{ - av_freep(&priv); -} - -static void libschroedinger_decode_frame_free(void *frame) -{ - schro_frame_unref(frame); -} - -static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext) -{ - FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data; - SchroDecoder *decoder = p_schro_params->decoder; - - p_schro_params->format = schro_decoder_get_video_format(decoder); - - /* Tell FFmpeg about sequence details. */ - if (avcodec_check_dimensions(avccontext, p_schro_params->format->width, - p_schro_params->format->height) < 0) { - av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n", - p_schro_params->format->width, p_schro_params->format->height); - avccontext->height = avccontext->width = 0; - return; - } - avccontext->height = p_schro_params->format->height; - avccontext->width = p_schro_params->format->width; - avccontext->pix_fmt = GetFfmpegChromaFormat(p_schro_params->format->chroma_format); - - if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, - &p_schro_params->frame_format) == -1) { - av_log(avccontext, AV_LOG_ERROR, - "This codec currently only supports planar YUV 4:2:0, 4:2:2 " - "and 4:4:4 formats.\n"); - return; - } - - avccontext->time_base.den = p_schro_params->format->frame_rate_numerator; - avccontext->time_base.num = p_schro_params->format->frame_rate_denominator; - - if (!p_schro_params->dec_pic.data[0]) - avpicture_alloc(&p_schro_params->dec_pic, - avccontext->pix_fmt, - avccontext->width, - avccontext->height); -} - -static int libschroedinger_decode_frame(AVCodecContext *avccontext, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - - FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data; - SchroDecoder *decoder = p_schro_params->decoder; - SchroVideoFormat *format; - AVPicture *picture = data; - SchroBuffer *enc_buf; - SchroFrame* frame; - int state; - int go = 1; - int outer = 1; - FfmpegSchroParseUnitContext parse_ctx; - - *data_size = 0; - - FfmpegSchroParseContextInit(&parse_ctx, buf, buf_size); - if (!buf_size) { - if (!p_schro_params->eos_signalled) { - state = schro_decoder_push_end_of_stream(decoder); - p_schro_params->eos_signalled = 1; - } - } - - /* Loop through all the individual parse units in the input buffer */ - do { - if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) { - /* Push buffer into decoder. */ - if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) && - SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0) - avccontext->has_b_frames = 1; - state = schro_decoder_push(decoder, enc_buf); - if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT) - libschroedinger_handle_first_access_unit(avccontext); - go = 1; - } else - outer = 0; - format = p_schro_params->format; - - while (go) { - /* Parse data and process result. */ - state = schro_decoder_wait(decoder); - switch (state) { - case SCHRO_DECODER_FIRST_ACCESS_UNIT: - libschroedinger_handle_first_access_unit(avccontext); - break; - - case SCHRO_DECODER_NEED_BITS: - /* Need more input data - stop iterating over what we have. */ - go = 0; - break; - - case SCHRO_DECODER_NEED_FRAME: - /* Decoder needs a frame - create one and push it in. */ - frame = ff_create_schro_frame(avccontext, - p_schro_params->frame_format); - schro_decoder_add_output_picture(decoder, frame); - break; - - case SCHRO_DECODER_OK: - /* Pull a frame out of the decoder. */ - frame = schro_decoder_pull(decoder); - - if (frame) - ff_dirac_schro_queue_push_back(&p_schro_params->dec_frame_queue, - frame); - break; - case SCHRO_DECODER_EOS: - go = 0; - p_schro_params->eos_pulled = 1; - schro_decoder_reset(decoder); - outer = 0; - break; - - case SCHRO_DECODER_ERROR: - return -1; - break; - } - } - } while (outer); - - /* Grab next frame to be returned from the top of the queue. */ - frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue); - - if (frame) { - memcpy(p_schro_params->dec_pic.data[0], - frame->components[0].data, - frame->components[0].length); - - memcpy(p_schro_params->dec_pic.data[1], - frame->components[1].data, - frame->components[1].length); - - memcpy(p_schro_params->dec_pic.data[2], - frame->components[2].data, - frame->components[2].length); - - /* Fill picture with current buffer data from Schroedinger. */ - avpicture_fill(picture, p_schro_params->dec_pic.data[0], - avccontext->pix_fmt, - avccontext->width, avccontext->height); - - *data_size = sizeof(AVPicture); - - /* Now free the frame resources. */ - libschroedinger_decode_frame_free(frame); - } - return buf_size; -} - - -static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext) -{ - FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data; - /* Free the decoder. */ - schro_decoder_free(p_schro_params->decoder); - av_freep(&p_schro_params->format); - - avpicture_free(&p_schro_params->dec_pic); - - /* Free data in the output frame queue. */ - ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue, - libschroedinger_decode_frame_free); - - return 0; -} - -static void libschroedinger_flush(AVCodecContext *avccontext) -{ - /* Got a seek request. Free the decoded frames queue and then reset - * the decoder */ - FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data; - - /* Free data in the output frame queue. */ - ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue, - libschroedinger_decode_frame_free); - - ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue); - schro_decoder_reset(p_schro_params->decoder); - p_schro_params->eos_pulled = 0; - p_schro_params->eos_signalled = 0; -} - -AVCodec libschroedinger_decoder = { - "libschroedinger", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DIRAC, - sizeof(FfmpegSchroDecoderParams), - libschroedinger_decode_init, - NULL, - libschroedinger_decode_close, - libschroedinger_decode_frame, - CODEC_CAP_DELAY, - .flush = libschroedinger_flush, - .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libschroedingerenc.c b/tizen/distrib/ffmpeg/libavcodec/libschroedingerenc.c deleted file mode 100644 index c375c73..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libschroedingerenc.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Dirac encoder support via Schroedinger libraries - * Copyright (c) 2008 BBC, Anuradha Suraparaju - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* Dirac encoder support via libschroedinger-1.0 libraries. More details about -* the Schroedinger project can be found at http://www.diracvideo.org/. -* The library implements Dirac Specification Version 2.2 -* (http://dirac.sourceforge.net/specification.html). -*/ - -#undef NDEBUG -#include - -#include -#include -#include - -#include "avcodec.h" -#include "libdirac_libschro.h" -#include "libschroedinger.h" - - -/** libschroedinger encoder private data */ -typedef struct FfmpegSchroEncoderParams { - /** Schroedinger video format */ - SchroVideoFormat *format; - - /** Schroedinger frame format */ - SchroFrameFormat frame_format; - - /** frame being encoded */ - AVFrame picture; - - /** frame size */ - int frame_size; - - /** Schroedinger encoder handle*/ - SchroEncoder* encoder; - - /** buffer to store encoder output before writing it to the frame queue*/ - unsigned char *enc_buf; - - /** Size of encoder buffer*/ - int enc_buf_size; - - /** queue storing encoded frames */ - FfmpegDiracSchroQueue enc_frame_queue; - - /** end of sequence signalled */ - int eos_signalled; - - /** end of sequence pulled */ - int eos_pulled; -} FfmpegSchroEncoderParams; - -/** -* Works out Schro-compatible chroma format. -*/ -static int SetSchroChromaFormat(AVCodecContext *avccontext) -{ - int num_formats = sizeof(ffmpeg_schro_pixel_format_map) / - sizeof(ffmpeg_schro_pixel_format_map[0]); - int idx; - - FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; - - for (idx = 0; idx < num_formats; ++idx) { - if (ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt == - avccontext->pix_fmt) { - p_schro_params->format->chroma_format = - ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt; - return 0; - } - } - - av_log(avccontext, AV_LOG_ERROR, - "This codec currently only supports planar YUV 4:2:0, 4:2:2" - " and 4:4:4 formats.\n"); - - return -1; -} - -static int libschroedinger_encode_init(AVCodecContext *avccontext) -{ - FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; - SchroVideoFormatEnum preset; - - /* Initialize the libraries that libschroedinger depends on. */ - schro_init(); - - /* Create an encoder object. */ - p_schro_params->encoder = schro_encoder_new(); - - if (!p_schro_params->encoder) { - av_log(avccontext, AV_LOG_ERROR, - "Unrecoverable Error: schro_encoder_new failed. "); - return -1; - } - - /* Initialize the format. */ - preset = ff_get_schro_video_format_preset(avccontext); - p_schro_params->format = - schro_encoder_get_video_format(p_schro_params->encoder); - schro_video_format_set_std_video_format(p_schro_params->format, preset); - p_schro_params->format->width = avccontext->width; - p_schro_params->format->height = avccontext->height; - - if (SetSchroChromaFormat(avccontext) == -1) - return -1; - - if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, - &p_schro_params->frame_format) == -1) { - av_log(avccontext, AV_LOG_ERROR, - "This codec currently supports only planar YUV 4:2:0, 4:2:2" - " and 4:4:4 formats.\n"); - return -1; - } - - p_schro_params->format->frame_rate_numerator = avccontext->time_base.den; - p_schro_params->format->frame_rate_denominator = avccontext->time_base.num; - - p_schro_params->frame_size = avpicture_get_size(avccontext->pix_fmt, - avccontext->width, - avccontext->height); - - avccontext->coded_frame = &p_schro_params->picture; - - if (!avccontext->gop_size) { - schro_encoder_setting_set_double(p_schro_params->encoder, - "gop_structure", - SCHRO_ENCODER_GOP_INTRA_ONLY); - - if (avccontext->coder_type == FF_CODER_TYPE_VLC) - schro_encoder_setting_set_double(p_schro_params->encoder, - "enable_noarith", 1); - } else { - schro_encoder_setting_set_double(p_schro_params->encoder, - "gop_structure", - SCHRO_ENCODER_GOP_BIREF); - avccontext->has_b_frames = 1; - } - - /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */ - if (avccontext->flags & CODEC_FLAG_QSCALE) { - if (!avccontext->global_quality) { - /* lossless coding */ - schro_encoder_setting_set_double(p_schro_params->encoder, - "rate_control", - SCHRO_ENCODER_RATE_CONTROL_LOSSLESS); - } else { - int noise_threshold; - schro_encoder_setting_set_double(p_schro_params->encoder, - "rate_control", - SCHRO_ENCODER_RATE_CONTROL_CONSTANT_NOISE_THRESHOLD); - - noise_threshold = avccontext->global_quality / FF_QP2LAMBDA; - if (noise_threshold > 100) - noise_threshold = 100; - schro_encoder_setting_set_double(p_schro_params->encoder, - "noise_threshold", - noise_threshold); - } - } else { - schro_encoder_setting_set_double(p_schro_params->encoder, - "rate_control", - SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE); - - schro_encoder_setting_set_double(p_schro_params->encoder, - "bitrate", - avccontext->bit_rate); - - } - - if (avccontext->flags & CODEC_FLAG_INTERLACED_ME) - /* All material can be coded as interlaced or progressive - irrespective of the type of source material. */ - schro_encoder_setting_set_double(p_schro_params->encoder, - "interlaced_coding", 1); - - /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger - * and libdirac support other bit-depth data. */ - schro_video_format_set_std_signal_range(p_schro_params->format, - SCHRO_SIGNAL_RANGE_8BIT_VIDEO); - - /* Set the encoder format. */ - schro_encoder_set_video_format(p_schro_params->encoder, - p_schro_params->format); - - /* Set the debug level. */ - schro_debug_set_level(avccontext->debug); - - schro_encoder_start(p_schro_params->encoder); - - /* Initialize the encoded frame queue. */ - ff_dirac_schro_queue_init(&p_schro_params->enc_frame_queue); - return 0; -} - -static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext, - void *in_data) -{ - FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; - SchroFrame *in_frame; - /* Input line size may differ from what the codec supports. Especially - * when transcoding from one format to another. So use avpicture_layout - * to copy the frame. */ - in_frame = ff_create_schro_frame(avccontext, p_schro_params->frame_format); - - if (in_frame) - avpicture_layout((AVPicture *)in_data, avccontext->pix_fmt, - avccontext->width, avccontext->height, - in_frame->components[0].data, - p_schro_params->frame_size); - - return in_frame; -} - -static void SchroedingerFreeFrame(void *data) -{ - FfmpegDiracSchroEncodedFrame *enc_frame = data; - - av_freep(&(enc_frame->p_encbuf)); - av_free(enc_frame); -} - -static int libschroedinger_encode_frame(AVCodecContext *avccontext, - unsigned char *frame, - int buf_size, void *data) -{ - int enc_size = 0; - FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; - SchroEncoder *encoder = p_schro_params->encoder; - struct FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; - int go = 1; - SchroBuffer *enc_buf; - int presentation_frame; - int parse_code; - int last_frame_in_sequence = 0; - - if (!data) { - /* Push end of sequence if not already signalled. */ - if (!p_schro_params->eos_signalled) { - schro_encoder_end_of_stream(encoder); - p_schro_params->eos_signalled = 1; - } - } else { - /* Allocate frame data to schro input buffer. */ - SchroFrame *in_frame = libschroedinger_frame_from_data(avccontext, - data); - /* Load next frame. */ - schro_encoder_push_frame(encoder, in_frame); - } - - if (p_schro_params->eos_pulled) - go = 0; - - /* Now check to see if we have any output from the encoder. */ - while (go) { - SchroStateEnum state; - state = schro_encoder_wait(encoder); - switch (state) { - case SCHRO_STATE_HAVE_BUFFER: - case SCHRO_STATE_END_OF_STREAM: - enc_buf = schro_encoder_pull(encoder, &presentation_frame); - assert(enc_buf->length > 0); - assert(enc_buf->length <= buf_size); - parse_code = enc_buf->data[4]; - - /* All non-frame data is prepended to actual frame data to - * be able to set the pts correctly. So we don't write data - * to the frame output queue until we actually have a frame - */ - p_schro_params->enc_buf = av_realloc(p_schro_params->enc_buf, - p_schro_params->enc_buf_size + enc_buf->length); - - memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size, - enc_buf->data, enc_buf->length); - p_schro_params->enc_buf_size += enc_buf->length; - - - if (state == SCHRO_STATE_END_OF_STREAM) { - p_schro_params->eos_pulled = 1; - go = 0; - } - - if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { - schro_buffer_unref(enc_buf); - break; - } - - /* Create output frame. */ - p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); - /* Set output data. */ - p_frame_output->size = p_schro_params->enc_buf_size; - p_frame_output->p_encbuf = p_schro_params->enc_buf; - if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && - SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) - p_frame_output->key_frame = 1; - - /* Parse the coded frame number from the bitstream. Bytes 14 - * through 17 represesent the frame number. */ - p_frame_output->frame_num = (enc_buf->data[13] << 24) + - (enc_buf->data[14] << 16) + - (enc_buf->data[15] << 8) + - enc_buf->data[16]; - - ff_dirac_schro_queue_push_back(&p_schro_params->enc_frame_queue, - p_frame_output); - p_schro_params->enc_buf_size = 0; - p_schro_params->enc_buf = NULL; - - schro_buffer_unref(enc_buf); - - break; - - case SCHRO_STATE_NEED_FRAME: - go = 0; - break; - - case SCHRO_STATE_AGAIN: - break; - - default: - av_log(avccontext, AV_LOG_ERROR, "Unknown Schro Encoder state\n"); - return -1; - } - } - - /* Copy 'next' frame in queue. */ - - if (p_schro_params->enc_frame_queue.size == 1 && - p_schro_params->eos_pulled) - last_frame_in_sequence = 1; - - p_frame_output = ff_dirac_schro_queue_pop(&p_schro_params->enc_frame_queue); - - if (!p_frame_output) - return 0; - - memcpy(frame, p_frame_output->p_encbuf, p_frame_output->size); - avccontext->coded_frame->key_frame = p_frame_output->key_frame; - /* Use the frame number of the encoded frame as the pts. It is OK to - * do so since Dirac is a constant frame rate codec. It expects input - * to be of constant frame rate. */ - avccontext->coded_frame->pts = p_frame_output->frame_num; - enc_size = p_frame_output->size; - - /* Append the end of sequence information to the last frame in the - * sequence. */ - if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) { - memcpy(frame + enc_size, p_schro_params->enc_buf, - p_schro_params->enc_buf_size); - enc_size += p_schro_params->enc_buf_size; - av_freep(&p_schro_params->enc_buf); - p_schro_params->enc_buf_size = 0; - } - - /* free frame */ - SchroedingerFreeFrame(p_frame_output); - - return enc_size; -} - - -static int libschroedinger_encode_close(AVCodecContext *avccontext) -{ - - FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; - - /* Close the encoder. */ - schro_encoder_free(p_schro_params->encoder); - - /* Free data in the output frame queue. */ - ff_dirac_schro_queue_free(&p_schro_params->enc_frame_queue, - SchroedingerFreeFrame); - - - /* Free the encoder buffer. */ - if (p_schro_params->enc_buf_size) - av_freep(&p_schro_params->enc_buf); - - /* Free the video format structure. */ - av_freep(&p_schro_params->format); - - return 0; -} - - -AVCodec libschroedinger_encoder = { - "libschroedinger", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DIRAC, - sizeof(FfmpegSchroEncoderParams), - libschroedinger_encode_init, - libschroedinger_encode_frame, - libschroedinger_encode_close, - .capabilities = CODEC_CAP_DELAY, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libspeexdec.c b/tizen/distrib/ffmpeg/libavcodec/libspeexdec.c deleted file mode 100644 index c5cfbd5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libspeexdec.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2008 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include -#include -#include -#include - -typedef struct { - SpeexBits bits; - SpeexStereoState stereo; - void *dec_state; - SpeexHeader *header; - int frame_size; -} LibSpeexContext; - - -static av_cold int libspeex_decode_init(AVCodecContext *avctx) -{ - LibSpeexContext *s = avctx->priv_data; - const SpeexMode *mode; - - // defaults in the case of a missing header - if (avctx->sample_rate <= 8000) - mode = &speex_nb_mode; - else if (avctx->sample_rate <= 16000) - mode = &speex_wb_mode; - else - mode = &speex_uwb_mode; - - if (avctx->extradata_size >= 80) - s->header = speex_packet_to_header(avctx->extradata, avctx->extradata_size); - - avctx->sample_fmt = SAMPLE_FMT_S16; - if (s->header) { - avctx->sample_rate = s->header->rate; - avctx->channels = s->header->nb_channels; - avctx->frame_size = s->frame_size = s->header->frame_size; - if (s->header->frames_per_packet) - avctx->frame_size *= s->header->frames_per_packet; - - mode = speex_lib_get_mode(s->header->mode); - if (!mode) { - av_log(avctx, AV_LOG_ERROR, "Unknown Speex mode %d", s->header->mode); - return -1; - } - } else - av_log(avctx, AV_LOG_INFO, "Missing Speex header, assuming defaults.\n"); - - if (avctx->channels > 2) { - av_log(avctx, AV_LOG_ERROR, "Only stereo and mono are supported.\n"); - return -1; - } - - speex_bits_init(&s->bits); - s->dec_state = speex_decoder_init(mode); - if (!s->dec_state) { - av_log(avctx, AV_LOG_ERROR, "Error initializing libspeex decoder.\n"); - return -1; - } - - if (!s->header) { - speex_decoder_ctl(s->dec_state, SPEEX_GET_FRAME_SIZE, &s->frame_size); - } - - if (avctx->channels == 2) { - SpeexCallback callback; - callback.callback_id = SPEEX_INBAND_STEREO; - callback.func = speex_std_stereo_request_handler; - callback.data = &s->stereo; - s->stereo = (SpeexStereoState)SPEEX_STEREO_STATE_INIT; - speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback); - } - return 0; -} - -static int libspeex_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - LibSpeexContext *s = avctx->priv_data; - int16_t *output = data, *end; - int i, num_samples; - - num_samples = s->frame_size * avctx->channels; - end = output + *data_size / sizeof(*output); - - speex_bits_read_from(&s->bits, buf, buf_size); - - for (i = 0; speex_bits_remaining(&s->bits) && output + num_samples < end; i++) { - int ret = speex_decode_int(s->dec_state, &s->bits, output); - if (ret <= -2) { - av_log(avctx, AV_LOG_ERROR, "Error decoding Speex frame.\n"); - return -1; - } else if (ret == -1) - // end of stream - break; - - if (avctx->channels == 2) - speex_decode_stereo_int(output, s->frame_size, &s->stereo); - - output += num_samples; - } - - avctx->frame_size = s->frame_size * i; - *data_size = avctx->channels * avctx->frame_size * sizeof(*output); - return buf_size; -} - -static av_cold int libspeex_decode_close(AVCodecContext *avctx) -{ - LibSpeexContext *s = avctx->priv_data; - - speex_header_free(s->header); - speex_bits_destroy(&s->bits); - speex_decoder_destroy(s->dec_state); - - return 0; -} - -AVCodec libspeex_decoder = { - "libspeex", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_SPEEX, - sizeof(LibSpeexContext), - libspeex_decode_init, - NULL, - libspeex_decode_close, - libspeex_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("libspeex Speex"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libtheoraenc.c b/tizen/distrib/ffmpeg/libavcodec/libtheoraenc.c deleted file mode 100644 index 2dc45a9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libtheoraenc.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2006 Paul Richards - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Theora encoder using libtheora. - * @author Paul Richards - * - * A lot of this is copy / paste from other output codecs in - * libavcodec or pure guesswork (or both). - * - * I have used t_ prefixes on variables which are libtheora types - * and o_ prefixes on variables which are libogg types. - */ - -/* FFmpeg includes */ -#include "libavutil/intreadwrite.h" -#include "libavutil/log.h" -#include "libavutil/base64.h" -#include "avcodec.h" - -/* libtheora includes */ -#include - -typedef struct TheoraContext { - th_enc_ctx *t_state; - uint8_t *stats; - int stats_size; - int stats_offset; - int uv_hshift; - int uv_vshift; - int keyframe_mask; -} TheoraContext; - -/** Concatenates an ogg_packet into the extradata. */ -static int concatenate_packet(unsigned int* offset, - AVCodecContext* avc_context, - const ogg_packet* packet) -{ - const char* message = NULL; - uint8_t* newdata = NULL; - int newsize = avc_context->extradata_size + 2 + packet->bytes; - - if (packet->bytes < 0) { - message = "ogg_packet has negative size"; - } else if (packet->bytes > 0xffff) { - message = "ogg_packet is larger than 65535 bytes"; - } else if (newsize < avc_context->extradata_size) { - message = "extradata_size would overflow"; - } else { - newdata = av_realloc(avc_context->extradata, newsize); - if (!newdata) - message = "av_realloc failed"; - } - if (message) { - av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message); - return -1; - } - - avc_context->extradata = newdata; - avc_context->extradata_size = newsize; - AV_WB16(avc_context->extradata + (*offset), packet->bytes); - *offset += 2; - memcpy(avc_context->extradata + (*offset), packet->packet, packet->bytes); - (*offset) += packet->bytes; - return 0; -} - -static int get_stats(AVCodecContext *avctx, int eos) -{ -#ifdef TH_ENCCTL_2PASS_OUT - TheoraContext *h = avctx->priv_data; - uint8_t *buf; - int bytes; - - bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_OUT, &buf, sizeof(buf)); - if (bytes < 0) { - av_log(avctx, AV_LOG_ERROR, "Error getting first pass stats\n"); - return -1; - } - if (!eos) { - h->stats = av_fast_realloc(h->stats, &h->stats_size, - h->stats_offset + bytes); - memcpy(h->stats + h->stats_offset, buf, bytes); - h->stats_offset += bytes; - } else { - int b64_size = ((h->stats_offset + 2) / 3) * 4 + 1; - // libtheora generates a summary header at the end - memcpy(h->stats, buf, bytes); - avctx->stats_out = av_malloc(b64_size); - av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset); - } - return 0; -#else - av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n"); - return -1; -#endif -} - -// libtheora won't read the entire buffer we give it at once, so we have to -// repeatedly submit it... -static int submit_stats(AVCodecContext *avctx) -{ -#ifdef TH_ENCCTL_2PASS_IN - TheoraContext *h = avctx->priv_data; - int bytes; - if (!h->stats) { - if (!avctx->stats_in) { - av_log(avctx, AV_LOG_ERROR, "No statsfile for second pass\n"); - return -1; - } - h->stats_size = strlen(avctx->stats_in) * 3/4; - h->stats = av_malloc(h->stats_size); - h->stats_size = av_base64_decode(h->stats, avctx->stats_in, h->stats_size); - } - while (h->stats_size - h->stats_offset > 0) { - bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_IN, - h->stats + h->stats_offset, - h->stats_size - h->stats_offset); - if (bytes < 0) { - av_log(avctx, AV_LOG_ERROR, "Error submitting stats\n"); - return -1; - } - if (!bytes) - return 0; - h->stats_offset += bytes; - } - return 0; -#else - av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n"); - return -1; -#endif -} - -static av_cold int encode_init(AVCodecContext* avc_context) -{ - th_info t_info; - th_comment t_comment; - ogg_packet o_packet; - unsigned int offset; - TheoraContext *h = avc_context->priv_data; - uint32_t gop_size = avc_context->gop_size; - - /* Set up the theora_info struct */ - th_info_init(&t_info); - t_info.frame_width = FFALIGN(avc_context->width, 16); - t_info.frame_height = FFALIGN(avc_context->height, 16); - t_info.pic_width = avc_context->width; - t_info.pic_height = avc_context->height; - t_info.pic_x = 0; - t_info.pic_y = 0; - /* Swap numerator and denominator as time_base in AVCodecContext gives the - * time period between frames, but theora_info needs the framerate. */ - t_info.fps_numerator = avc_context->time_base.den; - t_info.fps_denominator = avc_context->time_base.num; - if (avc_context->sample_aspect_ratio.num) { - t_info.aspect_numerator = avc_context->sample_aspect_ratio.num; - t_info.aspect_denominator = avc_context->sample_aspect_ratio.den; - } else { - t_info.aspect_numerator = 1; - t_info.aspect_denominator = 1; - } - - if (avc_context->color_primaries == AVCOL_PRI_BT470M) - t_info.colorspace = TH_CS_ITU_REC_470M; - else if (avc_context->color_primaries == AVCOL_PRI_BT470BG) - t_info.colorspace = TH_CS_ITU_REC_470BG; - else - t_info.colorspace = TH_CS_UNSPECIFIED; - - if (avc_context->pix_fmt == PIX_FMT_YUV420P) - t_info.pixel_fmt = TH_PF_420; - else if (avc_context->pix_fmt == PIX_FMT_YUV422P) - t_info.pixel_fmt = TH_PF_422; - else if (avc_context->pix_fmt == PIX_FMT_YUV444P) - t_info.pixel_fmt = TH_PF_444; - else { - av_log(avc_context, AV_LOG_ERROR, "Unsupported pix_fmt\n"); - return -1; - } - avcodec_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift); - - if (avc_context->flags & CODEC_FLAG_QSCALE) { - /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 - Theora accepts a quality parameter p, which is: - * 0 <= p <=63 - * an int value - */ - t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3; - t_info.target_bitrate = 0; - } else { - t_info.target_bitrate = avc_context->bit_rate; - t_info.quality = 0; - } - - /* Now initialise libtheora */ - h->t_state = th_encode_alloc(&t_info); - if (!h->t_state) { - av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n"); - return -1; - } - - h->keyframe_mask = (1 << t_info.keyframe_granule_shift) - 1; - /* Clear up theora_info struct */ - th_info_clear(&t_info); - - if (th_encode_ctl(h->t_state, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, - &gop_size, sizeof(gop_size))) { - av_log(avc_context, AV_LOG_ERROR, "Error setting GOP size\n"); - return -1; - } - - // need to enable 2 pass (via TH_ENCCTL_2PASS_) before encoding headers - if (avc_context->flags & CODEC_FLAG_PASS1) { - if (get_stats(avc_context, 0)) - return -1; - } else if (avc_context->flags & CODEC_FLAG_PASS2) { - if (submit_stats(avc_context)) - return -1; - } - - /* - Output first header packet consisting of theora - header, comment, and tables. - - Each one is prefixed with a 16bit size, then they - are concatenated together into ffmpeg's extradata. - */ - offset = 0; - - /* Headers */ - th_comment_init(&t_comment); - - while (th_encode_flushheader(h->t_state, &t_comment, &o_packet)) - if (concatenate_packet(&offset, avc_context, &o_packet)) - return -1; - - th_comment_clear(&t_comment); - - /* Set up the output AVFrame */ - avc_context->coded_frame= avcodec_alloc_frame(); - - return 0; -} - -static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf, - int buf_size, void *data) -{ - th_ycbcr_buffer t_yuv_buffer; - TheoraContext *h = avc_context->priv_data; - AVFrame *frame = data; - ogg_packet o_packet; - int result, i; - - // EOS, finish and get 1st pass stats if applicable - if (!frame) { - th_encode_packetout(h->t_state, 1, &o_packet); - if (avc_context->flags & CODEC_FLAG_PASS1) - if (get_stats(avc_context, 1)) - return -1; - return 0; - } - - /* Copy planes to the theora yuv_buffer */ - for (i = 0; i < 3; i++) { - t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> (i && h->uv_hshift); - t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift); - t_yuv_buffer[i].stride = frame->linesize[i]; - t_yuv_buffer[i].data = frame->data[i]; - } - - if (avc_context->flags & CODEC_FLAG_PASS2) - if (submit_stats(avc_context)) - return -1; - - /* Now call into theora_encode_YUVin */ - result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer); - if (result) { - const char* message; - switch (result) { - case -1: - message = "differing frame sizes"; - break; - case TH_EINVAL: - message = "encoder is not ready or is finished"; - break; - default: - message = "unknown reason"; - break; - } - av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result); - return -1; - } - - if (avc_context->flags & CODEC_FLAG_PASS1) - if (get_stats(avc_context, 0)) - return -1; - - /* Pick up returned ogg_packet */ - result = th_encode_packetout(h->t_state, 0, &o_packet); - switch (result) { - case 0: - /* No packet is ready */ - return 0; - case 1: - /* Success, we have a packet */ - break; - default: - av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result); - return -1; - } - - /* Copy ogg_packet content out to buffer */ - if (buf_size < o_packet.bytes) { - av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - memcpy(outbuf, o_packet.packet, o_packet.bytes); - - // HACK: assumes no encoder delay, this is true until libtheora becomes - // multithreaded (which will be disabled unless explictly requested) - avc_context->coded_frame->pts = frame->pts; - avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask); - - return o_packet.bytes; -} - -static av_cold int encode_close(AVCodecContext* avc_context) -{ - TheoraContext *h = avc_context->priv_data; - - th_encode_free(h->t_state); - av_freep(&h->stats); - av_freep(&avc_context->coded_frame); - av_freep(&avc_context->stats_out); - av_freep(&avc_context->extradata); - avc_context->extradata_size = 0; - - return 0; -} - -/** AVCodec struct exposed to libavcodec */ -AVCodec libtheora_encoder = { - .name = "libtheora", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_THEORA, - .priv_data_size = sizeof(TheoraContext), - .init = encode_init, - .close = encode_close, - .encode = encode_frame, - .capabilities = CODEC_CAP_DELAY, // needed to get the statsfile summary - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libvorbis.c b/tizen/distrib/ffmpeg/libavcodec/libvorbis.c deleted file mode 100644 index 81d328a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libvorbis.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * copyright (c) 2002 Mark Hills - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Ogg Vorbis codec support via libvorbisenc. - * @author Mark Hills - */ - -#include - -#include "avcodec.h" -#include "bytestream.h" - -#undef NDEBUG -#include - -#define OGGVORBIS_FRAME_SIZE 64 - -#define BUFFER_SIZE (1024*64) - -typedef struct OggVorbisContext { - vorbis_info vi ; - vorbis_dsp_state vd ; - vorbis_block vb ; - uint8_t buffer[BUFFER_SIZE]; - int buffer_index; - int eof; - - /* decoder */ - vorbis_comment vc ; - ogg_packet op; -} OggVorbisContext ; - - -static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) { - double cfreq; - - if(avccontext->flags & CODEC_FLAG_QSCALE) { - /* variable bitrate */ - if(vorbis_encode_setup_vbr(vi, avccontext->channels, - avccontext->sample_rate, - avccontext->global_quality / (float)FF_QP2LAMBDA / 10.0)) - return -1; - } else { - /* constant bitrate */ - if(vorbis_encode_setup_managed(vi, avccontext->channels, - avccontext->sample_rate, -1, avccontext->bit_rate, -1)) - return -1; - -#ifdef OGGVORBIS_VBR_BY_ESTIMATE - /* variable bitrate by estimate */ - if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE_AVG, NULL)) - return -1; -#endif - } - - /* cutoff frequency */ - if(avccontext->cutoff > 0) { - cfreq = avccontext->cutoff / 1000.0; - if(vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)) - return -1; - } - - return vorbis_encode_setup_init(vi); -} - -static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) { - OggVorbisContext *context = avccontext->priv_data ; - ogg_packet header, header_comm, header_code; - uint8_t *p; - unsigned int offset, len; - - vorbis_info_init(&context->vi) ; - if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) { - av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed\n") ; - return -1 ; - } - vorbis_analysis_init(&context->vd, &context->vi) ; - vorbis_block_init(&context->vd, &context->vb) ; - - vorbis_comment_init(&context->vc); - vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT) ; - - vorbis_analysis_headerout(&context->vd, &context->vc, &header, - &header_comm, &header_code); - - len = header.bytes + header_comm.bytes + header_code.bytes; - avccontext->extradata_size= 64 + len + len/255; - p = avccontext->extradata= av_mallocz(avccontext->extradata_size); - p[0] = 2; - offset = 1; - offset += av_xiphlacing(&p[offset], header.bytes); - offset += av_xiphlacing(&p[offset], header_comm.bytes); - memcpy(&p[offset], header.packet, header.bytes); - offset += header.bytes; - memcpy(&p[offset], header_comm.packet, header_comm.bytes); - offset += header_comm.bytes; - memcpy(&p[offset], header_code.packet, header_code.bytes); - offset += header_code.bytes; - avccontext->extradata_size = offset; - avccontext->extradata= av_realloc(avccontext->extradata, avccontext->extradata_size); - -/* vorbis_block_clear(&context->vb); - vorbis_dsp_clear(&context->vd); - vorbis_info_clear(&context->vi);*/ - vorbis_comment_clear(&context->vc); - - avccontext->frame_size = OGGVORBIS_FRAME_SIZE ; - - avccontext->coded_frame= avcodec_alloc_frame(); - avccontext->coded_frame->key_frame= 1; - - return 0 ; -} - - -static int oggvorbis_encode_frame(AVCodecContext *avccontext, - unsigned char *packets, - int buf_size, void *data) -{ - OggVorbisContext *context = avccontext->priv_data ; - ogg_packet op ; - signed short *audio = data ; - int l; - - if(data) { - int samples = OGGVORBIS_FRAME_SIZE; - float **buffer ; - - buffer = vorbis_analysis_buffer(&context->vd, samples) ; - if(context->vi.channels == 1) { - for(l = 0 ; l < samples ; l++) - buffer[0][l]=audio[l]/32768.f; - } else { - for(l = 0 ; l < samples ; l++){ - buffer[0][l]=audio[l*2]/32768.f; - buffer[1][l]=audio[l*2+1]/32768.f; - } - } - vorbis_analysis_wrote(&context->vd, samples) ; - } else { - if(!context->eof) - vorbis_analysis_wrote(&context->vd, 0) ; - context->eof = 1; - } - - while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) { - vorbis_analysis(&context->vb, NULL); - vorbis_bitrate_addblock(&context->vb) ; - - while(vorbis_bitrate_flushpacket(&context->vd, &op)) { - /* i'd love to say the following line is a hack, but sadly it's - * not, apparently the end of stream decision is in libogg. */ - if(op.bytes==1) - continue; - memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet)); - context->buffer_index += sizeof(ogg_packet); - memcpy(context->buffer + context->buffer_index, op.packet, op.bytes); - context->buffer_index += op.bytes; -// av_log(avccontext, AV_LOG_DEBUG, "e%d / %d\n", context->buffer_index, op.bytes); - } - } - - l=0; - if(context->buffer_index){ - ogg_packet *op2= (ogg_packet*)context->buffer; - op2->packet = context->buffer + sizeof(ogg_packet); - - l= op2->bytes; - avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base); - //FIXME we should reorder the user supplied pts and not assume that they are spaced by 1/sample_rate - - memcpy(packets, op2->packet, l); - context->buffer_index -= l + sizeof(ogg_packet); - memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index); -// av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l); - } - - return l; -} - - -static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) { - OggVorbisContext *context = avccontext->priv_data ; -/* ogg_packet op ; */ - - vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */ - - vorbis_block_clear(&context->vb); - vorbis_dsp_clear(&context->vd); - vorbis_info_clear(&context->vi); - - av_freep(&avccontext->coded_frame); - av_freep(&avccontext->extradata); - - return 0 ; -} - - -AVCodec libvorbis_encoder = { - "libvorbis", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_VORBIS, - sizeof(OggVorbisContext), - oggvorbis_encode_init, - oggvorbis_encode_frame, - oggvorbis_encode_close, - .capabilities= CODEC_CAP_DELAY, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("libvorbis Vorbis"), -} ; diff --git a/tizen/distrib/ffmpeg/libavcodec/libvpxdec.c b/tizen/distrib/ffmpeg/libavcodec/libvpxdec.c deleted file mode 100644 index 0464d12..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libvpxdec.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2010, Google, Inc. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VP8 decoder support via libvpx - */ - -#define VPX_CODEC_DISABLE_COMPAT 1 -#include -#include - -#include "avcodec.h" - -typedef struct VP8DecoderContext { - struct vpx_codec_ctx decoder; -} VP8Context; - -static av_cold int vp8_init(AVCodecContext *avctx) -{ - VP8Context *ctx = avctx->priv_data; - const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo; - struct vpx_codec_dec_cfg deccfg = { - /* token partitions+1 would be a decent choice */ - .threads = FFMIN(avctx->thread_count, 16) - }; - - av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); - av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config()); - - if (vpx_codec_dec_init(&ctx->decoder, iface, &deccfg, 0) != VPX_CODEC_OK) { - const char *error = vpx_codec_error(&ctx->decoder); - av_log(avctx, AV_LOG_ERROR, "Failed to initialize decoder: %s\n", - error); - return AVERROR(EINVAL); - } - - avctx->pix_fmt = PIX_FMT_YUV420P; - return 0; -} - -static int vp8_decode(AVCodecContext *avctx, - void *data, int *data_size, AVPacket *avpkt) -{ - VP8Context *ctx = avctx->priv_data; - AVFrame *picture = data; - const void *iter = NULL; - struct vpx_image *img; - - if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) != - VPX_CODEC_OK) { - const char *error = vpx_codec_error(&ctx->decoder); - const char *detail = vpx_codec_error_detail(&ctx->decoder); - - av_log(avctx, AV_LOG_ERROR, "Failed to decode frame: %s\n", error); - if (detail) - av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", - detail); - return AVERROR_INVALIDDATA; - } - - if ((img = vpx_codec_get_frame(&ctx->decoder, &iter))) { - if (img->fmt != VPX_IMG_FMT_I420) { - av_log(avctx, AV_LOG_ERROR, "Unsupported output colorspace (%d)\n", - img->fmt); - return AVERROR_INVALIDDATA; - } - - if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) { - av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n", - avctx->width, avctx->height, img->d_w, img->d_h); - if (avcodec_check_dimensions(avctx, img->d_w, img->d_h)) - return AVERROR_INVALIDDATA; - avcodec_set_dimensions(avctx, img->d_w, img->d_h); - } - picture->data[0] = img->planes[0]; - picture->data[1] = img->planes[1]; - picture->data[2] = img->planes[2]; - picture->data[3] = NULL; - picture->linesize[0] = img->stride[0]; - picture->linesize[1] = img->stride[1]; - picture->linesize[2] = img->stride[2]; - picture->linesize[3] = 0; - *data_size = sizeof(AVPicture); - } - return avpkt->size; -} - -static av_cold int vp8_free(AVCodecContext *avctx) -{ - VP8Context *ctx = avctx->priv_data; - vpx_codec_destroy(&ctx->decoder); - return 0; -} - -AVCodec libvpx_decoder = { - "libvpx", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VP8, - sizeof(VP8Context), - vp8_init, - NULL, /* encode */ - vp8_free, - vp8_decode, - 0, /* capabilities */ - .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libvpxenc.c b/tizen/distrib/ffmpeg/libavcodec/libvpxenc.c deleted file mode 100644 index fa393b8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libvpxenc.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (c) 2010, Google, Inc. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VP8 encoder support via libvpx - */ - -#define VPX_DISABLE_CTRL_TYPECHECKS 1 -#define VPX_CODEC_DISABLE_COMPAT 1 -#include -#include - -#include "avcodec.h" -#include "libavutil/base64.h" - -/** - * Portion of struct vpx_codec_cx_pkt from vpx_encoder.h. - * One encoded frame returned from the library. - */ -struct FrameListData { - void *buf; /**≤ compressed data buffer */ - size_t sz; /**≤ length of compressed data */ - int64_t pts; /**≤ time stamp to show frame - (in timebase units) */ - unsigned long duration; /**≤ duration to show frame - (in timebase units) */ - uint32_t flags; /**≤ flags for this frame */ - struct FrameListData *next; -}; - -typedef struct VP8EncoderContext { - struct vpx_codec_ctx encoder; - struct vpx_image rawimg; - struct vpx_fixed_buf twopass_stats; - unsigned long deadline; //i.e., RT/GOOD/BEST - struct FrameListData *coded_frame_list; -} VP8Context; - -/** String mappings for enum vp8e_enc_control_id */ -static const char *ctlidstr[] = { - [VP8E_UPD_ENTROPY] = "VP8E_UPD_ENTROPY", - [VP8E_UPD_REFERENCE] = "VP8E_UPD_REFERENCE", - [VP8E_USE_REFERENCE] = "VP8E_USE_REFERENCE", - [VP8E_SET_ROI_MAP] = "VP8E_SET_ROI_MAP", - [VP8E_SET_ACTIVEMAP] = "VP8E_SET_ACTIVEMAP", - [VP8E_SET_SCALEMODE] = "VP8E_SET_SCALEMODE", - [VP8E_SET_CPUUSED] = "VP8E_SET_CPUUSED", - [VP8E_SET_ENABLEAUTOALTREF] = "VP8E_SET_ENABLEAUTOALTREF", - [VP8E_SET_NOISE_SENSITIVITY] = "VP8E_SET_NOISE_SENSITIVITY", - [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS", - [VP8E_SET_STATIC_THRESHOLD] = "VP8E_SET_STATIC_THRESHOLD", - [VP8E_SET_TOKEN_PARTITIONS] = "VP8E_SET_TOKEN_PARTITIONS", - [VP8E_GET_LAST_QUANTIZER] = "VP8E_GET_LAST_QUANTIZER", - [VP8E_SET_ARNR_MAXFRAMES] = "VP8E_SET_ARNR_MAXFRAMES", - [VP8E_SET_ARNR_STRENGTH] = "VP8E_SET_ARNR_STRENGTH", - [VP8E_SET_ARNR_TYPE] = "VP8E_SET_ARNR_TYPE", -}; - -static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc) -{ - VP8Context *ctx = avctx->priv_data; - const char *error = vpx_codec_error(&ctx->encoder); - const char *detail = vpx_codec_error_detail(&ctx->encoder); - - av_log(avctx, AV_LOG_ERROR, "%s: %s\n", desc, error); - if (detail) - av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", detail); -} - -static av_cold void dump_enc_cfg(AVCodecContext *avctx, - const struct vpx_codec_enc_cfg *cfg) -{ - int width = -30; - int level = AV_LOG_DEBUG; - - av_log(avctx, level, "vpx_codec_enc_cfg\n"); - av_log(avctx, level, "generic settings\n" - " %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n" - " %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n", - width, "g_usage:", cfg->g_usage, - width, "g_threads:", cfg->g_threads, - width, "g_profile:", cfg->g_profile, - width, "g_w:", cfg->g_w, - width, "g_h:", cfg->g_h, - width, "g_timebase:", cfg->g_timebase.num, cfg->g_timebase.den, - width, "g_error_resilient:", cfg->g_error_resilient, - width, "g_pass:", cfg->g_pass, - width, "g_lag_in_frames:", cfg->g_lag_in_frames); - av_log(avctx, level, "rate control settings\n" - " %*s%u\n %*s%u\n %*s%u\n %*s%u\n" - " %*s%d\n %*s%p(%zu)\n %*s%u\n", - width, "rc_dropframe_thresh:", cfg->rc_dropframe_thresh, - width, "rc_resize_allowed:", cfg->rc_resize_allowed, - width, "rc_resize_up_thresh:", cfg->rc_resize_up_thresh, - width, "rc_resize_down_thresh:", cfg->rc_resize_down_thresh, - width, "rc_end_usage:", cfg->rc_end_usage, - width, "rc_twopass_stats_in:", cfg->rc_twopass_stats_in.buf, cfg->rc_twopass_stats_in.sz, - width, "rc_target_bitrate:", cfg->rc_target_bitrate); - av_log(avctx, level, "quantizer settings\n" - " %*s%u\n %*s%u\n", - width, "rc_min_quantizer:", cfg->rc_min_quantizer, - width, "rc_max_quantizer:", cfg->rc_max_quantizer); - av_log(avctx, level, "bitrate tolerance\n" - " %*s%u\n %*s%u\n", - width, "rc_undershoot_pct:", cfg->rc_undershoot_pct, - width, "rc_overshoot_pct:", cfg->rc_overshoot_pct); - av_log(avctx, level, "decoder buffer model\n" - " %*s%u\n %*s%u\n %*s%u\n", - width, "rc_buf_sz:", cfg->rc_buf_sz, - width, "rc_buf_initial_sz:", cfg->rc_buf_initial_sz, - width, "rc_buf_optimal_sz:", cfg->rc_buf_optimal_sz); - av_log(avctx, level, "2 pass rate control settings\n" - " %*s%u\n %*s%u\n %*s%u\n", - width, "rc_2pass_vbr_bias_pct:", cfg->rc_2pass_vbr_bias_pct, - width, "rc_2pass_vbr_minsection_pct:", cfg->rc_2pass_vbr_minsection_pct, - width, "rc_2pass_vbr_maxsection_pct:", cfg->rc_2pass_vbr_maxsection_pct); - av_log(avctx, level, "keyframing settings\n" - " %*s%d\n %*s%u\n %*s%u\n", - width, "kf_mode:", cfg->kf_mode, - width, "kf_min_dist:", cfg->kf_min_dist, - width, "kf_max_dist:", cfg->kf_max_dist); - av_log(avctx, level, "\n"); -} - -static void coded_frame_add(void *list, struct FrameListData *cx_frame) -{ - struct FrameListData **p = list; - - while (*p != NULL) - p = &(*p)->next; - *p = cx_frame; - cx_frame->next = NULL; -} - -static av_cold void free_coded_frame(struct FrameListData *cx_frame) -{ - av_freep(&cx_frame->buf); - av_freep(&cx_frame); -} - -static av_cold void free_frame_list(struct FrameListData *list) -{ - struct FrameListData *p = list; - - while (p) { - list = list->next; - free_coded_frame(p); - p = list; - } -} - -static av_cold int codecctl_int(AVCodecContext *avctx, - enum vp8e_enc_control_id id, int val) -{ - VP8Context *ctx = avctx->priv_data; - char buf[80]; - int width = -30; - int res; - - snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); - av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, val); - - res = vpx_codec_control(&ctx->encoder, id, val); - if (res != VPX_CODEC_OK) { - snprintf(buf, sizeof(buf), "Failed to set %s codec control", - ctlidstr[id]); - log_encoder_error(avctx, buf); - } - - return res == VPX_CODEC_OK ? 0 : AVERROR(EINVAL); -} - -static av_cold int vp8_free(AVCodecContext *avctx) -{ - VP8Context *ctx = avctx->priv_data; - - vpx_codec_destroy(&ctx->encoder); - av_freep(&ctx->twopass_stats.buf); - av_freep(&avctx->coded_frame); - av_freep(&avctx->stats_out); - free_frame_list(ctx->coded_frame_list); - return 0; -} - -static av_cold int vp8_init(AVCodecContext *avctx) -{ - VP8Context *ctx = avctx->priv_data; - const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo; - int cpuused = 3; - struct vpx_codec_enc_cfg enccfg; - int res; - - av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); - av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config()); - - if ((res = vpx_codec_enc_config_default(iface, &enccfg, 0)) != VPX_CODEC_OK) { - av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n", - vpx_codec_err_to_string(res)); - return AVERROR(EINVAL); - } - dump_enc_cfg(avctx, &enccfg); - - enccfg.g_w = avctx->width; - enccfg.g_h = avctx->height; - enccfg.g_timebase.num = avctx->time_base.num; - enccfg.g_timebase.den = avctx->time_base.den; - enccfg.g_threads = avctx->thread_count; - - if (avctx->flags & CODEC_FLAG_PASS1) - enccfg.g_pass = VPX_RC_FIRST_PASS; - else if (avctx->flags & CODEC_FLAG_PASS2) - enccfg.g_pass = VPX_RC_LAST_PASS; - else - enccfg.g_pass = VPX_RC_ONE_PASS; - - if (avctx->rc_min_rate == avctx->rc_max_rate && - avctx->rc_min_rate == avctx->bit_rate) - enccfg.rc_end_usage = VPX_CBR; - enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000, - AV_ROUND_NEAR_INF); - - //convert [1,51] -> [0,63] - enccfg.rc_min_quantizer = ((avctx->qmin * 5 + 1) >> 2) - 1; - enccfg.rc_max_quantizer = ((avctx->qmax * 5 + 1) >> 2) - 1; - - if (avctx->keyint_min == avctx->gop_size) - enccfg.kf_mode = VPX_KF_FIXED; - //_enc_init() will balk if kf_min_dist is set in this case - if (enccfg.kf_mode != VPX_KF_AUTO) - enccfg.kf_min_dist = avctx->keyint_min; - enccfg.kf_max_dist = avctx->gop_size; - - if (enccfg.g_pass == VPX_RC_FIRST_PASS) - enccfg.g_lag_in_frames = 0; - else if (enccfg.g_pass == VPX_RC_LAST_PASS) { - int decode_size; - - if (!avctx->stats_in) { - av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n"); - return AVERROR_INVALIDDATA; - } - - ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4; - ctx->twopass_stats.buf = av_malloc(ctx->twopass_stats.sz); - if (!ctx->twopass_stats.buf) { - av_log(avctx, AV_LOG_ERROR, - "Stat buffer alloc (%zu bytes) failed\n", - ctx->twopass_stats.sz); - return AVERROR(ENOMEM); - } - decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in, - ctx->twopass_stats.sz); - if (decode_size < 0) { - av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n"); - return AVERROR_INVALIDDATA; - } - - ctx->twopass_stats.sz = decode_size; - enccfg.rc_twopass_stats_in = ctx->twopass_stats; - } - - ctx->deadline = VPX_DL_GOOD_QUALITY; - - dump_enc_cfg(avctx, &enccfg); - /* Construct Encoder Context */ - res = vpx_codec_enc_init(&ctx->encoder, iface, &enccfg, 0); - if (res != VPX_CODEC_OK) { - log_encoder_error(avctx, "Failed to initialize encoder"); - return AVERROR(EINVAL); - } - - //codec control failures are currently treated only as warnings - av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n"); - codecctl_int(avctx, VP8E_SET_CPUUSED, cpuused); - codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction); - - //provide dummy value to initialize wrapper, values will be updated each _encode() - vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1, - (unsigned char*)1); - - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) { - av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n"); - vp8_free(avctx); - return AVERROR(ENOMEM); - } - return 0; -} - -static inline void cx_pktcpy(struct FrameListData *dst, - const struct vpx_codec_cx_pkt *src) -{ - dst->pts = src->data.frame.pts; - dst->duration = src->data.frame.duration; - dst->flags = src->data.frame.flags; - dst->sz = src->data.frame.sz; - dst->buf = src->data.frame.buf; -} - -/** - * Store coded frame information in format suitable for return from encode(). - * - * Write buffer information from @a cx_frame to @a buf & @a buf_size. - * Timing/frame details to @a coded_frame. - * @return Frame size written to @a buf on success - * @return AVERROR(EINVAL) on error - */ -static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, - uint8_t *buf, int buf_size, AVFrame *coded_frame) -{ - if ((int) cx_frame->sz <= buf_size) { - buf_size = cx_frame->sz; - memcpy(buf, cx_frame->buf, buf_size); - coded_frame->pts = cx_frame->pts; - coded_frame->key_frame = !!(cx_frame->flags & VPX_FRAME_IS_KEY); - - if (coded_frame->key_frame) - coded_frame->pict_type = FF_I_TYPE; - else - coded_frame->pict_type = FF_P_TYPE; - } else { - av_log(avctx, AV_LOG_ERROR, - "Compressed frame larger than storage provided! (%zu/%d)\n", - cx_frame->sz, buf_size); - return AVERROR(EINVAL); - } - return buf_size; -} - -/** - * Queue multiple output frames from the encoder, returning the front-most. - * In cases where vpx_codec_get_cx_data() returns more than 1 frame append - * the frame queue. Return the head frame if available. - * @return Stored frame size - * @return AVERROR(EINVAL) on output size error - * @return AVERROR(ENOMEM) on coded frame queue data allocation error - */ -static int queue_frames(AVCodecContext *avctx, uint8_t *buf, int buf_size, - AVFrame *coded_frame) -{ - VP8Context *ctx = avctx->priv_data; - const struct vpx_codec_cx_pkt *pkt; - const void *iter = NULL; - int size = 0; - - if (ctx->coded_frame_list) { - struct FrameListData *cx_frame = ctx->coded_frame_list; - /* return the leading frame if we've already begun queueing */ - size = storeframe(avctx, cx_frame, buf, buf_size, coded_frame); - if (size < 0) - return AVERROR(EINVAL); - ctx->coded_frame_list = cx_frame->next; - free_coded_frame(cx_frame); - } - - /* consume all available output from the encoder before returning. buffers - are only good through the next vpx_codec call */ - while ((pkt = vpx_codec_get_cx_data(&ctx->encoder, &iter))) { - switch (pkt->kind) { - case VPX_CODEC_CX_FRAME_PKT: - if (!size) { - struct FrameListData cx_frame; - - /* avoid storing the frame when the list is empty and we haven't yet - provided a frame for output */ - assert(!ctx->coded_frame_list); - cx_pktcpy(&cx_frame, pkt); - size = storeframe(avctx, &cx_frame, buf, buf_size, coded_frame); - if (size < 0) - return AVERROR(EINVAL); - } else { - struct FrameListData *cx_frame = - av_malloc(sizeof(struct FrameListData)); - - if (!cx_frame) { - av_log(avctx, AV_LOG_ERROR, - "Frame queue element alloc failed\n"); - return AVERROR(ENOMEM); - } - cx_pktcpy(cx_frame, pkt); - cx_frame->buf = av_malloc(cx_frame->sz); - - if (!cx_frame->buf) { - av_log(avctx, AV_LOG_ERROR, - "Data buffer alloc (%zu bytes) failed\n", - cx_frame->sz); - return AVERROR(ENOMEM); - } - memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz); - coded_frame_add(&ctx->coded_frame_list, cx_frame); - } - break; - case VPX_CODEC_STATS_PKT: { - struct vpx_fixed_buf *stats = &ctx->twopass_stats; - stats->buf = av_realloc(stats->buf, - stats->sz + pkt->data.twopass_stats.sz); - if (!stats->buf) { - av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n"); - return AVERROR(ENOMEM); - } - memcpy((uint8_t*)stats->buf + stats->sz, - pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz); - stats->sz += pkt->data.twopass_stats.sz; - break; - } - case VPX_CODEC_PSNR_PKT: //FIXME add support for CODEC_FLAG_PSNR - case VPX_CODEC_CUSTOM_PKT: - //ignore unsupported/unrecognized packet types - break; - } - } - - return size; -} - -static int vp8_encode(AVCodecContext *avctx, uint8_t *buf, int buf_size, - void *data) -{ - VP8Context *ctx = avctx->priv_data; - AVFrame *frame = data; - struct vpx_image *rawimg = NULL; - int64_t timestamp = 0; - int res, coded_size; - - if (frame) { - rawimg = &ctx->rawimg; - rawimg->planes[VPX_PLANE_Y] = frame->data[0]; - rawimg->planes[VPX_PLANE_U] = frame->data[1]; - rawimg->planes[VPX_PLANE_V] = frame->data[2]; - rawimg->stride[VPX_PLANE_Y] = frame->linesize[0]; - rawimg->stride[VPX_PLANE_U] = frame->linesize[1]; - rawimg->stride[VPX_PLANE_V] = frame->linesize[2]; - timestamp = frame->pts; - } - - res = vpx_codec_encode(&ctx->encoder, rawimg, timestamp, - avctx->ticks_per_frame, 0, ctx->deadline); - if (res != VPX_CODEC_OK) { - log_encoder_error(avctx, "Error encoding frame"); - return AVERROR_INVALIDDATA; - } - coded_size = queue_frames(avctx, buf, buf_size, avctx->coded_frame); - - if (!frame && avctx->flags & CODEC_FLAG_PASS1) { - unsigned int b64_size = ((ctx->twopass_stats.sz + 2) / 3) * 4 + 1; - - avctx->stats_out = av_malloc(b64_size); - if (!avctx->stats_out) { - av_log(avctx, AV_LOG_ERROR, "Stat buffer alloc (%d bytes) failed\n", - b64_size); - return AVERROR(ENOMEM); - } - av_base64_encode(avctx->stats_out, b64_size, ctx->twopass_stats.buf, - ctx->twopass_stats.sz); - } - return coded_size; -} - -AVCodec libvpx_encoder = { - "libvpx", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VP8, - sizeof(VP8Context), - vp8_init, - vp8_encode, - vp8_free, - NULL, - CODEC_CAP_DELAY, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libx264.c b/tizen/distrib/ffmpeg/libavcodec/libx264.c deleted file mode 100644 index df7b2e8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libx264.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * H.264 encoding using the x264 library - * Copyright (C) 2005 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include -#include -#include -#include -#include - -typedef struct X264Context { - x264_param_t params; - x264_t *enc; - x264_picture_t pic; - uint8_t *sei; - int sei_size; - AVFrame out_pic; -} X264Context; - -static void X264_log(void *p, int level, const char *fmt, va_list args) -{ - static const int level_map[] = { - [X264_LOG_ERROR] = AV_LOG_ERROR, - [X264_LOG_WARNING] = AV_LOG_WARNING, - [X264_LOG_INFO] = AV_LOG_INFO, - [X264_LOG_DEBUG] = AV_LOG_DEBUG - }; - - if (level < 0 || level > X264_LOG_DEBUG) - return; - - av_vlog(p, level_map[level], fmt, args); -} - - -static int encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, - x264_nal_t *nals, int nnal, int skip_sei) -{ - X264Context *x4 = ctx->priv_data; - uint8_t *p = buf; - int i; - - /* Write the SEI as part of the first frame. */ - if (x4->sei_size > 0 && nnal > 0) { - memcpy(p, x4->sei, x4->sei_size); - p += x4->sei_size; - x4->sei_size = 0; - } - - for (i = 0; i < nnal; i++){ - /* Don't put the SEI in extradata. */ - if (skip_sei && nals[i].i_type == NAL_SEI) { - x4->sei_size = nals[i].i_payload; - x4->sei = av_malloc(x4->sei_size); - memcpy(x4->sei, nals[i].p_payload, nals[i].i_payload); - continue; - } - memcpy(p, nals[i].p_payload, nals[i].i_payload); - p += nals[i].i_payload; - } - - return p - buf; -} - -static int X264_frame(AVCodecContext *ctx, uint8_t *buf, - int bufsize, void *data) -{ - X264Context *x4 = ctx->priv_data; - AVFrame *frame = data; - x264_nal_t *nal; - int nnal, i; - x264_picture_t pic_out; - - x4->pic.img.i_csp = X264_CSP_I420; - x4->pic.img.i_plane = 3; - - if (frame) { - for (i = 0; i < 3; i++) { - x4->pic.img.plane[i] = frame->data[i]; - x4->pic.img.i_stride[i] = frame->linesize[i]; - } - - x4->pic.i_pts = frame->pts; - x4->pic.i_type = X264_TYPE_AUTO; - } - - if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) - return -1; - - bufsize = encode_nals(ctx, buf, bufsize, nal, nnal, 0); - if (bufsize < 0) - return -1; - - /* FIXME: libx264 now provides DTS, but AVFrame doesn't have a field for it. */ - x4->out_pic.pts = pic_out.i_pts; - - switch (pic_out.i_type) { - case X264_TYPE_IDR: - case X264_TYPE_I: - x4->out_pic.pict_type = FF_I_TYPE; - break; - case X264_TYPE_P: - x4->out_pic.pict_type = FF_P_TYPE; - break; - case X264_TYPE_B: - case X264_TYPE_BREF: - x4->out_pic.pict_type = FF_B_TYPE; - break; - } - - x4->out_pic.key_frame = pic_out.b_keyframe; - x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; - - return bufsize; -} - -static av_cold int X264_close(AVCodecContext *avctx) -{ - X264Context *x4 = avctx->priv_data; - - av_freep(&avctx->extradata); - av_free(x4->sei); - - if (x4->enc) - x264_encoder_close(x4->enc); - - return 0; -} - -static av_cold int X264_init(AVCodecContext *avctx) -{ - X264Context *x4 = avctx->priv_data; - - x4->sei_size = 0; - x264_param_default(&x4->params); - - x4->params.pf_log = X264_log; - x4->params.p_log_private = avctx; - - x4->params.i_keyint_max = avctx->gop_size; - x4->params.rc.i_bitrate = avctx->bit_rate / 1000; - x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000; - x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate / 1000; - x4->params.rc.b_stat_write = avctx->flags & CODEC_FLAG_PASS1; - if (avctx->flags & CODEC_FLAG_PASS2) { - x4->params.rc.b_stat_read = 1; - } else { - if (avctx->crf) { - x4->params.rc.i_rc_method = X264_RC_CRF; - x4->params.rc.f_rf_constant = avctx->crf; - } else if (avctx->cqp > -1) { - x4->params.rc.i_rc_method = X264_RC_CQP; - x4->params.rc.i_qp_constant = avctx->cqp; - } - } - - // if neither crf nor cqp modes are selected we have to enable the RC - // we do it this way because we cannot check if the bitrate has been set - if (!(avctx->crf || (avctx->cqp > -1))) - x4->params.rc.i_rc_method = X264_RC_ABR; - - x4->params.i_bframe = avctx->max_b_frames; - x4->params.b_cabac = avctx->coder_type == FF_CODER_TYPE_AC; - x4->params.i_bframe_adaptive = avctx->b_frame_strategy; - x4->params.i_bframe_bias = avctx->bframebias; - x4->params.i_bframe_pyramid = avctx->flags2 & CODEC_FLAG2_BPYRAMID ? X264_B_PYRAMID_NORMAL : X264_B_PYRAMID_NONE; - avctx->has_b_frames = avctx->flags2 & CODEC_FLAG2_BPYRAMID ? 2 : !!avctx->max_b_frames; - - x4->params.i_keyint_min = avctx->keyint_min; - if (x4->params.i_keyint_min > x4->params.i_keyint_max) - x4->params.i_keyint_min = x4->params.i_keyint_max; - - x4->params.i_scenecut_threshold = avctx->scenechange_threshold; - - x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER; - x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha; - x4->params.i_deblocking_filter_beta = avctx->deblockbeta; - - x4->params.rc.i_qp_min = avctx->qmin; - x4->params.rc.i_qp_max = avctx->qmax; - x4->params.rc.i_qp_step = avctx->max_qdiff; - - x4->params.rc.f_qcompress = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */ - x4->params.rc.f_qblur = avctx->qblur; /* temporally blur quants */ - x4->params.rc.f_complexity_blur = avctx->complexityblur; - - x4->params.i_frame_reference = avctx->refs; - - x4->params.i_width = avctx->width; - x4->params.i_height = avctx->height; - x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num; - x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den; - x4->params.i_fps_num = x4->params.i_timebase_den = avctx->time_base.den; - x4->params.i_fps_den = x4->params.i_timebase_num = avctx->time_base.num; - - x4->params.analyse.inter = 0; - if (avctx->partitions) { - if (avctx->partitions & X264_PART_I4X4) - x4->params.analyse.inter |= X264_ANALYSE_I4x4; - if (avctx->partitions & X264_PART_I8X8) - x4->params.analyse.inter |= X264_ANALYSE_I8x8; - if (avctx->partitions & X264_PART_P8X8) - x4->params.analyse.inter |= X264_ANALYSE_PSUB16x16; - if (avctx->partitions & X264_PART_P4X4) - x4->params.analyse.inter |= X264_ANALYSE_PSUB8x8; - if (avctx->partitions & X264_PART_B8X8) - x4->params.analyse.inter |= X264_ANALYSE_BSUB16x16; - } - - x4->params.analyse.i_direct_mv_pred = avctx->directpred; - - x4->params.analyse.b_weighted_bipred = avctx->flags2 & CODEC_FLAG2_WPRED; - x4->params.analyse.i_weighted_pred = avctx->weighted_p_pred; - - if (avctx->me_method == ME_EPZS) - x4->params.analyse.i_me_method = X264_ME_DIA; - else if (avctx->me_method == ME_HEX) - x4->params.analyse.i_me_method = X264_ME_HEX; - else if (avctx->me_method == ME_UMH) - x4->params.analyse.i_me_method = X264_ME_UMH; - else if (avctx->me_method == ME_FULL) - x4->params.analyse.i_me_method = X264_ME_ESA; - else if (avctx->me_method == ME_TESA) - x4->params.analyse.i_me_method = X264_ME_TESA; - else x4->params.analyse.i_me_method = X264_ME_HEX; - - x4->params.rc.i_aq_mode = avctx->aq_mode; - x4->params.rc.f_aq_strength = avctx->aq_strength; - x4->params.rc.i_lookahead = avctx->rc_lookahead; - - x4->params.analyse.b_psy = avctx->flags2 & CODEC_FLAG2_PSY; - x4->params.analyse.f_psy_rd = avctx->psy_rd; - x4->params.analyse.f_psy_trellis = avctx->psy_trellis; - - x4->params.analyse.i_me_range = avctx->me_range; - x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality; - - x4->params.analyse.b_mixed_references = avctx->flags2 & CODEC_FLAG2_MIXED_REFS; - x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA; - x4->params.analyse.b_transform_8x8 = avctx->flags2 & CODEC_FLAG2_8X8DCT; - x4->params.analyse.b_fast_pskip = avctx->flags2 & CODEC_FLAG2_FASTPSKIP; - - x4->params.analyse.i_trellis = avctx->trellis; - x4->params.analyse.i_noise_reduction = avctx->noise_reduction; - - if (avctx->level > 0) - x4->params.i_level_idc = avctx->level; - - x4->params.rc.f_rate_tolerance = - (float)avctx->bit_rate_tolerance/avctx->bit_rate; - - if ((avctx->rc_buffer_size != 0) && - (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) { - x4->params.rc.f_vbv_buffer_init = - (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size; - } else - x4->params.rc.f_vbv_buffer_init = 0.9; - - x4->params.rc.b_mb_tree = !!(avctx->flags2 & CODEC_FLAG2_MBTREE); - x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor); - x4->params.rc.f_pb_factor = avctx->b_quant_factor; - x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset; - - x4->params.analyse.b_psnr = avctx->flags & CODEC_FLAG_PSNR; - x4->params.analyse.b_ssim = avctx->flags2 & CODEC_FLAG2_SSIM; - x4->params.i_log_level = X264_LOG_DEBUG; - - x4->params.b_aud = avctx->flags2 & CODEC_FLAG2_AUD; - - x4->params.i_threads = avctx->thread_count; - - x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT; - - if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) - x4->params.b_repeat_headers = 0; - - x4->enc = x264_encoder_open(&x4->params); - if (!x4->enc) - return -1; - - avctx->coded_frame = &x4->out_pic; - - if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { - x264_nal_t *nal; - int nnal, s, i; - - s = x264_encoder_headers(x4->enc, &nal, &nnal); - - for (i = 0; i < nnal; i++) - if (nal[i].i_type == NAL_SEI) - av_log(avctx, AV_LOG_INFO, "%s\n", nal[i].p_payload+25); - - avctx->extradata = av_malloc(s); - avctx->extradata_size = encode_nals(avctx, avctx->extradata, s, nal, nnal, 1); - } - - return 0; -} - -AVCodec libx264_encoder = { - .name = "libx264", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_H264, - .priv_data_size = sizeof(X264Context), - .init = X264_init, - .encode = X264_frame, - .close = X264_close, - .capabilities = CODEC_CAP_DELAY, - .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_NONE }, - .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/libxvid_internal.h b/tizen/distrib/ffmpeg/libavcodec/libxvid_internal.h deleted file mode 100644 index ffa5cf8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libxvid_internal.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * copyright (C) 2006 Corey Hickey - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_LIBXVID_INTERNAL_H -#define AVCODEC_LIBXVID_INTERNAL_H - -/** - * @file - * common functions for use with the Xvid wrappers - */ - - -int av_tempfile(char *prefix, char **filename); - -#endif /* AVCODEC_LIBXVID_INTERNAL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/libxvid_rc.c b/tizen/distrib/ffmpeg/libavcodec/libxvid_rc.c deleted file mode 100644 index c161ba7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libxvid_rc.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Xvid rate control wrapper for lavc video encoders - * - * Copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "avcodec.h" -#include "libxvid_internal.h" -//#include "dsputil.h" -#include "mpegvideo.h" - -#undef NDEBUG -#include - -extern unsigned int xvid_debug; - -int ff_xvid_rate_control_init(MpegEncContext *s){ - char *tmp_name; - int fd, i; - xvid_plg_create_t xvid_plg_create; - xvid_plugin_2pass2_t xvid_2pass2; - -//xvid_debug=-1; - - fd=av_tempfile("xvidrc.", &tmp_name); - if (fd == -1) { - av_log(NULL, AV_LOG_ERROR, "Can't create temporary pass2 file.\n"); - return -1; - } - - for(i=0; irc_context.num_entries; i++){ - static const char *frame_types = " ipbs"; - char tmp[256]; - RateControlEntry *rce; - - rce= &s->rc_context.entry[i]; - - snprintf(tmp, sizeof(tmp), "%c %d %d %d %d %d %d\n", - frame_types[rce->pict_type], (int)lrintf(rce->qscale / FF_QP2LAMBDA), rce->i_count, s->mb_num - rce->i_count - rce->skip_count, - rce->skip_count, (rce->i_tex_bits + rce->p_tex_bits + rce->misc_bits+7)/8, (rce->header_bits+rce->mv_bits+7)/8); - -//av_log(NULL, AV_LOG_ERROR, "%s\n", tmp); - write(fd, tmp, strlen(tmp)); - } - - close(fd); - - memset(&xvid_2pass2, 0, sizeof(xvid_2pass2)); - xvid_2pass2.version= XVID_MAKE_VERSION(1,1,0); - xvid_2pass2.filename= tmp_name; - xvid_2pass2.bitrate= s->avctx->bit_rate; - xvid_2pass2.vbv_size= s->avctx->rc_buffer_size; - xvid_2pass2.vbv_maxrate= s->avctx->rc_max_rate; - xvid_2pass2.vbv_initial= s->avctx->rc_initial_buffer_occupancy; - - memset(&xvid_plg_create, 0, sizeof(xvid_plg_create)); - xvid_plg_create.version= XVID_MAKE_VERSION(1,1,0); - xvid_plg_create.fbase= s->avctx->time_base.den; - xvid_plg_create.fincr= s->avctx->time_base.num; - xvid_plg_create.param= &xvid_2pass2; - - if(xvid_plugin_2pass2(NULL, XVID_PLG_CREATE, &xvid_plg_create, &s->rc_context.non_lavc_opaque)<0){ - av_log(NULL, AV_LOG_ERROR, "xvid_plugin_2pass2 failed\n"); - return -1; - } - return 0; -} - -float ff_xvid_rate_estimate_qscale(MpegEncContext *s, int dry_run){ - xvid_plg_data_t xvid_plg_data; - - memset(&xvid_plg_data, 0, sizeof(xvid_plg_data)); - xvid_plg_data.version= XVID_MAKE_VERSION(1,1,0); - xvid_plg_data.width = s->width; - xvid_plg_data.height= s->height; - xvid_plg_data.mb_width = s->mb_width; - xvid_plg_data.mb_height= s->mb_height; - xvid_plg_data.fbase= s->avctx->time_base.den; - xvid_plg_data.fincr= s->avctx->time_base.num; - xvid_plg_data.min_quant[0]= s->avctx->qmin; - xvid_plg_data.min_quant[1]= s->avctx->qmin; - xvid_plg_data.min_quant[2]= s->avctx->qmin; //FIXME i/b factor & offset - xvid_plg_data.max_quant[0]= s->avctx->qmax; - xvid_plg_data.max_quant[1]= s->avctx->qmax; - xvid_plg_data.max_quant[2]= s->avctx->qmax; //FIXME i/b factor & offset - xvid_plg_data.bquant_offset = 0; // 100 * s->avctx->b_quant_offset; - xvid_plg_data.bquant_ratio = 100; // * s->avctx->b_quant_factor; - -#if 0 - xvid_plg_data.stats.hlength= X -#endif - - if(!s->rc_context.dry_run_qscale){ - if(s->picture_number){ - xvid_plg_data.length= - xvid_plg_data.stats.length= (s->frame_bits + 7)/8; - xvid_plg_data.frame_num= s->rc_context.last_picture_number; - xvid_plg_data.quant= s->qscale; - - xvid_plg_data.type= s->last_pict_type; - if(xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_AFTER, &xvid_plg_data, NULL)){ - av_log(s->avctx, AV_LOG_ERROR, "xvid_plugin_2pass2(handle, XVID_PLG_AFTER, ...) FAILED\n"); - return -1; - } - } - s->rc_context.last_picture_number= - xvid_plg_data.frame_num= s->picture_number; - xvid_plg_data.quant= 0; - if(xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_BEFORE, &xvid_plg_data, NULL)){ - av_log(s->avctx, AV_LOG_ERROR, "xvid_plugin_2pass2(handle, XVID_PLG_BEFORE, ...) FAILED\n"); - return -1; - } - s->rc_context.dry_run_qscale= xvid_plg_data.quant; - } - xvid_plg_data.quant= s->rc_context.dry_run_qscale; - if(!dry_run) - s->rc_context.dry_run_qscale= 0; - - if(s->pict_type == FF_B_TYPE) //FIXME this is not exactly identical to xvid - return xvid_plg_data.quant * FF_QP2LAMBDA * s->avctx->b_quant_factor + s->avctx->b_quant_offset; - else - return xvid_plg_data.quant * FF_QP2LAMBDA; -} - -void ff_xvid_rate_control_uninit(MpegEncContext *s){ - xvid_plg_destroy_t xvid_plg_destroy; - - xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_DESTROY, &xvid_plg_destroy, NULL); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/libxvidff.c b/tizen/distrib/ffmpeg/libavcodec/libxvidff.c deleted file mode 100644 index 2a404cd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/libxvidff.c +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Interface to xvidcore for mpeg4 encoding - * Copyright (c) 2004 Adam Thayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Interface to xvidcore for MPEG-4 compliant encoding. - * @author Adam Thayer (krevnik@comcast.net) - */ - -#include -#include -#include "avcodec.h" -#include "libavutil/intreadwrite.h" -#include "libxvid_internal.h" - -/** - * Buffer management macros. - */ -#define BUFFER_SIZE 1024 -#define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x)) -#define BUFFER_CAT(x) (&((x)[strlen(x)])) - -/* For PPC Use */ -int has_altivec(void); - -/** - * Structure for the private Xvid context. - * This stores all the private context for the codec. - */ -struct xvid_context { - void *encoder_handle; /** Handle for Xvid encoder */ - int xsize, ysize; /** Frame size */ - int vop_flags; /** VOP flags for Xvid encoder */ - int vol_flags; /** VOL flags for Xvid encoder */ - int me_flags; /** Motion Estimation flags */ - int qscale; /** Do we use constant scale? */ - int quicktime_format; /** Are we in a QT-based format? */ - AVFrame encoded_picture; /** Encoded frame information */ - char *twopassbuffer; /** Character buffer for two-pass */ - char *old_twopassbuffer; /** Old character buffer (two-pass) */ - char *twopassfile; /** second pass temp file name */ - unsigned char *intra_matrix; /** P-Frame Quant Matrix */ - unsigned char *inter_matrix; /** I-Frame Quant Matrix */ -}; - -/** - * Structure for the private first-pass plugin. - */ -struct xvid_ff_pass1 { - int version; /** Xvid version */ - struct xvid_context *context; /** Pointer to private context */ -}; - -/* Prototypes - See function implementation for details */ -int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len); -int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2); -void xvid_correct_framerate(AVCodecContext *avctx); - -/** - * Creates the private context for the encoder. - * All buffers are allocated, settings are loaded from the user, - * and the encoder context created. - * - * @param avctx AVCodecContext pointer to context - * @return Returns 0 on success, -1 on failure - */ -static av_cold int xvid_encode_init(AVCodecContext *avctx) { - int xerr, i; - int xvid_flags = avctx->flags; - struct xvid_context *x = avctx->priv_data; - uint16_t *intra, *inter; - int fd; - - xvid_plugin_single_t single; - struct xvid_ff_pass1 rc2pass1; - xvid_plugin_2pass2_t rc2pass2; - xvid_gbl_init_t xvid_gbl_init; - xvid_enc_create_t xvid_enc_create; - xvid_enc_plugin_t plugins[7]; - - /* Bring in VOP flags from ffmpeg command-line */ - x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ - if( xvid_flags & CODEC_FLAG_4MV ) - x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ - if( avctx->trellis - ) - x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */ - if( xvid_flags & CODEC_FLAG_AC_PRED ) - x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */ - if( xvid_flags & CODEC_FLAG_GRAY ) - x->vop_flags |= XVID_VOP_GREYSCALE; - - /* Decide which ME quality setting to use */ - x->me_flags = 0; - switch( avctx->me_method ) { - case ME_FULL: /* Quality 6 */ - x->me_flags |= XVID_ME_EXTSEARCH16 - | XVID_ME_EXTSEARCH8; - - case ME_EPZS: /* Quality 4 */ - x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 - | XVID_ME_HALFPELREFINE8 - | XVID_ME_CHROMA_PVOP - | XVID_ME_CHROMA_BVOP; - - case ME_LOG: /* Quality 2 */ - case ME_PHODS: - case ME_X1: - x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 - | XVID_ME_HALFPELREFINE16; - - case ME_ZERO: /* Quality 0 */ - default: - break; - } - - /* Decide how we should decide blocks */ - switch( avctx->mb_decision ) { - case 2: - x->vop_flags |= XVID_VOP_MODEDECISION_RD; - x->me_flags |= XVID_ME_HALFPELREFINE8_RD - | XVID_ME_QUARTERPELREFINE8_RD - | XVID_ME_EXTSEARCH_RD - | XVID_ME_CHECKPREDICTION_RD; - case 1: - if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) ) - x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD; - x->me_flags |= XVID_ME_HALFPELREFINE16_RD - | XVID_ME_QUARTERPELREFINE16_RD; - - default: - break; - } - - /* Bring in VOL flags from ffmpeg command-line */ - x->vol_flags = 0; - if( xvid_flags & CODEC_FLAG_GMC ) { - x->vol_flags |= XVID_VOL_GMC; - x->me_flags |= XVID_ME_GME_REFINE; - } - if( xvid_flags & CODEC_FLAG_QPEL ) { - x->vol_flags |= XVID_VOL_QUARTERPEL; - x->me_flags |= XVID_ME_QUARTERPELREFINE16; - if( x->vop_flags & XVID_VOP_INTER4V ) - x->me_flags |= XVID_ME_QUARTERPELREFINE8; - } - - memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init)); - xvid_gbl_init.version = XVID_VERSION; - xvid_gbl_init.debug = 0; - -#if ARCH_PPC - /* Xvid's PPC support is borked, use libavcodec to detect */ -#if HAVE_ALTIVEC - if( has_altivec() ) { - xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC; - } else -#endif - xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; -#else - /* Xvid can detect on x86 */ - xvid_gbl_init.cpu_flags = 0; -#endif - - /* Initialize */ - xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL); - - /* Create the encoder reference */ - memset(&xvid_enc_create, 0, sizeof(xvid_enc_create)); - xvid_enc_create.version = XVID_VERSION; - - /* Store the desired frame size */ - xvid_enc_create.width = x->xsize = avctx->width; - xvid_enc_create.height = x->ysize = avctx->height; - - /* Xvid can determine the proper profile to use */ - /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */ - - /* We don't use zones */ - xvid_enc_create.zones = NULL; - xvid_enc_create.num_zones = 0; - - xvid_enc_create.num_threads = avctx->thread_count; - - xvid_enc_create.plugins = plugins; - xvid_enc_create.num_plugins = 0; - - /* Initialize Buffers */ - x->twopassbuffer = NULL; - x->old_twopassbuffer = NULL; - x->twopassfile = NULL; - - if( xvid_flags & CODEC_FLAG_PASS1 ) { - memset(&rc2pass1, 0, sizeof(struct xvid_ff_pass1)); - rc2pass1.version = XVID_VERSION; - rc2pass1.context = x; - x->twopassbuffer = av_malloc(BUFFER_SIZE); - x->old_twopassbuffer = av_malloc(BUFFER_SIZE); - if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) { - av_log(avctx, AV_LOG_ERROR, - "Xvid: Cannot allocate 2-pass log buffers\n"); - return -1; - } - x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0; - - plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass; - plugins[xvid_enc_create.num_plugins].param = &rc2pass1; - xvid_enc_create.num_plugins++; - } else if( xvid_flags & CODEC_FLAG_PASS2 ) { - memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t)); - rc2pass2.version = XVID_VERSION; - rc2pass2.bitrate = avctx->bit_rate; - - fd = av_tempfile("xvidff.", &(x->twopassfile)); - if( fd == -1 ) { - av_log(avctx, AV_LOG_ERROR, - "Xvid: Cannot write 2-pass pipe\n"); - return -1; - } - - if( avctx->stats_in == NULL ) { - av_log(avctx, AV_LOG_ERROR, - "Xvid: No 2-pass information loaded for second pass\n"); - return -1; - } - - if( strlen(avctx->stats_in) > - write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) { - close(fd); - av_log(avctx, AV_LOG_ERROR, - "Xvid: Cannot write to 2-pass pipe\n"); - return -1; - } - - close(fd); - rc2pass2.filename = x->twopassfile; - plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2; - plugins[xvid_enc_create.num_plugins].param = &rc2pass2; - xvid_enc_create.num_plugins++; - } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) { - /* Single Pass Bitrate Control! */ - memset(&single, 0, sizeof(xvid_plugin_single_t)); - single.version = XVID_VERSION; - single.bitrate = avctx->bit_rate; - - plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single; - plugins[xvid_enc_create.num_plugins].param = &single; - xvid_enc_create.num_plugins++; - } - - /* Luminance Masking */ - if( 0.0 != avctx->lumi_masking ) { - plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking; - plugins[xvid_enc_create.num_plugins].param = NULL; - xvid_enc_create.num_plugins++; - } - - /* Frame Rate and Key Frames */ - xvid_correct_framerate(avctx); - xvid_enc_create.fincr = avctx->time_base.num; - xvid_enc_create.fbase = avctx->time_base.den; - if( avctx->gop_size > 0 ) - xvid_enc_create.max_key_interval = avctx->gop_size; - else - xvid_enc_create.max_key_interval = 240; /* Xvid's best default */ - - /* Quants */ - if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1; - else x->qscale = 0; - - xvid_enc_create.min_quant[0] = avctx->qmin; - xvid_enc_create.min_quant[1] = avctx->qmin; - xvid_enc_create.min_quant[2] = avctx->qmin; - xvid_enc_create.max_quant[0] = avctx->qmax; - xvid_enc_create.max_quant[1] = avctx->qmax; - xvid_enc_create.max_quant[2] = avctx->qmax; - - /* Quant Matrices */ - x->intra_matrix = x->inter_matrix = NULL; - if( avctx->mpeg_quant ) - x->vol_flags |= XVID_VOL_MPEGQUANT; - if( (avctx->intra_matrix || avctx->inter_matrix) ) { - x->vol_flags |= XVID_VOL_MPEGQUANT; - - if( avctx->intra_matrix ) { - intra = avctx->intra_matrix; - x->intra_matrix = av_malloc(sizeof(unsigned char) * 64); - } else - intra = NULL; - if( avctx->inter_matrix ) { - inter = avctx->inter_matrix; - x->inter_matrix = av_malloc(sizeof(unsigned char) * 64); - } else - inter = NULL; - - for( i = 0; i < 64; i++ ) { - if( intra ) - x->intra_matrix[i] = (unsigned char)intra[i]; - if( inter ) - x->inter_matrix[i] = (unsigned char)inter[i]; - } - } - - /* Misc Settings */ - xvid_enc_create.frame_drop_ratio = 0; - xvid_enc_create.global = 0; - if( xvid_flags & CODEC_FLAG_CLOSED_GOP ) - xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP; - - /* Determines which codec mode we are operating in */ - avctx->extradata = NULL; - avctx->extradata_size = 0; - if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) { - /* In this case, we are claiming to be MPEG4 */ - x->quicktime_format = 1; - avctx->codec_id = CODEC_ID_MPEG4; - } else { - /* We are claiming to be Xvid */ - x->quicktime_format = 0; - if(!avctx->codec_tag) - avctx->codec_tag = AV_RL32("xvid"); - } - - /* Bframes */ - xvid_enc_create.max_bframes = avctx->max_b_frames; - xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset; - xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor; - if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED; - - /* Create encoder context */ - xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); - if( xerr ) { - av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); - return -1; - } - - x->encoder_handle = xvid_enc_create.handle; - avctx->coded_frame = &x->encoded_picture; - - return 0; -} - -/** - * Encodes a single frame. - * - * @param avctx AVCodecContext pointer to context - * @param frame Pointer to encoded frame buffer - * @param buf_size Size of encoded frame buffer - * @param data Pointer to AVFrame of unencoded frame - * @return Returns 0 on success, -1 on failure - */ -static int xvid_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) { - int xerr, i; - char *tmp; - struct xvid_context *x = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p = &(x->encoded_picture); - - xvid_enc_frame_t xvid_enc_frame; - xvid_enc_stats_t xvid_enc_stats; - - /* Start setting up the frame */ - memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame)); - xvid_enc_frame.version = XVID_VERSION; - memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats)); - xvid_enc_stats.version = XVID_VERSION; - *p = *picture; - - /* Let Xvid know where to put the frame. */ - xvid_enc_frame.bitstream = frame; - xvid_enc_frame.length = buf_size; - - /* Initialize input image fields */ - if( avctx->pix_fmt != PIX_FMT_YUV420P ) { - av_log(avctx, AV_LOG_ERROR, "Xvid: Color spaces other than 420p not supported\n"); - return -1; - } - - xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */ - - for( i = 0; i < 4; i++ ) { - xvid_enc_frame.input.plane[i] = picture->data[i]; - xvid_enc_frame.input.stride[i] = picture->linesize[i]; - } - - /* Encoder Flags */ - xvid_enc_frame.vop_flags = x->vop_flags; - xvid_enc_frame.vol_flags = x->vol_flags; - xvid_enc_frame.motion = x->me_flags; - xvid_enc_frame.type = XVID_TYPE_AUTO; - - /* Pixel aspect ratio setting */ - if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 || - avctx->sample_aspect_ratio.den < 1 || avctx->sample_aspect_ratio.den > 255) { - av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n", - avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); - return -1; - } - xvid_enc_frame.par = XVID_PAR_EXT; - xvid_enc_frame.par_width = avctx->sample_aspect_ratio.num; - xvid_enc_frame.par_height = avctx->sample_aspect_ratio.den; - - /* Quant Setting */ - if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA; - else xvid_enc_frame.quant = 0; - - /* Matrices */ - xvid_enc_frame.quant_intra_matrix = x->intra_matrix; - xvid_enc_frame.quant_inter_matrix = x->inter_matrix; - - /* Encode */ - xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE, - &xvid_enc_frame, &xvid_enc_stats); - - /* Two-pass log buffer swapping */ - avctx->stats_out = NULL; - if( x->twopassbuffer ) { - tmp = x->old_twopassbuffer; - x->old_twopassbuffer = x->twopassbuffer; - x->twopassbuffer = tmp; - x->twopassbuffer[0] = 0; - if( x->old_twopassbuffer[0] != 0 ) { - avctx->stats_out = x->old_twopassbuffer; - } - } - - if( 0 <= xerr ) { - p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA; - if( xvid_enc_stats.type == XVID_TYPE_PVOP ) - p->pict_type = FF_P_TYPE; - else if( xvid_enc_stats.type == XVID_TYPE_BVOP ) - p->pict_type = FF_B_TYPE; - else if( xvid_enc_stats.type == XVID_TYPE_SVOP ) - p->pict_type = FF_S_TYPE; - else - p->pict_type = FF_I_TYPE; - if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) { - p->key_frame = 1; - if( x->quicktime_format ) - return xvid_strip_vol_header(avctx, frame, - xvid_enc_stats.hlength, xerr); - } else - p->key_frame = 0; - - return xerr; - } else { - av_log(avctx, AV_LOG_ERROR, "Xvid: Encoding Error Occurred: %i\n", xerr); - return -1; - } -} - -/** - * Destroys the private context for the encoder. - * All buffers are freed, and the Xvid encoder context is destroyed. - * - * @param avctx AVCodecContext pointer to context - * @return Returns 0, success guaranteed - */ -static av_cold int xvid_encode_close(AVCodecContext *avctx) { - struct xvid_context *x = avctx->priv_data; - - xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); - - if( avctx->extradata != NULL ) - av_freep(&avctx->extradata); - if( x->twopassbuffer != NULL ) { - av_free(x->twopassbuffer); - av_free(x->old_twopassbuffer); - } - if( x->twopassfile != NULL ) - av_free(x->twopassfile); - if( x->intra_matrix != NULL ) - av_free(x->intra_matrix); - if( x->inter_matrix != NULL ) - av_free(x->inter_matrix); - - return 0; -} - -/** - * Routine to create a global VO/VOL header for MP4 container. - * What we do here is extract the header from the Xvid bitstream - * as it is encoded. We also strip the repeated headers from the - * bitstream when a global header is requested for MPEG-4 ISO - * compliance. - * - * @param avctx AVCodecContext pointer to context - * @param frame Pointer to encoded frame data - * @param header_len Length of header to search - * @param frame_len Length of encoded frame data - * @return Returns new length of frame data - */ -int xvid_strip_vol_header(AVCodecContext *avctx, - unsigned char *frame, - unsigned int header_len, - unsigned int frame_len) { - int vo_len = 0, i; - - for( i = 0; i < header_len - 3; i++ ) { - if( frame[i] == 0x00 && - frame[i+1] == 0x00 && - frame[i+2] == 0x01 && - frame[i+3] == 0xB6 ) { - vo_len = i; - break; - } - } - - if( vo_len > 0 ) { - /* We need to store the header, so extract it */ - if( avctx->extradata == NULL ) { - avctx->extradata = av_malloc(vo_len); - memcpy(avctx->extradata, frame, vo_len); - avctx->extradata_size = vo_len; - } - /* Less dangerous now, memmove properly copies the two - chunks of overlapping data */ - memmove(frame, &(frame[vo_len]), frame_len - vo_len); - return frame_len - vo_len; - } else - return frame_len; -} - -/** - * Routine to correct a possibly erroneous framerate being fed to us. - * Xvid currently chokes on framerates where the ticks per frame is - * extremely large. This function works to correct problems in this area - * by estimating a new framerate and taking the simpler fraction of - * the two presented. - * - * @param avctx Context that contains the framerate to correct. - */ -void xvid_correct_framerate(AVCodecContext *avctx) { - int frate, fbase; - int est_frate, est_fbase; - int gcd; - float est_fps, fps; - - frate = avctx->time_base.den; - fbase = avctx->time_base.num; - - gcd = av_gcd(frate, fbase); - if( gcd > 1 ) { - frate /= gcd; - fbase /= gcd; - } - - if( frate <= 65000 && fbase <= 65000 ) { - avctx->time_base.den = frate; - avctx->time_base.num = fbase; - return; - } - - fps = (float)frate / (float)fbase; - est_fps = roundf(fps * 1000.0) / 1000.0; - - est_frate = (int)est_fps; - if( est_fps > (int)est_fps ) { - est_frate = (est_frate + 1) * 1000; - est_fbase = (int)roundf((float)est_frate / est_fps); - } else - est_fbase = 1; - - gcd = av_gcd(est_frate, est_fbase); - if( gcd > 1 ) { - est_frate /= gcd; - est_fbase /= gcd; - } - - if( fbase > est_fbase ) { - avctx->time_base.den = est_frate; - avctx->time_base.num = est_fbase; - av_log(avctx, AV_LOG_DEBUG, - "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n", - est_fps, (((est_fps - fps)/fps) * 100.0)); - } else { - avctx->time_base.den = frate; - avctx->time_base.num = fbase; - } -} - -/* - * Xvid 2-Pass Kludge Section - * - * Xvid's default 2-pass doesn't allow us to create data as we need to, so - * this section spends time replacing the first pass plugin so we can write - * statistic information as libavcodec requests in. We have another kludge - * that allows us to pass data to the second pass in Xvid without a custom - * rate-control plugin. - */ - -/** - * Initializes the two-pass plugin and context. - * - * @param param Input construction parameter structure - * @param handle Private context handle - * @return Returns XVID_ERR_xxxx on failure, or 0 on success. - */ -static int xvid_ff_2pass_create(xvid_plg_create_t * param, - void ** handle) { - struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *)param->param; - char *log = x->context->twopassbuffer; - - /* Do a quick bounds check */ - if( log == NULL ) - return XVID_ERR_FAIL; - - /* We use snprintf() */ - /* This is because we can safely prevent a buffer overflow */ - log[0] = 0; - snprintf(log, BUFFER_REMAINING(log), - "# ffmpeg 2-pass log file, using xvid codec\n"); - snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), - "# Do not modify. libxvidcore version: %d.%d.%d\n\n", - XVID_VERSION_MAJOR(XVID_VERSION), - XVID_VERSION_MINOR(XVID_VERSION), - XVID_VERSION_PATCH(XVID_VERSION)); - - *handle = x->context; - return 0; -} - -/** - * Destroys the two-pass plugin context. - * - * @param ref Context pointer for the plugin - * @param param Destrooy context - * @return Returns 0, success guaranteed - */ -static int xvid_ff_2pass_destroy(struct xvid_context *ref, - xvid_plg_destroy_t *param) { - /* Currently cannot think of anything to do on destruction */ - /* Still, the framework should be here for reference/use */ - if( ref->twopassbuffer != NULL ) - ref->twopassbuffer[0] = 0; - return 0; -} - -/** - * Enables fast encode mode during the first pass. - * - * @param ref Context pointer for the plugin - * @param param Frame data - * @return Returns 0, success guaranteed - */ -static int xvid_ff_2pass_before(struct xvid_context *ref, - xvid_plg_data_t *param) { - int motion_remove; - int motion_replacements; - int vop_remove; - - /* Nothing to do here, result is changed too much */ - if( param->zone && param->zone->mode == XVID_ZONE_QUANT ) - return 0; - - /* We can implement a 'turbo' first pass mode here */ - param->quant = 2; - - /* Init values */ - motion_remove = ~XVID_ME_CHROMA_PVOP & - ~XVID_ME_CHROMA_BVOP & - ~XVID_ME_EXTSEARCH16 & - ~XVID_ME_ADVANCEDDIAMOND16; - motion_replacements = XVID_ME_FAST_MODEINTERPOLATE | - XVID_ME_SKIP_DELTASEARCH | - XVID_ME_FASTREFINE16 | - XVID_ME_BFRAME_EARLYSTOP; - vop_remove = ~XVID_VOP_MODEDECISION_RD & - ~XVID_VOP_FAST_MODEDECISION_RD & - ~XVID_VOP_TRELLISQUANT & - ~XVID_VOP_INTER4V & - ~XVID_VOP_HQACPRED; - - param->vol_flags &= ~XVID_VOL_GMC; - param->vop_flags &= vop_remove; - param->motion_flags &= motion_remove; - param->motion_flags |= motion_replacements; - - return 0; -} - -/** - * Captures statistic data and writes it during first pass. - * - * @param ref Context pointer for the plugin - * @param param Statistic data - * @return Returns XVID_ERR_xxxx on failure, or 0 on success - */ -static int xvid_ff_2pass_after(struct xvid_context *ref, - xvid_plg_data_t *param) { - char *log = ref->twopassbuffer; - char *frame_types = " ipbs"; - char frame_type; - - /* Quick bounds check */ - if( log == NULL ) - return XVID_ERR_FAIL; - - /* Convert the type given to us into a character */ - if( param->type < 5 && param->type > 0 ) { - frame_type = frame_types[param->type]; - } else { - return XVID_ERR_FAIL; - } - - snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), - "%c %d %d %d %d %d %d\n", - frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks, - param->stats.ublks, param->stats.length, param->stats.hlength); - - return 0; -} - -/** - * Dispatch function for our custom plugin. - * This handles the dispatch for the Xvid plugin. It passes data - * on to other functions for actual processing. - * - * @param ref Context pointer for the plugin - * @param cmd The task given for us to complete - * @param p1 First parameter (varies) - * @param p2 Second parameter (varies) - * @return Returns XVID_ERR_xxxx on failure, or 0 on success - */ -int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) { - switch( cmd ) { - case XVID_PLG_INFO: - case XVID_PLG_FRAME: - return 0; - - case XVID_PLG_BEFORE: - return xvid_ff_2pass_before(ref, p1); - - case XVID_PLG_CREATE: - return xvid_ff_2pass_create(p1, p2); - - case XVID_PLG_AFTER: - return xvid_ff_2pass_after(ref, p1); - - case XVID_PLG_DESTROY: - return xvid_ff_2pass_destroy(ref, p1); - - default: - return XVID_ERR_FAIL; - } -} - -/** - * Xvid codec definition for libavcodec. - */ -AVCodec libxvid_encoder = { - "libxvid", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(struct xvid_context), - xvid_encode_init, - xvid_encode_frame, - xvid_encode_close, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ljpegenc.c b/tizen/distrib/ffmpeg/libavcodec/ljpegenc.c deleted file mode 100644 index 2ef07c3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ljpegenc.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * lossless JPEG encoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer - * - * Support for external huffman table, various fixes (AVID workaround), - * aspecting, new decode_frame mechanism and apple mjpeg-b support - * by Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * lossless JPEG encoder. - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mjpeg.h" -#include "mjpegenc.h" - - -static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - MpegEncContext * const s = avctx->priv_data; - MJpegContext * const m = s->mjpeg_ctx; - AVFrame *pict = data; - const int width= s->width; - const int height= s->height; - AVFrame * const p= (AVFrame*)&s->current_picture; - const int predictor= avctx->prediction_method+1; - - init_put_bits(&s->pb, buf, buf_size); - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - ff_mjpeg_encode_picture_header(s); - - s->header_bits= put_bits_count(&s->pb); - - if(avctx->pix_fmt == PIX_FMT_BGRA){ - int x, y, i; - const int linesize= p->linesize[0]; - uint16_t (*buffer)[4]= (void *) s->rd_scratchpad; - int left[3], top[3], topleft[3]; - - for(i=0; i<3; i++){ - buffer[0][i]= 1 << (9 - 1); - } - - for(y = 0; y < height; y++) { - const int modified_predictor= y ? predictor : 1; - uint8_t *ptr = p->data[0] + (linesize * y); - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - for(i=0; i<3; i++){ - top[i]= left[i]= topleft[i]= buffer[0][i]; - } - for(x = 0; x < width; x++) { - buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100; - buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100; - buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2; - - for(i=0;i<3;i++) { - int pred, diff; - - PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); - - topleft[i]= top[i]; - top[i]= buffer[x+1][i]; - - left[i]= buffer[x][i]; - - diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100; - - if(i==0) - ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } - }else{ - int mb_x, mb_y, i; - const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0]; - const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0]; - - for(mb_y = 0; mb_y < mb_height; mb_y++) { - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - for(mb_x = 0; mb_x < mb_width; mb_x++) { - if(mb_x==0 || mb_y==0){ - for(i=0;i<3;i++) { - uint8_t *ptr; - int x, y, h, v, linesize; - h = s->mjpeg_hsample[i]; - v = s->mjpeg_vsample[i]; - linesize= p->linesize[i]; - - for(y=0; ydata[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - if(y==0 && mb_y==0){ - if(x==0 && mb_x==0){ - pred= 128; - }else{ - pred= ptr[-1]; - } - }else{ - if(x==0 && mb_x==0){ - pred= ptr[-linesize]; - }else{ - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - } - } - - if(i==0) - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } - }else{ - for(i=0;i<3;i++) { - uint8_t *ptr; - int x, y, h, v, linesize; - h = s->mjpeg_hsample[i]; - v = s->mjpeg_vsample[i]; - linesize= p->linesize[i]; - - for(y=0; ydata[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap -//printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr); - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - - if(i==0) - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } - } - } - } - } - - emms_c(); - - ff_mjpeg_encode_picture_trailer(s); - s->picture_number++; - - flush_put_bits(&s->pb); - return put_bits_ptr(&s->pb) - s->pb.buf; -// return (put_bits_count(&f->pb)+7)/8; -} - - -AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them - "ljpeg", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_LJPEG, - sizeof(MpegEncContext), - MPV_encode_init, - encode_picture_lossless, - MPV_encode_end, - .long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/loco.c b/tizen/distrib/ffmpeg/libavcodec/loco.c deleted file mode 100644 index d19a80c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/loco.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * LOCO codec - * Copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * LOCO codec. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "golomb.h" -#include "mathops.h" - -enum LOCO_MODE {LOCO_UNKN=0, LOCO_CYUY2=-1, LOCO_CRGB=-2, LOCO_CRGBA=-3, LOCO_CYV12=-4, - LOCO_YUY2=1, LOCO_UYVY=2, LOCO_RGB=3, LOCO_RGBA=4, LOCO_YV12=5}; - -typedef struct LOCOContext{ - AVCodecContext *avctx; - AVFrame pic; - int lossy; - int mode; -} LOCOContext; - -typedef struct RICEContext{ - GetBitContext gb; - int save, run, run2; /* internal rice decoder state */ - int sum, count; /* sum and count for getting rice parameter */ - int lossy; -}RICEContext; - -static int loco_get_rice_param(RICEContext *r) -{ - int cnt = 0; - int val = r->count; - - while(r->sum > val && cnt < 9) { - val <<= 1; - cnt++; - } - - return cnt; -} - -static inline void loco_update_rice_param(RICEContext *r, int val) -{ - r->sum += val; - r->count++; - - if(r->count == 16) { - r->sum >>= 1; - r->count >>= 1; - } -} - -static inline int loco_get_rice(RICEContext *r) -{ - int v; - if (r->run > 0) { /* we have zero run */ - r->run--; - loco_update_rice_param(r, 0); - return 0; - } - v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0); - loco_update_rice_param(r, (v+1)>>1); - if (!v) { - if (r->save >= 0) { - r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0); - if(r->run > 1) - r->save += r->run + 1; - else - r->save -= 3; - } - else - r->run2++; - } else { - v = ((v>>1) + r->lossy) ^ -(v&1); - if (r->run2 > 0) { - if (r->run2 > 2) - r->save += r->run2; - else - r->save -= 3; - r->run2 = 0; - } - } - - return v; -} - -/* LOCO main predictor - LOCO-I/JPEG-LS predictor */ -static inline int loco_predict(uint8_t* data, int stride, int step) -{ - int a, b, c; - - a = data[-stride]; - b = data[-step]; - c = data[-stride - step]; - - return mid_pred(a, a + b - c, b); -} - -static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int height, - int stride, const uint8_t *buf, int buf_size, int step) -{ - RICEContext rc; - int val; - int i, j; - - init_get_bits(&rc.gb, buf, buf_size*8); - rc.save = 0; - rc.run = 0; - rc.run2 = 0; - rc.lossy = l->lossy; - - rc.sum = 8; - rc.count = 1; - - /* restore top left pixel */ - val = loco_get_rice(&rc); - data[0] = 128 + val; - /* restore top line */ - for (i = 1; i < width; i++) { - val = loco_get_rice(&rc); - data[i * step] = data[i * step - step] + val; - } - data += stride; - for (j = 1; j < height; j++) { - /* restore left column */ - val = loco_get_rice(&rc); - data[0] = data[-stride] + val; - /* restore all other pixels */ - for (i = 1; i < width; i++) { - val = loco_get_rice(&rc); - data[i * step] = loco_predict(&data[i * step], stride, step) + val; - } - data += stride; - } - - return (get_bits_count(&rc.gb) + 7) >> 3; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - LOCOContext * const l = avctx->priv_data; - AVFrame * const p= (AVFrame*)&l->pic; - int decoded; - - 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->key_frame = 1; - - switch(l->mode) { - case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: - decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 1); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height, - p->linesize[1], buf, buf_size, 1); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height, - p->linesize[2], buf, buf_size, 1); - break; - case LOCO_CYV12: case LOCO_YV12: - decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 1); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2, - p->linesize[2], buf, buf_size, 1); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2, - p->linesize[1], buf, buf_size, 1); - break; - case LOCO_CRGB: case LOCO_RGB: - decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, - -p->linesize[0], buf, buf_size, 3); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height, - -p->linesize[0], buf, buf_size, 3); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height, - -p->linesize[0], buf, buf_size, 3); - break; - case LOCO_RGBA: - decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[0] + 1, avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[0] + 2, avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); - buf += decoded; buf_size -= decoded; - decoded = loco_decode_plane(l, p->data[0] + 3, avctx->width, avctx->height, - p->linesize[0], buf, buf_size, 4); - break; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = l->pic; - - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - LOCOContext * const l = avctx->priv_data; - int version; - - l->avctx = avctx; - if (avctx->extradata_size < 12) { - av_log(avctx, AV_LOG_ERROR, "Extradata size must be >= 12 instead of %i\n", - avctx->extradata_size); - return -1; - } - version = AV_RL32(avctx->extradata); - switch(version) { - case 1: - l->lossy = 0; - break; - case 2: - l->lossy = AV_RL32(avctx->extradata + 8); - break; - default: - l->lossy = AV_RL32(avctx->extradata + 8); - av_log(avctx, AV_LOG_INFO, "This is LOCO codec version %i, please upload file for study\n", version); - } - - l->mode = AV_RL32(avctx->extradata + 4); - switch(l->mode) { - case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: - avctx->pix_fmt = PIX_FMT_YUV422P; - break; - case LOCO_CRGB: case LOCO_RGB: - avctx->pix_fmt = PIX_FMT_BGR24; - break; - case LOCO_CYV12: case LOCO_YV12: - avctx->pix_fmt = PIX_FMT_YUV420P; - break; - case LOCO_CRGBA: case LOCO_RGBA: - avctx->pix_fmt = PIX_FMT_RGB32; - break; - default: - av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode); - return -1; - } - if(avctx->debug & FF_DEBUG_PICT_INFO) - av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode); - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - LOCOContext * const l = avctx->priv_data; - AVFrame *pic = &l->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - -AVCodec loco_decoder = { - "loco", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_LOCO, - sizeof(LOCOContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("LOCO"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/lpc.c b/tizen/distrib/ffmpeg/libavcodec/lpc.c deleted file mode 100644 index 49e41d8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lpc.c +++ /dev/null @@ -1,236 +0,0 @@ -/** - * LPC utility code - * Copyright (c) 2006 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/lls.h" -#include "dsputil.h" - -#define LPC_USE_DOUBLE -#include "lpc.h" - - -/** - * Apply Welch window function to audio block - */ -static void apply_welch_window(const int32_t *data, int len, double *w_data) -{ - int i, n2; - double w; - double c; - - assert(!(len&1)); //the optimization in r11881 does not support odd len - //if someone wants odd len extend the change in r11881 - - n2 = (len >> 1); - c = 2.0 / (len - 1.0); - - w_data+=n2; - data+=n2; - for(i=0; i qmax) && (sh > 0)) { - sh--; - } - - /* since negative shift values are unsupported in decoder, scale down - coefficients instead */ - if(sh == 0 && cmax > qmax) { - double scale = ((double)qmax) / cmax; - for(i=0; i=min_order-1; i--) { - if(ref[i] > 0.10) { - est = i+1; - break; - } - } - return est; -} - -/** - * Calculate LPC coefficients for multiple orders - * - * @param use_lpc LPC method for determining coefficients - * 0 = LPC with fixed pre-defined coeffs - * 1 = LPC with coeffs determined by Levinson-Durbin recursion - * 2+ = LPC with coeffs determined by Cholesky factorization using (use_lpc-1) passes. - */ -int ff_lpc_calc_coefs(DSPContext *s, - const int32_t *samples, int blocksize, int min_order, - int max_order, int precision, - int32_t coefs[][MAX_LPC_ORDER], int *shift, int use_lpc, - int omethod, int max_shift, int zero_shift) -{ - double autoc[MAX_LPC_ORDER+1]; - double ref[MAX_LPC_ORDER]; - double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; - int i, j, pass; - int opt_order; - - assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && use_lpc > 0); - - if(use_lpc == 1){ - s->lpc_compute_autocorr(samples, blocksize, max_order, autoc); - - compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1); - - for(i=0; i>pass) + fabs(eval - var[0]); - inv = 1/eval; - rinv = sqrt(inv); - for(j=0; j<=max_order; j++) - var[j] *= rinv; - weight += inv; - }else - weight++; - - av_update_lls(&m[pass&1], var, 1.0); - } - av_solve_lls(&m[pass&1], 0.001, 0); - } - - for(i=0; i0; i--) - ref[i] = ref[i-1] - ref[i]; - } - opt_order = max_order; - - if(omethod == ORDER_METHOD_EST) { - opt_order = estimate_best_order(ref, min_order, max_order); - i = opt_order-1; - quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); - } else { - for(i=min_order-1; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_LPC_H -#define AVCODEC_LPC_H - -#include -#include "dsputil.h" - -#define ORDER_METHOD_EST 0 -#define ORDER_METHOD_2LEVEL 1 -#define ORDER_METHOD_4LEVEL 2 -#define ORDER_METHOD_8LEVEL 3 -#define ORDER_METHOD_SEARCH 4 -#define ORDER_METHOD_LOG 5 - -#define MIN_LPC_ORDER 1 -#define MAX_LPC_ORDER 32 - - -/** - * Calculate LPC coefficients for multiple orders - */ -int ff_lpc_calc_coefs(DSPContext *s, - const int32_t *samples, int blocksize, int min_order, - int max_order, int precision, - int32_t coefs[][MAX_LPC_ORDER], int *shift, int use_lpc, - int omethod, int max_shift, int zero_shift); - -void ff_lpc_compute_autocorr(const int32_t *data, int len, int lag, - double *autoc); - -#ifdef LPC_USE_DOUBLE -#define LPC_TYPE double -#else -#define LPC_TYPE float -#endif - -/** - * Levinson-Durbin recursion. - * Produces LPC coefficients from autocorrelation data. - */ -static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order, - LPC_TYPE *lpc, int lpc_stride, int fail, - int normalize) -{ - int i, j; - LPC_TYPE err; - LPC_TYPE *lpc_last = lpc; - - if (normalize) - err = *autoc++; - - if (fail && (autoc[max_order - 1] == 0 || err <= 0)) - return -1; - - for(i=0; i>1; j++) { - LPC_TYPE f = lpc_last[ j]; - LPC_TYPE b = lpc_last[i-1-j]; - lpc[ j] = f + r * b; - lpc[i-1-j] = b + r * f; - } - - if (fail && err < 0) - return -1; - - lpc_last = lpc; - lpc += lpc_stride; - } - - return 0; -} - -#endif /* AVCODEC_LPC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/lsp.c b/tizen/distrib/ffmpeg/libavcodec/lsp.c deleted file mode 100644 index 003ffbc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lsp.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * LSP routines for ACELP-based codecs - * - * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet (QCELP decoder) - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "avcodec.h" -#define FRAC_BITS 14 -#include "mathops.h" -#include "lsp.h" -#include "celp_math.h" - -void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order) -{ - int i, j; - - /* sort lsfq in ascending order. float bubble agorithm, - O(n) if data already sorted, O(n^2) - otherwise */ - for(i=0; i=0 && lsfq[j] > lsfq[j+1]; j--) - FFSWAP(int16_t, lsfq[j], lsfq[j+1]); - - for(i=0; i> 15); // divide by PI and (0,13) -> (0,14) -} - -/** - * \brief decodes polynomial coefficients from LSP - * \param f [out] decoded polynomial coefficients (-0x20000000 <= (3.22) <= 0x1fffffff) - * \param lsp LSP coefficients (-0x8000 <= (0.15) <= 0x7fff) - */ -static void lsp2poly(int* f, const int16_t* lsp, int lp_half_order) -{ - int i, j; - - f[0] = 0x400000; // 1.0 in (3.22) - f[1] = -lsp[0] << 8; // *2 and (0.15) -> (3.22) - - for(i=2; i<=lp_half_order; i++) - { - f[i] = f[i-2]; - for(j=i; j>1; j--) - f[j] -= MULL(f[j-1], lsp[2*i-2], FRAC_BITS) - f[j-2]; - - f[1] -= lsp[2*i-2] << 8; - } -} - -void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order) -{ - int i; - int f1[lp_half_order+1]; // (3.22) - int f2[lp_half_order+1]; // (3.22) - - lsp2poly(f1, lsp , lp_half_order); - lsp2poly(f2, lsp+1, lp_half_order); - - /* 3.2.6 of G.729, Equations 25 and 26*/ - lp[0] = 4096; - for(i=1; i> 11; // divide by 2 and (3.22) -> (3.12) - lp[(lp_half_order << 1) + 1 - i] = (ff1 - ff2) >> 11; // divide by 2 and (3.22) -> (3.12) - } -} - -void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order) -{ - int16_t lsp_1st[lp_order]; // (0.15) - int i; - - /* LSP values for first subframe (3.2.5 of G.729, Equation 24)*/ - for(i=0; i> 1) + (lsp_prev[i] >> 1); -#else - lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) >> 1; -#endif - - ff_acelp_lsp2lpc(lp_1st, lsp_1st, lp_order >> 1); - - /* LSP values for second subframe (3.2.5 of G.729)*/ - ff_acelp_lsp2lpc(lp_2nd, lsp_2nd, lp_order >> 1); -} - -void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order) -{ - int i, j; - - f[0] = 1.0; - f[1] = -2 * lsp[0]; - lsp -= 2; - for(i=2; i<=lp_half_order; i++) - { - double val = -2 * lsp[2*i]; - f[i] = val * f[i-1] + 2*f[i-2]; - for(j=i-1; j>1; j--) - f[j] += f[j-1] * val + f[j-2]; - f[1] += val; - } -} - -void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order) -{ - double pa[MAX_LP_HALF_ORDER+1], qa[MAX_LP_HALF_ORDER+1]; - float *lpc2 = lpc + (lp_half_order << 1) - 1; - - assert(lp_half_order <= MAX_LP_HALF_ORDER); - - ff_lsp2polyf(lsp, pa, lp_half_order); - ff_lsp2polyf(lsp + 1, qa, lp_half_order); - - while (lp_half_order--) { - double paf = pa[lp_half_order+1] + pa[lp_half_order]; - double qaf = qa[lp_half_order+1] - qa[lp_half_order]; - - lpc [ lp_half_order] = 0.5*(paf+qaf); - lpc2[-lp_half_order] = 0.5*(paf-qaf); - } -} - -void ff_sort_nearly_sorted_floats(float *vals, int len) -{ - int i,j; - - for (i = 0; i < len - 1; i++) - for (j = i; j >= 0 && vals[j] > vals[j+1]; j--) - FFSWAP(float, vals[j], vals[j+1]); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/lsp.h b/tizen/distrib/ffmpeg/libavcodec/lsp.h deleted file mode 100644 index c3aee7b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lsp.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * LSP computing for ACELP-based codecs - * - * Copyright (c) 2008 Vladimir Voroshilov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_LSP_H -#define AVCODEC_LSP_H - -#include - -/** - (I.F) means fixed-point value with F fractional and I integer bits -*/ - -/** - * \brief ensure a minimum distance between LSFs - * \param lsfq [in/out] LSF to check and adjust - * \param lsfq_min_distance minimum distance between LSFs - * \param lsfq_min minimum allowed LSF value - * \param lsfq_max maximum allowed LSF value - * \param lp_order LP filter order - */ -void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order); - -/** - * Adjust the quantized LSFs so they are increasing and not too close. - * - * This step is not mentioned in the AMR spec but is in the reference C decoder. - * Omitting this step creates audible distortion on the sinusoidal sweep - * test vectors in 3GPP TS 26.074. - * - * @param[in,out] lsf LSFs in Hertz - * @param min_spacing minimum distance between two consecutive lsf values - * @param size size of the lsf vector - */ -void ff_set_min_dist_lsf(float *lsf, double min_spacing, int order); - -/** - * \brief Convert LSF to LSP - * \param lsp [out] LSP coefficients (-0x8000 <= (0.15) < 0x8000) - * \param lsf normalized LSF coefficients (0 <= (2.13) < 0x2000 * PI) - * \param lp_order LP filter order - * - * \remark It is safe to pass the same array into the lsf and lsp parameters. - */ -void ff_acelp_lsf2lsp(int16_t *lsp, const int16_t *lsf, int lp_order); - -/** - * \brief LSP to LP conversion (3.2.6 of G.729) - * \param lp [out] decoded LP coefficients (-0x8000 <= (3.12) < 0x8000) - * \param lsp LSP coefficients (-0x8000 <= (0.15) < 0x8000) - * \param lp_half_order LP filter order, divided by 2 - */ -void ff_acelp_lsp2lpc(int16_t* lp, const int16_t* lsp, int lp_half_order); - -/** - * \brief Interpolate LSP for the first subframe and convert LSP -> LP for both subframes (3.2.5 and 3.2.6 of G.729) - * \param lp_1st [out] decoded LP coefficients for first subframe (-0x8000 <= (3.12) < 0x8000) - * \param lp_2nd [out] decoded LP coefficients for second subframe (-0x8000 <= (3.12) < 0x8000) - * \param lsp_2nd LSP coefficients of the second subframe (-0x8000 <= (0.15) < 0x8000) - * \param lsp_prev LSP coefficients from the second subframe of the previous frame (-0x8000 <= (0.15) < 0x8000) - * \param lp_order LP filter order - */ -void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd, const int16_t* lsp_prev, int lp_order); - - -#define MAX_LP_HALF_ORDER 8 - -/** - * Reconstructs LPC coefficients from the line spectral pair frequencies. - * - * @param lsp line spectral pairs in cosine domain - * @param lpc linear predictive coding coefficients - * @param lp_half_order half the number of the amount of LPCs to be - * reconstructed, need to be smaller or equal to MAX_LP_HALF_ORDER - * - * @note buffers should have a minimux size of 2*lp_half_order elements. - * - * TIA/EIA/IS-733 2.4.3.3.5 - */ -void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order); - -/** - * Sort values in ascending order. - * - * @note O(n) if data already sorted, O(n^2) - otherwise - */ -void ff_sort_nearly_sorted_floats(float *vals, int len); - -/** - * Computes the Pa / (1 + z(-1)) or Qa / (1 - z(-1)) coefficients - * needed for LSP to LPC conversion. - * We only need to calculate the 6 first elements of the polynomial. - * - * @param lsp line spectral pairs in cosine domain - * @param f [out] polynomial input/output as a vector - * - * TIA/EIA/IS-733 2.4.3.3.5-1/2 - */ -void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order); - -#endif /* AVCODEC_LSP_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/lzw.c b/tizen/distrib/ffmpeg/libavcodec/lzw.c deleted file mode 100644 index 8043789..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lzw.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * LZW decoder - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief LZW decoding routines - * @author Fabrice Bellard - * Modified for use in TIFF by Konstantin Shishkov - */ - -#include "avcodec.h" -#include "lzw.h" - -#define LZW_MAXBITS 12 -#define LZW_SIZTABLE (1<mode == FF_LZW_GIF) { - while (s->bbits < s->cursize) { - if (!s->bs) { - s->bs = *s->pbuf++; - } - s->bbuf |= (*s->pbuf++) << s->bbits; - s->bbits += 8; - s->bs--; - } - c = s->bbuf; - s->bbuf >>= s->cursize; - } else { // TIFF - while (s->bbits < s->cursize) { - s->bbuf = (s->bbuf << 8) | (*s->pbuf++); - s->bbits += 8; - } - c = s->bbuf >> (s->bbits - s->cursize); - } - s->bbits -= s->cursize; - return c & s->curmask; -} - -const uint8_t* ff_lzw_cur_ptr(LZWState *p) -{ - return ((struct LZWState*)p)->pbuf; -} - -void ff_lzw_decode_tail(LZWState *p) -{ - struct LZWState *s = (struct LZWState *)p; - - if(s->mode == FF_LZW_GIF) { - while(s->pbuf < s->ebuf && s->bs>0){ - s->pbuf += s->bs; - s->bs = *s->pbuf++; - } - }else - s->pbuf= s->ebuf; -} - -av_cold void ff_lzw_decode_open(LZWState **p) -{ - *p = av_mallocz(sizeof(struct LZWState)); -} - -av_cold void ff_lzw_decode_close(LZWState **p) -{ - av_freep(p); -} - -/** - * Initialize LZW decoder - * @param s LZW context - * @param csize initial code size in bits - * @param buf input data - * @param buf_size input data size - * @param mode decoder working mode - either GIF or TIFF - */ -int ff_lzw_decode_init(LZWState *p, int csize, const uint8_t *buf, int buf_size, int mode) -{ - struct LZWState *s = (struct LZWState *)p; - - if(csize < 1 || csize >= LZW_MAXBITS) - return -1; - /* read buffer */ - s->pbuf = buf; - s->ebuf = s->pbuf + buf_size; - s->bbuf = 0; - s->bbits = 0; - s->bs = 0; - - /* decoder */ - s->codesize = csize; - s->cursize = s->codesize + 1; - s->curmask = mask[s->cursize]; - s->top_slot = 1 << s->cursize; - s->clear_code = 1 << s->codesize; - s->end_code = s->clear_code + 1; - s->slot = s->newcodes = s->clear_code + 2; - s->oc = s->fc = -1; - s->sp = s->stack; - - s->mode = mode; - s->extra_slot = s->mode == FF_LZW_TIFF; - return 0; -} - -/** - * Decode given number of bytes - * NOTE: the algorithm here is inspired from the LZW GIF decoder - * written by Steven A. Bennett in 1987. - * - * @param s LZW context - * @param buf output buffer - * @param len number of bytes to decode - * @return number of bytes decoded - */ -int ff_lzw_decode(LZWState *p, uint8_t *buf, int len){ - int l, c, code, oc, fc; - uint8_t *sp; - struct LZWState *s = (struct LZWState *)p; - - if (s->end_code < 0) - return 0; - - l = len; - sp = s->sp; - oc = s->oc; - fc = s->fc; - - for (;;) { - while (sp > s->stack) { - *buf++ = *(--sp); - if ((--l) == 0) - goto the_end; - } - c = lzw_get_code(s); - if (c == s->end_code) { - break; - } else if (c == s->clear_code) { - s->cursize = s->codesize + 1; - s->curmask = mask[s->cursize]; - s->slot = s->newcodes; - s->top_slot = 1 << s->cursize; - fc= oc= -1; - } else { - code = c; - if (code == s->slot && fc>=0) { - *sp++ = fc; - code = oc; - }else if(code >= s->slot) - break; - while (code >= s->newcodes) { - *sp++ = s->suffix[code]; - code = s->prefix[code]; - } - *sp++ = code; - if (s->slot < s->top_slot && oc>=0) { - s->suffix[s->slot] = code; - s->prefix[s->slot++] = oc; - } - fc = code; - oc = c; - if (s->slot >= s->top_slot - s->extra_slot) { - if (s->cursize < LZW_MAXBITS) { - s->top_slot <<= 1; - s->curmask = mask[++s->cursize]; - } - } - } - } - s->end_code = -1; - the_end: - s->sp = sp; - s->oc = oc; - s->fc = fc; - return len - l; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/lzw.h b/tizen/distrib/ffmpeg/libavcodec/lzw.h deleted file mode 100644 index 76a5b67..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lzw.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * LZW decoder - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief LZW decoding routines - * @author Fabrice Bellard - * Modified for use in TIFF by Konstantin Shishkov - */ - -#ifndef AVCODEC_LZW_H -#define AVCODEC_LZW_H - -#include - -struct PutBitContext; - -enum FF_LZW_MODES{ - FF_LZW_GIF, - FF_LZW_TIFF -}; - -/* clients should not know what LZWState is */ -typedef void LZWState; - -/* first two functions de/allocate memory for LZWState */ -void ff_lzw_decode_open(LZWState **p); -void ff_lzw_decode_close(LZWState **p); -int ff_lzw_decode_init(LZWState *s, int csize, const uint8_t *buf, int buf_size, int mode); -int ff_lzw_decode(LZWState *s, uint8_t *buf, int len); -const uint8_t* ff_lzw_cur_ptr(LZWState *lzw); -void ff_lzw_decode_tail(LZWState *lzw); - -/** LZW encode state */ -struct LZWEncodeState; -extern const int ff_lzw_encode_state_size; - -void ff_lzw_encode_init(struct LZWEncodeState *s, uint8_t *outbuf, int outsize, - int maxbits, enum FF_LZW_MODES mode, - void (*lzw_put_bits)(struct PutBitContext *, int, unsigned int)); -int ff_lzw_encode(struct LZWEncodeState * s, const uint8_t * inbuf, int insize); -int ff_lzw_encode_flush(struct LZWEncodeState *s, - void (*lzw_flush_put_bits)(struct PutBitContext *)); - -#endif /* AVCODEC_LZW_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/lzwenc.c b/tizen/distrib/ffmpeg/libavcodec/lzwenc.c deleted file mode 100644 index 23248a6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/lzwenc.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * LZW encoder - * Copyright (c) 2007 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * LZW encoder - * @file - * @author Bartlomiej Wolowiec - */ - -#include "avcodec.h" -#include "put_bits.h" -#include "lzw.h" - -#define LZW_MAXBITS 12 -#define LZW_SIZTABLE (1<= LZW_HASH_SIZE) - head -= LZW_HASH_SIZE; - assert(head >= 0 && head < LZW_HASH_SIZE); - return head; -} - -/** - * Hash function calculates next hash value - * @param head Actual hash code - * @param offset Offset calculated by hashOffset - * @return New hash value - */ -static inline int hashNext(int head, const int offset) -{ - head -= offset; - if(head < 0) - head += LZW_HASH_SIZE; - return head; -} - -/** - * Hash function calculates hash offset - * @param head Actual hash code - * @return Hash offset - */ -static inline int hashOffset(const int head) -{ - return head ? LZW_HASH_SIZE - head : 1; -} - -/** - * Write one code to stream - * @param s LZW state - * @param c code to write - */ -static inline void writeCode(LZWEncodeState * s, int c) -{ - assert(0 <= c && c < 1 << s->bits); - s->put_bits(&s->pb, s->bits, c); -} - - -/** - * Find LZW code for block - * @param s LZW state - * @param c Last character in block - * @param hash_prefix LZW code for prefix - * @return LZW code for block or -1 if not found in table - */ -static inline int findCode(LZWEncodeState * s, uint8_t c, int hash_prefix) -{ - int h = hash(FFMAX(hash_prefix, 0), c); - int hash_offset = hashOffset(h); - - while (s->tab[h].hash_prefix != LZW_PREFIX_FREE) { - if ((s->tab[h].suffix == c) - && (s->tab[h].hash_prefix == hash_prefix)) - return h; - h = hashNext(h, hash_offset); - } - - return h; -} - -/** - * Add block to LZW code table - * @param s LZW state - * @param c Last character in block - * @param hash_prefix LZW code for prefix - * @param hash_code LZW code for bytes block - */ -static inline void addCode(LZWEncodeState * s, uint8_t c, int hash_prefix, int hash_code) -{ - s->tab[hash_code].code = s->tabsize; - s->tab[hash_code].suffix = c; - s->tab[hash_code].hash_prefix = hash_prefix; - - s->tabsize++; - - if (s->tabsize >= (1 << s->bits) + (s->mode == FF_LZW_GIF)) - s->bits++; -} - -/** - * Clear LZW code table - * @param s LZW state - */ -static void clearTable(LZWEncodeState * s) -{ - int i, h; - - writeCode(s, s->clear_code); - s->bits = 9; - for (i = 0; i < LZW_HASH_SIZE; i++) { - s->tab[i].hash_prefix = LZW_PREFIX_FREE; - } - for (i = 0; i < 256; i++) { - h = hash(0, i); - s->tab[h].code = i; - s->tab[h].suffix = i; - s->tab[h].hash_prefix = LZW_PREFIX_EMPTY; - } - s->tabsize = 258; -} - -/** - * Calculate number of bytes written - * @param s LZW encode state - * @return Number of bytes written - */ -static int writtenBytes(LZWEncodeState *s){ - int ret = put_bits_count(&s->pb) >> 3; - ret -= s->output_bytes; - s->output_bytes += ret; - return ret; -} - -/** - * Initialize LZW encoder. Please set s->clear_code, s->end_code and s->maxbits before run. - * @param s LZW state - * @param outbuf Output buffer - * @param outsize Size of output buffer - * @param maxbits Maximum length of code - */ -void ff_lzw_encode_init(LZWEncodeState *s, uint8_t *outbuf, int outsize, - int maxbits, enum FF_LZW_MODES mode, - void (*lzw_put_bits)(PutBitContext *, int, unsigned)) -{ - s->clear_code = 256; - s->end_code = 257; - s->maxbits = maxbits; - init_put_bits(&s->pb, outbuf, outsize); - s->bufsize = outsize; - assert(s->maxbits >= 9 && s->maxbits <= LZW_MAXBITS); - s->maxcode = 1 << s->maxbits; - s->output_bytes = 0; - s->last_code = LZW_PREFIX_EMPTY; - s->bits = 9; - s->mode = mode; - s->put_bits = lzw_put_bits; -} - -/** - * LZW main compress function - * @param s LZW state - * @param inbuf Input buffer - * @param insize Size of input buffer - * @return Number of bytes written or -1 on error - */ -int ff_lzw_encode(LZWEncodeState * s, const uint8_t * inbuf, int insize) -{ - int i; - - if(insize * 3 > (s->bufsize - s->output_bytes) * 2){ - return -1; - } - - if (s->last_code == LZW_PREFIX_EMPTY) - clearTable(s); - - for (i = 0; i < insize; i++) { - uint8_t c = *inbuf++; - int code = findCode(s, c, s->last_code); - if (s->tab[code].hash_prefix == LZW_PREFIX_FREE) { - writeCode(s, s->last_code); - addCode(s, c, s->last_code, code); - code= hash(0, c); - } - s->last_code = s->tab[code].code; - if (s->tabsize >= s->maxcode - 1) { - clearTable(s); - } - } - - return writtenBytes(s); -} - -/** - * Write end code and flush bitstream - * @param s LZW state - * @return Number of bytes written or -1 on error - */ -int ff_lzw_encode_flush(LZWEncodeState *s, - void (*lzw_flush_put_bits)(PutBitContext *)) -{ - if (s->last_code != -1) - writeCode(s, s->last_code); - writeCode(s, s->end_code); - lzw_flush_put_bits(&s->pb); - s->last_code = -1; - - return writtenBytes(s); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mace.c b/tizen/distrib/ffmpeg/libavcodec/mace.c deleted file mode 100644 index 3c71320..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mace.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * MACE decoder - * Copyright (c) 2002 Laszlo Torok - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MACE decoder. - */ - -#include "avcodec.h" - -/* - * Adapted to ffmpeg by Francois Revol - * (removed 68k REG stuff, changed types, added some statics and consts, - * libavcodec api, context stuff, interlaced stereo out). - */ - -static const int16_t MACEtab1[] = {-13, 8, 76, 222, 222, 76, 8, -13}; - -static const int16_t MACEtab3[] = {-18, 140, 140, -18}; - -static const int16_t MACEtab2[][4] = { - { 37, 116, 206, 330}, { 39, 121, 216, 346}, - { 41, 127, 225, 361}, { 42, 132, 235, 377}, - { 44, 137, 245, 392}, { 46, 144, 256, 410}, - { 48, 150, 267, 428}, { 51, 157, 280, 449}, - { 53, 165, 293, 470}, { 55, 172, 306, 490}, - { 58, 179, 319, 511}, { 60, 187, 333, 534}, - { 63, 195, 348, 557}, { 66, 205, 364, 583}, - { 69, 214, 380, 609}, { 72, 223, 396, 635}, - { 75, 233, 414, 663}, { 79, 244, 433, 694}, - { 82, 254, 453, 725}, { 86, 265, 472, 756}, - { 90, 278, 495, 792}, { 94, 290, 516, 826}, - { 98, 303, 538, 862}, { 102, 316, 562, 901}, - { 107, 331, 588, 942}, { 112, 345, 614, 983}, - { 117, 361, 641, 1027}, { 122, 377, 670, 1074}, - { 127, 394, 701, 1123}, { 133, 411, 732, 1172}, - { 139, 430, 764, 1224}, { 145, 449, 799, 1280}, - { 152, 469, 835, 1337}, { 159, 490, 872, 1397}, - { 166, 512, 911, 1459}, { 173, 535, 951, 1523}, - { 181, 558, 993, 1590}, { 189, 584, 1038, 1663}, - { 197, 610, 1085, 1738}, { 206, 637, 1133, 1815}, - { 215, 665, 1183, 1895}, { 225, 695, 1237, 1980}, - { 235, 726, 1291, 2068}, { 246, 759, 1349, 2161}, - { 257, 792, 1409, 2257}, { 268, 828, 1472, 2357}, - { 280, 865, 1538, 2463}, { 293, 903, 1606, 2572}, - { 306, 944, 1678, 2688}, { 319, 986, 1753, 2807}, - { 334, 1030, 1832, 2933}, { 349, 1076, 1914, 3065}, - { 364, 1124, 1999, 3202}, { 380, 1174, 2088, 3344}, - { 398, 1227, 2182, 3494}, { 415, 1281, 2278, 3649}, - { 434, 1339, 2380, 3811}, { 453, 1398, 2486, 3982}, - { 473, 1461, 2598, 4160}, { 495, 1526, 2714, 4346}, - { 517, 1594, 2835, 4540}, { 540, 1665, 2961, 4741}, - { 564, 1740, 3093, 4953}, { 589, 1818, 3232, 5175}, - { 615, 1898, 3375, 5405}, { 643, 1984, 3527, 5647}, - { 671, 2072, 3683, 5898}, { 701, 2164, 3848, 6161}, - { 733, 2261, 4020, 6438}, { 766, 2362, 4199, 6724}, - { 800, 2467, 4386, 7024}, { 836, 2578, 4583, 7339}, - { 873, 2692, 4786, 7664}, { 912, 2813, 5001, 8008}, - { 952, 2938, 5223, 8364}, { 995, 3070, 5457, 8739}, - { 1039, 3207, 5701, 9129}, { 1086, 3350, 5956, 9537}, - { 1134, 3499, 6220, 9960}, { 1185, 3655, 6497, 10404}, - { 1238, 3818, 6788, 10869}, { 1293, 3989, 7091, 11355}, - { 1351, 4166, 7407, 11861}, { 1411, 4352, 7738, 12390}, - { 1474, 4547, 8084, 12946}, { 1540, 4750, 8444, 13522}, - { 1609, 4962, 8821, 14126}, { 1680, 5183, 9215, 14756}, - { 1756, 5415, 9626, 15415}, { 1834, 5657, 10057, 16104}, - { 1916, 5909, 10505, 16822}, { 2001, 6173, 10975, 17574}, - { 2091, 6448, 11463, 18356}, { 2184, 6736, 11974, 19175}, - { 2282, 7037, 12510, 20032}, { 2383, 7351, 13068, 20926}, - { 2490, 7679, 13652, 21861}, { 2601, 8021, 14260, 22834}, - { 2717, 8380, 14897, 23854}, { 2838, 8753, 15561, 24918}, - { 2965, 9144, 16256, 26031}, { 3097, 9553, 16982, 27193}, - { 3236, 9979, 17740, 28407}, { 3380, 10424, 18532, 29675}, - { 3531, 10890, 19359, 31000}, { 3688, 11375, 20222, 32382}, - { 3853, 11883, 21125, 32767}, { 4025, 12414, 22069, 32767}, - { 4205, 12967, 23053, 32767}, { 4392, 13546, 24082, 32767}, - { 4589, 14151, 25157, 32767}, { 4793, 14783, 26280, 32767}, - { 5007, 15442, 27452, 32767}, { 5231, 16132, 28678, 32767}, - { 5464, 16851, 29957, 32767}, { 5708, 17603, 31294, 32767}, - { 5963, 18389, 32691, 32767}, { 6229, 19210, 32767, 32767}, - { 6507, 20067, 32767, 32767}, { 6797, 20963, 32767, 32767}, - { 7101, 21899, 32767, 32767}, { 7418, 22876, 32767, 32767}, - { 7749, 23897, 32767, 32767}, { 8095, 24964, 32767, 32767}, - { 8456, 26078, 32767, 32767}, { 8833, 27242, 32767, 32767}, - { 9228, 28457, 32767, 32767}, { 9639, 29727, 32767, 32767} -}; - -static const int16_t MACEtab4[][2] = { - { 64, 216}, { 67, 226}, { 70, 236}, { 74, 246}, - { 77, 257}, { 80, 268}, { 84, 280}, { 88, 294}, - { 92, 307}, { 96, 321}, { 100, 334}, { 104, 350}, - { 109, 365}, { 114, 382}, { 119, 399}, { 124, 416}, - { 130, 434}, { 136, 454}, { 142, 475}, { 148, 495}, - { 155, 519}, { 162, 541}, { 169, 564}, { 176, 590}, - { 185, 617}, { 193, 644}, { 201, 673}, { 210, 703}, - { 220, 735}, { 230, 767}, { 240, 801}, { 251, 838}, - { 262, 876}, { 274, 914}, { 286, 955}, { 299, 997}, - { 312, 1041}, { 326, 1089}, { 341, 1138}, { 356, 1188}, - { 372, 1241}, { 388, 1297}, { 406, 1354}, { 424, 1415}, - { 443, 1478}, { 462, 1544}, { 483, 1613}, { 505, 1684}, - { 527, 1760}, { 551, 1838}, { 576, 1921}, { 601, 2007}, - { 628, 2097}, { 656, 2190}, { 686, 2288}, { 716, 2389}, - { 748, 2496}, { 781, 2607}, { 816, 2724}, { 853, 2846}, - { 891, 2973}, { 930, 3104}, { 972, 3243}, { 1016, 3389}, - { 1061, 3539}, { 1108, 3698}, { 1158, 3862}, { 1209, 4035}, - { 1264, 4216}, { 1320, 4403}, { 1379, 4599}, { 1441, 4806}, - { 1505, 5019}, { 1572, 5244}, { 1642, 5477}, { 1715, 5722}, - { 1792, 5978}, { 1872, 6245}, { 1955, 6522}, { 2043, 6813}, - { 2134, 7118}, { 2229, 7436}, { 2329, 7767}, { 2432, 8114}, - { 2541, 8477}, { 2655, 8854}, { 2773, 9250}, { 2897, 9663}, - { 3026, 10094}, { 3162, 10546}, { 3303, 11016}, { 3450, 11508}, - { 3604, 12020}, { 3765, 12556}, { 3933, 13118}, { 4108, 13703}, - { 4292, 14315}, { 4483, 14953}, { 4683, 15621}, { 4892, 16318}, - { 5111, 17046}, { 5339, 17807}, { 5577, 18602}, { 5826, 19433}, - { 6086, 20300}, { 6358, 21205}, { 6642, 22152}, { 6938, 23141}, - { 7248, 24173}, { 7571, 25252}, { 7909, 26380}, { 8262, 27557}, - { 8631, 28786}, { 9016, 30072}, { 9419, 31413}, { 9839, 32767}, - { 10278, 32767}, { 10737, 32767}, { 11216, 32767}, { 11717, 32767}, - { 12240, 32767}, { 12786, 32767}, { 13356, 32767}, { 13953, 32767}, - { 14576, 32767}, { 15226, 32767}, { 15906, 32767}, { 16615, 32767} -}; - -static const struct { - const int16_t *tab1; const int16_t *tab2; int stride; -} tabs[] = { - {MACEtab1, &MACEtab2[0][0], 4}, - {MACEtab3, &MACEtab4[0][0], 2}, - {MACEtab1, &MACEtab2[0][0], 4} -}; - -#define QT_8S_2_16S(x) (((x) & 0xFF00) | (((x) >> 8) & 0xFF)) - -typedef struct ChannelData { - int16_t index, factor, prev2, previous, level; -} ChannelData; - -typedef struct MACEContext { - ChannelData chd[2]; -} MACEContext; - -/** - * MACE version of av_clip_int16(). We have to do this to keep binary - * identical output to the binary decoder. - */ -static inline int16_t mace_broken_clip_int16(int n) -{ - if (n > 32767) - return 32767; - else if (n < -32768) - return -32767; - else - return n; -} - -static int16_t read_table(ChannelData *chd, uint8_t val, int tab_idx) -{ - int16_t current; - - if (val < tabs[tab_idx].stride) - current = tabs[tab_idx].tab2[((chd->index & 0x7f0) >> 4) * tabs[tab_idx].stride + val]; - else - current = - 1 - tabs[tab_idx].tab2[((chd->index & 0x7f0) >> 4)*tabs[tab_idx].stride + 2*tabs[tab_idx].stride-val-1]; - - if (( chd->index += tabs[tab_idx].tab1[val]-(chd->index >> 5) ) < 0) - chd->index = 0; - - return current; -} - -static void chomp3(ChannelData *chd, int16_t *output, uint8_t val, - int tab_idx, - uint32_t numChannels) -{ - - int16_t current = read_table(chd, val, tab_idx); - - current = mace_broken_clip_int16(current + chd->level); - - chd->level = current - (current >> 3); - *output = QT_8S_2_16S(current); -} - -static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, - int tab_idx, - uint32_t numChannels) -{ - int16_t current = read_table(chd, val, tab_idx); - - if ((chd->previous ^ current) >= 0) { - chd->factor = FFMIN(chd->factor + 506, 32767); - } else { - if (chd->factor - 314 < -32768) - chd->factor = -32767; - else - chd->factor -= 314; - } - - current = mace_broken_clip_int16(current + chd->level); - - chd->level = (current*chd->factor) >> 15; - current >>= 1; - - output[0] = QT_8S_2_16S(chd->previous + chd->prev2 - - ((chd->prev2-current) >> 2)); - output[numChannels] = QT_8S_2_16S(chd->previous + current + - ((chd->prev2-current) >> 2)); - chd->prev2 = chd->previous; - chd->previous = current; -} - -static av_cold int mace_decode_init(AVCodecContext * avctx) -{ - if (avctx->channels > 2) - return -1; - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -static int mace_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - int16_t *samples = data; - MACEContext *ctx = avctx->priv_data; - int i, j, k, l; - int is_mace3 = (avctx->codec_id == CODEC_ID_MACE3); - - if (*data_size < (3 * buf_size << (2-is_mace3))) { - av_log(avctx, AV_LOG_ERROR, "Output buffer too small!\n"); - return -1; - } - - for(i = 0; i < avctx->channels; i++) { - int16_t *output = samples + i; - - for (j=0; j < buf_size / (avctx->channels << is_mace3); j++) - for (k=0; k < (1 << is_mace3); k++) { - uint8_t pkt = buf[(i << is_mace3) + - (j*avctx->channels << is_mace3) + k]; - - uint8_t val[2][3] = {{pkt >> 5, (pkt >> 3) & 3, pkt & 7 }, - {pkt & 7 , (pkt >> 3) & 3, pkt >> 5}}; - - for (l=0; l < 3; l++) { - if (is_mace3) - chomp3(&ctx->chd[i], output, val[1][l], l, - avctx->channels); - else - chomp6(&ctx->chd[i], output, val[0][l], l, - avctx->channels); - - output += avctx->channels << (1-is_mace3); - } - } - } - - *data_size = 3 * buf_size << (2-is_mace3); - - return buf_size; -} - -AVCodec mace3_decoder = { - "mace3", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MACE3, - sizeof(MACEContext), - mace_decode_init, - NULL, - NULL, - mace_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"), -}; - -AVCodec mace6_decoder = { - "mace6", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MACE6, - sizeof(MACEContext), - mace_decode_init, - NULL, - NULL, - mace_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/mathops.h b/tizen/distrib/ffmpeg/libavcodec/mathops.h deleted file mode 100644 index 149910b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mathops.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * simple math operations - * Copyright (c) 2001, 2002 Fabrice Bellard - * Copyright (c) 2006 Michael Niedermayer et al - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVCODEC_MATHOPS_H -#define AVCODEC_MATHOPS_H - -#include "libavutil/common.h" - -#if ARCH_ARM -# include "arm/mathops.h" -#elif ARCH_AVR32 -# include "avr32/mathops.h" -#elif ARCH_BFIN -# include "bfin/mathops.h" -#elif ARCH_MIPS -# include "mips/mathops.h" -#elif ARCH_PPC -# include "ppc/mathops.h" -#elif ARCH_X86 -# include "x86/mathops.h" -#endif - -/* generic implementation */ - -#ifndef MULL -# define MULL(a,b,s) (((int64_t)(a) * (int64_t)(b)) >> (s)) -#endif - -#ifndef MULH -//gcc 3.4 creates an incredibly bloated mess out of this -//# define MULH(a,b) (((int64_t)(a) * (int64_t)(b))>>32) - -static av_always_inline int MULH(int a, int b){ - return ((int64_t)(a) * (int64_t)(b))>>32; -} -#endif - -#ifndef UMULH -static av_always_inline unsigned UMULH(unsigned a, unsigned b){ - return ((uint64_t)(a) * (uint64_t)(b))>>32; -} -#endif - -#ifndef MUL64 -# define MUL64(a,b) ((int64_t)(a) * (int64_t)(b)) -#endif - -#ifndef MAC64 -# define MAC64(d, a, b) ((d) += MUL64(a, b)) -#endif - -#ifndef MLS64 -# define MLS64(d, a, b) ((d) -= MUL64(a, b)) -#endif - -/* signed 16x16 -> 32 multiply add accumulate */ -#ifndef MAC16 -# define MAC16(rt, ra, rb) rt += (ra) * (rb) -#endif - -/* signed 16x16 -> 32 multiply */ -#ifndef MUL16 -# define MUL16(ra, rb) ((ra) * (rb)) -#endif - -#ifndef MLS16 -# define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb)) -#endif - -/* median of 3 */ -#ifndef mid_pred -#define mid_pred mid_pred -static inline av_const int mid_pred(int a, int b, int c) -{ -#if 0 - int t= (a-b)&((a-b)>>31); - a-=t; - b+=t; - b-= (b-c)&((b-c)>>31); - b+= (a-b)&((a-b)>>31); - - return b; -#else - if(a>b){ - if(c>b){ - if(c>a) b=a; - else b=c; - } - }else{ - if(b>c){ - if(c>a) b=c; - else b=a; - } - } - return b; -#endif -} -#endif - -#ifndef sign_extend -static inline av_const int sign_extend(int val, unsigned bits) -{ - return (val << (INT_BIT - bits)) >> (INT_BIT - bits); -} -#endif - -#ifndef zero_extend -static inline av_const unsigned zero_extend(unsigned val, unsigned bits) -{ - return (val << (INT_BIT - bits)) >> (INT_BIT - bits); -} -#endif - -#ifndef COPY3_IF_LT -#define COPY3_IF_LT(x, y, a, b, c, d)\ -if ((y) < (x)) {\ - (x) = (y);\ - (a) = (b);\ - (c) = (d);\ -} -#endif - -#ifndef NEG_SSR32 -# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) -#endif - -#ifndef NEG_USR32 -# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) -#endif - -#endif /* AVCODEC_MATHOPS_H */ - diff --git a/tizen/distrib/ffmpeg/libavcodec/mdct.c b/tizen/distrib/ffmpeg/libavcodec/mdct.c deleted file mode 100644 index 69e1bbf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mdct.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * MDCT/IMDCT transforms - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "libavutil/common.h" -#include "libavutil/mathematics.h" -#include "fft.h" - -/** - * @file - * MDCT/IMDCT transforms. - */ - -// Generate a Kaiser-Bessel Derived Window. -#define BESSEL_I0_ITER 50 // default: 50 iterations of Bessel I0 approximation -av_cold void ff_kbd_window_init(float *window, float alpha, int n) -{ - int i, j; - double sum = 0.0, bessel, tmp; - double local_window[n]; - double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n); - - for (i = 0; i < n; i++) { - tmp = i * (n - i) * alpha2; - bessel = 1.0; - for (j = BESSEL_I0_ITER; j > 0; j--) - bessel = bessel * tmp / (j * j) + 1; - sum += bessel; - local_window[i] = sum; - } - - sum++; - for (i = 0; i < n; i++) - window[i] = sqrt(local_window[i] / sum); -} - -#include "mdct_tablegen.h" - -/** - * init MDCT or IMDCT computation. - */ -av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale) -{ - int n, n4, i; - double alpha, theta; - int tstep; - - memset(s, 0, sizeof(*s)); - n = 1 << nbits; - s->mdct_bits = nbits; - s->mdct_size = n; - n4 = n >> 2; - s->permutation = FF_MDCT_PERM_NONE; - - if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0) - goto fail; - - s->tcos = av_malloc(n/2 * sizeof(FFTSample)); - if (!s->tcos) - goto fail; - - switch (s->permutation) { - case FF_MDCT_PERM_NONE: - s->tsin = s->tcos + n4; - tstep = 1; - break; - case FF_MDCT_PERM_INTERLEAVE: - s->tsin = s->tcos + 1; - tstep = 2; - break; - default: - goto fail; - } - - theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0); - scale = sqrt(fabs(scale)); - for(i=0;itcos[i*tstep] = -cos(alpha) * scale; - s->tsin[i*tstep] = -sin(alpha) * scale; - } - return 0; - fail: - ff_mdct_end(s); - return -1; -} - -/* complex multiplication: p = a * b */ -#define CMUL(pre, pim, are, aim, bre, bim) \ -{\ - FFTSample _are = (are);\ - FFTSample _aim = (aim);\ - FFTSample _bre = (bre);\ - FFTSample _bim = (bim);\ - (pre) = _are * _bre - _aim * _bim;\ - (pim) = _are * _bim + _aim * _bre;\ -} - -/** - * Compute the middle half of the inverse MDCT of size N = 2^nbits, - * thus excluding the parts that can be derived by symmetry - * @param output N/2 samples - * @param input N/2 samples - */ -void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - int k, n8, n4, n2, n, j; - const uint16_t *revtab = s->revtab; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - const FFTSample *in1, *in2; - FFTComplex *z = (FFTComplex *)output; - - n = 1 << s->mdct_bits; - n2 = n >> 1; - n4 = n >> 2; - n8 = n >> 3; - - /* pre rotation */ - in1 = input; - in2 = input + n2 - 1; - for(k = 0; k < n4; k++) { - j=revtab[k]; - CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); - in1 += 2; - in2 -= 2; - } - ff_fft_calc(s, z); - - /* post rotation + reordering */ - for(k = 0; k < n8; k++) { - FFTSample r0, i0, r1, i1; - CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]); - CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]); - z[n8-k-1].re = r0; - z[n8-k-1].im = i0; - z[n8+k ].re = r1; - z[n8+k ].im = i1; - } -} - -/** - * Compute inverse MDCT of size N = 2^nbits - * @param output N samples - * @param input N/2 samples - */ -void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - int k; - int n = 1 << s->mdct_bits; - int n2 = n >> 1; - int n4 = n >> 2; - - ff_imdct_half_c(s, output+n4, input); - - for(k = 0; k < n4; k++) { - output[k] = -output[n2-k-1]; - output[n-k-1] = output[n2+k]; - } -} - -/** - * Compute MDCT of size N = 2^nbits - * @param input N samples - * @param out N/2 samples - */ -void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input) -{ - int i, j, n, n8, n4, n2, n3; - FFTSample re, im; - const uint16_t *revtab = s->revtab; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - FFTComplex *x = (FFTComplex *)out; - - n = 1 << s->mdct_bits; - n2 = n >> 1; - n4 = n >> 2; - n8 = n >> 3; - n3 = 3 * n4; - - /* pre rotation */ - for(i=0;itcos); - ff_fft_end(s); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.c b/tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.c deleted file mode 100644 index 6205f06..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Generate a header file for hardcoded MDCT tables - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#define CONFIG_HARDCODED_TABLES 0 -#define SINETABLE_CONST -#define SINETABLE(size) \ - float ff_sine_##size[size] -#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -#include "mdct_tablegen.h" -#include "tableprint.h" - -int main(void) -{ - int i; - - write_fileheader(); - - for (i = 5; i <= 12; i++) { - ff_init_ff_sine_windows(i); - printf("SINETABLE(%4i) = {\n", 1 << i); - write_float_array(ff_sine_windows[i], 1 << i); - printf("};\n"); - } - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.h b/tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.h deleted file mode 100644 index 1722c3b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mdct_tablegen.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Header file for hardcoded MDCT tables - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -// do not use libavutil/mathematics.h since this is compiled both -// for the host and the target and config.h is only valid for the target -#include -#include "../libavutil/attributes.h" - -#if !CONFIG_HARDCODED_TABLES -SINETABLE( 32); -SINETABLE( 64); -SINETABLE( 128); -SINETABLE( 256); -SINETABLE( 512); -SINETABLE(1024); -SINETABLE(2048); -SINETABLE(4096); -#else -#include "libavcodec/mdct_tables.h" -#endif - -SINETABLE_CONST float * const ff_sine_windows[] = { - NULL, NULL, NULL, NULL, NULL, // unused - ff_sine_32 , ff_sine_64 , - ff_sine_128, ff_sine_256, ff_sine_512, ff_sine_1024, ff_sine_2048, ff_sine_4096 -}; - -// Generate a sine window. -av_cold void ff_sine_window_init(float *window, int n) { - int i; - for(i = 0; i < n; i++) - window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n))); -} - -av_cold void ff_init_ff_sine_windows(int index) { - assert(index >= 0 && index < FF_ARRAY_ELEMS(ff_sine_windows)); -#if !CONFIG_HARDCODED_TABLES - ff_sine_window_init(ff_sine_windows[index], 1 << index); -#endif -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mdec.c b/tizen/distrib/ffmpeg/libavcodec/mdec.c deleted file mode 100644 index 606a749..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mdec.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Sony PlayStation MDEC (Motion DECoder) - * Copyright (c) 2003 Michael Niedermayer - * - * based upon code from Sebastian Jedruszkiewicz - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sony PlayStation MDEC (Motion DECoder) - * This is very similar to intra-only MPEG-1. - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mpeg12.h" - -typedef struct MDECContext{ - AVCodecContext *avctx; - DSPContext dsp; - AVFrame picture; - GetBitContext gb; - ScanTable scantable; - int version; - int qscale; - int last_dc[3]; - int mb_width; - int mb_height; - int mb_x, mb_y; - DECLARE_ALIGNED(16, DCTELEM, block)[6][64]; - uint8_t *bitstream_buffer; - unsigned int bitstream_buffer_size; - int block_last_index[6]; -} MDECContext; - -//very similar to MPEG-1 -static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n) -{ - int level, diff, i, j, run; - int component; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable= a->scantable.permutated; - const uint16_t *quant_matrix= ff_mpeg1_default_intra_matrix; - const int qscale= a->qscale; - - /* DC coefficient */ - if(a->version==2){ - block[0]= 2*get_sbits(&a->gb, 10) + 1024; - }else{ - component = (n <= 3 ? 0 : n - 4 + 1); - diff = decode_dc(&a->gb, component); - if (diff >= 0xffff) - return -1; - a->last_dc[component]+= diff; - block[0] = a->last_dc[component]<<3; - } - - i = 0; - { - OPEN_READER(re, &a->gb); - /* now quantify & encode AC coefficients */ - for(;;) { - UPDATE_CACHE(re, &a->gb); - GET_RL_VLC(level, run, re, &a->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level == 127){ - break; - } else if(level != 0) { - i += run; - j = scantable[i]; - level= (level*qscale*quant_matrix[j])>>3; - level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1); - LAST_SKIP_BITS(re, &a->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6); - UPDATE_CACHE(re, &a->gb); - level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10); - i += run; - j = scantable[i]; - if(level<0){ - level= -level; - level= (level*qscale*quant_matrix[j])>>3; - level= (level-1)|1; - level= -level; - }else{ - level= (level*qscale*quant_matrix[j])>>3; - level= (level-1)|1; - } - } - if (i > 63){ - av_log(a->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y); - return -1; - } - - block[j] = level; - } - CLOSE_READER(re, &a->gb); - } - a->block_last_index[n] = i; - return 0; -} - -static inline int decode_mb(MDECContext *a, DCTELEM block[6][64]){ - int i; - const int block_index[6]= {5,4,0,1,2,3}; - - a->dsp.clear_blocks(block[0]); - - for(i=0; i<6; i++){ - if( mdec_decode_block_intra(a, block[ block_index[i] ], block_index[i]) < 0) - return -1; - } - return 0; -} - -static inline void idct_put(MDECContext *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 int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MDECContext * const a = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= &a->picture; - int i; - - 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= FF_I_TYPE; - p->key_frame= 1; - - av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!a->bitstream_buffer) - return AVERROR(ENOMEM); - for(i=0; ibitstream_buffer[i] = buf[i+1]; - a->bitstream_buffer[i+1]= buf[i ]; - } - init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); - - /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */ - skip_bits(&a->gb, 32); - - a->qscale= get_bits(&a->gb, 16); - a->version= get_bits(&a->gb, 16); - - a->last_dc[0]= - a->last_dc[1]= - a->last_dc[2]= 128; - - for(a->mb_x=0; a->mb_xmb_width; a->mb_x++){ - for(a->mb_y=0; a->mb_ymb_height; a->mb_y++){ - if( decode_mb(a, a->block) <0) - return -1; - - idct_put(a, a->mb_x, a->mb_y); - } - } - - p->quality= a->qscale * FF_QP2LAMBDA; - memset(p->qscale_table, a->qscale, a->mb_width); - - *picture = a->picture; - *data_size = sizeof(AVPicture); - - return (get_bits_count(&a->gb)+31)/32*4; -} - -static av_cold void mdec_common_init(AVCodecContext *avctx){ - MDECContext * const a = avctx->priv_data; - - dsputil_init(&a->dsp, avctx); - - a->mb_width = (avctx->coded_width + 15) / 16; - a->mb_height = (avctx->coded_height + 15) / 16; - - avctx->coded_frame= &a->picture; - a->avctx= avctx; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - MDECContext * const a = avctx->priv_data; - AVFrame *p= &a->picture; - - mdec_common_init(avctx); - ff_mpeg12_init_vlcs(); - ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_zigzag_direct); - - p->qstride= 0; - p->qscale_table= av_mallocz(a->mb_width); - avctx->pix_fmt= PIX_FMT_YUV420P; - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - MDECContext * const a = avctx->priv_data; - - if(a->picture.data[0]) - avctx->release_buffer(avctx, &a->picture); - av_freep(&a->bitstream_buffer); - av_freep(&a->picture.qscale_table); - a->bitstream_buffer_size=0; - - return 0; -} - -AVCodec mdec_decoder = { - "mdec", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MDEC, - sizeof(MDECContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/mimic.c b/tizen/distrib/ffmpeg/libavcodec/mimic.c deleted file mode 100644 index e5f7123..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mimic.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (C) 2005 Ole André Vadla Ravnås - * Copyright (C) 2008 Ramiro Polla - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include "avcodec.h" -#include "get_bits.h" -#include "bytestream.h" -#include "dsputil.h" - -#define MIMIC_HEADER_SIZE 20 - -typedef struct { - AVCodecContext *avctx; - - int num_vblocks[3]; - int num_hblocks[3]; - - void *swap_buf; - int swap_buf_size; - - int cur_index; - int prev_index; - - AVFrame buf_ptrs [16]; - AVPicture flipped_ptrs[16]; - - DECLARE_ALIGNED(16, DCTELEM, dct_block)[64]; - - GetBitContext gb; - ScanTable scantable; - DSPContext dsp; - VLC vlc; -} MimicContext; - -static const uint32_t huffcodes[] = { - 0x0000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000b, - 0x0000001b, 0x00000038, 0x00000078, 0x00000079, 0x0000007a, 0x000000f9, - 0x000000fa, 0x000003fb, 0x000007f8, 0x000007f9, 0x000007fa, 0x000007fb, - 0x00000ff8, 0x00000ff9, 0x00000001, 0x00000039, 0x0000007b, 0x000000fb, - 0x000001f8, 0x000001f9, 0x00000ffa, 0x00000ffb, 0x00001ff8, 0x00001ff9, - 0x00001ffa, 0x00001ffb, 0x00003ff8, 0x00003ff9, 0x00003ffa, 0x00000000, - 0x00000004, 0x0000003a, 0x000001fa, 0x00003ffb, 0x00007ff8, 0x00007ff9, - 0x00007ffa, 0x00007ffb, 0x0000fff8, 0x0000fff9, 0x0000fffa, 0x0000fffb, - 0x0001fff8, 0x0001fff9, 0x0001fffa, 0x00000000, 0x0000000c, 0x000000f8, - 0x000001fb, 0x0001fffb, 0x0003fff8, 0x0003fff9, 0x0003fffa, 0x0003fffb, - 0x0007fff8, 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9, - 0x000ffffa, 0x00000000, 0x0000001a, 0x000003f8, 0x000ffffb, 0x001ffff8, - 0x001ffff9, 0x001ffffa, 0x001ffffb, 0x003ffff8, 0x003ffff9, 0x003ffffa, - 0x003ffffb, 0x007ffff8, 0x007ffff9, 0x007ffffa, 0x007ffffb, 0x00000000, - 0x0000003b, 0x000003f9, 0x00fffff8, 0x00fffff9, 0x00fffffa, 0x00fffffb, - 0x01fffff8, 0x01fffff9, 0x01fffffa, 0x01fffffb, 0x03fffff8, 0x03fffff9, - 0x03fffffa, 0x03fffffb, 0x07fffff8, 0x00000000, 0x000003fa, 0x07fffff9, - 0x07fffffa, 0x07fffffb, 0x0ffffff8, 0x0ffffff9, 0x0ffffffa, 0x0ffffffb, - 0x1ffffff8, 0x1ffffff9, 0x1ffffffa, 0x1ffffffb, 0x3ffffff8, 0x3ffffff9, - 0x3ffffffa, -}; - -static const uint8_t huffbits[] = { - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 4, 5, 6, 7, 7, 7, 8, - 8, 10, 11, 11, 11, 11, 12, 12, 2, 6, 7, 8, - 9, 9, 12, 12, 13, 13, 13, 13, 14, 14, 14, 0, - 3, 6, 9, 14, 15, 15, 15, 15, 16, 16, 16, 16, - 17, 17, 17, 0, 4, 8, 9, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 0, 5, 10, 20, 21, - 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 0, - 6, 10, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, - 26, 26, 27, 0, 10, 27, 27, 27, 28, 28, 28, 28, - 29, 29, 29, 29, 30, 30, 30, -}; - -static const uint8_t col_zag[64] = { - 0, 8, 1, 2, 9, 16, 24, 17, - 10, 3, 4, 11, 18, 25, 32, 40, - 33, 26, 19, 12, 5, 6, 13, 20, - 27, 34, 41, 48, 56, 49, 42, 35, - 28, 21, 14, 7, 15, 22, 29, 36, - 43, 50, 57, 58, 51, 44, 37, 30, - 23, 31, 38, 45, 52, 59, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, -}; - -static av_cold int mimic_decode_init(AVCodecContext *avctx) -{ - MimicContext *ctx = avctx->priv_data; - - ctx->prev_index = 0; - ctx->cur_index = 15; - - if(init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits), - huffbits, 1, 1, huffcodes, 4, 4, 0)) { - av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n"); - return -1; - } - dsputil_init(&ctx->dsp, avctx); - ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag); - - return 0; -} - -static const int8_t vlcdec_lookup[9][64] = { - { 0, }, - { -1, 1, }, - { -3, 3, -2, 2, }, - { -7, 7, -6, 6, -5, 5, -4, 4, }, - { -15, 15, -14, 14, -13, 13, -12, 12, - -11, 11, -10, 10, -9, 9, -8, 8, }, - { -31, 31, -30, 30, -29, 29, -28, 28, - -27, 27, -26, 26, -25, 25, -24, 24, - -23, 23, -22, 22, -21, 21, -20, 20, - -19, 19, -18, 18, -17, 17, -16, 16, }, - { -63, 63, -62, 62, -61, 61, -60, 60, - -59, 59, -58, 58, -57, 57, -56, 56, - -55, 55, -54, 54, -53, 53, -52, 52, - -51, 51, -50, 50, -49, 49, -48, 48, - -47, 47, -46, 46, -45, 45, -44, 44, - -43, 43, -42, 42, -41, 41, -40, 40, - -39, 39, -38, 38, -37, 37, -36, 36, - -35, 35, -34, 34, -33, 33, -32, 32, }, - { -127, 127, -126, 126, -125, 125, -124, 124, - -123, 123, -122, 122, -121, 121, -120, 120, - -119, 119, -118, 118, -117, 117, -116, 116, - -115, 115, -114, 114, -113, 113, -112, 112, - -111, 111, -110, 110, -109, 109, -108, 108, - -107, 107, -106, 106, -105, 105, -104, 104, - -103, 103, -102, 102, -101, 101, -100, 100, - -99, 99, -98, 98, -97, 97, -96, 96, }, - { -95, 95, -94, 94, -93, 93, -92, 92, - -91, 91, -90, 90, -89, 89, -88, 88, - -87, 87, -86, 86, -85, 85, -84, 84, - -83, 83, -82, 82, -81, 81, -80, 80, - -79, 79, -78, 78, -77, 77, -76, 76, - -75, 75, -74, 74, -73, 73, -72, 72, - -71, 71, -70, 70, -69, 69, -68, 68, - -67, 67, -66, 66, -65, 65, -64, 64, }, -}; - -static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale) -{ - DCTELEM *block = ctx->dct_block; - unsigned int pos; - - ctx->dsp.clear_block(block); - - block[0] = get_bits(&ctx->gb, 8) << 3; - - for(pos = 1; pos < num_coeffs; pos++) { - uint32_t vlc, num_bits; - int value; - int coeff; - - vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3); - if(!vlc) /* end-of-block code */ - return 1; - if(vlc == -1) - return 0; - - /* pos_add and num_bits are coded in the vlc code */ - pos += vlc&15; // pos_add - num_bits = vlc>>4; // num_bits - - if(pos >= 64) - return 0; - - value = get_bits(&ctx->gb, num_bits); - - /* FFmpeg's IDCT behaves somewhat different from the original code, so - * a factor of 4 was added to the input */ - - coeff = vlcdec_lookup[num_bits][value]; - if(pos<3) - coeff <<= 4; - else /* TODO Use >> 10 instead of / 1001 */ - coeff = (coeff * qscale) / 1001; - - block[ctx->scantable.permutated[pos]] = coeff; - } - - return 1; -} - -static int decode(MimicContext *ctx, int quality, int num_coeffs, - int is_iframe) -{ - int y, x, plane; - - for(plane = 0; plane < 3; plane++) { - const int is_chroma = !!plane; - const int qscale = av_clip(10000-quality,is_chroma?1000:2000,10000)<<2; - const int stride = ctx->flipped_ptrs[ctx->cur_index].linesize[plane]; - const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane]; - uint8_t *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane]; - - for(y = 0; y < ctx->num_vblocks[plane]; y++) { - for(x = 0; x < ctx->num_hblocks[plane]; x++) { - - /* Check for a change condition in the current block. - * - iframes always change. - * - Luma plane changes on get_bits1 == 0 - * - Chroma planes change on get_bits1 == 1 */ - if(is_iframe || get_bits1(&ctx->gb) == is_chroma) { - - /* Luma planes may use a backreference from the 15 last - * frames preceding the previous. (get_bits1 == 1) - * Chroma planes don't use backreferences. */ - if(is_chroma || is_iframe || !get_bits1(&ctx->gb)) { - - if(!vlc_decode_block(ctx, num_coeffs, qscale)) - return 0; - ctx->dsp.idct_put(dst, stride, ctx->dct_block); - } else { - unsigned int backref = get_bits(&ctx->gb, 4); - int index = (ctx->cur_index+backref)&15; - uint8_t *p = ctx->flipped_ptrs[index].data[0]; - - if(p) { - p += src - - ctx->flipped_ptrs[ctx->prev_index].data[plane]; - ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8); - } else { - av_log(ctx->avctx, AV_LOG_ERROR, - "No such backreference! Buggy sample.\n"); - } - } - } else { - ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8); - } - src += 8; - dst += 8; - } - src += (stride - ctx->num_hblocks[plane])<<3; - dst += (stride - ctx->num_hblocks[plane])<<3; - } - } - - return 1; -} - -/** - * Flip the buffer upside-down and put it in the YVU order to match the - * way Mimic encodes frames. - */ -static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src) -{ - int i; - dst->data[0] = src->data[0]+( ctx->avctx->height -1)*src->linesize[0]; - dst->data[1] = src->data[2]+((ctx->avctx->height>>1)-1)*src->linesize[2]; - dst->data[2] = src->data[1]+((ctx->avctx->height>>1)-1)*src->linesize[1]; - for(i = 0; i < 3; i++) - dst->linesize[i] = -src->linesize[i]; -} - -static int mimic_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MimicContext *ctx = avctx->priv_data; - int is_pframe; - int width, height; - int quality, num_coeffs; - int swap_buf_size = buf_size - MIMIC_HEADER_SIZE; - - if(buf_size < MIMIC_HEADER_SIZE) { - av_log(avctx, AV_LOG_ERROR, "insufficient data\n"); - return -1; - } - - buf += 2; /* some constant (always 256) */ - quality = bytestream_get_le16(&buf); - width = bytestream_get_le16(&buf); - height = bytestream_get_le16(&buf); - buf += 4; /* some constant */ - is_pframe = bytestream_get_le32(&buf); - num_coeffs = bytestream_get_byte(&buf); - buf += 3; /* some constant */ - - if(!ctx->avctx) { - int i; - - if(!(width == 160 && height == 120) && - !(width == 320 && height == 240)) { - av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n"); - return -1; - } - - ctx->avctx = avctx; - avctx->width = width; - avctx->height = height; - avctx->pix_fmt = PIX_FMT_YUV420P; - for(i = 0; i < 3; i++) { - ctx->num_vblocks[i] = -((-height) >> (3 + !!i)); - ctx->num_hblocks[i] = width >> (3 + !!i) ; - } - } else if(width != ctx->avctx->width || height != ctx->avctx->height) { - av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n"); - return -1; - } - - if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) { - av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n"); - return -1; - } - - ctx->buf_ptrs[ctx->cur_index].reference = 1; - if(avctx->get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index], - (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]); - - av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size, - swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if(!ctx->swap_buf) - return AVERROR(ENOMEM); - - ctx->dsp.bswap_buf(ctx->swap_buf, - (const uint32_t*) buf, - swap_buf_size>>2); - init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3); - - if(!decode(ctx, quality, num_coeffs, !is_pframe)) { - avctx->release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]); - return -1; - } - - ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? FF_P_TYPE:FF_I_TYPE; - *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index]; - *data_size = sizeof(AVFrame); - - ctx->prev_index = ctx->cur_index; - ctx->cur_index--; - ctx->cur_index &= 15; - - /* Only release frames that aren't used for backreferences anymore */ - if(ctx->buf_ptrs[ctx->cur_index].data[0]) - avctx->release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]); - - return buf_size; -} - -static av_cold int mimic_decode_end(AVCodecContext *avctx) -{ - MimicContext *ctx = avctx->priv_data; - int i; - - av_free(ctx->swap_buf); - for(i = 0; i < 16; i++) - if(ctx->buf_ptrs[i].data[0]) - avctx->release_buffer(avctx, &ctx->buf_ptrs[i]); - free_vlc(&ctx->vlc); - - return 0; -} - -AVCodec mimic_decoder = { - "mimic", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MIMIC, - sizeof(MimicContext), - mimic_decode_init, - NULL, - mimic_decode_end, - mimic_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Mimic"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mips/Makefile b/tizen/distrib/ffmpeg/libavcodec/mips/Makefile deleted file mode 100644 index 3f4da68..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mips/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -OBJS-$(HAVE_MMI) += ps2/dsputil_mmi.o \ - ps2/idct_mmi.o \ - ps2/mpegvideo_mmi.o \ diff --git a/tizen/distrib/ffmpeg/libavcodec/mips/mathops.h b/tizen/distrib/ffmpeg/libavcodec/mips/mathops.h deleted file mode 100644 index a1b04ed..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mips/mathops.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MIPS_MATHOPS_H -#define AVCODEC_MIPS_MATHOPS_H - -#include -#include "config.h" -#include "libavutil/common.h" - -#if HAVE_LOONGSON - -static inline av_const int64_t MAC64(int64_t d, int a, int b) -{ - int64_t m; - __asm__ ("dmult.g %1, %2, %3 \n\t" - "daddu %0, %0, %1 \n\t" - : "+r"(d), "=&r"(m) : "r"(a), "r"(b)); - return d; -} -#define MAC64(d, a, b) ((d) = MAC64(d, a, b)) - -static inline av_const int64_t MLS64(int64_t d, int a, int b) -{ - int64_t m; - __asm__ ("dmult.g %1, %2, %3 \n\t" - "dsubu %0, %0, %1 \n\t" - : "+r"(d), "=&r"(m) : "r"(a), "r"(b)); - return d; -} -#define MLS64(d, a, b) ((d) = MLS64(d, a, b)) - -#elif ARCH_MIPS64 - -static inline av_const int64_t MAC64(int64_t d, int a, int b) -{ - int64_t m; - __asm__ ("dmult %2, %3 \n\t" - "mflo %1 \n\t" - "daddu %0, %0, %1 \n\t" - : "+r"(d), "=&r"(m) : "r"(a), "r"(b)); - return d; -} -#define MAC64(d, a, b) ((d) = MAC64(d, a, b)) - -static inline av_const int64_t MLS64(int64_t d, int a, int b) -{ - int64_t m; - __asm__ ("dmult %2, %3 \n\t" - "mflo %1 \n\t" - "dsubu %0, %0, %1 \n\t" - : "+r"(d), "=&r"(m) : "r"(a), "r"(b)); - return d; -} -#define MLS64(d, a, b) ((d) = MLS64(d, a, b)) - -#endif - -#endif /* AVCODEC_MIPS_MATHOPS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpeg.c b/tizen/distrib/ffmpeg/libavcodec/mjpeg.c deleted file mode 100644 index 6eba27d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpeg.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * MJPEG encoder and decoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer - * - * Support for external huffman table, various fixes (AVID workaround), - * aspecting, new decode_frame mechanism and apple mjpeg-b support - * by Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MJPEG encoder and decoder. - */ - -#include "mjpeg.h" - - -#if 0 -/* These are the sample quantization tables given in JPEG spec section K.1. - * The spec says that the values given produce "good" quality, and - * when divided by 2, "very good" quality. - */ -const unsigned char std_luminance_quant_tbl[64] = { - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 56, 68, 109, 103, 77, - 24, 35, 55, 64, 81, 104, 113, 92, - 49, 64, 78, 87, 103, 121, 120, 101, - 72, 92, 95, 98, 112, 100, 103, 99 -}; -const unsigned char std_chrominance_quant_tbl[64] = { - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 -}; -#endif - -/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ -/* IMPORTANT: these are only valid for 8-bit data precision! */ -const uint8_t ff_mjpeg_bits_dc_luminance[17] = -{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; -const uint8_t ff_mjpeg_val_dc[12] = -{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; - -const uint8_t ff_mjpeg_bits_dc_chrominance[17] = -{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; - -const uint8_t ff_mjpeg_bits_ac_luminance[17] = -{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; -const uint8_t ff_mjpeg_val_ac_luminance[] = -{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa -}; - -const uint8_t ff_mjpeg_bits_ac_chrominance[17] = -{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; - -const uint8_t ff_mjpeg_val_ac_chrominance[] = -{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa -}; - -/* isn't this function nicer than the one in the libjpeg ? */ -void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, - const uint8_t *bits_table, - const uint8_t *val_table) -{ - int i, j, k,nb, code, sym; - - code = 0; - k = 0; - for(i=1;i<=16;i++) { - nb = bits_table[i]; - for(j=0;j 0xbf reserved */ -} JPEG_MARKER; - -static inline void put_marker(PutBitContext *p, int code) -{ - put_bits(p, 8, 0xff); - put_bits(p, 8, code); -} - -#define PREDICT(ret, topleft, top, left, predictor)\ - switch(predictor){\ - case 1: ret= left; break;\ - case 2: ret= top; break;\ - case 3: ret= topleft; break;\ - case 4: ret= left + top - topleft; break;\ - case 5: ret= left + ((top - topleft)>>1); break;\ - case 6: ret= top + ((left - topleft)>>1); break;\ - default:\ - case 7: ret= (left + top)>>1; break;\ - } - -extern const uint8_t ff_mjpeg_bits_dc_luminance[]; -extern const uint8_t ff_mjpeg_val_dc[]; - -extern const uint8_t ff_mjpeg_bits_dc_chrominance[]; - -extern const uint8_t ff_mjpeg_bits_ac_luminance[]; -extern const uint8_t ff_mjpeg_val_ac_luminance[]; - -extern const uint8_t ff_mjpeg_bits_ac_chrominance[]; -extern const uint8_t ff_mjpeg_val_ac_chrominance[]; - -void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, - const uint8_t *bits_table, - const uint8_t *val_table); - -#endif /* AVCODEC_MJPEG_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpeg_parser.c b/tizen/distrib/ffmpeg/libavcodec/mjpeg_parser.c deleted file mode 100644 index b1848fa..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpeg_parser.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * MJPEG parser - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MJPEG parser. - */ - -#include "parser.h" - - -/** - * 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(ParseContext *pc, const uint8_t *buf, int buf_size){ - int vop_found, i; - uint16_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=0; - return i-1; - } - } - } - pc->frame_start_found= vop_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int jpeg_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - - -AVCodecParser mjpeg_parser = { - { CODEC_ID_MJPEG }, - sizeof(ParseContext), - NULL, - jpeg_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpega_dump_header_bsf.c b/tizen/distrib/ffmpeg/libavcodec/mjpega_dump_header_bsf.c deleted file mode 100644 index bb7858e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpega_dump_header_bsf.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * MJPEG A dump header bitstream filter - * Copyright (c) 2006 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MJPEG A dump header bitstream filter - * modifies bitstream to be decoded by quicktime - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "mjpeg.h" - - -static int mjpega_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe) -{ - uint8_t *poutbufp; - unsigned dqt = 0, dht = 0, sof0 = 0; - int i; - - if (avctx->codec_id != CODEC_ID_MJPEG) { - av_log(avctx, AV_LOG_ERROR, "mjpega bitstream filter only applies to mjpeg codec\n"); - return 0; - } - - *poutbuf_size = 0; - *poutbuf = av_malloc(buf_size + 44 + FF_INPUT_BUFFER_PADDING_SIZE); - poutbufp = *poutbuf; - bytestream_put_byte(&poutbufp, 0xff); - bytestream_put_byte(&poutbufp, SOI); - bytestream_put_byte(&poutbufp, 0xff); - bytestream_put_byte(&poutbufp, APP1); - bytestream_put_be16(&poutbufp, 42); /* size */ - bytestream_put_be32(&poutbufp, 0); - bytestream_put_buffer(&poutbufp, "mjpg", 4); - bytestream_put_be32(&poutbufp, buf_size + 44); /* field size */ - bytestream_put_be32(&poutbufp, buf_size + 44); /* pad field size */ - bytestream_put_be32(&poutbufp, 0); /* next ptr */ - - for (i = 0; i < buf_size - 1; i++) { - if (buf[i] == 0xff) { - switch (buf[i + 1]) { - case DQT: dqt = i + 46; break; - case DHT: dht = i + 46; break; - case SOF0: sof0 = i + 46; break; - case SOS: - bytestream_put_be32(&poutbufp, dqt); /* quant off */ - bytestream_put_be32(&poutbufp, dht); /* huff off */ - bytestream_put_be32(&poutbufp, sof0); /* image off */ - bytestream_put_be32(&poutbufp, i + 46); /* scan off */ - bytestream_put_be32(&poutbufp, i + 46 + AV_RB16(buf + i + 2)); /* data off */ - bytestream_put_buffer(&poutbufp, buf + 2, buf_size - 2); /* skip already written SOI */ - *poutbuf_size = poutbufp - *poutbuf; - return 1; - case APP1: - if (i + 8 < buf_size && AV_RL32(buf + i + 8) == AV_RL32("mjpg")) { - av_log(avctx, AV_LOG_ERROR, "bitstream already formatted\n"); - memcpy(*poutbuf, buf, buf_size); - *poutbuf_size = buf_size; - return 1; - } - } - } - } - av_freep(poutbuf); - av_log(avctx, AV_LOG_ERROR, "could not find SOS marker in bitstream\n"); - return 0; -} - -AVBitStreamFilter mjpega_dump_header_bsf = { - "mjpegadump", - 0, - mjpega_dump_header, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpegbdec.c b/tizen/distrib/ffmpeg/libavcodec/mjpegbdec.c deleted file mode 100644 index b418f57..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpegbdec.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Apple MJPEG-B decoder - * Copyright (c) 2002 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Apple MJPEG-B decoder. - */ - -#include "avcodec.h" -#include "mjpeg.h" -#include "mjpegdec.h" - -static uint32_t read_offs(AVCodecContext *avctx, GetBitContext *gb, uint32_t size, const char *err_msg){ - uint32_t offs= get_bits_long(gb, 32); - if(offs >= size){ - av_log(avctx, AV_LOG_WARNING, err_msg, offs, size); - return 0; - } - return offs; -} - -static int mjpegb_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MJpegDecodeContext *s = avctx->priv_data; - const uint8_t *buf_end, *buf_ptr; - AVFrame *picture = data; - GetBitContext hgb; /* for the header */ - uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs; - uint32_t field_size, sod_offs; - - buf_ptr = buf; - buf_end = buf + buf_size; - -read_header: - /* reset on every SOI */ - s->restart_interval = 0; - s->restart_count = 0; - s->mjpb_skiptosod = 0; - - init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); - - skip_bits(&hgb, 32); /* reserved zeros */ - - if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) - { - av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); - return 0; - } - - field_size = get_bits_long(&hgb, 32); /* field size */ - av_log(avctx, AV_LOG_DEBUG, "field size: 0x%x\n", field_size); - skip_bits(&hgb, 32); /* padded field size */ - second_field_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "second_field_offs is %d and size is %d\n"); - av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%x\n", second_field_offs); - - dqt_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dqt is %d and size is %d\n"); - av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%x\n", dqt_offs); - if (dqt_offs) - { - init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - (buf_ptr+dqt_offs))*8); - s->start_code = DQT; - ff_mjpeg_decode_dqt(s); - } - - dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size is %d\n"); - av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%x\n", dht_offs); - if (dht_offs) - { - init_get_bits(&s->gb, buf_ptr+dht_offs, (buf_end - (buf_ptr+dht_offs))*8); - s->start_code = DHT; - ff_mjpeg_decode_dht(s); - } - - sof_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); - av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%x\n", sof_offs); - if (sof_offs) - { - init_get_bits(&s->gb, buf_ptr+sof_offs, (buf_end - (buf_ptr+sof_offs))*8); - s->start_code = SOF0; - if (ff_mjpeg_decode_sof(s) < 0) - return -1; - } - - sos_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sos is %d and size is %d\n"); - av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%x\n", sos_offs); - sod_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); - av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs); - if (sos_offs) - { -// init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8); - init_get_bits(&s->gb, buf_ptr+sos_offs, field_size*8); - s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); - s->start_code = SOS; - ff_mjpeg_decode_sos(s); - } - - if (s->interlaced) { - s->bottom_field ^= 1; - /* if not bottom field, do not output image yet */ - if (s->bottom_field != s->interlace_polarity && second_field_offs) - { - buf_ptr = buf + second_field_offs; - second_field_offs = 0; - goto read_header; - } - } - - //XXX FIXME factorize, this looks very similar to the EOI code - - *picture= s->picture; - *data_size = sizeof(AVFrame); - - if(!s->lossless){ - picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]); - picture->qstride= 0; - picture->qscale_table= s->qscale_table; - memset(picture->qscale_table, picture->quality, (s->width+15)/16); - if(avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality); - picture->quality*= FF_QP2LAMBDA; - } - - return buf_ptr - buf; -} - -AVCodec mjpegb_decoder = { - "mjpegb", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MJPEGB, - sizeof(MJpegDecodeContext), - ff_mjpeg_decode_init, - NULL, - ff_mjpeg_decode_end, - mjpegb_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpegdec.c b/tizen/distrib/ffmpeg/libavcodec/mjpegdec.c deleted file mode 100644 index 7f57af9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpegdec.c +++ /dev/null @@ -1,1560 +0,0 @@ -/* - * MJPEG decoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer - * - * Support for external huffman table, various fixes (AVID workaround), - * aspecting, new decode_frame mechanism and apple mjpeg-b support - * by Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MJPEG decoder. - */ - -//#define DEBUG -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "mjpeg.h" -#include "mjpegdec.h" -#include "jpeglsdec.h" - - -static int build_vlc(VLC *vlc, const uint8_t *bits_table, const uint8_t *val_table, - int nb_codes, int use_static, int is_ac) -{ - uint8_t huff_size[256+16]; - uint16_t huff_code[256+16]; - - assert(nb_codes <= 256); - - memset(huff_size, 0, sizeof(huff_size)); - ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table); - - if(is_ac){ - memmove(huff_size+16, huff_size, sizeof(uint8_t)*nb_codes); - memmove(huff_code+16, huff_code, sizeof(uint16_t)*nb_codes); - memset(huff_size, 0, sizeof(uint8_t)*16); - memset(huff_code, 0, sizeof(uint16_t)*16); - nb_codes += 16; - } - - return init_vlc(vlc, 9, nb_codes, huff_size, 1, 1, huff_code, 2, 2, use_static); -} - -static void build_basic_mjpeg_vlc(MJpegDecodeContext * s) { - build_vlc(&s->vlcs[0][0], ff_mjpeg_bits_dc_luminance, - ff_mjpeg_val_dc, 12, 0, 0); - build_vlc(&s->vlcs[0][1], ff_mjpeg_bits_dc_chrominance, - ff_mjpeg_val_dc, 12, 0, 0); - build_vlc(&s->vlcs[1][0], ff_mjpeg_bits_ac_luminance, - ff_mjpeg_val_ac_luminance, 251, 0, 1); - build_vlc(&s->vlcs[1][1], ff_mjpeg_bits_ac_chrominance, - ff_mjpeg_val_ac_chrominance, 251, 0, 1); -} - -av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) -{ - MJpegDecodeContext *s = avctx->priv_data; - - s->avctx = avctx; - dsputil_init(&s->dsp, avctx); - ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); - s->buffer_size = 0; - s->buffer = NULL; - s->start_code = -1; - s->first_picture = 1; - s->org_height = avctx->coded_height; - avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; - - build_basic_mjpeg_vlc(s); - - if (avctx->flags & CODEC_FLAG_EXTERN_HUFF) - { - av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n"); - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); - if (ff_mjpeg_decode_dht(s)) { - av_log(avctx, AV_LOG_ERROR, "mjpeg: error using external huffman table, switching back to internal\n"); - build_basic_mjpeg_vlc(s); - } - } - if (avctx->extradata_size > 9 && - AV_RL32(avctx->extradata + 4) == MKTAG('f','i','e','l')) { - if (avctx->extradata[9] == 6) { /* quicktime icefloe 019 */ - s->interlace_polarity = 1; /* bottom field first */ - av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n"); - } - } - if (avctx->codec->id == CODEC_ID_AMV) - s->flipped = 1; - - return 0; -} - - -/* quantize tables */ -int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) -{ - int len, index, i, j; - - len = get_bits(&s->gb, 16) - 2; - - while (len >= 65) { - /* only 8 bit precision handled */ - if (get_bits(&s->gb, 4) != 0) - { - av_log(s->avctx, AV_LOG_ERROR, "dqt: 16bit precision\n"); - return -1; - } - index = get_bits(&s->gb, 4); - if (index >= 4) - return -1; - av_log(s->avctx, AV_LOG_DEBUG, "index=%d\n", index); - /* read quant table */ - for(i=0;i<64;i++) { - j = s->scantable.permutated[i]; - s->quant_matrixes[index][j] = get_bits(&s->gb, 8); - } - - //XXX FIXME finetune, and perhaps add dc too - s->qscale[index]= FFMAX( - s->quant_matrixes[index][s->scantable.permutated[1]], - s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1; - av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n", index, s->qscale[index]); - len -= 65; - } - - return 0; -} - -/* decode huffman tables and build VLC decoders */ -int ff_mjpeg_decode_dht(MJpegDecodeContext *s) -{ - int len, index, i, class, n, v, code_max; - uint8_t bits_table[17]; - uint8_t val_table[256]; - - len = get_bits(&s->gb, 16) - 2; - - while (len > 0) { - if (len < 17) - return -1; - class = get_bits(&s->gb, 4); - if (class >= 2) - return -1; - index = get_bits(&s->gb, 4); - if (index >= 4) - return -1; - n = 0; - for(i=1;i<=16;i++) { - bits_table[i] = get_bits(&s->gb, 8); - n += bits_table[i]; - } - len -= 17; - if (len < n || n > 256) - return -1; - - code_max = 0; - for(i=0;igb, 8); - if (v > code_max) - code_max = v; - val_table[i] = v; - } - len -= n; - - /* build VLC and flush previous vlc if present */ - free_vlc(&s->vlcs[class][index]); - av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n", - class, index, code_max + 1); - if(build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1, 0, class > 0) < 0){ - return -1; - } - } - return 0; -} - -int ff_mjpeg_decode_sof(MJpegDecodeContext *s) -{ - int len, nb_components, i, width, height, pix_fmt_id; - - /* XXX: verify len field validity */ - len = get_bits(&s->gb, 16); - s->bits= get_bits(&s->gb, 8); - - if(s->pegasus_rct) s->bits=9; - if(s->bits==9 && !s->pegasus_rct) s->rct=1; //FIXME ugly - - if (s->bits != 8 && !s->lossless){ - av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n"); - return -1; - } - - height = get_bits(&s->gb, 16); - width = get_bits(&s->gb, 16); - - //HACK for odd_height.mov - if(s->interlaced && s->width == width && s->height == height + 1) - height= s->height; - - av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height); - if(avcodec_check_dimensions(s->avctx, width, height)) - return -1; - - nb_components = get_bits(&s->gb, 8); - if (nb_components <= 0 || - nb_components > MAX_COMPONENTS) - return -1; - if (s->ls && !(s->bits <= 8 || nb_components == 1)){ - av_log(s->avctx, AV_LOG_ERROR, "only <= 8 bits/component or 16-bit gray accepted for JPEG-LS\n"); - return -1; - } - s->nb_components = nb_components; - s->h_max = 1; - s->v_max = 1; - for(i=0;icomponent_id[i] = get_bits(&s->gb, 8) - 1; - s->h_count[i] = get_bits(&s->gb, 4); - s->v_count[i] = get_bits(&s->gb, 4); - /* compute hmax and vmax (only used in interleaved case) */ - if (s->h_count[i] > s->h_max) - s->h_max = s->h_count[i]; - if (s->v_count[i] > s->v_max) - s->v_max = s->v_count[i]; - s->quant_index[i] = get_bits(&s->gb, 8); - if (s->quant_index[i] >= 4) - return -1; - av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], - s->v_count[i], s->component_id[i], s->quant_index[i]); - } - - if(s->ls && (s->h_max > 1 || s->v_max > 1)) { - av_log(s->avctx, AV_LOG_ERROR, "Subsampling in JPEG-LS is not supported.\n"); - return -1; - } - - if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1; - - /* if different size, realloc/alloc picture */ - /* XXX: also check h_count and v_count */ - if (width != s->width || height != s->height) { - av_freep(&s->qscale_table); - - s->width = width; - s->height = height; - s->interlaced = 0; - - /* test interlaced mode */ - if (s->first_picture && - s->org_height != 0 && - s->height < ((s->org_height * 3) / 4)) { - s->interlaced = 1; - s->bottom_field = s->interlace_polarity; - s->picture.interlaced_frame = 1; - s->picture.top_field_first = !s->interlace_polarity; - height *= 2; - } - - avcodec_set_dimensions(s->avctx, width, height); - - s->qscale_table= av_mallocz((s->width+15)/16); - - s->first_picture = 0; - } - - if(s->interlaced && (s->bottom_field == !s->interlace_polarity)) - return 0; - - /* XXX: not complete test ! */ - pix_fmt_id = (s->h_count[0] << 28) | (s->v_count[0] << 24) | - (s->h_count[1] << 20) | (s->v_count[1] << 16) | - (s->h_count[2] << 12) | (s->v_count[2] << 8) | - (s->h_count[3] << 4) | s->v_count[3]; - av_log(s->avctx, AV_LOG_DEBUG, "pix fmt id %x\n", pix_fmt_id); - //NOTE we do not allocate pictures large enough for the possible padding of h/v_count being 4 - if(!(pix_fmt_id & 0xD0D0D0D0)) - pix_fmt_id-= (pix_fmt_id & 0xF0F0F0F0)>>1; - if(!(pix_fmt_id & 0x0D0D0D0D)) - pix_fmt_id-= (pix_fmt_id & 0x0F0F0F0F)>>1; - - switch(pix_fmt_id){ - case 0x11111100: - if(s->rgb){ - s->avctx->pix_fmt = PIX_FMT_BGRA; - }else - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; - assert(s->nb_components==3); - break; - case 0x11000000: - s->avctx->pix_fmt = PIX_FMT_GRAY8; - break; - case 0x12111100: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV440P : PIX_FMT_YUVJ440P; - break; - case 0x21111100: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P; - break; - case 0x22111100: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); - return -1; - } - if(s->ls){ - if(s->nb_components > 1) - s->avctx->pix_fmt = PIX_FMT_RGB24; - else if(s->bits <= 8) - s->avctx->pix_fmt = PIX_FMT_GRAY8; - else - s->avctx->pix_fmt = PIX_FMT_GRAY16; - } - - if(s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - - s->picture.reference= 0; - if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - s->picture.pict_type= FF_I_TYPE; - s->picture.key_frame= 1; - s->got_picture = 1; - - for(i=0; i<3; i++){ - s->linesize[i]= s->picture.linesize[i] << s->interlaced; - } - -// printf("%d %d %d %d %d %d\n", s->width, s->height, s->linesize[0], s->linesize[1], s->interlaced, s->avctx->height); - - if (len != (8+(3*nb_components))) - { - av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len); - } - - /* totally blank picture as progressive JPEG will only add details to it */ - if(s->progressive){ - int bw = (width + s->h_max*8-1) / (s->h_max*8); - int bh = (height + s->v_max*8-1) / (s->v_max*8); - for(i=0; inb_components; i++) { - int size = bw * bh * s->h_count[i] * s->v_count[i]; - av_freep(&s->blocks[i]); - av_freep(&s->last_nnz[i]); - s->blocks[i] = av_malloc(size * sizeof(**s->blocks)); - s->last_nnz[i] = av_mallocz(size * sizeof(**s->last_nnz)); - s->block_stride[i] = bw * s->h_count[i]; - } - memset(s->coefs_finished, 0, sizeof(s->coefs_finished)); - } - return 0; -} - -static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index) -{ - int code; - code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2); - if (code < 0) - { - av_log(s->avctx, AV_LOG_WARNING, "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index, - &s->vlcs[0][dc_index]); - return 0xffff; - } - - if(code) - return get_xbits(&s->gb, code); - else - return 0; -} - -/* decode block and dequantize */ -static int decode_block(MJpegDecodeContext *s, DCTELEM *block, - int component, int dc_index, int ac_index, int16_t *quant_matrix) -{ - int code, i, j, level, val; - - /* DC coef */ - val = mjpeg_decode_dc(s, dc_index); - if (val == 0xffff) { - av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); - return -1; - } - val = val * quant_matrix[0] + s->last_dc[component]; - s->last_dc[component] = val; - block[0] = val; - /* AC coefs */ - i = 0; - {OPEN_READER(re, &s->gb) - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) - - /* EOB */ - if (code == 0x10) - break; - i += ((unsigned)code) >> 4; - if(code != 0x100){ - code &= 0xf; - if(code > MIN_CACHE_BITS - 16){ - UPDATE_CACHE(re, &s->gb) - } - { - int cache=GET_CACHE(re,&s->gb); - int sign=(~cache)>>31; - level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; - } - - LAST_SKIP_BITS(re, &s->gb, code) - - if (i >= 63) { - if(i == 63){ - j = s->scantable.permutated[63]; - block[j] = level * quant_matrix[j]; - break; - } - av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); - return -1; - } - j = s->scantable.permutated[i]; - block[j] = level * quant_matrix[j]; - } - } - CLOSE_READER(re, &s->gb)} - - return 0; -} - -static int decode_dc_progressive(MJpegDecodeContext *s, DCTELEM *block, int component, - int dc_index, int16_t *quant_matrix, int Al) -{ - int val; - s->dsp.clear_block(block); - val = mjpeg_decode_dc(s, dc_index); - if (val == 0xffff) { - av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); - return -1; - } - val = (val * quant_matrix[0] << Al) + s->last_dc[component]; - s->last_dc[component] = val; - block[0] = val; - return 0; -} - -/* decode block and dequantize - progressive JPEG version */ -static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block, uint8_t *last_nnz, - int ac_index, int16_t *quant_matrix, - int ss, int se, int Al, int *EOBRUN) -{ - int code, i, j, level, val, run; - - if(*EOBRUN){ - (*EOBRUN)--; - return 0; - } - {OPEN_READER(re, &s->gb) - for(i=ss;;i++) { - UPDATE_CACHE(re, &s->gb); - GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) - /* Progressive JPEG use AC coeffs from zero and this decoder sets offset 16 by default */ - code -= 16; - if(code & 0xF) { - i += ((unsigned) code) >> 4; - code &= 0xf; - if(code > MIN_CACHE_BITS - 16){ - UPDATE_CACHE(re, &s->gb) - } - { - int cache=GET_CACHE(re,&s->gb); - int sign=(~cache)>>31; - level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; - } - - LAST_SKIP_BITS(re, &s->gb, code) - - if (i >= se) { - if(i == se){ - j = s->scantable.permutated[se]; - block[j] = level * quant_matrix[j] << Al; - break; - } - av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); - return -1; - } - j = s->scantable.permutated[i]; - block[j] = level * quant_matrix[j] << Al; - }else{ - run = ((unsigned) code) >> 4; - if(run == 0xF){// ZRL - skip 15 coefficients - i += 15; - }else{ - val = run; - run = (1 << run); - UPDATE_CACHE(re, &s->gb); - run += (GET_CACHE(re, &s->gb) >> (32 - val)) & (run - 1); - if(val) - LAST_SKIP_BITS(re, &s->gb, val); - *EOBRUN = run - 1; - break; - } - } - } - CLOSE_READER(re, &s->gb)} - if(i > *last_nnz) - *last_nnz = i; - return 0; -} - -#define REFINE_BIT(j) {\ - UPDATE_CACHE(re, &s->gb);\ - sign = block[j]>>15;\ - block[j] += SHOW_UBITS(re, &s->gb, 1) * ((quant_matrix[j]^sign)-sign) << Al;\ - LAST_SKIP_BITS(re, &s->gb, 1);\ -} - -#define ZERO_RUN \ -for(;;i++) {\ - if(i > last) {\ - i += run;\ - if(i > se) {\ - av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);\ - return -1;\ - }\ - break;\ - }\ - j = s->scantable.permutated[i];\ - if(block[j])\ - REFINE_BIT(j)\ - else if(run-- == 0)\ - break;\ -} - -/* decode block and dequantize - progressive JPEG refinement pass */ -static int decode_block_refinement(MJpegDecodeContext *s, DCTELEM *block, uint8_t *last_nnz, - int ac_index, int16_t *quant_matrix, - int ss, int se, int Al, int *EOBRUN) -{ - int code, i=ss, j, sign, val, run; - int last = FFMIN(se, *last_nnz); - - OPEN_READER(re, &s->gb); - if(*EOBRUN) - (*EOBRUN)--; - else { - for(;;i++) { - UPDATE_CACHE(re, &s->gb); - GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) - /* Progressive JPEG use AC coeffs from zero and this decoder sets offset 16 by default */ - code -= 16; - if(code & 0xF) { - run = ((unsigned) code) >> 4; - UPDATE_CACHE(re, &s->gb); - val = SHOW_UBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - ZERO_RUN; - j = s->scantable.permutated[i]; - val--; - block[j] = ((quant_matrix[j]^val)-val) << Al; - if(i == se) { - if(i > *last_nnz) - *last_nnz = i; - CLOSE_READER(re, &s->gb) - return 0; - } - }else{ - run = ((unsigned) code) >> 4; - if(run == 0xF){ - ZERO_RUN; - }else{ - val = run; - run = (1 << run); - if(val) { - UPDATE_CACHE(re, &s->gb); - run += SHOW_UBITS(re, &s->gb, val); - LAST_SKIP_BITS(re, &s->gb, val); - } - *EOBRUN = run - 1; - break; - } - } - } - - if(i > *last_nnz) - *last_nnz = i; - } - - for(;i<=last;i++) { - j = s->scantable.permutated[i]; - if(block[j]) - REFINE_BIT(j) - } - CLOSE_READER(re, &s->gb); - - return 0; -} -#undef REFINE_BIT -#undef ZERO_RUN - -static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point_transform){ - int i, mb_x, mb_y; - uint16_t (*buffer)[4]; - int left[3], top[3], topleft[3]; - const int linesize= s->linesize[0]; - const int mask= (1<bits)-1; - - av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0])); - buffer= s->ljpeg_buffer; - - for(i=0; i<3; i++){ - buffer[0][i]= 1 << (s->bits + point_transform - 1); - } - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { - const int modified_predictor= mb_y ? predictor : 1; - uint8_t *ptr = s->picture.data[0] + (linesize * mb_y); - - if (s->interlaced && s->bottom_field) - ptr += linesize >> 1; - - for(i=0; i<3; i++){ - top[i]= left[i]= topleft[i]= buffer[0][i]; - } - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - if (s->restart_interval && !s->restart_count) - s->restart_count = s->restart_interval; - - for(i=0;i<3;i++) { - int pred; - - topleft[i]= top[i]; - top[i]= buffer[mb_x][i]; - - PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); - - left[i]= - buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform)); - } - - if (s->restart_interval && !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - } - } - - if(s->rct){ - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200)>>2); - ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; - ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; - } - }else if(s->pegasus_rct){ - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2])>>2); - ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; - ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; - } - }else{ - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[4*mb_x+0] = buffer[mb_x][2]; - ptr[4*mb_x+1] = buffer[mb_x][1]; - ptr[4*mb_x+2] = buffer[mb_x][0]; - } - } - } - return 0; -} - -static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point_transform){ - int i, mb_x, mb_y; - const int nb_components=3; - - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - if (s->restart_interval && !s->restart_count) - s->restart_count = s->restart_interval; - - if(mb_x==0 || mb_y==0 || s->interlaced){ - for(i=0;inb_blocks[i]; - c = s->comp_index[i]; - h = s->h_scount[i]; - v = s->v_scount[i]; - x = 0; - y = 0; - linesize= s->linesize[c]; - - for(j=0; jpicture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - if(y==0 && mb_y==0){ - if(x==0 && mb_x==0){ - pred= 128 << point_transform; - }else{ - pred= ptr[-1]; - } - }else{ - if(x==0 && mb_x==0){ - pred= ptr[-linesize]; - }else{ - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - } - } - - if (s->interlaced && s->bottom_field) - ptr += linesize >> 1; - *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); - - if (++x == h) { - x = 0; - y++; - } - } - } - }else{ - for(i=0;inb_blocks[i]; - c = s->comp_index[i]; - h = s->h_scount[i]; - v = s->v_scount[i]; - x = 0; - y = 0; - linesize= s->linesize[c]; - - for(j=0; jpicture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); - if (++x == h) { - x = 0; - y++; - } - } - } - } - if (s->restart_interval && !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - } - } - } - return 0; -} - -static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, int Al){ - int i, mb_x, mb_y; - uint8_t* data[MAX_COMPONENTS]; - int linesize[MAX_COMPONENTS]; - - if(s->flipped && s->avctx->flags & CODEC_FLAG_EMU_EDGE) { - av_log(s->avctx, AV_LOG_ERROR, "Can not flip image with CODEC_FLAG_EMU_EDGE set!\n"); - s->flipped = 0; - } - for(i=0; i < nb_components; i++) { - int c = s->comp_index[i]; - data[c] = s->picture.data[c]; - linesize[c]=s->linesize[c]; - s->coefs_finished[c] |= 1; - if(s->flipped) { - //picture should be flipped upside-down for this codec - data[c] += (linesize[c] * (s->v_scount[i] * (8 * s->mb_height -((s->height/s->v_max)&7)) - 1 )); - linesize[c] *= -1; - } - } - - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - if (s->restart_interval && !s->restart_count) - s->restart_count = s->restart_interval; - - for(i=0;inb_blocks[i]; - c = s->comp_index[i]; - h = s->h_scount[i]; - v = s->v_scount[i]; - x = 0; - y = 0; - for(j=0;j> s->avctx->lowres); - if(s->interlaced && s->bottom_field) - ptr += linesize[c] >> 1; - if(!s->progressive) { - s->dsp.clear_block(s->block); - if(decode_block(s, s->block, i, - s->dc_index[i], s->ac_index[i], - s->quant_matrixes[ s->quant_index[c] ]) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); - return -1; - } - s->dsp.idct_put(ptr, linesize[c], s->block); - } else { - int block_idx = s->block_stride[c] * (v * mb_y + y) + (h * mb_x + x); - DCTELEM *block = s->blocks[c][block_idx]; - if(Ah) - block[0] += get_bits1(&s->gb) * s->quant_matrixes[ s->quant_index[c] ][0] << Al; - else if(decode_dc_progressive(s, block, i, s->dc_index[i], s->quant_matrixes[ s->quant_index[c] ], Al) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); - return -1; - } - } -// av_log(s->avctx, AV_LOG_DEBUG, "mb: %d %d processed\n", mb_y, mb_x); -//av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d \n", mb_x, mb_y, x, y, c, s->bottom_field, (v * mb_y + y) * 8, (h * mb_x + x) * 8); - if (++x == h) { - x = 0; - y++; - } - } - } - - if (s->restart_interval && !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - for (i=0; ilast_dc[i] = 1024; - } - } - } - return 0; -} - -static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int se, int Ah, int Al){ - int mb_x, mb_y; - int EOBRUN = 0; - int c = s->comp_index[0]; - uint8_t* data = s->picture.data[c]; - int linesize = s->linesize[c]; - int last_scan = 0; - int16_t *quant_matrix = s->quant_matrixes[ s->quant_index[c] ]; - - if(!Al) { - s->coefs_finished[c] |= (1LL<<(se+1))-(1LL<coefs_finished[c]; - } - - if(s->interlaced && s->bottom_field) - data += linesize >> 1; - - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { - uint8_t *ptr = data + (mb_y*linesize*8 >> s->avctx->lowres); - int block_idx = mb_y * s->block_stride[c]; - DCTELEM (*block)[64] = &s->blocks[c][block_idx]; - uint8_t *last_nnz = &s->last_nnz[c][block_idx]; - for(mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) { - int ret; - if(Ah) - ret = decode_block_refinement(s, *block, last_nnz, s->ac_index[0], - quant_matrix, ss, se, Al, &EOBRUN); - else - ret = decode_block_progressive(s, *block, last_nnz, s->ac_index[0], - quant_matrix, ss, se, Al, &EOBRUN); - if(ret < 0) { - av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); - return -1; - } - if(last_scan) { - s->dsp.idct_put(ptr, linesize, *block); - ptr += 8 >> s->avctx->lowres; - } - } - } - return 0; -} - -int ff_mjpeg_decode_sos(MJpegDecodeContext *s) -{ - int len, nb_components, i, h, v, predictor, point_transform; - int index, id; - const int block_size= s->lossless ? 1 : 8; - int ilv, prev_shift; - - /* XXX: verify len field validity */ - len = get_bits(&s->gb, 16); - nb_components = get_bits(&s->gb, 8); - if (nb_components == 0 || nb_components > MAX_COMPONENTS){ - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: nb_components (%d) unsupported\n", nb_components); - return -1; - } - if (len != 6+2*nb_components) - { - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len); - return -1; - } - for(i=0;igb, 8) - 1; - av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id); - /* find component index */ - for(index=0;indexnb_components;index++) - if (id == s->component_id[index]) - break; - if (index == s->nb_components) - { - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: index(%d) out of components\n", index); - return -1; - } - /* Metasoft MJPEG codec has Cb and Cr swapped */ - if (s->avctx->codec_tag == MKTAG('M', 'T', 'S', 'J') - && nb_components == 3 && s->nb_components == 3 && i) - index = 3 - i; - - s->comp_index[i] = index; - - s->nb_blocks[i] = s->h_count[index] * s->v_count[index]; - s->h_scount[i] = s->h_count[index]; - s->v_scount[i] = s->v_count[index]; - - s->dc_index[i] = get_bits(&s->gb, 4); - s->ac_index[i] = get_bits(&s->gb, 4); - - if (s->dc_index[i] < 0 || s->ac_index[i] < 0 || - s->dc_index[i] >= 4 || s->ac_index[i] >= 4) - goto out_of_range; - if (!s->vlcs[0][s->dc_index[i]].table || !s->vlcs[1][s->ac_index[i]].table) - goto out_of_range; - } - - predictor= get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */ - ilv= get_bits(&s->gb, 8); /* JPEG Se / JPEG-LS ILV */ - prev_shift = get_bits(&s->gb, 4); /* Ah */ - point_transform= get_bits(&s->gb, 4); /* Al */ - - for(i=0;ilast_dc[i] = 1024; - - if (nb_components > 1) { - /* interleaved stream */ - s->mb_width = (s->width + s->h_max * block_size - 1) / (s->h_max * block_size); - s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size); - } else if(!s->ls) { /* skip this for JPEG-LS */ - h = s->h_max / s->h_scount[0]; - v = s->v_max / s->v_scount[0]; - s->mb_width = (s->width + h * block_size - 1) / (h * block_size); - s->mb_height = (s->height + v * block_size - 1) / (v * block_size); - s->nb_blocks[0] = 1; - s->h_scount[0] = 1; - s->v_scount[0] = 1; - } - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d %s\n", s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "", - predictor, point_transform, ilv, s->bits, - s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : "")); - - - /* mjpeg-b can have padding bytes between sos and image data, skip them */ - for (i = s->mjpb_skiptosod; i > 0; i--) - skip_bits(&s->gb, 8); - - if(s->lossless){ - if(CONFIG_JPEGLS_DECODER && s->ls){ -// for(){ -// reset_ls_coding_parameters(s, 0); - - if(ff_jpegls_decode_picture(s, predictor, point_transform, ilv) < 0) - return -1; - }else{ - if(s->rgb){ - if(ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0) - return -1; - }else{ - if(ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0) - return -1; - } - } - }else{ - if(s->progressive && predictor) { - if(mjpeg_decode_scan_progressive_ac(s, predictor, ilv, prev_shift, point_transform) < 0) - return -1; - } else { - if(mjpeg_decode_scan(s, nb_components, prev_shift, point_transform) < 0) - return -1; - } - } - emms_c(); - return 0; - out_of_range: - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n"); - return -1; -} - -static int mjpeg_decode_dri(MJpegDecodeContext *s) -{ - if (get_bits(&s->gb, 16) != 4) - return -1; - s->restart_interval = get_bits(&s->gb, 16); - s->restart_count = 0; - av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n", s->restart_interval); - - return 0; -} - -static int mjpeg_decode_app(MJpegDecodeContext *s) -{ - int len, id, i; - - len = get_bits(&s->gb, 16); - if (len < 5) - return -1; - if(8*len + get_bits_count(&s->gb) > s->gb.size_in_bits) - return -1; - - id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); - id = be2me_32(id); - len -= 6; - - if(s->avctx->debug & FF_DEBUG_STARTCODE){ - av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X\n", id); - } - - /* buggy AVID, it puts EOI only at every 10th frame */ - /* also this fourcc is used by non-avid files too, it holds some - informations, but it's always present in AVID creates files */ - if (id == AV_RL32("AVI1")) - { - /* structure: - 4bytes AVI1 - 1bytes polarity - 1bytes always zero - 4bytes field_size - 4bytes field_size_less_padding - */ - s->buggy_avid = 1; -// if (s->first_picture) -// printf("mjpeg: workarounding buggy AVID\n"); - i = get_bits(&s->gb, 8); - if (i==2) s->bottom_field= 1; - else if(i==1) s->bottom_field= 0; -#if 0 - skip_bits(&s->gb, 8); - skip_bits(&s->gb, 32); - skip_bits(&s->gb, 32); - len -= 10; -#endif -// if (s->interlace_polarity) -// printf("mjpeg: interlace polarity: %d\n", s->interlace_polarity); - goto out; - } - -// len -= 2; - - if (id == AV_RL32("JFIF")) - { - int t_w, t_h, v1, v2; - skip_bits(&s->gb, 8); /* the trailing zero-byte */ - v1= get_bits(&s->gb, 8); - v2= get_bits(&s->gb, 8); - skip_bits(&s->gb, 8); - - s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 16); - s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 16); - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg: JFIF header found (version: %x.%x) SAR=%d/%d\n", - v1, v2, - s->avctx->sample_aspect_ratio.num, - s->avctx->sample_aspect_ratio.den - ); - - t_w = get_bits(&s->gb, 8); - t_h = get_bits(&s->gb, 8); - if (t_w && t_h) - { - /* skip thumbnail */ - if (len-10-(t_w*t_h*3) > 0) - len -= t_w*t_h*3; - } - len -= 10; - goto out; - } - - if (id == AV_RL32("Adob") && (get_bits(&s->gb, 8) == 'e')) - { - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg: Adobe header found\n"); - skip_bits(&s->gb, 16); /* version */ - skip_bits(&s->gb, 16); /* flags0 */ - skip_bits(&s->gb, 16); /* flags1 */ - skip_bits(&s->gb, 8); /* transform */ - len -= 7; - goto out; - } - - if (id == AV_RL32("LJIF")){ - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "Pegasus lossless jpeg header found\n"); - skip_bits(&s->gb, 16); /* version ? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - switch( get_bits(&s->gb, 8)){ - case 1: - s->rgb= 1; - s->pegasus_rct=0; - break; - case 2: - s->rgb= 1; - s->pegasus_rct=1; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace\n"); - } - len -= 9; - goto out; - } - - /* Apple MJPEG-A */ - if ((s->start_code == APP1) && (len > (0x28 - 8))) - { - id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); - id = be2me_32(id); - len -= 4; - if (id == AV_RL32("mjpg")) /* Apple MJPEG-A */ - { -#if 0 - skip_bits(&s->gb, 32); /* field size */ - skip_bits(&s->gb, 32); /* pad field size */ - skip_bits(&s->gb, 32); /* next off */ - skip_bits(&s->gb, 32); /* quant off */ - skip_bits(&s->gb, 32); /* huff off */ - skip_bits(&s->gb, 32); /* image off */ - skip_bits(&s->gb, 32); /* scan off */ - skip_bits(&s->gb, 32); /* data off */ -#endif - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg: Apple MJPEG-A header found\n"); - } - } - -out: - /* slow but needed for extreme adobe jpegs */ - if (len < 0) - av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error, decode_app parser read over the end\n"); - while(--len > 0) - skip_bits(&s->gb, 8); - - return 0; -} - -static int mjpeg_decode_com(MJpegDecodeContext *s) -{ - int len = get_bits(&s->gb, 16); - if (len >= 2 && 8*len - 16 + get_bits_count(&s->gb) <= s->gb.size_in_bits) { - char *cbuf = av_malloc(len - 1); - if (cbuf) { - int i; - for (i = 0; i < len - 2; i++) - cbuf[i] = get_bits(&s->gb, 8); - if (i > 0 && cbuf[i-1] == '\n') - cbuf[i-1] = 0; - else - cbuf[i] = 0; - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg comment: '%s'\n", cbuf); - - /* buggy avid, it puts EOI only at every 10th frame */ - if (!strcmp(cbuf, "AVID")) - { - s->buggy_avid = 1; - // if (s->first_picture) - // printf("mjpeg: workarounding buggy AVID\n"); - } - else if(!strcmp(cbuf, "CS=ITU601")){ - s->cs_itu601= 1; - } - else if((len > 20 && !strncmp(cbuf, "Intel(R) JPEG Library", 21)) || - (len > 19 && !strncmp(cbuf, "Metasoft MJPEG Codec", 20))){ - s->flipped = 1; - } - - av_free(cbuf); - } - } - - return 0; -} - -#if 0 -static int valid_marker_list[] = -{ - /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */ -/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -} -#endif - -/* return the 8 bit start code value and update the search - state. Return -1 if no start code found */ -static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end) -{ - const uint8_t *buf_ptr; - unsigned int v, v2; - int val; -#ifdef DEBUG - int skipped=0; -#endif - - buf_ptr = *pbuf_ptr; - while (buf_ptr < buf_end) { - v = *buf_ptr++; - v2 = *buf_ptr; - if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_ptr < buf_end) { - val = *buf_ptr++; - goto found; - } -#ifdef DEBUG - skipped++; -#endif - } - val = -1; -found: - dprintf(NULL, "find_marker skipped %d bytes\n", skipped); - *pbuf_ptr = buf_ptr; - return val; -} - -int ff_mjpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MJpegDecodeContext *s = avctx->priv_data; - const uint8_t *buf_end, *buf_ptr; - int start_code; - AVFrame *picture = data; - - s->got_picture = 0; // picture from previous image can not be reused - buf_ptr = buf; - buf_end = buf + buf_size; - while (buf_ptr < buf_end) { - /* find start next marker */ - start_code = find_marker(&buf_ptr, buf_end); - { - /* EOF */ - if (start_code < 0) { - goto the_end; - } else { - av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", start_code, buf_end - buf_ptr); - - if ((buf_end - buf_ptr) > s->buffer_size) - { - av_free(s->buffer); - s->buffer_size = buf_end-buf_ptr; - s->buffer = av_malloc(s->buffer_size + FF_INPUT_BUFFER_PADDING_SIZE); - av_log(avctx, AV_LOG_DEBUG, "buffer too small, expanding to %d bytes\n", - s->buffer_size); - } - - /* unescape buffer of SOS, use special treatment for JPEG-LS */ - if (start_code == SOS && !s->ls) - { - const uint8_t *src = buf_ptr; - uint8_t *dst = s->buffer; - - while (srccodec_id != CODEC_ID_THP) - { - if (x == 0xff) { - while (src < buf_end && x == 0xff) - x = *(src++); - - if (x >= 0xd0 && x <= 0xd7) - *(dst++) = x; - else if (x) - break; - } - } - } - init_get_bits(&s->gb, s->buffer, (dst - s->buffer)*8); - - av_log(avctx, AV_LOG_DEBUG, "escaping removed %td bytes\n", - (buf_end - buf_ptr) - (dst - s->buffer)); - } - else if(start_code == SOS && s->ls){ - const uint8_t *src = buf_ptr; - uint8_t *dst = s->buffer; - int bit_count = 0; - int t = 0, b = 0; - PutBitContext pb; - - s->cur_scan++; - - /* find marker */ - while (src + t < buf_end){ - uint8_t x = src[t++]; - if (x == 0xff){ - while((src + t < buf_end) && x == 0xff) - x = src[t++]; - if (x & 0x80) { - t -= 2; - break; - } - } - } - bit_count = t * 8; - - init_put_bits(&pb, dst, t); - - /* unescape bitstream */ - while(b < t){ - uint8_t x = src[b++]; - put_bits(&pb, 8, x); - if(x == 0xFF){ - x = src[b++]; - put_bits(&pb, 7, x); - bit_count--; - } - } - flush_put_bits(&pb); - - init_get_bits(&s->gb, dst, bit_count); - } - else - init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8); - - s->start_code = start_code; - if(s->avctx->debug & FF_DEBUG_STARTCODE){ - av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); - } - - /* process markers */ - if (start_code >= 0xd0 && start_code <= 0xd7) { - av_log(avctx, AV_LOG_DEBUG, "restart marker: %d\n", start_code&0x0f); - /* APP fields */ - } else if (start_code >= APP0 && start_code <= APP15) { - mjpeg_decode_app(s); - /* Comment */ - } else if (start_code == COM){ - mjpeg_decode_com(s); - } - - switch(start_code) { - case SOI: - s->restart_interval = 0; - - s->restart_count = 0; - /* nothing to do on SOI */ - break; - case DQT: - ff_mjpeg_decode_dqt(s); - break; - case DHT: - if(ff_mjpeg_decode_dht(s) < 0){ - av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); - return -1; - } - break; - case SOF0: - case SOF1: - s->lossless=0; - s->ls=0; - s->progressive=0; - if (ff_mjpeg_decode_sof(s) < 0) - return -1; - break; - case SOF2: - s->lossless=0; - s->ls=0; - s->progressive=1; - if (ff_mjpeg_decode_sof(s) < 0) - return -1; - break; - case SOF3: - s->lossless=1; - s->ls=0; - s->progressive=0; - if (ff_mjpeg_decode_sof(s) < 0) - return -1; - break; - case SOF48: - s->lossless=1; - s->ls=1; - s->progressive=0; - if (ff_mjpeg_decode_sof(s) < 0) - return -1; - break; - case LSE: - if (!CONFIG_JPEGLS_DECODER || ff_jpegls_decode_lse(s) < 0) - return -1; - break; - case EOI: - s->cur_scan = 0; - if ((s->buggy_avid && !s->interlaced) || s->restart_interval) - break; -eoi_parser: - if (!s->got_picture) { - av_log(avctx, AV_LOG_WARNING, "Found EOI before any SOF, ignoring\n"); - break; - } - { - if (s->interlaced) { - s->bottom_field ^= 1; - /* if not bottom field, do not output image yet */ - if (s->bottom_field == !s->interlace_polarity) - goto not_the_end; - } - *picture = s->picture; - *data_size = sizeof(AVFrame); - - if(!s->lossless){ - picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]); - picture->qstride= 0; - picture->qscale_table= s->qscale_table; - memset(picture->qscale_table, picture->quality, (s->width+15)/16); - if(avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality); - picture->quality*= FF_QP2LAMBDA; - } - - goto the_end; - } - break; - case SOS: - if (!s->got_picture) { - av_log(avctx, AV_LOG_WARNING, "Can not process SOS before SOF, skipping\n"); - break; - } - ff_mjpeg_decode_sos(s); - /* buggy avid puts EOI every 10-20th frame */ - /* if restart period is over process EOI */ - if ((s->buggy_avid && !s->interlaced) || s->restart_interval) - goto eoi_parser; - break; - case DRI: - mjpeg_decode_dri(s); - break; - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - case JPG: - av_log(avctx, AV_LOG_ERROR, "mjpeg: unsupported coding type (%x)\n", start_code); - break; -// default: -// printf("mjpeg: unsupported marker (%x)\n", start_code); -// break; - } - -not_the_end: - /* eof process start code */ - buf_ptr += (get_bits_count(&s->gb)+7)/8; - av_log(avctx, AV_LOG_DEBUG, "marker parser used %d bytes (%d bits)\n", - (get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb)); - } - } - } - if (s->got_picture) { - av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n"); - goto eoi_parser; - } - av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n"); - return -1; -the_end: - av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %td bytes\n", buf_end - buf_ptr); -// return buf_end - buf_ptr; - return buf_ptr - buf; -} - -av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) -{ - MJpegDecodeContext *s = avctx->priv_data; - int i, j; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - av_free(s->buffer); - av_free(s->qscale_table); - av_freep(&s->ljpeg_buffer); - s->ljpeg_buffer_size=0; - - for(i=0;i<2;i++) { - for(j=0;j<4;j++) - free_vlc(&s->vlcs[i][j]); - } - for(i=0; iblocks[i]); - av_freep(&s->last_nnz[i]); - } - return 0; -} - -AVCodec mjpeg_decoder = { - "mjpeg", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MJPEG, - sizeof(MJpegDecodeContext), - ff_mjpeg_decode_init, - NULL, - ff_mjpeg_decode_end, - ff_mjpeg_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), -}; - -AVCodec thp_decoder = { - "thp", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_THP, - sizeof(MJpegDecodeContext), - ff_mjpeg_decode_init, - NULL, - ff_mjpeg_decode_end, - ff_mjpeg_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpegdec.h b/tizen/distrib/ffmpeg/libavcodec/mjpegdec.h deleted file mode 100644 index bbf734b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpegdec.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * MJPEG decoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MJPEG decoder. - */ - -#ifndef AVCODEC_MJPEGDEC_H -#define AVCODEC_MJPEGDEC_H - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" - -#define MAX_COMPONENTS 4 - -typedef struct MJpegDecodeContext { - AVCodecContext *avctx; - GetBitContext gb; - - int start_code; /* current start code */ - int buffer_size; - uint8_t *buffer; - - int16_t quant_matrixes[4][64]; - VLC vlcs[2][4]; - int qscale[4]; ///< quantizer scale calculated from quant_matrixes - - int org_height; /* size given at codec init */ - int first_picture; /* true if decoding first picture */ - int interlaced; /* true if interlaced */ - int bottom_field; /* true if bottom field */ - int lossless; - int ls; - int progressive; - int rgb; - int rct; /* standard rct */ - int pegasus_rct; /* pegasus reversible colorspace transform */ - int bits; /* bits per component */ - - int maxval; - int near; ///< near lossless bound (si 0 for lossless) - int t1,t2,t3; - int reset; ///< context halfing intervall ?rename - - int width, height; - int mb_width, mb_height; - int nb_components; - int block_stride[MAX_COMPONENTS]; - int component_id[MAX_COMPONENTS]; - int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */ - int v_count[MAX_COMPONENTS]; - int comp_index[MAX_COMPONENTS]; - int dc_index[MAX_COMPONENTS]; - int ac_index[MAX_COMPONENTS]; - int nb_blocks[MAX_COMPONENTS]; - int h_scount[MAX_COMPONENTS]; - int v_scount[MAX_COMPONENTS]; - int h_max, v_max; /* maximum h and v counts */ - int quant_index[4]; /* quant table index for each component */ - int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */ - AVFrame picture; /* picture structure */ - int got_picture; ///< we found a SOF and picture is valid, too. - int linesize[MAX_COMPONENTS]; ///< linesize << interlaced - int8_t *qscale_table; - DECLARE_ALIGNED(16, DCTELEM, block)[64]; - DCTELEM (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode) - uint8_t *last_nnz[MAX_COMPONENTS]; - uint64_t coefs_finished[MAX_COMPONENTS]; ///< bitmask of which coefs have been completely decoded (progressive mode) - ScanTable scantable; - DSPContext dsp; - - int restart_interval; - int restart_count; - - int buggy_avid; - int cs_itu601; - int interlace_polarity; - - int mjpb_skiptosod; - - int cur_scan; /* current scan, used by JPEG-LS */ - int flipped; /* true if picture is flipped */ - - uint16_t (*ljpeg_buffer)[4]; - unsigned int ljpeg_buffer_size; -} MJpegDecodeContext; - -int ff_mjpeg_decode_init(AVCodecContext *avctx); -int ff_mjpeg_decode_end(AVCodecContext *avctx); -int ff_mjpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt); -int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); -int ff_mjpeg_decode_dht(MJpegDecodeContext *s); -int ff_mjpeg_decode_sof(MJpegDecodeContext *s); -int ff_mjpeg_decode_sos(MJpegDecodeContext *s); - -#endif /* AVCODEC_MJPEGDEC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpegenc.c b/tizen/distrib/ffmpeg/libavcodec/mjpegenc.c deleted file mode 100644 index ec819c8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpegenc.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * MJPEG encoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer - * - * Support for external huffman table, various fixes (AVID workaround), - * aspecting, new decode_frame mechanism and apple mjpeg-b support - * by Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MJPEG encoder. - */ - -//#define DEBUG -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mjpeg.h" -#include "mjpegenc.h" - -/* use two quantizer tables (one for luminance and one for chrominance) */ -/* not yet working */ -#undef TWOMATRIXES - - -av_cold int ff_mjpeg_encode_init(MpegEncContext *s) -{ - MJpegContext *m; - - m = av_malloc(sizeof(MJpegContext)); - if (!m) - return -1; - - s->min_qcoeff=-1023; - s->max_qcoeff= 1023; - - /* build all the huffman tables */ - ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance, - m->huff_code_dc_luminance, - ff_mjpeg_bits_dc_luminance, - ff_mjpeg_val_dc); - ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance, - m->huff_code_dc_chrominance, - ff_mjpeg_bits_dc_chrominance, - ff_mjpeg_val_dc); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance, - m->huff_code_ac_luminance, - ff_mjpeg_bits_ac_luminance, - ff_mjpeg_val_ac_luminance); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance, - m->huff_code_ac_chrominance, - ff_mjpeg_bits_ac_chrominance, - ff_mjpeg_val_ac_chrominance); - - s->mjpeg_ctx = m; - return 0; -} - -void ff_mjpeg_encode_close(MpegEncContext *s) -{ - av_free(s->mjpeg_ctx); -} - -/* table_class: 0 = DC coef, 1 = AC coefs */ -static int put_huffman_table(MpegEncContext *s, int table_class, int table_id, - const uint8_t *bits_table, const uint8_t *value_table) -{ - PutBitContext *p = &s->pb; - int n, i; - - put_bits(p, 4, table_class); - put_bits(p, 4, table_id); - - n = 0; - for(i=1;i<=16;i++) { - n += bits_table[i]; - put_bits(p, 8, bits_table[i]); - } - - for(i=0;ipb; - int i, j, size; - uint8_t *ptr; - - /* quant matrixes */ - put_marker(p, DQT); -#ifdef TWOMATRIXES - put_bits(p, 16, 2 + 2 * (1 + 64)); -#else - put_bits(p, 16, 2 + 1 * (1 + 64)); -#endif - put_bits(p, 4, 0); /* 8 bit precision */ - put_bits(p, 4, 0); /* table 0 */ - for(i=0;i<64;i++) { - j = s->intra_scantable.permutated[i]; - put_bits(p, 8, s->intra_matrix[j]); - } -#ifdef TWOMATRIXES - put_bits(p, 4, 0); /* 8 bit precision */ - put_bits(p, 4, 1); /* table 1 */ - for(i=0;i<64;i++) { - j = s->intra_scantable.permutated[i]; - put_bits(p, 8, s->chroma_intra_matrix[j]); - } -#endif - - /* huffman table */ - put_marker(p, DHT); - flush_put_bits(p); - ptr = put_bits_ptr(p); - put_bits(p, 16, 0); /* patched later */ - size = 2; - size += put_huffman_table(s, 0, 0, ff_mjpeg_bits_dc_luminance, - ff_mjpeg_val_dc); - size += put_huffman_table(s, 0, 1, ff_mjpeg_bits_dc_chrominance, - ff_mjpeg_val_dc); - - size += put_huffman_table(s, 1, 0, ff_mjpeg_bits_ac_luminance, - ff_mjpeg_val_ac_luminance); - size += put_huffman_table(s, 1, 1, ff_mjpeg_bits_ac_chrominance, - ff_mjpeg_val_ac_chrominance); - AV_WB16(ptr, size); -} - -static void jpeg_put_comments(MpegEncContext *s) -{ - PutBitContext *p = &s->pb; - int size; - uint8_t *ptr; - - if (s->aspect_ratio_info /* && !lossless */) - { - /* JFIF header */ - put_marker(p, APP0); - put_bits(p, 16, 16); - ff_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ - put_bits(p, 16, 0x0201); /* v 1.02 */ - put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ - put_bits(p, 16, s->avctx->sample_aspect_ratio.num); - put_bits(p, 16, s->avctx->sample_aspect_ratio.den); - put_bits(p, 8, 0); /* thumbnail width */ - put_bits(p, 8, 0); /* thumbnail height */ - } - - /* comment */ - if(!(s->flags & CODEC_FLAG_BITEXACT)){ - put_marker(p, COM); - flush_put_bits(p); - ptr = put_bits_ptr(p); - put_bits(p, 16, 0); /* patched later */ - ff_put_string(p, LIBAVCODEC_IDENT, 1); - size = strlen(LIBAVCODEC_IDENT)+3; - AV_WB16(ptr, size); - } - - if( s->avctx->pix_fmt == PIX_FMT_YUV420P - ||s->avctx->pix_fmt == PIX_FMT_YUV422P - ||s->avctx->pix_fmt == PIX_FMT_YUV444P){ - put_marker(p, COM); - flush_put_bits(p); - ptr = put_bits_ptr(p); - put_bits(p, 16, 0); /* patched later */ - ff_put_string(p, "CS=ITU601", 1); - size = strlen("CS=ITU601")+3; - AV_WB16(ptr, size); - } -} - -void ff_mjpeg_encode_picture_header(MpegEncContext *s) -{ - const int lossless= s->avctx->codec_id != CODEC_ID_MJPEG; - - put_marker(&s->pb, SOI); - - jpeg_put_comments(s); - - jpeg_table_header(s); - - switch(s->avctx->codec_id){ - case CODEC_ID_MJPEG: put_marker(&s->pb, SOF0 ); break; - case CODEC_ID_LJPEG: put_marker(&s->pb, SOF3 ); break; - default: assert(0); - } - - put_bits(&s->pb, 16, 17); - if(lossless && s->avctx->pix_fmt == PIX_FMT_BGRA) - put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */ - else - put_bits(&s->pb, 8, 8); /* 8 bits/component */ - put_bits(&s->pb, 16, s->height); - put_bits(&s->pb, 16, s->width); - put_bits(&s->pb, 8, 3); /* 3 components */ - - /* Y component */ - put_bits(&s->pb, 8, 1); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[0]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[0]); /* V factor */ - put_bits(&s->pb, 8, 0); /* select matrix */ - - /* Cb component */ - put_bits(&s->pb, 8, 2); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ -#ifdef TWOMATRIXES - put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ -#else - put_bits(&s->pb, 8, 0); /* select matrix */ -#endif - - /* Cr component */ - put_bits(&s->pb, 8, 3); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ -#ifdef TWOMATRIXES - put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ -#else - put_bits(&s->pb, 8, 0); /* select matrix */ -#endif - - /* scan header */ - put_marker(&s->pb, SOS); - put_bits(&s->pb, 16, 12); /* length */ - put_bits(&s->pb, 8, 3); /* 3 components */ - - /* Y component */ - put_bits(&s->pb, 8, 1); /* index */ - put_bits(&s->pb, 4, 0); /* DC huffman table index */ - put_bits(&s->pb, 4, 0); /* AC huffman table index */ - - /* Cb component */ - put_bits(&s->pb, 8, 2); /* index */ - put_bits(&s->pb, 4, 1); /* DC huffman table index */ - put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ - - /* Cr component */ - put_bits(&s->pb, 8, 3); /* index */ - put_bits(&s->pb, 4, 1); /* DC huffman table index */ - put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ - - put_bits(&s->pb, 8, lossless ? s->avctx->prediction_method+1 : 0); /* Ss (not used) */ - - switch(s->avctx->codec_id){ - case CODEC_ID_MJPEG: put_bits(&s->pb, 8, 63); break; /* Se (not used) */ - case CODEC_ID_LJPEG: put_bits(&s->pb, 8, 0); break; /* not used */ - default: assert(0); - } - - put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ -} - -static void escape_FF(MpegEncContext *s, int start) -{ - int size= put_bits_count(&s->pb) - start*8; - int i, ff_count; - uint8_t *buf= s->pb.buf + start; - int align= (-(size_t)(buf))&3; - - assert((size&7) == 0); - size >>= 3; - - ff_count=0; - for(i=0; i>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - v= *(uint32_t*)(&buf[i+4]); - acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - v= *(uint32_t*)(&buf[i+8]); - acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - v= *(uint32_t*)(&buf[i+12]); - acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - - acc>>=4; - acc+= (acc>>16); - acc+= (acc>>8); - ff_count+= acc&0xFF; - } - for(; ipb); - skip_put_bytes(&s->pb, ff_count); - - for(i=size-1; ff_count; i--){ - int v= buf[i]; - - if(v==0xFF){ -//printf("%d %d\n", i, ff_count); - buf[i+ff_count]= 0; - ff_count--; - } - - buf[i+ff_count]= v; - } -} - -void ff_mjpeg_encode_stuffing(PutBitContext * pbc) -{ - int length; - length= (-put_bits_count(pbc))&7; - if(length) put_bits(pbc, length, (1<pb); - flush_put_bits(&s->pb); - - assert((s->header_bits&7)==0); - - escape_FF(s, s->header_bits>>3); - - put_marker(&s->pb, EOI); -} - -void ff_mjpeg_encode_dc(MpegEncContext *s, int val, - uint8_t *huff_size, uint16_t *huff_code) -{ - int mant, nbits; - - if (val == 0) { - put_bits(&s->pb, huff_size[0], huff_code[0]); - } else { - mant = val; - if (val < 0) { - val = -val; - mant--; - } - - nbits= av_log2_16bit(val) + 1; - - put_bits(&s->pb, huff_size[nbits], huff_code[nbits]); - - put_sbits(&s->pb, nbits, mant); - } -} - -static void encode_block(MpegEncContext *s, DCTELEM *block, int n) -{ - int mant, nbits, code, i, j; - int component, dc, run, last_index, val; - MJpegContext *m = s->mjpeg_ctx; - uint8_t *huff_size_ac; - uint16_t *huff_code_ac; - - /* DC coef */ - component = (n <= 3 ? 0 : (n&1) + 1); - dc = block[0]; /* overflow is impossible */ - val = dc - s->last_dc[component]; - if (n < 4) { - ff_mjpeg_encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); - huff_size_ac = m->huff_size_ac_luminance; - huff_code_ac = m->huff_code_ac_luminance; - } else { - ff_mjpeg_encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - huff_size_ac = m->huff_size_ac_chrominance; - huff_code_ac = m->huff_code_ac_chrominance; - } - s->last_dc[component] = dc; - - /* AC coefs */ - - run = 0; - last_index = s->block_last_index[n]; - for(i=1;i<=last_index;i++) { - j = s->intra_scantable.permutated[i]; - val = block[j]; - if (val == 0) { - run++; - } else { - while (run >= 16) { - put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]); - run -= 16; - } - mant = val; - if (val < 0) { - val = -val; - mant--; - } - - nbits= av_log2(val) + 1; - code = (run << 4) | nbits; - - put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); - - put_sbits(&s->pb, nbits, mant); - run = 0; - } - } - - /* output EOB only if not already 64 values */ - if (last_index < 63 || run != 0) - put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); -} - -void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]) -{ - int i; - for(i=0;i<5;i++) { - encode_block(s, block[i], i); - } - if (s->chroma_format == CHROMA_420) { - encode_block(s, block[5], 5); - } else { - encode_block(s, block[6], 6); - encode_block(s, block[5], 5); - encode_block(s, block[7], 7); - } -} - -AVCodec mjpeg_encoder = { - "mjpeg", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MJPEG, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mjpegenc.h b/tizen/distrib/ffmpeg/libavcodec/mjpegenc.h deleted file mode 100644 index 49627a3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mjpegenc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * MJPEG encoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer - * - * Support for external huffman table, various fixes (AVID workaround), - * aspecting, new decode_frame mechanism and apple mjpeg-b support - * by Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MJPEG encoder. - */ - -#ifndef AVCODEC_MJPEGENC_H -#define AVCODEC_MJPEGENC_H - -#include "dsputil.h" -#include "mpegvideo.h" - -typedef struct MJpegContext { - uint8_t huff_size_dc_luminance[12]; //FIXME use array [3] instead of lumi / chrom, for easier addressing - uint16_t huff_code_dc_luminance[12]; - uint8_t huff_size_dc_chrominance[12]; - uint16_t huff_code_dc_chrominance[12]; - - uint8_t huff_size_ac_luminance[256]; - uint16_t huff_code_ac_luminance[256]; - uint8_t huff_size_ac_chrominance[256]; - uint16_t huff_code_ac_chrominance[256]; -} MJpegContext; - -int ff_mjpeg_encode_init(MpegEncContext *s); -void ff_mjpeg_encode_close(MpegEncContext *s); -void ff_mjpeg_encode_picture_header(MpegEncContext *s); -void ff_mjpeg_encode_picture_trailer(MpegEncContext *s); -void ff_mjpeg_encode_stuffing(PutBitContext *pbc); -void ff_mjpeg_encode_dc(MpegEncContext *s, int val, - uint8_t *huff_size, uint16_t *huff_code); -void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]); - -#endif /* AVCODEC_MJPEGENC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c b/tizen/distrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c deleted file mode 100644 index 6be0ba4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Sun mediaLib optimized DSP utils - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" - -#include -#include -#include -#include -#include - -/* misc */ - -static void get_pixels_mlib(DCTELEM *restrict block, const uint8_t *pixels, int line_size) -{ - int i; - - for (i=0;i<8;i++) { - mlib_VectorConvert_S16_U8_Mod((mlib_s16 *)block, (mlib_u8 *)pixels, 8); - - pixels += line_size; - block += 8; - } -} - -static void diff_pixels_mlib(DCTELEM *restrict block, const uint8_t *s1, const uint8_t *s2, int line_size) -{ - int i; - - for (i=0;i<8;i++) { - mlib_VectorSub_S16_U8_Mod((mlib_s16 *)block, (mlib_u8 *)s1, (mlib_u8 *)s2, 8); - - s1 += line_size; - s2 += line_size; - block += 8; - } -} - -static void add_pixels_clamped_mlib(const DCTELEM *block, uint8_t *pixels, int line_size) -{ - mlib_VideoAddBlock_U8_S16(pixels, (mlib_s16 *)block, line_size); -} - -/* put block, width 16 pixel, height 8/16 */ - -static void put_pixels16_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoCopyRef_U8_U8_16x8(dest, (uint8_t *)ref, stride); - break; - - case 16: - mlib_VideoCopyRef_U8_U8_16x16(dest, (uint8_t *)ref, stride); - break; - - default: - assert(0); - } -} - -static void put_pixels16_x2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoInterpX_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpX_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void put_pixels16_y2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoInterpY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void put_pixels16_xy2_mlib(uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoInterpXY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpXY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -/* put block, width 8 pixel, height 4/8/16 */ - -static void put_pixels8_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoCopyRef_U8_U8_8x4(dest, (uint8_t *)ref, stride); - break; - - case 8: - mlib_VideoCopyRef_U8_U8_8x8(dest, (uint8_t *)ref, stride); - break; - - case 16: - mlib_VideoCopyRef_U8_U8_8x16(dest, (uint8_t *)ref, stride); - break; - - default: - assert(0); - } -} - -static void put_pixels8_x2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoInterpX_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); - break; - - case 8: - mlib_VideoInterpX_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpX_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void put_pixels8_y2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoInterpY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); - break; - - case 8: - mlib_VideoInterpY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void put_pixels8_xy2_mlib(uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoInterpXY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); - break; - - case 8: - mlib_VideoInterpXY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpXY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -/* average block, width 16 pixel, height 8/16 */ - -static void avg_pixels16_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoCopyRefAve_U8_U8_16x8(dest, (uint8_t *)ref, stride); - break; - - case 16: - mlib_VideoCopyRefAve_U8_U8_16x16(dest, (uint8_t *)ref, stride); - break; - - default: - assert(0); - } -} - -static void avg_pixels16_x2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoInterpAveX_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpAveX_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void avg_pixels16_y2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoInterpAveY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpAveY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void avg_pixels16_xy2_mlib(uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 8: - mlib_VideoInterpAveXY_U8_U8_16x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpAveXY_U8_U8_16x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -/* average block, width 8 pixel, height 4/8/16 */ - -static void avg_pixels8_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoCopyRefAve_U8_U8_8x4(dest, (uint8_t *)ref, stride); - break; - - case 8: - mlib_VideoCopyRefAve_U8_U8_8x8(dest, (uint8_t *)ref, stride); - break; - - case 16: - mlib_VideoCopyRefAve_U8_U8_8x16(dest, (uint8_t *)ref, stride); - break; - - default: - assert(0); - } -} - -static void avg_pixels8_x2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoInterpAveX_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); - break; - - case 8: - mlib_VideoInterpAveX_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpAveX_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void avg_pixels8_y2_mlib (uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoInterpAveY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); - break; - - case 8: - mlib_VideoInterpAveY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpAveY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -static void avg_pixels8_xy2_mlib(uint8_t * dest, const uint8_t * ref, - int stride, int height) -{ - switch (height) { - case 4: - mlib_VideoInterpAveXY_U8_U8_8x4(dest, (uint8_t *)ref, stride, stride); - break; - - case 8: - mlib_VideoInterpAveXY_U8_U8_8x8(dest, (uint8_t *)ref, stride, stride); - break; - - case 16: - mlib_VideoInterpAveXY_U8_U8_8x16(dest, (uint8_t *)ref, stride, stride); - break; - - default: - assert(0); - } -} - -/* swap byte order of a buffer */ - -static void bswap_buf_mlib(uint32_t *dst, const uint32_t *src, int w) -{ - mlib_VectorReverseByteOrder_U32_U32(dst, src, w); -} - -/* transformations */ - -static void ff_idct_put_mlib(uint8_t *dest, int line_size, DCTELEM *data) -{ - int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - mlib_VideoIDCT8x8_S16_S16 (data, data); - - for(i=0;i<8;i++) { - dest[0] = cm[data[0]]; - dest[1] = cm[data[1]]; - dest[2] = cm[data[2]]; - dest[3] = cm[data[3]]; - dest[4] = cm[data[4]]; - dest[5] = cm[data[5]]; - dest[6] = cm[data[6]]; - dest[7] = cm[data[7]]; - - dest += line_size; - data += 8; - } -} - -static void ff_idct_add_mlib(uint8_t *dest, int line_size, DCTELEM *data) -{ - mlib_VideoIDCT8x8_S16_S16 (data, data); - mlib_VideoAddBlock_U8_S16(dest, (mlib_s16 *)data, line_size); -} - -static void ff_idct_mlib(DCTELEM *data) -{ - mlib_VideoIDCT8x8_S16_S16 (data, data); -} - -static void ff_fdct_mlib(DCTELEM *data) -{ - mlib_VideoDCT8x8_S16_S16 (data, data); -} - -void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx) -{ - c->get_pixels = get_pixels_mlib; - c->diff_pixels = diff_pixels_mlib; - c->add_pixels_clamped = add_pixels_clamped_mlib; - - c->put_pixels_tab[0][0] = put_pixels16_mlib; - c->put_pixels_tab[0][1] = put_pixels16_x2_mlib; - c->put_pixels_tab[0][2] = put_pixels16_y2_mlib; - c->put_pixels_tab[0][3] = put_pixels16_xy2_mlib; - c->put_pixels_tab[1][0] = put_pixels8_mlib; - c->put_pixels_tab[1][1] = put_pixels8_x2_mlib; - c->put_pixels_tab[1][2] = put_pixels8_y2_mlib; - c->put_pixels_tab[1][3] = put_pixels8_xy2_mlib; - - c->avg_pixels_tab[0][0] = avg_pixels16_mlib; - c->avg_pixels_tab[0][1] = avg_pixels16_x2_mlib; - c->avg_pixels_tab[0][2] = avg_pixels16_y2_mlib; - c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mlib; - c->avg_pixels_tab[1][0] = avg_pixels8_mlib; - c->avg_pixels_tab[1][1] = avg_pixels8_x2_mlib; - c->avg_pixels_tab[1][2] = avg_pixels8_y2_mlib; - c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mlib; - - c->put_no_rnd_pixels_tab[0][0] = put_pixels16_mlib; - c->put_no_rnd_pixels_tab[1][0] = put_pixels8_mlib; - - c->bswap_buf = bswap_buf_mlib; -} - -void MPV_common_init_mlib(MpegEncContext *s) -{ - if(s->avctx->dct_algo==FF_DCT_AUTO || s->avctx->dct_algo==FF_DCT_MLIB){ - s->dsp.fdct = ff_fdct_mlib; - } - - if(s->avctx->idct_algo==FF_IDCT_MLIB){ - s->dsp.idct_put= ff_idct_put_mlib; - s->dsp.idct_add= ff_idct_add_mlib; - s->dsp.idct = ff_idct_mlib; - s->dsp.idct_permutation_type= FF_NO_IDCT_PERM; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mlp.c b/tizen/distrib/ffmpeg/libavcodec/mlp.c deleted file mode 100644 index 87f7c77..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mlp.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * MLP codec common code - * Copyright (c) 2007-2008 Ian Caulfield - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavutil/crc.h" -#include "libavutil/intreadwrite.h" -#include "mlp.h" - -const uint8_t ff_mlp_huffman_tables[3][18][2] = { - { /* Huffman table 0, -7 - +10 */ - {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, - {0x04, 3}, {0x05, 3}, {0x06, 3}, {0x07, 3}, - {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, - }, { /* Huffman table 1, -7 - +8 */ - {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, - {0x02, 2}, {0x03, 2}, - {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, - }, { /* Huffman table 2, -7 - +7 */ - {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, - {0x01, 1}, - {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, - } -}; - -static int crc_init = 0; -#if CONFIG_SMALL -#define CRC_TABLE_SIZE 257 -#else -#define CRC_TABLE_SIZE 1024 -#endif -static AVCRC crc_63[CRC_TABLE_SIZE]; -static AVCRC crc_1D[CRC_TABLE_SIZE]; -static AVCRC crc_2D[CRC_TABLE_SIZE]; - -av_cold void ff_mlp_init_crc(void) -{ - if (!crc_init) { - av_crc_init(crc_63, 0, 8, 0x63, sizeof(crc_63)); - av_crc_init(crc_1D, 0, 8, 0x1D, sizeof(crc_1D)); - av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D)); - crc_init = 1; - } -} - -uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size) -{ - uint16_t crc; - - crc = av_crc(crc_2D, 0, buf, buf_size - 2); - crc ^= AV_RL16(buf + buf_size - 2); - return crc; -} - -uint8_t ff_mlp_checksum8(const uint8_t *buf, unsigned int buf_size) -{ - uint8_t checksum = av_crc(crc_63, 0x3c, buf, buf_size - 1); // crc_63[0xa2] == 0x3c - checksum ^= buf[buf_size-1]; - return checksum; -} - -uint8_t ff_mlp_restart_checksum(const uint8_t *buf, unsigned int bit_size) -{ - int i; - int num_bytes = (bit_size + 2) / 8; - - int crc = crc_1D[buf[0] & 0x3f]; - crc = av_crc(crc_1D, crc, buf + 1, num_bytes - 2); - crc ^= buf[num_bytes - 1]; - - for (i = 0; i < ((bit_size + 2) & 7); i++) { - crc <<= 1; - if (crc & 0x100) - crc ^= 0x11D; - crc ^= (buf[num_bytes] >> (7 - i)) & 1; - } - - return crc; -} - -uint8_t ff_mlp_calculate_parity(const uint8_t *buf, unsigned int buf_size) -{ - uint32_t scratch = 0; - const uint8_t *buf_end = buf + buf_size; - - for (; ((intptr_t) buf & 3) && buf < buf_end; buf++) - scratch ^= *buf; - for (; buf < buf_end - 3; buf += 4) - scratch ^= *((const uint32_t*)buf); - - scratch = xor_32_to_8(scratch); - - for (; buf < buf_end; buf++) - scratch ^= *buf; - - return scratch; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mlp.h b/tizen/distrib/ffmpeg/libavcodec/mlp.h deleted file mode 100644 index 628b58d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mlp.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * MLP codec common header file - * Copyright (c) 2007-2008 Ian Caulfield - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MLP_H -#define AVCODEC_MLP_H - -#include - -#include "avcodec.h" - -/** Last possible matrix channel for each codec */ -#define MAX_MATRIX_CHANNEL_MLP 5 -#define MAX_MATRIX_CHANNEL_TRUEHD 7 -/** Maximum number of channels in a valid stream. - * MLP : 5.1 + 2 noise channels -> 8 channels - * TrueHD: 7.1 -> 8 channels - */ -#define MAX_CHANNELS 8 - -/** Maximum number of matrices used in decoding; most streams have one matrix - * per output channel, but some rematrix a channel (usually 0) more than once. - */ -#define MAX_MATRICES_MLP 6 -#define MAX_MATRICES_TRUEHD 8 -#define MAX_MATRICES 8 - -/** Maximum number of substreams that can be decoded. - * MLP's limit is 2. TrueHD supports at least up to 3. - */ -#define MAX_SUBSTREAMS 3 - -/** which multiple of 48000 the maximum sample rate is */ -#define MAX_RATEFACTOR 4 -/** maximum sample frequency seen in files */ -#define MAX_SAMPLERATE (MAX_RATEFACTOR * 48000) - -/** maximum number of audio samples within one access unit */ -#define MAX_BLOCKSIZE (40 * MAX_RATEFACTOR) -/** next power of two greater than MAX_BLOCKSIZE */ -#define MAX_BLOCKSIZE_POW2 (64 * MAX_RATEFACTOR) - -/** number of allowed filters */ -#define NUM_FILTERS 2 - -/** The maximum number of taps in IIR and FIR filters. */ -#define MAX_FIR_ORDER 8 -#define MAX_IIR_ORDER 4 - -/** Code that signals end of a stream. */ -#define END_OF_STREAM 0xd234d234 - -#define FIR 0 -#define IIR 1 - -/** filter data */ -typedef struct { - uint8_t order; ///< number of taps in filter - uint8_t shift; ///< Right shift to apply to output of filter. - - int32_t state[MAX_FIR_ORDER]; -} FilterParams; - -/** sample data coding information */ -typedef struct { - FilterParams filter_params[NUM_FILTERS]; - int32_t coeff[NUM_FILTERS][MAX_FIR_ORDER]; - - int16_t huff_offset; ///< Offset to apply to residual values. - int32_t sign_huff_offset; ///< sign/rounding-corrected version of huff_offset - uint8_t codebook; ///< Which VLC codebook to use to read residuals. - uint8_t huff_lsbs; ///< Size of residual suffix not encoded using VLC. -} ChannelParams; - -/** Tables defining the Huffman codes. - * There are three entropy coding methods used in MLP (four if you count - * "none" as a method). These use the same sequences for codes starting with - * 00 or 01, but have different codes starting with 1. - */ -extern const uint8_t ff_mlp_huffman_tables[3][18][2]; - -/** MLP uses checksums that seem to be based on the standard CRC algorithm, but - * are not (in implementation terms, the table lookup and XOR are reversed). - * We can implement this behavior using a standard av_crc on all but the - * last element, then XOR that with the last element. - */ -uint8_t ff_mlp_checksum8 (const uint8_t *buf, unsigned int buf_size); -uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size); - -/** Calculate an 8-bit checksum over a restart header -- a non-multiple-of-8 - * number of bits, starting two bits into the first byte of buf. - */ -uint8_t ff_mlp_restart_checksum(const uint8_t *buf, unsigned int bit_size); - -/** XOR together all the bytes of a buffer. - * Does this belong in dspcontext? - */ -uint8_t ff_mlp_calculate_parity(const uint8_t *buf, unsigned int buf_size); - -void ff_mlp_init_crc(void); - -/** XOR four bytes into one. */ -static inline uint8_t xor_32_to_8(uint32_t value) -{ - value ^= value >> 16; - value ^= value >> 8; - return value; -} - -#endif /* AVCODEC_MLP_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mlp_parser.c b/tizen/distrib/ffmpeg/libavcodec/mlp_parser.c deleted file mode 100644 index 90bf939..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mlp_parser.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * MLP parser - * Copyright (c) 2007 Ian Caulfield - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MLP parser - */ - -#include - -#include "libavutil/crc.h" -#include "get_bits.h" -#include "parser.h" -#include "mlp_parser.h" -#include "mlp.h" - -static const uint8_t mlp_quants[16] = { - 16, 20, 24, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t mlp_channels[32] = { - 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4, - 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t thd_chancount[13] = { -// LR C LFE LRs LRvh LRc LRrs Cs Ts LRsd LRw Cvh LFE2 - 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1 -}; - -static int mlp_samplerate(int in) -{ - if (in == 0xF) - return 0; - - return (in & 8 ? 44100 : 48000) << (in & 7) ; -} - -static int truehd_channels(int chanmap) -{ - int channels = 0, i; - - for (i = 0; i < 13; i++) - channels += thd_chancount[i] * ((chanmap >> i) & 1); - - return channels; -} - -/** Read a major sync info header - contains high level information about - * the stream - sample rate, channel arrangement etc. Most of this - * information is not actually necessary for decoding, only for playback. - * gb must be a freshly initialized GetBitContext with no bits read. - */ - -int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) -{ - int ratebits; - uint16_t checksum; - - assert(get_bits_count(gb) == 0); - - if (gb->size_in_bits < 28 << 3) { - av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n"); - return -1; - } - - checksum = ff_mlp_checksum16(gb->buffer, 26); - if (checksum != AV_RL16(gb->buffer+26)) { - av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n"); - return -1; - } - - if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */ - return -1; - - mh->stream_type = get_bits(gb, 8); - - if (mh->stream_type == 0xbb) { - mh->group1_bits = mlp_quants[get_bits(gb, 4)]; - mh->group2_bits = mlp_quants[get_bits(gb, 4)]; - - ratebits = get_bits(gb, 4); - mh->group1_samplerate = mlp_samplerate(ratebits); - mh->group2_samplerate = mlp_samplerate(get_bits(gb, 4)); - - skip_bits(gb, 11); - - mh->channels_mlp = get_bits(gb, 5); - } else if (mh->stream_type == 0xba) { - mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere? - mh->group2_bits = 0; - - ratebits = get_bits(gb, 4); - mh->group1_samplerate = mlp_samplerate(ratebits); - mh->group2_samplerate = 0; - - skip_bits(gb, 8); - - mh->channels_thd_stream1 = get_bits(gb, 5); - - skip_bits(gb, 2); - - mh->channels_thd_stream2 = get_bits(gb, 13); - } else - return -1; - - mh->access_unit_size = 40 << (ratebits & 7); - mh->access_unit_size_pow2 = 64 << (ratebits & 7); - - skip_bits_long(gb, 48); - - mh->is_vbr = get_bits1(gb); - - mh->peak_bitrate = (get_bits(gb, 15) * mh->group1_samplerate + 8) >> 4; - - mh->num_substreams = get_bits(gb, 4); - - skip_bits_long(gb, 4 + 11 * 8); - - return 0; -} - -typedef struct MLPParseContext -{ - ParseContext pc; - - int bytes_left; - - int in_sync; - - int num_substreams; -} MLPParseContext; - -static av_cold int mlp_init(AVCodecParserContext *s) -{ - ff_mlp_init_crc(); - return 0; -} - -static int mlp_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - MLPParseContext *mp = s->priv_data; - int sync_present; - uint8_t parity_bits; - int next; - int i, p = 0; - - *poutbuf_size = 0; - if (buf_size == 0) - return 0; - - if (!mp->in_sync) { - // Not in sync - find a major sync header - - for (i = 0; i < buf_size; i++) { - mp->pc.state = (mp->pc.state << 8) | buf[i]; - if ((mp->pc.state & 0xfffffffe) == 0xf8726fba && - // ignore if we do not have the data for the start of header - mp->pc.index + i >= 7) { - mp->in_sync = 1; - mp->bytes_left = 0; - break; - } - } - - if (!mp->in_sync) { - ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size); - return buf_size; - } - - ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size); - - return i - 7; - } - - if (mp->bytes_left == 0) { - // Find length of this packet - - /* Copy overread bytes from last frame into buffer. */ - for(; mp->pc.overread>0; mp->pc.overread--) { - mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++]; - } - - if (mp->pc.index + buf_size < 2) { - ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size); - return buf_size; - } - - mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8) - | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]); - mp->bytes_left = (mp->bytes_left & 0xfff) * 2; - mp->bytes_left -= mp->pc.index; - } - - next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left; - - if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) { - mp->bytes_left -= buf_size; - return buf_size; - } - - mp->bytes_left = 0; - - sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba; - - if (!sync_present) { - /* The first nibble of a frame is a parity check of the 4-byte - * access unit header and all the 2- or 4-byte substream headers. */ - // Only check when this isn't a sync frame - syncs have a checksum. - - parity_bits = 0; - for (i = -1; i < mp->num_substreams; i++) { - parity_bits ^= buf[p++]; - parity_bits ^= buf[p++]; - - if (i < 0 || buf[p-2] & 0x80) { - parity_bits ^= buf[p++]; - parity_bits ^= buf[p++]; - } - } - - if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) { - av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n"); - goto lost_sync; - } - } else { - GetBitContext gb; - MLPHeaderInfo mh; - - init_get_bits(&gb, buf + 4, (buf_size - 4) << 3); - if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0) - goto lost_sync; - - avctx->bits_per_raw_sample = mh.group1_bits; - if (avctx->bits_per_raw_sample > 16) - avctx->sample_fmt = SAMPLE_FMT_S32; - else - avctx->sample_fmt = SAMPLE_FMT_S16; - avctx->sample_rate = mh.group1_samplerate; - avctx->frame_size = mh.access_unit_size; - - if (mh.stream_type == 0xbb) { - /* MLP stream */ - avctx->channels = mlp_channels[mh.channels_mlp]; - } else { /* mh.stream_type == 0xba */ - /* TrueHD stream */ - if (mh.channels_thd_stream2) - avctx->channels = truehd_channels(mh.channels_thd_stream2); - else - avctx->channels = truehd_channels(mh.channels_thd_stream1); - } - - if (!mh.is_vbr) /* Stream is CBR */ - avctx->bit_rate = mh.peak_bitrate; - - mp->num_substreams = mh.num_substreams; - } - - *poutbuf = buf; - *poutbuf_size = buf_size; - - return next; - -lost_sync: - mp->in_sync = 0; - return 1; -} - -AVCodecParser mlp_parser = { - { CODEC_ID_MLP, CODEC_ID_TRUEHD }, - sizeof(MLPParseContext), - mlp_init, - mlp_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mlp_parser.h b/tizen/distrib/ffmpeg/libavcodec/mlp_parser.h deleted file mode 100644 index d7ce2b8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mlp_parser.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * MLP parser prototypes - * Copyright (c) 2007 Ian Caulfield - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MLP parser prototypes - */ - -#ifndef AVCODEC_MLP_PARSER_H -#define AVCODEC_MLP_PARSER_H - -#include "get_bits.h" - -typedef struct MLPHeaderInfo -{ - int stream_type; ///< 0xBB for MLP, 0xBA for TrueHD - - int group1_bits; ///< The bit depth of the first substream - int group2_bits; ///< Bit depth of the second substream (MLP only) - - int group1_samplerate; ///< Sample rate of first substream - int group2_samplerate; ///< Sample rate of second substream (MLP only) - - int channels_mlp; ///< Channel arrangement for MLP streams - int channels_thd_stream1; ///< Channel arrangement for substream 1 of TrueHD streams (5.1) - int channels_thd_stream2; ///< Channel arrangement for substream 2 of TrueHD streams (7.1) - - int access_unit_size; ///< Number of samples per coded frame - int access_unit_size_pow2; ///< Next power of two above number of samples per frame - - int is_vbr; ///< Stream is VBR instead of CBR - int peak_bitrate; ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR - - int num_substreams; ///< Number of substreams within stream -} MLPHeaderInfo; - - -int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb); - -#endif /* AVCODEC_MLP_PARSER_H */ - diff --git a/tizen/distrib/ffmpeg/libavcodec/mlpdec.c b/tizen/distrib/ffmpeg/libavcodec/mlpdec.c deleted file mode 100644 index 80fbbdb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mlpdec.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * MLP decoder - * Copyright (c) 2007-2008 Ian Caulfield - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MLP decoder - */ - -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "libavutil/intreadwrite.h" -#include "get_bits.h" -#include "libavutil/crc.h" -#include "parser.h" -#include "mlp_parser.h" -#include "mlp.h" - -/** number of bits used for VLC lookup - longest Huffman code is 9 */ -#define VLC_BITS 9 - - -static const char* sample_message = - "Please file a bug report following the instructions at " - "http://ffmpeg.org/bugreports.html and include " - "a sample of this file."; - -typedef struct SubStream { - //! Set if a valid restart header has been read. Otherwise the substream cannot be decoded. - uint8_t restart_seen; - - //@{ - /** restart header data */ - //! The type of noise to be used in the rematrix stage. - uint16_t noise_type; - - //! The index of the first channel coded in this substream. - uint8_t min_channel; - //! The index of the last channel coded in this substream. - uint8_t max_channel; - //! The number of channels input into the rematrix stage. - uint8_t max_matrix_channel; - //! For each channel output by the matrix, the output channel to map it to - uint8_t ch_assign[MAX_CHANNELS]; - - //! Channel coding parameters for channels in the substream - ChannelParams channel_params[MAX_CHANNELS]; - - //! The left shift applied to random noise in 0x31ea substreams. - uint8_t noise_shift; - //! The current seed value for the pseudorandom noise generator(s). - uint32_t noisegen_seed; - - //! Set if the substream contains extra info to check the size of VLC blocks. - uint8_t data_check_present; - - //! Bitmask of which parameter sets are conveyed in a decoding parameter block. - uint8_t param_presence_flags; -#define PARAM_BLOCKSIZE (1 << 7) -#define PARAM_MATRIX (1 << 6) -#define PARAM_OUTSHIFT (1 << 5) -#define PARAM_QUANTSTEP (1 << 4) -#define PARAM_FIR (1 << 3) -#define PARAM_IIR (1 << 2) -#define PARAM_HUFFOFFSET (1 << 1) -#define PARAM_PRESENCE (1 << 0) - //@} - - //@{ - /** matrix data */ - - //! Number of matrices to be applied. - uint8_t num_primitive_matrices; - - //! matrix output channel - uint8_t matrix_out_ch[MAX_MATRICES]; - - //! Whether the LSBs of the matrix output are encoded in the bitstream. - uint8_t lsb_bypass[MAX_MATRICES]; - //! Matrix coefficients, stored as 2.14 fixed point. - int32_t matrix_coeff[MAX_MATRICES][MAX_CHANNELS]; - //! Left shift to apply to noise values in 0x31eb substreams. - uint8_t matrix_noise_shift[MAX_MATRICES]; - //@} - - //! Left shift to apply to Huffman-decoded residuals. - uint8_t quant_step_size[MAX_CHANNELS]; - - //! number of PCM samples in current audio block - uint16_t blocksize; - //! Number of PCM samples decoded so far in this frame. - uint16_t blockpos; - - //! Left shift to apply to decoded PCM values to get final 24-bit output. - int8_t output_shift[MAX_CHANNELS]; - - //! Running XOR of all output samples. - int32_t lossless_check_data; - -} SubStream; - -typedef struct MLPDecodeContext { - AVCodecContext *avctx; - - //! Current access unit being read has a major sync. - int is_major_sync_unit; - - //! Set if a valid major sync block has been read. Otherwise no decoding is possible. - uint8_t params_valid; - - //! Number of substreams contained within this stream. - uint8_t num_substreams; - - //! Index of the last substream to decode - further substreams are skipped. - uint8_t max_decoded_substream; - - //! number of PCM samples contained in each frame - int access_unit_size; - //! next power of two above the number of samples in each frame - int access_unit_size_pow2; - - SubStream substream[MAX_SUBSTREAMS]; - - int matrix_changed; - int filter_changed[MAX_CHANNELS][NUM_FILTERS]; - - int8_t noise_buffer[MAX_BLOCKSIZE_POW2]; - int8_t bypassed_lsbs[MAX_BLOCKSIZE][MAX_CHANNELS]; - int32_t sample_buffer[MAX_BLOCKSIZE][MAX_CHANNELS]; - - DSPContext dsp; -} MLPDecodeContext; - -static VLC huff_vlc[3]; - -/** Initialize static data, constant between all invocations of the codec. */ - -static av_cold void init_static(void) -{ - if (!huff_vlc[0].bits) { - INIT_VLC_STATIC(&huff_vlc[0], VLC_BITS, 18, - &ff_mlp_huffman_tables[0][0][1], 2, 1, - &ff_mlp_huffman_tables[0][0][0], 2, 1, 512); - INIT_VLC_STATIC(&huff_vlc[1], VLC_BITS, 16, - &ff_mlp_huffman_tables[1][0][1], 2, 1, - &ff_mlp_huffman_tables[1][0][0], 2, 1, 512); - INIT_VLC_STATIC(&huff_vlc[2], VLC_BITS, 15, - &ff_mlp_huffman_tables[2][0][1], 2, 1, - &ff_mlp_huffman_tables[2][0][0], 2, 1, 512); - } - - ff_mlp_init_crc(); -} - -static inline int32_t calculate_sign_huff(MLPDecodeContext *m, - unsigned int substr, unsigned int ch) -{ - SubStream *s = &m->substream[substr]; - ChannelParams *cp = &s->channel_params[ch]; - int lsb_bits = cp->huff_lsbs - s->quant_step_size[ch]; - int sign_shift = lsb_bits + (cp->codebook ? 2 - cp->codebook : -1); - int32_t sign_huff_offset = cp->huff_offset; - - if (cp->codebook > 0) - sign_huff_offset -= 7 << lsb_bits; - - if (sign_shift >= 0) - sign_huff_offset -= 1 << sign_shift; - - return sign_huff_offset; -} - -/** Read a sample, consisting of either, both or neither of entropy-coded MSBs - * and plain LSBs. */ - -static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp, - unsigned int substr, unsigned int pos) -{ - SubStream *s = &m->substream[substr]; - unsigned int mat, channel; - - for (mat = 0; mat < s->num_primitive_matrices; mat++) - if (s->lsb_bypass[mat]) - m->bypassed_lsbs[pos + s->blockpos][mat] = get_bits1(gbp); - - for (channel = s->min_channel; channel <= s->max_channel; channel++) { - ChannelParams *cp = &s->channel_params[channel]; - int codebook = cp->codebook; - int quant_step_size = s->quant_step_size[channel]; - int lsb_bits = cp->huff_lsbs - quant_step_size; - int result = 0; - - if (codebook > 0) - result = get_vlc2(gbp, huff_vlc[codebook-1].table, - VLC_BITS, (9 + VLC_BITS - 1) / VLC_BITS); - - if (result < 0) - return -1; - - if (lsb_bits > 0) - result = (result << lsb_bits) + get_bits(gbp, lsb_bits); - - result += cp->sign_huff_offset; - result <<= quant_step_size; - - m->sample_buffer[pos + s->blockpos][channel] = result; - } - - return 0; -} - -static av_cold int mlp_decode_init(AVCodecContext *avctx) -{ - MLPDecodeContext *m = avctx->priv_data; - int substr; - - init_static(); - m->avctx = avctx; - for (substr = 0; substr < MAX_SUBSTREAMS; substr++) - m->substream[substr].lossless_check_data = 0xffffffff; - dsputil_init(&m->dsp, avctx); - - return 0; -} - -/** Read a major sync info header - contains high level information about - * the stream - sample rate, channel arrangement etc. Most of this - * information is not actually necessary for decoding, only for playback. - */ - -static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) -{ - MLPHeaderInfo mh; - int substr; - - if (ff_mlp_read_major_sync(m->avctx, &mh, gb) != 0) - return -1; - - if (mh.group1_bits == 0) { - av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown bits per sample\n"); - return -1; - } - if (mh.group2_bits > mh.group1_bits) { - av_log(m->avctx, AV_LOG_ERROR, - "Channel group 2 cannot have more bits per sample than group 1.\n"); - return -1; - } - - if (mh.group2_samplerate && mh.group2_samplerate != mh.group1_samplerate) { - av_log(m->avctx, AV_LOG_ERROR, - "Channel groups with differing sample rates are not currently supported.\n"); - return -1; - } - - if (mh.group1_samplerate == 0) { - av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown sampling rate\n"); - return -1; - } - if (mh.group1_samplerate > MAX_SAMPLERATE) { - av_log(m->avctx, AV_LOG_ERROR, - "Sampling rate %d is greater than the supported maximum (%d).\n", - mh.group1_samplerate, MAX_SAMPLERATE); - return -1; - } - if (mh.access_unit_size > MAX_BLOCKSIZE) { - av_log(m->avctx, AV_LOG_ERROR, - "Block size %d is greater than the supported maximum (%d).\n", - mh.access_unit_size, MAX_BLOCKSIZE); - return -1; - } - if (mh.access_unit_size_pow2 > MAX_BLOCKSIZE_POW2) { - av_log(m->avctx, AV_LOG_ERROR, - "Block size pow2 %d is greater than the supported maximum (%d).\n", - mh.access_unit_size_pow2, MAX_BLOCKSIZE_POW2); - return -1; - } - - if (mh.num_substreams == 0) - return -1; - if (m->avctx->codec_id == CODEC_ID_MLP && mh.num_substreams > 2) { - av_log(m->avctx, AV_LOG_ERROR, "MLP only supports up to 2 substreams.\n"); - return -1; - } - if (mh.num_substreams > MAX_SUBSTREAMS) { - av_log(m->avctx, AV_LOG_ERROR, - "Number of substreams %d is larger than the maximum supported " - "by the decoder. %s\n", mh.num_substreams, sample_message); - return -1; - } - - m->access_unit_size = mh.access_unit_size; - m->access_unit_size_pow2 = mh.access_unit_size_pow2; - - m->num_substreams = mh.num_substreams; - m->max_decoded_substream = m->num_substreams - 1; - - m->avctx->sample_rate = mh.group1_samplerate; - m->avctx->frame_size = mh.access_unit_size; - - m->avctx->bits_per_raw_sample = mh.group1_bits; - if (mh.group1_bits > 16) - m->avctx->sample_fmt = SAMPLE_FMT_S32; - else - m->avctx->sample_fmt = SAMPLE_FMT_S16; - - m->params_valid = 1; - for (substr = 0; substr < MAX_SUBSTREAMS; substr++) - m->substream[substr].restart_seen = 0; - - return 0; -} - -/** Read a restart header from a block in a substream. This contains parameters - * required to decode the audio that do not change very often. Generally - * (always) present only in blocks following a major sync. */ - -static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, - const uint8_t *buf, unsigned int substr) -{ - SubStream *s = &m->substream[substr]; - unsigned int ch; - int sync_word, tmp; - uint8_t checksum; - uint8_t lossless_check; - int start_count = get_bits_count(gbp); - const int max_matrix_channel = m->avctx->codec_id == CODEC_ID_MLP - ? MAX_MATRIX_CHANNEL_MLP - : MAX_MATRIX_CHANNEL_TRUEHD; - - sync_word = get_bits(gbp, 13); - - if (sync_word != 0x31ea >> 1) { - av_log(m->avctx, AV_LOG_ERROR, - "restart header sync incorrect (got 0x%04x)\n", sync_word); - return -1; - } - - s->noise_type = get_bits1(gbp); - - if (m->avctx->codec_id == CODEC_ID_MLP && s->noise_type) { - av_log(m->avctx, AV_LOG_ERROR, "MLP must have 0x31ea sync word.\n"); - return -1; - } - - skip_bits(gbp, 16); /* Output timestamp */ - - s->min_channel = get_bits(gbp, 4); - s->max_channel = get_bits(gbp, 4); - s->max_matrix_channel = get_bits(gbp, 4); - - if (s->max_matrix_channel > max_matrix_channel) { - av_log(m->avctx, AV_LOG_ERROR, - "Max matrix channel cannot be greater than %d.\n", - max_matrix_channel); - return -1; - } - - if (s->max_channel != s->max_matrix_channel) { - av_log(m->avctx, AV_LOG_ERROR, - "Max channel must be equal max matrix channel.\n"); - return -1; - } - - /* This should happen for TrueHD streams with >6 channels and MLP's noise - * type. It is not yet known if this is allowed. */ - if (s->max_channel > MAX_MATRIX_CHANNEL_MLP && !s->noise_type) { - av_log(m->avctx, AV_LOG_ERROR, - "Number of channels %d is larger than the maximum supported " - "by the decoder. %s\n", s->max_channel+2, sample_message); - return -1; - } - - if (s->min_channel > s->max_channel) { - av_log(m->avctx, AV_LOG_ERROR, - "Substream min channel cannot be greater than max channel.\n"); - return -1; - } - - if (m->avctx->request_channels > 0 - && s->max_channel + 1 >= m->avctx->request_channels - && substr < m->max_decoded_substream) { - av_log(m->avctx, AV_LOG_DEBUG, - "Extracting %d channel downmix from substream %d. " - "Further substreams will be skipped.\n", - s->max_channel + 1, substr); - m->max_decoded_substream = substr; - } - - s->noise_shift = get_bits(gbp, 4); - s->noisegen_seed = get_bits(gbp, 23); - - skip_bits(gbp, 19); - - s->data_check_present = get_bits1(gbp); - lossless_check = get_bits(gbp, 8); - if (substr == m->max_decoded_substream - && s->lossless_check_data != 0xffffffff) { - tmp = xor_32_to_8(s->lossless_check_data); - if (tmp != lossless_check) - av_log(m->avctx, AV_LOG_WARNING, - "Lossless check failed - expected %02x, calculated %02x.\n", - lossless_check, tmp); - } - - skip_bits(gbp, 16); - - memset(s->ch_assign, 0, sizeof(s->ch_assign)); - - for (ch = 0; ch <= s->max_matrix_channel; ch++) { - int ch_assign = get_bits(gbp, 6); - if (ch_assign > s->max_matrix_channel) { - av_log(m->avctx, AV_LOG_ERROR, - "Assignment of matrix channel %d to invalid output channel %d. %s\n", - ch, ch_assign, sample_message); - return -1; - } - s->ch_assign[ch_assign] = ch; - } - - checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); - - if (checksum != get_bits(gbp, 8)) - av_log(m->avctx, AV_LOG_ERROR, "restart header checksum error\n"); - - /* Set default decoding parameters. */ - s->param_presence_flags = 0xff; - s->num_primitive_matrices = 0; - s->blocksize = 8; - s->lossless_check_data = 0; - - memset(s->output_shift , 0, sizeof(s->output_shift )); - memset(s->quant_step_size, 0, sizeof(s->quant_step_size)); - - for (ch = s->min_channel; ch <= s->max_channel; ch++) { - ChannelParams *cp = &s->channel_params[ch]; - cp->filter_params[FIR].order = 0; - cp->filter_params[IIR].order = 0; - cp->filter_params[FIR].shift = 0; - cp->filter_params[IIR].shift = 0; - - /* Default audio coding is 24-bit raw PCM. */ - cp->huff_offset = 0; - cp->sign_huff_offset = (-1) << 23; - cp->codebook = 0; - cp->huff_lsbs = 24; - } - - if (substr == m->max_decoded_substream) - m->avctx->channels = s->max_matrix_channel + 1; - - return 0; -} - -/** Read parameters for one of the prediction filters. */ - -static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp, - unsigned int substr, unsigned int channel, - unsigned int filter) -{ - SubStream *s = &m->substream[substr]; - FilterParams *fp = &s->channel_params[channel].filter_params[filter]; - const int max_order = filter ? MAX_IIR_ORDER : MAX_FIR_ORDER; - const char fchar = filter ? 'I' : 'F'; - int i, order; - - // Filter is 0 for FIR, 1 for IIR. - assert(filter < 2); - - if (m->filter_changed[channel][filter]++ > 1) { - av_log(m->avctx, AV_LOG_ERROR, "Filters may change only once per access unit.\n"); - return -1; - } - - order = get_bits(gbp, 4); - if (order > max_order) { - av_log(m->avctx, AV_LOG_ERROR, - "%cIR filter order %d is greater than maximum %d.\n", - fchar, order, max_order); - return -1; - } - fp->order = order; - - if (order > 0) { - int32_t *fcoeff = s->channel_params[channel].coeff[filter]; - int coeff_bits, coeff_shift; - - fp->shift = get_bits(gbp, 4); - - coeff_bits = get_bits(gbp, 5); - coeff_shift = get_bits(gbp, 3); - if (coeff_bits < 1 || coeff_bits > 16) { - av_log(m->avctx, AV_LOG_ERROR, - "%cIR filter coeff_bits must be between 1 and 16.\n", - fchar); - return -1; - } - if (coeff_bits + coeff_shift > 16) { - av_log(m->avctx, AV_LOG_ERROR, - "Sum of coeff_bits and coeff_shift for %cIR filter must be 16 or less.\n", - fchar); - return -1; - } - - for (i = 0; i < order; i++) - fcoeff[i] = get_sbits(gbp, coeff_bits) << coeff_shift; - - if (get_bits1(gbp)) { - int state_bits, state_shift; - - if (filter == FIR) { - av_log(m->avctx, AV_LOG_ERROR, - "FIR filter has state data specified.\n"); - return -1; - } - - state_bits = get_bits(gbp, 4); - state_shift = get_bits(gbp, 4); - - /* TODO: Check validity of state data. */ - - for (i = 0; i < order; i++) - fp->state[i] = get_sbits(gbp, state_bits) << state_shift; - } - } - - return 0; -} - -/** Read parameters for primitive matrices. */ - -static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitContext *gbp) -{ - SubStream *s = &m->substream[substr]; - unsigned int mat, ch; - const int max_primitive_matrices = m->avctx->codec_id == CODEC_ID_MLP - ? MAX_MATRICES_MLP - : MAX_MATRICES_TRUEHD; - - if (m->matrix_changed++ > 1) { - av_log(m->avctx, AV_LOG_ERROR, "Matrices may change only once per access unit.\n"); - return -1; - } - - s->num_primitive_matrices = get_bits(gbp, 4); - - if (s->num_primitive_matrices > max_primitive_matrices) { - av_log(m->avctx, AV_LOG_ERROR, - "Number of primitive matrices cannot be greater than %d.\n", - max_primitive_matrices); - return -1; - } - - for (mat = 0; mat < s->num_primitive_matrices; mat++) { - int frac_bits, max_chan; - s->matrix_out_ch[mat] = get_bits(gbp, 4); - frac_bits = get_bits(gbp, 4); - s->lsb_bypass [mat] = get_bits1(gbp); - - if (s->matrix_out_ch[mat] > s->max_matrix_channel) { - av_log(m->avctx, AV_LOG_ERROR, - "Invalid channel %d specified as output from matrix.\n", - s->matrix_out_ch[mat]); - return -1; - } - if (frac_bits > 14) { - av_log(m->avctx, AV_LOG_ERROR, - "Too many fractional bits specified.\n"); - return -1; - } - - max_chan = s->max_matrix_channel; - if (!s->noise_type) - max_chan+=2; - - for (ch = 0; ch <= max_chan; ch++) { - int coeff_val = 0; - if (get_bits1(gbp)) - coeff_val = get_sbits(gbp, frac_bits + 2); - - s->matrix_coeff[mat][ch] = coeff_val << (14 - frac_bits); - } - - if (s->noise_type) - s->matrix_noise_shift[mat] = get_bits(gbp, 4); - else - s->matrix_noise_shift[mat] = 0; - } - - return 0; -} - -/** Read channel parameters. */ - -static int read_channel_params(MLPDecodeContext *m, unsigned int substr, - GetBitContext *gbp, unsigned int ch) -{ - SubStream *s = &m->substream[substr]; - ChannelParams *cp = &s->channel_params[ch]; - FilterParams *fir = &cp->filter_params[FIR]; - FilterParams *iir = &cp->filter_params[IIR]; - - if (s->param_presence_flags & PARAM_FIR) - if (get_bits1(gbp)) - if (read_filter_params(m, gbp, substr, ch, FIR) < 0) - return -1; - - if (s->param_presence_flags & PARAM_IIR) - if (get_bits1(gbp)) - if (read_filter_params(m, gbp, substr, ch, IIR) < 0) - return -1; - - if (fir->order + iir->order > 8) { - av_log(m->avctx, AV_LOG_ERROR, "Total filter orders too high.\n"); - return -1; - } - - if (fir->order && iir->order && - fir->shift != iir->shift) { - av_log(m->avctx, AV_LOG_ERROR, - "FIR and IIR filters must use the same precision.\n"); - return -1; - } - /* The FIR and IIR filters must have the same precision. - * To simplify the filtering code, only the precision of the - * FIR filter is considered. If only the IIR filter is employed, - * the FIR filter precision is set to that of the IIR filter, so - * that the filtering code can use it. */ - if (!fir->order && iir->order) - fir->shift = iir->shift; - - if (s->param_presence_flags & PARAM_HUFFOFFSET) - if (get_bits1(gbp)) - cp->huff_offset = get_sbits(gbp, 15); - - cp->codebook = get_bits(gbp, 2); - cp->huff_lsbs = get_bits(gbp, 5); - - if (cp->huff_lsbs > 24) { - av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n"); - return -1; - } - - cp->sign_huff_offset = calculate_sign_huff(m, substr, ch); - - return 0; -} - -/** Read decoding parameters that change more often than those in the restart - * header. */ - -static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, - unsigned int substr) -{ - SubStream *s = &m->substream[substr]; - unsigned int ch; - - if (s->param_presence_flags & PARAM_PRESENCE) - if (get_bits1(gbp)) - s->param_presence_flags = get_bits(gbp, 8); - - if (s->param_presence_flags & PARAM_BLOCKSIZE) - if (get_bits1(gbp)) { - s->blocksize = get_bits(gbp, 9); - if (s->blocksize < 8 || s->blocksize > m->access_unit_size) { - av_log(m->avctx, AV_LOG_ERROR, "Invalid blocksize."); - s->blocksize = 0; - return -1; - } - } - - if (s->param_presence_flags & PARAM_MATRIX) - if (get_bits1(gbp)) - if (read_matrix_params(m, substr, gbp) < 0) - return -1; - - if (s->param_presence_flags & PARAM_OUTSHIFT) - if (get_bits1(gbp)) - for (ch = 0; ch <= s->max_matrix_channel; ch++) - s->output_shift[ch] = get_sbits(gbp, 4); - - if (s->param_presence_flags & PARAM_QUANTSTEP) - if (get_bits1(gbp)) - for (ch = 0; ch <= s->max_channel; ch++) { - ChannelParams *cp = &s->channel_params[ch]; - - s->quant_step_size[ch] = get_bits(gbp, 4); - - cp->sign_huff_offset = calculate_sign_huff(m, substr, ch); - } - - for (ch = s->min_channel; ch <= s->max_channel; ch++) - if (get_bits1(gbp)) - if (read_channel_params(m, substr, gbp, ch) < 0) - return -1; - - return 0; -} - -#define MSB_MASK(bits) (-1u << bits) - -/** Generate PCM samples using the prediction filters and residual values - * read from the data stream, and update the filter state. */ - -static void filter_channel(MLPDecodeContext *m, unsigned int substr, - unsigned int channel) -{ - SubStream *s = &m->substream[substr]; - const int32_t *fircoeff = s->channel_params[channel].coeff[FIR]; - int32_t state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FIR_ORDER]; - int32_t *firbuf = state_buffer[FIR] + MAX_BLOCKSIZE; - int32_t *iirbuf = state_buffer[IIR] + MAX_BLOCKSIZE; - FilterParams *fir = &s->channel_params[channel].filter_params[FIR]; - FilterParams *iir = &s->channel_params[channel].filter_params[IIR]; - unsigned int filter_shift = fir->shift; - int32_t mask = MSB_MASK(s->quant_step_size[channel]); - - memcpy(firbuf, fir->state, MAX_FIR_ORDER * sizeof(int32_t)); - memcpy(iirbuf, iir->state, MAX_IIR_ORDER * sizeof(int32_t)); - - m->dsp.mlp_filter_channel(firbuf, fircoeff, - fir->order, iir->order, - filter_shift, mask, s->blocksize, - &m->sample_buffer[s->blockpos][channel]); - - memcpy(fir->state, firbuf - s->blocksize, MAX_FIR_ORDER * sizeof(int32_t)); - memcpy(iir->state, iirbuf - s->blocksize, MAX_IIR_ORDER * sizeof(int32_t)); -} - -/** Read a block of PCM residual data (or actual if no filtering active). */ - -static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp, - unsigned int substr) -{ - SubStream *s = &m->substream[substr]; - unsigned int i, ch, expected_stream_pos = 0; - - if (s->data_check_present) { - expected_stream_pos = get_bits_count(gbp); - expected_stream_pos += get_bits(gbp, 16); - av_log(m->avctx, AV_LOG_WARNING, "This file contains some features " - "we have not tested yet. %s\n", sample_message); - } - - if (s->blockpos + s->blocksize > m->access_unit_size) { - av_log(m->avctx, AV_LOG_ERROR, "too many audio samples in frame\n"); - return -1; - } - - memset(&m->bypassed_lsbs[s->blockpos][0], 0, - s->blocksize * sizeof(m->bypassed_lsbs[0])); - - for (i = 0; i < s->blocksize; i++) - if (read_huff_channels(m, gbp, substr, i) < 0) - return -1; - - for (ch = s->min_channel; ch <= s->max_channel; ch++) - filter_channel(m, substr, ch); - - s->blockpos += s->blocksize; - - if (s->data_check_present) { - if (get_bits_count(gbp) != expected_stream_pos) - av_log(m->avctx, AV_LOG_ERROR, "block data length mismatch\n"); - skip_bits(gbp, 8); - } - - return 0; -} - -/** Data table used for TrueHD noise generation function. */ - -static const int8_t noise_table[256] = { - 30, 51, 22, 54, 3, 7, -4, 38, 14, 55, 46, 81, 22, 58, -3, 2, - 52, 31, -7, 51, 15, 44, 74, 30, 85, -17, 10, 33, 18, 80, 28, 62, - 10, 32, 23, 69, 72, 26, 35, 17, 73, 60, 8, 56, 2, 6, -2, -5, - 51, 4, 11, 50, 66, 76, 21, 44, 33, 47, 1, 26, 64, 48, 57, 40, - 38, 16, -10, -28, 92, 22, -18, 29, -10, 5, -13, 49, 19, 24, 70, 34, - 61, 48, 30, 14, -6, 25, 58, 33, 42, 60, 67, 17, 54, 17, 22, 30, - 67, 44, -9, 50, -11, 43, 40, 32, 59, 82, 13, 49, -14, 55, 60, 36, - 48, 49, 31, 47, 15, 12, 4, 65, 1, 23, 29, 39, 45, -2, 84, 69, - 0, 72, 37, 57, 27, 41, -15, -16, 35, 31, 14, 61, 24, 0, 27, 24, - 16, 41, 55, 34, 53, 9, 56, 12, 25, 29, 53, 5, 20, -20, -8, 20, - 13, 28, -3, 78, 38, 16, 11, 62, 46, 29, 21, 24, 46, 65, 43, -23, - 89, 18, 74, 21, 38, -12, 19, 12, -19, 8, 15, 33, 4, 57, 9, -8, - 36, 35, 26, 28, 7, 83, 63, 79, 75, 11, 3, 87, 37, 47, 34, 40, - 39, 19, 20, 42, 27, 34, 39, 77, 13, 42, 59, 64, 45, -1, 32, 37, - 45, -5, 53, -6, 7, 36, 50, 23, 6, 32, 9, -21, 18, 71, 27, 52, - -25, 31, 35, 42, -1, 68, 63, 52, 26, 43, 66, 37, 41, 25, 40, 70, -}; - -/** Noise generation functions. - * I'm not sure what these are for - they seem to be some kind of pseudorandom - * sequence generators, used to generate noise data which is used when the - * channels are rematrixed. I'm not sure if they provide a practical benefit - * to compression, or just obfuscate the decoder. Are they for some kind of - * dithering? */ - -/** Generate two channels of noise, used in the matrix when - * restart sync word == 0x31ea. */ - -static void generate_2_noise_channels(MLPDecodeContext *m, unsigned int substr) -{ - SubStream *s = &m->substream[substr]; - unsigned int i; - uint32_t seed = s->noisegen_seed; - unsigned int maxchan = s->max_matrix_channel; - - for (i = 0; i < s->blockpos; i++) { - uint16_t seed_shr7 = seed >> 7; - m->sample_buffer[i][maxchan+1] = ((int8_t)(seed >> 15)) << s->noise_shift; - m->sample_buffer[i][maxchan+2] = ((int8_t) seed_shr7) << s->noise_shift; - - seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5); - } - - s->noisegen_seed = seed; -} - -/** Generate a block of noise, used when restart sync word == 0x31eb. */ - -static void fill_noise_buffer(MLPDecodeContext *m, unsigned int substr) -{ - SubStream *s = &m->substream[substr]; - unsigned int i; - uint32_t seed = s->noisegen_seed; - - for (i = 0; i < m->access_unit_size_pow2; i++) { - uint8_t seed_shr15 = seed >> 15; - m->noise_buffer[i] = noise_table[seed_shr15]; - seed = (seed << 8) ^ seed_shr15 ^ (seed_shr15 << 5); - } - - s->noisegen_seed = seed; -} - - -/** Apply the channel matrices in turn to reconstruct the original audio - * samples. */ - -static void rematrix_channels(MLPDecodeContext *m, unsigned int substr) -{ - SubStream *s = &m->substream[substr]; - unsigned int mat, src_ch, i; - unsigned int maxchan; - - maxchan = s->max_matrix_channel; - if (!s->noise_type) { - generate_2_noise_channels(m, substr); - maxchan += 2; - } else { - fill_noise_buffer(m, substr); - } - - for (mat = 0; mat < s->num_primitive_matrices; mat++) { - int matrix_noise_shift = s->matrix_noise_shift[mat]; - unsigned int dest_ch = s->matrix_out_ch[mat]; - int32_t mask = MSB_MASK(s->quant_step_size[dest_ch]); - int32_t *coeffs = s->matrix_coeff[mat]; - int index = s->num_primitive_matrices - mat; - int index2 = 2 * index + 1; - - /* TODO: DSPContext? */ - - for (i = 0; i < s->blockpos; i++) { - int32_t bypassed_lsb = m->bypassed_lsbs[i][mat]; - int32_t *samples = m->sample_buffer[i]; - int64_t accum = 0; - - for (src_ch = 0; src_ch <= maxchan; src_ch++) - accum += (int64_t) samples[src_ch] * coeffs[src_ch]; - - if (matrix_noise_shift) { - index &= m->access_unit_size_pow2 - 1; - accum += m->noise_buffer[index] << (matrix_noise_shift + 7); - index += index2; - } - - samples[dest_ch] = ((accum >> 14) & mask) + bypassed_lsb; - } - } -} - -/** Write the audio data into the output buffer. */ - -static int output_data_internal(MLPDecodeContext *m, unsigned int substr, - uint8_t *data, unsigned int *data_size, int is32) -{ - SubStream *s = &m->substream[substr]; - unsigned int i, out_ch = 0; - int32_t *data_32 = (int32_t*) data; - int16_t *data_16 = (int16_t*) data; - - if (*data_size < (s->max_channel + 1) * s->blockpos * (is32 ? 4 : 2)) - return -1; - - for (i = 0; i < s->blockpos; i++) { - for (out_ch = 0; out_ch <= s->max_matrix_channel; out_ch++) { - int mat_ch = s->ch_assign[out_ch]; - int32_t sample = m->sample_buffer[i][mat_ch] - << s->output_shift[mat_ch]; - s->lossless_check_data ^= (sample & 0xffffff) << mat_ch; - if (is32) *data_32++ = sample << 8; - else *data_16++ = sample >> 8; - } - } - - *data_size = i * out_ch * (is32 ? 4 : 2); - - return 0; -} - -static int output_data(MLPDecodeContext *m, unsigned int substr, - uint8_t *data, unsigned int *data_size) -{ - if (m->avctx->sample_fmt == SAMPLE_FMT_S32) - return output_data_internal(m, substr, data, data_size, 1); - else - return output_data_internal(m, substr, data, data_size, 0); -} - - -/** Read an access unit from the stream. - * Returns < 0 on error, 0 if not enough data is present in the input stream - * otherwise returns the number of bytes consumed. */ - -static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MLPDecodeContext *m = avctx->priv_data; - GetBitContext gb; - unsigned int length, substr; - unsigned int substream_start; - unsigned int header_size = 4; - unsigned int substr_header_size = 0; - uint8_t substream_parity_present[MAX_SUBSTREAMS]; - uint16_t substream_data_len[MAX_SUBSTREAMS]; - uint8_t parity_bits; - - if (buf_size < 4) - return 0; - - length = (AV_RB16(buf) & 0xfff) * 2; - - if (length < 4 || length > buf_size) - return -1; - - init_get_bits(&gb, (buf + 4), (length - 4) * 8); - - m->is_major_sync_unit = 0; - if (show_bits_long(&gb, 31) == (0xf8726fba >> 1)) { - if (read_major_sync(m, &gb) < 0) - goto error; - m->is_major_sync_unit = 1; - header_size += 28; - } - - if (!m->params_valid) { - av_log(m->avctx, AV_LOG_WARNING, - "Stream parameters not seen; skipping frame.\n"); - *data_size = 0; - return length; - } - - substream_start = 0; - - for (substr = 0; substr < m->num_substreams; substr++) { - int extraword_present, checkdata_present, end, nonrestart_substr; - - extraword_present = get_bits1(&gb); - nonrestart_substr = get_bits1(&gb); - checkdata_present = get_bits1(&gb); - skip_bits1(&gb); - - end = get_bits(&gb, 12) * 2; - - substr_header_size += 2; - - if (extraword_present) { - if (m->avctx->codec_id == CODEC_ID_MLP) { - av_log(m->avctx, AV_LOG_ERROR, "There must be no extraword for MLP.\n"); - goto error; - } - skip_bits(&gb, 16); - substr_header_size += 2; - } - - if (!(nonrestart_substr ^ m->is_major_sync_unit)) { - av_log(m->avctx, AV_LOG_ERROR, "Invalid nonrestart_substr.\n"); - goto error; - } - - if (end + header_size + substr_header_size > length) { - av_log(m->avctx, AV_LOG_ERROR, - "Indicated length of substream %d data goes off end of " - "packet.\n", substr); - end = length - header_size - substr_header_size; - } - - if (end < substream_start) { - av_log(avctx, AV_LOG_ERROR, - "Indicated end offset of substream %d data " - "is smaller than calculated start offset.\n", - substr); - goto error; - } - - if (substr > m->max_decoded_substream) - continue; - - substream_parity_present[substr] = checkdata_present; - substream_data_len[substr] = end - substream_start; - substream_start = end; - } - - parity_bits = ff_mlp_calculate_parity(buf, 4); - parity_bits ^= ff_mlp_calculate_parity(buf + header_size, substr_header_size); - - if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) { - av_log(avctx, AV_LOG_ERROR, "Parity check failed.\n"); - goto error; - } - - buf += header_size + substr_header_size; - - for (substr = 0; substr <= m->max_decoded_substream; substr++) { - SubStream *s = &m->substream[substr]; - init_get_bits(&gb, buf, substream_data_len[substr] * 8); - - m->matrix_changed = 0; - memset(m->filter_changed, 0, sizeof(m->filter_changed)); - - s->blockpos = 0; - do { - if (get_bits1(&gb)) { - if (get_bits1(&gb)) { - /* A restart header should be present. */ - if (read_restart_header(m, &gb, buf, substr) < 0) - goto next_substr; - s->restart_seen = 1; - } - - if (!s->restart_seen) - goto next_substr; - if (read_decoding_params(m, &gb, substr) < 0) - goto next_substr; - } - - if (!s->restart_seen) - goto next_substr; - - if (read_block_data(m, &gb, substr) < 0) - return -1; - - if (get_bits_count(&gb) >= substream_data_len[substr] * 8) - goto substream_length_mismatch; - - } while (!get_bits1(&gb)); - - skip_bits(&gb, (-get_bits_count(&gb)) & 15); - - if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 32) { - int shorten_by; - - if (get_bits(&gb, 16) != 0xD234) - return -1; - - shorten_by = get_bits(&gb, 16); - if (m->avctx->codec_id == CODEC_ID_TRUEHD && shorten_by & 0x2000) - s->blockpos -= FFMIN(shorten_by & 0x1FFF, s->blockpos); - else if (m->avctx->codec_id == CODEC_ID_MLP && shorten_by != 0xD234) - return -1; - - if (substr == m->max_decoded_substream) - av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n"); - } - - if (substream_parity_present[substr]) { - uint8_t parity, checksum; - - if (substream_data_len[substr] * 8 - get_bits_count(&gb) != 16) - goto substream_length_mismatch; - - parity = ff_mlp_calculate_parity(buf, substream_data_len[substr] - 2); - checksum = ff_mlp_checksum8 (buf, substream_data_len[substr] - 2); - - if ((get_bits(&gb, 8) ^ parity) != 0xa9 ) - av_log(m->avctx, AV_LOG_ERROR, "Substream %d parity check failed.\n", substr); - if ( get_bits(&gb, 8) != checksum) - av_log(m->avctx, AV_LOG_ERROR, "Substream %d checksum failed.\n" , substr); - } - - if (substream_data_len[substr] * 8 != get_bits_count(&gb)) - goto substream_length_mismatch; - -next_substr: - if (!s->restart_seen) - av_log(m->avctx, AV_LOG_ERROR, - "No restart header present in substream %d.\n", substr); - - buf += substream_data_len[substr]; - } - - rematrix_channels(m, m->max_decoded_substream); - - if (output_data(m, m->max_decoded_substream, data, data_size) < 0) - return -1; - - return length; - -substream_length_mismatch: - av_log(m->avctx, AV_LOG_ERROR, "substream %d length mismatch\n", substr); - return -1; - -error: - m->params_valid = 0; - return -1; -} - -AVCodec mlp_decoder = { - "mlp", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MLP, - sizeof(MLPDecodeContext), - mlp_decode_init, - NULL, - NULL, - read_access_unit, - .long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"), -}; - -#if CONFIG_TRUEHD_DECODER -AVCodec truehd_decoder = { - "truehd", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_TRUEHD, - sizeof(MLPDecodeContext), - mlp_decode_init, - NULL, - NULL, - read_access_unit, - .long_name = NULL_IF_CONFIG_SMALL("TrueHD"), -}; -#endif /* CONFIG_TRUEHD_DECODER */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mlpdsp.c b/tizen/distrib/ffmpeg/libavcodec/mlpdsp.c deleted file mode 100644 index a0647ee..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mlpdsp.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2007-2008 Ian Caulfield - * 2009 Ramiro Polla - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/mlp.h" -#include "dsputil.h" - -static void ff_mlp_filter_channel(int32_t *state, const int32_t *coeff, - int firorder, int iirorder, - unsigned int filter_shift, int32_t mask, int blocksize, - int32_t *sample_buffer) -{ - int32_t *firbuf = state; - int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER; - const int32_t *fircoeff = coeff; - const int32_t *iircoeff = coeff + MAX_FIR_ORDER; - int i; - - for (i = 0; i < blocksize; i++) { - int32_t residual = *sample_buffer; - unsigned int order; - int64_t accum = 0; - int32_t result; - - for (order = 0; order < firorder; order++) - accum += (int64_t) firbuf[order] * fircoeff[order]; - for (order = 0; order < iirorder; order++) - accum += (int64_t) iirbuf[order] * iircoeff[order]; - - accum = accum >> filter_shift; - result = (accum + residual) & mask; - - *--firbuf = result; - *--iirbuf = result - accum; - - *sample_buffer = result; - sample_buffer += MAX_CHANNELS; - } -} - -void ff_mlp_init(DSPContext* c, AVCodecContext *avctx) -{ - c->mlp_filter_channel = ff_mlp_filter_channel; - if (ARCH_X86) - ff_mlp_init_x86(c, avctx); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mmvideo.c b/tizen/distrib/ffmpeg/libavcodec/mmvideo.c deleted file mode 100644 index 6dbc0c4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mmvideo.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * American Laser Games MM Video Decoder - * Copyright (c) 2006,2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * American Laser Games MM Video Decoder - * by Peter Ross (pross@xvid.org) - * - * The MM format was used by IBM-PC ports of ALG's "arcade shooter" games, - * including Mad Dog McCree and Crime Patrol. - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=American_Laser_Games_MM - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#define MM_PREAMBLE_SIZE 6 - -#define MM_TYPE_INTER 0x5 -#define MM_TYPE_INTRA 0x8 -#define MM_TYPE_INTRA_HH 0xc -#define MM_TYPE_INTER_HH 0xd -#define MM_TYPE_INTRA_HHV 0xe -#define MM_TYPE_INTER_HHV 0xf -#define MM_TYPE_PALETTE 0x31 - -typedef struct MmContext { - AVCodecContext *avctx; - AVFrame frame; - int palette[AVPALETTE_COUNT]; -} MmContext; - -static av_cold int mm_decode_init(AVCodecContext *avctx) -{ - MmContext *s = avctx->priv_data; - - s->avctx = avctx; - - avctx->pix_fmt = PIX_FMT_PAL8; - - s->frame.reference = 1; - if (avctx->get_buffer(avctx, &s->frame)) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - return 0; -} - -static void mm_decode_pal(MmContext *s, const uint8_t *buf, const uint8_t *buf_end) -{ - int i; - buf += 4; - for (i=0; i<128 && buf+2palette[i] = AV_RB24(buf); - s->palette[i+128] = s->palette[i]<<2; - buf += 3; - } -} - -static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) -{ - int i, x, y; - i=0; x=0; y=0; - - while(iframe.data[0] + y*s->frame.linesize[0] + x, color, run_length); - if (half_vert) - memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length); - } - x+= run_length; - - if (x >= s->avctx->width) { - x=0; - y += half_vert ? 2 : 1; - } - } -} - -static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) -{ - const int data_ptr = 2 + AV_RL16(&buf[0]); - int d, r, y; - d = data_ptr; r = 2; y = 0; - - while(r < data_ptr) { - int i, j; - int length = buf[r] & 0x7f; - int x = buf[r+1] + ((buf[r] & 0x80) << 1); - r += 2; - - if (length==0) { - y += x; - continue; - } - - for(i=0; i> (7-j)) & 1; - if (replace) { - int color = buf[d]; - s->frame.data[0][y*s->frame.linesize[0] + x] = color; - if (half_horiz) - s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color; - if (half_vert) { - s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color; - if (half_horiz) - s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color; - } - d++; - } - x += half_horiz ? 2 : 1; - } - } - - r += length; - y += half_vert ? 2 : 1; - } -} - -static int mm_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MmContext *s = avctx->priv_data; - const uint8_t *buf_end = buf+buf_size; - int type; - - type = AV_RL16(&buf[0]); - buf += MM_PREAMBLE_SIZE; - buf_size -= MM_PREAMBLE_SIZE; - - switch(type) { - case MM_TYPE_PALETTE : mm_decode_pal(s, buf, buf_end); return buf_size; - case MM_TYPE_INTRA : mm_decode_intra(s, 0, 0, buf, buf_size); break; - case MM_TYPE_INTRA_HH : mm_decode_intra(s, 1, 0, buf, buf_size); break; - case MM_TYPE_INTRA_HHV : mm_decode_intra(s, 1, 1, buf, buf_size); break; - case MM_TYPE_INTER : mm_decode_inter(s, 0, 0, buf, buf_size); break; - case MM_TYPE_INTER_HH : mm_decode_inter(s, 1, 0, buf, buf_size); break; - case MM_TYPE_INTER_HHV : mm_decode_inter(s, 1, 1, buf, buf_size); break; - default : - return -1; - } - - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - return buf_size; -} - -static av_cold int mm_decode_end(AVCodecContext *avctx) -{ - MmContext *s = avctx->priv_data; - - if(s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec mmvideo_decoder = { - "mmvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MMVIDEO, - sizeof(MmContext), - mm_decode_init, - NULL, - mm_decode_end, - mm_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM Video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/motion-test.c b/tizen/distrib/ffmpeg/libavcodec/motion-test.c deleted file mode 100644 index 37f55a6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/motion-test.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * motion test. - */ - -#include -#include -#include -#include -#include - -#include "config.h" -#include "dsputil.h" -#include "libavutil/lfg.h" - -#undef exit -#undef printf - -#define WIDTH 64 -#define HEIGHT 64 - -uint8_t img1[WIDTH * HEIGHT]; -uint8_t img2[WIDTH * HEIGHT]; - -static void fill_random(uint8_t *tab, int size) -{ - int i; - AVLFG prng; - - av_lfg_init(&prng, 1); - for(i=0;idsp_mask = FF_MM_FORCE; - dsputil_init(&cctx, ctx); - for (c = 0; c < flags_size; c++) { - int x; - ctx->dsp_mask = FF_MM_FORCE | flags[c]; - dsputil_init(&mmxctx, ctx); - - for (x = 0; x < 2; x++) { - printf("%s for %dx%d pixels\n", c ? "mmx2" : "mmx", - x ? 8 : 16, x ? 8 : 16); - test_motion("mmx", mmxctx.pix_abs[x][0], cctx.pix_abs[x][0]); - test_motion("mmx_x2", mmxctx.pix_abs[x][1], cctx.pix_abs[x][1]); - test_motion("mmx_y2", mmxctx.pix_abs[x][2], cctx.pix_abs[x][2]); - test_motion("mmx_xy2", mmxctx.pix_abs[x][3], cctx.pix_abs[x][3]); - } - } - av_free(ctx); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/motion_est.c b/tizen/distrib/ffmpeg/libavcodec/motion_est.c deleted file mode 100644 index 82a36d0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/motion_est.c +++ /dev/null @@ -1,2016 +0,0 @@ -/* - * Motion estimation - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * new motion estimation (X1/EPZS) by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Motion estimation. - */ - -#include -#include -#include -#include "libavutil/intmath.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mathops.h" -#include "mpegvideo.h" - -#undef NDEBUG -#include - -#define SQ(a) ((a)*(a)) - -#define P_LEFT P[1] -#define P_TOP P[2] -#define P_TOPRIGHT P[3] -#define P_MEDIAN P[4] -#define P_MV1 P[9] - -static inline int sad_hpel_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - int src_index, int ref_index, - int size, int h); - -static inline int update_map_generation(MotionEstContext *c) -{ - c->map_generation+= 1<<(ME_MAP_MV_BITS*2); - if(c->map_generation==0){ - c->map_generation= 1<<(ME_MAP_MV_BITS*2); - memset(c->map, 0, sizeof(uint32_t)*ME_MAP_SIZE); - } - return c->map_generation; -} - -/* shape adaptive search stuff */ -typedef struct Minima{ - int height; - int x, y; - int checked; -}Minima; - -static int minima_cmp(const void *a, const void *b){ - const Minima *da = (const Minima *) a; - const Minima *db = (const Minima *) b; - - return da->height - db->height; -} - -#define FLAG_QPEL 1 //must be 1 -#define FLAG_CHROMA 2 -#define FLAG_DIRECT 4 - -static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){ - const int offset[3]= { - y*c-> stride + x, - ((y*c->uvstride + x)>>1), - ((y*c->uvstride + x)>>1), - }; - int i; - for(i=0; i<3; i++){ - c->src[0][i]= src [i] + offset[i]; - c->ref[0][i]= ref [i] + offset[i]; - } - if(ref_index){ - for(i=0; i<3; i++){ - c->ref[ref_index][i]= ref2[i] + offset[i]; - } - } -} - -static int get_flags(MotionEstContext *c, int direct, int chroma){ - return ((c->avctx->flags&CODEC_FLAG_QPEL) ? FLAG_QPEL : 0) - + (direct ? FLAG_DIRECT : 0) - + (chroma ? FLAG_CHROMA : 0); -} - -static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby, - const int size, const int h, int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){ - MotionEstContext * const c= &s->me; - const int stride= c->stride; - const int hx= subx + (x<<(1+qpel)); - const int hy= suby + (y<<(1+qpel)); - uint8_t * const * const ref= c->ref[ref_index]; - uint8_t * const * const src= c->src[src_index]; - int d; - //FIXME check chroma 4mv, (no crashes ...) - assert(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1)); - if(x >= c->xmin && hx <= c->xmax<<(qpel+1) && y >= c->ymin && hy <= c->ymax<<(qpel+1)){ - const int time_pp= s->pp_time; - const int time_pb= s->pb_time; - const int mask= 2*qpel+1; - if(s->mv_type==MV_TYPE_8X8){ - int i; - for(i=0; i<4; i++){ - int fx = c->direct_basis_mv[i][0] + hx; - int fy = c->direct_basis_mv[i][1] + hy; - int bx = hx ? fx - c->co_located_mv[i][0] : c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(qpel+4)); - int by = hy ? fy - c->co_located_mv[i][1] : c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(qpel+4)); - int fxy= (fx&mask) + ((fy&mask)<<(qpel+1)); - int bxy= (bx&mask) + ((by&mask)<<(qpel+1)); - - uint8_t *dst= c->temp + 8*(i&1) + 8*stride*(i>>1); - if(qpel){ - c->qpel_put[1][fxy](dst, ref[0] + (fx>>2) + (fy>>2)*stride, stride); - c->qpel_avg[1][bxy](dst, ref[8] + (bx>>2) + (by>>2)*stride, stride); - }else{ - c->hpel_put[1][fxy](dst, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 8); - c->hpel_avg[1][bxy](dst, ref[8] + (bx>>1) + (by>>1)*stride, stride, 8); - } - } - }else{ - int fx = c->direct_basis_mv[0][0] + hx; - int fy = c->direct_basis_mv[0][1] + hy; - int bx = hx ? fx - c->co_located_mv[0][0] : (c->co_located_mv[0][0]*(time_pb - time_pp)/time_pp); - int by = hy ? fy - c->co_located_mv[0][1] : (c->co_located_mv[0][1]*(time_pb - time_pp)/time_pp); - int fxy= (fx&mask) + ((fy&mask)<<(qpel+1)); - int bxy= (bx&mask) + ((by&mask)<<(qpel+1)); - - if(qpel){ - c->qpel_put[1][fxy](c->temp , ref[0] + (fx>>2) + (fy>>2)*stride , stride); - c->qpel_put[1][fxy](c->temp + 8 , ref[0] + (fx>>2) + (fy>>2)*stride + 8 , stride); - c->qpel_put[1][fxy](c->temp + 8*stride, ref[0] + (fx>>2) + (fy>>2)*stride + 8*stride, stride); - c->qpel_put[1][fxy](c->temp + 8 + 8*stride, ref[0] + (fx>>2) + (fy>>2)*stride + 8 + 8*stride, stride); - c->qpel_avg[1][bxy](c->temp , ref[8] + (bx>>2) + (by>>2)*stride , stride); - c->qpel_avg[1][bxy](c->temp + 8 , ref[8] + (bx>>2) + (by>>2)*stride + 8 , stride); - c->qpel_avg[1][bxy](c->temp + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8*stride, stride); - c->qpel_avg[1][bxy](c->temp + 8 + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8 + 8*stride, stride); - }else{ - assert((fx>>1) + 16*s->mb_x >= -16); - assert((fy>>1) + 16*s->mb_y >= -16); - assert((fx>>1) + 16*s->mb_x <= s->width); - assert((fy>>1) + 16*s->mb_y <= s->height); - assert((bx>>1) + 16*s->mb_x >= -16); - assert((by>>1) + 16*s->mb_y >= -16); - assert((bx>>1) + 16*s->mb_x <= s->width); - assert((by>>1) + 16*s->mb_y <= s->height); - - c->hpel_put[0][fxy](c->temp, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 16); - c->hpel_avg[0][bxy](c->temp, ref[8] + (bx>>1) + (by>>1)*stride, stride, 16); - } - } - d = cmp_func(s, c->temp, src[0], stride, 16); - }else - d= 256*256*256*32; - return d; -} - -static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby, - const int size, const int h, int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel, int chroma){ - MotionEstContext * const c= &s->me; - const int stride= c->stride; - const int uvstride= c->uvstride; - const int dxy= subx + (suby<<(1+qpel)); //FIXME log2_subpel? - const int hx= subx + (x<<(1+qpel)); - const int hy= suby + (y<<(1+qpel)); - uint8_t * const * const ref= c->ref[ref_index]; - uint8_t * const * const src= c->src[src_index]; - int d; - //FIXME check chroma 4mv, (no crashes ...) - int uvdxy; /* no, it might not be used uninitialized */ - if(dxy){ - if(qpel){ - c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h) - if(chroma){ - int cx= hx/2; - int cy= hy/2; - cx= (cx>>1)|(cx&1); - cy= (cy>>1)|(cy&1); - uvdxy= (cx&1) + 2*(cy&1); - //FIXME x/y wrong, but mpeg4 qpel is sick anyway, we should drop as much of it as possible in favor for h264 - } - }else{ - c->hpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride, h); - if(chroma) - uvdxy= dxy | (x&1) | (2*(y&1)); - } - d = cmp_func(s, c->temp, src[0], stride, h); - }else{ - d = cmp_func(s, src[0], ref[0] + x + y*stride, stride, h); - if(chroma) - uvdxy= (x&1) + 2*(y&1); - } - if(chroma){ - uint8_t * const uvtemp= c->temp + 16*stride; - c->hpel_put[size+1][uvdxy](uvtemp , ref[1] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1); - c->hpel_put[size+1][uvdxy](uvtemp+8, ref[2] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1); - d += chroma_cmp_func(s, uvtemp , src[1], uvstride, h>>1); - d += chroma_cmp_func(s, uvtemp+8, src[2], uvstride, h>>1); - } - return d; -} - -static int cmp_simple(MpegEncContext *s, const int x, const int y, - int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func){ - return cmp_inline(s,x,y,0,0,0,16,ref_index,src_index, cmp_func, chroma_cmp_func, 0, 0); -} - -static int cmp_fpel_internal(MpegEncContext *s, const int x, const int y, - const int size, const int h, int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ - if(flags&FLAG_DIRECT){ - return cmp_direct_inline(s,x,y,0,0,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL); - }else{ - return cmp_inline(s,x,y,0,0,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0, flags&FLAG_CHROMA); - } -} - -static int cmp_internal(MpegEncContext *s, const int x, const int y, const int subx, const int suby, - const int size, const int h, int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ - if(flags&FLAG_DIRECT){ - return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL); - }else{ - return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags&FLAG_QPEL, flags&FLAG_CHROMA); - } -} - -/*! \brief compares a block (either a full macroblock or a partition thereof) - against a proposed motion-compensated prediction of that block - */ -static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby, - const int size, const int h, int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ - if(av_builtin_constant_p(flags) && av_builtin_constant_p(h) && av_builtin_constant_p(size) - && av_builtin_constant_p(subx) && av_builtin_constant_p(suby) - && flags==0 && h==16 && size==0 && subx==0 && suby==0){ - return cmp_simple(s,x,y,ref_index,src_index, cmp_func, chroma_cmp_func); - }else if(av_builtin_constant_p(subx) && av_builtin_constant_p(suby) - && subx==0 && suby==0){ - return cmp_fpel_internal(s,x,y,size,h,ref_index,src_index, cmp_func, chroma_cmp_func,flags); - }else{ - return cmp_internal(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, flags); - } -} - -static int cmp_hpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby, - const int size, const int h, int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ - if(flags&FLAG_DIRECT){ - return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0); - }else{ - return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 0, flags&FLAG_CHROMA); - } -} - -static int cmp_qpel(MpegEncContext *s, const int x, const int y, const int subx, const int suby, - const int size, const int h, int ref_index, int src_index, - me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags){ - if(flags&FLAG_DIRECT){ - return cmp_direct_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 1); - }else{ - return cmp_inline(s,x,y,subx,suby,size,h,ref_index,src_index, cmp_func, chroma_cmp_func, 1, flags&FLAG_CHROMA); - } -} - -#include "motion_est_template.c" - -static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){ - return 0; -} - -static void zero_hpel(uint8_t *a, const uint8_t *b, int stride, int h){ -} - -int ff_init_me(MpegEncContext *s){ - MotionEstContext * const c= &s->me; - int cache_size= FFMIN(ME_MAP_SIZE>>ME_MAP_SHIFT, 1<avctx->dia_size)&255, FFABS(s->avctx->pre_dia_size)&255); - - if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -ME_MAP_SIZE){ - av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n"); - return -1; - } - //special case of snow is needed because snow uses its own iterative ME code - if(s->me_method!=ME_ZERO && s->me_method!=ME_EPZS && s->me_method!=ME_X1 && s->avctx->codec_id != CODEC_ID_SNOW){ - av_log(s->avctx, AV_LOG_ERROR, "me_method is only allowed to be set to zero and epzs; for hex,umh,full and others see dia_size\n"); - return -1; - } - - c->avctx= s->avctx; - - if(cache_size < 2*dia_size && !c->stride){ - av_log(s->avctx, AV_LOG_INFO, "ME_MAP size may be a little small for the selected diamond size\n"); - } - - ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, c->avctx->me_pre_cmp); - ff_set_cmp(&s->dsp, s->dsp.me_cmp, c->avctx->me_cmp); - ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, c->avctx->me_sub_cmp); - ff_set_cmp(&s->dsp, s->dsp.mb_cmp, c->avctx->mb_cmp); - - c->flags = get_flags(c, 0, c->avctx->me_cmp &FF_CMP_CHROMA); - c->sub_flags= get_flags(c, 0, c->avctx->me_sub_cmp&FF_CMP_CHROMA); - c->mb_flags = get_flags(c, 0, c->avctx->mb_cmp &FF_CMP_CHROMA); - -/*FIXME s->no_rounding b_type*/ - if(s->flags&CODEC_FLAG_QPEL){ - c->sub_motion_search= qpel_motion_search; - c->qpel_avg= s->dsp.avg_qpel_pixels_tab; - if(s->no_rounding) c->qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab; - else c->qpel_put= s->dsp.put_qpel_pixels_tab; - }else{ - if(c->avctx->me_sub_cmp&FF_CMP_CHROMA) - c->sub_motion_search= hpel_motion_search; - else if( c->avctx->me_sub_cmp == FF_CMP_SAD - && c->avctx-> me_cmp == FF_CMP_SAD - && c->avctx-> mb_cmp == FF_CMP_SAD) - c->sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles - else - c->sub_motion_search= hpel_motion_search; - } - c->hpel_avg= s->dsp.avg_pixels_tab; - if(s->no_rounding) c->hpel_put= s->dsp.put_no_rnd_pixels_tab; - else c->hpel_put= s->dsp.put_pixels_tab; - - if(s->linesize){ - c->stride = s->linesize; - c->uvstride= s->uvlinesize; - }else{ - c->stride = 16*s->mb_width + 32; - c->uvstride= 8*s->mb_width + 16; - } - - /* 8x8 fullpel search would need a 4x4 chroma compare, which we do - * not have yet, and even if we had, the motion estimation code - * does not expect it. */ - if(s->codec_id != CODEC_ID_SNOW){ - if((c->avctx->me_cmp&FF_CMP_CHROMA)/* && !s->dsp.me_cmp[2]*/){ - s->dsp.me_cmp[2]= zero_cmp; - } - if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){ - s->dsp.me_sub_cmp[2]= zero_cmp; - } - c->hpel_put[2][0]= c->hpel_put[2][1]= - c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel; - } - - if(s->codec_id == CODEC_ID_H261){ - c->sub_motion_search= no_sub_motion_search; - } - - return 0; -} - -#if 0 -static int pix_dev(uint8_t * pix, int line_size, int mean) -{ - int s, i, j; - - s = 0; - for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j += 8) { - s += FFABS(pix[0]-mean); - s += FFABS(pix[1]-mean); - s += FFABS(pix[2]-mean); - s += FFABS(pix[3]-mean); - s += FFABS(pix[4]-mean); - s += FFABS(pix[5]-mean); - s += FFABS(pix[6]-mean); - s += FFABS(pix[7]-mean); - pix += 8; - } - pix += line_size - 16; - } - return s; -} -#endif - -static inline void no_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr) -{ - *mx_ptr = 16 * s->mb_x; - *my_ptr = 16 * s->mb_y; -} - -#define Z_THRESHOLD 256 - -#define CHECK_SAD_HALF_MV(suffix, x, y) \ -{\ - d= s->dsp.pix_abs[size][(x?1:0)+(y?2:0)](NULL, pix, ptr+((x)>>1), stride, h);\ - d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*penalty_factor;\ - COPY3_IF_LT(dminh, d, dx, x, dy, y)\ -} - -static inline int sad_hpel_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - int src_index, int ref_index, - int size, int h) -{ - MotionEstContext * const c= &s->me; - const int penalty_factor= c->sub_penalty_factor; - int mx, my, dminh; - uint8_t *pix, *ptr; - int stride= c->stride; - const int flags= c->sub_flags; - LOAD_COMMON - - assert(flags == 0); - - if(c->skip){ -// printf("S"); - *mx_ptr = 0; - *my_ptr = 0; - return dmin; - } -// printf("N"); - - pix = c->src[src_index][0]; - - mx = *mx_ptr; - my = *my_ptr; - ptr = c->ref[ref_index][0] + (my * stride) + mx; - - dminh = dmin; - - if (mx > xmin && mx < xmax && - my > ymin && my < ymax) { - int dx=0, dy=0; - int d, pen_x, pen_y; - const int index= (my<mb_x + s->mb_y*s->mb_stride; - - s->p_mv_table[xy][0] = mx; - s->p_mv_table[xy][1] = my; - - /* has already been set to the 4 MV if 4MV is done */ - if(mv4){ - int mot_xy= s->block_index[0]; - - s->current_picture.motion_val[0][mot_xy ][0]= mx; - s->current_picture.motion_val[0][mot_xy ][1]= my; - s->current_picture.motion_val[0][mot_xy+1][0]= mx; - s->current_picture.motion_val[0][mot_xy+1][1]= my; - - mot_xy += s->b8_stride; - s->current_picture.motion_val[0][mot_xy ][0]= mx; - s->current_picture.motion_val[0][mot_xy ][1]= my; - s->current_picture.motion_val[0][mot_xy+1][0]= mx; - s->current_picture.motion_val[0][mot_xy+1][1]= my; - } -} - -/** - * get fullpel ME search limits. - */ -static inline void get_limits(MpegEncContext *s, int x, int y) -{ - MotionEstContext * const c= &s->me; - int range= c->avctx->me_range >> (1 + !!(c->flags&FLAG_QPEL)); -/* - if(c->avctx->me_range) c->range= c->avctx->me_range >> 1; - else c->range= 16; -*/ - if (s->unrestricted_mv) { - c->xmin = - x - 16; - c->ymin = - y - 16; - c->xmax = - x + s->mb_width *16; - c->ymax = - y + s->mb_height*16; - } else if (s->out_format == FMT_H261){ - // Search range of H261 is different from other codec standards - c->xmin = (x > 15) ? - 15 : 0; - c->ymin = (y > 15) ? - 15 : 0; - c->xmax = (x < s->mb_width * 16 - 16) ? 15 : 0; - c->ymax = (y < s->mb_height * 16 - 16) ? 15 : 0; - } else { - c->xmin = - x; - c->ymin = - y; - c->xmax = - x + s->mb_width *16 - 16; - c->ymax = - y + s->mb_height*16 - 16; - } - if(range){ - c->xmin = FFMAX(c->xmin,-range); - c->xmax = FFMIN(c->xmax, range); - c->ymin = FFMAX(c->ymin,-range); - c->ymax = FFMIN(c->ymax, range); - } -} - -static inline void init_mv4_ref(MotionEstContext *c){ - const int stride= c->stride; - - c->ref[1][0] = c->ref[0][0] + 8; - c->ref[2][0] = c->ref[0][0] + 8*stride; - c->ref[3][0] = c->ref[2][0] + 8; - c->src[1][0] = c->src[0][0] + 8; - c->src[2][0] = c->src[0][0] + 8*stride; - c->src[3][0] = c->src[2][0] + 8; -} - -static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) -{ - MotionEstContext * const c= &s->me; - const int size= 1; - const int h=8; - int block; - int P[10][2]; - int dmin_sum=0, mx4_sum=0, my4_sum=0; - int same=1; - const int stride= c->stride; - uint8_t *mv_penalty= c->current_mv_penalty; - - init_mv4_ref(c); - - for(block=0; block<4; block++){ - int mx4, my4; - int pred_x4, pred_y4; - int dmin4; - static const int off[4]= {2, 1, 1, -1}; - const int mot_stride = s->b8_stride; - const int mot_xy = s->block_index[block]; - - P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; - P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; - - if(P_LEFT[0] > (c->xmax<xmax<first_slice_line && block<2) { - c->pred_x= pred_x4= P_LEFT[0]; - c->pred_y= pred_y4= P_LEFT[1]; - } else { - P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; - P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; - P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0]; - P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; - if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->xmax<xmax< (c->ymax<ymax<pred_x= pred_x4 = P_MEDIAN[0]; - c->pred_y= pred_y4 = P_MEDIAN[1]; - } - P_MV1[0]= mx; - P_MV1[1]= my; - - dmin4 = epzs_motion_search4(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift); - - dmin4= c->sub_motion_search(s, &mx4, &my4, dmin4, block, block, size, h); - - if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){ - int dxy; - const int offset= ((block&1) + (block>>1)*stride)*8; - uint8_t *dest_y = c->scratchpad + offset; - if(s->quarter_sample){ - uint8_t *ref= c->ref[block][0] + (mx4>>2) + (my4>>2)*stride; - dxy = ((my4 & 3) << 2) | (mx4 & 3); - - if(s->no_rounding) - s->dsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y , ref , stride); - else - s->dsp.put_qpel_pixels_tab [1][dxy](dest_y , ref , stride); - }else{ - uint8_t *ref= c->ref[block][0] + (mx4>>1) + (my4>>1)*stride; - dxy = ((my4 & 1) << 1) | (mx4 & 1); - - if(s->no_rounding) - s->dsp.put_no_rnd_pixels_tab[1][dxy](dest_y , ref , stride, h); - else - s->dsp.put_pixels_tab [1][dxy](dest_y , ref , stride, h); - } - dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*c->mb_penalty_factor; - }else - dmin_sum+= dmin4; - - if(s->quarter_sample){ - mx4_sum+= mx4/2; - my4_sum+= my4/2; - }else{ - mx4_sum+= mx4; - my4_sum+= my4; - } - - s->current_picture.motion_val[0][ s->block_index[block] ][0]= mx4; - s->current_picture.motion_val[0][ s->block_index[block] ][1]= my4; - - if(mx4 != mx || my4 != my) same=0; - } - - if(same) - return INT_MAX; - - if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){ - dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*16*stride, c->scratchpad, stride, 16); - } - - if(c->avctx->mb_cmp&FF_CMP_CHROMA){ - int dxy; - int mx, my; - int offset; - - mx= ff_h263_round_chroma(mx4_sum); - my= ff_h263_round_chroma(my4_sum); - dxy = ((my & 1) << 1) | (mx & 1); - - offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize; - - if(s->no_rounding){ - s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8); - s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8); - }else{ - s->dsp.put_pixels_tab [1][dxy](c->scratchpad , s->last_picture.data[1] + offset, s->uvlinesize, 8); - s->dsp.put_pixels_tab [1][dxy](c->scratchpad+8 , s->last_picture.data[2] + offset, s->uvlinesize, 8); - } - - dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad , s->uvlinesize, 8); - dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad+8, s->uvlinesize, 8); - } - - c->pred_x= mx; - c->pred_y= my; - - switch(c->avctx->mb_cmp&0xFF){ - /*case FF_CMP_SSE: - return dmin_sum+ 32*s->qscale*s->qscale;*/ - case FF_CMP_RD: - return dmin_sum; - default: - return dmin_sum+ 11*c->mb_penalty_factor; - } -} - -static inline void init_interlaced_ref(MpegEncContext *s, int ref_index){ - MotionEstContext * const c= &s->me; - - c->ref[1+ref_index][0] = c->ref[0+ref_index][0] + s->linesize; - c->src[1][0] = c->src[0][0] + s->linesize; - if(c->flags & FLAG_CHROMA){ - c->ref[1+ref_index][1] = c->ref[0+ref_index][1] + s->uvlinesize; - c->ref[1+ref_index][2] = c->ref[0+ref_index][2] + s->uvlinesize; - c->src[1][1] = c->src[0][1] + s->uvlinesize; - c->src[1][2] = c->src[0][2] + s->uvlinesize; - } -} - -static int interlaced_search(MpegEncContext *s, int ref_index, - int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select) -{ - MotionEstContext * const c= &s->me; - const int size=0; - const int h=8; - int block; - int P[10][2]; - uint8_t * const mv_penalty= c->current_mv_penalty; - int same=1; - const int stride= 2*s->linesize; - int dmin_sum= 0; - const int mot_stride= s->mb_stride; - const int xy= s->mb_x + s->mb_y*mot_stride; - - c->ymin>>=1; - c->ymax>>=1; - c->stride<<=1; - c->uvstride<<=1; - init_interlaced_ref(s, ref_index); - - for(block=0; block<2; block++){ - int field_select; - int best_dmin= INT_MAX; - int best_field= -1; - - for(field_select=0; field_select<2; field_select++){ - int dmin, mx_i, my_i; - int16_t (*mv_table)[2]= mv_tables[block][field_select]; - - if(user_field_select){ - assert(field_select==0 || field_select==1); - assert(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1); - if(field_select_tables[block][xy] != field_select) - continue; - } - - P_LEFT[0] = mv_table[xy - 1][0]; - P_LEFT[1] = mv_table[xy - 1][1]; - if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1); - - c->pred_x= P_LEFT[0]; - c->pred_y= P_LEFT[1]; - - if(!s->first_slice_line){ - P_TOP[0] = mv_table[xy - mot_stride][0]; - P_TOP[1] = mv_table[xy - mot_stride][1]; - P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0]; - P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1]; - if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1); - if(P_TOPRIGHT[0] < (c->xmin<<1)) P_TOPRIGHT[0]= (c->xmin<<1); - if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1); - if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1); - - P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); - P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); - } - P_MV1[0]= mx; //FIXME not correct if block != field_select - P_MV1[1]= my / 2; - - dmin = epzs_motion_search2(s, &mx_i, &my_i, P, block, field_select+ref_index, mv_table, (1<<16)>>1); - - dmin= c->sub_motion_search(s, &mx_i, &my_i, dmin, block, field_select+ref_index, size, h); - - mv_table[xy][0]= mx_i; - mv_table[xy][1]= my_i; - - if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){ - int dxy; - - //FIXME chroma ME - uint8_t *ref= c->ref[field_select+ref_index][0] + (mx_i>>1) + (my_i>>1)*stride; - dxy = ((my_i & 1) << 1) | (mx_i & 1); - - if(s->no_rounding){ - s->dsp.put_no_rnd_pixels_tab[size][dxy](c->scratchpad, ref , stride, h); - }else{ - s->dsp.put_pixels_tab [size][dxy](c->scratchpad, ref , stride, h); - } - dmin= s->dsp.mb_cmp[size](s, c->src[block][0], c->scratchpad, stride, h); - dmin+= (mv_penalty[mx_i-c->pred_x] + mv_penalty[my_i-c->pred_y] + 1)*c->mb_penalty_factor; - }else - dmin+= c->mb_penalty_factor; //field_select bits - - dmin += field_select != block; //slightly prefer same field - - if(dmin < best_dmin){ - best_dmin= dmin; - best_field= field_select; - } - } - { - int16_t (*mv_table)[2]= mv_tables[block][best_field]; - - if(mv_table[xy][0] != mx) same=0; //FIXME check if these checks work and are any good at all - if(mv_table[xy][1]&1) same=0; - if(mv_table[xy][1]*2 != my) same=0; - if(best_field != block) same=0; - } - - field_select_tables[block][xy]= best_field; - dmin_sum += best_dmin; - } - - c->ymin<<=1; - c->ymax<<=1; - c->stride>>=1; - c->uvstride>>=1; - - if(same) - return INT_MAX; - - switch(c->avctx->mb_cmp&0xFF){ - /*case FF_CMP_SSE: - return dmin_sum+ 32*s->qscale*s->qscale;*/ - case FF_CMP_RD: - return dmin_sum; - default: - return dmin_sum+ 11*c->mb_penalty_factor; - } -} - -static void clip_input_mv(MpegEncContext * s, int16_t *mv, int interlaced){ - int ymax= s->me.ymax>>interlaced; - int ymin= s->me.ymin>>interlaced; - - if(mv[0] < s->me.xmin) mv[0] = s->me.xmin; - if(mv[0] > s->me.xmax) mv[0] = s->me.xmax; - if(mv[1] < ymin) mv[1] = ymin; - if(mv[1] > ymax) mv[1] = ymax; -} - -static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int p_type){ - MotionEstContext * const c= &s->me; - Picture *p= s->current_picture_ptr; - int mb_xy= mb_x + mb_y*s->mb_stride; - int xy= 2*mb_x + 2*mb_y*s->b8_stride; - int mb_type= s->current_picture.mb_type[mb_xy]; - int flags= c->flags; - int shift= (flags&FLAG_QPEL) + 1; - int mask= (1<dsp.sse[0]; - me_cmp_func chroma_cmpf= s->dsp.sse[1]; - - if(p_type && USES_LIST(mb_type, 1)){ - av_log(c->avctx, AV_LOG_ERROR, "backward motion vector in P frame\n"); - return INT_MAX/2; - } - assert(IS_INTRA(mb_type) || USES_LIST(mb_type,0) || USES_LIST(mb_type,1)); - - for(i=0; i<4; i++){ - int xy= s->block_index[i]; - clip_input_mv(s, p->motion_val[0][xy], !!IS_INTERLACED(mb_type)); - clip_input_mv(s, p->motion_val[1][xy], !!IS_INTERLACED(mb_type)); - } - - if(IS_INTERLACED(mb_type)){ - int xy2= xy + s->b8_stride; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA; - c->stride<<=1; - c->uvstride<<=1; - - if(!(s->flags & CODEC_FLAG_INTERLACED_ME)){ - av_log(c->avctx, AV_LOG_ERROR, "Interlaced macroblock selected but interlaced motion estimation disabled\n"); - return INT_MAX/2; - } - - if(USES_LIST(mb_type, 0)){ - int field_select0= p->ref_index[0][4*mb_xy ]; - int field_select1= p->ref_index[0][4*mb_xy+2]; - assert(field_select0==0 ||field_select0==1); - assert(field_select1==0 ||field_select1==1); - init_interlaced_ref(s, 0); - - if(p_type){ - s->p_field_select_table[0][mb_xy]= field_select0; - s->p_field_select_table[1][mb_xy]= field_select1; - *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ]; - *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2]; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER_I; - }else{ - s->b_field_select_table[0][0][mb_xy]= field_select0; - s->b_field_select_table[0][1][mb_xy]= field_select1; - *(uint32_t*)s->b_field_mv_table[0][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ]; - *(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2]; - s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_FORWARD_I; - } - - x= p->motion_val[0][xy ][0]; - y= p->motion_val[0][xy ][1]; - d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0, 0, cmpf, chroma_cmpf, flags); - x= p->motion_val[0][xy2][0]; - y= p->motion_val[0][xy2][1]; - d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1, 1, cmpf, chroma_cmpf, flags); - } - if(USES_LIST(mb_type, 1)){ - int field_select0= p->ref_index[1][4*mb_xy ]; - int field_select1= p->ref_index[1][4*mb_xy+2]; - assert(field_select0==0 ||field_select0==1); - assert(field_select1==0 ||field_select1==1); - init_interlaced_ref(s, 2); - - s->b_field_select_table[1][0][mb_xy]= field_select0; - s->b_field_select_table[1][1][mb_xy]= field_select1; - *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[1][xy ]; - *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[1][xy2]; - if(USES_LIST(mb_type, 0)){ - s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BIDIR_I; - }else{ - s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BACKWARD_I; - } - - x= p->motion_val[1][xy ][0]; - y= p->motion_val[1][xy ][1]; - d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0+2, 0, cmpf, chroma_cmpf, flags); - x= p->motion_val[1][xy2][0]; - y= p->motion_val[1][xy2][1]; - d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1+2, 1, cmpf, chroma_cmpf, flags); - //FIXME bidir scores - } - c->stride>>=1; - c->uvstride>>=1; - }else if(IS_8X8(mb_type)){ - if(!(s->flags & CODEC_FLAG_4MV)){ - av_log(c->avctx, AV_LOG_ERROR, "4MV macroblock selected but 4MV encoding disabled\n"); - return INT_MAX/2; - } - cmpf= s->dsp.sse[1]; - chroma_cmpf= s->dsp.sse[1]; - init_mv4_ref(c); - for(i=0; i<4; i++){ - xy= s->block_index[i]; - x= p->motion_val[0][xy][0]; - y= p->motion_val[0][xy][1]; - d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 1, 8, i, i, cmpf, chroma_cmpf, flags); - } - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER4V; - }else{ - if(USES_LIST(mb_type, 0)){ - if(p_type){ - *(uint32_t*)s->p_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy]; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER; - }else if(USES_LIST(mb_type, 1)){ - *(uint32_t*)s->b_bidir_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy]; - *(uint32_t*)s->b_bidir_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy]; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BIDIR; - }else{ - *(uint32_t*)s->b_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy]; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_FORWARD; - } - x= p->motion_val[0][xy][0]; - y= p->motion_val[0][xy][1]; - d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 0, 0, cmpf, chroma_cmpf, flags); - }else if(USES_LIST(mb_type, 1)){ - *(uint32_t*)s->b_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy]; - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BACKWARD; - - x= p->motion_val[1][xy][0]; - y= p->motion_val[1][xy][1]; - d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 2, 0, cmpf, chroma_cmpf, flags); - }else - s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA; - } - return d; -} - -void ff_estimate_p_frame_motion(MpegEncContext * s, - int mb_x, int mb_y) -{ - MotionEstContext * const c= &s->me; - uint8_t *pix, *ppix; - int sum, mx, my, dmin; - int varc; ///< the variance of the block (sum of squared (p[y][x]-average)) - int vard; ///< sum of squared differences with the estimated motion vector - int P[10][2]; - const int shift= 1+s->quarter_sample; - int mb_type=0; - Picture * const pic= &s->current_picture; - - init_ref(c, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0); - - assert(s->quarter_sample==0 || s->quarter_sample==1); - assert(s->linesize == c->stride); - assert(s->uvlinesize == c->uvstride); - - c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); - c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); - c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; - - get_limits(s, 16*mb_x, 16*mb_y); - c->skip=0; - - /* intra / predictive decision */ - pix = c->src[0][0]; - sum = s->dsp.pix_sum(pix, s->linesize); - varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500; - - pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; - pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8; - c->mb_var_sum_temp += (varc+128)>>8; - - if(c->avctx->me_threshold){ - vard= check_input_motion(s, mb_x, mb_y, 1); - - if((vard+128)>>8 < c->avctx->me_threshold){ - int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); - int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20; - pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8; - c->mc_mb_var_sum_temp += (vard+128)>>8; - c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score); - return; - } - if((vard+128)>>8 < c->avctx->mb_threshold) - mb_type= s->mb_type[mb_x + mb_y*s->mb_stride]; - } - - switch(s->me_method) { - case ME_ZERO: - default: - no_motion_search(s, &mx, &my); - mx-= mb_x*16; - my-= mb_y*16; - dmin = 0; - break; - case ME_X1: - case ME_EPZS: - { - const int mot_stride = s->b8_stride; - const int mot_xy = s->block_index[0]; - - P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; - P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; - - if(P_LEFT[0] > (c->xmax<xmax<first_slice_line) { - P_TOP[0] = s->current_picture.motion_val[0][mot_xy - mot_stride ][0]; - P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; - P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0]; - P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1]; - if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->ymax<ymax<out_format == FMT_H263){ - c->pred_x = P_MEDIAN[0]; - c->pred_y = P_MEDIAN[1]; - }else { /* mpeg1 at least */ - c->pred_x= P_LEFT[0]; - c->pred_y= P_LEFT[1]; - } - }else{ - c->pred_x= P_LEFT[0]; - c->pred_y= P_LEFT[1]; - } - - } - dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16); - - break; - } - - /* At this point (mx,my) are full-pell and the relative displacement */ - ppix = c->ref[0][0] + (my * s->linesize) + mx; - - vard = s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16); - - pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8; -// pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; - c->mc_mb_var_sum_temp += (vard+128)>>8; - -#if 0 - printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n", - varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); -#endif - if(mb_type){ - int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); - int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20; - c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score); - - if(mb_type == CANDIDATE_MB_TYPE_INTER){ - c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); - set_p_mv_tables(s, mx, my, 1); - }else{ - mx <<=shift; - my <<=shift; - } - if(mb_type == CANDIDATE_MB_TYPE_INTER4V){ - h263_mv4_search(s, mx, my, shift); - - set_p_mv_tables(s, mx, my, 0); - } - if(mb_type == CANDIDATE_MB_TYPE_INTER_I){ - interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 1); - } - }else if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ - int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); - int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20; - c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score); - - if (vard*2 + 200*256 > varc) - mb_type|= CANDIDATE_MB_TYPE_INTRA; - if (varc*2 + 200*256 > vard || s->qscale > 24){ -// if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){ - mb_type|= CANDIDATE_MB_TYPE_INTER; - c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); - if(s->flags&CODEC_FLAG_MV0) - if(mx || my) - mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference - }else{ - mx <<=shift; - my <<=shift; - } - if((s->flags&CODEC_FLAG_4MV) - && !c->skip && varc>50<<8 && vard>10<<8){ - if(h263_mv4_search(s, mx, my, shift) < INT_MAX) - mb_type|=CANDIDATE_MB_TYPE_INTER4V; - - set_p_mv_tables(s, mx, my, 0); - }else - set_p_mv_tables(s, mx, my, 1); - if((s->flags&CODEC_FLAG_INTERLACED_ME) - && !c->skip){ //FIXME varc/d checks - if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX) - mb_type |= CANDIDATE_MB_TYPE_INTER_I; - } - }else{ - int intra_score, i; - mb_type= CANDIDATE_MB_TYPE_INTER; - - dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); - if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) - dmin= ff_get_mb_score(s, mx, my, 0, 0, 0, 16, 1); - - if((s->flags&CODEC_FLAG_4MV) - && !c->skip && varc>50<<8 && vard>10<<8){ - int dmin4= h263_mv4_search(s, mx, my, shift); - if(dmin4 < dmin){ - mb_type= CANDIDATE_MB_TYPE_INTER4V; - dmin=dmin4; - } - } - if((s->flags&CODEC_FLAG_INTERLACED_ME) - && !c->skip){ //FIXME varc/d checks - int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0); - if(dmin_i < dmin){ - mb_type = CANDIDATE_MB_TYPE_INTER_I; - dmin= dmin_i; - } - } - -// pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin; - set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V); - - /* get intra luma score */ - if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){ - intra_score= varc - 500; - }else{ - int mean= (sum+128)>>8; - mean*= 0x01010101; - - for(i=0; i<16; i++){ - *(uint32_t*)(&c->scratchpad[i*s->linesize+ 0]) = mean; - *(uint32_t*)(&c->scratchpad[i*s->linesize+ 4]) = mean; - *(uint32_t*)(&c->scratchpad[i*s->linesize+ 8]) = mean; - *(uint32_t*)(&c->scratchpad[i*s->linesize+12]) = mean; - } - - intra_score= s->dsp.mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16); - } -#if 0 //FIXME - /* get chroma score */ - if(c->avctx->mb_cmp&FF_CMP_CHROMA){ - for(i=1; i<3; i++){ - uint8_t *dest_c; - int mean; - - if(s->out_format == FMT_H263){ - mean= (s->dc_val[i][mb_x + mb_y*s->b8_stride] + 4)>>3; //FIXME not exact but simple ;) - }else{ - mean= (s->last_dc[i] + 4)>>3; - } - dest_c = s->new_picture.data[i] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; - - mean*= 0x01010101; - for(i=0; i<8; i++){ - *(uint32_t*)(&c->scratchpad[i*s->uvlinesize+ 0]) = mean; - *(uint32_t*)(&c->scratchpad[i*s->uvlinesize+ 4]) = mean; - } - - intra_score+= s->dsp.mb_cmp[1](s, c->scratchpad, dest_c, s->uvlinesize); - } - } -#endif - intra_score += c->mb_penalty_factor*16; - - if(intra_score < dmin){ - mb_type= CANDIDATE_MB_TYPE_INTRA; - s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup - }else - s->current_picture.mb_type[mb_y*s->mb_stride + mb_x]= 0; - - { - int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100); - int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20; - c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score); - } - } - - s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type; -} - -int ff_pre_estimate_p_frame_motion(MpegEncContext * s, - int mb_x, int mb_y) -{ - MotionEstContext * const c= &s->me; - int mx, my, dmin; - int P[10][2]; - const int shift= 1+s->quarter_sample; - const int xy= mb_x + mb_y*s->mb_stride; - init_ref(c, s->new_picture.data, s->last_picture.data, NULL, 16*mb_x, 16*mb_y, 0); - - assert(s->quarter_sample==0 || s->quarter_sample==1); - - c->pre_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp); - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; - - get_limits(s, 16*mb_x, 16*mb_y); - c->skip=0; - - P_LEFT[0] = s->p_mv_table[xy + 1][0]; - P_LEFT[1] = s->p_mv_table[xy + 1][1]; - - if(P_LEFT[0] < (c->xmin<xmin<first_slice_line) { - c->pred_x= P_LEFT[0]; - c->pred_y= P_LEFT[1]; - P_TOP[0]= P_TOPRIGHT[0]= P_MEDIAN[0]= - P_TOP[1]= P_TOPRIGHT[1]= P_MEDIAN[1]= 0; //FIXME - } else { - P_TOP[0] = s->p_mv_table[xy + s->mb_stride ][0]; - P_TOP[1] = s->p_mv_table[xy + s->mb_stride ][1]; - P_TOPRIGHT[0] = s->p_mv_table[xy + s->mb_stride - 1][0]; - P_TOPRIGHT[1] = s->p_mv_table[xy + s->mb_stride - 1][1]; - if(P_TOP[1] < (c->ymin<ymin< (c->xmax<xmax<ymin<ymin<pred_x = P_MEDIAN[0]; - c->pred_y = P_MEDIAN[1]; - } - - dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16); - - s->p_mv_table[xy][0] = mx<p_mv_table[xy][1] = my<me; - int mx, my, dmin; - int P[10][2]; - const int shift= 1+s->quarter_sample; - const int mot_stride = s->mb_stride; - const int mot_xy = mb_y*mot_stride + mb_x; - uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_MV; - int mv_scale; - - c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); - c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); - c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); - c->current_mv_penalty= mv_penalty; - - get_limits(s, 16*mb_x, 16*mb_y); - - switch(s->me_method) { - case ME_ZERO: - default: - no_motion_search(s, &mx, &my); - dmin = 0; - mx-= mb_x*16; - my-= mb_y*16; - break; - case ME_X1: - case ME_EPZS: - { - P_LEFT[0] = mv_table[mot_xy - 1][0]; - P_LEFT[1] = mv_table[mot_xy - 1][1]; - - if(P_LEFT[0] > (c->xmax<xmax<first_slice_line) { - P_TOP[0] = mv_table[mot_xy - mot_stride ][0]; - P_TOP[1] = mv_table[mot_xy - mot_stride ][1]; - P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1 ][0]; - P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1 ][1]; - if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->ymax<ymax<pred_x= P_LEFT[0]; - c->pred_y= P_LEFT[1]; - } - - if(mv_table == s->b_forw_mv_table){ - mv_scale= (s->pb_time<<16) / (s->pp_time<pb_time - s->pp_time)<<16) / (s->pp_time<p_mv_table, mv_scale, 0, 16); - - break; - } - - dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16); - - if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) - dmin= ff_get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1); - -//printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my); -// s->mb_type[mb_y*s->mb_width + mb_x]= mb_type; - mv_table[mot_xy][0]= mx; - mv_table[mot_xy][1]= my; - - return dmin; -} - -static inline int check_bidir_mv(MpegEncContext * s, - int motion_fx, int motion_fy, - int motion_bx, int motion_by, - int pred_fx, int pred_fy, - int pred_bx, int pred_by, - int size, int h) -{ - //FIXME optimize? - //FIXME better f_code prediction (max mv & distance) - //FIXME pointers - MotionEstContext * const c= &s->me; - uint8_t * const mv_penalty_f= c->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame - uint8_t * const mv_penalty_b= c->mv_penalty[s->b_code] + MAX_MV; // f_code of the prev frame - int stride= c->stride; - uint8_t *dest_y = c->scratchpad; - uint8_t *ptr; - int dxy; - int src_x, src_y; - int fbmin; - uint8_t **src_data= c->src[0]; - uint8_t **ref_data= c->ref[0]; - uint8_t **ref2_data= c->ref[2]; - - if(s->quarter_sample){ - dxy = ((motion_fy & 3) << 2) | (motion_fx & 3); - src_x = motion_fx >> 2; - src_y = motion_fy >> 2; - - ptr = ref_data[0] + (src_y * stride) + src_x; - s->dsp.put_qpel_pixels_tab[0][dxy](dest_y , ptr , stride); - - dxy = ((motion_by & 3) << 2) | (motion_bx & 3); - src_x = motion_bx >> 2; - src_y = motion_by >> 2; - - ptr = ref2_data[0] + (src_y * stride) + src_x; - s->dsp.avg_qpel_pixels_tab[size][dxy](dest_y , ptr , stride); - }else{ - dxy = ((motion_fy & 1) << 1) | (motion_fx & 1); - src_x = motion_fx >> 1; - src_y = motion_fy >> 1; - - ptr = ref_data[0] + (src_y * stride) + src_x; - s->dsp.put_pixels_tab[size][dxy](dest_y , ptr , stride, h); - - dxy = ((motion_by & 1) << 1) | (motion_bx & 1); - src_x = motion_bx >> 1; - src_y = motion_by >> 1; - - ptr = ref2_data[0] + (src_y * stride) + src_x; - s->dsp.avg_pixels_tab[size][dxy](dest_y , ptr , stride, h); - } - - fbmin = (mv_penalty_f[motion_fx-pred_fx] + mv_penalty_f[motion_fy-pred_fy])*c->mb_penalty_factor - +(mv_penalty_b[motion_bx-pred_bx] + mv_penalty_b[motion_by-pred_by])*c->mb_penalty_factor - + s->dsp.mb_cmp[size](s, src_data[0], dest_y, stride, h); //FIXME new_pic - - if(c->avctx->mb_cmp&FF_CMP_CHROMA){ - } - //FIXME CHROMA !!! - - return fbmin; -} - -/* refine the bidir vectors in hq mode and return the score in both lq & hq mode*/ -static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) -{ - MotionEstContext * const c= &s->me; - const int mot_stride = s->mb_stride; - const int xy = mb_y *mot_stride + mb_x; - int fbmin; - int pred_fx= s->b_bidir_forw_mv_table[xy-1][0]; - int pred_fy= s->b_bidir_forw_mv_table[xy-1][1]; - int pred_bx= s->b_bidir_back_mv_table[xy-1][0]; - int pred_by= s->b_bidir_back_mv_table[xy-1][1]; - int motion_fx= s->b_bidir_forw_mv_table[xy][0]= s->b_forw_mv_table[xy][0]; - int motion_fy= s->b_bidir_forw_mv_table[xy][1]= s->b_forw_mv_table[xy][1]; - int motion_bx= s->b_bidir_back_mv_table[xy][0]= s->b_back_mv_table[xy][0]; - int motion_by= s->b_bidir_back_mv_table[xy][1]= s->b_back_mv_table[xy][1]; - const int flags= c->sub_flags; - const int qpel= flags&FLAG_QPEL; - const int shift= 1+qpel; - const int xmin= c->xmin<ymin<xmax<ymax<avctx->bidir_refine){ - int end; - static const uint8_t limittab[5]={0,8,32,64,80}; - const int limit= limittab[s->avctx->bidir_refine]; - static const int8_t vect[][4]={ -{ 0, 0, 0, 1}, { 0, 0, 0,-1}, { 0, 0, 1, 0}, { 0, 0,-1, 0}, { 0, 1, 0, 0}, { 0,-1, 0, 0}, { 1, 0, 0, 0}, {-1, 0, 0, 0}, - -{ 0, 0, 1, 1}, { 0, 0,-1,-1}, { 0, 1, 1, 0}, { 0,-1,-1, 0}, { 1, 1, 0, 0}, {-1,-1, 0, 0}, { 1, 0, 0, 1}, {-1, 0, 0,-1}, -{ 0, 1, 0, 1}, { 0,-1, 0,-1}, { 1, 0, 1, 0}, {-1, 0,-1, 0}, -{ 0, 0,-1, 1}, { 0, 0, 1,-1}, { 0,-1, 1, 0}, { 0, 1,-1, 0}, {-1, 1, 0, 0}, { 1,-1, 0, 0}, { 1, 0, 0,-1}, {-1, 0, 0, 1}, -{ 0,-1, 0, 1}, { 0, 1, 0,-1}, {-1, 0, 1, 0}, { 1, 0,-1, 0}, - -{ 0, 1, 1, 1}, { 0,-1,-1,-1}, { 1, 1, 1, 0}, {-1,-1,-1, 0}, { 1, 1, 0, 1}, {-1,-1, 0,-1}, { 1, 0, 1, 1}, {-1, 0,-1,-1}, -{ 0,-1, 1, 1}, { 0, 1,-1,-1}, {-1, 1, 1, 0}, { 1,-1,-1, 0}, { 1, 1, 0,-1}, {-1,-1, 0, 1}, { 1, 0,-1, 1}, {-1, 0, 1,-1}, -{ 0, 1,-1, 1}, { 0,-1, 1,-1}, { 1,-1, 1, 0}, {-1, 1,-1, 0}, {-1, 1, 0, 1}, { 1,-1, 0,-1}, { 1, 0, 1,-1}, {-1, 0,-1, 1}, -{ 0, 1, 1,-1}, { 0,-1,-1, 1}, { 1, 1,-1, 0}, {-1,-1, 1, 0}, { 1,-1, 0, 1}, {-1, 1, 0,-1}, {-1, 0, 1, 1}, { 1, 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}, - }; - static const uint8_t hash[]={ -HASH( 0, 0, 0, 1), HASH( 0, 0, 0,-1), HASH( 0, 0, 1, 0), HASH( 0, 0,-1, 0), HASH( 0, 1, 0, 0), HASH( 0,-1, 0, 0), HASH( 1, 0, 0, 0), HASH(-1, 0, 0, 0), - -HASH( 0, 0, 1, 1), HASH( 0, 0,-1,-1), HASH( 0, 1, 1, 0), HASH( 0,-1,-1, 0), HASH( 1, 1, 0, 0), HASH(-1,-1, 0, 0), HASH( 1, 0, 0, 1), HASH(-1, 0, 0,-1), -HASH( 0, 1, 0, 1), HASH( 0,-1, 0,-1), HASH( 1, 0, 1, 0), HASH(-1, 0,-1, 0), -HASH( 0, 0,-1, 1), HASH( 0, 0, 1,-1), HASH( 0,-1, 1, 0), HASH( 0, 1,-1, 0), HASH(-1, 1, 0, 0), HASH( 1,-1, 0, 0), HASH( 1, 0, 0,-1), HASH(-1, 0, 0, 1), -HASH( 0,-1, 0, 1), HASH( 0, 1, 0,-1), HASH(-1, 0, 1, 0), HASH( 1, 0,-1, 0), - -HASH( 0, 1, 1, 1), HASH( 0,-1,-1,-1), HASH( 1, 1, 1, 0), HASH(-1,-1,-1, 0), HASH( 1, 1, 0, 1), HASH(-1,-1, 0,-1), HASH( 1, 0, 1, 1), HASH(-1, 0,-1,-1), -HASH( 0,-1, 1, 1), HASH( 0, 1,-1,-1), HASH(-1, 1, 1, 0), HASH( 1,-1,-1, 0), HASH( 1, 1, 0,-1), HASH(-1,-1, 0, 1), HASH( 1, 0,-1, 1), HASH(-1, 0, 1,-1), -HASH( 0, 1,-1, 1), HASH( 0,-1, 1,-1), HASH( 1,-1, 1, 0), HASH(-1, 1,-1, 0), HASH(-1, 1, 0, 1), HASH( 1,-1, 0,-1), HASH( 1, 0, 1,-1), HASH(-1, 0,-1, 1), -HASH( 0, 1, 1,-1), HASH( 0,-1,-1, 1), HASH( 1, 1,-1, 0), HASH(-1,-1, 1, 0), HASH( 1,-1, 0, 1), HASH(-1, 1, 0,-1), HASH(-1, 0, 1, 1), HASH( 1, 0,-1,-1), - -HASH( 1, 1, 1, 1), HASH(-1,-1,-1,-1), -HASH( 1, 1, 1,-1), HASH(-1,-1,-1, 1), HASH( 1, 1,-1, 1), HASH(-1,-1, 1,-1), HASH( 1,-1, 1, 1), HASH(-1, 1,-1,-1), HASH(-1, 1, 1, 1), HASH( 1,-1,-1,-1), -HASH( 1, 1,-1,-1), HASH(-1,-1, 1, 1), HASH( 1,-1,-1, 1), HASH(-1, 1, 1,-1), HASH( 1,-1, 1,-1), HASH(-1, 1,-1, 1), -}; - -#define CHECK_BIDIR(fx,fy,bx,by)\ - if( !map[(hashidx+HASH(fx,fy,bx,by))&255]\ - &&(fx<=0 || motion_fx+fx<=xmax) && (fy<=0 || motion_fy+fy<=ymax) && (bx<=0 || motion_bx+bx<=xmax) && (by<=0 || motion_by+by<=ymax)\ - &&(fx>=0 || motion_fx+fx>=xmin) && (fy>=0 || motion_fy+fy>=ymin) && (bx>=0 || motion_bx+bx>=xmin) && (by>=0 || motion_by+by>=ymin)){\ - int score;\ - map[(hashidx+HASH(fx,fy,bx,by))&255] = 1;\ - score= check_bidir_mv(s, motion_fx+fx, motion_fy+fy, motion_bx+bx, motion_by+by, pred_fx, pred_fy, pred_bx, pred_by, 0, 16);\ - if(score < fbmin){\ - hashidx += HASH(fx,fy,bx,by);\ - fbmin= score;\ - motion_fx+=fx;\ - motion_fy+=fy;\ - motion_bx+=bx;\ - motion_by+=by;\ - end=0;\ - }\ - } -#define CHECK_BIDIR2(a,b,c,d)\ -CHECK_BIDIR(a,b,c,d)\ -CHECK_BIDIR(-(a),-(b),-(c),-(d)) - - do{ - int i; - int borderdist=0; - end=1; - - CHECK_BIDIR2(0,0,0,1) - CHECK_BIDIR2(0,0,1,0) - CHECK_BIDIR2(0,1,0,0) - CHECK_BIDIR2(1,0,0,0) - - for(i=8; ib_bidir_forw_mv_table[xy][0]= motion_fx; - s->b_bidir_forw_mv_table[xy][1]= motion_fy; - s->b_bidir_back_mv_table[xy][0]= motion_bx; - s->b_bidir_back_mv_table[xy][1]= motion_by; - - return fbmin; -} - -static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) -{ - MotionEstContext * const c= &s->me; - int P[10][2]; - const int mot_stride = s->mb_stride; - const int mot_xy = mb_y*mot_stride + mb_x; - const int shift= 1+s->quarter_sample; - int dmin, i; - const int time_pp= s->pp_time; - const int time_pb= s->pb_time; - int mx, my, xmin, xmax, ymin, ymax; - int16_t (*mv_table)[2]= s->b_direct_mv_table; - - c->current_mv_penalty= c->mv_penalty[1] + MAX_MV; - ymin= xmin=(-32)>>shift; - ymax= xmax= 31>>shift; - - if(IS_8X8(s->next_picture.mb_type[mot_xy])){ - s->mv_type= MV_TYPE_8X8; - }else{ - s->mv_type= MV_TYPE_16X16; - } - - for(i=0; i<4; i++){ - int index= s->block_index[i]; - int min, max; - - c->co_located_mv[i][0]= s->next_picture.motion_val[0][index][0]; - c->co_located_mv[i][1]= s->next_picture.motion_val[0][index][1]; - c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3)); - c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3)); -// c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3); -// c->direct_basis_mv[1][i][1]= c->co_located_mv[i][1]*(time_pb - time_pp)/time_pp + ((i>>1)<<(shift+3); - - max= FFMAX(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift; - min= FFMIN(c->direct_basis_mv[i][0], c->direct_basis_mv[i][0] - c->co_located_mv[i][0])>>shift; - max+= 16*mb_x + 1; // +-1 is for the simpler rounding - min+= 16*mb_x - 1; - xmax= FFMIN(xmax, s->width - max); - xmin= FFMAX(xmin, - 16 - min); - - max= FFMAX(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift; - min= FFMIN(c->direct_basis_mv[i][1], c->direct_basis_mv[i][1] - c->co_located_mv[i][1])>>shift; - max+= 16*mb_y + 1; // +-1 is for the simpler rounding - min+= 16*mb_y - 1; - ymax= FFMIN(ymax, s->height - max); - ymin= FFMAX(ymin, - 16 - min); - - if(s->mv_type == MV_TYPE_16X16) break; - } - - assert(xmax <= 15 && ymax <= 15 && xmin >= -16 && ymin >= -16); - - if(xmax < 0 || xmin >0 || ymax < 0 || ymin > 0){ - s->b_direct_mv_table[mot_xy][0]= 0; - s->b_direct_mv_table[mot_xy][1]= 0; - - return 256*256*256*64; - } - - c->xmin= xmin; - c->ymin= ymin; - c->xmax= xmax; - c->ymax= ymax; - c->flags |= FLAG_DIRECT; - c->sub_flags |= FLAG_DIRECT; - c->pred_x=0; - c->pred_y=0; - - P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin<first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped - P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<sub_flags&FLAG_QPEL) - dmin = qpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); - else - dmin = hpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); - - if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip) - dmin= ff_get_mb_score(s, mx, my, 0, 0, 0, 16, 1); - - get_limits(s, 16*mb_x, 16*mb_y); //restore c->?min/max, maybe not needed - - mv_table[mot_xy][0]= mx; - mv_table[mot_xy][1]= my; - c->flags &= ~FLAG_DIRECT; - c->sub_flags &= ~FLAG_DIRECT; - - return dmin; -} - -void ff_estimate_b_frame_motion(MpegEncContext * s, - int mb_x, int mb_y) -{ - MotionEstContext * const c= &s->me; - const int penalty_factor= c->mb_penalty_factor; - int fmin, bmin, dmin, fbmin, bimin, fimin; - int type=0; - const int xy = mb_y*s->mb_stride + mb_x; - init_ref(c, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2); - - get_limits(s, 16*mb_x, 16*mb_y); - - c->skip=0; - - if(s->codec_id == CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]){ - int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0 - - score= ((unsigned)(score*score + 128*256))>>16; - c->mc_mb_var_sum_temp += score; - s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE - s->mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0; - - return; - } - - if(c->avctx->me_threshold){ - int vard= check_input_motion(s, mb_x, mb_y, 0); - - if((vard+128)>>8 < c->avctx->me_threshold){ -// pix = c->src[0][0]; -// sum = s->dsp.pix_sum(pix, s->linesize); -// varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500; - -// pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8; - s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8; -/* pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8; - c->mb_var_sum_temp += (varc+128)>>8;*/ - c->mc_mb_var_sum_temp += (vard+128)>>8; -/* if (vard <= 64<<8 || vard < varc) { - c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); - }else{ - c->scene_change_score+= s->qscale * s->avctx->scenechange_factor; - }*/ - return; - } - if((vard+128)>>8 < c->avctx->mb_threshold){ - type= s->mb_type[mb_y*s->mb_stride + mb_x]; - if(type == CANDIDATE_MB_TYPE_DIRECT){ - direct_search(s, mb_x, mb_y); - } - if(type == CANDIDATE_MB_TYPE_FORWARD || type == CANDIDATE_MB_TYPE_BIDIR){ - c->skip=0; - ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code); - } - if(type == CANDIDATE_MB_TYPE_BACKWARD || type == CANDIDATE_MB_TYPE_BIDIR){ - c->skip=0; - ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code); - } - if(type == CANDIDATE_MB_TYPE_FORWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){ - c->skip=0; - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; - interlaced_search(s, 0, - s->b_field_mv_table[0], s->b_field_select_table[0], - s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 1); - } - if(type == CANDIDATE_MB_TYPE_BACKWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){ - c->skip=0; - c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV; - interlaced_search(s, 2, - s->b_field_mv_table[1], s->b_field_select_table[1], - s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 1); - } - return; - } - } - - if (s->codec_id == CODEC_ID_MPEG4) - dmin= direct_search(s, mb_x, mb_y); - else - dmin= INT_MAX; -//FIXME penalty stuff for non mpeg4 - c->skip=0; - fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) + 3*penalty_factor; - - c->skip=0; - bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + 2*penalty_factor; -//printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); - - c->skip=0; - fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor; -//printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin); - - if(s->flags & CODEC_FLAG_INTERLACED_ME){ -//FIXME mb type penalty - c->skip=0; - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; - fimin= interlaced_search(s, 0, - s->b_field_mv_table[0], s->b_field_select_table[0], - s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0); - c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV; - bimin= interlaced_search(s, 2, - s->b_field_mv_table[1], s->b_field_select_table[1], - s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0); - }else - fimin= bimin= INT_MAX; - - { - int score= fmin; - type = CANDIDATE_MB_TYPE_FORWARD; - - if (dmin <= score){ - score = dmin; - type = CANDIDATE_MB_TYPE_DIRECT; - } - if(bmin>16; - c->mc_mb_var_sum_temp += score; - s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE - } - - if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ - type= CANDIDATE_MB_TYPE_FORWARD | CANDIDATE_MB_TYPE_BACKWARD | CANDIDATE_MB_TYPE_BIDIR | CANDIDATE_MB_TYPE_DIRECT; - if(fimin < INT_MAX) - type |= CANDIDATE_MB_TYPE_FORWARD_I; - if(bimin < INT_MAX) - type |= CANDIDATE_MB_TYPE_BACKWARD_I; - if(fimin < INT_MAX && bimin < INT_MAX){ - type |= CANDIDATE_MB_TYPE_BIDIR_I; - } - //FIXME something smarter - if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB - if(s->codec_id == CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && s->flags&CODEC_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy]) - type |= CANDIDATE_MB_TYPE_DIRECT0; -#if 0 - if(s->out_format == FMT_MPEG1) - type |= CANDIDATE_MB_TYPE_INTRA; -#endif - } - - s->mb_type[mb_y*s->mb_stride + mb_x]= type; -} - -/* find best f_code for ME which do unlimited searches */ -int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) -{ - if(s->me_method>=ME_EPZS){ - int score[8]; - int i, y, range= s->avctx->me_range ? s->avctx->me_range : (INT_MAX/2); - uint8_t * fcode_tab= s->fcode_tab; - int best_fcode=-1; - int best_score=-10000000; - - if(s->msmpeg4_version) - range= FFMIN(range, 16); - else if(s->codec_id == CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) - range= FFMIN(range, 256); - - for(i=0; i<8; i++) score[i]= s->mb_num*(8-i); - - for(y=0; ymb_height; y++){ - int x; - int xy= y*s->mb_stride; - for(x=0; xmb_width; x++){ - if(s->mb_type[xy] & type){ - int mx= mv_table[xy][0]; - int my= mv_table[xy][1]; - int fcode= FFMAX(fcode_tab[mx + MAX_MV], - fcode_tab[my + MAX_MV]); - int j; - - if(mx >= range || mx < -range || - my >= range || my < -range) - continue; - - for(j=0; jpict_type==FF_B_TYPE || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy]) - score[j]-= 170; - } - } - xy++; - } - } - - for(i=1; i<8; i++){ - if(score[i] > best_score){ - best_score= score[i]; - best_fcode= i; - } -// printf("%d %d\n", i, score[i]); - } - -// printf("fcode: %d type: %d\n", i, s->pict_type); - return best_fcode; -/* for(i=0; i<=MAX_FCODE; i++){ - printf("%d ", mv_num[i]); - } - printf("\n");*/ - }else{ - return 1; - } -} - -void ff_fix_long_p_mvs(MpegEncContext * s) -{ - MotionEstContext * const c= &s->me; - const int f_code= s->f_code; - int y, range; - assert(s->pict_type==FF_P_TYPE); - - range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code); - - assert(range <= 16 || !s->msmpeg4_version); - assert(range <=256 || !(s->codec_id == CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL)); - - if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range; - -//printf("%d no:%d %d//\n", clip, noclip, f_code); - if(s->flags&CODEC_FLAG_4MV){ - const int wrap= s->b8_stride; - - /* clip / convert to intra 8x8 type MVs */ - for(y=0; ymb_height; y++){ - int xy= y*2*wrap; - int i= y*s->mb_stride; - int x; - - for(x=0; xmb_width; x++){ - if(s->mb_type[i]&CANDIDATE_MB_TYPE_INTER4V){ - int block; - for(block=0; block<4; block++){ - int off= (block& 1) + (block>>1)*wrap; - int mx= s->current_picture.motion_val[0][ xy + off ][0]; - int my= s->current_picture.motion_val[0][ xy + off ][1]; - - if( mx >=range || mx <-range - || my >=range || my <-range){ - s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V; - s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA; - s->current_picture.mb_type[i]= CANDIDATE_MB_TYPE_INTRA; - } - } - } - xy+=2; - i++; - } - } - } -} - -/** - * - * @param truncate 1 for truncation, 0 for using intra - */ -void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select, - int16_t (*mv_table)[2], int f_code, int type, int truncate) -{ - MotionEstContext * const c= &s->me; - int y, h_range, v_range; - - // RAL: 8 in MPEG-1, 16 in MPEG-4 - int range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code); - - if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range; - - h_range= range; - v_range= field_select_table ? range>>1 : range; - - /* clip / convert to intra 16x16 type MVs */ - for(y=0; ymb_height; y++){ - int x; - int xy= y*s->mb_stride; - for(x=0; xmb_width; x++){ - if (s->mb_type[xy] & type){ // RAL: "type" test added... - if(field_select_table==NULL || field_select_table[xy] == field_select){ - if( mv_table[xy][0] >=h_range || mv_table[xy][0] <-h_range - || mv_table[xy][1] >=v_range || mv_table[xy][1] <-v_range){ - - if(truncate){ - if (mv_table[xy][0] > h_range-1) mv_table[xy][0]= h_range-1; - else if(mv_table[xy][0] < -h_range ) mv_table[xy][0]= -h_range; - if (mv_table[xy][1] > v_range-1) mv_table[xy][1]= v_range-1; - else if(mv_table[xy][1] < -v_range ) mv_table[xy][1]= -v_range; - }else{ - s->mb_type[xy] &= ~type; - s->mb_type[xy] |= CANDIDATE_MB_TYPE_INTRA; - mv_table[xy][0]= - mv_table[xy][1]= 0; - } - } - } - } - xy++; - } - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/motion_est_template.c b/tizen/distrib/ffmpeg/libavcodec/motion_est_template.c deleted file mode 100644 index 8f730ef..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/motion_est_template.c +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * Motion estimation - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Motion estimation template. - */ - -//Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...) -#define LOAD_COMMON\ - uint32_t av_unused * const score_map= c->score_map;\ - const int av_unused xmin= c->xmin;\ - const int av_unused ymin= c->ymin;\ - const int av_unused xmax= c->xmax;\ - const int av_unused ymax= c->ymax;\ - uint8_t *mv_penalty= c->current_mv_penalty;\ - const int pred_x= c->pred_x;\ - const int pred_y= c->pred_y;\ - -#define CHECK_HALF_MV(dx, dy, x, y)\ -{\ - const int hx= 2*(x)+(dx);\ - const int hy= 2*(y)+(dy);\ - d= cmp_hpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);\ - d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\ - COPY3_IF_LT(dmin, d, bx, hx, by, hy)\ -} - -#if 0 -static int hpel_motion_search)(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - uint8_t *ref_data[3], - int size) -{ - const int xx = 16 * s->mb_x + 8*(n&1); - const int yy = 16 * s->mb_y + 8*(n>>1); - const int mx = *mx_ptr; - const int my = *my_ptr; - const int penalty_factor= c->sub_penalty_factor; - - LOAD_COMMON - - // INIT; - //FIXME factorize - me_cmp_func cmp, chroma_cmp, cmp_sub, chroma_cmp_sub; - - if(s->no_rounding /*FIXME b_type*/){ - hpel_put= &s->dsp.put_no_rnd_pixels_tab[size]; - chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1]; - }else{ - hpel_put=& s->dsp.put_pixels_tab[size]; - chroma_hpel_put= &s->dsp.put_pixels_tab[size+1]; - } - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - cmp_sub= s->dsp.me_sub_cmp[size]; - chroma_cmp_sub= s->dsp.me_sub_cmp[size+1]; - - if(c->skip){ //FIXME somehow move up (benchmark) - *mx_ptr = 0; - *my_ptr = 0; - return dmin; - } - - if(c->avctx->me_cmp != c->avctx->me_sub_cmp){ - CMP_HPEL(dmin, 0, 0, mx, my, size); - if(mx || my) - dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor; - } - - if (mx > xmin && mx < xmax && - my > ymin && my < ymax) { - int bx=2*mx, by=2*my; - int d= dmin; - - CHECK_HALF_MV(1, 1, mx-1, my-1) - CHECK_HALF_MV(0, 1, mx , my-1) - CHECK_HALF_MV(1, 1, mx , my-1) - CHECK_HALF_MV(1, 0, mx-1, my ) - CHECK_HALF_MV(1, 0, mx , my ) - CHECK_HALF_MV(1, 1, mx-1, my ) - CHECK_HALF_MV(0, 1, mx , my ) - CHECK_HALF_MV(1, 1, mx , my ) - - assert(bx >= xmin*2 || bx <= xmax*2 || by >= ymin*2 || by <= ymax*2); - - *mx_ptr = bx; - *my_ptr = by; - }else{ - *mx_ptr =2*mx; - *my_ptr =2*my; - } - - return dmin; -} - -#else -static int hpel_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - int src_index, int ref_index, - int size, int h) -{ - MotionEstContext * const c= &s->me; - const int mx = *mx_ptr; - const int my = *my_ptr; - const int penalty_factor= c->sub_penalty_factor; - me_cmp_func cmp_sub, chroma_cmp_sub; - int bx=2*mx, by=2*my; - - LOAD_COMMON - int flags= c->sub_flags; - - //FIXME factorize - - cmp_sub= s->dsp.me_sub_cmp[size]; - chroma_cmp_sub= s->dsp.me_sub_cmp[size+1]; - - if(c->skip){ //FIXME move out of hpel? - *mx_ptr = 0; - *my_ptr = 0; - return dmin; - } - - if(c->avctx->me_cmp != c->avctx->me_sub_cmp){ - dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags); - if(mx || my || size>0) - dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor; - } - - if (mx > xmin && mx < xmax && - my > ymin && my < ymax) { - int d= dmin; - const int index= (my<penalty_factor; - const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)] - + (mv_penalty[bx-2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor; - const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)] - + (mv_penalty[bx+2 - pred_x] + mv_penalty[by - pred_y])*c->penalty_factor; - const int b= score_map[(index+(1<penalty_factor; - -#if 1 - int key; - int map_generation= c->map_generation; -#ifndef NDEBUG - uint32_t *map= c->map; -#endif - key= ((my-1)<= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2); - } - - *mx_ptr = bx; - *my_ptr = by; - - return dmin; -} -#endif - -static int no_sub_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - int src_index, int ref_index, - int size, int h) -{ - (*mx_ptr)<<=1; - (*my_ptr)<<=1; - return dmin; -} - -inline int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, - int ref_index, int size, int h, int add_rate) -{ -// const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp; - MotionEstContext * const c= &s->me; - const int penalty_factor= c->mb_penalty_factor; - const int flags= c->mb_flags; - const int qpel= flags & FLAG_QPEL; - const int mask= 1+2*qpel; - me_cmp_func cmp_sub, chroma_cmp_sub; - int d; - - LOAD_COMMON - - //FIXME factorize - - cmp_sub= s->dsp.mb_cmp[size]; - chroma_cmp_sub= s->dsp.mb_cmp[size+1]; - -// assert(!c->skip); -// assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp); - - d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags); - //FIXME check cbp before adding penalty for (0,0) vector - if(add_rate && (mx || my || size>0)) - d += (mv_penalty[mx - pred_x] + mv_penalty[my - pred_y])*penalty_factor; - - return d; -} - -#define CHECK_QUARTER_MV(dx, dy, x, y)\ -{\ - const int hx= 4*(x)+(dx);\ - const int hy= 4*(y)+(dy);\ - d= cmp_qpel(s, x, y, dx, dy, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ - d += (mv_penalty[hx - pred_x] + mv_penalty[hy - pred_y])*penalty_factor;\ - COPY3_IF_LT(dmin, d, bx, hx, by, hy)\ -} - -static int qpel_motion_search(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - int src_index, int ref_index, - int size, int h) -{ - MotionEstContext * const c= &s->me; - const int mx = *mx_ptr; - const int my = *my_ptr; - const int penalty_factor= c->sub_penalty_factor; - const int map_generation= c->map_generation; - const int subpel_quality= c->avctx->me_subpel_quality; - uint32_t *map= c->map; - me_cmp_func cmpf, chroma_cmpf; - me_cmp_func cmp_sub, chroma_cmp_sub; - - LOAD_COMMON - int flags= c->sub_flags; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; //factorize FIXME - //FIXME factorize - - cmp_sub= s->dsp.me_sub_cmp[size]; - chroma_cmp_sub= s->dsp.me_sub_cmp[size+1]; - - if(c->skip){ //FIXME somehow move up (benchmark) - *mx_ptr = 0; - *my_ptr = 0; - return dmin; - } - - if(c->avctx->me_cmp != c->avctx->me_sub_cmp){ - dmin= cmp(s, mx, my, 0, 0, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags); - if(mx || my || size>0) - dmin += (mv_penalty[4*mx - pred_x] + mv_penalty[4*my - pred_y])*penalty_factor; - } - - if (mx > xmin && mx < xmax && - my > ymin && my < ymax) { - int bx=4*mx, by=4*my; - int d= dmin; - int i, nx, ny; - const int index= (my<me.dia_size>=2){ - const int tl= score_map[(index-(1<>10; - int i; - - if((nx&3)==0 && (ny&3)==0) continue; - - score += (mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor; - -// if(nx&1) score-=1024*c->penalty_factor; -// if(ny&1) score-=1024*c->penalty_factor; - - for(i=0; i<8; i++){ - if(score < best[i]){ - memmove(&best[i+1], &best[i], sizeof(int)*(7-i)); - memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i)); - best[i]= score; - best_pos[i][0]= nx + 4*mx; - best_pos[i][1]= ny + 4*my; - break; - } - } - } - } - }else{ - int tl; - //FIXME this could overflow (unlikely though) - const int cx = 4*(r - l); - const int cx2= r + l - 2*c; - const int cy = 4*(b - t); - const int cy2= b + t - 2*c; - int cxy; - - if(map[(index-(1<penalty_factor; - // if(ny&1) score-=32*c->penalty_factor; - - for(i=0; i<8; i++){ - if(score < best[i]){ - memmove(&best[i+1], &best[i], sizeof(int)*(7-i)); - memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i)); - best[i]= score; - best_pos[i][0]= nx + 4*mx; - best_pos[i][1]= ny + 4*my; - break; - } - } - } - } - } - for(i=0; i>2, ny>>2) - } - -#if 0 - const int tl= score_map[(index-(1<>2, (ny + oy[i])>>2) - } -#endif -#if 0 - //outer ring - CHECK_QUARTER_MV(1, 3, mx-1, my-1) - CHECK_QUARTER_MV(1, 2, mx-1, my-1) - CHECK_QUARTER_MV(1, 1, mx-1, my-1) - CHECK_QUARTER_MV(2, 1, mx-1, my-1) - CHECK_QUARTER_MV(3, 1, mx-1, my-1) - CHECK_QUARTER_MV(0, 1, mx , my-1) - CHECK_QUARTER_MV(1, 1, mx , my-1) - CHECK_QUARTER_MV(2, 1, mx , my-1) - CHECK_QUARTER_MV(3, 1, mx , my-1) - CHECK_QUARTER_MV(3, 2, mx , my-1) - CHECK_QUARTER_MV(3, 3, mx , my-1) - CHECK_QUARTER_MV(3, 0, mx , my ) - CHECK_QUARTER_MV(3, 1, mx , my ) - CHECK_QUARTER_MV(3, 2, mx , my ) - CHECK_QUARTER_MV(3, 3, mx , my ) - CHECK_QUARTER_MV(2, 3, mx , my ) - CHECK_QUARTER_MV(1, 3, mx , my ) - CHECK_QUARTER_MV(0, 3, mx , my ) - CHECK_QUARTER_MV(3, 3, mx-1, my ) - CHECK_QUARTER_MV(2, 3, mx-1, my ) - CHECK_QUARTER_MV(1, 3, mx-1, my ) - CHECK_QUARTER_MV(1, 2, mx-1, my ) - CHECK_QUARTER_MV(1, 1, mx-1, my ) - CHECK_QUARTER_MV(1, 0, mx-1, my ) -#endif - assert(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4); - - *mx_ptr = bx; - *my_ptr = by; - }else{ - *mx_ptr =4*mx; - *my_ptr =4*my; - } - - return dmin; -} - - -#define CHECK_MV(x,y)\ -{\ - const int key= ((y)<= xmin);\ - assert((x) <= xmax);\ - assert((y) >= ymin);\ - assert((y) <= ymax);\ -/*printf("check_mv %d %d\n", x, y);*/\ - if(map[index]!=key){\ - d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ - map[index]= key;\ - score_map[index]= d;\ - d += (mv_penalty[((x)<mb_x, s->mb_y);\ -if( (x)>(xmax<<(S)) ) printf("%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\ -if( (y)<(ymin<<(S)) ) printf("%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\ -if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\ - -#define LOAD_COMMON2\ - uint32_t *map= c->map;\ - const int qpel= flags&FLAG_QPEL;\ - const int shift= 1+qpel;\ - -static av_always_inline int small_diamond_search(MpegEncContext * s, int *best, int dmin, - int src_index, int ref_index, int const penalty_factor, - int size, int h, int flags) -{ - MotionEstContext * const c= &s->me; - me_cmp_func cmpf, chroma_cmpf; - int next_dir=-1; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - { /* ensure that the best point is in the MAP as h/qpel refinement needs it */ - const int key= (best[1]<xmin) CHECK_MV_DIR(x-1, y , 0) - if(dir!=3 && y>ymin) CHECK_MV_DIR(x , y-1, 1) - if(dir!=0 && xme; - me_cmp_func cmpf, chroma_cmpf; - int dia_size; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - for(dia_size=1; dia_size<=4; dia_size++){ - int dir; - const int x= best[0]; - const int y= best[1]; - - if(dia_size&(dia_size-1)) continue; - - if( x + dia_size > xmax - || x - dia_size < xmin - || y + dia_size > ymax - || y - dia_size < ymin) - continue; - - for(dir= 0; dirdx){ - dx^=dy; dy^=dx; dx^=dy; -} -stats[dy*8 + dx] ++; -if(256*256*256*64 % (stats[0]+1)==0){ - for(i=0; i<64; i++){ - if((i&7)==0) printf("\n"); - printf("%8d ", stats[i]); - } - printf("\n"); -} -} -#endif - } - return dmin; -} - -static int hex_search(MpegEncContext * s, int *best, int dmin, - int src_index, int ref_index, int const penalty_factor, - int size, int h, int flags, int dia_size) -{ - MotionEstContext * const c= &s->me; - me_cmp_func cmpf, chroma_cmpf; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - int x,y,d; - const int dec= dia_size & (dia_size-1); - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){ - do{ - x= best[0]; - y= best[1]; - - CHECK_CLIPPED_MV(x -dia_size , y); - CHECK_CLIPPED_MV(x+ dia_size , y); - CHECK_CLIPPED_MV(x+( dia_size>>1), y+dia_size); - CHECK_CLIPPED_MV(x+( dia_size>>1), y-dia_size); - if(dia_size>1){ - CHECK_CLIPPED_MV(x+(-dia_size>>1), y+dia_size); - CHECK_CLIPPED_MV(x+(-dia_size>>1), y-dia_size); - } - }while(best[0] != x || best[1] != y); - } - - return dmin; -} - -static int l2s_dia_search(MpegEncContext * s, int *best, int dmin, - int src_index, int ref_index, int const penalty_factor, - int size, int h, int flags) -{ - MotionEstContext * const c= &s->me; - me_cmp_func cmpf, chroma_cmpf; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - int x,y,i,d; - int dia_size= c->dia_size&0xFF; - const int dec= dia_size & (dia_size-1); - static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1}, - { 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}}; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){ - do{ - x= best[0]; - y= best[1]; - for(i=0; i<8; i++){ - CHECK_CLIPPED_MV(x+hex[i][0]*dia_size, y+hex[i][1]*dia_size); - } - }while(best[0] != x || best[1] != y); - } - - x= best[0]; - y= best[1]; - CHECK_CLIPPED_MV(x+1, y); - CHECK_CLIPPED_MV(x, y+1); - CHECK_CLIPPED_MV(x-1, y); - CHECK_CLIPPED_MV(x, y-1); - - return dmin; -} - -static int umh_search(MpegEncContext * s, int *best, int dmin, - int src_index, int ref_index, int const penalty_factor, - int size, int h, int flags) -{ - MotionEstContext * const c= &s->me; - me_cmp_func cmpf, chroma_cmpf; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - int x,y,x2,y2, i, j, d; - const int dia_size= c->dia_size&0xFE; - static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2}, - { 4,-2}, { 4,-1}, { 4, 0}, { 4, 1}, { 4, 2}, - {-2, 3}, { 0, 4}, { 2, 3}, - {-2,-3}, { 0,-4}, { 2,-3},}; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - x= best[0]; - y= best[1]; - for(x2=FFMAX(x-dia_size+1, xmin); x2<=FFMIN(x+dia_size-1,xmax); x2+=2){ - CHECK_MV(x2, y); - } - for(y2=FFMAX(y-dia_size/2+1, ymin); y2<=FFMIN(y+dia_size/2-1,ymax); y2+=2){ - CHECK_MV(x, y2); - } - - x= best[0]; - y= best[1]; - for(y2=FFMAX(y-2, ymin); y2<=FFMIN(y+2,ymax); y2++){ - for(x2=FFMAX(x-2, xmin); x2<=FFMIN(x+2,xmax); x2++){ - CHECK_MV(x2, y2); - } - } - -//FIXME prevent the CLIP stuff - - for(j=1; j<=dia_size/4; j++){ - for(i=0; i<16; i++){ - CHECK_CLIPPED_MV(x+hex[i][0]*j, y+hex[i][1]*j); - } - } - - return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, 2); -} - -static int full_search(MpegEncContext * s, int *best, int dmin, - int src_index, int ref_index, int const penalty_factor, - int size, int h, int flags) -{ - MotionEstContext * const c= &s->me; - me_cmp_func cmpf, chroma_cmpf; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - int x,y, d; - const int dia_size= c->dia_size&0xFF; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - for(y=FFMAX(-dia_size, ymin); y<=FFMIN(dia_size,ymax); y++){ - for(x=FFMAX(-dia_size, xmin); x<=FFMIN(dia_size,xmax); x++){ - CHECK_MV(x, y); - } - } - - x= best[0]; - y= best[1]; - d= dmin; - CHECK_CLIPPED_MV(x , y); - CHECK_CLIPPED_MV(x+1, y); - CHECK_CLIPPED_MV(x, y+1); - CHECK_CLIPPED_MV(x-1, y); - CHECK_CLIPPED_MV(x, y-1); - best[0]= x; - best[1]= y; - - return d; -} - -#define SAB_CHECK_MV(ax,ay)\ -{\ - const int key= ((ay)<= minima[j].height) j++;\ -\ - memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\ -\ - minima[j].checked= 0;\ - minima[j].height= d;\ - minima[j].x= ax;\ - minima[j].y= ay;\ - \ - i=-1;\ - continue;\ - }\ - }\ -} - -#define MAX_SAB_SIZE ME_MAP_SIZE -static int sab_diamond_search(MpegEncContext * s, int *best, int dmin, - int src_index, int ref_index, int const penalty_factor, - int size, int h, int flags) -{ - MotionEstContext * const c= &s->me; - me_cmp_func cmpf, chroma_cmpf; - Minima minima[MAX_SAB_SIZE]; - const int minima_count= FFABS(c->dia_size); - int i, j; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - /*Note j>=ME_MAP_MV_BITS; - minima[j].y= key & ((1< xmax || minima[j].x < xmin - || minima[j].y > ymax || minima[j].y < ymin) - continue; - - minima[j].checked=0; - if(minima[j].x || minima[j].y) - minima[j].height+= (mv_penalty[((minima[j].x)<= xmax || x <= xmin - || y >= ymax || y <= ymin) - continue; - - SAB_CHECK_MV(x-1, y) - SAB_CHECK_MV(x+1, y) - SAB_CHECK_MV(x , y-1) - SAB_CHECK_MV(x , y+1) - - minima[i].checked= 1; - } - - best[0]= minima[0].x; - best[1]= minima[0].y; - dmin= minima[0].height; - - if( best[0] < xmax && best[0] > xmin - && best[1] < ymax && best[1] > ymin){ - int d; - //ensure that the refernece samples for hpel refinement are in the map - CHECK_MV(best[0]-1, best[1]) - CHECK_MV(best[0]+1, best[1]) - CHECK_MV(best[0], best[1]-1) - CHECK_MV(best[0], best[1]+1) - } - return dmin; -} - -static int var_diamond_search(MpegEncContext * s, int *best, int dmin, - int src_index, int ref_index, int const penalty_factor, - int size, int h, int flags) -{ - MotionEstContext * const c= &s->me; - me_cmp_func cmpf, chroma_cmpf; - int dia_size; - LOAD_COMMON - LOAD_COMMON2 - int map_generation= c->map_generation; - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - for(dia_size=1; dia_size<=c->dia_size; dia_size++){ - int dir, start, end; - const int x= best[0]; - const int y= best[1]; - - start= FFMAX(0, y + dia_size - ymax); - end = FFMIN(dia_size, xmax - x + 1); - for(dir= start; dirme; - if(c->dia_size==-1) - return funny_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - else if(c->dia_size<-1) - return sab_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - else if(c->dia_size<2) - return small_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - else if(c->dia_size>1024) - return full_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - else if(c->dia_size>768) - return umh_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - else if(c->dia_size>512) - return hex_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags, c->dia_size&0xFF); - else if(c->dia_size>256) - return l2s_dia_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - else - return var_diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); -} - -/*! - \param P[10][2] a list of candidate mvs to check before starting the - iterative search. If one of the candidates is close to the optimal mv, then - it takes fewer iterations. And it increases the chance that we find the - optimal mv. - */ -static av_always_inline int epzs_motion_search_internal(MpegEncContext * s, int *mx_ptr, int *my_ptr, - int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], - int ref_mv_scale, int flags, int size, int h) -{ - MotionEstContext * const c= &s->me; - int best[2]={0, 0}; /*!< x and y coordinates of the best motion vector. - i.e. the difference between the position of the - block currently being encoded and the position of - the block chosen to predict it from. */ - int d; ///< the score (cmp + penalty) of any given mv - int dmin; /*!< the best value of d, i.e. the score - corresponding to the mv stored in best[]. */ - int map_generation; - int penalty_factor; - const int ref_mv_stride= s->mb_stride; //pass as arg FIXME - const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME - me_cmp_func cmpf, chroma_cmpf; - - LOAD_COMMON - LOAD_COMMON2 - - if(c->pre_pass){ - penalty_factor= c->pre_penalty_factor; - cmpf= s->dsp.me_pre_cmp[size]; - chroma_cmpf= s->dsp.me_pre_cmp[size+1]; - }else{ - penalty_factor= c->penalty_factor; - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - } - - map_generation= update_map_generation(c); - - assert(cmpf); - dmin= cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags); - map[0]= map_generation; - score_map[0]= dmin; - - //FIXME precalc first term below? - if((s->pict_type == FF_B_TYPE && !(c->flags & FLAG_DIRECT)) || s->flags&CODEC_FLAG_MV0) - dmin += (mv_penalty[pred_x] + mv_penalty[pred_y])*penalty_factor; - - /* first line */ - if (s->first_slice_line) { - CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) - CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) - }else{ - if(dmin<((h*h*s->avctx->mv0_threshold)>>8) - && ( P_LEFT[0] |P_LEFT[1] - |P_TOP[0] |P_TOP[1] - |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){ - *mx_ptr= 0; - *my_ptr= 0; - c->skip=1; - return dmin; - } - CHECK_MV( P_MEDIAN[0] >>shift , P_MEDIAN[1] >>shift) - CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift) , (P_MEDIAN[1]>>shift)-1) - CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift) , (P_MEDIAN[1]>>shift)+1) - CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift)-1, (P_MEDIAN[1]>>shift) ) - CHECK_CLIPPED_MV((P_MEDIAN[0]>>shift)+1, (P_MEDIAN[1]>>shift) ) - CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) - CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift) - CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift) - CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) - } - if(dmin>h*h*4){ - if(c->pre_pass){ - CHECK_CLIPPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16) - if(!s->first_slice_line) - CHECK_CLIPPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) - }else{ - CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) - if(s->mb_y+1end_mb_y) //FIXME replace at least with last_slice_line - CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) - } - } - - if(c->avctx->last_predictor_count){ - const int count= c->avctx->last_predictor_count; - const int xstart= FFMAX(0, s->mb_x - count); - const int ystart= FFMAX(0, s->mb_y - count); - const int xend= FFMIN(s->mb_width , s->mb_x + count + 1); - const int yend= FFMIN(s->mb_height, s->mb_y + count + 1); - int mb_y; - - for(mb_y=ystart; mb_y>16; - int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16; - - if(mx>xmax || mxymax || myme; -//FIXME convert other functions in the same way if faster - if(c->flags==0 && h==16 && size==0){ - return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, 0, 0, 16); -// case FLAG_QPEL: -// return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, FLAG_QPEL); - }else{ - return epzs_motion_search_internal(s, mx_ptr, my_ptr, P, src_index, ref_index, last_mv, ref_mv_scale, c->flags, size, h); - } -} - -static int epzs_motion_search4(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int P[10][2], - int src_index, int ref_index, int16_t (*last_mv)[2], - int ref_mv_scale) -{ - MotionEstContext * const c= &s->me; - int best[2]={0, 0}; - int d, dmin; - int map_generation; - const int penalty_factor= c->penalty_factor; - const int size=1; - const int h=8; - const int ref_mv_stride= s->mb_stride; - const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride; - me_cmp_func cmpf, chroma_cmpf; - LOAD_COMMON - int flags= c->flags; - LOAD_COMMON2 - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - map_generation= update_map_generation(c); - - dmin = 1000000; -//printf("%d %d %d %d //",xmin, ymin, xmax, ymax); - /* first line */ - if (s->first_slice_line) { - CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) - CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) - CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) - }else{ - CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) - //FIXME try some early stop - CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) - CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) - CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) - CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) - CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) - } - if(dmin>64*4){ - CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) - if(s->mb_y+1end_mb_y) //FIXME replace at least with last_slice_line - CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) - } - - dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - - *mx_ptr= best[0]; - *my_ptr= best[1]; - -// printf("%d %d %d \n", best[0], best[1], dmin); - return dmin; -} - -//try to merge with above FIXME (needs PSNR test) -static int epzs_motion_search2(MpegEncContext * s, - int *mx_ptr, int *my_ptr, int P[10][2], - int src_index, int ref_index, int16_t (*last_mv)[2], - int ref_mv_scale) -{ - MotionEstContext * const c= &s->me; - int best[2]={0, 0}; - int d, dmin; - int map_generation; - const int penalty_factor= c->penalty_factor; - const int size=0; //FIXME pass as arg - const int h=8; - const int ref_mv_stride= s->mb_stride; - const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride; - me_cmp_func cmpf, chroma_cmpf; - LOAD_COMMON - int flags= c->flags; - LOAD_COMMON2 - - cmpf= s->dsp.me_cmp[size]; - chroma_cmpf= s->dsp.me_cmp[size+1]; - - map_generation= update_map_generation(c); - - dmin = 1000000; -//printf("%d %d %d %d //",xmin, ymin, xmax, ymax); - /* first line */ - if (s->first_slice_line) { - CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) - CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) - CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) - }else{ - CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) - //FIXME try some early stop - CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) - CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) - CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) - CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) - CHECK_CLIPPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) - } - if(dmin>64*4){ - CHECK_CLIPPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) - if(s->mb_y+1end_mb_y) //FIXME replace at least with last_slice_line - CHECK_CLIPPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, - (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) - } - - dmin= diamond_search(s, best, dmin, src_index, ref_index, penalty_factor, size, h, flags); - - *mx_ptr= best[0]; - *my_ptr= best[1]; - -// printf("%d %d %d \n", best[0], best[1], dmin); - return dmin; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/motionpixels.c b/tizen/distrib/ffmpeg/libavcodec/motionpixels.c deleted file mode 100644 index 9bc5e20..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/motionpixels.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Motion Pixels Video Decoder - * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" - -#define MAX_HUFF_CODES 16 - -#include "motionpixels_tablegen.h" - -typedef struct HuffCode { - int code; - uint8_t size; - uint8_t delta; -} HuffCode; - -typedef struct MotionPixelsContext { - AVCodecContext *avctx; - AVFrame frame; - DSPContext dsp; - uint8_t *changes_map; - int offset_bits_len; - int codes_count, current_codes_count; - int max_codes_bits; - HuffCode codes[MAX_HUFF_CODES]; - VLC vlc; - YuvPixel *vpt, *hpt; - uint8_t gradient_scale[3]; - uint8_t *bswapbuf; - int bswapbuf_size; -} MotionPixelsContext; - -static av_cold int mp_decode_init(AVCodecContext *avctx) -{ - MotionPixelsContext *mp = avctx->priv_data; - - motionpixels_tableinit(); - mp->avctx = avctx; - dsputil_init(&mp->dsp, avctx); - mp->changes_map = av_mallocz(avctx->width * avctx->height); - mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1; - mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel)); - mp->hpt = av_mallocz(avctx->height * avctx->width / 16 * sizeof(YuvPixel)); - avctx->pix_fmt = PIX_FMT_RGB555; - return 0; -} - -static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int count, int bits_len, int read_color) -{ - uint16_t *pixels; - int offset, w, h, color = 0, x, y, i; - - while (count--) { - offset = get_bits_long(gb, mp->offset_bits_len); - w = get_bits(gb, bits_len) + 1; - h = get_bits(gb, bits_len) + 1; - if (read_color) - color = get_bits(gb, 15); - x = offset % mp->avctx->width; - y = offset / mp->avctx->width; - if (y >= mp->avctx->height) - continue; - w = FFMIN(w, mp->avctx->width - x); - h = FFMIN(h, mp->avctx->height - y); - pixels = (uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; - while (h--) { - mp->changes_map[offset] = w; - if (read_color) - for (i = 0; i < w; ++i) - pixels[i] = color; - offset += mp->avctx->width; - pixels += mp->frame.linesize[0] / 2; - } - } -} - -static void mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int code) -{ - while (get_bits1(gb)) { - ++size; - if (size > mp->max_codes_bits) { - av_log(mp->avctx, AV_LOG_ERROR, "invalid code size %d/%d\n", size, mp->max_codes_bits); - return; - } - code <<= 1; - mp_get_code(mp, gb, size, code + 1); - } - if (mp->current_codes_count >= MAX_HUFF_CODES) { - av_log(mp->avctx, AV_LOG_ERROR, "too many codes\n"); - return; - } - mp->codes[mp->current_codes_count ].code = code; - mp->codes[mp->current_codes_count++].size = size; -} - -static void mp_read_codes_table(MotionPixelsContext *mp, GetBitContext *gb) -{ - if (mp->codes_count == 1) { - mp->codes[0].delta = get_bits(gb, 4); - } else { - int i; - - mp->max_codes_bits = get_bits(gb, 4); - for (i = 0; i < mp->codes_count; ++i) - mp->codes[i].delta = get_bits(gb, 4); - mp->current_codes_count = 0; - mp_get_code(mp, gb, 0, 0); - } -} - -static int mp_gradient(MotionPixelsContext *mp, int component, int v) -{ - int delta; - - delta = (v - 7) * mp->gradient_scale[component]; - mp->gradient_scale[component] = (v == 0 || v == 14) ? 2 : 1; - return delta; -} - -static YuvPixel mp_get_yuv_from_rgb(MotionPixelsContext *mp, int x, int y) -{ - int color; - - color = *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; - return mp_rgb_yuv_table[color]; -} - -static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const YuvPixel *p) -{ - int color; - - color = mp_yuv_to_rgb(p->y, p->v, p->u, 1); - *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2] = color; -} - -static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb) -{ - int i; - - i = (mp->codes_count == 1) ? 0 : get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1); - return mp->codes[i].delta; -} - -static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) -{ - YuvPixel p; - const int y0 = y * mp->avctx->width; - int w, i, x = 0; - - p = mp->vpt[y]; - if (mp->changes_map[y0 + x] == 0) { - memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); - ++x; - } - while (x < mp->avctx->width) { - w = mp->changes_map[y0 + x]; - if (w != 0) { - if ((y & 3) == 0) { - if (mp->changes_map[y0 + x + mp->avctx->width] < w || - mp->changes_map[y0 + x + mp->avctx->width * 2] < w || - mp->changes_map[y0 + x + mp->avctx->width * 3] < w) { - for (i = (x + 3) & ~3; i < x + w; i += 4) { - mp->hpt[((y / 4) * mp->avctx->width + i) / 4] = mp_get_yuv_from_rgb(mp, i, y); - } - } - } - x += w; - memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); - p = mp_get_yuv_from_rgb(mp, x - 1, y); - } else { - p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); - if ((x & 3) == 0) { - if ((y & 3) == 0) { - p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); - p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); - mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p; - } else { - p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v; - p.u = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].u; - } - } - mp_set_rgb_from_yuv(mp, x, y, &p); - ++x; - } - } -} - -static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) -{ - YuvPixel p; - int y, y0; - - for (y = 0; y < mp->avctx->height; ++y) { - if (mp->changes_map[y * mp->avctx->width] != 0) { - memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale)); - p = mp_get_yuv_from_rgb(mp, 0, y); - } else { - p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); - if ((y & 3) == 0) { - p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); - p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); - } - mp->vpt[y] = p; - mp_set_rgb_from_yuv(mp, 0, y, &p); - } - } - for (y0 = 0; y0 < 2; ++y0) - for (y = y0; y < mp->avctx->height; y += 2) - mp_decode_line(mp, gb, y); -} - -static int mp_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MotionPixelsContext *mp = avctx->priv_data; - GetBitContext gb; - int i, count1, count2, sz; - - mp->frame.reference = 1; - mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &mp->frame)) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - - /* le32 bitstream msb first */ - av_fast_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!mp->bswapbuf) - return AVERROR(ENOMEM); - mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4); - if (buf_size & 3) - memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); - init_get_bits(&gb, mp->bswapbuf, buf_size * 8); - - memset(mp->changes_map, 0, avctx->width * avctx->height); - for (i = !(avctx->extradata[1] & 2); i < 2; ++i) { - count1 = get_bits(&gb, 12); - count2 = get_bits(&gb, 12); - mp_read_changes_map(mp, &gb, count1, 8, i); - mp_read_changes_map(mp, &gb, count2, 4, i); - } - - mp->codes_count = get_bits(&gb, 4); - if (mp->codes_count == 0) - goto end; - - if (mp->changes_map[0] == 0) { - *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15); - mp->changes_map[0] = 1; - } - mp_read_codes_table(mp, &gb); - - sz = get_bits(&gb, 18); - if (avctx->extradata[0] != 5) - sz += get_bits(&gb, 18); - if (sz == 0) - goto end; - - init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0); - mp_decode_frame_helper(mp, &gb); - free_vlc(&mp->vlc); - -end: - *data_size = sizeof(AVFrame); - *(AVFrame *)data = mp->frame; - return buf_size; -} - -static av_cold int mp_decode_end(AVCodecContext *avctx) -{ - MotionPixelsContext *mp = avctx->priv_data; - - av_freep(&mp->changes_map); - av_freep(&mp->vpt); - av_freep(&mp->hpt); - av_freep(&mp->bswapbuf); - if (mp->frame.data[0]) - avctx->release_buffer(avctx, &mp->frame); - - return 0; -} - -AVCodec motionpixels_decoder = { - "motionpixels", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MOTIONPIXELS, - sizeof(MotionPixelsContext), - mp_decode_init, - NULL, - mp_decode_end, - mp_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.c b/tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.c deleted file mode 100644 index 5f1220a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Generate a header file for hardcoded motionpixels RGB to YUV table - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#define CONFIG_HARDCODED_TABLES 0 -#define MAX_NEG_CROP 0 -#define ff_cropTbl ((uint8_t *)NULL) -#include "motionpixels_tablegen.h" -#include "tableprint.h" - -int main(void) -{ - motionpixels_tableinit(); - - write_fileheader(); - - printf("static const YuvPixel mp_rgb_yuv_table[1 << 15] = {\n"); - write_int8_2d_array(mp_rgb_yuv_table, 1 << 15, 3); - printf("};\n"); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.h b/tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.h deleted file mode 100644 index 5d6df52..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/motionpixels_tablegen.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Header file for hardcoded motionpixels RGB to YUV table - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MOTIONPIXELS_TABLEGEN_H -#define MOTIONPIXELS_TABLEGEN_H - -#include - -typedef struct YuvPixel { - int8_t y, v, u; -} YuvPixel; - -static int mp_yuv_to_rgb(int y, int v, int u, int clip_rgb) { - static const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int r, g, b; - - r = (1000 * y + 701 * v) / 1000; - g = (1000 * y - 357 * v - 172 * u) / 1000; - b = (1000 * y + 886 * u) / 1000; - if (clip_rgb) - return ((cm[r * 8] & 0xF8) << 7) | ((cm[g * 8] & 0xF8) << 2) | (cm[b * 8] >> 3); - if ((unsigned)r < 32 && (unsigned)g < 32 && (unsigned)b < 32) - return (r << 10) | (g << 5) | b; - return 1 << 15; -} - -#if CONFIG_HARDCODED_TABLES -#define motionpixels_tableinit() -#include "libavcodec/motionpixels_tables.h" -#else -static YuvPixel mp_rgb_yuv_table[1 << 15]; - -static void mp_set_zero_yuv(YuvPixel *p) -{ - int i, j; - - for (i = 0; i < 31; ++i) { - for (j = 31; j > i; --j) - if (!(p[j].u | p[j].v | p[j].y)) - p[j] = p[j - 1]; - for (j = 0; j < 31 - i; ++j) - if (!(p[j].u | p[j].v | p[j].y)) - p[j] = p[j + 1]; - } -} - -static void mp_build_rgb_yuv_table(YuvPixel *p) -{ - int y, v, u, i; - - for (y = 0; y <= 31; ++y) - for (v = -31; v <= 31; ++v) - for (u = -31; u <= 31; ++u) { - i = mp_yuv_to_rgb(y, v, u, 0); - if (i < (1 << 15) && !(p[i].u | p[i].v | p[i].y)) { - p[i].y = y; - p[i].v = v; - p[i].u = u; - } - } - for (i = 0; i < 1024; ++i) - mp_set_zero_yuv(p + i * 32); -} - -static void motionpixels_tableinit(void) -{ - if (!mp_rgb_yuv_table[0].u) - mp_build_rgb_yuv_table(mp_rgb_yuv_table); -} -#endif /* CONFIG_HARDCODED_TABLES */ - -#endif /* MOTIONPIXELS_TABLEGEN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/movsub_bsf.c b/tizen/distrib/ffmpeg/libavcodec/movsub_bsf.c deleted file mode 100644 index 2423f2d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/movsub_bsf.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2008 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - - -static int text2movsub(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - if (buf_size > 0xffff) return 0; - *poutbuf_size = buf_size + 2; - *poutbuf = av_malloc(*poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE); - AV_WB16(*poutbuf, buf_size); - memcpy(*poutbuf + 2, buf, buf_size); - return 1; -} - -AVBitStreamFilter text2movsub_bsf={ - "text2movsub", - 0, - text2movsub, -}; - -static int mov2textsub(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - if (buf_size < 2) return 0; - *poutbuf_size = FFMIN(buf_size - 2, AV_RB16(buf)); - *poutbuf = av_malloc(*poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(*poutbuf, buf + 2, *poutbuf_size); - return 1; -} - -AVBitStreamFilter mov2textsub_bsf={ - "mov2textsub", - 0, - mov2textsub, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mp3_header_compress_bsf.c b/tizen/distrib/ffmpeg/libavcodec/mp3_header_compress_bsf.c deleted file mode 100644 index f5c5138..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mp3_header_compress_bsf.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "mpegaudio.h" - - -static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - uint32_t header, extraheader; - int mode_extension, header_size; - - if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); - return -1; - } - - header = AV_RB32(buf); - mode_extension= (header>>4)&3; - - if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){ -output_unchanged: - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - - av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); - return 0; - } - - if(avctx->extradata_size == 0){ - avctx->extradata_size=15; - avctx->extradata= av_malloc(avctx->extradata_size); - strcpy(avctx->extradata, "FFCMP3 0.0"); - memcpy(avctx->extradata+11, buf, 4); - } - if(avctx->extradata_size != 15){ - av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n"); - return -1; - } - extraheader = AV_RB32(avctx->extradata+11); - if((extraheader&MP3_MASK) != (header&MP3_MASK)) - goto output_unchanged; - - header_size= (header&0x10000) ? 4 : 6; - - *poutbuf_size= buf_size - header_size; - *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(avctx->channels==2){ - if((header & (3<<19)) != 3<<19){ - (*poutbuf)[1] &= 0x3F; - (*poutbuf)[1] |= mode_extension<<6; - FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]); - }else{ - (*poutbuf)[1] &= 0x8F; - (*poutbuf)[1] |= mode_extension<<4; - } - } - - return 1; -} - -AVBitStreamFilter mp3_header_compress_bsf={ - "mp3comp", - 0, - mp3_header_compress, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mp3_header_decompress_bsf.c b/tizen/distrib/ffmpeg/libavcodec/mp3_header_decompress_bsf.c deleted file mode 100644 index d897ed9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mp3_header_decompress_bsf.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "mpegaudio.h" -#include "mpegaudiodata.h" - - -static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - uint32_t header; - int sample_rate= avctx->sample_rate; - int sample_rate_index=0; - int lsf, mpeg25, bitrate_index, frame_size; - - header = AV_RB32(buf); - if(ff_mpa_check_header(header) >= 0){ - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - - return 0; - } - - if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){ - av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size); - return -1; - } - - header= AV_RB32(avctx->extradata+11) & MP3_MASK; - - lsf = sample_rate < (24000+32000)/2; - mpeg25 = sample_rate < (12000+16000)/2; - sample_rate_index= (header>>10)&3; - sample_rate= ff_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off - - for(bitrate_index=2; bitrate_index<30; bitrate_index++){ - frame_size = ff_mpa_bitrate_tab[lsf][2][bitrate_index>>1]; - frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); - if(frame_size == buf_size + 4) - break; - if(frame_size == buf_size + 6) - break; - } - if(bitrate_index == 30){ - av_log(avctx, AV_LOG_ERROR, "Could not find bitrate_index.\n"); - return -1; - } - - header |= (bitrate_index&1)<<9; - header |= (bitrate_index>>1)<<12; - header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0 - - *poutbuf_size= frame_size; - *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(avctx->channels==2){ - uint8_t *p= *poutbuf + frame_size - buf_size; - if(lsf){ - FFSWAP(int, p[1], p[2]); - header |= (p[1] & 0xC0)>>2; - p[1] &= 0x3F; - }else{ - header |= p[1] & 0x30; - p[1] &= 0xCF; - } - } - - AV_WB32(*poutbuf, header); - - return 1; -} - -AVBitStreamFilter mp3_header_decompress_bsf={ - "mp3decomp", - 0, - mp3_header_decompress, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpc.c b/tizen/distrib/ffmpeg/libavcodec/mpc.c deleted file mode 100644 index 30ae591..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpc.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Musepack decoder core - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Musepack decoder core - * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples - * divided into 32 subbands. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "mpegaudio.h" - -#include "mpc.h" -#include "mpcdata.h" - -void ff_mpc_init(void) -{ - ff_mpa_synth_init(ff_mpa_synth_window); -} - -/** - * Process decoded Musepack data and produce PCM - */ -static void mpc_synth(MPCContext *c, int16_t *out) -{ - int dither_state = 0; - int i, ch; - OUT_INT samples[MPA_MAX_CHANNELS * MPA_FRAME_SIZE], *samples_ptr; - - for(ch = 0; ch < 2; ch++){ - samples_ptr = samples + ch; - for(i = 0; i < SAMPLES_PER_BAND; i++) { - ff_mpa_synth_filter(c->synth_buf[ch], &(c->synth_buf_offset[ch]), - ff_mpa_synth_window, &dither_state, - samples_ptr, 2, - c->sb_samples[ch][i]); - samples_ptr += 64; - } - } - for(i = 0; i < MPC_FRAME_SIZE*2; i++) - *out++=samples[i]; -} - -void ff_mpc_dequantize_and_synth(MPCContext * c, int maxband, void *data) -{ - int i, j, ch; - Band *bands = c->bands; - int off; - float mul; - - /* dequantize */ - memset(c->sb_samples, 0, sizeof(c->sb_samples)); - off = 0; - for(i = 0; i <= maxband; i++, off += SAMPLES_PER_BAND){ - for(ch = 0; ch < 2; ch++){ - if(bands[i].res[ch]){ - j = 0; - mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][0]]; - for(; j < 12; j++) - c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; - mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][1]]; - for(; j < 24; j++) - c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; - mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][2]]; - for(; j < 36; j++) - c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; - } - } - if(bands[i].msf){ - int t1, t2; - for(j = 0; j < SAMPLES_PER_BAND; j++){ - t1 = c->sb_samples[0][j][i]; - t2 = c->sb_samples[1][j][i]; - c->sb_samples[0][j][i] = t1 + t2; - c->sb_samples[1][j][i] = t1 - t2; - } - } - } - - mpc_synth(c, data); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mpc.h b/tizen/distrib/ffmpeg/libavcodec/mpc.h deleted file mode 100644 index 25d1d2c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Musepack decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Musepack decoder - * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples - * divided into 32 subbands. - */ - -#ifndef AVCODEC_MPC_H -#define AVCODEC_MPC_H - -#include "libavutil/lfg.h" -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "mpegaudio.h" - -#include "mpcdata.h" - -#define BANDS 32 -#define SAMPLES_PER_BAND 36 -#define MPC_FRAME_SIZE (BANDS * SAMPLES_PER_BAND) - -/** Subband structure - hold all variables for each subband */ -typedef struct { - int msf; ///< mid-stereo flag - int res[2]; - int scfi[2]; - int scf_idx[2][3]; - int Q[2]; -}Band; - -typedef struct { - DSPContext dsp; - GetBitContext gb; - int IS, MSS, gapless; - int lastframelen; - int maxbands, last_max_band; - int last_bits_used; - int oldDSCF[2][BANDS]; - Band bands[BANDS]; - int Q[2][MPC_FRAME_SIZE]; - int cur_frame, frames; - uint8_t *bits; - int buf_size; - AVLFG rnd; - int frames_to_skip; - /* for synthesis */ - DECLARE_ALIGNED(16, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512*2]; - int synth_buf_offset[MPA_MAX_CHANNELS]; - DECLARE_ALIGNED(16, int32_t, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT]; -} MPCContext; - -void ff_mpc_init(void); -void ff_mpc_dequantize_and_synth(MPCContext *c, int maxband, void *dst); - -#endif /* AVCODEC_MPC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpc7.c b/tizen/distrib/ffmpeg/libavcodec/mpc7.c deleted file mode 100644 index 42de27e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpc7.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Musepack SV7 decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples - * divided into 32 subbands. - */ - -#include "libavutil/lfg.h" -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "mpegaudio.h" - -#include "mpc.h" -#include "mpc7data.h" - -#define BANDS 32 -#define SAMPLES_PER_BAND 36 -#define MPC_FRAME_SIZE (BANDS * SAMPLES_PER_BAND) - -static VLC scfi_vlc, dscf_vlc, hdr_vlc, quant_vlc[MPC7_QUANT_VLC_TABLES][2]; - -static const uint16_t quant_offsets[MPC7_QUANT_VLC_TABLES*2 + 1] = -{ - 0, 512, 1024, 1536, 2052, 2564, 3076, 3588, 4100, 4612, 5124, - 5636, 6164, 6676, 7224 -}; - - -static av_cold int mpc7_decode_init(AVCodecContext * avctx) -{ - int i, j; - MPCContext *c = avctx->priv_data; - GetBitContext gb; - uint8_t buf[16]; - static int vlc_initialized = 0; - - static VLC_TYPE scfi_table[1 << MPC7_SCFI_BITS][2]; - static VLC_TYPE dscf_table[1 << MPC7_DSCF_BITS][2]; - static VLC_TYPE hdr_table[1 << MPC7_HDR_BITS][2]; - static VLC_TYPE quant_tables[7224][2]; - - if(avctx->extradata_size < 16){ - av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); - return -1; - } - memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); - av_lfg_init(&c->rnd, 0xDEADBEEF); - dsputil_init(&c->dsp, avctx); - c->dsp.bswap_buf((uint32_t*)buf, (const uint32_t*)avctx->extradata, 4); - ff_mpc_init(); - init_get_bits(&gb, buf, 128); - - c->IS = get_bits1(&gb); - c->MSS = get_bits1(&gb); - c->maxbands = get_bits(&gb, 6); - if(c->maxbands >= BANDS){ - av_log(avctx, AV_LOG_ERROR, "Too many bands: %i\n", c->maxbands); - return -1; - } - skip_bits_long(&gb, 88); - c->gapless = get_bits1(&gb); - c->lastframelen = get_bits(&gb, 11); - av_log(avctx, AV_LOG_DEBUG, "IS: %d, MSS: %d, TG: %d, LFL: %d, bands: %d\n", - c->IS, c->MSS, c->gapless, c->lastframelen, c->maxbands); - c->frames_to_skip = 0; - - avctx->sample_fmt = SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; - - if(vlc_initialized) return 0; - av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); - scfi_vlc.table = scfi_table; - scfi_vlc.table_allocated = 1 << MPC7_SCFI_BITS; - if(init_vlc(&scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE, - &mpc7_scfi[1], 2, 1, - &mpc7_scfi[0], 2, 1, INIT_VLC_USE_NEW_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init SCFI VLC\n"); - return -1; - } - dscf_vlc.table = dscf_table; - dscf_vlc.table_allocated = 1 << MPC7_DSCF_BITS; - if(init_vlc(&dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE, - &mpc7_dscf[1], 2, 1, - &mpc7_dscf[0], 2, 1, INIT_VLC_USE_NEW_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init DSCF VLC\n"); - return -1; - } - hdr_vlc.table = hdr_table; - hdr_vlc.table_allocated = 1 << MPC7_HDR_BITS; - if(init_vlc(&hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE, - &mpc7_hdr[1], 2, 1, - &mpc7_hdr[0], 2, 1, INIT_VLC_USE_NEW_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init HDR VLC\n"); - return -1; - } - for(i = 0; i < MPC7_QUANT_VLC_TABLES; i++){ - for(j = 0; j < 2; j++){ - quant_vlc[i][j].table = &quant_tables[quant_offsets[i*2 + j]]; - quant_vlc[i][j].table_allocated = quant_offsets[i*2 + j + 1] - quant_offsets[i*2 + j]; - if(init_vlc(&quant_vlc[i][j], 9, mpc7_quant_vlc_sizes[i], - &mpc7_quant_vlc[i][j][1], 4, 2, - &mpc7_quant_vlc[i][j][0], 4, 2, INIT_VLC_USE_NEW_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init QUANT VLC %i,%i\n",i,j); - return -1; - } - } - } - vlc_initialized = 1; - return 0; -} - -/** - * Fill samples for given subband - */ -static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int *dst) -{ - int i, i1, t; - switch(idx){ - case -1: - for(i = 0; i < SAMPLES_PER_BAND; i++){ - *dst++ = (av_lfg_get(&c->rnd) & 0x3FC) - 510; - } - break; - case 1: - i1 = get_bits1(gb); - for(i = 0; i < SAMPLES_PER_BAND/3; i++){ - t = get_vlc2(gb, quant_vlc[0][i1].table, 9, 2); - *dst++ = mpc7_idx30[t]; - *dst++ = mpc7_idx31[t]; - *dst++ = mpc7_idx32[t]; - } - break; - case 2: - i1 = get_bits1(gb); - for(i = 0; i < SAMPLES_PER_BAND/2; i++){ - t = get_vlc2(gb, quant_vlc[1][i1].table, 9, 2); - *dst++ = mpc7_idx50[t]; - *dst++ = mpc7_idx51[t]; - } - break; - case 3: case 4: case 5: case 6: case 7: - i1 = get_bits1(gb); - for(i = 0; i < SAMPLES_PER_BAND; i++) - *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1].table, 9, 2) - mpc7_quant_vlc_off[idx-1]; - break; - case 8: case 9: case 10: case 11: case 12: - case 13: case 14: case 15: case 16: case 17: - t = (1 << (idx - 2)) - 1; - for(i = 0; i < SAMPLES_PER_BAND; i++) - *dst++ = get_bits(gb, idx - 1) - t; - break; - default: // case 0 and -2..-17 - return; - } -} - -static int get_scale_idx(GetBitContext *gb, int ref) -{ - int t = get_vlc2(gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; - if (t == 8) - return get_bits(gb, 6); - return ref + t; -} - -static int mpc7_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MPCContext *c = avctx->priv_data; - GetBitContext gb; - uint8_t *bits; - int i, ch; - int mb = -1; - Band *bands = c->bands; - int off; - int bits_used, bits_avail; - - memset(bands, 0, sizeof(bands)); - if(buf_size <= 4){ - av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size); - } - - bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE); - c->dsp.bswap_buf((uint32_t*)bits, (const uint32_t*)(buf + 4), (buf_size - 4) >> 2); - init_get_bits(&gb, bits, (buf_size - 4)* 8); - skip_bits(&gb, buf[0]); - - /* read subband indexes */ - for(i = 0; i <= c->maxbands; i++){ - for(ch = 0; ch < 2; ch++){ - int t = 4; - if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; - if(t == 4) bands[i].res[ch] = get_bits(&gb, 4); - else bands[i].res[ch] = bands[i-1].res[ch] + t; - } - - if(bands[i].res[0] || bands[i].res[1]){ - mb = i; - if(c->MSS) bands[i].msf = get_bits1(&gb); - } - } - /* get scale indexes coding method */ - for(i = 0; i <= mb; i++) - for(ch = 0; ch < 2; ch++) - if(bands[i].res[ch]) bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc.table, MPC7_SCFI_BITS, 1); - /* get scale indexes */ - for(i = 0; i <= mb; i++){ - for(ch = 0; ch < 2; ch++){ - if(bands[i].res[ch]){ - bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i]; - bands[i].scf_idx[ch][0] = get_scale_idx(&gb, bands[i].scf_idx[ch][2]); - switch(bands[i].scfi[ch]){ - case 0: - bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]); - bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]); - break; - case 1: - bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]); - bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1]; - break; - case 2: - bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; - bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]); - break; - case 3: - bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; - break; - } - c->oldDSCF[ch][i] = bands[i].scf_idx[ch][2]; - } - } - } - /* get quantizers */ - memset(c->Q, 0, sizeof(c->Q)); - off = 0; - for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND) - for(ch = 0; ch < 2; ch++) - idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off); - - ff_mpc_dequantize_and_synth(c, mb, data); - - av_free(bits); - - bits_used = get_bits_count(&gb); - bits_avail = (buf_size - 4) * 8; - if(!buf[1] && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))){ - av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); - return -1; - } - if(c->frames_to_skip){ - c->frames_to_skip--; - *data_size = 0; - return buf_size; - } - *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4; - - return buf_size; -} - -static void mpc7_decode_flush(AVCodecContext *avctx) -{ - MPCContext *c = avctx->priv_data; - - memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); - c->frames_to_skip = 32; -} - -AVCodec mpc7_decoder = { - "mpc7", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MUSEPACK7, - sizeof(MPCContext), - mpc7_decode_init, - NULL, - NULL, - mpc7_decode_frame, - .flush = mpc7_decode_flush, - .long_name = NULL_IF_CONFIG_SMALL("Musepack SV7"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpc7data.h b/tizen/distrib/ffmpeg/libavcodec/mpc7data.h deleted file mode 100644 index 5609e8f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpc7data.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Musepack decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPC7DATA_H -#define AVCODEC_MPC7DATA_H - -#include - -static const int8_t mpc7_idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; -static const int8_t mpc7_idx31[] = { -1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1}; -static const int8_t mpc7_idx32[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}; -static const int8_t mpc7_idx50[] = { -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}; -static const int8_t mpc7_idx51[] = { -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}; - -#define MPC7_SCFI_SIZE 4 -#define MPC7_SCFI_BITS 3 -static const uint8_t mpc7_scfi[MPC7_SCFI_SIZE * 2] = { - 0x2, 3, 0x1, 1, 0x3, 3, 0x0, 2 -}; - -#define MPC7_DSCF_SIZE 16 -#define MPC7_DSCF_BITS 6 -static const uint8_t mpc7_dscf[MPC7_DSCF_SIZE * 2] = { - 0x20, 6, 0x04, 5, 0x11, 5, 0x1E, 5, 0x0D, 4, 0x00, 3, 0x03, 3, 0x09, 4, - 0x05, 3, 0x02, 3, 0x0E, 4, 0x03, 4, 0x1F, 5, 0x05, 5, 0x21, 6, 0x0C, 4 -}; - -#define MPC7_HDR_SIZE 10 -#define MPC7_HDR_BITS 9 -static const uint8_t mpc7_hdr[MPC7_HDR_SIZE * 2] = { - 0x5C, 8, 0x2F, 7, 0x0A, 5, 0x04, 4, 0x00, 2, - 0x01, 1, 0x03, 3, 0x16, 6, 0xBB, 9, 0xBA, 9 -}; - -#define MPC7_QUANT_VLC_TABLES 7 -static const uint8_t mpc7_quant_vlc_sizes[MPC7_QUANT_VLC_TABLES * 2] = { - 27, 25, 7, 9, 15, 31, 63 -}; - -static const uint8_t mpc7_quant_vlc_off[MPC7_QUANT_VLC_TABLES] = { - 0, 0, 3, 4, 7, 15, 31 -}; - -static const uint16_t mpc7_quant_vlc[MPC7_QUANT_VLC_TABLES][2][64 * 2] = { -{ - { - 0x0036, 6, 0x0009, 5, 0x0020, 6, 0x0005, 5, 0x000A, 4, 0x0007, 5, - 0x0034, 6, 0x0000, 5, 0x0023, 6, 0x000A, 5, 0x0006, 4, 0x0004, 5, - 0x000B, 4, 0x0007, 3, 0x000C, 4, 0x0003, 5, 0x0007, 4, 0x000B, 5, - 0x0022, 6, 0x0001, 5, 0x0035, 6, 0x0006, 5, 0x0009, 4, 0x0002, 5, - 0x0021, 6, 0x0008, 5, 0x0037, 6 - }, - { - 0x0067, 8, 0x003E, 7, 0x00E1, 9, 0x0037, 7, 0x0003, 4, 0x0034, 7, - 0x0065, 8, 0x003C, 7, 0x00E3, 9, 0x0018, 6, 0x0000, 4, 0x003D, 7, - 0x0004, 4, 0x0001, 1, 0x0005, 4, 0x003F, 7, 0x0001, 4, 0x003B, 7, - 0x00E2, 9, 0x0039, 7, 0x0064, 8, 0x0035, 7, 0x0002, 4, 0x0036, 7, - 0x00E0, 9, 0x003A, 7, 0x0066, 8 - } -}, -{ - { - 0x0059, 7, 0x002F, 6, 0x000F, 5, 0x0000, 5, 0x005B, 7, 0x0004, 5, - 0x0006, 4, 0x000D, 4, 0x0004, 4, 0x0005, 5, 0x0014, 5, 0x000C, 4, - 0x0004, 3, 0x000F, 4, 0x000E, 5, 0x0003, 5, 0x0003, 4, 0x000E, 4, - 0x0005, 4, 0x0001, 5, 0x005A, 7, 0x0002, 5, 0x0015, 5, 0x002E, 6, - 0x0058, 7 - }, - { - 0x0399, 10, 0x0071, 7, 0x0033, 6, 0x00E7, 8, 0x039A, 10, 0x0068, 7, - 0x001E, 5, 0x0000, 3, 0x001D, 5, 0x0069, 7, 0x0032, 6, 0x0001, 3, - 0x0002, 2, 0x0003, 3, 0x0031, 6, 0x006B, 7, 0x001B, 5, 0x0002, 3, - 0x001F, 5, 0x0070, 7, 0x0398, 10, 0x006A, 7, 0x0030, 6, 0x0072, 7, - 0x039B, 10 - } -}, -{ - { - 0x000C, 4, 0x0004, 3, 0x0000, 2, 0x0001, 2, 0x0007, 3, 0x0005, 3, 0x000D, 4 - }, - { - 0x0004, 5, 0x0003, 4, 0x0002, 2, 0x0003, 2, 0x0001, 2, 0x0000, 3, 0x0005, 5 - } -}, -{ - { - 0x0005, 4, 0x0000, 3, 0x0004, 3, 0x0006, 3, 0x0007, 3, 0x0005, 3, 0x0003, 3, 0x0001, 3, 0x0004, 4 - }, - { - 0x0009, 5, 0x000C, 4, 0x0003, 3, 0x0000, 2, 0x0002, 2, 0x0007, 3, 0x000D, 4, 0x0005, 4, 0x0008, 5 - } -}, -{ - { - 0x0039, 6, 0x0017, 5, 0x0008, 4, 0x000A, 4, 0x000D, 4, 0x0000, 3, - 0x0002, 3, 0x0003, 3, 0x0001, 3, 0x000F, 4, 0x000C, 4, 0x0009, 4, - 0x001D, 5, 0x0016, 5, 0x0038, 6, - }, - { - 0x00E5, 8, 0x0038, 6, 0x0007, 5, 0x0002, 4, 0x0000, 3, 0x0003, 3, - 0x0005, 3, 0x0006, 3, 0x0004, 3, 0x0002, 3, 0x000F, 4, 0x001D, 5, - 0x0006, 5, 0x0073, 7, 0x00E4, 8, - }, -}, -{ - { - 0x0041, 7, 0x0006, 6, 0x002C, 6, 0x002D, 6, 0x003B, 6, 0x000D, 5, - 0x0011, 5, 0x0013, 5, 0x0017, 5, 0x0015, 5, 0x001A, 5, 0x001E, 5, - 0x0000, 4, 0x0002, 4, 0x0005, 4, 0x0007, 4, 0x0003, 4, 0x0004, 4, - 0x001F, 5, 0x001C, 5, 0x0019, 5, 0x001B, 5, 0x0018, 5, 0x0014, 5, - 0x0012, 5, 0x000C, 5, 0x0002, 5, 0x003A, 6, 0x0021, 6, 0x0007, 6, - 0x0040, 7 - }, - { - 0x1948, 13, 0x194A, 13, 0x0328, 10, 0x0195, 9, 0x00CB, 8, 0x0066, 7, - 0x0031, 6, 0x0009, 5, 0x000F, 5, 0x001F, 5, 0x0002, 4, 0x0006, 4, - 0x0008, 4, 0x000B, 4, 0x000D, 4, 0x0000, 3, 0x000E, 4, 0x000A, 4, - 0x0009, 4, 0x0005, 4, 0x0003, 4, 0x001E, 5, 0x000E, 5, 0x0008, 5, - 0x0030, 6, 0x0067, 7, 0x00C9, 8, 0x00C8, 8, 0x0653, 11, 0x1949, 13, - 0x194B, 13 - } -}, -{ - { - 0x0067, 8, 0x0099, 8, 0x00B5, 8, 0x00E9, 8, 0x0040, 7, 0x0041, 7, - 0x004D, 7, 0x0051, 7, 0x005B, 7, 0x0071, 7, 0x0070, 7, 0x0018, 6, - 0x001D, 6, 0x0023, 6, 0x0025, 6, 0x0029, 6, 0x002C, 6, 0x002E, 6, - 0x0033, 6, 0x0031, 6, 0x0036, 6, 0x0037, 6, 0x0039, 6, 0x003C, 6, - 0x0000, 5, 0x0002, 5, 0x000A, 5, 0x0005, 5, 0x0009, 5, 0x0006, 5, - 0x000D, 5, 0x0007, 5, 0x000B, 5, 0x000F, 5, 0x0008, 5, 0x0004, 5, - 0x0003, 5, 0x0001, 5, 0x003F, 6, 0x003E, 6, 0x003D, 6, 0x0035, 6, - 0x003B, 6, 0x0034, 6, 0x0030, 6, 0x002F, 6, 0x002B, 6, 0x002A, 6, - 0x0027, 6, 0x0024, 6, 0x0021, 6, 0x001C, 6, 0x0075, 7, 0x0065, 7, - 0x0064, 7, 0x0050, 7, 0x0045, 7, 0x0044, 7, 0x0032, 7, 0x00E8, 8, - 0x00B4, 8, 0x0098, 8, 0x0066, 8 - }, - { - 0x37A4, 14, 0x37AD, 14, 0x37A6, 14, 0x37AE, 14, 0x0DEA, 12, 0x02F0, 10, - 0x02F1, 10, 0x00A0, 9, 0x00A2, 9, 0x01BC, 9, 0x007A, 8, 0x00DF, 8, - 0x003C, 7, 0x0049, 7, 0x006E, 7, 0x000E, 6, 0x0018, 6, 0x0019, 6, - 0x0022, 6, 0x0025, 6, 0x0036, 6, 0x0003, 5, 0x0009, 5, 0x000B, 5, - 0x0010, 5, 0x0013, 5, 0x0015, 5, 0x0018, 5, 0x001A, 5, 0x001D, 5, - 0x001F, 5, 0x0002, 4, 0x0000, 4, 0x001E, 5, 0x001C, 5, 0x0019, 5, - 0x0016, 5, 0x0014, 5, 0x000E, 5, 0x000D, 5, 0x0008, 5, 0x0006, 5, - 0x0002, 5, 0x002E, 6, 0x0023, 6, 0x001F, 6, 0x0015, 6, 0x000F, 6, - 0x005F, 7, 0x0048, 7, 0x0029, 7, 0x00BD, 8, 0x007B, 8, 0x0179, 9, - 0x00A1, 9, 0x037B, 10, 0x0147, 10, 0x0146, 10, 0x0DE8, 12, 0x37AF, 14, - 0x37A7, 14, 0x37AC, 14, 0x37A5, 14 - } -} -}; - -#endif /* AVCODEC_MPC7DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpc8.c b/tizen/distrib/ffmpeg/libavcodec/mpc8.c deleted file mode 100644 index 3762746..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpc8.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Musepack SV8 decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples - * divided into 32 subbands. - */ - -#include "libavutil/lfg.h" -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "mpegaudio.h" - -#include "mpc.h" -#include "mpcdata.h" -#include "mpc8data.h" -#include "mpc8huff.h" - -static VLC band_vlc, scfi_vlc[2], dscf_vlc[2], res_vlc[2]; -static VLC q1_vlc, q2_vlc[2], q3_vlc[2], quant_vlc[4][2], q9up_vlc; - -static const int q3_offsets[2] = { MPC8_Q3_OFFSET, MPC8_Q4_OFFSET }; -static const int quant_offsets[6] = { MPC8_Q5_OFFSET, MPC8_Q6_OFFSET, MPC8_Q7_OFFSET, MPC8_Q8_OFFSET }; - -static inline int mpc8_dec_base(GetBitContext *gb, int k, int n) -{ - int len = mpc8_cnk_len[k-1][n-1] - 1; - int code = len ? get_bits_long(gb, len) : 0; - - if (code >= mpc8_cnk_lost[k-1][n-1]) - code = ((code << 1) | get_bits1(gb)) - mpc8_cnk_lost[k-1][n-1]; - - return code; -} - -static inline int mpc8_dec_enum(GetBitContext *gb, int k, int n) -{ - int bits = 0; - const uint32_t * C = mpc8_cnk[k-1]; - int code = mpc8_dec_base(gb, k, n); - - do { - n--; - if (code >= C[n]) { - bits |= 1 << n; - code -= C[n]; - C -= 32; - k--; - } - } while(k > 0); - - return bits; -} - -static inline int mpc8_get_mod_golomb(GetBitContext *gb, int m) -{ - if(mpc8_cnk_len[0][m] < 1) return 0; - return mpc8_dec_base(gb, 1, m+1); -} - -static int mpc8_get_mask(GetBitContext *gb, int size, int t) -{ - int mask = 0; - - if(t && t != size) - mask = mpc8_dec_enum(gb, FFMIN(t, size - t), size); - if((t << 1) > size) mask = ~mask; - - return mask; -} - -static const uint16_t vlc_offsets[13] = { - 0, 640, 1184, 1748, 2298, 2426, 2554, 3066, 3578, 4106, 4618, 5196, 5708 -}; - -static av_cold int mpc8_decode_init(AVCodecContext * avctx) -{ - int i; - MPCContext *c = avctx->priv_data; - GetBitContext gb; - static int vlc_initialized = 0; - - static VLC_TYPE band_table[542][2]; - static VLC_TYPE q1_table[520][2]; - static VLC_TYPE q9up_table[524][2]; - static VLC_TYPE scfi0_table[1 << MPC8_SCFI0_BITS][2]; - static VLC_TYPE scfi1_table[1 << MPC8_SCFI1_BITS][2]; - static VLC_TYPE dscf0_table[560][2]; - static VLC_TYPE dscf1_table[598][2]; - static VLC_TYPE q3_0_table[512][2]; - static VLC_TYPE q3_1_table[516][2]; - static VLC_TYPE codes_table[5708][2]; - - if(avctx->extradata_size < 2){ - av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); - return -1; - } - memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); - av_lfg_init(&c->rnd, 0xDEADBEEF); - dsputil_init(&c->dsp, avctx); - - ff_mpc_init(); - - init_get_bits(&gb, avctx->extradata, 16); - - skip_bits(&gb, 3);//sample rate - c->maxbands = get_bits(&gb, 5) + 1; - skip_bits(&gb, 4);//channels - c->MSS = get_bits1(&gb); - c->frames = 1 << (get_bits(&gb, 3) * 2); - - avctx->sample_fmt = SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; - - if(vlc_initialized) return 0; - av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); - - band_vlc.table = band_table; - band_vlc.table_allocated = 542; - init_vlc(&band_vlc, MPC8_BANDS_BITS, MPC8_BANDS_SIZE, - mpc8_bands_bits, 1, 1, - mpc8_bands_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - q1_vlc.table = q1_table; - q1_vlc.table_allocated = 520; - init_vlc(&q1_vlc, MPC8_Q1_BITS, MPC8_Q1_SIZE, - mpc8_q1_bits, 1, 1, - mpc8_q1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - q9up_vlc.table = q9up_table; - q9up_vlc.table_allocated = 524; - init_vlc(&q9up_vlc, MPC8_Q9UP_BITS, MPC8_Q9UP_SIZE, - mpc8_q9up_bits, 1, 1, - mpc8_q9up_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - scfi_vlc[0].table = scfi0_table; - scfi_vlc[0].table_allocated = 1 << MPC8_SCFI0_BITS; - init_vlc(&scfi_vlc[0], MPC8_SCFI0_BITS, MPC8_SCFI0_SIZE, - mpc8_scfi0_bits, 1, 1, - mpc8_scfi0_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - scfi_vlc[1].table = scfi1_table; - scfi_vlc[1].table_allocated = 1 << MPC8_SCFI1_BITS; - init_vlc(&scfi_vlc[1], MPC8_SCFI1_BITS, MPC8_SCFI1_SIZE, - mpc8_scfi1_bits, 1, 1, - mpc8_scfi1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - dscf_vlc[0].table = dscf0_table; - dscf_vlc[0].table_allocated = 560; - init_vlc(&dscf_vlc[0], MPC8_DSCF0_BITS, MPC8_DSCF0_SIZE, - mpc8_dscf0_bits, 1, 1, - mpc8_dscf0_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - dscf_vlc[1].table = dscf1_table; - dscf_vlc[1].table_allocated = 598; - init_vlc(&dscf_vlc[1], MPC8_DSCF1_BITS, MPC8_DSCF1_SIZE, - mpc8_dscf1_bits, 1, 1, - mpc8_dscf1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - - q3_vlc[0].table = q3_0_table; - q3_vlc[0].table_allocated = 512; - init_vlc_sparse(&q3_vlc[0], MPC8_Q3_BITS, MPC8_Q3_SIZE, - mpc8_q3_bits, 1, 1, - mpc8_q3_codes, 1, 1, - mpc8_q3_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); - q3_vlc[1].table = q3_1_table; - q3_vlc[1].table_allocated = 516; - init_vlc_sparse(&q3_vlc[1], MPC8_Q4_BITS, MPC8_Q4_SIZE, - mpc8_q4_bits, 1, 1, - mpc8_q4_codes, 1, 1, - mpc8_q4_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); - - for(i = 0; i < 2; i++){ - res_vlc[i].table = &codes_table[vlc_offsets[0+i]]; - res_vlc[i].table_allocated = vlc_offsets[1+i] - vlc_offsets[0+i]; - init_vlc(&res_vlc[i], MPC8_RES_BITS, MPC8_RES_SIZE, - &mpc8_res_bits[i], 1, 1, - &mpc8_res_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - - q2_vlc[i].table = &codes_table[vlc_offsets[2+i]]; - q2_vlc[i].table_allocated = vlc_offsets[3+i] - vlc_offsets[2+i]; - init_vlc(&q2_vlc[i], MPC8_Q2_BITS, MPC8_Q2_SIZE, - &mpc8_q2_bits[i], 1, 1, - &mpc8_q2_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - - quant_vlc[0][i].table = &codes_table[vlc_offsets[4+i]]; - quant_vlc[0][i].table_allocated = vlc_offsets[5+i] - vlc_offsets[4+i]; - init_vlc(&quant_vlc[0][i], MPC8_Q5_BITS, MPC8_Q5_SIZE, - &mpc8_q5_bits[i], 1, 1, - &mpc8_q5_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - quant_vlc[1][i].table = &codes_table[vlc_offsets[6+i]]; - quant_vlc[1][i].table_allocated = vlc_offsets[7+i] - vlc_offsets[6+i]; - init_vlc(&quant_vlc[1][i], MPC8_Q6_BITS, MPC8_Q6_SIZE, - &mpc8_q6_bits[i], 1, 1, - &mpc8_q6_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - quant_vlc[2][i].table = &codes_table[vlc_offsets[8+i]]; - quant_vlc[2][i].table_allocated = vlc_offsets[9+i] - vlc_offsets[8+i]; - init_vlc(&quant_vlc[2][i], MPC8_Q7_BITS, MPC8_Q7_SIZE, - &mpc8_q7_bits[i], 1, 1, - &mpc8_q7_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - quant_vlc[3][i].table = &codes_table[vlc_offsets[10+i]]; - quant_vlc[3][i].table_allocated = vlc_offsets[11+i] - vlc_offsets[10+i]; - init_vlc(&quant_vlc[3][i], MPC8_Q8_BITS, MPC8_Q8_SIZE, - &mpc8_q8_bits[i], 1, 1, - &mpc8_q8_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - vlc_initialized = 1; - return 0; -} - -static int mpc8_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MPCContext *c = avctx->priv_data; - GetBitContext gb2, *gb = &gb2; - int i, j, k, ch, cnt, res, t; - Band *bands = c->bands; - int off; - int maxband, keyframe; - int last[2]; - - keyframe = c->cur_frame == 0; - - if(keyframe){ - memset(c->Q, 0, sizeof(c->Q)); - c->last_bits_used = 0; - } - init_get_bits(gb, buf, buf_size * 8); - skip_bits(gb, c->last_bits_used & 7); - - if(keyframe) - maxband = mpc8_get_mod_golomb(gb, c->maxbands + 1); - else{ - maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2); - if(maxband > 32) maxband -= 33; - } - c->last_max_band = maxband; - - /* read subband indexes */ - if(maxband){ - last[0] = last[1] = 0; - for(i = maxband - 1; i >= 0; i--){ - for(ch = 0; ch < 2; ch++){ - last[ch] = get_vlc2(gb, res_vlc[last[ch] > 2].table, MPC8_RES_BITS, 2) + last[ch]; - if(last[ch] > 15) last[ch] -= 17; - bands[i].res[ch] = last[ch]; - } - } - if(c->MSS){ - int mask; - - cnt = 0; - for(i = 0; i < maxband; i++) - if(bands[i].res[0] || bands[i].res[1]) - cnt++; - t = mpc8_get_mod_golomb(gb, cnt); - mask = mpc8_get_mask(gb, cnt, t); - for(i = maxband - 1; i >= 0; i--) - if(bands[i].res[0] || bands[i].res[1]){ - bands[i].msf = mask & 1; - mask >>= 1; - } - } - } - for(i = maxband; i < c->maxbands; i++) - bands[i].res[0] = bands[i].res[1] = 0; - - if(keyframe){ - for(i = 0; i < 32; i++) - c->oldDSCF[0][i] = c->oldDSCF[1][i] = 1; - } - - for(i = 0; i < maxband; i++){ - if(bands[i].res[0] || bands[i].res[1]){ - cnt = !!bands[i].res[0] + !!bands[i].res[1] - 1; - if(cnt >= 0){ - t = get_vlc2(gb, scfi_vlc[cnt].table, scfi_vlc[cnt].bits, 1); - if(bands[i].res[0]) bands[i].scfi[0] = t >> (2 * cnt); - if(bands[i].res[1]) bands[i].scfi[1] = t & 3; - } - } - } - - for(i = 0; i < maxband; i++){ - for(ch = 0; ch < 2; ch++){ - if(!bands[i].res[ch]) continue; - - if(c->oldDSCF[ch][i]){ - bands[i].scf_idx[ch][0] = get_bits(gb, 7) - 6; - c->oldDSCF[ch][i] = 0; - }else{ - t = get_vlc2(gb, dscf_vlc[1].table, MPC8_DSCF1_BITS, 2); - if(t == 64) - t += get_bits(gb, 6); - bands[i].scf_idx[ch][0] = ((bands[i].scf_idx[ch][2] + t - 25) & 0x7F) - 6; - } - for(j = 0; j < 2; j++){ - if((bands[i].scfi[ch] << j) & 2) - bands[i].scf_idx[ch][j + 1] = bands[i].scf_idx[ch][j]; - else{ - t = get_vlc2(gb, dscf_vlc[0].table, MPC8_DSCF0_BITS, 2); - if(t == 31) - t = 64 + get_bits(gb, 6); - bands[i].scf_idx[ch][j + 1] = ((bands[i].scf_idx[ch][j] + t - 25) & 0x7F) - 6; - } - } - } - } - - for(i = 0, off = 0; i < maxband; i++, off += SAMPLES_PER_BAND){ - for(ch = 0; ch < 2; ch++){ - res = bands[i].res[ch]; - switch(res){ - case -1: - for(j = 0; j < SAMPLES_PER_BAND; j++) - c->Q[ch][off + j] = (av_lfg_get(&c->rnd) & 0x3FC) - 510; - break; - case 0: - break; - case 1: - for(j = 0; j < SAMPLES_PER_BAND; j += SAMPLES_PER_BAND / 2){ - cnt = get_vlc2(gb, q1_vlc.table, MPC8_Q1_BITS, 2); - t = mpc8_get_mask(gb, 18, cnt); - for(k = 0; k < SAMPLES_PER_BAND / 2; k++, t <<= 1) - c->Q[ch][off + j + k] = (t & 0x20000) ? (get_bits1(gb) << 1) - 1 : 0; - } - break; - case 2: - cnt = 6;//2*mpc8_thres[res] - for(j = 0; j < SAMPLES_PER_BAND; j += 3){ - t = get_vlc2(gb, q2_vlc[cnt > 3].table, MPC8_Q2_BITS, 2); - c->Q[ch][off + j + 0] = mpc8_idx50[t]; - c->Q[ch][off + j + 1] = mpc8_idx51[t]; - c->Q[ch][off + j + 2] = mpc8_idx52[t]; - cnt = (cnt >> 1) + mpc8_huffq2[t]; - } - break; - case 3: - case 4: - for(j = 0; j < SAMPLES_PER_BAND; j += 2){ - t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3]; - c->Q[ch][off + j + 1] = t >> 4; - c->Q[ch][off + j + 0] = (t & 8) ? (t & 0xF) - 16 : (t & 0xF); - } - break; - case 5: - case 6: - case 7: - case 8: - cnt = 2 * mpc8_thres[res]; - for(j = 0; j < SAMPLES_PER_BAND; j++){ - t = get_vlc2(gb, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5]; - c->Q[ch][off + j] = t; - cnt = (cnt >> 1) + FFABS(c->Q[ch][off + j]); - } - break; - default: - for(j = 0; j < SAMPLES_PER_BAND; j++){ - c->Q[ch][off + j] = get_vlc2(gb, q9up_vlc.table, MPC8_Q9UP_BITS, 2); - if(res != 9){ - c->Q[ch][off + j] <<= res - 9; - c->Q[ch][off + j] |= get_bits(gb, res - 9); - } - c->Q[ch][off + j] -= (1 << (res - 2)) - 1; - } - } - } - } - - ff_mpc_dequantize_and_synth(c, maxband, data); - - c->cur_frame++; - - c->last_bits_used = get_bits_count(gb); - if(c->cur_frame >= c->frames) - c->cur_frame = 0; - *data_size = MPC_FRAME_SIZE * 4; - - return c->cur_frame ? c->last_bits_used >> 3 : buf_size; -} - -AVCodec mpc8_decoder = { - "mpc8", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MUSEPACK8, - sizeof(MPCContext), - mpc8_decode_init, - NULL, - NULL, - mpc8_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpc8data.h b/tizen/distrib/ffmpeg/libavcodec/mpc8data.h deleted file mode 100644 index 22c2be4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpc8data.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Musepack SV8 decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPC8DATA_H -#define AVCODEC_MPC8DATA_H - -#include - -static const int8_t mpc8_idx50[125] = { - -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 -}; -static const int8_t mpc8_idx51[125] = { - -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 -}; -static const int8_t mpc8_idx52[125] = { - -2, -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 -}; - -static const unsigned int mpc8_thres[] = {0, 0, 3, 0, 0, 1, 3, 4, 8}; -static const int8_t mpc8_huffq2[5*5*5] = { - 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, - 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, - 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 2, 3, 4, 3, - 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, - 4, 3, 4, 5, 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, - 6, 5, 4, 5, 6 -}; - - -static const uint32_t mpc8_cnk[16][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, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465}, - {0, 0, 0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969, 1140, 1330, 1540, 1771, 2024, 2300, 2600, 2925, 3276, 3654, 4060, 4495}, - {0, 0, 0, 0, 1, 5, 15, 35, 70, 126, 210, 330, 495, 715, 1001, 1365, 1820, 2380, 3060, 3876, 4845, 5985, 7315, 8855, 10626, 12650, 14950, 17550, 20475, 23751, 27405, 31465}, - {0, 0, 0, 0, 0, 1, 6, 21, 56, 126, 252, 462, 792, 1287, 2002, 3003, 4368, 6188, 8568, 11628, 15504, 20349, 26334, 33649, 42504, 53130, 65780, 80730, 98280, 118755, 142506, 169911}, - {0, 0, 0, 0, 0, 0, 1, 7, 28, 84, 210, 462, 924, 1716, 3003, 5005, 8008, 12376, 18564, 27132, 38760, 54264, 74613, 100947, 134596, 177100, 230230, 296010, 376740, 475020, 593775, 736281}, - {0, 0, 0, 0, 0, 0, 0, 1, 8, 36, 120, 330, 792, 1716, 3432, 6435, 11440, 19448, 31824, 50388, 77520, 116280, 170544, 245157, 346104, 480700, 657800, 888030, 1184040, 1560780, 2035800, 2629575}, - {0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 45, 165, 495, 1287, 3003, 6435, 12870, 24310, 43758, 75582, 125970, 203490, 319770, 490314, 735471, 1081575, 1562275, 2220075, 3108105, 4292145, 5852925, 7888725}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 55, 220, 715, 2002, 5005, 11440, 24310, 48620, 92378, 167960, 293930, 497420, 817190, 1307504, 2042975, 3124550, 4686825, 6906900, 10015005, 14307150, 20160075}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 66, 286, 1001, 3003, 8008, 19448, 43758, 92378, 184756, 352716, 646646, 1144066, 1961256, 3268760, 5311735, 8436285, 13123110, 20030010, 30045015, 44352165}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 78, 364, 1365, 4368, 12376, 31824, 75582, 167960, 352716, 705432, 1352078, 2496144, 4457400, 7726160, 13037895, 21474180, 34597290, 54627300, 84672315}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 91, 455, 1820, 6188, 18564, 50388, 125970, 293930, 646646, 1352078, 2704156, 5200300, 9657700, 17383860, 30421755, 51895935, 86493225, 141120525}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 105, 560, 2380, 8568, 27132, 77520, 203490, 497420, 1144066, 2496144, 5200300, 10400600, 20058300, 37442160, 67863915, 119759850, 206253075}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 15, 120, 680, 3060, 11628, 38760, 116280, 319770, 817190, 1961256, 4457400, 9657700, 20058300, 40116600, 77558760, 145422675, 265182525}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 136, 816, 3876, 15504, 54264, 170544, 490314, 1307504, 3268760, 7726160, 17383860, 37442160, 77558760, 155117520, 300540195}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 153, 969, 4845, 20349, 74613, 245157, 735471, 2042975, 5311735, 13037895, 30421755, 67863915, 145422675, 300540195} -}; - -static const uint8_t mpc8_cnk_len[16][33] = -{ - {0, 1, 2, 2, 3, 3, 3, 3, 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}, - {0, 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0}, - {0, 0, 0, 2, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 0}, - {0, 0, 0, 0, 3, 4, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 0}, - {0, 0, 0, 0, 0, 3, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 0}, - {0, 0, 0, 0, 0, 0, 3, 5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 0}, - {0, 0, 0, 0, 0, 0, 0, 3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 23, 24, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 10, 11, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 24, 25, 25, 26, 26, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 28, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 27, 28, 29, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 16, 17, 19, 20, 21, 23, 24, 25, 26, 27, 28, 28, 29, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 10, 12, 14, 16, 18, 19, 21, 22, 23, 25, 26, 27, 28, 29, 30, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 13, 15, 17, 18, 20, 21, 23, 24, 25, 27, 28, 29, 30, 0} - -}; - -static const uint32_t mpc8_cnk_lost[16][33] = -{ - {0, 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 31}, - {0, 0, 1, 2, 6, 1, 11, 4, 28, 19, 9, 62, 50, 37, 23, 8, 120, 103, 85, 66, 46, 25, 3, 236, 212, 187, 161, 134, 106, 77, 47, 16, 0}, - {0, 0, 0, 0, 6, 12, 29, 8, 44, 8, 91, 36, 226, 148, 57, 464, 344, 208, 55, 908, 718, 508, 277, 24, 1796, 1496, 1171, 820, 442, 36, 3697, 3232, 0}, - {0, 0, 0, 0, 3, 1, 29, 58, 2, 46, 182, 17, 309, 23, 683, 228, 1716, 1036, 220, 3347, 2207, 877, 7529, 5758, 3734, 1434, 15218, 12293, 9017, 5363, 1303, 29576, 0}, - {0, 0, 0, 0, 0, 2, 11, 8, 2, 4, 50, 232, 761, 46, 1093, 3824, 2004, 7816, 4756, 880, 12419, 6434, 31887, 23032, 12406, 65292, 50342, 32792, 12317, 119638, 92233, 60768, 0}, - {0, 0, 0, 0, 0, 0, 1, 4, 44, 46, 50, 100, 332, 1093, 3187, 184, 4008, 14204, 5636, 26776, 11272, 56459, 30125, 127548, 85044, 31914, 228278, 147548, 49268, 454801, 312295, 142384, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 182, 232, 332, 664, 1757, 4944, 13320, 944, 15148, 53552, 14792, 91600, 16987, 178184, 43588, 390776, 160546, 913112, 536372, 61352, 1564729, 828448, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 7, 19, 91, 17, 761, 1093, 1757, 3514, 8458, 21778, 55490, 5102, 58654, 204518, 33974, 313105, 1015577, 534877, 1974229, 1086199, 4096463, 2535683, 499883, 6258916, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9, 36, 309, 46, 3187, 4944, 8458, 16916, 38694, 94184, 230358, 26868, 231386, 789648, 54177, 1069754, 3701783, 1481708, 6762211, 2470066, 13394357, 5505632, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 62, 226, 23, 1093, 184, 13320, 21778, 38694, 77388, 171572, 401930, 953086, 135896, 925544, 3076873, 8340931, 3654106, 13524422, 3509417, 22756699, 2596624, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 50, 148, 683, 3824, 4008, 944, 55490, 94184, 171572, 343144, 745074, 1698160, 3931208, 662448, 3739321, 12080252, 32511574, 12481564, 49545413, 5193248, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 37, 57, 228, 2004, 14204, 15148, 5102, 230358, 401930, 745074, 1490148, 3188308, 7119516, 16170572, 3132677, 15212929, 47724503, 127314931, 42642616, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 464, 1716, 7816, 5636, 53552, 58654, 26868, 953086, 1698160, 3188308, 6376616, 13496132, 29666704, 66353813, 14457878, 62182381, 189497312, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 344, 1036, 4756, 26776, 14792, 204518, 231386, 135896, 3931208, 7119516, 13496132, 26992264, 56658968, 123012781, 3252931, 65435312, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 208, 220, 880, 11272, 91600, 33974, 789648, 925544, 662448, 16170572, 29666704, 56658968, 113317936, 236330717, 508019104, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 103, 55, 3347, 12419, 56459, 16987, 313105, 54177, 3076873, 3739321, 3132677, 66353813, 123012781, 236330717, 0} -}; - -#endif /* AVCODEC_MPC8DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpc8huff.h b/tizen/distrib/ffmpeg/libavcodec/mpc8huff.h deleted file mode 100644 index 8491037..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpc8huff.h +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Musepack SV8 decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPC8HUFF_H -#define AVCODEC_MPC8HUFF_H - -#include - -#define MPC8_BANDS_SIZE 33 -#define MPC8_BANDS_BITS 9 - -static const uint8_t mpc8_bands_codes[MPC8_BANDS_SIZE] = { - 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, - 0x05, 0x06, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x01, 0x09, 0x0A, 0x0B, 0x07, - 0x08, 0x09, 0x06, 0x07, 0x05, 0x05, 0x03, 0x03, - 0x01, -}; -static const int8_t mpc8_bands_bits[MPC8_BANDS_SIZE] = { - 1, 3, 5, 6, 7, 8, 8, 9, - 10, 11, 12, 12, 12, 13, 12, 12, - 12, 12, 12, 13, 12, 12, 12, 11, - 11, 11, 10, 10, 9, 8, 6, 5, - 2, -}; - -#define MPC8_SCFI0_SIZE 4 -#define MPC8_SCFI0_BITS 3 - -static const uint8_t mpc8_scfi0_codes[MPC8_SCFI0_SIZE] = { - 0x00, 0x01, 0x01, 0x01, -}; -static const int8_t mpc8_scfi0_bits[MPC8_SCFI0_SIZE] = { - 3, 3, 1, 2, -}; - -#define MPC8_SCFI1_SIZE 16 -#define MPC8_SCFI1_BITS 7 - -static const uint8_t mpc8_scfi1_codes[MPC8_SCFI1_SIZE] = { - 0x01, 0x00, 0x02, 0x03, 0x01, 0x03, 0x04, 0x05, - 0x04, 0x06, 0x02, 0x02, 0x05, 0x07, 0x03, 0x03, - -}; -static const int8_t mpc8_scfi1_bits[MPC8_SCFI1_SIZE] = { - 6, 7, 6, 6, 7, 5, 5, 5, - 6, 5, 2, 3, 6, 5, 3, 2, - -}; - -#define MPC8_DSCF0_SIZE 64 -#define MPC8_DSCF0_BITS 9 - -static const uint8_t mpc8_dscf0_codes[MPC8_DSCF0_SIZE] = { - 0x03, 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x07, 0x08, 0x09, 0x0A, 0x07, - 0x08, 0x09, 0x0A, 0x07, 0x08, 0x09, 0x0A, 0x06, - 0x07, 0x05, 0x04, 0x05, 0x06, 0x06, 0x07, 0x0A, - 0x08, 0x05, 0x06, 0x07, 0x09, 0x07, 0x08, 0x09, - 0x0B, 0x0B, 0x0C, 0x0D, 0x0B, 0x0C, 0x0D, 0x0B, - 0x0C, 0x0D, 0x07, 0x08, 0x09, 0x06, 0x07, 0x03, - 0x04, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, -}; -static const int8_t mpc8_dscf0_bits[MPC8_DSCF0_SIZE] = { - 12, 12, 12, 11, 11, 11, 10, 10, - 10, 10, 10, 9, 9, 9, 9, 8, - 8, 8, 8, 7, 7, 7, 7, 6, - 6, 5, 4, 4, 5, 4, 4, 10, - 4, 3, 3, 3, 4, 5, 6, 6, - 7, 8, 8, 8, 9, 9, 9, 10, - 10, 10, 11, 11, 11, 12, 12, 13, - 13, 13, 14, 14, 14, 14, 14, 14, - -}; - -#define MPC8_DSCF1_SIZE 65 -#define MPC8_DSCF1_BITS 9 - -static const uint8_t mpc8_dscf1_codes[MPC8_DSCF1_SIZE] = { - 0x00, 0x03, 0x04, 0x04, 0x05, 0x06, 0x05, 0x06, - 0x07, 0x08, 0x07, 0x08, 0x09, 0x0A, 0x07, 0x08, - 0x09, 0x0A, 0x07, 0x08, 0x09, 0x06, 0x07, 0x05, - 0x06, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x05, 0x04, 0x05, 0x05, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0B, 0x0C, 0x0D, 0x0B, 0x0C, - 0x0D, 0x09, 0x0A, 0x0B, 0x0C, 0x07, 0x08, 0x09, - 0x05, 0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x0D, -}; -static const int8_t mpc8_dscf1_bits[MPC8_DSCF1_SIZE] = { - 15, 14, 14, 13, 13, 13, 12, 12, - 12, 12, 11, 11, 11, 11, 10, 10, - 10, 10, 9, 9, 9, 8, 8, 7, - 7, 6, 5, 4, 4, 3, 3, 3, - 3, 3, 4, 5, 5, 6, 7, 8, - 8, 9, 9, 10, 10, 10, 11, 11, - 11, 12, 12, 12, 12, 13, 13, 13, - 14, 14, 14, 15, 15, 15, 15, 15, - 12, -}; - -#define MPC8_RES_SIZE 17 -#define MPC8_RES_BITS 9 - -static const uint8_t mpc8_res_codes[2][MPC8_RES_SIZE] = { - { - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, - 0x01, - }, - { - 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, - 0x03, - } -}; -static const int8_t mpc8_res_bits[2][MPC8_RES_SIZE] = { - { - 1, 2, 4, 5, 6, 7, 9, 10, - 11, 12, 13, 14, 15, 16, 16, 8, - 3, - }, - { - 2, 2, 3, 5, 7, 8, 10, 12, - 14, 14, 14, 14, 11, 9, 6, 4, - 2, - } -}; - -#define MPC8_Q1_SIZE 19 -#define MPC8_Q1_BITS 9 - -static const uint8_t mpc8_q1_codes[MPC8_Q1_SIZE] = { - 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x03, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x01, -}; -static const int8_t mpc8_q1_bits[MPC8_Q1_SIZE] = { - 6, 4, 4, 3, 3, 3, 3, 3, - 4, 4, 4, 5, 7, 8, 9, 10, - 11, 12, 12, -}; - -#define MPC8_Q9UP_SIZE 256 -#define MPC8_Q9UP_BITS 9 - -static const uint8_t mpc8_q9up_codes[MPC8_Q9UP_SIZE] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x26, 0x27, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, - 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, - 0x28, 0x26, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, - 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, - 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, - 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, - 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x56, 0x57, 0x58, 0x59, - 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x3E, - 0x3F, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7A, 0x6B, 0x7B, 0x6C, 0x6D, 0x6E, - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, - 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, - 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, - 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, - 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x27, 0x28, 0x29, - 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, - 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4A, 0x4B, 0x06, 0x07, 0x08, 0x09, 0x00, 0x01, -}; -static const int8_t mpc8_q9up_bits[MPC8_Q9UP_SIZE] = { - 10, 10, 10, 10, 10, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 8, 9, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 6, - 6, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 8, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 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, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 10, 10, 10, 10, 11, 11, -}; - -#define MPC8_Q2_SIZE 125 -#define MPC8_Q2_BITS 9 - -static const uint8_t mpc8_q2_codes[2][MPC8_Q2_SIZE] = { -{ - 0x02, 0x03, 0x0F, 0x04, 0x00, 0x05, 0x0C, 0x12, - 0x0D, 0x06, 0x07, 0x13, 0x15, 0x14, 0x08, 0x09, - 0x0E, 0x15, 0x0F, 0x0A, 0x03, 0x0B, 0x10, 0x0C, - 0x01, 0x0D, 0x10, 0x16, 0x11, 0x0E, 0x12, 0x0F, - 0x10, 0x16, 0x13, 0x17, 0x11, 0x08, 0x12, 0x18, - 0x14, 0x13, 0x14, 0x17, 0x15, 0x0F, 0x16, 0x19, - 0x17, 0x10, 0x11, 0x1A, 0x18, 0x1B, 0x12, 0x1C, - 0x15, 0x09, 0x16, 0x1D, 0x19, 0x0A, 0x07, 0x0B, - 0x1A, 0x1E, 0x17, 0x0C, 0x18, 0x1F, 0x13, 0x20, - 0x1B, 0x21, 0x14, 0x11, 0x18, 0x22, 0x19, 0x12, - 0x1A, 0x19, 0x1A, 0x1B, 0x1B, 0x23, 0x1C, 0x0D, - 0x1D, 0x24, 0x1C, 0x1C, 0x1E, 0x1F, 0x1D, 0x13, - 0x1E, 0x25, 0x1F, 0x14, 0x02, 0x15, 0x15, 0x16, - 0x04, 0x17, 0x20, 0x26, 0x21, 0x18, 0x16, 0x27, - 0x1D, 0x28, 0x19, 0x1A, 0x22, 0x29, 0x23, 0x1B, - 0x03, 0x1C, 0x17, 0x1D, 0x05, -}, -{ - 0x02, 0x03, 0x0F, 0x04, 0x00, 0x05, 0x0C, 0x0D, - 0x0E, 0x06, 0x07, 0x0F, 0x1E, 0x10, 0x10, 0x08, - 0x11, 0x12, 0x13, 0x09, 0x03, 0x0A, 0x11, 0x0B, - 0x01, 0x0C, 0x14, 0x15, 0x16, 0x0D, 0x17, 0x12, - 0x0E, 0x13, 0x18, 0x19, 0x14, 0x0F, 0x10, 0x1A, - 0x1B, 0x15, 0x11, 0x16, 0x1C, 0x0E, 0x1D, 0x1E, - 0x1F, 0x0F, 0x12, 0x20, 0x1F, 0x21, 0x13, 0x22, - 0x12, 0x13, 0x14, 0x23, 0x20, 0x15, 0x0F, 0x16, - 0x21, 0x24, 0x17, 0x18, 0x19, 0x25, 0x14, 0x26, - 0x22, 0x27, 0x15, 0x10, 0x28, 0x29, 0x2A, 0x11, - 0x2B, 0x17, 0x1A, 0x18, 0x2C, 0x2D, 0x1B, 0x1C, - 0x19, 0x2E, 0x2F, 0x1A, 0x1D, 0x1B, 0x30, 0x12, - 0x31, 0x32, 0x33, 0x13, 0x02, 0x14, 0x15, 0x16, - 0x04, 0x17, 0x34, 0x35, 0x36, 0x18, 0x16, 0x37, - 0x23, 0x38, 0x19, 0x1A, 0x39, 0x3A, 0x3B, 0x1B, - 0x03, 0x1C, 0x17, 0x1D, 0x05, -} -}; -static const int8_t mpc8_q2_bits[2][MPC8_Q2_SIZE] = { -{ - 12, 11, 10, 11, 13, 11, 9, 8, - 9, 11, 11, 8, 7, 8, 11, 11, - 9, 8, 9, 11, 12, 11, 10, 11, - 13, 11, 9, 8, 9, 11, 9, 6, - 6, 7, 9, 8, 6, 4, 6, 8, - 9, 6, 6, 7, 9, 11, 9, 8, - 9, 11, 10, 8, 7, 8, 10, 8, - 6, 4, 6, 8, 7, 4, 3, 4, - 7, 8, 6, 4, 6, 8, 10, 8, - 7, 8, 10, 11, 9, 8, 9, 11, - 9, 6, 6, 6, 9, 8, 6, 4, - 6, 8, 9, 7, 6, 6, 9, 11, - 9, 8, 9, 11, 13, 11, 10, 11, - 12, 11, 9, 8, 9, 11, 10, 8, - 7, 8, 11, 11, 9, 8, 9, 11, - 13, 11, 10, 11, 12, -}, -{ - 11, 10, 9, 10, 12, 10, 8, 8, - 8, 10, 10, 8, 7, 8, 9, 10, - 8, 8, 8, 10, 11, 10, 9, 10, - 12, 10, 8, 8, 8, 10, 8, 6, - 5, 6, 8, 8, 6, 5, 5, 8, - 8, 6, 5, 6, 8, 10, 8, 8, - 8, 10, 9, 8, 7, 8, 9, 8, - 5, 5, 5, 8, 7, 5, 4, 5, - 7, 8, 5, 5, 5, 8, 9, 8, - 7, 8, 9, 10, 8, 8, 8, 10, - 8, 6, 5, 6, 8, 8, 5, 5, - 6, 8, 8, 6, 5, 6, 8, 10, - 8, 8, 8, 10, 12, 10, 10, 10, - 11, 10, 8, 8, 8, 10, 9, 8, - 7, 8, 10, 10, 8, 8, 8, 10, - 12, 10, 9, 10, 11, -} -}; - -#define MPC8_Q3_SIZE 49 -#define MPC8_Q3_BITS 9 -#define MPC8_Q3_OFFSET -48 - -static const uint8_t mpc8_q3_codes[MPC8_Q3_SIZE] = { - 0x07, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x0F, - 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x13, 0x12, 0x11, - 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, - 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, - 0x09, 0x08, 0x07, 0x06, 0x05, 0x09, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, - 0x00, -}; -static const int8_t mpc8_q3_bits[MPC8_Q3_SIZE] = { - 3, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, - 9, -}; -static const int8_t mpc8_q3_syms[MPC8_Q3_SIZE] = { - 48, 65, 64, 49, 63, 32, 47, 80, - 79, 50, 62, 33, 16, 82, 81, 95, - 94, 66, 78, 34, 46, 17, 31, 30, - 97, 96, 111, 67, 77, 51, 61, 35, - 45, 18, 1, 0, 15, 98, 110, 83, - 93, 19, 29, 2, 14, 99, 109, 3, - 13, -}; - -#define MPC8_Q4_SIZE 81 -#define MPC8_Q4_BITS 9 -#define MPC8_Q4_OFFSET -64 - -static const uint8_t mpc8_q4_codes[MPC8_Q4_SIZE] = { - 0x0F, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, - 0x16, 0x15, 0x14, 0x13, 0x12, 0x23, 0x22, 0x21, - 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, - 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, - 0x10, 0x0F, 0x0E, 0x0D, 0x19, 0x18, 0x17, 0x16, - 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, - 0x0D, 0x0C, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, - 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, - 0x09, 0x08, 0x07, 0x06, 0x05, 0x09, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, - 0x00, -}; -static const int8_t mpc8_q4_bits[MPC8_Q4_SIZE] = { - 4, 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, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 10, 10, 10, - 10, -}; -static const int8_t mpc8_q4_syms[MPC8_Q4_SIZE] = { - 64, 96, 81, 80, 95, 66, 65, 79, - 78, 49, 48, 63, 32, 113, 112, 98, - 97, 111, 110, 83, 82, 94, 93, 67, - 77, 51, 50, 62, 61, 34, 33, 47, - 46, 17, 16, 31, 128, 114, 127, 126, - 99, 109, 68, 76, 35, 45, 18, 30, - 0, 15, 130, 129, 143, 142, 115, 125, - 100, 108, 84, 92, 52, 60, 36, 44, - 19, 29, 2, 1, 14, 131, 141, 116, - 124, 20, 28, 3, 13, 132, 140, 4, - 12, -}; - -#define MPC8_Q5_SIZE 15 -#define MPC8_Q5_BITS 7 -#define MPC8_Q5_OFFSET -7 - -static const uint8_t mpc8_q5_codes[2][MPC8_Q5_SIZE] = { -{ - 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, - 0x04, 0x05, 0x03, 0x03, 0x03, 0x02, 0x03, -}, -{ - 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x04, 0x05, 0x03, 0x02, 0x03, -} -}; -static const int8_t mpc8_q5_bits[2][MPC8_Q5_SIZE] = { -{ - 7, 7, 6, 5, 4, 3, 3, 2, - 3, 3, 4, 5, 6, 7, 7, -}, -{ - 6, 6, 5, 4, 4, 3, 3, 3, - 3, 3, 4, 4, 5, 6, 6, -} -}; - -#define MPC8_Q6_SIZE 31 -#define MPC8_Q6_BITS 9 -#define MPC8_Q6_OFFSET -15 - -static const uint8_t mpc8_q6_codes[2][MPC8_Q6_SIZE] = { -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x03, - 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x04, 0x03, - 0x05, 0x06, 0x07, 0x07, 0x06, 0x07, 0x08, 0x09, - 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07, -}, -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x04, - 0x05, 0x06, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x07, 0x08, 0x09, - 0x06, 0x07, 0x05, 0x06, 0x07, 0x02, 0x03, -} -}; -static const int8_t mpc8_q6_bits[2][MPC8_Q6_SIZE] = { -{ - 9, 9, 9, 9, 8, 8, 7, 6, - 6, 6, 5, 5, 4, 4, 3, 2, - 3, 4, 4, 5, 6, 6, 6, 6, - 7, 8, 8, 9, 9, 9, 9, -}, -{ - 8, 8, 7, 7, 7, 6, 6, 5, - 5, 5, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 5, 5, 5, - 6, 6, 7, 7, 7, 8, 8, -} -}; - -#define MPC8_Q7_SIZE 63 -#define MPC8_Q7_BITS 9 -#define MPC8_Q7_OFFSET -31 - -static const uint8_t mpc8_q7_codes[2][MPC8_Q7_SIZE] = { -{ - 0x00, 0x01, 0x02, 0x08, 0x09, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x0A, 0x0B, 0x0C, 0x0D, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0A, 0x0B, 0x0C, 0x08, 0x09, 0x06, 0x04, 0x03, - 0x05, 0x07, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x0F, - 0x10, 0x11, 0x12, 0x0F, 0x13, 0x10, 0x11, 0x12, - 0x13, 0x0E, 0x0F, 0x10, 0x11, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0x12, 0x13, 0x0D, 0x0E, 0x0F, -}, -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, - 0x1E, 0x1F, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x02, 0x03, -} -}; -static const int8_t mpc8_q7_bits[2][MPC8_Q7_SIZE] = { -{ - 10, 10, 10, 9, 9, 10, 10, 10, - 10, 10, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 7, 7, 7, 7, 7, - 6, 6, 6, 5, 5, 4, 3, 2, - 3, 4, 5, 5, 6, 6, 6, 7, - 7, 7, 7, 8, 7, 8, 8, 8, - 8, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 9, 9, 10, 10, 10, -}, -{ - 9, 9, 8, 8, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 7, 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, 6, 6, 6, 6, 6, 6, - 6, 7, 7, 7, 7, 7, 8, 8, - 8, 8, 8, 8, 8, 9, 9, -} -}; - -#define MPC8_Q8_SIZE 127 -#define MPC8_Q8_BITS 9 -#define MPC8_Q8_OFFSET -63 - -static const uint8_t mpc8_q8_codes[2][MPC8_Q8_SIZE] = { -{ - 0x03, 0x04, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x1A, - 0x0F, 0x1B, 0x10, 0x00, 0x01, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x11, 0x0C, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1C, 0x1A, - 0x1B, 0x1C, 0x1D, 0x1E, 0x1D, 0x1E, 0x1F, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x19, 0x25, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F, 0x14, 0x15, 0x16, 0x17, - 0x0E, 0x0F, 0x10, 0x11, 0x0B, 0x07, 0x04, 0x03, - 0x05, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x18, - 0x19, 0x1A, 0x1B, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x26, 0x27, 0x28, 0x29, 0x2A, - 0x2B, 0x2C, 0x2D, 0x2E, 0x1F, 0x20, 0x2F, 0x21, - 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x0D, 0x0E, 0x2A, 0x0F, 0x10, 0x11, 0x12, 0x02, - 0x13, 0x03, 0x04, 0x05, 0x2B, 0x2C, 0x30, 0x31, - 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, -}, -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, - 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, - 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, - 0x2F, 0x30, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, - 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x31, 0x3F, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, - 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x16, - 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, - 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x04, 0x05, 0x06, 0x07, -} -}; -static const int8_t mpc8_q8_bits[2][MPC8_Q8_SIZE] = { -{ - 11, 11, 10, 10, 10, 10, 10, 9, - 10, 9, 10, 12, 12, 11, 11, 11, - 11, 11, 11, 11, 10, 11, 10, 10, - 10, 10, 10, 10, 10, 10, 9, 10, - 10, 10, 10, 10, 9, 9, 9, 9, - 9, 9, 9, 9, 8, 9, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, - 6, 6, 6, 6, 5, 4, 3, 2, - 3, 5, 5, 6, 6, 6, 6, 7, - 7, 7, 7, 8, 8, 8, 8, 8, - 8, 8, 8, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 10, 10, 9, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 10, 11, 11, 11, 11, 12, - 11, 12, 12, 12, 10, 10, 9, 9, - 10, 10, 10, 10, 10, 10, 10, -}, -{ - 9, 9, 9, 9, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 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, 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, 7, 6, 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, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 9, 9, 9, 9, -} -}; - -#endif /* AVCODEC_MPC8HUFF_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpcdata.h b/tizen/distrib/ffmpeg/libavcodec/mpcdata.h deleted file mode 100644 index a2212ec..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpcdata.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Musepack decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPCDATA_H -#define AVCODEC_MPCDATA_H - -#include - -static const float mpc_CC[18] = { - 65536.0000, 21845.3333, 13107.2000, 9362.2857, 7281.7778, 4369.0667, 2114.0645, - 1040.2539, 516.0315, 257.0039, 128.2505, 64.0626, 32.0156, 16.0039, 8.0010, - 4.0002, 2.0001, 1.0000 -}; - -static const float mpc_SCF[128] = { - 307.330047607421875000, 255.999984741210937500, 213.243041992187500000, 177.627334594726562500, - 147.960128784179687500, 123.247924804687500000, 102.663139343261718750, 85.516410827636718750, - 71.233520507812500000, 59.336143493652343750, 49.425861358642578125, 41.170787811279296875, - 34.294471740722656250, 28.566631317138671875, 23.795452117919921875, 19.821151733398437500, - 16.510635375976562500, 13.753040313720703125, 11.456016540527343750, 9.542640686035156250, - 7.948835372924804688, 6.621226310729980469, 5.515353679656982422, 4.594182968139648438, - 3.826865673065185547, 3.187705039978027344, 2.655296564102172852, 2.211810588836669922, - 1.842395424842834473, 1.534679770469665527, 1.278358578681945801, 1.064847946166992188, - 0.886997759342193604, 0.738851964473724365, 0.615449428558349609, 0.512657463550567627, - 0.427033752202987671, 0.355710864067077637, 0.296300262212753296, 0.246812388300895691, - 0.205589950084686279, 0.171252459287643433, 0.142649993300437927, 0.118824683129787445, - 0.098978661000728607, 0.082447312772274017, 0.068677015602588654, 0.057206626981496811, - 0.047652013599872589, 0.039693206548690796, 0.033063672482967377, 0.027541399002075195, - 0.022941453382372856, 0.019109787419438362, 0.015918083488941193, 0.013259455561637878, - 0.011044870130717754, 0.009200163185596466, 0.007663558237254620, 0.006383595988154411, - 0.005317411851137877, 0.004429301247000694, 0.003689522389322519, 0.003073300700634718, - 0.002560000168159604, 0.002132430672645569, 0.001776273478753865, 0.001479601487517357, - 0.001232479466125369, 0.001026631565764546, 0.000855164253152907, 0.000712335284333676, - 0.000593361502978951, 0.000494258652906865, 0.000411707907915115, 0.000342944724252447, - 0.000285666319541633, 0.000237954518524930, 0.000198211506358348, 0.000165106350323185, - 0.000137530398205854, 0.000114560163638089, 0.000095426403277088, 0.000079488345363643, - 0.000066212254751008, 0.000055153526773211, 0.000045941822463647, 0.000038268648495432, - 0.000031877043511486, 0.000026552961571724, 0.000022118103515822, 0.000018423952496960, - 0.000015346795407822, 0.000012783583770215, 0.000010648477655195, 0.000008869976227288, - 0.000007388518497464, 0.000006154492893984, 0.000005126573796588, 0.000004270336830814, - 0.000003557107902452, 0.000002963002089018, 0.000002468123511790, 0.000002055899130937, - 0.000001712524181130, 0.000001426499579793, 0.000001188246528727, 0.000000989786371974, - 0.000000824472920158, 0.000000686770022185, 0.000000572066142013, 0.000000476520028769, - 0.000000396931966407, 0.000000330636652279, 0.000000275413924555, 0.000000229414467867, - 0.000000191097811353, 0.000000159180785886, 0.000000132594522029, 0.000000110448674207, - 0.000000092001613439, 0.000000076635565449, 0.000000063835940978, 0.000000053174105119, - 0.000000044293003043, 0.000000036895215771, 0.000000030733001921, 0.000000025599996789 -}; - -#endif /* AVCODEC_MPCDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg12.c b/tizen/distrib/ffmpeg/libavcodec/mpeg12.c deleted file mode 100644 index bc9ddcc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg12.c +++ /dev/null @@ -1,2610 +0,0 @@ -/* - * MPEG-1/2 decoder - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG-1/2 decoder - */ - -//#define DEBUG -#include "internal.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - -#include "mpeg12.h" -#include "mpeg12data.h" -#include "mpeg12decdata.h" -#include "bytestream.h" -#include "vdpau_internal.h" -#include "xvmc_internal.h" - -//#undef NDEBUG -//#include - - -#define MV_VLC_BITS 9 -#define MBINCR_VLC_BITS 9 -#define MB_PAT_VLC_BITS 9 -#define MB_PTYPE_VLC_BITS 6 -#define MB_BTYPE_VLC_BITS 6 - -static inline int mpeg1_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n); -static inline int mpeg1_decode_block_inter(MpegEncContext *s, - DCTELEM *block, - int n); -static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); -static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, - DCTELEM *block, - int n); -static inline int mpeg2_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n); -static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n); -static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); -static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred); -static void exchange_uv(MpegEncContext *s); - -static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { - PIX_FMT_XVMC_MPEG2_IDCT, - PIX_FMT_XVMC_MPEG2_MC, - PIX_FMT_NONE}; - -uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; - - -#define INIT_2D_VLC_RL(rl, static_size)\ -{\ - static RL_VLC_ELEM rl_vlc_table[static_size];\ - INIT_VLC_STATIC(&rl.vlc, TEX_VLC_BITS, rl.n + 2,\ - &rl.table_vlc[0][1], 4, 2,\ - &rl.table_vlc[0][0], 4, 2, static_size);\ -\ - rl.rl_vlc[0]= rl_vlc_table;\ - init_2d_vlc_rl(&rl);\ -} - -static void init_2d_vlc_rl(RLTable *rl) -{ - int i; - - 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= 65; - level= MAX_LEVEL; - }else if(len<0){ //more bits needed - run= 0; - level= code; - }else{ - if(code==rl->n){ //esc - run= 65; - level= 0; - }else if(code==rl->n+1){ //eob - run= 0; - level= 127; - }else{ - run= rl->table_run [code] + 1; - level= rl->table_level[code]; - } - } - rl->rl_vlc[0][i].len= len; - rl->rl_vlc[0][i].level= level; - rl->rl_vlc[0][i].run= run; - } -} - -void ff_mpeg12_common_init(MpegEncContext *s) -{ - - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg2_dc_scale_table[s->intra_dc_precision]; - -} - -void ff_mpeg1_clean_buffers(MpegEncContext *s){ - s->last_dc[0] = 1 << (7 + s->intra_dc_precision); - s->last_dc[1] = s->last_dc[0]; - s->last_dc[2] = s->last_dc[0]; - memset(s->last_mv, 0, sizeof(s->last_mv)); -} - - -/******************************************/ -/* decoding */ - -static VLC mv_vlc; -static VLC mbincr_vlc; -static VLC mb_ptype_vlc; -static VLC mb_btype_vlc; -static VLC mb_pat_vlc; - -av_cold void ff_mpeg12_init_vlcs(void) -{ - static int done = 0; - - if (!done) { - done = 1; - - INIT_VLC_STATIC(&dc_lum_vlc, DC_VLC_BITS, 12, - ff_mpeg12_vlc_dc_lum_bits, 1, 1, - ff_mpeg12_vlc_dc_lum_code, 2, 2, 512); - INIT_VLC_STATIC(&dc_chroma_vlc, DC_VLC_BITS, 12, - ff_mpeg12_vlc_dc_chroma_bits, 1, 1, - ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514); - INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17, - &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1, - &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518); - INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36, - &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1, - &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538); - INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64, - &ff_mpeg12_mbPatTable[0][1], 2, 1, - &ff_mpeg12_mbPatTable[0][0], 2, 1, 512); - - INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7, - &table_mb_ptype[0][1], 2, 1, - &table_mb_ptype[0][0], 2, 1, 64); - INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, - &table_mb_btype[0][1], 2, 1, - &table_mb_btype[0][0], 2, 1, 64); - init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); - init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); - - INIT_2D_VLC_RL(ff_rl_mpeg1, 680); - INIT_2D_VLC_RL(ff_rl_mpeg2, 674); - } -} - -static inline int get_dmv(MpegEncContext *s) -{ - if(get_bits1(&s->gb)) - return 1 - (get_bits1(&s->gb) << 1); - else - return 0; -} - -static inline int get_qscale(MpegEncContext *s) -{ - int qscale = get_bits(&s->gb, 5); - if (s->q_scale_type) { - return non_linear_qscale[qscale]; - } else { - return qscale << 1; - } -} - -/* motion type (for MPEG-2) */ -#define MT_FIELD 1 -#define MT_FRAME 2 -#define MT_16X8 2 -#define MT_DMV 3 - -static int mpeg_decode_mb(MpegEncContext *s, - DCTELEM block[12][64]) -{ - int i, j, k, cbp, val, mb_type, motion_type; - const int mb_block_count = 4 + (1<< s->chroma_format); - - dprintf(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); - - assert(s->mb_skipped==0); - - if (s->mb_skip_run-- != 0) { - if (s->pict_type == FF_P_TYPE) { - s->mb_skipped = 1; - s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; - } else { - int mb_type; - - if(s->mb_x) - mb_type= s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]; - else - mb_type= s->current_picture.mb_type[ s->mb_width + (s->mb_y-1)*s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all - if(IS_INTRA(mb_type)) - return -1; - - s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= - mb_type | MB_TYPE_SKIP; -// assert(s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]&(MB_TYPE_16x16|MB_TYPE_16x8)); - - if((s->mv[0][0][0]|s->mv[0][0][1]|s->mv[1][0][0]|s->mv[1][0][1])==0) - s->mb_skipped = 1; - } - - return 0; - } - - switch(s->pict_type) { - default: - case FF_I_TYPE: - if (get_bits1(&s->gb) == 0) { - if (get_bits1(&s->gb) == 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA; - } else { - mb_type = MB_TYPE_INTRA; - } - break; - case FF_P_TYPE: - mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1); - if (mb_type < 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = ptype2mb_type[ mb_type ]; - break; - case FF_B_TYPE: - mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1); - if (mb_type < 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_type = btype2mb_type[ mb_type ]; - break; - } - dprintf(s->avctx, "mb_type=%x\n", mb_type); -// motion_type = 0; /* avoid warning */ - if (IS_INTRA(mb_type)) { - s->dsp.clear_blocks(s->block[0]); - - if(!s->chroma_y_shift){ - s->dsp.clear_blocks(s->block[6]); - } - - /* compute DCT type */ - if (s->picture_structure == PICT_FRAME && //FIXME add an interlaced_dct coded var? - !s->frame_pred_frame_dct) { - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - if (s->concealment_motion_vectors) { - /* just parse them */ - if (s->picture_structure != PICT_FRAME) - skip_bits1(&s->gb); /* field select */ - - s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] = - mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]); - s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] = - mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]); - - skip_bits1(&s->gb); /* marker */ - }else - memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */ - s->mb_intra = 1; - //if 1, we memcpy blocks in xvmcvideo - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){ - ff_xvmc_pack_pblocks(s,-1);//inter are always full blocks - if(s->swap_uv){ - exchange_uv(s); - } - } - - if (s->codec_id == CODEC_ID_MPEG2VIDEO) { - if(s->flags2 & CODEC_FLAG2_FAST){ - for(i=0;i<6;i++) { - mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i); - } - }else{ - for(i=0;ipblocks[i], i) < 0) - return -1; - } - } - } else { - for(i=0;i<6;i++) { - if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0) - return -1; - } - } - } else { - if (mb_type & MB_TYPE_ZERO_MV){ - assert(mb_type & MB_TYPE_CBP); - - s->mv_dir = MV_DIR_FORWARD; - if(s->picture_structure == PICT_FRAME){ - if(!s->frame_pred_frame_dct) - s->interlaced_dct = get_bits1(&s->gb); - s->mv_type = MV_TYPE_16X16; - }else{ - s->mv_type = MV_TYPE_FIELD; - mb_type |= MB_TYPE_INTERLACED; - s->field_select[0][0]= s->picture_structure - 1; - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - s->last_mv[0][0][0] = 0; - s->last_mv[0][0][1] = 0; - s->last_mv[0][1][0] = 0; - s->last_mv[0][1][1] = 0; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - }else{ - assert(mb_type & MB_TYPE_L0L1); -//FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED - /* get additional motion vector type */ - if (s->frame_pred_frame_dct) - motion_type = MT_FRAME; - else{ - motion_type = get_bits(&s->gb, 2); - if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type)) - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - - /* motion vectors */ - s->mv_dir= (mb_type>>13)&3; - dprintf(s->avctx, "motion_type=%d\n", motion_type); - switch(motion_type) { - case MT_FRAME: /* or MT_16X8 */ - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x16; - s->mv_type = MV_TYPE_16X16; - for(i=0;i<2;i++) { - if (USES_LIST(mb_type, i)) { - /* MT_FRAME */ - s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] = - mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); - s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] = - mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]); - /* full_pel: only for MPEG-1 */ - if (s->full_pel[i]){ - s->mv[i][0][0] <<= 1; - s->mv[i][0][1] <<= 1; - } - } - } - } else { - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; - s->mv_type = MV_TYPE_16X8; - for(i=0;i<2;i++) { - if (USES_LIST(mb_type, i)) { - /* MT_16X8 */ - for(j=0;j<2;j++) { - s->field_select[i][j] = get_bits1(&s->gb); - for(k=0;k<2;k++) { - val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], - s->last_mv[i][j][k]); - s->last_mv[i][j][k] = val; - s->mv[i][j][k] = val; - } - } - } - } - } - break; - case MT_FIELD: - s->mv_type = MV_TYPE_FIELD; - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; - for(i=0;i<2;i++) { - if (USES_LIST(mb_type, i)) { - for(j=0;j<2;j++) { - s->field_select[i][j] = get_bits1(&s->gb); - val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], - s->last_mv[i][j][0]); - s->last_mv[i][j][0] = val; - s->mv[i][j][0] = val; - dprintf(s->avctx, "fmx=%d\n", val); - val = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][j][1] >> 1); - s->last_mv[i][j][1] = val << 1; - s->mv[i][j][1] = val; - dprintf(s->avctx, "fmy=%d\n", val); - } - } - } - } else { - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; - for(i=0;i<2;i++) { - if (USES_LIST(mb_type, i)) { - s->field_select[i][0] = get_bits1(&s->gb); - for(k=0;k<2;k++) { - val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], - s->last_mv[i][0][k]); - s->last_mv[i][0][k] = val; - s->last_mv[i][1][k] = val; - s->mv[i][0][k] = val; - } - } - } - } - break; - case MT_DMV: - s->mv_type = MV_TYPE_DMV; - for(i=0;i<2;i++) { - if (USES_LIST(mb_type, i)) { - int dmx, dmy, mx, my, m; - const int my_shift= s->picture_structure == PICT_FRAME; - - mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], - s->last_mv[i][0][0]); - s->last_mv[i][0][0] = mx; - s->last_mv[i][1][0] = mx; - dmx = get_dmv(s); - my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][0][1] >> my_shift); - dmy = get_dmv(s); - - - s->last_mv[i][0][1] = my<last_mv[i][1][1] = my<mv[i][0][0] = mx; - s->mv[i][0][1] = my; - s->mv[i][1][0] = mx;//not used - s->mv[i][1][1] = my;//not used - - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; - - //m = 1 + 2 * s->top_field_first; - m = s->top_field_first ? 1 : 3; - - /* top -> top pred */ - s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; - m = 4 - m; - s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; - } else { - mb_type |= MB_TYPE_16x16; - - s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy; - if(s->picture_structure == PICT_TOP_FIELD) - s->mv[i][2][1]--; - else - s->mv[i][2][1]++; - } - } - } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - } - - s->mb_intra = 0; - if (HAS_CBP(mb_type)) { - s->dsp.clear_blocks(s->block[0]); - - cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); - if(mb_block_count > 6){ - cbp<<= mb_block_count-6; - cbp |= get_bits(&s->gb, mb_block_count-6); - s->dsp.clear_blocks(s->block[6]); - } - if (cbp <= 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - //if 1, we memcpy blocks in xvmcvideo - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){ - ff_xvmc_pack_pblocks(s,cbp); - if(s->swap_uv){ - exchange_uv(s); - } - } - - if (s->codec_id == CODEC_ID_MPEG2VIDEO) { - if(s->flags2 & CODEC_FLAG2_FAST){ - for(i=0;i<6;i++) { - if(cbp & 32) { - mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i); - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - }else{ - cbp<<= 12-mb_block_count; - - for(i=0;ipblocks[i], i) < 0) - return -1; - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - } - } else { - if(s->flags2 & CODEC_FLAG2_FAST){ - for(i=0;i<6;i++) { - if (cbp & 32) { - mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i); - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - }else{ - for(i=0;i<6;i++) { - if (cbp & 32) { - if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0) - return -1; - } else { - s->block_last_index[i] = -1; - } - cbp+=cbp; - } - } - } - }else{ - for(i=0;i<12;i++) - s->block_last_index[i] = -1; - } - } - - s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= mb_type; - - return 0; -} - -/* as H.263, but only 17 codes */ -static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) -{ - int code, sign, val, l, shift; - - 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 = fcode - 1; - val = code; - if (shift) { - val = (val - 1) << shift; - val |= get_bits(&s->gb, shift); - val++; - } - if (sign) - val = -val; - val += pred; - - /* modulo decoding */ - l= INT_BIT - 5 - shift; - val = (val<>l; - return val; -} - -static inline int mpeg1_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int level, dc, diff, i, j, run; - int component; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable= s->intra_scantable.permutated; - const uint16_t *quant_matrix= s->intra_matrix; - const int qscale= s->qscale; - - /* DC coefficient */ - component = (n <= 3 ? 0 : n - 4 + 1); - diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return -1; - dc = s->last_dc[component]; - dc += diff; - s->last_dc[component] = dc; - block[0] = dc*quant_matrix[0]; - dprintf(s->avctx, "dc=%d diff=%d\n", dc, diff); - i = 0; - { - OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefficients */ - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level == 127){ - break; - } else if(level != 0) { - i += run; - j = scantable[i]; - level= (level*qscale*quant_matrix[j])>>4; - level= (level-1)|1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); - if (level == -128) { - level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8); - } else if (level == 0) { - level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8); - } - i += run; - j = scantable[i]; - if(level<0){ - level= -level; - level= (level*qscale*quant_matrix[j])>>4; - level= (level-1)|1; - level= -level; - }else{ - level= (level*qscale*quant_matrix[j])>>4; - level= (level-1)|1; - } - } - 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[j] = level; - } - CLOSE_READER(re, &s->gb); - } - s->block_last_index[n] = i; - return 0; -} - -int ff_mpeg1_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n) -{ - return mpeg1_decode_block_intra(s, block, n); -} - -static inline int mpeg1_decode_block_inter(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable= s->intra_scantable.permutated; - const uint16_t *quant_matrix= s->inter_matrix; - const int qscale= s->qscale; - - { - OPEN_READER(re, &s->gb); - i = -1; - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level= (3*qscale*quant_matrix[0])>>5; - level= (level-1)|1; - if(GET_CACHE(re, &s->gb)&0x40000000) - level= -level; - block[0] = level; - i++; - SKIP_BITS(re, &s->gb, 2); - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - /* now quantify & encode AC coefficients */ - for(;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level != 0) { - i += run; - j = scantable[i]; - level= ((level*2+1)*qscale*quant_matrix[j])>>5; - level= (level-1)|1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); - if (level == -128) { - level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8); - } else if (level == 0) { - level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8); - } - i += run; - j = scantable[i]; - if(level<0){ - level= -level; - level= ((level*2+1)*qscale*quant_matrix[j])>>5; - level= (level-1)|1; - level= -level; - }else{ - level= ((level*2+1)*qscale*quant_matrix[j])>>5; - level= (level-1)|1; - } - } - 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[j] = level; -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; -#if MIN_CACHE_BITS >= 19 - UPDATE_CACHE(re, &s->gb); -#endif - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - } - s->block_last_index[n] = i; - return 0; -} - -static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable= s->intra_scantable.permutated; - const int qscale= s->qscale; - - { - OPEN_READER(re, &s->gb); - i = -1; - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level= (3*qscale)>>1; - level= (level-1)|1; - if(GET_CACHE(re, &s->gb)&0x40000000) - level= -level; - block[0] = level; - i++; - SKIP_BITS(re, &s->gb, 2); - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - - /* now quantify & encode AC coefficients */ - for(;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level != 0) { - i += run; - j = scantable[i]; - level= ((level*2+1)*qscale)>>1; - level= (level-1)|1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); - if (level == -128) { - level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8); - } else if (level == 0) { - level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8); - } - i += run; - j = scantable[i]; - if(level<0){ - level= -level; - level= ((level*2+1)*qscale)>>1; - level= (level-1)|1; - level= -level; - }else{ - level= ((level*2+1)*qscale)>>1; - level= (level-1)|1; - } - } - - block[j] = level; -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; -#if MIN_CACHE_BITS >= 19 - UPDATE_CACHE(re, &s->gb); -#endif - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - } - s->block_last_index[n] = i; - return 0; -} - - -static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable= s->intra_scantable.permutated; - const uint16_t *quant_matrix; - const int qscale= s->qscale; - int mismatch; - - mismatch = 1; - - { - OPEN_READER(re, &s->gb); - i = -1; - if (n < 4) - quant_matrix = s->inter_matrix; - else - quant_matrix = s->chroma_inter_matrix; - - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level= (3*qscale*quant_matrix[0])>>5; - if(GET_CACHE(re, &s->gb)&0x40000000) - level= -level; - block[0] = level; - mismatch ^= level; - i++; - SKIP_BITS(re, &s->gb, 2); - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - - /* now quantify & encode AC coefficients */ - for(;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level != 0) { - i += run; - j = scantable[i]; - level= ((level*2+1)*qscale*quant_matrix[j])>>5; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - - i += run; - j = scantable[i]; - if(level<0){ - level= ((-level*2+1)*qscale*quant_matrix[j])>>5; - level= -level; - }else{ - level= ((level*2+1)*qscale*quant_matrix[j])>>5; - } - } - 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; - } - - mismatch ^= level; - block[j] = level; -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; -#if MIN_CACHE_BITS >= 19 - UPDATE_CACHE(re, &s->gb); -#endif - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - } - block[63] ^= (mismatch & 1); - - s->block_last_index[n] = i; - return 0; -} - -static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int level, i, j, run; - RLTable *rl = &ff_rl_mpeg1; - uint8_t * const scantable= s->intra_scantable.permutated; - const int qscale= s->qscale; - OPEN_READER(re, &s->gb); - i = -1; - - // special case for first coefficient, no need to add second VLC table - UPDATE_CACHE(re, &s->gb); - if (((int32_t)GET_CACHE(re, &s->gb)) < 0) { - level= (3*qscale)>>1; - if(GET_CACHE(re, &s->gb)&0x40000000) - level= -level; - block[0] = level; - i++; - SKIP_BITS(re, &s->gb, 2); - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - goto end; - } -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - - /* now quantify & encode AC coefficients */ - for(;;) { - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level != 0) { - i += run; - j = scantable[i]; - level= ((level*2+1)*qscale)>>1; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - - i += run; - j = scantable[i]; - if(level<0){ - level= ((-level*2+1)*qscale)>>1; - level= -level; - }else{ - level= ((level*2+1)*qscale)>>1; - } - } - - block[j] = level; -#if MIN_CACHE_BITS < 19 - UPDATE_CACHE(re, &s->gb); -#endif - if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) - break; -#if MIN_CACHE_BITS >=19 - UPDATE_CACHE(re, &s->gb); -#endif - } -end: - LAST_SKIP_BITS(re, &s->gb, 2); - CLOSE_READER(re, &s->gb); - s->block_last_index[n] = i; - return 0; -} - - -static inline int mpeg2_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int level, dc, diff, i, j, run; - int component; - RLTable *rl; - uint8_t * const scantable= s->intra_scantable.permutated; - const uint16_t *quant_matrix; - const int qscale= s->qscale; - int mismatch; - - /* DC coefficient */ - if (n < 4){ - quant_matrix = s->intra_matrix; - component = 0; - }else{ - quant_matrix = s->chroma_intra_matrix; - component = (n&1) + 1; - } - diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return -1; - dc = s->last_dc[component]; - dc += diff; - s->last_dc[component] = dc; - block[0] = dc << (3 - s->intra_dc_precision); - dprintf(s->avctx, "dc=%d\n", block[0]); - mismatch = block[0] ^ 1; - i = 0; - if (s->intra_vlc_format) - rl = &ff_rl_mpeg2; - else - rl = &ff_rl_mpeg1; - - { - OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefficients */ - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level == 127){ - break; - } else if(level != 0) { - i += run; - j = scantable[i]; - level= (level*qscale*quant_matrix[j])>>4; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - i += run; - j = scantable[i]; - if(level<0){ - level= (-level*qscale*quant_matrix[j])>>4; - level= -level; - }else{ - level= (level*qscale*quant_matrix[j])>>4; - } - } - 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; - } - - mismatch^= level; - block[j] = level; - } - CLOSE_READER(re, &s->gb); - } - block[63]^= mismatch&1; - - s->block_last_index[n] = i; - return 0; -} - -static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int level, dc, diff, j, run; - int component; - RLTable *rl; - uint8_t * scantable= s->intra_scantable.permutated; - const uint16_t *quant_matrix; - const int qscale= s->qscale; - - /* DC coefficient */ - if (n < 4){ - quant_matrix = s->intra_matrix; - component = 0; - }else{ - quant_matrix = s->chroma_intra_matrix; - component = (n&1) + 1; - } - diff = decode_dc(&s->gb, component); - if (diff >= 0xffff) - return -1; - dc = s->last_dc[component]; - dc += diff; - s->last_dc[component] = dc; - block[0] = dc << (3 - s->intra_dc_precision); - if (s->intra_vlc_format) - rl = &ff_rl_mpeg2; - else - rl = &ff_rl_mpeg1; - - { - OPEN_READER(re, &s->gb); - /* now quantify & encode AC coefficients */ - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); - - if(level == 127){ - break; - } else if(level != 0) { - scantable += run; - j = *scantable; - level= (level*qscale*quant_matrix[j])>>4; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); - } else { - /* escape */ - run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); - UPDATE_CACHE(re, &s->gb); - level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - scantable += run; - j = *scantable; - if(level<0){ - level= (-level*qscale*quant_matrix[j])>>4; - level= -level; - }else{ - level= (level*qscale*quant_matrix[j])>>4; - } - } - - block[j] = level; - } - CLOSE_READER(re, &s->gb); - } - - s->block_last_index[n] = scantable - s->intra_scantable.permutated; - return 0; -} - -typedef struct Mpeg1Context { - MpegEncContext mpeg_enc_ctx; - int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ - int repeat_field; /* true if we must repeat the field */ - AVPanScan pan_scan; /** some temporary storage for the panscan */ - int slice_count; - int swap_uv;//indicate VCR2 - int save_aspect_info; - int save_width, save_height, save_progressive_seq; - AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator - int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame? -} Mpeg1Context; - -static av_cold int mpeg_decode_init(AVCodecContext *avctx) -{ - Mpeg1Context *s = avctx->priv_data; - MpegEncContext *s2 = &s->mpeg_enc_ctx; - int i; - - /* we need some permutation to store matrices, - * until MPV_common_init() sets the real permutation. */ - for(i=0;i<64;i++) - s2->dsp.idct_permutation[i]=i; - - MPV_decode_defaults(s2); - - s->mpeg_enc_ctx.avctx= avctx; - s->mpeg_enc_ctx.flags= avctx->flags; - s->mpeg_enc_ctx.flags2= avctx->flags2; - ff_mpeg12_common_init(&s->mpeg_enc_ctx); - ff_mpeg12_init_vlcs(); - - s->mpeg_enc_ctx_allocated = 0; - s->mpeg_enc_ctx.picture_number = 0; - s->repeat_field = 0; - s->mpeg_enc_ctx.codec_id= avctx->codec->id; - avctx->color_range= AVCOL_RANGE_MPEG; - if (avctx->codec->id == CODEC_ID_MPEG1VIDEO) - avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; - else - avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; - return 0; -} - -static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, - const uint8_t *new_perm){ - uint16_t temp_matrix[64]; - int i; - - memcpy(temp_matrix,matrix,64*sizeof(uint16_t)); - - for(i=0;i<64;i++){ - matrix[new_perm[i]] = temp_matrix[old_perm[i]]; - } -} - -static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx){ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - - if(avctx->xvmc_acceleration) - return avctx->get_format(avctx,pixfmt_xvmc_mpg2_420); - else if(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){ - if(avctx->codec_id == CODEC_ID_MPEG1VIDEO) - return PIX_FMT_VDPAU_MPEG1; - else - return PIX_FMT_VDPAU_MPEG2; - }else{ - if(s->chroma_format < 2) - return avctx->get_format(avctx,ff_hwaccel_pixfmt_list_420); - else if(s->chroma_format == 2) - return PIX_FMT_YUV422P; - else - return PIX_FMT_YUV444P; - } -} - -/* Call this function when we know all parameters. - * It may be called in different places for MPEG-1 and MPEG-2. */ -static int mpeg_decode_postinit(AVCodecContext *avctx){ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - uint8_t old_permutation[64]; - - if ( - (s1->mpeg_enc_ctx_allocated == 0)|| - avctx->coded_width != s->width || - avctx->coded_height != s->height|| - s1->save_width != s->width || - s1->save_height != s->height || - s1->save_aspect_info != s->aspect_ratio_info|| - s1->save_progressive_seq != s->progressive_sequence || - 0) - { - - if (s1->mpeg_enc_ctx_allocated) { - ParseContext pc= s->parse_context; - s->parse_context.buffer=0; - MPV_common_end(s); - s->parse_context= pc; - } - - if( (s->width == 0 )||(s->height == 0)) - return -2; - - avcodec_set_dimensions(avctx, s->width, s->height); - avctx->bit_rate = s->bit_rate; - s1->save_aspect_info = s->aspect_ratio_info; - s1->save_width = s->width; - s1->save_height = s->height; - s1->save_progressive_seq = s->progressive_sequence; - - /* low_delay may be forced, in this case we will have B-frames - * that behave like P-frames. */ - avctx->has_b_frames = !(s->low_delay); - - assert((avctx->sub_id==1) == (avctx->codec_id==CODEC_ID_MPEG1VIDEO)); - if(avctx->codec_id==CODEC_ID_MPEG1VIDEO){ - //MPEG-1 fps - avctx->time_base.den= ff_frame_rate_tab[s->frame_rate_index].num; - avctx->time_base.num= ff_frame_rate_tab[s->frame_rate_index].den; - //MPEG-1 aspect - avctx->sample_aspect_ratio= av_d2q( - 1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255); - avctx->ticks_per_frame=1; - }else{//MPEG-2 - //MPEG-2 fps - av_reduce( - &s->avctx->time_base.den, - &s->avctx->time_base.num, - ff_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2, - ff_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den, - 1<<30); - avctx->ticks_per_frame=2; - //MPEG-2 aspect - if(s->aspect_ratio_info > 1){ - //we ignore the spec here as reality does not match the spec, see for example - // res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg - if( (s1->pan_scan.width == 0 )||(s1->pan_scan.height == 0) || 1){ - s->avctx->sample_aspect_ratio= - av_div_q( - ff_mpeg2_aspect[s->aspect_ratio_info], - (AVRational){s->width, s->height} - ); - }else{ - s->avctx->sample_aspect_ratio= - av_div_q( - ff_mpeg2_aspect[s->aspect_ratio_info], - (AVRational){s1->pan_scan.width, s1->pan_scan.height} - ); - } - }else{ - s->avctx->sample_aspect_ratio= - ff_mpeg2_aspect[s->aspect_ratio_info]; - } - }//MPEG-2 - - avctx->pix_fmt = mpeg_get_pixelformat(avctx); - avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); - //until then pix_fmt may be changed right after codec init - if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || - avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) - if( avctx->idct_algo == FF_IDCT_AUTO ) - avctx->idct_algo = FF_IDCT_SIMPLE; - - /* Quantization matrices may need reordering - * if DCT permutation is changed. */ - memcpy(old_permutation,s->dsp.idct_permutation,64*sizeof(uint8_t)); - - if (MPV_common_init(s) < 0) - return -2; - - quant_matrix_rebuild(s->intra_matrix, old_permutation,s->dsp.idct_permutation); - quant_matrix_rebuild(s->inter_matrix, old_permutation,s->dsp.idct_permutation); - quant_matrix_rebuild(s->chroma_intra_matrix,old_permutation,s->dsp.idct_permutation); - quant_matrix_rebuild(s->chroma_inter_matrix,old_permutation,s->dsp.idct_permutation); - - s1->mpeg_enc_ctx_allocated = 1; - } - return 0; -} - -static int mpeg1_decode_picture(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int ref, f_code, vbv_delay; - - init_get_bits(&s->gb, buf, buf_size*8); - - ref = get_bits(&s->gb, 10); /* temporal ref */ - s->pict_type = get_bits(&s->gb, 3); - if(s->pict_type == 0 || s->pict_type > 3) - return -1; - - vbv_delay= get_bits(&s->gb, 16); - if (s->pict_type == FF_P_TYPE || s->pict_type == FF_B_TYPE) { - s->full_pel[0] = get_bits1(&s->gb); - f_code = get_bits(&s->gb, 3); - if (f_code == 0 && avctx->error_recognition >= FF_ER_COMPLIANT) - return -1; - s->mpeg_f_code[0][0] = f_code; - s->mpeg_f_code[0][1] = f_code; - } - if (s->pict_type == FF_B_TYPE) { - s->full_pel[1] = get_bits1(&s->gb); - f_code = get_bits(&s->gb, 3); - if (f_code == 0 && avctx->error_recognition >= FF_ER_COMPLIANT) - return -1; - s->mpeg_f_code[1][0] = f_code; - s->mpeg_f_code[1][1] = f_code; - } - s->current_picture.pict_type= s->pict_type; - s->current_picture.key_frame= s->pict_type == FF_I_TYPE; - - if(avctx->debug & FF_DEBUG_PICT_INFO) - av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type); - - s->y_dc_scale = 8; - s->c_dc_scale = 8; - return 0; -} - -static void mpeg_decode_sequence_extension(Mpeg1Context *s1) -{ - MpegEncContext *s= &s1->mpeg_enc_ctx; - int horiz_size_ext, vert_size_ext; - int bit_rate_ext; - - skip_bits(&s->gb, 1); /* profile and level esc*/ - s->avctx->profile= get_bits(&s->gb, 3); - s->avctx->level= get_bits(&s->gb, 4); - s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */ - s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */ - horiz_size_ext = get_bits(&s->gb, 2); - vert_size_ext = get_bits(&s->gb, 2); - s->width |= (horiz_size_ext << 12); - s->height |= (vert_size_ext << 12); - bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */ - s->bit_rate += (bit_rate_ext << 18) * 400; - skip_bits1(&s->gb); /* marker */ - s->avctx->rc_buffer_size += get_bits(&s->gb, 8)*1024*16<<10; - - s->low_delay = get_bits1(&s->gb); - if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1; - - s1->frame_rate_ext.num = get_bits(&s->gb, 2)+1; - s1->frame_rate_ext.den = get_bits(&s->gb, 5)+1; - - dprintf(s->avctx, "sequence extension\n"); - s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO; - s->avctx->sub_id = 2; /* indicates MPEG-2 found */ - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n", - s->avctx->profile, s->avctx->level, s->avctx->rc_buffer_size, s->bit_rate); - -} - -static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1) -{ - MpegEncContext *s= &s1->mpeg_enc_ctx; - int color_description, w, h; - - skip_bits(&s->gb, 3); /* video format */ - color_description= get_bits1(&s->gb); - if(color_description){ - s->avctx->color_primaries= get_bits(&s->gb, 8); - s->avctx->color_trc = get_bits(&s->gb, 8); - s->avctx->colorspace = get_bits(&s->gb, 8); - } - w= get_bits(&s->gb, 14); - skip_bits(&s->gb, 1); //marker - h= get_bits(&s->gb, 14); - skip_bits(&s->gb, 1); //marker - - s1->pan_scan.width= 16*w; - s1->pan_scan.height=16*h; - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h); -} - -static void mpeg_decode_picture_display_extension(Mpeg1Context *s1) -{ - MpegEncContext *s= &s1->mpeg_enc_ctx; - int i,nofco; - - nofco = 1; - if(s->progressive_sequence){ - if(s->repeat_first_field){ - nofco++; - if(s->top_field_first) - nofco++; - } - }else{ - if(s->picture_structure == PICT_FRAME){ - nofco++; - if(s->repeat_first_field) - nofco++; - } - } - for(i=0; ipan_scan.position[i][0]= get_sbits(&s->gb, 16); - skip_bits(&s->gb, 1); //marker - s1->pan_scan.position[i][1]= get_sbits(&s->gb, 16); - skip_bits(&s->gb, 1); //marker - } - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "pde (%d,%d) (%d,%d) (%d,%d)\n", - s1->pan_scan.position[0][0], s1->pan_scan.position[0][1], - s1->pan_scan.position[1][0], s1->pan_scan.position[1][1], - s1->pan_scan.position[2][0], s1->pan_scan.position[2][1] - ); -} - -static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra){ - int i; - - for(i=0; i<64; i++) { - int j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - int v = get_bits(&s->gb, 8); - if(v==0){ - av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n"); - return -1; - } - if(intra && i==0 && v!=8){ - av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n"); - v= 8; // needed by pink.mpg / issue1046 - } - matrix0[j] = v; - if(matrix1) - matrix1[j] = v; - } - return 0; -} - -static void mpeg_decode_quant_matrix_extension(MpegEncContext *s) -{ - dprintf(s->avctx, "matrix extension\n"); - - if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); - if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); - if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL , 1); - if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL , 0); -} - -static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) -{ - MpegEncContext *s= &s1->mpeg_enc_ctx; - - s->full_pel[0] = s->full_pel[1] = 0; - s->mpeg_f_code[0][0] = get_bits(&s->gb, 4); - s->mpeg_f_code[0][1] = get_bits(&s->gb, 4); - s->mpeg_f_code[1][0] = get_bits(&s->gb, 4); - s->mpeg_f_code[1][1] = get_bits(&s->gb, 4); - if(!s->pict_type && s1->mpeg_enc_ctx_allocated){ - av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n"); - if(s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1]==15){ - if(s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15) - s->pict_type= FF_I_TYPE; - else - s->pict_type= FF_P_TYPE; - }else - s->pict_type= FF_B_TYPE; - s->current_picture.pict_type= s->pict_type; - s->current_picture.key_frame= s->pict_type == FF_I_TYPE; - } - s->intra_dc_precision = get_bits(&s->gb, 2); - s->picture_structure = get_bits(&s->gb, 2); - s->top_field_first = get_bits1(&s->gb); - s->frame_pred_frame_dct = get_bits1(&s->gb); - s->concealment_motion_vectors = get_bits1(&s->gb); - s->q_scale_type = get_bits1(&s->gb); - s->intra_vlc_format = get_bits1(&s->gb); - s->alternate_scan = get_bits1(&s->gb); - s->repeat_first_field = get_bits1(&s->gb); - s->chroma_420_type = get_bits1(&s->gb); - s->progressive_frame = get_bits1(&s->gb); - - if(s->progressive_sequence && !s->progressive_frame){ - s->progressive_frame= 1; - av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n"); - } - - if(s->picture_structure==0 || (s->progressive_frame && s->picture_structure!=PICT_FRAME)){ - av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure); - s->picture_structure= PICT_FRAME; - } - - if(s->progressive_sequence && !s->frame_pred_frame_dct){ - av_log(s->avctx, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n"); - s->frame_pred_frame_dct= 1; - } - - if(s->picture_structure == PICT_FRAME){ - s->first_field=0; - s->v_edge_pos= 16*s->mb_height; - }else{ - s->first_field ^= 1; - s->v_edge_pos= 8*s->mb_height; - memset(s->mbskip_table, 0, s->mb_stride*s->mb_height); - } - - 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); - }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); - } - - /* composite display not parsed */ - dprintf(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision); - dprintf(s->avctx, "picture_structure=%d\n", s->picture_structure); - dprintf(s->avctx, "top field first=%d\n", s->top_field_first); - dprintf(s->avctx, "repeat first field=%d\n", s->repeat_first_field); - dprintf(s->avctx, "conceal=%d\n", s->concealment_motion_vectors); - dprintf(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format); - dprintf(s->avctx, "alternate_scan=%d\n", s->alternate_scan); - dprintf(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct); - dprintf(s->avctx, "progressive_frame=%d\n", s->progressive_frame); -} - -static void exchange_uv(MpegEncContext *s){ - DCTELEM (*tmp)[64]; - - tmp = s->pblocks[4]; - s->pblocks[4] = s->pblocks[5]; - s->pblocks[5] = tmp; -} - -static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size){ - AVCodecContext *avctx= s->avctx; - Mpeg1Context *s1 = (Mpeg1Context*)s; - - /* start frame decoding */ - if(s->first_field || s->picture_structure==PICT_FRAME){ - if(MPV_frame_start(s, avctx) < 0) - return -1; - - ff_er_frame_start(s); - - /* first check if we must repeat the frame */ - s->current_picture_ptr->repeat_pict = 0; - if (s->repeat_first_field) { - if (s->progressive_sequence) { - if (s->top_field_first) - s->current_picture_ptr->repeat_pict = 4; - else - s->current_picture_ptr->repeat_pict = 2; - } else if (s->progressive_frame) { - s->current_picture_ptr->repeat_pict = 1; - } - } - - *s->current_picture_ptr->pan_scan= s1->pan_scan; - }else{ //second field - int i; - - if(!s->current_picture_ptr){ - av_log(s->avctx, AV_LOG_ERROR, "first field missing\n"); - return -1; - } - - for(i=0; i<4; i++){ - s->current_picture.data[i] = s->current_picture_ptr->data[i]; - if(s->picture_structure == PICT_BOTTOM_FIELD){ - s->current_picture.data[i] += s->current_picture_ptr->linesize[i]; - } - } - } - - if (avctx->hwaccel) { - if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) - return -1; - } - -// MPV_frame_start will call this function too, -// but we need to call it on every field - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) - if(ff_xvmc_field_start(s,avctx) < 0) - return -1; - - return 0; -} - -#define DECODE_SLICE_ERROR -1 -#define DECODE_SLICE_OK 0 - -/** - * decodes a slice. MpegEncContext.mb_y must be set to the MB row from the startcode - * @return DECODE_SLICE_ERROR if the slice is damaged
- * DECODE_SLICE_OK if this slice is ok
- */ -static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, - const uint8_t **buf, int buf_size) -{ - MpegEncContext *s = &s1->mpeg_enc_ctx; - AVCodecContext *avctx= s->avctx; - const int field_pic= s->picture_structure != PICT_FRAME; - const int lowres= s->avctx->lowres; - - s->resync_mb_x= - s->resync_mb_y= -1; - - assert(mb_y < s->mb_height); - - init_get_bits(&s->gb, *buf, buf_size*8); - - ff_mpeg1_clean_buffers(s); - s->interlaced_dct = 0; - - s->qscale = get_qscale(s); - - if(s->qscale == 0){ - av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n"); - return -1; - } - - /* extra slice info */ - while (get_bits1(&s->gb) != 0) { - skip_bits(&s->gb, 8); - } - - s->mb_x=0; - - if(mb_y==0 && s->codec_tag == AV_RL32("SLIF")){ - skip_bits1(&s->gb); - }else{ - for(;;) { - int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n"); - return -1; - } - if (code >= 33) { - if (code == 33) { - s->mb_x += 33; - } - /* otherwise, stuffing, nothing to do */ - } else { - s->mb_x += code; - break; - } - } - } - - if(s->mb_x >= (unsigned)s->mb_width){ - av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n"); - return -1; - } - - if (avctx->hwaccel) { - const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */ - int start_code = -1; - buf_end = ff_find_start_code(buf_start + 2, *buf + buf_size, &start_code); - if (buf_end < *buf + buf_size) - buf_end -= 4; - s->mb_y = mb_y; - if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0) - return DECODE_SLICE_ERROR; - *buf = buf_end; - return DECODE_SLICE_OK; - } - - s->resync_mb_x= s->mb_x; - s->resync_mb_y= s->mb_y= mb_y; - s->mb_skip_run= 0; - ff_init_block_index(s); - - if (s->mb_y==0 && s->mb_x==0 && (s->first_field || s->picture_structure==PICT_FRAME)) { - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", - s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1], - s->pict_type == FF_I_TYPE ? "I" : (s->pict_type == FF_P_TYPE ? "P" : (s->pict_type == FF_B_TYPE ? "B" : "S")), - s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", - s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors, - s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :""); - } - } - - for(;;) { - //If 1, we memcpy blocks in xvmcvideo. - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) - ff_xvmc_init_block(s);//set s->block - - if(mpeg_decode_mb(s, s->block) < 0) - return -1; - - if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs - const int wrap = s->b8_stride; - int xy = s->mb_x*2 + s->mb_y*2*wrap; - int b8_xy= 4*(s->mb_x + s->mb_y*s->mb_stride); - int motion_x, motion_y, dir, i; - - for(i=0; i<2; i++){ - for(dir=0; dir<2; dir++){ - if (s->mb_intra || (dir==1 && s->pict_type != FF_B_TYPE)) { - motion_x = motion_y = 0; - }else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)){ - motion_x = s->mv[dir][0][0]; - motion_y = s->mv[dir][0][1]; - } else /*if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8))*/ { - motion_x = s->mv[dir][i][0]; - motion_y = s->mv[dir][i][1]; - } - - s->current_picture.motion_val[dir][xy ][0] = motion_x; - s->current_picture.motion_val[dir][xy ][1] = motion_y; - s->current_picture.motion_val[dir][xy + 1][0] = motion_x; - s->current_picture.motion_val[dir][xy + 1][1] = motion_y; - s->current_picture.ref_index [dir][b8_xy ]= - s->current_picture.ref_index [dir][b8_xy + 1]= s->field_select[dir][i]; - assert(s->field_select[dir][i]==0 || s->field_select[dir][i]==1); - } - xy += wrap; - b8_xy +=2; - } - } - - s->dest[0] += 16 >> lowres; - s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift; - s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift; - - MPV_decode_mb(s, s->block); - - if (++s->mb_x >= s->mb_width) { - const int mb_size= 16>>s->avctx->lowres; - - ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size); - - s->mb_x = 0; - s->mb_y += 1<mb_y >= s->mb_height){ - int left= get_bits_left(&s->gb); - int is_d10= s->chroma_format==2 && s->pict_type==FF_I_TYPE && avctx->profile==0 && avctx->level==5 - && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0 - && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/; - - if(left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) - || (avctx->error_recognition >= FF_ER_AGGRESSIVE && left>8)){ - av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23))); - return -1; - }else - goto eos; - } - - ff_init_block_index(s); - } - - /* skip mb handling */ - if (s->mb_skip_run == -1) { - /* read increment again */ - s->mb_skip_run = 0; - for(;;) { - int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n"); - return -1; - } - if (code >= 33) { - if (code == 33) { - s->mb_skip_run += 33; - }else if(code == 35){ - if(s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0){ - av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n"); - return -1; - } - goto eos; /* end of slice */ - } - /* otherwise, stuffing, nothing to do */ - } else { - s->mb_skip_run += code; - break; - } - } - if(s->mb_skip_run){ - int i; - if(s->pict_type == FF_I_TYPE){ - av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<12;i++) - s->block_last_index[i] = -1; - if(s->picture_structure == PICT_FRAME) - s->mv_type = MV_TYPE_16X16; - else - s->mv_type = MV_TYPE_FIELD; - if (s->pict_type == FF_P_TYPE) { - /* if P type, zero motion vector is implied */ - s->mv_dir = MV_DIR_FORWARD; - s->mv[0][0][0] = s->mv[0][0][1] = 0; - s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; - s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; - s->field_select[0][0]= (s->picture_structure - 1) & 1; - } else { - /* if B type, reuse previous vectors and directions */ - s->mv[0][0][0] = s->last_mv[0][0][0]; - s->mv[0][0][1] = s->last_mv[0][0][1]; - s->mv[1][0][0] = s->last_mv[1][0][0]; - s->mv[1][0][1] = s->last_mv[1][0][1]; - } - } - } - } -eos: // end of slice - *buf += (get_bits_count(&s->gb)-1)/8; -//printf("y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y); - return 0; -} - -static int slice_decode_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= *(void**)arg; - const uint8_t *buf= s->gb.buffer; - int mb_y= s->start_mb_y; - const int field_pic= s->picture_structure != PICT_FRAME; - - s->error_count= (3*(s->end_mb_y - s->start_mb_y)*s->mb_width) >> field_pic; - - for(;;){ - uint32_t start_code; - int ret; - - ret= mpeg_decode_slice((Mpeg1Context*)s, mb_y, &buf, s->gb.buffer_end - buf); - emms_c(); -//av_log(c, AV_LOG_DEBUG, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n", -//ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, s->start_mb_y, s->end_mb_y, s->error_count); - if(ret < 0){ - if(s->resync_mb_x>=0 && s->resync_mb_y>=0) - 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); - }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); - } - - if(s->mb_y == s->end_mb_y) - return 0; - - start_code= -1; - buf = ff_find_start_code(buf, s->gb.buffer_end, &start_code); - mb_y= start_code - SLICE_MIN_START_CODE; - if(mb_y < 0 || mb_y >= s->end_mb_y) - return -1; - } - - return 0; //not reached -} - -/** - * Handles slice ends. - * @return 1 if it seems to be the last slice - */ -static int slice_end(AVCodecContext *avctx, AVFrame *pict) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - - if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr) - return 0; - - if (s->avctx->hwaccel) { - if (s->avctx->hwaccel->end_frame(s->avctx) < 0) - av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n"); - } - - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) - ff_xvmc_field_end(s); - - /* end of slice reached */ - if (/*s->mb_y<mb_height &&*/ !s->first_field) { - /* end of image */ - - s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_MPEG2; - - ff_er_frame_end(s); - - MPV_frame_end(s); - - if (s->pict_type == FF_B_TYPE || s->low_delay) { - *pict= *(AVFrame*)s->current_picture_ptr; - ff_print_debug_info(s, pict); - } else { - s->picture_number++; - /* latency of 1 frame for I- and P-frames */ - /* XXX: use another variable than picture_number */ - if (s->last_picture_ptr != NULL) { - *pict= *(AVFrame*)s->last_picture_ptr; - ff_print_debug_info(s, pict); - } - } - - return 1; - } else { - return 0; - } -} - -static int mpeg1_decode_sequence(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int width,height; - int i, v, j; - - init_get_bits(&s->gb, buf, buf_size*8); - - width = get_bits(&s->gb, 12); - height = get_bits(&s->gb, 12); - if (width <= 0 || height <= 0) - return -1; - s->aspect_ratio_info= get_bits(&s->gb, 4); - if (s->aspect_ratio_info == 0) { - av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n"); - if (avctx->error_recognition >= FF_ER_COMPLIANT) - return -1; - } - s->frame_rate_index = get_bits(&s->gb, 4); - if (s->frame_rate_index == 0 || s->frame_rate_index > 13) - return -1; - s->bit_rate = get_bits(&s->gb, 18) * 400; - if (get_bits1(&s->gb) == 0) /* marker */ - return -1; - s->width = width; - s->height = height; - - s->avctx->rc_buffer_size= get_bits(&s->gb, 10) * 1024*16; - skip_bits(&s->gb, 1); - - /* get matrix */ - if (get_bits1(&s->gb)) { - load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1); - } else { - for(i=0;i<64;i++) { - j = s->dsp.idct_permutation[i]; - v = ff_mpeg1_default_intra_matrix[i]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - } - } - if (get_bits1(&s->gb)) { - load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0); - } else { - for(i=0;i<64;i++) { - int j= s->dsp.idct_permutation[i]; - v = ff_mpeg1_default_non_intra_matrix[i]; - s->inter_matrix[j] = v; - s->chroma_inter_matrix[j] = v; - } - } - - if(show_bits(&s->gb, 23) != 0){ - av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n"); - return -1; - } - - /* we set MPEG-2 parameters so that it emulates MPEG-1 */ - s->progressive_sequence = 1; - s->progressive_frame = 1; - s->picture_structure = PICT_FRAME; - s->frame_pred_frame_dct = 1; - s->chroma_format = 1; - s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG1VIDEO; - avctx->sub_id = 1; /* indicates MPEG-1 */ - s->out_format = FMT_MPEG1; - s->swap_uv = 0;//AFAIK VCR2 does not have SEQ_HEADER - if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1; - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d\n", - s->avctx->rc_buffer_size, s->bit_rate); - - return 0; -} - -static int vcr2_init_sequence(AVCodecContext *avctx) -{ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - int i, v; - - /* start new MPEG-1 context decoding */ - s->out_format = FMT_MPEG1; - if (s1->mpeg_enc_ctx_allocated) { - MPV_common_end(s); - } - s->width = avctx->coded_width; - s->height = avctx->coded_height; - avctx->has_b_frames= 0; //true? - s->low_delay= 1; - - avctx->pix_fmt = mpeg_get_pixelformat(avctx); - avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); - - if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ) - if( avctx->idct_algo == FF_IDCT_AUTO ) - avctx->idct_algo = FF_IDCT_SIMPLE; - - if (MPV_common_init(s) < 0) - return -1; - exchange_uv(s);//common init reset pblocks, so we swap them here - s->swap_uv = 1;// in case of xvmc we need to swap uv for each MB - s1->mpeg_enc_ctx_allocated = 1; - - for(i=0;i<64;i++) { - int j= s->dsp.idct_permutation[i]; - v = ff_mpeg1_default_intra_matrix[i]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - - v = ff_mpeg1_default_non_intra_matrix[i]; - s->inter_matrix[j] = v; - s->chroma_inter_matrix[j] = v; - } - - s->progressive_sequence = 1; - s->progressive_frame = 1; - s->picture_structure = PICT_FRAME; - s->frame_pred_frame_dct = 1; - s->chroma_format = 1; - s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO; - avctx->sub_id = 2; /* indicates MPEG-2 */ - s1->save_width = s->width; - s1->save_height = s->height; - s1->save_progressive_seq = s->progressive_sequence; - return 0; -} - - -static void mpeg_decode_user_data(AVCodecContext *avctx, - const uint8_t *p, int buf_size) -{ - const uint8_t *buf_end = p+buf_size; - - /* we parse the DTG active format information */ - if (buf_end - p >= 5 && - p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') { - int flags = p[4]; - p += 5; - if (flags & 0x80) { - /* skip event id */ - p += 2; - } - if (flags & 0x40) { - if (buf_end - p < 1) - return; - avctx->dtg_active_format = p[0] & 0x0f; - } - } -} - -static void mpeg_decode_gop(AVCodecContext *avctx, - const uint8_t *buf, int buf_size){ - Mpeg1Context *s1 = avctx->priv_data; - MpegEncContext *s = &s1->mpeg_enc_ctx; - - int drop_frame_flag; - int time_code_hours, time_code_minutes; - int time_code_seconds, time_code_pictures; - int broken_link; - - init_get_bits(&s->gb, buf, buf_size*8); - - drop_frame_flag = get_bits1(&s->gb); - - time_code_hours=get_bits(&s->gb,5); - time_code_minutes = get_bits(&s->gb,6); - skip_bits1(&s->gb);//marker bit - time_code_seconds = get_bits(&s->gb,6); - time_code_pictures = get_bits(&s->gb,6); - - s->closed_gop = get_bits1(&s->gb); - /*broken_link indicate that after editing the - reference frames of the first B-Frames after GOP I-Frame - are missing (open gop)*/ - broken_link = get_bits1(&s->gb); - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "GOP (%2d:%02d:%02d.[%02d]) closed_gop=%d broken_link=%d\n", - time_code_hours, time_code_minutes, time_code_seconds, - time_code_pictures, s->closed_gop, broken_link); -} -/** - * 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_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s) -{ - int i; - uint32_t state= pc->state; - - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - -/* - 0 frame start -> 1/4 - 1 first_SEQEXT -> 0/2 - 2 first field start -> 3/0 - 3 second_SEQEXT -> 2/0 - 4 searching end -*/ - - for(i=0; iframe_start_found>=0 && pc->frame_start_found<=4); - if(pc->frame_start_found&1){ - if(state == EXT_START_CODE && (buf[i]&0xF0) != 0x80) - pc->frame_start_found--; - else if(state == EXT_START_CODE+2){ - if((buf[i]&3) == 3) pc->frame_start_found= 0; - else pc->frame_start_found= (pc->frame_start_found+1)&3; - } - state++; - }else{ - i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1; - if(pc->frame_start_found==0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ - i++; - pc->frame_start_found=4; - } - if(state == SEQ_END_CODE){ - pc->state=-1; - return i+1; - } - if(pc->frame_start_found==2 && state == SEQ_START_CODE) - pc->frame_start_found= 0; - if(pc->frame_start_found<4 && state == EXT_START_CODE) - pc->frame_start_found++; - if(pc->frame_start_found == 4 && (state&0xFFFFFF00) == 0x100){ - if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){ - pc->frame_start_found=0; - pc->state=-1; - return i-3; - } - } - if(pc->frame_start_found == 0 && s && state == PICTURE_START_CODE){ - ff_fetch_timestamp(s, i-3, 1); - } - } - } - pc->state= state; - return END_NOT_FOUND; -} - -static int decode_chunks(AVCodecContext *avctx, - AVFrame *picture, int *data_size, - const uint8_t *buf, int buf_size); - -/* handle buffering and image synchronisation */ -static int mpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - Mpeg1Context *s = avctx->priv_data; - AVFrame *picture = data; - MpegEncContext *s2 = &s->mpeg_enc_ctx; - dprintf(avctx, "fill_buffer\n"); - - if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) { - /* special case for last picture */ - if (s2->low_delay==0 && s2->next_picture_ptr) { - *picture= *(AVFrame*)s2->next_picture_ptr; - s2->next_picture_ptr= NULL; - - *data_size = sizeof(AVFrame); - } - return buf_size; - } - - if(s2->flags&CODEC_FLAG_TRUNCATED){ - int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL); - - if( ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 ) - return buf_size; - } - -#if 0 - if (s->repeat_field % 2 == 1) { - s->repeat_field++; - //fprintf(stderr,"\nRepeating last frame: %d -> %d! pict: %d %d", avctx->frame_number-1, avctx->frame_number, - // s2->picture_number, s->repeat_field); - if (avctx->flags & CODEC_FLAG_REPEAT_FIELD) { - *data_size = sizeof(AVPicture); - goto the_end; - } - } -#endif - - if(s->mpeg_enc_ctx_allocated==0 && avctx->codec_tag == AV_RL32("VCR2")) - vcr2_init_sequence(avctx); - - s->slice_count= 0; - - if(avctx->extradata && !avctx->frame_number) - decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size); - - return decode_chunks(avctx, picture, data_size, buf, buf_size); -} - -static int decode_chunks(AVCodecContext *avctx, - AVFrame *picture, int *data_size, - const uint8_t *buf, int buf_size) -{ - Mpeg1Context *s = avctx->priv_data; - MpegEncContext *s2 = &s->mpeg_enc_ctx; - const uint8_t *buf_ptr = buf; - const uint8_t *buf_end = buf + buf_size; - int ret, input_size; - int last_code= 0; - - for(;;) { - /* find next start code */ - uint32_t start_code = -1; - buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code); - if (start_code > 0x1ff){ - if(s2->pict_type != FF_B_TYPE || avctx->skip_frame <= AVDISCARD_DEFAULT){ - if(avctx->thread_count > 1){ - int i; - - avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*)); - for(i=0; islice_count; i++) - s2->error_count += s2->thread_context[i]->error_count; - } - - if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); - - if (slice_end(avctx, picture)) { - if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice - *data_size = sizeof(AVPicture); - } - } - s2->pict_type= 0; - return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index); - } - - input_size = buf_end - buf_ptr; - - if(avctx->debug & FF_DEBUG_STARTCODE){ - av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size); - } - - /* prepare data for next start code */ - switch(start_code) { - case SEQ_START_CODE: - if(last_code == 0){ - mpeg1_decode_sequence(avctx, buf_ptr, - input_size); - s->sync=1; - }else{ - av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code); - } - break; - - case PICTURE_START_CODE: - if(last_code == 0 || last_code == SLICE_MIN_START_CODE){ - if(mpeg_decode_postinit(avctx) < 0){ - av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n"); - return -1; - } - - /* we have a complete image: we try to decompress it */ - if(mpeg1_decode_picture(avctx, - buf_ptr, input_size) < 0) - s2->pict_type=0; - s2->first_slice = 1; - last_code= PICTURE_START_CODE; - }else{ - av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code); - } - break; - case EXT_START_CODE: - init_get_bits(&s2->gb, buf_ptr, input_size*8); - - switch(get_bits(&s2->gb, 4)) { - case 0x1: - if(last_code == 0){ - mpeg_decode_sequence_extension(s); - }else{ - av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code); - } - break; - case 0x2: - mpeg_decode_sequence_display_extension(s); - break; - case 0x3: - mpeg_decode_quant_matrix_extension(s2); - break; - case 0x7: - mpeg_decode_picture_display_extension(s); - break; - case 0x8: - if(last_code == PICTURE_START_CODE){ - mpeg_decode_picture_coding_extension(s); - }else{ - av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code); - } - break; - } - break; - case USER_START_CODE: - mpeg_decode_user_data(avctx, - buf_ptr, input_size); - break; - case GOP_START_CODE: - if(last_code == 0){ - s2->first_field=0; - mpeg_decode_gop(avctx, - buf_ptr, input_size); - s->sync=1; - }else{ - av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code); - } - break; - default: - if (start_code >= SLICE_MIN_START_CODE && - start_code <= SLICE_MAX_START_CODE && last_code!=0) { - const int field_pic= s2->picture_structure != PICT_FRAME; - int mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic; - last_code= SLICE_MIN_START_CODE; - - if(s2->picture_structure == PICT_BOTTOM_FIELD) - mb_y++; - - if (mb_y >= s2->mb_height){ - av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height); - return -1; - } - - if(s2->last_picture_ptr==NULL){ - /* Skip B-frames if we do not have reference frames and gop is not closed */ - if(s2->pict_type==FF_B_TYPE){ - if(!s2->closed_gop) - break; - } - } - if(s2->pict_type==FF_I_TYPE) - s->sync=1; - if(s2->next_picture_ptr==NULL){ - /* Skip P-frames if we do not have a reference frame or we have an invalid header. */ - if(s2->pict_type==FF_P_TYPE && !s->sync) break; - } - /* Skip B-frames if we are in a hurry. */ - if(avctx->hurry_up && s2->pict_type==FF_B_TYPE) break; - if( (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==FF_B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=FF_I_TYPE) - || avctx->skip_frame >= AVDISCARD_ALL) - break; - /* Skip everything if we are in a hurry>=5. */ - if(avctx->hurry_up>=5) break; - - if (!s->mpeg_enc_ctx_allocated) break; - - if(s2->codec_id == CODEC_ID_MPEG2VIDEO){ - if(mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom) - break; - } - - if(!s2->pict_type){ - av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n"); - break; - } - - if(s2->first_slice){ - s2->first_slice=0; - if(mpeg_field_start(s2, buf, buf_size) < 0) - return -1; - } - if(!s2->current_picture_ptr){ - av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n"); - return -1; - } - - if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) { - s->slice_count++; - break; - } - - if(avctx->thread_count > 1){ - int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count; - if(threshold <= mb_y){ - MpegEncContext *thread_context= s2->thread_context[s->slice_count]; - - thread_context->start_mb_y= mb_y; - thread_context->end_mb_y = s2->mb_height; - if(s->slice_count){ - s2->thread_context[s->slice_count-1]->end_mb_y= mb_y; - ff_update_duplicate_context(thread_context, s2); - } - init_get_bits(&thread_context->gb, buf_ptr, input_size*8); - s->slice_count++; - } - buf_ptr += 2; //FIXME add minimum number of bytes per slice - }else{ - ret = mpeg_decode_slice(s, mb_y, &buf_ptr, input_size); - emms_c(); - - if(ret < 0){ - if(s2->resync_mb_x>=0 && s2->resync_mb_y>=0) - ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, AC_ERROR|DC_ERROR|MV_ERROR); - }else{ - ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, AC_END|DC_END|MV_END); - } - } - } - break; - } - } -} - -static void flush(AVCodecContext *avctx){ - Mpeg1Context *s = avctx->priv_data; - - s->sync=0; - - ff_mpeg_flush(avctx); -} - -static int mpeg_decode_end(AVCodecContext *avctx) -{ - Mpeg1Context *s = avctx->priv_data; - - if (s->mpeg_enc_ctx_allocated) - MPV_common_end(&s->mpeg_enc_ctx); - return 0; -} - -AVCodec mpeg1video_decoder = { - "mpeg1video", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG1VIDEO, - sizeof(Mpeg1Context), - mpeg_decode_init, - NULL, - mpeg_decode_end, - mpeg_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), -}; - -AVCodec mpeg2video_decoder = { - "mpeg2video", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG2VIDEO, - sizeof(Mpeg1Context), - mpeg_decode_init, - NULL, - mpeg_decode_end, - mpeg_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"), -}; - -//legacy decoder -AVCodec mpegvideo_decoder = { - "mpegvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG2VIDEO, - sizeof(Mpeg1Context), - mpeg_decode_init, - NULL, - mpeg_decode_end, - mpeg_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), -}; - -#if CONFIG_MPEG_XVMC_DECODER -static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){ - if( avctx->thread_count > 1) - return -1; - if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) ) - return -1; - if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) ){ - dprintf(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n"); - } - mpeg_decode_init(avctx); - - avctx->pix_fmt = PIX_FMT_XVMC_MPEG2_IDCT; - avctx->xvmc_acceleration = 2;//2 - the blocks are packed! - - return 0; -} - -AVCodec mpeg_xvmc_decoder = { - "mpegvideo_xvmc", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG2VIDEO_XVMC, - sizeof(Mpeg1Context), - mpeg_mc_decode_init, - NULL, - mpeg_decode_end, - mpeg_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY, - .flush= flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"), -}; - -#endif - -#if CONFIG_MPEG_VDPAU_DECODER -AVCodec mpeg_vdpau_decoder = { - "mpegvideo_vdpau", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG2VIDEO, - sizeof(Mpeg1Context), - mpeg_decode_init, - NULL, - mpeg_decode_end, - mpeg_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY, - .flush= flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"), -}; -#endif - -#if CONFIG_MPEG1_VDPAU_DECODER -AVCodec mpeg1_vdpau_decoder = { - "mpeg1video_vdpau", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG1VIDEO, - sizeof(Mpeg1Context), - mpeg_decode_init, - NULL, - mpeg_decode_end, - mpeg_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY, - .flush= flush, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"), -}; -#endif - diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg12.h b/tizen/distrib/ffmpeg/libavcodec/mpeg12.h deleted file mode 100644 index 30bb675..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg12.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * MPEG1/2 common code - * Copyright (c) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPEG12_H -#define AVCODEC_MPEG12_H - -#include "mpegvideo.h" - -#define DC_VLC_BITS 9 -#define TEX_VLC_BITS 9 - -static VLC dc_lum_vlc; -static VLC dc_chroma_vlc; - -extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; - -void ff_mpeg12_common_init(MpegEncContext *s); -void ff_mpeg12_init_vlcs(void); - -static inline int decode_dc(GetBitContext *gb, int component) -{ - int code, diff; - - if (component == 0) { - code = get_vlc2(gb, dc_lum_vlc.table, DC_VLC_BITS, 2); - } else { - code = get_vlc2(gb, dc_chroma_vlc.table, DC_VLC_BITS, 2); - } - if (code < 0){ - av_log(NULL, AV_LOG_ERROR, "invalid dc code at\n"); - return 0xffff; - } - if (code == 0) { - diff = 0; - } else { - diff = get_xbits(gb, code); - } - return diff; -} - -extern int ff_mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n); - -#endif /* AVCODEC_MPEG12_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg12data.c b/tizen/distrib/ffmpeg/libavcodec/mpeg12data.c deleted file mode 100644 index 8b1f563..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg12data.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * MPEG1/2 tables - * copyright (c) 2000,2001 Fabrice Bellard - * copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG1/2 tables. - */ - -#include "mpeg12data.h" - -const uint16_t ff_mpeg1_default_intra_matrix[64] = { - 8, 16, 19, 22, 26, 27, 29, 34, - 16, 16, 22, 24, 27, 29, 34, 37, - 19, 22, 26, 27, 29, 34, 34, 38, - 22, 22, 26, 27, 29, 34, 37, 40, - 22, 26, 27, 29, 32, 35, 40, 48, - 26, 27, 29, 32, 35, 40, 48, 58, - 26, 27, 29, 34, 38, 46, 56, 69, - 27, 29, 35, 38, 46, 56, 69, 83 -}; - -const uint16_t ff_mpeg1_default_non_intra_matrix[64] = { - 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, -}; - -const uint16_t ff_mpeg12_vlc_dc_lum_code[12] = { - 0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff, -}; -const unsigned char ff_mpeg12_vlc_dc_lum_bits[12] = { - 3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9, -}; - -const uint16_t ff_mpeg12_vlc_dc_chroma_code[12] = { - 0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff, -}; -const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12] = { - 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, -}; - -static const uint16_t mpeg1_vlc[113][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 }, { 0x1f, 14 }, - { 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 }, - { 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 }, - { 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 }, - { 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 }, - { 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 }, - { 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 }, - { 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 }, - { 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 }, - { 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 }, - { 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 }, - { 0x11, 16 }, { 0x10, 16 }, { 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 }, { 0x14, 16 }, - { 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 }, - { 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 }, - { 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 }, - { 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 }, - { 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 }, - { 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 }, - { 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 }, - { 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 }, - { 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 }, - { 0x1, 6 }, /* escape */ - { 0x2, 2 }, /* EOB */ -}; - -static const uint16_t mpeg2_vlc[113][2] = { - {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5}, - {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7}, - {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8}, - {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14}, - {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14}, - {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14}, - {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14}, - {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15}, - {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15}, - {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15}, - {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8}, - {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15}, - {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15}, - {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16}, - {0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7}, - {0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5}, - {0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6}, - {0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9}, - {0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16}, - {0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12}, - {0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13}, - {0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16}, - {0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16}, - {0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16}, - {0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12}, - {0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13}, - {0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16}, - {0x1d,16}, {0x1c,16}, {0x1b,16}, - {0x01,6}, /* escape */ - {0x06,4}, /* EOB */ -}; - -static const int8_t mpeg1_level[111] = { - 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, - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 1, 2, 3, 4, 5, 1, - 2, 3, 4, 1, 2, 3, 1, 2, - 3, 1, 2, 3, 1, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 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, -}; - -static const int8_t mpeg1_run[111] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 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, 2, 2, 2, 2, 2, 3, - 3, 3, 3, 4, 4, 4, 5, 5, - 5, 6, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, - 13, 13, 14, 14, 15, 15, 16, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, -}; - -RLTable ff_rl_mpeg1 = { - 111, - 111, - mpeg1_vlc, - mpeg1_run, - mpeg1_level, -}; - -RLTable ff_rl_mpeg2 = { - 111, - 111, - mpeg2_vlc, - mpeg1_run, - mpeg1_level, -}; - -const uint8_t ff_mpeg12_mbAddrIncrTable[36][2] = { - {0x1, 1}, - {0x3, 3}, - {0x2, 3}, - {0x3, 4}, - {0x2, 4}, - {0x3, 5}, - {0x2, 5}, - {0x7, 7}, - {0x6, 7}, - {0xb, 8}, - {0xa, 8}, - {0x9, 8}, - {0x8, 8}, - {0x7, 8}, - {0x6, 8}, - {0x17, 10}, - {0x16, 10}, - {0x15, 10}, - {0x14, 10}, - {0x13, 10}, - {0x12, 10}, - {0x23, 11}, - {0x22, 11}, - {0x21, 11}, - {0x20, 11}, - {0x1f, 11}, - {0x1e, 11}, - {0x1d, 11}, - {0x1c, 11}, - {0x1b, 11}, - {0x1a, 11}, - {0x19, 11}, - {0x18, 11}, - {0x8, 11}, /* escape */ - {0xf, 11}, /* stuffing */ - {0x0, 8}, /* end (and 15 more 0 bits should follow) */ -}; - -const uint8_t ff_mpeg12_mbPatTable[64][2] = { - {0x1, 9}, - {0xb, 5}, - {0x9, 5}, - {0xd, 6}, - {0xd, 4}, - {0x17, 7}, - {0x13, 7}, - {0x1f, 8}, - {0xc, 4}, - {0x16, 7}, - {0x12, 7}, - {0x1e, 8}, - {0x13, 5}, - {0x1b, 8}, - {0x17, 8}, - {0x13, 8}, - {0xb, 4}, - {0x15, 7}, - {0x11, 7}, - {0x1d, 8}, - {0x11, 5}, - {0x19, 8}, - {0x15, 8}, - {0x11, 8}, - {0xf, 6}, - {0xf, 8}, - {0xd, 8}, - {0x3, 9}, - {0xf, 5}, - {0xb, 8}, - {0x7, 8}, - {0x7, 9}, - {0xa, 4}, - {0x14, 7}, - {0x10, 7}, - {0x1c, 8}, - {0xe, 6}, - {0xe, 8}, - {0xc, 8}, - {0x2, 9}, - {0x10, 5}, - {0x18, 8}, - {0x14, 8}, - {0x10, 8}, - {0xe, 5}, - {0xa, 8}, - {0x6, 8}, - {0x6, 9}, - {0x12, 5}, - {0x1a, 8}, - {0x16, 8}, - {0x12, 8}, - {0xd, 5}, - {0x9, 8}, - {0x5, 8}, - {0x5, 9}, - {0xc, 5}, - {0x8, 8}, - {0x4, 8}, - {0x4, 9}, - {0x7, 3}, - {0xa, 5}, - {0x8, 5}, - {0xc, 6} -}; - -const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = { -{ 0x1, 1 }, -{ 0x1, 2 }, -{ 0x1, 3 }, -{ 0x1, 4 }, -{ 0x3, 6 }, -{ 0x5, 7 }, -{ 0x4, 7 }, -{ 0x3, 7 }, -{ 0xb, 9 }, -{ 0xa, 9 }, -{ 0x9, 9 }, -{ 0x11, 10 }, -{ 0x10, 10 }, -{ 0xf, 10 }, -{ 0xe, 10 }, -{ 0xd, 10 }, -{ 0xc, 10 }, -}; - -const AVRational ff_frame_rate_tab[] = { - { 0, 0}, - {24000, 1001}, - { 24, 1}, - { 25, 1}, - {30000, 1001}, - { 30, 1}, - { 50, 1}, - {60000, 1001}, - { 60, 1}, - // Xing's 15fps: (9) - { 15, 1}, - // libmpeg3's "Unofficial economy rates": (10-13) - { 5, 1}, - { 10, 1}, - { 12, 1}, - { 15, 1}, - { 0, 0}, -}; - -const float ff_mpeg1_aspect[16]={ - 0.0000, - 1.0000, - 0.6735, - 0.7031, - - 0.7615, - 0.8055, - 0.8437, - 0.8935, - - 0.9157, - 0.9815, - 1.0255, - 1.0695, - - 1.0950, - 1.1575, - 1.2015, -}; - -const AVRational ff_mpeg2_aspect[16]={ - {0,1}, - {1,1}, - {4,3}, - {16,9}, - {221,100}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg12data.h b/tizen/distrib/ffmpeg/libavcodec/mpeg12data.h deleted file mode 100644 index 9695e9d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg12data.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * MPEG1/2 tables - * copyright (c) 2000,2001 Fabrice Bellard - * copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG1/2 tables. - */ - -#ifndef AVCODEC_MPEG12DATA_H -#define AVCODEC_MPEG12DATA_H - -#include -#include "libavutil/rational.h" -#include "rl.h" - -extern const uint16_t ff_mpeg1_default_intra_matrix[64]; -extern const uint16_t ff_mpeg1_default_non_intra_matrix[64]; - -extern const uint16_t ff_mpeg12_vlc_dc_lum_code[12]; -extern const unsigned char ff_mpeg12_vlc_dc_lum_bits[12]; -extern const uint16_t ff_mpeg12_vlc_dc_chroma_code[12]; -extern const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12]; - -extern RLTable ff_rl_mpeg1; -extern RLTable ff_rl_mpeg2; - -extern const uint8_t ff_mpeg12_mbAddrIncrTable[36][2]; -extern const uint8_t ff_mpeg12_mbPatTable[64][2]; - -extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2]; - -extern const AVRational ff_frame_rate_tab[]; - -extern const float ff_mpeg1_aspect[16]; -extern const AVRational ff_mpeg2_aspect[16]; - -#endif /* AVCODEC_MPEG12DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg12decdata.h b/tizen/distrib/ffmpeg/libavcodec/mpeg12decdata.h deleted file mode 100644 index 66ca5c4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg12decdata.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * MPEG1/2 decoder tables - * copyright (c) 2000,2001 Fabrice Bellard - * copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG1/2 decoder tables. - */ - -#ifndef AVCODEC_MPEG12DECDATA_H -#define AVCODEC_MPEG12DECDATA_H - -#include -#include "mpegvideo.h" - - -#define MB_TYPE_ZERO_MV 0x20000000 -#define IS_ZERO_MV(a) ((a)&MB_TYPE_ZERO_MV) - -static const uint8_t table_mb_ptype[7][2] = { - { 3, 5 }, // 0x01 MB_INTRA - { 1, 2 }, // 0x02 MB_PAT - { 1, 3 }, // 0x08 MB_FOR - { 1, 1 }, // 0x0A MB_FOR|MB_PAT - { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA - { 1, 5 }, // 0x12 MB_QUANT|MB_PAT - { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT -}; - -static const uint32_t ptype2mb_type[7] = { - MB_TYPE_INTRA, - MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, - MB_TYPE_L0, - MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_INTRA, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, -}; - -static const uint8_t table_mb_btype[11][2] = { - { 3, 5 }, // 0x01 MB_INTRA - { 2, 3 }, // 0x04 MB_BACK - { 3, 3 }, // 0x06 MB_BACK|MB_PAT - { 2, 4 }, // 0x08 MB_FOR - { 3, 4 }, // 0x0A MB_FOR|MB_PAT - { 2, 2 }, // 0x0C MB_FOR|MB_BACK - { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT - { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA - { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT - { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT - { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT -}; - -static const uint32_t btype2mb_type[11] = { - MB_TYPE_INTRA, - MB_TYPE_L1, - MB_TYPE_L1 | MB_TYPE_CBP, - MB_TYPE_L0, - MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_L0L1, - MB_TYPE_L0L1 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_INTRA, - MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP, -}; - -static const uint8_t non_linear_qscale[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8,10,12,14,16,18,20,22, - 24,28,32,36,40,44,48,52, - 56,64,72,80,88,96,104,112, -}; - -#endif /* AVCODEC_MPEG12DECDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg12enc.c b/tizen/distrib/ffmpeg/libavcodec/mpeg12enc.c deleted file mode 100644 index bf36129..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg12enc.c +++ /dev/null @@ -1,959 +0,0 @@ -/* - * MPEG1/2 encoder - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG1/2 encoder - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - -#include "mpeg12.h" -#include "mpeg12data.h" -#include "bytestream.h" - - -static const uint8_t inv_non_linear_qscale[13] = { - 0, 2, 4, 6, 8, - 9,10,11,12,13,14,15,16, -}; - -static const uint8_t svcd_scan_offset_placeholder[14] = { - 0x10, 0x0E, - 0x00, 0x80, 0x81, - 0x00, 0x80, 0x81, - 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, -}; - -static void mpeg1_encode_block(MpegEncContext *s, - DCTELEM *block, - int component); -static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added - -static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; -static uint8_t fcode_tab[MAX_MV*2+1]; - -static uint8_t uni_mpeg1_ac_vlc_len [64*64*2]; -static uint8_t uni_mpeg2_ac_vlc_len [64*64*2]; - -/* simple include everything table for dc, first byte is bits number next 3 are code*/ -static uint32_t mpeg1_lum_dc_uni[512]; -static uint32_t mpeg1_chr_dc_uni[512]; - -static uint8_t mpeg1_index_run[2][64]; -static int8_t mpeg1_max_level[2][64]; - -static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){ - int i; - - for(i=0; i<128; i++){ - int level= i-64; - int run; - for(run=0; run<64; run++){ - int len, bits, code; - - int alevel= FFABS(level); - int sign= (level>>31)&1; - - if (alevel > rl->max_level[0][run]) - code= 111; /*rl->n*/ - else - code= rl->index_run[0][run] + alevel - 1; - - if (code < 111 /* rl->n */) { - /* store the vlc & sign at once */ - len= rl->table_vlc[code][1]+1; - bits= (rl->table_vlc[code][0]<<1) + sign; - } else { - len= rl->table_vlc[111/*rl->n*/][1]+6; - bits= rl->table_vlc[111/*rl->n*/][0]<<6; - - bits|= run; - if (alevel < 128) { - bits<<=8; len+=8; - bits|= level & 0xff; - } else { - bits<<=16; len+=16; - bits|= level & 0xff; - if (level < 0) { - bits|= 0x8001 + level + 255; - } else { - bits|= level & 0xffff; - } - } - } - - uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len; - } - } -} - - -static int find_frame_rate_index(MpegEncContext *s){ - int i; - int64_t dmin= INT64_MAX; - int64_t d; - - for(i=1;i<14;i++) { - int64_t n0= 1001LL/ff_frame_rate_tab[i].den*ff_frame_rate_tab[i].num*s->avctx->time_base.num; - int64_t n1= 1001LL*s->avctx->time_base.den; - if(s->avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL && i>=9) break; - - d = FFABS(n0 - n1); - if(d < dmin){ - dmin=d; - s->frame_rate_index= i; - } - } - if(dmin) - return -1; - else - return 0; -} - -static av_cold int encode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - - if(MPV_encode_init(avctx) < 0) - return -1; - - if(find_frame_rate_index(s) < 0){ - if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num); - return -1; - }else{ - av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->time_base.den, avctx->time_base.num); - } - } - - if(avctx->profile == FF_PROFILE_UNKNOWN){ - if(avctx->level != FF_LEVEL_UNKNOWN){ - av_log(avctx, AV_LOG_ERROR, "Set profile and level\n"); - return -1; - } - avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; /* Main or 4:2:2 */ - } - - if(avctx->level == FF_LEVEL_UNKNOWN){ - if(avctx->profile == 0){ /* 4:2:2 */ - if(avctx->width <= 720 && avctx->height <= 608) avctx->level = 5; /* Main */ - else avctx->level = 2; /* High */ - }else{ - if(avctx->profile != 1 && s->chroma_format != CHROMA_420){ - av_log(avctx, AV_LOG_ERROR, "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n"); - return -1; - } - if(avctx->width <= 720 && avctx->height <= 576) avctx->level = 8; /* Main */ - else if(avctx->width <= 1440) avctx->level = 6; /* High 1440 */ - else avctx->level = 4; /* High */ - } - } - - if((avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) && s->frame_rate_index != 4){ - av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n"); - return -1; - } - - return 0; -} - -static void put_header(MpegEncContext *s, int header) -{ - align_put_bits(&s->pb); - put_bits(&s->pb, 16, header>>16); - put_sbits(&s->pb, 16, header); -} - -/* put sequence header if needed */ -static void mpeg1_encode_sequence_header(MpegEncContext *s) -{ - unsigned int vbv_buffer_size; - unsigned int fps, v; - int i; - uint64_t time_code; - float best_aspect_error= 1E10; - float aspect_ratio= av_q2d(s->avctx->sample_aspect_ratio); - int constraint_parameter_flag; - - if(aspect_ratio==0.0) aspect_ratio= 1.0; //pixel aspect 1:1 (VGA) - - if (s->current_picture.key_frame) { - AVRational framerate= ff_frame_rate_tab[s->frame_rate_index]; - - /* mpeg1 header repeated every gop */ - put_header(s, SEQ_START_CODE); - - put_sbits(&s->pb, 12, s->width ); - put_sbits(&s->pb, 12, s->height); - - for(i=1; i<15; i++){ - float error= aspect_ratio; - if(s->codec_id == CODEC_ID_MPEG1VIDEO || i <=1) - error-= 1.0/ff_mpeg1_aspect[i]; - else - error-= av_q2d(ff_mpeg2_aspect[i])*s->height/s->width; - - error= FFABS(error); - - if(error < best_aspect_error){ - best_aspect_error= error; - s->aspect_ratio_info= i; - } - } - - put_bits(&s->pb, 4, s->aspect_ratio_info); - put_bits(&s->pb, 4, s->frame_rate_index); - - if(s->avctx->rc_max_rate){ - v = (s->avctx->rc_max_rate + 399) / 400; - if (v > 0x3ffff && s->codec_id == CODEC_ID_MPEG1VIDEO) - v = 0x3ffff; - }else{ - v= 0x3FFFF; - } - - if(s->avctx->rc_buffer_size) - vbv_buffer_size = s->avctx->rc_buffer_size; - else - /* VBV calculation: Scaled so that a VCD has the proper VBV size of 40 kilobytes */ - vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024; - vbv_buffer_size= (vbv_buffer_size + 16383) / 16384; - - put_sbits(&s->pb, 18, v); - put_bits(&s->pb, 1, 1); /* marker */ - put_sbits(&s->pb, 10, vbv_buffer_size); - - constraint_parameter_flag= - s->width <= 768 && s->height <= 576 && - s->mb_width * s->mb_height <= 396 && - s->mb_width * s->mb_height * framerate.num <= framerate.den*396*25 && - framerate.num <= framerate.den*30 && - s->avctx->me_range && s->avctx->me_range < 128 && - vbv_buffer_size <= 20 && - v <= 1856000/400 && - s->codec_id == CODEC_ID_MPEG1VIDEO; - - put_bits(&s->pb, 1, constraint_parameter_flag); - - ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); - ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); - - if(s->codec_id == CODEC_ID_MPEG2VIDEO){ - put_header(s, EXT_START_CODE); - put_bits(&s->pb, 4, 1); //seq ext - - put_bits(&s->pb, 1, s->avctx->profile == 0); //escx 1 for 4:2:2 profile */ - - put_bits(&s->pb, 3, s->avctx->profile); //profile - put_bits(&s->pb, 4, s->avctx->level); //level - - put_bits(&s->pb, 1, s->progressive_sequence); - put_bits(&s->pb, 2, s->chroma_format); - put_bits(&s->pb, 2, s->width >>12); - put_bits(&s->pb, 2, s->height>>12); - put_bits(&s->pb, 12, v>>18); //bitrate ext - put_bits(&s->pb, 1, 1); //marker - put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext - put_bits(&s->pb, 1, s->low_delay); - put_bits(&s->pb, 2, 0); // frame_rate_ext_n - put_bits(&s->pb, 5, 0); // frame_rate_ext_d - } - - put_header(s, GOP_START_CODE); - put_bits(&s->pb, 1, !!(s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)); /* drop frame flag */ - /* time code : we must convert from the real frame rate to a - fake mpeg frame rate in case of low frame rate */ - fps = (framerate.num + framerate.den/2)/ framerate.den; - time_code = s->current_picture_ptr->coded_picture_number + s->avctx->timecode_frame_start; - - s->gop_picture_number = s->current_picture_ptr->coded_picture_number; - if (s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) { - /* only works for NTSC 29.97 */ - int d = time_code / 17982; - int m = time_code % 17982; - //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */ - time_code += 18 * d + 2 * ((m - 2) / 1798); - } - put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); - put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); - put_bits(&s->pb, 6, (uint32_t)((time_code % fps))); - put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP)); - put_bits(&s->pb, 1, 0); /* broken link */ - } -} - -static inline void encode_mb_skip_run(MpegEncContext *s, int run){ - while (run >= 33) { - put_bits(&s->pb, 11, 0x008); - run -= 33; - } - put_bits(&s->pb, ff_mpeg12_mbAddrIncrTable[run][1], - ff_mpeg12_mbAddrIncrTable[run][0]); -} - -static av_always_inline void put_qscale(MpegEncContext *s) -{ - if(s->q_scale_type){ - assert(s->qscale>=1 && s->qscale <=12); - put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]); - }else{ - put_bits(&s->pb, 5, s->qscale); - } -} - -void ff_mpeg1_encode_slice_header(MpegEncContext *s){ - if (s->height > 2800) { - put_header(s, SLICE_MIN_START_CODE + (s->mb_y & 127)); - put_bits(&s->pb, 3, s->mb_y >> 7); /* slice_vertical_position_extension */ - } else { - put_header(s, SLICE_MIN_START_CODE + s->mb_y); - } - put_qscale(s); - put_bits(&s->pb, 1, 0); /* slice extra information */ -} - -void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) -{ - mpeg1_encode_sequence_header(s); - - /* mpeg1 picture header */ - put_header(s, PICTURE_START_CODE); - /* temporal reference */ - - // RAL: s->picture_number instead of s->fake_picture_number - put_bits(&s->pb, 10, (s->picture_number - - s->gop_picture_number) & 0x3ff); - put_bits(&s->pb, 3, s->pict_type); - - s->vbv_delay_ptr= s->pb.buf + put_bits_count(&s->pb)/8; - put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */ - - // RAL: Forward f_code also needed for B frames - if (s->pict_type == FF_P_TYPE || s->pict_type == FF_B_TYPE) { - put_bits(&s->pb, 1, 0); /* half pel coordinates */ - if(s->codec_id == CODEC_ID_MPEG1VIDEO) - put_bits(&s->pb, 3, s->f_code); /* forward_f_code */ - else - put_bits(&s->pb, 3, 7); /* forward_f_code */ - } - - // RAL: Backward f_code necessary for B frames - if (s->pict_type == FF_B_TYPE) { - put_bits(&s->pb, 1, 0); /* half pel coordinates */ - if(s->codec_id == CODEC_ID_MPEG1VIDEO) - put_bits(&s->pb, 3, s->b_code); /* backward_f_code */ - else - put_bits(&s->pb, 3, 7); /* backward_f_code */ - } - - put_bits(&s->pb, 1, 0); /* extra bit picture */ - - s->frame_pred_frame_dct = 1; - if(s->codec_id == CODEC_ID_MPEG2VIDEO){ - put_header(s, EXT_START_CODE); - put_bits(&s->pb, 4, 8); //pic ext - if (s->pict_type == FF_P_TYPE || s->pict_type == FF_B_TYPE) { - put_bits(&s->pb, 4, s->f_code); - put_bits(&s->pb, 4, s->f_code); - }else{ - put_bits(&s->pb, 8, 255); - } - if (s->pict_type == FF_B_TYPE) { - put_bits(&s->pb, 4, s->b_code); - put_bits(&s->pb, 4, s->b_code); - }else{ - put_bits(&s->pb, 8, 255); - } - put_bits(&s->pb, 2, s->intra_dc_precision); - - assert(s->picture_structure == PICT_FRAME); - put_bits(&s->pb, 2, s->picture_structure); - if (s->progressive_sequence) { - put_bits(&s->pb, 1, 0); /* no repeat */ - } else { - put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first); - } - /* XXX: optimize the generation of this flag with entropy - measures */ - s->frame_pred_frame_dct = s->progressive_sequence; - - put_bits(&s->pb, 1, s->frame_pred_frame_dct); - put_bits(&s->pb, 1, s->concealment_motion_vectors); - put_bits(&s->pb, 1, s->q_scale_type); - put_bits(&s->pb, 1, s->intra_vlc_format); - put_bits(&s->pb, 1, s->alternate_scan); - put_bits(&s->pb, 1, s->repeat_first_field); - s->progressive_frame = s->progressive_sequence; - put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */ - put_bits(&s->pb, 1, s->progressive_frame); - put_bits(&s->pb, 1, 0); //composite_display_flag - } - if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){ - int i; - - put_header(s, USER_START_CODE); - for(i=0; ipb, 8, svcd_scan_offset_placeholder[i]); - } - } - - s->mb_y=0; - ff_mpeg1_encode_slice_header(s); -} - -static inline void put_mb_modes(MpegEncContext *s, int n, int bits, - int has_mv, int field_motion) -{ - put_bits(&s->pb, n, bits); - if (!s->frame_pred_frame_dct) { - if (has_mv) - put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */ - put_bits(&s->pb, 1, s->interlaced_dct); - } -} - -static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y, - int mb_block_count) -{ - int i, cbp; - const int mb_x = s->mb_x; - const int mb_y = s->mb_y; - const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y; - - /* compute cbp */ - cbp = 0; - for(i=0;iblock_last_index[i] >= 0) - cbp |= 1 << (mb_block_count - 1 - i); - } - - if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 && - (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && - ((s->pict_type == FF_P_TYPE && (motion_x | motion_y) == 0) || - (s->pict_type == FF_B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | - ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { - s->mb_skip_run++; - s->qscale -= s->dquant; - s->skip_count++; - s->misc_bits++; - s->last_bits++; - if(s->pict_type == FF_P_TYPE){ - s->last_mv[0][1][0]= s->last_mv[0][0][0]= - s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0; - } - } else { - if(first_mb){ - assert(s->mb_skip_run == 0); - encode_mb_skip_run(s, s->mb_x); - }else{ - encode_mb_skip_run(s, s->mb_skip_run); - } - - if (s->pict_type == FF_I_TYPE) { - if(s->dquant && cbp){ - put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */ - put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */ - s->qscale -= s->dquant; - } - s->misc_bits+= get_bits_diff(s); - s->i_count++; - } else if (s->mb_intra) { - if(s->dquant && cbp){ - put_mb_modes(s, 6, 0x01, 0, 0); - put_qscale(s); - }else{ - put_mb_modes(s, 5, 0x03, 0, 0); - s->qscale -= s->dquant; - } - s->misc_bits+= get_bits_diff(s); - s->i_count++; - memset(s->last_mv, 0, sizeof(s->last_mv)); - } else if (s->pict_type == FF_P_TYPE) { - if(s->mv_type == MV_TYPE_16X16){ - if (cbp != 0) { - if ((motion_x|motion_y) == 0) { - if(s->dquant){ - put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */ - put_qscale(s); - }else{ - put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */ - } - s->misc_bits+= get_bits_diff(s); - } else { - if(s->dquant){ - put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ - put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ - } - s->misc_bits+= get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added - s->mv_bits+= get_bits_diff(s); - } - } else { - put_bits(&s->pb, 3, 1); /* motion only */ - if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - s->misc_bits+= get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added - s->qscale -= s->dquant; - s->mv_bits+= get_bits_diff(s); - } - s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x; - s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y; - }else{ - assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD); - - if (cbp) { - if(s->dquant){ - put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ - put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ - } - } else { - put_bits(&s->pb, 3, 1); /* motion only */ - put_bits(&s->pb, 2, 1); /* motion_type: field */ - s->qscale -= s->dquant; - } - s->misc_bits+= get_bits_diff(s); - for(i=0; i<2; i++){ - put_bits(&s->pb, 1, s->field_select[0][i]); - mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); - mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0]; - s->last_mv[0][i][1]= 2*s->mv[0][i][1]; - } - s->mv_bits+= get_bits_diff(s); - } - if(cbp) { - if (s->chroma_y_shift) { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); - } else { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); - put_sbits(&s->pb, 2, cbp); - } - } - s->f_count++; - } else{ - if(s->mv_type == MV_TYPE_16X16){ - if (cbp){ // With coded bloc pattern - if (s->dquant) { - if(s->mv_dir == MV_DIR_FORWARD) - put_mb_modes(s, 6, 3, 1, 0); - else - put_mb_modes(s, 8-s->mv_dir, 2, 1, 0); - put_qscale(s); - } else { - put_mb_modes(s, 5-s->mv_dir, 3, 1, 0); - } - }else{ // No coded bloc pattern - put_bits(&s->pb, 5-s->mv_dir, 2); - if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - s->qscale -= s->dquant; - } - s->misc_bits += get_bits_diff(s); - if (s->mv_dir&MV_DIR_FORWARD){ - mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); - mpeg1_encode_motion(s, 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){ - mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); - mpeg1_encode_motion(s, 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{ - assert(s->mv_type == MV_TYPE_FIELD); - assert(!s->frame_pred_frame_dct); - if (cbp){ // With coded bloc pattern - if (s->dquant) { - if(s->mv_dir == MV_DIR_FORWARD) - put_mb_modes(s, 6, 3, 1, 1); - else - put_mb_modes(s, 8-s->mv_dir, 2, 1, 1); - put_qscale(s); - } else { - put_mb_modes(s, 5-s->mv_dir, 3, 1, 1); - } - }else{ // No coded bloc pattern - put_bits(&s->pb, 5-s->mv_dir, 2); - put_bits(&s->pb, 2, 1); /* motion_type: field */ - s->qscale -= s->dquant; - } - s->misc_bits += get_bits_diff(s); - if (s->mv_dir&MV_DIR_FORWARD){ - for(i=0; i<2; i++){ - put_bits(&s->pb, 1, s->field_select[0][i]); - mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); - mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0]; - s->last_mv[0][i][1]= 2*s->mv[0][i][1]; - } - s->f_count++; - } - if (s->mv_dir&MV_DIR_BACKWARD){ - for(i=0; i<2; i++){ - put_bits(&s->pb, 1, s->field_select[1][i]); - mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); - mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code); - s->last_mv[1][i][0]= s->mv[1][i][0]; - s->last_mv[1][i][1]= 2*s->mv[1][i][1]; - } - s->b_count++; - } - } - s->mv_bits += get_bits_diff(s); - if(cbp) { - if (s->chroma_y_shift) { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); - } else { - put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); - put_sbits(&s->pb, 2, cbp); - } - } - } - for(i=0;imb_skip_run = 0; - if(s->mb_intra) - s->i_tex_bits+= get_bits_diff(s); - else - s->p_tex_bits+= get_bits_diff(s); - } -} - -void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y) -{ - if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6); - else mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8); -} - -// RAL: Parameter added: f_or_b_code -static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) -{ - if (val == 0) { - /* zero vector */ - put_bits(&s->pb, - ff_mpeg12_mbMotionVectorTable[0][1], - ff_mpeg12_mbMotionVectorTable[0][0]); - } else { - int code, sign, bits; - int bit_size = f_or_b_code - 1; - int range = 1 << bit_size; - /* modulo encoding */ - int l= INT_BIT - 5 - bit_size; - val= (val<>l; - - if (val >= 0) { - val--; - code = (val >> bit_size) + 1; - bits = val & (range - 1); - sign = 0; - } else { - val = -val; - val--; - code = (val >> bit_size) + 1; - bits = val & (range - 1); - sign = 1; - } - - assert(code > 0 && code <= 16); - - put_bits(&s->pb, - ff_mpeg12_mbMotionVectorTable[code][1], - ff_mpeg12_mbMotionVectorTable[code][0]); - - put_bits(&s->pb, 1, sign); - if (bit_size > 0) { - put_bits(&s->pb, bit_size, bits); - } - } -} - -void ff_mpeg1_encode_init(MpegEncContext *s) -{ - static int done=0; - - ff_mpeg12_common_init(s); - - if(!done){ - int f_code; - int mv; - int i; - - done=1; - init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); - init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); - - for(i=0; i<64; i++) - { - mpeg1_max_level[0][i]= ff_rl_mpeg1.max_level[0][i]; - mpeg1_index_run[0][i]= ff_rl_mpeg1.index_run[0][i]; - } - - init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len); - if(s->intra_vlc_format) - init_uni_ac_vlc(&ff_rl_mpeg2, uni_mpeg2_ac_vlc_len); - - /* build unified dc encoding tables */ - for(i=-255; i<256; i++) - { - int adiff, index; - int bits, code; - int diff=i; - - adiff = FFABS(diff); - if(diff<0) diff--; - index = av_log2(2*adiff); - - bits= ff_mpeg12_vlc_dc_lum_bits[index] + index; - code= (ff_mpeg12_vlc_dc_lum_code[index]<> bit_size) + 1; - if(code<17){ - len= ff_mpeg12_mbMotionVectorTable[code][1] + 1 + bit_size; - }else{ - len= ff_mpeg12_mbMotionVectorTable[16][1] + 2 + bit_size; - } - } - - mv_penalty[f_code][mv+MAX_MV]= len; - } - } - - - for(f_code=MAX_FCODE; f_code>0; f_code--){ - for(mv=-(8<me.mv_penalty= mv_penalty; - s->fcode_tab= fcode_tab; - if(s->codec_id == CODEC_ID_MPEG1VIDEO){ - s->min_qcoeff=-255; - s->max_qcoeff= 255; - }else{ - s->min_qcoeff=-2047; - s->max_qcoeff= 2047; - } - if (s->intra_vlc_format) { - s->intra_ac_vlc_length= - s->intra_ac_vlc_last_length= uni_mpeg2_ac_vlc_len; - } else { - s->intra_ac_vlc_length= - s->intra_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; - } - s->inter_ac_vlc_length= - s->inter_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; -} - -static inline void encode_dc(MpegEncContext *s, int diff, int component) -{ - if(((unsigned) (diff+255)) >= 511){ - int index; - - if(diff<0){ - index= av_log2_16bit(-2*diff); - diff--; - }else{ - index= av_log2_16bit(2*diff); - } - if (component == 0) { - put_bits( - &s->pb, - ff_mpeg12_vlc_dc_lum_bits[index] + index, - (ff_mpeg12_vlc_dc_lum_code[index]<pb, - ff_mpeg12_vlc_dc_chroma_bits[index] + index, - (ff_mpeg12_vlc_dc_chroma_code[index]<pb, - mpeg1_lum_dc_uni[diff+255]&0xFF, - mpeg1_lum_dc_uni[diff+255]>>8); - } else { - put_bits( - &s->pb, - mpeg1_chr_dc_uni[diff+255]&0xFF, - mpeg1_chr_dc_uni[diff+255]>>8); - } - } -} - -static void mpeg1_encode_block(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign; - int code, component; - const uint16_t (*table_vlc)[2] = ff_rl_mpeg1.table_vlc; - - last_index = s->block_last_index[n]; - - /* DC coef */ - if (s->mb_intra) { - component = (n <= 3 ? 0 : (n&1) + 1); - dc = block[0]; /* overflow is impossible */ - diff = dc - s->last_dc[component]; - encode_dc(s, diff, component); - s->last_dc[component] = dc; - i = 1; - if (s->intra_vlc_format) - table_vlc = ff_rl_mpeg2.table_vlc; - } else { - /* encode the first coefficient : needs to be done here because - it is handled slightly differently */ - level = block[0]; - if (abs(level) == 1) { - code = ((uint32_t)level >> 31); /* the sign bit */ - put_bits(&s->pb, 2, code | 0x02); - i = 1; - } else { - i = 0; - last_non_zero = -1; - goto next_coef; - } - } - - /* now quantify & encode AC coefs */ - last_non_zero = i - 1; - - for(;i<=last_index;i++) { - j = s->intra_scantable.permutated[i]; - level = block[j]; - next_coef: -#if 0 - if (level != 0) - dprintf(s->avctx, "level[%d]=%d\n", i, level); -#endif - /* encode using VLC */ - if (level != 0) { - run = i - last_non_zero - 1; - - alevel= level; - MASK_ABS(sign, alevel) - sign&=1; - - if (alevel <= mpeg1_max_level[0][run]){ - code= mpeg1_index_run[0][run] + alevel - 1; - /* store the vlc & sign at once */ - put_bits(&s->pb, table_vlc[code][1]+1, (table_vlc[code][0]<<1) + sign); - } else { - /* escape seems to be pretty rare <5% so I do not optimize it */ - put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]); - /* escape: only clip in this case */ - put_bits(&s->pb, 6, run); - if(s->codec_id == CODEC_ID_MPEG1VIDEO){ - if (alevel < 128) { - put_sbits(&s->pb, 8, level); - } else { - if (level < 0) { - put_bits(&s->pb, 16, 0x8001 + level + 255); - } else { - put_sbits(&s->pb, 16, level); - } - } - }else{ - put_sbits(&s->pb, 12, level); - } - } - last_non_zero = i; - } - } - /* end of block */ - put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]); -} - -AVCodec mpeg1video_encoder = { - "mpeg1video", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG1VIDEO, - sizeof(MpegEncContext), - encode_init, - MPV_encode_picture, - MPV_encode_end, - .supported_framerates= ff_frame_rate_tab+1, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .capabilities= CODEC_CAP_DELAY, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), -}; - -AVCodec mpeg2video_encoder = { - "mpeg2video", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG2VIDEO, - sizeof(MpegEncContext), - encode_init, - MPV_encode_picture, - MPV_encode_end, - .supported_framerates= ff_frame_rate_tab+1, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE}, - .capabilities= CODEC_CAP_DELAY, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4audio.c b/tizen/distrib/ffmpeg/libavcodec/mpeg4audio.c deleted file mode 100644 index 7507212..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4audio.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * MPEG-4 Audio common code - * Copyright (c) 2008 Baptiste Coudurier - * Copyright (c) 2009 Alex Converse - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "get_bits.h" -#include "put_bits.h" -#include "mpeg4audio.h" - -/** - * Parse MPEG-4 audio configuration for ALS object type. - * @param[in] gb bit reader context - * @param[in] c MPEG4AudioConfig structure to fill - * @return on success 0 is returned, otherwise a value < 0 - */ -static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c) -{ - if (get_bits_left(gb) < 112) - return -1; - - if (get_bits_long(gb, 32) != MKBETAG('A','L','S','\0')) - return -1; - - // override AudioSpecificConfig channel configuration and sample rate - // which are buggy in old ALS conformance files - c->sample_rate = get_bits_long(gb, 32); - - // skip number of samples - skip_bits_long(gb, 32); - - // read number of channels - c->chan_config = 0; - c->channels = get_bits(gb, 16) + 1; - - return 0; -} - -const int ff_mpeg4audio_sample_rates[16] = { - 96000, 88200, 64000, 48000, 44100, 32000, - 24000, 22050, 16000, 12000, 11025, 8000, 7350 -}; - -const uint8_t ff_mpeg4audio_channels[8] = { - 0, 1, 2, 3, 4, 5, 6, 8 -}; - -static inline int get_object_type(GetBitContext *gb) -{ - int object_type = get_bits(gb, 5); - if (object_type == AOT_ESCAPE) - object_type = 32 + get_bits(gb, 6); - return object_type; -} - -static inline int get_sample_rate(GetBitContext *gb, int *index) -{ - *index = get_bits(gb, 4); - return *index == 0x0f ? get_bits(gb, 24) : - ff_mpeg4audio_sample_rates[*index]; -} - -int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size) -{ - GetBitContext gb; - int specific_config_bitindex; - - init_get_bits(&gb, buf, buf_size*8); - c->object_type = get_object_type(&gb); - c->sample_rate = get_sample_rate(&gb, &c->sampling_index); - c->chan_config = get_bits(&gb, 4); - if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) - c->channels = ff_mpeg4audio_channels[c->chan_config]; - c->sbr = -1; - c->ps = -1; - if (c->object_type == AOT_SBR || (c->object_type == AOT_PS && - // check for W6132 Annex YYYY draft MP3onMP4 - !(show_bits(&gb, 3) & 0x03 && !(show_bits(&gb, 9) & 0x3F)))) { - if (c->object_type == AOT_PS) - c->ps = 1; - c->ext_object_type = AOT_SBR; - c->sbr = 1; - c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index); - c->object_type = get_object_type(&gb); - if (c->object_type == AOT_ER_BSAC) - c->ext_chan_config = get_bits(&gb, 4); - } else { - c->ext_object_type = AOT_NULL; - c->ext_sample_rate = 0; - } - specific_config_bitindex = get_bits_count(&gb); - - if (c->object_type == AOT_ALS) { - skip_bits(&gb, 5); - if (show_bits_long(&gb, 24) != MKBETAG('\0','A','L','S')) - skip_bits_long(&gb, 24); - - specific_config_bitindex = get_bits_count(&gb); - - if (parse_config_ALS(&gb, c)) - return -1; - } - - if (c->ext_object_type != AOT_SBR) { - while (get_bits_left(&gb) > 15) { - if (show_bits(&gb, 11) == 0x2b7) { // sync extension - get_bits(&gb, 11); - c->ext_object_type = get_object_type(&gb); - if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(&gb)) == 1) - c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index); - if (get_bits_left(&gb) > 11 && get_bits(&gb, 11) == 0x548) - c->ps = get_bits1(&gb); - break; - } else - get_bits1(&gb); // skip 1 bit - } - } - return specific_config_bitindex; -} - -static av_always_inline unsigned int copy_bits(PutBitContext *pb, - GetBitContext *gb, - int bits) -{ - unsigned int el = get_bits(gb, bits); - put_bits(pb, bits, el); - return el; -} - -int ff_copy_pce_data(PutBitContext *pb, GetBitContext *gb) -{ - int five_bit_ch, four_bit_ch, comment_size, bits; - int offset = put_bits_count(pb); - - copy_bits(pb, gb, 10); //Tag, Object Type, Frequency - five_bit_ch = copy_bits(pb, gb, 4); //Front - five_bit_ch += copy_bits(pb, gb, 4); //Side - five_bit_ch += copy_bits(pb, gb, 4); //Back - four_bit_ch = copy_bits(pb, gb, 2); //LFE - four_bit_ch += copy_bits(pb, gb, 3); //Data - five_bit_ch += copy_bits(pb, gb, 4); //Coupling - if (copy_bits(pb, gb, 1)) //Mono Mixdown - copy_bits(pb, gb, 4); - if (copy_bits(pb, gb, 1)) //Stereo Mixdown - copy_bits(pb, gb, 4); - if (copy_bits(pb, gb, 1)) //Matrix Mixdown - copy_bits(pb, gb, 3); - for (bits = five_bit_ch*5+four_bit_ch*4; bits > 16; bits -= 16) - copy_bits(pb, gb, 16); - if (bits) - copy_bits(pb, gb, bits); - align_put_bits(pb); - align_get_bits(gb); - comment_size = copy_bits(pb, gb, 8); - for (; comment_size > 0; comment_size--) - copy_bits(pb, gb, 8); - - return put_bits_count(pb) - offset; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4audio.h b/tizen/distrib/ffmpeg/libavcodec/mpeg4audio.h deleted file mode 100644 index b941850..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4audio.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * MPEG-4 Audio common header - * Copyright (c) 2008 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPEG4AUDIO_H -#define AVCODEC_MPEG4AUDIO_H - -#include -#include "get_bits.h" -#include "put_bits.h" - -typedef struct { - int object_type; - int sampling_index; - int sample_rate; - int chan_config; - int sbr; //< -1 implicit, 1 presence - int ext_object_type; - int ext_sampling_index; - int ext_sample_rate; - int ext_chan_config; - int channels; - int ps; //< -1 implicit, 1 presence -} MPEG4AudioConfig; - -extern const int ff_mpeg4audio_sample_rates[16]; -extern const uint8_t ff_mpeg4audio_channels[8]; -/** - * Parse MPEG-4 systems extradata to retrieve audio configuration. - * @param[in] c MPEG4AudioConfig structure to fill. - * @param[in] buf Extradata from container. - * @param[in] buf_size Extradata size. - * @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata. - */ -int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size); - -enum AudioObjectType { - AOT_NULL, - // Support? Name - AOT_AAC_MAIN, ///< Y Main - AOT_AAC_LC, ///< Y Low Complexity - AOT_AAC_SSR, ///< N (code in SoC repo) Scalable Sample Rate - AOT_AAC_LTP, ///< N (code in SoC repo) Long Term Prediction - AOT_SBR, ///< Y Spectral Band Replication - AOT_AAC_SCALABLE, ///< N Scalable - AOT_TWINVQ, ///< N Twin Vector Quantizer - AOT_CELP, ///< N Code Excited Linear Prediction - AOT_HVXC, ///< N Harmonic Vector eXcitation Coding - AOT_TTSI = 12, ///< N Text-To-Speech Interface - AOT_MAINSYNTH, ///< N Main Synthesis - AOT_WAVESYNTH, ///< N Wavetable Synthesis - AOT_MIDI, ///< N General MIDI - AOT_SAFX, ///< N Algorithmic Synthesis and Audio Effects - AOT_ER_AAC_LC, ///< N Error Resilient Low Complexity - AOT_ER_AAC_LTP = 19, ///< N Error Resilient Long Term Prediction - AOT_ER_AAC_SCALABLE, ///< N Error Resilient Scalable - AOT_ER_TWINVQ, ///< N Error Resilient Twin Vector Quantizer - AOT_ER_BSAC, ///< N Error Resilient Bit-Sliced Arithmetic Coding - AOT_ER_AAC_LD, ///< N Error Resilient Low Delay - AOT_ER_CELP, ///< N Error Resilient Code Excited Linear Prediction - AOT_ER_HVXC, ///< N Error Resilient Harmonic Vector eXcitation Coding - AOT_ER_HILN, ///< N Error Resilient Harmonic and Individual Lines plus Noise - AOT_ER_PARAM, ///< N Error Resilient Parametric - AOT_SSC, ///< N SinuSoidal Coding - AOT_PS, ///< N Parametric Stereo - AOT_SURROUND, ///< N MPEG Surround - AOT_ESCAPE, ///< Y Escape Value - AOT_L1, ///< Y Layer 1 - AOT_L2, ///< Y Layer 2 - AOT_L3, ///< Y Layer 3 - AOT_DST, ///< N Direct Stream Transfer - AOT_ALS, ///< Y Audio LosslesS - AOT_SLS, ///< N Scalable LosslesS - AOT_SLS_NON_CORE, ///< N Scalable LosslesS (non core) - AOT_ER_AAC_ELD, ///< N Error Resilient Enhanced Low Delay - AOT_SMR_SIMPLE, ///< N Symbolic Music Representation Simple - AOT_SMR_MAIN, ///< N Symbolic Music Representation Main - AOT_USAC_NOSBR, ///< N Unified Speech and Audio Coding (no SBR) - AOT_SAOC, ///< N Spatial Audio Object Coding - AOT_LD_SURROUND, ///< N Low Delay MPEG Surround - AOT_USAC, ///< N Unified Speech and Audio Coding -}; - -#define MAX_PCE_SIZE 304 /// - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * mpeg4 tables. - */ - -#ifndef AVCODEC_MPEG4DATA_H -#define AVCODEC_MPEG4DATA_H - -#include -#include "mpegvideo.h" - -/* dc encoding for mpeg4 */ -const uint8_t ff_mpeg4_DCtab_lum[13][2] = -{ - {3,3}, {3,2}, {2,2}, {2,3}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7}, - {1,8}, {1,9}, {1,10}, {1,11}, -}; - -const uint8_t ff_mpeg4_DCtab_chrom[13][2] = -{ - {3,2}, {2,2}, {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7}, {1,8}, - {1,9}, {1,10}, {1,11}, {1,12}, -}; - -const uint16_t ff_mpeg4_intra_vlc[103][2] = { -{ 0x2, 2 }, -{ 0x6, 3 },{ 0xf, 4 },{ 0xd, 5 },{ 0xc, 5 }, -{ 0x15, 6 },{ 0x13, 6 },{ 0x12, 6 },{ 0x17, 7 }, -{ 0x1f, 8 },{ 0x1e, 8 },{ 0x1d, 8 },{ 0x25, 9 }, -{ 0x24, 9 },{ 0x23, 9 },{ 0x21, 9 },{ 0x21, 10 }, -{ 0x20, 10 },{ 0xf, 10 },{ 0xe, 10 },{ 0x7, 11 }, -{ 0x6, 11 },{ 0x20, 11 },{ 0x21, 11 },{ 0x50, 12 }, -{ 0x51, 12 },{ 0x52, 12 },{ 0xe, 4 },{ 0x14, 6 }, -{ 0x16, 7 },{ 0x1c, 8 },{ 0x20, 9 },{ 0x1f, 9 }, -{ 0xd, 10 },{ 0x22, 11 },{ 0x53, 12 },{ 0x55, 12 }, -{ 0xb, 5 },{ 0x15, 7 },{ 0x1e, 9 },{ 0xc, 10 }, -{ 0x56, 12 },{ 0x11, 6 },{ 0x1b, 8 },{ 0x1d, 9 }, -{ 0xb, 10 },{ 0x10, 6 },{ 0x22, 9 },{ 0xa, 10 }, -{ 0xd, 6 },{ 0x1c, 9 },{ 0x8, 10 },{ 0x12, 7 }, -{ 0x1b, 9 },{ 0x54, 12 },{ 0x14, 7 },{ 0x1a, 9 }, -{ 0x57, 12 },{ 0x19, 8 },{ 0x9, 10 },{ 0x18, 8 }, -{ 0x23, 11 },{ 0x17, 8 },{ 0x19, 9 },{ 0x18, 9 }, -{ 0x7, 10 },{ 0x58, 12 },{ 0x7, 4 },{ 0xc, 6 }, -{ 0x16, 8 },{ 0x17, 9 },{ 0x6, 10 },{ 0x5, 11 }, -{ 0x4, 11 },{ 0x59, 12 },{ 0xf, 6 },{ 0x16, 9 }, -{ 0x5, 10 },{ 0xe, 6 },{ 0x4, 10 },{ 0x11, 7 }, -{ 0x24, 11 },{ 0x10, 7 },{ 0x25, 11 },{ 0x13, 7 }, -{ 0x5a, 12 },{ 0x15, 8 },{ 0x5b, 12 },{ 0x14, 8 }, -{ 0x13, 8 },{ 0x1a, 8 },{ 0x15, 9 },{ 0x14, 9 }, -{ 0x13, 9 },{ 0x12, 9 },{ 0x11, 9 },{ 0x26, 11 }, -{ 0x27, 11 },{ 0x5c, 12 },{ 0x5d, 12 },{ 0x5e, 12 }, -{ 0x5f, 12 },{ 0x3, 7 }, -}; - -const int8_t ff_mpeg4_intra_level[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, 26, 27, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 1, 2, 3, - 4, 5, 1, 2, 3, 4, 1, 2, - 3, 1, 2, 3, 1, 2, 3, 1, - 2, 3, 1, 2, 1, 2, 1, 1, - 1, 1, 1, 1, 2, 3, 4, 5, - 6, 7, 8, 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, -}; - -const int8_t ff_mpeg4_intra_run[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, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 4, 4, - 4, 5, 5, 5, 6, 6, 6, 7, - 7, 7, 8, 8, 9, 9, 10, 11, - 12, 13, 14, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 2, 2, - 3, 3, 4, 4, 5, 5, 6, 6, - 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, -}; - -RLTable ff_mpeg4_rl_intra = { - 102, - 67, - ff_mpeg4_intra_vlc, - ff_mpeg4_intra_run, - ff_mpeg4_intra_level, -}; - -/* Note this is identical to the intra rvlc except that it is reordered. */ -const uint16_t inter_rvlc[170][2]={ -{0x0006, 3},{0x0001, 4},{0x0004, 5},{0x001C, 7}, -{0x003C, 8},{0x003D, 8},{0x007C, 9},{0x00FC, 10}, -{0x00FD, 10},{0x01FC, 11},{0x01FD, 11},{0x03FC, 12}, -{0x07FC, 13},{0x07FD, 13},{0x0BFC, 13},{0x0BFD, 13}, -{0x0FFC, 14},{0x0FFD, 14},{0x1FFC, 15},{0x0007, 3}, -{0x000C, 6},{0x005C, 8},{0x007D, 9},{0x017C, 10}, -{0x02FC, 11},{0x03FD, 12},{0x0DFC, 13},{0x17FC, 14}, -{0x17FD, 14},{0x000A, 4},{0x001D, 7},{0x00BC, 9}, -{0x02FD, 11},{0x05FC, 12},{0x1BFC, 14},{0x1BFD, 14}, -{0x0005, 5},{0x005D, 8},{0x017D, 10},{0x05FD, 12}, -{0x0DFD, 13},{0x1DFC, 14},{0x1FFD, 15},{0x0008, 5}, -{0x006C, 8},{0x037C, 11},{0x0EFC, 13},{0x2FFC, 15}, -{0x0009, 5},{0x00BD, 9},{0x037D, 11},{0x0EFD, 13}, -{0x000D, 6},{0x01BC, 10},{0x06FC, 12},{0x1DFD, 14}, -{0x0014, 6},{0x01BD, 10},{0x06FD, 12},{0x2FFD, 15}, -{0x0015, 6},{0x01DC, 10},{0x0F7C, 13},{0x002C, 7}, -{0x01DD, 10},{0x1EFC, 14},{0x002D, 7},{0x03BC, 11}, -{0x0034, 7},{0x077C, 12},{0x006D, 8},{0x0F7D, 13}, -{0x0074, 8},{0x1EFD, 14},{0x0075, 8},{0x1F7C, 14}, -{0x00DC, 9},{0x1F7D, 14},{0x00DD, 9},{0x1FBC, 14}, -{0x00EC, 9},{0x37FC, 15},{0x01EC, 10},{0x01ED, 10}, -{0x01F4, 10},{0x03BD, 11},{0x03DC, 11},{0x03DD, 11}, -{0x03EC, 11},{0x03ED, 11},{0x03F4, 11},{0x077D, 12}, -{0x07BC, 12},{0x07BD, 12},{0x0FBC, 13},{0x0FBD, 13}, -{0x0FDC, 13},{0x0FDD, 13},{0x1FBD, 14},{0x1FDC, 14}, -{0x1FDD, 14},{0x37FD, 15},{0x3BFC, 15}, -{0x000B, 4},{0x0078, 8},{0x03F5, 11},{0x0FEC, 13}, -{0x1FEC, 14},{0x0012, 5},{0x00ED, 9},{0x07DC, 12}, -{0x1FED, 14},{0x3BFD, 15},{0x0013, 5},{0x03F8, 11}, -{0x3DFC, 15},{0x0018, 6},{0x07DD, 12},{0x0019, 6}, -{0x07EC, 12},{0x0022, 6},{0x0FED, 13},{0x0023, 6}, -{0x0FF4, 13},{0x0035, 7},{0x0FF5, 13},{0x0038, 7}, -{0x0FF8, 13},{0x0039, 7},{0x0FF9, 13},{0x0042, 7}, -{0x1FF4, 14},{0x0043, 7},{0x1FF5, 14},{0x0079, 8}, -{0x1FF8, 14},{0x0082, 8},{0x3DFD, 15},{0x0083, 8}, -{0x00F4, 9},{0x00F5, 9},{0x00F8, 9},{0x00F9, 9}, -{0x0102, 9},{0x0103, 9},{0x01F5, 10},{0x01F8, 10}, -{0x01F9, 10},{0x0202, 10},{0x0203, 10},{0x03F9, 11}, -{0x0402, 11},{0x0403, 11},{0x07ED, 12},{0x07F4, 12}, -{0x07F5, 12},{0x07F8, 12},{0x07F9, 12},{0x0802, 12}, -{0x0803, 12},{0x1002, 13},{0x1003, 13},{0x1FF9, 14}, -{0x2002, 14},{0x2003, 14},{0x3EFC, 15},{0x3EFD, 15}, -{0x3F7C, 15},{0x3F7D, 15},{0x0000, 4} -}; - -static const int8_t inter_rvlc_run[169]={ - 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, 2, 2, 2, - 2, 2, 2, 2, 3, 3, 3, 3, - 3, 3, 3, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 6, 6, 6, 6, - 7, 7, 7, 7, 8, 8, 8, 9, - 9, 9, 10, 10, 11, 11, 12, 12, -13, 13, 14, 14, 15, 15, 16, 16, -17, 17, 18, 19, 20, 21, 22, 23, -24, 25, 26, 27, 28, 29, 30, 31, -32, 33, 34, 35, 36, 37, 38, - 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 2, 2, 2, 3, 3, 4, - 4, 5, 5, 6, 6, 7, 7, 8, - 8, 9, 9, 10, 10, 11, 11, 12, -12, 13, 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, -}; - -static const int8_t inter_rvlc_level[169]={ - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, -17, 18, 19, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 1, 2, 3, - 4, 5, 6, 7, 1, 2, 3, 4, - 5, 6, 7, 1, 2, 3, 4, 5, - 1, 2, 3, 4, 1, 2, 3, 4, - 1, 2, 3, 4, 1, 2, 3, 1, - 2, 3, 1, 2, 1, 2, 1, 2, - 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, 1, 1, 1, 1, 1, - 1, 2, 3, 4, 5, 1, 2, 3, - 4, 5, 1, 2, 3, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 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, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, -}; - -RLTable rvlc_rl_inter = { - 169, - 103, - inter_rvlc, - inter_rvlc_run, - inter_rvlc_level, -}; - -const uint16_t intra_rvlc[170][2]={ -{0x0006, 3},{0x0007, 3},{0x000A, 4},{0x0009, 5}, -{0x0014, 6},{0x0015, 6},{0x0034, 7},{0x0074, 8}, -{0x0075, 8},{0x00DD, 9},{0x00EC, 9},{0x01EC, 10}, -{0x01ED, 10},{0x01F4, 10},{0x03EC, 11},{0x03ED, 11}, -{0x03F4, 11},{0x077D, 12},{0x07BC, 12},{0x0FBD, 13}, -{0x0FDC, 13},{0x07BD, 12},{0x0FDD, 13},{0x1FBD, 14}, -{0x1FDC, 14},{0x1FDD, 14},{0x1FFC, 15},{0x0001, 4}, -{0x0008, 5},{0x002D, 7},{0x006C, 8},{0x006D, 8}, -{0x00DC, 9},{0x01DD, 10},{0x03DC, 11},{0x03DD, 11}, -{0x077C, 12},{0x0FBC, 13},{0x1F7D, 14},{0x1FBC, 14}, -{0x0004, 5},{0x002C, 7},{0x00BC, 9},{0x01DC, 10}, -{0x03BC, 11},{0x03BD, 11},{0x0EFD, 13},{0x0F7C, 13}, -{0x0F7D, 13},{0x1EFD, 14},{0x1F7C, 14},{0x0005, 5}, -{0x005C, 8},{0x00BD, 9},{0x037D, 11},{0x06FC, 12}, -{0x0EFC, 13},{0x1DFD, 14},{0x1EFC, 14},{0x1FFD, 15}, -{0x000C, 6},{0x005D, 8},{0x01BD, 10},{0x03FD, 12}, -{0x06FD, 12},{0x1BFD, 14},{0x000D, 6},{0x007D, 9}, -{0x02FC, 11},{0x05FC, 12},{0x1BFC, 14},{0x1DFC, 14}, -{0x001C, 7},{0x017C, 10},{0x02FD, 11},{0x05FD, 12}, -{0x2FFC, 15},{0x001D, 7},{0x017D, 10},{0x037C, 11}, -{0x0DFD, 13},{0x2FFD, 15},{0x003C, 8},{0x01BC, 10}, -{0x0BFD, 13},{0x17FD, 14},{0x003D, 8},{0x01FD, 11}, -{0x0DFC, 13},{0x37FC, 15},{0x007C, 9},{0x03FC, 12}, -{0x00FC, 10},{0x0BFC, 13},{0x00FD, 10},{0x37FD, 15}, -{0x01FC, 11},{0x07FC, 13},{0x07FD, 13},{0x0FFC, 14}, -{0x0FFD, 14},{0x17FC, 14},{0x3BFC, 15}, -{0x000B, 4},{0x0078, 8},{0x03F5, 11},{0x0FEC, 13}, -{0x1FEC, 14},{0x0012, 5},{0x00ED, 9},{0x07DC, 12}, -{0x1FED, 14},{0x3BFD, 15},{0x0013, 5},{0x03F8, 11}, -{0x3DFC, 15},{0x0018, 6},{0x07DD, 12},{0x0019, 6}, -{0x07EC, 12},{0x0022, 6},{0x0FED, 13},{0x0023, 6}, -{0x0FF4, 13},{0x0035, 7},{0x0FF5, 13},{0x0038, 7}, -{0x0FF8, 13},{0x0039, 7},{0x0FF9, 13},{0x0042, 7}, -{0x1FF4, 14},{0x0043, 7},{0x1FF5, 14},{0x0079, 8}, -{0x1FF8, 14},{0x0082, 8},{0x3DFD, 15},{0x0083, 8}, -{0x00F4, 9},{0x00F5, 9},{0x00F8, 9},{0x00F9, 9}, -{0x0102, 9},{0x0103, 9},{0x01F5, 10},{0x01F8, 10}, -{0x01F9, 10},{0x0202, 10},{0x0203, 10},{0x03F9, 11}, -{0x0402, 11},{0x0403, 11},{0x07ED, 12},{0x07F4, 12}, -{0x07F5, 12},{0x07F8, 12},{0x07F9, 12},{0x0802, 12}, -{0x0803, 12},{0x1002, 13},{0x1003, 13},{0x1FF9, 14}, -{0x2002, 14},{0x2003, 14},{0x3EFC, 15},{0x3EFD, 15}, -{0x3F7C, 15},{0x3F7D, 15},{0x0000, 4} -}; - -static const int8_t intra_rvlc_run[169]={ - 0, 0, 0, 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, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 4, 4, 4, - 4, 4, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 7, 7, 7, - 7, 7, 8, 8, 8, 8, 9, 9, - 9, 9, 10, 10, 11, 11, 12, 12, -13, 14, 15, 16, 17, 18, 19, - 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 2, 2, 2, 3, 3, 4, - 4, 5, 5, 6, 6, 7, 7, 8, - 8, 9, 9, 10, 10, 11, 11, 12, -12, 13, 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, -}; - -static const int8_t intra_rvlc_level[169]={ - 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, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 1, 2, 3, 4, - 5, 6, 1, 2, 3, 4, 5, 6, - 1, 2, 3, 4, 5, 1, 2, 3, - 4, 5, 1, 2, 3, 4, 1, 2, - 3, 4, 1, 2, 1, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 1, - 1, 2, 3, 4, 5, 1, 2, 3, - 4, 5, 1, 2, 3, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 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, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, -}; - -RLTable rvlc_rl_intra = { - 169, - 103, - intra_rvlc, - intra_rvlc_run, - intra_rvlc_level, -}; - -const uint16_t sprite_trajectory_tab[15][2] = { - {0x00, 2}, {0x02, 3}, {0x03, 3}, {0x04, 3}, {0x05, 3}, {0x06, 3}, - {0x0E, 4}, {0x1E, 5}, {0x3E, 6}, {0x7E, 7}, {0xFE, 8}, - {0x1FE, 9},{0x3FE, 10},{0x7FE, 11},{0xFFE, 12}, -}; - -const uint8_t mb_type_b_tab[4][2] = { - {1, 1}, {1, 2}, {1, 3}, {1, 4}, -}; - -/* these matrixes will be permuted for the idct */ -const int16_t ff_mpeg4_default_intra_matrix[64] = { - 8, 17, 18, 19, 21, 23, 25, 27, - 17, 18, 19, 21, 23, 25, 27, 28, - 20, 21, 22, 23, 24, 26, 28, 30, - 21, 22, 23, 24, 26, 28, 30, 32, - 22, 23, 24, 26, 28, 30, 32, 35, - 23, 24, 26, 28, 30, 32, 35, 38, - 25, 26, 28, 30, 32, 35, 38, 41, - 27, 28, 30, 32, 35, 38, 41, 45, -}; - -const int16_t ff_mpeg4_default_non_intra_matrix[64] = { - 16, 17, 18, 19, 20, 21, 22, 23, - 17, 18, 19, 20, 21, 22, 23, 24, - 18, 19, 20, 21, 22, 23, 24, 25, - 19, 20, 21, 22, 23, 24, 26, 27, - 20, 21, 22, 23, 25, 26, 27, 28, - 21, 22, 23, 24, 26, 27, 28, 30, - 22, 23, 24, 26, 27, 28, 30, 31, - 23, 24, 25, 27, 28, 30, 31, 33, -}; - -const uint8_t ff_mpeg4_y_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, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,34,36,38,40,42,44,46 -}; -const uint8_t ff_mpeg4_c_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, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,20,21,22,23,24,25 -}; - -const uint16_t ff_mpeg4_resync_prefix[8]={ - 0x7F00, 0x7E00, 0x7C00, 0x7800, 0x7000, 0x6000, 0x4000, 0x0000 -}; - -const uint8_t mpeg4_dc_threshold[8]={ - 99, 13, 15, 17, 19, 21, 23, 0 -}; - -#endif /* AVCODEC_MPEG4DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4video.c b/tizen/distrib/ffmpeg/libavcodec/mpeg4video.c deleted file mode 100644 index dd4dd8a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4video.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * MPEG4 decoder / encoder common code. - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mpegvideo.h" -#include "mpeg4video.h" -#include "mpeg4data.h" - -uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3]; - -int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s){ - switch(s->pict_type){ - case FF_I_TYPE: - return 16; - case FF_P_TYPE: - case FF_S_TYPE: - return s->f_code+15; - case FF_B_TYPE: - return FFMAX3(s->f_code, s->b_code, 2) + 15; - default: - return -1; - } -} - -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; -} - -#define tab_size ((signed)FF_ARRAY_ELEMS(s->direct_scale_mv[0])) -#define tab_bias (tab_size/2) - -//used by mpeg4 and rv10 decoder -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; - uint16_t time_pb; - 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][4*mb_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 - } -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4video.h b/tizen/distrib/ffmpeg/libavcodec/mpeg4video.h deleted file mode 100644 index aab3236..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4video.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * MPEG4 encoder/decoder internal header. - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPEG4VIDEO_H -#define AVCODEC_MPEG4VIDEO_H - -#include -#include "get_bits.h" -#include "mpegvideo.h" -#include "rl.h" - -// shapes -#define RECT_SHAPE 0 -#define BIN_SHAPE 1 -#define BIN_ONLY_SHAPE 2 -#define GRAY_SHAPE 3 - -#define SIMPLE_VO_TYPE 1 -#define CORE_VO_TYPE 3 -#define MAIN_VO_TYPE 4 -#define NBIT_VO_TYPE 5 -#define ARTS_VO_TYPE 10 -#define ACE_VO_TYPE 12 -#define ADV_SIMPLE_VO_TYPE 17 - -// aspect_ratio_info -#define EXTENDED_PAR 15 - -//vol_sprite_usage / sprite_enable -#define STATIC_SPRITE 1 -#define GMC_SPRITE 2 - -#define MOTION_MARKER 0x1F001 -#define DC_MARKER 0x6B001 - -#define VOS_STARTCODE 0x1B0 -#define USER_DATA_STARTCODE 0x1B2 -#define GOP_STARTCODE 0x1B3 -#define VISUAL_OBJ_STARTCODE 0x1B5 -#define VOP_STARTCODE 0x1B6 - -/* dc encoding for mpeg4 */ -extern const uint8_t ff_mpeg4_DCtab_lum[13][2]; -extern const uint8_t ff_mpeg4_DCtab_chrom[13][2]; - -extern const uint16_t ff_mpeg4_intra_vlc[103][2]; -extern RLTable ff_mpeg4_rl_intra; - -/* Note this is identical to the intra rvlc except that it is reordered. */ -extern const uint16_t inter_rvlc[170][2]; -extern RLTable rvlc_rl_inter; - -extern const uint16_t intra_rvlc[170][2]; -extern RLTable rvlc_rl_intra; - -extern const uint16_t sprite_trajectory_tab[15][2]; -extern const uint8_t mb_type_b_tab[4][2]; - -/* these matrixes will be permuted for the idct */ -extern const int16_t ff_mpeg4_default_intra_matrix[64]; -extern const int16_t ff_mpeg4_default_non_intra_matrix[64]; - -extern const uint8_t ff_mpeg4_y_dc_scale_table[32]; -extern const uint8_t ff_mpeg4_c_dc_scale_table[32]; -extern const uint16_t ff_mpeg4_resync_prefix[8]; - -extern const uint8_t mpeg4_dc_threshold[8]; - -void mpeg4_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, - int dir); -void ff_set_mpeg4_time(MpegEncContext * s); -void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number); - -int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb); -void ff_mpeg4_encode_video_packet_header(MpegEncContext *s); -void ff_mpeg4_clean_buffers(MpegEncContext *s); -void ff_mpeg4_stuffing(PutBitContext * pbc); -void ff_mpeg4_init_partitions(MpegEncContext *s); -void ff_mpeg4_merge_partitions(MpegEncContext *s); -void ff_clean_mpeg4_qscales(MpegEncContext *s); -int ff_mpeg4_decode_partitions(MpegEncContext *s); -int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s); -int mpeg4_decode_video_packet_header(MpegEncContext *s); -void ff_mpeg4_init_direct_mv(MpegEncContext *s); - -/** - * - * @return the mb_type - */ -int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my); - -extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3]; - - -#if 0 //3IV1 is quite rare and it slows things down a tiny bit -#define IS_3IV1 s->codec_tag == AV_RL32("3IV1") -#else -#define IS_3IV1 0 -#endif - - -/** - * 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; - int16_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_recognition>=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; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.c b/tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.c deleted file mode 100644 index 5dbda8b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * MPEG4 Video frame extraction - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" -#include "mpegvideo.h" -#include "mpeg4video.h" -#include "mpeg4video_parser.h" - - -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; -} - -/* XXX: make it use less memory */ -static int av_mpeg4_decode_header(AVCodecParserContext *s1, - AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - ParseContext1 *pc = s1->priv_data; - MpegEncContext *s = pc->enc; - GetBitContext gb1, *gb = &gb1; - int ret; - - s->avctx = avctx; - s->current_picture_ptr = &s->current_picture; - - if (avctx->extradata_size && pc->first_picture){ - init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); - ret = ff_mpeg4_decode_picture_header(s, gb); - } - - init_get_bits(gb, buf, 8 * buf_size); - ret = ff_mpeg4_decode_picture_header(s, gb); - if (s->width && (!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height)) { - avcodec_set_dimensions(avctx, s->width, s->height); - } - s1->pict_type= s->pict_type; - pc->first_picture = 0; - return ret; -} - -static av_cold int mpeg4video_parse_init(AVCodecParserContext *s) -{ - ParseContext1 *pc = s->priv_data; - - pc->enc = av_mallocz(sizeof(MpegEncContext)); - if (!pc->enc) - return -1; - pc->first_picture = 1; - return 0; -} - -static int mpeg4video_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= ff_mpeg4_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - av_mpeg4_decode_header(s, avctx, buf, buf_size); - - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - - -AVCodecParser mpeg4video_parser = { - { CODEC_ID_MPEG4 }, - sizeof(ParseContext1), - mpeg4video_parse_init, - mpeg4video_parse, - ff_parse1_close, - ff_mpeg4video_split, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.h b/tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.h deleted file mode 100644 index 822a24c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4video_parser.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * MPEG4 video parser prototypes - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MPEG4VIDEO_PARSER_H -#define AVCODEC_MPEG4VIDEO_PARSER_H - -#include "parser.h" - -/** - * 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); - -#endif /* AVCODEC_MPEG4VIDEO_PARSER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4videodec.c b/tizen/distrib/ffmpeg/libavcodec/mpeg4videodec.c deleted file mode 100644 index fa69c9e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4videodec.c +++ /dev/null @@ -1,2267 +0,0 @@ -/* - * MPEG4 decoder. - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mpegvideo.h" -#include "mpeg4video.h" -#include "h263.h" - -// The defines below define the number of bits that are read at once for -// reading vlc values. Changing these may improve speed and data cache needs -// be aware though that decreasing them may need the number of stages that is -// passed to get_vlc* to be increased. -#define SPRITE_TRAJ_VLC_BITS 6 -#define DC_VLC_BITS 9 -#define MB_TYPE_B_VLC_BITS 4 - - -static VLC dc_lum, dc_chrom; -static VLC sprite_trajectory; -static VLC mb_type_b_vlc; - -static const int mb_type_b_map[4]= { - MB_TYPE_DIRECT2 | MB_TYPE_L0L1, - MB_TYPE_L0L1 | MB_TYPE_16x16, - MB_TYPE_L1 | MB_TYPE_16x16, - MB_TYPE_L0 | MB_TYPE_16x16, -}; - -/** - * 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 ]]; - -} - -/** - * check if the next stuff is a resync marker or the end. - * @return 0 if not - */ -static inline int mpeg4_is_resync(MpegEncContext *s){ - int bits_count= get_bits_count(&s->gb); - int v= show_bits(&s->gb, 16); - - if(s->workaround_bugs&FF_BUG_NO_PADDING){ - return 0; - } - - while(v<=0xFF){ - if(s->pict_type==FF_B_TYPE || (v>>(8-s->pict_type)!=1) || s->partitioned_frame) - break; - skip_bits(&s->gb, 8+s->pict_type); - bits_count+= 8+s->pict_type; - v= show_bits(&s->gb, 16); - } - - if(bits_count + 8 >= s->gb.size_in_bits){ - v>>=8; - v|= 0x7F >> (7-(bits_count&7)); - - if(v==0x7F) - return 1; - }else{ - if(v == 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; -} - -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 */ - s->sprite_traj[i][0]= d[i][0]= x; - s->sprite_traj[i][1]= d[i][1]= y; - } - for(; i<4; i++) - s->sprite_traj[i][0]= s->sprite_traj[i][1]= 0; - - 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]; - 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; - } -} - -/** - * decodes the next video packet. - * @return <0 if something went wrong - */ -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 == FF_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 already 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 == FF_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 != FF_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 == FF_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 - - return 0; -} - -/** - * gets the average motion vector for a GMC MB. - * @param n either 0 for the x component or 1 for y - * @return 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 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_recognition>=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 first partition. - * @return number of MBs decoded or <0 if an error occurred - */ -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==FF_I_TYPE){ - int i; - - do{ - if(show_bits_long(&s->gb, 19)==DC_MARKER){ - return mb_num-1; - } - - cbpc = get_vlc2(&s->gb, ff_h263_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==FF_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, ff_h263_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==FF_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 occurred - */ -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==FF_I_TYPE){ - int ac_pred= get_bits1(&s->gb); - int cbpy = get_vlc2(&s->gb, ff_h263_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, ff_h263_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, ff_h263_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==FF_I_TYPE ? (DC_ERROR|MV_ERROR) : MV_ERROR; - const int part_a_end = s->pict_type==FF_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==FF_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==FF_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==FF_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; -} - -/** - * decodes a block. - * @return <0 if an error occurred - */ -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->use_intra_dc_vlc){ - /* 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 = &ff_h263_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 = ff_h263_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 = ff_h263_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_recognition >= FF_ER_COMPLIANT){ - const int abs_level= FFABS(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_recognition > 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_recognition > 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->use_intra_dc_vlc){ - 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; -} - -/** - * decode partition C of one MB. - * @return <0 if an error occurred - */ -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]; - - s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold; - - if(s->current_picture.qscale_table[xy] != s->qscale){ - ff_set_qscale(s, s->current_picture.qscale_table[xy] ); - } - - if (s->pict_type == FF_P_TYPE || s->pict_type==FF_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==FF_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){ - 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; - } -} - -static int 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 == FF_P_TYPE || s->pict_type==FF_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==FF_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, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); - 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==FF_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, ff_h263_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==FF_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, ff_h263_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, ff_h263_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); - - s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold; - - 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==FF_B_TYPE && s->next_picture.mbskip_table[xy + delta]) - return SLICE_OK; - return SLICE_END; - } - } - - return SLICE_OK; -} - - -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; - } - 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= ff_h263_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!=CHROMA_420){ - 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->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */ - s->width = width; - s->height = 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); - if(s->num_sprite_warping_points > 3){ - av_log(s->avctx, AV_LOG_ERROR, "%d sprite_warping_points\n", s->num_sprite_warping_points); - s->num_sprite_warping_points= 0; - return -1; - } - 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)){ - int pos= get_bits_count(gb); - int estimation_method= get_bits(gb, 2); - if(estimation_method<2){ - if(!get_bits1(gb)){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //opaque - s->cplx_estimation_trash_i += 8*get_bits1(gb); //transparent - s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_cae - s->cplx_estimation_trash_i += 8*get_bits1(gb); //inter_cae - s->cplx_estimation_trash_i += 8*get_bits1(gb); //no_update - s->cplx_estimation_trash_i += 8*get_bits1(gb); //upampling - } - if(!get_bits1(gb)){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_blocks - s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter_blocks - s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter4v_blocks - s->cplx_estimation_trash_i += 8*get_bits1(gb); //not coded blocks - } - if(!check_marker(gb, "in complexity estimation part 1")){ - skip_bits_long(gb, pos - get_bits_count(gb)); - goto no_cplx_est; - } - if(!get_bits1(gb)){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_coeffs - s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_lines - s->cplx_estimation_trash_i += 8*get_bits1(gb); //vlc_syms - s->cplx_estimation_trash_i += 4*get_bits1(gb); //vlc_bits - } - if(!get_bits1(gb)){ - s->cplx_estimation_trash_p += 8*get_bits1(gb); //apm - s->cplx_estimation_trash_p += 8*get_bits1(gb); //npm - s->cplx_estimation_trash_b += 8*get_bits1(gb); //interpolate_mc_q - s->cplx_estimation_trash_p += 8*get_bits1(gb); //forwback_mc_q - s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel2 - s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel4 - } - if(!check_marker(gb, "in complexity estimation part 2")){ - skip_bits_long(gb, pos - get_bits_count(gb)); - goto no_cplx_est; - } - if(estimation_method==1){ - s->cplx_estimation_trash_i += 8*get_bits1(gb); //sadct - s->cplx_estimation_trash_p += 8*get_bits1(gb); //qpel - } - }else - av_log(s->avctx, AV_LOG_ERROR, "Invalid Complexity estimation method %d\n", estimation_method); - }else{ -no_cplx_est: - s->cplx_estimation_trash_i= - s->cplx_estimation_trash_p= - s->cplx_estimation_trash_b= 0; - } - - 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){ - /* illegal scalability header (VERY broken encoder), - * trying to workaround */ - 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. - * Also initializes 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 && get_bits_count(gb) < 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'; - if(s->divx_packed && !s->showed_packed_warning) { - av_log(s->avctx, AV_LOG_WARNING, "Invalid and inefficient vfw-avi packed B frames detected\n"); - s->showed_packed_warning=1; - } - } - - /* 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; - } - - return 0; -} - -static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ - int time_incr, time_increment; - - s->pict_type = get_bits(gb, 2) + FF_I_TYPE; /* pict type: I = 0 , P = 1 */ - if(s->pict_type==FF_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!=FF_B_TYPE; - if(s->partitioned_frame) - s->decode_mb= mpeg4_decode_partitioned_mb; - else - s->decode_mb= 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 ( s->pict_type == FF_P_TYPE - || (s->pict_type == FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE)) { - if((show_bits(gb, s->time_increment_bits+6)&0x37) == 0x30) break; - }else - if((show_bits(gb, s->time_increment_bits+5)&0x1F) == 0x18) 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); - - if(s->pict_type!=FF_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){ - /* header is not mpeg-4-compatible, broken encoder, - * trying to workaround */ - 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){ - /* messed up order, maybe after seeking? skipping current b-frame */ - 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; - if(!s->progressive_sequence){ - if(s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1) - return FRAME_SKIPPED; - } - } - - 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; - } - if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == FF_P_TYPE - || (s->pict_type == FF_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 != FF_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) { - skip_bits_long(gb, s->cplx_estimation_trash_i); - if(s->pict_type != FF_I_TYPE) - skip_bits_long(gb, s->cplx_estimation_trash_p); - if(s->pict_type == FF_B_TYPE) - skip_bits_long(gb, s->cplx_estimation_trash_b); - - 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 == FF_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 != FF_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 == FF_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 ce:%d/%d/%d\n", - s->qscale, s->f_code, s->b_code, - s->pict_type == FF_I_TYPE ? "I" : (s->pict_type == FF_P_TYPE ? "P" : (s->pict_type == FF_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, s->cplx_estimation_trash_i, s->cplx_estimation_trash_p, s->cplx_estimation_trash_b); - } - - if(!s->scalability){ - if (s->shape!=RECT_SHAPE && s->pict_type!=FF_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==-1 && 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->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630){ - skip_bits(gb, 24); - if(get_bits(gb, 8) == 0xF0) - goto end; - } - - startcode = 0xff; - for(;;) { - if(get_bits_count(gb) >= gb->size_in_bits){ - if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0)){ - 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){ - break; - } - - align_get_bits(gb); - startcode = 0xff; - } -end: - if(s->flags& CODEC_FLAG_LOW_DELAY) - s->low_delay=1; - s->avctx->has_b_frames= !s->low_delay; - return decode_vop_header(s, gb); -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - int ret; - static int done = 0; - - s->divx_version= - s->divx_build= - s->xvid_build= - s->lavc_build= -1; - - if((ret=ff_h263_decode_init(avctx)) < 0) - return ret; - - if (!done) { - done = 1; - - init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); - init_rl(&rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); - init_rl(&rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); - INIT_VLC_RL(ff_mpeg4_rl_intra, 554); - INIT_VLC_RL(rvlc_rl_inter, 1072); - INIT_VLC_RL(rvlc_rl_intra, 1072); - INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_lum[0][1], 2, 1, - &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); - INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_chrom[0][1], 2, 1, - &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); - INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, - &sprite_trajectory_tab[0][1], 4, 2, - &sprite_trajectory_tab[0][0], 4, 2, 128); - INIT_VLC_STATIC(&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, 16); - } - - s->h263_pred = 1; - s->low_delay = 0; //default, might be overriden in the vol header during header parsing - s->decode_mb= mpeg4_decode_mb; - s->time_increment_bits = 4; /* default value for broken headers */ - avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; - - return 0; -} - -AVCodec mpeg4_decoder = { - "mpeg4", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(MpegEncContext), - 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, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), - .pix_fmts= ff_hwaccel_pixfmt_list_420, -}; - - -#if CONFIG_MPEG4_VDPAU_DECODER -AVCodec mpeg4_vdpau_decoder = { - "mpeg4_vdpau", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(MpegEncContext), - decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"), - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_VDPAU_MPEG4, PIX_FMT_NONE}, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/mpeg4videoenc.c b/tizen/distrib/ffmpeg/libavcodec/mpeg4videoenc.c deleted file mode 100644 index 79190f0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpeg4videoenc.c +++ /dev/null @@ -1,1352 +0,0 @@ -/* - * MPEG4 encoder. - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2010 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mpegvideo.h" -#include "h263.h" -#include "mpeg4video.h" - -//The uni_DCtab_* tables below contain unified bits+length tables to encode DC -//differences in mpeg4. Unified in the sense that the specification specifies -//this encoding in several steps. -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]; - -//unified encoding tables for run length encoding of coefficients -//unified in the sense that the specification specifies the encoding in several steps. -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]; -//#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 -*/ - - -/** - * Returns the number of bits that encoding the 8x8 block in block would need. - * @param[in] block_last_index last index in scantable order that refers to a non zero element in block. - */ -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; - - last= j; - } - } - - return rate; -} - - -/** - * Restores the ac coefficients in block that have been changed by decide_ac_pred(). - * This function also restores s->block_last_index. - * @param[in,out] block MB coefficients, these will be restored - * @param[in] dir ac prediction direction for each 8x8 block - * @param[out] st scantable for each 8x8 block - * @param[in] zigzag_last_index index refering to the last non zero coefficient in zigzag order - */ -static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], const int dir[6], uint8_t *st[6], const 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 ]; - } - } - } -} - -/** - * Returns the optimal value (0 or 1) for the ac_pred element for the given MB in mpeg4. - * This function will also update s->block_last_index and s->ac_val. - * @param[in,out] block MB coefficients, these will be updated if 1 is returned - * @param[in] dir ac prediction direction for each 8x8 block - * @param[out] st scantable for each 8x8 block - * @param[out] zigzag_last_index index refering to the last non zero coefficient in zigzag order - */ -static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], const 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]); - } - - if(score < 0){ - return 1; - }else{ - restore_ac_coeffs(s, block, dir, st, zigzag_last_index); - return 0; - } -} - -/** - * 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== FF_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_BIDIR; - } - } - } -} - - -/** - * 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 - /* DC will overflow if level is outside the [-255,255] range. */ - 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, ff_mpeg4_DCtab_lum[size][1], ff_mpeg4_DCtab_lum[size][0]); - } else { - /* chrominance */ - put_bits(&s->pb, ff_mpeg4_DCtab_chrom[size][1], ff_mpeg4_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 = &ff_mpeg4_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 = &ff_h263_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_sbits(ac_pb, 12, slevel); - 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; - 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; - len_tab = uni_mpeg4_intra_rl_len; - } else { - if(last_index<0) return 0; - i = 0; - 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; -} - -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); - } - } - } -} - -//FIXME this is duplicated to h263.c -static const int dquant_code[5]= {1,0,9,2,3}; - -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!=FF_B_TYPE ? &s->tex_pb : &s->pb; - PutBitContext * const dc_pb = s->data_partitioning && s->pict_type!=FF_I_TYPE ? &s->pb2 : &s->pb; - const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0; - - if (!s->mb_intra) { - int i, cbp; - - if(s->pict_type==FF_B_TYPE){ - static const int mb_type_table[8]= {-1, 3, 2, 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==FF_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!=FF_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, - ff_h263_inter_MCBPC_bits[cbpc], - ff_h263_inter_MCBPC_code[cbpc]); - - put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_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, - ff_h263_inter_MCBPC_bits[cbpc], - ff_h263_inter_MCBPC_code[cbpc]); - - put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_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, - ff_h263_inter_MCBPC_bits[cbpc+16], - ff_h263_inter_MCBPC_code[cbpc+16]); - put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_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); - }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 == FF_I_TYPE) { - if(s->dquant) cbpc+=4; - put_bits(&s->pb, - ff_h263_intra_MCBPC_bits[cbpc], - ff_h263_intra_MCBPC_code[cbpc]); - } else { - if(s->dquant) cbpc+=8; - put_bits(&s->pb, 1, 0); /* mb coded */ - put_bits(&s->pb, - ff_h263_inter_MCBPC_bits[cbpc + 4], - ff_h263_inter_MCBPC_code[cbpc + 4]); - } - put_bits(pb2, 1, s->ac_pred); - cbpy = cbp >> 2; - put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_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); - } -} - -/** - * 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<pict_type==FF_B_TYPE){ - ff_mpeg4_init_direct_mv(s); - }else{ - s->last_time_base= s->time_base; - s->time_base= s->time/s->avctx->time_base.den; - } -} - -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 (!CONFIG_MPEG4_ENCODER) return; - - 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 */ - } - - s->aspect_ratio_info= ff_h263_aspect_to_info(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==FF_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!=FF_B_TYPE; - - 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 == FF_P_TYPE - || (s->pict_type == FF_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 != FF_I_TYPE) - put_bits(&s->pb, 3, s->f_code); /* fcode_for */ - if (s->pict_type == FF_B_TYPE) - put_bits(&s->pb, 3, s->b_code); /* fcode_back */ -} - - -static void init_uni_dc_tab(void) -{ - int level, uni_code, uni_len; - - for(level=-256; level<256; level++){ - int size, v, l; - /* find number of bits */ - size = 0; - v = abs(level); - while (v) { - v >>= 1; - size++; - } - - if (level < 0) - l= (-level) ^ ((1 << size) - 1); - else - l= level; - - /* luminance */ - uni_code= ff_mpeg4_DCtab_lum[size][0]; - uni_len = ff_mpeg4_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= ff_mpeg4_DCtab_chrom[size][0]; - uni_len = ff_mpeg4_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; - - } -} - -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; - } - /* 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; - } - } - /* 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; - } - } - /* 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 av_cold int encode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - int ret; - static int done = 0; - - if((ret=MPV_encode_init(avctx)) < 0) - return ret; - - if (!done) { - done = 1; - - init_uni_dc_tab(); - - init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); - - init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len); - init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); - } - - 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; - } - return 0; -} - -void ff_mpeg4_init_partitions(MpegEncContext *s) -{ - uint8_t *start= put_bits_ptr(&s->pb); - uint8_t *end= s->pb.buf_end; - int size= end - start; - int pb_size = (((intptr_t)start + size/3)&(~3)) - (intptr_t)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==FF_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); -} - - -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 */ -} - -AVCodec mpeg4_encoder = { - "mpeg4", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(MpegEncContext), - encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .capabilities= CODEC_CAP_DELAY, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudio.c b/tizen/distrib/ffmpeg/libavcodec/mpegaudio.c deleted file mode 100644 index cba5299..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudio.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * MPEG Audio common code - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG Audio common code. - */ - -#include "mpegaudio.h" - - -/* bitrate is in kb/s */ -int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf) -{ - int ch_bitrate, table; - - ch_bitrate = bitrate / nb_channels; - if (!lsf) { - if ((freq == 48000 && ch_bitrate >= 56) || - (ch_bitrate >= 56 && ch_bitrate <= 80)) - table = 0; - else if (freq != 48000 && ch_bitrate >= 96) - table = 1; - else if (freq != 32000 && ch_bitrate <= 48) - table = 2; - else - table = 3; - } else { - table = 4; - } - return table; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudio.h b/tizen/distrib/ffmpeg/libavcodec/mpegaudio.h deleted file mode 100644 index 26ec2be..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudio.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * mpeg audio declarations for both encoder and decoder. - */ - -#ifndef AVCODEC_MPEGAUDIO_H -#define AVCODEC_MPEGAUDIO_H - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" - -#define CONFIG_AUDIO_NONSHORT 0 - -/* max frame size, in samples */ -#define MPA_FRAME_SIZE 1152 - -/* max compressed frame size */ -#define MPA_MAX_CODED_FRAME_SIZE 1792 - -#define MPA_MAX_CHANNELS 2 - -#define SBLIMIT 32 /* number of subbands */ - -#define MPA_STEREO 0 -#define MPA_JSTEREO 1 -#define MPA_DUAL 2 -#define MPA_MONO 3 - -/* header + layer + bitrate + freq + lsf/mpeg25 */ -#define SAME_HEADER_MASK \ - (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) - -#define MP3_MASK 0xFFFE0CCF - -#if CONFIG_MPEGAUDIO_HP -#define FRAC_BITS 23 /* fractional bits for sb_samples and dct */ -#define WFRAC_BITS 16 /* fractional bits for window */ -#else -#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */ -#define WFRAC_BITS 14 /* fractional bits for window */ -#endif - -#define FRAC_ONE (1 << FRAC_BITS) - -#define FIX(a) ((int)((a) * FRAC_ONE)) - -#if CONFIG_MPEGAUDIO_HP && CONFIG_AUDIO_NONSHORT -typedef int32_t OUT_INT; -#define OUT_MAX INT32_MAX -#define OUT_MIN INT32_MIN -#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 31) -#define OUT_FMT SAMPLE_FMT_S32 -#else -typedef int16_t OUT_INT; -#define OUT_MAX INT16_MAX -#define OUT_MIN INT16_MIN -#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15) -#define OUT_FMT SAMPLE_FMT_S16 -#endif - -#if FRAC_BITS <= 15 -typedef int16_t MPA_INT; -#else -typedef int32_t MPA_INT; -#endif - -#define BACKSTEP_SIZE 512 -#define EXTRABYTES 24 - -/* layer 3 "granule" */ -typedef struct GranuleDef { - uint8_t scfsi; - int part2_3_length; - int big_values; - int global_gain; - int scalefac_compress; - uint8_t block_type; - uint8_t switch_point; - int table_select[3]; - int subblock_gain[3]; - uint8_t scalefac_scale; - uint8_t count1table_select; - int region_size[3]; /* number of huffman codes in each region */ - int preflag; - int short_start, long_end; /* long/short band indexes */ - uint8_t scale_factors[40]; - int32_t sb_hybrid[SBLIMIT * 18]; /* 576 samples */ -} GranuleDef; - -#define MPA_DECODE_HEADER \ - int frame_size; \ - int error_protection; \ - int layer; \ - int sample_rate; \ - int sample_rate_index; /* between 0 and 8 */ \ - int bit_rate; \ - int nb_channels; \ - int mode; \ - int mode_ext; \ - int lsf; - -typedef struct MPADecodeHeader { - MPA_DECODE_HEADER -} MPADecodeHeader; - -typedef struct MPADecodeContext { - MPA_DECODE_HEADER - uint8_t last_buf[2*BACKSTEP_SIZE + EXTRABYTES]; - int last_buf_size; - /* next header (used in free format parsing) */ - uint32_t free_format_next_header; - GetBitContext gb; - GetBitContext in_gb; - DECLARE_ALIGNED(16, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512 * 2]; - int synth_buf_offset[MPA_MAX_CHANNELS]; - DECLARE_ALIGNED(16, int32_t, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT]; - int32_t mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */ - GranuleDef granules[2][2]; /* Used in Layer 3 */ -#ifdef DEBUG - int frame_count; -#endif - void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g); - int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3 - int dither_state; - int error_recognition; - AVCodecContext* avctx; -} MPADecodeContext; - -/* layer 3 huffman tables */ -typedef struct HuffTable { - int xsize; - const uint8_t *bits; - const uint16_t *codes; -} HuffTable; - -int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf); -int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bitrate); -extern MPA_INT ff_mpa_synth_window[]; -void ff_mpa_synth_init(MPA_INT *window); -void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, - MPA_INT *window, int *dither_state, - OUT_INT *samples, int incr, - int32_t sb_samples[SBLIMIT]); - -/* fast header check for resync */ -static inline int ff_mpa_check_header(uint32_t header){ - /* header */ - if ((header & 0xffe00000) != 0xffe00000) - return -1; - /* layer check */ - if ((header & (3<<17)) == 0) - return -1; - /* bit rate */ - if ((header & (0xf<<12)) == 0xf<<12) - return -1; - /* frequency */ - if ((header & (3<<10)) == 3<<10) - return -1; - return 0; -} - -#endif /* AVCODEC_MPEGAUDIO_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudio3.h b/tizen/distrib/ffmpeg/libavcodec/mpegaudio3.h deleted file mode 100644 index c374a59..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudio3.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* layer 3 "granule" */ -typedef struct GranuleDef { - uint8_t scfsi; - int part2_3_length; - int big_values; - int global_gain; - int scalefac_compress; - uint8_t block_type; - uint8_t switch_point; - int table_select[3]; - int subblock_gain[3]; - uint8_t scalefac_scale; - uint8_t count1table_select; - int region_size[3]; /* number of huffman codes in each region */ - int preflag; - int short_start, long_end; /* long/short band indexes */ - uint8_t scale_factors[40]; - int32_t sb_hybrid[SBLIMIT * 18]; /* 576 samples */ -} GranuleDef; - -void ff_mp3_init(void); - -/** - * Compute huffman coded region sizes. - */ -void ff_init_short_region(MPADecodeContext *s, GranuleDef *g); - -/** - * Compute huffman coded region sizes. - */ -void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2); - -void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g); diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudio_parser.c b/tizen/distrib/ffmpeg/libavcodec/mpegaudio_parser.c deleted file mode 100644 index 6d7ab8a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudio_parser.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * MPEG Audio parser - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" -#include "mpegaudio.h" -#include "mpegaudiodecheader.h" - - -typedef struct MpegAudioParseContext { - ParseContext pc; - int frame_size; - uint32_t header; - int header_count; -} MpegAudioParseContext; - -#define MPA_HEADER_SIZE 4 - -/* header + layer + bitrate + freq + lsf/mpeg25 */ -#undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ -#define SAME_HEADER_MASK \ - (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) - -/* useful helper to get mpeg audio stream infos. Return -1 if error in - header, otherwise the coded frame size in bytes */ -int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate) -{ - MPADecodeHeader s1, *s = &s1; - - if (ff_mpa_check_header(head) != 0) - return -1; - - if (ff_mpegaudio_decode_header(s, head) != 0) { - return -1; - } - - switch(s->layer) { - case 1: - avctx->codec_id = CODEC_ID_MP1; - *frame_size = 384; - break; - case 2: - avctx->codec_id = CODEC_ID_MP2; - *frame_size = 1152; - break; - default: - case 3: - avctx->codec_id = CODEC_ID_MP3; - if (s->lsf) - *frame_size = 576; - else - *frame_size = 1152; - break; - } - - *sample_rate = s->sample_rate; - *channels = s->nb_channels; - *bit_rate = s->bit_rate; - avctx->sub_id = s->layer; - return s->frame_size; -} - -static int mpegaudio_parse(AVCodecParserContext *s1, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - MpegAudioParseContext *s = s1->priv_data; - ParseContext *pc = &s->pc; - uint32_t state= pc->state; - int i; - int next= END_NOT_FOUND; - - for(i=0; iframe_size){ - int inc= FFMIN(buf_size - i, s->frame_size); - i += inc; - s->frame_size -= inc; - - if(!s->frame_size){ - next= i; - break; - } - }else{ - while(iheader_count= -2; - } else { - if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) - s->header_count= -3; - s->header= state; - s->header_count++; - s->frame_size = ret-4; - - if(s->header_count > 1){ - avctx->sample_rate= sr; - avctx->channels = channels; - avctx->frame_size = frame_size; - avctx->bit_rate = bit_rate; - } - break; - } - } - } - } - - pc->state= state; - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - - -AVCodecParser mpegaudio_parser = { - { CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3 }, - sizeof(MpegAudioParseContext), - NULL, - mpegaudio_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.c b/tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.c deleted file mode 100644 index 70d145b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Generate a header file for hardcoded mpegaudiodec tables - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#define CONFIG_HARDCODED_TABLES 0 -#include "mpegaudio_tablegen.h" -#include "tableprint.h" - -int main(void) -{ - mpegaudio_tableinit(); - - write_fileheader(); - - printf("static const int8_t table_4_3_exp[TABLE_4_3_SIZE] = {\n"); - write_int8_array(table_4_3_exp, TABLE_4_3_SIZE); - printf("};\n"); - - printf("static const uint32_t table_4_3_value[TABLE_4_3_SIZE] = {\n"); - write_uint32_array(table_4_3_value, TABLE_4_3_SIZE); - printf("};\n"); - - printf("static const uint32_t exp_table[512] = {\n"); - write_uint32_array(exp_table, 512); - printf("};\n"); - - printf("static const uint32_t expval_table[512][16] = {\n"); - write_uint32_2d_array(expval_table, 512, 16); - printf("};\n"); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.h b/tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.h deleted file mode 100644 index 9d056cb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudio_tablegen.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Header file for hardcoded mpegaudiodec tables - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MPEGAUDIO_TABLEGEN_H -#define MPEGAUDIO_TABLEGEN_H - -#include -// do not use libavutil/mathematics.h since this is compiled both -// for the host and the target and config.h is only valid for the target -#include - -#define TABLE_4_3_SIZE (8191 + 16)*4 -#if CONFIG_HARDCODED_TABLES -#define mpegaudio_tableinit() -#include "libavcodec/mpegaudio_tables.h" -#else -static int8_t table_4_3_exp[TABLE_4_3_SIZE]; -static uint32_t table_4_3_value[TABLE_4_3_SIZE]; -static uint32_t exp_table[512]; -static uint32_t expval_table[512][16]; - -static void mpegaudio_tableinit(void) -{ - int i, value, exponent; - for (i = 1; i < TABLE_4_3_SIZE; i++) { - double value = i / 4; - double f, fm; - int e, m; - f = value * cbrtf(value) * pow(2, (i & 3) * 0.25); - fm = frexp(f, &e); - m = (uint32_t)(fm * (1LL << 31) + 0.5); - e += FRAC_BITS - 31 + 5 - 100; - - /* normalized to FRAC_BITS */ - table_4_3_value[i] = m; - table_4_3_exp[i] = -e; - } - for (exponent = 0; exponent < 512; exponent++) { - for (value = 0; value < 16; value++) { - double f = (double)value * cbrtf(value) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5); - expval_table[exponent][value] = llrint(f); - } - exp_table[exponent] = expval_table[exponent][1]; - } -} -#endif /* CONFIG_HARDCODED_TABLES */ - -#endif /* MPEGAUDIO_TABLEGEN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.c b/tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.c deleted file mode 100644 index c9dabf3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * MPEG Audio common tables - * copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * mpeg audio layer common tables. - */ - -#include "mpegaudiodata.h" - - -const uint16_t ff_mpa_bitrate_tab[2][3][15] = { - { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, - { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} - } -}; - -const uint16_t ff_mpa_freq_tab[3] = { 44100, 48000, 32000 }; - -/*******************************************************/ -/* half mpeg encoding window (full precision) */ -const int32_t ff_mpa_enwindow[257] = { - 0, -1, -1, -1, -1, -1, -1, -2, - -2, -2, -2, -3, -3, -4, -4, -5, - -5, -6, -7, -7, -8, -9, -10, -11, - -13, -14, -16, -17, -19, -21, -24, -26, - -29, -31, -35, -38, -41, -45, -49, -53, - -58, -63, -68, -73, -79, -85, -91, -97, - -104, -111, -117, -125, -132, -139, -147, -154, - -161, -169, -176, -183, -190, -196, -202, -208, - 213, 218, 222, 225, 227, 228, 228, 227, - 224, 221, 215, 208, 200, 189, 177, 163, - 146, 127, 106, 83, 57, 29, -2, -36, - -72, -111, -153, -197, -244, -294, -347, -401, - -459, -519, -581, -645, -711, -779, -848, -919, - -991, -1064, -1137, -1210, -1283, -1356, -1428, -1498, - -1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962, - -2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063, - 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535, - 1414, 1280, 1131, 970, 794, 605, 402, 185, - -45, -288, -545, -814, -1095, -1388, -1692, -2006, - -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, - -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, - -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585, - -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750, - -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134, - 6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082, - 70, -998, -2122, -3300, -4533, -5818, -7154, -8540, - -9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189, --22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640, --37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137, --51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684, --64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420, --72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992, - 75038, -}; - -/*******************************************************/ -/* layer 2 tables */ - -const int ff_mpa_sblimit_table[5] = { 27 , 30 , 8, 12 , 30 }; - -const int ff_mpa_quant_steps[17] = { - 3, 5, 7, 9, 15, - 31, 63, 127, 255, 511, - 1023, 2047, 4095, 8191, 16383, - 32767, 65535 -}; - -/* we use a negative value if grouped */ -const int ff_mpa_quant_bits[17] = { - -5, -7, 3, -10, 4, - 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, - 15, 16 -}; - -/* encoding tables which give the quantization index. Note how it is - possible to store them efficiently ! */ -static const unsigned char alloc_table_1[] = { - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, -}; - -static const unsigned char alloc_table_3[] = { - 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, -}; - -static const unsigned char alloc_table_4[] = { - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, -}; - -const unsigned char * const ff_mpa_alloc_tables[5] = -{ alloc_table_1, alloc_table_1, alloc_table_3, alloc_table_3, alloc_table_4, }; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.h b/tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.h deleted file mode 100644 index 5626e3d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodata.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * MPEG Audio common tables - * copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * mpeg audio layer common tables. - */ - -#ifndef AVCODEC_MPEGAUDIODATA_H -#define AVCODEC_MPEGAUDIODATA_H - -#include "libavutil/common.h" - -#define MODE_EXT_MS_STEREO 2 -#define MODE_EXT_I_STEREO 1 - -extern const uint16_t ff_mpa_bitrate_tab[2][3][15]; -extern const uint16_t ff_mpa_freq_tab[3]; -extern const int32_t ff_mpa_enwindow[257]; -extern const int ff_mpa_sblimit_table[5]; -extern const int ff_mpa_quant_steps[17]; -extern const int ff_mpa_quant_bits[17]; -extern const unsigned char * const ff_mpa_alloc_tables[5]; - -#endif /* AVCODEC_MPEGAUDIODATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodec.c b/tizen/distrib/ffmpeg/libavcodec/mpegaudiodec.c deleted file mode 100644 index 25fad80..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodec.c +++ /dev/null @@ -1,2571 +0,0 @@ -/* - * MPEG Audio decoder - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG Audio decoder. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" - -/* - * TODO: - * - in low precision mode, use more 16 bit multiplies in synth filter - * - test lsf / mpeg25 extensively. - */ - -#include "mpegaudio.h" -#include "mpegaudiodecheader.h" - -#include "mathops.h" - -/* WARNING: only correct for posititive numbers */ -#define FIXR(a) ((int)((a) * FRAC_ONE + 0.5)) -#define FRAC_RND(a) (((a) + (FRAC_ONE/2)) >> FRAC_BITS) - -#define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5)) - -/****************/ - -#define HEADER_SIZE 4 - -#include "mpegaudiodata.h" -#include "mpegaudiodectab.h" - -static void compute_antialias_integer(MPADecodeContext *s, GranuleDef *g); -static void compute_antialias_float(MPADecodeContext *s, GranuleDef *g); - -/* vlc structure for decoding layer 3 huffman tables */ -static VLC huff_vlc[16]; -static VLC_TYPE huff_vlc_tables[ - 0+128+128+128+130+128+154+166+ - 142+204+190+170+542+460+662+414 - ][2]; -static const int huff_vlc_tables_sizes[16] = { - 0, 128, 128, 128, 130, 128, 154, 166, - 142, 204, 190, 170, 542, 460, 662, 414 -}; -static VLC huff_quad_vlc[2]; -static VLC_TYPE huff_quad_vlc_tables[128+16][2]; -static const int huff_quad_vlc_tables_sizes[2] = { - 128, 16 -}; -/* computed from band_size_long */ -static uint16_t band_index_long[9][23]; -#include "mpegaudio_tablegen.h" -/* intensity stereo coef table */ -static int32_t is_table[2][16]; -static int32_t is_table_lsf[2][2][16]; -static int32_t csa_table[8][4]; -static float csa_table_float[8][4]; -static int32_t mdct_win[8][36]; - -/* lower 2 bits: modulo 3, higher bits: shift */ -static uint16_t scale_factor_modshift[64]; -/* [i][j]: 2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */ -static int32_t scale_factor_mult[15][3]; -/* mult table for layer 2 group quantization */ - -#define SCALE_GEN(v) \ -{ FIXR(1.0 * (v)), FIXR(0.7937005259 * (v)), FIXR(0.6299605249 * (v)) } - -static const int32_t scale_factor_mult2[3][3] = { - SCALE_GEN(4.0 / 3.0), /* 3 steps */ - SCALE_GEN(4.0 / 5.0), /* 5 steps */ - SCALE_GEN(4.0 / 9.0), /* 9 steps */ -}; - -DECLARE_ALIGNED(16, MPA_INT, ff_mpa_synth_window)[512]; - -/** - * Convert region offsets to region sizes and truncate - * size to big_values. - */ -static void ff_region_offset2size(GranuleDef *g){ - int i, k, j=0; - g->region_size[2] = (576 / 2); - for(i=0;i<3;i++) { - k = FFMIN(g->region_size[i], g->big_values); - g->region_size[i] = k - j; - j = k; - } -} - -static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){ - if (g->block_type == 2) - g->region_size[0] = (36 / 2); - else { - if (s->sample_rate_index <= 2) - g->region_size[0] = (36 / 2); - else if (s->sample_rate_index != 8) - g->region_size[0] = (54 / 2); - else - g->region_size[0] = (108 / 2); - } - g->region_size[1] = (576 / 2); -} - -static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2){ - int l; - g->region_size[0] = - band_index_long[s->sample_rate_index][ra1 + 1] >> 1; - /* should not overflow */ - l = FFMIN(ra1 + ra2 + 2, 22); - g->region_size[1] = - band_index_long[s->sample_rate_index][l] >> 1; -} - -static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){ - if (g->block_type == 2) { - if (g->switch_point) { - /* if switched mode, we handle the 36 first samples as - long blocks. For 8000Hz, we handle the 48 first - exponents as long blocks (XXX: check this!) */ - if (s->sample_rate_index <= 2) - g->long_end = 8; - else if (s->sample_rate_index != 8) - g->long_end = 6; - else - g->long_end = 4; /* 8000 Hz */ - - g->short_start = 2 + (s->sample_rate_index != 8); - } else { - g->long_end = 0; - g->short_start = 0; - } - } else { - g->short_start = 13; - g->long_end = 22; - } -} - -/* layer 1 unscaling */ -/* n = number of bits of the mantissa minus 1 */ -static inline int l1_unscale(int n, int mant, int scale_factor) -{ - int shift, mod; - int64_t val; - - shift = scale_factor_modshift[scale_factor]; - mod = shift & 3; - shift >>= 2; - val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]); - shift += n; - /* NOTE: at this point, 1 <= shift >= 21 + 15 */ - return (int)((val + (1LL << (shift - 1))) >> shift); -} - -static inline int l2_unscale_group(int steps, int mant, int scale_factor) -{ - int shift, mod, val; - - shift = scale_factor_modshift[scale_factor]; - mod = shift & 3; - shift >>= 2; - - val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod]; - /* NOTE: at this point, 0 <= shift <= 21 */ - if (shift > 0) - val = (val + (1 << (shift - 1))) >> shift; - return val; -} - -/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */ -static inline int l3_unscale(int value, int exponent) -{ - unsigned int m; - int e; - - e = table_4_3_exp [4*value + (exponent&3)]; - m = table_4_3_value[4*value + (exponent&3)]; - e -= (exponent >> 2); - assert(e>=1); - if (e > 31) - return 0; - m = (m + (1 << (e-1))) >> e; - - return m; -} - -/* all integer n^(4/3) computation code */ -#define DEV_ORDER 13 - -#define POW_FRAC_BITS 24 -#define POW_FRAC_ONE (1 << POW_FRAC_BITS) -#define POW_FIX(a) ((int)((a) * POW_FRAC_ONE)) -#define POW_MULL(a,b) (((int64_t)(a) * (int64_t)(b)) >> POW_FRAC_BITS) - -static int dev_4_3_coefs[DEV_ORDER]; - -#if 0 /* unused */ -static int pow_mult3[3] = { - POW_FIX(1.0), - POW_FIX(1.25992104989487316476), - POW_FIX(1.58740105196819947474), -}; -#endif - -static av_cold void int_pow_init(void) -{ - int i, a; - - a = POW_FIX(1.0); - for(i=0;i= 0; j--) - a1 = POW_MULL(a, dev_4_3_coefs[j] + a1); - a = (1 << POW_FRAC_BITS) + a1; - /* exponent compute (exact) */ - e = e * 4; - er = e % 3; - eq = e / 3; - a = POW_MULL(a, pow_mult3[er]); - while (a >= 2 * POW_FRAC_ONE) { - a = a >> 1; - eq++; - } - /* convert to float */ - while (a < POW_FRAC_ONE) { - a = a << 1; - eq--; - } - /* now POW_FRAC_ONE <= a < 2 * POW_FRAC_ONE */ -#if POW_FRAC_BITS > FRAC_BITS - a = (a + (1 << (POW_FRAC_BITS - FRAC_BITS - 1))) >> (POW_FRAC_BITS - FRAC_BITS); - /* correct overflow */ - if (a >= 2 * (1 << FRAC_BITS)) { - a = a >> 1; - eq++; - } -#endif - *exp_ptr = eq; - return a; -} -#endif - -static av_cold int decode_init(AVCodecContext * avctx) -{ - MPADecodeContext *s = avctx->priv_data; - static int init=0; - int i, j, k; - - s->avctx = avctx; - - avctx->sample_fmt= OUT_FMT; - s->error_recognition= avctx->error_recognition; - - if(avctx->antialias_algo != FF_AA_FLOAT) - s->compute_antialias= compute_antialias_integer; - else - s->compute_antialias= compute_antialias_float; - - if (!init && !avctx->parse_only) { - int offset; - - /* scale factors table for layer 1/2 */ - for(i=0;i<64;i++) { - int shift, mod; - /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */ - shift = (i / 3); - mod = i % 3; - scale_factor_modshift[i] = mod | (shift << 2); - } - - /* scale factor multiply for layer 1 */ - for(i=0;i<15;i++) { - int n, norm; - n = i + 2; - norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1); - scale_factor_mult[i][0] = MULL(FIXR(1.0 * 2.0), norm, FRAC_BITS); - scale_factor_mult[i][1] = MULL(FIXR(0.7937005259 * 2.0), norm, FRAC_BITS); - scale_factor_mult[i][2] = MULL(FIXR(0.6299605249 * 2.0), norm, FRAC_BITS); - dprintf(avctx, "%d: norm=%x s=%x %x %x\n", - i, norm, - scale_factor_mult[i][0], - scale_factor_mult[i][1], - scale_factor_mult[i][2]); - } - - ff_mpa_synth_init(ff_mpa_synth_window); - - /* huffman decode tables */ - offset = 0; - for(i=1;i<16;i++) { - const HuffTable *h = &mpa_huff_tables[i]; - int xsize, x, y; - uint8_t tmp_bits [512]; - uint16_t tmp_codes[512]; - - memset(tmp_bits , 0, sizeof(tmp_bits )); - memset(tmp_codes, 0, sizeof(tmp_codes)); - - xsize = h->xsize; - - j = 0; - for(x=0;xbits [j ]; - tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++]; - } - } - - /* XXX: fail test */ - huff_vlc[i].table = huff_vlc_tables+offset; - huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i]; - init_vlc(&huff_vlc[i], 7, 512, - tmp_bits, 1, 1, tmp_codes, 2, 2, - INIT_VLC_USE_NEW_STATIC); - offset += huff_vlc_tables_sizes[i]; - } - assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables)); - - offset = 0; - for(i=0;i<2;i++) { - huff_quad_vlc[i].table = huff_quad_vlc_tables+offset; - huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i]; - init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16, - mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1, - INIT_VLC_USE_NEW_STATIC); - offset += huff_quad_vlc_tables_sizes[i]; - } - assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables)); - - for(i=0;i<9;i++) { - k = 0; - for(j=0;j<22;j++) { - band_index_long[i][j] = k; - k += band_size_long[i][j]; - } - band_index_long[i][22] = k; - } - - /* compute n ^ (4/3) and store it in mantissa/exp format */ - - int_pow_init(); - mpegaudio_tableinit(); - - for(i=0;i<7;i++) { - float f; - int v; - if (i != 6) { - f = tan((double)i * M_PI / 12.0); - v = FIXR(f / (1.0 + f)); - } else { - v = FIXR(1.0); - } - is_table[0][i] = v; - is_table[1][6 - i] = v; - } - /* invalid values */ - for(i=7;i<16;i++) - is_table[0][i] = is_table[1][i] = 0.0; - - for(i=0;i<16;i++) { - double f; - int e, k; - - for(j=0;j<2;j++) { - e = -(j + 1) * ((i + 1) >> 1); - f = pow(2.0, e / 4.0); - k = i & 1; - is_table_lsf[j][k ^ 1][i] = FIXR(f); - is_table_lsf[j][k][i] = FIXR(1.0); - dprintf(avctx, "is_table_lsf %d %d: %x %x\n", - i, j, is_table_lsf[j][0][i], is_table_lsf[j][1][i]); - } - } - - for(i=0;i<8;i++) { - float ci, cs, ca; - ci = ci_table[i]; - cs = 1.0 / sqrt(1.0 + ci * ci); - ca = cs * ci; - csa_table[i][0] = FIXHR(cs/4); - csa_table[i][1] = FIXHR(ca/4); - csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4); - csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4); - csa_table_float[i][0] = cs; - csa_table_float[i][1] = ca; - csa_table_float[i][2] = ca + cs; - csa_table_float[i][3] = ca - cs; - } - - /* compute mdct windows */ - for(i=0;i<36;i++) { - for(j=0; j<4; j++){ - double d; - - if(j==2 && i%3 != 1) - continue; - - d= sin(M_PI * (i + 0.5) / 36.0); - if(j==1){ - if (i>=30) d= 0; - else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0); - else if(i>=18) d= 1; - }else if(j==3){ - if (i< 6) d= 0; - else if(i< 12) d= sin(M_PI * (i - 6 + 0.5) / 12.0); - else if(i< 18) d= 1; - } - //merge last stage of imdct into the window coefficients - d*= 0.5 / cos(M_PI*(2*i + 19)/72); - - if(j==2) - mdct_win[j][i/3] = FIXHR((d / (1<<5))); - else - mdct_win[j][i ] = FIXHR((d / (1<<5))); - } - } - - /* NOTE: we do frequency inversion adter the MDCT by changing - the sign of the right window coefs */ - for(j=0;j<4;j++) { - for(i=0;i<36;i+=2) { - mdct_win[j + 4][i] = mdct_win[j][i]; - mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1]; - } - } - - init = 1; - } - - if (avctx->codec_id == CODEC_ID_MP3ADU) - s->adu_mode = 1; - return 0; -} - -/* tab[i][j] = 1.0 / (2.0 * cos(pi*(2*k+1) / 2^(6 - j))) */ - -/* cos(i*pi/64) */ - -#define COS0_0 FIXHR(0.50060299823519630134/2) -#define COS0_1 FIXHR(0.50547095989754365998/2) -#define COS0_2 FIXHR(0.51544730992262454697/2) -#define COS0_3 FIXHR(0.53104259108978417447/2) -#define COS0_4 FIXHR(0.55310389603444452782/2) -#define COS0_5 FIXHR(0.58293496820613387367/2) -#define COS0_6 FIXHR(0.62250412303566481615/2) -#define COS0_7 FIXHR(0.67480834145500574602/2) -#define COS0_8 FIXHR(0.74453627100229844977/2) -#define COS0_9 FIXHR(0.83934964541552703873/2) -#define COS0_10 FIXHR(0.97256823786196069369/2) -#define COS0_11 FIXHR(1.16943993343288495515/4) -#define COS0_12 FIXHR(1.48416461631416627724/4) -#define COS0_13 FIXHR(2.05778100995341155085/8) -#define COS0_14 FIXHR(3.40760841846871878570/8) -#define COS0_15 FIXHR(10.19000812354805681150/32) - -#define COS1_0 FIXHR(0.50241928618815570551/2) -#define COS1_1 FIXHR(0.52249861493968888062/2) -#define COS1_2 FIXHR(0.56694403481635770368/2) -#define COS1_3 FIXHR(0.64682178335999012954/2) -#define COS1_4 FIXHR(0.78815462345125022473/2) -#define COS1_5 FIXHR(1.06067768599034747134/4) -#define COS1_6 FIXHR(1.72244709823833392782/4) -#define COS1_7 FIXHR(5.10114861868916385802/16) - -#define COS2_0 FIXHR(0.50979557910415916894/2) -#define COS2_1 FIXHR(0.60134488693504528054/2) -#define COS2_2 FIXHR(0.89997622313641570463/2) -#define COS2_3 FIXHR(2.56291544774150617881/8) - -#define COS3_0 FIXHR(0.54119610014619698439/2) -#define COS3_1 FIXHR(1.30656296487637652785/4) - -#define COS4_0 FIXHR(0.70710678118654752439/2) - -/* butterfly operator */ -#define BF(a, b, c, s)\ -{\ - tmp0 = tab[a] + tab[b];\ - tmp1 = tab[a] - tab[b];\ - tab[a] = tmp0;\ - tab[b] = MULH(tmp1<<(s), c);\ -} - -#define BF1(a, b, c, d)\ -{\ - BF(a, b, COS4_0, 1);\ - BF(c, d,-COS4_0, 1);\ - tab[c] += tab[d];\ -} - -#define BF2(a, b, c, d)\ -{\ - BF(a, b, COS4_0, 1);\ - BF(c, d,-COS4_0, 1);\ - tab[c] += tab[d];\ - tab[a] += tab[c];\ - tab[c] += tab[b];\ - tab[b] += tab[d];\ -} - -#define ADD(a, b) tab[a] += tab[b] - -/* DCT32 without 1/sqrt(2) coef zero scaling. */ -static void dct32(int32_t *out, int32_t *tab) -{ - int tmp0, tmp1; - - /* pass 1 */ - BF( 0, 31, COS0_0 , 1); - BF(15, 16, COS0_15, 5); - /* pass 2 */ - BF( 0, 15, COS1_0 , 1); - BF(16, 31,-COS1_0 , 1); - /* pass 1 */ - BF( 7, 24, COS0_7 , 1); - BF( 8, 23, COS0_8 , 1); - /* pass 2 */ - BF( 7, 8, COS1_7 , 4); - BF(23, 24,-COS1_7 , 4); - /* pass 3 */ - BF( 0, 7, COS2_0 , 1); - BF( 8, 15,-COS2_0 , 1); - BF(16, 23, COS2_0 , 1); - BF(24, 31,-COS2_0 , 1); - /* pass 1 */ - BF( 3, 28, COS0_3 , 1); - BF(12, 19, COS0_12, 2); - /* pass 2 */ - BF( 3, 12, COS1_3 , 1); - BF(19, 28,-COS1_3 , 1); - /* pass 1 */ - BF( 4, 27, COS0_4 , 1); - BF(11, 20, COS0_11, 2); - /* pass 2 */ - BF( 4, 11, COS1_4 , 1); - BF(20, 27,-COS1_4 , 1); - /* pass 3 */ - BF( 3, 4, COS2_3 , 3); - BF(11, 12,-COS2_3 , 3); - BF(19, 20, COS2_3 , 3); - BF(27, 28,-COS2_3 , 3); - /* pass 4 */ - BF( 0, 3, COS3_0 , 1); - BF( 4, 7,-COS3_0 , 1); - BF( 8, 11, COS3_0 , 1); - BF(12, 15,-COS3_0 , 1); - BF(16, 19, COS3_0 , 1); - BF(20, 23,-COS3_0 , 1); - BF(24, 27, COS3_0 , 1); - BF(28, 31,-COS3_0 , 1); - - - - /* pass 1 */ - BF( 1, 30, COS0_1 , 1); - BF(14, 17, COS0_14, 3); - /* pass 2 */ - BF( 1, 14, COS1_1 , 1); - BF(17, 30,-COS1_1 , 1); - /* pass 1 */ - BF( 6, 25, COS0_6 , 1); - BF( 9, 22, COS0_9 , 1); - /* pass 2 */ - BF( 6, 9, COS1_6 , 2); - BF(22, 25,-COS1_6 , 2); - /* pass 3 */ - BF( 1, 6, COS2_1 , 1); - BF( 9, 14,-COS2_1 , 1); - BF(17, 22, COS2_1 , 1); - BF(25, 30,-COS2_1 , 1); - - /* pass 1 */ - BF( 2, 29, COS0_2 , 1); - BF(13, 18, COS0_13, 3); - /* pass 2 */ - BF( 2, 13, COS1_2 , 1); - BF(18, 29,-COS1_2 , 1); - /* pass 1 */ - BF( 5, 26, COS0_5 , 1); - BF(10, 21, COS0_10, 1); - /* pass 2 */ - BF( 5, 10, COS1_5 , 2); - BF(21, 26,-COS1_5 , 2); - /* pass 3 */ - BF( 2, 5, COS2_2 , 1); - BF(10, 13,-COS2_2 , 1); - BF(18, 21, COS2_2 , 1); - BF(26, 29,-COS2_2 , 1); - /* pass 4 */ - BF( 1, 2, COS3_1 , 2); - BF( 5, 6,-COS3_1 , 2); - BF( 9, 10, COS3_1 , 2); - BF(13, 14,-COS3_1 , 2); - BF(17, 18, COS3_1 , 2); - BF(21, 22,-COS3_1 , 2); - BF(25, 26, COS3_1 , 2); - BF(29, 30,-COS3_1 , 2); - - /* pass 5 */ - BF1( 0, 1, 2, 3); - BF2( 4, 5, 6, 7); - BF1( 8, 9, 10, 11); - BF2(12, 13, 14, 15); - BF1(16, 17, 18, 19); - BF2(20, 21, 22, 23); - BF1(24, 25, 26, 27); - BF2(28, 29, 30, 31); - - /* pass 6 */ - - ADD( 8, 12); - ADD(12, 10); - ADD(10, 14); - ADD(14, 9); - ADD( 9, 13); - ADD(13, 11); - ADD(11, 15); - - out[ 0] = tab[0]; - out[16] = tab[1]; - out[ 8] = tab[2]; - out[24] = tab[3]; - out[ 4] = tab[4]; - out[20] = tab[5]; - out[12] = tab[6]; - out[28] = tab[7]; - out[ 2] = tab[8]; - out[18] = tab[9]; - out[10] = tab[10]; - out[26] = tab[11]; - out[ 6] = tab[12]; - out[22] = tab[13]; - out[14] = tab[14]; - out[30] = tab[15]; - - ADD(24, 28); - ADD(28, 26); - ADD(26, 30); - ADD(30, 25); - ADD(25, 29); - ADD(29, 27); - ADD(27, 31); - - out[ 1] = tab[16] + tab[24]; - out[17] = tab[17] + tab[25]; - out[ 9] = tab[18] + tab[26]; - out[25] = tab[19] + tab[27]; - out[ 5] = tab[20] + tab[28]; - out[21] = tab[21] + tab[29]; - out[13] = tab[22] + tab[30]; - out[29] = tab[23] + tab[31]; - out[ 3] = tab[24] + tab[20]; - out[19] = tab[25] + tab[21]; - out[11] = tab[26] + tab[22]; - out[27] = tab[27] + tab[23]; - out[ 7] = tab[28] + tab[18]; - out[23] = tab[29] + tab[19]; - out[15] = tab[30] + tab[17]; - out[31] = tab[31]; -} - -#if FRAC_BITS <= 15 - -static inline int round_sample(int *sum) -{ - int sum1; - sum1 = (*sum) >> OUT_SHIFT; - *sum &= (1< 32 multiply add accumulate */ -#define MACS(rt, ra, rb) MAC16(rt, ra, rb) - -/* signed 16x16 -> 32 multiply */ -#define MULS(ra, rb) MUL16(ra, rb) - -#define MLSS(rt, ra, rb) MLS16(rt, ra, rb) - -#else - -static inline int round_sample(int64_t *sum) -{ - int sum1; - sum1 = (int)((*sum) >> OUT_SHIFT); - *sum &= (1<> (16 - WFRAC_BITS); -#endif - window[i] = v; - if ((i & 63) != 0) - v = -v; - if (i != 0) - window[512 - i] = v; - } -} - -/* 32 sub band synthesis filter. Input: 32 sub band samples, Output: - 32 samples. */ -/* XXX: optimize by avoiding ring buffer usage */ -void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, - MPA_INT *window, int *dither_state, - OUT_INT *samples, int incr, - int32_t sb_samples[SBLIMIT]) -{ - register MPA_INT *synth_buf; - register const MPA_INT *w, *w2, *p; - int j, offset; - OUT_INT *samples2; -#if FRAC_BITS <= 15 - int32_t tmp[32]; - int sum, sum2; -#else - int64_t sum, sum2; -#endif - - offset = *synth_buf_offset; - synth_buf = synth_buf_ptr + offset; - -#if FRAC_BITS <= 15 - dct32(tmp, sb_samples); - for(j=0;j<32;j++) { - /* NOTE: can cause a loss in precision if very high amplitude - sound */ - synth_buf[j] = av_clip_int16(tmp[j]); - } -#else - dct32(synth_buf, sb_samples); -#endif - - /* copy to avoid wrap */ - memcpy(synth_buf + 512, synth_buf, 32 * sizeof(MPA_INT)); - - samples2 = samples + 31 * incr; - w = window; - w2 = window + 31; - - sum = *dither_state; - p = synth_buf + 16; - SUM8(MACS, sum, w, p); - p = synth_buf + 48; - SUM8(MLSS, sum, w + 32, p); - *samples = round_sample(&sum); - samples += incr; - w++; - - /* we calculate two samples at the same time to avoid one memory - access per two sample */ - for(j=1;j<16;j++) { - sum2 = 0; - p = synth_buf + 16 + j; - SUM8P2(sum, MACS, sum2, MLSS, w, w2, p); - p = synth_buf + 48 - j; - SUM8P2(sum, MLSS, sum2, MLSS, w + 32, w2 + 32, p); - - *samples = round_sample(&sum); - samples += incr; - sum += sum2; - *samples2 = round_sample(&sum); - samples2 -= incr; - w++; - w2--; - } - - p = synth_buf + 32; - SUM8(MLSS, sum, w + 32, p); - *samples = round_sample(&sum); - *dither_state= sum; - - offset = (offset - 32) & 511; - *synth_buf_offset = offset; -} - -#define C3 FIXHR(0.86602540378443864676/2) - -/* 0.5 / cos(pi*(2*i+1)/36) */ -static const int icos36[9] = { - FIXR(0.50190991877167369479), - FIXR(0.51763809020504152469), //0 - FIXR(0.55168895948124587824), - FIXR(0.61038729438072803416), - FIXR(0.70710678118654752439), //1 - FIXR(0.87172339781054900991), - FIXR(1.18310079157624925896), - FIXR(1.93185165257813657349), //2 - FIXR(5.73685662283492756461), -}; - -/* 0.5 / cos(pi*(2*i+1)/36) */ -static const int icos36h[9] = { - FIXHR(0.50190991877167369479/2), - FIXHR(0.51763809020504152469/2), //0 - FIXHR(0.55168895948124587824/2), - FIXHR(0.61038729438072803416/2), - FIXHR(0.70710678118654752439/2), //1 - FIXHR(0.87172339781054900991/2), - FIXHR(1.18310079157624925896/4), - FIXHR(1.93185165257813657349/4), //2 -// FIXHR(5.73685662283492756461), -}; - -/* 12 points IMDCT. We compute it "by hand" by factorizing obvious - cases. */ -static void imdct12(int *out, int *in) -{ - int in0, in1, in2, in3, in4, in5, t1, t2; - - in0= in[0*3]; - in1= in[1*3] + in[0*3]; - in2= in[2*3] + in[1*3]; - in3= in[3*3] + in[2*3]; - in4= in[4*3] + in[3*3]; - in5= in[5*3] + in[4*3]; - in5 += in3; - in3 += in1; - - in2= MULH(2*in2, C3); - in3= MULH(4*in3, C3); - - t1 = in0 - in4; - t2 = MULH(2*(in1 - in5), icos36h[4]); - - out[ 7]= - out[10]= t1 + t2; - out[ 1]= - out[ 4]= t1 - t2; - - in0 += in4>>1; - in4 = in0 + in2; - in5 += 2*in1; - in1 = MULH(in5 + in3, icos36h[1]); - out[ 8]= - out[ 9]= in4 + in1; - out[ 2]= - out[ 3]= in4 - in1; - - in0 -= in2; - in5 = MULH(2*(in5 - in3), icos36h[7]); - out[ 0]= - out[ 5]= in0 - in5; - out[ 6]= - out[11]= in0 + in5; -} - -/* cos(pi*i/18) */ -#define C1 FIXHR(0.98480775301220805936/2) -#define C2 FIXHR(0.93969262078590838405/2) -#define C3 FIXHR(0.86602540378443864676/2) -#define C4 FIXHR(0.76604444311897803520/2) -#define C5 FIXHR(0.64278760968653932632/2) -#define C6 FIXHR(0.5/2) -#define C7 FIXHR(0.34202014332566873304/2) -#define C8 FIXHR(0.17364817766693034885/2) - - -/* using Lee like decomposition followed by hand coded 9 points DCT */ -static void imdct36(int *out, int *buf, int *in, int *win) -{ - int i, j, t0, t1, t2, t3, s0, s1, s2, s3; - int tmp[18], *tmp1, *in1; - - for(i=17;i>=1;i--) - in[i] += in[i-1]; - for(i=17;i>=3;i-=2) - in[i] += in[i-2]; - - for(j=0;j<2;j++) { - tmp1 = tmp + j; - in1 = in + j; -#if 0 -//more accurate but slower - int64_t t0, t1, t2, t3; - t2 = in1[2*4] + in1[2*8] - in1[2*2]; - - t3 = (in1[2*0] + (int64_t)(in1[2*6]>>1))<<32; - t1 = in1[2*0] - in1[2*6]; - tmp1[ 6] = t1 - (t2>>1); - tmp1[16] = t1 + t2; - - t0 = MUL64(2*(in1[2*2] + in1[2*4]), C2); - t1 = MUL64( in1[2*4] - in1[2*8] , -2*C8); - t2 = MUL64(2*(in1[2*2] + in1[2*8]), -C4); - - tmp1[10] = (t3 - t0 - t2) >> 32; - tmp1[ 2] = (t3 + t0 + t1) >> 32; - tmp1[14] = (t3 + t2 - t1) >> 32; - - tmp1[ 4] = MULH(2*(in1[2*5] + in1[2*7] - in1[2*1]), -C3); - t2 = MUL64(2*(in1[2*1] + in1[2*5]), C1); - t3 = MUL64( in1[2*5] - in1[2*7] , -2*C7); - t0 = MUL64(2*in1[2*3], C3); - - t1 = MUL64(2*(in1[2*1] + in1[2*7]), -C5); - - tmp1[ 0] = (t2 + t3 + t0) >> 32; - tmp1[12] = (t2 + t1 - t0) >> 32; - tmp1[ 8] = (t3 - t1 - t0) >> 32; -#else - t2 = in1[2*4] + in1[2*8] - in1[2*2]; - - t3 = in1[2*0] + (in1[2*6]>>1); - t1 = in1[2*0] - in1[2*6]; - tmp1[ 6] = t1 - (t2>>1); - tmp1[16] = t1 + t2; - - t0 = MULH(2*(in1[2*2] + in1[2*4]), C2); - t1 = MULH( in1[2*4] - in1[2*8] , -2*C8); - t2 = MULH(2*(in1[2*2] + in1[2*8]), -C4); - - tmp1[10] = t3 - t0 - t2; - tmp1[ 2] = t3 + t0 + t1; - tmp1[14] = t3 + t2 - t1; - - tmp1[ 4] = MULH(2*(in1[2*5] + in1[2*7] - in1[2*1]), -C3); - t2 = MULH(2*(in1[2*1] + in1[2*5]), C1); - t3 = MULH( in1[2*5] - in1[2*7] , -2*C7); - t0 = MULH(2*in1[2*3], C3); - - t1 = MULH(2*(in1[2*1] + in1[2*7]), -C5); - - tmp1[ 0] = t2 + t3 + t0; - tmp1[12] = t2 + t1 - t0; - tmp1[ 8] = t3 - t1 - t0; -#endif - } - - i = 0; - for(j=0;j<4;j++) { - t0 = tmp[i]; - t1 = tmp[i + 2]; - s0 = t1 + t0; - s2 = t1 - t0; - - t2 = tmp[i + 1]; - t3 = tmp[i + 3]; - s1 = MULH(2*(t3 + t2), icos36h[j]); - s3 = MULL(t3 - t2, icos36[8 - j], FRAC_BITS); - - t0 = s0 + s1; - t1 = s0 - s1; - out[(9 + j)*SBLIMIT] = MULH(t1, win[9 + j]) + buf[9 + j]; - out[(8 - j)*SBLIMIT] = MULH(t1, win[8 - j]) + buf[8 - j]; - buf[9 + j] = MULH(t0, win[18 + 9 + j]); - buf[8 - j] = MULH(t0, win[18 + 8 - j]); - - t0 = s2 + s3; - t1 = s2 - s3; - out[(9 + 8 - j)*SBLIMIT] = MULH(t1, win[9 + 8 - j]) + buf[9 + 8 - j]; - out[( j)*SBLIMIT] = MULH(t1, win[ j]) + buf[ j]; - buf[9 + 8 - j] = MULH(t0, win[18 + 9 + 8 - j]); - buf[ + j] = MULH(t0, win[18 + j]); - i += 4; - } - - s0 = tmp[16]; - s1 = MULH(2*tmp[17], icos36h[4]); - t0 = s0 + s1; - t1 = s0 - s1; - out[(9 + 4)*SBLIMIT] = MULH(t1, win[9 + 4]) + buf[9 + 4]; - out[(8 - 4)*SBLIMIT] = MULH(t1, win[8 - 4]) + buf[8 - 4]; - buf[9 + 4] = MULH(t0, win[18 + 9 + 4]); - buf[8 - 4] = MULH(t0, win[18 + 8 - 4]); -} - -/* return the number of decoded frames */ -static int mp_decode_layer1(MPADecodeContext *s) -{ - int bound, i, v, n, ch, j, mant; - uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT]; - uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT]; - - if (s->mode == MPA_JSTEREO) - bound = (s->mode_ext + 1) * 4; - else - bound = SBLIMIT; - - /* allocation bits */ - for(i=0;inb_channels;ch++) { - allocation[ch][i] = get_bits(&s->gb, 4); - } - } - for(i=bound;igb, 4); - } - - /* scale factors */ - for(i=0;inb_channels;ch++) { - if (allocation[ch][i]) - scale_factors[ch][i] = get_bits(&s->gb, 6); - } - } - for(i=bound;igb, 6); - scale_factors[1][i] = get_bits(&s->gb, 6); - } - } - - /* compute samples */ - for(j=0;j<12;j++) { - for(i=0;inb_channels;ch++) { - n = allocation[ch][i]; - if (n) { - mant = get_bits(&s->gb, n + 1); - v = l1_unscale(n, mant, scale_factors[ch][i]); - } else { - v = 0; - } - s->sb_samples[ch][j][i] = v; - } - } - for(i=bound;igb, n + 1); - v = l1_unscale(n, mant, scale_factors[0][i]); - s->sb_samples[0][j][i] = v; - v = l1_unscale(n, mant, scale_factors[1][i]); - s->sb_samples[1][j][i] = v; - } else { - s->sb_samples[0][j][i] = 0; - s->sb_samples[1][j][i] = 0; - } - } - } - return 12; -} - -static int mp_decode_layer2(MPADecodeContext *s) -{ - int sblimit; /* number of used subbands */ - const unsigned char *alloc_table; - int table, bit_alloc_bits, i, j, ch, bound, v; - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf; - int scale, qindex, bits, steps, k, l, m, b; - - /* select decoding table */ - table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels, - s->sample_rate, s->lsf); - sblimit = ff_mpa_sblimit_table[table]; - alloc_table = ff_mpa_alloc_tables[table]; - - if (s->mode == MPA_JSTEREO) - bound = (s->mode_ext + 1) * 4; - else - bound = sblimit; - - dprintf(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit); - - /* sanity check */ - if( bound > sblimit ) bound = sblimit; - - /* parse bit allocation */ - j = 0; - for(i=0;inb_channels;ch++) { - bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits); - } - j += 1 << bit_alloc_bits; - } - for(i=bound;igb, bit_alloc_bits); - bit_alloc[0][i] = v; - bit_alloc[1][i] = v; - j += 1 << bit_alloc_bits; - } - - /* scale codes */ - for(i=0;inb_channels;ch++) { - if (bit_alloc[ch][i]) - scale_code[ch][i] = get_bits(&s->gb, 2); - } - } - - /* scale factors */ - for(i=0;inb_channels;ch++) { - if (bit_alloc[ch][i]) { - sf = scale_factors[ch][i]; - switch(scale_code[ch][i]) { - default: - case 0: - sf[0] = get_bits(&s->gb, 6); - sf[1] = get_bits(&s->gb, 6); - sf[2] = get_bits(&s->gb, 6); - break; - case 2: - sf[0] = get_bits(&s->gb, 6); - sf[1] = sf[0]; - sf[2] = sf[0]; - break; - case 1: - sf[0] = get_bits(&s->gb, 6); - sf[2] = get_bits(&s->gb, 6); - sf[1] = sf[0]; - break; - case 3: - sf[0] = get_bits(&s->gb, 6); - sf[2] = get_bits(&s->gb, 6); - sf[1] = sf[2]; - break; - } - } - } - } - - /* samples */ - for(k=0;k<3;k++) { - for(l=0;l<12;l+=3) { - j = 0; - for(i=0;inb_channels;ch++) { - b = bit_alloc[ch][i]; - if (b) { - scale = scale_factors[ch][i][k]; - qindex = alloc_table[j+b]; - bits = ff_mpa_quant_bits[qindex]; - if (bits < 0) { - /* 3 values at the same time */ - v = get_bits(&s->gb, -bits); - steps = ff_mpa_quant_steps[qindex]; - s->sb_samples[ch][k * 12 + l + 0][i] = - l2_unscale_group(steps, v % steps, scale); - v = v / steps; - s->sb_samples[ch][k * 12 + l + 1][i] = - l2_unscale_group(steps, v % steps, scale); - v = v / steps; - s->sb_samples[ch][k * 12 + l + 2][i] = - l2_unscale_group(steps, v, scale); - } else { - for(m=0;m<3;m++) { - v = get_bits(&s->gb, bits); - v = l1_unscale(bits - 1, v, scale); - s->sb_samples[ch][k * 12 + l + m][i] = v; - } - } - } else { - s->sb_samples[ch][k * 12 + l + 0][i] = 0; - s->sb_samples[ch][k * 12 + l + 1][i] = 0; - s->sb_samples[ch][k * 12 + l + 2][i] = 0; - } - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - /* XXX: find a way to avoid this duplication of code */ - for(i=bound;igb, -bits); - steps = ff_mpa_quant_steps[qindex]; - mant = v % steps; - v = v / steps; - s->sb_samples[0][k * 12 + l + 0][i] = - l2_unscale_group(steps, mant, scale0); - s->sb_samples[1][k * 12 + l + 0][i] = - l2_unscale_group(steps, mant, scale1); - mant = v % steps; - v = v / steps; - s->sb_samples[0][k * 12 + l + 1][i] = - l2_unscale_group(steps, mant, scale0); - s->sb_samples[1][k * 12 + l + 1][i] = - l2_unscale_group(steps, mant, scale1); - s->sb_samples[0][k * 12 + l + 2][i] = - l2_unscale_group(steps, v, scale0); - s->sb_samples[1][k * 12 + l + 2][i] = - l2_unscale_group(steps, v, scale1); - } else { - for(m=0;m<3;m++) { - mant = get_bits(&s->gb, bits); - s->sb_samples[0][k * 12 + l + m][i] = - l1_unscale(bits - 1, mant, scale0); - s->sb_samples[1][k * 12 + l + m][i] = - l1_unscale(bits - 1, mant, scale1); - } - } - } else { - s->sb_samples[0][k * 12 + l + 0][i] = 0; - s->sb_samples[0][k * 12 + l + 1][i] = 0; - s->sb_samples[0][k * 12 + l + 2][i] = 0; - s->sb_samples[1][k * 12 + l + 0][i] = 0; - s->sb_samples[1][k * 12 + l + 1][i] = 0; - s->sb_samples[1][k * 12 + l + 2][i] = 0; - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - /* fill remaining samples to zero */ - for(i=sblimit;inb_channels;ch++) { - s->sb_samples[ch][k * 12 + l + 0][i] = 0; - s->sb_samples[ch][k * 12 + l + 1][i] = 0; - s->sb_samples[ch][k * 12 + l + 2][i] = 0; - } - } - } - } - return 3 * 12; -} - -#define SPLIT(dst,sf,n)\ - if(n==3){\ - int m= (sf*171)>>9;\ - dst= sf - 3*m;\ - sf=m;\ - }else if(n==4){\ - dst= sf&3;\ - sf>>=2;\ - }else if(n==5){\ - int m= (sf*205)>>10;\ - dst= sf - 5*m;\ - sf=m;\ - }else if(n==6){\ - int m= (sf*171)>>10;\ - dst= sf - 6*m;\ - sf=m;\ - }else{\ - dst=0;\ - } - -static av_always_inline void lsf_sf_expand(int *slen, - int sf, int n1, int n2, int n3) -{ - SPLIT(slen[3], sf, n3) - SPLIT(slen[2], sf, n2) - SPLIT(slen[1], sf, n1) - slen[0] = sf; -} - -static void exponents_from_scale_factors(MPADecodeContext *s, - GranuleDef *g, - int16_t *exponents) -{ - const uint8_t *bstab, *pretab; - int len, i, j, k, l, v0, shift, gain, gains[3]; - int16_t *exp_ptr; - - exp_ptr = exponents; - gain = g->global_gain - 210; - shift = g->scalefac_scale + 1; - - bstab = band_size_long[s->sample_rate_index]; - pretab = mpa_pretab[g->preflag]; - for(i=0;ilong_end;i++) { - v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400; - len = bstab[i]; - for(j=len;j>0;j--) - *exp_ptr++ = v0; - } - - if (g->short_start < 13) { - bstab = band_size_short[s->sample_rate_index]; - gains[0] = gain - (g->subblock_gain[0] << 3); - gains[1] = gain - (g->subblock_gain[1] << 3); - gains[2] = gain - (g->subblock_gain[2] << 3); - k = g->long_end; - for(i=g->short_start;i<13;i++) { - len = bstab[i]; - for(l=0;l<3;l++) { - v0 = gains[l] - (g->scale_factors[k++] << shift) + 400; - for(j=len;j>0;j--) - *exp_ptr++ = v0; - } - } - } -} - -/* handle n = 0 too */ -static inline int get_bitsz(GetBitContext *s, int n) -{ - if (n == 0) - return 0; - else - return get_bits(s, n); -} - - -static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, int *end_pos2){ - if(s->in_gb.buffer && *pos >= s->gb.size_in_bits){ - s->gb= s->in_gb; - s->in_gb.buffer=NULL; - assert((get_bits_count(&s->gb) & 7) == 0); - skip_bits_long(&s->gb, *pos - *end_pos); - *end_pos2= - *end_pos= *end_pos2 + get_bits_count(&s->gb) - *pos; - *pos= get_bits_count(&s->gb); - } -} - -static int huffman_decode(MPADecodeContext *s, GranuleDef *g, - int16_t *exponents, int end_pos2) -{ - int s_index; - int i; - int last_pos, bits_left; - VLC *vlc; - int end_pos= FFMIN(end_pos2, s->gb.size_in_bits); - - /* low frequencies (called big values) */ - s_index = 0; - for(i=0;i<3;i++) { - int j, k, l, linbits; - j = g->region_size[i]; - if (j == 0) - continue; - /* select vlc table */ - k = g->table_select[i]; - l = mpa_huff_data[k][0]; - linbits = mpa_huff_data[k][1]; - vlc = &huff_vlc[l]; - - if(!l){ - memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*2*j); - s_index += 2*j; - continue; - } - - /* read huffcode and compute each couple */ - for(;j>0;j--) { - int exponent, x, y, v; - int pos= get_bits_count(&s->gb); - - if (pos >= end_pos){ -// av_log(NULL, AV_LOG_ERROR, "pos: %d %d %d %d\n", pos, end_pos, end_pos2, s_index); - switch_buffer(s, &pos, &end_pos, &end_pos2); -// av_log(NULL, AV_LOG_ERROR, "new pos: %d %d\n", pos, end_pos); - if(pos >= end_pos) - break; - } - y = get_vlc2(&s->gb, vlc->table, 7, 3); - - if(!y){ - g->sb_hybrid[s_index ] = - g->sb_hybrid[s_index+1] = 0; - s_index += 2; - continue; - } - - exponent= exponents[s_index]; - - dprintf(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n", - i, g->region_size[i] - j, x, y, exponent); - if(y&16){ - x = y >> 5; - y = y & 0x0f; - if (x < 15){ - v = expval_table[ exponent ][ x ]; -// v = expval_table[ (exponent&3) ][ x ] >> FFMIN(0 - (exponent>>2), 31); - }else{ - x += get_bitsz(&s->gb, linbits); - v = l3_unscale(x, exponent); - } - if (get_bits1(&s->gb)) - v = -v; - g->sb_hybrid[s_index] = v; - if (y < 15){ - v = expval_table[ exponent ][ y ]; - }else{ - y += get_bitsz(&s->gb, linbits); - v = l3_unscale(y, exponent); - } - if (get_bits1(&s->gb)) - v = -v; - g->sb_hybrid[s_index+1] = v; - }else{ - x = y >> 5; - y = y & 0x0f; - x += y; - if (x < 15){ - v = expval_table[ exponent ][ x ]; - }else{ - x += get_bitsz(&s->gb, linbits); - v = l3_unscale(x, exponent); - } - if (get_bits1(&s->gb)) - v = -v; - g->sb_hybrid[s_index+!!y] = v; - g->sb_hybrid[s_index+ !y] = 0; - } - s_index+=2; - } - } - - /* high frequencies */ - vlc = &huff_quad_vlc[g->count1table_select]; - last_pos=0; - while (s_index <= 572) { - int pos, code; - pos = get_bits_count(&s->gb); - if (pos >= end_pos) { - if (pos > end_pos2 && last_pos){ - /* some encoders generate an incorrect size for this - part. We must go back into the data */ - s_index -= 4; - skip_bits_long(&s->gb, last_pos - pos); - av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos); - if(s->error_recognition >= FF_ER_COMPLIANT) - s_index=0; - break; - } -// av_log(NULL, AV_LOG_ERROR, "pos2: %d %d %d %d\n", pos, end_pos, end_pos2, s_index); - switch_buffer(s, &pos, &end_pos, &end_pos2); -// av_log(NULL, AV_LOG_ERROR, "new pos2: %d %d %d\n", pos, end_pos, s_index); - if(pos >= end_pos) - break; - } - last_pos= pos; - - code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1); - dprintf(s->avctx, "t=%d code=%d\n", g->count1table_select, code); - g->sb_hybrid[s_index+0]= - g->sb_hybrid[s_index+1]= - g->sb_hybrid[s_index+2]= - g->sb_hybrid[s_index+3]= 0; - while(code){ - static const int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; - int v; - int pos= s_index+idxtab[code]; - code ^= 8>>idxtab[code]; - v = exp_table[ exponents[pos] ]; -// v = exp_table[ (exponents[pos]&3) ] >> FFMIN(0 - (exponents[pos]>>2), 31); - if(get_bits1(&s->gb)) - v = -v; - g->sb_hybrid[pos] = v; - } - s_index+=4; - } - /* skip extension bits */ - bits_left = end_pos2 - get_bits_count(&s->gb); -//av_log(NULL, AV_LOG_ERROR, "left:%d buf:%p\n", bits_left, s->in_gb.buffer); - if (bits_left < 0 && s->error_recognition >= FF_ER_COMPLIANT) { - av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); - s_index=0; - }else if(bits_left > 0 && s->error_recognition >= FF_ER_AGGRESSIVE){ - av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); - s_index=0; - } - memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*(576 - s_index)); - skip_bits_long(&s->gb, bits_left); - - i= get_bits_count(&s->gb); - switch_buffer(s, &i, &end_pos, &end_pos2); - - return 0; -} - -/* Reorder short blocks from bitstream order to interleaved order. It - would be faster to do it in parsing, but the code would be far more - complicated */ -static void reorder_block(MPADecodeContext *s, GranuleDef *g) -{ - int i, j, len; - int32_t *ptr, *dst, *ptr1; - int32_t tmp[576]; - - if (g->block_type != 2) - return; - - if (g->switch_point) { - if (s->sample_rate_index != 8) { - ptr = g->sb_hybrid + 36; - } else { - ptr = g->sb_hybrid + 48; - } - } else { - ptr = g->sb_hybrid; - } - - for(i=g->short_start;i<13;i++) { - len = band_size_short[s->sample_rate_index][i]; - ptr1 = ptr; - dst = tmp; - for(j=len;j>0;j--) { - *dst++ = ptr[0*len]; - *dst++ = ptr[1*len]; - *dst++ = ptr[2*len]; - ptr++; - } - ptr+=2*len; - memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1)); - } -} - -#define ISQRT2 FIXR(0.70710678118654752440) - -static void compute_stereo(MPADecodeContext *s, - GranuleDef *g0, GranuleDef *g1) -{ - int i, j, k, l; - int32_t v1, v2; - int sf_max, tmp0, tmp1, sf, len, non_zero_found; - int32_t (*is_tab)[16]; - int32_t *tab0, *tab1; - int non_zero_found_short[3]; - - /* intensity stereo */ - if (s->mode_ext & MODE_EXT_I_STEREO) { - if (!s->lsf) { - is_tab = is_table; - sf_max = 7; - } else { - is_tab = is_table_lsf[g1->scalefac_compress & 1]; - sf_max = 16; - } - - tab0 = g0->sb_hybrid + 576; - tab1 = g1->sb_hybrid + 576; - - non_zero_found_short[0] = 0; - non_zero_found_short[1] = 0; - non_zero_found_short[2] = 0; - k = (13 - g1->short_start) * 3 + g1->long_end - 3; - for(i = 12;i >= g1->short_start;i--) { - /* for last band, use previous scale factor */ - if (i != 11) - k -= 3; - len = band_size_short[s->sample_rate_index][i]; - for(l=2;l>=0;l--) { - tab0 -= len; - tab1 -= len; - if (!non_zero_found_short[l]) { - /* test if non zero band. if so, stop doing i-stereo */ - for(j=0;jscale_factors[k + l]; - if (sf >= sf_max) - goto found1; - - v1 = is_tab[0][sf]; - v2 = is_tab[1][sf]; - for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { - /* lower part of the spectrum : do ms stereo - if enabled */ - for(j=0;jlong_end - 1;i >= 0;i--) { - len = band_size_long[s->sample_rate_index][i]; - tab0 -= len; - tab1 -= len; - /* test if non zero band. if so, stop doing i-stereo */ - if (!non_zero_found) { - for(j=0;jscale_factors[k]; - if (sf >= sf_max) - goto found2; - v1 = is_tab[0][sf]; - v2 = is_tab[1][sf]; - for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { - /* lower part of the spectrum : do ms stereo - if enabled */ - for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { - /* ms stereo ONLY */ - /* NOTE: the 1/sqrt(2) normalization factor is included in the - global gain */ - tab0 = g0->sb_hybrid; - tab1 = g1->sb_hybrid; - for(i=0;i<576;i++) { - tmp0 = tab0[i]; - tmp1 = tab1[i]; - tab0[i] = tmp0 + tmp1; - tab1[i] = tmp0 - tmp1; - } - } -} - -static void compute_antialias_integer(MPADecodeContext *s, - GranuleDef *g) -{ - int32_t *ptr, *csa; - int n, i; - - /* we antialias only "long" bands */ - if (g->block_type == 2) { - if (!g->switch_point) - return; - /* XXX: check this for 8000Hz case */ - n = 1; - } else { - n = SBLIMIT - 1; - } - - ptr = g->sb_hybrid + 18; - for(i = n;i > 0;i--) { - int tmp0, tmp1, tmp2; - csa = &csa_table[0][0]; -#define INT_AA(j) \ - tmp0 = ptr[-1-j];\ - tmp1 = ptr[ j];\ - tmp2= MULH(tmp0 + tmp1, csa[0+4*j]);\ - ptr[-1-j] = 4*(tmp2 - MULH(tmp1, csa[2+4*j]));\ - ptr[ j] = 4*(tmp2 + MULH(tmp0, csa[3+4*j])); - - INT_AA(0) - INT_AA(1) - INT_AA(2) - INT_AA(3) - INT_AA(4) - INT_AA(5) - INT_AA(6) - INT_AA(7) - - ptr += 18; - } -} - -static void compute_antialias_float(MPADecodeContext *s, - GranuleDef *g) -{ - int32_t *ptr; - int n, i; - - /* we antialias only "long" bands */ - if (g->block_type == 2) { - if (!g->switch_point) - return; - /* XXX: check this for 8000Hz case */ - n = 1; - } else { - n = SBLIMIT - 1; - } - - ptr = g->sb_hybrid + 18; - for(i = n;i > 0;i--) { - float tmp0, tmp1; - float *csa = &csa_table_float[0][0]; -#define FLOAT_AA(j)\ - tmp0= ptr[-1-j];\ - tmp1= ptr[ j];\ - ptr[-1-j] = lrintf(tmp0 * csa[0+4*j] - tmp1 * csa[1+4*j]);\ - ptr[ j] = lrintf(tmp0 * csa[1+4*j] + tmp1 * csa[0+4*j]); - - FLOAT_AA(0) - FLOAT_AA(1) - FLOAT_AA(2) - FLOAT_AA(3) - FLOAT_AA(4) - FLOAT_AA(5) - FLOAT_AA(6) - FLOAT_AA(7) - - ptr += 18; - } -} - -static void compute_imdct(MPADecodeContext *s, - GranuleDef *g, - int32_t *sb_samples, - int32_t *mdct_buf) -{ - int32_t *ptr, *win, *win1, *buf, *out_ptr, *ptr1; - int32_t out2[12]; - int i, j, mdct_long_end, v, sblimit; - - /* find last non zero block */ - ptr = g->sb_hybrid + 576; - ptr1 = g->sb_hybrid + 2 * 18; - while (ptr >= ptr1) { - ptr -= 6; - v = ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5]; - if (v != 0) - break; - } - sblimit = ((ptr - g->sb_hybrid) / 18) + 1; - - if (g->block_type == 2) { - /* XXX: check for 8000 Hz */ - if (g->switch_point) - mdct_long_end = 2; - else - mdct_long_end = 0; - } else { - mdct_long_end = sblimit; - } - - buf = mdct_buf; - ptr = g->sb_hybrid; - for(j=0;jswitch_point && j < 2) - win1 = mdct_win[0]; - else - win1 = mdct_win[g->block_type]; - /* select frequency inversion */ - win = win1 + ((4 * 36) & -(j & 1)); - imdct36(out_ptr, buf, ptr, win); - out_ptr += 18*SBLIMIT; - ptr += 18; - buf += 18; - } - for(j=mdct_long_end;jlsf) { - main_data_begin = get_bits(&s->gb, 8); - private_bits = get_bits(&s->gb, s->nb_channels); - nb_granules = 1; - } else { - main_data_begin = get_bits(&s->gb, 9); - if (s->nb_channels == 2) - private_bits = get_bits(&s->gb, 3); - else - private_bits = get_bits(&s->gb, 5); - nb_granules = 2; - for(ch=0;chnb_channels;ch++) { - s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */ - s->granules[ch][1].scfsi = get_bits(&s->gb, 4); - } - } - - for(gr=0;grnb_channels;ch++) { - dprintf(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch); - g = &s->granules[ch][gr]; - g->part2_3_length = get_bits(&s->gb, 12); - g->big_values = get_bits(&s->gb, 9); - if(g->big_values > 288){ - av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n"); - return -1; - } - - g->global_gain = get_bits(&s->gb, 8); - /* if MS stereo only is selected, we precompute the - 1/sqrt(2) renormalization factor */ - if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) == - MODE_EXT_MS_STEREO) - g->global_gain -= 2; - if (s->lsf) - g->scalefac_compress = get_bits(&s->gb, 9); - else - g->scalefac_compress = get_bits(&s->gb, 4); - blocksplit_flag = get_bits1(&s->gb); - if (blocksplit_flag) { - g->block_type = get_bits(&s->gb, 2); - if (g->block_type == 0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n"); - return -1; - } - g->switch_point = get_bits1(&s->gb); - for(i=0;i<2;i++) - g->table_select[i] = get_bits(&s->gb, 5); - for(i=0;i<3;i++) - g->subblock_gain[i] = get_bits(&s->gb, 3); - ff_init_short_region(s, g); - } else { - int region_address1, region_address2; - g->block_type = 0; - g->switch_point = 0; - for(i=0;i<3;i++) - g->table_select[i] = get_bits(&s->gb, 5); - /* compute huffman coded region sizes */ - region_address1 = get_bits(&s->gb, 4); - region_address2 = get_bits(&s->gb, 3); - dprintf(s->avctx, "region1=%d region2=%d\n", - region_address1, region_address2); - ff_init_long_region(s, g, region_address1, region_address2); - } - ff_region_offset2size(g); - ff_compute_band_indexes(s, g); - - g->preflag = 0; - if (!s->lsf) - g->preflag = get_bits1(&s->gb); - g->scalefac_scale = get_bits1(&s->gb); - g->count1table_select = get_bits1(&s->gb); - dprintf(s->avctx, "block_type=%d switch_point=%d\n", - g->block_type, g->switch_point); - } - } - - if (!s->adu_mode) { - const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); - assert((get_bits_count(&s->gb) & 7) == 0); - /* now we get bits from the main_data_begin offset */ - dprintf(s->avctx, "seekback: %d\n", main_data_begin); -//av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size); - - memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES); - s->in_gb= s->gb; - init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8); - skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin)); - } - - for(gr=0;grnb_channels;ch++) { - g = &s->granules[ch][gr]; - if(get_bits_count(&s->gb)<0){ - av_log(s->avctx, AV_LOG_DEBUG, "mdb:%d, lastbuf:%d skipping granule %d\n", - main_data_begin, s->last_buf_size, gr); - skip_bits_long(&s->gb, g->part2_3_length); - memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid)); - if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer){ - skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits); - s->gb= s->in_gb; - s->in_gb.buffer=NULL; - } - continue; - } - - bits_pos = get_bits_count(&s->gb); - - if (!s->lsf) { - uint8_t *sc; - int slen, slen1, slen2; - - /* MPEG1 scale factors */ - slen1 = slen_table[0][g->scalefac_compress]; - slen2 = slen_table[1][g->scalefac_compress]; - dprintf(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2); - if (g->block_type == 2) { - n = g->switch_point ? 17 : 18; - j = 0; - if(slen1){ - for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen1); - }else{ - for(i=0;iscale_factors[j++] = 0; - } - if(slen2){ - for(i=0;i<18;i++) - g->scale_factors[j++] = get_bits(&s->gb, slen2); - for(i=0;i<3;i++) - g->scale_factors[j++] = 0; - }else{ - for(i=0;i<21;i++) - g->scale_factors[j++] = 0; - } - } else { - sc = s->granules[ch][0].scale_factors; - j = 0; - for(k=0;k<4;k++) { - n = (k == 0 ? 6 : 5); - if ((g->scfsi & (0x8 >> k)) == 0) { - slen = (k < 2) ? slen1 : slen2; - if(slen){ - for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen); - }else{ - for(i=0;iscale_factors[j++] = 0; - } - } else { - /* simply copy from last granule */ - for(i=0;iscale_factors[j] = sc[j]; - j++; - } - } - } - g->scale_factors[j++] = 0; - } - } else { - int tindex, tindex2, slen[4], sl, sf; - - /* LSF scale factors */ - if (g->block_type == 2) { - tindex = g->switch_point ? 2 : 1; - } else { - tindex = 0; - } - sf = g->scalefac_compress; - if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) { - /* intensity stereo case */ - sf >>= 1; - if (sf < 180) { - lsf_sf_expand(slen, sf, 6, 6, 0); - tindex2 = 3; - } else if (sf < 244) { - lsf_sf_expand(slen, sf - 180, 4, 4, 0); - tindex2 = 4; - } else { - lsf_sf_expand(slen, sf - 244, 3, 0, 0); - tindex2 = 5; - } - } else { - /* normal case */ - if (sf < 400) { - lsf_sf_expand(slen, sf, 5, 4, 4); - tindex2 = 0; - } else if (sf < 500) { - lsf_sf_expand(slen, sf - 400, 5, 4, 0); - tindex2 = 1; - } else { - lsf_sf_expand(slen, sf - 500, 3, 0, 0); - tindex2 = 2; - g->preflag = 1; - } - } - - j = 0; - for(k=0;k<4;k++) { - n = lsf_nsf_table[tindex2][tindex][k]; - sl = slen[k]; - if(sl){ - for(i=0;iscale_factors[j++] = get_bits(&s->gb, sl); - }else{ - for(i=0;iscale_factors[j++] = 0; - } - } - /* XXX: should compute exact size */ - for(;j<40;j++) - g->scale_factors[j] = 0; - } - - exponents_from_scale_factors(s, g, exponents); - - /* read Huffman coded residue */ - huffman_decode(s, g, exponents, bits_pos + g->part2_3_length); - } /* ch */ - - if (s->nb_channels == 2) - compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]); - - for(ch=0;chnb_channels;ch++) { - g = &s->granules[ch][gr]; - - reorder_block(s, g); - s->compute_antialias(s, g); - compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]); - } - } /* gr */ - if(get_bits_count(&s->gb)<0) - skip_bits_long(&s->gb, -get_bits_count(&s->gb)); - return nb_granules * 18; -} - -static int mp_decode_frame(MPADecodeContext *s, - OUT_INT *samples, const uint8_t *buf, int buf_size) -{ - int i, nb_frames, ch; - OUT_INT *samples_ptr; - - init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE)*8); - - /* skip error protection field */ - if (s->error_protection) - skip_bits(&s->gb, 16); - - dprintf(s->avctx, "frame %d:\n", s->frame_count); - switch(s->layer) { - case 1: - s->avctx->frame_size = 384; - nb_frames = mp_decode_layer1(s); - break; - case 2: - s->avctx->frame_size = 1152; - nb_frames = mp_decode_layer2(s); - break; - case 3: - s->avctx->frame_size = s->lsf ? 576 : 1152; - default: - nb_frames = mp_decode_layer3(s); - - s->last_buf_size=0; - if(s->in_gb.buffer){ - align_get_bits(&s->gb); - i= get_bits_left(&s->gb)>>3; - if(i >= 0 && i <= BACKSTEP_SIZE){ - memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i); - s->last_buf_size=i; - }else - av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i); - s->gb= s->in_gb; - s->in_gb.buffer= NULL; - } - - align_get_bits(&s->gb); - assert((get_bits_count(&s->gb) & 7) == 0); - i= get_bits_left(&s->gb)>>3; - - if(i<0 || i > BACKSTEP_SIZE || nb_frames<0){ - if(i<0) - av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i); - i= FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE); - } - assert(i <= buf_size - HEADER_SIZE && i>= 0); - memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i); - s->last_buf_size += i; - - break; - } - - /* apply the synthesis filter */ - for(ch=0;chnb_channels;ch++) { - samples_ptr = samples + ch; - for(i=0;isynth_buf[ch], &(s->synth_buf_offset[ch]), - ff_mpa_synth_window, &s->dither_state, - samples_ptr, s->nb_channels, - s->sb_samples[ch][i]); - samples_ptr += 32 * s->nb_channels; - } - } - - return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels; -} - -static int decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MPADecodeContext *s = avctx->priv_data; - uint32_t header; - int out_size; - OUT_INT *out_samples = data; - - if(buf_size < HEADER_SIZE) - return -1; - - header = AV_RB32(buf); - if(ff_mpa_check_header(header) < 0){ - av_log(avctx, AV_LOG_ERROR, "Header missing\n"); - return -1; - } - - if (ff_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) { - /* free format: prepare to compute frame size */ - s->frame_size = -1; - return -1; - } - /* update codec info */ - avctx->channels = s->nb_channels; - avctx->bit_rate = s->bit_rate; - avctx->sub_id = s->layer; - - if(*data_size < 1152*avctx->channels*sizeof(OUT_INT)) - return -1; - *data_size = 0; - - if(s->frame_size<=0 || s->frame_size > buf_size){ - av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); - return -1; - }else if(s->frame_size < buf_size){ - av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n"); - buf_size= s->frame_size; - } - - out_size = mp_decode_frame(s, out_samples, buf, buf_size); - if(out_size>=0){ - *data_size = out_size; - avctx->sample_rate = s->sample_rate; - //FIXME maybe move the other codec info stuff from above here too - }else - av_log(avctx, AV_LOG_DEBUG, "Error while decoding MPEG audio frame.\n"); //FIXME return -1 / but also return the number of bytes consumed - s->frame_size = 0; - return buf_size; -} - -static void flush(AVCodecContext *avctx){ - MPADecodeContext *s = avctx->priv_data; - memset(s->synth_buf, 0, sizeof(s->synth_buf)); - s->last_buf_size= 0; -} - -#if CONFIG_MP3ADU_DECODER -static int decode_frame_adu(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MPADecodeContext *s = avctx->priv_data; - uint32_t header; - int len, out_size; - OUT_INT *out_samples = data; - - len = buf_size; - - // Discard too short frames - if (buf_size < HEADER_SIZE) { - *data_size = 0; - return buf_size; - } - - - if (len > MPA_MAX_CODED_FRAME_SIZE) - len = MPA_MAX_CODED_FRAME_SIZE; - - // Get header and restore sync word - header = AV_RB32(buf) | 0xffe00000; - - if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame - *data_size = 0; - return buf_size; - } - - ff_mpegaudio_decode_header((MPADecodeHeader *)s, header); - /* update codec info */ - avctx->sample_rate = s->sample_rate; - avctx->channels = s->nb_channels; - avctx->bit_rate = s->bit_rate; - avctx->sub_id = s->layer; - - s->frame_size = len; - - if (avctx->parse_only) { - out_size = buf_size; - } else { - out_size = mp_decode_frame(s, out_samples, buf, buf_size); - } - - *data_size = out_size; - return buf_size; -} -#endif /* CONFIG_MP3ADU_DECODER */ - -#if CONFIG_MP3ON4_DECODER - -/** - * Context for MP3On4 decoder - */ -typedef struct MP3On4DecodeContext { - int frames; ///< number of mp3 frames per block (number of mp3 decoder instances) - int syncword; ///< syncword patch - const uint8_t *coff; ///< channels offsets in output buffer - MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance -} MP3On4DecodeContext; - -#include "mpeg4audio.h" - -/* Next 3 arrays are indexed by channel config number (passed via codecdata) */ -static const uint8_t mp3Frames[8] = {0,1,1,2,3,3,4,5}; /* number of mp3 decoder instances */ -/* offsets into output buffer, assume output order is FL FR BL BR C LFE */ -static const uint8_t chan_offset[8][5] = { - {0}, - {0}, // C - {0}, // FLR - {2,0}, // C FLR - {2,0,3}, // C FLR BS - {4,0,2}, // C FLR BLRS - {4,0,2,5}, // C FLR BLRS LFE - {4,0,2,6,5}, // C FLR BLRS BLR LFE -}; - - -static int decode_init_mp3on4(AVCodecContext * avctx) -{ - MP3On4DecodeContext *s = avctx->priv_data; - MPEG4AudioConfig cfg; - int i; - - if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) { - av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n"); - return -1; - } - - ff_mpeg4audio_get_config(&cfg, avctx->extradata, avctx->extradata_size); - if (!cfg.chan_config || cfg.chan_config > 7) { - av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n"); - return -1; - } - s->frames = mp3Frames[cfg.chan_config]; - s->coff = chan_offset[cfg.chan_config]; - avctx->channels = ff_mpeg4audio_channels[cfg.chan_config]; - - if (cfg.sample_rate < 16000) - s->syncword = 0xffe00000; - else - s->syncword = 0xfff00000; - - /* Init the first mp3 decoder in standard way, so that all tables get builded - * We replace avctx->priv_data with the context of the first decoder so that - * decode_init() does not have to be changed. - * Other decoders will be initialized here copying data from the first context - */ - // Allocate zeroed memory for the first decoder context - s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext)); - // Put decoder context in place to make init_decode() happy - avctx->priv_data = s->mp3decctx[0]; - decode_init(avctx); - // Restore mp3on4 context pointer - avctx->priv_data = s; - s->mp3decctx[0]->adu_mode = 1; // Set adu mode - - /* Create a separate codec/context for each frame (first is already ok). - * Each frame is 1 or 2 channels - up to 5 frames allowed - */ - for (i = 1; i < s->frames; i++) { - s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext)); - s->mp3decctx[i]->compute_antialias = s->mp3decctx[0]->compute_antialias; - s->mp3decctx[i]->adu_mode = 1; - s->mp3decctx[i]->avctx = avctx; - } - - return 0; -} - - -static av_cold int decode_close_mp3on4(AVCodecContext * avctx) -{ - MP3On4DecodeContext *s = avctx->priv_data; - int i; - - for (i = 0; i < s->frames; i++) - if (s->mp3decctx[i]) - av_free(s->mp3decctx[i]); - - return 0; -} - - -static int decode_frame_mp3on4(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MP3On4DecodeContext *s = avctx->priv_data; - MPADecodeContext *m; - int fsize, len = buf_size, out_size = 0; - uint32_t header; - OUT_INT *out_samples = data; - OUT_INT decoded_buf[MPA_FRAME_SIZE * MPA_MAX_CHANNELS]; - OUT_INT *outptr, *bp; - int fr, j, n; - - if(*data_size < MPA_FRAME_SIZE * MPA_MAX_CHANNELS * s->frames * sizeof(OUT_INT)) - return -1; - - *data_size = 0; - // Discard too short frames - if (buf_size < HEADER_SIZE) - return -1; - - // If only one decoder interleave is not needed - outptr = s->frames == 1 ? out_samples : decoded_buf; - - avctx->bit_rate = 0; - - for (fr = 0; fr < s->frames; fr++) { - fsize = AV_RB16(buf) >> 4; - fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE); - m = s->mp3decctx[fr]; - assert (m != NULL); - - header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header - - if (ff_mpa_check_header(header) < 0) // Bad header, discard block - break; - - ff_mpegaudio_decode_header((MPADecodeHeader *)m, header); - out_size += mp_decode_frame(m, outptr, buf, fsize); - buf += fsize; - len -= fsize; - - if(s->frames > 1) { - n = m->avctx->frame_size*m->nb_channels; - /* interleave output data */ - bp = out_samples + s->coff[fr]; - if(m->nb_channels == 1) { - for(j = 0; j < n; j++) { - *bp = decoded_buf[j]; - bp += avctx->channels; - } - } else { - for(j = 0; j < n; j++) { - bp[0] = decoded_buf[j++]; - bp[1] = decoded_buf[j]; - bp += avctx->channels; - } - } - } - avctx->bit_rate += m->bit_rate; - } - - /* update codec info */ - avctx->sample_rate = s->mp3decctx[0]->sample_rate; - - *data_size = out_size; - return buf_size; -} -#endif /* CONFIG_MP3ON4_DECODER */ - -#if CONFIG_MP1_DECODER -AVCodec mp1_decoder = -{ - "mp1", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP1, - sizeof(MPADecodeContext), - decode_init, - NULL, - NULL, - decode_frame, - CODEC_CAP_PARSE_ONLY, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"), -}; -#endif -#if CONFIG_MP2_DECODER -AVCodec mp2_decoder = -{ - "mp2", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP2, - sizeof(MPADecodeContext), - decode_init, - NULL, - NULL, - decode_frame, - CODEC_CAP_PARSE_ONLY, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), -}; -#endif -#if CONFIG_MP3_DECODER -AVCodec mp3_decoder = -{ - "mp3", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP3, - sizeof(MPADecodeContext), - decode_init, - NULL, - NULL, - decode_frame, - CODEC_CAP_PARSE_ONLY, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), -}; -#endif -#if CONFIG_MP3ADU_DECODER -AVCodec mp3adu_decoder = -{ - "mp3adu", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP3ADU, - sizeof(MPADecodeContext), - decode_init, - NULL, - NULL, - decode_frame_adu, - CODEC_CAP_PARSE_ONLY, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"), -}; -#endif -#if CONFIG_MP3ON4_DECODER -AVCodec mp3on4_decoder = -{ - "mp3on4", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP3ON4, - sizeof(MP3On4DecodeContext), - decode_init_mp3on4, - NULL, - decode_close_mp3on4, - decode_frame_mp3on4, - .flush= flush, - .long_name= NULL_IF_CONFIG_SMALL("MP3onMP4"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.c b/tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.c deleted file mode 100644 index 67f882f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * MPEG Audio header decoder - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG Audio header decoder. - */ - -//#define DEBUG -#include "avcodec.h" -#include "mpegaudio.h" -#include "mpegaudiodata.h" -#include "mpegaudiodecheader.h" - - -int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header) -{ - int sample_rate, frame_size, mpeg25, padding; - int sample_rate_index, bitrate_index; - if (header & (1<<20)) { - s->lsf = (header & (1<<19)) ? 0 : 1; - mpeg25 = 0; - } else { - s->lsf = 1; - mpeg25 = 1; - } - - s->layer = 4 - ((header >> 17) & 3); - /* extract frequency */ - sample_rate_index = (header >> 10) & 3; - sample_rate = ff_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25); - sample_rate_index += 3 * (s->lsf + mpeg25); - s->sample_rate_index = sample_rate_index; - s->error_protection = ((header >> 16) & 1) ^ 1; - s->sample_rate = sample_rate; - - bitrate_index = (header >> 12) & 0xf; - padding = (header >> 9) & 1; - //extension = (header >> 8) & 1; - s->mode = (header >> 6) & 3; - s->mode_ext = (header >> 4) & 3; - //copyright = (header >> 3) & 1; - //original = (header >> 2) & 1; - //emphasis = header & 3; - - if (s->mode == MPA_MONO) - s->nb_channels = 1; - else - s->nb_channels = 2; - - if (bitrate_index != 0) { - frame_size = ff_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index]; - s->bit_rate = frame_size * 1000; - switch(s->layer) { - case 1: - frame_size = (frame_size * 12000) / sample_rate; - frame_size = (frame_size + padding) * 4; - break; - case 2: - frame_size = (frame_size * 144000) / sample_rate; - frame_size += padding; - break; - default: - case 3: - frame_size = (frame_size * 144000) / (sample_rate << s->lsf); - frame_size += padding; - break; - } - s->frame_size = frame_size; - } else { - /* if no frame size computed, signal it */ - return 1; - } - -#if defined(DEBUG) - dprintf(NULL, "layer%d, %d Hz, %d kbits/s, ", - s->layer, s->sample_rate, s->bit_rate); - if (s->nb_channels == 2) { - if (s->layer == 3) { - if (s->mode_ext & MODE_EXT_MS_STEREO) - dprintf(NULL, "ms-"); - if (s->mode_ext & MODE_EXT_I_STEREO) - dprintf(NULL, "i-"); - } - dprintf(NULL, "stereo"); - } else { - dprintf(NULL, "mono"); - } - dprintf(NULL, "\n"); -#endif - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.h b/tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.h deleted file mode 100644 index 5578618..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodecheader.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * MPEG Audio header decoder - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MPEG Audio header decoder. - */ - -#ifndef AVCODEC_MPEGAUDIODECHEADER_H -#define AVCODEC_MPEGAUDIODECHEADER_H - -#include "libavutil/common.h" -#include "mpegaudio.h" - - -/* header decoding. MUST check the header before because no - consistency check is done there. Return 1 if free format found and - that the frame size must be computed externally */ -int ff_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header); - -#endif /* AVCODEC_MPEGAUDIODECHEADER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodectab.h b/tizen/distrib/ffmpeg/libavcodec/mpegaudiodectab.h deleted file mode 100644 index 234a70e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudiodectab.h +++ /dev/null @@ -1,606 +0,0 @@ -/* - * MPEG Audio decoder - * copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * mpeg audio layer decoder tables. - */ - -#ifndef AVCODEC_MPEGAUDIODECTAB_H -#define AVCODEC_MPEGAUDIODECTAB_H - -#include -#include "mpegaudio.h" - -/*******************************************************/ -/* layer 3 tables */ - -/* layer3 scale factor size */ -static const uint8_t slen_table[2][16] = { - { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, - { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }, -}; - -/* number of lsf scale factors for a given size */ -static const uint8_t lsf_nsf_table[6][3][4] = { - { { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } }, - { { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } }, - { { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } }, - { { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } }, - { { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } }, - { { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } }, -}; - -/* mpegaudio layer 3 huffman tables */ - -static const uint16_t mpa_huffcodes_1[4] = { - 0x0001, 0x0001, 0x0001, 0x0000, -}; - -static const uint8_t mpa_huffbits_1[4] = { - 1, 3, 2, 3, -}; - -static const uint16_t mpa_huffcodes_2[9] = { - 0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002, - 0x0000, -}; - -static const uint8_t mpa_huffbits_2[9] = { - 1, 3, 6, 3, 3, 5, 5, 5, - 6, -}; - -static const uint16_t mpa_huffcodes_3[9] = { - 0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002, - 0x0000, -}; - -static const uint8_t mpa_huffbits_3[9] = { - 2, 2, 6, 3, 2, 5, 5, 5, - 6, -}; - -static const uint16_t mpa_huffcodes_5[16] = { - 0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004, - 0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000, -}; - -static const uint8_t mpa_huffbits_5[16] = { - 1, 3, 6, 7, 3, 3, 6, 7, - 6, 6, 7, 8, 7, 6, 7, 8, -}; - -static const uint16_t mpa_huffcodes_6[16] = { - 0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002, - 0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000, -}; - -static const uint8_t mpa_huffbits_6[16] = { - 3, 3, 5, 7, 3, 2, 4, 5, - 4, 4, 5, 6, 6, 5, 6, 7, -}; - -static const uint16_t mpa_huffcodes_7[36] = { - 0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003, - 0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011, - 0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002, - 0x0007, 0x0006, 0x0009, 0x000e, 0x0003, 0x0001, 0x0006, 0x0004, - 0x0005, 0x0003, 0x0002, 0x0000, -}; - -static const uint8_t mpa_huffbits_7[36] = { - 1, 3, 6, 8, 8, 9, 3, 4, - 6, 7, 7, 8, 6, 5, 7, 8, - 8, 9, 7, 7, 8, 9, 9, 9, - 7, 7, 8, 9, 9, 10, 8, 8, - 9, 10, 10, 10, -}; - -static const uint16_t mpa_huffcodes_8[36] = { - 0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001, - 0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e, - 0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004, - 0x000d, 0x0005, 0x0008, 0x000b, 0x0005, 0x0001, 0x000c, 0x0004, - 0x0004, 0x0001, 0x0001, 0x0000, -}; - -static const uint8_t mpa_huffbits_8[36] = { - 2, 3, 6, 8, 8, 9, 3, 2, - 4, 8, 8, 8, 6, 4, 6, 8, - 8, 9, 8, 8, 8, 9, 9, 10, - 8, 7, 8, 9, 10, 10, 9, 8, - 9, 9, 11, 11, -}; - -static const uint16_t mpa_huffcodes_9[36] = { - 0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004, - 0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008, - 0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001, - 0x000b, 0x0007, 0x0009, 0x0006, 0x0004, 0x0001, 0x000e, 0x0004, - 0x0006, 0x0002, 0x0006, 0x0000, -}; - -static const uint8_t mpa_huffbits_9[36] = { - 3, 3, 5, 6, 8, 9, 3, 3, - 4, 5, 6, 8, 4, 4, 5, 6, - 7, 8, 6, 5, 6, 7, 7, 8, - 7, 6, 7, 7, 8, 9, 8, 7, - 8, 8, 9, 9, -}; - -static const uint16_t mpa_huffcodes_10[64] = { - 0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011, - 0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007, - 0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006, - 0x000e, 0x000d, 0x0016, 0x0022, 0x002e, 0x0017, 0x0012, 0x0007, - 0x0014, 0x0013, 0x0021, 0x002f, 0x001b, 0x0016, 0x0009, 0x0003, - 0x001f, 0x0016, 0x0029, 0x001a, 0x0015, 0x0014, 0x0005, 0x0003, - 0x000e, 0x000d, 0x000a, 0x000b, 0x0010, 0x0006, 0x0005, 0x0001, - 0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000, -}; - -static const uint8_t mpa_huffbits_10[64] = { - 1, 3, 6, 8, 9, 9, 9, 10, - 3, 4, 6, 7, 8, 9, 8, 8, - 6, 6, 7, 8, 9, 10, 9, 9, - 7, 7, 8, 9, 10, 10, 9, 10, - 8, 8, 9, 10, 10, 10, 10, 10, - 9, 9, 10, 10, 11, 11, 10, 11, - 8, 8, 9, 10, 10, 10, 11, 11, - 9, 8, 9, 10, 10, 11, 11, 11, -}; - -static const uint16_t mpa_huffcodes_11[64] = { - 0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f, - 0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a, - 0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005, - 0x0019, 0x000b, 0x0013, 0x003b, 0x001b, 0x0012, 0x000c, 0x0005, - 0x0023, 0x0021, 0x001f, 0x003a, 0x001e, 0x0010, 0x0007, 0x0005, - 0x001c, 0x001a, 0x0020, 0x0013, 0x0011, 0x000f, 0x0008, 0x000e, - 0x000e, 0x000c, 0x0009, 0x000d, 0x000e, 0x0009, 0x0004, 0x0001, - 0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000, -}; - -static const uint8_t mpa_huffbits_11[64] = { - 2, 3, 5, 7, 8, 9, 8, 9, - 3, 3, 4, 6, 8, 8, 7, 8, - 5, 5, 6, 7, 8, 9, 8, 8, - 7, 6, 7, 9, 8, 10, 8, 9, - 8, 8, 8, 9, 9, 10, 9, 10, - 8, 8, 9, 10, 10, 11, 10, 11, - 8, 7, 7, 8, 9, 10, 10, 10, - 8, 7, 8, 9, 10, 10, 10, 10, -}; - -static const uint16_t mpa_huffcodes_12[64] = { - 0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a, - 0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b, - 0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007, - 0x0011, 0x000a, 0x000f, 0x000c, 0x0012, 0x001c, 0x000e, 0x0005, - 0x0020, 0x000d, 0x0016, 0x0013, 0x0012, 0x0010, 0x0009, 0x0005, - 0x0028, 0x0011, 0x001f, 0x001d, 0x0011, 0x000d, 0x0004, 0x0002, - 0x001b, 0x000c, 0x000b, 0x000f, 0x000a, 0x0007, 0x0004, 0x0001, - 0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000, -}; - -static const uint8_t mpa_huffbits_12[64] = { - 4, 3, 5, 7, 8, 9, 9, 9, - 3, 3, 4, 5, 7, 7, 8, 8, - 5, 4, 5, 6, 7, 8, 7, 8, - 6, 5, 6, 6, 7, 8, 8, 8, - 7, 6, 7, 7, 8, 8, 8, 9, - 8, 7, 8, 8, 8, 9, 8, 9, - 8, 7, 7, 8, 8, 9, 9, 10, - 9, 8, 8, 9, 9, 9, 9, 10, -}; - -static const uint16_t mpa_huffcodes_13[256] = { - 0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047, - 0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013, - 0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021, - 0x001f, 0x0018, 0x0020, 0x0018, 0x001f, 0x0023, 0x0016, 0x000e, - 0x000f, 0x000d, 0x0017, 0x0024, 0x003b, 0x0031, 0x004d, 0x0041, - 0x001d, 0x0028, 0x001e, 0x0028, 0x001b, 0x0021, 0x002a, 0x0010, - 0x0016, 0x0014, 0x0025, 0x003d, 0x0038, 0x004f, 0x0049, 0x0040, - 0x002b, 0x004c, 0x0038, 0x0025, 0x001a, 0x001f, 0x0019, 0x000e, - 0x0023, 0x0010, 0x003c, 0x0039, 0x0061, 0x004b, 0x0072, 0x005b, - 0x0036, 0x0049, 0x0037, 0x0029, 0x0030, 0x0035, 0x0017, 0x0018, - 0x003a, 0x001b, 0x0032, 0x0060, 0x004c, 0x0046, 0x005d, 0x0054, - 0x004d, 0x003a, 0x004f, 0x001d, 0x004a, 0x0031, 0x0029, 0x0011, - 0x002f, 0x002d, 0x004e, 0x004a, 0x0073, 0x005e, 0x005a, 0x004f, - 0x0045, 0x0053, 0x0047, 0x0032, 0x003b, 0x0026, 0x0024, 0x000f, - 0x0048, 0x0022, 0x0038, 0x005f, 0x005c, 0x0055, 0x005b, 0x005a, - 0x0056, 0x0049, 0x004d, 0x0041, 0x0033, 0x002c, 0x002b, 0x002a, - 0x002b, 0x0014, 0x001e, 0x002c, 0x0037, 0x004e, 0x0048, 0x0057, - 0x004e, 0x003d, 0x002e, 0x0036, 0x0025, 0x001e, 0x0014, 0x0010, - 0x0035, 0x0019, 0x0029, 0x0025, 0x002c, 0x003b, 0x0036, 0x0051, - 0x0042, 0x004c, 0x0039, 0x0036, 0x0025, 0x0012, 0x0027, 0x000b, - 0x0023, 0x0021, 0x001f, 0x0039, 0x002a, 0x0052, 0x0048, 0x0050, - 0x002f, 0x003a, 0x0037, 0x0015, 0x0016, 0x001a, 0x0026, 0x0016, - 0x0035, 0x0019, 0x0017, 0x0026, 0x0046, 0x003c, 0x0033, 0x0024, - 0x0037, 0x001a, 0x0022, 0x0017, 0x001b, 0x000e, 0x0009, 0x0007, - 0x0022, 0x0020, 0x001c, 0x0027, 0x0031, 0x004b, 0x001e, 0x0034, - 0x0030, 0x0028, 0x0034, 0x001c, 0x0012, 0x0011, 0x0009, 0x0005, - 0x002d, 0x0015, 0x0022, 0x0040, 0x0038, 0x0032, 0x0031, 0x002d, - 0x001f, 0x0013, 0x000c, 0x000f, 0x000a, 0x0007, 0x0006, 0x0003, - 0x0030, 0x0017, 0x0014, 0x0027, 0x0024, 0x0023, 0x0035, 0x0015, - 0x0010, 0x0017, 0x000d, 0x000a, 0x0006, 0x0001, 0x0004, 0x0002, - 0x0010, 0x000f, 0x0011, 0x001b, 0x0019, 0x0014, 0x001d, 0x000b, - 0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001, -}; - -static const uint8_t mpa_huffbits_13[256] = { - 1, 4, 6, 7, 8, 9, 9, 10, - 9, 10, 11, 11, 12, 12, 13, 13, - 3, 4, 6, 7, 8, 8, 9, 9, - 9, 9, 10, 10, 11, 12, 12, 12, - 6, 6, 7, 8, 9, 9, 10, 10, - 9, 10, 10, 11, 11, 12, 13, 13, - 7, 7, 8, 9, 9, 10, 10, 10, - 10, 11, 11, 11, 11, 12, 13, 13, - 8, 7, 9, 9, 10, 10, 11, 11, - 10, 11, 11, 12, 12, 13, 13, 14, - 9, 8, 9, 10, 10, 10, 11, 11, - 11, 11, 12, 11, 13, 13, 14, 14, - 9, 9, 10, 10, 11, 11, 11, 11, - 11, 12, 12, 12, 13, 13, 14, 14, - 10, 9, 10, 11, 11, 11, 12, 12, - 12, 12, 13, 13, 13, 14, 16, 16, - 9, 8, 9, 10, 10, 11, 11, 12, - 12, 12, 12, 13, 13, 14, 15, 15, - 10, 9, 10, 10, 11, 11, 11, 13, - 12, 13, 13, 14, 14, 14, 16, 15, - 10, 10, 10, 11, 11, 12, 12, 13, - 12, 13, 14, 13, 14, 15, 16, 17, - 11, 10, 10, 11, 12, 12, 12, 12, - 13, 13, 13, 14, 15, 15, 15, 16, - 11, 11, 11, 12, 12, 13, 12, 13, - 14, 14, 15, 15, 15, 16, 16, 16, - 12, 11, 12, 13, 13, 13, 14, 14, - 14, 14, 14, 15, 16, 15, 16, 16, - 13, 12, 12, 13, 13, 13, 15, 14, - 14, 17, 15, 15, 15, 17, 16, 16, - 12, 12, 13, 14, 14, 14, 15, 14, - 15, 15, 16, 16, 19, 18, 19, 16, -}; - -static const uint16_t mpa_huffcodes_15[256] = { - 0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c, - 0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f, - 0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033, - 0x002a, 0x0046, 0x0034, 0x0053, 0x0041, 0x0029, 0x003b, 0x0024, - 0x0013, 0x0011, 0x000f, 0x0018, 0x0029, 0x0022, 0x003b, 0x0030, - 0x0028, 0x0040, 0x0032, 0x004e, 0x003e, 0x0050, 0x0038, 0x0021, - 0x001d, 0x001c, 0x0019, 0x002b, 0x0027, 0x003f, 0x0037, 0x005d, - 0x004c, 0x003b, 0x005d, 0x0048, 0x0036, 0x004b, 0x0032, 0x001d, - 0x0034, 0x0016, 0x002a, 0x0028, 0x0043, 0x0039, 0x005f, 0x004f, - 0x0048, 0x0039, 0x0059, 0x0045, 0x0031, 0x0042, 0x002e, 0x001b, - 0x004d, 0x0025, 0x0023, 0x0042, 0x003a, 0x0034, 0x005b, 0x004a, - 0x003e, 0x0030, 0x004f, 0x003f, 0x005a, 0x003e, 0x0028, 0x0026, - 0x007d, 0x0020, 0x003c, 0x0038, 0x0032, 0x005c, 0x004e, 0x0041, - 0x0037, 0x0057, 0x0047, 0x0033, 0x0049, 0x0033, 0x0046, 0x001e, - 0x006d, 0x0035, 0x0031, 0x005e, 0x0058, 0x004b, 0x0042, 0x007a, - 0x005b, 0x0049, 0x0038, 0x002a, 0x0040, 0x002c, 0x0015, 0x0019, - 0x005a, 0x002b, 0x0029, 0x004d, 0x0049, 0x003f, 0x0038, 0x005c, - 0x004d, 0x0042, 0x002f, 0x0043, 0x0030, 0x0035, 0x0024, 0x0014, - 0x0047, 0x0022, 0x0043, 0x003c, 0x003a, 0x0031, 0x0058, 0x004c, - 0x0043, 0x006a, 0x0047, 0x0036, 0x0026, 0x0027, 0x0017, 0x000f, - 0x006d, 0x0035, 0x0033, 0x002f, 0x005a, 0x0052, 0x003a, 0x0039, - 0x0030, 0x0048, 0x0039, 0x0029, 0x0017, 0x001b, 0x003e, 0x0009, - 0x0056, 0x002a, 0x0028, 0x0025, 0x0046, 0x0040, 0x0034, 0x002b, - 0x0046, 0x0037, 0x002a, 0x0019, 0x001d, 0x0012, 0x000b, 0x000b, - 0x0076, 0x0044, 0x001e, 0x0037, 0x0032, 0x002e, 0x004a, 0x0041, - 0x0031, 0x0027, 0x0018, 0x0010, 0x0016, 0x000d, 0x000e, 0x0007, - 0x005b, 0x002c, 0x0027, 0x0026, 0x0022, 0x003f, 0x0034, 0x002d, - 0x001f, 0x0034, 0x001c, 0x0013, 0x000e, 0x0008, 0x0009, 0x0003, - 0x007b, 0x003c, 0x003a, 0x0035, 0x002f, 0x002b, 0x0020, 0x0016, - 0x0025, 0x0018, 0x0011, 0x000c, 0x000f, 0x000a, 0x0002, 0x0001, - 0x0047, 0x0025, 0x0022, 0x001e, 0x001c, 0x0014, 0x0011, 0x001a, - 0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000, -}; - -static const uint8_t mpa_huffbits_15[256] = { - 3, 4, 5, 7, 7, 8, 9, 9, - 9, 10, 10, 11, 11, 11, 12, 13, - 4, 3, 5, 6, 7, 7, 8, 8, - 8, 9, 9, 10, 10, 10, 11, 11, - 5, 5, 5, 6, 7, 7, 8, 8, - 8, 9, 9, 10, 10, 11, 11, 11, - 6, 6, 6, 7, 7, 8, 8, 9, - 9, 9, 10, 10, 10, 11, 11, 11, - 7, 6, 7, 7, 8, 8, 9, 9, - 9, 9, 10, 10, 10, 11, 11, 11, - 8, 7, 7, 8, 8, 8, 9, 9, - 9, 9, 10, 10, 11, 11, 11, 12, - 9, 7, 8, 8, 8, 9, 9, 9, - 9, 10, 10, 10, 11, 11, 12, 12, - 9, 8, 8, 9, 9, 9, 9, 10, - 10, 10, 10, 10, 11, 11, 11, 12, - 9, 8, 8, 9, 9, 9, 9, 10, - 10, 10, 10, 11, 11, 12, 12, 12, - 9, 8, 9, 9, 9, 9, 10, 10, - 10, 11, 11, 11, 11, 12, 12, 12, - 10, 9, 9, 9, 10, 10, 10, 10, - 10, 11, 11, 11, 11, 12, 13, 12, - 10, 9, 9, 9, 10, 10, 10, 10, - 11, 11, 11, 11, 12, 12, 12, 13, - 11, 10, 9, 10, 10, 10, 11, 11, - 11, 11, 11, 11, 12, 12, 13, 13, - 11, 10, 10, 10, 10, 11, 11, 11, - 11, 12, 12, 12, 12, 12, 13, 13, - 12, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 13, 13, 12, 13, - 12, 11, 11, 11, 11, 11, 11, 12, - 12, 12, 12, 12, 13, 13, 13, 13, -}; - -static const uint16_t mpa_huffcodes_16[256] = { - 0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d, - 0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011, - 0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f, - 0x0053, 0x004b, 0x0044, 0x0077, 0x00c9, 0x006b, 0x00cf, 0x0009, - 0x000f, 0x000d, 0x0017, 0x0026, 0x0043, 0x003a, 0x0067, 0x005a, - 0x00a1, 0x0048, 0x007f, 0x0075, 0x006e, 0x00d1, 0x00ce, 0x0010, - 0x002d, 0x0015, 0x0027, 0x0045, 0x0040, 0x0072, 0x0063, 0x0057, - 0x009e, 0x008c, 0x00fc, 0x00d4, 0x00c7, 0x0183, 0x016d, 0x001a, - 0x004b, 0x0024, 0x0044, 0x0041, 0x0073, 0x0065, 0x00b3, 0x00a4, - 0x009b, 0x0108, 0x00f6, 0x00e2, 0x018b, 0x017e, 0x016a, 0x0009, - 0x0042, 0x001e, 0x003b, 0x0038, 0x0066, 0x00b9, 0x00ad, 0x0109, - 0x008e, 0x00fd, 0x00e8, 0x0190, 0x0184, 0x017a, 0x01bd, 0x0010, - 0x006f, 0x0036, 0x0034, 0x0064, 0x00b8, 0x00b2, 0x00a0, 0x0085, - 0x0101, 0x00f4, 0x00e4, 0x00d9, 0x0181, 0x016e, 0x02cb, 0x000a, - 0x0062, 0x0030, 0x005b, 0x0058, 0x00a5, 0x009d, 0x0094, 0x0105, - 0x00f8, 0x0197, 0x018d, 0x0174, 0x017c, 0x0379, 0x0374, 0x0008, - 0x0055, 0x0054, 0x0051, 0x009f, 0x009c, 0x008f, 0x0104, 0x00f9, - 0x01ab, 0x0191, 0x0188, 0x017f, 0x02d7, 0x02c9, 0x02c4, 0x0007, - 0x009a, 0x004c, 0x0049, 0x008d, 0x0083, 0x0100, 0x00f5, 0x01aa, - 0x0196, 0x018a, 0x0180, 0x02df, 0x0167, 0x02c6, 0x0160, 0x000b, - 0x008b, 0x0081, 0x0043, 0x007d, 0x00f7, 0x00e9, 0x00e5, 0x00db, - 0x0189, 0x02e7, 0x02e1, 0x02d0, 0x0375, 0x0372, 0x01b7, 0x0004, - 0x00f3, 0x0078, 0x0076, 0x0073, 0x00e3, 0x00df, 0x018c, 0x02ea, - 0x02e6, 0x02e0, 0x02d1, 0x02c8, 0x02c2, 0x00df, 0x01b4, 0x0006, - 0x00ca, 0x00e0, 0x00de, 0x00da, 0x00d8, 0x0185, 0x0182, 0x017d, - 0x016c, 0x0378, 0x01bb, 0x02c3, 0x01b8, 0x01b5, 0x06c0, 0x0004, - 0x02eb, 0x00d3, 0x00d2, 0x00d0, 0x0172, 0x017b, 0x02de, 0x02d3, - 0x02ca, 0x06c7, 0x0373, 0x036d, 0x036c, 0x0d83, 0x0361, 0x0002, - 0x0179, 0x0171, 0x0066, 0x00bb, 0x02d6, 0x02d2, 0x0166, 0x02c7, - 0x02c5, 0x0362, 0x06c6, 0x0367, 0x0d82, 0x0366, 0x01b2, 0x0000, - 0x000c, 0x000a, 0x0007, 0x000b, 0x000a, 0x0011, 0x000b, 0x0009, - 0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003, -}; - -static const uint8_t mpa_huffbits_16[256] = { - 1, 4, 6, 8, 9, 9, 10, 10, - 11, 11, 11, 12, 12, 12, 13, 9, - 3, 4, 6, 7, 8, 9, 9, 9, - 10, 10, 10, 11, 12, 11, 12, 8, - 6, 6, 7, 8, 9, 9, 10, 10, - 11, 10, 11, 11, 11, 12, 12, 9, - 8, 7, 8, 9, 9, 10, 10, 10, - 11, 11, 12, 12, 12, 13, 13, 10, - 9, 8, 9, 9, 10, 10, 11, 11, - 11, 12, 12, 12, 13, 13, 13, 9, - 9, 8, 9, 9, 10, 11, 11, 12, - 11, 12, 12, 13, 13, 13, 14, 10, - 10, 9, 9, 10, 11, 11, 11, 11, - 12, 12, 12, 12, 13, 13, 14, 10, - 10, 9, 10, 10, 11, 11, 11, 12, - 12, 13, 13, 13, 13, 15, 15, 10, - 10, 10, 10, 11, 11, 11, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 10, - 11, 10, 10, 11, 11, 12, 12, 13, - 13, 13, 13, 14, 13, 14, 13, 11, - 11, 11, 10, 11, 12, 12, 12, 12, - 13, 14, 14, 14, 15, 15, 14, 10, - 12, 11, 11, 11, 12, 12, 13, 14, - 14, 14, 14, 14, 14, 13, 14, 11, - 12, 12, 12, 12, 12, 13, 13, 13, - 13, 15, 14, 14, 14, 14, 16, 11, - 14, 12, 12, 12, 13, 13, 14, 14, - 14, 16, 15, 15, 15, 17, 15, 11, - 13, 13, 11, 12, 14, 14, 13, 14, - 14, 15, 16, 15, 17, 15, 14, 11, - 9, 8, 8, 9, 9, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 8, -}; - -static const uint16_t mpa_huffcodes_24[256] = { - 0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2, - 0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058, - 0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8, - 0x00d1, 0x00c6, 0x0147, 0x0159, 0x013f, 0x0129, 0x0117, 0x002a, - 0x002f, 0x0016, 0x0029, 0x004a, 0x0044, 0x0080, 0x0078, 0x00dd, - 0x00cf, 0x00c2, 0x00b6, 0x0154, 0x013b, 0x0127, 0x021d, 0x0012, - 0x0051, 0x0027, 0x004b, 0x0046, 0x0086, 0x007d, 0x0074, 0x00dc, - 0x00cc, 0x00be, 0x00b2, 0x0145, 0x0137, 0x0125, 0x010f, 0x0010, - 0x0093, 0x0048, 0x0045, 0x0087, 0x007f, 0x0076, 0x0070, 0x00d2, - 0x00c8, 0x00bc, 0x0160, 0x0143, 0x0132, 0x011d, 0x021c, 0x000e, - 0x0107, 0x0042, 0x0081, 0x007e, 0x0077, 0x0072, 0x00d6, 0x00ca, - 0x00c0, 0x00b4, 0x0155, 0x013d, 0x012d, 0x0119, 0x0106, 0x000c, - 0x00f9, 0x007b, 0x0079, 0x0075, 0x0071, 0x00d7, 0x00ce, 0x00c3, - 0x00b9, 0x015b, 0x014a, 0x0134, 0x0123, 0x0110, 0x0208, 0x000a, - 0x01b3, 0x0073, 0x006f, 0x006d, 0x00d3, 0x00cb, 0x00c4, 0x00bb, - 0x0161, 0x014c, 0x0139, 0x012a, 0x011b, 0x0213, 0x017d, 0x0011, - 0x01ab, 0x00d4, 0x00d0, 0x00cd, 0x00c9, 0x00c1, 0x00ba, 0x00b1, - 0x00a9, 0x0140, 0x012f, 0x011e, 0x010c, 0x0202, 0x0179, 0x0010, - 0x014f, 0x00c7, 0x00c5, 0x00bf, 0x00bd, 0x00b5, 0x00ae, 0x014d, - 0x0141, 0x0131, 0x0121, 0x0113, 0x0209, 0x017b, 0x0173, 0x000b, - 0x029c, 0x00b8, 0x00b7, 0x00b3, 0x00af, 0x0158, 0x014b, 0x013a, - 0x0130, 0x0122, 0x0115, 0x0212, 0x017f, 0x0175, 0x016e, 0x000a, - 0x028c, 0x015a, 0x00ab, 0x00a8, 0x00a4, 0x013e, 0x0135, 0x012b, - 0x011f, 0x0114, 0x0107, 0x0201, 0x0177, 0x0170, 0x016a, 0x0006, - 0x0288, 0x0142, 0x013c, 0x0138, 0x0133, 0x012e, 0x0124, 0x011c, - 0x010d, 0x0105, 0x0200, 0x0178, 0x0172, 0x016c, 0x0167, 0x0004, - 0x026c, 0x012c, 0x0128, 0x0126, 0x0120, 0x011a, 0x0111, 0x010a, - 0x0203, 0x017c, 0x0176, 0x0171, 0x016d, 0x0169, 0x0165, 0x0002, - 0x0409, 0x0118, 0x0116, 0x0112, 0x010b, 0x0108, 0x0103, 0x017e, - 0x017a, 0x0174, 0x016f, 0x016b, 0x0168, 0x0166, 0x0164, 0x0000, - 0x002b, 0x0014, 0x0013, 0x0011, 0x000f, 0x000d, 0x000b, 0x0009, - 0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003, -}; - -static const uint8_t mpa_huffbits_24[256] = { - 4, 4, 6, 7, 8, 9, 9, 10, - 10, 11, 11, 11, 11, 11, 12, 9, - 4, 4, 5, 6, 7, 8, 8, 9, - 9, 9, 10, 10, 10, 10, 10, 8, - 6, 5, 6, 7, 7, 8, 8, 9, - 9, 9, 9, 10, 10, 10, 11, 7, - 7, 6, 7, 7, 8, 8, 8, 9, - 9, 9, 9, 10, 10, 10, 10, 7, - 8, 7, 7, 8, 8, 8, 8, 9, - 9, 9, 10, 10, 10, 10, 11, 7, - 9, 7, 8, 8, 8, 8, 9, 9, - 9, 9, 10, 10, 10, 10, 10, 7, - 9, 8, 8, 8, 8, 9, 9, 9, - 9, 10, 10, 10, 10, 10, 11, 7, - 10, 8, 8, 8, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 11, 11, 8, - 10, 9, 9, 9, 9, 9, 9, 9, - 9, 10, 10, 10, 10, 11, 11, 8, - 10, 9, 9, 9, 9, 9, 9, 10, - 10, 10, 10, 10, 11, 11, 11, 8, - 11, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 11, 11, 11, 11, 8, - 11, 10, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 11, 11, 11, 11, 8, - 11, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 11, 11, 11, 8, - 11, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 8, - 12, 10, 10, 10, 10, 10, 10, 11, - 11, 11, 11, 11, 11, 11, 11, 8, - 8, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 8, 8, 8, 8, 4, -}; - -static const HuffTable mpa_huff_tables[16] = { -{ 1, NULL, NULL }, -{ 2, mpa_huffbits_1, mpa_huffcodes_1 }, -{ 3, mpa_huffbits_2, mpa_huffcodes_2 }, -{ 3, mpa_huffbits_3, mpa_huffcodes_3 }, -{ 4, mpa_huffbits_5, mpa_huffcodes_5 }, -{ 4, mpa_huffbits_6, mpa_huffcodes_6 }, -{ 6, mpa_huffbits_7, mpa_huffcodes_7 }, -{ 6, mpa_huffbits_8, mpa_huffcodes_8 }, -{ 6, mpa_huffbits_9, mpa_huffcodes_9 }, -{ 8, mpa_huffbits_10, mpa_huffcodes_10 }, -{ 8, mpa_huffbits_11, mpa_huffcodes_11 }, -{ 8, mpa_huffbits_12, mpa_huffcodes_12 }, -{ 16, mpa_huffbits_13, mpa_huffcodes_13 }, -{ 16, mpa_huffbits_15, mpa_huffcodes_15 }, -{ 16, mpa_huffbits_16, mpa_huffcodes_16 }, -{ 16, mpa_huffbits_24, mpa_huffcodes_24 }, -}; - -static const uint8_t mpa_huff_data[32][2] = { -{ 0, 0 }, -{ 1, 0 }, -{ 2, 0 }, -{ 3, 0 }, -{ 0, 0 }, -{ 4, 0 }, -{ 5, 0 }, -{ 6, 0 }, -{ 7, 0 }, -{ 8, 0 }, -{ 9, 0 }, -{ 10, 0 }, -{ 11, 0 }, -{ 12, 0 }, -{ 0, 0 }, -{ 13, 0 }, -{ 14, 1 }, -{ 14, 2 }, -{ 14, 3 }, -{ 14, 4 }, -{ 14, 6 }, -{ 14, 8 }, -{ 14, 10 }, -{ 14, 13 }, -{ 15, 4 }, -{ 15, 5 }, -{ 15, 6 }, -{ 15, 7 }, -{ 15, 8 }, -{ 15, 9 }, -{ 15, 11 }, -{ 15, 13 }, -}; - - -/* huffman tables for quadrules */ -static const uint8_t mpa_quad_codes[2][16] = { - { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, }, - { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, }, -}; - -static const uint8_t mpa_quad_bits[2][16] = { - { 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, }, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, }, -}; - -/* band size tables */ -static const uint8_t band_size_long[9][22] = { -{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, - 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */ -{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, - 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */ -{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, - 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */ -{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, - 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */ -{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, - 18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */ -{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, - 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */ -{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, - 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */ -{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, - 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */ -{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, - 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */ -}; - -static const uint8_t band_size_short[9][13] = { -{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */ -{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */ -{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */ -{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */ -{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */ -{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */ -{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */ -{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */ -{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */ -}; - -static const uint8_t mpa_pretab[2][22] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 2, 3, 3, 3, 2, 0 }, -}; - -/* table for alias reduction (XXX: store it as integer !) */ -static const float ci_table[8] = { - -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037, -}; - -#endif /* AVCODEC_MPEGAUDIODECTAB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudioenc.c b/tizen/distrib/ffmpeg/libavcodec/mpegaudioenc.c deleted file mode 100644 index 264175e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudioenc.c +++ /dev/null @@ -1,805 +0,0 @@ -/* - * The simplest mpeg audio layer 2 encoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * The simplest mpeg audio layer 2 encoder. - */ - -#include "avcodec.h" -#include "put_bits.h" - -#undef CONFIG_MPEGAUDIO_HP -#define CONFIG_MPEGAUDIO_HP 0 -#include "mpegaudio.h" - -/* currently, cannot change these constants (need to modify - quantization stage) */ -#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) - -#define SAMPLES_BUF_SIZE 4096 - -typedef struct MpegAudioContext { - PutBitContext pb; - int nb_channels; - int freq, bit_rate; - int lsf; /* 1 if mpeg2 low bitrate selected */ - int bitrate_index; /* bit rate */ - int freq_index; - int frame_size; /* frame size, in bits, without padding */ - int64_t nb_samples; /* total number of samples encoded */ - /* padding computation */ - int frame_frac, frame_frac_incr, do_padding; - short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */ - int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */ - int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT]; - unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */ - /* code to group 3 scale factors */ - unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT]; - int sblimit; /* number of used subbands */ - const unsigned char *alloc_table; -} MpegAudioContext; - -/* define it to use floats in quantization (I don't like floats !) */ -#define USE_FLOATS - -#include "mpegaudiodata.h" -#include "mpegaudiotab.h" - -static av_cold int MPA_encode_init(AVCodecContext *avctx) -{ - MpegAudioContext *s = avctx->priv_data; - int freq = avctx->sample_rate; - int bitrate = avctx->bit_rate; - int channels = avctx->channels; - int i, v, table; - float a; - - if (channels <= 0 || channels > 2){ - av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels); - return -1; - } - bitrate = bitrate / 1000; - s->nb_channels = channels; - s->freq = freq; - s->bit_rate = bitrate * 1000; - avctx->frame_size = MPA_FRAME_SIZE; - - /* encoding freq */ - s->lsf = 0; - for(i=0;i<3;i++) { - if (ff_mpa_freq_tab[i] == freq) - break; - if ((ff_mpa_freq_tab[i] / 2) == freq) { - s->lsf = 1; - break; - } - } - if (i == 3){ - av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq); - return -1; - } - s->freq_index = i; - - /* encoding bitrate & frequency */ - for(i=0;i<15;i++) { - if (ff_mpa_bitrate_tab[s->lsf][1][i] == bitrate) - break; - } - if (i == 15){ - av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate); - return -1; - } - s->bitrate_index = i; - - /* compute total header size & pad bit */ - - a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0); - s->frame_size = ((int)a) * 8; - - /* frame fractional size to compute padding */ - s->frame_frac = 0; - s->frame_frac_incr = (int)((a - floor(a)) * 65536.0); - - /* select the right allocation table */ - table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf); - - /* number of used subbands */ - s->sblimit = ff_mpa_sblimit_table[table]; - s->alloc_table = ff_mpa_alloc_tables[table]; - - dprintf(avctx, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n", - bitrate, freq, s->frame_size, table, s->frame_frac_incr); - - for(i=0;inb_channels;i++) - s->samples_offset[i] = 0; - - for(i=0;i<257;i++) { - int v; - v = ff_mpa_enwindow[i]; -#if WFRAC_BITS != 16 - v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); -#endif - filter_bank[i] = v; - if ((i & 63) != 0) - v = -v; - if (i != 0) - filter_bank[512 - i] = v; - } - - for(i=0;i<64;i++) { - v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20)); - if (v <= 0) - v = 1; - scale_factor_table[i] = v; -#ifdef USE_FLOATS - scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20); -#else -#define P 15 - scale_factor_shift[i] = 21 - P - (i / 3); - scale_factor_mult[i] = (1 << P) * pow(2.0, (i % 3) / 3.0); -#endif - } - for(i=0;i<128;i++) { - v = i - 64; - if (v <= -3) - v = 0; - else if (v < 0) - v = 1; - else if (v == 0) - v = 2; - else if (v < 3) - v = 3; - else - v = 4; - scale_diff_table[i] = v; - } - - for(i=0;i<17;i++) { - v = ff_mpa_quant_bits[i]; - if (v < 0) - v = -v; - else - v = v * 3; - total_quant_bits[i] = 12 * v; - } - - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; -} - -/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */ -static void idct32(int *out, int *tab) -{ - int i, j; - int *t, *t1, xr; - const int *xp = costab32; - - for(j=31;j>=3;j-=2) tab[j] += tab[j - 2]; - - t = tab + 30; - t1 = tab + 2; - do { - t[0] += t[-4]; - t[1] += t[1 - 4]; - t -= 4; - } while (t != t1); - - t = tab + 28; - t1 = tab + 4; - do { - t[0] += t[-8]; - t[1] += t[1-8]; - t[2] += t[2-8]; - t[3] += t[3-8]; - t -= 8; - } while (t != t1); - - t = tab; - t1 = tab + 32; - do { - t[ 3] = -t[ 3]; - t[ 6] = -t[ 6]; - - t[11] = -t[11]; - t[12] = -t[12]; - t[13] = -t[13]; - t[15] = -t[15]; - t += 16; - } while (t != t1); - - - t = tab; - t1 = tab + 8; - do { - int x1, x2, x3, x4; - - x3 = MUL(t[16], FIX(SQRT2*0.5)); - x4 = t[0] - x3; - x3 = t[0] + x3; - - x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5)); - x1 = MUL((t[8] - x2), xp[0]); - x2 = MUL((t[8] + x2), xp[1]); - - t[ 0] = x3 + x1; - t[ 8] = x4 - x2; - t[16] = x4 + x2; - t[24] = x3 - x1; - t++; - } while (t != t1); - - xp += 2; - t = tab; - t1 = tab + 4; - do { - xr = MUL(t[28],xp[0]); - t[28] = (t[0] - xr); - t[0] = (t[0] + xr); - - xr = MUL(t[4],xp[1]); - t[ 4] = (t[24] - xr); - t[24] = (t[24] + xr); - - xr = MUL(t[20],xp[2]); - t[20] = (t[8] - xr); - t[ 8] = (t[8] + xr); - - xr = MUL(t[12],xp[3]); - t[12] = (t[16] - xr); - t[16] = (t[16] + xr); - t++; - } while (t != t1); - xp += 4; - - for (i = 0; i < 4; i++) { - xr = MUL(tab[30-i*4],xp[0]); - tab[30-i*4] = (tab[i*4] - xr); - tab[ i*4] = (tab[i*4] + xr); - - xr = MUL(tab[ 2+i*4],xp[1]); - tab[ 2+i*4] = (tab[28-i*4] - xr); - tab[28-i*4] = (tab[28-i*4] + xr); - - xr = MUL(tab[31-i*4],xp[0]); - tab[31-i*4] = (tab[1+i*4] - xr); - tab[ 1+i*4] = (tab[1+i*4] + xr); - - xr = MUL(tab[ 3+i*4],xp[1]); - tab[ 3+i*4] = (tab[29-i*4] - xr); - tab[29-i*4] = (tab[29-i*4] + xr); - - xp += 2; - } - - t = tab + 30; - t1 = tab + 1; - do { - xr = MUL(t1[0], *xp); - t1[0] = (t[0] - xr); - t[0] = (t[0] + xr); - t -= 2; - t1 += 2; - xp++; - } while (t >= tab); - - for(i=0;i<32;i++) { - out[i] = tab[bitinv32[i]]; - } -} - -#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS) - -static void filter(MpegAudioContext *s, int ch, short *samples, int incr) -{ - short *p, *q; - int sum, offset, i, j; - int tmp[64]; - int tmp1[32]; - int *out; - - // print_pow1(samples, 1152); - - offset = s->samples_offset[ch]; - out = &s->sb_samples[ch][0][0][0]; - for(j=0;j<36;j++) { - /* 32 samples at once */ - for(i=0;i<32;i++) { - s->samples_buf[ch][offset + (31 - i)] = samples[0]; - samples += incr; - } - - /* filter */ - p = s->samples_buf[ch] + offset; - q = filter_bank; - /* maxsum = 23169 */ - for(i=0;i<64;i++) { - sum = p[0*64] * q[0*64]; - sum += p[1*64] * q[1*64]; - sum += p[2*64] * q[2*64]; - sum += p[3*64] * q[3*64]; - sum += p[4*64] * q[4*64]; - sum += p[5*64] * q[5*64]; - sum += p[6*64] * q[6*64]; - sum += p[7*64] * q[7*64]; - tmp[i] = sum; - p++; - q++; - } - tmp1[0] = tmp[16] >> WSHIFT; - for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT; - for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT; - - idct32(out, tmp1); - - /* advance of 32 samples */ - offset -= 32; - out += 32; - /* handle the wrap around */ - if (offset < 0) { - memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32), - s->samples_buf[ch], (512 - 32) * 2); - offset = SAMPLES_BUF_SIZE - 512; - } - } - s->samples_offset[ch] = offset; - - // print_pow(s->sb_samples, 1152); -} - -static void compute_scale_factors(unsigned char scale_code[SBLIMIT], - unsigned char scale_factors[SBLIMIT][3], - int sb_samples[3][12][SBLIMIT], - int sblimit) -{ - int *p, vmax, v, n, i, j, k, code; - int index, d1, d2; - unsigned char *sf = &scale_factors[0][0]; - - for(j=0;j vmax) - vmax = v; - } - /* compute the scale factor index using log 2 computations */ - if (vmax > 1) { - n = av_log2(vmax); - /* n is the position of the MSB of vmax. now - use at most 2 compares to find the index */ - index = (21 - n) * 3 - 3; - if (index >= 0) { - while (vmax <= scale_factor_table[index+1]) - index++; - } else { - index = 0; /* very unlikely case of overflow */ - } - } else { - index = 62; /* value 63 is not allowed */ - } - -#if 0 - printf("%2d:%d in=%x %x %d\n", - j, i, vmax, scale_factor_table[index], index); -#endif - /* store the scale factor */ - assert(index >=0 && index <= 63); - sf[i] = index; - } - - /* compute the transmission factor : look if the scale factors - are close enough to each other */ - d1 = scale_diff_table[sf[0] - sf[1] + 64]; - d2 = scale_diff_table[sf[1] - sf[2] + 64]; - - /* handle the 25 cases */ - switch(d1 * 5 + d2) { - case 0*5+0: - case 0*5+4: - case 3*5+4: - case 4*5+0: - case 4*5+4: - code = 0; - break; - case 0*5+1: - case 0*5+2: - case 4*5+1: - case 4*5+2: - code = 3; - sf[2] = sf[1]; - break; - case 0*5+3: - case 4*5+3: - code = 3; - sf[1] = sf[2]; - break; - case 1*5+0: - case 1*5+4: - case 2*5+4: - code = 1; - sf[1] = sf[0]; - break; - case 1*5+1: - case 1*5+2: - case 2*5+0: - case 2*5+1: - case 2*5+2: - code = 2; - sf[1] = sf[2] = sf[0]; - break; - case 2*5+3: - case 3*5+3: - code = 2; - sf[0] = sf[1] = sf[2]; - break; - case 3*5+0: - case 3*5+1: - case 3*5+2: - code = 2; - sf[0] = sf[2] = sf[1]; - break; - case 1*5+3: - code = 2; - if (sf[0] > sf[2]) - sf[0] = sf[2]; - sf[1] = sf[2] = sf[0]; - break; - default: - assert(0); //cannot happen - code = 0; /* kill warning */ - } - -#if 0 - printf("%d: %2d %2d %2d %d %d -> %d\n", j, - sf[0], sf[1], sf[2], d1, d2, code); -#endif - scale_code[j] = code; - sf += 3; - } -} - -/* The most important function : psycho acoustic module. In this - encoder there is basically none, so this is the worst you can do, - but also this is the simpler. */ -static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT]) -{ - int i; - - for(i=0;isblimit;i++) { - smr[i] = (int)(fixed_smr[i] * 10); - } -} - - -#define SB_NOTALLOCATED 0 -#define SB_ALLOCATED 1 -#define SB_NOMORE 2 - -/* Try to maximize the smr while using a number of bits inferior to - the frame size. I tried to make the code simpler, faster and - smaller than other encoders :-) */ -static void compute_bit_allocation(MpegAudioContext *s, - short smr1[MPA_MAX_CHANNELS][SBLIMIT], - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int *padding) -{ - int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size; - int incr; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT]; - const unsigned char *alloc; - - memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT); - memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT); - memset(bit_alloc, 0, s->nb_channels * SBLIMIT); - - /* compute frame size and padding */ - max_frame_size = s->frame_size; - s->frame_frac += s->frame_frac_incr; - if (s->frame_frac >= 65536) { - s->frame_frac -= 65536; - s->do_padding = 1; - max_frame_size += 8; - } else { - s->do_padding = 0; - } - - /* compute the header + bit alloc size */ - current_frame_size = 32; - alloc = s->alloc_table; - for(i=0;isblimit;i++) { - incr = alloc[0]; - current_frame_size += incr * s->nb_channels; - alloc += 1 << incr; - } - for(;;) { - /* look for the subband with the largest signal to mask ratio */ - max_sb = -1; - max_ch = -1; - max_smr = INT_MIN; - for(ch=0;chnb_channels;ch++) { - for(i=0;isblimit;i++) { - if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) { - max_smr = smr[ch][i]; - max_sb = i; - max_ch = ch; - } - } - } -#if 0 - printf("current=%d max=%d max_sb=%d alloc=%d\n", - current_frame_size, max_frame_size, max_sb, - bit_alloc[max_sb]); -#endif - if (max_sb < 0) - break; - - /* find alloc table entry (XXX: not optimal, should use - pointer table) */ - alloc = s->alloc_table; - for(i=0;iscale_code[max_ch][max_sb]] * 6; - incr += total_quant_bits[alloc[1]]; - } else { - /* increments bit allocation */ - b = bit_alloc[max_ch][max_sb]; - incr = total_quant_bits[alloc[b + 1]] - - total_quant_bits[alloc[b]]; - } - - if (current_frame_size + incr <= max_frame_size) { - /* can increase size */ - b = ++bit_alloc[max_ch][max_sb]; - current_frame_size += incr; - /* decrease smr by the resolution we added */ - smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]]; - /* max allocation size reached ? */ - if (b == ((1 << alloc[0]) - 1)) - subband_status[max_ch][max_sb] = SB_NOMORE; - else - subband_status[max_ch][max_sb] = SB_ALLOCATED; - } else { - /* cannot increase the size of this subband */ - subband_status[max_ch][max_sb] = SB_NOMORE; - } - } - *padding = max_frame_size - current_frame_size; - assert(*padding >= 0); - -#if 0 - for(i=0;isblimit;i++) { - printf("%d ", bit_alloc[i]); - } - printf("\n"); -#endif -} - -/* - * Output the mpeg audio layer 2 frame. Note how the code is small - * compared to other encoders :-) - */ -static void encode_frame(MpegAudioContext *s, - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int padding) -{ - int i, j, k, l, bit_alloc_bits, b, ch; - unsigned char *sf; - int q[3]; - PutBitContext *p = &s->pb; - - /* header */ - - put_bits(p, 12, 0xfff); - put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */ - put_bits(p, 2, 4-2); /* layer 2 */ - put_bits(p, 1, 1); /* no error protection */ - put_bits(p, 4, s->bitrate_index); - put_bits(p, 2, s->freq_index); - put_bits(p, 1, s->do_padding); /* use padding */ - put_bits(p, 1, 0); /* private_bit */ - put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO); - put_bits(p, 2, 0); /* mode_ext */ - put_bits(p, 1, 0); /* no copyright */ - put_bits(p, 1, 1); /* original */ - put_bits(p, 2, 0); /* no emphasis */ - - /* bit allocation */ - j = 0; - for(i=0;isblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;chnb_channels;ch++) { - put_bits(p, bit_alloc_bits, bit_alloc[ch][i]); - } - j += 1 << bit_alloc_bits; - } - - /* scale codes */ - for(i=0;isblimit;i++) { - for(ch=0;chnb_channels;ch++) { - if (bit_alloc[ch][i]) - put_bits(p, 2, s->scale_code[ch][i]); - } - } - - /* scale factors */ - for(i=0;isblimit;i++) { - for(ch=0;chnb_channels;ch++) { - if (bit_alloc[ch][i]) { - sf = &s->scale_factors[ch][i][0]; - switch(s->scale_code[ch][i]) { - case 0: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[1]); - put_bits(p, 6, sf[2]); - break; - case 3: - case 1: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[2]); - break; - case 2: - put_bits(p, 6, sf[0]); - break; - } - } - } - } - - /* quantization & write sub band samples */ - - for(k=0;k<3;k++) { - for(l=0;l<12;l+=3) { - j = 0; - for(i=0;isblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;chnb_channels;ch++) { - b = bit_alloc[ch][i]; - if (b) { - int qindex, steps, m, sample, bits; - /* we encode 3 sub band samples of the same sub band at a time */ - qindex = s->alloc_table[j+b]; - steps = ff_mpa_quant_steps[qindex]; - for(m=0;m<3;m++) { - sample = s->sb_samples[ch][k][l + m][i]; - /* divide by scale factor */ -#ifdef USE_FLOATS - { - float a; - a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]]; - q[m] = (int)((a + 1.0) * steps * 0.5); - } -#else - { - int q1, e, shift, mult; - e = s->scale_factors[ch][i][k]; - shift = scale_factor_shift[e]; - mult = scale_factor_mult[e]; - - /* normalize to P bits */ - if (shift < 0) - q1 = sample << (-shift); - else - q1 = sample >> shift; - q1 = (q1 * mult) >> P; - q[m] = ((q1 + (1 << P)) * steps) >> (P + 1); - } -#endif - if (q[m] >= steps) - q[m] = steps - 1; - assert(q[m] >= 0 && q[m] < steps); - } - bits = ff_mpa_quant_bits[qindex]; - if (bits < 0) { - /* group the 3 values to save bits */ - put_bits(p, -bits, - q[0] + steps * (q[1] + steps * q[2])); -#if 0 - printf("%d: gr1 %d\n", - i, q[0] + steps * (q[1] + steps * q[2])); -#endif - } else { -#if 0 - printf("%d: gr3 %d %d %d\n", - i, q[0], q[1], q[2]); -#endif - put_bits(p, bits, q[0]); - put_bits(p, bits, q[1]); - put_bits(p, bits, q[2]); - } - } - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - } - } - - /* padding */ - for(i=0;ipriv_data; - short *samples = data; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; - int padding, i; - - for(i=0;inb_channels;i++) { - filter(s, i, samples + i, s->nb_channels); - } - - for(i=0;inb_channels;i++) { - compute_scale_factors(s->scale_code[i], s->scale_factors[i], - s->sb_samples[i], s->sblimit); - } - for(i=0;inb_channels;i++) { - psycho_acoustic_model(s, smr[i]); - } - compute_bit_allocation(s, smr, bit_alloc, &padding); - - init_put_bits(&s->pb, frame, MPA_MAX_CODED_FRAME_SIZE); - - encode_frame(s, bit_alloc, padding); - - s->nb_samples += MPA_FRAME_SIZE; - return put_bits_ptr(&s->pb) - s->pb.buf; -} - -static av_cold int MPA_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - return 0; -} - -AVCodec mp2_encoder = { - "mp2", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_MP2, - sizeof(MpegAudioContext), - MPA_encode_init, - MPA_encode_frame, - MPA_encode_close, - NULL, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .supported_samplerates= (const int[]){44100, 48000, 32000, 22050, 24000, 16000, 0}, - .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), -}; - -#undef FIX diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegaudiotab.h b/tizen/distrib/ffmpeg/libavcodec/mpegaudiotab.h deleted file mode 100644 index 35129e6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegaudiotab.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * mpeg audio layer 2 tables. Most of them come from the mpeg audio - * specification. - * - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * mpeg audio layer 2 tables. - * Most of them come from the mpeg audio specification. - */ - -#ifndef AVCODEC_MPEGAUDIOTAB_H -#define AVCODEC_MPEGAUDIOTAB_H - -#include -#include "mpegaudio.h" - -#define SQRT2 1.41421356237309514547 - -static const int costab32[30] = { - FIX(0.54119610014619701222), - FIX(1.3065629648763763537), - - FIX(0.50979557910415917998), - FIX(2.5629154477415054814), - FIX(0.89997622313641556513), - FIX(0.60134488693504528634), - - FIX(0.5024192861881556782), - FIX(5.1011486186891552563), - FIX(0.78815462345125020249), - FIX(0.64682178335999007679), - FIX(0.56694403481635768927), - FIX(1.0606776859903470633), - FIX(1.7224470982383341955), - FIX(0.52249861493968885462), - - FIX(10.19000812354803287), - FIX(0.674808341455005678), - FIX(1.1694399334328846596), - FIX(0.53104259108978413284), - FIX(2.0577810099534108446), - FIX(0.58293496820613388554), - FIX(0.83934964541552681272), - FIX(0.50547095989754364798), - FIX(3.4076084184687189804), - FIX(0.62250412303566482475), - FIX(0.97256823786196078263), - FIX(0.51544730992262455249), - FIX(1.4841646163141661852), - FIX(0.5531038960344445421), - FIX(0.74453627100229857749), - FIX(0.5006029982351962726), -}; - -static const int bitinv32[32] = { - 0, 16, 8, 24, 4, 20, 12, 28, - 2, 18, 10, 26, 6, 22, 14, 30, - 1, 17, 9, 25, 5, 21, 13, 29, - 3, 19, 11, 27, 7, 23, 15, 31 -}; - - -static int16_t filter_bank[512]; - -static int scale_factor_table[64]; -#ifdef USE_FLOATS -static float scale_factor_inv_table[64]; -#else -static int8_t scale_factor_shift[64]; -static unsigned short scale_factor_mult[64]; -#endif -static unsigned char scale_diff_table[128]; - -/* total number of bits per allocation group */ -static unsigned short total_quant_bits[17]; - -/* signal to noise ratio of each quantification step (could be - computed from quant_steps[]). The values are dB multiplied by 10 -*/ -static const unsigned short quant_snr[17] = { - 70, 110, 160, 208, - 253, 316, 378, 439, - 499, 559, 620, 680, - 740, 800, 861, 920, - 980 -}; - -/* fixed psycho acoustic model. Values of SNR taken from the 'toolame' - project */ -static const float fixed_smr[SBLIMIT] = { - 30, 17, 16, 10, 3, 12, 8, 2.5, - 5, 5, 6, 6, 5, 6, 10, 6, - -4, -10, -21, -30, -42, -55, -68, -75, - -75, -75, -75, -75, -91, -107, -110, -108 -}; - -static const unsigned char nb_scale_factors[4] = { 3, 2, 1, 2 }; - -#endif /* AVCODEC_MPEGAUDIOTAB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegvideo.c b/tizen/distrib/ffmpeg/libavcodec/mpegvideo.c deleted file mode 100644 index e11fee8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegvideo.c +++ /dev/null @@ -1,2414 +0,0 @@ -/* - * The simplest mpeg encoder (well, it was the simplest!) - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * 4MV & hq & B-frame encoding stuff by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * The simplest mpeg encoder (well, it was the simplest!). - */ - -#include "libavutil/intmath.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mpegvideo_common.h" -#include "mjpegenc.h" -#include "msmpeg4.h" -#include "faandct.h" -#include "xvmc_internal.h" -#include - -//#undef NDEBUG -//#include - -static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale); -static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale); -static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale); -static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s, - DCTELEM *block, int n, int qscale); -static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale); -static void dct_unquantize_h263_intra_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale); -static void dct_unquantize_h263_inter_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale); - - -/* enable all paranoid tests for rounding, overflows, etc... */ -//#define PARANOID - -//#define DEBUG - - -static const uint8_t ff_default_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, 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 -}; - -const uint8_t ff_mpeg1_dc_scale_table[128]={ -// 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 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -}; - -static const uint8_t mpeg2_dc_scale_table1[128]={ -// 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 - 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, -}; - -static const uint8_t mpeg2_dc_scale_table2[128]={ -// 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 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -}; - -static const uint8_t mpeg2_dc_scale_table3[128]={ -// 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 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 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 * const ff_mpeg2_dc_scale_table[4]={ - ff_mpeg1_dc_scale_table, - mpeg2_dc_scale_table1, - mpeg2_dc_scale_table2, - mpeg2_dc_scale_table3, -}; - -const enum PixelFormat ff_pixfmt_list_420[] = { - PIX_FMT_YUV420P, - PIX_FMT_NONE -}; - -const enum PixelFormat ff_hwaccel_pixfmt_list_420[] = { - PIX_FMT_DXVA2_VLD, - PIX_FMT_VAAPI_VLD, - PIX_FMT_YUV420P, - PIX_FMT_NONE -}; - -const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){ - int i; - - assert(p<=end); - if(p>=end) - return end; - - for(i=0; i<3; i++){ - uint32_t tmp= *state << 8; - *state= tmp + *(p++); - if(tmp == 0x100 || p==end) - return p; - } - - while(p 1 ) p+= 3; - else if(p[-2] ) p+= 2; - else if(p[-3]|(p[-1]-1)) p++; - else{ - p++; - break; - } - } - - p= FFMIN(p, end)-4; - *state= AV_RB32(p); - - return p+4; -} - -/* init common dct for both encoder and decoder */ -av_cold int ff_dct_common_init(MpegEncContext *s) -{ - s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c; - s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c; - s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c; - s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c; - s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c; - if(s->flags & CODEC_FLAG_BITEXACT) - s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact; - s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c; - -#if HAVE_MMX - MPV_common_init_mmx(s); -#elif ARCH_ALPHA - MPV_common_init_axp(s); -#elif CONFIG_MLIB - MPV_common_init_mlib(s); -#elif HAVE_MMI - MPV_common_init_mmi(s); -#elif ARCH_ARM - MPV_common_init_arm(s); -#elif HAVE_ALTIVEC - MPV_common_init_altivec(s); -#elif ARCH_BFIN - MPV_common_init_bfin(s); -#endif - - /* load & permutate scantables - note: only wmv uses different ones - */ - 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); - }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); - - return 0; -} - -void ff_copy_picture(Picture *dst, Picture *src){ - *dst = *src; - dst->type= FF_BUFFER_TYPE_COPY; -} - -/** - * Releases a frame buffer - */ -static void free_frame_buffer(MpegEncContext *s, Picture *pic) -{ - s->avctx->release_buffer(s->avctx, (AVFrame*)pic); - av_freep(&pic->hwaccel_picture_private); -} - -/** - * Allocates a frame buffer - */ -static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) -{ - int r; - - if (s->avctx->hwaccel) { - assert(!pic->hwaccel_picture_private); - if (s->avctx->hwaccel->priv_data_size) { - pic->hwaccel_picture_private = av_mallocz(s->avctx->hwaccel->priv_data_size); - if (!pic->hwaccel_picture_private) { - av_log(s->avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n"); - return -1; - } - } - } - - r = s->avctx->get_buffer(s->avctx, (AVFrame*)pic); - - if (r<0 || !pic->age || !pic->type || !pic->data[0]) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", r, pic->age, pic->type, pic->data[0]); - av_freep(&pic->hwaccel_picture_private); - return -1; - } - - if (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n"); - free_frame_buffer(s, pic); - return -1; - } - - if (pic->linesize[1] != pic->linesize[2]) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n"); - free_frame_buffer(s, pic); - return -1; - } - - return 0; -} - -/** - * allocates a Picture - * The pixels are allocated/set by calling get_buffer() if shared=0 - */ -int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared){ - const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) does not sig11 - const int mb_array_size= s->mb_stride*s->mb_height; - const int b8_array_size= s->b8_stride*s->mb_height*2; - const int b4_array_size= s->b4_stride*s->mb_height*4; - int i; - int r= -1; - - if(shared){ - assert(pic->data[0]); - assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED); - pic->type= FF_BUFFER_TYPE_SHARED; - }else{ - assert(!pic->data[0]); - - if (alloc_frame_buffer(s, pic) < 0) - return -1; - - s->linesize = pic->linesize[0]; - s->uvlinesize= pic->linesize[1]; - } - - if(pic->qscale_table==NULL){ - if (s->encoding) { - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_var , mb_array_size * sizeof(int16_t) , fail) - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mc_mb_var, mb_array_size * sizeof(int16_t) , fail) - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_mean , mb_array_size * sizeof(int8_t ) , fail) - } - - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mbskip_table , mb_array_size * sizeof(uint8_t)+2, fail) //the +2 is for the slice end check - FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table , mb_array_size * sizeof(uint8_t) , fail) - FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_type_base , (big_mb_num + s->mb_stride) * sizeof(uint32_t), fail) - pic->mb_type= pic->mb_type_base + 2*s->mb_stride+1; - if(s->out_format == FMT_H264){ - for(i=0; i<2; i++){ - FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i], 2 * (b4_array_size+4) * sizeof(int16_t), fail) - pic->motion_val[i]= pic->motion_val_base[i]+4; - FF_ALLOCZ_OR_GOTO(s->avctx, pic->ref_index[i], 4*mb_array_size * sizeof(uint8_t), fail) - } - pic->motion_subsample_log2= 2; - }else if(s->out_format == FMT_H263 || s->encoding || (s->avctx->debug&FF_DEBUG_MV) || (s->avctx->debug_mv)){ - for(i=0; i<2; i++){ - FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i], 2 * (b8_array_size+4) * sizeof(int16_t), fail) - pic->motion_val[i]= pic->motion_val_base[i]+4; - FF_ALLOCZ_OR_GOTO(s->avctx, pic->ref_index[i], 4*mb_array_size * sizeof(uint8_t), fail) - } - pic->motion_subsample_log2= 3; - } - if(s->avctx->debug&FF_DEBUG_DCT_COEFF) { - FF_ALLOCZ_OR_GOTO(s->avctx, pic->dct_coeff, 64 * mb_array_size * sizeof(DCTELEM)*6, fail) - } - pic->qstride= s->mb_stride; - FF_ALLOCZ_OR_GOTO(s->avctx, pic->pan_scan , 1 * sizeof(AVPanScan), fail) - } - - /* It might be nicer if the application would keep track of these - * but it would require an API change. */ - memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1); - s->prev_pict_types[0]= s->dropable ? FF_B_TYPE : s->pict_type; - if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == FF_B_TYPE) - pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway. - - return 0; -fail: //for the FF_ALLOCZ_OR_GOTO macro - if(r>=0) - free_frame_buffer(s, pic); - return -1; -} - -/** - * deallocates a picture - */ -static void free_picture(MpegEncContext *s, Picture *pic){ - int i; - - if(pic->data[0] && pic->type!=FF_BUFFER_TYPE_SHARED){ - free_frame_buffer(s, pic); - } - - av_freep(&pic->mb_var); - av_freep(&pic->mc_mb_var); - av_freep(&pic->mb_mean); - av_freep(&pic->mbskip_table); - av_freep(&pic->qscale_table); - av_freep(&pic->mb_type_base); - av_freep(&pic->dct_coeff); - av_freep(&pic->pan_scan); - pic->mb_type= NULL; - for(i=0; i<2; i++){ - av_freep(&pic->motion_val_base[i]); - av_freep(&pic->ref_index[i]); - } - - if(pic->type == FF_BUFFER_TYPE_SHARED){ - for(i=0; i<4; i++){ - pic->base[i]= - pic->data[i]= NULL; - } - pic->type= 0; - } -} - -static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){ - int i; - - // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264) - FF_ALLOCZ_OR_GOTO(s->avctx, s->allocated_edge_emu_buffer, (s->width+64)*2*21*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance - s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21; - - //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer() - FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, (s->width+64)*4*16*2*sizeof(uint8_t), fail) - s->me.temp= s->me.scratchpad; - s->rd_scratchpad= s->me.scratchpad; - s->b_scratchpad= s->me.scratchpad; - s->obmc_scratchpad= s->me.scratchpad + 16; - if (s->encoding) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map , ME_MAP_SIZE*sizeof(uint32_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map, ME_MAP_SIZE*sizeof(uint32_t), fail) - if(s->avctx->noise_reduction){ - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum, 2 * 64 * sizeof(int), fail) - } - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64*12*2 * sizeof(DCTELEM), fail) - s->block= s->blocks[0]; - - for(i=0;i<12;i++){ - s->pblocks[i] = &s->block[i]; - } - return 0; -fail: - return -1; //free() through MPV_common_end() -} - -static void free_duplicate_context(MpegEncContext *s){ - if(s==NULL) return; - - av_freep(&s->allocated_edge_emu_buffer); s->edge_emu_buffer= NULL; - av_freep(&s->me.scratchpad); - s->me.temp= - s->rd_scratchpad= - s->b_scratchpad= - s->obmc_scratchpad= NULL; - - av_freep(&s->dct_error_sum); - av_freep(&s->me.map); - av_freep(&s->me.score_map); - av_freep(&s->blocks); - s->block= NULL; -} - -static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src){ -#define COPY(a) bak->a= src->a - COPY(allocated_edge_emu_buffer); - COPY(edge_emu_buffer); - COPY(me.scratchpad); - COPY(me.temp); - COPY(rd_scratchpad); - COPY(b_scratchpad); - COPY(obmc_scratchpad); - COPY(me.map); - COPY(me.score_map); - COPY(blocks); - COPY(block); - COPY(start_mb_y); - COPY(end_mb_y); - COPY(me.map_generation); - COPY(pb); - COPY(dct_error_sum); - COPY(dct_count[0]); - COPY(dct_count[1]); -#undef COPY -} - -void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src){ - MpegEncContext bak; - int i; - //FIXME copy only needed parts -//START_TIMER - backup_duplicate_context(&bak, dst); - memcpy(dst, src, sizeof(MpegEncContext)); - backup_duplicate_context(dst, &bak); - for(i=0;i<12;i++){ - dst->pblocks[i] = &dst->block[i]; - } -//STOP_TIMER("update_duplicate_context") //about 10k cycles / 0.01 sec for 1000frames on 1ghz with 2 threads -} - -/** - * sets the given MpegEncContext to common defaults (same for encoding and decoding). - * the changed fields will not depend upon the prior state of the MpegEncContext. - */ -void MPV_common_defaults(MpegEncContext *s){ - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg1_dc_scale_table; - s->chroma_qscale_table= ff_default_chroma_qscale_table; - s->progressive_frame= 1; - s->progressive_sequence= 1; - s->picture_structure= PICT_FRAME; - - s->coded_picture_number = 0; - s->picture_number = 0; - s->input_picture_number = 0; - - s->picture_in_gop_number = 0; - - s->f_code = 1; - s->b_code = 1; -} - -/** - * sets the given MpegEncContext to defaults for decoding. - * the changed fields will not depend upon the prior state of the MpegEncContext. - */ -void MPV_decode_defaults(MpegEncContext *s){ - MPV_common_defaults(s); -} - -/** - * init common structure for both encoder and decoder. - * this assumes that some variables like width/height are already set - */ -av_cold int MPV_common_init(MpegEncContext *s) -{ - int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y, threads; - - if(s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) - s->mb_height = (s->height + 31) / 32 * 2; - else - s->mb_height = (s->height + 15) / 16; - - if(s->avctx->pix_fmt == PIX_FMT_NONE){ - av_log(s->avctx, AV_LOG_ERROR, "decoding to PIX_FMT_NONE is not supported.\n"); - return -1; - } - - if(s->avctx->thread_count > MAX_THREADS || (s->avctx->thread_count > s->mb_height && s->mb_height)){ - av_log(s->avctx, AV_LOG_ERROR, "too many threads\n"); - return -1; - } - - if((s->width || s->height) && avcodec_check_dimensions(s->avctx, s->width, s->height)) - return -1; - - dsputil_init(&s->dsp, s->avctx); - ff_dct_common_init(s); - - s->flags= s->avctx->flags; - s->flags2= s->avctx->flags2; - - s->mb_width = (s->width + 15) / 16; - s->mb_stride = s->mb_width + 1; - s->b8_stride = s->mb_width*2 + 1; - s->b4_stride = s->mb_width*4 + 1; - mb_array_size= s->mb_height * s->mb_stride; - mv_table_size= (s->mb_height+2) * s->mb_stride + 1; - - /* set chroma shifts */ - avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,&(s->chroma_x_shift), - &(s->chroma_y_shift) ); - - /* set default edge pos, will be overriden in decode_header if needed */ - s->h_edge_pos= s->mb_width*16; - s->v_edge_pos= s->mb_height*16; - - s->mb_num = s->mb_width * s->mb_height; - - s->block_wrap[0]= - s->block_wrap[1]= - s->block_wrap[2]= - s->block_wrap[3]= s->b8_stride; - s->block_wrap[4]= - s->block_wrap[5]= s->mb_stride; - - y_size = s->b8_stride * (2 * s->mb_height + 1); - c_size = s->mb_stride * (s->mb_height + 1); - yc_size = y_size + 2 * c_size; - - /* convert fourcc to upper case */ - s->codec_tag= toupper( s->avctx->codec_tag &0xFF) - + (toupper((s->avctx->codec_tag>>8 )&0xFF)<<8 ) - + (toupper((s->avctx->codec_tag>>16)&0xFF)<<16) - + (toupper((s->avctx->codec_tag>>24)&0xFF)<<24); - - s->stream_codec_tag= toupper( s->avctx->stream_codec_tag &0xFF) - + (toupper((s->avctx->stream_codec_tag>>8 )&0xFF)<<8 ) - + (toupper((s->avctx->stream_codec_tag>>16)&0xFF)<<16) - + (toupper((s->avctx->stream_codec_tag>>24)&0xFF)<<24); - - s->avctx->coded_frame= (AVFrame*)&s->current_picture; - - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num+1)*sizeof(int), fail) //error ressilience code looks cleaner with this - for(y=0; ymb_height; y++){ - for(x=0; xmb_width; x++){ - s->mb_index2xy[ x + y*s->mb_width ] = x + y*s->mb_stride; - } - } - s->mb_index2xy[ s->mb_height*s->mb_width ] = (s->mb_height-1)*s->mb_stride + s->mb_width; //FIXME really needed? - - if (s->encoding) { - /* Allocate MV tables */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) - s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1; - s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1; - s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1; - s->b_bidir_forw_mv_table= s->b_bidir_forw_mv_table_base + s->mb_stride + 1; - s->b_bidir_back_mv_table= s->b_bidir_back_mv_table_base + s->mb_stride + 1; - s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1; - - if(s->msmpeg4_version){ - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, 2*2*(MAX_LEVEL+1)*(MAX_RUN+1)*2*sizeof(int), fail); - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); - - /* Allocate MB type table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type , mb_array_size * sizeof(uint16_t), fail) //needed for encoding - - FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail) - - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix , 64*32 * sizeof(int), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix , 64*32 * sizeof(int), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64*32*2 * sizeof(uint16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail) - - if(s->avctx->noise_reduction){ - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, 2 * 64 * sizeof(uint16_t), fail) - } - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, MAX_PICTURE_COUNT * sizeof(Picture), fail) - for(i = 0; i < MAX_PICTURE_COUNT; i++) { - avcodec_get_frame_defaults((AVFrame *)&s->picture[i]); - } - - FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, mb_array_size*sizeof(uint8_t), fail) - - if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){ - /* interlaced direct mode decoding tables */ - for(i=0; i<2; i++){ - int j, k; - for(j=0; j<2; j++){ - for(k=0; k<2; k++){ - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_mv_table_base[i][j][k], mv_table_size * 2 * sizeof(int16_t), fail) - s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + s->mb_stride + 1; - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail) - s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j]+ s->mb_stride + 1; - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail) - } - } - if (s->out_format == FMT_H263) { - /* ac values */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base, yc_size * sizeof(int16_t) * 16, fail); - s->ac_val[0] = s->ac_val_base + s->b8_stride + 1; - s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1; - s->ac_val[2] = s->ac_val[1] + c_size; - - /* cbp values */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->coded_block_base, y_size, fail); - s->coded_block= s->coded_block_base + s->b8_stride + 1; - - /* cbp, ac_pred, pred_dir */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail) - } - - if (s->h263_pred || s->h263_plus || !s->encoding) { - /* dc values */ - //MN: we need these for error resilience of intra-frames - FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail); - s->dc_val[0] = s->dc_val_base + s->b8_stride + 1; - s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1; - s->dc_val[2] = s->dc_val[1] + c_size; - for(i=0;idc_val_base[i] = 1024; - } - - /* which mb is a intra block */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mbintra_table, mb_array_size, fail); - memset(s->mbintra_table, 1, mb_array_size); - - /* init macroblock skip table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size+2, fail); - //Note the +1 is for a quicker mpeg4 slice_end detection - FF_ALLOCZ_OR_GOTO(s->avctx, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE, fail); - - s->parse_context.state= -1; - if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){ - s->visualization_buffer[0] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH); - s->visualization_buffer[1] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH); - s->visualization_buffer[2] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH); - } - - s->context_initialized = 1; - - s->thread_context[0]= s; - threads = s->avctx->thread_count; - - for(i=1; ithread_context[i]= av_malloc(sizeof(MpegEncContext)); - memcpy(s->thread_context[i], s, sizeof(MpegEncContext)); - } - - for(i=0; ithread_context[i], s) < 0) - goto fail; - s->thread_context[i]->start_mb_y= (s->mb_height*(i ) + s->avctx->thread_count/2) / s->avctx->thread_count; - s->thread_context[i]->end_mb_y = (s->mb_height*(i+1) + s->avctx->thread_count/2) / s->avctx->thread_count; - } - - return 0; - fail: - MPV_common_end(s); - return -1; -} - -/* init common structure for both encoder and decoder */ -void MPV_common_end(MpegEncContext *s) -{ - int i, j, k; - - for(i=0; iavctx->thread_count; i++){ - free_duplicate_context(s->thread_context[i]); - } - for(i=1; iavctx->thread_count; i++){ - av_freep(&s->thread_context[i]); - } - - av_freep(&s->parse_context.buffer); - s->parse_context.buffer_size=0; - - av_freep(&s->mb_type); - av_freep(&s->p_mv_table_base); - av_freep(&s->b_forw_mv_table_base); - av_freep(&s->b_back_mv_table_base); - av_freep(&s->b_bidir_forw_mv_table_base); - av_freep(&s->b_bidir_back_mv_table_base); - av_freep(&s->b_direct_mv_table_base); - s->p_mv_table= NULL; - s->b_forw_mv_table= NULL; - s->b_back_mv_table= NULL; - s->b_bidir_forw_mv_table= NULL; - s->b_bidir_back_mv_table= NULL; - s->b_direct_mv_table= NULL; - for(i=0; i<2; i++){ - for(j=0; j<2; j++){ - for(k=0; k<2; k++){ - av_freep(&s->b_field_mv_table_base[i][j][k]); - s->b_field_mv_table[i][j][k]=NULL; - } - av_freep(&s->b_field_select_table[i][j]); - av_freep(&s->p_field_mv_table_base[i][j]); - s->p_field_mv_table[i][j]=NULL; - } - av_freep(&s->p_field_select_table[i]); - } - - av_freep(&s->dc_val_base); - av_freep(&s->ac_val_base); - av_freep(&s->coded_block_base); - av_freep(&s->mbintra_table); - av_freep(&s->cbp_table); - av_freep(&s->pred_dir_table); - - av_freep(&s->mbskip_table); - av_freep(&s->prev_pict_types); - av_freep(&s->bitstream_buffer); - s->allocated_bitstream_buffer_size=0; - - av_freep(&s->avctx->stats_out); - av_freep(&s->ac_stats); - av_freep(&s->error_status_table); - av_freep(&s->mb_index2xy); - av_freep(&s->lambda_table); - av_freep(&s->q_intra_matrix); - av_freep(&s->q_inter_matrix); - av_freep(&s->q_intra_matrix16); - av_freep(&s->q_inter_matrix16); - av_freep(&s->input_picture); - av_freep(&s->reordered_input_picture); - av_freep(&s->dct_offset); - - if(s->picture){ - for(i=0; ipicture[i]); - } - } - av_freep(&s->picture); - s->context_initialized = 0; - s->last_picture_ptr= - s->next_picture_ptr= - s->current_picture_ptr= NULL; - s->linesize= s->uvlinesize= 0; - - for(i=0; i<3; i++) - av_freep(&s->visualization_buffer[i]); - - avcodec_default_free_buffers(s->avctx); -} - -void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]) -{ - int8_t max_level[MAX_RUN+1], max_run[MAX_LEVEL+1]; - uint8_t index_run[MAX_RUN+1]; - int last, run, level, start, end, i; - - /* If table is static, we can quit if rl->max_level[0] is not NULL */ - if(static_store && rl->max_level[0]) - return; - - /* compute max_level[], max_run[] and index_run[] */ - for(last=0;last<2;last++) { - if (last == 0) { - start = 0; - end = rl->last; - } else { - start = rl->last; - end = rl->n; - } - - memset(max_level, 0, MAX_RUN + 1); - memset(max_run, 0, MAX_LEVEL + 1); - memset(index_run, rl->n, MAX_RUN + 1); - for(i=start;itable_run[i]; - level = rl->table_level[i]; - if (index_run[run] == rl->n) - index_run[run] = i; - if (level > max_level[run]) - max_level[run] = level; - if (run > max_run[level]) - max_run[level] = run; - } - if(static_store) - rl->max_level[last] = static_store[last]; - else - rl->max_level[last] = av_malloc(MAX_RUN + 1); - memcpy(rl->max_level[last], max_level, MAX_RUN + 1); - if(static_store) - rl->max_run[last] = static_store[last] + MAX_RUN + 1; - else - rl->max_run[last] = av_malloc(MAX_LEVEL + 1); - memcpy(rl->max_run[last], max_run, MAX_LEVEL + 1); - if(static_store) - rl->index_run[last] = static_store[last] + MAX_RUN + MAX_LEVEL + 2; - else - rl->index_run[last] = av_malloc(MAX_RUN + 1); - memcpy(rl->index_run[last], index_run, MAX_RUN + 1); - } -} - -void init_vlc_rl(RLTable *rl) -{ - int i, q; - - for(q=0; q<32; q++){ - int qmul= q*2; - int qadd= (q-1)|1; - - if(q==0){ - qmul=1; - qadd=0; - } - 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; - } - } -} - -int ff_find_unused_picture(MpegEncContext *s, int shared){ - int i; - - if(shared){ - for(i=0; ipicture[i].data[0]==NULL && s->picture[i].type==0) return i; - } - }else{ - for(i=0; ipicture[i].data[0]==NULL && s->picture[i].type!=0) return i; //FIXME - } - for(i=0; ipicture[i].data[0]==NULL) return i; - } - } - - av_log(s->avctx, AV_LOG_FATAL, "Internal error, picture buffer overflow\n"); - /* We could return -1, but the codec would crash trying to draw into a - * non-existing frame anyway. This is safer than waiting for a random crash. - * Also the return of this is never useful, an encoder must only allocate - * as much as allowed in the specification. This has no relationship to how - * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large - * enough for such valid streams). - * Plus, a decoder has to check stream validity and remove frames if too - * many reference frames are around. Waiting for "OOM" is not correct at - * all. Similarly, missing reference frames have to be replaced by - * interpolated/MC frames, anything else is a bug in the codec ... - */ - abort(); - return -1; -} - -static void update_noise_reduction(MpegEncContext *s){ - int intra, i; - - for(intra=0; intra<2; intra++){ - if(s->dct_count[intra] > (1<<16)){ - for(i=0; i<64; i++){ - s->dct_error_sum[intra][i] >>=1; - } - s->dct_count[intra] >>= 1; - } - - for(i=0; i<64; i++){ - s->dct_offset[intra][i]= (s->avctx->noise_reduction * s->dct_count[intra] + s->dct_error_sum[intra][i]/2) / (s->dct_error_sum[intra][i]+1); - } - } -} - -/** - * generic function for encode/decode called after coding/decoding the header and before a frame is coded/decoded - */ -int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) -{ - int i; - Picture *pic; - s->mb_skipped = 0; - - assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3); - - /* mark&release old frames */ - if (s->pict_type != FF_B_TYPE && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->data[0]) { - if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){ - free_frame_buffer(s, s->last_picture_ptr); - - /* release forgotten pictures */ - /* if(mpeg124/h263) */ - if(!s->encoding){ - for(i=0; ipicture[i].data[0] && &s->picture[i] != s->next_picture_ptr && s->picture[i].reference){ - av_log(avctx, AV_LOG_ERROR, "releasing zombie picture\n"); - free_frame_buffer(s, &s->picture[i]); - } - } - } - } - } - - if(!s->encoding){ - /* release non reference frames */ - for(i=0; ipicture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ - free_frame_buffer(s, &s->picture[i]); - } - } - - if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL) - pic= s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header) - else{ - i= ff_find_unused_picture(s, 0); - pic= &s->picture[i]; - } - - pic->reference= 0; - if (!s->dropable){ - if (s->codec_id == CODEC_ID_H264) - pic->reference = s->picture_structure; - else if (s->pict_type != FF_B_TYPE) - pic->reference = 3; - } - - pic->coded_picture_number= s->coded_picture_number++; - - if(ff_alloc_picture(s, pic, 0) < 0) - return -1; - - s->current_picture_ptr= pic; - s->current_picture_ptr->top_field_first= s->top_field_first; //FIXME use only the vars from current_pic - s->current_picture_ptr->interlaced_frame= !s->progressive_frame && !s->progressive_sequence; - } - - s->current_picture_ptr->pict_type= s->pict_type; -// if(s->flags && CODEC_FLAG_QSCALE) - // s->current_picture_ptr->quality= s->new_picture_ptr->quality; - s->current_picture_ptr->key_frame= s->pict_type == FF_I_TYPE; - - ff_copy_picture(&s->current_picture, s->current_picture_ptr); - - if (s->pict_type != FF_B_TYPE) { - s->last_picture_ptr= s->next_picture_ptr; - if(!s->dropable) - s->next_picture_ptr= s->current_picture_ptr; - } -/* av_log(s->avctx, AV_LOG_DEBUG, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n", s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr, - s->last_picture_ptr ? s->last_picture_ptr->data[0] : NULL, - s->next_picture_ptr ? s->next_picture_ptr->data[0] : NULL, - s->current_picture_ptr ? s->current_picture_ptr->data[0] : NULL, - s->pict_type, s->dropable);*/ - - if(s->codec_id != CODEC_ID_H264){ - if((s->last_picture_ptr==NULL || s->last_picture_ptr->data[0]==NULL) && s->pict_type!=FF_I_TYPE){ - av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n"); - /* Allocate a dummy frame */ - i= ff_find_unused_picture(s, 0); - s->last_picture_ptr= &s->picture[i]; - if(ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) - return -1; - } - if((s->next_picture_ptr==NULL || s->next_picture_ptr->data[0]==NULL) && s->pict_type==FF_B_TYPE){ - /* Allocate a dummy frame */ - i= ff_find_unused_picture(s, 0); - s->next_picture_ptr= &s->picture[i]; - if(ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) - return -1; - } - } - - if(s->last_picture_ptr) ff_copy_picture(&s->last_picture, s->last_picture_ptr); - if(s->next_picture_ptr) ff_copy_picture(&s->next_picture, s->next_picture_ptr); - - assert(s->pict_type == FF_I_TYPE || (s->last_picture_ptr && s->last_picture_ptr->data[0])); - - if(s->picture_structure!=PICT_FRAME && s->out_format != FMT_H264){ - int i; - for(i=0; i<4; i++){ - if(s->picture_structure == PICT_BOTTOM_FIELD){ - s->current_picture.data[i] += s->current_picture.linesize[i]; - } - s->current_picture.linesize[i] *= 2; - s->last_picture.linesize[i] *=2; - s->next_picture.linesize[i] *=2; - } - } - - s->hurry_up= s->avctx->hurry_up; - s->error_recognition= avctx->error_recognition; - - /* set dequantizer, we can't do it during init as it might change for mpeg4 - and we can't do it in the header decode as init is not called for mpeg4 there yet */ - if(s->mpeg_quant || s->codec_id == CODEC_ID_MPEG2VIDEO){ - s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra; - s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter; - }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ - s->dct_unquantize_intra = s->dct_unquantize_h263_intra; - s->dct_unquantize_inter = s->dct_unquantize_h263_inter; - }else{ - s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra; - s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter; - } - - if(s->dct_error_sum){ - assert(s->avctx->noise_reduction && s->encoding); - - update_noise_reduction(s); - } - - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) - return ff_xvmc_field_start(s, avctx); - - return 0; -} - -/* generic function for encode/decode called after a frame has been coded/decoded */ -void MPV_frame_end(MpegEncContext *s) -{ - int i; - /* draw edge for correct motion prediction if outside */ - //just to make sure that all data is rendered. - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){ - ff_xvmc_field_end(s); - }else if(!s->avctx->hwaccel - && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - && s->unrestricted_mv - && s->current_picture.reference - && !s->intra_only - && !(s->flags&CODEC_FLAG_EMU_EDGE)) { - s->dsp.draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH ); - s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); - s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); - } - emms_c(); - - s->last_pict_type = s->pict_type; - s->last_lambda_for[s->pict_type]= s->current_picture_ptr->quality; - if(s->pict_type!=FF_B_TYPE){ - s->last_non_b_pict_type= s->pict_type; - } -#if 0 - /* copy back current_picture variables */ - for(i=0; ipicture[i].data[0] == s->current_picture.data[0]){ - s->picture[i]= s->current_picture; - break; - } - } - assert(iencoding){ - /* release non-reference frames */ - for(i=0; ipicture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ - free_frame_buffer(s, &s->picture[i]); - } - } - } - // clear copies, to avoid confusion -#if 0 - memset(&s->last_picture, 0, sizeof(Picture)); - memset(&s->next_picture, 0, sizeof(Picture)); - memset(&s->current_picture, 0, sizeof(Picture)); -#endif - s->avctx->coded_frame= (AVFrame*)s->current_picture_ptr; -} - -/** - * draws an line from (ex, ey) -> (sx, sy). - * @param w width of the image - * @param h height of the image - * @param stride stride/linesize of the image - * @param color color of the arrow - */ -static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){ - int x, y, fr, f; - - sx= av_clip(sx, 0, w-1); - sy= av_clip(sy, 0, h-1); - ex= av_clip(ex, 0, w-1); - ey= av_clip(ey, 0, h-1); - - buf[sy*stride + sx]+= color; - - if(FFABS(ex - sx) > FFABS(ey - sy)){ - if(sx > ex){ - FFSWAP(int, sx, ex); - FFSWAP(int, sy, ey); - } - buf+= sx + sy*stride; - ex-= sx; - f= ((ey-sy)<<16)/ex; - for(x= 0; x <= ex; x++){ - y = (x*f)>>16; - fr= (x*f)&0xFFFF; - buf[ y *stride + x]+= (color*(0x10000-fr))>>16; - buf[(y+1)*stride + x]+= (color* fr )>>16; - } - }else{ - if(sy > ey){ - FFSWAP(int, sx, ex); - FFSWAP(int, sy, ey); - } - buf+= sx + sy*stride; - ey-= sy; - if(ey) f= ((ex-sx)<<16)/ey; - else f= 0; - for(y= 0; y <= ey; y++){ - x = (y*f)>>16; - fr= (y*f)&0xFFFF; - buf[y*stride + x ]+= (color*(0x10000-fr))>>16; - buf[y*stride + x+1]+= (color* fr )>>16; - } - } -} - -/** - * draws an arrow from (ex, ey) -> (sx, sy). - * @param w width of the image - * @param h height of the image - * @param stride stride/linesize of the image - * @param color color of the arrow - */ -static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){ - int dx,dy; - - sx= av_clip(sx, -100, w+100); - sy= av_clip(sy, -100, h+100); - ex= av_clip(ex, -100, w+100); - ey= av_clip(ey, -100, h+100); - - dx= ex - sx; - dy= ey - sy; - - if(dx*dx + dy*dy > 3*3){ - int rx= dx + dy; - int ry= -dx + dy; - int length= ff_sqrt((rx*rx + ry*ry)<<8); - - //FIXME subpixel accuracy - rx= ROUNDED_DIV(rx*3<<4, length); - ry= ROUNDED_DIV(ry*3<<4, length); - - draw_line(buf, sx, sy, sx + rx, sy + ry, w, h, stride, color); - draw_line(buf, sx, sy, sx - ry, sy + rx, w, h, stride, color); - } - draw_line(buf, sx, sy, ex, ey, w, h, stride, color); -} - -/** - * prints debuging info for the given picture. - */ -void ff_print_debug_info(MpegEncContext *s, AVFrame *pict){ - - if(s->avctx->hwaccel || !pict || !pict->mb_type) return; - - if(s->avctx->debug&(FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)){ - int x,y; - - av_log(s->avctx,AV_LOG_DEBUG,"New frame, type: "); - switch (pict->pict_type) { - case FF_I_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"I\n"); break; - case FF_P_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"P\n"); break; - case FF_B_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"B\n"); break; - case FF_S_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"S\n"); break; - case FF_SI_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SI\n"); break; - case FF_SP_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SP\n"); break; - } - for(y=0; ymb_height; y++){ - for(x=0; xmb_width; x++){ - if(s->avctx->debug&FF_DEBUG_SKIP){ - int count= s->mbskip_table[x + y*s->mb_stride]; - if(count>9) count=9; - av_log(s->avctx, AV_LOG_DEBUG, "%1d", count); - } - if(s->avctx->debug&FF_DEBUG_QP){ - av_log(s->avctx, AV_LOG_DEBUG, "%2d", pict->qscale_table[x + y*s->mb_stride]); - } - if(s->avctx->debug&FF_DEBUG_MB_TYPE){ - int mb_type= pict->mb_type[x + y*s->mb_stride]; - //Type & MV direction - if(IS_PCM(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "P"); - else if(IS_INTRA(mb_type) && IS_ACPRED(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "A"); - else if(IS_INTRA4x4(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "i"); - else if(IS_INTRA16x16(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "I"); - else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "d"); - else if(IS_DIRECT(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "D"); - else if(IS_GMC(mb_type) && IS_SKIP(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "g"); - else if(IS_GMC(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "G"); - else if(IS_SKIP(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "S"); - else if(!USES_LIST(mb_type, 1)) - av_log(s->avctx, AV_LOG_DEBUG, ">"); - else if(!USES_LIST(mb_type, 0)) - av_log(s->avctx, AV_LOG_DEBUG, "<"); - else{ - assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1)); - av_log(s->avctx, AV_LOG_DEBUG, "X"); - } - - //segmentation - if(IS_8X8(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "+"); - else if(IS_16X8(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "-"); - else if(IS_8X16(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, "|"); - else if(IS_INTRA(mb_type) || IS_16X16(mb_type)) - av_log(s->avctx, AV_LOG_DEBUG, " "); - else - av_log(s->avctx, AV_LOG_DEBUG, "?"); - - - if(IS_INTERLACED(mb_type) && s->codec_id == CODEC_ID_H264) - av_log(s->avctx, AV_LOG_DEBUG, "="); - else - av_log(s->avctx, AV_LOG_DEBUG, " "); - } -// av_log(s->avctx, AV_LOG_DEBUG, " "); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } - } - - if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){ - const int shift= 1 + s->quarter_sample; - int mb_y; - uint8_t *ptr; - int i; - int h_chroma_shift, v_chroma_shift, block_height; - const int width = s->avctx->width; - const int height= s->avctx->height; - const int mv_sample_log2= 4 - pict->motion_subsample_log2; - const int mv_stride= (s->mb_width << mv_sample_log2) + (s->codec_id == CODEC_ID_H264 ? 0 : 1); - s->low_delay=0; //needed to see the vectors without trashing the buffers - - avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); - for(i=0; i<3; i++){ - memcpy(s->visualization_buffer[i], pict->data[i], (i==0) ? pict->linesize[i]*height:pict->linesize[i]*height >> v_chroma_shift); - pict->data[i]= s->visualization_buffer[i]; - } - pict->type= FF_BUFFER_TYPE_COPY; - ptr= pict->data[0]; - block_height = 16>>v_chroma_shift; - - for(mb_y=0; mb_ymb_height; mb_y++){ - int mb_x; - for(mb_x=0; mb_xmb_width; mb_x++){ - const int mb_index= mb_x + mb_y*s->mb_stride; - if((s->avctx->debug_mv) && pict->motion_val){ - int type; - for(type=0; type<3; type++){ - int direction = 0; - switch (type) { - case 0: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_P_FOR)) || (pict->pict_type!=FF_P_TYPE)) - continue; - direction = 0; - break; - case 1: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_FOR)) || (pict->pict_type!=FF_B_TYPE)) - continue; - direction = 0; - break; - case 2: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_BACK)) || (pict->pict_type!=FF_B_TYPE)) - continue; - direction = 1; - break; - } - if(!USES_LIST(pict->mb_type[mb_index], direction)) - continue; - - if(IS_8X8(pict->mb_type[mb_index])){ - int i; - for(i=0; i<4; i++){ - int sx= mb_x*16 + 4 + 8*(i&1); - int sy= mb_y*16 + 4 + 8*(i>>1); - int xy= (mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*mv_stride) << (mv_sample_log2-1); - int mx= (pict->motion_val[direction][xy][0]>>shift) + sx; - int my= (pict->motion_val[direction][xy][1]>>shift) + sy; - draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100); - } - }else if(IS_16X8(pict->mb_type[mb_index])){ - int i; - for(i=0; i<2; i++){ - int sx=mb_x*16 + 8; - int sy=mb_y*16 + 4 + 8*i; - int xy= (mb_x*2 + (mb_y*2 + i)*mv_stride) << (mv_sample_log2-1); - int mx=(pict->motion_val[direction][xy][0]>>shift); - int my=(pict->motion_val[direction][xy][1]>>shift); - - if(IS_INTERLACED(pict->mb_type[mb_index])) - my*=2; - - draw_arrow(ptr, sx, sy, mx+sx, my+sy, width, height, s->linesize, 100); - } - }else if(IS_8X16(pict->mb_type[mb_index])){ - int i; - for(i=0; i<2; i++){ - int sx=mb_x*16 + 4 + 8*i; - int sy=mb_y*16 + 8; - int xy= (mb_x*2 + i + mb_y*2*mv_stride) << (mv_sample_log2-1); - int mx=(pict->motion_val[direction][xy][0]>>shift); - int my=(pict->motion_val[direction][xy][1]>>shift); - - if(IS_INTERLACED(pict->mb_type[mb_index])) - my*=2; - - draw_arrow(ptr, sx, sy, mx+sx, my+sy, width, height, s->linesize, 100); - } - }else{ - int sx= mb_x*16 + 8; - int sy= mb_y*16 + 8; - int xy= (mb_x + mb_y*mv_stride) << mv_sample_log2; - int mx= (pict->motion_val[direction][xy][0]>>shift) + sx; - int my= (pict->motion_val[direction][xy][1]>>shift) + sy; - draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100); - } - } - } - if((s->avctx->debug&FF_DEBUG_VIS_QP) && pict->motion_val){ - uint64_t c= (pict->qscale_table[mb_index]*128/31) * 0x0101010101010101ULL; - int y; - for(y=0; ydata[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= c; - *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= c; - } - } - if((s->avctx->debug&FF_DEBUG_VIS_MB_TYPE) && pict->motion_val){ - int mb_type= pict->mb_type[mb_index]; - uint64_t u,v; - int y; -#define COLOR(theta, r)\ -u= (int)(128 + r*cos(theta*3.141592/180));\ -v= (int)(128 + r*sin(theta*3.141592/180)); - - - u=v=128; - if(IS_PCM(mb_type)){ - COLOR(120,48) - }else if((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) || IS_INTRA16x16(mb_type)){ - COLOR(30,48) - }else if(IS_INTRA4x4(mb_type)){ - COLOR(90,48) - }else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type)){ -// COLOR(120,48) - }else if(IS_DIRECT(mb_type)){ - COLOR(150,48) - }else if(IS_GMC(mb_type) && IS_SKIP(mb_type)){ - COLOR(170,48) - }else if(IS_GMC(mb_type)){ - COLOR(190,48) - }else if(IS_SKIP(mb_type)){ -// COLOR(180,48) - }else if(!USES_LIST(mb_type, 1)){ - COLOR(240,48) - }else if(!USES_LIST(mb_type, 0)){ - COLOR(0,48) - }else{ - assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1)); - COLOR(300,48) - } - - u*= 0x0101010101010101ULL; - v*= 0x0101010101010101ULL; - for(y=0; ydata[1] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[1])= u; - *(uint64_t*)(pict->data[2] + 8*mb_x + (block_height*mb_y + y)*pict->linesize[2])= v; - } - - //segmentation - if(IS_8X8(mb_type) || IS_16X8(mb_type)){ - *(uint64_t*)(pict->data[0] + 16*mb_x + 0 + (16*mb_y + 8)*pict->linesize[0])^= 0x8080808080808080ULL; - *(uint64_t*)(pict->data[0] + 16*mb_x + 8 + (16*mb_y + 8)*pict->linesize[0])^= 0x8080808080808080ULL; - } - if(IS_8X8(mb_type) || IS_8X16(mb_type)){ - for(y=0; y<16; y++) - pict->data[0][16*mb_x + 8 + (16*mb_y + y)*pict->linesize[0]]^= 0x80; - } - if(IS_8X8(mb_type) && mv_sample_log2 >= 2){ - int dm= 1 << (mv_sample_log2-2); - for(i=0; i<4; i++){ - int sx= mb_x*16 + 8*(i&1); - int sy= mb_y*16 + 8*(i>>1); - int xy= (mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*mv_stride) << (mv_sample_log2-1); - //FIXME bidir - int32_t *mv = (int32_t*)&pict->motion_val[0][xy]; - if(mv[0] != mv[dm] || mv[dm*mv_stride] != mv[dm*(mv_stride+1)]) - for(y=0; y<8; y++) - pict->data[0][sx + 4 + (sy + y)*pict->linesize[0]]^= 0x80; - if(mv[0] != mv[dm*mv_stride] || mv[dm] != mv[dm*(mv_stride+1)]) - *(uint64_t*)(pict->data[0] + sx + (sy + 4)*pict->linesize[0])^= 0x8080808080808080ULL; - } - } - - if(IS_INTERLACED(mb_type) && s->codec_id == CODEC_ID_H264){ - // hmm - } - } - s->mbskip_table[mb_index]=0; - } - } - } -} - -static inline int hpel_motion_lowres(MpegEncContext *s, - uint8_t *dest, uint8_t *src, - int field_based, int field_select, - int src_x, int src_y, - int width, int height, int stride, - int h_edge_pos, int v_edge_pos, - int w, int h, h264_chroma_mc_func *pix_op, - int motion_x, int motion_y) -{ - const int lowres= s->avctx->lowres; - const int op_index= FFMIN(lowres, 2); - const int s_mask= (2<quarter_sample){ - motion_x/=2; - motion_y/=2; - } - - sx= motion_x & s_mask; - sy= motion_y & s_mask; - src_x += motion_x >> (lowres+1); - src_y += motion_y >> (lowres+1); - - src += src_y * stride + src_x; - - if( (unsigned)src_x > h_edge_pos - (!!sx) - w - || (unsigned)src_y >(v_edge_pos >> field_based) - (!!sy) - h){ - ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<edge_emu_buffer; - emu=1; - } - - sx= (sx << 2) >> lowres; - sy= (sy << 2) >> lowres; - if(field_select) - src += s->linesize; - pix_op[op_index](dest, src, stride, h, sx, sy); - return emu; -} - -/* apply one mpeg motion vector to the three components */ -static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, h264_chroma_mc_func *pix_op, - int motion_x, int motion_y, int h, int mb_y) -{ - uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, uvsx, uvsy; - const int lowres= s->avctx->lowres; - const int op_index= FFMIN(lowres, 2); - const int block_s= 8>>lowres; - const int s_mask= (2<h_edge_pos >> lowres; - const int v_edge_pos = s->v_edge_pos >> lowres; - linesize = s->current_picture.linesize[0] << field_based; - uvlinesize = s->current_picture.linesize[1] << field_based; - - if(s->quarter_sample){ //FIXME obviously not perfect but qpel will not work in lowres anyway - motion_x/=2; - motion_y/=2; - } - - if(field_based){ - motion_y += (bottom_field - field_select)*((1<mb_x*2*block_s + (motion_x >> (lowres+1)); - src_y =( mb_y*2*block_s>>field_based) + (motion_y >> (lowres+1)); - - if (s->out_format == FMT_H263) { - uvsx = ((motion_x>>1) & s_mask) | (sx&1); - uvsy = ((motion_y>>1) & s_mask) | (sy&1); - uvsrc_x = src_x>>1; - uvsrc_y = src_y>>1; - }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261 - mx = motion_x / 4; - my = motion_y / 4; - uvsx = (2*mx) & s_mask; - uvsy = (2*my) & s_mask; - uvsrc_x = s->mb_x*block_s + (mx >> lowres); - uvsrc_y = mb_y*block_s + (my >> lowres); - } else { - mx = motion_x / 2; - my = motion_y / 2; - uvsx = mx & s_mask; - uvsy = my & s_mask; - uvsrc_x = s->mb_x*block_s + (mx >> (lowres+1)); - uvsrc_y =( mb_y*block_s>>field_based) + (my >> (lowres+1)); - } - - ptr_y = ref_picture[0] + src_y * linesize + src_x; - ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; - ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - - if( (unsigned)src_x > h_edge_pos - (!!sx) - 2*block_s - || (unsigned)src_y >(v_edge_pos >> field_based) - (!!sy) - h){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based, - src_x, src_y<edge_emu_buffer; - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize; - ff_emulated_edge_mc(uvbuf , ptr_cb, s->uvlinesize, 9, 9+field_based, - uvsrc_x, uvsrc_y<>1, v_edge_pos>>1); - ff_emulated_edge_mc(uvbuf+16, ptr_cr, s->uvlinesize, 9, 9+field_based, - uvsrc_x, uvsrc_y<>1, v_edge_pos>>1); - ptr_cb= uvbuf; - ptr_cr= uvbuf+16; - } - } - - if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data - dest_y += s->linesize; - dest_cb+= s->uvlinesize; - dest_cr+= s->uvlinesize; - } - - if(field_select){ - ptr_y += s->linesize; - ptr_cb+= s->uvlinesize; - ptr_cr+= s->uvlinesize; - } - - sx= (sx << 2) >> lowres; - sy= (sy << 2) >> lowres; - pix_op[lowres-1](dest_y, ptr_y, linesize, h, sx, sy); - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - uvsx= (uvsx << 2) >> lowres; - uvsy= (uvsy << 2) >> lowres; - pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); - pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); - } - //FIXME h261 lowres loop filter -} - -static inline void chroma_4mv_motion_lowres(MpegEncContext *s, - uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture, - h264_chroma_mc_func *pix_op, - int mx, int my){ - const int lowres= s->avctx->lowres; - const int op_index= FFMIN(lowres, 2); - const int block_s= 8>>lowres; - const int s_mask= (2<h_edge_pos >> (lowres+1); - const int v_edge_pos = s->v_edge_pos >> (lowres+1); - int emu=0, src_x, src_y, offset, sx, sy; - uint8_t *ptr; - - if(s->quarter_sample){ - mx/=2; - my/=2; - } - - /* In case of 8X8, we construct a single chroma motion vector - with a special rounding */ - mx= ff_h263_round_chroma(mx); - my= ff_h263_round_chroma(my); - - sx= mx & s_mask; - sy= my & s_mask; - src_x = s->mb_x*block_s + (mx >> (lowres+1)); - src_y = s->mb_y*block_s + (my >> (lowres+1)); - - offset = src_y * s->uvlinesize + src_x; - ptr = ref_picture[1] + offset; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x > h_edge_pos - (!!sx) - block_s - || (unsigned)src_y > v_edge_pos - (!!sy) - block_s){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos); - ptr= s->edge_emu_buffer; - emu=1; - } - } - sx= (sx << 2) >> lowres; - sy= (sy << 2) >> lowres; - pix_op[op_index](dest_cb, ptr, s->uvlinesize, block_s, sx, sy); - - ptr = ref_picture[2] + offset; - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos); - ptr= s->edge_emu_buffer; - } - pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy); -} - -/** - * motion compensation of a single macroblock - * @param s context - * @param dest_y luma destination pointer - * @param dest_cb chroma cb/u destination pointer - * @param dest_cr chroma cr/v destination pointer - * @param dir direction (0->forward, 1->backward) - * @param ref_picture array[3] of pointers to the 3 planes of the reference picture - * @param pic_op halfpel motion compensation function (average or put normally) - * the motion vectors are taken from s->mv and the MV type from s->mv_type - */ -static inline void MPV_motion_lowres(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int dir, uint8_t **ref_picture, - h264_chroma_mc_func *pix_op) -{ - int mx, my; - int mb_x, mb_y, i; - const int lowres= s->avctx->lowres; - const int block_s= 8>>lowres; - - mb_x = s->mb_x; - mb_y = s->mb_y; - - switch(s->mv_type) { - case MV_TYPE_16X16: - mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, - 0, 0, 0, - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s, mb_y); - break; - case MV_TYPE_8X8: - mx = 0; - my = 0; - for(i=0;i<4;i++) { - hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) * s->linesize)*block_s, - ref_picture[0], 0, 0, - (2*mb_x + (i & 1))*block_s, (2*mb_y + (i >>1))*block_s, - s->width, s->height, s->linesize, - s->h_edge_pos >> lowres, s->v_edge_pos >> lowres, - block_s, block_s, pix_op, - s->mv[dir][i][0], s->mv[dir][i][1]); - - mx += s->mv[dir][i][0]; - my += s->mv[dir][i][1]; - } - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) - chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture, pix_op, mx, my); - break; - case MV_TYPE_FIELD: - if (s->picture_structure == PICT_FRAME) { - /* top field */ - mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, - 1, 0, s->field_select[dir][0], - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], block_s, mb_y); - /* bottom field */ - mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, - 1, 1, s->field_select[dir][1], - ref_picture, pix_op, - s->mv[dir][1][0], s->mv[dir][1][1], block_s, mb_y); - } else { - if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){ - ref_picture= s->current_picture_ptr->data; - } - - mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, - 0, 0, s->field_select[dir][0], - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 2*block_s, mb_y>>1); - } - break; - case MV_TYPE_16X8: - for(i=0; i<2; i++){ - uint8_t ** ref2picture; - - if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == FF_B_TYPE || s->first_field){ - ref2picture= ref_picture; - }else{ - ref2picture= s->current_picture_ptr->data; - } - - mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, - 0, 0, s->field_select[dir][i], - ref2picture, pix_op, - s->mv[dir][i][0], s->mv[dir][i][1] + 2*block_s*i, block_s, mb_y>>1); - - dest_y += 2*block_s*s->linesize; - dest_cb+= (2*block_s>>s->chroma_y_shift)*s->uvlinesize; - dest_cr+= (2*block_s>>s->chroma_y_shift)*s->uvlinesize; - } - break; - case MV_TYPE_DMV: - if(s->picture_structure == PICT_FRAME){ - for(i=0; i<2; i++){ - int j; - for(j=0; j<2; j++){ - mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, - 1, j, j^i, - ref_picture, pix_op, - s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], block_s, mb_y); - } - pix_op = s->dsp.avg_h264_chroma_pixels_tab; - } - }else{ - for(i=0; i<2; i++){ - mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr, - 0, 0, s->picture_structure != i+1, - ref_picture, pix_op, - s->mv[dir][2*i][0],s->mv[dir][2*i][1],2*block_s, mb_y>>1); - - // after put we make avg of the same block - pix_op = s->dsp.avg_h264_chroma_pixels_tab; - - //opposite parity is always in the same frame if this is second field - if(!s->first_field){ - ref_picture = s->current_picture_ptr->data; - } - } - } - break; - default: assert(0); - } -} - -/* put block[] to dest[] */ -static inline void put_dct(MpegEncContext *s, - DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale) -{ - s->dct_unquantize_intra(s, block, i, qscale); - s->dsp.idct_put (dest, line_size, block); -} - -/* add block[] to dest[] */ -static inline void add_dct(MpegEncContext *s, - DCTELEM *block, int i, uint8_t *dest, int line_size) -{ - if (s->block_last_index[i] >= 0) { - s->dsp.idct_add (dest, line_size, block); - } -} - -static inline void add_dequant_dct(MpegEncContext *s, - DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale) -{ - if (s->block_last_index[i] >= 0) { - s->dct_unquantize_inter(s, block, i, qscale); - - s->dsp.idct_add (dest, line_size, block); - } -} - -/** - * cleans dc, ac, coded_block for the current non intra MB - */ -void ff_clean_intra_table_entries(MpegEncContext *s) -{ - int wrap = s->b8_stride; - int xy = s->block_index[0]; - - s->dc_val[0][xy ] = - s->dc_val[0][xy + 1 ] = - s->dc_val[0][xy + wrap] = - s->dc_val[0][xy + 1 + wrap] = 1024; - /* ac pred */ - memset(s->ac_val[0][xy ], 0, 32 * sizeof(int16_t)); - memset(s->ac_val[0][xy + wrap], 0, 32 * sizeof(int16_t)); - if (s->msmpeg4_version>=3) { - s->coded_block[xy ] = - s->coded_block[xy + 1 ] = - s->coded_block[xy + wrap] = - s->coded_block[xy + 1 + wrap] = 0; - } - /* chroma */ - wrap = s->mb_stride; - xy = s->mb_x + s->mb_y * wrap; - s->dc_val[1][xy] = - s->dc_val[2][xy] = 1024; - /* ac pred */ - memset(s->ac_val[1][xy], 0, 16 * sizeof(int16_t)); - memset(s->ac_val[2][xy], 0, 16 * sizeof(int16_t)); - - s->mbintra_table[xy]= 0; -} - -/* generic function called after a macroblock has been parsed by the - decoder or after it has been encoded by the encoder. - - Important variables used: - s->mb_intra : true if intra macroblock - s->mv_dir : motion vector direction - s->mv_type : motion vector type - s->mv : motion vector - s->interlaced_dct : true if interlaced dct used (mpeg2) - */ -static av_always_inline -void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], - int lowres_flag, int is_mpeg12) -{ - const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; - if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){ - ff_xvmc_decode_mb(s);//xvmc uses pblocks - return; - } - - if(s->avctx->debug&FF_DEBUG_DCT_COEFF) { - /* save DCT coefficients */ - int i,j; - DCTELEM *dct = &s->current_picture.dct_coeff[mb_xy*64*6]; - for(i=0; i<6; i++) - for(j=0; j<64; j++) - *dct++ = block[i][s->dsp.idct_permutation[j]]; - } - - s->current_picture.qscale_table[mb_xy]= s->qscale; - - /* update DC predictors for P macroblocks */ - if (!s->mb_intra) { - if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) { - if(s->mbintra_table[mb_xy]) - ff_clean_intra_table_entries(s); - } else { - s->last_dc[0] = - s->last_dc[1] = - s->last_dc[2] = 128 << s->intra_dc_precision; - } - } - else if (!is_mpeg12 && (s->h263_pred || s->h263_aic)) - s->mbintra_table[mb_xy]=1; - - if ((s->flags&CODEC_FLAG_PSNR) || !(s->encoding && (s->intra_only || s->pict_type==FF_B_TYPE) && s->avctx->mb_decision != FF_MB_DECISION_RD)) { //FIXME precalc - uint8_t *dest_y, *dest_cb, *dest_cr; - int dct_linesize, dct_offset; - op_pixels_func (*op_pix)[4]; - qpel_mc_func (*op_qpix)[16]; - const int linesize= s->current_picture.linesize[0]; //not s->linesize as this would be wrong for field pics - const int uvlinesize= s->current_picture.linesize[1]; - const int readable= s->pict_type != FF_B_TYPE || s->encoding || s->avctx->draw_horiz_band || lowres_flag; - const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8; - - /* avoid copy if macroblock skipped in last frame too */ - /* skip only during decoding as we might trash the buffers during encoding a bit */ - if(!s->encoding){ - uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy]; - const int age= s->current_picture.age; - - assert(age); - - if (s->mb_skipped) { - s->mb_skipped= 0; - assert(s->pict_type!=FF_I_TYPE); - - (*mbskip_ptr) ++; /* indicate that this time we skipped it */ - if(*mbskip_ptr >99) *mbskip_ptr= 99; - - /* if previous was skipped too, then nothing to do ! */ - if (*mbskip_ptr >= age && s->current_picture.reference){ - return; - } - } else if(!s->current_picture.reference){ - (*mbskip_ptr) ++; /* increase counter so the age can be compared cleanly */ - if(*mbskip_ptr >99) *mbskip_ptr= 99; - } else{ - *mbskip_ptr = 0; /* not skipped */ - } - } - - dct_linesize = linesize << s->interlaced_dct; - dct_offset =(s->interlaced_dct)? linesize : linesize*block_size; - - if(readable){ - dest_y= s->dest[0]; - dest_cb= s->dest[1]; - dest_cr= s->dest[2]; - }else{ - dest_y = s->b_scratchpad; - dest_cb= s->b_scratchpad+16*linesize; - dest_cr= s->b_scratchpad+32*linesize; - } - - if (!s->mb_intra) { - /* motion handling */ - /* decoding or more than one mb_type (MC was already done otherwise) */ - if(!s->encoding){ - if(lowres_flag){ - h264_chroma_mc_func *op_pix = s->dsp.put_h264_chroma_pixels_tab; - - if (s->mv_dir & MV_DIR_FORWARD) { - MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix); - op_pix = s->dsp.avg_h264_chroma_pixels_tab; - } - if (s->mv_dir & MV_DIR_BACKWARD) { - MPV_motion_lowres(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix); - } - }else{ - op_qpix= s->me.qpel_put; - if ((!s->no_rounding) || s->pict_type==FF_B_TYPE){ - op_pix = s->dsp.put_pixels_tab; - }else{ - op_pix = s->dsp.put_no_rnd_pixels_tab; - } - if (s->mv_dir & MV_DIR_FORWARD) { - MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix); - op_pix = s->dsp.avg_pixels_tab; - op_qpix= s->me.qpel_avg; - } - if (s->mv_dir & MV_DIR_BACKWARD) { - MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix); - } - } - } - - /* skip dequant / idct if we are really late ;) */ - if(s->hurry_up>1) goto skip_idct; - if(s->avctx->skip_idct){ - if( (s->avctx->skip_idct >= AVDISCARD_NONREF && s->pict_type == FF_B_TYPE) - ||(s->avctx->skip_idct >= AVDISCARD_NONKEY && s->pict_type != FF_I_TYPE) - || s->avctx->skip_idct >= AVDISCARD_ALL) - goto skip_idct; - } - - /* add dct residue */ - if(s->encoding || !( s->h263_msmpeg4 || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO - || (s->codec_id==CODEC_ID_MPEG4 && !s->mpeg_quant))){ - add_dequant_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); - add_dequant_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); - add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); - add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - if (s->chroma_y_shift){ - add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); - add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); - }else{ - dct_linesize >>= 1; - dct_offset >>=1; - add_dequant_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); - add_dequant_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); - add_dequant_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); - add_dequant_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); - } - } - } else if(is_mpeg12 || (s->codec_id != CODEC_ID_WMV2)){ - add_dct(s, block[0], 0, dest_y , dct_linesize); - add_dct(s, block[1], 1, dest_y + block_size, dct_linesize); - add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize); - add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize); - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - if(s->chroma_y_shift){//Chroma420 - add_dct(s, block[4], 4, dest_cb, uvlinesize); - add_dct(s, block[5], 5, dest_cr, uvlinesize); - }else{ - //chroma422 - dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset =(s->interlaced_dct)? uvlinesize : uvlinesize*8; - - add_dct(s, block[4], 4, dest_cb, dct_linesize); - add_dct(s, block[5], 5, dest_cr, dct_linesize); - add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize); - add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize); - if(!s->chroma_x_shift){//Chroma444 - add_dct(s, block[8], 8, dest_cb+8, dct_linesize); - add_dct(s, block[9], 9, dest_cr+8, dct_linesize); - add_dct(s, block[10], 10, dest_cb+8+dct_offset, dct_linesize); - add_dct(s, block[11], 11, dest_cr+8+dct_offset, dct_linesize); - } - } - }//fi gray - } - else if (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) { - ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr); - } - } else { - /* dct only in intra block */ - if(s->encoding || !(s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO)){ - put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); - put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); - put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); - put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - if(s->chroma_y_shift){ - put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); - put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); - }else{ - dct_offset >>=1; - dct_linesize >>=1; - put_dct(s, block[4], 4, dest_cb, dct_linesize, s->chroma_qscale); - put_dct(s, block[5], 5, dest_cr, dct_linesize, s->chroma_qscale); - put_dct(s, block[6], 6, dest_cb + dct_offset, dct_linesize, s->chroma_qscale); - put_dct(s, block[7], 7, dest_cr + dct_offset, dct_linesize, s->chroma_qscale); - } - } - }else{ - s->dsp.idct_put(dest_y , dct_linesize, block[0]); - s->dsp.idct_put(dest_y + block_size, dct_linesize, block[1]); - s->dsp.idct_put(dest_y + dct_offset , dct_linesize, block[2]); - s->dsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]); - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - if(s->chroma_y_shift){ - s->dsp.idct_put(dest_cb, uvlinesize, block[4]); - s->dsp.idct_put(dest_cr, uvlinesize, block[5]); - }else{ - - dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset =(s->interlaced_dct)? uvlinesize : uvlinesize*8; - - s->dsp.idct_put(dest_cb, dct_linesize, block[4]); - s->dsp.idct_put(dest_cr, dct_linesize, block[5]); - s->dsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]); - s->dsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]); - if(!s->chroma_x_shift){//Chroma444 - s->dsp.idct_put(dest_cb + 8, dct_linesize, block[8]); - s->dsp.idct_put(dest_cr + 8, dct_linesize, block[9]); - s->dsp.idct_put(dest_cb + 8 + dct_offset, dct_linesize, block[10]); - s->dsp.idct_put(dest_cr + 8 + dct_offset, dct_linesize, block[11]); - } - } - }//gray - } - } -skip_idct: - if(!readable){ - s->dsp.put_pixels_tab[0][0](s->dest[0], dest_y , linesize,16); - s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift); - s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift); - } - } -} - -void MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){ -#if !CONFIG_SMALL - if(s->out_format == FMT_MPEG1) { - if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 1); - else MPV_decode_mb_internal(s, block, 0, 1); - } else -#endif - if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 0); - else MPV_decode_mb_internal(s, block, 0, 0); -} - -/** - * - * @param h is the normal height, this will be reduced automatically if needed for the last row - */ -void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ - if (s->avctx->draw_horiz_band) { - AVFrame *src; - const int field_pic= s->picture_structure != PICT_FRAME; - int offset[4]; - - h= FFMIN(h, (s->avctx->height>>field_pic) - y); - - if(field_pic && !(s->avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)){ - h <<= 1; - y <<= 1; - if(s->first_field) return; - } - - if(s->pict_type==FF_B_TYPE || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER)) - src= (AVFrame*)s->current_picture_ptr; - else if(s->last_picture_ptr) - src= (AVFrame*)s->last_picture_ptr; - else - return; - - if(s->pict_type==FF_B_TYPE && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){ - offset[0]= - offset[1]= - offset[2]= - offset[3]= 0; - }else{ - offset[0]= y * s->linesize; - offset[1]= - offset[2]= (y >> s->chroma_y_shift) * s->uvlinesize; - offset[3]= 0; - } - - emms_c(); - - s->avctx->draw_horiz_band(s->avctx, src, offset, - y, s->picture_structure, h); - } -} - -void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename - const int linesize= s->current_picture.linesize[0]; //not s->linesize as this would be wrong for field pics - const int uvlinesize= s->current_picture.linesize[1]; - const int mb_size= 4 - s->avctx->lowres; - - s->block_index[0]= s->b8_stride*(s->mb_y*2 ) - 2 + s->mb_x*2; - s->block_index[1]= s->b8_stride*(s->mb_y*2 ) - 1 + s->mb_x*2; - s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1) - 2 + s->mb_x*2; - s->block_index[3]= s->b8_stride*(s->mb_y*2 + 1) - 1 + s->mb_x*2; - s->block_index[4]= s->mb_stride*(s->mb_y + 1) + s->b8_stride*s->mb_height*2 + s->mb_x - 1; - s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1; - //block_index is not used by mpeg2, so it is not affected by chroma_format - - s->dest[0] = s->current_picture.data[0] + ((s->mb_x - 1) << mb_size); - s->dest[1] = s->current_picture.data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift)); - s->dest[2] = s->current_picture.data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift)); - - if(!(s->pict_type==FF_B_TYPE && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME)) - { - if(s->picture_structure==PICT_FRAME){ - s->dest[0] += s->mb_y * linesize << mb_size; - s->dest[1] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift); - s->dest[2] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift); - }else{ - s->dest[0] += (s->mb_y>>1) * linesize << mb_size; - s->dest[1] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift); - s->dest[2] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift); - assert((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD)); - } - } -} - -void ff_mpeg_flush(AVCodecContext *avctx){ - int i; - MpegEncContext *s = avctx->priv_data; - - if(s==NULL || s->picture==NULL) - return; - - for(i=0; ipicture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL - || s->picture[i].type == FF_BUFFER_TYPE_USER)) - free_frame_buffer(s, &s->picture[i]); - } - s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; - - s->mb_x= s->mb_y= 0; - s->closed_gop= 0; - - s->parse_context.state= -1; - s->parse_context.frame_start_found= 0; - s->parse_context.overread= 0; - s->parse_context.overread_index= 0; - s->parse_context.index= 0; - s->parse_context.last_index= 0; - s->bitstream_buffer_size=0; - s->pp_time=0; -} - -static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int i, level, nCoeffs; - const uint16_t *quant_matrix; - - nCoeffs= s->block_last_index[n]; - - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; - /* XXX: only mpeg1 */ - quant_matrix = s->intra_matrix; - for(i=1;i<=nCoeffs;i++) { - int j= s->intra_scantable.permutated[i]; - level = block[j]; - if (level) { - if (level < 0) { - level = -level; - level = (int)(level * qscale * quant_matrix[j]) >> 3; - level = (level - 1) | 1; - level = -level; - } else { - level = (int)(level * qscale * quant_matrix[j]) >> 3; - level = (level - 1) | 1; - } - block[j] = level; - } - } -} - -static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int i, level, nCoeffs; - const uint16_t *quant_matrix; - - nCoeffs= s->block_last_index[n]; - - quant_matrix = s->inter_matrix; - for(i=0; i<=nCoeffs; i++) { - int j= s->intra_scantable.permutated[i]; - level = block[j]; - if (level) { - if (level < 0) { - level = -level; - level = (((level << 1) + 1) * qscale * - ((int) (quant_matrix[j]))) >> 4; - level = (level - 1) | 1; - level = -level; - } else { - level = (((level << 1) + 1) * qscale * - ((int) (quant_matrix[j]))) >> 4; - level = (level - 1) | 1; - } - block[j] = level; - } - } -} - -static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int i, level, nCoeffs; - const uint16_t *quant_matrix; - - if(s->alternate_scan) nCoeffs= 63; - else nCoeffs= s->block_last_index[n]; - - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; - quant_matrix = s->intra_matrix; - for(i=1;i<=nCoeffs;i++) { - int j= s->intra_scantable.permutated[i]; - level = block[j]; - if (level) { - if (level < 0) { - level = -level; - level = (int)(level * qscale * quant_matrix[j]) >> 3; - level = -level; - } else { - level = (int)(level * qscale * quant_matrix[j]) >> 3; - } - block[j] = level; - } - } -} - -static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int i, level, nCoeffs; - const uint16_t *quant_matrix; - int sum=-1; - - if(s->alternate_scan) nCoeffs= 63; - else nCoeffs= s->block_last_index[n]; - - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; - quant_matrix = s->intra_matrix; - for(i=1;i<=nCoeffs;i++) { - int j= s->intra_scantable.permutated[i]; - level = block[j]; - if (level) { - if (level < 0) { - level = -level; - level = (int)(level * qscale * quant_matrix[j]) >> 3; - level = -level; - } else { - level = (int)(level * qscale * quant_matrix[j]) >> 3; - } - block[j] = level; - sum+=level; - } - } - block[63]^=sum&1; -} - -static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int i, level, nCoeffs; - const uint16_t *quant_matrix; - int sum=-1; - - if(s->alternate_scan) nCoeffs= 63; - else nCoeffs= s->block_last_index[n]; - - quant_matrix = s->inter_matrix; - for(i=0; i<=nCoeffs; i++) { - int j= s->intra_scantable.permutated[i]; - level = block[j]; - if (level) { - if (level < 0) { - level = -level; - level = (((level << 1) + 1) * qscale * - ((int) (quant_matrix[j]))) >> 4; - level = -level; - } else { - level = (((level << 1) + 1) * qscale * - ((int) (quant_matrix[j]))) >> 4; - } - block[j] = level; - sum+=level; - } - } - block[63]^=sum&1; -} - -static void dct_unquantize_h263_intra_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int i, level, qmul, qadd; - int nCoeffs; - - assert(s->block_last_index[n]>=0); - - qmul = qscale << 1; - - if (!s->h263_aic) { - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; - qadd = (qscale - 1) | 1; - }else{ - qadd = 0; - } - if(s->ac_pred) - nCoeffs=63; - else - nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; - - for(i=1; i<=nCoeffs; i++) { - level = block[i]; - if (level) { - if (level < 0) { - level = level * qmul - qadd; - } else { - level = level * qmul + qadd; - } - block[i] = level; - } - } -} - -static void dct_unquantize_h263_inter_c(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int i, level, qmul, qadd; - int nCoeffs; - - assert(s->block_last_index[n]>=0); - - qadd = (qscale - 1) | 1; - qmul = qscale << 1; - - nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; - - for(i=0; i<=nCoeffs; i++) { - level = block[i]; - if (level) { - if (level < 0) { - level = level * qmul - qadd; - } else { - level = level * qmul + qadd; - } - block[i] = level; - } - } -} - -/** - * set qscale and update qscale dependent 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 ]; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegvideo.h b/tizen/distrib/ffmpeg/libavcodec/mpegvideo.h deleted file mode 100644 index 8cd20b7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegvideo.h +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Generic DCT based hybrid video encoder - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * mpegvideo header. - */ - -#ifndef AVCODEC_MPEGVIDEO_H -#define AVCODEC_MPEGVIDEO_H - -#include "dsputil.h" -#include "get_bits.h" -#include "put_bits.h" -#include "ratecontrol.h" -#include "parser.h" -#include "mpeg12data.h" -#include "rl.h" - -#define FRAME_SKIPPED 100 ///< return value for header parsers if frame is not coded - -enum OutputFormat { - FMT_MPEG1, - FMT_H261, - FMT_H263, - FMT_MJPEG, - FMT_H264, -}; - -#define MPEG_BUF_SIZE (16 * 1024) - -#define QMAT_SHIFT_MMX 16 -#define QMAT_SHIFT 22 - -#define MAX_FCODE 7 -#define MAX_MV 2048 - -#define MAX_THREADS 16 - -#define MAX_PICTURE_COUNT 32 - -#define ME_MAP_SIZE 64 -#define ME_MAP_SHIFT 3 -#define ME_MAP_MV_BITS 11 - -#define MAX_MB_BYTES (30*16*16*3/8 + 120) - -#define INPLACE_OFFSET 16 - -/* Start codes. */ -#define SEQ_END_CODE 0x000001b7 -#define SEQ_START_CODE 0x000001b3 -#define GOP_START_CODE 0x000001b8 -#define PICTURE_START_CODE 0x00000100 -#define SLICE_MIN_START_CODE 0x00000101 -#define SLICE_MAX_START_CODE 0x000001af -#define EXT_START_CODE 0x000001b5 -#define USER_START_CODE 0x000001b2 - -/** - * Picture. - */ -typedef struct Picture{ - FF_COMMON_FRAME - - /** - * halfpel luma planes. - */ - uint8_t *interpolated[3]; - int16_t (*motion_val_base[2])[2]; - uint32_t *mb_type_base; -#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is just one type -#define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4) -#define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16) -#define IS_PCM(a) ((a)&MB_TYPE_INTRA_PCM) -#define IS_INTRA(a) ((a)&7) -#define IS_INTER(a) ((a)&(MB_TYPE_16x16|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8)) -#define IS_SKIP(a) ((a)&MB_TYPE_SKIP) -#define IS_INTRA_PCM(a) ((a)&MB_TYPE_INTRA_PCM) -#define IS_INTERLACED(a) ((a)&MB_TYPE_INTERLACED) -#define IS_DIRECT(a) ((a)&MB_TYPE_DIRECT2) -#define IS_GMC(a) ((a)&MB_TYPE_GMC) -#define IS_16X16(a) ((a)&MB_TYPE_16x16) -#define IS_16X8(a) ((a)&MB_TYPE_16x8) -#define IS_8X16(a) ((a)&MB_TYPE_8x16) -#define IS_8X8(a) ((a)&MB_TYPE_8x8) -#define IS_SUB_8X8(a) ((a)&MB_TYPE_16x16) //note reused -#define IS_SUB_8X4(a) ((a)&MB_TYPE_16x8) //note reused -#define IS_SUB_4X8(a) ((a)&MB_TYPE_8x16) //note reused -#define IS_SUB_4X4(a) ((a)&MB_TYPE_8x8) //note reused -#define IS_ACPRED(a) ((a)&MB_TYPE_ACPRED) -#define IS_QUANT(a) ((a)&MB_TYPE_QUANT) -#define IS_DIR(a, part, list) ((a) & (MB_TYPE_P0L0<<((part)+2*(list)))) -#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list)))) ///< does this mb use listX, note does not work if subMBs -#define HAS_CBP(a) ((a)&MB_TYPE_CBP) - - int field_poc[2]; ///< h264 top/bottom POC - int poc; ///< h264 frame POC - int frame_num; ///< h264 frame_num (raw frame_num from slice header) - int mmco_reset; ///< h264 MMCO_RESET set this 1. Reordering code must not mix pictures before and after MMCO_RESET. - int pic_id; /**< h264 pic_num (short -> no wrap version of pic_num, - pic_num & max_pic_num; long -> long_pic_num) */ - int long_ref; ///< 1->long term reference 0->short term reference - int ref_poc[2][2][16]; ///< h264 POCs of the frames used as reference (FIXME need per slice) - int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice) - int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF - - int mb_var_sum; ///< sum of MB variance for current frame - int mc_mb_var_sum; ///< motion compensated MB variance for current frame - uint16_t *mb_var; ///< Table for MB variances - uint16_t *mc_mb_var; ///< Table for motion compensated MB variances - uint8_t *mb_mean; ///< Table for MB luminance - int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decision FIXME remove - int b_frame_score; /* */ -} Picture; - -struct MpegEncContext; - -/** - * Motion estimation context. - */ -typedef struct MotionEstContext{ - AVCodecContext *avctx; - int skip; ///< set if ME is skipped for the current MB - int co_located_mv[4][2]; ///< mv from last P-frame for direct mode ME - int direct_basis_mv[4][2]; - uint8_t *scratchpad; ///< data area for the ME algo, so that the ME does not need to malloc/free - uint8_t *best_mb; - uint8_t *temp_mb[2]; - uint8_t *temp; - int best_bits; - uint32_t *map; ///< map to avoid duplicate evaluations - uint32_t *score_map; ///< map to store the scores - int map_generation; - int pre_penalty_factor; - int penalty_factor; /*!< an estimate of the bits required to - code a given mv value, e.g. (1,0) takes - more bits than (0,0). We have to - estimate whether any reduction in - residual is worth the extra bits. */ - int sub_penalty_factor; - int mb_penalty_factor; - int flags; - int sub_flags; - int mb_flags; - int pre_pass; ///< = 1 for the pre pass - int dia_size; - int xmin; - int xmax; - int ymin; - int ymax; - int pred_x; - int pred_y; - uint8_t *src[4][4]; - uint8_t *ref[4][4]; - int stride; - int uvstride; - /* temp variables for picture complexity calculation */ - int mc_mb_var_sum_temp; - int mb_var_sum_temp; - int scene_change_score; -/* cmp, chroma_cmp;*/ - op_pixels_func (*hpel_put)[4]; - op_pixels_func (*hpel_avg)[4]; - qpel_mc_func (*qpel_put)[16]; - qpel_mc_func (*qpel_avg)[16]; - uint8_t (*mv_penalty)[MAX_MV*2+1]; ///< amount of bits needed to encode a MV - uint8_t *current_mv_penalty; - int (*sub_motion_search)(struct MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - int src_index, int ref_index, - int size, int h); -}MotionEstContext; - -/** - * MpegEncContext. - */ -typedef struct MpegEncContext { - struct AVCodecContext *avctx; - /* the following parameters must be initialized before encoding */ - int width, height;///< picture size. must be a multiple of 16 - int gop_size; - int intra_only; ///< if true, only intra pictures are generated - int bit_rate; ///< wanted bit rate - enum OutputFormat out_format; ///< output format - int h263_pred; ///< use mpeg4/h263 ac/dc predictions - int pb_frame; ///< PB frame mode (0 = none, 1 = base, 2 = improved) - -/* the following codec id fields are deprecated in favor of codec_id */ - int h263_plus; ///< h263 plus headers - int h263_msmpeg4; ///< generate MSMPEG4 compatible stream (deprecated, use msmpeg4_version instead) - int h263_flv; ///< use flv h263 header - - enum CodecID codec_id; /* see CODEC_ID_xxx */ - int fixed_qscale; ///< fixed qscale if non zero - int encoding; ///< true if we are encoding (vs decoding) - int flags; ///< AVCodecContext.flags (HQ, MV4, ...) - int flags2; ///< AVCodecContext.flags2 - int max_b_frames; ///< max number of b-frames for encoding - int luma_elim_threshold; - int chroma_elim_threshold; - int strict_std_compliance; ///< strictly follow the std (MPEG4, ...) - int workaround_bugs; ///< workaround bugs in encoders which cannot be detected automatically - int codec_tag; ///< internal codec_tag upper case converted from avctx codec_tag - int stream_codec_tag; ///< internal stream_codec_tag upper case converted from avctx stream_codec_tag - /* the following fields are managed internally by the encoder */ - - /** bit output */ - PutBitContext pb; - - /* sequence parameters */ - int context_initialized; - int input_picture_number; ///< used to set pic->display_picture_number, should not be used for/by anything else - int coded_picture_number; ///< used to set pic->coded_picture_number, should not be used for/by anything else - int picture_number; //FIXME remove, unclear definition - int picture_in_gop_number; ///< 0-> first pic in gop, ... - int b_frames_since_non_b; ///< used for encoding, relative to not yet reordered input - int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video() - int mb_width, mb_height; ///< number of MBs horizontally & vertically - int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 - int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing - int b4_stride; ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressing - int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication) - int mb_num; ///< number of MBs of a picture - int linesize; ///< line size, in bytes, may be different from width - int uvlinesize; ///< line size, for chroma in bytes, may be different from width - Picture *picture; ///< main picture buffer - Picture **input_picture; ///< next pictures on display order for encoding - Picture **reordered_input_picture; ///< pointer to the next pictures in codedorder for encoding - - int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) - int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) - struct MpegEncContext *thread_context[MAX_THREADS]; - - /** - * copy of the previous picture structure. - * note, linesize & data, might not match the previous picture (for field pictures) - */ - Picture last_picture; - - /** - * copy of the next picture structure. - * note, linesize & data, might not match the next picture (for field pictures) - */ - Picture next_picture; - - /** - * copy of the source picture structure for encoding. - * note, linesize & data, might not match the source picture (for field pictures) - */ - Picture new_picture; - - /** - * copy of the current picture structure. - * note, linesize & data, might not match the current picture (for field pictures) - */ - Picture current_picture; ///< buffer to store the decompressed current picture - - Picture *last_picture_ptr; ///< pointer to the previous picture. - Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) - Picture *current_picture_ptr; ///< pointer to the current picture - uint8_t *visualization_buffer[3]; //< temporary buffer vor MV visualization - int last_dc[3]; ///< last DC values for MPEG1 - int16_t *dc_val_base; - int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous - int16_t dc_cache[4*5]; - int y_dc_scale, c_dc_scale; - const uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table - const uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table - const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (h263) - uint8_t *coded_block_base; - uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1) - int16_t (*ac_val_base)[16]; - int16_t (*ac_val[3])[16]; ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous - int ac_pred; - uint8_t *prev_pict_types; ///< previous picture types in bitstream order, used for mb skip -#define PREV_PICT_TYPES_BUFFER_SIZE 256 - int mb_skipped; ///< MUST BE SET only during DECODING - uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example) - and used for b-frame encoding & decoding (contains skip table of next P Frame) */ - uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding - uint8_t *cbp_table; ///< used to store cbp, ac_pred for partitioned decoding - uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding - uint8_t *allocated_edge_emu_buffer; - uint8_t *edge_emu_buffer; ///< points into the middle of allocated_edge_emu_buffer - uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision - uint8_t *obmc_scratchpad; - uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers - - int qscale; ///< QP - int chroma_qscale; ///< chroma QP - unsigned int lambda; ///< lagrange multipler used in rate distortion - unsigned int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT - int *lambda_table; - int adaptive_quant; ///< use adaptive quantization - int dquant; ///< qscale difference to prev qscale - int closed_gop; ///< MPEG1/2 GOP is closed - int pict_type; ///< FF_I_TYPE, FF_P_TYPE, FF_B_TYPE, ... - int last_pict_type; //FIXME removes - int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol - int dropable; - int frame_rate_index; - int last_lambda_for[5]; ///< last lambda for a specific pict type - int skipdct; ///< skip dct and code zero residual - - /* motion compensation */ - int unrestricted_mv; ///< mv can point outside of the coded picture - int h263_long_vectors; ///< use horrible h263v1 long vector mode - int decode; ///< if 0 then decoding will be skipped (for encoding b frames for example) - - DSPContext dsp; ///< pointers for accelerated dsp functions - int f_code; ///< forward MV resolution - int b_code; ///< backward MV resolution for B Frames (mpeg4) - int16_t (*p_mv_table_base)[2]; - int16_t (*b_forw_mv_table_base)[2]; - int16_t (*b_back_mv_table_base)[2]; - int16_t (*b_bidir_forw_mv_table_base)[2]; - int16_t (*b_bidir_back_mv_table_base)[2]; - int16_t (*b_direct_mv_table_base)[2]; - int16_t (*p_field_mv_table_base[2][2])[2]; - int16_t (*b_field_mv_table_base[2][2][2])[2]; - int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) p-frame encoding - int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode b-frame encoding - int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode b-frame encoding - int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding - int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding - int16_t (*b_direct_mv_table)[2]; ///< MV table (1MV per MB) direct mode b-frame encoding - int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced p-frame encoding - int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced b-frame encoding - uint8_t (*p_field_select_table[2]); - uint8_t (*b_field_select_table[2][2]); - int me_method; ///< ME algorithm - int mv_dir; -#define MV_DIR_FORWARD 1 -#define MV_DIR_BACKWARD 2 -#define MV_DIRECT 4 ///< bidirectional mode where the difference equals the MV of the last P/S/I-Frame (mpeg4) - int mv_type; -#define MV_TYPE_16X16 0 ///< 1 vector for the whole mb -#define MV_TYPE_8X8 1 ///< 4 vectors (h263, mpeg4 4MV) -#define MV_TYPE_16X8 2 ///< 2 vectors, one per 16x8 block -#define MV_TYPE_FIELD 3 ///< 2 vectors, one per field -#define MV_TYPE_DMV 4 ///< 2 vectors, special mpeg2 Dual Prime Vectors - /**motion vectors for a macroblock - first coordinate : 0 = forward 1 = backward - second " : depend on type - third " : 0 = x, 1 = y - */ - int mv[2][4][2]; - int field_select[2][2]; - int last_mv[2][2][2]; ///< last MV, used for MV prediction in MPEG1 & B-frame MPEG4 - uint8_t *fcode_tab; ///< smallest fcode needed for each MV - int16_t direct_scale_mv[2][64]; ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv - - MotionEstContext me; - - int no_rounding; /**< apply no rounding to motion compensation (MPEG4, msmpeg4, ...) - for b-frames rounding mode is always 0 */ - - int hurry_up; /**< when set to 1 during decoding, b frames will be skipped - when set to 2 idct/dequant will be skipped too */ - - /* macroblock layer */ - int mb_x, mb_y; - int mb_skip_run; - int mb_intra; - uint16_t *mb_type; ///< Table for candidate MB types for encoding -#define CANDIDATE_MB_TYPE_INTRA 0x01 -#define CANDIDATE_MB_TYPE_INTER 0x02 -#define CANDIDATE_MB_TYPE_INTER4V 0x04 -#define CANDIDATE_MB_TYPE_SKIPPED 0x08 -//#define MB_TYPE_GMC 0x10 - -#define CANDIDATE_MB_TYPE_DIRECT 0x10 -#define CANDIDATE_MB_TYPE_FORWARD 0x20 -#define CANDIDATE_MB_TYPE_BACKWARD 0x40 -#define CANDIDATE_MB_TYPE_BIDIR 0x80 - -#define CANDIDATE_MB_TYPE_INTER_I 0x100 -#define CANDIDATE_MB_TYPE_FORWARD_I 0x200 -#define CANDIDATE_MB_TYPE_BACKWARD_I 0x400 -#define CANDIDATE_MB_TYPE_BIDIR_I 0x800 - -#define CANDIDATE_MB_TYPE_DIRECT0 0x1000 - - int block_index[6]; ///< index to current MB in block based arrays with edges - int block_wrap[6]; - uint8_t *dest[3]; - - int *mb_index2xy; ///< mb_index -> mb_x + mb_y*mb_stride - - /** matrix transmitted in the bitstream */ - uint16_t intra_matrix[64]; - uint16_t chroma_intra_matrix[64]; - uint16_t inter_matrix[64]; - uint16_t chroma_inter_matrix[64]; -#define QUANT_BIAS_SHIFT 8 - int intra_quant_bias; ///< bias for the quantizer - int inter_quant_bias; ///< bias for the quantizer - int min_qcoeff; ///< minimum encodable coefficient - int max_qcoeff; ///< maximum encodable coefficient - int ac_esc_length; ///< num of bits needed to encode the longest esc - uint8_t *intra_ac_vlc_length; - uint8_t *intra_ac_vlc_last_length; - uint8_t *inter_ac_vlc_length; - uint8_t *inter_ac_vlc_last_length; - uint8_t *luma_dc_vlc_length; - uint8_t *chroma_dc_vlc_length; -#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level)) - - int coded_score[8]; - - /** precomputed matrix (combine qscale and DCT renorm) */ - int (*q_intra_matrix)[64]; - int (*q_inter_matrix)[64]; - /** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/ - uint16_t (*q_intra_matrix16)[2][64]; - uint16_t (*q_inter_matrix16)[2][64]; - int block_last_index[12]; ///< last non zero coefficient in block - /* scantables */ - ScanTable intra_scantable; - ScanTable intra_h_scantable; - ScanTable intra_v_scantable; - ScanTable inter_scantable; ///< if inter == intra then intra should be used to reduce tha cache usage - - /* noise reduction */ - int (*dct_error_sum)[64]; - int dct_count[2]; - uint16_t (*dct_offset)[64]; - - void *opaque; ///< private data for the user - - /* bit rate control */ - int64_t wanted_bits; - int64_t total_bits; - int frame_bits; ///< bits used for the current frame - int next_lambda; ///< next lambda used for retrying to encode a frame - RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c - - /* statistics, used for 2-pass encoding */ - int mv_bits; - int header_bits; - int i_tex_bits; - int p_tex_bits; - int i_count; - int f_count; - int b_count; - int skip_count; - int misc_bits; ///< cbp, mb_type - int last_bits; ///< temp var used for calculating the above vars - - /* error concealment / resync */ - int error_count; - uint8_t *error_status_table; ///< table of the error status of each MB -#define VP_START 1 ///< current MB is the first after a resync marker -#define AC_ERROR 2 -#define DC_ERROR 4 -#define MV_ERROR 8 -#define AC_END 16 -#define DC_END 32 -#define MV_END 64 -//FIXME some prefix? - - int resync_mb_x; ///< x position of last resync marker - int resync_mb_y; ///< y position of last resync marker - GetBitContext last_resync_gb; ///< used to search for the next resync marker - int mb_num_left; ///< number of MBs left in this video packet (for partitioned Slices only) - int next_p_frame_damaged; ///< set if the next p frame is damaged, to avoid showing trashed b frames - int error_recognition; - - ParseContext parse_context; - - /* H.263 specific */ - int gob_index; - int obmc; ///< overlapped block motion compensation - int showed_packed_warning; ///< flag for having shown the warning about divxs invalid b frames - - /* H.263+ specific */ - int umvplus; ///< == H263+ && unrestricted_mv - int h263_aic; ///< Advanded INTRA Coding (AIC) - int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top - int h263_slice_structured; - int alt_inter_vlc; ///< alternative inter vlc - int modified_quant; - int loop_filter; - int custom_pcf; - - /* mpeg4 specific */ - int time_increment_bits; ///< number of bits to represent the fractional part of time - int last_time_base; - int time_base; ///< time in seconds of last I,P,S Frame - int64_t time; ///< time of current frame - int64_t last_non_b_time; - uint16_t pp_time; ///< time distance between the last 2 p,s,i frames - uint16_t pb_time; ///< time distance between the last b and p,s,i frame - uint16_t pp_field_time; - uint16_t pb_field_time; ///< like above, just for interlaced - int shape; - int vol_sprite_usage; - int sprite_width; - int sprite_height; - int sprite_left; - int sprite_top; - int sprite_brightness_change; - int num_sprite_warping_points; - int real_sprite_warping_points; - uint16_t sprite_traj[4][2]; ///< sprite trajectory points - int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY] - int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY] - int sprite_shift[2]; ///< sprite shift [isChroma] - int mcsel; - int quant_precision; - int quarter_sample; ///< 1->qpel, 0->half pel ME/MC - int scalability; - int hierachy_type; - int enhancement_type; - int new_pred; - int reduced_res_vop; - int aspect_ratio_info; //FIXME remove - int sprite_warping_accuracy; - int low_latency_sprite; - int data_partitioning; ///< data partitioning flag from header - int partitioned_frame; ///< is current frame partitioned - int rvlc; ///< reversible vlc - int resync_marker; ///< could this stream contain resync markers - int low_delay; ///< no reordering needed / has no b-frames - int vo_type; - int vol_control_parameters; ///< does the stream contain the low_delay flag, used to workaround buggy encoders - int intra_dc_threshold; ///< QP above whch the ac VLC should be used for intra dc - int use_intra_dc_vlc; - PutBitContext tex_pb; ///< used for data partitioned VOPs - PutBitContext pb2; ///< used for data partitioned VOPs - int mpeg_quant; - int t_frame; ///< time distance of first I -> B, used for interlaced b frames - int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4 - int cplx_estimation_trash_i; - int cplx_estimation_trash_p; - int cplx_estimation_trash_b; - - /* divx specific, used to workaround (many) bugs in divx5 */ - int divx_version; - int divx_build; - int divx_packed; - uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them - int bitstream_buffer_size; - unsigned int allocated_bitstream_buffer_size; - - int xvid_build; - - /* lavc specific stuff, used to workaround bugs in libavcodec */ - int lavc_build; - - /* RV10 specific */ - int rv10_version; ///< RV10 version: 0 or 3 - int rv10_first_dc_coded[3]; - int orig_width, orig_height; - - /* MJPEG specific */ - struct MJpegContext *mjpeg_ctx; - int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1} - int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1} - - /* MSMPEG4 specific */ - int mv_table_index; - int rl_table_index; - int rl_chroma_table_index; - int dc_table_index; - int use_skip_mb_code; - int slice_height; ///< in macroblocks - int first_slice_line; ///< used in mpeg4 too to handle resync markers - int flipflop_rounding; - int msmpeg4_version; ///< 0=not msmpeg4, 1=mp41, 2=mp42, 3=mp43/divx3 4=wmv1/7 5=wmv2/8 - int per_mb_rl_table; - int esc3_level_length; - int esc3_run_length; - /** [mb_intra][isChroma][level][run][last] */ - int (*ac_stats)[2][MAX_LEVEL+1][MAX_RUN+1][2]; - int inter_intra_pred; - int mspel; - - /* decompression specific */ - GetBitContext gb; - - /* Mpeg1 specific */ - int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific - int last_mv_dir; ///< last mv_dir, used for b frame encoding - int broken_link; ///< no_output_of_prior_pics_flag - uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream - - /* MPEG-2-specific - I wished not to have to support this mess. */ - int progressive_sequence; - int mpeg_f_code[2][2]; - int picture_structure; -/* picture type */ -#define PICT_TOP_FIELD 1 -#define PICT_BOTTOM_FIELD 2 -#define PICT_FRAME 3 - - int intra_dc_precision; - int frame_pred_frame_dct; - int top_field_first; - int concealment_motion_vectors; - int q_scale_type; - int intra_vlc_format; - int alternate_scan; - int repeat_first_field; - int chroma_420_type; - int chroma_format; -#define CHROMA_420 1 -#define CHROMA_422 2 -#define CHROMA_444 3 - int chroma_x_shift;//depend on pix_format, that depend on chroma_format - int chroma_y_shift; - - int progressive_frame; - int full_pel[2]; - int interlaced_dct; - int first_slice; - int first_field; ///< is 1 for the first field of a field picture 0 otherwise - - /* RTP specific */ - int rtp_mode; - - uint8_t *ptr_lastgob; - int swap_uv; //vcr2 codec is an MPEG-2 variant with U and V swapped - DCTELEM (*pblocks[12])[64]; - - DCTELEM (*block)[64]; ///< points to one of the following blocks - DCTELEM (*blocks)[8][64]; // for HQ mode we need to keep the best block - int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch() -#define SLICE_OK 0 -#define SLICE_ERROR -1 -#define SLICE_END -2 ///>s->avctx->lowres; - - s->block_index[0]+=2; - s->block_index[1]+=2; - s->block_index[2]+=2; - s->block_index[3]+=2; - s->block_index[4]++; - s->block_index[5]++; - s->dest[0]+= 2*block_size; - s->dest[1]+= block_size; - s->dest[2]+= block_size; -} - -static inline int get_bits_diff(MpegEncContext *s){ - const int bits= put_bits_count(&s->pb); - const int last= s->last_bits; - - s->last_bits = bits; - - return bits - last; -} - -static inline int ff_h263_round_chroma(int x){ - static const uint8_t h263_chroma_roundtab[16] = { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - }; - return h263_chroma_roundtab[x & 0xf] + (x >> 3); -} - -/* motion_est.c */ -void ff_estimate_p_frame_motion(MpegEncContext * s, - int mb_x, int mb_y); -void ff_estimate_b_frame_motion(MpegEncContext * s, - int mb_x, int mb_y); -int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type); -void ff_fix_long_p_mvs(MpegEncContext * s); -void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select, - int16_t (*mv_table)[2], int f_code, int type, int truncate); -int ff_init_me(MpegEncContext *s); -int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y); -int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, - int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], - int ref_mv_scale, int size, int h); -int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, - int ref_index, int size, int h, int add_rate); - -/* mpeg12.c */ -extern const uint8_t ff_mpeg1_dc_scale_table[128]; -extern const uint8_t * const ff_mpeg2_dc_scale_table[4]; - -void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number); -void mpeg1_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void ff_mpeg1_encode_init(MpegEncContext *s); -void ff_mpeg1_encode_slice_header(MpegEncContext *s); -void ff_mpeg1_clean_buffers(MpegEncContext *s); -int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s); - -extern const uint8_t ff_aic_dc_scale_table[32]; -extern const uint8_t ff_h263_chroma_qscale_table[32]; -extern const uint8_t ff_h263_loop_filter_strength[32]; - -/* h261.c */ -void ff_h261_loop_filter(MpegEncContext *s); -void ff_h261_reorder_mb_index(MpegEncContext* s); -void ff_h261_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number); -void ff_h261_encode_init(MpegEncContext *s); -int ff_h261_get_picture_format(int width, int height); - - -/* rv10.c */ -void rv10_encode_picture_header(MpegEncContext *s, int picture_number); -int rv_decode_dc(MpegEncContext *s, int n); -void rv20_encode_picture_header(MpegEncContext *s, int picture_number); - - -/* msmpeg4.c */ -void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number); -void msmpeg4_encode_ext_header(MpegEncContext * s); -void msmpeg4_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y); -int msmpeg4_decode_picture_header(MpegEncContext * s); -int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size); -int ff_msmpeg4_decode_init(AVCodecContext *avctx); -void ff_msmpeg4_encode_init(MpegEncContext *s); -int ff_wmv2_decode_picture_header(MpegEncContext * s); -int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s); -void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr); -void ff_mspel_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h); -int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number); -void ff_wmv2_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y); - -#endif /* AVCODEC_MPEGVIDEO_H */ - diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_common.h b/tizen/distrib/ffmpeg/libavcodec/mpegvideo_common.h deleted file mode 100644 index 7310666..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_common.h +++ /dev/null @@ -1,901 +0,0 @@ -/* - * The simplest mpeg encoder (well, it was the simplest!) - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * 4MV & hq & B-frame encoding stuff by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * The simplest mpeg encoder (well, it was the simplest!). - */ - -#ifndef AVCODEC_MPEGVIDEO_COMMON_H -#define AVCODEC_MPEGVIDEO_COMMON_H - -#include -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mjpegenc.h" -#include "msmpeg4.h" -#include "faandct.h" -#include - -int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); -int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); -void denoise_dct_c(MpegEncContext *s, DCTELEM *block); - -/** - * allocates a Picture - * The pixels are allocated/set by calling get_buffer() if shared=0 - */ -int alloc_picture(MpegEncContext *s, Picture *pic, int shared); - -/** - * sets the given MpegEncContext to common defaults (same for encoding and decoding). - * the changed fields will not depend upon the prior state of the MpegEncContext. - */ -void MPV_common_defaults(MpegEncContext *s); - -static inline void gmc1_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture) -{ - uint8_t *ptr; - int offset, src_x, src_y, linesize, uvlinesize; - int motion_x, motion_y; - int emu=0; - - motion_x= s->sprite_offset[0][0]; - motion_y= s->sprite_offset[0][1]; - src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1)); - src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1)); - motion_x<<=(3-s->sprite_warping_accuracy); - motion_y<<=(3-s->sprite_warping_accuracy); - src_x = av_clip(src_x, -16, s->width); - if (src_x == s->width) - motion_x =0; - src_y = av_clip(src_y, -16, s->height); - if (src_y == s->height) - motion_y =0; - - linesize = s->linesize; - uvlinesize = s->uvlinesize; - - ptr = ref_picture[0] + (src_y * linesize) + src_x; - - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x >= s->h_edge_pos - 17 - || (unsigned)src_y >= s->v_edge_pos - 17){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos); - ptr= s->edge_emu_buffer; - } - } - - if((motion_x|motion_y)&7){ - s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); - s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); - }else{ - int dxy; - - dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2); - if (s->no_rounding){ - s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); - }else{ - s->dsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16); - } - } - - if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return; - - motion_x= s->sprite_offset[1][0]; - motion_y= s->sprite_offset[1][1]; - src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1)); - src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1)); - motion_x<<=(3-s->sprite_warping_accuracy); - motion_y<<=(3-s->sprite_warping_accuracy); - src_x = av_clip(src_x, -8, s->width>>1); - if (src_x == s->width>>1) - motion_x =0; - src_y = av_clip(src_y, -8, s->height>>1); - if (src_y == s->height>>1) - motion_y =0; - - offset = (src_y * uvlinesize) + src_x; - ptr = ref_picture[1] + offset; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9 - || (unsigned)src_y >= (s->v_edge_pos>>1) - 9){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - emu=1; - } - } - s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); - - ptr = ref_picture[2] + offset; - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - } - s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); - - return; -} - -static inline void gmc_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture) -{ - uint8_t *ptr; - int linesize, uvlinesize; - const int a= s->sprite_warping_accuracy; - int ox, oy; - - linesize = s->linesize; - uvlinesize = s->uvlinesize; - - ptr = ref_picture[0]; - - ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16; - oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16; - - s->dsp.gmc(dest_y, ptr, linesize, 16, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos, s->v_edge_pos); - s->dsp.gmc(dest_y+8, ptr, linesize, 16, - ox + s->sprite_delta[0][0]*8, - oy + s->sprite_delta[1][0]*8, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos, s->v_edge_pos); - - if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return; - - ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8; - oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8; - - ptr = ref_picture[1]; - s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos>>1, s->v_edge_pos>>1); - - ptr = ref_picture[2]; - s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos>>1, s->v_edge_pos>>1); -} - -static inline int hpel_motion(MpegEncContext *s, - uint8_t *dest, uint8_t *src, - int field_based, int field_select, - int src_x, int src_y, - int width, int height, int stride, - int h_edge_pos, int v_edge_pos, - int w, int h, op_pixels_func *pix_op, - int motion_x, int motion_y) -{ - int dxy; - int emu=0; - - dxy = ((motion_y & 1) << 1) | (motion_x & 1); - src_x += motion_x >> 1; - src_y += motion_y >> 1; - - /* WARNING: do no forget half pels */ - src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu? - if (src_x == width) - dxy &= ~1; - src_y = av_clip(src_y, -16, height); - if (src_y == height) - dxy &= ~2; - src += src_y * stride + src_x; - - if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){ - if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w - || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){ - ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<v_edge_pos); - src= s->edge_emu_buffer; - emu=1; - } - } - if(field_select) - src += s->linesize; - pix_op[dxy](dest, src, stride, h); - return emu; -} - -static av_always_inline -void mpeg_motion_internal(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h, int is_mpeg12, int mb_y) -{ - uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int dxy, uvdxy, mx, my, src_x, src_y, - uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize; - -#if 0 -if(s->quarter_sample) -{ - motion_x>>=1; - motion_y>>=1; -} -#endif - - v_edge_pos = s->v_edge_pos >> field_based; - linesize = s->current_picture.linesize[0] << field_based; - uvlinesize = s->current_picture.linesize[1] << field_based; - - dxy = ((motion_y & 1) << 1) | (motion_x & 1); - src_x = s->mb_x* 16 + (motion_x >> 1); - src_y =( mb_y<<(4-field_based)) + (motion_y >> 1); - - if (!is_mpeg12 && s->out_format == FMT_H263) { - if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){ - mx = (motion_x>>1)|(motion_x&1); - my = motion_y >>1; - uvdxy = ((my & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); - }else{ - uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); - uvsrc_x = src_x>>1; - uvsrc_y = src_y>>1; - } - }else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261 - mx = motion_x / 4; - my = motion_y / 4; - uvdxy = 0; - uvsrc_x = s->mb_x*8 + mx; - uvsrc_y = mb_y*8 + my; - } else { - if(s->chroma_y_shift){ - mx = motion_x / 2; - my = motion_y / 2; - uvdxy = ((my & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y =( mb_y<<(3-field_based))+ (my >> 1); - } else { - if(s->chroma_x_shift){ - //Chroma422 - mx = motion_x / 2; - uvdxy = ((motion_y & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y = src_y; - } else { - //Chroma444 - uvdxy = dxy; - uvsrc_x = src_x; - uvsrc_y = src_y; - } - } - } - - ptr_y = ref_picture[0] + src_y * linesize + src_x; - ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; - ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - - if( (unsigned)src_x > s->h_edge_pos - (motion_x&1) - 16 - || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){ - if(is_mpeg12 || s->codec_id == CODEC_ID_MPEG2VIDEO || - s->codec_id == CODEC_ID_MPEG1VIDEO){ - av_log(s->avctx,AV_LOG_DEBUG, - "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y); - return; - } - ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, - 17, 17+field_based, - src_x, src_y<h_edge_pos, s->v_edge_pos); - ptr_y = s->edge_emu_buffer; - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize; - ff_emulated_edge_mc(uvbuf , - ptr_cb, s->uvlinesize, - 9, 9+field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - ff_emulated_edge_mc(uvbuf+16, - ptr_cr, s->uvlinesize, - 9, 9+field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - ptr_cb= uvbuf; - ptr_cr= uvbuf+16; - } - } - - if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data - dest_y += s->linesize; - dest_cb+= s->uvlinesize; - dest_cr+= s->uvlinesize; - } - - if(field_select){ - ptr_y += s->linesize; - ptr_cb+= s->uvlinesize; - ptr_cr+= s->uvlinesize; - } - - pix_op[0][dxy](dest_y, ptr_y, linesize, h); - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - pix_op[s->chroma_x_shift][uvdxy] - (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); - pix_op[s->chroma_x_shift][uvdxy] - (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); - } - if(!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) && - s->out_format == FMT_H261){ - ff_h261_loop_filter(s); - } -} -/* apply one mpeg motion vector to the three components */ -static av_always_inline -void mpeg_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h, int mb_y) -{ -#if !CONFIG_SMALL - if(s->out_format == FMT_MPEG1) - mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based, - bottom_field, field_select, ref_picture, pix_op, - motion_x, motion_y, h, 1, mb_y); - else -#endif - mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based, - bottom_field, field_select, ref_picture, pix_op, - motion_x, motion_y, h, 0, mb_y); -} - -//FIXME move to dsputil, avg variant, 16x16 version -static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){ - int x; - uint8_t * const top = src[1]; - uint8_t * const left = src[2]; - uint8_t * const mid = src[0]; - uint8_t * const right = src[3]; - uint8_t * const bottom= src[4]; -#define OBMC_FILTER(x, t, l, m, r, b)\ - dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3 -#define OBMC_FILTER4(x, t, l, m, r, b)\ - OBMC_FILTER(x , t, l, m, r, b);\ - OBMC_FILTER(x+1 , t, l, m, r, b);\ - OBMC_FILTER(x +stride, t, l, m, r, b);\ - OBMC_FILTER(x+1+stride, t, l, m, r, b); - - x=0; - OBMC_FILTER (x , 2, 2, 4, 0, 0); - OBMC_FILTER (x+1, 2, 1, 5, 0, 0); - OBMC_FILTER4(x+2, 2, 1, 5, 0, 0); - OBMC_FILTER4(x+4, 2, 0, 5, 1, 0); - OBMC_FILTER (x+6, 2, 0, 5, 1, 0); - OBMC_FILTER (x+7, 2, 0, 4, 2, 0); - x+= stride; - OBMC_FILTER (x , 1, 2, 5, 0, 0); - OBMC_FILTER (x+1, 1, 2, 5, 0, 0); - OBMC_FILTER (x+6, 1, 0, 5, 2, 0); - OBMC_FILTER (x+7, 1, 0, 5, 2, 0); - x+= stride; - OBMC_FILTER4(x , 1, 2, 5, 0, 0); - OBMC_FILTER4(x+2, 1, 1, 6, 0, 0); - OBMC_FILTER4(x+4, 1, 0, 6, 1, 0); - OBMC_FILTER4(x+6, 1, 0, 5, 2, 0); - x+= 2*stride; - OBMC_FILTER4(x , 0, 2, 5, 0, 1); - OBMC_FILTER4(x+2, 0, 1, 6, 0, 1); - OBMC_FILTER4(x+4, 0, 0, 6, 1, 1); - OBMC_FILTER4(x+6, 0, 0, 5, 2, 1); - x+= 2*stride; - OBMC_FILTER (x , 0, 2, 5, 0, 1); - OBMC_FILTER (x+1, 0, 2, 5, 0, 1); - OBMC_FILTER4(x+2, 0, 1, 5, 0, 2); - OBMC_FILTER4(x+4, 0, 0, 5, 1, 2); - OBMC_FILTER (x+6, 0, 0, 5, 2, 1); - OBMC_FILTER (x+7, 0, 0, 5, 2, 1); - x+= stride; - OBMC_FILTER (x , 0, 2, 4, 0, 2); - OBMC_FILTER (x+1, 0, 1, 5, 0, 2); - OBMC_FILTER (x+6, 0, 0, 5, 1, 2); - OBMC_FILTER (x+7, 0, 0, 4, 2, 2); -} - -/* obmc for 1 8x8 luma block */ -static inline void obmc_motion(MpegEncContext *s, - uint8_t *dest, uint8_t *src, - int src_x, int src_y, - op_pixels_func *pix_op, - int16_t mv[5][2]/* mid top left right bottom*/) -#define MID 0 -{ - int i; - uint8_t *ptr[5]; - - assert(s->quarter_sample==0); - - for(i=0; i<5; i++){ - if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){ - ptr[i]= ptr[MID]; - }else{ - ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1); - hpel_motion(s, ptr[i], src, 0, 0, - src_x, src_y, - s->width, s->height, s->linesize, - s->h_edge_pos, s->v_edge_pos, - 8, 8, pix_op, - mv[i][0], mv[i][1]); - } - } - - put_obmc(dest, ptr, s->linesize); -} - -static inline void qpel_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - qpel_mc_func (*qpix_op)[16], - int motion_x, int motion_y, int h) -{ - uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize; - - dxy = ((motion_y & 3) << 2) | (motion_x & 3); - src_x = s->mb_x * 16 + (motion_x >> 2); - src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); - - v_edge_pos = s->v_edge_pos >> field_based; - linesize = s->linesize << field_based; - uvlinesize = s->uvlinesize << field_based; - - if(field_based){ - mx= motion_x/2; - my= motion_y>>1; - }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){ - static const int rtab[8]= {0,0,1,1,0,0,0,1}; - mx= (motion_x>>1) + rtab[motion_x&7]; - my= (motion_y>>1) + rtab[motion_y&7]; - }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){ - mx= (motion_x>>1)|(motion_x&1); - my= (motion_y>>1)|(motion_y&1); - }else{ - mx= motion_x/2; - my= motion_y/2; - } - mx= (mx>>1)|(mx&1); - my= (my>>1)|(my&1); - - uvdxy= (mx&1) | ((my&1)<<1); - mx>>=1; - my>>=1; - - uvsrc_x = s->mb_x * 8 + mx; - uvsrc_y = s->mb_y * (8 >> field_based) + my; - - ptr_y = ref_picture[0] + src_y * linesize + src_x; - ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; - ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - - if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16 - || (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, - 17, 17+field_based, src_x, src_y<h_edge_pos, s->v_edge_pos); - ptr_y= s->edge_emu_buffer; - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize; - ff_emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize, - 9, 9 + field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - ff_emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, - 9, 9 + field_based, - uvsrc_x, uvsrc_y<h_edge_pos>>1, s->v_edge_pos>>1); - ptr_cb= uvbuf; - ptr_cr= uvbuf + 16; - } - } - - if(!field_based) - qpix_op[0][dxy](dest_y, ptr_y, linesize); - else{ - if(bottom_field){ - dest_y += s->linesize; - dest_cb+= s->uvlinesize; - dest_cr+= s->uvlinesize; - } - - if(field_select){ - ptr_y += s->linesize; - ptr_cb += s->uvlinesize; - ptr_cr += s->uvlinesize; - } - //damn interlaced mode - //FIXME boundary mirroring is not exactly correct here - qpix_op[1][dxy](dest_y , ptr_y , linesize); - qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize); - } - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ - pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1); - pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1); - } -} - -/** - * h263 chroma 4mv motion compensation. - */ -static inline void chroma_4mv_motion(MpegEncContext *s, - uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture, - op_pixels_func *pix_op, - int mx, int my){ - int dxy, emu=0, src_x, src_y, offset; - uint8_t *ptr; - - /* In case of 8X8, we construct a single chroma motion vector - with a special rounding */ - mx= ff_h263_round_chroma(mx); - my= ff_h263_round_chroma(my); - - dxy = ((my & 1) << 1) | (mx & 1); - mx >>= 1; - my >>= 1; - - src_x = s->mb_x * 8 + mx; - src_y = s->mb_y * 8 + my; - src_x = av_clip(src_x, -8, s->width/2); - if (src_x == s->width/2) - dxy &= ~1; - src_y = av_clip(src_y, -8, s->height/2); - if (src_y == s->height/2) - dxy &= ~2; - - offset = (src_y * (s->uvlinesize)) + src_x; - ptr = ref_picture[1] + offset; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x > (s->h_edge_pos>>1) - (dxy &1) - 8 - || (unsigned)src_y > (s->v_edge_pos>>1) - (dxy>>1) - 8){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, - 9, 9, src_x, src_y, - s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - emu=1; - } - } - pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8); - - ptr = ref_picture[2] + offset; - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, - 9, 9, src_x, src_y, - s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - } - pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8); -} - -static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ - /* fetch pixels for estimated mv 4 macroblocks ahead - * optimized for 64byte cache lines */ - const int shift = s->quarter_sample ? 2 : 1; - const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8; - const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y; - int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; - s->dsp.prefetch(pix[0]+off, s->linesize, 4); - off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; - s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2); -} - -/** - * motion compensation of a single macroblock - * @param s context - * @param dest_y luma destination pointer - * @param dest_cb chroma cb/u destination pointer - * @param dest_cr chroma cr/v destination pointer - * @param dir direction (0->forward, 1->backward) - * @param ref_picture array[3] of pointers to the 3 planes of the reference picture - * @param pic_op halfpel motion compensation function (average or put normally) - * @param pic_op qpel motion compensation function (average or put normally) - * the motion vectors are taken from s->mv and the MV type from s->mv_type - */ -static av_always_inline void MPV_motion_internal(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, - uint8_t *dest_cr, int dir, - uint8_t **ref_picture, - op_pixels_func (*pix_op)[4], - qpel_mc_func (*qpix_op)[16], int is_mpeg12) -{ - int dxy, mx, my, src_x, src_y, motion_x, motion_y; - int mb_x, mb_y, i; - uint8_t *ptr, *dest; - - mb_x = s->mb_x; - mb_y = s->mb_y; - - prefetch_motion(s, ref_picture, dir); - - if(!is_mpeg12 && s->obmc && s->pict_type != FF_B_TYPE){ - int16_t mv_cache[4][4][2]; - const int xy= s->mb_x + s->mb_y*s->mb_stride; - const int mot_stride= s->b8_stride; - const int mot_xy= mb_x*2 + mb_y*2*mot_stride; - - assert(!s->mb_skipped); - - memcpy(mv_cache[1][1], s->current_picture.motion_val[0][mot_xy ], sizeof(int16_t)*4); - memcpy(mv_cache[2][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); - memcpy(mv_cache[3][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); - - if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){ - memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4); - }else{ - memcpy(mv_cache[0][1], s->current_picture.motion_val[0][mot_xy-mot_stride], sizeof(int16_t)*4); - } - - if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){ - *(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1]; - *(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1]; - }else{ - *(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1]; - *(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride]; - } - - if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){ - *(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2]; - *(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2]; - }else{ - *(int32_t*)mv_cache[1][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2]; - *(int32_t*)mv_cache[2][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2+mot_stride]; - } - - mx = 0; - my = 0; - for(i=0;i<4;i++) { - const int x= (i&1)+1; - const int y= (i>>1)+1; - int16_t mv[5][2]= { - {mv_cache[y][x ][0], mv_cache[y][x ][1]}, - {mv_cache[y-1][x][0], mv_cache[y-1][x][1]}, - {mv_cache[y][x-1][0], mv_cache[y][x-1][1]}, - {mv_cache[y][x+1][0], mv_cache[y][x+1][1]}, - {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}}; - //FIXME cleanup - obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, - ref_picture[0], - mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, - pix_op[1], - mv); - - mx += mv[0][0]; - my += mv[0][1]; - } - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) - chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); - - return; - } - - switch(s->mv_type) { - case MV_TYPE_16X16: - if(s->mcsel){ - if(s->real_sprite_warping_points==1){ - gmc1_motion(s, dest_y, dest_cb, dest_cr, - ref_picture); - }else{ - gmc_motion(s, dest_y, dest_cb, dest_cr, - ref_picture); - } - }else if(!is_mpeg12 && s->quarter_sample){ - qpel_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, 0, - ref_picture, pix_op, qpix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else if(!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && s->mspel){ - ff_mspel_motion(s, dest_y, dest_cb, dest_cr, - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else - { - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, 0, - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y); - } - break; - case MV_TYPE_8X8: - if (!is_mpeg12) { - mx = 0; - my = 0; - if(s->quarter_sample){ - for(i=0;i<4;i++) { - motion_x = s->mv[dir][i][0]; - motion_y = s->mv[dir][i][1]; - - dxy = ((motion_y & 3) << 2) | (motion_x & 3); - src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; - src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8; - - /* WARNING: do no forget half pels */ - src_x = av_clip(src_x, -16, s->width); - if (src_x == s->width) - dxy &= ~3; - src_y = av_clip(src_y, -16, s->height); - if (src_y == s->height) - dxy &= ~12; - - ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8 - || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, - s->linesize, 9, 9, - src_x, src_y, - s->h_edge_pos, s->v_edge_pos); - ptr= s->edge_emu_buffer; - } - } - dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; - qpix_op[1][dxy](dest, ptr, s->linesize); - - mx += s->mv[dir][i][0]/2; - my += s->mv[dir][i][1]/2; - } - }else{ - for(i=0;i<4;i++) { - hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, - ref_picture[0], 0, 0, - mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, - s->width, s->height, s->linesize, - s->h_edge_pos, s->v_edge_pos, - 8, 8, pix_op[1], - s->mv[dir][i][0], s->mv[dir][i][1]); - - mx += s->mv[dir][i][0]; - my += s->mv[dir][i][1]; - } - } - - if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) - chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); - } - break; - case MV_TYPE_FIELD: - if (s->picture_structure == PICT_FRAME) { - if(!is_mpeg12 && s->quarter_sample){ - for(i=0; i<2; i++){ - qpel_motion(s, dest_y, dest_cb, dest_cr, - 1, i, s->field_select[dir][i], - ref_picture, pix_op, qpix_op, - s->mv[dir][i][0], s->mv[dir][i][1], 8); - } - }else{ - /* top field */ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 1, 0, s->field_select[dir][0], - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y); - /* bottom field */ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 1, 1, s->field_select[dir][1], - ref_picture, pix_op, - s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y); - } - } else { - if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){ - ref_picture= s->current_picture_ptr->data; - } - - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, s->field_select[dir][0], - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1); - } - break; - case MV_TYPE_16X8: - for(i=0; i<2; i++){ - uint8_t ** ref2picture; - - if(s->picture_structure == s->field_select[dir][i] + 1 - || s->pict_type == FF_B_TYPE || s->first_field){ - ref2picture= ref_picture; - }else{ - ref2picture= s->current_picture_ptr->data; - } - - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, s->field_select[dir][i], - ref2picture, pix_op, - s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1); - - dest_y += 16*s->linesize; - dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize; - dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize; - } - break; - case MV_TYPE_DMV: - if(s->picture_structure == PICT_FRAME){ - for(i=0; i<2; i++){ - int j; - for(j=0; j<2; j++){ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 1, j, j^i, - ref_picture, pix_op, - s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8, mb_y); - } - pix_op = s->dsp.avg_pixels_tab; - } - }else{ - for(i=0; i<2; i++){ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, s->picture_structure != i+1, - ref_picture, pix_op, - s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1); - - // after put we make avg of the same block - pix_op=s->dsp.avg_pixels_tab; - - //opposite parity is always in the same frame if this is second field - if(!s->first_field){ - ref_picture = s->current_picture_ptr->data; - } - } - } - break; - default: assert(0); - } -} - -static inline void MPV_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, - uint8_t *dest_cr, int dir, - uint8_t **ref_picture, - op_pixels_func (*pix_op)[4], - qpel_mc_func (*qpix_op)[16]) -{ -#if !CONFIG_SMALL - if(s->out_format == FMT_MPEG1) - MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir, - ref_picture, pix_op, qpix_op, 1); - else -#endif - MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir, - ref_picture, pix_op, qpix_op, 0); -} -#endif /* AVCODEC_MPEGVIDEO_COMMON_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_enc.c b/tizen/distrib/ffmpeg/libavcodec/mpegvideo_enc.c deleted file mode 100644 index a8616d0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_enc.c +++ /dev/null @@ -1,3842 +0,0 @@ -/* - * The simplest mpeg encoder (well, it was the simplest!) - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * 4MV & hq & B-frame encoding stuff by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * The simplest mpeg encoder (well, it was the simplest!). - */ - -#include "libavutil/intmath.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mpegvideo_common.h" -#include "h263.h" -#include "mjpegenc.h" -#include "msmpeg4.h" -#include "faandct.h" -#include "aandcttab.h" -#include "flv.h" -#include "mpeg4video.h" -#include "internal.h" -#include - -//#undef NDEBUG -//#include - -static int encode_picture(MpegEncContext *s, int picture_number); -static int dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale); -static int sse_mb(MpegEncContext *s); - -/* enable all paranoid tests for rounding, overflows, etc... */ -//#define PARANOID - -//#define DEBUG - -static uint8_t default_mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; -static uint8_t default_fcode_tab[MAX_MV*2+1]; - -void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64], - const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra) -{ - int qscale; - int shift=0; - - for(qscale=qmin; qscale<=qmax; qscale++){ - int i; - if (dsp->fdct == ff_jpeg_fdct_islow -#ifdef FAAN_POSTSCALE - || dsp->fdct == ff_faandct -#endif - ) { - for(i=0;i<64;i++) { - const int j= dsp->idct_permutation[i]; - /* 16 <= qscale * quant_matrix[i] <= 7905 */ - /* 19952 <= ff_aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ - /* (1 << 36) / 19952 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= (1 << 36) / 249205026 */ - /* 3444240 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= 275 */ - - qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / - (qscale * quant_matrix[j])); - } - } else if (dsp->fdct == fdct_ifast -#ifndef FAAN_POSTSCALE - || dsp->fdct == ff_faandct -#endif - ) { - for(i=0;i<64;i++) { - const int j= dsp->idct_permutation[i]; - /* 16 <= qscale * quant_matrix[i] <= 7905 */ - /* 19952 <= ff_aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ - /* (1 << 36) / 19952 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */ - /* 3444240 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= 275 */ - - qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) / - (ff_aanscales[i] * qscale * quant_matrix[j])); - } - } else { - for(i=0;i<64;i++) { - const int j= dsp->idct_permutation[i]; - /* We can safely suppose that 16 <= quant_matrix[i] <= 255 - So 16 <= qscale * quant_matrix[i] <= 7905 - so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905 - so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67 - */ - qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j])); -// qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]); - qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]); - - if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1; - qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]); - } - } - - for(i=intra; i<64; i++){ - int64_t max= 8191; - if (dsp->fdct == fdct_ifast -#ifndef FAAN_POSTSCALE - || dsp->fdct == ff_faandct -#endif - ) { - max = (8191LL*ff_aanscales[i]) >> 14; - } - while(((max * qmat[qscale][i]) >> shift) > INT_MAX){ - shift++; - } - } - } - if(shift){ - av_log(NULL, AV_LOG_INFO, "Warning, QMAT_SHIFT is larger than %d, overflows possible\n", QMAT_SHIFT - shift); - } -} - -static inline void update_qscale(MpegEncContext *s){ - s->qscale= (s->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); - s->qscale= av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax); - - s->lambda2= (s->lambda*s->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; -} - -void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix){ - int i; - - if(matrix){ - put_bits(pb, 1, 1); - for(i=0;i<64;i++) { - put_bits(pb, 8, matrix[ ff_zigzag_direct[i] ]); - } - }else - put_bits(pb, 1, 0); -} - -/** - * init s->current_picture.qscale_table from s->lambda_table - */ -void ff_init_qscale_tab(MpegEncContext *s){ - int8_t * const qscale_table= s->current_picture.qscale_table; - int i; - - for(i=0; imb_num; i++){ - unsigned int lam= s->lambda_table[ s->mb_index2xy[i] ]; - int qp= (lam*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); - qscale_table[ s->mb_index2xy[i] ]= av_clip(qp, s->avctx->qmin, s->avctx->qmax); - } -} - -static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, AVFrame *src){ - int i; - - dst->pict_type = src->pict_type; - dst->quality = src->quality; - dst->coded_picture_number = src->coded_picture_number; - dst->display_picture_number = src->display_picture_number; -// dst->reference = src->reference; - dst->pts = src->pts; - dst->interlaced_frame = src->interlaced_frame; - dst->top_field_first = src->top_field_first; - - if(s->avctx->me_threshold){ - if(!src->motion_val[0]) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_val not set!\n"); - if(!src->mb_type) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.mb_type not set!\n"); - if(!src->ref_index[0]) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.ref_index not set!\n"); - if(src->motion_subsample_log2 != dst->motion_subsample_log2) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n", - src->motion_subsample_log2, dst->motion_subsample_log2); - - memcpy(dst->mb_type, src->mb_type, s->mb_stride * s->mb_height * sizeof(dst->mb_type[0])); - - for(i=0; i<2; i++){ - int stride= ((16*s->mb_width )>>src->motion_subsample_log2) + 1; - int height= ((16*s->mb_height)>>src->motion_subsample_log2); - - if(src->motion_val[i] && src->motion_val[i] != dst->motion_val[i]){ - memcpy(dst->motion_val[i], src->motion_val[i], 2*stride*height*sizeof(int16_t)); - } - if(src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]){ - memcpy(dst->ref_index[i], src->ref_index[i], s->mb_stride*4*s->mb_height*sizeof(int8_t)); - } - } - } -} - -static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContext *src){ -#define COPY(a) dst->a= src->a - COPY(pict_type); - COPY(current_picture); - COPY(f_code); - COPY(b_code); - COPY(qscale); - COPY(lambda); - COPY(lambda2); - COPY(picture_in_gop_number); - COPY(gop_picture_number); - COPY(frame_pred_frame_dct); //FIXME don't set in encode_header - COPY(progressive_frame); //FIXME don't set in encode_header - COPY(partitioned_frame); //FIXME don't set in encode_header -#undef COPY -} - -/** - * sets the given MpegEncContext to defaults for encoding. - * the changed fields will not depend upon the prior state of the MpegEncContext. - */ -static void MPV_encode_defaults(MpegEncContext *s){ - int i; - MPV_common_defaults(s); - - for(i=-16; i<16; i++){ - default_fcode_tab[i + MAX_MV]= 1; - } - s->me.mv_penalty= default_mv_penalty; - s->fcode_tab= default_fcode_tab; -} - -/* init video encoder */ -av_cold int MPV_encode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - int i; - int chroma_h_shift, chroma_v_shift; - - MPV_encode_defaults(s); - - switch (avctx->codec_id) { - case CODEC_ID_MPEG2VIDEO: - if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){ - av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n"); - return -1; - } - break; - case CODEC_ID_LJPEG: - case CODEC_ID_MJPEG: - if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && avctx->pix_fmt != PIX_FMT_RGB32 && - ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){ - av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n"); - return -1; - } - break; - default: - if(avctx->pix_fmt != PIX_FMT_YUV420P){ - av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n"); - return -1; - } - } - - switch (avctx->pix_fmt) { - case PIX_FMT_YUVJ422P: - case PIX_FMT_YUV422P: - s->chroma_format = CHROMA_422; - break; - case PIX_FMT_YUVJ420P: - case PIX_FMT_YUV420P: - default: - s->chroma_format = CHROMA_420; - break; - } - - s->bit_rate = avctx->bit_rate; - s->width = avctx->width; - s->height = avctx->height; - if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n"); - avctx->gop_size=600; - } - s->gop_size = avctx->gop_size; - s->avctx = avctx; - s->flags= avctx->flags; - s->flags2= avctx->flags2; - s->max_b_frames= avctx->max_b_frames; - s->codec_id= avctx->codec->id; - s->luma_elim_threshold = avctx->luma_elim_threshold; - s->chroma_elim_threshold= avctx->chroma_elim_threshold; - s->strict_std_compliance= avctx->strict_std_compliance; - s->data_partitioning= avctx->flags & CODEC_FLAG_PART; - s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0; - s->mpeg_quant= avctx->mpeg_quant; - s->rtp_mode= !!avctx->rtp_payload_size; - s->intra_dc_precision= avctx->intra_dc_precision; - s->user_specified_pts = AV_NOPTS_VALUE; - - if (s->gop_size <= 1) { - s->intra_only = 1; - s->gop_size = 12; - } else { - s->intra_only = 0; - } - - s->me_method = avctx->me_method; - - /* Fixed QSCALE */ - s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE); - - s->adaptive_quant= ( s->avctx->lumi_masking - || s->avctx->dark_masking - || s->avctx->temporal_cplx_masking - || s->avctx->spatial_cplx_masking - || s->avctx->p_masking - || s->avctx->border_masking - || (s->flags&CODEC_FLAG_QP_RD)) - && !s->fixed_qscale; - - s->obmc= !!(s->flags & CODEC_FLAG_OBMC); - s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER); - s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN); - s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC); - s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT); - - if(avctx->rc_max_rate && !avctx->rc_buffer_size){ - av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n"); - return -1; - } - - if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){ - av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n"); - } - - if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){ - av_log(avctx, AV_LOG_ERROR, "bitrate below min bitrate\n"); - return -1; - } - - if(avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate){ - av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n"); - return -1; - } - - if(avctx->rc_max_rate && avctx->rc_max_rate == avctx->bit_rate && avctx->rc_max_rate != avctx->rc_min_rate){ - av_log(avctx, AV_LOG_INFO, "impossible bitrate constraints, this will fail\n"); - } - - if(avctx->rc_buffer_size && avctx->bit_rate*av_q2d(avctx->time_base) > avctx->rc_buffer_size){ - av_log(avctx, AV_LOG_ERROR, "VBV buffer too small for bitrate\n"); - return -1; - } - - if(avctx->bit_rate*av_q2d(avctx->time_base) > avctx->bit_rate_tolerance){ - av_log(avctx, AV_LOG_ERROR, "bitrate tolerance too small for bitrate\n"); - return -1; - } - - if( s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate - && (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO) - && 90000LL * (avctx->rc_buffer_size-1) > s->avctx->rc_max_rate*0xFFFFLL){ - - av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the specified vbv buffer is too large for the given bitrate!\n"); - } - - if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4 - && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P && s->codec_id != CODEC_ID_FLV1){ - av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n"); - return -1; - } - - if(s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE){ - av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n"); - return -1; - } - - if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){ - av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n"); - return -1; - } - - if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){ - av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n"); - return -1; - } - - if(s->data_partitioning && s->codec_id != CODEC_ID_MPEG4){ - av_log(avctx, AV_LOG_ERROR, "data partitioning not supported by codec\n"); - return -1; - } - - if(s->max_b_frames && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n"); - return -1; - } - - if ((s->codec_id == CODEC_ID_MPEG4 || s->codec_id == CODEC_ID_H263 || - s->codec_id == CODEC_ID_H263P) && - (avctx->sample_aspect_ratio.num > 255 || avctx->sample_aspect_ratio.den > 255)) { - av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i, limit is 255/255\n", - avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); - return -1; - } - - if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)) - && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n"); - return -1; - } - - if(s->mpeg_quant && s->codec_id != CODEC_ID_MPEG4){ //FIXME mpeg2 uses that too - av_log(avctx, AV_LOG_ERROR, "mpeg2 style quantization not supported by codec\n"); - return -1; - } - - if((s->flags & CODEC_FLAG_CBP_RD) && !avctx->trellis){ - av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n"); - return -1; - } - - if((s->flags & CODEC_FLAG_QP_RD) && s->avctx->mb_decision != FF_MB_DECISION_RD){ - av_log(avctx, AV_LOG_ERROR, "QP RD needs mbd=2\n"); - return -1; - } - - if(s->avctx->scenechange_threshold < 1000000000 && (s->flags & CODEC_FLAG_CLOSED_GOP)){ - av_log(avctx, AV_LOG_ERROR, "closed gop with scene change detection are not supported yet, set threshold to 1000000000\n"); - return -1; - } - - if((s->flags2 & CODEC_FLAG2_INTRA_VLC) && s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "intra vlc table not supported by codec\n"); - return -1; - } - - if(s->flags & CODEC_FLAG_LOW_DELAY){ - if (s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "low delay forcing is only available for mpeg2\n"); - return -1; - } - if (s->max_b_frames != 0){ - av_log(avctx, AV_LOG_ERROR, "b frames cannot be used with low delay\n"); - return -1; - } - } - - if(s->q_scale_type == 1){ - if(s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "non linear quant is only available for mpeg2\n"); - return -1; - } - if(avctx->qmax > 12){ - av_log(avctx, AV_LOG_ERROR, "non linear quant only supports qmax <= 12 currently\n"); - return -1; - } - } - - if(s->avctx->thread_count > 1 && s->codec_id != CODEC_ID_MPEG4 - && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO - && (s->codec_id != CODEC_ID_H263P || !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))){ - av_log(avctx, AV_LOG_ERROR, "multi threaded encoding not supported by codec\n"); - return -1; - } - - if(s->avctx->thread_count < 1){ - av_log(avctx, AV_LOG_ERROR, "automatic thread number detection not supported by codec, patch welcome\n"); - return -1; - } - - if(s->avctx->thread_count > 1) - s->rtp_mode= 1; - - if(!avctx->time_base.den || !avctx->time_base.num){ - av_log(avctx, AV_LOG_ERROR, "framerate not set\n"); - return -1; - } - - i= (INT_MAX/2+128)>>8; - if(avctx->me_threshold >= i){ - av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n", i - 1); - return -1; - } - if(avctx->mb_threshold >= i){ - av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n", i - 1); - return -1; - } - - if(avctx->b_frame_strategy && (avctx->flags&CODEC_FLAG_PASS2)){ - av_log(avctx, AV_LOG_INFO, "notice: b_frame_strategy only affects the first pass\n"); - avctx->b_frame_strategy = 0; - } - - i= av_gcd(avctx->time_base.den, avctx->time_base.num); - if(i > 1){ - av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n"); - avctx->time_base.den /= i; - avctx->time_base.num /= i; -// return -1; - } - - if(s->mpeg_quant || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO || s->codec_id==CODEC_ID_MJPEG){ - s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x - s->inter_quant_bias= 0; - }else{ - s->intra_quant_bias=0; - s->inter_quant_bias=-(1<<(QUANT_BIAS_SHIFT-2)); //(a - x/4)/x - } - - if(avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) - s->intra_quant_bias= avctx->intra_quant_bias; - if(avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS) - s->inter_quant_bias= avctx->inter_quant_bias; - - avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); - - if(avctx->codec_id == CODEC_ID_MPEG4 && s->avctx->time_base.den > (1<<16)-1){ - av_log(avctx, AV_LOG_ERROR, "timebase not supported by mpeg 4 standard\n"); - return -1; - } - s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; - - switch(avctx->codec->id) { - case CODEC_ID_MPEG1VIDEO: - s->out_format = FMT_MPEG1; - s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY); - avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); - break; - case CODEC_ID_MPEG2VIDEO: - s->out_format = FMT_MPEG1; - s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY); - avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); - s->rtp_mode= 1; - break; - case CODEC_ID_LJPEG: - case CODEC_ID_MJPEG: - s->out_format = FMT_MJPEG; - s->intra_only = 1; /* force intra only for jpeg */ - if(avctx->codec->id == CODEC_ID_LJPEG && avctx->pix_fmt == PIX_FMT_BGRA){ - s->mjpeg_vsample[0] = s->mjpeg_hsample[0] = - s->mjpeg_vsample[1] = s->mjpeg_hsample[1] = - s->mjpeg_vsample[2] = s->mjpeg_hsample[2] = 1; - }else{ - s->mjpeg_vsample[0] = 2; - s->mjpeg_vsample[1] = 2>>chroma_v_shift; - s->mjpeg_vsample[2] = 2>>chroma_v_shift; - s->mjpeg_hsample[0] = 2; - s->mjpeg_hsample[1] = 2>>chroma_h_shift; - s->mjpeg_hsample[2] = 2>>chroma_h_shift; - } - if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) - || ff_mjpeg_encode_init(s) < 0) - return -1; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_H261: - if (!CONFIG_H261_ENCODER) return -1; - if (ff_h261_get_picture_format(s->width, s->height) < 0) { - av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for the H.261 codec.\nValid sizes are 176x144, 352x288\n", s->width, s->height); - return -1; - } - s->out_format = FMT_H261; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_H263: - if (!CONFIG_H263_ENCODER) return -1; - if (ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), s->width, s->height) == 7) { - av_log(avctx, AV_LOG_INFO, "The specified picture size of %dx%d is not valid for the H.263 codec.\nValid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152. Try H.263+.\n", s->width, s->height); - return -1; - } - s->out_format = FMT_H263; - s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_H263P: - s->out_format = FMT_H263; - s->h263_plus = 1; - /* Fx */ - s->umvplus = (avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0; - s->h263_aic= (avctx->flags & CODEC_FLAG_AC_PRED) ? 1:0; - s->modified_quant= s->h263_aic; - s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0; - s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; - s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0; - s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; - s->h263_slice_structured= (s->flags & CODEC_FLAG_H263P_SLICE_STRUCT) ? 1:0; - - /* /Fx */ - /* These are just to be sure */ - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_FLV1: - s->out_format = FMT_H263; - s->h263_flv = 2; /* format = 1; 11-bit codes */ - s->unrestricted_mv = 1; - s->rtp_mode=0; /* don't allow GOB */ - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_RV10: - s->out_format = FMT_H263; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_RV20: - s->out_format = FMT_H263; - avctx->delay=0; - s->low_delay=1; - s->modified_quant=1; - s->h263_aic=1; - s->h263_plus=1; - s->loop_filter=1; - s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; - break; - case CODEC_ID_MPEG4: - s->out_format = FMT_H263; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->low_delay= s->max_b_frames ? 0 : 1; - avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); - break; - case CODEC_ID_MSMPEG4V1: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 1; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_MSMPEG4V2: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 2; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_MSMPEG4V3: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 3; - s->flipflop_rounding=1; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_WMV1: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 4; - s->flipflop_rounding=1; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_WMV2: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 5; - s->flipflop_rounding=1; - avctx->delay=0; - s->low_delay=1; - break; - default: - return -1; - } - - avctx->has_b_frames= !s->low_delay; - - s->encoding = 1; - - s->progressive_frame= - s->progressive_sequence= !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)); - - /* init */ - if (MPV_common_init(s) < 0) - return -1; - - if(!s->dct_quantize) - s->dct_quantize = dct_quantize_c; - if(!s->denoise_dct) - s->denoise_dct = denoise_dct_c; - s->fast_dct_quantize = s->dct_quantize; - if(avctx->trellis) - s->dct_quantize = dct_quantize_trellis_c; - - if((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant) - s->chroma_qscale_table= ff_h263_chroma_qscale_table; - - s->quant_precision=5; - - ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp); - ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp); - - if (CONFIG_H261_ENCODER && s->out_format == FMT_H261) - ff_h261_encode_init(s); - if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) - h263_encode_init(s); - if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version) - ff_msmpeg4_encode_init(s); - if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) - && s->out_format == FMT_MPEG1) - ff_mpeg1_encode_init(s); - - /* init q matrix */ - for(i=0;i<64;i++) { - int j= s->dsp.idct_permutation[i]; - if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){ - s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i]; - s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i]; - }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ - s->intra_matrix[j] = - s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; - }else - { /* mpeg1/2 */ - s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i]; - s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; - } - if(s->avctx->intra_matrix) - s->intra_matrix[j] = s->avctx->intra_matrix[i]; - if(s->avctx->inter_matrix) - s->inter_matrix[j] = s->avctx->inter_matrix[i]; - } - - /* precompute matrix */ - /* for mjpeg, we do include qscale in the matrix */ - if (s->out_format != FMT_MJPEG) { - ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, - s->intra_matrix, s->intra_quant_bias, avctx->qmin, 31, 1); - ff_convert_matrix(&s->dsp, s->q_inter_matrix, s->q_inter_matrix16, - s->inter_matrix, s->inter_quant_bias, avctx->qmin, 31, 0); - } - - if(ff_rate_control_init(s) < 0) - return -1; - - return 0; -} - -av_cold int MPV_encode_end(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - - ff_rate_control_uninit(s); - - MPV_common_end(s); - if ((CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) && s->out_format == FMT_MJPEG) - ff_mjpeg_encode_close(s); - - av_freep(&avctx->extradata); - - return 0; -} - -static int get_sae(uint8_t *src, int ref, int stride){ - int x,y; - int acc=0; - - for(y=0; y<16; y++){ - for(x=0; x<16; x++){ - acc+= FFABS(src[x+y*stride] - ref); - } - } - - return acc; -} - -static int get_intra_count(MpegEncContext *s, uint8_t *src, uint8_t *ref, int stride){ - int x, y, w, h; - int acc=0; - - w= s->width &~15; - h= s->height&~15; - - for(y=0; ydsp.sad[0](NULL, src + offset, ref + offset, stride, 16); - int mean= (s->dsp.pix_sum(src + offset, stride) + 128)>>8; - int sae = get_sae(src + offset, mean, stride); - - acc+= sae + 500 < sad; - } - } - return acc; -} - - -static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ - AVFrame *pic=NULL; - int64_t pts; - int i; - const int encoding_delay= s->max_b_frames; - int direct=1; - - if(pic_arg){ - pts= pic_arg->pts; - pic_arg->display_picture_number= s->input_picture_number++; - - if(pts != AV_NOPTS_VALUE){ - if(s->user_specified_pts != AV_NOPTS_VALUE){ - int64_t time= pts; - int64_t last= s->user_specified_pts; - - if(time <= last){ - av_log(s->avctx, AV_LOG_ERROR, "Error, Invalid timestamp=%"PRId64", last=%"PRId64"\n", pts, s->user_specified_pts); - return -1; - } - } - s->user_specified_pts= pts; - }else{ - if(s->user_specified_pts != AV_NOPTS_VALUE){ - s->user_specified_pts= - pts= s->user_specified_pts + 1; - av_log(s->avctx, AV_LOG_INFO, "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n", pts); - }else{ - pts= pic_arg->display_picture_number; - } - } - } - - if(pic_arg){ - if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0; - if(pic_arg->linesize[0] != s->linesize) direct=0; - if(pic_arg->linesize[1] != s->uvlinesize) direct=0; - if(pic_arg->linesize[2] != s->uvlinesize) direct=0; - -// av_log(AV_LOG_DEBUG, "%d %d %d %d\n",pic_arg->linesize[0], pic_arg->linesize[1], s->linesize, s->uvlinesize); - - if(direct){ - i= ff_find_unused_picture(s, 1); - - pic= (AVFrame*)&s->picture[i]; - pic->reference= 3; - - for(i=0; i<4; i++){ - pic->data[i]= pic_arg->data[i]; - pic->linesize[i]= pic_arg->linesize[i]; - } - if(ff_alloc_picture(s, (Picture*)pic, 1) < 0){ - return -1; - } - }else{ - i= ff_find_unused_picture(s, 0); - - pic= (AVFrame*)&s->picture[i]; - pic->reference= 3; - - if(ff_alloc_picture(s, (Picture*)pic, 0) < 0){ - return -1; - } - - if( pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] - && pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] - && pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]){ - // empty - }else{ - int h_chroma_shift, v_chroma_shift; - avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); - - for(i=0; i<3; i++){ - int src_stride= pic_arg->linesize[i]; - int dst_stride= i ? s->uvlinesize : s->linesize; - int h_shift= i ? h_chroma_shift : 0; - int v_shift= i ? v_chroma_shift : 0; - int w= s->width >>h_shift; - int h= s->height>>v_shift; - uint8_t *src= pic_arg->data[i]; - uint8_t *dst= pic->data[i]; - - if(!s->avctx->rc_buffer_size) - dst +=INPLACE_OFFSET; - - if(src_stride==dst_stride) - memcpy(dst, src, src_stride*h); - else{ - while(h--){ - memcpy(dst, src, w); - dst += dst_stride; - src += src_stride; - } - } - } - } - } - copy_picture_attributes(s, pic, pic_arg); - pic->pts= pts; //we set this here to avoid modifiying pic_arg - } - - /* shift buffer entries */ - for(i=1; iencoding_delay+1*/; i++) - s->input_picture[i-1]= s->input_picture[i]; - - s->input_picture[encoding_delay]= (Picture*)pic; - - return 0; -} - -static int skip_check(MpegEncContext *s, Picture *p, Picture *ref){ - int x, y, plane; - int score=0; - int64_t score64=0; - - for(plane=0; plane<3; plane++){ - const int stride= p->linesize[plane]; - const int bw= plane ? 1 : 2; - for(y=0; ymb_height*bw; y++){ - for(x=0; xmb_width*bw; x++){ - int off= p->type == FF_BUFFER_TYPE_SHARED ? 0: 16; - int v= s->dsp.frame_skip_cmp[1](s, p->data[plane] + 8*(x + y*stride)+off, ref->data[plane] + 8*(x + y*stride), stride, 8); - - switch(s->avctx->frame_skip_exp){ - case 0: score= FFMAX(score, v); break; - case 1: score+= FFABS(v);break; - case 2: score+= v*v;break; - case 3: score64+= FFABS(v*v*(int64_t)v);break; - case 4: score64+= v*v*(int64_t)(v*v);break; - } - } - } - } - - if(score) score64= score; - - if(score64 < s->avctx->frame_skip_threshold) - return 1; - if(score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda)>>8)) - return 1; - return 0; -} - -static int estimate_best_b_count(MpegEncContext *s){ - AVCodec *codec= avcodec_find_encoder(s->avctx->codec_id); - AVCodecContext *c= avcodec_alloc_context(); - AVFrame input[FF_MAX_B_FRAMES+2]; - const int scale= s->avctx->brd_scale; - int i, j, out_size, p_lambda, b_lambda, lambda2; - int outbuf_size= s->width * s->height; //FIXME - uint8_t *outbuf= av_malloc(outbuf_size); - int64_t best_rd= INT64_MAX; - int best_b_count= -1; - - assert(scale>=0 && scale <=3); - -// emms_c(); - p_lambda= s->last_lambda_for[FF_P_TYPE]; //s->next_picture_ptr->quality; - b_lambda= s->last_lambda_for[FF_B_TYPE]; //p_lambda *FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset; - if(!b_lambda) b_lambda= p_lambda; //FIXME we should do this somewhere else - lambda2= (b_lambda*b_lambda + (1<> FF_LAMBDA_SHIFT; - - c->width = s->width >> scale; - c->height= s->height>> scale; - c->flags= CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR | CODEC_FLAG_INPUT_PRESERVED /*| CODEC_FLAG_EMU_EDGE*/; - c->flags|= s->avctx->flags & CODEC_FLAG_QPEL; - c->mb_decision= s->avctx->mb_decision; - c->me_cmp= s->avctx->me_cmp; - c->mb_cmp= s->avctx->mb_cmp; - c->me_sub_cmp= s->avctx->me_sub_cmp; - c->pix_fmt = PIX_FMT_YUV420P; - c->time_base= s->avctx->time_base; - c->max_b_frames= s->max_b_frames; - - if (avcodec_open(c, codec) < 0) - return -1; - - for(i=0; imax_b_frames+2; i++){ - int ysize= c->width*c->height; - int csize= (c->width/2)*(c->height/2); - Picture pre_input, *pre_input_ptr= i ? s->input_picture[i-1] : s->next_picture_ptr; - - avcodec_get_frame_defaults(&input[i]); - input[i].data[0]= av_malloc(ysize + 2*csize); - input[i].data[1]= input[i].data[0] + ysize; - input[i].data[2]= input[i].data[1] + csize; - input[i].linesize[0]= c->width; - input[i].linesize[1]= - input[i].linesize[2]= c->width/2; - - if(pre_input_ptr && (!i || s->input_picture[i-1])) { - pre_input= *pre_input_ptr; - - if(pre_input.type != FF_BUFFER_TYPE_SHARED && i) { - pre_input.data[0]+=INPLACE_OFFSET; - pre_input.data[1]+=INPLACE_OFFSET; - pre_input.data[2]+=INPLACE_OFFSET; - } - - s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], pre_input.data[0], pre_input.linesize[0], c->width, c->height); - s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], pre_input.data[1], pre_input.linesize[1], c->width>>1, c->height>>1); - s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], pre_input.data[2], pre_input.linesize[2], c->width>>1, c->height>>1); - } - } - - for(j=0; jmax_b_frames+1; j++){ - int64_t rd=0; - - if(!s->input_picture[j]) - break; - - c->error[0]= c->error[1]= c->error[2]= 0; - - input[0].pict_type= FF_I_TYPE; - input[0].quality= 1 * FF_QP2LAMBDA; - out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[0]); -// rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT; - - for(i=0; imax_b_frames+1; i++){ - int is_p= i % (j+1) == j || i==s->max_b_frames; - - input[i+1].pict_type= is_p ? FF_P_TYPE : FF_B_TYPE; - input[i+1].quality= is_p ? p_lambda : b_lambda; - out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[i+1]); - rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); - } - - /* get the delayed frames */ - while(out_size){ - out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); - rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); - } - - rd += c->error[0] + c->error[1] + c->error[2]; - - if(rd < best_rd){ - best_rd= rd; - best_b_count= j; - } - } - - av_freep(&outbuf); - avcodec_close(c); - av_freep(&c); - - for(i=0; imax_b_frames+2; i++){ - av_freep(&input[i].data[0]); - } - - return best_b_count; -} - -static int select_input_picture(MpegEncContext *s){ - int i; - - for(i=1; ireordered_input_picture[i-1]= s->reordered_input_picture[i]; - s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL; - - /* set next picture type & ordering */ - if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){ - if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture_ptr==NULL || s->intra_only){ - s->reordered_input_picture[0]= s->input_picture[0]; - s->reordered_input_picture[0]->pict_type= FF_I_TYPE; - s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++; - }else{ - int b_frames; - - if(s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor){ - if(s->picture_in_gop_number < s->gop_size && skip_check(s, s->input_picture[0], s->next_picture_ptr)){ - //FIXME check that te gop check above is +-1 correct -//av_log(NULL, AV_LOG_DEBUG, "skip %p %"PRId64"\n", s->input_picture[0]->data[0], s->input_picture[0]->pts); - - if(s->input_picture[0]->type == FF_BUFFER_TYPE_SHARED){ - for(i=0; i<4; i++) - s->input_picture[0]->data[i]= NULL; - s->input_picture[0]->type= 0; - }else{ - assert( s->input_picture[0]->type==FF_BUFFER_TYPE_USER - || s->input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); - - s->avctx->release_buffer(s->avctx, (AVFrame*)s->input_picture[0]); - } - - emms_c(); - ff_vbv_update(s, 0); - - goto no_output_pic; - } - } - - if(s->flags&CODEC_FLAG_PASS2){ - for(i=0; imax_b_frames+1; i++){ - int pict_num= s->input_picture[0]->display_picture_number + i; - - if(pict_num >= s->rc_context.num_entries) - break; - if(!s->input_picture[i]){ - s->rc_context.entry[pict_num-1].new_pict_type = FF_P_TYPE; - break; - } - - s->input_picture[i]->pict_type= - s->rc_context.entry[pict_num].new_pict_type; - } - } - - if(s->avctx->b_frame_strategy==0){ - b_frames= s->max_b_frames; - while(b_frames && !s->input_picture[b_frames]) b_frames--; - }else if(s->avctx->b_frame_strategy==1){ - for(i=1; imax_b_frames+1; i++){ - if(s->input_picture[i] && s->input_picture[i]->b_frame_score==0){ - s->input_picture[i]->b_frame_score= - get_intra_count(s, s->input_picture[i ]->data[0], - s->input_picture[i-1]->data[0], s->linesize) + 1; - } - } - for(i=0; imax_b_frames+1; i++){ - if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/s->avctx->b_sensitivity) break; - } - - b_frames= FFMAX(0, i-1); - - /* reset scores */ - for(i=0; iinput_picture[i]->b_frame_score=0; - } - }else if(s->avctx->b_frame_strategy==2){ - b_frames= estimate_best_b_count(s); - }else{ - av_log(s->avctx, AV_LOG_ERROR, "illegal b frame strategy\n"); - b_frames=0; - } - - emms_c(); -//static int b_count=0; -//b_count+= b_frames; -//av_log(s->avctx, AV_LOG_DEBUG, "b_frames: %d\n", b_count); - - for(i= b_frames - 1; i>=0; i--){ - int type= s->input_picture[i]->pict_type; - if(type && type != FF_B_TYPE) - b_frames= i; - } - if(s->input_picture[b_frames]->pict_type == FF_B_TYPE && b_frames == s->max_b_frames){ - av_log(s->avctx, AV_LOG_ERROR, "warning, too many b frames in a row\n"); - } - - if(s->picture_in_gop_number + b_frames >= s->gop_size){ - if((s->flags2 & CODEC_FLAG2_STRICT_GOP) && s->gop_size > s->picture_in_gop_number){ - b_frames= s->gop_size - s->picture_in_gop_number - 1; - }else{ - if(s->flags & CODEC_FLAG_CLOSED_GOP) - b_frames=0; - s->input_picture[b_frames]->pict_type= FF_I_TYPE; - } - } - - if( (s->flags & CODEC_FLAG_CLOSED_GOP) - && b_frames - && s->input_picture[b_frames]->pict_type== FF_I_TYPE) - b_frames--; - - s->reordered_input_picture[0]= s->input_picture[b_frames]; - if(s->reordered_input_picture[0]->pict_type != FF_I_TYPE) - s->reordered_input_picture[0]->pict_type= FF_P_TYPE; - s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++; - for(i=0; ireordered_input_picture[i+1]= s->input_picture[i]; - s->reordered_input_picture[i+1]->pict_type= FF_B_TYPE; - s->reordered_input_picture[i+1]->coded_picture_number= s->coded_picture_number++; - } - } - } -no_output_pic: - if(s->reordered_input_picture[0]){ - s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=FF_B_TYPE ? 3 : 0; - - ff_copy_picture(&s->new_picture, s->reordered_input_picture[0]); - - if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_SHARED || s->avctx->rc_buffer_size){ - // input is a shared pix, so we can't modifiy it -> alloc a new one & ensure that the shared one is reuseable - - int i= ff_find_unused_picture(s, 0); - Picture *pic= &s->picture[i]; - - pic->reference = s->reordered_input_picture[0]->reference; - if(ff_alloc_picture(s, pic, 0) < 0){ - return -1; - } - - /* mark us unused / free shared pic */ - if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_INTERNAL) - s->avctx->release_buffer(s->avctx, (AVFrame*)s->reordered_input_picture[0]); - for(i=0; i<4; i++) - s->reordered_input_picture[0]->data[i]= NULL; - s->reordered_input_picture[0]->type= 0; - - copy_picture_attributes(s, (AVFrame*)pic, (AVFrame*)s->reordered_input_picture[0]); - - s->current_picture_ptr= pic; - }else{ - // input is not a shared pix -> reuse buffer for current_pix - - assert( s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_USER - || s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); - - s->current_picture_ptr= s->reordered_input_picture[0]; - for(i=0; i<4; i++){ - s->new_picture.data[i]+= INPLACE_OFFSET; - } - } - ff_copy_picture(&s->current_picture, s->current_picture_ptr); - - s->picture_number= s->new_picture.display_picture_number; -//printf("dpn:%d\n", s->picture_number); - }else{ - memset(&s->new_picture, 0, sizeof(Picture)); - } - return 0; -} - -int MPV_encode_picture(AVCodecContext *avctx, - unsigned char *buf, int buf_size, void *data) -{ - MpegEncContext *s = avctx->priv_data; - AVFrame *pic_arg = data; - int i, stuffing_count; - - for(i=0; ithread_count; i++){ - int start_y= s->thread_context[i]->start_mb_y; - int end_y= s->thread_context[i]-> end_mb_y; - int h= s->mb_height; - uint8_t *start= buf + (size_t)(((int64_t) buf_size)*start_y/h); - uint8_t *end = buf + (size_t)(((int64_t) buf_size)* end_y/h); - - init_put_bits(&s->thread_context[i]->pb, start, end - start); - } - - s->picture_in_gop_number++; - - if(load_input_picture(s, pic_arg) < 0) - return -1; - - if(select_input_picture(s) < 0){ - return -1; - } - - /* output? */ - if(s->new_picture.data[0]){ - s->pict_type= s->new_picture.pict_type; -//emms_c(); -//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale); - MPV_frame_start(s, avctx); -vbv_retry: - if (encode_picture(s, s->picture_number) < 0) - return -1; - - avctx->header_bits = s->header_bits; - avctx->mv_bits = s->mv_bits; - avctx->misc_bits = s->misc_bits; - avctx->i_tex_bits = s->i_tex_bits; - avctx->p_tex_bits = s->p_tex_bits; - avctx->i_count = s->i_count; - avctx->p_count = s->mb_num - s->i_count - s->skip_count; //FIXME f/b_count in avctx - avctx->skip_count = s->skip_count; - - MPV_frame_end(s); - - if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG) - ff_mjpeg_encode_picture_trailer(s); - - if(avctx->rc_buffer_size){ - RateControlContext *rcc= &s->rc_context; - int max_size= rcc->buffer_index * avctx->rc_max_available_vbv_use; - - if(put_bits_count(&s->pb) > max_size && s->lambda < s->avctx->lmax){ - s->next_lambda= FFMAX(s->lambda+1, s->lambda*(s->qscale+1) / s->qscale); - if(s->adaptive_quant){ - int i; - for(i=0; imb_height*s->mb_stride; i++) - s->lambda_table[i]= FFMAX(s->lambda_table[i]+1, s->lambda_table[i]*(s->qscale+1) / s->qscale); - } - s->mb_skipped = 0; //done in MPV_frame_start() - if(s->pict_type==FF_P_TYPE){ //done in encode_picture() so we must undo it - if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4) - s->no_rounding ^= 1; - } - if(s->pict_type!=FF_B_TYPE){ - s->time_base= s->last_time_base; - s->last_non_b_time= s->time - s->pp_time; - } -// av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda); - for(i=0; ithread_count; i++){ - PutBitContext *pb= &s->thread_context[i]->pb; - init_put_bits(pb, pb->buf, pb->buf_end - pb->buf); - } - goto vbv_retry; - } - - assert(s->avctx->rc_max_rate); - } - - if(s->flags&CODEC_FLAG_PASS1) - ff_write_pass1_stats(s); - - for(i=0; i<4; i++){ - s->current_picture_ptr->error[i]= s->current_picture.error[i]; - avctx->error[i] += s->current_picture_ptr->error[i]; - } - - if(s->flags&CODEC_FLAG_PASS1) - assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits + avctx->i_tex_bits + avctx->p_tex_bits == put_bits_count(&s->pb)); - flush_put_bits(&s->pb); - s->frame_bits = put_bits_count(&s->pb); - - stuffing_count= ff_vbv_update(s, s->frame_bits); - if(stuffing_count){ - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < stuffing_count + 50){ - av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n"); - return -1; - } - - switch(s->codec_id){ - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - while(stuffing_count--){ - put_bits(&s->pb, 8, 0); - } - break; - case CODEC_ID_MPEG4: - put_bits(&s->pb, 16, 0); - put_bits(&s->pb, 16, 0x1C3); - stuffing_count -= 4; - while(stuffing_count--){ - put_bits(&s->pb, 8, 0xFF); - } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n"); - } - flush_put_bits(&s->pb); - s->frame_bits = put_bits_count(&s->pb); - } - - /* update mpeg1/2 vbv_delay for CBR */ - if(s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate && s->out_format == FMT_MPEG1 - && 90000LL * (avctx->rc_buffer_size-1) <= s->avctx->rc_max_rate*0xFFFFLL){ - int vbv_delay, min_delay; - double inbits = s->avctx->rc_max_rate*av_q2d(s->avctx->time_base); - int minbits= s->frame_bits - 8*(s->vbv_delay_ptr - s->pb.buf - 1); - double bits = s->rc_context.buffer_index + minbits - inbits; - - if(bits<0) - av_log(s->avctx, AV_LOG_ERROR, "Internal error, negative bits\n"); - - assert(s->repeat_first_field==0); - - vbv_delay= bits * 90000 / s->avctx->rc_max_rate; - min_delay= (minbits * 90000LL + s->avctx->rc_max_rate - 1)/ s->avctx->rc_max_rate; - - vbv_delay= FFMAX(vbv_delay, min_delay); - - assert(vbv_delay < 0xFFFF); - - s->vbv_delay_ptr[0] &= 0xF8; - s->vbv_delay_ptr[0] |= vbv_delay>>13; - s->vbv_delay_ptr[1] = vbv_delay>>5; - s->vbv_delay_ptr[2] &= 0x07; - s->vbv_delay_ptr[2] |= vbv_delay<<3; - } - s->total_bits += s->frame_bits; - avctx->frame_bits = s->frame_bits; - }else{ - assert((put_bits_ptr(&s->pb) == s->pb.buf)); - s->frame_bits=0; - } - assert((s->frame_bits&7)==0); - - return s->frame_bits/8; -} - -static inline void dct_single_coeff_elimination(MpegEncContext *s, int n, int threshold) -{ - static const char tab[64]= - {3,2,2,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}; - int score=0; - int run=0; - int i; - DCTELEM *block= s->block[n]; - const int last_index= s->block_last_index[n]; - int skip_dc; - - if(threshold<0){ - skip_dc=0; - threshold= -threshold; - }else - skip_dc=1; - - /* Are all we could set to zero already zero? */ - if(last_index<=skip_dc - 1) return; - - for(i=0; i<=last_index; i++){ - const int j = s->intra_scantable.permutated[i]; - const int level = FFABS(block[j]); - if(level==1){ - if(skip_dc && i==0) continue; - score+= tab[run]; - run=0; - }else if(level>1){ - return; - }else{ - run++; - } - } - if(score >= threshold) return; - for(i=skip_dc; i<=last_index; i++){ - const int j = s->intra_scantable.permutated[i]; - block[j]=0; - } - if(block[0]) s->block_last_index[n]= 0; - else s->block_last_index[n]= -1; -} - -static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index) -{ - int i; - const int maxlevel= s->max_qcoeff; - const int minlevel= s->min_qcoeff; - int overflow=0; - - if(s->mb_intra){ - i=1; //skip clipping of intra dc - }else - i=0; - - for(;i<=last_index; i++){ - const int j= s->intra_scantable.permutated[i]; - int level = block[j]; - - if (level>maxlevel){ - level=maxlevel; - overflow++; - }else if(levelavctx->mb_decision == FF_MB_DECISION_SIMPLE) - av_log(s->avctx, AV_LOG_INFO, "warning, clipping %d dct coefficients to %d..%d\n", overflow, minlevel, maxlevel); -} - -static void get_visual_weight(int16_t *weight, uint8_t *ptr, int stride){ - int x, y; -//FIXME optimize - for(y=0; y<8; y++){ - for(x=0; x<8; x++){ - int x2, y2; - int sum=0; - int sqr=0; - int count=0; - - for(y2= FFMAX(y-1, 0); y2 < FFMIN(8, y+2); y2++){ - for(x2= FFMAX(x-1, 0); x2 < FFMIN(8, x+2); x2++){ - int v= ptr[x2 + y2*stride]; - sum += v; - sqr += v*v; - count++; - } - } - weight[x + 8*y]= (36*ff_sqrt(count*sqr - sum*sum)) / count; - } - } -} - -static av_always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, int motion_y, int mb_block_height, int mb_block_count) -{ - int16_t weight[8][64]; - DCTELEM orig[8][64]; - const int mb_x= s->mb_x; - const int mb_y= s->mb_y; - int i; - int skip_dct[8]; - int dct_offset = s->linesize*8; //default for progressive frames - uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int wrap_y, wrap_c; - - for(i=0; iskipdct; - - if(s->adaptive_quant){ - const int last_qp= s->qscale; - const int mb_xy= mb_x + mb_y*s->mb_stride; - - s->lambda= s->lambda_table[mb_xy]; - update_qscale(s); - - if(!(s->flags&CODEC_FLAG_QP_RD)){ - s->qscale= s->current_picture_ptr->qscale_table[mb_xy]; - s->dquant= s->qscale - last_qp; - - if(s->out_format==FMT_H263){ - s->dquant= av_clip(s->dquant, -2, 2); - - if(s->codec_id==CODEC_ID_MPEG4){ - if(!s->mb_intra){ - if(s->pict_type == FF_B_TYPE){ - if(s->dquant&1 || s->mv_dir&MV_DIRECT) - s->dquant= 0; - } - if(s->mv_type==MV_TYPE_8X8) - s->dquant=0; - } - } - } - } - ff_set_qscale(s, last_qp + s->dquant); - }else if(s->flags&CODEC_FLAG_QP_RD) - ff_set_qscale(s, s->qscale + s->dquant); - - wrap_y = s->linesize; - wrap_c = s->uvlinesize; - ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16; - ptr_cb = s->new_picture.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; - ptr_cr = s->new_picture.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; - - if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ - uint8_t *ebuf= s->edge_emu_buffer + 32; - ff_emulated_edge_mc(ebuf , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width , s->height); - ptr_y= ebuf; - ff_emulated_edge_mc(ebuf+18*wrap_y , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); - ptr_cb= ebuf+18*wrap_y; - ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); - ptr_cr= ebuf+18*wrap_y+8; - } - - if (s->mb_intra) { - if(s->flags&CODEC_FLAG_INTERLACED_DCT){ - int progressive_score, interlaced_score; - - s->interlaced_dct=0; - progressive_score= s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y, 8) - +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y*8, NULL, wrap_y, 8) - 400; - - if(progressive_score > 0){ - interlaced_score = s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y*2, 8) - +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y , NULL, wrap_y*2, 8); - if(progressive_score > interlaced_score){ - s->interlaced_dct=1; - - dct_offset= wrap_y; - wrap_y<<=1; - if (s->chroma_format == CHROMA_422) - wrap_c<<=1; - } - } - } - - s->dsp.get_pixels(s->block[0], ptr_y , wrap_y); - s->dsp.get_pixels(s->block[1], ptr_y + 8, wrap_y); - s->dsp.get_pixels(s->block[2], ptr_y + dct_offset , wrap_y); - s->dsp.get_pixels(s->block[3], ptr_y + dct_offset + 8, wrap_y); - - if(s->flags&CODEC_FLAG_GRAY){ - skip_dct[4]= 1; - skip_dct[5]= 1; - }else{ - s->dsp.get_pixels(s->block[4], ptr_cb, wrap_c); - s->dsp.get_pixels(s->block[5], ptr_cr, wrap_c); - if(!s->chroma_y_shift){ /* 422 */ - s->dsp.get_pixels(s->block[6], ptr_cb + (dct_offset>>1), wrap_c); - s->dsp.get_pixels(s->block[7], ptr_cr + (dct_offset>>1), wrap_c); - } - } - }else{ - op_pixels_func (*op_pix)[4]; - qpel_mc_func (*op_qpix)[16]; - uint8_t *dest_y, *dest_cb, *dest_cr; - - dest_y = s->dest[0]; - dest_cb = s->dest[1]; - dest_cr = s->dest[2]; - - if ((!s->no_rounding) || s->pict_type==FF_B_TYPE){ - op_pix = s->dsp.put_pixels_tab; - op_qpix= s->dsp.put_qpel_pixels_tab; - }else{ - op_pix = s->dsp.put_no_rnd_pixels_tab; - op_qpix= s->dsp.put_no_rnd_qpel_pixels_tab; - } - - if (s->mv_dir & MV_DIR_FORWARD) { - MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix); - op_pix = s->dsp.avg_pixels_tab; - op_qpix= s->dsp.avg_qpel_pixels_tab; - } - if (s->mv_dir & MV_DIR_BACKWARD) { - MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix); - } - - if(s->flags&CODEC_FLAG_INTERLACED_DCT){ - int progressive_score, interlaced_score; - - s->interlaced_dct=0; - progressive_score= s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y, 8) - +s->dsp.ildct_cmp[0](s, dest_y + wrap_y*8, ptr_y + wrap_y*8, wrap_y, 8) - 400; - - if(s->avctx->ildct_cmp == FF_CMP_VSSE) progressive_score -= 400; - - if(progressive_score>0){ - interlaced_score = s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y*2, 8) - +s->dsp.ildct_cmp[0](s, dest_y + wrap_y , ptr_y + wrap_y , wrap_y*2, 8); - - if(progressive_score > interlaced_score){ - s->interlaced_dct=1; - - dct_offset= wrap_y; - wrap_y<<=1; - if (s->chroma_format == CHROMA_422) - wrap_c<<=1; - } - } - } - - s->dsp.diff_pixels(s->block[0], ptr_y , dest_y , wrap_y); - s->dsp.diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y); - s->dsp.diff_pixels(s->block[2], ptr_y + dct_offset , dest_y + dct_offset , wrap_y); - s->dsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8, dest_y + dct_offset + 8, wrap_y); - - if(s->flags&CODEC_FLAG_GRAY){ - skip_dct[4]= 1; - skip_dct[5]= 1; - }else{ - s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c); - s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c); - if(!s->chroma_y_shift){ /* 422 */ - s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset>>1), dest_cb + (dct_offset>>1), wrap_c); - s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset>>1), dest_cr + (dct_offset>>1), wrap_c); - } - } - /* pre quantization */ - if(s->current_picture.mc_mb_var[s->mb_stride*mb_y+ mb_x]<2*s->qscale*s->qscale){ - //FIXME optimize - if(s->dsp.sad[1](NULL, ptr_y , dest_y , wrap_y, 8) < 20*s->qscale) skip_dct[0]= 1; - if(s->dsp.sad[1](NULL, ptr_y + 8, dest_y + 8, wrap_y, 8) < 20*s->qscale) skip_dct[1]= 1; - if(s->dsp.sad[1](NULL, ptr_y +dct_offset , dest_y +dct_offset , wrap_y, 8) < 20*s->qscale) skip_dct[2]= 1; - if(s->dsp.sad[1](NULL, ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y, 8) < 20*s->qscale) skip_dct[3]= 1; - if(s->dsp.sad[1](NULL, ptr_cb , dest_cb , wrap_c, 8) < 20*s->qscale) skip_dct[4]= 1; - if(s->dsp.sad[1](NULL, ptr_cr , dest_cr , wrap_c, 8) < 20*s->qscale) skip_dct[5]= 1; - if(!s->chroma_y_shift){ /* 422 */ - if(s->dsp.sad[1](NULL, ptr_cb +(dct_offset>>1), dest_cb +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[6]= 1; - if(s->dsp.sad[1](NULL, ptr_cr +(dct_offset>>1), dest_cr +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[7]= 1; - } - } - } - - if(s->avctx->quantizer_noise_shaping){ - if(!skip_dct[0]) get_visual_weight(weight[0], ptr_y , wrap_y); - if(!skip_dct[1]) get_visual_weight(weight[1], ptr_y + 8, wrap_y); - if(!skip_dct[2]) get_visual_weight(weight[2], ptr_y + dct_offset , wrap_y); - if(!skip_dct[3]) get_visual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y); - if(!skip_dct[4]) get_visual_weight(weight[4], ptr_cb , wrap_c); - if(!skip_dct[5]) get_visual_weight(weight[5], ptr_cr , wrap_c); - if(!s->chroma_y_shift){ /* 422 */ - if(!skip_dct[6]) get_visual_weight(weight[6], ptr_cb + (dct_offset>>1), wrap_c); - if(!skip_dct[7]) get_visual_weight(weight[7], ptr_cr + (dct_offset>>1), wrap_c); - } - memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*mb_block_count); - } - - /* DCT & quantize */ - assert(s->out_format!=FMT_MJPEG || s->qscale==8); - { - for(i=0;iblock_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow); - // FIXME we could decide to change to quantizer instead of clipping - // JS: I don't think that would be a good idea it could lower quality instead - // of improve it. Just INTRADC clipping deserves changes in quantizer - if (overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]); - }else - s->block_last_index[i]= -1; - } - if(s->avctx->quantizer_noise_shaping){ - for(i=0;iblock_last_index[i] = dct_quantize_refine(s, s->block[i], weight[i], orig[i], i, s->qscale); - } - } - } - - if(s->luma_elim_threshold && !s->mb_intra) - for(i=0; i<4; i++) - dct_single_coeff_elimination(s, i, s->luma_elim_threshold); - if(s->chroma_elim_threshold && !s->mb_intra) - for(i=4; ichroma_elim_threshold); - - if(s->flags & CODEC_FLAG_CBP_RD){ - for(i=0;iblock_last_index[i] == -1) - s->coded_score[i]= INT_MAX/256; - } - } - } - - if((s->flags&CODEC_FLAG_GRAY) && s->mb_intra){ - s->block_last_index[4]= - s->block_last_index[5]= 0; - s->block[4][0]= - s->block[5][0]= (1024 + s->c_dc_scale/2)/ s->c_dc_scale; - } - - //non c quantize code returns incorrect block_last_index FIXME - if(s->alternate_scan && s->dct_quantize != dct_quantize_c){ - for(i=0; iblock_last_index[i]>0){ - for(j=63; j>0; j--){ - if(s->block[i][ s->intra_scantable.permutated[j] ]) break; - } - s->block_last_index[i]= j; - } - } - } - - /* huffman encode */ - switch(s->codec_id){ //FIXME funct ptr could be slightly faster - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) - mpeg1_encode_mb(s, s->block, motion_x, motion_y); - break; - case CODEC_ID_MPEG4: - if (CONFIG_MPEG4_ENCODER) - mpeg4_encode_mb(s, s->block, motion_x, motion_y); - break; - case CODEC_ID_MSMPEG4V2: - case CODEC_ID_MSMPEG4V3: - case CODEC_ID_WMV1: - if (CONFIG_MSMPEG4_ENCODER) - msmpeg4_encode_mb(s, s->block, motion_x, motion_y); - break; - case CODEC_ID_WMV2: - if (CONFIG_WMV2_ENCODER) - ff_wmv2_encode_mb(s, s->block, motion_x, motion_y); - break; - case CODEC_ID_H261: - if (CONFIG_H261_ENCODER) - ff_h261_encode_mb(s, s->block, motion_x, motion_y); - break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_FLV1: - case CODEC_ID_RV10: - case CODEC_ID_RV20: - if (CONFIG_H263_ENCODER) - h263_encode_mb(s, s->block, motion_x, motion_y); - break; - case CODEC_ID_MJPEG: - if (CONFIG_MJPEG_ENCODER) - ff_mjpeg_encode_mb(s, s->block); - break; - default: - assert(0); - } -} - -static av_always_inline void encode_mb(MpegEncContext *s, int motion_x, int motion_y) -{ - if (s->chroma_format == CHROMA_420) encode_mb_internal(s, motion_x, motion_y, 8, 6); - else encode_mb_internal(s, motion_x, motion_y, 16, 8); -} - -static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){ - int i; - - memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? - - /* mpeg1 */ - d->mb_skip_run= s->mb_skip_run; - for(i=0; i<3; i++) - d->last_dc[i]= s->last_dc[i]; - - /* statistics */ - d->mv_bits= s->mv_bits; - d->i_tex_bits= s->i_tex_bits; - d->p_tex_bits= s->p_tex_bits; - d->i_count= s->i_count; - d->f_count= s->f_count; - d->b_count= s->b_count; - d->skip_count= s->skip_count; - d->misc_bits= s->misc_bits; - d->last_bits= 0; - - d->mb_skipped= 0; - d->qscale= s->qscale; - d->dquant= s->dquant; - - d->esc3_level_length= s->esc3_level_length; -} - -static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){ - int i; - - memcpy(d->mv, s->mv, 2*4*2*sizeof(int)); - memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? - - /* mpeg1 */ - d->mb_skip_run= s->mb_skip_run; - for(i=0; i<3; i++) - d->last_dc[i]= s->last_dc[i]; - - /* statistics */ - d->mv_bits= s->mv_bits; - d->i_tex_bits= s->i_tex_bits; - d->p_tex_bits= s->p_tex_bits; - d->i_count= s->i_count; - d->f_count= s->f_count; - d->b_count= s->b_count; - d->skip_count= s->skip_count; - d->misc_bits= s->misc_bits; - - d->mb_intra= s->mb_intra; - d->mb_skipped= s->mb_skipped; - d->mv_type= s->mv_type; - d->mv_dir= s->mv_dir; - d->pb= s->pb; - if(s->data_partitioning){ - d->pb2= s->pb2; - d->tex_pb= s->tex_pb; - } - d->block= s->block; - for(i=0; i<8; i++) - d->block_last_index[i]= s->block_last_index[i]; - d->interlaced_dct= s->interlaced_dct; - d->qscale= s->qscale; - - d->esc3_level_length= s->esc3_level_length; -} - -static inline void encode_mb_hq(MpegEncContext *s, MpegEncContext *backup, MpegEncContext *best, int type, - PutBitContext pb[2], PutBitContext pb2[2], PutBitContext tex_pb[2], - int *dmin, int *next_block, int motion_x, int motion_y) -{ - int score; - uint8_t *dest_backup[3]; - - copy_context_before_encode(s, backup, type); - - s->block= s->blocks[*next_block]; - s->pb= pb[*next_block]; - if(s->data_partitioning){ - s->pb2 = pb2 [*next_block]; - s->tex_pb= tex_pb[*next_block]; - } - - if(*next_block){ - memcpy(dest_backup, s->dest, sizeof(s->dest)); - s->dest[0] = s->rd_scratchpad; - s->dest[1] = s->rd_scratchpad + 16*s->linesize; - s->dest[2] = s->rd_scratchpad + 16*s->linesize + 8; - assert(s->linesize >= 32); //FIXME - } - - encode_mb(s, motion_x, motion_y); - - score= put_bits_count(&s->pb); - if(s->data_partitioning){ - score+= put_bits_count(&s->pb2); - score+= put_bits_count(&s->tex_pb); - } - - if(s->avctx->mb_decision == FF_MB_DECISION_RD){ - MPV_decode_mb(s, s->block); - - score *= s->lambda2; - score += sse_mb(s) << FF_LAMBDA_SHIFT; - } - - if(*next_block){ - memcpy(s->dest, dest_backup, sizeof(s->dest)); - } - - if(score<*dmin){ - *dmin= score; - *next_block^=1; - - copy_context_after_encode(best, s, type); - } -} - -static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride){ - uint32_t *sq = ff_squareTbl + 256; - int acc=0; - int x,y; - - if(w==16 && h==16) - return s->dsp.sse[0](NULL, src1, src2, stride, 16); - else if(w==8 && h==8) - return s->dsp.sse[1](NULL, src1, src2, stride, 8); - - for(y=0; y=0); - - return acc; -} - -static int sse_mb(MpegEncContext *s){ - int w= 16; - int h= 16; - - if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16; - if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16; - - if(w==16 && h==16) - if(s->avctx->mb_cmp == FF_CMP_NSSE){ - return s->dsp.nsse[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16) - +s->dsp.nsse[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8) - +s->dsp.nsse[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8); - }else{ - return s->dsp.sse[0](NULL, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16) - +s->dsp.sse[1](NULL, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8) - +s->dsp.sse[1](NULL, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8); - } - else - return sse(s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], w, h, s->linesize) - +sse(s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], w>>1, h>>1, s->uvlinesize) - +sse(s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], w>>1, h>>1, s->uvlinesize); -} - -static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= *(void**)arg; - - - s->me.pre_pass=1; - s->me.dia_size= s->avctx->pre_dia_size; - s->first_slice_line=1; - for(s->mb_y= s->end_mb_y-1; s->mb_y >= s->start_mb_y; s->mb_y--) { - for(s->mb_x=s->mb_width-1; s->mb_x >=0 ;s->mb_x--) { - ff_pre_estimate_p_frame_motion(s, s->mb_x, s->mb_y); - } - s->first_slice_line=0; - } - - s->me.pre_pass=0; - - return 0; -} - -static int estimate_motion_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= *(void**)arg; - - ff_check_alignment(); - - s->me.dia_size= s->avctx->dia_size; - s->first_slice_line=1; - for(s->mb_y= s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { - s->mb_x=0; //for block init below - ff_init_block_index(s); - for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { - s->block_index[0]+=2; - s->block_index[1]+=2; - s->block_index[2]+=2; - s->block_index[3]+=2; - - /* compute motion vector & mb_type and store in context */ - if(s->pict_type==FF_B_TYPE) - ff_estimate_b_frame_motion(s, s->mb_x, s->mb_y); - else - ff_estimate_p_frame_motion(s, s->mb_x, s->mb_y); - } - s->first_slice_line=0; - } - return 0; -} - -static int mb_var_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= *(void**)arg; - int mb_x, mb_y; - - ff_check_alignment(); - - for(mb_y=s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { - for(mb_x=0; mb_x < s->mb_width; mb_x++) { - int xx = mb_x * 16; - int yy = mb_y * 16; - uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx; - int varc; - int sum = s->dsp.pix_sum(pix, s->linesize); - - varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; - - s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc; - s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; - s->me.mb_var_sum_temp += varc; - } - } - return 0; -} - -static void write_slice_end(MpegEncContext *s){ - if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4){ - if(s->partitioned_frame){ - ff_mpeg4_merge_partitions(s); - } - - ff_mpeg4_stuffing(&s->pb); - }else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){ - ff_mjpeg_encode_stuffing(&s->pb); - } - - align_put_bits(&s->pb); - flush_put_bits(&s->pb); - - if((s->flags&CODEC_FLAG_PASS1) && !s->partitioned_frame) - s->misc_bits+= get_bits_diff(s); -} - -static int encode_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= *(void**)arg; - int mb_x, mb_y, pdif = 0; - int chr_h= 16>>s->chroma_y_shift; - int i, j; - MpegEncContext best_s, backup_s; - uint8_t bit_buf[2][MAX_MB_BYTES]; - uint8_t bit_buf2[2][MAX_MB_BYTES]; - uint8_t bit_buf_tex[2][MAX_MB_BYTES]; - PutBitContext pb[2], pb2[2], tex_pb[2]; -//printf("%d->%d\n", s->resync_mb_y, s->end_mb_y); - - ff_check_alignment(); - - for(i=0; i<2; i++){ - init_put_bits(&pb [i], bit_buf [i], MAX_MB_BYTES); - init_put_bits(&pb2 [i], bit_buf2 [i], MAX_MB_BYTES); - init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES); - } - - s->last_bits= put_bits_count(&s->pb); - s->mv_bits=0; - s->misc_bits=0; - s->i_tex_bits=0; - s->p_tex_bits=0; - s->i_count=0; - s->f_count=0; - s->b_count=0; - s->skip_count=0; - - for(i=0; i<3; i++){ - /* init last dc values */ - /* note: quant matrix value (8) is implied here */ - s->last_dc[i] = 128 << s->intra_dc_precision; - - s->current_picture.error[i] = 0; - } - s->mb_skip_run = 0; - memset(s->last_mv, 0, sizeof(s->last_mv)); - - s->last_mv_dir = 0; - - switch(s->codec_id){ - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_FLV1: - if (CONFIG_H263_ENCODER) - s->gob_index = ff_h263_get_gob_height(s); - break; - case CODEC_ID_MPEG4: - if(CONFIG_MPEG4_ENCODER && s->partitioned_frame) - ff_mpeg4_init_partitions(s); - break; - } - - s->resync_mb_x=0; - s->resync_mb_y=0; - s->first_slice_line = 1; - s->ptr_lastgob = s->pb.buf; - for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { -// printf("row %d at %X\n", s->mb_y, (int)s); - s->mb_x=0; - s->mb_y= mb_y; - - ff_set_qscale(s, s->qscale); - ff_init_block_index(s); - - for(mb_x=0; mb_x < s->mb_width; mb_x++) { - int xy= mb_y*s->mb_stride + mb_x; // removed const, H261 needs to adjust this - int mb_type= s->mb_type[xy]; -// int d; - int dmin= INT_MAX; - int dir; - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - if(s->data_partitioning){ - if( s->pb2 .buf_end - s->pb2 .buf - (put_bits_count(&s-> pb2)>>3) < MAX_MB_BYTES - || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - } - - s->mb_x = mb_x; - s->mb_y = mb_y; // moved into loop, can get changed by H.261 - ff_update_block_index(s); - - if(CONFIG_H261_ENCODER && s->codec_id == CODEC_ID_H261){ - ff_h261_reorder_mb_index(s); - xy= s->mb_y*s->mb_stride + s->mb_x; - mb_type= s->mb_type[xy]; - } - - /* write gob / video packet header */ - if(s->rtp_mode){ - int current_packet_size, is_gob_start; - - current_packet_size= ((put_bits_count(&s->pb)+7)>>3) - (s->ptr_lastgob - s->pb.buf); - - is_gob_start= s->avctx->rtp_payload_size && current_packet_size >= s->avctx->rtp_payload_size && mb_y + mb_x>0; - - if(s->start_mb_y == mb_y && mb_y > 0 && mb_x==0) is_gob_start=1; - - switch(s->codec_id){ - case CODEC_ID_H263: - case CODEC_ID_H263P: - if(!s->h263_slice_structured) - if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0; - break; - case CODEC_ID_MPEG2VIDEO: - if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1; - case CODEC_ID_MPEG1VIDEO: - if(s->mb_skip_run) is_gob_start=0; - break; - } - - if(is_gob_start){ - if(s->start_mb_y != mb_y || mb_x!=0){ - write_slice_end(s); - - if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){ - ff_mpeg4_init_partitions(s); - } - } - - assert((put_bits_count(&s->pb)&7) == 0); - current_packet_size= put_bits_ptr(&s->pb) - s->ptr_lastgob; - - if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){ - int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y; - int d= 100 / s->avctx->error_rate; - if(r % d == 0){ - current_packet_size=0; -#ifndef ALT_BITSTREAM_WRITER - s->pb.buf_ptr= s->ptr_lastgob; -#endif - assert(put_bits_ptr(&s->pb) == s->ptr_lastgob); - } - } - - if (s->avctx->rtp_callback){ - int number_mb = (mb_y - s->resync_mb_y)*s->mb_width + mb_x - s->resync_mb_x; - s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, number_mb); - } - - switch(s->codec_id){ - case CODEC_ID_MPEG4: - if (CONFIG_MPEG4_ENCODER) { - ff_mpeg4_encode_video_packet_header(s); - ff_mpeg4_clean_buffers(s); - } - break; - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) { - ff_mpeg1_encode_slice_header(s); - ff_mpeg1_clean_buffers(s); - } - break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - if (CONFIG_H263_ENCODER) - h263_encode_gob_header(s, mb_y); - break; - } - - if(s->flags&CODEC_FLAG_PASS1){ - int bits= put_bits_count(&s->pb); - s->misc_bits+= bits - s->last_bits; - s->last_bits= bits; - } - - s->ptr_lastgob += current_packet_size; - s->first_slice_line=1; - s->resync_mb_x=mb_x; - s->resync_mb_y=mb_y; - } - } - - if( (s->resync_mb_x == s->mb_x) - && s->resync_mb_y+1 == s->mb_y){ - s->first_slice_line=0; - } - - s->mb_skipped=0; - s->dquant=0; //only for QP_RD - - if(mb_type & (mb_type-1) || (s->flags & CODEC_FLAG_QP_RD)){ // more than 1 MB type possible or CODEC_FLAG_QP_RD - int next_block=0; - int pb_bits_count, pb2_bits_count, tex_pb_bits_count; - - copy_context_before_encode(&backup_s, s, -1); - backup_s.pb= s->pb; - best_s.data_partitioning= s->data_partitioning; - best_s.partitioned_frame= s->partitioned_frame; - if(s->data_partitioning){ - backup_s.pb2= s->pb2; - backup_s.tex_pb= s->tex_pb; - } - - if(mb_type&CANDIDATE_MB_TYPE_INTER){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = s->p_mv_table[xy][0]; - s->mv[0][0][1] = s->p_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_INTER_I){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->p_field_select_table[i][xy]; - s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0]; - s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_SKIPPED){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_SKIPPED, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_INTER4V){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_8X8; - s->mb_intra= 0; - 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]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_FORWARD){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; - s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_BACKWARD){ - s->mv_dir = MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[1][0][0] = s->b_back_mv_table[xy][0]; - s->mv[1][0][1] = s->b_back_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[1][0][0], s->mv[1][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_BIDIR){ - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0]; - s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; - s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; - s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_FORWARD_I){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->b_field_select_table[0][i][xy]; - s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0]; - s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_BACKWARD_I){ - s->mv_dir = MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[1][i] = s->b_field_select_table[1][i][xy]; - s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0]; - s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_BIDIR_I){ - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(dir=0; dir<2; dir++){ - for(i=0; i<2; i++){ - j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy]; - s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0]; - s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1]; - } - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_INTRA){ - s->mv_dir = 0; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 1; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTRA, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - if(s->h263_pred || s->h263_aic){ - if(best_s.mb_intra) - s->mbintra_table[mb_x + mb_y*s->mb_stride]=1; - else - ff_clean_intra_table_entries(s); //old mode? - } - } - - if((s->flags & CODEC_FLAG_QP_RD) && dmin < INT_MAX){ - if(best_s.mv_type==MV_TYPE_16X16){ //FIXME move 4mv after QPRD - const int last_qp= backup_s.qscale; - int qpi, qp, dc[6]; - DCTELEM ac[6][16]; - const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0; - static const int dquant_tab[4]={-1,1,-2,2}; - - assert(backup_s.dquant == 0); - - //FIXME intra - s->mv_dir= best_s.mv_dir; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= best_s.mb_intra; - s->mv[0][0][0] = best_s.mv[0][0][0]; - s->mv[0][0][1] = best_s.mv[0][0][1]; - s->mv[1][0][0] = best_s.mv[1][0][0]; - s->mv[1][0][1] = best_s.mv[1][0][1]; - - qpi = s->pict_type == FF_B_TYPE ? 2 : 0; - for(; qpi<4; qpi++){ - int dquant= dquant_tab[qpi]; - qp= last_qp + dquant; - if(qp < s->avctx->qmin || qp > s->avctx->qmax) - continue; - backup_s.dquant= dquant; - if(s->mb_intra && s->dc_val[0]){ - for(i=0; i<6; i++){ - dc[i]= s->dc_val[0][ s->block_index[i] ]; - memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16); - } - } - - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]); - if(best_s.qscale != qp){ - if(s->mb_intra && s->dc_val[0]){ - for(i=0; i<6; i++){ - s->dc_val[0][ s->block_index[i] ]= dc[i]; - memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16); - } - } - } - } - } - } - if(CONFIG_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT){ - int mx= s->b_direct_mv_table[xy][0]; - int my= s->b_direct_mv_table[xy][1]; - - backup_s.dquant = 0; - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - s->mb_intra= 0; - ff_mpeg4_set_direct_mv(s, mx, my); - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb, - &dmin, &next_block, mx, my); - } - if(CONFIG_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT0){ - backup_s.dquant = 0; - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - s->mb_intra= 0; - ff_mpeg4_set_direct_mv(s, 0, 0); - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(!best_s.mb_intra && s->flags2&CODEC_FLAG2_SKIP_RD){ - int coded=0; - for(i=0; i<6; i++) - coded |= s->block_last_index[i]; - if(coded){ - int mx,my; - memcpy(s->mv, best_s.mv, sizeof(s->mv)); - if(CONFIG_MPEG4_ENCODER && best_s.mv_dir & MV_DIRECT){ - mx=my=0; //FIXME find the one we actually used - ff_mpeg4_set_direct_mv(s, mx, my); - }else if(best_s.mv_dir&MV_DIR_BACKWARD){ - mx= s->mv[1][0][0]; - my= s->mv[1][0][1]; - }else{ - mx= s->mv[0][0][0]; - my= s->mv[0][0][1]; - } - - s->mv_dir= best_s.mv_dir; - s->mv_type = best_s.mv_type; - s->mb_intra= 0; -/* s->mv[0][0][0] = best_s.mv[0][0][0]; - s->mv[0][0][1] = best_s.mv[0][0][1]; - s->mv[1][0][0] = best_s.mv[1][0][0]; - s->mv[1][0][1] = best_s.mv[1][0][1];*/ - backup_s.dquant= 0; - s->skipdct=1; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb, - &dmin, &next_block, mx, my); - s->skipdct=0; - } - } - - s->current_picture.qscale_table[xy]= best_s.qscale; - - copy_context_after_encode(s, &best_s, -1); - - pb_bits_count= put_bits_count(&s->pb); - flush_put_bits(&s->pb); - ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count); - s->pb= backup_s.pb; - - if(s->data_partitioning){ - pb2_bits_count= put_bits_count(&s->pb2); - flush_put_bits(&s->pb2); - ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count); - s->pb2= backup_s.pb2; - - tex_pb_bits_count= put_bits_count(&s->tex_pb); - flush_put_bits(&s->tex_pb); - ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count); - s->tex_pb= backup_s.tex_pb; - } - s->last_bits= put_bits_count(&s->pb); - - if (CONFIG_H263_ENCODER && - s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE) - ff_h263_update_motion_val(s); - - if(next_block==0){ //FIXME 16 vs linesize16 - s->dsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad , s->linesize ,16); - s->dsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize , s->uvlinesize, 8); - s->dsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8); - } - - if(s->avctx->mb_decision == FF_MB_DECISION_BITS) - MPV_decode_mb(s, s->block); - } else { - int motion_x = 0, motion_y = 0; - s->mv_type=MV_TYPE_16X16; - // only one MB-Type possible - - switch(mb_type){ - case CANDIDATE_MB_TYPE_INTRA: - s->mv_dir = 0; - s->mb_intra= 1; - motion_x= s->mv[0][0][0] = 0; - motion_y= s->mv[0][0][1] = 0; - break; - case CANDIDATE_MB_TYPE_INTER: - s->mv_dir = MV_DIR_FORWARD; - s->mb_intra= 0; - motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0]; - motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1]; - break; - case CANDIDATE_MB_TYPE_INTER_I: - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->p_field_select_table[i][xy]; - s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0]; - s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1]; - } - break; - case CANDIDATE_MB_TYPE_INTER4V: - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_8X8; - s->mb_intra= 0; - 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]; - } - break; - case CANDIDATE_MB_TYPE_DIRECT: - if (CONFIG_MPEG4_ENCODER) { - s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT; - s->mb_intra= 0; - motion_x=s->b_direct_mv_table[xy][0]; - motion_y=s->b_direct_mv_table[xy][1]; - ff_mpeg4_set_direct_mv(s, motion_x, motion_y); - } - break; - case CANDIDATE_MB_TYPE_DIRECT0: - if (CONFIG_MPEG4_ENCODER) { - s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT; - s->mb_intra= 0; - ff_mpeg4_set_direct_mv(s, 0, 0); - } - break; - case CANDIDATE_MB_TYPE_BIDIR: - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mb_intra= 0; - s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0]; - s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; - s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; - s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; - break; - case CANDIDATE_MB_TYPE_BACKWARD: - s->mv_dir = MV_DIR_BACKWARD; - s->mb_intra= 0; - motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0]; - motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1]; - break; - case CANDIDATE_MB_TYPE_FORWARD: - s->mv_dir = MV_DIR_FORWARD; - s->mb_intra= 0; - motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; - motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; -// printf(" %d %d ", motion_x, motion_y); - break; - case CANDIDATE_MB_TYPE_FORWARD_I: - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->b_field_select_table[0][i][xy]; - s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0]; - s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1]; - } - break; - case CANDIDATE_MB_TYPE_BACKWARD_I: - s->mv_dir = MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[1][i] = s->b_field_select_table[1][i][xy]; - s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0]; - s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1]; - } - break; - case CANDIDATE_MB_TYPE_BIDIR_I: - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(dir=0; dir<2; dir++){ - for(i=0; i<2; i++){ - j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy]; - s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0]; - s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1]; - } - } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "illegal MB type\n"); - } - - encode_mb(s, motion_x, motion_y); - - // RAL: Update last macroblock type - s->last_mv_dir = s->mv_dir; - - if (CONFIG_H263_ENCODER && - s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE) - ff_h263_update_motion_val(s); - - MPV_decode_mb(s, s->block); - } - - /* clean the MV table in IPS frames for direct mode in B frames */ - if(s->mb_intra /* && I,P,S_TYPE */){ - s->p_mv_table[xy][0]=0; - s->p_mv_table[xy][1]=0; - } - - if(s->flags&CODEC_FLAG_PSNR){ - int w= 16; - int h= 16; - - if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16; - if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16; - - s->current_picture.error[0] += sse( - s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, - s->dest[0], w, h, s->linesize); - s->current_picture.error[1] += sse( - s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h, - s->dest[1], w>>1, h>>s->chroma_y_shift, s->uvlinesize); - s->current_picture.error[2] += sse( - s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*chr_h, - s->dest[2], w>>1, h>>s->chroma_y_shift, s->uvlinesize); - } - if(s->loop_filter){ - if(CONFIG_H263_ENCODER && s->out_format == FMT_H263) - ff_h263_loop_filter(s); - } -//printf("MB %d %d bits\n", s->mb_x+s->mb_y*s->mb_stride, put_bits_count(&s->pb)); - } - } - - //not beautiful here but we must write it before flushing so it has to be here - if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == FF_I_TYPE) - msmpeg4_encode_ext_header(s); - - write_slice_end(s); - - /* Send the last GOB if RTP */ - if (s->avctx->rtp_callback) { - int number_mb = (mb_y - s->resync_mb_y)*s->mb_width - s->resync_mb_x; - pdif = put_bits_ptr(&s->pb) - s->ptr_lastgob; - /* Call the RTP callback to send the last GOB */ - emms_c(); - s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, number_mb); - } - - return 0; -} - -#define MERGE(field) dst->field += src->field; src->field=0 -static void merge_context_after_me(MpegEncContext *dst, MpegEncContext *src){ - MERGE(me.scene_change_score); - MERGE(me.mc_mb_var_sum_temp); - MERGE(me.mb_var_sum_temp); -} - -static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src){ - int i; - - MERGE(dct_count[0]); //note, the other dct vars are not part of the context - MERGE(dct_count[1]); - MERGE(mv_bits); - MERGE(i_tex_bits); - MERGE(p_tex_bits); - MERGE(i_count); - MERGE(f_count); - MERGE(b_count); - MERGE(skip_count); - MERGE(misc_bits); - MERGE(error_count); - MERGE(padding_bug_score); - MERGE(current_picture.error[0]); - MERGE(current_picture.error[1]); - MERGE(current_picture.error[2]); - - if(dst->avctx->noise_reduction){ - for(i=0; i<64; i++){ - MERGE(dct_error_sum[0][i]); - MERGE(dct_error_sum[1][i]); - } - } - - assert(put_bits_count(&src->pb) % 8 ==0); - assert(put_bits_count(&dst->pb) % 8 ==0); - ff_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb)); - flush_put_bits(&dst->pb); -} - -static int estimate_qp(MpegEncContext *s, int dry_run){ - if (s->next_lambda){ - s->current_picture_ptr->quality= - s->current_picture.quality = s->next_lambda; - if(!dry_run) s->next_lambda= 0; - } else if (!s->fixed_qscale) { - s->current_picture_ptr->quality= - s->current_picture.quality = ff_rate_estimate_qscale(s, dry_run); - if (s->current_picture.quality < 0) - return -1; - } - - if(s->adaptive_quant){ - switch(s->codec_id){ - case CODEC_ID_MPEG4: - if (CONFIG_MPEG4_ENCODER) - ff_clean_mpeg4_qscales(s); - break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_FLV1: - if (CONFIG_H263_ENCODER) - ff_clean_h263_qscales(s); - break; - default: - ff_init_qscale_tab(s); - } - - s->lambda= s->lambda_table[0]; - //FIXME broken - }else - s->lambda= s->current_picture.quality; -//printf("%d %d\n", s->avctx->global_quality, s->current_picture.quality); - update_qscale(s); - return 0; -} - -/* must be called before writing the header */ -static void set_frame_distances(MpegEncContext * s){ - assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE); - s->time= s->current_picture_ptr->pts*s->avctx->time_base.num; - - if(s->pict_type==FF_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); - }else{ - s->pp_time= s->time - s->last_non_b_time; - s->last_non_b_time= s->time; - assert(s->picture_number==0 || s->pp_time > 0); - } -} - -static int encode_picture(MpegEncContext *s, int picture_number) -{ - int i; - int bits; - - s->picture_number = picture_number; - - /* Reset the average MB variance */ - s->me.mb_var_sum_temp = - s->me.mc_mb_var_sum_temp = 0; - - /* we need to initialize some time vars before we can encode b-frames */ - // RAL: Condition added for MPEG1VIDEO - if (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO || (s->h263_pred && !s->h263_msmpeg4)) - set_frame_distances(s); - if(CONFIG_MPEG4_ENCODER && s->codec_id == CODEC_ID_MPEG4) - ff_set_mpeg4_time(s); - - s->me.scene_change_score=0; - -// s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME rate distortion - - if(s->pict_type==FF_I_TYPE){ - if(s->msmpeg4_version >= 3) s->no_rounding=1; - else s->no_rounding=0; - }else if(s->pict_type!=FF_B_TYPE){ - if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4) - s->no_rounding ^= 1; - } - - if(s->flags & CODEC_FLAG_PASS2){ - if (estimate_qp(s,1) < 0) - return -1; - ff_get_2pass_fcode(s); - }else if(!(s->flags & CODEC_FLAG_QSCALE)){ - if(s->pict_type==FF_B_TYPE) - s->lambda= s->last_lambda_for[s->pict_type]; - else - s->lambda= s->last_lambda_for[s->last_non_b_pict_type]; - update_qscale(s); - } - - s->mb_intra=0; //for the rate distortion & bit compare functions - for(i=1; iavctx->thread_count; i++){ - ff_update_duplicate_context(s->thread_context[i], s); - } - - if(ff_init_me(s)<0) - return -1; - - /* Estimate motion for every MB */ - if(s->pict_type != FF_I_TYPE){ - s->lambda = (s->lambda * s->avctx->me_penalty_compensation + 128)>>8; - s->lambda2= (s->lambda2* (int64_t)s->avctx->me_penalty_compensation + 128)>>8; - if(s->pict_type != FF_B_TYPE && s->avctx->me_threshold==0){ - if((s->avctx->pre_me && s->last_non_b_pict_type==FF_I_TYPE) || s->avctx->pre_me==2){ - s->avctx->execute(s->avctx, pre_estimate_motion_thread, &s->thread_context[0], NULL, s->avctx->thread_count, sizeof(void*)); - } - } - - s->avctx->execute(s->avctx, estimate_motion_thread, &s->thread_context[0], NULL, s->avctx->thread_count, sizeof(void*)); - }else /* if(s->pict_type == FF_I_TYPE) */{ - /* I-Frame */ - for(i=0; imb_stride*s->mb_height; i++) - s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA; - - if(!s->fixed_qscale){ - /* finding spatial complexity for I-frame rate control */ - s->avctx->execute(s->avctx, mb_var_thread, &s->thread_context[0], NULL, s->avctx->thread_count, sizeof(void*)); - } - } - for(i=1; iavctx->thread_count; i++){ - merge_context_after_me(s, s->thread_context[i]); - } - s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->me.mc_mb_var_sum_temp; - s->current_picture. mb_var_sum= s->current_picture_ptr-> mb_var_sum= s->me. mb_var_sum_temp; - emms_c(); - - if(s->me.scene_change_score > s->avctx->scenechange_threshold && s->pict_type == FF_P_TYPE){ - s->pict_type= FF_I_TYPE; - for(i=0; imb_stride*s->mb_height; i++) - s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA; -//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum); - } - - if(!s->umvplus){ - if(s->pict_type==FF_P_TYPE || s->pict_type==FF_S_TYPE) { - s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER); - - if(s->flags & CODEC_FLAG_INTERLACED_ME){ - int a,b; - a= ff_get_best_fcode(s, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select - b= ff_get_best_fcode(s, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I); - s->f_code= FFMAX3(s->f_code, a, b); - } - - ff_fix_long_p_mvs(s); - ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0); - if(s->flags & CODEC_FLAG_INTERLACED_ME){ - int j; - for(i=0; i<2; i++){ - for(j=0; j<2; j++) - ff_fix_long_mvs(s, s->p_field_select_table[i], j, - s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, 0); - } - } - } - - if(s->pict_type==FF_B_TYPE){ - int a, b; - - a = ff_get_best_fcode(s, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD); - b = ff_get_best_fcode(s, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR); - s->f_code = FFMAX(a, b); - - a = ff_get_best_fcode(s, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD); - b = ff_get_best_fcode(s, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR); - s->b_code = FFMAX(a, b); - - ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_FORWARD, 1); - ff_fix_long_mvs(s, NULL, 0, s->b_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BACKWARD, 1); - ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1); - ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1); - if(s->flags & CODEC_FLAG_INTERLACED_ME){ - int dir, j; - for(dir=0; dir<2; dir++){ - for(i=0; i<2; i++){ - for(j=0; j<2; j++){ - int type= dir ? (CANDIDATE_MB_TYPE_BACKWARD_I|CANDIDATE_MB_TYPE_BIDIR_I) - : (CANDIDATE_MB_TYPE_FORWARD_I |CANDIDATE_MB_TYPE_BIDIR_I); - ff_fix_long_mvs(s, s->b_field_select_table[dir][i], j, - s->b_field_mv_table[dir][i][j], dir ? s->b_code : s->f_code, type, 1); - } - } - } - } - } - } - - if (estimate_qp(s, 0) < 0) - return -1; - - if(s->qscale < 3 && s->max_qcoeff<=128 && s->pict_type==FF_I_TYPE && !(s->flags & CODEC_FLAG_QSCALE)) - s->qscale= 3; //reduce clipping problems - - if (s->out_format == FMT_MJPEG) { - /* for mjpeg, we do include qscale in the matrix */ - for(i=1;i<64;i++){ - int j= s->dsp.idct_permutation[i]; - - s->intra_matrix[j] = av_clip_uint8((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3); - } - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg2_dc_scale_table[s->intra_dc_precision]; - s->intra_matrix[0] = ff_mpeg2_dc_scale_table[s->intra_dc_precision][8]; - ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, - s->intra_matrix, s->intra_quant_bias, 8, 8, 1); - s->qscale= 8; - } - - //FIXME var duplication - s->current_picture_ptr->key_frame= - s->current_picture.key_frame= s->pict_type == FF_I_TYPE; //FIXME pic_ptr - s->current_picture_ptr->pict_type= - s->current_picture.pict_type= s->pict_type; - - if(s->current_picture.key_frame) - s->picture_in_gop_number=0; - - s->last_bits= put_bits_count(&s->pb); - switch(s->out_format) { - case FMT_MJPEG: - if (CONFIG_MJPEG_ENCODER) - ff_mjpeg_encode_picture_header(s); - break; - case FMT_H261: - if (CONFIG_H261_ENCODER) - ff_h261_encode_picture_header(s, picture_number); - break; - case FMT_H263: - if (CONFIG_WMV2_ENCODER && s->codec_id == CODEC_ID_WMV2) - ff_wmv2_encode_picture_header(s, picture_number); - else if (CONFIG_MSMPEG4_ENCODER && s->h263_msmpeg4) - msmpeg4_encode_picture_header(s, picture_number); - else if (CONFIG_MPEG4_ENCODER && s->h263_pred) - mpeg4_encode_picture_header(s, picture_number); - else if (CONFIG_RV10_ENCODER && s->codec_id == CODEC_ID_RV10) - rv10_encode_picture_header(s, picture_number); - else if (CONFIG_RV20_ENCODER && s->codec_id == CODEC_ID_RV20) - rv20_encode_picture_header(s, picture_number); - else if (CONFIG_FLV_ENCODER && s->codec_id == CODEC_ID_FLV1) - ff_flv_encode_picture_header(s, picture_number); - else if (CONFIG_H263_ENCODER) - h263_encode_picture_header(s, picture_number); - break; - case FMT_MPEG1: - if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) - mpeg1_encode_picture_header(s, picture_number); - break; - case FMT_H264: - break; - default: - assert(0); - } - bits= put_bits_count(&s->pb); - s->header_bits= bits - s->last_bits; - - for(i=1; iavctx->thread_count; i++){ - update_duplicate_context_after_me(s->thread_context[i], s); - } - s->avctx->execute(s->avctx, encode_thread, &s->thread_context[0], NULL, s->avctx->thread_count, sizeof(void*)); - for(i=1; iavctx->thread_count; i++){ - merge_context_after_encode(s, s->thread_context[i]); - } - emms_c(); - return 0; -} - -void denoise_dct_c(MpegEncContext *s, DCTELEM *block){ - const int intra= s->mb_intra; - int i; - - s->dct_count[intra]++; - - for(i=0; i<64; i++){ - int level= block[i]; - - if(level){ - if(level>0){ - s->dct_error_sum[intra][i] += level; - level -= s->dct_offset[intra][i]; - if(level<0) level=0; - }else{ - s->dct_error_sum[intra][i] -= level; - level += s->dct_offset[intra][i]; - if(level>0) level=0; - } - block[i]= level; - } - } -} - -int dct_quantize_trellis_c(MpegEncContext *s, - DCTELEM *block, int n, - int qscale, int *overflow){ - const int *qmat; - const uint8_t *scantable= s->intra_scantable.scantable; - const uint8_t *perm_scantable= s->intra_scantable.permutated; - int max=0; - unsigned int threshold1, threshold2; - int bias=0; - int run_tab[65]; - int level_tab[65]; - int score_tab[65]; - int survivor[65]; - int survivor_count; - int last_run=0; - int last_level=0; - int last_score= 0; - int last_i; - int coeff[2][64]; - int coeff_count[64]; - int qmul, qadd, start_i, last_non_zero, i, dc; - const int esc_length= s->ac_esc_length; - uint8_t * length; - uint8_t * last_length; - const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); - - s->dsp.fdct (block); - - if(s->dct_error_sum) - s->denoise_dct(s, block); - qmul= qscale*16; - qadd= ((qscale-1)|1)*8; - - if (s->mb_intra) { - int q; - if (!s->h263_aic) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - q = q << 3; - } else{ - /* For AIC we skip quant/dequant of INTRADC */ - q = 1 << 3; - qadd=0; - } - - /* note: block[0] is assumed to be positive */ - block[0] = (block[0] + (q >> 1)) / q; - start_i = 1; - last_non_zero = 0; - qmat = s->q_intra_matrix[qscale]; - if(s->mpeg_quant || s->out_format == FMT_MPEG1) - bias= 1<<(QMAT_SHIFT-1); - length = s->intra_ac_vlc_length; - last_length= s->intra_ac_vlc_last_length; - } else { - start_i = 0; - last_non_zero = -1; - qmat = s->q_inter_matrix[qscale]; - length = s->inter_ac_vlc_length; - last_length= s->inter_ac_vlc_last_length; - } - last_i= start_i; - - threshold1= (1<=start_i; i--) { - const int j = scantable[i]; - int level = block[j] * qmat[j]; - - if(((unsigned)(level+threshold1))>threshold2){ - last_non_zero = i; - break; - } - } - - for(i=start_i; i<=last_non_zero; i++) { - const int j = scantable[i]; - int level = block[j] * qmat[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)>>QMAT_SHIFT; - coeff[0][i]= level; - coeff[1][i]= level-1; -// coeff[2][k]= level-2; - }else{ - level= (bias - level)>>QMAT_SHIFT; - coeff[0][i]= -level; - coeff[1][i]= -level+1; -// coeff[2][k]= -level+2; - } - coeff_count[i]= FFMIN(level, 2); - assert(coeff_count[i]); - max |=level; - }else{ - coeff[0][i]= (level>>31)|1; - coeff_count[i]= 1; - } - } - - *overflow= s->max_qcoeff < max; //overflow might have happened - - if(last_non_zero < start_i){ - memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM)); - return last_non_zero; - } - - score_tab[start_i]= 0; - survivor[0]= start_i; - survivor_count= 1; - - for(i=start_i; i<=last_non_zero; i++){ - int level_index, j, zero_distortion; - int dct_coeff= FFABS(block[ scantable[i] ]); - int best_score=256*256*256*120; - - if ( s->dsp.fdct == fdct_ifast -#ifndef FAAN_POSTSCALE - || s->dsp.fdct == ff_faandct -#endif - ) - dct_coeff= (dct_coeff*ff_inv_aanscales[ scantable[i] ]) >> 12; - zero_distortion= dct_coeff*dct_coeff; - - for(level_index=0; level_index < coeff_count[i]; level_index++){ - int distortion; - int level= coeff[level_index][i]; - const int alevel= FFABS(level); - int unquant_coeff; - - assert(level); - - if(s->out_format == FMT_H263){ - unquant_coeff= alevel*qmul + qadd; - }else{ //MPEG1 - j= s->dsp.idct_permutation[ scantable[i] ]; //FIXME optimize - if(s->mb_intra){ - unquant_coeff = (int)( alevel * qscale * s->intra_matrix[j]) >> 3; - unquant_coeff = (unquant_coeff - 1) | 1; - }else{ - unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4; - unquant_coeff = (unquant_coeff - 1) | 1; - } - unquant_coeff<<= 3; - } - - distortion= (unquant_coeff - dct_coeff) * (unquant_coeff - dct_coeff) - zero_distortion; - level+=64; - if((level&(~127)) == 0){ - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distortion + length[UNI_AC_ENC_INDEX(run, level)]*lambda; - score += score_tab[i-run]; - - if(score < best_score){ - best_score= score; - run_tab[i+1]= run; - level_tab[i+1]= level-64; - } - } - - if(s->out_format == FMT_H263){ - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distortion + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda; - score += score_tab[i-run]; - if(score < last_score){ - last_score= score; - last_run= run; - last_level= level-64; - last_i= i+1; - } - } - } - }else{ - distortion += esc_length*lambda; - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distortion + score_tab[i-run]; - - if(score < best_score){ - best_score= score; - run_tab[i+1]= run; - level_tab[i+1]= level-64; - } - } - - if(s->out_format == FMT_H263){ - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distortion + score_tab[i-run]; - if(score < last_score){ - last_score= score; - last_run= run; - last_level= level-64; - last_i= i+1; - } - } - } - } - } - - score_tab[i+1]= best_score; - - //Note: there is a vlc code in mpeg4 which is 1 bit shorter then another one with a shorter run and the same level - if(last_non_zero <= 27){ - for(; survivor_count; survivor_count--){ - if(score_tab[ survivor[survivor_count-1] ] <= best_score) - break; - } - }else{ - for(; survivor_count; survivor_count--){ - if(score_tab[ survivor[survivor_count-1] ] <= best_score + lambda) - break; - } - } - - survivor[ survivor_count++ ]= i+1; - } - - if(s->out_format != FMT_H263){ - last_score= 256*256*256*120; - for(i= survivor[0]; i<=last_non_zero + 1; i++){ - int score= score_tab[i]; - if(i) score += lambda*2; //FIXME exacter? - - if(score < last_score){ - last_score= score; - last_i= i; - last_level= level_tab[i]; - last_run= run_tab[i]; - } - } - } - - s->coded_score[n] = last_score; - - dc= FFABS(block[0]); - last_non_zero= last_i - 1; - memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM)); - - if(last_non_zero < start_i) - return last_non_zero; - - if(last_non_zero == 0 && start_i == 0){ - int best_level= 0; - int best_score= dc * dc; - - for(i=0; iout_format == FMT_H263){ - unquant_coeff= (alevel*qmul + qadd)>>3; - }else{ //MPEG1 - unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[0])) >> 4; - unquant_coeff = (unquant_coeff - 1) | 1; - } - unquant_coeff = (unquant_coeff + 4) >> 3; - unquant_coeff<<= 3 + 3; - - distortion= (unquant_coeff - dc) * (unquant_coeff - dc); - level+=64; - if((level&(~127)) == 0) score= distortion + last_length[UNI_AC_ENC_INDEX(0, level)]*lambda; - else score= distortion + esc_length*lambda; - - if(score < best_score){ - best_score= score; - best_level= level - 64; - } - } - block[0]= best_level; - s->coded_score[n] = best_score - dc*dc; - if(best_level == 0) return -1; - else return last_non_zero; - } - - i= last_i; - assert(last_level); - - block[ perm_scantable[last_non_zero] ]= last_level; - i -= last_run + 1; - - for(; i>start_i; i -= run_tab[i] + 1){ - block[ perm_scantable[i-1] ]= level_tab[i]; - } - - return last_non_zero; -} - -//#define REFINE_STATS 1 -static int16_t basis[64][64]; - -static void build_basis(uint8_t *perm){ - int i, j, x, y; - emms_c(); - for(i=0; i<8; i++){ - for(j=0; j<8; j++){ - for(y=0; y<8; y++){ - for(x=0; x<8; x++){ - double s= 0.25*(1<intra_scantable.scantable; - const uint8_t *perm_scantable= s->intra_scantable.permutated; -// unsigned int threshold1, threshold2; -// int bias=0; - int run_tab[65]; - int prev_run=0; - int prev_level=0; - int qmul, qadd, start_i, last_non_zero, i, dc; - uint8_t * length; - uint8_t * last_length; - int lambda; - int rle_index, run, q = 1, sum; //q is only used when s->mb_intra is true -#ifdef REFINE_STATS -static int count=0; -static int after_last=0; -static int to_zero=0; -static int from_zero=0; -static int raise=0; -static int lower=0; -static int messed_sign=0; -#endif - - if(basis[0][0] == 0) - build_basis(s->dsp.idct_permutation); - - qmul= qscale*2; - qadd= (qscale-1)|1; - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - } else{ - /* For AIC we skip quant/dequant of INTRADC */ - q = 1; - qadd=0; - } - q <<= RECON_SHIFT-3; - /* note: block[0] is assumed to be positive */ - dc= block[0]*q; -// block[0] = (block[0] + (q >> 1)) / q; - start_i = 1; -// if(s->mpeg_quant || s->out_format == FMT_MPEG1) -// bias= 1<<(QMAT_SHIFT-1); - length = s->intra_ac_vlc_length; - last_length= s->intra_ac_vlc_last_length; - } else { - dc= 0; - start_i = 0; - length = s->inter_ac_vlc_length; - last_length= s->inter_ac_vlc_last_length; - } - last_non_zero = s->block_last_index[n]; - -#ifdef REFINE_STATS -{START_TIMER -#endif - dc += (1<<(RECON_SHIFT-1)); - for(i=0; i<64; i++){ - rem[i]= dc - (orig[i]<0); - assert(w<(1<<6)); - sum += w*w; - } - lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6); -#ifdef REFINE_STATS -{START_TIMER -#endif - run=0; - rle_index=0; - for(i=start_i; i<=last_non_zero; i++){ - int j= perm_scantable[i]; - const int level= block[j]; - int coeff; - - if(level){ - if(level<0) coeff= qmul*level - qadd; - else coeff= qmul*level + qadd; - run_tab[rle_index++]=run; - run=0; - - s->dsp.add_8x8basis(rem, basis[j], coeff); - }else{ - run++; - } - } -#ifdef REFINE_STATS -if(last_non_zero>0){ -STOP_TIMER("init rem[]") -} -} - -{START_TIMER -#endif - for(;;){ - int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0); - int best_coeff=0; - int best_change=0; - int run2, best_unquant_change=0, analyze_gradient; -#ifdef REFINE_STATS -{START_TIMER -#endif - analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3; - - if(analyze_gradient){ -#ifdef REFINE_STATS -{START_TIMER -#endif - for(i=0; i<64; i++){ - int w= weight[i]; - - d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12); - } -#ifdef REFINE_STATS -STOP_TIMER("rem*w*w")} -{START_TIMER -#endif - s->dsp.fdct(d1); -#ifdef REFINE_STATS -STOP_TIMER("dct")} -#endif - } - - if(start_i){ - const int level= block[0]; - int change, old_coeff; - - assert(s->mb_intra); - - old_coeff= q*level; - - for(change=-1; change<=1; change+=2){ - int new_level= level + change; - int score, new_coeff; - - new_coeff= q*new_level; - if(new_coeff >= 2048 || new_coeff < 0) - continue; - - score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff); - if(scoreavctx->quantizer_noise_shaping < 3 && i > last_non_zero + 1) - break; - - if(level){ - if(level<0) old_coeff= qmul*level - qadd; - else old_coeff= qmul*level + qadd; - run2= run_tab[rle_index++]; //FIXME ! maybe after last - }else{ - old_coeff=0; - run2--; - assert(run2>=0 || i >= last_non_zero ); - } - - for(change=-1; change<=1; change+=2){ - int new_level= level + change; - int score, new_coeff, unquant_change; - - score=0; - if(s->avctx->quantizer_noise_shaping < 2 && FFABS(new_level) > FFABS(level)) - continue; - - if(new_level){ - if(new_level<0) new_coeff= qmul*new_level - qadd; - else new_coeff= qmul*new_level + qadd; - if(new_coeff >= 2048 || new_coeff <= -2048) - continue; - //FIXME check for overflow - - if(level){ - if(level < 63 && level > -63){ - if(i < last_non_zero) - score += length[UNI_AC_ENC_INDEX(run, new_level+64)] - - length[UNI_AC_ENC_INDEX(run, level+64)]; - else - score += last_length[UNI_AC_ENC_INDEX(run, new_level+64)] - - last_length[UNI_AC_ENC_INDEX(run, level+64)]; - } - }else{ - assert(FFABS(new_level)==1); - - if(analyze_gradient){ - int g= d1[ scantable[i] ]; - if(g && (g^new_level) >= 0) - continue; - } - - if(i < last_non_zero){ - int next_i= i + run2 + 1; - int next_level= block[ perm_scantable[next_i] ] + 64; - - if(next_level&(~127)) - next_level= 0; - - if(next_i < last_non_zero) - score += length[UNI_AC_ENC_INDEX(run, 65)] - + length[UNI_AC_ENC_INDEX(run2, next_level)] - - length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]; - else - score += length[UNI_AC_ENC_INDEX(run, 65)] - + last_length[UNI_AC_ENC_INDEX(run2, next_level)] - - last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]; - }else{ - score += last_length[UNI_AC_ENC_INDEX(run, 65)]; - if(prev_level){ - score += length[UNI_AC_ENC_INDEX(prev_run, prev_level)] - - last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)]; - } - } - } - }else{ - new_coeff=0; - assert(FFABS(level)==1); - - if(i < last_non_zero){ - int next_i= i + run2 + 1; - int next_level= block[ perm_scantable[next_i] ] + 64; - - if(next_level&(~127)) - next_level= 0; - - if(next_i < last_non_zero) - score += length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)] - - length[UNI_AC_ENC_INDEX(run2, next_level)] - - length[UNI_AC_ENC_INDEX(run, 65)]; - else - score += last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)] - - last_length[UNI_AC_ENC_INDEX(run2, next_level)] - - length[UNI_AC_ENC_INDEX(run, 65)]; - }else{ - score += -last_length[UNI_AC_ENC_INDEX(run, 65)]; - if(prev_level){ - score += last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)] - - length[UNI_AC_ENC_INDEX(prev_run, prev_level)]; - } - } - } - - score *= lambda; - - unquant_change= new_coeff - old_coeff; - assert((score < 100*lambda && score > -100*lambda) || lambda==0); - - score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change); - if(score last_non_zero){ - last_non_zero= best_coeff; - assert(block[j]); -#ifdef REFINE_STATS -after_last++; -#endif - }else{ -#ifdef REFINE_STATS -if(block[j]){ - if(block[j] - best_change){ - if(FFABS(block[j]) > FFABS(block[j] - best_change)){ - raise++; - }else{ - lower++; - } - }else{ - from_zero++; - } -}else{ - to_zero++; -} -#endif - for(; last_non_zero>=start_i; last_non_zero--){ - if(block[perm_scantable[last_non_zero]]) - break; - } - } -#ifdef REFINE_STATS -count++; -if(256*256*256*64 % count == 0){ - printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number); -} -#endif - run=0; - rle_index=0; - for(i=start_i; i<=last_non_zero; i++){ - int j= perm_scantable[i]; - const int level= block[j]; - - if(level){ - run_tab[rle_index++]=run; - run=0; - }else{ - run++; - } - } - - s->dsp.add_8x8basis(rem, basis[j], best_unquant_change); - }else{ - break; - } - } -#ifdef REFINE_STATS -if(last_non_zero>0){ -STOP_TIMER("iterative search") -} -} -#endif - - return last_non_zero; -} - -int dct_quantize_c(MpegEncContext *s, - DCTELEM *block, int n, - int qscale, int *overflow) -{ - int i, j, level, last_non_zero, q, start_i; - const int *qmat; - const uint8_t *scantable= s->intra_scantable.scantable; - int bias; - int max=0; - unsigned int threshold1, threshold2; - - s->dsp.fdct (block); - - if(s->dct_error_sum) - s->denoise_dct(s, block); - - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - q = q << 3; - } else - /* For AIC we skip quant/dequant of INTRADC */ - q = 1 << 3; - - /* note: block[0] is assumed to be positive */ - block[0] = (block[0] + (q >> 1)) / q; - start_i = 1; - last_non_zero = 0; - qmat = s->q_intra_matrix[qscale]; - bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT); - } else { - start_i = 0; - last_non_zero = -1; - qmat = s->q_inter_matrix[qscale]; - bias= s->inter_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT); - } - threshold1= (1<=start_i;i--) { - j = scantable[i]; - level = block[j] * qmat[j]; - - if(((unsigned)(level+threshold1))>threshold2){ - last_non_zero = i; - break; - }else{ - block[j]=0; - } - } - for(i=start_i; i<=last_non_zero; i++) { - j = scantable[i]; - level = block[j] * qmat[j]; - -// if( bias+level >= (1<= (1<threshold2){ - if(level>0){ - level= (bias + level)>>QMAT_SHIFT; - block[j]= level; - }else{ - level= (bias - level)>>QMAT_SHIFT; - block[j]= -level; - } - max |=level; - }else{ - block[j]=0; - } - } - *overflow= s->max_qcoeff < max; //overflow might have happened - - /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ - if (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM) - ff_block_permute(block, s->dsp.idct_permutation, scantable, last_non_zero); - - return last_non_zero; -} - -AVCodec h263_encoder = { - "h263", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_H263, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"), -}; - -AVCodec h263p_encoder = { - "h263p", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_H263P, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"), -}; - -AVCodec msmpeg4v1_encoder = { - "msmpeg4v1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSMPEG4V1, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"), -}; - -AVCodec msmpeg4v2_encoder = { - "msmpeg4v2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSMPEG4V2, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), -}; - -AVCodec msmpeg4v3_encoder = { - "msmpeg4", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSMPEG4V3, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), -}; - -AVCodec wmv1_encoder = { - "wmv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WMV1, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_parser.c b/tizen/distrib/ffmpeg/libavcodec/mpegvideo_parser.c deleted file mode 100644 index 546c3bd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_parser.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * MPEG1 / MPEG2 video parser - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" -#include "mpegvideo.h" - -static void mpegvideo_extract_headers(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - ParseContext1 *pc = s->priv_data; - const uint8_t *buf_end = buf + buf_size; - uint32_t start_code; - int frame_rate_index, ext_type, bytes_left; - int frame_rate_ext_n, frame_rate_ext_d; - int picture_structure, top_field_first, repeat_first_field, progressive_frame; - int horiz_size_ext, vert_size_ext, bit_rate_ext; - int did_set_size=0; -//FIXME replace the crap with get_bits() - s->repeat_pict = 0; - - while (buf < buf_end) { - start_code= -1; - buf= ff_find_start_code(buf, buf_end, &start_code); - bytes_left = buf_end - buf; - switch(start_code) { - case PICTURE_START_CODE: - if (bytes_left >= 2) { - s->pict_type = (buf[1] >> 3) & 7; - } - break; - case SEQ_START_CODE: - if (bytes_left >= 7) { - pc->width = (buf[0] << 4) | (buf[1] >> 4); - pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; - if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){ - avcodec_set_dimensions(avctx, pc->width, pc->height); - did_set_size=1; - } - frame_rate_index = buf[3] & 0xf; - pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num; - pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den; - avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; - avctx->codec_id = CODEC_ID_MPEG1VIDEO; - avctx->sub_id = 1; - } - break; - case EXT_START_CODE: - if (bytes_left >= 1) { - ext_type = (buf[0] >> 4); - switch(ext_type) { - case 0x1: /* sequence extension */ - if (bytes_left >= 6) { - horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); - vert_size_ext = (buf[2] >> 5) & 3; - bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); - frame_rate_ext_n = (buf[5] >> 5) & 3; - frame_rate_ext_d = (buf[5] & 0x1f); - pc->progressive_sequence = buf[1] & (1 << 3); - avctx->has_b_frames= !(buf[5] >> 7); - - pc->width |=(horiz_size_ext << 12); - pc->height |=( vert_size_ext << 12); - avctx->bit_rate += (bit_rate_ext << 18) * 400; - if(did_set_size) - avcodec_set_dimensions(avctx, pc->width, pc->height); - avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1) * 2; - avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); - avctx->codec_id = CODEC_ID_MPEG2VIDEO; - avctx->sub_id = 2; /* forces MPEG2 */ - } - break; - case 0x8: /* picture coding extension */ - if (bytes_left >= 5) { - picture_structure = buf[2]&3; - top_field_first = buf[3] & (1 << 7); - repeat_first_field = buf[3] & (1 << 1); - progressive_frame = buf[4] & (1 << 7); - - /* check if we must repeat the frame */ - s->repeat_pict = 1; - if (repeat_first_field) { - if (pc->progressive_sequence) { - if (top_field_first) - s->repeat_pict = 5; - else - s->repeat_pict = 3; - } else if (progressive_frame) { - s->repeat_pict = 2; - } - } - } - break; - } - } - break; - case -1: - goto the_end; - default: - /* we stop parsing when we encounter a slice. It ensures - that this function takes a negligible amount of time */ - if (start_code >= SLICE_MIN_START_CODE && - start_code <= SLICE_MAX_START_CODE) - goto the_end; - break; - } - } - the_end: ; -} - -static int mpegvideo_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext1 *pc1 = s->priv_data; - ParseContext *pc= &pc1->pc; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= ff_mpeg1_find_frame_end(pc, buf, buf_size, s); - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - } - /* we have a full frame : we just parse the first few MPEG headers - to have the full timing information. The time take by this - function should be negligible for uncorrupted streams */ - mpegvideo_extract_headers(s, avctx, buf, buf_size); -#if 0 - printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", - s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); -#endif - - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -static int mpegvideo_split(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - int i; - uint32_t state= -1; - - for(i=0; i= 0x100) - return i-3; - } - return 0; -} - -AVCodecParser mpegvideo_parser = { - { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, - sizeof(ParseContext1), - NULL, - mpegvideo_parse, - ff_parse1_close, - mpegvideo_split, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_xvmc.c b/tizen/distrib/ffmpeg/libavcodec/mpegvideo_xvmc.c deleted file mode 100644 index df81e5d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/mpegvideo_xvmc.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * XVideo Motion Compensation - * Copyright (c) 2003 Ivan Kalvachev - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - -#undef NDEBUG -#include - -#include "xvmc.h" -#include "xvmc_internal.h" - -/** - * Initializes the block field of the MpegEncContext pointer passed as - * parameter after making sure that the data is not corrupted. - * In order to implement something like direct rendering instead of decoding - * coefficients in s->blocks and then copying them, copy them directly - * into the data_blocks array provided by xvmc. - */ -void ff_xvmc_init_block(MpegEncContext *s) -{ - struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.data[2]; - assert(render && render->xvmc_id == AV_XVMC_ID); - - s->block = (DCTELEM (*)[64])(render->data_blocks + render->next_free_data_block_num * 64); -} - -/** - * Fills individual block pointers, so there are no gaps in the data_block array - * in case not all blocks in the macroblock are coded. - */ -void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp) -{ - int i, j = 0; - const int mb_block_count = 4 + (1 << s->chroma_format); - - cbp <<= 12-mb_block_count; - for (i = 0; i < mb_block_count; i++) { - if (cbp & (1 << 11)) - s->pblocks[i] = &s->block[j++]; - else - s->pblocks[i] = NULL; - cbp += cbp; - } -} - -/** - * Finds and stores the surfaces that are used as reference frames. - * This function should be called for every new field and/or frame. - * It should be safe to call the function a few times for the same field. - */ -int ff_xvmc_field_start(MpegEncContext *s, AVCodecContext *avctx) -{ - struct xvmc_pix_fmt *last, *next, *render = (struct xvmc_pix_fmt*)s->current_picture.data[2]; - const int mb_block_count = 4 + (1 << s->chroma_format); - - assert(avctx); - if (!render || render->xvmc_id != AV_XVMC_ID || - !render->data_blocks || !render->mv_blocks || - (unsigned int)render->allocated_mv_blocks > INT_MAX/(64*6) || - (unsigned int)render->allocated_data_blocks > INT_MAX/64 || - !render->p_surface) { - av_log(avctx, AV_LOG_ERROR, - "Render token doesn't look as expected.\n"); - return -1; // make sure that this is a render packet - } - - if (render->filled_mv_blocks_num) { - av_log(avctx, AV_LOG_ERROR, - "Rendering surface contains %i unprocessed blocks.\n", - render->filled_mv_blocks_num); - return -1; - } - if (render->allocated_mv_blocks < 1 || - render->allocated_data_blocks < render->allocated_mv_blocks*mb_block_count || - render->start_mv_blocks_num >= render->allocated_mv_blocks || - render->next_free_data_block_num > - render->allocated_data_blocks - - mb_block_count*(render->allocated_mv_blocks-render->start_mv_blocks_num)) { - av_log(avctx, AV_LOG_ERROR, - "Rendering surface doesn't provide enough block structures to work with.\n"); - return -1; - } - - render->picture_structure = s->picture_structure; - render->flags = s->first_field ? 0 : XVMC_SECOND_FIELD; - render->p_future_surface = NULL; - render->p_past_surface = NULL; - - switch(s->pict_type) { - case FF_I_TYPE: - return 0; // no prediction from other frames - case FF_B_TYPE: - next = (struct xvmc_pix_fmt*)s->next_picture.data[2]; - if (!next) - return -1; - if (next->xvmc_id != AV_XVMC_ID) - return -1; - render->p_future_surface = next->p_surface; - // no return here, going to set forward prediction - case FF_P_TYPE: - last = (struct xvmc_pix_fmt*)s->last_picture.data[2]; - if (!last) - last = render; // predict second field from the first - if (last->xvmc_id != AV_XVMC_ID) - return -1; - render->p_past_surface = last->p_surface; - return 0; - } - -return -1; -} - -/** - * Completes frame/field rendering by passing any remaining blocks. - * Normally ff_draw_horiz_band() is called for each slice, however, - * some leftover blocks, for example from error_resilience(), may remain. - * It should be safe to call the function a few times for the same field. - */ -void ff_xvmc_field_end(MpegEncContext *s) -{ - struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.data[2]; - assert(render); - - if (render->filled_mv_blocks_num > 0) - ff_draw_horiz_band(s, 0, 0); -} - -/** - * Synthesizes the data needed by XvMC to render one macroblock of data. - * Fills all relevant fields, if necessary do IDCT. - */ -void ff_xvmc_decode_mb(MpegEncContext *s) -{ - XvMCMacroBlock *mv_block; - struct xvmc_pix_fmt *render; - int i, cbp, blocks_per_mb; - - const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; - - - if (s->encoding) { - av_log(s->avctx, AV_LOG_ERROR, "XVMC doesn't support encoding!!!\n"); - return; - } - - // from MPV_decode_mb(), update DC predictors for P macroblocks - if (!s->mb_intra) { - s->last_dc[0] = - s->last_dc[1] = - s->last_dc[2] = 128 << s->intra_dc_precision; - } - - // MC doesn't skip blocks - s->mb_skipped = 0; - - - // Do I need to export quant when I could not perform postprocessing? - // Anyway, it doesn't hurt. - s->current_picture.qscale_table[mb_xy] = s->qscale; - - // start of XVMC-specific code - render = (struct xvmc_pix_fmt*)s->current_picture.data[2]; - assert(render); - assert(render->xvmc_id == AV_XVMC_ID); - assert(render->mv_blocks); - - // take the next free macroblock - mv_block = &render->mv_blocks[render->start_mv_blocks_num + - render->filled_mv_blocks_num]; - - mv_block->x = s->mb_x; - mv_block->y = s->mb_y; - mv_block->dct_type = s->interlaced_dct; // XVMC_DCT_TYPE_FRAME/FIELD; - if (s->mb_intra) { - mv_block->macroblock_type = XVMC_MB_TYPE_INTRA; // no MC, all done - } else { - mv_block->macroblock_type = XVMC_MB_TYPE_PATTERN; - - if (s->mv_dir & MV_DIR_FORWARD) { - mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD; - // PMV[n][dir][xy] = mv[dir][n][xy] - mv_block->PMV[0][0][0] = s->mv[0][0][0]; - mv_block->PMV[0][0][1] = s->mv[0][0][1]; - mv_block->PMV[1][0][0] = s->mv[0][1][0]; - mv_block->PMV[1][0][1] = s->mv[0][1][1]; - } - if (s->mv_dir & MV_DIR_BACKWARD) { - mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD; - mv_block->PMV[0][1][0] = s->mv[1][0][0]; - mv_block->PMV[0][1][1] = s->mv[1][0][1]; - mv_block->PMV[1][1][0] = s->mv[1][1][0]; - mv_block->PMV[1][1][1] = s->mv[1][1][1]; - } - - switch(s->mv_type) { - case MV_TYPE_16X16: - mv_block->motion_type = XVMC_PREDICTION_FRAME; - break; - case MV_TYPE_16X8: - mv_block->motion_type = XVMC_PREDICTION_16x8; - break; - case MV_TYPE_FIELD: - mv_block->motion_type = XVMC_PREDICTION_FIELD; - if (s->picture_structure == PICT_FRAME) { - mv_block->PMV[0][0][1] <<= 1; - mv_block->PMV[1][0][1] <<= 1; - mv_block->PMV[0][1][1] <<= 1; - mv_block->PMV[1][1][1] <<= 1; - } - break; - case MV_TYPE_DMV: - mv_block->motion_type = XVMC_PREDICTION_DUAL_PRIME; - if (s->picture_structure == PICT_FRAME) { - - mv_block->PMV[0][0][0] = s->mv[0][0][0]; // top from top - mv_block->PMV[0][0][1] = s->mv[0][0][1] << 1; - - mv_block->PMV[0][1][0] = s->mv[0][0][0]; // bottom from bottom - mv_block->PMV[0][1][1] = s->mv[0][0][1] << 1; - - mv_block->PMV[1][0][0] = s->mv[0][2][0]; // dmv00, top from bottom - mv_block->PMV[1][0][1] = s->mv[0][2][1] << 1; // dmv01 - - mv_block->PMV[1][1][0] = s->mv[0][3][0]; // dmv10, bottom from top - mv_block->PMV[1][1][1] = s->mv[0][3][1] << 1; // dmv11 - - } else { - mv_block->PMV[0][1][0] = s->mv[0][2][0]; // dmv00 - mv_block->PMV[0][1][1] = s->mv[0][2][1]; // dmv01 - } - break; - default: - assert(0); - } - - mv_block->motion_vertical_field_select = 0; - - // set correct field references - if (s->mv_type == MV_TYPE_FIELD || s->mv_type == MV_TYPE_16X8) { - mv_block->motion_vertical_field_select |= s->field_select[0][0]; - mv_block->motion_vertical_field_select |= s->field_select[1][0] << 1; - mv_block->motion_vertical_field_select |= s->field_select[0][1] << 2; - mv_block->motion_vertical_field_select |= s->field_select[1][1] << 3; - } - } // !intra - // time to handle data blocks - mv_block->index = render->next_free_data_block_num; - - blocks_per_mb = 6; - if (s->chroma_format >= 2) { - blocks_per_mb = 4 + (1 << s->chroma_format); - } - - // calculate cbp - cbp = 0; - for (i = 0; i < blocks_per_mb; i++) { - cbp += cbp; - if (s->block_last_index[i] >= 0) - cbp++; - } - - if (s->flags & CODEC_FLAG_GRAY) { - if (s->mb_intra) { // intra frames are always full chroma blocks - for (i = 4; i < blocks_per_mb; i++) { - memset(s->pblocks[i], 0, sizeof(*s->pblocks[i])); // so we need to clear them - if (!render->unsigned_intra) - *s->pblocks[i][0] = 1 << 10; - } - } else { - cbp &= 0xf << (blocks_per_mb - 4); - blocks_per_mb = 4; // luminance blocks only - } - } - mv_block->coded_block_pattern = cbp; - if (cbp == 0) - mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN; - - for (i = 0; i < blocks_per_mb; i++) { - if (s->block_last_index[i] >= 0) { - // I do not have unsigned_intra MOCO to test, hope it is OK. - if (s->mb_intra && (render->idct || (!render->idct && !render->unsigned_intra))) - *s->pblocks[i][0] -= 1 << 10; - if (!render->idct) { - s->dsp.idct(*s->pblocks[i]); - /* It is unclear if MC hardware requires pixel diff values to be - * in the range [-255;255]. TODO: Clipping if such hardware is - * ever found. As of now it would only be an unnecessary - * slowdown. */ - } - // copy blocks only if the codec doesn't support pblocks reordering - if (s->avctx->xvmc_acceleration == 1) { - memcpy(&render->data_blocks[render->next_free_data_block_num*64], - s->pblocks[i], sizeof(*s->pblocks[i])); - } - render->next_free_data_block_num++; - } - } - render->filled_mv_blocks_num++; - - assert(render->filled_mv_blocks_num <= render->allocated_mv_blocks); - assert(render->next_free_data_block_num <= render->allocated_data_blocks); - /* The above conditions should not be able to fail as long as this function - * is used and the following 'if ()' automatically calls a callback to free - * blocks. */ - - - if (render->filled_mv_blocks_num == render->allocated_mv_blocks) - ff_draw_horiz_band(s, 0, 0); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/msmpeg4.c b/tizen/distrib/ffmpeg/libavcodec/msmpeg4.c deleted file mode 100644 index 84658fe..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msmpeg4.c +++ /dev/null @@ -1,1976 +0,0 @@ -/* - * MSMPEG4 backend for ffmpeg encoder and decoder - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * msmpeg4v1 & v2 stuff by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MSMPEG4 backend for ffmpeg encoder and decoder. - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "msmpeg4.h" -#include "libavutil/x86_cpu.h" -#include "h263.h" -#include "mpeg4video.h" - -/* - * You can also call this codec : MPEG4 with a twist ! - * - * TODO: - * - (encoding) select best mv table (two choices) - * - (encoding) select best vlc/dc table - */ -//#define DEBUG - -#define DC_VLC_BITS 9 -#define V2_INTRA_CBPC_VLC_BITS 3 -#define V2_MB_TYPE_VLC_BITS 7 -#define MV_VLC_BITS 9 -#define V2_MV_VLC_BITS 9 -#define TEX_VLC_BITS 9 - -#define II_BITRATE 128*1024 -#define MBAC_BITRATE 50*1024 - -#define DEFAULT_INTER_INDEX 3 - -static uint32_t v2_dc_lum_table[512][2]; -static uint32_t v2_dc_chroma_table[512][2]; - -/* vc1 externs */ -extern const uint8_t wmv3_dc_scale_table[32]; - -#ifdef DEBUG -int frame_count = 0; -#endif - -#include "msmpeg4data.h" - -#if CONFIG_ENCODERS //strangely gcc includes this even if it is not referenced -static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; -#endif //CONFIG_ENCODERS - -static uint8_t static_rl_table_store[NB_RL_TABLES][2][2*MAX_RUN + MAX_LEVEL + 3]; - -/* This table is practically identical to the one from h263 - * except that it is inverted. */ -static av_cold void init_h263_dc_for_msmpeg4(void) -{ - int level, uni_code, uni_len; - - for(level=-256; level<256; level++){ - int size, v, l; - /* find number of bits */ - size = 0; - v = abs(level); - while (v) { - v >>= 1; - size++; - } - - if (level < 0) - l= (-level) ^ ((1 << size) - 1); - else - l= level; - - /* luminance h263 */ - uni_code= ff_mpeg4_DCtab_lum[size][0]; - uni_len = ff_mpeg4_DCtab_lum[size][1]; - uni_code ^= (1< 0) { - uni_code<<=size; uni_code|=l; - uni_len+=size; - if (size > 8){ - uni_code<<=1; uni_code|=1; - uni_len++; - } - } - v2_dc_lum_table[level+256][0]= uni_code; - v2_dc_lum_table[level+256][1]= uni_len; - - /* chrominance h263 */ - uni_code= ff_mpeg4_DCtab_chrom[size][0]; - uni_len = ff_mpeg4_DCtab_chrom[size][1]; - uni_code ^= (1< 0) { - uni_code<<=size; uni_code|=l; - uni_len+=size; - if (size > 8){ - uni_code<<=1; uni_code|=1; - uni_len++; - } - } - v2_dc_chroma_table[level+256][0]= uni_code; - v2_dc_chroma_table[level+256][1]= uni_len; - - } -} - -static av_cold void common_init(MpegEncContext * s) -{ - static int initialized=0; - - switch(s->msmpeg4_version){ - case 1: - case 2: - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg1_dc_scale_table; - break; - case 3: - if(s->workaround_bugs){ - s->y_dc_scale_table= old_ff_y_dc_scale_table; - s->c_dc_scale_table= wmv1_c_dc_scale_table; - } else{ - s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; - s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; - } - break; - case 4: - case 5: - s->y_dc_scale_table= wmv1_y_dc_scale_table; - s->c_dc_scale_table= wmv1_c_dc_scale_table; - break; -#if CONFIG_VC1_DECODER - case 6: - s->y_dc_scale_table= wmv3_dc_scale_table; - s->c_dc_scale_table= wmv3_dc_scale_table; - break; -#endif - - } - - - if(s->msmpeg4_version>=4){ - ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , wmv1_scantable[1]); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, wmv1_scantable[2]); - ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, wmv1_scantable[3]); - ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , wmv1_scantable[0]); - } - //Note the default tables are set in common_init in mpegvideo.c - - if(!initialized){ - initialized=1; - - init_h263_dc_for_msmpeg4(); - } -} - -#if CONFIG_ENCODERS - -/* build the table which associate a (x,y) motion vector to a vlc */ -static void init_mv_table(MVTable *tab) -{ - int i, x, y; - - tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096); - /* mark all entries as not used */ - for(i=0;i<4096;i++) - tab->table_mv_index[i] = tab->n; - - for(i=0;in;i++) { - x = tab->table_mvx[i]; - y = tab->table_mvy[i]; - tab->table_mv_index[(x << 6) | y] = i; - } -} - -void ff_msmpeg4_code012(PutBitContext *pb, int n) -{ - if (n == 0) { - put_bits(pb, 1, 0); - } else { - put_bits(pb, 1, 1); - put_bits(pb, 1, (n >= 2)); - } -} - -static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra){ - int size=0; - int code; - int run_diff= intra ? 0 : 1; - - code = get_rl_index(rl, last, run, level); - size+= rl->table_vlc[code][1]; - 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: - size++; - if (level > MAX_LEVEL) - goto esc3; - run1 = run - rl->max_run[last][level] - run_diff; - if (run1 < 0) - goto esc3; - code = get_rl_index(rl, last, run1, level); - if (code == rl->n) { - esc3: - /* third escape */ - size+=1+1+6+8; - } else { - /* second escape */ - size+= 1+1+ rl->table_vlc[code][1]; - } - } else { - /* first escape */ - size+= 1+1+ rl->table_vlc[code][1]; - } - } else { - size++; - } - return size; -} - -av_cold void ff_msmpeg4_encode_init(MpegEncContext *s) -{ - static int init_done=0; - int i; - - common_init(s); - if(s->msmpeg4_version>=4){ - s->min_qcoeff= -255; - s->max_qcoeff= 255; - } - - if (!init_done) { - /* init various encoding tables */ - init_done = 1; - init_mv_table(&mv_tables[0]); - init_mv_table(&mv_tables[1]); - for(i=0;i0){// ;) - size++; - chroma_size++; - } - for(level=0; level<=MAX_LEVEL; level++){ - int run; - for(run=0; run<=MAX_RUN; run++){ - int last; - const int last_size= size + chroma_size; - for(last=0; last<2; last++){ - int inter_count = s->ac_stats[0][0][level][run][last] + s->ac_stats[0][1][level][run][last]; - int intra_luma_count = s->ac_stats[1][0][level][run][last]; - int intra_chroma_count= s->ac_stats[1][1][level][run][last]; - - if(s->pict_type==FF_I_TYPE){ - size += intra_luma_count *rl_length[i ][level][run][last]; - chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last]; - }else{ - size+= intra_luma_count *rl_length[i ][level][run][last] - +intra_chroma_count*rl_length[i+3][level][run][last] - +inter_count *rl_length[i+3][level][run][last]; - } - } - if(last_size == size+chroma_size) break; - } - } - if(sizepict_type, best, s->qscale, s->mb_var_sum, s->mc_mb_var_sum, best_size); - - if(s->pict_type==FF_P_TYPE) chroma_best= best; - - memset(s->ac_stats, 0, sizeof(int)*(MAX_LEVEL+1)*(MAX_RUN+1)*2*2*2); - - s->rl_table_index = best; - s->rl_chroma_table_index= chroma_best; - - if(s->pict_type != s->last_non_b_pict_type){ - s->rl_table_index= 2; - if(s->pict_type==FF_I_TYPE) - s->rl_chroma_table_index= 1; - else - s->rl_chroma_table_index= 2; - } - -} - -/* write MSMPEG4 compatible frame header */ -void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) -{ - find_best_tables(s); - - align_put_bits(&s->pb); - put_bits(&s->pb, 2, s->pict_type - 1); - - put_bits(&s->pb, 5, s->qscale); - if(s->msmpeg4_version<=2){ - s->rl_table_index = 2; - s->rl_chroma_table_index = 2; - } - - s->dc_table_index = 1; - s->mv_table_index = 1; /* only if P frame */ - s->use_skip_mb_code = 1; /* only if P frame */ - s->per_mb_rl_table = 0; - if(s->msmpeg4_version==4) - s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==FF_P_TYPE); -//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height); - - if (s->pict_type == FF_I_TYPE) { - s->slice_height= s->mb_height/1; - put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height); - - if(s->msmpeg4_version==4){ - msmpeg4_encode_ext_header(s); - if(s->bit_rate>MBAC_BITRATE) - put_bits(&s->pb, 1, s->per_mb_rl_table); - } - - if(s->msmpeg4_version>2){ - if(!s->per_mb_rl_table){ - ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); - ff_msmpeg4_code012(&s->pb, s->rl_table_index); - } - - put_bits(&s->pb, 1, s->dc_table_index); - } - } else { - put_bits(&s->pb, 1, s->use_skip_mb_code); - - if(s->msmpeg4_version==4 && s->bit_rate>MBAC_BITRATE) - put_bits(&s->pb, 1, s->per_mb_rl_table); - - if(s->msmpeg4_version>2){ - if(!s->per_mb_rl_table) - ff_msmpeg4_code012(&s->pb, s->rl_table_index); - - put_bits(&s->pb, 1, s->dc_table_index); - - put_bits(&s->pb, 1, s->mv_table_index); - } - } - - s->esc3_level_length= 0; - s->esc3_run_length= 0; -} - -void msmpeg4_encode_ext_header(MpegEncContext * s) -{ - put_bits(&s->pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 - - put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); - - if(s->msmpeg4_version>=3) - put_bits(&s->pb, 1, s->flipflop_rounding); - else - assert(s->flipflop_rounding==0); -} - -#endif //CONFIG_ENCODERS - -/* predict coded block */ -int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) -{ - int xy, wrap, pred, a, b, c; - - xy = s->block_index[n]; - wrap = s->b8_stride; - - /* B C - * A X - */ - a = s->coded_block[xy - 1 ]; - b = s->coded_block[xy - 1 - wrap]; - c = s->coded_block[xy - wrap]; - - if (b == c) { - pred = a; - } else { - pred = c; - } - - /* store value */ - *coded_block_ptr = &s->coded_block[xy]; - - return pred; -} - -#if CONFIG_ENCODERS - -void ff_msmpeg4_encode_motion(MpegEncContext * s, - int mx, int my) -{ - int code; - MVTable *mv; - - /* modulo encoding */ - /* WARNING : you cannot reach all the MVs even with the modulo - encoding. This is a somewhat strange compromise they took !!! */ - if (mx <= -64) - mx += 64; - else if (mx >= 64) - mx -= 64; - if (my <= -64) - my += 64; - else if (my >= 64) - my -= 64; - - mx += 32; - my += 32; -#if 0 - if ((unsigned)mx >= 64 || - (unsigned)my >= 64) - av_log(s->avctx, AV_LOG_ERROR, "error mx=%d my=%d\n", mx, my); -#endif - mv = &mv_tables[s->mv_table_index]; - - code = mv->table_mv_index[(mx << 6) | my]; - put_bits(&s->pb, - mv->table_mv_bits[code], - mv->table_mv_code[code]); - if (code == mv->n) { - /* escape : code literally */ - put_bits(&s->pb, 6, mx); - put_bits(&s->pb, 6, my); - } -} - -void ff_msmpeg4_handle_slices(MpegEncContext *s){ - if (s->mb_x == 0) { - if (s->slice_height && (s->mb_y % s->slice_height) == 0) { - if(s->msmpeg4_version < 4){ - ff_mpeg4_clean_buffers(s); - } - s->first_slice_line = 1; - } else { - s->first_slice_line = 0; - } - } -} - -static void msmpeg4v2_encode_motion(MpegEncContext * s, int val) -{ - int range, 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 = s->f_code - 1; - range = 1 << bit_size; - if (val <= -64) - val += 64; - else if (val >= 64) - val -= 64; - - if (val >= 0) { - sign = 0; - } else { - val = -val; - 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); - } - } -} - -void msmpeg4_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y) -{ - int cbp, coded_cbp, i; - int pred_x, pred_y; - uint8_t *coded_block; - - ff_msmpeg4_handle_slices(s); - - if (!s->mb_intra) { - /* compute cbp */ - cbp = 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } - if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) { - /* skip macroblock */ - put_bits(&s->pb, 1, 1); - s->last_bits++; - s->misc_bits++; - s->skip_count++; - - return; - } - if (s->use_skip_mb_code) - put_bits(&s->pb, 1, 0); /* mb coded */ - - if(s->msmpeg4_version<=2){ - put_bits(&s->pb, - v2_mb_type[cbp&3][1], - v2_mb_type[cbp&3][0]); - if((cbp&3) != 3) coded_cbp= cbp ^ 0x3C; - else coded_cbp= cbp; - - put_bits(&s->pb, - ff_h263_cbpy_tab[coded_cbp>>2][1], - ff_h263_cbpy_tab[coded_cbp>>2][0]); - - s->misc_bits += get_bits_diff(s); - - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - msmpeg4v2_encode_motion(s, motion_x - pred_x); - msmpeg4v2_encode_motion(s, motion_y - pred_y); - }else{ - put_bits(&s->pb, - table_mb_non_intra[cbp + 64][1], - table_mb_non_intra[cbp + 64][0]); - - s->misc_bits += get_bits_diff(s); - - /* motion vector */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - ff_msmpeg4_encode_motion(s, motion_x - pred_x, - motion_y - pred_y); - } - - s->mv_bits += get_bits_diff(s); - - for (i = 0; i < 6; i++) { - ff_msmpeg4_encode_block(s, block[i], i); - } - s->p_tex_bits += get_bits_diff(s); - } else { - /* compute cbp */ - cbp = 0; - coded_cbp = 0; - for (i = 0; i < 6; i++) { - int val, pred; - val = (s->block_last_index[i] >= 1); - cbp |= val << (5 - i); - if (i < 4) { - /* predict value for close blocks only for luma */ - pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); - *coded_block = val; - val = val ^ pred; - } - coded_cbp |= val << (5 - i); - } -#if 0 - if (coded_cbp) - printf("cbp=%x %x\n", cbp, coded_cbp); -#endif - - if(s->msmpeg4_version<=2){ - if (s->pict_type == FF_I_TYPE) { - put_bits(&s->pb, - v2_intra_cbpc[cbp&3][1], v2_intra_cbpc[cbp&3][0]); - } else { - if (s->use_skip_mb_code) - put_bits(&s->pb, 1, 0); /* mb coded */ - put_bits(&s->pb, - v2_mb_type[(cbp&3) + 4][1], - v2_mb_type[(cbp&3) + 4][0]); - } - put_bits(&s->pb, 1, 0); /* no AC prediction yet */ - put_bits(&s->pb, - ff_h263_cbpy_tab[cbp>>2][1], - ff_h263_cbpy_tab[cbp>>2][0]); - }else{ - if (s->pict_type == FF_I_TYPE) { - put_bits(&s->pb, - ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); - } else { - if (s->use_skip_mb_code) - put_bits(&s->pb, 1, 0); /* mb coded */ - put_bits(&s->pb, - table_mb_non_intra[cbp][1], - table_mb_non_intra[cbp][0]); - } - put_bits(&s->pb, 1, 0); /* no AC prediction yet */ - if(s->inter_intra_pred){ - s->h263_aic_dir=0; - put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); - } - } - s->misc_bits += get_bits_diff(s); - - for (i = 0; i < 6; i++) { - ff_msmpeg4_encode_block(s, block[i], i); - } - s->i_tex_bits += get_bits_diff(s); - s->i_count++; - } -} - -#endif //CONFIG_ENCODERS - -static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n, - int32_t **dc_val_ptr) -{ - int i; - - if (n < 4) { - i= 0; - } else { - i= n-3; - } - - *dc_val_ptr= &s->last_dc[i]; - return s->last_dc[i]; -} - -static int get_dc(uint8_t *src, int stride, int scale) -{ - int y; - int sum=0; - for(y=0; y<8; y++){ - int x; - for(x=0; x<8; x++){ - sum+=src[x + y*stride]; - } - } - return FASTDIV((sum + (scale>>1)), scale); -} - -/* dir = 0: left, dir = 1: top prediction */ -static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, - int16_t **dc_val_ptr, int *dir_ptr) -{ - int a, b, c, wrap, pred, scale; - int16_t *dc_val; - - /* find prediction */ - if (n < 4) { - scale = s->y_dc_scale; - } else { - scale = s->c_dc_scale; - } - - 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]; - - if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){ - b=c=1024; - } - - /* XXX: the following solution consumes divisions, but it does not - necessitate to modify mpegvideo.c. The problem comes from the - fact they decided to store the quantized DC (which would lead - to problems if Q could vary !) */ -#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE - __asm__ volatile( - "movl %3, %%eax \n\t" - "shrl $1, %%eax \n\t" - "addl %%eax, %2 \n\t" - "addl %%eax, %1 \n\t" - "addl %0, %%eax \n\t" - "mull %4 \n\t" - "movl %%edx, %0 \n\t" - "movl %1, %%eax \n\t" - "mull %4 \n\t" - "movl %%edx, %1 \n\t" - "movl %2, %%eax \n\t" - "mull %4 \n\t" - "movl %%edx, %2 \n\t" - : "+b" (a), "+c" (b), "+D" (c) - : "g" (scale), "S" (ff_inverse[scale]) - : "%eax", "%edx" - ); -#else - /* #elif ARCH_ALPHA */ - /* Divisions are extremely costly on Alpha; optimize the most - common case. But they are costly everywhere... - */ - if (scale == 8) { - a = (a + (8 >> 1)) / 8; - b = (b + (8 >> 1)) / 8; - c = (c + (8 >> 1)) / 8; - } else { - a = FASTDIV((a + (scale >> 1)), scale); - b = FASTDIV((b + (scale >> 1)), scale); - c = FASTDIV((c + (scale >> 1)), scale); - } -#endif - /* XXX: WARNING: they did not choose the same test as MPEG4. This - is very important ! */ - if(s->msmpeg4_version>3){ - if(s->inter_intra_pred){ - uint8_t *dest; - int wrap; - - if(n==1){ - pred=a; - *dir_ptr = 0; - }else if(n==2){ - pred=c; - *dir_ptr = 1; - }else if(n==3){ - if (abs(a - b) < abs(b - c)) { - pred = c; - *dir_ptr = 1; - } else { - pred = a; - *dir_ptr = 0; - } - }else{ - if(n<4){ - wrap= s->linesize; - dest= s->current_picture.data[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8; - }else{ - wrap= s->uvlinesize; - dest= s->current_picture.data[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8; - } - if(s->mb_x==0) a= (1024 + (scale>>1))/scale; - else a= get_dc(dest-8, wrap, scale*8); - if(s->mb_y==0) c= (1024 + (scale>>1))/scale; - else c= get_dc(dest-8*wrap, wrap, scale*8); - - if (s->h263_aic_dir==0) { - pred= a; - *dir_ptr = 0; - }else if (s->h263_aic_dir==1) { - if(n==0){ - pred= c; - *dir_ptr = 1; - }else{ - pred= a; - *dir_ptr = 0; - } - }else if (s->h263_aic_dir==2) { - if(n==0){ - pred= a; - *dir_ptr = 0; - }else{ - pred= c; - *dir_ptr = 1; - } - } else { - pred= c; - *dir_ptr = 1; - } - } - }else{ - if (abs(a - b) < abs(b - c)) { - pred = c; - *dir_ptr = 1; - } else { - pred = a; - *dir_ptr = 0; - } - } - }else{ - if (abs(a - b) <= abs(b - c)) { - pred = c; - *dir_ptr = 1; - } else { - pred = a; - *dir_ptr = 0; - } - } - - /* update predictor */ - *dc_val_ptr = &dc_val[0]; - return pred; -} - -#define DC_MAX 119 - -static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr) -{ - int sign, code; - int pred, extquant; - int extrabits = 0; - - if(s->msmpeg4_version==1){ - int32_t *dc_val; - pred = msmpeg4v1_pred_dc(s, n, &dc_val); - - /* update predictor */ - *dc_val= level; - }else{ - int16_t *dc_val; - pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); - - /* update predictor */ - if (n < 4) { - *dc_val = level * s->y_dc_scale; - } else { - *dc_val = level * s->c_dc_scale; - } - } - - /* do the prediction */ - level -= pred; - - if(s->msmpeg4_version<=2){ - if (n < 4) { - put_bits(&s->pb, - v2_dc_lum_table[level+256][1], - v2_dc_lum_table[level+256][0]); - }else{ - put_bits(&s->pb, - v2_dc_chroma_table[level+256][1], - v2_dc_chroma_table[level+256][0]); - } - }else{ - sign = 0; - if (level < 0) { - level = -level; - sign = 1; - } - code = level; - if (code > DC_MAX) - code = DC_MAX; - else if( s->msmpeg4_version>=6 ) { - if( s->qscale == 1 ) { - extquant = (level + 3) & 0x3; - code = ((level+3)>>2); - } else if( s->qscale == 2 ) { - extquant = (level + 1) & 0x1; - code = ((level+1)>>1); - } - } - - if (s->dc_table_index == 0) { - if (n < 4) { - put_bits(&s->pb, ff_table0_dc_lum[code][1], ff_table0_dc_lum[code][0]); - } else { - put_bits(&s->pb, ff_table0_dc_chroma[code][1], ff_table0_dc_chroma[code][0]); - } - } else { - if (n < 4) { - put_bits(&s->pb, ff_table1_dc_lum[code][1], ff_table1_dc_lum[code][0]); - } else { - put_bits(&s->pb, ff_table1_dc_chroma[code][1], ff_table1_dc_chroma[code][0]); - } - } - - if(s->msmpeg4_version>=6 && s->qscale<=2) - extrabits = 3 - s->qscale; - - if (code == DC_MAX) - put_bits(&s->pb, 8 + extrabits, level); - else if(extrabits > 0)//== VC1 && s->qscale<=2 - put_bits(&s->pb, extrabits, extquant); - - if (level != 0) { - put_bits(&s->pb, 1, sign); - } - } -} - -/* Encoding of a block. Very similar to MPEG4 except for a different - escape coding (same as H263) and more vlc tables. - */ -void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) -{ - int level, run, last, i, j, last_index; - int last_non_zero, sign, slevel; - int code, run_diff, dc_pred_dir; - const RLTable *rl; - const uint8_t *scantable; - - if (s->mb_intra) { - msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir); - i = 1; - if (n < 4) { - rl = &rl_table[s->rl_table_index]; - } else { - rl = &rl_table[3 + s->rl_chroma_table_index]; - } - run_diff = s->msmpeg4_version>=4; - scantable= s->intra_scantable.permutated; - } else { - i = 0; - rl = &rl_table[3 + s->rl_table_index]; - if(s->msmpeg4_version<=2) - run_diff = 0; - else - run_diff = 1; - scantable= s->inter_scantable.permutated; - } - - /* recalculate block_last_index for M$ wmv1 */ - if(s->msmpeg4_version>=4 && s->msmpeg4_version<6 && s->block_last_index[n]>0){ - for(last_index=63; last_index>=0; last_index--){ - if(block[scantable[last_index]]) break; - } - s->block_last_index[n]= last_index; - }else - last_index = s->block_last_index[n]; - /* AC coefs */ - last_non_zero = i - 1; - for (; i <= last_index; i++) { - j = scantable[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; - } - - if(level<=MAX_LEVEL && run<=MAX_RUN){ - s->ac_stats[s->mb_intra][n>3][level][run][last]++; - } -#if 0 -else - s->ac_stats[s->mb_intra][n>3][40][63][0]++; //esc3 like -#endif - 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) { - 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(&s->pb, 1, 0); - if (level > MAX_LEVEL) - goto esc3; - run1 = run - rl->max_run[last][level] - run_diff; - if (run1 < 0) - goto esc3; - code = get_rl_index(rl, last, run1+1, level); - if (s->msmpeg4_version == 4 && code == rl->n) - goto esc3; - code = get_rl_index(rl, last, run1, level); - if (code == rl->n) { - esc3: - /* third escape */ - put_bits(&s->pb, 1, 0); - put_bits(&s->pb, 1, last); - if(s->msmpeg4_version>=4){ - if(s->esc3_level_length==0){ - s->esc3_level_length=8; - s->esc3_run_length= 6; - //ESCLVLSZ + ESCRUNSZ - if(s->qscale<8) - put_bits(&s->pb, 6 + (s->msmpeg4_version>=6), 3); - else - put_bits(&s->pb, 8, 3); - } - put_bits(&s->pb, s->esc3_run_length, run); - put_bits(&s->pb, 1, sign); - put_bits(&s->pb, s->esc3_level_length, level); - }else{ - put_bits(&s->pb, 6, run); - put_sbits(&s->pb, 8, slevel); - } - } else { - /* second escape */ - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(&s->pb, 1, sign); - } - } else { - /* first escape */ - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(&s->pb, 1, sign); - } - } else { - put_bits(&s->pb, 1, sign); - } - last_non_zero = i; - } - } -} - -/****************************************/ -/* decoding stuff */ - -VLC ff_mb_non_intra_vlc[4]; -static VLC v2_dc_lum_vlc; -static VLC v2_dc_chroma_vlc; -static VLC v2_intra_cbpc_vlc; -static VLC v2_mb_type_vlc; -static VLC v2_mv_vlc; -VLC ff_inter_intra_vlc; - -/* This is identical to h263 except that its range is multiplied by 2. */ -static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) -{ - int code, val, sign, shift; - - code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2); -// printf("MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred); - if (code < 0) - return 0xffff; - - if (code == 0) - return pred; - 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; - if (val <= -64) - val += 64; - else if (val >= 64) - val -= 64; - - return val; -} - -static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) -{ - int cbp, code, i; - - if (s->pict_type == FF_P_TYPE) { - if (s->use_skip_mb_code) { - 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->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - return 0; - } - } - - if(s->msmpeg4_version==2) - code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1); - else - code = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); - if(code<0 || code>7){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y); - return -1; - } - - s->mb_intra = code >>2; - - cbp = code & 0x3; - } else { - s->mb_intra = 1; - if(s->msmpeg4_version==2) - cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1); - else - cbp= get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1); - if(cbp<0 || cbp>3){ - av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; - } - } - - if (!s->mb_intra) { - int mx, my, cbpy; - - cbpy= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1); - if(cbpy<0){ - av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); - return -1; - } - - cbp|= cbpy<<2; - if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C; - - h263_pred_motion(s, 0, 0, &mx, &my); - mx= msmpeg4v2_decode_motion(s, mx, 1); - my= msmpeg4v2_decode_motion(s, my, 1); - - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - } else { - if(s->msmpeg4_version==2){ - s->ac_pred = get_bits1(&s->gb); - cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors - } else{ - s->ac_pred = 0; - cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors - if(s->pict_type==FF_P_TYPE) cbp^=0x3C; - } - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - return 0; -} - -static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) -{ - int cbp, code, i; - uint8_t *coded_val; - uint32_t * const mb_type_ptr= &s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]; - - if (s->pict_type == FF_P_TYPE) { - if (s->use_skip_mb_code) { - 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->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; - - return 0; - } - } - - code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); - if (code < 0) - return -1; - //s->mb_intra = (code & 0x40) ? 0 : 1; - s->mb_intra = (~code & 0x40) >> 6; - - cbp = code & 0x3f; - } else { - s->mb_intra = 1; - code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if (code < 0) - return -1; - /* predict coded block pattern */ - cbp = 0; - for(i=0;i<6;i++) { - int val = ((code >> (5 - i)) & 1); - if (i < 4) { - int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); - val = val ^ pred; - *coded_val = val; - } - cbp |= val << (5 - i); - } - } - - if (!s->mb_intra) { - int mx, my; -//printf("P at %d %d\n", s->mb_x, s->mb_y); - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - h263_pred_motion(s, 0, 0, &mx, &my); - if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0) - return -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16; - } else { -//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); - s->ac_pred = get_bits1(&s->gb); - *mb_type_ptr = MB_TYPE_INTRA; - if(s->inter_intra_pred){ - s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); -// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); - } - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - - return 0; -} - -/* init all vlc decoding tables */ -av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - static int done = 0; - int i; - MVTable *mv; - - ff_h263_decode_init(avctx); - - common_init(s); - - if (!done) { - done = 1; - - for(i=0;ivlc, MV_VLC_BITS, mv->n + 1, - mv->table_mv_bits, 1, 1, - mv->table_mv_code, 2, 2, 3714); - mv = &mv_tables[1]; - INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1, - mv->table_mv_bits, 1, 1, - mv->table_mv_code, 2, 2, 2694); - - INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120, - &ff_table0_dc_lum[0][1], 8, 4, - &ff_table0_dc_lum[0][0], 8, 4, 1158); - INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120, - &ff_table0_dc_chroma[0][1], 8, 4, - &ff_table0_dc_chroma[0][0], 8, 4, 1118); - INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120, - &ff_table1_dc_lum[0][1], 8, 4, - &ff_table1_dc_lum[0][0], 8, 4, 1476); - INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120, - &ff_table1_dc_chroma[0][1], 8, 4, - &ff_table1_dc_chroma[0][0], 8, 4, 1216); - - INIT_VLC_STATIC(&v2_dc_lum_vlc, DC_VLC_BITS, 512, - &v2_dc_lum_table[0][1], 8, 4, - &v2_dc_lum_table[0][0], 8, 4, 1472); - INIT_VLC_STATIC(&v2_dc_chroma_vlc, DC_VLC_BITS, 512, - &v2_dc_chroma_table[0][1], 8, 4, - &v2_dc_chroma_table[0][0], 8, 4, 1506); - - INIT_VLC_STATIC(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4, - &v2_intra_cbpc[0][1], 2, 1, - &v2_intra_cbpc[0][0], 2, 1, 8); - INIT_VLC_STATIC(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8, - &v2_mb_type[0][1], 2, 1, - &v2_mb_type[0][0], 2, 1, 128); - INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 538); - - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128, - &wmv2_inter_table[0][0][1], 8, 4, - &wmv2_inter_table[0][0][0], 8, 4, 1636); - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128, - &wmv2_inter_table[1][0][1], 8, 4, - &wmv2_inter_table[1][0][0], 8, 4, 2648); - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128, - &wmv2_inter_table[2][0][1], 8, 4, - &wmv2_inter_table[2][0][0], 8, 4, 1532); - INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128, - &wmv2_inter_table[3][0][1], 8, 4, - &wmv2_inter_table[3][0][0], 8, 4, 2488); - - INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64, - &ff_msmp4_mb_i_table[0][1], 4, 2, - &ff_msmp4_mb_i_table[0][0], 4, 2, 536); - - INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, - &table_inter_intra[0][1], 2, 1, - &table_inter_intra[0][0], 2, 1, 8); - } - - switch(s->msmpeg4_version){ - case 1: - case 2: - s->decode_mb= msmpeg4v12_decode_mb; - break; - case 3: - case 4: - s->decode_mb= msmpeg4v34_decode_mb; - break; - case 5: - if (CONFIG_WMV2_DECODER) - s->decode_mb= ff_wmv2_decode_mb; - case 6: - //FIXME + TODO VC1 decode mb - break; - } - - s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe - - return 0; -} - -int msmpeg4_decode_picture_header(MpegEncContext * s) -{ - int code; - -#if 0 -{ -int i; -for(i=0; igb.size_in_bits; i++) - av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb)); -// get_bits1(&s->gb); -av_log(s->avctx, AV_LOG_DEBUG, "END\n"); -return -1; -} -#endif - - if(s->msmpeg4_version==1){ - int start_code; - start_code = (get_bits(&s->gb, 16)<<16) | get_bits(&s->gb, 16); - if(start_code!=0x00000100){ - av_log(s->avctx, AV_LOG_ERROR, "invalid startcode\n"); - return -1; - } - - skip_bits(&s->gb, 5); // frame number */ - } - - s->pict_type = get_bits(&s->gb, 2) + 1; - if (s->pict_type != FF_I_TYPE && - s->pict_type != FF_P_TYPE){ - av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n"); - return -1; - } -#if 0 -{ - static int had_i=0; - if(s->pict_type == FF_I_TYPE) had_i=1; - if(!had_i) return -1; -} -#endif - s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); - if(s->qscale==0){ - av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n"); - return -1; - } - - if (s->pict_type == FF_I_TYPE) { - code = get_bits(&s->gb, 5); - if(s->msmpeg4_version==1){ - if(code==0 || code>s->mb_height){ - av_log(s->avctx, AV_LOG_ERROR, "invalid slice height %d\n", code); - return -1; - } - - s->slice_height = code; - }else{ - /* 0x17: one slice, 0x18: two slices, ... */ - if (code < 0x17){ - av_log(s->avctx, AV_LOG_ERROR, "error, slice code was %X\n", code); - return -1; - } - - s->slice_height = s->mb_height / (code - 0x16); - } - - switch(s->msmpeg4_version){ - case 1: - case 2: - s->rl_chroma_table_index = 2; - s->rl_table_index = 2; - - s->dc_table_index = 0; //not used - break; - case 3: - s->rl_chroma_table_index = decode012(&s->gb); - s->rl_table_index = decode012(&s->gb); - - s->dc_table_index = get_bits1(&s->gb); - break; - case 4: - msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8); - - if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_chroma_table_index = decode012(&s->gb); - s->rl_table_index = decode012(&s->gb); - } - - s->dc_table_index = get_bits1(&s->gb); - s->inter_intra_pred= 0; - break; - } - s->no_rounding = 1; - if(s->avctx->debug&FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n", - s->qscale, - s->rl_chroma_table_index, - s->rl_table_index, - s->dc_table_index, - s->per_mb_rl_table, - s->slice_height); - } else { - switch(s->msmpeg4_version){ - case 1: - case 2: - if(s->msmpeg4_version==1) - s->use_skip_mb_code = 1; - else - s->use_skip_mb_code = get_bits1(&s->gb); - s->rl_table_index = 2; - s->rl_chroma_table_index = s->rl_table_index; - s->dc_table_index = 0; //not used - s->mv_table_index = 0; - break; - case 3: - s->use_skip_mb_code = get_bits1(&s->gb); - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - - s->dc_table_index = get_bits1(&s->gb); - - s->mv_table_index = get_bits1(&s->gb); - break; - case 4: - s->use_skip_mb_code = get_bits1(&s->gb); - - if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - s->dc_table_index = get_bits1(&s->gb); - - s->mv_table_index = get_bits1(&s->gb); - s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); - break; - } - - if(s->avctx->debug&FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n", - s->use_skip_mb_code, - s->rl_table_index, - s->rl_chroma_table_index, - s->dc_table_index, - s->mv_table_index, - s->per_mb_rl_table, - s->qscale); - - if(s->flipflop_rounding){ - s->no_rounding ^= 1; - }else{ - s->no_rounding = 0; - } - } -//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height); - - s->esc3_level_length= 0; - s->esc3_run_length= 0; - - return 0; -} - -int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size) -{ - int left= buf_size*8 - get_bits_count(&s->gb); - int length= s->msmpeg4_version>=3 ? 17 : 16; - /* the alt_bitstream reader could read over the end so we need to check it */ - if(left>=length && leftgb, 5); - s->bit_rate= get_bits(&s->gb, 11)*1024; - if(s->msmpeg4_version>=3) - s->flipflop_rounding= get_bits1(&s->gb); - else - s->flipflop_rounding= 0; - -// printf("fps:%2d bps:%2d roundingType:%1d\n", fps, s->bit_rate/1024, s->flipflop_rounding); - } - else if(leftflipflop_rounding= 0; - if(s->msmpeg4_version != 2) - av_log(s->avctx, AV_LOG_ERROR, "ext header missing, %d left\n", left); - } - else - { - av_log(s->avctx, AV_LOG_ERROR, "I frame too long, ignoring ext header\n"); - } - - return 0; -} - -static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) -{ - int level, pred; - - if(s->msmpeg4_version<=2){ - if (n < 4) { - level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3); - } else { - level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3); - } - if (level < 0) - return -1; - level-=256; - }else{ //FIXME optimize use unified tables & index - if (n < 4) { - level = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } else { - level = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } - if (level < 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); - return -1; - } - - if (level == DC_MAX) { - level = get_bits(&s->gb, 8); - if (get_bits1(&s->gb)) - level = -level; - } else if (level != 0) { - if (get_bits1(&s->gb)) - level = -level; - } - } - - if(s->msmpeg4_version==1){ - int32_t *dc_val; - pred = msmpeg4v1_pred_dc(s, n, &dc_val); - level += pred; - - /* update predictor */ - *dc_val= level; - }else{ - int16_t *dc_val; - pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); - level += pred; - - /* update predictor */ - if (n < 4) { - *dc_val = level * s->y_dc_scale; - } else { - *dc_val = level * s->c_dc_scale; - } - } - - return level; -} - -//#define ERROR_DETAILS -int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, const uint8_t *scan_table) -{ - int level, i, last, run, run_diff; - int av_uninit(dc_pred_dir); - RLTable *rl; - RL_VLC_ELEM *rl_vlc; - int qmul, qadd; - - if (s->mb_intra) { - qmul=1; - qadd=0; - - /* DC coef */ - level = msmpeg4_decode_dc(s, n, &dc_pred_dir); - - if (level < 0){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale); - if(s->inter_intra_pred) level=0; - else return -1; - } - if (n < 4) { - rl = &rl_table[s->rl_table_index]; - if(level > 256*s->y_dc_scale){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale); - if(!s->inter_intra_pred) return -1; - } - } else { - rl = &rl_table[3 + s->rl_chroma_table_index]; - if(level > 256*s->c_dc_scale){ - av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale); - if(!s->inter_intra_pred) return -1; - } - } - block[0] = level; - - run_diff = s->msmpeg4_version >= 4; - i = 0; - if (!coded) { - goto not_coded; - } - if (s->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; - } - rl_vlc= rl->rl_vlc[0]; - } else { - qmul = s->qscale << 1; - qadd = (s->qscale - 1) | 1; - i = -1; - rl = &rl_table[3 + s->rl_table_index]; - - if(s->msmpeg4_version==2) - run_diff = 0; - else - run_diff = 1; - - if (!coded) { - s->block_last_index[n] = i; - return 0; - } - if(!scan_table) - scan_table = s->inter_scantable.permutated; - rl_vlc= rl->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) { - int cache; - cache= GET_CACHE(re, &s->gb); - /* escape */ - if (s->msmpeg4_version==1 || (cache&0x80000000)==0) { - if (s->msmpeg4_version==1 || (cache&0x40000000)==0) { - /* third escape */ - if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2); - UPDATE_CACHE(re, &s->gb); - if(s->msmpeg4_version<=3){ - last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); - run= SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6); - level= SHOW_SBITS(re, &s->gb, 8); LAST_SKIP_CACHE(re, &s->gb, 8); - SKIP_COUNTER(re, &s->gb, 1+6+8); - }else{ - int sign; - last= SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1); - if(!s->esc3_level_length){ - int ll; - //printf("ESC-3 %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y); - if(s->qscale<8){ - ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3); - if(ll==0){ - ll= 8+SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1); - } - }else{ - ll=2; - while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){ - ll++; - SKIP_BITS(re, &s->gb, 1); - } - if(ll<8) SKIP_BITS(re, &s->gb, 1); - } - - s->esc3_level_length= ll; - s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2); -//printf("level length:%d, run length: %d\n", ll, s->esc3_run_length); - UPDATE_CACHE(re, &s->gb); - } - run= SHOW_UBITS(re, &s->gb, s->esc3_run_length); - SKIP_BITS(re, &s->gb, s->esc3_run_length); - - sign= SHOW_UBITS(re, &s->gb, 1); - SKIP_BITS(re, &s->gb, 1); - - level= SHOW_UBITS(re, &s->gb, s->esc3_level_length); - SKIP_BITS(re, &s->gb, s->esc3_level_length); - if(sign) level= -level; - } -//printf("level: %d, run: %d at %d %d\n", level, run, s->mb_x, s->mb_y); -#if 0 // waste of time / this will detect very few errors - { - const int abs_level= FFABS(level); - const int run1= run - rl->max_run[last][abs_level] - run_diff; - if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ - if(abs_level <= rl->max_level[last][run]){ - av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); - return DECODING_AC_LOST; - } - 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 DECODING_AC_LOST; - } - 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 DECODING_AC_LOST; - } - } - } -#endif - //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ; - if (level>0) level= level * qmul + qadd; - else level= level * qmul - qadd; -#if 0 // waste of time too :( - if(level>2048 || level<-2048){ - av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc\n"); - return DECODING_AC_LOST; - } -#endif - i+= run + 1; - if(last) i+=192; -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC3 level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level); -#endif - } else { - /* second escape */ -#if MIN_CACHE_BITS < 23 - 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] + run_diff; //FIXME opt indexing - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC2 level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level); -#endif - } - } else { - /* first escape */ -#if MIN_CACHE_BITS < 22 - 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); -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC1 level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level); -#endif - } - } else { - i+= run; - level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); - LAST_SKIP_BITS(re, &s->gb, 1); -#ifdef ERROR_DETAILS - if(run==66) - av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code level=%d\n", level); - else if((i>62 && i<192) || i>192+63) - av_log(s->avctx, AV_LOG_ERROR, "run overflow i=%d run=%d level=%d\n", i, run, level); -#endif - } - if (i > 62){ - i-= 192; - if(i&(~63)){ - const int left= get_bits_left(&s->gb); - if(((i+192 == 64 && level/qmul==-1) || s->error_recognition<=1) && left>=0){ - av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y); - break; - }else{ - 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 (s->mb_intra) { - mpeg4_pred_ac(s, block, n, dc_pred_dir); - if (s->ac_pred) { - i = 63; /* XXX: not optimal */ - } - } - if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize - s->block_last_index[n] = i; - - return 0; -} - -int ff_msmpeg4_decode_motion(MpegEncContext * s, - int *mx_ptr, int *my_ptr) -{ - MVTable *mv; - int code, mx, my; - - mv = &mv_tables[s->mv_table_index]; - - code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal MV code at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - if (code == mv->n) { -//printf("MV ESC %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y); - mx = get_bits(&s->gb, 6); - my = get_bits(&s->gb, 6); - } else { - mx = mv->table_mvx[code]; - my = mv->table_mvy[code]; - } - - mx += *mx_ptr - 32; - my += *my_ptr - 32; - /* WARNING : they do not do exactly modulo encoding */ - if (mx <= -64) - mx += 64; - else if (mx >= 64) - mx -= 64; - - if (my <= -64) - my += 64; - else if (my >= 64) - my -= 64; - *mx_ptr = mx; - *my_ptr = my; - return 0; -} - -AVCodec msmpeg4v1_decoder = { - "msmpeg4v1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSMPEG4V1, - sizeof(MpegEncContext), - ff_msmpeg4_decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"), - .pix_fmts= ff_pixfmt_list_420, -}; - -AVCodec msmpeg4v2_decoder = { - "msmpeg4v2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSMPEG4V2, - sizeof(MpegEncContext), - ff_msmpeg4_decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), - .pix_fmts= ff_pixfmt_list_420, -}; - -AVCodec msmpeg4v3_decoder = { - "msmpeg4", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSMPEG4V3, - sizeof(MpegEncContext), - ff_msmpeg4_decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), - .pix_fmts= ff_pixfmt_list_420, -}; - -AVCodec wmv1_decoder = { - "wmv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WMV1, - sizeof(MpegEncContext), - ff_msmpeg4_decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"), - .pix_fmts= ff_pixfmt_list_420, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/msmpeg4.h b/tizen/distrib/ffmpeg/libavcodec/msmpeg4.h deleted file mode 100644 index 28372a0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msmpeg4.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * MSMPEG4 backend for ffmpeg encoder and decoder - * copyright (c) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - */ - -#ifndef AVCODEC_MSMPEG4_H -#define AVCODEC_MSMPEG4_H - -#include "config.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - -#define INTER_INTRA_VLC_BITS 3 -#define MB_NON_INTRA_VLC_BITS 9 -#define MB_INTRA_VLC_BITS 9 - -extern VLC ff_mb_non_intra_vlc[4]; -extern VLC ff_inter_intra_vlc; - -void ff_msmpeg4_code012(PutBitContext *pb, int n); -void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n); -void ff_msmpeg4_handle_slices(MpegEncContext *s); -void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my); -int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, - uint8_t **coded_block_ptr); -int ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); -int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, const uint8_t *scan_table); -int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); - -#define CONFIG_MSMPEG4_DECODER (CONFIG_MSMPEG4V1_DECODER || \ - CONFIG_MSMPEG4V2_DECODER || \ - CONFIG_MSMPEG4V3_DECODER || \ - CONFIG_WMV2_DECODER || \ - CONFIG_VC1_DECODER) -#define CONFIG_MSMPEG4_ENCODER (CONFIG_MSMPEG4V1_ENCODER || \ - CONFIG_MSMPEG4V2_ENCODER || \ - CONFIG_MSMPEG4V3_ENCODER || \ - CONFIG_WMV2_ENCODER) - -#endif /* AVCODEC_MSMPEG4_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/msmpeg4data.c b/tizen/distrib/ffmpeg/libavcodec/msmpeg4data.c deleted file mode 100644 index f72715d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msmpeg4data.c +++ /dev/null @@ -1,2001 +0,0 @@ -/* - * MSMPEG4 backend for ffmpeg encoder and decoder - * copyright (c) 2001 Fabrice Bellard - * copyright (c) 2002-2004 Michael Niedermayer - * - * msmpeg4v1 & v2 stuff by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MSMPEG4 data tables. - */ - -#include "msmpeg4data.h" - -VLC ff_msmp4_mb_i_vlc; -VLC ff_msmp4_dc_luma_vlc[2]; -VLC ff_msmp4_dc_chroma_vlc[2]; - -/* intra picture macroblock coded block pattern */ -const uint16_t ff_msmp4_mb_i_table[64][2] = { -{ 0x1, 1 },{ 0x17, 6 },{ 0x9, 5 },{ 0x5, 5 }, -{ 0x6, 5 },{ 0x47, 9 },{ 0x20, 7 },{ 0x10, 7 }, -{ 0x2, 5 },{ 0x7c, 9 },{ 0x3a, 7 },{ 0x1d, 7 }, -{ 0x2, 6 },{ 0xec, 9 },{ 0x77, 8 },{ 0x0, 8 }, -{ 0x3, 5 },{ 0xb7, 9 },{ 0x2c, 7 },{ 0x13, 7 }, -{ 0x1, 6 },{ 0x168, 10 },{ 0x46, 8 },{ 0x3f, 8 }, -{ 0x1e, 6 },{ 0x712, 13 },{ 0xb5, 9 },{ 0x42, 8 }, -{ 0x22, 7 },{ 0x1c5, 11 },{ 0x11e, 10 },{ 0x87, 9 }, -{ 0x6, 4 },{ 0x3, 9 },{ 0x1e, 7 },{ 0x1c, 6 }, -{ 0x12, 7 },{ 0x388, 12 },{ 0x44, 9 },{ 0x70, 9 }, -{ 0x1f, 6 },{ 0x23e, 11 },{ 0x39, 8 },{ 0x8e, 9 }, -{ 0x1, 7 },{ 0x1c6, 11 },{ 0xb6, 9 },{ 0x45, 9 }, -{ 0x14, 6 },{ 0x23f, 11 },{ 0x7d, 9 },{ 0x18, 9 }, -{ 0x7, 7 },{ 0x1c7, 11 },{ 0x86, 9 },{ 0x19, 9 }, -{ 0x15, 6 },{ 0x1db, 10 },{ 0x2, 9 },{ 0x46, 9 }, -{ 0xd, 8 },{ 0x713, 13 },{ 0x1da, 10 },{ 0x169, 10 }, -}; - -/* non intra picture macroblock coded block pattern + mb type */ -const uint32_t table_mb_non_intra[128][2] = { -{ 0x40, 7 },{ 0x13c9, 13 },{ 0x9fd, 12 },{ 0x1fc, 15 }, -{ 0x9fc, 12 },{ 0xa83, 18 },{ 0x12d34, 17 },{ 0x83bc, 16 }, -{ 0x83a, 12 },{ 0x7f8, 17 },{ 0x3fd, 16 },{ 0x3ff, 16 }, -{ 0x79, 13 },{ 0xa82, 18 },{ 0x969d, 16 },{ 0x2a4, 16 }, -{ 0x978, 12 },{ 0x543, 17 },{ 0x41df, 15 },{ 0x7f9, 17 }, -{ 0x12f3, 13 },{ 0x25a6b, 18 },{ 0x25ef9, 18 },{ 0x3fa, 16 }, -{ 0x20ee, 14 },{ 0x969ab, 20 },{ 0x969c, 16 },{ 0x25ef8, 18 }, -{ 0x12d2, 13 },{ 0xa85, 18 },{ 0x969e, 16 },{ 0x4bc8, 15 }, -{ 0x3d, 12 },{ 0x12f7f, 17 },{ 0x2a2, 16 },{ 0x969f, 16 }, -{ 0x25ee, 14 },{ 0x12d355, 21 },{ 0x12f7d, 17 },{ 0x12f7e, 17 }, -{ 0x9e5, 12 },{ 0xa81, 18 },{ 0x4b4d4, 19 },{ 0x83bd, 16 }, -{ 0x78, 13 },{ 0x969b, 16 },{ 0x3fe, 16 },{ 0x2a5, 16 }, -{ 0x7e, 13 },{ 0xa80, 18 },{ 0x2a3, 16 },{ 0x3fb, 16 }, -{ 0x1076, 13 },{ 0xa84, 18 },{ 0x153, 15 },{ 0x4bc9, 15 }, -{ 0x55, 13 },{ 0x12d354, 21 },{ 0x4bde, 15 },{ 0x25e5, 14 }, -{ 0x25b, 10 },{ 0x4b4c, 15 },{ 0x96b, 12 },{ 0x96a, 12 }, -{ 0x1, 2 },{ 0x0, 7 },{ 0x26, 6 },{ 0x12b, 9 }, -{ 0x7, 3 },{ 0x20f, 10 },{ 0x4, 9 },{ 0x28, 12 }, -{ 0x6, 3 },{ 0x20a, 10 },{ 0x128, 9 },{ 0x2b, 12 }, -{ 0x11, 5 },{ 0x1b, 11 },{ 0x13a, 9 },{ 0x4ff, 11 }, -{ 0x3, 4 },{ 0x277, 10 },{ 0x106, 9 },{ 0x839, 12 }, -{ 0xb, 4 },{ 0x27b, 10 },{ 0x12c, 9 },{ 0x4bf, 11 }, -{ 0x9, 6 },{ 0x35, 12 },{ 0x27e, 10 },{ 0x13c8, 13 }, -{ 0x1, 6 },{ 0x4aa, 11 },{ 0x208, 10 },{ 0x29, 12 }, -{ 0x1, 4 },{ 0x254, 10 },{ 0x12e, 9 },{ 0x838, 12 }, -{ 0x24, 6 },{ 0x4f3, 11 },{ 0x276, 10 },{ 0x12f6, 13 }, -{ 0x1, 5 },{ 0x27a, 10 },{ 0x13e, 9 },{ 0x3e, 12 }, -{ 0x8, 6 },{ 0x413, 11 },{ 0xc, 10 },{ 0x4be, 11 }, -{ 0x14, 5 },{ 0x412, 11 },{ 0x253, 10 },{ 0x97a, 12 }, -{ 0x21, 6 },{ 0x4ab, 11 },{ 0x20b, 10 },{ 0x34, 12 }, -{ 0x15, 5 },{ 0x278, 10 },{ 0x252, 10 },{ 0x968, 12 }, -{ 0x5, 5 },{ 0xb, 10 },{ 0x9c, 8 },{ 0xe, 10 }, -}; - -/* dc table 0 */ - -const uint32_t ff_table0_dc_lum[120][2] = { -{ 0x1, 1 },{ 0x1, 2 },{ 0x1, 4 },{ 0x1, 5 }, -{ 0x5, 5 },{ 0x7, 5 },{ 0x8, 6 },{ 0xc, 6 }, -{ 0x0, 7 },{ 0x2, 7 },{ 0x12, 7 },{ 0x1a, 7 }, -{ 0x3, 8 },{ 0x7, 8 },{ 0x27, 8 },{ 0x37, 8 }, -{ 0x5, 9 },{ 0x4c, 9 },{ 0x6c, 9 },{ 0x6d, 9 }, -{ 0x8, 10 },{ 0x19, 10 },{ 0x9b, 10 },{ 0x1b, 10 }, -{ 0x9a, 10 },{ 0x13, 11 },{ 0x34, 11 },{ 0x35, 11 }, -{ 0x61, 12 },{ 0x48, 13 },{ 0xc4, 13 },{ 0x4a, 13 }, -{ 0xc6, 13 },{ 0xc7, 13 },{ 0x92, 14 },{ 0x18b, 14 }, -{ 0x93, 14 },{ 0x183, 14 },{ 0x182, 14 },{ 0x96, 14 }, -{ 0x97, 14 },{ 0x180, 14 },{ 0x314, 15 },{ 0x315, 15 }, -{ 0x605, 16 },{ 0x604, 16 },{ 0x606, 16 },{ 0xc0e, 17 }, -{ 0x303cd, 23 },{ 0x303c9, 23 },{ 0x303c8, 23 },{ 0x303ca, 23 }, -{ 0x303cb, 23 },{ 0x303cc, 23 },{ 0x303ce, 23 },{ 0x303cf, 23 }, -{ 0x303d0, 23 },{ 0x303d1, 23 },{ 0x303d2, 23 },{ 0x303d3, 23 }, -{ 0x303d4, 23 },{ 0x303d5, 23 },{ 0x303d6, 23 },{ 0x303d7, 23 }, -{ 0x303d8, 23 },{ 0x303d9, 23 },{ 0x303da, 23 },{ 0x303db, 23 }, -{ 0x303dc, 23 },{ 0x303dd, 23 },{ 0x303de, 23 },{ 0x303df, 23 }, -{ 0x303e0, 23 },{ 0x303e1, 23 },{ 0x303e2, 23 },{ 0x303e3, 23 }, -{ 0x303e4, 23 },{ 0x303e5, 23 },{ 0x303e6, 23 },{ 0x303e7, 23 }, -{ 0x303e8, 23 },{ 0x303e9, 23 },{ 0x303ea, 23 },{ 0x303eb, 23 }, -{ 0x303ec, 23 },{ 0x303ed, 23 },{ 0x303ee, 23 },{ 0x303ef, 23 }, -{ 0x303f0, 23 },{ 0x303f1, 23 },{ 0x303f2, 23 },{ 0x303f3, 23 }, -{ 0x303f4, 23 },{ 0x303f5, 23 },{ 0x303f6, 23 },{ 0x303f7, 23 }, -{ 0x303f8, 23 },{ 0x303f9, 23 },{ 0x303fa, 23 },{ 0x303fb, 23 }, -{ 0x303fc, 23 },{ 0x303fd, 23 },{ 0x303fe, 23 },{ 0x303ff, 23 }, -{ 0x60780, 24 },{ 0x60781, 24 },{ 0x60782, 24 },{ 0x60783, 24 }, -{ 0x60784, 24 },{ 0x60785, 24 },{ 0x60786, 24 },{ 0x60787, 24 }, -{ 0x60788, 24 },{ 0x60789, 24 },{ 0x6078a, 24 },{ 0x6078b, 24 }, -{ 0x6078c, 24 },{ 0x6078d, 24 },{ 0x6078e, 24 },{ 0x6078f, 24 }, -}; - -const uint32_t ff_table0_dc_chroma[120][2] = { -{ 0x0, 2 },{ 0x1, 2 },{ 0x5, 3 },{ 0x9, 4 }, -{ 0xd, 4 },{ 0x11, 5 },{ 0x1d, 5 },{ 0x1f, 5 }, -{ 0x21, 6 },{ 0x31, 6 },{ 0x38, 6 },{ 0x33, 6 }, -{ 0x39, 6 },{ 0x3d, 6 },{ 0x61, 7 },{ 0x79, 7 }, -{ 0x80, 8 },{ 0xc8, 8 },{ 0xca, 8 },{ 0xf0, 8 }, -{ 0x81, 8 },{ 0xc0, 8 },{ 0xc9, 8 },{ 0x107, 9 }, -{ 0x106, 9 },{ 0x196, 9 },{ 0x183, 9 },{ 0x1e3, 9 }, -{ 0x1e2, 9 },{ 0x20a, 10 },{ 0x20b, 10 },{ 0x609, 11 }, -{ 0x412, 11 },{ 0x413, 11 },{ 0x60b, 11 },{ 0x411, 11 }, -{ 0x60a, 11 },{ 0x65f, 11 },{ 0x410, 11 },{ 0x65d, 11 }, -{ 0x65e, 11 },{ 0xcb8, 12 },{ 0xc10, 12 },{ 0xcb9, 12 }, -{ 0x1823, 13 },{ 0x3045, 14 },{ 0x6089, 15 },{ 0xc110, 16 }, -{ 0x304448, 22 },{ 0x304449, 22 },{ 0x30444a, 22 },{ 0x30444b, 22 }, -{ 0x30444c, 22 },{ 0x30444d, 22 },{ 0x30444e, 22 },{ 0x30444f, 22 }, -{ 0x304450, 22 },{ 0x304451, 22 },{ 0x304452, 22 },{ 0x304453, 22 }, -{ 0x304454, 22 },{ 0x304455, 22 },{ 0x304456, 22 },{ 0x304457, 22 }, -{ 0x304458, 22 },{ 0x304459, 22 },{ 0x30445a, 22 },{ 0x30445b, 22 }, -{ 0x30445c, 22 },{ 0x30445d, 22 },{ 0x30445e, 22 },{ 0x30445f, 22 }, -{ 0x304460, 22 },{ 0x304461, 22 },{ 0x304462, 22 },{ 0x304463, 22 }, -{ 0x304464, 22 },{ 0x304465, 22 },{ 0x304466, 22 },{ 0x304467, 22 }, -{ 0x304468, 22 },{ 0x304469, 22 },{ 0x30446a, 22 },{ 0x30446b, 22 }, -{ 0x30446c, 22 },{ 0x30446d, 22 },{ 0x30446e, 22 },{ 0x30446f, 22 }, -{ 0x304470, 22 },{ 0x304471, 22 },{ 0x304472, 22 },{ 0x304473, 22 }, -{ 0x304474, 22 },{ 0x304475, 22 },{ 0x304476, 22 },{ 0x304477, 22 }, -{ 0x304478, 22 },{ 0x304479, 22 },{ 0x30447a, 22 },{ 0x30447b, 22 }, -{ 0x30447c, 22 },{ 0x30447d, 22 },{ 0x30447e, 22 },{ 0x30447f, 22 }, -{ 0x608880, 23 },{ 0x608881, 23 },{ 0x608882, 23 },{ 0x608883, 23 }, -{ 0x608884, 23 },{ 0x608885, 23 },{ 0x608886, 23 },{ 0x608887, 23 }, -{ 0x608888, 23 },{ 0x608889, 23 },{ 0x60888a, 23 },{ 0x60888b, 23 }, -{ 0x60888c, 23 },{ 0x60888d, 23 },{ 0x60888e, 23 },{ 0x60888f, 23 }, -}; - -/* dc table 1 */ - -const uint32_t ff_table1_dc_lum[120][2] = { -{ 0x2, 2 },{ 0x3, 2 },{ 0x3, 3 },{ 0x2, 4 }, -{ 0x5, 4 },{ 0x1, 5 },{ 0x3, 5 },{ 0x8, 5 }, -{ 0x0, 6 },{ 0x5, 6 },{ 0xd, 6 },{ 0xf, 6 }, -{ 0x13, 6 },{ 0x8, 7 },{ 0x18, 7 },{ 0x1c, 7 }, -{ 0x24, 7 },{ 0x4, 8 },{ 0x6, 8 },{ 0x12, 8 }, -{ 0x32, 8 },{ 0x3b, 8 },{ 0x4a, 8 },{ 0x4b, 8 }, -{ 0xb, 9 },{ 0x26, 9 },{ 0x27, 9 },{ 0x66, 9 }, -{ 0x74, 9 },{ 0x75, 9 },{ 0x14, 10 },{ 0x1c, 10 }, -{ 0x1f, 10 },{ 0x1d, 10 },{ 0x2b, 11 },{ 0x3d, 11 }, -{ 0x19d, 11 },{ 0x19f, 11 },{ 0x54, 12 },{ 0x339, 12 }, -{ 0x338, 12 },{ 0x33d, 12 },{ 0xab, 13 },{ 0xf1, 13 }, -{ 0x678, 13 },{ 0xf2, 13 },{ 0x1e0, 14 },{ 0x1e1, 14 }, -{ 0x154, 14 },{ 0xcf2, 14 },{ 0x3cc, 15 },{ 0x2ab, 15 }, -{ 0x19e7, 15 },{ 0x3ce, 15 },{ 0x19e6, 15 },{ 0x554, 16 }, -{ 0x79f, 16 },{ 0x555, 16 },{ 0xf3d, 17 },{ 0xf37, 17 }, -{ 0xf3c, 17 },{ 0xf35, 17 },{ 0x1e6d, 18 },{ 0x1e68, 18 }, -{ 0x3cd8, 19 },{ 0x3cd3, 19 },{ 0x3cd9, 19 },{ 0x79a4, 20 }, -{ 0xf34ba, 25 },{ 0xf34b4, 25 },{ 0xf34b5, 25 },{ 0xf34b6, 25 }, -{ 0xf34b7, 25 },{ 0xf34b8, 25 },{ 0xf34b9, 25 },{ 0xf34bb, 25 }, -{ 0xf34bc, 25 },{ 0xf34bd, 25 },{ 0xf34be, 25 },{ 0xf34bf, 25 }, -{ 0x1e6940, 26 },{ 0x1e6941, 26 },{ 0x1e6942, 26 },{ 0x1e6943, 26 }, -{ 0x1e6944, 26 },{ 0x1e6945, 26 },{ 0x1e6946, 26 },{ 0x1e6947, 26 }, -{ 0x1e6948, 26 },{ 0x1e6949, 26 },{ 0x1e694a, 26 },{ 0x1e694b, 26 }, -{ 0x1e694c, 26 },{ 0x1e694d, 26 },{ 0x1e694e, 26 },{ 0x1e694f, 26 }, -{ 0x1e6950, 26 },{ 0x1e6951, 26 },{ 0x1e6952, 26 },{ 0x1e6953, 26 }, -{ 0x1e6954, 26 },{ 0x1e6955, 26 },{ 0x1e6956, 26 },{ 0x1e6957, 26 }, -{ 0x1e6958, 26 },{ 0x1e6959, 26 },{ 0x1e695a, 26 },{ 0x1e695b, 26 }, -{ 0x1e695c, 26 },{ 0x1e695d, 26 },{ 0x1e695e, 26 },{ 0x1e695f, 26 }, -{ 0x1e6960, 26 },{ 0x1e6961, 26 },{ 0x1e6962, 26 },{ 0x1e6963, 26 }, -{ 0x1e6964, 26 },{ 0x1e6965, 26 },{ 0x1e6966, 26 },{ 0x1e6967, 26 }, -}; - -const uint32_t ff_table1_dc_chroma[120][2] = { -{ 0x0, 2 },{ 0x1, 2 },{ 0x4, 3 },{ 0x7, 3 }, -{ 0xb, 4 },{ 0xd, 4 },{ 0x15, 5 },{ 0x28, 6 }, -{ 0x30, 6 },{ 0x32, 6 },{ 0x52, 7 },{ 0x62, 7 }, -{ 0x66, 7 },{ 0xa6, 8 },{ 0xc6, 8 },{ 0xcf, 8 }, -{ 0x14f, 9 },{ 0x18e, 9 },{ 0x19c, 9 },{ 0x29d, 10 }, -{ 0x33a, 10 },{ 0x538, 11 },{ 0x63c, 11 },{ 0x63e, 11 }, -{ 0x63f, 11 },{ 0x676, 11 },{ 0xa73, 12 },{ 0xc7a, 12 }, -{ 0xcef, 12 },{ 0x14e5, 13 },{ 0x19dd, 13 },{ 0x29c8, 14 }, -{ 0x29c9, 14 },{ 0x63dd, 15 },{ 0x33b8, 14 },{ 0x33b9, 14 }, -{ 0xc7b6, 16 },{ 0x63d8, 15 },{ 0x63df, 15 },{ 0xc7b3, 16 }, -{ 0xc7b4, 16 },{ 0xc7b5, 16 },{ 0x63de, 15 },{ 0xc7b7, 16 }, -{ 0xc7b8, 16 },{ 0xc7b9, 16 },{ 0x18f65, 17 },{ 0x31ec8, 18 }, -{ 0xc7b248, 24 },{ 0xc7b249, 24 },{ 0xc7b24a, 24 },{ 0xc7b24b, 24 }, -{ 0xc7b24c, 24 },{ 0xc7b24d, 24 },{ 0xc7b24e, 24 },{ 0xc7b24f, 24 }, -{ 0xc7b250, 24 },{ 0xc7b251, 24 },{ 0xc7b252, 24 },{ 0xc7b253, 24 }, -{ 0xc7b254, 24 },{ 0xc7b255, 24 },{ 0xc7b256, 24 },{ 0xc7b257, 24 }, -{ 0xc7b258, 24 },{ 0xc7b259, 24 },{ 0xc7b25a, 24 },{ 0xc7b25b, 24 }, -{ 0xc7b25c, 24 },{ 0xc7b25d, 24 },{ 0xc7b25e, 24 },{ 0xc7b25f, 24 }, -{ 0xc7b260, 24 },{ 0xc7b261, 24 },{ 0xc7b262, 24 },{ 0xc7b263, 24 }, -{ 0xc7b264, 24 },{ 0xc7b265, 24 },{ 0xc7b266, 24 },{ 0xc7b267, 24 }, -{ 0xc7b268, 24 },{ 0xc7b269, 24 },{ 0xc7b26a, 24 },{ 0xc7b26b, 24 }, -{ 0xc7b26c, 24 },{ 0xc7b26d, 24 },{ 0xc7b26e, 24 },{ 0xc7b26f, 24 }, -{ 0xc7b270, 24 },{ 0xc7b271, 24 },{ 0xc7b272, 24 },{ 0xc7b273, 24 }, -{ 0xc7b274, 24 },{ 0xc7b275, 24 },{ 0xc7b276, 24 },{ 0xc7b277, 24 }, -{ 0xc7b278, 24 },{ 0xc7b279, 24 },{ 0xc7b27a, 24 },{ 0xc7b27b, 24 }, -{ 0xc7b27c, 24 },{ 0xc7b27d, 24 },{ 0xc7b27e, 24 },{ 0xc7b27f, 24 }, -{ 0x18f6480, 25 },{ 0x18f6481, 25 },{ 0x18f6482, 25 },{ 0x18f6483, 25 }, -{ 0x18f6484, 25 },{ 0x18f6485, 25 },{ 0x18f6486, 25 },{ 0x18f6487, 25 }, -{ 0x18f6488, 25 },{ 0x18f6489, 25 },{ 0x18f648a, 25 },{ 0x18f648b, 25 }, -{ 0x18f648c, 25 },{ 0x18f648d, 25 },{ 0x18f648e, 25 },{ 0x18f648f, 25 }, -}; - -/* vlc table 0, for intra luma */ - -static const uint16_t table0_vlc[133][2] = { -{ 0x1, 2 },{ 0x6, 3 },{ 0xf, 4 },{ 0x16, 5 }, -{ 0x20, 6 },{ 0x18, 7 },{ 0x8, 8 },{ 0x9a, 8 }, -{ 0x56, 9 },{ 0x13e, 9 },{ 0xf0, 10 },{ 0x3a5, 10 }, -{ 0x77, 11 },{ 0x1ef, 11 },{ 0x9a, 12 },{ 0x5d, 13 }, -{ 0x1, 4 },{ 0x11, 5 },{ 0x2, 7 },{ 0xb, 8 }, -{ 0x12, 9 },{ 0x1d6, 9 },{ 0x27e, 10 },{ 0x191, 11 }, -{ 0xea, 12 },{ 0x3dc, 12 },{ 0x13b, 13 },{ 0x4, 5 }, -{ 0x14, 7 },{ 0x9e, 8 },{ 0x9, 10 },{ 0x1ac, 11 }, -{ 0x1e2, 11 },{ 0x3ca, 12 },{ 0x5f, 13 },{ 0x17, 5 }, -{ 0x4e, 7 },{ 0x5e, 9 },{ 0xf3, 10 },{ 0x1ad, 11 }, -{ 0xec, 12 },{ 0x5f0, 13 },{ 0xe, 6 },{ 0xe1, 8 }, -{ 0x3a4, 10 },{ 0x9c, 12 },{ 0x13d, 13 },{ 0x3b, 6 }, -{ 0x1c, 9 },{ 0x14, 11 },{ 0x9be, 12 },{ 0x6, 7 }, -{ 0x7a, 9 },{ 0x190, 11 },{ 0x137, 13 },{ 0x1b, 7 }, -{ 0x8, 10 },{ 0x75c, 11 },{ 0x71, 7 },{ 0xd7, 10 }, -{ 0x9bf, 12 },{ 0x7, 8 },{ 0xaf, 10 },{ 0x4cc, 11 }, -{ 0x34, 8 },{ 0x265, 10 },{ 0x9f, 12 },{ 0xe0, 8 }, -{ 0x16, 11 },{ 0x327, 12 },{ 0x15, 9 },{ 0x17d, 11 }, -{ 0xebb, 12 },{ 0x14, 9 },{ 0xf6, 10 },{ 0x1e4, 11 }, -{ 0xcb, 10 },{ 0x99d, 12 },{ 0xca, 10 },{ 0x2fc, 12 }, -{ 0x17f, 11 },{ 0x4cd, 11 },{ 0x2fd, 12 },{ 0x4fe, 11 }, -{ 0x13a, 13 },{ 0xa, 4 },{ 0x42, 7 },{ 0x1d3, 9 }, -{ 0x4dd, 11 },{ 0x12, 5 },{ 0xe8, 8 },{ 0x4c, 11 }, -{ 0x136, 13 },{ 0x39, 6 },{ 0x264, 10 },{ 0xeba, 12 }, -{ 0x0, 7 },{ 0xae, 10 },{ 0x99c, 12 },{ 0x1f, 7 }, -{ 0x4de, 11 },{ 0x43, 7 },{ 0x4dc, 11 },{ 0x3, 8 }, -{ 0x3cb, 12 },{ 0x6, 8 },{ 0x99e, 12 },{ 0x2a, 8 }, -{ 0x5f1, 13 },{ 0xf, 8 },{ 0x9fe, 12 },{ 0x33, 8 }, -{ 0x9ff, 12 },{ 0x98, 8 },{ 0x99f, 12 },{ 0xea, 8 }, -{ 0x13c, 13 },{ 0x2e, 8 },{ 0x192, 11 },{ 0x136, 9 }, -{ 0x6a, 9 },{ 0x15, 11 },{ 0x3af, 10 },{ 0x1e3, 11 }, -{ 0x74, 11 },{ 0xeb, 12 },{ 0x2f9, 12 },{ 0x5c, 13 }, -{ 0xed, 12 },{ 0x3dd, 12 },{ 0x326, 12 },{ 0x5e, 13 }, -{ 0x16, 7 }, -}; - -static const int8_t table0_level[132] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 1, 2, 3, 4, 5, - 6, 7, 8, 1, 2, 3, 4, 5, - 6, 7, 1, 2, 3, 4, 5, 1, - 2, 3, 4, 1, 2, 3, 4, 1, - 2, 3, 1, 2, 3, 1, 2, 3, - 1, 2, 3, 1, 2, 3, 1, 2, - 3, 1, 2, 3, 1, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 2, 3, - 4, 1, 2, 3, 4, 1, 2, 3, - 1, 2, 3, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, -}; - -static const int8_t table0_run[132] = { - 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, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, - 3, 3, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 6, 6, 6, 6, 7, - 7, 7, 8, 8, 8, 9, 9, 9, - 10, 10, 10, 11, 11, 11, 12, 12, - 12, 13, 13, 13, 14, 14, 15, 15, - 16, 17, 18, 19, 20, 0, 0, 0, - 0, 1, 1, 1, 1, 2, 2, 2, - 3, 3, 3, 4, 4, 5, 5, 6, - 6, 7, 7, 8, 8, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, -}; - -/* vlc table 1, for intra chroma and P macroblocks */ - -static const uint16_t table1_vlc[149][2] = { -{ 0x4, 3 },{ 0x14, 5 },{ 0x17, 7 },{ 0x7f, 8 }, -{ 0x154, 9 },{ 0x1f2, 10 },{ 0xbf, 11 },{ 0x65, 12 }, -{ 0xaaa, 12 },{ 0x630, 13 },{ 0x1597, 13 },{ 0x3b7, 14 }, -{ 0x2b22, 14 },{ 0xbe6, 15 },{ 0xb, 4 },{ 0x37, 7 }, -{ 0x62, 9 },{ 0x7, 11 },{ 0x166, 12 },{ 0xce, 13 }, -{ 0x1590, 13 },{ 0x5f6, 14 },{ 0xbe7, 15 },{ 0x7, 5 }, -{ 0x6d, 8 },{ 0x3, 11 },{ 0x31f, 12 },{ 0x5f2, 14 }, -{ 0x2, 6 },{ 0x61, 9 },{ 0x55, 12 },{ 0x1df, 14 }, -{ 0x1a, 6 },{ 0x1e, 10 },{ 0xac9, 12 },{ 0x2b23, 14 }, -{ 0x1e, 6 },{ 0x1f, 10 },{ 0xac3, 12 },{ 0x2b2b, 14 }, -{ 0x6, 7 },{ 0x4, 11 },{ 0x2f8, 13 },{ 0x19, 7 }, -{ 0x6, 11 },{ 0x63d, 13 },{ 0x57, 7 },{ 0x182, 11 }, -{ 0x2aa2, 14 },{ 0x4, 8 },{ 0x180, 11 },{ 0x59c, 14 }, -{ 0x7d, 8 },{ 0x164, 12 },{ 0x76d, 15 },{ 0x2, 9 }, -{ 0x18d, 11 },{ 0x1581, 13 },{ 0xad, 8 },{ 0x60, 12 }, -{ 0xc67, 14 },{ 0x1c, 9 },{ 0xee, 13 },{ 0x3, 9 }, -{ 0x2cf, 13 },{ 0xd9, 9 },{ 0x1580, 13 },{ 0x2, 11 }, -{ 0x183, 11 },{ 0x57, 12 },{ 0x61, 12 },{ 0x31, 11 }, -{ 0x66, 12 },{ 0x631, 13 },{ 0x632, 13 },{ 0xac, 13 }, -{ 0x31d, 12 },{ 0x76, 12 },{ 0x3a, 11 },{ 0x165, 12 }, -{ 0xc66, 14 },{ 0x3, 2 },{ 0x54, 7 },{ 0x2ab, 10 }, -{ 0x16, 13 },{ 0x5f7, 14 },{ 0x5, 4 },{ 0xf8, 9 }, -{ 0xaa9, 12 },{ 0x5f, 15 },{ 0x4, 4 },{ 0x1c, 10 }, -{ 0x1550, 13 },{ 0x4, 5 },{ 0x77, 11 },{ 0x76c, 15 }, -{ 0xe, 5 },{ 0xa, 12 },{ 0xc, 5 },{ 0x562, 11 }, -{ 0x4, 6 },{ 0x31c, 12 },{ 0x6, 6 },{ 0xc8, 13 }, -{ 0xd, 6 },{ 0x1da, 13 },{ 0x7, 6 },{ 0xc9, 13 }, -{ 0x1, 7 },{ 0x2e, 14 },{ 0x14, 7 },{ 0x1596, 13 }, -{ 0xa, 7 },{ 0xac2, 12 },{ 0x16, 7 },{ 0x15b, 14 }, -{ 0x15, 7 },{ 0x15a, 14 },{ 0xf, 8 },{ 0x5e, 15 }, -{ 0x7e, 8 },{ 0xab, 8 },{ 0x2d, 9 },{ 0xd8, 9 }, -{ 0xb, 9 },{ 0x14, 10 },{ 0x2b3, 10 },{ 0x1f3, 10 }, -{ 0x3a, 10 },{ 0x0, 10 },{ 0x58, 10 },{ 0x2e, 9 }, -{ 0x5e, 10 },{ 0x563, 11 },{ 0xec, 12 },{ 0x54, 12 }, -{ 0xac1, 12 },{ 0x1556, 13 },{ 0x2fa, 13 },{ 0x181, 11 }, -{ 0x1557, 13 },{ 0x59d, 14 },{ 0x2aa3, 14 },{ 0x2b2a, 14 }, -{ 0x1de, 14 },{ 0x63c, 13 },{ 0xcf, 13 },{ 0x1594, 13 }, -{ 0xd, 9 }, -}; - -static const int8_t table1_level[148] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 1, - 2, 3, 4, 5, 1, 2, 3, 4, - 1, 2, 3, 4, 1, 2, 3, 4, - 1, 2, 3, 1, 2, 3, 1, 2, - 3, 1, 2, 3, 1, 2, 3, 1, - 2, 3, 1, 2, 3, 1, 2, 1, - 2, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 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, 2, 1, 2, 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, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, -}; - -static const int8_t table1_run[148] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 6, 7, 7, 7, 8, 8, - 8, 9, 9, 9, 10, 10, 10, 11, - 11, 11, 12, 12, 12, 13, 13, 14, - 14, 15, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 2, 2, 2, 3, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13, 14, 14, 15, 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, -}; - -/* third vlc table */ - -static const uint16_t table2_vlc[186][2] = { -{ 0x1, 2 },{ 0x5, 3 },{ 0xd, 4 },{ 0x12, 5 }, -{ 0xe, 6 },{ 0x15, 7 },{ 0x13, 8 },{ 0x3f, 8 }, -{ 0x4b, 9 },{ 0x11f, 9 },{ 0xb8, 10 },{ 0x3e3, 10 }, -{ 0x172, 11 },{ 0x24d, 12 },{ 0x3da, 12 },{ 0x2dd, 13 }, -{ 0x1f55, 13 },{ 0x5b9, 14 },{ 0x3eae, 14 },{ 0x0, 4 }, -{ 0x10, 5 },{ 0x8, 7 },{ 0x20, 8 },{ 0x29, 9 }, -{ 0x1f4, 9 },{ 0x233, 10 },{ 0x1e0, 11 },{ 0x12a, 12 }, -{ 0x3dd, 12 },{ 0x50a, 13 },{ 0x1f29, 13 },{ 0xa42, 14 }, -{ 0x1272, 15 },{ 0x1737, 15 },{ 0x3, 5 },{ 0x11, 7 }, -{ 0xc4, 8 },{ 0x4b, 10 },{ 0xb4, 11 },{ 0x7d4, 11 }, -{ 0x345, 12 },{ 0x2d7, 13 },{ 0x7bf, 13 },{ 0x938, 14 }, -{ 0xbbb, 14 },{ 0x95e, 15 },{ 0x13, 5 },{ 0x78, 7 }, -{ 0x69, 9 },{ 0x232, 10 },{ 0x461, 11 },{ 0x3ec, 12 }, -{ 0x520, 13 },{ 0x1f2a, 13 },{ 0x3e50, 14 },{ 0x3e51, 14 }, -{ 0x1486, 15 },{ 0xc, 6 },{ 0x24, 9 },{ 0x94, 11 }, -{ 0x8c0, 12 },{ 0xf09, 14 },{ 0x1ef0, 15 },{ 0x3d, 6 }, -{ 0x53, 9 },{ 0x1a0, 11 },{ 0x2d6, 13 },{ 0xf08, 14 }, -{ 0x13, 7 },{ 0x7c, 9 },{ 0x7c1, 11 },{ 0x4ac, 14 }, -{ 0x1b, 7 },{ 0xa0, 10 },{ 0x344, 12 },{ 0xf79, 14 }, -{ 0x79, 7 },{ 0x3e1, 10 },{ 0x2d4, 13 },{ 0x2306, 14 }, -{ 0x21, 8 },{ 0x23c, 10 },{ 0xfae, 12 },{ 0x23de, 14 }, -{ 0x35, 8 },{ 0x175, 11 },{ 0x7b3, 13 },{ 0xc5, 8 }, -{ 0x174, 11 },{ 0x785, 13 },{ 0x48, 9 },{ 0x1a3, 11 }, -{ 0x49e, 13 },{ 0x2c, 9 },{ 0xfa, 10 },{ 0x7d6, 11 }, -{ 0x92, 10 },{ 0x5cc, 13 },{ 0x1ef1, 15 },{ 0xa3, 10 }, -{ 0x3ed, 12 },{ 0x93e, 14 },{ 0x1e2, 11 },{ 0x1273, 15 }, -{ 0x7c4, 11 },{ 0x1487, 15 },{ 0x291, 12 },{ 0x293, 12 }, -{ 0xf8a, 12 },{ 0x509, 13 },{ 0x508, 13 },{ 0x78d, 13 }, -{ 0x7be, 13 },{ 0x78c, 13 },{ 0x4ae, 14 },{ 0xbba, 14 }, -{ 0x2307, 14 },{ 0xb9a, 14 },{ 0x1736, 15 },{ 0xe, 4 }, -{ 0x45, 7 },{ 0x1f3, 9 },{ 0x47a, 11 },{ 0x5dc, 13 }, -{ 0x23df, 14 },{ 0x19, 5 },{ 0x28, 9 },{ 0x176, 11 }, -{ 0x49d, 13 },{ 0x23dd, 14 },{ 0x30, 6 },{ 0xa2, 10 }, -{ 0x2ef, 12 },{ 0x5b8, 14 },{ 0x3f, 6 },{ 0xa5, 10 }, -{ 0x3db, 12 },{ 0x93f, 14 },{ 0x44, 7 },{ 0x7cb, 11 }, -{ 0x95f, 15 },{ 0x63, 7 },{ 0x3c3, 12 },{ 0x15, 8 }, -{ 0x8f6, 12 },{ 0x17, 8 },{ 0x498, 13 },{ 0x2c, 8 }, -{ 0x7b2, 13 },{ 0x2f, 8 },{ 0x1f54, 13 },{ 0x8d, 8 }, -{ 0x7bd, 13 },{ 0x8e, 8 },{ 0x1182, 13 },{ 0xfb, 8 }, -{ 0x50b, 13 },{ 0x2d, 8 },{ 0x7c0, 11 },{ 0x79, 9 }, -{ 0x1f5f, 13 },{ 0x7a, 9 },{ 0x1f56, 13 },{ 0x231, 10 }, -{ 0x3e4, 10 },{ 0x1a1, 11 },{ 0x143, 11 },{ 0x1f7, 11 }, -{ 0x16f, 12 },{ 0x292, 12 },{ 0x2e7, 12 },{ 0x16c, 12 }, -{ 0x16d, 12 },{ 0x3dc, 12 },{ 0xf8b, 12 },{ 0x499, 13 }, -{ 0x3d8, 12 },{ 0x78e, 13 },{ 0x2d5, 13 },{ 0x1f5e, 13 }, -{ 0x1f2b, 13 },{ 0x78f, 13 },{ 0x4ad, 14 },{ 0x3eaf, 14 }, -{ 0x23dc, 14 },{ 0x4a, 9 }, -}; - -static const int8_t table2_level[185] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, - 11, 1, 2, 3, 4, 5, 6, 1, - 2, 3, 4, 5, 1, 2, 3, 4, - 1, 2, 3, 4, 1, 2, 3, 4, - 1, 2, 3, 4, 1, 2, 3, 1, - 2, 3, 1, 2, 3, 1, 2, 3, - 1, 2, 3, 1, 2, 3, 1, 2, - 1, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 4, 5, 6, 1, 2, 3, - 4, 5, 1, 2, 3, 4, 1, 2, - 3, 4, 1, 2, 3, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 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, 1, 1, 1, 1, 1, - 1, -}; - -static const int8_t table2_run[185] = { - 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, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 6, 6, 6, 6, - 7, 7, 7, 7, 8, 8, 8, 8, - 9, 9, 9, 9, 10, 10, 10, 11, - 11, 11, 12, 12, 12, 13, 13, 13, - 14, 14, 14, 15, 15, 15, 16, 16, - 17, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 0, - 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 3, 3, - 3, 3, 4, 4, 4, 5, 5, 6, - 6, 7, 7, 8, 8, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, - 14, 15, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, - 37, -}; - -/* second non intra vlc table */ -static const uint16_t table4_vlc[169][2] = { -{ 0x0, 3 },{ 0x3, 4 },{ 0xb, 5 },{ 0x14, 6 }, -{ 0x3f, 6 },{ 0x5d, 7 },{ 0xa2, 8 },{ 0xac, 9 }, -{ 0x16e, 9 },{ 0x20a, 10 },{ 0x2e2, 10 },{ 0x432, 11 }, -{ 0x5c9, 11 },{ 0x827, 12 },{ 0xb54, 12 },{ 0x4e6, 13 }, -{ 0x105f, 13 },{ 0x172a, 13 },{ 0x20b2, 14 },{ 0x2d4e, 14 }, -{ 0x39f0, 14 },{ 0x4175, 15 },{ 0x5a9e, 15 },{ 0x4, 4 }, -{ 0x1e, 5 },{ 0x42, 7 },{ 0xb6, 8 },{ 0x173, 9 }, -{ 0x395, 10 },{ 0x72e, 11 },{ 0xb94, 12 },{ 0x16a4, 13 }, -{ 0x20b3, 14 },{ 0x2e45, 14 },{ 0x5, 5 },{ 0x40, 7 }, -{ 0x49, 9 },{ 0x28f, 10 },{ 0x5cb, 11 },{ 0x48a, 13 }, -{ 0x9dd, 14 },{ 0x73e2, 15 },{ 0x18, 5 },{ 0x25, 8 }, -{ 0x8a, 10 },{ 0x51b, 11 },{ 0xe5f, 12 },{ 0x9c9, 14 }, -{ 0x139c, 15 },{ 0x29, 6 },{ 0x4f, 9 },{ 0x412, 11 }, -{ 0x48d, 13 },{ 0x2e41, 14 },{ 0x38, 6 },{ 0x10e, 9 }, -{ 0x5a8, 11 },{ 0x105c, 13 },{ 0x39f2, 14 },{ 0x58, 7 }, -{ 0x21f, 10 },{ 0xe7e, 12 },{ 0x39ff, 14 },{ 0x23, 8 }, -{ 0x2e3, 10 },{ 0x4e5, 13 },{ 0x2e40, 14 },{ 0xa1, 8 }, -{ 0x5be, 11 },{ 0x9c8, 14 },{ 0x83, 8 },{ 0x13a, 11 }, -{ 0x1721, 13 },{ 0x44, 9 },{ 0x276, 12 },{ 0x39f6, 14 }, -{ 0x8b, 10 },{ 0x4ef, 13 },{ 0x5a9b, 15 },{ 0x208, 10 }, -{ 0x1cfe, 13 },{ 0x399, 10 },{ 0x1cb4, 13 },{ 0x39e, 10 }, -{ 0x39f3, 14 },{ 0x5ab, 11 },{ 0x73e3, 15 },{ 0x737, 11 }, -{ 0x5a9f, 15 },{ 0x82d, 12 },{ 0xe69, 12 },{ 0xe68, 12 }, -{ 0x433, 11 },{ 0xb7b, 12 },{ 0x2df8, 14 },{ 0x2e56, 14 }, -{ 0x2e57, 14 },{ 0x39f7, 14 },{ 0x51a5, 15 },{ 0x3, 3 }, -{ 0x2a, 6 },{ 0xe4, 8 },{ 0x28e, 10 },{ 0x735, 11 }, -{ 0x1058, 13 },{ 0x1cfa, 13 },{ 0x2df9, 14 },{ 0x4174, 15 }, -{ 0x9, 4 },{ 0x54, 8 },{ 0x398, 10 },{ 0x48b, 13 }, -{ 0x139d, 15 },{ 0xd, 4 },{ 0xad, 9 },{ 0x826, 12 }, -{ 0x2d4c, 14 },{ 0x11, 5 },{ 0x16b, 9 },{ 0xb7f, 12 }, -{ 0x51a4, 15 },{ 0x19, 5 },{ 0x21b, 10 },{ 0x16fd, 13 }, -{ 0x1d, 5 },{ 0x394, 10 },{ 0x28d3, 14 },{ 0x2b, 6 }, -{ 0x5bc, 11 },{ 0x5a9a, 15 },{ 0x2f, 6 },{ 0x247, 12 }, -{ 0x10, 7 },{ 0xa35, 12 },{ 0x3e, 6 },{ 0xb7a, 12 }, -{ 0x59, 7 },{ 0x105e, 13 },{ 0x26, 8 },{ 0x9cf, 14 }, -{ 0x55, 8 },{ 0x1cb5, 13 },{ 0x57, 8 },{ 0xe5b, 12 }, -{ 0xa0, 8 },{ 0x1468, 13 },{ 0x170, 9 },{ 0x90, 10 }, -{ 0x1ce, 9 },{ 0x21a, 10 },{ 0x218, 10 },{ 0x168, 9 }, -{ 0x21e, 10 },{ 0x244, 12 },{ 0x736, 11 },{ 0x138, 11 }, -{ 0x519, 11 },{ 0xe5e, 12 },{ 0x72c, 11 },{ 0xb55, 12 }, -{ 0x9dc, 14 },{ 0x20bb, 14 },{ 0x48c, 13 },{ 0x1723, 13 }, -{ 0x2e44, 14 },{ 0x16a5, 13 },{ 0x518, 11 },{ 0x39fe, 14 }, -{ 0x169, 9 }, -}; - -static const int8_t table4_level[168] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 1, - 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 1, 2, 3, 4, 5, 6, - 7, 8, 1, 2, 3, 4, 5, 6, - 7, 1, 2, 3, 4, 5, 1, 2, - 3, 4, 5, 1, 2, 3, 4, 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, - 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 1, 2, 3, 4, - 5, 1, 2, 3, 4, 1, 2, 3, - 4, 1, 2, 3, 1, 2, 3, 1, - 2, 3, 1, 2, 1, 2, 1, 2, - 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, 1, 1, 1, 1, 1, 1, -}; - -static const int8_t table4_run[168] = { - 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, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 5, 5, - 5, 5, 5, 6, 6, 6, 6, 7, - 7, 7, 7, 8, 8, 8, 9, 9, - 9, 10, 10, 10, 11, 11, 11, 12, - 12, 13, 13, 14, 14, 15, 15, 16, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 3, 3, 3, - 3, 4, 4, 4, 5, 5, 5, 6, - 6, 6, 7, 7, 8, 8, 9, 9, - 10, 10, 11, 11, 12, 12, 13, 13, - 14, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, -}; - -extern const uint16_t inter_vlc[103][2]; -extern const int8_t inter_level[102]; -extern const int8_t inter_run[102]; - -extern const uint16_t ff_mpeg4_intra_vlc[103][2]; -extern const int8_t ff_mpeg4_intra_level[102]; -extern const int8_t ff_mpeg4_intra_run[102]; - -RLTable rl_table[NB_RL_TABLES] = { - /* intra luminance tables */ - /* low motion */ - { - 132, - 85, - table0_vlc, - table0_run, - table0_level, - }, - /* high motion */ - { - 185, - 119, - table2_vlc, - table2_run, - table2_level, - }, - /* mid-rate */ - { - 102, - 67, - ff_mpeg4_intra_vlc, - ff_mpeg4_intra_run, - ff_mpeg4_intra_level, - }, - /* intra chrominance / non intra tables */ - /* low motion inter */ - { - 148, - 81, - table1_vlc, - table1_run, - table1_level, - }, - /* high motion inter */ - { - 168, - 99, - table4_vlc, - table4_run, - table4_level, - }, - /* mid rate inter */ - { - 102, - 58, - inter_vlc, - inter_run, - inter_level, - }, -}; - -/* motion vector table 0 */ - -static const uint16_t table0_mv_code[1100] = { - 0x0001, 0x0003, 0x0005, 0x0007, 0x0003, 0x0008, 0x000c, 0x0001, - 0x0002, 0x001b, 0x0006, 0x000b, 0x0015, 0x0002, 0x000e, 0x000f, - 0x0014, 0x0020, 0x0022, 0x0025, 0x0027, 0x0029, 0x002d, 0x004b, - 0x004d, 0x0003, 0x0022, 0x0023, 0x0025, 0x0027, 0x0042, 0x0048, - 0x0049, 0x0050, 0x005c, 0x0091, 0x009f, 0x000e, 0x0043, 0x004c, - 0x0054, 0x0056, 0x008c, 0x0098, 0x009a, 0x009b, 0x00b1, 0x00b2, - 0x0120, 0x0121, 0x0126, 0x0133, 0x0139, 0x01a1, 0x01a4, 0x01a5, - 0x01a6, 0x01a7, 0x01ae, 0x01af, 0x000b, 0x0019, 0x0085, 0x0090, - 0x009b, 0x00aa, 0x00af, 0x010c, 0x010e, 0x011c, 0x011e, 0x0133, - 0x0144, 0x0160, 0x0174, 0x0175, 0x0177, 0x0178, 0x0249, 0x024b, - 0x0252, 0x0261, 0x0265, 0x0270, 0x0352, 0x0353, 0x0355, 0x0359, - 0x0010, 0x0011, 0x0013, 0x0034, 0x0035, 0x0036, 0x0037, 0x003d, - 0x003e, 0x0109, 0x0126, 0x0156, 0x021a, 0x021e, 0x023a, 0x023e, - 0x028e, 0x028f, 0x02cf, 0x0491, 0x0494, 0x049f, 0x04a0, 0x04a3, - 0x04a6, 0x04a7, 0x04ad, 0x04ae, 0x04c0, 0x04c4, 0x04c6, 0x04c8, - 0x04c9, 0x04f5, 0x04f6, 0x04f7, 0x0680, 0x0682, 0x0683, 0x0688, - 0x0689, 0x068d, 0x068e, 0x068f, 0x06a2, 0x06a3, 0x06a9, 0x06b0, - 0x06b1, 0x06b4, 0x06b5, 0x0024, 0x0060, 0x0063, 0x0078, 0x0079, - 0x0211, 0x0244, 0x0245, 0x0247, 0x0248, 0x0249, 0x024a, 0x024b, - 0x026b, 0x02af, 0x02b8, 0x02bb, 0x0436, 0x0476, 0x0477, 0x047e, - 0x04c8, 0x04c9, 0x04ca, 0x0514, 0x0586, 0x0587, 0x0598, 0x059d, - 0x05d9, 0x05da, 0x0920, 0x0921, 0x093b, 0x093c, 0x093d, 0x0942, - 0x0943, 0x0944, 0x0945, 0x0959, 0x095e, 0x095f, 0x0982, 0x0983, - 0x098e, 0x098f, 0x09c4, 0x09e7, 0x09e8, 0x09e9, 0x0d02, 0x0d17, - 0x0d18, 0x0d19, 0x0d41, 0x0d42, 0x0d43, 0x0d50, 0x0d5f, 0x0d6d, - 0x0d6e, 0x0d6f, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x041e, 0x041f, 0x0420, 0x0421, - 0x048c, 0x048d, 0x04d3, 0x04d4, 0x04d5, 0x055c, 0x055d, 0x0572, - 0x0573, 0x0574, 0x0575, 0x08de, 0x08df, 0x08fe, 0x08ff, 0x0996, - 0x0a36, 0x0a37, 0x0b08, 0x0b09, 0x0b0a, 0x0b0b, 0x0b32, 0x0b33, - 0x0b34, 0x0b35, 0x0b36, 0x0b37, 0x0b38, 0x0b39, 0x0bb0, 0x0bf7, - 0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb, 0x0bfc, 0x0bfd, 0x0bfe, 0x0bff, - 0x1254, 0x1255, 0x1256, 0x1257, 0x1270, 0x1271, 0x1272, 0x1273, - 0x1274, 0x1275, 0x12ab, 0x12ac, 0x12ad, 0x12ae, 0x12af, 0x12b0, - 0x12b1, 0x1315, 0x1316, 0x1317, 0x13bf, 0x13c0, 0x13c1, 0x13c2, - 0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7, 0x13c8, 0x13c9, 0x13ca, - 0x13cb, 0x13cc, 0x13cd, 0x1a06, 0x1a07, 0x1a28, 0x1a29, 0x1a2a, - 0x1a2b, 0x1a2c, 0x1a2d, 0x1a80, 0x1abb, 0x1abc, 0x1abd, 0x1ad8, - 0x1ad9, 0x0094, 0x0095, 0x0096, 0x0097, 0x00a0, 0x00a1, 0x00a2, - 0x00a3, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837, - 0x0838, 0x0839, 0x083a, 0x083b, 0x0939, 0x093a, 0x093b, 0x093c, - 0x093d, 0x093e, 0x093f, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x09a4, - 0x09a5, 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, - 0x11b3, 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, - 0x11bb, 0x132f, 0x1454, 0x1455, 0x1456, 0x1457, 0x1458, 0x1459, - 0x145a, 0x145b, 0x145c, 0x145d, 0x145e, 0x145f, 0x1460, 0x1461, - 0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467, 0x1468, 0x1469, - 0x146a, 0x146b, 0x17de, 0x17df, 0x17e0, 0x17e1, 0x17e2, 0x17e3, - 0x17e4, 0x17e5, 0x17e6, 0x17e7, 0x17e8, 0x17e9, 0x17ea, 0x17eb, - 0x17ec, 0x17ed, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, - 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, - 0x254e, 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, - 0x2628, 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, - 0x276d, 0x276e, 0x276f, 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, - 0x2775, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c, - 0x277d, 0x3503, 0x3544, 0x3545, 0x3546, 0x3547, 0x3560, 0x3561, - 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, 0x3569, - 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, 0x3571, - 0x3572, 0x3573, 0x3574, 0x3575, 0x03f0, 0x103d, 0x103e, 0x103f, - 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, - 0x1048, 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f, - 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, - 0x1058, 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f, - 0x1060, 0x1061, 0x1270, 0x1271, 0x21b8, 0x21b9, 0x21ba, 0x21bb, - 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x21f0, 0x21f1, 0x21f2, 0x21f3, - 0x21f4, 0x21f5, 0x21f6, 0x21f7, 0x21f8, 0x21f9, 0x21fa, 0x21fb, - 0x21fc, 0x21fd, 0x21fe, 0x21ff, 0x2340, 0x2341, 0x2342, 0x2343, - 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, - 0x234c, 0x234d, 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, - 0x2354, 0x2355, 0x2356, 0x2357, 0x265c, 0x2f88, 0x2f89, 0x2f8a, - 0x2f8b, 0x2f8c, 0x2f8d, 0x2f8e, 0x2f8f, 0x2f90, 0x2f91, 0x2f92, - 0x2f93, 0x2f94, 0x2f95, 0x2f96, 0x2f97, 0x2f98, 0x2f99, 0x2f9a, - 0x2f9b, 0x2f9c, 0x2f9d, 0x2f9e, 0x2f9f, 0x2fa0, 0x2fa1, 0x2fa2, - 0x2fa3, 0x2fa4, 0x2fa5, 0x2fa6, 0x2fa7, 0x2fa8, 0x2fa9, 0x2faa, - 0x2fab, 0x2fac, 0x2fad, 0x2fae, 0x2faf, 0x2fb0, 0x2fb1, 0x2fb2, - 0x2fb3, 0x2fb4, 0x2fb5, 0x2fb6, 0x2fb7, 0x2fb8, 0x2fb9, 0x2fba, - 0x2fbb, 0x4c52, 0x4c53, 0x4e28, 0x4e29, 0x4e2a, 0x4e2b, 0x4e2c, - 0x4e2d, 0x4e2e, 0x4e2f, 0x4e30, 0x4e31, 0x4e32, 0x4e33, 0x4e34, - 0x4e35, 0x4e36, 0x4e37, 0x4e38, 0x4e39, 0x4e3a, 0x4e3b, 0x4e3c, - 0x4e3d, 0x4e3e, 0x4e3f, 0x4e80, 0x4e81, 0x4e82, 0x4e83, 0x4e84, - 0x4e85, 0x4e86, 0x4e87, 0x4e88, 0x4e89, 0x4e8a, 0x4e8b, 0x4e8c, - 0x4e8d, 0x4e8e, 0x4e8f, 0x4e90, 0x4e91, 0x4e92, 0x4e93, 0x4e94, - 0x4e95, 0x4e96, 0x4e97, 0x4e98, 0x4e99, 0x4e9a, 0x4e9b, 0x4e9c, - 0x4e9d, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea1, 0x4ea2, 0x4ea3, 0x4ea4, - 0x4ea5, 0x4ea6, 0x4ea7, 0x4ea8, 0x4ea9, 0x4eaa, 0x4eab, 0x4eac, - 0x4ead, 0x4eae, 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb2, 0x4eb3, 0x4eb4, - 0x4eb5, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9, 0x4eba, 0x4ebb, 0x4ebc, - 0x4ebd, 0x4ebe, 0x4ebf, 0x4ec0, 0x4ec1, 0x4ec2, 0x4ec3, 0x4ec4, - 0x4ec5, 0x4ec6, 0x4ec7, 0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x6a04, - 0x6a05, 0x07e2, 0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 0x07e8, - 0x07e9, 0x07ea, 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0, - 0x07f1, 0x07f2, 0x07f3, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 0x07f8, - 0x07f9, 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x07fe, 0x07ff, 0x2000, - 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, - 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x200e, 0x200f, 0x2010, - 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, - 0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201e, 0x201f, 0x2020, - 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 0x2028, - 0x2029, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x202f, 0x2030, - 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 0x2038, - 0x2039, 0x203a, 0x203b, 0x203c, 0x203d, 0x203e, 0x203f, 0x2040, - 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 0x2048, - 0x2049, 0x204a, 0x204b, 0x204c, 0x204d, 0x204e, 0x204f, 0x2050, - 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, - 0x2059, 0x205a, 0x205b, 0x205c, 0x205d, 0x205e, 0x205f, 0x2060, - 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, - 0x2069, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 0x2070, - 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, - 0x2079, 0x4cba, 0x4cbb, 0x5d88, 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c, - 0x5d8d, 0x5d8e, 0x5d8f, 0x5db0, 0x5db1, 0x5db2, 0x5db3, 0x5db4, - 0x5db5, 0x5db6, 0x5db7, 0x5db8, 0x5db9, 0x5dba, 0x5dbb, 0x5dbc, - 0x5dbd, 0x5dbe, 0x5dbf, 0x5e40, 0x5e41, 0x5e42, 0x5e43, 0x5e44, - 0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4c, - 0x5e4d, 0x5e4e, 0x5e4f, 0x5e50, 0x5e51, 0x5e52, 0x5e53, 0x5e54, - 0x5e55, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, 0x5e5b, 0x5e5c, - 0x5e5d, 0x5e5e, 0x5e5f, 0x5e60, 0x5e61, 0x5e62, 0x5e63, 0x5e64, - 0x5e65, 0x5e66, 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c, - 0x5e6d, 0x5e6e, 0x5e6f, 0x5e70, 0x5e71, 0x5e72, 0x5e73, 0x5e74, - 0x5e75, 0x5e76, 0x5e77, 0x5e78, 0x5e79, 0x5e7a, 0x5e7b, 0x5e7c, - 0x5e7d, 0x5e7e, 0x5e7f, 0x5e80, 0x5e81, 0x5e82, 0x5e83, 0x5e84, - 0x5e85, 0x5e86, 0x5e87, 0x5e88, 0x5e89, 0x5e8a, 0x5e8b, 0x5e8c, - 0x5e8d, 0x5e8e, 0x5e8f, 0x5e90, 0x5e91, 0x5e92, 0x5e93, 0x5e94, - 0x5e95, 0x5e96, 0x5e97, 0x5e98, 0x5e99, 0x5e9a, 0x5e9b, 0x5e9c, - 0x5e9d, 0x5e9e, 0x5e9f, 0x5ea0, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4, - 0x5ea5, 0x5ea6, 0x5ea7, 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac, - 0x5ead, 0x5eae, 0x5eaf, 0x5eb0, 0x5eb1, 0x5eb2, 0x5eb3, 0x5eb4, - 0x5eb5, 0x5eb6, 0x5eb7, 0x5eb8, 0x5eb9, 0x5eba, 0x5ebb, 0x5ebc, - 0x5ebd, 0x5ebe, 0x5ebf, 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4, - 0x5ec5, 0x5ec6, 0x5ec7, 0x5ec8, 0x5ec9, 0x5eca, 0x5ecb, 0x5ecc, - 0x5ecd, 0x5ece, 0x5ecf, 0x5ed0, 0x5ed1, 0x5ed2, 0x5ed3, 0x5ed4, - 0x5ed5, 0x5ed6, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edb, 0x5edc, - 0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4, - 0x5ee5, 0x5ee6, 0x5ee7, 0x5ee8, 0x5ee9, 0x5eea, 0x5eeb, 0x5eec, - 0x5eed, 0x5eee, 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef4, - 0x5ef5, 0x5ef6, 0x5ef7, 0x5ef8, 0x5ef9, 0x5efa, 0x5efb, 0x5efc, - 0x5efd, 0x5efe, 0x5eff, 0x5f00, 0x5f01, 0x5f02, 0x5f03, 0x5f04, - 0x5f05, 0x5f06, 0x5f07, 0x5f08, 0x5f09, 0x5f0a, 0x5f0b, 0x5f0c, - 0x5f0d, 0x5f0e, 0x5f0f, 0x0000, -}; - -static const uint8_t table0_mv_bits[1100] = { - 1, 4, 4, 4, 5, 5, 5, 6, - 6, 6, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 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, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 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, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 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, 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, 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, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 8, -}; - -static const uint8_t table0_mvx[1099] = { - 32, 32, 31, 32, 33, 31, 33, 31, - 33, 32, 34, 32, 30, 32, 31, 34, - 35, 32, 34, 33, 29, 33, 30, 30, - 31, 31, 35, 29, 33, 35, 33, 34, - 31, 29, 30, 34, 30, 36, 28, 32, - 34, 37, 30, 27, 32, 25, 39, 32, - 34, 32, 35, 35, 35, 31, 35, 29, - 32, 29, 30, 29, 37, 27, 36, 38, - 37, 33, 32, 31, 29, 31, 28, 36, - 33, 30, 34, 33, 33, 28, 27, 25, - 31, 26, 39, 32, 32, 31, 33, 39, - 31, 38, 28, 36, 21, 23, 43, 36, - 34, 41, 30, 25, 28, 31, 30, 34, - 38, 35, 61, 34, 28, 30, 37, 37, - 35, 27, 36, 3, 59, 38, 37, 32, - 31, 29, 26, 33, 37, 33, 27, 27, - 35, 34, 34, 40, 42, 33, 32, 29, - 4, 5, 28, 24, 25, 35, 39, 38, - 32, 23, 27, 32, 30, 35, 26, 34, - 60, 36, 29, 22, 26, 41, 7, 30, - 38, 30, 36, 29, 30, 41, 26, 25, - 32, 34, 24, 39, 1, 25, 39, 32, - 28, 29, 32, 38, 26, 36, 28, 63, - 28, 39, 23, 21, 26, 35, 31, 35, - 57, 31, 29, 29, 28, 30, 27, 35, - 2, 38, 40, 34, 37, 29, 38, 43, - 26, 32, 33, 42, 24, 40, 28, 32, - 32, 32, 36, 32, 43, 25, 21, 31, - 30, 31, 41, 29, 33, 37, 26, 37, - 27, 59, 23, 33, 35, 31, 31, 37, - 38, 39, 32, 23, 32, 27, 37, 36, - 31, 40, 25, 27, 38, 31, 36, 28, - 31, 36, 25, 45, 3, 34, 38, 39, - 40, 38, 30, 32, 19, 24, 25, 26, - 45, 20, 24, 33, 33, 31, 41, 34, - 39, 47, 40, 58, 59, 41, 33, 3, - 17, 61, 42, 30, 26, 29, 36, 61, - 33, 37, 62, 28, 25, 38, 25, 38, - 17, 23, 34, 33, 21, 33, 49, 27, - 32, 23, 27, 22, 24, 22, 39, 43, - 27, 37, 6, 42, 47, 26, 30, 31, - 41, 39, 33, 22, 45, 36, 32, 45, - 19, 22, 30, 5, 5, 17, 29, 22, - 31, 31, 43, 37, 27, 32, 32, 32, - 33, 34, 43, 35, 29, 26, 22, 32, - 19, 32, 25, 31, 41, 49, 28, 34, - 28, 39, 34, 19, 37, 38, 29, 21, - 36, 42, 24, 48, 16, 28, 49, 22, - 34, 31, 38, 39, 44, 11, 35, 30, - 33, 33, 23, 28, 33, 46, 15, 13, - 24, 41, 24, 34, 34, 30, 26, 24, - 14, 60, 21, 29, 39, 23, 35, 37, - 63, 45, 33, 34, 47, 41, 22, 42, - 35, 35, 23, 32, 35, 43, 32, 7, - 31, 41, 20, 31, 16, 13, 63, 25, - 30, 32, 35, 30, 30, 31, 42, 47, - 39, 38, 40, 40, 51, 55, 56, 18, - 21, 39, 39, 33, 17, 41, 23, 24, - 43, 25, 31, 20, 19, 45, 1, 34, - 31, 22, 35, 15, 46, 46, 35, 31, - 28, 29, 29, 23, 41, 27, 14, 53, - 53, 27, 24, 32, 57, 32, 17, 42, - 37, 29, 33, 1, 25, 32, 32, 63, - 26, 40, 44, 36, 31, 39, 20, 20, - 44, 23, 33, 34, 35, 33, 33, 28, - 41, 23, 41, 41, 29, 25, 26, 49, - 29, 24, 37, 49, 50, 51, 51, 26, - 39, 25, 26, 15, 39, 18, 42, 17, - 4, 31, 32, 32, 60, 1, 42, 32, - 0, 12, 19, 35, 21, 41, 17, 26, - 20, 45, 46, 32, 37, 22, 47, 29, - 31, 27, 29, 30, 21, 33, 35, 18, - 25, 33, 50, 51, 42, 2, 15, 51, - 53, 33, 25, 29, 55, 37, 38, 33, - 38, 59, 38, 33, 39, 13, 32, 40, - 61, 61, 32, 9, 44, 3, 31, 29, - 25, 31, 27, 23, 9, 25, 9, 29, - 20, 30, 30, 42, 18, 28, 25, 28, - 28, 21, 29, 43, 29, 43, 26, 44, - 44, 21, 38, 21, 24, 45, 45, 35, - 39, 22, 35, 36, 34, 34, 45, 34, - 29, 31, 46, 25, 46, 16, 17, 31, - 20, 32, 47, 47, 47, 32, 49, 49, - 49, 31, 1, 27, 28, 39, 39, 21, - 36, 23, 51, 2, 40, 51, 32, 53, - 24, 30, 24, 30, 21, 40, 57, 57, - 31, 41, 58, 32, 12, 4, 32, 34, - 59, 31, 32, 13, 9, 35, 26, 35, - 37, 61, 37, 63, 26, 29, 41, 38, - 23, 20, 41, 26, 41, 42, 42, 42, - 26, 26, 26, 26, 1, 26, 37, 37, - 37, 23, 34, 42, 27, 43, 34, 27, - 31, 24, 33, 16, 3, 31, 24, 33, - 24, 4, 44, 44, 11, 44, 31, 13, - 13, 44, 45, 13, 25, 22, 38, 26, - 38, 38, 39, 32, 30, 39, 30, 22, - 32, 26, 30, 47, 47, 47, 19, 47, - 30, 31, 35, 8, 23, 47, 47, 27, - 35, 47, 31, 48, 35, 19, 36, 49, - 49, 33, 31, 39, 27, 39, 49, 49, - 50, 50, 50, 39, 31, 51, 51, 39, - 28, 33, 33, 21, 40, 31, 52, 53, - 40, 53, 9, 33, 31, 53, 54, 54, - 54, 55, 55, 34, 15, 56, 25, 56, - 21, 21, 40, 40, 25, 40, 58, 36, - 5, 41, 41, 12, 60, 41, 41, 37, - 22, 61, 18, 29, 29, 30, 61, 30, - 61, 62, 62, 30, 30, 63, 18, 13, - 30, 23, 19, 20, 20, 41, 13, 2, - 5, 5, 1, 5, 32, 6, 32, 35, - 20, 35, 27, 35, 35, 36, 36, 13, - 36, 41, 41, 41, 3, 30, 42, 27, - 20, 30, 27, 28, 30, 21, 33, 33, - 14, 24, 30, 42, 24, 33, 25, 42, - 43, 14, 43, 43, 14, 43, 7, 36, - 37, 37, 37, 37, 7, 14, 25, 43, - 43, 44, 15, 37, 7, 7, 3, 1, - 8, 15, 15, 8, 44, 44, 44, 45, - 45, 45, 45, 8, 8, 45, 21, 45, - 28, 28, 28, 21, 28, 28, 22, 37, - 46, 46, 37, 8, 29, 37, 29, 22, - 46, 37, 22, 29, 47, 47, 38, 38, - 16, 38, 38, 33, 38, 22, 47, 47, - 29, 25, 16, 0, 48, 1, 34, 48, - 48, 34, 25, 26, 26, 49, 49, 26, - 1, 49, 4, 26, 4, 49, 1, 9, - 49, 49, 49, 10, 49, 17, 38, 17, - 17, 50, 38, 50, 50, 22, 38, 51, - 38, 38, 51, 39, 39, 18, 22, 39, - 51, 22, 52, 52, 52, 39, 53, 53, - 10, 23, 18, 29, 10, 53, 29, 54, - 11, 54, 11, 11, 55, 1, 18, 55, - 55, 55, 55, 55, 55, 29, 34, 18, - 29, 56, 56, 34, 57, 34, 34, 29, - 29, 57, 57, 35, 35, 35, 35, 35, - 39, 35, 59, 59, 18, 59, 39, 30, - 18, 40, 60, 60, 61, 30, 18, 61, - 61, 19, 19, -}; - -static const uint8_t table0_mvy[1099] = { - 32, 31, 32, 33, 32, 31, 31, 33, - 33, 34, 32, 30, 32, 35, 34, 31, - 32, 29, 33, 30, 32, 34, 33, 31, - 30, 35, 31, 31, 29, 33, 35, 30, - 29, 33, 34, 34, 30, 32, 32, 36, - 29, 32, 35, 32, 28, 32, 32, 27, - 35, 37, 34, 29, 30, 36, 35, 34, - 25, 30, 29, 35, 33, 31, 31, 32, - 31, 28, 39, 28, 29, 37, 31, 33, - 27, 36, 28, 36, 37, 33, 33, 31, - 27, 32, 31, 38, 26, 25, 25, 33, - 39, 31, 34, 30, 32, 32, 32, 34, - 36, 32, 28, 33, 30, 38, 37, 27, - 33, 28, 32, 37, 35, 38, 29, 34, - 27, 29, 29, 32, 32, 34, 35, 3, - 26, 36, 31, 38, 30, 26, 35, 34, - 37, 26, 25, 32, 32, 39, 23, 37, - 32, 32, 29, 32, 29, 36, 29, 30, - 41, 31, 30, 21, 39, 25, 34, 38, - 32, 35, 39, 32, 33, 33, 32, 27, - 29, 25, 28, 27, 26, 31, 30, 35, - 24, 24, 31, 34, 32, 30, 35, 40, - 28, 38, 5, 35, 29, 36, 36, 32, - 38, 30, 33, 31, 35, 26, 23, 38, - 32, 41, 28, 25, 37, 40, 37, 39, - 32, 36, 33, 39, 25, 26, 28, 31, - 28, 42, 23, 31, 33, 31, 39, 1, - 59, 22, 27, 4, 33, 34, 33, 24, - 41, 3, 35, 41, 41, 28, 36, 36, - 28, 33, 35, 21, 23, 21, 22, 37, - 27, 27, 43, 29, 60, 39, 27, 25, - 59, 34, 27, 27, 26, 40, 37, 27, - 61, 26, 39, 33, 31, 22, 37, 25, - 30, 25, 24, 61, 31, 34, 25, 38, - 32, 32, 30, 3, 61, 43, 29, 23, - 28, 32, 28, 32, 31, 34, 5, 33, - 32, 33, 33, 42, 37, 23, 38, 31, - 40, 26, 32, 26, 37, 38, 36, 24, - 29, 30, 20, 22, 29, 24, 32, 41, - 2, 34, 25, 33, 29, 31, 39, 35, - 36, 24, 32, 30, 33, 27, 44, 60, - 30, 36, 19, 34, 31, 24, 16, 35, - 32, 38, 21, 33, 31, 31, 21, 35, - 5, 17, 29, 38, 38, 18, 58, 19, - 43, 41, 30, 41, 43, 39, 29, 7, - 29, 17, 28, 19, 28, 31, 25, 19, - 40, 26, 21, 33, 39, 23, 40, 30, - 39, 34, 35, 32, 32, 24, 33, 30, - 40, 47, 39, 37, 32, 33, 24, 23, - 45, 47, 27, 23, 42, 32, 32, 33, - 36, 37, 37, 17, 18, 22, 40, 38, - 32, 31, 35, 24, 17, 25, 17, 23, - 33, 34, 51, 42, 31, 36, 36, 29, - 21, 22, 37, 44, 43, 25, 47, 33, - 45, 27, 31, 58, 31, 32, 31, 38, - 43, 20, 47, 45, 54, 1, 26, 34, - 38, 14, 22, 24, 33, 34, 32, 32, - 37, 21, 23, 49, 35, 23, 28, 39, - 39, 23, 55, 33, 30, 30, 63, 16, - 42, 28, 13, 33, 33, 35, 19, 46, - 43, 17, 19, 36, 39, 24, 31, 32, - 33, 26, 28, 62, 33, 63, 33, 39, - 19, 49, 17, 31, 43, 13, 15, 29, - 25, 35, 33, 23, 49, 41, 28, 29, - 34, 38, 7, 61, 11, 50, 13, 41, - 19, 47, 25, 26, 15, 42, 41, 29, - 45, 27, 17, 35, 32, 29, 32, 24, - 13, 26, 26, 31, 24, 33, 28, 30, - 31, 11, 45, 46, 33, 33, 35, 57, - 32, 32, 35, 45, 34, 11, 37, 42, - 39, 37, 31, 49, 21, 27, 29, 47, - 53, 40, 51, 16, 26, 1, 40, 30, - 41, 44, 34, 25, 27, 31, 35, 35, - 31, 15, 49, 1, 35, 40, 5, 58, - 21, 29, 22, 59, 45, 31, 9, 26, - 9, 29, 11, 32, 30, 3, 13, 20, - 18, 20, 11, 3, 29, 40, 31, 53, - 30, 17, 20, 37, 31, 42, 47, 47, - 54, 38, 9, 34, 13, 37, 21, 25, - 27, 43, 42, 45, 40, 25, 27, 46, - 22, 25, 53, 20, 2, 14, 39, 15, - 22, 44, 34, 21, 38, 33, 27, 48, - 34, 52, 35, 47, 49, 54, 2, 13, - 23, 52, 29, 45, 22, 49, 54, 21, - 40, 42, 31, 30, 29, 34, 0, 25, - 23, 51, 24, 59, 28, 38, 29, 31, - 2, 13, 31, 8, 31, 33, 12, 45, - 41, 7, 14, 30, 25, 18, 43, 20, - 43, 35, 44, 1, 49, 42, 42, 18, - 41, 38, 41, 44, 53, 11, 20, 25, - 45, 46, 47, 48, 39, 52, 46, 49, - 63, 55, 44, 38, 13, 13, 57, 22, - 51, 16, 12, 28, 35, 57, 25, 20, - 26, 28, 28, 29, 32, 31, 62, 34, - 35, 35, 19, 49, 48, 39, 40, 18, - 43, 46, 11, 6, 48, 19, 49, 41, - 10, 23, 58, 17, 21, 23, 34, 30, - 60, 0, 44, 34, 26, 37, 46, 43, - 49, 59, 4, 34, 59, 37, 22, 25, - 28, 46, 6, 40, 59, 42, 36, 61, - 28, 30, 31, 43, 10, 22, 23, 47, - 20, 52, 55, 36, 25, 16, 1, 11, - 27, 29, 5, 63, 18, 41, 31, 34, - 38, 1, 5, 13, 28, 31, 17, 38, - 39, 41, 36, 37, 22, 39, 33, 43, - 43, 15, 17, 49, 30, 21, 22, 20, - 10, 17, 25, 54, 57, 3, 34, 8, - 36, 25, 31, 14, 15, 19, 29, 25, - 18, 39, 53, 22, 27, 20, 29, 33, - 41, 42, 35, 62, 50, 29, 53, 50, - 35, 55, 42, 61, 63, 4, 7, 42, - 21, 46, 47, 49, 27, 46, 17, 55, - 41, 50, 63, 4, 56, 18, 8, 10, - 18, 51, 63, 36, 55, 18, 5, 55, - 9, 29, 17, 21, 30, 27, 1, 59, - 7, 11, 12, 15, 5, 42, 24, 41, - 43, 7, 27, 22, 25, 31, 30, 37, - 22, 39, 53, 29, 36, 37, 48, 0, - 5, 13, 17, 31, 32, 26, 46, 28, - 44, 45, 46, 53, 49, 51, 3, 41, - 3, 22, 42, 33, 5, 45, 7, 22, - 40, 53, 24, 14, 25, 27, 10, 12, - 34, 16, 17, 53, 20, 26, 39, 45, - 18, 45, 35, 33, 31, 49, 4, 39, - 42, 11, 51, 5, 13, 26, 27, 17, - 52, 30, 0, 22, 12, 34, 62, 36, - 38, 41, 47, 30, 63, 38, 41, 43, - 59, 33, 45, 37, 38, 40, 47, 24, - 48, 49, 30, 1, 10, 22, 49, 15, - 39, 59, 31, 32, 33, 18, 13, 15, - 31, 21, 27, 44, 42, 39, 46, 17, - 26, 32, 30, 31, 0, 30, 34, 9, - 12, 13, 25, 31, 32, 55, 43, 35, - 61, 33, 35, 46, 25, 47, 48, 62, - 63, 38, 61, 1, 2, 5, 7, 9, - 46, 10, 34, 35, 36, 55, 51, 7, - 40, 23, 34, 37, 5, 13, 42, 18, - 25, 27, 28, -}; - -/* motion vector table 1 */ -static const uint16_t table1_mv_code[1100] = { - 0x0000, 0x0007, 0x0009, 0x000f, 0x000a, 0x0011, 0x001a, 0x001c, - 0x0011, 0x0031, 0x0025, 0x002d, 0x002f, 0x006f, 0x0075, 0x0041, - 0x004c, 0x004e, 0x005c, 0x0060, 0x0062, 0x0066, 0x0068, 0x0069, - 0x006b, 0x00a6, 0x00c1, 0x00cb, 0x00cc, 0x00ce, 0x00da, 0x00e8, - 0x00ee, 0x0087, 0x0090, 0x009e, 0x009f, 0x00ba, 0x00ca, 0x00d8, - 0x00db, 0x00df, 0x0104, 0x0109, 0x010c, 0x0143, 0x0145, 0x014a, - 0x0156, 0x015c, 0x01b3, 0x01d3, 0x01da, 0x0103, 0x0109, 0x010b, - 0x0122, 0x0127, 0x0134, 0x0161, 0x0164, 0x0176, 0x0184, 0x018d, - 0x018e, 0x018f, 0x0190, 0x0193, 0x0196, 0x019d, 0x019e, 0x019f, - 0x01a9, 0x01b2, 0x01b4, 0x01ba, 0x01bb, 0x01bc, 0x0201, 0x0202, - 0x0205, 0x0207, 0x020d, 0x0210, 0x0211, 0x0215, 0x021b, 0x021f, - 0x0281, 0x0285, 0x0290, 0x029c, 0x029d, 0x02a2, 0x02a7, 0x02a8, - 0x02aa, 0x02b0, 0x02b1, 0x02b4, 0x02bc, 0x02bf, 0x0320, 0x0326, - 0x0327, 0x0329, 0x032a, 0x0336, 0x0360, 0x0362, 0x0363, 0x0372, - 0x03b2, 0x03bc, 0x03bd, 0x0203, 0x0205, 0x021a, 0x0249, 0x024a, - 0x024c, 0x02c7, 0x02ca, 0x02ce, 0x02ef, 0x030d, 0x0322, 0x0325, - 0x0338, 0x0373, 0x037a, 0x0409, 0x0415, 0x0416, 0x0418, 0x0428, - 0x042d, 0x042f, 0x0434, 0x0508, 0x0509, 0x0510, 0x0511, 0x051c, - 0x051e, 0x0524, 0x0541, 0x0543, 0x0546, 0x0547, 0x054d, 0x0557, - 0x055f, 0x056a, 0x056c, 0x056d, 0x056f, 0x0576, 0x0577, 0x057a, - 0x057b, 0x057c, 0x057d, 0x0600, 0x0601, 0x0603, 0x0614, 0x0616, - 0x0617, 0x061c, 0x061f, 0x0642, 0x0648, 0x0649, 0x064a, 0x064b, - 0x0657, 0x0668, 0x0669, 0x066b, 0x066e, 0x067f, 0x06c2, 0x06c8, - 0x06cb, 0x06de, 0x06df, 0x06e2, 0x06e3, 0x06ef, 0x0748, 0x074b, - 0x076e, 0x076f, 0x077c, 0x0409, 0x0423, 0x0428, 0x0429, 0x042a, - 0x042b, 0x0432, 0x0433, 0x0496, 0x049a, 0x04d5, 0x04db, 0x0581, - 0x0582, 0x058b, 0x058c, 0x058d, 0x0598, 0x0599, 0x059a, 0x059e, - 0x05dd, 0x0619, 0x0632, 0x0633, 0x0648, 0x0672, 0x06a1, 0x06a2, - 0x06a3, 0x06af, 0x06e2, 0x06e3, 0x06e4, 0x0800, 0x0801, 0x0802, - 0x0803, 0x081a, 0x081b, 0x0829, 0x082f, 0x0832, 0x083e, 0x083f, - 0x0852, 0x0853, 0x0858, 0x086b, 0x0877, 0x0878, 0x0879, 0x087a, - 0x087b, 0x0a00, 0x0a01, 0x0a0d, 0x0a0e, 0x0a0f, 0x0a24, 0x0a37, - 0x0a3a, 0x0a3b, 0x0a3e, 0x0a46, 0x0a47, 0x0a4a, 0x0a4b, 0x0a5f, - 0x0a79, 0x0a7a, 0x0a7b, 0x0a80, 0x0a81, 0x0a84, 0x0a85, 0x0a99, - 0x0aa5, 0x0aa6, 0x0ab8, 0x0aba, 0x0abb, 0x0abc, 0x0abd, 0x0ac8, - 0x0ace, 0x0acf, 0x0ad7, 0x0adc, 0x0aeb, 0x0c04, 0x0c25, 0x0c26, - 0x0c27, 0x0c2a, 0x0c2b, 0x0c3a, 0x0c3b, 0x0c3c, 0x0c3d, 0x0ca0, - 0x0cad, 0x0cd4, 0x0cd5, 0x0cfc, 0x0cfd, 0x0d86, 0x0d92, 0x0d93, - 0x0d94, 0x0d95, 0x0db0, 0x0db8, 0x0db9, 0x0dba, 0x0dbb, 0x0dc0, - 0x0dc2, 0x0dc3, 0x0dda, 0x0ddb, 0x0ddc, 0x0ddd, 0x0e92, 0x0e93, - 0x0e94, 0x0e95, 0x0ec7, 0x0ecc, 0x0ece, 0x0ecf, 0x0ed8, 0x0ed9, - 0x0eda, 0x0edb, 0x0808, 0x0809, 0x080a, 0x0810, 0x0811, 0x0844, - 0x0845, 0x0861, 0x0862, 0x0863, 0x086c, 0x0922, 0x0923, 0x092e, - 0x092f, 0x0936, 0x0937, 0x09b1, 0x09b2, 0x09b3, 0x09b4, 0x09b5, - 0x09b8, 0x09b9, 0x09ba, 0x09bb, 0x09bc, 0x09bd, 0x09be, 0x09bf, - 0x0b00, 0x0b15, 0x0b2c, 0x0b2d, 0x0b2e, 0x0b2f, 0x0b36, 0x0bb9, - 0x0c28, 0x0c2a, 0x0c2b, 0x0c2c, 0x0c2d, 0x0c2e, 0x0c2f, 0x0c30, - 0x0c31, 0x0c38, 0x0c60, 0x0c61, 0x0c62, 0x0c63, 0x0c8d, 0x0c8e, - 0x0c8f, 0x0c92, 0x0cbe, 0x0cbf, 0x0ce6, 0x0ce7, 0x0d40, 0x0d41, - 0x0d57, 0x0d58, 0x0d59, 0x0d5a, 0x0d5b, 0x0d5c, 0x0d5d, 0x0d98, - 0x0d99, 0x0d9a, 0x0d9b, 0x0d9c, 0x0d9d, 0x0dad, 0x0dae, 0x0daf, - 0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3, 0x0dca, 0x0dcb, 0x0dec, 0x0ded, - 0x0dee, 0x0def, 0x1018, 0x1022, 0x1023, 0x1030, 0x1031, 0x1032, - 0x1033, 0x1050, 0x1051, 0x105c, 0x1074, 0x1075, 0x1076, 0x1077, - 0x1078, 0x1079, 0x107a, 0x107b, 0x10b2, 0x10b3, 0x10b8, 0x10b9, - 0x10ba, 0x10bb, 0x10d4, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x1404, - 0x1405, 0x1406, 0x1407, 0x1410, 0x1411, 0x1412, 0x1413, 0x1414, - 0x1415, 0x1416, 0x1417, 0x1418, 0x1419, 0x1466, 0x1467, 0x1468, - 0x1469, 0x146a, 0x146b, 0x146c, 0x146d, 0x147e, 0x147f, 0x1488, - 0x1489, 0x148a, 0x148b, 0x14b6, 0x14b7, 0x14b8, 0x14b9, 0x14ba, - 0x14bb, 0x14bc, 0x14bd, 0x14f0, 0x14f1, 0x14f8, 0x14f9, 0x14fa, - 0x14fb, 0x14fc, 0x14fd, 0x14fe, 0x14ff, 0x152a, 0x152b, 0x152c, - 0x152d, 0x152e, 0x152f, 0x1530, 0x1531, 0x1548, 0x1549, 0x154e, - 0x154f, 0x1558, 0x1559, 0x155a, 0x155b, 0x1572, 0x159a, 0x159b, - 0x15ac, 0x15ba, 0x15bb, 0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4, - 0x15d5, 0x181d, 0x181e, 0x181f, 0x1840, 0x1841, 0x1842, 0x1843, - 0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x1861, 0x1862, - 0x1863, 0x1864, 0x1865, 0x1866, 0x1867, 0x1868, 0x1869, 0x186a, - 0x186b, 0x186c, 0x186d, 0x186e, 0x191b, 0x191c, 0x191d, 0x191e, - 0x191f, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947, 0x1958, - 0x1959, 0x19ed, 0x19ee, 0x19ef, 0x19f0, 0x19f1, 0x19f2, 0x19f3, - 0x19f4, 0x19f5, 0x19f6, 0x19f7, 0x1b0e, 0x1b0f, 0x1b62, 0x1b63, - 0x1b64, 0x1b65, 0x1b66, 0x1b67, 0x1b68, 0x1b69, 0x1b6a, 0x1b6b, - 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b82, 0x1ba8, 0x1ba9, 0x1baa, - 0x1bab, 0x1bac, 0x1bad, 0x1bae, 0x1baf, 0x1bb0, 0x1bb1, 0x1bb2, - 0x1bb3, 0x1d80, 0x1d81, 0x1d82, 0x1d83, 0x1d84, 0x1d85, 0x1d86, - 0x1d87, 0x1d88, 0x1d89, 0x1d8a, 0x1d8b, 0x1d8c, 0x1d8d, 0x1007, - 0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, 0x100f, - 0x1016, 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, - 0x1087, 0x10c0, 0x123a, 0x123b, 0x123c, 0x123d, 0x123e, 0x123f, - 0x1240, 0x1241, 0x1242, 0x1243, 0x1350, 0x1352, 0x1353, 0x1358, - 0x1359, 0x135a, 0x135b, 0x135c, 0x135d, 0x135e, 0x135f, 0x1360, - 0x1361, 0x1602, 0x1603, 0x160c, 0x160d, 0x160e, 0x160f, 0x1620, - 0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627, 0x1628, - 0x1629, 0x166e, 0x166f, 0x167c, 0x167d, 0x167e, 0x167f, 0x1770, - 0x1771, 0x1852, 0x1853, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, - 0x1877, 0x1878, 0x1879, 0x187a, 0x187b, 0x187c, 0x187d, 0x187e, - 0x187f, 0x1918, 0x1919, 0x1926, 0x1927, 0x1970, 0x1971, 0x1972, - 0x1973, 0x1974, 0x1975, 0x1976, 0x1977, 0x1978, 0x1979, 0x197a, - 0x197b, 0x1aa0, 0x1aa1, 0x1aa2, 0x1aa3, 0x1aa4, 0x1aa5, 0x1aa6, - 0x1aa7, 0x1aa8, 0x1aa9, 0x1aaa, 0x1aab, 0x1aac, 0x1aad, 0x1b3c, - 0x1b3d, 0x1b3e, 0x1b3f, 0x1b50, 0x1b51, 0x1b52, 0x1b53, 0x1b54, - 0x1b55, 0x1b56, 0x1b57, 0x1b58, 0x1b59, 0x2032, 0x2033, 0x2034, - 0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203a, 0x203b, 0x203c, - 0x203d, 0x203e, 0x203f, 0x2040, 0x2041, 0x2042, 0x2043, 0x20ba, - 0x20bb, 0x20cc, 0x20cd, 0x20ce, 0x20cf, 0x20e0, 0x20e1, 0x20e2, - 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x21aa, 0x21ab, 0x21c0, - 0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, 0x21c8, - 0x21c9, 0x21ca, 0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, 0x21d0, - 0x21d1, 0x21d2, 0x21d3, 0x2894, 0x2895, 0x2896, 0x2897, 0x2898, - 0x2899, 0x289a, 0x289b, 0x289c, 0x289d, 0x289e, 0x289f, 0x28c0, - 0x28c1, 0x28c2, 0x28c3, 0x28c4, 0x28c5, 0x28c6, 0x28c7, 0x28c8, - 0x28c9, 0x28ca, 0x28cb, 0x2930, 0x2931, 0x2932, 0x2933, 0x2934, - 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, 0x293a, 0x293b, 0x293c, - 0x293d, 0x293e, 0x293f, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964, - 0x2965, 0x2966, 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x2a40, - 0x2a41, 0x2a42, 0x2a43, 0x2a44, 0x2a45, 0x2a46, 0x2a47, 0x2a48, - 0x2a49, 0x2a4a, 0x2a4b, 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 0x2a50, - 0x2a51, 0x2a52, 0x2a53, 0x2ae6, 0x2ae7, 0x2b24, 0x2b25, 0x2b26, - 0x2b27, 0x2b28, 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e, - 0x2b2f, 0x2b30, 0x2b31, 0x2b32, 0x2b33, 0x2b5a, 0x2b5b, 0x3014, - 0x3015, 0x3016, 0x3017, 0x3020, 0x3021, 0x3022, 0x3023, 0x3024, - 0x3025, 0x3026, 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, 0x302c, - 0x302d, 0x302e, 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, - 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, 0x30c0, 0x30c1, 0x30de, - 0x30df, 0x3218, 0x3219, 0x321a, 0x321b, 0x321c, 0x321d, 0x321e, - 0x321f, 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, - 0x3227, 0x3228, 0x3229, 0x322a, 0x322b, 0x322c, 0x322d, 0x322e, - 0x322f, 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3378, - 0x3379, 0x337a, 0x337b, 0x337c, 0x337d, 0x337e, 0x337f, 0x33c0, - 0x33c1, 0x33c2, 0x33c3, 0x33c4, 0x33c5, 0x33c6, 0x33c7, 0x33c8, - 0x33c9, 0x33ca, 0x33cb, 0x33cc, 0x33cd, 0x33ce, 0x33cf, 0x33d0, - 0x33d1, 0x33d2, 0x33d3, 0x33d4, 0x33d5, 0x33d6, 0x33d7, 0x33d8, - 0x33d9, 0x3706, 0x3707, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, - 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c, - 0x373d, 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744, - 0x3745, 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c, - 0x374d, 0x374e, 0x374f, 0x3b34, 0x3b35, 0x3b36, 0x3b37, 0x3be8, - 0x3be9, 0x3bea, 0x3beb, 0x3bec, 0x3bed, 0x3bee, 0x3bef, 0x3bf0, - 0x3bf1, 0x3bf2, 0x3bf3, 0x3bf4, 0x3bf5, 0x3bf6, 0x3bf7, 0x3bf8, - 0x3bf9, 0x3bfa, 0x3bfb, 0x3bfc, 0x3bfd, 0x3bfe, 0x3bff, 0x2000, - 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, - 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x202e, 0x202f, 0x2182, - 0x2183, 0x21b4, 0x21b5, 0x21b6, 0x21b7, 0x21b8, 0x21b9, 0x21ba, - 0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x2460, 0x2461, 0x2462, - 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a, - 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472, - 0x2473, 0x26a2, 0x26a3, 0x000b, -}; - -static const uint8_t table1_mv_bits[1100] = { - 2, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 7, 7, 7, 7, 7, 8, - 8, 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, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 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, 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, 11, 11, 11, 11, 11, - 11, 11, 11, 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, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 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, 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, 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, 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, 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, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 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 table1_mvx[1099] = { - 32, 31, 32, 31, 33, 32, 33, 33, - 31, 34, 30, 32, 32, 34, 35, 32, - 34, 33, 29, 30, 30, 32, 31, 31, - 33, 35, 35, 33, 31, 29, 29, 33, - 34, 30, 31, 28, 36, 30, 34, 32, - 32, 37, 32, 32, 25, 27, 39, 32, - 32, 32, 38, 35, 36, 32, 37, 61, - 26, 32, 34, 35, 3, 35, 27, 28, - 29, 34, 28, 37, 31, 36, 32, 27, - 31, 30, 29, 39, 33, 29, 33, 35, - 25, 25, 29, 33, 31, 31, 31, 33, - 32, 30, 32, 32, 41, 39, 33, 36, - 32, 28, 34, 36, 38, 24, 60, 31, - 23, 28, 32, 33, 59, 32, 40, 30, - 5, 34, 32, 38, 32, 30, 43, 4, - 32, 32, 42, 31, 31, 32, 26, 38, - 26, 22, 21, 37, 61, 63, 37, 31, - 32, 33, 2, 1, 23, 33, 41, 27, - 35, 30, 38, 23, 33, 3, 28, 34, - 34, 27, 41, 29, 39, 35, 36, 29, - 32, 27, 30, 32, 24, 61, 37, 26, - 59, 25, 35, 27, 36, 37, 30, 31, - 34, 40, 3, 28, 34, 39, 32, 31, - 32, 30, 24, 28, 35, 36, 26, 32, - 31, 33, 29, 33, 39, 25, 30, 24, - 35, 59, 29, 34, 25, 30, 21, 35, - 43, 40, 32, 29, 5, 28, 31, 62, - 33, 33, 25, 31, 21, 31, 43, 31, - 34, 33, 20, 40, 39, 31, 31, 57, - 38, 32, 42, 33, 32, 31, 32, 29, - 30, 44, 5, 31, 22, 34, 36, 17, - 38, 58, 38, 35, 32, 60, 35, 24, - 32, 38, 16, 45, 42, 32, 31, 29, - 4, 30, 17, 40, 46, 48, 63, 32, - 42, 19, 41, 22, 28, 36, 45, 33, - 33, 32, 29, 7, 41, 42, 18, 33, - 33, 32, 22, 37, 1, 26, 22, 23, - 49, 28, 26, 27, 32, 33, 27, 23, - 28, 36, 15, 6, 34, 27, 31, 26, - 23, 2, 33, 32, 34, 41, 28, 32, - 41, 0, 36, 38, 34, 31, 47, 32, - 17, 31, 39, 33, 37, 51, 30, 47, - 32, 50, 32, 19, 63, 30, 25, 27, - 33, 62, 24, 31, 27, 30, 37, 31, - 45, 32, 39, 20, 46, 47, 35, 19, - 34, 1, 49, 21, 21, 14, 51, 26, - 23, 31, 36, 35, 58, 29, 29, 21, - 20, 42, 13, 28, 12, 40, 31, 33, - 39, 60, 32, 44, 33, 31, 28, 37, - 29, 32, 30, 49, 43, 28, 39, 25, - 32, 48, 2, 15, 20, 25, 31, 28, - 21, 24, 25, 15, 31, 17, 37, 43, - 18, 32, 33, 24, 33, 36, 13, 33, - 31, 39, 11, 31, 33, 32, 39, 37, - 32, 32, 29, 17, 44, 46, 36, 35, - 26, 37, 58, 32, 34, 38, 8, 38, - 38, 22, 29, 25, 16, 35, 32, 35, - 33, 43, 18, 46, 38, 50, 33, 18, - 53, 60, 13, 32, 36, 33, 51, 36, - 43, 45, 27, 42, 29, 24, 30, 25, - 31, 52, 31, 35, 38, 9, 22, 34, - 4, 17, 28, 55, 42, 25, 17, 20, - 47, 34, 33, 16, 40, 25, 16, 30, - 53, 29, 10, 11, 14, 26, 33, 4, - 35, 44, 26, 16, 31, 26, 34, 38, - 29, 31, 30, 24, 22, 61, 32, 9, - 45, 34, 31, 19, 9, 31, 46, 31, - 35, 54, 29, 57, 30, 50, 3, 31, - 63, 34, 47, 41, 51, 18, 31, 14, - 37, 38, 31, 24, 32, 31, 50, 33, - 31, 54, 27, 9, 33, 23, 19, 32, - 29, 29, 33, 28, 47, 49, 30, 47, - 33, 27, 25, 54, 44, 45, 50, 58, - 51, 48, 33, 59, 33, 34, 57, 13, - 26, 33, 13, 48, 30, 11, 7, 56, - 34, 55, 26, 0, 26, 35, 1, 51, - 33, 53, 31, 45, 12, 29, 29, 51, - 31, 48, 2, 6, 34, 30, 28, 33, - 60, 40, 27, 46, 31, 9, 35, 29, - 31, 39, 55, 46, 19, 37, 62, 34, - 30, 16, 19, 49, 41, 41, 39, 37, - 14, 5, 13, 35, 55, 30, 40, 40, - 42, 8, 20, 25, 45, 35, 33, 36, - 54, 38, 27, 37, 62, 40, 15, 59, - 49, 31, 29, 34, 34, 39, 24, 29, - 25, 29, 21, 29, 10, 61, 33, 49, - 35, 34, 3, 38, 39, 29, 7, 41, - 1, 35, 4, 23, 15, 23, 11, 37, - 28, 35, 30, 30, 24, 1, 43, 56, - 8, 34, 42, 24, 45, 30, 20, 23, - 8, 38, 22, 33, 17, 52, 34, 22, - 53, 43, 44, 1, 27, 31, 41, 43, - 41, 30, 31, 36, 30, 5, 55, 31, - 33, 30, 40, 23, 15, 29, 34, 34, - 59, 34, 30, 11, 13, 38, 5, 0, - 30, 42, 5, 30, 29, 34, 10, 44, - 30, 63, 35, 12, 3, 26, 15, 17, - 25, 34, 43, 39, 34, 56, 29, 23, - 30, 12, 30, 10, 35, 9, 24, 58, - 10, 12, 54, 33, 37, 20, 41, 35, - 29, 18, 61, 30, 40, 24, 39, 53, - 62, 26, 29, 33, 34, 53, 49, 21, - 27, 11, 63, 20, 26, 23, 7, 13, - 6, 47, 29, 30, 9, 51, 22, 34, - 21, 25, 33, 56, 57, 30, 38, 51, - 51, 38, 63, 28, 40, 35, 33, 18, - 33, 33, 24, 58, 58, 34, 49, 29, - 43, 4, 1, 4, 42, 35, 35, 30, - 17, 5, 56, 61, 25, 37, 36, 55, - 28, 35, 29, 50, 48, 52, 2, 42, - 34, 40, 46, 46, 43, 35, 29, 48, - 20, 29, 31, 41, 7, 30, 35, 19, - 14, 21, 8, 39, 39, 40, 46, 55, - 34, 6, 30, 34, 37, 25, 37, 33, - 22, 44, 52, 17, 35, 29, 36, 35, - 40, 37, 28, 30, 50, 14, 28, 55, - 6, 23, 19, 14, 30, 3, 30, 28, - 28, 61, 61, 47, 45, 48, 40, 40, - 34, 34, 25, 30, 29, 35, 4, 26, - 53, 50, 26, 41, 27, 59, 27, 38, - 39, 3, 50, 43, 47, 23, 33, 55, - 35, 21, 23, 35, 61, 33, 46, 52, - 35, 34, 24, 30, 43, 16, 37, 21, - 2, 24, 45, 34, 30, 55, 55, 1, - 29, 29, 26, 28, 25, 31, 36, 22, - 17, 30, 52, 2, 44, 44, 57, 26, - 62, 41, 39, 57, 26, 46, 49, 11, - 16, 19, 5, 59, 38, 39, 58, 38, - 25, 49, 50, 22, 28, 59, 9, 59, - 7, 28, 55, 17, 4, 35, 50, 21, - 29, 44, 47, 18, 24, 19, 25, 42, - 35, 3, 51, 35, 16, 35, 30, 63, - 57, 39, 39, 25, 35, 38, 9, 16, - 36, 45, 31, 60, 14, 34, 42, 24, - 0, 37, 18, 61, 57, 37, 28, 53, - 20, 46, 14, 47, 38, 38, 38, 9, - 34, 39, 43, 17, 39, 59, 5, 27, - 0, 12, 27, -}; - -static const uint8_t table1_mvy[1099] = { - 32, 32, 31, 31, 32, 33, 31, 33, - 33, 32, 32, 30, 34, 31, 32, 29, - 33, 30, 32, 33, 31, 35, 34, 30, - 34, 31, 33, 29, 29, 31, 33, 35, - 30, 30, 35, 32, 32, 34, 34, 28, - 25, 32, 36, 27, 32, 32, 32, 37, - 39, 3, 32, 30, 31, 26, 31, 32, - 32, 38, 29, 29, 32, 34, 31, 31, - 34, 35, 33, 33, 28, 33, 1, 33, - 27, 29, 30, 31, 28, 29, 37, 35, - 31, 33, 35, 27, 36, 37, 25, 25, - 61, 35, 4, 5, 32, 33, 36, 30, - 23, 30, 28, 34, 31, 32, 32, 39, - 32, 34, 21, 39, 32, 59, 32, 28, - 32, 36, 60, 33, 24, 36, 32, 32, - 41, 2, 32, 38, 26, 22, 33, 30, - 31, 32, 32, 30, 31, 32, 29, 3, - 40, 38, 32, 32, 33, 26, 31, 34, - 28, 38, 34, 31, 3, 31, 35, 38, - 27, 35, 33, 28, 29, 27, 29, 27, - 43, 29, 37, 63, 31, 33, 34, 30, - 31, 30, 37, 30, 35, 35, 26, 41, - 37, 31, 33, 28, 26, 30, 42, 24, - 7, 27, 33, 29, 36, 28, 34, 57, - 23, 41, 36, 23, 35, 34, 25, 30, - 25, 33, 25, 25, 29, 24, 33, 39, - 33, 33, 0, 37, 31, 36, 21, 32, - 61, 24, 35, 61, 31, 5, 31, 59, - 39, 21, 32, 30, 34, 22, 40, 32, - 29, 16, 31, 5, 62, 2, 20, 39, - 39, 32, 33, 1, 31, 24, 36, 32, - 36, 32, 28, 26, 6, 31, 38, 34, - 58, 35, 32, 33, 33, 17, 43, 26, - 31, 40, 31, 34, 32, 32, 31, 19, - 30, 32, 29, 33, 38, 38, 32, 59, - 40, 18, 38, 32, 35, 34, 32, 17, - 1, 15, 30, 28, 31, 28, 34, 29, - 32, 27, 35, 27, 49, 22, 37, 34, - 37, 26, 32, 32, 22, 28, 45, 29, - 30, 31, 43, 46, 41, 30, 26, 13, - 34, 32, 27, 38, 42, 42, 33, 47, - 33, 60, 27, 42, 25, 32, 22, 32, - 48, 32, 45, 33, 33, 41, 27, 25, - 19, 31, 35, 19, 36, 42, 27, 17, - 31, 44, 28, 33, 33, 31, 23, 31, - 40, 33, 31, 34, 30, 32, 33, 36, - 35, 47, 37, 41, 31, 23, 41, 29, - 30, 35, 32, 25, 32, 28, 58, 2, - 37, 33, 14, 33, 49, 20, 39, 36, - 21, 9, 23, 33, 35, 24, 39, 37, - 11, 33, 30, 31, 31, 28, 51, 40, - 35, 29, 25, 33, 46, 35, 37, 30, - 30, 8, 63, 28, 15, 40, 33, 45, - 49, 25, 32, 4, 47, 51, 36, 39, - 53, 10, 24, 29, 30, 31, 25, 40, - 38, 38, 33, 56, 23, 27, 32, 37, - 26, 29, 43, 36, 33, 24, 55, 43, - 9, 29, 34, 34, 24, 33, 18, 33, - 33, 30, 31, 50, 24, 60, 30, 39, - 34, 30, 39, 28, 22, 38, 2, 26, - 63, 32, 57, 21, 39, 33, 28, 18, - 30, 34, 22, 33, 29, 41, 30, 34, - 35, 21, 13, 34, 35, 39, 30, 46, - 32, 42, 32, 31, 33, 26, 11, 33, - 22, 31, 25, 31, 53, 27, 43, 25, - 40, 50, 21, 36, 38, 30, 12, 31, - 34, 20, 15, 29, 32, 62, 30, 13, - 17, 32, 19, 31, 20, 31, 30, 7, - 1, 17, 34, 37, 31, 31, 44, 34, - 26, 40, 16, 37, 52, 48, 30, 20, - 18, 33, 38, 29, 7, 25, 30, 54, - 45, 47, 46, 41, 29, 29, 16, 30, - 14, 26, 38, 34, 34, 29, 34, 30, - 29, 30, 57, 30, 4, 46, 33, 29, - 39, 44, 30, 31, 50, 33, 31, 32, - 19, 32, 40, 31, 37, 47, 1, 35, - 16, 31, 0, 35, 33, 1, 17, 34, - 9, 34, 33, 31, 49, 43, 42, 51, - 34, 29, 23, 29, 14, 30, 45, 49, - 11, 24, 31, 28, 35, 41, 30, 44, - 18, 29, 34, 35, 36, 25, 26, 21, - 31, 30, 34, 19, 34, 44, 36, 38, - 25, 31, 28, 23, 37, 3, 55, 41, - 30, 22, 41, 24, 33, 26, 35, 35, - 30, 55, 51, 47, 48, 38, 24, 15, - 21, 50, 25, 46, 30, 29, 10, 34, - 42, 45, 29, 42, 22, 3, 33, 27, - 34, 1, 34, 28, 34, 36, 35, 23, - 23, 13, 58, 3, 26, 63, 25, 31, - 34, 61, 38, 39, 25, 61, 29, 37, - 30, 41, 26, 48, 28, 33, 50, 35, - 30, 37, 29, 29, 40, 6, 39, 28, - 28, 19, 8, 22, 45, 34, 35, 10, - 58, 17, 37, 39, 30, 18, 54, 14, - 29, 16, 59, 30, 35, 23, 35, 30, - 47, 36, 29, 55, 20, 12, 31, 35, - 14, 29, 18, 34, 34, 24, 29, 26, - 22, 2, 27, 23, 8, 30, 55, 38, - 60, 31, 4, 34, 49, 34, 27, 34, - 33, 30, 31, 54, 42, 35, 38, 46, - 44, 26, 27, 9, 39, 25, 21, 29, - 28, 42, 13, 0, 5, 34, 37, 28, - 24, 29, 63, 26, 22, 27, 29, 25, - 33, 25, 61, 0, 35, 25, 36, 15, - 27, 40, 53, 33, 3, 10, 16, 37, - 38, 18, 30, 46, 27, 9, 6, 29, - 62, 8, 42, 28, 29, 3, 25, 16, - 26, 29, 35, 28, 27, 51, 61, 48, - 37, 9, 34, 7, 49, 45, 20, 29, - 21, 5, 5, 29, 28, 34, 29, 24, - 10, 24, 35, 36, 38, 55, 11, 36, - 38, 53, 54, 26, 30, 49, 20, 27, - 30, 39, 33, 41, 49, 22, 38, 38, - 4, 30, 8, 9, 3, 24, 22, 50, - 37, 36, 31, 27, 2, 9, 42, 63, - 25, 19, 44, 1, 28, 28, 48, 30, - 34, 41, 41, 38, 12, 27, 15, 0, - 16, 34, 35, 38, 28, 29, 40, 42, - 51, 52, 45, 54, 59, 59, 42, 44, - 37, 26, 46, 24, 15, 39, 22, 46, - 19, 35, 38, 17, 37, 23, 52, 55, - 50, 37, 26, 11, 37, 12, 24, 30, - 16, 13, 22, 13, 36, 35, 40, 41, - 34, 41, 26, 53, 51, 5, 21, 30, - 2, 63, 41, 20, 1, 56, 21, 24, - 25, 5, 28, 35, 26, 28, 30, 18, - 29, 23, 40, 34, 20, 42, 39, 34, - 28, 61, 38, 27, 62, 9, 36, 17, - 9, 49, 24, 25, 54, 34, 39, 37, - 3, 1, 25, 38, 38, 44, 35, 36, - 12, 60, 36, 38, 40, 25, 43, 39, - 53, 28, 39, 57, 46, 10, 52, 27, - 35, 42, 45, 59, 15, 60, 38, 24, - 23, 39, 12, 29, 24, 0, 20, 16, - 28, 43, 35, 28, 1, 49, 4, 21, - 42, 39, 29, 3, 44, 21, 53, 55, - 11, 5, 3, 39, 53, 28, 25, 19, - 34, 28, 21, -}; - -MVTable mv_tables[2] = { - { - 1099, - table0_mv_code, - table0_mv_bits, - table0_mvx, - table0_mvy, - }, - { - 1099, - table1_mv_code, - table1_mv_bits, - table1_mvx, - table1_mvy, - } -}; - -const uint8_t v2_mb_type[8][2] = { - {1, 1}, {0 , 2}, {3 , 3}, {9 , 5}, - {5, 4}, {0x21, 7}, {0x20, 7}, {0x11, 6}, -}; - -const uint8_t v2_intra_cbpc[4][2] = { - {1, 1}, {0, 3}, {1, 3}, {1, 2}, -}; - -const uint8_t wmv1_y_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, 8, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 -}; -const uint8_t wmv1_c_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, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 -}; - -const uint8_t old_ff_y_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, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 -}; - -const uint8_t wmv1_scantable[WMV1_SCANTABLE_COUNT][64]={ - { - 0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, - 0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, - 0x30, 0x38, 0x29, 0x21, 0x1A, 0x13, 0x0C, 0x05, - 0x06, 0x0D, 0x14, 0x1B, 0x22, 0x31, 0x39, 0x3A, - 0x32, 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, - 0x16, 0x1D, 0x24, 0x2B, 0x33, 0x3B, 0x3C, 0x34, - 0x2C, 0x25, 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x35, - 0x3D, 0x3E, 0x36, 0x2E, 0x27, 0x2F, 0x37, 0x3F, - }, - { - 0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, - 0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, - 0x21, 0x30, 0x1A, 0x13, 0x0C, 0x05, 0x06, 0x0D, - 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, 0x2A, - 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, 0x16, 0x1D, - 0x24, 0x2B, 0x32, 0x3A, 0x33, 0x3B, 0x2C, 0x25, - 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3C, 0x35, - 0x3D, 0x2E, 0x27, 0x2F, 0x36, 0x3E, 0x37, 0x3F, - }, - { - 0x00, 0x01, 0x08, 0x02, 0x03, 0x09, 0x10, 0x18, - 0x11, 0x0A, 0x04, 0x05, 0x0B, 0x12, 0x19, 0x20, - 0x28, 0x30, 0x21, 0x1A, 0x13, 0x0C, 0x06, 0x07, - 0x0D, 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, - 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x0F, 0x16, 0x1D, - 0x24, 0x2B, 0x32, 0x3A, 0x33, 0x2C, 0x25, 0x1E, - 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x3C, 0x35, - 0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, - }, - { - 0x00, 0x08, 0x10, 0x01, 0x18, 0x20, 0x28, 0x09, - 0x02, 0x03, 0x0A, 0x11, 0x19, 0x30, 0x38, 0x29, - 0x21, 0x1A, 0x12, 0x0B, 0x04, 0x05, 0x0C, 0x13, - 0x1B, 0x22, 0x31, 0x39, 0x32, 0x2A, 0x23, 0x1C, - 0x14, 0x0D, 0x06, 0x07, 0x0E, 0x15, 0x1D, 0x24, - 0x2B, 0x33, 0x3A, 0x3B, 0x34, 0x2C, 0x25, 0x1E, - 0x16, 0x0F, 0x17, 0x1F, 0x26, 0x2D, 0x3C, 0x35, - 0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, - } -}; - -const uint8_t table_inter_intra[4][2]={ - {0,1} /*Luma-Left Chroma-Left*/, - {2,2} /*Luma-Top Chroma-Left*/, - {6,3} /*luma-Left Chroma-Top */, - {7,3} /*luma-Top Chroma-Top */ -}; - -static const uint32_t table_mb_non_intra2[128][2] = { -{0x0000A7, 14}, {0x01B2B8, 18}, {0x01B28E, 18}, {0x036575, 19}, -{0x006CAC, 16}, {0x000A69, 18}, {0x002934, 20}, {0x00526B, 21}, -{0x006CA1, 16}, {0x01B2B9, 18}, {0x0029AD, 20}, {0x029353, 24}, -{0x006CA7, 16}, {0x006CAB, 16}, {0x01B2BB, 18}, {0x00029B, 16}, -{0x00D944, 17}, {0x000A6A, 18}, {0x0149A8, 23}, {0x03651F, 19}, -{0x006CAF, 16}, {0x000A4C, 18}, {0x03651E, 19}, {0x000A48, 18}, -{0x00299C, 20}, {0x00299F, 20}, {0x029352, 24}, {0x0029AC, 20}, -{0x000296, 16}, {0x00D946, 17}, {0x000A68, 18}, {0x000298, 16}, -{0x000527, 17}, {0x00D94D, 17}, {0x0014D7, 19}, {0x036574, 19}, -{0x000A5C, 18}, {0x01B299, 18}, {0x00299D, 20}, {0x00299E, 20}, -{0x000525, 17}, {0x000A66, 18}, {0x00A4D5, 22}, {0x00149B, 19}, -{0x000295, 16}, {0x006CAD, 16}, {0x000A49, 18}, {0x000521, 17}, -{0x006CAA, 16}, {0x00D945, 17}, {0x01B298, 18}, {0x00052F, 17}, -{0x003654, 15}, {0x006CA0, 16}, {0x000532, 17}, {0x000291, 16}, -{0x003652, 15}, {0x000520, 17}, {0x000A5D, 18}, {0x000294, 16}, -{0x00009B, 11}, {0x0006E2, 12}, {0x000028, 12}, {0x0001B0, 10}, -{0x000001, 3}, {0x000010, 8}, {0x00002F, 6}, {0x00004C, 10}, -{0x00000D, 4}, {0x000000, 10}, {0x000006, 9}, {0x000134, 12}, -{0x00000C, 4}, {0x000007, 10}, {0x000007, 9}, {0x0006E1, 12}, -{0x00000E, 5}, {0x0000DA, 9}, {0x000022, 9}, {0x000364, 11}, -{0x00000F, 4}, {0x000006, 10}, {0x00000F, 9}, {0x000135, 12}, -{0x000014, 5}, {0x0000DD, 9}, {0x000004, 9}, {0x000015, 11}, -{0x00001A, 6}, {0x0001B3, 10}, {0x000005, 10}, {0x0006E3, 12}, -{0x00000C, 5}, {0x0000B9, 8}, {0x000004, 8}, {0x0000DB, 9}, -{0x00000E, 4}, {0x00000B, 10}, {0x000023, 9}, {0x0006CB, 12}, -{0x000005, 6}, {0x0001B1, 10}, {0x000001, 10}, {0x0006E0, 12}, -{0x000011, 5}, {0x0000DF, 9}, {0x00000E, 9}, {0x000373, 11}, -{0x000003, 5}, {0x0000B8, 8}, {0x000006, 8}, {0x000175, 9}, -{0x000015, 5}, {0x000174, 9}, {0x000027, 9}, {0x000372, 11}, -{0x000010, 5}, {0x0000BB, 8}, {0x000005, 8}, {0x0000DE, 9}, -{0x00000F, 5}, {0x000001, 9}, {0x000012, 8}, {0x000004, 10}, -{0x000002, 3}, {0x000016, 5}, {0x000009, 4}, {0x000001, 5}, -}; - -static const uint32_t table_mb_non_intra3[128][2] = { -{0x0002A1, 10}, {0x005740, 15}, {0x01A0BF, 18}, {0x015D19, 17}, -{0x001514, 13}, {0x00461E, 15}, {0x015176, 17}, {0x015177, 17}, -{0x0011AD, 13}, {0x00682E, 16}, {0x0682F9, 20}, {0x03417D, 19}, -{0x001A36, 14}, {0x002A2D, 14}, {0x00D05E, 17}, {0x006824, 16}, -{0x001515, 13}, {0x00545C, 15}, {0x0230E9, 18}, {0x011AFA, 17}, -{0x0015D7, 13}, {0x005747, 15}, {0x008D79, 16}, {0x006825, 16}, -{0x002BA2, 14}, {0x00A8BA, 16}, {0x0235F6, 18}, {0x015D18, 17}, -{0x0011AE, 13}, {0x00346F, 15}, {0x008C3B, 16}, {0x00346E, 15}, -{0x000D1A, 13}, {0x00461F, 15}, {0x0682F8, 20}, {0x011875, 17}, -{0x002BA1, 14}, {0x008D61, 16}, {0x0235F7, 18}, {0x0230E8, 18}, -{0x001513, 13}, {0x008D7B, 16}, {0x011AF4, 17}, {0x011AF5, 17}, -{0x001185, 13}, {0x0046BF, 15}, {0x008D60, 16}, {0x008D7C, 16}, -{0x001512, 13}, {0x00461C, 15}, {0x00AE8D, 16}, {0x008D78, 16}, -{0x000D0E, 13}, {0x003413, 15}, {0x0046B1, 15}, {0x003416, 15}, -{0x000AEA, 12}, {0x002A2C, 14}, {0x005741, 15}, {0x002A2F, 14}, -{0x000158, 9}, {0x0008D2, 12}, {0x00054C, 11}, {0x000686, 12}, -{0x000000, 2}, {0x000069, 8}, {0x00006B, 8}, {0x00068C, 12}, -{0x000007, 3}, {0x00015E, 9}, {0x0002A3, 10}, {0x000AE9, 12}, -{0x000006, 3}, {0x000231, 10}, {0x0002B8, 10}, {0x001A08, 14}, -{0x000010, 5}, {0x0001A9, 10}, {0x000342, 11}, {0x000A88, 12}, -{0x000004, 4}, {0x0001A2, 10}, {0x0002A4, 10}, {0x001184, 13}, -{0x000012, 5}, {0x000232, 10}, {0x0002B2, 10}, {0x000680, 12}, -{0x00001B, 6}, {0x00046A, 11}, {0x00068E, 12}, {0x002359, 14}, -{0x000016, 5}, {0x00015F, 9}, {0x0002A0, 10}, {0x00054D, 11}, -{0x000005, 4}, {0x000233, 10}, {0x0002B9, 10}, {0x0015D6, 13}, -{0x000022, 6}, {0x000468, 11}, {0x000683, 12}, {0x001A0A, 14}, -{0x000013, 5}, {0x000236, 10}, {0x0002BB, 10}, {0x001186, 13}, -{0x000017, 5}, {0x0001AB, 10}, {0x0002A7, 10}, {0x0008D3, 12}, -{0x000014, 5}, {0x000237, 10}, {0x000460, 11}, {0x000D0F, 13}, -{0x000019, 6}, {0x0001AA, 10}, {0x0002B3, 10}, {0x000681, 12}, -{0x000018, 6}, {0x0001A8, 10}, {0x0002A5, 10}, {0x00068F, 12}, -{0x000007, 4}, {0x000055, 7}, {0x000047, 7}, {0x0000AD, 8}, -}; - -static const uint32_t table_mb_non_intra4[128][2] = { -{0x0000D4, 8}, {0x0021C5, 14}, {0x00F18A, 16}, {0x00D5BC, 16}, -{0x000879, 12}, {0x00354D, 14}, {0x010E3F, 17}, {0x010F54, 17}, -{0x000866, 12}, {0x00356E, 14}, {0x010F55, 17}, {0x010E3E, 17}, -{0x0010CE, 13}, {0x003C84, 14}, {0x00D5BD, 16}, {0x00F18B, 16}, -{0x000868, 12}, {0x00438C, 15}, {0x0087AB, 16}, {0x00790B, 15}, -{0x000F10, 12}, {0x00433D, 15}, {0x006AD3, 15}, {0x00790A, 15}, -{0x001AA7, 13}, {0x0043D4, 15}, {0x00871E, 16}, {0x006ADF, 15}, -{0x000D7C, 12}, {0x003C94, 14}, {0x00438D, 15}, {0x006AD2, 15}, -{0x0006BC, 11}, {0x0021E9, 14}, {0x006ADA, 15}, {0x006A99, 15}, -{0x0010F7, 13}, {0x004389, 15}, {0x006ADB, 15}, {0x0078C4, 15}, -{0x000D56, 12}, {0x0035F7, 14}, {0x00438E, 15}, {0x006A98, 15}, -{0x000D52, 12}, {0x003C95, 14}, {0x004388, 15}, {0x00433C, 15}, -{0x000D54, 12}, {0x001E4B, 13}, {0x003C63, 14}, {0x003C83, 14}, -{0x000861, 12}, {0x0021EB, 14}, {0x00356C, 14}, {0x0035F6, 14}, -{0x000863, 12}, {0x00219F, 14}, {0x003568, 14}, {0x003C82, 14}, -{0x0001AE, 9}, {0x0010C0, 13}, {0x000F11, 12}, {0x001AFA, 13}, -{0x000000, 1}, {0x0000F0, 8}, {0x0001AD, 9}, {0x0010C1, 13}, -{0x00000A, 4}, {0x0003C5, 10}, {0x000789, 11}, {0x001AB5, 13}, -{0x000009, 4}, {0x000435, 11}, {0x000793, 11}, {0x001E40, 13}, -{0x00001D, 5}, {0x0003CB, 10}, {0x000878, 12}, {0x001AAF, 13}, -{0x00000B, 4}, {0x0003C7, 10}, {0x000791, 11}, {0x001AAB, 13}, -{0x00001F, 5}, {0x000436, 11}, {0x0006BF, 11}, {0x000F19, 12}, -{0x00003D, 6}, {0x000D51, 12}, {0x0010C4, 13}, {0x0021E8, 14}, -{0x000036, 6}, {0x000437, 11}, {0x0006AF, 11}, {0x0010C5, 13}, -{0x00000C, 4}, {0x000432, 11}, {0x000794, 11}, {0x001E30, 13}, -{0x000042, 7}, {0x000870, 12}, {0x000F24, 12}, {0x001E43, 13}, -{0x000020, 6}, {0x00043E, 11}, {0x000795, 11}, {0x001AAA, 13}, -{0x000037, 6}, {0x0006AC, 11}, {0x0006AE, 11}, {0x0010F6, 13}, -{0x000034, 6}, {0x00043A, 11}, {0x000D50, 12}, {0x001AAE, 13}, -{0x000039, 6}, {0x00043F, 11}, {0x00078D, 11}, {0x0010D2, 13}, -{0x000038, 6}, {0x00043B, 11}, {0x0006BD, 11}, {0x0010D3, 13}, -{0x000011, 5}, {0x0001AC, 9}, {0x0000F3, 8}, {0x000439, 11}, -}; - -const uint32_t (* const wmv2_inter_table[WMV2_INTER_CBP_TABLE_COUNT])[2]={ - table_mb_non_intra2, - table_mb_non_intra3, - table_mb_non_intra4, - table_mb_non_intra, -}; - -const uint8_t wmv2_scantableA[64]={ -0x00, 0x01, 0x02, 0x08, 0x03, 0x09, 0x0A, 0x10, -0x04, 0x0B, 0x11, 0x18, 0x12, 0x0C, 0x05, 0x13, -0x19, 0x0D, 0x14, 0x1A, 0x1B, 0x06, 0x15, 0x1C, -0x0E, 0x16, 0x1D, 0x07, 0x1E, 0x0F, 0x17, 0x1F, -}; - -const uint8_t wmv2_scantableB[64]={ -0x00, 0x08, 0x01, 0x10, 0x09, 0x18, 0x11, 0x02, -0x20, 0x0A, 0x19, 0x28, 0x12, 0x30, 0x21, 0x1A, -0x38, 0x29, 0x22, 0x03, 0x31, 0x39, 0x0B, 0x2A, -0x13, 0x32, 0x1B, 0x3A, 0x23, 0x2B, 0x33, 0x3B, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/msmpeg4data.h b/tizen/distrib/ffmpeg/libavcodec/msmpeg4data.h deleted file mode 100644 index 623d957..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msmpeg4data.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * MSMPEG4 backend for ffmpeg encoder and decoder - * copyright (c) 2001 Fabrice Bellard - * copyright (c) 2002-2004 Michael Niedermayer - * - * msmpeg4v1 & v2 stuff by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MSMPEG4 data tables. - */ - -#ifndef AVCODEC_MSMPEG4DATA_H -#define AVCODEC_MSMPEG4DATA_H - -#include "libavutil/common.h" -#include "get_bits.h" -#include "rl.h" - -/* motion vector table */ -typedef struct MVTable { - int n; - const uint16_t *table_mv_code; - const uint8_t *table_mv_bits; - const uint8_t *table_mvx; - const uint8_t *table_mvy; - uint16_t *table_mv_index; /* encoding: convert mv to index in table_mv */ - VLC vlc; /* decoding: vlc */ -} MVTable; - -extern VLC ff_msmp4_mb_i_vlc; -extern VLC ff_msmp4_dc_luma_vlc[2]; -extern VLC ff_msmp4_dc_chroma_vlc[2]; - -/* intra picture macroblock coded block pattern */ -extern const uint16_t ff_msmp4_mb_i_table[64][2]; - -#define WMV1_SCANTABLE_COUNT 4 - -extern const uint8_t wmv1_scantable[WMV1_SCANTABLE_COUNT][64]; - -#define NB_RL_TABLES 6 - -extern RLTable rl_table[NB_RL_TABLES]; - -extern const uint8_t wmv1_y_dc_scale_table[32]; -extern const uint8_t wmv1_c_dc_scale_table[32]; -extern const uint8_t old_ff_y_dc_scale_table[32]; - -extern MVTable mv_tables[2]; - -extern const uint8_t v2_mb_type[8][2]; -extern const uint8_t v2_intra_cbpc[4][2]; - -extern const uint32_t table_mb_non_intra[128][2]; -extern const uint8_t table_inter_intra[4][2]; - -extern const uint32_t ff_table0_dc_lum[120][2]; -extern const uint32_t ff_table1_dc_lum[120][2]; -extern const uint32_t ff_table0_dc_chroma[120][2]; -extern const uint32_t ff_table1_dc_chroma[120][2]; - -#define WMV2_INTER_CBP_TABLE_COUNT 4 -extern const uint32_t (* const wmv2_inter_table[WMV2_INTER_CBP_TABLE_COUNT])[2]; - -extern const uint8_t wmv2_scantableA[64]; -extern const uint8_t wmv2_scantableB[64]; - -#endif /* AVCODEC_MSMPEG4DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/msrle.c b/tizen/distrib/ffmpeg/libavcodec/msrle.c deleted file mode 100644 index 28eb5d3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msrle.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Micrsoft RLE Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MS RLE Video Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the MS RLE format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * The MS RLE decoder outputs PAL8 colorspace data. - * - * Note that this decoder expects the palette colors from the end of the - * BITMAPINFO header passed through palctrl. - */ - -#include -#include -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "msrledec.h" - -typedef struct MsrleContext { - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *buf; - int size; - -} MsrleContext; - -static av_cold int msrle_decode_init(AVCodecContext *avctx) -{ - MsrleContext *s = avctx->priv_data; - - s->avctx = avctx; - - switch (avctx->bits_per_coded_sample) { - case 4: - case 8: - avctx->pix_fmt = PIX_FMT_PAL8; - break; - case 24: - avctx->pix_fmt = PIX_FMT_BGR24; - break; - default: - av_log(avctx, AV_LOG_ERROR, "unsupported bits per sample\n"); - return -1; - } - - s->frame.data[0] = NULL; - - return 0; -} - -static int msrle_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MsrleContext *s = avctx->priv_data; - int istride = FFALIGN(avctx->width*avctx->bits_per_coded_sample, 32) / 8; - - s->buf = 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; - } - - if (s->avctx->palctrl) { - /* make the palette available */ - memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); - if (s->avctx->palctrl->palette_changed) { - s->frame.palette_has_changed = 1; - s->avctx->palctrl->palette_changed = 0; - } - } - - /* FIXME how to correctly detect RLE ??? */ - if (avctx->height * istride == avpkt->size) { /* assume uncompressed */ - int linesize = avctx->width * avctx->bits_per_coded_sample / 8; - uint8_t *ptr = s->frame.data[0]; - uint8_t *buf = avpkt->data + (avctx->height-1)*istride; - int i, j; - - for (i = 0; i < avctx->height; i++) { - if (avctx->bits_per_coded_sample == 4) { - for (j = 0; j < avctx->width - 1; j += 2) { - ptr[j+0] = buf[j>>1] >> 4; - ptr[j+1] = buf[j>>1] & 0xF; - } - if (avctx->width & 1) - ptr[j+0] = buf[j>>1] >> 4; - } else { - memcpy(ptr, buf, linesize); - } - buf -= istride; - ptr += s->frame.linesize[0]; - } - } else { - ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, buf, buf_size); - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /* report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int msrle_decode_end(AVCodecContext *avctx) -{ - MsrleContext *s = avctx->priv_data; - - /* release the last frame */ - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec msrle_decoder = { - "msrle", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSRLE, - sizeof(MsrleContext), - msrle_decode_init, - NULL, - msrle_decode_end, - msrle_decode_frame, - CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("Microsoft RLE"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/msrledec.c b/tizen/distrib/ffmpeg/libavcodec/msrledec.c deleted file mode 100644 index 6e16d53..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msrledec.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Microsoft RLE decoder - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MS RLE decoder based on decoder by Mike Melanson and my own for TSCC - * For more information about the MS RLE format, visit: - * http://www.multimedia.cx/msrle.txt - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "msrledec.h" - -#define FETCH_NEXT_STREAM_BYTE() \ - if (stream_ptr >= data_size) \ - { \ - av_log(avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (1)\n"); \ - return -1; \ - } \ - stream_byte = data[stream_ptr++]; - -static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, - const uint8_t *data, int data_size) -{ - int stream_ptr = 0; - unsigned char rle_code; - unsigned char extra_byte, odd_pixel; - unsigned char stream_byte; - int pixel_ptr = 0; - int row_dec = pic->linesize[0]; - int row_ptr = (avctx->height - 1) * row_dec; - int frame_size = row_dec * avctx->height; - int i; - - 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 */ - return 0; - } 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 - odd_pixel = stream_byte & 1; - rle_code = (stream_byte + 1) / 2; - extra_byte = rle_code & 0x01; - if ((row_ptr + pixel_ptr + stream_byte > frame_size) || - (row_ptr < 0)) { - av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); - return -1; - } - - for (i = 0; i < rle_code; i++) { - if (pixel_ptr >= avctx->width) - break; - FETCH_NEXT_STREAM_BYTE(); - pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; - pixel_ptr++; - if (i + 1 == rle_code && odd_pixel) - break; - if (pixel_ptr >= avctx->width) - break; - pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; - pixel_ptr++; - } - - // if the RLE code is odd, skip a byte in the stream - if (extra_byte) - stream_ptr++; - } - } else { - // decode a run of data - if ((row_ptr + pixel_ptr + stream_byte > frame_size) || - (row_ptr < 0)) { - av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); - return -1; - } - FETCH_NEXT_STREAM_BYTE(); - for (i = 0; i < rle_code; i++) { - if (pixel_ptr >= avctx->width) - break; - if ((i & 1) == 0) - pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; - else - pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; - pixel_ptr++; - } - } - } - - /* one last sanity check on the way out */ - if (stream_ptr < data_size) { - av_log(avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n", - stream_ptr, data_size); - return -1; - } - - return 0; -} - - -static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int depth, - const uint8_t *data, int srcsize) -{ - uint8_t *output, *output_end; - const uint8_t* src = data; - int p1, p2, line=avctx->height - 1, pos=0, i; - uint16_t av_uninit(pix16); - uint32_t av_uninit(pix32); - - output = pic->data[0] + (avctx->height - 1) * pic->linesize[0]; - output_end = pic->data[0] + (avctx->height) * pic->linesize[0]; - while(src < data + srcsize) { - p1 = *src++; - if(p1 == 0) { //Escape code - p2 = *src++; - if(p2 == 0) { //End-of-line - output = pic->data[0] + (--line) * pic->linesize[0]; - if (line < 0 && !(src+1 < data + srcsize && AV_RB16(src) == 1)) { - av_log(avctx, AV_LOG_ERROR, "Next line is beyond picture bounds\n"); - return -1; - } - pos = 0; - continue; - } else if(p2 == 1) { //End-of-picture - return 0; - } else if(p2 == 2) { //Skip - p1 = *src++; - p2 = *src++; - line -= p2; - if (line < 0){ - av_log(avctx, AV_LOG_ERROR, "Skip beyond picture bounds\n"); - return -1; - } - pos += p1; - output = pic->data[0] + line * pic->linesize[0] + pos * (depth >> 3); - continue; - } - // Copy data - if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) - ||(pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) { - src += p2 * (depth >> 3); - continue; - } - if ((depth == 8) || (depth == 24)) { - for(i = 0; i < p2 * (depth >> 3); i++) { - *output++ = *src++; - } - // RLE8 copy is actually padded - and runs are not! - if(depth == 8 && (p2 & 1)) { - src++; - } - } else if (depth == 16) { - for(i = 0; i < p2; i++) { - pix16 = AV_RL16(src); - src += 2; - *(uint16_t*)output = pix16; - output += 2; - } - } else if (depth == 32) { - for(i = 0; i < p2; i++) { - pix32 = AV_RL32(src); - src += 4; - *(uint32_t*)output = pix32; - output += 4; - } - } - pos += p2; - } else { //run of pixels - uint8_t pix[3]; //original pixel - switch(depth){ - case 8: pix[0] = *src++; - break; - case 16: pix16 = AV_RL16(src); - src += 2; - break; - case 24: pix[0] = *src++; - pix[1] = *src++; - pix[2] = *src++; - break; - case 32: pix32 = AV_RL32(src); - src += 4; - break; - } - if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) - ||(pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end)) - continue; - for(i = 0; i < p1; i++) { - switch(depth){ - case 8: *output++ = pix[0]; - break; - case 16: *(uint16_t*)output = pix16; - output += 2; - break; - case 24: *output++ = pix[0]; - *output++ = pix[1]; - *output++ = pix[2]; - break; - case 32: *(uint32_t*)output = pix32; - output += 4; - break; - } - } - pos += p1; - } - } - - av_log(avctx, AV_LOG_WARNING, "MS RLE warning: no end-of-picture code\n"); - return 0; -} - - -int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, - const uint8_t* data, int data_size) -{ - switch(depth){ - case 4: - return msrle_decode_pal4(avctx, pic, data, data_size); - case 8: - case 16: - case 24: - case 32: - return msrle_decode_8_16_24_32(avctx, pic, depth, data, data_size); - default: - av_log(avctx, AV_LOG_ERROR, "Unknown depth %d\n", depth); - return -1; - } -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/msrledec.h b/tizen/distrib/ffmpeg/libavcodec/msrledec.h deleted file mode 100644 index 7495de5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msrledec.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Microsoft RLE decoder - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_MSRLEDEC_H -#define AVCODEC_MSRLEDEC_H - -#include "avcodec.h" - -/** - * Decodes stream in MS RLE format into frame. - * - * @param avctx codec context - * @param pic destination frame - * @param depth bit depth - * @param data input stream - * @param data_size input size - */ -int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, - const uint8_t* data, int data_size); - -#endif /* AVCODEC_MSRLEDEC_H */ - diff --git a/tizen/distrib/ffmpeg/libavcodec/msvideo1.c b/tizen/distrib/ffmpeg/libavcodec/msvideo1.c deleted file mode 100644 index 30aca39..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/msvideo1.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Microsoft Video-1 Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Microsoft Video-1 Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the MS Video-1 format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * This decoder outputs either PAL8 or RGB555 data, depending on the - * whether a RGB palette was passed through palctrl; - * if it's present, then the data is PAL8; RGB555 otherwise. - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#define PALETTE_COUNT 256 -#define CHECK_STREAM_PTR(n) \ - if ((stream_ptr + n) > s->size ) { \ - av_log(s->avctx, AV_LOG_ERROR, " MS Video-1 warning: stream_ptr out of bounds (%d >= %d)\n", \ - stream_ptr + n, s->size); \ - return; \ - } - -typedef struct Msvideo1Context { - - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *buf; - int size; - - int mode_8bit; /* if it's not 8-bit, it's 16-bit */ - -} Msvideo1Context; - -static av_cold int msvideo1_decode_init(AVCodecContext *avctx) -{ - Msvideo1Context *s = avctx->priv_data; - - s->avctx = avctx; - - /* figure out the colorspace based on the presence of a palette */ - if (s->avctx->palctrl) { - s->mode_8bit = 1; - avctx->pix_fmt = PIX_FMT_PAL8; - } else { - s->mode_8bit = 0; - avctx->pix_fmt = PIX_FMT_RGB555; - } - - s->frame.data[0] = NULL; - - return 0; -} - -static void msvideo1_decode_8bit(Msvideo1Context *s) -{ - int block_ptr, pixel_ptr; - int total_blocks; - int pixel_x, pixel_y; /* pixel width and height iterators */ - int block_x, block_y; /* block width and height iterators */ - int blocks_wide, blocks_high; /* width and height in 4x4 blocks */ - int block_inc; - int row_dec; - - /* decoding parameters */ - int stream_ptr; - unsigned char byte_a, byte_b; - unsigned short flags; - int skip_blocks; - unsigned char colors[8]; - unsigned char *pixels = s->frame.data[0]; - int stride = s->frame.linesize[0]; - - stream_ptr = 0; - skip_blocks = 0; - blocks_wide = s->avctx->width / 4; - blocks_high = s->avctx->height / 4; - total_blocks = blocks_wide * blocks_high; - block_inc = 4; - row_dec = stride + 4; - - for (block_y = blocks_high; block_y > 0; block_y--) { - block_ptr = ((block_y * 4) - 1) * stride; - for (block_x = blocks_wide; block_x > 0; block_x--) { - /* check if this block should be skipped */ - if (skip_blocks) { - block_ptr += block_inc; - skip_blocks--; - total_blocks--; - continue; - } - - pixel_ptr = block_ptr; - - /* get the next two bytes in the encoded data stream */ - CHECK_STREAM_PTR(2); - byte_a = s->buf[stream_ptr++]; - byte_b = s->buf[stream_ptr++]; - - /* check if the decode is finished */ - if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0)) - return; - else if ((byte_b & 0xFC) == 0x84) { - /* skip code, but don't count the current block */ - skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1; - } else if (byte_b < 0x80) { - /* 2-color encoding */ - flags = (byte_b << 8) | byte_a; - - CHECK_STREAM_PTR(2); - colors[0] = s->buf[stream_ptr++]; - colors[1] = s->buf[stream_ptr++]; - - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) - pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1]; - pixel_ptr -= row_dec; - } - } else if (byte_b >= 0x90) { - /* 8-color encoding */ - flags = (byte_b << 8) | byte_a; - - CHECK_STREAM_PTR(8); - memcpy(colors, &s->buf[stream_ptr], 8); - stream_ptr += 8; - - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) - pixels[pixel_ptr++] = - colors[((pixel_y & 0x2) << 1) + - (pixel_x & 0x2) + ((flags & 0x1) ^ 1)]; - pixel_ptr -= row_dec; - } - } else { - /* 1-color encoding */ - colors[0] = byte_a; - - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) - pixels[pixel_ptr++] = colors[0]; - pixel_ptr -= row_dec; - } - } - - block_ptr += block_inc; - total_blocks--; - } - } - - /* make the palette available on the way out */ - if (s->avctx->pix_fmt == PIX_FMT_PAL8) { - memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); - if (s->avctx->palctrl->palette_changed) { - s->frame.palette_has_changed = 1; - s->avctx->palctrl->palette_changed = 0; - } - } -} - -static void msvideo1_decode_16bit(Msvideo1Context *s) -{ - int block_ptr, pixel_ptr; - int total_blocks; - int pixel_x, pixel_y; /* pixel width and height iterators */ - int block_x, block_y; /* block width and height iterators */ - int blocks_wide, blocks_high; /* width and height in 4x4 blocks */ - int block_inc; - int row_dec; - - /* decoding parameters */ - int stream_ptr; - unsigned char byte_a, byte_b; - unsigned short flags; - int skip_blocks; - unsigned short colors[8]; - unsigned short *pixels = (unsigned short *)s->frame.data[0]; - int stride = s->frame.linesize[0] / 2; - - stream_ptr = 0; - skip_blocks = 0; - blocks_wide = s->avctx->width / 4; - blocks_high = s->avctx->height / 4; - total_blocks = blocks_wide * blocks_high; - block_inc = 4; - row_dec = stride + 4; - - for (block_y = blocks_high; block_y > 0; block_y--) { - block_ptr = ((block_y * 4) - 1) * stride; - for (block_x = blocks_wide; block_x > 0; block_x--) { - /* check if this block should be skipped */ - if (skip_blocks) { - block_ptr += block_inc; - skip_blocks--; - total_blocks--; - continue; - } - - pixel_ptr = block_ptr; - - /* get the next two bytes in the encoded data stream */ - CHECK_STREAM_PTR(2); - byte_a = s->buf[stream_ptr++]; - byte_b = s->buf[stream_ptr++]; - - /* check if the decode is finished */ - if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0)) { - return; - } else if ((byte_b & 0xFC) == 0x84) { - /* skip code, but don't count the current block */ - skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1; - } else if (byte_b < 0x80) { - /* 2- or 8-color encoding modes */ - flags = (byte_b << 8) | byte_a; - - CHECK_STREAM_PTR(4); - colors[0] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - colors[1] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - - if (colors[0] & 0x8000) { - /* 8-color encoding */ - CHECK_STREAM_PTR(12); - colors[2] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - colors[3] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - colors[4] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - colors[5] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - colors[6] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - colors[7] = AV_RL16(&s->buf[stream_ptr]); - stream_ptr += 2; - - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) - pixels[pixel_ptr++] = - colors[((pixel_y & 0x2) << 1) + - (pixel_x & 0x2) + ((flags & 0x1) ^ 1)]; - pixel_ptr -= row_dec; - } - } else { - /* 2-color encoding */ - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1) - pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1]; - pixel_ptr -= row_dec; - } - } - } else { - /* otherwise, it's a 1-color block */ - colors[0] = (byte_b << 8) | byte_a; - - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) - pixels[pixel_ptr++] = colors[0]; - pixel_ptr -= row_dec; - } - } - - block_ptr += block_inc; - total_blocks--; - } - } -} - -static int msvideo1_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - Msvideo1Context *s = avctx->priv_data; - - s->buf = 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(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - - if (s->mode_8bit) - msvideo1_decode_8bit(s); - else - msvideo1_decode_16bit(s); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /* report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int msvideo1_decode_end(AVCodecContext *avctx) -{ - Msvideo1Context *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec msvideo1_decoder = { - "msvideo1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MSVIDEO1, - sizeof(Msvideo1Context), - msvideo1_decode_init, - NULL, - msvideo1_decode_end, - msvideo1_decode_frame, - CODEC_CAP_DR1, - .long_name= NULL_IF_CONFIG_SMALL("Microsoft Video 1"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/nellymoser.c b/tizen/distrib/ffmpeg/libavcodec/nellymoser.c deleted file mode 100644 index 0716c25..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/nellymoser.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Common code between Nellymoser encoder and decoder - * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5, - * 539459aeb7d425140b62a3ec7dbf6dc8e408a306, and - * 520e17cd55896441042b14df2566a6eb610ed444 - * Copyright (c) 2007 Loic Minier - * Benjamin Larsson - * - * 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 AUTHORS OR 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. - */ - -/** - * @file - * The 3 alphanumeric copyright notices are md5summed they are from the original - * implementors. The original code is available from http://code.google.com/p/nelly2pcm/ - */ - -#include "nellymoser.h" -#include "avcodec.h" -#include "dsputil.h" - -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" - -const float ff_nelly_dequantization_table[127] = { - 0.0000000000, - --0.8472560048, 0.7224709988, - --1.5247479677,-0.4531480074, 0.3753609955, 1.4717899561, - --1.9822579622,-1.1929379702,-0.5829370022,-0.0693780035, 0.3909569979, 0.9069200158, 1.4862740040, 2.2215409279, - --2.3887870312,-1.8067539930,-1.4105420113,-1.0773609877,-0.7995010018,-0.5558109879,-0.3334020078,-0.1324490011, - 0.0568020009, 0.2548770010, 0.4773550034, 0.7386850119, 1.0443060398, 1.3954459429, 1.8098750114, 2.3918759823, - --2.3893830776,-1.9884680510,-1.7514040470,-1.5643119812,-1.3922129869,-1.2164649963,-1.0469499826,-0.8905100226, --0.7645580173,-0.6454579830,-0.5259280205,-0.4059549868,-0.3029719889,-0.2096900046,-0.1239869967,-0.0479229987, - 0.0257730000, 0.1001340002, 0.1737180054, 0.2585540116, 0.3522900045, 0.4569880068, 0.5767750144, 0.7003160119, - 0.8425520062, 1.0093879700, 1.1821349859, 1.3534560204, 1.5320819616, 1.7332619429, 1.9722349644, 2.3978140354, - --2.5756309032,-2.0573320389,-1.8984919786,-1.7727810144,-1.6662600040,-1.5742180347,-1.4993319511,-1.4316639900, --1.3652280569,-1.3000990152,-1.2280930281,-1.1588579416,-1.0921250582,-1.0135740042,-0.9202849865,-0.8287050128, --0.7374889851,-0.6447759867,-0.5590940118,-0.4857139885,-0.4110319912,-0.3459700048,-0.2851159871,-0.2341620028, --0.1870580018,-0.1442500055,-0.1107169986,-0.0739680007,-0.0365610011,-0.0073290002, 0.0203610007, 0.0479039997, - 0.0751969963, 0.0980999991, 0.1220389977, 0.1458999962, 0.1694349945, 0.1970459968, 0.2252430022, 0.2556869984, - 0.2870100141, 0.3197099864, 0.3525829911, 0.3889069855, 0.4334920049, 0.4769459963, 0.5204820037, 0.5644530058, - 0.6122040153, 0.6685929894, 0.7341650128, 0.8032159805, 0.8784040213, 0.9566209912, 1.0397069454, 1.1293770075, - 1.2211159468, 1.3080279827, 1.4024800062, 1.5056819916, 1.6227730513, 1.7724959850, 1.9430880547, 2.2903931141 -}; - -const uint8_t ff_nelly_band_sizes_table[NELLY_BANDS] = { -2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 12, 14, 15 -}; - -const uint16_t ff_nelly_init_table[64] = { -3134, 5342, 6870, 7792, 8569, 9185, 9744, 10191, 10631, 11061, 11434, 11770, -12116, 12513, 12925, 13300, 13674, 14027, 14352, 14716, 15117, 15477, 15824, -16157, 16513, 16804, 17090, 17401, 17679, 17948, 18238, 18520, 18764, 19078, -19381, 19640, 19921, 20205, 20500, 20813, 21162, 21465, 21794, 22137, 22453, -22756, 23067, 23350, 23636, 23926, 24227, 24521, 24819, 25107, 25414, 25730, -26120, 26497, 26895, 27344, 27877, 28463, 29426, 31355 -}; - -const int16_t ff_nelly_delta_table[32] = { --11725, -9420, -7910, -6801, -5948, -5233, -4599, -4039, -3507, -3030, -2596, --2170, -1774, -1383, -1016, -660, -329, -1, 337, 696, 1085, 1512, 1962, 2433, -2968, 3569, 4314, 5279, 6622, 8154, 10076, 12975 -}; - -static inline int signed_shift(int i, int shift) { - if (shift > 0) - return i << shift; - return i >> -shift; -} - -static int sum_bits(short *buf, short shift, short off) -{ - int i, ret = 0; - - for (i = 0; i < NELLY_FILL_LEN; i++) { - int b = buf[i]-off; - b = ((b>>(shift-1))+1)>>1; - ret += av_clip(b, 0, NELLY_BIT_CAP); - } - - return ret; -} - -static int headroom(int *la) -{ - int l; - if (*la == 0) { - return 31; - } - l = 30 - av_log2(FFABS(*la)); - *la <<= l; - return l; -} - - -void ff_nelly_get_sample_bits(const float *buf, int *bits) -{ - int i, j; - short sbuf[128]; - int bitsum = 0, last_bitsum, small_bitsum, big_bitsum; - short shift, shift_saved; - int max, sum, last_off, tmp; - int big_off, small_off; - int off; - - max = 0; - for (i = 0; i < NELLY_FILL_LEN; i++) { - max = FFMAX(max, buf[i]); - } - shift = -16; - shift += headroom(&max); - - sum = 0; - for (i = 0; i < NELLY_FILL_LEN; i++) { - sbuf[i] = signed_shift(buf[i], shift); - sbuf[i] = (3*sbuf[i])>>2; - sum += sbuf[i]; - } - - shift += 11; - shift_saved = shift; - sum -= NELLY_DETAIL_BITS << shift; - shift += headroom(&sum); - small_off = (NELLY_BASE_OFF * (sum>>16)) >> 15; - shift = shift_saved - (NELLY_BASE_SHIFT+shift-31); - - small_off = signed_shift(small_off, shift); - - bitsum = sum_bits(sbuf, shift_saved, small_off); - - if (bitsum != NELLY_DETAIL_BITS) { - off = bitsum - NELLY_DETAIL_BITS; - - for(shift=0; FFABS(off) <= 16383; shift++) - off *= 2; - - off = (off * NELLY_BASE_OFF) >> 15; - shift = shift_saved-(NELLY_BASE_SHIFT+shift-15); - - off = signed_shift(off, shift); - - for (j = 1; j < 20; j++) { - last_off = small_off; - small_off += off; - last_bitsum = bitsum; - - bitsum = sum_bits(sbuf, shift_saved, small_off); - - if ((bitsum-NELLY_DETAIL_BITS) * (last_bitsum-NELLY_DETAIL_BITS) <= 0) - break; - } - - if (bitsum > NELLY_DETAIL_BITS) { - big_off = small_off; - small_off = last_off; - big_bitsum=bitsum; - small_bitsum=last_bitsum; - } else { - big_off = last_off; - big_bitsum=last_bitsum; - small_bitsum=bitsum; - } - - while (bitsum != NELLY_DETAIL_BITS && j <= 19) { - off = (big_off+small_off)>>1; - bitsum = sum_bits(sbuf, shift_saved, off); - if (bitsum > NELLY_DETAIL_BITS) { - big_off=off; - big_bitsum=bitsum; - } else { - small_off = off; - small_bitsum=bitsum; - } - j++; - } - - if (abs(big_bitsum-NELLY_DETAIL_BITS) >= - abs(small_bitsum-NELLY_DETAIL_BITS)) { - bitsum = small_bitsum; - } else { - small_off = big_off; - bitsum = big_bitsum; - } - } - - for (i = 0; i < NELLY_FILL_LEN; i++) { - tmp = sbuf[i]-small_off; - tmp = ((tmp>>(shift_saved-1))+1)>>1; - bits[i] = av_clip(tmp, 0, NELLY_BIT_CAP); - } - - if (bitsum > NELLY_DETAIL_BITS) { - tmp = i = 0; - while (tmp < NELLY_DETAIL_BITS) { - tmp += bits[i]; - i++; - } - - bits[i-1] -= tmp - NELLY_DETAIL_BITS; - for(; i < NELLY_FILL_LEN; i++) - bits[i] = 0; - } -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/nellymoser.h b/tizen/distrib/ffmpeg/libavcodec/nellymoser.h deleted file mode 100644 index 88d9aa6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/nellymoser.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Common code between Nellymoser encoder and decoder - * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5, - * 539459aeb7d425140b62a3ec7dbf6dc8e408a306, and - * 520e17cd55896441042b14df2566a6eb610ed444 - * Copyright (c) 2007 Loic Minier - * Benjamin Larsson - * - * 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 AUTHORS OR 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. - */ - -/** - * @file - * The 3 alphanumeric copyright notices are md5summed they are from the original - * implementors. The original code is available from http://code.google.com/p/nelly2pcm/ - */ - -#ifndef AVCODEC_NELLYMOSER_H -#define AVCODEC_NELLYMOSER_H - -#include "avcodec.h" - -#define NELLY_BANDS 23 -#define NELLY_BLOCK_LEN 64 -#define NELLY_HEADER_BITS 116 -#define NELLY_DETAIL_BITS 198 -#define NELLY_BUF_LEN 128 -#define NELLY_FILL_LEN 124 -#define NELLY_BIT_CAP 6 -#define NELLY_BASE_OFF 4228 -#define NELLY_BASE_SHIFT 19 -#define NELLY_SAMPLES (2 * NELLY_BUF_LEN) - -extern const float ff_nelly_dequantization_table[127]; -extern const uint8_t ff_nelly_band_sizes_table[NELLY_BANDS]; -extern const uint16_t ff_nelly_init_table[64]; -extern const int16_t ff_nelly_delta_table[32]; - -void ff_nelly_get_sample_bits(const float *buf, int *bits); - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/nellymoserdec.c b/tizen/distrib/ffmpeg/libavcodec/nellymoserdec.c deleted file mode 100644 index 82a3f07..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/nellymoserdec.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * NellyMoser audio decoder - * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5, - * 539459aeb7d425140b62a3ec7dbf6dc8e408a306, and - * 520e17cd55896441042b14df2566a6eb610ed444 - * Copyright (c) 2007 Loic Minier - * Benjamin Larsson - * - * 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 AUTHORS OR 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. - */ - -/** - * @file - * The 3 alphanumeric copyright notices are md5summed they are from the original - * implementors. The original code is available from http://code.google.com/p/nelly2pcm/ - */ - -#include "nellymoser.h" -#include "libavutil/lfg.h" -#include "libavutil/random_seed.h" -#include "avcodec.h" -#include "dsputil.h" -#include "fft.h" - -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" - - -typedef struct NellyMoserDecodeContext { - AVCodecContext* avctx; - DECLARE_ALIGNED(16, float,float_buf)[NELLY_SAMPLES]; - float state[128]; - AVLFG random_state; - GetBitContext gb; - int add_bias; - float scale_bias; - DSPContext dsp; - FFTContext imdct_ctx; - DECLARE_ALIGNED(16, float,imdct_out)[NELLY_BUF_LEN * 2]; -} NellyMoserDecodeContext; - -static void overlap_and_window(NellyMoserDecodeContext *s, float *state, float *audio, float *a_in) -{ - int bot, top; - - bot = 0; - top = NELLY_BUF_LEN-1; - - while (bot < NELLY_BUF_LEN) { - audio[bot] = a_in [bot]*ff_sine_128[bot] - +state[bot]*ff_sine_128[top] + s->add_bias; - - bot++; - top--; - } - memcpy(state, a_in + NELLY_BUF_LEN, sizeof(float)*NELLY_BUF_LEN); -} - -static void nelly_decode_block(NellyMoserDecodeContext *s, - const unsigned char block[NELLY_BLOCK_LEN], - float audio[NELLY_SAMPLES]) -{ - int i,j; - float buf[NELLY_FILL_LEN], pows[NELLY_FILL_LEN]; - float *aptr, *bptr, *pptr, val, pval; - int bits[NELLY_BUF_LEN]; - unsigned char v; - - init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); - - bptr = buf; - pptr = pows; - val = ff_nelly_init_table[get_bits(&s->gb, 6)]; - for (i=0 ; i 0) - val += ff_nelly_delta_table[get_bits(&s->gb, 5)]; - pval = -pow(2, val/2048) * s->scale_bias; - for (j = 0; j < ff_nelly_band_sizes_table[i]; j++) { - *bptr++ = val; - *pptr++ = pval; - } - - } - - ff_nelly_get_sample_bits(buf, bits); - - for (i = 0; i < 2; i++) { - aptr = audio + i * NELLY_BUF_LEN; - - init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); - skip_bits_long(&s->gb, NELLY_HEADER_BITS + i*NELLY_DETAIL_BITS); - - for (j = 0; j < NELLY_FILL_LEN; j++) { - if (bits[j] <= 0) { - aptr[j] = M_SQRT1_2*pows[j]; - if (av_lfg_get(&s->random_state) & 1) - aptr[j] *= -1.0; - } else { - v = get_bits(&s->gb, bits[j]); - aptr[j] = ff_nelly_dequantization_table[(1<imdct_ctx, s->imdct_out, aptr); - /* XXX: overlapping and windowing should be part of a more - generic imdct function */ - overlap_and_window(s, s->state, aptr, s->imdct_out); - } -} - -static av_cold int decode_init(AVCodecContext * avctx) { - NellyMoserDecodeContext *s = avctx->priv_data; - - s->avctx = avctx; - av_lfg_init(&s->random_state, 0); - ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0); - - dsputil_init(&s->dsp, avctx); - - if(s->dsp.float_to_int16 == ff_float_to_int16_c) { - s->add_bias = 385; - s->scale_bias = 1.0/(8*32768); - } else { - s->add_bias = 0; - s->scale_bias = 1.0/(1*8); - } - - /* Generate overlap window */ - if (!ff_sine_128[127]) - ff_init_ff_sine_windows(7); - - avctx->sample_fmt = SAMPLE_FMT_S16; - avctx->channel_layout = CH_LAYOUT_MONO; - return 0; -} - -static int decode_tag(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - NellyMoserDecodeContext *s = avctx->priv_data; - int blocks, i; - int16_t* samples; - *data_size = 0; - samples = (int16_t*)data; - - if (buf_size < avctx->block_align) - return buf_size; - - switch (buf_size) { - case 64: // 8000Hz - blocks = 1; break; - case 128: // 11025Hz - blocks = 2; break; - case 192: // 16000Hz - blocks = 3; break; - case 256: // 22050Hz - blocks = 4; break; - case 512: // 44100Hz - blocks = 8; break; - default: - av_log(avctx, AV_LOG_DEBUG, "Tag size %d.\n", buf_size); - return buf_size; - } - - for (i=0 ; ifloat_buf); - s->dsp.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES); - *data_size += NELLY_SAMPLES*sizeof(int16_t); - } - - return buf_size; -} - -static av_cold int decode_end(AVCodecContext * avctx) { - NellyMoserDecodeContext *s = avctx->priv_data; - - ff_mdct_end(&s->imdct_ctx); - return 0; -} - -AVCodec nellymoser_decoder = { - "nellymoser", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_NELLYMOSER, - sizeof(NellyMoserDecodeContext), - decode_init, - NULL, - decode_end, - decode_tag, - .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/nellymoserenc.c b/tizen/distrib/ffmpeg/libavcodec/nellymoserenc.c deleted file mode 100644 index dd9a271..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/nellymoserenc.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Nellymoser encoder - * This code is developed as part of Google Summer of Code 2008 Program. - * - * Copyright (c) 2008 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Nellymoser encoder - * by Bartlomiej Wolowiec - * - * Generic codec information: libavcodec/nellymoserdec.c - * - * Some information also from: http://samples.mplayerhq.hu/A-codecs/Nelly_Moser/ASAO/ASAO.zip - * (Copyright Joseph Artsimovich and UAB "DKD") - * - * for more information about nellymoser format, visit: - * http://wiki.multimedia.cx/index.php?title=Nellymoser - */ - -#include "nellymoser.h" -#include "avcodec.h" -#include "dsputil.h" -#include "fft.h" - -#define BITSTREAM_WRITER_LE -#include "put_bits.h" - -#define POW_TABLE_SIZE (1<<11) -#define POW_TABLE_OFFSET 3 -#define OPT_SIZE ((1<<15) + 3000) - -typedef struct NellyMoserEncodeContext { - AVCodecContext *avctx; - int last_frame; - int bufsel; - int have_saved; - DSPContext dsp; - FFTContext mdct_ctx; - DECLARE_ALIGNED(16, float, mdct_out)[NELLY_SAMPLES]; - DECLARE_ALIGNED(16, float, in_buff)[NELLY_SAMPLES]; - DECLARE_ALIGNED(16, float, buf)[2][3 * NELLY_BUF_LEN]; ///< sample buffer - float (*opt )[NELLY_BANDS]; - uint8_t (*path)[NELLY_BANDS]; -} NellyMoserEncodeContext; - -static float pow_table[POW_TABLE_SIZE]; ///< -pow(2, -i / 2048.0 - 3.0); - -static const uint8_t sf_lut[96] = { - 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, - 5, 5, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 13, 13, 14, - 15, 15, 16, 17, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 26, - 27, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, - 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, - 54, 55, 55, 56, 57, 57, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, -}; - -static const uint8_t sf_delta_lut[78] = { - 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, - 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, - 13, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23, - 23, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, - 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, -}; - -static const uint8_t quant_lut[230] = { - 0, - - 0, 1, 2, - - 0, 1, 2, 3, 4, 5, 6, - - 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, - 12, 13, 13, 13, 14, - - 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, - 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29, - 30, - - 0, 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, 7, 8, 8, 9, 9, 9, - 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, - 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, - 21, 21, 22, 22, 23, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 42, 43, 44, 44, 45, 45, - 46, 47, 47, 48, 48, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, - 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 57, - 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 61, - 61, 61, 61, 61, 62, -}; - -static const float quant_lut_mul[7] = { 0.0, 0.0, 2.0, 2.0, 5.0, 12.0, 36.6 }; -static const float quant_lut_add[7] = { 0.0, 0.0, 2.0, 7.0, 21.0, 56.0, 157.0 }; -static const uint8_t quant_lut_offset[8] = { 0, 0, 1, 4, 11, 32, 81, 230 }; - -static void apply_mdct(NellyMoserEncodeContext *s) -{ - memcpy(s->in_buff, s->buf[s->bufsel], NELLY_BUF_LEN * sizeof(float)); - s->dsp.vector_fmul(s->in_buff, ff_sine_128, NELLY_BUF_LEN); - s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN, ff_sine_128, - NELLY_BUF_LEN); - ff_mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff); - - s->dsp.vector_fmul(s->buf[s->bufsel] + NELLY_BUF_LEN, ff_sine_128, NELLY_BUF_LEN); - s->dsp.vector_fmul_reverse(s->buf[s->bufsel] + 2 * NELLY_BUF_LEN, s->buf[1 - s->bufsel], ff_sine_128, - NELLY_BUF_LEN); - ff_mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN); -} - -static av_cold int encode_init(AVCodecContext *avctx) -{ - NellyMoserEncodeContext *s = avctx->priv_data; - int i; - - if (avctx->channels != 1) { - av_log(avctx, AV_LOG_ERROR, "Nellymoser supports only 1 channel\n"); - return -1; - } - - if (avctx->sample_rate != 8000 && avctx->sample_rate != 16000 && - avctx->sample_rate != 11025 && - avctx->sample_rate != 22050 && avctx->sample_rate != 44100 && - avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) { - av_log(avctx, AV_LOG_ERROR, "Nellymoser works only with 8000, 16000, 11025, 22050 and 44100 sample rate\n"); - return -1; - } - - avctx->frame_size = NELLY_SAMPLES; - s->avctx = avctx; - ff_mdct_init(&s->mdct_ctx, 8, 0, 1.0); - dsputil_init(&s->dsp, avctx); - - /* Generate overlap window */ - ff_sine_window_init(ff_sine_128, 128); - for (i = 0; i < POW_TABLE_SIZE; i++) - pow_table[i] = -pow(2, -i / 2048.0 - 3.0 + POW_TABLE_OFFSET); - - if (s->avctx->trellis) { - s->opt = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(float )); - s->path = av_malloc(NELLY_BANDS * OPT_SIZE * sizeof(uint8_t)); - } - - return 0; -} - -static av_cold int encode_end(AVCodecContext *avctx) -{ - NellyMoserEncodeContext *s = avctx->priv_data; - - ff_mdct_end(&s->mdct_ctx); - - if (s->avctx->trellis) { - av_free(s->opt); - av_free(s->path); - } - - return 0; -} - -#define find_best(val, table, LUT, LUT_add, LUT_size) \ - best_idx = \ - LUT[av_clip ((lrintf(val) >> 8) + LUT_add, 0, LUT_size - 1)]; \ - if (fabs(val - table[best_idx]) > fabs(val - table[best_idx + 1])) \ - best_idx++; - -static void get_exponent_greedy(NellyMoserEncodeContext *s, float *cand, int *idx_table) -{ - int band, best_idx, power_idx = 0; - float power_candidate; - - //base exponent - find_best(cand[0], ff_nelly_init_table, sf_lut, -20, 96); - idx_table[0] = best_idx; - power_idx = ff_nelly_init_table[best_idx]; - - for (band = 1; band < NELLY_BANDS; band++) { - power_candidate = cand[band] - power_idx; - find_best(power_candidate, ff_nelly_delta_table, sf_delta_lut, 37, 78); - idx_table[band] = best_idx; - power_idx += ff_nelly_delta_table[best_idx]; - } -} - -static inline float distance(float x, float y, int band) -{ - //return pow(fabs(x-y), 2.0); - float tmp = x - y; - return tmp * tmp; -} - -static void get_exponent_dynamic(NellyMoserEncodeContext *s, float *cand, int *idx_table) -{ - int i, j, band, best_idx; - float power_candidate, best_val; - - float (*opt )[NELLY_BANDS] = s->opt ; - uint8_t(*path)[NELLY_BANDS] = s->path; - - for (i = 0; i < NELLY_BANDS * OPT_SIZE; i++) { - opt[0][i] = INFINITY; - } - - for (i = 0; i < 64; i++) { - opt[0][ff_nelly_init_table[i]] = distance(cand[0], ff_nelly_init_table[i], 0); - path[0][ff_nelly_init_table[i]] = i; - } - - for (band = 1; band < NELLY_BANDS; band++) { - int q, c = 0; - float tmp; - int idx_min, idx_max, idx; - power_candidate = cand[band]; - for (q = 1000; !c && q < OPT_SIZE; q <<= 2) { - idx_min = FFMAX(0, cand[band] - q); - idx_max = FFMIN(OPT_SIZE, cand[band - 1] + q); - for (i = FFMAX(0, cand[band - 1] - q); i < FFMIN(OPT_SIZE, cand[band - 1] + q); i++) { - if ( isinf(opt[band - 1][i]) ) - continue; - for (j = 0; j < 32; j++) { - idx = i + ff_nelly_delta_table[j]; - if (idx > idx_max) - break; - if (idx >= idx_min) { - tmp = opt[band - 1][i] + distance(idx, power_candidate, band); - if (opt[band][idx] > tmp) { - opt[band][idx] = tmp; - path[band][idx] = j; - c = 1; - } - } - } - } - } - assert(c); //FIXME - } - - best_val = INFINITY; - best_idx = -1; - band = NELLY_BANDS - 1; - for (i = 0; i < OPT_SIZE; i++) { - if (best_val > opt[band][i]) { - best_val = opt[band][i]; - best_idx = i; - } - } - for (band = NELLY_BANDS - 1; band >= 0; band--) { - idx_table[band] = path[band][best_idx]; - if (band) { - best_idx -= ff_nelly_delta_table[path[band][best_idx]]; - } - } -} - -/** - * Encodes NELLY_SAMPLES samples. It assumes, that samples contains 3 * NELLY_BUF_LEN values - * @param s encoder context - * @param output output buffer - * @param output_size size of output buffer - */ -static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int output_size) -{ - PutBitContext pb; - int i, j, band, block, best_idx, power_idx = 0; - float power_val, coeff, coeff_sum; - float pows[NELLY_FILL_LEN]; - int bits[NELLY_BUF_LEN], idx_table[NELLY_BANDS]; - float cand[NELLY_BANDS]; - - apply_mdct(s); - - init_put_bits(&pb, output, output_size * 8); - - i = 0; - for (band = 0; band < NELLY_BANDS; band++) { - coeff_sum = 0; - for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) { - coeff_sum += s->mdct_out[i ] * s->mdct_out[i ] - + s->mdct_out[i + NELLY_BUF_LEN] * s->mdct_out[i + NELLY_BUF_LEN]; - } - cand[band] = - log(FFMAX(1.0, coeff_sum / (ff_nelly_band_sizes_table[band] << 7))) * 1024.0 / M_LN2; - } - - if (s->avctx->trellis) { - get_exponent_dynamic(s, cand, idx_table); - } else { - get_exponent_greedy(s, cand, idx_table); - } - - i = 0; - for (band = 0; band < NELLY_BANDS; band++) { - if (band) { - power_idx += ff_nelly_delta_table[idx_table[band]]; - put_bits(&pb, 5, idx_table[band]); - } else { - power_idx = ff_nelly_init_table[idx_table[0]]; - put_bits(&pb, 6, idx_table[0]); - } - power_val = pow_table[power_idx & 0x7FF] / (1 << ((power_idx >> 11) + POW_TABLE_OFFSET)); - for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) { - s->mdct_out[i] *= power_val; - s->mdct_out[i + NELLY_BUF_LEN] *= power_val; - pows[i] = power_idx; - } - } - - ff_nelly_get_sample_bits(pows, bits); - - for (block = 0; block < 2; block++) { - for (i = 0; i < NELLY_FILL_LEN; i++) { - if (bits[i] > 0) { - const float *table = ff_nelly_dequantization_table + (1 << bits[i]) - 1; - coeff = s->mdct_out[block * NELLY_BUF_LEN + i]; - best_idx = - quant_lut[av_clip ( - coeff * quant_lut_mul[bits[i]] + quant_lut_add[bits[i]], - quant_lut_offset[bits[i]], - quant_lut_offset[bits[i]+1] - 1 - )]; - if (fabs(coeff - table[best_idx]) > fabs(coeff - table[best_idx + 1])) - best_idx++; - - put_bits(&pb, bits[i], best_idx); - } - } - if (!block) - put_bits(&pb, NELLY_HEADER_BITS + NELLY_DETAIL_BITS - put_bits_count(&pb), 0); - } - - flush_put_bits(&pb); -} - -static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data) -{ - NellyMoserEncodeContext *s = avctx->priv_data; - int16_t *samples = data; - int i; - - if (s->last_frame) - return 0; - - if (data) { - for (i = 0; i < avctx->frame_size; i++) { - s->buf[s->bufsel][i] = samples[i]; - } - for (; i < NELLY_SAMPLES; i++) { - s->buf[s->bufsel][i] = 0; - } - s->bufsel = 1 - s->bufsel; - if (!s->have_saved) { - s->have_saved = 1; - return 0; - } - } else { - memset(s->buf[s->bufsel], 0, sizeof(s->buf[0][0]) * NELLY_BUF_LEN); - s->bufsel = 1 - s->bufsel; - s->last_frame = 1; - } - - if (s->have_saved) { - encode_block(s, frame, buf_size); - return NELLY_BLOCK_LEN; - } - return 0; -} - -AVCodec nellymoser_encoder = { - .name = "nellymoser", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_NELLYMOSER, - .priv_data_size = sizeof(NellyMoserEncodeContext), - .init = encode_init, - .encode = encode_frame, - .close = encode_end, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/noise_bsf.c b/tizen/distrib/ffmpeg/libavcodec/noise_bsf.c deleted file mode 100644 index c49dd1f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/noise_bsf.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" - - -static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - unsigned int *state= bsfc->priv_data; - int amount= args ? atoi(args) : (*state % 10001+1); - int i; - - *poutbuf= av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - memcpy(*poutbuf, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - for(i=0; i -#include - -#include "libavutil/bswap.h" -#include "libavutil/lzo.h" -#include "avcodec.h" -#include "dsputil.h" -#include "rtjpeg.h" - -typedef struct { - AVFrame pic; - int codec_frameheader; - int quality; - int width, height; - unsigned int decomp_size; - unsigned char* decomp_buf; - uint32_t lq[64], cq[64]; - RTJpegContext rtj; - DSPContext dsp; -} NuvContext; - -static const uint8_t fallback_lquant[] = { - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 56, 68, 109, 103, 77, - 24, 35, 55, 64, 81, 104, 113, 92, - 49, 64, 78, 87, 103, 121, 120, 101, - 72, 92, 95, 98, 112, 100, 103, 99 -}; - -static const uint8_t fallback_cquant[] = { - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 -}; - -/** - * \brief copy frame data from buffer to AVFrame, handling stride. - * \param f destination AVFrame - * \param src source buffer, does not use any line-stride - * \param width width of the video frame - * \param height height of the video frame - */ -static void copy_frame(AVFrame *f, const uint8_t *src, - int width, int height) { - AVPicture pic; - avpicture_fill(&pic, src, PIX_FMT_YUV420P, width, height); - av_picture_copy((AVPicture *)f, &pic, PIX_FMT_YUV420P, width, height); -} - -/** - * \brief extract quantization tables from codec data into our context - */ -static int get_quant(AVCodecContext *avctx, NuvContext *c, - const uint8_t *buf, int size) { - int i; - if (size < 2 * 64 * 4) { - av_log(avctx, AV_LOG_ERROR, "insufficient rtjpeg quant data\n"); - return -1; - } - for (i = 0; i < 64; i++, buf += 4) - c->lq[i] = AV_RL32(buf); - for (i = 0; i < 64; i++, buf += 4) - c->cq[i] = AV_RL32(buf); - return 0; -} - -/** - * \brief set quantization tables from a quality value - */ -static void get_quant_quality(NuvContext *c, int quality) { - int i; - quality = FFMAX(quality, 1); - for (i = 0; i < 64; i++) { - c->lq[i] = (fallback_lquant[i] << 7) / quality; - c->cq[i] = (fallback_cquant[i] << 7) / quality; - } -} - -static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) { - NuvContext *c = avctx->priv_data; - width = (width + 1) & ~1; - height = (height + 1) & ~1; - if (quality >= 0) - get_quant_quality(c, quality); - if (width != c->width || height != c->height) { - if (avcodec_check_dimensions(avctx, height, width) < 0) - return 0; - avctx->width = c->width = width; - avctx->height = c->height = height; - c->decomp_size = c->height * c->width * 3 / 2; - c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + AV_LZO_OUTPUT_PADDING); - if (!c->decomp_buf) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 0; - } - rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); - } else if (quality != c->quality) - rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); - return 1; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - NuvContext *c = avctx->priv_data; - AVFrame *picture = data; - int orig_size = buf_size; - int keyframe; - int result; - enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', - NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3', - NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype; - - if (buf_size < 12) { - av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); - return -1; - } - - // codec data (rtjpeg quant tables) - if (buf[0] == 'D' && buf[1] == 'R') { - int ret; - // skip rest of the frameheader. - buf = &buf[12]; - buf_size -= 12; - ret = get_quant(avctx, c, buf, buf_size); - if (ret < 0) - return ret; - rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); - return orig_size; - } - - if (buf[0] != 'V' || buf_size < 12) { - av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n"); - return -1; - } - comptype = buf[1]; - switch (comptype) { - case NUV_RTJPEG_IN_LZO: - case NUV_RTJPEG: - keyframe = !buf[2]; break; - case NUV_COPY_LAST: - keyframe = 0; break; - default: - keyframe = 1; break; - } - // skip rest of the frameheader. - buf = &buf[12]; - buf_size -= 12; - if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { - int outlen = c->decomp_size, inlen = buf_size; - if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) - av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); - buf = c->decomp_buf; - buf_size = c->decomp_size; - } - if (c->codec_frameheader) { - int w, h, q; - if (buf_size < 12) { - av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); - return -1; - } - w = AV_RL16(&buf[6]); - h = AV_RL16(&buf[8]); - q = buf[10]; - if (!codec_reinit(avctx, w, h, q)) - return -1; - buf = &buf[12]; - buf_size -= 12; - } - - if (keyframe && c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 3; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - result = avctx->reget_buffer(avctx, &c->pic); - if (result < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - c->pic.pict_type = keyframe ? FF_I_TYPE : FF_P_TYPE; - c->pic.key_frame = keyframe; - // decompress/copy/whatever data - switch (comptype) { - case NUV_LZO: - case NUV_UNCOMPRESSED: { - int height = c->height; - if (buf_size < c->width * height * 3 / 2) { - av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n"); - height = buf_size / c->width / 3 * 2; - } - copy_frame(&c->pic, buf, c->width, height); - break; - } - case NUV_RTJPEG_IN_LZO: - case NUV_RTJPEG: { - rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); - break; - } - case NUV_BLACK: { - memset(c->pic.data[0], 0, c->width * c->height); - memset(c->pic.data[1], 128, c->width * c->height / 4); - memset(c->pic.data[2], 128, c->width * c->height / 4); - break; - } - case NUV_COPY_LAST: { - /* nothing more to do here */ - break; - } - default: - av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); - return -1; - } - - *picture = c->pic; - *data_size = sizeof(AVFrame); - return orig_size; -} - -static av_cold int decode_init(AVCodecContext *avctx) { - NuvContext *c = avctx->priv_data; - avctx->pix_fmt = PIX_FMT_YUV420P; - c->pic.data[0] = NULL; - c->decomp_buf = NULL; - c->quality = -1; - c->width = 0; - c->height = 0; - c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G'); - if (avctx->extradata_size) - get_quant(avctx, c, avctx->extradata, avctx->extradata_size); - dsputil_init(&c->dsp, avctx); - if (!codec_reinit(avctx, avctx->width, avctx->height, -1)) - return 1; - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) { - NuvContext *c = avctx->priv_data; - av_freep(&c->decomp_buf); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - return 0; -} - -AVCodec nuv_decoder = { - "nuv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_NUV, - sizeof(NuvContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/opt.c b/tizen/distrib/ffmpeg/libavcodec/opt.c deleted file mode 100644 index f9cba05..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/opt.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * AVOptions - * Copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * AVOptions - * @author Michael Niedermayer - */ - -#include "avcodec.h" -#include "opt.h" -#include "eval.h" - -//FIXME order them and do a bin search -const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags){ - AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass - const AVOption *o= c->option; - - for(;o && o->name; o++){ - if(!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags ) - return o; - } - return NULL; -} - -const AVOption *av_next_option(void *obj, const AVOption *last){ - if(last && last[1].name) return ++last; - else if(last) return NULL; - else return (*(AVClass**)obj)->option; -} - -static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out){ - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); - void *dst; - if(o_out) - *o_out= o; - if(!o || o->offset<=0) - return AVERROR(ENOENT); - - if(o->max*den < num*intnum || o->min*den > num*intnum) { - av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name); - return AVERROR(ERANGE); - } - - dst= ((uint8_t*)obj) + o->offset; - - switch(o->type){ - case FF_OPT_TYPE_FLAGS: - case FF_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; - case FF_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break; - case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; - case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; - case FF_OPT_TYPE_RATIONAL: - if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; - else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); - break; - default: - return AVERROR(EINVAL); - } - return 0; -} - -static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ - const AVOption *o = NULL; - if (av_set_number2(obj, name, num, den, intnum, &o) < 0) - return NULL; - else - return o; -} - -static const double const_values[]={ - M_PI, - M_E, - FF_QP2LAMBDA, - 0 -}; - -static const char * const const_names[]={ - "PI", - "E", - "QP2LAMBDA", - 0 -}; - -static int hexchar2int(char c) { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - return -1; -} - -int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out){ - int ret; - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); - if (o_out) - *o_out = o; - if(!o) - return AVERROR(ENOENT); - if(!val || o->offset<=0) - return AVERROR(EINVAL); - - if(o->type == FF_OPT_TYPE_BINARY){ - uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset); - int *lendst = (int *)(dst + 1); - uint8_t *bin, *ptr; - int len = strlen(val); - av_freep(dst); - *lendst = 0; - if (len & 1) return AVERROR(EINVAL); - len /= 2; - ptr = bin = av_malloc(len); - while (*val) { - int a = hexchar2int(*val++); - int b = hexchar2int(*val++); - if (a < 0 || b < 0) { - av_free(bin); - return AVERROR(EINVAL); - } - *ptr++ = (a << 4) | b; - } - *dst = bin; - *lendst = len; - return 0; - } - if(o->type != FF_OPT_TYPE_STRING){ - int notfirst=0; - for(;;){ - int i; - char buf[256]; - int cmd=0; - double d; - const char *error = NULL; - - if(*val == '+' || *val == '-') - cmd= *(val++); - - for(i=0; iunit, 0, 0); - if(o_named && o_named->type == FF_OPT_TYPE_CONST) - d= o_named->default_val; - else if(!strcmp(buf, "default")) d= o->default_val; - else if(!strcmp(buf, "max" )) d= o->max; - else if(!strcmp(buf, "min" )) d= o->min; - else if(!strcmp(buf, "none" )) d= 0; - else if(!strcmp(buf, "all" )) d= ~0; - else { - if (error) - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error); - return AVERROR(EINVAL); - } - } - if(o->type == FF_OPT_TYPE_FLAGS){ - if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; - else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; - }else{ - if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d; - else if(cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d; - } - - if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0) - return ret; - val+= i; - if(!*val) - return 0; - notfirst=1; - } - return AVERROR(EINVAL); - } - - if(alloc){ - av_free(*(void**)(((uint8_t*)obj) + o->offset)); - val= av_strdup(val); - } - - memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); - return 0; -} - -#if LIBAVCODEC_VERSION_MAJOR < 53 -const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){ - const AVOption *o; - if (av_set_string3(obj, name, val, alloc, &o) < 0) - return NULL; - return o; -} - -const AVOption *av_set_string(void *obj, const char *name, const char *val){ - const AVOption *o; - if (av_set_string3(obj, name, val, 0, &o) < 0) - return NULL; - return o; -} -#endif - -const AVOption *av_set_double(void *obj, const char *name, double n){ - return av_set_number(obj, name, n, 1, 1); -} - -const AVOption *av_set_q(void *obj, const char *name, AVRational n){ - return av_set_number(obj, name, n.num, n.den, 1); -} - -const AVOption *av_set_int(void *obj, const char *name, int64_t n){ - return av_set_number(obj, name, 1, 1, n); -} - -/** - * - * @param buf a buffer which is used for returning non string values as strings, can be NULL - * @param buf_len allocated length in bytes of buf - */ -const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len){ - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); - void *dst; - uint8_t *bin; - int len, i; - if(!o || o->offset<=0) - return NULL; - if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) - return NULL; - - dst= ((uint8_t*)obj) + o->offset; - if(o_out) *o_out= o; - - switch(o->type){ - case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break; - case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; - case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break; - case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; - case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; - case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; - case FF_OPT_TYPE_STRING: return *(void**)dst; - case FF_OPT_TYPE_BINARY: - len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *)); - if(len >= (buf_len + 1)/2) return NULL; - bin = *(uint8_t**)dst; - for(i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]); - break; - default: return NULL; - } - return buf; -} - -static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum){ - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); - void *dst; - if(!o || o->offset<=0) - goto error; - - dst= ((uint8_t*)obj) + o->offset; - - if(o_out) *o_out= o; - - switch(o->type){ - case FF_OPT_TYPE_FLAGS: *intnum= *(unsigned int*)dst;return 0; - case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0; - case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0; - case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0; - case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0; - case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num; - *den = ((AVRational*)dst)->den; - return 0; - } -error: - *den=*intnum=0; - return -1; -} - -double av_get_double(void *obj, const char *name, const AVOption **o_out){ - int64_t intnum=1; - double num=1; - int den=1; - - av_get_number(obj, name, o_out, &num, &den, &intnum); - return num*intnum/den; -} - -AVRational av_get_q(void *obj, const char *name, const AVOption **o_out){ - int64_t intnum=1; - double num=1; - int den=1; - - av_get_number(obj, name, o_out, &num, &den, &intnum); - if(num == 1.0 && (int)intnum == intnum) - return (AVRational){intnum, den}; - else - return av_d2q(num*intnum/den, 1<<24); -} - -int64_t av_get_int(void *obj, const char *name, const AVOption **o_out){ - int64_t intnum=1; - double num=1; - int den=1; - - av_get_number(obj, name, o_out, &num, &den, &intnum); - return num*intnum/den; -} - -static void opt_list(void *obj, void *av_log_obj, const char *unit) -{ - const AVOption *opt=NULL; - - while((opt= av_next_option(obj, opt))){ - if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM))) - continue; - - /* Don't print CONST's on level one. - * Don't print anything but CONST's on level two. - * Only print items from the requested unit. - */ - if (!unit && opt->type==FF_OPT_TYPE_CONST) - continue; - else if (unit && opt->type!=FF_OPT_TYPE_CONST) - continue; - else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit)) - continue; - else if (unit && opt->type == FF_OPT_TYPE_CONST) - av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); - else - av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name); - - switch( opt->type ) - { - case FF_OPT_TYPE_FLAGS: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_INT: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_INT64: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_DOUBLE: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_FLOAT: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_STRING: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_RATIONAL: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_BINARY: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - case FF_OPT_TYPE_CONST: - default: - av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); - break; - } - av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); - av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); - av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); - av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); - av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); - - if(opt->help) - av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); - av_log(av_log_obj, AV_LOG_INFO, "\n"); - if (opt->unit && opt->type != FF_OPT_TYPE_CONST) { - opt_list(obj, av_log_obj, opt->unit); - } - } -} - -int av_opt_show(void *obj, void *av_log_obj){ - if(!obj) - return -1; - - av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name); - - opt_list(obj, av_log_obj, NULL); - - return 0; -} - -/** Set the values of the AVCodecContext or AVFormatContext structure. - * They are set to the defaults specified in the according AVOption options - * array default_val field. - * - * @param s AVCodecContext or AVFormatContext for which the defaults will be set - */ -void av_opt_set_defaults2(void *s, int mask, int flags) -{ - const AVOption *opt = NULL; - while ((opt = av_next_option(s, opt)) != NULL) { - if((opt->flags & mask) != flags) - continue; - switch(opt->type) { - case FF_OPT_TYPE_CONST: - /* Nothing to be done here */ - break; - case FF_OPT_TYPE_FLAGS: - case FF_OPT_TYPE_INT: { - int val; - val = opt->default_val; - av_set_int(s, opt->name, val); - } - break; - case FF_OPT_TYPE_INT64: - if((double)(opt->default_val+0.6) == opt->default_val) - av_log(s, AV_LOG_DEBUG, "loss of precision in default of %s\n", opt->name); - av_set_int(s, opt->name, opt->default_val); - break; - case FF_OPT_TYPE_FLOAT: { - double val; - val = opt->default_val; - av_set_double(s, opt->name, val); - } - break; - case FF_OPT_TYPE_RATIONAL: { - AVRational val; - val = av_d2q(opt->default_val, INT_MAX); - av_set_q(s, opt->name, val); - } - break; - case FF_OPT_TYPE_STRING: - case FF_OPT_TYPE_BINARY: - /* Cannot set default for string as default_val is of type * double */ - break; - default: - av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name); - } - } -} - -void av_opt_set_defaults(void *s){ - av_opt_set_defaults2(s, 0, 0); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/opt.h b/tizen/distrib/ffmpeg/libavcodec/opt.h deleted file mode 100644 index 55ca4ea..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/opt.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * AVOptions - * copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_OPT_H -#define AVCODEC_OPT_H - -/** - * @file - * AVOptions - */ - -#include "libavutil/rational.h" -#include "avcodec.h" - -enum AVOptionType{ - FF_OPT_TYPE_FLAGS, - FF_OPT_TYPE_INT, - FF_OPT_TYPE_INT64, - FF_OPT_TYPE_DOUBLE, - FF_OPT_TYPE_FLOAT, - FF_OPT_TYPE_STRING, - FF_OPT_TYPE_RATIONAL, - FF_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length - FF_OPT_TYPE_CONST=128, -}; - -/** - * AVOption - */ -typedef struct AVOption { - const char *name; - - /** - * short English help text - * @todo What about other languages? - */ - const char *help; - - /** - * The offset relative to the context structure where the option - * value is stored. It should be 0 for named constants. - */ - int offset; - enum AVOptionType type; - - /** - * the default value for scalar options - */ - double default_val; - double min; ///< minimum valid value for the option - double max; ///< maximum valid value for the option - - int flags; -#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding -#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding -#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... -#define AV_OPT_FLAG_AUDIO_PARAM 8 -#define AV_OPT_FLAG_VIDEO_PARAM 16 -#define AV_OPT_FLAG_SUBTITLE_PARAM 32 -//FIXME think about enc-audio, ... style flags - - /** - * The logical unit to which the option belongs. Non-constant - * options and corresponding named constants share the same - * unit. May be NULL. - */ - const char *unit; -} AVOption; - -/** - * AVOption2. - * THIS IS NOT PART OF THE API/ABI YET! - * This is identical to AVOption except that default_val was replaced by - * an union, it should be compatible with AVOption on normal platforms. - */ -typedef struct AVOption2 { - const char *name; - - /** - * short English help text - * @todo What about other languages? - */ - const char *help; - - /** - * The offset relative to the context structure where the option - * value is stored. It should be 0 for named constants. - */ - int offset; - enum AVOptionType type; - - /** - * the default value for scalar options - */ - union { - double dbl; - const char *str; - } default_val; - - double min; ///< minimum valid value for the option - double max; ///< maximum valid value for the option - - int flags; -/* -#define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding -#define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding -#define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... -#define AV_OPT_FLAG_AUDIO_PARAM 8 -#define AV_OPT_FLAG_VIDEO_PARAM 16 -#define AV_OPT_FLAG_SUBTITLE_PARAM 32 -*/ -//FIXME think about enc-audio, ... style flags - - /** - * The logical unit to which the option belongs. Non-constant - * options and corresponding named constants share the same - * unit. May be NULL. - */ - const char *unit; -} AVOption2; - - -/** - * Looks for an option in obj. Looks only for the options which - * have the flags set as specified in mask and flags (that is, - * for which it is the case that opt->flags & mask == flags). - * - * @param[in] obj a pointer to a struct whose first element is a - * pointer to an AVClass - * @param[in] name the name of the option to look for - * @param[in] unit the unit of the option to look for, or any if NULL - * @return a pointer to the option found, or NULL if no option - * has been found - */ -const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags); - -#if LIBAVCODEC_VERSION_MAJOR < 53 -/** - * @see av_set_string2() - */ -attribute_deprecated const AVOption *av_set_string(void *obj, const char *name, const char *val); - -/** - * @return a pointer to the AVOption corresponding to the field set or - * NULL if no matching AVOption exists, or if the value val is not - * valid - * @see av_set_string3() - */ -attribute_deprecated const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc); -#endif - -/** - * Sets the field of obj with the given name to value. - * - * @param[in] obj A struct whose first element is a pointer to an - * AVClass. - * @param[in] name the name of the field to set - * @param[in] val The value to set. If the field is not of a string - * type, then the given string is parsed. - * SI postfixes and some named scalars are supported. - * If the field is of a numeric type, it has to be a numeric or named - * scalar. Behavior with more than one scalar and +- infix operators - * is undefined. - * If the field is of a flags type, it has to be a sequence of numeric - * scalars or named flags separated by '+' or '-'. Prefixing a flag - * with '+' causes it to be set without affecting the other flags; - * similarly, '-' unsets a flag. - * @param[out] o_out if non-NULL put here a pointer to the AVOption - * found - * @param alloc when 1 then the old value will be av_freed() and the - * new av_strduped() - * when 0 then no av_free() nor av_strdup() will be used - * @return 0 if the value has been set, or an AVERROR code in case of - * error: - * AVERROR(ENOENT) if no matching option exists - * AVERROR(ERANGE) if the value is out of range - * AVERROR(EINVAL) if the value is not valid - */ -int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out); - -const AVOption *av_set_double(void *obj, const char *name, double n); -const AVOption *av_set_q(void *obj, const char *name, AVRational n); -const AVOption *av_set_int(void *obj, const char *name, int64_t n); -double av_get_double(void *obj, const char *name, const AVOption **o_out); -AVRational av_get_q(void *obj, const char *name, const AVOption **o_out); -int64_t av_get_int(void *obj, const char *name, const AVOption **o_out); -const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len); -const AVOption *av_next_option(void *obj, const AVOption *last); -int av_opt_show(void *obj, void *av_log_obj); -void av_opt_set_defaults(void *s); -void av_opt_set_defaults2(void *s, int mask, int flags); - -#endif /* AVCODEC_OPT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/options.c b/tizen/distrib/ffmpeg/libavcodec/options.c deleted file mode 100644 index 6835352..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/options.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Options definition for AVCodecContext. - */ - -#include "avcodec.h" -#include "opt.h" -#include /* FLT_MIN, FLT_MAX */ - -static const char* context_to_name(void* ptr) { - AVCodecContext *avc= ptr; - - if(avc && avc->codec && avc->codec->name) - return avc->codec->name; - else - return "NULL"; -} - -#define OFFSET(x) offsetof(AVCodecContext,x) -#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C -//these names are too long to be readable -#define V AV_OPT_FLAG_VIDEO_PARAM -#define A AV_OPT_FLAG_AUDIO_PARAM -#define S AV_OPT_FLAG_SUBTITLE_PARAM -#define E AV_OPT_FLAG_ENCODING_PARAM -#define D AV_OPT_FLAG_DECODING_PARAM - -#define AV_CODEC_DEFAULT_BITRATE 200*1000 - -static const AVOption options[]={ -{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, AV_CODEC_DEFAULT_BITRATE, INT_MIN, INT_MAX, V|E}, -{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, 64*1000, INT_MIN, INT_MAX, A|E}, -{"bt", "set video bitrate tolerance (in bits/s)", OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, AV_CODEC_DEFAULT_BITRATE*20, 1, INT_MAX, V|E}, -{"flags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, 0, UINT_MAX, V|A|E|D, "flags"}, -{"mv4", "use four motion vector by macroblock (mpeg4)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_4MV, INT_MIN, INT_MAX, V|E, "flags"}, -{"obmc", "use overlapped block motion compensation (h263+)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_OBMC, INT_MIN, INT_MAX, V|E, "flags"}, -{"qpel", "use 1/4 pel motion compensation", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QPEL, INT_MIN, INT_MAX, V|E, "flags"}, -{"loop", "use loop filter", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_LOOP_FILTER, INT_MIN, INT_MAX, V|E, "flags"}, -{"qscale", "use fixed qscale", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QSCALE, INT_MIN, INT_MAX, 0, "flags"}, -{"gmc", "use gmc", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GMC, INT_MIN, INT_MAX, V|E, "flags"}, -{"mv0", "always try a mb with mv=<0,0>", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_MV0, INT_MIN, INT_MAX, V|E, "flags"}, -{"part", "use data partitioning", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PART, INT_MIN, INT_MAX, V|E, "flags"}, -{"input_preserved", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INPUT_PRESERVED, INT_MIN, INT_MAX, 0, "flags"}, -{"pass1", "use internal 2pass ratecontrol in first pass mode", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PASS1, INT_MIN, INT_MAX, 0, "flags"}, -{"pass2", "use internal 2pass ratecontrol in second pass mode", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PASS2, INT_MIN, INT_MAX, 0, "flags"}, -{"extern_huff", "use external huffman table (for mjpeg)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_EXTERN_HUFF, INT_MIN, INT_MAX, 0, "flags"}, -{"gray", "only decode/encode grayscale", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GRAY, INT_MIN, INT_MAX, V|E|D, "flags"}, -{"emu_edge", "don't draw edges", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_EMU_EDGE, INT_MIN, INT_MAX, 0, "flags"}, -{"psnr", "error[?] variables will be set during encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PSNR, INT_MIN, INT_MAX, V|E, "flags"}, -{"truncated", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_TRUNCATED, INT_MIN, INT_MAX, 0, "flags"}, -{"naq", "normalize adaptive quantization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_NORMALIZE_AQP, INT_MIN, INT_MAX, V|E, "flags"}, -{"ildct", "use interlaced dct", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INTERLACED_DCT, INT_MIN, INT_MAX, V|E, "flags"}, -{"low_delay", "force low delay", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_LOW_DELAY, INT_MIN, INT_MAX, V|D|E, "flags"}, -{"alt", "enable alternate scantable (mpeg2/mpeg4)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_ALT_SCAN, INT_MIN, INT_MAX, V|E, "flags"}, -{"global_header", "place global headers in extradata instead of every keyframe", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GLOBAL_HEADER, INT_MIN, INT_MAX, V|A|E, "flags"}, -{"bitexact", "use only bitexact stuff (except (i)dct)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_BITEXACT, INT_MIN, INT_MAX, A|V|S|D|E, "flags"}, -{"aic", "h263 advanced intra coding / mpeg4 ac prediction", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_AC_PRED, INT_MIN, INT_MAX, V|E, "flags"}, -{"umv", "use unlimited motion vectors", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_UMV, INT_MIN, INT_MAX, V|E, "flags"}, -{"cbp", "use rate distortion optimization for cbp", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_CBP_RD, INT_MIN, INT_MAX, V|E, "flags"}, -{"qprd", "use rate distortion optimization for qp selection", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QP_RD, INT_MIN, INT_MAX, V|E, "flags"}, -{"aiv", "h263 alternative inter vlc", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_AIV, INT_MIN, INT_MAX, V|E, "flags"}, -{"slice", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_SLICE_STRUCT, INT_MIN, INT_MAX, V|E, "flags"}, -{"ilme", "interlaced motion estimation", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INTERLACED_ME, INT_MIN, INT_MAX, V|E, "flags"}, -{"scan_offset", "will reserve space for svcd scan offset user data", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_SVCD_SCAN_OFFSET, INT_MIN, INT_MAX, V|E, "flags"}, -{"cgop", "closed gop", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_CLOSED_GOP, INT_MIN, INT_MAX, V|E, "flags"}, -{"fast", "allow non spec compliant speedup tricks", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_FAST, INT_MIN, INT_MAX, V|E, "flags2"}, -{"sgop", "strictly enforce gop size", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_STRICT_GOP, INT_MIN, INT_MAX, V|E, "flags2"}, -{"noout", "skip bitstream encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_NO_OUTPUT, INT_MIN, INT_MAX, V|E, "flags2"}, -{"local_header", "place global headers at every keyframe instead of in extradata", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_LOCAL_HEADER, INT_MIN, INT_MAX, V|E, "flags2"}, -{"sub_id", NULL, OFFSET(sub_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"me_method", "set motion estimation method", OFFSET(me_method), FF_OPT_TYPE_INT, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method"}, -{"zero", "zero motion estimation (fastest)", 0, FF_OPT_TYPE_CONST, ME_ZERO, INT_MIN, INT_MAX, V|E, "me_method" }, -{"full", "full motion estimation (slowest)", 0, FF_OPT_TYPE_CONST, ME_FULL, INT_MIN, INT_MAX, V|E, "me_method" }, -{"epzs", "EPZS motion estimation (default)", 0, FF_OPT_TYPE_CONST, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method" }, -{"esa", "esa motion estimation (alias for full)", 0, FF_OPT_TYPE_CONST, ME_FULL, INT_MIN, INT_MAX, V|E, "me_method" }, -{"tesa", "tesa motion estimation", 0, FF_OPT_TYPE_CONST, ME_TESA, INT_MIN, INT_MAX, V|E, "me_method" }, -{"dia", "dia motion estimation (alias for epzs)", 0, FF_OPT_TYPE_CONST, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method" }, -{"log", "log motion estimation", 0, FF_OPT_TYPE_CONST, ME_LOG, INT_MIN, INT_MAX, V|E, "me_method" }, -{"phods", "phods motion estimation", 0, FF_OPT_TYPE_CONST, ME_PHODS, INT_MIN, INT_MAX, V|E, "me_method" }, -{"x1", "X1 motion estimation", 0, FF_OPT_TYPE_CONST, ME_X1, INT_MIN, INT_MAX, V|E, "me_method" }, -{"hex", "hex motion estimation", 0, FF_OPT_TYPE_CONST, ME_HEX, INT_MIN, INT_MAX, V|E, "me_method" }, -{"umh", "umh motion estimation", 0, FF_OPT_TYPE_CONST, ME_UMH, INT_MIN, INT_MAX, V|E, "me_method" }, -{"iter", "iter motion estimation", 0, FF_OPT_TYPE_CONST, ME_ITER, INT_MIN, INT_MAX, V|E, "me_method" }, -{"extradata_size", NULL, OFFSET(extradata_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"time_base", NULL, OFFSET(time_base), FF_OPT_TYPE_RATIONAL, DEFAULT, INT_MIN, INT_MAX}, -{"g", "set the group of picture size", OFFSET(gop_size), FF_OPT_TYPE_INT, 12, INT_MIN, INT_MAX, V|E}, -{"rate_emu", "frame rate emulation", OFFSET(rate_emu), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"ac", "set number of audio channels", OFFSET(channels), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|E}, -{"frame_size", NULL, OFFSET(frame_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|E}, -{"frame_number", NULL, OFFSET(frame_number), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -#if LIBAVCODEC_VERSION_MAJOR < 53 -{"real_pict_num", NULL, OFFSET(real_pict_num), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -#endif -{"delay", NULL, OFFSET(delay), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"qcomp", "video quantizer scale compression (VBR)", OFFSET(qcompress), FF_OPT_TYPE_FLOAT, 0.5, -FLT_MAX, FLT_MAX, V|E}, -{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), FF_OPT_TYPE_FLOAT, 0.5, 0, FLT_MAX, V|E}, -{"qmin", "min video quantizer scale (VBR)", OFFSET(qmin), FF_OPT_TYPE_INT, 2, 1, 51, V|E}, -{"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), FF_OPT_TYPE_INT, 31, 1, 51, V|E}, -{"qdiff", "max difference between the quantizer scale (VBR)", OFFSET(max_qdiff), FF_OPT_TYPE_INT, 3, INT_MIN, INT_MAX, V|E}, -{"bf", "use 'frames' B frames", OFFSET(max_b_frames), FF_OPT_TYPE_INT, DEFAULT, 0, FF_MAX_B_FRAMES, V|E}, -{"b_qfactor", "qp factor between p and b frames", OFFSET(b_quant_factor), FF_OPT_TYPE_FLOAT, 1.25, -FLT_MAX, FLT_MAX, V|E}, -{"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX, V|E}, -{"wpredp", "weighted prediction analysis method", OFFSET(weighted_p_pred), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX, V|E}, -{"hurry_up", NULL, OFFSET(hurry_up), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, -{"ps", "rtp payload size in bytes", OFFSET(rtp_payload_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"mv_bits", NULL, OFFSET(mv_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"header_bits", NULL, OFFSET(header_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"i_tex_bits", NULL, OFFSET(i_tex_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"p_tex_bits", NULL, OFFSET(p_tex_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"i_count", NULL, OFFSET(i_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"p_count", NULL, OFFSET(p_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"skip_count", NULL, OFFSET(skip_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"misc_bits", NULL, OFFSET(misc_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"frame_bits", NULL, OFFSET(frame_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"codec_tag", NULL, OFFSET(codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"bug", "workaround not auto detected encoder bugs", OFFSET(workaround_bugs), FF_OPT_TYPE_FLAGS, FF_BUG_AUTODETECT, INT_MIN, INT_MAX, V|D, "bug"}, -{"autodetect", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AUTODETECT, INT_MIN, INT_MAX, V|D, "bug"}, -{"old_msmpeg4", "some old lavc generated msmpeg4v3 files (no autodetection)", 0, FF_OPT_TYPE_CONST, FF_BUG_OLD_MSMPEG4, INT_MIN, INT_MAX, V|D, "bug"}, -{"xvid_ilace", "Xvid interlacing bug (autodetected if fourcc==XVIX)", 0, FF_OPT_TYPE_CONST, FF_BUG_XVID_ILACE, INT_MIN, INT_MAX, V|D, "bug"}, -{"ump4", "(autodetected if fourcc==UMP4)", 0, FF_OPT_TYPE_CONST, FF_BUG_UMP4, INT_MIN, INT_MAX, V|D, "bug"}, -{"no_padding", "padding bug (autodetected)", 0, FF_OPT_TYPE_CONST, FF_BUG_NO_PADDING, INT_MIN, INT_MAX, V|D, "bug"}, -{"amv", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AMV, INT_MIN, INT_MAX, V|D, "bug"}, -{"ac_vlc", "illegal vlc bug (autodetected per fourcc)", 0, FF_OPT_TYPE_CONST, FF_BUG_AC_VLC, INT_MIN, INT_MAX, V|D, "bug"}, -{"qpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_QPEL_CHROMA, INT_MIN, INT_MAX, V|D, "bug"}, -{"std_qpel", "old standard qpel (autodetected per fourcc/version)", 0, FF_OPT_TYPE_CONST, FF_BUG_STD_QPEL, INT_MIN, INT_MAX, V|D, "bug"}, -{"qpel_chroma2", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_QPEL_CHROMA2, INT_MIN, INT_MAX, V|D, "bug"}, -{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per fourcc/version)", 0, FF_OPT_TYPE_CONST, FF_BUG_DIRECT_BLOCKSIZE, INT_MIN, INT_MAX, V|D, "bug"}, -{"edge", "edge padding bug (autodetected per fourcc/version)", 0, FF_OPT_TYPE_CONST, FF_BUG_EDGE, INT_MIN, INT_MAX, V|D, "bug"}, -{"hpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_HPEL_CHROMA, INT_MIN, INT_MAX, V|D, "bug"}, -{"dc_clip", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_DC_CLIP, INT_MIN, INT_MAX, V|D, "bug"}, -{"ms", "workaround various bugs in microsofts broken decoders", 0, FF_OPT_TYPE_CONST, FF_BUG_MS, INT_MIN, INT_MAX, V|D, "bug"}, -{"trunc", "trancated frames", 0, FF_OPT_TYPE_CONST,FF_BUG_TRUNCATED, INT_MIN, INT_MAX, V|D, "bug"}, -{"lelim", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)", OFFSET(luma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"celim", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)", OFFSET(chroma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|V|D|E, "strict"}, -{"very", "strictly conform to a older more strict version of the spec or reference software", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_VERY_STRICT, INT_MIN, INT_MAX, V|D|E, "strict"}, -{"strict", "strictly conform to all the things in the spec no matter what consequences", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_STRICT, INT_MIN, INT_MAX, V|D|E, "strict"}, -{"normal", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_NORMAL, INT_MIN, INT_MAX, V|D|E, "strict"}, -{"inofficial", "allow unofficial extensions", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_INOFFICIAL, INT_MIN, INT_MAX, V|D|E, "strict"}, -{"experimental", "allow non standardized experimental things", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|D|E, "strict"}, -{"b_qoffset", "qp offset between P and B frames", OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, 1.25, -FLT_MAX, FLT_MAX, V|E}, -{"er", "set error detection aggressivity", OFFSET(error_recognition), FF_OPT_TYPE_INT, FF_ER_CAREFUL, INT_MIN, INT_MAX, A|V|D, "er"}, -{"careful", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, -{"compliant", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_COMPLIANT, INT_MIN, INT_MAX, V|D, "er"}, -{"aggressive", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_AGGRESSIVE, INT_MIN, INT_MAX, V|D, "er"}, -{"very_aggressive", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_VERY_AGGRESSIVE, INT_MIN, INT_MAX, V|D, "er"}, -{"has_b_frames", NULL, OFFSET(has_b_frames), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"block_align", NULL, OFFSET(block_align), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"parse_only", NULL, OFFSET(parse_only), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"stats_out", NULL, OFFSET(stats_out), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX}, -{"stats_in", NULL, OFFSET(stats_in), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX}, -{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", OFFSET(rc_qsquish), FF_OPT_TYPE_FLOAT, DEFAULT, 0, 99, V|E}, -{"rc_qmod_amp", "experimental quantizer modulation", OFFSET(rc_qmod_amp), FF_OPT_TYPE_FLOAT, DEFAULT, -FLT_MAX, FLT_MAX, V|E}, -{"rc_qmod_freq", "experimental quantizer modulation", OFFSET(rc_qmod_freq), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"rc_override_count", NULL, OFFSET(rc_override_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"rc_eq", "set rate control equation", OFFSET(rc_eq), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX, V|E}, -{"maxrate", "set max video bitrate tolerance (in bits/s)", OFFSET(rc_max_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"minrate", "set min video bitrate tolerance (in bits/s)", OFFSET(rc_min_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|V|E}, -{"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, 1.0, -FLT_MAX, FLT_MAX, V|E}, -{"i_qfactor", "qp factor between P and I frames", OFFSET(i_quant_factor), FF_OPT_TYPE_FLOAT, -0.8, -FLT_MAX, FLT_MAX, V|E}, -{"i_qoffset", "qp offset between P and I frames", OFFSET(i_quant_offset), FF_OPT_TYPE_FLOAT, 0.0, -FLT_MAX, FLT_MAX, V|E}, -{"rc_init_cplx", "initial complexity for 1-pass encoding", OFFSET(rc_initial_cplx), FF_OPT_TYPE_FLOAT, DEFAULT, -FLT_MAX, FLT_MAX, V|E}, -{"dct", "DCT algorithm", OFFSET(dct_algo), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|E, "dct"}, -{"auto", "autoselect a good one (default)", 0, FF_OPT_TYPE_CONST, FF_DCT_AUTO, INT_MIN, INT_MAX, V|E, "dct"}, -{"fastint", "fast integer", 0, FF_OPT_TYPE_CONST, FF_DCT_FASTINT, INT_MIN, INT_MAX, V|E, "dct"}, -{"int", "accurate integer", 0, FF_OPT_TYPE_CONST, FF_DCT_INT, INT_MIN, INT_MAX, V|E, "dct"}, -{"mmx", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_MMX, INT_MIN, INT_MAX, V|E, "dct"}, -{"mlib", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_MLIB, INT_MIN, INT_MAX, V|E, "dct"}, -{"altivec", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_ALTIVEC, INT_MIN, INT_MAX, V|E, "dct"}, -{"faan", "floating point AAN DCT", 0, FF_OPT_TYPE_CONST, FF_DCT_FAAN, INT_MIN, INT_MAX, V|E, "dct"}, -{"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"p_mask", "inter masking", OFFSET(p_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"idct", "select IDCT implementation", OFFSET(idct_algo), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|E|D, "idct"}, -{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_AUTO, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_INT, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simple", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLE, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplemmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEMMX, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"libmpeg2mmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_LIBMPEG2MMX, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"ps2", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_PS2, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"mlib", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_MLIB, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"arm", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_ARM, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"altivec", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_ALTIVEC, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"sh4", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SH4, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplearm", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARM, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplearmv5te", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARMV5TE, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplearmv6", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARMV6, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simpleneon", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLENEON, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplealpha", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEALPHA, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"h264", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_H264, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"vp3", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_VP3, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"ipp", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_IPP, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"xvidmmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_XVIDMMX, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"faani", "floating point AAN IDCT", 0, FF_OPT_TYPE_CONST, FF_IDCT_FAAN, INT_MIN, INT_MAX, V|D|E, "idct"}, -{"slice_count", NULL, OFFSET(slice_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"ec", "set error concealment strategy", OFFSET(error_concealment), FF_OPT_TYPE_FLAGS, 3, INT_MIN, INT_MAX, V|D, "ec"}, -{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, FF_OPT_TYPE_CONST, FF_EC_GUESS_MVS, INT_MIN, INT_MAX, V|D, "ec"}, -{"deblock", "use strong deblock filter for damaged MBs", 0, FF_OPT_TYPE_CONST, FF_EC_DEBLOCK, INT_MIN, INT_MAX, V|D, "ec"}, -{"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"pred", "prediction method", OFFSET(prediction_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "pred"}, -{"left", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_LEFT, INT_MIN, INT_MAX, V|E, "pred"}, -{"plane", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_PLANE, INT_MIN, INT_MAX, V|E, "pred"}, -{"median", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_MEDIAN, INT_MIN, INT_MAX, V|E, "pred"}, -{"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), FF_OPT_TYPE_RATIONAL, DEFAULT, 0, 10, V|E}, -{"debug", "print specific debug info", OFFSET(debug), FF_OPT_TYPE_FLAGS, DEFAULT, 0, INT_MAX, V|A|S|E|D, "debug"}, -{"pict", "picture info", 0, FF_OPT_TYPE_CONST, FF_DEBUG_PICT_INFO, INT_MIN, INT_MAX, V|D, "debug"}, -{"rc", "rate control", 0, FF_OPT_TYPE_CONST, FF_DEBUG_RC, INT_MIN, INT_MAX, V|E, "debug"}, -{"bitstream", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_BITSTREAM, INT_MIN, INT_MAX, V|D, "debug"}, -{"mb_type", "macroblock (MB) type", 0, FF_OPT_TYPE_CONST, FF_DEBUG_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, -{"qp", "per-block quantization parameter (QP)", 0, FF_OPT_TYPE_CONST, FF_DEBUG_QP, INT_MIN, INT_MAX, V|D, "debug"}, -{"mv", "motion vector", 0, FF_OPT_TYPE_CONST, FF_DEBUG_MV, INT_MIN, INT_MAX, V|D, "debug"}, -{"dct_coeff", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_DCT_COEFF, INT_MIN, INT_MAX, V|D, "debug"}, -{"skip", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_SKIP, INT_MIN, INT_MAX, V|D, "debug"}, -{"startcode", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_STARTCODE, INT_MIN, INT_MAX, V|D, "debug"}, -{"pts", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_PTS, INT_MIN, INT_MAX, V|D, "debug"}, -{"er", "error recognition", 0, FF_OPT_TYPE_CONST, FF_DEBUG_ER, INT_MIN, INT_MAX, V|D, "debug"}, -{"mmco", "memory management control operations (H.264)", 0, FF_OPT_TYPE_CONST, FF_DEBUG_MMCO, INT_MIN, INT_MAX, V|D, "debug"}, -{"bugs", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_BUGS, INT_MIN, INT_MAX, V|D, "debug"}, -{"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_QP, INT_MIN, INT_MAX, V|D, "debug"}, -{"vis_mb_type", "visualize block types", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, -{"buffers", "picture buffer allocations", 0, FF_OPT_TYPE_CONST, FF_DEBUG_BUFFERS, INT_MIN, INT_MAX, V|D, "debug"}, -{"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|D, "debug_mv"}, -{"pf", "forward predicted MVs of P-frames", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_P_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, -{"bf", "forward predicted MVs of B-frames", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, -{"bb", "backward predicted MVs of B-frames", 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_BACK, INT_MIN, INT_MAX, V|D, "debug_mv"}, -{"mb_qmin", "obsolete, use qmin", OFFSET(mb_qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"mb_qmax", "obsolete, use qmax", OFFSET(mb_qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"cmp", "full pel me compare function", OFFSET(me_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"subcmp", "sub pel me compare function", OFFSET(me_sub_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"ildctcmp", "interlaced dct compare function", OFFSET(ildct_cmp), FF_OPT_TYPE_INT, FF_CMP_VSAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"preme", "pre motion estimation", OFFSET(pre_me), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"sad", "sum of absolute differences, fast (default)", 0, FF_OPT_TYPE_CONST, FF_CMP_SAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"sse", "sum of squared errors", 0, FF_OPT_TYPE_CONST, FF_CMP_SSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"satd", "sum of absolute Hadamard transformed differences", 0, FF_OPT_TYPE_CONST, FF_CMP_SATD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"dct", "sum of absolute DCT transformed differences", 0, FF_OPT_TYPE_CONST, FF_CMP_DCT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, FF_OPT_TYPE_CONST, FF_CMP_PSNR, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"bit", "number of bits needed for the block", 0, FF_OPT_TYPE_CONST, FF_CMP_BIT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"rd", "rate distortion optimal, slow", 0, FF_OPT_TYPE_CONST, FF_CMP_RD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"zero", "0", 0, FF_OPT_TYPE_CONST, FF_CMP_ZERO, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"vsad", "sum of absolute vertical differences", 0, FF_OPT_TYPE_CONST, FF_CMP_VSAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"vsse","sum of squared vertical differences", 0, FF_OPT_TYPE_CONST, FF_CMP_VSSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"nsse", "noise preserving sum of squared differences", 0, FF_OPT_TYPE_CONST, FF_CMP_NSSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, -#if CONFIG_SNOW_ENCODER -{"w53", "5/3 wavelet, only used in snow", 0, FF_OPT_TYPE_CONST, FF_CMP_W53, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"w97", "9/7 wavelet, only used in snow", 0, FF_OPT_TYPE_CONST, FF_CMP_W97, INT_MIN, INT_MAX, V|E, "cmp_func"}, -#endif -{"dctmax", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_DCTMAX, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_CHROMA, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"subq", "sub pel motion estimation quality", OFFSET(me_subpel_quality), FF_OPT_TYPE_INT, 8, INT_MIN, INT_MAX, V|E}, -{"dtg_active_format", NULL, OFFSET(dtg_active_format), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"ibias", "intra quant bias", OFFSET(intra_quant_bias), FF_OPT_TYPE_INT, FF_DEFAULT_QUANT_BIAS, INT_MIN, INT_MAX, V|E}, -{"pbias", "inter quant bias", OFFSET(inter_quant_bias), FF_OPT_TYPE_INT, FF_DEFAULT_QUANT_BIAS, INT_MIN, INT_MAX, V|E}, -{"color_table_id", NULL, OFFSET(color_table_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"internal_buffer_count", NULL, OFFSET(internal_buffer_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"global_quality", NULL, OFFSET(global_quality), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"coder", NULL, OFFSET(coder_type), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "coder"}, -{"vlc", "variable length coder / huffman coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_VLC, INT_MIN, INT_MAX, V|E, "coder"}, -{"ac", "arithmetic coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_AC, INT_MIN, INT_MAX, V|E, "coder"}, -{"raw", "raw (no encoding)", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_RAW, INT_MIN, INT_MAX, V|E, "coder"}, -{"rle", "run-length coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_RLE, INT_MIN, INT_MAX, V|E, "coder"}, -{"deflate", "deflate-based coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_DEFLATE, INT_MIN, INT_MAX, V|E, "coder"}, -{"context", "context model", OFFSET(context_model), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"slice_flags", NULL, OFFSET(slice_flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "mbd"}, -{"simple", "use mbcmp (default)", 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_SIMPLE, INT_MIN, INT_MAX, V|E, "mbd"}, -{"bits", "use fewest bits", 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_BITS, INT_MIN, INT_MAX, V|E, "mbd"}, -{"rd", "use best rate distortion", 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_RD, INT_MIN, INT_MAX, V|E, "mbd"}, -{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"lmin", "min lagrange factor (VBR)", OFFSET(lmin), FF_OPT_TYPE_INT, 2*FF_QP2LAMBDA, 0, INT_MAX, V|E}, -{"lmax", "max lagrange factor (VBR)", OFFSET(lmax), FF_OPT_TYPE_INT, 31*FF_QP2LAMBDA, 0, INT_MAX, V|E}, -{"nr", "noise reduction", OFFSET(noise_reduction), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"inter_threshold", NULL, OFFSET(inter_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"flags2", NULL, OFFSET(flags2), FF_OPT_TYPE_FLAGS, CODEC_FLAG2_FASTPSKIP|CODEC_FLAG2_BIT_RESERVOIR|CODEC_FLAG2_PSY|CODEC_FLAG2_MBTREE, 0, UINT_MAX, V|A|E|D, "flags2"}, -{"error", NULL, OFFSET(error_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"antialias", "MP3 antialias algorithm", OFFSET(antialias_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D, "aa"}, -{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_AUTO, INT_MIN, INT_MAX, V|D, "aa"}, -{"fastint", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_FASTINT, INT_MIN, INT_MAX, V|D, "aa"}, -{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_INT, INT_MIN, INT_MAX, V|D, "aa"}, -{"float", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_FLOAT, INT_MIN, INT_MAX, V|D, "aa"}, -{"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"threads", NULL, OFFSET(thread_count), FF_OPT_TYPE_INT, 1, INT_MIN, INT_MAX, V|E|D}, -{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX, V|E}, -{"nssew", "nsse weight", OFFSET(nsse_weight), FF_OPT_TYPE_INT, 8, INT_MIN, INT_MAX, V|E}, -{"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, -{"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, -{"profile", NULL, OFFSET(profile), FF_OPT_TYPE_INT, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, -{"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, -{"aac_main", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_MAIN, INT_MIN, INT_MAX, A|E, "profile"}, -{"aac_low", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_LOW, INT_MIN, INT_MAX, A|E, "profile"}, -{"aac_ssr", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_SSR, INT_MIN, INT_MAX, A|E, "profile"}, -{"aac_ltp", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_LTP, INT_MIN, INT_MAX, A|E, "profile"}, -{"level", NULL, OFFSET(level), FF_OPT_TYPE_INT, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, -{"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, -{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|D}, -{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), FF_OPT_TYPE_INT, FF_CMP_DCTMAX, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"border_mask", "increases the quantizer for macroblocks close to borders", OFFSET(border_masking), FF_OPT_TYPE_FLOAT, DEFAULT, -FLT_MAX, FLT_MAX, V|E}, -{"mblmin", "min macroblock lagrange factor (VBR)", OFFSET(mb_lmin), FF_OPT_TYPE_INT, FF_QP2LAMBDA * 2, 1, FF_LAMBDA_MAX, V|E}, -{"mblmax", "max macroblock lagrange factor (VBR)", OFFSET(mb_lmax), FF_OPT_TYPE_INT, FF_QP2LAMBDA * 31, 1, FF_LAMBDA_MAX, V|E}, -{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), FF_OPT_TYPE_INT, 256, INT_MIN, INT_MAX, V|E}, -{"skip_loop_filter", NULL, OFFSET(skip_loop_filter), FF_OPT_TYPE_INT, AVDISCARD_DEFAULT, INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"skip_idct" , NULL, OFFSET(skip_idct) , FF_OPT_TYPE_INT, AVDISCARD_DEFAULT, INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"skip_frame" , NULL, OFFSET(skip_frame) , FF_OPT_TYPE_INT, AVDISCARD_DEFAULT, INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"none" , NULL, 0, FF_OPT_TYPE_CONST, AVDISCARD_NONE , INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"default" , NULL, 0, FF_OPT_TYPE_CONST, AVDISCARD_DEFAULT, INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"noref" , NULL, 0, FF_OPT_TYPE_CONST, AVDISCARD_NONREF , INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"bidir" , NULL, 0, FF_OPT_TYPE_CONST, AVDISCARD_BIDIR , INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"nokey" , NULL, 0, FF_OPT_TYPE_CONST, AVDISCARD_NONKEY , INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"all" , NULL, 0, FF_OPT_TYPE_CONST, AVDISCARD_ALL , INT_MIN, INT_MAX, V|D, "avdiscard"}, -{"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), FF_OPT_TYPE_INT, 1, 0, 4, V|E}, -{"brd_scale", "downscales frames for dynamic B-frame decision", OFFSET(brd_scale), FF_OPT_TYPE_INT, DEFAULT, 0, 10, V|E}, -{"crf", "enables constant quality mode, and selects the quality (x264)", OFFSET(crf), FF_OPT_TYPE_FLOAT, DEFAULT, 0, 51, V|E}, -{"cqp", "constant quantization parameter rate control method", OFFSET(cqp), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, V|E}, -{"keyint_min", "minimum interval between IDR-frames (x264)", OFFSET(keyint_min), FF_OPT_TYPE_INT, 25, INT_MIN, INT_MAX, V|E}, -{"refs", "reference frames to consider for motion compensation (Snow)", OFFSET(refs), FF_OPT_TYPE_INT, 1, INT_MIN, INT_MAX, V|E}, -{"chromaoffset", "chroma qp offset from luma", OFFSET(chromaoffset), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"bframebias", "influences how often B-frames are used", OFFSET(bframebias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"trellis", "rate-distortion optimal quantization", OFFSET(trellis), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|A|E}, -{"directpred", "direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto)", OFFSET(directpred), FF_OPT_TYPE_INT, 2, INT_MIN, INT_MAX, V|E}, -{"bpyramid", "allows B-frames to be used as references for predicting", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BPYRAMID, INT_MIN, INT_MAX, V|E, "flags2"}, -{"wpred", "weighted biprediction for b-frames (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_WPRED, INT_MIN, INT_MAX, V|E, "flags2"}, -{"mixed_refs", "one reference per partition, as opposed to one reference per macroblock", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_MIXED_REFS, INT_MIN, INT_MAX, V|E, "flags2"}, -{"dct8x8", "high profile 8x8 transform (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_8X8DCT, INT_MIN, INT_MAX, V|E, "flags2"}, -{"fastpskip", "fast pskip (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_FASTPSKIP, INT_MIN, INT_MAX, V|E, "flags2"}, -{"aud", "access unit delimiters (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_AUD, INT_MIN, INT_MAX, V|E, "flags2"}, -{"skiprd", "RD optimal MB level residual skipping", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_SKIP_RD, INT_MIN, INT_MAX, V|E, "flags2"}, -{"complexityblur", "reduce fluctuations in qp (before curve compression)", OFFSET(complexityblur), FF_OPT_TYPE_FLOAT, 20.0, FLT_MIN, FLT_MAX, V|E}, -{"deblockalpha", "in-loop deblocking filter alphac0 parameter", OFFSET(deblockalpha), FF_OPT_TYPE_INT, DEFAULT, -6, 6, V|E}, -{"deblockbeta", "in-loop deblocking filter beta parameter", OFFSET(deblockbeta), FF_OPT_TYPE_INT, DEFAULT, -6, 6, V|E}, -{"partitions", "macroblock subpartition sizes to consider", OFFSET(partitions), FF_OPT_TYPE_FLAGS, DEFAULT, INT_MIN, INT_MAX, V|E, "partitions"}, -{"parti4x4", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_I4X4, INT_MIN, INT_MAX, V|E, "partitions"}, -{"parti8x8", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_I8X8, INT_MIN, INT_MAX, V|E, "partitions"}, -{"partp4x4", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_P4X4, INT_MIN, INT_MAX, V|E, "partitions"}, -{"partp8x8", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_P8X8, INT_MIN, INT_MAX, V|E, "partitions"}, -{"partb8x8", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_B8X8, INT_MIN, INT_MAX, V|E, "partitions"}, -{"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), FF_OPT_TYPE_INT, 6, 0, INT_MAX, V|E}, -{"mv0_threshold", NULL, OFFSET(mv0_threshold), FF_OPT_TYPE_INT, 256, 0, INT_MAX, V|E}, -{"ivlc", "intra vlc table", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_INTRA_VLC, INT_MIN, INT_MAX, V|E, "flags2"}, -{"b_sensitivity", "adjusts sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), FF_OPT_TYPE_INT, 40, 1, INT_MAX, V|E}, -{"compression_level", NULL, OFFSET(compression_level), FF_OPT_TYPE_INT, FF_COMPRESSION_DEFAULT, INT_MIN, INT_MAX, V|A|E}, -{"use_lpc", "sets whether to use LPC mode (FLAC)", OFFSET(use_lpc), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"lpc_coeff_precision", "LPC coefficient precision (FLAC)", OFFSET(lpc_coeff_precision), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, A|E}, -{"min_prediction_order", NULL, OFFSET(min_prediction_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"max_prediction_order", NULL, OFFSET(max_prediction_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"prediction_order_method", "search method for selecting prediction order", OFFSET(prediction_order_method), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"min_partition_order", NULL, OFFSET(min_partition_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"max_partition_order", NULL, OFFSET(max_partition_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"timecode_frame_start", "GOP timecode frame start number, in non drop frame format", OFFSET(timecode_frame_start), FF_OPT_TYPE_INT64, 0, 0, INT64_MAX, V|E}, -{"drop_frame_timecode", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_DROP_FRAME_TIMECODE, INT_MIN, INT_MAX, V|E, "flags2"}, -{"non_linear_q", "use non linear quantizer", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_NON_LINEAR_QUANT, INT_MIN, INT_MAX, V|E, "flags2"}, -{"request_channels", "set desired number of audio channels", OFFSET(request_channels), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, A|D}, -{"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, 1.0, 0.0, 1.0, A|D}, -{"reservoir", "use bit reservoir", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BIT_RESERVOIR, INT_MIN, INT_MAX, A|E, "flags2"}, -{"mbtree", "use macroblock tree ratecontrol (x264 only)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_MBTREE, INT_MIN, INT_MAX, V|E, "flags2"}, -{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"channel_layout", NULL, OFFSET(channel_layout), FF_OPT_TYPE_INT64, DEFAULT, 0, INT64_MAX, A|E|D, "channel_layout"}, -{"request_channel_layout", NULL, OFFSET(request_channel_layout), FF_OPT_TYPE_INT64, DEFAULT, 0, INT64_MAX, A|D, "request_channel_layout"}, -{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), FF_OPT_TYPE_FLOAT, 1.0/3, 0.0, FLT_MAX, V|E}, -{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), FF_OPT_TYPE_FLOAT, 3, 0.0, FLT_MAX, V|E}, -{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), FF_OPT_TYPE_INT, 1, 1, INT_MAX, A|V|E|D}, -{"color_primaries", NULL, OFFSET(color_primaries), FF_OPT_TYPE_INT, AVCOL_PRI_UNSPECIFIED, 1, AVCOL_PRI_NB-1, V|E|D}, -{"color_trc", NULL, OFFSET(color_trc), FF_OPT_TYPE_INT, AVCOL_TRC_UNSPECIFIED, 1, AVCOL_TRC_NB-1, V|E|D}, -{"colorspace", NULL, OFFSET(colorspace), FF_OPT_TYPE_INT, AVCOL_SPC_UNSPECIFIED, 1, AVCOL_SPC_NB-1, V|E|D}, -{"color_range", NULL, OFFSET(color_range), FF_OPT_TYPE_INT, AVCOL_RANGE_UNSPECIFIED, 0, AVCOL_RANGE_NB-1, V|E|D}, -{"chroma_sample_location", NULL, OFFSET(chroma_sample_location), FF_OPT_TYPE_INT, AVCHROMA_LOC_UNSPECIFIED, 0, AVCHROMA_LOC_NB-1, V|E|D}, -{"psy", "use psycho visual optimization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_PSY, INT_MIN, INT_MAX, V|E, "flags2"}, -{"psy_rd", "specify psycho visual strength", OFFSET(psy_rd), FF_OPT_TYPE_FLOAT, 1.0, 0, FLT_MAX, V|E}, -{"psy_trellis", "specify psycho visual trellis", OFFSET(psy_trellis), FF_OPT_TYPE_FLOAT, 0, 0, FLT_MAX, V|E}, -{"aq_mode", "specify aq method", OFFSET(aq_mode), FF_OPT_TYPE_INT, 1, 0, INT_MAX, V|E}, -{"aq_strength", "specify aq strength", OFFSET(aq_strength), FF_OPT_TYPE_FLOAT, 1.0, 0, FLT_MAX, V|E}, -{"rc_lookahead", "specify number of frames to look ahead for frametype", OFFSET(rc_lookahead), FF_OPT_TYPE_INT, 40, 0, INT_MAX, V|E}, -{"ssim", "ssim will be calculated during encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_SSIM, INT_MIN, INT_MAX, V|E, "flags2"}, -{NULL}, -}; - -#undef A -#undef V -#undef S -#undef E -#undef D -#undef DEFAULT - -static const AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options, LIBAVUTIL_VERSION_INT }; - -void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){ - int flags=0; - memset(s, 0, sizeof(AVCodecContext)); - - s->av_class= &av_codec_context_class; - - s->codec_type = codec_type; - if(codec_type == AVMEDIA_TYPE_AUDIO) - flags= AV_OPT_FLAG_AUDIO_PARAM; - else if(codec_type == AVMEDIA_TYPE_VIDEO) - flags= AV_OPT_FLAG_VIDEO_PARAM; - else if(codec_type == AVMEDIA_TYPE_SUBTITLE) - flags= AV_OPT_FLAG_SUBTITLE_PARAM; - av_opt_set_defaults2(s, flags, flags); - - s->time_base= (AVRational){0,1}; - s->get_buffer= avcodec_default_get_buffer; - s->release_buffer= avcodec_default_release_buffer; - s->get_format= avcodec_default_get_format; - s->execute= avcodec_default_execute; - s->execute2= avcodec_default_execute2; - s->sample_aspect_ratio= (AVRational){0,1}; - s->pix_fmt= PIX_FMT_NONE; - s->sample_fmt= SAMPLE_FMT_NONE; - - s->palctrl = NULL; - s->reget_buffer= avcodec_default_reget_buffer; - s->reordered_opaque= AV_NOPTS_VALUE; -} - -AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){ - AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); - - if(avctx==NULL) return NULL; - - avcodec_get_context_defaults2(avctx, codec_type); - - return avctx; -} - -void avcodec_get_context_defaults(AVCodecContext *s){ - avcodec_get_context_defaults2(s, AVMEDIA_TYPE_UNKNOWN); -} - -AVCodecContext *avcodec_alloc_context(void){ - return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN); -} - -int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) -{ - if (dest->codec) { // check that the dest context is uninitialized - av_log(dest, AV_LOG_ERROR, - "Tried to copy AVCodecContext %p into already-initialized %p\n", - src, dest); - return AVERROR(EINVAL); - } - memcpy(dest, src, sizeof(*dest)); - - /* set values specific to opened codecs back to their default state */ - dest->priv_data = NULL; - dest->codec = NULL; - dest->palctrl = NULL; - dest->slice_offset = NULL; - dest->internal_buffer = NULL; - dest->hwaccel = NULL; - dest->execute = NULL; - dest->execute2 = NULL; - dest->reget_buffer = NULL; - dest->thread_opaque = NULL; - - /* reallocate values that should be allocated separately */ - dest->rc_eq = NULL; - dest->extradata = NULL; - dest->intra_matrix = NULL; - dest->inter_matrix = NULL; - dest->rc_override = NULL; - if (src->rc_eq) { - dest->rc_eq = av_strdup(src->rc_eq); - if (!dest->rc_eq) - return AVERROR(ENOMEM); - } - -#define alloc_and_copy_or_fail(obj, size, pad) \ - if (src->obj && size > 0) { \ - dest->obj = av_malloc(size + pad); \ - if (!dest->obj) \ - goto fail; \ - memcpy(dest->obj, src->obj, size); \ - if (pad) \ - memset(((uint8_t *) dest->obj) + size, 0, pad); \ - } - alloc_and_copy_or_fail(extradata, src->extradata_size, - FF_INPUT_BUFFER_PADDING_SIZE); - alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0); - alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0); - alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0); -#undef alloc_and_copy_or_fail - - return 0; - -fail: - av_freep(&dest->rc_override); - av_freep(&dest->intra_matrix); - av_freep(&dest->inter_matrix); - av_freep(&dest->extradata); - av_freep(&dest->rc_eq); - return AVERROR(ENOMEM); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/os2thread.c b/tizen/distrib/ffmpeg/libavcodec/os2thread.c deleted file mode 100644 index 3d1367c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/os2thread.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -//#define DEBUG - -// Ported by Vlad Stelmahovsky - -#include "avcodec.h" - -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_DOSDEVIOCTL -#include - -typedef struct ThreadContext{ - AVCodecContext *avctx; - int thread; - HEV work_sem; - HEV done_sem; - int (*func)(AVCodecContext *c, void *arg); - void *arg; - int ret; -}ThreadContext; - - -static void attribute_align_arg thread_func(void *v){ - ThreadContext *c= v; - - for(;;){ - //printf("thread_func %X enter wait\n", (int)v); fflush(stdout); - DosWaitEventSem(c->work_sem, SEM_INDEFINITE_WAIT); -// WaitForSingleObject(c->work_sem, INFINITE); -//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; - //printf("thread_func %X signal complete\n", (int)v); fflush(stdout); - DosPostEventSem(c->done_sem); -// ReleaseSemaphore(c->done_sem, 1, 0); - } - - return; -} - -/** - * free what has been allocated by avcodec_thread_init(). - * must be called after decoding has finished, especially do not call while avcodec_thread_execute() is running - */ -void avcodec_thread_free(AVCodecContext *s){ - ThreadContext *c= s->thread_opaque; - int i; - - for(i=0; ithread_count; i++){ - - c[i].func= NULL; - DosPostEventSem(c[i].work_sem); - // ReleaseSemaphore(c[i].work_sem, 1, 0); - DosWaitThread((PTID)&c[i].thread,DCWW_WAIT); -// WaitForSingleObject(c[i].thread, INFINITE); - if(c[i].work_sem) DosCloseEventSem(c[i].work_sem);//CloseHandle(c[i].work_sem); - if(c[i].done_sem) DosCloseEventSem(c[i].done_sem);//CloseHandle(c[i].done_sem); - } - - av_freep(&s->thread_opaque); -} - -static int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size){ - 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; - - if (thread_count <= 1) - return 0; - - 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; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/pamenc.c b/tizen/distrib/ffmpeg/libavcodec/pamenc.c deleted file mode 100644 index ae0ea3a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pamenc.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * PAM image format - * Copyright (c) 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "pnm.h" - - -static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, - int buf_size, void *data) -{ - PNMContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p = (AVFrame*)&s->picture; - int i, h, w, n, linesize, depth, maxval; - const char *tuple_type; - uint8_t *ptr; - - if (buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200) { - av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - *p = *pict; - p->pict_type = FF_I_TYPE; - p->key_frame = 1; - - s->bytestream_start = - s->bytestream = outbuf; - s->bytestream_end = outbuf+buf_size; - - h = avctx->height; - w = avctx->width; - switch (avctx->pix_fmt) { - case PIX_FMT_MONOWHITE: - n = (w + 7) >> 3; - depth = 1; - maxval = 1; - tuple_type = "BLACKANDWHITE"; - break; - case PIX_FMT_GRAY8: - n = w; - depth = 1; - maxval = 255; - tuple_type = "GRAYSCALE"; - break; - case PIX_FMT_RGB24: - n = w * 3; - depth = 3; - maxval = 255; - tuple_type = "RGB"; - break; - case PIX_FMT_RGB32: - n = w * 4; - depth = 4; - maxval = 255; - tuple_type = "RGB_ALPHA"; - break; - default: - return -1; - } - snprintf(s->bytestream, s->bytestream_end - s->bytestream, - "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n", - w, h, depth, maxval, tuple_type); - s->bytestream += strlen(s->bytestream); - - ptr = p->data[0]; - linesize = p->linesize[0]; - - if (avctx->pix_fmt == PIX_FMT_RGB32) { - int j; - unsigned int v; - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - v = ((uint32_t *)ptr)[j]; - bytestream_put_be24(&s->bytestream, v); - *s->bytestream++ = v >> 24; - } - ptr += linesize; - } - } else { - for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; - } - } - return s->bytestream - s->bytestream_start; -} - - -AVCodec pam_encoder = { - "pam", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PAM, - sizeof(PNMContext), - ff_pnm_init, - pam_encode_frame, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/parser.c b/tizen/distrib/ffmpeg/libavcodec/parser.c deleted file mode 100644 index 864b5f2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/parser.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Audio and Video frame extraction - * Copyright (c) 2003 Fabrice Bellard - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" - -static AVCodecParser *av_first_parser = NULL; - -AVCodecParser* av_parser_next(AVCodecParser *p){ - if(p) return p->next; - else return av_first_parser; -} - -void av_register_codec_parser(AVCodecParser *parser) -{ - parser->next = av_first_parser; - av_first_parser = parser; -} - -AVCodecParserContext *av_parser_init(int codec_id) -{ - AVCodecParserContext *s; - AVCodecParser *parser; - int ret; - - if(codec_id == CODEC_ID_NONE) - return NULL; - - for(parser = av_first_parser; parser != NULL; parser = parser->next) { - if (parser->codec_ids[0] == codec_id || - parser->codec_ids[1] == codec_id || - parser->codec_ids[2] == codec_id || - parser->codec_ids[3] == codec_id || - parser->codec_ids[4] == codec_id) - goto found; - } - return NULL; - found: - s = av_mallocz(sizeof(AVCodecParserContext)); - if (!s) - return NULL; - s->parser = parser; - s->priv_data = av_mallocz(parser->priv_data_size); - if (!s->priv_data) { - av_free(s); - return NULL; - } - if (parser->parser_init) { - ret = parser->parser_init(s); - if (ret != 0) { - av_free(s->priv_data); - av_free(s); - return NULL; - } - } - s->fetch_timestamp=1; - s->pict_type = FF_I_TYPE; - s->key_frame = -1; - s->convergence_duration = AV_NOPTS_VALUE; - s->dts_sync_point = INT_MIN; - s->dts_ref_dts_delta = INT_MIN; - s->pts_dts_delta = INT_MIN; - return s; -} - -void ff_fetch_timestamp(AVCodecParserContext *s, int off, int remove){ - int i; - - s->dts= s->pts= AV_NOPTS_VALUE; - s->pos= -1; - s->offset= 0; - for(i = 0; i < AV_PARSER_PTS_NB; i++) { - if ( s->cur_offset + off >= s->cur_frame_offset[i] - && (s->frame_offset < s->cur_frame_offset[i] || - (!s->frame_offset && !s->next_frame_offset)) // first field/frame - //check is disabled because mpeg-ts doesnt send complete PES packets - && /*s->next_frame_offset + off <*/ s->cur_frame_end[i]){ - s->dts= s->cur_frame_dts[i]; - s->pts= s->cur_frame_pts[i]; - s->pos= s->cur_frame_pos[i]; - s->offset = s->next_frame_offset - s->cur_frame_offset[i]; - if(remove) - s->cur_frame_offset[i]= INT64_MAX; - if(s->cur_offset + off < s->cur_frame_end[i]) - break; - } - } -} - -/** - * - * @param buf input - * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output) - * @param pts input presentation timestamp - * @param dts input decoding timestamp - * @param poutbuf will contain a pointer to the first byte of the output frame - * @param poutbuf_size will contain the length of the output frame - * @return the number of bytes of the input bitstream used - * - * Example: - * @code - * while(in_len){ - * len = av_parser_parse(myparser, AVCodecContext, &data, &size, - * in_data, in_len, - * pts, dts); - * in_data += len; - * in_len -= len; - * - * if(size) - * decode_frame(data, size); - * } - * @endcode - * - * @deprecated Use av_parser_parse2() instead. - */ -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) -{ - return av_parser_parse2(s, avctx, poutbuf, poutbuf_size, buf, buf_size, pts, dts, AV_NOPTS_VALUE); -} - -int av_parser_parse2(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, - int64_t pts, int64_t dts, - int64_t pos) -{ - int index, i; - uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; - - if (buf_size == 0) { - /* padding is always necessary even if EOF, so we add it here */ - memset(dummy_buf, 0, sizeof(dummy_buf)); - buf = dummy_buf; - } else if (s->cur_offset + buf_size != - s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */ - /* add a new packet descriptor */ - i = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); - s->cur_frame_start_index = i; - s->cur_frame_offset[i] = s->cur_offset; - s->cur_frame_end[i] = s->cur_offset + buf_size; - s->cur_frame_pts[i] = pts; - s->cur_frame_dts[i] = dts; - s->cur_frame_pos[i] = pos; - } - - if (s->fetch_timestamp){ - s->fetch_timestamp=0; - s->last_pts = s->pts; - s->last_dts = s->dts; - s->last_pos = s->pos; - ff_fetch_timestamp(s, 0, 0); - } - - /* WARNING: the returned index can be negative */ - index = s->parser->parser_parse(s, avctx, (const uint8_t **)poutbuf, poutbuf_size, buf, buf_size); -//av_log(NULL, AV_LOG_DEBUG, "parser: in:%"PRId64", %"PRId64", out:%"PRId64", %"PRId64", in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id); - /* update the file pointer */ - if (*poutbuf_size) { - /* fill the data for the current frame */ - s->frame_offset = s->next_frame_offset; - - /* offset of the next frame */ - s->next_frame_offset = s->cur_offset + index; - s->fetch_timestamp=1; - } - if (index < 0) - index = 0; - s->cur_offset += index; - return index; -} - -/** - * - * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed - * @deprecated use AVBitstreamFilter - */ -int av_parser_change(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - - if(s && s->parser->split){ - if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){ - int i= s->parser->split(avctx, buf, buf_size); - buf += i; - buf_size -= i; - } - } - - /* cast to avoid warning about discarding qualifiers */ - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - if(avctx->extradata){ - if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) - /*||(s->pict_type != FF_I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/ - /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ - int size= buf_size + avctx->extradata_size; - *poutbuf_size= size; - *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - - memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); - memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - return 1; - } - } - - return 0; -} - -void av_parser_close(AVCodecParserContext *s) -{ - if(s){ - if (s->parser->parser_close) - s->parser->parser_close(s); - av_free(s->priv_data); - av_free(s); - } -} - -/*****************************************************/ - -/** - * combines the (truncated) bitstream to a complete frame - * @return -1 if no complete frame could be created, AVERROR(ENOMEM) if there was a memory allocation error - */ -int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) -{ -#if 0 - if(pc->overread){ - printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); - printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); - } -#endif - - /* Copy overread bytes from last frame into buffer. */ - for(; pc->overread>0; pc->overread--){ - pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; - } - - /* flush remaining if EOF */ - if(!*buf_size && next == END_NOT_FOUND){ - next= 0; - } - - pc->last_index= pc->index; - - /* copy into buffer end return */ - if(next == END_NOT_FOUND){ - void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); - - if(!new_buffer) - return AVERROR(ENOMEM); - pc->buffer = new_buffer; - memcpy(&pc->buffer[pc->index], *buf, *buf_size); - pc->index += *buf_size; - return -1; - } - - *buf_size= - pc->overread_index= pc->index + next; - - /* append to buffer */ - if(pc->index){ - void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); - - if(!new_buffer) - return AVERROR(ENOMEM); - pc->buffer = new_buffer; - memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); - pc->index = 0; - *buf= pc->buffer; - } - - /* store overread bytes */ - for(;next < 0; next++){ - pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; - pc->state64 = (pc->state64<<8) | pc->buffer[pc->last_index + next]; - pc->overread++; - } - -#if 0 - if(pc->overread){ - printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); - printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); - } -#endif - - return 0; -} - -void ff_parse_close(AVCodecParserContext *s) -{ - ParseContext *pc = s->priv_data; - - av_freep(&pc->buffer); -} - -void ff_parse1_close(AVCodecParserContext *s) -{ - ParseContext1 *pc1 = s->priv_data; - - av_free(pc1->pc.buffer); - av_free(pc1->enc); -} - -/*************************/ - -int ff_mpeg4video_split(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - int i; - uint32_t state= -1; - - for(i=0; i> 4; - - if (avctx->debug & FF_DEBUG_PICT_INFO) - dprintf(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n", - header[0], header[1], header[2], header[3]); - - /* get the sample depth and derive the sample format from it */ - avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6]; - if (!avctx->bits_per_coded_sample) { - av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (0)\n"); - return -1; - } - avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? SAMPLE_FMT_S16 : - SAMPLE_FMT_S32; - - /* get the sample rate. Not all values are known or exist. */ - switch (header[2] & 0x0f) { - case 1: - avctx->sample_rate = 48000; - break; - case 4: - avctx->sample_rate = 96000; - break; - case 5: - avctx->sample_rate = 192000; - break; - default: - avctx->sample_rate = 0; - av_log(avctx, AV_LOG_ERROR, "unsupported sample rate (%d)\n", - header[2] & 0x0f); - return -1; - } - - /* - * get the channel number (and mapping). Not all values are known or exist. - * It must be noted that the number of channels in the MPEG stream can - * differ from the actual meaningful number, e.g. mono audio still has two - * channels, one being empty. - */ - avctx->channel_layout = channel_layouts[channel_layout]; - avctx->channels = channels[channel_layout]; - if (!avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "unsupported channel configuration (%d)\n", - channel_layout); - return -1; - } - - avctx->bit_rate = avctx->channels * avctx->sample_rate * - avctx->bits_per_coded_sample; - - if (avctx->debug & FF_DEBUG_PICT_INFO) - dprintf(avctx, - "pcm_bluray_parse_header: %d channels, %d bits per sample, %d kHz, %d kbit\n", - avctx->channels, avctx->bits_per_coded_sample, - avctx->sample_rate, avctx->bit_rate); - return 0; -} - -static int pcm_bluray_decode_frame(AVCodecContext *avctx, - void *data, - int *data_size, - AVPacket *avpkt) -{ - const uint8_t *src = avpkt->data; - int buf_size = avpkt->size; - int num_source_channels, channel, retval; - int sample_size, samples, output_size; - int16_t *dst16 = data; - int32_t *dst32 = data; - - if (buf_size < 4) { - av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n"); - return -1; - } - - if (pcm_bluray_parse_header(avctx, src)) - return -1; - src += 4; - buf_size -= 4; - - /* There's always an even number of channels in the source */ - num_source_channels = FFALIGN(avctx->channels, 2); - sample_size = (num_source_channels * avctx->bits_per_coded_sample) >> 3; - samples = buf_size / sample_size; - - output_size = samples * avctx->channels * - (avctx->sample_fmt == SAMPLE_FMT_S32 ? 4 : 2); - if (output_size > *data_size) { - av_log(avctx, AV_LOG_ERROR, - "Insufficient output buffer space (%d bytes, needed %d bytes)\n", - *data_size, output_size); - return -1; - } - *data_size = output_size; - - if (samples) { - switch (avctx->channel_layout) { - /* cases with same number of source and coded channels */ - case CH_LAYOUT_STEREO: - case CH_LAYOUT_4POINT0: - case CH_LAYOUT_2_2: - samples *= num_source_channels; - if (SAMPLE_FMT_S16 == avctx->sample_fmt) { -#if HAVE_BIGENDIAN - memcpy(dst16, src, output_size); -#else - do { - *dst16++ = bytestream_get_be16(&src); - } while (--samples); -#endif - } else { - do { - *dst32++ = bytestream_get_be24(&src) << 8; - } while (--samples); - } - break; - /* cases where number of source channels = coded channels + 1 */ - case CH_LAYOUT_MONO: - case CH_LAYOUT_SURROUND: - case CH_LAYOUT_2_1: - case CH_LAYOUT_5POINT0: - if (SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { -#if HAVE_BIGENDIAN - memcpy(dst16, src, avctx->channels * 2); - dst16 += avctx->channels; - src += sample_size; -#else - channel = avctx->channels; - do { - *dst16++ = bytestream_get_be16(&src); - } while (--channel); - src += 2; -#endif - } while (--samples); - } else { - do { - channel = avctx->channels; - do { - *dst32++ = bytestream_get_be24(&src) << 8; - } while (--channel); - src += 3; - } while (--samples); - } - break; - /* remapping: L, R, C, LBack, RBack, LF */ - case CH_LAYOUT_5POINT1: - if (SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { - dst16[0] = bytestream_get_be16(&src); - dst16[1] = bytestream_get_be16(&src); - dst16[2] = bytestream_get_be16(&src); - dst16[4] = bytestream_get_be16(&src); - dst16[5] = bytestream_get_be16(&src); - dst16[3] = bytestream_get_be16(&src); - dst16 += 6; - } while (--samples); - } else { - do { - dst32[0] = bytestream_get_be24(&src) << 8; - dst32[1] = bytestream_get_be24(&src) << 8; - dst32[2] = bytestream_get_be24(&src) << 8; - dst32[4] = bytestream_get_be24(&src) << 8; - dst32[5] = bytestream_get_be24(&src) << 8; - dst32[3] = bytestream_get_be24(&src) << 8; - dst32 += 6; - } while (--samples); - } - break; - /* remapping: L, R, C, LSide, LBack, RBack, RSide, */ - case CH_LAYOUT_7POINT0: - if (SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { - dst16[0] = bytestream_get_be16(&src); - dst16[1] = bytestream_get_be16(&src); - dst16[2] = bytestream_get_be16(&src); - dst16[5] = bytestream_get_be16(&src); - dst16[3] = bytestream_get_be16(&src); - dst16[4] = bytestream_get_be16(&src); - dst16[6] = bytestream_get_be16(&src); - dst16 += 7; - src += 2; - } while (--samples); - } else { - do { - dst32[0] = bytestream_get_be24(&src) << 8; - dst32[1] = bytestream_get_be24(&src) << 8; - dst32[2] = bytestream_get_be24(&src) << 8; - dst32[5] = bytestream_get_be24(&src) << 8; - dst32[3] = bytestream_get_be24(&src) << 8; - dst32[4] = bytestream_get_be24(&src) << 8; - dst32[6] = bytestream_get_be24(&src) << 8; - dst32 += 7; - src += 3; - } while (--samples); - } - break; - /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */ - case CH_LAYOUT_7POINT1: - if (SAMPLE_FMT_S16 == avctx->sample_fmt) { - do { - dst16[0] = bytestream_get_be16(&src); - dst16[1] = bytestream_get_be16(&src); - dst16[2] = bytestream_get_be16(&src); - dst16[6] = bytestream_get_be16(&src); - dst16[4] = bytestream_get_be16(&src); - dst16[5] = bytestream_get_be16(&src); - dst16[7] = bytestream_get_be16(&src); - dst16[3] = bytestream_get_be16(&src); - dst16 += 8; - } while (--samples); - } else { - do { - dst32[0] = bytestream_get_be24(&src) << 8; - dst32[1] = bytestream_get_be24(&src) << 8; - dst32[2] = bytestream_get_be24(&src) << 8; - dst32[6] = bytestream_get_be24(&src) << 8; - dst32[4] = bytestream_get_be24(&src) << 8; - dst32[5] = bytestream_get_be24(&src) << 8; - dst32[7] = bytestream_get_be24(&src) << 8; - dst32[3] = bytestream_get_be24(&src) << 8; - dst32 += 8; - } while (--samples); - } - break; - } - } - - retval = src - avpkt->data; - if (avctx->debug & FF_DEBUG_BITSTREAM) - dprintf(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n", - retval, *data_size); - return retval; -} - -AVCodec pcm_bluray_decoder = { - "pcm_bluray", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_PCM_BLURAY, - 0, - NULL, - NULL, - NULL, - pcm_bluray_decode_frame, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16, SAMPLE_FMT_S32, - SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/pcm.c b/tizen/distrib/ffmpeg/libavcodec/pcm.c deleted file mode 100644 index 746a520..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pcm.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * PCM codecs - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * PCM codecs - */ - -#include "avcodec.h" -#include "libavutil/common.h" /* for av_reverse */ -#include "bytestream.h" -#include "pcm_tablegen.h" - -#define MAX_CHANNELS 64 - -static av_cold int pcm_encode_init(AVCodecContext *avctx) -{ - avctx->frame_size = 1; - switch(avctx->codec->id) { - case CODEC_ID_PCM_ALAW: - pcm_alaw_tableinit(); - break; - case CODEC_ID_PCM_MULAW: - pcm_ulaw_tableinit(); - break; - default: - break; - } - - avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); - avctx->block_align = avctx->channels * avctx->bits_per_coded_sample/8; - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; -} - -static av_cold int pcm_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - - return 0; -} - -/** - * Write PCM samples macro - * @param type Datatype of native machine format - * @param endian bytestream_put_xxx() suffix - * @param src Source pointer (variable name) - * @param dst Destination pointer (variable name) - * @param n Total number of samples (variable name) - * @param shift Bitshift (bits) - * @param offset Sample value offset - */ -#define ENCODE(type, endian, src, dst, n, shift, offset) \ - samples_##type = (type*)src; \ - for(;n>0;n--) { \ - register type v = (*samples_##type++ >> shift) + offset; \ - bytestream_put_##endian(&dst, v); \ - } - -static int pcm_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) -{ - int n, sample_size, v; - short *samples; - unsigned char *dst; - uint8_t *srcu8; - int16_t *samples_int16_t; - int32_t *samples_int32_t; - int64_t *samples_int64_t; - uint16_t *samples_uint16_t; - uint32_t *samples_uint32_t; - - sample_size = av_get_bits_per_sample(avctx->codec->id)/8; - n = buf_size / sample_size; - samples = data; - dst = frame; - - if (avctx->sample_fmt!=avctx->codec->sample_fmts[0]) { - av_log(avctx, AV_LOG_ERROR, "invalid sample_fmt\n"); - return -1; - } - - switch(avctx->codec->id) { - case CODEC_ID_PCM_U32LE: - ENCODE(uint32_t, le32, samples, dst, n, 0, 0x80000000) - break; - case CODEC_ID_PCM_U32BE: - ENCODE(uint32_t, be32, samples, dst, n, 0, 0x80000000) - break; - case CODEC_ID_PCM_S24LE: - ENCODE(int32_t, le24, samples, dst, n, 8, 0) - break; - case CODEC_ID_PCM_S24BE: - ENCODE(int32_t, be24, samples, dst, n, 8, 0) - break; - case CODEC_ID_PCM_U24LE: - ENCODE(uint32_t, le24, samples, dst, n, 8, 0x800000) - break; - case CODEC_ID_PCM_U24BE: - ENCODE(uint32_t, be24, samples, dst, n, 8, 0x800000) - break; - case CODEC_ID_PCM_S24DAUD: - for(;n>0;n--) { - uint32_t tmp = av_reverse[(*samples >> 8) & 0xff] + - (av_reverse[*samples & 0xff] << 8); - tmp <<= 4; // sync flags would go here - bytestream_put_be24(&dst, tmp); - samples++; - } - break; - case CODEC_ID_PCM_U16LE: - ENCODE(uint16_t, le16, samples, dst, n, 0, 0x8000) - break; - case CODEC_ID_PCM_U16BE: - ENCODE(uint16_t, be16, samples, dst, n, 0, 0x8000) - break; - case CODEC_ID_PCM_S8: - srcu8= data; - for(;n>0;n--) { - v = *srcu8++; - *dst++ = v - 128; - } - break; -#if HAVE_BIGENDIAN - case CODEC_ID_PCM_F64LE: - ENCODE(int64_t, le64, samples, dst, n, 0, 0) - break; - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_F32LE: - ENCODE(int32_t, le32, samples, dst, n, 0, 0) - break; - case CODEC_ID_PCM_S16LE: - ENCODE(int16_t, le16, samples, dst, n, 0, 0) - break; - case CODEC_ID_PCM_F64BE: - case CODEC_ID_PCM_F32BE: - case CODEC_ID_PCM_S32BE: - case CODEC_ID_PCM_S16BE: -#else - case CODEC_ID_PCM_F64BE: - ENCODE(int64_t, be64, samples, dst, n, 0, 0) - break; - case CODEC_ID_PCM_F32BE: - case CODEC_ID_PCM_S32BE: - ENCODE(int32_t, be32, samples, dst, n, 0, 0) - break; - case CODEC_ID_PCM_S16BE: - ENCODE(int16_t, be16, samples, dst, n, 0, 0) - break; - case CODEC_ID_PCM_F64LE: - case CODEC_ID_PCM_F32LE: - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_S16LE: -#endif /* HAVE_BIGENDIAN */ - case CODEC_ID_PCM_U8: - memcpy(dst, samples, n*sample_size); - dst += n*sample_size; - break; - case CODEC_ID_PCM_ZORK: - for(;n>0;n--) { - v= *samples++ >> 8; - if(v<0) v = -v; - else v+= 128; - *dst++ = v; - } - break; - case CODEC_ID_PCM_ALAW: - for(;n>0;n--) { - v = *samples++; - *dst++ = linear_to_alaw[(v + 32768) >> 2]; - } - break; - case CODEC_ID_PCM_MULAW: - for(;n>0;n--) { - v = *samples++; - *dst++ = linear_to_ulaw[(v + 32768) >> 2]; - } - break; - default: - return -1; - } - //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels); - - return dst - frame; -} - -typedef struct PCMDecode { - short table[256]; -} PCMDecode; - -static av_cold int pcm_decode_init(AVCodecContext * avctx) -{ - PCMDecode *s = avctx->priv_data; - int i; - - switch(avctx->codec->id) { - case CODEC_ID_PCM_ALAW: - for(i=0;i<256;i++) - s->table[i] = alaw2linear(i); - break; - case CODEC_ID_PCM_MULAW: - for(i=0;i<256;i++) - s->table[i] = ulaw2linear(i); - break; - default: - break; - } - - avctx->sample_fmt = avctx->codec->sample_fmts[0]; - return 0; -} - -/** - * Read PCM samples macro - * @param type Datatype of native machine format - * @param endian bytestream_get_xxx() endian suffix - * @param src Source pointer (variable name) - * @param dst Destination pointer (variable name) - * @param n Total number of samples (variable name) - * @param shift Bitshift (bits) - * @param offset Sample value offset - */ -#define DECODE(type, endian, src, dst, n, shift, offset) \ - dst_##type = (type*)dst; \ - for(;n>0;n--) { \ - register type v = bytestream_get_##endian(&src); \ - *dst_##type++ = (v - offset) << shift; \ - } \ - dst = (short*)dst_##type; - -static int pcm_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - PCMDecode *s = avctx->priv_data; - int sample_size, c, n; - short *samples; - const uint8_t *src, *src8, *src2[MAX_CHANNELS]; - uint8_t *dstu8; - int16_t *dst_int16_t; - int32_t *dst_int32_t; - int64_t *dst_int64_t; - uint16_t *dst_uint16_t; - uint32_t *dst_uint32_t; - - samples = data; - src = buf; - - if (avctx->sample_fmt!=avctx->codec->sample_fmts[0]) { - av_log(avctx, AV_LOG_ERROR, "invalid sample_fmt\n"); - return -1; - } - - if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){ - av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); - return -1; - } - - sample_size = av_get_bits_per_sample(avctx->codec_id)/8; - - /* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */ - if (CODEC_ID_PCM_DVD == avctx->codec_id) - /* 2 samples are interleaved per block in PCM_DVD */ - sample_size = avctx->bits_per_coded_sample * 2 / 8; - - n = avctx->channels * sample_size; - - if(n && buf_size % n){ - if (buf_size < n) { - av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n"); - return -1; - }else - buf_size -= buf_size % n; - } - - buf_size= FFMIN(buf_size, *data_size/2); - *data_size=0; - - n = buf_size/sample_size; - - switch(avctx->codec->id) { - case CODEC_ID_PCM_U32LE: - DECODE(uint32_t, le32, src, samples, n, 0, 0x80000000) - break; - case CODEC_ID_PCM_U32BE: - DECODE(uint32_t, be32, src, samples, n, 0, 0x80000000) - break; - case CODEC_ID_PCM_S24LE: - DECODE(int32_t, le24, src, samples, n, 8, 0) - break; - case CODEC_ID_PCM_S24BE: - DECODE(int32_t, be24, src, samples, n, 8, 0) - break; - case CODEC_ID_PCM_U24LE: - DECODE(uint32_t, le24, src, samples, n, 8, 0x800000) - break; - case CODEC_ID_PCM_U24BE: - DECODE(uint32_t, be24, src, samples, n, 8, 0x800000) - break; - case CODEC_ID_PCM_S24DAUD: - for(;n>0;n--) { - uint32_t v = bytestream_get_be24(&src); - v >>= 4; // sync flags are here - *samples++ = av_reverse[(v >> 8) & 0xff] + - (av_reverse[v & 0xff] << 8); - } - break; - case CODEC_ID_PCM_S16LE_PLANAR: - n /= avctx->channels; - for(c=0;cchannels;c++) - src2[c] = &src[c*n*2]; - for(;n>0;n--) - for(c=0;cchannels;c++) - *samples++ = bytestream_get_le16(&src2[c]); - src = src2[avctx->channels-1]; - break; - case CODEC_ID_PCM_U16LE: - DECODE(uint16_t, le16, src, samples, n, 0, 0x8000) - break; - case CODEC_ID_PCM_U16BE: - DECODE(uint16_t, be16, src, samples, n, 0, 0x8000) - break; - case CODEC_ID_PCM_S8: - dstu8= (uint8_t*)samples; - for(;n>0;n--) { - *dstu8++ = *src++ + 128; - } - samples= (short*)dstu8; - break; -#if HAVE_BIGENDIAN - case CODEC_ID_PCM_F64LE: - DECODE(int64_t, le64, src, samples, n, 0, 0) - break; - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_F32LE: - DECODE(int32_t, le32, src, samples, n, 0, 0) - break; - case CODEC_ID_PCM_S16LE: - DECODE(int16_t, le16, src, samples, n, 0, 0) - break; - case CODEC_ID_PCM_F64BE: - case CODEC_ID_PCM_F32BE: - case CODEC_ID_PCM_S32BE: - case CODEC_ID_PCM_S16BE: -#else - case CODEC_ID_PCM_F64BE: - DECODE(int64_t, be64, src, samples, n, 0, 0) - break; - case CODEC_ID_PCM_F32BE: - case CODEC_ID_PCM_S32BE: - DECODE(int32_t, be32, src, samples, n, 0, 0) - break; - case CODEC_ID_PCM_S16BE: - DECODE(int16_t, be16, src, samples, n, 0, 0) - break; - case CODEC_ID_PCM_F64LE: - case CODEC_ID_PCM_F32LE: - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_S16LE: -#endif /* HAVE_BIGENDIAN */ - case CODEC_ID_PCM_U8: - memcpy(samples, src, n*sample_size); - src += n*sample_size; - samples = (short*)((uint8_t*)data + n*sample_size); - break; - case CODEC_ID_PCM_ZORK: - for(;n>0;n--) { - int x= *src++; - if(x&128) x-= 128; - else x = -x; - *samples++ = x << 8; - } - break; - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - for(;n>0;n--) { - *samples++ = s->table[*src++]; - } - break; - case CODEC_ID_PCM_DVD: - dst_int32_t = data; - n /= avctx->channels; - switch (avctx->bits_per_coded_sample) { - case 20: - while (n--) { - c = avctx->channels; - src8 = src + 4*c; - while (c--) { - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8 &0xf0) << 8); - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++ &0x0f) << 12); - } - src = src8; - } - break; - case 24: - while (n--) { - c = avctx->channels; - src8 = src + 4*c; - while (c--) { - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); - *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); - } - src = src8; - } - break; - default: - av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n"); - return -1; - break; - } - samples = (short *) dst_int32_t; - break; - default: - return -1; - } - *data_size = (uint8_t *)samples - (uint8_t *)data; - return src - buf; -} - -#if CONFIG_ENCODERS -#define PCM_ENCODER(id,sample_fmt_,name,long_name_) \ -AVCodec name ## _encoder = { \ - #name, \ - AVMEDIA_TYPE_AUDIO, \ - id, \ - 0, \ - pcm_encode_init, \ - pcm_encode_frame, \ - pcm_encode_close, \ - NULL, \ - .sample_fmts = (const enum SampleFormat[]){sample_fmt_,SAMPLE_FMT_NONE}, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ -}; -#else -#define PCM_ENCODER(id,sample_fmt_,name,long_name_) -#endif - -#if CONFIG_DECODERS -#define PCM_DECODER(id,sample_fmt_,name,long_name_) \ -AVCodec name ## _decoder = { \ - #name, \ - AVMEDIA_TYPE_AUDIO, \ - id, \ - sizeof(PCMDecode), \ - pcm_decode_init, \ - NULL, \ - NULL, \ - pcm_decode_frame, \ - .sample_fmts = (const enum SampleFormat[]){sample_fmt_,SAMPLE_FMT_NONE}, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ -}; -#else -#define PCM_DECODER(id,sample_fmt_,name,long_name_) -#endif - -#define PCM_CODEC(id, sample_fmt_, name, long_name_) \ - PCM_ENCODER(id,sample_fmt_,name,long_name_) PCM_DECODER(id,sample_fmt_,name,long_name_) - -/* Note: Do not forget to add new entries to the Makefile as well. */ -PCM_CODEC (CODEC_ID_PCM_ALAW, SAMPLE_FMT_S16, pcm_alaw, "PCM A-law"); -PCM_CODEC (CODEC_ID_PCM_DVD, SAMPLE_FMT_S32, pcm_dvd, "PCM signed 20|24-bit big-endian"); -PCM_CODEC (CODEC_ID_PCM_F32BE, SAMPLE_FMT_FLT, pcm_f32be, "PCM 32-bit floating point big-endian"); -PCM_CODEC (CODEC_ID_PCM_F32LE, SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian"); -PCM_CODEC (CODEC_ID_PCM_F64BE, SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian"); -PCM_CODEC (CODEC_ID_PCM_F64LE, SAMPLE_FMT_DBL, pcm_f64le, "PCM 64-bit floating point little-endian"); -PCM_CODEC (CODEC_ID_PCM_MULAW, SAMPLE_FMT_S16, pcm_mulaw, "PCM mu-law"); -PCM_CODEC (CODEC_ID_PCM_S8, SAMPLE_FMT_U8, pcm_s8, "PCM signed 8-bit"); -PCM_CODEC (CODEC_ID_PCM_S16BE, SAMPLE_FMT_S16, pcm_s16be, "PCM signed 16-bit big-endian"); -PCM_CODEC (CODEC_ID_PCM_S16LE, SAMPLE_FMT_S16, pcm_s16le, "PCM signed 16-bit little-endian"); -PCM_DECODER(CODEC_ID_PCM_S16LE_PLANAR, SAMPLE_FMT_S16, pcm_s16le_planar, "PCM 16-bit little-endian planar"); -PCM_CODEC (CODEC_ID_PCM_S24BE, SAMPLE_FMT_S32, pcm_s24be, "PCM signed 24-bit big-endian"); -PCM_CODEC (CODEC_ID_PCM_S24DAUD, SAMPLE_FMT_S16, pcm_s24daud, "PCM D-Cinema audio signed 24-bit"); -PCM_CODEC (CODEC_ID_PCM_S24LE, SAMPLE_FMT_S32, pcm_s24le, "PCM signed 24-bit little-endian"); -PCM_CODEC (CODEC_ID_PCM_S32BE, SAMPLE_FMT_S32, pcm_s32be, "PCM signed 32-bit big-endian"); -PCM_CODEC (CODEC_ID_PCM_S32LE, SAMPLE_FMT_S32, pcm_s32le, "PCM signed 32-bit little-endian"); -PCM_CODEC (CODEC_ID_PCM_U8, SAMPLE_FMT_U8, pcm_u8, "PCM unsigned 8-bit"); -PCM_CODEC (CODEC_ID_PCM_U16BE, SAMPLE_FMT_S16, pcm_u16be, "PCM unsigned 16-bit big-endian"); -PCM_CODEC (CODEC_ID_PCM_U16LE, SAMPLE_FMT_S16, pcm_u16le, "PCM unsigned 16-bit little-endian"); -PCM_CODEC (CODEC_ID_PCM_U24BE, SAMPLE_FMT_S32, pcm_u24be, "PCM unsigned 24-bit big-endian"); -PCM_CODEC (CODEC_ID_PCM_U24LE, SAMPLE_FMT_S32, pcm_u24le, "PCM unsigned 24-bit little-endian"); -PCM_CODEC (CODEC_ID_PCM_U32BE, SAMPLE_FMT_S32, pcm_u32be, "PCM unsigned 32-bit big-endian"); -PCM_CODEC (CODEC_ID_PCM_U32LE, SAMPLE_FMT_S32, pcm_u32le, "PCM unsigned 32-bit little-endian"); -PCM_CODEC (CODEC_ID_PCM_ZORK, SAMPLE_FMT_S16, pcm_zork, "PCM Zork"); diff --git a/tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.c b/tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.c deleted file mode 100644 index 57ecb43..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Generate a header file for hardcoded PCM tables - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#define CONFIG_HARDCODED_TABLES 0 -#include "pcm_tablegen.h" -#include "tableprint.h" - -int main(void) -{ - pcm_alaw_tableinit(); - pcm_ulaw_tableinit(); - - write_fileheader(); - - printf("static const uint8_t linear_to_alaw[1 << 14] = {\n"); - write_uint8_array(linear_to_alaw, 1 << 14); - printf("};\n"); - - printf("static const uint8_t linear_to_ulaw[1 << 14] = {\n"); - write_uint8_array(linear_to_ulaw, 1 << 14); - printf("};\n"); - - return 0; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.h b/tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.h deleted file mode 100644 index 8921baa..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pcm_tablegen.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Header file for hardcoded PCM tables - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef PCM_TABLEGEN_H -#define PCM_TABLEGEN_H - -#include -#include "../libavutil/attributes.h" - -/* from g711.c by SUN microsystems (unrestricted use) */ - -#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ -#define QUANT_MASK (0xf) /* Quantization field mask. */ -#define NSEGS (8) /* Number of A-law segments. */ -#define SEG_SHIFT (4) /* Left shift for segment number. */ -#define SEG_MASK (0x70) /* Segment field mask. */ - -#define BIAS (0x84) /* Bias for linear code. */ - -/* - * alaw2linear() - Convert an A-law value to 16-bit linear PCM - * - */ -static av_cold int alaw2linear(unsigned char a_val) -{ - int t; - int seg; - - a_val ^= 0x55; - - t = a_val & QUANT_MASK; - seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; - if(seg) t= (t + t + 1 + 32) << (seg + 2); - else t= (t + t + 1 ) << 3; - - return (a_val & SIGN_BIT) ? t : -t; -} - -static av_cold int ulaw2linear(unsigned char u_val) -{ - int t; - - /* Complement to obtain normal u-law value. */ - u_val = ~u_val; - - /* - * Extract and bias the quantization bits. Then - * shift up by the segment number and subtract out the bias. - */ - t = ((u_val & QUANT_MASK) << 3) + BIAS; - t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; - - return (u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS); -} - -#if CONFIG_HARDCODED_TABLES -#define pcm_alaw_tableinit() -#define pcm_ulaw_tableinit() -#include "libavcodec/pcm_tables.h" -#else -/* 16384 entries per table */ -static uint8_t linear_to_alaw[16384]; -static uint8_t linear_to_ulaw[16384]; - -static av_cold void build_xlaw_table(uint8_t *linear_to_xlaw, - int (*xlaw2linear)(unsigned char), - int mask) -{ - int i, j, v, v1, v2; - - j = 0; - for(i=0;i<128;i++) { - if (i != 127) { - v1 = xlaw2linear(i ^ mask); - v2 = xlaw2linear((i + 1) ^ mask); - v = (v1 + v2 + 4) >> 3; - } else { - v = 8192; - } - for(;j 0) - linear_to_xlaw[8192 - j] = (i ^ (mask ^ 0x80)); - } - } - linear_to_xlaw[0] = linear_to_xlaw[1]; -} - -static void pcm_alaw_tableinit(void) -{ - build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5); -} - -static void pcm_ulaw_tableinit(void) -{ - build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff); -} -#endif /* CONFIG_HARDCODED_TABLES */ - -#endif /* PCM_TABLEGEN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/pcx.c b/tizen/distrib/ffmpeg/libavcodec/pcx.c deleted file mode 100644 index 2174184..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pcx.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * PC Paintbrush PCX (.pcx) image decoder - * Copyright (c) 2007, 2008 Ivo van Poorten - * - * This decoder does not support CGA palettes. I am unable to find samples - * and Netpbm cannot generate them. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "get_bits.h" - -typedef struct PCXContext { - AVFrame picture; -} PCXContext; - -static av_cold int pcx_init(AVCodecContext *avctx) { - PCXContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - - return 0; -} - -/** - * @return advanced src pointer - */ -static const uint8_t *pcx_rle_decode(const uint8_t *src, uint8_t *dst, - unsigned int bytes_per_scanline, int compressed) { - unsigned int i = 0; - unsigned char run, value; - - if (compressed) { - while (i= 0xc0) { - run = value & 0x3f; - value = *src++; - } - while (idata; - int buf_size = avpkt->size; - PCXContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; - int compressed, xmin, ymin, xmax, ymax; - unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, - bytes_per_scanline; - uint8_t *ptr; - uint8_t const *bufstart = buf; - - if (buf[0] != 0x0a || buf[1] > 5) { - av_log(avctx, AV_LOG_ERROR, "this is not PCX encoded data\n"); - return -1; - } - - compressed = buf[2]; - xmin = AV_RL16(buf+ 4); - ymin = AV_RL16(buf+ 6); - xmax = AV_RL16(buf+ 8); - ymax = AV_RL16(buf+10); - - if (xmax < xmin || ymax < ymin) { - av_log(avctx, AV_LOG_ERROR, "invalid image dimensions\n"); - return -1; - } - - w = xmax - xmin + 1; - h = ymax - ymin + 1; - - bits_per_pixel = buf[3]; - bytes_per_line = AV_RL16(buf+66); - nplanes = buf[65]; - bytes_per_scanline = nplanes * bytes_per_line; - - if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8) { - av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); - return -1; - } - - switch ((nplanes<<8) + bits_per_pixel) { - case 0x0308: - avctx->pix_fmt = PIX_FMT_RGB24; - break; - case 0x0108: - case 0x0104: - case 0x0102: - case 0x0101: - case 0x0401: - case 0x0301: - case 0x0201: - avctx->pix_fmt = PIX_FMT_PAL8; - break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n"); - return -1; - } - - buf += 128; - - if (p->data[0]) - avctx->release_buffer(avctx, p); - - if (avcodec_check_dimensions(avctx, w, h)) - return -1; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - 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; - - ptr = p->data[0]; - stride = p->linesize[0]; - - if (nplanes == 3 && bits_per_pixel == 8) { - uint8_t scanline[bytes_per_scanline]; - - for (y=0; y> (x&7), v = 0; - for (i=nplanes - 1; i>=0; i--) { - v <<= 1; - v += !!(scanline[i*bytes_per_line + (x>>3)] & m); - } - ptr[x] = v; - } - ptr += stride; - } - } - - if (nplanes == 1 && bits_per_pixel == 8) { - pcx_palette(&buf, (uint32_t *) p->data[1], 256); - } else if (bits_per_pixel < 8) { - const uint8_t *palette = bufstart+16; - pcx_palette(&palette, (uint32_t *) p->data[1], 16); - } - - *picture = s->picture; - *data_size = sizeof(AVFrame); - - return buf - bufstart; -} - -static av_cold int pcx_end(AVCodecContext *avctx) { - PCXContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec pcx_decoder = { - "pcx", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PCX, - sizeof(PCXContext), - pcx_init, - NULL, - pcx_end, - pcx_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/pcxenc.c b/tizen/distrib/ffmpeg/libavcodec/pcxenc.c deleted file mode 100644 index a3ce284..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pcxenc.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * PC Paintbrush PCX (.pcx) image encoder - * Copyright (c) 2009 Daniel Verkamp - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * PCX image encoder - * @file - * @author Daniel Verkamp - * @sa http://www.qzx.com/pc-gpe/pcx.txt - */ - -#include "avcodec.h" -#include "bytestream.h" - -typedef struct PCXContext { - AVFrame picture; -} PCXContext; - -static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF }; - -static av_cold int pcx_encode_init(AVCodecContext *avctx) -{ - PCXContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - -/** - * PCX run-length encoder - * @param dst output buffer - * @param dst_size size of output buffer - * @param src input buffer - * @param src_plane_size size of one plane of input buffer in bytes - * @param nplanes number of planes in input buffer - * @return number of bytes written to dst or -1 on error - * @bug will not work for nplanes != 1 && bpp != 8 - */ -static int pcx_rle_encode( uint8_t *dst, int dst_size, - const uint8_t *src, int src_plane_size, int nplanes) -{ - int p; - const uint8_t *dst_start = dst; - - // check worst-case upper bound on dst_size - if (dst_size < 2LL * src_plane_size * nplanes || src_plane_size <= 0) - return -1; - - for (p = 0; p < nplanes; p++) { - int count = 1; - const uint8_t *src_plane = src + p; - const uint8_t *src_plane_end = src_plane + src_plane_size * nplanes; - uint8_t prev = *src_plane; - src_plane += nplanes; - - for (; ; src_plane += nplanes) { - if (src_plane < src_plane_end && *src_plane == prev && count < 0x3F) { - // current byte is same as prev - ++count; - } else { - // output prev * count - if (count != 1 || prev >= 0xC0) - *dst++ = 0xC0 | count; - *dst++ = prev; - - if (src_plane == src_plane_end) - break; - - // start new run - count = 1; - prev = *src_plane; - } - } - } - - return dst - dst_start; -} - -static int pcx_encode_frame(AVCodecContext *avctx, - unsigned char *buf, int buf_size, void *data) -{ - PCXContext *s = avctx->priv_data; - AVFrame *const pict = &s->picture; - const uint8_t *buf_start = buf; - const uint8_t *buf_end = buf + buf_size; - - int bpp, nplanes, i, y, line_bytes, written; - const uint32_t *pal = NULL; - const uint8_t *src; - - *pict = *(AVFrame *)data; - pict->pict_type = FF_I_TYPE; - pict->key_frame = 1; - - if (avctx->width > 65535 || avctx->height > 65535) { - av_log(avctx, AV_LOG_ERROR, "image dimensions do not fit in 16 bits\n"); - return -1; - } - - switch (avctx->pix_fmt) { - case PIX_FMT_RGB24: - bpp = 8; - nplanes = 3; - break; - case PIX_FMT_RGB8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB4_BYTE: - case PIX_FMT_BGR4_BYTE: - case PIX_FMT_GRAY8: - case PIX_FMT_PAL8: - bpp = 8; - nplanes = 1; - pal = (uint32_t *)pict->data[1]; - break; - case PIX_FMT_MONOBLACK: - bpp = 1; - nplanes = 1; - pal = monoblack_pal; - break; - default: - av_log(avctx, AV_LOG_ERROR, "unsupported pixfmt\n"); - return -1; - } - - line_bytes = (avctx->width * bpp + 7) >> 3; - line_bytes = (line_bytes + 1) & ~1; - - bytestream_put_byte(&buf, 10); // manufacturer - bytestream_put_byte(&buf, 5); // version - bytestream_put_byte(&buf, 1); // encoding - bytestream_put_byte(&buf, bpp); // bits per pixel per plane - bytestream_put_le16(&buf, 0); // x min - bytestream_put_le16(&buf, 0); // y min - bytestream_put_le16(&buf, avctx->width - 1); // x max - bytestream_put_le16(&buf, avctx->height - 1); // y max - bytestream_put_le16(&buf, 0); // horizontal DPI - bytestream_put_le16(&buf, 0); // vertical DPI - for (i = 0; i < 16; i++) - bytestream_put_be24(&buf, pal ? pal[i] : 0);// palette (<= 16 color only) - bytestream_put_byte(&buf, 0); // reserved - bytestream_put_byte(&buf, nplanes); // number of planes - bytestream_put_le16(&buf, line_bytes); // scanline plane size in bytes - - while (buf - buf_start < 128) - *buf++= 0; - - src = pict->data[0]; - - for (y = 0; y < avctx->height; y++) { - if ((written = pcx_rle_encode(buf, buf_end - buf, - src, line_bytes, nplanes)) < 0) { - av_log(avctx, AV_LOG_ERROR, "buffer too small\n"); - return -1; - } - buf += written; - src += pict->linesize[0]; - } - - if (nplanes == 1 && bpp == 8) { - if (buf_end - buf < 257) { - av_log(avctx, AV_LOG_ERROR, "buffer too small\n"); - return -1; - } - bytestream_put_byte(&buf, 12); - for (i = 0; i < 256; i++) { - bytestream_put_be24(&buf, pal[i]); - } - } - - return buf - buf_start; -} - -AVCodec pcx_encoder = { - "pcx", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PCX, - sizeof(PCXContext), - pcx_encode_init, - pcx_encode_frame, - NULL, - .pix_fmts = (const enum PixelFormat[]){ - PIX_FMT_RGB24, - PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8, - PIX_FMT_MONOBLACK, - PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/pgssubdec.c b/tizen/distrib/ffmpeg/libavcodec/pgssubdec.c deleted file mode 100644 index 5512006..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pgssubdec.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * PGS subtitle decoder - * Copyright (c) 2009 Stephen Backway - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * PGS subtitle decoder - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "colorspace.h" -#include "bytestream.h" - -//#define DEBUG_PACKET_CONTENTS - -#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) - -enum SegmentType { - PALETTE_SEGMENT = 0x14, - PICTURE_SEGMENT = 0x15, - PRESENTATION_SEGMENT = 0x16, - WINDOW_SEGMENT = 0x17, - DISPLAY_SEGMENT = 0x80, -}; - -typedef struct PGSSubPresentation { - int x; - int y; - int video_w; - int video_h; - int id_number; -} PGSSubPresentation; - -typedef struct PGSSubPicture { - int w; - int h; - uint8_t *rle; - unsigned int rle_buffer_size, rle_data_len; -} PGSSubPicture; - -typedef struct PGSSubContext { - PGSSubPresentation presentation; - uint32_t clut[256]; - PGSSubPicture picture; -} PGSSubContext; - -static av_cold int init_decoder(AVCodecContext *avctx) -{ - avctx->pix_fmt = PIX_FMT_RGB32; - - return 0; -} - -static av_cold int close_decoder(AVCodecContext *avctx) -{ - PGSSubContext *ctx = avctx->priv_data; - - av_freep(&ctx->picture.rle); - ctx->picture.rle_buffer_size = 0; - - return 0; -} - -/** - * Decodes the RLE data. - * - * The subtitle is stored as an Run Length Encoded image. - * - * @param avctx contains the current codec context - * @param sub pointer to the processed subtitle data - * @param buf pointer to the RLE data to process - * @param buf_size size of the RLE data to process - */ -static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub, - const uint8_t *buf, unsigned int buf_size) -{ - const uint8_t *rle_bitmap_end; - int pixel_count, line_count; - - rle_bitmap_end = buf + buf_size; - - sub->rects[0]->pict.data[0] = av_malloc(sub->rects[0]->w * sub->rects[0]->h); - - if (!sub->rects[0]->pict.data[0]) - return -1; - - pixel_count = 0; - line_count = 0; - - while (buf < rle_bitmap_end && line_count < sub->rects[0]->h) { - uint8_t flags, color; - int run; - - color = bytestream_get_byte(&buf); - run = 1; - - if (color == 0x00) { - flags = bytestream_get_byte(&buf); - run = flags & 0x3f; - if (flags & 0x40) - run = (run << 8) + bytestream_get_byte(&buf); - color = flags & 0x80 ? bytestream_get_byte(&buf) : 0; - } - - if (run > 0 && pixel_count + run <= sub->rects[0]->w * sub->rects[0]->h) { - memset(sub->rects[0]->pict.data[0] + pixel_count, color, run); - pixel_count += run; - } else if (!run) { - /* - * New Line. Check if correct pixels decoded, if not display warning - * and adjust bitmap pointer to correct new line position. - */ - if (pixel_count % sub->rects[0]->w > 0) - av_log(avctx, AV_LOG_ERROR, "Decoded %d pixels, when line should be %d pixels\n", - pixel_count % sub->rects[0]->w, sub->rects[0]->w); - line_count++; - } - } - - dprintf(avctx, "Pixel Count = %d, Area = %d\n", pixel_count, sub->rects[0]->w * sub->rects[0]->h); - - return 0; -} - -/** - * Parses the picture segment packet. - * - * The picture segment contains details on the sequence id, - * width, height and Run Length Encoded (RLE) bitmap data. - * - * @param avctx contains the current codec context - * @param buf pointer to the packet to process - * @param buf_size size of packet to process - * @todo TODO: Enable support for RLE data over multiple packets - */ -static int parse_picture_segment(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - PGSSubContext *ctx = avctx->priv_data; - - uint8_t sequence_desc; - unsigned int rle_bitmap_len, width, height; - - /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */ - buf += 3; - - /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */ - sequence_desc = bytestream_get_byte(&buf); - - if (!(sequence_desc & 0x80)) { - av_log(avctx, AV_LOG_ERROR, "Decoder does not support object data over multiple packets.\n"); - return -1; - } - - /* Decode rle bitmap length */ - rle_bitmap_len = bytestream_get_be24(&buf); - - /* Check to ensure we have enough data for rle_bitmap_length if just a single packet */ - if (rle_bitmap_len > buf_size - 7) { - av_log(avctx, AV_LOG_ERROR, "Not enough RLE data for specified length of %d.\n", rle_bitmap_len); - return -1; - } - - ctx->picture.rle_data_len = rle_bitmap_len; - - /* Get bitmap dimensions from data */ - width = bytestream_get_be16(&buf); - height = bytestream_get_be16(&buf); - - /* Make sure the bitmap is not too large */ - if (ctx->presentation.video_w < width || ctx->presentation.video_h < height) { - av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger then video.\n"); - return -1; - } - - ctx->picture.w = width; - ctx->picture.h = height; - - av_fast_malloc(&ctx->picture.rle, &ctx->picture.rle_buffer_size, rle_bitmap_len); - - if (!ctx->picture.rle) - return -1; - - memcpy(ctx->picture.rle, buf, rle_bitmap_len); - - return 0; -} - -/** - * Parses the palette segment packet. - * - * The palette segment contains details of the palette, - * a maximum of 256 colors can be defined. - * - * @param avctx contains the current codec context - * @param buf pointer to the packet to process - * @param buf_size size of packet to process - */ -static void parse_palette_segment(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - PGSSubContext *ctx = avctx->priv_data; - - const uint8_t *buf_end = buf + buf_size; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int color_id; - int y, cb, cr, alpha; - int r, g, b, r_add, g_add, b_add; - - /* Skip two null bytes */ - buf += 2; - - while (buf < buf_end) { - color_id = bytestream_get_byte(&buf); - y = bytestream_get_byte(&buf); - cb = bytestream_get_byte(&buf); - cr = bytestream_get_byte(&buf); - alpha = bytestream_get_byte(&buf); - - YUV_TO_RGB1(cb, cr); - YUV_TO_RGB2(r, g, b, y); - - dprintf(avctx, "Color %d := (%d,%d,%d,%d)\n", color_id, r, g, b, alpha); - - /* Store color in palette */ - ctx->clut[color_id] = RGBA(r,g,b,alpha); - } -} - -/** - * Parses the presentation segment packet. - * - * The presentation segment contains details on the video - * width, video height, x & y subtitle position. - * - * @param avctx contains the current codec context - * @param buf pointer to the packet to process - * @param buf_size size of packet to process - * @todo TODO: Implement cropping - * @todo TODO: Implement forcing of subtitles - * @todo TODO: Blanking of subtitle - */ -static void parse_presentation_segment(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - PGSSubContext *ctx = avctx->priv_data; - - int x, y; - uint8_t block; - - ctx->presentation.video_w = bytestream_get_be16(&buf); - ctx->presentation.video_h = bytestream_get_be16(&buf); - - dprintf(avctx, "Video Dimensions %dx%d\n", - ctx->presentation.video_w, ctx->presentation.video_h); - - /* Skip 1 bytes of unknown, frame rate? */ - buf++; - - ctx->presentation.id_number = bytestream_get_be16(&buf); - - /* Next byte is the state. */ - block = bytestream_get_byte(&buf);; - if (block == 0x80) { - /* - * Skip 7 bytes of unknown: - * palette_update_flag (0x80), - * palette_id_to_use, - * Object Number (if > 0 determines if more data to process), - * object_id_ref (2 bytes), - * window_id_ref, - * composition_flag (0x80 - object cropped, 0x40 - object forced) - */ - buf += 7; - - x = bytestream_get_be16(&buf); - y = bytestream_get_be16(&buf); - - /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/ - - dprintf(avctx, "Subtitle Placement x=%d, y=%d\n", x, y); - - if (x > ctx->presentation.video_w || y > ctx->presentation.video_h) { - av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n", - x, y, ctx->presentation.video_w, ctx->presentation.video_h); - x = 0; y = 0; - } - - /* Fill in dimensions */ - ctx->presentation.x = x; - ctx->presentation.y = y; - } else if (block == 0x00) { - /* TODO: Blank context as subtitle should not be displayed. - * If the subtitle is blanked now the subtitle is not - * on screen long enough to read, due to a delay in - * initial display timing. - */ - } -} - -/** - * Parses the display segment packet. - * - * The display segment controls the updating of the display. - * - * @param avctx contains the current codec context - * @param data pointer to the data pertaining the subtitle to display - * @param buf pointer to the packet to process - * @param buf_size size of packet to process - * @todo TODO: Fix start time, relies on correct PTS, currently too late - * - * @todo TODO: Fix end time, normally cleared by a second display - * @todo segment, which is currently ignored as it clears - * @todo the subtitle too early. - */ -static int display_end_segment(AVCodecContext *avctx, void *data, - const uint8_t *buf, int buf_size) -{ - AVSubtitle *sub = data; - PGSSubContext *ctx = avctx->priv_data; - - /* - * The end display time is a timeout value and is only reached - * if the next subtitle is later then timeout or subtitle has - * not been cleared by a subsequent empty display command. - */ - - memset(sub, 0, sizeof(*sub)); - sub->start_display_time = 0; - sub->end_display_time = 20000; - sub->format = 0; - - sub->rects = av_mallocz(sizeof(*sub->rects)); - sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); - sub->num_rects = 1; - - sub->rects[0]->x = ctx->presentation.x; - sub->rects[0]->y = ctx->presentation.y; - sub->rects[0]->w = ctx->picture.w; - sub->rects[0]->h = ctx->picture.h; - sub->rects[0]->type = SUBTITLE_BITMAP; - - /* Process bitmap */ - sub->rects[0]->pict.linesize[0] = ctx->picture.w; - - if (ctx->picture.rle) - if(decode_rle(avctx, sub, ctx->picture.rle, ctx->picture.rle_data_len) < 0) - return 0; - - /* Allocate memory for colors */ - sub->rects[0]->nb_colors = 256; - sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); - - memcpy(sub->rects[0]->pict.data[1], ctx->clut, sub->rects[0]->nb_colors * sizeof(uint32_t)); - - return 1; -} - -static int decode(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - - const uint8_t *buf_end; - uint8_t segment_type; - int segment_length; - -#ifdef DEBUG_PACKET_CONTENTS - int i; - - av_log(avctx, AV_LOG_INFO, "PGS 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 & 15) - av_log(avctx, AV_LOG_INFO, "\n"); -#endif - - *data_size = 0; - - /* Ensure that we have received at a least a segment code and segment length */ - if (buf_size < 3) - return -1; - - buf_end = buf + buf_size; - - /* Step through buffer to identify segments */ - while (buf < buf_end) { - segment_type = bytestream_get_byte(&buf); - segment_length = bytestream_get_be16(&buf); - - dprintf(avctx, "Segment Length %d, Segment Type %x\n", segment_length, segment_type); - - if (segment_type != DISPLAY_SEGMENT && segment_length > buf_end - buf) - break; - - switch (segment_type) { - case PALETTE_SEGMENT: - parse_palette_segment(avctx, buf, segment_length); - break; - case PICTURE_SEGMENT: - parse_picture_segment(avctx, buf, segment_length); - break; - case PRESENTATION_SEGMENT: - parse_presentation_segment(avctx, buf, segment_length); - break; - case WINDOW_SEGMENT: - /* - * Window Segment Structure (No new information provided): - * 2 bytes: Unkown, - * 2 bytes: X position of subtitle, - * 2 bytes: Y position of subtitle, - * 2 bytes: Width of subtitle, - * 2 bytes: Height of subtitle. - */ - break; - case DISPLAY_SEGMENT: - *data_size = display_end_segment(avctx, data, buf, segment_length); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown subtitle segment type 0x%x, length %d\n", - segment_type, segment_length); - break; - } - - buf += segment_length; - } - - return buf_size; -} - -AVCodec pgssub_decoder = { - "pgssub", - AVMEDIA_TYPE_SUBTITLE, - CODEC_ID_HDMV_PGS_SUBTITLE, - sizeof(PGSSubContext), - init_decoder, - NULL, - close_decoder, - decode, - .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/png.c b/tizen/distrib/ffmpeg/libavcodec/png.c deleted file mode 100644 index 534dc68..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/png.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * PNG image format - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "bytestream.h" -#include "png.h" - -const uint8_t ff_pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; -const uint8_t ff_mngsig[8] = {138, 77, 78, 71, 13, 10, 26, 10}; - -/* Mask to determine which y pixels are valid in a pass */ -const uint8_t ff_png_pass_ymask[NB_PASSES] = { - 0x80, 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, -}; - -/* minimum x value */ -const uint8_t ff_png_pass_xmin[NB_PASSES] = { - 0, 4, 0, 2, 0, 1, 0 -}; - -/* x shift to get row width */ -const uint8_t ff_png_pass_xshift[NB_PASSES] = { - 3, 3, 2, 2, 1, 1, 0 -}; - -/* Mask to determine which pixels are valid in a pass */ -const uint8_t ff_png_pass_mask[NB_PASSES] = { - 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff -}; - -void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size) -{ - if(items >= UINT_MAX / size) - return NULL; - return av_malloc(items * size); -} - -void ff_png_zfree(void *opaque, void *ptr) -{ - av_free(ptr); -} - -int ff_png_get_nb_channels(int color_type) -{ - int channels; - channels = 1; - if ((color_type & (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)) == - PNG_COLOR_MASK_COLOR) - channels = 3; - if (color_type & PNG_COLOR_MASK_ALPHA) - channels++; - return channels; -} - -/* compute the row size of an interleaved pass */ -int ff_png_pass_row_size(int pass, int bits_per_pixel, int width) -{ - int shift, xmin, pass_width; - - xmin = ff_png_pass_xmin[pass]; - if (width <= xmin) - return 0; - shift = ff_png_pass_xshift[pass]; - pass_width = (width - xmin + (1 << shift) - 1) >> shift; - return (pass_width * bits_per_pixel + 7) >> 3; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/png.h b/tizen/distrib/ffmpeg/libavcodec/png.h deleted file mode 100644 index 7c0ab9f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/png.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * PNG image format - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PNG_H -#define AVCODEC_PNG_H - -#include - -#define PNG_COLOR_MASK_PALETTE 1 -#define PNG_COLOR_MASK_COLOR 2 -#define PNG_COLOR_MASK_ALPHA 4 - -#define PNG_COLOR_TYPE_GRAY 0 -#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) -#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) -#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) -#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) - -#define PNG_FILTER_TYPE_LOCO 64 -#define PNG_FILTER_VALUE_NONE 0 -#define PNG_FILTER_VALUE_SUB 1 -#define PNG_FILTER_VALUE_UP 2 -#define PNG_FILTER_VALUE_AVG 3 -#define PNG_FILTER_VALUE_PAETH 4 -#define PNG_FILTER_VALUE_MIXED 5 - -#define PNG_IHDR 0x0001 -#define PNG_IDAT 0x0002 -#define PNG_ALLIMAGE 0x0004 -#define PNG_PLTE 0x0008 - -#define NB_PASSES 7 - -extern const uint8_t ff_pngsig[8]; -extern const uint8_t ff_mngsig[8]; - -/* Mask to determine which y pixels are valid in a pass */ -extern const uint8_t ff_png_pass_ymask[NB_PASSES]; - -/* minimum x value */ -extern const uint8_t ff_png_pass_xmin[NB_PASSES]; - -/* x shift to get row width */ -extern const uint8_t ff_png_pass_xshift[NB_PASSES]; - -/* Mask to determine which pixels are valid in a pass */ -extern const uint8_t ff_png_pass_mask[NB_PASSES]; - -void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size); - -void ff_png_zfree(void *opaque, void *ptr); - -int ff_png_get_nb_channels(int color_type); - -/* compute the row size of an interleaved pass */ -int ff_png_pass_row_size(int pass, int bits_per_pixel, int width); - -void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); - -#endif /* AVCODEC_PNG_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/pngdec.c b/tizen/distrib/ffmpeg/libavcodec/pngdec.c deleted file mode 100644 index 03859a991..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pngdec.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * PNG image format - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "bytestream.h" -#include "png.h" -#include "dsputil.h" - -/* TODO: - * - add 2, 4 and 16 bit depth support - */ - -#include - -//#define DEBUG - -typedef struct PNGDecContext { - DSPContext dsp; - - const uint8_t *bytestream; - const uint8_t *bytestream_start; - const uint8_t *bytestream_end; - AVFrame picture1, picture2; - AVFrame *current_picture, *last_picture; - - int state; - int width, height; - int bit_depth; - int color_type; - int compression_type; - int interlace_type; - int filter_type; - int channels; - int bits_per_pixel; - int bpp; - - uint8_t *image_buf; - int image_linesize; - uint32_t palette[256]; - uint8_t *crow_buf; - uint8_t *last_row; - uint8_t *tmp_row; - int pass; - int crow_size; /* compressed row size (include filter type) */ - int row_size; /* decompressed row size */ - int pass_row_size; /* decompress row size of the current pass */ - int y; - z_stream zstream; -} PNGDecContext; - -/* Mask to determine which y pixels can be written in a pass */ -static const uint8_t png_pass_dsp_ymask[NB_PASSES] = { - 0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55, -}; - -/* Mask to determine which pixels to overwrite while displaying */ -static const uint8_t png_pass_dsp_mask[NB_PASSES] = { - 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff -}; - -/* NOTE: we try to construct a good looking image at each pass. width - is the original image width. We also do pixel format conversion at - this stage */ -static void png_put_interlaced_row(uint8_t *dst, int width, - int bits_per_pixel, int pass, - int color_type, const uint8_t *src) -{ - int x, mask, dsp_mask, j, src_x, b, bpp; - uint8_t *d; - const uint8_t *s; - - mask = ff_png_pass_mask[pass]; - dsp_mask = png_pass_dsp_mask[pass]; - switch(bits_per_pixel) { - case 1: - /* we must initialize the line to zero before writing to it */ - if (pass == 0) - memset(dst, 0, (width + 7) >> 3); - src_x = 0; - for(x = 0; x < width; x++) { - j = (x & 7); - if ((dsp_mask << j) & 0x80) { - b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1; - dst[x >> 3] |= b << (7 - j); - } - if ((mask << j) & 0x80) - src_x++; - } - break; - default: - bpp = bits_per_pixel >> 3; - d = dst; - s = src; - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - for(x = 0; x < width; x++) { - j = x & 7; - if ((dsp_mask << j) & 0x80) { - *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2]; - } - d += bpp; - if ((mask << j) & 0x80) - s += bpp; - } - } else { - for(x = 0; x < width; x++) { - j = x & 7; - if ((dsp_mask << j) & 0x80) { - memcpy(d, s, bpp); - } - d += bpp; - if ((mask << j) & 0x80) - s += bpp; - } - } - break; - } -} - -void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp) -{ - int i; - for(i = 0; i < w; i++) { - int a, b, c, p, pa, pb, pc; - - a = dst[i - bpp]; - b = top[i]; - c = top[i - bpp]; - - p = b - c; - pc = a - c; - - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); - - if (pa <= pb && pa <= pc) - p = a; - else if (pb <= pc) - p = b; - else - p = c; - dst[i] = p + src[i]; - } -} - -#define UNROLL1(bpp, op) {\ - r = dst[0];\ - if(bpp >= 2) g = dst[1];\ - if(bpp >= 3) b = dst[2];\ - if(bpp >= 4) a = dst[3];\ - for(; i < size; i+=bpp) {\ - dst[i+0] = r = op(r, src[i+0], last[i+0]);\ - if(bpp == 1) continue;\ - dst[i+1] = g = op(g, src[i+1], last[i+1]);\ - if(bpp == 2) continue;\ - dst[i+2] = b = op(b, src[i+2], last[i+2]);\ - if(bpp == 3) continue;\ - dst[i+3] = a = op(a, src[i+3], last[i+3]);\ - }\ -} - -#define UNROLL_FILTER(op)\ - if(bpp == 1) UNROLL1(1, op)\ - else if(bpp == 2) UNROLL1(2, op)\ - else if(bpp == 3) UNROLL1(3, op)\ - else if(bpp == 4) UNROLL1(4, op)\ - else {\ - for (; i < size; i += bpp) {\ - int j;\ - for (j = 0; j < bpp; j++)\ - dst[i+j] = op(dst[i+j-bpp], src[i+j], last[i+j]);\ - }\ - } - -/* NOTE: 'dst' can be equal to 'last' */ -static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type, - uint8_t *src, uint8_t *last, int size, int bpp) -{ - int i, p, r, g, b, a; - - switch(filter_type) { - case PNG_FILTER_VALUE_NONE: - memcpy(dst, src, size); - break; - case PNG_FILTER_VALUE_SUB: - for(i = 0; i < bpp; i++) { - dst[i] = src[i]; - } - if(bpp == 4) { - p = *(int*)dst; - for(; i < size; i+=bpp) { - int s = *(int*)(src+i); - p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080); - *(int*)(dst+i) = p; - } - } else { -#define OP_SUB(x,s,l) x+s - UNROLL_FILTER(OP_SUB); - } - break; - case PNG_FILTER_VALUE_UP: - dsp->add_bytes_l2(dst, src, last, size); - break; - case PNG_FILTER_VALUE_AVG: - for(i = 0; i < bpp; i++) { - p = (last[i] >> 1); - dst[i] = p + src[i]; - } -#define OP_AVG(x,s,l) (((x + l) >> 1) + s) & 0xff - UNROLL_FILTER(OP_AVG); - break; - case PNG_FILTER_VALUE_PAETH: - for(i = 0; i < bpp; i++) { - p = last[i]; - dst[i] = p + src[i]; - } - if(bpp > 1 && size > 4) { - // would write off the end of the array if we let it process the last pixel with bpp=3 - int w = bpp==4 ? size : size-3; - dsp->add_png_paeth_prediction(dst+i, src+i, last+i, w-i, bpp); - i = w; - } - ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp); - break; - } -} - -static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco) -{ - int j; - unsigned int r, g, b, a; - - for(j = 0;j < width; j++) { - r = src[0]; - g = src[1]; - b = src[2]; - a = src[3]; - if(loco) { - r = (r+g)&0xff; - b = (b+g)&0xff; - } - *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b; - dst += 4; - src += 4; - } -} - -static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco) -{ - if(loco) - convert_to_rgb32_loco(dst, src, width, 1); - else - convert_to_rgb32_loco(dst, src, width, 0); -} - -static void deloco_rgb24(uint8_t *dst, int size) -{ - int i; - for(i=0; iinterlace_type) { - ptr = s->image_buf + s->image_linesize * s->y; - /* need to swap bytes correctly for RGB_ALPHA */ - if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1, - s->last_row, s->row_size, s->bpp); - convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO); - FFSWAP(uint8_t*, s->last_row, s->tmp_row); - } else { - /* in normal case, we avoid one copy */ - if (s->y == 0) - last_row = s->last_row; - else - last_row = ptr - s->image_linesize; - - png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1, - last_row, s->row_size, s->bpp); - } - /* loco lags by 1 row so that it doesn't interfere with top prediction */ - if (s->filter_type == PNG_FILTER_TYPE_LOCO && - s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0) - deloco_rgb24(ptr - s->image_linesize, s->row_size); - s->y++; - if (s->y == s->height) { - s->state |= PNG_ALLIMAGE; - if (s->filter_type == PNG_FILTER_TYPE_LOCO && - s->color_type == PNG_COLOR_TYPE_RGB) - deloco_rgb24(ptr, s->row_size); - } - } else { - got_line = 0; - for(;;) { - ptr = s->image_buf + s->image_linesize * s->y; - if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { - /* if we already read one row, it is time to stop to - wait for the next one */ - if (got_line) - break; - png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1, - s->last_row, s->pass_row_size, s->bpp); - FFSWAP(uint8_t*, s->last_row, s->tmp_row); - got_line = 1; - } - if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) { - /* NOTE: RGB32 is handled directly in png_put_interlaced_row */ - png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass, - s->color_type, s->last_row); - } - s->y++; - if (s->y == s->height) { - for(;;) { - if (s->pass == NB_PASSES - 1) { - s->state |= PNG_ALLIMAGE; - goto the_end; - } else { - s->pass++; - s->y = 0; - s->pass_row_size = ff_png_pass_row_size(s->pass, - s->bits_per_pixel, - s->width); - s->crow_size = s->pass_row_size + 1; - if (s->pass_row_size != 0) - break; - /* skip pass if empty row */ - } - } - } - } - the_end: ; - } -} - -static int png_decode_idat(PNGDecContext *s, int length) -{ - int ret; - s->zstream.avail_in = length; - s->zstream.next_in = s->bytestream; - s->bytestream += length; - - if(s->bytestream > s->bytestream_end) - return -1; - - /* decode one line if possible */ - while (s->zstream.avail_in > 0) { - ret = inflate(&s->zstream, Z_PARTIAL_FLUSH); - if (ret != Z_OK && ret != Z_STREAM_END) { - return -1; - } - if (s->zstream.avail_out == 0) { - if (!(s->state & PNG_ALLIMAGE)) { - png_handle_row(s); - } - s->zstream.avail_out = s->crow_size; - s->zstream.next_out = s->crow_buf; - } - } - return 0; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - PNGDecContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p; - uint8_t *crow_buf_base = NULL; - uint32_t tag, length; - int ret, crc; - - FFSWAP(AVFrame *, s->current_picture, s->last_picture); - avctx->coded_frame= s->current_picture; - p = s->current_picture; - - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf + buf_size; - - /* check signature */ - if (memcmp(s->bytestream, ff_pngsig, 8) != 0 && - memcmp(s->bytestream, ff_mngsig, 8) != 0) - return -1; - s->bytestream+= 8; - s->y= - s->state=0; -// memset(s, 0, sizeof(PNGDecContext)); - /* init the zlib */ - s->zstream.zalloc = ff_png_zalloc; - s->zstream.zfree = ff_png_zfree; - s->zstream.opaque = NULL; - ret = inflateInit(&s->zstream); - if (ret != Z_OK) - return -1; - for(;;) { - int tag32; - if (s->bytestream >= s->bytestream_end) - goto fail; - length = bytestream_get_be32(&s->bytestream); - if (length > 0x7fffffff) - goto fail; - tag32 = bytestream_get_be32(&s->bytestream); - tag = bswap_32(tag32); - dprintf(avctx, "png: tag=%c%c%c%c length=%u\n", - (tag & 0xff), - ((tag >> 8) & 0xff), - ((tag >> 16) & 0xff), - ((tag >> 24) & 0xff), length); - switch(tag) { - case MKTAG('I', 'H', 'D', 'R'): - if (length != 13) - goto fail; - s->width = bytestream_get_be32(&s->bytestream); - s->height = bytestream_get_be32(&s->bytestream); - if(avcodec_check_dimensions(avctx, s->width, s->height)){ - s->width= s->height= 0; - goto fail; - } - s->bit_depth = *s->bytestream++; - s->color_type = *s->bytestream++; - s->compression_type = *s->bytestream++; - s->filter_type = *s->bytestream++; - s->interlace_type = *s->bytestream++; - crc = bytestream_get_be32(&s->bytestream); - s->state |= PNG_IHDR; - dprintf(avctx, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", - s->width, s->height, s->bit_depth, s->color_type, - s->compression_type, s->filter_type, s->interlace_type); - break; - case MKTAG('I', 'D', 'A', 'T'): - if (!(s->state & PNG_IHDR)) - goto fail; - if (!(s->state & PNG_IDAT)) { - /* init image info */ - avctx->width = s->width; - avctx->height = s->height; - - s->channels = ff_png_get_nb_channels(s->color_type); - s->bits_per_pixel = s->bit_depth * s->channels; - s->bpp = (s->bits_per_pixel + 7) >> 3; - s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3; - - if (s->bit_depth == 8 && - s->color_type == PNG_COLOR_TYPE_RGB) { - avctx->pix_fmt = PIX_FMT_RGB24; - } else if (s->bit_depth == 8 && - s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - avctx->pix_fmt = PIX_FMT_RGB32; - } else if (s->bit_depth == 8 && - s->color_type == PNG_COLOR_TYPE_GRAY) { - avctx->pix_fmt = PIX_FMT_GRAY8; - } else if (s->bit_depth == 16 && - s->color_type == PNG_COLOR_TYPE_GRAY) { - avctx->pix_fmt = PIX_FMT_GRAY16BE; - } else if (s->bit_depth == 16 && - s->color_type == PNG_COLOR_TYPE_RGB) { - avctx->pix_fmt = PIX_FMT_RGB48BE; - } else if (s->bit_depth == 1 && - s->color_type == PNG_COLOR_TYPE_GRAY) { - avctx->pix_fmt = PIX_FMT_MONOBLACK; - } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { - avctx->pix_fmt = PIX_FMT_PAL8; - } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - avctx->pix_fmt = PIX_FMT_Y400A; - } else { - goto fail; - } - 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"); - goto fail; - } - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - p->interlaced_frame = !!s->interlace_type; - - /* compute the compressed row size */ - if (!s->interlace_type) { - s->crow_size = s->row_size + 1; - } else { - s->pass = 0; - s->pass_row_size = ff_png_pass_row_size(s->pass, - s->bits_per_pixel, - s->width); - s->crow_size = s->pass_row_size + 1; - } - dprintf(avctx, "row_size=%d crow_size =%d\n", - s->row_size, s->crow_size); - s->image_buf = p->data[0]; - s->image_linesize = p->linesize[0]; - /* copy the palette if needed */ - if (s->color_type == PNG_COLOR_TYPE_PALETTE) - memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t)); - /* empty row is used if differencing to the first row */ - s->last_row = av_mallocz(s->row_size); - if (!s->last_row) - goto fail; - if (s->interlace_type || - s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - s->tmp_row = av_malloc(s->row_size); - if (!s->tmp_row) - goto fail; - } - /* compressed row */ - crow_buf_base = av_malloc(s->row_size + 16); - if (!crow_buf_base) - goto fail; - - /* we want crow_buf+1 to be 16-byte aligned */ - s->crow_buf = crow_buf_base + 15; - s->zstream.avail_out = s->crow_size; - s->zstream.next_out = s->crow_buf; - } - s->state |= PNG_IDAT; - if (png_decode_idat(s, length) < 0) - goto fail; - /* skip crc */ - crc = bytestream_get_be32(&s->bytestream); - break; - case MKTAG('P', 'L', 'T', 'E'): - { - int n, i, r, g, b; - - if ((length % 3) != 0 || length > 256 * 3) - goto skip_tag; - /* read the palette */ - n = length / 3; - for(i=0;ibytestream++; - g = *s->bytestream++; - b = *s->bytestream++; - s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b; - } - for(;i<256;i++) { - s->palette[i] = (0xff << 24); - } - s->state |= PNG_PLTE; - crc = bytestream_get_be32(&s->bytestream); - } - break; - case MKTAG('t', 'R', 'N', 'S'): - { - int v, i; - - /* read the transparency. XXX: Only palette mode supported */ - if (s->color_type != PNG_COLOR_TYPE_PALETTE || - length > 256 || - !(s->state & PNG_PLTE)) - goto skip_tag; - for(i=0;ibytestream++; - s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24); - } - crc = bytestream_get_be32(&s->bytestream); - } - break; - case MKTAG('I', 'E', 'N', 'D'): - if (!(s->state & PNG_ALLIMAGE)) - goto fail; - crc = bytestream_get_be32(&s->bytestream); - goto exit_loop; - default: - /* skip tag */ - skip_tag: - s->bytestream += length + 4; - break; - } - } - exit_loop: - /* handle p-frames only if a predecessor frame is available */ - if(s->last_picture->data[0] != NULL) { - if(!(avpkt->flags & AV_PKT_FLAG_KEY)) { - int i, j; - uint8_t *pd = s->current_picture->data[0]; - uint8_t *pd_last = s->last_picture->data[0]; - - for(j=0; j < s->height; j++) { - for(i=0; i < s->width * s->bpp; i++) { - pd[i] += pd_last[i]; - } - pd += s->image_linesize; - pd_last += s->image_linesize; - } - } - } - - *picture= *s->current_picture; - *data_size = sizeof(AVFrame); - - ret = s->bytestream - s->bytestream_start; - the_end: - inflateEnd(&s->zstream); - av_free(crow_buf_base); - s->crow_buf = NULL; - av_freep(&s->last_row); - av_freep(&s->tmp_row); - return ret; - fail: - ret = -1; - goto the_end; -} - -static av_cold int png_dec_init(AVCodecContext *avctx){ - PNGDecContext *s = avctx->priv_data; - - s->current_picture = &s->picture1; - s->last_picture = &s->picture2; - avcodec_get_frame_defaults(&s->picture1); - avcodec_get_frame_defaults(&s->picture2); - dsputil_init(&s->dsp, avctx); - - return 0; -} - -static av_cold int png_dec_end(AVCodecContext *avctx) -{ - PNGDecContext *s = avctx->priv_data; - - if (s->picture1.data[0]) - avctx->release_buffer(avctx, &s->picture1); - if (s->picture2.data[0]) - avctx->release_buffer(avctx, &s->picture2); - - return 0; -} - -AVCodec png_decoder = { - "png", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PNG, - sizeof(PNGDecContext), - png_dec_init, - NULL, - png_dec_end, - decode_frame, - CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("PNG image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/pngenc.c b/tizen/distrib/ffmpeg/libavcodec/pngenc.c deleted file mode 100644 index 615bcc4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pngenc.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * PNG image format - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "bytestream.h" -#include "dsputil.h" -#include "png.h" - -/* TODO: - * - add 2, 4 and 16 bit depth support - */ - -#include - -//#define DEBUG - -#define IOBUF_SIZE 4096 - -typedef struct PNGEncContext { - DSPContext dsp; - - uint8_t *bytestream; - uint8_t *bytestream_start; - uint8_t *bytestream_end; - AVFrame picture; - - int filter_type; - - z_stream zstream; - uint8_t buf[IOBUF_SIZE]; -} PNGEncContext; - -static void png_get_interlaced_row(uint8_t *dst, int row_size, - int bits_per_pixel, int pass, - const uint8_t *src, int width) -{ - int x, mask, dst_x, j, b, bpp; - uint8_t *d; - const uint8_t *s; - - mask = ff_png_pass_mask[pass]; - switch(bits_per_pixel) { - case 1: - memset(dst, 0, row_size); - dst_x = 0; - for(x = 0; x < width; x++) { - j = (x & 7); - if ((mask << j) & 0x80) { - b = (src[x >> 3] >> (7 - j)) & 1; - dst[dst_x >> 3] |= b << (7 - (dst_x & 7)); - dst_x++; - } - } - break; - default: - bpp = bits_per_pixel >> 3; - d = dst; - s = src; - for(x = 0; x < width; x++) { - j = x & 7; - if ((mask << j) & 0x80) { - memcpy(d, s, bpp); - d += bpp; - } - s += bpp; - } - break; - } -} - -static void sub_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp) -{ - int i; - for(i = 0; i < w; i++) { - int a, b, c, p, pa, pb, pc; - - a = src[i - bpp]; - b = top[i]; - c = top[i - bpp]; - - p = b - c; - pc = a - c; - - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); - - if (pa <= pb && pa <= pc) - p = a; - else if (pb <= pc) - p = b; - else - p = c; - dst[i] = src[i] - p; - } -} - -static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type, - uint8_t *src, uint8_t *top, int size, int bpp) -{ - int i; - - switch(filter_type) { - case PNG_FILTER_VALUE_NONE: - memcpy(dst, src, size); - break; - case PNG_FILTER_VALUE_SUB: - dsp->diff_bytes(dst, src, src-bpp, size); - memcpy(dst, src, bpp); - break; - case PNG_FILTER_VALUE_UP: - dsp->diff_bytes(dst, src, top, size); - break; - case PNG_FILTER_VALUE_AVG: - for(i = 0; i < bpp; i++) - dst[i] = src[i] - (top[i] >> 1); - for(; i < size; i++) - dst[i] = src[i] - ((src[i-bpp] + top[i]) >> 1); - break; - case PNG_FILTER_VALUE_PAETH: - for(i = 0; i < bpp; i++) - dst[i] = src[i] - top[i]; - sub_png_paeth_prediction(dst+i, src+i, top+i, size-i, bpp); - break; - } -} - -static uint8_t *png_choose_filter(PNGEncContext *s, uint8_t *dst, - uint8_t *src, uint8_t *top, int size, int bpp) -{ - int pred = s->filter_type; - assert(bpp || !pred); - if(!top && pred) - pred = PNG_FILTER_VALUE_SUB; - if(pred == PNG_FILTER_VALUE_MIXED) { - int i; - int cost, bcost = INT_MAX; - uint8_t *buf1 = dst, *buf2 = dst + size + 16; - for(pred=0; pred<5; pred++) { - png_filter_row(&s->dsp, buf1+1, pred, src, top, size, bpp); - buf1[0] = pred; - cost = 0; - for(i=0; i<=size; i++) - cost += abs((int8_t)buf1[i]); - if(cost < bcost) { - bcost = cost; - FFSWAP(uint8_t*, buf1, buf2); - } - } - return buf2; - } else { - png_filter_row(&s->dsp, dst+1, pred, src, top, size, bpp); - dst[0] = pred; - return dst; - } -} - -static void convert_from_rgb32(uint8_t *dst, const uint8_t *src, int width) -{ - uint8_t *d; - int j; - unsigned int v; - - d = dst; - for(j = 0; j < width; j++) { - v = ((const uint32_t *)src)[j]; - d[0] = v >> 16; - d[1] = v >> 8; - d[2] = v; - d[3] = v >> 24; - d += 4; - } -} - -static void png_write_chunk(uint8_t **f, uint32_t tag, - const uint8_t *buf, int length) -{ - uint32_t crc; - uint8_t tagbuf[4]; - - bytestream_put_be32(f, length); - crc = crc32(0, Z_NULL, 0); - AV_WL32(tagbuf, tag); - crc = crc32(crc, tagbuf, 4); - bytestream_put_be32(f, bswap_32(tag)); - if (length > 0) { - crc = crc32(crc, buf, length); - memcpy(*f, buf, length); - *f += length; - } - bytestream_put_be32(f, crc); -} - -/* XXX: do filtering */ -static int png_write_row(PNGEncContext *s, const uint8_t *data, int size) -{ - int ret; - - s->zstream.avail_in = size; - s->zstream.next_in = (uint8_t *)data; - while (s->zstream.avail_in > 0) { - ret = deflate(&s->zstream, Z_NO_FLUSH); - if (ret != Z_OK) - return -1; - if (s->zstream.avail_out == 0) { - if(s->bytestream_end - s->bytestream > IOBUF_SIZE + 100) - png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, IOBUF_SIZE); - s->zstream.avail_out = IOBUF_SIZE; - s->zstream.next_out = s->buf; - } - } - return 0; -} - -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - PNGEncContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= &s->picture; - int bit_depth, color_type, y, len, row_size, ret, is_progressive; - int bits_per_pixel, pass_row_size; - int compression_level; - uint8_t *ptr, *top; - uint8_t *crow_base = NULL, *crow_buf, *crow; - uint8_t *progressive_buf = NULL; - uint8_t *rgba_buf = NULL; - uint8_t *top_buf = NULL; - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf+buf_size; - - is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); - switch(avctx->pix_fmt) { - case PIX_FMT_RGB32: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_RGB_ALPHA; - break; - case PIX_FMT_RGB24: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_RGB; - break; - case PIX_FMT_GRAY8: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_GRAY; - break; - case PIX_FMT_MONOBLACK: - bit_depth = 1; - color_type = PNG_COLOR_TYPE_GRAY; - break; - case PIX_FMT_PAL8: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_PALETTE; - break; - default: - return -1; - } - bits_per_pixel = ff_png_get_nb_channels(color_type) * bit_depth; - row_size = (avctx->width * bits_per_pixel + 7) >> 3; - - s->zstream.zalloc = ff_png_zalloc; - s->zstream.zfree = ff_png_zfree; - s->zstream.opaque = NULL; - compression_level = avctx->compression_level == FF_COMPRESSION_DEFAULT ? - Z_DEFAULT_COMPRESSION : - av_clip(avctx->compression_level, 0, 9); - ret = deflateInit2(&s->zstream, compression_level, - Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY); - if (ret != Z_OK) - return -1; - crow_base = av_malloc((row_size + 32) << (s->filter_type == PNG_FILTER_VALUE_MIXED)); - if (!crow_base) - goto fail; - crow_buf = crow_base + 15; // pixel data should be aligned, but there's a control byte before it - if (is_progressive) { - progressive_buf = av_malloc(row_size + 1); - if (!progressive_buf) - goto fail; - } - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - rgba_buf = av_malloc(row_size + 1); - if (!rgba_buf) - goto fail; - } - if (is_progressive || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - top_buf = av_malloc(row_size + 1); - if (!top_buf) - goto fail; - } - - /* write png header */ - memcpy(s->bytestream, ff_pngsig, 8); - s->bytestream += 8; - - AV_WB32(s->buf, avctx->width); - AV_WB32(s->buf + 4, avctx->height); - s->buf[8] = bit_depth; - s->buf[9] = color_type; - s->buf[10] = 0; /* compression type */ - s->buf[11] = 0; /* filter type */ - s->buf[12] = is_progressive; /* interlace type */ - - png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13); - - /* put the palette if needed */ - if (color_type == PNG_COLOR_TYPE_PALETTE) { - int has_alpha, alpha, i; - unsigned int v; - uint32_t *palette; - uint8_t *alpha_ptr; - - palette = (uint32_t *)p->data[1]; - ptr = s->buf; - alpha_ptr = s->buf + 256 * 3; - has_alpha = 0; - for(i = 0; i < 256; i++) { - v = palette[i]; - alpha = v >> 24; - if (alpha && alpha != 0xff) - has_alpha = 1; - *alpha_ptr++ = alpha; - bytestream_put_be24(&ptr, v); - } - png_write_chunk(&s->bytestream, MKTAG('P', 'L', 'T', 'E'), s->buf, 256 * 3); - if (has_alpha) { - png_write_chunk(&s->bytestream, MKTAG('t', 'R', 'N', 'S'), s->buf + 256 * 3, 256); - } - } - - /* now put each row */ - s->zstream.avail_out = IOBUF_SIZE; - s->zstream.next_out = s->buf; - if (is_progressive) { - int pass; - - for(pass = 0; pass < NB_PASSES; pass++) { - /* NOTE: a pass is completely omited if no pixels would be - output */ - pass_row_size = ff_png_pass_row_size(pass, bits_per_pixel, avctx->width); - if (pass_row_size > 0) { - top = NULL; - for(y = 0; y < avctx->height; y++) { - if ((ff_png_pass_ymask[pass] << (y & 7)) & 0x80) { - ptr = p->data[0] + y * p->linesize[0]; - FFSWAP(uint8_t*, progressive_buf, top_buf); - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - convert_from_rgb32(rgba_buf, ptr, avctx->width); - ptr = rgba_buf; - } - png_get_interlaced_row(progressive_buf, pass_row_size, - bits_per_pixel, pass, - ptr, avctx->width); - crow = png_choose_filter(s, crow_buf, progressive_buf, top, pass_row_size, bits_per_pixel>>3); - png_write_row(s, crow, pass_row_size + 1); - top = progressive_buf; - } - } - } - } - } else { - top = NULL; - for(y = 0; y < avctx->height; y++) { - ptr = p->data[0] + y * p->linesize[0]; - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - FFSWAP(uint8_t*, rgba_buf, top_buf); - convert_from_rgb32(rgba_buf, ptr, avctx->width); - ptr = rgba_buf; - } - crow = png_choose_filter(s, crow_buf, ptr, top, row_size, bits_per_pixel>>3); - png_write_row(s, crow, row_size + 1); - top = ptr; - } - } - /* compress last bytes */ - for(;;) { - ret = deflate(&s->zstream, Z_FINISH); - if (ret == Z_OK || ret == Z_STREAM_END) { - len = IOBUF_SIZE - s->zstream.avail_out; - if (len > 0 && s->bytestream_end - s->bytestream > len + 100) { - png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, len); - } - s->zstream.avail_out = IOBUF_SIZE; - s->zstream.next_out = s->buf; - if (ret == Z_STREAM_END) - break; - } else { - goto fail; - } - } - png_write_chunk(&s->bytestream, MKTAG('I', 'E', 'N', 'D'), NULL, 0); - - ret = s->bytestream - s->bytestream_start; - the_end: - av_free(crow_base); - av_free(progressive_buf); - av_free(rgba_buf); - av_free(top_buf); - deflateEnd(&s->zstream); - return ret; - fail: - ret = -1; - goto the_end; -} - -static av_cold int png_enc_init(AVCodecContext *avctx){ - PNGEncContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - dsputil_init(&s->dsp, avctx); - - s->filter_type = av_clip(avctx->prediction_method, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED); - if(avctx->pix_fmt == PIX_FMT_MONOBLACK) - s->filter_type = PNG_FILTER_VALUE_NONE; - - return 0; -} - -AVCodec png_encoder = { - "png", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PNG, - sizeof(PNGEncContext), - png_enc_init, - encode_frame, - NULL, //encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("PNG image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/pnm.c b/tizen/distrib/ffmpeg/libavcodec/pnm.c deleted file mode 100644 index cb6a713..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pnm.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * PNM image format - * Copyright (c) 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "pnm.h" - -static inline int pnm_space(int c) -{ - return c == ' ' || c == '\n' || c == '\r' || c == '\t'; -} - -static void pnm_get(PNMContext *sc, char *str, int buf_size) -{ - char *s; - int c; - - /* skip spaces and comments */ - for (;;) { - c = *sc->bytestream++; - if (c == '#') { - do { - c = *sc->bytestream++; - } while (c != '\n' && sc->bytestream < sc->bytestream_end); - } else if (!pnm_space(c)) { - break; - } - } - - s = str; - while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) { - if ((s - str) < buf_size - 1) - *s++ = c; - c = *sc->bytestream++; - } - *s = '\0'; -} - -int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) -{ - char buf1[32], tuple_type[32]; - int h, w, depth, maxval; - - pnm_get(s, buf1, sizeof(buf1)); - s->type= buf1[1]-'0'; - if(buf1[0] != 'P') - return -1; - - if (s->type==1 || s->type==4) { - avctx->pix_fmt = PIX_FMT_MONOWHITE; - } else if (s->type==2 || s->type==5) { - if (avctx->codec_id == CODEC_ID_PGMYUV) - avctx->pix_fmt = PIX_FMT_YUV420P; - else - avctx->pix_fmt = PIX_FMT_GRAY8; - } else if (s->type==3 || s->type==6) { - avctx->pix_fmt = PIX_FMT_RGB24; - } else if (s->type==7) { - w = -1; - h = -1; - maxval = -1; - depth = -1; - tuple_type[0] = '\0'; - for (;;) { - pnm_get(s, buf1, sizeof(buf1)); - if (!strcmp(buf1, "WIDTH")) { - pnm_get(s, buf1, sizeof(buf1)); - w = strtol(buf1, NULL, 10); - } else if (!strcmp(buf1, "HEIGHT")) { - pnm_get(s, buf1, sizeof(buf1)); - h = strtol(buf1, NULL, 10); - } else if (!strcmp(buf1, "DEPTH")) { - pnm_get(s, buf1, sizeof(buf1)); - depth = strtol(buf1, NULL, 10); - } else if (!strcmp(buf1, "MAXVAL")) { - pnm_get(s, buf1, sizeof(buf1)); - maxval = strtol(buf1, NULL, 10); - } else if (!strcmp(buf1, "TUPLETYPE")) { - pnm_get(s, tuple_type, sizeof(tuple_type)); - } else if (!strcmp(buf1, "ENDHDR")) { - break; - } else { - return -1; - } - } - /* check that all tags are present */ - if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || avcodec_check_dimensions(avctx, w, h)) - return -1; - - avctx->width = w; - avctx->height = h; - if (depth == 1) { - if (maxval == 1) - avctx->pix_fmt = PIX_FMT_MONOWHITE; - else - avctx->pix_fmt = PIX_FMT_GRAY8; - } else if (depth == 3) { - if (maxval < 256) { - avctx->pix_fmt = PIX_FMT_RGB24; - } else { - av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n"); - avctx->pix_fmt = PIX_FMT_NONE; - return -1; - } - } else if (depth == 4) { - avctx->pix_fmt = PIX_FMT_RGB32; - } else { - return -1; - } - return 0; - } else { - return -1; - } - pnm_get(s, buf1, sizeof(buf1)); - avctx->width = atoi(buf1); - if (avctx->width <= 0) - return -1; - pnm_get(s, buf1, sizeof(buf1)); - avctx->height = atoi(buf1); - if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) - return -1; - if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { - pnm_get(s, buf1, sizeof(buf1)); - s->maxval = atoi(buf1); - if (s->maxval >= 256) { - if (avctx->pix_fmt == PIX_FMT_GRAY8) { - avctx->pix_fmt = PIX_FMT_GRAY16BE; - if (s->maxval != 65535) - avctx->pix_fmt = PIX_FMT_GRAY16; - } else if (avctx->pix_fmt == PIX_FMT_RGB24) { - if (s->maxval > 255) - avctx->pix_fmt = PIX_FMT_RGB48BE; - } else { - av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n"); - avctx->pix_fmt = PIX_FMT_NONE; - return -1; - } - } - }else - s->maxval=1; - /* more check if YUV420 */ - if (avctx->pix_fmt == PIX_FMT_YUV420P) { - if ((avctx->width & 1) != 0) - return -1; - h = (avctx->height * 2); - if ((h % 3) != 0) - return -1; - h /= 3; - avctx->height = h; - } - return 0; -} - -av_cold int ff_pnm_end(AVCodecContext *avctx) -{ - PNMContext *s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -av_cold int ff_pnm_init(AVCodecContext *avctx) -{ - PNMContext *s = avctx->priv_data; - - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame = (AVFrame*)&s->picture; - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/pnm.h b/tizen/distrib/ffmpeg/libavcodec/pnm.h deleted file mode 100644 index ac4b108..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pnm.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * PNM image format - * Copyright (c) 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PNM_H -#define AVCODEC_PNM_H - -#include "avcodec.h" - -typedef struct PNMContext { - uint8_t *bytestream; - uint8_t *bytestream_start; - uint8_t *bytestream_end; - AVFrame picture; - int maxval; ///< maximum value of a pixel - int type; -} PNMContext; - -int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s); -av_cold int ff_pnm_end(AVCodecContext *avctx); -av_cold int ff_pnm_init(AVCodecContext *avctx); - -#endif /* AVCODEC_PNM_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/pnm_parser.c b/tizen/distrib/ffmpeg/libavcodec/pnm_parser.c deleted file mode 100644 index b8ba1a8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pnm_parser.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * PNM image parser - * Copyright (c) 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" //for ParseContext -#include "pnm.h" - - -static int pnm_parse(AVCodecParserContext *s, AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - PNMContext pnmctx; - int next; - - for (; pc->overread > 0; pc->overread--) { - pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; - } -retry: - if (pc->index) { - pnmctx.bytestream_start = - pnmctx.bytestream = pc->buffer; - pnmctx.bytestream_end = pc->buffer + pc->index; - } else { - pnmctx.bytestream_start = - pnmctx.bytestream = (uint8_t *) buf; /* casts avoid warnings */ - pnmctx.bytestream_end = (uint8_t *) buf + buf_size; - } - if (ff_pnm_decode_header(avctx, &pnmctx) < 0) { - if (pnmctx.bytestream < pnmctx.bytestream_end) { - if (pc->index) { - pc->index = 0; - } else { - buf++; - buf_size--; - } - goto retry; - } -#if 0 - if (pc->index && pc->index * 2 + FF_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index) { - memcpy(pc->buffer + pc->index, buf, pc->index); - pc->index += pc->index; - buf += pc->index; - buf_size -= pc->index; - goto retry; - } -#endif - next = END_NOT_FOUND; - } else { - next = pnmctx.bytestream - pnmctx.bytestream_start - + avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); - if (pnmctx.bytestream_start != buf) - next -= pc->index; - if (next > buf_size) - next = END_NOT_FOUND; - } - - if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser pnm_parser = { - { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM, CODEC_ID_PBM, CODEC_ID_PAM}, - sizeof(ParseContext), - NULL, - pnm_parse, - ff_parse_close, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/pnmdec.c b/tizen/distrib/ffmpeg/libavcodec/pnmdec.c deleted file mode 100644 index 66033c1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pnmdec.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * PNM image format - * Copyright (c) 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "put_bits.h" -#include "pnm.h" - - -static int pnm_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - PNMContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = (AVFrame*)&s->picture; - int i, j, n, linesize, h, upgrade = 0; - unsigned char *ptr; - int components, sample_len; - - s->bytestream_start = - s->bytestream = buf; - s->bytestream_end = buf + buf_size; - - if (ff_pnm_decode_header(avctx, s) < 0) - return -1; - - 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 = FF_I_TYPE; - p->key_frame = 1; - - switch (avctx->pix_fmt) { - default: - return -1; - case PIX_FMT_RGB48BE: - n = avctx->width * 6; - components=3; - sample_len=16; - goto do_read; - case PIX_FMT_RGB24: - n = avctx->width * 3; - components=3; - sample_len=8; - goto do_read; - case PIX_FMT_GRAY8: - n = avctx->width; - components=1; - sample_len=8; - if (s->maxval < 255) - upgrade = 1; - goto do_read; - case PIX_FMT_GRAY16BE: - case PIX_FMT_GRAY16LE: - n = avctx->width * 2; - components=1; - sample_len=16; - if (s->maxval < 65535) - upgrade = 2; - goto do_read; - case PIX_FMT_MONOWHITE: - case PIX_FMT_MONOBLACK: - n = (avctx->width + 7) >> 3; - components=1; - sample_len=1; - do_read: - ptr = p->data[0]; - linesize = p->linesize[0]; - if (s->bytestream + n * avctx->height > s->bytestream_end) - return -1; - if(s->type < 4){ - for (i=0; iheight; i++) { - PutBitContext pb; - init_put_bits(&pb, ptr, linesize); - for(j=0; jwidth * components; j++){ - unsigned int c=0; - int v=0; - while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' )) - s->bytestream++; - if(s->bytestream >= s->bytestream_end) - return -1; - do{ - v= 10*v + c; - c= (*s->bytestream++) - '0'; - }while(c <= 9); - put_bits(&pb, sample_len, (((1<maxval>>1))/s->maxval); - } - flush_put_bits(&pb); - ptr+= linesize; - } - }else{ - for (i = 0; i < avctx->height; i++) { - if (!upgrade) - memcpy(ptr, s->bytestream, n); - else if (upgrade == 1) { - unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval; - for (j = 0; j < n; j++) - ptr[j] = (s->bytestream[j] * f + 64) >> 7; - } else if (upgrade == 2) { - unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval; - for (j = 0; j < n / 2; j++) { - v = be2me_16(((uint16_t *)s->bytestream)[j]); - ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; - } - } - s->bytestream += n; - ptr += linesize; - } - } - break; - case PIX_FMT_YUV420P: - { - unsigned char *ptr1, *ptr2; - - n = avctx->width; - ptr = p->data[0]; - linesize = p->linesize[0]; - if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end) - return -1; - for (i = 0; i < avctx->height; i++) { - memcpy(ptr, s->bytestream, n); - s->bytestream += n; - ptr += linesize; - } - ptr1 = p->data[1]; - ptr2 = p->data[2]; - n >>= 1; - h = avctx->height >> 1; - for (i = 0; i < h; i++) { - memcpy(ptr1, s->bytestream, n); - s->bytestream += n; - memcpy(ptr2, s->bytestream, n); - s->bytestream += n; - ptr1 += p->linesize[1]; - ptr2 += p->linesize[2]; - } - } - break; - case PIX_FMT_RGB32: - ptr = p->data[0]; - linesize = p->linesize[0]; - if (s->bytestream + avctx->width * avctx->height * 4 > s->bytestream_end) - return -1; - for (i = 0; i < avctx->height; i++) { - int j, r, g, b, a; - - for (j = 0; j < avctx->width; j++) { - r = *s->bytestream++; - g = *s->bytestream++; - b = *s->bytestream++; - a = *s->bytestream++; - ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b; - } - ptr += linesize; - } - break; - } - *picture = *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); - - return s->bytestream - s->bytestream_start; -} - - -#if CONFIG_PGM_DECODER -AVCodec pgm_decoder = { - "pgm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PGM, - sizeof(PNMContext), - ff_pnm_init, - NULL, - ff_pnm_end, - pnm_decode_frame, - CODEC_CAP_DR1, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), -}; -#endif - -#if CONFIG_PGMYUV_DECODER -AVCodec pgmyuv_decoder = { - "pgmyuv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PGMYUV, - sizeof(PNMContext), - ff_pnm_init, - NULL, - ff_pnm_end, - pnm_decode_frame, - CODEC_CAP_DR1, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), -}; -#endif - -#if CONFIG_PPM_DECODER -AVCodec ppm_decoder = { - "ppm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PPM, - sizeof(PNMContext), - ff_pnm_init, - NULL, - ff_pnm_end, - pnm_decode_frame, - CODEC_CAP_DR1, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB48BE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), -}; -#endif - -#if CONFIG_PBM_DECODER -AVCodec pbm_decoder = { - "pbm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PBM, - sizeof(PNMContext), - ff_pnm_init, - NULL, - ff_pnm_end, - pnm_decode_frame, - CODEC_CAP_DR1, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_MONOWHITE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), -}; -#endif - -#if CONFIG_PAM_DECODER -AVCodec pam_decoder = { - "pam", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PAM, - sizeof(PNMContext), - ff_pnm_init, - NULL, - ff_pnm_end, - pnm_decode_frame, - CODEC_CAP_DR1, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/pnmenc.c b/tizen/distrib/ffmpeg/libavcodec/pnmenc.c deleted file mode 100644 index 1fbf665..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pnmenc.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * PNM image format - * Copyright (c) 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "pnm.h" - - -static int pnm_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, - int buf_size, void *data) -{ - PNMContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p = (AVFrame*)&s->picture; - int i, h, h1, c, n, linesize; - uint8_t *ptr, *ptr1, *ptr2; - - if (buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200) { - av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - *p = *pict; - p->pict_type = FF_I_TYPE; - p->key_frame = 1; - - s->bytestream_start = - s->bytestream = outbuf; - s->bytestream_end = outbuf + buf_size; - - h = avctx->height; - h1 = h; - switch (avctx->pix_fmt) { - case PIX_FMT_MONOWHITE: - c = '4'; - n = (avctx->width + 7) >> 3; - break; - case PIX_FMT_GRAY8: - c = '5'; - n = avctx->width; - break; - case PIX_FMT_GRAY16BE: - c = '5'; - n = avctx->width * 2; - break; - case PIX_FMT_RGB24: - c = '6'; - n = avctx->width * 3; - break; - case PIX_FMT_RGB48BE: - c = '6'; - n = avctx->width * 6; - break; - case PIX_FMT_YUV420P: - c = '5'; - n = avctx->width; - h1 = (h * 3) / 2; - break; - default: - return -1; - } - snprintf(s->bytestream, s->bytestream_end - s->bytestream, - "P%c\n%d %d\n", c, avctx->width, h1); - s->bytestream += strlen(s->bytestream); - if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { - snprintf(s->bytestream, s->bytestream_end - s->bytestream, - "%d\n", (avctx->pix_fmt != PIX_FMT_GRAY16BE && avctx->pix_fmt != PIX_FMT_RGB48BE) ? 255 : 65535); - s->bytestream += strlen(s->bytestream); - } - - ptr = p->data[0]; - linesize = p->linesize[0]; - for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; - } - - if (avctx->pix_fmt == PIX_FMT_YUV420P) { - h >>= 1; - n >>= 1; - ptr1 = p->data[1]; - ptr2 = p->data[2]; - for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr1, n); - s->bytestream += n; - memcpy(s->bytestream, ptr2, n); - s->bytestream += n; - ptr1 += p->linesize[1]; - ptr2 += p->linesize[2]; - } - } - return s->bytestream - s->bytestream_start; -} - - -#if CONFIG_PGM_ENCODER -AVCodec pgm_encoder = { - "pgm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PGM, - sizeof(PNMContext), - ff_pnm_init, - pnm_encode_frame, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), -}; -#endif - -#if CONFIG_PGMYUV_ENCODER -AVCodec pgmyuv_encoder = { - "pgmyuv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PGMYUV, - sizeof(PNMContext), - ff_pnm_init, - pnm_encode_frame, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), -}; -#endif - -#if CONFIG_PPM_ENCODER -AVCodec ppm_encoder = { - "ppm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PPM, - sizeof(PNMContext), - ff_pnm_init, - pnm_encode_frame, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB48BE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), -}; -#endif - -#if CONFIG_PBM_ENCODER -AVCodec pbm_encoder = { - "pbm", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PBM, - sizeof(PNMContext), - ff_pnm_init, - pnm_encode_frame, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_MONOWHITE, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/Makefile b/tizen/distrib/ffmpeg/libavcodec/ppc/Makefile deleted file mode 100644 index 5d5a59b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -OBJS += ppc/dsputil_ppc.o \ - -ALTIVEC-OBJS-$(CONFIG_H264DSP) += ppc/h264_altivec.o -ALTIVEC-OBJS-$(CONFIG_VC1_DECODER) += ppc/vc1dsp_altivec.o -ALTIVEC-OBJS-$(CONFIG_VP3_DECODER) += ppc/vp3dsp_altivec.o -ALTIVEC-OBJS-$(CONFIG_VP5_DECODER) += ppc/vp3dsp_altivec.o -ALTIVEC-OBJS-$(CONFIG_VP6_DECODER) += ppc/vp3dsp_altivec.o - -OBJS-$(HAVE_ALTIVEC) += ppc/check_altivec.o \ - ppc/dsputil_altivec.o \ - ppc/fdct_altivec.o \ - ppc/fft_altivec.o \ - ppc/float_altivec.o \ - ppc/gmc_altivec.o \ - ppc/idct_altivec.o \ - ppc/int_altivec.o \ - ppc/mpegvideo_altivec.o \ - $(ALTIVEC-OBJS-yes) diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/check_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/check_altivec.c deleted file mode 100644 index c8bc6ed..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/check_altivec.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -/** - * @file - * Checks for AltiVec presence. - */ - -#ifdef __APPLE__ -#undef _POSIX_C_SOURCE -#include -#elif defined(__OpenBSD__) -#include -#include -#include -#elif defined(__AMIGAOS4__) -#include -#include -#include -#endif /* __APPLE__ */ - -#include "config.h" -#include "dsputil_altivec.h" - -/** - * This function MAY rely on signal() or fork() in order to make sure AltiVec - * is present. - */ - -int has_altivec(void) -{ -#ifdef __AMIGAOS4__ - ULONG result = 0; - extern struct ExecIFace *IExec; - - IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE); - if (result == VECTORTYPE_ALTIVEC) return 1; - return 0; -#elif defined(__APPLE__) || defined(__OpenBSD__) -#ifdef __OpenBSD__ - int sels[2] = {CTL_MACHDEP, CPU_ALTIVEC}; -#else - int sels[2] = {CTL_HW, HW_VECTORUNIT}; -#endif - int has_vu = 0; - size_t len = sizeof(has_vu); - int err; - - err = sysctl(sels, 2, &has_vu, &len, NULL, 0); - - if (err == 0) return has_vu != 0; - return 0; -#elif CONFIG_RUNTIME_CPUDETECT - int proc_ver; - // Support of mfspr PVR emulation added in Linux 2.6.17. - __asm__ volatile("mfspr %0, 287" : "=r" (proc_ver)); - proc_ver >>= 16; - if (proc_ver & 0x8000 || - proc_ver == 0x000c || - proc_ver == 0x0039 || proc_ver == 0x003c || - proc_ver == 0x0044 || proc_ver == 0x0045 || - proc_ver == 0x0070) - return 1; - return 0; -#else - // Since we were compiled for AltiVec, just assume we have it - // until someone comes up with a proper way (not involving signal hacks). - return 1; -#endif /* __AMIGAOS4__ */ -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c deleted file mode 100644 index 925b6c8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c +++ /dev/null @@ -1,1457 +0,0 @@ -/* - * Copyright (c) 2002 Brian Foley - * Copyright (c) 2002 Dieter Shirley - * Copyright (c) 2003-2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif -#include "libavcodec/dsputil.h" -#include "dsputil_ppc.h" -#include "util_altivec.h" -#include "types_altivec.h" -#include "dsputil_altivec.h" - -static int sad16_x2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int i; - int s; - const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); - vector unsigned char *tv; - vector unsigned char pix1v, pix2v, pix2iv, avgv, t5; - vector unsigned int sad; - vector signed int sumdiffs; - - s = 0; - sad = (vector unsigned int)vec_splat_u32(0); - for (i = 0; i < h; i++) { - /* Read unaligned pixels into our vectors. The vectors are as follows: - pix1v: pix1[0]-pix1[15] - pix2v: pix2[0]-pix2[15] pix2iv: pix2[1]-pix2[16] */ - tv = (vector unsigned char *) pix1; - pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1)); - - tv = (vector unsigned char *) &pix2[0]; - pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0])); - - tv = (vector unsigned char *) &pix2[1]; - pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1])); - - /* Calculate the average vector */ - avgv = vec_avg(pix2v, pix2iv); - - /* Calculate a sum of abs differences vector */ - t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv)); - - /* Add each 4 pixel group together and put 4 results into sad */ - sad = vec_sum4s(t5, sad); - - pix1 += line_size; - pix2 += line_size; - } - /* Sum up the four partial sums, and put the result into s */ - sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero); - sumdiffs = vec_splat(sumdiffs, 3); - vec_ste(sumdiffs, 0, &s); - - return s; -} - -static int sad16_y2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int i; - int s; - const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); - vector unsigned char *tv; - vector unsigned char pix1v, pix2v, pix3v, avgv, t5; - vector unsigned int sad; - vector signed int sumdiffs; - uint8_t *pix3 = pix2 + line_size; - - s = 0; - sad = (vector unsigned int)vec_splat_u32(0); - - /* Due to the fact that pix3 = pix2 + line_size, the pix3 of one - iteration becomes pix2 in the next iteration. We can use this - fact to avoid a potentially expensive unaligned read, each - time around the loop. - Read unaligned pixels into our vectors. The vectors are as follows: - pix2v: pix2[0]-pix2[15] - Split the pixel vectors into shorts */ - tv = (vector unsigned char *) &pix2[0]; - pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0])); - - for (i = 0; i < h; i++) { - /* Read unaligned pixels into our vectors. The vectors are as follows: - pix1v: pix1[0]-pix1[15] - pix3v: pix3[0]-pix3[15] */ - tv = (vector unsigned char *) pix1; - pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1)); - - tv = (vector unsigned char *) &pix3[0]; - pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0])); - - /* Calculate the average vector */ - avgv = vec_avg(pix2v, pix3v); - - /* Calculate a sum of abs differences vector */ - t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv)); - - /* Add each 4 pixel group together and put 4 results into sad */ - sad = vec_sum4s(t5, sad); - - pix1 += line_size; - pix2v = pix3v; - pix3 += line_size; - - } - - /* Sum up the four partial sums, and put the result into s */ - sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero); - sumdiffs = vec_splat(sumdiffs, 3); - vec_ste(sumdiffs, 0, &s); - return s; -} - -static int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int i; - int s; - uint8_t *pix3 = pix2 + line_size; - const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); - const vector unsigned short two = (const vector unsigned short)vec_splat_u16(2); - vector unsigned char *tv, avgv, t5; - vector unsigned char pix1v, pix2v, pix3v, pix2iv, pix3iv; - vector unsigned short pix2lv, pix2hv, pix2ilv, pix2ihv; - vector unsigned short pix3lv, pix3hv, pix3ilv, pix3ihv; - vector unsigned short avghv, avglv; - vector unsigned short t1, t2, t3, t4; - vector unsigned int sad; - vector signed int sumdiffs; - - sad = (vector unsigned int)vec_splat_u32(0); - - s = 0; - - /* Due to the fact that pix3 = pix2 + line_size, the pix3 of one - iteration becomes pix2 in the next iteration. We can use this - fact to avoid a potentially expensive unaligned read, as well - as some splitting, and vector addition each time around the loop. - Read unaligned pixels into our vectors. The vectors are as follows: - pix2v: pix2[0]-pix2[15] pix2iv: pix2[1]-pix2[16] - Split the pixel vectors into shorts */ - tv = (vector unsigned char *) &pix2[0]; - pix2v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[0])); - - tv = (vector unsigned char *) &pix2[1]; - pix2iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix2[1])); - - pix2hv = (vector unsigned short) vec_mergeh(zero, pix2v); - pix2lv = (vector unsigned short) vec_mergel(zero, pix2v); - pix2ihv = (vector unsigned short) vec_mergeh(zero, pix2iv); - pix2ilv = (vector unsigned short) vec_mergel(zero, pix2iv); - t1 = vec_add(pix2hv, pix2ihv); - t2 = vec_add(pix2lv, pix2ilv); - - for (i = 0; i < h; i++) { - /* Read unaligned pixels into our vectors. The vectors are as follows: - pix1v: pix1[0]-pix1[15] - pix3v: pix3[0]-pix3[15] pix3iv: pix3[1]-pix3[16] */ - tv = (vector unsigned char *) pix1; - pix1v = vec_perm(tv[0], tv[1], vec_lvsl(0, pix1)); - - tv = (vector unsigned char *) &pix3[0]; - pix3v = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[0])); - - tv = (vector unsigned char *) &pix3[1]; - pix3iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[1])); - - /* Note that AltiVec does have vec_avg, but this works on vector pairs - and rounds up. We could do avg(avg(a,b),avg(c,d)), but the rounding - would mean that, for example, avg(3,0,0,1) = 2, when it should be 1. - Instead, we have to split the pixel vectors into vectors of shorts, - and do the averaging by hand. */ - - /* Split the pixel vectors into shorts */ - pix3hv = (vector unsigned short) vec_mergeh(zero, pix3v); - pix3lv = (vector unsigned short) vec_mergel(zero, pix3v); - pix3ihv = (vector unsigned short) vec_mergeh(zero, pix3iv); - pix3ilv = (vector unsigned short) vec_mergel(zero, pix3iv); - - /* Do the averaging on them */ - t3 = vec_add(pix3hv, pix3ihv); - t4 = vec_add(pix3lv, pix3ilv); - - avghv = vec_sr(vec_add(vec_add(t1, t3), two), two); - avglv = vec_sr(vec_add(vec_add(t2, t4), two), two); - - /* Pack the shorts back into a result */ - avgv = vec_pack(avghv, avglv); - - /* Calculate a sum of abs differences vector */ - t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv)); - - /* Add each 4 pixel group together and put 4 results into sad */ - sad = vec_sum4s(t5, sad); - - pix1 += line_size; - pix3 += line_size; - /* Transfer the calculated values for pix3 into pix2 */ - t1 = t3; - t2 = t4; - } - /* Sum up the four partial sums, and put the result into s */ - sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero); - sumdiffs = vec_splat(sumdiffs, 3); - vec_ste(sumdiffs, 0, &s); - - return s; -} - -static int sad16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int i; - int s; - const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); - vector unsigned char perm1, perm2, *pix1v, *pix2v; - vector unsigned char t1, t2, t3,t4, t5; - vector unsigned int sad; - vector signed int sumdiffs; - - sad = (vector unsigned int)vec_splat_u32(0); - - - for (i = 0; i < h; i++) { - /* Read potentially unaligned pixels into t1 and t2 */ - perm1 = vec_lvsl(0, pix1); - pix1v = (vector unsigned char *) pix1; - perm2 = vec_lvsl(0, pix2); - pix2v = (vector unsigned char *) pix2; - t1 = vec_perm(pix1v[0], pix1v[1], perm1); - t2 = vec_perm(pix2v[0], pix2v[1], perm2); - - /* Calculate a sum of abs differences vector */ - t3 = vec_max(t1, t2); - t4 = vec_min(t1, t2); - t5 = vec_sub(t3, t4); - - /* Add each 4 pixel group together and put 4 results into sad */ - sad = vec_sum4s(t5, sad); - - pix1 += line_size; - pix2 += line_size; - } - - /* Sum up the four partial sums, and put the result into s */ - sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero); - sumdiffs = vec_splat(sumdiffs, 3); - vec_ste(sumdiffs, 0, &s); - - return s; -} - -static int sad8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int i; - int s; - const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); - vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v; - vector unsigned char t1, t2, t3,t4, t5; - vector unsigned int sad; - vector signed int sumdiffs; - - sad = (vector unsigned int)vec_splat_u32(0); - - permclear = (vector unsigned char){255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0}; - - for (i = 0; i < h; i++) { - /* Read potentially unaligned pixels into t1 and t2 - Since we're reading 16 pixels, and actually only want 8, - mask out the last 8 pixels. The 0s don't change the sum. */ - perm1 = vec_lvsl(0, pix1); - pix1v = (vector unsigned char *) pix1; - perm2 = vec_lvsl(0, pix2); - pix2v = (vector unsigned char *) pix2; - t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear); - t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear); - - /* Calculate a sum of abs differences vector */ - t3 = vec_max(t1, t2); - t4 = vec_min(t1, t2); - t5 = vec_sub(t3, t4); - - /* Add each 4 pixel group together and put 4 results into sad */ - sad = vec_sum4s(t5, sad); - - pix1 += line_size; - pix2 += line_size; - } - - /* Sum up the four partial sums, and put the result into s */ - sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero); - sumdiffs = vec_splat(sumdiffs, 3); - vec_ste(sumdiffs, 0, &s); - - return s; -} - -static int pix_norm1_altivec(uint8_t *pix, int line_size) -{ - int i; - int s; - const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); - vector unsigned char *tv; - vector unsigned char pixv; - vector unsigned int sv; - vector signed int sum; - - sv = (vector unsigned int)vec_splat_u32(0); - - s = 0; - for (i = 0; i < 16; i++) { - /* Read in the potentially unaligned pixels */ - tv = (vector unsigned char *) pix; - pixv = vec_perm(tv[0], tv[1], vec_lvsl(0, pix)); - - /* Square the values, and add them to our sum */ - sv = vec_msum(pixv, pixv, sv); - - pix += line_size; - } - /* Sum up the four partial sums, and put the result into s */ - sum = vec_sums((vector signed int) sv, (vector signed int) zero); - sum = vec_splat(sum, 3); - vec_ste(sum, 0, &s); - - return s; -} - -/** - * Sum of Squared Errors for a 8x8 block. - * AltiVec-enhanced. - * It's the sad8_altivec code above w/ squaring added. - */ -static int sse8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int i; - int s; - const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); - vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v; - vector unsigned char t1, t2, t3,t4, t5; - vector unsigned int sum; - vector signed int sumsqr; - - sum = (vector unsigned int)vec_splat_u32(0); - - permclear = (vector unsigned char){255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0}; - - - for (i = 0; i < h; i++) { - /* Read potentially unaligned pixels into t1 and t2 - Since we're reading 16 pixels, and actually only want 8, - mask out the last 8 pixels. The 0s don't change the sum. */ - perm1 = vec_lvsl(0, pix1); - pix1v = (vector unsigned char *) pix1; - perm2 = vec_lvsl(0, pix2); - pix2v = (vector unsigned char *) pix2; - t1 = vec_and(vec_perm(pix1v[0], pix1v[1], perm1), permclear); - t2 = vec_and(vec_perm(pix2v[0], pix2v[1], perm2), permclear); - - /* Since we want to use unsigned chars, we can take advantage - of the fact that abs(a-b)^2 = (a-b)^2. */ - - /* Calculate abs differences vector */ - t3 = vec_max(t1, t2); - t4 = vec_min(t1, t2); - t5 = vec_sub(t3, t4); - - /* Square the values and add them to our sum */ - sum = vec_msum(t5, t5, sum); - - pix1 += line_size; - pix2 += line_size; - } - - /* Sum up the four partial sums, and put the result into s */ - sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero); - sumsqr = vec_splat(sumsqr, 3); - vec_ste(sumsqr, 0, &s); - - return s; -} - -/** - * Sum of Squared Errors for a 16x16 block. - * AltiVec-enhanced. - * It's the sad16_altivec code above w/ squaring added. - */ -static int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int i; - int s; - const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); - vector unsigned char perm1, perm2, *pix1v, *pix2v; - vector unsigned char t1, t2, t3,t4, t5; - vector unsigned int sum; - vector signed int sumsqr; - - sum = (vector unsigned int)vec_splat_u32(0); - - for (i = 0; i < h; i++) { - /* Read potentially unaligned pixels into t1 and t2 */ - perm1 = vec_lvsl(0, pix1); - pix1v = (vector unsigned char *) pix1; - perm2 = vec_lvsl(0, pix2); - pix2v = (vector unsigned char *) pix2; - t1 = vec_perm(pix1v[0], pix1v[1], perm1); - t2 = vec_perm(pix2v[0], pix2v[1], perm2); - - /* Since we want to use unsigned chars, we can take advantage - of the fact that abs(a-b)^2 = (a-b)^2. */ - - /* Calculate abs differences vector */ - t3 = vec_max(t1, t2); - t4 = vec_min(t1, t2); - t5 = vec_sub(t3, t4); - - /* Square the values and add them to our sum */ - sum = vec_msum(t5, t5, sum); - - pix1 += line_size; - pix2 += line_size; - } - - /* Sum up the four partial sums, and put the result into s */ - sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero); - sumsqr = vec_splat(sumsqr, 3); - vec_ste(sumsqr, 0, &s); - - return s; -} - -static int pix_sum_altivec(uint8_t * pix, int line_size) -{ - const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); - vector unsigned char perm, *pixv; - vector unsigned char t1; - vector unsigned int sad; - vector signed int sumdiffs; - - int i; - int s; - - sad = (vector unsigned int)vec_splat_u32(0); - - for (i = 0; i < 16; i++) { - /* Read the potentially unaligned 16 pixels into t1 */ - perm = vec_lvsl(0, pix); - pixv = (vector unsigned char *) pix; - t1 = vec_perm(pixv[0], pixv[1], perm); - - /* Add each 4 pixel group together and put 4 results into sad */ - sad = vec_sum4s(t1, sad); - - pix += line_size; - } - - /* Sum up the four partial sums, and put the result into s */ - sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero); - sumdiffs = vec_splat(sumdiffs, 3); - vec_ste(sumdiffs, 0, &s); - - return s; -} - -static void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line_size) -{ - int i; - vector unsigned char perm, bytes, *pixv; - const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); - vector signed short shorts; - - for (i = 0; i < 8; i++) { - // Read potentially unaligned pixels. - // We're reading 16 pixels, and actually only want 8, - // but we simply ignore the extras. - perm = vec_lvsl(0, pixels); - pixv = (vector unsigned char *) pixels; - bytes = vec_perm(pixv[0], pixv[1], perm); - - // convert the bytes into shorts - shorts = (vector signed short)vec_mergeh(zero, bytes); - - // save the data to the block, we assume the block is 16-byte aligned - vec_st(shorts, i*16, (vector signed short*)block); - - pixels += line_size; - } -} - -static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1, - const uint8_t *s2, int stride) -{ - int i; - vector unsigned char perm, bytes, *pixv; - const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); - vector signed short shorts1, shorts2; - - for (i = 0; i < 4; i++) { - // Read potentially unaligned pixels - // We're reading 16 pixels, and actually only want 8, - // but we simply ignore the extras. - perm = vec_lvsl(0, s1); - pixv = (vector unsigned char *) s1; - bytes = vec_perm(pixv[0], pixv[1], perm); - - // convert the bytes into shorts - shorts1 = (vector signed short)vec_mergeh(zero, bytes); - - // Do the same for the second block of pixels - perm = vec_lvsl(0, s2); - pixv = (vector unsigned char *) s2; - bytes = vec_perm(pixv[0], pixv[1], perm); - - // convert the bytes into shorts - shorts2 = (vector signed short)vec_mergeh(zero, bytes); - - // Do the subtraction - shorts1 = vec_sub(shorts1, shorts2); - - // save the data to the block, we assume the block is 16-byte aligned - vec_st(shorts1, 0, (vector signed short*)block); - - s1 += stride; - s2 += stride; - block += 8; - - - // The code below is a copy of the code above... This is a manual - // unroll. - - // Read potentially unaligned pixels - // We're reading 16 pixels, and actually only want 8, - // but we simply ignore the extras. - perm = vec_lvsl(0, s1); - pixv = (vector unsigned char *) s1; - bytes = vec_perm(pixv[0], pixv[1], perm); - - // convert the bytes into shorts - shorts1 = (vector signed short)vec_mergeh(zero, bytes); - - // Do the same for the second block of pixels - perm = vec_lvsl(0, s2); - pixv = (vector unsigned char *) s2; - bytes = vec_perm(pixv[0], pixv[1], perm); - - // convert the bytes into shorts - shorts2 = (vector signed short)vec_mergeh(zero, bytes); - - // Do the subtraction - shorts1 = vec_sub(shorts1, shorts2); - - // save the data to the block, we assume the block is 16-byte aligned - vec_st(shorts1, 0, (vector signed short*)block); - - s1 += stride; - s2 += stride; - block += 8; - } -} - - -static void clear_block_altivec(DCTELEM *block) { - LOAD_ZERO; - vec_st(zero_s16v, 0, block); - vec_st(zero_s16v, 16, block); - vec_st(zero_s16v, 32, block); - vec_st(zero_s16v, 48, block); - vec_st(zero_s16v, 64, block); - vec_st(zero_s16v, 80, block); - vec_st(zero_s16v, 96, block); - vec_st(zero_s16v, 112, block); -} - - -static void add_bytes_altivec(uint8_t *dst, uint8_t *src, int w) { - register int i; - register vector unsigned char vdst, vsrc; - - /* dst and src are 16 bytes-aligned (guaranteed) */ - for (i = 0 ; (i + 15) < w ; i+=16) { - vdst = vec_ld(i, (unsigned char*)dst); - vsrc = vec_ld(i, (unsigned char*)src); - vdst = vec_add(vsrc, vdst); - vec_st(vdst, i, (unsigned char*)dst); - } - /* if w is not a multiple of 16 */ - for (; (i < w) ; i++) { - dst[i] = src[i]; - } -} - -/* next one assumes that ((line_size % 16) == 0) */ -void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_put_pixels16_num, 1); - register vector unsigned char pixelsv1, pixelsv2; - register vector unsigned char pixelsv1B, pixelsv2B; - register vector unsigned char pixelsv1C, pixelsv2C; - register vector unsigned char pixelsv1D, pixelsv2D; - - register vector unsigned char perm = vec_lvsl(0, pixels); - int i; - register int line_size_2 = line_size << 1; - register int line_size_3 = line_size + line_size_2; - register int line_size_4 = line_size << 2; - -POWERPC_PERF_START_COUNT(altivec_put_pixels16_num, 1); -// hand-unrolling the loop by 4 gains about 15% -// mininum execution time goes from 74 to 60 cycles -// it's faster than -funroll-loops, but using -// -funroll-loops w/ this is bad - 74 cycles again. -// all this is on a 7450, tuning for the 7450 -#if 0 - for (i = 0; i < h; i++) { - pixelsv1 = vec_ld(0, pixels); - pixelsv2 = vec_ld(16, pixels); - vec_st(vec_perm(pixelsv1, pixelsv2, perm), - 0, block); - pixels+=line_size; - block +=line_size; - } -#else - for (i = 0; i < h; i += 4) { - pixelsv1 = vec_ld( 0, pixels); - pixelsv2 = vec_ld(15, pixels); - pixelsv1B = vec_ld(line_size, pixels); - pixelsv2B = vec_ld(15 + line_size, pixels); - pixelsv1C = vec_ld(line_size_2, pixels); - pixelsv2C = vec_ld(15 + line_size_2, pixels); - pixelsv1D = vec_ld(line_size_3, pixels); - pixelsv2D = vec_ld(15 + line_size_3, pixels); - vec_st(vec_perm(pixelsv1, pixelsv2, perm), - 0, (unsigned char*)block); - vec_st(vec_perm(pixelsv1B, pixelsv2B, perm), - line_size, (unsigned char*)block); - vec_st(vec_perm(pixelsv1C, pixelsv2C, perm), - line_size_2, (unsigned char*)block); - vec_st(vec_perm(pixelsv1D, pixelsv2D, perm), - line_size_3, (unsigned char*)block); - pixels+=line_size_4; - block +=line_size_4; - } -#endif -POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_num, 1); -} - -/* next one assumes that ((line_size % 16) == 0) */ -#define op_avg(a,b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) ) -void avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_avg_pixels16_num, 1); - register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv; - register vector unsigned char perm = vec_lvsl(0, pixels); - int i; - -POWERPC_PERF_START_COUNT(altivec_avg_pixels16_num, 1); - - for (i = 0; i < h; i++) { - pixelsv1 = vec_ld( 0, pixels); - pixelsv2 = vec_ld(16,pixels); - blockv = vec_ld(0, block); - pixelsv = vec_perm(pixelsv1, pixelsv2, perm); - blockv = vec_avg(blockv,pixelsv); - vec_st(blockv, 0, (unsigned char*)block); - pixels+=line_size; - block +=line_size; - } - -POWERPC_PERF_STOP_COUNT(altivec_avg_pixels16_num, 1); -} - -/* next one assumes that ((line_size % 8) == 0) */ -static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_avg_pixels8_num, 1); - register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv; - int i; - -POWERPC_PERF_START_COUNT(altivec_avg_pixels8_num, 1); - - for (i = 0; i < h; i++) { - /* block is 8 bytes-aligned, so we're either in the - left block (16 bytes-aligned) or in the right block (not) */ - int rightside = ((unsigned long)block & 0x0000000F); - - blockv = vec_ld(0, block); - pixelsv1 = vec_ld( 0, pixels); - pixelsv2 = vec_ld(16, pixels); - pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels)); - - if (rightside) { - pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1)); - } else { - pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3)); - } - - blockv = vec_avg(blockv, pixelsv); - - vec_st(blockv, 0, block); - - pixels += line_size; - block += line_size; - } - -POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_num, 1); -} - -/* next one assumes that ((line_size % 8) == 0) */ -static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_put_pixels8_xy2_num, 1); - register int i; - register vector unsigned char pixelsv1, pixelsv2, pixelsavg; - register vector unsigned char blockv, temp1, temp2; - register vector unsigned short pixelssum1, pixelssum2, temp3; - register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); - register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); - - temp1 = vec_ld(0, pixels); - temp2 = vec_ld(16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); - if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); - } - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum1 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - pixelssum1 = vec_add(pixelssum1, vctwo); - -POWERPC_PERF_START_COUNT(altivec_put_pixels8_xy2_num, 1); - for (i = 0; i < h ; i++) { - int rightside = ((unsigned long)block & 0x0000000F); - blockv = vec_ld(0, block); - - temp1 = vec_ld(line_size, pixels); - temp2 = vec_ld(line_size + 16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); - if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); - } - - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum2 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - temp3 = vec_add(pixelssum1, pixelssum2); - temp3 = vec_sra(temp3, vctwo); - pixelssum1 = vec_add(pixelssum2, vctwo); - pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero); - - if (rightside) { - blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1)); - } else { - blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3)); - } - - vec_st(blockv, 0, block); - - block += line_size; - pixels += line_size; - } - -POWERPC_PERF_STOP_COUNT(altivec_put_pixels8_xy2_num, 1); -} - -/* next one assumes that ((line_size % 8) == 0) */ -static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels8_xy2_num, 1); - register int i; - register vector unsigned char pixelsv1, pixelsv2, pixelsavg; - register vector unsigned char blockv, temp1, temp2; - register vector unsigned short pixelssum1, pixelssum2, temp3; - register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); - register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1); - register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); - - temp1 = vec_ld(0, pixels); - temp2 = vec_ld(16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); - if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); - } - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum1 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - pixelssum1 = vec_add(pixelssum1, vcone); - -POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1); - for (i = 0; i < h ; i++) { - int rightside = ((unsigned long)block & 0x0000000F); - blockv = vec_ld(0, block); - - temp1 = vec_ld(line_size, pixels); - temp2 = vec_ld(line_size + 16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); - if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); - } - - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum2 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - temp3 = vec_add(pixelssum1, pixelssum2); - temp3 = vec_sra(temp3, vctwo); - pixelssum1 = vec_add(pixelssum2, vcone); - pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero); - - if (rightside) { - blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1)); - } else { - blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3)); - } - - vec_st(blockv, 0, block); - - block += line_size; - pixels += line_size; - } - -POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1); -} - -/* next one assumes that ((line_size % 16) == 0) */ -static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_put_pixels16_xy2_num, 1); - register int i; - register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4; - register vector unsigned char blockv, temp1, temp2; - register vector unsigned short temp3, temp4, - pixelssum1, pixelssum2, pixelssum3, pixelssum4; - register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); - register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); - -POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1); - - temp1 = vec_ld(0, pixels); - temp2 = vec_ld(16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); - if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); - } - pixelsv3 = vec_mergel(vczero, pixelsv1); - pixelsv4 = vec_mergel(vczero, pixelsv2); - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum3 = vec_add((vector unsigned short)pixelsv3, - (vector unsigned short)pixelsv4); - pixelssum3 = vec_add(pixelssum3, vctwo); - pixelssum1 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - pixelssum1 = vec_add(pixelssum1, vctwo); - - for (i = 0; i < h ; i++) { - blockv = vec_ld(0, block); - - temp1 = vec_ld(line_size, pixels); - temp2 = vec_ld(line_size + 16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); - if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); - } - - pixelsv3 = vec_mergel(vczero, pixelsv1); - pixelsv4 = vec_mergel(vczero, pixelsv2); - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - - pixelssum4 = vec_add((vector unsigned short)pixelsv3, - (vector unsigned short)pixelsv4); - pixelssum2 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - temp4 = vec_add(pixelssum3, pixelssum4); - temp4 = vec_sra(temp4, vctwo); - temp3 = vec_add(pixelssum1, pixelssum2); - temp3 = vec_sra(temp3, vctwo); - - pixelssum3 = vec_add(pixelssum4, vctwo); - pixelssum1 = vec_add(pixelssum2, vctwo); - - blockv = vec_packsu(temp3, temp4); - - vec_st(blockv, 0, block); - - block += line_size; - pixels += line_size; - } - -POWERPC_PERF_STOP_COUNT(altivec_put_pixels16_xy2_num, 1); -} - -/* next one assumes that ((line_size % 16) == 0) */ -static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels16_xy2_num, 1); - register int i; - register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4; - register vector unsigned char blockv, temp1, temp2; - register vector unsigned short temp3, temp4, - pixelssum1, pixelssum2, pixelssum3, pixelssum4; - register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); - register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1); - register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); - -POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1); - - temp1 = vec_ld(0, pixels); - temp2 = vec_ld(16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); - if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); - } - pixelsv3 = vec_mergel(vczero, pixelsv1); - pixelsv4 = vec_mergel(vczero, pixelsv2); - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum3 = vec_add((vector unsigned short)pixelsv3, - (vector unsigned short)pixelsv4); - pixelssum3 = vec_add(pixelssum3, vcone); - pixelssum1 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - pixelssum1 = vec_add(pixelssum1, vcone); - - for (i = 0; i < h ; i++) { - blockv = vec_ld(0, block); - - temp1 = vec_ld(line_size, pixels); - temp2 = vec_ld(line_size + 16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); - if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); - } - - pixelsv3 = vec_mergel(vczero, pixelsv1); - pixelsv4 = vec_mergel(vczero, pixelsv2); - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - - pixelssum4 = vec_add((vector unsigned short)pixelsv3, - (vector unsigned short)pixelsv4); - pixelssum2 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - temp4 = vec_add(pixelssum3, pixelssum4); - temp4 = vec_sra(temp4, vctwo); - temp3 = vec_add(pixelssum1, pixelssum2); - temp3 = vec_sra(temp3, vctwo); - - pixelssum3 = vec_add(pixelssum4, vcone); - pixelssum1 = vec_add(pixelssum2, vcone); - - blockv = vec_packsu(temp3, temp4); - - vec_st(blockv, 0, block); - - block += line_size; - pixels += line_size; - } - -POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1); -} - -static int hadamard8_diff8x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){ -POWERPC_PERF_DECLARE(altivec_hadamard8_diff8x8_num, 1); - int sum; - register const vector unsigned char vzero = - (const vector unsigned char)vec_splat_u8(0); - register vector signed short temp0, temp1, temp2, temp3, temp4, - temp5, temp6, temp7; -POWERPC_PERF_START_COUNT(altivec_hadamard8_diff8x8_num, 1); - { - register const vector signed short vprod1 =(const vector signed short) - { 1,-1, 1,-1, 1,-1, 1,-1 }; - register const vector signed short vprod2 =(const vector signed short) - { 1, 1,-1,-1, 1, 1,-1,-1 }; - register const vector signed short vprod3 =(const vector signed short) - { 1, 1, 1, 1,-1,-1,-1,-1 }; - register const vector unsigned char perm1 = (const vector unsigned char) - {0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, - 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D}; - register const vector unsigned char perm2 = (const vector unsigned char) - {0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, - 0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B}; - register const vector unsigned char perm3 = (const vector unsigned char) - {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; - -#define ONEITERBUTTERFLY(i, res) \ - { \ - register vector unsigned char src1, src2, srcO; \ - register vector unsigned char dst1, dst2, dstO; \ - register vector signed short srcV, dstV; \ - register vector signed short but0, but1, but2, op1, op2, op3; \ - src1 = vec_ld(stride * i, src); \ - src2 = vec_ld((stride * i) + 15, src); \ - srcO = vec_perm(src1, src2, vec_lvsl(stride * i, src)); \ - dst1 = vec_ld(stride * i, dst); \ - dst2 = vec_ld((stride * i) + 15, dst); \ - dstO = vec_perm(dst1, dst2, vec_lvsl(stride * i, dst)); \ - /* promote the unsigned chars to signed shorts */ \ - /* we're in the 8x8 function, we only care for the first 8 */ \ - srcV = (vector signed short)vec_mergeh((vector signed char)vzero, \ - (vector signed char)srcO); \ - dstV = (vector signed short)vec_mergeh((vector signed char)vzero, \ - (vector signed char)dstO); \ - /* subtractions inside the first butterfly */ \ - but0 = vec_sub(srcV, dstV); \ - op1 = vec_perm(but0, but0, perm1); \ - but1 = vec_mladd(but0, vprod1, op1); \ - op2 = vec_perm(but1, but1, perm2); \ - but2 = vec_mladd(but1, vprod2, op2); \ - op3 = vec_perm(but2, but2, perm3); \ - res = vec_mladd(but2, vprod3, op3); \ - } - ONEITERBUTTERFLY(0, temp0); - ONEITERBUTTERFLY(1, temp1); - ONEITERBUTTERFLY(2, temp2); - ONEITERBUTTERFLY(3, temp3); - ONEITERBUTTERFLY(4, temp4); - ONEITERBUTTERFLY(5, temp5); - ONEITERBUTTERFLY(6, temp6); - ONEITERBUTTERFLY(7, temp7); - } -#undef ONEITERBUTTERFLY - { - register vector signed int vsum; - register vector signed short line0 = vec_add(temp0, temp1); - register vector signed short line1 = vec_sub(temp0, temp1); - register vector signed short line2 = vec_add(temp2, temp3); - register vector signed short line3 = vec_sub(temp2, temp3); - register vector signed short line4 = vec_add(temp4, temp5); - register vector signed short line5 = vec_sub(temp4, temp5); - register vector signed short line6 = vec_add(temp6, temp7); - register vector signed short line7 = vec_sub(temp6, temp7); - - register vector signed short line0B = vec_add(line0, line2); - register vector signed short line2B = vec_sub(line0, line2); - register vector signed short line1B = vec_add(line1, line3); - register vector signed short line3B = vec_sub(line1, line3); - register vector signed short line4B = vec_add(line4, line6); - register vector signed short line6B = vec_sub(line4, line6); - register vector signed short line5B = vec_add(line5, line7); - register vector signed short line7B = vec_sub(line5, line7); - - register vector signed short line0C = vec_add(line0B, line4B); - register vector signed short line4C = vec_sub(line0B, line4B); - register vector signed short line1C = vec_add(line1B, line5B); - register vector signed short line5C = vec_sub(line1B, line5B); - register vector signed short line2C = vec_add(line2B, line6B); - register vector signed short line6C = vec_sub(line2B, line6B); - register vector signed short line3C = vec_add(line3B, line7B); - register vector signed short line7C = vec_sub(line3B, line7B); - - vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0)); - vsum = vec_sum4s(vec_abs(line1C), vsum); - vsum = vec_sum4s(vec_abs(line2C), vsum); - vsum = vec_sum4s(vec_abs(line3C), vsum); - vsum = vec_sum4s(vec_abs(line4C), vsum); - vsum = vec_sum4s(vec_abs(line5C), vsum); - vsum = vec_sum4s(vec_abs(line6C), vsum); - vsum = vec_sum4s(vec_abs(line7C), vsum); - vsum = vec_sums(vsum, (vector signed int)vzero); - vsum = vec_splat(vsum, 3); - vec_ste(vsum, 0, &sum); - } -POWERPC_PERF_STOP_COUNT(altivec_hadamard8_diff8x8_num, 1); - return sum; -} - -/* -16x8 works with 16 elements; it allows to avoid replicating loads, and -give the compiler more rooms for scheduling. It's only used from -inside hadamard8_diff16_altivec. - -Unfortunately, it seems gcc-3.3 is a bit dumb, and the compiled code has a LOT -of spill code, it seems gcc (unlike xlc) cannot keep everything in registers -by itself. The following code include hand-made registers allocation. It's not -clean, but on a 7450 the resulting code is much faster (best case fall from -700+ cycles to 550). - -xlc doesn't add spill code, but it doesn't know how to schedule for the 7450, -and its code isn't much faster than gcc-3.3 on the 7450 (but uses 25% less -instructions...) - -On the 970, the hand-made RA is still a win (around 690 vs. around 780), but -xlc goes to around 660 on the regular C code... -*/ - -static int hadamard8_diff16x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h) { - int sum; - register vector signed short - temp0 __asm__ ("v0"), - temp1 __asm__ ("v1"), - temp2 __asm__ ("v2"), - temp3 __asm__ ("v3"), - temp4 __asm__ ("v4"), - temp5 __asm__ ("v5"), - temp6 __asm__ ("v6"), - temp7 __asm__ ("v7"); - register vector signed short - temp0S __asm__ ("v8"), - temp1S __asm__ ("v9"), - temp2S __asm__ ("v10"), - temp3S __asm__ ("v11"), - temp4S __asm__ ("v12"), - temp5S __asm__ ("v13"), - temp6S __asm__ ("v14"), - temp7S __asm__ ("v15"); - register const vector unsigned char vzero __asm__ ("v31") = - (const vector unsigned char)vec_splat_u8(0); - { - register const vector signed short vprod1 __asm__ ("v16") = - (const vector signed short){ 1,-1, 1,-1, 1,-1, 1,-1 }; - register const vector signed short vprod2 __asm__ ("v17") = - (const vector signed short){ 1, 1,-1,-1, 1, 1,-1,-1 }; - register const vector signed short vprod3 __asm__ ("v18") = - (const vector signed short){ 1, 1, 1, 1,-1,-1,-1,-1 }; - register const vector unsigned char perm1 __asm__ ("v19") = - (const vector unsigned char) - {0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, - 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D}; - register const vector unsigned char perm2 __asm__ ("v20") = - (const vector unsigned char) - {0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, - 0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B}; - register const vector unsigned char perm3 __asm__ ("v21") = - (const vector unsigned char) - {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; - -#define ONEITERBUTTERFLY(i, res1, res2) \ - { \ - register vector unsigned char src1 __asm__ ("v22"), \ - src2 __asm__ ("v23"), \ - dst1 __asm__ ("v24"), \ - dst2 __asm__ ("v25"), \ - srcO __asm__ ("v22"), \ - dstO __asm__ ("v23"); \ - \ - register vector signed short srcV __asm__ ("v24"), \ - dstV __asm__ ("v25"), \ - srcW __asm__ ("v26"), \ - dstW __asm__ ("v27"), \ - but0 __asm__ ("v28"), \ - but0S __asm__ ("v29"), \ - op1 __asm__ ("v30"), \ - but1 __asm__ ("v22"), \ - op1S __asm__ ("v23"), \ - but1S __asm__ ("v24"), \ - op2 __asm__ ("v25"), \ - but2 __asm__ ("v26"), \ - op2S __asm__ ("v27"), \ - but2S __asm__ ("v28"), \ - op3 __asm__ ("v29"), \ - op3S __asm__ ("v30"); \ - \ - src1 = vec_ld(stride * i, src); \ - src2 = vec_ld((stride * i) + 16, src); \ - srcO = vec_perm(src1, src2, vec_lvsl(stride * i, src)); \ - dst1 = vec_ld(stride * i, dst); \ - dst2 = vec_ld((stride * i) + 16, dst); \ - dstO = vec_perm(dst1, dst2, vec_lvsl(stride * i, dst)); \ - /* promote the unsigned chars to signed shorts */ \ - srcV = (vector signed short)vec_mergeh((vector signed char)vzero, \ - (vector signed char)srcO); \ - dstV = (vector signed short)vec_mergeh((vector signed char)vzero, \ - (vector signed char)dstO); \ - srcW = (vector signed short)vec_mergel((vector signed char)vzero, \ - (vector signed char)srcO); \ - dstW = (vector signed short)vec_mergel((vector signed char)vzero, \ - (vector signed char)dstO); \ - /* subtractions inside the first butterfly */ \ - but0 = vec_sub(srcV, dstV); \ - but0S = vec_sub(srcW, dstW); \ - op1 = vec_perm(but0, but0, perm1); \ - but1 = vec_mladd(but0, vprod1, op1); \ - op1S = vec_perm(but0S, but0S, perm1); \ - but1S = vec_mladd(but0S, vprod1, op1S); \ - op2 = vec_perm(but1, but1, perm2); \ - but2 = vec_mladd(but1, vprod2, op2); \ - op2S = vec_perm(but1S, but1S, perm2); \ - but2S = vec_mladd(but1S, vprod2, op2S); \ - op3 = vec_perm(but2, but2, perm3); \ - res1 = vec_mladd(but2, vprod3, op3); \ - op3S = vec_perm(but2S, but2S, perm3); \ - res2 = vec_mladd(but2S, vprod3, op3S); \ - } - ONEITERBUTTERFLY(0, temp0, temp0S); - ONEITERBUTTERFLY(1, temp1, temp1S); - ONEITERBUTTERFLY(2, temp2, temp2S); - ONEITERBUTTERFLY(3, temp3, temp3S); - ONEITERBUTTERFLY(4, temp4, temp4S); - ONEITERBUTTERFLY(5, temp5, temp5S); - ONEITERBUTTERFLY(6, temp6, temp6S); - ONEITERBUTTERFLY(7, temp7, temp7S); - } -#undef ONEITERBUTTERFLY - { - register vector signed int vsum; - register vector signed short line0S, line1S, line2S, line3S, line4S, - line5S, line6S, line7S, line0BS,line2BS, - line1BS,line3BS,line4BS,line6BS,line5BS, - line7BS,line0CS,line4CS,line1CS,line5CS, - line2CS,line6CS,line3CS,line7CS; - - register vector signed short line0 = vec_add(temp0, temp1); - register vector signed short line1 = vec_sub(temp0, temp1); - register vector signed short line2 = vec_add(temp2, temp3); - register vector signed short line3 = vec_sub(temp2, temp3); - register vector signed short line4 = vec_add(temp4, temp5); - register vector signed short line5 = vec_sub(temp4, temp5); - register vector signed short line6 = vec_add(temp6, temp7); - register vector signed short line7 = vec_sub(temp6, temp7); - - register vector signed short line0B = vec_add(line0, line2); - register vector signed short line2B = vec_sub(line0, line2); - register vector signed short line1B = vec_add(line1, line3); - register vector signed short line3B = vec_sub(line1, line3); - register vector signed short line4B = vec_add(line4, line6); - register vector signed short line6B = vec_sub(line4, line6); - register vector signed short line5B = vec_add(line5, line7); - register vector signed short line7B = vec_sub(line5, line7); - - register vector signed short line0C = vec_add(line0B, line4B); - register vector signed short line4C = vec_sub(line0B, line4B); - register vector signed short line1C = vec_add(line1B, line5B); - register vector signed short line5C = vec_sub(line1B, line5B); - register vector signed short line2C = vec_add(line2B, line6B); - register vector signed short line6C = vec_sub(line2B, line6B); - register vector signed short line3C = vec_add(line3B, line7B); - register vector signed short line7C = vec_sub(line3B, line7B); - - vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0)); - vsum = vec_sum4s(vec_abs(line1C), vsum); - vsum = vec_sum4s(vec_abs(line2C), vsum); - vsum = vec_sum4s(vec_abs(line3C), vsum); - vsum = vec_sum4s(vec_abs(line4C), vsum); - vsum = vec_sum4s(vec_abs(line5C), vsum); - vsum = vec_sum4s(vec_abs(line6C), vsum); - vsum = vec_sum4s(vec_abs(line7C), vsum); - - line0S = vec_add(temp0S, temp1S); - line1S = vec_sub(temp0S, temp1S); - line2S = vec_add(temp2S, temp3S); - line3S = vec_sub(temp2S, temp3S); - line4S = vec_add(temp4S, temp5S); - line5S = vec_sub(temp4S, temp5S); - line6S = vec_add(temp6S, temp7S); - line7S = vec_sub(temp6S, temp7S); - - line0BS = vec_add(line0S, line2S); - line2BS = vec_sub(line0S, line2S); - line1BS = vec_add(line1S, line3S); - line3BS = vec_sub(line1S, line3S); - line4BS = vec_add(line4S, line6S); - line6BS = vec_sub(line4S, line6S); - line5BS = vec_add(line5S, line7S); - line7BS = vec_sub(line5S, line7S); - - line0CS = vec_add(line0BS, line4BS); - line4CS = vec_sub(line0BS, line4BS); - line1CS = vec_add(line1BS, line5BS); - line5CS = vec_sub(line1BS, line5BS); - line2CS = vec_add(line2BS, line6BS); - line6CS = vec_sub(line2BS, line6BS); - line3CS = vec_add(line3BS, line7BS); - line7CS = vec_sub(line3BS, line7BS); - - vsum = vec_sum4s(vec_abs(line0CS), vsum); - vsum = vec_sum4s(vec_abs(line1CS), vsum); - vsum = vec_sum4s(vec_abs(line2CS), vsum); - vsum = vec_sum4s(vec_abs(line3CS), vsum); - vsum = vec_sum4s(vec_abs(line4CS), vsum); - vsum = vec_sum4s(vec_abs(line5CS), vsum); - vsum = vec_sum4s(vec_abs(line6CS), vsum); - vsum = vec_sum4s(vec_abs(line7CS), vsum); - vsum = vec_sums(vsum, (vector signed int)vzero); - vsum = vec_splat(vsum, 3); - vec_ste(vsum, 0, &sum); - } - return sum; -} - -static int hadamard8_diff16_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){ -POWERPC_PERF_DECLARE(altivec_hadamard8_diff16_num, 1); - int score; -POWERPC_PERF_START_COUNT(altivec_hadamard8_diff16_num, 1); - score = hadamard8_diff16x8_altivec(s, dst, src, stride, 8); - if (h==16) { - dst += 8*stride; - src += 8*stride; - score += hadamard8_diff16x8_altivec(s, dst, src, stride, 8); - } -POWERPC_PERF_STOP_COUNT(altivec_hadamard8_diff16_num, 1); - return score; -} - -static void vorbis_inverse_coupling_altivec(float *mag, float *ang, - int blocksize) -{ - int i; - vector float m, a; - vector bool int t0, t1; - const vector unsigned int v_31 = //XXX - vec_add(vec_add(vec_splat_u32(15),vec_splat_u32(15)),vec_splat_u32(1)); - for (i = 0; i < blocksize; i += 4) { - m = vec_ld(0, mag+i); - a = vec_ld(0, ang+i); - t0 = vec_cmple(m, (vector float)vec_splat_u32(0)); - t1 = vec_cmple(a, (vector float)vec_splat_u32(0)); - a = vec_xor(a, (vector float) vec_sl((vector unsigned int)t0, v_31)); - t0 = (vector bool int)vec_and(a, t1); - t1 = (vector bool int)vec_andc(a, t1); - a = vec_sub(m, (vector float)t1); - m = vec_add(m, (vector float)t0); - vec_stl(a, 0, ang+i); - vec_stl(m, 0, mag+i); - } -} - -/* next one assumes that ((line_size % 8) == 0) */ -static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ -POWERPC_PERF_DECLARE(altivec_avg_pixels8_xy2_num, 1); - register int i; - register vector unsigned char pixelsv1, pixelsv2, pixelsavg; - register vector unsigned char blockv, temp1, temp2, blocktemp; - register vector unsigned short pixelssum1, pixelssum2, temp3; - - register const vector unsigned char vczero = (const vector unsigned char) - vec_splat_u8(0); - register const vector unsigned short vctwo = (const vector unsigned short) - vec_splat_u16(2); - - temp1 = vec_ld(0, pixels); - temp2 = vec_ld(16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels)); - if ((((unsigned long)pixels) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels)); - } - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum1 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - pixelssum1 = vec_add(pixelssum1, vctwo); - -POWERPC_PERF_START_COUNT(altivec_avg_pixels8_xy2_num, 1); - for (i = 0; i < h ; i++) { - int rightside = ((unsigned long)block & 0x0000000F); - blockv = vec_ld(0, block); - - temp1 = vec_ld(line_size, pixels); - temp2 = vec_ld(line_size + 16, pixels); - pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels)); - if (((((unsigned long)pixels) + line_size) & 0x0000000F) == 0x0000000F) { - pixelsv2 = temp2; - } else { - pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels)); - } - - pixelsv1 = vec_mergeh(vczero, pixelsv1); - pixelsv2 = vec_mergeh(vczero, pixelsv2); - pixelssum2 = vec_add((vector unsigned short)pixelsv1, - (vector unsigned short)pixelsv2); - temp3 = vec_add(pixelssum1, pixelssum2); - temp3 = vec_sra(temp3, vctwo); - pixelssum1 = vec_add(pixelssum2, vctwo); - pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero); - - if (rightside) { - blocktemp = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1)); - } else { - blocktemp = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3)); - } - - blockv = vec_avg(blocktemp, blockv); - vec_st(blockv, 0, block); - - block += line_size; - pixels += line_size; - } - -POWERPC_PERF_STOP_COUNT(altivec_avg_pixels8_xy2_num, 1); -} - -void dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx) -{ - c->pix_abs[0][1] = sad16_x2_altivec; - c->pix_abs[0][2] = sad16_y2_altivec; - c->pix_abs[0][3] = sad16_xy2_altivec; - c->pix_abs[0][0] = sad16_altivec; - c->pix_abs[1][0] = sad8_altivec; - c->sad[0]= sad16_altivec; - c->sad[1]= sad8_altivec; - c->pix_norm1 = pix_norm1_altivec; - c->sse[1]= sse8_altivec; - c->sse[0]= sse16_altivec; - c->pix_sum = pix_sum_altivec; - c->diff_pixels = diff_pixels_altivec; - c->get_pixels = get_pixels_altivec; - c->clear_block = clear_block_altivec; - c->add_bytes= add_bytes_altivec; - c->put_pixels_tab[0][0] = put_pixels16_altivec; - /* the two functions do the same thing, so use the same code */ - c->put_no_rnd_pixels_tab[0][0] = put_pixels16_altivec; - c->avg_pixels_tab[0][0] = avg_pixels16_altivec; - c->avg_pixels_tab[1][0] = avg_pixels8_altivec; - c->avg_pixels_tab[1][3] = avg_pixels8_xy2_altivec; - c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec; - c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec; - c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec; - c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec; - - c->hadamard8_diff[0] = hadamard8_diff16_altivec; - c->hadamard8_diff[1] = hadamard8_diff8x8_altivec; - if (CONFIG_VORBIS_DECODER) - c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h b/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h deleted file mode 100644 index 18f8dd8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2002 Brian Foley - * Copyright (c) 2002 Dieter Shirley - * Copyright (c) 2003-2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PPC_DSPUTIL_ALTIVEC_H -#define AVCODEC_PPC_DSPUTIL_ALTIVEC_H - -#include -#include "libavcodec/dsputil.h" - -void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h); - -void avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h); - -int has_altivec(void); - -void fdct_altivec(int16_t *block); -void gmc1_altivec(uint8_t *dst, uint8_t *src, int stride, int h, - int x16, int y16, int rounder); -void idct_put_altivec(uint8_t *dest, int line_size, int16_t *block); -void idct_add_altivec(uint8_t *dest, int line_size, int16_t *block); - -void ff_vp3_idct_altivec(DCTELEM *block); -void ff_vp3_idct_put_altivec(uint8_t *dest, int line_size, DCTELEM *block); -void ff_vp3_idct_add_altivec(uint8_t *dest, int line_size, DCTELEM *block); - -void dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx); - -void dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx); -void vc1dsp_init_altivec(DSPContext* c, AVCodecContext *avctx); -void float_init_altivec(DSPContext* c, AVCodecContext *avctx); -void int_init_altivec(DSPContext* c, AVCodecContext *avctx); - -#endif /* AVCODEC_PPC_DSPUTIL_ALTIVEC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c b/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c deleted file mode 100644 index cf0ac39..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2002 Brian Foley - * Copyright (c) 2002 Dieter Shirley - * Copyright (c) 2003-2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" - -#include "dsputil_ppc.h" - -#include "dsputil_altivec.h" - -int mm_flags = 0; - -int mm_support(void) -{ - int result = 0; -#if HAVE_ALTIVEC - if (has_altivec()) { - result |= FF_MM_ALTIVEC; - } -#endif /* result */ - return result; -} - -#if CONFIG_POWERPC_PERF -unsigned long long perfdata[POWERPC_NUM_PMC_ENABLED][powerpc_perf_total][powerpc_data_total]; -/* list below must match enum in dsputil_ppc.h */ -static unsigned char* perfname[] = { - "ff_fft_calc_altivec", - "gmc1_altivec", - "dct_unquantize_h263_altivec", - "fdct_altivec", - "idct_add_altivec", - "idct_put_altivec", - "put_pixels16_altivec", - "avg_pixels16_altivec", - "avg_pixels8_altivec", - "put_pixels8_xy2_altivec", - "put_no_rnd_pixels8_xy2_altivec", - "put_pixels16_xy2_altivec", - "put_no_rnd_pixels16_xy2_altivec", - "hadamard8_diff8x8_altivec", - "hadamard8_diff16_altivec", - "avg_pixels8_xy2_altivec", - "clear_blocks_dcbz32_ppc", - "clear_blocks_dcbz128_ppc", - "put_h264_chroma_mc8_altivec", - "avg_h264_chroma_mc8_altivec", - "put_h264_qpel16_h_lowpass_altivec", - "avg_h264_qpel16_h_lowpass_altivec", - "put_h264_qpel16_v_lowpass_altivec", - "avg_h264_qpel16_v_lowpass_altivec", - "put_h264_qpel16_hv_lowpass_altivec", - "avg_h264_qpel16_hv_lowpass_altivec", - "" -}; -#include -#endif - -#if CONFIG_POWERPC_PERF -void powerpc_display_perf_report(void) -{ - int i, j; - av_log(NULL, AV_LOG_INFO, "PowerPC performance report\n Values are from the PMC registers, and represent whatever the registers are set to record.\n"); - for(i = 0 ; i < powerpc_perf_total ; i++) { - for (j = 0; j < POWERPC_NUM_PMC_ENABLED ; j++) { - if (perfdata[j][i][powerpc_data_num] != (unsigned long long)0) - av_log(NULL, AV_LOG_INFO, - " Function \"%s\" (pmc%d):\n\tmin: %"PRIu64"\n\tmax: %"PRIu64"\n\tavg: %1.2lf (%"PRIu64")\n", - perfname[i], - j+1, - perfdata[j][i][powerpc_data_min], - perfdata[j][i][powerpc_data_max], - (double)perfdata[j][i][powerpc_data_sum] / - (double)perfdata[j][i][powerpc_data_num], - perfdata[j][i][powerpc_data_num]); - } - } -} -#endif /* CONFIG_POWERPC_PERF */ - -/* ***** WARNING ***** WARNING ***** WARNING ***** */ -/* -clear_blocks_dcbz32_ppc will not work properly on PowerPC processors with a -cache line size not equal to 32 bytes. -Fortunately all processor used by Apple up to at least the 7450 (aka second -generation G4) use 32 bytes cache line. -This is due to the use of the 'dcbz' instruction. It simply clear to zero a -single cache line, so you need to know the cache line size to use it ! -It's absurd, but it's fast... - -update 24/06/2003 : Apple released yesterday the G5, with a PPC970. cache line -size: 128 bytes. Oups. -The semantic of dcbz was changed, it always clear 32 bytes. so the function -below will work, but will be slow. So I fixed check_dcbz_effect to use dcbzl, -which is defined to clear a cache line (as dcbz before). So we still can -distinguish, and use dcbz (32 bytes) or dcbzl (one cache line) as required. - -see -and -*/ -static void clear_blocks_dcbz32_ppc(DCTELEM *blocks) -{ -POWERPC_PERF_DECLARE(powerpc_clear_blocks_dcbz32, 1); - register int misal = ((unsigned long)blocks & 0x00000010); - register int i = 0; -POWERPC_PERF_START_COUNT(powerpc_clear_blocks_dcbz32, 1); -#if 1 - if (misal) { - ((unsigned long*)blocks)[0] = 0L; - ((unsigned long*)blocks)[1] = 0L; - ((unsigned long*)blocks)[2] = 0L; - ((unsigned long*)blocks)[3] = 0L; - i += 16; - } - for ( ; i < sizeof(DCTELEM)*6*64-31 ; i += 32) { - __asm__ volatile("dcbz %0,%1" : : "b" (blocks), "r" (i) : "memory"); - } - if (misal) { - ((unsigned long*)blocks)[188] = 0L; - ((unsigned long*)blocks)[189] = 0L; - ((unsigned long*)blocks)[190] = 0L; - ((unsigned long*)blocks)[191] = 0L; - i += 16; - } -#else - memset(blocks, 0, sizeof(DCTELEM)*6*64); -#endif -POWERPC_PERF_STOP_COUNT(powerpc_clear_blocks_dcbz32, 1); -} - -/* same as above, when dcbzl clear a whole 128B cache line - i.e. the PPC970 aka G5 */ -#if HAVE_DCBZL -static void clear_blocks_dcbz128_ppc(DCTELEM *blocks) -{ -POWERPC_PERF_DECLARE(powerpc_clear_blocks_dcbz128, 1); - register int misal = ((unsigned long)blocks & 0x0000007f); - register int i = 0; -POWERPC_PERF_START_COUNT(powerpc_clear_blocks_dcbz128, 1); -#if 1 - if (misal) { - // we could probably also optimize this case, - // but there's not much point as the machines - // aren't available yet (2003-06-26) - memset(blocks, 0, sizeof(DCTELEM)*6*64); - } - else - for ( ; i < sizeof(DCTELEM)*6*64 ; i += 128) { - __asm__ volatile("dcbzl %0,%1" : : "b" (blocks), "r" (i) : "memory"); - } -#else - memset(blocks, 0, sizeof(DCTELEM)*6*64); -#endif -POWERPC_PERF_STOP_COUNT(powerpc_clear_blocks_dcbz128, 1); -} -#else -static void clear_blocks_dcbz128_ppc(DCTELEM *blocks) -{ - memset(blocks, 0, sizeof(DCTELEM)*6*64); -} -#endif - -#if HAVE_DCBZL -/* check dcbz report how many bytes are set to 0 by dcbz */ -/* update 24/06/2003 : replace dcbz by dcbzl to get - the intended effect (Apple "fixed" dcbz) - unfortunately this cannot be used unless the assembler - knows about dcbzl ... */ -static long check_dcbzl_effect(void) -{ - register char *fakedata = av_malloc(1024); - register char *fakedata_middle; - register long zero = 0; - register long i = 0; - long count = 0; - - if (!fakedata) { - return 0L; - } - - fakedata_middle = (fakedata + 512); - - memset(fakedata, 0xFF, 1024); - - /* below the constraint "b" seems to mean "Address base register" - in gcc-3.3 / RS/6000 speaks. seems to avoid using r0, so.... */ - __asm__ volatile("dcbzl %0, %1" : : "b" (fakedata_middle), "r" (zero)); - - for (i = 0; i < 1024 ; i ++) { - if (fakedata[i] == (char)0) - count++; - } - - av_free(fakedata); - - return count; -} -#else -static long check_dcbzl_effect(void) -{ - return 0; -} -#endif - -static void prefetch_ppc(void *mem, int stride, int h) -{ - register const uint8_t *p = mem; - do { - __asm__ volatile ("dcbt 0,%0" : : "r" (p)); - p+= stride; - } while(--h); -} - -void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx) -{ - // Common optimizations whether AltiVec is available or not - c->prefetch = prefetch_ppc; - switch (check_dcbzl_effect()) { - case 32: - c->clear_blocks = clear_blocks_dcbz32_ppc; - break; - case 128: - c->clear_blocks = clear_blocks_dcbz128_ppc; - break; - default: - break; - } - -#if HAVE_ALTIVEC - if(CONFIG_H264_DECODER) dsputil_h264_init_ppc(c, avctx); - - if (has_altivec()) { - mm_flags |= FF_MM_ALTIVEC; - - dsputil_init_altivec(c, avctx); - if(CONFIG_VC1_DECODER) - vc1dsp_init_altivec(c, avctx); - float_init_altivec(c, avctx); - int_init_altivec(c, avctx); - c->gmc1 = gmc1_altivec; - -#if CONFIG_ENCODERS - if (avctx->dct_algo == FF_DCT_AUTO || - avctx->dct_algo == FF_DCT_ALTIVEC) { - c->fdct = fdct_altivec; - } -#endif //CONFIG_ENCODERS - - if (avctx->lowres==0) { - if ((avctx->idct_algo == FF_IDCT_AUTO) || - (avctx->idct_algo == FF_IDCT_ALTIVEC)) { - c->idct_put = idct_put_altivec; - c->idct_add = idct_add_altivec; - c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; - }else if((CONFIG_VP3_DECODER || CONFIG_VP5_DECODER || CONFIG_VP6_DECODER) && - avctx->idct_algo==FF_IDCT_VP3){ - c->idct_put = ff_vp3_idct_put_altivec; - c->idct_add = ff_vp3_idct_add_altivec; - c->idct = ff_vp3_idct_altivec; - c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; - } - } - -#if CONFIG_POWERPC_PERF - { - int i, j; - for (i = 0 ; i < powerpc_perf_total ; i++) { - for (j = 0; j < POWERPC_NUM_PMC_ENABLED ; j++) { - perfdata[j][i][powerpc_data_min] = 0xFFFFFFFFFFFFFFFFULL; - perfdata[j][i][powerpc_data_max] = 0x0000000000000000ULL; - perfdata[j][i][powerpc_data_sum] = 0x0000000000000000ULL; - perfdata[j][i][powerpc_data_num] = 0x0000000000000000ULL; - } - } - } -#endif /* CONFIG_POWERPC_PERF */ - } -#endif /* HAVE_ALTIVEC */ -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h b/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h deleted file mode 100644 index d028574..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2003-2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PPC_DSPUTIL_PPC_H -#define AVCODEC_PPC_DSPUTIL_PPC_H - -#include "config.h" - -#if CONFIG_POWERPC_PERF -void powerpc_display_perf_report(void); -/* the 604* have 2, the G3* have 4, the G4s have 6, - and the G5 are completely different (they MUST use - ARCH_PPC64, and let's hope all future 64 bis PPC - will use the same PMCs... */ -#define POWERPC_NUM_PMC_ENABLED 6 -/* if you add to the enum below, also add to the perfname array - in dsputil_ppc.c */ -enum powerpc_perf_index { - altivec_fft_num = 0, - altivec_gmc1_num, - altivec_dct_unquantize_h263_num, - altivec_fdct, - altivec_idct_add_num, - altivec_idct_put_num, - altivec_put_pixels16_num, - altivec_avg_pixels16_num, - altivec_avg_pixels8_num, - altivec_put_pixels8_xy2_num, - altivec_put_no_rnd_pixels8_xy2_num, - altivec_put_pixels16_xy2_num, - altivec_put_no_rnd_pixels16_xy2_num, - altivec_hadamard8_diff8x8_num, - altivec_hadamard8_diff16_num, - altivec_avg_pixels8_xy2_num, - powerpc_clear_blocks_dcbz32, - powerpc_clear_blocks_dcbz128, - altivec_put_h264_chroma_mc8_num, - altivec_avg_h264_chroma_mc8_num, - altivec_put_h264_qpel16_h_lowpass_num, - altivec_avg_h264_qpel16_h_lowpass_num, - altivec_put_h264_qpel16_v_lowpass_num, - altivec_avg_h264_qpel16_v_lowpass_num, - altivec_put_h264_qpel16_hv_lowpass_num, - altivec_avg_h264_qpel16_hv_lowpass_num, - powerpc_perf_total -}; -enum powerpc_data_index { - powerpc_data_min = 0, - powerpc_data_max, - powerpc_data_sum, - powerpc_data_num, - powerpc_data_total -}; -extern unsigned long long perfdata[POWERPC_NUM_PMC_ENABLED][powerpc_perf_total][powerpc_data_total]; - -#if !ARCH_PPC64 -#define POWERP_PMC_DATATYPE unsigned long -#define POWERPC_GET_PMC1(a) __asm__ volatile("mfspr %0, 937" : "=r" (a)) -#define POWERPC_GET_PMC2(a) __asm__ volatile("mfspr %0, 938" : "=r" (a)) -#if (POWERPC_NUM_PMC_ENABLED > 2) -#define POWERPC_GET_PMC3(a) __asm__ volatile("mfspr %0, 941" : "=r" (a)) -#define POWERPC_GET_PMC4(a) __asm__ volatile("mfspr %0, 942" : "=r" (a)) -#else -#define POWERPC_GET_PMC3(a) do {} while (0) -#define POWERPC_GET_PMC4(a) do {} while (0) -#endif -#if (POWERPC_NUM_PMC_ENABLED > 4) -#define POWERPC_GET_PMC5(a) __asm__ volatile("mfspr %0, 929" : "=r" (a)) -#define POWERPC_GET_PMC6(a) __asm__ volatile("mfspr %0, 930" : "=r" (a)) -#else -#define POWERPC_GET_PMC5(a) do {} while (0) -#define POWERPC_GET_PMC6(a) do {} while (0) -#endif -#else /* ARCH_PPC64 */ -#define POWERP_PMC_DATATYPE unsigned long long -#define POWERPC_GET_PMC1(a) __asm__ volatile("mfspr %0, 771" : "=r" (a)) -#define POWERPC_GET_PMC2(a) __asm__ volatile("mfspr %0, 772" : "=r" (a)) -#if (POWERPC_NUM_PMC_ENABLED > 2) -#define POWERPC_GET_PMC3(a) __asm__ volatile("mfspr %0, 773" : "=r" (a)) -#define POWERPC_GET_PMC4(a) __asm__ volatile("mfspr %0, 774" : "=r" (a)) -#else -#define POWERPC_GET_PMC3(a) do {} while (0) -#define POWERPC_GET_PMC4(a) do {} while (0) -#endif -#if (POWERPC_NUM_PMC_ENABLED > 4) -#define POWERPC_GET_PMC5(a) __asm__ volatile("mfspr %0, 775" : "=r" (a)) -#define POWERPC_GET_PMC6(a) __asm__ volatile("mfspr %0, 776" : "=r" (a)) -#else -#define POWERPC_GET_PMC5(a) do {} while (0) -#define POWERPC_GET_PMC6(a) do {} while (0) -#endif -#endif /* ARCH_PPC64 */ -#define POWERPC_PERF_DECLARE(a, cond) \ - POWERP_PMC_DATATYPE \ - pmc_start[POWERPC_NUM_PMC_ENABLED], \ - pmc_stop[POWERPC_NUM_PMC_ENABLED], \ - pmc_loop_index; -#define POWERPC_PERF_START_COUNT(a, cond) do { \ - POWERPC_GET_PMC6(pmc_start[5]); \ - POWERPC_GET_PMC5(pmc_start[4]); \ - POWERPC_GET_PMC4(pmc_start[3]); \ - POWERPC_GET_PMC3(pmc_start[2]); \ - POWERPC_GET_PMC2(pmc_start[1]); \ - POWERPC_GET_PMC1(pmc_start[0]); \ - } while (0) -#define POWERPC_PERF_STOP_COUNT(a, cond) do { \ - POWERPC_GET_PMC1(pmc_stop[0]); \ - POWERPC_GET_PMC2(pmc_stop[1]); \ - POWERPC_GET_PMC3(pmc_stop[2]); \ - POWERPC_GET_PMC4(pmc_stop[3]); \ - POWERPC_GET_PMC5(pmc_stop[4]); \ - POWERPC_GET_PMC6(pmc_stop[5]); \ - if (cond) { \ - for(pmc_loop_index = 0; \ - pmc_loop_index < POWERPC_NUM_PMC_ENABLED; \ - pmc_loop_index++) { \ - if (pmc_stop[pmc_loop_index] >= pmc_start[pmc_loop_index]) { \ - POWERP_PMC_DATATYPE diff = \ - pmc_stop[pmc_loop_index] - pmc_start[pmc_loop_index]; \ - if (diff < perfdata[pmc_loop_index][a][powerpc_data_min]) \ - perfdata[pmc_loop_index][a][powerpc_data_min] = diff; \ - if (diff > perfdata[pmc_loop_index][a][powerpc_data_max]) \ - perfdata[pmc_loop_index][a][powerpc_data_max] = diff; \ - perfdata[pmc_loop_index][a][powerpc_data_sum] += diff; \ - perfdata[pmc_loop_index][a][powerpc_data_num] ++; \ - } \ - } \ - } \ -} while (0) -#else /* CONFIG_POWERPC_PERF */ -// those are needed to avoid empty statements. -#define POWERPC_PERF_DECLARE(a, cond) int altivec_placeholder __attribute__ ((unused)) -#define POWERPC_PERF_START_COUNT(a, cond) do {} while (0) -#define POWERPC_PERF_STOP_COUNT(a, cond) do {} while (0) -#endif /* CONFIG_POWERPC_PERF */ - -#endif /* AVCODEC_PPC_DSPUTIL_PPC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/fdct_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/fdct_altivec.c deleted file mode 100644 index 8f3bc26..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/fdct_altivec.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright (C) 2003 James Klicman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif -#include "libavutil/common.h" -#include "libavcodec/dsputil.h" -#include "dsputil_ppc.h" -#include "dsputil_altivec.h" - -#define vs16(v) ((vector signed short)(v)) -#define vs32(v) ((vector signed int)(v)) -#define vu8(v) ((vector unsigned char)(v)) -#define vu16(v) ((vector unsigned short)(v)) -#define vu32(v) ((vector unsigned int)(v)) - - -#define C1 0.98078525066375732421875000 /* cos(1*PI/16) */ -#define C2 0.92387950420379638671875000 /* cos(2*PI/16) */ -#define C3 0.83146959543228149414062500 /* cos(3*PI/16) */ -#define C4 0.70710676908493041992187500 /* cos(4*PI/16) */ -#define C5 0.55557024478912353515625000 /* cos(5*PI/16) */ -#define C6 0.38268342614173889160156250 /* cos(6*PI/16) */ -#define C7 0.19509032368659973144531250 /* cos(7*PI/16) */ -#define SQRT_2 1.41421353816986083984375000 /* sqrt(2) */ - - -#define W0 -(2 * C2) -#define W1 (2 * C6) -#define W2 (SQRT_2 * C6) -#define W3 (SQRT_2 * C3) -#define W4 (SQRT_2 * (-C1 + C3 + C5 - C7)) -#define W5 (SQRT_2 * ( C1 + C3 - C5 + C7)) -#define W6 (SQRT_2 * ( C1 + C3 + C5 - C7)) -#define W7 (SQRT_2 * ( C1 + C3 - C5 - C7)) -#define W8 (SQRT_2 * ( C7 - C3)) -#define W9 (SQRT_2 * (-C1 - C3)) -#define WA (SQRT_2 * (-C3 - C5)) -#define WB (SQRT_2 * ( C5 - C3)) - - -static vector float fdctconsts[3] = { - { W0, W1, W2, W3 }, - { W4, W5, W6, W7 }, - { W8, W9, WA, WB } -}; - -#define LD_W0 vec_splat(cnsts0, 0) -#define LD_W1 vec_splat(cnsts0, 1) -#define LD_W2 vec_splat(cnsts0, 2) -#define LD_W3 vec_splat(cnsts0, 3) -#define LD_W4 vec_splat(cnsts1, 0) -#define LD_W5 vec_splat(cnsts1, 1) -#define LD_W6 vec_splat(cnsts1, 2) -#define LD_W7 vec_splat(cnsts1, 3) -#define LD_W8 vec_splat(cnsts2, 0) -#define LD_W9 vec_splat(cnsts2, 1) -#define LD_WA vec_splat(cnsts2, 2) -#define LD_WB vec_splat(cnsts2, 3) - - -#define FDCTROW(b0,b1,b2,b3,b4,b5,b6,b7) /* {{{ */ \ - x0 = vec_add(b0, b7); /* x0 = b0 + b7; */ \ - x7 = vec_sub(b0, b7); /* x7 = b0 - b7; */ \ - x1 = vec_add(b1, b6); /* x1 = b1 + b6; */ \ - x6 = vec_sub(b1, b6); /* x6 = b1 - b6; */ \ - x2 = vec_add(b2, b5); /* x2 = b2 + b5; */ \ - x5 = vec_sub(b2, b5); /* x5 = b2 - b5; */ \ - x3 = vec_add(b3, b4); /* x3 = b3 + b4; */ \ - x4 = vec_sub(b3, b4); /* x4 = b3 - b4; */ \ - \ - b7 = vec_add(x0, x3); /* b7 = x0 + x3; */ \ - b1 = vec_add(x1, x2); /* b1 = x1 + x2; */ \ - b0 = vec_add(b7, b1); /* b0 = b7 + b1; */ \ - b4 = vec_sub(b7, b1); /* b4 = b7 - b1; */ \ - \ - b2 = vec_sub(x0, x3); /* b2 = x0 - x3; */ \ - b6 = vec_sub(x1, x2); /* b6 = x1 - x2; */ \ - b5 = vec_add(b6, b2); /* b5 = b6 + b2; */ \ - cnst = LD_W2; \ - b5 = vec_madd(cnst, b5, mzero); /* b5 = b5 * W2; */ \ - cnst = LD_W1; \ - b2 = vec_madd(cnst, b2, b5); /* b2 = b5 + b2 * W1; */ \ - cnst = LD_W0; \ - b6 = vec_madd(cnst, b6, b5); /* b6 = b5 + b6 * W0; */ \ - \ - x0 = vec_add(x4, x7); /* x0 = x4 + x7; */ \ - x1 = vec_add(x5, x6); /* x1 = x5 + x6; */ \ - x2 = vec_add(x4, x6); /* x2 = x4 + x6; */ \ - x3 = vec_add(x5, x7); /* x3 = x5 + x7; */ \ - x8 = vec_add(x2, x3); /* x8 = x2 + x3; */ \ - cnst = LD_W3; \ - x8 = vec_madd(cnst, x8, mzero); /* x8 = x8 * W3; */ \ - \ - cnst = LD_W8; \ - x0 = vec_madd(cnst, x0, mzero); /* x0 *= W8; */ \ - cnst = LD_W9; \ - x1 = vec_madd(cnst, x1, mzero); /* x1 *= W9; */ \ - cnst = LD_WA; \ - x2 = vec_madd(cnst, x2, x8); /* x2 = x2 * WA + x8; */ \ - cnst = LD_WB; \ - x3 = vec_madd(cnst, x3, x8); /* x3 = x3 * WB + x8; */ \ - \ - cnst = LD_W4; \ - b7 = vec_madd(cnst, x4, x0); /* b7 = x4 * W4 + x0; */ \ - cnst = LD_W5; \ - b5 = vec_madd(cnst, x5, x1); /* b5 = x5 * W5 + x1; */ \ - cnst = LD_W6; \ - b3 = vec_madd(cnst, x6, x1); /* b3 = x6 * W6 + x1; */ \ - cnst = LD_W7; \ - b1 = vec_madd(cnst, x7, x0); /* b1 = x7 * W7 + x0; */ \ - \ - b7 = vec_add(b7, x2); /* b7 = b7 + x2; */ \ - b5 = vec_add(b5, x3); /* b5 = b5 + x3; */ \ - b3 = vec_add(b3, x2); /* b3 = b3 + x2; */ \ - b1 = vec_add(b1, x3); /* b1 = b1 + x3; */ \ - /* }}} */ - -#define FDCTCOL(b0,b1,b2,b3,b4,b5,b6,b7) /* {{{ */ \ - x0 = vec_add(b0, b7); /* x0 = b0 + b7; */ \ - x7 = vec_sub(b0, b7); /* x7 = b0 - b7; */ \ - x1 = vec_add(b1, b6); /* x1 = b1 + b6; */ \ - x6 = vec_sub(b1, b6); /* x6 = b1 - b6; */ \ - x2 = vec_add(b2, b5); /* x2 = b2 + b5; */ \ - x5 = vec_sub(b2, b5); /* x5 = b2 - b5; */ \ - x3 = vec_add(b3, b4); /* x3 = b3 + b4; */ \ - x4 = vec_sub(b3, b4); /* x4 = b3 - b4; */ \ - \ - b7 = vec_add(x0, x3); /* b7 = x0 + x3; */ \ - b1 = vec_add(x1, x2); /* b1 = x1 + x2; */ \ - b0 = vec_add(b7, b1); /* b0 = b7 + b1; */ \ - b4 = vec_sub(b7, b1); /* b4 = b7 - b1; */ \ - \ - b2 = vec_sub(x0, x3); /* b2 = x0 - x3; */ \ - b6 = vec_sub(x1, x2); /* b6 = x1 - x2; */ \ - b5 = vec_add(b6, b2); /* b5 = b6 + b2; */ \ - cnst = LD_W2; \ - b5 = vec_madd(cnst, b5, mzero); /* b5 = b5 * W2; */ \ - cnst = LD_W1; \ - b2 = vec_madd(cnst, b2, b5); /* b2 = b5 + b2 * W1; */ \ - cnst = LD_W0; \ - b6 = vec_madd(cnst, b6, b5); /* b6 = b5 + b6 * W0; */ \ - \ - x0 = vec_add(x4, x7); /* x0 = x4 + x7; */ \ - x1 = vec_add(x5, x6); /* x1 = x5 + x6; */ \ - x2 = vec_add(x4, x6); /* x2 = x4 + x6; */ \ - x3 = vec_add(x5, x7); /* x3 = x5 + x7; */ \ - x8 = vec_add(x2, x3); /* x8 = x2 + x3; */ \ - cnst = LD_W3; \ - x8 = vec_madd(cnst, x8, mzero); /* x8 = x8 * W3; */ \ - \ - cnst = LD_W8; \ - x0 = vec_madd(cnst, x0, mzero); /* x0 *= W8; */ \ - cnst = LD_W9; \ - x1 = vec_madd(cnst, x1, mzero); /* x1 *= W9; */ \ - cnst = LD_WA; \ - x2 = vec_madd(cnst, x2, x8); /* x2 = x2 * WA + x8; */ \ - cnst = LD_WB; \ - x3 = vec_madd(cnst, x3, x8); /* x3 = x3 * WB + x8; */ \ - \ - cnst = LD_W4; \ - b7 = vec_madd(cnst, x4, x0); /* b7 = x4 * W4 + x0; */ \ - cnst = LD_W5; \ - b5 = vec_madd(cnst, x5, x1); /* b5 = x5 * W5 + x1; */ \ - cnst = LD_W6; \ - b3 = vec_madd(cnst, x6, x1); /* b3 = x6 * W6 + x1; */ \ - cnst = LD_W7; \ - b1 = vec_madd(cnst, x7, x0); /* b1 = x7 * W7 + x0; */ \ - \ - b7 = vec_add(b7, x2); /* b7 += x2; */ \ - b5 = vec_add(b5, x3); /* b5 += x3; */ \ - b3 = vec_add(b3, x2); /* b3 += x2; */ \ - b1 = vec_add(b1, x3); /* b1 += x3; */ \ - /* }}} */ - - - -/* two dimensional discrete cosine transform */ - -void fdct_altivec(int16_t *block) -{ -POWERPC_PERF_DECLARE(altivec_fdct, 1); - vector signed short *bp; - vector float *cp; - vector float b00, b10, b20, b30, b40, b50, b60, b70; - vector float b01, b11, b21, b31, b41, b51, b61, b71; - vector float mzero, cnst, cnsts0, cnsts1, cnsts2; - vector float x0, x1, x2, x3, x4, x5, x6, x7, x8; - - POWERPC_PERF_START_COUNT(altivec_fdct, 1); - - - /* setup constants {{{ */ - /* mzero = -0.0 */ - mzero = ((vector float)vec_splat_u32(-1)); - mzero = ((vector float)vec_sl(vu32(mzero), vu32(mzero))); - cp = fdctconsts; - cnsts0 = vec_ld(0, cp); cp++; - cnsts1 = vec_ld(0, cp); cp++; - cnsts2 = vec_ld(0, cp); - /* }}} */ - - - /* 8x8 matrix transpose (vector short[8]) {{{ */ -#define MERGE_S16(hl,a,b) vec_merge##hl(vs16(a), vs16(b)) - - bp = (vector signed short*)block; - b00 = ((vector float)vec_ld(0, bp)); - b40 = ((vector float)vec_ld(16*4, bp)); - b01 = ((vector float)MERGE_S16(h, b00, b40)); - b11 = ((vector float)MERGE_S16(l, b00, b40)); - bp++; - b10 = ((vector float)vec_ld(0, bp)); - b50 = ((vector float)vec_ld(16*4, bp)); - b21 = ((vector float)MERGE_S16(h, b10, b50)); - b31 = ((vector float)MERGE_S16(l, b10, b50)); - bp++; - b20 = ((vector float)vec_ld(0, bp)); - b60 = ((vector float)vec_ld(16*4, bp)); - b41 = ((vector float)MERGE_S16(h, b20, b60)); - b51 = ((vector float)MERGE_S16(l, b20, b60)); - bp++; - b30 = ((vector float)vec_ld(0, bp)); - b70 = ((vector float)vec_ld(16*4, bp)); - b61 = ((vector float)MERGE_S16(h, b30, b70)); - b71 = ((vector float)MERGE_S16(l, b30, b70)); - - x0 = ((vector float)MERGE_S16(h, b01, b41)); - x1 = ((vector float)MERGE_S16(l, b01, b41)); - x2 = ((vector float)MERGE_S16(h, b11, b51)); - x3 = ((vector float)MERGE_S16(l, b11, b51)); - x4 = ((vector float)MERGE_S16(h, b21, b61)); - x5 = ((vector float)MERGE_S16(l, b21, b61)); - x6 = ((vector float)MERGE_S16(h, b31, b71)); - x7 = ((vector float)MERGE_S16(l, b31, b71)); - - b00 = ((vector float)MERGE_S16(h, x0, x4)); - b10 = ((vector float)MERGE_S16(l, x0, x4)); - b20 = ((vector float)MERGE_S16(h, x1, x5)); - b30 = ((vector float)MERGE_S16(l, x1, x5)); - b40 = ((vector float)MERGE_S16(h, x2, x6)); - b50 = ((vector float)MERGE_S16(l, x2, x6)); - b60 = ((vector float)MERGE_S16(h, x3, x7)); - b70 = ((vector float)MERGE_S16(l, x3, x7)); - -#undef MERGE_S16 - /* }}} */ - - -/* Some of the initial calculations can be done as vector short before - * conversion to vector float. The following code section takes advantage - * of this. - */ -#if 1 - /* fdct rows {{{ */ - x0 = ((vector float)vec_add(vs16(b00), vs16(b70))); - x7 = ((vector float)vec_sub(vs16(b00), vs16(b70))); - x1 = ((vector float)vec_add(vs16(b10), vs16(b60))); - x6 = ((vector float)vec_sub(vs16(b10), vs16(b60))); - x2 = ((vector float)vec_add(vs16(b20), vs16(b50))); - x5 = ((vector float)vec_sub(vs16(b20), vs16(b50))); - x3 = ((vector float)vec_add(vs16(b30), vs16(b40))); - x4 = ((vector float)vec_sub(vs16(b30), vs16(b40))); - - b70 = ((vector float)vec_add(vs16(x0), vs16(x3))); - b10 = ((vector float)vec_add(vs16(x1), vs16(x2))); - - b00 = ((vector float)vec_add(vs16(b70), vs16(b10))); - b40 = ((vector float)vec_sub(vs16(b70), vs16(b10))); - -#define CTF0(n) \ - b##n##1 = ((vector float)vec_unpackl(vs16(b##n##0))); \ - b##n##0 = ((vector float)vec_unpackh(vs16(b##n##0))); \ - b##n##1 = vec_ctf(vs32(b##n##1), 0); \ - b##n##0 = vec_ctf(vs32(b##n##0), 0); - - CTF0(0); - CTF0(4); - - b20 = ((vector float)vec_sub(vs16(x0), vs16(x3))); - b60 = ((vector float)vec_sub(vs16(x1), vs16(x2))); - - CTF0(2); - CTF0(6); - -#undef CTF0 - - x0 = vec_add(b60, b20); - x1 = vec_add(b61, b21); - - cnst = LD_W2; - x0 = vec_madd(cnst, x0, mzero); - x1 = vec_madd(cnst, x1, mzero); - cnst = LD_W1; - b20 = vec_madd(cnst, b20, x0); - b21 = vec_madd(cnst, b21, x1); - cnst = LD_W0; - b60 = vec_madd(cnst, b60, x0); - b61 = vec_madd(cnst, b61, x1); - -#define CTFX(x,b) \ - b##0 = ((vector float)vec_unpackh(vs16(x))); \ - b##1 = ((vector float)vec_unpackl(vs16(x))); \ - b##0 = vec_ctf(vs32(b##0), 0); \ - b##1 = vec_ctf(vs32(b##1), 0); \ - - CTFX(x4, b7); - CTFX(x5, b5); - CTFX(x6, b3); - CTFX(x7, b1); - -#undef CTFX - - - x0 = vec_add(b70, b10); - x1 = vec_add(b50, b30); - x2 = vec_add(b70, b30); - x3 = vec_add(b50, b10); - x8 = vec_add(x2, x3); - cnst = LD_W3; - x8 = vec_madd(cnst, x8, mzero); - - cnst = LD_W8; - x0 = vec_madd(cnst, x0, mzero); - cnst = LD_W9; - x1 = vec_madd(cnst, x1, mzero); - cnst = LD_WA; - x2 = vec_madd(cnst, x2, x8); - cnst = LD_WB; - x3 = vec_madd(cnst, x3, x8); - - cnst = LD_W4; - b70 = vec_madd(cnst, b70, x0); - cnst = LD_W5; - b50 = vec_madd(cnst, b50, x1); - cnst = LD_W6; - b30 = vec_madd(cnst, b30, x1); - cnst = LD_W7; - b10 = vec_madd(cnst, b10, x0); - - b70 = vec_add(b70, x2); - b50 = vec_add(b50, x3); - b30 = vec_add(b30, x2); - b10 = vec_add(b10, x3); - - - x0 = vec_add(b71, b11); - x1 = vec_add(b51, b31); - x2 = vec_add(b71, b31); - x3 = vec_add(b51, b11); - x8 = vec_add(x2, x3); - cnst = LD_W3; - x8 = vec_madd(cnst, x8, mzero); - - cnst = LD_W8; - x0 = vec_madd(cnst, x0, mzero); - cnst = LD_W9; - x1 = vec_madd(cnst, x1, mzero); - cnst = LD_WA; - x2 = vec_madd(cnst, x2, x8); - cnst = LD_WB; - x3 = vec_madd(cnst, x3, x8); - - cnst = LD_W4; - b71 = vec_madd(cnst, b71, x0); - cnst = LD_W5; - b51 = vec_madd(cnst, b51, x1); - cnst = LD_W6; - b31 = vec_madd(cnst, b31, x1); - cnst = LD_W7; - b11 = vec_madd(cnst, b11, x0); - - b71 = vec_add(b71, x2); - b51 = vec_add(b51, x3); - b31 = vec_add(b31, x2); - b11 = vec_add(b11, x3); - /* }}} */ -#else - /* convert to float {{{ */ -#define CTF(n) \ - vs32(b##n##1) = vec_unpackl(vs16(b##n##0)); \ - vs32(b##n##0) = vec_unpackh(vs16(b##n##0)); \ - b##n##1 = vec_ctf(vs32(b##n##1), 0); \ - b##n##0 = vec_ctf(vs32(b##n##0), 0); \ - - CTF(0); - CTF(1); - CTF(2); - CTF(3); - CTF(4); - CTF(5); - CTF(6); - CTF(7); - -#undef CTF - /* }}} */ - - FDCTROW(b00, b10, b20, b30, b40, b50, b60, b70); - FDCTROW(b01, b11, b21, b31, b41, b51, b61, b71); -#endif - - - /* 8x8 matrix transpose (vector float[8][2]) {{{ */ - x0 = vec_mergel(b00, b20); - x1 = vec_mergeh(b00, b20); - x2 = vec_mergel(b10, b30); - x3 = vec_mergeh(b10, b30); - - b00 = vec_mergeh(x1, x3); - b10 = vec_mergel(x1, x3); - b20 = vec_mergeh(x0, x2); - b30 = vec_mergel(x0, x2); - - x4 = vec_mergel(b41, b61); - x5 = vec_mergeh(b41, b61); - x6 = vec_mergel(b51, b71); - x7 = vec_mergeh(b51, b71); - - b41 = vec_mergeh(x5, x7); - b51 = vec_mergel(x5, x7); - b61 = vec_mergeh(x4, x6); - b71 = vec_mergel(x4, x6); - - x0 = vec_mergel(b01, b21); - x1 = vec_mergeh(b01, b21); - x2 = vec_mergel(b11, b31); - x3 = vec_mergeh(b11, b31); - - x4 = vec_mergel(b40, b60); - x5 = vec_mergeh(b40, b60); - x6 = vec_mergel(b50, b70); - x7 = vec_mergeh(b50, b70); - - b40 = vec_mergeh(x1, x3); - b50 = vec_mergel(x1, x3); - b60 = vec_mergeh(x0, x2); - b70 = vec_mergel(x0, x2); - - b01 = vec_mergeh(x5, x7); - b11 = vec_mergel(x5, x7); - b21 = vec_mergeh(x4, x6); - b31 = vec_mergel(x4, x6); - /* }}} */ - - - FDCTCOL(b00, b10, b20, b30, b40, b50, b60, b70); - FDCTCOL(b01, b11, b21, b31, b41, b51, b61, b71); - - - /* round, convert back to short {{{ */ -#define CTS(n) \ - b##n##0 = vec_round(b##n##0); \ - b##n##1 = vec_round(b##n##1); \ - b##n##0 = ((vector float)vec_cts(b##n##0, 0)); \ - b##n##1 = ((vector float)vec_cts(b##n##1, 0)); \ - b##n##0 = ((vector float)vec_pack(vs32(b##n##0), vs32(b##n##1))); \ - vec_st(vs16(b##n##0), 0, bp); - - bp = (vector signed short*)block; - CTS(0); bp++; - CTS(1); bp++; - CTS(2); bp++; - CTS(3); bp++; - CTS(4); bp++; - CTS(5); bp++; - CTS(6); bp++; - CTS(7); - -#undef CTS - /* }}} */ - -POWERPC_PERF_STOP_COUNT(altivec_fdct, 1); -} - -/* vim:set foldmethod=marker foldlevel=0: */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/fft_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/fft_altivec.c deleted file mode 100644 index ce35ab6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/fft_altivec.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * FFT/IFFT transforms - * AltiVec-enabled - * Copyright (c) 2003 Romain Dolbeau - * Based on code Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "libavcodec/fft.h" -#include "dsputil_ppc.h" -#include "util_altivec.h" -#include "dsputil_altivec.h" - -/** - * 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. - * AltiVec-enabled - * This code assumes that the 'z' pointer is 16 bytes-aligned - * It also assumes all FFTComplex are 8 bytes-aligned pair of float - * The code is exactly the same as the SSE version, except - * that successive MUL + ADD/SUB have been merged into - * fused multiply-add ('vec_madd' in altivec) - */ -static void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z) -{ -POWERPC_PERF_DECLARE(altivec_fft_num, s->nbits >= 6); - register const vector float vczero = (const vector float)vec_splat_u32(0.); - - int ln = s->nbits; - int j, np, np2; - int nblocks, nloops; - register FFTComplex *p, *q; - FFTComplex *cptr, *cptr1; - int k; - -POWERPC_PERF_START_COUNT(altivec_fft_num, s->nbits >= 6); - - np = 1 << ln; - - { - vector float *r, a, b, a1, c1, c2; - - r = (vector float *)&z[0]; - - c1 = vcii(p,p,n,n); - - if (s->inverse) { - c2 = vcii(p,p,n,p); - } else { - c2 = vcii(p,p,p,n); - } - - j = (np >> 2); - do { - a = vec_ld(0, r); - a1 = vec_ld(sizeof(vector float), r); - - b = vec_perm(a,a,vcprmle(1,0,3,2)); - a = vec_madd(a,c1,b); - /* do the pass 0 butterfly */ - - b = vec_perm(a1,a1,vcprmle(1,0,3,2)); - b = vec_madd(a1,c1,b); - /* do the pass 0 butterfly */ - - /* multiply third by -i */ - b = vec_perm(b,b,vcprmle(2,3,1,0)); - - /* do the pass 1 butterfly */ - vec_st(vec_madd(b,c2,a), 0, r); - vec_st(vec_nmsub(b,c2,a), sizeof(vector float), r); - - 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 { - vector float a,b,c,t1; - - a = vec_ld(0, (float*)p); - b = vec_ld(0, (float*)q); - - /* complex mul */ - c = vec_ld(0, (float*)cptr); - /* cre*re cim*re */ - t1 = vec_madd(c, vec_perm(b,b,vcprmle(2,2,0,0)),vczero); - c = vec_ld(sizeof(vector float), (float*)cptr); - /* -cim*im cre*im */ - b = vec_madd(c, vec_perm(b,b,vcprmle(3,3,1,1)),t1); - - /* butterfly */ - vec_st(vec_add(a,b), 0, (float*)p); - vec_st(vec_sub(a,b), 0, (float*)q); - - 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); - -POWERPC_PERF_STOP_COUNT(altivec_fft_num, s->nbits >= 6); -} - -av_cold void ff_fft_init_altivec(FFTContext *s) -{ - s->fft_calc = ff_fft_calc_altivec; - s->split_radix = 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/float_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/float_altivec.c deleted file mode 100644 index d1f9f1a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/float_altivec.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2006 Luca Barbato - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" - -#include "dsputil_altivec.h" -#include "util_altivec.h" - -static void vector_fmul_altivec(float *dst, const float *src, int len) -{ - int i; - vector float d0, d1, s, zero = (vector float)vec_splat_u32(0); - for(i=0; ivector_fmul = vector_fmul_altivec; - c->vector_fmul_reverse = vector_fmul_reverse_altivec; - c->vector_fmul_add = vector_fmul_add_altivec; - c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec; - if(!(avctx->flags & CODEC_FLAG_BITEXACT)) { - c->vector_fmul_window = vector_fmul_window_altivec; - c->float_to_int16 = float_to_int16_altivec; - c->float_to_int16_interleave = float_to_int16_interleave_altivec; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/gmc_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/gmc_altivec.c deleted file mode 100644 index fa71047..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/gmc_altivec.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * GMC (Global Motion Compensation) - * AltiVec-enabled - * Copyright (c) 2003 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_ppc.h" -#include "util_altivec.h" -#include "types_altivec.h" -#include "dsputil_altivec.h" - -/* - altivec-enhanced gmc1. ATM this code assume stride is a multiple of 8, - to preserve proper dst alignment. -*/ -#define GMC1_PERF_COND (h==8) -void gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, int stride, int h, int x16, int y16, int rounder) -{ -POWERPC_PERF_DECLARE(altivec_gmc1_num, GMC1_PERF_COND); - const DECLARE_ALIGNED(16, unsigned short, rounder_a) = rounder; - const DECLARE_ALIGNED(16, unsigned short, ABCD)[8] = - { - (16-x16)*(16-y16), /* A */ - ( x16)*(16-y16), /* B */ - (16-x16)*( y16), /* C */ - ( x16)*( y16), /* D */ - 0, 0, 0, 0 /* padding */ - }; - register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); - register const vector unsigned short vcsr8 = (const vector unsigned short)vec_splat_u16(8); - register vector unsigned char dstv, dstv2, src_0, src_1, srcvA, srcvB, srcvC, srcvD; - register vector unsigned short Av, Bv, Cv, Dv, rounderV, tempA, tempB, tempC, tempD; - int i; - unsigned long dst_odd = (unsigned long)dst & 0x0000000F; - unsigned long src_really_odd = (unsigned long)src & 0x0000000F; - - -POWERPC_PERF_START_COUNT(altivec_gmc1_num, GMC1_PERF_COND); - - tempA = vec_ld(0, (unsigned short*)ABCD); - Av = vec_splat(tempA, 0); - Bv = vec_splat(tempA, 1); - Cv = vec_splat(tempA, 2); - Dv = vec_splat(tempA, 3); - - rounderV = vec_splat((vec_u16)vec_lde(0, &rounder_a), 0); - - // we'll be able to pick-up our 9 char elements - // at src from those 32 bytes - // we load the first batch here, as inside the loop - // we can re-use 'src+stride' from one iteration - // as the 'src' of the next. - src_0 = vec_ld(0, src); - src_1 = vec_ld(16, src); - srcvA = vec_perm(src_0, src_1, vec_lvsl(0, src)); - - if (src_really_odd != 0x0000000F) { - // if src & 0xF == 0xF, then (src+1) is properly aligned - // on the second vector. - srcvB = vec_perm(src_0, src_1, vec_lvsl(1, src)); - } else { - srcvB = src_1; - } - srcvA = vec_mergeh(vczero, srcvA); - srcvB = vec_mergeh(vczero, srcvB); - - for(i=0; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "libavcodec/h264data.h" -#include "libavcodec/h264dsp.h" - -#include "dsputil_ppc.h" -#include "dsputil_altivec.h" -#include "util_altivec.h" -#include "types_altivec.h" - -#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s -#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s) - -#define OP_U8_ALTIVEC PUT_OP_U8_ALTIVEC -#define PREFIX_h264_chroma_mc8_altivec put_h264_chroma_mc8_altivec -#define PREFIX_no_rnd_vc1_chroma_mc8_altivec put_no_rnd_vc1_chroma_mc8_altivec -#define PREFIX_h264_chroma_mc8_num altivec_put_h264_chroma_mc8_num -#define PREFIX_h264_qpel16_h_lowpass_altivec put_h264_qpel16_h_lowpass_altivec -#define PREFIX_h264_qpel16_h_lowpass_num altivec_put_h264_qpel16_h_lowpass_num -#define PREFIX_h264_qpel16_v_lowpass_altivec put_h264_qpel16_v_lowpass_altivec -#define PREFIX_h264_qpel16_v_lowpass_num altivec_put_h264_qpel16_v_lowpass_num -#define PREFIX_h264_qpel16_hv_lowpass_altivec put_h264_qpel16_hv_lowpass_altivec -#define PREFIX_h264_qpel16_hv_lowpass_num altivec_put_h264_qpel16_hv_lowpass_num -#include "h264_template_altivec.c" -#undef OP_U8_ALTIVEC -#undef PREFIX_h264_chroma_mc8_altivec -#undef PREFIX_no_rnd_vc1_chroma_mc8_altivec -#undef PREFIX_h264_chroma_mc8_num -#undef PREFIX_h264_qpel16_h_lowpass_altivec -#undef PREFIX_h264_qpel16_h_lowpass_num -#undef PREFIX_h264_qpel16_v_lowpass_altivec -#undef PREFIX_h264_qpel16_v_lowpass_num -#undef PREFIX_h264_qpel16_hv_lowpass_altivec -#undef PREFIX_h264_qpel16_hv_lowpass_num - -#define OP_U8_ALTIVEC AVG_OP_U8_ALTIVEC -#define PREFIX_h264_chroma_mc8_altivec avg_h264_chroma_mc8_altivec -#define PREFIX_no_rnd_vc1_chroma_mc8_altivec avg_no_rnd_vc1_chroma_mc8_altivec -#define PREFIX_h264_chroma_mc8_num altivec_avg_h264_chroma_mc8_num -#define PREFIX_h264_qpel16_h_lowpass_altivec avg_h264_qpel16_h_lowpass_altivec -#define PREFIX_h264_qpel16_h_lowpass_num altivec_avg_h264_qpel16_h_lowpass_num -#define PREFIX_h264_qpel16_v_lowpass_altivec avg_h264_qpel16_v_lowpass_altivec -#define PREFIX_h264_qpel16_v_lowpass_num altivec_avg_h264_qpel16_v_lowpass_num -#define PREFIX_h264_qpel16_hv_lowpass_altivec avg_h264_qpel16_hv_lowpass_altivec -#define PREFIX_h264_qpel16_hv_lowpass_num altivec_avg_h264_qpel16_hv_lowpass_num -#include "h264_template_altivec.c" -#undef OP_U8_ALTIVEC -#undef PREFIX_h264_chroma_mc8_altivec -#undef PREFIX_no_rnd_vc1_chroma_mc8_altivec -#undef PREFIX_h264_chroma_mc8_num -#undef PREFIX_h264_qpel16_h_lowpass_altivec -#undef PREFIX_h264_qpel16_h_lowpass_num -#undef PREFIX_h264_qpel16_v_lowpass_altivec -#undef PREFIX_h264_qpel16_v_lowpass_num -#undef PREFIX_h264_qpel16_hv_lowpass_altivec -#undef PREFIX_h264_qpel16_hv_lowpass_num - -#define H264_MC(OPNAME, SIZE, CODETYPE) \ -static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## CODETYPE (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels ## SIZE ## _ ## CODETYPE(dst, src, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){ \ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+1, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+stride, half, stride, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(dst, tmp, src, stride, SIZE, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\ - DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\ -}\ - -static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, - const uint8_t * src2, int dst_stride, - int src_stride1, int h) -{ - int i; - vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align; - - mask_ = vec_lvsl(0, src2); - - for (i = 0; i < h; i++) { - - tmp1 = vec_ld(i * src_stride1, src1); - mask = vec_lvsl(i * src_stride1, src1); - tmp2 = vec_ld(i * src_stride1 + 15, src1); - - a = vec_perm(tmp1, tmp2, mask); - - tmp1 = vec_ld(i * 16, src2); - tmp2 = vec_ld(i * 16 + 15, src2); - - b = vec_perm(tmp1, tmp2, mask_); - - tmp1 = vec_ld(0, dst); - mask = vec_lvsl(0, dst); - tmp2 = vec_ld(15, dst); - - d = vec_avg(a, b); - - edges = vec_perm(tmp2, tmp1, mask); - - align = vec_lvsr(0, dst); - - tmp2 = vec_perm(d, edges, align); - tmp1 = vec_perm(edges, d, align); - - vec_st(tmp2, 15, dst); - vec_st(tmp1, 0 , dst); - - dst += dst_stride; - } -} - -static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, - const uint8_t * src2, int dst_stride, - int src_stride1, int h) -{ - int i; - vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align; - - mask_ = vec_lvsl(0, src2); - - for (i = 0; i < h; i++) { - - tmp1 = vec_ld(i * src_stride1, src1); - mask = vec_lvsl(i * src_stride1, src1); - tmp2 = vec_ld(i * src_stride1 + 15, src1); - - a = vec_perm(tmp1, tmp2, mask); - - tmp1 = vec_ld(i * 16, src2); - tmp2 = vec_ld(i * 16 + 15, src2); - - b = vec_perm(tmp1, tmp2, mask_); - - tmp1 = vec_ld(0, dst); - mask = vec_lvsl(0, dst); - tmp2 = vec_ld(15, dst); - - d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b)); - - edges = vec_perm(tmp2, tmp1, mask); - - align = vec_lvsr(0, dst); - - tmp2 = vec_perm(d, edges, align); - tmp1 = vec_perm(edges, d, align); - - vec_st(tmp2, 15, dst); - vec_st(tmp1, 0 , dst); - - dst += dst_stride; - } -} - -/* Implemented but could be faster -#define put_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) put_pixels16_l2(d,s1,s2,ds,s1s,16,h) -#define avg_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) avg_pixels16_l2(d,s1,s2,ds,s1s,16,h) - */ - -H264_MC(put_, 16, altivec) -H264_MC(avg_, 16, altivec) - - -/**************************************************************************** - * IDCT transform: - ****************************************************************************/ - -#define VEC_1D_DCT(vb0,vb1,vb2,vb3,va0,va1,va2,va3) \ - /* 1st stage */ \ - vz0 = vec_add(vb0,vb2); /* temp[0] = Y[0] + Y[2] */ \ - vz1 = vec_sub(vb0,vb2); /* temp[1] = Y[0] - Y[2] */ \ - vz2 = vec_sra(vb1,vec_splat_u16(1)); \ - vz2 = vec_sub(vz2,vb3); /* temp[2] = Y[1].1/2 - Y[3] */ \ - vz3 = vec_sra(vb3,vec_splat_u16(1)); \ - vz3 = vec_add(vb1,vz3); /* temp[3] = Y[1] + Y[3].1/2 */ \ - /* 2nd stage: output */ \ - va0 = vec_add(vz0,vz3); /* x[0] = temp[0] + temp[3] */ \ - va1 = vec_add(vz1,vz2); /* x[1] = temp[1] + temp[2] */ \ - va2 = vec_sub(vz1,vz2); /* x[2] = temp[1] - temp[2] */ \ - va3 = vec_sub(vz0,vz3) /* x[3] = temp[0] - temp[3] */ - -#define VEC_TRANSPOSE_4(a0,a1,a2,a3,b0,b1,b2,b3) \ - b0 = vec_mergeh( a0, a0 ); \ - b1 = vec_mergeh( a1, a0 ); \ - b2 = vec_mergeh( a2, a0 ); \ - b3 = vec_mergeh( a3, a0 ); \ - a0 = vec_mergeh( b0, b2 ); \ - a1 = vec_mergel( b0, b2 ); \ - a2 = vec_mergeh( b1, b3 ); \ - a3 = vec_mergel( b1, b3 ); \ - b0 = vec_mergeh( a0, a2 ); \ - b1 = vec_mergel( a0, a2 ); \ - b2 = vec_mergeh( a1, a3 ); \ - b3 = vec_mergel( a1, a3 ) - -#define VEC_LOAD_U8_ADD_S16_STORE_U8(va) \ - vdst_orig = vec_ld(0, dst); \ - vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask); \ - vdst_ss = (vec_s16) vec_mergeh(zero_u8v, vdst); \ - va = vec_add(va, vdst_ss); \ - va_u8 = vec_packsu(va, zero_s16v); \ - va_u32 = vec_splat((vec_u32)va_u8, 0); \ - vec_ste(va_u32, element, (uint32_t*)dst); - -static void ff_h264_idct_add_altivec(uint8_t *dst, DCTELEM *block, int stride) -{ - vec_s16 va0, va1, va2, va3; - vec_s16 vz0, vz1, vz2, vz3; - vec_s16 vtmp0, vtmp1, vtmp2, vtmp3; - vec_u8 va_u8; - vec_u32 va_u32; - vec_s16 vdst_ss; - const vec_u16 v6us = vec_splat_u16(6); - vec_u8 vdst, vdst_orig; - vec_u8 vdst_mask = vec_lvsl(0, dst); - int element = ((unsigned long)dst & 0xf) >> 2; - LOAD_ZERO; - - block[0] += 32; /* add 32 as a DC-level for rounding */ - - vtmp0 = vec_ld(0,block); - vtmp1 = vec_sld(vtmp0, vtmp0, 8); - vtmp2 = vec_ld(16,block); - vtmp3 = vec_sld(vtmp2, vtmp2, 8); - - VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3); - VEC_TRANSPOSE_4(va0,va1,va2,va3,vtmp0,vtmp1,vtmp2,vtmp3); - VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3); - - va0 = vec_sra(va0,v6us); - va1 = vec_sra(va1,v6us); - va2 = vec_sra(va2,v6us); - va3 = vec_sra(va3,v6us); - - VEC_LOAD_U8_ADD_S16_STORE_U8(va0); - dst += stride; - VEC_LOAD_U8_ADD_S16_STORE_U8(va1); - dst += stride; - VEC_LOAD_U8_ADD_S16_STORE_U8(va2); - dst += stride; - VEC_LOAD_U8_ADD_S16_STORE_U8(va3); -} - -#define IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7, d0, d1, d2, d3, d4, d5, d6, d7) {\ - /* a0 = SRC(0) + SRC(4); */ \ - vec_s16 a0v = vec_add(s0, s4); \ - /* a2 = SRC(0) - SRC(4); */ \ - vec_s16 a2v = vec_sub(s0, s4); \ - /* a4 = (SRC(2)>>1) - SRC(6); */ \ - vec_s16 a4v = vec_sub(vec_sra(s2, onev), s6); \ - /* a6 = (SRC(6)>>1) + SRC(2); */ \ - vec_s16 a6v = vec_add(vec_sra(s6, onev), s2); \ - /* b0 = a0 + a6; */ \ - vec_s16 b0v = vec_add(a0v, a6v); \ - /* b2 = a2 + a4; */ \ - vec_s16 b2v = vec_add(a2v, a4v); \ - /* b4 = a2 - a4; */ \ - vec_s16 b4v = vec_sub(a2v, a4v); \ - /* b6 = a0 - a6; */ \ - vec_s16 b6v = vec_sub(a0v, a6v); \ - /* a1 = SRC(5) - SRC(3) - SRC(7) - (SRC(7)>>1); */ \ - /* a1 = (SRC(5)-SRC(3)) - (SRC(7) + (SRC(7)>>1)); */ \ - vec_s16 a1v = vec_sub( vec_sub(s5, s3), vec_add(s7, vec_sra(s7, onev)) ); \ - /* a3 = SRC(7) + SRC(1) - SRC(3) - (SRC(3)>>1); */ \ - /* a3 = (SRC(7)+SRC(1)) - (SRC(3) + (SRC(3)>>1)); */ \ - vec_s16 a3v = vec_sub( vec_add(s7, s1), vec_add(s3, vec_sra(s3, onev)) );\ - /* a5 = SRC(7) - SRC(1) + SRC(5) + (SRC(5)>>1); */ \ - /* a5 = (SRC(7)-SRC(1)) + SRC(5) + (SRC(5)>>1); */ \ - vec_s16 a5v = vec_add( vec_sub(s7, s1), vec_add(s5, vec_sra(s5, onev)) );\ - /* a7 = SRC(5)+SRC(3) + SRC(1) + (SRC(1)>>1); */ \ - vec_s16 a7v = vec_add( vec_add(s5, s3), vec_add(s1, vec_sra(s1, onev)) );\ - /* b1 = (a7>>2) + a1; */ \ - vec_s16 b1v = vec_add( vec_sra(a7v, twov), a1v); \ - /* b3 = a3 + (a5>>2); */ \ - vec_s16 b3v = vec_add(a3v, vec_sra(a5v, twov)); \ - /* b5 = (a3>>2) - a5; */ \ - vec_s16 b5v = vec_sub( vec_sra(a3v, twov), a5v); \ - /* b7 = a7 - (a1>>2); */ \ - vec_s16 b7v = vec_sub( a7v, vec_sra(a1v, twov)); \ - /* DST(0, b0 + b7); */ \ - d0 = vec_add(b0v, b7v); \ - /* DST(1, b2 + b5); */ \ - d1 = vec_add(b2v, b5v); \ - /* DST(2, b4 + b3); */ \ - d2 = vec_add(b4v, b3v); \ - /* DST(3, b6 + b1); */ \ - d3 = vec_add(b6v, b1v); \ - /* DST(4, b6 - b1); */ \ - d4 = vec_sub(b6v, b1v); \ - /* DST(5, b4 - b3); */ \ - d5 = vec_sub(b4v, b3v); \ - /* DST(6, b2 - b5); */ \ - d6 = vec_sub(b2v, b5v); \ - /* DST(7, b0 - b7); */ \ - d7 = vec_sub(b0v, b7v); \ -} - -#define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \ - /* unaligned load */ \ - vec_u8 hv = vec_ld( 0, dest ); \ - vec_u8 lv = vec_ld( 7, dest ); \ - vec_u8 dstv = vec_perm( hv, lv, (vec_u8)perm_ldv ); \ - vec_s16 idct_sh6 = vec_sra(idctv, sixv); \ - vec_u16 dst16 = (vec_u16)vec_mergeh(zero_u8v, dstv); \ - vec_s16 idstsum = vec_adds(idct_sh6, (vec_s16)dst16); \ - vec_u8 idstsum8 = vec_packsu(zero_s16v, idstsum); \ - vec_u8 edgehv; \ - /* unaligned store */ \ - vec_u8 bodyv = vec_perm( idstsum8, idstsum8, perm_stv );\ - vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv ); \ - lv = vec_sel( lv, bodyv, edgelv ); \ - vec_st( lv, 7, dest ); \ - hv = vec_ld( 0, dest ); \ - edgehv = vec_perm( zero_u8v, sel, perm_stv ); \ - hv = vec_sel( hv, bodyv, edgehv ); \ - vec_st( hv, 0, dest ); \ - } - -static void ff_h264_idct8_add_altivec( uint8_t *dst, DCTELEM *dct, int stride ) { - vec_s16 s0, s1, s2, s3, s4, s5, s6, s7; - vec_s16 d0, d1, d2, d3, d4, d5, d6, d7; - vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7; - - vec_u8 perm_ldv = vec_lvsl(0, dst); - vec_u8 perm_stv = vec_lvsr(8, dst); - - const vec_u16 onev = vec_splat_u16(1); - const vec_u16 twov = vec_splat_u16(2); - const vec_u16 sixv = vec_splat_u16(6); - - const vec_u8 sel = (vec_u8) {0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1}; - LOAD_ZERO; - - dct[0] += 32; // rounding for the >>6 at the end - - s0 = vec_ld(0x00, (int16_t*)dct); - s1 = vec_ld(0x10, (int16_t*)dct); - s2 = vec_ld(0x20, (int16_t*)dct); - s3 = vec_ld(0x30, (int16_t*)dct); - s4 = vec_ld(0x40, (int16_t*)dct); - s5 = vec_ld(0x50, (int16_t*)dct); - s6 = vec_ld(0x60, (int16_t*)dct); - s7 = vec_ld(0x70, (int16_t*)dct); - - IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7, - d0, d1, d2, d3, d4, d5, d6, d7); - - TRANSPOSE8( d0, d1, d2, d3, d4, d5, d6, d7 ); - - IDCT8_1D_ALTIVEC(d0, d1, d2, d3, d4, d5, d6, d7, - idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7); - - ALTIVEC_STORE_SUM_CLIP(&dst[0*stride], idct0, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[1*stride], idct1, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[2*stride], idct2, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[3*stride], idct3, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[4*stride], idct4, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[5*stride], idct5, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[6*stride], idct6, perm_ldv, perm_stv, sel); - ALTIVEC_STORE_SUM_CLIP(&dst[7*stride], idct7, perm_ldv, perm_stv, sel); -} - -static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, DCTELEM *block, int stride, int size) -{ - vec_s16 dc16; - vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner; - LOAD_ZERO; - DECLARE_ALIGNED(16, int, dc); - int i; - - dc = (block[0] + 32) >> 6; - dc16 = vec_splat((vec_s16) vec_lde(0, &dc), 1); - - if (size == 4) - dc16 = vec_sld(dc16, zero_s16v, 8); - dcplus = vec_packsu(dc16, zero_s16v); - dcminus = vec_packsu(vec_sub(zero_s16v, dc16), zero_s16v); - - aligner = vec_lvsr(0, dst); - dcplus = vec_perm(dcplus, dcplus, aligner); - dcminus = vec_perm(dcminus, dcminus, aligner); - - for (i = 0; i < size; i += 4) { - v0 = vec_ld(0, dst+0*stride); - v1 = vec_ld(0, dst+1*stride); - v2 = vec_ld(0, dst+2*stride); - v3 = vec_ld(0, dst+3*stride); - - v0 = vec_adds(v0, dcplus); - v1 = vec_adds(v1, dcplus); - v2 = vec_adds(v2, dcplus); - v3 = vec_adds(v3, dcplus); - - v0 = vec_subs(v0, dcminus); - v1 = vec_subs(v1, dcminus); - v2 = vec_subs(v2, dcminus); - v3 = vec_subs(v3, dcminus); - - vec_st(v0, 0, dst+0*stride); - vec_st(v1, 0, dst+1*stride); - vec_st(v2, 0, dst+2*stride); - vec_st(v3, 0, dst+3*stride); - - dst += 4*stride; - } -} - -static void h264_idct_dc_add_altivec(uint8_t *dst, DCTELEM *block, int stride) -{ - h264_idct_dc_add_internal(dst, block, stride, 4); -} - -static void ff_h264_idct8_dc_add_altivec(uint8_t *dst, DCTELEM *block, int stride) -{ - h264_idct_dc_add_internal(dst, block, stride, 8); -} - -static void ff_h264_idct_add16_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride); - } - } -} - -static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - if(nnzc[ scan8[i] ]) ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride); - else if(block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride); - } -} - -static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i+=4){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) ff_h264_idct8_dc_add_altivec(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct8_add_altivec (dst + block_offset[i], block + i*16, stride); - } - } -} - -static void ff_h264_idct_add8_altivec(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=16; i<16+8; i++){ - if(nnzc[ scan8[i] ]) - ff_h264_idct_add_altivec(dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - else if(block[i*16]) - h264_idct_dc_add_altivec(dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - } -} - -#define transpose4x16(r0, r1, r2, r3) { \ - register vec_u8 r4; \ - register vec_u8 r5; \ - register vec_u8 r6; \ - register vec_u8 r7; \ - \ - r4 = vec_mergeh(r0, r2); /*0, 2 set 0*/ \ - r5 = vec_mergel(r0, r2); /*0, 2 set 1*/ \ - r6 = vec_mergeh(r1, r3); /*1, 3 set 0*/ \ - r7 = vec_mergel(r1, r3); /*1, 3 set 1*/ \ - \ - r0 = vec_mergeh(r4, r6); /*all set 0*/ \ - r1 = vec_mergel(r4, r6); /*all set 1*/ \ - r2 = vec_mergeh(r5, r7); /*all set 2*/ \ - r3 = vec_mergel(r5, r7); /*all set 3*/ \ -} - -static inline void write16x4(uint8_t *dst, int dst_stride, - register vec_u8 r0, register vec_u8 r1, - register vec_u8 r2, register vec_u8 r3) { - DECLARE_ALIGNED(16, unsigned char, result)[64]; - uint32_t *src_int = (uint32_t *)result, *dst_int = (uint32_t *)dst; - int int_dst_stride = dst_stride/4; - - vec_st(r0, 0, result); - vec_st(r1, 16, result); - vec_st(r2, 32, result); - vec_st(r3, 48, result); - /* FIXME: there has to be a better way!!!! */ - *dst_int = *src_int; - *(dst_int+ int_dst_stride) = *(src_int + 1); - *(dst_int+ 2*int_dst_stride) = *(src_int + 2); - *(dst_int+ 3*int_dst_stride) = *(src_int + 3); - *(dst_int+ 4*int_dst_stride) = *(src_int + 4); - *(dst_int+ 5*int_dst_stride) = *(src_int + 5); - *(dst_int+ 6*int_dst_stride) = *(src_int + 6); - *(dst_int+ 7*int_dst_stride) = *(src_int + 7); - *(dst_int+ 8*int_dst_stride) = *(src_int + 8); - *(dst_int+ 9*int_dst_stride) = *(src_int + 9); - *(dst_int+10*int_dst_stride) = *(src_int + 10); - *(dst_int+11*int_dst_stride) = *(src_int + 11); - *(dst_int+12*int_dst_stride) = *(src_int + 12); - *(dst_int+13*int_dst_stride) = *(src_int + 13); - *(dst_int+14*int_dst_stride) = *(src_int + 14); - *(dst_int+15*int_dst_stride) = *(src_int + 15); -} - -/** \brief performs a 6x16 transpose of data in src, and stores it to dst - \todo FIXME: see if we can't spare some vec_lvsl() by them factorizing - out of unaligned_load() */ -#define readAndTranspose16x6(src, src_stride, r8, r9, r10, r11, r12, r13) {\ - register vec_u8 r0 = unaligned_load(0, src); \ - register vec_u8 r1 = unaligned_load( src_stride, src); \ - register vec_u8 r2 = unaligned_load(2* src_stride, src); \ - register vec_u8 r3 = unaligned_load(3* src_stride, src); \ - register vec_u8 r4 = unaligned_load(4* src_stride, src); \ - register vec_u8 r5 = unaligned_load(5* src_stride, src); \ - register vec_u8 r6 = unaligned_load(6* src_stride, src); \ - register vec_u8 r7 = unaligned_load(7* src_stride, src); \ - register vec_u8 r14 = unaligned_load(14*src_stride, src); \ - register vec_u8 r15 = unaligned_load(15*src_stride, src); \ - \ - r8 = unaligned_load( 8*src_stride, src); \ - r9 = unaligned_load( 9*src_stride, src); \ - r10 = unaligned_load(10*src_stride, src); \ - r11 = unaligned_load(11*src_stride, src); \ - r12 = unaligned_load(12*src_stride, src); \ - r13 = unaligned_load(13*src_stride, src); \ - \ - /*Merge first pairs*/ \ - r0 = vec_mergeh(r0, r8); /*0, 8*/ \ - r1 = vec_mergeh(r1, r9); /*1, 9*/ \ - r2 = vec_mergeh(r2, r10); /*2,10*/ \ - r3 = vec_mergeh(r3, r11); /*3,11*/ \ - r4 = vec_mergeh(r4, r12); /*4,12*/ \ - r5 = vec_mergeh(r5, r13); /*5,13*/ \ - r6 = vec_mergeh(r6, r14); /*6,14*/ \ - r7 = vec_mergeh(r7, r15); /*7,15*/ \ - \ - /*Merge second pairs*/ \ - r8 = vec_mergeh(r0, r4); /*0,4, 8,12 set 0*/ \ - r9 = vec_mergel(r0, r4); /*0,4, 8,12 set 1*/ \ - r10 = vec_mergeh(r1, r5); /*1,5, 9,13 set 0*/ \ - r11 = vec_mergel(r1, r5); /*1,5, 9,13 set 1*/ \ - r12 = vec_mergeh(r2, r6); /*2,6,10,14 set 0*/ \ - r13 = vec_mergel(r2, r6); /*2,6,10,14 set 1*/ \ - r14 = vec_mergeh(r3, r7); /*3,7,11,15 set 0*/ \ - r15 = vec_mergel(r3, r7); /*3,7,11,15 set 1*/ \ - \ - /*Third merge*/ \ - r0 = vec_mergeh(r8, r12); /*0,2,4,6,8,10,12,14 set 0*/ \ - r1 = vec_mergel(r8, r12); /*0,2,4,6,8,10,12,14 set 1*/ \ - r2 = vec_mergeh(r9, r13); /*0,2,4,6,8,10,12,14 set 2*/ \ - r4 = vec_mergeh(r10, r14); /*1,3,5,7,9,11,13,15 set 0*/ \ - r5 = vec_mergel(r10, r14); /*1,3,5,7,9,11,13,15 set 1*/ \ - r6 = vec_mergeh(r11, r15); /*1,3,5,7,9,11,13,15 set 2*/ \ - /* Don't need to compute 3 and 7*/ \ - \ - /*Final merge*/ \ - r8 = vec_mergeh(r0, r4); /*all set 0*/ \ - r9 = vec_mergel(r0, r4); /*all set 1*/ \ - r10 = vec_mergeh(r1, r5); /*all set 2*/ \ - r11 = vec_mergel(r1, r5); /*all set 3*/ \ - r12 = vec_mergeh(r2, r6); /*all set 4*/ \ - r13 = vec_mergel(r2, r6); /*all set 5*/ \ - /* Don't need to compute 14 and 15*/ \ - \ -} - -// out: o = |x-y| < a -static inline vec_u8 diff_lt_altivec ( register vec_u8 x, - register vec_u8 y, - register vec_u8 a) { - - register vec_u8 diff = vec_subs(x, y); - register vec_u8 diffneg = vec_subs(y, x); - register vec_u8 o = vec_or(diff, diffneg); /* |x-y| */ - o = (vec_u8)vec_cmplt(o, a); - return o; -} - -static inline vec_u8 h264_deblock_mask ( register vec_u8 p0, - register vec_u8 p1, - register vec_u8 q0, - register vec_u8 q1, - register vec_u8 alpha, - register vec_u8 beta) { - - register vec_u8 mask; - register vec_u8 tempmask; - - mask = diff_lt_altivec(p0, q0, alpha); - tempmask = diff_lt_altivec(p1, p0, beta); - mask = vec_and(mask, tempmask); - tempmask = diff_lt_altivec(q1, q0, beta); - mask = vec_and(mask, tempmask); - - return mask; -} - -// out: newp1 = clip((p2 + ((p0 + q0 + 1) >> 1)) >> 1, p1-tc0, p1+tc0) -static inline vec_u8 h264_deblock_q1(register vec_u8 p0, - register vec_u8 p1, - register vec_u8 p2, - register vec_u8 q0, - register vec_u8 tc0) { - - register vec_u8 average = vec_avg(p0, q0); - register vec_u8 temp; - register vec_u8 uncliped; - register vec_u8 ones; - register vec_u8 max; - register vec_u8 min; - register vec_u8 newp1; - - temp = vec_xor(average, p2); - average = vec_avg(average, p2); /*avg(p2, avg(p0, q0)) */ - ones = vec_splat_u8(1); - temp = vec_and(temp, ones); /*(p2^avg(p0, q0)) & 1 */ - uncliped = vec_subs(average, temp); /*(p2+((p0+q0+1)>>1))>>1 */ - max = vec_adds(p1, tc0); - min = vec_subs(p1, tc0); - newp1 = vec_max(min, uncliped); - newp1 = vec_min(max, newp1); - return newp1; -} - -#define h264_deblock_p0_q0(p0, p1, q0, q1, tc0masked) { \ - \ - const vec_u8 A0v = vec_sl(vec_splat_u8(10), vec_splat_u8(4)); \ - \ - register vec_u8 pq0bit = vec_xor(p0,q0); \ - register vec_u8 q1minus; \ - register vec_u8 p0minus; \ - register vec_u8 stage1; \ - register vec_u8 stage2; \ - register vec_u8 vec160; \ - register vec_u8 delta; \ - register vec_u8 deltaneg; \ - \ - q1minus = vec_nor(q1, q1); /* 255 - q1 */ \ - stage1 = vec_avg(p1, q1minus); /* (p1 - q1 + 256)>>1 */ \ - stage2 = vec_sr(stage1, vec_splat_u8(1)); /* (p1 - q1 + 256)>>2 = 64 + (p1 - q1) >> 2 */ \ - p0minus = vec_nor(p0, p0); /* 255 - p0 */ \ - stage1 = vec_avg(q0, p0minus); /* (q0 - p0 + 256)>>1 */ \ - pq0bit = vec_and(pq0bit, vec_splat_u8(1)); \ - stage2 = vec_avg(stage2, pq0bit); /* 32 + ((q0 - p0)&1 + (p1 - q1) >> 2 + 1) >> 1 */ \ - stage2 = vec_adds(stage2, stage1); /* 160 + ((p0 - q0) + (p1 - q1) >> 2 + 1) >> 1 */ \ - vec160 = vec_ld(0, &A0v); \ - deltaneg = vec_subs(vec160, stage2); /* -d */ \ - delta = vec_subs(stage2, vec160); /* d */ \ - deltaneg = vec_min(tc0masked, deltaneg); \ - delta = vec_min(tc0masked, delta); \ - p0 = vec_subs(p0, deltaneg); \ - q0 = vec_subs(q0, delta); \ - p0 = vec_adds(p0, delta); \ - q0 = vec_adds(q0, deltaneg); \ -} - -#define h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0) { \ - DECLARE_ALIGNED(16, unsigned char, temp)[16]; \ - register vec_u8 alphavec; \ - register vec_u8 betavec; \ - register vec_u8 mask; \ - register vec_u8 p1mask; \ - register vec_u8 q1mask; \ - register vector signed char tc0vec; \ - register vec_u8 finaltc0; \ - register vec_u8 tc0masked; \ - register vec_u8 newp1; \ - register vec_u8 newq1; \ - \ - temp[0] = alpha; \ - temp[1] = beta; \ - alphavec = vec_ld(0, temp); \ - betavec = vec_splat(alphavec, 0x1); \ - alphavec = vec_splat(alphavec, 0x0); \ - mask = h264_deblock_mask(p0, p1, q0, q1, alphavec, betavec); /*if in block */ \ - \ - *((int *)temp) = *((int *)tc0); \ - tc0vec = vec_ld(0, (signed char*)temp); \ - tc0vec = vec_mergeh(tc0vec, tc0vec); \ - tc0vec = vec_mergeh(tc0vec, tc0vec); \ - mask = vec_and(mask, vec_cmpgt(tc0vec, vec_splat_s8(-1))); /* if tc0[i] >= 0 */ \ - finaltc0 = vec_and((vec_u8)tc0vec, mask); /* tc = tc0 */ \ - \ - p1mask = diff_lt_altivec(p2, p0, betavec); \ - p1mask = vec_and(p1mask, mask); /* if ( |p2 - p0| < beta) */ \ - tc0masked = vec_and(p1mask, (vec_u8)tc0vec); \ - finaltc0 = vec_sub(finaltc0, p1mask); /* tc++ */ \ - newp1 = h264_deblock_q1(p0, p1, p2, q0, tc0masked); \ - /*end if*/ \ - \ - q1mask = diff_lt_altivec(q2, q0, betavec); \ - q1mask = vec_and(q1mask, mask); /* if ( |q2 - q0| < beta ) */\ - tc0masked = vec_and(q1mask, (vec_u8)tc0vec); \ - finaltc0 = vec_sub(finaltc0, q1mask); /* tc++ */ \ - newq1 = h264_deblock_q1(p0, q1, q2, q0, tc0masked); \ - /*end if*/ \ - \ - h264_deblock_p0_q0(p0, p1, q0, q1, finaltc0); \ - p1 = newp1; \ - q1 = newq1; \ -} - -static void h264_v_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { - - if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) >= 0) { - register vec_u8 p2 = vec_ld(-3*stride, pix); - register vec_u8 p1 = vec_ld(-2*stride, pix); - register vec_u8 p0 = vec_ld(-1*stride, pix); - register vec_u8 q0 = vec_ld(0, pix); - register vec_u8 q1 = vec_ld(stride, pix); - register vec_u8 q2 = vec_ld(2*stride, pix); - h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0); - vec_st(p1, -2*stride, pix); - vec_st(p0, -1*stride, pix); - vec_st(q0, 0, pix); - vec_st(q1, stride, pix); - } -} - -static void h264_h_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { - - register vec_u8 line0, line1, line2, line3, line4, line5; - if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) < 0) - return; - readAndTranspose16x6(pix-3, stride, line0, line1, line2, line3, line4, line5); - h264_loop_filter_luma_altivec(line0, line1, line2, line3, line4, line5, alpha, beta, tc0); - transpose4x16(line1, line2, line3, line4); - write16x4(pix-2, stride, line1, line2, line3, line4); -} - -static av_always_inline -void weight_h264_WxH_altivec(uint8_t *block, int stride, int log2_denom, int weight, int offset, int w, int h) -{ - int y, aligned; - vec_u8 vblock; - vec_s16 vtemp, vweight, voffset, v0, v1; - vec_u16 vlog2_denom; - DECLARE_ALIGNED(16, int32_t, temp)[4]; - LOAD_ZERO; - - offset <<= log2_denom; - if(log2_denom) offset += 1<<(log2_denom-1); - temp[0] = log2_denom; - temp[1] = weight; - temp[2] = offset; - - vtemp = (vec_s16)vec_ld(0, temp); - vlog2_denom = (vec_u16)vec_splat(vtemp, 1); - vweight = vec_splat(vtemp, 3); - voffset = vec_splat(vtemp, 5); - aligned = !((unsigned long)block & 0xf); - - for (y=0; yput_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec; - c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec; - c->put_no_rnd_vc1_chroma_pixels_tab[0] = put_no_rnd_vc1_chroma_mc8_altivec; - c->avg_no_rnd_vc1_chroma_pixels_tab[0] = avg_no_rnd_vc1_chroma_mc8_altivec; - -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec - - dspfunc(put_h264_qpel, 0, 16); - dspfunc(avg_h264_qpel, 0, 16); -#undef dspfunc - } -} - -void ff_h264dsp_init_ppc(H264DSPContext *c) -{ - if (has_altivec()) { - c->h264_idct_add = ff_h264_idct_add_altivec; - c->h264_idct_add8 = ff_h264_idct_add8_altivec; - c->h264_idct_add16 = ff_h264_idct_add16_altivec; - c->h264_idct_add16intra = ff_h264_idct_add16intra_altivec; - c->h264_idct_dc_add= h264_idct_dc_add_altivec; - c->h264_idct8_dc_add = ff_h264_idct8_dc_add_altivec; - c->h264_idct8_add = ff_h264_idct8_add_altivec; - c->h264_idct8_add4 = ff_h264_idct8_add4_altivec; - c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec; - c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec; - - c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16x16_altivec; - c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels16x8_altivec; - c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels8x16_altivec; - c->weight_h264_pixels_tab[3] = ff_weight_h264_pixels8x8_altivec; - c->weight_h264_pixels_tab[4] = ff_weight_h264_pixels8x4_altivec; - c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16x16_altivec; - c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels16x8_altivec; - c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels8x16_altivec; - c->biweight_h264_pixels_tab[3] = ff_biweight_h264_pixels8x8_altivec; - c->biweight_h264_pixels_tab[4] = ff_biweight_h264_pixels8x4_altivec; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c deleted file mode 100644 index c0a4eb7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c +++ /dev/null @@ -1,783 +0,0 @@ -/* - * Copyright (c) 2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//#define DEBUG_ALIGNMENT -#ifdef DEBUG_ALIGNMENT -#define ASSERT_ALIGNED(ptr) assert(((unsigned long)ptr&0x0000000F)); -#else -#define ASSERT_ALIGNED(ptr) ; -#endif - -/* this code assume that stride % 16 == 0 */ - -#define CHROMA_MC8_ALTIVEC_CORE(BIAS1, BIAS2) \ - vsrc2ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc2uc);\ - vsrc3ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc3uc);\ -\ - psum = vec_mladd(vA, vsrc0ssH, BIAS1);\ - psum = vec_mladd(vB, vsrc1ssH, psum);\ - psum = vec_mladd(vC, vsrc2ssH, psum);\ - psum = vec_mladd(vD, vsrc3ssH, psum);\ - psum = BIAS2(psum);\ - psum = vec_sr(psum, v6us);\ -\ - vdst = vec_ld(0, dst);\ - ppsum = (vec_u8)vec_pack(psum, psum);\ - vfdst = vec_perm(vdst, ppsum, fperm);\ -\ - OP_U8_ALTIVEC(fsum, vfdst, vdst);\ -\ - vec_st(fsum, 0, dst);\ -\ - vsrc0ssH = vsrc2ssH;\ - vsrc1ssH = vsrc3ssH;\ -\ - dst += stride;\ - src += stride; - -#define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \ -\ - vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);\ - vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);\ -\ - psum = vec_mladd(vA, vsrc0ssH, v32ss);\ - psum = vec_mladd(vE, vsrc1ssH, psum);\ - psum = vec_sr(psum, v6us);\ -\ - vdst = vec_ld(0, dst);\ - ppsum = (vec_u8)vec_pack(psum, psum);\ - vfdst = vec_perm(vdst, ppsum, fperm);\ -\ - OP_U8_ALTIVEC(fsum, vfdst, vdst);\ -\ - vec_st(fsum, 0, dst);\ -\ - dst += stride;\ - src += stride; - -#define noop(a) a -#define add28(a) vec_add(v28ss, a) - -static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, - int stride, int h, int x, int y) { - POWERPC_PERF_DECLARE(PREFIX_h264_chroma_mc8_num, 1); - DECLARE_ALIGNED(16, signed int, ABCD)[4] = - {((8 - x) * (8 - y)), - (( x) * (8 - y)), - ((8 - x) * ( y)), - (( x) * ( y))}; - register int i; - vec_u8 fperm; - const vec_s32 vABCD = vec_ld(0, ABCD); - const vec_s16 vA = vec_splat((vec_s16)vABCD, 1); - const vec_s16 vB = vec_splat((vec_s16)vABCD, 3); - const vec_s16 vC = vec_splat((vec_s16)vABCD, 5); - const vec_s16 vD = vec_splat((vec_s16)vABCD, 7); - LOAD_ZERO; - const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5)); - const vec_u16 v6us = vec_splat_u16(6); - register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1; - register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0; - - vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1; - vec_u8 vsrc0uc, vsrc1uc; - vec_s16 vsrc0ssH, vsrc1ssH; - vec_u8 vsrcCuc, vsrc2uc, vsrc3uc; - vec_s16 vsrc2ssH, vsrc3ssH, psum; - vec_u8 vdst, ppsum, vfdst, fsum; - - POWERPC_PERF_START_COUNT(PREFIX_h264_chroma_mc8_num, 1); - - if (((unsigned long)dst) % 16 == 0) { - fperm = (vec_u8){0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x08, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F}; - } else { - fperm = (vec_u8){0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F}; - } - - vsrcAuc = vec_ld(0, src); - - if (loadSecond) - vsrcBuc = vec_ld(16, src); - vsrcperm0 = vec_lvsl(0, src); - vsrcperm1 = vec_lvsl(1, src); - - vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0); - if (reallyBadAlign) - vsrc1uc = vsrcBuc; - else - vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); - - vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc); - vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc); - - if (ABCD[3]) { - if (!loadSecond) {// -> !reallyBadAlign - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); - vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); - vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); - - CHROMA_MC8_ALTIVEC_CORE(v32ss, noop) - } - } else { - vec_u8 vsrcDuc; - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); - vsrcDuc = vec_ld(stride + 16, src); - vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); - if (reallyBadAlign) - vsrc3uc = vsrcDuc; - else - vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); - - CHROMA_MC8_ALTIVEC_CORE(v32ss, noop) - } - } - } else { - const vec_s16 vE = vec_add(vB, vC); - if (ABCD[2]) { // x == 0 B == 0 - if (!loadSecond) {// -> !reallyBadAlign - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); - vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); - CHROMA_MC8_ALTIVEC_CORE_SIMPLE - - vsrc0uc = vsrc1uc; - } - } else { - vec_u8 vsrcDuc; - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); - vsrcDuc = vec_ld(stride + 15, src); - vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); - CHROMA_MC8_ALTIVEC_CORE_SIMPLE - - vsrc0uc = vsrc1uc; - } - } - } else { // y == 0 C == 0 - if (!loadSecond) {// -> !reallyBadAlign - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(0, src); - vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); - vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); - - CHROMA_MC8_ALTIVEC_CORE_SIMPLE - } - } else { - vec_u8 vsrcDuc; - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(0, src); - vsrcDuc = vec_ld(15, src); - vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); - if (reallyBadAlign) - vsrc1uc = vsrcDuc; - else - vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); - - CHROMA_MC8_ALTIVEC_CORE_SIMPLE - } - } - } - } - POWERPC_PERF_STOP_COUNT(PREFIX_h264_chroma_mc8_num, 1); -} - -/* this code assume that stride % 16 == 0 */ -static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) { - DECLARE_ALIGNED(16, signed int, ABCD)[4] = - {((8 - x) * (8 - y)), - (( x) * (8 - y)), - ((8 - x) * ( y)), - (( x) * ( y))}; - register int i; - vec_u8 fperm; - const vec_s32 vABCD = vec_ld(0, ABCD); - const vec_s16 vA = vec_splat((vec_s16)vABCD, 1); - const vec_s16 vB = vec_splat((vec_s16)vABCD, 3); - const vec_s16 vC = vec_splat((vec_s16)vABCD, 5); - const vec_s16 vD = vec_splat((vec_s16)vABCD, 7); - LOAD_ZERO; - const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4)); - const vec_u16 v6us = vec_splat_u16(6); - register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1; - register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0; - - vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1; - vec_u8 vsrc0uc, vsrc1uc; - vec_s16 vsrc0ssH, vsrc1ssH; - vec_u8 vsrcCuc, vsrc2uc, vsrc3uc; - vec_s16 vsrc2ssH, vsrc3ssH, psum; - vec_u8 vdst, ppsum, vfdst, fsum; - - if (((unsigned long)dst) % 16 == 0) { - fperm = (vec_u8){0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x08, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F}; - } else { - fperm = (vec_u8){0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F}; - } - - vsrcAuc = vec_ld(0, src); - - if (loadSecond) - vsrcBuc = vec_ld(16, src); - vsrcperm0 = vec_lvsl(0, src); - vsrcperm1 = vec_lvsl(1, src); - - vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0); - if (reallyBadAlign) - vsrc1uc = vsrcBuc; - else - vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); - - vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc); - vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc); - - if (!loadSecond) {// -> !reallyBadAlign - for (i = 0 ; i < h ; i++) { - - - vsrcCuc = vec_ld(stride + 0, src); - - vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); - vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); - - CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28) - } - } else { - vec_u8 vsrcDuc; - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); - vsrcDuc = vec_ld(stride + 16, src); - - vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); - if (reallyBadAlign) - vsrc3uc = vsrcDuc; - else - vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); - - CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28) - } - } -} - -#undef noop -#undef add28 -#undef CHROMA_MC8_ALTIVEC_CORE - -/* this code assume stride % 16 == 0 */ -static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) { - POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_h_lowpass_num, 1); - register int i; - - LOAD_ZERO; - const vec_u8 permM2 = vec_lvsl(-2, src); - const vec_u8 permM1 = vec_lvsl(-1, src); - const vec_u8 permP0 = vec_lvsl(+0, src); - const vec_u8 permP1 = vec_lvsl(+1, src); - const vec_u8 permP2 = vec_lvsl(+2, src); - const vec_u8 permP3 = vec_lvsl(+3, src); - const vec_s16 v5ss = vec_splat_s16(5); - const vec_u16 v5us = vec_splat_u16(5); - const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); - - vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; - - register int align = ((((unsigned long)src) - 2) % 16); - - vec_s16 srcP0A, srcP0B, srcP1A, srcP1B, - srcP2A, srcP2B, srcP3A, srcP3B, - srcM1A, srcM1B, srcM2A, srcM2B, - sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, - pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, - psumA, psumB, sumA, sumB; - - vec_u8 sum, vdst, fsum; - - POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_h_lowpass_num, 1); - - for (i = 0 ; i < 16 ; i ++) { - vec_u8 srcR1 = vec_ld(-2, src); - vec_u8 srcR2 = vec_ld(14, src); - - switch (align) { - default: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = vec_perm(srcR1, srcR2, permP3); - } break; - case 11: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = srcR2; - } break; - case 12: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = srcR2; - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 13: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = srcR2; - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 14: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = srcR2; - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 15: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = srcR2; - srcP0 = vec_perm(srcR2, srcR3, permP0); - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - } - - srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0); - srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0); - srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1); - srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1); - - srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2); - srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2); - srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3); - srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3); - - srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1); - srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1); - srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2); - srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2); - - sum1A = vec_adds(srcP0A, srcP1A); - sum1B = vec_adds(srcP0B, srcP1B); - sum2A = vec_adds(srcM1A, srcP2A); - sum2B = vec_adds(srcM1B, srcP2B); - sum3A = vec_adds(srcM2A, srcP3A); - sum3B = vec_adds(srcM2B, srcP3B); - - pp1A = vec_mladd(sum1A, v20ss, v16ss); - pp1B = vec_mladd(sum1B, v20ss, v16ss); - - pp2A = vec_mladd(sum2A, v5ss, zero_s16v); - pp2B = vec_mladd(sum2B, v5ss, zero_s16v); - - pp3A = vec_add(sum3A, pp1A); - pp3B = vec_add(sum3B, pp1B); - - psumA = vec_sub(pp3A, pp2A); - psumB = vec_sub(pp3B, pp2B); - - sumA = vec_sra(psumA, v5us); - sumB = vec_sra(psumB, v5us); - - sum = vec_packsu(sumA, sumB); - - ASSERT_ALIGNED(dst); - vdst = vec_ld(0, dst); - - OP_U8_ALTIVEC(fsum, sum, vdst); - - vec_st(fsum, 0, dst); - - src += srcStride; - dst += dstStride; - } - POWERPC_PERF_STOP_COUNT(PREFIX_h264_qpel16_h_lowpass_num, 1); -} - -/* this code assume stride % 16 == 0 */ -static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) { - POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_v_lowpass_num, 1); - - register int i; - - LOAD_ZERO; - const vec_u8 perm = vec_lvsl(0, src); - const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vec_u16 v5us = vec_splat_u16(5); - const vec_s16 v5ss = vec_splat_s16(5); - const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); - - uint8_t *srcbis = src - (srcStride * 2); - - const vec_u8 srcM2a = vec_ld(0, srcbis); - const vec_u8 srcM2b = vec_ld(16, srcbis); - const vec_u8 srcM2 = vec_perm(srcM2a, srcM2b, perm); - //srcbis += srcStride; - const vec_u8 srcM1a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcM1b = vec_ld(16, srcbis); - const vec_u8 srcM1 = vec_perm(srcM1a, srcM1b, perm); - //srcbis += srcStride; - const vec_u8 srcP0a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcP0b = vec_ld(16, srcbis); - const vec_u8 srcP0 = vec_perm(srcP0a, srcP0b, perm); - //srcbis += srcStride; - const vec_u8 srcP1a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcP1b = vec_ld(16, srcbis); - const vec_u8 srcP1 = vec_perm(srcP1a, srcP1b, perm); - //srcbis += srcStride; - const vec_u8 srcP2a = vec_ld(0, srcbis += srcStride); - const vec_u8 srcP2b = vec_ld(16, srcbis); - const vec_u8 srcP2 = vec_perm(srcP2a, srcP2b, perm); - //srcbis += srcStride; - - vec_s16 srcM2ssA = (vec_s16) vec_mergeh(zero_u8v, srcM2); - vec_s16 srcM2ssB = (vec_s16) vec_mergel(zero_u8v, srcM2); - vec_s16 srcM1ssA = (vec_s16) vec_mergeh(zero_u8v, srcM1); - vec_s16 srcM1ssB = (vec_s16) vec_mergel(zero_u8v, srcM1); - vec_s16 srcP0ssA = (vec_s16) vec_mergeh(zero_u8v, srcP0); - vec_s16 srcP0ssB = (vec_s16) vec_mergel(zero_u8v, srcP0); - vec_s16 srcP1ssA = (vec_s16) vec_mergeh(zero_u8v, srcP1); - vec_s16 srcP1ssB = (vec_s16) vec_mergel(zero_u8v, srcP1); - vec_s16 srcP2ssA = (vec_s16) vec_mergeh(zero_u8v, srcP2); - vec_s16 srcP2ssB = (vec_s16) vec_mergel(zero_u8v, srcP2); - - vec_s16 pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, - psumA, psumB, sumA, sumB, - srcP3ssA, srcP3ssB, - sum1A, sum1B, sum2A, sum2B, sum3A, sum3B; - - vec_u8 sum, vdst, fsum, srcP3a, srcP3b, srcP3; - - POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_v_lowpass_num, 1); - - for (i = 0 ; i < 16 ; i++) { - srcP3a = vec_ld(0, srcbis += srcStride); - srcP3b = vec_ld(16, srcbis); - srcP3 = vec_perm(srcP3a, srcP3b, perm); - srcP3ssA = (vec_s16) vec_mergeh(zero_u8v, srcP3); - srcP3ssB = (vec_s16) vec_mergel(zero_u8v, srcP3); - //srcbis += srcStride; - - sum1A = vec_adds(srcP0ssA, srcP1ssA); - sum1B = vec_adds(srcP0ssB, srcP1ssB); - sum2A = vec_adds(srcM1ssA, srcP2ssA); - sum2B = vec_adds(srcM1ssB, srcP2ssB); - sum3A = vec_adds(srcM2ssA, srcP3ssA); - sum3B = vec_adds(srcM2ssB, srcP3ssB); - - srcM2ssA = srcM1ssA; - srcM2ssB = srcM1ssB; - srcM1ssA = srcP0ssA; - srcM1ssB = srcP0ssB; - srcP0ssA = srcP1ssA; - srcP0ssB = srcP1ssB; - srcP1ssA = srcP2ssA; - srcP1ssB = srcP2ssB; - srcP2ssA = srcP3ssA; - srcP2ssB = srcP3ssB; - - pp1A = vec_mladd(sum1A, v20ss, v16ss); - pp1B = vec_mladd(sum1B, v20ss, v16ss); - - pp2A = vec_mladd(sum2A, v5ss, zero_s16v); - pp2B = vec_mladd(sum2B, v5ss, zero_s16v); - - pp3A = vec_add(sum3A, pp1A); - pp3B = vec_add(sum3B, pp1B); - - psumA = vec_sub(pp3A, pp2A); - psumB = vec_sub(pp3B, pp2B); - - sumA = vec_sra(psumA, v5us); - sumB = vec_sra(psumB, v5us); - - sum = vec_packsu(sumA, sumB); - - ASSERT_ALIGNED(dst); - vdst = vec_ld(0, dst); - - OP_U8_ALTIVEC(fsum, sum, vdst); - - vec_st(fsum, 0, dst); - - dst += dstStride; - } - POWERPC_PERF_STOP_COUNT(PREFIX_h264_qpel16_v_lowpass_num, 1); -} - -/* this code assume stride % 16 == 0 *and* tmp is properly aligned */ -static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, uint8_t * src, int dstStride, int tmpStride, int srcStride) { - POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_hv_lowpass_num, 1); - register int i; - LOAD_ZERO; - const vec_u8 permM2 = vec_lvsl(-2, src); - const vec_u8 permM1 = vec_lvsl(-1, src); - const vec_u8 permP0 = vec_lvsl(+0, src); - const vec_u8 permP1 = vec_lvsl(+1, src); - const vec_u8 permP2 = vec_lvsl(+2, src); - const vec_u8 permP3 = vec_lvsl(+3, src); - const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vec_u32 v10ui = vec_splat_u32(10); - const vec_s16 v5ss = vec_splat_s16(5); - const vec_s16 v1ss = vec_splat_s16(1); - const vec_s32 v512si = vec_sl(vec_splat_s32(1),vec_splat_u32(9)); - const vec_u32 v16ui = vec_sl(vec_splat_u32(1),vec_splat_u32(4)); - - register int align = ((((unsigned long)src) - 2) % 16); - - vec_s16 srcP0A, srcP0B, srcP1A, srcP1B, - srcP2A, srcP2B, srcP3A, srcP3B, - srcM1A, srcM1B, srcM2A, srcM2B, - sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, - pp1A, pp1B, pp2A, pp2B, psumA, psumB; - - const vec_u8 mperm = (const vec_u8) - {0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B, - 0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F}; - int16_t *tmpbis = tmp; - - vec_s16 tmpM1ssA, tmpM1ssB, tmpM2ssA, tmpM2ssB, - tmpP0ssA, tmpP0ssB, tmpP1ssA, tmpP1ssB, - tmpP2ssA, tmpP2ssB; - - vec_s32 pp1Ae, pp1Ao, pp1Be, pp1Bo, pp2Ae, pp2Ao, pp2Be, pp2Bo, - pp3Ae, pp3Ao, pp3Be, pp3Bo, pp1cAe, pp1cAo, pp1cBe, pp1cBo, - pp32Ae, pp32Ao, pp32Be, pp32Bo, sumAe, sumAo, sumBe, sumBo, - ssumAe, ssumAo, ssumBe, ssumBo; - vec_u8 fsum, sumv, sum, vdst; - vec_s16 ssume, ssumo; - - POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_hv_lowpass_num, 1); - src -= (2 * srcStride); - for (i = 0 ; i < 21 ; i ++) { - vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; - vec_u8 srcR1 = vec_ld(-2, src); - vec_u8 srcR2 = vec_ld(14, src); - - switch (align) { - default: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = vec_perm(srcR1, srcR2, permP3); - } break; - case 11: { - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = vec_perm(srcR1, srcR2, permP2); - srcP3 = srcR2; - } break; - case 12: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = vec_perm(srcR1, srcR2, permP1); - srcP2 = srcR2; - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 13: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = vec_perm(srcR1, srcR2, permP0); - srcP1 = srcR2; - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 14: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = vec_perm(srcR1, srcR2, permM1); - srcP0 = srcR2; - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - case 15: { - vec_u8 srcR3 = vec_ld(30, src); - srcM2 = vec_perm(srcR1, srcR2, permM2); - srcM1 = srcR2; - srcP0 = vec_perm(srcR2, srcR3, permP0); - srcP1 = vec_perm(srcR2, srcR3, permP1); - srcP2 = vec_perm(srcR2, srcR3, permP2); - srcP3 = vec_perm(srcR2, srcR3, permP3); - } break; - } - - srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0); - srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0); - srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1); - srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1); - - srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2); - srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2); - srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3); - srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3); - - srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1); - srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1); - srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2); - srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2); - - sum1A = vec_adds(srcP0A, srcP1A); - sum1B = vec_adds(srcP0B, srcP1B); - sum2A = vec_adds(srcM1A, srcP2A); - sum2B = vec_adds(srcM1B, srcP2B); - sum3A = vec_adds(srcM2A, srcP3A); - sum3B = vec_adds(srcM2B, srcP3B); - - pp1A = vec_mladd(sum1A, v20ss, sum3A); - pp1B = vec_mladd(sum1B, v20ss, sum3B); - - pp2A = vec_mladd(sum2A, v5ss, zero_s16v); - pp2B = vec_mladd(sum2B, v5ss, zero_s16v); - - psumA = vec_sub(pp1A, pp2A); - psumB = vec_sub(pp1B, pp2B); - - vec_st(psumA, 0, tmp); - vec_st(psumB, 16, tmp); - - src += srcStride; - tmp += tmpStride; /* int16_t*, and stride is 16, so it's OK here */ - } - - tmpM2ssA = vec_ld(0, tmpbis); - tmpM2ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpM1ssA = vec_ld(0, tmpbis); - tmpM1ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpP0ssA = vec_ld(0, tmpbis); - tmpP0ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpP1ssA = vec_ld(0, tmpbis); - tmpP1ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - tmpP2ssA = vec_ld(0, tmpbis); - tmpP2ssB = vec_ld(16, tmpbis); - tmpbis += tmpStride; - - for (i = 0 ; i < 16 ; i++) { - const vec_s16 tmpP3ssA = vec_ld(0, tmpbis); - const vec_s16 tmpP3ssB = vec_ld(16, tmpbis); - - const vec_s16 sum1A = vec_adds(tmpP0ssA, tmpP1ssA); - const vec_s16 sum1B = vec_adds(tmpP0ssB, tmpP1ssB); - const vec_s16 sum2A = vec_adds(tmpM1ssA, tmpP2ssA); - const vec_s16 sum2B = vec_adds(tmpM1ssB, tmpP2ssB); - const vec_s16 sum3A = vec_adds(tmpM2ssA, tmpP3ssA); - const vec_s16 sum3B = vec_adds(tmpM2ssB, tmpP3ssB); - - tmpbis += tmpStride; - - tmpM2ssA = tmpM1ssA; - tmpM2ssB = tmpM1ssB; - tmpM1ssA = tmpP0ssA; - tmpM1ssB = tmpP0ssB; - tmpP0ssA = tmpP1ssA; - tmpP0ssB = tmpP1ssB; - tmpP1ssA = tmpP2ssA; - tmpP1ssB = tmpP2ssB; - tmpP2ssA = tmpP3ssA; - tmpP2ssB = tmpP3ssB; - - pp1Ae = vec_mule(sum1A, v20ss); - pp1Ao = vec_mulo(sum1A, v20ss); - pp1Be = vec_mule(sum1B, v20ss); - pp1Bo = vec_mulo(sum1B, v20ss); - - pp2Ae = vec_mule(sum2A, v5ss); - pp2Ao = vec_mulo(sum2A, v5ss); - pp2Be = vec_mule(sum2B, v5ss); - pp2Bo = vec_mulo(sum2B, v5ss); - - pp3Ae = vec_sra((vec_s32)sum3A, v16ui); - pp3Ao = vec_mulo(sum3A, v1ss); - pp3Be = vec_sra((vec_s32)sum3B, v16ui); - pp3Bo = vec_mulo(sum3B, v1ss); - - pp1cAe = vec_add(pp1Ae, v512si); - pp1cAo = vec_add(pp1Ao, v512si); - pp1cBe = vec_add(pp1Be, v512si); - pp1cBo = vec_add(pp1Bo, v512si); - - pp32Ae = vec_sub(pp3Ae, pp2Ae); - pp32Ao = vec_sub(pp3Ao, pp2Ao); - pp32Be = vec_sub(pp3Be, pp2Be); - pp32Bo = vec_sub(pp3Bo, pp2Bo); - - sumAe = vec_add(pp1cAe, pp32Ae); - sumAo = vec_add(pp1cAo, pp32Ao); - sumBe = vec_add(pp1cBe, pp32Be); - sumBo = vec_add(pp1cBo, pp32Bo); - - ssumAe = vec_sra(sumAe, v10ui); - ssumAo = vec_sra(sumAo, v10ui); - ssumBe = vec_sra(sumBe, v10ui); - ssumBo = vec_sra(sumBo, v10ui); - - ssume = vec_packs(ssumAe, ssumBe); - ssumo = vec_packs(ssumAo, ssumBo); - - sumv = vec_packsu(ssume, ssumo); - sum = vec_perm(sumv, sumv, mperm); - - ASSERT_ALIGNED(dst); - vdst = vec_ld(0, dst); - - OP_U8_ALTIVEC(fsum, sum, vdst); - - vec_st(fsum, 0, dst); - - dst += dstStride; - } - POWERPC_PERF_STOP_COUNT(PREFIX_h264_qpel16_hv_lowpass_num, 1); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/idct_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/idct_altivec.c deleted file mode 100644 index 7c6b79e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/idct_altivec.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2001 Michel Lespinasse - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * NOTE: This code is based on GPL code from the libmpeg2 project. The - * author, Michel Lespinasses, has given explicit permission to release - * under LGPL as part of FFmpeg. - */ - -/* - * FFmpeg integration by Dieter Shirley - * - * This file is a direct copy of the AltiVec IDCT module from the libmpeg2 - * project. I've deleted all of the libmpeg2-specific code, renamed the - * functions and reordered the function parameters. The only change to the - * IDCT function itself was to factor out the partial transposition, and to - * perform a full transpose at the end of the function. - */ - - -#include /* malloc(), free() */ -#include -#include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif -#include "libavcodec/dsputil.h" -#include "types_altivec.h" -#include "dsputil_ppc.h" -#include "dsputil_altivec.h" - -#define IDCT_HALF \ - /* 1st stage */ \ - t1 = vec_mradds (a1, vx7, vx1 ); \ - t8 = vec_mradds (a1, vx1, vec_subs (zero, vx7)); \ - t7 = vec_mradds (a2, vx5, vx3); \ - t3 = vec_mradds (ma2, vx3, vx5); \ - \ - /* 2nd stage */ \ - t5 = vec_adds (vx0, vx4); \ - t0 = vec_subs (vx0, vx4); \ - t2 = vec_mradds (a0, vx6, vx2); \ - t4 = vec_mradds (a0, vx2, vec_subs (zero, vx6)); \ - t6 = vec_adds (t8, t3); \ - t3 = vec_subs (t8, t3); \ - t8 = vec_subs (t1, t7); \ - t1 = vec_adds (t1, t7); \ - \ - /* 3rd stage */ \ - t7 = vec_adds (t5, t2); \ - t2 = vec_subs (t5, t2); \ - t5 = vec_adds (t0, t4); \ - t0 = vec_subs (t0, t4); \ - t4 = vec_subs (t8, t3); \ - t3 = vec_adds (t8, t3); \ - \ - /* 4th stage */ \ - vy0 = vec_adds (t7, t1); \ - vy7 = vec_subs (t7, t1); \ - vy1 = vec_mradds (c4, t3, t5); \ - vy6 = vec_mradds (mc4, t3, t5); \ - vy2 = vec_mradds (c4, t4, t0); \ - vy5 = vec_mradds (mc4, t4, t0); \ - vy3 = vec_adds (t2, t6); \ - vy4 = vec_subs (t2, t6); - - -#define IDCT \ - vec_s16 vx0, vx1, vx2, vx3, vx4, vx5, vx6, vx7; \ - vec_s16 vy0, vy1, vy2, vy3, vy4, vy5, vy6, vy7; \ - vec_s16 a0, a1, a2, ma2, c4, mc4, zero, bias; \ - vec_s16 t0, t1, t2, t3, t4, t5, t6, t7, t8; \ - vec_u16 shift; \ - \ - c4 = vec_splat (constants[0], 0); \ - a0 = vec_splat (constants[0], 1); \ - a1 = vec_splat (constants[0], 2); \ - a2 = vec_splat (constants[0], 3); \ - mc4 = vec_splat (constants[0], 4); \ - ma2 = vec_splat (constants[0], 5); \ - bias = (vec_s16)vec_splat ((vec_s32)constants[0], 3); \ - \ - zero = vec_splat_s16 (0); \ - shift = vec_splat_u16 (4); \ - \ - vx0 = vec_mradds (vec_sl (block[0], shift), constants[1], zero); \ - vx1 = vec_mradds (vec_sl (block[1], shift), constants[2], zero); \ - vx2 = vec_mradds (vec_sl (block[2], shift), constants[3], zero); \ - vx3 = vec_mradds (vec_sl (block[3], shift), constants[4], zero); \ - vx4 = vec_mradds (vec_sl (block[4], shift), constants[1], zero); \ - vx5 = vec_mradds (vec_sl (block[5], shift), constants[4], zero); \ - vx6 = vec_mradds (vec_sl (block[6], shift), constants[3], zero); \ - vx7 = vec_mradds (vec_sl (block[7], shift), constants[2], zero); \ - \ - IDCT_HALF \ - \ - vx0 = vec_mergeh (vy0, vy4); \ - vx1 = vec_mergel (vy0, vy4); \ - vx2 = vec_mergeh (vy1, vy5); \ - vx3 = vec_mergel (vy1, vy5); \ - vx4 = vec_mergeh (vy2, vy6); \ - vx5 = vec_mergel (vy2, vy6); \ - vx6 = vec_mergeh (vy3, vy7); \ - vx7 = vec_mergel (vy3, vy7); \ - \ - vy0 = vec_mergeh (vx0, vx4); \ - vy1 = vec_mergel (vx0, vx4); \ - vy2 = vec_mergeh (vx1, vx5); \ - vy3 = vec_mergel (vx1, vx5); \ - vy4 = vec_mergeh (vx2, vx6); \ - vy5 = vec_mergel (vx2, vx6); \ - vy6 = vec_mergeh (vx3, vx7); \ - vy7 = vec_mergel (vx3, vx7); \ - \ - vx0 = vec_adds (vec_mergeh (vy0, vy4), bias); \ - vx1 = vec_mergel (vy0, vy4); \ - vx2 = vec_mergeh (vy1, vy5); \ - vx3 = vec_mergel (vy1, vy5); \ - vx4 = vec_mergeh (vy2, vy6); \ - vx5 = vec_mergel (vy2, vy6); \ - vx6 = vec_mergeh (vy3, vy7); \ - vx7 = vec_mergel (vy3, vy7); \ - \ - IDCT_HALF \ - \ - shift = vec_splat_u16 (6); \ - vx0 = vec_sra (vy0, shift); \ - vx1 = vec_sra (vy1, shift); \ - vx2 = vec_sra (vy2, shift); \ - vx3 = vec_sra (vy3, shift); \ - vx4 = vec_sra (vy4, shift); \ - vx5 = vec_sra (vy5, shift); \ - vx6 = vec_sra (vy6, shift); \ - vx7 = vec_sra (vy7, shift); - - -static const vec_s16 constants[5] = { - {23170, 13573, 6518, 21895, -23170, -21895, 32, 31}, - {16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725}, - {22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521}, - {21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692}, - {19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722} -}; - -void idct_put_altivec(uint8_t* dest, int stride, int16_t *blk) -{ -POWERPC_PERF_DECLARE(altivec_idct_put_num, 1); - vec_s16 *block = (vec_s16*)blk; - vec_u8 tmp; - -#if CONFIG_POWERPC_PERF -POWERPC_PERF_START_COUNT(altivec_idct_put_num, 1); -#endif - IDCT - -#define COPY(dest,src) \ - tmp = vec_packsu (src, src); \ - vec_ste ((vec_u32)tmp, 0, (unsigned int *)dest); \ - vec_ste ((vec_u32)tmp, 4, (unsigned int *)dest); - - COPY (dest, vx0) dest += stride; - COPY (dest, vx1) dest += stride; - COPY (dest, vx2) dest += stride; - COPY (dest, vx3) dest += stride; - COPY (dest, vx4) dest += stride; - COPY (dest, vx5) dest += stride; - COPY (dest, vx6) dest += stride; - COPY (dest, vx7) - -POWERPC_PERF_STOP_COUNT(altivec_idct_put_num, 1); -} - -void idct_add_altivec(uint8_t* dest, int stride, int16_t *blk) -{ -POWERPC_PERF_DECLARE(altivec_idct_add_num, 1); - vec_s16 *block = (vec_s16*)blk; - vec_u8 tmp; - vec_s16 tmp2, tmp3; - vec_u8 perm0; - vec_u8 perm1; - vec_u8 p0, p1, p; - -#if CONFIG_POWERPC_PERF -POWERPC_PERF_START_COUNT(altivec_idct_add_num, 1); -#endif - - IDCT - - p0 = vec_lvsl (0, dest); - p1 = vec_lvsl (stride, dest); - p = vec_splat_u8 (-1); - perm0 = vec_mergeh (p, p0); - perm1 = vec_mergeh (p, p1); - -#define ADD(dest,src,perm) \ - /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ - tmp = vec_ld (0, dest); \ - tmp2 = (vec_s16)vec_perm (tmp, (vec_u8)zero, perm); \ - tmp3 = vec_adds (tmp2, src); \ - tmp = vec_packsu (tmp3, tmp3); \ - vec_ste ((vec_u32)tmp, 0, (unsigned int *)dest); \ - vec_ste ((vec_u32)tmp, 4, (unsigned int *)dest); - - ADD (dest, vx0, perm0) dest += stride; - ADD (dest, vx1, perm1) dest += stride; - ADD (dest, vx2, perm0) dest += stride; - ADD (dest, vx3, perm1) dest += stride; - ADD (dest, vx4, perm0) dest += stride; - ADD (dest, vx5, perm1) dest += stride; - ADD (dest, vx6, perm0) dest += stride; - ADD (dest, vx7, perm1) - -POWERPC_PERF_STOP_COUNT(altivec_idct_add_num, 1); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/int_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/int_altivec.c deleted file mode 100644 index 7fb11dd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/int_altivec.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2007 Luca Barbato - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - ** @file - ** integer misc ops. - **/ - -#include "config.h" -#if HAVE_ALTIVEC_H -#include -#endif - -#include "libavcodec/dsputil.h" - -#include "dsputil_altivec.h" - -#include "types_altivec.h" - -static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2, - int size) { - int i, size16; - vector signed char vpix1; - vector signed short vpix2, vdiff, vpix1l,vpix1h; - union { vector signed int vscore; - int32_t score[4]; - } u; - u.vscore = vec_splat_s32(0); -// -//XXX lazy way, fix it later - -#define vec_unaligned_load(b) \ - vec_perm(vec_ld(0,b),vec_ld(15,b),vec_lvsl(0, b)); - - size16 = size >> 4; - while(size16) { -// score += (pix1[i]-pix2[i])*(pix1[i]-pix2[i]); - //load pix1 and the first batch of pix2 - - vpix1 = vec_unaligned_load(pix1); - vpix2 = vec_unaligned_load(pix2); - pix2 += 8; - //unpack - vpix1h = vec_unpackh(vpix1); - vdiff = vec_sub(vpix1h, vpix2); - vpix1l = vec_unpackl(vpix1); - // load another batch from pix2 - vpix2 = vec_unaligned_load(pix2); - u.vscore = vec_msum(vdiff, vdiff, u.vscore); - vdiff = vec_sub(vpix1l, vpix2); - u.vscore = vec_msum(vdiff, vdiff, u.vscore); - pix1 += 16; - pix2 += 8; - size16--; - } - u.vscore = vec_sums(u.vscore, vec_splat_s32(0)); - - size %= 16; - for (i = 0; i < size; i++) { - u.score[3] += (pix1[i]-pix2[i])*(pix1[i]-pix2[i]); - } - return u.score[3]; -} - -static int32_t scalarproduct_int16_altivec(int16_t * v1, int16_t * v2, int order, const int shift) -{ - int i; - LOAD_ZERO; - register vec_s16 vec1, *pv; - register vec_s32 res = vec_splat_s32(0), t; - register vec_u32 shifts; - int32_t ires; - - shifts = zero_u32v; - if(shift & 0x10) shifts = vec_add(shifts, vec_sl(vec_splat_u32(0x08), vec_splat_u32(0x1))); - if(shift & 0x08) shifts = vec_add(shifts, vec_splat_u32(0x08)); - if(shift & 0x04) shifts = vec_add(shifts, vec_splat_u32(0x04)); - if(shift & 0x02) shifts = vec_add(shifts, vec_splat_u32(0x02)); - if(shift & 0x01) shifts = vec_add(shifts, vec_splat_u32(0x01)); - - for(i = 0; i < order; i += 8){ - pv = (vec_s16*)v1; - vec1 = vec_perm(pv[0], pv[1], vec_lvsl(0, v1)); - t = vec_msum(vec1, vec_ld(0, v2), zero_s32v); - t = vec_sr(t, shifts); - res = vec_sums(t, res); - v1 += 8; - v2 += 8; - } - res = vec_splat(res, 3); - vec_ste(res, 0, &ires); - return ires; -} - -static int32_t scalarproduct_and_madd_int16_altivec(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul) -{ - LOAD_ZERO; - vec_s16 *pv1 = (vec_s16*)v1; - vec_s16 *pv2 = (vec_s16*)v2; - vec_s16 *pv3 = (vec_s16*)v3; - register vec_s16 muls = {mul,mul,mul,mul,mul,mul,mul,mul}; - register vec_s16 t0, t1, i0, i1; - register vec_s16 i2 = pv2[0], i3 = pv3[0]; - register vec_s32 res = zero_s32v; - register vec_u8 align = vec_lvsl(0, v2); - int32_t ires; - order >>= 4; - do { - t0 = vec_perm(i2, pv2[1], align); - i2 = pv2[2]; - t1 = vec_perm(pv2[1], i2, align); - i0 = pv1[0]; - i1 = pv1[1]; - res = vec_msum(t0, i0, res); - res = vec_msum(t1, i1, res); - t0 = vec_perm(i3, pv3[1], align); - i3 = pv3[2]; - t1 = vec_perm(pv3[1], i3, align); - pv1[0] = vec_mladd(t0, muls, i0); - pv1[1] = vec_mladd(t1, muls, i1); - pv1 += 2; - pv2 += 2; - pv3 += 2; - } while(--order); - res = vec_splat(vec_sums(res, zero_s32v), 3); - vec_ste(res, 0, &ires); - return ires; -} - -void int_init_altivec(DSPContext* c, AVCodecContext *avctx) -{ - c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec; - c->scalarproduct_int16 = scalarproduct_int16_altivec; - c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_altivec; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/mathops.h b/tizen/distrib/ffmpeg/libavcodec/ppc/mathops.h deleted file mode 100644 index dbd714f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/mathops.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * simple math operations - * Copyright (c) 2001, 2002 Fabrice Bellard - * Copyright (c) 2006 Michael Niedermayer et al - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PPC_MATHOPS_H -#define AVCODEC_PPC_MATHOPS_H - -#include -#include "config.h" -#include "libavutil/common.h" - -#if HAVE_PPC4XX -/* signed 16x16 -> 32 multiply add accumulate */ -#define MAC16(rt, ra, rb) \ - __asm__ ("maclhw %0, %2, %3" : "=r" (rt) : "0" (rt), "r" (ra), "r" (rb)); - -/* signed 16x16 -> 32 multiply */ -#define MUL16(ra, rb) \ - ({ int __rt; \ - __asm__ ("mullhw %0, %1, %2" : "=r" (__rt) : "r" (ra), "r" (rb)); \ - __rt; }) -#endif - -#define MULH MULH -static inline av_const int MULH(int a, int b){ - int r; - __asm__ ("mulhw %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); - return r; -} - -#if !ARCH_PPC64 -static inline av_const int64_t MAC64(int64_t d, int a, int b) -{ - union { uint64_t x; unsigned hl[2]; } x = { d }; - int h, l; - __asm__ ("mullw %3, %4, %5 \n\t" - "mulhw %2, %4, %5 \n\t" - "addc %1, %1, %3 \n\t" - "adde %0, %0, %2 \n\t" - : "+r"(x.hl[0]), "+r"(x.hl[1]), "=&r"(h), "=&r"(l) - : "r"(a), "r"(b)); - return x.x; -} -#define MAC64(d, a, b) ((d) = MAC64(d, a, b)) - -static inline av_const int64_t MLS64(int64_t d, int a, int b) -{ - union { uint64_t x; unsigned hl[2]; } x = { d }; - int h, l; - __asm__ ("mullw %3, %4, %5 \n\t" - "mulhw %2, %4, %5 \n\t" - "subfc %1, %3, %1 \n\t" - "subfe %0, %2, %0 \n\t" - : "+r"(x.hl[0]), "+r"(x.hl[1]), "=&r"(h), "=&r"(l) - : "r"(a), "r"(b)); - return x.x; -} -#define MLS64(d, a, b) ((d) = MLS64(d, a, b)) -#endif - -#endif /* AVCODEC_PPC_MATHOPS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c deleted file mode 100644 index 07e63be..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Copyright (c) 2002 Dieter Shirley - * - * dct_unquantize_h263_altivec: - * Copyright (c) 2003 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" - -#include "dsputil_ppc.h" -#include "util_altivec.h" -#include "types_altivec.h" -#include "dsputil_altivec.h" - -// Swaps two variables (used for altivec registers) -#define SWAP(a,b) \ -do { \ - __typeof__(a) swap_temp=a; \ - a=b; \ - b=swap_temp; \ -} while (0) - -// transposes a matrix consisting of four vectors with four elements each -#define TRANSPOSE4(a,b,c,d) \ -do { \ - __typeof__(a) _trans_ach = vec_mergeh(a, c); \ - __typeof__(a) _trans_acl = vec_mergel(a, c); \ - __typeof__(a) _trans_bdh = vec_mergeh(b, d); \ - __typeof__(a) _trans_bdl = vec_mergel(b, d); \ - \ - a = vec_mergeh(_trans_ach, _trans_bdh); \ - b = vec_mergel(_trans_ach, _trans_bdh); \ - c = vec_mergeh(_trans_acl, _trans_bdl); \ - d = vec_mergel(_trans_acl, _trans_bdl); \ -} while (0) - - -// Loads a four-byte value (int or float) from the target address -// into every element in the target vector. Only works if the -// target address is four-byte aligned (which should be always). -#define LOAD4(vec, address) \ -{ \ - __typeof__(vec)* _load_addr = (__typeof__(vec)*)(address); \ - vector unsigned char _perm_vec = vec_lvsl(0,(address)); \ - vec = vec_ld(0, _load_addr); \ - vec = vec_perm(vec, vec, _perm_vec); \ - vec = vec_splat(vec, 0); \ -} - - -#define FOUROF(a) {a,a,a,a} - -static int dct_quantize_altivec(MpegEncContext* s, - DCTELEM* data, int n, - int qscale, int* overflow) -{ - int lastNonZero; - vector float row0, row1, row2, row3, row4, row5, row6, row7; - vector float alt0, alt1, alt2, alt3, alt4, alt5, alt6, alt7; - const vector float zero = (const vector float)FOUROF(0.); - // used after quantize step - int oldBaseValue = 0; - - // Load the data into the row/alt vectors - { - vector signed short data0, data1, data2, data3, data4, data5, data6, data7; - - data0 = vec_ld(0, data); - data1 = vec_ld(16, data); - data2 = vec_ld(32, data); - data3 = vec_ld(48, data); - data4 = vec_ld(64, data); - data5 = vec_ld(80, data); - data6 = vec_ld(96, data); - data7 = vec_ld(112, data); - - // Transpose the data before we start - TRANSPOSE8(data0, data1, data2, data3, data4, data5, data6, data7); - - // load the data into floating point vectors. We load - // the high half of each row into the main row vectors - // and the low half into the alt vectors. - row0 = vec_ctf(vec_unpackh(data0), 0); - alt0 = vec_ctf(vec_unpackl(data0), 0); - row1 = vec_ctf(vec_unpackh(data1), 0); - alt1 = vec_ctf(vec_unpackl(data1), 0); - row2 = vec_ctf(vec_unpackh(data2), 0); - alt2 = vec_ctf(vec_unpackl(data2), 0); - row3 = vec_ctf(vec_unpackh(data3), 0); - alt3 = vec_ctf(vec_unpackl(data3), 0); - row4 = vec_ctf(vec_unpackh(data4), 0); - alt4 = vec_ctf(vec_unpackl(data4), 0); - row5 = vec_ctf(vec_unpackh(data5), 0); - alt5 = vec_ctf(vec_unpackl(data5), 0); - row6 = vec_ctf(vec_unpackh(data6), 0); - alt6 = vec_ctf(vec_unpackl(data6), 0); - row7 = vec_ctf(vec_unpackh(data7), 0); - alt7 = vec_ctf(vec_unpackl(data7), 0); - } - - // The following block could exist as a separate an altivec dct - // function. However, if we put it inline, the DCT data can remain - // in the vector local variables, as floats, which we'll use during the - // quantize step... - { - const vector float vec_0_298631336 = (vector float)FOUROF(0.298631336f); - const vector float vec_0_390180644 = (vector float)FOUROF(-0.390180644f); - const vector float vec_0_541196100 = (vector float)FOUROF(0.541196100f); - const vector float vec_0_765366865 = (vector float)FOUROF(0.765366865f); - const vector float vec_0_899976223 = (vector float)FOUROF(-0.899976223f); - const vector float vec_1_175875602 = (vector float)FOUROF(1.175875602f); - const vector float vec_1_501321110 = (vector float)FOUROF(1.501321110f); - const vector float vec_1_847759065 = (vector float)FOUROF(-1.847759065f); - const vector float vec_1_961570560 = (vector float)FOUROF(-1.961570560f); - const vector float vec_2_053119869 = (vector float)FOUROF(2.053119869f); - const vector float vec_2_562915447 = (vector float)FOUROF(-2.562915447f); - const vector float vec_3_072711026 = (vector float)FOUROF(3.072711026f); - - - int whichPass, whichHalf; - - for(whichPass = 1; whichPass<=2; whichPass++) { - for(whichHalf = 1; whichHalf<=2; whichHalf++) { - vector float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - vector float tmp10, tmp11, tmp12, tmp13; - vector float z1, z2, z3, z4, z5; - - tmp0 = vec_add(row0, row7); // tmp0 = dataptr[0] + dataptr[7]; - tmp7 = vec_sub(row0, row7); // tmp7 = dataptr[0] - dataptr[7]; - tmp3 = vec_add(row3, row4); // tmp3 = dataptr[3] + dataptr[4]; - tmp4 = vec_sub(row3, row4); // tmp4 = dataptr[3] - dataptr[4]; - tmp1 = vec_add(row1, row6); // tmp1 = dataptr[1] + dataptr[6]; - tmp6 = vec_sub(row1, row6); // tmp6 = dataptr[1] - dataptr[6]; - tmp2 = vec_add(row2, row5); // tmp2 = dataptr[2] + dataptr[5]; - tmp5 = vec_sub(row2, row5); // tmp5 = dataptr[2] - dataptr[5]; - - tmp10 = vec_add(tmp0, tmp3); // tmp10 = tmp0 + tmp3; - tmp13 = vec_sub(tmp0, tmp3); // tmp13 = tmp0 - tmp3; - tmp11 = vec_add(tmp1, tmp2); // tmp11 = tmp1 + tmp2; - tmp12 = vec_sub(tmp1, tmp2); // tmp12 = tmp1 - tmp2; - - - // dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); - row0 = vec_add(tmp10, tmp11); - - // dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); - row4 = vec_sub(tmp10, tmp11); - - - // z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); - z1 = vec_madd(vec_add(tmp12, tmp13), vec_0_541196100, (vector float)zero); - - // dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - // CONST_BITS-PASS1_BITS); - row2 = vec_madd(tmp13, vec_0_765366865, z1); - - // dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - // CONST_BITS-PASS1_BITS); - row6 = vec_madd(tmp12, vec_1_847759065, z1); - - z1 = vec_add(tmp4, tmp7); // z1 = tmp4 + tmp7; - z2 = vec_add(tmp5, tmp6); // z2 = tmp5 + tmp6; - z3 = vec_add(tmp4, tmp6); // z3 = tmp4 + tmp6; - z4 = vec_add(tmp5, tmp7); // z4 = tmp5 + tmp7; - - // z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ - z5 = vec_madd(vec_add(z3, z4), vec_1_175875602, (vector float)zero); - - // z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ - z3 = vec_madd(z3, vec_1_961570560, z5); - - // z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ - z4 = vec_madd(z4, vec_0_390180644, z5); - - // The following adds are rolled into the multiplies above - // z3 = vec_add(z3, z5); // z3 += z5; - // z4 = vec_add(z4, z5); // z4 += z5; - - // z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ - // Wow! It's actually more efficient to roll this multiply - // into the adds below, even thought the multiply gets done twice! - // z2 = vec_madd(z2, vec_2_562915447, (vector float)zero); - - // z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ - // Same with this one... - // z1 = vec_madd(z1, vec_0_899976223, (vector float)zero); - - // tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ - // dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); - row7 = vec_madd(tmp4, vec_0_298631336, vec_madd(z1, vec_0_899976223, z3)); - - // tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ - // dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); - row5 = vec_madd(tmp5, vec_2_053119869, vec_madd(z2, vec_2_562915447, z4)); - - // tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ - // dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); - row3 = vec_madd(tmp6, vec_3_072711026, vec_madd(z2, vec_2_562915447, z3)); - - // tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ - // dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); - row1 = vec_madd(z1, vec_0_899976223, vec_madd(tmp7, vec_1_501321110, z4)); - - // Swap the row values with the alts. If this is the first half, - // this sets up the low values to be acted on in the second half. - // If this is the second half, it puts the high values back in - // the row values where they are expected to be when we're done. - SWAP(row0, alt0); - SWAP(row1, alt1); - SWAP(row2, alt2); - SWAP(row3, alt3); - SWAP(row4, alt4); - SWAP(row5, alt5); - SWAP(row6, alt6); - SWAP(row7, alt7); - } - - if (whichPass == 1) { - // transpose the data for the second pass - - // First, block transpose the upper right with lower left. - SWAP(row4, alt0); - SWAP(row5, alt1); - SWAP(row6, alt2); - SWAP(row7, alt3); - - // Now, transpose each block of four - TRANSPOSE4(row0, row1, row2, row3); - TRANSPOSE4(row4, row5, row6, row7); - TRANSPOSE4(alt0, alt1, alt2, alt3); - TRANSPOSE4(alt4, alt5, alt6, alt7); - } - } - } - - // perform the quantize step, using the floating point data - // still in the row/alt registers - { - const int* biasAddr; - const vector signed int* qmat; - vector float bias, negBias; - - if (s->mb_intra) { - vector signed int baseVector; - - // We must cache element 0 in the intra case - // (it needs special handling). - baseVector = vec_cts(vec_splat(row0, 0), 0); - vec_ste(baseVector, 0, &oldBaseValue); - - qmat = (vector signed int*)s->q_intra_matrix[qscale]; - biasAddr = &(s->intra_quant_bias); - } else { - qmat = (vector signed int*)s->q_inter_matrix[qscale]; - biasAddr = &(s->inter_quant_bias); - } - - // Load the bias vector (We add 0.5 to the bias so that we're - // rounding when we convert to int, instead of flooring.) - { - vector signed int biasInt; - const vector float negOneFloat = (vector float)FOUROF(-1.0f); - LOAD4(biasInt, biasAddr); - bias = vec_ctf(biasInt, QUANT_BIAS_SHIFT); - negBias = vec_madd(bias, negOneFloat, zero); - } - - { - vector float q0, q1, q2, q3, q4, q5, q6, q7; - - q0 = vec_ctf(qmat[0], QMAT_SHIFT); - q1 = vec_ctf(qmat[2], QMAT_SHIFT); - q2 = vec_ctf(qmat[4], QMAT_SHIFT); - q3 = vec_ctf(qmat[6], QMAT_SHIFT); - q4 = vec_ctf(qmat[8], QMAT_SHIFT); - q5 = vec_ctf(qmat[10], QMAT_SHIFT); - q6 = vec_ctf(qmat[12], QMAT_SHIFT); - q7 = vec_ctf(qmat[14], QMAT_SHIFT); - - row0 = vec_sel(vec_madd(row0, q0, negBias), vec_madd(row0, q0, bias), - vec_cmpgt(row0, zero)); - row1 = vec_sel(vec_madd(row1, q1, negBias), vec_madd(row1, q1, bias), - vec_cmpgt(row1, zero)); - row2 = vec_sel(vec_madd(row2, q2, negBias), vec_madd(row2, q2, bias), - vec_cmpgt(row2, zero)); - row3 = vec_sel(vec_madd(row3, q3, negBias), vec_madd(row3, q3, bias), - vec_cmpgt(row3, zero)); - row4 = vec_sel(vec_madd(row4, q4, negBias), vec_madd(row4, q4, bias), - vec_cmpgt(row4, zero)); - row5 = vec_sel(vec_madd(row5, q5, negBias), vec_madd(row5, q5, bias), - vec_cmpgt(row5, zero)); - row6 = vec_sel(vec_madd(row6, q6, negBias), vec_madd(row6, q6, bias), - vec_cmpgt(row6, zero)); - row7 = vec_sel(vec_madd(row7, q7, negBias), vec_madd(row7, q7, bias), - vec_cmpgt(row7, zero)); - - q0 = vec_ctf(qmat[1], QMAT_SHIFT); - q1 = vec_ctf(qmat[3], QMAT_SHIFT); - q2 = vec_ctf(qmat[5], QMAT_SHIFT); - q3 = vec_ctf(qmat[7], QMAT_SHIFT); - q4 = vec_ctf(qmat[9], QMAT_SHIFT); - q5 = vec_ctf(qmat[11], QMAT_SHIFT); - q6 = vec_ctf(qmat[13], QMAT_SHIFT); - q7 = vec_ctf(qmat[15], QMAT_SHIFT); - - alt0 = vec_sel(vec_madd(alt0, q0, negBias), vec_madd(alt0, q0, bias), - vec_cmpgt(alt0, zero)); - alt1 = vec_sel(vec_madd(alt1, q1, negBias), vec_madd(alt1, q1, bias), - vec_cmpgt(alt1, zero)); - alt2 = vec_sel(vec_madd(alt2, q2, negBias), vec_madd(alt2, q2, bias), - vec_cmpgt(alt2, zero)); - alt3 = vec_sel(vec_madd(alt3, q3, negBias), vec_madd(alt3, q3, bias), - vec_cmpgt(alt3, zero)); - alt4 = vec_sel(vec_madd(alt4, q4, negBias), vec_madd(alt4, q4, bias), - vec_cmpgt(alt4, zero)); - alt5 = vec_sel(vec_madd(alt5, q5, negBias), vec_madd(alt5, q5, bias), - vec_cmpgt(alt5, zero)); - alt6 = vec_sel(vec_madd(alt6, q6, negBias), vec_madd(alt6, q6, bias), - vec_cmpgt(alt6, zero)); - alt7 = vec_sel(vec_madd(alt7, q7, negBias), vec_madd(alt7, q7, bias), - vec_cmpgt(alt7, zero)); - } - - - } - - // Store the data back into the original block - { - vector signed short data0, data1, data2, data3, data4, data5, data6, data7; - - data0 = vec_pack(vec_cts(row0, 0), vec_cts(alt0, 0)); - data1 = vec_pack(vec_cts(row1, 0), vec_cts(alt1, 0)); - data2 = vec_pack(vec_cts(row2, 0), vec_cts(alt2, 0)); - data3 = vec_pack(vec_cts(row3, 0), vec_cts(alt3, 0)); - data4 = vec_pack(vec_cts(row4, 0), vec_cts(alt4, 0)); - data5 = vec_pack(vec_cts(row5, 0), vec_cts(alt5, 0)); - data6 = vec_pack(vec_cts(row6, 0), vec_cts(alt6, 0)); - data7 = vec_pack(vec_cts(row7, 0), vec_cts(alt7, 0)); - - { - // Clamp for overflow - vector signed int max_q_int, min_q_int; - vector signed short max_q, min_q; - - LOAD4(max_q_int, &(s->max_qcoeff)); - LOAD4(min_q_int, &(s->min_qcoeff)); - - max_q = vec_pack(max_q_int, max_q_int); - min_q = vec_pack(min_q_int, min_q_int); - - data0 = vec_max(vec_min(data0, max_q), min_q); - data1 = vec_max(vec_min(data1, max_q), min_q); - data2 = vec_max(vec_min(data2, max_q), min_q); - data4 = vec_max(vec_min(data4, max_q), min_q); - data5 = vec_max(vec_min(data5, max_q), min_q); - data6 = vec_max(vec_min(data6, max_q), min_q); - data7 = vec_max(vec_min(data7, max_q), min_q); - } - - { - vector bool char zero_01, zero_23, zero_45, zero_67; - vector signed char scanIndexes_01, scanIndexes_23, scanIndexes_45, scanIndexes_67; - vector signed char negOne = vec_splat_s8(-1); - vector signed char* scanPtr = - (vector signed char*)(s->intra_scantable.inverse); - signed char lastNonZeroChar; - - // Determine the largest non-zero index. - zero_01 = vec_pack(vec_cmpeq(data0, (vector signed short)zero), - vec_cmpeq(data1, (vector signed short)zero)); - zero_23 = vec_pack(vec_cmpeq(data2, (vector signed short)zero), - vec_cmpeq(data3, (vector signed short)zero)); - zero_45 = vec_pack(vec_cmpeq(data4, (vector signed short)zero), - vec_cmpeq(data5, (vector signed short)zero)); - zero_67 = vec_pack(vec_cmpeq(data6, (vector signed short)zero), - vec_cmpeq(data7, (vector signed short)zero)); - - // 64 biggest values - scanIndexes_01 = vec_sel(scanPtr[0], negOne, zero_01); - scanIndexes_23 = vec_sel(scanPtr[1], negOne, zero_23); - scanIndexes_45 = vec_sel(scanPtr[2], negOne, zero_45); - scanIndexes_67 = vec_sel(scanPtr[3], negOne, zero_67); - - // 32 largest values - scanIndexes_01 = vec_max(scanIndexes_01, scanIndexes_23); - scanIndexes_45 = vec_max(scanIndexes_45, scanIndexes_67); - - // 16 largest values - scanIndexes_01 = vec_max(scanIndexes_01, scanIndexes_45); - - // 8 largest values - scanIndexes_01 = vec_max(vec_mergeh(scanIndexes_01, negOne), - vec_mergel(scanIndexes_01, negOne)); - - // 4 largest values - scanIndexes_01 = vec_max(vec_mergeh(scanIndexes_01, negOne), - vec_mergel(scanIndexes_01, negOne)); - - // 2 largest values - scanIndexes_01 = vec_max(vec_mergeh(scanIndexes_01, negOne), - vec_mergel(scanIndexes_01, negOne)); - - // largest value - scanIndexes_01 = vec_max(vec_mergeh(scanIndexes_01, negOne), - vec_mergel(scanIndexes_01, negOne)); - - scanIndexes_01 = vec_splat(scanIndexes_01, 0); - - - vec_ste(scanIndexes_01, 0, &lastNonZeroChar); - - lastNonZero = lastNonZeroChar; - - // While the data is still in vectors we check for the transpose IDCT permute - // and handle it using the vector unit if we can. This is the permute used - // by the altivec idct, so it is common when using the altivec dct. - - if ((lastNonZero > 0) && (s->dsp.idct_permutation_type == FF_TRANSPOSE_IDCT_PERM)) { - TRANSPOSE8(data0, data1, data2, data3, data4, data5, data6, data7); - } - - vec_st(data0, 0, data); - vec_st(data1, 16, data); - vec_st(data2, 32, data); - vec_st(data3, 48, data); - vec_st(data4, 64, data); - vec_st(data5, 80, data); - vec_st(data6, 96, data); - vec_st(data7, 112, data); - } - } - - // special handling of block[0] - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - oldBaseValue /= s->y_dc_scale; - else - oldBaseValue /= s->c_dc_scale; - } - - // Divide by 8, rounding the result - data[0] = (oldBaseValue + 4) >> 3; - } - - // We handled the transpose permutation above and we don't - // need to permute the "no" permutation case. - if ((lastNonZero > 0) && - (s->dsp.idct_permutation_type != FF_TRANSPOSE_IDCT_PERM) && - (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM)) { - ff_block_permute(data, s->dsp.idct_permutation, - s->intra_scantable.scantable, lastNonZero); - } - - return lastNonZero; -} - -/* AltiVec version of dct_unquantize_h263 - this code assumes `block' is 16 bytes-aligned */ -static void dct_unquantize_h263_altivec(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ -POWERPC_PERF_DECLARE(altivec_dct_unquantize_h263_num, 1); - int i, level, qmul, qadd; - int nCoeffs; - - assert(s->block_last_index[n]>=0); - -POWERPC_PERF_START_COUNT(altivec_dct_unquantize_h263_num, 1); - - qadd = (qscale - 1) | 1; - qmul = qscale << 1; - - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - block[0] = block[0] * s->y_dc_scale; - else - block[0] = block[0] * s->c_dc_scale; - }else - qadd = 0; - i = 1; - nCoeffs= 63; //does not always use zigzag table - } else { - i = 0; - nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; - } - - { - register const vector signed short vczero = (const vector signed short)vec_splat_s16(0); - DECLARE_ALIGNED(16, short, qmul8) = qmul; - DECLARE_ALIGNED(16, short, qadd8) = qadd; - register vector signed short blockv, qmulv, qaddv, nqaddv, temp1; - register vector bool short blockv_null, blockv_neg; - register short backup_0 = block[0]; - register int j = 0; - - qmulv = vec_splat((vec_s16)vec_lde(0, &qmul8), 0); - qaddv = vec_splat((vec_s16)vec_lde(0, &qadd8), 0); - nqaddv = vec_sub(vczero, qaddv); - -#if 0 // block *is* 16 bytes-aligned, it seems. - // first make sure block[j] is 16 bytes-aligned - for(j = 0; (j <= nCoeffs) && ((((unsigned long)block) + (j << 1)) & 0x0000000F) ; j++) { - level = block[j]; - if (level) { - if (level < 0) { - level = level * qmul - qadd; - } else { - level = level * qmul + qadd; - } - block[j] = level; - } - } -#endif - - // vectorize all the 16 bytes-aligned blocks - // of 8 elements - for(; (j + 7) <= nCoeffs ; j+=8) { - blockv = vec_ld(j << 1, block); - blockv_neg = vec_cmplt(blockv, vczero); - blockv_null = vec_cmpeq(blockv, vczero); - // choose between +qadd or -qadd as the third operand - temp1 = vec_sel(qaddv, nqaddv, blockv_neg); - // multiply & add (block{i,i+7} * qmul [+-] qadd) - temp1 = vec_mladd(blockv, qmulv, temp1); - // put 0 where block[{i,i+7} used to have 0 - blockv = vec_sel(temp1, blockv, blockv_null); - vec_st(blockv, j << 1, block); - } - - // if nCoeffs isn't a multiple of 8, finish the job - // using good old scalar units. - // (we could do it using a truncated vector, - // but I'm not sure it's worth the hassle) - for(; j <= nCoeffs ; j++) { - level = block[j]; - if (level) { - if (level < 0) { - level = level * qmul - qadd; - } else { - level = level * qmul + qadd; - } - block[j] = level; - } - } - - if (i == 1) { - // cheat. this avoid special-casing the first iteration - block[0] = backup_0; - } - } -POWERPC_PERF_STOP_COUNT(altivec_dct_unquantize_h263_num, nCoeffs == 63); -} - - -void MPV_common_init_altivec(MpegEncContext *s) -{ - if ((mm_flags & FF_MM_ALTIVEC) == 0) return; - - if (s->avctx->lowres==0) { - if ((s->avctx->idct_algo == FF_IDCT_AUTO) || - (s->avctx->idct_algo == FF_IDCT_ALTIVEC)) { - s->dsp.idct_put = idct_put_altivec; - s->dsp.idct_add = idct_add_altivec; - s->dsp.idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; - } - } - - // Test to make sure that the dct required alignments are met. - if ((((long)(s->q_intra_matrix) & 0x0f) != 0) || - (((long)(s->q_inter_matrix) & 0x0f) != 0)) { - av_log(s->avctx, AV_LOG_INFO, "Internal Error: q-matrix blocks must be 16-byte aligned " - "to use AltiVec DCT. Reverting to non-AltiVec version.\n"); - return; - } - - if (((long)(s->intra_scantable.inverse) & 0x0f) != 0) { - av_log(s->avctx, AV_LOG_INFO, "Internal Error: scan table blocks must be 16-byte aligned " - "to use AltiVec DCT. Reverting to non-AltiVec version.\n"); - return; - } - - - if ((s->avctx->dct_algo == FF_DCT_AUTO) || - (s->avctx->dct_algo == FF_DCT_ALTIVEC)) { -#if 0 /* seems to cause trouble under some circumstances */ - s->dct_quantize = dct_quantize_altivec; -#endif - s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec; - s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/types_altivec.h b/tizen/distrib/ffmpeg/libavcodec/ppc/types_altivec.h deleted file mode 100644 index 2870e83..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/types_altivec.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2006 Guillaume Poirier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PPC_TYPES_ALTIVEC_H -#define AVCODEC_PPC_TYPES_ALTIVEC_H - -/*********************************************************************** - * Vector types - **********************************************************************/ -#define vec_u8 vector unsigned char -#define vec_s8 vector signed char -#define vec_u16 vector unsigned short -#define vec_s16 vector signed short -#define vec_u32 vector unsigned int -#define vec_s32 vector signed int - -/*********************************************************************** - * Null vector - **********************************************************************/ -#define LOAD_ZERO const vec_u8 zerov = vec_splat_u8( 0 ) - -#define zero_u8v (vec_u8) zerov -#define zero_s8v (vec_s8) zerov -#define zero_u16v (vec_u16) zerov -#define zero_s16v (vec_s16) zerov -#define zero_u32v (vec_u32) zerov -#define zero_s32v (vec_s32) zerov - -#endif /* AVCODEC_PPC_TYPES_ALTIVEC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/util_altivec.h b/tizen/distrib/ffmpeg/libavcodec/ppc/util_altivec.h deleted file mode 100644 index 62f228a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/util_altivec.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Contains misc utility macros and inline functions - */ - -#ifndef AVCODEC_PPC_UTIL_ALTIVEC_H -#define AVCODEC_PPC_UTIL_ALTIVEC_H - -#include - -#include "config.h" - -#if HAVE_ALTIVEC_H -#include -#endif - -// used to build registers permutation vectors (vcprm) -// the 's' are for words in the _s_econd vector -#define WORD_0 0x00,0x01,0x02,0x03 -#define WORD_1 0x04,0x05,0x06,0x07 -#define WORD_2 0x08,0x09,0x0a,0x0b -#define WORD_3 0x0c,0x0d,0x0e,0x0f -#define WORD_s0 0x10,0x11,0x12,0x13 -#define WORD_s1 0x14,0x15,0x16,0x17 -#define WORD_s2 0x18,0x19,0x1a,0x1b -#define WORD_s3 0x1c,0x1d,0x1e,0x1f - -#define vcprm(a,b,c,d) (const vector unsigned char){WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d} -#define vcii(a,b,c,d) (const vector float){FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d} - -// vcprmle is used to keep the same index as in the SSE version. -// it's the same as vcprm, with the index inversed -// ('le' is Little Endian) -#define vcprmle(a,b,c,d) vcprm(d,c,b,a) - -// used to build inverse/identity vectors (vcii) -// n is _n_egative, p is _p_ositive -#define FLOAT_n -1. -#define FLOAT_p 1. - - -// Transpose 8x8 matrix of 16-bit elements (in-place) -#define TRANSPOSE8(a,b,c,d,e,f,g,h) \ -do { \ - vector signed short A1, B1, C1, D1, E1, F1, G1, H1; \ - vector signed short A2, B2, C2, D2, E2, F2, G2, H2; \ - \ - A1 = vec_mergeh (a, e); \ - B1 = vec_mergel (a, e); \ - C1 = vec_mergeh (b, f); \ - D1 = vec_mergel (b, f); \ - E1 = vec_mergeh (c, g); \ - F1 = vec_mergel (c, g); \ - G1 = vec_mergeh (d, h); \ - H1 = vec_mergel (d, h); \ - \ - A2 = vec_mergeh (A1, E1); \ - B2 = vec_mergel (A1, E1); \ - C2 = vec_mergeh (B1, F1); \ - D2 = vec_mergel (B1, F1); \ - E2 = vec_mergeh (C1, G1); \ - F2 = vec_mergel (C1, G1); \ - G2 = vec_mergeh (D1, H1); \ - H2 = vec_mergel (D1, H1); \ - \ - a = vec_mergeh (A2, E2); \ - b = vec_mergel (A2, E2); \ - c = vec_mergeh (B2, F2); \ - d = vec_mergel (B2, F2); \ - e = vec_mergeh (C2, G2); \ - f = vec_mergel (C2, G2); \ - g = vec_mergeh (D2, H2); \ - h = vec_mergel (D2, H2); \ -} while (0) - - -/** \brief loads unaligned vector \a *src with offset \a offset - and returns it */ -static inline vector unsigned char unaligned_load(int offset, uint8_t *src) -{ - register vector unsigned char first = vec_ld(offset, src); - register vector unsigned char second = vec_ld(offset+15, src); - register vector unsigned char mask = vec_lvsl(offset, src); - return vec_perm(first, second, mask); -} - -#endif /* AVCODEC_PPC_UTIL_ALTIVEC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c deleted file mode 100644 index a2f55f2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * VC-1 and WMV3 decoder - DSP functions AltiVec-optimized - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" - -#include "util_altivec.h" -#include "dsputil_altivec.h" - -// main steps of 8x8 transform -#define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \ -do { \ - t0 = vec_sl(vec_add(s0, s4), vec_2); \ - t0 = vec_add(vec_sl(t0, vec_1), t0); \ - t0 = vec_add(t0, vec_rnd); \ - t1 = vec_sl(vec_sub(s0, s4), vec_2); \ - t1 = vec_add(vec_sl(t1, vec_1), t1); \ - t1 = vec_add(t1, vec_rnd); \ - t2 = vec_add(vec_sl(s6, vec_2), vec_sl(s6, vec_1)); \ - t2 = vec_add(t2, vec_sl(s2, vec_4)); \ - t3 = vec_add(vec_sl(s2, vec_2), vec_sl(s2, vec_1)); \ - t3 = vec_sub(t3, vec_sl(s6, vec_4)); \ - t4 = vec_add(t0, t2); \ - t5 = vec_add(t1, t3); \ - t6 = vec_sub(t1, t3); \ - t7 = vec_sub(t0, t2); \ -\ - t0 = vec_sl(vec_add(s1, s3), vec_4); \ - t0 = vec_add(t0, vec_sl(s5, vec_3)); \ - t0 = vec_add(t0, vec_sl(s7, vec_2)); \ - t0 = vec_add(t0, vec_sub(s5, s3)); \ -\ - t1 = vec_sl(vec_sub(s1, s5), vec_4); \ - t1 = vec_sub(t1, vec_sl(s7, vec_3)); \ - t1 = vec_sub(t1, vec_sl(s3, vec_2)); \ - t1 = vec_sub(t1, vec_add(s1, s7)); \ -\ - t2 = vec_sl(vec_sub(s7, s3), vec_4); \ - t2 = vec_add(t2, vec_sl(s1, vec_3)); \ - t2 = vec_add(t2, vec_sl(s5, vec_2)); \ - t2 = vec_add(t2, vec_sub(s1, s7)); \ -\ - t3 = vec_sl(vec_sub(s5, s7), vec_4); \ - t3 = vec_sub(t3, vec_sl(s3, vec_3)); \ - t3 = vec_add(t3, vec_sl(s1, vec_2)); \ - t3 = vec_sub(t3, vec_add(s3, s5)); \ -\ - s0 = vec_add(t4, t0); \ - s1 = vec_add(t5, t1); \ - s2 = vec_add(t6, t2); \ - s3 = vec_add(t7, t3); \ - s4 = vec_sub(t7, t3); \ - s5 = vec_sub(t6, t2); \ - s6 = vec_sub(t5, t1); \ - s7 = vec_sub(t4, t0); \ -}while(0) - -#define SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7) \ -do { \ - s0 = vec_sra(s0, vec_3); \ - s1 = vec_sra(s1, vec_3); \ - s2 = vec_sra(s2, vec_3); \ - s3 = vec_sra(s3, vec_3); \ - s4 = vec_sra(s4, vec_3); \ - s5 = vec_sra(s5, vec_3); \ - s6 = vec_sra(s6, vec_3); \ - s7 = vec_sra(s7, vec_3); \ -}while(0) - -#define SHIFT_VERT8(s0, s1, s2, s3, s4, s5, s6, s7) \ -do { \ - s0 = vec_sra(s0, vec_7); \ - s1 = vec_sra(s1, vec_7); \ - s2 = vec_sra(s2, vec_7); \ - s3 = vec_sra(s3, vec_7); \ - s4 = vec_sra(vec_add(s4, vec_1s), vec_7); \ - s5 = vec_sra(vec_add(s5, vec_1s), vec_7); \ - s6 = vec_sra(vec_add(s6, vec_1s), vec_7); \ - s7 = vec_sra(vec_add(s7, vec_1s), vec_7); \ -}while(0) - -/* main steps of 4x4 transform */ -#define STEP4(s0, s1, s2, s3, vec_rnd) \ -do { \ - t1 = vec_add(vec_sl(s0, vec_4), s0); \ - t1 = vec_add(t1, vec_rnd); \ - t2 = vec_add(vec_sl(s2, vec_4), s2); \ - t0 = vec_add(t1, t2); \ - t1 = vec_sub(t1, t2); \ - t3 = vec_sl(vec_sub(s3, s1), vec_1); \ - t3 = vec_add(t3, vec_sl(t3, vec_2)); \ - t2 = vec_add(t3, vec_sl(s1, vec_5)); \ - t3 = vec_add(t3, vec_sl(s3, vec_3)); \ - t3 = vec_add(t3, vec_sl(s3, vec_2)); \ - s0 = vec_add(t0, t2); \ - s1 = vec_sub(t1, t3); \ - s2 = vec_add(t1, t3); \ - s3 = vec_sub(t0, t2); \ -}while (0) - -#define SHIFT_HOR4(s0, s1, s2, s3) \ - s0 = vec_sra(s0, vec_3); \ - s1 = vec_sra(s1, vec_3); \ - s2 = vec_sra(s2, vec_3); \ - s3 = vec_sra(s3, vec_3); - -#define SHIFT_VERT4(s0, s1, s2, s3) \ - s0 = vec_sra(s0, vec_7); \ - s1 = vec_sra(s1, vec_7); \ - s2 = vec_sra(s2, vec_7); \ - s3 = vec_sra(s3, vec_7); - -/** Do inverse transform on 8x8 block -*/ -static void vc1_inv_trans_8x8_altivec(DCTELEM block[64]) -{ - vector signed short src0, src1, src2, src3, src4, src5, src6, src7; - vector signed int s0, s1, s2, s3, s4, s5, s6, s7; - vector signed int s8, s9, sA, sB, sC, sD, sE, sF; - vector signed int t0, t1, t2, t3, t4, t5, t6, t7; - const vector signed int vec_64 = vec_sl(vec_splat_s32(4), vec_splat_u32(4)); - const vector unsigned int vec_7 = vec_splat_u32(7); - const vector unsigned int vec_4 = vec_splat_u32(4); - const vector signed int vec_4s = vec_splat_s32(4); - const vector unsigned int vec_3 = vec_splat_u32(3); - const vector unsigned int vec_2 = vec_splat_u32(2); - const vector signed int vec_1s = vec_splat_s32(1); - const vector unsigned int vec_1 = vec_splat_u32(1); - - - src0 = vec_ld( 0, block); - src1 = vec_ld( 16, block); - src2 = vec_ld( 32, block); - src3 = vec_ld( 48, block); - src4 = vec_ld( 64, block); - src5 = vec_ld( 80, block); - src6 = vec_ld( 96, block); - src7 = vec_ld(112, block); - - TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); - s0 = vec_unpackl(src0); - s1 = vec_unpackl(src1); - s2 = vec_unpackl(src2); - s3 = vec_unpackl(src3); - s4 = vec_unpackl(src4); - s5 = vec_unpackl(src5); - s6 = vec_unpackl(src6); - s7 = vec_unpackl(src7); - s8 = vec_unpackh(src0); - s9 = vec_unpackh(src1); - sA = vec_unpackh(src2); - sB = vec_unpackh(src3); - sC = vec_unpackh(src4); - sD = vec_unpackh(src5); - sE = vec_unpackh(src6); - sF = vec_unpackh(src7); - STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_4s); - SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7); - STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_4s); - SHIFT_HOR8(s8, s9, sA, sB, sC, sD, sE, sF); - src0 = vec_pack(s8, s0); - src1 = vec_pack(s9, s1); - src2 = vec_pack(sA, s2); - src3 = vec_pack(sB, s3); - src4 = vec_pack(sC, s4); - src5 = vec_pack(sD, s5); - src6 = vec_pack(sE, s6); - src7 = vec_pack(sF, s7); - TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); - - s0 = vec_unpackl(src0); - s1 = vec_unpackl(src1); - s2 = vec_unpackl(src2); - s3 = vec_unpackl(src3); - s4 = vec_unpackl(src4); - s5 = vec_unpackl(src5); - s6 = vec_unpackl(src6); - s7 = vec_unpackl(src7); - s8 = vec_unpackh(src0); - s9 = vec_unpackh(src1); - sA = vec_unpackh(src2); - sB = vec_unpackh(src3); - sC = vec_unpackh(src4); - sD = vec_unpackh(src5); - sE = vec_unpackh(src6); - sF = vec_unpackh(src7); - STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_64); - SHIFT_VERT8(s0, s1, s2, s3, s4, s5, s6, s7); - STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_64); - SHIFT_VERT8(s8, s9, sA, sB, sC, sD, sE, sF); - src0 = vec_pack(s8, s0); - src1 = vec_pack(s9, s1); - src2 = vec_pack(sA, s2); - src3 = vec_pack(sB, s3); - src4 = vec_pack(sC, s4); - src5 = vec_pack(sD, s5); - src6 = vec_pack(sE, s6); - src7 = vec_pack(sF, s7); - - vec_st(src0, 0, block); - vec_st(src1, 16, block); - vec_st(src2, 32, block); - vec_st(src3, 48, block); - vec_st(src4, 64, block); - vec_st(src5, 80, block); - vec_st(src6, 96, block); - vec_st(src7,112, block); -} - -/** Do inverse transform on 8x4 part of block -*/ -static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block) -{ - vector signed short src0, src1, src2, src3, src4, src5, src6, src7; - vector signed int s0, s1, s2, s3, s4, s5, s6, s7; - vector signed int s8, s9, sA, sB, sC, sD, sE, sF; - vector signed int t0, t1, t2, t3, t4, t5, t6, t7; - const vector signed int vec_64 = vec_sl(vec_splat_s32(4), vec_splat_u32(4)); - const vector unsigned int vec_7 = vec_splat_u32(7); - const vector unsigned int vec_5 = vec_splat_u32(5); - const vector unsigned int vec_4 = vec_splat_u32(4); - const vector signed int vec_4s = vec_splat_s32(4); - const vector unsigned int vec_3 = vec_splat_u32(3); - const vector unsigned int vec_2 = vec_splat_u32(2); - const vector unsigned int vec_1 = vec_splat_u32(1); - vector unsigned char tmp; - vector signed short tmp2, tmp3; - vector unsigned char perm0, perm1, p0, p1, p; - - src0 = vec_ld( 0, block); - src1 = vec_ld( 16, block); - src2 = vec_ld( 32, block); - src3 = vec_ld( 48, block); - src4 = vec_ld( 64, block); - src5 = vec_ld( 80, block); - src6 = vec_ld( 96, block); - src7 = vec_ld(112, block); - - TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); - s0 = vec_unpackl(src0); - s1 = vec_unpackl(src1); - s2 = vec_unpackl(src2); - s3 = vec_unpackl(src3); - s4 = vec_unpackl(src4); - s5 = vec_unpackl(src5); - s6 = vec_unpackl(src6); - s7 = vec_unpackl(src7); - s8 = vec_unpackh(src0); - s9 = vec_unpackh(src1); - sA = vec_unpackh(src2); - sB = vec_unpackh(src3); - sC = vec_unpackh(src4); - sD = vec_unpackh(src5); - sE = vec_unpackh(src6); - sF = vec_unpackh(src7); - STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_4s); - SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7); - STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_4s); - SHIFT_HOR8(s8, s9, sA, sB, sC, sD, sE, sF); - src0 = vec_pack(s8, s0); - src1 = vec_pack(s9, s1); - src2 = vec_pack(sA, s2); - src3 = vec_pack(sB, s3); - src4 = vec_pack(sC, s4); - src5 = vec_pack(sD, s5); - src6 = vec_pack(sE, s6); - src7 = vec_pack(sF, s7); - TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); - - s0 = vec_unpackh(src0); - s1 = vec_unpackh(src1); - s2 = vec_unpackh(src2); - s3 = vec_unpackh(src3); - s8 = vec_unpackl(src0); - s9 = vec_unpackl(src1); - sA = vec_unpackl(src2); - sB = vec_unpackl(src3); - STEP4(s0, s1, s2, s3, vec_64); - SHIFT_VERT4(s0, s1, s2, s3); - STEP4(s8, s9, sA, sB, vec_64); - SHIFT_VERT4(s8, s9, sA, sB); - src0 = vec_pack(s0, s8); - src1 = vec_pack(s1, s9); - src2 = vec_pack(s2, sA); - src3 = vec_pack(s3, sB); - - p0 = vec_lvsl (0, dest); - p1 = vec_lvsl (stride, dest); - p = vec_splat_u8 (-1); - perm0 = vec_mergeh (p, p0); - perm1 = vec_mergeh (p, p1); - -#define ADD(dest,src,perm) \ - /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ - tmp = vec_ld (0, dest); \ - tmp2 = (vector signed short)vec_perm (tmp, vec_splat_u8(0), perm); \ - tmp3 = vec_adds (tmp2, src); \ - tmp = vec_packsu (tmp3, tmp3); \ - vec_ste ((vector unsigned int)tmp, 0, (unsigned int *)dest); \ - vec_ste ((vector unsigned int)tmp, 4, (unsigned int *)dest); - - ADD (dest, src0, perm0) dest += stride; - ADD (dest, src1, perm1) dest += stride; - ADD (dest, src2, perm0) dest += stride; - ADD (dest, src3, perm1) -} - - -void vc1dsp_init_altivec(DSPContext* dsp, AVCodecContext *avctx) { - dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_altivec; - dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_altivec; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c b/tizen/distrib/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c deleted file mode 100644 index b0509d8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ppc/vp3dsp_altivec.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2009 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "util_altivec.h" -#include "types_altivec.h" -#include "dsputil_altivec.h" - -static const vec_s16 constants = - {0, 64277, 60547, 54491, 46341, 36410, 25080, 12785}; -static const vec_u8 interleave_high = - {0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29}; - -#define IDCT_START \ - vec_s16 A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;\ - vec_s16 Ed, Gd, Add, Bdd, Fd, Hd;\ - vec_s16 eight = vec_splat_s16(8);\ - vec_u16 four = vec_splat_u16(4);\ -\ - vec_s16 C1 = vec_splat(constants, 1);\ - vec_s16 C2 = vec_splat(constants, 2);\ - vec_s16 C3 = vec_splat(constants, 3);\ - vec_s16 C4 = vec_splat(constants, 4);\ - vec_s16 C5 = vec_splat(constants, 5);\ - vec_s16 C6 = vec_splat(constants, 6);\ - vec_s16 C7 = vec_splat(constants, 7);\ -\ - vec_s16 b0 = vec_ld(0x00, block);\ - vec_s16 b1 = vec_ld(0x10, block);\ - vec_s16 b2 = vec_ld(0x20, block);\ - vec_s16 b3 = vec_ld(0x30, block);\ - vec_s16 b4 = vec_ld(0x40, block);\ - vec_s16 b5 = vec_ld(0x50, block);\ - vec_s16 b6 = vec_ld(0x60, block);\ - vec_s16 b7 = vec_ld(0x70, block); - -// these functions do (a*C)>>16 -// things are tricky because a is signed, but C unsigned. -// M15 is used if C fits in 15 bit unsigned (C6,C7) -// M16 is used if C requires 16 bits unsigned -static inline vec_s16 M15(vec_s16 a, vec_s16 C) -{ - return (vec_s16)vec_perm(vec_mule(a,C), vec_mulo(a,C), interleave_high); -} -static inline vec_s16 M16(vec_s16 a, vec_s16 C) -{ - return vec_add(a, M15(a, C)); -} - -#define IDCT_1D(ADD, SHIFT)\ - A = vec_add(M16(b1, C1), M15(b7, C7));\ - B = vec_sub(M15(b1, C7), M16(b7, C1));\ - C = vec_add(M16(b3, C3), M16(b5, C5));\ - D = vec_sub(M16(b5, C3), M16(b3, C5));\ -\ - Ad = M16(vec_sub(A, C), C4);\ - Bd = M16(vec_sub(B, D), C4);\ -\ - Cd = vec_add(A, C);\ - Dd = vec_add(B, D);\ -\ - E = ADD(M16(vec_add(b0, b4), C4));\ - F = ADD(M16(vec_sub(b0, b4), C4));\ -\ - G = vec_add(M16(b2, C2), M15(b6, C6));\ - H = vec_sub(M15(b2, C6), M16(b6, C2));\ -\ - Ed = vec_sub(E, G);\ - Gd = vec_add(E, G);\ -\ - Add = vec_add(F, Ad);\ - Bdd = vec_sub(Bd, H);\ -\ - Fd = vec_sub(F, Ad);\ - Hd = vec_add(Bd, H);\ -\ - b0 = SHIFT(vec_add(Gd, Cd));\ - b7 = SHIFT(vec_sub(Gd, Cd));\ -\ - b1 = SHIFT(vec_add(Add, Hd));\ - b2 = SHIFT(vec_sub(Add, Hd));\ -\ - b3 = SHIFT(vec_add(Ed, Dd));\ - b4 = SHIFT(vec_sub(Ed, Dd));\ -\ - b5 = SHIFT(vec_add(Fd, Bdd));\ - b6 = SHIFT(vec_sub(Fd, Bdd)); - -#define NOP(a) a -#define ADD8(a) vec_add(a, eight) -#define SHIFT4(a) vec_sra(a, four) - -void ff_vp3_idct_altivec(DCTELEM block[64]) -{ - IDCT_START - - IDCT_1D(NOP, NOP) - TRANSPOSE8(b0, b1, b2, b3, b4, b5, b6, b7); - IDCT_1D(ADD8, SHIFT4) - - vec_st(b0, 0x00, block); - vec_st(b1, 0x10, block); - vec_st(b2, 0x20, block); - vec_st(b3, 0x30, block); - vec_st(b4, 0x40, block); - vec_st(b5, 0x50, block); - vec_st(b6, 0x60, block); - vec_st(b7, 0x70, block); -} - -void ff_vp3_idct_put_altivec(uint8_t *dst, int stride, DCTELEM block[64]) -{ - vec_u8 t; - IDCT_START - - // pixels are signed; so add 128*16 in addition to the normal 8 - vec_s16 v2048 = vec_sl(vec_splat_s16(1), vec_splat_u16(11)); - eight = vec_add(eight, v2048); - - IDCT_1D(NOP, NOP) - TRANSPOSE8(b0, b1, b2, b3, b4, b5, b6, b7); - IDCT_1D(ADD8, SHIFT4) - -#define PUT(a)\ - t = vec_packsu(a, a);\ - vec_ste((vec_u32)t, 0, (unsigned int *)dst);\ - vec_ste((vec_u32)t, 4, (unsigned int *)dst); - - PUT(b0) dst += stride; - PUT(b1) dst += stride; - PUT(b2) dst += stride; - PUT(b3) dst += stride; - PUT(b4) dst += stride; - PUT(b5) dst += stride; - PUT(b6) dst += stride; - PUT(b7) -} - -void ff_vp3_idct_add_altivec(uint8_t *dst, int stride, DCTELEM block[64]) -{ - LOAD_ZERO; - vec_u8 t, vdst; - vec_s16 vdst_16; - vec_u8 vdst_mask = vec_mergeh(vec_splat_u8(-1), vec_lvsl(0, dst)); - - IDCT_START - - IDCT_1D(NOP, NOP) - TRANSPOSE8(b0, b1, b2, b3, b4, b5, b6, b7); - IDCT_1D(ADD8, SHIFT4) - -#define ADD(a)\ - vdst = vec_ld(0, dst);\ - vdst_16 = (vec_s16)vec_perm(vdst, zero_u8v, vdst_mask);\ - vdst_16 = vec_adds(a, vdst_16);\ - t = vec_packsu(vdst_16, vdst_16);\ - vec_ste((vec_u32)t, 0, (unsigned int *)dst);\ - vec_ste((vec_u32)t, 4, (unsigned int *)dst); - - ADD(b0) dst += stride; - ADD(b1) dst += stride; - ADD(b2) dst += stride; - ADD(b3) dst += stride; - ADD(b4) dst += stride; - ADD(b5) dst += stride; - ADD(b6) dst += stride; - ADD(b7) -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c b/tizen/distrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c deleted file mode 100644 index 15b5b56..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * MMI optimized DSP utils - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * MMI optimization by Leon van Stuivenberg - * clear_blocks_mmi() by BroadQ - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "mmi.h" - -void ff_mmi_idct_put(uint8_t *dest, int line_size, DCTELEM *block); -void ff_mmi_idct_add(uint8_t *dest, int line_size, DCTELEM *block); -void ff_mmi_idct(DCTELEM *block); - -static void clear_blocks_mmi(DCTELEM * blocks) -{ - __asm__ volatile( - ".set noreorder \n" - "addiu $9, %0, 768 \n" - "nop \n" - "1: \n" - "sq $0, 0(%0) \n" - "move $8, %0 \n" - "addi %0, %0, 64 \n" - "sq $0, 16($8) \n" - "slt $10, %0, $9 \n" - "sq $0, 32($8) \n" - "bnez $10, 1b \n" - "sq $0, 48($8) \n" - ".set reorder \n" - : "+r" (blocks) :: "$8", "$9", "memory" ); -} - - -static void get_pixels_mmi(DCTELEM *block, const uint8_t *pixels, int line_size) -{ - __asm__ volatile( - ".set push \n\t" - ".set mips3 \n\t" - "ld $8, 0(%0) \n\t" - "add %0, %0, %2 \n\t" - "ld $9, 0(%0) \n\t" - "add %0, %0, %2 \n\t" - "ld $10, 0(%0) \n\t" - "pextlb $8, $0, $8 \n\t" - "sq $8, 0(%1) \n\t" - "add %0, %0, %2 \n\t" - "ld $8, 0(%0) \n\t" - "pextlb $9, $0, $9 \n\t" - "sq $9, 16(%1) \n\t" - "add %0, %0, %2 \n\t" - "ld $9, 0(%0) \n\t" - "pextlb $10, $0, $10 \n\t" - "sq $10, 32(%1) \n\t" - "add %0, %0, %2 \n\t" - "ld $10, 0(%0) \n\t" - "pextlb $8, $0, $8 \n\t" - "sq $8, 48(%1) \n\t" - "add %0, %0, %2 \n\t" - "ld $8, 0(%0) \n\t" - "pextlb $9, $0, $9 \n\t" - "sq $9, 64(%1) \n\t" - "add %0, %0, %2 \n\t" - "ld $9, 0(%0) \n\t" - "pextlb $10, $0, $10 \n\t" - "sq $10, 80(%1) \n\t" - "pextlb $8, $0, $8 \n\t" - "sq $8, 96(%1) \n\t" - "pextlb $9, $0, $9 \n\t" - "sq $9, 112(%1) \n\t" - ".set pop \n\t" - : "+r" (pixels) : "r" (block), "r" (line_size) : "$8", "$9", "$10", "memory" ); -} - - -static void put_pixels8_mmi(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - __asm__ volatile( - ".set push \n\t" - ".set mips3 \n\t" - "1: \n\t" - "ldr $8, 0(%1) \n\t" - "addiu %2, %2, -1 \n\t" - "ldl $8, 7(%1) \n\t" - "add %1, %1, %3 \n\t" - "sd $8, 0(%0) \n\t" - "add %0, %0, %3 \n\t" - "bgtz %2, 1b \n\t" - ".set pop \n\t" - : "+r" (block), "+r" (pixels), "+r" (h) : "r" (line_size) - : "$8", "memory" ); -} - - -static void put_pixels16_mmi(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - __asm__ volatile ( - ".set push \n\t" - ".set mips3 \n\t" - "1: \n\t" - "ldr $8, 0(%1) \n\t" - "add $11, %1, %3 \n\t" - "ldl $8, 7(%1) \n\t" - "add $10, %0, %3 \n\t" - "ldr $9, 8(%1) \n\t" - "ldl $9, 15(%1) \n\t" - "ldr $12, 0($11) \n\t" - "add %1, $11, %3 \n\t" - "ldl $12, 7($11) \n\t" - "pcpyld $8, $9, $8 \n\t" - "sq $8, 0(%0) \n\t" - "ldr $13, 8($11) \n\t" - "addiu %2, %2, -2 \n\t" - "ldl $13, 15($11) \n\t" - "add %0, $10, %3 \n\t" - "pcpyld $12, $13, $12 \n\t" - "sq $12, 0($10) \n\t" - "bgtz %2, 1b \n\t" - ".set pop \n\t" - : "+r" (block), "+r" (pixels), "+r" (h) : "r" (line_size) - : "$8", "$9", "$10", "$11", "$12", "$13", "memory" ); -} - - -void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx) -{ - const int idct_algo= avctx->idct_algo; - - c->clear_blocks = clear_blocks_mmi; - - c->put_pixels_tab[1][0] = put_pixels8_mmi; - c->put_no_rnd_pixels_tab[1][0] = put_pixels8_mmi; - - c->put_pixels_tab[0][0] = put_pixels16_mmi; - c->put_no_rnd_pixels_tab[0][0] = put_pixels16_mmi; - - c->get_pixels = get_pixels_mmi; - - if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_PS2){ - c->idct_put= ff_mmi_idct_put; - c->idct_add= ff_mmi_idct_add; - c->idct = ff_mmi_idct; - c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; - } -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/ps2/idct_mmi.c b/tizen/distrib/ffmpeg/libavcodec/ps2/idct_mmi.c deleted file mode 100644 index bfe362a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ps2/idct_mmi.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Originally provided by Intel at Application Note AP-922. - * - * Column code adapted from Peter Gubanov. - * Copyright (c) 2000-2001 Peter Gubanov - * http://www.elecard.com/peter/idct.shtml - * rounding trick copyright (c) 2000 Michel Lespinasse - * - * MMI port and (c) 2002 by Leon van Stuivenberg - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "libavcodec/dsputil.h" -#include "mmi.h" - -#define BITS_INV_ACC 5 // 4 or 5 for IEEE -#define SHIFT_INV_ROW (16 - BITS_INV_ACC) -#define SHIFT_INV_COL (1 + BITS_INV_ACC) - -#define TG1 6518 -#define TG2 13573 -#define TG3 21895 -#define CS4 23170 - -#define ROUNDER_0 0 -#define ROUNDER_1 16 - -#define TAB_i_04 (32+0) -#define TAB_i_17 (32+64) -#define TAB_i_26 (32+128) -#define TAB_i_35 (32+192) - -#define TG_1_16 (32+256+0) -#define TG_2_16 (32+256+16) -#define TG_3_16 (32+256+32) -#define COS_4_16 (32+256+48) - -#define CLIPMAX (32+256+64+0) - -static short consttable[] align16 = { -/* rounder 0*/ // assume SHIFT_INV_ROW == 11 - 0x3ff, 1, 0x3ff, 1, 0x3ff, 1, 0x3ff, 1, -/* rounder 1*/ - 0x3ff, 0, 0x3ff, 0, 0x3ff, 0, 0x3ff, 0, -/* row 0/4*/ - 16384, 21407, -16384, -21407, 22725, 19266, -22725, -12873, - 8867, 16384, 8867, 16384, 4520, 12873, -4520, 19266, - 16384, -8867, 16384, -8867, 12873, -22725, 19266, -22725, - 21407, -16384, -21407, 16384, 19266, 4520, -12873, 4520, -/* row 1/7*/ - 22725, 29692, -22725, -29692, 31521, 26722, -31521, -17855, - 12299, 22725, 12299, 22725, 6270, 17855, -6270, 26722, - 22725, -12299, 22725, -12299, 17855, -31521, 26722, -31521, - 29692, -22725, -29692, 22725, 26722, 6270, -17855, 6270, -/* row 2/6*/ - 21407, 27969, -21407, -27969, 29692, 25172, -29692, -16819, - 11585, 21407, 11585, 21407, 5906, 16819, -5906, 25172, - 21407, -11585, 21407, -11585, 16819, -29692, 25172, -29692, - 27969, -21407, -27969, 21407, 25172, 5906, -16819, 5906, -/*row 3/5*/ - 19266, 25172, -19266, -25172, 26722, 22654, -26722, -15137, - 10426, 19266, 10426, 19266, 5315, 15137, -5315, 22654, - 19266, -10426, 19266, -10426, 15137, -26722, 22654, -26722, - 25172, -19266, -25172, 19266, 22654, 5315, -15137, 5315, -/*column constants*/ - TG1, TG1, TG1, TG1, TG1, TG1, TG1, TG1, - TG2, TG2, TG2, TG2, TG2, TG2, TG2, TG2, - TG3, TG3, TG3, TG3, TG3, TG3, TG3, TG3, - CS4, CS4, CS4, CS4, CS4, CS4, CS4, CS4, -/* clamp */ - 255, 255, 255, 255, 255, 255, 255, 255 -}; - - -#define DCT_8_INV_ROW1(blk, rowoff, taboff, rnd, outreg) { \ - lq(blk, rowoff, $16); /* r16 = x7 x5 x3 x1 x6 x4 x2 x0 */ \ - /*slot*/ \ - lq($24, 0+taboff, $17); /* r17 = w */ \ - /*delay slot $16*/ \ - lq($24, 16+taboff, $18);/* r18 = w */ \ - prevh($16, $2); /* r2 = x1 x3 x5 x7 x0 x2 x4 x6 */ \ - lq($24, 32+taboff, $19);/* r19 = w */ \ - phmadh($17, $16, $17); /* r17 = b1"b0'a1"a0' */ \ - lq($24, 48+taboff, $20);/* r20 = w */ \ - phmadh($18, $2, $18); /* r18 = b1'b0"a1'a0" */ \ - phmadh($19, $16, $19); /* r19 = b3"b2'a3"a2' */ \ - phmadh($20, $2, $20); /* r20 = b3'b2"a3'a2" */ \ - paddw($17, $18, $17); /* r17 = (b1)(b0)(a1)(a0) */ \ - paddw($19, $20, $19); /* r19 = (b3)(b2)(a3)(a2) */ \ - pcpyld($19, $17, $18); /* r18 = (a3)(a2)(a1)(a0) */ \ - pcpyud($17, $19, $20); /* r20 = (b3)(b2)(b1)(b0) */ \ - paddw($18, rnd, $18); /* r18 = (a3)(a2)(a1)(a0) */\ - paddw($18, $20, $17); /* r17 = ()()()(a0+b0) */ \ - psubw($18, $20, $20); /* r20 = ()()()(a0-b0) */ \ - psraw($17, SHIFT_INV_ROW, $17); /* r17 = (y3 y2 y1 y0) */ \ - psraw($20, SHIFT_INV_ROW, $20); /* r20 = (y4 y5 y6 y7) */ \ - ppach($20, $17, outreg);/* out = y4 y5 y6 y7 y3 y2 y1 y0 Note order */ \ -\ - prevh(outreg, $2); \ - pcpyud($2, $2, $2); \ - pcpyld($2, outreg, outreg); \ -} - - -#define DCT_8_INV_COL8() \ -\ - lq($24, TG_3_16, $2); /* r2 = tn3 */ \ -\ - pmulth($11, $2, $17); /* r17 = x3 * tn3 (6420) */ \ - psraw($17, 15, $17); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $17, $17); /* r17 = x3 * tn3 */ \ - psubh($17, $13, $17); /* r17 = tm35 */ \ -\ - pmulth($13, $2, $18); /* r18 = x5 * tn3 (6420) */ \ - psraw($18, 15, $18); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $18, $18); /* r18 = x5 * tn3 */ \ - paddh($18, $11, $18); /* r18 = tp35 */ \ -\ - lq($24, TG_1_16, $2); /* r2 = tn1 */ \ -\ - pmulth($15, $2, $19); /* r19 = x7 * tn1 (6420) */ \ - psraw($19, 15, $19); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $19, $19); /* r19 = x7 * tn1 */ \ - paddh($19, $9, $19); /* r19 = tp17 */ \ -\ - pmulth($9, $2, $20); /* r20 = x1 * tn1 (6420) */ \ - psraw($20, 15, $20); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $20, $20); /* r20 = x1 * tn1 */ \ - psubh($20, $15, $20); /* r20 = tm17 */ \ -\ - psubh($19, $18, $3); /* r3 = t1 */ \ - paddh($20, $17, $16); /* r16 = t2 */ \ - psubh($20, $17, $23); /* r23 = b3 */ \ - paddh($19, $18, $20); /* r20 = b0 */ \ -\ - lq($24, COS_4_16, $2); /* r2 = cs4 */ \ -\ - paddh($3, $16, $21); /* r21 = t1+t2 */ \ - psubh($3, $16, $22); /* r22 = t1-t2 */ \ -\ - pmulth($21, $2, $21); /* r21 = cs4 * (t1+t2) 6420 */ \ - psraw($21, 15, $21); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $21, $21); /* r21 = b1 */ \ -\ - pmulth($22, $2, $22); /* r22 = cs4 * (t1-t2) 6420 */ \ - psraw($22, 15, $22); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $22, $22); /* r22 = b2 */ \ -\ - lq($24, TG_2_16, $2); /* r2 = tn2 */ \ -\ - pmulth($10, $2, $17); /* r17 = x2 * tn2 (6420) */ \ - psraw($17, 15, $17); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $17, $17); /* r17 = x3 * tn3 */ \ - psubh($17, $14, $17); /* r17 = tm26 */ \ -\ - pmulth($14, $2, $18); /* r18 = x6 * tn2 (6420) */ \ - psraw($18, 15, $18); \ - pmfhl_uw($3); /* r3 = 7531 */ \ - psraw($3, 15, $3); \ - pinteh($3, $18, $18); /* r18 = x6 * tn2 */ \ - paddh($18, $10, $18); /* r18 = tp26 */ \ -\ - paddh($8, $12, $2); /* r2 = tp04 */ \ - psubh($8, $12, $3); /* r3 = tm04 */ \ -\ - paddh($2, $18, $16); /* r16 = a0 */ \ - psubh($2, $18, $19); /* r19 = a3 */ \ - psubh($3, $17, $18); /* r18 = a2 */ \ - paddh($3, $17, $17); /* r17 = a1 */ - - -#define DCT_8_INV_COL8_STORE(blk) \ -\ - paddh($16, $20, $2); /* y0 a0+b0 */ \ - psubh($16, $20, $16); /* y7 a0-b0 */ \ - psrah($2, SHIFT_INV_COL, $2); \ - psrah($16, SHIFT_INV_COL, $16); \ - sq($2, 0, blk); \ - sq($16, 112, blk); \ -\ - paddh($17, $21, $3); /* y1 a1+b1 */ \ - psubh($17, $21, $17); /* y6 a1-b1 */ \ - psrah($3, SHIFT_INV_COL, $3); \ - psrah($17, SHIFT_INV_COL, $17); \ - sq($3, 16, blk); \ - sq($17, 96, blk); \ -\ - paddh($18, $22, $2); /* y2 a2+b2 */ \ - psubh($18, $22, $18); /* y5 a2-b2 */ \ - psrah($2, SHIFT_INV_COL, $2); \ - psrah($18, SHIFT_INV_COL, $18); \ - sq($2, 32, blk); \ - sq($18, 80, blk); \ -\ - paddh($19, $23, $3); /* y3 a3+b3 */ \ - psubh($19, $23, $19); /* y4 a3-b3 */ \ - psrah($3, SHIFT_INV_COL, $3); \ - psrah($19, SHIFT_INV_COL, $19); \ - sq($3, 48, blk); \ - sq($19, 64, blk); - - - -#define DCT_8_INV_COL8_PMS() \ - paddh($16, $20, $2); /* y0 a0+b0 */ \ - psubh($16, $20, $20); /* y7 a0-b0 */ \ - psrah($2, SHIFT_INV_COL, $16); \ - psrah($20, SHIFT_INV_COL, $20); \ -\ - paddh($17, $21, $3); /* y1 a1+b1 */ \ - psubh($17, $21, $21); /* y6 a1-b1 */ \ - psrah($3, SHIFT_INV_COL, $17); \ - psrah($21, SHIFT_INV_COL, $21); \ -\ - paddh($18, $22, $2); /* y2 a2+b2 */ \ - psubh($18, $22, $22); /* y5 a2-b2 */ \ - psrah($2, SHIFT_INV_COL, $18); \ - psrah($22, SHIFT_INV_COL, $22); \ -\ - paddh($19, $23, $3); /* y3 a3+b3 */ \ - psubh($19, $23, $23); /* y4 a3-b3 */ \ - psrah($3, SHIFT_INV_COL, $19); \ - psrah($23, SHIFT_INV_COL, $23); - -#define PUT(rs) \ - pminh(rs, $11, $2); \ - pmaxh($2, $0, $2); \ - ppacb($0, $2, $2); \ - sd3(2, 0, 4); \ - __asm__ volatile ("add $4, $5, $4"); - -#define DCT_8_INV_COL8_PUT() \ - PUT($16); \ - PUT($17); \ - PUT($18); \ - PUT($19); \ - PUT($23); \ - PUT($22); \ - PUT($21); \ - PUT($20); - -#define ADD(rs) \ - ld3(4, 0, 2); \ - pextlb($0, $2, $2); \ - paddh($2, rs, $2); \ - pminh($2, $11, $2); \ - pmaxh($2, $0, $2); \ - ppacb($0, $2, $2); \ - sd3(2, 0, 4); \ - __asm__ volatile ("add $4, $5, $4"); - -/*fixme: schedule*/ -#define DCT_8_INV_COL8_ADD() \ - ADD($16); \ - ADD($17); \ - ADD($18); \ - ADD($19); \ - ADD($23); \ - ADD($22); \ - ADD($21); \ - ADD($20); - - -void ff_mmi_idct(int16_t * block) -{ - /* $4 = block */ - __asm__ volatile("la $24, %0"::"m"(consttable[0])); - lq($24, ROUNDER_0, $8); - lq($24, ROUNDER_1, $7); - DCT_8_INV_ROW1($4, 0, TAB_i_04, $8, $8); - DCT_8_INV_ROW1($4, 16, TAB_i_17, $7, $9); - DCT_8_INV_ROW1($4, 32, TAB_i_26, $7, $10); - DCT_8_INV_ROW1($4, 48, TAB_i_35, $7, $11); - DCT_8_INV_ROW1($4, 64, TAB_i_04, $7, $12); - DCT_8_INV_ROW1($4, 80, TAB_i_35, $7, $13); - DCT_8_INV_ROW1($4, 96, TAB_i_26, $7, $14); - DCT_8_INV_ROW1($4, 112, TAB_i_17, $7, $15); - DCT_8_INV_COL8(); - DCT_8_INV_COL8_STORE($4); - - //let savedtemp regs be saved - __asm__ volatile(" ":::"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23"); -} - - -void ff_mmi_idct_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - /* $4 = dest, $5 = line_size, $6 = block */ - __asm__ volatile("la $24, %0"::"m"(consttable[0])); - lq($24, ROUNDER_0, $8); - lq($24, ROUNDER_1, $7); - DCT_8_INV_ROW1($6, 0, TAB_i_04, $8, $8); - DCT_8_INV_ROW1($6, 16, TAB_i_17, $7, $9); - DCT_8_INV_ROW1($6, 32, TAB_i_26, $7, $10); - DCT_8_INV_ROW1($6, 48, TAB_i_35, $7, $11); - DCT_8_INV_ROW1($6, 64, TAB_i_04, $7, $12); - DCT_8_INV_ROW1($6, 80, TAB_i_35, $7, $13); - DCT_8_INV_ROW1($6, 96, TAB_i_26, $7, $14); - DCT_8_INV_ROW1($6, 112, TAB_i_17, $7, $15); - DCT_8_INV_COL8(); - lq($24, CLIPMAX, $11); - DCT_8_INV_COL8_PMS(); - DCT_8_INV_COL8_PUT(); - - //let savedtemp regs be saved - __asm__ volatile(" ":::"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23"); -} - - -void ff_mmi_idct_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - /* $4 = dest, $5 = line_size, $6 = block */ - __asm__ volatile("la $24, %0"::"m"(consttable[0])); - lq($24, ROUNDER_0, $8); - lq($24, ROUNDER_1, $7); - DCT_8_INV_ROW1($6, 0, TAB_i_04, $8, $8); - DCT_8_INV_ROW1($6, 16, TAB_i_17, $7, $9); - DCT_8_INV_ROW1($6, 32, TAB_i_26, $7, $10); - DCT_8_INV_ROW1($6, 48, TAB_i_35, $7, $11); - DCT_8_INV_ROW1($6, 64, TAB_i_04, $7, $12); - DCT_8_INV_ROW1($6, 80, TAB_i_35, $7, $13); - DCT_8_INV_ROW1($6, 96, TAB_i_26, $7, $14); - DCT_8_INV_ROW1($6, 112, TAB_i_17, $7, $15); - DCT_8_INV_COL8(); - lq($24, CLIPMAX, $11); - DCT_8_INV_COL8_PMS(); - DCT_8_INV_COL8_ADD(); - - //let savedtemp regs be saved - __asm__ volatile(" ":::"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23"); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/ps2/mmi.h b/tizen/distrib/ffmpeg/libavcodec/ps2/mmi.h deleted file mode 100644 index 0265456..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ps2/mmi.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * copyright (c) 2002 Leon van Stuivenberg - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PS2_MMI_H -#define AVCODEC_PS2_MMI_H - -#define align16 __attribute__ ((aligned (16))) - -/* -#define r0 $zero -#define r1 $at //assembler! -#define r2 $v0 //return -#define r3 $v1 //return -#define r4 $a0 //arg -#define r5 $a1 //arg -#define r6 $a2 //arg -#define r7 $a3 //arg -#define r8 $t0 //temp -#define r9 $t1 //temp -#define r10 $t2 //temp -#define r11 $t3 //temp -#define r12 $t4 //temp -#define r13 $t5 //temp -#define r14 $t6 //temp -#define r15 $t7 //temp -#define r16 $s0 //saved temp -#define r17 $s1 //saved temp -#define r18 $s2 //saved temp -#define r19 $s3 //saved temp -#define r20 $s4 //saved temp -#define r21 $s5 //saved temp -#define r22 $s6 //saved temp -#define r23 $s7 //saved temp -#define r24 $t8 //temp -#define r25 $t9 //temp -#define r26 $k0 //kernel -#define r27 $k1 //kernel -#define r28 $gp //global ptr -#define r29 $sp //stack ptr -#define r30 $fp //frame ptr -#define r31 $ra //return addr -*/ - - -#define lq(base, off, reg) \ - __asm__ volatile ("lq " #reg ", %0("#base ")" : : "i" (off) ) - -#define lq2(mem, reg) \ - __asm__ volatile ("lq " #reg ", %0" : : "r" (mem)) - -#define sq(reg, off, base) \ - __asm__ volatile ("sq " #reg ", %0("#base ")" : : "i" (off) ) - -/* -#define ld(base, off, reg) \ - __asm__ volatile ("ld " #reg ", " #off "("#base ")") -*/ - -#define ld3(base, off, reg) \ - __asm__ volatile (".word %0" : : "i" ( 0xdc000000 | (base<<21) | (reg<<16) | (off))) - -#define ldr3(base, off, reg) \ - __asm__ volatile (".word %0" : : "i" ( 0x6c000000 | (base<<21) | (reg<<16) | (off))) - -#define ldl3(base, off, reg) \ - __asm__ volatile (".word %0" : : "i" ( 0x68000000 | (base<<21) | (reg<<16) | (off))) - -/* -#define sd(reg, off, base) \ - __asm__ volatile ("sd " #reg ", " #off "("#base ")") -*/ -//seems assembler has bug encoding mnemonic 'sd', so DIY -#define sd3(reg, off, base) \ - __asm__ volatile (".word %0" : : "i" ( 0xfc000000 | (base<<21) | (reg<<16) | (off))) - -#define sw(reg, off, base) \ - __asm__ volatile ("sw " #reg ", " #off "("#base ")") - -#define sq2(reg, mem) \ - __asm__ volatile ("sq " #reg ", %0" : : "m" (*(mem))) - -#define pinth(rs, rt, rd) \ - __asm__ volatile ("pinth " #rd ", " #rs ", " #rt ) - -#define phmadh(rs, rt, rd) \ - __asm__ volatile ("phmadh " #rd ", " #rs ", " #rt ) - -#define pcpyud(rs, rt, rd) \ - __asm__ volatile ("pcpyud " #rd ", " #rs ", " #rt ) - -#define pcpyld(rs, rt, rd) \ - __asm__ volatile ("pcpyld " #rd ", " #rs ", " #rt ) - -#define pcpyh(rt, rd) \ - __asm__ volatile ("pcpyh " #rd ", " #rt ) - -#define paddw(rs, rt, rd) \ - __asm__ volatile ("paddw " #rd ", " #rs ", " #rt ) - -#define pextlw(rs, rt, rd) \ - __asm__ volatile ("pextlw " #rd ", " #rs ", " #rt ) - -#define pextuw(rs, rt, rd) \ - __asm__ volatile ("pextuw " #rd ", " #rs ", " #rt ) - -#define pextlh(rs, rt, rd) \ - __asm__ volatile ("pextlh " #rd ", " #rs ", " #rt ) - -#define pextuh(rs, rt, rd) \ - __asm__ volatile ("pextuh " #rd ", " #rs ", " #rt ) - -#define psubw(rs, rt, rd) \ - __asm__ volatile ("psubw " #rd ", " #rs ", " #rt ) - -#define psraw(rt, sa, rd) \ - __asm__ volatile ("psraw " #rd ", " #rt ", %0" : : "i"(sa) ) - -#define ppach(rs, rt, rd) \ - __asm__ volatile ("ppach " #rd ", " #rs ", " #rt ) - -#define ppacb(rs, rt, rd) \ - __asm__ volatile ("ppacb " #rd ", " #rs ", " #rt ) - -#define prevh(rt, rd) \ - __asm__ volatile ("prevh " #rd ", " #rt ) - -#define pmulth(rs, rt, rd) \ - __asm__ volatile ("pmulth " #rd ", " #rs ", " #rt ) - -#define pmaxh(rs, rt, rd) \ - __asm__ volatile ("pmaxh " #rd ", " #rs ", " #rt ) - -#define pminh(rs, rt, rd) \ - __asm__ volatile ("pminh " #rd ", " #rs ", " #rt ) - -#define pinteh(rs, rt, rd) \ - __asm__ volatile ("pinteh " #rd ", " #rs ", " #rt ) - -#define paddh(rs, rt, rd) \ - __asm__ volatile ("paddh " #rd ", " #rs ", " #rt ) - -#define psubh(rs, rt, rd) \ - __asm__ volatile ("psubh " #rd ", " #rs ", " #rt ) - -#define psrah(rt, sa, rd) \ - __asm__ volatile ("psrah " #rd ", " #rt ", %0" : : "i"(sa) ) - -#define pmfhl_uw(rd) \ - __asm__ volatile ("pmfhl.uw " #rd) - -#define pextlb(rs, rt, rd) \ - __asm__ volatile ("pextlb " #rd ", " #rs ", " #rt ) - -#endif /* AVCODEC_PS2_MMI_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c b/tizen/distrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c deleted file mode 100644 index 68c3b0d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2000,2001 Fabrice Bellard - * - * MMI optimization by Leon van Stuivenberg - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" - -static void dct_unquantize_h263_mmi(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - int level=0, qmul, qadd; - int nCoeffs; - - assert(s->block_last_index[n]>=0); - - qadd = (qscale - 1) | 1; - qmul = qscale << 1; - - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - level = block[0] * s->y_dc_scale; - else - level = block[0] * s->c_dc_scale; - }else { - qadd = 0; - level = block[0]; - } - nCoeffs= 63; //does not always use zigzag table - } else { - nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; - } - - __asm__ volatile( - "add $14, $0, %3 \n\t" - "pcpyld $8, %0, %0 \n\t" - "pcpyh $8, $8 \n\t" //r8 = qmul - "pcpyld $9, %1, %1 \n\t" - "pcpyh $9, $9 \n\t" //r9 = qadd - ".p2align 2 \n\t" - "1: \n\t" - "lq $10, 0($14) \n\t" //r10 = level - "addi $14, $14, 16 \n\t" //block+=8 - "addi %2, %2, -8 \n\t" - "pcgth $11, $0, $10 \n\t" //r11 = level < 0 ? -1 : 0 - "pcgth $12, $10, $0 \n\t" //r12 = level > 0 ? -1 : 0 - "por $12, $11, $12 \n\t" - "pmulth $10, $10, $8 \n\t" - "paddh $13, $9, $11 \n\t" - "pxor $13, $13, $11 \n\t" //r13 = level < 0 ? -qadd : qadd - "pmfhl.uw $11 \n\t" - "pinteh $10, $11, $10 \n\t" //r10 = level * qmul - "paddh $10, $10, $13 \n\t" - "pand $10, $10, $12 \n\t" - "sq $10, -16($14) \n\t" - "bgez %2, 1b \n\t" - :: "r"(qmul), "r" (qadd), "r" (nCoeffs), "r" (block) : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "memory" ); - - if(s->mb_intra) - block[0]= level; -} - - -void MPV_common_init_mmi(MpegEncContext *s) -{ - s->dct_unquantize_h263_intra = - s->dct_unquantize_h263_inter = dct_unquantize_h263_mmi; -} - - diff --git a/tizen/distrib/ffmpeg/libavcodec/psymodel.c b/tizen/distrib/ffmpeg/libavcodec/psymodel.c deleted file mode 100644 index f87dbcf..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/psymodel.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * audio encoder psychoacoustic model - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "psymodel.h" -#include "iirfilter.h" - -extern const FFPsyModel ff_aac_psy_model; - -av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, - int num_lens, - const uint8_t **bands, const int* num_bands) -{ - ctx->avctx = avctx; - ctx->psy_bands = av_mallocz(sizeof(FFPsyBand) * PSY_MAX_BANDS * avctx->channels); - ctx->bands = av_malloc (sizeof(ctx->bands[0]) * num_lens); - ctx->num_bands = av_malloc (sizeof(ctx->num_bands[0]) * num_lens); - memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens); - memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens); - switch (ctx->avctx->codec_id) { - case CODEC_ID_AAC: - ctx->model = &ff_aac_psy_model; - break; - } - if (ctx->model->init) - return ctx->model->init(ctx); - return 0; -} - -FFPsyWindowInfo ff_psy_suggest_window(FFPsyContext *ctx, - const int16_t *audio, const int16_t *la, - int channel, int prev_type) -{ - return ctx->model->window(ctx, audio, la, channel, prev_type); -} - -void ff_psy_set_band_info(FFPsyContext *ctx, int channel, - const float *coeffs, FFPsyWindowInfo *wi) -{ - ctx->model->analyze(ctx, channel, coeffs, wi); -} - -av_cold void ff_psy_end(FFPsyContext *ctx) -{ - if (ctx->model->end) - ctx->model->end(ctx); - av_freep(&ctx->bands); - av_freep(&ctx->num_bands); - av_freep(&ctx->psy_bands); -} - -typedef struct FFPsyPreprocessContext{ - AVCodecContext *avctx; - float stereo_att; - struct FFIIRFilterCoeffs *fcoeffs; - struct FFIIRFilterState **fstate; -}FFPsyPreprocessContext; - -#define FILT_ORDER 4 - -av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx) -{ - FFPsyPreprocessContext *ctx; - int i; - float cutoff_coeff = 0; - ctx = av_mallocz(sizeof(FFPsyPreprocessContext)); - ctx->avctx = avctx; - - if (avctx->cutoff > 0) - cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate; - - if (cutoff_coeff) - ctx->fcoeffs = ff_iir_filter_init_coeffs(FF_FILTER_TYPE_BUTTERWORTH, FF_FILTER_MODE_LOWPASS, - FILT_ORDER, cutoff_coeff, 0.0, 0.0); - if (ctx->fcoeffs) { - ctx->fstate = av_mallocz(sizeof(ctx->fstate[0]) * avctx->channels); - for (i = 0; i < avctx->channels; i++) - ctx->fstate[i] = ff_iir_filter_init_state(FILT_ORDER); - } - return ctx; -} - -void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, - const int16_t *audio, int16_t *dest, - int tag, int channels) -{ - int ch, i; - if (ctx->fstate) { - for (ch = 0; ch < channels; ch++) - ff_iir_filter(ctx->fcoeffs, ctx->fstate[tag+ch], ctx->avctx->frame_size, - audio + ch, ctx->avctx->channels, - dest + ch, ctx->avctx->channels); - } else { - for (ch = 0; ch < channels; ch++) - for (i = 0; i < ctx->avctx->frame_size; i++) - dest[i*ctx->avctx->channels + ch] = audio[i*ctx->avctx->channels + ch]; - } -} - -av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx) -{ - int i; - ff_iir_filter_free_coeffs(ctx->fcoeffs); - if (ctx->fstate) - for (i = 0; i < ctx->avctx->channels; i++) - ff_iir_filter_free_state(ctx->fstate[i]); - av_freep(&ctx->fstate); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/psymodel.h b/tizen/distrib/ffmpeg/libavcodec/psymodel.h deleted file mode 100644 index bc19d49..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/psymodel.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * audio encoder psychoacoustic model - * Copyright (C) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_PSYMODEL_H -#define AVCODEC_PSYMODEL_H - -#include "avcodec.h" - -/** maximum possible number of bands */ -#define PSY_MAX_BANDS 128 - -/** - * single band psychoacoustic information - */ -typedef struct FFPsyBand { - int bits; - float energy; - float threshold; - float distortion; - float perceptual_weight; -} FFPsyBand; - -/** - * windowing related information - */ -typedef struct FFPsyWindowInfo { - int window_type[3]; ///< window type (short/long/transitional, etc.) - current, previous and next - int window_shape; ///< window shape (sine/KBD/whatever) - int num_windows; ///< number of windows in a frame - int grouping[8]; ///< window grouping (for e.g. AAC) - int *window_sizes; ///< sequence of window sizes inside one frame (for eg. WMA) -} FFPsyWindowInfo; - -/** - * context used by psychoacoustic model - */ -typedef struct FFPsyContext { - AVCodecContext *avctx; ///< encoder context - const struct FFPsyModel *model; ///< encoder-specific model functions - - FFPsyBand *psy_bands; ///< frame bands information - - uint8_t **bands; ///< scalefactor band sizes for possible frame sizes - int *num_bands; ///< number of scalefactor bands for possible frame sizes - int num_lens; ///< number of scalefactor band sets - - void* model_priv_data; ///< psychoacoustic model implementation private data -} FFPsyContext; - -/** - * codec-specific psychoacoustic model implementation - */ -typedef struct FFPsyModel { - const char *name; - int (*init) (FFPsyContext *apc); - FFPsyWindowInfo (*window)(FFPsyContext *ctx, const int16_t *audio, const int16_t *la, int channel, int prev_type); - void (*analyze)(FFPsyContext *ctx, int channel, const float *coeffs, FFPsyWindowInfo *wi); - void (*end) (FFPsyContext *apc); -} FFPsyModel; - -/** - * Initialize psychoacoustic model. - * - * @param ctx model context - * @param avctx codec context - * @param num_lens number of possible frame lengths - * @param bands scalefactor band lengths for all frame lengths - * @param num_bands number of scalefactor bands for all frame lengths - * - * @return zero if successful, a negative value if not - */ -av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, - int num_lens, - const uint8_t **bands, const int* num_bands); - -/** - * Suggest window sequence for channel. - * - * @param ctx model context - * @param audio samples for the current frame - * @param la lookahead samples (NULL when unavailable) - * @param channel number of channel element to analyze - * @param prev_type previous window type - * - * @return suggested window information in a structure - */ -FFPsyWindowInfo ff_psy_suggest_window(FFPsyContext *ctx, - const int16_t *audio, const int16_t *la, - int channel, int prev_type); - - -/** - * Perform psychoacoustic analysis and set band info (threshold, energy). - * - * @param ctx model context - * @param channel audio channel number - * @param coeffs pointer to the transformed coefficients - * @param wi window information - */ -void ff_psy_set_band_info(FFPsyContext *ctx, int channel, const float *coeffs, - FFPsyWindowInfo *wi); - -/** - * Cleanup model context at the end. - * - * @param ctx model context - */ -av_cold void ff_psy_end(FFPsyContext *ctx); - - -/************************************************************************** - * Audio preprocessing stuff. * - * This should be moved into some audio filter eventually. * - **************************************************************************/ -struct FFPsyPreprocessContext; - -/** - * psychoacoustic model audio preprocessing initialization - */ -av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx); - -/** - * Preprocess several channel in audio frame in order to compress it better. - * - * @param ctx preprocessing context - * @param audio samples to preprocess - * @param dest place to put filtered samples - * @param tag channel number - * @param channels number of channel to preprocess (some additional work may be done on stereo pair) - */ -void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, - const int16_t *audio, int16_t *dest, - int tag, int channels); - -/** - * Cleanup audio preprocessing module. - */ -av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx); - -#endif /* AVCODEC_PSYMODEL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/pthread.c b/tizen/distrib/ffmpeg/libavcodec/pthread.c deleted file mode 100644 index 1628b21..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/pthread.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2004 Roman Shaposhnik - * - * Many thanks to Steven M. Schultz for providing clever ideas and - * to Michael Niedermayer for writing initial - * implementation. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include - -#include "avcodec.h" - -typedef int (action_func)(AVCodecContext *c, void *arg); -typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); - -typedef struct ThreadContext { - pthread_t *workers; - action_func *func; - action_func2 *func2; - void *args; - int *rets; - int rets_count; - int job_count; - int job_size; - - pthread_cond_t last_job_cond; - pthread_cond_t current_job_cond; - pthread_mutex_t current_job_lock; - int current_job; - int done; -} ThreadContext; - -static void* attribute_align_arg worker(void *v) -{ - AVCodecContext *avctx = v; - ThreadContext *c = avctx->thread_opaque; - int our_job = c->job_count; - int thread_count = avctx->thread_count; - int self_id; - - pthread_mutex_lock(&c->current_job_lock); - self_id = c->current_job++; - for (;;){ - while (our_job >= c->job_count) { - if (c->current_job == thread_count + c->job_count) - pthread_cond_signal(&c->last_job_cond); - - pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); - our_job = self_id; - - if (c->done) { - pthread_mutex_unlock(&c->current_job_lock); - return NULL; - } - } - pthread_mutex_unlock(&c->current_job_lock); - - c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size): - c->func2(avctx, c->args, our_job, self_id); - - pthread_mutex_lock(&c->current_job_lock); - our_job = c->current_job++; - } -} - -static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count) -{ - pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); - pthread_mutex_unlock(&c->current_job_lock); -} - -void avcodec_thread_free(AVCodecContext *avctx) -{ - ThreadContext *c = avctx->thread_opaque; - int i; - - pthread_mutex_lock(&c->current_job_lock); - c->done = 1; - pthread_cond_broadcast(&c->current_job_cond); - pthread_mutex_unlock(&c->current_job_lock); - - for (i=0; ithread_count; i++) - pthread_join(c->workers[i], NULL); - - pthread_mutex_destroy(&c->current_job_lock); - pthread_cond_destroy(&c->current_job_cond); - pthread_cond_destroy(&c->last_job_cond); - av_free(c->workers); - av_freep(&avctx->thread_opaque); -} - -static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size) -{ - ThreadContext *c= avctx->thread_opaque; - int dummy_ret; - - if (job_count <= 0) - return 0; - - pthread_mutex_lock(&c->current_job_lock); - - c->current_job = avctx->thread_count; - c->job_count = job_count; - c->job_size = job_size; - c->args = arg; - c->func = func; - if (ret) { - c->rets = ret; - c->rets_count = job_count; - } else { - c->rets = &dummy_ret; - c->rets_count = 1; - } - pthread_cond_broadcast(&c->current_job_cond); - - avcodec_thread_park_workers(c, avctx->thread_count); - - return 0; -} - -static int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count) -{ - ThreadContext *c= avctx->thread_opaque; - c->func2 = func2; - return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0); -} - -int avcodec_thread_init(AVCodecContext *avctx, int thread_count) -{ - int i; - ThreadContext *c; - - avctx->thread_count = thread_count; - - if (thread_count <= 1) - return 0; - - c = av_mallocz(sizeof(ThreadContext)); - if (!c) - return -1; - - c->workers = av_mallocz(sizeof(pthread_t)*thread_count); - if (!c->workers) { - av_free(c); - return -1; - } - - avctx->thread_opaque = c; - c->current_job = 0; - c->job_count = 0; - c->job_size = 0; - c->done = 0; - pthread_cond_init(&c->current_job_cond, NULL); - pthread_cond_init(&c->last_job_cond, NULL); - pthread_mutex_init(&c->current_job_lock, NULL); - pthread_mutex_lock(&c->current_job_lock); - for (i=0; iworkers[i], NULL, worker, avctx)) { - avctx->thread_count = i; - pthread_mutex_unlock(&c->current_job_lock); - avcodec_thread_free(avctx); - return -1; - } - } - - avcodec_thread_park_workers(c, thread_count); - - avctx->execute = avcodec_thread_execute; - avctx->execute2 = avcodec_thread_execute2; - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ptx.c b/tizen/distrib/ffmpeg/libavcodec/ptx.c deleted file mode 100644 index d8798f2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ptx.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * V.Flash PTX (.ptx) image decoder - * Copyright (c) 2007 Ivo van Poorten - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct PTXContext { - AVFrame picture; -} PTXContext; - -static av_cold int ptx_init(AVCodecContext *avctx) { - PTXContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - - return 0; -} - -static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - PTXContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; - unsigned int offset, w, h, y, stride, bytes_per_pixel; - uint8_t *ptr; - - offset = AV_RL16(buf); - w = AV_RL16(buf+8); - h = AV_RL16(buf+10); - bytes_per_pixel = AV_RL16(buf+12) >> 3; - - if (bytes_per_pixel != 2) { - av_log(avctx, AV_LOG_ERROR, "image format is not rgb15, please report on ffmpeg-users mailing list\n"); - return -1; - } - - avctx->pix_fmt = PIX_FMT_RGB555; - - if (offset != 0x2c) - av_log(avctx, AV_LOG_WARNING, "offset != 0x2c, untested due to lack of sample files\n"); - - buf += offset; - - if (p->data[0]) - avctx->release_buffer(avctx, p); - - if (avcodec_check_dimensions(avctx, w, h)) - return -1; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - 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; - - ptr = p->data[0]; - stride = p->linesize[0]; - - for (y=0; ypicture; - *data_size = sizeof(AVPicture); - - return offset + w*h*bytes_per_pixel; -} - -static av_cold int ptx_end(AVCodecContext *avctx) { - PTXContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec ptx_decoder = { - "ptx", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_PTX, - sizeof(PTXContext), - ptx_init, - NULL, - ptx_end, - ptx_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("V.Flash PTX image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/put_bits.h b/tizen/distrib/ffmpeg/libavcodec/put_bits.h deleted file mode 100644 index 80a514d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/put_bits.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * bitstream writer API - */ - -#ifndef AVCODEC_PUT_BITS_H -#define AVCODEC_PUT_BITS_H - -#include -#include -#include -#include "libavutil/bswap.h" -#include "libavutil/common.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/log.h" -#include "mathops.h" - -//#define ALT_BITSTREAM_WRITER -//#define ALIGNED_BITSTREAM_WRITER - -/* 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 - int size_in_bits; -} PutBitContext; - -/** - * Initializes the PutBitContext s. - * - * @param buffer the buffer where to put bits - * @param buffer_size the size in bytes of buffer - */ -static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size) -{ - if(buffer_size < 0) { - buffer_size = 0; - buffer = NULL; - } - - s->size_in_bits= 8*buffer_size; - 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 -} - -/** - * Returns the total number of bits written to the bitstream. - */ -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 -} - -/** - * Pads 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 -#ifndef BITSTREAM_WRITER_LE - s->bit_buf<<= s->bit_left; -#endif - while (s->bit_left < 32) { - /* XXX: should test end of buffer */ -#ifdef BITSTREAM_WRITER_LE - *s->buf_ptr++=s->bit_buf; - s->bit_buf>>=8; -#else - *s->buf_ptr++=s->bit_buf >> 24; - s->bit_buf<<=8; -#endif - s->bit_left+=8; - } - s->bit_left=32; - s->bit_buf=0; -#endif -} - -#if defined(ALT_BITSTREAM_WRITER) || defined(BITSTREAM_WRITER_LE) -#define align_put_bits align_put_bits_unsupported_here -#define ff_put_string ff_put_string_unsupported_here -#define ff_copy_bits ff_copy_bits_unsupported_here -#else -/** - * Pads the bitstream with zeros up to the next byte boundary. - */ -void align_put_bits(PutBitContext *s); - -/** - * Puts the string string in the bitstream. - * - * @param terminate_string 0-terminates the written string if value is 1 - */ -void ff_put_string(PutBitContext *pb, const char *string, int terminate_string); - -/** - * Copies the content of src to the bitstream. - * - * @param length the number of bits of src to copy - */ -void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); -#endif - -/** - * Writes up to 31 bits into a bitstream. - * Use put_bits32 to write 32 bits. - */ -static inline void put_bits(PutBitContext *s, int n, unsigned int value) -#ifndef ALT_BITSTREAM_WRITER -{ - unsigned int bit_buf; - int bit_left; - - // printf("put_bits=%d %x\n", n, value); - assert(n <= 31 && 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 */ -#ifdef BITSTREAM_WRITER_LE - bit_buf |= value << (32 - bit_left); - if (n >= bit_left) { -#if !HAVE_FAST_UNALIGNED - if (3 & (intptr_t) s->buf_ptr) { - AV_WL32(s->buf_ptr, bit_buf); - } else -#endif - *(uint32_t *)s->buf_ptr = le2me_32(bit_buf); - s->buf_ptr+=4; - bit_buf = (bit_left==32)?0:value >> bit_left; - bit_left+=32; - } - bit_left-=n; -#else - if (n < bit_left) { - bit_buf = (bit_buf<> (n - bit_left); -#if !HAVE_FAST_UNALIGNED - if (3 & (intptr_t) s->buf_ptr) { - AV_WB32(s->buf_ptr, 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; - } -#endif - - s->bit_buf = bit_buf; - s->bit_left = bit_left; -} -#else /* ALT_BITSTREAM_WRITER defined */ -{ -# ifdef ALIGNED_BITSTREAM_WRITER -# if ARCH_X86 - __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 ARCH_X86 - __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 void put_sbits(PutBitContext *pb, int n, int32_t value) -{ - assert(n >= 0 && n <= 31); - - put_bits(pb, n, value & ((1<> 16; -#ifdef BITSTREAM_WRITER_LE - put_bits(s, 16, lo); - put_bits(s, 16, hi); -#else - put_bits(s, 16, hi); - put_bits(s, 16, lo); -#endif -} - -/** - * Returns the pointer to the byte where the bitstream writer will put - * the next bit. - */ -static inline uint8_t* put_bits_ptr(PutBitContext *s) -{ -#ifdef ALT_BITSTREAM_WRITER - return s->buf + (s->index>>3); -#else - return s->buf_ptr; -#endif -} - -/** - * Skips the given number of bytes. - * 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 do not matter. - * If n is 0 the behavior is undefined. - */ -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-= 4*(s->bit_left>>5); - s->bit_left &= 31; -#endif -} - -/** - * Changes the end of the buffer. - * - * @param size the new size in bytes of the buffer where to put bits - */ -static inline void set_put_bits_buffer_size(PutBitContext *s, int size) -{ - s->buf_end= s->buf + size; -} - -#endif /* AVCODEC_PUT_BITS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/qcelpdata.h b/tizen/distrib/ffmpeg/libavcodec/qcelpdata.h deleted file mode 100644 index d79cea9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qcelpdata.h +++ /dev/null @@ -1,552 +0,0 @@ -/* - * QCELP decoder - * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_QCELPDATA_H -#define AVCODEC_QCELPDATA_H - -/** - * @file - * Data tables for the QCELP decoder - * @author Reynaldo H. Verdejo Pinochet - * @remark FFmpeg merging spearheaded by Kenan Gillet - * @remark Development mentored by Benjamin Larson - */ - -#include -#include -#include "libavutil/common.h" - -/** - * QCELP unpacked data frame - */ -typedef struct { -/// @defgroup qcelp_codebook_parameters QCELP excitation codebook parameters -/// @{ - uint8_t cbsign[16]; ///!< sign of the codebook gain for each codebook subframe - uint8_t cbgain[16]; ///!< unsigned codebook gain for each codebook subframe - uint8_t cindex[16]; ///!< codebook index for each codebook subframe -/// @} - -/// @defgroup qcelp_pitch_parameters QCELP pitch prediction parameters -/// @{ - uint8_t plag[4]; ///!< pitch lag for each pitch subframe - uint8_t pfrac[4]; ///!< fractional pitch lag for each pitch subframe - uint8_t pgain[4]; ///!< pitch gain for each pitch subframe -/// @} - - /** - * line spectral pair frequencies (LSP) for RATE_OCTAVE, - * line spectral pair frequencies grouped into five vectors - * of dimension two (LSPV) for other rates - */ - uint8_t lspv[10]; - - /** - * reserved bits only present in bitrate 1, 1/4 and 1/8 packets - */ - uint8_t reserved; -} QCELPFrame; - -/** - * pre-calculated table for hammsinc function - * Only half of the table is needed because of symmetry. - * - * TIA/EIA/IS-733 2.4.5.2-2/3 - */ -static const float qcelp_hammsinc_table[4] = { -0.006822, 0.041249, -0.143459, 0.588863}; - -typedef struct { - uint8_t index; /*!< index into the QCELPContext structure */ - uint8_t bitpos; /*!< position of the lowest bit in the value's byte */ - uint8_t bitlen; /*!< number of bits to read */ -} QCELPBitmap; - -#define QCELP_OF(variable, bit, len) {offsetof(QCELPFrame, variable), bit, len} - -/** - * bitmap unpacking tables for RATE_FULL - * - * TIA/EIA/IS-733 Table 2.4.7.1-1 - */ -static const QCELPBitmap qcelp_rate_full_bitmap[] = { - // start on bit - QCELP_OF(lspv [ 2], 0, 3), // 265 - QCELP_OF(lspv [ 1], 0, 7), // 262 - QCELP_OF(lspv [ 0], 0, 6), // 255 - QCELP_OF(lspv [ 4], 0, 6), // 249 - QCELP_OF(lspv [ 3], 0, 6), // 243 - QCELP_OF(lspv [ 2], 3, 4), // 237 - QCELP_OF(cbsign[ 0], 0, 1), // 233 - QCELP_OF(cbgain[ 0], 0, 4), // 232 - QCELP_OF(pfrac [ 0], 0, 1), // 228 - QCELP_OF(plag [ 0], 0, 7), // 227 - QCELP_OF(pgain [ 0], 0, 3), // 220 - QCELP_OF(cindex[ 1], 0, 4), // 217 - QCELP_OF(cbsign[ 1], 0, 1), // 213 - QCELP_OF(cbgain[ 1], 0, 4), // 212 - QCELP_OF(cindex[ 0], 0, 7), // 208 - QCELP_OF(cbgain[ 3], 0, 1), // 201 - QCELP_OF(cindex[ 2], 0, 7), // 200 - QCELP_OF(cbsign[ 2], 0, 1), // 193 - QCELP_OF(cbgain[ 2], 0, 4), // 192 - QCELP_OF(cindex[ 1], 4, 3), // 188 - QCELP_OF(plag [ 1], 0, 3), // 185 - QCELP_OF(pgain [ 1], 0, 3), // 182 - QCELP_OF(cindex[ 3], 0, 7), // 179 - QCELP_OF(cbsign[ 3], 0, 1), // 172 - QCELP_OF(cbgain[ 3], 1, 2), // 171 - QCELP_OF(cindex[ 4], 0, 6), // 169 - QCELP_OF(cbsign[ 4], 0, 1), // 163 - QCELP_OF(cbgain[ 4], 0, 4), // 162 - QCELP_OF(pfrac [ 1], 0, 1), // 158 - QCELP_OF(plag [ 1], 3, 4), // 157 - QCELP_OF(cbgain[ 6], 0, 3), // 153 - QCELP_OF(cindex[ 5], 0, 7), // 150 - QCELP_OF(cbsign[ 5], 0, 1), // 143 - QCELP_OF(cbgain[ 5], 0, 4), // 142 - QCELP_OF(cindex[ 4], 6, 1), // 138 - QCELP_OF(cindex[ 7], 0, 3), // 137 - QCELP_OF(cbsign[ 7], 0, 1), // 134 - QCELP_OF(cbgain[ 7], 0, 3), // 133 - QCELP_OF(cindex[ 6], 0, 7), // 130 - QCELP_OF(cbsign[ 6], 0, 1), // 123 - QCELP_OF(cbgain[ 6], 3, 1), // 122 - QCELP_OF(cbgain[ 8], 0, 1), // 121 - QCELP_OF(pfrac [ 2], 0, 1), // 120 - QCELP_OF(plag [ 2], 0, 7), // 119 - QCELP_OF(pgain [ 2], 0, 3), // 112 - QCELP_OF(cindex[ 7], 3, 4), // 109 - QCELP_OF(cbsign[ 9], 0, 1), // 105 - QCELP_OF(cbgain[ 9], 0, 4), // 104 - QCELP_OF(cindex[ 8], 0, 7), // 100 - QCELP_OF(cbsign[ 8], 0, 1), // 93 - QCELP_OF(cbgain[ 8], 1, 3), // 92 - QCELP_OF(cindex[10], 0, 4), // 89 - QCELP_OF(cbsign[10], 0, 1), // 85 - QCELP_OF(cbgain[10], 0, 4), // 84 - QCELP_OF(cindex[ 9], 0, 7), // 80 - QCELP_OF(pgain [ 3], 0, 2), // 73 - QCELP_OF(cindex[11], 0, 7), // 71 - QCELP_OF(cbsign[11], 0, 1), // 64 - QCELP_OF(cbgain[11], 0, 3), // 63 - QCELP_OF(cindex[10], 4, 3), // 60 - QCELP_OF(cindex[12], 0, 2), // 57 - QCELP_OF(cbsign[12], 0, 1), // 55 - QCELP_OF(cbgain[12], 0, 4), // 54 - QCELP_OF(pfrac [ 3], 0, 1), // 50 - QCELP_OF(plag [ 3], 0, 7), // 49 - QCELP_OF(pgain [ 3], 2, 1), // 42 - QCELP_OF(cindex[13], 0, 6), // 41 - QCELP_OF(cbsign[13], 0, 1), // 35 - QCELP_OF(cbgain[13], 0, 4), // 34 - QCELP_OF(cindex[12], 2, 5), // 30 - QCELP_OF(cbgain[15], 0, 3), // 25 - QCELP_OF(cindex[14], 0, 7), // 22 - QCELP_OF(cbsign[14], 0, 1), // 15 - QCELP_OF(cbgain[14], 0, 4), // 14 - QCELP_OF(cindex[13], 6, 1), // 10 - QCELP_OF(reserved, 0, 2), // 9 - QCELP_OF(cindex[15], 0, 7), // 7 - QCELP_OF(cbsign[15], 0, 1) // 0 -}; - -/** - * bitmap unpacking tables for RATE_HALF - * - * TIA/EIA/IS-733 Table 2.4.7.2-1 - */ -static const QCELPBitmap qcelp_rate_half_bitmap[] = { - // start on bit - QCELP_OF(lspv [2], 0, 3), // 123 - QCELP_OF(lspv [1], 0, 7), // 120 - QCELP_OF(lspv [0], 0, 6), // 113 - QCELP_OF(lspv [4], 0, 6), // 107 - QCELP_OF(lspv [3], 0, 6), // 101 - QCELP_OF(lspv [2], 3, 4), // 95 - QCELP_OF(cbsign[0], 0, 1), // 91 - QCELP_OF(cbgain[0], 0, 4), // 90 - QCELP_OF(pfrac [0], 0, 1), // 86 - QCELP_OF(plag [0], 0, 7), // 85 - QCELP_OF(pgain [0], 0, 3), // 78 - QCELP_OF(plag [1], 0, 6), // 75 - QCELP_OF(pgain [1], 0, 3), // 69 - QCELP_OF(cindex[0], 0, 7), // 66 - QCELP_OF(pgain [2], 0, 2), // 59 - QCELP_OF(cindex[1], 0, 7), // 57 - QCELP_OF(cbsign[1], 0, 1), // 50 - QCELP_OF(cbgain[1], 0, 4), // 49 - QCELP_OF(pfrac [1], 0, 1), // 45 - QCELP_OF(plag [1], 6, 1), // 44 - QCELP_OF(cindex[2], 0, 2), // 43 - QCELP_OF(cbsign[2], 0, 1), // 41 - QCELP_OF(cbgain[2], 0, 4), // 40 - QCELP_OF(pfrac [2], 0, 1), // 36 - QCELP_OF(plag [2], 0, 7), // 35 - QCELP_OF(pgain [2], 2, 1), // 28 - QCELP_OF(pfrac [3], 0, 1), // 27 - QCELP_OF(plag [3], 0, 7), // 26 - QCELP_OF(pgain [3], 0, 3), // 19 - QCELP_OF(cindex[2], 2, 5), // 16 - QCELP_OF(cindex[3], 0, 7), // 11 - QCELP_OF(cbsign[3], 0, 1), // 4 - QCELP_OF(cbgain[3], 0, 4) // 3 -}; - -/** - * bitmap unpacking tables for RATE_QUARTER - * - * TIA/EIA/IS-733 Table 2.4.7.3-1 - */ -static const QCELPBitmap qcelp_rate_quarter_bitmap[] = { - // start on bit - QCELP_OF(lspv [2], 0, 3), // 53 - QCELP_OF(lspv [1], 0, 7), // 50 - QCELP_OF(lspv [0], 0, 6), // 43 - QCELP_OF(lspv [4], 0, 6), // 37 - QCELP_OF(lspv [3], 0, 6), // 31 - QCELP_OF(lspv [2], 3, 4), // 25 - QCELP_OF(cbgain[3], 0, 4), // 21 - QCELP_OF(cbgain[2], 0, 4), // 17 - QCELP_OF(cbgain[1], 0, 4), // 13 - QCELP_OF(cbgain[0], 0, 4), // 9 - QCELP_OF(reserved, 0, 2), // 5 - QCELP_OF(cbgain[4], 0, 4) // 3 -}; - -/** - * bitmap unpacking tables for RATE_OCTAVE - * - * trick: CBSEED is written into QCELPContext.cbsign[15], - * which is not used for RATE_OCTAVE. - * CBSEED is only used to ensure the occurrence of random bit - * patterns in the 16 first bits that are used as the seed. - * - * TIA/EIA/IS-733 Table 2.4.7.4-1 - */ -static const QCELPBitmap qcelp_rate_octave_bitmap[] = { - // start on bit - QCELP_OF(cbsign[15], 3, 1), // 19 - QCELP_OF(lspv [0], 0, 1), // 18 - QCELP_OF(lspv [1], 0, 1), // 17 - QCELP_OF(lspv [2], 0, 1), // 16 - QCELP_OF(cbsign[15], 2, 1), // 15 - QCELP_OF(lspv [3], 0, 1), // 14 - QCELP_OF(lspv [4], 0, 1), // 13 - QCELP_OF(lspv [5], 0, 1), // 12 - QCELP_OF(cbsign[15], 1, 1), // 11 - QCELP_OF(lspv [6], 0, 1), // 10 - QCELP_OF(lspv [7], 0, 1), // 9 - QCELP_OF(lspv [8], 0, 1), // 8 - QCELP_OF(cbsign[15], 0, 1), // 7 - QCELP_OF(lspv [9], 0, 1), // 6 - QCELP_OF(cbgain [0], 0, 2), // 7 - QCELP_OF(reserved, 0, 4) // 3 -}; - -/** - * position of the bitmapping data for each packet type in - * the QCELPContext - */ -static const QCELPBitmap * const qcelp_unpacking_bitmaps_per_rate[5] = { - NULL, ///!< for SILENCE rate - qcelp_rate_octave_bitmap, - qcelp_rate_quarter_bitmap, - qcelp_rate_half_bitmap, - qcelp_rate_full_bitmap, -}; - -static const uint16_t qcelp_unpacking_bitmaps_lengths[5] = { - 0, ///!< for SILENCE rate - FF_ARRAY_ELEMS(qcelp_rate_octave_bitmap), - FF_ARRAY_ELEMS(qcelp_rate_quarter_bitmap), - FF_ARRAY_ELEMS(qcelp_rate_half_bitmap), - FF_ARRAY_ELEMS(qcelp_rate_full_bitmap), -}; - -typedef uint16_t qcelp_vector[2]; - -/** - * LSP vector quantization tables in x*10000 form - * - * TIA/EIA/IS-733 tables 2.4.3.2.6.3-1 through 2.4.3.2.6.3-5 - */ - -static const qcelp_vector qcelp_lspvq1[64]= { -{ 327, 118},{ 919, 111},{ 427, 440},{1327, 185}, -{ 469, 50},{1272, 91},{ 892, 59},{1771, 193}, -{ 222, 158},{1100, 127},{ 827, 55},{ 978, 791}, -{ 665, 47},{ 700,1401},{ 670, 859},{1913,1048}, -{ 471, 215},{1046, 125},{ 645, 298},{1599, 160}, -{ 593, 39},{1187, 462},{ 749, 341},{1520, 511}, -{ 290, 792},{ 909, 362},{ 753, 81},{1111,1058}, -{ 519, 253},{ 828, 839},{ 685, 541},{1421,1258}, -{ 386, 130},{ 962, 119},{ 542, 387},{1431, 185}, -{ 526, 51},{1175, 260},{ 831, 167},{1728, 510}, -{ 273, 437},{1172, 113},{ 771, 144},{1122, 751}, -{ 619, 119},{ 492,1276},{ 658, 695},{1882, 615}, -{ 415, 200},{1018, 88},{ 681, 339},{1436, 325}, -{ 555, 122},{1042, 485},{ 826, 345},{1374, 743}, -{ 383,1018},{1005, 358},{ 704, 86},{1301, 586}, -{ 597, 241},{ 832, 621},{ 555, 573},{1504, 839}}; - -static const qcelp_vector qcelp_lspvq2[128]= { -{ 255, 293},{ 904, 219},{ 151,1211},{1447, 498}, -{ 470, 253},{1559, 177},{1547, 994},{2394, 242}, -{ 91, 813},{ 857, 590},{ 934,1326},{1889, 282}, -{ 813, 472},{1057,1494},{ 450,3315},{2163,1895}, -{ 538, 532},{1399, 218},{ 146,1552},{1755, 626}, -{ 822, 202},{1299, 663},{ 706,1732},{2656, 401}, -{ 418, 745},{ 762,1038},{ 583,1748},{1746,1285}, -{ 527,1169},{1314, 830},{ 556,2116},{1073,2321}, -{ 297, 570},{ 981, 403},{ 468,1103},{1740, 243}, -{ 725, 179},{1255, 474},{1374,1362},{1922, 912}, -{ 285, 947},{ 930, 700},{ 593,1372},{1909, 576}, -{ 588, 916},{1110,1116},{ 224,2719},{1633,2220}, -{ 402, 520},{1061, 448},{ 402,1352},{1499, 775}, -{ 664, 589},{1081, 727},{ 801,2206},{2165,1157}, -{ 566, 802},{ 911,1116},{ 306,1703},{1792, 836}, -{ 655, 999},{1061,1038},{ 298,2089},{1110,1753}, -{ 361, 311},{ 970, 239},{ 265,1231},{1495, 573}, -{ 566, 262},{1569, 293},{1341,1144},{2271, 544}, -{ 214, 877},{ 847, 719},{ 794,1384},{2067, 274}, -{ 703, 688},{1099,1306},{ 391,2947},{2024,1670}, -{ 471, 525},{1245, 290},{ 264,1557},{1568, 807}, -{ 718, 399},{1193, 685},{ 883,1594},{2729, 764}, -{ 500, 754},{ 809,1108},{ 541,1648},{1523,1385}, -{ 614,1196},{1209, 847},{ 345,2242},{1442,1747}, -{ 199, 560},{1092, 194},{ 349,1253},{1653, 507}, -{ 625, 354},{1376, 431},{1187,1465},{2164, 872}, -{ 360, 974},{1008, 698},{ 704,1346},{2114, 452}, -{ 720, 816},{1240,1089},{ 439,2475},{1498,2040}, -{ 336, 718},{1213, 187},{ 451,1450},{1368, 885}, -{ 592, 578},{1131, 531},{ 861,1855},{1764,1500}, -{ 444, 970},{ 935, 903},{ 424,1687},{1633,1102}, -{ 793, 897},{1060, 897},{ 185,2011},{1205,1855}}; - -static const qcelp_vector qcelp_lspvq3[128]= { -{ 225, 283},{1296, 355},{ 543, 343},{2073, 274}, -{ 204,1099},{1562, 523},{1388, 161},{2784, 274}, -{ 112, 849},{1870, 175},{1189, 160},{1490,1088}, -{ 969,1115},{ 659,3322},{1158,1073},{3183,1363}, -{ 517, 223},{1740, 223},{ 704, 387},{2637, 234}, -{ 692,1005},{1287,1610},{ 952, 532},{2393, 646}, -{ 490, 552},{1619, 657},{ 845, 670},{1784,2280}, -{ 191,1775},{ 272,2868},{ 942, 952},{2628,1479}, -{ 278, 579},{1565, 218},{ 814, 180},{2379, 187}, -{ 276,1444},{1199,1223},{1200, 349},{3009, 307}, -{ 312, 844},{1898, 306},{ 863, 470},{1685,1241}, -{ 513,1727},{ 711,2233},{1085, 864},{3398, 527}, -{ 414, 440},{1356, 612},{ 964, 147},{2173, 738}, -{ 465,1292},{ 877,1749},{1104, 689},{2105,1311}, -{ 580, 864},{1895, 752},{ 652, 609},{1485,1699}, -{ 514,1400},{ 386,2131},{ 933, 798},{2473, 986}, -{ 334, 360},{1375, 398},{ 621, 276},{2183, 280}, -{ 311,1114},{1382, 807},{1284, 175},{2605, 636}, -{ 230, 816},{1739, 408},{1074, 176},{1619,1120}, -{ 784,1371},{ 448,3050},{1189, 880},{3039,1165}, -{ 424, 241},{1672, 186},{ 815, 333},{2432, 324}, -{ 584,1029},{1137,1546},{1015, 585},{2198, 995}, -{ 574, 581},{1746, 647},{ 733, 740},{1938,1737}, -{ 347,1710},{ 373,2429},{ 787,1061},{2439,1438}, -{ 185, 536},{1489, 178},{ 703, 216},{2178, 487}, -{ 154,1421},{1414, 994},{1103, 352},{3072, 473}, -{ 408, 819},{2055, 168},{ 998, 354},{1917,1140}, -{ 665,1799},{ 993,2213},{1234, 631},{3003, 762}, -{ 373, 620},{1518, 425},{ 913, 300},{1966, 836}, -{ 402,1185},{ 948,1385},{1121, 555},{1802,1509}, -{ 474, 886},{1888, 610},{ 739, 585},{1231,2379}, -{ 661,1335},{ 205,2211},{ 823, 822},{2480,1179}}; - -static const qcelp_vector qcelp_lspvq4[64]= { -{ 348, 311},{ 812,1145},{ 552, 461},{1826, 263}, -{ 601, 675},{1730, 172},{1523, 193},{2449, 277}, -{ 334, 668},{ 805,1441},{1319, 207},{1684, 910}, -{ 582,1318},{1403,1098},{ 979, 832},{2700,1359}, -{ 624, 228},{1292, 979},{ 800, 195},{2226, 285}, -{ 730, 862},{1537, 601},{1115, 509},{2720, 354}, -{ 218,1167},{1212,1538},{1074, 247},{1674,1710}, -{ 322,2142},{1263, 777},{ 981, 556},{2119,1710}, -{ 193, 596},{1035, 957},{ 694, 397},{1997, 253}, -{ 743, 603},{1584, 321},{1346, 346},{2221, 708}, -{ 451, 732},{1040,1415},{1184, 230},{1853, 919}, -{ 310,1661},{1625, 706},{ 856, 843},{2902, 702}, -{ 467, 348},{1108,1048},{ 859, 306},{1964, 463}, -{ 560,1013},{1425, 533},{1142, 634},{2391, 879}, -{ 397,1084},{1345,1700},{ 976, 248},{1887,1189}, -{ 644,2087},{1262, 603},{ 877, 550},{2203,1307}}; - -static const qcelp_vector qcelp_lspvq5[64]= { -{ 360, 222},{ 820,1097},{ 601, 319},{1656, 198}, -{ 604, 513},{1552, 141},{1391, 155},{2474, 261}, -{ 269, 785},{1463, 646},{1123, 191},{2015, 223}, -{ 785, 844},{1202,1011},{ 980, 807},{3014, 793}, -{ 570, 180},{1135,1382},{ 778, 256},{1901, 179}, -{ 807, 622},{1461, 458},{1231, 178},{2028, 821}, -{ 387, 927},{1496,1004},{ 888, 392},{2246, 341}, -{ 295,1462},{1156, 694},{1022, 473},{2226,1364}, -{ 210, 478},{1029,1020},{ 722, 181},{1730, 251}, -{ 730, 488},{1465, 293},{1303, 326},{2595, 387}, -{ 458, 584},{1569, 742},{1029, 173},{1910, 495}, -{ 605,1159},{1268, 719},{ 973, 646},{2872, 428}, -{ 443, 334},{ 835,1465},{ 912, 138},{1716, 442}, -{ 620, 778},{1316, 450},{1186, 335},{1446,1665}, -{ 486,1050},{1675,1019},{ 880, 278},{2214, 202}, -{ 539,1564},{1142, 533},{ 984, 391},{2130,1089}}; - -static const qcelp_vector * const qcelp_lspvq[5] = { - qcelp_lspvq1, - qcelp_lspvq2, - qcelp_lspvq3, - qcelp_lspvq4, - qcelp_lspvq5 -}; - -/** - * the final gain scalefactor before clipping into a usable output float - */ -#define QCELP_SCALE 8192. - -/** - * table for computing Ga (decoded linear codebook gain magnitude) - * - * @note The table could fit in int16_t in x*8 form, but it seems - * to be slower on x86 - * - * TIA/EIA/IS-733 2.4.6.2.1-3 - */ - -static const float qcelp_g12ga[61] = { - 1.000/QCELP_SCALE, 1.125/QCELP_SCALE, 1.250/QCELP_SCALE, 1.375/QCELP_SCALE, - 1.625/QCELP_SCALE, 1.750/QCELP_SCALE, 2.000/QCELP_SCALE, 2.250/QCELP_SCALE, - 2.500/QCELP_SCALE, 2.875/QCELP_SCALE, 3.125/QCELP_SCALE, 3.500/QCELP_SCALE, - 4.000/QCELP_SCALE, 4.500/QCELP_SCALE, 5.000/QCELP_SCALE, 5.625/QCELP_SCALE, - 6.250/QCELP_SCALE, 7.125/QCELP_SCALE, 8.000/QCELP_SCALE, 8.875/QCELP_SCALE, - 10.000/QCELP_SCALE, 11.250/QCELP_SCALE, 12.625/QCELP_SCALE, 14.125/QCELP_SCALE, - 15.875/QCELP_SCALE, 17.750/QCELP_SCALE, 20.000/QCELP_SCALE, 22.375/QCELP_SCALE, - 25.125/QCELP_SCALE, 28.125/QCELP_SCALE, 31.625/QCELP_SCALE, 35.500/QCELP_SCALE, - 39.750/QCELP_SCALE, 44.625/QCELP_SCALE, 50.125/QCELP_SCALE, 56.250/QCELP_SCALE, - 63.125/QCELP_SCALE, 70.750/QCELP_SCALE, 79.375/QCELP_SCALE, 89.125/QCELP_SCALE, - 100.000/QCELP_SCALE, 112.250/QCELP_SCALE, 125.875/QCELP_SCALE, 141.250/QCELP_SCALE, - 158.500/QCELP_SCALE, 177.875/QCELP_SCALE, 199.500/QCELP_SCALE, 223.875/QCELP_SCALE, - 251.250/QCELP_SCALE, 281.875/QCELP_SCALE, 316.250/QCELP_SCALE, 354.875/QCELP_SCALE, - 398.125/QCELP_SCALE, 446.625/QCELP_SCALE, 501.125/QCELP_SCALE, 562.375/QCELP_SCALE, - 631.000/QCELP_SCALE, 708.000/QCELP_SCALE, 794.375/QCELP_SCALE, 891.250/QCELP_SCALE, - 1000.000/QCELP_SCALE}; - -/** - * circular codebook for rate 1 frames in x*100 form - * - * TIA/EIA/IS-733 2.4.6.1-2 - */ -static const int16_t qcelp_rate_full_codebook[128] = { - 10, -65, -59, 12, 110, 34, -134, 157, - 104, -84, -34, -115, 23, -101, 3, 45, - -101, -16, -59, 28, -45, 134, -67, 22, - 61, -29, 226, -26, -55, -179, 157, -51, - -220, -93, -37, 60, 118, 74, -48, -95, - -181, 111, 36, -52, -215, 78, -112, 39, - -17, -47, -223, 19, 12, -98, -142, 130, - 54, -127, 21, -12, 39, -48, 12, 128, - 6, -167, 82, -102, -79, 55, -44, 48, - -20, -53, 8, -61, 11, -70, -157, -168, - 20, -56, -74, 78, 33, -63, -173, -2, - -75, -53, -146, 77, 66, -29, 9, -75, - 65, 119, -43, 76, 233, 98, 125, -156, - -27, 78, -9, 170, 176, 143, -148, -7, - 27, -136, 5, 27, 18, 139, 204, 7, - -184, -197, 52, -3, 78, -189, 8, -65 -}; -#define QCELP_RATE_FULL_CODEBOOK_RATIO .01 - -/** - * circular codebook for rate 1/2 frames in x*2 form - * - * TIA/EIA/IS-733 2.4.6.1-1 - */ -static const int8_t qcelp_rate_half_codebook[128] = { - 0, -4, 0, -3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, -3, -2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 0, 0, 4, 0, - 0, 3, 2, 0, 3, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 0, 0, - -3, 3, 0, 0, -2, 0, 3, 0, - 0, 0, 0, 0, 0, 0, -5, 0, - 0, 0, 0, 3, 0, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 4, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 6, -3, -4, 0, -3, -3, - 3, -3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; -#define QCELP_RATE_HALF_CODEBOOK_RATIO 0.5 - -/** - * sqrt(1.887) is the maximum of the pseudorandom - * white sequence used to generate the scaled codebook - * vector for bitrate 1/4. - * - * TIA/EIA/IS-733 2.4.8.1.2 - */ -#define QCELP_SQRT1887 1.373681186 - -/** - * table for impulse response of BPF used to filter - * the white excitation for bitrate 1/4 synthesis - * - * Only half the tables are needed because of symmetry. - * - * TIA/EIA/IS-733 2.4.8.1.2-1.1 - */ -static const double qcelp_rnd_fir_coefs[11] = { - -1.344519e-1, 1.735384e-2, -6.905826e-2, 2.434368e-2, - -8.210701e-2, 3.041388e-2, -9.251384e-2, 3.501983e-2, - -9.918777e-2, 3.749518e-2, 8.985137e-1 -}; - -/** - * This spread factor is used, for bitrate 1/8 and I_F_Q, - * to force the LSP frequencies to be at least 80 Hz apart. - * - * TIA/EIA/IS-733 2.4.3.3.2 - */ -#define QCELP_LSP_SPREAD_FACTOR 0.02 - -/** - * predictor coefficient for the conversion of LSP codes - * to LSP frequencies for 1/8 and I_F_Q - * - * TIA/EIA/IS-733 2.4.3.2.7-2 - */ -#define QCELP_LSP_OCTAVE_PREDICTOR 29.0/32 - -/** - * initial coefficient to perform bandwidth expansion on LPC - * - * @note: 0.9883 looks like an approximation of 253/256. - * - * TIA/EIA/IS-733 2.4.3.3.6 6 - */ -#define QCELP_BANDWIDTH_EXPANSION_COEFF 0.9883 - -#endif /* AVCODEC_QCELPDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/qcelpdec.c b/tizen/distrib/ffmpeg/libavcodec/qcelpdec.c deleted file mode 100644 index 97785ad..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qcelpdec.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * QCELP decoder - * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QCELP decoder - * @author Reynaldo H. Verdejo Pinochet - * @remark FFmpeg merging spearheaded by Kenan Gillet - * @remark Development mentored by Benjamin Larson - */ - -#include - -#include "avcodec.h" -#include "internal.h" -#include "get_bits.h" - -#include "qcelpdata.h" - -#include "celp_math.h" -#include "celp_filters.h" -#include "acelp_filters.h" -#include "acelp_vectors.h" -#include "lsp.h" - -#undef NDEBUG -#include - -typedef enum -{ - I_F_Q = -1, /*!< insufficient frame quality */ - SILENCE, - RATE_OCTAVE, - RATE_QUARTER, - RATE_HALF, - RATE_FULL -} qcelp_packet_rate; - -typedef struct -{ - GetBitContext gb; - qcelp_packet_rate bitrate; - QCELPFrame frame; /*!< unpacked data frame */ - - uint8_t erasure_count; - uint8_t octave_count; /*!< count the consecutive RATE_OCTAVE frames */ - float prev_lspf[10]; - float predictor_lspf[10];/*!< LSP predictor for RATE_OCTAVE and I_F_Q */ - float pitch_synthesis_filter_mem[303]; - float pitch_pre_filter_mem[303]; - float rnd_fir_filter_mem[180]; - float formant_mem[170]; - float last_codebook_gain; - int prev_g1[2]; - int prev_bitrate; - float pitch_gain[4]; - uint8_t pitch_lag[4]; - uint16_t first16bits; - uint8_t warned_buf_mismatch_bitrate; - - /* postfilter */ - float postfilter_synth_mem[10]; - float postfilter_agc_mem; - float postfilter_tilt_mem; -} QCELPContext; - -/** - * Initialize the speech codec according to the specification. - * - * TIA/EIA/IS-733 2.4.9 - */ -static av_cold int qcelp_decode_init(AVCodecContext *avctx) -{ - QCELPContext *q = avctx->priv_data; - int i; - - avctx->sample_fmt = SAMPLE_FMT_FLT; - - for(i=0; i<10; i++) - q->prev_lspf[i] = (i+1)/11.; - - return 0; -} - -/** - * Decodes the 10 quantized LSP frequencies from the LSPV/LSP - * transmission codes of any bitrate and checks for badly received packets. - * - * @param q the context - * @param lspf line spectral pair frequencies - * - * @return 0 on success, -1 if the packet is badly received - * - * TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3 - */ -static int decode_lspf(QCELPContext *q, float *lspf) -{ - int i; - float tmp_lspf, smooth, erasure_coeff; - const float *predictors; - - if(q->bitrate == RATE_OCTAVE || q->bitrate == I_F_Q) - { - predictors = (q->prev_bitrate != RATE_OCTAVE && - q->prev_bitrate != I_F_Q ? - q->prev_lspf : q->predictor_lspf); - - if(q->bitrate == RATE_OCTAVE) - { - q->octave_count++; - - for(i=0; i<10; i++) - { - q->predictor_lspf[i] = - lspf[i] = (q->frame.lspv[i] ? QCELP_LSP_SPREAD_FACTOR - : -QCELP_LSP_SPREAD_FACTOR) - + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR - + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11); - } - smooth = (q->octave_count < 10 ? .875 : 0.1); - }else - { - erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR; - - assert(q->bitrate == I_F_Q); - - if(q->erasure_count > 1) - erasure_coeff *= (q->erasure_count < 4 ? 0.9 : 0.7); - - for(i=0; i<10; i++) - { - q->predictor_lspf[i] = - lspf[i] = (i + 1) * ( 1 - erasure_coeff)/11 - + erasure_coeff * predictors[i]; - } - smooth = 0.125; - } - - // Check the stability of the LSP frequencies. - lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR); - for(i=1; i<10; i++) - lspf[i] = FFMAX(lspf[i], (lspf[i-1] + QCELP_LSP_SPREAD_FACTOR)); - - lspf[9] = FFMIN(lspf[9], (1.0 - QCELP_LSP_SPREAD_FACTOR)); - for(i=9; i>0; i--) - lspf[i-1] = FFMIN(lspf[i-1], (lspf[i] - QCELP_LSP_SPREAD_FACTOR)); - - // Low-pass filter the LSP frequencies. - ff_weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0-smooth, 10); - }else - { - q->octave_count = 0; - - tmp_lspf = 0.; - for(i=0; i<5 ; i++) - { - lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001; - lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001; - } - - // Check for badly received packets. - if(q->bitrate == RATE_QUARTER) - { - if(lspf[9] <= .70 || lspf[9] >= .97) - return -1; - for(i=3; i<10; i++) - if(fabs(lspf[i] - lspf[i-2]) < .08) - return -1; - }else - { - if(lspf[9] <= .66 || lspf[9] >= .985) - return -1; - for(i=4; i<10; i++) - if (fabs(lspf[i] - lspf[i-4]) < .0931) - return -1; - } - } - return 0; -} - -/** - * Converts codebook transmission codes to GAIN and INDEX. - * - * @param q the context - * @param gain array holding the decoded gain - * - * TIA/EIA/IS-733 2.4.6.2 - */ -static void decode_gain_and_index(QCELPContext *q, - float *gain) { - int i, subframes_count, g1[16]; - float slope; - - if(q->bitrate >= RATE_QUARTER) - { - switch(q->bitrate) - { - case RATE_FULL: subframes_count = 16; break; - case RATE_HALF: subframes_count = 4; break; - default: subframes_count = 5; - } - for(i=0; iframe.cbgain[i]; - if(q->bitrate == RATE_FULL && !((i+1) & 3)) - { - g1[i] += av_clip((g1[i-1] + g1[i-2] + g1[i-3]) / 3 - 6, 0, 32); - } - - gain[i] = qcelp_g12ga[g1[i]]; - - if(q->frame.cbsign[i]) - { - gain[i] = -gain[i]; - q->frame.cindex[i] = (q->frame.cindex[i]-89) & 127; - } - } - - q->prev_g1[0] = g1[i-2]; - q->prev_g1[1] = g1[i-1]; - q->last_codebook_gain = qcelp_g12ga[g1[i-1]]; - - if(q->bitrate == RATE_QUARTER) - { - // Provide smoothing of the unvoiced excitation energy. - gain[7] = gain[4]; - gain[6] = 0.4*gain[3] + 0.6*gain[4]; - gain[5] = gain[3]; - gain[4] = 0.8*gain[2] + 0.2*gain[3]; - gain[3] = 0.2*gain[1] + 0.8*gain[2]; - gain[2] = gain[1]; - gain[1] = 0.6*gain[0] + 0.4*gain[1]; - } - }else if (q->bitrate != SILENCE) - { - if(q->bitrate == RATE_OCTAVE) - { - g1[0] = 2 * q->frame.cbgain[0] - + av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54); - subframes_count = 8; - }else - { - assert(q->bitrate == I_F_Q); - - g1[0] = q->prev_g1[1]; - switch(q->erasure_count) - { - case 1 : break; - case 2 : g1[0] -= 1; break; - case 3 : g1[0] -= 2; break; - default: g1[0] -= 6; - } - if(g1[0] < 0) - g1[0] = 0; - subframes_count = 4; - } - // This interpolation is done to produce smoother background noise. - slope = 0.5*(qcelp_g12ga[g1[0]] - q->last_codebook_gain) / subframes_count; - for(i=1; i<=subframes_count; i++) - gain[i-1] = q->last_codebook_gain + slope * i; - - q->last_codebook_gain = gain[i-2]; - q->prev_g1[0] = q->prev_g1[1]; - q->prev_g1[1] = g1[0]; - } -} - -/** - * If the received packet is Rate 1/4 a further sanity check is made of the - * codebook gain. - * - * @param cbgain the unpacked cbgain array - * @return -1 if the sanity check fails, 0 otherwise - * - * TIA/EIA/IS-733 2.4.8.7.3 - */ -static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain) -{ - int i, diff, prev_diff=0; - - for(i=1; i<5; i++) - { - diff = cbgain[i] - cbgain[i-1]; - if(FFABS(diff) > 10) - return -1; - else if(FFABS(diff - prev_diff) > 12) - return -1; - prev_diff = diff; - } - return 0; -} - -/** - * Computes the scaled codebook vector Cdn From INDEX and GAIN - * for all rates. - * - * The specification lacks some information here. - * - * TIA/EIA/IS-733 has an omission on the codebook index determination - * formula for RATE_FULL and RATE_HALF frames at section 2.4.8.1.1. It says - * you have to subtract the decoded index parameter from the given scaled - * codebook vector index 'n' to get the desired circular codebook index, but - * it does not mention that you have to clamp 'n' to [0-9] in order to get - * RI-compliant results. - * - * The reason for this mistake seems to be the fact they forgot to mention you - * have to do these calculations per codebook subframe and adjust given - * equation values accordingly. - * - * @param q the context - * @param gain array holding the 4 pitch subframe gain values - * @param cdn_vector array for the generated scaled codebook vector - */ -static void compute_svector(QCELPContext *q, const float *gain, - float *cdn_vector) -{ - int i, j, k; - uint16_t cbseed, cindex; - float *rnd, tmp_gain, fir_filter_value; - - switch(q->bitrate) - { - case RATE_FULL: - for(i=0; i<16; i++) - { - tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; - cindex = -q->frame.cindex[i]; - for(j=0; j<10; j++) - *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127]; - } - break; - case RATE_HALF: - for(i=0; i<4; i++) - { - tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO; - cindex = -q->frame.cindex[i]; - for (j = 0; j < 40; j++) - *cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127]; - } - break; - case RATE_QUARTER: - cbseed = (0x0003 & q->frame.lspv[4])<<14 | - (0x003F & q->frame.lspv[3])<< 8 | - (0x0060 & q->frame.lspv[2])<< 1 | - (0x0007 & q->frame.lspv[1])<< 3 | - (0x0038 & q->frame.lspv[0])>> 3 ; - rnd = q->rnd_fir_filter_mem + 20; - for(i=0; i<8; i++) - { - tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); - for(k=0; k<20; k++) - { - cbseed = 521 * cbseed + 259; - *rnd = (int16_t)cbseed; - - // FIR filter - fir_filter_value = 0.0; - for(j=0; j<10; j++) - fir_filter_value += qcelp_rnd_fir_coefs[j ] - * (rnd[-j ] + rnd[-20+j]); - - fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10]; - *cdn_vector++ = tmp_gain * fir_filter_value; - rnd++; - } - } - memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160, 20 * sizeof(float)); - break; - case RATE_OCTAVE: - cbseed = q->first16bits; - for(i=0; i<8; i++) - { - tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); - for(j=0; j<20; j++) - { - cbseed = 521 * cbseed + 259; - *cdn_vector++ = tmp_gain * (int16_t)cbseed; - } - } - break; - case I_F_Q: - cbseed = -44; // random codebook index - for(i=0; i<4; i++) - { - tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; - for(j=0; j<40; j++) - *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cbseed++ & 127]; - } - break; - case SILENCE: - memset(cdn_vector, 0, 160 * sizeof(float)); - break; - } -} - -/** - * Apply generic gain control. - * - * @param v_out output vector - * @param v_in gain-controlled vector - * @param v_ref vector to control gain of - * - * TIA/EIA/IS-733 2.4.8.3, 2.4.8.6 - */ -static void apply_gain_ctrl(float *v_out, const float *v_ref, - const float *v_in) -{ - int i; - - for (i = 0; i < 160; i += 40) - ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i, - ff_dot_productf(v_ref + i, - v_ref + i, 40), - 40); -} - -/** - * Apply filter in pitch-subframe steps. - * - * @param memory buffer for the previous state of the filter - * - must be able to contain 303 elements - * - the 143 first elements are from the previous state - * - the next 160 are for output - * @param v_in input filter vector - * @param gain per-subframe gain array, each element is between 0.0 and 2.0 - * @param lag per-subframe lag array, each element is - * - between 16 and 143 if its corresponding pfrac is 0, - * - between 16 and 139 otherwise - * @param pfrac per-subframe boolean array, 1 if the lag is fractional, 0 - * otherwise - * - * @return filter output vector - */ -static const float *do_pitchfilter(float memory[303], const float v_in[160], - const float gain[4], const uint8_t *lag, - const uint8_t pfrac[4]) -{ - int i, j; - float *v_lag, *v_out; - const float *v_len; - - v_out = memory + 143; // Output vector starts at memory[143]. - - for(i=0; i<4; i++) - { - if(gain[i]) - { - v_lag = memory + 143 + 40 * i - lag[i]; - for(v_len=v_in+40; v_inbitrate >= RATE_HALF || - q->bitrate == SILENCE || - (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) - { - - if(q->bitrate >= RATE_HALF) - { - - // Compute gain & lag for the whole frame. - for(i=0; i<4; i++) - { - q->pitch_gain[i] = q->frame.plag[i] ? (q->frame.pgain[i] + 1) * 0.25 : 0.0; - - q->pitch_lag[i] = q->frame.plag[i] + 16; - } - }else - { - float max_pitch_gain; - - if (q->bitrate == I_F_Q) - { - if (q->erasure_count < 3) - max_pitch_gain = 0.9 - 0.3 * (q->erasure_count - 1); - else - max_pitch_gain = 0.0; - }else - { - assert(q->bitrate == SILENCE); - max_pitch_gain = 1.0; - } - for(i=0; i<4; i++) - q->pitch_gain[i] = FFMIN(q->pitch_gain[i], max_pitch_gain); - - memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac)); - } - - // pitch synthesis filter - v_synthesis_filtered = do_pitchfilter(q->pitch_synthesis_filter_mem, - cdn_vector, q->pitch_gain, - q->pitch_lag, q->frame.pfrac); - - // pitch prefilter update - for(i=0; i<4; i++) - q->pitch_gain[i] = 0.5 * FFMIN(q->pitch_gain[i], 1.0); - - v_pre_filtered = do_pitchfilter(q->pitch_pre_filter_mem, - v_synthesis_filtered, - q->pitch_gain, q->pitch_lag, - q->frame.pfrac); - - apply_gain_ctrl(cdn_vector, v_synthesis_filtered, v_pre_filtered); - }else - { - memcpy(q->pitch_synthesis_filter_mem, cdn_vector + 17, - 143 * sizeof(float)); - memcpy(q->pitch_pre_filter_mem, cdn_vector + 17, 143 * sizeof(float)); - memset(q->pitch_gain, 0, sizeof(q->pitch_gain)); - memset(q->pitch_lag, 0, sizeof(q->pitch_lag)); - } -} - -/** - * Reconstructs LPC coefficients from the line spectral pair frequencies - * and performs bandwidth expansion. - * - * @param lspf line spectral pair frequencies - * @param lpc linear predictive coding coefficients - * - * @note: bandwidth_expansion_coeff could be precalculated into a table - * but it seems to be slower on x86 - * - * TIA/EIA/IS-733 2.4.3.3.5 - */ -static void lspf2lpc(const float *lspf, float *lpc) -{ - double lsp[10]; - double bandwidth_expansion_coeff = QCELP_BANDWIDTH_EXPANSION_COEFF; - int i; - - for (i=0; i<10; i++) - lsp[i] = cos(M_PI * lspf[i]); - - ff_acelp_lspd2lpc(lsp, lpc, 5); - - for (i=0; i<10; i++) - { - lpc[i] *= bandwidth_expansion_coeff; - bandwidth_expansion_coeff *= QCELP_BANDWIDTH_EXPANSION_COEFF; - } -} - -/** - * Interpolates LSP frequencies and computes LPC coefficients - * for a given bitrate & pitch subframe. - * - * TIA/EIA/IS-733 2.4.3.3.4, 2.4.8.7.2 - * - * @param q the context - * @param curr_lspf LSP frequencies vector of the current frame - * @param lpc float vector for the resulting LPC - * @param subframe_num frame number in decoded stream - */ -static void interpolate_lpc(QCELPContext *q, const float *curr_lspf, - float *lpc, const int subframe_num) -{ - float interpolated_lspf[10]; - float weight; - - if(q->bitrate >= RATE_QUARTER) - weight = 0.25 * (subframe_num + 1); - else if(q->bitrate == RATE_OCTAVE && !subframe_num) - weight = 0.625; - else - weight = 1.0; - - if(weight != 1.0) - { - ff_weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf, - weight, 1.0 - weight, 10); - lspf2lpc(interpolated_lspf, lpc); - }else if(q->bitrate >= RATE_QUARTER || - (q->bitrate == I_F_Q && !subframe_num)) - lspf2lpc(curr_lspf, lpc); - else if(q->bitrate == SILENCE && !subframe_num) - lspf2lpc(q->prev_lspf, lpc); -} - -static qcelp_packet_rate buf_size2bitrate(const int buf_size) -{ - switch(buf_size) - { - case 35: return RATE_FULL; - case 17: return RATE_HALF; - case 8: return RATE_QUARTER; - case 4: return RATE_OCTAVE; - case 1: return SILENCE; - } - - return I_F_Q; -} - -/** - * Determine the bitrate from the frame size and/or the first byte of the frame. - * - * @param avctx the AV codec context - * @param buf_size length of the buffer - * @param buf the bufffer - * - * @return the bitrate on success, - * I_F_Q if the bitrate cannot be satisfactorily determined - * - * TIA/EIA/IS-733 2.4.8.7.1 - */ -static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx, const int buf_size, - const uint8_t **buf) -{ - qcelp_packet_rate bitrate; - - if((bitrate = buf_size2bitrate(buf_size)) >= 0) - { - if(bitrate > **buf) - { - QCELPContext *q = avctx->priv_data; - if (!q->warned_buf_mismatch_bitrate) - { - av_log(avctx, AV_LOG_WARNING, - "Claimed bitrate and buffer size mismatch.\n"); - q->warned_buf_mismatch_bitrate = 1; - } - bitrate = **buf; - }else if(bitrate < **buf) - { - av_log(avctx, AV_LOG_ERROR, - "Buffer is too small for the claimed bitrate.\n"); - return I_F_Q; - } - (*buf)++; - }else if((bitrate = buf_size2bitrate(buf_size + 1)) >= 0) - { - av_log(avctx, AV_LOG_WARNING, - "Bitrate byte is missing, guessing the bitrate from packet size.\n"); - }else - return I_F_Q; - - if(bitrate == SILENCE) - { - //FIXME: Remove experimental warning when tested with samples. - av_log_ask_for_sample(avctx, "'Blank frame handling is experimental."); - } - return bitrate; -} - -static void warn_insufficient_frame_quality(AVCodecContext *avctx, - const char *message) -{ - av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, - message); -} - -static void postfilter(QCELPContext *q, float *samples, float *lpc) -{ - static const float pow_0_775[10] = { - 0.775000, 0.600625, 0.465484, 0.360750, 0.279582, - 0.216676, 0.167924, 0.130141, 0.100859, 0.078166 - }, pow_0_625[10] = { - 0.625000, 0.390625, 0.244141, 0.152588, 0.095367, - 0.059605, 0.037253, 0.023283, 0.014552, 0.009095 - }; - float lpc_s[10], lpc_p[10], pole_out[170], zero_out[160]; - int n; - - for (n = 0; n < 10; n++) { - lpc_s[n] = lpc[n] * pow_0_625[n]; - lpc_p[n] = lpc[n] * pow_0_775[n]; - } - - ff_celp_lp_zero_synthesis_filterf(zero_out, lpc_s, - q->formant_mem + 10, 160, 10); - memcpy(pole_out, q->postfilter_synth_mem, sizeof(float) * 10); - ff_celp_lp_synthesis_filterf(pole_out + 10, lpc_p, zero_out, 160, 10); - memcpy(q->postfilter_synth_mem, pole_out + 160, sizeof(float) * 10); - - ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, pole_out + 10, 160); - - ff_adaptive_gain_control(samples, pole_out + 10, - ff_dot_productf(q->formant_mem + 10, q->formant_mem + 10, 160), - 160, 0.9375, &q->postfilter_agc_mem); -} - -static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - QCELPContext *q = avctx->priv_data; - float *outbuffer = data; - int i; - float quantized_lspf[10], lpc[10]; - float gain[16]; - float *formant_mem; - - if((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) - { - warn_insufficient_frame_quality(avctx, "bitrate cannot be determined."); - goto erasure; - } - - if(q->bitrate == RATE_OCTAVE && - (q->first16bits = AV_RB16(buf)) == 0xFFFF) - { - warn_insufficient_frame_quality(avctx, "Bitrate is 1/8 and first 16 bits are on."); - goto erasure; - } - - if(q->bitrate > SILENCE) - { - const QCELPBitmap *bitmaps = qcelp_unpacking_bitmaps_per_rate[q->bitrate]; - const QCELPBitmap *bitmaps_end = qcelp_unpacking_bitmaps_per_rate[q->bitrate] - + qcelp_unpacking_bitmaps_lengths[q->bitrate]; - uint8_t *unpacked_data = (uint8_t *)&q->frame; - - init_get_bits(&q->gb, buf, 8*buf_size); - - memset(&q->frame, 0, sizeof(QCELPFrame)); - - for(; bitmaps < bitmaps_end; bitmaps++) - unpacked_data[bitmaps->index] |= get_bits(&q->gb, bitmaps->bitlen) << bitmaps->bitpos; - - // Check for erasures/blanks on rates 1, 1/4 and 1/8. - if(q->frame.reserved) - { - warn_insufficient_frame_quality(avctx, "Wrong data in reserved frame area."); - goto erasure; - } - if(q->bitrate == RATE_QUARTER && - codebook_sanity_check_for_rate_quarter(q->frame.cbgain)) - { - warn_insufficient_frame_quality(avctx, "Codebook gain sanity check failed."); - goto erasure; - } - - if(q->bitrate >= RATE_HALF) - { - for(i=0; i<4; i++) - { - if(q->frame.pfrac[i] && q->frame.plag[i] >= 124) - { - warn_insufficient_frame_quality(avctx, "Cannot initialize pitch filter."); - goto erasure; - } - } - } - } - - decode_gain_and_index(q, gain); - compute_svector(q, gain, outbuffer); - - if(decode_lspf(q, quantized_lspf) < 0) - { - warn_insufficient_frame_quality(avctx, "Badly received packets in frame."); - goto erasure; - } - - - apply_pitch_filters(q, outbuffer); - - if(q->bitrate == I_F_Q) - { -erasure: - q->bitrate = I_F_Q; - q->erasure_count++; - decode_gain_and_index(q, gain); - compute_svector(q, gain, outbuffer); - decode_lspf(q, quantized_lspf); - apply_pitch_filters(q, outbuffer); - }else - q->erasure_count = 0; - - formant_mem = q->formant_mem + 10; - for(i=0; i<4; i++) - { - interpolate_lpc(q, quantized_lspf, lpc, i); - ff_celp_lp_synthesis_filterf(formant_mem, lpc, outbuffer + i * 40, 40, - 10); - formant_mem += 40; - } - - // postfilter, as per TIA/EIA/IS-733 2.4.8.6 - postfilter(q, outbuffer, lpc); - - memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float)); - - memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf)); - q->prev_bitrate = q->bitrate; - - *data_size = 160 * sizeof(*outbuffer); - - return *data_size; -} - -AVCodec qcelp_decoder = -{ - .name = "qcelp", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_QCELP, - .init = qcelp_decode_init, - .decode = qcelp_decode_frame, - .priv_data_size = sizeof(QCELPContext), - .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/qdm2.c b/tizen/distrib/ffmpeg/libavcodec/qdm2.c deleted file mode 100644 index 6451fbe..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qdm2.c +++ /dev/null @@ -1,1984 +0,0 @@ -/* - * QDM2 compatible decoder - * Copyright (c) 2003 Ewald Snel - * Copyright (c) 2005 Benjamin Larsson - * Copyright (c) 2005 Alex Beregszaszi - * Copyright (c) 2005 Roberto Togni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QDM2 decoder - * @author Ewald Snel, Benjamin Larsson, Alex Beregszaszi, Roberto Togni - * The decoder is not perfect yet, there are still some distortions - * especially on files encoded with 16 or 8 subbands. - */ - -#include -#include -#include - -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" -#include "mpegaudio.h" - -#include "qdm2data.h" -#include "qdm2_tablegen.h" - -#undef NDEBUG -#include - - -#define QDM2_LIST_ADD(list, size, packet) \ -do { \ - if (size > 0) { \ - list[size - 1].next = &list[size]; \ - } \ - list[size].packet = packet; \ - list[size].next = NULL; \ - size++; \ -} while(0) - -// Result is 8, 16 or 30 -#define QDM2_SB_USED(sub_sampling) (((sub_sampling) >= 2) ? 30 : 8 << (sub_sampling)) - -#define FIX_NOISE_IDX(noise_idx) \ - if ((noise_idx) >= 3840) \ - (noise_idx) -= 3840; \ - -#define SB_DITHERING_NOISE(sb,noise_idx) (noise_table[(noise_idx)++] * sb_noise_attenuation[(sb)]) - -#define BITS_LEFT(length,gb) ((length) - get_bits_count ((gb))) - -#define SAMPLES_NEEDED \ - av_log (NULL,AV_LOG_INFO,"This file triggers some untested code. Please contact the developers.\n"); - -#define SAMPLES_NEEDED_2(why) \ - av_log (NULL,AV_LOG_INFO,"This file triggers some missing code. Please contact the developers.\nPosition: %s\n",why); - - -typedef int8_t sb_int8_array[2][30][64]; - -/** - * Subpacket - */ -typedef struct { - int type; ///< subpacket type - unsigned int size; ///< subpacket size - const uint8_t *data; ///< pointer to subpacket data (points to input data buffer, it's not a private copy) -} QDM2SubPacket; - -/** - * A node in the subpacket list - */ -typedef struct QDM2SubPNode { - QDM2SubPacket *packet; ///< packet - struct QDM2SubPNode *next; ///< pointer to next packet in the list, NULL if leaf node -} QDM2SubPNode; - -typedef struct { - float re; - float im; -} QDM2Complex; - -typedef struct { - float level; - QDM2Complex *complex; - const float *table; - int phase; - int phase_shift; - int duration; - short time_index; - short cutoff; -} FFTTone; - -typedef struct { - int16_t sub_packet; - uint8_t channel; - int16_t offset; - int16_t exp; - uint8_t phase; -} FFTCoefficient; - -typedef struct { - DECLARE_ALIGNED(16, QDM2Complex, complex)[MPA_MAX_CHANNELS][256]; -} QDM2FFT; - -/** - * QDM2 decoder context - */ -typedef struct { - /// Parameters from codec header, do not change during playback - int nb_channels; ///< number of channels - int channels; ///< number of channels - int group_size; ///< size of frame group (16 frames per group) - int fft_size; ///< size of FFT, in complex numbers - int checksum_size; ///< size of data block, used also for checksum - - /// Parameters built from header parameters, do not change during playback - int group_order; ///< order of frame group - int fft_order; ///< order of FFT (actually fftorder+1) - int fft_frame_size; ///< size of fft frame, in components (1 comples = re + im) - int frame_size; ///< size of data frame - int frequency_range; - int sub_sampling; ///< subsampling: 0=25%, 1=50%, 2=100% */ - int coeff_per_sb_select; ///< selector for "num. of coeffs. per subband" tables. Can be 0, 1, 2 - int cm_table_select; ///< selector for "coding method" tables. Can be 0, 1 (from init: 0-4) - - /// Packets and packet lists - QDM2SubPacket sub_packets[16]; ///< the packets themselves - QDM2SubPNode sub_packet_list_A[16]; ///< list of all packets - QDM2SubPNode sub_packet_list_B[16]; ///< FFT packets B are on list - int sub_packets_B; ///< number of packets on 'B' list - QDM2SubPNode sub_packet_list_C[16]; ///< packets with errors? - QDM2SubPNode sub_packet_list_D[16]; ///< DCT packets - - /// FFT and tones - FFTTone fft_tones[1000]; - int fft_tone_start; - int fft_tone_end; - FFTCoefficient fft_coefs[1000]; - int fft_coefs_index; - int fft_coefs_min_index[5]; - int fft_coefs_max_index[5]; - int fft_level_exp[6]; - RDFTContext rdft_ctx; - QDM2FFT fft; - - /// I/O data - const uint8_t *compressed_data; - int compressed_size; - float output_buffer[1024]; - - /// Synthesis filter - DECLARE_ALIGNED(16, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512*2]; - int synth_buf_offset[MPA_MAX_CHANNELS]; - DECLARE_ALIGNED(16, int32_t, sb_samples)[MPA_MAX_CHANNELS][128][SBLIMIT]; - - /// Mixed temporary data used in decoding - float tone_level[MPA_MAX_CHANNELS][30][64]; - int8_t coding_method[MPA_MAX_CHANNELS][30][64]; - int8_t quantized_coeffs[MPA_MAX_CHANNELS][10][8]; - int8_t tone_level_idx_base[MPA_MAX_CHANNELS][30][8]; - int8_t tone_level_idx_hi1[MPA_MAX_CHANNELS][3][8][8]; - int8_t tone_level_idx_mid[MPA_MAX_CHANNELS][26][8]; - int8_t tone_level_idx_hi2[MPA_MAX_CHANNELS][26]; - int8_t tone_level_idx[MPA_MAX_CHANNELS][30][64]; - int8_t tone_level_idx_temp[MPA_MAX_CHANNELS][30][64]; - - // Flags - int has_errors; ///< packet has errors - int superblocktype_2_3; ///< select fft tables and some algorithm based on superblock type - int do_synth_filter; ///< used to perform or skip synthesis filter - - int sub_packet; - int noise_idx; ///< index for dithering noise table -} QDM2Context; - - -static uint8_t empty_buffer[FF_INPUT_BUFFER_PADDING_SIZE]; - -static VLC vlc_tab_level; -static VLC vlc_tab_diff; -static VLC vlc_tab_run; -static VLC fft_level_exp_alt_vlc; -static VLC fft_level_exp_vlc; -static VLC fft_stereo_exp_vlc; -static VLC fft_stereo_phase_vlc; -static VLC vlc_tab_tone_level_idx_hi1; -static VLC vlc_tab_tone_level_idx_mid; -static VLC vlc_tab_tone_level_idx_hi2; -static VLC vlc_tab_type30; -static VLC vlc_tab_type34; -static VLC vlc_tab_fft_tone_offset[5]; - -static const uint16_t qdm2_vlc_offs[] = { - 0,260,566,598,894,1166,1230,1294,1678,1950,2214,2278,2310,2570,2834,3124,3448,3838, -}; - -static av_cold void qdm2_init_vlc(void) -{ - static int vlcs_initialized = 0; - static VLC_TYPE qdm2_table[3838][2]; - - if (!vlcs_initialized) { - - vlc_tab_level.table = &qdm2_table[qdm2_vlc_offs[0]]; - vlc_tab_level.table_allocated = qdm2_vlc_offs[1] - qdm2_vlc_offs[0]; - init_vlc (&vlc_tab_level, 8, 24, - vlc_tab_level_huffbits, 1, 1, - vlc_tab_level_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_diff.table = &qdm2_table[qdm2_vlc_offs[1]]; - vlc_tab_diff.table_allocated = qdm2_vlc_offs[2] - qdm2_vlc_offs[1]; - init_vlc (&vlc_tab_diff, 8, 37, - vlc_tab_diff_huffbits, 1, 1, - vlc_tab_diff_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_run.table = &qdm2_table[qdm2_vlc_offs[2]]; - vlc_tab_run.table_allocated = qdm2_vlc_offs[3] - qdm2_vlc_offs[2]; - init_vlc (&vlc_tab_run, 5, 6, - vlc_tab_run_huffbits, 1, 1, - vlc_tab_run_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - fft_level_exp_alt_vlc.table = &qdm2_table[qdm2_vlc_offs[3]]; - fft_level_exp_alt_vlc.table_allocated = qdm2_vlc_offs[4] - qdm2_vlc_offs[3]; - init_vlc (&fft_level_exp_alt_vlc, 8, 28, - fft_level_exp_alt_huffbits, 1, 1, - fft_level_exp_alt_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - - fft_level_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[4]]; - fft_level_exp_vlc.table_allocated = qdm2_vlc_offs[5] - qdm2_vlc_offs[4]; - init_vlc (&fft_level_exp_vlc, 8, 20, - fft_level_exp_huffbits, 1, 1, - fft_level_exp_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - fft_stereo_exp_vlc.table = &qdm2_table[qdm2_vlc_offs[5]]; - fft_stereo_exp_vlc.table_allocated = qdm2_vlc_offs[6] - qdm2_vlc_offs[5]; - init_vlc (&fft_stereo_exp_vlc, 6, 7, - fft_stereo_exp_huffbits, 1, 1, - fft_stereo_exp_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - fft_stereo_phase_vlc.table = &qdm2_table[qdm2_vlc_offs[6]]; - fft_stereo_phase_vlc.table_allocated = qdm2_vlc_offs[7] - qdm2_vlc_offs[6]; - init_vlc (&fft_stereo_phase_vlc, 6, 9, - fft_stereo_phase_huffbits, 1, 1, - fft_stereo_phase_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_tone_level_idx_hi1.table = &qdm2_table[qdm2_vlc_offs[7]]; - vlc_tab_tone_level_idx_hi1.table_allocated = qdm2_vlc_offs[8] - qdm2_vlc_offs[7]; - init_vlc (&vlc_tab_tone_level_idx_hi1, 8, 20, - vlc_tab_tone_level_idx_hi1_huffbits, 1, 1, - vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_tone_level_idx_mid.table = &qdm2_table[qdm2_vlc_offs[8]]; - vlc_tab_tone_level_idx_mid.table_allocated = qdm2_vlc_offs[9] - qdm2_vlc_offs[8]; - init_vlc (&vlc_tab_tone_level_idx_mid, 8, 24, - vlc_tab_tone_level_idx_mid_huffbits, 1, 1, - vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_tone_level_idx_hi2.table = &qdm2_table[qdm2_vlc_offs[9]]; - vlc_tab_tone_level_idx_hi2.table_allocated = qdm2_vlc_offs[10] - qdm2_vlc_offs[9]; - init_vlc (&vlc_tab_tone_level_idx_hi2, 8, 24, - vlc_tab_tone_level_idx_hi2_huffbits, 1, 1, - vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_type30.table = &qdm2_table[qdm2_vlc_offs[10]]; - vlc_tab_type30.table_allocated = qdm2_vlc_offs[11] - qdm2_vlc_offs[10]; - init_vlc (&vlc_tab_type30, 6, 9, - vlc_tab_type30_huffbits, 1, 1, - vlc_tab_type30_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_type34.table = &qdm2_table[qdm2_vlc_offs[11]]; - vlc_tab_type34.table_allocated = qdm2_vlc_offs[12] - qdm2_vlc_offs[11]; - init_vlc (&vlc_tab_type34, 5, 10, - vlc_tab_type34_huffbits, 1, 1, - vlc_tab_type34_huffcodes, 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[0].table = &qdm2_table[qdm2_vlc_offs[12]]; - vlc_tab_fft_tone_offset[0].table_allocated = qdm2_vlc_offs[13] - qdm2_vlc_offs[12]; - init_vlc (&vlc_tab_fft_tone_offset[0], 8, 23, - vlc_tab_fft_tone_offset_0_huffbits, 1, 1, - vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[1].table = &qdm2_table[qdm2_vlc_offs[13]]; - vlc_tab_fft_tone_offset[1].table_allocated = qdm2_vlc_offs[14] - qdm2_vlc_offs[13]; - init_vlc (&vlc_tab_fft_tone_offset[1], 8, 28, - vlc_tab_fft_tone_offset_1_huffbits, 1, 1, - vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[2].table = &qdm2_table[qdm2_vlc_offs[14]]; - vlc_tab_fft_tone_offset[2].table_allocated = qdm2_vlc_offs[15] - qdm2_vlc_offs[14]; - init_vlc (&vlc_tab_fft_tone_offset[2], 8, 32, - vlc_tab_fft_tone_offset_2_huffbits, 1, 1, - vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[3].table = &qdm2_table[qdm2_vlc_offs[15]]; - vlc_tab_fft_tone_offset[3].table_allocated = qdm2_vlc_offs[16] - qdm2_vlc_offs[15]; - init_vlc (&vlc_tab_fft_tone_offset[3], 8, 35, - vlc_tab_fft_tone_offset_3_huffbits, 1, 1, - vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlc_tab_fft_tone_offset[4].table = &qdm2_table[qdm2_vlc_offs[16]]; - vlc_tab_fft_tone_offset[4].table_allocated = qdm2_vlc_offs[17] - qdm2_vlc_offs[16]; - init_vlc (&vlc_tab_fft_tone_offset[4], 8, 38, - vlc_tab_fft_tone_offset_4_huffbits, 1, 1, - vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); - - vlcs_initialized=1; - } -} - - -/* for floating point to fixed point conversion */ -static const float f2i_scale = (float) (1 << (FRAC_BITS - 15)); - - -static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth) -{ - int value; - - value = get_vlc2(gb, vlc->table, vlc->bits, depth); - - /* stage-2, 3 bits exponent escape sequence */ - if (value-- == 0) - value = get_bits (gb, get_bits (gb, 3) + 1); - - /* stage-3, optional */ - if (flag) { - int tmp = vlc_stage3_values[value]; - - if ((value & ~3) > 0) - tmp += get_bits (gb, (value >> 2)); - value = tmp; - } - - return value; -} - - -static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) -{ - int value = qdm2_get_vlc (gb, vlc, 0, depth); - - return (value & 1) ? ((value + 1) >> 1) : -(value >> 1); -} - - -/** - * QDM2 checksum - * - * @param data pointer to data to be checksum'ed - * @param length data length - * @param value checksum value - * - * @return 0 if checksum is OK - */ -static uint16_t qdm2_packet_checksum (const uint8_t *data, int length, int value) { - int i; - - for (i=0; i < length; i++) - value -= data[i]; - - return (uint16_t)(value & 0xffff); -} - - -/** - * Fills a QDM2SubPacket structure with packet type, size, and data pointer. - * - * @param gb bitreader context - * @param sub_packet packet under analysis - */ -static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub_packet) -{ - sub_packet->type = get_bits (gb, 8); - - if (sub_packet->type == 0) { - sub_packet->size = 0; - sub_packet->data = NULL; - } else { - sub_packet->size = get_bits (gb, 8); - - if (sub_packet->type & 0x80) { - sub_packet->size <<= 8; - sub_packet->size |= get_bits (gb, 8); - sub_packet->type &= 0x7f; - } - - if (sub_packet->type == 0x7f) - sub_packet->type |= (get_bits (gb, 8) << 8); - - sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; // FIXME: this depends on bitreader internal data - } - - av_log(NULL,AV_LOG_DEBUG,"Subpacket: type=%d size=%d start_offs=%x\n", - sub_packet->type, sub_packet->size, get_bits_count(gb) / 8); -} - - -/** - * Return node pointer to first packet of requested type in list. - * - * @param list list of subpackets to be scanned - * @param type type of searched subpacket - * @return node pointer for subpacket if found, else NULL - */ -static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int type) -{ - while (list != NULL && list->packet != NULL) { - if (list->packet->type == type) - return list; - list = list->next; - } - return NULL; -} - - -/** - * Replaces 8 elements with their average value. - * Called by qdm2_decode_superblock before starting subblock decoding. - * - * @param q context - */ -static void average_quantized_coeffs (QDM2Context *q) -{ - int i, j, n, ch, sum; - - n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; - - for (ch = 0; ch < q->nb_channels; ch++) - for (i = 0; i < n; i++) { - sum = 0; - - for (j = 0; j < 8; j++) - sum += q->quantized_coeffs[ch][i][j]; - - sum /= 8; - if (sum > 0) - sum--; - - for (j=0; j < 8; j++) - q->quantized_coeffs[ch][i][j] = sum; - } -} - - -/** - * Build subband samples with noise weighted by q->tone_level. - * Called by synthfilt_build_sb_samples. - * - * @param q context - * @param sb subband index - */ -static void build_sb_samples_from_noise (QDM2Context *q, int sb) -{ - int ch, j; - - FIX_NOISE_IDX(q->noise_idx); - - if (!q->nb_channels) - return; - - for (ch = 0; ch < q->nb_channels; ch++) - for (j = 0; j < 64; j++) { - q->sb_samples[ch][j * 2][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5); - q->sb_samples[ch][j * 2 + 1][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5); - } -} - - -/** - * Called while processing data from subpackets 11 and 12. - * Used after making changes to coding_method array. - * - * @param sb subband index - * @param channels number of channels - * @param coding_method q->coding_method[0][0][0] - */ -static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method) -{ - int j,k; - int ch; - int run, case_val; - int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4}; - - for (ch = 0; ch < channels; ch++) { - for (j = 0; j < 64; ) { - if((coding_method[ch][sb][j] - 8) > 22) { - run = 1; - case_val = 8; - } else { - switch (switchtable[coding_method[ch][sb][j]-8]) { - case 0: run = 10; case_val = 10; break; - case 1: run = 1; case_val = 16; break; - case 2: run = 5; case_val = 24; break; - case 3: run = 3; case_val = 30; break; - case 4: run = 1; case_val = 30; break; - case 5: run = 1; case_val = 8; break; - default: run = 1; case_val = 8; break; - } - } - for (k = 0; k < run; k++) - if (j + k < 128) - if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j]) - if (k > 0) { - SAMPLES_NEEDED - //not debugged, almost never used - memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t)); - memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t)); - } - j += run; - } - } -} - - -/** - * Related to synthesis filter - * Called by process_subpacket_10 - * - * @param q context - * @param flag 1 if called after getting data from subpacket 10, 0 if no subpacket 10 - */ -static void fill_tone_level_array (QDM2Context *q, int flag) -{ - int i, sb, ch, sb_used; - int tmp, tab; - - // This should never happen - if (q->nb_channels <= 0) - return; - - for (ch = 0; ch < q->nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (i = 0; i < 8; i++) { - if ((tab=coeff_per_sb_for_dequant[q->coeff_per_sb_select][sb]) < (last_coeff[q->coeff_per_sb_select] - 1)) - tmp = q->quantized_coeffs[ch][tab + 1][i] * dequant_table[q->coeff_per_sb_select][tab + 1][sb]+ - q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb]; - else - tmp = q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb]; - if(tmp < 0) - tmp += 0xff; - q->tone_level_idx_base[ch][sb][i] = (tmp / 256) & 0xff; - } - - sb_used = QDM2_SB_USED(q->sub_sampling); - - if ((q->superblocktype_2_3 != 0) && !flag) { - for (sb = 0; sb < sb_used; sb++) - for (ch = 0; ch < q->nb_channels; ch++) - for (i = 0; i < 64; i++) { - q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8]; - if (q->tone_level_idx[ch][sb][i] < 0) - q->tone_level[ch][sb][i] = 0; - else - q->tone_level[ch][sb][i] = fft_tone_level_table[0][q->tone_level_idx[ch][sb][i] & 0x3f]; - } - } else { - tab = q->superblocktype_2_3 ? 0 : 1; - for (sb = 0; sb < sb_used; sb++) { - if ((sb >= 4) && (sb <= 23)) { - for (ch = 0; ch < q->nb_channels; ch++) - for (i = 0; i < 64; i++) { - tmp = q->tone_level_idx_base[ch][sb][i / 8] - - q->tone_level_idx_hi1[ch][sb / 8][i / 8][i % 8] - - q->tone_level_idx_mid[ch][sb - 4][i / 8] - - q->tone_level_idx_hi2[ch][sb - 4]; - q->tone_level_idx[ch][sb][i] = tmp & 0xff; - if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) - q->tone_level[ch][sb][i] = 0; - else - q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; - } - } else { - if (sb > 4) { - for (ch = 0; ch < q->nb_channels; ch++) - for (i = 0; i < 64; i++) { - tmp = q->tone_level_idx_base[ch][sb][i / 8] - - q->tone_level_idx_hi1[ch][2][i / 8][i % 8] - - q->tone_level_idx_hi2[ch][sb - 4]; - q->tone_level_idx[ch][sb][i] = tmp & 0xff; - if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) - q->tone_level[ch][sb][i] = 0; - else - q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; - } - } else { - for (ch = 0; ch < q->nb_channels; ch++) - for (i = 0; i < 64; i++) { - tmp = q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8]; - if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp)) - q->tone_level[ch][sb][i] = 0; - else - q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f]; - } - } - } - } - } - - return; -} - - -/** - * Related to synthesis filter - * Called by process_subpacket_11 - * c is built with data from subpacket 11 - * Most of this function is used only if superblock_type_2_3 == 0, never seen it in samples - * - * @param tone_level_idx - * @param tone_level_idx_temp - * @param coding_method q->coding_method[0][0][0] - * @param nb_channels number of channels - * @param c coming from subpacket 11, passed as 8*c - * @param superblocktype_2_3 flag based on superblock packet type - * @param cm_table_select q->cm_table_select - */ -static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_array tone_level_idx_temp, - sb_int8_array coding_method, int nb_channels, - int c, int superblocktype_2_3, int cm_table_select) -{ - int ch, sb, j; - int tmp, acc, esp_40, comp; - int add1, add2, add3, add4; - int64_t multres; - - // This should never happen - if (nb_channels <= 0) - return; - - if (!superblocktype_2_3) { - /* This case is untested, no samples available */ - SAMPLES_NEEDED - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) { - for (j = 1; j < 63; j++) { // The loop only iterates to 63 so the code doesn't overflow the buffer - add1 = tone_level_idx[ch][sb][j] - 10; - if (add1 < 0) - add1 = 0; - add2 = add3 = add4 = 0; - if (sb > 1) { - add2 = tone_level_idx[ch][sb - 2][j] + tone_level_idx_offset_table[sb][0] - 6; - if (add2 < 0) - add2 = 0; - } - if (sb > 0) { - add3 = tone_level_idx[ch][sb - 1][j] + tone_level_idx_offset_table[sb][1] - 6; - if (add3 < 0) - add3 = 0; - } - if (sb < 29) { - add4 = tone_level_idx[ch][sb + 1][j] + tone_level_idx_offset_table[sb][3] - 6; - if (add4 < 0) - add4 = 0; - } - tmp = tone_level_idx[ch][sb][j + 1] * 2 - add4 - add3 - add2 - add1; - if (tmp < 0) - tmp = 0; - tone_level_idx_temp[ch][sb][j + 1] = tmp & 0xff; - } - tone_level_idx_temp[ch][sb][0] = tone_level_idx_temp[ch][sb][1]; - } - acc = 0; - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) - acc += tone_level_idx_temp[ch][sb][j]; - - multres = 0x66666667 * (acc * 10); - esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31); - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) { - comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10; - if (comp < 0) - comp += 0xff; - comp /= 256; // signed shift - switch(sb) { - case 0: - if (comp < 30) - comp = 30; - comp += 15; - break; - case 1: - if (comp < 24) - comp = 24; - comp += 10; - break; - case 2: - case 3: - case 4: - if (comp < 16) - comp = 16; - } - if (comp <= 5) - tmp = 0; - else if (comp <= 10) - tmp = 10; - else if (comp <= 16) - tmp = 16; - else if (comp <= 24) - tmp = -1; - else - tmp = 0; - coding_method[ch][sb][j] = ((tmp & 0xfffa) + 30 )& 0xff; - } - for (sb = 0; sb < 30; sb++) - fix_coding_method_array(sb, nb_channels, coding_method); - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) - if (sb >= 10) { - if (coding_method[ch][sb][j] < 10) - coding_method[ch][sb][j] = 10; - } else { - if (sb >= 2) { - if (coding_method[ch][sb][j] < 16) - coding_method[ch][sb][j] = 16; - } else { - if (coding_method[ch][sb][j] < 30) - coding_method[ch][sb][j] = 30; - } - } - } else { // superblocktype_2_3 != 0 - for (ch = 0; ch < nb_channels; ch++) - for (sb = 0; sb < 30; sb++) - for (j = 0; j < 64; j++) - coding_method[ch][sb][j] = coding_method_table[cm_table_select][sb]; - } - - return; -} - - -/** - * - * Called by process_subpacket_11 to process more data from subpacket 11 with sb 0-8 - * Called by process_subpacket_12 to process data from subpacket 12 with sb 8-sb_used - * - * @param q context - * @param gb bitreader context - * @param length packet length in bits - * @param sb_min lower subband processed (sb_min included) - * @param sb_max higher subband processed (sb_max excluded) - */ -static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max) -{ - int sb, j, k, n, ch, run, channels; - int joined_stereo, zero_encoding, chs; - int type34_first; - float type34_div = 0; - float type34_predictor; - float samples[10], sign_bits[16]; - - if (length == 0) { - // If no data use noise - for (sb=sb_min; sb < sb_max; sb++) - build_sb_samples_from_noise (q, sb); - - return; - } - - for (sb = sb_min; sb < sb_max; sb++) { - FIX_NOISE_IDX(q->noise_idx); - - channels = q->nb_channels; - - if (q->nb_channels <= 1 || sb < 12) - joined_stereo = 0; - else if (sb >= 24) - joined_stereo = 1; - else - joined_stereo = (BITS_LEFT(length,gb) >= 1) ? get_bits1 (gb) : 0; - - if (joined_stereo) { - if (BITS_LEFT(length,gb) >= 16) - for (j = 0; j < 16; j++) - sign_bits[j] = get_bits1 (gb); - - for (j = 0; j < 64; j++) - if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j]) - q->coding_method[0][sb][j] = q->coding_method[1][sb][j]; - - fix_coding_method_array(sb, q->nb_channels, q->coding_method); - channels = 1; - } - - for (ch = 0; ch < channels; ch++) { - zero_encoding = (BITS_LEFT(length,gb) >= 1) ? get_bits1(gb) : 0; - type34_predictor = 0.0; - type34_first = 1; - - for (j = 0; j < 128; ) { - switch (q->coding_method[ch][sb][j / 2]) { - case 8: - if (BITS_LEFT(length,gb) >= 10) { - if (zero_encoding) { - for (k = 0; k < 5; k++) { - if ((j + 2 * k) >= 128) - break; - samples[2 * k] = get_bits1(gb) ? dequant_1bit[joined_stereo][2 * get_bits1(gb)] : 0; - } - } else { - n = get_bits(gb, 8); - for (k = 0; k < 5; k++) - samples[2 * k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; - } - for (k = 0; k < 5; k++) - samples[2 * k + 1] = SB_DITHERING_NOISE(sb,q->noise_idx); - } else { - for (k = 0; k < 10; k++) - samples[k] = SB_DITHERING_NOISE(sb,q->noise_idx); - } - run = 10; - break; - - case 10: - if (BITS_LEFT(length,gb) >= 1) { - float f = 0.81; - - if (get_bits1(gb)) - f = -f; - f -= noise_samples[((sb + 1) * (j +5 * ch + 1)) & 127] * 9.0 / 40.0; - samples[0] = f; - } else { - samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); - } - run = 1; - break; - - case 16: - if (BITS_LEFT(length,gb) >= 10) { - if (zero_encoding) { - for (k = 0; k < 5; k++) { - if ((j + k) >= 128) - break; - samples[k] = (get_bits1(gb) == 0) ? 0 : dequant_1bit[joined_stereo][2 * get_bits1(gb)]; - } - } else { - n = get_bits (gb, 8); - for (k = 0; k < 5; k++) - samples[k] = dequant_1bit[joined_stereo][random_dequant_index[n][k]]; - } - } else { - for (k = 0; k < 5; k++) - samples[k] = SB_DITHERING_NOISE(sb,q->noise_idx); - } - run = 5; - break; - - case 24: - if (BITS_LEFT(length,gb) >= 7) { - n = get_bits(gb, 7); - for (k = 0; k < 3; k++) - samples[k] = (random_dequant_type24[n][k] - 2.0) * 0.5; - } else { - for (k = 0; k < 3; k++) - samples[k] = SB_DITHERING_NOISE(sb,q->noise_idx); - } - run = 3; - break; - - case 30: - if (BITS_LEFT(length,gb) >= 4) - samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1)]; - else - samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); - - run = 1; - break; - - case 34: - if (BITS_LEFT(length,gb) >= 7) { - if (type34_first) { - type34_div = (float)(1 << get_bits(gb, 2)); - samples[0] = ((float)get_bits(gb, 5) - 16.0) / 15.0; - type34_predictor = samples[0]; - type34_first = 0; - } else { - samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1)] / type34_div + type34_predictor; - type34_predictor = samples[0]; - } - } else { - samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); - } - run = 1; - break; - - default: - samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); - run = 1; - break; - } - - if (joined_stereo) { - float tmp[10][MPA_MAX_CHANNELS]; - - for (k = 0; k < run; k++) { - tmp[k][0] = samples[k]; - tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k]; - } - for (chs = 0; chs < q->nb_channels; chs++) - for (k = 0; k < run; k++) - if ((j + k) < 128) - q->sb_samples[chs][j + k][sb] = (int32_t)(f2i_scale * q->tone_level[chs][sb][((j + k)/2)] * tmp[k][chs] + .5); - } else { - for (k = 0; k < run; k++) - if ((j + k) < 128) - q->sb_samples[ch][j + k][sb] = (int32_t)(f2i_scale * q->tone_level[ch][sb][(j + k)/2] * samples[k] + .5); - } - - j += run; - } // j loop - } // channel loop - } // subband loop -} - - -/** - * Init the first element of a channel in quantized_coeffs with data from packet 10 (quantized_coeffs[ch][0]). - * This is similar to process_subpacket_9, but for a single channel and for element [0] - * same VLC tables as process_subpacket_9 are used. - * - * @param q context - * @param quantized_coeffs pointer to quantized_coeffs[ch][0] - * @param gb bitreader context - * @param length packet length in bits - */ -static void init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb, int length) -{ - int i, k, run, level, diff; - - if (BITS_LEFT(length,gb) < 16) - return; - level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2); - - quantized_coeffs[0] = level; - - for (i = 0; i < 7; ) { - if (BITS_LEFT(length,gb) < 16) - break; - run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1) + 1; - - if (BITS_LEFT(length,gb) < 16) - break; - diff = qdm2_get_se_vlc(&vlc_tab_diff, gb, 2); - - for (k = 1; k <= run; k++) - quantized_coeffs[i + k] = (level + ((k * diff) / run)); - - level += diff; - i += run; - } -} - - -/** - * Related to synthesis filter, process data from packet 10 - * Init part of quantized_coeffs via function init_quantized_coeffs_elem0 - * Init tone_level_idx_hi1, tone_level_idx_hi2, tone_level_idx_mid with data from packet 10 - * - * @param q context - * @param gb bitreader context - * @param length packet length in bits - */ -static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb, int length) -{ - int sb, j, k, n, ch; - - for (ch = 0; ch < q->nb_channels; ch++) { - init_quantized_coeffs_elem0(q->quantized_coeffs[ch][0], gb, length); - - if (BITS_LEFT(length,gb) < 16) { - memset(q->quantized_coeffs[ch][0], 0, 8); - break; - } - } - - n = q->sub_sampling + 1; - - for (sb = 0; sb < n; sb++) - for (ch = 0; ch < q->nb_channels; ch++) - for (j = 0; j < 8; j++) { - if (BITS_LEFT(length,gb) < 1) - break; - if (get_bits1(gb)) { - for (k=0; k < 8; k++) { - if (BITS_LEFT(length,gb) < 16) - break; - q->tone_level_idx_hi1[ch][sb][j][k] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi1, 0, 2); - } - } else { - for (k=0; k < 8; k++) - q->tone_level_idx_hi1[ch][sb][j][k] = 0; - } - } - - n = QDM2_SB_USED(q->sub_sampling) - 4; - - for (sb = 0; sb < n; sb++) - for (ch = 0; ch < q->nb_channels; ch++) { - if (BITS_LEFT(length,gb) < 16) - break; - q->tone_level_idx_hi2[ch][sb] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_hi2, 0, 2); - if (sb > 19) - q->tone_level_idx_hi2[ch][sb] -= 16; - else - for (j = 0; j < 8; j++) - q->tone_level_idx_mid[ch][sb][j] = -16; - } - - n = QDM2_SB_USED(q->sub_sampling) - 5; - - for (sb = 0; sb < n; sb++) - for (ch = 0; ch < q->nb_channels; ch++) - for (j = 0; j < 8; j++) { - if (BITS_LEFT(length,gb) < 16) - break; - q->tone_level_idx_mid[ch][sb][j] = qdm2_get_vlc(gb, &vlc_tab_tone_level_idx_mid, 0, 2) - 32; - } -} - -/** - * Process subpacket 9, init quantized_coeffs with data from it - * - * @param q context - * @param node pointer to node with packet - */ -static void process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node) -{ - GetBitContext gb; - int i, j, k, n, ch, run, level, diff; - - init_get_bits(&gb, node->packet->data, node->packet->size*8); - - n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1; // same as averagesomething function - - for (i = 1; i < n; i++) - for (ch=0; ch < q->nb_channels; ch++) { - level = qdm2_get_vlc(&gb, &vlc_tab_level, 0, 2); - q->quantized_coeffs[ch][i][0] = level; - - for (j = 0; j < (8 - 1); ) { - run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1; - diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2); - - for (k = 1; k <= run; k++) - q->quantized_coeffs[ch][i][j + k] = (level + ((k*diff) / run)); - - level += diff; - j += run; - } - } - - for (ch = 0; ch < q->nb_channels; ch++) - for (i = 0; i < 8; i++) - q->quantized_coeffs[ch][0][i] = 0; -} - - -/** - * Process subpacket 10 if not null, else - * - * @param q context - * @param node pointer to node with packet - * @param length packet length in bits - */ -static void process_subpacket_10 (QDM2Context *q, QDM2SubPNode *node, int length) -{ - GetBitContext gb; - - init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8)); - - if (length != 0) { - init_tone_level_dequantization(q, &gb, length); - fill_tone_level_array(q, 1); - } else { - fill_tone_level_array(q, 0); - } -} - - -/** - * Process subpacket 11 - * - * @param q context - * @param node pointer to node with packet - * @param length packet length in bit - */ -static void process_subpacket_11 (QDM2Context *q, QDM2SubPNode *node, int length) -{ - GetBitContext gb; - - init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8)); - if (length >= 32) { - int c = get_bits (&gb, 13); - - if (c > 3) - fill_coding_method_array (q->tone_level_idx, q->tone_level_idx_temp, q->coding_method, - q->nb_channels, 8*c, q->superblocktype_2_3, q->cm_table_select); - } - - synthfilt_build_sb_samples(q, &gb, length, 0, 8); -} - - -/** - * Process subpacket 12 - * - * @param q context - * @param node pointer to node with packet - * @param length packet length in bits - */ -static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node, int length) -{ - GetBitContext gb; - - init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8)); - synthfilt_build_sb_samples(q, &gb, length, 8, QDM2_SB_USED(q->sub_sampling)); -} - -/* - * Process new subpackets for synthesis filter - * - * @param q context - * @param list list with synthesis filter packets (list D) - */ -static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list) -{ - QDM2SubPNode *nodes[4]; - - nodes[0] = qdm2_search_subpacket_type_in_list(list, 9); - if (nodes[0] != NULL) - process_subpacket_9(q, nodes[0]); - - nodes[1] = qdm2_search_subpacket_type_in_list(list, 10); - if (nodes[1] != NULL) - process_subpacket_10(q, nodes[1], nodes[1]->packet->size << 3); - else - process_subpacket_10(q, NULL, 0); - - nodes[2] = qdm2_search_subpacket_type_in_list(list, 11); - if (nodes[0] != NULL && nodes[1] != NULL && nodes[2] != NULL) - process_subpacket_11(q, nodes[2], (nodes[2]->packet->size << 3)); - else - process_subpacket_11(q, NULL, 0); - - nodes[3] = qdm2_search_subpacket_type_in_list(list, 12); - if (nodes[0] != NULL && nodes[1] != NULL && nodes[3] != NULL) - process_subpacket_12(q, nodes[3], (nodes[3]->packet->size << 3)); - else - process_subpacket_12(q, NULL, 0); -} - - -/* - * Decode superblock, fill packet lists. - * - * @param q context - */ -static void qdm2_decode_super_block (QDM2Context *q) -{ - GetBitContext gb; - QDM2SubPacket header, *packet; - int i, packet_bytes, sub_packet_size, sub_packets_D; - unsigned int next_index = 0; - - memset(q->tone_level_idx_hi1, 0, sizeof(q->tone_level_idx_hi1)); - memset(q->tone_level_idx_mid, 0, sizeof(q->tone_level_idx_mid)); - memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2)); - - q->sub_packets_B = 0; - sub_packets_D = 0; - - average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8] - - init_get_bits(&gb, q->compressed_data, q->compressed_size*8); - qdm2_decode_sub_packet_header(&gb, &header); - - if (header.type < 2 || header.type >= 8) { - q->has_errors = 1; - av_log(NULL,AV_LOG_ERROR,"bad superblock type\n"); - return; - } - - q->superblocktype_2_3 = (header.type == 2 || header.type == 3); - packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); - - init_get_bits(&gb, header.data, header.size*8); - - if (header.type == 2 || header.type == 4 || header.type == 5) { - int csum = 257 * get_bits(&gb, 8) + 2 * get_bits(&gb, 8); - - csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum); - - if (csum != 0) { - q->has_errors = 1; - av_log(NULL,AV_LOG_ERROR,"bad packet checksum\n"); - return; - } - } - - q->sub_packet_list_B[0].packet = NULL; - q->sub_packet_list_D[0].packet = NULL; - - for (i = 0; i < 6; i++) - if (--q->fft_level_exp[i] < 0) - q->fft_level_exp[i] = 0; - - for (i = 0; packet_bytes > 0; i++) { - int j; - - q->sub_packet_list_A[i].next = NULL; - - if (i > 0) { - q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i]; - - /* seek to next block */ - init_get_bits(&gb, header.data, header.size*8); - skip_bits(&gb, next_index*8); - - if (next_index >= header.size) - break; - } - - /* decode subpacket */ - packet = &q->sub_packets[i]; - qdm2_decode_sub_packet_header(&gb, packet); - next_index = packet->size + get_bits_count(&gb) / 8; - sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2; - - if (packet->type == 0) - break; - - if (sub_packet_size > packet_bytes) { - if (packet->type != 10 && packet->type != 11 && packet->type != 12) - break; - packet->size += packet_bytes - sub_packet_size; - } - - packet_bytes -= sub_packet_size; - - /* add subpacket to 'all subpackets' list */ - q->sub_packet_list_A[i].packet = packet; - - /* add subpacket to related list */ - if (packet->type == 8) { - SAMPLES_NEEDED_2("packet type 8"); - return; - } else if (packet->type >= 9 && packet->type <= 12) { - /* packets for MPEG Audio like Synthesis Filter */ - QDM2_LIST_ADD(q->sub_packet_list_D, sub_packets_D, packet); - } else if (packet->type == 13) { - for (j = 0; j < 6; j++) - q->fft_level_exp[j] = get_bits(&gb, 6); - } else if (packet->type == 14) { - for (j = 0; j < 6; j++) - q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2); - } else if (packet->type == 15) { - SAMPLES_NEEDED_2("packet type 15") - return; - } else if (packet->type >= 16 && packet->type < 48 && !fft_subpackets[packet->type - 16]) { - /* packets for FFT */ - QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet); - } - } // Packet bytes loop - -/* **************************************************************** */ - if (q->sub_packet_list_D[0].packet != NULL) { - process_synthesis_subpackets(q, q->sub_packet_list_D); - q->do_synth_filter = 1; - } else if (q->do_synth_filter) { - process_subpacket_10(q, NULL, 0); - process_subpacket_11(q, NULL, 0); - process_subpacket_12(q, NULL, 0); - } -/* **************************************************************** */ -} - - -static void qdm2_fft_init_coefficient (QDM2Context *q, int sub_packet, - int offset, int duration, int channel, - int exp, int phase) -{ - if (q->fft_coefs_min_index[duration] < 0) - q->fft_coefs_min_index[duration] = q->fft_coefs_index; - - q->fft_coefs[q->fft_coefs_index].sub_packet = ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet); - q->fft_coefs[q->fft_coefs_index].channel = channel; - q->fft_coefs[q->fft_coefs_index].offset = offset; - q->fft_coefs[q->fft_coefs_index].exp = exp; - q->fft_coefs[q->fft_coefs_index].phase = phase; - q->fft_coefs_index++; -} - - -static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *gb, int b) -{ - int channel, stereo, phase, exp; - int local_int_4, local_int_8, stereo_phase, local_int_10; - int local_int_14, stereo_exp, local_int_20, local_int_28; - int n, offset; - - local_int_4 = 0; - local_int_28 = 0; - local_int_20 = 2; - local_int_8 = (4 - duration); - local_int_10 = 1 << (q->group_order - duration - 1); - offset = 1; - - while (1) { - if (q->superblocktype_2_3) { - while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { - offset = 1; - if (n == 0) { - local_int_4 += local_int_10; - local_int_28 += (1 << local_int_8); - } else { - local_int_4 += 8*local_int_10; - local_int_28 += (8 << local_int_8); - } - } - offset += (n - 2); - } else { - offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); - while (offset >= (local_int_10 - 1)) { - offset += (1 - (local_int_10 - 1)); - local_int_4 += local_int_10; - local_int_28 += (1 << local_int_8); - } - } - - if (local_int_4 >= q->group_size) - return; - - local_int_14 = (offset >> local_int_8); - - if (q->nb_channels > 1) { - channel = get_bits1(gb); - stereo = get_bits1(gb); - } else { - channel = 0; - stereo = 0; - } - - exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); - exp += q->fft_level_exp[fft_level_index_table[local_int_14]]; - exp = (exp < 0) ? 0 : exp; - - phase = get_bits(gb, 3); - stereo_exp = 0; - stereo_phase = 0; - - if (stereo) { - stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); - stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1)); - if (stereo_phase < 0) - stereo_phase += 8; - } - - if (q->frequency_range > (local_int_14 + 1)) { - int sub_packet = (local_int_20 + local_int_28); - - qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase); - if (stereo) - qdm2_fft_init_coefficient(q, sub_packet, offset, duration, (1 - channel), stereo_exp, stereo_phase); - } - - offset++; - } -} - - -static void qdm2_decode_fft_packets (QDM2Context *q) -{ - int i, j, min, max, value, type, unknown_flag; - GetBitContext gb; - - if (q->sub_packet_list_B[0].packet == NULL) - return; - - /* reset minimum indexes for FFT coefficients */ - q->fft_coefs_index = 0; - for (i=0; i < 5; i++) - q->fft_coefs_min_index[i] = -1; - - /* process subpackets ordered by type, largest type first */ - for (i = 0, max = 256; i < q->sub_packets_B; i++) { - QDM2SubPacket *packet= NULL; - - /* find subpacket with largest type less than max */ - for (j = 0, min = 0; j < q->sub_packets_B; j++) { - value = q->sub_packet_list_B[j].packet->type; - if (value > min && value < max) { - min = value; - packet = q->sub_packet_list_B[j].packet; - } - } - - max = min; - - /* check for errors (?) */ - if (!packet) - return; - - if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16])) - return; - - /* decode FFT tones */ - init_get_bits (&gb, packet->data, packet->size*8); - - if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16]) - unknown_flag = 1; - else - unknown_flag = 0; - - type = packet->type; - - if ((type >= 17 && type < 24) || (type >= 33 && type < 40)) { - int duration = q->sub_sampling + 5 - (type & 15); - - if (duration >= 0 && duration < 4) - qdm2_fft_decode_tones(q, duration, &gb, unknown_flag); - } else if (type == 31) { - for (j=0; j < 4; j++) - qdm2_fft_decode_tones(q, j, &gb, unknown_flag); - } else if (type == 46) { - for (j=0; j < 6; j++) - q->fft_level_exp[j] = get_bits(&gb, 6); - for (j=0; j < 4; j++) - qdm2_fft_decode_tones(q, j, &gb, unknown_flag); - } - } // Loop on B packets - - /* calculate maximum indexes for FFT coefficients */ - for (i = 0, j = -1; i < 5; i++) - if (q->fft_coefs_min_index[i] >= 0) { - if (j >= 0) - q->fft_coefs_max_index[j] = q->fft_coefs_min_index[i]; - j = i; - } - if (j >= 0) - q->fft_coefs_max_index[j] = q->fft_coefs_index; -} - - -static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone) -{ - float level, f[6]; - int i; - QDM2Complex c; - const double iscale = 2.0*M_PI / 512.0; - - tone->phase += tone->phase_shift; - - /* calculate current level (maximum amplitude) of tone */ - level = fft_tone_envelope_table[tone->duration][tone->time_index] * tone->level; - c.im = level * sin(tone->phase*iscale); - c.re = level * cos(tone->phase*iscale); - - /* generate FFT coefficients for tone */ - if (tone->duration >= 3 || tone->cutoff >= 3) { - tone->complex[0].im += c.im; - tone->complex[0].re += c.re; - tone->complex[1].im -= c.im; - tone->complex[1].re -= c.re; - } else { - f[1] = -tone->table[4]; - f[0] = tone->table[3] - tone->table[0]; - f[2] = 1.0 - tone->table[2] - tone->table[3]; - f[3] = tone->table[1] + tone->table[4] - 1.0; - f[4] = tone->table[0] - tone->table[1]; - f[5] = tone->table[2]; - for (i = 0; i < 2; i++) { - tone->complex[fft_cutoff_index_table[tone->cutoff][i]].re += c.re * f[i]; - tone->complex[fft_cutoff_index_table[tone->cutoff][i]].im += c.im *((tone->cutoff <= i) ? -f[i] : f[i]); - } - for (i = 0; i < 4; i++) { - tone->complex[i].re += c.re * f[i+2]; - tone->complex[i].im += c.im * f[i+2]; - } - } - - /* copy the tone if it has not yet died out */ - if (++tone->time_index < ((1 << (5 - tone->duration)) - 1)) { - memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone)); - q->fft_tone_end = (q->fft_tone_end + 1) % 1000; - } -} - - -static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet) -{ - int i, j, ch; - const double iscale = 0.25 * M_PI; - - for (ch = 0; ch < q->channels; ch++) { - memset(q->fft.complex[ch], 0, q->fft_size * sizeof(QDM2Complex)); - } - - - /* apply FFT tones with duration 4 (1 FFT period) */ - if (q->fft_coefs_min_index[4] >= 0) - for (i = q->fft_coefs_min_index[4]; i < q->fft_coefs_max_index[4]; i++) { - float level; - QDM2Complex c; - - if (q->fft_coefs[i].sub_packet != sub_packet) - break; - - ch = (q->channels == 1) ? 0 : q->fft_coefs[i].channel; - level = (q->fft_coefs[i].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[i].exp & 63]; - - c.re = level * cos(q->fft_coefs[i].phase * iscale); - c.im = level * sin(q->fft_coefs[i].phase * iscale); - q->fft.complex[ch][q->fft_coefs[i].offset + 0].re += c.re; - q->fft.complex[ch][q->fft_coefs[i].offset + 0].im += c.im; - q->fft.complex[ch][q->fft_coefs[i].offset + 1].re -= c.re; - q->fft.complex[ch][q->fft_coefs[i].offset + 1].im -= c.im; - } - - /* generate existing FFT tones */ - for (i = q->fft_tone_end; i != q->fft_tone_start; ) { - qdm2_fft_generate_tone(q, &q->fft_tones[q->fft_tone_start]); - q->fft_tone_start = (q->fft_tone_start + 1) % 1000; - } - - /* create and generate new FFT tones with duration 0 (long) to 3 (short) */ - for (i = 0; i < 4; i++) - if (q->fft_coefs_min_index[i] >= 0) { - for (j = q->fft_coefs_min_index[i]; j < q->fft_coefs_max_index[i]; j++) { - int offset, four_i; - FFTTone tone; - - if (q->fft_coefs[j].sub_packet != sub_packet) - break; - - four_i = (4 - i); - offset = q->fft_coefs[j].offset >> four_i; - ch = (q->channels == 1) ? 0 : q->fft_coefs[j].channel; - - if (offset < q->frequency_range) { - if (offset < 2) - tone.cutoff = offset; - else - tone.cutoff = (offset >= 60) ? 3 : 2; - - tone.level = (q->fft_coefs[j].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[j].exp & 63]; - tone.complex = &q->fft.complex[ch][offset]; - tone.table = fft_tone_sample_table[i][q->fft_coefs[j].offset - (offset << four_i)]; - tone.phase = 64 * q->fft_coefs[j].phase - (offset << 8) - 128; - tone.phase_shift = (2 * q->fft_coefs[j].offset + 1) << (7 - four_i); - tone.duration = i; - tone.time_index = 0; - - qdm2_fft_generate_tone(q, &tone); - } - } - q->fft_coefs_min_index[i] = j; - } -} - - -static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet) -{ - const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.5f : 1.0f; - int i; - q->fft.complex[channel][0].re *= 2.0f; - q->fft.complex[channel][0].im = 0.0f; - ff_rdft_calc(&q->rdft_ctx, (FFTSample *)q->fft.complex[channel]); - /* add samples to output buffer */ - for (i = 0; i < ((q->fft_frame_size + 15) & ~15); i++) - q->output_buffer[q->channels * i + channel] += ((float *) q->fft.complex[channel])[i] * gain; -} - - -/** - * @param q context - * @param index subpacket number - */ -static void qdm2_synthesis_filter (QDM2Context *q, int index) -{ - OUT_INT samples[MPA_MAX_CHANNELS * MPA_FRAME_SIZE]; - int i, k, ch, sb_used, sub_sampling, dither_state = 0; - - /* copy sb_samples */ - sb_used = QDM2_SB_USED(q->sub_sampling); - - for (ch = 0; ch < q->channels; ch++) - for (i = 0; i < 8; i++) - for (k=sb_used; k < SBLIMIT; k++) - q->sb_samples[ch][(8 * index) + i][k] = 0; - - for (ch = 0; ch < q->nb_channels; ch++) { - OUT_INT *samples_ptr = samples + ch; - - for (i = 0; i < 8; i++) { - ff_mpa_synth_filter(q->synth_buf[ch], &(q->synth_buf_offset[ch]), - ff_mpa_synth_window, &dither_state, - samples_ptr, q->nb_channels, - q->sb_samples[ch][(8 * index) + i]); - samples_ptr += 32 * q->nb_channels; - } - } - - /* add samples to output buffer */ - sub_sampling = (4 >> q->sub_sampling); - - for (ch = 0; ch < q->channels; ch++) - for (i = 0; i < q->frame_size; i++) - q->output_buffer[q->channels * i + ch] += (float)(samples[q->nb_channels * sub_sampling * i + ch] >> (sizeof(OUT_INT)*8-16)); -} - - -/** - * Init static data (does not depend on specific file) - * - * @param q context - */ -static av_cold void qdm2_init(QDM2Context *q) { - static int initialized = 0; - - if (initialized != 0) - return; - initialized = 1; - - qdm2_init_vlc(); - ff_mpa_synth_init(ff_mpa_synth_window); - softclip_table_init(); - rnd_table_init(); - init_noise_samples(); - - av_log(NULL, AV_LOG_DEBUG, "init done\n"); -} - - -#if 0 -static void dump_context(QDM2Context *q) -{ - int i; -#define PRINT(a,b) av_log(NULL,AV_LOG_DEBUG," %s = %d\n", a, b); - PRINT("compressed_data",q->compressed_data); - PRINT("compressed_size",q->compressed_size); - PRINT("frame_size",q->frame_size); - PRINT("checksum_size",q->checksum_size); - PRINT("channels",q->channels); - PRINT("nb_channels",q->nb_channels); - PRINT("fft_frame_size",q->fft_frame_size); - PRINT("fft_size",q->fft_size); - PRINT("sub_sampling",q->sub_sampling); - PRINT("fft_order",q->fft_order); - PRINT("group_order",q->group_order); - PRINT("group_size",q->group_size); - PRINT("sub_packet",q->sub_packet); - PRINT("frequency_range",q->frequency_range); - PRINT("has_errors",q->has_errors); - PRINT("fft_tone_end",q->fft_tone_end); - PRINT("fft_tone_start",q->fft_tone_start); - PRINT("fft_coefs_index",q->fft_coefs_index); - PRINT("coeff_per_sb_select",q->coeff_per_sb_select); - PRINT("cm_table_select",q->cm_table_select); - PRINT("noise_idx",q->noise_idx); - - for (i = q->fft_tone_start; i < q->fft_tone_end; i++) - { - FFTTone *t = &q->fft_tones[i]; - - av_log(NULL,AV_LOG_DEBUG,"Tone (%d) dump:\n", i); - av_log(NULL,AV_LOG_DEBUG," level = %f\n", t->level); -// PRINT(" level", t->level); - PRINT(" phase", t->phase); - PRINT(" phase_shift", t->phase_shift); - PRINT(" duration", t->duration); - PRINT(" samples_im", t->samples_im); - PRINT(" samples_re", t->samples_re); - PRINT(" table", t->table); - } - -} -#endif - - -/** - * Init parameters from codec extradata - */ -static av_cold int qdm2_decode_init(AVCodecContext *avctx) -{ - QDM2Context *s = avctx->priv_data; - uint8_t *extradata; - int extradata_size; - int tmp_val, tmp, size; - - /* extradata parsing - - Structure: - wave { - frma (QDM2) - QDCA - QDCP - } - - 32 size (including this field) - 32 tag (=frma) - 32 type (=QDM2 or QDMC) - - 32 size (including this field, in bytes) - 32 tag (=QDCA) // maybe mandatory parameters - 32 unknown (=1) - 32 channels (=2) - 32 samplerate (=44100) - 32 bitrate (=96000) - 32 block size (=4096) - 32 frame size (=256) (for one channel) - 32 packet size (=1300) - - 32 size (including this field, in bytes) - 32 tag (=QDCP) // maybe some tuneable parameters - 32 float1 (=1.0) - 32 zero ? - 32 float2 (=1.0) - 32 float3 (=1.0) - 32 unknown (27) - 32 unknown (8) - 32 zero ? - */ - - if (!avctx->extradata || (avctx->extradata_size < 48)) { - av_log(avctx, AV_LOG_ERROR, "extradata missing or truncated\n"); - return -1; - } - - extradata = avctx->extradata; - extradata_size = avctx->extradata_size; - - while (extradata_size > 7) { - if (!memcmp(extradata, "frmaQDM", 7)) - break; - extradata++; - extradata_size--; - } - - if (extradata_size < 12) { - av_log(avctx, AV_LOG_ERROR, "not enough extradata (%i)\n", - extradata_size); - return -1; - } - - if (memcmp(extradata, "frmaQDM", 7)) { - av_log(avctx, AV_LOG_ERROR, "invalid headers, QDM? not found\n"); - return -1; - } - - if (extradata[7] == 'C') { -// s->is_qdmc = 1; - av_log(avctx, AV_LOG_ERROR, "stream is QDMC version 1, which is not supported\n"); - return -1; - } - - extradata += 8; - extradata_size -= 8; - - size = AV_RB32(extradata); - - if(size > extradata_size){ - av_log(avctx, AV_LOG_ERROR, "extradata size too small, %i < %i\n", - extradata_size, size); - return -1; - } - - extradata += 4; - av_log(avctx, AV_LOG_DEBUG, "size: %d\n", size); - if (AV_RB32(extradata) != MKBETAG('Q','D','C','A')) { - av_log(avctx, AV_LOG_ERROR, "invalid extradata, expecting QDCA\n"); - return -1; - } - - extradata += 8; - - avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata); - extradata += 4; - - avctx->sample_rate = AV_RB32(extradata); - extradata += 4; - - avctx->bit_rate = AV_RB32(extradata); - extradata += 4; - - s->group_size = AV_RB32(extradata); - extradata += 4; - - s->fft_size = AV_RB32(extradata); - extradata += 4; - - s->checksum_size = AV_RB32(extradata); - - s->fft_order = av_log2(s->fft_size) + 1; - s->fft_frame_size = 2 * s->fft_size; // complex has two floats - - // something like max decodable tones - s->group_order = av_log2(s->group_size) + 1; - s->frame_size = s->group_size / 16; // 16 iterations per super block - - s->sub_sampling = s->fft_order - 7; - s->frequency_range = 255 / (1 << (2 - s->sub_sampling)); - - switch ((s->sub_sampling * 2 + s->channels - 1)) { - case 0: tmp = 40; break; - case 1: tmp = 48; break; - case 2: tmp = 56; break; - case 3: tmp = 72; break; - case 4: tmp = 80; break; - case 5: tmp = 100;break; - default: tmp=s->sub_sampling; break; - } - tmp_val = 0; - if ((tmp * 1000) < avctx->bit_rate) tmp_val = 1; - if ((tmp * 1440) < avctx->bit_rate) tmp_val = 2; - if ((tmp * 1760) < avctx->bit_rate) tmp_val = 3; - if ((tmp * 2240) < avctx->bit_rate) tmp_val = 4; - s->cm_table_select = tmp_val; - - if (s->sub_sampling == 0) - tmp = 7999; - else - tmp = ((-(s->sub_sampling -1)) & 8000) + 20000; - /* - 0: 7999 -> 0 - 1: 20000 -> 2 - 2: 28000 -> 2 - */ - if (tmp < 8000) - s->coeff_per_sb_select = 0; - else if (tmp <= 16000) - s->coeff_per_sb_select = 1; - else - s->coeff_per_sb_select = 2; - - // Fail on unknown fft order - if ((s->fft_order < 7) || (s->fft_order > 9)) { - av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order); - return -1; - } - - ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R); - - qdm2_init(s); - - avctx->sample_fmt = SAMPLE_FMT_S16; - -// dump_context(s); - return 0; -} - - -static av_cold int qdm2_decode_close(AVCodecContext *avctx) -{ - QDM2Context *s = avctx->priv_data; - - ff_rdft_end(&s->rdft_ctx); - - return 0; -} - - -static void qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out) -{ - int ch, i; - const int frame_size = (q->frame_size * q->channels); - - /* select input buffer */ - q->compressed_data = in; - q->compressed_size = q->checksum_size; - -// dump_context(q); - - /* copy old block, clear new block of output samples */ - memmove(q->output_buffer, &q->output_buffer[frame_size], frame_size * sizeof(float)); - memset(&q->output_buffer[frame_size], 0, frame_size * sizeof(float)); - - /* decode block of QDM2 compressed data */ - if (q->sub_packet == 0) { - q->has_errors = 0; // zero it for a new super block - av_log(NULL,AV_LOG_DEBUG,"Superblock follows\n"); - qdm2_decode_super_block(q); - } - - /* parse subpackets */ - if (!q->has_errors) { - if (q->sub_packet == 2) - qdm2_decode_fft_packets(q); - - qdm2_fft_tone_synthesizer(q, q->sub_packet); - } - - /* sound synthesis stage 1 (FFT) */ - for (ch = 0; ch < q->channels; ch++) { - qdm2_calculate_fft(q, ch, q->sub_packet); - - if (!q->has_errors && q->sub_packet_list_C[0].packet != NULL) { - SAMPLES_NEEDED_2("has errors, and C list is not empty") - return; - } - } - - /* sound synthesis stage 2 (MPEG audio like synthesis filter) */ - if (!q->has_errors && q->do_synth_filter) - qdm2_synthesis_filter(q, q->sub_packet); - - q->sub_packet = (q->sub_packet + 1) % 16; - - /* clip and convert output float[] to 16bit signed samples */ - for (i = 0; i < frame_size; i++) { - int value = (int)q->output_buffer[i]; - - if (value > SOFTCLIP_THRESHOLD) - value = (value > HARDCLIP_THRESHOLD) ? 32767 : softclip_table[ value - SOFTCLIP_THRESHOLD]; - else if (value < -SOFTCLIP_THRESHOLD) - value = (value < -HARDCLIP_THRESHOLD) ? -32767 : -softclip_table[-value - SOFTCLIP_THRESHOLD]; - - out[i] = value; - } -} - - -static int qdm2_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - QDM2Context *s = avctx->priv_data; - - if(!buf) - return 0; - if(buf_size < s->checksum_size) - return -1; - - *data_size = s->channels * s->frame_size * sizeof(int16_t); - - av_log(avctx, AV_LOG_DEBUG, "decode(%d): %p[%d] -> %p[%d]\n", - buf_size, buf, s->checksum_size, data, *data_size); - - qdm2_decode(s, buf, data); - - // reading only when next superblock found - if (s->sub_packet == 0) { - return s->checksum_size; - } - - return 0; -} - -AVCodec qdm2_decoder = -{ - .name = "qdm2", - .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_QDM2, - .priv_data_size = sizeof(QDM2Context), - .init = qdm2_decode_init, - .close = qdm2_decode_close, - .decode = qdm2_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.c b/tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.c deleted file mode 100644 index c225bc4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Generate a header file for hardcoded QDM2 tables - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#define CONFIG_HARDCODED_TABLES 0 -#include "qdm2_tablegen.h" -#include "tableprint.h" - -int main(void) -{ - softclip_table_init(); - rnd_table_init(); - init_noise_samples(); - - write_fileheader(); - - printf("static const uint16_t softclip_table[HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1] = {\n"); - write_uint16_array(softclip_table, HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1); - printf("};\n"); - - printf("static const float noise_table[4096] = {\n"); - write_float_array(noise_table, 4096); - printf("};\n"); - - printf("static const uint8_t random_dequant_index[256][5] = {\n"); - write_uint8_2d_array(random_dequant_index, 256, 5); - printf("};\n"); - - printf("static const uint8_t random_dequant_type24[128][3] = {\n"); - write_uint8_2d_array(random_dequant_type24, 128, 3); - printf("};\n"); - - printf("static const float noise_samples[128] = {\n"); - write_float_array(noise_samples, 128); - printf("};\n"); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.h b/tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.h deleted file mode 100644 index de9ff0c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qdm2_tablegen.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Header file for hardcoded QDM2 tables - * - * Copyright (c) 2010 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef QDM2_TABLEGEN_H -#define QDM2_TABLEGEN_H - -#include -#include -#include "../libavutil/attributes.h" - -#define SOFTCLIP_THRESHOLD 27600 -#define HARDCLIP_THRESHOLD 35716 - -#if CONFIG_HARDCODED_TABLES -#define softclip_table_init() -#define rnd_table_init() -#define init_noise_samples() -#include "libavcodec/qdm2_tables.h" -#else -static uint16_t softclip_table[HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1]; -static float noise_table[4096]; -static uint8_t random_dequant_index[256][5]; -static uint8_t random_dequant_type24[128][3]; -static float noise_samples[128]; - -static av_cold void softclip_table_init(void) { - int i; - double dfl = SOFTCLIP_THRESHOLD - 32767; - float delta = 1.0 / -dfl; - for (i = 0; i < HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1; i++) - softclip_table[i] = SOFTCLIP_THRESHOLD - ((int)(sin((float)i * delta) * dfl) & 0x0000FFFF); -} - - -// random generated table -static av_cold void rnd_table_init(void) { - int i,j; - uint32_t ldw,hdw; - uint64_t tmp64_1; - uint64_t random_seed = 0; - float delta = 1.0 / 16384.0; - for(i = 0; i < 4096 ;i++) { - random_seed = random_seed * 214013 + 2531011; - noise_table[i] = (delta * (float)(((int32_t)random_seed >> 16) & 0x00007FFF)- 1.0) * 1.3; - } - - for (i = 0; i < 256 ;i++) { - random_seed = 81; - ldw = i; - for (j = 0; j < 5 ;j++) { - random_dequant_index[i][j] = (uint8_t)((ldw / random_seed) & 0xFF); - ldw = (uint32_t)ldw % (uint32_t)random_seed; - tmp64_1 = (random_seed * 0x55555556); - hdw = (uint32_t)(tmp64_1 >> 32); - random_seed = (uint64_t)(hdw + (ldw >> 31)); - } - } - for (i = 0; i < 128 ;i++) { - random_seed = 25; - ldw = i; - for (j = 0; j < 3 ;j++) { - random_dequant_type24[i][j] = (uint8_t)((ldw / random_seed) & 0xFF); - ldw = (uint32_t)ldw % (uint32_t)random_seed; - tmp64_1 = (random_seed * 0x66666667); - hdw = (uint32_t)(tmp64_1 >> 33); - random_seed = hdw + (ldw >> 31); - } - } -} - - -static av_cold void init_noise_samples(void) { - int i; - int random_seed = 0; - float delta = 1.0 / 16384.0; - for (i = 0; i < 128;i++) { - random_seed = random_seed * 214013 + 2531011; - noise_samples[i] = (delta * (float)((random_seed >> 16) & 0x00007fff) - 1.0); - } -} -#endif /* CONFIG_HARDCODED_TABLES */ - -#endif /* QDM2_TABLEGEN_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/qdm2data.h b/tizen/distrib/ffmpeg/libavcodec/qdm2data.h deleted file mode 100644 index 355d613..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qdm2data.h +++ /dev/null @@ -1,531 +0,0 @@ -/* - * QDM2 compatible decoder - * Copyright (c) 2003 Ewald Snel - * Copyright (c) 2005 Benjamin Larsson - * Copyright (c) 2005 Alex Beregszaszi - * Copyright (c) 2005 Roberto Togni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - /** - * @file - * Various QDM2 tables. - */ - -#ifndef AVCODEC_QDM2DATA_H -#define AVCODEC_QDM2DATA_H - -#include - -/** VLC TABLES **/ - -/* values in this table range from -1..23; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_level_huffcodes[24] = { - 0x037c, 0x0004, 0x003c, 0x004c, 0x003a, 0x002c, 0x001c, 0x001a, - 0x0024, 0x0014, 0x0001, 0x0002, 0x0000, 0x0003, 0x0007, 0x0005, - 0x0006, 0x0008, 0x0009, 0x000a, 0x000c, 0x00fc, 0x007c, 0x017c -}; - -static const uint8_t vlc_tab_level_huffbits[24] = { - 10, 6, 7, 7, 6, 6, 6, 6, 6, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 7, 8, 9, 10 -}; - -/* values in this table range from -1..36; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_diff_huffcodes[37] = { - 0x1c57, 0x0004, 0x0000, 0x0001, 0x0003, 0x0002, 0x000f, 0x000e, - 0x0007, 0x0016, 0x0037, 0x0027, 0x0026, 0x0066, 0x0006, 0x0097, - 0x0046, 0x01c6, 0x0017, 0x0786, 0x0086, 0x0257, 0x00d7, 0x0357, - 0x00c6, 0x0386, 0x0186, 0x0000, 0x0157, 0x0c57, 0x0057, 0x0000, - 0x0b86, 0x0000, 0x1457, 0x0000, 0x0457 -}; - -static const uint8_t vlc_tab_diff_huffbits[37] = { - 13, 3, 3, 2, 3, 3, 4, 4, 6, 5, 6, 6, 7, 7, 8, 8, - 8, 9, 8, 11, 9, 10, 8, 10, 9, 12, 10, 0, 10, 13, 11, 0, - 12, 0, 13, 0, 13 -}; - -/* values in this table range from -1..5; adjust retrieved value by -1 */ -static const uint8_t vlc_tab_run_huffcodes[6] = { - 0x1f, 0x00, 0x01, 0x03, 0x07, 0x0f -}; - -static const uint8_t vlc_tab_run_huffbits[6] = { - 5, 1, 2, 3, 4, 5 -}; - -/* values in this table range from -1..19; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_tone_level_idx_hi1_huffcodes[20] = { - 0x5714, 0x000c, 0x0002, 0x0001, 0x0000, 0x0004, 0x0034, 0x0054, - 0x0094, 0x0014, 0x0114, 0x0214, 0x0314, 0x0614, 0x0e14, 0x0f14, - 0x2714, 0x0714, 0x1714, 0x3714 -}; - -static const uint8_t vlc_tab_tone_level_idx_hi1_huffbits[20] = { - 15, 4, 2, 1, 3, 5, 6, 7, 8, 10, 10, 11, 11, 12, 12, 12, 14, 14, 15, 14 -}; - -/* values in this table range from -1..23; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_tone_level_idx_mid_huffcodes[24] = { - 0x0fea, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x03ea, 0x00ea, 0x002a, 0x001a, - 0x0006, 0x0001, 0x0000, 0x0002, 0x000a, 0x006a, 0x01ea, 0x07ea -}; - -static const uint8_t vlc_tab_tone_level_idx_mid_huffbits[24] = { - 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12 -}; - -/* values in this table range from -1..23; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_tone_level_idx_hi2_huffcodes[24] = { - 0x0664, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0064, 0x00e4, - 0x00a4, 0x0068, 0x0004, 0x0008, 0x0014, 0x0018, 0x0000, 0x0001, - 0x0002, 0x0003, 0x000c, 0x0028, 0x0024, 0x0164, 0x0000, 0x0264 -}; - -static const uint8_t vlc_tab_tone_level_idx_hi2_huffbits[24] = { - 11, 0, 0, 0, 0, 0, 10, 8, 8, 7, 6, 6, 5, 5, 4, 2, 2, 2, 4, 7, 8, 9, 0, 11 -}; - -/* values in this table range from -1..8; adjust retrieved value by -1 */ -static const uint8_t vlc_tab_type30_huffcodes[9] = { - 0x3c, 0x06, 0x00, 0x01, 0x03, 0x02, 0x04, 0x0c, 0x1c -}; - -static const uint8_t vlc_tab_type30_huffbits[9] = { - 6, 3, 3, 2, 2, 3, 4, 5, 6 -}; - -/* values in this table range from -1..9; adjust retrieved value by -1 */ -static const uint8_t vlc_tab_type34_huffcodes[10] = { - 0x18, 0x00, 0x01, 0x04, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08 -}; - -static const uint8_t vlc_tab_type34_huffbits[10] = { - 5, 4, 3, 3, 3, 3, 3, 3, 3, 5 -}; - -/* values in this table range from -1..22; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_0_huffcodes[23] = { - 0x038e, 0x0001, 0x0000, 0x0022, 0x000a, 0x0006, 0x0012, 0x0002, - 0x001e, 0x003e, 0x0056, 0x0016, 0x000e, 0x0032, 0x0072, 0x0042, - 0x008e, 0x004e, 0x00f2, 0x002e, 0x0036, 0x00c2, 0x018e -}; - -static const uint8_t vlc_tab_fft_tone_offset_0_huffbits[23] = { - 10, 1, 2, 6, 4, 5, 6, 7, 6, 6, 7, 7, 8, 7, 8, 8, 9, 7, 8, 6, 6, 8, 10 -}; - -/* values in this table range from -1..27; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_1_huffcodes[28] = { - 0x07a4, 0x0001, 0x0020, 0x0012, 0x001c, 0x0008, 0x0006, 0x0010, - 0x0000, 0x0014, 0x0004, 0x0032, 0x0070, 0x000c, 0x0002, 0x003a, - 0x001a, 0x002c, 0x002a, 0x0022, 0x0024, 0x000a, 0x0064, 0x0030, - 0x0062, 0x00a4, 0x01a4, 0x03a4 -}; - -static const uint8_t vlc_tab_fft_tone_offset_1_huffbits[28] = { - 11, 1, 6, 6, 5, 4, 3, 6, 6, 5, 6, 6, 7, 6, 6, 6, - 6, 6, 6, 7, 8, 6, 7, 7, 7, 9, 10, 11 -}; - -/* values in this table range from -1..31; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_2_huffcodes[32] = { - 0x1760, 0x0001, 0x0000, 0x0082, 0x000c, 0x0006, 0x0003, 0x0007, - 0x0008, 0x0004, 0x0010, 0x0012, 0x0022, 0x001a, 0x0000, 0x0020, - 0x000a, 0x0040, 0x004a, 0x006a, 0x002a, 0x0042, 0x0002, 0x0060, - 0x00aa, 0x00e0, 0x00c2, 0x01c2, 0x0160, 0x0360, 0x0760, 0x0f60 -}; - -static const uint8_t vlc_tab_fft_tone_offset_2_huffbits[32] = { - 13, 2, 0, 8, 4, 3, 3, 3, 4, 4, 5, 5, 6, 5, 7, 7, - 7, 7, 7, 7, 8, 8, 8, 9, 8, 8, 9, 9, 10, 11, 13, 12 -}; - -/* values in this table range from -1..34; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_3_huffcodes[35] = { - 0x33ea, 0x0005, 0x0000, 0x000c, 0x0000, 0x0006, 0x0003, 0x0008, - 0x0002, 0x0001, 0x0004, 0x0007, 0x001a, 0x000f, 0x001c, 0x002c, - 0x000a, 0x001d, 0x002d, 0x002a, 0x000d, 0x004c, 0x008c, 0x006a, - 0x00cd, 0x004d, 0x00ea, 0x020c, 0x030c, 0x010c, 0x01ea, 0x07ea, - 0x0bea, 0x03ea, 0x13ea -}; - -static const uint8_t vlc_tab_fft_tone_offset_3_huffbits[35] = { - 14, 4, 0, 10, 4, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, - 6, 5, 6, 7, 7, 7, 8, 8, 8, 8, 9, 10, 10, 10, 10, 11, - 12, 13, 14 -}; - -/* values in this table range from -1..37; adjust retrieved value by -1 */ -static const uint16_t vlc_tab_fft_tone_offset_4_huffcodes[38] = { - 0x5282, 0x0016, 0x0000, 0x0136, 0x0004, 0x0000, 0x0007, 0x000a, - 0x000e, 0x0003, 0x0001, 0x000d, 0x0006, 0x0009, 0x0012, 0x0005, - 0x0025, 0x0022, 0x0015, 0x0002, 0x0076, 0x0035, 0x0042, 0x00c2, - 0x0182, 0x00b6, 0x0036, 0x03c2, 0x0482, 0x01c2, 0x0682, 0x0882, - 0x0a82, 0x0082, 0x0282, 0x1282, 0x3282, 0x2282 -}; - -static const uint8_t vlc_tab_fft_tone_offset_4_huffbits[38] = { - 15, 6, 0, 9, 3, 3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 6, - 6, 6, 6, 8, 7, 6, 8, 9, 9, 8, 9, 10, 11, 10, 11, 12, - 12, 12, 14, 15, 14, 14 -}; - -/** FFT TABLES **/ - -/* values in this table range from -1..27; adjust retrieved value by -1 */ -static const uint16_t fft_level_exp_alt_huffcodes[28] = { - 0x1ec6, 0x0006, 0x00c2, 0x0142, 0x0242, 0x0246, 0x00c6, 0x0046, - 0x0042, 0x0146, 0x00a2, 0x0062, 0x0026, 0x0016, 0x000e, 0x0005, - 0x0004, 0x0003, 0x0000, 0x0001, 0x000a, 0x0012, 0x0002, 0x0022, - 0x01c6, 0x02c6, 0x06c6, 0x0ec6 -}; - -static const uint8_t fft_level_exp_alt_huffbits[28] = { - 13, 7, 8, 9, 10, 10, 10, 10, 10, 9, 8, 7, 6, 5, 4, 3, - 3, 2, 3, 3, 4, 5, 7, 8, 9, 11, 12, 13 -}; - -/* values in this table range from -1..19; adjust retrieved value by -1 */ -static const uint16_t fft_level_exp_huffcodes[20] = { - 0x0f24, 0x0001, 0x0002, 0x0000, 0x0006, 0x0005, 0x0007, 0x000c, - 0x000b, 0x0014, 0x0013, 0x0004, 0x0003, 0x0023, 0x0064, 0x00a4, - 0x0024, 0x0124, 0x0324, 0x0724 -}; - -static const uint8_t fft_level_exp_huffbits[20] = { - 12, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 8, 9, 10, 11, 12 -}; - -/* values in this table range from -1..6; adjust retrieved value by -1 */ -static const uint8_t fft_stereo_exp_huffcodes[7] = { - 0x3e, 0x01, 0x00, 0x02, 0x06, 0x0e, 0x1e -}; - -static const uint8_t fft_stereo_exp_huffbits[7] = { - 6, 1, 2, 3, 4, 5, 6 -}; - -/* values in this table range from -1..8; adjust retrieved value by -1 */ -static const uint8_t fft_stereo_phase_huffcodes[9] = { - 0x35, 0x02, 0x00, 0x01, 0x0d, 0x15, 0x05, 0x09, 0x03 -}; - -static const uint8_t fft_stereo_phase_huffbits[9] = { - 6, 2, 2, 4, 4, 6, 5, 4, 2 -}; - -static const int fft_cutoff_index_table[4][2] = { - { 1, 2 }, {-1, 0 }, {-1,-2 }, { 0, 0 } -}; - -static const int16_t fft_level_index_table[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 3, 3, 3, 3, 3, 3, 3, - 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, - 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, - 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, -}; - -static const uint8_t last_coeff[3] = { - 4, 7, 10 -}; - -static const uint8_t coeff_per_sb_for_avg[3][30] = { - { 0, 1, 1, 1, 1, 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 }, - { 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, - { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9 } -}; - -static const uint32_t dequant_table[3][10][30] = { - { { 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 256, 256, 205, 154, 102, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 51, 102, 154, 205, 256, 238, 219, 201, 183, 165, 146, 128, 110, 91, 73, 55, 37, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 18, 37, 55, 73, 91, 110, 128, 146, 165, 183, 201, 219, 238, 256, 228, 199, 171, 142, 114, 85, 57, 28 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 256, 171, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 85, 171, 256, 171, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 85, 171, 256, 219, 183, 146, 110, 73, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 73, 110, 146, 183, 219, 256, 228, 199, 171, 142, 114, 85, 57, 28, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 57, 85, 114, 142, 171, 199, 228, 256, 213, 171, 128, 85, 43 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 256, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 256, 171, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 85, 171, 256, 192, 128, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 128, 192, 256, 205, 154, 102, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 102, 154, 205, 256, 213, 171, 128, 85, 43, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 85, 128, 171, 213, 256, 213, 171, 128, 85, 43 } } -}; - -static const uint8_t coeff_per_sb_for_dequant[3][30] = { - { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 }, - { 0, 1, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9 } -}; - -/* first index is subband, 2nd index is 0, 1 or 3 (2 is unused) */ -static const int8_t tone_level_idx_offset_table[30][4] = { - { -50, -50, 0, -50 }, - { -50, -50, 0, -50 }, - { -50, -9, 0, -19 }, - { -16, -6, 0, -12 }, - { -11, -4, 0, -8 }, - { -8, -3, 0, -6 }, - { -7, -3, 0, -5 }, - { -6, -2, 0, -4 }, - { -5, -2, 0, -3 }, - { -4, -1, 0, -3 }, - { -4, -1, 0, -2 }, - { -3, -1, 0, -2 }, - { -3, -1, 0, -2 }, - { -3, -1, 0, -2 }, - { -2, -1, 0, -1 }, - { -2, -1, 0, -1 }, - { -2, -1, 0, -1 }, - { -2, 0, 0, -1 }, - { -2, 0, 0, -1 }, - { -1, 0, 0, -1 }, - { -1, 0, 0, -1 }, - { -1, 0, 0, -1 }, - { -1, 0, 0, -1 }, - { -1, 0, 0, -1 }, - { -1, 0, 0, -1 }, - { -1, 0, 0, -1 }, - { -1, 0, 0, 0 }, - { -1, 0, 0, 0 }, - { -1, 0, 0, 0 }, - { -1, 0, 0, 0 } -}; - -/* all my samples have 1st index 0 or 1 */ -/* second index is subband, only indexes 0-29 seem to be used */ -static const int8_t coding_method_table[5][30] = { - { 34, 30, 24, 24, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 - }, - { 34, 30, 24, 24, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 - }, - { 34, 30, 30, 30, 24, 24, 16, 16, 16, 16, 16, 16, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 - }, - { 34, 34, 30, 30, 24, 24, 24, 24, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, 10 - }, - { 34, 34, 30, 30, 30, 30, 30, 30, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 - }, -}; - -static const int vlc_stage3_values[60] = { - 0, 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, - 28, 36, 44, 52, 60, 76, 92, 108, 124, 156, 188, 220, - 252, 316, 380, 444, 508, 636, 764, 892, 1020, 1276, 1532, 1788, - 2044, 2556, 3068, 3580, 4092, 5116, 6140, 7164, 8188, 10236, 12284, 14332, - 16380, 20476, 24572, 28668, 32764, 40956, 49148, 57340, 65532, 81916, 98300,114684 -}; - -static const float fft_tone_sample_table[4][16][5] = { - { { .0100000000f,-.0037037037f,-.0020000000f,-.0069444444f,-.0018416207f }, - { .0416666667f, .0000000000f, .0000000000f,-.0208333333f,-.0123456791f }, - { .1250000000f, .0558035709f, .0330687836f,-.0164473690f,-.0097465888f }, - { .1562500000f, .0625000000f, .0370370370f,-.0062500000f,-.0037037037f }, - { .1996007860f, .0781250000f, .0462962948f, .0022727272f, .0013468013f }, - { .2000000000f, .0625000000f, .0370370373f, .0208333333f, .0074074073f }, - { .2127659619f, .0555555556f, .0329218097f, .0208333333f, .0123456791f }, - { .2173913121f, .0473484844f, .0280583613f, .0347222239f, .0205761325f }, - { .2173913121f, .0347222239f, .0205761325f, .0473484844f, .0280583613f }, - { .2127659619f, .0208333333f, .0123456791f, .0555555556f, .0329218097f }, - { .2000000000f, .0208333333f, .0074074073f, .0625000000f, .0370370370f }, - { .1996007860f, .0022727272f, .0013468013f, .0781250000f, .0462962948f }, - { .1562500000f,-.0062500000f,-.0037037037f, .0625000000f, .0370370370f }, - { .1250000000f,-.0164473690f,-.0097465888f, .0558035709f, .0330687836f }, - { .0416666667f,-.0208333333f,-.0123456791f, .0000000000f, .0000000000f }, - { .0100000000f,-.0069444444f,-.0018416207f,-.0037037037f,-.0020000000f } }, - - { { .0050000000f,-.0200000000f, .0125000000f,-.3030303030f, .0020000000f }, - { .1041666642f, .0400000000f,-.0250000000f, .0333333333f,-.0200000000f }, - { .1250000000f, .0100000000f, .0142857144f,-.0500000007f,-.0200000000f }, - { .1562500000f,-.0006250000f,-.00049382716f,-.000625000f,-.00049382716f }, - { .1562500000f,-.0006250000f,-.00049382716f,-.000625000f,-.00049382716f }, - { .1250000000f,-.0500000000f,-.0200000000f, .0100000000f, .0142857144f }, - { .1041666667f, .0333333333f,-.0200000000f, .0400000000f,-.0250000000f }, - { .0050000000f,-.3030303030f, .0020000001f,-.0200000000f, .0125000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f } }, - - { { .1428571492f, .1250000000f,-.0285714287f,-.0357142873f, .0208333333f }, - { .1818181818f, .0588235296f, .0333333333f, .0212765951f, .0100000000f }, - { .1818181818f, .0212765951f, .0100000000f, .0588235296f, .0333333333f }, - { .1428571492f,-.0357142873f, .0208333333f, .1250000000f,-.0285714287f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f } }, - - { { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f }, - { .0000000000f, .0000000000f, .0000000000f, .0000000000f, .0000000000f } } -}; - -static const float fft_tone_level_table[2][64] = { { -/* pow ~ (i > 46) ? 0 : (((((i & 1) ? 431 : 304) << (i >> 1))) / 1024.0); */ - 0.17677669f, 0.42677650f, 0.60355347f, 0.85355347f, - 1.20710683f, 1.68359375f, 2.37500000f, 3.36718750f, - 4.75000000f, 6.73437500f, 9.50000000f, 13.4687500f, - 19.0000000f, 26.9375000f, 38.0000000f, 53.8750000f, - 76.0000000f, 107.750000f, 152.000000f, 215.500000f, - 304.000000f, 431.000000f, 608.000000f, 862.000000f, - 1216.00000f, 1724.00000f, 2432.00000f, 3448.00000f, - 4864.00000f, 6896.00000f, 9728.00000f, 13792.0000f, - 19456.0000f, 27584.0000f, 38912.0000f, 55168.0000f, - 77824.0000f, 110336.000f, 155648.000f, 220672.000f, - 311296.000f, 441344.000f, 622592.000f, 882688.000f, - 1245184.00f, 1765376.00f, 2490368.00f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, - }, { -/* pow = (i > 45) ? 0 : ((((i & 1) ? 431 : 304) << (i >> 1)) / 512.0); */ - 0.59375000f, 0.84179688f, 1.18750000f, 1.68359375f, - 2.37500000f, 3.36718750f, 4.75000000f, 6.73437500f, - 9.50000000f, 13.4687500f, 19.0000000f, 26.9375000f, - 38.0000000f, 53.8750000f, 76.0000000f, 107.750000f, - 152.000000f, 215.500000f, 304.000000f, 431.000000f, - 608.000000f, 862.000000f, 1216.00000f, 1724.00000f, - 2432.00000f, 3448.00000f, 4864.00000f, 6896.00000f, - 9728.00000f, 13792.0000f, 19456.0000f, 27584.0000f, - 38912.0000f, 55168.0000f, 77824.0000f, 110336.000f, - 155648.000f, 220672.000f, 311296.000f, 441344.000f, - 622592.000f, 882688.000f, 1245184.00f, 1765376.00f, - 2490368.00f, 3530752.00f, 0.00000000f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f, - 0.00000000f, 0.00000000f, 0.00000000f, 0.00000000f -} }; - -static const float fft_tone_envelope_table[4][31] = { - { .009607375f, .038060248f, .084265202f, .146446645f, .222214907f, .308658302f, - .402454883f, .500000060f, .597545207f, .691341758f, .777785182f, .853553414f, - .915734828f, .961939812f, .990392685f, 1.00000000f, .990392625f, .961939752f, - .915734768f, .853553295f, .777785063f, .691341639f, .597545087f, .500000000f, - .402454853f, .308658272f, .222214878f, .146446615f, .084265172f, .038060218f, - .009607345f }, - { .038060248f, .146446645f, .308658302f, .500000060f, .691341758f, .853553414f, - .961939812f, 1.00000000f, .961939752f, .853553295f, .691341639f, .500000000f, - .308658272f, .146446615f, .038060218f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f }, - { .146446645f, .500000060f, .853553414f, 1.00000000f, .853553295f, .500000000f, - .146446615f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f }, - { .500000060f, 1.00000000f, .500000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, .000000000f, - .000000000f } -}; - -static const float sb_noise_attenuation[32] = { - 0.0f, 0.0f, 0.3f, 0.4f, 0.5f, 0.7f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -}; - -static const uint8_t fft_subpackets[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 -}; - -/* first index is joined_stereo, second index is 0 or 2 (1 is unused) */ -static const float dequant_1bit[2][3] = { - {-0.920000f, 0.000000f, 0.920000f }, - {-0.890000f, 0.000000f, 0.890000f } -}; - -static const float type30_dequant[8] = { - -1.0f,-0.625f,-0.291666656732559f,0.0f, - 0.25f,0.5f,0.75f,1.0f, -}; - -static const float type34_delta[10] = { // FIXME: covers 8 entries.. - -1.0f,-0.60947573184967f,-0.333333343267441f,-0.138071194291115f,0.0f, - 0.138071194291115f,0.333333343267441f,0.60947573184967f,1.0f,0.0f, -}; - -#endif /* AVCODEC_QDM2DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/qdrw.c b/tizen/distrib/ffmpeg/libavcodec/qdrw.c deleted file mode 100644 index 5750058..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qdrw.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * QuickDraw (qdrw) codec - * Copyright (c) 2004 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Apple QuickDraw codec. - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct QdrawContext{ - AVCodecContext *avctx; - AVFrame pic; -} QdrawContext; - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - QdrawContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; - uint8_t* outdata; - int colors; - int i; - uint32_t *pal; - int r, g, b; - - 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= FF_I_TYPE; - p->key_frame= 1; - - outdata = a->pic.data[0]; - - buf += 0x68; /* jump to palette */ - colors = AV_RB32(buf); - buf += 4; - - if(colors < 0 || colors > 256) { - av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); - return -1; - } - - pal = (uint32_t*)p->data[1]; - for (i = 0; i <= colors; i++) { - unsigned int idx; - idx = AV_RB16(buf); /* color index */ - buf += 2; - - if (idx > 255) { - av_log(avctx, AV_LOG_ERROR, "Palette index out of range: %u\n", idx); - buf += 6; - continue; - } - r = *buf++; - buf++; - g = *buf++; - buf++; - b = *buf++; - buf++; - pal[idx] = (r << 16) | (g << 8) | b; - } - p->palette_has_changed = 1; - - buf += 18; /* skip unneeded data */ - for (i = 0; i < avctx->height; i++) { - int size, left, code, pix; - const uint8_t *next; - uint8_t *out; - int tsize = 0; - - /* decode line */ - out = outdata; - size = AV_RB16(buf); /* size of packed line */ - buf += 2; - left = size; - next = buf + size; - while (left > 0) { - code = *buf++; - if (code & 0x80 ) { /* run */ - pix = *buf++; - if ((out + (257 - code)) > (outdata + a->pic.linesize[0])) - break; - memset(out, pix, 257 - code); - out += 257 - code; - tsize += 257 - code; - left -= 2; - } else { /* copy */ - if ((out + code) > (outdata + a->pic.linesize[0])) - break; - memcpy(out, buf, code + 1); - out += code + 1; - buf += code + 1; - left -= 2 + code; - tsize += code + 1; - } - } - buf = next; - outdata += a->pic.linesize[0]; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = a->pic; - - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx){ -// QdrawContext * const a = avctx->priv_data; - - avctx->pix_fmt= PIX_FMT_PAL8; - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - QdrawContext * const a = avctx->priv_data; - AVFrame *pic = &a->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - -AVCodec qdraw_decoder = { - "qdraw", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_QDRAW, - sizeof(QdrawContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/qpeg.c b/tizen/distrib/ffmpeg/libavcodec/qpeg.c deleted file mode 100644 index e6a0b30..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qpeg.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * QPEG codec - * Copyright (c) 2004 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QPEG codec. - */ - -#include "avcodec.h" - -typedef struct QpegContext{ - AVCodecContext *avctx; - AVFrame pic; - uint8_t *refdata; -} QpegContext; - -static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size, - int stride, int width, int height) -{ - int i; - int code; - int c0, c1; - int run, copy; - int filled = 0; - int rows_to_go; - - rows_to_go = height; - height--; - dst = dst + height * stride; - - while((size > 0) && (rows_to_go > 0)) { - code = *src++; - size--; - run = copy = 0; - if(code == 0xFC) /* end-of-picture code */ - break; - if(code >= 0xF8) { /* very long run */ - c0 = *src++; - c1 = *src++; - size -= 2; - run = ((code & 0x7) << 16) + (c0 << 8) + c1 + 2; - } else if (code >= 0xF0) { /* long run */ - c0 = *src++; - size--; - run = ((code & 0xF) << 8) + c0 + 2; - } else if (code >= 0xE0) { /* short run */ - run = (code & 0x1F) + 2; - } else if (code >= 0xC0) { /* very long copy */ - c0 = *src++; - c1 = *src++; - size -= 2; - copy = ((code & 0x3F) << 16) + (c0 << 8) + c1 + 1; - } else if (code >= 0x80) { /* long copy */ - c0 = *src++; - size--; - copy = ((code & 0x7F) << 8) + c0 + 1; - } else { /* short copy */ - copy = code + 1; - } - - /* perform actual run or copy */ - if(run) { - int p; - - p = *src++; - size--; - for(i = 0; i < run; i++) { - dst[filled++] = p; - if (filled >= width) { - filled = 0; - dst -= stride; - rows_to_go--; - if(rows_to_go <= 0) - break; - } - } - } else { - size -= copy; - for(i = 0; i < copy; i++) { - dst[filled++] = *src++; - if (filled >= width) { - filled = 0; - dst -= stride; - rows_to_go--; - if(rows_to_go <= 0) - break; - } - } - } - } -} - -static const int qpeg_table_h[16] = - { 0x00, 0x20, 0x20, 0x20, 0x18, 0x10, 0x10, 0x20, 0x10, 0x08, 0x18, 0x08, 0x08, 0x18, 0x10, 0x04}; -static const int qpeg_table_w[16] = - { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04}; - -/* Decodes delta frames */ -static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, - int stride, int width, int height, - int delta, const uint8_t *ctable, uint8_t *refdata) -{ - int i, j; - int code; - int filled = 0; - int orig_height; - - /* copy prev frame */ - for(i = 0; i < height; i++) - memcpy(refdata + (i * width), dst + (i * stride), width); - - orig_height = height; - height--; - dst = dst + height * stride; - - while((size > 0) && (height >= 0)) { - code = *src++; - size--; - - if(delta) { - /* motion compensation */ - while((code & 0xF0) == 0xF0) { - if(delta == 1) { - int me_idx; - int me_w, me_h, me_x, me_y; - uint8_t *me_plane; - int corr, val; - - /* get block size by index */ - me_idx = code & 0xF; - me_w = qpeg_table_w[me_idx]; - me_h = qpeg_table_h[me_idx]; - - /* extract motion vector */ - corr = *src++; - size--; - - val = corr >> 4; - if(val > 7) - val -= 16; - me_x = val; - - val = corr & 0xF; - if(val > 7) - val -= 16; - me_y = val; - - /* check motion vector */ - if ((me_x + filled < 0) || (me_x + me_w + filled > width) || - (height - me_y - me_h < 0) || (height - me_y > orig_height) || - (filled + me_w > width) || (height - me_h < 0)) - av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", - me_x, me_y, me_w, me_h, filled, height); - else { - /* do motion compensation */ - me_plane = refdata + (filled + me_x) + (height - me_y) * width; - for(j = 0; j < me_h; j++) { - for(i = 0; i < me_w; i++) - dst[filled + i - (j * stride)] = me_plane[i - (j * width)]; - } - } - } - code = *src++; - size--; - } - } - - if(code == 0xE0) /* end-of-picture code */ - break; - if(code > 0xE0) { /* run code: 0xE1..0xFF */ - int p; - - code &= 0x1F; - p = *src++; - size--; - for(i = 0; i <= code; i++) { - dst[filled++] = p; - if(filled >= width) { - filled = 0; - dst -= stride; - height--; - } - } - } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */ - code &= 0x1F; - - for(i = 0; i <= code; i++) { - dst[filled++] = *src++; - if(filled >= width) { - filled = 0; - dst -= stride; - height--; - } - } - size -= code + 1; - } else if(code >= 0x80) { /* skip code: 0x80..0xBF */ - int skip; - - code &= 0x3F; - /* codes 0x80 and 0x81 are actually escape codes, - skip value minus constant is in the next byte */ - if(!code) - skip = (*src++) + 64; - else if(code == 1) - skip = (*src++) + 320; - else - skip = code; - filled += skip; - while( filled >= width) { - filled -= width; - dst -= stride; - height--; - if(height < 0) - break; - } - } else { - /* zero code treated as one-pixel skip */ - if(code) - dst[filled++] = ctable[code & 0x7F]; - else - filled++; - if(filled >= width) { - filled = 0; - dst -= stride; - height--; - } - } - } -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - QpegContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; - uint8_t* outdata; - int delta; - - 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; - } - outdata = a->pic.data[0]; - if(buf[0x85] == 0x10) { - qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height); - } else { - delta = buf[0x85]; - qpeg_decode_inter(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height, delta, buf + 4, a->refdata); - } - - /* make the palette available on the way out */ - memcpy(a->pic.data[1], a->avctx->palctrl->palette, AVPALETTE_SIZE); - if (a->avctx->palctrl->palette_changed) { - a->pic.palette_has_changed = 1; - a->avctx->palctrl->palette_changed = 0; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = a->pic; - - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - QpegContext * const a = avctx->priv_data; - - if (!avctx->palctrl) { - av_log(avctx, AV_LOG_FATAL, "Missing required palette via palctrl\n"); - return -1; - } - a->avctx = avctx; - avctx->pix_fmt= PIX_FMT_PAL8; - a->refdata = av_malloc(avctx->width * avctx->height); - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - QpegContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; - - if(p->data[0]) - avctx->release_buffer(avctx, p); - - av_free(a->refdata); - return 0; -} - -AVCodec qpeg_decoder = { - "qpeg", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_QPEG, - sizeof(QpegContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Q-team QPEG"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/qtrle.c b/tizen/distrib/ffmpeg/libavcodec/qtrle.c deleted file mode 100644 index 1fd9a80..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qtrle.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Quicktime Animation (RLE) Video Decoder - * Copyright (C) 2004 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the QT RLE format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * The QT RLE decoder has seven modes of operation: - * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8 - * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555 - * data. 24-bit data is RGB24 and 32-bit data is RGB32. - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct QtrleContext { - - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *buf; - int size; - -} QtrleContext; - -#define CHECK_STREAM_PTR(n) \ - if ((stream_ptr + n) > s->size) { \ - av_log (s->avctx, AV_LOG_INFO, "Problem: stream_ptr out of bounds (%d >= %d)\n", \ - stream_ptr + n, s->size); \ - return; \ - } - -#define CHECK_PIXEL_PTR(n) \ - if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \ - av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \ - pixel_ptr + n, pixel_limit); \ - return; \ - } \ - -static void qtrle_decode_1bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) -{ - int rle_code; - int pixel_ptr = 0; - int row_inc = s->frame.linesize[0]; - unsigned char pi0, pi1; /* 2 8-pixel values */ - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; - int skip; - - while (lines_to_change) { - CHECK_STREAM_PTR(2); - skip = s->buf[stream_ptr++]; - rle_code = (signed char)s->buf[stream_ptr++]; - if (rle_code == 0) - break; - if(skip & 0x80) { - lines_to_change--; - row_ptr += row_inc; - pixel_ptr = row_ptr + 2 * (skip & 0x7f); - } else - pixel_ptr += 2 * skip; - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ - - if (rle_code < 0) { - /* decode the run length code */ - rle_code = -rle_code; - /* get the next 2 bytes from the stream, treat them as groups - * of 8 pixels, and output them rle_code times */ - CHECK_STREAM_PTR(2); - pi0 = s->buf[stream_ptr++]; - pi1 = s->buf[stream_ptr++]; - CHECK_PIXEL_PTR(rle_code * 2); - - while (rle_code--) { - rgb[pixel_ptr++] = pi0; - rgb[pixel_ptr++] = pi1; - } - } else { - /* copy the same pixel directly to output 2 times */ - rle_code *= 2; - CHECK_STREAM_PTR(rle_code); - CHECK_PIXEL_PTR(rle_code); - - while (rle_code--) - rgb[pixel_ptr++] = s->buf[stream_ptr++]; - } - } -} - -static inline void qtrle_decode_2n4bpp(QtrleContext *s, int stream_ptr, - int row_ptr, int lines_to_change, int bpp) -{ - int rle_code, i; - int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char pi[16]; /* 16 palette indices */ - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; - int num_pixels = (bpp == 4) ? 8 : 16; - - while (lines_to_change--) { - CHECK_STREAM_PTR(2); - pixel_ptr = row_ptr + (num_pixels * (s->buf[stream_ptr++] - 1)); - - while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { - if (rle_code == 0) { - /* there's another skip code in the stream */ - CHECK_STREAM_PTR(1); - pixel_ptr += (num_pixels * (s->buf[stream_ptr++] - 1)); - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ - } else if (rle_code < 0) { - /* decode the run length code */ - rle_code = -rle_code; - /* get the next 4 bytes from the stream, treat them as palette - * indexes, and output them rle_code times */ - CHECK_STREAM_PTR(4); - for (i = num_pixels-1; i >= 0; i--) { - pi[num_pixels-1-i] = (s->buf[stream_ptr] >> ((i*bpp) & 0x07)) & ((1<>2)-1)) == 0); - } - CHECK_PIXEL_PTR(rle_code * num_pixels); - while (rle_code--) { - for (i = 0; i < num_pixels; i++) - rgb[pixel_ptr++] = pi[i]; - } - } else { - /* copy the same pixel directly to output 4 times */ - rle_code *= 4; - CHECK_STREAM_PTR(rle_code); - CHECK_PIXEL_PTR(rle_code*(num_pixels>>2)); - while (rle_code--) { - if(bpp == 4) { - rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x0f; - rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x0f; - } else { - rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 6) & 0x03; - rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x03; - rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 2) & 0x03; - rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x03; - } - } - } - } - row_ptr += row_inc; - } -} - -static void qtrle_decode_8bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) -{ - int rle_code; - int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char pi1, pi2, pi3, pi4; /* 4 palette indexes */ - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; - - while (lines_to_change--) { - CHECK_STREAM_PTR(2); - pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1)); - - while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { - if (rle_code == 0) { - /* there's another skip code in the stream */ - CHECK_STREAM_PTR(1); - pixel_ptr += (4 * (s->buf[stream_ptr++] - 1)); - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ - } else if (rle_code < 0) { - /* decode the run length code */ - rle_code = -rle_code; - /* get the next 4 bytes from the stream, treat them as palette - * indexes, and output them rle_code times */ - CHECK_STREAM_PTR(4); - pi1 = s->buf[stream_ptr++]; - pi2 = s->buf[stream_ptr++]; - pi3 = s->buf[stream_ptr++]; - pi4 = s->buf[stream_ptr++]; - - CHECK_PIXEL_PTR(rle_code * 4); - - while (rle_code--) { - rgb[pixel_ptr++] = pi1; - rgb[pixel_ptr++] = pi2; - rgb[pixel_ptr++] = pi3; - rgb[pixel_ptr++] = pi4; - } - } else { - /* copy the same pixel directly to output 4 times */ - rle_code *= 4; - CHECK_STREAM_PTR(rle_code); - CHECK_PIXEL_PTR(rle_code); - - while (rle_code--) { - rgb[pixel_ptr++] = s->buf[stream_ptr++]; - } - } - } - row_ptr += row_inc; - } -} - -static void qtrle_decode_16bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) -{ - int rle_code; - int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned short rgb16; - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; - - while (lines_to_change--) { - CHECK_STREAM_PTR(2); - pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2; - - while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { - if (rle_code == 0) { - /* there's another skip code in the stream */ - CHECK_STREAM_PTR(1); - pixel_ptr += (s->buf[stream_ptr++] - 1) * 2; - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ - } else if (rle_code < 0) { - /* decode the run length code */ - rle_code = -rle_code; - CHECK_STREAM_PTR(2); - rgb16 = AV_RB16(&s->buf[stream_ptr]); - stream_ptr += 2; - - CHECK_PIXEL_PTR(rle_code * 2); - - while (rle_code--) { - *(unsigned short *)(&rgb[pixel_ptr]) = rgb16; - pixel_ptr += 2; - } - } else { - CHECK_STREAM_PTR(rle_code * 2); - CHECK_PIXEL_PTR(rle_code * 2); - - /* copy pixels directly to output */ - while (rle_code--) { - rgb16 = AV_RB16(&s->buf[stream_ptr]); - stream_ptr += 2; - *(unsigned short *)(&rgb[pixel_ptr]) = rgb16; - pixel_ptr += 2; - } - } - } - row_ptr += row_inc; - } -} - -static void qtrle_decode_24bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) -{ - int rle_code; - int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char r, g, b; - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; - - while (lines_to_change--) { - CHECK_STREAM_PTR(2); - pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3; - - while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { - if (rle_code == 0) { - /* there's another skip code in the stream */ - CHECK_STREAM_PTR(1); - pixel_ptr += (s->buf[stream_ptr++] - 1) * 3; - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ - } else if (rle_code < 0) { - /* decode the run length code */ - rle_code = -rle_code; - CHECK_STREAM_PTR(3); - r = s->buf[stream_ptr++]; - g = s->buf[stream_ptr++]; - b = s->buf[stream_ptr++]; - - CHECK_PIXEL_PTR(rle_code * 3); - - while (rle_code--) { - rgb[pixel_ptr++] = r; - rgb[pixel_ptr++] = g; - rgb[pixel_ptr++] = b; - } - } else { - CHECK_STREAM_PTR(rle_code * 3); - CHECK_PIXEL_PTR(rle_code * 3); - - /* copy pixels directly to output */ - while (rle_code--) { - rgb[pixel_ptr++] = s->buf[stream_ptr++]; - rgb[pixel_ptr++] = s->buf[stream_ptr++]; - rgb[pixel_ptr++] = s->buf[stream_ptr++]; - } - } - } - row_ptr += row_inc; - } -} - -static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) -{ - int rle_code; - int pixel_ptr; - int row_inc = s->frame.linesize[0]; - unsigned char a, r, g, b; - unsigned int argb; - unsigned char *rgb = s->frame.data[0]; - int pixel_limit = s->frame.linesize[0] * s->avctx->height; - - while (lines_to_change--) { - CHECK_STREAM_PTR(2); - pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4; - - while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { - if (rle_code == 0) { - /* there's another skip code in the stream */ - CHECK_STREAM_PTR(1); - pixel_ptr += (s->buf[stream_ptr++] - 1) * 4; - CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ - } else if (rle_code < 0) { - /* decode the run length code */ - rle_code = -rle_code; - CHECK_STREAM_PTR(4); - a = s->buf[stream_ptr++]; - r = s->buf[stream_ptr++]; - g = s->buf[stream_ptr++]; - b = s->buf[stream_ptr++]; - argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); - - CHECK_PIXEL_PTR(rle_code * 4); - - while (rle_code--) { - *(unsigned int *)(&rgb[pixel_ptr]) = argb; - pixel_ptr += 4; - } - } else { - CHECK_STREAM_PTR(rle_code * 4); - CHECK_PIXEL_PTR(rle_code * 4); - - /* copy pixels directly to output */ - while (rle_code--) { - a = s->buf[stream_ptr++]; - r = s->buf[stream_ptr++]; - g = s->buf[stream_ptr++]; - b = s->buf[stream_ptr++]; - argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); - *(unsigned int *)(&rgb[pixel_ptr]) = argb; - pixel_ptr += 4; - } - } - } - row_ptr += row_inc; - } -} - -static av_cold int qtrle_decode_init(AVCodecContext *avctx) -{ - QtrleContext *s = avctx->priv_data; - - s->avctx = avctx; - switch (avctx->bits_per_coded_sample) { - case 1: - case 33: - avctx->pix_fmt = PIX_FMT_MONOWHITE; - break; - - case 2: - case 4: - case 8: - case 34: - case 36: - case 40: - avctx->pix_fmt = PIX_FMT_PAL8; - break; - - case 16: - avctx->pix_fmt = PIX_FMT_RGB555; - break; - - case 24: - avctx->pix_fmt = PIX_FMT_RGB24; - break; - - case 32: - avctx->pix_fmt = PIX_FMT_RGB32; - break; - - default: - av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", - avctx->bits_per_coded_sample); - break; - } - - s->frame.data[0] = NULL; - - return 0; -} - -static int qtrle_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - QtrleContext *s = avctx->priv_data; - int header, start_line; - int stream_ptr, height, row_ptr; - int has_palette = 0; - - s->buf = 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 | FF_BUFFER_HINTS_READABLE; - if (avctx->reget_buffer(avctx, &s->frame)) { - av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - - /* check if this frame is even supposed to change */ - if (s->size < 8) - goto done; - - /* start after the chunk size */ - stream_ptr = 4; - - /* fetch the header */ - header = AV_RB16(&s->buf[stream_ptr]); - stream_ptr += 2; - - /* if a header is present, fetch additional decoding parameters */ - if (header & 0x0008) { - if(s->size < 14) - goto done; - start_line = AV_RB16(&s->buf[stream_ptr]); - stream_ptr += 4; - height = AV_RB16(&s->buf[stream_ptr]); - stream_ptr += 4; - } else { - start_line = 0; - height = s->avctx->height; - } - row_ptr = s->frame.linesize[0] * start_line; - - switch (avctx->bits_per_coded_sample) { - case 1: - case 33: - qtrle_decode_1bpp(s, stream_ptr, row_ptr, height); - break; - - case 2: - case 34: - qtrle_decode_2n4bpp(s, stream_ptr, row_ptr, height, 2); - has_palette = 1; - break; - - case 4: - case 36: - qtrle_decode_2n4bpp(s, stream_ptr, row_ptr, height, 4); - has_palette = 1; - break; - - case 8: - case 40: - qtrle_decode_8bpp(s, stream_ptr, row_ptr, height); - has_palette = 1; - break; - - case 16: - qtrle_decode_16bpp(s, stream_ptr, row_ptr, height); - break; - - case 24: - qtrle_decode_24bpp(s, stream_ptr, row_ptr, height); - break; - - case 32: - qtrle_decode_32bpp(s, stream_ptr, row_ptr, height); - break; - - default: - av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", - avctx->bits_per_coded_sample); - break; - } - - if(has_palette) { - /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); - if (s->avctx->palctrl->palette_changed) { - s->frame.palette_has_changed = 1; - s->avctx->palctrl->palette_changed = 0; - } - } - -done: - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int qtrle_decode_end(AVCodecContext *avctx) -{ - QtrleContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec qtrle_decoder = { - "qtrle", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_QTRLE, - sizeof(QtrleContext), - qtrle_decode_init, - NULL, - qtrle_decode_end, - qtrle_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/qtrleenc.c b/tizen/distrib/ffmpeg/libavcodec/qtrleenc.c deleted file mode 100644 index 7f95c7f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/qtrleenc.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Quicktime Animation (RLE) Video Encoder - * Copyright (C) 2007 Clemens Fruhwirth - * Copyright (C) 2007 Alexis Ballier - * - * This file is based on flashsvenc.c. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" - -/** Maximum RLE code for bulk copy */ -#define MAX_RLE_BULK 127 -/** Maximum RLE code for repeat */ -#define MAX_RLE_REPEAT 128 -/** Maximum RLE code for skip */ -#define MAX_RLE_SKIP 254 - -typedef struct QtrleEncContext { - AVCodecContext *avctx; - AVFrame frame; - int pixel_size; - AVPicture previous_frame; - unsigned int max_buf_size; - /** - * This array will contain at ith position the value of the best RLE code - * if the line started at pixel i - * There can be 3 values : - * skip (0) : skip as much as possible pixels because they are equal to the - * previous frame ones - * repeat (<-1) : repeat that pixel -rle_code times, still as much as - * possible - * copy (>0) : copy the raw next rle_code pixels */ - signed char *rlecode_table; - /** - * This array will contain the length of the best rle encoding of the line - * starting at ith pixel */ - int *length_table; - /** - * Will contain at ith position the number of consecutive pixels equal to the previous - * frame starting from pixel i */ - uint8_t* skip_table; -} QtrleEncContext; - -static av_cold int qtrle_encode_init(AVCodecContext *avctx) -{ - QtrleEncContext *s = avctx->priv_data; - - if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { - return -1; - } - s->avctx=avctx; - - switch (avctx->pix_fmt) { - case PIX_FMT_RGB555BE: - s->pixel_size = 2; - break; - case PIX_FMT_RGB24: - s->pixel_size = 3; - break; - case PIX_FMT_ARGB: - s->pixel_size = 4; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n"); - break; - } - avctx->bits_per_coded_sample = s->pixel_size*8; - - s->rlecode_table = av_mallocz(s->avctx->width); - s->skip_table = av_mallocz(s->avctx->width); - s->length_table = av_mallocz((s->avctx->width + 1)*sizeof(int)); - if (!s->skip_table || !s->length_table || !s->rlecode_table) { - av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n"); - return -1; - } - if (avpicture_alloc(&s->previous_frame, avctx->pix_fmt, avctx->width, avctx->height) < 0) { - av_log(avctx, AV_LOG_ERROR, "Error allocating picture\n"); - return -1; - } - - s->max_buf_size = s->avctx->width*s->avctx->height*s->pixel_size /* image base material */ - + 15 /* header + footer */ - + s->avctx->height*2 /* skip code+rle end */ - + s->avctx->width/MAX_RLE_BULK + 1 /* rle codes */; - avctx->coded_frame = &s->frame; - return 0; -} - -/** - * Computes the best RLE sequence for a line - */ -static void qtrle_encode_line(QtrleEncContext *s, AVFrame *p, int line, uint8_t **buf) -{ - int width=s->avctx->width; - int i; - signed char rlecode; - - /* We will use it to compute the best bulk copy sequence */ - unsigned int bulkcount; - /* This will be the number of pixels equal to the preivous frame one's - * starting from the ith pixel */ - unsigned int skipcount; - /* This will be the number of consecutive equal pixels in the current - * frame, starting from the ith one also */ - unsigned int av_uninit(repeatcount); - - /* The cost of the three different possibilities */ - int total_bulk_cost; - int total_skip_cost; - int total_repeat_cost; - - int temp_cost; - int j; - - uint8_t *this_line = p-> data[0] + line*p-> linesize[0] + - (width - 1)*s->pixel_size; - uint8_t *prev_line = s->previous_frame.data[0] + line*s->previous_frame.linesize[0] + - (width - 1)*s->pixel_size; - - s->length_table[width] = 0; - skipcount = 0; - - for (i = width - 1; i >= 0; i--) { - - if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size)) - skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP); - else - skipcount = 0; - - total_skip_cost = s->length_table[i + skipcount] + 2; - s->skip_table[i] = skipcount; - - - if (i < width - 1 && !memcmp(this_line, this_line + s->pixel_size, s->pixel_size)) - repeatcount = FFMIN(repeatcount + 1, MAX_RLE_REPEAT); - else - repeatcount = 1; - - total_repeat_cost = s->length_table[i + repeatcount] + 1 + s->pixel_size; - - /* skip code is free for the first pixel, it costs one byte for repeat and bulk copy - * so let's make it aware */ - if (i == 0) { - total_skip_cost--; - total_repeat_cost++; - } - - if (repeatcount > 1 && (skipcount == 0 || total_repeat_cost < total_skip_cost)) { - /* repeat is the best */ - s->length_table[i] = total_repeat_cost; - s->rlecode_table[i] = -repeatcount; - } - else if (skipcount > 0) { - /* skip is the best choice here */ - s->length_table[i] = total_skip_cost; - s->rlecode_table[i] = 0; - } - else { - /* We cannot do neither skip nor repeat - * thus we search for the best bulk copy to do */ - - int limit = FFMIN(width - i, MAX_RLE_BULK); - - temp_cost = 1 + s->pixel_size + !i; - total_bulk_cost = INT_MAX; - - for (j = 1; j <= limit; j++) { - if (s->length_table[i + j] + temp_cost < total_bulk_cost) { - /* We have found a better bulk copy ... */ - total_bulk_cost = s->length_table[i + j] + temp_cost; - bulkcount = j; - } - temp_cost += s->pixel_size; - } - - s->length_table[i] = total_bulk_cost; - s->rlecode_table[i] = bulkcount; - } - - this_line -= s->pixel_size; - prev_line -= s->pixel_size; - } - - /* Good ! Now we have the best sequence for this line, let's ouput it */ - - /* We do a special case for the first pixel so that we avoid testing it in - * the whole loop */ - - i=0; - this_line = p-> data[0] + line*p->linesize[0]; - - if (s->rlecode_table[0] == 0) { - bytestream_put_byte(buf, s->skip_table[0] + 1); - i += s->skip_table[0]; - } - else bytestream_put_byte(buf, 1); - - - while (i < width) { - rlecode = s->rlecode_table[i]; - bytestream_put_byte(buf, rlecode); - if (rlecode == 0) { - /* Write a skip sequence */ - bytestream_put_byte(buf, s->skip_table[i] + 1); - i += s->skip_table[i]; - } - else if (rlecode > 0) { - /* bulk copy */ - bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size); - i += rlecode; - } - else { - /* repeat the bits */ - bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size); - i -= rlecode; - } - } - bytestream_put_byte(buf, -1); // end RLE line -} - -/** Encodes frame including header */ -static int encode_frame(QtrleEncContext *s, AVFrame *p, uint8_t *buf) -{ - int i; - int start_line = 0; - int end_line = s->avctx->height; - uint8_t *orig_buf = buf; - - if (!s->frame.key_frame) { - unsigned line_size = s->avctx->width * s->pixel_size; - for (start_line = 0; start_line < s->avctx->height; start_line++) - if (memcmp(p->data[0] + start_line*p->linesize[0], - s->previous_frame.data[0] + start_line*s->previous_frame.linesize[0], - line_size)) - break; - - for (end_line=s->avctx->height; end_line > start_line; end_line--) - if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0], - s->previous_frame.data[0] + (end_line - 1)*s->previous_frame.linesize[0], - line_size)) - break; - } - - bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later - - if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height) - bytestream_put_be16(&buf, 0); // header - else { - bytestream_put_be16(&buf, 8); // header - bytestream_put_be16(&buf, start_line); // starting line - bytestream_put_be16(&buf, 0); // unknown - bytestream_put_be16(&buf, end_line - start_line); // lines to update - bytestream_put_be16(&buf, 0); // unknown - } - for (i = start_line; i < end_line; i++) - qtrle_encode_line(s, p, i, &buf); - - bytestream_put_byte(&buf, 0); // zero skip code = frame finished - AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size - return buf - orig_buf; -} - -static int qtrle_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) -{ - QtrleEncContext * const s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p = &s->frame; - int chunksize; - - *p = *pict; - - if (buf_size < s->max_buf_size) { - /* Upper bound check for compressed data */ - av_log(avctx, AV_LOG_ERROR, "buf_size %d < %d\n", buf_size, s->max_buf_size); - return -1; - } - - if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) { - /* I-Frame */ - p->pict_type = FF_I_TYPE; - p->key_frame = 1; - } else { - /* P-Frame */ - p->pict_type = FF_P_TYPE; - p->key_frame = 0; - } - - chunksize = encode_frame(s, pict, buf); - - /* save the current frame */ - av_picture_copy(&s->previous_frame, (AVPicture *)p, avctx->pix_fmt, avctx->width, avctx->height); - return chunksize; -} - -static av_cold int qtrle_encode_end(AVCodecContext *avctx) -{ - QtrleEncContext *s = avctx->priv_data; - - avpicture_free(&s->previous_frame); - av_free(s->rlecode_table); - av_free(s->length_table); - av_free(s->skip_table); - return 0; -} - -AVCodec qtrle_encoder = { - "qtrle", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_QTRLE, - sizeof(QtrleEncContext), - qtrle_encode_init, - qtrle_encode_frame, - qtrle_encode_end, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB555BE, PIX_FMT_ARGB, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/r210dec.c b/tizen/distrib/ffmpeg/libavcodec/r210dec.c deleted file mode 100644 index 416f764..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/r210dec.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * R210 decoder - * - * Copyright (c) 2009 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "libavutil/bswap.h" - -static av_cold int decode_init(AVCodecContext *avctx) -{ - avctx->pix_fmt = PIX_FMT_RGB48; - avctx->bits_per_raw_sample = 10; - - avctx->coded_frame = avcodec_alloc_frame(); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - int h, w; - AVFrame *pic = avctx->coded_frame; - const uint32_t *src = (const uint32_t *)avpkt->data; - int aligned_width = FFALIGN(avctx->width, 64); - uint8_t *dst_line; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - if (avpkt->size < 4 * aligned_width * avctx->height) { - av_log(avctx, AV_LOG_ERROR, "packet too small\n"); - return -1; - } - - pic->reference = 0; - if (avctx->get_buffer(avctx, pic) < 0) - return -1; - - pic->pict_type = FF_I_TYPE; - pic->key_frame = 1; - dst_line = pic->data[0]; - - for (h = 0; h < avctx->height; h++) { - uint16_t *dst = (uint16_t *)dst_line; - for (w = 0; w < avctx->width; w++) { - uint32_t pixel = be2me_32(*src++); - uint16_t r, g, b; - b = pixel << 6; - g = (pixel >> 4) & 0xffc0; - r = (pixel >> 14) & 0xffc0; - *dst++ = r | (r >> 10); - *dst++ = g | (g >> 10); - *dst++ = b | (b >> 10); - } - src += aligned_width - avctx->width; - dst_line += pic->linesize[0]; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = *avctx->coded_frame; - - return avpkt->size; -} - -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - -AVCodec r210_decoder = { - "r210", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_R210, - 0, - decode_init, - NULL, - decode_close, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ra144.c b/tizen/distrib/ffmpeg/libavcodec/ra144.c deleted file mode 100644 index efa62c4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ra144.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Real Audio 1.0 (14.4K) - * - * Copyright (c) 2008 Vitor Sessak - * Copyright (c) 2003 Nick Kurshev - * Based on public domain decoder at http://www.honeypot.net/audio - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intmath.h" -#include "avcodec.h" -#include "get_bits.h" -#include "ra144.h" -#include "celp_filters.h" - -#define NBLOCKS 4 ///< number of subblocks within a block -#define BLOCKSIZE 40 ///< subblock size in 16-bit words -#define BUFFERSIZE 146 ///< the size of the adaptive codebook - - -typedef struct { - AVCodecContext *avctx; - - unsigned int old_energy; ///< previous frame energy - - unsigned int lpc_tables[2][10]; - - /** LPC coefficients: lpc_coef[0] is the coefficients of the current frame - * and lpc_coef[1] of the previous one. */ - unsigned int *lpc_coef[2]; - - unsigned int lpc_refl_rms[2]; - - /** The current subblock padded by the last 10 values of the previous one. */ - int16_t curr_sblock[50]; - - /** Adaptive codebook, its size is two units bigger to avoid a - * buffer overflow. */ - uint16_t adapt_cb[146+2]; -} RA144Context; - -static av_cold int ra144_decode_init(AVCodecContext * avctx) -{ - RA144Context *ractx = avctx->priv_data; - - ractx->avctx = avctx; - - ractx->lpc_coef[0] = ractx->lpc_tables[0]; - ractx->lpc_coef[1] = ractx->lpc_tables[1]; - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -/** - * Evaluate sqrt(x << 24). x must fit in 20 bits. This value is evaluated in an - * odd way to make the output identical to the binary decoder. - */ -static int t_sqrt(unsigned int x) -{ - int s = 2; - while (x > 0xfff) { - s++; - x >>= 2; - } - - return ff_sqrt(x << 20) << s; -} - -/** - * Evaluate the LPC filter coefficients from the reflection coefficients. - * Does the inverse of the eval_refl() function. - */ -static void eval_coefs(int *coefs, const int *refl) -{ - int buffer[10]; - int *b1 = buffer; - int *b2 = coefs; - int i, j; - - for (i=0; i < 10; i++) { - b1[i] = refl[i] << 4; - - for (j=0; j < i; j++) - b1[j] = ((refl[i] * b2[i-j-1]) >> 12) + b2[j]; - - FFSWAP(int *, b1, b2); - } - - for (i=0; i < 10; i++) - coefs[i] >>= 4; -} - -/** - * Copy the last offset values of *source to *target. If those values are not - * enough to fill the target buffer, fill it with another copy of those values. - */ -static void copy_and_dup(int16_t *target, const int16_t *source, int offset) -{ - source += BUFFERSIZE - offset; - - memcpy(target, source, FFMIN(BLOCKSIZE, offset)*sizeof(*target)); - if (offset < BLOCKSIZE) - memcpy(target + offset, source, (BLOCKSIZE - offset)*sizeof(*target)); -} - -/** inverse root mean square */ -static int irms(const int16_t *data) -{ - unsigned int i, sum = 0; - - for (i=0; i < BLOCKSIZE; i++) - sum += data[i] * data[i]; - - if (sum == 0) - return 0; /* OOPS - division by zero */ - - return 0x20000000 / (t_sqrt(sum) >> 8); -} - -static void add_wav(int16_t *dest, int n, int skip_first, int *m, - const int16_t *s1, const int8_t *s2, const int8_t *s3) -{ - int i; - int v[3]; - - v[0] = 0; - for (i=!skip_first; i<3; i++) - v[i] = (gain_val_tab[n][i] * m[i]) >> gain_exp_tab[n]; - - if (v[0]) { - for (i=0; i < BLOCKSIZE; i++) - dest[i] = (s1[i]*v[0] + s2[i]*v[1] + s3[i]*v[2]) >> 12; - } else { - for (i=0; i < BLOCKSIZE; i++) - dest[i] = ( s2[i]*v[1] + s3[i]*v[2]) >> 12; - } -} - -static unsigned int rescale_rms(unsigned int rms, unsigned int energy) -{ - return (rms * energy) >> 10; -} - -static unsigned int rms(const int *data) -{ - int i; - unsigned int res = 0x10000; - int b = 10; - - for (i=0; i < 10; i++) { - res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12; - - if (res == 0) - return 0; - - while (res <= 0x3fff) { - b++; - res <<= 2; - } - } - - return t_sqrt(res) >> b; -} - -static void do_output_subblock(RA144Context *ractx, const uint16_t *lpc_coefs, - int gval, GetBitContext *gb) -{ - uint16_t buffer_a[40]; - uint16_t *block; - int cba_idx = get_bits(gb, 7); // index of the adaptive CB, 0 if none - int gain = get_bits(gb, 8); - int cb1_idx = get_bits(gb, 7); - int cb2_idx = get_bits(gb, 7); - int m[3]; - - if (cba_idx) { - cba_idx += BLOCKSIZE/2 - 1; - copy_and_dup(buffer_a, ractx->adapt_cb, cba_idx); - m[0] = (irms(buffer_a) * gval) >> 12; - } else { - m[0] = 0; - } - - m[1] = (cb1_base[cb1_idx] * gval) >> 8; - m[2] = (cb2_base[cb2_idx] * gval) >> 8; - - memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE, - (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb)); - - block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE; - - add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL, - cb1_vects[cb1_idx], cb2_vects[cb2_idx]); - - memcpy(ractx->curr_sblock, ractx->curr_sblock + 40, - 10*sizeof(*ractx->curr_sblock)); - - if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + 10, lpc_coefs, - block, BLOCKSIZE, 10, 1, 0xfff)) - memset(ractx->curr_sblock, 0, 50*sizeof(*ractx->curr_sblock)); -} - -static void int_to_int16(int16_t *out, const int *inp) -{ - int i; - - for (i=0; i < 10; i++) - *out++ = *inp++; -} - -/** - * Evaluate the reflection coefficients from the filter coefficients. - * Does the inverse of the eval_coefs() function. - * - * @return 1 if one of the reflection coefficients is greater than - * 4095, 0 if not. - */ -static int eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx) -{ - int b, i, j; - int buffer1[10]; - int buffer2[10]; - int *bp1 = buffer1; - int *bp2 = buffer2; - - for (i=0; i < 10; i++) - buffer2[i] = coefs[i]; - - refl[9] = bp2[9]; - - if ((unsigned) bp2[9] + 0x1000 > 0x1fff) { - av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n"); - return 1; - } - - for (i=8; i >= 0; i--) { - b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12); - - if (!b) - b = -2; - - for (j=0; j <= i; j++) - bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * (0x1000000 / b)) >> 12; - - if ((unsigned) bp1[i] + 0x1000 > 0x1fff) - return 1; - - refl[i] = bp1[i]; - - FFSWAP(int *, bp1, bp2); - } - return 0; -} - -static int interp(RA144Context *ractx, int16_t *out, int a, - int copyold, int energy) -{ - int work[10]; - int b = NBLOCKS - a; - int i; - - // Interpolate block coefficients from the this frame's forth block and - // last frame's forth block. - for (i=0; i<10; i++) - out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2; - - if (eval_refl(work, out, ractx->avctx)) { - // The interpolated coefficients are unstable, copy either new or old - // coefficients. - int_to_int16(out, ractx->lpc_coef[copyold]); - return rescale_rms(ractx->lpc_refl_rms[copyold], energy); - } else { - return rescale_rms(rms(work), energy); - } -} - -/** Uncompress one block (20 bytes -> 160*2 bytes). */ -static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2}; - unsigned int refl_rms[4]; // RMS of the reflection coefficients - uint16_t block_coefs[4][10]; // LPC coefficients of each sub-block - unsigned int lpc_refl[10]; // LPC reflection coefficients of the frame - int i, j; - int16_t *data = vdata; - unsigned int energy; - - RA144Context *ractx = avctx->priv_data; - GetBitContext gb; - - if (*data_size < 2*160) - return -1; - - if(buf_size < 20) { - av_log(avctx, AV_LOG_ERROR, - "Frame too small (%d bytes). Truncated file?\n", buf_size); - *data_size = 0; - return buf_size; - } - init_get_bits(&gb, buf, 20 * 8); - - for (i=0; i<10; i++) - lpc_refl[i] = lpc_refl_cb[i][get_bits(&gb, sizes[i])]; - - eval_coefs(ractx->lpc_coef[0], lpc_refl); - ractx->lpc_refl_rms[0] = rms(lpc_refl); - - energy = energy_tab[get_bits(&gb, 5)]; - - refl_rms[0] = interp(ractx, block_coefs[0], 1, 1, ractx->old_energy); - refl_rms[1] = interp(ractx, block_coefs[1], 2, energy <= ractx->old_energy, - t_sqrt(energy*ractx->old_energy) >> 12); - refl_rms[2] = interp(ractx, block_coefs[2], 3, 0, energy); - refl_rms[3] = rescale_rms(ractx->lpc_refl_rms[0], energy); - - int_to_int16(block_coefs[3], ractx->lpc_coef[0]); - - for (i=0; i < 4; i++) { - do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb); - - for (j=0; j < BLOCKSIZE; j++) - *data++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2); - } - - ractx->old_energy = energy; - ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0]; - - FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]); - - *data_size = 2*160; - return 20; -} - -AVCodec ra_144_decoder = -{ - "real_144", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_RA_144, - sizeof(RA144Context), - ra144_decode_init, - NULL, - NULL, - ra144_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ra144.h b/tizen/distrib/ffmpeg/libavcodec/ra144.h deleted file mode 100644 index 4413530..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ra144.h +++ /dev/null @@ -1,1506 +0,0 @@ -/* - * Real Audio 1.0 (14.4K) - * Copyright (c) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_RA144_H -#define AVCODEC_RA144_H - -#include - -static const int16_t gain_val_tab[256][3] = { - { 541, 956, 768}, { 877, 581, 568}, { 675,1574, 635}, {1248,1464, 668}, - {1246, 839, 1394}, {2560,1386, 991}, { 925, 687, 608}, {2208, 797, 1144}, - { 535, 832, 799}, { 762, 605, 1154}, { 832,1122, 1003}, {1180, 687, 1176}, - {1292, 901, 732}, {1656, 689, 896}, {1750,1248, 848}, {2284, 942, 1022}, - { 824,1472, 643}, { 517, 765, 512}, { 562,1816, 1522}, { 694,1826, 2700}, - { 704, 524, 672}, {1442, 757, 2232}, { 884, 551, 1266}, {2232,1007, 1692}, - { 932, 746, 777}, {1132, 822, 926}, {1226, 771, 611}, {2948,1342, 1008}, - {1302, 594, 1158}, {1602, 636, 1128}, {3408, 910, 1438}, {1996, 614, 575}, - { 665, 935, 628}, { 631,1192, 829}, { 644, 926, 1052}, { 879, 988, 1226}, - { 941,2768, 2772}, { 565,1344, 2304}, { 547, 628, 740}, { 639, 532, 1074}, - { 955,1208, 598}, {1124,1160, 900}, {1206, 899, 1242}, { 746, 533, 624}, - {1458,1028, 735}, {1706,1102, 692}, {1898,1018, 1004}, {2176, 988, 735}, - {1578, 782, 1642}, { 897, 516, 754}, {2068, 702, 1656}, {2344, 818, 1526}, - { 907, 652, 592}, {1056, 652, 642}, {2124,1416, 780}, {2664,1250, 727}, - {1894, 727, 1108}, {2196, 657, 981}, {4840, 920, 1704}, {4992,1238, 983}, - {2420, 909, 1094}, {2760, 935, 1032}, {2800, 612, 853}, {3068, 832, 574}, - { 523,1796, 923}, { 722,1916, 1382}, {1226,1542, 928}, { 758, 757, 584}, - { 512,1134, 577}, { 615,1276, 698}, { 574,2568, 2356}, { 993,2728, 3512}, - { 539, 890, 913}, { 694, 928, 1088}, { 805, 600, 1360}, {2160, 951, 3128}, - { 816, 950, 590}, { 955, 847, 811}, {1094, 883, 556}, {1304, 888, 604}, - { 863,1170, 855}, {1023, 997, 1032}, { 932,1228, 1280}, { 627, 564, 573}, - { 876, 900, 1448}, {1030, 857, 1792}, {1294, 953, 1758}, {1612, 854, 1714}, - {1090,1166, 631}, {1314,1202, 751}, {1480, 905, 795}, {1682,1016, 568}, - {1494,1178, 983}, { 878, 613, 526}, {1728,1446, 779}, {2136,1348, 774}, - { 950, 649, 939}, {1180, 703, 899}, {1236, 527, 1158}, {1450, 647, 972}, - {1282, 647, 707}, {1460, 663, 644}, {1614, 572, 578}, {3516,1222, 821}, - {2668, 729, 1682}, {3128, 585, 1502}, {3208, 733, 976}, {6800, 871, 1416}, - {3480, 743, 1408}, {3764, 899, 1170}, {3772, 632, 875}, {4092, 732, 638}, - {3112, 753, 2620}, {3372, 945, 1890}, {3768, 969, 2288}, {2016, 559, 854}, - {1736, 729, 787}, {1940, 686, 547}, {2140, 635, 674}, {4480,1272, 828}, - {3976, 592, 1666}, {4384, 621, 1388}, {4400, 801, 955}, {4656, 522, 646}, - {4848, 625, 1636}, {4984, 591, 874}, {5352, 535, 1001}, {11216,938, 1184}, - { 925,3280, 1476}, { 735,1580, 1088}, {1150,1576, 674}, { 655, 783, 528}, - { 527,2052, 1354}, { 782,1704, 1880}, { 578, 910, 1026}, { 692, 882, 1468}, - { 586, 683, 715}, { 739, 609, 717}, { 778, 773, 697}, { 922, 785, 813}, - { 766, 651, 984}, { 978, 596, 1030}, {1070, 757, 1080}, {1324, 687, 1178}, - {1108,2144, 979}, { 723, 982, 690}, { 936, 956, 527}, {1180,1002, 547}, - { 517,1306, 825}, { 832,1184, 974}, {1024, 957, 903}, {1262,1090, 906}, - {1028, 720, 649}, {1192, 679, 694}, {2468,1480, 979}, {2844,1370, 877}, - {1310, 835, 848}, {1508, 839, 698}, {1742,1030, 769}, {1910, 852, 573}, - {1280, 859, 1174}, {1584, 863, 1108}, {1686, 708, 1364}, {1942, 768, 1104}, - { 891, 536, 690}, {1016, 560, 663}, {2172, 870, 1348}, {2404, 999, 1170}, - {1890, 966, 889}, {2116, 912, 777}, {2296,1020, 714}, {4872,1844, 932}, - {2392, 778, 929}, {2604, 772, 744}, {2764, 957, 722}, {5832,1532, 984}, - {2188, 519, 1264}, {2332, 532, 922}, {5064, 995, 2412}, {2708, 571, 874}, - {2408, 545, 666}, {5016,1084, 875}, {5376, 983, 1196}, {5536, 979, 730}, - {5344, 634, 1744}, {5688, 706, 1348}, {5912, 977, 1190}, {6072, 905, 763}, - {6048, 582, 1526}, {11968,1013,1816}, {12864,937, 1900}, {12560,1086, 998}, - {1998, 684, 1884}, {2504, 633, 1992}, {1252, 567, 835}, {1478, 571, 973}, - {2620, 769, 1414}, {2808, 952, 1142}, {2908, 712, 1028}, {2976, 686, 741}, - {1462, 552, 714}, {3296, 991, 1452}, {1590, 615, 544}, {3480,1150, 824}, - {3212, 832, 923}, {3276, 839, 531}, {3548, 786, 852}, {3732, 764, 570}, - {5728, 906, 2616}, {6272, 804, 2252}, {3096, 535, 876}, {3228, 598, 649}, - {6536, 759, 1436}, {6648, 993, 846}, {6864, 567, 1210},{14016,1012, 1302}, - {3408, 548, 1098}, {7160,1008, 1742}, {7136,1000, 1182}, {7480,1032, 836}, - {7448, 612, 1552}, {7744, 614, 816}, {8384, 777, 1438}, {8784, 694, 786}, - { 882,1508, 1068}, { 597, 837, 766}, {1270, 954, 1408}, { 803, 550, 798}, - {1398,1308, 798}, {1848,1534, 738}, { 970, 675, 608}, {1264, 706, 684}, - {1716, 767, 1126}, {2108, 765, 1404}, {2236, 924, 1003}, {2472,1048, 611}, - { 999, 942, 963}, {1094, 857, 935}, {2936, 926, 1138}, {1934, 746, 551}, - {3336, 633, 1762}, {3764, 701, 1454}, {1890, 564, 636}, {4096,1126, 793}, - {3936, 556, 1140}, {3936, 540, 740}, {4216, 764, 874}, {8480,1328, 1014}, - {2184, 515, 1042}, {4432, 934, 1344}, {4784, 945, 1112}, {5016,1062, 733}, - {9216,1020, 2028}, {9968, 924, 1188}, {5424, 909, 1206}, {6512, 744, 1086} -}; - -static const uint8_t gain_exp_tab[256] = { - 15, 15, 15, 15, 15, 16, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 13, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13, - 13, 13, 13, 13, 14, 13, 12, 12, 13, 13, 13, 12, 13, 13, 13, 13, - 13, 12, 13, 13, 12, 12, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, - 13, 13, 13, 12, 12, 12, 13, 13, 12, 12, 12, 13, 12, 12, 12, 12, - 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 13, 13, 13, 13, - 13, 13, 13, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, - 13, 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 11, 11, 11, 11, - 12, 12, 12, 12, 11, 11, 12, 12, 12, 12, 12, 13, 12, 12, 12, 13, - 12, 12, 13, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, - 12, 12, 11, 11, 12, 12, 12, 12, 11, 12, 11, 12, 12, 12, 12, 12, - 13, 13, 12, 12, 13, 13, 13, 14, 12, 13, 13, 13, 13, 13, 13, 13, - 11, 10, 11, 10, 11, 11, 10, 10, 11, 11, 11, 11, 10, 9, 11, 10, - 12, 12, 11, 12, 12, 12, 12, 13, 11, 12, 12, 12, 13, 13, 12, 12 -}; - -static const int8_t cb1_vects[128][40]={ - { - 38, -4, 15, -4, 14, -13, 12, -11, -2, -6, - -6, -11, -45, -16, -11, -13, -7, 6, -12, 4, - -20, 3, -16, 12, -1, 12, 46, 24, 0, 33, - -3, 9, -12, -12, -8, -7, 17, -6, 0, -2, - }, { - 60, -16, 3, -22, 10, -32, 0, -28, -17, -18, - -3, -25, -37, -23, -10, 3, 2, 3, 0, 3, - -14, 0, -14, -1, 0, 2, 32, 9, -1, 25, - 7, 13, -5, 13, 8, 1, 2, 8, -10, 6, - }, { - 27, -12, 28, -2, 6, -7, 15, 9, -11, 1, - -13, -11, -40, 4, -29, -14, -19, -5, -23, -8, - -30, -13, -17, 0, -14, 12, 34, 20, -2, 25, - 2, -16, -4, -12, 15, 16, 29, 7, 24, 10, - }, { - 49, -24, 16, -20, 2, -26, 2, -7, -25, -10, - -11, -25, -32, -3, -27, 2, -8, -8, -11, -9, - -24, -17, -16, -14, -13, 2, 20, 5, -4, 17, - 14, -12, 3, 13, 33, 25, 14, 23, 15, 19, - }, { - 46, -6, 21, 8, -2, -16, -5, -8, -11, 4, - 8, 15, -24, 4, -2, -26, -3, -16, -16, -14, - -9, -2, -1, 4, 19, 7, 36, 17, 9, 13, - 0, 31, -5, -12, 7, -8, 11, -15, -13, -4, - }, { - 68, -18, 9, -9, -6, -35, -18, -25, -26, -7, - 10, 1, -16, -3, -1, -9, 6, -19, -4, -15, - -4, -6, 0, -8, 20, -2, 23, 2, 7, 5, - 12, 35, 1, 13, 24, 0, -3, 0, -22, 4, - }, { - 35, -14, 34, 10, -10, -10, -1, 12, -20, 12, - 0, 15, -18, 24, -20, -27, -14, -28, -27, -27, - -20, -19, -2, -8, 5, 7, 25, 13, 5, 5, - 6, 5, 2, -12, 31, 15, 23, -1, 12, 8, - }, { - 57, -26, 22, -7, -14, -28, -14, -3, -35, 0, - 3, 1, -11, 16, -18, -10, -4, -31, -15, -28, - -14, -23, -1, -21, 7, -2, 11, -1, 3, -1, - 18, 9, 10, 13, 49, 24, 8, 14, 2, 16, - }, { - 25, 15, 22, 11, 18, 4, 15, -22, 8, -2, - -17, -9, -48, -20, -30, -17, -16, 11, -1, 16, - 2, 10, -5, 26, -2, -4, 22, 0, 2, 10, - -6, 13, -14, 10, -23, 0, 10, -2, 1, 0, - }, { - 47, 3, 11, -6, 15, -13, 2, -38, -6, -13, - -15, -22, -40, -28, -28, 0, -5, 8, 10, 15, - 7, 7, -4, 13, -1, -14, 9, -14, 0, 2, - 4, 18, -7, 36, -6, 8, -3, 13, -7, 8, - }, { - 14, 7, 36, 13, 10, 10, 18, 0, 0, 5, - -25, -8, -43, 0, -48, -18, -27, 0, -12, 3, - -7, -6, -7, 13, -15, -5, 11, -3, 0, 2, - 0, -12, -6, 10, 0, 23, 22, 11, 26, 12, - }, { - 36, -5, 24, -4, 7, -7, 6, -17, -14, -5, - -22, -22, -35, -8, -46, -1, -17, -3, 0, 2, - -2, -10, -5, 0, -14, -15, -2, -18, -2, -4, - 11, -7, 1, 36, 18, 32, 7, 27, 17, 20, - }, { - 33, 13, 29, 24, 1, 1, -2, -18, 0, 9, - -3, 17, -27, 0, -21, -30, -12, -11, -5, -2, - 12, 4, 9, 19, 18, -9, 13, -6, 11, -8, - -2, 35, -8, 10, -7, -1, 4, -11, -10, -2, - }, { - 55, 1, 17, 6, -1, -16, -15, -35, -15, -2, - 0, 4, -19, -8, -20, -13, -1, -14, 7, -3, - 18, 0, 10, 5, 19, -19, 0, -21, 8, -16, - 9, 39, 0, 36, 10, 7, -9, 4, -20, 5, - }, { - 22, 5, 42, 26, -6, 8, 1, 2, -9, 17, - -10, 18, -21, 19, -39, -31, -23, -23, -16, -15, - 2, -12, 7, 6, 5, -9, 1, -10, 7, -16, - 4, 9, 0, 10, 17, 22, 16, 2, 14, 9, - }, { - 44, -6, 30, 8, -9, -10, -11, -14, -23, 5, - -8, 4, -14, 12, -37, -14, -12, -26, -4, -16, - 8, -16, 9, -7, 6, -19, -12, -25, 5, -24, - 15, 13, 8, 36, 34, 31, 1, 18, 4, 18, - }, { - -3, -5, -9, -7, 15, -1, 5, 13, 2, 12, - 5, 2, -21, -23, -2, -16, 0, 5, -6, 13, - -23, 3, -32, 10, -15, 8, 44, 28, 9, 37, - -2, 13, -9, -15, -12, -27, -7, -12, 0, -11, - }, { - 18, -17, -21, -25, 11, -19, -6, -3, -11, 0, - 7, -11, -13, -31, -1, 0, 9, 1, 5, 12, - -18, 0, -31, -2, -13, -1, 30, 14, 7, 29, - 9, 18, -1, 10, 4, -18, -22, 3, -10, -2, - }, { - -13, -13, 3, -5, 7, 4, 9, 34, -5, 20, - -2, 3, -16, -3, -20, -17, -11, -7, -17, 0, - -34, -13, -33, -2, -28, 8, 32, 24, 5, 29, - 3, -12, 0, -15, 11, -3, 3, 2, 24, 1, - }, { - 8, -25, -8, -23, 3, -13, -3, 17, -20, 8, - 0, -10, -8, -11, -18, 0, -1, -10, -5, 0, - -28, -17, -32, -15, -26, -1, 19, 9, 3, 21, - 15, -7, 6, 9, 29, 5, -10, 17, 15, 9, - }, { - 4, -6, -3, 5, -1, -4, -11, 16, -6, 23, - 19, 29, 0, -3, 6, -30, 3, -17, -10, -5, - -13, -2, -17, 3, 5, 3, 35, 21, 17, 17, - 2, 35, -2, -15, 3, -28, -13, -21, -13, -13, - }, { - 26, -19, -15, -12, -5, -22, -24, 0, -21, 12, - 21, 15, 8, -11, 7, -12, 14, -20, 2, -6, - -7, -6, -16, -9, 6, -5, 21, 7, 15, 10, - 13, 39, 5, 10, 20, -19, -28, -5, -22, -5, - }, { - -5, -15, 9, 7, -9, 2, -8, 37, -14, 31, - 11, 29, 5, 16, -11, -30, -7, -29, -21, -18, - -23, -19, -18, -9, -7, 3, 23, 17, 14, 9, - 8, 9, 6, -15, 27, -4, -2, -6, 12, -1, - }, { - 16, -27, -2, -10, -13, -16, -20, 20, -29, 20, - 14, 16, 13, 8, -9, -13, 2, -33, -9, -19, - -17, -23, -17, -22, -6, -6, 9, 2, 12, 2, - 20, 13, 13, 10, 45, 4, -16, 8, 2, 7, - }, { - -16, 14, -2, 8, 20, 17, 9, 2, 14, 16, - -6, 5, -24, -28, -21, -20, -8, 9, 4, 25, - -1, 11, -22, 24, -15, -8, 21, 5, 11, 14, - -5, 18, -11, 7, -27, -20, -14, -7, 1, -9, - }, { - 6, 2, -14, -9, 16, -1, -3, -14, 0, 5, - -3, -8, -16, -36, -19, -3, 1, 6, 17, 24, - 4, 7, -21, 11, -14, -18, 7, -9, 9, 7, - 6, 22, -3, 33, -10, -11, -28, 7, -7, 0, - }, { - -26, 6, 11, 10, 12, 23, 12, 23, 5, 24, - -13, 5, -19, -8, -38, -21, -20, -2, -6, 12, - -11, -5, -23, 11, -29, -9, 9, 0, 7, 6, - 1, -7, -2, 7, -3, 3, -2, 6, 27, 3, - }, { - -4, -6, 0, -7, 8, 4, 0, 6, -9, 13, - -11, -7, -11, -15, -37, -4, -9, -5, 5, 11, - -5, -9, -22, -1, -27, -18, -4, -14, 5, 0, - 12, -3, 4, 32, 14, 12, -17, 22, 17, 11, - }, { - -8, 12, 3, 21, 3, 14, -8, 5, 4, 28, - 7, 32, -2, -8, -12, -34, -4, -12, 1, 6, - 9, 4, -7, 17, 4, -13, 11, -1, 19, -4, - 0, 39, -4, 7, -11, -21, -20, -16, -10, -11, - }, { - 13, 0, -8, 3, 0, -4, -21, -11, -9, 16, - 10, 18, 5, -16, -10, -16, 5, -15, 13, 5, - 15, 1, -6, 4, 6, -23, -2, -16, 17, -12, - 10, 44, 3, 33, 6, -12, -34, -1, -20, -3, - }, { - -18, 4, 17, 23, -4, 20, -4, 26, -3, 36, - 0, 32, 2, 12, -29, -34, -16, -24, -10, -6, - 0, -12, -8, 4, -8, -13, 0, -6, 16, -12, - 5, 13, 3, 7, 13, 3, -8, -2, 14, 0, - }, { - 3, -7, 5, 5, -8, 2, -17, 9, -18, 24, - 2, 19, 10, 4, -28, -17, -5, -28, 2, -7, - 4, -15, -7, -8, -6, -23, -13, -21, 14, -20, - 17, 18, 11, 33, 30, 11, -23, 13, 5, 9, - }, { - 60, 10, 7, -1, 9, -8, 6, -13, 2, -15, - -1, -10, -13, -11, 15, 0, 6, 9, -1, 0, - -13, 1, -11, -3, -13, 21, 13, 26, -7, 31, - -10, -7, -16, -33, -31, -10, 22, -8, 1, -2, - }, { - 82, -1, -4, -19, 6, -27, -6, -29, -12, -26, - 1, -24, -5, -18, 17, 17, 17, 6, 10, 0, - -7, -2, -9, -16, -12, 11, 0, 11, -9, 23, - 0, -3, -8, -8, -13, -1, 8, 7, -7, 6, - }, { - 49, 2, 21, 0, 1, -2, 9, 8, -6, -6, - -8, -10, -8, 9, -2, 0, -4, -2, -13, -12, - -23, -15, -12, -16, -26, 21, 2, 21, -11, 23, - -4, -33, -7, -33, -6, 13, 34, 5, 27, 10, - }, { - 71, -10, 9, -17, -1, -20, -3, -8, -21, -18, - -6, -24, 0, 1, 0, 16, 6, -5, 0, -13, - -17, -19, -11, -29, -25, 11, -11, 6, -13, 15, - 7, -29, 0, -8, 11, 22, 20, 21, 17, 18, - }, { - 67, 8, 14, 11, -7, -11, -11, -9, -7, -3, - 13, 16, 8, 9, 24, -12, 10, -13, -5, -17, - -2, -4, 3, -10, 6, 17, 4, 19, 0, 11, - -6, 13, -9, -33, -14, -10, 16, -17, -10, -4, - }, { - 90, -3, 2, -6, -10, -29, -24, -26, -21, -15, - 15, 2, 16, 1, 25, 4, 21, -16, 6, -18, - 3, -8, 5, -24, 8, 7, -9, 4, -1, 3, - 5, 18, -1, -7, 2, -1, 2, -1, -19, 3, - }, { - 57, 0, 27, 13, -14, -5, -7, 11, -15, 4, - 5, 16, 13, 29, 6, -13, 0, -25, -16, -31, - -12, -22, 2, -23, -6, 16, -7, 14, -2, 3, - 0, -12, 0, -33, 9, 13, 28, -3, 14, 7, - }, { - 79, -11, 15, -4, -18, -23, -20, -5, -30, -7, - 7, 2, 21, 21, 8, 3, 10, -28, -4, -31, - -6, -25, 3, -37, -4, 7, -20, 0, -4, -4, - 11, -7, 6, -8, 27, 22, 14, 12, 5, 16, - }, { - 47, 30, 15, 14, 14, 9, 9, -23, 13, -10, - -12, -7, -16, -15, -3, -3, -1, 14, 9, 12, - 9, 8, 0, 10, -14, 4, -9, 2, -5, 8, - -13, -3, -18, -10, -45, -3, 16, -4, 4, 0, - }, { - 69, 17, 3, -3, 10, -8, -3, -40, -1, -21, - -10, -21, -8, -23, -1, 13, 8, 11, 21, 11, - 15, 4, 0, -2, -13, -5, -23, -12, -7, 0, - -1, 0, -10, 14, -28, 5, 1, 11, -5, 7, - }, { - 36, 21, 28, 16, 6, 16, 12, -2, 4, -2, - -20, -7, -11, 4, -20, -4, -12, 2, -1, 0, - 0, -8, -2, -2, -27, 4, -21, -2, -9, 0, - -6, -29, -9, -10, -21, 21, 28, 10, 29, 11, - }, { - 58, 9, 16, -1, 2, -2, 0, -19, -10, -13, - -17, -21, -3, -3, -19, 12, -2, 0, 10, -1, - 5, -12, 0, -15, -26, -5, -34, -16, -11, -7, - 4, -25, -2, 14, -3, 29, 13, 25, 20, 20, - }, { - 55, 28, 21, 27, -2, 7, -8, -20, 4, 1, - 1, 18, 5, 4, 5, -16, 2, -8, 5, -5, - 19, 2, 14, 3, 6, 0, -18, -4, 2, -11, - -8, 18, -11, -10, -29, -3, 10, -13, -8, -3, - }, { - 77, 16, 9, 9, -6, -11, -21, -37, -10, -10, - 4, 5, 13, -3, 7, 0, 13, -11, 17, -6, - 25, -1, 15, -9, 7, -9, -32, -19, 0, -18, - 2, 22, -3, 15, -12, 5, -4, 2, -17, 5, - }, { - 44, 20, 34, 29, -10, 13, -4, 0, -4, 9, - -5, 19, 10, 24, -11, -17, -8, -20, -5, -19, - 9, -14, 12, -9, -6, 0, -30, -9, 0, -19, - -2, -7, -2, -10, -5, 20, 21, 1, 17, 9, - }, { - 66, 8, 23, 11, -14, -5, -17, -16, -19, -2, - -3, 5, 18, 17, -10, 0, 1, -23, 6, -20, - 15, -18, 14, -22, -5, -10, -44, -23, -2, -26, - 9, -3, 4, 14, 12, 29, 7, 16, 7, 18, - }, { - 18, 9, -17, -4, 11, 3, 0, 11, 7, 4, - 10, 3, 10, -18, 24, -3, 14, 7, 4, 10, - -16, 1, -27, -4, -27, 17, 12, 30, 0, 35, - -9, -3, -12, -36, -35, -30, -2, -13, 2, -11, - }, { - 40, -2, -29, -22, 7, -14, -12, -5, -7, -7, - 12, -9, 18, -26, 26, 14, 24, 4, 16, 9, - -10, -2, -26, -18, -26, 7, -1, 15, -1, 27, - 2, 0, -4, -11, -17, -21, -16, 1, -7, -3, - }, { - 8, 1, -3, -2, 3, 10, 3, 32, -1, 12, - 2, 4, 15, 1, 7, -3, 2, -4, -6, -3, - -26, -15, -29, -17, -40, 17, 0, 26, -2, 27, - -2, -29, -4, -36, -10, -6, 9, 0, 27, 0, - }, { - 30, -11, -15, -20, 0, -8, -9, 15, -15, 0, - 5, -9, 23, -6, 8, 13, 13, -7, 5, -3, - -20, -19, -27, -31, -39, 7, -13, 11, -4, 19, - 8, -25, 3, -11, 7, 2, -4, 16, 18, 9, - }, { - 26, 7, -11, 8, -5, 1, -17, 14, -1, 15, - 24, 30, 32, 1, 33, -16, 18, -14, 0, -8, - -6, -4, -12, -12, -6, 13, 2, 23, 8, 15, - -4, 17, -5, -36, -18, -30, -8, -22, -10, -14, - }, { - 48, -4, -23, -9, -9, -17, -30, -2, -16, 3, - 26, 16, 40, -6, 35, 1, 28, -17, 12, -9, - 0, -8, -11, -25, -5, 3, -10, 8, 6, 7, - 6, 22, 1, -11, -1, -21, -22, -7, -19, -5, - }, { - 15, 0, 2, 10, -13, 7, -14, 35, -10, 23, - 16, 31, 37, 21, 16, -17, 6, -26, -10, -21, - -16, -21, -13, -25, -19, 13, -8, 19, 5, 7, - 1, -8, 2, -36, 5, -6, 3, -8, 15, -1, - }, { - 37, -12, -9, -7, -17, -11, -26, 18, -25, 12, - 19, 17, 45, 14, 17, 0, 17, -30, 1, -22, - -10, -25, -12, -38, -18, 3, -22, 4, 3, 0, - 13, -3, 10, -11, 23, 2, -10, 7, 5, 7, - }, { - 5, 29, -9, 11, 15, 22, 3, 0, 18, 8, - -1, 6, 7, -23, 6, -6, 5, 12, 15, 21, - 5, 8, -17, 9, -28, 0, -11, 6, 2, 12, - -11, 0, -14, -13, -49, -22, -8, -9, 4, -9, - }, { - 27, 16, -21, -6, 12, 3, -9, -16, 3, -2, - 1, -7, 15, -31, 7, 10, 16, 9, 27, 21, - 11, 5, -16, -3, -26, -9, -24, -7, 0, 4, - 0, 4, -6, 11, -32, -14, -23, 6, -5, -1, - }, { - -4, 20, 3, 13, 8, 28, 6, 21, 10, 16, - -8, 7, 12, -3, -11, -7, -5, 0, 4, 8, - -4, -8, -18, -3, -41, 0, -22, 2, 0, 4, - -5, -25, -6, -14, -25, 1, 2, 4, 29, 2, - }, { - 17, 8, -8, -4, 4, 10, -6, 5, -4, 5, - -6, -6, 20, -10, -9, 9, 4, -2, 16, 7, - 1, -12, -17, -16, -39, -9, -36, -12, -2, -3, - 6, -21, 1, 11, -7, 10, -11, 20, 20, 11, - }, { - 13, 27, -3, 24, -1, 19, -14, 3, 9, 20, - 12, 33, 29, -3, 15, -20, 9, -9, 11, 3, - 16, 2, -2, 2, -7, -3, -20, 0, 10, -7, - -7, 22, -7, -13, -33, -23, -14, -18, -7, -12, - }, { - 35, 15, -15, 6, -4, 1, -27, -12, -5, 8, - 15, 19, 37, -11, 16, -2, 20, -12, 23, 2, - 22, -1, -1, -11, -5, -13, -34, -14, 8, -14, - 4, 26, 0, 11, -16, -14, -29, -2, -17, -3, - }, { - 3, 19, 9, 26, -8, 26, -10, 24, 0, 28, - 5, 33, 34, 17, -2, -20, -1, -22, 0, -10, - 6, -14, -3, -10, -20, -4, -32, -4, 7, -15, - 0, -3, 0, -13, -9, 0, -3, -4, 17, 0, - }, { - 25, 7, -2, 8, -12, 7, -23, 8, -13, 16, - 7, 20, 42, 9, 0, -3, 9, -25, 12, -10, - 12, -18, -2, -24, -19, -13, -46, -19, 5, -22, - 10, 0, 8, 11, 8, 9, -17, 11, 7, 8, - }, { - -25, -7, 2, -8, 12, -7, 23, -8, 13, -16, - -7, -20, -42, -9, 0, 3, -9, 25, -12, 10, - -12, 18, 2, 24, 19, 13, 46, 19, -5, 22, - -10, 0, -8, -11, -8, -9, 17, -11, -7, -8, - }, { - -3, -19, -9, -26, 8, -26, 10, -24, 0, -28, - -5, -33, -34, -17, 2, 20, 1, 22, 0, 10, - -6, 14, 3, 10, 20, 4, 32, 4, -7, 15, - 0, 3, 0, 13, 9, 0, 3, 4, -17, 0, - }, { - -35, -15, 15, -6, 4, -1, 27, 12, 5, -8, - -15, -19, -37, 11, -16, 2, -20, 12, -23, -2, - -22, 1, 1, 11, 5, 13, 34, 14, -8, 14, - -4, -26, 0, -11, 16, 14, 29, 2, 17, 3, - }, { - -13, -27, 3, -24, 1, -19, 14, -3, -9, -20, - -12, -33, -29, 3, -15, 20, -9, 9, -11, -3, - -16, -2, 2, -2, 7, 3, 20, 0, -10, 7, - 7, -22, 7, 13, 33, 23, 14, 18, 7, 12, - }, { - -17, -8, 8, 4, -4, -10, 6, -5, 4, -5, - 6, 6, -20, 10, 9, -9, -4, 2, -16, -7, - -1, 12, 17, 16, 39, 9, 36, 12, 2, 3, - -6, 21, -1, -11, 7, -10, 11, -20, -20, -11, - }, { - 4, -20, -3, -13, -8, -28, -6, -21, -10, -16, - 8, -7, -12, 3, 11, 7, 5, 0, -4, -8, - 4, 8, 18, 3, 41, 0, 22, -2, 0, -4, - 5, 25, 6, 14, 25, -1, -2, -4, -29, -2, - }, { - -27, -16, 21, 6, -12, -3, 9, 16, -3, 2, - -1, 7, -15, 31, -7, -10, -16, -9, -27, -21, - -11, -5, 16, 3, 26, 9, 24, 7, 0, -4, - 0, -4, 6, -11, 32, 14, 23, -6, 5, 1, - }, { - -5, -29, 9, -11, -15, -22, -3, 0, -18, -8, - 1, -6, -7, 23, -6, 6, -5, -12, -15, -21, - -5, -8, 17, -9, 28, 0, 11, -6, -2, -12, - 11, 0, 14, 13, 49, 22, 8, 9, -4, 9, - }, { - -37, 12, 9, 7, 17, 11, 26, -18, 25, -12, - -19, -17, -45, -14, -17, 0, -17, 30, -1, 22, - 10, 25, 12, 38, 18, -3, 22, -4, -3, 0, - -13, 3, -10, 11, -23, -2, 10, -7, -5, -7, - }, { - -15, 0, -2, -10, 13, -7, 14, -35, 10, -23, - -16, -31, -37, -21, -16, 17, -6, 26, 10, 21, - 16, 21, 13, 25, 19, -13, 8, -19, -5, -7, - -1, 8, -2, 36, -5, 6, -3, 8, -15, 1, - }, { - -48, 4, 23, 9, 9, 17, 30, 2, 16, -3, - -26, -16, -40, 6, -35, -1, -28, 17, -12, 9, - 0, 8, 11, 25, 5, -3, 10, -8, -6, -7, - -6, -22, -1, 11, 1, 21, 22, 7, 19, 5, - }, { - -26, -7, 11, -8, 5, -1, 17, -14, 1, -15, - -24, -30, -32, -1, -33, 16, -18, 14, 0, 8, - 6, 4, 12, 12, 6, -13, -2, -23, -8, -15, - 4, -17, 5, 36, 18, 30, 8, 22, 10, 14, - }, { - -30, 11, 15, 20, 0, 8, 9, -15, 15, 0, - -5, 9, -23, 6, -8, -13, -13, 7, -5, 3, - 20, 19, 27, 31, 39, -7, 13, -11, 4, -19, - -8, 25, -3, 11, -7, -2, 4, -16, -18, -9, - }, { - -8, -1, 3, 2, -3, -10, -3, -32, 1, -12, - -2, -4, -15, -1, -7, 3, -2, 4, 6, 3, - 26, 15, 29, 17, 40, -17, 0, -26, 2, -27, - 2, 29, 4, 36, 10, 6, -9, 0, -27, 0, - }, { - -40, 2, 29, 22, -7, 14, 12, 5, 7, 7, - -12, 9, -18, 26, -26, -14, -24, -4, -16, -9, - 10, 2, 26, 18, 26, -7, 1, -15, 1, -27, - -2, 0, 4, 11, 17, 21, 16, -1, 7, 3, - }, { - -18, -9, 17, 4, -11, -3, 0, -11, -7, -4, - -10, -3, -10, 18, -24, 3, -14, -7, -4, -10, - 16, -1, 27, 4, 27, -17, -12, -30, 0, -35, - 9, 3, 12, 36, 35, 30, 2, 13, -2, 11, - }, { - -66, -8, -23, -11, 14, 5, 17, 16, 19, 2, - 3, -5, -18, -17, 10, 0, -1, 23, -6, 20, - -15, 18, -14, 22, 5, 10, 44, 23, 2, 26, - -9, 3, -4, -14, -12, -29, -7, -16, -7, -18, - }, { - -44, -20, -34, -29, 10, -13, 4, 0, 4, -9, - 5, -19, -10, -24, 11, 17, 8, 20, 5, 19, - -9, 14, -12, 9, 6, 0, 30, 9, 0, 19, - 2, 7, 2, 10, 5, -20, -21, -1, -17, -9, - }, { - -77, -16, -9, -9, 6, 11, 21, 37, 10, 10, - -4, -5, -13, 3, -7, 0, -13, 11, -17, 6, - -25, 1, -15, 9, -7, 9, 32, 19, 0, 18, - -2, -22, 3, -15, 12, -5, 4, -2, 17, -5, - }, { - -55, -28, -21, -27, 2, -7, 8, 20, -4, -1, - -1, -18, -5, -4, -5, 16, -2, 8, -5, 5, - -19, -2, -14, -3, -6, 0, 18, 4, -2, 11, - 8, -18, 11, 10, 29, 3, -10, 13, 8, 3, - }, { - -58, -9, -16, 1, -2, 2, 0, 19, 10, 13, - 17, 21, 3, 3, 19, -12, 2, 0, -10, 1, - -5, 12, 0, 15, 26, 5, 34, 16, 11, 7, - -4, 25, 2, -14, 3, -29, -13, -25, -20, -20, - }, { - -36, -21, -28, -16, -6, -16, -12, 2, -4, 2, - 20, 7, 11, -4, 20, 4, 12, -2, 1, 0, - 0, 8, 2, 2, 27, -4, 21, 2, 9, 0, - 6, 29, 9, 10, 21, -21, -28, -10, -29, -11, - }, { - -69, -17, -3, 3, -10, 8, 3, 40, 1, 21, - 10, 21, 8, 23, 1, -13, -8, -11, -21, -11, - -15, -4, 0, 2, 13, 5, 23, 12, 7, 0, - 1, 0, 10, -14, 28, -5, -1, -11, 5, -7, - }, { - -47, -30, -15, -14, -14, -9, -9, 23, -13, 10, - 12, 7, 16, 15, 3, 3, 1, -14, -9, -12, - -9, -8, 0, -10, 14, -4, 9, -2, 5, -8, - 13, 3, 18, 10, 45, 3, -16, 4, -4, 0, - }, { - -79, 11, -15, 4, 18, 23, 20, 5, 30, 7, - -7, -2, -21, -21, -8, -3, -10, 28, 4, 31, - 6, 25, -3, 37, 4, -7, 20, 0, 4, 4, - -11, 7, -6, 8, -27, -22, -14, -12, -5, -16, - }, { - -57, 0, -27, -13, 14, 5, 7, -11, 15, -4, - -5, -16, -13, -29, -6, 13, 0, 25, 16, 31, - 12, 22, -2, 23, 6, -16, 7, -14, 2, -3, - 0, 12, 0, 33, -9, -13, -28, 3, -14, -7, - }, { - -90, 3, -2, 6, 10, 29, 24, 26, 21, 15, - -15, -2, -16, -1, -25, -4, -21, 16, -6, 18, - -3, 8, -5, 24, -8, -7, 9, -4, 1, -3, - -5, -18, 1, 7, -2, 1, -2, 1, 19, -3, - }, { - -67, -8, -14, -11, 7, 11, 11, 9, 7, 3, - -13, -16, -8, -9, -24, 12, -10, 13, 5, 17, - 2, 4, -3, 10, -6, -17, -4, -19, 0, -11, - 6, -13, 9, 33, 14, 10, -16, 17, 10, 4, - }, { - -71, 10, -9, 17, 1, 20, 3, 8, 21, 18, - 6, 24, 0, -1, 0, -16, -6, 5, 0, 13, - 17, 19, 11, 29, 25, -11, 11, -6, 13, -15, - -7, 29, 0, 8, -11, -22, -20, -21, -17, -18, - }, { - -49, -2, -21, 0, -1, 2, -9, -8, 6, 6, - 8, 10, 8, -9, 2, 0, 4, 2, 13, 12, - 23, 15, 12, 16, 26, -21, -2, -21, 11, -23, - 4, 33, 7, 33, 6, -13, -34, -5, -27, -10, - }, { - -82, 1, 4, 19, -6, 27, 6, 29, 12, 26, - -1, 24, 5, 18, -17, -17, -17, -6, -10, 0, - 7, 2, 9, 16, 12, -11, 0, -11, 9, -23, - 0, 3, 8, 8, 13, 1, -8, -7, 7, -6, - }, { - -60, -10, -7, 1, -9, 8, -6, 13, -2, 15, - 1, 10, 13, 11, -15, 0, -6, -9, 1, 0, - 13, -1, 11, 3, 13, -21, -13, -26, 7, -31, - 10, 7, 16, 33, 31, 10, -22, 8, -1, 2, - }, { - -3, 7, -5, -5, 8, -2, 17, -9, 18, -24, - -2, -19, -10, -4, 28, 17, 5, 28, -2, 7, - -4, 15, 7, 8, 6, 23, 13, 21, -14, 20, - -17, -18, -11, -33, -30, -11, 23, -13, -5, -9, - }, { - 18, -4, -17, -23, 4, -20, 4, -26, 3, -36, - 0, -32, -2, -12, 29, 34, 16, 24, 10, 6, - 0, 12, 8, -4, 8, 13, 0, 6, -16, 12, - -5, -13, -3, -7, -13, -3, 8, 2, -14, 0, - }, { - -13, 0, 8, -3, 0, 4, 21, 11, 9, -16, - -10, -18, -5, 16, 10, 16, -5, 15, -13, -5, - -15, -1, 6, -4, -6, 23, 2, 16, -17, 12, - -10, -44, -3, -33, -6, 12, 34, 1, 20, 3, - }, { - 8, -12, -3, -21, -3, -14, 8, -5, -4, -28, - -7, -32, 2, 8, 12, 34, 4, 12, -1, -6, - -9, -4, 7, -17, -4, 13, -11, 1, -19, 4, - 0, -39, 4, -7, 11, 21, 20, 16, 10, 11, - }, { - 4, 6, 0, 7, -8, -4, 0, -6, 9, -13, - 11, 7, 11, 15, 37, 4, 9, 5, -5, -11, - 5, 9, 22, 1, 27, 18, 4, 14, -5, 0, - -12, 3, -4, -32, -14, -12, 17, -22, -17, -11, - }, { - 26, -6, -11, -10, -12, -23, -12, -23, -5, -24, - 13, -5, 19, 8, 38, 21, 20, 2, 6, -12, - 11, 5, 23, -11, 29, 9, -9, 0, -7, -6, - -1, 7, 2, -7, 3, -3, 2, -6, -27, -3, - }, { - -6, -2, 14, 9, -16, 1, 3, 14, 0, -5, - 3, 8, 16, 36, 19, 3, -1, -6, -17, -24, - -4, -7, 21, -11, 14, 18, -7, 9, -9, -7, - -6, -22, 3, -33, 10, 11, 28, -7, 7, 0, - }, { - 16, -14, 2, -8, -20, -17, -9, -2, -14, -16, - 6, -5, 24, 28, 21, 20, 8, -9, -4, -25, - 1, -11, 22, -24, 15, 8, -21, -5, -11, -14, - 5, -18, 11, -7, 27, 20, 14, 7, -1, 9, - }, { - -16, 27, 2, 10, 13, 16, 20, -20, 29, -20, - -14, -16, -13, -8, 9, 13, -2, 33, 9, 19, - 17, 23, 17, 22, 6, 6, -9, -2, -12, -2, - -20, -13, -13, -10, -45, -4, 16, -8, -2, -7, - }, { - 5, 15, -9, -7, 9, -2, 8, -37, 14, -31, - -11, -29, -5, -16, 11, 30, 7, 29, 21, 18, - 23, 19, 18, 9, 7, -3, -23, -17, -14, -9, - -8, -9, -6, 15, -27, 4, 2, 6, -12, 1, - }, { - -26, 19, 15, 12, 5, 22, 24, 0, 21, -12, - -21, -15, -8, 11, -7, 12, -14, 20, -2, 6, - 7, 6, 16, 9, -6, 5, -21, -7, -15, -10, - -13, -39, -5, -10, -20, 19, 28, 5, 22, 5, - }, { - -4, 6, 3, -5, 1, 4, 11, -16, 6, -23, - -19, -29, 0, 3, -6, 30, -3, 17, 10, 5, - 13, 2, 17, -3, -5, -3, -35, -21, -17, -17, - -2, -35, 2, 15, -3, 28, 13, 21, 13, 13, - }, { - -8, 25, 8, 23, -3, 13, 3, -17, 20, -8, - 0, 10, 8, 11, 18, 0, 1, 10, 5, 0, - 28, 17, 32, 15, 26, 1, -19, -9, -3, -21, - -15, 7, -6, -9, -29, -5, 10, -17, -15, -9, - }, { - 13, 13, -3, 5, -7, -4, -9, -34, 5, -20, - 2, -3, 16, 3, 20, 17, 11, 7, 17, 0, - 34, 13, 33, 2, 28, -8, -32, -24, -5, -29, - -3, 12, 0, 15, -11, 3, -3, -2, -24, -1, - }, { - -18, 17, 21, 25, -11, 19, 6, 3, 11, 0, - -7, 11, 13, 31, 1, 0, -9, -1, -5, -12, - 18, 0, 31, 2, 13, 1, -30, -14, -7, -29, - -9, -18, 1, -10, -4, 18, 22, -3, 10, 2, - }, { - 3, 5, 9, 7, -15, 1, -5, -13, -2, -12, - -5, -2, 21, 23, 2, 16, 0, -5, 6, -13, - 23, -3, 32, -10, 15, -8, -44, -28, -9, -37, - 2, -13, 9, 15, 12, 27, 7, 12, 0, 11, - }, { - -44, 6, -30, -8, 9, 10, 11, 14, 23, -5, - 8, -4, 14, -12, 37, 14, 12, 26, 4, 16, - -8, 16, -9, 7, -6, 19, 12, 25, -5, 24, - -15, -13, -8, -36, -34, -31, -1, -18, -4, -18, - }, { - -22, -5, -42, -26, 6, -8, -1, -2, 9, -17, - 10, -18, 21, -19, 39, 31, 23, 23, 16, 15, - -2, 12, -7, -6, -5, 9, -1, 10, -7, 16, - -4, -9, 0, -10, -17, -22, -16, -2, -14, -9, - }, { - -55, -1, -17, -6, 1, 16, 15, 35, 15, 2, - 0, -4, 19, 8, 20, 13, 1, 14, -7, 3, - -18, 0, -10, -5, -19, 19, 0, 21, -8, 16, - -9, -39, 0, -36, -10, -7, 9, -4, 20, -5, - }, { - -33, -13, -29, -24, -1, -1, 2, 18, 0, -9, - 3, -17, 27, 0, 21, 30, 12, 11, 5, 2, - -12, -4, -9, -19, -18, 9, -13, 6, -11, 8, - 2, -35, 8, -10, 7, 1, -4, 11, 10, 2, - }, { - -36, 5, -24, 4, -7, 7, -6, 17, 14, 5, - 22, 22, 35, 8, 46, 1, 17, 3, 0, -2, - 2, 10, 5, 0, 14, 15, 2, 18, 2, 4, - -11, 7, -1, -36, -18, -32, -7, -27, -17, -20, - }, { - -14, -7, -36, -13, -10, -10, -18, 0, 0, -5, - 25, 8, 43, 0, 48, 18, 27, 0, 12, -3, - 7, 6, 7, -13, 15, 5, -11, 3, 0, -2, - 0, 12, 6, -10, 0, -23, -22, -11, -26, -12, - }, { - -47, -3, -11, 6, -15, 13, -2, 38, 6, 13, - 15, 22, 40, 28, 28, 0, 5, -8, -10, -15, - -7, -7, 4, -13, 1, 14, -9, 14, 0, -2, - -4, -18, 7, -36, 6, -8, 3, -13, 7, -8, - }, { - -25, -15, -22, -11, -18, -4, -15, 22, -8, 2, - 17, 9, 48, 20, 30, 17, 16, -11, 1, -16, - -2, -10, 5, -26, 2, 4, -22, 0, -2, -10, - 6, -13, 14, -10, 23, 0, -10, 2, -1, 0, - }, { - -57, 26, -22, 7, 14, 28, 14, 3, 35, 0, - -3, -1, 11, -16, 18, 10, 4, 31, 15, 28, - 14, 23, 1, 21, -7, 2, -11, 1, -3, 1, - -18, -9, -10, -13, -49, -24, -8, -14, -2, -16, - }, { - -35, 14, -34, -10, 10, 10, 1, -12, 20, -12, - 0, -15, 18, -24, 20, 27, 14, 28, 27, 27, - 20, 19, 2, 8, -5, -7, -25, -13, -5, -5, - -6, -5, -2, 12, -31, -15, -23, 1, -12, -8, - }, { - -68, 18, -9, 9, 6, 35, 18, 25, 26, 7, - -10, -1, 16, 3, 1, 9, -6, 19, 4, 15, - 4, 6, 0, 8, -20, 2, -23, -2, -7, -5, - -12, -35, -1, -13, -24, 0, 3, 0, 22, -4, - }, { - -46, 6, -21, -8, 2, 16, 5, 8, 11, -4, - -8, -15, 24, -4, 2, 26, 3, 16, 16, 14, - 9, 2, 1, -4, -19, -7, -36, -17, -9, -13, - 0, -31, 5, 12, -7, 8, -11, 15, 13, 4, - }, { - -49, 24, -16, 20, -2, 26, -2, 7, 25, 10, - 11, 25, 32, 3, 27, -2, 8, 8, 11, 9, - 24, 17, 16, 14, 13, -2, -20, -5, 4, -17, - -14, 12, -3, -13, -33, -25, -14, -23, -15, -19, - }, { - -27, 12, -28, 2, -6, 7, -15, -9, 11, -1, - 13, 11, 40, -4, 29, 14, 19, 5, 23, 8, - 30, 13, 17, 0, 14, -12, -34, -20, 2, -25, - -2, 16, 4, 12, -15, -16, -29, -7, -24, -10, - }, { - -60, 16, -3, 22, -10, 32, 0, 28, 17, 18, - 3, 25, 37, 23, 10, -3, -2, -3, 0, -3, - 14, 0, 14, 1, 0, -2, -32, -9, 1, -25, - -7, -13, 5, -13, -8, -1, -2, -8, 10, -6, - }, { - -38, 4, -15, 4, -14, 13, -12, 11, 2, 6, - 6, 11, 45, 16, 11, 13, 7, -6, 12, -4, - 20, -3, 16, -12, 1, -12, -46, -24, 0, -33, - 3, -9, 12, 12, 8, 7, -17, 6, 0, 2 - } -}; - -static const int8_t cb2_vects[128][40]={ - { - 73, -32, -60, -15, -26, 59, 2, -33, 30, -10, - -3, -17, 8, 30, -1, -26, -4, -22, 10, 16, - -36, -5, -11, 56, 37, 6, -10, -5, -13, -3, - 6, -5, 11, 4, -19, -5, -16, 41, 24, 13, - }, { - 4, -11, -37, 23, -5, 46, -2, -29, -5, -39, - -21, -9, 0, 49, 12, -9, -16, -26, 22, 15, - -45, -20, -5, 40, 22, 17, -26, 31, -14, 2, - -14, 10, 30, 20, -27, -9, -39, 39, 18, 5, - }, { - 34, -25, -48, -28, -11, 34, -2, -41, 9, -7, - -17, 21, 20, 24, -17, -33, 0, -24, 10, 42, - 3, -5, 10, 42, 11, 8, -3, 3, 16, 9, - 22, -2, 0, -33, -10, 18, 7, 58, 10, 28, - }, { - -34, -4, -25, 10, 9, 21, -7, -36, -26, -36, - -35, 28, 12, 42, -3, -16, -12, -28, 21, 42, - -5, -21, 16, 26, -4, 19, -19, 39, 15, 15, - 1, 13, 19, -17, -17, 14, -15, 55, 4, 19, - }, { - 28, -20, -51, -14, -6, 7, 0, -26, 27, -4, - 18, -40, -6, 16, -1, -15, 0, -55, -5, -16, - -19, 14, -3, 49, 14, 1, -22, -30, -12, 0, - 24, 15, 9, -17, -45, -29, 4, 28, 51, 35, - }, { - -40, 0, -28, 24, 14, -5, -4, -21, -7, -33, - 0, -32, -15, 35, 12, 1, -11, -58, 5, -16, - -28, 0, 1, 33, 0, 11, -39, 5, -14, 6, - 3, 31, 28, -1, -53, -33, -19, 25, 46, 26, - }, { - -11, -14, -39, -27, 9, -17, -4, -33, 6, 0, - 4, -1, 5, 10, -17, -22, 5, -57, -5, 9, - 20, 13, 18, 35, -11, 3, -16, -22, 17, 13, - 40, 19, -1, -55, -35, -5, 27, 44, 37, 49, - }, { - -80, 6, -16, 11, 30, -30, -9, -28, -28, -29, - -13, 6, -2, 28, -3, -5, -7, -60, 5, 9, - 11, -1, 24, 19, -27, 13, -32, 13, 15, 19, - 19, 35, 17, -39, -43, -9, 4, 42, 32, 41, - }, { - 78, -21, -43, 4, -38, 17, 17, -5, 55, 24, - -15, -36, 14, 4, 24, -24, 12, 5, 17, 31, - -54, -5, -2, 27, 43, -12, 2, 9, -9, -15, - 22, -3, 28, 21, -20, 3, 20, 28, 9, -5, - }, { - 9, -1, -20, 43, -17, 3, 12, 0, 20, -4, - -33, -29, 6, 22, 38, -7, 0, 1, 29, 30, - -63, -21, 3, 11, 27, -1, -14, 45, -10, -9, - 1, 12, 47, 37, -28, 0, -2, 26, 4, -13, - }, { - 39, -14, -30, -8, -22, -8, 12, -12, 34, 27, - -29, 2, 26, -2, 8, -31, 16, 3, 17, 57, - -14, -6, 19, 13, 16, -10, 8, 17, 20, -2, - 38, 0, 17, -16, -11, 27, 44, 45, -4, 8, - }, { - -29, 5, -7, 30, -1, -21, 7, -7, 0, 0, - -47, 9, 18, 15, 22, -14, 4, 0, 28, 57, - -23, -21, 25, -2, 1, 0, -7, 53, 19, 3, - 17, 15, 36, 0, -19, 24, 21, 43, -9, 0, - }, { - 33, -10, -34, 5, -17, -35, 15, 1, 53, 30, - 6, -59, 0, -10, 24, -13, 17, -27, 1, -1, - -37, 13, 4, 20, 20, -18, -10, -16, -8, -11, - 39, 18, 26, 0, -46, -20, 41, 15, 37, 15, - }, { - -35, 10, -11, 44, 3, -48, 10, 6, 17, 2, - -11, -51, -8, 8, 38, 3, 4, -31, 12, -2, - -46, -1, 10, 4, 5, -7, -26, 19, -10, -5, - 18, 34, 45, 15, -54, -24, 18, 13, 31, 7, - }, { - -5, -3, -21, -7, -2, -60, 10, -5, 32, 34, - -7, -20, 11, -16, 8, -20, 21, -29, 1, 24, - 2, 13, 27, 6, -5, -15, -3, -8, 21, 1, - 55, 21, 15, -38, -37, 3, 65, 32, 23, 30, - }, { - -74, 17, 0, 31, 18, -73, 5, 0, -3, 5, - -25, -12, 3, 1, 22, -3, 9, -33, 12, 24, - -6, -2, 33, -9, -21, -5, -20, 27, 19, 7, - 34, 37, 34, -22, -44, 0, 41, 29, 17, 21, - }, { - 76, -35, -31, -28, -49, 43, -40, 0, 29, -14, - 8, 5, 10, 18, -26, -46, 0, 7, 6, 3, - -25, -7, -2, 40, 28, 14, 18, -3, -27, -28, - -8, -45, -13, 34, -13, -27, -15, 31, 12, 3, - }, { - 7, -15, -9, 9, -28, 29, -45, 5, -6, -43, - -9, 12, 2, 36, -12, -30, -11, 3, 17, 3, - -34, -22, 3, 24, 12, 24, 2, 32, -28, -22, - -29, -29, 5, 50, -21, -31, -38, 29, 7, -5, - }, { - 36, -29, -19, -41, -34, 18, -45, -6, 8, -10, - -5, 43, 23, 11, -42, -53, 5, 5, 6, 30, - 14, -8, 20, 26, 1, 16, 25, 4, 3, -15, - 7, -41, -23, -3, -4, -3, 8, 48, -1, 17, - }, { - -32, -8, 3, -2, -13, 4, -50, -1, -27, -39, - -23, 51, 15, 30, -27, -37, -7, 1, 17, 29, - 5, -23, 25, 10, -14, 26, 8, 41, 1, -9, - -13, -26, -5, 12, -12, -7, -14, 45, -6, 9, - }, { - 31, -24, -23, -27, -29, -9, -43, 8, 26, -7, - 30, -17, -4, 3, -26, -35, 5, -24, -10, -28, - -9, 12, 5, 33, 5, 8, 5, -29, -26, -24, - 9, -23, -14, 12, -39, -52, 5, 18, 39, 24, - }, { - -37, -3, 0, 10, -7, -22, -48, 12, -8, -36, - 12, -9, -12, 22, -12, -19, -6, -28, 0, -29, - -18, -3, 11, 17, -10, 18, -10, 7, -27, -18, - -11, -7, 3, 28, -47, -55, -18, 15, 34, 16, - }, { - -8, -17, -10, -40, -13, -34, -47, 0, 5, -4, - 16, 21, 8, -2, -42, -43, 10, -26, -10, -2, - 31, 11, 27, 19, -21, 10, 12, -20, 3, -11, - 25, -20, -25, -25, -29, -28, 28, 34, 25, 38, - }, { - -77, 2, 11, -1, 7, -47, -52, 5, -29, -33, - -1, 28, 0, 15, -28, -26, -2, -30, 0, -2, - 22, -4, 33, 3, -36, 21, -3, 15, 2, -5, - 4, -4, -6, -9, -37, -31, 5, 32, 20, 30, - }, { - 81, -25, -14, -8, -61, 0, -25, 28, 54, 20, - -3, -14, 17, -8, 0, -44, 16, 35, 13, 18, - -43, -7, 6, 11, 33, -4, 30, 11, -22, -40, - 6, -43, 3, 50, -14, -18, 22, 18, -1, -16, - }, { - 12, -4, 8, 29, -39, -12, -30, 33, 19, -8, - -21, -6, 8, 9, 13, -28, 4, 31, 24, 18, - -52, -23, 12, -4, 18, 5, 14, 47, -24, -34, - -14, -27, 22, 66, -22, -22, -1, 16, -6, -24, - }, { - 41, -18, -2, -21, -45, -24, -30, 21, 33, 24, - -17, 24, 29, -15, -16, -51, 21, 33, 13, 45, - -3, -8, 28, -2, 7, -2, 37, 19, 7, -27, - 22, -39, -7, 12, -5, 5, 45, 35, -15, -1, - }, { - -27, 1, 20, 17, -24, -38, -35, 26, -1, -4, - -35, 32, 21, 3, -2, -35, 8, 29, 24, 44, - -12, -24, 34, -18, -8, 7, 21, 55, 5, -21, - 2, -23, 11, 28, -13, 1, 22, 33, -21, -10, - }, { - 36, -13, -5, -7, -40, -51, -28, 36, 52, 27, - 18, -36, 2, -22, 0, -33, 21, 2, -3, -13, - -26, 11, 14, 4, 10, -10, 18, -14, -22, -36, - 24, -21, 1, 28, -40, -42, 42, 5, 25, 5, - }, { - -32, 6, 17, 31, -19, -65, -33, 41, 16, -1, - 0, -29, -6, -4, 13, -17, 9, -1, 8, -14, - -35, -3, 19, -11, -4, 0, 1, 21, -23, -30, - 3, -5, 20, 44, -48, -46, 19, 3, 20, -3, - }, { - -3, -7, 6, -20, -25, -77, -32, 29, 31, 30, - 4, 2, 14, -29, -16, -40, 26, 0, -3, 12, - 13, 10, 36, -9, -15, -8, 24, -6, 7, -22, - 40, -17, -8, -9, -31, -18, 66, 22, 11, 19, - }, { - -72, 13, 29, 18, -4, -90, -37, 34, -4, 1, - -13, 9, 6, -11, -2, -24, 13, -3, 7, 11, - 4, -4, 42, -25, -31, 1, 8, 29, 6, -17, - 19, -2, 10, 6, -38, -22, 42, 19, 6, 11, - }, { - 116, -20, -68, -30, -28, 83, 28, -18, 32, -22, - -13, -21, 5, 28, 5, -7, -24, -8, -22, 17, - -23, 30, -25, 45, 15, -9, -11, -18, 22, -10, - 4, -2, 19, -12, 23, 3, -43, 2, 12, -4, - }, { - 47, 0, -45, 7, -7, 69, 23, -13, -2, -51, - -32, -14, -3, 47, 19, 8, -37, -11, -10, 16, - -32, 15, -19, 29, 0, 1, -28, 18, 20, -4, - -16, 13, 38, 3, 15, 0, -66, 0, 7, -13, - }, { - 77, -13, -56, -43, -13, 57, 23, -26, 11, -19, - -27, 16, 17, 22, -10, -15, -19, -10, -22, 43, - 16, 30, -2, 31, -11, -6, -5, -9, 52, 2, - 20, 0, 8, -50, 33, 27, -19, 19, -1, 9, - }, { - 8, 6, -33, -4, 7, 44, 18, -21, -23, -48, - -46, 24, 9, 40, 3, 1, -32, -13, -11, 43, - 7, 14, 3, 15, -26, 3, -21, 26, 50, 8, - 0, 16, 27, -34, 25, 23, -43, 17, -6, 1, - }, { - 71, -9, -59, -29, -8, 30, 26, -11, 30, -16, - 8, -44, -9, 14, 5, 2, -19, -40, -38, -15, - -7, 50, -17, 38, -7, -14, -24, -43, 22, -6, - 22, 19, 17, -34, -2, -20, -23, -10, 39, 16, - }, { - 2, 11, -36, 9, 13, 17, 21, -6, -5, -45, - -10, -36, -18, 33, 19, 19, -31, -44, -27, -15, - -16, 34, -11, 22, -22, -4, -40, -7, 21, 0, - 1, 35, 36, -18, -10, -24, -46, -12, 34, 8, - }, { - 32, -2, -47, -42, 7, 5, 21, -18, 9, -12, - -5, -5, 2, 8, -10, -4, -14, -42, -38, 10, - 33, 49, 5, 24, -33, -12, -17, -35, 52, 6, - 38, 22, 7, -72, 7, 3, 0, 6, 25, 30, - }, { - -36, 18, -24, -3, 28, -7, 16, -13, -26, -41, - -24, 1, -5, 26, 3, 12, -27, -46, -27, 10, - 24, 34, 10, 8, -49, -2, -34, 0, 51, 12, - 17, 38, 25, -56, 0, 0, -22, 3, 20, 22, - }, { - 121, -9, -50, -10, -40, 40, 43, 9, 58, 12, - -25, -41, 11, 2, 31, -5, -8, 19, -15, 32, - -41, 30, -16, 16, 20, -28, 0, -3, 26, -22, - 19, 0, 36, 4, 22, 12, -6, -9, -1, -24, - }, { - 52, 10, -27, 27, -18, 26, 38, 14, 23, -16, - -44, -33, 3, 20, 45, 10, -20, 15, -3, 31, - -50, 14, -10, 0, 5, -17, -15, 32, 24, -16, - -1, 15, 55, 20, 14, 8, -29, -12, -7, -32, - }, { - 82, -3, -38, -23, -24, 15, 38, 2, 37, 15, - -39, -2, 23, -4, 15, -12, -3, 17, -15, 58, - -1, 29, 6, 2, -5, -26, 7, 4, 56, -9, - 35, 3, 25, -33, 32, 36, 17, 7, -15, -9, - }, { - 13, 17, -15, 15, -3, 1, 33, 7, 1, -12, - -58, 5, 15, 13, 29, 3, -16, 13, -4, 57, - -10, 13, 11, -13, -21, -15, -9, 40, 55, -3, - 14, 19, 44, -17, 24, 32, -5, 4, -21, -18, - }, { - 76, 1, -41, -9, -19, -12, 41, 17, 55, 18, - -3, -63, -3, -12, 30, 5, -3, -12, -31, 0, - -24, 49, -8, 9, -1, -33, -12, -29, 27, -18, - 37, 21, 34, -17, -3, -11, 14, -23, 25, -2, - }, { - 7, 22, -18, 29, 1, -25, 36, 21, 20, -9, - -22, -56, -11, 6, 45, 21, -15, -16, -20, -1, - -33, 34, -2, -6, -17, -23, -28, 6, 25, -12, - 16, 37, 53, -1, -11, -15, -8, -25, 20, -11, - }, { - 37, 8, -29, -22, -4, -37, 36, 9, 34, 22, - -17, -24, 8, -18, 15, -2, 1, -14, -31, 25, - 15, 48, 13, -4, -28, -31, -5, -21, 57, -4, - 53, 24, 23, -55, 6, 12, 37, -6, 11, 11, - }, { - -31, 28, -6, 16, 16, -50, 31, 14, 0, -6, - -36, -17, 0, 0, 29, 14, -11, -18, -20, 25, - 6, 33, 19, -20, -43, -21, -21, 14, 55, 0, - 32, 40, 42, -39, -1, 8, 14, -8, 6, 3, - }, { - 119, -24, -39, -44, -51, 66, -14, 15, 31, -26, - -1, 0, 7, 16, -19, -28, -19, 22, -26, 4, - -13, 28, -16, 29, 5, -1, 16, -16, 8, -35, - -10, -42, -4, 17, 29, -19, -42, -7, 0, -15, - }, { - 50, -3, -16, -5, -30, 53, -19, 20, -3, -55, - -19, 8, 0, 34, -5, -11, -32, 18, -15, 4, - -22, 13, -10, 13, -9, 8, 0, 19, 7, -29, - -31, -26, 13, 33, 21, -22, -65, -9, -4, -23, - }, { - 79, -17, -27, -56, -36, 41, -19, 8, 10, -22, - -15, 39, 20, 9, -35, -35, -15, 20, -26, 31, - 26, 27, 6, 15, -20, 0, 23, -8, 38, -22, - 5, -38, -15, -20, 39, 4, -18, 9, -13, -1, - }, { - 10, 3, -4, -18, -15, 27, -24, 13, -24, -51, - -34, 47, 12, 28, -21, -19, -27, 16, -15, 30, - 17, 12, 12, 0, -36, 10, 7, 27, 37, -16, - -15, -22, 3, -4, 31, 1, -42, 7, -18, -9, - }, { - 74, -12, -30, -42, -30, 14, -16, 23, 29, -19, - 20, -21, -7, 1, -19, -17, -14, -10, -43, -27, - 3, 48, -8, 22, -16, -7, 4, -42, 9, -31, - 6, -20, -6, -4, 3, -43, -22, -20, 28, 5, - }, { - 5, 7, -7, -4, -9, 0, -21, 28, -6, -48, - 2, -14, -15, 20, -5, 0, -27, -14, -32, -28, - -5, 32, -2, 6, -32, 3, -12, -5, 8, -25, - -14, -4, 12, 11, -4, -47, -45, -22, 22, -2, - }, { - 34, -6, -18, -55, -15, -11, -21, 16, 8, -16, - 6, 16, 5, -4, -35, -24, -10, -12, -43, -1, - 43, 47, 14, 8, -43, -5, 10, -34, 39, -18, - 22, -16, -17, -42, 13, -19, 1, -3, 14, 20, - }, { - -34, 14, 4, -17, 5, -24, -26, 20, -27, -45, - -12, 24, -2, 13, -21, -8, -22, -16, -32, -2, - 34, 31, 20, -7, -58, 5, -5, 2, 38, -12, - 2, -1, 1, -26, 5, -23, -21, -6, 8, 11, - }, { - 124, -13, -21, -23, -62, 23, 0, 43, 57, 8, - -13, -18, 14, -10, 6, -26, -3, 49, -19, 19, - -31, 27, -7, 0, 11, -20, 29, -1, 12, -47, - 4, -39, 11, 34, 28, -9, -5, -19, -13, -34, - }, { - 55, 6, 1, 14, -41, 10, -4, 48, 22, -20, - -31, -10, 5, 7, 20, -9, -16, 45, -8, 19, - -40, 12, -1, -15, -4, -10, 12, 34, 11, -41, - -16, -24, 30, 49, 20, -13, -28, -22, -18, -43, - }, { - 84, -6, -9, -36, -47, -1, -4, 36, 36, 12, - -27, 20, 26, -17, -9, -33, 1, 47, -19, 46, - 9, 27, 15, -13, -15, -18, 35, 6, 42, -33, - 20, -36, 1, -4, 38, 14, 18, -2, -27, -20, - }, { - 15, 13, 13, 1, -26, -14, -9, 41, 1, -16, - -46, 27, 18, 1, 4, -16, -11, 43, -8, 45, - 0, 11, 21, -29, -30, -8, 19, 42, 41, -28, - 0, -20, 20, 11, 30, 10, -4, -5, -32, -28, - }, { - 79, -2, -12, -22, -42, -28, -1, 51, 54, 15, - 8, -41, 0, -24, 6, -15, 1, 17, -36, -12, - -14, 47, 0, -6, -11, -26, 16, -27, 13, -43, - 22, -18, 10, 12, 2, -34, 15, -33, 13, -13, - }, { - 10, 18, 10, 15, -21, -41, -6, 56, 19, -13, - -9, -33, -9, -6, 20, 1, -11, 13, -24, -13, - -23, 32, 6, -22, -26, -15, 0, 8, 12, -37, - 1, -2, 28, 27, -5, -37, -7, -35, 8, -21, - }, { - 39, 4, 0, -35, -27, -53, -6, 44, 33, 18, - -5, -2, 11, -31, -9, -22, 6, 15, -36, 13, - 25, 46, 23, -20, -37, -24, 23, -19, 43, -29, - 38, -14, 0, -26, 12, -10, 38, -16, 0, 0, - }, { - -29, 25, 22, 2, -6, -67, -11, 49, -1, -10, - -24, 5, 3, -13, 4, -5, -6, 11, -25, 12, - 16, 31, 28, -36, -53, -13, 6, 16, 42, -24, - 17, 1, 18, -10, 4, -13, 15, -18, -5, -7, - }, { - 29, -25, -22, -2, 6, 67, 11, -49, 1, 10, - 24, -5, -3, 13, -4, 5, 6, -11, 25, -12, - -16, -31, -28, 36, 53, 13, -6, -16, -42, 24, - -17, -1, -18, 10, -4, 13, -15, 18, 5, 7, - }, { - -39, -4, 0, 35, 27, 53, 6, -44, -33, -18, - 5, 2, -11, 31, 9, 22, -6, -15, 36, -13, - -25, -46, -23, 20, 37, 24, -23, 19, -43, 29, - -38, 14, 0, 26, -12, 10, -38, 16, 0, 0, - }, { - -10, -18, -10, -15, 21, 41, 6, -56, -19, 13, - 9, 33, 9, 6, -20, -1, 11, -13, 24, 13, - 23, -32, -6, 22, 26, 15, 0, -8, -12, 37, - -1, 2, -28, -27, 5, 37, 7, 35, -8, 21, - }, { - -79, 2, 12, 22, 42, 28, 1, -51, -54, -15, - -8, 41, 0, 24, -6, 15, -1, -17, 36, 12, - 14, -47, 0, 6, 11, 26, -16, 27, -13, 43, - -22, 18, -10, -12, -2, 34, -15, 33, -13, 13, - }, { - -15, -13, -13, -1, 26, 14, 9, -41, -1, 16, - 46, -27, -18, -1, -4, 16, 11, -43, 8, -45, - 0, -11, -21, 29, 30, 8, -19, -42, -41, 28, - 0, 20, -20, -11, -30, -10, 4, 5, 32, 28, - }, { - -84, 6, 9, 36, 47, 1, 4, -36, -36, -12, - 27, -20, -26, 17, 9, 33, -1, -47, 19, -46, - -9, -27, -15, 13, 15, 18, -35, -6, -42, 33, - -20, 36, -1, 4, -38, -14, -18, 2, 27, 20, - }, { - -55, -6, -1, -14, 41, -10, 4, -48, -22, 20, - 31, 10, -5, -7, -20, 9, 16, -45, 8, -19, - 40, -12, 1, 15, 4, 10, -12, -34, -11, 41, - 16, 24, -30, -49, -20, 13, 28, 22, 18, 43, - }, { - -124, 13, 21, 23, 62, -23, 0, -43, -57, -8, - 13, 18, -14, 10, -6, 26, 3, -49, 19, -19, - 31, -27, 7, 0, -11, 20, -29, 1, -12, 47, - -4, 39, -11, -34, -28, 9, 5, 19, 13, 34, - }, { - 34, -14, -4, 17, -5, 24, 26, -20, 27, 45, - 12, -24, 2, -13, 21, 8, 22, 16, 32, 2, - -34, -31, -20, 7, 58, -5, 5, -2, -38, 12, - -2, 1, -1, 26, -5, 23, 21, 6, -8, -11, - }, { - -34, 6, 18, 55, 15, 11, 21, -16, -8, 16, - -6, -16, -5, 4, 35, 24, 10, 12, 43, 1, - -43, -47, -14, -8, 43, 5, -10, 34, -39, 18, - -22, 16, 17, 42, -13, 19, -1, 3, -14, -20, - }, { - -5, -7, 7, 4, 9, 0, 21, -28, 6, 48, - -2, 14, 15, -20, 5, 0, 27, 14, 32, 28, - 5, -32, 2, -6, 32, -3, 12, 5, -8, 25, - 14, 4, -12, -11, 4, 47, 45, 22, -22, 2, - }, { - -74, 12, 30, 42, 30, -14, 16, -23, -29, 19, - -20, 21, 7, -1, 19, 17, 14, 10, 43, 27, - -3, -48, 8, -22, 16, 7, -4, 42, -9, 31, - -6, 20, 6, 4, -3, 43, 22, 20, -28, -5, - }, { - -10, -3, 4, 18, 15, -27, 24, -13, 24, 51, - 34, -47, -12, -28, 21, 19, 27, -16, 15, -30, - -17, -12, -12, 0, 36, -10, -7, -27, -37, 16, - 15, 22, -3, 4, -31, -1, 42, -7, 18, 9, - }, { - -79, 17, 27, 56, 36, -41, 19, -8, -10, 22, - 15, -39, -20, -9, 35, 35, 15, -20, 26, -31, - -26, -27, -6, -15, 20, 0, -23, 8, -38, 22, - -5, 38, 15, 20, -39, -4, 18, -9, 13, 1, - }, { - -50, 3, 16, 5, 30, -53, 19, -20, 3, 55, - 19, -8, 0, -34, 5, 11, 32, -18, 15, -4, - 22, -13, 10, -13, 9, -8, 0, -19, -7, 29, - 31, 26, -13, -33, -21, 22, 65, 9, 4, 23, - }, { - -119, 24, 39, 44, 51, -66, 14, -15, -31, 26, - 1, 0, -7, -16, 19, 28, 19, -22, 26, -4, - 13, -28, 16, -29, -5, 1, -16, 16, -8, 35, - 10, 42, 4, -17, -29, 19, 42, 7, 0, 15, - }, { - 31, -28, 6, -16, -16, 50, -31, -14, 0, 6, - 36, 17, 0, 0, -29, -14, 11, 18, 20, -25, - -6, -33, -19, 20, 43, 21, 21, -14, -55, 0, - -32, -40, -42, 39, 1, -8, -14, 8, -6, -3, - }, { - -37, -8, 29, 22, 4, 37, -36, -9, -34, -22, - 17, 24, -8, 18, -15, 2, -1, 14, 31, -25, - -15, -48, -13, 4, 28, 31, 5, 21, -57, 4, - -53, -24, -23, 55, -6, -12, -37, 6, -11, -11, - }, { - -7, -22, 18, -29, -1, 25, -36, -21, -20, 9, - 22, 56, 11, -6, -45, -21, 15, 16, 20, 1, - 33, -34, 2, 6, 17, 23, 28, -6, -25, 12, - -16, -37, -53, 1, 11, 15, 8, 25, -20, 11, - }, { - -76, -1, 41, 9, 19, 12, -41, -17, -55, -18, - 3, 63, 3, 12, -30, -5, 3, 12, 31, 0, - 24, -49, 8, -9, 1, 33, 12, 29, -27, 18, - -37, -21, -34, 17, 3, 11, -14, 23, -25, 2, - }, { - -13, -17, 15, -15, 3, -1, -33, -7, -1, 12, - 58, -5, -15, -13, -29, -3, 16, -13, 4, -57, - 10, -13, -11, 13, 21, 15, 9, -40, -55, 3, - -14, -19, -44, 17, -24, -32, 5, -4, 21, 18, - }, { - -82, 3, 38, 23, 24, -15, -38, -2, -37, -15, - 39, 2, -23, 4, -15, 12, 3, -17, 15, -58, - 1, -29, -6, -2, 5, 26, -7, -4, -56, 9, - -35, -3, -25, 33, -32, -36, -17, -7, 15, 9, - }, { - -52, -10, 27, -27, 18, -26, -38, -14, -23, 16, - 44, 33, -3, -20, -45, -10, 20, -15, 3, -31, - 50, -14, 10, 0, -5, 17, 15, -32, -24, 16, - 1, -15, -55, -20, -14, -8, 29, 12, 7, 32, - }, { - -121, 9, 50, 10, 40, -40, -43, -9, -58, -12, - 25, 41, -11, -2, -31, 5, 8, -19, 15, -32, - 41, -30, 16, -16, -20, 28, 0, 3, -26, 22, - -19, 0, -36, -4, -22, -12, 6, 9, 1, 24, - }, { - 36, -18, 24, 3, -28, 7, -16, 13, 26, 41, - 24, -1, 5, -26, -3, -12, 27, 46, 27, -10, - -24, -34, -10, -8, 49, 2, 34, 0, -51, -12, - -17, -38, -25, 56, 0, 0, 22, -3, -20, -22, - }, { - -32, 2, 47, 42, -7, -5, -21, 18, -9, 12, - 5, 5, -2, -8, 10, 4, 14, 42, 38, -10, - -33, -49, -5, -24, 33, 12, 17, 35, -52, -6, - -38, -22, -7, 72, -7, -3, 0, -6, -25, -30, - }, { - -2, -11, 36, -9, -13, -17, -21, 6, 5, 45, - 10, 36, 18, -33, -19, -19, 31, 44, 27, 15, - 16, -34, 11, -22, 22, 4, 40, 7, -21, 0, - -1, -35, -36, 18, 10, 24, 46, 12, -34, -8, - }, { - -71, 9, 59, 29, 8, -30, -26, 11, -30, 16, - -8, 44, 9, -14, -5, -2, 19, 40, 38, 15, - 7, -50, 17, -38, 7, 14, 24, 43, -22, 6, - -22, -19, -17, 34, 2, 20, 23, 10, -39, -16, - }, { - -8, -6, 33, 4, -7, -44, -18, 21, 23, 48, - 46, -24, -9, -40, -3, -1, 32, 13, 11, -43, - -7, -14, -3, -15, 26, -3, 21, -26, -50, -8, - 0, -16, -27, 34, -25, -23, 43, -17, 6, -1, - }, { - -77, 13, 56, 43, 13, -57, -23, 26, -11, 19, - 27, -16, -17, -22, 10, 15, 19, 10, 22, -43, - -16, -30, 2, -31, 11, 6, 5, 9, -52, -2, - -20, 0, -8, 50, -33, -27, 19, -19, 1, -9, - }, { - -47, 0, 45, -7, 7, -69, -23, 13, 2, 51, - 32, 14, 3, -47, -19, -8, 37, 11, 10, -16, - 32, -15, 19, -29, 0, -1, 28, -18, -20, 4, - 16, -13, -38, -3, -15, 0, 66, 0, -7, 13, - }, { - -116, 20, 68, 30, 28, -83, -28, 18, -32, 22, - 13, 21, -5, -28, -5, 7, 24, 8, 22, -17, - 23, -30, 25, -45, -15, 9, 11, 18, -22, 10, - -4, 2, -19, 12, -23, -3, 43, -2, -12, 4, - }, { - 72, -13, -29, -18, 4, 90, 37, -34, 4, -1, - 13, -9, -6, 11, 2, 24, -13, 3, -7, -11, - -4, 4, -42, 25, 31, -1, -8, -29, -6, 17, - -19, 2, -10, -6, 38, 22, -42, -19, -6, -11, - }, { - 3, 7, -6, 20, 25, 77, 32, -29, -31, -30, - -4, -2, -14, 29, 16, 40, -26, 0, 3, -12, - -13, -10, -36, 9, 15, 8, -24, 6, -7, 22, - -40, 17, 8, 9, 31, 18, -66, -22, -11, -19, - }, { - 32, -6, -17, -31, 19, 65, 33, -41, -16, 1, - 0, 29, 6, 4, -13, 17, -9, 1, -8, 14, - 35, 3, -19, 11, 4, 0, -1, -21, 23, 30, - -3, 5, -20, -44, 48, 46, -19, -3, -20, 3, - }, { - -36, 13, 5, 7, 40, 51, 28, -36, -52, -27, - -18, 36, -2, 22, 0, 33, -21, -2, 3, 13, - 26, -11, -14, -4, -10, 10, -18, 14, 22, 36, - -24, 21, -1, -28, 40, 42, -42, -5, -25, -5, - }, { - 27, -1, -20, -17, 24, 38, 35, -26, 1, 4, - 35, -32, -21, -3, 2, 35, -8, -29, -24, -44, - 12, 24, -34, 18, 8, -7, -21, -55, -5, 21, - -2, 23, -11, -28, 13, -1, -22, -33, 21, 10, - }, { - -41, 18, 2, 21, 45, 24, 30, -21, -33, -24, - 17, -24, -29, 15, 16, 51, -21, -33, -13, -45, - 3, 8, -28, 2, -7, 2, -37, -19, -7, 27, - -22, 39, 7, -12, 5, -5, -45, -35, 15, 1, - }, { - -12, 4, -8, -29, 39, 12, 30, -33, -19, 8, - 21, 6, -8, -9, -13, 28, -4, -31, -24, -18, - 52, 23, -12, 4, -18, -5, -14, -47, 24, 34, - 14, 27, -22, -66, 22, 22, 1, -16, 6, 24, - }, { - -81, 25, 14, 8, 61, 0, 25, -28, -54, -20, - 3, 14, -17, 8, 0, 44, -16, -35, -13, -18, - 43, 7, -6, -11, -33, 4, -30, -11, 22, 40, - -6, 43, -3, -50, 14, 18, -22, -18, 1, 16, - }, { - 77, -2, -11, 1, -7, 47, 52, -5, 29, 33, - 1, -28, 0, -15, 28, 26, 2, 30, 0, 2, - -22, 4, -33, -3, 36, -21, 3, -15, -2, 5, - -4, 4, 6, 9, 37, 31, -5, -32, -20, -30, - }, { - 8, 17, 10, 40, 13, 34, 47, 0, -5, 4, - -16, -21, -8, 2, 42, 43, -10, 26, 10, 2, - -31, -11, -27, -19, 21, -10, -12, 20, -3, 11, - -25, 20, 25, 25, 29, 28, -28, -34, -25, -38, - }, { - 37, 3, 0, -10, 7, 22, 48, -12, 8, 36, - -12, 9, 12, -22, 12, 19, 6, 28, 0, 29, - 18, 3, -11, -17, 10, -18, 10, -7, 27, 18, - 11, 7, -3, -28, 47, 55, 18, -15, -34, -16, - }, { - -31, 24, 23, 27, 29, 9, 43, -8, -26, 7, - -30, 17, 4, -3, 26, 35, -5, 24, 10, 28, - 9, -12, -5, -33, -5, -8, -5, 29, 26, 24, - -9, 23, 14, -12, 39, 52, -5, -18, -39, -24, - }, { - 32, 8, -3, 2, 13, -4, 50, 1, 27, 39, - 23, -51, -15, -30, 27, 37, 7, -1, -17, -29, - -5, 23, -25, -10, 14, -26, -8, -41, -1, 9, - 13, 26, 5, -12, 12, 7, 14, -45, 6, -9, - }, { - -36, 29, 19, 41, 34, -18, 45, 6, -8, 10, - 5, -43, -23, -11, 42, 53, -5, -5, -6, -30, - -14, 8, -20, -26, -1, -16, -25, -4, -3, 15, - -7, 41, 23, 3, 4, 3, -8, -48, 1, -17, - }, { - -7, 15, 9, -9, 28, -29, 45, -5, 6, 43, - 9, -12, -2, -36, 12, 30, 11, -3, -17, -3, - 34, 22, -3, -24, -12, -24, -2, -32, 28, 22, - 29, 29, -5, -50, 21, 31, 38, -29, -7, 5, - }, { - -76, 35, 31, 28, 49, -43, 40, 0, -29, 14, - -8, -5, -10, -18, 26, 46, 0, -7, -6, -3, - 25, 7, 2, -40, -28, -14, -18, 3, 27, 28, - 8, 45, 13, -34, 13, 27, 15, -31, -12, -3, - }, { - 74, -17, 0, -31, -18, 73, -5, 0, 3, -5, - 25, 12, -3, -1, -22, 3, -9, 33, -12, -24, - 6, 2, -33, 9, 21, 5, 20, -27, -19, -7, - -34, -37, -34, 22, 44, 0, -41, -29, -17, -21, - }, { - 5, 3, 21, 7, 2, 60, -10, 5, -32, -34, - 7, 20, -11, 16, -8, 20, -21, 29, -1, -24, - -2, -13, -27, -6, 5, 15, 3, 8, -21, -1, - -55, -21, -15, 38, 37, -3, -65, -32, -23, -30, - }, { - 35, -10, 11, -44, -3, 48, -10, -6, -17, -2, - 11, 51, 8, -8, -38, -3, -4, 31, -12, 2, - 46, 1, -10, -4, -5, 7, 26, -19, 10, 5, - -18, -34, -45, -15, 54, 24, -18, -13, -31, -7, - }, { - -33, 10, 34, -5, 17, 35, -15, -1, -53, -30, - -6, 59, 0, 10, -24, 13, -17, 27, -1, 1, - 37, -13, -4, -20, -20, 18, 10, 16, 8, 11, - -39, -18, -26, 0, 46, 20, -41, -15, -37, -15, - }, { - 29, -5, 7, -30, 1, 21, -7, 7, 0, 0, - 47, -9, -18, -15, -22, 14, -4, 0, -28, -57, - 23, 21, -25, 2, -1, 0, 7, -53, -19, -3, - -17, -15, -36, 0, 19, -24, -21, -43, 9, 0, - }, { - -39, 14, 30, 8, 22, 8, -12, 12, -34, -27, - 29, -2, -26, 2, -8, 31, -16, -3, -17, -57, - 14, 6, -19, -13, -16, 10, -8, -17, -20, 2, - -38, 0, -17, 16, 11, -27, -44, -45, 4, -8, - }, { - -9, 1, 20, -43, 17, -3, -12, 0, -20, 4, - 33, 29, -6, -22, -38, 7, 0, -1, -29, -30, - 63, 21, -3, -11, -27, 1, 14, -45, 10, 9, - -1, -12, -47, -37, 28, 0, 2, -26, -4, 13, - }, { - -78, 21, 43, -4, 38, -17, -17, 5, -55, -24, - 15, 36, -14, -4, -24, 24, -12, -5, -17, -31, - 54, 5, 2, -27, -43, 12, -2, -9, 9, 15, - -22, 3, -28, -21, 20, -3, -20, -28, -9, 5, - }, { - 80, -6, 16, -11, -30, 30, 9, 28, 28, 29, - 13, -6, 2, -28, 3, 5, 7, 60, -5, -9, - -11, 1, -24, -19, 27, -13, 32, -13, -15, -19, - -19, -35, -17, 39, 43, 9, -4, -42, -32, -41, - }, { - 11, 14, 39, 27, -9, 17, 4, 33, -6, 0, - -4, 1, -5, -10, 17, 22, -5, 57, 5, -9, - -20, -13, -18, -35, 11, -3, 16, 22, -17, -13, - -40, -19, 1, 55, 35, 5, -27, -44, -37, -49, - }, { - 40, 0, 28, -24, -14, 5, 4, 21, 7, 33, - 0, 32, 15, -35, -12, -1, 11, 58, -5, 16, - 28, 0, -1, -33, 0, -11, 39, -5, 14, -6, - -3, -31, -28, 1, 53, 33, 19, -25, -46, -26, - }, { - -28, 20, 51, 14, 6, -7, 0, 26, -27, 4, - -18, 40, 6, -16, 1, 15, 0, 55, 5, 16, - 19, -14, 3, -49, -14, -1, 22, 30, 12, 0, - -24, -15, -9, 17, 45, 29, -4, -28, -51, -35, - }, { - 34, 4, 25, -10, -9, -21, 7, 36, 26, 36, - 35, -28, -12, -42, 3, 16, 12, 28, -21, -42, - 5, 21, -16, -26, 4, -19, 19, -39, -15, -15, - -1, -13, -19, 17, 17, -14, 15, -55, -4, -19, - }, { - -34, 25, 48, 28, 11, -34, 2, 41, -9, 7, - 17, -21, -20, -24, 17, 33, 0, 24, -10, -42, - -3, 5, -10, -42, -11, -8, 3, -3, -16, -9, - -22, 2, 0, 33, 10, -18, -7, -58, -10, -28, - }, { - -4, 11, 37, -23, 5, -46, 2, 29, 5, 39, - 21, 9, 0, -49, -12, 9, 16, 26, -22, -15, - 45, 20, 5, -40, -22, -17, 26, -31, 14, -2, - 14, -10, -30, -20, 27, 9, 39, -39, -18, -5, - }, { - -73, 32, 60, 15, 26, -59, -2, 33, -30, 10, - 3, 17, -8, -30, 1, 26, 4, 22, -10, -16, - 36, 5, 11, -56, -37, -6, 10, 5, 13, 3, - -6, 5, -11, -4, 19, 5, 16, -41, -24, -13 - } -}; - -static const uint16_t cb1_base[128]={ - 19657, 18474, 18365, 17520, 21048, 18231, 18584, 16671, - 20363, 19069, 19409, 18430, 21844, 18753, 19613, 17411, - 20389, 21772, 20129, 21702, 20978, 20472, 19627, 19387, - 21477, 23134, 21841, 23919, 22089, 21519, 21134, 20852, - 19675, 17821, 19044, 17477, 19986, 16955, 18446, 16086, - 21138, 18899, 20952, 18929, 21452, 17833, 20104, 17159, - 19770, 20056, 20336, 20866, 19329, 18217, 18908, 18004, - 21556, 21948, 23079, 23889, 20922, 19544, 20984, 19781, - 19781, 20984, 19544, 20922, 23889, 23079, 21948, 21556, - 18004, 18908, 18217, 19329, 20866, 20336, 20056, 19770, - 17159, 20104, 17833, 21452, 18929, 20952, 18899, 21138, - 16086, 18446, 16955, 19986, 17477, 19044, 17821, 19675, - 20852, 21134, 21519, 22089, 23919, 21841, 23134, 21477, - 19387, 19627, 20472, 20978, 21702, 20129, 21772, 20389, - 17411, 19613, 18753, 21844, 18430, 19409, 19069, 20363, - 16671, 18584, 18231, 21048, 17520, 18365, 18474, 19657, -}; - -static const uint16_t cb2_base[128]={ - 12174, 13380, 13879, 13832, 13170, 13227, 13204, 12053, - 12410, 13988, 14348, 14631, 13100, 13415, 13224, 12268, - 11982, 13825, 13499, 14210, 13877, 14788, 13811, 13109, - 11449, 13275, 12833, 13717, 12728, 13696, 12759, 12405, - 10230, 12185, 11628, 13161, 11762, 13458, 12312, 12818, - 10443, 12773, 12011, 14020, 11818, 13825, 12453, 13226, - 10446, 13162, 11881, 14300, 12859, 16288, 13490, 15053, - 10155, 12820, 11519, 13973, 12041, 15081, 12635, 14198, - 14198, 12635, 15081, 12041, 13973, 11519, 12820, 10155, - 15053, 13490, 16288, 12859, 14300, 11881, 13162, 10446, - 13226, 12453, 13825, 11818, 14020, 12011, 12773, 10443, - 12818, 12312, 13458, 11762, 13161, 11628, 12185, 10230, - 12405, 12759, 13696, 12728, 13717, 12833, 13275, 11449, - 13109, 13811, 14788, 13877, 14210, 13499, 13825, 11982, - 12268, 13224, 13415, 13100, 14631, 14348, 13988, 12410, - 12053, 13204, 13227, 13170, 13832, 13879, 13380, 12174, -}; - -static const int16_t energy_tab[32]={ - 0, 16, 20, 25, 32, 41, 51, 65, - 81, 103, 129, 163, 205, 259, 326, 410, - 516, 650, 819, 1031, 1298, 1634, 2057, 2590, - 3261, 4105, 5168, 6507, 8192, 10313, 12983, 16345 -}; - -static const int16_t lpc_refl_cb1[64]={ - -4041, -4018, -3998, -3977, -3954, -3930, -3906, -3879, - -3852, -3825, -3795, -3764, -3731, -3699, -3666, -3631, - -3594, -3555, -3513, -3468, -3420, -3372, -3321, -3268, - -3212, -3153, -3090, -3021, -2944, -2863, -2772, -2676, - -2565, -2445, -2328, -2202, -2072, -1941, -1808, -1660, - -1508, -1348, -1185, -994, -798, -600, -374, -110, - 152, 447, 720, 982, 1229, 1456, 1682, 1916, - 2130, 2353, 2595, 2853, 3118, 3363, 3588, 3814 -}; - -static const int16_t lpc_refl_cb2[32]={ - -3091, -2386, -1871, -1425, -1021, -649, -316, -20, - 267, 544, 810, 1065, 1305, 1534, 1756, 1970, - 2171, 2359, 2536, 2700, 2854, 2996, 3133, 3263, - 3386, 3499, 3603, 3701, 3789, 3870, 3947, 4020 -}; - -static const int16_t lpc_refl_cb3[32]={ - -3525, -3295, -3081, -2890, -2696, -2511, -2328, -2149, - -1979, -1817, -1658, -1498, -1341, -1188, -1032, -876, - -721, -561, -394, -228, -54, 119, 296, 484, - 683, 895, 1123, 1373, 1651, 1965, 2360, 2854 -}; - -static const int16_t lpc_refl_cb4[16]={ - -1845, -1057, -522, -77, 301, 647, 975, 1285, - 1582, 1873, 2163, 2452, 2735, 3017, 3299, 3569 -}; - -static const int16_t lpc_refl_cb5[16]={ - -2691, -2187, -1788, -1435, -1118, -837, -571, -316, - -59, 201, 470, 759, 1077, 1457, 1908, 2495 -}; - -static const int16_t lpc_refl_cb6[8]={ - -1372, -474, 133, 632, 1100, 1571, 2075, 2672 -}; - -static const int16_t lpc_refl_cb7[8]={ - -2389, -1787, -1231, -717, -239, 234, 770, 1474 -}; - -static const int16_t lpc_refl_cb8[8]={ - -1569, -864, -296, 200, 670, 1151, 1709, 2385 -}; - -static const int16_t lpc_refl_cb9[8]={ - -2200, -1608, -1062, -569, -120, 338, 863, 1621 -}; - -static const int16_t lpc_refl_cb10[4]={ - -617, 190, 802, 1483 -}; - -static const int16_t * const lpc_refl_cb[10]={ - lpc_refl_cb1, lpc_refl_cb2, lpc_refl_cb3, lpc_refl_cb4, lpc_refl_cb5, - lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10 -}; - -#endif /* AVCODEC_RA144_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ra288.c b/tizen/distrib/ffmpeg/libavcodec/ra288.c deleted file mode 100644 index 20a21f5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ra288.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * RealAudio 2.0 (28.8K) - * Copyright (c) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" -#include "ra288.h" -#include "lpc.h" -#include "celp_math.h" -#include "celp_filters.h" - -typedef struct { - float sp_lpc[36]; ///< LPC coefficients for speech data (spec: A) - float gain_lpc[10]; ///< LPC coefficients for gain (spec: GB) - - /** speech data history (spec: SB). - * Its first 70 coefficients are updated only at backward filtering. - */ - float sp_hist[111]; - - /// speech part of the gain autocorrelation (spec: REXP) - float sp_rec[37]; - - /** log-gain history (spec: SBLG). - * Its first 28 coefficients are updated only at backward filtering. - */ - float gain_hist[38]; - - /// recursive part of the gain autocorrelation (spec: REXPLG) - float gain_rec[11]; -} RA288Context; - -static av_cold int ra288_decode_init(AVCodecContext *avctx) -{ - avctx->sample_fmt = SAMPLE_FMT_FLT; - return 0; -} - -static void apply_window(float *tgt, const float *m1, const float *m2, int n) -{ - while (n--) - *tgt++ = *m1++ * *m2++; -} - -static void convolve(float *tgt, const float *src, int len, int n) -{ - for (; n >= 0; n--) - tgt[n] = ff_dot_productf(src, src - n, len); - -} - -static void decode(RA288Context *ractx, float gain, int cb_coef) -{ - int i; - double sumsum; - float sum, buffer[5]; - float *block = ractx->sp_hist + 70 + 36; // current block - float *gain_block = ractx->gain_hist + 28; - - memmove(ractx->sp_hist + 70, ractx->sp_hist + 75, 36*sizeof(*block)); - - /* block 46 of G.728 spec */ - sum = 32.; - for (i=0; i < 10; i++) - sum -= gain_block[9-i] * ractx->gain_lpc[i]; - - /* block 47 of G.728 spec */ - sum = av_clipf(sum, 0, 60); - - /* block 48 of G.728 spec */ - /* exp(sum * 0.1151292546497) == pow(10.0,sum/20) */ - sumsum = exp(sum * 0.1151292546497) * gain * (1.0/(1<<23)); - - for (i=0; i < 5; i++) - buffer[i] = codetable[cb_coef][i] * sumsum; - - sum = ff_dot_productf(buffer, buffer, 5) * ((1<<24)/5.); - - sum = FFMAX(sum, 1); - - /* shift and store */ - memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block)); - - gain_block[9] = 10 * log10(sum) - 32; - - ff_celp_lp_synthesis_filterf(block, ractx->sp_lpc, buffer, 5, 36); -} - -/** - * Hybrid window filtering, see blocks 36 and 49 of the G.728 specification. - * - * @param order filter order - * @param n input length - * @param non_rec number of non-recursive samples - * @param out filter output - * @param hist pointer to the input history of the filter - * @param out pointer to the non-recursive part of the output - * @param out2 pointer to the recursive part of the output - * @param window pointer to the windowing function table - */ -static void do_hybrid_window(int order, int n, int non_rec, float *out, - float *hist, float *out2, const float *window) -{ - int i; - float buffer1[order + 1]; - float buffer2[order + 1]; - float work[order + n + non_rec]; - - apply_window(work, window, hist, order + n + non_rec); - - convolve(buffer1, work + order , n , order); - convolve(buffer2, work + order + n, non_rec, order); - - for (i=0; i <= order; i++) { - out2[i] = out2[i] * 0.5625 + buffer1[i]; - out [i] = out2[i] + buffer2[i]; - } - - /* Multiply by the white noise correcting factor (WNCF). */ - *out *= 257./256.; -} - -/** - * Backward synthesis filter, find the LPC coefficients from past speech data. - */ -static void backward_filter(float *hist, float *rec, const float *window, - float *lpc, const float *tab, - int order, int n, int non_rec, int move_size) -{ - float temp[order+1]; - - do_hybrid_window(order, n, non_rec, temp, hist, rec, window); - - if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1)) - apply_window(lpc, lpc, tab, order); - - memmove(hist, hist + n, move_size*sizeof(*hist)); -} - -static int ra288_decode_frame(AVCodecContext * avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - float *out = data; - int i, j; - RA288Context *ractx = avctx->priv_data; - GetBitContext gb; - - if (buf_size < avctx->block_align) { - av_log(avctx, AV_LOG_ERROR, - "Error! Input buffer is too small [%d<%d]\n", - buf_size, avctx->block_align); - return 0; - } - - if (*data_size < 32*5*4) - return -1; - - init_get_bits(&gb, buf, avctx->block_align * 8); - - for (i=0; i < 32; i++) { - float gain = amptable[get_bits(&gb, 3)]; - int cb_coef = get_bits(&gb, 6 + (i&1)); - - decode(ractx, gain, cb_coef); - - for (j=0; j < 5; j++) - *(out++) = ractx->sp_hist[70 + 36 + j]; - - if ((i & 7) == 3) { - backward_filter(ractx->sp_hist, ractx->sp_rec, syn_window, - ractx->sp_lpc, syn_bw_tab, 36, 40, 35, 70); - - backward_filter(ractx->gain_hist, ractx->gain_rec, gain_window, - ractx->gain_lpc, gain_bw_tab, 10, 8, 20, 28); - } - } - - *data_size = (char *)out - (char *)data; - return avctx->block_align; -} - -AVCodec ra_288_decoder = -{ - "real_288", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_RA_288, - sizeof(RA288Context), - ra288_decode_init, - NULL, - NULL, - ra288_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ra288.h b/tizen/distrib/ffmpeg/libavcodec/ra288.h deleted file mode 100644 index d7fd4b5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ra288.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * RealAudio 2.0 (28.8K) - * Copyright (c) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_RA288_H -#define AVCODEC_RA288_H - -#include - -static const float amptable[8]={ - 0.515625, 0.90234375, 1.57910156, 2.76342773, - -0.515625, -0.90234375, -1.57910156, -2.76342773 -}; - -static const int16_t codetable[128][5]={ - { 668, -2950, -1254, -1790, -2553}, { -5032, -4577, -1045, 2908, 3318}, - { -2819, -2677, -948, -2825, -4450}, { -6679, -340, 1482, -1276, 1262}, - { -562, -6757, 1281, 179, -1274}, { -2512, -7130, -4925, 6913, 2411}, - { -2478, -156, 4683, -3873, 0}, { -8208, 2140, -478, -2785, 533}, - { 1889, 2759, 1381, -6955, -5913}, { 5082, -2460, -5778, 1797, 568}, - { -2208, -3309, -4523, -6236, -7505}, { -2719, 4358, -2988, -1149, 2664}, - { 1259, 995, 2711, -2464,-10390}, { 1722, -7569, -2742, 2171, -2329}, - { 1032, 747, -858, -7946,-12843}, { 3106, 4856, -4193, -2541, 1035}, - { 1862, -960, -6628, 410, 5882}, { -2493, -2628, -4000, -60, 7202}, - { -2672, 1446, 1536, -3831, 1233}, { -5302, 6912, 1589, -4187, 3665}, - { -3456, -8170, -7709, 1384, 4698}, { -4699, -6209,-11176, 8104, 16830}, - { 930, 7004, 1269, -8977, 2567}, { 4649, 11804, 3441, -5657, 1199}, - { 2542, -183, -8859, -7976, 3230}, { -2872, -2011, -9713, -8385, 12983}, - { 3086, 2140, -3680, -9643, -2896}, { -7609, 6515, -2283, -2522, 6332}, - { -3333, -5620, -9130,-11131, 5543}, { -407, -6721,-17466, -2889, 11568}, - { 3692, 6796, -262,-10846, -1856}, { 7275, 13404, -2989,-10595, 4936}, - { 244, -2219, 2656, 3776, -5412}, { -4043, -5934, 2131, 863, -2866}, - { -3302, 1743, -2006, -128, -2052}, { -6361, 3342, -1583, -21, 1142}, - { -3837, -1831, 6397, 2545, -2848}, { -9332, -6528, 5309, 1986, -2245}, - { -4490, 748, 1935, -3027, -493}, { -9255, 5366, 3193, -4493, 1784}, - { 4784, -370, 1866, 1057, -1889}, { 7342, -2690, -2577, 676, -611}, - { -502, 2235, -1850, -1777, -2049}, { 1011, 3880, -2465, 2209, -152}, - { 2592, 2829, 5588, 2839, -7306}, { -3049, -4918, 5955, 9201, -4447}, - { 697, 3908, 5798, -4451, -4644}, { -2121, 5444, -2570, 321, -1202}, - { 2846, -2086, 3532, 566, -708}, { -4279, 950, 4980, 3749, 452}, - { -2484, 3502, 1719, -170, 238}, { -3435, 263, 2114, -2005, 2361}, - { -7338, -1208, 9347, -1216, -4013}, {-13498, -439, 8028, -4232, 361}, - { -3729, 5433, 2004, -4727, -1259}, { -3986, 7743, 8429, -3691, -987}, - { 5198, -423, 1150, -1281, 816}, { 7409, 4109, -3949, 2690, 30}, - { 1246, 3055, -35, -1370, -246}, { -1489, 5635, -678, -2627, 3170}, - { 4830, -4585, 2008, -1062, 799}, { -129, 717, 4594, 14937, 10706}, - { 417, 2759, 1850, -5057, -1153}, { -3887, 7361, -5768, 4285, 666}, - { 1443, -938, 20, -2119, -1697}, { -3712, -3402, -2212, 110, 2136}, - { -2952, 12, -1568, -3500, -1855}, { -1315, -1731, 1160, -558, 1709}, - { 88, -4569, 194, -454, -2957}, { -2839, -1666, -273, 2084, -155}, - { -189, -2376, 1663, -1040, -2449}, { -2842, -1369, 636, -248, -2677}, - { 1517, 79, -3013, -3669, -973}, { 1913, -2493, -5312, -749, 1271}, - { -2903, -3324, -3756, -3690, -1829}, { -2913, -1547, -2760, -1406, 1124}, - { 1844, -1834, 456, 706, -4272}, { 467, -4256, -1909, 1521, 1134}, - { -127, -994, -637, -1491, -6494}, { 873, -2045, -3828, -2792, -578}, - { 2311, -1817, 2632, -3052, 1968}, { 641, 1194, 1893, 4107, 6342}, - { -45, 1198, 2160, -1449, 2203}, { -2004, 1713, 3518, 2652, 4251}, - { 2936, -3968, 1280, 131, -1476}, { 2827, 8, -1928, 2658, 3513}, - { 3199, -816, 2687, -1741, -1407}, { 2948, 4029, 394, -253, 1298}, - { 4286, 51, -4507, -32, -659}, { 3903, 5646, -5588, -2592, 5707}, - { -606, 1234, -1607, -5187, 664}, { -525, 3620, -2192, -2527, 1707}, - { 4297, -3251, -2283, 812, -2264}, { 5765, 528, -3287, 1352, 1672}, - { 2735, 1241, -1103, -3273, -3407}, { 4033, 1648, -2965, -1174, 1444}, - { 74, 918, 1999, 915, -1026}, { -2496, -1605, 2034, 2950, 229}, - { -2168, 2037, 15, -1264, -208}, { -3552, 1530, 581, 1491, 962}, - { -2613, -2338, 3621, -1488, -2185}, { -1747, 81, 5538, 1432, -2257}, - { -1019, 867, 214, -2284, -1510}, { -1684, 2816, -229, 2551, -1389}, - { 2707, 504, 479, 2783, -1009}, { 2517, -1487, -1596, 621, 1929}, - { -148, 2206, -4288, 1292, -1401}, { -527, 1243, -2731, 1909, 1280}, - { 2149, -1501, 3688, 610, -4591}, { 3306, -3369, 1875, 3636, -1217}, - { 2574, 2513, 1449, -3074, -4979}, { 814, 1826, -2497, 4234, -4077}, - { 1664, -220, 3418, 1002, 1115}, { 781, 1658, 3919, 6130, 3140}, - { 1148, 4065, 1516, 815, 199}, { 1191, 2489, 2561, 2421, 2443}, - { 770, -5915, 5515, -368, -3199}, { 1190, 1047, 3742, 6927, -2089}, - { 292, 3099, 4308, -758, -2455}, { 523, 3921, 4044, 1386, 85}, - { 4367, 1006, -1252, -1466, -1383}, { 3852, 1579, -77, 2064, 868}, - { 5109, 2919, -202, 359, -509}, { 3650, 3206, 2303, 1693, 1296}, - { 2905, -3907, 229, -1196, -2332}, { 5977, -3585, 805, 3825, -3138}, - { 3746, -606, 53, -269, -3301}, { 606, 2018, -1316, 4064, 398} -}; - -static const float syn_window[111]={ - 0.576690972, 0.580838025, 0.585013986, 0.589219987, 0.59345597, 0.597723007, - 0.602020264, 0.606384277, 0.610748291, 0.615142822, 0.619598389, 0.624084473, - 0.628570557, 0.633117676, 0.637695313, 0.642272949, 0.646911621, 0.651580811, - 0.656280518, 0.66104126, 0.665802002, 0.670593262, 0.675445557, 0.680328369, - 0.685241699, 0.690185547, 0.695159912, 0.700164795, 0.705230713, 0.710327148, - 0.715454102, 0.720611572, 0.725830078, 0.731048584, 0.736328125, 0.741638184, - 0.747009277, 0.752380371, 0.7578125, 0.763305664, 0.768798828, 0.774353027, - 0.779937744, 0.785583496, 0.791229248, 0.796936035, 0.802703857, 0.808502197, - 0.814331055, 0.820220947, 0.826141357, 0.832092285, 0.838104248, 0.844146729, - 0.850250244, 0.856384277, 0.862548828, 0.868774414, 0.875061035, 0.881378174, - 0.88772583, 0.894134521, 0.900604248, 0.907104492, 0.913635254, 0.920227051, - 0.926879883, 0.933563232, 0.940307617, 0.94708252, 0.953918457, 0.96081543, - 0.96774292, 0.974731445, 0.981781006, 0.988861084, 0.994842529, 0.998565674, - 0.999969482, 0.99911499, 0.996002197, 0.990600586, 0.982910156, 0.973022461, - 0.960876465, 0.946533203, 0.930053711, 0.911437988, 0.89074707, 0.868041992, - 0.843322754, 0.816680908, 0.788208008, 0.757904053, 0.725891113, 0.692199707, - 0.656921387, 0.620178223, 0.582000732, 0.542480469, 0.501739502, 0.459838867, - 0.416900635, 0.373016357, 0.328277588, 0.282775879, 0.236663818, 0.189971924, - 0.142852783, 0.0954284668,0.0477600098 -}; - -static const float gain_window[38]={ - 0.505699992, 0.524200022, 0.54339999, 0.563300014, 0.583953857, 0.60534668, - 0.627502441, 0.650482178, 0.674316406, 0.699005127, 0.724578857, 0.75112915, - 0.778625488, 0.807128906, 0.836669922, 0.86730957, 0.899078369, 0.932006836, - 0.961486816, 0.982757568, 0.995635986, 1, 0.995819092, 0.983154297, - 0.96206665, 0.932769775, 0.895507813, 0.850585938, 0.798400879, 0.739379883, - 0.674072266, 0.602996826, 0.526763916, 0.446014404, 0.361480713, 0.273834229, - 0.183868408, 0.0923461914 -}; - -/** synthesis bandwidth broadening table */ -static const float syn_bw_tab[36]={ - 0.98828125, 0.976699829, 0.965254128, 0.953942537, 0.942763507, 0.931715488, - 0.920796931, 0.910006344, 0.899342179, 0.888803005, 0.878387332, 0.868093729, - 0.857920766, 0.847867012, 0.837931097, 0.828111589, 0.818407178, 0.808816493, - 0.799338162, 0.789970934, 0.780713439, 0.771564424, 0.762522638, 0.753586829, - 0.744755745, 0.736028135, 0.727402806, 0.718878567, 0.710454226, 0.702128589, - 0.693900526, 0.685768902, 0.677732527, 0.669790328, 0.66194123, 0.654184103 -}; - -/** gain bandwidth broadening table */ -static const float gain_bw_tab[10]={ - 0.90625, 0.821289063, 0.74432373, 0.674499512, 0.61126709, - 0.553955078, 0.50201416, 0.454956055, 0.41229248, 0.373657227 -}; - -#endif /* AVCODEC_RA288_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rangecoder.c b/tizen/distrib/ffmpeg/libavcodec/rangecoder.c deleted file mode 100644 index 04c2738..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rangecoder.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Range coder - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Range coder. - * based upon - * "Range encoding: an algorithm for removing redundancy from a digitised - * message. - * G. N. N. Martin Presented in March 1979 to the Video & - * Data Recording Conference, - * IBM UK Scientific Center held in Southampton July 24-27 1979." - * - */ - -#include - -#include "avcodec.h" -#include "rangecoder.h" -#include "bytestream.h" - - -void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size){ - c->bytestream_start= - c->bytestream= buf; - c->bytestream_end= buf + buf_size; - - c->low= 0; - c->range= 0xFF00; - c->outstanding_count= 0; - c->outstanding_byte= -1; -} - -void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size){ - /* cast to avoid compiler warning */ - ff_init_range_encoder(c, (uint8_t *) buf, buf_size); - - c->low = bytestream_get_be16(&c->bytestream); -} - -void ff_build_rac_states(RangeCoder *c, int factor, int max_p){ - const int64_t one= 1LL<<32; - int64_t p; - int last_p8, p8, i; - - memset(c->zero_state, 0, sizeof(c->zero_state)); - memset(c-> one_state, 0, sizeof(c-> one_state)); - - last_p8= 0; - p= one/2; - for(i=0; i<128; i++){ - p8= (256*p + one/2) >> 32; //FIXME try without the one - if(p8 <= last_p8) p8= last_p8+1; - if(last_p8 && last_p8<256 && p8<=max_p) - c->one_state[last_p8]= p8; - - p+= ((one-p)*factor + one/2) >> 32; - last_p8= p8; - } - - for(i=256-max_p; i<=max_p; i++){ - if(c->one_state[i]) - continue; - - p= (i*one + 128) >> 8; - p+= ((one-p)*factor + one/2) >> 32; - p8= (256*p + one/2) >> 32; //FIXME try without the one - if(p8 <= i) p8= i+1; - if(p8 > max_p) p8= max_p; - c->one_state[ i]= p8; - } - - for(i=1; i<255; i++) - c->zero_state[i]= 256-c->one_state[256-i]; -} - -/** - * - * @return the number of bytes written - */ -int ff_rac_terminate(RangeCoder *c){ - c->range=0xFF; - c->low +=0xFF; - renorm_encoder(c); - c->range=0xFF; - renorm_encoder(c); - - assert(c->low == 0); - assert(c->range >= 0x100); - - return c->bytestream - c->bytestream_start; -} - -#ifdef TEST -#define SIZE 10240 - -#include "libavutil/lfg.h" - -int main(void){ - RangeCoder c; - uint8_t b[9*SIZE]; - uint8_t r[9*SIZE]; - int i; - uint8_t state[10]= {0}; - AVLFG prng; - - av_lfg_init(&prng, 1); - - ff_init_range_encoder(&c, b, SIZE); - ff_build_rac_states(&c, 0.05*(1LL<<32), 128+64+32+16); - - memset(state, 128, sizeof(state)); - - for(i=0; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Range coder. - */ - -#ifndef AVCODEC_RANGECODER_H -#define AVCODEC_RANGECODER_H - -#include -#include -#include "libavutil/common.h" - -typedef struct RangeCoder{ - int low; - int range; - int outstanding_count; - int outstanding_byte; - uint8_t zero_state[256]; - uint8_t one_state[256]; - uint8_t *bytestream_start; - uint8_t *bytestream; - uint8_t *bytestream_end; -}RangeCoder; - -void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size); -void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size); -int ff_rac_terminate(RangeCoder *c); -void ff_build_rac_states(RangeCoder *c, int factor, int max_p); - -static inline void renorm_encoder(RangeCoder *c){ - //FIXME optimize - while(c->range < 0x100){ - if(c->outstanding_byte < 0){ - c->outstanding_byte= c->low>>8; - }else if(c->low <= 0xFF00){ - *c->bytestream++ = c->outstanding_byte; - for(;c->outstanding_count; c->outstanding_count--) - *c->bytestream++ = 0xFF; - c->outstanding_byte= c->low>>8; - }else if(c->low >= 0x10000){ - *c->bytestream++ = c->outstanding_byte + 1; - for(;c->outstanding_count; c->outstanding_count--) - *c->bytestream++ = 0x00; - c->outstanding_byte= (c->low>>8) & 0xFF; - }else{ - c->outstanding_count++; - } - - c->low = (c->low & 0xFF)<<8; - c->range <<= 8; - } -} - -static inline int get_rac_count(RangeCoder *c){ - int x= c->bytestream - c->bytestream_start + c->outstanding_count; - if(c->outstanding_byte >= 0) - x++; - return 8*x - av_log2(c->range); -} - -static inline void put_rac(RangeCoder *c, uint8_t * const state, int bit){ - int range1= (c->range * (*state)) >> 8; - - assert(*state); - assert(range1 < c->range); - assert(range1 > 0); - if(!bit){ - c->range -= range1; - *state= c->zero_state[*state]; - }else{ - c->low += c->range - range1; - c->range = range1; - *state= c->one_state[*state]; - } - - renorm_encoder(c); -} - -static inline void refill(RangeCoder *c){ - if(c->range < 0x100){ - c->range <<= 8; - c->low <<= 8; - if(c->bytestream < c->bytestream_end) - c->low+= c->bytestream[0]; - c->bytestream++; - } -} - -static inline int get_rac(RangeCoder *c, uint8_t * const state){ - int range1= (c->range * (*state)) >> 8; - int av_unused one_mask; - - c->range -= range1; -#if 1 - if(c->low < c->range){ - *state= c->zero_state[*state]; - refill(c); - return 0; - }else{ - c->low -= c->range; - *state= c->one_state[*state]; - c->range = range1; - refill(c); - return 1; - } -#else - one_mask= (c->range - c->low-1)>>31; - - c->low -= c->range & one_mask; - c->range += (range1 - c->range) & one_mask; - - *state= c->zero_state[(*state) + (256&one_mask)]; - - refill(c); - - return one_mask&1; -#endif -} - -#endif /* AVCODEC_RANGECODER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/ratecontrol.c b/tizen/distrib/ffmpeg/libavcodec/ratecontrol.c deleted file mode 100644 index e52ef1a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ratecontrol.c +++ /dev/null @@ -1,961 +0,0 @@ -/* - * Rate control for video encoders - * - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Rate control for video encoders. - */ - -#include "libavutil/intmath.h" -#include "avcodec.h" -#include "dsputil.h" -#include "ratecontrol.h" -#include "mpegvideo.h" -#include "eval.h" - -#undef NDEBUG // Always check asserts, the speed effect is far too small to disable them. -#include - -#ifndef M_E -#define M_E 2.718281828 -#endif - -static int init_pass2(MpegEncContext *s); -static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num); - -void ff_write_pass1_stats(MpegEncContext *s){ - snprintf(s->avctx->stats_out, 256, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n", - s->current_picture_ptr->display_picture_number, s->current_picture_ptr->coded_picture_number, s->pict_type, - s->current_picture.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits, - s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count, s->skip_count, s->header_bits); -} - -static inline double qp2bits(RateControlEntry *rce, double qp){ - if(qp<=0.0){ - av_log(NULL, AV_LOG_ERROR, "qp<=0.0\n"); - } - return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ qp; -} - -static inline double bits2qp(RateControlEntry *rce, double bits){ - if(bits<0.9){ - av_log(NULL, AV_LOG_ERROR, "bits<0.9\n"); - } - return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits; -} - -int ff_rate_control_init(MpegEncContext *s) -{ - RateControlContext *rcc= &s->rc_context; - int i; - const char *error = NULL; - static const char * const const_names[]={ - "PI", - "E", - "iTex", - "pTex", - "tex", - "mv", - "fCode", - "iCount", - "mcVar", - "var", - "isI", - "isP", - "isB", - "avgQP", - "qComp", -/* "lastIQP", - "lastPQP", - "lastBQP", - "nextNonBQP",*/ - "avgIITex", - "avgPITex", - "avgPPTex", - "avgBPTex", - "avgTex", - NULL - }; - static double (* const func1[])(void *, double)={ - (void *)bits2qp, - (void *)qp2bits, - NULL - }; - static const char * const func1_names[]={ - "bits2qp", - "qp2bits", - NULL - }; - emms_c(); - - rcc->rc_eq_eval = ff_parse_expr(s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1, func1_names, NULL, NULL, &error); - if (!rcc->rc_eq_eval) { - av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\": %s\n", s->avctx->rc_eq, error? error : ""); - return -1; - } - - for(i=0; i<5; i++){ - rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0; - rcc->pred[i].count= 1.0; - - rcc->pred[i].decay= 0.4; - rcc->i_cplx_sum [i]= - rcc->p_cplx_sum [i]= - rcc->mv_bits_sum[i]= - rcc->qscale_sum [i]= - rcc->frame_count[i]= 1; // 1 is better because of 1/0 and such - rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5; - } - rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy; - - if(s->flags&CODEC_FLAG_PASS2){ - int i; - char *p; - - /* find number of pics */ - p= s->avctx->stats_in; - for(i=-1; p; i++){ - p= strchr(p+1, ';'); - } - i+= s->max_b_frames; - if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry)) - return -1; - rcc->entry = av_mallocz(i*sizeof(RateControlEntry)); - rcc->num_entries= i; - - /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */ - for(i=0; inum_entries; i++){ - RateControlEntry *rce= &rcc->entry[i]; - rce->pict_type= rce->new_pict_type=FF_P_TYPE; - rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2; - rce->misc_bits= s->mb_num + 10; - rce->mb_var_sum= s->mb_num*100; - } - - /* read stats */ - p= s->avctx->stats_in; - for(i=0; inum_entries - s->max_b_frames; i++){ - RateControlEntry *rce; - int picture_number; - int e; - char *next; - - next= strchr(p, ';'); - if(next){ - (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write - next++; - } - e= sscanf(p, " in:%d ", &picture_number); - - assert(picture_number >= 0); - assert(picture_number < rcc->num_entries); - rce= &rcc->entry[picture_number]; - - e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d", - &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits, - &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits); - if(e!=14){ - av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e); - return -1; - } - - p= next; - } - - if(init_pass2(s) < 0) return -1; - - //FIXME maybe move to end - if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) { -#if CONFIG_LIBXVID - return ff_xvid_rate_control_init(s); -#else - av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n"); - return -1; -#endif - } - } - - if(!(s->flags&CODEC_FLAG_PASS2)){ - - rcc->short_term_qsum=0.001; - rcc->short_term_qcount=0.001; - - rcc->pass1_rc_eq_output_sum= 0.001; - rcc->pass1_wanted_bits=0.001; - - if(s->avctx->qblur > 1.0){ - av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n"); - return -1; - } - /* init stuff with the user specified complexity */ - if(s->avctx->rc_initial_cplx){ - for(i=0; i<60*30; i++){ - double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num; - RateControlEntry rce; - - if (i%((s->gop_size+3)/4)==0) rce.pict_type= FF_I_TYPE; - else if(i%(s->max_b_frames+1)) rce.pict_type= FF_B_TYPE; - else rce.pict_type= FF_P_TYPE; - - rce.new_pict_type= rce.pict_type; - rce.mc_mb_var_sum= bits*s->mb_num/100000; - rce.mb_var_sum = s->mb_num; - rce.qscale = FF_QP2LAMBDA * 2; - rce.f_code = 2; - rce.b_code = 1; - rce.misc_bits= 1; - - if(s->pict_type== FF_I_TYPE){ - rce.i_count = s->mb_num; - rce.i_tex_bits= bits; - rce.p_tex_bits= 0; - rce.mv_bits= 0; - }else{ - rce.i_count = 0; //FIXME we do know this approx - rce.i_tex_bits= 0; - rce.p_tex_bits= bits*0.9; - rce.mv_bits= bits*0.1; - } - rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale; - rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale; - rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits; - rcc->frame_count[rce.pict_type] ++; - - get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i); - rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME misbehaves a little for variable fps - } - } - - } - - return 0; -} - -void ff_rate_control_uninit(MpegEncContext *s) -{ - RateControlContext *rcc= &s->rc_context; - emms_c(); - - ff_free_expr(rcc->rc_eq_eval); - av_freep(&rcc->entry); - -#if CONFIG_LIBXVID - if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) - ff_xvid_rate_control_uninit(s); -#endif -} - -int ff_vbv_update(MpegEncContext *s, int frame_size){ - RateControlContext *rcc= &s->rc_context; - const double fps= 1/av_q2d(s->avctx->time_base); - const int buffer_size= s->avctx->rc_buffer_size; - const double min_rate= s->avctx->rc_min_rate/fps; - const double max_rate= s->avctx->rc_max_rate/fps; - -//printf("%d %f %d %f %f\n", buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate); - if(buffer_size){ - int left; - - rcc->buffer_index-= frame_size; - if(rcc->buffer_index < 0){ - av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n"); - rcc->buffer_index= 0; - } - - left= buffer_size - rcc->buffer_index - 1; - rcc->buffer_index += av_clip(left, min_rate, max_rate); - - if(rcc->buffer_index > buffer_size){ - int stuffing= ceil((rcc->buffer_index - buffer_size)/8); - - if(stuffing < 4 && s->codec_id == CODEC_ID_MPEG4) - stuffing=4; - rcc->buffer_index -= 8*stuffing; - - if(s->avctx->debug & FF_DEBUG_RC) - av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing); - - return stuffing; - } - } - return 0; -} - -/** - * modifies the bitrate curve from pass1 for one frame - */ -static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){ - RateControlContext *rcc= &s->rc_context; - AVCodecContext *a= s->avctx; - double q, bits; - const int pict_type= rce->new_pict_type; - const double mb_num= s->mb_num; - int i; - - double const_values[]={ - M_PI, - M_E, - rce->i_tex_bits*rce->qscale, - rce->p_tex_bits*rce->qscale, - (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale, - rce->mv_bits/mb_num, - rce->pict_type == FF_B_TYPE ? (rce->f_code + rce->b_code)*0.5 : rce->f_code, - rce->i_count/mb_num, - rce->mc_mb_var_sum/mb_num, - rce->mb_var_sum/mb_num, - rce->pict_type == FF_I_TYPE, - rce->pict_type == FF_P_TYPE, - rce->pict_type == FF_B_TYPE, - rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type], - a->qcompress, -/* rcc->last_qscale_for[FF_I_TYPE], - rcc->last_qscale_for[FF_P_TYPE], - rcc->last_qscale_for[FF_B_TYPE], - rcc->next_non_b_qscale,*/ - rcc->i_cplx_sum[FF_I_TYPE] / (double)rcc->frame_count[FF_I_TYPE], - rcc->i_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE], - rcc->p_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE], - rcc->p_cplx_sum[FF_B_TYPE] / (double)rcc->frame_count[FF_B_TYPE], - (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type], - 0 - }; - - bits= ff_eval_expr(rcc->rc_eq_eval, const_values, rce); - if (isnan(bits)) { - av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->avctx->rc_eq); - return -1; - } - - rcc->pass1_rc_eq_output_sum+= bits; - bits*=rate_factor; - if(bits<0.0) bits=0.0; - bits+= 1.0; //avoid 1/0 issues - - /* user override */ - for(i=0; iavctx->rc_override_count; i++){ - RcOverride *rco= s->avctx->rc_override; - if(rco[i].start_frame > frame_num) continue; - if(rco[i].end_frame < frame_num) continue; - - if(rco[i].qscale) - bits= qp2bits(rce, rco[i].qscale); //FIXME move at end to really force it? - else - bits*= rco[i].quality_factor; - } - - q= bits2qp(rce, bits); - - /* I/B difference */ - if (pict_type==FF_I_TYPE && s->avctx->i_quant_factor<0.0) - q= -q*s->avctx->i_quant_factor + s->avctx->i_quant_offset; - else if(pict_type==FF_B_TYPE && s->avctx->b_quant_factor<0.0) - q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset; - if(q<1) q=1; - - return q; -} - -static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q){ - RateControlContext *rcc= &s->rc_context; - AVCodecContext *a= s->avctx; - const int pict_type= rce->new_pict_type; - const double last_p_q = rcc->last_qscale_for[FF_P_TYPE]; - const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type]; - - if (pict_type==FF_I_TYPE && (a->i_quant_factor>0.0 || rcc->last_non_b_pict_type==FF_P_TYPE)) - q= last_p_q *FFABS(a->i_quant_factor) + a->i_quant_offset; - else if(pict_type==FF_B_TYPE && a->b_quant_factor>0.0) - q= last_non_b_q* a->b_quant_factor + a->b_quant_offset; - if(q<1) q=1; - - /* last qscale / qdiff stuff */ - if(rcc->last_non_b_pict_type==pict_type || pict_type!=FF_I_TYPE){ - double last_q= rcc->last_qscale_for[pict_type]; - const int maxdiff= FF_QP2LAMBDA * a->max_qdiff; - - if (q > last_q + maxdiff) q= last_q + maxdiff; - else if(q < last_q - maxdiff) q= last_q - maxdiff; - } - - rcc->last_qscale_for[pict_type]= q; //Note we cannot do that after blurring - - if(pict_type!=FF_B_TYPE) - rcc->last_non_b_pict_type= pict_type; - - return q; -} - -/** - * gets the qmin & qmax for pict_type - */ -static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type){ - int qmin= s->avctx->lmin; - int qmax= s->avctx->lmax; - - assert(qmin <= qmax); - - if(pict_type==FF_B_TYPE){ - qmin= (int)(qmin*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5); - qmax= (int)(qmax*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5); - }else if(pict_type==FF_I_TYPE){ - qmin= (int)(qmin*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5); - qmax= (int)(qmax*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5); - } - - qmin= av_clip(qmin, 1, FF_LAMBDA_MAX); - qmax= av_clip(qmax, 1, FF_LAMBDA_MAX); - - if(qmaxrc_context; - int qmin, qmax; - const int pict_type= rce->new_pict_type; - const double buffer_size= s->avctx->rc_buffer_size; - const double fps= 1/av_q2d(s->avctx->time_base); - const double min_rate= s->avctx->rc_min_rate / fps; - const double max_rate= s->avctx->rc_max_rate / fps; - - get_qminmax(&qmin, &qmax, s, pict_type); - - /* modulation */ - if(s->avctx->rc_qmod_freq && frame_num%s->avctx->rc_qmod_freq==0 && pict_type==FF_P_TYPE) - q*= s->avctx->rc_qmod_amp; - -//printf("q:%f\n", q); - /* buffer overflow/underflow protection */ - if(buffer_size){ - double expected_size= rcc->buffer_index; - double q_limit; - - if(min_rate){ - double d= 2*(buffer_size - expected_size)/buffer_size; - if(d>1.0) d=1.0; - else if(d<0.0001) d=0.0001; - q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); - - q_limit= bits2qp(rce, FFMAX((min_rate - buffer_size + rcc->buffer_index) * s->avctx->rc_min_vbv_overflow_use, 1)); - if(q > q_limit){ - if(s->avctx->debug&FF_DEBUG_RC){ - av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit); - } - q= q_limit; - } - } - - if(max_rate){ - double d= 2*expected_size/buffer_size; - if(d>1.0) d=1.0; - else if(d<0.0001) d=0.0001; - q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); - - q_limit= bits2qp(rce, FFMAX(rcc->buffer_index * s->avctx->rc_max_available_vbv_use, 1)); - if(q < q_limit){ - if(s->avctx->debug&FF_DEBUG_RC){ - av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit); - } - q= q_limit; - } - } - } -//printf("q:%f max:%f min:%f size:%f index:%d bits:%f agr:%f\n", q,max_rate, min_rate, buffer_size, rcc->buffer_index, bits, s->avctx->rc_buffer_aggressivity); - if(s->avctx->rc_qsquish==0.0 || qmin==qmax){ - if (qqmax) q=qmax; - }else{ - double min2= log(qmin); - double max2= log(qmax); - - q= log(q); - q= (q - min2)/(max2-min2) - 0.5; - q*= -4.0; - q= 1.0/(1.0 + exp(q)); - q= q*(max2-min2) + min2; - - q= exp(q); - } - - return q; -} - -//---------------------------------- -// 1 Pass Code - -static double predict_size(Predictor *p, double q, double var) -{ - return p->coeff*var / (q*p->count); -} - -/* -static double predict_qp(Predictor *p, double size, double var) -{ -//printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size); - return p->coeff*var / (size*p->count); -} -*/ - -static void update_predictor(Predictor *p, double q, double var, double size) -{ - double new_coeff= size*q / (var + 1); - if(var<10) return; - - p->count*= p->decay; - p->coeff*= p->decay; - p->count++; - p->coeff+= new_coeff; -} - -static void adaptive_quantization(MpegEncContext *s, double q){ - int i; - const float lumi_masking= s->avctx->lumi_masking / (128.0*128.0); - const float dark_masking= s->avctx->dark_masking / (128.0*128.0); - const float temp_cplx_masking= s->avctx->temporal_cplx_masking; - const float spatial_cplx_masking = s->avctx->spatial_cplx_masking; - const float p_masking = s->avctx->p_masking; - const float border_masking = s->avctx->border_masking; - float bits_sum= 0.0; - float cplx_sum= 0.0; - float cplx_tab[s->mb_num]; - float bits_tab[s->mb_num]; - const int qmin= s->avctx->mb_lmin; - const int qmax= s->avctx->mb_lmax; - Picture * const pic= &s->current_picture; - const int mb_width = s->mb_width; - const int mb_height = s->mb_height; - - for(i=0; imb_num; i++){ - const int mb_xy= s->mb_index2xy[i]; - float temp_cplx= sqrt(pic->mc_mb_var[mb_xy]); //FIXME merge in pow() - float spat_cplx= sqrt(pic->mb_var[mb_xy]); - const int lumi= pic->mb_mean[mb_xy]; - float bits, cplx, factor; - int mb_x = mb_xy % s->mb_stride; - int mb_y = mb_xy / s->mb_stride; - int mb_distance; - float mb_factor = 0.0; -#if 0 - if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune - if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune -#endif - if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune - if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune - - if((s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTRA)){//FIXME hq mode - cplx= spat_cplx; - factor= 1.0 + p_masking; - }else{ - cplx= temp_cplx; - factor= pow(temp_cplx, - temp_cplx_masking); - } - factor*=pow(spat_cplx, - spatial_cplx_masking); - - if(lumi>127) - factor*= (1.0 - (lumi-128)*(lumi-128)*lumi_masking); - else - factor*= (1.0 - (lumi-128)*(lumi-128)*dark_masking); - - if(mb_x < mb_width/5){ - mb_distance = mb_width/5 - mb_x; - mb_factor = (float)mb_distance / (float)(mb_width/5); - }else if(mb_x > 4*mb_width/5){ - mb_distance = mb_x - 4*mb_width/5; - mb_factor = (float)mb_distance / (float)(mb_width/5); - } - if(mb_y < mb_height/5){ - mb_distance = mb_height/5 - mb_y; - mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5)); - }else if(mb_y > 4*mb_height/5){ - mb_distance = mb_y - 4*mb_height/5; - mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5)); - } - - factor*= 1.0 - border_masking*mb_factor; - - if(factor<0.00001) factor= 0.00001; - - bits= cplx*factor; - cplx_sum+= cplx; - bits_sum+= bits; - cplx_tab[i]= cplx; - bits_tab[i]= bits; - } - - /* handle qmin/qmax clipping */ - if(s->flags&CODEC_FLAG_NORMALIZE_AQP){ - float factor= bits_sum/cplx_sum; - for(i=0; imb_num; i++){ - float newq= q*cplx_tab[i]/bits_tab[i]; - newq*= factor; - - if (newq > qmax){ - bits_sum -= bits_tab[i]; - cplx_sum -= cplx_tab[i]*q/qmax; - } - else if(newq < qmin){ - bits_sum -= bits_tab[i]; - cplx_sum -= cplx_tab[i]*q/qmin; - } - } - if(bits_sum < 0.001) bits_sum= 0.001; - if(cplx_sum < 0.001) cplx_sum= 0.001; - } - - for(i=0; imb_num; i++){ - const int mb_xy= s->mb_index2xy[i]; - float newq= q*cplx_tab[i]/bits_tab[i]; - int intq; - - if(s->flags&CODEC_FLAG_NORMALIZE_AQP){ - newq*= bits_sum/cplx_sum; - } - - intq= (int)(newq + 0.5); - - if (intq > qmax) intq= qmax; - else if(intq < qmin) intq= qmin; -//if(i%s->mb_width==0) printf("\n"); -//printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i])); - s->lambda_table[mb_xy]= intq; - } -} - -void ff_get_2pass_fcode(MpegEncContext *s){ - RateControlContext *rcc= &s->rc_context; - int picture_number= s->picture_number; - RateControlEntry *rce; - - rce= &rcc->entry[picture_number]; - s->f_code= rce->f_code; - s->b_code= rce->b_code; -} - -//FIXME rd or at least approx for dquant - -float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) -{ - float q; - int qmin, qmax; - float br_compensation; - double diff; - double short_term_q; - double fps; - int picture_number= s->picture_number; - int64_t wanted_bits; - RateControlContext *rcc= &s->rc_context; - AVCodecContext *a= s->avctx; - RateControlEntry local_rce, *rce; - double bits; - double rate_factor; - int var; - const int pict_type= s->pict_type; - Picture * const pic= &s->current_picture; - emms_c(); - -#if CONFIG_LIBXVID - if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) - return ff_xvid_rate_estimate_qscale(s, dry_run); -#endif - - get_qminmax(&qmin, &qmax, s, pict_type); - - fps= 1/av_q2d(s->avctx->time_base); -//printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate); - /* update predictors */ - if(picture_number>2 && !dry_run){ - const int last_var= s->last_pict_type == FF_I_TYPE ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum; - update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits); - } - - if(s->flags&CODEC_FLAG_PASS2){ - assert(picture_number>=0); - assert(picture_numbernum_entries); - rce= &rcc->entry[picture_number]; - wanted_bits= rce->expected_bits; - }else{ - Picture *dts_pic; - rce= &local_rce; - - //FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering - //but the reordering is simpler for now until h.264 b pyramid must be handeld - if(s->pict_type == FF_B_TYPE || s->low_delay) - dts_pic= s->current_picture_ptr; - else - dts_pic= s->last_picture_ptr; - -//if(dts_pic) -// av_log(NULL, AV_LOG_ERROR, "%Ld %Ld %Ld %d\n", s->current_picture_ptr->pts, s->user_specified_pts, dts_pic->pts, picture_number); - - if(!dts_pic || dts_pic->pts == AV_NOPTS_VALUE) - wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps); - else - wanted_bits= (uint64_t)(s->bit_rate*(double)dts_pic->pts/fps); - } - - diff= s->total_bits - wanted_bits; - br_compensation= (a->bit_rate_tolerance - diff)/a->bit_rate_tolerance; - if(br_compensation<=0.0) br_compensation=0.001; - - var= pict_type == FF_I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum; - - short_term_q = 0; /* avoid warning */ - if(s->flags&CODEC_FLAG_PASS2){ - if(pict_type!=FF_I_TYPE) - assert(pict_type == rce->new_pict_type); - - q= rce->new_qscale / br_compensation; -//printf("%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale, br_compensation, s->frame_bits, var, pict_type); - }else{ - rce->pict_type= - rce->new_pict_type= pict_type; - rce->mc_mb_var_sum= pic->mc_mb_var_sum; - rce->mb_var_sum = pic-> mb_var_sum; - rce->qscale = FF_QP2LAMBDA * 2; - rce->f_code = s->f_code; - rce->b_code = s->b_code; - rce->misc_bits= 1; - - bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var)); - if(pict_type== FF_I_TYPE){ - rce->i_count = s->mb_num; - rce->i_tex_bits= bits; - rce->p_tex_bits= 0; - rce->mv_bits= 0; - }else{ - rce->i_count = 0; //FIXME we do know this approx - rce->i_tex_bits= 0; - rce->p_tex_bits= bits*0.9; - - rce->mv_bits= bits*0.1; - } - rcc->i_cplx_sum [pict_type] += rce->i_tex_bits*rce->qscale; - rcc->p_cplx_sum [pict_type] += rce->p_tex_bits*rce->qscale; - rcc->mv_bits_sum[pict_type] += rce->mv_bits; - rcc->frame_count[pict_type] ++; - - bits= rce->i_tex_bits + rce->p_tex_bits; - rate_factor= rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum * br_compensation; - - q= get_qscale(s, rce, rate_factor, picture_number); - if (q < 0) - return -1; - - assert(q>0.0); -//printf("%f ", q); - q= get_diff_limited_q(s, rce, q); -//printf("%f ", q); - assert(q>0.0); - - if(pict_type==FF_P_TYPE || s->intra_only){ //FIXME type dependent blur like in 2-pass - rcc->short_term_qsum*=a->qblur; - rcc->short_term_qcount*=a->qblur; - - rcc->short_term_qsum+= q; - rcc->short_term_qcount++; -//printf("%f ", q); - q= short_term_q= rcc->short_term_qsum/rcc->short_term_qcount; -//printf("%f ", q); - } - assert(q>0.0); - - q= modify_qscale(s, rce, q, picture_number); - - rcc->pass1_wanted_bits+= s->bit_rate/fps; - - assert(q>0.0); - } - - if(s->avctx->debug&FF_DEBUG_RC){ - av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n", - av_get_pict_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000, - br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps - ); - } - - if (qqmax) q=qmax; - - if(s->adaptive_quant) - adaptive_quantization(s, q); - else - q= (int)(q + 0.5); - - if(!dry_run){ - rcc->last_qscale= q; - rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum; - rcc->last_mb_var_sum= pic->mb_var_sum; - } -#if 0 -{ - static int mvsum=0, texsum=0; - mvsum += s->mv_bits; - texsum += s->i_tex_bits + s->p_tex_bits; - printf("%d %d//\n\n", mvsum, texsum); -} -#endif - return q; -} - -//---------------------------------------------- -// 2-Pass code - -static int init_pass2(MpegEncContext *s) -{ - RateControlContext *rcc= &s->rc_context; - AVCodecContext *a= s->avctx; - int i, toobig; - double fps= 1/av_q2d(s->avctx->time_base); - double complexity[5]={0,0,0,0,0}; // aproximate bits at quant=1 - uint64_t const_bits[5]={0,0,0,0,0}; // quantizer independent bits - uint64_t all_const_bits; - uint64_t all_available_bits= (uint64_t)(s->bit_rate*(double)rcc->num_entries/fps); - double rate_factor=0; - double step; - //int last_i_frame=-10000000; - const int filter_size= (int)(a->qblur*4) | 1; - double expected_bits; - double *qscale, *blurred_qscale, qscale_sum; - - /* find complexity & const_bits & decide the pict_types */ - for(i=0; inum_entries; i++){ - RateControlEntry *rce= &rcc->entry[i]; - - rce->new_pict_type= rce->pict_type; - rcc->i_cplx_sum [rce->pict_type] += rce->i_tex_bits*rce->qscale; - rcc->p_cplx_sum [rce->pict_type] += rce->p_tex_bits*rce->qscale; - rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits; - rcc->frame_count[rce->pict_type] ++; - - complexity[rce->new_pict_type]+= (rce->i_tex_bits+ rce->p_tex_bits)*(double)rce->qscale; - const_bits[rce->new_pict_type]+= rce->mv_bits + rce->misc_bits; - } - all_const_bits= const_bits[FF_I_TYPE] + const_bits[FF_P_TYPE] + const_bits[FF_B_TYPE]; - - if(all_available_bits < all_const_bits){ - av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is too low\n"); - return -1; - } - - qscale= av_malloc(sizeof(double)*rcc->num_entries); - blurred_qscale= av_malloc(sizeof(double)*rcc->num_entries); - toobig = 0; - - for(step=256*256; step>0.0000001; step*=0.5){ - expected_bits=0; - rate_factor+= step; - - rcc->buffer_index= s->avctx->rc_buffer_size/2; - - /* find qscale */ - for(i=0; inum_entries; i++){ - qscale[i]= get_qscale(s, &rcc->entry[i], rate_factor, i); - } - assert(filter_size%2==1); - - /* fixed I/B QP relative to P mode */ - for(i=rcc->num_entries-1; i>=0; i--){ - RateControlEntry *rce= &rcc->entry[i]; - - qscale[i]= get_diff_limited_q(s, rce, qscale[i]); - } - - /* smooth curve */ - for(i=0; inum_entries; i++){ - RateControlEntry *rce= &rcc->entry[i]; - const int pict_type= rce->new_pict_type; - int j; - double q=0.0, sum=0.0; - - for(j=0; jqblur==0 ? 1.0 : exp(-d*d/(a->qblur * a->qblur)); - - if(index < 0 || index >= rcc->num_entries) continue; - if(pict_type != rcc->entry[index].new_pict_type) continue; - q+= qscale[index] * coeff; - sum+= coeff; - } - blurred_qscale[i]= q/sum; - } - - /* find expected bits */ - for(i=0; inum_entries; i++){ - RateControlEntry *rce= &rcc->entry[i]; - double bits; - rce->new_qscale= modify_qscale(s, rce, blurred_qscale[i], i); - bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits; -//printf("%d %f\n", rce->new_bits, blurred_qscale[i]); - bits += 8*ff_vbv_update(s, bits); - - rce->expected_bits= expected_bits; - expected_bits += bits; - } - - /* - av_log(s->avctx, AV_LOG_INFO, - "expected_bits: %f all_available_bits: %d rate_factor: %f\n", - expected_bits, (int)all_available_bits, rate_factor); - */ - if(expected_bits > all_available_bits) { - rate_factor-= step; - ++toobig; - } - } - av_free(qscale); - av_free(blurred_qscale); - - /* check bitrate calculations and print info */ - qscale_sum = 0.0; - for(i=0; inum_entries; i++){ - /* av_log(s->avctx, AV_LOG_DEBUG, "[lavc rc] entry[%d].new_qscale = %.3f qp = %.3f\n", - i, rcc->entry[i].new_qscale, rcc->entry[i].new_qscale / FF_QP2LAMBDA); */ - qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA, s->avctx->qmin, s->avctx->qmax); - } - assert(toobig <= 40); - av_log(s->avctx, AV_LOG_DEBUG, - "[lavc rc] requested bitrate: %d bps expected bitrate: %d bps\n", - s->bit_rate, - (int)(expected_bits / ((double)all_available_bits/s->bit_rate))); - av_log(s->avctx, AV_LOG_DEBUG, - "[lavc rc] estimated target average qp: %.3f\n", - (float)qscale_sum / rcc->num_entries); - if (toobig == 0) { - av_log(s->avctx, AV_LOG_INFO, - "[lavc rc] Using all of requested bitrate is not " - "necessary for this video with these parameters.\n"); - } else if (toobig == 40) { - av_log(s->avctx, AV_LOG_ERROR, - "[lavc rc] Error: bitrate too low for this video " - "with these parameters.\n"); - return -1; - } else if (fabs(expected_bits/all_available_bits - 1.0) > 0.01) { - av_log(s->avctx, AV_LOG_ERROR, - "[lavc rc] Error: 2pass curve failed to converge\n"); - return -1; - } - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/ratecontrol.h b/tizen/distrib/ffmpeg/libavcodec/ratecontrol.h deleted file mode 100644 index d5fe2bc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ratecontrol.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Ratecontrol - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_RATECONTROL_H -#define AVCODEC_RATECONTROL_H - -/** - * @file - * ratecontrol header. - */ - -#include -#include -#include "eval.h" - -typedef struct Predictor{ - double coeff; - double count; - double decay; -} Predictor; - -typedef struct RateControlEntry{ - int pict_type; - float qscale; - int mv_bits; - int i_tex_bits; - int p_tex_bits; - int misc_bits; - int header_bits; - uint64_t expected_bits; - int new_pict_type; - float new_qscale; - int mc_mb_var_sum; - int mb_var_sum; - int i_count; - int skip_count; - int f_code; - int b_code; -}RateControlEntry; - -/** - * rate control context. - */ -typedef struct RateControlContext{ - FILE *stats_file; - int num_entries; ///< number of RateControlEntries - RateControlEntry *entry; - double buffer_index; ///< amount of bits in the video/audio buffer - Predictor pred[5]; - double short_term_qsum; ///< sum of recent qscales - double short_term_qcount; ///< count of recent qscales - double pass1_rc_eq_output_sum;///< sum of the output of the rc equation, this is used for normalization - double pass1_wanted_bits; ///< bits which should have been outputed by the pass1 code (including complexity init) - double last_qscale; - double last_qscale_for[5]; ///< last qscale for a specific pict type, used for max_diff & ipb factor stuff - int last_mc_mb_var_sum; - int last_mb_var_sum; - uint64_t i_cplx_sum[5]; - uint64_t p_cplx_sum[5]; - uint64_t mv_bits_sum[5]; - uint64_t qscale_sum[5]; - int frame_count[5]; - int last_non_b_pict_type; - - void *non_lavc_opaque; ///< context for non lavc rc code (for example xvid) - float dry_run_qscale; ///< for xvid rc - int last_picture_number; ///< for xvid rc - AVExpr * rc_eq_eval; -}RateControlContext; - -struct MpegEncContext; - -/* rate control */ -int ff_rate_control_init(struct MpegEncContext *s); -float ff_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); -void ff_write_pass1_stats(struct MpegEncContext *s); -void ff_rate_control_uninit(struct MpegEncContext *s); -int ff_vbv_update(struct MpegEncContext *s, int frame_size); -void ff_get_2pass_fcode(struct MpegEncContext *s); - -int ff_xvid_rate_control_init(struct MpegEncContext *s); -void ff_xvid_rate_control_uninit(struct MpegEncContext *s); -float ff_xvid_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); - -#endif /* AVCODEC_RATECONTROL_H */ - diff --git a/tizen/distrib/ffmpeg/libavcodec/raw.c b/tizen/distrib/ffmpeg/libavcodec/raw.c deleted file mode 100644 index c2ce3bc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/raw.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Raw Video Codec - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Raw Video Codec - */ - -#include "avcodec.h" -#include "raw.h" - -const PixelFormatTag ff_raw_pixelFormatTags[] = { - { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */ - { PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') }, - { PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') }, - { PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') }, - { PIX_FMT_YUV410P, MKTAG('Y', 'V', 'U', '9') }, - { PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') }, - { PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') }, - { PIX_FMT_YUV422P, MKTAG('P', '4', '2', '2') }, - { PIX_FMT_GRAY8, MKTAG('Y', '8', '0', '0') }, - { PIX_FMT_GRAY8, MKTAG(' ', ' ', 'Y', '8') }, - - - { PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */ - { PIX_FMT_YUYV422, MKTAG('Y', '4', '2', '2') }, - { PIX_FMT_YUYV422, MKTAG('V', '4', '2', '2') }, - { PIX_FMT_YUYV422, MKTAG('V', 'Y', 'U', 'Y') }, - { PIX_FMT_YUYV422, MKTAG('Y', 'U', 'N', 'V') }, - { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') }, - { PIX_FMT_UYVY422, MKTAG('H', 'D', 'Y', 'C') }, - { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'V') }, - { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'N', 'Y') }, - { PIX_FMT_UYVY422, MKTAG('u', 'y', 'v', '1') }, - { PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', '1') }, - { PIX_FMT_UYVY422, MKTAG('A', 'V', 'R', 'n') }, /* Avid AVI Codec 1:1 */ - { PIX_FMT_UYVY422, MKTAG('A', 'V', '1', 'x') }, /* Avid 1:1x */ - { PIX_FMT_UYVY422, MKTAG('A', 'V', 'u', 'p') }, - { PIX_FMT_UYVY422, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */ - { PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') }, - { PIX_FMT_RGB555LE, MKTAG('R', 'G', 'B', 15) }, - { PIX_FMT_BGR555LE, MKTAG('B', 'G', 'R', 15) }, - { PIX_FMT_RGB565LE, MKTAG('R', 'G', 'B', 16) }, - { PIX_FMT_BGR565LE, MKTAG('B', 'G', 'R', 16) }, - { PIX_FMT_RGB565LE, MKTAG( 3 , 0 , 0 , 0) }, - - /* quicktime */ - { PIX_FMT_UYVY422, MKTAG('2', 'v', 'u', 'y') }, - { PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', 'y') }, - { PIX_FMT_UYVY422, MKTAG('A', 'V', 'U', 'I') }, /* FIXME merge both fields */ - { PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', '2') }, - { PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', 's') }, - { PIX_FMT_PAL8, MKTAG('W', 'R', 'A', 'W') }, - - { PIX_FMT_NONE, 0 }, -}; - -unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat fmt) -{ - const PixelFormatTag * tags = ff_raw_pixelFormatTags; - while (tags->pix_fmt >= 0) { - if (tags->pix_fmt == fmt) - return tags->fourcc; - tags++; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/raw.h b/tizen/distrib/ffmpeg/libavcodec/raw.h deleted file mode 100644 index e74006a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/raw.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Raw Video Codec - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Raw Video Codec - */ - -#ifndef AVCODEC_RAW_H -#define AVCODEC_RAW_H - -#include "avcodec.h" - -typedef struct PixelFormatTag { - enum PixelFormat pix_fmt; - unsigned int fourcc; -} PixelFormatTag; - -extern const PixelFormatTag ff_raw_pixelFormatTags[]; - -#endif /* AVCODEC_RAW_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rawdec.c b/tizen/distrib/ffmpeg/libavcodec/rawdec.c deleted file mode 100644 index 8b398d2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rawdec.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Raw Video Decoder - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Raw Video Decoder - */ - -#include "avcodec.h" -#include "raw.h" -#include "libavutil/intreadwrite.h" - -typedef struct RawVideoContext { - unsigned char * buffer; /* block of memory for holding one frame */ - int length; /* number of bytes in buffer */ - int flip; - AVFrame pic; ///< AVCodecContext.coded_frame -} RawVideoContext; - -static const PixelFormatTag pixelFormatBpsAVI[] = { - { PIX_FMT_PAL8, 4 }, - { PIX_FMT_PAL8, 8 }, - { PIX_FMT_RGB555, 15 }, - { PIX_FMT_RGB555, 16 }, - { PIX_FMT_BGR24, 24 }, - { PIX_FMT_RGB32, 32 }, - { PIX_FMT_NONE, 0 }, -}; - -static const PixelFormatTag pixelFormatBpsMOV[] = { - { PIX_FMT_MONOWHITE, 1 }, - { PIX_FMT_PAL8, 2 }, - { PIX_FMT_PAL8, 4 }, - { PIX_FMT_PAL8, 8 }, - // FIXME swscale does not support 16 bit in .mov, sample 16bit.mov - // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html - { PIX_FMT_RGB555BE, 16 }, - { PIX_FMT_RGB24, 24 }, - { PIX_FMT_ARGB, 32 }, - { PIX_FMT_NONE, 0 }, -}; - -static enum PixelFormat findPixelFormat(const PixelFormatTag *tags, unsigned int fourcc) -{ - while (tags->pix_fmt >= 0) { - if (tags->fourcc == fourcc) - return tags->pix_fmt; - tags++; - } - return PIX_FMT_YUV420P; -} - -static av_cold int raw_init_decoder(AVCodecContext *avctx) -{ - RawVideoContext *context = avctx->priv_data; - - if (avctx->codec_tag == MKTAG('r','a','w',' ')) - avctx->pix_fmt = findPixelFormat(pixelFormatBpsMOV, avctx->bits_per_coded_sample); - else if (avctx->codec_tag) - avctx->pix_fmt = findPixelFormat(ff_raw_pixelFormatTags, avctx->codec_tag); - else if (avctx->bits_per_coded_sample) - avctx->pix_fmt = findPixelFormat(pixelFormatBpsAVI, avctx->bits_per_coded_sample); - - context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); - context->buffer = av_malloc(context->length); - context->pic.pict_type = FF_I_TYPE; - context->pic.key_frame = 1; - - avctx->coded_frame= &context->pic; - - if (!context->buffer) - return -1; - - if((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) || - avctx->codec_tag == MKTAG( 3 , 0 , 0 , 0 )) - context->flip=1; - - return 0; -} - -static void flip(AVCodecContext *avctx, AVPicture * picture){ - picture->data[0] += picture->linesize[0] * (avctx->height-1); - picture->linesize[0] *= -1; -} - -static int raw_decode(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - RawVideoContext *context = avctx->priv_data; - - AVFrame * frame = (AVFrame *) data; - AVPicture * picture = (AVPicture *) data; - - frame->interlaced_frame = avctx->coded_frame->interlaced_frame; - frame->top_field_first = avctx->coded_frame->top_field_first; - - //2bpp and 4bpp raw in avi and mov (yes this is ugly ...) - if((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) && - avctx->pix_fmt==PIX_FMT_PAL8 && - (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))){ - int i; - uint8_t *dst = context->buffer + 256*4; - buf_size = context->length - 256*4; - if (avctx->bits_per_coded_sample == 4){ - for(i=0; 2*i+1 < buf_size; i++){ - dst[2*i+0]= buf[i]>>4; - dst[2*i+1]= buf[i]&15; - } - } else - for(i=0; 4*i+3 < buf_size; i++){ - dst[4*i+0]= buf[i]>>6; - dst[4*i+1]= buf[i]>>4&3; - dst[4*i+2]= buf[i]>>2&3; - dst[4*i+3]= buf[i] &3; - } - buf= dst; - } - - if(avctx->codec_tag == MKTAG('A', 'V', '1', 'x') || - avctx->codec_tag == MKTAG('A', 'V', 'u', 'p')) - buf += buf_size - context->length; - - if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) - return -1; - - avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); - if(avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length){ - frame->data[1]= context->buffer; - } - if (avctx->palctrl && avctx->palctrl->palette_changed) { - memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); - avctx->palctrl->palette_changed = 0; - } - if(avctx->pix_fmt==PIX_FMT_BGR24 && ((frame->linesize[0]+3)&~3)*avctx->height <= buf_size) - frame->linesize[0] = (frame->linesize[0]+3)&~3; - - if(context->flip) - flip(avctx, picture); - - if ( avctx->codec_tag == MKTAG('Y', 'V', '1', '2') - || avctx->codec_tag == MKTAG('Y', 'V', 'U', '9')) - FFSWAP(uint8_t *, picture->data[1], picture->data[2]); - - if(avctx->codec_tag == AV_RL32("yuv2") && - avctx->pix_fmt == PIX_FMT_YUYV422) { - int x, y; - uint8_t *line = picture->data[0]; - for(y = 0; y < avctx->height; y++) { - for(x = 0; x < avctx->width; x++) - line[2*x + 1] ^= 0x80; - line += picture->linesize[0]; - } - } - - *data_size = sizeof(AVPicture); - return buf_size; -} - -static av_cold int raw_close_decoder(AVCodecContext *avctx) -{ - RawVideoContext *context = avctx->priv_data; - - av_freep(&context->buffer); - return 0; -} - -AVCodec rawvideo_decoder = { - "rawvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RAWVIDEO, - sizeof(RawVideoContext), - raw_init_decoder, - NULL, - raw_close_decoder, - raw_decode, - .long_name = NULL_IF_CONFIG_SMALL("raw video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rawenc.c b/tizen/distrib/ffmpeg/libavcodec/rawenc.c deleted file mode 100644 index 4199704..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rawenc.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Raw Video Encoder - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Raw Video Encoder - */ - -#include "avcodec.h" -#include "raw.h" -#include "libavutil/pixdesc.h" -#include "libavutil/intreadwrite.h" - -static av_cold int raw_init_encoder(AVCodecContext *avctx) -{ - avctx->coded_frame = (AVFrame *)avctx->priv_data; - avctx->coded_frame->pict_type = FF_I_TYPE; - avctx->coded_frame->key_frame = 1; - avctx->bits_per_coded_sample = av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]); - if(!avctx->codec_tag) - avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); - return 0; -} - -static int raw_encode(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) -{ - int ret = avpicture_layout((AVPicture *)data, avctx->pix_fmt, avctx->width, - avctx->height, frame, buf_size); - - if(avctx->codec_tag == AV_RL32("yuv2") && ret > 0 && - avctx->pix_fmt == PIX_FMT_YUYV422) { - int x; - for(x = 1; x < avctx->height*avctx->width*2; x += 2) - frame[x] ^= 0x80; - } - return ret; -} - -AVCodec rawvideo_encoder = { - "rawvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RAWVIDEO, - sizeof(AVFrame), - raw_init_encoder, - raw_encode, - .long_name = NULL_IF_CONFIG_SMALL("raw video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rdft.c b/tizen/distrib/ffmpeg/libavcodec/rdft.c deleted file mode 100644 index f37263b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rdft.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * (I)RDFT transforms - * Copyright (c) 2009 Alex Converse - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include -#include "libavutil/mathematics.h" -#include "fft.h" - -/** - * @file - * (Inverse) Real Discrete Fourier Transforms. - */ - -/* sin(2*pi*x/n) for 0<=xnbits; - const float k1 = 0.5; - const float k2 = 0.5 - s->inverse; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - - if (!s->inverse) { - ff_fft_permute(&s->fft, (FFTComplex*)data); - ff_fft_calc(&s->fft, (FFTComplex*)data); - } - /* i=0 is a special case because of packing, the DC term is real, so we - are going to throw the N/2 term (also real) in with it. */ - ev.re = data[0]; - data[0] = ev.re+data[1]; - data[1] = ev.re-data[1]; - for (i = 1; i < (n>>2); i++) { - i1 = 2*i; - i2 = n-i1; - /* Separate even and odd FFTs */ - ev.re = k1*(data[i1 ]+data[i2 ]); - od.im = -k2*(data[i1 ]-data[i2 ]); - ev.im = k1*(data[i1+1]-data[i2+1]); - od.re = k2*(data[i1+1]+data[i2+1]); - /* Apply twiddle factors to the odd FFT and add to the even FFT */ - data[i1 ] = ev.re + od.re*tcos[i] - od.im*tsin[i]; - data[i1+1] = ev.im + od.im*tcos[i] + od.re*tsin[i]; - data[i2 ] = ev.re - od.re*tcos[i] + od.im*tsin[i]; - data[i2+1] = -ev.im + od.im*tcos[i] + od.re*tsin[i]; - } - data[2*i+1]=s->sign_convention*data[2*i+1]; - if (s->inverse) { - data[0] *= k1; - data[1] *= k1; - ff_fft_permute(&s->fft, (FFTComplex*)data); - ff_fft_calc(&s->fft, (FFTComplex*)data); - } -} - -av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans) -{ - int n = 1 << nbits; - int i; - const double theta = (trans == DFT_R2C || trans == DFT_C2R ? -1 : 1)*2*M_PI/n; - - s->nbits = nbits; - s->inverse = trans == IDFT_C2R || trans == DFT_C2R; - s->sign_convention = trans == IDFT_R2C || trans == DFT_C2R ? 1 : -1; - - if (nbits < 4 || nbits > 16) - return -1; - - if (ff_fft_init(&s->fft, nbits-1, trans == IDFT_C2R || trans == IDFT_R2C) < 0) - return -1; - - ff_init_ff_cos_tabs(nbits); - s->tcos = ff_cos_tabs[nbits]; - s->tsin = ff_sin_tabs[nbits]+(trans == DFT_R2C || trans == DFT_C2R)*(n>>2); -#if !CONFIG_HARDCODED_TABLES - for (i = 0; i < (n>>2); i++) { - s->tsin[i] = sin(i*theta); - } -#endif - s->rdft_calc = ff_rdft_calc_c; - - if (ARCH_ARM) ff_rdft_init_arm(s); - - return 0; -} - -av_cold void ff_rdft_end(RDFTContext *s) -{ - ff_fft_end(&s->fft); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/rectangle.h b/tizen/distrib/ffmpeg/libavcodec/rectangle.h deleted file mode 100644 index cf4a9cc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rectangle.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * rectangle filling function - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * useful rectangle filling function - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_RECTANGLE_H -#define AVCODEC_RECTANGLE_H - -#include -#include "config.h" -#include "libavutil/common.h" -#include "dsputil.h" - -/** - * 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, 2 or 4), should be a constant - */ -static av_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==2 || size==4); - assert(w<=4); - - w *= size; - stride *= size; - - assert((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0); - assert((stride&(w-1))==0); - if(w==2){ - const uint16_t v= size==4 ? val : val*0x0101; - *(uint16_t*)(p + 0*stride)= v; - if(h==1) return; - *(uint16_t*)(p + 1*stride)= v; - if(h==2) return; - *(uint16_t*)(p + 2*stride)= v; - *(uint16_t*)(p + 3*stride)= v; - }else if(w==4){ - const uint32_t v= size==4 ? val : size==2 ? val*0x00010001 : val*0x01010101; - *(uint32_t*)(p + 0*stride)= v; - if(h==1) return; - *(uint32_t*)(p + 1*stride)= v; - if(h==2) return; - *(uint32_t*)(p + 2*stride)= v; - *(uint32_t*)(p + 3*stride)= v; - }else if(w==8){ - //gcc can't optimize 64bit math on x86_32 -#if HAVE_FAST_64BIT - const uint64_t v= size==2 ? val*0x0001000100010001ULL : val*0x0100000001ULL; - *(uint64_t*)(p + 0*stride)= v; - if(h==1) return; - *(uint64_t*)(p + 1*stride)= v; - if(h==2) return; - *(uint64_t*)(p + 2*stride)= v; - *(uint64_t*)(p + 3*stride)= v; - }else if(w==16){ - const uint64_t v= val*0x0100000001ULL; - *(uint64_t*)(p + 0+0*stride)= v; - *(uint64_t*)(p + 8+0*stride)= v; - *(uint64_t*)(p + 0+1*stride)= v; - *(uint64_t*)(p + 8+1*stride)= v; - if(h==2) return; - *(uint64_t*)(p + 0+2*stride)= v; - *(uint64_t*)(p + 8+2*stride)= v; - *(uint64_t*)(p + 0+3*stride)= v; - *(uint64_t*)(p + 8+3*stride)= v; -#else - const uint32_t v= size==2 ? val*0x00010001 : val; - *(uint32_t*)(p + 0+0*stride)= v; - *(uint32_t*)(p + 4+0*stride)= v; - if(h==1) return; - *(uint32_t*)(p + 0+1*stride)= v; - *(uint32_t*)(p + 4+1*stride)= v; - if(h==2) return; - *(uint32_t*)(p + 0+2*stride)= v; - *(uint32_t*)(p + 4+2*stride)= v; - *(uint32_t*)(p + 0+3*stride)= v; - *(uint32_t*)(p + 4+3*stride)= v; - }else if(w==16){ - *(uint32_t*)(p + 0+0*stride)= val; - *(uint32_t*)(p + 4+0*stride)= val; - *(uint32_t*)(p + 8+0*stride)= val; - *(uint32_t*)(p +12+0*stride)= val; - *(uint32_t*)(p + 0+1*stride)= val; - *(uint32_t*)(p + 4+1*stride)= val; - *(uint32_t*)(p + 8+1*stride)= val; - *(uint32_t*)(p +12+1*stride)= val; - if(h==2) return; - *(uint32_t*)(p + 0+2*stride)= val; - *(uint32_t*)(p + 4+2*stride)= val; - *(uint32_t*)(p + 8+2*stride)= val; - *(uint32_t*)(p +12+2*stride)= val; - *(uint32_t*)(p + 0+3*stride)= val; - *(uint32_t*)(p + 4+3*stride)= val; - *(uint32_t*)(p + 8+3*stride)= val; - *(uint32_t*)(p +12+3*stride)= val; -#endif - }else - assert(0); - assert(h==4); -} - -#endif /* AVCODEC_RECTANGLE_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/remove_extradata_bsf.c b/tizen/distrib/ffmpeg/libavcodec/remove_extradata_bsf.c deleted file mode 100644 index 95bd98b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/remove_extradata_bsf.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" - - -static int remove_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - int cmd= args ? *args : 0; - AVCodecParserContext *s; - - if(!bsfc->parser){ - bsfc->parser= av_parser_init(avctx->codec_id); - } - s= bsfc->parser; - - if(s && s->parser->split){ - if( (((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) && cmd=='a') - ||(!keyframe && cmd=='k') - ||(cmd=='e' || !cmd) - ){ - int i= s->parser->split(avctx, buf, buf_size); - buf += i; - buf_size -= i; - } - } - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - - return 0; -} - -AVBitStreamFilter remove_extradata_bsf={ - "remove_extra", - 0, - remove_extradata, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/resample.c b/tizen/distrib/ffmpeg/libavcodec/resample.c deleted file mode 100644 index b008180..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/resample.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * samplerate conversion for both audio and video - * Copyright (c) 2000 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * samplerate conversion for both audio and video - */ - -#include "avcodec.h" -#include "audioconvert.h" -#include "opt.h" - -struct AVResampleContext; - -static const char *context_to_name(void *ptr) -{ - return "audioresample"; -} - -static const AVOption options[] = {{NULL}}; -static const AVClass audioresample_context_class = { "ReSampleContext", context_to_name, options, LIBAVUTIL_VERSION_INT }; - -struct ReSampleContext { - struct AVResampleContext *resample_context; - short *temp[2]; - int temp_len; - float ratio; - /* channel convert */ - int input_channels, output_channels, filter_channels; - AVAudioConvert *convert_ctx[2]; - enum SampleFormat sample_fmt[2]; ///< input and output sample format - unsigned sample_size[2]; ///< size of one sample in sample_fmt - short *buffer[2]; ///< buffers used for conversion to S16 - unsigned buffer_size[2]; ///< sizes of allocated buffers -}; - -/* n1: number of samples */ -static void stereo_to_mono(short *output, short *input, int n1) -{ - short *p, *q; - int n = n1; - - p = input; - q = output; - while (n >= 4) { - q[0] = (p[0] + p[1]) >> 1; - q[1] = (p[2] + p[3]) >> 1; - q[2] = (p[4] + p[5]) >> 1; - q[3] = (p[6] + p[7]) >> 1; - q += 4; - p += 8; - n -= 4; - } - while (n > 0) { - q[0] = (p[0] + p[1]) >> 1; - q++; - p += 2; - n--; - } -} - -/* n1: number of samples */ -static void mono_to_stereo(short *output, short *input, int n1) -{ - short *p, *q; - int n = n1; - int v; - - p = input; - q = output; - while (n >= 4) { - v = p[0]; q[0] = v; q[1] = v; - v = p[1]; q[2] = v; q[3] = v; - v = p[2]; q[4] = v; q[5] = v; - v = p[3]; q[6] = v; q[7] = v; - q += 8; - p += 4; - n -= 4; - } - while (n > 0) { - v = p[0]; q[0] = v; q[1] = v; - q += 2; - p += 1; - n--; - } -} - -/* XXX: should use more abstract 'N' channels system */ -static void stereo_split(short *output1, short *output2, short *input, int n) -{ - int i; - - for(i=0;i 2) - { - av_log(NULL, AV_LOG_ERROR, "Resampling with input channels greater than 2 unsupported.\n"); - return NULL; - } - - s = av_mallocz(sizeof(ReSampleContext)); - if (!s) - { - av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context.\n"); - return NULL; - } - - s->ratio = (float)output_rate / (float)input_rate; - - s->input_channels = input_channels; - s->output_channels = output_channels; - - s->filter_channels = s->input_channels; - if (s->output_channels < s->filter_channels) - s->filter_channels = s->output_channels; - - s->sample_fmt [0] = sample_fmt_in; - s->sample_fmt [1] = sample_fmt_out; - s->sample_size[0] = av_get_bits_per_sample_format(s->sample_fmt[0])>>3; - s->sample_size[1] = av_get_bits_per_sample_format(s->sample_fmt[1])>>3; - - if (s->sample_fmt[0] != SAMPLE_FMT_S16) { - if (!(s->convert_ctx[0] = av_audio_convert_alloc(SAMPLE_FMT_S16, 1, - s->sample_fmt[0], 1, NULL, 0))) { - av_log(s, AV_LOG_ERROR, - "Cannot convert %s sample format to s16 sample format\n", - avcodec_get_sample_fmt_name(s->sample_fmt[0])); - av_free(s); - return NULL; - } - } - - if (s->sample_fmt[1] != SAMPLE_FMT_S16) { - if (!(s->convert_ctx[1] = av_audio_convert_alloc(s->sample_fmt[1], 1, - SAMPLE_FMT_S16, 1, NULL, 0))) { - av_log(s, AV_LOG_ERROR, - "Cannot convert s16 sample format to %s sample format\n", - avcodec_get_sample_fmt_name(s->sample_fmt[1])); - av_audio_convert_free(s->convert_ctx[0]); - av_free(s); - return NULL; - } - } - -/* - * AC-3 output is the only case where filter_channels could be greater than 2. - * input channels can't be greater than 2, so resample the 2 channels and then - * expand to 6 channels after the resampling. - */ - if(s->filter_channels>2) - s->filter_channels = 2; - -#define TAPS 16 - s->resample_context= av_resample_init(output_rate, input_rate, - filter_length, log2_phase_count, linear, cutoff); - - *(const AVClass**)s->resample_context = &audioresample_context_class; - - return s; -} - -#if LIBAVCODEC_VERSION_MAJOR < 53 -ReSampleContext *audio_resample_init(int output_channels, int input_channels, - int output_rate, int input_rate) -{ - return av_audio_resample_init(output_channels, input_channels, - output_rate, input_rate, - SAMPLE_FMT_S16, SAMPLE_FMT_S16, - TAPS, 10, 0, 0.8); -} -#endif - -/* resample audio. 'nb_samples' is the number of input samples */ -/* XXX: optimize it ! */ -int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples) -{ - int i, nb_samples1; - short *bufin[2]; - short *bufout[2]; - short *buftmp2[2], *buftmp3[2]; - short *output_bak = NULL; - int lenout; - - if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) { - /* nothing to do */ - memcpy(output, input, nb_samples * s->input_channels * sizeof(short)); - return nb_samples; - } - - if (s->sample_fmt[0] != SAMPLE_FMT_S16) { - int istride[1] = { s->sample_size[0] }; - int ostride[1] = { 2 }; - const void *ibuf[1] = { input }; - void *obuf[1]; - unsigned input_size = nb_samples*s->input_channels*2; - - if (!s->buffer_size[0] || s->buffer_size[0] < input_size) { - av_free(s->buffer[0]); - s->buffer_size[0] = input_size; - s->buffer[0] = av_malloc(s->buffer_size[0]); - if (!s->buffer[0]) { - av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); - return 0; - } - } - - obuf[0] = s->buffer[0]; - - if (av_audio_convert(s->convert_ctx[0], obuf, ostride, - ibuf, istride, nb_samples*s->input_channels) < 0) { - av_log(s->resample_context, AV_LOG_ERROR, "Audio sample format conversion failed\n"); - return 0; - } - - input = s->buffer[0]; - } - - lenout= 4*nb_samples * s->ratio + 16; - - if (s->sample_fmt[1] != SAMPLE_FMT_S16) { - output_bak = output; - - if (!s->buffer_size[1] || s->buffer_size[1] < lenout) { - av_free(s->buffer[1]); - s->buffer_size[1] = lenout; - s->buffer[1] = av_malloc(s->buffer_size[1]); - if (!s->buffer[1]) { - av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); - return 0; - } - } - - output = s->buffer[1]; - } - - /* XXX: move those malloc to resample init code */ - for(i=0; ifilter_channels; i++){ - bufin[i]= av_malloc( (nb_samples + s->temp_len) * sizeof(short) ); - memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short)); - buftmp2[i] = bufin[i] + s->temp_len; - } - - /* make some zoom to avoid round pb */ - bufout[0]= av_malloc( lenout * sizeof(short) ); - bufout[1]= av_malloc( lenout * sizeof(short) ); - - if (s->input_channels == 2 && - s->output_channels == 1) { - buftmp3[0] = output; - stereo_to_mono(buftmp2[0], input, nb_samples); - } else if (s->output_channels >= 2 && s->input_channels == 1) { - buftmp3[0] = bufout[0]; - memcpy(buftmp2[0], input, nb_samples*sizeof(short)); - } else if (s->output_channels >= 2) { - buftmp3[0] = bufout[0]; - buftmp3[1] = bufout[1]; - stereo_split(buftmp2[0], buftmp2[1], input, nb_samples); - } else { - buftmp3[0] = output; - memcpy(buftmp2[0], input, nb_samples*sizeof(short)); - } - - nb_samples += s->temp_len; - - /* resample each channel */ - nb_samples1 = 0; /* avoid warning */ - for(i=0;ifilter_channels;i++) { - int consumed; - int is_last= i+1 == s->filter_channels; - - nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i], &consumed, nb_samples, lenout, is_last); - s->temp_len= nb_samples - consumed; - s->temp[i]= av_realloc(s->temp[i], s->temp_len*sizeof(short)); - memcpy(s->temp[i], bufin[i] + consumed, s->temp_len*sizeof(short)); - } - - if (s->output_channels == 2 && s->input_channels == 1) { - mono_to_stereo(output, buftmp3[0], nb_samples1); - } else if (s->output_channels == 2) { - stereo_mux(output, buftmp3[0], buftmp3[1], nb_samples1); - } else if (s->output_channels == 6) { - ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1); - } - - if (s->sample_fmt[1] != SAMPLE_FMT_S16) { - int istride[1] = { 2 }; - int ostride[1] = { s->sample_size[1] }; - const void *ibuf[1] = { output }; - void *obuf[1] = { output_bak }; - - if (av_audio_convert(s->convert_ctx[1], obuf, ostride, - ibuf, istride, nb_samples1*s->output_channels) < 0) { - av_log(s->resample_context, AV_LOG_ERROR, "Audio sample format convertion failed\n"); - return 0; - } - } - - for(i=0; ifilter_channels; i++) - av_free(bufin[i]); - - av_free(bufout[0]); - av_free(bufout[1]); - return nb_samples1; -} - -void audio_resample_close(ReSampleContext *s) -{ - av_resample_close(s->resample_context); - av_freep(&s->temp[0]); - av_freep(&s->temp[1]); - av_freep(&s->buffer[0]); - av_freep(&s->buffer[1]); - av_audio_convert_free(s->convert_ctx[0]); - av_audio_convert_free(s->convert_ctx[1]); - av_free(s); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/resample2.c b/tizen/distrib/ffmpeg/libavcodec/resample2.c deleted file mode 100644 index 45f41a1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/resample2.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * audio resampling - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio resampling - * @author Michael Niedermayer - */ - -#include "avcodec.h" -#include "dsputil.h" - -#ifndef CONFIG_RESAMPLE_HP -#define FILTER_SHIFT 15 - -#define FELEM int16_t -#define FELEM2 int32_t -#define FELEML int64_t -#define FELEM_MAX INT16_MAX -#define FELEM_MIN INT16_MIN -#define WINDOW_TYPE 9 -#elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE) -#define FILTER_SHIFT 30 - -#define FELEM int32_t -#define FELEM2 int64_t -#define FELEML int64_t -#define FELEM_MAX INT32_MAX -#define FELEM_MIN INT32_MIN -#define WINDOW_TYPE 12 -#else -#define FILTER_SHIFT 0 - -#define FELEM double -#define FELEM2 double -#define FELEML double -#define WINDOW_TYPE 24 -#endif - - -typedef struct AVResampleContext{ - const AVClass *av_class; - FELEM *filter_bank; - int filter_length; - int ideal_dst_incr; - int dst_incr; - int index; - int frac; - int src_incr; - int compensation_distance; - int phase_shift; - int phase_mask; - int linear; -}AVResampleContext; - -/** - * 0th order modified bessel function of the first kind. - */ -static double bessel(double x){ - double v=1; - double lastv=0; - double t=1; - int i; - - x= x*x/4; - for(i=1; v != lastv; i++){ - lastv=v; - t *= x/(i*i); - v += t; - } - return v; -} - -/** - * builds a polyphase filterbank. - * @param factor resampling factor - * @param scale wanted sum of coefficients for each filter - * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16 - */ -static void build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){ - int ph, i; - double x, y, w, tab[tap_count]; - const int center= (tap_count-1)/2; - - /* if upsampling, only need to interpolate, no filter */ - if (factor > 1.0) - factor = 1.0; - - for(ph=0;phphase_shift= phase_shift; - c->phase_mask= phase_count-1; - c->linear= linear; - - c->filter_length= FFMAX((int)ceil(filter_size/factor), 1); - c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM)); - build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); - c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; - - c->src_incr= out_rate; - c->ideal_dst_incr= c->dst_incr= in_rate * phase_count; - c->index= -phase_count*((c->filter_length-1)/2); - - return c; -} - -void av_resample_close(AVResampleContext *c){ - av_freep(&c->filter_bank); - av_freep(&c); -} - -void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){ -// sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr; - c->compensation_distance= compensation_distance; - c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance; -} - -int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){ - int dst_index, i; - int index= c->index; - int frac= c->frac; - int dst_incr_frac= c->dst_incr % c->src_incr; - int dst_incr= c->dst_incr / c->src_incr; - int compensation_distance= c->compensation_distance; - - if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){ - int64_t index2= ((int64_t)index)<<32; - int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; - dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr); - - for(dst_index=0; dst_index < dst_size; dst_index++){ - dst[dst_index] = src[index2>>32]; - index2 += incr; - } - frac += dst_index * dst_incr_frac; - index += dst_index * dst_incr; - index += frac / c->src_incr; - frac %= c->src_incr; - }else{ - for(dst_index=0; dst_index < dst_size; dst_index++){ - FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask); - int sample_index= index >> c->phase_shift; - FELEM2 val=0; - - if(sample_index < 0){ - for(i=0; ifilter_length; i++) - val += src[FFABS(sample_index + i) % src_size] * filter[i]; - }else if(sample_index + c->filter_length > src_size){ - break; - }else if(c->linear){ - FELEM2 v2=0; - for(i=0; ifilter_length; i++){ - val += src[sample_index + i] * (FELEM2)filter[i]; - v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length]; - } - val+=(v2-val)*(FELEML)frac / c->src_incr; - }else{ - for(i=0; ifilter_length; i++){ - val += src[sample_index + i] * (FELEM2)filter[i]; - } - } - -#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE - dst[dst_index] = av_clip_int16(lrintf(val)); -#else - val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT; - dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val; -#endif - - frac += dst_incr_frac; - index += dst_incr; - if(frac >= c->src_incr){ - frac -= c->src_incr; - index++; - } - - if(dst_index + 1 == compensation_distance){ - compensation_distance= 0; - dst_incr_frac= c->ideal_dst_incr % c->src_incr; - dst_incr= c->ideal_dst_incr / c->src_incr; - } - } - } - *consumed= FFMAX(index, 0) >> c->phase_shift; - if(index>=0) index &= c->phase_mask; - - if(compensation_distance){ - compensation_distance -= dst_index; - assert(compensation_distance > 0); - } - if(update_ctx){ - c->frac= frac; - c->index= index; - c->dst_incr= dst_incr_frac + c->src_incr*dst_incr; - c->compensation_distance= compensation_distance; - } -#if 0 - if(update_ctx && !c->compensation_distance){ -#undef rand - av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2); -av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance); - } -#endif - - return dst_index; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/rl.h b/tizen/distrib/ffmpeg/libavcodec/rl.h deleted file mode 100644 index b244589..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rl.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2000-2002 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * rl header. - */ - -#ifndef AVCODEC_RL_H -#define AVCODEC_RL_H - -#include -#include "get_bits.h" - -/* run length table */ -#define MAX_RUN 64 -#define MAX_LEVEL 64 - -/** RLTable. */ -typedef struct RLTable { - int n; ///< number of entries of table_vlc minus 1 - int last; ///< number of values for last = 0 - const uint16_t (*table_vlc)[2]; - const int8_t *table_run; - const int8_t *table_level; - uint8_t *index_run[2]; ///< encoding only - int8_t *max_level[2]; ///< encoding & decoding - int8_t *max_run[2]; ///< encoding & decoding - VLC vlc; ///< decoding only deprecated FIXME remove - RL_VLC_ELEM *rl_vlc[32]; ///< decoding only -} RLTable; - -/** - * - * @param static_store static uint8_t array[2][2*MAX_RUN + MAX_LEVEL + 3] which will hold - * the level and run tables, if this is NULL av_malloc() will be used - */ -void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]); -void init_vlc_rl(RLTable *rl); - -#define INIT_VLC_RL(rl, static_size)\ -{\ - int q;\ - static RL_VLC_ELEM rl_vlc_table[32][static_size];\ - INIT_VLC_STATIC(&rl.vlc, 9, rl.n + 1,\ - &rl.table_vlc[0][1], 4, 2,\ - &rl.table_vlc[0][0], 4, 2, static_size);\ -\ - if(!rl.rl_vlc[0]){\ - for(q=0; q<32; q++)\ - rl.rl_vlc[q]= rl_vlc_table[q];\ -\ - init_vlc_rl(&rl);\ - }\ -} - -static inline int get_rl_index(const RLTable *rl, int last, int run, int level) -{ - int index; - index = rl->index_run[last][run]; - if (index >= rl->n) - return rl->n; - if (level > rl->max_level[last][run]) - return rl->n; - return index + level - 1; -} - -#endif /* AVCODEC_RL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rl2.c b/tizen/distrib/ffmpeg/libavcodec/rl2.c deleted file mode 100644 index 30f5e83..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rl2.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * RL2 Video Decoder - * Copyright (C) 2008 Sascha Sommer (saschasommer@freenet.de) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * RL2 Video Decoder - * @file - * @author Sascha Sommer (saschasommer@freenet.de) - * For more information about the RL2 format, visit: - * http://wiki.multimedia.cx/index.php?title=RL2 - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - - -#define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr count, palette - -typedef struct Rl2Context { - AVCodecContext *avctx; - AVFrame frame; - - unsigned short video_base; ///< initial drawing offset - unsigned int clr_count; ///< number of used colors (currently unused) - unsigned char* back_frame; ///< background frame - unsigned int palette[AVPALETTE_COUNT]; -} Rl2Context; - -/** - * Run Length Decode a single 320x200 frame - * @param s rl2 context - * @param buf input buffer - * @param size input buffer size - * @param out ouput buffer - * @param stride stride of the output buffer - * @param video_base offset of the rle data inside the frame - */ -static void rl2_rle_decode(Rl2Context *s,const unsigned char* in,int size, - unsigned char* out,int stride,int video_base){ - int base_x = video_base % s->avctx->width; - int base_y = video_base / s->avctx->width; - int stride_adj = stride - s->avctx->width; - int i; - const unsigned char* back_frame = s->back_frame; - const unsigned char* in_end = in + size; - const unsigned char* out_end = out + stride * s->avctx->height; - unsigned char* line_end = out + s->avctx->width; - - /** copy start of the background frame */ - for(i=0;i<=base_y;i++){ - if(s->back_frame) - memcpy(out,back_frame,s->avctx->width); - out += stride; - back_frame += s->avctx->width; - } - back_frame += base_x - s->avctx->width; - line_end = out - stride_adj; - out += base_x - stride; - - /** decode the variable part of the frame */ - while(in < in_end){ - unsigned char val = *in++; - int len = 1; - if(val >= 0x80){ - if(in >= in_end) - break; - len = *in++; - if(!len) - break; - } - - if(len >= out_end - out) - break; - - if(s->back_frame) - val |= 0x80; - else - val &= ~0x80; - - while(len--){ - *out++ = (val == 0x80)? *back_frame:val; - back_frame++; - if(out == line_end){ - out += stride_adj; - line_end += stride; - if(len >= out_end - out) - break; - } - } - } - - /** copy the rest from the background frame */ - if(s->back_frame){ - while(out < out_end){ - memcpy(out, back_frame, line_end - out); - back_frame += line_end - out; - out = line_end + stride_adj; - line_end += stride; - } - } -} - - -/** - * Initialize the decoder - * @param avctx decoder context - * @return 0 success, -1 on error - */ -static av_cold int rl2_decode_init(AVCodecContext *avctx) -{ - Rl2Context *s = avctx->priv_data; - int back_size; - int i; - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - /** parse extra data */ - if(!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE){ - av_log(avctx, AV_LOG_ERROR, "invalid extradata size\n"); - return -1; - } - - /** get frame_offset */ - s->video_base = AV_RL16(&avctx->extradata[0]); - s->clr_count = AV_RL32(&avctx->extradata[2]); - - if(s->video_base >= avctx->width * avctx->height){ - av_log(avctx, AV_LOG_ERROR, "invalid video_base\n"); - return -1; - } - - /** initialize palette */ - for(i=0;ipalette[i] = AV_RB24(&avctx->extradata[6 + i * 3]); - - /** decode background frame if present */ - back_size = avctx->extradata_size - EXTRADATA1_SIZE; - - if(back_size > 0){ - unsigned char* back_frame = av_mallocz(avctx->width*avctx->height); - if(!back_frame) - return -1; - rl2_rle_decode(s,avctx->extradata + EXTRADATA1_SIZE,back_size, - back_frame,avctx->width,0); - s->back_frame = back_frame; - } - return 0; -} - - -/** - * Decode a single frame - * @param avctx decoder context - * @param data decoded frame - * @param data_size size of the decoded frame - * @param buf input buffer - * @param buf_size input buffer size - * @return 0 success, -1 on error - */ -static int rl2_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - Rl2Context *s = avctx->priv_data; - - if(s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - /** get buffer */ - s->frame.reference= 0; - if(avctx->get_buffer(avctx, &s->frame)) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - /** run length decode */ - rl2_rle_decode(s,buf,buf_size,s->frame.data[0],s->frame.linesize[0],s->video_base); - - /** make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /** report that the buffer was completely consumed */ - return buf_size; -} - - -/** - * Uninit decoder - * @param avctx decoder context - * @return 0 success, -1 on error - */ -static av_cold int rl2_decode_end(AVCodecContext *avctx) -{ - Rl2Context *s = avctx->priv_data; - - if(s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - av_free(s->back_frame); - - return 0; -} - - -AVCodec rl2_decoder = { - "rl2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RL2, - sizeof(Rl2Context), - rl2_decode_init, - NULL, - rl2_decode_end, - rl2_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("RL2 video"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/rle.c b/tizen/distrib/ffmpeg/libavcodec/rle.c deleted file mode 100644 index 6e468f8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rle.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * RLE encoder - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "rle.h" - -/** - * Count up to 127 consecutive pixels which are either all the same or - * all differ from the previous and next pixels. - * @param start Pointer to the first pixel - * @param len Maximum number of pixels - * @param bpp Bytes per pixel - * @param same 1 if searching for identical pixel values. 0 for differing - * @return Number of matching consecutive pixels found - */ -static int count_pixels(const uint8_t *start, int len, int bpp, int same) -{ - const uint8_t *pos; - int count = 1; - - for(pos = start + bpp; count < FFMIN(127, len); pos += bpp, count ++) { - if(same != !memcmp(pos-bpp, pos, bpp)) { - if(!same) { - /* if bpp == 1, then 0 1 1 0 is more efficiently encoded as a single - * raw block of pixels. for larger bpp, RLE is as good or better */ - if(bpp == 1 && count + 1 < FFMIN(127, len) && *pos != *(pos+1)) - continue; - - /* if RLE can encode the next block better than as a raw block, - * back up and leave _all_ the identical pixels for RLE */ - count --; - } - break; - } - } - - return count; -} - -int ff_rle_encode(uint8_t *outbuf, int out_size, const uint8_t *ptr , int bpp, int w, - int add_rep, int xor_rep, int add_raw, int xor_raw) -{ - int count, x; - uint8_t *out = outbuf; - - for(x = 0; x < w; x += count) { - /* see if we can encode the next set of pixels with RLE */ - if((count = count_pixels(ptr, w-x, bpp, 1)) > 1) { - if(out + bpp + 1 > outbuf + out_size) return -1; - *out++ = (count ^ xor_rep) + add_rep; - memcpy(out, ptr, bpp); - out += bpp; - } else { - /* fall back on uncompressed */ - count = count_pixels(ptr, w-x, bpp, 0); - if(out + bpp*count >= outbuf + out_size) return -1; - *out++ = (count ^ xor_raw) + add_raw; - - memcpy(out, ptr, bpp * count); - out += bpp * count; - } - - ptr += count * bpp; - } - - return out - outbuf; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/rle.h b/tizen/distrib/ffmpeg/libavcodec/rle.h deleted file mode 100644 index f892443..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rle.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * RLE encoder - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_RLE_H -#define AVCODEC_RLE_H - -#include - -/** - * RLE compress the row, with maximum size of out_size. Value before repeated bytes is (count ^ xor_rep) + add_rep. - * Value before raw bytes is (count ^ xor_raw) + add_raw. - * @param outbuf Output buffer - * @param out_size Maximum output size - * @param ptr Input buffer - * @param bpp Bytes per pixel - * @param w Image width - * @return Size of output in bytes, or -1 if larger than out_size - */ -int ff_rle_encode(uint8_t *outbuf, int out_size, const uint8_t *inbuf, int bpp, int w, - int add_rep, int xor_rep, int add_raw, int xor_raw); - -#endif /* AVCODEC_RLE_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/roqaudioenc.c b/tizen/distrib/ffmpeg/libavcodec/roqaudioenc.c deleted file mode 100644 index 11fd6f0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/roqaudioenc.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * RoQ audio encoder - * - * Copyright (c) 2005 Eric Lasota - * Based on RoQ specs (c)2001 Tim Ferguson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intmath.h" -#include "avcodec.h" -#include "bytestream.h" - -#define ROQ_FIRST_FRAME_SIZE (735*8) -#define ROQ_FRAME_SIZE 735 - - -#define MAX_DPCM (127*127) - - -typedef struct -{ - short lastSample[2]; -} ROQDPCMContext; - -static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) -{ - ROQDPCMContext *context = avctx->priv_data; - - if (avctx->channels > 2) { - av_log(avctx, AV_LOG_ERROR, "Audio must be mono or stereo\n"); - return -1; - } - if (avctx->sample_rate != 22050) { - av_log(avctx, AV_LOG_ERROR, "Audio must be 22050 Hz\n"); - return -1; - } - if (avctx->sample_fmt != SAMPLE_FMT_S16) { - av_log(avctx, AV_LOG_ERROR, "Audio must be signed 16-bit\n"); - return -1; - } - - avctx->frame_size = ROQ_FIRST_FRAME_SIZE; - - context->lastSample[0] = context->lastSample[1] = 0; - - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; -} - -static unsigned char dpcm_predict(short *previous, short current) -{ - int diff; - int negative; - int result; - int predicted; - - diff = current - *previous; - - negative = diff<0; - diff = FFABS(diff); - - if (diff >= MAX_DPCM) - result = 127; - else { - result = ff_sqrt(diff); - result += diff > result*result+result; - } - - /* See if this overflows */ - retry: - diff = result*result; - if (negative) - diff = -diff; - predicted = *previous + diff; - - /* If it overflows, back off a step */ - if (predicted > 32767 || predicted < -32768) { - result--; - goto retry; - } - - /* Add the sign bit */ - result |= negative << 7; //if (negative) result |= 128; - - *previous = predicted; - - return result; -} - -static int roq_dpcm_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) -{ - int i, samples, stereo, ch; - short *in; - unsigned char *out; - - ROQDPCMContext *context = avctx->priv_data; - - stereo = (avctx->channels == 2); - - if (stereo) { - context->lastSample[0] &= 0xFF00; - context->lastSample[1] &= 0xFF00; - } - - out = frame; - in = data; - - bytestream_put_byte(&out, stereo ? 0x21 : 0x20); - bytestream_put_byte(&out, 0x10); - bytestream_put_le32(&out, avctx->frame_size*avctx->channels); - - if (stereo) { - bytestream_put_byte(&out, (context->lastSample[1])>>8); - bytestream_put_byte(&out, (context->lastSample[0])>>8); - } else - bytestream_put_le16(&out, context->lastSample[0]); - - /* Write the actual samples */ - samples = avctx->frame_size; - for (i=0; ichannels; ch++) - *out++ = dpcm_predict(&context->lastSample[ch], *in++); - - /* Use smaller frames from now on */ - avctx->frame_size = ROQ_FRAME_SIZE; - - /* Return the result size */ - return out - frame; -} - -static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - - return 0; -} - -AVCodec roq_dpcm_encoder = { - "roq_dpcm", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_ROQ_DPCM, - sizeof(ROQDPCMContext), - roq_dpcm_encode_init, - roq_dpcm_encode_frame, - roq_dpcm_encode_close, - NULL, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("id RoQ DPCM"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/roqvideo.c b/tizen/distrib/ffmpeg/libavcodec/roqvideo.c deleted file mode 100644 index 830eb7b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/roqvideo.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2003 Mike Melanson - * Copyright (C) 2003 Dr. Tim Ferguson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * id RoQ Video common functions based on work by Dr. Tim Ferguson - */ - -#include "avcodec.h" -#include "roqvideo.h" - -static inline void block_copy(unsigned char *out, unsigned char *in, - int outstride, int instride, int sz) -{ - int rows = sz; - while(rows--) { - memcpy(out, in, sz); - out += outstride; - in += instride; - } -} - -void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) -{ - unsigned char *bptr; - int boffs,stride; - - stride = ri->current_frame->linesize[0]; - boffs = y*stride + x; - - bptr = ri->current_frame->data[0] + boffs; - bptr[0 ] = cell->y[0]; - bptr[1 ] = cell->y[1]; - bptr[stride ] = cell->y[2]; - bptr[stride+1] = cell->y[3]; - - stride = ri->current_frame->linesize[1]; - boffs = y*stride + x; - - bptr = ri->current_frame->data[1] + boffs; - bptr[0 ] = - bptr[1 ] = - bptr[stride ] = - bptr[stride+1] = cell->u; - - bptr = ri->current_frame->data[2] + boffs; - bptr[0 ] = - bptr[1 ] = - bptr[stride ] = - bptr[stride+1] = cell->v; -} - -void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) -{ - unsigned char *bptr; - int boffs,stride; - - stride = ri->current_frame->linesize[0]; - boffs = y*stride + x; - - bptr = ri->current_frame->data[0] + boffs; - bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell->y[0]; - bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell->y[1]; - bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell->y[2]; - bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->y[3]; - - stride = ri->current_frame->linesize[1]; - boffs = y*stride + x; - - bptr = ri->current_frame->data[1] + boffs; - bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = - bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = - bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = - bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->u; - - bptr = ri->current_frame->data[2] + boffs; - bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = - bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = - bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = - bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->v; -} - - -static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax, - int deltay, int sz) -{ - int mx, my, cp; - - mx = x + deltax; - my = y + deltay; - - /* check MV against frame boundaries */ - if ((mx < 0) || (mx > ri->width - sz) || - (my < 0) || (my > ri->height - sz)) { - av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", - mx, my, ri->width, ri->height); - return; - } - - for(cp = 0; cp < 3; cp++) { - int outstride = ri->current_frame->linesize[cp]; - int instride = ri->last_frame ->linesize[cp]; - block_copy(ri->current_frame->data[cp] + y*outstride + x, - ri->last_frame->data[cp] + my*instride + mx, - outstride, instride, sz); - } -} - - -void ff_apply_motion_4x4(RoqContext *ri, int x, int y, - int deltax, int deltay) -{ - apply_motion_generic(ri, x, y, deltax, deltay, 4); -} - -void ff_apply_motion_8x8(RoqContext *ri, int x, int y, - int deltax, int deltay) -{ - apply_motion_generic(ri, x, y, deltax, deltay, 8); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/roqvideo.h b/tizen/distrib/ffmpeg/libavcodec/roqvideo.h deleted file mode 100644 index 3fe11c6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/roqvideo.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2003 Mike Melanson - * Copyright (C) 2003 Dr. Tim Ferguson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ROQVIDEO_H -#define AVCODEC_ROQVIDEO_H - -#include "libavutil/lfg.h" -#include "avcodec.h" -#include "dsputil.h" - -typedef struct { - unsigned char y[4]; - unsigned char u, v; -} roq_cell; - -typedef struct { - int idx[4]; -} roq_qcell; - -typedef struct { - int d[2]; -} motion_vect; - -struct RoqTempData; - -typedef struct RoqContext { - - AVCodecContext *avctx; - DSPContext dsp; - AVFrame frames[2]; - AVFrame *last_frame; - AVFrame *current_frame; - int first_frame; - - roq_cell cb2x2[256]; - roq_qcell cb4x4[256]; - - const unsigned char *buf; - int size; - int width, height; - - /* Encoder only data */ - AVLFG randctx; - uint64_t lambda; - - motion_vect *this_motion4; - motion_vect *last_motion4; - - motion_vect *this_motion8; - motion_vect *last_motion8; - - unsigned int framesSinceKeyframe; - - AVFrame *frame_to_enc; - uint8_t *out_buf; - struct RoqTempData *tmpData; -} RoqContext; - -#define RoQ_INFO 0x1001 -#define RoQ_QUAD_CODEBOOK 0x1002 -#define RoQ_QUAD_VQ 0x1011 -#define RoQ_SOUND_MONO 0x1020 -#define RoQ_SOUND_STEREO 0x1021 - -#define RoQ_ID_MOT 0x00 -#define RoQ_ID_FCC 0x01 -#define RoQ_ID_SLD 0x02 -#define RoQ_ID_CCC 0x03 - -void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell); -void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell); - -void ff_apply_motion_4x4(RoqContext *ri, int x, int y, int deltax, int deltay); - -void ff_apply_motion_8x8(RoqContext *ri, int x, int y, int deltax, int deltay); - -#endif /* AVCODEC_ROQVIDEO_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/roqvideodec.c b/tizen/distrib/ffmpeg/libavcodec/roqvideodec.c deleted file mode 100644 index 7c6f5ff..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/roqvideodec.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * id RoQ Video Decoder by Dr. Tim Ferguson - * For more information about the id RoQ format, visit: - * http://www.csse.monash.edu.au/~timf/ - */ - -#include -#include -#include - -#include "avcodec.h" -#include "bytestream.h" -#include "roqvideo.h" - -static void roqvideo_decode_frame(RoqContext *ri) -{ - unsigned int chunk_id = 0, chunk_arg = 0; - unsigned long chunk_size = 0; - int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1; - int vqid, bpos, xpos, ypos, xp, yp, x, y, mx, my; - int frame_stats[2][4] = {{0},{0}}; - roq_qcell *qcell; - const unsigned char *buf = ri->buf; - const unsigned char *buf_end = ri->buf + ri->size; - - while (buf < buf_end) { - chunk_id = bytestream_get_le16(&buf); - chunk_size = bytestream_get_le32(&buf); - chunk_arg = bytestream_get_le16(&buf); - - if(chunk_id == RoQ_QUAD_VQ) - break; - if(chunk_id == RoQ_QUAD_CODEBOOK) { - if((nv1 = chunk_arg >> 8) == 0) - nv1 = 256; - if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) - nv2 = 256; - for(i = 0; i < nv1; i++) { - ri->cb2x2[i].y[0] = *buf++; - ri->cb2x2[i].y[1] = *buf++; - ri->cb2x2[i].y[2] = *buf++; - ri->cb2x2[i].y[3] = *buf++; - ri->cb2x2[i].u = *buf++; - ri->cb2x2[i].v = *buf++; - } - for(i = 0; i < nv2; i++) - for(j = 0; j < 4; j++) - ri->cb4x4[i].idx[j] = *buf++; - } - } - - bpos = xpos = ypos = 0; - while(bpos < chunk_size) { - for (yp = ypos; yp < ypos + 16; yp += 8) - for (xp = xpos; xp < xpos + 16; xp += 8) { - if (vqflg_pos < 0) { - vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); - vqflg_pos = 7; - } - vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; - frame_stats[0][vqid]++; - vqflg_pos--; - - switch(vqid) { - case RoQ_ID_MOT: - break; - case RoQ_ID_FCC: - mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); - my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); - ff_apply_motion_8x8(ri, xp, yp, mx, my); - break; - case RoQ_ID_SLD: - qcell = ri->cb4x4 + buf[bpos++]; - ff_apply_vector_4x4(ri, xp, yp, ri->cb2x2 + qcell->idx[0]); - ff_apply_vector_4x4(ri, xp+4, yp, ri->cb2x2 + qcell->idx[1]); - ff_apply_vector_4x4(ri, xp, yp+4, ri->cb2x2 + qcell->idx[2]); - ff_apply_vector_4x4(ri, xp+4, yp+4, ri->cb2x2 + qcell->idx[3]); - break; - case RoQ_ID_CCC: - for (k = 0; k < 4; k++) { - x = xp; y = yp; - if(k & 0x01) x += 4; - if(k & 0x02) y += 4; - - if (vqflg_pos < 0) { - vqflg = buf[bpos++]; - vqflg |= (buf[bpos++] << 8); - vqflg_pos = 7; - } - vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; - frame_stats[1][vqid]++; - vqflg_pos--; - switch(vqid) { - case RoQ_ID_MOT: - break; - case RoQ_ID_FCC: - mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); - my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); - ff_apply_motion_4x4(ri, x, y, mx, my); - break; - case RoQ_ID_SLD: - qcell = ri->cb4x4 + buf[bpos++]; - ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + qcell->idx[0]); - ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + qcell->idx[1]); - ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + qcell->idx[2]); - ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + qcell->idx[3]); - break; - case RoQ_ID_CCC: - ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + buf[bpos]); - ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + buf[bpos+1]); - ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + buf[bpos+2]); - ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + buf[bpos+3]); - bpos += 4; - break; - } - } - break; - default: - av_log(ri->avctx, AV_LOG_ERROR, "Unknown vq code: %d\n", vqid); - } - } - - xpos += 16; - if (xpos >= ri->width) { - xpos -= ri->width; - ypos += 16; - } - if(ypos >= ri->height) - break; - } -} - - -static av_cold int roq_decode_init(AVCodecContext *avctx) -{ - RoqContext *s = avctx->priv_data; - - s->avctx = avctx; - s->width = avctx->width; - s->height = avctx->height; - s->last_frame = &s->frames[0]; - s->current_frame = &s->frames[1]; - avctx->pix_fmt = PIX_FMT_YUV444P; - - return 0; -} - -static int roq_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - RoqContext *s = avctx->priv_data; - int copy= !s->current_frame->data[0]; - - if (avctx->reget_buffer(avctx, s->current_frame)) { - av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); - return -1; - } - - if(copy) - av_picture_copy((AVPicture*)s->current_frame, (AVPicture*)s->last_frame, - avctx->pix_fmt, avctx->width, avctx->height); - - s->buf = buf; - s->size = buf_size; - roqvideo_decode_frame(s); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = *s->current_frame; - - /* shuffle frames */ - FFSWAP(AVFrame *, s->current_frame, s->last_frame); - - return buf_size; -} - -static av_cold int roq_decode_end(AVCodecContext *avctx) -{ - RoqContext *s = avctx->priv_data; - - /* release the last frame */ - if (s->last_frame->data[0]) - avctx->release_buffer(avctx, s->last_frame); - if (s->current_frame->data[0]) - avctx->release_buffer(avctx, s->current_frame); - - return 0; -} - -AVCodec roq_decoder = { - "roqvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ROQ, - sizeof(RoqContext), - roq_decode_init, - NULL, - roq_decode_end, - roq_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/roqvideoenc.c b/tizen/distrib/ffmpeg/libavcodec/roqvideoenc.c deleted file mode 100644 index f9fbb64..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/roqvideoenc.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * RoQ Video Encoder. - * - * Copyright (C) 2007 Vitor Sessak - * Copyright (C) 2004-2007 Eric Lasota - * Based on RoQ specs (C) 2001 Tim Ferguson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * id RoQ encoder by Vitor. Based on the Switchblade3 library and the - * Switchblade3 FFmpeg glue by Eric Lasota. - */ - -/* - * COSTS: - * Level 1: - * SKIP - 2 bits - * MOTION - 2 + 8 bits - * CODEBOOK - 2 + 8 bits - * SUBDIVIDE - 2 + combined subcel cost - * - * Level 2: - * SKIP - 2 bits - * MOTION - 2 + 8 bits - * CODEBOOK - 2 + 8 bits - * SUBDIVIDE - 2 + 4*8 bits - * - * Maximum cost: 138 bits per cel - * - * Proper evaluation requires LCD fraction comparison, which requires - * Squared Error (SE) loss * savings increase - * - * Maximum savings increase: 136 bits - * Maximum SE loss without overflow: 31580641 - * Components in 8x8 supercel: 192 - * Maximum SE precision per component: 164482 - * >65025, so no truncation is needed (phew) - */ - -#include - -#include "roqvideo.h" -#include "bytestream.h" -#include "elbg.h" -#include "mathops.h" - -#define CHROMA_BIAS 1 - -/** - * Maximum number of generated 4x4 codebooks. Can't be 256 to workaround a - * Quake 3 bug. - */ -#define MAX_CBS_4x4 255 - -#define MAX_CBS_2x2 256 ///< Maximum number of 2x2 codebooks. - -/* The cast is useful when multiplying it by INT_MAX */ -#define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE) - -/* Macroblock support functions */ -static void unpack_roq_cell(roq_cell *cell, uint8_t u[4*3]) -{ - memcpy(u , cell->y, 4); - memset(u+4, cell->u, 4); - memset(u+8, cell->v, 4); -} - -static void unpack_roq_qcell(uint8_t cb2[], roq_qcell *qcell, uint8_t u[4*4*3]) -{ - int i,cp; - static const int offsets[4] = {0, 2, 8, 10}; - - for (cp=0; cp<3; cp++) - for (i=0; i<4; i++) { - u[4*4*cp + offsets[i] ] = cb2[qcell->idx[i]*2*2*3 + 4*cp ]; - u[4*4*cp + offsets[i]+1] = cb2[qcell->idx[i]*2*2*3 + 4*cp+1]; - u[4*4*cp + offsets[i]+4] = cb2[qcell->idx[i]*2*2*3 + 4*cp+2]; - u[4*4*cp + offsets[i]+5] = cb2[qcell->idx[i]*2*2*3 + 4*cp+3]; - } -} - - -static void enlarge_roq_mb4(uint8_t base[3*16], uint8_t u[3*64]) -{ - int x,y,cp; - - for(cp=0; cp<3; cp++) - for(y=0; y<8; y++) - for(x=0; x<8; x++) - *u++ = base[(y/2)*4 + (x/2) + 16*cp]; -} - -static inline int square(int x) -{ - return x*x; -} - -static inline int eval_sse(uint8_t *a, uint8_t *b, int count) -{ - int diff=0; - - while(count--) - diff += square(*b++ - *a++); - - return diff; -} - -// FIXME Could use DSPContext.sse, but it is not so speed critical (used -// just for motion estimation). -static int block_sse(uint8_t **buf1, uint8_t **buf2, int x1, int y1, int x2, - int y2, int *stride1, int *stride2, int size) -{ - int i, k; - int sse=0; - - for (k=0; k<3; k++) { - int bias = (k ? CHROMA_BIAS : 4); - for (i=0; i 7) - return INT_MAX; - - if (my < -7 || my > 7) - return INT_MAX; - - mx += x; - my += y; - - if ((unsigned) mx > enc->width-size || (unsigned) my > enc->height-size) - return INT_MAX; - - return block_sse(enc->frame_to_enc->data, enc->last_frame->data, x, y, - mx, my, - enc->frame_to_enc->linesize, enc->last_frame->linesize, - size); -} - -/** - * Returns distortion between two macroblocks - */ -static inline int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size) -{ - int cp, sdiff=0; - - for(cp=0;cp<3;cp++) { - int bias = (cp ? CHROMA_BIAS : 4); - sdiff += bias*eval_sse(a, b, size*size); - a += size*size; - b += size*size; - } - - return sdiff; -} - -typedef struct -{ - int eval_dist[4]; - int best_bit_use; - int best_coding; - - int subCels[4]; - motion_vect motion; - int cbEntry; -} SubcelEvaluation; - -typedef struct -{ - int eval_dist[4]; - int best_coding; - - SubcelEvaluation subCels[4]; - - motion_vect motion; - int cbEntry; - - int sourceX, sourceY; -} CelEvaluation; - -typedef struct -{ - int numCB4; - int numCB2; - int usedCB2[MAX_CBS_2x2]; - int usedCB4[MAX_CBS_4x4]; - uint8_t unpacked_cb2[MAX_CBS_2x2*2*2*3]; - uint8_t unpacked_cb4[MAX_CBS_4x4*4*4*3]; - uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4*8*8*3]; -} RoqCodebooks; - -/** - * Temporary vars - */ -typedef struct RoqTempData -{ - CelEvaluation *cel_evals; - - int f2i4[MAX_CBS_4x4]; - int i2f4[MAX_CBS_4x4]; - int f2i2[MAX_CBS_2x2]; - int i2f2[MAX_CBS_2x2]; - - int mainChunkSize; - - int numCB4; - int numCB2; - - RoqCodebooks codebooks; - - int *closest_cb2; - int used_option[4]; -} RoqTempdata; - -/** - * Initializes cel evaluators and sets their source coordinates - */ -static void create_cel_evals(RoqContext *enc, RoqTempdata *tempData) -{ - int n=0, x, y, i; - - tempData->cel_evals = av_malloc(enc->width*enc->height/64 * sizeof(CelEvaluation)); - - /* Map to the ROQ quadtree order */ - for (y=0; yheight; y+=16) - for (x=0; xwidth; x+=16) - for(i=0; i<4; i++) { - tempData->cel_evals[n ].sourceX = x + (i&1)*8; - tempData->cel_evals[n++].sourceY = y + (i&2)*4; - } -} - -/** - * Get macroblocks from parts of the image - */ -static void get_frame_mb(AVFrame *frame, int x, int y, uint8_t mb[], int dim) -{ - int i, j, cp; - - for (cp=0; cp<3; cp++) { - int stride = frame->linesize[cp]; - for (i=0; idata[cp][(y+i)*stride + x + j]; - } -} - -/** - * Find the codebook with the lowest distortion from an image - */ -static int index_mb(uint8_t cluster[], uint8_t cb[], int numCB, - int *outIndex, int dim) -{ - int i, lDiff = INT_MAX, pick=0; - - /* Diff against the others */ - for (i=0; iwidth/blocksize)*enc->height/blocksize; - - if (blocksize == 4) { - last_motion = enc->last_motion4; - this_motion = enc->this_motion4; - } else { - last_motion = enc->last_motion8; - this_motion = enc->this_motion8; - } - - for (i=0; iheight; i+=blocksize) - for (j=0; jwidth; j+=blocksize) { - lowestdiff = eval_motion_dist(enc, j, i, (motion_vect) {{0,0}}, - blocksize); - bestpick.d[0] = 0; - bestpick.d[1] = 0; - - if (blocksize == 4) - EVAL_MOTION(enc->this_motion8[(i/8)*(enc->width/8) + j/8]); - - offset = (i/blocksize)*enc->width/blocksize + j/blocksize; - if (offset < max && offset >= 0) - EVAL_MOTION(last_motion[offset]); - - offset++; - if (offset < max && offset >= 0) - EVAL_MOTION(last_motion[offset]); - - offset = (i/blocksize + 1)*enc->width/blocksize + j/blocksize; - if (offset < max && offset >= 0) - EVAL_MOTION(last_motion[offset]); - - off[0]= (i/blocksize)*enc->width/blocksize + j/blocksize - 1; - off[1]= off[0] - enc->width/blocksize + 1; - off[2]= off[1] + 1; - - if (i) { - - for(k=0; k<2; k++) - vect.d[k]= mid_pred(this_motion[off[0]].d[k], - this_motion[off[1]].d[k], - this_motion[off[2]].d[k]); - - EVAL_MOTION(vect); - for(k=0; k<3; k++) - EVAL_MOTION(this_motion[off[k]]); - } else if(j) - EVAL_MOTION(this_motion[off[0]]); - - vect = bestpick; - - oldbest = -1; - while (oldbest != lowestdiff) { - oldbest = lowestdiff; - for (k=0; k<8; k++) { - vect2 = vect; - vect2.d[0] += offsets[k].d[0]; - vect2.d[1] += offsets[k].d[1]; - EVAL_MOTION(vect2); - } - vect = bestpick; - } - offset = (i/blocksize)*enc->width/blocksize + j/blocksize; - this_motion[offset] = bestpick; - } -} - -/** - * Gets distortion for all options available to a subcel - */ -static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, - int y, RoqContext *enc, RoqTempdata *tempData) -{ - uint8_t mb4[4*4*3]; - uint8_t mb2[2*2*3]; - int cluster_index; - int i, best_dist; - - static const int bitsUsed[4] = {2, 10, 10, 34}; - - if (enc->framesSinceKeyframe >= 1) { - subcel->motion = enc->this_motion4[y*enc->width/16 + x/4]; - - subcel->eval_dist[RoQ_ID_FCC] = - eval_motion_dist(enc, x, y, - enc->this_motion4[y*enc->width/16 + x/4], 4); - } else - subcel->eval_dist[RoQ_ID_FCC] = INT_MAX; - - if (enc->framesSinceKeyframe >= 2) - subcel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, - enc->current_frame->data, x, - y, x, y, - enc->frame_to_enc->linesize, - enc->current_frame->linesize, - 4); - else - subcel->eval_dist[RoQ_ID_MOT] = INT_MAX; - - cluster_index = y*enc->width/16 + x/4; - - get_frame_mb(enc->frame_to_enc, x, y, mb4, 4); - - subcel->eval_dist[RoQ_ID_SLD] = index_mb(mb4, - tempData->codebooks.unpacked_cb4, - tempData->codebooks.numCB4, - &subcel->cbEntry, 4); - - subcel->eval_dist[RoQ_ID_CCC] = 0; - - for(i=0;i<4;i++) { - subcel->subCels[i] = tempData->closest_cb2[cluster_index*4+i]; - - get_frame_mb(enc->frame_to_enc, x+2*(i&1), - y+(i&2), mb2, 2); - - subcel->eval_dist[RoQ_ID_CCC] += - squared_diff_macroblock(tempData->codebooks.unpacked_cb2 + subcel->subCels[i]*2*2*3, mb2, 2); - } - - best_dist = INT_MAX; - for (i=0; i<4; i++) - if (ROQ_LAMBDA_SCALE*subcel->eval_dist[i] + enc->lambda*bitsUsed[i] < - best_dist) { - subcel->best_coding = i; - subcel->best_bit_use = bitsUsed[i]; - best_dist = ROQ_LAMBDA_SCALE*subcel->eval_dist[i] + - enc->lambda*bitsUsed[i]; - } -} - -/** - * Gets distortion for all options available to a cel - */ -static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, - RoqTempdata *tempData) -{ - uint8_t mb8[8*8*3]; - int index = cel->sourceY*enc->width/64 + cel->sourceX/8; - int i, j, best_dist, divide_bit_use; - - int bitsUsed[4] = {2, 10, 10, 0}; - - if (enc->framesSinceKeyframe >= 1) { - cel->motion = enc->this_motion8[index]; - - cel->eval_dist[RoQ_ID_FCC] = - eval_motion_dist(enc, cel->sourceX, cel->sourceY, - enc->this_motion8[index], 8); - } else - cel->eval_dist[RoQ_ID_FCC] = INT_MAX; - - if (enc->framesSinceKeyframe >= 2) - cel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, - enc->current_frame->data, - cel->sourceX, cel->sourceY, - cel->sourceX, cel->sourceY, - enc->frame_to_enc->linesize, - enc->current_frame->linesize,8); - else - cel->eval_dist[RoQ_ID_MOT] = INT_MAX; - - get_frame_mb(enc->frame_to_enc, cel->sourceX, cel->sourceY, mb8, 8); - - cel->eval_dist[RoQ_ID_SLD] = - index_mb(mb8, tempData->codebooks.unpacked_cb4_enlarged, - tempData->codebooks.numCB4, &cel->cbEntry, 8); - - gather_data_for_subcel(cel->subCels + 0, cel->sourceX+0, cel->sourceY+0, enc, tempData); - gather_data_for_subcel(cel->subCels + 1, cel->sourceX+4, cel->sourceY+0, enc, tempData); - gather_data_for_subcel(cel->subCels + 2, cel->sourceX+0, cel->sourceY+4, enc, tempData); - gather_data_for_subcel(cel->subCels + 3, cel->sourceX+4, cel->sourceY+4, enc, tempData); - - cel->eval_dist[RoQ_ID_CCC] = 0; - divide_bit_use = 0; - for (i=0; i<4; i++) { - cel->eval_dist[RoQ_ID_CCC] += - cel->subCels[i].eval_dist[cel->subCels[i].best_coding]; - divide_bit_use += cel->subCels[i].best_bit_use; - } - - best_dist = INT_MAX; - bitsUsed[3] = 2 + divide_bit_use; - - for (i=0; i<4; i++) - if (ROQ_LAMBDA_SCALE*cel->eval_dist[i] + enc->lambda*bitsUsed[i] < - best_dist) { - cel->best_coding = i; - best_dist = ROQ_LAMBDA_SCALE*cel->eval_dist[i] + - enc->lambda*bitsUsed[i]; - } - - tempData->used_option[cel->best_coding]++; - tempData->mainChunkSize += bitsUsed[cel->best_coding]; - - if (cel->best_coding == RoQ_ID_SLD) - tempData->codebooks.usedCB4[cel->cbEntry]++; - - if (cel->best_coding == RoQ_ID_CCC) - for (i=0; i<4; i++) { - if (cel->subCels[i].best_coding == RoQ_ID_SLD) - tempData->codebooks.usedCB4[cel->subCels[i].cbEntry]++; - else if (cel->subCels[i].best_coding == RoQ_ID_CCC) - for (j=0; j<4; j++) - tempData->codebooks.usedCB2[cel->subCels[i].subCels[j]]++; - } -} - -static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) -{ - int i, j, idx=0; - - /* Make remaps for the final codebook usage */ - for (i=0; icodebooks.usedCB4[i]) { - tempData->i2f4[i] = idx; - tempData->f2i4[idx] = i; - for (j=0; j<4; j++) - tempData->codebooks.usedCB2[enc->cb4x4[i].idx[j]]++; - idx++; - } - } - - tempData->numCB4 = idx; - - idx = 0; - for (i=0; icodebooks.usedCB2[i]) { - tempData->i2f2[i] = idx; - tempData->f2i2[idx] = i; - idx++; - } - } - tempData->numCB2 = idx; - -} - -/** - * Write codebook chunk - */ -static void write_codebooks(RoqContext *enc, RoqTempdata *tempData) -{ - int i, j; - uint8_t **outp= &enc->out_buf; - - if (tempData->numCB2) { - bytestream_put_le16(outp, RoQ_QUAD_CODEBOOK); - bytestream_put_le32(outp, tempData->numCB2*6 + tempData->numCB4*4); - bytestream_put_byte(outp, tempData->numCB4); - bytestream_put_byte(outp, tempData->numCB2); - - for (i=0; inumCB2; i++) { - bytestream_put_buffer(outp, enc->cb2x2[tempData->f2i2[i]].y, 4); - bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].u); - bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].v); - } - - for (i=0; inumCB4; i++) - for (j=0; j<4; j++) - bytestream_put_byte(outp, tempData->i2f2[enc->cb4x4[tempData->f2i4[i]].idx[j]]); - - } -} - -static inline uint8_t motion_arg(motion_vect mot) -{ - uint8_t ax = 8 - ((uint8_t) mot.d[0]); - uint8_t ay = 8 - ((uint8_t) mot.d[1]); - return ((ax&15)<<4) | (ay&15); -} - -typedef struct -{ - int typeSpool; - int typeSpoolLength; - uint8_t argumentSpool[64]; - uint8_t *args; - uint8_t **pout; -} CodingSpool; - -/* NOTE: Typecodes must be spooled AFTER arguments!! */ -static void write_typecode(CodingSpool *s, uint8_t type) -{ - s->typeSpool |= (type & 3) << (14 - s->typeSpoolLength); - s->typeSpoolLength += 2; - if (s->typeSpoolLength == 16) { - bytestream_put_le16(s->pout, s->typeSpool); - bytestream_put_buffer(s->pout, s->argumentSpool, - s->args - s->argumentSpool); - s->typeSpoolLength = 0; - s->typeSpool = 0; - s->args = s->argumentSpool; - } -} - -static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, int w, int h, int numBlocks) -{ - int i, j, k; - int x, y; - int subX, subY; - int dist=0; - - roq_qcell *qcell; - CelEvaluation *eval; - - CodingSpool spool; - - spool.typeSpool=0; - spool.typeSpoolLength=0; - spool.args = spool.argumentSpool; - spool.pout = &enc->out_buf; - - if (tempData->used_option[RoQ_ID_CCC]%2) - tempData->mainChunkSize+=8; //FIXME - - /* Write the video chunk header */ - bytestream_put_le16(&enc->out_buf, RoQ_QUAD_VQ); - bytestream_put_le32(&enc->out_buf, tempData->mainChunkSize/8); - bytestream_put_byte(&enc->out_buf, 0x0); - bytestream_put_byte(&enc->out_buf, 0x0); - - for (i=0; icel_evals + i; - - x = eval->sourceX; - y = eval->sourceY; - dist += eval->eval_dist[eval->best_coding]; - - switch (eval->best_coding) { - case RoQ_ID_MOT: - write_typecode(&spool, RoQ_ID_MOT); - break; - - case RoQ_ID_FCC: - bytestream_put_byte(&spool.args, motion_arg(eval->motion)); - - write_typecode(&spool, RoQ_ID_FCC); - ff_apply_motion_8x8(enc, x, y, - eval->motion.d[0], eval->motion.d[1]); - break; - - case RoQ_ID_SLD: - bytestream_put_byte(&spool.args, tempData->i2f4[eval->cbEntry]); - write_typecode(&spool, RoQ_ID_SLD); - - qcell = enc->cb4x4 + eval->cbEntry; - ff_apply_vector_4x4(enc, x , y , enc->cb2x2 + qcell->idx[0]); - ff_apply_vector_4x4(enc, x+4, y , enc->cb2x2 + qcell->idx[1]); - ff_apply_vector_4x4(enc, x , y+4, enc->cb2x2 + qcell->idx[2]); - ff_apply_vector_4x4(enc, x+4, y+4, enc->cb2x2 + qcell->idx[3]); - break; - - case RoQ_ID_CCC: - write_typecode(&spool, RoQ_ID_CCC); - - for (j=0; j<4; j++) { - subX = x + 4*(j&1); - subY = y + 2*(j&2); - - switch(eval->subCels[j].best_coding) { - case RoQ_ID_MOT: - break; - - case RoQ_ID_FCC: - bytestream_put_byte(&spool.args, - motion_arg(eval->subCels[j].motion)); - - ff_apply_motion_4x4(enc, subX, subY, - eval->subCels[j].motion.d[0], - eval->subCels[j].motion.d[1]); - break; - - case RoQ_ID_SLD: - bytestream_put_byte(&spool.args, - tempData->i2f4[eval->subCels[j].cbEntry]); - - qcell = enc->cb4x4 + eval->subCels[j].cbEntry; - - ff_apply_vector_2x2(enc, subX , subY , - enc->cb2x2 + qcell->idx[0]); - ff_apply_vector_2x2(enc, subX+2, subY , - enc->cb2x2 + qcell->idx[1]); - ff_apply_vector_2x2(enc, subX , subY+2, - enc->cb2x2 + qcell->idx[2]); - ff_apply_vector_2x2(enc, subX+2, subY+2, - enc->cb2x2 + qcell->idx[3]); - break; - - case RoQ_ID_CCC: - for (k=0; k<4; k++) { - int cb_idx = eval->subCels[j].subCels[k]; - bytestream_put_byte(&spool.args, - tempData->i2f2[cb_idx]); - - ff_apply_vector_2x2(enc, subX + 2*(k&1), subY + (k&2), - enc->cb2x2 + cb_idx); - } - break; - } - write_typecode(&spool, eval->subCels[j].best_coding); - } - break; - } - } - - /* Flush the remainder of the argument/type spool */ - while (spool.typeSpoolLength) - write_typecode(&spool, 0x0); - -#if 0 - uint8_t *fdata[3] = {enc->frame_to_enc->data[0], - enc->frame_to_enc->data[1], - enc->frame_to_enc->data[2]}; - uint8_t *cdata[3] = {enc->current_frame->data[0], - enc->current_frame->data[1], - enc->current_frame->data[2]}; - av_log(enc->avctx, AV_LOG_ERROR, "Expected distortion: %i Actual: %i\n", - dist, - block_sse(fdata, cdata, 0, 0, 0, 0, - enc->frame_to_enc->linesize, - enc->current_frame->linesize, - enc->width)); //WARNING: Square dimensions implied... -#endif -} - - -/** - * Create a single YUV cell from a 2x2 section of the image - */ -static inline void frame_block_to_cell(uint8_t *block, uint8_t **data, - int top, int left, int *stride) -{ - int i, j, u=0, v=0; - - for (i=0; i<2; i++) - for (j=0; j<2; j++) { - int x = (top+i)*stride[0] + left + j; - *block++ = data[0][x]; - x = (top+i)*stride[1] + left + j; - u += data[1][x]; - v += data[2][x]; - } - - *block++ = (u+2)/4; - *block++ = (v+2)/4; -} - -/** - * Creates YUV clusters for the entire image - */ -static void create_clusters(AVFrame *frame, int w, int h, uint8_t *yuvClusters) -{ - int i, j, k, l; - - for (i=0; idata, - i+2*k, j+2*l, frame->linesize); - yuvClusters += 24; - } -} - -static void generate_codebook(RoqContext *enc, RoqTempdata *tempdata, - int *points, int inputCount, roq_cell *results, - int size, int cbsize) -{ - int i, j, k; - int c_size = size*size/4; - int *buf; - int *codebook = av_malloc(6*c_size*cbsize*sizeof(int)); - int *closest_cb; - - if (size == 4) - closest_cb = av_malloc(6*c_size*inputCount*sizeof(int)); - else - closest_cb = tempdata->closest_cb2; - - ff_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); - ff_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); - - if (size == 4) - av_free(closest_cb); - - buf = codebook; - for (i=0; iy[j] = *buf++; - - results->u = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS; - results->v = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS; - results++; - } - - av_free(codebook); -} - -static void generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData) -{ - int i,j; - RoqCodebooks *codebooks = &tempData->codebooks; - int max = enc->width*enc->height/16; - uint8_t mb2[3*4]; - roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4); - uint8_t *yuvClusters=av_malloc(sizeof(int)*max*6*4); - int *points = av_malloc(max*6*4*sizeof(int)); - int bias; - - /* Subsample YUV data */ - create_clusters(enc->frame_to_enc, enc->width, enc->height, yuvClusters); - - /* Cast to integer and apply chroma bias */ - for (i=0; inumCB4 = MAX_CBS_4x4; - - tempData->closest_cb2 = av_malloc(max*4*sizeof(int)); - - /* Create 2x2 codebooks */ - generate_codebook(enc, tempData, points, max*4, enc->cb2x2, 2, MAX_CBS_2x2); - - codebooks->numCB2 = MAX_CBS_2x2; - - /* Unpack 2x2 codebook clusters */ - for (i=0; inumCB2; i++) - unpack_roq_cell(enc->cb2x2 + i, codebooks->unpacked_cb2 + i*2*2*3); - - /* Index all 4x4 entries to the 2x2 entries, unpack, and enlarge */ - for (i=0; inumCB4; i++) { - for (j=0; j<4; j++) { - unpack_roq_cell(&results4[4*i + j], mb2); - index_mb(mb2, codebooks->unpacked_cb2, codebooks->numCB2, - &enc->cb4x4[i].idx[j], 2); - } - unpack_roq_qcell(codebooks->unpacked_cb2, enc->cb4x4 + i, - codebooks->unpacked_cb4 + i*4*4*3); - enlarge_roq_mb4(codebooks->unpacked_cb4 + i*4*4*3, - codebooks->unpacked_cb4_enlarged + i*8*8*3); - } - - av_free(yuvClusters); - av_free(points); - av_free(results4); -} - -static void roq_encode_video(RoqContext *enc) -{ - RoqTempdata *tempData = enc->tmpData; - int i; - - memset(tempData, 0, sizeof(*tempData)); - - create_cel_evals(enc, tempData); - - generate_new_codebooks(enc, tempData); - - if (enc->framesSinceKeyframe >= 1) { - motion_search(enc, 8); - motion_search(enc, 4); - } - - retry_encode: - for (i=0; iwidth*enc->height/64; i++) - gather_data_for_cel(tempData->cel_evals + i, enc, tempData); - - /* Quake 3 can't handle chunks bigger than 65536 bytes */ - if (tempData->mainChunkSize/8 > 65536) { - enc->lambda *= .8; - goto retry_encode; - } - - remap_codebooks(enc, tempData); - - write_codebooks(enc, tempData); - - reconstruct_and_encode_image(enc, tempData, enc->width, enc->height, - enc->width*enc->height/64); - - enc->avctx->coded_frame = enc->current_frame; - - /* Rotate frame history */ - FFSWAP(AVFrame *, enc->current_frame, enc->last_frame); - FFSWAP(motion_vect *, enc->last_motion4, enc->this_motion4); - FFSWAP(motion_vect *, enc->last_motion8, enc->this_motion8); - - av_free(tempData->cel_evals); - av_free(tempData->closest_cb2); - - enc->framesSinceKeyframe++; -} - -static int roq_encode_init(AVCodecContext *avctx) -{ - RoqContext *enc = avctx->priv_data; - - av_lfg_init(&enc->randctx, 1); - - enc->framesSinceKeyframe = 0; - if ((avctx->width & 0xf) || (avctx->height & 0xf)) { - av_log(avctx, AV_LOG_ERROR, "Dimensions must be divisible by 16\n"); - return -1; - } - - if (((avctx->width)&(avctx->width-1))||((avctx->height)&(avctx->height-1))) - av_log(avctx, AV_LOG_ERROR, "Warning: dimensions not power of two\n"); - - enc->width = avctx->width; - enc->height = avctx->height; - - enc->framesSinceKeyframe = 0; - enc->first_frame = 1; - - enc->last_frame = &enc->frames[0]; - enc->current_frame = &enc->frames[1]; - - enc->tmpData = av_malloc(sizeof(RoqTempdata)); - - enc->this_motion4 = - av_mallocz((enc->width*enc->height/16)*sizeof(motion_vect)); - - enc->last_motion4 = - av_malloc ((enc->width*enc->height/16)*sizeof(motion_vect)); - - enc->this_motion8 = - av_mallocz((enc->width*enc->height/64)*sizeof(motion_vect)); - - enc->last_motion8 = - av_malloc ((enc->width*enc->height/64)*sizeof(motion_vect)); - - return 0; -} - -static void roq_write_video_info_chunk(RoqContext *enc) -{ - /* ROQ info chunk */ - bytestream_put_le16(&enc->out_buf, RoQ_INFO); - - /* Size: 8 bytes */ - bytestream_put_le32(&enc->out_buf, 8); - - /* Unused argument */ - bytestream_put_byte(&enc->out_buf, 0x00); - bytestream_put_byte(&enc->out_buf, 0x00); - - /* Width */ - bytestream_put_le16(&enc->out_buf, enc->width); - - /* Height */ - bytestream_put_le16(&enc->out_buf, enc->height); - - /* Unused in Quake 3, mimics the output of the real encoder */ - bytestream_put_byte(&enc->out_buf, 0x08); - bytestream_put_byte(&enc->out_buf, 0x00); - bytestream_put_byte(&enc->out_buf, 0x04); - bytestream_put_byte(&enc->out_buf, 0x00); -} - -static int roq_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) -{ - RoqContext *enc = avctx->priv_data; - AVFrame *frame= data; - uint8_t *buf_start = buf; - - enc->out_buf = buf; - enc->avctx = avctx; - - enc->frame_to_enc = frame; - - if (frame->quality) - enc->lambda = frame->quality - 1; - else - enc->lambda = 2*ROQ_LAMBDA_SCALE; - - /* 138 bits max per 8x8 block + - * 256 codebooks*(6 bytes 2x2 + 4 bytes 4x4) + 8 bytes frame header */ - if (((enc->width*enc->height/64)*138+7)/8 + 256*(6+4) + 8 > buf_size) { - av_log(avctx, AV_LOG_ERROR, " RoQ: Output buffer too small!\n"); - return -1; - } - - /* Check for I frame */ - if (enc->framesSinceKeyframe == avctx->gop_size) - enc->framesSinceKeyframe = 0; - - if (enc->first_frame) { - /* Alloc memory for the reconstruction data (we must know the stride - for that) */ - if (avctx->get_buffer(avctx, enc->current_frame) || - avctx->get_buffer(avctx, enc->last_frame)) { - av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); - return -1; - } - - /* Before the first video frame, write a "video info" chunk */ - roq_write_video_info_chunk(enc); - - enc->first_frame = 0; - } - - /* Encode the actual frame */ - roq_encode_video(enc); - - return enc->out_buf - buf_start; -} - -static int roq_encode_end(AVCodecContext *avctx) -{ - RoqContext *enc = avctx->priv_data; - - avctx->release_buffer(avctx, enc->last_frame); - avctx->release_buffer(avctx, enc->current_frame); - - av_free(enc->tmpData); - av_free(enc->this_motion4); - av_free(enc->last_motion4); - av_free(enc->this_motion8); - av_free(enc->last_motion8); - - return 0; -} - -AVCodec roq_encoder = -{ - "roqvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ROQ, - sizeof(RoqContext), - roq_encode_init, - roq_encode_frame, - roq_encode_end, - .supported_framerates = (const AVRational[]){{30,1}, {0,0}}, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV444P, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rpza.c b/tizen/distrib/ffmpeg/libavcodec/rpza.c deleted file mode 100644 index e103f52..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rpza.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Quicktime Video (RPZA) Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QT RPZA Video Decoder by Roberto Togni - * For more information about the RPZA format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * The RPZA decoder outputs RGB555 colorspace data. - * - * Note that this decoder reads big endian RGB555 pixel values from the - * bytestream, arranges them in the host's endian order, and outputs - * them to the final rendered map in the same host endian order. This is - * intended behavior as the ffmpeg documentation states that RGB555 pixels - * shall be stored in native CPU endianness. - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct RpzaContext { - - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *buf; - int size; - -} RpzaContext; - -#define ADVANCE_BLOCK() \ -{ \ - pixel_ptr += 4; \ - if (pixel_ptr >= width) \ - { \ - pixel_ptr = 0; \ - row_ptr += stride * 4; \ - } \ - total_blocks--; \ - if (total_blocks < 0) \ - { \ - av_log(s->avctx, AV_LOG_ERROR, "warning: block counter just went negative (this should not happen)\n"); \ - return; \ - } \ -} - -static void rpza_decode_stream(RpzaContext *s) -{ - int width = s->avctx->width; - int stride = s->frame.linesize[0] / 2; - int row_inc = stride - 4; - int stream_ptr = 0; - int chunk_size; - unsigned char opcode; - int n_blocks; - unsigned short colorA = 0, colorB; - unsigned short color4[4]; - unsigned char index, idx; - unsigned short ta, tb; - unsigned short *pixels = (unsigned short *)s->frame.data[0]; - - int row_ptr = 0; - int pixel_ptr = 0; - int block_ptr; - int pixel_x, pixel_y; - int total_blocks; - - /* First byte is always 0xe1. Warn if it's different */ - if (s->buf[stream_ptr] != 0xe1) - av_log(s->avctx, AV_LOG_ERROR, "First chunk byte is 0x%02x instead of 0xe1\n", - s->buf[stream_ptr]); - - /* Get chunk size, ingnoring first byte */ - chunk_size = AV_RB32(&s->buf[stream_ptr]) & 0x00FFFFFF; - stream_ptr += 4; - - /* If length mismatch use size from MOV file and try to decode anyway */ - if (chunk_size != s->size) - av_log(s->avctx, AV_LOG_ERROR, "MOV chunk size != encoded chunk size; using MOV chunk size\n"); - - chunk_size = s->size; - - /* Number of 4x4 blocks in frame. */ - total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4); - - /* Process chunk data */ - while (stream_ptr < chunk_size) { - opcode = s->buf[stream_ptr++]; /* Get opcode */ - - n_blocks = (opcode & 0x1f) + 1; /* Extract block counter from opcode */ - - /* If opcode MSbit is 0, we need more data to decide what to do */ - if ((opcode & 0x80) == 0) { - colorA = (opcode << 8) | (s->buf[stream_ptr++]); - opcode = 0; - if ((s->buf[stream_ptr] & 0x80) != 0) { - /* Must behave as opcode 110xxxxx, using colorA computed - * above. Use fake opcode 0x20 to enter switch block at - * the right place */ - opcode = 0x20; - n_blocks = 1; - } - } - - switch (opcode & 0xe0) { - - /* Skip blocks */ - case 0x80: - while (n_blocks--) { - ADVANCE_BLOCK(); - } - break; - - /* Fill blocks with one color */ - case 0xa0: - colorA = AV_RB16 (&s->buf[stream_ptr]); - stream_ptr += 2; - while (n_blocks--) { - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++){ - pixels[block_ptr] = colorA; - block_ptr++; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* Fill blocks with 4 colors */ - case 0xc0: - colorA = AV_RB16 (&s->buf[stream_ptr]); - stream_ptr += 2; - case 0x20: - colorB = AV_RB16 (&s->buf[stream_ptr]); - stream_ptr += 2; - - /* sort out the colors */ - color4[0] = colorB; - color4[1] = 0; - color4[2] = 0; - color4[3] = colorA; - - /* red components */ - ta = (colorA >> 10) & 0x1F; - tb = (colorB >> 10) & 0x1F; - color4[1] |= ((11 * ta + 21 * tb) >> 5) << 10; - color4[2] |= ((21 * ta + 11 * tb) >> 5) << 10; - - /* green components */ - ta = (colorA >> 5) & 0x1F; - tb = (colorB >> 5) & 0x1F; - color4[1] |= ((11 * ta + 21 * tb) >> 5) << 5; - color4[2] |= ((21 * ta + 11 * tb) >> 5) << 5; - - /* blue components */ - ta = colorA & 0x1F; - tb = colorB & 0x1F; - color4[1] |= ((11 * ta + 21 * tb) >> 5); - color4[2] |= ((21 * ta + 11 * tb) >> 5); - - while (n_blocks--) { - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - index = s->buf[stream_ptr++]; - for (pixel_x = 0; pixel_x < 4; pixel_x++){ - idx = (index >> (2 * (3 - pixel_x))) & 0x03; - pixels[block_ptr] = color4[idx]; - block_ptr++; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* Fill block with 16 colors */ - case 0x00: - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++){ - /* We already have color of upper left pixel */ - if ((pixel_y != 0) || (pixel_x !=0)) { - colorA = AV_RB16 (&s->buf[stream_ptr]); - stream_ptr += 2; - } - pixels[block_ptr] = colorA; - block_ptr++; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - break; - - /* Unknown opcode */ - default: - av_log(s->avctx, AV_LOG_ERROR, "Unknown opcode %d in rpza chunk." - " Skip remaining %d bytes of chunk data.\n", opcode, - chunk_size - stream_ptr); - return; - } /* Opcode switch */ - } -} - -static av_cold int rpza_decode_init(AVCodecContext *avctx) -{ - RpzaContext *s = avctx->priv_data; - - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_RGB555; - - s->frame.data[0] = NULL; - - return 0; -} - -static int rpza_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - RpzaContext *s = avctx->priv_data; - - s->buf = 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; - } - - rpza_decode_stream(s); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int rpza_decode_end(AVCodecContext *avctx) -{ - RpzaContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec rpza_decoder = { - "rpza", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RPZA, - sizeof(RpzaContext), - rpza_decode_init, - NULL, - rpza_decode_end, - rpza_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rtjpeg.c b/tizen/distrib/ffmpeg/libavcodec/rtjpeg.c deleted file mode 100644 index 4c48f25..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rtjpeg.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * RTJpeg decoding functions - * Copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "libavutil/common.h" -#include "get_bits.h" -#include "dsputil.h" -#include "rtjpeg.h" - -#define PUT_COEFF(c) \ - i = scan[coeff--]; \ - block[i] = (c) * quant[i]; - -//! aligns the bitstream to the give power of two -#define ALIGN(a) \ - n = (-get_bits_count(gb)) & (a - 1); \ - if (n) {skip_bits(gb, n);} - -/** - * \brief read one block from stream - * \param gb contains stream data - * \param block where data is written to - * \param scan array containing the mapping stream address -> block position - * \param quant quantization factors - * \return 0 means the block is not coded, < 0 means an error occurred. - * - * Note: GetBitContext is used to make the code simpler, since all data is - * aligned this could be done faster in a different way, e.g. as it is done - * in MPlayer libmpcodecs/native/rtjpegn.c. - */ -static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan, - const uint32_t *quant) { - int coeff, i, n; - int8_t ac; - uint8_t dc = get_bits(gb, 8); - - // block not coded - if (dc == 255) - return 0; - - // number of non-zero coefficients - coeff = get_bits(gb, 6); - if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits) - return -1; - - // normally we would only need to clear the (63 - coeff) last values, - // but since we do not know where they are we just clear the whole block - memset(block, 0, 64 * sizeof(DCTELEM)); - - // 2 bits per coefficient - while (coeff) { - ac = get_sbits(gb, 2); - if (ac == -2) - break; // continue with more bits - PUT_COEFF(ac); - } - - // 4 bits per coefficient - ALIGN(4); - if (get_bits_count(gb) + (coeff << 2) >= gb->size_in_bits) - return -1; - while (coeff) { - ac = get_sbits(gb, 4); - if (ac == -8) - break; // continue with more bits - PUT_COEFF(ac); - } - - // 8 bits per coefficient - ALIGN(8); - if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits) - return -1; - while (coeff) { - ac = get_sbits(gb, 8); - PUT_COEFF(ac); - } - - PUT_COEFF(dc); - return 1; -} - -/** - * \brief decode one rtjpeg YUV420 frame - * \param c context, must be initialized via rtjpeg_decode_init - * \param f AVFrame to place decoded frame into. If parts of the frame - * are not coded they are left unchanged, so consider initializing it - * \param buf buffer containing input data - * \param buf_size length of input data in bytes - * \return number of bytes consumed from the input buffer - */ -int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, - const uint8_t *buf, int buf_size) { - GetBitContext gb; - int w = c->w / 16, h = c->h / 16; - int x, y; - uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0]; - uint8_t *u = f->data[1], *v = f->data[2]; - init_get_bits(&gb, buf, buf_size * 8); - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - DCTELEM *block = c->block; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y1, f->linesize[0], block); - y1 += 8; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y1, f->linesize[0], block); - y1 += 8; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y2, f->linesize[0], block); - y2 += 8; - if (get_block(&gb, block, c->scan, c->lquant) > 0) - c->dsp->idct_put(y2, f->linesize[0], block); - y2 += 8; - if (get_block(&gb, block, c->scan, c->cquant) > 0) - c->dsp->idct_put(u, f->linesize[1], block); - u += 8; - if (get_block(&gb, block, c->scan, c->cquant) > 0) - c->dsp->idct_put(v, f->linesize[2], block); - v += 8; - } - y1 += 2 * 8 * (f->linesize[0] - w); - y2 += 2 * 8 * (f->linesize[0] - w); - u += 8 * (f->linesize[1] - w); - v += 8 * (f->linesize[2] - w); - } - return get_bits_count(&gb) / 8; -} - -/** - * \brief initialize an RTJpegContext, may be called multiple times - * \param c context to initialize - * \param dsp specifies the idct to use for decoding - * \param width width of image, will be rounded down to the nearest multiple - * of 16 for decoding - * \param height height of image, will be rounded down to the nearest multiple - * of 16 for decoding - * \param lquant luma quantization table to use - * \param cquant chroma quantization table to use - */ -void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp, - int width, int height, - const uint32_t *lquant, const uint32_t *cquant) { - int i; - c->dsp = dsp; - for (i = 0; i < 64; i++) { - int z = ff_zigzag_direct[i]; - int p = c->dsp->idct_permutation[i]; - z = ((z << 3) | (z >> 3)) & 63; // rtjpeg uses a transposed variant - - // permute the scan and quantization tables for the chosen idct - c->scan[i] = c->dsp->idct_permutation[z]; - c->lquant[p] = lquant[i]; - c->cquant[p] = cquant[i]; - } - c->w = width; - c->h = height; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/rtjpeg.h b/tizen/distrib/ffmpeg/libavcodec/rtjpeg.h deleted file mode 100644 index 4bcb9f7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rtjpeg.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * RTJpeg decoding functions - * copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_RTJPEG_H -#define AVCODEC_RTJPEG_H - -#include -#include "dsputil.h" - -typedef struct { - int w, h; - DSPContext *dsp; - uint8_t scan[64]; - uint32_t lquant[64]; - uint32_t cquant[64]; - DECLARE_ALIGNED(16, DCTELEM, block)[64]; -} RTJpegContext; - -void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp, - int width, int height, - const uint32_t *lquant, const uint32_t *cquant); - -int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, - const uint8_t *buf, int buf_size); -#endif /* AVCODEC_RTJPEG_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rv10.c b/tizen/distrib/ffmpeg/libavcodec/rv10.c deleted file mode 100644 index b6ca031..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv10.c +++ /dev/null @@ -1,736 +0,0 @@ -/* - * RV10/RV20 decoder - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV10/RV20 decoder - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mpeg4video.h" -#include "h263.h" - -//#define DEBUG - -#define DC_VLC_BITS 14 //FIXME find a better solution - -static const uint16_t rv_lum_code[256] = -{ - 0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06, - 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e, - 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, - 0x0f17, 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, - 0x0f1f, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, - 0x0f27, 0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, - 0x0f2f, 0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36, - 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e, - 0x0f3f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386, - 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e, - 0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, - 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, - 0x039f, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, - 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, - 0x00cf, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, - 0x0057, 0x0020, 0x0021, 0x0022, 0x0023, 0x000c, 0x000d, 0x0004, - 0x0000, 0x0005, 0x000e, 0x000f, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, - 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, - 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, - 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, - 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, - 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, - 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47, - 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f, - 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57, - 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f, - 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, - 0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, - 0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, - 0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, -}; - -static const uint8_t rv_lum_bits[256] = -{ - 14, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 7, 7, 7, 7, 7, 7, 7, - 7, 6, 6, 6, 6, 5, 5, 4, - 2, 4, 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, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, -}; - -static const uint16_t rv_chrom_code[256] = -{ - 0xfe7f, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06, - 0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e, - 0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16, - 0x3f17, 0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e, - 0x3f1f, 0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26, - 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e, - 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36, - 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e, - 0x3f3f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86, - 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e, - 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96, - 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e, - 0x0f9f, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, - 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, - 0x03cf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, - 0x00e7, 0x0030, 0x0031, 0x0032, 0x0033, 0x0008, 0x0009, 0x0002, - 0x0000, 0x0003, 0x000a, 0x000b, 0x0034, 0x0035, 0x0036, 0x0037, - 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, - 0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7, - 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df, - 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7, - 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, - 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, - 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, - 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47, - 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f, - 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57, - 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f, - 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67, - 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f, - 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77, - 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f, -}; - -static const uint8_t rv_chrom_bits[256] = -{ - 16, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 8, 8, 8, 8, 8, 8, 8, - 8, 6, 6, 6, 6, 4, 4, 3, - 2, 3, 4, 4, 6, 6, 6, 6, - 8, 8, 8, 8, 8, 8, 8, 8, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, -}; - -static VLC rv_dc_lum, rv_dc_chrom; - -int rv_decode_dc(MpegEncContext *s, int n) -{ - int code; - - if (n < 4) { - code = get_vlc2(&s->gb, rv_dc_lum.table, DC_VLC_BITS, 2); - if (code < 0) { - /* XXX: I don't understand why they use LONGER codes than - necessary. The following code would be completely useless - if they had thought about it !!! */ - code = get_bits(&s->gb, 7); - if (code == 0x7c) { - code = (int8_t)(get_bits(&s->gb, 7) + 1); - } else if (code == 0x7d) { - code = -128 + get_bits(&s->gb, 7); - } else if (code == 0x7e) { - if (get_bits1(&s->gb) == 0) - code = (int8_t)(get_bits(&s->gb, 8) + 1); - else - code = (int8_t)(get_bits(&s->gb, 8)); - } else if (code == 0x7f) { - skip_bits(&s->gb, 11); - code = 1; - } - } else { - code -= 128; - } - } else { - code = get_vlc2(&s->gb, rv_dc_chrom.table, DC_VLC_BITS, 2); - /* same remark */ - if (code < 0) { - code = get_bits(&s->gb, 9); - if (code == 0x1fc) { - code = (int8_t)(get_bits(&s->gb, 7) + 1); - } else if (code == 0x1fd) { - code = -128 + get_bits(&s->gb, 7); - } else if (code == 0x1fe) { - skip_bits(&s->gb, 9); - code = 1; - } else { - av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n"); - return 0xffff; - } - } else { - code -= 128; - } - } - return -code; -} - -/* read RV 1.0 compatible frame header */ -static int rv10_decode_picture_header(MpegEncContext *s) -{ - int mb_count, pb_frame, marker, unk, mb_xy; - - marker = get_bits1(&s->gb); - - if (get_bits1(&s->gb)) - s->pict_type = FF_P_TYPE; - else - s->pict_type = FF_I_TYPE; - if(!marker) av_log(s->avctx, AV_LOG_ERROR, "marker missing\n"); - pb_frame = get_bits1(&s->gb); - - dprintf(s->avctx, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame); - - if (pb_frame){ - av_log(s->avctx, AV_LOG_ERROR, "pb frame not supported\n"); - return -1; - } - - s->qscale = get_bits(&s->gb, 5); - if(s->qscale==0){ - av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n"); - return -1; - } - - if (s->pict_type == FF_I_TYPE) { - if (s->rv10_version == 3) { - /* specific MPEG like DC coding not used */ - s->last_dc[0] = get_bits(&s->gb, 8); - s->last_dc[1] = get_bits(&s->gb, 8); - s->last_dc[2] = get_bits(&s->gb, 8); - dprintf(s->avctx, "DC:%d %d %d\n", s->last_dc[0], - s->last_dc[1], s->last_dc[2]); - } - } - /* if multiple packets per frame are sent, the position at which - to display the macroblocks is coded here */ - - mb_xy= s->mb_x + s->mb_y*s->mb_width; - if(show_bits(&s->gb, 12)==0 || (mb_xy && mb_xy < s->mb_num)){ - s->mb_x = get_bits(&s->gb, 6); /* mb_x */ - s->mb_y = get_bits(&s->gb, 6); /* mb_y */ - mb_count = get_bits(&s->gb, 12); - } else { - s->mb_x = 0; - s->mb_y = 0; - mb_count = s->mb_width * s->mb_height; - } - unk= get_bits(&s->gb, 3); /* ignored */ - s->f_code = 1; - s->unrestricted_mv = 1; - - return mb_count; -} - -static int rv20_decode_picture_header(MpegEncContext *s) -{ - int seq, mb_pos, i; - -#if 0 - GetBitContext gb= s->gb; - for(i=0; i<64; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&gb)); - if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); -#endif -#if 0 - av_log(s->avctx, AV_LOG_DEBUG, "%3dx%03d/%02Xx%02X ", s->width, s->height, s->width/4, s->height/4); - for(i=0; iavctx->extradata_size; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "%02X ", ((uint8_t*)s->avctx->extradata)[i]); - if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); -#endif - - if(s->avctx->sub_id == 0x30202002 || s->avctx->sub_id == 0x30203002){ - if (get_bits(&s->gb, 3)){ - av_log(s->avctx, AV_LOG_ERROR, "unknown triplet set\n"); - return -1; - } - } - - i= get_bits(&s->gb, 2); - switch(i){ - case 0: s->pict_type= FF_I_TYPE; break; - case 1: s->pict_type= FF_I_TYPE; break; //hmm ... - case 2: s->pict_type= FF_P_TYPE; break; - case 3: s->pict_type= FF_B_TYPE; break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown frame type\n"); - return -1; - } - - if(s->last_picture_ptr==NULL && s->pict_type==FF_B_TYPE){ - av_log(s->avctx, AV_LOG_ERROR, "early B pix\n"); - return -1; - } - - if (get_bits1(&s->gb)){ - av_log(s->avctx, AV_LOG_ERROR, "unknown bit set\n"); - return -1; - } - - s->qscale = get_bits(&s->gb, 5); - if(s->qscale==0){ - av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n"); - return -1; - } - if(s->avctx->sub_id == 0x30203002){ - if (get_bits1(&s->gb)){ - av_log(s->avctx, AV_LOG_ERROR, "unknown bit2 set\n"); - return -1; - } - } - - if(s->avctx->has_b_frames){ - int f, new_w, new_h; - int v= s->avctx->extradata_size >= 4 ? 7&((uint8_t*)s->avctx->extradata)[1] : 0; - - if (get_bits1(&s->gb)){ - av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n"); - } - seq= get_bits(&s->gb, 13)<<2; - - f= get_bits(&s->gb, av_log2(v)+1); - - if(f){ - new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f]; - new_h= 4*((uint8_t*)s->avctx->extradata)[7+2*f]; - }else{ - new_w= s->orig_width ; - new_h= s->orig_height; - } - if(new_w != s->width || new_h != s->height){ - av_log(s->avctx, AV_LOG_DEBUG, "attempting to change resolution to %dx%d\n", new_w, new_h); - if (avcodec_check_dimensions(s->avctx, new_w, new_h) < 0) - return -1; - MPV_common_end(s); - avcodec_set_dimensions(s->avctx, new_w, new_h); - s->width = new_w; - s->height = new_h; - if (MPV_common_init(s) < 0) - return -1; - } - - if(s->avctx->debug & FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, v); - } - }else{ - seq= get_bits(&s->gb, 8)*128; - } - -// if(s->avctx->sub_id <= 0x20201002){ //0x20201002 definitely needs this - mb_pos= ff_h263_decode_mba(s); -/* }else{ - mb_pos= get_bits(&s->gb, av_log2(s->mb_num-1)+1); - s->mb_x= mb_pos % s->mb_width; - s->mb_y= mb_pos / s->mb_width; - }*/ -//av_log(s->avctx, AV_LOG_DEBUG, "%d\n", seq); - seq |= s->time &~0x7FFF; - if(seq - s->time > 0x4000) seq -= 0x8000; - if(seq - s->time < -0x4000) seq += 0x8000; - if(seq != s->time){ - if(s->pict_type!=FF_B_TYPE){ - s->time= seq; - s->pp_time= s->time - s->last_non_b_time; - s->last_non_b_time= s->time; - }else{ - s->time= seq; - 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){ - av_log(s->avctx, AV_LOG_DEBUG, "messed up order, possible from seeking? skipping current b frame\n"); - return FRAME_SKIPPED; - } - ff_mpeg4_init_direct_mv(s); - } - } -// printf("%d %d %d %d %d\n", seq, (int)s->time, (int)s->last_non_b_time, s->pp_time, s->pb_time); -/*for(i=0; i<32; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb)); -} -av_log(s->avctx, AV_LOG_DEBUG, "\n");*/ - s->no_rounding= get_bits1(&s->gb); - - s->f_code = 1; - s->unrestricted_mv = 1; - s->h263_aic= s->pict_type == FF_I_TYPE; -// s->alt_inter_vlc=1; -// s->obmc=1; -// s->umvplus=1; - s->modified_quant=1; - if(!s->avctx->lowres) - s->loop_filter=1; - - if(s->avctx->debug & FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n", - seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding); - } - - assert(s->pict_type != FF_B_TYPE || !s->low_delay); - - return s->mb_width*s->mb_height - mb_pos; -} - -static av_cold int rv10_decode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - static int done=0; - - if (avctx->extradata_size < 8) { - av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); - return -1; - } - - MPV_decode_defaults(s); - - s->avctx= avctx; - s->out_format = FMT_H263; - s->codec_id= avctx->codec_id; - - s->orig_width = s->width = avctx->coded_width; - s->orig_height= s->height = avctx->coded_height; - - s->h263_long_vectors= ((uint8_t*)avctx->extradata)[3] & 1; - avctx->sub_id= AV_RB32((uint8_t*)avctx->extradata + 4); - - if (avctx->sub_id == 0x10000000) { - s->rv10_version= 0; - s->low_delay=1; - } else if (avctx->sub_id == 0x10001000) { - s->rv10_version= 3; - s->low_delay=1; - } else if (avctx->sub_id == 0x10002000) { - s->rv10_version= 3; - s->low_delay=1; - s->obmc=1; - } else if (avctx->sub_id == 0x10003000) { - s->rv10_version= 3; - s->low_delay=1; - } else if (avctx->sub_id == 0x10003001) { - s->rv10_version= 3; - s->low_delay=1; - } else if ( avctx->sub_id == 0x20001000 - || (avctx->sub_id >= 0x20100000 && avctx->sub_id < 0x201a0000)) { - s->low_delay=1; - } else if ( avctx->sub_id == 0x30202002 - || avctx->sub_id == 0x30203002 - || (avctx->sub_id >= 0x20200002 && avctx->sub_id < 0x20300000)) { - s->low_delay=0; - s->avctx->has_b_frames=1; - } else - av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", avctx->sub_id); - - if(avctx->debug & FF_DEBUG_PICT_INFO){ - av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", avctx->sub_id, avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1); - } - - avctx->pix_fmt = PIX_FMT_YUV420P; - - if (MPV_common_init(s) < 0) - return -1; - - h263_decode_init_vlc(s); - - /* init rv vlc */ - if (!done) { - INIT_VLC_STATIC(&rv_dc_lum, DC_VLC_BITS, 256, - rv_lum_bits, 1, 1, - rv_lum_code, 2, 2, 16384); - INIT_VLC_STATIC(&rv_dc_chrom, DC_VLC_BITS, 256, - rv_chrom_bits, 1, 1, - rv_chrom_code, 2, 2, 16388); - done = 1; - } - - return 0; -} - -static av_cold int rv10_decode_end(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - - MPV_common_end(s); - return 0; -} - -static int rv10_decode_packet(AVCodecContext *avctx, - const uint8_t *buf, int buf_size, int buf_size2) -{ - MpegEncContext *s = avctx->priv_data; - int mb_count, mb_pos, left, start_mb_x; - - init_get_bits(&s->gb, buf, buf_size*8); - if(s->codec_id ==CODEC_ID_RV10) - mb_count = rv10_decode_picture_header(s); - else - mb_count = rv20_decode_picture_header(s); - if (mb_count < 0) { - av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n"); - return -1; - } - - if (s->mb_x >= s->mb_width || - s->mb_y >= s->mb_height) { - av_log(s->avctx, AV_LOG_ERROR, "POS ERROR %d %d\n", s->mb_x, s->mb_y); - return -1; - } - mb_pos = s->mb_y * s->mb_width + s->mb_x; - left = s->mb_width * s->mb_height - mb_pos; - if (mb_count > left) { - av_log(s->avctx, AV_LOG_ERROR, "COUNT ERROR\n"); - return -1; - } - - if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) { - if(s->current_picture_ptr){ //FIXME write parser so we always have complete frames? - ff_er_frame_end(s); - MPV_frame_end(s); - s->mb_x= s->mb_y = s->resync_mb_x = s->resync_mb_y= 0; - } - if(MPV_frame_start(s, avctx) < 0) - return -1; - ff_er_frame_start(s); - } - - dprintf(avctx, "qscale=%d\n", s->qscale); - - /* default quantization values */ - if(s->codec_id== CODEC_ID_RV10){ - if(s->mb_y==0) s->first_slice_line=1; - }else{ - s->first_slice_line=1; - s->resync_mb_x= s->mb_x; - } - start_mb_x= s->mb_x; - s->resync_mb_y= s->mb_y; - 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->modified_quant) - s->chroma_qscale_table= ff_h263_chroma_qscale_table; - - ff_set_qscale(s, s->qscale); - - s->rv10_first_dc_coded[0] = 0; - s->rv10_first_dc_coded[1] = 0; - s->rv10_first_dc_coded[2] = 0; - s->block_wrap[0]= - s->block_wrap[1]= - s->block_wrap[2]= - s->block_wrap[3]= s->b8_stride; - s->block_wrap[4]= - s->block_wrap[5]= s->mb_stride; - ff_init_block_index(s); - /* decode each macroblock */ - - for(s->mb_num_left= mb_count; s->mb_num_left>0; s->mb_num_left--) { - int ret; - ff_update_block_index(s); - dprintf(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y); - - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - ret=ff_h263_decode_mb(s, s->block); - - if (ret != SLICE_ERROR && s->gb.size_in_bits < get_bits_count(&s->gb) && 8*buf_size2 >= get_bits_count(&s->gb)){ - av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n", s->gb.size_in_bits, 8*buf_size2); - s->gb.size_in_bits= 8*buf_size2; - ret= SLICE_OK; - } - - if (ret == SLICE_ERROR || s->gb.size_in_bits < get_bits_count(&s->gb)) { - av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); - return -1; - } - if(s->pict_type != FF_B_TYPE) - ff_h263_update_motion_val(s); - MPV_decode_mb(s, s->block); - if(s->loop_filter) - ff_h263_loop_filter(s); - - if (++s->mb_x == s->mb_width) { - s->mb_x = 0; - s->mb_y++; - ff_init_block_index(s); - } - if(s->mb_x == s->resync_mb_x) - s->first_slice_line=0; - if(ret == SLICE_END) break; - } - - ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END); - - return s->gb.size_in_bits; -} - -static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) -{ - if(avctx->slice_count) return avctx->slice_offset[n]; - else return AV_RL32(buf + n*8); -} - -static int rv10_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MpegEncContext *s = avctx->priv_data; - int i; - AVFrame *pict = data; - int slice_count; - const uint8_t *slices_hdr = NULL; - - dprintf(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); - - /* no supplementary picture */ - if (buf_size == 0) { - return 0; - } - - if(!avctx->slice_count){ - slice_count = (*buf++) + 1; - slices_hdr = buf + 4; - buf += 8 * slice_count; - }else - slice_count = avctx->slice_count; - - for(i=0; i= slice_count) - size2= buf_size - offset; - else - size2= get_slice_offset(avctx, slices_hdr, i+2) - offset; - - if(rv10_decode_packet(avctx, buf+offset, size, size2) > 8*size) - i++; - } - - if(s->current_picture_ptr != NULL && s->mb_y>=s->mb_height){ - ff_er_frame_end(s); - MPV_frame_end(s); - - if (s->pict_type == FF_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); - } - s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) - } - - return buf_size; -} - -AVCodec rv10_decoder = { - "rv10", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RV10, - sizeof(MpegEncContext), - rv10_decode_init, - NULL, - rv10_decode_end, - rv10_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"), - .pix_fmts= ff_pixfmt_list_420, -}; - -AVCodec rv20_decoder = { - "rv20", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RV20, - sizeof(MpegEncContext), - rv10_decode_init, - NULL, - rv10_decode_end, - rv10_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .flush= ff_mpeg_flush, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"), - .pix_fmts= ff_pixfmt_list_420, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rv10enc.c b/tizen/distrib/ffmpeg/libavcodec/rv10enc.c deleted file mode 100644 index 51ca691..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv10enc.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * RV10 encoder - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV10 encoder - */ - -#include "mpegvideo.h" -#include "put_bits.h" - -void rv10_encode_picture_header(MpegEncContext *s, int picture_number) -{ - int full_frame= 0; - - align_put_bits(&s->pb); - - put_bits(&s->pb, 1, 1); /* marker */ - - put_bits(&s->pb, 1, (s->pict_type == FF_P_TYPE)); - - put_bits(&s->pb, 1, 0); /* not PB frame */ - - put_bits(&s->pb, 5, s->qscale); - - if (s->pict_type == FF_I_TYPE) { - /* specific MPEG like DC coding not used */ - } - /* if multiple packets per frame are sent, the position at which - to display the macroblocks is coded here */ - if(!full_frame){ - put_bits(&s->pb, 6, 0); /* mb_x */ - put_bits(&s->pb, 6, 0); /* mb_y */ - put_bits(&s->pb, 12, s->mb_width * s->mb_height); - } - - put_bits(&s->pb, 3, 0); /* ignored */ -} - -AVCodec rv10_encoder = { - "rv10", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RV10, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("RealVideo 1.0"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rv20enc.c b/tizen/distrib/ffmpeg/libavcodec/rv20enc.c deleted file mode 100644 index 5ab0b9a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv20enc.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * RV20 encoder - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV20 encoder - */ - -#include "mpegvideo.h" -#include "h263.h" -#include "put_bits.h" - -void rv20_encode_picture_header(MpegEncContext *s, int picture_number){ - put_bits(&s->pb, 2, s->pict_type); //I 0 vs. 1 ? - put_bits(&s->pb, 1, 0); /* unknown bit */ - put_bits(&s->pb, 5, s->qscale); - - put_sbits(&s->pb, 8, picture_number); //FIXME wrong, but correct is not known - s->mb_x= s->mb_y= 0; - ff_h263_encode_mba(s); - - put_bits(&s->pb, 1, s->no_rounding); - - assert(s->f_code == 1); - assert(s->unrestricted_mv == 1); - assert(s->alt_inter_vlc == 0); - assert(s->umvplus == 0); - assert(s->modified_quant==1); - assert(s->loop_filter==1); - - s->h263_aic= s->pict_type == FF_I_TYPE; - 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; - } -} - -AVCodec rv20_encoder = { - "rv20", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RV20, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("RealVideo 2.0"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rv30.c b/tizen/distrib/ffmpeg/libavcodec/rv30.c deleted file mode 100644 index 22a5dd5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv30.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * RV30 decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV30 decoder - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "golomb.h" - -#include "rv34.h" -#include "rv30data.h" - - -static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) -{ - int mb_bits; - int w = r->s.width, h = r->s.height; - int mb_size; - int rpr; - - memset(si, 0, sizeof(SliceInfo)); - if(get_bits(gb, 3)) - return -1; - si->type = get_bits(gb, 2); - if(si->type == 1) si->type = 0; - if(get_bits1(gb)) - return -1; - si->quant = get_bits(gb, 5); - skip_bits1(gb); - si->pts = get_bits(gb, 13); - rpr = get_bits(gb, r->rpr); - if(rpr){ - w = r->s.avctx->extradata[6 + rpr*2] << 2; - h = r->s.avctx->extradata[7 + rpr*2] << 2; - } - si->width = w; - si->height = h; - mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); - mb_bits = ff_rv34_get_start_offset(gb, mb_size); - si->start = get_bits(gb, mb_bits); - skip_bits1(gb); - return 0; -} - -/** - * Decode 4x4 intra types array. - */ -static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) -{ - int i, j, k; - - for(i = 0; i < 4; i++, dst += r->intra_types_stride - 4){ - for(j = 0; j < 4; j+= 2){ - int code = svq3_get_ue_golomb(gb) << 1; - if(code >= 81*2){ - av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); - return -1; - } - for(k = 0; k < 2; k++){ - int A = dst[-r->intra_types_stride] + 1; - int B = dst[-1] + 1; - *dst++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + k]]; - if(dst[-1] == 9){ - av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction mode\n"); - return -1; - } - } - } - } - return 0; -} - -/** - * Decode macroblock information. - */ -static int rv30_decode_mb_info(RV34DecContext *r) -{ - static const int rv30_p_types[6] = { RV34_MB_SKIP, RV34_MB_P_16x16, RV34_MB_P_8x8, -1, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; - static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_DIRECT, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int code = svq3_get_ue_golomb(gb); - - if(code > 11){ - av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); - return -1; - } - if(code > 5){ - av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n"); - code -= 6; - } - if(s->pict_type != FF_B_TYPE) - return rv30_p_types[code]; - else - return rv30_b_types[code]; -} - -static inline void rv30_weak_loop_filter(uint8_t *src, const int step, - const int stride, const int lim) -{ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int i, diff; - - for(i = 0; i < 4; i++){ - diff = ((src[-2*step] - src[1*step]) - (src[-1*step] - src[0*step])*4) >> 3; - diff = av_clip(diff, -lim, lim); - src[-1*step] = cm[src[-1*step] + diff]; - src[ 0*step] = cm[src[ 0*step] - diff]; - src += stride; - } -} - -static void rv30_loop_filter(RV34DecContext *r, int row) -{ - MpegEncContext *s = &r->s; - int mb_pos, mb_x; - int i, j, k; - uint8_t *Y, *C; - int loc_lim, cur_lim, left_lim = 0, top_lim = 0; - - mb_pos = row * s->mb_stride; - for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - int mbtype = s->current_picture_ptr->mb_type[mb_pos]; - if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) - r->deblock_coefs[mb_pos] = 0xFFFF; - if(IS_INTRA(mbtype)) - r->cbp_chroma[mb_pos] = 0xFF; - } - - /* all vertical edges are filtered first - * and horizontal edges are filtered on the next iteration - */ - mb_pos = row * s->mb_stride; - for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; - if(mb_x) - left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]]; - for(j = 0; j < 16; j += 4){ - Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x; - for(i = !mb_x; i < 4; i++, Y += 4){ - int ij = i + j; - loc_lim = 0; - if(r->deblock_coefs[mb_pos] & (1 << ij)) - loc_lim = cur_lim; - else if(!i && r->deblock_coefs[mb_pos - 1] & (1 << (ij + 3))) - loc_lim = left_lim; - else if( i && r->deblock_coefs[mb_pos] & (1 << (ij - 1))) - loc_lim = cur_lim; - if(loc_lim) - rv30_weak_loop_filter(Y, 1, s->linesize, loc_lim); - } - } - for(k = 0; k < 2; k++){ - int cur_cbp, left_cbp = 0; - cur_cbp = (r->cbp_chroma[mb_pos] >> (k*4)) & 0xF; - if(mb_x) - left_cbp = (r->cbp_chroma[mb_pos - 1] >> (k*4)) & 0xF; - for(j = 0; j < 8; j += 4){ - C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize + 4 * !mb_x; - for(i = !mb_x; i < 2; i++, C += 4){ - int ij = i + (j >> 1); - loc_lim = 0; - if(cur_cbp && (1 << ij)) - loc_lim = cur_lim; - else if(!i && left_cbp & (1 << (ij + 1))) - loc_lim = left_lim; - else if( i && cur_cbp & (1 << (ij - 1))) - loc_lim = cur_lim; - if(loc_lim) - rv30_weak_loop_filter(C, 1, s->uvlinesize, loc_lim); - } - } - } - } - mb_pos = row * s->mb_stride; - for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]]; - if(row) - top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]]; - for(j = 4*!row; j < 16; j += 4){ - Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize; - for(i = 0; i < 4; i++, Y += 4){ - int ij = i + j; - loc_lim = 0; - if(r->deblock_coefs[mb_pos] & (1 << ij)) - loc_lim = cur_lim; - else if(!j && r->deblock_coefs[mb_pos - s->mb_stride] & (1 << (ij + 12))) - loc_lim = top_lim; - else if( j && r->deblock_coefs[mb_pos] & (1 << (ij - 4))) - loc_lim = cur_lim; - if(loc_lim) - rv30_weak_loop_filter(Y, s->linesize, 1, loc_lim); - } - } - for(k = 0; k < 2; k++){ - int cur_cbp, top_cbp = 0; - cur_cbp = (r->cbp_chroma[mb_pos] >> (k*4)) & 0xF; - if(row) - top_cbp = (r->cbp_chroma[mb_pos - s->mb_stride] >> (k*4)) & 0xF; - for(j = 4*!row; j < 8; j += 4){ - C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j) * s->uvlinesize; - for(i = 0; i < 2; i++, C += 4){ - int ij = i + (j >> 1); - loc_lim = 0; - if(r->cbp_chroma[mb_pos] && (1 << ij)) - loc_lim = cur_lim; - else if(!j && top_cbp & (1 << (ij + 2))) - loc_lim = top_lim; - else if( j && cur_cbp & (1 << (ij - 2))) - loc_lim = cur_lim; - if(loc_lim) - rv30_weak_loop_filter(C, s->uvlinesize, 1, loc_lim); - } - } - } - } -} - -/** - * Initialize decoder. - */ -static av_cold int rv30_decode_init(AVCodecContext *avctx) -{ - RV34DecContext *r = avctx->priv_data; - - r->rv30 = 1; - ff_rv34_decode_init(avctx); - if(avctx->extradata_size < 2){ - av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); - return -1; - } - r->rpr = (avctx->extradata[1] & 7) >> 1; - r->rpr = FFMIN(r->rpr + 1, 3); - if(avctx->extradata_size - 8 < (r->rpr - 1) * 2){ - av_log(avctx, AV_LOG_ERROR, "Insufficient extradata - need at least %d bytes, got %d\n", - 6 + r->rpr * 2, avctx->extradata_size); - } - r->parse_slice_header = rv30_parse_slice_header; - r->decode_intra_types = rv30_decode_intra_types; - r->decode_mb_info = rv30_decode_mb_info; - r->loop_filter = rv30_loop_filter; - r->luma_dc_quant_i = rv30_luma_dc_quant; - r->luma_dc_quant_p = rv30_luma_dc_quant; - return 0; -} - -AVCodec rv30_decoder = { - "rv30", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RV30, - sizeof(RV34DecContext), - rv30_decode_init, - NULL, - ff_rv34_decode_end, - ff_rv34_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .flush = ff_mpeg_flush, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 3.0"), - .pix_fmts= ff_pixfmt_list_420, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rv30data.h b/tizen/distrib/ffmpeg/libavcodec/rv30data.h deleted file mode 100644 index 9cc48a6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv30data.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * RealVideo 3 decoder - * copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * miscellaneous RV30 tables - */ - -#ifndef AVCODEC_RV30DATA_H -#define AVCODEC_RV30DATA_H - -#include - -/** DC quantizer mapping for RV30 */ -static const uint8_t rv30_luma_dc_quant[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 22, 22, 23, 23, 23, 24, 24, 25, 25 -}; - -/** - * This table is used for storing the differences - * between the predicted and the real intra type. - */ -static const uint8_t rv30_itype_code[9*9*2] = { - 0, 0, 0, 1, 1, 0, 1, 1, 0, 2, 2, 0, 0, 3, 3, 0, 1, 2, - 2, 1, 0, 4, 4, 0, 3, 1, 1, 3, 0, 5, 5, 0, 2, 2, 1, 4, - 4, 1, 0, 6, 3, 2, 1, 5, 2, 3, 5, 1, 6, 0, 0, 7, 4, 2, - 2, 4, 3, 3, 6, 1, 1, 6, 7, 0, 0, 8, 5, 2, 4, 3, 2, 5, - 3, 4, 1, 7, 4, 4, 7, 1, 8, 0, 6, 2, 3, 5, 5, 3, 2, 6, - 1, 8, 2, 7, 7, 2, 8, 1, 5, 4, 4, 5, 3, 6, 6, 3, 8, 2, - 4, 6, 5, 5, 6, 4, 2, 8, 7, 3, 3, 7, 6, 5, 5, 6, 7, 4, - 4, 7, 8, 3, 3, 8, 7, 5, 8, 4, 5, 7, 4, 8, 6, 6, 7, 6, - 5, 8, 8, 5, 6, 7, 8, 6, 7, 7, 6, 8, 8, 7, 7, 8, 8, 8, -}; - -/** - * This table is used for retrieving the current intra type - * based on its neighbors and adjustment provided by - * code read and decoded before. - * - * This is really a three-dimensional matrix with dimensions - * [-1..9][-1..9][0..9]. The first and second coordinates are - * detemined by the top and left neighbors (-1 if unavailable). - */ -static const uint8_t rv30_itype_from_context[900] = { - 0, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 2, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, - - 0, 1, 9, 9, 9, 9, 9, 9, 9, - 0, 2, 1, 6, 4, 8, 5, 7, 3, - 1, 0, 2, 6, 5, 4, 3, 8, 7, - 2, 8, 0, 1, 7, 4, 3, 6, 5, - 2, 0, 1, 3, 8, 5, 4, 7, 6, - 2, 0, 1, 4, 6, 7, 8, 3, 5, - 0, 1, 5, 2, 6, 3, 8, 4, 7, - 0, 1, 6, 2, 4, 7, 5, 8, 3, - 2, 7, 0, 1, 4, 8, 6, 3, 5, - 2, 8, 0, 1, 7, 3, 4, 5, 6, - - 1, 0, 9, 9, 9, 9, 9, 9, 9, - 1, 2, 5, 6, 3, 0, 4, 8, 7, - 1, 6, 2, 5, 3, 0, 4, 8, 7, - 2, 1, 7, 6, 8, 3, 5, 0, 4, - 1, 2, 5, 3, 6, 8, 4, 7, 0, - 1, 6, 2, 0, 4, 5, 8, 7, 3, - 1, 5, 2, 6, 3, 8, 4, 0, 7, - 1, 6, 0, 2, 4, 5, 7, 3, 8, - 2, 1, 7, 6, 0, 8, 5, 4, 3, - 1, 2, 7, 8, 3, 4, 5, 6, 0, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 2, 1, 8, 7, 6, 5, 4, 3, - 1, 2, 0, 6, 5, 7, 4, 8, 3, - 2, 8, 7, 1, 0, 6, 4, 3, 5, - 2, 0, 8, 1, 3, 7, 5, 4, 6, - 2, 0, 4, 1, 7, 8, 6, 3, 5, - 2, 0, 1, 5, 8, 4, 6, 7, 3, - 2, 0, 6, 1, 4, 7, 8, 5, 3, - 2, 7, 8, 1, 0, 5, 4, 6, 3, - 2, 8, 7, 1, 0, 4, 3, 6, 5, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 2, 1, 3, 5, 8, 6, 4, 7, - 1, 0, 2, 5, 3, 6, 4, 8, 7, - 2, 8, 1, 0, 3, 5, 7, 6, 4, - 3, 2, 5, 8, 1, 4, 6, 7, 0, - 4, 2, 0, 6, 1, 5, 8, 3, 7, - 5, 3, 1, 2, 8, 6, 4, 0, 7, - 1, 6, 0, 2, 4, 5, 8, 3, 7, - 2, 7, 0, 1, 5, 4, 8, 6, 3, - 2, 8, 3, 5, 1, 0, 7, 6, 4, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 0, 6, 1, 4, 7, 5, 8, 3, - 1, 6, 2, 0, 4, 5, 3, 7, 8, - 2, 8, 7, 6, 4, 0, 1, 5, 3, - 4, 2, 1, 0, 6, 8, 3, 5, 7, - 4, 2, 6, 0, 1, 5, 7, 8, 3, - 1, 2, 5, 0, 6, 3, 4, 7, 8, - 6, 4, 0, 1, 2, 7, 5, 3, 8, - 2, 7, 4, 6, 0, 1, 8, 5, 3, - 2, 8, 7, 4, 6, 1, 3, 5, 0, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 5, 1, 2, 3, 6, 8, 0, 4, 7, - 1, 5, 6, 3, 2, 0, 4, 8, 7, - 2, 1, 5, 3, 6, 8, 7, 4, 0, - 5, 3, 1, 2, 6, 8, 4, 7, 0, - 1, 6, 2, 4, 5, 8, 0, 3, 7, - 5, 1, 3, 6, 2, 0, 8, 4, 7, - 1, 6, 5, 2, 0, 4, 3, 7, 8, - 2, 7, 1, 6, 5, 0, 8, 3, 4, - 2, 5, 1, 3, 6, 8, 4, 0, 7, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 1, 6, 2, 0, 5, 4, 3, 7, 8, - 1, 6, 5, 4, 2, 3, 0, 7, 8, - 2, 1, 6, 7, 4, 8, 5, 3, 0, - 2, 1, 6, 5, 8, 4, 3, 0, 7, - 6, 4, 1, 2, 0, 5, 7, 8, 3, - 1, 6, 5, 2, 3, 0, 4, 8, 7, - 6, 1, 4, 0, 2, 7, 5, 3, 8, - 2, 7, 4, 6, 1, 5, 0, 8, 3, - 2, 1, 6, 8, 4, 7, 3, 5, 0, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 0, 4, 7, 6, 1, 8, 5, 3, - 6, 1, 2, 0, 4, 7, 5, 8, 3, - 2, 7, 8, 0, 1, 6, 4, 3, 5, - 2, 4, 0, 8, 3, 1, 7, 6, 5, - 4, 2, 7, 0, 6, 1, 8, 5, 3, - 2, 1, 0, 8, 5, 6, 7, 4, 3, - 2, 6, 4, 1, 7, 0, 5, 8, 3, - 2, 7, 4, 0, 8, 6, 1, 5, 3, - 2, 8, 7, 4, 1, 0, 3, 6, 5, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 0, 8, 1, 3, 4, 6, 5, 7, - 1, 2, 0, 6, 8, 5, 7, 3, 4, - 2, 8, 7, 1, 0, 3, 6, 5, 4, - 8, 3, 2, 5, 1, 0, 4, 7, 6, - 2, 0, 4, 8, 5, 1, 7, 6, 3, - 2, 1, 0, 8, 5, 3, 6, 4, 7, - 2, 1, 6, 0, 8, 4, 5, 7, 3, - 2, 7, 8, 4, 0, 6, 1, 5, 3, - 2, 8, 3, 0, 7, 4, 1, 6, 5, -}; - -/** - * Loop filter limits are taken from this table. - */ -static const uint8_t rv30_loop_filt_lim[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5 -}; -#endif /* AVCODEC_RV30DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rv30dsp.c b/tizen/distrib/ffmpeg/libavcodec/rv30dsp.c deleted file mode 100644 index 4700e78..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv30dsp.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * RV30 decoder motion compensation functions - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV30 decoder motion compensation functions - */ - -#include "avcodec.h" -#include "dsputil.h" - -#define RV30_LOWPASS(OPNAME, OP) \ -static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ - const int h=8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i;\ - for(i=0; i>4);\ - OP(dst[1], (-(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + 8)>>4);\ - OP(dst[2], (-(src[ 1]+src[4]) + src[2]*C1 + src[3]*C2 + 8)>>4);\ - OP(dst[3], (-(src[ 2]+src[5]) + src[3]*C1 + src[4]*C2 + 8)>>4);\ - OP(dst[4], (-(src[ 3]+src[6]) + src[4]*C1 + src[5]*C2 + 8)>>4);\ - OP(dst[5], (-(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + 8)>>4);\ - OP(dst[6], (-(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + 8)>>4);\ - OP(dst[7], (-(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + 8)>>4);\ - dst+=dstStride;\ - src+=srcStride;\ - }\ -}\ -\ -static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ - const int w=8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i;\ - for(i=0; i>4);\ - OP(dst[1*dstStride], (-(src0+src3) + src1*C1 + src2*C2 + 8)>>4);\ - OP(dst[2*dstStride], (-(src1+src4) + src2*C1 + src3*C2 + 8)>>4);\ - OP(dst[3*dstStride], (-(src2+src5) + src3*C1 + src4*C2 + 8)>>4);\ - OP(dst[4*dstStride], (-(src3+src6) + src4*C1 + src5*C2 + 8)>>4);\ - OP(dst[5*dstStride], (-(src4+src7) + src5*C1 + src6*C2 + 8)>>4);\ - OP(dst[6*dstStride], (-(src5+src8) + src6*C1 + src7*C2 + 8)>>4);\ - OP(dst[7*dstStride], (-(src6+src9) + src7*C1 + src8*C2 + 8)>>4);\ - dst++;\ - src++;\ - }\ -}\ -\ -static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int w = 8;\ - const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i, j;\ - for(j = 0; j < h; j++){\ - for(i = 0; i < w; i++){\ - OP(dst[i], (\ - src[srcStride*-1+i-1] -12*src[srcStride*-1+i] -6*src[srcStride*-1+i+1] +src[srcStride*-1+i+2]+\ - -12*src[srcStride* 0+i-1] +144*src[srcStride* 0+i] +72*src[srcStride* 0+i+1] -12*src[srcStride* 0+i+2] +\ - -6*src[srcStride* 1+i-1] +72*src[srcStride* 1+i] +36*src[srcStride* 1+i+1] -6*src[srcStride* 1+i+2] +\ - src[srcStride* 2+i-1] -12*src[srcStride* 2+i] -6*src[srcStride* 2+i+1] +src[srcStride* 2+i+2] +\ - 128)>>8);\ - }\ - src += srcStride;\ - dst += dstStride;\ - }\ -}\ -\ -static void OPNAME ## rv30_tpel8_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int w = 8;\ - const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i, j;\ - for(j = 0; j < h; j++){\ - for(i = 0; i < w; i++){\ - OP(dst[i], (\ - src[srcStride*-1+i-1] -12*src[srcStride*-1+i+1] -6*src[srcStride*-1+i] +src[srcStride*-1+i+2]+\ - -12*src[srcStride* 0+i-1] +144*src[srcStride* 0+i+1] +72*src[srcStride* 0+i] -12*src[srcStride* 0+i+2]+\ - -6*src[srcStride* 1+i-1] +72*src[srcStride* 1+i+1] +36*src[srcStride* 1+i] -6*src[srcStride* 1+i+2]+\ - src[srcStride* 2+i-1] -12*src[srcStride* 2+i+1] -6*src[srcStride* 2+i] +src[srcStride* 2+i+2]+\ - 128)>>8);\ - }\ - src += srcStride;\ - dst += dstStride;\ - }\ -}\ -\ -static void OPNAME ## rv30_tpel8_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int w = 8;\ - const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i, j;\ - for(j = 0; j < h; j++){\ - for(i = 0; i < w; i++){\ - OP(dst[i], (\ - src[srcStride*-1+i-1] -12*src[srcStride*-1+i] -6*src[srcStride*-1+i+1] +src[srcStride*-1+i+2]+\ - -6*src[srcStride* 0+i-1] +72*src[srcStride* 0+i] +36*src[srcStride* 0+i+1] -6*src[srcStride* 0+i+2]+\ - -12*src[srcStride* 1+i-1] +144*src[srcStride* 1+i] +72*src[srcStride* 1+i+1] -12*src[srcStride* 1+i+2]+\ - src[srcStride* 2+i-1] -12*src[srcStride* 2+i] -6*src[srcStride* 2+i+1] +src[srcStride* 2+i+2]+\ - 128)>>8);\ - }\ - src += srcStride;\ - dst += dstStride;\ - }\ -}\ -\ -static void OPNAME ## rv30_tpel8_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int w = 8;\ - const int h = 8;\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i, j;\ - for(j = 0; j < h; j++){\ - for(i = 0; i < w; i++){\ - OP(dst[i], (\ - 36*src[i+srcStride*0] +54*src[i+1+srcStride*0] +6*src[i+2+srcStride*0]+\ - 54*src[i+srcStride*1] +81*src[i+1+srcStride*1] +9*src[i+2+srcStride*1]+\ - 6*src[i+srcStride*2] + 9*src[i+1+srcStride*2] + src[i+2+srcStride*2]+\ - 128)>>8);\ - }\ - src += srcStride;\ - dst += dstStride;\ - }\ -}\ -\ -static void OPNAME ## rv30_tpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ - OPNAME ## rv30_tpel8_v_lowpass(dst , src , dstStride, srcStride, C1, C2);\ - OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv30_tpel8_v_lowpass(dst , src , dstStride, srcStride, C1, C2);\ - OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ -}\ -\ -static void OPNAME ## rv30_tpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ - OPNAME ## rv30_tpel8_h_lowpass(dst , src , dstStride, srcStride, C1, C2);\ - OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv30_tpel8_h_lowpass(dst , src , dstStride, srcStride, C1, C2);\ - OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ -}\ -\ -static void OPNAME ## rv30_tpel16_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## rv30_tpel8_hv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv30_tpel8_hv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\ -}\ -\ -static void OPNAME ## rv30_tpel16_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## rv30_tpel8_hhv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hhv_lowpass(dst+8, src+8, dstStride, srcStride);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv30_tpel8_hhv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hhv_lowpass(dst+8, src+8, dstStride, srcStride);\ -}\ -\ -static void OPNAME ## rv30_tpel16_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## rv30_tpel8_hvv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hvv_lowpass(dst+8, src+8, dstStride, srcStride);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv30_tpel8_hvv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hvv_lowpass(dst+8, src+8, dstStride, srcStride);\ -}\ -\ -static void OPNAME ## rv30_tpel16_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## rv30_tpel8_hhvv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hhvv_lowpass(dst+8, src+8, dstStride, srcStride);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv30_tpel8_hhvv_lowpass(dst , src , dstStride, srcStride);\ - OPNAME ## rv30_tpel8_hhvv_lowpass(dst+8, src+8, dstStride, srcStride);\ -}\ -\ - -#define RV30_MC(OPNAME, SIZE) \ -static void OPNAME ## rv30_tpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 12, 6);\ -}\ -\ -static void OPNAME ## rv30_tpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 6, 12);\ -}\ -\ -static void OPNAME ## rv30_tpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 12, 6);\ -}\ -\ -static void OPNAME ## rv30_tpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 6, 12);\ -}\ -\ -static void OPNAME ## rv30_tpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _hv_lowpass(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## rv30_tpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _hvv_lowpass(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## rv30_tpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _hhv_lowpass(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## rv30_tpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv30_tpel ## SIZE ## _hhvv_lowpass(dst, src, stride, stride);\ -}\ -\ - -#define op_avg(a, b) a = (((a)+cm[b]+1)>>1) -#define op_put(a, b) a = cm[b] - -RV30_LOWPASS(put_ , op_put) -RV30_LOWPASS(avg_ , op_avg) -RV30_MC(put_, 8) -RV30_MC(put_, 16) -RV30_MC(avg_, 8) -RV30_MC(avg_, 16) - -av_cold void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx) { - c->put_rv30_tpel_pixels_tab[0][ 0] = c->put_h264_qpel_pixels_tab[0][0]; - c->put_rv30_tpel_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c; - c->put_rv30_tpel_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c; - c->put_rv30_tpel_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c; - c->put_rv30_tpel_pixels_tab[0][ 5] = put_rv30_tpel16_mc11_c; - c->put_rv30_tpel_pixels_tab[0][ 6] = put_rv30_tpel16_mc21_c; - c->put_rv30_tpel_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c; - c->put_rv30_tpel_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c; - c->put_rv30_tpel_pixels_tab[0][10] = put_rv30_tpel16_mc22_c; - c->avg_rv30_tpel_pixels_tab[0][ 0] = c->avg_h264_qpel_pixels_tab[0][0]; - c->avg_rv30_tpel_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c; - c->avg_rv30_tpel_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c; - c->avg_rv30_tpel_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c; - c->avg_rv30_tpel_pixels_tab[0][ 5] = avg_rv30_tpel16_mc11_c; - c->avg_rv30_tpel_pixels_tab[0][ 6] = avg_rv30_tpel16_mc21_c; - c->avg_rv30_tpel_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c; - c->avg_rv30_tpel_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c; - c->avg_rv30_tpel_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c; - c->put_rv30_tpel_pixels_tab[1][ 0] = c->put_h264_qpel_pixels_tab[1][0]; - c->put_rv30_tpel_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c; - c->put_rv30_tpel_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c; - c->put_rv30_tpel_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c; - c->put_rv30_tpel_pixels_tab[1][ 5] = put_rv30_tpel8_mc11_c; - c->put_rv30_tpel_pixels_tab[1][ 6] = put_rv30_tpel8_mc21_c; - c->put_rv30_tpel_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c; - c->put_rv30_tpel_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c; - c->put_rv30_tpel_pixels_tab[1][10] = put_rv30_tpel8_mc22_c; - c->avg_rv30_tpel_pixels_tab[1][ 0] = c->avg_h264_qpel_pixels_tab[1][0]; - c->avg_rv30_tpel_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c; - c->avg_rv30_tpel_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c; - c->avg_rv30_tpel_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c; - c->avg_rv30_tpel_pixels_tab[1][ 5] = avg_rv30_tpel8_mc11_c; - c->avg_rv30_tpel_pixels_tab[1][ 6] = avg_rv30_tpel8_mc21_c; - c->avg_rv30_tpel_pixels_tab[1][ 8] = avg_rv30_tpel8_mc02_c; - c->avg_rv30_tpel_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c; - c->avg_rv30_tpel_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/rv34.c b/tizen/distrib/ffmpeg/libavcodec/rv34.c deleted file mode 100644 index 88652f9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv34.c +++ /dev/null @@ -1,1531 +0,0 @@ -/* - * RV30/40 decoder common data - * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV30/40 decoder common data - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "golomb.h" -#include "mathops.h" -#include "rectangle.h" - -#include "rv34vlc.h" -#include "rv34data.h" -#include "rv34.h" - -//#define DEBUG - -static inline void ZERO8x2(void* dst, int stride) -{ - fill_rectangle(dst, 1, 2, stride, 0, 4); - fill_rectangle(((uint8_t*)(dst))+4, 1, 2, stride, 0, 4); -} - -/** translation of RV30/40 macroblock types to lavc ones */ -static const int rv34_mb_type_to_lavc[12] = { - MB_TYPE_INTRA, - MB_TYPE_INTRA16x16 | MB_TYPE_SEPARATE_DC, - MB_TYPE_16x16 | MB_TYPE_L0, - MB_TYPE_8x8 | MB_TYPE_L0, - MB_TYPE_16x16 | MB_TYPE_L0, - MB_TYPE_16x16 | MB_TYPE_L1, - MB_TYPE_SKIP, - MB_TYPE_DIRECT2 | MB_TYPE_16x16, - MB_TYPE_16x8 | MB_TYPE_L0, - MB_TYPE_8x16 | MB_TYPE_L0, - MB_TYPE_16x16 | MB_TYPE_L0L1, - MB_TYPE_16x16 | MB_TYPE_L0 | MB_TYPE_SEPARATE_DC -}; - - -static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES]; - -/** - * @defgroup vlc RV30/40 VLC generating functions - * @{ - */ - -static const int table_offs[] = { - 0, 1818, 3622, 4144, 4698, 5234, 5804, 5868, 5900, 5932, - 5996, 6252, 6316, 6348, 6380, 7674, 8944, 10274, 11668, 12250, - 14060, 15846, 16372, 16962, 17512, 18148, 18180, 18212, 18244, 18308, - 18564, 18628, 18660, 18692, 20036, 21314, 22648, 23968, 24614, 26384, - 28190, 28736, 29366, 29938, 30608, 30640, 30672, 30704, 30768, 31024, - 31088, 31120, 31184, 32570, 33898, 35236, 36644, 37286, 39020, 40802, - 41368, 42052, 42692, 43348, 43380, 43412, 43444, 43476, 43604, 43668, - 43700, 43732, 45100, 46430, 47778, 49160, 49802, 51550, 53340, 53972, - 54648, 55348, 55994, 56122, 56154, 56186, 56218, 56346, 56410, 56442, - 56474, 57878, 59290, 60636, 62036, 62682, 64460, 64524, 64588, 64716, - 64844, 66076, 67466, 67978, 68542, 69064, 69648, 70296, 72010, 72074, - 72138, 72202, 72330, 73572, 74936, 75454, 76030, 76566, 77176, 77822, - 79582, 79646, 79678, 79742, 79870, 81180, 82536, 83064, 83672, 84242, - 84934, 85576, 87384, 87448, 87480, 87544, 87672, 88982, 90340, 90902, - 91598, 92182, 92846, 93488, 95246, 95278, 95310, 95374, 95502, 96878, - 98266, 98848, 99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416, - 103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398, - 111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592 -}; - -static VLC_TYPE table_data[117592][2]; - -/** - * Generate VLC from codeword lengths. - * @param bits codeword lengths (zeroes are accepted) - * @param size length of input data - * @param vlc output VLC - * @param insyms symbols for input codes (NULL for default ones) - * @param num VLC table number (for static initialization) - */ -static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms, - const int num) -{ - int i; - int counts[17] = {0}, codes[17]; - uint16_t cw[size], syms[size]; - uint8_t bits2[size]; - int maxbits = 0, realsize = 0; - - for(i = 0; i < size; i++){ - if(bits[i]){ - bits2[realsize] = bits[i]; - syms[realsize] = insyms ? insyms[i] : i; - realsize++; - maxbits = FFMAX(maxbits, bits[i]); - counts[bits[i]]++; - } - } - - codes[0] = 0; - for(i = 0; i < 16; i++) - codes[i+1] = (codes[i] + counts[i]) << 1; - for(i = 0; i < realsize; i++) - cw[i] = codes[bits2[i]]++; - - vlc->table = &table_data[table_offs[num]]; - vlc->table_allocated = table_offs[num + 1] - table_offs[num]; - init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize, - bits2, 1, 1, - cw, 2, 2, - syms, 2, 2, INIT_VLC_USE_NEW_STATIC); -} - -/** - * Initialize all tables. - */ -static av_cold void rv34_init_tables(void) -{ - int i, j, k; - - for(i = 0; i < NUM_INTRA_TABLES; i++){ - for(j = 0; j < 2; j++){ - rv34_gen_vlc(rv34_table_intra_cbppat [i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j], NULL, 19*i + 0 + j); - rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL, 19*i + 2 + j); - rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j], NULL, 19*i + 4 + j); - for(k = 0; k < 4; k++){ - rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k], rv34_cbp_code, 19*i + 6 + j*4 + k); - } - } - for(j = 0; j < 4; j++){ - rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL, 19*i + 14 + j); - } - rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18); - } - - for(i = 0; i < NUM_INTER_TABLES; i++){ - rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL, i*12 + 95); - for(j = 0; j < 4; j++){ - rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code, i*12 + 96 + j); - } - for(j = 0; j < 2; j++){ - rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j], NULL, i*12 + 100 + j); - rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL, i*12 + 102 + j); - rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j], NULL, i*12 + 104 + j); - } - rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106); - } -} - -/** @} */ // vlc group - - -/** - * @defgroup transform RV30/40 inverse transform functions - * @{ - */ - -static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block) -{ - int i; - - for(i=0; i<4; i++){ - const int z0= 13*(block[i+8*0] + block[i+8*2]); - const int z1= 13*(block[i+8*0] - block[i+8*2]); - const int z2= 7* block[i+8*1] - 17*block[i+8*3]; - const int z3= 17* block[i+8*1] + 7*block[i+8*3]; - - temp[4*i+0]= z0+z3; - temp[4*i+1]= z1+z2; - temp[4*i+2]= z1-z2; - temp[4*i+3]= z0-z3; - } -} - -/** - * Real Video 3.0/4.0 inverse transform - * Code is almost the same as in SVQ3, only scaling is different. - */ -static void rv34_inv_transform(DCTELEM *block){ - int temp[16]; - int i; - - rv34_row_transform(temp, block); - - for(i=0; i<4; i++){ - const int z0= 13*(temp[4*0+i] + temp[4*2+i]) + 0x200; - const int z1= 13*(temp[4*0+i] - temp[4*2+i]) + 0x200; - const int z2= 7* temp[4*1+i] - 17*temp[4*3+i]; - const int z3= 17* temp[4*1+i] + 7*temp[4*3+i]; - - block[i*8+0]= (z0 + z3)>>10; - block[i*8+1]= (z1 + z2)>>10; - block[i*8+2]= (z1 - z2)>>10; - block[i*8+3]= (z0 - z3)>>10; - } - -} - -/** - * RealVideo 3.0/4.0 inverse transform for DC block - * - * Code is almost the same as rv34_inv_transform() - * but final coefficients are multiplied by 1.5 and have no rounding. - */ -static void rv34_inv_transform_noround(DCTELEM *block){ - int temp[16]; - int i; - - rv34_row_transform(temp, block); - - for(i=0; i<4; i++){ - const int z0= 13*(temp[4*0+i] + temp[4*2+i]); - const int z1= 13*(temp[4*0+i] - temp[4*2+i]); - const int z2= 7* temp[4*1+i] - 17*temp[4*3+i]; - const int z3= 17* temp[4*1+i] + 7*temp[4*3+i]; - - block[i*8+0]= ((z0 + z3)*3)>>11; - block[i*8+1]= ((z1 + z2)*3)>>11; - block[i*8+2]= ((z1 - z2)*3)>>11; - block[i*8+3]= ((z0 - z3)*3)>>11; - } - -} - -/** @} */ // transform - - -/** - * @defgroup block RV30/40 4x4 block decoding functions - * @{ - */ - -/** - * Decode coded block pattern. - */ -static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table) -{ - int pattern, code, cbp=0; - int ones; - static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000}; - static const int shifts[4] = { 0, 2, 8, 10 }; - const int *curshift = shifts; - int i, t, mask; - - code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2); - pattern = code & 0xF; - code >>= 4; - - ones = rv34_count_ones[pattern]; - - for(mask = 8; mask; mask >>= 1, curshift++){ - if(pattern & mask) - cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0]; - } - - for(i = 0; i < 4; i++){ - t = modulo_three_table[code][i]; - if(t == 1) - cbp |= cbp_masks[get_bits1(gb)] << i; - if(t == 2) - cbp |= cbp_masks[2] << i; - } - return cbp; -} - -/** - * Get one coefficient value from the bistream and store it. - */ -static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc) -{ - if(coef){ - if(coef == esc){ - coef = get_vlc2(gb, vlc->table, 9, 2); - if(coef > 23){ - coef -= 23; - coef = 22 + ((1 << coef) | get_bits(gb, coef)); - } - coef += esc; - } - if(get_bits1(gb)) - coef = -coef; - *dst = coef; - } -} - -/** - * Decode 2x2 subblock of coefficients. - */ -static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc) -{ - int coeffs[4]; - - coeffs[0] = modulo_three_table[code][0]; - coeffs[1] = modulo_three_table[code][1]; - coeffs[2] = modulo_three_table[code][2]; - coeffs[3] = modulo_three_table[code][3]; - decode_coeff(dst , coeffs[0], 3, gb, vlc); - if(is_block2){ - decode_coeff(dst+8, coeffs[1], 2, gb, vlc); - decode_coeff(dst+1, coeffs[2], 2, gb, vlc); - }else{ - decode_coeff(dst+1, coeffs[1], 2, gb, vlc); - decode_coeff(dst+8, coeffs[2], 2, gb, vlc); - } - decode_coeff(dst+9, coeffs[3], 2, gb, vlc); -} - -/** - * Decode coefficients for 4x4 block. - * - * This is done by filling 2x2 subblocks with decoded coefficients - * in this order (the same for subblocks and subblock coefficients): - * o--o - * / - * / - * o--o - */ - -static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc) -{ - int code, pattern; - - code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2); - - pattern = code & 0x7; - - code >>= 3; - decode_subblock(dst, code, 0, gb, &rvlc->coefficient); - - if(pattern & 4){ - code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); - decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient); - } - if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block - code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); - decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient); - } - if(pattern & 1){ - code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2); - decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient); - } - -} - -/** - * Dequantize ordinary 4x4 block. - * @todo optimize - */ -static inline void rv34_dequant4x4(DCTELEM *block, int Qdc, int Q) -{ - int i, j; - - block[0] = (block[0] * Qdc + 8) >> 4; - for(i = 0; i < 4; i++) - for(j = !i; j < 4; j++) - block[j + i*8] = (block[j + i*8] * Q + 8) >> 4; -} - -/** - * Dequantize 4x4 block of DC values for 16x16 macroblock. - * @todo optimize - */ -static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q) -{ - int i; - - for(i = 0; i < 3; i++) - block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4; - for(; i < 16; i++) - block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4; -} -/** @} */ //block functions - - -/** - * @defgroup bitstream RV30/40 bitstream parsing - * @{ - */ - -/** - * Decode starting slice position. - * @todo Maybe replace with ff_h263_decode_mba() ? - */ -int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size) -{ - int i; - for(i = 0; i < 5; i++) - if(rv34_mb_max_sizes[i] >= mb_size - 1) - break; - return rv34_mb_bits_sizes[i]; -} - -/** - * Select VLC set for decoding from current quantizer, modifier and frame type. - */ -static inline RV34VLC* choose_vlc_set(int quant, int mod, int type) -{ - if(mod == 2 && quant < 19) quant += 10; - else if(mod && quant < 26) quant += 5; - return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][av_clip(quant, 0, 30)]] - : &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]]; -} - -/** - * Decode quantizer difference and return modified quantizer. - */ -static inline int rv34_decode_dquant(GetBitContext *gb, int quant) -{ - if(get_bits1(gb)) - return rv34_dquant_tab[get_bits1(gb)][quant]; - else - return get_bits(gb, 5); -} - -/** @} */ //bitstream functions - -/** - * @defgroup mv motion vector related code (prediction, reconstruction, motion compensation) - * @{ - */ - -/** macroblock partition width in 8x8 blocks */ -static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 }; - -/** macroblock partition height in 8x8 blocks */ -static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 }; - -/** availability index for subblocks */ -static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 }; - -/** - * motion vector prediction - * - * Motion prediction performed for the block by using median prediction of - * motion vectors from the left, top and right top blocks but in corner cases - * some other vectors may be used instead. - */ -static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no) -{ - MpegEncContext *s = &r->s; - int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; - int A[2] = {0}, B[2], C[2]; - int i, j; - int mx, my; - int avail_index = avail_indexes[subblock_no]; - int c_off = part_sizes_w[block_type]; - - mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride; - if(subblock_no == 3) - c_off = -1; - - if(r->avail_cache[avail_index - 1]){ - A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0]; - A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1]; - } - if(r->avail_cache[avail_index - 4]){ - B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0]; - B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1]; - }else{ - B[0] = A[0]; - B[1] = A[1]; - } - if(!r->avail_cache[avail_index - 4 + c_off]){ - if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1] || r->rv30)){ - C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0]; - C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1]; - }else{ - C[0] = A[0]; - C[1] = A[1]; - } - }else{ - C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0]; - C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1]; - } - mx = mid_pred(A[0], B[0], C[0]); - my = mid_pred(A[1], B[1], C[1]); - mx += r->dmv[dmv_no][0]; - my += r->dmv[dmv_no][1]; - for(j = 0; j < part_sizes_h[block_type]; j++){ - for(i = 0; i < part_sizes_w[block_type]; i++){ - s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx; - s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my; - } - } -} - -#define GET_PTS_DIFF(a, b) ((a - b + 8192) & 0x1FFF) - -/** - * Calculate motion vector component that should be added for direct blocks. - */ -static int calc_add_mv(RV34DecContext *r, int dir, int val) -{ - int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts); - int dist = dir ? -GET_PTS_DIFF(r->next_pts, r->cur_pts) : GET_PTS_DIFF(r->cur_pts, r->last_pts); - int mul; - - if(!refdist) return 0; - mul = (dist << 14) / refdist; - return (val * mul + 0x2000) >> 14; -} - -/** - * Predict motion vector for B-frame macroblock. - */ -static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2], - int A_avail, int B_avail, int C_avail, - int *mx, int *my) -{ - if(A_avail + B_avail + C_avail != 3){ - *mx = A[0] + B[0] + C[0]; - *my = A[1] + B[1] + C[1]; - if(A_avail + B_avail + C_avail == 2){ - *mx /= 2; - *my /= 2; - } - }else{ - *mx = mid_pred(A[0], B[0], C[0]); - *my = mid_pred(A[1], B[1], C[1]); - } -} - -/** - * motion vector prediction for B-frames - */ -static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir) -{ - MpegEncContext *s = &r->s; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; - int A[2], B[2], C[2]; - int has_A = 0, has_B = 0, has_C = 0; - int mx, my; - int i, j; - Picture *cur_pic = s->current_picture_ptr; - const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0; - int type = cur_pic->mb_type[mb_pos]; - - memset(A, 0, sizeof(A)); - memset(B, 0, sizeof(B)); - memset(C, 0, sizeof(C)); - if((r->avail_cache[6-1] & type) & mask){ - A[0] = cur_pic->motion_val[dir][mv_pos - 1][0]; - A[1] = cur_pic->motion_val[dir][mv_pos - 1][1]; - has_A = 1; - } - if((r->avail_cache[6-4] & type) & mask){ - B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0]; - B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1]; - has_B = 1; - } - if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){ - C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0]; - C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1]; - has_C = 1; - }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){ - C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0]; - C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1]; - has_C = 1; - } - - rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my); - - mx += r->dmv[dir][0]; - my += r->dmv[dir][1]; - - for(j = 0; j < 2; j++){ - for(i = 0; i < 2; i++){ - cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx; - cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my; - } - } - if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){ - ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride); - } -} - -/** - * motion vector prediction - RV3 version - */ -static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir) -{ - MpegEncContext *s = &r->s; - int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; - int A[2] = {0}, B[2], C[2]; - int i, j, k; - int mx, my; - int avail_index = avail_indexes[0]; - - if(r->avail_cache[avail_index - 1]){ - A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0]; - A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1]; - } - if(r->avail_cache[avail_index - 4]){ - B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0]; - B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1]; - }else{ - B[0] = A[0]; - B[1] = A[1]; - } - if(!r->avail_cache[avail_index - 4 + 2]){ - if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1])){ - C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0]; - C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1]; - }else{ - C[0] = A[0]; - C[1] = A[1]; - } - }else{ - C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][0]; - C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][1]; - } - mx = mid_pred(A[0], B[0], C[0]); - my = mid_pred(A[1], B[1], C[1]); - mx += r->dmv[0][0]; - my += r->dmv[0][1]; - for(j = 0; j < 2; j++){ - for(i = 0; i < 2; i++){ - for(k = 0; k < 2; k++){ - s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx; - s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my; - } - } - } -} - -static const int chroma_coeffs[3] = { 0, 3, 5 }; - -/** - * generic motion compensation function - * - * @param r decoder context - * @param block_type type of the current block - * @param xoff horizontal offset from the start of the current block - * @param yoff vertical offset from the start of the current block - * @param mv_off offset to the motion vector information - * @param width width of the current partition in 8x8 blocks - * @param height height of the current partition in 8x8 blocks - * @param dir motion compensation direction (i.e. from the last or the next reference frame) - * @param thirdpel motion vectors are specified in 1/3 of pixel - * @param qpel_mc a set of functions used to perform luma motion compensation - * @param chroma_mc a set of functions used to perform chroma motion compensation - */ -static inline void rv34_mc(RV34DecContext *r, const int block_type, - const int xoff, const int yoff, int mv_off, - const int width, const int height, int dir, - const int thirdpel, - qpel_mc_func (*qpel_mc)[16], - h264_chroma_mc_func (*chroma_mc)) -{ - MpegEncContext *s = &r->s; - uint8_t *Y, *U, *V, *srcY, *srcU, *srcV; - int dxy, mx, my, umx, umy, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; - int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off; - int is16x16 = 1; - - if(thirdpel){ - int chroma_mx, chroma_my; - mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24); - my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24); - lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3; - ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3; - chroma_mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + 1) >> 1; - chroma_my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + 1) >> 1; - umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24); - umy = (chroma_my + (3 << 24)) / 3 - (1 << 24); - uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3]; - uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3]; - }else{ - int cx, cy; - mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2; - my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2; - lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3; - ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3; - cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2; - cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2; - umx = cx >> 2; - umy = cy >> 2; - uvmx = (cx & 3) << 1; - uvmy = (cy & 3) << 1; - //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3 - if(uvmx == 6 && uvmy == 6) - uvmx = uvmy = 4; - } - dxy = ly*4 + lx; - srcY = dir ? s->next_picture_ptr->data[0] : s->last_picture_ptr->data[0]; - srcU = dir ? s->next_picture_ptr->data[1] : s->last_picture_ptr->data[1]; - srcV = dir ? s->next_picture_ptr->data[2] : s->last_picture_ptr->data[2]; - src_x = s->mb_x * 16 + xoff + mx; - src_y = s->mb_y * 16 + yoff + my; - uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx; - uvsrc_y = s->mb_y * 8 + (yoff >> 1) + umy; - srcY += src_y * s->linesize + src_x; - srcU += uvsrc_y * s->uvlinesize + uvsrc_x; - srcV += uvsrc_y * s->uvlinesize + uvsrc_x; - if( (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 - || (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){ - uint8_t *uvbuf= s->edge_emu_buffer + 22 * s->linesize; - - srcY -= 2 + 2*s->linesize; - ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6, - src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos); - srcY = s->edge_emu_buffer + 2 + 2*s->linesize; - ff_emulated_edge_mc(uvbuf , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - srcU = uvbuf; - srcV = uvbuf + 16; - } - Y = s->dest[0] + xoff + yoff *s->linesize; - U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize; - V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize; - - if(block_type == RV34_MB_P_16x8){ - qpel_mc[1][dxy](Y, srcY, s->linesize); - Y += 8; - srcY += 8; - }else if(block_type == RV34_MB_P_8x16){ - qpel_mc[1][dxy](Y, srcY, s->linesize); - Y += 8 * s->linesize; - srcY += 8 * s->linesize; - } - is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16); - qpel_mc[!is16x16][dxy](Y, srcY, s->linesize); - chroma_mc[2-width] (U, srcU, s->uvlinesize, height*4, uvmx, uvmy); - chroma_mc[2-width] (V, srcV, s->uvlinesize, height*4, uvmx, uvmy); -} - -static void rv34_mc_1mv(RV34DecContext *r, const int block_type, - const int xoff, const int yoff, int mv_off, - const int width, const int height, int dir) -{ - rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, - r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab - : r->s.dsp.put_rv40_qpel_pixels_tab, - r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab - : r->s.dsp.put_rv40_chroma_pixels_tab); -} - -static void rv34_mc_2mv(RV34DecContext *r, const int block_type) -{ - rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, - r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab - : r->s.dsp.put_rv40_qpel_pixels_tab, - r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab - : r->s.dsp.put_rv40_chroma_pixels_tab); - rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, - r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab - : r->s.dsp.avg_rv40_qpel_pixels_tab, - r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab - : r->s.dsp.avg_rv40_chroma_pixels_tab); -} - -static void rv34_mc_2mv_skip(RV34DecContext *r) -{ - int i, j; - for(j = 0; j < 2; j++) - for(i = 0; i < 2; i++){ - rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30, - r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab - : r->s.dsp.put_rv40_qpel_pixels_tab, - r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab - : r->s.dsp.put_rv40_chroma_pixels_tab); - rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30, - r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab - : r->s.dsp.avg_rv40_qpel_pixels_tab, - r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab - : r->s.dsp.avg_rv40_chroma_pixels_tab); - } -} - -/** number of motion vectors in each macroblock type */ -static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 }; - -/** - * Decode motion vector differences - * and perform motion vector reconstruction and motion compensation. - */ -static int rv34_decode_mv(RV34DecContext *r, int block_type) -{ - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int i, j, k, l; - int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; - int next_bt; - - memset(r->dmv, 0, sizeof(r->dmv)); - for(i = 0; i < num_mvs[block_type]; i++){ - r->dmv[i][0] = svq3_get_se_golomb(gb); - r->dmv[i][1] = svq3_get_se_golomb(gb); - } - switch(block_type){ - case RV34_MB_TYPE_INTRA: - case RV34_MB_TYPE_INTRA16x16: - ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); - return 0; - case RV34_MB_SKIP: - if(s->pict_type == FF_P_TYPE){ - ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); - rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); - break; - } - case RV34_MB_B_DIRECT: - //surprisingly, it uses motion scheme from next reference frame - next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride]; - if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){ - ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); - ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); - }else - for(j = 0; j < 2; j++) - for(i = 0; i < 2; i++) - for(k = 0; k < 2; k++) - for(l = 0; l < 2; l++) - s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]); - if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC - rv34_mc_2mv(r, block_type); - else - rv34_mc_2mv_skip(r); - ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); - break; - case RV34_MB_P_16x16: - case RV34_MB_P_MIX16x16: - rv34_pred_mv(r, block_type, 0, 0); - rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); - break; - case RV34_MB_B_FORWARD: - case RV34_MB_B_BACKWARD: - r->dmv[1][0] = r->dmv[0][0]; - r->dmv[1][1] = r->dmv[0][1]; - if(r->rv30) - rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD); - else - rv34_pred_mv_b (r, block_type, block_type == RV34_MB_B_BACKWARD); - rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD); - break; - case RV34_MB_P_16x8: - case RV34_MB_P_8x16: - rv34_pred_mv(r, block_type, 0, 0); - rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1); - if(block_type == RV34_MB_P_16x8){ - rv34_mc_1mv(r, block_type, 0, 0, 0, 2, 1, 0); - rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0); - } - if(block_type == RV34_MB_P_8x16){ - rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0); - rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0); - } - break; - case RV34_MB_B_BIDIR: - rv34_pred_mv_b (r, block_type, 0); - rv34_pred_mv_b (r, block_type, 1); - rv34_mc_2mv (r, block_type); - break; - case RV34_MB_P_8x8: - for(i=0;i< 4;i++){ - rv34_pred_mv(r, block_type, i, i); - rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0); - } - break; - } - - return 0; -} -/** @} */ // mv group - -/** - * @defgroup recons Macroblock reconstruction functions - * @{ - */ -/** mapping of RV30/40 intra prediction types to standard H.264 types */ -static const int ittrans[9] = { - DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED, - VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED, -}; - -/** mapping of RV30/40 intra 16x16 prediction types to standard H.264 types */ -static const int ittrans16[4] = { - DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8, -}; - -/** - * Perform 4x4 intra prediction. - */ -static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right) -{ - uint8_t *prev = dst - stride + 4; - uint32_t topleft; - - if(!up && !left) - itype = DC_128_PRED; - else if(!up){ - if(itype == VERT_PRED) itype = HOR_PRED; - if(itype == DC_PRED) itype = LEFT_DC_PRED; - }else if(!left){ - if(itype == HOR_PRED) itype = VERT_PRED; - if(itype == DC_PRED) itype = TOP_DC_PRED; - if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN; - } - if(!down){ - if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN; - if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN; - if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN; - } - if(!right && up){ - topleft = dst[-stride + 3] * 0x01010101; - prev = (uint8_t*)&topleft; - } - r->h.pred4x4[itype](dst, prev, stride); -} - -/** add_pixels_clamped for 4x4 block */ -static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off) -{ - int x, y; - for(y = 0; y < 4; y++) - for(x = 0; x < 4; x++) - dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]); -} - -static inline int adjust_pred16(int itype, int up, int left) -{ - if(!up && !left) - itype = DC_128_PRED8x8; - else if(!up){ - if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8; - if(itype == VERT_PRED8x8) itype = HOR_PRED8x8; - if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8; - }else if(!left){ - if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8; - if(itype == HOR_PRED8x8) itype = VERT_PRED8x8; - if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8; - } - return itype; -} - -static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int cbp, int is16) -{ - MpegEncContext *s = &r->s; - DSPContext *dsp = &s->dsp; - int i, j; - uint8_t *Y, *U, *V; - int itype; - int avail[6*8] = {0}; - int idx; - - // Set neighbour information. - if(r->avail_cache[1]) - avail[0] = 1; - if(r->avail_cache[2]) - avail[1] = avail[2] = 1; - if(r->avail_cache[3]) - avail[3] = avail[4] = 1; - if(r->avail_cache[4]) - avail[5] = 1; - if(r->avail_cache[5]) - avail[8] = avail[16] = 1; - if(r->avail_cache[9]) - avail[24] = avail[32] = 1; - - Y = s->dest[0]; - U = s->dest[1]; - V = s->dest[2]; - if(!is16){ - for(j = 0; j < 4; j++){ - idx = 9 + j*8; - for(i = 0; i < 4; i++, cbp >>= 1, Y += 4, idx++){ - rv34_pred_4x4_block(r, Y, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]); - avail[idx] = 1; - if(cbp & 1) - rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32); - } - Y += s->linesize * 4 - 4*4; - intra_types += r->intra_types_stride; - } - intra_types -= r->intra_types_stride * 4; - fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4); - for(j = 0; j < 2; j++){ - idx = 6 + j*4; - for(i = 0; i < 2; i++, cbp >>= 1, idx++){ - rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); - rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); - r->avail_cache[idx] = 1; - if(cbp & 0x01) - rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32); - if(cbp & 0x10) - rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32); - } - } - }else{ - itype = ittrans16[intra_types[0]]; - itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]); - r->h.pred16x16[itype](Y, s->linesize); - dsp->add_pixels_clamped(s->block[0], Y, s->linesize); - dsp->add_pixels_clamped(s->block[1], Y + 8, s->linesize); - Y += s->linesize * 8; - dsp->add_pixels_clamped(s->block[2], Y, s->linesize); - dsp->add_pixels_clamped(s->block[3], Y + 8, s->linesize); - - itype = ittrans16[intra_types[0]]; - if(itype == PLANE_PRED8x8) itype = DC_PRED8x8; - itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]); - r->h.pred8x8[itype](U, s->uvlinesize); - dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize); - r->h.pred8x8[itype](V, s->uvlinesize); - dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize); - } -} - -/** @} */ // recons group - -/** - * @addtogroup bitstream - * Decode macroblock header and return CBP in case of success, -1 otherwise. - */ -static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) -{ - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int i, t; - - if(!r->si.type){ - r->is16 = get_bits1(gb); - if(!r->is16 && !r->rv30){ - if(!get_bits1(gb)) - av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); - } - s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA; - r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA; - }else{ - r->block_type = r->decode_mb_info(r); - if(r->block_type == -1) - return -1; - s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; - r->mb_type[mb_pos] = r->block_type; - if(r->block_type == RV34_MB_SKIP){ - if(s->pict_type == FF_P_TYPE) - r->mb_type[mb_pos] = RV34_MB_P_16x16; - if(s->pict_type == FF_B_TYPE) - r->mb_type[mb_pos] = RV34_MB_B_DIRECT; - } - r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); - rv34_decode_mv(r, r->block_type); - if(r->block_type == RV34_MB_SKIP){ - fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0])); - return 0; - } - r->chroma_vlc = 1; - r->luma_vlc = 0; - } - if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ - if(r->is16){ - t = get_bits(gb, 2); - fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0])); - r->luma_vlc = 2; - }else{ - if(r->decode_intra_types(r, gb, intra_types) < 0) - return -1; - r->luma_vlc = 1; - } - r->chroma_vlc = 0; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); - }else{ - for(i = 0; i < 16; i++) - intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); - if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){ - r->is16 = 1; - r->chroma_vlc = 1; - r->luma_vlc = 2; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); - } - } - - return rv34_decode_cbp(gb, r->cur_vlcs, r->is16); -} - -/** - * @addtogroup recons - * @{ - */ -/** - * mask for retrieving all bits in coded block pattern - * corresponding to one 8x8 block - */ -#define LUMA_CBP_BLOCK_MASK 0x33 - -#define U_CBP_MASK 0x0F0000 -#define V_CBP_MASK 0xF00000 - - -static void rv34_apply_differences(RV34DecContext *r, int cbp) -{ - static const int shifts[4] = { 0, 2, 8, 10 }; - MpegEncContext *s = &r->s; - int i; - - for(i = 0; i < 4; i++) - if((cbp & (LUMA_CBP_BLOCK_MASK << shifts[i])) || r->block_type == RV34_MB_P_MIX16x16) - s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize); - if(cbp & U_CBP_MASK) - s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize); - if(cbp & V_CBP_MASK) - s->dsp.add_pixels_clamped(s->block[5], s->dest[2], s->uvlinesize); -} - -static int is_mv_diff_gt_3(int16_t (*motion_val)[2], int step) -{ - int d; - d = motion_val[0][0] - motion_val[-step][0]; - if(d < -3 || d > 3) - return 1; - d = motion_val[0][1] - motion_val[-step][1]; - if(d < -3 || d > 3) - return 1; - return 0; -} - -static int rv34_set_deblock_coef(RV34DecContext *r) -{ - MpegEncContext *s = &r->s; - int hmvmask = 0, vmvmask = 0, i, j; - int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; - int16_t (*motion_val)[2] = s->current_picture_ptr->motion_val[0][midx]; - for(j = 0; j < 16; j += 8){ - for(i = 0; i < 2; i++){ - if(is_mv_diff_gt_3(motion_val + i, 1)) - vmvmask |= 0x11 << (j + i*2); - if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride)) - hmvmask |= 0x03 << (j + i*2); - } - motion_val += s->b8_stride; - } - if(s->first_slice_line) - hmvmask &= ~0x000F; - if(!s->mb_x) - vmvmask &= ~0x1111; - if(r->rv30){ //RV30 marks both subblocks on the edge for filtering - vmvmask |= (vmvmask & 0x4444) >> 1; - hmvmask |= (hmvmask & 0x0F00) >> 4; - if(s->mb_x) - r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3; - if(!s->first_slice_line) - r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12; - } - return hmvmask | vmvmask; -} - -static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) -{ - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int cbp, cbp2; - int i, blknum, blkoff; - DCTELEM block16[64]; - int luma_dc_quant; - int dist; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - - // Calculate which neighbours are available. Maybe it's worth optimizing too. - memset(r->avail_cache, 0, sizeof(r->avail_cache)); - fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4); - dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width; - if(s->mb_x && dist) - r->avail_cache[5] = - r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1]; - if(dist >= s->mb_width) - r->avail_cache[2] = - r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]; - if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1) - r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1]; - if(s->mb_x && dist > s->mb_width) - r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1]; - - s->qscale = r->si.quant; - cbp = cbp2 = rv34_decode_mb_header(r, intra_types); - r->cbp_luma [mb_pos] = cbp; - r->cbp_chroma[mb_pos] = cbp >> 16; - if(s->pict_type == FF_I_TYPE) - r->deblock_coefs[mb_pos] = 0xFFFF; - else - r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos]; - s->current_picture_ptr->qscale_table[mb_pos] = s->qscale; - - if(cbp == -1) - return -1; - - luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale]; - if(r->is16){ - memset(block16, 0, sizeof(block16)); - rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0); - rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]); - rv34_inv_transform_noround(block16); - } - - for(i = 0; i < 16; i++, cbp >>= 1){ - if(!r->is16 && !(cbp & 1)) continue; - blknum = ((i & 2) >> 1) + ((i & 8) >> 2); - blkoff = ((i & 1) << 2) + ((i & 4) << 3); - if(cbp & 1) - rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0); - rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]); - if(r->is16) //FIXME: optimize - s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)]; - rv34_inv_transform(s->block[blknum] + blkoff); - } - if(r->block_type == RV34_MB_P_MIX16x16) - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); - for(; i < 24; i++, cbp >>= 1){ - if(!(cbp & 1)) continue; - blknum = ((i & 4) >> 2) + 4; - blkoff = ((i & 1) << 2) + ((i & 2) << 4); - rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1); - rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]); - rv34_inv_transform(s->block[blknum] + blkoff); - } - if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])) - rv34_output_macroblock(r, intra_types, cbp2, r->is16); - else - rv34_apply_differences(r, cbp2); - - return 0; -} - -static int check_slice_end(RV34DecContext *r, MpegEncContext *s) -{ - int bits; - if(s->mb_y >= s->mb_height) - return 1; - if(!s->mb_num_left) - return 1; - if(r->s.mb_skip_run > 1) - return 0; - bits = r->bits - get_bits_count(&s->gb); - if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits))) - return 1; - return 0; -} - -static inline int slice_compare(SliceInfo *si1, SliceInfo *si2) -{ - return si1->type != si2->type || - si1->start >= si2->start || - si1->width != si2->width || - si1->height != si2->height|| - si1->pts != si2->pts; -} - -static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size) -{ - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int mb_pos; - int res; - - init_get_bits(&r->s.gb, buf, buf_size*8); - res = r->parse_slice_header(r, gb, &r->si); - if(res < 0){ - av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n"); - return -1; - } - - if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) { - if(s->width != r->si.width || s->height != r->si.height){ - av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height); - MPV_common_end(s); - s->width = r->si.width; - s->height = r->si.height; - avcodec_set_dimensions(s->avctx, s->width, s->height); - if(MPV_common_init(s) < 0) - return -1; - r->intra_types_stride = s->mb_width*4 + 4; - r->intra_types_hist = av_realloc(r->intra_types_hist, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); - r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; - r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); - r->cbp_luma = av_realloc(r->cbp_luma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); - r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); - r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs)); - } - s->pict_type = r->si.type ? r->si.type : FF_I_TYPE; - if(MPV_frame_start(s, s->avctx) < 0) - return -1; - ff_er_frame_start(s); - r->cur_pts = r->si.pts; - if(s->pict_type != FF_B_TYPE){ - r->last_pts = r->next_pts; - r->next_pts = r->cur_pts; - } - s->mb_x = s->mb_y = 0; - } - - r->si.end = end; - s->qscale = r->si.quant; - r->bits = buf_size*8; - s->mb_num_left = r->si.end - r->si.start; - r->s.mb_skip_run = 0; - - mb_pos = s->mb_x + s->mb_y * s->mb_width; - if(r->si.start != mb_pos){ - av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos); - s->mb_x = r->si.start % s->mb_width; - s->mb_y = r->si.start / s->mb_width; - } - memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); - s->first_slice_line = 1; - s->resync_mb_x= s->mb_x; - s->resync_mb_y= s->mb_y; - - ff_init_block_index(s); - while(!check_slice_end(r, s)) { - ff_update_block_index(s); - s->dsp.clear_blocks(s->block[0]); - - if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 4) < 0){ - ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_ERROR|DC_ERROR|MV_ERROR); - return -1; - } - if (++s->mb_x == s->mb_width) { - s->mb_x = 0; - s->mb_y++; - ff_init_block_index(s); - - memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist)); - memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist)); - - if(r->loop_filter && s->mb_y >= 2) - r->loop_filter(r, s->mb_y - 2); - } - if(s->mb_x == s->resync_mb_x) - s->first_slice_line=0; - s->mb_num_left--; - } - 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 s->mb_y == s->mb_height; -} - -/** @} */ // recons group end - -/** - * Initialize decoder. - */ -av_cold int ff_rv34_decode_init(AVCodecContext *avctx) -{ - RV34DecContext *r = avctx->priv_data; - MpegEncContext *s = &r->s; - - MPV_decode_defaults(s); - s->avctx= avctx; - s->out_format = FMT_H263; - s->codec_id= avctx->codec_id; - - s->width = avctx->width; - s->height = avctx->height; - - r->s.avctx = avctx; - avctx->flags |= CODEC_FLAG_EMU_EDGE; - r->s.flags |= CODEC_FLAG_EMU_EDGE; - avctx->pix_fmt = PIX_FMT_YUV420P; - avctx->has_b_frames = 1; - s->low_delay = 0; - - if (MPV_common_init(s) < 0) - return -1; - - ff_h264_pred_init(&r->h, CODEC_ID_RV40); - - r->intra_types_stride = 4*s->mb_stride + 4; - r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); - r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; - - r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); - - r->cbp_luma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); - r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); - r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs)); - - if(!intra_vlcs[0].cbppattern[0].bits) - rv34_init_tables(); - - return 0; -} - -static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) -{ - if(avctx->slice_count) return avctx->slice_offset[n]; - else return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) : AV_RB32(buf + n*8); -} - -int ff_rv34_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - RV34DecContext *r = avctx->priv_data; - MpegEncContext *s = &r->s; - AVFrame *pict = data; - SliceInfo si; - int i; - int slice_count; - const uint8_t *slices_hdr = NULL; - int last = 0; - - /* 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(!avctx->slice_count){ - slice_count = (*buf++) + 1; - slices_hdr = buf + 4; - buf += 8 * slice_count; - }else - slice_count = avctx->slice_count; - - //parse first slice header to check whether this frame can be decoded - if(get_slice_offset(avctx, slices_hdr, 0) > buf_size){ - av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n"); - return -1; - } - init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), buf_size-get_slice_offset(avctx, slices_hdr, 0)); - if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){ - av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n"); - return -1; - } - if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == FF_B_TYPE) - return -1; - /* skip b frames if we are in a hurry */ - if(avctx->hurry_up && si.type==FF_B_TYPE) return buf_size; - if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==FF_B_TYPE) - || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=FF_I_TYPE) - || avctx->skip_frame >= AVDISCARD_ALL) - return buf_size; - /* skip everything if we are in a hurry>=5 */ - if(avctx->hurry_up>=5) - return buf_size; - - for(i=0; i buf_size){ - av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n"); - break; - } - - r->si.end = s->mb_width * s->mb_height; - if(i+1 < slice_count){ - init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8); - if(r->parse_slice_header(r, &r->s.gb, &si) < 0){ - if(i+2 < slice_count) - size = get_slice_offset(avctx, slices_hdr, i+2) - offset; - else - size = buf_size - offset; - }else - r->si.end = si.start; - } - last = rv34_decode_slice(r, r->si.end, buf + offset, size); - s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start; - if(last) - break; - } - - if(last){ - if(r->loop_filter) - r->loop_filter(r, s->mb_height - 1); - ff_er_frame_end(s); - MPV_frame_end(s); - if (s->pict_type == FF_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); - } - s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) - } - return buf_size; -} - -av_cold int ff_rv34_decode_end(AVCodecContext *avctx) -{ - RV34DecContext *r = avctx->priv_data; - - MPV_common_end(&r->s); - - av_freep(&r->intra_types_hist); - r->intra_types = NULL; - av_freep(&r->mb_type); - av_freep(&r->cbp_luma); - av_freep(&r->cbp_chroma); - av_freep(&r->deblock_coefs); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/rv34.h b/tizen/distrib/ffmpeg/libavcodec/rv34.h deleted file mode 100644 index 24a27ce..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv34.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * RV30/40 decoder common data declarations - * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV30 and RV40 decoder common data declarations - */ - -#ifndef AVCODEC_RV34_H -#define AVCODEC_RV34_H - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - -#include "h264pred.h" - -#define MB_TYPE_SEPARATE_DC 0x01000000 -#define IS_SEPARATE_DC(a) ((a) & MB_TYPE_SEPARATE_DC) - -/** - * RV30 and RV40 Macroblock types - */ -enum RV40BlockTypes{ - RV34_MB_TYPE_INTRA, ///< Intra macroblock - RV34_MB_TYPE_INTRA16x16, ///< Intra macroblock with DCs in a separate 4x4 block - RV34_MB_P_16x16, ///< P-frame macroblock, one motion frame - RV34_MB_P_8x8, ///< P-frame macroblock, 8x8 motion compensation partitions - RV34_MB_B_FORWARD, ///< B-frame macroblock, forward prediction - RV34_MB_B_BACKWARD, ///< B-frame macroblock, backward prediction - RV34_MB_SKIP, ///< Skipped block - RV34_MB_B_DIRECT, ///< Bidirectionally predicted B-frame macroblock, no motion vectors - RV34_MB_P_16x8, ///< P-frame macroblock, 16x8 motion compensation partitions - RV34_MB_P_8x16, ///< P-frame macroblock, 8x16 motion compensation partitions - RV34_MB_B_BIDIR, ///< Bidirectionally predicted B-frame macroblock, two motion vectors - RV34_MB_P_MIX16x16, ///< P-frame macroblock with DCs in a separate 4x4 block, one motion vector - RV34_MB_TYPES -}; - -/** - * VLC tables used by the decoder - * - * Intra frame VLC sets do not contain some of those tables. - */ -typedef struct RV34VLC{ - VLC cbppattern[2]; ///< VLCs used for pattern of coded block patterns decoding - VLC cbp[2][4]; ///< VLCs used for coded block patterns decoding - VLC first_pattern[4]; ///< VLCs used for decoding coefficients in the first subblock - VLC second_pattern[2]; ///< VLCs used for decoding coefficients in the subblocks 2 and 3 - VLC third_pattern[2]; ///< VLCs used for decoding coefficients in the last subblock - VLC coefficient; ///< VLCs used for decoding big coefficients -}RV34VLC; - -/** essential slice information */ -typedef struct SliceInfo{ - int type; ///< slice type (intra, inter) - int quant; ///< quantizer used for this slice - int vlc_set; ///< VLCs used for this slice - int start, end; ///< start and end macroblocks of the slice - int width; ///< coded width - int height; ///< coded height - int pts; ///< frame timestamp -}SliceInfo; - -/** decoder context */ -typedef struct RV34DecContext{ - MpegEncContext s; - int8_t *intra_types_hist;///< old block types, used for prediction - int8_t *intra_types; ///< block types - int intra_types_stride;///< block types array stride - const uint8_t *luma_dc_quant_i;///< luma subblock DC quantizer for intraframes - const uint8_t *luma_dc_quant_p;///< luma subblock DC quantizer for interframes - - RV34VLC *cur_vlcs; ///< VLC set used for current frame decoding - int bits; ///< slice size in bits - H264PredContext h; ///< functions for 4x4 and 16x16 intra block prediction - SliceInfo si; ///< current slice information - - int *mb_type; ///< internal macroblock types - int block_type; ///< current block type - int luma_vlc; ///< which VLC set will be used for decoding of luma blocks - int chroma_vlc; ///< which VLC set will be used for decoding of chroma blocks - int is16; ///< current block has additional 16x16 specific features or not - int dmv[4][2]; ///< differential motion vectors for the current macroblock - - int rv30; ///< indicates which RV variasnt is currently decoded - int rpr; ///< one field size in RV30 slice header - - int cur_pts, last_pts, next_pts; - - uint16_t *cbp_luma; ///< CBP values for luma subblocks - uint8_t *cbp_chroma; ///< CBP values for chroma subblocks - int *deblock_coefs; ///< deblock coefficients for each macroblock - - /** 8x8 block available flags (for MV prediction) */ - DECLARE_ALIGNED(8, uint32_t, avail_cache)[3*4]; - - int (*parse_slice_header)(struct RV34DecContext *r, GetBitContext *gb, SliceInfo *si); - int (*decode_mb_info)(struct RV34DecContext *r); - int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int8_t *dst); - void (*loop_filter)(struct RV34DecContext *r, int row); -}RV34DecContext; - -/** - * common decoding functions - */ -int ff_rv34_get_start_offset(GetBitContext *gb, int blocks); -int ff_rv34_decode_init(AVCodecContext *avctx); -int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt); -int ff_rv34_decode_end(AVCodecContext *avctx); - -#endif /* AVCODEC_RV34_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rv34data.h b/tizen/distrib/ffmpeg/libavcodec/rv34data.h deleted file mode 100644 index 2155084..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv34data.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * RealVideo 4 decoder - * copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * miscellaneous RV30/40 tables - */ - -#ifndef AVCODEC_RV34DATA_H -#define AVCODEC_RV34DATA_H - -#include - -/** - * number of ones in nibble minus one - */ -static const uint8_t rv34_count_ones[16] = { - 0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 2, 1, 2, 2, 3 -}; - -/** - * values used to reconstruct coded block pattern - */ -static const uint8_t rv34_cbp_code[16] = { - 0x00, 0x20, 0x10, 0x30, 0x02, 0x22, 0x12, 0x32, - 0x01, 0x21, 0x11, 0x31, 0x03, 0x23, 0x13, 0x33 -}; - -/** - * precalculated results of division by three and modulo three for values 0-107 - * - * A lot of four-tuples in RV40 are represented as c0*27+c1*9+c2*3+c3. - * This table allows conversion from a value back to a vector. - */ -static const uint8_t modulo_three_table[108][4] = { - { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 2 }, { 0, 0, 1, 0 }, - { 0, 0, 1, 1 }, { 0, 0, 1, 2 }, { 0, 0, 2, 0 }, { 0, 0, 2, 1 }, - { 0, 0, 2, 2 }, { 0, 1, 0, 0 }, { 0, 1, 0, 1 }, { 0, 1, 0, 2 }, - { 0, 1, 1, 0 }, { 0, 1, 1, 1 }, { 0, 1, 1, 2 }, { 0, 1, 2, 0 }, - { 0, 1, 2, 1 }, { 0, 1, 2, 2 }, { 0, 2, 0, 0 }, { 0, 2, 0, 1 }, - { 0, 2, 0, 2 }, { 0, 2, 1, 0 }, { 0, 2, 1, 1 }, { 0, 2, 1, 2 }, - { 0, 2, 2, 0 }, { 0, 2, 2, 1 }, { 0, 2, 2, 2 }, { 1, 0, 0, 0 }, - { 1, 0, 0, 1 }, { 1, 0, 0, 2 }, { 1, 0, 1, 0 }, { 1, 0, 1, 1 }, - { 1, 0, 1, 2 }, { 1, 0, 2, 0 }, { 1, 0, 2, 1 }, { 1, 0, 2, 2 }, - { 1, 1, 0, 0 }, { 1, 1, 0, 1 }, { 1, 1, 0, 2 }, { 1, 1, 1, 0 }, - { 1, 1, 1, 1 }, { 1, 1, 1, 2 }, { 1, 1, 2, 0 }, { 1, 1, 2, 1 }, - { 1, 1, 2, 2 }, { 1, 2, 0, 0 }, { 1, 2, 0, 1 }, { 1, 2, 0, 2 }, - { 1, 2, 1, 0 }, { 1, 2, 1, 1 }, { 1, 2, 1, 2 }, { 1, 2, 2, 0 }, - { 1, 2, 2, 1 }, { 1, 2, 2, 2 }, { 2, 0, 0, 0 }, { 2, 0, 0, 1 }, - { 2, 0, 0, 2 }, { 2, 0, 1, 0 }, { 2, 0, 1, 1 }, { 2, 0, 1, 2 }, - { 2, 0, 2, 0 }, { 2, 0, 2, 1 }, { 2, 0, 2, 2 }, { 2, 1, 0, 0 }, - { 2, 1, 0, 1 }, { 2, 1, 0, 2 }, { 2, 1, 1, 0 }, { 2, 1, 1, 1 }, - { 2, 1, 1, 2 }, { 2, 1, 2, 0 }, { 2, 1, 2, 1 }, { 2, 1, 2, 2 }, - { 2, 2, 0, 0 }, { 2, 2, 0, 1 }, { 2, 2, 0, 2 }, { 2, 2, 1, 0 }, - { 2, 2, 1, 1 }, { 2, 2, 1, 2 }, { 2, 2, 2, 0 }, { 2, 2, 2, 1 }, - { 2, 2, 2, 2 }, { 3, 0, 0, 0 }, { 3, 0, 0, 1 }, { 3, 0, 0, 2 }, - { 3, 0, 1, 0 }, { 3, 0, 1, 1 }, { 3, 0, 1, 2 }, { 3, 0, 2, 0 }, - { 3, 0, 2, 1 }, { 3, 0, 2, 2 }, { 3, 1, 0, 0 }, { 3, 1, 0, 1 }, - { 3, 1, 0, 2 }, { 3, 1, 1, 0 }, { 3, 1, 1, 1 }, { 3, 1, 1, 2 }, - { 3, 1, 2, 0 }, { 3, 1, 2, 1 }, { 3, 1, 2, 2 }, { 3, 2, 0, 0 }, - { 3, 2, 0, 1 }, { 3, 2, 0, 2 }, { 3, 2, 1, 0 }, { 3, 2, 1, 1 }, - { 3, 2, 1, 2 }, { 3, 2, 2, 0 }, { 3, 2, 2, 1 }, { 3, 2, 2, 2 }, -}; - -/** - * quantizer values used for AC and DC coefficients in chroma blocks - */ -static const uint8_t rv34_chroma_quant[2][32] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25 }, - { 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23 } -}; - -/** - * This table is used for dequantizing. - */ -static const uint16_t rv34_qscale_tab[32] = { - 60, 67, 76, 85, 96, 108, 121, 136, - 152, 171, 192, 216, 242, 272, 305, 341, - 383, 432, 481, 544, 606, 683, 767, 854, - 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211 -}; - -/** - * 4x4 dezigzag pattern - */ -static const uint8_t rv34_dezigzag[16] = { - 0, 1, 8, 16, - 9, 2, 3, 10, - 17, 24, 25, 18, - 11, 19, 26, 27 -}; - -/** - * tables used to translate a quantizer value into a VLC set for decoding - * The first table is used for intraframes. - */ -static const uint8_t rv34_quant_to_vlc_set[2][31] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, - 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6 }, -}; - -/** - * table for obtaining the quantizer difference - * @todo Use with modified_quant_tab from h263data.h. - */ -static const uint8_t rv34_dquant_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 -} -}; - -/** - * maximum number of macroblocks for each of the possible slice offset sizes - * @todo This is the same as ff_mba_max, maybe use it instead. - */ -static const uint16_t rv34_mb_max_sizes[6] = { 0x2F, 0x62, 0x18B, 0x62F, 0x18BF, 0x23FF }; -/** - * bits needed to code the slice offset for the given size - * @todo This is the same as ff_mba_length, maybe use it instead. - */ -static const uint8_t rv34_mb_bits_sizes[6] = { 6, 7, 9, 11, 13, 14 }; - -#endif /* AVCODEC_RV34DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rv34vlc.h b/tizen/distrib/ffmpeg/libavcodec/rv34vlc.h deleted file mode 100644 index 2b89e4c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv34vlc.h +++ /dev/null @@ -1,4054 +0,0 @@ -/* - * RealVideo 3/4 decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV30/40 VLC tables - */ - -#ifndef AVCODEC_RV34VLC_H -#define AVCODEC_RV34VLC_H - -#include - -#define NUM_INTRA_TABLES 5 -#define NUM_INTER_TABLES 7 - -#define CBPPAT_VLC_SIZE 1296 -#define CBP_VLC_SIZE 16 -#define FIRSTBLK_VLC_SIZE 864 -#define OTHERBLK_VLC_SIZE 108 -#define COEFF_VLC_SIZE 32 - -static const uint8_t rv34_table_intra_cbppat[NUM_INTRA_TABLES][2][CBPPAT_VLC_SIZE] = { - { - { - 8, 10, 10, 10, 10, 10, 11, 10, 10, 11, 10, 10, 10, 10, 10, 6, - 12, 12, 13, 12, 13, 12, 13, 11, 13, 13, 13, 12, 13, 12, 12, 8, - 14, 13, 16, 13, 15, 13, 16, 12, 16, 16, 16, 14, 16, 13, 14, 10, - 12, 13, 12, 12, 13, 13, 13, 12, 13, 13, 12, 12, 13, 12, 12, 8, - 13, 14, 14, 12, 14, 14, 14, 12, 14, 15, 14, 12, 14, 13, 13, 8, - 16, 16, 16, 12, 16, 16, 16, 13, 16, 16, 16, 13, 16, 14, 14, 9, - 14, 16, 13, 13, 16, 16, 16, 14, 15, 16, 14, 13, 15, 15, 14, 10, - 16, 16, 14, 13, 16, 16, 16, 13, 16, 16, 16, 13, 16, 15, 14, 10, - 16, 16, 16, 11, 16, 16, 16, 12, 16, 16, 16, 12, 16, 16, 15, 9, - 12, 13, 13, 13, 12, 12, 14, 12, 12, 14, 13, 12, 12, 12, 12, 8, - 14, 14, 16, 14, 13, 12, 14, 12, 14, 15, 14, 13, 13, 12, 13, 8, - 16, 16, 16, 15, 16, 13, 16, 13, 16, 16, 16, 15, 16, 13, 15, 10, - 14, 16, 14, 14, 14, 14, 15, 13, 14, 16, 14, 13, 13, 13, 13, 9, - 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 14, 13, 14, 13, 13, 8, - 16, 16, 16, 14, 16, 14, 16, 13, 16, 16, 16, 14, 16, 14, 14, 9, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 14, 10, - 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 16, 14, 16, 15, 14, 9, - 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 16, 13, 16, 15, 15, 8, - 14, 16, 16, 16, 14, 14, 16, 14, 16, 16, 16, 15, 13, 13, 14, 10, - 16, 16, 16, 16, 15, 13, 16, 13, 16, 16, 16, 16, 16, 13, 14, 10, - 16, 16, 16, 16, 16, 11, 16, 12, 16, 16, 16, 16, 16, 12, 16, 9, - 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 14, 14, 10, - 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 16, 15, 16, 13, 14, 9, - 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, 13, 14, 8, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 11, - 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, 9, - 16, 16, 16, 14, 16, 15, 16, 11, 16, 16, 16, 14, 16, 14, 14, 8, - 12, 13, 13, 13, 13, 13, 14, 12, 12, 13, 12, 12, 12, 12, 12, 8, - 14, 14, 16, 14, 15, 14, 16, 13, 14, 15, 14, 13, 14, 13, 13, 9, - 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 16, 14, 16, 14, 16, 10, - 14, 15, 14, 14, 15, 14, 15, 13, 14, 14, 13, 12, 13, 13, 13, 9, - 15, 16, 15, 14, 16, 16, 16, 13, 15, 16, 14, 12, 14, 13, 13, 8, - 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 16, 13, 16, 14, 14, 9, - 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 13, 13, 16, 16, 14, 10, - 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 15, 13, 16, 14, 14, 9, - 16, 16, 16, 12, 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 15, 8, - 13, 14, 14, 14, 14, 14, 16, 13, 13, 14, 14, 13, 12, 12, 12, 8, - 16, 16, 16, 14, 15, 14, 16, 13, 15, 16, 14, 13, 13, 12, 13, 8, - 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 14, 16, 13, 14, 9, - 15, 16, 16, 15, 16, 15, 16, 13, 14, 16, 14, 13, 13, 13, 12, 8, - 16, 16, 16, 14, 16, 14, 15, 12, 15, 15, 14, 12, 13, 12, 12, 7, - 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 16, 13, 16, 13, 13, 7, - 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 14, 14, 16, 14, 13, 9, - 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 14, 12, 16, 13, 12, 7, - 16, 16, 16, 12, 16, 16, 16, 11, 16, 16, 15, 12, 16, 13, 13, 6, - 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 13, 13, 14, 10, - 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 14, 13, 14, 9, - 16, 16, 16, 16, 16, 13, 16, 13, 16, 16, 16, 16, 16, 12, 14, 8, - 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 14, 13, 13, 9, - 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 13, 14, 12, 12, 7, - 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 13, 14, 12, 13, 6, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 14, 9, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 13, 15, 13, 12, 7, - 16, 16, 16, 13, 16, 14, 16, 11, 16, 16, 16, 12, 16, 12, 12, 5, - 14, 16, 15, 16, 16, 16, 16, 15, 14, 15, 14, 14, 13, 14, 13, 10, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, 16, 10, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, 14, 15, 14, 13, 10, - 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, 13, 16, 14, 14, 9, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 15, 9, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, 13, 16, 16, 13, 10, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 13, 16, 16, 13, 9, - 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 15, 12, 16, 16, 14, 8, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 15, 14, 13, 13, 13, 9, - 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 14, 13, 13, 9, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 15, 9, - 16, 16, 16, 16, 16, 16, 16, 15, 15, 16, 14, 14, 14, 13, 13, 9, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 14, 12, 13, 12, 12, 7, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 13, 16, 13, 13, 7, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 13, 16, 14, 13, 9, - 16, 16, 16, 15, 16, 16, 16, 13, 16, 16, 13, 12, 14, 13, 12, 6, - 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 14, 10, 15, 12, 12, 5, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, 13, 13, 9, - 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 13, 12, 13, 8, - 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 15, 12, 14, 8, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 13, 13, 13, 8, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 15, 13, 12, 11, 12, 6, - 16, 16, 16, 15, 16, 14, 16, 12, 16, 16, 16, 12, 13, 10, 12, 5, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 13, 14, 12, 8, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 13, 12, 13, 12, 10, 5, - 16, 16, 16, 13, 16, 13, 16, 10, 16, 16, 13, 10, 13, 10, 10, 1, - }, - { - 2, 7, 7, 8, 7, 8, 9, 8, 7, 9, 8, 8, 8, 8, 9, 7, - 6, 9, 10, 10, 10, 10, 11, 10, 10, 11, 11, 11, 10, 11, 11, 9, - 9, 11, 12, 12, 12, 13, 14, 13, 13, 14, 14, 13, 13, 13, 14, 11, - 6, 10, 9, 10, 10, 11, 11, 11, 10, 11, 10, 11, 11, 11, 11, 9, - 6, 9, 10, 10, 10, 11, 12, 11, 10, 12, 11, 11, 11, 11, 11, 8, - 9, 11, 12, 12, 12, 13, 13, 13, 12, 14, 14, 13, 13, 13, 13, 10, - 9, 13, 11, 13, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 14, 12, - 9, 12, 12, 12, 12, 14, 14, 13, 13, 14, 13, 13, 13, 14, 13, 11, - 8, 12, 12, 11, 12, 14, 14, 12, 13, 14, 14, 13, 13, 13, 14, 11, - 6, 10, 10, 11, 9, 10, 12, 11, 10, 12, 11, 11, 10, 11, 11, 9, - 7, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, 11, 11, 11, 9, - 9, 12, 13, 13, 12, 12, 14, 13, 13, 14, 14, 13, 14, 13, 14, 11, - 8, 11, 11, 12, 11, 12, 12, 12, 11, 13, 12, 12, 12, 12, 12, 10, - 7, 10, 10, 11, 10, 11, 12, 11, 10, 12, 11, 11, 11, 11, 11, 8, - 9, 11, 12, 12, 12, 12, 13, 12, 12, 13, 13, 12, 13, 12, 13, 10, - 10, 13, 13, 14, 14, 14, 15, 14, 14, 15, 14, 15, 14, 14, 14, 12, - 9, 12, 12, 13, 12, 13, 14, 13, 12, 13, 13, 12, 13, 13, 13, 10, - 9, 12, 12, 12, 12, 13, 14, 12, 12, 14, 13, 12, 13, 13, 13, 10, - 9, 12, 13, 13, 11, 13, 14, 13, 13, 14, 14, 14, 12, 13, 13, 11, - 10, 12, 13, 13, 12, 12, 14, 13, 13, 14, 14, 14, 13, 13, 14, 11, - 10, 13, 14, 14, 13, 12, 15, 13, 14, 14, 14, 14, 15, 13, 14, 11, - 11, 14, 14, 14, 13, 14, 15, 14, 14, 15, 15, 14, 13, 14, 14, 12, - 10, 13, 12, 13, 12, 12, 14, 13, 13, 14, 13, 13, 13, 13, 13, 10, - 10, 12, 13, 13, 13, 12, 14, 12, 13, 14, 14, 13, 13, 13, 13, 10, - 13, 15, 16, 16, 15, 15, 16, 16, 15, 16, 15, 16, 16, 16, 16, 14, - 11, 14, 14, 14, 14, 14, 15, 14, 14, 15, 15, 14, 14, 14, 15, 11, - 10, 13, 13, 13, 13, 13, 14, 12, 13, 14, 14, 13, 13, 13, 13, 10, - 6, 10, 10, 11, 10, 11, 12, 11, 10, 12, 10, 11, 10, 11, 11, 9, - 8, 11, 11, 12, 11, 12, 13, 12, 11, 12, 12, 12, 12, 12, 12, 10, - 11, 13, 14, 14, 13, 14, 15, 14, 13, 15, 15, 14, 14, 14, 15, 12, - 7, 11, 10, 12, 11, 12, 12, 12, 11, 12, 11, 12, 11, 12, 12, 10, - 7, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, 11, 11, 11, 9, - 10, 12, 13, 13, 12, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 10, - 10, 13, 12, 14, 13, 14, 14, 14, 13, 14, 12, 14, 15, 14, 14, 11, - 10, 12, 12, 12, 12, 13, 14, 13, 13, 14, 13, 12, 13, 13, 13, 10, - 9, 12, 13, 13, 13, 14, 14, 13, 13, 14, 14, 13, 13, 13, 13, 10, - 7, 10, 10, 11, 10, 11, 12, 11, 10, 12, 12, 11, 9, 11, 11, 9, - 7, 10, 11, 11, 10, 11, 12, 11, 10, 12, 12, 11, 11, 11, 11, 9, - 10, 12, 13, 13, 13, 13, 15, 13, 13, 14, 13, 13, 13, 13, 13, 10, - 8, 11, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 11, 12, 11, 9, - 6, 9, 9, 10, 9, 10, 10, 10, 9, 11, 10, 10, 9, 10, 10, 7, - 8, 10, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 11, 11, 11, 8, - 10, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 13, 13, 13, 13, 11, - 8, 11, 11, 11, 11, 12, 12, 11, 11, 12, 11, 11, 11, 11, 11, 8, - 8, 11, 11, 11, 11, 12, 12, 10, 11, 12, 12, 11, 11, 11, 11, 8, - 10, 13, 13, 13, 12, 13, 14, 13, 12, 14, 14, 14, 10, 13, 13, 11, - 10, 12, 12, 13, 12, 13, 14, 12, 12, 13, 13, 13, 12, 12, 13, 10, - 11, 13, 14, 14, 13, 13, 14, 13, 13, 15, 14, 13, 13, 13, 13, 10, - 10, 12, 13, 13, 12, 13, 14, 13, 13, 14, 14, 13, 12, 13, 13, 11, - 8, 11, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 11, 11, 11, 8, - 9, 11, 12, 12, 11, 11, 12, 11, 12, 12, 12, 11, 12, 11, 11, 8, - 12, 15, 14, 14, 14, 15, 15, 14, 14, 15, 15, 14, 14, 14, 15, 12, - 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 13, 12, 12, 12, 12, 9, - 9, 11, 11, 11, 11, 11, 12, 10, 11, 12, 12, 11, 11, 11, 11, 7, - 10, 13, 13, 13, 13, 14, 15, 14, 13, 14, 14, 14, 12, 14, 15, 12, - 11, 14, 14, 14, 14, 15, 15, 14, 14, 15, 15, 15, 14, 15, 15, 12, - 13, 16, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 14, - 10, 13, 13, 14, 13, 15, 14, 14, 13, 15, 13, 14, 14, 14, 14, 12, - 10, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 14, 11, - 12, 14, 14, 14, 14, 15, 15, 14, 14, 15, 15, 14, 15, 14, 14, 12, - 11, 14, 14, 15, 14, 15, 15, 14, 14, 15, 12, 14, 15, 16, 15, 12, - 11, 13, 13, 14, 13, 14, 14, 14, 14, 14, 13, 13, 14, 14, 14, 11, - 11, 14, 14, 14, 14, 15, 15, 14, 14, 16, 14, 13, 14, 14, 14, 11, - 10, 13, 13, 13, 12, 14, 14, 14, 12, 15, 14, 14, 11, 13, 13, 12, - 10, 12, 13, 14, 12, 13, 14, 13, 13, 14, 14, 13, 12, 13, 13, 11, - 12, 14, 14, 15, 14, 15, 16, 15, 15, 15, 15, 15, 14, 14, 15, 12, - 10, 13, 13, 13, 12, 13, 14, 13, 13, 14, 13, 13, 12, 13, 13, 11, - 9, 11, 11, 12, 11, 12, 12, 11, 11, 12, 12, 11, 11, 11, 11, 9, - 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 13, 12, 13, 12, 12, 9, - 11, 13, 13, 15, 14, 14, 15, 14, 14, 15, 14, 14, 14, 14, 14, 11, - 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 11, 11, 12, 12, 12, 8, - 9, 12, 12, 11, 12, 12, 13, 11, 12, 12, 12, 11, 12, 11, 11, 8, - 10, 13, 13, 14, 12, 14, 15, 14, 13, 15, 15, 14, 10, 13, 13, 11, - 11, 13, 14, 13, 13, 14, 14, 13, 13, 14, 14, 14, 11, 13, 13, 11, - 12, 14, 14, 14, 14, 14, 15, 14, 15, 16, 15, 14, 13, 13, 14, 11, - 11, 14, 13, 14, 13, 14, 15, 14, 13, 15, 14, 14, 11, 13, 13, 11, - 9, 12, 12, 12, 11, 12, 13, 11, 12, 13, 12, 11, 10, 11, 11, 8, - 10, 12, 12, 12, 12, 12, 13, 11, 12, 12, 12, 11, 11, 11, 11, 8, - 12, 15, 14, 15, 14, 15, 16, 15, 15, 15, 15, 14, 14, 14, 14, 12, - 10, 12, 12, 12, 12, 12, 13, 11, 12, 13, 12, 11, 11, 11, 11, 8, - 8, 10, 10, 10, 10, 10, 11, 9, 10, 11, 10, 9, 10, 9, 9, 5, - }, - }, - { - { - 12, 12, 11, 9, 11, 10, 11, 9, 11, 11, 10, 9, 9, 8, 9, 5, - 14, 13, 14, 11, 14, 11, 13, 10, 14, 13, 12, 10, 12, 10, 11, 6, - 16, 13, 16, 12, 16, 12, 16, 11, 16, 14, 16, 12, 15, 12, 13, 8, - 14, 14, 12, 11, 14, 12, 13, 10, 13, 13, 11, 10, 12, 11, 10, 6, - 16, 15, 14, 11, 16, 13, 14, 10, 15, 14, 13, 10, 13, 11, 11, 7, - 16, 16, 16, 11, 16, 14, 16, 11, 16, 16, 15, 12, 15, 13, 13, 8, - 16, 16, 13, 12, 16, 16, 15, 12, 16, 16, 12, 11, 15, 13, 12, 8, - 16, 16, 14, 11, 16, 16, 16, 11, 16, 16, 14, 11, 15, 14, 13, 8, - 16, 16, 15, 10, 16, 16, 16, 10, 16, 16, 15, 11, 16, 14, 14, 8, - 14, 14, 14, 12, 13, 11, 13, 10, 13, 13, 12, 11, 11, 10, 10, 6, - 16, 15, 16, 13, 13, 11, 14, 11, 15, 14, 13, 11, 12, 10, 11, 7, - 16, 15, 16, 14, 16, 11, 16, 11, 16, 16, 16, 13, 16, 12, 13, 8, - 16, 16, 14, 13, 15, 13, 14, 11, 14, 15, 13, 11, 13, 11, 11, 7, - 16, 16, 15, 13, 15, 13, 14, 11, 16, 15, 14, 11, 13, 11, 11, 7, - 16, 16, 16, 13, 16, 13, 16, 11, 16, 16, 16, 12, 16, 12, 13, 8, - 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 14, 13, 15, 14, 13, 9, - 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 14, 12, 15, 13, 13, 8, - 16, 16, 16, 12, 16, 16, 16, 11, 16, 16, 15, 12, 16, 13, 13, 7, - 16, 16, 16, 16, 13, 12, 16, 12, 16, 16, 14, 13, 12, 11, 12, 8, - 16, 16, 16, 15, 14, 11, 16, 11, 16, 16, 16, 13, 14, 11, 13, 8, - 16, 16, 16, 16, 15, 10, 16, 11, 16, 16, 16, 14, 15, 11, 13, 8, - 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 14, 14, 14, 12, 13, 9, - 16, 16, 16, 15, 16, 13, 16, 12, 16, 16, 16, 13, 14, 12, 13, 8, - 16, 16, 16, 14, 16, 12, 16, 11, 16, 16, 16, 13, 15, 12, 13, 7, - 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 16, 14, 13, 9, - 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 14, 16, 13, 13, 8, - 16, 16, 16, 14, 16, 14, 16, 10, 16, 16, 16, 13, 16, 13, 13, 7, - 14, 14, 13, 12, 13, 12, 13, 11, 12, 13, 11, 10, 11, 10, 10, 6, - 16, 16, 15, 13, 16, 13, 15, 11, 14, 14, 13, 11, 13, 11, 11, 7, - 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 16, 13, 16, 13, 14, 9, - 16, 16, 13, 13, 15, 14, 14, 11, 13, 14, 11, 11, 12, 11, 11, 7, - 16, 16, 15, 12, 16, 14, 15, 11, 14, 14, 12, 11, 13, 11, 11, 7, - 16, 16, 16, 13, 16, 14, 16, 12, 16, 16, 14, 12, 16, 13, 13, 8, - 16, 16, 14, 14, 16, 16, 16, 13, 16, 16, 12, 11, 15, 13, 12, 8, - 16, 16, 15, 13, 16, 16, 16, 12, 16, 16, 13, 11, 16, 13, 12, 8, - 16, 16, 16, 11, 16, 16, 16, 11, 16, 16, 14, 11, 16, 14, 13, 7, - 16, 16, 15, 13, 14, 13, 14, 11, 14, 14, 12, 11, 11, 10, 11, 7, - 16, 16, 16, 13, 14, 12, 15, 11, 15, 14, 13, 11, 12, 11, 11, 7, - 16, 16, 16, 14, 16, 13, 16, 12, 16, 16, 16, 13, 14, 12, 13, 8, - 16, 16, 15, 13, 15, 14, 14, 12, 14, 14, 12, 11, 12, 11, 11, 7, - 16, 16, 14, 12, 15, 13, 14, 11, 15, 14, 13, 11, 12, 11, 11, 6, - 16, 16, 16, 13, 16, 13, 16, 11, 16, 15, 14, 11, 14, 11, 12, 6, - 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 13, 12, 14, 13, 12, 8, - 16, 16, 15, 13, 16, 14, 15, 11, 16, 16, 13, 11, 14, 12, 11, 6, - 16, 16, 16, 12, 16, 14, 15, 11, 16, 16, 13, 10, 14, 12, 12, 6, - 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 14, 13, 12, 11, 12, 8, - 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 15, 13, 13, 11, 12, 8, - 16, 16, 16, 15, 16, 12, 16, 12, 16, 16, 16, 14, 14, 11, 13, 7, - 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 14, 13, 13, 12, 12, 8, - 16, 16, 16, 14, 15, 13, 15, 11, 16, 15, 14, 12, 13, 11, 11, 6, - 16, 16, 16, 14, 16, 12, 15, 11, 16, 16, 15, 12, 14, 11, 12, 6, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 15, 13, 14, 13, 12, 8, - 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 14, 12, 13, 12, 11, 6, - 16, 16, 16, 13, 16, 13, 15, 10, 16, 16, 14, 11, 14, 11, 11, 5, - 16, 16, 15, 14, 16, 16, 16, 13, 14, 14, 12, 12, 12, 12, 12, 8, - 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, 13, 14, 13, 13, 9, - 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 16, 13, 15, 9, - 16, 16, 14, 15, 16, 16, 16, 14, 14, 16, 12, 12, 13, 13, 12, 8, - 16, 16, 16, 14, 16, 16, 16, 13, 16, 15, 13, 12, 14, 12, 12, 8, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 14, 12, 16, 13, 13, 8, - 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 11, 11, 15, 14, 12, 8, - 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 12, 11, 15, 13, 12, 8, - 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 13, 10, 16, 13, 12, 7, - 16, 16, 16, 16, 16, 15, 16, 13, 14, 16, 13, 13, 12, 12, 12, 8, - 16, 16, 16, 15, 16, 14, 16, 13, 16, 16, 14, 13, 13, 12, 12, 8, - 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 16, 13, 15, 12, 14, 8, - 16, 16, 16, 15, 16, 16, 16, 13, 14, 16, 13, 12, 12, 12, 11, 8, - 16, 16, 16, 14, 16, 14, 16, 12, 14, 14, 13, 11, 13, 11, 11, 6, - 16, 16, 16, 14, 16, 14, 16, 12, 16, 15, 14, 11, 14, 11, 12, 6, - 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 12, 12, 14, 13, 11, 8, - 16, 16, 15, 14, 16, 16, 16, 12, 16, 15, 12, 11, 13, 12, 11, 6, - 16, 16, 16, 13, 16, 14, 16, 11, 16, 14, 13, 10, 14, 11, 11, 5, - 16, 16, 16, 16, 16, 16, 16, 14, 14, 16, 15, 13, 11, 11, 11, 8, - 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 16, 13, 12, 11, 12, 7, - 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 13, 13, 11, 13, 7, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 14, 13, 12, 12, 11, 7, - 16, 16, 16, 15, 16, 14, 15, 12, 16, 14, 13, 12, 12, 11, 11, 6, - 16, 16, 16, 14, 16, 13, 15, 11, 16, 14, 14, 11, 13, 10, 11, 5, - 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 13, 12, 12, 12, 11, 7, - 16, 16, 16, 14, 16, 14, 15, 12, 16, 15, 12, 11, 12, 11, 10, 5, - 16, 16, 16, 13, 16, 13, 14, 10, 16, 14, 12, 9, 12, 10, 9, 3, - }, - { - 2, 6, 6, 7, 6, 7, 8, 7, 7, 8, 7, 8, 7, 8, 8, 5, - 5, 8, 9, 9, 9, 9, 12, 10, 10, 11, 10, 10, 10, 11, 11, 8, - 9, 10, 13, 12, 13, 12, 15, 13, 13, 14, 13, 14, 13, 13, 14, 11, - 5, 10, 9, 10, 10, 10, 12, 10, 10, 12, 10, 11, 11, 11, 11, 8, - 6, 9, 10, 9, 10, 11, 12, 10, 10, 12, 11, 11, 10, 11, 11, 8, - 9, 11, 12, 11, 12, 13, 14, 12, 13, 14, 14, 12, 13, 13, 13, 11, - 10, 13, 11, 12, 14, 14, 15, 13, 13, 15, 12, 13, 14, 14, 14, 12, - 9, 12, 12, 12, 13, 13, 15, 13, 13, 14, 13, 13, 14, 13, 15, 11, - 8, 11, 12, 10, 12, 13, 14, 12, 13, 14, 14, 13, 13, 13, 14, 11, - 5, 9, 10, 10, 9, 10, 12, 11, 10, 12, 11, 11, 9, 11, 11, 9, - 6, 10, 10, 11, 10, 10, 12, 11, 11, 12, 11, 11, 11, 11, 11, 9, - 9, 11, 13, 13, 12, 11, 14, 12, 13, 15, 13, 13, 14, 13, 14, 11, - 8, 11, 11, 12, 11, 12, 13, 12, 12, 13, 12, 13, 12, 12, 12, 10, - 7, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, 11, 11, 12, 9, - 9, 12, 12, 12, 12, 12, 14, 12, 13, 14, 13, 13, 13, 13, 13, 11, - 11, 14, 13, 15, 15, 16, 16, 15, 15, 16, 15, 15, 16, 16, 15, 13, - 10, 12, 13, 13, 13, 14, 15, 13, 13, 14, 13, 13, 14, 14, 14, 11, - 9, 12, 12, 12, 13, 13, 14, 12, 13, 14, 14, 13, 13, 13, 14, 11, - 9, 13, 13, 13, 11, 12, 15, 13, 13, 15, 14, 14, 11, 13, 14, 11, - 10, 13, 13, 13, 12, 12, 15, 13, 13, 15, 14, 14, 13, 13, 14, 11, - 10, 12, 13, 13, 12, 11, 14, 12, 13, 15, 13, 13, 13, 13, 14, 11, - 11, 14, 15, 15, 13, 14, 16, 14, 14, 16, 16, 14, 14, 15, 15, 13, - 10, 13, 13, 13, 12, 13, 14, 13, 13, 14, 14, 14, 13, 13, 14, 11, - 10, 12, 13, 13, 13, 12, 14, 13, 13, 14, 14, 13, 13, 13, 13, 11, - 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 12, 15, 15, 15, 14, 15, 16, 14, 15, 16, 16, 15, 16, 15, 15, 13, - 10, 12, 12, 12, 13, 13, 14, 12, 13, 14, 13, 13, 13, 13, 13, 11, - 6, 10, 10, 11, 10, 11, 12, 11, 10, 12, 11, 11, 10, 11, 11, 9, - 8, 11, 12, 12, 12, 12, 13, 12, 12, 13, 12, 13, 12, 13, 13, 10, - 11, 13, 15, 14, 15, 14, 16, 14, 15, 16, 16, 14, 15, 15, 15, 13, - 7, 11, 10, 12, 11, 11, 13, 11, 11, 13, 10, 11, 12, 12, 12, 10, - 7, 11, 11, 11, 11, 11, 13, 11, 11, 13, 11, 12, 12, 12, 12, 9, - 10, 12, 13, 13, 13, 13, 15, 13, 14, 15, 14, 14, 14, 14, 15, 11, - 10, 13, 12, 14, 14, 14, 15, 13, 13, 15, 12, 13, 15, 15, 14, 12, - 10, 13, 12, 12, 13, 13, 15, 14, 13, 15, 13, 13, 14, 14, 14, 11, - 10, 13, 13, 12, 13, 14, 15, 13, 13, 15, 13, 13, 14, 14, 14, 11, - 7, 10, 11, 11, 10, 11, 12, 11, 10, 12, 12, 12, 9, 11, 12, 9, - 7, 11, 11, 11, 11, 11, 13, 11, 11, 13, 12, 12, 11, 12, 12, 9, - 10, 12, 14, 13, 13, 13, 16, 13, 14, 16, 14, 14, 13, 13, 14, 11, - 8, 11, 11, 12, 11, 12, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, - 6, 9, 9, 10, 9, 10, 11, 10, 10, 11, 10, 10, 10, 10, 10, 8, - 8, 11, 11, 11, 12, 11, 13, 11, 12, 13, 12, 12, 12, 12, 12, 10, - 11, 14, 13, 14, 14, 14, 16, 14, 14, 16, 14, 14, 15, 15, 14, 12, - 9, 12, 11, 12, 12, 12, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, - 8, 11, 11, 11, 11, 11, 13, 11, 12, 12, 12, 12, 12, 12, 12, 9, - 10, 13, 14, 13, 11, 13, 14, 14, 13, 15, 15, 14, 10, 13, 14, 11, - 10, 13, 13, 13, 12, 13, 14, 13, 13, 14, 14, 14, 13, 13, 13, 11, - 10, 13, 14, 13, 13, 12, 15, 13, 14, 15, 14, 14, 14, 13, 14, 12, - 11, 14, 14, 14, 13, 13, 15, 14, 14, 15, 14, 15, 13, 14, 14, 12, - 9, 11, 12, 12, 11, 11, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, - 9, 11, 12, 12, 12, 11, 13, 11, 12, 13, 12, 12, 12, 12, 12, 10, - 13, 15, 15, 16, 15, 16, 16, 15, 16, 16, 16, 15, 15, 15, 16, 14, - 10, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 11, - 8, 11, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 12, 11, 12, 9, - 11, 14, 14, 15, 14, 15, 15, 14, 13, 15, 14, 15, 12, 14, 15, 13, - 12, 15, 15, 15, 15, 15, 16, 15, 15, 16, 16, 16, 15, 16, 15, 13, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 11, 14, 13, 15, 14, 14, 16, 14, 14, 16, 13, 14, 15, 14, 15, 12, - 11, 14, 13, 14, 14, 14, 16, 15, 14, 16, 14, 14, 15, 15, 15, 12, - 13, 15, 15, 15, 15, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 13, - 11, 14, 13, 14, 14, 14, 15, 14, 14, 16, 12, 14, 16, 16, 14, 12, - 11, 14, 14, 14, 14, 15, 16, 15, 14, 16, 13, 14, 16, 15, 14, 12, - 12, 14, 14, 14, 14, 14, 16, 14, 15, 16, 14, 14, 14, 15, 15, 12, - 11, 14, 14, 14, 13, 14, 16, 15, 13, 16, 15, 15, 11, 14, 14, 12, - 11, 14, 14, 15, 14, 14, 16, 14, 14, 15, 14, 14, 13, 15, 15, 12, - 13, 15, 16, 15, 15, 15, 16, 15, 16, 16, 16, 16, 15, 15, 16, 13, - 11, 14, 14, 14, 14, 14, 15, 14, 14, 16, 14, 14, 14, 15, 14, 12, - 9, 12, 12, 12, 12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 12, 10, - 11, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 14, 13, 13, 14, 11, - 12, 15, 14, 15, 15, 15, 16, 15, 14, 16, 14, 14, 16, 16, 14, 13, - 10, 12, 12, 12, 12, 12, 14, 12, 13, 13, 12, 12, 13, 13, 13, 10, - 10, 12, 12, 12, 12, 12, 14, 12, 12, 13, 12, 12, 12, 12, 12, 10, - 10, 14, 14, 14, 12, 14, 16, 14, 13, 16, 16, 16, 10, 13, 14, 12, - 11, 14, 14, 14, 13, 14, 16, 14, 14, 16, 15, 14, 12, 13, 14, 12, - 12, 14, 14, 14, 14, 14, 16, 14, 14, 16, 15, 15, 14, 14, 15, 12, - 12, 14, 15, 15, 14, 15, 16, 14, 15, 15, 15, 15, 13, 15, 14, 12, - 9, 12, 12, 12, 12, 13, 13, 12, 12, 13, 13, 12, 11, 12, 12, 10, - 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, - 13, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 15, 16, 15, 13, - 10, 12, 12, 13, 12, 13, 13, 12, 13, 14, 13, 13, 12, 13, 13, 10, - 7, 10, 10, 10, 10, 10, 11, 10, 10, 11, 10, 10, 10, 10, 10, 7, - }, - }, - { - { - 10, 10, 9, 8, 9, 8, 9, 7, 9, 9, 8, 7, 8, 7, 7, 4, - 13, 11, 12, 9, 12, 9, 12, 9, 12, 11, 11, 9, 10, 9, 9, 6, - 15, 12, 15, 11, 14, 10, 14, 10, 14, 13, 13, 11, 13, 11, 12, 7, - 13, 12, 11, 9, 12, 11, 12, 9, 12, 12, 10, 9, 10, 10, 9, 6, - 14, 13, 12, 10, 13, 12, 13, 9, 13, 12, 11, 10, 12, 11, 10, 6, - 16, 14, 14, 10, 15, 13, 14, 10, 15, 15, 14, 11, 14, 12, 12, 8, - 15, 14, 12, 11, 15, 14, 13, 11, 14, 14, 11, 10, 13, 12, 11, 8, - 15, 16, 13, 11, 16, 14, 14, 11, 15, 15, 12, 10, 14, 13, 12, 8, - 16, 15, 14, 10, 16, 14, 14, 10, 16, 15, 14, 10, 14, 13, 12, 7, - 13, 12, 12, 11, 11, 9, 12, 9, 12, 12, 11, 10, 10, 9, 9, 6, - 13, 13, 14, 12, 12, 10, 12, 10, 14, 13, 12, 11, 11, 10, 10, 7, - 16, 14, 16, 13, 14, 11, 15, 10, 16, 15, 14, 12, 14, 11, 12, 8, - 14, 14, 13, 12, 13, 12, 13, 10, 13, 13, 12, 11, 11, 10, 10, 7, - 15, 14, 14, 12, 14, 12, 13, 10, 14, 13, 12, 11, 12, 11, 11, 7, - 16, 15, 16, 13, 15, 13, 15, 10, 16, 15, 14, 12, 14, 12, 12, 7, - 15, 16, 14, 13, 16, 14, 14, 12, 15, 15, 12, 12, 13, 12, 12, 8, - 16, 16, 14, 13, 16, 14, 14, 11, 15, 15, 14, 11, 14, 12, 12, 8, - 16, 16, 15, 12, 16, 14, 15, 10, 16, 16, 13, 12, 14, 13, 12, 7, - 14, 14, 14, 13, 13, 11, 13, 11, 14, 14, 13, 12, 11, 10, 11, 8, - 16, 15, 16, 13, 13, 11, 14, 11, 15, 14, 14, 13, 12, 11, 12, 8, - 15, 15, 16, 14, 14, 10, 14, 10, 16, 15, 15, 13, 14, 10, 12, 8, - 16, 16, 16, 14, 15, 13, 14, 12, 15, 15, 13, 13, 13, 12, 12, 8, - 16, 16, 16, 14, 15, 13, 14, 11, 16, 16, 14, 13, 13, 12, 12, 8, - 16, 16, 16, 14, 16, 12, 15, 11, 16, 15, 15, 13, 14, 12, 12, 8, - 16, 16, 16, 16, 16, 15, 15, 13, 16, 16, 14, 13, 14, 13, 12, 9, - 16, 16, 16, 14, 16, 15, 15, 11, 16, 16, 14, 13, 15, 13, 12, 8, - 16, 16, 16, 14, 16, 14, 14, 10, 16, 16, 15, 13, 14, 12, 12, 7, - 12, 12, 12, 11, 12, 11, 12, 10, 11, 11, 10, 9, 9, 9, 9, 6, - 14, 13, 14, 12, 13, 12, 13, 10, 13, 13, 12, 10, 12, 10, 11, 7, - 16, 14, 16, 13, 15, 13, 16, 12, 15, 14, 14, 12, 14, 12, 13, 8, - 14, 14, 13, 11, 14, 12, 13, 11, 12, 12, 10, 10, 11, 10, 10, 7, - 14, 14, 13, 12, 14, 12, 13, 11, 13, 13, 12, 10, 12, 11, 10, 7, - 16, 15, 15, 12, 16, 14, 15, 11, 16, 14, 13, 11, 14, 12, 12, 8, - 16, 16, 13, 13, 16, 15, 14, 12, 14, 14, 11, 11, 13, 12, 11, 8, - 16, 16, 14, 12, 16, 14, 14, 12, 15, 14, 12, 11, 14, 12, 12, 8, - 16, 15, 14, 11, 16, 15, 15, 11, 16, 15, 13, 11, 14, 13, 12, 8, - 14, 13, 13, 12, 13, 11, 13, 10, 12, 13, 11, 10, 10, 10, 10, 7, - 15, 14, 14, 13, 13, 12, 13, 11, 14, 13, 12, 11, 12, 10, 11, 7, - 16, 15, 16, 14, 15, 12, 15, 11, 16, 14, 14, 12, 14, 11, 12, 8, - 14, 15, 13, 12, 14, 13, 13, 11, 13, 13, 11, 11, 11, 10, 10, 7, - 14, 14, 14, 12, 14, 13, 13, 10, 14, 13, 12, 10, 12, 10, 10, 6, - 16, 15, 15, 13, 16, 13, 15, 11, 15, 14, 13, 11, 13, 11, 11, 7, - 16, 16, 14, 13, 16, 15, 14, 12, 15, 15, 12, 11, 13, 12, 11, 8, - 16, 16, 14, 13, 16, 14, 14, 11, 15, 14, 12, 11, 13, 12, 11, 7, - 16, 16, 15, 12, 16, 14, 14, 11, 15, 15, 13, 11, 14, 12, 11, 6, - 16, 15, 15, 14, 14, 12, 14, 12, 13, 14, 13, 12, 11, 11, 11, 8, - 16, 16, 16, 14, 14, 12, 15, 12, 15, 14, 14, 12, 12, 11, 12, 8, - 16, 16, 16, 15, 14, 12, 15, 12, 16, 15, 14, 13, 13, 11, 12, 8, - 16, 16, 16, 15, 15, 14, 15, 12, 14, 14, 13, 12, 12, 11, 11, 8, - 16, 16, 15, 14, 14, 12, 14, 11, 14, 14, 13, 12, 12, 11, 11, 7, - 16, 16, 16, 14, 15, 12, 14, 11, 15, 15, 14, 12, 13, 11, 12, 7, - 16, 16, 16, 16, 16, 15, 16, 13, 15, 15, 14, 12, 13, 12, 11, 8, - 16, 16, 16, 14, 15, 14, 14, 12, 16, 15, 13, 12, 13, 12, 11, 7, - 16, 16, 16, 13, 16, 13, 14, 10, 16, 15, 14, 11, 13, 11, 11, 6, - 14, 15, 13, 13, 14, 13, 14, 12, 12, 13, 11, 11, 11, 11, 10, 8, - 16, 16, 15, 13, 16, 14, 16, 13, 14, 14, 13, 12, 13, 12, 12, 8, - 16, 16, 16, 14, 16, 14, 16, 13, 16, 14, 15, 13, 15, 13, 13, 9, - 15, 15, 14, 14, 15, 14, 14, 12, 13, 14, 11, 11, 12, 12, 11, 8, - 15, 16, 15, 13, 15, 14, 14, 12, 14, 14, 12, 11, 13, 12, 12, 8, - 16, 16, 16, 13, 16, 15, 15, 13, 16, 15, 14, 11, 15, 12, 13, 8, - 16, 16, 14, 13, 16, 15, 15, 13, 14, 14, 10, 11, 14, 12, 11, 8, - 16, 16, 15, 13, 16, 16, 15, 13, 15, 14, 12, 11, 14, 13, 12, 8, - 16, 16, 15, 13, 16, 15, 16, 12, 16, 14, 13, 10, 15, 13, 12, 7, - 15, 15, 15, 14, 14, 14, 15, 12, 13, 14, 12, 12, 11, 11, 11, 8, - 16, 15, 16, 14, 15, 13, 15, 12, 14, 14, 13, 12, 12, 11, 12, 8, - 16, 16, 16, 15, 16, 14, 16, 13, 16, 15, 14, 12, 14, 11, 13, 8, - 16, 16, 15, 14, 16, 14, 15, 13, 14, 14, 12, 11, 12, 11, 11, 8, - 15, 16, 15, 14, 15, 14, 14, 12, 14, 13, 12, 11, 12, 11, 11, 7, - 16, 16, 16, 14, 16, 13, 16, 12, 15, 14, 13, 11, 13, 11, 12, 7, - 16, 16, 15, 14, 16, 15, 15, 13, 14, 15, 11, 11, 13, 12, 11, 8, - 16, 16, 15, 13, 16, 14, 15, 12, 15, 14, 12, 11, 13, 11, 11, 7, - 16, 16, 15, 13, 16, 14, 16, 12, 15, 14, 13, 10, 13, 11, 11, 6, - 16, 16, 16, 14, 14, 14, 15, 13, 14, 14, 14, 12, 11, 11, 11, 8, - 16, 16, 16, 14, 15, 14, 16, 13, 15, 14, 14, 13, 12, 11, 11, 7, - 16, 16, 16, 16, 15, 13, 16, 12, 15, 15, 14, 12, 13, 10, 12, 7, - 16, 16, 16, 14, 15, 15, 14, 13, 14, 14, 13, 12, 12, 11, 11, 8, - 16, 15, 16, 14, 16, 13, 15, 12, 14, 14, 13, 12, 12, 10, 10, 6, - 16, 15, 16, 14, 16, 13, 16, 11, 16, 14, 13, 11, 13, 10, 11, 6, - 16, 16, 16, 15, 16, 16, 15, 13, 14, 16, 12, 12, 12, 12, 10, 7, - 16, 16, 16, 14, 16, 14, 14, 12, 15, 15, 12, 11, 12, 11, 10, 6, - 16, 16, 16, 13, 16, 13, 15, 10, 15, 14, 13, 10, 13, 10, 10, 4, - }, - { - 1, 6, 6, 7, 6, 7, 9, 8, 7, 9, 7, 8, 7, 8, 8, 6, - 6, 9, 10, 10, 10, 10, 12, 11, 10, 12, 11, 11, 11, 11, 12, 9, - 9, 10, 13, 11, 13, 12, 14, 13, 14, 14, 14, 14, 14, 14, 14, 12, - 6, 10, 9, 10, 10, 11, 13, 11, 11, 13, 10, 12, 11, 12, 12, 9, - 6, 10, 10, 10, 10, 11, 13, 11, 11, 13, 12, 12, 11, 12, 12, 9, - 9, 11, 13, 12, 13, 14, 15, 13, 14, 16, 14, 14, 14, 14, 15, 12, - 10, 13, 11, 13, 14, 14, 16, 14, 14, 15, 13, 14, 15, 15, 16, 12, - 9, 13, 12, 12, 14, 14, 16, 14, 14, 15, 14, 14, 15, 15, 15, 12, - 8, 11, 12, 11, 13, 14, 15, 13, 13, 15, 14, 14, 13, 15, 15, 11, - 6, 10, 10, 11, 9, 10, 13, 11, 10, 13, 11, 12, 10, 12, 12, 9, - 6, 10, 10, 11, 11, 10, 13, 11, 11, 13, 11, 12, 12, 12, 13, 10, - 9, 12, 13, 13, 13, 12, 16, 13, 14, 15, 14, 14, 15, 14, 15, 12, - 8, 12, 12, 13, 12, 13, 15, 14, 13, 15, 13, 14, 13, 13, 14, 11, - 7, 11, 11, 12, 11, 12, 13, 12, 12, 13, 12, 13, 12, 13, 13, 10, - 9, 12, 13, 13, 13, 13, 16, 13, 13, 15, 14, 14, 14, 15, 15, 12, - 11, 15, 14, 15, 15, 16, 16, 16, 15, 16, 15, 16, 16, 16, 16, 14, - 10, 13, 13, 14, 14, 14, 16, 15, 14, 16, 15, 15, 15, 15, 16, 13, - 9, 12, 13, 13, 13, 14, 16, 14, 13, 15, 14, 14, 14, 16, 15, 12, - 10, 13, 14, 14, 11, 13, 16, 14, 14, 16, 15, 15, 12, 14, 15, 12, - 10, 13, 14, 14, 12, 12, 16, 15, 14, 16, 15, 15, 14, 14, 16, 12, - 9, 12, 13, 14, 13, 11, 16, 13, 14, 15, 13, 14, 14, 14, 15, 12, - 11, 15, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 13, 14, 14, 13, 14, 16, 15, 14, 16, 16, 16, 14, 15, 16, 13, - 10, 13, 13, 14, 13, 13, 16, 13, 13, 14, 14, 15, 15, 14, 15, 13, - 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 12, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 12, 13, 14, 13, 13, 14, 13, 13, 14, 13, 14, 14, 14, 15, 12, - 6, 10, 11, 11, 10, 11, 13, 12, 11, 13, 11, 12, 11, 12, 12, 10, - 8, 12, 13, 13, 12, 13, 14, 14, 13, 15, 14, 14, 14, 14, 15, 12, - 12, 14, 16, 15, 15, 15, 16, 15, 16, 16, 16, 16, 16, 16, 16, 14, - 7, 11, 11, 12, 12, 12, 14, 13, 12, 14, 11, 12, 13, 13, 13, 11, - 8, 11, 12, 12, 12, 12, 14, 13, 12, 14, 12, 13, 13, 14, 14, 11, - 11, 13, 14, 14, 14, 14, 16, 15, 15, 16, 15, 15, 16, 16, 16, 13, - 10, 14, 12, 14, 14, 15, 16, 15, 13, 16, 12, 14, 16, 16, 15, 13, - 10, 13, 13, 14, 14, 15, 16, 15, 14, 16, 14, 15, 15, 16, 16, 12, - 10, 13, 14, 13, 14, 14, 16, 15, 14, 16, 15, 15, 14, 16, 16, 13, - 7, 11, 11, 11, 10, 12, 14, 13, 11, 14, 13, 13, 10, 12, 13, 10, - 8, 11, 12, 12, 11, 12, 14, 13, 12, 15, 13, 13, 12, 13, 14, 11, - 11, 13, 14, 14, 14, 14, 16, 15, 14, 16, 15, 16, 16, 16, 16, 14, - 8, 12, 12, 13, 12, 13, 15, 14, 12, 15, 13, 13, 13, 14, 14, 11, - 6, 10, 10, 11, 10, 11, 13, 12, 11, 13, 11, 12, 11, 12, 12, 9, - 9, 12, 13, 13, 13, 13, 14, 13, 13, 15, 14, 14, 14, 14, 14, 12, - 11, 15, 14, 15, 14, 15, 16, 16, 16, 16, 15, 16, 16, 16, 16, 14, - 9, 13, 12, 13, 13, 13, 15, 14, 13, 14, 13, 14, 14, 15, 14, 12, - 9, 12, 12, 12, 12, 13, 14, 13, 13, 14, 13, 13, 13, 13, 14, 11, - 10, 13, 15, 14, 12, 14, 16, 14, 14, 16, 15, 15, 12, 14, 16, 12, - 10, 14, 14, 14, 13, 14, 16, 15, 14, 16, 16, 16, 13, 14, 16, 13, - 11, 13, 14, 14, 14, 13, 16, 14, 14, 16, 15, 15, 15, 15, 16, 13, - 11, 15, 15, 15, 14, 15, 16, 16, 15, 16, 16, 16, 14, 16, 16, 13, - 9, 13, 13, 13, 12, 13, 15, 14, 13, 15, 14, 14, 13, 14, 15, 11, - 9, 12, 12, 13, 12, 12, 14, 13, 13, 14, 13, 14, 14, 14, 14, 11, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 11, 14, 14, 15, 15, 14, 16, 16, 14, 16, 14, 15, 15, 16, 16, 12, - 9, 12, 12, 13, 12, 12, 14, 12, 12, 14, 13, 13, 13, 13, 14, 11, - 11, 14, 14, 16, 14, 16, 16, 16, 13, 16, 14, 16, 14, 16, 16, 13, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 15, 14, 16, 14, 15, 16, 16, 15, 16, 14, 15, 16, 16, 16, 13, - 11, 15, 14, 16, 15, 16, 16, 16, 15, 16, 15, 16, 16, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 11, 14, 13, 14, 15, 14, 16, 15, 14, 16, 12, 14, 16, 16, 15, 13, - 11, 14, 14, 16, 14, 15, 16, 16, 15, 16, 14, 15, 16, 16, 16, 14, - 12, 14, 14, 15, 14, 16, 16, 15, 14, 16, 15, 15, 15, 16, 16, 13, - 11, 14, 15, 15, 13, 15, 16, 16, 14, 16, 16, 16, 12, 15, 15, 13, - 11, 15, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 11, 15, 14, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 10, 13, 13, 14, 14, 14, 16, 15, 14, 16, 14, 15, 14, 14, 15, 12, - 12, 15, 14, 16, 14, 15, 16, 15, 15, 16, 15, 15, 16, 15, 16, 13, - 12, 16, 14, 16, 15, 16, 16, 16, 16, 16, 14, 15, 16, 16, 16, 14, - 10, 13, 13, 14, 14, 13, 16, 14, 13, 16, 13, 14, 15, 15, 15, 12, - 10, 13, 13, 14, 13, 13, 16, 14, 14, 15, 14, 14, 14, 14, 15, 12, - 10, 14, 15, 14, 13, 15, 16, 15, 14, 16, 16, 16, 11, 14, 16, 12, - 11, 14, 14, 16, 14, 15, 16, 15, 15, 16, 16, 16, 13, 15, 16, 13, - 12, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 15, 16, 13, - 12, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 13, - 10, 13, 14, 14, 13, 14, 16, 14, 13, 16, 15, 14, 12, 14, 16, 11, - 10, 13, 13, 14, 13, 14, 16, 14, 14, 15, 14, 14, 13, 14, 14, 11, - 13, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 11, 13, 14, 15, 14, 14, 16, 15, 14, 16, 14, 15, 14, 15, 16, 12, - 8, 11, 11, 11, 11, 12, 13, 12, 11, 13, 11, 12, 11, 12, 12, 9, - }, - }, - { - { - 8, 8, 8, 7, 8, 7, 8, 6, 8, 8, 7, 6, 7, 6, 6, 4, - 11, 10, 11, 9, 11, 9, 11, 8, 11, 10, 10, 9, 10, 8, 9, 6, - 13, 11, 13, 10, 12, 10, 13, 9, 13, 12, 13, 10, 12, 10, 11, 7, - 11, 11, 10, 9, 11, 10, 11, 9, 10, 11, 9, 8, 10, 9, 9, 6, - 12, 12, 11, 9, 12, 11, 12, 9, 12, 12, 11, 9, 11, 10, 10, 7, - 14, 13, 13, 10, 15, 12, 13, 10, 15, 13, 13, 10, 13, 12, 12, 8, - 13, 13, 11, 10, 14, 13, 12, 10, 13, 13, 10, 10, 12, 11, 10, 8, - 15, 14, 13, 10, 14, 13, 13, 10, 14, 13, 12, 10, 13, 12, 11, 8, - 14, 14, 13, 10, 16, 13, 13, 10, 15, 14, 13, 10, 13, 12, 12, 8, - 11, 11, 11, 10, 10, 9, 10, 9, 10, 10, 10, 9, 9, 8, 9, 6, - 12, 12, 12, 11, 11, 9, 12, 9, 12, 12, 11, 10, 11, 9, 10, 7, - 14, 13, 14, 12, 13, 10, 13, 10, 15, 13, 14, 12, 12, 10, 12, 8, - 13, 13, 12, 11, 12, 11, 12, 10, 12, 12, 11, 10, 11, 10, 10, 7, - 14, 13, 13, 11, 13, 12, 12, 10, 13, 13, 12, 11, 12, 10, 10, 7, - 16, 15, 15, 12, 14, 12, 13, 10, 15, 14, 13, 12, 13, 12, 12, 8, - 15, 15, 13, 13, 14, 14, 14, 12, 14, 14, 12, 11, 13, 12, 11, 8, - 15, 16, 14, 12, 15, 14, 13, 11, 15, 15, 13, 12, 13, 12, 11, 8, - 16, 15, 15, 12, 16, 14, 14, 10, 15, 15, 14, 12, 14, 12, 12, 8, - 13, 13, 13, 13, 11, 10, 12, 10, 12, 13, 12, 11, 10, 10, 10, 8, - 14, 13, 14, 13, 12, 10, 13, 10, 14, 14, 13, 12, 12, 10, 11, 8, - 15, 14, 16, 14, 13, 10, 14, 10, 16, 14, 14, 13, 13, 10, 12, 8, - 15, 15, 14, 14, 14, 13, 13, 12, 14, 14, 13, 12, 12, 11, 11, 9, - 15, 15, 15, 14, 14, 12, 14, 11, 15, 14, 13, 13, 13, 11, 11, 8, - 16, 15, 16, 14, 15, 12, 14, 11, 16, 16, 15, 13, 14, 12, 12, 8, - 16, 16, 16, 14, 15, 14, 14, 12, 15, 15, 14, 13, 13, 12, 11, 9, - 16, 16, 15, 15, 16, 14, 14, 11, 16, 16, 14, 13, 14, 12, 12, 8, - 16, 16, 16, 13, 15, 13, 14, 10, 16, 16, 15, 13, 14, 12, 12, 8, - 11, 11, 11, 10, 11, 10, 11, 9, 10, 10, 9, 8, 9, 9, 9, 6, - 12, 12, 13, 11, 12, 11, 12, 10, 12, 12, 11, 10, 11, 10, 10, 7, - 15, 13, 15, 12, 14, 13, 14, 11, 14, 13, 13, 11, 13, 11, 12, 8, - 12, 13, 12, 11, 13, 11, 12, 10, 11, 12, 10, 9, 11, 10, 10, 7, - 14, 13, 13, 11, 14, 12, 13, 11, 12, 12, 11, 10, 12, 11, 10, 7, - 15, 14, 15, 12, 15, 13, 15, 11, 15, 14, 13, 11, 13, 12, 12, 8, - 14, 14, 13, 12, 15, 14, 13, 12, 13, 13, 11, 10, 13, 12, 11, 8, - 16, 15, 13, 12, 15, 14, 14, 12, 14, 14, 12, 11, 14, 12, 11, 8, - 16, 15, 14, 12, 16, 15, 15, 11, 15, 14, 13, 11, 14, 13, 12, 8, - 12, 12, 12, 11, 12, 11, 12, 10, 11, 11, 11, 10, 10, 9, 9, 7, - 13, 13, 14, 12, 13, 11, 13, 11, 13, 12, 12, 11, 11, 10, 10, 7, - 15, 14, 16, 13, 14, 12, 14, 11, 14, 14, 14, 12, 13, 11, 12, 8, - 13, 13, 13, 12, 13, 12, 13, 11, 12, 12, 11, 10, 11, 10, 10, 7, - 14, 14, 13, 12, 13, 12, 13, 10, 13, 13, 11, 10, 12, 10, 10, 7, - 16, 15, 15, 13, 15, 12, 14, 11, 15, 14, 13, 11, 13, 11, 11, 7, - 15, 16, 14, 13, 15, 14, 14, 12, 14, 14, 12, 11, 13, 12, 11, 8, - 16, 15, 14, 13, 15, 14, 14, 11, 14, 14, 12, 11, 13, 12, 11, 7, - 16, 15, 15, 12, 16, 14, 14, 11, 15, 14, 13, 11, 14, 12, 11, 7, - 14, 15, 14, 14, 13, 12, 13, 12, 13, 13, 12, 12, 11, 10, 11, 8, - 15, 15, 15, 14, 13, 12, 14, 12, 14, 14, 13, 12, 12, 11, 11, 8, - 16, 15, 16, 14, 14, 12, 15, 12, 16, 14, 14, 13, 13, 11, 12, 8, - 15, 15, 15, 14, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 8, - 15, 15, 15, 14, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 7, - 16, 15, 16, 14, 15, 12, 15, 11, 15, 14, 14, 12, 13, 11, 12, 7, - 16, 16, 16, 15, 16, 15, 14, 13, 15, 15, 13, 12, 13, 12, 11, 9, - 16, 16, 16, 14, 15, 14, 14, 12, 15, 15, 13, 12, 14, 12, 11, 8, - 16, 16, 16, 14, 16, 14, 14, 11, 15, 15, 14, 12, 14, 12, 11, 7, - 13, 13, 13, 12, 13, 12, 13, 11, 11, 12, 11, 10, 10, 10, 10, 8, - 15, 14, 14, 13, 14, 13, 14, 12, 13, 13, 12, 11, 13, 11, 11, 8, - 16, 15, 16, 14, 16, 14, 16, 13, 15, 14, 14, 12, 14, 12, 13, 9, - 14, 15, 13, 13, 14, 13, 14, 12, 12, 13, 11, 11, 12, 11, 11, 8, - 15, 15, 14, 13, 15, 14, 14, 12, 13, 13, 12, 11, 13, 12, 11, 8, - 16, 16, 16, 13, 16, 15, 16, 13, 15, 14, 14, 12, 14, 13, 13, 9, - 14, 15, 13, 13, 16, 15, 15, 13, 13, 14, 11, 11, 13, 12, 11, 9, - 16, 16, 14, 13, 16, 15, 16, 13, 14, 14, 12, 11, 14, 13, 12, 8, - 16, 16, 15, 12, 16, 15, 15, 12, 15, 14, 13, 11, 14, 13, 12, 8, - 14, 14, 14, 13, 14, 13, 14, 12, 12, 13, 12, 11, 11, 11, 11, 8, - 15, 15, 15, 14, 14, 13, 15, 12, 14, 13, 13, 12, 12, 11, 11, 8, - 16, 16, 16, 15, 15, 14, 16, 13, 15, 14, 14, 12, 14, 12, 12, 9, - 15, 15, 14, 14, 14, 14, 14, 13, 13, 14, 12, 11, 12, 11, 11, 8, - 15, 15, 15, 13, 15, 14, 14, 12, 13, 13, 12, 11, 12, 11, 11, 7, - 16, 15, 16, 14, 16, 14, 15, 12, 15, 14, 14, 12, 13, 12, 12, 8, - 16, 16, 15, 14, 16, 15, 15, 13, 14, 14, 12, 11, 13, 12, 11, 8, - 16, 16, 15, 13, 16, 14, 14, 12, 14, 15, 12, 11, 13, 12, 11, 7, - 16, 16, 16, 13, 16, 15, 15, 12, 15, 14, 13, 11, 14, 12, 11, 7, - 15, 15, 15, 14, 13, 13, 14, 13, 13, 14, 13, 12, 11, 11, 11, 8, - 16, 16, 16, 14, 15, 13, 15, 12, 14, 14, 14, 13, 12, 11, 12, 8, - 16, 16, 16, 14, 15, 13, 15, 12, 15, 14, 14, 12, 13, 11, 12, 8, - 15, 16, 16, 14, 15, 14, 15, 13, 14, 14, 12, 12, 11, 11, 11, 8, - 16, 15, 15, 14, 15, 14, 14, 12, 14, 14, 13, 12, 12, 11, 11, 7, - 16, 16, 16, 13, 15, 13, 15, 12, 15, 14, 14, 12, 13, 11, 11, 7, - 16, 16, 16, 15, 15, 16, 15, 13, 14, 14, 12, 12, 12, 12, 11, 8, - 16, 16, 16, 14, 16, 14, 14, 12, 15, 15, 13, 11, 12, 11, 10, 7, - 16, 16, 15, 13, 16, 14, 14, 11, 15, 14, 13, 10, 13, 11, 10, 5, - }, - { - 1, 6, 6, 7, 6, 7, 9, 7, 6, 9, 7, 8, 7, 8, 8, 5, - 5, 8, 10, 10, 10, 10, 12, 11, 11, 12, 11, 11, 11, 12, 12, 9, - 9, 10, 12, 11, 13, 12, 15, 13, 14, 15, 15, 14, 14, 15, 15, 12, - 6, 10, 9, 10, 10, 11, 13, 12, 11, 13, 11, 12, 12, 12, 12, 10, - 6, 10, 10, 10, 11, 11, 13, 11, 11, 13, 12, 12, 11, 12, 12, 10, - 9, 12, 13, 12, 13, 13, 16, 13, 14, 16, 15, 14, 14, 15, 16, 12, - 9, 13, 11, 13, 14, 14, 16, 15, 14, 16, 13, 15, 15, 15, 15, 12, - 9, 13, 12, 13, 14, 15, 16, 15, 14, 16, 15, 15, 15, 15, 16, 12, - 8, 12, 12, 11, 13, 14, 15, 13, 13, 15, 14, 14, 14, 14, 14, 12, - 6, 10, 10, 11, 9, 10, 13, 11, 11, 13, 12, 12, 10, 12, 12, 9, - 6, 10, 11, 11, 11, 10, 13, 12, 11, 13, 12, 12, 12, 12, 13, 10, - 9, 12, 13, 13, 13, 12, 16, 13, 14, 16, 14, 15, 16, 14, 15, 12, - 8, 12, 13, 13, 13, 13, 16, 14, 13, 16, 13, 14, 14, 14, 14, 12, - 7, 11, 11, 12, 11, 12, 14, 13, 12, 14, 13, 13, 12, 13, 13, 11, - 9, 12, 13, 13, 13, 13, 15, 14, 14, 16, 16, 15, 15, 15, 16, 12, - 11, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 14, 14, 15, 15, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, - 9, 13, 13, 13, 14, 14, 16, 14, 14, 16, 15, 14, 14, 16, 16, 13, - 9, 13, 14, 14, 11, 13, 16, 14, 13, 16, 15, 16, 13, 14, 15, 12, - 10, 13, 14, 15, 13, 12, 16, 14, 14, 16, 15, 15, 14, 14, 16, 13, - 9, 12, 13, 14, 12, 11, 15, 13, 13, 15, 13, 14, 15, 14, 16, 12, - 11, 15, 16, 16, 14, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 13, - 11, 14, 14, 15, 13, 14, 16, 15, 15, 16, 16, 16, 16, 16, 16, 13, - 10, 12, 13, 14, 13, 13, 16, 14, 14, 14, 14, 16, 15, 14, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 9, 12, 13, 14, 13, 13, 16, 13, 13, 15, 15, 16, 15, 15, 16, 12, - 6, 11, 11, 12, 10, 12, 13, 12, 11, 13, 11, 12, 11, 12, 13, 10, - 9, 12, 13, 13, 13, 13, 16, 14, 14, 15, 14, 14, 14, 14, 14, 12, - 12, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 7, 11, 11, 12, 12, 12, 14, 13, 12, 14, 11, 13, 13, 13, 13, 11, - 8, 12, 12, 13, 12, 13, 14, 13, 13, 14, 13, 13, 13, 14, 14, 11, - 11, 14, 14, 15, 16, 15, 16, 16, 15, 16, 16, 16, 16, 16, 16, 13, - 10, 14, 12, 14, 15, 15, 16, 16, 14, 16, 12, 15, 16, 16, 16, 13, - 11, 14, 13, 15, 15, 15, 16, 16, 14, 16, 14, 14, 16, 16, 16, 13, - 11, 14, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 13, - 7, 11, 12, 11, 10, 12, 14, 13, 12, 14, 13, 13, 10, 12, 13, 10, - 8, 12, 12, 13, 12, 12, 15, 13, 13, 14, 13, 13, 13, 13, 14, 11, - 11, 13, 15, 16, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 9, 12, 13, 13, 13, 13, 15, 14, 13, 15, 13, 14, 13, 14, 14, 12, - 7, 11, 11, 11, 11, 11, 13, 12, 11, 13, 11, 12, 11, 12, 12, 10, - 9, 12, 13, 13, 13, 13, 16, 13, 14, 16, 15, 14, 14, 14, 16, 12, - 12, 14, 14, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 14, - 10, 13, 13, 14, 14, 14, 16, 15, 14, 16, 14, 14, 16, 15, 15, 12, - 9, 12, 13, 13, 13, 15, 16, 14, 13, 16, 14, 13, 13, 14, 14, 11, - 10, 14, 15, 14, 12, 14, 16, 15, 13, 16, 16, 16, 12, 14, 16, 12, - 11, 14, 14, 14, 14, 14, 16, 15, 15, 16, 16, 16, 14, 15, 16, 13, - 11, 14, 14, 16, 14, 13, 16, 15, 14, 16, 15, 16, 15, 15, 16, 13, - 12, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, - 10, 13, 14, 14, 13, 14, 16, 14, 13, 16, 15, 15, 13, 14, 14, 12, - 9, 12, 13, 14, 13, 12, 16, 14, 13, 16, 14, 14, 14, 14, 15, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 9, 12, 13, 13, 13, 13, 14, 13, 12, 15, 14, 14, 14, 14, 14, 11, - 11, 14, 14, 16, 14, 16, 16, 16, 13, 16, 14, 16, 14, 16, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 14, 14, 16, 16, 15, 16, 16, 15, 16, 14, 16, 16, 16, 16, 14, - 12, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 14, 12, 15, 15, 15, 16, 16, 14, 16, 12, 14, 16, 16, 15, 14, - 12, 15, 14, 16, 16, 16, 16, 16, 15, 16, 14, 16, 16, 16, 16, 14, - 12, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, - 11, 15, 15, 16, 14, 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 13, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 11, 15, 14, 16, 14, 14, 16, 15, 14, 16, 15, 16, 15, 16, 16, 12, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 12, 16, 15, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 14, - 10, 14, 13, 14, 15, 14, 16, 15, 14, 16, 13, 16, 16, 16, 15, 13, - 10, 14, 14, 14, 13, 14, 16, 15, 15, 16, 14, 14, 14, 16, 16, 12, - 10, 14, 15, 14, 13, 16, 16, 15, 13, 16, 16, 16, 12, 14, 16, 12, - 11, 16, 16, 16, 14, 15, 16, 16, 16, 16, 16, 16, 14, 16, 16, 13, - 12, 15, 14, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, - 11, 14, 14, 14, 14, 15, 16, 14, 14, 16, 16, 16, 13, 15, 15, 12, - 10, 14, 13, 14, 14, 14, 16, 15, 14, 16, 15, 15, 14, 14, 16, 12, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 12, 14, 14, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 13, - 8, 11, 11, 12, 12, 12, 13, 12, 11, 13, 12, 12, 12, 13, 12, 10, - }, - }, - { - { - 5, 6, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 6, 4, - 9, 9, 9, 8, 9, 8, 10, 8, 10, 10, 9, 9, 9, 8, 9, 6, - 11, 10, 12, 10, 11, 10, 12, 9, 12, 11, 11, 10, 11, 10, 11, 8, - 9, 10, 9, 8, 10, 10, 10, 9, 9, 10, 8, 8, 9, 9, 8, 7, - 10, 11, 10, 9, 11, 11, 11, 9, 11, 11, 10, 9, 10, 10, 10, 7, - 13, 12, 12, 10, 13, 12, 13, 10, 13, 12, 12, 11, 13, 12, 11, 9, - 11, 12, 10, 10, 12, 12, 11, 10, 11, 12, 10, 10, 11, 11, 10, 8, - 12, 12, 11, 10, 13, 13, 13, 10, 13, 13, 12, 11, 13, 12, 11, 9, - 12, 12, 12, 10, 13, 13, 13, 10, 13, 13, 12, 10, 13, 12, 12, 9, - 9, 9, 10, 10, 9, 8, 10, 9, 9, 10, 9, 9, 8, 8, 9, 6, - 10, 11, 11, 11, 10, 9, 11, 9, 11, 11, 11, 10, 10, 9, 10, 7, - 12, 12, 13, 12, 12, 10, 13, 10, 13, 13, 13, 12, 12, 11, 11, 9, - 11, 12, 11, 11, 11, 11, 11, 10, 11, 12, 10, 10, 10, 10, 10, 8, - 12, 12, 12, 11, 12, 11, 11, 10, 12, 12, 11, 11, 11, 11, 10, 8, - 14, 13, 13, 12, 13, 12, 13, 10, 14, 14, 13, 12, 13, 12, 12, 9, - 13, 14, 13, 12, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 11, 9, - 14, 14, 13, 12, 13, 13, 13, 11, 14, 14, 13, 12, 13, 12, 12, 9, - 14, 15, 14, 12, 15, 13, 13, 11, 15, 14, 14, 12, 14, 13, 12, 9, - 11, 11, 12, 12, 10, 10, 12, 11, 11, 12, 11, 11, 10, 10, 10, 8, - 12, 12, 14, 13, 11, 10, 12, 11, 13, 13, 13, 12, 12, 10, 11, 9, - 13, 13, 14, 14, 12, 10, 13, 11, 14, 14, 14, 13, 12, 11, 12, 9, - 13, 13, 13, 13, 12, 13, 13, 12, 13, 14, 12, 12, 12, 12, 11, 9, - 13, 14, 14, 13, 13, 12, 13, 11, 14, 14, 13, 12, 13, 12, 12, 9, - 14, 14, 14, 14, 14, 12, 13, 11, 15, 15, 15, 13, 14, 12, 12, 9, - 14, 15, 15, 13, 14, 14, 13, 12, 13, 14, 13, 13, 12, 12, 11, 10, - 16, 16, 15, 14, 15, 14, 13, 11, 15, 15, 14, 13, 13, 13, 12, 9, - 15, 15, 15, 13, 14, 13, 13, 11, 15, 15, 15, 13, 14, 13, 12, 9, - 8, 9, 9, 9, 9, 9, 10, 9, 8, 10, 9, 9, 8, 8, 9, 7, - 11, 11, 11, 11, 11, 11, 12, 10, 11, 11, 11, 10, 10, 10, 10, 8, - 13, 13, 14, 12, 13, 12, 14, 11, 13, 13, 13, 12, 13, 11, 12, 9, - 10, 11, 10, 11, 11, 11, 12, 10, 10, 11, 10, 10, 10, 10, 10, 8, - 12, 12, 12, 11, 12, 12, 12, 11, 11, 12, 11, 10, 11, 11, 10, 8, - 14, 13, 14, 12, 14, 13, 14, 12, 14, 13, 13, 11, 13, 12, 12, 9, - 12, 13, 12, 12, 13, 13, 13, 12, 12, 13, 11, 11, 12, 12, 11, 9, - 13, 14, 13, 12, 14, 14, 14, 12, 14, 13, 12, 11, 13, 12, 12, 9, - 14, 14, 13, 12, 15, 14, 15, 12, 14, 14, 13, 11, 13, 13, 12, 9, - 10, 11, 11, 11, 10, 10, 12, 10, 10, 11, 10, 10, 9, 9, 10, 7, - 12, 12, 13, 12, 12, 11, 12, 11, 12, 12, 12, 11, 11, 10, 10, 8, - 14, 13, 14, 13, 14, 12, 13, 12, 14, 13, 14, 12, 13, 11, 12, 9, - 12, 13, 12, 12, 12, 12, 12, 11, 11, 12, 11, 10, 10, 10, 10, 8, - 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 10, 11, 10, 10, 7, - 14, 14, 14, 12, 14, 12, 14, 11, 14, 13, 13, 11, 13, 11, 11, 8, - 13, 15, 13, 13, 14, 14, 14, 12, 13, 14, 12, 12, 12, 12, 11, 9, - 14, 15, 13, 12, 14, 13, 13, 11, 13, 13, 12, 11, 13, 12, 11, 8, - 15, 15, 15, 12, 15, 14, 14, 11, 14, 14, 13, 11, 13, 12, 12, 8, - 12, 13, 13, 13, 12, 12, 13, 12, 12, 13, 12, 12, 11, 11, 11, 9, - 13, 14, 15, 14, 13, 12, 14, 12, 13, 13, 14, 12, 12, 11, 12, 9, - 14, 14, 15, 14, 14, 12, 14, 12, 14, 14, 14, 13, 13, 11, 12, 9, - 13, 14, 14, 14, 13, 13, 14, 13, 13, 13, 12, 12, 12, 12, 11, 9, - 14, 14, 14, 13, 13, 13, 13, 12, 13, 14, 13, 12, 12, 11, 11, 8, - 15, 14, 15, 14, 14, 13, 14, 11, 15, 14, 14, 12, 13, 11, 12, 8, - 14, 15, 14, 14, 15, 14, 14, 13, 14, 15, 13, 13, 12, 12, 11, 10, - 16, 15, 14, 14, 14, 14, 13, 12, 14, 14, 13, 12, 13, 12, 11, 9, - 15, 15, 15, 14, 16, 14, 14, 11, 15, 15, 14, 12, 13, 12, 11, 8, - 11, 12, 11, 12, 12, 12, 12, 11, 10, 11, 10, 10, 10, 10, 10, 8, - 13, 13, 13, 13, 13, 13, 14, 12, 12, 12, 12, 12, 12, 11, 12, 9, - 14, 14, 14, 13, 15, 13, 15, 13, 14, 14, 14, 12, 14, 12, 13, 10, - 12, 13, 12, 13, 13, 13, 13, 12, 11, 12, 11, 11, 12, 11, 11, 9, - 14, 14, 13, 13, 14, 14, 14, 12, 12, 13, 12, 11, 13, 12, 12, 9, - 14, 14, 15, 13, 15, 15, 15, 13, 15, 13, 13, 12, 14, 12, 13, 10, - 13, 15, 12, 13, 14, 14, 14, 13, 12, 13, 11, 11, 13, 12, 11, 10, - 14, 15, 14, 13, 15, 14, 15, 13, 14, 14, 12, 11, 13, 13, 12, 9, - 14, 15, 14, 13, 15, 14, 15, 13, 14, 14, 13, 11, 14, 13, 12, 9, - 12, 13, 13, 13, 12, 13, 13, 12, 11, 12, 12, 11, 11, 11, 11, 9, - 13, 14, 14, 13, 14, 13, 14, 12, 13, 13, 13, 12, 12, 11, 11, 9, - 15, 15, 16, 14, 15, 14, 14, 13, 15, 14, 14, 13, 13, 12, 13, 10, - 13, 14, 14, 13, 13, 14, 14, 13, 12, 13, 12, 12, 11, 11, 11, 9, - 14, 14, 14, 13, 14, 13, 14, 12, 13, 13, 12, 11, 12, 11, 11, 8, - 15, 15, 15, 13, 15, 14, 14, 12, 14, 13, 13, 12, 13, 12, 12, 9, - 14, 15, 14, 14, 15, 15, 14, 13, 13, 14, 12, 12, 13, 12, 12, 9, - 15, 15, 14, 13, 15, 14, 14, 13, 14, 14, 12, 11, 13, 12, 11, 8, - 15, 16, 14, 13, 15, 15, 15, 12, 14, 14, 13, 11, 14, 12, 12, 8, - 12, 14, 13, 13, 13, 13, 14, 12, 12, 13, 12, 12, 10, 11, 11, 9, - 14, 15, 15, 14, 13, 13, 15, 13, 13, 14, 14, 12, 12, 11, 12, 9, - 15, 15, 16, 14, 14, 13, 15, 13, 14, 14, 14, 13, 13, 11, 12, 9, - 14, 15, 14, 14, 14, 14, 14, 13, 13, 14, 13, 12, 12, 12, 11, 9, - 14, 15, 15, 14, 14, 14, 14, 12, 13, 14, 13, 12, 12, 11, 11, 8, - 15, 15, 15, 14, 14, 13, 15, 12, 15, 14, 14, 12, 13, 11, 11, 8, - 14, 16, 14, 14, 14, 15, 14, 13, 13, 14, 12, 12, 12, 12, 11, 9, - 15, 15, 15, 14, 15, 14, 14, 12, 14, 14, 13, 12, 12, 11, 11, 8, - 15, 15, 14, 13, 15, 13, 14, 12, 14, 14, 13, 11, 13, 11, 11, 7, - }, - { - 1, 5, 6, 7, 6, 7, 9, 8, 6, 9, 8, 8, 7, 8, 8, 6, - 5, 8, 10, 10, 10, 11, 13, 12, 11, 13, 12, 12, 12, 12, 13, 10, - 8, 10, 13, 12, 13, 13, 16, 14, 14, 16, 16, 14, 16, 16, 16, 12, - 5, 10, 9, 11, 11, 12, 13, 12, 11, 13, 11, 12, 12, 12, 13, 10, - 6, 10, 11, 11, 11, 12, 14, 12, 11, 13, 13, 13, 12, 13, 13, 11, - 8, 12, 13, 12, 14, 14, 16, 14, 14, 16, 16, 16, 16, 16, 16, 13, - 9, 13, 11, 14, 14, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, - 9, 13, 13, 13, 14, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 14, - 8, 12, 13, 12, 13, 14, 16, 14, 14, 16, 16, 16, 14, 16, 16, 13, - 5, 10, 11, 12, 9, 11, 13, 12, 11, 13, 13, 13, 11, 12, 13, 10, - 6, 10, 11, 12, 11, 11, 14, 13, 12, 14, 12, 13, 13, 13, 13, 11, - 9, 12, 14, 15, 13, 13, 16, 16, 14, 16, 16, 16, 16, 16, 16, 13, - 8, 13, 13, 14, 13, 14, 16, 16, 14, 16, 14, 16, 14, 16, 14, 13, - 7, 11, 12, 13, 12, 12, 14, 13, 12, 14, 13, 14, 13, 14, 14, 12, - 9, 13, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 15, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 9, 13, 14, 14, 14, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, - 9, 13, 14, 15, 11, 13, 16, 14, 14, 16, 16, 16, 13, 14, 16, 13, - 9, 13, 14, 16, 13, 13, 16, 16, 14, 16, 16, 16, 16, 15, 16, 14, - 8, 12, 13, 16, 13, 12, 16, 14, 13, 16, 14, 16, 16, 16, 16, 13, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 14, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 9, 13, 16, 16, 14, 14, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 13, 14, 15, 14, 14, 16, 14, 13, 16, 16, 16, 14, 16, 16, 14, - 6, 11, 11, 12, 11, 12, 14, 13, 11, 14, 12, 13, 12, 13, 13, 11, - 9, 13, 13, 14, 13, 14, 16, 16, 14, 16, 16, 16, 15, 16, 16, 13, - 11, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 7, 11, 11, 13, 12, 13, 16, 14, 12, 16, 12, 14, 14, 14, 14, 12, - 8, 12, 12, 13, 12, 14, 16, 14, 13, 16, 14, 14, 14, 14, 14, 12, - 11, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 14, 13, 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 16, - 10, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 7, 11, 12, 12, 11, 13, 16, 14, 12, 15, 14, 14, 11, 13, 13, 12, - 8, 12, 12, 13, 13, 13, 16, 14, 13, 16, 13, 15, 13, 14, 14, 12, - 11, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 8, 12, 13, 14, 13, 14, 16, 16, 14, 16, 14, 16, 14, 16, 15, 13, - 6, 11, 11, 12, 11, 12, 13, 13, 11, 13, 12, 13, 12, 13, 13, 11, - 9, 13, 14, 14, 14, 14, 16, 14, 14, 16, 16, 16, 16, 16, 14, 13, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 14, 13, 14, 14, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, - 9, 13, 14, 13, 13, 16, 16, 14, 13, 16, 16, 16, 13, 16, 14, 13, - 10, 14, 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 13, 14, 16, 14, - 11, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 14, 16, 16, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 14, 14, 14, 14, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 13, - 9, 13, 13, 16, 14, 14, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 13, 14, 14, 13, 16, 16, 14, 13, 16, 14, 16, 14, 14, 16, 12, - 10, 14, 14, 16, 16, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 14, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 14, 13, 16, 16, 16, 16, 16, 14, 16, 12, 16, 16, 16, 16, 14, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 14, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, - 11, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 15, 14, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 14, - 10, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 10, 14, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 14, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 15, 14, 16, 14, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 13, - 10, 15, 14, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 8, 12, 12, 13, 12, 14, 14, 14, 12, 16, 13, 14, 12, 14, 14, 11, - }, - }, -}; - - -static const uint8_t rv34_table_intra_cbp[NUM_INTRA_TABLES][8][CBP_VLC_SIZE] = { - { - { 0, 3, 3, 4, 3, 5, 5, 5, 2, 5, 4, 6, 4, 6, 6, 6, }, - { 0, 2, 3, 4, 2, 5, 6, 7, 3, 6, 5, 7, 4, 7, 8, 8, }, - { 0, 3, 4, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 3, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 6, 3, 5, 6, 5, }, - { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 4, 5, 4, 4, 4, 2, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 6, 6, 5, 6, 5, 6, 4, 6, 6, 5, 4, 4, 4, 4, 1, }, - { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, - }, - { - { 0, 4, 3, 4, 3, 4, 5, 4, 3, 5, 4, 5, 3, 5, 5, 5, }, - { 0, 2, 3, 4, 2, 5, 6, 7, 3, 6, 5, 7, 4, 7, 8, 8, }, - { 0, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 3, 4, 4, 3, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 6, 3, 5, 6, 5, }, - { 0, 4, 4, 4, 4, 4, 5, 4, 4, 5, 5, 5, 4, 4, 4, 2, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 5, 6, 5, 5, 5, 6, 4, 6, 6, 5, 4, 5, 4, 4, 1, }, - { 0, 4, 4, 4, 4, 4, 5, 4, 4, 5, 5, 4, 4, 4, 5, 2, }, - }, - { - { 0, 3, 3, 4, 3, 4, 4, 5, 3, 5, 4, 5, 4, 5, 5, 5, }, - { 0, 2, 3, 4, 2, 4, 6, 7, 3, 6, 5, 7, 5, 7, 8, 8, }, - { 0, 4, 4, 4, 4, 4, 5, 4, 3, 5, 4, 4, 4, 4, 4, 3, }, - { 0, 3, 3, 4, 3, 3, 6, 6, 3, 6, 4, 6, 3, 6, 6, 5, }, - { 0, 4, 4, 4, 3, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 5, 5, 4, 4, 1, }, - { 0, 4, 4, 4, 4, 4, 6, 4, 4, 6, 5, 4, 4, 4, 4, 2, }, - }, - { - { 0, 3, 3, 4, 3, 4, 4, 5, 3, 5, 4, 5, 4, 5, 5, 5, }, - { 0, 2, 3, 4, 2, 4, 7, 6, 3, 7, 5, 7, 5, 7, 7, 7, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 3, 3, 3, 3, 4, 6, 6, 3, 6, 4, 6, 3, 6, 6, 5, }, - { 0, 3, 4, 4, 3, 4, 5, 4, 4, 5, 4, 5, 4, 5, 4, 3, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 4, 5, 4, 4, 4, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, - { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, - }, - { - { 0, 3, 3, 4, 3, 4, 5, 6, 2, 5, 4, 7, 4, 6, 6, 7, }, - { 0, 2, 3, 4, 2, 4, 6, 7, 3, 7, 5, 7, 5, 7, 7, 7, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 2, 3, 4, 3, 4, 6, 5, 3, 6, 4, 6, 4, 6, 6, 6, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, - { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, - { 0, 3, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3, }, - }, -}; - - -static const uint8_t rv34_table_intra_firstpat[NUM_INTRA_TABLES][4][FIRSTBLK_VLC_SIZE] = { - { - { - 0, 10, 5, 10, 7, 12, 9, 11, 8, 13, 9, 12, 10, 13, 11, 12, - 16, 16, 14, 15, 15, 16, 13, 14, 5, 12, 6, 11, 9, 13, 10, 11, - 9, 14, 9, 12, 11, 14, 11, 12, 16, 16, 14, 15, 15, 16, 13, 13, - 10, 15, 9, 12, 12, 16, 11, 12, 12, 16, 10, 13, 13, 16, 11, 12, - 16, 16, 13, 14, 15, 16, 13, 12, 6, 12, 8, 11, 8, 12, 10, 11, - 9, 14, 10, 12, 10, 13, 11, 12, 15, 16, 14, 15, 14, 16, 13, 13, - 8, 13, 9, 12, 10, 13, 10, 12, 10, 14, 9, 12, 11, 14, 10, 12, - 15, 16, 13, 15, 14, 16, 13, 13, 11, 16, 10, 13, 13, 16, 11, 12, - 12, 16, 11, 13, 13, 16, 11, 12, 16, 16, 13, 14, 15, 16, 12, 12, - 10, 16, 12, 14, 10, 14, 11, 12, 12, 16, 13, 14, 11, 14, 12, 12, - 16, 16, 15, 16, 14, 15, 13, 13, 11, 16, 12, 14, 11, 14, 11, 12, - 12, 16, 12, 14, 11, 14, 11, 12, 16, 16, 14, 15, 13, 15, 13, 12, - 14, 16, 13, 14, 13, 16, 12, 12, 14, 16, 13, 14, 13, 16, 12, 12, - 16, 16, 14, 14, 14, 15, 12, 11, 2, 10, 6, 10, 7, 12, 9, 11, - 8, 12, 9, 11, 10, 13, 10, 11, 15, 16, 14, 15, 14, 16, 13, 13, - 5, 12, 6, 11, 9, 13, 10, 11, 9, 13, 9, 11, 10, 13, 10, 11, - 15, 16, 13, 14, 14, 16, 13, 13, 9, 15, 8, 12, 12, 15, 11, 11, - 11, 16, 10, 12, 13, 15, 11, 11, 15, 16, 13, 14, 15, 16, 12, 12, - 6, 12, 8, 11, 8, 12, 9, 11, 9, 14, 9, 12, 10, 13, 10, 11, - 15, 16, 14, 15, 14, 16, 13, 13, 7, 13, 8, 11, 9, 13, 10, 11, - 9, 14, 9, 12, 10, 13, 10, 11, 14, 16, 13, 14, 13, 16, 12, 12, - 11, 16, 10, 12, 12, 15, 11, 11, 11, 16, 10, 12, 12, 15, 11, 11, - 15, 16, 12, 13, 14, 16, 12, 11, 9, 15, 11, 13, 9, 13, 11, 12, - 11, 16, 12, 14, 10, 14, 11, 12, 16, 16, 14, 15, 13, 15, 12, 12, - 11, 16, 11, 14, 10, 14, 11, 12, 11, 16, 12, 13, 11, 14, 11, 11, - 15, 16, 14, 15, 13, 14, 12, 12, 13, 16, 12, 14, 13, 15, 11, 11, - 13, 16, 12, 14, 13, 15, 11, 11, 16, 16, 13, 14, 13, 15, 11, 10, - 5, 12, 7, 11, 8, 13, 10, 11, 9, 13, 9, 12, 10, 14, 11, 12, - 16, 16, 14, 15, 14, 16, 13, 13, 7, 13, 7, 11, 9, 13, 10, 11, - 9, 14, 9, 12, 11, 14, 11, 12, 16, 16, 14, 14, 14, 16, 13, 13, - 9, 15, 8, 12, 12, 15, 11, 12, 11, 16, 10, 12, 13, 16, 11, 12, - 16, 16, 13, 14, 15, 16, 12, 12, 7, 13, 8, 12, 9, 13, 10, 11, - 10, 14, 10, 12, 10, 14, 11, 12, 16, 16, 14, 15, 14, 16, 13, 13, - 8, 14, 9, 12, 10, 13, 10, 11, 9, 14, 9, 12, 10, 14, 10, 11, - 15, 16, 13, 14, 14, 16, 12, 12, 11, 16, 10, 12, 12, 15, 11, 12, - 11, 16, 10, 12, 12, 15, 11, 11, 15, 16, 12, 14, 14, 16, 12, 11, - 10, 16, 11, 13, 9, 14, 11, 12, 12, 16, 12, 14, 11, 14, 11, 12, - 16, 16, 14, 16, 14, 15, 13, 12, 11, 16, 11, 14, 10, 14, 11, 12, - 11, 16, 12, 14, 11, 14, 11, 11, 15, 16, 14, 15, 13, 15, 12, 12, - 13, 16, 12, 14, 13, 15, 11, 11, 13, 16, 12, 14, 12, 14, 11, 11, - 15, 16, 12, 13, 13, 14, 11, 10, 6, 13, 8, 11, 9, 13, 10, 11, - 10, 14, 10, 12, 10, 13, 10, 11, 15, 16, 13, 13, 13, 14, 12, 11, - 7, 13, 8, 11, 9, 13, 9, 11, 10, 14, 9, 11, 10, 13, 10, 11, - 15, 16, 13, 13, 13, 14, 11, 11, 9, 14, 8, 11, 10, 13, 9, 10, - 11, 15, 9, 11, 11, 13, 9, 10, 15, 16, 12, 13, 13, 14, 10, 9, - 7, 13, 8, 11, 9, 13, 9, 11, 10, 14, 10, 12, 10, 13, 10, 11, - 15, 16, 13, 13, 13, 14, 11, 11, 8, 13, 8, 11, 9, 13, 9, 10, - 9, 14, 9, 11, 10, 13, 9, 10, 14, 16, 12, 13, 13, 14, 11, 10, - 9, 14, 8, 11, 10, 13, 9, 9, 10, 14, 8, 11, 10, 13, 9, 9, - 14, 16, 11, 12, 12, 14, 10, 9, 9, 14, 9, 12, 8, 12, 9, 10, - 11, 15, 10, 12, 10, 13, 9, 10, 15, 16, 13, 13, 12, 13, 11, 10, - 9, 14, 9, 12, 9, 12, 9, 10, 10, 14, 10, 12, 9, 12, 9, 9, - 14, 16, 12, 13, 11, 13, 10, 9, 10, 14, 9, 11, 10, 12, 8, 8, - 10, 14, 9, 11, 10, 12, 8, 8, 12, 14, 9, 10, 10, 11, 8, 7, - }, - { - 0, 9, 6, 9, 6, 10, 8, 9, 7, 11, 8, 11, 9, 11, 9, 10, - 14, 16, 13, 14, 13, 14, 12, 11, 5, 11, 7, 10, 8, 10, 8, 9, - 8, 12, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, - 10, 14, 9, 11, 11, 13, 10, 10, 11, 15, 9, 11, 12, 13, 10, 10, - 15, 16, 12, 12, 13, 14, 11, 9, 6, 11, 7, 10, 7, 10, 8, 9, - 8, 12, 9, 11, 9, 11, 9, 10, 14, 16, 13, 13, 13, 14, 11, 11, - 7, 12, 8, 11, 8, 11, 9, 9, 9, 13, 9, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 12, 14, 11, 10, 11, 14, 10, 12, 11, 13, 10, 10, - 12, 15, 10, 12, 12, 13, 10, 10, 15, 16, 12, 12, 13, 14, 10, 9, - 10, 14, 11, 13, 9, 12, 10, 10, 11, 15, 12, 13, 10, 12, 10, 10, - 14, 16, 13, 14, 12, 13, 11, 10, 11, 14, 11, 13, 10, 12, 10, 10, - 12, 15, 11, 13, 10, 12, 10, 10, 15, 16, 13, 13, 12, 13, 11, 9, - 13, 16, 12, 13, 12, 13, 10, 9, 14, 16, 12, 13, 12, 13, 10, 9, - 16, 16, 12, 12, 13, 13, 10, 7, 4, 10, 6, 9, 7, 10, 8, 9, - 8, 12, 9, 11, 9, 11, 9, 9, 14, 16, 13, 13, 13, 14, 11, 11, - 6, 11, 7, 10, 8, 11, 8, 9, 9, 12, 9, 11, 9, 12, 9, 9, - 14, 16, 12, 13, 13, 14, 11, 10, 10, 14, 9, 11, 11, 13, 9, 9, - 11, 14, 9, 11, 11, 13, 10, 9, 14, 16, 11, 12, 13, 14, 10, 9, - 6, 11, 8, 10, 7, 10, 8, 9, 9, 12, 9, 11, 9, 11, 9, 9, - 14, 16, 13, 13, 12, 13, 11, 10, 8, 12, 8, 10, 8, 11, 9, 9, - 9, 12, 9, 11, 9, 11, 9, 9, 14, 16, 12, 13, 12, 13, 11, 10, - 11, 14, 10, 11, 11, 13, 9, 9, 11, 14, 10, 11, 11, 13, 9, 9, - 14, 16, 11, 12, 13, 14, 10, 8, 10, 14, 11, 12, 9, 12, 10, 10, - 11, 14, 11, 13, 10, 12, 10, 10, 14, 16, 13, 14, 12, 13, 11, 9, - 11, 14, 11, 12, 10, 12, 10, 10, 11, 14, 11, 12, 10, 12, 10, 9, - 14, 16, 13, 13, 11, 12, 10, 9, 13, 16, 12, 13, 12, 13, 10, 9, - 13, 16, 11, 12, 11, 13, 10, 8, 15, 16, 12, 12, 12, 12, 9, 7, - 8, 12, 8, 11, 9, 12, 9, 10, 10, 14, 10, 12, 11, 13, 10, 10, - 16, 16, 14, 14, 14, 14, 12, 11, 8, 13, 8, 11, 9, 12, 10, 10, - 11, 14, 10, 12, 11, 13, 10, 10, 16, 16, 13, 14, 14, 14, 12, 11, - 11, 14, 9, 12, 11, 13, 10, 10, 12, 15, 10, 12, 12, 14, 10, 10, - 15, 16, 12, 12, 14, 14, 11, 9, 9, 13, 9, 11, 9, 12, 10, 10, - 11, 14, 10, 12, 10, 12, 10, 10, 15, 16, 14, 14, 13, 14, 12, 11, - 9, 13, 9, 11, 10, 12, 10, 10, 10, 14, 10, 12, 10, 12, 10, 10, - 15, 16, 13, 13, 13, 14, 11, 10, 11, 15, 10, 12, 11, 13, 10, 10, - 11, 15, 10, 12, 12, 13, 10, 9, 15, 16, 11, 12, 13, 14, 10, 9, - 11, 15, 11, 13, 10, 12, 10, 10, 12, 16, 12, 13, 11, 13, 10, 10, - 16, 16, 14, 14, 12, 13, 11, 9, 11, 15, 11, 13, 10, 13, 10, 10, - 12, 15, 12, 13, 10, 12, 10, 10, 14, 16, 13, 13, 12, 13, 10, 9, - 13, 16, 12, 13, 12, 13, 10, 9, 13, 16, 11, 12, 11, 13, 10, 9, - 14, 16, 11, 12, 12, 12, 9, 7, 10, 15, 10, 12, 11, 13, 10, 10, - 12, 16, 12, 13, 12, 13, 11, 10, 16, 16, 14, 14, 14, 15, 12, 10, - 10, 14, 10, 12, 10, 13, 10, 10, 12, 15, 11, 12, 11, 13, 10, 10, - 16, 16, 14, 13, 14, 14, 11, 9, 11, 14, 10, 11, 11, 12, 9, 9, - 12, 15, 10, 11, 11, 13, 9, 8, 16, 16, 12, 12, 13, 13, 10, 7, - 10, 15, 10, 12, 10, 13, 10, 10, 12, 15, 11, 12, 11, 13, 10, 10, - 16, 16, 14, 13, 14, 14, 11, 9, 10, 14, 10, 12, 10, 12, 10, 10, - 12, 15, 11, 12, 11, 13, 10, 10, 16, 16, 13, 13, 13, 14, 11, 9, - 11, 14, 10, 11, 10, 12, 9, 8, 11, 14, 9, 11, 11, 12, 9, 8, - 14, 16, 10, 11, 12, 13, 9, 7, 11, 15, 11, 12, 10, 12, 10, 9, - 13, 16, 11, 12, 11, 12, 10, 9, 16, 16, 13, 13, 12, 13, 10, 7, - 11, 15, 10, 12, 10, 12, 9, 8, 12, 15, 11, 12, 10, 12, 9, 8, - 14, 16, 12, 12, 11, 12, 9, 7, 11, 14, 10, 11, 10, 12, 8, 7, - 11, 14, 9, 10, 10, 11, 8, 6, 12, 15, 9, 9, 9, 10, 7, 4, - }, - { - 0, 6, 3, 7, 3, 7, 6, 7, 5, 9, 6, 9, 7, 9, 8, 8, - 16, 16, 16, 16, 16, 16, 16, 11, 3, 8, 5, 8, 6, 8, 7, 7, - 7, 11, 7, 10, 8, 10, 8, 9, 16, 16, 16, 16, 16, 16, 14, 10, - 8, 16, 7, 11, 10, 16, 9, 9, 11, 16, 9, 14, 16, 16, 10, 9, - 16, 16, 16, 16, 16, 16, 16, 10, 3, 8, 5, 8, 5, 8, 7, 7, - 7, 11, 8, 10, 8, 10, 8, 9, 16, 16, 16, 16, 16, 16, 16, 11, - 6, 10, 7, 9, 7, 10, 8, 8, 8, 11, 8, 10, 8, 11, 8, 8, - 16, 16, 16, 16, 16, 16, 11, 10, 10, 16, 9, 13, 11, 16, 10, 9, - 11, 16, 9, 11, 16, 16, 10, 9, 16, 16, 11, 16, 16, 16, 11, 9, - 9, 16, 10, 11, 8, 11, 9, 9, 11, 16, 12, 16, 10, 16, 10, 10, - 16, 16, 16, 16, 16, 16, 16, 10, 10, 16, 11, 16, 10, 16, 10, 10, - 11, 16, 11, 16, 10, 16, 10, 9, 16, 16, 16, 16, 16, 16, 11, 9, - 16, 16, 16, 16, 16, 16, 11, 9, 16, 16, 16, 16, 16, 16, 11, 9, - 16, 16, 11, 16, 16, 16, 9, 7, 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, 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, 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, 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, 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, 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, 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, - }, - { - 2, 8, 5, 9, 6, 9, 8, 8, 8, 12, 9, 11, 9, 11, 10, 10, - 16, 16, 14, 16, 14, 16, 14, 12, 5, 10, 6, 9, 8, 10, 8, 9, - 9, 12, 9, 11, 10, 12, 10, 10, 16, 16, 14, 15, 15, 16, 13, 12, - 10, 13, 9, 12, 11, 12, 10, 10, 12, 15, 11, 12, 12, 13, 11, 10, - 16, 16, 15, 14, 15, 16, 13, 12, 6, 10, 8, 10, 7, 10, 8, 9, - 9, 13, 10, 11, 10, 12, 10, 10, 16, 16, 14, 16, 14, 16, 13, 12, - 7, 11, 8, 11, 9, 11, 9, 9, 10, 13, 10, 11, 10, 12, 10, 9, - 16, 16, 14, 14, 14, 15, 12, 11, 11, 14, 11, 12, 11, 13, 10, 10, - 12, 15, 11, 13, 12, 13, 11, 10, 16, 16, 14, 16, 15, 15, 13, 11, - 10, 13, 11, 12, 10, 12, 10, 10, 12, 15, 12, 13, 11, 13, 11, 11, - 16, 16, 15, 16, 14, 15, 13, 11, 11, 14, 11, 13, 11, 12, 11, 10, - 12, 16, 12, 13, 12, 13, 11, 10, 16, 16, 15, 16, 13, 15, 12, 11, - 13, 15, 12, 13, 13, 14, 11, 11, 14, 16, 13, 13, 13, 14, 11, 11, - 16, 16, 15, 14, 15, 15, 12, 10, 3, 8, 6, 9, 7, 9, 8, 8, - 8, 12, 9, 11, 9, 11, 9, 9, 16, 16, 15, 15, 15, 16, 13, 12, - 6, 10, 7, 9, 8, 10, 8, 8, 9, 12, 9, 11, 10, 12, 10, 9, - 16, 16, 14, 14, 14, 15, 13, 11, 10, 13, 9, 11, 11, 12, 10, 10, - 12, 14, 11, 12, 12, 13, 11, 10, 16, 16, 14, 14, 15, 15, 13, 11, - 6, 10, 8, 10, 7, 10, 8, 9, 10, 12, 10, 11, 10, 11, 10, 9, - 16, 16, 14, 15, 14, 15, 13, 11, 8, 11, 8, 10, 9, 11, 9, 9, - 9, 13, 9, 11, 10, 11, 9, 9, 16, 16, 13, 14, 14, 14, 12, 10, - 11, 14, 10, 12, 11, 12, 10, 10, 12, 14, 11, 12, 12, 13, 10, 10, - 16, 16, 13, 14, 15, 15, 12, 10, 10, 13, 11, 12, 10, 12, 10, 10, - 12, 14, 12, 13, 11, 13, 11, 10, 16, 16, 15, 14, 14, 14, 12, 11, - 11, 14, 11, 12, 10, 12, 10, 10, 12, 15, 12, 12, 11, 13, 10, 10, - 16, 16, 14, 15, 13, 14, 12, 10, 13, 15, 12, 13, 12, 13, 11, 10, - 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 14, 13, 15, 11, 9, - 6, 10, 8, 10, 8, 11, 9, 10, 11, 13, 11, 12, 11, 13, 11, 10, - 16, 16, 16, 16, 16, 16, 13, 12, 8, 11, 9, 11, 9, 11, 10, 10, - 11, 14, 11, 12, 11, 12, 11, 10, 16, 16, 15, 15, 16, 16, 13, 12, - 11, 14, 10, 12, 12, 13, 11, 10, 13, 16, 12, 13, 13, 14, 11, 11, - 16, 16, 15, 16, 16, 16, 13, 12, 8, 12, 9, 11, 9, 11, 10, 10, - 11, 14, 11, 12, 11, 12, 11, 10, 16, 16, 16, 16, 16, 16, 13, 12, - 9, 12, 10, 11, 10, 12, 10, 10, 11, 14, 11, 12, 11, 13, 10, 10, - 16, 16, 15, 14, 15, 15, 13, 11, 12, 14, 11, 13, 12, 13, 11, 10, - 12, 15, 11, 12, 13, 13, 11, 10, 16, 16, 14, 15, 16, 15, 13, 11, - 11, 15, 12, 13, 11, 13, 11, 10, 13, 16, 13, 14, 12, 14, 11, 11, - 16, 16, 16, 16, 15, 15, 13, 12, 12, 14, 12, 13, 11, 13, 11, 10, - 13, 15, 12, 13, 11, 13, 11, 10, 16, 16, 15, 15, 13, 15, 13, 11, - 13, 16, 13, 13, 13, 13, 12, 11, 13, 16, 13, 13, 13, 13, 11, 10, - 16, 16, 13, 15, 14, 14, 12, 9, 9, 13, 10, 12, 11, 13, 11, 11, - 13, 16, 13, 14, 13, 14, 12, 11, 16, 16, 16, 16, 16, 16, 14, 12, - 10, 14, 11, 13, 11, 13, 11, 10, 13, 16, 13, 13, 13, 14, 12, 11, - 16, 16, 16, 16, 16, 16, 14, 12, 11, 15, 11, 13, 12, 13, 11, 10, - 14, 16, 12, 13, 13, 14, 12, 10, 16, 16, 15, 16, 16, 16, 13, 11, - 10, 14, 11, 12, 11, 13, 11, 10, 13, 16, 12, 13, 12, 14, 12, 11, - 16, 16, 16, 16, 16, 16, 14, 12, 11, 14, 11, 12, 11, 13, 11, 10, - 13, 15, 12, 13, 12, 13, 11, 10, 16, 16, 15, 15, 16, 16, 13, 11, - 12, 15, 12, 13, 12, 13, 11, 10, 13, 16, 12, 13, 13, 13, 11, 10, - 16, 16, 14, 14, 16, 15, 13, 10, 12, 15, 12, 13, 12, 13, 11, 10, - 14, 16, 13, 14, 13, 14, 12, 11, 16, 16, 16, 16, 15, 16, 13, 11, - 12, 16, 12, 13, 12, 13, 11, 10, 13, 16, 13, 13, 12, 14, 11, 10, - 16, 16, 15, 16, 14, 15, 13, 10, 12, 15, 12, 14, 12, 13, 11, 10, - 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 14, 13, 14, 11, 8, - }, - }, - { - { - 0, 11, 5, 11, 7, 13, 10, 12, 7, 13, 9, 13, 10, 14, 12, 13, - 16, 16, 15, 16, 16, 16, 15, 15, 4, 13, 6, 12, 10, 14, 11, 12, - 8, 14, 9, 13, 11, 15, 12, 13, 16, 16, 15, 16, 15, 16, 15, 14, - 9, 16, 9, 13, 13, 16, 12, 13, 12, 16, 10, 14, 14, 16, 13, 13, - 16, 16, 14, 16, 16, 16, 14, 14, 5, 13, 8, 13, 8, 13, 11, 12, - 9, 14, 10, 13, 10, 14, 12, 13, 16, 16, 15, 16, 15, 16, 14, 15, - 7, 14, 9, 13, 10, 14, 11, 13, 9, 15, 10, 13, 11, 14, 12, 13, - 16, 16, 14, 16, 15, 16, 14, 14, 11, 16, 11, 14, 13, 16, 12, 13, - 12, 16, 11, 14, 14, 16, 12, 13, 16, 16, 14, 15, 16, 16, 14, 13, - 10, 16, 12, 15, 10, 15, 12, 14, 12, 16, 13, 16, 11, 15, 13, 14, - 16, 16, 16, 16, 14, 16, 14, 14, 11, 16, 12, 15, 11, 16, 12, 13, - 12, 16, 13, 15, 12, 16, 12, 13, 16, 16, 16, 16, 14, 16, 14, 14, - 14, 16, 13, 15, 14, 16, 13, 13, 14, 16, 14, 15, 14, 16, 13, 13, - 16, 16, 15, 16, 15, 16, 13, 13, 2, 12, 6, 11, 7, 13, 10, 12, - 7, 13, 9, 12, 10, 14, 11, 12, 16, 16, 15, 16, 15, 16, 14, 15, - 5, 13, 6, 12, 9, 13, 10, 12, 8, 14, 9, 13, 11, 14, 11, 13, - 16, 16, 14, 16, 15, 16, 14, 14, 9, 16, 8, 13, 12, 16, 11, 13, - 11, 16, 10, 13, 13, 16, 12, 13, 16, 16, 13, 15, 16, 16, 13, 13, - 5, 13, 8, 12, 7, 13, 10, 12, 8, 14, 10, 13, 10, 14, 11, 13, - 16, 16, 14, 16, 15, 16, 14, 14, 7, 14, 8, 12, 9, 14, 11, 12, - 8, 14, 9, 13, 10, 14, 11, 12, 15, 16, 14, 15, 14, 16, 13, 14, - 11, 16, 10, 13, 13, 16, 12, 13, 11, 16, 10, 13, 13, 16, 12, 13, - 16, 16, 13, 15, 15, 16, 13, 13, 9, 16, 12, 15, 9, 14, 11, 13, - 11, 16, 13, 15, 11, 14, 12, 13, 16, 16, 15, 16, 14, 16, 14, 14, - 11, 16, 12, 14, 11, 15, 12, 13, 11, 16, 12, 14, 11, 15, 12, 13, - 16, 16, 15, 16, 14, 16, 13, 13, 13, 16, 13, 15, 13, 16, 12, 13, - 14, 16, 13, 15, 13, 16, 12, 12, 16, 16, 14, 15, 14, 16, 12, 12, - 4, 13, 7, 12, 8, 14, 11, 12, 9, 14, 10, 13, 11, 14, 12, 13, - 16, 16, 15, 16, 16, 16, 15, 15, 6, 14, 7, 12, 10, 14, 11, 12, - 9, 15, 10, 13, 11, 15, 12, 13, 16, 16, 15, 16, 16, 16, 14, 14, - 9, 16, 8, 13, 12, 16, 11, 13, 12, 16, 10, 14, 13, 16, 12, 13, - 16, 16, 14, 16, 16, 16, 14, 14, 6, 14, 8, 13, 8, 14, 11, 13, - 9, 15, 10, 13, 11, 14, 12, 13, 16, 16, 15, 16, 16, 16, 14, 14, - 7, 15, 9, 13, 10, 14, 11, 13, 9, 15, 10, 13, 11, 14, 11, 13, - 16, 16, 14, 16, 15, 16, 14, 14, 10, 16, 10, 13, 12, 16, 12, 13, - 11, 16, 10, 13, 13, 16, 12, 13, 16, 16, 13, 14, 15, 16, 13, 13, - 9, 16, 12, 14, 9, 14, 11, 13, 12, 16, 12, 15, 11, 15, 12, 13, - 16, 16, 16, 16, 15, 16, 14, 14, 10, 16, 12, 15, 11, 15, 12, 13, - 11, 16, 12, 14, 11, 15, 12, 13, 16, 16, 14, 16, 13, 16, 13, 13, - 13, 16, 13, 15, 13, 16, 12, 13, 13, 16, 12, 14, 13, 16, 12, 12, - 15, 16, 13, 14, 13, 16, 12, 12, 6, 14, 8, 13, 9, 14, 10, 12, - 10, 15, 10, 12, 11, 14, 11, 12, 16, 16, 14, 14, 14, 16, 13, 13, - 7, 15, 8, 13, 9, 14, 10, 12, 10, 15, 10, 13, 11, 14, 11, 12, - 16, 16, 14, 14, 14, 16, 13, 12, 9, 16, 8, 12, 11, 14, 10, 11, - 11, 16, 10, 13, 11, 14, 10, 11, 16, 16, 13, 14, 14, 16, 12, 11, - 7, 14, 9, 13, 9, 14, 10, 12, 10, 16, 10, 13, 11, 14, 11, 12, - 16, 16, 14, 14, 14, 15, 13, 12, 7, 14, 9, 13, 9, 14, 10, 12, - 9, 14, 10, 12, 10, 14, 11, 12, 15, 16, 13, 14, 14, 15, 12, 12, - 9, 15, 9, 12, 11, 14, 10, 11, 10, 15, 9, 12, 11, 14, 10, 11, - 14, 16, 11, 13, 13, 15, 11, 11, 9, 16, 10, 13, 9, 14, 10, 11, - 11, 16, 11, 13, 10, 14, 10, 11, 16, 16, 14, 15, 13, 15, 12, 12, - 9, 16, 10, 13, 9, 13, 10, 11, 10, 15, 10, 13, 10, 13, 10, 11, - 14, 16, 13, 14, 12, 14, 11, 11, 11, 16, 10, 13, 11, 13, 9, 10, - 11, 14, 10, 12, 10, 13, 9, 9, 13, 15, 10, 11, 11, 12, 9, 8, - }, - { - 0, 10, 5, 10, 6, 11, 8, 10, 7, 12, 8, 11, 9, 12, 9, 10, - 14, 16, 13, 13, 13, 14, 12, 11, 5, 12, 6, 10, 8, 12, 9, 10, - 8, 13, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, - 9, 15, 8, 12, 11, 14, 10, 10, 11, 16, 9, 12, 12, 14, 10, 10, - 14, 16, 11, 12, 13, 14, 11, 10, 5, 12, 8, 11, 7, 11, 9, 10, - 8, 13, 9, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, - 7, 13, 8, 11, 9, 12, 9, 10, 9, 13, 9, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 12, 13, 11, 10, 11, 15, 10, 12, 12, 14, 10, 10, - 12, 16, 10, 12, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 10, 9, - 10, 15, 11, 13, 9, 13, 10, 10, 11, 15, 12, 13, 10, 12, 10, 10, - 14, 16, 13, 14, 12, 13, 11, 10, 11, 16, 11, 13, 10, 13, 10, 10, - 11, 16, 11, 13, 10, 13, 10, 10, 14, 16, 13, 14, 12, 13, 11, 9, - 13, 16, 12, 13, 12, 14, 11, 10, 14, 16, 12, 13, 12, 14, 10, 9, - 16, 16, 12, 13, 13, 13, 10, 8, 3, 11, 6, 10, 7, 11, 9, 10, - 8, 12, 8, 11, 9, 12, 9, 10, 14, 16, 13, 13, 13, 14, 11, 11, - 5, 12, 6, 10, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 13, 14, 11, 10, 9, 14, 8, 11, 11, 14, 10, 10, - 11, 15, 9, 11, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 11, 9, - 6, 12, 8, 11, 7, 11, 9, 10, 8, 13, 9, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 13, 13, 11, 10, 7, 13, 8, 11, 8, 12, 9, 10, - 9, 13, 9, 11, 9, 12, 9, 9, 14, 16, 12, 13, 12, 13, 11, 10, - 10, 15, 9, 12, 11, 14, 10, 10, 11, 15, 9, 11, 11, 13, 10, 9, - 14, 16, 11, 12, 13, 14, 10, 9, 9, 15, 11, 13, 9, 12, 10, 10, - 11, 15, 11, 13, 9, 12, 10, 10, 14, 16, 13, 14, 12, 13, 11, 10, - 10, 15, 11, 13, 10, 13, 10, 10, 11, 15, 11, 13, 10, 12, 10, 10, - 14, 16, 12, 13, 11, 12, 10, 9, 13, 16, 12, 13, 12, 14, 10, 9, - 13, 16, 11, 12, 12, 13, 10, 9, 14, 16, 11, 12, 12, 13, 9, 8, - 7, 13, 8, 12, 9, 13, 10, 11, 10, 14, 10, 12, 11, 13, 11, 11, - 16, 16, 13, 14, 14, 14, 12, 11, 8, 14, 8, 12, 9, 13, 10, 10, - 10, 14, 10, 12, 11, 13, 10, 10, 16, 16, 13, 13, 14, 14, 12, 11, - 10, 15, 9, 12, 11, 14, 10, 10, 12, 16, 10, 12, 12, 14, 10, 10, - 16, 16, 12, 13, 14, 15, 11, 10, 8, 14, 9, 12, 9, 13, 10, 11, - 10, 15, 10, 12, 10, 13, 10, 11, 16, 16, 13, 14, 14, 14, 12, 11, - 8, 14, 9, 12, 9, 13, 10, 10, 10, 14, 10, 12, 10, 13, 10, 10, - 15, 16, 13, 13, 13, 14, 11, 10, 10, 15, 10, 12, 12, 14, 10, 10, - 11, 16, 9, 12, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 10, 9, - 11, 16, 11, 13, 10, 13, 10, 10, 12, 16, 12, 13, 10, 13, 11, 10, - 15, 16, 14, 14, 12, 13, 11, 10, 11, 16, 11, 13, 10, 13, 10, 10, - 11, 16, 12, 13, 10, 12, 10, 10, 14, 16, 13, 14, 11, 13, 11, 9, - 13, 16, 12, 13, 12, 14, 10, 10, 12, 16, 11, 12, 12, 13, 10, 9, - 14, 16, 11, 12, 11, 12, 9, 8, 10, 16, 10, 13, 11, 14, 11, 11, - 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 14, 13, 14, 14, 12, 10, - 10, 15, 10, 13, 10, 13, 10, 11, 12, 16, 11, 13, 11, 13, 11, 10, - 16, 16, 14, 13, 14, 14, 12, 10, 11, 15, 9, 12, 11, 13, 10, 9, - 12, 16, 10, 12, 12, 13, 10, 9, 16, 16, 12, 12, 13, 14, 10, 8, - 10, 16, 10, 13, 10, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 10, - 16, 16, 14, 13, 14, 14, 12, 10, 9, 15, 9, 12, 10, 13, 10, 10, - 11, 16, 10, 12, 11, 13, 10, 10, 16, 16, 13, 13, 13, 14, 11, 9, - 10, 15, 9, 11, 11, 13, 9, 9, 11, 15, 9, 11, 11, 13, 9, 8, - 14, 16, 10, 11, 13, 13, 10, 8, 11, 16, 11, 13, 10, 13, 10, 9, - 13, 16, 11, 13, 11, 13, 10, 9, 16, 16, 13, 13, 13, 13, 10, 8, - 11, 16, 10, 12, 10, 13, 10, 9, 11, 16, 11, 12, 10, 12, 9, 9, - 15, 16, 12, 13, 11, 12, 10, 8, 11, 16, 10, 12, 11, 12, 9, 8, - 11, 15, 9, 11, 10, 12, 9, 7, 13, 15, 9, 9, 10, 10, 7, 5, - }, - { - 0, 7, 3, 8, 4, 9, 7, 8, 5, 10, 7, 10, 8, 11, 8, 9, - 16, 16, 16, 16, 16, 16, 11, 10, 2, 10, 4, 9, 7, 10, 7, 8, - 7, 16, 7, 10, 9, 16, 8, 9, 16, 16, 16, 16, 16, 16, 11, 10, - 8, 16, 7, 10, 10, 16, 9, 8, 10, 16, 9, 11, 16, 16, 9, 9, - 16, 16, 16, 16, 16, 16, 11, 9, 3, 10, 6, 9, 6, 11, 8, 8, - 7, 16, 8, 10, 9, 16, 9, 9, 16, 16, 16, 16, 16, 16, 11, 10, - 5, 16, 7, 10, 8, 11, 8, 8, 8, 16, 8, 10, 9, 16, 8, 8, - 16, 16, 11, 16, 16, 16, 10, 9, 9, 16, 9, 11, 11, 16, 9, 9, - 11, 16, 9, 11, 11, 16, 9, 8, 16, 16, 10, 16, 16, 16, 10, 9, - 8, 16, 10, 16, 8, 16, 10, 9, 12, 16, 11, 16, 10, 16, 10, 9, - 16, 16, 16, 16, 16, 16, 12, 10, 10, 16, 11, 16, 10, 16, 10, 9, - 11, 16, 11, 16, 10, 16, 10, 9, 16, 16, 16, 16, 16, 16, 11, 9, - 16, 16, 16, 16, 16, 16, 10, 9, 16, 16, 11, 16, 16, 16, 10, 9, - 16, 16, 10, 11, 11, 16, 9, 7, 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, 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, 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, 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, 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, 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, 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, - }, - { - 2, 9, 6, 9, 6, 10, 8, 9, 8, 12, 9, 11, 9, 12, 10, 10, - 16, 16, 14, 14, 15, 15, 13, 12, 5, 11, 7, 10, 8, 11, 9, 9, - 9, 13, 9, 11, 10, 12, 10, 10, 15, 16, 14, 14, 14, 16, 12, 11, - 10, 14, 9, 11, 11, 13, 10, 10, 12, 15, 10, 12, 12, 13, 11, 10, - 16, 16, 14, 15, 14, 15, 12, 11, 5, 11, 8, 10, 7, 11, 9, 9, - 9, 13, 9, 12, 9, 12, 10, 10, 15, 16, 13, 14, 13, 16, 12, 11, - 7, 12, 8, 11, 9, 11, 9, 10, 9, 13, 9, 11, 10, 12, 9, 9, - 16, 16, 13, 14, 13, 14, 11, 11, 10, 14, 10, 12, 11, 13, 10, 10, - 11, 16, 11, 12, 12, 13, 10, 10, 16, 16, 13, 14, 13, 14, 12, 11, - 10, 14, 11, 13, 10, 13, 10, 11, 12, 16, 12, 13, 10, 12, 11, 11, - 16, 16, 14, 15, 13, 14, 12, 11, 11, 15, 11, 13, 11, 13, 10, 10, - 12, 15, 12, 13, 11, 13, 11, 10, 15, 16, 14, 15, 13, 15, 12, 11, - 12, 16, 12, 13, 12, 14, 11, 11, 13, 16, 12, 13, 12, 14, 11, 10, - 16, 16, 13, 14, 13, 14, 11, 10, 3, 10, 6, 9, 7, 10, 8, 9, - 9, 12, 9, 11, 10, 12, 9, 10, 15, 16, 14, 14, 14, 14, 12, 11, - 6, 11, 7, 10, 8, 10, 9, 9, 9, 13, 9, 11, 10, 12, 9, 9, - 15, 16, 13, 14, 14, 15, 12, 11, 10, 14, 9, 11, 11, 12, 10, 10, - 12, 14, 10, 12, 11, 13, 10, 10, 15, 16, 13, 14, 14, 16, 12, 11, - 6, 11, 8, 10, 7, 11, 9, 9, 9, 13, 9, 11, 9, 12, 9, 9, - 15, 16, 14, 14, 13, 14, 12, 11, 7, 11, 8, 11, 8, 11, 9, 9, - 9, 12, 9, 11, 9, 12, 9, 9, 15, 16, 13, 13, 13, 14, 11, 10, - 10, 13, 10, 12, 11, 13, 10, 10, 11, 15, 10, 12, 11, 13, 10, 10, - 14, 16, 12, 13, 13, 14, 11, 10, 10, 14, 11, 12, 9, 12, 10, 10, - 11, 15, 11, 13, 10, 13, 10, 10, 15, 16, 14, 14, 13, 14, 12, 11, - 10, 14, 10, 12, 10, 12, 10, 10, 11, 15, 11, 12, 10, 12, 10, 10, - 15, 16, 13, 14, 12, 14, 11, 10, 12, 16, 11, 13, 12, 14, 11, 10, - 12, 16, 12, 13, 11, 13, 10, 10, 15, 16, 12, 14, 12, 14, 11, 9, - 7, 12, 9, 11, 9, 12, 10, 10, 11, 14, 11, 12, 11, 13, 11, 11, - 16, 16, 15, 16, 15, 16, 13, 12, 8, 12, 9, 11, 9, 12, 10, 10, - 11, 14, 11, 12, 11, 13, 10, 10, 16, 16, 14, 15, 15, 16, 13, 12, - 11, 14, 10, 12, 11, 13, 10, 10, 12, 16, 11, 13, 12, 14, 11, 10, - 16, 16, 14, 15, 14, 16, 12, 11, 8, 13, 9, 11, 9, 12, 10, 10, - 11, 14, 11, 12, 11, 13, 10, 10, 16, 16, 15, 15, 14, 15, 13, 12, - 9, 13, 9, 12, 9, 12, 10, 10, 11, 14, 10, 12, 10, 12, 10, 10, - 16, 16, 14, 15, 14, 14, 12, 11, 11, 15, 11, 12, 11, 13, 11, 10, - 12, 16, 11, 12, 12, 13, 11, 10, 16, 16, 13, 15, 14, 15, 11, 11, - 11, 16, 11, 13, 10, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, - 16, 16, 14, 15, 14, 15, 13, 11, 11, 16, 11, 13, 11, 13, 11, 10, - 12, 16, 12, 13, 10, 13, 11, 10, 16, 16, 14, 14, 12, 14, 12, 10, - 12, 16, 12, 14, 12, 14, 11, 11, 13, 16, 12, 14, 12, 14, 11, 10, - 15, 16, 12, 14, 12, 14, 11, 9, 9, 14, 11, 13, 11, 13, 11, 11, - 13, 16, 12, 14, 13, 14, 12, 11, 16, 16, 16, 16, 16, 16, 14, 12, - 9, 14, 10, 12, 10, 13, 11, 11, 12, 16, 12, 13, 13, 14, 11, 11, - 16, 16, 16, 16, 16, 14, 13, 12, 10, 15, 11, 13, 11, 14, 11, 10, - 13, 16, 12, 13, 12, 15, 11, 10, 16, 16, 14, 16, 15, 16, 13, 11, - 10, 14, 10, 13, 11, 14, 11, 11, 13, 16, 12, 13, 12, 14, 11, 11, - 16, 16, 16, 16, 15, 16, 13, 12, 10, 14, 10, 12, 10, 13, 10, 11, - 12, 15, 12, 13, 12, 13, 11, 10, 16, 16, 14, 14, 15, 15, 13, 11, - 11, 16, 11, 13, 11, 14, 11, 10, 12, 16, 11, 13, 12, 14, 11, 10, - 16, 16, 13, 14, 14, 15, 12, 10, 11, 16, 12, 13, 11, 14, 11, 10, - 13, 16, 13, 14, 12, 14, 11, 11, 16, 16, 15, 16, 15, 15, 12, 11, - 11, 16, 12, 13, 11, 14, 11, 10, 13, 16, 12, 13, 11, 14, 11, 10, - 16, 16, 14, 15, 13, 14, 12, 10, 12, 16, 12, 14, 12, 14, 10, 10, - 12, 16, 11, 13, 11, 14, 10, 10, 14, 16, 11, 13, 12, 13, 10, 8, - }, - }, - { - { - 0, 12, 6, 13, 7, 14, 11, 14, 8, 14, 10, 14, 11, 15, 13, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 5, 14, 7, 13, 10, 16, 12, 14, - 9, 16, 10, 14, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 9, 14, 14, 16, 13, 16, 12, 16, 11, 16, 16, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 5, 14, 9, 14, 8, 14, 12, 14, - 9, 16, 11, 14, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 14, 11, 16, 12, 14, 10, 16, 11, 15, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 14, 16, 14, 16, - 13, 16, 12, 16, 15, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 13, 16, 11, 16, 14, 16, 13, 16, 14, 16, 13, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 14, 16, 13, 16, 14, 16, - 13, 16, 14, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 16, 16, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 1, 12, 6, 12, 8, 14, 11, 13, - 8, 14, 10, 13, 11, 14, 13, 14, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 14, 7, 13, 10, 14, 11, 14, 9, 16, 10, 14, 12, 16, 13, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 14, 13, 16, 13, 14, - 12, 16, 11, 15, 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 14, 9, 13, 8, 14, 12, 14, 9, 16, 11, 14, 11, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 7, 15, 9, 14, 10, 16, 12, 14, - 9, 16, 10, 14, 11, 16, 12, 14, 16, 16, 16, 16, 16, 16, 15, 16, - 11, 16, 11, 15, 14, 16, 13, 15, 12, 16, 11, 15, 14, 16, 13, 14, - 16, 16, 14, 16, 16, 16, 14, 16, 10, 16, 13, 16, 10, 16, 13, 16, - 12, 16, 14, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 13, 16, 12, 16, 13, 16, 12, 16, 13, 16, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 15, 16, 14, 16, 14, 16, 16, 16, 14, 16, - 15, 16, 14, 16, 14, 16, 14, 16, 16, 16, 16, 16, 16, 16, 14, 14, - 4, 14, 8, 13, 9, 16, 12, 14, 9, 16, 11, 14, 11, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 6, 15, 8, 13, 10, 16, 12, 14, - 10, 16, 11, 14, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 9, 14, 13, 16, 13, 15, 12, 16, 11, 16, 14, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 9, 14, 9, 16, 12, 14, - 10, 16, 11, 15, 12, 16, 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 14, 11, 16, 12, 14, 10, 16, 11, 14, 12, 16, 13, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 15, 14, 16, 13, 15, - 12, 16, 11, 15, 14, 16, 13, 14, 16, 16, 14, 16, 16, 16, 14, 16, - 10, 16, 13, 16, 10, 16, 13, 15, 13, 16, 14, 16, 12, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 12, 16, 13, 16, - 12, 16, 13, 16, 11, 16, 13, 16, 16, 16, 16, 16, 15, 16, 15, 16, - 14, 16, 14, 16, 15, 16, 14, 16, 14, 16, 14, 16, 14, 16, 14, 14, - 16, 16, 14, 16, 15, 16, 14, 14, 6, 16, 9, 14, 10, 16, 12, 14, - 10, 16, 11, 13, 12, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 14, - 7, 16, 9, 14, 10, 16, 12, 13, 11, 16, 11, 14, 12, 16, 12, 14, - 16, 16, 16, 16, 16, 16, 14, 14, 9, 16, 9, 14, 12, 16, 11, 13, - 12, 16, 11, 14, 12, 16, 12, 13, 16, 16, 14, 16, 16, 16, 13, 14, - 7, 16, 10, 14, 10, 16, 12, 14, 11, 16, 11, 14, 11, 16, 12, 14, - 16, 16, 16, 16, 16, 16, 14, 14, 8, 16, 10, 14, 10, 16, 11, 13, - 10, 16, 11, 13, 11, 16, 12, 13, 16, 16, 14, 16, 16, 16, 14, 14, - 10, 16, 9, 13, 12, 16, 11, 13, 11, 16, 10, 13, 12, 16, 11, 12, - 16, 16, 13, 15, 15, 16, 13, 13, 9, 16, 11, 14, 9, 16, 11, 13, - 12, 16, 12, 16, 12, 16, 12, 13, 16, 16, 16, 16, 15, 16, 14, 14, - 10, 16, 11, 14, 10, 16, 11, 13, 11, 16, 12, 14, 10, 15, 11, 13, - 16, 16, 15, 16, 13, 16, 13, 13, 12, 16, 11, 13, 12, 16, 11, 12, - 12, 16, 11, 13, 11, 14, 11, 11, 13, 16, 12, 13, 12, 14, 11, 11, - }, - { - 0, 10, 5, 10, 6, 11, 8, 10, 7, 12, 8, 11, 8, 12, 9, 10, - 14, 16, 13, 13, 13, 14, 12, 11, 4, 12, 6, 10, 8, 12, 9, 10, - 8, 13, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, - 9, 15, 8, 12, 12, 14, 10, 11, 11, 16, 9, 12, 12, 14, 10, 10, - 14, 16, 11, 13, 13, 15, 11, 11, 4, 12, 8, 11, 6, 11, 9, 10, - 8, 13, 9, 11, 8, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, - 7, 13, 8, 11, 9, 12, 9, 10, 8, 13, 9, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 12, 13, 11, 10, 11, 16, 10, 12, 12, 14, 10, 11, - 11, 16, 10, 12, 12, 14, 10, 10, 15, 16, 11, 13, 13, 14, 11, 10, - 10, 16, 11, 13, 9, 13, 10, 11, 11, 15, 12, 13, 10, 12, 10, 11, - 15, 16, 13, 14, 12, 13, 11, 11, 11, 16, 11, 13, 10, 13, 10, 11, - 12, 16, 11, 13, 10, 13, 10, 10, 15, 16, 13, 14, 12, 13, 11, 10, - 13, 16, 12, 13, 13, 14, 11, 11, 14, 16, 12, 13, 12, 14, 11, 10, - 16, 16, 13, 13, 13, 14, 11, 9, 3, 11, 6, 10, 6, 11, 9, 10, - 8, 12, 8, 11, 9, 12, 9, 10, 14, 16, 13, 13, 13, 13, 12, 11, - 5, 12, 6, 10, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 13, 14, 11, 11, 9, 15, 8, 11, 11, 14, 10, 10, - 11, 15, 9, 11, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 11, 10, - 5, 12, 8, 11, 7, 11, 9, 10, 8, 13, 9, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 13, 13, 11, 11, 7, 13, 8, 11, 8, 12, 9, 10, - 8, 13, 8, 11, 9, 12, 9, 9, 13, 16, 11, 13, 12, 13, 11, 10, - 10, 15, 9, 12, 11, 14, 10, 10, 11, 15, 9, 11, 11, 13, 10, 10, - 14, 16, 11, 12, 13, 14, 10, 10, 9, 16, 11, 13, 9, 12, 10, 10, - 11, 16, 11, 13, 9, 12, 10, 10, 15, 16, 13, 14, 12, 13, 11, 10, - 11, 16, 11, 13, 10, 13, 10, 10, 11, 15, 11, 13, 9, 12, 10, 10, - 14, 16, 12, 13, 11, 13, 10, 10, 13, 16, 12, 13, 12, 14, 11, 10, - 13, 16, 11, 13, 12, 13, 10, 10, 14, 16, 11, 12, 12, 13, 10, 9, - 7, 14, 8, 12, 9, 13, 10, 11, 10, 14, 10, 12, 11, 13, 11, 11, - 16, 16, 14, 14, 14, 14, 12, 12, 7, 14, 8, 12, 9, 13, 10, 11, - 10, 14, 10, 12, 11, 13, 10, 11, 16, 16, 13, 13, 14, 14, 12, 11, - 10, 15, 9, 12, 12, 14, 10, 10, 12, 16, 9, 12, 12, 14, 10, 10, - 16, 16, 12, 13, 14, 15, 12, 11, 8, 14, 9, 12, 9, 13, 10, 11, - 10, 15, 10, 12, 10, 13, 10, 11, 16, 16, 14, 14, 14, 14, 12, 11, - 8, 14, 9, 12, 9, 13, 10, 11, 10, 14, 10, 12, 10, 13, 10, 10, - 15, 16, 13, 13, 13, 14, 12, 11, 10, 15, 10, 12, 12, 14, 10, 10, - 11, 16, 9, 12, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 11, 10, - 11, 16, 11, 14, 9, 13, 10, 11, 12, 16, 12, 14, 10, 13, 11, 11, - 16, 16, 14, 15, 13, 14, 12, 11, 11, 16, 12, 14, 10, 13, 11, 11, - 11, 16, 11, 13, 10, 13, 10, 10, 15, 16, 13, 14, 12, 13, 11, 10, - 13, 16, 12, 14, 13, 14, 11, 10, 12, 16, 11, 13, 12, 13, 10, 10, - 14, 16, 11, 12, 11, 13, 10, 9, 10, 16, 10, 13, 11, 14, 11, 11, - 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 14, 13, 14, 15, 12, 11, - 10, 16, 10, 13, 10, 14, 11, 11, 12, 16, 11, 13, 11, 14, 11, 11, - 16, 16, 14, 13, 14, 14, 12, 11, 11, 15, 9, 12, 11, 14, 10, 10, - 13, 16, 10, 12, 12, 14, 10, 10, 16, 16, 13, 13, 14, 14, 11, 10, - 10, 16, 10, 13, 11, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, - 16, 16, 14, 14, 14, 14, 12, 11, 9, 16, 10, 13, 10, 14, 11, 11, - 11, 15, 11, 12, 11, 13, 11, 11, 16, 16, 13, 13, 14, 14, 12, 10, - 10, 15, 9, 12, 11, 14, 10, 10, 11, 16, 9, 11, 11, 13, 10, 9, - 15, 16, 11, 12, 13, 14, 10, 9, 11, 16, 11, 13, 10, 13, 10, 10, - 13, 16, 12, 13, 11, 13, 10, 10, 16, 16, 14, 14, 13, 13, 11, 10, - 11, 16, 11, 13, 10, 13, 10, 10, 12, 16, 11, 13, 10, 13, 10, 10, - 15, 16, 13, 13, 12, 13, 11, 9, 11, 16, 11, 12, 11, 13, 10, 9, - 11, 15, 10, 11, 11, 12, 9, 8, 13, 15, 10, 10, 10, 11, 8, 7, - }, - { - 0, 9, 3, 8, 5, 9, 7, 8, 5, 11, 6, 9, 8, 11, 8, 9, - 16, 16, 16, 16, 16, 16, 11, 10, 2, 10, 4, 9, 7, 10, 7, 8, - 7, 16, 7, 10, 9, 11, 8, 9, 16, 16, 11, 16, 16, 16, 11, 10, - 7, 16, 7, 10, 10, 16, 8, 9, 10, 16, 8, 10, 11, 16, 9, 9, - 16, 16, 16, 16, 16, 16, 11, 10, 3, 11, 6, 9, 6, 11, 8, 8, - 7, 16, 8, 10, 8, 11, 8, 9, 16, 16, 15, 16, 16, 16, 11, 10, - 5, 11, 7, 9, 8, 11, 8, 8, 7, 16, 7, 10, 8, 11, 8, 8, - 16, 16, 11, 16, 16, 16, 10, 9, 9, 16, 8, 11, 11, 16, 9, 9, - 10, 16, 8, 11, 11, 16, 9, 9, 16, 16, 10, 16, 16, 16, 10, 9, - 8, 16, 10, 11, 8, 16, 9, 9, 11, 16, 11, 16, 10, 16, 10, 9, - 16, 16, 16, 16, 16, 16, 11, 10, 9, 16, 10, 16, 10, 16, 9, 9, - 10, 16, 10, 16, 9, 16, 9, 9, 16, 16, 16, 16, 15, 16, 10, 9, - 16, 16, 11, 16, 16, 16, 10, 10, 13, 16, 11, 16, 11, 16, 10, 9, - 16, 16, 10, 11, 11, 16, 9, 8, 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, 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, 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, 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, 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, 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, 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, - }, - { - 1, 10, 6, 10, 7, 11, 9, 10, 8, 12, 9, 12, 9, 12, 10, 10, - 16, 16, 14, 16, 14, 15, 13, 12, 5, 12, 7, 10, 9, 11, 9, 10, - 9, 13, 9, 12, 10, 13, 10, 10, 16, 16, 14, 15, 14, 14, 13, 12, - 10, 15, 10, 12, 12, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, - 16, 16, 14, 16, 15, 16, 13, 12, 6, 12, 8, 11, 8, 11, 10, 10, - 9, 13, 10, 12, 10, 12, 10, 10, 15, 16, 13, 15, 13, 14, 12, 12, - 7, 13, 9, 11, 9, 12, 10, 10, 9, 14, 10, 12, 10, 13, 10, 10, - 15, 16, 13, 15, 13, 14, 12, 11, 11, 15, 11, 13, 12, 14, 11, 11, - 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 13, 15, 14, 16, 12, 11, - 10, 16, 12, 14, 10, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, - 16, 16, 15, 16, 14, 16, 13, 12, 11, 16, 12, 14, 11, 14, 11, 11, - 12, 16, 12, 14, 11, 14, 11, 11, 16, 16, 14, 15, 13, 15, 12, 12, - 13, 16, 13, 15, 13, 15, 12, 12, 13, 16, 12, 15, 12, 15, 11, 11, - 16, 16, 13, 16, 13, 15, 12, 11, 4, 11, 7, 10, 7, 11, 9, 10, - 9, 13, 9, 12, 10, 12, 10, 10, 15, 16, 14, 15, 14, 15, 13, 12, - 6, 12, 7, 11, 9, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 10, - 15, 16, 14, 15, 14, 15, 12, 12, 10, 15, 9, 12, 12, 13, 11, 11, - 12, 15, 11, 13, 12, 14, 11, 11, 16, 16, 13, 15, 14, 16, 12, 12, - 6, 12, 8, 11, 8, 11, 9, 10, 9, 14, 10, 12, 10, 12, 10, 10, - 14, 16, 13, 14, 13, 14, 12, 12, 8, 13, 9, 11, 9, 12, 10, 10, - 9, 13, 9, 12, 9, 12, 9, 10, 14, 16, 13, 14, 13, 14, 12, 11, - 11, 15, 11, 13, 11, 14, 11, 11, 12, 16, 10, 13, 12, 13, 11, 10, - 15, 16, 12, 15, 13, 16, 12, 11, 10, 15, 11, 13, 10, 13, 11, 11, - 12, 16, 12, 14, 11, 13, 11, 11, 16, 16, 14, 15, 13, 16, 13, 12, - 11, 16, 11, 14, 11, 13, 11, 11, 12, 16, 12, 14, 10, 13, 11, 11, - 15, 16, 13, 16, 12, 14, 12, 11, 12, 16, 12, 14, 12, 15, 11, 11, - 13, 16, 12, 14, 12, 14, 11, 11, 15, 16, 13, 15, 13, 15, 11, 10, - 7, 13, 9, 12, 10, 13, 11, 11, 11, 15, 12, 13, 12, 13, 11, 11, - 16, 16, 15, 16, 16, 16, 14, 13, 8, 13, 9, 12, 10, 13, 11, 11, - 12, 15, 11, 13, 12, 13, 11, 11, 16, 16, 14, 15, 15, 16, 13, 12, - 11, 16, 11, 13, 12, 14, 11, 11, 13, 16, 12, 14, 13, 15, 12, 11, - 16, 16, 14, 16, 15, 16, 13, 12, 9, 15, 10, 13, 10, 13, 11, 11, - 12, 15, 11, 13, 11, 13, 11, 11, 16, 16, 14, 16, 16, 16, 13, 12, - 9, 14, 10, 13, 10, 13, 11, 11, 11, 14, 11, 13, 11, 13, 11, 11, - 16, 16, 14, 16, 14, 16, 12, 12, 11, 16, 11, 14, 12, 14, 12, 11, - 12, 16, 11, 13, 13, 14, 11, 11, 16, 16, 13, 15, 14, 16, 12, 11, - 12, 16, 12, 14, 11, 14, 11, 11, 13, 16, 13, 14, 12, 15, 12, 11, - 16, 16, 16, 16, 14, 16, 13, 12, 12, 16, 12, 14, 11, 14, 12, 11, - 12, 16, 12, 15, 11, 14, 11, 11, 16, 16, 14, 16, 13, 15, 12, 12, - 13, 16, 13, 16, 13, 16, 12, 12, 13, 16, 12, 15, 12, 16, 11, 11, - 14, 16, 12, 15, 12, 15, 11, 10, 9, 16, 11, 14, 12, 14, 12, 12, - 13, 16, 13, 15, 14, 16, 12, 12, 16, 16, 16, 16, 16, 16, 14, 13, - 10, 16, 11, 14, 12, 14, 12, 12, 13, 16, 13, 14, 13, 16, 12, 12, - 16, 16, 15, 16, 16, 16, 13, 12, 11, 16, 11, 14, 12, 15, 12, 11, - 13, 16, 12, 14, 13, 16, 12, 11, 16, 16, 14, 16, 16, 16, 13, 12, - 11, 16, 11, 14, 12, 14, 12, 12, 13, 16, 12, 15, 13, 16, 12, 12, - 16, 16, 16, 16, 16, 16, 14, 13, 10, 16, 11, 14, 11, 15, 11, 11, - 13, 16, 12, 14, 12, 14, 12, 11, 16, 16, 14, 16, 16, 16, 13, 12, - 11, 16, 11, 15, 12, 15, 12, 11, 13, 16, 11, 14, 13, 15, 12, 11, - 16, 16, 13, 16, 14, 16, 12, 11, 12, 16, 12, 15, 11, 15, 12, 11, - 14, 16, 13, 15, 12, 16, 12, 11, 16, 16, 15, 16, 14, 16, 13, 12, - 11, 16, 12, 15, 11, 15, 11, 11, 13, 16, 13, 16, 11, 15, 11, 11, - 16, 16, 14, 16, 13, 15, 12, 11, 12, 16, 12, 15, 12, 16, 11, 11, - 12, 16, 11, 15, 12, 14, 11, 11, 13, 16, 12, 13, 11, 13, 10, 9, - }, - }, - { - { - 0, 13, 6, 13, 8, 14, 12, 16, 8, 16, 11, 16, 12, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 7, 14, 11, 16, 13, 16, - 9, 16, 11, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 10, 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 5, 16, 10, 16, 8, 16, 13, 16, - 10, 16, 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 16, 11, 16, 13, 16, 10, 16, 12, 16, 12, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 16, 16, 16, 16, - 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 11, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, - 14, 16, 16, 16, 13, 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, 1, 13, 7, 13, 8, 16, 12, 16, - 8, 16, 10, 16, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 4, 16, 7, 14, 10, 16, 12, 16, 9, 16, 10, 16, 12, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 9, 16, 14, 16, 14, 16, - 13, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 16, 9, 16, 8, 16, 12, 16, 9, 16, 11, 16, 11, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 10, 16, 11, 16, 13, 16, - 9, 16, 11, 16, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 12, 16, 16, 16, 14, 16, 13, 16, 12, 16, 16, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 13, 16, 11, 16, 14, 16, - 13, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 14, 16, 13, 16, 14, 16, 13, 16, 14, 16, 13, 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, - 4, 16, 8, 16, 9, 16, 13, 16, 10, 16, 11, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 8, 16, 11, 16, 13, 16, - 10, 16, 11, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 9, 16, 13, 16, 13, 16, 13, 16, 12, 16, 16, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 10, 16, 13, 16, - 10, 16, 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 16, 11, 16, 13, 16, 10, 16, 11, 16, 12, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 16, 16, 14, 16, - 12, 16, 11, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 13, 16, 10, 16, 13, 16, 13, 16, 16, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 12, 16, 14, 16, - 12, 16, 15, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 10, 16, 13, 16, - 11, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 9, 16, 11, 16, 12, 16, 11, 16, 11, 16, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 16, 12, 16, 12, 16, - 13, 16, 11, 16, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 16, 10, 16, 12, 16, 11, 16, 12, 16, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 10, 16, 11, 16, 12, 16, - 10, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 10, 14, 12, 16, 12, 16, 11, 16, 10, 14, 13, 16, 12, 14, - 16, 16, 14, 16, 16, 16, 14, 16, 9, 16, 12, 16, 10, 16, 12, 16, - 13, 16, 13, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 11, 16, 12, 16, 11, 16, 12, 16, 11, 16, 12, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 12, 16, 13, 16, 12, 13, - 12, 16, 12, 16, 12, 16, 12, 13, 16, 16, 13, 14, 13, 16, 13, 13, - }, - { - 0, 10, 5, 10, 5, 10, 8, 10, 6, 11, 8, 11, 8, 11, 9, 10, - 14, 16, 13, 14, 13, 14, 12, 12, 4, 12, 5, 10, 8, 12, 9, 10, - 7, 12, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 12, 12, - 9, 16, 8, 12, 12, 14, 10, 11, 11, 16, 9, 12, 12, 14, 11, 11, - 14, 16, 12, 13, 14, 15, 12, 12, 4, 12, 7, 11, 6, 11, 9, 10, - 8, 12, 9, 11, 8, 11, 9, 10, 14, 16, 12, 14, 13, 14, 12, 12, - 7, 13, 8, 11, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 12, 13, 11, 11, 11, 16, 10, 12, 12, 14, 11, 11, - 12, 16, 10, 12, 12, 14, 11, 11, 16, 16, 12, 13, 14, 15, 12, 11, - 10, 16, 11, 14, 9, 13, 10, 11, 11, 16, 12, 14, 10, 13, 11, 11, - 15, 16, 13, 14, 13, 14, 12, 12, 11, 16, 12, 14, 10, 13, 11, 11, - 12, 16, 12, 14, 11, 13, 11, 11, 15, 16, 13, 14, 13, 14, 12, 11, - 14, 16, 13, 14, 13, 15, 12, 12, 14, 16, 12, 14, 13, 15, 11, 11, - 16, 16, 13, 14, 14, 15, 12, 11, 3, 11, 5, 10, 6, 11, 9, 10, - 7, 12, 8, 11, 9, 11, 9, 10, 14, 16, 13, 13, 13, 14, 12, 12, - 5, 12, 6, 10, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, - 14, 16, 12, 13, 13, 14, 12, 12, 9, 16, 8, 11, 11, 14, 10, 11, - 11, 16, 9, 12, 12, 14, 10, 11, 15, 16, 12, 13, 14, 15, 12, 11, - 5, 12, 7, 11, 6, 11, 9, 10, 8, 13, 9, 11, 8, 11, 9, 10, - 14, 16, 12, 14, 13, 13, 12, 12, 7, 13, 8, 11, 8, 12, 9, 10, - 8, 12, 8, 11, 9, 12, 9, 10, 13, 16, 12, 13, 12, 13, 11, 11, - 10, 16, 9, 12, 12, 14, 10, 11, 11, 15, 9, 12, 12, 14, 10, 11, - 14, 16, 11, 13, 13, 14, 11, 11, 9, 16, 11, 14, 8, 13, 10, 11, - 11, 16, 12, 13, 10, 13, 10, 11, 16, 16, 13, 15, 13, 14, 12, 12, - 11, 16, 11, 14, 10, 13, 10, 11, 11, 16, 11, 13, 10, 13, 10, 11, - 14, 16, 13, 14, 12, 13, 11, 11, 14, 16, 12, 14, 13, 15, 11, 11, - 13, 16, 12, 13, 12, 14, 11, 11, 14, 16, 12, 13, 12, 13, 11, 10, - 6, 14, 8, 12, 9, 13, 10, 11, 10, 14, 10, 12, 11, 13, 11, 12, - 16, 16, 14, 14, 14, 14, 13, 12, 7, 14, 8, 12, 9, 13, 10, 11, - 10, 14, 10, 12, 11, 13, 11, 11, 16, 16, 13, 14, 14, 15, 13, 12, - 10, 16, 8, 12, 12, 14, 10, 11, 12, 16, 10, 12, 13, 15, 11, 11, - 16, 16, 13, 14, 15, 16, 12, 12, 8, 15, 9, 13, 9, 13, 10, 11, - 10, 15, 10, 13, 10, 13, 11, 11, 16, 16, 14, 14, 14, 14, 13, 12, - 8, 15, 9, 12, 10, 13, 10, 11, 10, 14, 10, 12, 10, 13, 10, 11, - 16, 16, 13, 14, 13, 14, 12, 12, 10, 16, 10, 13, 12, 15, 11, 11, - 11, 16, 9, 12, 12, 14, 11, 11, 14, 16, 11, 13, 14, 16, 12, 11, - 10, 16, 12, 14, 9, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, - 16, 16, 15, 16, 14, 14, 13, 12, 11, 16, 12, 14, 11, 14, 11, 11, - 11, 16, 12, 14, 10, 13, 11, 11, 15, 16, 13, 15, 12, 14, 12, 11, - 14, 16, 13, 14, 13, 16, 12, 12, 12, 16, 12, 13, 12, 14, 11, 11, - 14, 16, 11, 12, 12, 13, 10, 10, 9, 16, 10, 14, 11, 15, 12, 12, - 12, 16, 11, 13, 12, 15, 12, 12, 16, 16, 14, 13, 15, 15, 13, 12, - 10, 16, 10, 14, 11, 15, 11, 12, 12, 16, 11, 13, 12, 14, 12, 12, - 16, 16, 14, 13, 15, 14, 13, 12, 11, 16, 9, 12, 12, 14, 11, 11, - 13, 16, 11, 13, 13, 15, 11, 11, 16, 16, 14, 14, 16, 16, 12, 12, - 10, 16, 10, 14, 11, 14, 11, 12, 12, 16, 11, 13, 12, 14, 12, 12, - 16, 16, 14, 14, 15, 15, 13, 12, 10, 16, 10, 13, 11, 14, 11, 12, - 11, 16, 11, 13, 11, 14, 11, 12, 16, 16, 14, 14, 14, 14, 13, 12, - 11, 16, 10, 12, 12, 15, 11, 11, 12, 16, 9, 12, 12, 14, 10, 11, - 16, 16, 12, 13, 14, 15, 11, 11, 11, 16, 12, 14, 10, 14, 11, 11, - 13, 16, 12, 14, 12, 14, 11, 11, 16, 16, 15, 15, 14, 15, 12, 12, - 11, 16, 12, 14, 11, 14, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, - 16, 16, 14, 14, 13, 14, 12, 11, 12, 16, 11, 13, 12, 14, 10, 10, - 12, 15, 11, 12, 12, 13, 10, 10, 14, 15, 11, 11, 12, 12, 10, 9, - }, - { - 0, 8, 3, 8, 5, 9, 7, 8, 5, 10, 6, 10, 8, 11, 8, 9, - 16, 16, 15, 16, 16, 16, 11, 11, 2, 10, 4, 9, 7, 10, 7, 8, - 7, 16, 7, 10, 9, 11, 8, 9, 16, 16, 15, 16, 16, 16, 11, 11, - 7, 16, 6, 11, 10, 16, 9, 10, 10, 16, 9, 11, 11, 16, 9, 10, - 16, 16, 16, 16, 16, 16, 16, 11, 3, 10, 6, 9, 5, 10, 7, 9, - 7, 16, 8, 10, 8, 11, 8, 9, 16, 16, 16, 16, 16, 16, 11, 11, - 5, 11, 7, 10, 8, 11, 8, 9, 7, 14, 7, 10, 8, 11, 8, 9, - 16, 16, 11, 16, 16, 16, 10, 11, 9, 16, 9, 11, 11, 16, 9, 10, - 10, 16, 8, 11, 11, 16, 9, 10, 16, 16, 11, 16, 16, 16, 11, 10, - 8, 16, 9, 16, 7, 16, 9, 10, 11, 16, 11, 16, 10, 16, 10, 10, - 16, 16, 16, 16, 16, 16, 16, 11, 9, 16, 10, 16, 9, 16, 9, 10, - 10, 16, 10, 16, 9, 16, 9, 10, 16, 16, 16, 16, 11, 16, 11, 11, - 16, 16, 16, 16, 16, 16, 10, 10, 11, 16, 11, 16, 11, 16, 10, 10, - 16, 16, 11, 16, 11, 16, 10, 9, 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, 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, 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, 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, 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, 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, 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, - }, - { - 1, 10, 6, 10, 7, 11, 9, 10, 8, 12, 9, 12, 9, 12, 10, 10, - 15, 16, 14, 15, 14, 16, 13, 12, 5, 12, 7, 11, 8, 11, 9, 10, - 9, 13, 9, 12, 10, 12, 10, 10, 16, 16, 14, 15, 13, 16, 13, 12, - 10, 15, 10, 13, 12, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, - 16, 16, 14, 16, 14, 16, 13, 12, 5, 12, 8, 11, 7, 11, 9, 10, - 9, 13, 10, 12, 9, 12, 10, 10, 14, 16, 14, 15, 13, 14, 13, 12, - 7, 13, 9, 12, 9, 12, 10, 10, 9, 13, 9, 12, 9, 12, 10, 10, - 14, 16, 13, 14, 13, 15, 12, 12, 11, 16, 11, 13, 12, 14, 11, 11, - 12, 16, 11, 14, 12, 14, 11, 11, 16, 16, 14, 16, 14, 16, 13, 12, - 10, 16, 11, 14, 10, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, - 15, 16, 15, 16, 14, 16, 13, 12, 11, 16, 12, 14, 11, 14, 11, 12, - 12, 16, 12, 14, 11, 14, 11, 11, 15, 16, 14, 16, 13, 16, 13, 12, - 13, 16, 13, 16, 13, 16, 12, 12, 13, 16, 13, 16, 13, 16, 12, 12, - 16, 16, 14, 15, 14, 16, 13, 12, 4, 11, 7, 10, 7, 11, 9, 10, - 9, 13, 9, 11, 9, 12, 10, 10, 15, 16, 14, 15, 14, 15, 13, 12, - 6, 12, 7, 11, 8, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 10, - 15, 16, 13, 14, 14, 15, 12, 12, 10, 14, 10, 12, 12, 13, 11, 11, - 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 14, 15, 15, 16, 13, 12, - 6, 12, 8, 11, 8, 11, 9, 10, 9, 13, 10, 12, 9, 12, 10, 10, - 16, 16, 14, 15, 13, 14, 12, 12, 8, 13, 9, 11, 9, 12, 9, 10, - 9, 13, 9, 12, 9, 12, 9, 10, 14, 16, 13, 14, 13, 14, 12, 11, - 11, 15, 11, 13, 12, 14, 11, 11, 11, 16, 10, 13, 12, 14, 11, 11, - 15, 16, 13, 15, 14, 16, 12, 11, 10, 16, 12, 13, 10, 13, 11, 11, - 11, 16, 12, 14, 10, 13, 11, 11, 16, 16, 14, 16, 13, 16, 13, 12, - 11, 16, 12, 14, 10, 14, 11, 11, 11, 16, 12, 14, 10, 13, 11, 11, - 16, 16, 14, 16, 12, 15, 12, 11, 13, 16, 13, 15, 13, 15, 12, 12, - 13, 16, 12, 15, 12, 15, 12, 11, 15, 16, 13, 16, 13, 16, 12, 11, - 8, 14, 9, 12, 10, 13, 11, 11, 11, 16, 11, 13, 11, 13, 11, 11, - 16, 16, 16, 16, 16, 16, 14, 13, 9, 14, 10, 12, 10, 13, 11, 11, - 11, 16, 11, 13, 12, 13, 11, 11, 16, 16, 15, 16, 15, 16, 14, 12, - 11, 16, 11, 13, 12, 14, 12, 11, 13, 16, 12, 14, 13, 14, 12, 11, - 16, 16, 15, 16, 16, 16, 14, 13, 9, 14, 10, 13, 10, 13, 11, 11, - 11, 16, 11, 13, 11, 13, 11, 11, 16, 16, 15, 16, 14, 15, 14, 13, - 9, 14, 10, 13, 10, 13, 11, 11, 11, 15, 11, 13, 11, 13, 11, 11, - 16, 16, 14, 16, 14, 16, 13, 12, 12, 16, 12, 14, 13, 14, 12, 11, - 12, 16, 11, 14, 12, 15, 12, 11, 16, 16, 13, 16, 15, 16, 13, 11, - 11, 16, 12, 14, 11, 14, 12, 11, 13, 16, 13, 15, 12, 14, 12, 12, - 16, 16, 16, 16, 14, 16, 14, 13, 12, 16, 13, 15, 11, 14, 12, 12, - 12, 16, 13, 14, 11, 15, 12, 11, 16, 16, 15, 16, 13, 15, 13, 12, - 13, 16, 13, 15, 13, 16, 12, 12, 13, 16, 13, 15, 13, 15, 12, 12, - 15, 16, 13, 16, 13, 15, 11, 10, 10, 16, 12, 14, 12, 15, 12, 12, - 14, 16, 13, 15, 13, 16, 13, 12, 16, 16, 16, 16, 16, 16, 15, 13, - 10, 16, 12, 14, 12, 15, 12, 12, 13, 16, 13, 15, 13, 15, 13, 12, - 16, 16, 16, 16, 16, 16, 14, 13, 11, 16, 12, 15, 13, 16, 12, 12, - 14, 16, 13, 16, 13, 16, 12, 12, 16, 16, 15, 16, 15, 16, 14, 12, - 11, 16, 12, 14, 12, 16, 12, 12, 14, 16, 13, 15, 13, 15, 13, 12, - 16, 16, 16, 16, 16, 16, 15, 13, 11, 16, 12, 14, 12, 15, 12, 12, - 13, 16, 12, 14, 12, 15, 12, 12, 16, 16, 16, 16, 16, 16, 14, 12, - 12, 16, 12, 15, 13, 16, 12, 12, 13, 16, 12, 15, 13, 15, 12, 11, - 16, 16, 14, 16, 15, 16, 13, 12, 12, 16, 13, 16, 12, 16, 12, 12, - 15, 16, 14, 16, 13, 16, 12, 12, 16, 16, 16, 16, 16, 16, 14, 13, - 12, 16, 13, 15, 12, 16, 12, 12, 13, 16, 13, 15, 12, 15, 12, 12, - 16, 16, 15, 16, 14, 16, 13, 12, 13, 16, 13, 16, 12, 16, 12, 12, - 13, 16, 12, 16, 12, 15, 12, 12, 14, 16, 12, 14, 12, 14, 11, 10, - }, - }, - { - { - 0, 16, 6, 16, 8, 16, 16, 16, 9, 16, 11, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 7, 16, 11, 16, 16, 16, - 10, 16, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 10, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 5, 16, 10, 16, 9, 16, 16, 16, - 10, 16, 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 11, 16, 12, 16, 16, 16, 10, 16, 12, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 13, 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, 1, 16, 7, 16, 8, 16, 13, 16, - 9, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 4, 16, 7, 16, 11, 16, 13, 16, 9, 16, 11, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 16, 16, 16, 16, 16, - 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 4, 16, 10, 16, 8, 16, 16, 16, 10, 16, 12, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 10, 16, 11, 16, 16, 16, - 9, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 12, 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 16, 16, 11, 16, 16, 16, - 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, 13, 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, - 4, 16, 8, 16, 10, 16, 16, 16, 10, 16, 11, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 8, 16, 11, 16, 16, 16, - 10, 16, 12, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 9, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 10, 16, 16, 16, - 11, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 11, 16, 11, 16, 16, 16, 10, 16, 12, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 12, 16, 16, 16, 16, 16, - 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 12, 16, 16, 16, - 12, 16, 16, 16, 13, 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, 6, 16, 10, 16, 11, 16, 16, 16, - 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 9, 16, 11, 16, 13, 16, 11, 16, 12, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 16, 13, 16, 12, 16, - 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 16, 10, 16, 14, 16, 12, 16, 12, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 11, 16, 13, 16, - 10, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 10, 16, 13, 16, 12, 16, 12, 16, 11, 16, 16, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 12, 16, 10, 16, 13, 16, - 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 13, 16, 11, 16, 13, 16, 12, 16, 13, 16, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 13, 16, 16, 16, 12, 16, - 13, 16, 12, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - }, - { - 0, 10, 4, 10, 5, 11, 9, 11, 6, 11, 8, 11, 8, 12, 10, 12, - 15, 16, 13, 15, 14, 15, 13, 14, 4, 12, 5, 11, 8, 12, 9, 11, - 7, 13, 8, 12, 9, 13, 10, 12, 15, 16, 13, 15, 14, 16, 13, 14, - 10, 16, 9, 13, 12, 16, 11, 13, 11, 16, 10, 14, 13, 16, 12, 13, - 16, 16, 14, 16, 15, 16, 14, 15, 4, 12, 7, 12, 6, 12, 9, 11, - 8, 13, 9, 12, 9, 12, 10, 12, 15, 16, 13, 15, 14, 15, 13, 14, - 7, 13, 8, 12, 9, 13, 10, 12, 8, 13, 9, 12, 9, 13, 10, 12, - 14, 16, 13, 15, 13, 15, 13, 14, 12, 16, 11, 14, 13, 16, 12, 13, - 12, 16, 11, 14, 13, 16, 12, 13, 16, 16, 14, 16, 15, 16, 14, 15, - 10, 16, 12, 16, 10, 14, 12, 13, 12, 16, 13, 16, 11, 14, 12, 13, - 16, 16, 16, 16, 15, 16, 14, 15, 12, 16, 13, 16, 11, 15, 12, 13, - 13, 16, 13, 16, 12, 15, 12, 14, 16, 16, 16, 16, 14, 16, 13, 14, - 16, 16, 14, 16, 14, 16, 13, 15, 16, 16, 14, 16, 14, 16, 13, 15, - 16, 16, 16, 16, 16, 16, 14, 16, 2, 11, 5, 11, 6, 11, 9, 11, - 7, 12, 8, 11, 9, 12, 10, 12, 15, 16, 14, 14, 14, 14, 13, 14, - 4, 13, 6, 11, 8, 12, 9, 11, 8, 13, 8, 12, 10, 13, 10, 12, - 15, 16, 13, 15, 14, 15, 13, 14, 9, 16, 8, 13, 12, 15, 11, 12, - 11, 16, 10, 14, 13, 16, 12, 13, 16, 16, 14, 16, 16, 16, 14, 15, - 5, 13, 8, 12, 7, 12, 9, 11, 8, 13, 9, 12, 9, 12, 10, 12, - 16, 16, 14, 15, 14, 15, 13, 13, 7, 13, 8, 12, 9, 13, 10, 12, - 8, 13, 8, 12, 9, 13, 10, 12, 14, 16, 13, 14, 13, 15, 12, 13, - 11, 16, 10, 14, 13, 16, 12, 13, 11, 16, 10, 13, 12, 15, 11, 13, - 14, 16, 12, 14, 14, 16, 13, 14, 10, 16, 12, 15, 9, 14, 11, 13, - 12, 16, 12, 16, 11, 14, 12, 13, 16, 16, 15, 16, 16, 16, 14, 15, - 11, 16, 12, 15, 11, 15, 12, 13, 12, 16, 12, 15, 11, 14, 12, 13, - 16, 16, 14, 16, 13, 15, 13, 14, 15, 16, 14, 16, 14, 16, 13, 14, - 14, 16, 13, 16, 14, 16, 13, 14, 16, 16, 14, 16, 14, 16, 13, 14, - 7, 15, 8, 13, 9, 14, 11, 13, 10, 14, 10, 13, 11, 14, 12, 13, - 16, 16, 15, 16, 15, 16, 15, 14, 7, 16, 8, 13, 10, 14, 11, 13, - 11, 15, 10, 13, 12, 14, 12, 13, 16, 16, 16, 16, 16, 16, 15, 15, - 10, 16, 9, 13, 13, 16, 12, 13, 13, 16, 11, 14, 14, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 15, 16, 8, 16, 10, 14, 9, 14, 11, 13, - 11, 16, 11, 14, 11, 14, 12, 13, 16, 16, 16, 16, 16, 16, 14, 15, - 8, 16, 10, 14, 10, 14, 11, 13, 10, 15, 10, 14, 11, 14, 12, 13, - 16, 16, 14, 16, 15, 16, 14, 14, 11, 16, 10, 14, 13, 16, 12, 13, - 11, 16, 10, 13, 13, 16, 12, 13, 16, 16, 13, 16, 16, 16, 14, 14, - 11, 16, 12, 16, 10, 15, 12, 13, 14, 16, 14, 16, 12, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 11, 16, 12, 14, - 12, 16, 13, 16, 11, 14, 12, 13, 16, 16, 16, 16, 14, 16, 14, 14, - 15, 16, 14, 16, 16, 16, 13, 14, 13, 16, 13, 15, 14, 16, 13, 14, - 14, 16, 13, 14, 14, 15, 13, 14, 9, 16, 11, 16, 12, 16, 13, 14, - 12, 16, 12, 15, 13, 16, 13, 14, 16, 16, 16, 15, 16, 16, 15, 15, - 10, 16, 10, 16, 12, 16, 12, 14, 12, 16, 12, 14, 13, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 15, 15, 11, 16, 10, 14, 14, 16, 12, 13, - 14, 16, 12, 16, 14, 16, 13, 14, 16, 16, 16, 16, 16, 16, 16, 15, - 10, 16, 12, 16, 11, 16, 12, 14, 13, 16, 12, 15, 13, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 16, 15, 10, 16, 11, 16, 12, 16, 12, 14, - 12, 16, 12, 15, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 14, - 11, 16, 10, 14, 14, 16, 12, 13, 13, 16, 11, 14, 14, 16, 12, 13, - 16, 16, 15, 16, 16, 16, 14, 14, 12, 16, 13, 16, 11, 16, 12, 14, - 15, 16, 14, 16, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 16, - 12, 16, 13, 16, 12, 16, 12, 14, 13, 16, 13, 16, 12, 16, 12, 13, - 16, 16, 16, 16, 16, 16, 14, 15, 13, 16, 13, 16, 14, 16, 12, 13, - 13, 16, 13, 14, 14, 16, 12, 13, 16, 16, 14, 14, 14, 15, 13, 13, - }, - { - 0, 9, 3, 9, 5, 9, 7, 9, 5, 10, 7, 11, 8, 11, 9, 10, - 16, 16, 16, 16, 16, 16, 16, 16, 2, 11, 4, 10, 7, 11, 8, 10, - 7, 16, 7, 11, 9, 16, 9, 11, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 7, 16, 11, 16, 10, 11, 11, 16, 10, 16, 16, 16, 11, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 2, 11, 6, 10, 6, 10, 8, 10, - 7, 16, 8, 16, 8, 11, 9, 11, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 13, 7, 11, 8, 11, 9, 11, 6, 12, 8, 12, 8, 12, 9, 11, - 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 10, 16, 12, 16, 10, 13, - 10, 16, 9, 16, 11, 16, 11, 12, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 16, 8, 16, 10, 12, 11, 16, 12, 16, 10, 16, 11, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 11, 16, 10, 16, 11, 16, - 11, 16, 12, 16, 10, 16, 11, 12, 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, 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, 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, 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, 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, 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, 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, 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, - }, - { - 1, 10, 5, 10, 6, 10, 9, 10, 7, 12, 9, 12, 9, 12, 10, 10, - 16, 16, 15, 16, 14, 16, 13, 13, 5, 12, 7, 11, 8, 11, 9, 10, - 8, 13, 9, 12, 10, 12, 10, 11, 16, 16, 16, 16, 14, 16, 13, 12, - 10, 16, 10, 13, 12, 14, 12, 12, 12, 16, 11, 14, 13, 15, 12, 12, - 16, 16, 16, 15, 16, 16, 14, 13, 5, 12, 8, 11, 7, 11, 9, 10, - 8, 13, 10, 12, 9, 12, 10, 10, 15, 16, 14, 15, 14, 14, 13, 13, - 7, 13, 9, 12, 9, 12, 10, 10, 9, 13, 10, 13, 10, 13, 10, 10, - 14, 16, 14, 15, 14, 16, 13, 12, 11, 16, 12, 14, 12, 15, 12, 12, - 12, 16, 12, 15, 13, 16, 12, 12, 16, 16, 15, 16, 16, 16, 14, 13, - 10, 16, 12, 14, 10, 14, 12, 12, 12, 16, 13, 14, 11, 14, 12, 12, - 16, 16, 16, 16, 14, 16, 14, 13, 11, 16, 12, 14, 11, 14, 12, 12, - 12, 16, 13, 16, 11, 15, 12, 12, 16, 16, 16, 16, 14, 16, 14, 13, - 13, 16, 14, 16, 14, 16, 13, 13, 13, 16, 13, 16, 13, 16, 13, 12, - 16, 16, 16, 16, 16, 16, 13, 13, 4, 11, 7, 10, 7, 11, 9, 10, - 8, 12, 9, 12, 9, 12, 10, 11, 15, 16, 14, 15, 14, 16, 13, 13, - 6, 12, 7, 11, 8, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 10, - 16, 16, 15, 16, 15, 16, 13, 12, 10, 16, 10, 13, 12, 14, 12, 11, - 12, 16, 11, 14, 13, 14, 12, 12, 16, 16, 16, 14, 16, 16, 14, 13, - 6, 12, 8, 11, 7, 11, 9, 10, 9, 14, 10, 12, 9, 12, 10, 10, - 15, 16, 14, 16, 14, 16, 14, 13, 7, 13, 9, 12, 9, 12, 10, 10, - 9, 13, 9, 12, 9, 12, 10, 10, 14, 16, 13, 14, 14, 16, 12, 11, - 11, 16, 11, 14, 12, 14, 12, 12, 12, 16, 11, 14, 12, 14, 12, 11, - 16, 16, 13, 16, 14, 16, 13, 12, 10, 16, 12, 14, 10, 14, 11, 11, - 12, 16, 13, 14, 11, 14, 12, 12, 16, 16, 16, 16, 14, 16, 13, 13, - 11, 16, 12, 16, 11, 14, 12, 12, 12, 16, 12, 14, 11, 14, 12, 11, - 16, 16, 15, 16, 13, 15, 13, 12, 13, 16, 14, 16, 13, 16, 13, 12, - 13, 16, 13, 16, 13, 16, 13, 12, 16, 16, 14, 16, 14, 16, 12, 11, - 8, 13, 10, 12, 10, 13, 11, 11, 11, 14, 12, 14, 12, 14, 12, 12, - 16, 16, 16, 16, 16, 16, 14, 13, 9, 14, 10, 13, 10, 13, 11, 11, - 12, 16, 12, 13, 12, 13, 12, 11, 16, 16, 16, 16, 16, 16, 15, 14, - 12, 16, 11, 14, 13, 15, 12, 12, 13, 16, 12, 15, 14, 15, 13, 12, - 16, 16, 16, 16, 16, 16, 15, 13, 9, 14, 11, 13, 10, 13, 11, 11, - 11, 16, 12, 14, 12, 14, 12, 12, 16, 16, 16, 16, 16, 16, 16, 13, - 10, 15, 11, 13, 11, 14, 12, 11, 11, 16, 12, 14, 11, 14, 12, 11, - 16, 16, 16, 16, 16, 16, 14, 12, 12, 16, 12, 14, 13, 15, 13, 12, - 12, 16, 12, 14, 13, 15, 12, 12, 16, 16, 14, 16, 16, 16, 14, 12, - 12, 16, 13, 16, 11, 14, 12, 12, 14, 16, 14, 16, 12, 16, 13, 12, - 16, 16, 16, 16, 16, 16, 16, 13, 12, 16, 13, 16, 12, 16, 13, 12, - 12, 16, 13, 16, 12, 16, 12, 12, 16, 16, 16, 16, 14, 16, 14, 12, - 14, 16, 14, 16, 14, 16, 14, 13, 13, 16, 13, 16, 13, 16, 13, 12, - 16, 16, 13, 16, 13, 16, 12, 11, 9, 16, 12, 15, 13, 16, 13, 12, - 13, 16, 14, 16, 14, 16, 14, 13, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 16, 12, 15, 12, 15, 13, 12, 13, 16, 14, 16, 13, 16, 13, 12, - 16, 16, 16, 16, 16, 16, 16, 13, 12, 16, 12, 16, 13, 16, 13, 12, - 14, 16, 13, 16, 14, 16, 13, 12, 16, 16, 16, 16, 16, 16, 16, 13, - 11, 16, 12, 15, 12, 16, 13, 12, 14, 16, 14, 16, 13, 16, 13, 13, - 16, 16, 16, 16, 16, 16, 15, 13, 11, 16, 12, 16, 12, 16, 13, 12, - 13, 16, 13, 15, 13, 16, 13, 12, 16, 16, 16, 16, 16, 16, 15, 13, - 12, 16, 12, 16, 13, 16, 13, 12, 13, 16, 12, 16, 13, 16, 13, 12, - 16, 16, 14, 16, 16, 16, 14, 12, 12, 16, 14, 16, 11, 16, 13, 12, - 14, 16, 14, 16, 13, 16, 13, 12, 16, 16, 16, 16, 16, 16, 16, 13, - 12, 16, 13, 16, 12, 16, 13, 12, 13, 16, 13, 16, 12, 16, 13, 12, - 16, 16, 16, 16, 14, 16, 14, 12, 13, 16, 13, 16, 13, 16, 13, 13, - 13, 16, 12, 16, 12, 16, 12, 12, 14, 16, 13, 15, 13, 16, 12, 11, - }, - }, -}; - - -static const uint8_t rv34_table_intra_secondpat[NUM_INTRA_TABLES][2][OTHERBLK_VLC_SIZE] = { - { - { - 0, 5, 10, 3, 6, 10, 7, 8, 9, 4, 6, 10, 6, 7, 9, 8, - 8, 9, 8, 8, 9, 8, 9, 9, 9, 9, 8, 3, 6, 10, 4, 6, - 10, 7, 7, 9, 5, 7, 10, 6, 7, 9, 7, 7, 8, 7, 8, 9, - 8, 8, 9, 8, 8, 7, 6, 8, 10, 6, 8, 10, 7, 8, 9, 7, - 8, 10, 7, 8, 10, 8, 8, 8, 8, 9, 9, 8, 8, 9, 9, 8, - 7, 7, 8, 9, 7, 8, 9, 7, 7, 7, 8, 8, 9, 7, 8, 9, - 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 6, 5, - }, - { - 0, 5, 11, 3, 6, 11, 8, 9, 11, 3, 6, 10, 6, 7, 11, 9, - 9, 11, 7, 9, 11, 9, 9, 11, 10, 10, 11, 2, 6, 10, 4, 7, - 10, 7, 9, 11, 4, 7, 11, 6, 7, 10, 9, 9, 11, 7, 9, 11, - 8, 9, 10, 10, 10, 10, 5, 8, 11, 6, 8, 11, 8, 9, 11, 6, - 8, 11, 7, 8, 11, 9, 9, 11, 8, 10, 11, 9, 9, 11, 10, 10, - 10, 8, 9, 11, 8, 9, 11, 9, 9, 10, 8, 9, 11, 8, 9, 11, - 9, 9, 10, 8, 9, 10, 9, 9, 10, 9, 9, 8, - }, - }, - { - { - 0, 5, 10, 4, 6, 10, 7, 8, 10, 4, 6, 10, 6, 7, 9, 8, - 8, 9, 8, 8, 9, 8, 9, 9, 9, 9, 9, 2, 6, 10, 4, 6, - 10, 7, 7, 9, 5, 7, 10, 6, 7, 9, 7, 7, 9, 7, 8, 9, - 8, 8, 9, 9, 8, 8, 6, 8, 10, 6, 8, 10, 7, 8, 9, 6, - 8, 10, 7, 8, 10, 8, 8, 9, 8, 9, 10, 8, 8, 9, 9, 9, - 8, 8, 8, 10, 7, 8, 9, 7, 8, 8, 7, 8, 10, 7, 8, 9, - 7, 7, 8, 8, 8, 9, 8, 8, 8, 7, 7, 6, - }, - { - 0, 5, 12, 4, 7, 12, 8, 10, 13, 4, 7, 12, 6, 8, 12, 10, - 10, 12, 8, 9, 12, 10, 10, 12, 12, 12, 12, 1, 6, 12, 4, 7, - 12, 8, 9, 12, 4, 7, 12, 6, 8, 11, 9, 10, 12, 8, 9, 12, - 9, 10, 11, 11, 11, 12, 6, 8, 12, 7, 9, 12, 9, 10, 13, 6, - 9, 12, 8, 9, 12, 10, 10, 12, 9, 10, 12, 10, 10, 12, 12, 12, - 12, 8, 10, 12, 9, 10, 12, 10, 10, 12, 8, 10, 12, 9, 10, 12, - 10, 10, 11, 9, 10, 12, 10, 10, 11, 11, 10, 10, - }, - }, - { - { - 0, 5, 10, 3, 6, 10, 7, 8, 11, 4, 6, 10, 6, 7, 10, 8, - 9, 10, 8, 8, 10, 9, 9, 10, 10, 10, 10, 2, 6, 10, 4, 6, - 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, 8, 10, 7, 8, 10, - 8, 8, 9, 10, 9, 9, 5, 8, 11, 6, 8, 10, 7, 9, 10, 6, - 8, 11, 7, 8, 10, 8, 8, 10, 8, 9, 11, 9, 9, 10, 10, 9, - 9, 8, 9, 10, 8, 9, 10, 8, 9, 10, 8, 9, 10, 8, 8, 10, - 8, 8, 9, 8, 9, 10, 8, 8, 9, 9, 8, 8, - }, - { - 0, 6, 13, 4, 7, 14, 9, 11, 14, 3, 7, 13, 7, 8, 13, 11, - 11, 14, 8, 10, 13, 10, 11, 13, 13, 13, 14, 1, 6, 12, 4, 8, - 13, 9, 10, 15, 4, 8, 13, 7, 8, 12, 11, 11, 14, 8, 10, 13, - 10, 10, 13, 13, 13, 14, 5, 9, 13, 7, 9, 13, 10, 11, 14, 6, - 10, 14, 8, 10, 14, 11, 11, 14, 9, 11, 14, 11, 11, 13, 13, 13, - 14, 9, 10, 14, 9, 11, 13, 11, 12, 14, 9, 11, 13, 9, 11, 14, - 11, 12, 13, 10, 12, 15, 11, 11, 13, 13, 12, 13, - }, - }, - { - { - 0, 5, 11, 3, 6, 11, 7, 9, 12, 3, 6, 11, 6, 7, 11, 9, - 9, 11, 8, 9, 11, 9, 9, 11, 11, 11, 12, 2, 6, 11, 4, 6, - 11, 7, 9, 11, 4, 7, 11, 5, 7, 10, 9, 9, 11, 7, 8, 11, - 9, 9, 10, 11, 11, 11, 5, 8, 11, 6, 8, 11, 8, 9, 12, 6, - 8, 11, 7, 8, 11, 9, 9, 11, 8, 9, 12, 9, 9, 11, 11, 11, - 11, 8, 10, 12, 8, 10, 11, 9, 10, 12, 8, 10, 12, 8, 9, 12, - 10, 10, 12, 9, 10, 12, 9, 9, 11, 11, 10, 11, - }, - { - 0, 6, 13, 3, 8, 14, 10, 12, 16, 3, 8, 15, 7, 9, 15, 12, - 13, 15, 9, 11, 15, 11, 12, 16, 14, 16, 16, 1, 7, 13, 4, 8, - 14, 9, 11, 15, 4, 8, 14, 7, 9, 14, 12, 13, 15, 8, 10, 14, - 11, 11, 14, 16, 14, 16, 6, 9, 14, 7, 10, 14, 11, 13, 15, 7, - 10, 14, 9, 10, 13, 12, 12, 15, 10, 11, 14, 11, 11, 14, 14, 14, - 16, 9, 11, 14, 10, 11, 14, 13, 14, 15, 9, 12, 14, 10, 12, 16, - 13, 14, 16, 10, 13, 16, 12, 12, 14, 15, 14, 15, - }, - }, - { - { - 0, 6, 12, 3, 7, 12, 9, 11, 13, 4, 7, 12, 6, 8, 12, 10, - 11, 13, 8, 10, 13, 10, 11, 13, 13, 13, 14, 1, 6, 12, 4, 7, - 12, 9, 10, 14, 4, 7, 12, 6, 7, 12, 10, 11, 13, 8, 9, 13, - 10, 10, 12, 13, 13, 14, 6, 9, 13, 7, 9, 13, 10, 12, 14, 7, - 9, 13, 8, 10, 13, 11, 11, 14, 9, 11, 13, 11, 11, 14, 13, 13, - 14, 10, 12, 14, 10, 12, 14, 12, 13, 15, 10, 12, 14, 10, 12, 14, - 12, 13, 15, 11, 13, 15, 12, 12, 15, 14, 14, 14, - }, - { - 0, 6, 16, 3, 8, 16, 10, 13, 16, 3, 8, 16, 7, 9, 16, 13, - 16, 16, 8, 10, 16, 11, 13, 16, 16, 16, 16, 1, 7, 14, 4, 8, - 16, 10, 12, 16, 4, 8, 13, 7, 9, 16, 13, 14, 16, 8, 10, 16, - 11, 11, 14, 16, 16, 16, 6, 9, 14, 8, 10, 14, 12, 16, 16, 6, - 10, 13, 9, 11, 16, 13, 14, 16, 9, 12, 16, 12, 11, 16, 16, 16, - 16, 10, 12, 16, 11, 12, 16, 16, 14, 16, 9, 12, 16, 11, 12, 16, - 16, 15, 16, 10, 13, 16, 12, 13, 16, 16, 16, 16, - }, - }, -}; - -static const uint8_t rv34_table_intra_thirdpat[NUM_INTRA_TABLES][2][OTHERBLK_VLC_SIZE] = { - { - { - 0, 5, 10, 3, 6, 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, - 8, 10, 8, 9, 10, 9, 9, 10, 9, 9, 9, 2, 6, 10, 4, 7, - 10, 7, 8, 9, 5, 7, 10, 6, 7, 10, 8, 8, 9, 8, 9, 10, - 8, 8, 9, 9, 9, 8, 6, 8, 11, 6, 8, 10, 7, 8, 10, 6, - 8, 11, 7, 8, 10, 8, 8, 9, 8, 9, 10, 9, 9, 10, 9, 9, - 9, 7, 8, 10, 7, 8, 10, 7, 8, 8, 7, 8, 10, 7, 8, 9, - 7, 8, 8, 8, 8, 9, 8, 8, 8, 7, 7, 7, - }, - { - 0, 4, 10, 3, 6, 10, 7, 8, 11, 3, 6, 10, 5, 7, 10, 9, - 9, 11, 9, 10, 11, 9, 10, 11, 11, 11, 11, 2, 6, 10, 4, 6, - 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, 9, 10, 8, 9, 11, - 9, 9, 11, 10, 10, 11, 6, 8, 11, 6, 8, 11, 8, 9, 11, 7, - 9, 11, 7, 8, 11, 9, 9, 11, 9, 10, 12, 10, 10, 12, 11, 11, - 11, 8, 9, 11, 8, 9, 11, 9, 9, 11, 9, 10, 11, 9, 10, 11, - 9, 10, 11, 10, 11, 12, 10, 10, 12, 10, 10, 10, - }, - }, - { - { - 0, 5, 10, 3, 6, 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, - 9, 10, 8, 9, 11, 8, 9, 10, 10, 10, 10, 2, 6, 10, 4, 6, - 10, 7, 8, 10, 4, 7, 10, 5, 7, 10, 8, 8, 10, 8, 9, 10, - 8, 9, 10, 9, 9, 9, 5, 7, 11, 6, 8, 11, 7, 8, 11, 6, - 8, 11, 7, 8, 10, 8, 9, 10, 8, 9, 11, 9, 9, 10, 10, 9, - 10, 7, 8, 10, 7, 8, 10, 8, 9, 10, 8, 9, 10, 8, 9, 10, - 8, 8, 10, 9, 9, 10, 9, 9, 10, 9, 9, 9, - }, - { - 0, 5, 11, 3, 6, 11, 8, 9, 12, 4, 7, 12, 6, 7, 12, 9, - 10, 13, 10, 11, 13, 10, 11, 14, 12, 13, 14, 1, 6, 11, 4, 7, - 11, 8, 9, 12, 5, 7, 11, 6, 8, 12, 9, 10, 13, 10, 11, 14, - 10, 11, 13, 12, 12, 14, 6, 8, 12, 7, 9, 13, 9, 10, 14, 7, - 10, 13, 8, 10, 12, 11, 11, 13, 11, 13, 14, 11, 12, 14, 13, 13, - 15, 9, 10, 12, 9, 11, 14, 10, 11, 14, 11, 11, 13, 10, 11, 13, - 11, 12, 14, 12, 14, 15, 13, 13, 14, 13, 13, 14, - }, - }, - { - { - 0, 5, 11, 3, 6, 11, 7, 9, 11, 4, 6, 11, 5, 7, 10, 9, - 9, 11, 8, 9, 11, 9, 10, 11, 11, 11, 11, 2, 6, 10, 3, 6, - 10, 7, 9, 11, 4, 7, 10, 5, 7, 10, 8, 9, 11, 8, 9, 11, - 9, 9, 11, 11, 11, 11, 5, 8, 11, 6, 8, 11, 8, 10, 12, 6, - 8, 11, 7, 8, 11, 9, 10, 11, 9, 10, 12, 9, 10, 11, 11, 11, - 11, 8, 9, 11, 8, 10, 12, 9, 11, 12, 8, 10, 12, 9, 10, 12, - 10, 11, 12, 10, 11, 12, 10, 10, 11, 11, 11, 11, - }, - { - 0, 5, 13, 2, 7, 16, 9, 11, 16, 4, 8, 16, 7, 9, 16, 12, - 12, 16, 12, 16, 16, 12, 16, 16, 16, 16, 16, 1, 6, 13, 4, 8, - 16, 9, 11, 16, 6, 9, 16, 7, 10, 16, 13, 13, 16, 13, 15, 16, - 12, 16, 16, 16, 16, 16, 7, 9, 16, 8, 11, 15, 11, 13, 16, 10, - 12, 16, 10, 12, 16, 16, 13, 16, 16, 16, 16, 14, 16, 16, 16, 16, - 16, 12, 12, 16, 12, 16, 16, 16, 16, 16, 13, 14, 16, 12, 13, 16, - 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, - }, - }, - { - { - 0, 6, 11, 3, 7, 11, 8, 10, 12, 4, 7, 11, 6, 8, 11, 10, - 11, 12, 9, 10, 12, 10, 10, 12, 12, 12, 13, 1, 6, 11, 4, 7, - 11, 8, 10, 12, 4, 7, 11, 6, 8, 11, 10, 10, 12, 9, 10, 12, - 10, 10, 12, 13, 13, 13, 6, 8, 12, 7, 10, 12, 10, 12, 13, 7, - 9, 12, 8, 10, 12, 11, 11, 13, 11, 12, 14, 11, 11, 13, 13, 13, - 13, 9, 11, 13, 10, 12, 14, 12, 13, 15, 10, 12, 14, 11, 12, 14, - 13, 13, 14, 12, 13, 15, 13, 13, 14, 14, 14, 14, - }, - { - 0, 5, 16, 2, 6, 16, 10, 14, 16, 4, 8, 16, 7, 9, 16, 11, - 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 1, 6, 12, 4, 8, - 12, 12, 12, 16, 6, 8, 16, 8, 10, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 12, 16, 16, 7, 10, 16, 8, 11, 14, 16, 16, 16, 10, - 12, 16, 10, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - }, - }, - { - { - 0, 5, 11, 3, 6, 11, 10, 10, 12, 3, 7, 11, 6, 8, 11, 11, - 11, 12, 10, 10, 12, 11, 11, 13, 14, 13, 14, 1, 6, 11, 4, 7, - 11, 10, 11, 13, 5, 7, 11, 7, 8, 11, 11, 11, 13, 10, 11, 13, - 11, 11, 12, 13, 13, 14, 7, 10, 12, 9, 11, 13, 12, 13, 14, 9, - 10, 13, 9, 10, 13, 12, 11, 13, 12, 13, 16, 12, 13, 13, 14, 14, - 14, 11, 14, 16, 12, 14, 15, 14, 13, 16, 13, 13, 15, 13, 14, 16, - 14, 13, 16, 13, 13, 16, 13, 14, 15, 15, 14, 15, - }, - { - 0, 4, 16, 2, 7, 16, 10, 16, 16, 4, 10, 16, 7, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 6, 13, 4, 11, - 16, 16, 16, 16, 6, 10, 16, 8, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 8, 16, 16, 10, 16, 16, 16, 16, 16, 10, - 16, 16, 10, 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, - }, - }, -}; - - -static const uint8_t rv34_intra_coeff[NUM_INTRA_TABLES][COEFF_VLC_SIZE] = { -{ - 1, 3, 3, 4, 4, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, - 9, 9, 10, 10, 10, 11, 11, 11, 10, 10, 10, 12, 13, 14, 15, 15, -}, -{ - 1, 2, 3, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 10, 11, - 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 16, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, - 13, 13, 14, 14, 14, 14, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, - 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 14, 12, 16, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 5, 7, 7, 8, 8, 9, 10, 10, 12, 11, 13, 12, - 15, 13, 14, 13, 12, 15, 14, 13, 12, 12, 10, 11, 16, 16, 16, 16, -} -}; - - -static const uint8_t rv34_inter_cbppat[NUM_INTER_TABLES][CBPPAT_VLC_SIZE] = { -{ - 7, 9, 9, 8, 9, 8, 9, 8, 9, 9, 8, 8, 8, 8, 8, 4, - 7, 10, 11, 10, 11, 10, 12, 10, 12, 11, 11, 10, 11, 10, 10, 7, - 10, 11, 15, 12, 15, 12, 15, 12, 15, 14, 14, 12, 14, 12, 14, 9, - 7, 11, 10, 10, 12, 11, 11, 10, 11, 12, 10, 10, 11, 10, 10, 7, - 8, 12, 12, 11, 13, 12, 12, 10, 13, 13, 12, 10, 12, 11, 11, 7, - 11, 13, 15, 11, 15, 13, 15, 12, 16, 14, 14, 12, 15, 13, 13, 9, - 10, 15, 11, 12, 15, 14, 14, 12, 15, 15, 12, 12, 14, 14, 12, 9, - 11, 15, 13, 12, 16, 15, 14, 12, 15, 15, 13, 12, 15, 14, 13, 9, - 13, 15, 14, 10, 16, 15, 16, 11, 16, 16, 15, 12, 16, 15, 15, 9, - 7, 11, 11, 11, 11, 10, 11, 10, 11, 12, 11, 10, 10, 10, 10, 7, - 9, 12, 13, 12, 12, 11, 13, 10, 13, 13, 12, 11, 12, 10, 11, 7, - 12, 13, 16, 14, 15, 12, 16, 12, 16, 15, 15, 13, 15, 12, 14, 9, - 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 7, - 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 13, 11, 12, 11, 11, 7, - 12, 14, 15, 13, 16, 13, 15, 11, 16, 14, 15, 12, 15, 12, 13, 8, - 12, 16, 14, 14, 16, 15, 15, 13, 16, 15, 14, 13, 15, 14, 13, 9, - 12, 15, 14, 13, 15, 14, 15, 12, 16, 15, 14, 12, 14, 13, 13, 8, - 13, 16, 16, 12, 16, 14, 16, 11, 16, 16, 15, 12, 16, 14, 14, 8, - 10, 15, 15, 15, 12, 12, 14, 12, 14, 15, 15, 14, 12, 12, 13, 9, - 11, 15, 16, 14, 13, 12, 15, 12, 16, 15, 15, 14, 14, 12, 13, 9, - 14, 15, 16, 16, 15, 11, 16, 12, 16, 16, 16, 15, 16, 12, 15, 9, - 12, 16, 16, 15, 14, 14, 14, 13, 16, 16, 15, 14, 14, 13, 13, 9, - 12, 15, 15, 14, 14, 13, 15, 12, 16, 15, 14, 13, 14, 13, 13, 8, - 13, 16, 16, 15, 16, 12, 16, 11, 16, 16, 16, 14, 16, 13, 14, 8, - 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 16, 15, 16, 15, 14, 11, - 13, 16, 16, 15, 16, 15, 15, 12, 16, 16, 16, 14, 15, 14, 14, 9, - 14, 16, 16, 13, 16, 14, 16, 10, 16, 16, 16, 13, 16, 14, 14, 8, - 7, 12, 11, 11, 11, 11, 12, 10, 11, 11, 10, 10, 10, 10, 10, 7, - 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 8, - 12, 14, 16, 14, 16, 14, 16, 13, 16, 14, 15, 13, 15, 13, 14, 9, - 9, 13, 12, 12, 13, 12, 13, 11, 12, 13, 11, 10, 12, 11, 11, 7, - 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 7, - 12, 14, 16, 13, 16, 14, 15, 12, 15, 15, 14, 12, 15, 13, 13, 8, - 11, 15, 13, 14, 15, 15, 14, 13, 15, 15, 12, 12, 14, 14, 12, 9, - 11, 15, 14, 13, 15, 14, 14, 12, 15, 14, 13, 11, 14, 13, 12, 8, - 13, 16, 15, 12, 16, 15, 16, 12, 16, 16, 14, 11, 15, 14, 14, 8, - 8, 13, 13, 12, 12, 12, 13, 11, 12, 13, 12, 11, 11, 10, 10, 7, - 9, 13, 14, 12, 13, 12, 13, 11, 13, 13, 13, 11, 12, 11, 11, 7, - 12, 14, 16, 14, 15, 13, 15, 12, 15, 15, 15, 13, 14, 12, 13, 8, - 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 7, - 9, 13, 12, 12, 13, 12, 12, 10, 13, 13, 12, 10, 12, 10, 10, 6, - 11, 14, 14, 12, 14, 12, 14, 11, 14, 14, 13, 11, 13, 11, 12, 7, - 12, 16, 14, 14, 15, 15, 14, 13, 15, 15, 13, 12, 14, 13, 12, 8, - 11, 14, 13, 12, 14, 13, 13, 11, 14, 14, 13, 11, 13, 12, 11, 7, - 11, 14, 14, 12, 15, 13, 14, 11, 15, 14, 13, 11, 14, 12, 12, 6, - 11, 16, 15, 15, 13, 14, 15, 13, 14, 15, 15, 13, 12, 12, 12, 9, - 12, 15, 15, 14, 14, 13, 15, 12, 15, 15, 14, 13, 13, 11, 12, 8, - 13, 16, 16, 15, 16, 13, 16, 13, 16, 16, 15, 14, 14, 12, 14, 8, - 11, 16, 15, 14, 14, 14, 14, 13, 15, 15, 14, 13, 13, 12, 12, 8, - 11, 14, 14, 13, 13, 12, 14, 11, 14, 14, 13, 12, 12, 11, 11, 7, - 12, 14, 15, 13, 14, 12, 14, 11, 15, 14, 14, 12, 13, 11, 12, 7, - 13, 16, 16, 16, 16, 15, 16, 14, 16, 16, 15, 14, 15, 14, 13, 9, - 12, 15, 14, 13, 15, 13, 14, 12, 15, 15, 13, 12, 13, 12, 12, 7, - 11, 15, 14, 12, 14, 13, 14, 10, 15, 14, 13, 11, 13, 11, 11, 5, - 10, 15, 15, 15, 15, 14, 15, 13, 12, 14, 12, 12, 12, 13, 12, 9, - 12, 16, 16, 15, 16, 15, 16, 14, 14, 15, 14, 13, 14, 13, 13, 9, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 15, 11, - 11, 15, 15, 14, 15, 15, 15, 14, 14, 15, 12, 12, 13, 13, 12, 9, - 12, 15, 15, 14, 16, 14, 15, 13, 14, 14, 13, 12, 14, 13, 12, 8, - 13, 16, 16, 15, 16, 16, 16, 14, 16, 16, 15, 12, 16, 14, 14, 9, - 13, 16, 14, 16, 16, 16, 16, 15, 15, 16, 11, 12, 16, 15, 12, 9, - 13, 16, 15, 14, 16, 15, 16, 14, 15, 16, 12, 11, 15, 14, 13, 8, - 13, 16, 16, 13, 16, 16, 16, 13, 16, 16, 13, 11, 16, 14, 14, 8, - 11, 15, 15, 15, 14, 14, 15, 13, 13, 15, 14, 13, 12, 12, 12, 9, - 11, 15, 16, 14, 15, 14, 15, 13, 14, 14, 14, 13, 13, 12, 13, 8, - 13, 16, 16, 16, 16, 15, 16, 14, 16, 16, 16, 13, 15, 12, 14, 9, - 11, 16, 15, 14, 14, 14, 15, 13, 14, 14, 13, 12, 13, 12, 11, 8, - 11, 14, 14, 13, 14, 13, 14, 12, 13, 13, 12, 11, 12, 11, 11, 7, - 12, 15, 15, 13, 15, 14, 15, 12, 15, 14, 14, 11, 13, 12, 12, 7, - 13, 16, 15, 15, 16, 16, 16, 14, 15, 16, 12, 12, 14, 14, 12, 8, - 11, 15, 14, 13, 15, 13, 14, 12, 14, 14, 12, 11, 13, 12, 11, 6, - 11, 14, 14, 12, 15, 13, 14, 11, 15, 14, 12, 10, 13, 11, 11, 5, - 12, 16, 16, 16, 15, 15, 16, 15, 14, 16, 15, 15, 10, 12, 12, 9, - 13, 16, 16, 16, 15, 14, 16, 13, 15, 15, 15, 14, 12, 11, 13, 8, - 14, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 14, 14, 11, 14, 8, - 13, 16, 16, 15, 15, 15, 15, 14, 15, 16, 14, 13, 12, 12, 11, 8, - 11, 15, 15, 13, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 6, - 11, 15, 15, 13, 15, 12, 14, 11, 14, 14, 13, 11, 12, 10, 11, 5, - 13, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, 14, 14, 13, 11, 8, - 11, 14, 14, 13, 14, 13, 14, 11, 14, 14, 12, 11, 12, 11, 10, 5, - 10, 13, 13, 11, 13, 12, 13, 9, 13, 13, 12, 9, 12, 10, 10, 3, -}, -{ - 5, 7, 7, 7, 7, 7, 8, 7, 7, 8, 7, 7, 7, 7, 7, 4, - 7, 9, 11, 9, 11, 9, 11, 9, 11, 10, 10, 9, 10, 9, 10, 6, - 11, 11, 14, 11, 14, 11, 14, 11, 15, 13, 14, 12, 14, 12, 13, 9, - 6, 11, 10, 9, 11, 10, 11, 9, 11, 11, 9, 9, 10, 10, 9, 6, - 8, 11, 11, 10, 12, 11, 12, 10, 12, 12, 11, 10, 12, 11, 11, 7, - 11, 13, 14, 11, 15, 13, 15, 11, 15, 14, 14, 12, 14, 13, 13, 9, - 10, 14, 11, 11, 15, 14, 13, 12, 14, 14, 11, 11, 14, 13, 12, 9, - 11, 14, 13, 11, 15, 14, 14, 11, 15, 15, 13, 11, 14, 14, 13, 9, - 12, 14, 14, 10, 16, 15, 16, 11, 16, 16, 15, 11, 16, 15, 14, 9, - 6, 10, 11, 10, 10, 9, 11, 9, 10, 11, 10, 10, 9, 9, 9, 6, - 9, 12, 12, 11, 12, 10, 12, 10, 12, 12, 12, 11, 11, 10, 11, 7, - 12, 13, 15, 13, 14, 11, 15, 11, 15, 15, 14, 13, 14, 12, 14, 9, - 9, 12, 12, 11, 12, 11, 12, 11, 12, 13, 11, 11, 12, 11, 11, 7, - 9, 12, 12, 11, 13, 11, 12, 10, 13, 13, 12, 11, 12, 11, 11, 7, - 12, 14, 15, 12, 15, 12, 14, 11, 15, 15, 14, 12, 14, 13, 13, 8, - 12, 15, 14, 13, 15, 14, 14, 13, 16, 16, 14, 13, 15, 14, 13, 9, - 12, 15, 14, 13, 15, 14, 14, 12, 15, 15, 13, 12, 14, 13, 13, 9, - 13, 15, 15, 12, 16, 14, 15, 11, 16, 16, 15, 12, 15, 14, 14, 9, - 10, 14, 14, 14, 12, 11, 13, 12, 14, 15, 14, 13, 12, 11, 12, 9, - 12, 14, 15, 14, 13, 11, 14, 12, 15, 15, 15, 14, 13, 11, 13, 9, - 13, 15, 16, 15, 14, 11, 16, 11, 16, 16, 16, 14, 15, 12, 15, 9, - 12, 15, 15, 14, 14, 14, 14, 13, 15, 15, 14, 14, 14, 13, 13, 9, - 12, 15, 15, 14, 14, 13, 14, 12, 15, 15, 14, 13, 14, 13, 13, 9, - 13, 15, 16, 14, 15, 13, 16, 11, 16, 16, 15, 14, 15, 13, 14, 9, - 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 16, 16, 16, 16, 14, 11, - 14, 16, 16, 14, 16, 15, 15, 12, 16, 16, 16, 14, 15, 14, 14, 9, - 14, 16, 16, 14, 16, 14, 16, 11, 16, 16, 16, 14, 16, 14, 14, 9, - 6, 11, 10, 10, 10, 10, 11, 10, 10, 11, 9, 9, 9, 9, 9, 6, - 9, 12, 12, 11, 13, 11, 13, 11, 12, 12, 11, 11, 12, 11, 11, 7, - 12, 14, 16, 13, 16, 14, 16, 13, 15, 14, 15, 12, 15, 13, 14, 9, - 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 11, 10, 7, - 9, 12, 12, 11, 13, 12, 13, 11, 13, 12, 11, 10, 12, 11, 11, 7, - 12, 14, 15, 12, 15, 14, 15, 12, 15, 14, 14, 12, 14, 13, 13, 9, - 11, 15, 13, 13, 15, 14, 14, 13, 14, 15, 11, 11, 14, 14, 12, 9, - 11, 14, 13, 12, 15, 14, 14, 12, 14, 14, 12, 11, 14, 13, 12, 8, - 13, 15, 15, 12, 16, 15, 15, 12, 15, 15, 14, 11, 15, 14, 14, 8, - 8, 12, 12, 11, 11, 11, 12, 11, 11, 12, 11, 11, 10, 10, 10, 7, - 9, 13, 13, 12, 13, 11, 13, 11, 12, 13, 12, 11, 11, 10, 11, 7, - 12, 14, 15, 14, 15, 13, 15, 12, 15, 14, 14, 13, 14, 12, 13, 9, - 9, 13, 12, 12, 12, 12, 12, 11, 12, 13, 11, 11, 11, 11, 10, 7, - 9, 12, 12, 11, 12, 11, 12, 10, 12, 12, 11, 10, 11, 10, 10, 7, - 11, 13, 14, 12, 14, 12, 14, 11, 14, 13, 13, 11, 13, 11, 12, 7, - 12, 15, 14, 13, 15, 14, 14, 13, 15, 15, 13, 12, 13, 13, 12, 9, - 11, 14, 13, 12, 14, 13, 13, 11, 14, 14, 12, 11, 13, 12, 11, 7, - 11, 14, 14, 12, 14, 13, 14, 11, 14, 14, 13, 11, 13, 12, 12, 7, - 11, 15, 15, 14, 13, 13, 14, 13, 14, 15, 14, 13, 11, 11, 12, 9, - 12, 15, 15, 14, 14, 12, 14, 12, 14, 14, 14, 13, 12, 11, 12, 8, - 13, 16, 16, 15, 15, 12, 16, 13, 16, 15, 15, 14, 14, 12, 14, 9, - 12, 15, 15, 14, 14, 14, 14, 13, 15, 15, 14, 13, 12, 12, 12, 9, - 11, 14, 14, 13, 13, 12, 13, 11, 14, 13, 13, 12, 12, 11, 11, 7, - 12, 14, 15, 13, 14, 12, 14, 11, 15, 14, 13, 12, 13, 11, 12, 7, - 13, 16, 16, 15, 16, 15, 15, 14, 16, 16, 15, 14, 14, 14, 12, 9, - 12, 15, 14, 13, 14, 13, 14, 12, 15, 14, 13, 12, 13, 12, 12, 8, - 12, 14, 14, 13, 15, 13, 14, 11, 14, 14, 13, 12, 13, 12, 12, 6, - 10, 14, 14, 13, 14, 14, 14, 13, 12, 13, 12, 12, 12, 12, 11, 9, - 12, 15, 15, 14, 15, 14, 16, 14, 14, 14, 13, 12, 14, 13, 13, 9, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 16, 11, - 11, 15, 14, 14, 15, 14, 14, 14, 13, 14, 11, 12, 13, 13, 12, 9, - 12, 15, 14, 14, 15, 14, 15, 13, 14, 14, 13, 12, 14, 13, 13, 9, - 13, 16, 16, 14, 16, 15, 16, 14, 16, 15, 15, 12, 16, 14, 14, 9, - 13, 16, 14, 15, 16, 16, 16, 14, 14, 16, 11, 12, 15, 14, 12, 9, - 13, 16, 15, 14, 16, 15, 16, 14, 15, 15, 12, 11, 15, 14, 13, 9, - 14, 16, 16, 13, 16, 16, 16, 14, 16, 15, 13, 11, 16, 14, 14, 9, - 11, 15, 15, 14, 14, 14, 14, 13, 13, 14, 13, 13, 11, 11, 11, 9, - 12, 15, 15, 14, 15, 14, 15, 13, 14, 14, 13, 13, 13, 12, 12, 9, - 13, 16, 16, 16, 16, 14, 16, 14, 16, 15, 16, 14, 15, 12, 14, 9, - 11, 15, 14, 14, 15, 14, 14, 13, 14, 14, 12, 12, 12, 12, 11, 8, - 11, 14, 14, 13, 14, 13, 13, 12, 13, 13, 12, 11, 12, 11, 11, 7, - 12, 14, 15, 13, 15, 13, 14, 13, 14, 14, 13, 12, 13, 12, 12, 8, - 13, 16, 15, 15, 16, 15, 15, 14, 15, 16, 12, 12, 14, 14, 11, 9, - 12, 15, 14, 13, 15, 13, 14, 12, 14, 14, 12, 11, 13, 12, 11, 7, - 12, 14, 14, 13, 15, 13, 14, 12, 15, 14, 13, 10, 13, 12, 12, 6, - 12, 16, 16, 15, 14, 14, 15, 14, 13, 15, 14, 14, 10, 11, 11, 9, - 13, 16, 16, 15, 15, 14, 15, 14, 15, 15, 15, 14, 12, 11, 12, 8, - 14, 16, 16, 16, 16, 14, 16, 14, 16, 15, 15, 14, 14, 11, 14, 8, - 12, 16, 16, 15, 15, 14, 15, 14, 14, 16, 14, 14, 12, 12, 11, 8, - 11, 14, 14, 13, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 7, - 12, 14, 15, 13, 14, 13, 14, 12, 14, 14, 13, 12, 13, 11, 12, 6, - 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 14, 13, 13, 13, 11, 8, - 12, 15, 15, 13, 15, 13, 14, 12, 14, 14, 13, 12, 13, 12, 10, 6, - 11, 14, 13, 12, 14, 12, 13, 10, 14, 13, 12, 10, 12, 10, 10, 4, -}, -{ - 4, 6, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 6, 3, - 6, 9, 10, 9, 10, 9, 11, 9, 10, 10, 10, 9, 10, 9, 10, 6, - 10, 11, 14, 11, 14, 11, 14, 11, 14, 13, 14, 11, 14, 11, 13, 9, - 6, 10, 9, 9, 10, 10, 10, 9, 10, 11, 9, 9, 10, 10, 9, 6, - 8, 11, 11, 9, 12, 11, 12, 10, 12, 12, 11, 10, 12, 11, 11, 7, - 11, 13, 14, 11, 15, 13, 15, 11, 15, 14, 14, 11, 15, 13, 14, 9, - 10, 13, 11, 11, 14, 14, 13, 11, 14, 14, 11, 11, 13, 13, 11, 9, - 11, 14, 12, 11, 15, 14, 14, 11, 15, 15, 13, 11, 14, 14, 13, 9, - 12, 14, 13, 10, 16, 15, 16, 11, 16, 16, 14, 11, 16, 14, 14, 9, - 6, 10, 10, 10, 9, 9, 10, 9, 10, 11, 10, 10, 9, 9, 9, 6, - 8, 11, 12, 11, 11, 10, 12, 10, 12, 12, 12, 11, 11, 10, 11, 7, - 11, 13, 15, 13, 14, 11, 15, 11, 15, 14, 14, 13, 14, 12, 14, 9, - 8, 12, 12, 12, 12, 12, 12, 11, 12, 13, 11, 11, 11, 11, 11, 8, - 9, 12, 12, 11, 12, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 8, - 11, 14, 15, 13, 14, 13, 15, 11, 15, 15, 14, 13, 15, 13, 14, 9, - 12, 16, 14, 14, 15, 15, 14, 12, 15, 16, 14, 13, 14, 14, 13, 10, - 11, 15, 14, 13, 15, 14, 15, 12, 15, 16, 14, 13, 15, 14, 13, 9, - 13, 15, 15, 12, 16, 15, 16, 12, 16, 16, 15, 13, 15, 14, 14, 9, - 10, 14, 14, 14, 11, 11, 13, 11, 14, 14, 14, 13, 11, 11, 11, 9, - 11, 14, 15, 14, 13, 11, 14, 12, 15, 15, 15, 14, 13, 11, 13, 9, - 13, 14, 16, 15, 14, 11, 16, 12, 16, 16, 16, 14, 15, 12, 15, 10, - 12, 16, 15, 15, 14, 14, 14, 12, 16, 16, 14, 14, 14, 13, 13, 10, - 12, 15, 15, 14, 14, 13, 14, 12, 15, 16, 14, 14, 14, 13, 13, 9, - 13, 16, 16, 14, 16, 13, 16, 12, 16, 16, 16, 14, 16, 13, 15, 10, - 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 16, 16, 16, 16, 14, 11, - 13, 16, 16, 15, 16, 16, 16, 13, 16, 16, 16, 15, 16, 15, 14, 10, - 14, 16, 16, 14, 16, 14, 16, 12, 16, 16, 16, 15, 16, 15, 15, 10, - 6, 10, 10, 10, 10, 10, 11, 10, 9, 10, 9, 9, 9, 9, 9, 6, - 9, 12, 12, 11, 12, 11, 13, 11, 12, 12, 11, 10, 12, 11, 11, 8, - 12, 14, 15, 14, 15, 14, 16, 13, 15, 14, 14, 12, 15, 13, 14, 10, - 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 11, 10, 7, - 9, 12, 12, 11, 13, 12, 13, 11, 12, 13, 11, 10, 12, 12, 11, 8, - 11, 14, 14, 13, 15, 14, 15, 13, 15, 14, 14, 12, 15, 13, 14, 9, - 11, 15, 12, 13, 15, 15, 14, 13, 14, 15, 11, 11, 14, 14, 12, 9, - 11, 14, 13, 13, 15, 14, 15, 13, 15, 15, 13, 11, 15, 14, 13, 9, - 13, 15, 15, 12, 16, 15, 16, 13, 16, 15, 14, 11, 16, 15, 14, 9, - 8, 12, 12, 11, 11, 11, 12, 11, 11, 12, 11, 11, 9, 10, 10, 7, - 9, 12, 13, 12, 12, 11, 13, 11, 12, 13, 12, 12, 11, 11, 11, 8, - 12, 14, 15, 14, 15, 13, 16, 13, 15, 14, 15, 13, 14, 12, 14, 9, - 9, 13, 12, 12, 12, 12, 13, 12, 12, 13, 11, 11, 11, 11, 10, 8, - 9, 12, 12, 12, 12, 12, 13, 11, 12, 13, 11, 11, 12, 11, 11, 7, - 11, 13, 14, 13, 14, 13, 15, 12, 14, 14, 14, 12, 14, 12, 13, 8, - 12, 15, 14, 14, 15, 15, 14, 13, 15, 16, 13, 13, 14, 14, 12, 9, - 11, 14, 13, 13, 14, 14, 14, 12, 14, 15, 13, 12, 14, 13, 12, 8, - 11, 14, 14, 13, 15, 14, 15, 12, 15, 15, 14, 12, 14, 13, 13, 8, - 11, 14, 14, 14, 13, 13, 14, 13, 13, 14, 14, 13, 11, 11, 11, 9, - 11, 15, 15, 14, 14, 13, 15, 13, 14, 15, 14, 14, 13, 11, 13, 9, - 13, 16, 16, 16, 15, 13, 16, 13, 16, 16, 16, 15, 15, 12, 15, 10, - 11, 15, 15, 15, 14, 14, 14, 13, 15, 15, 14, 14, 13, 13, 12, 9, - 11, 14, 14, 13, 13, 13, 14, 12, 14, 14, 13, 13, 13, 12, 12, 8, - 12, 15, 15, 14, 15, 13, 15, 12, 15, 15, 14, 13, 14, 12, 13, 8, - 13, 16, 16, 16, 16, 16, 16, 14, 16, 16, 15, 15, 15, 15, 13, 10, - 12, 15, 15, 14, 15, 14, 15, 13, 15, 16, 14, 13, 14, 14, 13, 9, - 12, 15, 15, 14, 15, 14, 15, 12, 15, 15, 14, 13, 14, 13, 13, 8, - 10, 14, 13, 13, 14, 13, 14, 13, 11, 13, 11, 11, 11, 11, 11, 9, - 12, 15, 16, 14, 15, 14, 16, 14, 14, 14, 14, 13, 14, 13, 13, 10, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 13, 16, 14, 16, 11, - 11, 15, 14, 14, 15, 14, 15, 14, 13, 14, 11, 12, 13, 13, 11, 9, - 12, 15, 15, 14, 15, 15, 16, 14, 14, 14, 13, 12, 14, 13, 13, 9, - 13, 16, 16, 15, 16, 16, 16, 15, 16, 15, 15, 12, 16, 14, 15, 10, - 12, 16, 14, 15, 16, 16, 16, 14, 14, 16, 11, 12, 14, 15, 12, 9, - 13, 16, 15, 14, 16, 16, 16, 14, 15, 16, 13, 12, 15, 15, 13, 9, - 14, 16, 16, 14, 16, 16, 16, 15, 16, 16, 14, 12, 16, 15, 15, 10, - 11, 14, 14, 14, 14, 14, 14, 13, 12, 14, 13, 13, 11, 11, 11, 9, - 11, 15, 15, 14, 14, 14, 16, 14, 14, 14, 14, 13, 13, 12, 13, 9, - 13, 16, 16, 16, 16, 15, 16, 15, 16, 15, 16, 14, 15, 13, 15, 10, - 11, 15, 15, 14, 14, 14, 15, 14, 14, 15, 13, 13, 12, 13, 11, 9, - 11, 14, 14, 13, 14, 14, 14, 13, 13, 14, 13, 12, 13, 12, 12, 8, - 12, 15, 15, 14, 16, 14, 16, 14, 15, 15, 15, 13, 14, 13, 14, 9, - 13, 16, 15, 16, 16, 16, 16, 15, 15, 16, 13, 13, 14, 14, 12, 9, - 12, 15, 14, 14, 15, 15, 15, 13, 14, 15, 13, 12, 14, 13, 12, 8, - 12, 15, 14, 14, 15, 15, 15, 13, 15, 15, 14, 12, 14, 13, 13, 8, - 12, 16, 15, 15, 13, 14, 15, 14, 13, 15, 14, 14, 10, 11, 11, 9, - 12, 16, 16, 15, 15, 14, 16, 14, 15, 15, 15, 14, 13, 12, 13, 9, - 14, 16, 16, 16, 16, 14, 16, 15, 16, 15, 16, 15, 14, 12, 15, 10, - 12, 16, 15, 15, 15, 15, 15, 14, 15, 16, 14, 14, 12, 13, 11, 9, - 11, 15, 15, 14, 14, 14, 15, 13, 14, 15, 14, 13, 13, 12, 12, 8, - 12, 15, 15, 14, 15, 14, 15, 13, 15, 15, 14, 13, 14, 12, 13, 8, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, 14, 14, 14, 11, 9, - 12, 15, 15, 14, 15, 15, 15, 13, 15, 15, 14, 13, 14, 13, 12, 8, - 11, 14, 14, 13, 14, 13, 14, 12, 13, 14, 13, 12, 13, 12, 12, 7, -}, -{ - 2, 6, 6, 5, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 6, 3, - 6, 9, 10, 9, 10, 9, 11, 9, 10, 10, 10, 9, 10, 9, 10, 7, - 10, 11, 14, 11, 14, 11, 14, 11, 14, 13, 14, 12, 14, 12, 13, 9, - 6, 10, 9, 9, 10, 10, 10, 9, 10, 11, 9, 9, 10, 10, 9, 7, - 8, 11, 11, 9, 12, 11, 12, 10, 12, 12, 11, 10, 12, 11, 11, 8, - 11, 13, 14, 11, 16, 13, 15, 12, 16, 14, 14, 12, 15, 13, 14, 10, - 10, 13, 11, 11, 14, 14, 13, 11, 13, 14, 11, 11, 13, 13, 11, 9, - 11, 13, 13, 11, 15, 14, 14, 12, 15, 15, 13, 12, 15, 14, 13, 10, - 12, 14, 14, 11, 16, 15, 16, 12, 16, 16, 15, 12, 16, 15, 15, 10, - 6, 10, 10, 10, 9, 9, 10, 9, 10, 11, 10, 10, 9, 9, 9, 7, - 8, 11, 12, 11, 11, 10, 12, 10, 12, 12, 12, 11, 11, 10, 11, 8, - 12, 13, 16, 13, 14, 11, 16, 12, 16, 15, 15, 13, 14, 12, 14, 10, - 9, 13, 12, 12, 12, 12, 12, 11, 13, 13, 12, 12, 12, 12, 11, 8, - 10, 13, 13, 12, 13, 12, 13, 11, 14, 14, 13, 12, 13, 12, 12, 9, - 12, 14, 16, 13, 15, 13, 15, 12, 16, 16, 16, 13, 16, 14, 14, 10, - 12, 16, 14, 14, 16, 15, 14, 13, 16, 16, 14, 14, 15, 15, 13, 11, - 12, 16, 15, 14, 16, 15, 15, 12, 16, 16, 15, 14, 16, 15, 14, 10, - 14, 16, 16, 14, 16, 15, 16, 13, 16, 16, 16, 14, 16, 16, 15, 11, - 10, 14, 14, 13, 11, 11, 13, 12, 14, 14, 13, 13, 11, 11, 12, 9, - 12, 14, 16, 14, 13, 11, 14, 12, 16, 15, 15, 14, 14, 12, 13, 10, - 13, 14, 16, 15, 14, 11, 16, 12, 16, 16, 16, 15, 16, 13, 15, 11, - 12, 16, 15, 15, 14, 14, 14, 13, 16, 16, 15, 15, 14, 14, 13, 11, - 13, 16, 16, 15, 14, 14, 15, 13, 16, 16, 16, 15, 15, 14, 14, 11, - 14, 16, 16, 15, 16, 14, 16, 13, 16, 16, 16, 15, 16, 14, 15, 11, - 15, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, 12, - 15, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 15, 12, - 15, 16, 16, 15, 16, 15, 16, 13, 16, 16, 16, 16, 16, 16, 16, 11, - 6, 10, 10, 10, 10, 10, 11, 10, 9, 10, 9, 9, 9, 9, 9, 7, - 9, 12, 13, 12, 13, 12, 14, 12, 12, 12, 12, 11, 12, 11, 11, 8, - 12, 14, 16, 14, 16, 14, 16, 14, 15, 14, 15, 13, 16, 13, 14, 11, - 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 11, 10, 8, - 10, 13, 13, 12, 14, 13, 14, 12, 13, 13, 12, 11, 13, 12, 12, 9, - 12, 15, 15, 13, 16, 15, 16, 14, 16, 15, 15, 12, 16, 14, 15, 10, - 11, 15, 13, 13, 16, 15, 14, 13, 14, 15, 11, 12, 14, 14, 12, 10, - 12, 16, 14, 13, 16, 16, 16, 14, 16, 15, 13, 12, 15, 15, 14, 10, - 14, 16, 16, 14, 16, 16, 16, 14, 16, 16, 15, 13, 16, 16, 15, 11, - 8, 12, 12, 12, 11, 11, 12, 11, 11, 12, 11, 11, 9, 10, 10, 8, - 10, 13, 14, 13, 13, 12, 14, 12, 13, 13, 13, 12, 12, 11, 12, 9, - 13, 15, 16, 15, 16, 14, 16, 14, 16, 15, 16, 14, 15, 13, 15, 11, - 10, 13, 13, 13, 13, 13, 13, 12, 13, 14, 12, 12, 12, 12, 11, 9, - 10, 13, 13, 13, 13, 13, 14, 12, 13, 14, 13, 12, 12, 12, 12, 9, - 12, 15, 15, 14, 16, 14, 16, 13, 16, 15, 15, 13, 15, 13, 14, 10, - 13, 16, 15, 15, 16, 16, 15, 14, 16, 16, 13, 14, 15, 15, 12, 10, - 12, 16, 14, 14, 16, 16, 15, 13, 16, 16, 14, 13, 15, 14, 13, 10, - 13, 16, 16, 14, 16, 15, 16, 13, 16, 16, 16, 13, 16, 15, 15, 10, - 11, 15, 15, 14, 13, 13, 14, 13, 13, 15, 14, 14, 11, 12, 12, 10, - 12, 15, 16, 15, 14, 13, 16, 14, 16, 15, 16, 14, 13, 12, 13, 10, - 14, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 16, 13, 16, 11, - 12, 16, 16, 16, 15, 15, 15, 14, 15, 16, 14, 14, 13, 14, 12, 10, - 12, 16, 16, 15, 15, 14, 16, 13, 16, 16, 15, 14, 14, 13, 13, 10, - 13, 16, 16, 15, 16, 14, 16, 13, 16, 16, 16, 15, 16, 14, 15, 10, - 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 13, 12, - 14, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 16, 15, 14, 11, - 14, 16, 16, 15, 16, 16, 16, 13, 16, 16, 16, 15, 16, 15, 14, 10, - 10, 14, 13, 13, 13, 13, 14, 13, 11, 13, 11, 11, 11, 11, 11, 9, - 12, 15, 16, 15, 16, 15, 16, 14, 14, 14, 14, 13, 14, 13, 14, 11, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, 16, 12, - 11, 15, 14, 14, 15, 15, 15, 14, 13, 14, 11, 12, 13, 13, 12, 10, - 13, 16, 15, 15, 16, 16, 16, 15, 15, 15, 13, 12, 15, 14, 13, 10, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 12, - 13, 16, 14, 15, 16, 16, 16, 15, 14, 16, 11, 12, 15, 15, 12, 10, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 13, 16, 16, 14, 11, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 11, - 11, 15, 15, 14, 13, 14, 14, 14, 13, 14, 13, 13, 11, 12, 11, 10, - 12, 16, 16, 16, 16, 15, 16, 15, 15, 15, 15, 14, 13, 12, 14, 10, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 14, 16, 12, - 12, 16, 15, 15, 16, 16, 16, 14, 14, 15, 13, 13, 13, 13, 12, 10, - 12, 16, 16, 15, 15, 15, 16, 14, 14, 15, 14, 13, 14, 13, 13, 10, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 15, 11, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 15, 15, 12, 11, - 13, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, 13, 16, 14, 13, 10, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 15, 10, - 12, 16, 16, 15, 14, 15, 16, 14, 13, 15, 14, 14, 11, 12, 12, 10, - 13, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 15, 13, 12, 14, 11, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 11, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 15, 15, 13, 14, 12, 11, - 13, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 14, 13, 13, 10, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 15, 14, 14, 10, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 15, 16, 13, 11, - 14, 16, 16, 16, 16, 16, 16, 14, 16, 16, 15, 14, 15, 14, 13, 10, - 12, 15, 15, 14, 15, 14, 16, 14, 14, 16, 15, 13, 14, 13, 13, 9, -}, -{ - 2, 5, 5, 5, 5, 5, 6, 6, 5, 6, 5, 6, 5, 6, 6, 4, - 6, 8, 10, 8, 10, 9, 11, 9, 10, 10, 10, 9, 10, 9, 10, 8, - 10, 11, 13, 11, 13, 11, 14, 11, 14, 13, 13, 12, 13, 12, 13, 10, - 6, 10, 8, 9, 10, 10, 10, 9, 10, 11, 9, 9, 10, 10, 9, 7, - 8, 11, 11, 10, 12, 11, 12, 10, 12, 12, 11, 10, 12, 12, 11, 9, - 11, 13, 14, 11, 15, 14, 15, 12, 16, 14, 14, 12, 15, 14, 14, 11, - 10, 13, 11, 11, 14, 13, 13, 12, 13, 14, 11, 11, 13, 13, 12, 10, - 11, 14, 13, 11, 16, 14, 14, 12, 15, 15, 14, 12, 15, 14, 14, 11, - 12, 14, 14, 11, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 15, 12, - 6, 10, 10, 10, 8, 9, 10, 9, 10, 11, 10, 10, 9, 9, 9, 8, - 8, 11, 12, 12, 11, 10, 12, 11, 12, 12, 12, 12, 12, 11, 12, 9, - 11, 13, 16, 14, 14, 12, 15, 12, 16, 15, 16, 14, 14, 13, 14, 11, - 9, 13, 12, 12, 12, 12, 12, 11, 13, 13, 12, 12, 12, 12, 11, 10, - 10, 13, 13, 12, 13, 12, 13, 11, 14, 14, 13, 13, 13, 13, 12, 10, - 13, 14, 16, 14, 15, 14, 16, 13, 16, 16, 16, 14, 16, 14, 15, 12, - 12, 16, 14, 14, 16, 15, 14, 13, 16, 16, 14, 14, 15, 15, 13, 12, - 13, 16, 15, 14, 16, 16, 15, 13, 16, 16, 15, 14, 16, 16, 14, 12, - 14, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 12, - 10, 13, 14, 13, 11, 11, 13, 12, 13, 14, 13, 13, 11, 12, 12, 10, - 11, 14, 15, 15, 13, 12, 14, 13, 16, 16, 16, 15, 14, 13, 14, 11, - 12, 14, 16, 16, 14, 12, 16, 13, 16, 16, 16, 16, 15, 13, 16, 12, - 12, 16, 15, 16, 14, 15, 14, 14, 16, 16, 15, 16, 14, 14, 13, 12, - 13, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 16, 16, 14, 15, 12, - 14, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 16, 15, 16, 13, - 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 15, 13, - 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 13, - 15, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 13, - 6, 10, 10, 10, 10, 10, 10, 10, 8, 10, 9, 9, 8, 9, 9, 7, - 9, 12, 13, 12, 13, 12, 13, 12, 12, 12, 12, 11, 12, 11, 12, 10, - 12, 14, 16, 14, 16, 14, 16, 14, 16, 15, 15, 14, 16, 14, 15, 12, - 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 12, 10, 9, - 10, 13, 13, 12, 14, 13, 14, 12, 13, 13, 12, 11, 13, 13, 12, 10, - 13, 15, 16, 14, 16, 16, 16, 14, 16, 15, 15, 13, 16, 15, 15, 12, - 11, 15, 13, 13, 15, 15, 15, 14, 14, 14, 11, 12, 14, 14, 12, 11, - 13, 16, 14, 14, 16, 16, 16, 14, 16, 15, 13, 13, 16, 14, 14, 11, - 14, 16, 16, 14, 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 16, 12, - 8, 12, 12, 12, 11, 11, 12, 12, 11, 12, 11, 11, 9, 10, 10, 9, - 10, 13, 14, 13, 13, 12, 14, 13, 13, 13, 13, 13, 12, 11, 12, 10, - 13, 15, 16, 15, 16, 14, 16, 14, 16, 16, 16, 15, 16, 13, 15, 12, - 10, 14, 13, 13, 13, 13, 13, 13, 13, 14, 12, 12, 12, 12, 11, 10, - 10, 13, 13, 13, 13, 13, 14, 12, 13, 14, 13, 12, 13, 12, 12, 10, - 13, 16, 16, 14, 16, 15, 16, 14, 16, 16, 15, 14, 16, 14, 15, 11, - 13, 16, 15, 16, 16, 16, 15, 14, 16, 16, 14, 14, 15, 15, 13, 12, - 13, 16, 15, 14, 16, 16, 16, 14, 16, 16, 14, 14, 15, 15, 14, 11, - 14, 16, 16, 15, 16, 16, 16, 14, 16, 16, 16, 15, 16, 16, 15, 12, - 11, 14, 15, 14, 13, 13, 14, 14, 13, 15, 14, 14, 11, 12, 12, 11, - 13, 16, 16, 16, 14, 14, 16, 14, 16, 16, 16, 15, 14, 13, 14, 12, - 14, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, - 13, 16, 16, 16, 15, 16, 15, 15, 16, 16, 15, 16, 14, 14, 13, 12, - 13, 16, 16, 15, 15, 14, 16, 14, 16, 16, 16, 15, 14, 14, 14, 11, - 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 15, 16, 12, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 13, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, - 9, 13, 13, 13, 13, 13, 14, 13, 10, 12, 11, 12, 11, 12, 11, 10, - 12, 15, 16, 15, 16, 16, 16, 16, 14, 14, 14, 13, 14, 13, 14, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, - 11, 15, 14, 14, 15, 14, 15, 14, 13, 14, 11, 12, 13, 13, 12, 11, - 13, 16, 16, 15, 16, 16, 16, 15, 15, 15, 14, 13, 16, 15, 14, 12, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 13, - 12, 16, 14, 15, 16, 16, 16, 16, 14, 16, 11, 13, 15, 16, 13, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 16, 16, 15, 12, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 13, - 11, 15, 14, 14, 13, 14, 15, 14, 12, 14, 13, 13, 11, 12, 12, 11, - 13, 16, 16, 16, 16, 15, 16, 16, 15, 15, 15, 15, 14, 13, 14, 12, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 15, 14, 16, 13, 14, 13, 14, 13, 11, - 13, 16, 16, 16, 16, 16, 16, 15, 15, 16, 15, 14, 14, 14, 14, 11, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 15, 16, 16, 13, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 16, 16, 15, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, - 11, 16, 16, 15, 13, 15, 16, 15, 13, 15, 15, 15, 11, 12, 12, 11, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 15, 12, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 14, 14, 13, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 12, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 14, 13, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 12, - 12, 14, 14, 14, 14, 15, 16, 14, 14, 16, 15, 14, 14, 15, 14, 11, -}, -{ - 1, 5, 5, 6, 5, 6, 7, 7, 5, 7, 6, 7, 5, 6, 6, 6, - 6, 9, 10, 9, 10, 9, 11, 10, 11, 11, 11, 10, 11, 10, 11, 9, - 10, 11, 14, 12, 14, 12, 16, 12, 16, 13, 16, 13, 14, 13, 16, 12, - 6, 10, 9, 9, 10, 11, 11, 10, 10, 11, 9, 10, 10, 11, 10, 9, - 8, 11, 11, 10, 13, 12, 13, 12, 13, 13, 12, 12, 13, 13, 13, 11, - 11, 13, 16, 12, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 13, - 10, 14, 11, 12, 14, 14, 13, 13, 13, 16, 12, 13, 14, 16, 13, 12, - 11, 14, 13, 12, 16, 16, 16, 14, 16, 16, 14, 14, 16, 16, 16, 13, - 12, 14, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 6, 10, 10, 11, 9, 9, 11, 10, 10, 11, 11, 11, 9, 10, 10, 9, - 9, 12, 13, 12, 12, 11, 13, 12, 13, 13, 13, 13, 12, 12, 13, 11, - 12, 13, 16, 16, 16, 13, 16, 14, 16, 16, 16, 16, 16, 14, 16, 13, - 9, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 12, 11, - 10, 14, 14, 13, 14, 13, 14, 13, 16, 16, 14, 15, 14, 14, 14, 12, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 14, 14, 16, 11, 12, 14, 13, 14, 16, 16, 16, 12, 13, 13, 12, - 12, 16, 16, 16, 13, 13, 16, 14, 16, 16, 16, 16, 16, 14, 16, 13, - 13, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 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, - 6, 10, 10, 10, 10, 11, 11, 11, 9, 11, 9, 10, 9, 10, 10, 9, - 9, 13, 13, 13, 13, 13, 14, 13, 12, 13, 13, 12, 13, 12, 13, 11, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 8, 13, 12, 12, 13, 13, 13, 13, 11, 13, 10, 12, 12, 13, 12, 11, - 10, 14, 13, 13, 16, 16, 16, 14, 14, 14, 13, 13, 14, 14, 14, 12, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 11, 16, 13, 16, 16, 16, 16, 16, 14, 16, 12, 13, 16, 16, 14, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 13, 13, 13, 11, 12, 13, 13, 11, 13, 12, 13, 10, 12, 12, 11, - 10, 14, 16, 16, 14, 13, 16, 14, 14, 16, 16, 14, 13, 13, 14, 12, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 16, 14, 16, 14, 14, 14, 14, 13, 16, 13, 14, 13, 14, 12, 12, - 10, 14, 14, 14, 14, 16, 16, 14, 14, 16, 14, 14, 14, 14, 14, 12, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 12, 14, 14, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 14, 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, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 14, 13, 14, 13, 14, 16, 16, 11, 13, 12, 13, 11, 13, 12, 12, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 14, 16, 16, 16, 16, 16, 13, 16, 12, 13, 14, 16, 13, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 14, 16, 12, 16, 16, 16, 14, 14, - 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, - 11, 16, 16, 16, 14, 16, 16, 16, 13, 16, 14, 16, 12, 13, 13, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 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, - 11, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 12, 16, 14, 14, - 14, 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, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 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, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, -}, -{ - 1, 5, 5, 6, 5, 6, 7, 8, 5, 7, 6, 8, 6, 7, 7, 7, - 5, 9, 10, 10, 10, 10, 12, 11, 10, 11, 11, 11, 10, 11, 12, 10, - 9, 11, 13, 12, 13, 12, 16, 14, 16, 14, 16, 16, 16, 13, 16, 13, - 5, 10, 9, 10, 10, 11, 11, 11, 10, 11, 9, 11, 10, 11, 11, 10, - 8, 11, 11, 11, 12, 13, 13, 13, 12, 13, 12, 12, 13, 13, 13, 12, - 11, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 14, 11, 12, 14, 16, 13, 14, 13, 16, 12, 14, 16, 16, 13, 13, - 11, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 14, 14, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 10, 11, 11, 9, 10, 11, 11, 10, 12, 11, 12, 9, 11, 11, 11, - 8, 12, 13, 13, 11, 11, 14, 13, 13, 14, 13, 16, 12, 12, 13, 12, - 11, 13, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 13, 12, 13, 12, 13, 13, 14, 13, 16, 13, 16, 13, 16, 13, 13, - 10, 14, 13, 14, 13, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 14, 16, 16, 11, 12, 14, 16, 13, 16, 16, 16, 12, 14, 13, 13, - 11, 16, 16, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 14, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 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, - 5, 10, 10, 11, 10, 11, 12, 12, 8, 11, 10, 11, 9, 11, 11, 11, - 9, 12, 13, 13, 13, 13, 16, 16, 12, 13, 13, 13, 13, 13, 16, 13, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 13, 11, 13, 12, 13, 13, 14, 11, 13, 10, 13, 12, 14, 12, 12, - 10, 14, 13, 14, 16, 16, 16, 16, 13, 16, 13, 14, 16, 16, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 13, 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 13, 13, 13, 11, 13, 14, 16, 11, 13, 13, 14, 10, 12, 12, 12, - 10, 14, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, 13, 13, 16, 14, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 14, 16, 13, 16, 16, 16, 13, 16, 13, 16, 13, 16, 13, 14, - 10, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 13, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 16, - 13, 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, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 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, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 14, 13, 16, 13, 16, 16, 16, 10, 14, 12, 14, 11, 13, 13, 13, - 12, 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, - 11, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 16, 16, 16, 16, - 13, 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, - 11, 16, 16, 16, 16, 16, 16, 16, 13, 16, 13, 16, 16, 16, 16, 16, - 14, 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, - 10, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 16, 12, 16, 16, 16, - 13, 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, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 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, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 16, - 13, 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, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, -} -}; - - -static const uint8_t rv34_inter_cbp[NUM_INTER_TABLES][4][CBP_VLC_SIZE] = { -{ - { 0, 6, 6, 3, 6, 4, 5, 3, 6, 5, 4, 3, 3, 4, 4, 3 }, - { 0, 6, 6, 4, 6, 4, 5, 3, 6, 5, 4, 3, 4, 4, 4, 2 }, - { 0, 7, 7, 4, 7, 5, 5, 4, 7, 5, 5, 4, 5, 4, 4, 1 }, - { 0, 7, 7, 5, 7, 5, 6, 4, 7, 6, 5, 3, 5, 4, 4, 1 } -}, -{ - { 0, 6, 6, 3, 6, 3, 5, 4, 6, 5, 3, 4, 3, 4, 4, 3 }, - { 0, 6, 6, 4, 6, 4, 4, 4, 6, 4, 4, 3, 4, 4, 4, 2 }, - { 0, 6, 6, 4, 6, 4, 5, 4, 6, 5, 4, 3, 4, 4, 3, 2 }, - { 0, 7, 7, 5, 7, 5, 6, 4, 7, 6, 5, 3, 5, 4, 4, 1 } -}, -{ - { 0, 6, 6, 3, 6, 3, 5, 4, 6, 5, 3, 4, 3, 4, 4, 3 }, - { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2 }, - { 0, 6, 6, 4, 6, 4, 5, 3, 6, 5, 4, 3, 4, 4, 4, 2 }, - { 0, 7, 7, 5, 7, 5, 6, 4, 7, 6, 5, 3, 5, 4, 4, 1 } -}, -{ - { 0, 6, 6, 3, 6, 3, 5, 4, 6, 5, 3, 4, 3, 4, 4, 3 }, - { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2 }, - { 0, 6, 6, 4, 6, 4, 5, 3, 6, 5, 4, 3, 4, 4, 4, 2 }, - { 0, 7, 7, 4, 7, 5, 6, 4, 7, 6, 5, 4, 4, 4, 4, 1 } -}, -{ - { 0, 5, 5, 3, 5, 3, 5, 4, 5, 5, 3, 4, 3, 4, 4, 4 }, - { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 3, 4, 3, 4, 4, 3 }, - { 0, 6, 6, 4, 6, 4, 5, 4, 6, 5, 4, 3, 4, 4, 3, 2 }, - { 0, 7, 7, 4, 7, 5, 6, 4, 7, 6, 5, 4, 4, 4, 4, 1 } -}, -{ - { 0, 5, 5, 3, 5, 3, 5, 4, 5, 5, 3, 4, 3, 4, 4, 4 }, - { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 3, 4, 3, 4, 4, 3 }, - { 0, 5, 5, 3, 5, 4, 4, 4, 5, 4, 4, 4, 3, 4, 4, 3 }, - { 0, 6, 6, 4, 6, 4, 5, 4, 6, 5, 4, 3, 4, 4, 3, 2 } -}, -{ - { 0, 4, 4, 3, 4, 3, 5, 5, 4, 5, 3, 5, 3, 5, 4, 5 }, - { 0, 4, 4, 3, 4, 4, 5, 4, 4, 5, 3, 5, 3, 5, 4, 4 }, - { 0, 4, 4, 3, 4, 4, 5, 4, 4, 5, 4, 4, 3, 4, 4, 4 }, - { 0, 4, 4, 3, 5, 4, 5, 4, 5, 5, 4, 4, 3, 4, 4, 3 } -} -}; - - -static const uint8_t rv34_table_inter_firstpat[NUM_INTER_TABLES][2][FIRSTBLK_VLC_SIZE] = { - { - { - 0, 7, 5, 7, 5, 7, 6, 6, 7, 10, 7, 9, 8, 9, 8, 7, - 12, 14, 11, 12, 12, 12, 11, 9, 6, 9, 6, 8, 7, 9, 7, 7, - 8, 11, 8, 9, 9, 10, 9, 8, 13, 15, 12, 12, 12, 13, 11, 9, - 10, 13, 9, 10, 11, 12, 9, 8, 12, 14, 10, 11, 12, 13, 10, 9, - 16, 16, 12, 12, 14, 13, 11, 9, 6, 9, 7, 9, 7, 9, 8, 7, - 9, 11, 9, 10, 9, 10, 9, 8, 14, 16, 12, 12, 13, 13, 11, 9, - 8, 11, 8, 10, 9, 10, 9, 8, 10, 13, 10, 11, 10, 11, 9, 8, - 14, 16, 12, 12, 13, 13, 11, 9, 12, 14, 10, 11, 12, 13, 10, 9, - 13, 16, 11, 12, 13, 13, 10, 9, 16, 16, 13, 12, 14, 14, 11, 9, - 11, 13, 11, 12, 10, 11, 10, 9, 13, 14, 12, 12, 11, 12, 10, 9, - 16, 16, 13, 13, 13, 13, 11, 9, 12, 15, 12, 12, 11, 12, 10, 9, - 13, 16, 13, 13, 12, 12, 11, 9, 16, 16, 14, 13, 13, 13, 11, 9, - 14, 16, 13, 13, 13, 14, 11, 9, 16, 16, 13, 13, 14, 14, 11, 9, - 16, 16, 13, 13, 14, 13, 11, 8, 4, 9, 6, 8, 6, 9, 7, 7, - 8, 11, 8, 9, 9, 10, 8, 8, 13, 15, 12, 12, 13, 13, 11, 9, - 7, 10, 7, 9, 8, 10, 8, 8, 9, 12, 9, 10, 10, 11, 9, 8, - 14, 16, 12, 12, 13, 13, 11, 9, 11, 13, 9, 10, 11, 12, 9, 8, - 12, 14, 10, 11, 12, 13, 10, 9, 16, 16, 13, 12, 14, 14, 11, 9, - 7, 10, 8, 9, 8, 10, 8, 8, 10, 12, 10, 11, 10, 11, 9, 8, - 14, 16, 13, 13, 13, 13, 11, 9, 9, 12, 9, 10, 9, 11, 9, 8, - 11, 13, 10, 11, 10, 11, 10, 9, 15, 16, 13, 13, 13, 13, 11, 9, - 12, 14, 11, 11, 12, 13, 10, 9, 13, 16, 11, 12, 13, 13, 10, 9, - 16, 16, 12, 12, 14, 13, 11, 8, 11, 14, 11, 12, 10, 11, 10, 9, - 13, 15, 12, 13, 11, 12, 10, 9, 16, 16, 14, 13, 13, 13, 11, 9, - 12, 15, 12, 13, 11, 12, 10, 9, 13, 16, 13, 13, 12, 12, 11, 9, - 16, 16, 14, 13, 13, 13, 11, 9, 15, 16, 13, 13, 13, 13, 11, 9, - 16, 16, 13, 13, 13, 13, 11, 9, 16, 16, 13, 12, 13, 13, 10, 7, - 8, 11, 8, 10, 9, 11, 9, 9, 10, 13, 10, 11, 11, 12, 10, 9, - 15, 16, 13, 13, 14, 14, 12, 10, 9, 12, 9, 11, 10, 11, 9, 9, - 12, 14, 11, 11, 11, 12, 10, 9, 16, 16, 13, 13, 14, 14, 12, 10, - 12, 14, 10, 11, 12, 13, 10, 9, 14, 16, 11, 12, 13, 14, 10, 9, - 16, 16, 13, 13, 15, 14, 11, 9, 9, 12, 10, 11, 9, 11, 10, 9, - 12, 14, 11, 12, 11, 12, 10, 9, 16, 16, 14, 13, 14, 14, 12, 10, - 11, 14, 10, 12, 11, 12, 10, 9, 12, 15, 11, 12, 12, 13, 11, 10, - 16, 16, 14, 13, 14, 14, 12, 10, 13, 16, 11, 12, 13, 14, 11, 9, - 14, 16, 12, 12, 13, 14, 11, 9, 16, 16, 13, 13, 14, 14, 11, 9, - 12, 15, 12, 13, 10, 12, 10, 9, 14, 16, 13, 13, 11, 12, 11, 10, - 16, 16, 14, 14, 14, 13, 12, 9, 13, 16, 13, 13, 12, 13, 11, 10, - 14, 16, 13, 13, 12, 13, 11, 10, 16, 16, 14, 14, 13, 13, 12, 9, - 15, 16, 13, 13, 13, 14, 11, 9, 16, 16, 13, 13, 13, 14, 11, 9, - 16, 16, 13, 12, 13, 13, 10, 8, 10, 13, 10, 11, 10, 12, 10, 9, - 12, 14, 11, 12, 12, 13, 11, 10, 16, 16, 13, 13, 14, 14, 12, 9, - 11, 14, 10, 11, 11, 12, 10, 9, 13, 16, 11, 12, 12, 13, 11, 10, - 16, 16, 14, 13, 14, 14, 12, 9, 12, 15, 10, 11, 12, 13, 9, 8, - 14, 16, 11, 11, 13, 14, 10, 8, 16, 16, 12, 12, 14, 14, 10, 8, - 11, 14, 11, 12, 11, 12, 10, 9, 13, 16, 12, 13, 12, 13, 11, 10, - 16, 16, 14, 13, 14, 14, 12, 9, 12, 15, 11, 12, 11, 13, 10, 10, - 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 14, 13, 14, 14, 12, 9, - 13, 16, 11, 11, 13, 13, 10, 8, 14, 16, 11, 12, 13, 14, 10, 8, - 16, 16, 12, 12, 14, 14, 10, 8, 12, 15, 12, 13, 10, 11, 10, 9, - 14, 16, 13, 13, 11, 12, 10, 9, 16, 16, 14, 13, 13, 13, 11, 8, - 13, 16, 12, 13, 11, 12, 10, 9, 14, 16, 13, 13, 12, 12, 10, 9, - 16, 16, 14, 13, 13, 12, 10, 8, 14, 16, 12, 12, 12, 13, 10, 8, - 14, 16, 12, 12, 12, 13, 10, 7, 16, 16, 11, 11, 12, 11, 8, 5, - }, - { - 0, 7, 4, 8, 5, 8, 7, 8, 6, 10, 7, 10, 8, 10, 9, 9, - 13, 16, 12, 13, 13, 14, 12, 12, 4, 10, 6, 9, 8, 11, 8, 9, - 8, 12, 8, 11, 10, 12, 10, 10, 14, 16, 12, 13, 14, 15, 12, 12, - 9, 14, 9, 11, 12, 14, 11, 11, 11, 15, 10, 12, 13, 14, 11, 11, - 15, 16, 13, 14, 15, 16, 13, 12, 5, 10, 7, 10, 7, 10, 9, 9, - 8, 12, 9, 11, 10, 11, 10, 10, 14, 16, 13, 14, 14, 14, 12, 12, - 8, 12, 8, 11, 10, 12, 10, 10, 10, 14, 10, 12, 11, 13, 10, 11, - 15, 16, 13, 14, 14, 15, 13, 12, 11, 16, 10, 12, 13, 15, 11, 11, - 13, 16, 11, 13, 14, 15, 12, 12, 16, 16, 14, 14, 16, 16, 13, 12, - 11, 15, 11, 13, 11, 13, 11, 11, 13, 16, 12, 14, 12, 13, 12, 12, - 16, 16, 14, 15, 15, 15, 13, 12, 12, 16, 12, 14, 12, 14, 12, 12, - 14, 16, 13, 14, 13, 14, 12, 12, 16, 16, 14, 16, 16, 16, 13, 12, - 14, 16, 13, 14, 15, 16, 13, 12, 16, 16, 14, 15, 16, 16, 13, 12, - 16, 16, 15, 16, 16, 16, 13, 12, 2, 9, 5, 8, 6, 9, 8, 9, - 7, 11, 8, 10, 9, 11, 9, 10, 13, 16, 12, 13, 14, 14, 12, 12, - 5, 11, 6, 10, 9, 11, 9, 9, 9, 13, 9, 11, 10, 12, 10, 10, - 14, 16, 12, 14, 14, 15, 12, 12, 9, 14, 9, 11, 12, 14, 10, 11, - 11, 16, 10, 12, 13, 14, 11, 11, 16, 16, 13, 14, 15, 16, 13, 12, - 6, 11, 7, 10, 8, 11, 9, 9, 9, 13, 9, 11, 10, 12, 10, 10, - 14, 16, 13, 14, 14, 14, 12, 12, 8, 13, 8, 11, 10, 12, 10, 10, - 10, 13, 10, 12, 11, 13, 10, 11, 14, 16, 13, 14, 14, 15, 12, 12, - 11, 15, 10, 12, 13, 15, 11, 11, 12, 16, 11, 13, 13, 15, 12, 11, - 16, 16, 13, 14, 15, 16, 13, 12, 11, 15, 11, 13, 10, 13, 11, 11, - 13, 16, 12, 14, 12, 13, 12, 11, 16, 16, 14, 15, 15, 15, 13, 12, - 12, 16, 12, 13, 12, 14, 12, 12, 13, 16, 12, 14, 13, 14, 12, 12, - 16, 16, 14, 15, 15, 15, 13, 12, 14, 16, 13, 14, 15, 16, 12, 12, - 16, 16, 13, 14, 15, 16, 12, 12, 16, 16, 14, 15, 16, 16, 13, 12, - 6, 12, 7, 10, 9, 12, 9, 10, 9, 13, 9, 12, 11, 13, 11, 11, - 14, 16, 13, 14, 15, 15, 13, 12, 8, 13, 8, 11, 10, 13, 10, 10, - 10, 14, 10, 12, 12, 14, 11, 11, 15, 16, 13, 14, 16, 16, 13, 12, - 10, 15, 9, 12, 12, 15, 11, 11, 12, 16, 11, 13, 14, 16, 12, 12, - 16, 16, 14, 14, 16, 16, 13, 12, 8, 13, 9, 11, 10, 12, 10, 11, - 11, 14, 11, 12, 11, 13, 11, 11, 16, 16, 14, 15, 15, 16, 13, 12, - 10, 14, 10, 12, 11, 13, 11, 11, 11, 15, 11, 13, 12, 14, 11, 11, - 15, 16, 13, 14, 15, 16, 13, 12, 12, 16, 11, 13, 13, 16, 12, 12, - 13, 16, 11, 13, 14, 16, 12, 12, 16, 16, 13, 14, 16, 16, 13, 12, - 12, 16, 12, 14, 11, 13, 11, 11, 13, 16, 13, 14, 12, 14, 12, 12, - 16, 16, 15, 16, 16, 16, 14, 13, 13, 16, 12, 14, 12, 14, 12, 12, - 14, 16, 13, 14, 13, 14, 12, 12, 16, 16, 14, 16, 14, 16, 13, 12, - 15, 16, 13, 15, 15, 16, 13, 12, 15, 16, 13, 15, 14, 16, 13, 12, - 16, 16, 14, 15, 15, 16, 13, 11, 8, 13, 8, 11, 10, 13, 10, 11, - 11, 15, 10, 12, 12, 14, 11, 11, 15, 16, 13, 14, 15, 15, 13, 12, - 9, 14, 9, 12, 11, 14, 10, 11, 11, 16, 10, 12, 13, 14, 11, 11, - 16, 16, 13, 14, 15, 16, 13, 12, 11, 15, 9, 12, 12, 14, 10, 10, - 12, 16, 11, 12, 14, 15, 11, 11, 16, 16, 13, 14, 16, 16, 12, 11, - 9, 14, 10, 12, 11, 13, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, - 16, 16, 14, 14, 15, 15, 13, 12, 10, 15, 10, 12, 12, 14, 11, 11, - 12, 16, 11, 13, 13, 14, 11, 11, 16, 16, 14, 14, 15, 16, 13, 12, - 12, 16, 10, 12, 13, 15, 11, 11, 13, 16, 11, 13, 14, 15, 11, 11, - 16, 16, 13, 13, 15, 16, 12, 11, 12, 16, 11, 13, 10, 13, 11, 11, - 14, 16, 13, 14, 12, 14, 11, 11, 16, 16, 15, 16, 14, 15, 13, 11, - 13, 16, 12, 14, 12, 14, 11, 11, 13, 16, 12, 14, 12, 14, 11, 11, - 16, 16, 14, 15, 14, 14, 12, 11, 14, 16, 12, 13, 13, 15, 11, 11, - 14, 16, 12, 13, 13, 14, 11, 11, 15, 16, 12, 13, 13, 13, 10, 9, - }, - }, - { - { - 0, 7, 4, 7, 5, 7, 6, 6, 6, 10, 7, 8, 8, 9, 8, 7, - 13, 14, 11, 12, 12, 12, 11, 9, 5, 9, 6, 8, 7, 9, 7, 7, - 8, 11, 8, 9, 9, 10, 9, 8, 13, 16, 12, 12, 12, 13, 11, 9, - 10, 13, 8, 10, 11, 12, 9, 9, 12, 14, 10, 11, 12, 13, 10, 9, - 15, 16, 12, 12, 14, 14, 11, 9, 6, 10, 7, 9, 7, 9, 8, 7, - 8, 11, 9, 10, 9, 10, 9, 8, 14, 16, 12, 12, 13, 12, 11, 9, - 8, 11, 8, 10, 9, 10, 9, 8, 10, 13, 10, 11, 10, 11, 9, 9, - 14, 16, 12, 12, 13, 13, 11, 9, 12, 15, 10, 11, 12, 13, 10, 9, - 13, 16, 11, 12, 13, 13, 10, 9, 16, 16, 12, 13, 14, 14, 11, 9, - 10, 14, 11, 12, 9, 11, 10, 9, 12, 15, 12, 13, 11, 12, 11, 9, - 16, 16, 13, 13, 13, 13, 11, 9, 12, 15, 12, 13, 11, 12, 11, 9, - 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 13, 13, 13, 11, 9, - 14, 16, 13, 13, 13, 14, 11, 10, 16, 16, 13, 13, 13, 14, 11, 10, - 16, 16, 13, 13, 14, 14, 11, 9, 4, 9, 6, 8, 6, 9, 7, 7, - 8, 11, 8, 9, 9, 10, 9, 8, 13, 15, 12, 12, 13, 13, 11, 9, - 6, 10, 7, 9, 8, 10, 8, 8, 9, 12, 9, 10, 10, 11, 9, 8, - 14, 16, 12, 12, 13, 13, 11, 10, 10, 13, 8, 10, 11, 12, 9, 9, - 12, 15, 10, 11, 12, 13, 10, 9, 16, 16, 12, 12, 14, 14, 11, 9, - 7, 11, 8, 9, 7, 10, 8, 8, 9, 12, 10, 11, 9, 11, 9, 9, - 14, 16, 12, 13, 13, 13, 11, 10, 9, 12, 9, 10, 9, 11, 9, 9, - 10, 13, 10, 11, 10, 11, 10, 9, 14, 16, 12, 13, 13, 13, 11, 9, - 12, 15, 10, 11, 12, 13, 10, 9, 13, 16, 11, 12, 13, 13, 10, 9, - 16, 16, 12, 12, 14, 14, 11, 9, 10, 14, 11, 12, 9, 11, 10, 9, - 12, 16, 12, 13, 11, 12, 11, 9, 16, 16, 14, 14, 13, 13, 11, 9, - 12, 16, 12, 13, 11, 12, 10, 10, 13, 16, 12, 13, 11, 12, 11, 10, - 16, 16, 13, 13, 13, 13, 11, 9, 14, 16, 13, 13, 13, 14, 11, 9, - 15, 16, 13, 13, 13, 14, 11, 9, 16, 16, 13, 13, 13, 13, 10, 8, - 7, 11, 8, 10, 9, 11, 9, 9, 10, 13, 10, 11, 11, 12, 10, 10, - 15, 16, 13, 13, 14, 14, 12, 10, 9, 13, 9, 11, 10, 12, 10, 9, - 11, 14, 10, 12, 12, 13, 10, 10, 16, 16, 13, 13, 14, 14, 12, 10, - 11, 15, 9, 11, 12, 13, 10, 9, 13, 16, 11, 12, 13, 14, 11, 10, - 16, 16, 13, 13, 15, 15, 11, 10, 9, 13, 10, 11, 9, 11, 10, 9, - 11, 14, 11, 12, 11, 12, 11, 10, 16, 16, 14, 14, 14, 14, 12, 10, - 10, 14, 10, 12, 11, 12, 10, 10, 12, 15, 11, 12, 12, 13, 11, 10, - 16, 16, 13, 13, 14, 14, 12, 10, 13, 16, 11, 12, 13, 14, 11, 10, - 13, 16, 11, 12, 13, 14, 11, 10, 16, 16, 12, 13, 14, 14, 11, 9, - 11, 15, 12, 13, 10, 12, 10, 10, 13, 16, 13, 14, 11, 13, 11, 10, - 16, 16, 14, 14, 14, 14, 12, 10, 13, 16, 13, 13, 11, 13, 11, 10, - 14, 16, 13, 14, 12, 13, 11, 10, 16, 16, 14, 14, 13, 13, 12, 10, - 15, 16, 13, 14, 14, 14, 11, 10, 15, 16, 13, 13, 13, 14, 11, 10, - 16, 16, 12, 13, 13, 13, 10, 8, 9, 13, 10, 11, 10, 12, 10, 10, - 12, 15, 11, 12, 12, 13, 11, 10, 16, 16, 14, 13, 14, 14, 12, 10, - 10, 14, 10, 12, 11, 13, 10, 10, 13, 16, 11, 12, 12, 14, 11, 10, - 16, 16, 13, 13, 14, 14, 12, 10, 12, 16, 9, 11, 12, 14, 10, 9, - 13, 16, 10, 12, 13, 14, 10, 9, 16, 16, 12, 12, 14, 14, 11, 9, - 10, 14, 11, 12, 10, 12, 10, 10, 13, 16, 12, 13, 12, 13, 11, 10, - 16, 16, 14, 14, 14, 14, 12, 10, 11, 16, 11, 12, 11, 13, 11, 10, - 13, 16, 12, 13, 12, 14, 11, 10, 16, 16, 14, 14, 14, 14, 12, 10, - 13, 16, 11, 12, 13, 14, 10, 9, 14, 16, 11, 12, 13, 14, 10, 9, - 16, 16, 12, 12, 14, 14, 10, 8, 12, 16, 12, 13, 10, 12, 10, 9, - 14, 16, 13, 13, 11, 12, 11, 9, 16, 16, 14, 14, 13, 13, 11, 9, - 13, 16, 12, 13, 11, 12, 10, 9, 14, 16, 13, 13, 11, 13, 11, 9, - 16, 16, 14, 14, 13, 13, 11, 9, 14, 16, 12, 13, 12, 13, 10, 8, - 14, 16, 12, 12, 12, 13, 10, 8, 15, 16, 11, 11, 11, 12, 9, 6, - }, - { - 0, 7, 4, 7, 5, 8, 7, 8, 5, 10, 7, 10, 8, 10, 9, 10, - 13, 16, 12, 14, 14, 14, 13, 12, 4, 10, 6, 9, 8, 11, 9, 9, - 8, 12, 8, 11, 10, 12, 10, 10, 14, 16, 13, 14, 14, 15, 13, 12, - 9, 14, 9, 12, 12, 14, 11, 11, 12, 16, 11, 13, 13, 15, 12, 12, - 15, 16, 14, 15, 15, 16, 13, 13, 5, 10, 7, 10, 7, 10, 9, 9, - 8, 12, 9, 11, 9, 11, 10, 10, 14, 16, 13, 14, 14, 15, 13, 12, - 7, 12, 8, 11, 10, 12, 10, 10, 10, 13, 10, 12, 11, 13, 11, 11, - 15, 16, 13, 15, 14, 16, 13, 13, 11, 16, 11, 13, 13, 16, 12, 12, - 13, 16, 12, 14, 14, 16, 12, 12, 16, 16, 14, 16, 16, 16, 14, 13, - 11, 15, 12, 14, 11, 13, 11, 12, 13, 16, 12, 14, 12, 14, 12, 12, - 16, 16, 14, 16, 14, 16, 13, 13, 13, 16, 12, 14, 12, 14, 12, 12, - 14, 16, 13, 15, 13, 15, 13, 13, 16, 16, 15, 16, 16, 16, 14, 13, - 15, 16, 13, 16, 15, 16, 13, 13, 16, 16, 14, 16, 16, 16, 14, 13, - 16, 16, 16, 16, 16, 16, 14, 13, 2, 9, 5, 8, 6, 9, 8, 9, - 7, 11, 8, 10, 9, 11, 9, 10, 14, 16, 13, 14, 14, 15, 13, 12, - 5, 11, 6, 10, 9, 11, 9, 10, 8, 13, 9, 11, 11, 12, 10, 11, - 14, 16, 13, 14, 14, 16, 13, 13, 9, 15, 9, 12, 12, 14, 11, 11, - 12, 16, 11, 13, 13, 15, 12, 12, 16, 16, 14, 15, 16, 16, 14, 13, - 6, 11, 7, 10, 8, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 11, - 14, 16, 13, 14, 14, 15, 13, 13, 8, 12, 8, 11, 10, 12, 10, 11, - 9, 13, 10, 12, 11, 13, 11, 11, 14, 16, 13, 14, 14, 16, 13, 13, - 12, 16, 11, 13, 13, 15, 12, 12, 13, 16, 11, 13, 14, 16, 12, 12, - 16, 16, 14, 15, 16, 16, 13, 13, 11, 15, 11, 14, 10, 13, 11, 12, - 13, 16, 13, 15, 12, 14, 12, 12, 16, 16, 15, 16, 15, 16, 14, 13, - 12, 16, 12, 14, 12, 14, 12, 12, 13, 16, 13, 15, 13, 14, 12, 13, - 16, 16, 15, 16, 15, 16, 13, 13, 15, 16, 13, 16, 15, 16, 13, 13, - 16, 16, 14, 16, 16, 16, 13, 13, 16, 16, 15, 16, 16, 16, 14, 13, - 5, 12, 7, 10, 9, 12, 10, 10, 9, 13, 9, 12, 11, 13, 11, 11, - 15, 16, 13, 14, 15, 15, 13, 13, 7, 13, 8, 11, 10, 13, 10, 11, - 10, 14, 10, 12, 12, 14, 11, 12, 16, 16, 14, 15, 16, 16, 14, 13, - 10, 16, 9, 12, 13, 15, 11, 12, 13, 16, 11, 13, 14, 16, 12, 12, - 16, 16, 14, 16, 16, 16, 14, 13, 8, 13, 9, 12, 9, 12, 10, 11, - 11, 15, 11, 13, 11, 13, 11, 12, 16, 16, 14, 16, 16, 16, 14, 13, - 9, 14, 10, 12, 11, 13, 11, 12, 11, 15, 11, 13, 12, 14, 12, 12, - 16, 16, 14, 16, 15, 16, 14, 13, 12, 16, 11, 14, 14, 16, 12, 12, - 13, 16, 12, 14, 14, 16, 13, 13, 16, 16, 13, 15, 16, 16, 14, 13, - 11, 16, 12, 14, 10, 13, 12, 12, 13, 16, 13, 15, 12, 14, 12, 13, - 16, 16, 16, 16, 16, 16, 14, 14, 13, 16, 13, 15, 12, 15, 12, 13, - 13, 16, 13, 15, 12, 15, 13, 13, 16, 16, 15, 16, 14, 16, 14, 13, - 16, 16, 14, 16, 16, 16, 14, 13, 15, 16, 14, 16, 15, 16, 14, 13, - 16, 16, 14, 16, 15, 16, 13, 12, 8, 14, 9, 12, 10, 14, 11, 12, - 11, 16, 10, 13, 12, 14, 12, 12, 16, 16, 14, 15, 15, 16, 14, 13, - 9, 15, 9, 12, 12, 14, 11, 12, 12, 16, 11, 13, 13, 15, 12, 12, - 16, 16, 14, 15, 16, 16, 14, 13, 11, 16, 9, 12, 13, 15, 11, 11, - 13, 16, 11, 13, 14, 16, 12, 12, 16, 16, 14, 14, 16, 16, 13, 12, - 9, 15, 10, 13, 11, 14, 11, 12, 12, 16, 11, 14, 12, 14, 12, 12, - 16, 16, 14, 16, 16, 16, 14, 13, 10, 16, 10, 13, 12, 15, 12, 12, - 12, 16, 12, 14, 13, 15, 12, 12, 16, 16, 14, 16, 16, 16, 14, 13, - 12, 16, 11, 13, 13, 16, 12, 12, 13, 16, 11, 13, 14, 16, 12, 12, - 16, 16, 13, 14, 16, 16, 13, 12, 11, 16, 12, 14, 10, 13, 11, 12, - 13, 16, 13, 15, 12, 14, 12, 12, 16, 16, 16, 16, 15, 16, 13, 12, - 12, 16, 12, 15, 12, 14, 12, 12, 13, 16, 13, 15, 12, 14, 12, 12, - 16, 16, 15, 16, 14, 15, 13, 12, 14, 16, 13, 14, 13, 16, 12, 12, - 13, 16, 12, 14, 13, 15, 12, 12, 14, 16, 12, 13, 13, 14, 11, 10, - }, - }, - { - { - 0, 7, 4, 7, 5, 7, 6, 6, 6, 10, 7, 8, 8, 9, 8, 8, - 13, 14, 11, 12, 12, 12, 11, 10, 5, 9, 6, 8, 7, 9, 7, 7, - 8, 11, 8, 9, 9, 10, 9, 8, 13, 16, 12, 12, 13, 13, 11, 10, - 10, 14, 8, 10, 11, 13, 9, 9, 12, 15, 10, 11, 12, 13, 10, 10, - 16, 16, 12, 13, 14, 14, 11, 10, 5, 10, 7, 9, 6, 9, 8, 8, - 8, 11, 9, 10, 9, 10, 9, 8, 14, 16, 12, 12, 13, 13, 11, 10, - 8, 12, 8, 10, 9, 10, 9, 9, 10, 13, 9, 11, 10, 11, 9, 9, - 14, 16, 12, 13, 13, 13, 11, 10, 12, 16, 10, 12, 12, 13, 10, 10, - 13, 16, 11, 12, 13, 14, 11, 10, 16, 16, 12, 13, 14, 14, 11, 10, - 10, 14, 11, 13, 9, 11, 10, 10, 12, 16, 12, 13, 11, 12, 11, 10, - 16, 16, 13, 14, 13, 13, 12, 10, 12, 16, 12, 13, 11, 13, 11, 10, - 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 14, 13, 14, 12, 10, - 14, 16, 13, 14, 13, 14, 12, 11, 16, 16, 13, 14, 14, 15, 12, 11, - 16, 16, 13, 14, 14, 14, 11, 10, 3, 9, 5, 8, 6, 9, 7, 7, - 8, 11, 8, 10, 9, 10, 9, 8, 14, 15, 12, 12, 13, 13, 11, 10, - 6, 11, 6, 9, 8, 10, 8, 8, 9, 12, 9, 10, 10, 11, 9, 9, - 14, 16, 12, 13, 13, 13, 11, 10, 10, 14, 8, 11, 12, 13, 9, 9, - 12, 16, 10, 11, 12, 13, 10, 10, 16, 16, 12, 13, 14, 14, 11, 10, - 6, 11, 8, 10, 7, 10, 8, 8, 9, 12, 10, 11, 9, 11, 9, 9, - 14, 16, 12, 13, 13, 13, 12, 10, 9, 12, 9, 11, 9, 11, 9, 9, - 10, 13, 10, 11, 10, 12, 10, 9, 14, 16, 12, 13, 13, 13, 11, 10, - 12, 16, 10, 12, 12, 14, 10, 10, 13, 16, 10, 12, 13, 14, 11, 10, - 16, 16, 12, 13, 14, 14, 11, 10, 10, 15, 11, 13, 9, 11, 10, 10, - 12, 16, 12, 13, 11, 12, 11, 10, 16, 16, 14, 14, 13, 14, 12, 10, - 12, 16, 12, 13, 11, 13, 11, 10, 13, 16, 12, 13, 11, 13, 11, 10, - 16, 16, 13, 14, 13, 13, 12, 10, 14, 16, 13, 14, 14, 14, 11, 11, - 15, 16, 13, 14, 13, 14, 11, 10, 16, 16, 13, 13, 13, 14, 11, 9, - 7, 12, 8, 11, 9, 11, 9, 10, 10, 14, 10, 12, 11, 12, 11, 10, - 16, 16, 13, 13, 14, 14, 12, 11, 9, 13, 9, 11, 10, 12, 10, 10, - 11, 15, 10, 12, 12, 13, 11, 10, 16, 16, 13, 14, 14, 14, 12, 11, - 11, 16, 9, 11, 12, 14, 10, 10, 13, 16, 10, 12, 13, 14, 11, 10, - 16, 16, 13, 14, 16, 16, 12, 11, 9, 13, 10, 12, 9, 12, 10, 10, - 11, 15, 11, 13, 11, 13, 11, 11, 16, 16, 14, 14, 14, 14, 13, 11, - 10, 14, 10, 12, 11, 13, 11, 10, 12, 16, 11, 13, 12, 13, 11, 11, - 16, 16, 13, 14, 14, 14, 12, 11, 13, 16, 11, 13, 13, 14, 11, 11, - 13, 16, 11, 13, 13, 14, 11, 11, 16, 16, 12, 13, 14, 15, 12, 10, - 11, 16, 12, 14, 10, 12, 11, 10, 13, 16, 13, 14, 11, 13, 11, 11, - 16, 16, 15, 16, 14, 14, 13, 11, 13, 16, 13, 14, 12, 13, 11, 11, - 13, 16, 13, 14, 12, 13, 11, 11, 16, 16, 14, 14, 13, 14, 12, 11, - 15, 16, 13, 14, 14, 16, 12, 11, 14, 16, 13, 14, 13, 14, 12, 11, - 16, 16, 12, 13, 13, 14, 11, 9, 9, 14, 10, 12, 10, 13, 11, 11, - 12, 16, 12, 13, 12, 14, 12, 11, 16, 16, 14, 14, 14, 14, 13, 11, - 10, 16, 10, 13, 12, 14, 11, 11, 13, 16, 12, 13, 13, 14, 12, 11, - 16, 16, 14, 14, 15, 15, 13, 11, 12, 16, 9, 12, 13, 14, 10, 10, - 14, 16, 11, 12, 13, 15, 11, 10, 16, 16, 13, 13, 15, 16, 11, 10, - 10, 16, 11, 13, 11, 13, 11, 11, 13, 16, 12, 14, 12, 14, 12, 11, - 16, 16, 14, 14, 14, 14, 13, 11, 11, 16, 11, 13, 12, 14, 11, 11, - 13, 16, 12, 14, 13, 14, 12, 11, 16, 16, 14, 14, 14, 15, 13, 11, - 13, 16, 11, 13, 13, 14, 11, 10, 14, 16, 11, 13, 13, 14, 11, 10, - 16, 16, 12, 13, 14, 15, 11, 9, 12, 16, 12, 14, 10, 13, 11, 10, - 14, 16, 13, 14, 11, 13, 11, 10, 16, 16, 14, 15, 13, 14, 12, 10, - 13, 16, 13, 14, 11, 13, 11, 10, 14, 16, 13, 14, 12, 13, 11, 10, - 16, 16, 14, 14, 13, 13, 11, 10, 14, 16, 12, 13, 13, 14, 11, 9, - 14, 16, 12, 13, 12, 13, 10, 9, 14, 16, 11, 11, 12, 12, 9, 7, - }, - { - 0, 7, 3, 8, 5, 8, 7, 9, 5, 10, 7, 10, 8, 11, 10, 10, - 14, 16, 14, 15, 14, 16, 14, 14, 4, 10, 6, 10, 8, 11, 9, 10, - 8, 12, 9, 11, 10, 12, 11, 11, 15, 16, 14, 16, 15, 16, 14, 14, - 10, 16, 10, 13, 13, 16, 12, 13, 13, 16, 12, 14, 14, 16, 13, 13, - 16, 16, 16, 16, 16, 16, 14, 15, 4, 10, 7, 10, 7, 10, 9, 10, - 8, 12, 9, 12, 10, 12, 11, 12, 14, 16, 14, 16, 15, 16, 14, 14, - 8, 12, 9, 12, 10, 13, 11, 12, 10, 14, 11, 13, 11, 14, 12, 13, - 16, 16, 14, 16, 16, 16, 14, 15, 12, 16, 12, 14, 14, 16, 13, 14, - 14, 16, 13, 16, 16, 16, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 12, 16, 11, 14, 13, 13, 13, 16, 13, 16, 13, 15, 13, 14, - 16, 16, 16, 16, 16, 16, 15, 16, 13, 16, 13, 16, 13, 16, 13, 14, - 14, 16, 14, 16, 14, 16, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 2, 9, 5, 9, 6, 10, 8, 10, - 7, 11, 8, 11, 9, 12, 10, 11, 14, 16, 14, 16, 15, 16, 14, 14, - 5, 11, 6, 10, 9, 12, 10, 11, 9, 13, 9, 12, 11, 13, 11, 12, - 16, 16, 14, 16, 16, 16, 14, 14, 10, 16, 9, 13, 13, 16, 12, 13, - 13, 16, 12, 14, 14, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 14, - 5, 11, 8, 11, 7, 11, 10, 11, 9, 13, 10, 13, 10, 13, 11, 12, - 16, 16, 14, 16, 16, 16, 14, 14, 8, 13, 9, 12, 10, 13, 11, 12, - 10, 14, 10, 13, 11, 14, 12, 12, 16, 16, 14, 16, 15, 16, 14, 14, - 12, 16, 12, 14, 14, 16, 13, 14, 14, 16, 12, 16, 15, 16, 13, 14, - 16, 16, 15, 16, 16, 16, 15, 15, 11, 16, 12, 16, 10, 14, 12, 13, - 13, 16, 14, 16, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 15, 16, - 13, 16, 13, 16, 13, 16, 13, 14, 14, 16, 14, 16, 13, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, - 5, 13, 7, 12, 9, 13, 11, 12, 10, 14, 10, 13, 11, 13, 12, 13, - 16, 16, 16, 16, 16, 16, 16, 15, 7, 14, 8, 12, 11, 14, 11, 12, - 11, 16, 11, 13, 13, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 10, 14, 14, 16, 12, 13, 13, 16, 12, 15, 16, 16, 14, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 14, 10, 13, 9, 13, 11, 12, - 11, 16, 12, 14, 12, 14, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 11, 14, 12, 14, 12, 13, 11, 16, 12, 14, 12, 15, 13, 13, - 16, 16, 15, 16, 16, 16, 15, 16, 13, 16, 12, 16, 15, 16, 14, 14, - 13, 16, 12, 16, 16, 16, 14, 14, 16, 16, 14, 16, 16, 16, 14, 16, - 11, 16, 13, 16, 10, 14, 12, 13, 14, 16, 14, 16, 13, 16, 14, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 14, 16, 13, 16, 14, 15, - 13, 16, 14, 16, 13, 16, 14, 15, 16, 16, 16, 16, 15, 16, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 16, - 16, 16, 15, 16, 16, 16, 14, 14, 8, 16, 10, 14, 11, 16, 12, 13, - 12, 16, 12, 14, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 16, 14, - 10, 16, 10, 14, 12, 16, 12, 13, 13, 16, 12, 15, 14, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 16, 15, 11, 16, 10, 13, 13, 16, 12, 13, - 14, 16, 12, 14, 15, 16, 13, 13, 16, 16, 16, 16, 16, 16, 15, 14, - 10, 16, 11, 14, 11, 16, 12, 13, 13, 16, 13, 16, 13, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 16, 15, 11, 16, 12, 14, 13, 16, 13, 14, - 13, 16, 13, 16, 14, 16, 13, 14, 16, 16, 16, 16, 16, 16, 16, 15, - 13, 16, 12, 14, 14, 16, 13, 13, 13, 16, 12, 15, 14, 16, 13, 13, - 16, 16, 14, 16, 16, 16, 14, 13, 11, 16, 12, 16, 11, 15, 12, 13, - 14, 16, 14, 16, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 14, - 12, 16, 13, 16, 12, 16, 13, 14, 13, 16, 14, 16, 13, 16, 13, 14, - 16, 16, 16, 16, 14, 16, 14, 14, 14, 16, 13, 16, 14, 16, 13, 13, - 13, 16, 13, 16, 14, 16, 13, 13, 15, 16, 13, 14, 13, 15, 12, 12, - }, - }, - { - { - 0, 7, 4, 6, 4, 7, 6, 7, 6, 9, 7, 8, 7, 9, 8, 8, - 13, 14, 12, 12, 12, 13, 11, 11, 5, 9, 5, 8, 7, 9, 7, 8, - 8, 11, 8, 10, 9, 10, 9, 9, 13, 15, 12, 13, 12, 13, 11, 11, - 9, 14, 8, 11, 11, 13, 10, 10, 11, 15, 10, 12, 12, 13, 10, 11, - 14, 16, 12, 13, 14, 14, 12, 11, 5, 9, 7, 9, 6, 9, 8, 8, - 8, 11, 8, 10, 8, 10, 9, 9, 13, 16, 12, 13, 13, 13, 11, 11, - 7, 11, 8, 10, 9, 11, 9, 9, 9, 13, 9, 11, 10, 11, 10, 10, - 14, 16, 12, 13, 13, 13, 12, 11, 11, 16, 10, 12, 12, 14, 11, 11, - 13, 16, 11, 13, 13, 14, 11, 11, 16, 16, 13, 14, 14, 15, 12, 11, - 10, 15, 11, 13, 9, 12, 10, 10, 12, 16, 12, 13, 11, 12, 11, 11, - 15, 16, 13, 14, 13, 14, 12, 11, 12, 16, 12, 14, 11, 13, 11, 11, - 13, 16, 12, 14, 12, 13, 12, 11, 16, 16, 13, 14, 14, 14, 12, 11, - 14, 16, 13, 14, 14, 15, 12, 12, 16, 16, 13, 14, 14, 16, 12, 12, - 16, 16, 14, 14, 14, 15, 12, 11, 3, 9, 5, 8, 6, 9, 7, 8, - 7, 11, 8, 10, 9, 10, 9, 9, 13, 14, 12, 13, 13, 13, 12, 11, - 6, 11, 6, 9, 8, 10, 8, 9, 9, 12, 8, 10, 10, 11, 9, 10, - 14, 16, 12, 13, 13, 14, 12, 11, 9, 14, 8, 11, 11, 13, 10, 10, - 12, 16, 10, 12, 12, 14, 11, 11, 16, 16, 12, 13, 14, 15, 12, 11, - 6, 11, 8, 10, 7, 10, 8, 9, 9, 12, 9, 11, 9, 11, 10, 10, - 14, 16, 13, 13, 13, 14, 12, 11, 8, 12, 9, 11, 9, 11, 9, 10, - 10, 13, 9, 11, 10, 12, 10, 10, 14, 16, 12, 13, 13, 14, 12, 11, - 12, 16, 10, 12, 12, 14, 11, 11, 12, 16, 10, 12, 13, 14, 11, 11, - 15, 16, 12, 13, 14, 14, 11, 11, 10, 15, 11, 13, 9, 12, 10, 10, - 12, 16, 12, 14, 11, 13, 11, 11, 16, 16, 14, 14, 14, 14, 12, 11, - 12, 16, 12, 14, 11, 13, 11, 11, 13, 16, 12, 14, 11, 13, 11, 11, - 16, 16, 13, 14, 13, 14, 12, 11, 14, 16, 13, 14, 14, 15, 12, 11, - 14, 16, 13, 14, 13, 15, 12, 11, 16, 16, 13, 14, 13, 14, 11, 10, - 6, 13, 8, 11, 9, 12, 10, 10, 10, 14, 10, 12, 11, 13, 11, 11, - 16, 16, 13, 14, 14, 14, 13, 12, 8, 14, 8, 12, 10, 13, 10, 11, - 11, 15, 10, 12, 12, 13, 11, 11, 16, 16, 14, 14, 15, 16, 13, 12, - 11, 16, 9, 12, 12, 14, 11, 11, 13, 16, 11, 13, 13, 16, 11, 11, - 16, 16, 13, 14, 16, 16, 13, 12, 8, 14, 10, 12, 9, 12, 10, 11, - 11, 15, 11, 13, 11, 13, 11, 11, 16, 16, 14, 15, 14, 15, 13, 12, - 10, 15, 10, 13, 11, 13, 11, 11, 11, 15, 11, 13, 12, 13, 11, 11, - 16, 16, 13, 15, 14, 15, 13, 12, 12, 16, 11, 13, 13, 15, 11, 11, - 13, 16, 11, 13, 13, 15, 11, 11, 16, 16, 12, 14, 14, 16, 12, 11, - 11, 16, 12, 14, 10, 13, 11, 11, 13, 16, 13, 15, 12, 14, 12, 12, - 16, 16, 15, 16, 14, 15, 13, 12, 12, 16, 13, 14, 12, 14, 12, 12, - 13, 16, 13, 14, 12, 14, 12, 12, 16, 16, 14, 15, 13, 14, 12, 12, - 15, 16, 13, 15, 14, 16, 12, 12, 14, 16, 13, 14, 13, 15, 12, 12, - 15, 16, 12, 13, 13, 14, 11, 10, 9, 15, 10, 13, 11, 14, 11, 12, - 12, 16, 12, 14, 12, 14, 12, 12, 16, 16, 14, 14, 14, 15, 13, 12, - 10, 16, 10, 13, 12, 14, 12, 12, 13, 16, 12, 14, 13, 15, 12, 12, - 16, 16, 14, 14, 15, 16, 13, 12, 11, 16, 9, 12, 13, 15, 11, 11, - 14, 16, 11, 13, 14, 16, 11, 11, 16, 16, 13, 14, 16, 16, 12, 11, - 10, 16, 11, 14, 11, 14, 12, 12, 13, 16, 13, 14, 12, 14, 12, 12, - 16, 16, 14, 15, 15, 15, 13, 12, 11, 16, 12, 14, 12, 15, 12, 12, - 13, 16, 12, 14, 13, 15, 12, 12, 16, 16, 14, 15, 15, 16, 13, 12, - 12, 16, 11, 13, 13, 15, 11, 11, 13, 16, 11, 13, 13, 15, 11, 11, - 16, 16, 12, 13, 14, 16, 12, 10, 11, 16, 12, 14, 10, 13, 11, 11, - 14, 16, 13, 14, 12, 14, 11, 11, 16, 16, 15, 16, 14, 14, 12, 11, - 12, 16, 13, 14, 11, 14, 11, 11, 13, 16, 13, 14, 12, 14, 11, 11, - 16, 16, 14, 15, 13, 14, 12, 11, 14, 16, 12, 14, 13, 14, 11, 10, - 13, 16, 12, 13, 12, 14, 11, 10, 14, 16, 11, 12, 12, 12, 10, 8, - }, - { - 0, 8, 4, 9, 5, 9, 8, 10, 6, 11, 8, 11, 9, 12, 11, 12, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 6, 11, 9, 12, 10, 12, - 9, 13, 10, 13, 11, 16, 12, 13, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 11, 16, 16, 16, 14, 16, 14, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 8, 12, 7, 12, 10, 12, - 8, 13, 10, 13, 10, 13, 12, 14, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 13, 10, 14, 11, 16, 12, 14, 11, 16, 12, 16, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 14, 16, 12, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 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, 1, 10, 5, 10, 7, 11, 9, 11, - 8, 12, 9, 12, 10, 13, 12, 13, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 12, 7, 12, 10, 13, 11, 12, 9, 16, 10, 13, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 10, 16, 16, 16, 14, 16, - 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 6, 12, 9, 13, 8, 12, 11, 13, 10, 16, 11, 16, 11, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 10, 14, 11, 16, 12, 16, - 10, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 14, 16, 11, 16, 14, 16, - 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 15, 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, - 6, 16, 9, 13, 10, 16, 12, 14, 11, 16, 12, 16, 12, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 9, 14, 12, 16, 13, 16, - 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 10, 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 11, 16, 10, 16, 12, 16, - 12, 16, 13, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 13, 16, 14, 16, 11, 16, 13, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 16, 16, - 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 11, 16, 14, 16, 16, 16, 16, 16, 14, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 13, 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, 8, 16, 11, 16, 12, 16, 13, 16, - 13, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 11, 16, 13, 16, 14, 16, 14, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 10, 16, 16, 16, 13, 16, - 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 12, 16, 13, 16, 13, 16, 16, 16, 14, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 14, 16, 16, 16, - 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 12, 16, 16, 16, 14, 16, 14, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 11, 16, 13, 16, - 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 15, - }, - }, - { - { - 0, 7, 3, 7, 4, 7, 6, 7, 6, 9, 7, 9, 7, 9, 8, 9, - 13, 14, 12, 13, 13, 13, 12, 12, 4, 9, 5, 9, 7, 9, 8, 9, - 7, 11, 8, 10, 9, 11, 9, 10, 13, 16, 12, 14, 13, 14, 12, 12, - 9, 14, 8, 12, 12, 14, 10, 11, 11, 16, 10, 13, 13, 14, 11, 12, - 15, 16, 13, 14, 14, 16, 12, 12, 5, 10, 7, 9, 6, 9, 8, 9, - 8, 11, 8, 11, 8, 10, 9, 10, 14, 16, 12, 14, 13, 14, 12, 12, - 7, 12, 8, 11, 9, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 11, - 14, 16, 12, 14, 13, 14, 12, 12, 12, 16, 11, 13, 13, 15, 11, 12, - 13, 16, 11, 14, 13, 15, 12, 12, 15, 16, 13, 15, 14, 16, 13, 13, - 10, 15, 12, 14, 9, 13, 11, 12, 12, 16, 12, 14, 11, 13, 12, 12, - 15, 16, 13, 15, 14, 15, 13, 13, 12, 16, 12, 14, 12, 14, 12, 12, - 13, 16, 13, 14, 12, 14, 12, 12, 16, 16, 14, 15, 14, 16, 13, 13, - 15, 16, 13, 15, 14, 16, 12, 13, 16, 16, 14, 16, 14, 16, 13, 13, - 16, 16, 14, 16, 15, 16, 13, 13, 3, 9, 5, 9, 6, 9, 8, 9, - 7, 11, 8, 10, 9, 11, 9, 10, 14, 15, 13, 14, 13, 14, 12, 12, - 5, 11, 6, 10, 8, 11, 9, 10, 9, 12, 9, 11, 10, 12, 10, 11, - 14, 16, 13, 14, 14, 15, 13, 13, 9, 15, 8, 12, 12, 14, 10, 11, - 12, 16, 10, 13, 13, 15, 11, 12, 15, 16, 13, 14, 14, 16, 13, 13, - 6, 11, 8, 11, 7, 10, 9, 10, 9, 13, 10, 12, 9, 12, 10, 11, - 14, 16, 13, 14, 14, 14, 13, 13, 8, 13, 9, 12, 9, 12, 10, 11, - 9, 13, 9, 12, 10, 12, 10, 11, 14, 16, 12, 14, 13, 14, 12, 12, - 12, 16, 11, 13, 13, 15, 11, 12, 12, 16, 11, 13, 13, 15, 11, 12, - 14, 16, 12, 14, 14, 15, 12, 12, 10, 15, 11, 14, 9, 13, 11, 12, - 12, 16, 12, 14, 11, 14, 12, 12, 16, 16, 14, 16, 14, 15, 13, 13, - 12, 16, 12, 14, 11, 14, 12, 12, 12, 16, 13, 14, 11, 14, 12, 12, - 15, 16, 14, 15, 13, 15, 12, 13, 14, 16, 13, 15, 14, 16, 13, 13, - 14, 16, 13, 15, 14, 16, 12, 13, 15, 16, 13, 15, 13, 15, 12, 12, - 6, 13, 8, 12, 9, 12, 10, 11, 10, 14, 11, 13, 11, 13, 12, 12, - 15, 16, 14, 15, 15, 15, 14, 13, 8, 14, 9, 12, 11, 13, 11, 12, - 11, 15, 11, 13, 12, 14, 12, 12, 16, 16, 14, 15, 15, 16, 14, 14, - 10, 16, 9, 13, 12, 15, 11, 12, 13, 16, 11, 14, 13, 16, 12, 12, - 16, 16, 14, 15, 16, 16, 13, 13, 8, 14, 10, 13, 9, 13, 11, 12, - 11, 15, 12, 14, 11, 14, 12, 12, 16, 16, 15, 16, 15, 16, 14, 14, - 10, 15, 10, 13, 11, 14, 11, 12, 11, 15, 11, 14, 12, 14, 12, 12, - 15, 16, 14, 15, 14, 16, 13, 13, 12, 16, 11, 14, 13, 16, 12, 12, - 12, 16, 11, 14, 13, 15, 12, 12, 15, 16, 12, 14, 15, 16, 13, 13, - 11, 16, 12, 14, 10, 14, 11, 12, 13, 16, 13, 16, 12, 14, 12, 13, - 16, 16, 16, 16, 15, 16, 14, 13, 12, 16, 13, 15, 12, 14, 12, 13, - 13, 16, 13, 15, 12, 14, 12, 13, 16, 16, 14, 16, 13, 15, 13, 13, - 15, 16, 14, 16, 14, 16, 13, 13, 14, 16, 13, 15, 13, 16, 13, 13, - 14, 16, 12, 14, 13, 14, 12, 12, 9, 16, 11, 14, 11, 15, 12, 13, - 13, 16, 12, 14, 12, 15, 13, 13, 16, 16, 14, 15, 15, 15, 14, 13, - 11, 16, 11, 14, 12, 16, 12, 13, 13, 16, 12, 14, 13, 16, 13, 13, - 16, 16, 14, 15, 16, 16, 14, 13, 11, 16, 10, 13, 13, 16, 11, 12, - 14, 16, 11, 14, 14, 16, 12, 12, 16, 16, 14, 14, 16, 16, 13, 12, - 11, 16, 12, 14, 11, 15, 12, 13, 13, 16, 13, 15, 13, 16, 13, 13, - 16, 16, 15, 16, 15, 16, 14, 13, 11, 16, 12, 15, 12, 16, 12, 13, - 13, 16, 13, 15, 13, 16, 13, 13, 16, 16, 15, 16, 15, 16, 14, 13, - 12, 16, 11, 14, 13, 16, 12, 12, 13, 16, 11, 14, 13, 16, 12, 12, - 16, 16, 13, 14, 15, 16, 12, 12, 11, 16, 12, 14, 10, 14, 11, 12, - 14, 16, 13, 15, 12, 15, 12, 12, 16, 16, 16, 16, 14, 15, 13, 12, - 12, 16, 13, 15, 12, 14, 12, 12, 13, 16, 13, 15, 12, 14, 12, 12, - 16, 16, 14, 16, 14, 15, 12, 12, 14, 16, 13, 15, 13, 16, 11, 12, - 13, 16, 12, 14, 13, 15, 11, 11, 14, 16, 12, 13, 12, 13, 11, 10, - }, - { - 0, 8, 4, 9, 5, 10, 9, 11, 5, 11, 9, 12, 9, 13, 12, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 6, 12, 9, 13, 11, 13, - 9, 16, 10, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 12, 8, 13, 7, 12, 11, 16, - 8, 16, 11, 16, 11, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 10, 16, 11, 16, 13, 16, 11, 16, 12, 16, 13, 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, - 12, 16, 16, 16, 13, 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, 1, 10, 6, 11, 7, 12, 10, 13, - 7, 12, 10, 13, 10, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 13, 7, 12, 10, 16, 12, 16, 10, 16, 11, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 16, 16, 16, 16, - 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 13, 9, 16, 8, 16, 12, 16, 9, 16, 12, 16, 11, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 12, 16, 13, 16, - 10, 16, 12, 16, 12, 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, 12, 16, 16, 16, 12, 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, - 6, 16, 9, 16, 10, 16, 13, 16, 11, 16, 12, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 9, 16, 12, 16, 13, 16, - 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 10, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 11, 16, 11, 16, 13, 16, - 12, 16, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 13, 16, 16, 16, 11, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 16, 16, 11, 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, 13, 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, 7, 16, 11, 16, 12, 16, 16, 16, - 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 11, 16, 13, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 10, 16, 16, 16, 16, 16, - 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 11, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 16, 16, 13, 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, - }, - }, - { - { - 0, 7, 4, 8, 4, 8, 7, 8, 6, 10, 7, 10, 8, 10, 9, 10, - 13, 16, 13, 15, 13, 15, 13, 14, 4, 10, 5, 10, 7, 10, 9, 10, - 7, 12, 8, 11, 9, 12, 10, 11, 13, 16, 13, 15, 13, 16, 13, 14, - 9, 16, 9, 13, 12, 16, 11, 13, 11, 16, 11, 14, 13, 16, 12, 14, - 15, 16, 14, 16, 15, 16, 14, 14, 4, 10, 7, 10, 6, 10, 9, 10, - 8, 12, 9, 12, 9, 11, 10, 12, 13, 16, 13, 16, 14, 16, 13, 14, - 7, 12, 8, 12, 9, 12, 10, 12, 9, 13, 10, 13, 10, 13, 11, 12, - 14, 16, 13, 16, 14, 16, 13, 14, 12, 16, 11, 14, 13, 16, 12, 14, - 13, 16, 12, 16, 14, 16, 13, 14, 16, 16, 14, 16, 15, 16, 14, 14, - 10, 16, 12, 15, 10, 14, 12, 13, 12, 16, 13, 16, 12, 14, 13, 14, - 15, 16, 14, 16, 14, 16, 14, 14, 12, 16, 13, 16, 12, 16, 13, 14, - 13, 16, 13, 16, 13, 16, 13, 14, 16, 16, 14, 16, 15, 16, 14, 15, - 15, 16, 14, 16, 15, 16, 13, 15, 16, 16, 14, 16, 15, 16, 14, 15, - 16, 16, 16, 16, 16, 16, 15, 15, 2, 9, 5, 10, 6, 10, 8, 10, - 7, 11, 8, 11, 9, 11, 10, 11, 14, 16, 13, 15, 14, 15, 14, 14, - 5, 11, 6, 11, 8, 12, 9, 11, 8, 13, 9, 12, 10, 13, 11, 12, - 14, 16, 13, 15, 14, 16, 14, 14, 9, 16, 8, 13, 12, 16, 11, 13, - 12, 16, 11, 14, 13, 16, 12, 13, 16, 16, 14, 16, 15, 16, 14, 15, - 5, 12, 8, 11, 7, 11, 9, 11, 9, 13, 10, 13, 10, 13, 11, 12, - 14, 16, 14, 16, 14, 16, 14, 15, 8, 13, 9, 13, 10, 13, 11, 12, - 9, 13, 10, 13, 10, 13, 11, 13, 13, 16, 13, 15, 13, 16, 13, 14, - 12, 16, 11, 14, 13, 16, 12, 14, 12, 16, 11, 14, 13, 16, 12, 14, - 14, 16, 13, 16, 14, 16, 13, 14, 10, 16, 12, 15, 9, 14, 11, 13, - 12, 16, 13, 16, 12, 15, 12, 14, 16, 16, 15, 16, 15, 16, 14, 14, - 12, 16, 13, 16, 12, 16, 12, 14, 12, 16, 13, 16, 12, 15, 13, 14, - 15, 16, 14, 16, 14, 16, 14, 14, 15, 16, 14, 16, 14, 16, 14, 15, - 14, 16, 13, 16, 14, 16, 13, 14, 16, 16, 14, 16, 14, 16, 13, 14, - 6, 14, 9, 13, 9, 14, 11, 12, 10, 14, 11, 13, 11, 14, 12, 13, - 16, 16, 15, 16, 15, 16, 14, 15, 8, 15, 9, 13, 11, 14, 11, 13, - 11, 16, 11, 14, 12, 15, 12, 14, 16, 16, 15, 16, 16, 16, 15, 16, - 10, 16, 9, 14, 12, 16, 12, 13, 13, 16, 11, 15, 14, 16, 13, 14, - 16, 16, 15, 16, 16, 16, 15, 16, 8, 15, 10, 13, 10, 14, 11, 13, - 11, 16, 12, 14, 12, 14, 12, 14, 16, 16, 16, 16, 16, 16, 15, 16, - 10, 16, 11, 14, 11, 15, 12, 13, 11, 16, 11, 14, 12, 15, 12, 14, - 16, 16, 14, 16, 15, 16, 14, 15, 12, 16, 11, 15, 13, 16, 13, 14, - 12, 16, 11, 14, 13, 16, 13, 14, 15, 16, 13, 16, 16, 16, 14, 15, - 10, 16, 12, 15, 10, 15, 12, 13, 13, 16, 13, 16, 12, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 15, 15, 12, 16, 13, 16, 12, 16, 13, 14, - 12, 16, 13, 16, 12, 16, 13, 14, 16, 16, 15, 16, 14, 16, 14, 15, - 15, 16, 14, 16, 15, 16, 14, 15, 14, 16, 13, 16, 14, 16, 13, 14, - 14, 16, 13, 15, 14, 16, 13, 14, 9, 16, 11, 16, 11, 16, 12, 14, - 13, 16, 12, 16, 13, 16, 13, 14, 16, 16, 15, 16, 16, 16, 15, 15, - 11, 16, 11, 16, 12, 16, 13, 14, 13, 16, 12, 16, 13, 16, 13, 14, - 16, 16, 15, 16, 16, 16, 15, 15, 11, 16, 10, 15, 13, 16, 12, 13, - 14, 16, 12, 16, 14, 16, 13, 14, 16, 16, 15, 16, 16, 16, 14, 14, - 11, 16, 12, 16, 11, 16, 13, 14, 13, 16, 13, 16, 13, 16, 13, 14, - 16, 16, 16, 16, 16, 16, 15, 15, 11, 16, 12, 16, 12, 16, 13, 14, - 13, 16, 13, 16, 13, 16, 13, 14, 16, 16, 15, 16, 16, 16, 15, 14, - 12, 16, 12, 15, 13, 16, 12, 14, 13, 16, 12, 16, 14, 16, 13, 14, - 16, 16, 14, 16, 16, 16, 14, 14, 11, 16, 12, 16, 11, 16, 12, 14, - 14, 16, 14, 16, 12, 16, 13, 14, 16, 16, 16, 16, 16, 16, 15, 14, - 12, 16, 13, 16, 12, 16, 12, 14, 13, 16, 13, 16, 12, 16, 13, 14, - 16, 16, 16, 16, 15, 16, 14, 14, 14, 16, 13, 16, 14, 16, 12, 14, - 13, 16, 13, 16, 13, 16, 12, 13, 15, 16, 13, 14, 14, 15, 13, 13, - }, - { - 0, 8, 4, 10, 5, 11, 10, 16, 5, 12, 9, 16, 10, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 12, 7, 12, 9, 16, 12, 16, - 9, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 12, 9, 16, 8, 16, 12, 16, - 8, 16, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 8, 16, 11, 16, 12, 16, 16, 16, 11, 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, - 12, 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, 1, 11, 6, 12, 7, 16, 11, 16, - 7, 16, 10, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 16, 7, 16, 10, 16, 12, 16, 9, 16, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 16, 10, 16, 8, 16, 12, 16, 9, 16, 12, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 12, 16, 16, 16, - 10, 16, 12, 16, 12, 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, 12, 16, 16, 16, 12, 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, - 5, 16, 9, 16, 10, 16, 16, 16, 11, 16, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 9, 16, 12, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 11, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 11, 16, 11, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 16, 16, 16, 16, 11, 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, - 11, 16, 16, 16, 11, 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, 6, 16, 10, 16, 12, 16, 16, 16, - 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 9, 16, 16, 16, 16, 16, - 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 11, 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, - }, - }, - { - { - 0, 8, 4, 10, 5, 9, 8, 10, 6, 11, 8, 12, 8, 11, 10, 13, - 14, 16, 14, 16, 14, 16, 16, 16, 3, 11, 5, 11, 8, 12, 10, 12, - 7, 12, 9, 13, 10, 13, 11, 13, 14, 16, 14, 16, 16, 16, 16, 16, - 9, 16, 9, 16, 12, 16, 12, 16, 11, 16, 11, 16, 14, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 7, 12, 6, 11, 10, 12, - 8, 13, 9, 13, 9, 13, 11, 14, 13, 16, 14, 16, 14, 16, 16, 16, - 7, 13, 9, 13, 9, 13, 11, 13, 9, 14, 10, 16, 11, 16, 12, 16, - 15, 16, 14, 16, 16, 16, 16, 16, 12, 16, 12, 16, 14, 16, 13, 16, - 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 10, 16, 13, 16, 12, 16, 13, 16, 12, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 13, 16, 14, 16, - 13, 16, 14, 16, 14, 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, 2, 10, 5, 11, 6, 11, 9, 11, - 7, 12, 9, 13, 9, 13, 11, 13, 14, 16, 16, 16, 16, 16, 16, 16, - 4, 12, 6, 12, 8, 13, 10, 13, 8, 13, 9, 13, 11, 16, 12, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 8, 16, 12, 16, 12, 16, - 12, 16, 11, 16, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 12, 8, 13, 7, 13, 10, 13, 8, 14, 10, 14, 10, 14, 12, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 7, 14, 9, 16, 10, 16, 11, 14, - 8, 14, 10, 16, 11, 16, 12, 16, 13, 16, 14, 16, 16, 16, 16, 16, - 11, 16, 11, 16, 13, 16, 13, 16, 12, 16, 12, 16, 14, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 12, 16, 10, 16, 12, 16, - 12, 16, 13, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 13, 16, 12, 16, 14, 16, 12, 16, 13, 16, 12, 16, 14, 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, - 6, 16, 8, 16, 9, 16, 11, 13, 10, 16, 11, 16, 11, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 9, 16, 10, 16, 12, 16, - 11, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 9, 16, 12, 16, 13, 16, 13, 16, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 10, 16, 9, 16, 12, 16, - 11, 16, 12, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 11, 16, 11, 16, 12, 16, 11, 16, 12, 16, 13, 16, 13, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 14, 16, 14, 16, - 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 10, 16, 13, 16, 13, 16, 14, 16, 13, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 12, 16, 14, 16, - 12, 16, 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 11, 16, 13, 16, - 12, 16, 13, 16, 13, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 11, 16, 13, 16, 13, 16, 13, 16, 13, 16, 14, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 14, 16, 13, 16, - 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 12, 16, 12, 16, 13, 16, 13, 16, 13, 16, 13, 16, 14, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 12, 16, 13, 16, 14, 16, - 13, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 12, 16, 14, 16, 14, 16, 14, 16, 14, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 11, 16, 14, 16, - 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 14, 16, 13, 16, 14, 16, 16, 16, 16, 16, 14, 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, - }, - { - 0, 10, 4, 12, 5, 16, 11, 16, 6, 16, 10, 16, 11, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 3, 16, 7, 16, 10, 16, 16, 16, - 9, 16, 12, 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, 4, 16, 10, 16, 9, 16, 16, 16, - 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 12, 16, 16, 16, 16, 16, 11, 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 6, 16, 8, 16, 16, 16, - 8, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 16, 8, 16, 11, 16, 16, 16, 10, 16, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 16, 11, 16, 9, 16, 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 12, 16, 16, 16, 16, 16, - 10, 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, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 5, 16, 9, 16, 11, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 10, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 12, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 11, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 16, 16, 16, 16, 16, 16, 12, 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, - 12, 16, 16, 16, 12, 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, 6, 16, 11, 16, 15, 16, 16, 16, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 9, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 9, 16, 16, 16, 16, 16, - 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 11, 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, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 12, 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, - }, - }, -}; - -static const uint8_t rv34_table_inter_secondpat[NUM_INTER_TABLES][2][OTHERBLK_VLC_SIZE] = { - { - { - 0, 4, 8, 3, 6, 8, 6, 7, 8, 4, 6, 8, 6, 7, 8, 7, - 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 3, 6, 8, 4, 6, - 9, 7, 7, 8, 5, 7, 9, 6, 7, 9, 8, 8, 8, 7, 8, 8, - 8, 8, 8, 8, 8, 7, 6, 8, 9, 7, 8, 9, 7, 8, 9, 7, - 8, 9, 7, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 8, 8, - 8, 8, 9, 9, 8, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9, 9, - 8, 8, 8, 7, 8, 8, 8, 8, 8, 7, 7, 6, - }, - { - 0, 4, 9, 3, 6, 9, 7, 8, 10, 3, 6, 9, 5, 7, 10, 9, - 9, 10, 7, 8, 10, 8, 9, 10, 10, 10, 10, 2, 6, 9, 4, 7, - 10, 8, 9, 10, 4, 7, 10, 6, 7, 10, 9, 9, 10, 7, 8, 10, - 8, 9, 10, 10, 10, 10, 6, 8, 10, 7, 9, 11, 9, 10, 11, 7, - 9, 11, 8, 9, 11, 10, 10, 11, 8, 9, 11, 9, 10, 11, 11, 11, - 10, 8, 10, 11, 9, 10, 11, 9, 10, 11, 8, 10, 11, 9, 10, 11, - 10, 10, 11, 8, 10, 11, 9, 10, 10, 10, 10, 9, - }, - }, - { - { - 0, 4, 8, 3, 6, 8, 6, 7, 9, 4, 6, 8, 5, 7, 8, 8, - 8, 9, 7, 7, 8, 8, 8, 8, 8, 9, 8, 3, 6, 8, 4, 6, - 9, 7, 7, 9, 5, 6, 9, 6, 7, 9, 8, 8, 9, 7, 8, 8, - 8, 8, 8, 8, 8, 8, 6, 8, 9, 7, 8, 10, 7, 8, 9, 7, - 8, 10, 7, 8, 10, 8, 8, 9, 7, 8, 9, 8, 9, 9, 9, 9, - 8, 7, 9, 10, 8, 9, 10, 8, 8, 8, 8, 9, 10, 8, 9, 9, - 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 7, 6, - }, - { - 0, 4, 9, 3, 6, 10, 8, 9, 11, 3, 5, 9, 5, 7, 10, 9, - 10, 11, 7, 8, 10, 9, 9, 11, 11, 11, 12, 2, 5, 10, 4, 7, - 10, 8, 9, 11, 4, 6, 10, 6, 7, 10, 9, 10, 11, 7, 9, 10, - 9, 9, 11, 11, 11, 11, 6, 8, 11, 7, 9, 11, 9, 10, 12, 7, - 9, 11, 8, 9, 12, 10, 10, 12, 8, 10, 11, 10, 10, 11, 12, 11, - 11, 8, 10, 12, 9, 11, 12, 10, 11, 12, 9, 10, 12, 10, 11, 12, - 11, 11, 12, 9, 10, 12, 10, 10, 11, 11, 11, 10, - }, - }, - { - { - 0, 4, 8, 3, 6, 9, 7, 8, 9, 4, 6, 8, 5, 7, 9, 8, - 9, 9, 7, 8, 9, 8, 8, 9, 9, 9, 9, 2, 6, 9, 4, 6, - 9, 7, 8, 10, 5, 7, 9, 6, 7, 9, 8, 8, 9, 7, 8, 9, - 8, 8, 9, 9, 9, 9, 6, 8, 10, 7, 8, 10, 8, 9, 10, 6, - 8, 10, 8, 8, 10, 9, 9, 10, 8, 9, 10, 9, 9, 10, 10, 10, - 9, 8, 9, 10, 8, 9, 10, 8, 9, 10, 8, 9, 10, 9, 9, 10, - 9, 9, 9, 8, 9, 9, 8, 9, 9, 9, 9, 8, - }, - { - 0, 4, 10, 3, 6, 10, 8, 10, 12, 2, 6, 10, 6, 8, 11, 10, - 11, 12, 7, 9, 11, 9, 10, 12, 12, 13, 13, 2, 6, 10, 4, 7, - 11, 9, 10, 13, 4, 7, 11, 7, 8, 11, 10, 11, 12, 8, 9, 12, - 10, 10, 12, 12, 12, 13, 6, 9, 12, 8, 10, 13, 10, 12, 14, 7, - 10, 13, 9, 10, 13, 11, 11, 13, 9, 11, 13, 11, 11, 13, 13, 13, - 13, 9, 11, 13, 10, 12, 14, 11, 12, 14, 9, 11, 14, 11, 12, 14, - 12, 12, 14, 9, 12, 13, 11, 12, 13, 13, 12, 12, - }, - }, - { - { - 0, 4, 9, 3, 6, 9, 7, 8, 10, 3, 6, 9, 6, 7, 9, 9, - 9, 10, 7, 8, 9, 8, 9, 10, 10, 10, 11, 2, 6, 9, 4, 7, - 10, 7, 9, 10, 4, 7, 10, 6, 7, 10, 9, 9, 10, 7, 8, 10, - 8, 9, 10, 10, 10, 10, 6, 8, 11, 7, 9, 11, 8, 10, 11, 6, - 9, 11, 8, 9, 11, 9, 9, 11, 8, 9, 11, 9, 10, 11, 11, 10, - 10, 8, 10, 11, 9, 10, 11, 9, 10, 11, 8, 10, 11, 9, 10, 11, - 10, 10, 11, 8, 10, 11, 9, 10, 11, 10, 10, 10, - }, - { - 0, 4, 12, 3, 7, 12, 10, 11, 14, 3, 6, 12, 7, 9, 13, 12, - 13, 14, 8, 11, 13, 11, 12, 14, 14, 14, 14, 1, 7, 12, 5, 8, - 13, 10, 12, 14, 4, 8, 13, 8, 9, 13, 12, 13, 14, 9, 11, 14, - 11, 12, 14, 14, 14, 14, 7, 10, 14, 9, 11, 14, 11, 13, 16, 8, - 11, 14, 10, 12, 14, 13, 13, 16, 10, 12, 15, 12, 13, 15, 15, 15, - 15, 10, 13, 15, 12, 13, 14, 13, 15, 15, 10, 13, 15, 12, 13, 15, - 13, 14, 15, 10, 13, 14, 12, 13, 14, 14, 14, 14, - }, - }, - { - { - 0, 4, 9, 3, 6, 10, 7, 9, 11, 3, 5, 9, 5, 7, 10, 9, - 10, 12, 7, 8, 10, 9, 10, 11, 11, 12, 12, 2, 6, 10, 4, 7, - 10, 7, 9, 12, 4, 7, 10, 6, 7, 11, 9, 10, 12, 7, 9, 11, - 9, 9, 11, 11, 11, 12, 5, 8, 11, 7, 9, 12, 9, 10, 13, 6, - 9, 12, 8, 9, 12, 10, 10, 12, 8, 10, 12, 10, 10, 12, 12, 12, - 12, 8, 10, 12, 9, 11, 13, 10, 11, 13, 9, 11, 13, 10, 11, 13, - 11, 11, 13, 9, 11, 12, 10, 11, 12, 11, 11, 12, - }, - { - 0, 4, 12, 3, 7, 13, 10, 12, 15, 3, 7, 13, 7, 9, 14, 12, - 12, 13, 8, 11, 14, 11, 13, 15, 15, 14, 14, 1, 6, 13, 5, 8, - 13, 10, 13, 15, 4, 8, 13, 8, 9, 14, 13, 13, 15, 8, 11, 14, - 12, 12, 15, 15, 14, 14, 7, 10, 13, 9, 11, 13, 12, 14, 16, 8, - 11, 14, 10, 12, 15, 13, 13, 16, 10, 12, 15, 12, 13, 15, 15, 14, - 15, 11, 12, 14, 12, 14, 14, 13, 15, 15, 10, 12, 14, 12, 13, 15, - 14, 15, 15, 10, 13, 13, 12, 13, 15, 14, 14, 15, - }, - }, - { - { - 0, 5, 10, 3, 7, 11, 9, 11, 14, 3, 7, 11, 7, 8, 12, 11, - 12, 14, 7, 9, 12, 10, 11, 14, 13, 14, 16, 1, 7, 11, 5, 8, - 12, 9, 11, 15, 4, 8, 12, 7, 9, 13, 11, 12, 15, 8, 10, 13, - 10, 11, 14, 14, 14, 16, 6, 9, 13, 8, 11, 14, 10, 13, 16, 7, - 10, 14, 9, 11, 15, 12, 13, 16, 9, 11, 15, 12, 12, 15, 14, 14, - 16, 10, 12, 14, 11, 13, 15, 12, 14, 16, 10, 12, 15, 11, 13, 16, - 13, 14, 16, 10, 13, 16, 12, 13, 15, 14, 15, 16, - }, - { - 0, 5, 16, 3, 8, 14, 11, 13, 14, 2, 8, 14, 8, 10, 16, 13, - 13, 14, 9, 13, 16, 12, 13, 16, 16, 14, 16, 1, 7, 14, 6, 10, - 14, 12, 16, 16, 5, 9, 14, 9, 11, 16, 15, 16, 16, 10, 12, 16, - 13, 13, 16, 16, 14, 16, 8, 11, 14, 11, 13, 14, 14, 14, 16, 8, - 12, 14, 11, 13, 16, 16, 16, 16, 10, 12, 15, 13, 14, 16, 16, 16, - 16, 11, 14, 14, 14, 15, 16, 16, 15, 16, 10, 13, 16, 13, 14, 14, - 16, 16, 16, 10, 13, 16, 13, 14, 16, 16, 16, 16, - }, - }, - { - { - 0, 5, 11, 3, 7, 13, 9, 12, 16, 3, 7, 12, 6, 9, 14, 11, - 13, 16, 7, 10, 16, 11, 12, 16, 16, 16, 16, 1, 6, 12, 5, 9, - 16, 9, 13, 16, 4, 8, 16, 7, 10, 16, 12, 15, 16, 7, 11, 16, - 11, 12, 16, 16, 16, 16, 6, 10, 15, 8, 11, 16, 11, 14, 16, 7, - 11, 16, 10, 12, 16, 13, 16, 16, 9, 13, 16, 13, 14, 16, 16, 16, - 16, 10, 12, 16, 12, 16, 16, 16, 16, 16, 11, 13, 16, 13, 16, 16, - 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, - }, - { - 0, 5, 16, 3, 8, 16, 12, 12, 16, 2, 8, 16, 8, 10, 16, 13, - 13, 16, 9, 13, 16, 12, 13, 16, 16, 16, 16, 1, 8, 16, 6, 10, - 16, 12, 16, 16, 5, 9, 16, 9, 11, 16, 13, 16, 16, 9, 12, 14, - 12, 12, 16, 16, 16, 16, 8, 11, 13, 11, 12, 16, 14, 16, 16, 8, - 12, 16, 11, 13, 16, 16, 15, 16, 9, 13, 14, 12, 13, 16, 16, 16, - 16, 10, 12, 13, 14, 13, 16, 16, 16, 16, 9, 13, 16, 13, 12, 16, - 16, 16, 16, 10, 12, 16, 14, 15, 16, 16, 16, 16, - }, - }, -}; - -static const uint8_t rv34_table_inter_thirdpat[NUM_INTER_TABLES][2][OTHERBLK_VLC_SIZE] = { - { - { - 0, 5, 8, 3, 6, 9, 6, 7, 9, 4, 6, 9, 6, 7, 9, 8, - 8, 9, 7, 8, 9, 8, 9, 9, 9, 9, 9, 2, 6, 9, 4, 7, - 9, 7, 8, 9, 5, 7, 9, 6, 7, 9, 8, 8, 9, 7, 8, 9, - 8, 9, 9, 9, 9, 8, 5, 8, 10, 6, 8, 10, 8, 9, 9, 7, - 8, 10, 7, 9, 10, 8, 9, 9, 8, 9, 10, 9, 9, 10, 9, 9, - 9, 7, 9, 10, 8, 9, 10, 8, 8, 9, 8, 9, 10, 8, 9, 10, - 8, 8, 9, 8, 9, 9, 8, 9, 9, 8, 8, 7, - }, - { - 0, 4, 9, 2, 6, 10, 7, 8, 10, 3, 6, 10, 6, 7, 10, 9, - 9, 10, 8, 9, 11, 9, 10, 11, 10, 11, 11, 2, 6, 10, 4, 7, - 10, 8, 9, 10, 5, 7, 10, 7, 8, 10, 9, 9, 10, 9, 10, 11, - 10, 10, 11, 11, 11, 11, 6, 9, 11, 7, 9, 11, 9, 10, 12, 8, - 9, 11, 8, 10, 11, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, - 11, 9, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12, - 11, 11, 12, 11, 12, 12, 11, 12, 12, 12, 11, 11, - }, - }, - { - { - 0, 4, 9, 3, 6, 9, 6, 8, 9, 4, 6, 9, 5, 7, 9, 8, - 8, 9, 7, 8, 10, 8, 9, 10, 9, 9, 9, 2, 6, 9, 4, 7, - 9, 7, 8, 9, 5, 7, 9, 6, 7, 10, 8, 9, 9, 7, 9, 10, - 8, 9, 10, 9, 9, 9, 5, 8, 10, 6, 8, 10, 8, 9, 10, 7, - 8, 10, 7, 9, 11, 9, 9, 10, 8, 9, 10, 9, 10, 10, 10, 10, - 9, 7, 9, 10, 8, 9, 11, 8, 9, 10, 8, 9, 11, 8, 9, 11, - 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 8, - }, - { - 0, 4, 9, 2, 5, 10, 7, 8, 11, 3, 6, 10, 6, 7, 10, 9, - 10, 11, 8, 9, 11, 9, 10, 11, 11, 11, 12, 2, 6, 10, 4, 7, - 10, 8, 9, 11, 5, 7, 10, 6, 8, 10, 9, 10, 11, 9, 10, 12, - 10, 10, 12, 11, 12, 12, 6, 9, 11, 8, 9, 12, 9, 11, 13, 8, - 10, 12, 9, 10, 12, 11, 11, 12, 10, 12, 13, 11, 12, 13, 13, 12, - 13, 10, 11, 13, 10, 12, 13, 11, 12, 13, 11, 12, 13, 11, 12, 13, - 12, 12, 13, 12, 13, 14, 13, 13, 14, 13, 13, 13, - }, - }, - { - { - 0, 4, 9, 3, 6, 9, 7, 8, 10, 3, 6, 9, 5, 7, 10, 8, - 9, 10, 7, 9, 10, 8, 9, 10, 10, 10, 10, 2, 6, 9, 4, 7, - 10, 7, 9, 10, 4, 7, 10, 6, 8, 10, 8, 9, 10, 8, 9, 10, - 9, 9, 10, 10, 10, 10, 5, 8, 11, 7, 9, 11, 8, 10, 11, 7, - 9, 11, 8, 9, 11, 9, 10, 11, 9, 10, 11, 10, 10, 11, 11, 11, - 11, 8, 10, 11, 9, 10, 11, 9, 10, 11, 9, 10, 12, 9, 10, 12, - 10, 11, 11, 9, 10, 11, 10, 11, 11, 10, 10, 10, - }, - { - 0, 4, 10, 3, 6, 11, 8, 10, 12, 3, 6, 11, 6, 8, 11, 10, - 11, 13, 9, 10, 13, 11, 12, 14, 13, 13, 14, 1, 6, 10, 5, 8, - 12, 9, 10, 13, 5, 8, 11, 7, 9, 12, 11, 11, 13, 10, 12, 13, - 11, 12, 14, 14, 13, 15, 7, 10, 12, 9, 11, 14, 11, 12, 15, 9, - 11, 13, 10, 11, 14, 12, 12, 14, 12, 14, 16, 13, 13, 16, 14, 14, - 16, 12, 13, 15, 12, 14, 15, 13, 14, 16, 13, 14, 16, 14, 14, 16, - 14, 15, 16, 14, 16, 16, 15, 16, 16, 15, 15, 16, - }, - }, - { - { - 0, 4, 9, 2, 6, 9, 7, 9, 11, 3, 6, 10, 6, 7, 10, 9, - 10, 11, 7, 9, 10, 9, 10, 11, 11, 11, 12, 2, 6, 10, 4, 7, - 10, 8, 9, 11, 5, 7, 10, 7, 8, 10, 9, 10, 11, 8, 9, 11, - 9, 10, 11, 11, 12, 11, 6, 9, 11, 7, 10, 12, 9, 11, 12, 7, - 10, 12, 9, 10, 12, 11, 11, 12, 9, 11, 12, 10, 11, 12, 12, 12, - 12, 9, 11, 12, 9, 11, 13, 11, 12, 13, 9, 11, 13, 10, 12, 13, - 11, 12, 13, 11, 12, 13, 11, 12, 13, 12, 13, 12, - }, - { - 0, 4, 11, 2, 6, 12, 9, 11, 16, 4, 7, 12, 7, 9, 15, 11, - 12, 16, 10, 11, 16, 11, 13, 16, 16, 16, 16, 1, 6, 11, 5, 8, - 16, 9, 12, 16, 6, 9, 15, 8, 10, 16, 12, 13, 16, 12, 14, 16, - 12, 16, 16, 16, 16, 16, 8, 11, 14, 10, 12, 16, 12, 16, 16, 10, - 13, 16, 12, 16, 16, 13, 14, 16, 14, 16, 16, 16, 16, 16, 16, 16, - 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - }, - }, - { - { - 0, 5, 9, 3, 6, 10, 8, 10, 12, 3, 6, 10, 6, 8, 10, 10, - 11, 12, 8, 9, 11, 10, 10, 12, 13, 13, 13, 1, 6, 10, 5, 8, - 11, 9, 11, 13, 5, 8, 11, 7, 9, 11, 11, 11, 13, 8, 9, 11, - 10, 10, 12, 13, 13, 14, 6, 9, 12, 8, 11, 13, 11, 13, 15, 8, - 10, 13, 10, 11, 13, 12, 13, 15, 10, 12, 13, 12, 12, 13, 14, 14, - 14, 9, 12, 14, 11, 13, 15, 13, 15, 16, 11, 13, 15, 12, 14, 15, - 14, 15, 16, 13, 14, 15, 14, 14, 15, 15, 16, 16, - }, - { - 0, 4, 16, 2, 7, 16, 10, 13, 16, 3, 8, 16, 7, 10, 16, 16, - 16, 16, 12, 16, 16, 15, 16, 16, 16, 16, 16, 1, 7, 16, 6, 9, - 16, 10, 16, 16, 7, 12, 16, 9, 13, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 9, 16, 16, 11, 13, 16, 16, 16, 16, 12, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 14, 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, - }, - }, - { - { - 0, 4, 9, 3, 6, 11, 9, 12, 16, 3, 6, 10, 6, 8, 11, 12, - 13, 16, 8, 9, 12, 10, 11, 13, 16, 16, 16, 1, 6, 10, 5, 8, - 12, 10, 13, 16, 5, 8, 11, 8, 9, 13, 13, 14, 16, 9, 10, 14, - 11, 12, 15, 16, 16, 16, 6, 10, 13, 9, 12, 16, 14, 16, 16, 9, - 12, 14, 11, 13, 16, 16, 16, 16, 12, 14, 16, 14, 16, 16, 16, 16, - 16, 11, 16, 16, 13, 16, 16, 16, 16, 16, 12, 16, 16, 13, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - }, - { - 0, 4, 16, 2, 8, 16, 10, 16, 16, 3, 9, 16, 8, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 7, 16, 5, 10, - 16, 16, 16, 16, 7, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 10, 15, 16, 10, 16, 16, 16, 16, 16, 14, - 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, - }, - }, - { - { - 0, 3, 9, 3, 7, 11, 11, 15, 16, 3, 6, 11, 7, 9, 12, 16, - 16, 16, 8, 10, 16, 11, 16, 16, 16, 16, 16, 1, 6, 11, 6, 9, - 15, 16, 16, 16, 5, 8, 16, 9, 11, 16, 16, 16, 16, 10, 16, 16, - 16, 16, 16, 16, 16, 16, 7, 11, 16, 11, 16, 16, 16, 16, 16, 11, - 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, - }, - { - 0, 4, 16, 2, 8, 16, 16, 16, 16, 3, 12, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 7, 16, 5, 12, - 16, 16, 16, 16, 6, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 9, 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, - }, - }, -}; - - -static const uint8_t rv34_inter_coeff[NUM_INTER_TABLES][COEFF_VLC_SIZE] = { -{ - 1, 2, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, - 10, 10, 10, 11, 11, 11, 11, 12, 11, 11, 11, 13, 14, 15, 16, 16, -}, -{ - 1, 2, 3, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, 10, 10, 10, - 11, 11, 12, 12, 12, 12, 13, 13, 12, 12, 13, 14, 16, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, - 12, 12, 13, 13, 13, 14, 14, 15, 14, 14, 16, 16, 16, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, - 13, 13, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 11, 11, 13, 12, 12, 13, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -}, -{ - 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 10, 11, 14, 13, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, -} -}; - -#endif /* AVCODEC_RV34VLC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rv40.c b/tizen/distrib/ffmpeg/libavcodec/rv40.c deleted file mode 100644 index abdeeff..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv40.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * RV40 decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV40 decoder - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "golomb.h" - -#include "rv34.h" -#include "rv40vlc2.h" -#include "rv40data.h" - -static VLC aic_top_vlc; -static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM]; -static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS]; - -static const int16_t mode2_offs[] = { - 0, 614, 1222, 1794, 2410, 3014, 3586, 4202, 4792, 5382, 5966, 6542, - 7138, 7716, 8292, 8864, 9444, 10030, 10642, 11212, 11814 -}; - -/** - * Initialize all tables. - */ -static av_cold void rv40_init_tables(void) -{ - int i; - static VLC_TYPE aic_table[1 << AIC_TOP_BITS][2]; - static VLC_TYPE aic_mode1_table[AIC_MODE1_NUM << AIC_MODE1_BITS][2]; - static VLC_TYPE aic_mode2_table[11814][2]; - static VLC_TYPE ptype_table[NUM_PTYPE_VLCS << PTYPE_VLC_BITS][2]; - static VLC_TYPE btype_table[NUM_BTYPE_VLCS << BTYPE_VLC_BITS][2]; - - aic_top_vlc.table = aic_table; - aic_top_vlc.table_allocated = 1 << AIC_TOP_BITS; - init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE, - rv40_aic_top_vlc_bits, 1, 1, - rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); - for(i = 0; i < AIC_MODE1_NUM; i++){ - // Every tenth VLC table is empty - if((i % 10) == 9) continue; - aic_mode1_vlc[i].table = &aic_mode1_table[i << AIC_MODE1_BITS]; - aic_mode1_vlc[i].table_allocated = 1 << AIC_MODE1_BITS; - init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE, - aic_mode1_vlc_bits[i], 1, 1, - aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - for(i = 0; i < AIC_MODE2_NUM; i++){ - aic_mode2_vlc[i].table = &aic_mode2_table[mode2_offs[i]]; - aic_mode2_vlc[i].table_allocated = mode2_offs[i + 1] - mode2_offs[i]; - init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, - aic_mode2_vlc_bits[i], 1, 1, - aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - for(i = 0; i < NUM_PTYPE_VLCS; i++){ - ptype_vlc[i].table = &ptype_table[i << PTYPE_VLC_BITS]; - ptype_vlc[i].table_allocated = 1 << PTYPE_VLC_BITS; - init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, - ptype_vlc_bits[i], 1, 1, - ptype_vlc_codes[i], 1, 1, - ptype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); - } - for(i = 0; i < NUM_BTYPE_VLCS; i++){ - btype_vlc[i].table = &btype_table[i << BTYPE_VLC_BITS]; - btype_vlc[i].table_allocated = 1 << BTYPE_VLC_BITS; - init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, - btype_vlc_bits[i], 1, 1, - btype_vlc_codes[i], 1, 1, - btype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); - } -} - -/** - * Get stored dimension from bitstream. - * - * If the width/height is the standard one then it's coded as a 3-bit index. - * Otherwise it is coded as escaped 8-bit portions. - */ -static int get_dimension(GetBitContext *gb, const int *dim) -{ - int t = get_bits(gb, 3); - int val = dim[t]; - if(val < 0) - val = dim[get_bits1(gb) - val]; - if(!val){ - do{ - t = get_bits(gb, 8); - val += t << 2; - }while(t == 0xFF); - } - return val; -} - -/** - * Get encoded picture size - usually this is called from rv40_parse_slice_header. - */ -static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h) -{ - *w = get_dimension(gb, rv40_standard_widths); - *h = get_dimension(gb, rv40_standard_heights); -} - -static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) -{ - int mb_bits; - int w = r->s.width, h = r->s.height; - int mb_size; - - memset(si, 0, sizeof(SliceInfo)); - if(get_bits1(gb)) - return -1; - si->type = get_bits(gb, 2); - if(si->type == 1) si->type = 0; - si->quant = get_bits(gb, 5); - if(get_bits(gb, 2)) - return -1; - si->vlc_set = get_bits(gb, 2); - skip_bits1(gb); - si->pts = get_bits(gb, 13); - if(!si->type || !get_bits1(gb)) - rv40_parse_picture_size(gb, &w, &h); - if(avcodec_check_dimensions(r->s.avctx, w, h) < 0) - return -1; - si->width = w; - si->height = h; - mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); - mb_bits = ff_rv34_get_start_offset(gb, mb_size); - si->start = get_bits(gb, mb_bits); - - return 0; -} - -/** - * Decode 4x4 intra types array. - */ -static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) -{ - MpegEncContext *s = &r->s; - int i, j, k, v; - int A, B, C; - int pattern; - int8_t *ptr; - - for(i = 0; i < 4; i++, dst += r->intra_types_stride){ - if(!i && s->first_slice_line){ - pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1); - dst[0] = (pattern >> 2) & 2; - dst[1] = (pattern >> 1) & 2; - dst[2] = pattern & 2; - dst[3] = (pattern << 1) & 2; - continue; - } - ptr = dst; - for(j = 0; j < 4; j++){ - /* Coefficients are read using VLC chosen by the prediction pattern - * The first one (used for retrieving a pair of coefficients) is - * constructed from the top, top right and left coefficients - * The second one (used for retrieving only one coefficient) is - * top + 10 * left. - */ - A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row - B = ptr[-r->intra_types_stride]; - C = ptr[-1]; - pattern = A + (B << 4) + (C << 8); - for(k = 0; k < MODE2_PATTERNS_NUM; k++) - if(pattern == rv40_aic_table_index[k]) - break; - if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients - v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2); - *ptr++ = v/9; - *ptr++ = v%9; - j++; - }else{ - if(B != -1 && C != -1) - v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1); - else{ // tricky decoding - v = 0; - switch(C){ - case -1: // code 0 -> 1, 1 -> 0 - if(B < 2) - v = get_bits1(gb) ^ 1; - break; - case 0: - case 2: // code 0 -> 2, 1 -> 0 - v = (get_bits1(gb) ^ 1) << 1; - break; - } - } - *ptr++ = v; - } - } - } - return 0; -} - -/** - * Decode macroblock information. - */ -static int rv40_decode_mb_info(RV34DecContext *r) -{ - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int q, i; - int prev_type = 0; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int blocks[RV34_MB_TYPES] = {0}; - int count = 0; - - if(!r->s.mb_skip_run) - r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; - - if(--r->s.mb_skip_run) - return RV34_MB_SKIP; - - if(r->avail_cache[6-1]) - blocks[r->mb_type[mb_pos - 1]]++; - if(r->avail_cache[6-4]){ - blocks[r->mb_type[mb_pos - s->mb_stride]]++; - if(r->avail_cache[6-2]) - blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++; - if(r->avail_cache[6-5]) - blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++; - } - - for(i = 0; i < RV34_MB_TYPES; i++){ - if(blocks[i] > count){ - count = blocks[i]; - prev_type = i; - } - } - if(s->pict_type == FF_P_TYPE){ - prev_type = block_num_to_ptype_vlc_num[prev_type]; - q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); - if(q < PBTYPE_ESCAPE) - return q; - q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); - av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n"); - }else{ - prev_type = block_num_to_btype_vlc_num[prev_type]; - q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); - if(q < PBTYPE_ESCAPE) - return q; - q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); - av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n"); - } - return 0; -} - -#define CLIP_SYMM(a, b) av_clip(a, -(b), b) -/** - * weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1 - */ -static inline void rv40_weak_loop_filter(uint8_t *src, const int step, - const int filter_p1, const int filter_q1, - const int alpha, const int beta, - const int lim_p0q0, - const int lim_q1, const int lim_p1, - const int diff_p1p0, const int diff_q1q0, - const int diff_p1p2, const int diff_q1q2) -{ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int t, u, diff; - - t = src[0*step] - src[-1*step]; - if(!t) - return; - u = (alpha * FFABS(t)) >> 7; - if(u > 3 - (filter_p1 && filter_q1)) - return; - - t <<= 2; - if(filter_p1 && filter_q1) - t += src[-2*step] - src[1*step]; - diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0); - src[-1*step] = cm[src[-1*step] + diff]; - src[ 0*step] = cm[src[ 0*step] - diff]; - if(FFABS(diff_p1p2) <= beta && filter_p1){ - t = (diff_p1p0 + diff_p1p2 - diff) >> 1; - src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)]; - } - if(FFABS(diff_q1q2) <= beta && filter_q1){ - t = (diff_q1q0 + diff_q1q2 + diff) >> 1; - src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)]; - } -} - -static inline void rv40_adaptive_loop_filter(uint8_t *src, const int step, - const int stride, const int dmode, - const int lim_q1, const int lim_p1, - const int alpha, - const int beta, const int beta2, - const int chroma, const int edge) -{ - int diff_p1p0[4], diff_q1q0[4], diff_p1p2[4], diff_q1q2[4]; - int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0; - uint8_t *ptr; - int flag_strong0 = 1, flag_strong1 = 1; - int filter_p1, filter_q1; - int i; - int lims; - - for(i = 0, ptr = src; i < 4; i++, ptr += stride){ - diff_p1p0[i] = ptr[-2*step] - ptr[-1*step]; - diff_q1q0[i] = ptr[ 1*step] - ptr[ 0*step]; - sum_p1p0 += diff_p1p0[i]; - sum_q1q0 += diff_q1q0[i]; - } - filter_p1 = FFABS(sum_p1p0) < (beta<<2); - filter_q1 = FFABS(sum_q1q0) < (beta<<2); - if(!filter_p1 && !filter_q1) - return; - - for(i = 0, ptr = src; i < 4; i++, ptr += stride){ - diff_p1p2[i] = ptr[-2*step] - ptr[-3*step]; - diff_q1q2[i] = ptr[ 1*step] - ptr[ 2*step]; - sum_p1p2 += diff_p1p2[i]; - sum_q1q2 += diff_q1q2[i]; - } - - if(edge){ - flag_strong0 = filter_p1 && (FFABS(sum_p1p2) < beta2); - flag_strong1 = filter_q1 && (FFABS(sum_q1q2) < beta2); - }else{ - flag_strong0 = flag_strong1 = 0; - } - - lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1; - if(flag_strong0 && flag_strong1){ /* strong filtering */ - for(i = 0; i < 4; i++, src += stride){ - int sflag, p0, q0, p1, q1; - int t = src[0*step] - src[-1*step]; - - if(!t) continue; - sflag = (alpha * FFABS(t)) >> 7; - if(sflag > 1) continue; - - p0 = (25*src[-3*step] + 26*src[-2*step] - + 26*src[-1*step] - + 26*src[ 0*step] + 25*src[ 1*step] + rv40_dither_l[dmode + i]) >> 7; - q0 = (25*src[-2*step] + 26*src[-1*step] - + 26*src[ 0*step] - + 26*src[ 1*step] + 25*src[ 2*step] + rv40_dither_r[dmode + i]) >> 7; - if(sflag){ - p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims); - q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims); - } - p1 = (25*src[-4*step] + 26*src[-3*step] - + 26*src[-2*step] - + 26*p0 + 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7; - q1 = (25*src[-1*step] + 26*q0 - + 26*src[ 1*step] - + 26*src[ 2*step] + 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7; - if(sflag){ - p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims); - q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims); - } - src[-2*step] = p1; - src[-1*step] = p0; - src[ 0*step] = q0; - src[ 1*step] = q1; - if(!chroma){ - src[-3*step] = (25*src[-1*step] + 26*src[-2*step] + 51*src[-3*step] + 26*src[-4*step] + 64) >> 7; - src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] + 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7; - } - } - }else if(filter_p1 && filter_q1){ - for(i = 0; i < 4; i++, src += stride) - rv40_weak_loop_filter(src, step, 1, 1, alpha, beta, lims, lim_q1, lim_p1, - diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]); - }else{ - for(i = 0; i < 4; i++, src += stride) - rv40_weak_loop_filter(src, step, filter_p1, filter_q1, - alpha, beta, lims>>1, lim_q1>>1, lim_p1>>1, - diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]); - } -} - -static void rv40_v_loop_filter(uint8_t *src, int stride, int dmode, - int lim_q1, int lim_p1, - int alpha, int beta, int beta2, int chroma, int edge){ - rv40_adaptive_loop_filter(src, 1, stride, dmode, lim_q1, lim_p1, - alpha, beta, beta2, chroma, edge); -} -static void rv40_h_loop_filter(uint8_t *src, int stride, int dmode, - int lim_q1, int lim_p1, - int alpha, int beta, int beta2, int chroma, int edge){ - rv40_adaptive_loop_filter(src, stride, 1, dmode, lim_q1, lim_p1, - alpha, beta, beta2, chroma, edge); -} - -enum RV40BlockPos{ - POS_CUR, - POS_TOP, - POS_LEFT, - POS_BOTTOM, -}; - -#define MASK_CUR 0x0001 -#define MASK_RIGHT 0x0008 -#define MASK_BOTTOM 0x0010 -#define MASK_TOP 0x1000 -#define MASK_Y_TOP_ROW 0x000F -#define MASK_Y_LAST_ROW 0xF000 -#define MASK_Y_LEFT_COL 0x1111 -#define MASK_Y_RIGHT_COL 0x8888 -#define MASK_C_TOP_ROW 0x0003 -#define MASK_C_LAST_ROW 0x000C -#define MASK_C_LEFT_COL 0x0005 -#define MASK_C_RIGHT_COL 0x000A - -static const int neighbour_offs_x[4] = { 0, 0, -1, 0 }; -static const int neighbour_offs_y[4] = { 0, -1, 0, 1 }; - -/** - * RV40 loop filtering function - */ -static void rv40_loop_filter(RV34DecContext *r, int row) -{ - MpegEncContext *s = &r->s; - int mb_pos, mb_x; - int i, j, k; - uint8_t *Y, *C; - int alpha, beta, betaY, betaC; - int q; - int mbtype[4]; ///< current macroblock and its neighbours types - /** - * flags indicating that macroblock can be filtered with strong filter - * it is set only for intra coded MB and MB with DCs coded separately - */ - int mb_strong[4]; - int clip[4]; ///< MB filter clipping value calculated from filtering strength - /** - * coded block patterns for luma part of current macroblock and its neighbours - * Format: - * LSB corresponds to the top left block, - * each nibble represents one row of subblocks. - */ - int cbp[4]; - /** - * coded block patterns for chroma part of current macroblock and its neighbours - * Format is the same as for luma with two subblocks in a row. - */ - int uvcbp[4][2]; - /** - * This mask represents the pattern of luma subblocks that should be filtered - * in addition to the coded ones because because they lie at the edge of - * 8x8 block with different enough motion vectors - */ - int mvmasks[4]; - - mb_pos = row * s->mb_stride; - for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - int mbtype = s->current_picture_ptr->mb_type[mb_pos]; - if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) - r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF; - if(IS_INTRA(mbtype)) - r->cbp_chroma[mb_pos] = 0xFF; - } - mb_pos = row * s->mb_stride; - for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ - int y_h_deblock, y_v_deblock; - int c_v_deblock[2], c_h_deblock[2]; - int clip_left; - int avail[4]; - int y_to_deblock, c_to_deblock[2]; - - q = s->current_picture_ptr->qscale_table[mb_pos]; - alpha = rv40_alpha_tab[q]; - beta = rv40_beta_tab [q]; - betaY = betaC = beta * 3; - if(s->width * s->height <= 176*144) - betaY += beta; - - avail[0] = 1; - avail[1] = row; - avail[2] = mb_x; - avail[3] = row < s->mb_height - 1; - for(i = 0; i < 4; i++){ - if(avail[i]){ - int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride; - mvmasks[i] = r->deblock_coefs[pos]; - mbtype [i] = s->current_picture_ptr->mb_type[pos]; - cbp [i] = r->cbp_luma[pos]; - uvcbp[i][0] = r->cbp_chroma[pos] & 0xF; - uvcbp[i][1] = r->cbp_chroma[pos] >> 4; - }else{ - mvmasks[i] = 0; - mbtype [i] = mbtype[0]; - cbp [i] = 0; - uvcbp[i][0] = uvcbp[i][1] = 0; - } - mb_strong[i] = IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i]); - clip[i] = rv40_filter_clip_tbl[mb_strong[i] + 1][q]; - } - y_to_deblock = mvmasks[POS_CUR] - | (mvmasks[POS_BOTTOM] << 16); - /* This pattern contains bits signalling that horizontal edges of - * the current block can be filtered. - * That happens when either of adjacent subblocks is coded or lies on - * the edge of 8x8 blocks with motion vectors differing by more than - * 3/4 pel in any component (any edge orientation for some reason). - */ - y_h_deblock = y_to_deblock - | ((cbp[POS_CUR] << 4) & ~MASK_Y_TOP_ROW) - | ((cbp[POS_TOP] & MASK_Y_LAST_ROW) >> 12); - /* This pattern contains bits signalling that vertical edges of - * the current block can be filtered. - * That happens when either of adjacent subblocks is coded or lies on - * the edge of 8x8 blocks with motion vectors differing by more than - * 3/4 pel in any component (any edge orientation for some reason). - */ - y_v_deblock = y_to_deblock - | ((cbp[POS_CUR] << 1) & ~MASK_Y_LEFT_COL) - | ((cbp[POS_LEFT] & MASK_Y_RIGHT_COL) >> 3); - if(!mb_x) - y_v_deblock &= ~MASK_Y_LEFT_COL; - if(!row) - y_h_deblock &= ~MASK_Y_TOP_ROW; - if(row == s->mb_height - 1 || (mb_strong[POS_CUR] || mb_strong[POS_BOTTOM])) - y_h_deblock &= ~(MASK_Y_TOP_ROW << 16); - /* Calculating chroma patterns is similar and easier since there is - * no motion vector pattern for them. - */ - for(i = 0; i < 2; i++){ - c_to_deblock[i] = (uvcbp[POS_BOTTOM][i] << 4) | uvcbp[POS_CUR][i]; - c_v_deblock[i] = c_to_deblock[i] - | ((uvcbp[POS_CUR] [i] << 1) & ~MASK_C_LEFT_COL) - | ((uvcbp[POS_LEFT][i] & MASK_C_RIGHT_COL) >> 1); - c_h_deblock[i] = c_to_deblock[i] - | ((uvcbp[POS_TOP][i] & MASK_C_LAST_ROW) >> 2) - | (uvcbp[POS_CUR][i] << 2); - if(!mb_x) - c_v_deblock[i] &= ~MASK_C_LEFT_COL; - if(!row) - c_h_deblock[i] &= ~MASK_C_TOP_ROW; - if(row == s->mb_height - 1 || mb_strong[POS_CUR] || mb_strong[POS_BOTTOM]) - c_h_deblock[i] &= ~(MASK_C_TOP_ROW << 4); - } - - for(j = 0; j < 16; j += 4){ - Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize; - for(i = 0; i < 4; i++, Y += 4){ - int ij = i + j; - int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0; - int dither = j ? ij : i*4; - - // if bottom block is coded then we can filter its top edge - // (or bottom edge of this block, which is the same) - if(y_h_deblock & (MASK_BOTTOM << ij)){ - rv40_h_loop_filter(Y+4*s->linesize, s->linesize, dither, - y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0, - clip_cur, - alpha, beta, betaY, 0, 0); - } - // filter left block edge in ordinary mode (with low filtering strength) - if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){ - if(!i) - clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; - else - clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; - rv40_v_loop_filter(Y, s->linesize, dither, - clip_cur, - clip_left, - alpha, beta, betaY, 0, 0); - } - // filter top edge of the current macroblock when filtering strength is high - if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){ - rv40_h_loop_filter(Y, s->linesize, dither, - clip_cur, - mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0, - alpha, beta, betaY, 0, 1); - } - // filter left block edge in edge mode (with high filtering strength) - if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){ - clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; - rv40_v_loop_filter(Y, s->linesize, dither, - clip_cur, - clip_left, - alpha, beta, betaY, 0, 1); - } - } - } - for(k = 0; k < 2; k++){ - for(j = 0; j < 2; j++){ - C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize; - for(i = 0; i < 2; i++, C += 4){ - int ij = i + j*2; - int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0; - if(c_h_deblock[k] & (MASK_CUR << (ij+2))){ - int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0; - rv40_h_loop_filter(C+4*s->uvlinesize, s->uvlinesize, i*8, - clip_bot, - clip_cur, - alpha, beta, betaC, 1, 0); - } - if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){ - if(!i) - clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; - else - clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; - rv40_v_loop_filter(C, s->uvlinesize, j*8, - clip_cur, - clip_left, - alpha, beta, betaC, 1, 0); - } - if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){ - int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0; - rv40_h_loop_filter(C, s->uvlinesize, i*8, - clip_cur, - clip_top, - alpha, beta, betaC, 1, 1); - } - if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){ - clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; - rv40_v_loop_filter(C, s->uvlinesize, j*8, - clip_cur, - clip_left, - alpha, beta, betaC, 1, 1); - } - } - } - } - } -} - -/** - * Initialize decoder. - */ -static av_cold int rv40_decode_init(AVCodecContext *avctx) -{ - RV34DecContext *r = avctx->priv_data; - - r->rv30 = 0; - ff_rv34_decode_init(avctx); - if(!aic_top_vlc.bits) - rv40_init_tables(); - r->parse_slice_header = rv40_parse_slice_header; - r->decode_intra_types = rv40_decode_intra_types; - r->decode_mb_info = rv40_decode_mb_info; - r->loop_filter = rv40_loop_filter; - r->luma_dc_quant_i = rv40_luma_dc_quant[0]; - r->luma_dc_quant_p = rv40_luma_dc_quant[1]; - return 0; -} - -AVCodec rv40_decoder = { - "rv40", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_RV40, - sizeof(RV34DecContext), - rv40_decode_init, - NULL, - ff_rv34_decode_end, - ff_rv34_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .flush = ff_mpeg_flush, - .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"), - .pix_fmts= ff_pixfmt_list_420, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/rv40data.h b/tizen/distrib/ffmpeg/libavcodec/rv40data.h deleted file mode 100644 index 5566569..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv40data.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * RealVideo 4 decoder - * copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * miscellaneous RV40 tables - */ - -#ifndef AVCODEC_RV40DATA_H -#define AVCODEC_RV40DATA_H - -#include - -/** - * standard widths and heights coded in RV40 - */ -//@{ -static const int rv40_standard_widths[] = { 160, 172, 240, 320, 352, 640, 704, 0}; -static const int rv40_standard_heights[] = { 120, 132, 144, 240, 288, 480, -8, -10, 180, 360, 576, 0}; -//@} - -#define MODE2_PATTERNS_NUM 20 -/** - * intra types table - * - * These values are actually coded 3-tuples - * used for detecting standard block configurations. - */ -static const uint16_t rv40_aic_table_index[MODE2_PATTERNS_NUM] = { - 0x000, 0x100, 0x200, - 0x011, 0x111, 0x211, 0x511, 0x611, - 0x022, 0x122, 0x222, 0x722, - 0x272, 0x227, - 0x822, 0x282, 0x228, - 0x112, 0x116, 0x221 -}; - -/** - * luma quantizer values - * The second table is used for inter blocks. - */ -static const uint8_t rv40_luma_dc_quant[2][32] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 22, 22, 22, 22 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 20, 21, 21, 22, 23, 23, 23, 24, 24, 24, 24 } -}; - -/** - * @begingroup loopfilter coefficients used by the RV40 loop filter - * @{ - */ -/** - * dither values for deblocking filter - left/top values - */ -static const uint8_t rv40_dither_l[16] = { - 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30, - 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40 -}; -/** - * dither values for deblocking filter - right/bottom values - */ -static const uint8_t rv40_dither_r[16] = { - 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40, - 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40 -}; - -/** alpha parameter for RV40 loop filter - almost the same as in JVT-A003r1 */ -static const uint8_t rv40_alpha_tab[32] = { - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 122, 96, 75, 59, 47, 37, - 29, 23, 18, 15, 13, 11, 10, 9, - 8, 7, 6, 5, 4, 3, 2, 1 -}; -/** beta parameter for RV40 loop filter - almost the same as in JVT-A003r1 */ -static const uint8_t rv40_beta_tab[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 4, 4, 6, 6, - 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, 15, 16, 17 -}; -/** clip table for RV40 loop filter - the same as in JVT-A003r1 */ -static const uint8_t rv40_filter_clip_tbl[3][32] = { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 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, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5 - }, - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7, 8, 9 - } -}; -/** @} */ // end loopfilter group - -#endif /* AVCODEC_RV40DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/rv40dsp.c b/tizen/distrib/ffmpeg/libavcodec/rv40dsp.c deleted file mode 100644 index 27bc79e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv40dsp.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * RV40 decoder motion compensation functions - * Copyright (c) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV40 decoder motion compensation functions - */ - -#include "avcodec.h" -#include "dsputil.h" - -#define RV40_LOWPASS(OPNAME, OP) \ -static av_unused void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\ - const int h, const int C1, const int C2, const int SHIFT){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i;\ - for(i=0; i> SHIFT);\ - OP(dst[1], (src[-1] + src[ 4] - 5*(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[2], (src[ 0] + src[ 5] - 5*(src[ 1]+src[4]) + src[2]*C1 + src[3]*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[3], (src[ 1] + src[ 6] - 5*(src[ 2]+src[5]) + src[3]*C1 + src[4]*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[4], (src[ 2] + src[ 7] - 5*(src[ 3]+src[6]) + src[4]*C1 + src[5]*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[5], (src[ 3] + src[ 8] - 5*(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[6], (src[ 4] + src[ 9] - 5*(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[7], (src[ 5] + src[10] - 5*(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - dst+=dstStride;\ - src+=srcStride;\ - }\ -}\ -\ -static void OPNAME ## rv40_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\ - const int w, const int C1, const int C2, const int SHIFT){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i;\ - for(i=0; i> SHIFT);\ - OP(dst[1*dstStride], (srcA + src4 - 5*(src0+src3) + src1*C1 + src2*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[2*dstStride], (src0 + src5 - 5*(src1+src4) + src2*C1 + src3*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[3*dstStride], (src1 + src6 - 5*(src2+src5) + src3*C1 + src4*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[4*dstStride], (src2 + src7 - 5*(src3+src6) + src4*C1 + src5*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[5*dstStride], (src3 + src8 - 5*(src4+src7) + src5*C1 + src6*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[6*dstStride], (src4 + src9 - 5*(src5+src8) + src6*C1 + src7*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - OP(dst[7*dstStride], (src5 + src10 - 5*(src6+src9) + src7*C1 + src8*C2 + (1<<(SHIFT-1))) >> SHIFT);\ - dst++;\ - src++;\ - }\ -}\ -\ -static void OPNAME ## rv40_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\ - const int w, const int C1, const int C2, const int SHIFT){\ - OPNAME ## rv40_qpel8_v_lowpass(dst , src , dstStride, srcStride, 8, C1, C2, SHIFT);\ - OPNAME ## rv40_qpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, 8, C1, C2, SHIFT);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv40_qpel8_v_lowpass(dst , src , dstStride, srcStride, w-8, C1, C2, SHIFT);\ - OPNAME ## rv40_qpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, w-8, C1, C2, SHIFT);\ -}\ -\ -static void OPNAME ## rv40_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\ - const int h, const int C1, const int C2, const int SHIFT){\ - OPNAME ## rv40_qpel8_h_lowpass(dst , src , dstStride, srcStride, 8, C1, C2, SHIFT);\ - OPNAME ## rv40_qpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, 8, C1, C2, SHIFT);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## rv40_qpel8_h_lowpass(dst , src , dstStride, srcStride, h-8, C1, C2, SHIFT);\ - OPNAME ## rv40_qpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, h-8, C1, C2, SHIFT);\ -}\ -\ - -#define RV40_MC(OPNAME, SIZE) \ -static void OPNAME ## rv40_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 20, 20, 5);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 20, 20, 5);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\ -}\ -\ -static void OPNAME ## rv40_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\ - OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\ -}\ -\ - -#define op_avg(a, b) a = (((a)+cm[b]+1)>>1) -#define op_put(a, b) a = cm[b] - -RV40_LOWPASS(put_ , op_put) -RV40_LOWPASS(avg_ , op_avg) - -#undef op_avg -#undef op_put - -RV40_MC(put_, 8) -RV40_MC(put_, 16) -RV40_MC(avg_, 8) -RV40_MC(avg_, 16) - -static const int rv40_bias[4][4] = { - { 0, 16, 32, 16 }, - { 32, 28, 32, 28 }, - { 0, 32, 16, 32 }, - { 32, 28, 32, 28 } -}; - -#define RV40_CHROMA_MC(OPNAME, OP)\ -static void OPNAME ## rv40_chroma_mc4_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;\ - int bias = rv40_bias[y>>1][x>>1];\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - if(D){\ - for(i=0; i>1][x>>1];\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - if(D){\ - for(i=0; i>6)+1)>>1) -#define op_put(a, b) a = ((b)>>6) - -RV40_CHROMA_MC(put_, op_put) -RV40_CHROMA_MC(avg_, op_avg) - -void ff_rv40dsp_init(DSPContext* c, AVCodecContext *avctx) { - c->put_rv40_qpel_pixels_tab[0][ 0] = c->put_h264_qpel_pixels_tab[0][0]; - c->put_rv40_qpel_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c; - c->put_rv40_qpel_pixels_tab[0][ 2] = put_rv40_qpel16_mc20_c; - c->put_rv40_qpel_pixels_tab[0][ 3] = put_rv40_qpel16_mc30_c; - c->put_rv40_qpel_pixels_tab[0][ 4] = put_rv40_qpel16_mc01_c; - c->put_rv40_qpel_pixels_tab[0][ 5] = put_rv40_qpel16_mc11_c; - c->put_rv40_qpel_pixels_tab[0][ 6] = put_rv40_qpel16_mc21_c; - c->put_rv40_qpel_pixels_tab[0][ 7] = put_rv40_qpel16_mc31_c; - c->put_rv40_qpel_pixels_tab[0][ 8] = put_rv40_qpel16_mc02_c; - c->put_rv40_qpel_pixels_tab[0][ 9] = put_rv40_qpel16_mc12_c; - c->put_rv40_qpel_pixels_tab[0][10] = put_rv40_qpel16_mc22_c; - c->put_rv40_qpel_pixels_tab[0][11] = put_rv40_qpel16_mc32_c; - c->put_rv40_qpel_pixels_tab[0][12] = put_rv40_qpel16_mc03_c; - c->put_rv40_qpel_pixels_tab[0][13] = put_rv40_qpel16_mc13_c; - c->put_rv40_qpel_pixels_tab[0][14] = put_rv40_qpel16_mc23_c; - c->avg_rv40_qpel_pixels_tab[0][ 0] = c->avg_h264_qpel_pixels_tab[0][0]; - c->avg_rv40_qpel_pixels_tab[0][ 1] = avg_rv40_qpel16_mc10_c; - c->avg_rv40_qpel_pixels_tab[0][ 2] = avg_rv40_qpel16_mc20_c; - c->avg_rv40_qpel_pixels_tab[0][ 3] = avg_rv40_qpel16_mc30_c; - c->avg_rv40_qpel_pixels_tab[0][ 4] = avg_rv40_qpel16_mc01_c; - c->avg_rv40_qpel_pixels_tab[0][ 5] = avg_rv40_qpel16_mc11_c; - c->avg_rv40_qpel_pixels_tab[0][ 6] = avg_rv40_qpel16_mc21_c; - c->avg_rv40_qpel_pixels_tab[0][ 7] = avg_rv40_qpel16_mc31_c; - c->avg_rv40_qpel_pixels_tab[0][ 8] = avg_rv40_qpel16_mc02_c; - c->avg_rv40_qpel_pixels_tab[0][ 9] = avg_rv40_qpel16_mc12_c; - c->avg_rv40_qpel_pixels_tab[0][10] = avg_rv40_qpel16_mc22_c; - c->avg_rv40_qpel_pixels_tab[0][11] = avg_rv40_qpel16_mc32_c; - c->avg_rv40_qpel_pixels_tab[0][12] = avg_rv40_qpel16_mc03_c; - c->avg_rv40_qpel_pixels_tab[0][13] = avg_rv40_qpel16_mc13_c; - c->avg_rv40_qpel_pixels_tab[0][14] = avg_rv40_qpel16_mc23_c; - c->put_rv40_qpel_pixels_tab[1][ 0] = c->put_h264_qpel_pixels_tab[1][0]; - c->put_rv40_qpel_pixels_tab[1][ 1] = put_rv40_qpel8_mc10_c; - c->put_rv40_qpel_pixels_tab[1][ 2] = put_rv40_qpel8_mc20_c; - c->put_rv40_qpel_pixels_tab[1][ 3] = put_rv40_qpel8_mc30_c; - c->put_rv40_qpel_pixels_tab[1][ 4] = put_rv40_qpel8_mc01_c; - c->put_rv40_qpel_pixels_tab[1][ 5] = put_rv40_qpel8_mc11_c; - c->put_rv40_qpel_pixels_tab[1][ 6] = put_rv40_qpel8_mc21_c; - c->put_rv40_qpel_pixels_tab[1][ 7] = put_rv40_qpel8_mc31_c; - c->put_rv40_qpel_pixels_tab[1][ 8] = put_rv40_qpel8_mc02_c; - c->put_rv40_qpel_pixels_tab[1][ 9] = put_rv40_qpel8_mc12_c; - c->put_rv40_qpel_pixels_tab[1][10] = put_rv40_qpel8_mc22_c; - c->put_rv40_qpel_pixels_tab[1][11] = put_rv40_qpel8_mc32_c; - c->put_rv40_qpel_pixels_tab[1][12] = put_rv40_qpel8_mc03_c; - c->put_rv40_qpel_pixels_tab[1][13] = put_rv40_qpel8_mc13_c; - c->put_rv40_qpel_pixels_tab[1][14] = put_rv40_qpel8_mc23_c; - c->avg_rv40_qpel_pixels_tab[1][ 0] = c->avg_h264_qpel_pixels_tab[1][0]; - c->avg_rv40_qpel_pixels_tab[1][ 1] = avg_rv40_qpel8_mc10_c; - c->avg_rv40_qpel_pixels_tab[1][ 2] = avg_rv40_qpel8_mc20_c; - c->avg_rv40_qpel_pixels_tab[1][ 3] = avg_rv40_qpel8_mc30_c; - c->avg_rv40_qpel_pixels_tab[1][ 4] = avg_rv40_qpel8_mc01_c; - c->avg_rv40_qpel_pixels_tab[1][ 5] = avg_rv40_qpel8_mc11_c; - c->avg_rv40_qpel_pixels_tab[1][ 6] = avg_rv40_qpel8_mc21_c; - c->avg_rv40_qpel_pixels_tab[1][ 7] = avg_rv40_qpel8_mc31_c; - c->avg_rv40_qpel_pixels_tab[1][ 8] = avg_rv40_qpel8_mc02_c; - c->avg_rv40_qpel_pixels_tab[1][ 9] = avg_rv40_qpel8_mc12_c; - c->avg_rv40_qpel_pixels_tab[1][10] = avg_rv40_qpel8_mc22_c; - c->avg_rv40_qpel_pixels_tab[1][11] = avg_rv40_qpel8_mc32_c; - c->avg_rv40_qpel_pixels_tab[1][12] = avg_rv40_qpel8_mc03_c; - c->avg_rv40_qpel_pixels_tab[1][13] = avg_rv40_qpel8_mc13_c; - c->avg_rv40_qpel_pixels_tab[1][14] = avg_rv40_qpel8_mc23_c; - - c->put_rv40_chroma_pixels_tab[0]= put_rv40_chroma_mc8_c; - c->put_rv40_chroma_pixels_tab[1]= put_rv40_chroma_mc4_c; - c->avg_rv40_chroma_pixels_tab[0]= avg_rv40_chroma_mc8_c; - c->avg_rv40_chroma_pixels_tab[1]= avg_rv40_chroma_mc4_c; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/rv40vlc2.h b/tizen/distrib/ffmpeg/libavcodec/rv40vlc2.h deleted file mode 100644 index 15119a1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/rv40vlc2.h +++ /dev/null @@ -1,706 +0,0 @@ -/* - * RealVideo 4 decoder - * copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RV40 VLC tables used for macroblock information decoding - */ - -#ifndef AVCODEC_RV40VLC2_H -#define AVCODEC_RV40VLC2_H - -#include - -/** - * codes used for the first four block types - */ -//@{ -#define AIC_TOP_BITS 8 -#define AIC_TOP_SIZE 16 -static const uint8_t rv40_aic_top_vlc_codes[AIC_TOP_SIZE] = { - 0x01, 0x05, 0x01, 0x00, 0x03, 0x3D, 0x1D, 0x02, - 0x04, 0x3C, 0x3F, 0x1C, 0x0D, 0x3E, 0x0C, 0x01 -}; - -static const uint8_t rv40_aic_top_vlc_bits[AIC_TOP_SIZE] = { - 1, 4, 5, 5, 5, 7, 6, 5, 4, 7, 7, 6, 5, 7, 5, 3 -}; -//@} - -/** - * codes used for determining a pair of block types - */ -//@{ -#define AIC_MODE2_NUM 20 -#define AIC_MODE2_SIZE 81 -#define AIC_MODE2_BITS 9 - -static const uint16_t aic_mode2_vlc_codes[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { -{ 0x0001, 0x0001, 0x0005, 0x01F5, 0x0011, 0x0049, 0x0000, 0x0048, 0x004B, - 0x0035, 0x0003, 0x0034, 0x03C9, 0x01F4, 0x00C9, 0x004A, 0x0FD9, 0x03C8, - 0x0010, 0x0037, 0x0001, 0x00C8, 0x0075, 0x01F7, 0x00CB, 0x0074, 0x0002, - 0x01F6, 0x00CA, 0x01F1, 0x01F0, 0x1F81, 0x07F9, 0x1F80, 0x1F83, 0x07F8, - 0x0077, 0x00F5, 0x0036, 0x07FB, 0x0076, 0x1F82, 0x00F4, 0x00F7, 0x07FA, - 0x0071, 0x00F6, 0x03CB, 0x03CA, 0x0FD8, 0x00F1, 0x03F5, 0x1F8D, 0x07E5, - 0x0013, 0x0031, 0x00F0, 0x0FDB, 0x00F3, 0x07E4, 0x0030, 0x01F3, 0x07E7, - 0x03F4, 0x07E6, 0x0070, 0x3F19, 0x01F2, 0x3F18, 0x0FDA, 0x0033, 0x07E1, - 0x01FD, 0x01FC, 0x0073, 0x01FF, 0x0FC5, 0x0FC4, 0x0FC7, 0x03F7, 0x0072, }, -{ 0x0005, 0x0005, 0x0005, 0x0079, 0x0005, 0x000D, 0x001D, 0x0078, 0x0069, - 0x0004, 0x0001, 0x0007, 0x0068, 0x001C, 0x001F, 0x0004, 0x006B, 0x000C, - 0x0004, 0x001E, 0x0006, 0x006A, 0x0015, 0x000F, 0x0014, 0x0017, 0x0007, - 0x0016, 0x000E, 0x0011, 0x0009, 0x00D1, 0x00D0, 0x0181, 0x00D3, 0x007B, - 0x0010, 0x0013, 0x0004, 0x00D2, 0x0007, 0x0319, 0x0008, 0x007A, 0x00DD, - 0x0019, 0x0006, 0x000B, 0x0065, 0x00DC, 0x0012, 0x0064, 0x0180, 0x00DF, - 0x0006, 0x0018, 0x0001, 0x00DE, 0x001D, 0x00D9, 0x001B, 0x0067, 0x000A, - 0x00D8, 0x00DB, 0x001C, 0x0318, 0x00DA, 0x0635, 0x0183, 0x0000, 0x00C5, - 0x0066, 0x0061, 0x0035, 0x00C4, 0x0182, 0x0634, 0x031B, 0x00C7, 0x001F, }, -{ 0x0005, 0x0001, 0x001D, 0x01C1, 0x0035, 0x00F1, 0x006D, 0x00F0, 0x0049, - 0x0000, 0x0004, 0x0003, 0x00F3, 0x0048, 0x0034, 0x006C, 0x01C0, 0x01C3, - 0x0007, 0x0006, 0x0001, 0x006F, 0x0002, 0x004B, 0x006E, 0x001C, 0x0005, - 0x0069, 0x0068, 0x006B, 0x0037, 0x01C2, 0x00F2, 0x0395, 0x01CD, 0x00FD, - 0x006A, 0x0036, 0x0015, 0x01CC, 0x0014, 0x0394, 0x004A, 0x00FC, 0x00FF, - 0x0017, 0x0031, 0x00FE, 0x01CF, 0x0397, 0x00F9, 0x01CE, 0x0725, 0x0396, - 0x0016, 0x0030, 0x0075, 0x0724, 0x00F8, 0x0727, 0x0033, 0x0391, 0x0390, - 0x0011, 0x0032, 0x001F, 0x00FB, 0x0074, 0x0726, 0x00FA, 0x001E, 0x0077, - 0x0019, 0x0018, 0x0004, 0x0010, 0x003D, 0x0076, 0x0071, 0x0013, 0x0001, }, -{ 0x000D, 0x0019, 0x0011, 0x0015, 0x0061, 0x0019, 0x0014, 0x01AD, 0x0060, - 0x0018, 0x0001, 0x0005, 0x001B, 0x0010, 0x0019, 0x0005, 0x0017, 0x0018, - 0x0016, 0x0004, 0x0004, 0x0013, 0x000C, 0x0012, 0x001A, 0x0018, 0x0005, - 0x000F, 0x001B, 0x0004, 0x001D, 0x0011, 0x001C, 0x0010, 0x000E, 0x001B, - 0x0013, 0x001F, 0x001A, 0x0029, 0x0005, 0x0063, 0x001E, 0x0009, 0x0062, - 0x0008, 0x0007, 0x0007, 0x0019, 0x0004, 0x001A, 0x0018, 0x006D, 0x0007, - 0x001B, 0x0007, 0x001A, 0x006C, 0x0006, 0x0012, 0x0005, 0x006F, 0x000B, - 0x006E, 0x0069, 0x001D, 0x0359, 0x0028, 0x002B, 0x002A, 0x001C, 0x00D5, - 0x0358, 0x001F, 0x0001, 0x001E, 0x0068, 0x00D4, 0x00D7, 0x0019, 0x0000, }, -{ 0x00B9, 0x0061, 0x0060, 0x00B8, 0x02B5, 0x01AD, 0x00BB, 0x0AF5, 0x0151, - 0x0001, 0x0001, 0x0005, 0x0000, 0x0003, 0x0005, 0x0004, 0x0063, 0x0025, - 0x00BA, 0x0004, 0x0007, 0x0062, 0x00A5, 0x0024, 0x006D, 0x0002, 0x006C, - 0x02B4, 0x000D, 0x006F, 0x0027, 0x00A4, 0x0026, 0x01AC, 0x0150, 0x01AF, - 0x01AE, 0x0021, 0x006E, 0x02B7, 0x0020, 0x0153, 0x0023, 0x00A7, 0x0152, - 0x00A6, 0x0006, 0x000C, 0x0022, 0x01A9, 0x0019, 0x002D, 0x02B6, 0x01A8, - 0x000F, 0x0007, 0x000E, 0x00A1, 0x0069, 0x002C, 0x0001, 0x01AB, 0x00A0, - 0x02B1, 0x00A3, 0x002F, 0x0AF4, 0x02B0, 0x0AF7, 0x02B3, 0x0068, 0x015D, - 0x0AF6, 0x01AA, 0x0055, 0x015C, 0x02B2, 0x0579, 0x0578, 0x015F, 0x00A2, }, -{ 0x0905, 0x013D, 0x013C, 0x0904, 0x121D, 0x049D, 0x049C, 0x243D, 0x0907, - 0x00ED, 0x0001, 0x0015, 0x0041, 0x013F, 0x0031, 0x0014, 0x025D, 0x025C, - 0x013E, 0x000D, 0x0000, 0x0040, 0x0139, 0x0043, 0x0030, 0x0017, 0x0033, - 0x0906, 0x0032, 0x0042, 0x00EC, 0x025F, 0x00EF, 0x025E, 0x049F, 0x0138, - 0x0901, 0x013B, 0x0259, 0x121C, 0x049E, 0x0900, 0x0258, 0x243C, 0x121F, - 0x0903, 0x003D, 0x00EE, 0x025B, 0x025A, 0x004D, 0x013A, 0x0902, 0x0245, - 0x00E9, 0x0016, 0x00E8, 0x0499, 0x0125, 0x0244, 0x004C, 0x0498, 0x090D, - 0x00EB, 0x003C, 0x0011, 0x049B, 0x049A, 0x0485, 0x00EA, 0x003F, 0x0124, - 0x090C, 0x003E, 0x0039, 0x0095, 0x0247, 0x0246, 0x0484, 0x0094, 0x0038, }, -{ 0x0F09, 0x00CD, 0x01FD, 0x0791, 0x1E6D, 0x0790, 0x03D9, 0x3CD1, 0x3CD0, - 0x0075, 0x0001, 0x0001, 0x0035, 0x00CC, 0x0011, 0x0000, 0x03D8, 0x01FC, - 0x03DB, 0x0010, 0x0003, 0x00CF, 0x03DA, 0x00CE, 0x0074, 0x0034, 0x0077, - 0x0793, 0x0013, 0x0076, 0x0071, 0x03C5, 0x0070, 0x01FF, 0x0792, 0x01FE, - 0x01F9, 0x0037, 0x00C9, 0x0F08, 0x01F8, 0x03C4, 0x00C8, 0x0F0B, 0x079D, - 0x03C7, 0x0001, 0x0012, 0x0073, 0x00CB, 0x0005, 0x0036, 0x03C6, 0x0072, - 0x007D, 0x0002, 0x00CA, 0x079C, 0x01FB, 0x00F5, 0x0031, 0x079F, 0x0F0A, - 0x0F35, 0x079E, 0x01FA, 0x1E6C, 0x1E6F, 0x3CD3, 0x0799, 0x03C1, 0x1E6E, - 0x3CD2, 0x0030, 0x00F4, 0x007C, 0x03C0, 0x03C3, 0x0798, 0x01E5, 0x00F7, }, -{ 0x01A5, 0x0001, 0x001D, 0x0021, 0x00A1, 0x000D, 0x0061, 0x06B9, 0x00A0, - 0x0060, 0x0001, 0x0005, 0x000C, 0x0020, 0x001C, 0x0004, 0x01A4, 0x01A7, - 0x00A3, 0x001F, 0x001E, 0x0023, 0x0022, 0x002D, 0x002C, 0x0063, 0x0062, - 0x1A81, 0x01A6, 0x01A1, 0x06B8, 0x06BB, 0x00A2, 0x06BA, 0x0D59, 0x06A5, - 0x01A0, 0x000F, 0x006D, 0x06A4, 0x002F, 0x00AD, 0x006C, 0x06A7, 0x00AC, - 0x0D58, 0x000E, 0x01A3, 0x00AF, 0x00AE, 0x006F, 0x01A2, 0x0D5B, 0x00A9, - 0x0019, 0x0001, 0x0009, 0x00A8, 0x006E, 0x002E, 0x0000, 0x01AD, 0x00AB, - 0x00AA, 0x0355, 0x0029, 0x1A80, 0x1A83, 0x1A82, 0x0354, 0x01AC, 0x0D5A, - 0x1A8D, 0x01AF, 0x0357, 0x0D45, 0x0D44, 0x0D47, 0x1A8C, 0x06A6, 0x06A1, }, -{ 0x0001, 0x0011, 0x0005, 0x0775, 0x00F9, 0x00F8, 0x0031, 0x0030, 0x0049, - 0x00FB, 0x0010, 0x0033, 0x0EC9, 0x038D, 0x038C, 0x00FA, 0x038F, 0x0774, - 0x0048, 0x0032, 0x0000, 0x01D5, 0x00E5, 0x038E, 0x00E4, 0x0013, 0x000D, - 0x0389, 0x0777, 0x0388, 0x038B, 0x1DF9, 0x0EC8, 0x3BC9, 0x1DF8, 0x038A, - 0x03B5, 0x0776, 0x00E7, 0x3BC8, 0x01D4, 0x3BCB, 0x0ECB, 0x0771, 0x0ECA, - 0x01D7, 0x03B4, 0x01D6, 0x1DFB, 0x0EF5, 0x0770, 0x0EF4, 0x3BCA, 0x0773, - 0x00E6, 0x03B7, 0x004B, 0x1DFA, 0x03B6, 0x0EF7, 0x00E1, 0x0EF6, 0x0EF1, - 0x03B1, 0x01D1, 0x003D, 0x0EF0, 0x0772, 0x077D, 0x077C, 0x003C, 0x01D0, - 0x03B0, 0x01D3, 0x003F, 0x03B3, 0x01D2, 0x0EF3, 0x077F, 0x00E0, 0x004A, }, -{ 0x0015, 0x0049, 0x0014, 0x07D1, 0x03FD, 0x03FC, 0x01C1, 0x01C0, 0x00F1, - 0x0017, 0x0001, 0x0001, 0x01C3, 0x0048, 0x004B, 0x0016, 0x0031, 0x01C2, - 0x004A, 0x0011, 0x0000, 0x01CD, 0x00F0, 0x01CC, 0x0075, 0x0010, 0x000D, - 0x03FF, 0x01CF, 0x01CE, 0x07D0, 0x0F81, 0x07D3, 0x1F1D, 0x0F80, 0x07D2, - 0x01C9, 0x03FE, 0x0074, 0x07DD, 0x00F3, 0x1F1C, 0x07DC, 0x03F9, 0x07DF, - 0x00F2, 0x00FD, 0x0077, 0x07DE, 0x07D9, 0x01C8, 0x07D8, 0x0F83, 0x03F8, - 0x0030, 0x0076, 0x0013, 0x0F82, 0x00FC, 0x03FB, 0x0033, 0x03FA, 0x03E5, - 0x03E4, 0x01CB, 0x0032, 0x1F1F, 0x03E7, 0x07DB, 0x07DA, 0x003D, 0x01CA, - 0x07C5, 0x03E6, 0x0071, 0x0F8D, 0x07C4, 0x1F1E, 0x0F8C, 0x03E1, 0x01F5, }, -{ 0x0019, 0x0065, 0x0018, 0x0351, 0x0350, 0x0353, 0x0021, 0x0020, 0x0064, - 0x001D, 0x0005, 0x0005, 0x01A5, 0x0023, 0x0067, 0x0005, 0x0066, 0x0022, - 0x001B, 0x0004, 0x0001, 0x0004, 0x001C, 0x0061, 0x001A, 0x0005, 0x0004, - 0x0007, 0x002D, 0x0006, 0x002C, 0x01A4, 0x002F, 0x0352, 0x035D, 0x0060, - 0x0001, 0x002E, 0x001F, 0x035C, 0x0000, 0x06B1, 0x01A7, 0x0029, 0x01A6, - 0x0028, 0x0063, 0x0062, 0x035F, 0x01A1, 0x002B, 0x06B0, 0x06B3, 0x01A0, - 0x0003, 0x006D, 0x001E, 0x035E, 0x006C, 0x06B2, 0x0002, 0x01A3, 0x01A2, - 0x000D, 0x0005, 0x0007, 0x01AD, 0x006F, 0x002A, 0x006E, 0x0004, 0x0004, - 0x000C, 0x0007, 0x0006, 0x000F, 0x000E, 0x00D5, 0x0009, 0x0006, 0x0007, }, -{ 0x0065, 0x0181, 0x0064, 0x36C9, 0x06D5, 0x0DB5, 0x0379, 0x0180, 0x0183, - 0x00D5, 0x001D, 0x001C, 0x0DB4, 0x0182, 0x0378, 0x00D4, 0x00D7, 0x06D4, - 0x0067, 0x001F, 0x0001, 0x00D6, 0x00D1, 0x018D, 0x0066, 0x0001, 0x0000, - 0x037B, 0x06D7, 0x037A, 0x0DB7, 0x36C8, 0x06D6, 0x0DB6, 0x1B79, 0x0DB1, - 0x018C, 0x0365, 0x00D0, 0x1B78, 0x00D3, 0x1B7B, 0x0364, 0x06D1, 0x06D0, - 0x018F, 0x018E, 0x00D2, 0x36CB, 0x0367, 0x0366, 0x06D3, 0x0DB0, 0x06D2, - 0x0361, 0x06DD, 0x0189, 0x36CA, 0x0360, 0x36F5, 0x0188, 0x0DB3, 0x36F4, - 0x0009, 0x0008, 0x0005, 0x06DC, 0x00DD, 0x018B, 0x00DC, 0x0004, 0x000B, - 0x018A, 0x0061, 0x0003, 0x0363, 0x00DF, 0x06DF, 0x0362, 0x000A, 0x001E, }, -{ 0x001D, 0x0061, 0x000D, 0x0D55, 0x06B9, 0x06B8, 0x01A5, 0x0021, 0x0020, - 0x0023, 0x000C, 0x0060, 0x0D54, 0x00AD, 0x00AC, 0x0022, 0x00AF, 0x06BB, - 0x000F, 0x001C, 0x0001, 0x002D, 0x0063, 0x01A4, 0x000E, 0x0001, 0x0005, - 0x01A7, 0x06BA, 0x01A6, 0x06A5, 0x0D57, 0x0D56, 0x1ABD, 0x0D51, 0x00AE, - 0x002C, 0x00A9, 0x002F, 0x0D50, 0x01A1, 0x1ABC, 0x06A4, 0x06A7, 0x06A6, - 0x00A8, 0x06A1, 0x01A0, 0x1ABF, 0x0D53, 0x06A0, 0x0D52, 0x1ABE, 0x06A3, - 0x0062, 0x002E, 0x0009, 0x0D5D, 0x01A3, 0x0D5C, 0x006D, 0x00AB, 0x06A2, - 0x006C, 0x001F, 0x0001, 0x06AD, 0x0029, 0x01A2, 0x0028, 0x0004, 0x001E, - 0x01AD, 0x006F, 0x0000, 0x01AC, 0x01AF, 0x06AC, 0x00AA, 0x006E, 0x0019, }, -{ 0x0019, 0x007D, 0x0018, 0x01B5, 0x000D, 0x01B4, 0x007C, 0x007F, 0x01B7, - 0x000C, 0x001B, 0x001A, 0x01B6, 0x000F, 0x00D5, 0x0019, 0x007E, 0x00D4, - 0x0018, 0x001B, 0x0001, 0x000E, 0x0011, 0x0009, 0x0005, 0x0005, 0x0005, - 0x00D7, 0x01B1, 0x0008, 0x01B0, 0x0079, 0x06FD, 0x0371, 0x0370, 0x00D6, - 0x0078, 0x01B3, 0x0010, 0x0373, 0x0013, 0x06FC, 0x007B, 0x007A, 0x00D1, - 0x00D0, 0x00D3, 0x0065, 0x0372, 0x06FF, 0x0064, 0x06FE, 0x037D, 0x00D2, - 0x00DD, 0x0067, 0x0004, 0x037C, 0x0012, 0x01B2, 0x0007, 0x0066, 0x01BD, - 0x0006, 0x0061, 0x0004, 0x01BC, 0x001A, 0x0060, 0x001D, 0x0004, 0x001C, - 0x0063, 0x0001, 0x0007, 0x000B, 0x0000, 0x0062, 0x000A, 0x0005, 0x0007, }, -{ 0x0069, 0x0045, 0x0068, 0x04BD, 0x0255, 0x04BC, 0x00E5, 0x00E4, 0x0031, - 0x0030, 0x0019, 0x0001, 0x0121, 0x00E7, 0x00E6, 0x0033, 0x00E1, 0x00E0, - 0x006B, 0x0018, 0x0001, 0x0044, 0x0032, 0x0047, 0x006A, 0x001B, 0x0005, - 0x003D, 0x0046, 0x0015, 0x0041, 0x0120, 0x0123, 0x04BF, 0x0122, 0x0040, - 0x003C, 0x00E3, 0x0014, 0x0254, 0x0043, 0x0975, 0x012D, 0x00E2, 0x00ED, - 0x0042, 0x00EC, 0x004D, 0x0257, 0x0256, 0x0251, 0x04BE, 0x0974, 0x0250, - 0x00EF, 0x00EE, 0x004C, 0x04B9, 0x012C, 0x04B8, 0x004F, 0x04BB, 0x0253, - 0x003F, 0x0017, 0x0001, 0x0252, 0x00E9, 0x00E8, 0x00EB, 0x0000, 0x0003, - 0x0016, 0x0002, 0x0004, 0x004E, 0x003E, 0x00EA, 0x0049, 0x000D, 0x0007, }, -{ 0x000D, 0x01BD, 0x000C, 0x0D31, 0x0D30, 0x0D33, 0x0359, 0x0358, 0x002D, - 0x0065, 0x001D, 0x001C, 0x0D32, 0x035B, 0x035A, 0x002C, 0x01BC, 0x0345, - 0x000F, 0x001F, 0x0001, 0x002F, 0x0064, 0x01BF, 0x0067, 0x0001, 0x0005, - 0x0066, 0x002E, 0x0061, 0x0029, 0x0695, 0x0694, 0x0697, 0x0696, 0x0060, - 0x01BE, 0x0D3D, 0x0028, 0x1A49, 0x0344, 0x1A48, 0x1A4B, 0x0D3C, 0x0691, - 0x002B, 0x01B9, 0x002A, 0x0D3F, 0x0690, 0x0347, 0x0D3E, 0x1A4A, 0x0346, - 0x00D5, 0x0341, 0x0063, 0x0D39, 0x0340, 0x0D38, 0x01B8, 0x0D3B, 0x0D3A, - 0x00D4, 0x0062, 0x0000, 0x0693, 0x01BB, 0x0343, 0x0342, 0x001E, 0x000E, - 0x006D, 0x0009, 0x0001, 0x006C, 0x00D7, 0x034D, 0x01BA, 0x0008, 0x0004, }, -{ 0x0075, 0x00CD, 0x0035, 0x03C1, 0x03C0, 0x07F9, 0x03C3, 0x1F8D, 0x00CC, - 0x0074, 0x0011, 0x0010, 0x03C2, 0x0FD9, 0x01F1, 0x00CF, 0x03CD, 0x00CE, - 0x0034, 0x0001, 0x0001, 0x0037, 0x00C9, 0x00C8, 0x0036, 0x0000, 0x0001, - 0x0FD8, 0x03CC, 0x00CB, 0x01F0, 0x07F8, 0x03CF, 0x07FB, 0x07FA, 0x00CA, - 0x01F3, 0x03CE, 0x00F5, 0x0FDB, 0x00F4, 0x07E5, 0x07E4, 0x07E7, 0x01F2, - 0x07E6, 0x03C9, 0x01FD, 0x0FDA, 0x1F8C, 0x07E1, 0x1F8F, 0x1F8E, 0x03C8, - 0x03CB, 0x0077, 0x0076, 0x0FC5, 0x03CA, 0x07E0, 0x00F7, 0x0FC4, 0x03F5, - 0x00F6, 0x01FC, 0x0003, 0x03F4, 0x0071, 0x03F7, 0x00F1, 0x0013, 0x0031, - 0x0030, 0x0070, 0x0005, 0x0012, 0x0073, 0x01FF, 0x0072, 0x007D, 0x0002, }, -{ 0x0061, 0x0055, 0x0060, 0x02C9, 0x02C8, 0x02CB, 0x0171, 0x00B5, 0x0054, - 0x0001, 0x0001, 0x0001, 0x0057, 0x0001, 0x0063, 0x001D, 0x0062, 0x0039, - 0x006D, 0x0000, 0x0005, 0x0038, 0x0056, 0x00B4, 0x006C, 0x0003, 0x001C, - 0x006F, 0x003B, 0x0002, 0x003A, 0x0170, 0x00B7, 0x0173, 0x0051, 0x006E, - 0x0025, 0x0050, 0x0069, 0x02CA, 0x0024, 0x0027, 0x0172, 0x00B6, 0x00B1, - 0x000D, 0x000C, 0x001F, 0x017D, 0x0026, 0x0068, 0x0053, 0x017C, 0x006B, - 0x001E, 0x000F, 0x0004, 0x017F, 0x006A, 0x02F5, 0x0019, 0x0021, 0x0052, - 0x02F4, 0x02F7, 0x0020, 0x0BCD, 0x05E5, 0x05E4, 0x0BCC, 0x0023, 0x00B0, - 0x02F6, 0x00B3, 0x0022, 0x02F1, 0x02F0, 0x0BCF, 0x0BCE, 0x017E, 0x005D, }, -{ 0x00BD, 0x0025, 0x01A1, 0x0159, 0x0299, 0x00BC, 0x0024, 0x0505, 0x0504, - 0x01A0, 0x0001, 0x001D, 0x006D, 0x001C, 0x0001, 0x0005, 0x0027, 0x01A3, - 0x0158, 0x001F, 0x001E, 0x01A2, 0x0026, 0x0021, 0x000D, 0x0020, 0x0023, - 0x0298, 0x006C, 0x0022, 0x00BF, 0x00BE, 0x01AD, 0x002D, 0x029B, 0x00B9, - 0x01AC, 0x00B8, 0x01AF, 0x029A, 0x006F, 0x015B, 0x006E, 0x0285, 0x0284, - 0x01AE, 0x0019, 0x002C, 0x01A9, 0x01A8, 0x000C, 0x000F, 0x015A, 0x00BB, - 0x000E, 0x0000, 0x0069, 0x01AB, 0x0018, 0x01AA, 0x0004, 0x0055, 0x00BA, - 0x0507, 0x0145, 0x0054, 0x0506, 0x00A5, 0x0501, 0x00A4, 0x0057, 0x0500, - 0x0A05, 0x0144, 0x00A7, 0x0287, 0x0286, 0x0503, 0x0147, 0x0A04, 0x0146, }, -{ 0x0759, 0x0041, 0x00E5, 0x03BD, 0x0E9D, 0x012D, 0x012C, 0x3A1D, 0x03BC, - 0x012F, 0x000D, 0x0040, 0x00E4, 0x03BF, 0x0043, 0x0042, 0x0758, 0x03BE, - 0x00E7, 0x0001, 0x0000, 0x003D, 0x00E6, 0x0015, 0x0014, 0x0017, 0x003C, - 0x743D, 0x012E, 0x03B9, 0x03B8, 0x0E9C, 0x03BB, 0x075B, 0x3A1C, 0x0E9F, - 0x0129, 0x00E1, 0x0128, 0x0E9E, 0x012B, 0x075A, 0x00E0, 0x0E99, 0x0745, - 0x3A1F, 0x03BA, 0x0744, 0x0E98, 0x1D0D, 0x03A5, 0x0E9B, 0x743C, 0x0E9A, - 0x012A, 0x004D, 0x00E3, 0x0E85, 0x01D5, 0x0E84, 0x004C, 0x0747, 0x1D0C, - 0x01D4, 0x003F, 0x0016, 0x0746, 0x03A4, 0x0741, 0x004F, 0x003E, 0x01D7, - 0x0740, 0x000C, 0x0011, 0x004E, 0x00E2, 0x00ED, 0x00EC, 0x0049, 0x0048, }, -}; - -static const uint8_t aic_mode2_vlc_bits[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { -{ 1, 5, 4, 10, 6, 8, 5, 8, 8, - 7, 5, 7, 11, 10, 9, 8, 13, 11, - 6, 7, 3, 9, 8, 10, 9, 8, 5, - 10, 9, 10, 10, 14, 12, 14, 14, 12, - 8, 9, 7, 12, 8, 14, 9, 9, 12, - 8, 9, 11, 11, 13, 9, 11, 14, 12, - 6, 7, 9, 13, 9, 12, 7, 10, 12, - 11, 12, 8, 15, 10, 15, 13, 7, 12, - 10, 10, 8, 10, 13, 13, 13, 11, 8, }, -{ 4, 6, 5, 11, 8, 10, 7, 11, 9, - 4, 1, 4, 9, 7, 7, 5, 9, 10, - 6, 7, 4, 9, 9, 10, 9, 9, 6, - 9, 10, 9, 10, 12, 12, 13, 12, 11, - 9, 9, 8, 12, 8, 14, 10, 11, 12, - 7, 8, 10, 11, 12, 9, 11, 13, 12, - 6, 7, 8, 12, 9, 12, 7, 11, 10, - 12, 12, 9, 14, 12, 15, 13, 8, 12, - 11, 11, 10, 12, 13, 15, 14, 12, 9, }, -{ 5, 7, 6, 12, 9, 11, 8, 11, 10, - 7, 5, 7, 11, 10, 9, 8, 12, 12, - 5, 5, 1, 8, 7, 10, 8, 6, 4, - 8, 8, 8, 9, 12, 11, 13, 12, 11, - 8, 9, 8, 12, 8, 13, 10, 11, 11, - 8, 9, 11, 12, 13, 11, 12, 14, 13, - 8, 9, 10, 14, 11, 14, 9, 13, 13, - 8, 9, 6, 11, 10, 14, 11, 6, 10, - 6, 6, 4, 8, 9, 10, 10, 8, 5, }, -{ 11, 7, 8, 10, 12, 9, 10, 14, 12, - 7, 1, 5, 7, 8, 6, 4, 10, 9, - 10, 5, 4, 8, 11, 8, 7, 6, 7, - 11, 6, 7, 8, 10, 8, 10, 11, 9, - 10, 8, 9, 13, 9, 12, 8, 11, 12, - 11, 4, 7, 8, 9, 6, 8, 12, 9, - 8, 5, 8, 12, 9, 10, 6, 12, 11, - 12, 12, 10, 15, 13, 13, 13, 10, 13, - 15, 10, 9, 10, 12, 13, 13, 10, 9, }, -{ 11, 8, 8, 11, 13, 10, 11, 15, 12, - 7, 1, 4, 7, 7, 5, 4, 8, 9, - 11, 5, 5, 8, 11, 9, 8, 7, 8, - 13, 7, 8, 9, 11, 9, 10, 12, 10, - 10, 9, 8, 13, 9, 12, 9, 11, 12, - 11, 5, 7, 9, 10, 6, 9, 13, 10, - 7, 4, 7, 11, 8, 9, 5, 10, 11, - 13, 11, 9, 15, 13, 15, 13, 8, 12, - 15, 10, 10, 12, 13, 14, 14, 12, 11, }, -{ 12, 9, 9, 12, 13, 11, 11, 14, 12, - 8, 2, 5, 7, 9, 6, 5, 10, 10, - 9, 4, 2, 7, 9, 7, 6, 5, 6, - 12, 6, 7, 8, 10, 8, 10, 11, 9, - 12, 9, 10, 13, 11, 12, 10, 14, 13, - 12, 6, 8, 10, 10, 7, 9, 12, 10, - 8, 5, 8, 11, 9, 10, 7, 11, 12, - 8, 6, 5, 11, 11, 11, 8, 6, 9, - 12, 6, 6, 8, 10, 10, 11, 8, 6, }, -{ 13, 9, 10, 12, 14, 12, 11, 15, 15, - 8, 1, 5, 7, 9, 6, 5, 11, 10, - 11, 6, 5, 9, 11, 9, 8, 7, 8, - 12, 6, 8, 8, 11, 8, 10, 12, 10, - 10, 7, 9, 13, 10, 11, 9, 13, 12, - 11, 3, 6, 8, 9, 4, 7, 11, 8, - 8, 5, 9, 12, 10, 9, 7, 12, 13, - 13, 12, 10, 14, 14, 15, 12, 11, 14, - 15, 7, 9, 8, 11, 11, 12, 10, 9, }, -{ 10, 5, 6, 9, 11, 7, 8, 12, 11, - 8, 1, 4, 7, 9, 6, 4, 10, 10, - 11, 6, 6, 9, 9, 9, 9, 8, 8, - 14, 10, 10, 12, 12, 11, 12, 13, 12, - 10, 7, 8, 12, 9, 11, 8, 12, 11, - 13, 7, 10, 11, 11, 8, 10, 13, 11, - 6, 3, 7, 11, 8, 9, 5, 10, 11, - 11, 11, 9, 14, 14, 14, 11, 10, 13, - 14, 10, 11, 13, 13, 13, 14, 12, 12, }, -{ 2, 5, 3, 11, 8, 8, 6, 6, 7, - 8, 5, 6, 12, 10, 10, 8, 10, 11, - 7, 6, 2, 9, 8, 10, 8, 5, 4, - 10, 11, 10, 10, 13, 12, 14, 13, 10, - 10, 11, 8, 14, 9, 14, 12, 11, 12, - 9, 10, 9, 13, 12, 11, 12, 14, 11, - 8, 10, 7, 13, 10, 12, 8, 12, 12, - 10, 9, 6, 12, 11, 11, 11, 6, 9, - 10, 9, 6, 10, 9, 12, 11, 8, 7, }, -{ 6, 8, 6, 12, 11, 11, 10, 10, 9, - 6, 1, 3, 10, 8, 8, 6, 7, 10, - 8, 6, 3, 10, 9, 10, 8, 6, 5, - 11, 10, 10, 12, 13, 12, 14, 13, 12, - 10, 11, 8, 12, 9, 14, 12, 11, 12, - 9, 9, 8, 12, 12, 10, 12, 13, 11, - 7, 8, 6, 13, 9, 11, 7, 11, 11, - 11, 10, 7, 14, 11, 12, 12, 7, 10, - 12, 11, 8, 13, 12, 14, 13, 11, 10, }, -{ 7, 10, 7, 13, 13, 13, 11, 11, 10, - 8, 5, 6, 12, 11, 10, 9, 10, 11, - 7, 5, 1, 9, 8, 10, 7, 4, 4, - 9, 11, 9, 11, 12, 11, 13, 13, 10, - 9, 11, 8, 13, 9, 14, 12, 11, 12, - 11, 10, 10, 13, 12, 11, 14, 14, 12, - 9, 10, 8, 13, 10, 14, 9, 12, 12, - 9, 7, 4, 12, 10, 11, 10, 6, 7, - 9, 7, 4, 9, 9, 11, 9, 7, 5, }, -{ 7, 9, 7, 14, 11, 12, 10, 9, 9, - 8, 5, 5, 12, 9, 10, 8, 8, 11, - 7, 5, 2, 8, 8, 9, 7, 4, 4, - 10, 11, 10, 12, 14, 11, 12, 13, 12, - 9, 10, 8, 13, 8, 13, 10, 11, 11, - 9, 9, 8, 14, 10, 10, 11, 12, 11, - 10, 11, 9, 14, 10, 14, 9, 12, 14, - 6, 6, 3, 11, 8, 9, 8, 3, 6, - 9, 7, 4, 10, 8, 11, 10, 6, 5, }, -{ 6, 8, 7, 13, 12, 12, 10, 9, 9, - 9, 7, 8, 13, 11, 11, 9, 11, 12, - 7, 6, 1, 9, 8, 10, 7, 5, 4, - 10, 12, 10, 12, 13, 13, 14, 13, 11, - 9, 11, 9, 13, 10, 14, 12, 12, 12, - 11, 12, 10, 14, 13, 12, 13, 14, 12, - 8, 9, 7, 13, 10, 13, 8, 11, 12, - 8, 6, 3, 12, 9, 10, 9, 4, 6, - 10, 8, 5, 10, 10, 12, 11, 8, 6, }, -{ 7, 10, 7, 12, 9, 12, 10, 10, 12, - 9, 7, 7, 12, 9, 11, 6, 10, 11, - 6, 6, 1, 9, 8, 9, 7, 4, 5, - 11, 12, 9, 12, 10, 14, 13, 13, 11, - 10, 12, 8, 13, 8, 14, 10, 10, 11, - 11, 11, 10, 13, 14, 10, 14, 13, 11, - 11, 10, 7, 13, 8, 12, 7, 10, 12, - 7, 10, 4, 12, 6, 10, 8, 5, 8, - 10, 7, 4, 9, 7, 10, 9, 6, 5, }, -{ 7, 9, 7, 13, 12, 13, 10, 10, 8, - 8, 5, 6, 11, 10, 10, 8, 10, 10, - 7, 5, 2, 9, 8, 9, 7, 5, 3, - 8, 9, 7, 9, 11, 11, 13, 11, 9, - 8, 10, 7, 12, 9, 14, 11, 10, 10, - 9, 10, 9, 12, 12, 12, 13, 14, 12, - 10, 10, 9, 13, 11, 13, 9, 13, 12, - 8, 7, 4, 12, 10, 10, 10, 6, 6, - 7, 6, 3, 9, 8, 10, 9, 6, 3, }, -{ 7, 10, 7, 13, 13, 13, 11, 11, 9, - 8, 6, 6, 13, 11, 11, 9, 10, 11, - 7, 6, 1, 9, 8, 10, 8, 5, 4, - 8, 9, 8, 9, 12, 12, 12, 12, 8, - 10, 13, 9, 14, 11, 14, 14, 13, 12, - 9, 10, 9, 13, 12, 11, 13, 14, 11, - 9, 11, 8, 13, 11, 13, 10, 13, 13, - 9, 8, 5, 12, 10, 11, 11, 6, 7, - 8, 7, 3, 8, 9, 11, 10, 7, 4, }, -{ 8, 9, 7, 11, 11, 12, 11, 14, 9, - 8, 6, 6, 11, 13, 10, 9, 11, 9, - 7, 5, 1, 7, 9, 9, 7, 5, 3, - 13, 11, 9, 10, 12, 11, 12, 12, 9, - 10, 11, 9, 13, 9, 12, 12, 12, 10, - 12, 11, 10, 13, 14, 12, 14, 14, 11, - 11, 8, 8, 13, 11, 12, 9, 13, 11, - 9, 10, 5, 11, 8, 11, 9, 6, 7, - 7, 8, 4, 6, 8, 10, 8, 8, 5, }, -{ 8, 10, 8, 13, 13, 13, 12, 11, 10, - 5, 1, 3, 10, 7, 8, 6, 8, 9, - 8, 7, 4, 9, 10, 11, 8, 7, 6, - 8, 9, 7, 9, 12, 11, 12, 10, 8, - 9, 10, 8, 13, 9, 9, 12, 11, 11, - 7, 7, 6, 12, 9, 8, 10, 12, 8, - 6, 7, 4, 12, 8, 13, 6, 9, 10, - 13, 13, 9, 15, 14, 14, 15, 9, 11, - 13, 11, 9, 13, 13, 15, 15, 12, 10, }, -{ 10, 8, 9, 11, 12, 10, 8, 13, 13, - 9, 2, 5, 7, 5, 4, 3, 8, 9, - 11, 5, 5, 9, 8, 8, 6, 8, 8, - 12, 7, 8, 10, 10, 9, 8, 12, 10, - 9, 10, 9, 12, 7, 11, 7, 12, 12, - 9, 5, 8, 9, 9, 6, 6, 11, 10, - 6, 4, 7, 9, 5, 9, 3, 9, 10, - 13, 11, 9, 13, 10, 13, 10, 9, 13, - 14, 11, 10, 12, 12, 13, 11, 14, 11, }, -{ 11, 7, 8, 10, 12, 9, 9, 14, 10, - 9, 4, 7, 8, 10, 7, 7, 11, 10, - 8, 2, 2, 6, 8, 5, 5, 5, 6, - 15, 9, 10, 10, 12, 10, 11, 14, 12, - 9, 8, 9, 12, 9, 11, 8, 12, 11, - 14, 10, 11, 12, 13, 10, 12, 15, 12, - 9, 7, 8, 12, 9, 12, 7, 11, 13, - 9, 6, 5, 11, 10, 11, 7, 6, 9, - 11, 4, 5, 7, 8, 8, 8, 7, 7, }, -}; -//@} - -/** - * Codes used for determining block type - */ -//@{ -#define AIC_MODE1_NUM 90 -#define AIC_MODE1_SIZE 9 -#define AIC_MODE1_BITS 7 - -static const uint8_t aic_mode1_vlc_codes[AIC_MODE1_NUM][AIC_MODE1_SIZE] = { - { 0x01, 0x01, 0x01, 0x11, 0x00, 0x09, 0x03, 0x10, 0x05,}, - { 0x09, 0x01, 0x01, 0x05, 0x11, 0x00, 0x03, 0x21, 0x20,}, - { 0x01, 0x01, 0x01, 0x11, 0x09, 0x10, 0x05, 0x00, 0x03,}, - { 0x01, 0x01, 0x00, 0x03, 0x21, 0x05, 0x09, 0x20, 0x11,}, - { 0x01, 0x09, 0x00, 0x29, 0x08, 0x15, 0x03, 0x0B, 0x28,}, - { 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x02,}, - { 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x01, 0x09, 0x08,}, - { 0x01, 0x01, 0x01, 0x09, 0x01, 0x08, 0x00, 0x03, 0x05,}, - { 0x01, 0x01, 0x01, 0x00, 0x05, 0x11, 0x09, 0x10, 0x03,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x00, 0x03, 0x09, 0x08,}, - { 0x09, 0x01, 0x01, 0x05, 0x11, 0x00, 0x03, 0x21, 0x20,}, - { 0x01, 0x01, 0x01, 0x0D, 0x05, 0x04, 0x00, 0x07, 0x0C,}, - { 0x01, 0x01, 0x00, 0x05, 0x11, 0x03, 0x09, 0x21, 0x20,}, - { 0x05, 0x01, 0x01, 0x11, 0x00, 0x09, 0x03, 0x21, 0x20,}, - { 0x09, 0x01, 0x01, 0x00, 0x05, 0x01, 0x03, 0x11, 0x10,}, - { 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x02,}, - { 0x01, 0x01, 0x01, 0x09, 0x00, 0x05, 0x01, 0x03, 0x08,}, - { 0x01, 0x01, 0x01, 0x09, 0x11, 0x05, 0x00, 0x10, 0x03,}, - { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x00, 0x01, 0x09, 0x08, 0x15, 0x14, 0x0B, 0x03,}, - { 0x0D, 0x01, 0x01, 0x05, 0x0C, 0x04, 0x01, 0x00, 0x07,}, - { 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x03, 0x01, 0x01,}, - { 0x05, 0x01, 0x01, 0x04, 0x19, 0x07, 0x18, 0x0D, 0x00,}, - { 0x11, 0x09, 0x01, 0x21, 0x05, 0x20, 0x01, 0x00, 0x03,}, - { 0x41, 0x01, 0x00, 0x05, 0x40, 0x03, 0x09, 0x21, 0x11,}, - { 0x29, 0x01, 0x00, 0x28, 0x09, 0x15, 0x03, 0x08, 0x0B,}, - { 0x01, 0x00, 0x01, 0x11, 0x09, 0x10, 0x05, 0x01, 0x03,}, - { 0x05, 0x01, 0x01, 0x04, 0x0D, 0x0C, 0x07, 0x00, 0x01,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x00, 0x03, 0x05, 0x11, 0x10, 0x25, 0x24, 0x13,}, - { 0x21, 0x01, 0x01, 0x00, 0x11, 0x03, 0x05, 0x20, 0x09,}, - { 0x01, 0x01, 0x01, 0x00, 0x09, 0x11, 0x10, 0x05, 0x03,}, - { 0x21, 0x05, 0x01, 0x01, 0x09, 0x00, 0x11, 0x20, 0x03,}, - { 0x05, 0x01, 0x00, 0x04, 0x01, 0x19, 0x07, 0x18, 0x0D,}, - { 0x11, 0x01, 0x00, 0x01, 0x09, 0x01, 0x03, 0x10, 0x05,}, - { 0x1D, 0x01, 0x05, 0x0D, 0x0C, 0x04, 0x00, 0x1C, 0x0F,}, - { 0x05, 0x19, 0x01, 0x04, 0x00, 0x18, 0x1B, 0x1A, 0x07,}, - { 0x09, 0x01, 0x00, 0x01, 0x05, 0x03, 0x11, 0x10, 0x01,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x00, 0x03, 0x41, 0x05, 0x40, 0x09, 0x11, 0x21,}, - { 0x05, 0x01, 0x01, 0x19, 0x04, 0x07, 0x00, 0x18, 0x0D,}, - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x01, 0x00, 0x03,}, - { 0x01, 0x05, 0x00, 0x0D, 0x01, 0x04, 0x07, 0x19, 0x18,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x31, 0x01, 0x05, 0x19, 0x04, 0x07, 0x00, 0x30, 0x0D,}, - { 0x01, 0x00, 0x03, 0x11, 0x01, 0x05, 0x01, 0x09, 0x10,}, - { 0x01, 0x05, 0x01, 0x11, 0x01, 0x10, 0x00, 0x03, 0x09,}, - { 0x01, 0x09, 0x00, 0x29, 0x03, 0x08, 0x28, 0x15, 0x0B,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x00, 0x09, 0x15, 0x03, 0x08, 0x14, 0x0B,}, - { 0x11, 0x01, 0x01, 0x00, 0x09, 0x01, 0x03, 0x10, 0x05,}, - { 0x01, 0x00, 0x03, 0x25, 0x11, 0x05, 0x10, 0x24, 0x13,}, - { 0x11, 0x01, 0x00, 0x01, 0x09, 0x01, 0x05, 0x10, 0x03,}, - { 0x05, 0x01, 0x00, 0x0D, 0x0C, 0x04, 0x0F, 0x1D, 0x1C,}, - { 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x02,}, - { 0x21, 0x01, 0x05, 0x09, 0x11, 0x00, 0x03, 0x41, 0x40,}, - { 0x05, 0x01, 0x00, 0x1D, 0x1C, 0x0D, 0x0C, 0x0F, 0x04,}, - { 0x05, 0x01, 0x00, 0x0D, 0x31, 0x04, 0x19, 0x30, 0x07,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x00, 0x21, 0x05, 0x11, 0x03, 0x09, 0x20,}, - { 0x01, 0x01, 0x00, 0x11, 0x03, 0x05, 0x01, 0x09, 0x10,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x05, 0x01, 0x04, 0x19, 0x07, 0x0D, 0x00, 0x31, 0x30,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x05, 0x01, 0x01, 0x11, 0x09, 0x00, 0x03, 0x21, 0x20,}, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, - { 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x01, 0x01, 0x02,}, - { 0x09, 0x01, 0x00, 0x29, 0x08, 0x15, 0x03, 0x28, 0x0B,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x00, 0x01, 0x03,}, - { 0x09, 0x01, 0x00, 0x29, 0x28, 0x15, 0x08, 0x03, 0x0B,}, - { 0x01, 0x00, 0x01, 0x11, 0x05, 0x10, 0x09, 0x01, 0x03,}, - { 0x05, 0x04, 0x01, 0x1D, 0x0D, 0x0C, 0x1C, 0x00, 0x0F,}, - { 0x09, 0x11, 0x01, 0x41, 0x00, 0x40, 0x05, 0x03, 0x21,}, - { 0x0D, 0x05, 0x01, 0x1D, 0x1C, 0x0C, 0x04, 0x00, 0x0F,}, - { 0x41, 0x09, 0x01, 0x40, 0x00, 0x11, 0x05, 0x03, 0x21,}, - { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x00, 0x01, 0x03,}, - { 0x05, 0x04, 0x01, 0x0D, 0x01, 0x0C, 0x07, 0x01, 0x00,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, - - { 0x05, 0x04, 0x01, 0x07, 0x19, 0x31, 0x30, 0x0D, 0x00,}, - { 0x21, 0x01, 0x01, 0x00, 0x11, 0x09, 0x20, 0x05, 0x03,}, - { 0x05, 0x01, 0x01, 0x04, 0x07, 0x0D, 0x0C, 0x00, 0x01,}, - { 0x21, 0x09, 0x01, 0x00, 0x20, 0x05, 0x23, 0x22, 0x03,}, - { 0x31, 0x0D, 0x01, 0x19, 0x05, 0x30, 0x04, 0x07, 0x00,}, - { 0x31, 0x05, 0x01, 0x04, 0x19, 0x00, 0x0D, 0x30, 0x07,}, - { 0x31, 0x01, 0x00, 0x0D, 0x05, 0x19, 0x04, 0x30, 0x07,}, - { 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01,}, - { 0x01, 0x00, 0x01, 0x01, 0x05, 0x09, 0x08, 0x03, 0x01,}, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, -}; - -static const uint8_t aic_mode1_vlc_bits[AIC_MODE1_NUM][AIC_MODE1_SIZE] = { - { 1, 4, 2, 7, 4, 6, 4, 7, 5,}, - { 5, 1, 3, 4, 6, 3, 3, 7, 7,}, - { 1, 4, 2, 7, 6, 7, 5, 4, 4,}, - { 1, 3, 3, 3, 7, 4, 5, 7, 6,}, - { 2, 4, 2, 6, 4, 5, 2, 4, 6,}, - { 7, 2, 3, 4, 7, 1, 5, 7, 7,}, - { 5, 1, 3, 6, 5, 5, 2, 7, 7,}, - { 2, 5, 1, 7, 3, 7, 5, 5, 6,}, - { 2, 4, 1, 4, 5, 7, 6, 7, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 2, 1, 3, 6, 5, 5, 5, 7, 7,}, - { 5, 1, 3, 4, 6, 3, 3, 7, 7,}, - { 4, 1, 2, 6, 5, 5, 4, 5, 6,}, - { 3, 1, 3, 4, 6, 3, 5, 7, 7,}, - { 4, 1, 3, 6, 3, 5, 3, 7, 7,}, - { 6, 1, 4, 4, 5, 2, 4, 7, 7,}, - { 7, 1, 5, 7, 4, 3, 2, 7, 7,}, - { 5, 3, 2, 7, 5, 6, 1, 5, 7,}, - { 4, 1, 2, 6, 7, 5, 4, 7, 4,}, - { 1, 0, 1, 0, 0, 0, 0, 0, 0,}, - - { 3, 3, 1, 5, 5, 6, 6, 5, 3,}, - { 6, 2, 1, 5, 6, 5, 4, 4, 5,}, - { 6, 4, 1, 7, 6, 7, 6, 3, 2,}, - { 4, 3, 1, 4, 6, 4, 6, 5, 3,}, - { 6, 5, 1, 7, 4, 7, 3, 3, 3,}, - { 7, 2, 2, 3, 7, 2, 4, 6, 5,}, - { 6, 2, 2, 6, 4, 5, 2, 4, 4,}, - { 4, 4, 1, 7, 6, 7, 5, 2, 4,}, - { 5, 4, 1, 5, 6, 6, 5, 4, 2,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 2, 2, 2, 3, 5, 5, 6, 6, 5,}, - { 7, 1, 3, 3, 6, 3, 4, 7, 5,}, - { 2, 4, 1, 4, 6, 7, 7, 5, 4,}, - { 7, 4, 3, 1, 5, 3, 6, 7, 3,}, - { 4, 3, 3, 4, 1, 6, 4, 6, 5,}, - { 7, 4, 4, 2, 6, 1, 4, 7, 5,}, - { 5, 2, 3, 4, 4, 3, 2, 5, 4,}, - { 3, 5, 2, 3, 2, 5, 5, 5, 3,}, - { 6, 4, 4, 2, 5, 4, 7, 7, 1,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 2, 2, 2, 7, 3, 7, 4, 5, 6,}, - { 4, 1, 3, 6, 4, 4, 3, 6, 5,}, - { 2, 4, 1, 7, 3, 7, 6, 6, 6,}, - { 3, 4, 3, 5, 1, 4, 4, 6, 6,}, - { 4, 5, 2, 7, 1, 7, 3, 7, 7,}, - { 6, 2, 3, 5, 3, 3, 2, 6, 4,}, - { 4, 4, 4, 7, 2, 5, 1, 6, 7,}, - { 4, 5, 2, 7, 1, 7, 4, 4, 6,}, - { 2, 4, 2, 6, 2, 4, 6, 5, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 1, 3, 3, 5, 6, 3, 5, 6, 5,}, - { 7, 1, 4, 4, 6, 2, 4, 7, 5,}, - { 2, 2, 2, 6, 5, 3, 5, 6, 5,}, - { 7, 4, 4, 2, 6, 1, 5, 7, 4,}, - { 3, 2, 2, 4, 4, 3, 4, 5, 5,}, - { 7, 2, 5, 3, 7, 1, 4, 7, 7,}, - { 6, 2, 3, 4, 5, 2, 2, 7, 7,}, - { 3, 2, 2, 5, 5, 4, 4, 4, 3,}, - { 3, 2, 2, 4, 6, 3, 5, 6, 3,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 1, 3, 3, 7, 4, 6, 3, 5, 7,}, - { 4, 1, 4, 7, 4, 5, 2, 6, 7,}, - { 2, 4, 1, 7, 5, 7, 3, 7, 7,}, - { 3, 2, 3, 5, 3, 4, 2, 6, 6,}, - { 3, 5, 4, 7, 2, 7, 1, 7, 7,}, - { 4, 1, 3, 6, 5, 3, 3, 7, 7,}, - { 4, 2, 5, 7, 3, 7, 1, 7, 7,}, - { 7, 4, 1, 7, 3, 7, 2, 5, 7,}, - { 4, 2, 2, 6, 4, 5, 2, 6, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 3, 4, 1, 7, 6, 7, 6, 2, 6,}, - { 4, 2, 2, 6, 6, 5, 4, 2, 4,}, - { 4, 4, 1, 7, 5, 7, 6, 2, 4,}, - { 3, 3, 2, 5, 4, 4, 5, 2, 4,}, - { 4, 5, 2, 7, 2, 7, 3, 2, 6,}, - { 4, 3, 2, 5, 5, 4, 3, 2, 4,}, - { 7, 4, 2, 7, 2, 5, 3, 2, 6,}, - { 4, 6, 2, 7, 3, 7, 6, 1, 6,}, - { 5, 5, 1, 6, 4, 6, 5, 2, 4,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, - - { 3, 3, 2, 3, 5, 6, 6, 4, 2,}, - { 7, 1, 3, 3, 6, 5, 7, 4, 3,}, - { 5, 4, 1, 5, 5, 6, 6, 4, 2,}, - { 6, 4, 2, 2, 6, 3, 6, 6, 2,}, - { 6, 4, 2, 5, 3, 6, 3, 3, 2,}, - { 6, 3, 2, 3, 5, 2, 4, 6, 3,}, - { 6, 2, 2, 4, 3, 5, 3, 6, 3,}, - { 7, 5, 1, 7, 4, 7, 7, 3, 2,}, - { 5, 5, 2, 3, 6, 7, 7, 5, 1,}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, -}; - -//@} - -#define PBTYPE_ESCAPE 0xFF - -/** tables used for P-frame macroblock type decoding */ -//@{ -#define NUM_PTYPE_VLCS 7 -#define PTYPE_VLC_SIZE 8 -#define PTYPE_VLC_BITS 7 - -static const uint8_t ptype_vlc_codes[NUM_PTYPE_VLCS][PTYPE_VLC_SIZE] = { - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x0D, 0x05, 0x01, 0x04, 0x01, 0x00, 0x07, 0x0C }, - { 0x09, 0x11, 0x01, 0x00, 0x05, 0x03, 0x21, 0x20 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 } -}; - -static const uint8_t ptype_vlc_bits[NUM_PTYPE_VLCS][PTYPE_VLC_SIZE] = { - { 1, 2, 3, 6, 5, 4, 7, 7 }, - { 3, 1, 2, 7, 6, 5, 4, 7 }, - { 5, 4, 1, 4, 3, 3, 4, 5 }, - { 4, 5, 2, 2, 3, 2, 6, 6 }, - { 5, 6, 1, 4, 2, 3, 7, 7 }, - { 5, 6, 1, 4, 3, 2, 7, 7 }, - { 6, 3, 2, 7, 5, 4, 1, 7 } -}; - -static const uint8_t ptype_vlc_syms[PTYPE_VLC_SIZE] = { - 0, 1, 2, 3, 8, 9, 11, PBTYPE_ESCAPE -}; - -/** reverse of ptype_vlc_syms */ -static const uint8_t block_num_to_ptype_vlc_num[12] = { - 0, 1, 2, 3, 0, 0, 2, 0, 4, 5, 0, 6 -}; -//@} - -/** tables used for P-frame macroblock type decoding */ -//@{ -#define NUM_BTYPE_VLCS 6 -#define BTYPE_VLC_SIZE 7 -#define BTYPE_VLC_BITS 6 - -static const uint8_t btype_vlc_codes[NUM_BTYPE_VLCS][BTYPE_VLC_SIZE] = { - { 0x01, 0x05, 0x00, 0x03, 0x11, 0x09, 0x10 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x09, 0x01, 0x00, 0x01, 0x05, 0x03, 0x08 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 } -}; - -static const uint8_t btype_vlc_bits[NUM_BTYPE_VLCS][PTYPE_VLC_SIZE] = { - { 2, 3, 2, 2, 5, 4, 5 }, - { 4, 1, 3, 2, 6, 5, 6 }, - { 6, 4, 1, 2, 5, 3, 6 }, - { 5, 3, 3, 1, 4, 3, 5 }, - { 6, 5, 3, 2, 4, 1, 6 }, - { 6, 5, 3, 1, 4, 2, 6 } -}; - -static const uint8_t btype_vlc_syms[BTYPE_VLC_SIZE] = { - 0, 1, 4, 5, 10, 7, PBTYPE_ESCAPE -}; - -/** reverse of btype_vlc_syms */ -static const uint8_t block_num_to_btype_vlc_num[12] = { - 0, 1, 0, 0, 2, 3, 0, 5, 0, 0, 4, 0 -}; -//@} -#endif /* AVCODEC_RV40VLC2_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/s3tc.c b/tizen/distrib/ffmpeg/libavcodec/s3tc.c deleted file mode 100644 index 546ee21..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/s3tc.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * S3 Texture Compression (S3TC) decoding functions - * Copyright (c) 2007 by Ivo van Poorten - * - * see also: http://wiki.multimedia.cx/index.php?title=S3TC - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "s3tc.h" - -static inline void dxt1_decode_pixels(const uint8_t *s, uint32_t *d, - unsigned int qstride, unsigned int flag, - uint64_t alpha) { - unsigned int x, y, c0, c1, a = (!flag * 255) << 24; - unsigned int rb0, rb1, rb2, rb3, g0, g1, g2, g3; - uint32_t colors[4], pixels; - - c0 = AV_RL16(s); - c1 = AV_RL16(s+2); - - rb0 = (c0<<3 | c0<<8) & 0xf800f8; - rb1 = (c1<<3 | c1<<8) & 0xf800f8; - rb0 += (rb0>>5) & 0x070007; - rb1 += (rb1>>5) & 0x070007; - g0 = (c0 <<5) & 0x00fc00; - g1 = (c1 <<5) & 0x00fc00; - g0 += (g0 >>6) & 0x000300; - g1 += (g1 >>6) & 0x000300; - - colors[0] = rb0 + g0 + a; - colors[1] = rb1 + g1 + a; - - if (c0 > c1 || flag) { - rb2 = (((2*rb0+rb1) * 21) >> 6) & 0xff00ff; - rb3 = (((2*rb1+rb0) * 21) >> 6) & 0xff00ff; - g2 = (((2*g0 +g1 ) * 21) >> 6) & 0x00ff00; - g3 = (((2*g1 +g0 ) * 21) >> 6) & 0x00ff00; - colors[3] = rb3 + g3 + a; - } else { - rb2 = ((rb0+rb1) >> 1) & 0xff00ff; - g2 = ((g0 +g1 ) >> 1) & 0x00ff00; - colors[3] = 0; - } - - colors[2] = rb2 + g2 + a; - - pixels = AV_RL32(s+4); - for (y=0; y<4; y++) { - for (x=0; x<4; x++) { - a = (alpha & 0x0f) << 28; - a += a >> 4; - d[x] = a + colors[pixels&3]; - pixels >>= 2; - alpha >>= 4; - } - d += qstride; - } -} - -void ff_decode_dxt1(const uint8_t *s, uint8_t *dst, - const unsigned int w, const unsigned int h, - const unsigned int stride) { - unsigned int bx, by, qstride = stride/4; - uint32_t *d = (uint32_t *) dst; - - for (by=0; by < h/4; by++, d += stride-w) - for (bx=0; bx < w/4; bx++, s+=8, d+=4) - dxt1_decode_pixels(s, d, qstride, 0, 0LL); -} - -void ff_decode_dxt3(const uint8_t *s, uint8_t *dst, - const unsigned int w, const unsigned int h, - const unsigned int stride) { - unsigned int bx, by, qstride = stride/4; - uint32_t *d = (uint32_t *) dst; - - for (by=0; by < h/4; by++, d += stride-w) - for (bx=0; bx < w/4; bx++, s+=16, d+=4) - dxt1_decode_pixels(s+8, d, qstride, 1, AV_RL64(s)); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/s3tc.h b/tizen/distrib/ffmpeg/libavcodec/s3tc.h deleted file mode 100644 index 4919c07..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/s3tc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * S3 Texture Compression (S3TC) decoding functions - * Copyright (c) 2007 by Ivo van Poorten - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_S3TC_H -#define AVCODEC_S3TC_H - -#include - -#define FF_S3TC_DXT1 0x31545844 -#define FF_S3TC_DXT3 0x33545844 - -/** - * Decode DXT1 encoded data to RGB32 - * @param *src source buffer, has to be aligned on a 4-byte boundary - * @param *dst destination buffer - * @param w width of output image - * @param h height of output image - * @param stride line size of output image - */ -void ff_decode_dxt1(const uint8_t *src, uint8_t *dst, - const unsigned int w, const unsigned int h, - const unsigned int stride); -/** - * Decode DXT3 encoded data to RGB32 - * @param *src source buffer, has to be aligned on a 4-byte boundary - * @param *dst destination buffer - * @param w width of output image - * @param h height of output image - * @param stride line size of output image - */ -void ff_decode_dxt3(const uint8_t *src, uint8_t *dst, - const unsigned int w, const unsigned int h, - const unsigned int stride); - -#endif /* AVCODEC_S3TC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sbr.h b/tizen/distrib/ffmpeg/libavcodec/sbr.h deleted file mode 100644 index 2d9f4a5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sbr.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Spectral Band Replication definitions and structures - * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) - * Copyright (c) 2010 Alex Converse - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Spectral Band Replication definitions and structures - * @author Robert Swain ( rob opendot cl ) - */ - -#ifndef AVCODEC_SBR_H -#define AVCODEC_SBR_H - -#include -#include "fft.h" - -/** - * Spectral Band Replication header - spectrum parameters that invoke a reset if they differ from the previous header. - */ -typedef struct { - uint8_t bs_start_freq; - uint8_t bs_stop_freq; - uint8_t bs_xover_band; - - /** - * @defgroup bs_header_extra_1 Variables associated with bs_header_extra_1 - * @{ - */ - uint8_t bs_freq_scale; - uint8_t bs_alter_scale; - uint8_t bs_noise_bands; - /** @} */ -} SpectrumParameters; - -#define SBR_SYNTHESIS_BUF_SIZE ((1280-128)*2) - -/** - * Spectral Band Replication per channel data - */ -typedef struct { - /** - * @defgroup bitstream Main bitstream data variables - * @{ - */ - unsigned bs_frame_class; - unsigned bs_add_harmonic_flag; - unsigned bs_num_env; - uint8_t bs_freq_res[7]; - unsigned bs_num_noise; - uint8_t bs_df_env[5]; - uint8_t bs_df_noise[2]; - uint8_t bs_invf_mode[2][5]; - uint8_t bs_add_harmonic[48]; - unsigned bs_amp_res; - /** @} */ - - /** - * @defgroup state State variables - * @{ - */ - DECLARE_ALIGNED(16, float, synthesis_filterbank_samples)[SBR_SYNTHESIS_BUF_SIZE]; - DECLARE_ALIGNED(16, float, analysis_filterbank_samples) [1312]; - int synthesis_filterbank_samples_offset; - ///l_APrev and l_A - int e_a[2]; - ///Chirp factors - float bw_array[5]; - ///QMF values of the original signal - float W[2][32][32][2]; - ///QMF output of the HF adjustor - float Y[2][38][64][2]; - float g_temp[42][48]; - float q_temp[42][48]; - uint8_t s_indexmapped[8][48]; - ///Envelope scalefactors - float env_facs[6][48]; - ///Noise scalefactors - float noise_facs[3][5]; - ///Envelope time borders - uint8_t t_env[8]; - ///Envelope time border of the last envelope of the previous frame - uint8_t t_env_num_env_old; - ///Noise time borders - uint8_t t_q[3]; - unsigned f_indexnoise; - unsigned f_indexsine; - /** @} */ -} SBRData; - -/** - * Spectral Band Replication - */ -typedef struct { - int sample_rate; - int start; - int reset; - SpectrumParameters spectrum_params; - int bs_amp_res_header; - /** - * @defgroup bs_header_extra_2 variables associated with bs_header_extra_2 - * @{ - */ - unsigned bs_limiter_bands; - unsigned bs_limiter_gains; - unsigned bs_interpol_freq; - unsigned bs_smoothing_mode; - /** @} */ - unsigned bs_coupling; - unsigned k[5]; ///< k0, k1, k2 - ///kx', and kx respectively, kx is the first QMF subband where SBR is used. - ///kx' is its value from the previous frame - unsigned kx[2]; - ///M' and M respectively, M is the number of QMF subbands that use SBR. - unsigned m[2]; - ///The number of frequency bands in f_master - unsigned n_master; - SBRData data[2]; - ///N_Low and N_High respectively, the number of frequency bands for low and high resolution - unsigned n[2]; - ///Number of noise floor bands - unsigned n_q; - ///Number of limiter bands - unsigned n_lim; - ///The master QMF frequency grouping - uint16_t f_master[49]; - ///Frequency borders for low resolution SBR - uint16_t f_tablelow[25]; - ///Frequency borders for high resolution SBR - uint16_t f_tablehigh[49]; - ///Frequency borders for noise floors - uint16_t f_tablenoise[6]; - ///Frequency borders for the limiter - uint16_t f_tablelim[29]; - unsigned num_patches; - uint8_t patch_num_subbands[6]; - uint8_t patch_start_subband[6]; - ///QMF low frequency input to the HF generator - float X_low[32][40][2]; - ///QMF output of the HF generator - float X_high[64][40][2]; - ///QMF values of the reconstructed signal - DECLARE_ALIGNED(16, float, X)[2][2][32][64]; - ///Zeroth coefficient used to filter the subband signals - float alpha0[64][2]; - ///First coefficient used to filter the subband signals - float alpha1[64][2]; - ///Dequantized envelope scalefactors, remapped - float e_origmapped[7][48]; - ///Dequantized noise scalefactors, remapped - float q_mapped[7][48]; - ///Sinusoidal presence, remapped - uint8_t s_mapped[7][48]; - ///Estimated envelope - float e_curr[7][48]; - ///Amplitude adjusted noise scalefactors - float q_m[7][48]; - ///Sinusoidal levels - float s_m[7][48]; - float gain[7][48]; - DECLARE_ALIGNED(16, float, qmf_filter_scratch)[5][64]; - RDFTContext rdft; - FFTContext mdct; -} SpectralBandReplication; - -#endif /* AVCODEC_SBR_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sgi.h b/tizen/distrib/ffmpeg/libavcodec/sgi.h deleted file mode 100644 index be17f2e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sgi.h +++ /dev/null @@ -1,36 +0,0 @@ - /* - * SGI image encoder - * Xiaohui Sun - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SGI_H -#define AVCODEC_SGI_H - -/** - * SGI image file signature - */ -#define SGI_MAGIC 474 - -#define SGI_HEADER_SIZE 512 - -#define SGI_GRAYSCALE 1 -#define SGI_RGB 3 -#define SGI_RGBA 4 - -#endif /* AVCODEC_SGI_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sgidec.c b/tizen/distrib/ffmpeg/libavcodec/sgidec.c deleted file mode 100644 index bbfd94b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sgidec.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * SGI image decoder - * Todd Kirby - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "sgi.h" - -typedef struct SgiState { - AVFrame picture; - unsigned int width; - unsigned int height; - unsigned int depth; - unsigned int bytes_per_channel; - int linesize; -} SgiState; - -/** - * Expand an RLE row into a channel. - * @param in_buf input buffer - * @param in_end end of input buffer - * @param out_buf Points to one line after the output buffer. - * @param out_end end of line in output buffer - * @param pixelstride pixel stride of input buffer - * @return size of output in bytes, -1 if buffer overflows - */ -static int expand_rle_row(const uint8_t *in_buf, const uint8_t* in_end, - unsigned char *out_buf, uint8_t* out_end, int pixelstride) -{ - unsigned char pixel, count; - unsigned char *orig = out_buf; - - while (1) { - if(in_buf + 1 > in_end) return -1; - pixel = bytestream_get_byte(&in_buf); - if (!(count = (pixel & 0x7f))) { - return (out_buf - orig) / pixelstride; - } - - /* Check for buffer overflow. */ - if(out_buf + pixelstride * count >= out_end) return -1; - - if (pixel & 0x80) { - while (count--) { - *out_buf = bytestream_get_byte(&in_buf); - out_buf += pixelstride; - } - } else { - pixel = bytestream_get_byte(&in_buf); - - while (count--) { - *out_buf = pixel; - out_buf += pixelstride; - } - } - } -} - -/** - * Read a run length encoded SGI image. - * @param out_buf output buffer - * @param in_buf input buffer - * @param in_end end of input buffer - * @param s the current image state - * @return 0 if no error, else return error number. - */ -static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf, - const uint8_t *in_end, SgiState* s) -{ - uint8_t *dest_row; - unsigned int len = s->height * s->depth * 4; - const uint8_t *start_table = in_buf; - unsigned int y, z; - unsigned int start_offset; - - /* size of RLE offset and length tables */ - if(len * 2 > in_end - in_buf) { - return AVERROR_INVALIDDATA; - } - - in_buf -= SGI_HEADER_SIZE; - for (z = 0; z < s->depth; z++) { - dest_row = out_buf; - for (y = 0; y < s->height; y++) { - dest_row -= s->linesize; - start_offset = bytestream_get_be32(&start_table); - if(start_offset > in_end - in_buf) { - return AVERROR_INVALIDDATA; - } - if (expand_rle_row(in_buf + start_offset, in_end, dest_row + z, - dest_row + FFABS(s->linesize), s->depth) != s->width) - return AVERROR_INVALIDDATA; - } - } - return 0; -} - -/** - * Read an uncompressed SGI image. - * @param out_buf output buffer - * @param out_end end ofoutput buffer - * @param in_buf input buffer - * @param in_end end of input buffer - * @param s the current image state - * @return 0 if read success, otherwise return -1. - */ -static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end, - const uint8_t *in_buf, const uint8_t *in_end, SgiState* s) -{ - int x, y, z; - const uint8_t *ptr; - unsigned int offset = s->height * s->width * s->bytes_per_channel; - - /* Test buffer size. */ - if (offset * s->depth > in_end - in_buf) { - return -1; - } - - for (y = s->height - 1; y >= 0; y--) { - out_end = out_buf + (y * s->linesize); - for (x = s->width; x > 0; x--) { - ptr = in_buf += s->bytes_per_channel; - for(z = 0; z < s->depth; z ++) { - memcpy(out_end, ptr, s->bytes_per_channel); - out_end += s->bytes_per_channel; - ptr += offset; - } - } - } - return 0; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *in_buf = avpkt->data; - int buf_size = avpkt->size; - SgiState *s = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p = &s->picture; - const uint8_t *in_end = in_buf + buf_size; - unsigned int dimension, rle; - int ret = 0; - uint8_t *out_buf, *out_end; - - if (buf_size < SGI_HEADER_SIZE){ - av_log(avctx, AV_LOG_ERROR, "buf_size too small (%d)\n", buf_size); - return -1; - } - - /* Test for SGI magic. */ - if (bytestream_get_be16(&in_buf) != SGI_MAGIC) { - av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); - return -1; - } - - rle = bytestream_get_byte(&in_buf); - s->bytes_per_channel = bytestream_get_byte(&in_buf); - dimension = bytestream_get_be16(&in_buf); - s->width = bytestream_get_be16(&in_buf); - s->height = bytestream_get_be16(&in_buf); - s->depth = bytestream_get_be16(&in_buf); - - if (s->bytes_per_channel != 1 && (s->bytes_per_channel != 2 || rle)) { - av_log(avctx, AV_LOG_ERROR, "wrong channel number\n"); - return -1; - } - - /* Check for supported image dimensions. */ - if (dimension != 2 && dimension != 3) { - av_log(avctx, AV_LOG_ERROR, "wrong dimension number\n"); - return -1; - } - - if (s->depth == SGI_GRAYSCALE) { - avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_GRAY16BE : PIX_FMT_GRAY8; - } else if (s->depth == SGI_RGB) { - avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_RGB48BE : PIX_FMT_RGB24; - } else if (s->depth == SGI_RGBA && s->bytes_per_channel == 1) { - avctx->pix_fmt = PIX_FMT_RGBA; - } else { - av_log(avctx, AV_LOG_ERROR, "wrong picture format\n"); - return -1; - } - - if (avcodec_check_dimensions(avctx, s->width, s->height)) - return -1; - avcodec_set_dimensions(avctx, s->width, s->height); - - 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 = FF_I_TYPE; - p->key_frame = 1; - out_buf = p->data[0]; - - out_end = out_buf + p->linesize[0] * s->height; - - s->linesize = p->linesize[0]; - - /* Skip header. */ - in_buf += SGI_HEADER_SIZE - 12; - if (rle) { - ret = read_rle_sgi(out_end, in_buf, in_end, s); - } else { - ret = read_uncompressed_sgi(out_buf, out_end, in_buf, in_end, s); - } - - if (ret == 0) { - *picture = s->picture; - *data_size = sizeof(AVPicture); - return buf_size; - } else { - return -1; - } -} - -static av_cold int sgi_init(AVCodecContext *avctx){ - SgiState *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - -static av_cold int sgi_end(AVCodecContext *avctx) -{ - SgiState * const s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec sgi_decoder = { - "sgi", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SGI, - sizeof(SgiState), - sgi_init, - NULL, - sgi_end, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("SGI image"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/sgienc.c b/tizen/distrib/ffmpeg/libavcodec/sgienc.c deleted file mode 100644 index f9f3709..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sgienc.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * SGI image encoder - * Todd Kirby - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "sgi.h" -#include "rle.h" - -#define SGI_SINGLE_CHAN 2 -#define SGI_MULTI_CHAN 3 - -typedef struct SgiContext { - AVFrame picture; -} SgiContext; - -static av_cold int encode_init(AVCodecContext *avctx) -{ - SgiContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, - int buf_size, void *data) -{ - SgiContext *s = avctx->priv_data; - AVFrame * const p = &s->picture; - uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf; - int x, y, z, length, tablesize; - unsigned int width, height, depth, dimension; - unsigned char *orig_buf = buf, *end_buf = buf + buf_size; - - *p = *(AVFrame*)data; - p->pict_type = FF_I_TYPE; - p->key_frame = 1; - - width = avctx->width; - height = avctx->height; - - switch (avctx->pix_fmt) { - case PIX_FMT_GRAY8: - dimension = SGI_SINGLE_CHAN; - depth = SGI_GRAYSCALE; - break; - case PIX_FMT_RGB24: - dimension = SGI_MULTI_CHAN; - depth = SGI_RGB; - break; - case PIX_FMT_RGBA: - dimension = SGI_MULTI_CHAN; - depth = SGI_RGBA; - break; - default: - return AVERROR_INVALIDDATA; - } - - tablesize = depth * height * 4; - length = tablesize * 2 + SGI_HEADER_SIZE; - - if (buf_size < length) { - av_log(avctx, AV_LOG_ERROR, "buf_size too small(need %d, got %d)\n", length, buf_size); - return -1; - } - - /* Encode header. */ - bytestream_put_be16(&buf, SGI_MAGIC); - bytestream_put_byte(&buf, avctx->coder_type != FF_CODER_TYPE_RAW); /* RLE 1 - VERBATIM 0*/ - bytestream_put_byte(&buf, 1); /* bytes_per_channel */ - bytestream_put_be16(&buf, dimension); - bytestream_put_be16(&buf, width); - bytestream_put_be16(&buf, height); - bytestream_put_be16(&buf, depth); - - /* The rest are constant in this implementation. */ - bytestream_put_be32(&buf, 0L); /* pixmin */ - bytestream_put_be32(&buf, 255L); /* pixmax */ - bytestream_put_be32(&buf, 0L); /* dummy */ - - /* name */ - memset(buf, 0, SGI_HEADER_SIZE); - buf += 80; - - /* colormap */ - bytestream_put_be32(&buf, 0L); - - /* The rest of the 512 byte header is unused. */ - buf += 404; - offsettab = buf; - - if (avctx->coder_type != FF_CODER_TYPE_RAW) { - /* Skip RLE offset table. */ - buf += tablesize; - lengthtab = buf; - - /* Skip RLE length table. */ - buf += tablesize; - - /* Make an intermediate consecutive buffer. */ - if (!(encode_buf = av_malloc(width))) - return -1; - - for (z = 0; z < depth; z++) { - in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; - - for (y = 0; y < height; y++) { - bytestream_put_be32(&offsettab, buf - orig_buf); - - for (x = 0; x < width; x++) - encode_buf[x] = in_buf[depth * x]; - - if ((length = ff_rle_encode(buf, end_buf - buf - 1, encode_buf, 1, width, 0, 0, 0x80, 0)) < 1) { - av_free(encode_buf); - return -1; - } - - buf += length; - bytestream_put_byte(&buf, 0); - bytestream_put_be32(&lengthtab, length + 1); - in_buf -= p->linesize[0]; - } - } - - av_free(encode_buf); - } else { - for (z = 0; z < depth; z++) { - in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; - - for (y = 0; y < height; y++) { - for (x = 0; x < width * depth; x += depth) - bytestream_put_byte(&buf, in_buf[x]); - - in_buf -= p->linesize[0]; - } - } - } - - /* total length */ - return buf - orig_buf; -} - -AVCodec sgi_encoder = { - "sgi", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SGI, - sizeof(SgiContext), - encode_init, - encode_frame, - NULL, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_GRAY8, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("SGI image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/sh4/Makefile b/tizen/distrib/ffmpeg/libavcodec/sh4/Makefile deleted file mode 100644 index 142cba4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sh4/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -OBJS += sh4/dsputil_align.o \ - sh4/dsputil_sh4.o \ - sh4/idct_sh4.o \ diff --git a/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_align.c b/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_align.c deleted file mode 100644 index 9e7efde..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_align.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * aligned/packed access motion - * - * Copyright (c) 2001-2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "dsputil_sh4.h" - - -#define LP(p) *(uint32_t*)(p) -#define LPC(p) *(const uint32_t*)(p) - - -#define UNPACK(ph,pl,tt0,tt1) do { \ - uint32_t t0,t1; t0=tt0;t1=tt1; \ - ph = ( (t0 & ~BYTE_VEC32(0x03))>>2) + ( (t1 & ~BYTE_VEC32(0x03))>>2); \ - pl = (t0 & BYTE_VEC32(0x03)) + (t1 & BYTE_VEC32(0x03)); } while(0) - -#define rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x02))>>2) & BYTE_VEC32(0x03)) -#define no_rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x01))>>2) & BYTE_VEC32(0x03)) - -/* little endian */ -#define MERGE1(a,b,ofs) (ofs==0)?a:( ((a)>>(8*ofs))|((b)<<(32-8*ofs)) ) -#define MERGE2(a,b,ofs) (ofs==3)?b:( ((a)>>(8*(ofs+1)))|((b)<<(32-8*(ofs+1))) ) -/* big -#define MERGE1(a,b,ofs) (ofs==0)?a:( ((a)<<(8*ofs))|((b)>>(32-8*ofs)) ) -#define MERGE2(a,b,ofs) (ofs==3)?b:( ((a)<<(8+8*ofs))|((b)>>(32-8-8*ofs)) ) -*/ - - -#define put(d,s) d = s -#define avg(d,s) d = rnd_avg32(s,d) - -#define OP_C4(ofs) \ - ref-=ofs; \ - do { \ - OP(LP(dest),MERGE1(LPC(ref),LPC(ref+4),ofs)); \ - ref+=stride; \ - dest+=stride; \ - } while(--height) - -#define OP_C40() \ - do { \ - OP(LP(dest),LPC(ref)); \ - ref+=stride; \ - dest+=stride; \ - } while(--height) - - -#define OP put - -static void put_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height) -{ - switch((int)ref&3){ - case 0: OP_C40(); return; - case 1: OP_C4(1); return; - case 2: OP_C4(2); return; - case 3: OP_C4(3); return; - } -} - -#undef OP -#define OP avg - -static void avg_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height) -{ - switch((int)ref&3){ - case 0: OP_C40(); return; - case 1: OP_C4(1); return; - case 2: OP_C4(2); return; - case 3: OP_C4(3); return; - } -} - -#undef OP - -#define OP_C(ofs,sz,avg2) \ -{ \ - ref-=ofs; \ - do { \ - uint32_t t0,t1; \ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ - OP(LP(dest+0), MERGE1(t0,t1,ofs)); \ - t0 = LPC(ref+8); \ - OP(LP(dest+4), MERGE1(t1,t0,ofs)); \ -if (sz==16) { \ - t1 = LPC(ref+12); \ - OP(LP(dest+8), MERGE1(t0,t1,ofs)); \ - t0 = LPC(ref+16); \ - OP(LP(dest+12), MERGE1(t1,t0,ofs)); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -/* aligned */ -#define OP_C0(sz,avg2) \ -{ \ - do { \ - OP(LP(dest+0), LPC(ref+0)); \ - OP(LP(dest+4), LPC(ref+4)); \ -if (sz==16) { \ - OP(LP(dest+8), LPC(ref+8)); \ - OP(LP(dest+12), LPC(ref+12)); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -#define OP_X(ofs,sz,avg2) \ -{ \ - ref-=ofs; \ - do { \ - uint32_t t0,t1; \ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ - OP(LP(dest+0), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \ - t0 = LPC(ref+8); \ - OP(LP(dest+4), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \ -if (sz==16) { \ - t1 = LPC(ref+12); \ - OP(LP(dest+8), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \ - t0 = LPC(ref+16); \ - OP(LP(dest+12), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \ -} \ - ref+=stride; \ - dest+= stride; \ - } while(--height); \ -} - -/* aligned */ -#define OP_Y0(sz,avg2) \ -{ \ - uint32_t t0,t1,t2,t3,t; \ -\ - t0 = LPC(ref+0); \ - t1 = LPC(ref+4); \ -if (sz==16) { \ - t2 = LPC(ref+8); \ - t3 = LPC(ref+12); \ -} \ - do { \ - ref += stride; \ -\ - t = LPC(ref+0); \ - OP(LP(dest+0), avg2(t0,t)); t0 = t; \ - t = LPC(ref+4); \ - OP(LP(dest+4), avg2(t1,t)); t1 = t; \ -if (sz==16) { \ - t = LPC(ref+8); \ - OP(LP(dest+8), avg2(t2,t)); t2 = t; \ - t = LPC(ref+12); \ - OP(LP(dest+12), avg2(t3,t)); t3 = t; \ -} \ - dest+= stride; \ - } while(--height); \ -} - -#define OP_Y(ofs,sz,avg2) \ -{ \ - uint32_t t0,t1,t2,t3,t,w0,w1; \ -\ - ref-=ofs; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - t0 = MERGE1(w0,w1,ofs); \ - w0 = LPC(ref+8); \ - t1 = MERGE1(w1,w0,ofs); \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - t2 = MERGE1(w0,w1,ofs); \ - w0 = LPC(ref+16); \ - t3 = MERGE1(w1,w0,ofs); \ -} \ - do { \ - ref += stride; \ -\ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - t = MERGE1(w0,w1,ofs); \ - OP(LP(dest+0), avg2(t0,t)); t0 = t; \ - w0 = LPC(ref+8); \ - t = MERGE1(w1,w0,ofs); \ - OP(LP(dest+4), avg2(t1,t)); t1 = t; \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - t = MERGE1(w0,w1,ofs); \ - OP(LP(dest+8), avg2(t2,t)); t2 = t; \ - w0 = LPC(ref+16); \ - t = MERGE1(w1,w0,ofs); \ - OP(LP(dest+12), avg2(t3,t)); t3 = t; \ -} \ - dest+=stride; \ - } while(--height); \ -} - -#define OP_X0(sz,avg2) OP_X(0,sz,avg2) -#define OP_XY0(sz,PACK) OP_XY(0,sz,PACK) -#define OP_XY(ofs,sz,PACK) \ -{ \ - uint32_t t2,t3,w0,w1; \ - uint32_t a0,a1,a2,a3,a4,a5,a6,a7; \ -\ - ref -= ofs; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - UNPACK(a0,a1,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - w0 = LPC(ref+8); \ - UNPACK(a2,a3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - UNPACK(a4,a5,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - w0 = LPC(ref+16); \ - UNPACK(a6,a7,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ -} \ - do { \ - ref+=stride; \ - w0 = LPC(ref+0); \ - w1 = LPC(ref+4); \ - UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - OP(LP(dest+0),PACK(a0,a1,t2,t3)); \ - a0 = t2; a1 = t3; \ - w0 = LPC(ref+8); \ - UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ - OP(LP(dest+4),PACK(a2,a3,t2,t3)); \ - a2 = t2; a3 = t3; \ -if (sz==16) { \ - w1 = LPC(ref+12); \ - UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \ - OP(LP(dest+8),PACK(a4,a5,t2,t3)); \ - a4 = t2; a5 = t3; \ - w0 = LPC(ref+16); \ - UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \ - OP(LP(dest+12),PACK(a6,a7,t2,t3)); \ - a6 = t2; a7 = t3; \ -} \ - dest+=stride; \ - } while(--height); \ -} - -#define DEFFUNC(op,rnd,xy,sz,OP_N,avgfunc) \ -static void op##_##rnd##_pixels##sz##_##xy (uint8_t * dest, const uint8_t * ref, \ - const int stride, int height) \ -{ \ - switch((int)ref&3) { \ - case 0:OP_N##0(sz,rnd##_##avgfunc); return; \ - case 1:OP_N(1,sz,rnd##_##avgfunc); return; \ - case 2:OP_N(2,sz,rnd##_##avgfunc); return; \ - case 3:OP_N(3,sz,rnd##_##avgfunc); return; \ - } \ -} - -#define OP put - -DEFFUNC(put, rnd,o,8,OP_C,avg32) -DEFFUNC(put, rnd,x,8,OP_X,avg32) -DEFFUNC(put,no_rnd,x,8,OP_X,avg32) -DEFFUNC(put, rnd,y,8,OP_Y,avg32) -DEFFUNC(put,no_rnd,y,8,OP_Y,avg32) -DEFFUNC(put, rnd,xy,8,OP_XY,PACK) -DEFFUNC(put,no_rnd,xy,8,OP_XY,PACK) -DEFFUNC(put, rnd,o,16,OP_C,avg32) -DEFFUNC(put, rnd,x,16,OP_X,avg32) -DEFFUNC(put,no_rnd,x,16,OP_X,avg32) -DEFFUNC(put, rnd,y,16,OP_Y,avg32) -DEFFUNC(put,no_rnd,y,16,OP_Y,avg32) -DEFFUNC(put, rnd,xy,16,OP_XY,PACK) -DEFFUNC(put,no_rnd,xy,16,OP_XY,PACK) - -#undef OP -#define OP avg - -DEFFUNC(avg, rnd,o,8,OP_C,avg32) -DEFFUNC(avg, rnd,x,8,OP_X,avg32) -DEFFUNC(avg,no_rnd,x,8,OP_X,avg32) -DEFFUNC(avg, rnd,y,8,OP_Y,avg32) -DEFFUNC(avg,no_rnd,y,8,OP_Y,avg32) -DEFFUNC(avg, rnd,xy,8,OP_XY,PACK) -DEFFUNC(avg,no_rnd,xy,8,OP_XY,PACK) -DEFFUNC(avg, rnd,o,16,OP_C,avg32) -DEFFUNC(avg, rnd,x,16,OP_X,avg32) -DEFFUNC(avg,no_rnd,x,16,OP_X,avg32) -DEFFUNC(avg, rnd,y,16,OP_Y,avg32) -DEFFUNC(avg,no_rnd,y,16,OP_Y,avg32) -DEFFUNC(avg, rnd,xy,16,OP_XY,PACK) -DEFFUNC(avg,no_rnd,xy,16,OP_XY,PACK) - -#undef OP - -#define put_no_rnd_pixels8_o put_rnd_pixels8_o -#define put_no_rnd_pixels16_o put_rnd_pixels16_o -#define avg_no_rnd_pixels8_o avg_rnd_pixels8_o -#define avg_no_rnd_pixels16_o avg_rnd_pixels16_o - -#define put_pixels8_c put_rnd_pixels8_o -#define put_pixels16_c put_rnd_pixels16_o -#define avg_pixels8_c avg_rnd_pixels8_o -#define avg_pixels16_c avg_rnd_pixels16_o -#define put_no_rnd_pixels8_c put_rnd_pixels8_o -#define put_no_rnd_pixels16_c put_rnd_pixels16_o -#define avg_no_rnd_pixels8_c avg_rnd_pixels8_o -#define avg_no_rnd_pixels16_c avg_rnd_pixels16_o - -#define QPEL - -#ifdef QPEL - -#include "qpel.c" - -#endif - -void dsputil_init_align(DSPContext* c, AVCodecContext *avctx) -{ - c->put_pixels_tab[0][0] = put_rnd_pixels16_o; - c->put_pixels_tab[0][1] = put_rnd_pixels16_x; - c->put_pixels_tab[0][2] = put_rnd_pixels16_y; - c->put_pixels_tab[0][3] = put_rnd_pixels16_xy; - c->put_pixels_tab[1][0] = put_rnd_pixels8_o; - c->put_pixels_tab[1][1] = put_rnd_pixels8_x; - c->put_pixels_tab[1][2] = put_rnd_pixels8_y; - c->put_pixels_tab[1][3] = put_rnd_pixels8_xy; - - c->put_no_rnd_pixels_tab[0][0] = put_no_rnd_pixels16_o; - c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x; - c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y; - c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy; - c->put_no_rnd_pixels_tab[1][0] = put_no_rnd_pixels8_o; - c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x; - c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y; - c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy; - - c->avg_pixels_tab[0][0] = avg_rnd_pixels16_o; - c->avg_pixels_tab[0][1] = avg_rnd_pixels16_x; - c->avg_pixels_tab[0][2] = avg_rnd_pixels16_y; - c->avg_pixels_tab[0][3] = avg_rnd_pixels16_xy; - c->avg_pixels_tab[1][0] = avg_rnd_pixels8_o; - c->avg_pixels_tab[1][1] = avg_rnd_pixels8_x; - c->avg_pixels_tab[1][2] = avg_rnd_pixels8_y; - c->avg_pixels_tab[1][3] = avg_rnd_pixels8_xy; - - c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_o; - c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x; - c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y; - c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy; - c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_o; - c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x; - c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y; - c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy; - -#ifdef QPEL - -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_sh4; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_sh4; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_sh4; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_sh4; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_sh4; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_sh4; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_sh4; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_sh4; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_sh4; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_sh4; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_sh4; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_sh4; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_sh4; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_sh4; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_sh4; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_sh4 - - 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(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_sh4; - c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_sh4; - c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_sh4; - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_sh4; - c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_sh4; - c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_sh4; - - c->put_mspel_pixels_tab[0]= put_mspel8_mc00_sh4; - c->put_mspel_pixels_tab[1]= put_mspel8_mc10_sh4; - c->put_mspel_pixels_tab[2]= put_mspel8_mc20_sh4; - c->put_mspel_pixels_tab[3]= put_mspel8_mc30_sh4; - c->put_mspel_pixels_tab[4]= put_mspel8_mc02_sh4; - c->put_mspel_pixels_tab[5]= put_mspel8_mc12_sh4; - c->put_mspel_pixels_tab[6]= put_mspel8_mc22_sh4; - c->put_mspel_pixels_tab[7]= put_mspel8_mc32_sh4; - - c->gmc1 = gmc1_c; - c->gmc = gmc_c; - -#endif -} diff --git a/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c b/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c deleted file mode 100644 index ec06e24..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * sh4 dsputil - * - * Copyright (c) 2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "dsputil_sh4.h" -#include "sh4.h" - -static void memzero_align8(void *dst,size_t size) -{ - int fpscr; - fp_single_enter(fpscr); - dst = (char *)dst + size; - size /= 32; - __asm__ volatile ( - " fldi0 fr0\n" - " fldi0 fr1\n" - " fschg\n" // double - "1: \n" \ - " dt %1\n" - " fmov dr0,@-%0\n" - " fmov dr0,@-%0\n" - " fmov dr0,@-%0\n" - " bf.s 1b\n" - " fmov dr0,@-%0\n" - " fschg" //back to single - : "+r"(dst),"+r"(size) :: "memory" ); - fp_single_leave(fpscr); -} - -static void clear_blocks_sh4(DCTELEM *blocks) -{ - memzero_align8(blocks,sizeof(DCTELEM)*6*64); -} - -static void idct_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - idct_sh4(block); - for(i=0;i<8;i++) { - dest[0] = cm[block[0]]; - dest[1] = cm[block[1]]; - dest[2] = cm[block[2]]; - dest[3] = cm[block[3]]; - dest[4] = cm[block[4]]; - dest[5] = cm[block[5]]; - dest[6] = cm[block[6]]; - dest[7] = cm[block[7]]; - dest+=line_size; - block+=8; - } -} -static void idct_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - idct_sh4(block); - for(i=0;i<8;i++) { - dest[0] = cm[dest[0]+block[0]]; - dest[1] = cm[dest[1]+block[1]]; - dest[2] = cm[dest[2]+block[2]]; - dest[3] = cm[dest[3]+block[3]]; - dest[4] = cm[dest[4]+block[4]]; - dest[5] = cm[dest[5]+block[5]]; - dest[6] = cm[dest[6]+block[6]]; - dest[7] = cm[dest[7]+block[7]]; - dest+=line_size; - block+=8; - } -} - -void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx) -{ - const int idct_algo= avctx->idct_algo; - dsputil_init_align(c,avctx); - - c->clear_blocks = clear_blocks_sh4; - if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SH4){ - c->idct_put = idct_put; - c->idct_add = idct_add; - c->idct = idct_sh4; - c->idct_permutation_type= FF_NO_IDCT_PERM; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.h b/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.h deleted file mode 100644 index 2c1f77c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sh4/dsputil_sh4.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SH4_DSPUTIL_SH4_H -#define AVCODEC_SH4_DSPUTIL_SH4_H - -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" - -void idct_sh4(DCTELEM *block); -void dsputil_init_align(DSPContext* c, AVCodecContext *avctx); - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/sh4/idct_sh4.c b/tizen/distrib/ffmpeg/libavcodec/sh4/idct_sh4.c deleted file mode 100644 index 8d1a316..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sh4/idct_sh4.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * idct for sh4 - * - * Copyright (c) 2001-2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_sh4.h" -#include "sh4.h" - -#define c1 1.38703984532214752434 /* sqrt(2)*cos(1*pi/16) */ -#define c2 1.30656296487637657577 /* sqrt(2)*cos(2*pi/16) */ -#define c3 1.17587560241935884520 /* sqrt(2)*cos(3*pi/16) */ -#define c4 1.00000000000000000000 /* sqrt(2)*cos(4*pi/16) */ -#define c5 0.78569495838710234903 /* sqrt(2)*cos(5*pi/16) */ -#define c6 0.54119610014619712324 /* sqrt(2)*cos(6*pi/16) */ -#define c7 0.27589937928294311353 /* sqrt(2)*cos(7*pi/16) */ - -static const float even_table[] __attribute__ ((aligned(8))) = { - c4, c4, c4, c4, - c2, c6,-c6,-c2, - c4,-c4,-c4, c4, - c6,-c2, c2,-c6 -}; - -static const float odd_table[] __attribute__ ((aligned(8))) = { - c1, c3, c5, c7, - c3,-c7,-c1,-c5, - c5,-c1, c7, c3, - c7,-c5, c3,-c1 -}; - -#undef c1 -#undef c2 -#undef c3 -#undef c4 -#undef c5 -#undef c6 -#undef c7 - -#if 1 - -#define load_matrix(table) \ - do { \ - const float *t = table; \ - __asm__ volatile( \ - " fschg\n" \ - " fmov @%0+,xd0\n" \ - " fmov @%0+,xd2\n" \ - " fmov @%0+,xd4\n" \ - " fmov @%0+,xd6\n" \ - " fmov @%0+,xd8\n" \ - " fmov @%0+,xd10\n" \ - " fmov @%0+,xd12\n" \ - " fmov @%0+,xd14\n" \ - " fschg\n" \ - : "+r"(t) \ - ); \ - } while (0) - -#define ftrv() \ - __asm__ volatile("ftrv xmtrx,fv0" \ - : "+f"(fr0),"+f"(fr1),"+f"(fr2),"+f"(fr3)); - -#define DEFREG \ - register float fr0 __asm__("fr0"); \ - register float fr1 __asm__("fr1"); \ - register float fr2 __asm__("fr2"); \ - register float fr3 __asm__("fr3") - -#else - -/* generic C code for check */ - -static void ftrv_(const float xf[],float fv[]) -{ - float f0,f1,f2,f3; - f0 = fv[0]; - f1 = fv[1]; - f2 = fv[2]; - f3 = fv[3]; - fv[0] = xf[0]*f0 + xf[4]*f1 + xf[ 8]*f2 + xf[12]*f3; - fv[1] = xf[1]*f0 + xf[5]*f1 + xf[ 9]*f2 + xf[13]*f3; - fv[2] = xf[2]*f0 + xf[6]*f1 + xf[10]*f2 + xf[14]*f3; - fv[3] = xf[3]*f0 + xf[7]*f1 + xf[11]*f2 + xf[15]*f3; -} - -static void load_matrix_(float xf[],const float table[]) -{ - int i; - for(i=0;i<16;i++) xf[i]=table[i]; -} - -#define ftrv() ftrv_(xf,fv) -#define load_matrix(table) load_matrix_(xf,table) - -#define DEFREG \ - float fv[4],xf[16] - -#define fr0 fv[0] -#define fr1 fv[1] -#define fr2 fv[2] -#define fr3 fv[3] - -#endif - -#if 1 -#define DESCALE(x,n) (x)*(1.0f/(1<<(n))) -#else -#define DESCALE(x,n) (((int)(x)+(1<<(n-1)))>>(n)) -#endif - -/* this code work worse on gcc cvs. 3.2.3 work fine */ - - -#if 1 -//optimized - -void idct_sh4(DCTELEM *block) -{ - DEFREG; - - int i; - float tblock[8*8],*fblock; - int ofs1,ofs2,ofs3; - int fpscr; - - fp_single_enter(fpscr); - - /* row */ - - /* even part */ - load_matrix(even_table); - - fblock = tblock+4; - i = 8; - do { - fr0 = block[0]; - fr1 = block[2]; - fr2 = block[4]; - fr3 = block[6]; - block+=8; - ftrv(); - *--fblock = fr3; - *--fblock = fr2; - *--fblock = fr1; - *--fblock = fr0; - fblock+=8+4; - } while(--i); - block-=8*8; - fblock-=8*8+4; - - load_matrix(odd_table); - - i = 8; - - do { - float t0,t1,t2,t3; - fr0 = block[1]; - fr1 = block[3]; - fr2 = block[5]; - fr3 = block[7]; - block+=8; - ftrv(); - t0 = *fblock++; - t1 = *fblock++; - t2 = *fblock++; - t3 = *fblock++; - fblock+=4; - *--fblock = t0 - fr0; - *--fblock = t1 - fr1; - *--fblock = t2 - fr2; - *--fblock = t3 - fr3; - *--fblock = t3 + fr3; - *--fblock = t2 + fr2; - *--fblock = t1 + fr1; - *--fblock = t0 + fr0; - fblock+=8; - } while(--i); - block-=8*8; - fblock-=8*8; - - /* col */ - - /* even part */ - load_matrix(even_table); - - ofs1 = sizeof(float)*2*8; - ofs2 = sizeof(float)*4*8; - ofs3 = sizeof(float)*6*8; - - i = 8; - -#define OA(fblock,ofs) *(float*)((char*)fblock + ofs) - - do { - fr0 = OA(fblock, 0); - fr1 = OA(fblock,ofs1); - fr2 = OA(fblock,ofs2); - fr3 = OA(fblock,ofs3); - ftrv(); - OA(fblock,0 ) = fr0; - OA(fblock,ofs1) = fr1; - OA(fblock,ofs2) = fr2; - OA(fblock,ofs3) = fr3; - fblock++; - } while(--i); - fblock-=8; - - load_matrix(odd_table); - - i=8; - do { - float t0,t1,t2,t3; - t0 = OA(fblock, 0); /* [8*0] */ - t1 = OA(fblock,ofs1); /* [8*2] */ - t2 = OA(fblock,ofs2); /* [8*4] */ - t3 = OA(fblock,ofs3); /* [8*6] */ - fblock+=8; - fr0 = OA(fblock, 0); /* [8*1] */ - fr1 = OA(fblock,ofs1); /* [8*3] */ - fr2 = OA(fblock,ofs2); /* [8*5] */ - fr3 = OA(fblock,ofs3); /* [8*7] */ - fblock+=-8+1; - ftrv(); - block[8*0] = DESCALE(t0 + fr0,3); - block[8*7] = DESCALE(t0 - fr0,3); - block[8*1] = DESCALE(t1 + fr1,3); - block[8*6] = DESCALE(t1 - fr1,3); - block[8*2] = DESCALE(t2 + fr2,3); - block[8*5] = DESCALE(t2 - fr2,3); - block[8*3] = DESCALE(t3 + fr3,3); - block[8*4] = DESCALE(t3 - fr3,3); - block++; - } while(--i); - - fp_single_leave(fpscr); -} -#else -void idct_sh4(DCTELEM *block) -{ - DEFREG; - - int i; - float tblock[8*8],*fblock; - - /* row */ - - /* even part */ - load_matrix(even_table); - - fblock = tblock; - i = 8; - do { - fr0 = block[0]; - fr1 = block[2]; - fr2 = block[4]; - fr3 = block[6]; - block+=8; - ftrv(); - fblock[0] = fr0; - fblock[2] = fr1; - fblock[4] = fr2; - fblock[6] = fr3; - fblock+=8; - } while(--i); - block-=8*8; - fblock-=8*8; - - load_matrix(odd_table); - - i = 8; - - do { - float t0,t1,t2,t3; - fr0 = block[1]; - fr1 = block[3]; - fr2 = block[5]; - fr3 = block[7]; - block+=8; - ftrv(); - t0 = fblock[0]; - t1 = fblock[2]; - t2 = fblock[4]; - t3 = fblock[6]; - fblock[0] = t0 + fr0; - fblock[7] = t0 - fr0; - fblock[1] = t1 + fr1; - fblock[6] = t1 - fr1; - fblock[2] = t2 + fr2; - fblock[5] = t2 - fr2; - fblock[3] = t3 + fr3; - fblock[4] = t3 - fr3; - fblock+=8; - } while(--i); - block-=8*8; - fblock-=8*8; - - /* col */ - - /* even part */ - load_matrix(even_table); - - i = 8; - - do { - fr0 = fblock[8*0]; - fr1 = fblock[8*2]; - fr2 = fblock[8*4]; - fr3 = fblock[8*6]; - ftrv(); - fblock[8*0] = fr0; - fblock[8*2] = fr1; - fblock[8*4] = fr2; - fblock[8*6] = fr3; - fblock++; - } while(--i); - fblock-=8; - - load_matrix(odd_table); - - i=8; - do { - float t0,t1,t2,t3; - fr0 = fblock[8*1]; - fr1 = fblock[8*3]; - fr2 = fblock[8*5]; - fr3 = fblock[8*7]; - ftrv(); - t0 = fblock[8*0]; - t1 = fblock[8*2]; - t2 = fblock[8*4]; - t3 = fblock[8*6]; - fblock++; - block[8*0] = DESCALE(t0 + fr0,3); - block[8*7] = DESCALE(t0 - fr0,3); - block[8*1] = DESCALE(t1 + fr1,3); - block[8*6] = DESCALE(t1 - fr1,3); - block[8*2] = DESCALE(t2 + fr2,3); - block[8*5] = DESCALE(t2 - fr2,3); - block[8*3] = DESCALE(t3 + fr3,3); - block[8*4] = DESCALE(t3 - fr3,3); - block++; - } while(--i); -} -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/sh4/qpel.c b/tizen/distrib/ffmpeg/libavcodec/sh4/qpel.c deleted file mode 100644 index 917068d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sh4/qpel.c +++ /dev/null @@ -1,1409 +0,0 @@ -/* - * This is optimized for sh, which have post increment addressing (*p++). - * Some CPU may be index (p[n]) faster than post increment (*p++). - * - * copyright (c) 2001-2003 BERO - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define PIXOP2(OPNAME, OP) \ -\ -static inline void OPNAME ## _pixels4_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels4_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),no_rnd_avg32(AV_RN32(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),no_rnd_avg32(AV_RN32(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),rnd_avg32(AV_RN32(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),rnd_avg32(AV_RN32(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do { /* onlye src2 aligned */\ - OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels8_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),no_rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels8_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels16_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),no_rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),no_rnd_avg32(LPC(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),no_rnd_avg32(LPC(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _pixels16_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{\ - do {\ - OP(LP(dst ),rnd_avg32(LPC(src1 ),LPC(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \ - OP(LP(dst+8),rnd_avg32(LPC(src1+8),LPC(src2+8)) ); \ - OP(LP(dst+12),rnd_avg32(LPC(src1+12),LPC(src2+12)) ); \ - src1+=src_stride1; \ - src2+=src_stride2; \ - dst+=dst_stride; \ - } while(--h); \ -}\ -\ -static inline void OPNAME ## _no_rnd_pixels16_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _no_rnd_pixels16_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _pixels16_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _pixels16_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _no_rnd_pixels8_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _no_rnd_pixels8_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _pixels8_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ -{ OPNAME ## _pixels8_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \ -\ -static inline void OPNAME ## _pixels8_l4_aligned(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){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels8_l4_aligned(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){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _pixels8_l4_aligned0(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){\ - do { \ - uint32_t a0,a1,a2,a3; /* src1 only not aligned */\ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels8_l4_aligned0(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){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _pixels16_l4_aligned(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){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels16_l4_aligned(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){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LPC(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LPC(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _pixels16_l4_aligned0(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){\ - do { /* src1 is unaligned */\ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ -static inline void OPNAME ## _no_rnd_pixels16_l4_aligned0(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){\ - do { \ - uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \ - UNPACK(a2,a3,LPC(src3),LPC(src4)); \ - OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \ - UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \ - OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+8),LPC(src2+8)); \ - UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \ - OP(LP(dst+8),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,AV_RN32(src1+12),LPC(src2+12)); \ - UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \ - OP(LP(dst+12),no_rnd_PACK(a0,a1,a2,a3)); \ - src1+=src_stride1;\ - src2+=src_stride2;\ - src3+=src_stride3;\ - src4+=src_stride4;\ - dst+=dst_stride;\ - } while(--h); \ -} \ -\ - -#define op_avg(a, b) a = rnd_avg32(a,b) -#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 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); - - do { - int t0,t1,t2,t3; - uint8_t *s0 = src; - uint8_t *s1 = src+stride; - t0 = *s0++; t2 = *s1++; - t1 = *s0++; t3 = *s1++; - dst[0]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[1]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - t1 = *s0++; t3 = *s1++; - dst[2]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[3]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - t1 = *s0++; t3 = *s1++; - dst[4]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[5]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - t1 = *s0++; t3 = *s1++; - dst[6]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8; - t0 = *s0++; t2 = *s1++; - dst[7]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8; - dst+= stride; - src+= stride; - }while(--h); -} - -static void 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 + av_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= av_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= av_clip(src_x, 0, width) + av_clip(src_y, 0, height)*stride; - dst[y*stride + x]= src[index ]; - } - } - - vx+= dxx; - vy+= dyx; - } - ox += dxy; - oy += dyy; - } -} -#define H264_CHROMA_MC(OPNAME, OP)\ -static void OPNAME ## h264_chroma_mc2_sh4(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);\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - do {\ - int t0,t1,t2,t3; \ - uint8_t *s0 = src; \ - uint8_t *s1 = src+stride; \ - t0 = *s0++; t2 = *s1++; \ - t1 = *s0++; t3 = *s1++; \ - OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\ - dst+= stride;\ - src+= stride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## h264_chroma_mc4_sh4(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);\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - do {\ - int t0,t1,t2,t3; \ - uint8_t *s0 = src; \ - uint8_t *s1 = src+stride; \ - t0 = *s0++; t2 = *s1++; \ - t1 = *s0++; t3 = *s1++; \ - OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\ - dst+= stride;\ - src+= stride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## h264_chroma_mc8_sh4(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);\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - do {\ - int t0,t1,t2,t3; \ - uint8_t *s0 = src; \ - uint8_t *s1 = src+stride; \ - t0 = *s0++; t2 = *s1++; \ - t1 = *s0++; t3 = *s1++; \ - OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[4], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[5], (A*t1 + B*t0 + C*t3 + D*t2));\ - t1 = *s0++; t3 = *s1++; \ - OP(dst[6], (A*t0 + B*t1 + C*t2 + D*t3));\ - t0 = *s0++; t2 = *s1++; \ - OP(dst[7], (A*t1 + B*t0 + C*t3 + D*t2));\ - dst+= stride;\ - src+= stride;\ - }while(--h);\ -} - -#define op_avg(a, b) a = (((a)+(((b) + 32)>>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 - -#define QPEL_MC(r, OPNAME, RND, OP) \ -static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - do {\ - uint8_t *s = src; \ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - src0= *s++;\ - src1= *s++;\ - src2= *s++;\ - src3= *s++;\ - src4= *s++;\ - OP(dst[0], (src0+src1)*20 - (src0+src2)*6 + (src1+src3)*3 - (src2+src4));\ - src5= *s++;\ - OP(dst[1], (src1+src2)*20 - (src0+src3)*6 + (src0+src4)*3 - (src1+src5));\ - src6= *s++;\ - OP(dst[2], (src2+src3)*20 - (src1+src4)*6 + (src0+src5)*3 - (src0+src6));\ - src7= *s++;\ - OP(dst[3], (src3+src4)*20 - (src2+src5)*6 + (src1+src6)*3 - (src0+src7));\ - src8= *s++;\ - OP(dst[4], (src4+src5)*20 - (src3+src6)*6 + (src2+src7)*3 - (src1+src8));\ - OP(dst[5], (src5+src6)*20 - (src4+src7)*6 + (src3+src8)*3 - (src2+src8));\ - OP(dst[6], (src6+src7)*20 - (src5+src8)*6 + (src4+src8)*3 - (src3+src7));\ - OP(dst[7], (src7+src8)*20 - (src6+src8)*6 + (src5+src7)*3 - (src4+src6));\ - dst+=dstStride;\ - src+=srcStride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## mpeg4_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int w=8;\ - do{\ - uint8_t *s = src, *d=dst;\ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - src0 = *s; s+=srcStride; \ - src1 = *s; s+=srcStride; \ - src2 = *s; s+=srcStride; \ - src3 = *s; s+=srcStride; \ - src4 = *s; s+=srcStride; \ - OP(*d, (src0+src1)*20 - (src0+src2)*6 + (src1+src3)*3 - (src2+src4));d+=dstStride;\ - src5 = *s; s+=srcStride; \ - OP(*d, (src1+src2)*20 - (src0+src3)*6 + (src0+src4)*3 - (src1+src5));d+=dstStride;\ - src6 = *s; s+=srcStride; \ - OP(*d, (src2+src3)*20 - (src1+src4)*6 + (src0+src5)*3 - (src0+src6));d+=dstStride;\ - src7 = *s; s+=srcStride; \ - OP(*d, (src3+src4)*20 - (src2+src5)*6 + (src1+src6)*3 - (src0+src7));d+=dstStride;\ - src8 = *s; \ - OP(*d, (src4+src5)*20 - (src3+src6)*6 + (src2+src7)*3 - (src1+src8));d+=dstStride;\ - OP(*d, (src5+src6)*20 - (src4+src7)*6 + (src3+src8)*3 - (src2+src8));d+=dstStride;\ - OP(*d, (src6+src7)*20 - (src5+src8)*6 + (src4+src8)*3 - (src3+src7));d+=dstStride;\ - OP(*d, (src7+src8)*20 - (src6+src8)*6 + (src5+src7)*3 - (src4+src6));\ - dst++;\ - src++;\ - }while(--w);\ -}\ -\ -static void OPNAME ## mpeg4_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - do {\ - uint8_t *s = src;\ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - int src9,src10,src11,src12,src13,src14,src15,src16;\ - src0= *s++;\ - src1= *s++;\ - src2= *s++;\ - src3= *s++;\ - src4= *s++;\ - OP(dst[ 0], (src0 +src1 )*20 - (src0 +src2 )*6 + (src1 +src3 )*3 - (src2 +src4 ));\ - src5= *s++;\ - OP(dst[ 1], (src1 +src2 )*20 - (src0 +src3 )*6 + (src0 +src4 )*3 - (src1 +src5 ));\ - src6= *s++;\ - OP(dst[ 2], (src2 +src3 )*20 - (src1 +src4 )*6 + (src0 +src5 )*3 - (src0 +src6 ));\ - src7= *s++;\ - OP(dst[ 3], (src3 +src4 )*20 - (src2 +src5 )*6 + (src1 +src6 )*3 - (src0 +src7 ));\ - src8= *s++;\ - OP(dst[ 4], (src4 +src5 )*20 - (src3 +src6 )*6 + (src2 +src7 )*3 - (src1 +src8 ));\ - src9= *s++;\ - OP(dst[ 5], (src5 +src6 )*20 - (src4 +src7 )*6 + (src3 +src8 )*3 - (src2 +src9 ));\ - src10= *s++;\ - OP(dst[ 6], (src6 +src7 )*20 - (src5 +src8 )*6 + (src4 +src9 )*3 - (src3 +src10));\ - src11= *s++;\ - OP(dst[ 7], (src7 +src8 )*20 - (src6 +src9 )*6 + (src5 +src10)*3 - (src4 +src11));\ - src12= *s++;\ - OP(dst[ 8], (src8 +src9 )*20 - (src7 +src10)*6 + (src6 +src11)*3 - (src5 +src12));\ - src13= *s++;\ - OP(dst[ 9], (src9 +src10)*20 - (src8 +src11)*6 + (src7 +src12)*3 - (src6 +src13));\ - src14= *s++;\ - OP(dst[10], (src10+src11)*20 - (src9 +src12)*6 + (src8 +src13)*3 - (src7 +src14));\ - src15= *s++;\ - OP(dst[11], (src11+src12)*20 - (src10+src13)*6 + (src9 +src14)*3 - (src8 +src15));\ - src16= *s++;\ - OP(dst[12], (src12+src13)*20 - (src11+src14)*6 + (src10+src15)*3 - (src9 +src16));\ - OP(dst[13], (src13+src14)*20 - (src12+src15)*6 + (src11+src16)*3 - (src10+src16));\ - OP(dst[14], (src14+src15)*20 - (src13+src16)*6 + (src12+src16)*3 - (src11+src15));\ - OP(dst[15], (src15+src16)*20 - (src14+src16)*6 + (src13+src15)*3 - (src12+src14));\ - dst+=dstStride;\ - src+=srcStride;\ - }while(--h);\ -}\ -\ -static void OPNAME ## mpeg4_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int w=16;\ - do {\ - uint8_t *s = src, *d=dst;\ - int src0,src1,src2,src3,src4,src5,src6,src7,src8;\ - int src9,src10,src11,src12,src13,src14,src15,src16;\ - src0 = *s; s+=srcStride; \ - src1 = *s; s+=srcStride; \ - src2 = *s; s+=srcStride; \ - src3 = *s; s+=srcStride; \ - src4 = *s; s+=srcStride; \ - OP(*d, (src0 +src1 )*20 - (src0 +src2 )*6 + (src1 +src3 )*3 - (src2 +src4 ));d+=dstStride;\ - src5 = *s; s+=srcStride; \ - OP(*d, (src1 +src2 )*20 - (src0 +src3 )*6 + (src0 +src4 )*3 - (src1 +src5 ));d+=dstStride;\ - src6 = *s; s+=srcStride; \ - OP(*d, (src2 +src3 )*20 - (src1 +src4 )*6 + (src0 +src5 )*3 - (src0 +src6 ));d+=dstStride;\ - src7 = *s; s+=srcStride; \ - OP(*d, (src3 +src4 )*20 - (src2 +src5 )*6 + (src1 +src6 )*3 - (src0 +src7 ));d+=dstStride;\ - src8 = *s; s+=srcStride; \ - OP(*d, (src4 +src5 )*20 - (src3 +src6 )*6 + (src2 +src7 )*3 - (src1 +src8 ));d+=dstStride;\ - src9 = *s; s+=srcStride; \ - OP(*d, (src5 +src6 )*20 - (src4 +src7 )*6 + (src3 +src8 )*3 - (src2 +src9 ));d+=dstStride;\ - src10 = *s; s+=srcStride; \ - OP(*d, (src6 +src7 )*20 - (src5 +src8 )*6 + (src4 +src9 )*3 - (src3 +src10));d+=dstStride;\ - src11 = *s; s+=srcStride; \ - OP(*d, (src7 +src8 )*20 - (src6 +src9 )*6 + (src5 +src10)*3 - (src4 +src11));d+=dstStride;\ - src12 = *s; s+=srcStride; \ - OP(*d, (src8 +src9 )*20 - (src7 +src10)*6 + (src6 +src11)*3 - (src5 +src12));d+=dstStride;\ - src13 = *s; s+=srcStride; \ - OP(*d, (src9 +src10)*20 - (src8 +src11)*6 + (src7 +src12)*3 - (src6 +src13));d+=dstStride;\ - src14 = *s; s+=srcStride; \ - OP(*d, (src10+src11)*20 - (src9 +src12)*6 + (src8 +src13)*3 - (src7 +src14));d+=dstStride;\ - src15 = *s; s+=srcStride; \ - OP(*d, (src11+src12)*20 - (src10+src13)*6 + (src9 +src14)*3 - (src8 +src15));d+=dstStride;\ - src16 = *s; \ - OP(*d, (src12+src13)*20 - (src11+src14)*6 + (src10+src15)*3 - (src9 +src16));d+=dstStride;\ - OP(*d, (src13+src14)*20 - (src12+src15)*6 + (src11+src16)*3 - (src10+src16));d+=dstStride;\ - OP(*d, (src14+src15)*20 - (src13+src16)*6 + (src12+src16)*3 - (src11+src15));d+=dstStride;\ - OP(*d, (src15+src16)*20 - (src14+src16)*6 + (src13+src15)*3 - (src12+src14));\ - dst++;\ - src++;\ - }while(--w);\ -}\ -\ -static void OPNAME ## qpel8_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels8_c(dst, src, stride, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\ - OPNAME ## pixels8_l2_aligned2(dst, src, half, stride, stride, 8, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## mpeg4_qpel8_h_lowpass(dst, src, stride, stride, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\ - OPNAME ## pixels8_l2_aligned2(dst, src+1, half, stride, stride, 8, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t half[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16);\ - OPNAME ## pixels8_l2_aligned(dst, full, half, stride, 16, 8, 8);\ -}\ -\ -static void OPNAME ## qpel8_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - copy_block9(full, src, 16, stride, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, full, stride, 16);\ -}\ -\ -static void OPNAME ## qpel8_mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t half[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16);\ - OPNAME ## pixels8_l2_aligned(dst, full+16, half, stride, 16, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[72];\ - uint8_t halfHV[64];\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\ - put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\ - OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\ -}\ -static void OPNAME ## qpel8_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\ -}\ -static void OPNAME ## qpel8_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[16*9];\ - uint8_t halfH[72];\ - copy_block9(full, src, 16, stride, 9);\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\ - put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\ -}\ -static void OPNAME ## qpel8_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[72];\ - put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\ - OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\ -}\ -static void OPNAME ## qpel16_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels16_c(dst, src, stride, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\ - OPNAME ## pixels16_l2_aligned2(dst, src, half, stride, stride, 16, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## mpeg4_qpel16_h_lowpass(dst, src, stride, stride, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\ - OPNAME ## pixels16_l2_aligned2(dst, src+1, half, stride, stride, 16, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t half[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24);\ - OPNAME ## pixels16_l2_aligned(dst, full, half, stride, 24, 16, 16);\ -}\ -\ -static void OPNAME ## qpel16_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - copy_block17(full, src, 24, stride, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, full, stride, 24);\ -}\ -\ -static void OPNAME ## qpel16_mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t half[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24);\ - OPNAME ## pixels16_l2_aligned(dst, full+24, half, stride, 24, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[272];\ - uint8_t halfHV[256];\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\ - put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\ - OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\ -}\ -static void OPNAME ## qpel16_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\ -}\ -static void OPNAME ## qpel16_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[24*17];\ - uint8_t halfH[272];\ - copy_block17(full, src, 24, stride, 17);\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\ - put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\ -}\ -static void OPNAME ## qpel16_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t halfH[272];\ - put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\ - OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\ -} - -#define op_avg(a, b) a = (((a)+cm[((b) + 16)>>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 inline void OPNAME ## h264_qpel_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,int w,int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - do {\ - int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\ - uint8_t *s = src-2;\ - srcB = *s++;\ - srcA = *s++;\ - src0 = *s++;\ - src1 = *s++;\ - src2 = *s++;\ - src3 = *s++;\ - OP(dst[0], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\ - src4 = *s++;\ - OP(dst[1], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\ - src5 = *s++;\ - OP(dst[2], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\ - src6 = *s++;\ - OP(dst[3], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\ - if (w>4) { /* it optimized */ \ - int src7,src8,src9,src10; \ - src7 = *s++;\ - OP(dst[4], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\ - src8 = *s++;\ - OP(dst[5], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\ - src9 = *s++;\ - OP(dst[6], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\ - src10 = *s++;\ - OP(dst[7], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\ - if (w>8) { \ - int src11,src12,src13,src14,src15,src16,src17,src18; \ - src11 = *s++;\ - OP(dst[8] , (src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));\ - src12 = *s++;\ - OP(dst[9] , (src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));\ - src13 = *s++;\ - OP(dst[10], (src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));\ - src14 = *s++;\ - OP(dst[11], (src11+src12)*20 - (src10+src13)*5 + (src9 +src14));\ - src15 = *s++;\ - OP(dst[12], (src12+src13)*20 - (src11+src14)*5 + (src10+src15));\ - src16 = *s++;\ - OP(dst[13], (src13+src14)*20 - (src12+src15)*5 + (src11+src16));\ - src17 = *s++;\ - OP(dst[14], (src14+src15)*20 - (src13+src16)*5 + (src12+src17));\ - src18 = *s++;\ - OP(dst[15], (src15+src16)*20 - (src14+src17)*5 + (src13+src18));\ - } \ - } \ - dst+=dstStride;\ - src+=srcStride;\ - }while(--h);\ -}\ -\ -static inline void OPNAME ## h264_qpel_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,int w,int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - do{\ - int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\ - uint8_t *s = src-2*srcStride,*d=dst;\ - srcB = *s; s+=srcStride;\ - srcA = *s; s+=srcStride;\ - src0 = *s; s+=srcStride;\ - src1 = *s; s+=srcStride;\ - src2 = *s; s+=srcStride;\ - src3 = *s; s+=srcStride;\ - OP(*d, (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));d+=dstStride;\ - src4 = *s; s+=srcStride;\ - OP(*d, (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));d+=dstStride;\ - src5 = *s; s+=srcStride;\ - OP(*d, (src2+src3)*20 - (src1+src4)*5 + (src0+src5));d+=dstStride;\ - src6 = *s; s+=srcStride;\ - OP(*d, (src3+src4)*20 - (src2+src5)*5 + (src1+src6));d+=dstStride;\ - if (h>4) { \ - int src7,src8,src9,src10; \ - src7 = *s; s+=srcStride;\ - OP(*d, (src4+src5)*20 - (src3+src6)*5 + (src2+src7));d+=dstStride;\ - src8 = *s; s+=srcStride;\ - OP(*d, (src5+src6)*20 - (src4+src7)*5 + (src3+src8));d+=dstStride;\ - src9 = *s; s+=srcStride;\ - OP(*d, (src6+src7)*20 - (src5+src8)*5 + (src4+src9));d+=dstStride;\ - src10 = *s; s+=srcStride;\ - OP(*d, (src7+src8)*20 - (src6+src9)*5 + (src5+src10));d+=dstStride;\ - if (h>8) { \ - int src11,src12,src13,src14,src15,src16,src17,src18; \ - src11 = *s; s+=srcStride;\ - OP(*d , (src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));d+=dstStride;\ - src12 = *s; s+=srcStride;\ - OP(*d , (src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));d+=dstStride;\ - src13 = *s; s+=srcStride;\ - OP(*d, (src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));d+=dstStride;\ - src14 = *s; s+=srcStride;\ - OP(*d, (src11+src12)*20 - (src10+src13)*5 + (src9 +src14));d+=dstStride;\ - src15 = *s; s+=srcStride;\ - OP(*d, (src12+src13)*20 - (src11+src14)*5 + (src10+src15));d+=dstStride;\ - src16 = *s; s+=srcStride;\ - OP(*d, (src13+src14)*20 - (src12+src15)*5 + (src11+src16));d+=dstStride;\ - src17 = *s; s+=srcStride;\ - OP(*d, (src14+src15)*20 - (src13+src16)*5 + (src12+src17));d+=dstStride;\ - src18 = *s; s+=srcStride;\ - OP(*d, (src15+src16)*20 - (src14+src17)*5 + (src13+src18));d+=dstStride;\ - } \ - } \ - dst++;\ - src++;\ - }while(--w);\ -}\ -\ -static inline void OPNAME ## h264_qpel_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride,int w,int h){\ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ - int i;\ - src -= 2*srcStride;\ - i= h+5; \ - do {\ - int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\ - uint8_t *s = src-2;\ - srcB = *s++;\ - srcA = *s++;\ - src0 = *s++;\ - src1 = *s++;\ - src2 = *s++;\ - src3 = *s++;\ - tmp[0] = ((src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\ - src4 = *s++;\ - tmp[1] = ((src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\ - src5 = *s++;\ - tmp[2] = ((src2+src3)*20 - (src1+src4)*5 + (src0+src5));\ - src6 = *s++;\ - tmp[3] = ((src3+src4)*20 - (src2+src5)*5 + (src1+src6));\ - if (w>4) { /* it optimized */ \ - int src7,src8,src9,src10; \ - src7 = *s++;\ - tmp[4] = ((src4+src5)*20 - (src3+src6)*5 + (src2+src7));\ - src8 = *s++;\ - tmp[5] = ((src5+src6)*20 - (src4+src7)*5 + (src3+src8));\ - src9 = *s++;\ - tmp[6] = ((src6+src7)*20 - (src5+src8)*5 + (src4+src9));\ - src10 = *s++;\ - tmp[7] = ((src7+src8)*20 - (src6+src9)*5 + (src5+src10));\ - if (w>8) { \ - int src11,src12,src13,src14,src15,src16,src17,src18; \ - src11 = *s++;\ - tmp[8] = ((src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));\ - src12 = *s++;\ - tmp[9] = ((src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));\ - src13 = *s++;\ - tmp[10] = ((src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));\ - src14 = *s++;\ - tmp[11] = ((src11+src12)*20 - (src10+src13)*5 + (src9 +src14));\ - src15 = *s++;\ - tmp[12] = ((src12+src13)*20 - (src11+src14)*5 + (src10+src15));\ - src16 = *s++;\ - tmp[13] = ((src13+src14)*20 - (src12+src15)*5 + (src11+src16));\ - src17 = *s++;\ - tmp[14] = ((src14+src15)*20 - (src13+src16)*5 + (src12+src17));\ - src18 = *s++;\ - tmp[15] = ((src15+src16)*20 - (src14+src17)*5 + (src13+src18));\ - } \ - } \ - tmp+=tmpStride;\ - src+=srcStride;\ - }while(--i);\ - tmp -= tmpStride*(h+5-2);\ - i = w; \ - do {\ - int tmpB,tmpA,tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6;\ - int16_t *s = tmp-2*tmpStride; \ - uint8_t *d=dst;\ - tmpB = *s; s+=tmpStride;\ - tmpA = *s; s+=tmpStride;\ - tmp0 = *s; s+=tmpStride;\ - tmp1 = *s; s+=tmpStride;\ - tmp2 = *s; s+=tmpStride;\ - tmp3 = *s; s+=tmpStride;\ - OP2(*d, (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));d+=dstStride;\ - tmp4 = *s; s+=tmpStride;\ - OP2(*d, (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));d+=dstStride;\ - tmp5 = *s; s+=tmpStride;\ - OP2(*d, (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));d+=dstStride;\ - tmp6 = *s; s+=tmpStride;\ - OP2(*d, (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));d+=dstStride;\ - if (h>4) { \ - int tmp7,tmp8,tmp9,tmp10; \ - tmp7 = *s; s+=tmpStride;\ - OP2(*d, (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));d+=dstStride;\ - tmp8 = *s; s+=tmpStride;\ - OP2(*d, (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));d+=dstStride;\ - tmp9 = *s; s+=tmpStride;\ - OP2(*d, (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));d+=dstStride;\ - tmp10 = *s; s+=tmpStride;\ - OP2(*d, (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));d+=dstStride;\ - if (h>8) { \ - int tmp11,tmp12,tmp13,tmp14,tmp15,tmp16,tmp17,tmp18; \ - tmp11 = *s; s+=tmpStride;\ - OP2(*d , (tmp8 +tmp9 )*20 - (tmp7 +tmp10)*5 + (tmp6 +tmp11));d+=dstStride;\ - tmp12 = *s; s+=tmpStride;\ - OP2(*d , (tmp9 +tmp10)*20 - (tmp8 +tmp11)*5 + (tmp7 +tmp12));d+=dstStride;\ - tmp13 = *s; s+=tmpStride;\ - OP2(*d, (tmp10+tmp11)*20 - (tmp9 +tmp12)*5 + (tmp8 +tmp13));d+=dstStride;\ - tmp14 = *s; s+=tmpStride;\ - OP2(*d, (tmp11+tmp12)*20 - (tmp10+tmp13)*5 + (tmp9 +tmp14));d+=dstStride;\ - tmp15 = *s; s+=tmpStride;\ - OP2(*d, (tmp12+tmp13)*20 - (tmp11+tmp14)*5 + (tmp10+tmp15));d+=dstStride;\ - tmp16 = *s; s+=tmpStride;\ - OP2(*d, (tmp13+tmp14)*20 - (tmp12+tmp15)*5 + (tmp11+tmp16));d+=dstStride;\ - tmp17 = *s; s+=tmpStride;\ - OP2(*d, (tmp14+tmp15)*20 - (tmp13+tmp16)*5 + (tmp12+tmp17));d+=dstStride;\ - tmp18 = *s; s+=tmpStride;\ - OP2(*d, (tmp15+tmp16)*20 - (tmp14+tmp17)*5 + (tmp13+tmp18));d+=dstStride;\ - } \ - } \ - dst++;\ - tmp++;\ - }while(--i);\ -}\ -\ -static void OPNAME ## h264_qpel4_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,4,4); \ -}\ -static void OPNAME ## h264_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,8,8); \ -}\ -static void OPNAME ## h264_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,16,16); \ -}\ -\ -static void OPNAME ## h264_qpel4_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,4,4); \ -}\ -static void OPNAME ## h264_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,8,8); \ -}\ -static void OPNAME ## h264_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,16,16); \ -}\ -static void OPNAME ## h264_qpel4_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ - OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,4,4); \ -}\ -static void OPNAME ## h264_qpel8_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ - OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,8,8); \ -}\ -static void OPNAME ## h264_qpel16_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ - OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,16,16); \ -}\ - -#define H264_MC(OPNAME, SIZE) \ -static void OPNAME ## h264_qpel ## SIZE ## _mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels ## SIZE ## _c(dst, src, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_aligned2(dst, src, half, stride, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t half[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_aligned2(dst, src+1, half, stride, stride, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - uint8_t half[SIZE*SIZE];\ - copy_block ## SIZE (full, src - stride*2, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(half, full_mid, SIZE, SIZE);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, full_mid, half, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - copy_block ## SIZE (full, src - stride*2, SIZE, stride, SIZE + 5);\ - OPNAME ## h264_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - uint8_t half[SIZE*SIZE];\ - copy_block ## SIZE (full, src - stride*2, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(half, full_mid, SIZE, SIZE);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, full_mid+SIZE, half, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - uint8_t halfH[SIZE*SIZE];\ - uint8_t halfV[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\ - copy_block ## SIZE (full, src - stride*2, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - uint8_t halfH[SIZE*SIZE];\ - uint8_t halfV[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\ - copy_block ## SIZE (full, src - stride*2 + 1, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - uint8_t halfH[SIZE*SIZE];\ - uint8_t halfV[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\ - copy_block ## SIZE (full, src - stride*2, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - uint8_t halfH[SIZE*SIZE];\ - uint8_t halfV[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\ - copy_block ## SIZE (full, src - stride*2 + 1, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\ - int16_t tmp[SIZE*(SIZE+5)];\ - OPNAME ## h264_qpel ## SIZE ## _hv_lowpass(dst, tmp, src, stride, SIZE, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\ - int16_t tmp[SIZE*(SIZE+5)];\ - uint8_t halfH[SIZE*SIZE];\ - uint8_t halfHV[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\ - int16_t tmp[SIZE*(SIZE+5)];\ - uint8_t halfH[SIZE*SIZE];\ - uint8_t halfHV[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\ - put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - int16_t tmp[SIZE*(SIZE+5)];\ - uint8_t halfV[SIZE*SIZE];\ - uint8_t halfHV[SIZE*SIZE];\ - copy_block ## SIZE (full, src - stride*2, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\ - put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\ - uint8_t full[SIZE*(SIZE+5)];\ - uint8_t * const full_mid= full + SIZE*2;\ - int16_t tmp[SIZE*(SIZE+5)];\ - uint8_t halfV[SIZE*SIZE];\ - uint8_t halfHV[SIZE*SIZE];\ - copy_block ## SIZE (full, src - stride*2 + 1, SIZE, stride, SIZE + 5);\ - put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\ - put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\ -}\ - -#define op_avg(a, b) a = (((a)+cm[((b) + 16)>>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_, 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 - -static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - do{ - int src_1,src0,src1,src2,src3,src4,src5,src6,src7,src8,src9; - uint8_t *s = src; - src_1 = s[-1]; - src0 = *s++; - src1 = *s++; - src2 = *s++; - dst[0]= cm[(9*(src0 + src1) - (src_1 + src2) + 8)>>4]; - src3 = *s++; - dst[1]= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4]; - src4 = *s++; - dst[2]= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4]; - src5 = *s++; - dst[3]= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4]; - src6 = *s++; - dst[4]= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4]; - src7 = *s++; - dst[5]= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4]; - src8 = *s++; - dst[6]= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4]; - src9 = *s++; - dst[7]= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4]; - dst+=dstStride; - src+=srcStride; - }while(--h); -} - -static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - do{ - int src_1,src0,src1,src2,src3,src4,src5,src6,src7,src8,src9; - uint8_t *s = src,*d = dst; - src_1 = *(s-srcStride); - src0 = *s; s+=srcStride; - src1 = *s; s+=srcStride; - src2 = *s; s+=srcStride; - *d= cm[(9*(src0 + src1) - (src_1 + src2) + 8)>>4]; d+=dstStride; - src3 = *s; s+=srcStride; - *d= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4]; d+=dstStride; - src4 = *s; s+=srcStride; - *d= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4]; d+=dstStride; - src5 = *s; s+=srcStride; - *d= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4]; d+=dstStride; - src6 = *s; s+=srcStride; - *d= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4]; d+=dstStride; - src7 = *s; s+=srcStride; - *d= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4]; d+=dstStride; - src8 = *s; s+=srcStride; - *d= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4]; d+=dstStride; - src9 = *s; - *d= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4]; d+=dstStride; - src++; - dst++; - }while(--w); -} - -static void put_mspel8_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){ - put_pixels8_c(dst, src, stride, 8); -} - -static void put_mspel8_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){ - uint8_t half[64]; - wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); - put_pixels8_l2_aligned2(dst, src, half, stride, stride, 8, 8); -} - -static void put_mspel8_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){ - wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8); -} - -static void put_mspel8_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){ - uint8_t half[64]; - wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); - put_pixels8_l2_aligned2(dst, src+1, half, stride, stride, 8, 8); -} - -static void put_mspel8_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){ - wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8); -} - -static void put_mspel8_mc12_sh4(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_aligned(dst, halfV, halfHV, stride, 8, 8, 8); -} -static void put_mspel8_mc32_sh4(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_aligned(dst, halfV, halfHV, stride, 8, 8, 8); -} -static void put_mspel8_mc22_sh4(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); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/sh4/sh4.h b/tizen/distrib/ffmpeg/libavcodec/sh4/sh4.h deleted file mode 100644 index 5d46540..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sh4/sh4.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2008 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SH4_SH4_H -#define AVCODEC_SH4_SH4_H - -#ifdef __SH4__ -# define fp_single_enter(fpscr) \ - do { \ - __asm__ volatile ("sts fpscr, %0 \n\t" \ - "and %1, %0 \n\t" \ - "lds %0, fpscr \n\t" \ - : "=&r"(fpscr) : "r"(~(1<<19))); \ - } while (0) - -# define fp_single_leave(fpscr) \ - do { \ - __asm__ volatile ("or %1, %0 \n\t" \ - "lds %0, fpscr \n\t" \ - : "+r"(fpscr) : "r"(1<<19)); \ - } while (0) -#else -# define fp_single_enter(fpscr) ((void)fpscr) -# define fp_single_leave(fpscr) -#endif - -#endif /* AVCODEC_SH4_SH4_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/shorten.c b/tizen/distrib/ffmpeg/libavcodec/shorten.c deleted file mode 100644 index 7e17f18..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/shorten.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Shorten decoder - * Copyright (c) 2005 Jeff Muizelaar - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Shorten decoder - * @author Jeff Muizelaar - * - */ - -#define DEBUG -#include -#include "avcodec.h" -#include "get_bits.h" -#include "golomb.h" - -#define MAX_CHANNELS 8 -#define MAX_BLOCKSIZE 65535 - -#define OUT_BUFFER_SIZE 16384 - -#define ULONGSIZE 2 - -#define WAVE_FORMAT_PCM 0x0001 - -#define DEFAULT_BLOCK_SIZE 256 - -#define TYPESIZE 4 -#define CHANSIZE 0 -#define LPCQSIZE 2 -#define ENERGYSIZE 3 -#define BITSHIFTSIZE 2 - -#define TYPE_S16HL 3 -#define TYPE_S16LH 5 - -#define NWRAP 3 -#define NSKIPSIZE 1 - -#define LPCQUANT 5 -#define V2LPCQOFFSET (1 << LPCQUANT) - -#define FNSIZE 2 -#define FN_DIFF0 0 -#define FN_DIFF1 1 -#define FN_DIFF2 2 -#define FN_DIFF3 3 -#define FN_QUIT 4 -#define FN_BLOCKSIZE 5 -#define FN_BITSHIFT 6 -#define FN_QLPC 7 -#define FN_ZERO 8 -#define FN_VERBATIM 9 - -#define VERBATIM_CKSIZE_SIZE 5 -#define VERBATIM_BYTE_SIZE 8 -#define CANONICAL_HEADER_SIZE 44 - -typedef struct ShortenContext { - AVCodecContext *avctx; - GetBitContext gb; - - int min_framesize, max_framesize; - int channels; - - int32_t *decoded[MAX_CHANNELS]; - int32_t *offset[MAX_CHANNELS]; - uint8_t *bitstream; - int bitstream_size; - int bitstream_index; - unsigned int allocated_bitstream_size; - int header_size; - uint8_t header[OUT_BUFFER_SIZE]; - int version; - int cur_chan; - int bitshift; - int nmean; - int internal_ftype; - int nwrap; - int blocksize; - int bitindex; - int32_t lpcqoffset; -} ShortenContext; - -static av_cold int shorten_decode_init(AVCodecContext * avctx) -{ - ShortenContext *s = avctx->priv_data; - s->avctx = avctx; - avctx->sample_fmt = SAMPLE_FMT_S16; - - return 0; -} - -static int allocate_buffers(ShortenContext *s) -{ - int i, chan; - for (chan=0; chanchannels; chan++) { - if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){ - av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n"); - return -1; - } - if(s->blocksize + s->nwrap >= UINT_MAX/sizeof(int32_t) || s->blocksize + s->nwrap <= (unsigned)s->nwrap){ - av_log(s->avctx, AV_LOG_ERROR, "s->blocksize + s->nwrap too large\n"); - return -1; - } - - s->offset[chan] = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean)); - - s->decoded[chan] = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); - for (i=0; inwrap; i++) - s->decoded[chan][i] = 0; - s->decoded[chan] += s->nwrap; - } - return 0; -} - - -static inline unsigned int get_uint(ShortenContext *s, int k) -{ - if (s->version != 0) - k = get_ur_golomb_shorten(&s->gb, ULONGSIZE); - return get_ur_golomb_shorten(&s->gb, k); -} - - -static void fix_bitshift(ShortenContext *s, int32_t *buffer) -{ - int i; - - if (s->bitshift != 0) - for (i = 0; i < s->blocksize; i++) - buffer[s->nwrap + i] <<= s->bitshift; -} - - -static void init_offset(ShortenContext *s) -{ - int32_t mean = 0; - int chan, i; - int nblock = FFMAX(1, s->nmean); - /* initialise offset */ - switch (s->internal_ftype) - { - case TYPE_S16HL: - case TYPE_S16LH: - mean = 0; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown audio type"); - abort(); - } - - for (chan = 0; chan < s->channels; chan++) - for (i = 0; i < nblock; i++) - s->offset[chan][i] = mean; -} - -static inline int get_le32(GetBitContext *gb) -{ - return bswap_32(get_bits_long(gb, 32)); -} - -static inline short get_le16(GetBitContext *gb) -{ - return bswap_16(get_bits_long(gb, 16)); -} - -static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header_size) -{ - GetBitContext hb; - int len; - int chunk_size; - short wave_format; - - init_get_bits(&hb, header, header_size*8); - if (get_le32(&hb) != MKTAG('R','I','F','F')) { - av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); - return -1; - } - - chunk_size = get_le32(&hb); - - if (get_le32(&hb) != MKTAG('W','A','V','E')) { - av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n"); - return -1; - } - - while (get_le32(&hb) != MKTAG('f','m','t',' ')) { - len = get_le32(&hb); - skip_bits(&hb, 8*len); - } - len = get_le32(&hb); - - if (len < 16) { - av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n"); - return -1; - } - - wave_format = get_le16(&hb); - - switch (wave_format) { - case WAVE_FORMAT_PCM: - break; - default: - av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n"); - return -1; - } - - avctx->channels = get_le16(&hb); - avctx->sample_rate = get_le32(&hb); - avctx->bit_rate = get_le32(&hb) * 8; - avctx->block_align = get_le16(&hb); - avctx->bits_per_coded_sample = get_le16(&hb); - - if (avctx->bits_per_coded_sample != 16) { - av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n"); - return -1; - } - - len -= 16; - if (len > 0) - av_log(avctx, AV_LOG_INFO, "%d header bytes unparsed\n", len); - - return 0; -} - -static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) { - int i, chan; - for (i=0; igb, LPCQUANT); - - for (i=0; i < s->blocksize; i++) { - sum = s->lpcqoffset; - for (j=0; jdecoded[channel][i-j-1]; - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> LPCQUANT); - } -} - - -static int shorten_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - ShortenContext *s = avctx->priv_data; - int i, input_buf_size = 0; - int16_t *samples = data; - if(s->max_framesize == 0){ - s->max_framesize= 1024; // 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= FFMIN(buf_size, s->max_framesize - s->bitstream_size); - 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){ - //dprintf(avctx, "wanna more data ... %d\n", buf_size); - *data_size = 0; - return input_buf_size; - } - } - init_get_bits(&s->gb, buf, buf_size*8); - skip_bits(&s->gb, s->bitindex); - if (!s->blocksize) - { - int maxnlpc = 0; - /* shorten signature */ - if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) { - av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n"); - return -1; - } - - s->lpcqoffset = 0; - s->blocksize = DEFAULT_BLOCK_SIZE; - s->channels = 1; - s->nmean = -1; - s->version = get_bits(&s->gb, 8); - s->internal_ftype = get_uint(s, TYPESIZE); - - s->channels = get_uint(s, CHANSIZE); - if (s->channels > MAX_CHANNELS) { - av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); - return -1; - } - - /* get blocksize if version > 0 */ - if (s->version > 0) { - int skip_bytes; - s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE)); - maxnlpc = get_uint(s, LPCQSIZE); - s->nmean = get_uint(s, 0); - - skip_bytes = get_uint(s, NSKIPSIZE); - for (i=0; igb, 8); - } - } - s->nwrap = FFMAX(NWRAP, maxnlpc); - - if (allocate_buffers(s)) - return -1; - - init_offset(s); - - if (s->version > 1) - s->lpcqoffset = V2LPCQOFFSET; - - if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) { - av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n"); - return -1; - } - - s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); - if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size); - return -1; - } - - for (i=0; iheader_size; i++) - s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); - - if (decode_wave_header(avctx, s->header, s->header_size) < 0) - return -1; - - s->cur_chan = 0; - s->bitshift = 0; - } - else - { - int cmd; - int len; - cmd = get_ur_golomb_shorten(&s->gb, FNSIZE); - switch (cmd) { - case FN_ZERO: - case FN_DIFF0: - case FN_DIFF1: - case FN_DIFF2: - case FN_DIFF3: - case FN_QLPC: - { - int residual_size = 0; - int channel = s->cur_chan; - int32_t coffset; - if (cmd != FN_ZERO) { - residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE); - /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */ - if (s->version == 0) - residual_size--; - } - - if (s->nmean == 0) - coffset = s->offset[channel][0]; - else { - int32_t sum = (s->version < 2) ? 0 : s->nmean / 2; - for (i=0; inmean; i++) - sum += s->offset[channel][i]; - coffset = sum / s->nmean; - if (s->version >= 2) - coffset >>= FFMIN(1, s->bitshift); - } - switch (cmd) { - case FN_ZERO: - for (i=0; iblocksize; i++) - s->decoded[channel][i] = 0; - break; - case FN_DIFF0: - for (i=0; iblocksize; i++) - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + coffset; - break; - case FN_DIFF1: - for (i=0; iblocksize; i++) - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + s->decoded[channel][i - 1]; - break; - case FN_DIFF2: - for (i=0; iblocksize; i++) - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 2*s->decoded[channel][i-1] - - s->decoded[channel][i-2]; - break; - case FN_DIFF3: - for (i=0; iblocksize; i++) - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 3*s->decoded[channel][i-1] - - 3*s->decoded[channel][i-2] - + s->decoded[channel][i-3]; - break; - case FN_QLPC: - { - int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); - for (i=0; idecoded[channel][i - pred_order] -= coffset; - decode_subframe_lpc(s, channel, residual_size, pred_order); - if (coffset != 0) - for (i=0; i < s->blocksize; i++) - s->decoded[channel][i] += coffset; - } - } - if (s->nmean > 0) { - int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2; - for (i=0; iblocksize; i++) - sum += s->decoded[channel][i]; - - for (i=1; inmean; i++) - s->offset[channel][i-1] = s->offset[channel][i]; - - if (s->version < 2) - s->offset[channel][s->nmean - 1] = sum / s->blocksize; - else - s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift; - } - for (i=-s->nwrap; i<0; i++) - s->decoded[channel][i] = s->decoded[channel][i + s->blocksize]; - - fix_bitshift(s, s->decoded[channel]); - - s->cur_chan++; - if (s->cur_chan == s->channels) { - samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded); - s->cur_chan = 0; - goto frame_done; - } - break; - } - break; - case FN_VERBATIM: - len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); - while (len--) { - get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); - } - break; - case FN_BITSHIFT: - s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); - break; - case FN_BLOCKSIZE: - s->blocksize = get_uint(s, av_log2(s->blocksize)); - break; - case FN_QUIT: - *data_size = 0; - return buf_size; - break; - default: - av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd); - return -1; - break; - } - } -frame_done: - *data_size = (int8_t *)samples - (int8_t *)data; - - // s->last_blocksize = s->blocksize; - s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8); - i= (get_bits_count(&s->gb))/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 av_cold int shorten_decode_close(AVCodecContext *avctx) -{ - ShortenContext *s = avctx->priv_data; - int i; - - for (i = 0; i < s->channels; i++) { - s->decoded[i] -= s->nwrap; - av_freep(&s->decoded[i]); - av_freep(&s->offset[i]); - } - av_freep(&s->bitstream); - return 0; -} - -static void shorten_flush(AVCodecContext *avctx){ - ShortenContext *s = avctx->priv_data; - - s->bitstream_size= - s->bitstream_index= 0; -} - -AVCodec shorten_decoder = { - "shorten", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_SHORTEN, - sizeof(ShortenContext), - shorten_decode_init, - NULL, - shorten_decode_close, - shorten_decode_frame, - .flush= shorten_flush, - .long_name= NULL_IF_CONFIG_SMALL("Shorten"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/simple_idct.c b/tizen/distrib/ffmpeg/libavcodec/simple_idct.c deleted file mode 100644 index 475be6d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/simple_idct.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Simple IDCT - * - * Copyright (c) 2001 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * simpleidct in C. - */ - -/* - based upon some outcommented c code from mpeg2dec (idct_mmx.c - written by Aaron Holtzman ) - */ -#include "avcodec.h" -#include "dsputil.h" -#include "mathops.h" -#include "simple_idct.h" - -#if 0 -#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ -#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ -#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ -#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */ -#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ -#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ -#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ -#define ROW_SHIFT 8 -#define COL_SHIFT 17 -#else -#define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 -#define ROW_SHIFT 11 -#define COL_SHIFT 20 // 6 -#endif - -static inline void idctRowCondDC (DCTELEM * row) -{ - int a0, a1, a2, a3, b0, b1, b2, b3; -#if HAVE_FAST_64BIT - uint64_t temp; -#else - uint32_t temp; -#endif - -#if HAVE_FAST_64BIT -#if HAVE_BIGENDIAN -#define ROW0_MASK 0xffff000000000000LL -#else -#define ROW0_MASK 0xffffLL -#endif - if(sizeof(DCTELEM)==2){ - if ( ((((uint64_t *)row)[0] & ~ROW0_MASK) | - ((uint64_t *)row)[1]) == 0) { - temp = (row[0] << 3) & 0xffff; - temp += temp << 16; - temp += temp << 32; - ((uint64_t *)row)[0] = temp; - ((uint64_t *)row)[1] = temp; - return; - } - }else{ - 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; - return; - } - } -#else - if(sizeof(DCTELEM)==2){ - if (!(((uint32_t*)row)[1] | - ((uint32_t*)row)[2] | - ((uint32_t*)row)[3] | - row[1])) { - temp = (row[0] << 3) & 0xffff; - temp += temp << 16; - ((uint32_t*)row)[0]=((uint32_t*)row)[1] = - ((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp; - return; - } - }else{ - 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; - return; - } - } -#endif - - a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1)); - a1 = a0; - a2 = a0; - a3 = a0; - - /* no need to optimize : gcc does it */ - a0 += W2 * row[2]; - a1 += W6 * row[2]; - a2 -= W6 * row[2]; - a3 -= W2 * row[2]; - - b0 = MUL16(W1, row[1]); - MAC16(b0, W3, row[3]); - b1 = MUL16(W3, row[1]); - MAC16(b1, -W7, row[3]); - b2 = MUL16(W5, row[1]); - MAC16(b2, -W1, row[3]); - b3 = MUL16(W7, row[1]); - MAC16(b3, -W5, row[3]); - -#if HAVE_FAST_64BIT - temp = ((uint64_t*)row)[1]; -#else - temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3]; -#endif - if (temp != 0) { - a0 += W4*row[4] + W6*row[6]; - a1 += - W4*row[4] - W2*row[6]; - a2 += - W4*row[4] + W2*row[6]; - a3 += W4*row[4] - W6*row[6]; - - MAC16(b0, W5, row[5]); - MAC16(b0, W7, row[7]); - - MAC16(b1, -W1, row[5]); - MAC16(b1, -W5, row[7]); - - MAC16(b2, W7, row[5]); - MAC16(b2, W3, row[7]); - - MAC16(b3, W3, row[5]); - MAC16(b3, -W1, row[7]); - } - - row[0] = (a0 + b0) >> ROW_SHIFT; - row[7] = (a0 - b0) >> ROW_SHIFT; - row[1] = (a1 + b1) >> ROW_SHIFT; - row[6] = (a1 - b1) >> ROW_SHIFT; - row[2] = (a2 + b2) >> ROW_SHIFT; - row[5] = (a2 - b2) >> ROW_SHIFT; - row[3] = (a3 + b3) >> ROW_SHIFT; - row[4] = (a3 - b3) >> ROW_SHIFT; -} - -static inline void idctSparseColPut (uint8_t *dest, int line_size, - DCTELEM * col) -{ - int a0, a1, a2, a3, b0, b1, b2, b3; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - /* XXX: I did that only to give same values as previous code */ - a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); - a1 = a0; - a2 = a0; - a3 = a0; - - a0 += + W2*col[8*2]; - a1 += + W6*col[8*2]; - a2 += - W6*col[8*2]; - a3 += - W2*col[8*2]; - - b0 = MUL16(W1, col[8*1]); - b1 = MUL16(W3, col[8*1]); - b2 = MUL16(W5, col[8*1]); - b3 = MUL16(W7, col[8*1]); - - MAC16(b0, + W3, col[8*3]); - MAC16(b1, - W7, col[8*3]); - MAC16(b2, - W1, col[8*3]); - MAC16(b3, - W5, col[8*3]); - - 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*5]) { - MAC16(b0, + W5, col[8*5]); - MAC16(b1, - W1, col[8*5]); - MAC16(b2, + W7, col[8*5]); - MAC16(b3, + W3, col[8*5]); - } - - 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*7]) { - MAC16(b0, + W7, col[8*7]); - MAC16(b1, - W5, col[8*7]); - MAC16(b2, + W3, col[8*7]); - MAC16(b3, - W1, col[8*7]); - } - - dest[0] = cm[(a0 + b0) >> COL_SHIFT]; - dest += line_size; - dest[0] = cm[(a1 + b1) >> COL_SHIFT]; - dest += line_size; - dest[0] = cm[(a2 + b2) >> COL_SHIFT]; - dest += line_size; - dest[0] = cm[(a3 + b3) >> COL_SHIFT]; - dest += line_size; - dest[0] = cm[(a3 - b3) >> COL_SHIFT]; - dest += line_size; - dest[0] = cm[(a2 - b2) >> COL_SHIFT]; - dest += line_size; - dest[0] = cm[(a1 - b1) >> COL_SHIFT]; - dest += line_size; - dest[0] = cm[(a0 - b0) >> COL_SHIFT]; -} - -static inline void idctSparseColAdd (uint8_t *dest, int line_size, - DCTELEM * col) -{ - int a0, a1, a2, a3, b0, b1, b2, b3; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - /* XXX: I did that only to give same values as previous code */ - a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); - a1 = a0; - a2 = a0; - a3 = a0; - - a0 += + W2*col[8*2]; - a1 += + W6*col[8*2]; - a2 += - W6*col[8*2]; - a3 += - W2*col[8*2]; - - b0 = MUL16(W1, col[8*1]); - b1 = MUL16(W3, col[8*1]); - b2 = MUL16(W5, col[8*1]); - b3 = MUL16(W7, col[8*1]); - - MAC16(b0, + W3, col[8*3]); - MAC16(b1, - W7, col[8*3]); - MAC16(b2, - W1, col[8*3]); - MAC16(b3, - W5, col[8*3]); - - 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*5]) { - MAC16(b0, + W5, col[8*5]); - MAC16(b1, - W1, col[8*5]); - MAC16(b2, + W7, col[8*5]); - MAC16(b3, + W3, col[8*5]); - } - - 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*7]) { - MAC16(b0, + W7, col[8*7]); - MAC16(b1, - W5, col[8*7]); - MAC16(b2, + W3, col[8*7]); - MAC16(b3, - W1, col[8*7]); - } - - dest[0] = cm[dest[0] + ((a0 + b0) >> COL_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((a1 + b1) >> COL_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((a2 + b2) >> COL_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((a3 + b3) >> COL_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((a3 - b3) >> COL_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((a2 - b2) >> COL_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((a1 - b1) >> COL_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((a0 - b0) >> COL_SHIFT)]; -} - -static inline void idctSparseCol (DCTELEM * col) -{ - int a0, a1, a2, a3, b0, b1, b2, b3; - - /* XXX: I did that only to give same values as previous code */ - a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4)); - a1 = a0; - a2 = a0; - a3 = a0; - - a0 += + W2*col[8*2]; - a1 += + W6*col[8*2]; - a2 += - W6*col[8*2]; - a3 += - W2*col[8*2]; - - b0 = MUL16(W1, col[8*1]); - b1 = MUL16(W3, col[8*1]); - b2 = MUL16(W5, col[8*1]); - b3 = MUL16(W7, col[8*1]); - - MAC16(b0, + W3, col[8*3]); - MAC16(b1, - W7, col[8*3]); - MAC16(b2, - W1, col[8*3]); - MAC16(b3, - W5, col[8*3]); - - 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*5]) { - MAC16(b0, + W5, col[8*5]); - MAC16(b1, - W1, col[8*5]); - MAC16(b2, + W7, col[8*5]); - MAC16(b3, + W3, col[8*5]); - } - - 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*7]) { - MAC16(b0, + W7, col[8*7]); - MAC16(b1, - W5, col[8*7]); - MAC16(b2, + W3, col[8*7]); - MAC16(b3, - W1, col[8*7]); - } - - 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); -} - -void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - for(i=0; i<8; i++) - idctRowCondDC(block + i*8); - - for(i=0; i<8; i++) - idctSparseColPut(dest + i, line_size, block + i); -} - -void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - for(i=0; i<8; i++) - idctRowCondDC(block + i*8); - - for(i=0; i<8; i++) - idctSparseColAdd(dest + i, line_size, block + i); -} - -void ff_simple_idct(DCTELEM *block) -{ - int i; - for(i=0; i<8; i++) - idctRowCondDC(block + i*8); - - for(i=0; i<8; i++) - idctSparseCol(block + i); -} - -/* 2x4x8 idct */ - -#define CN_SHIFT 12 -#define C_FIX(x) ((int)((x) * (1 << CN_SHIFT) + 0.5)) -#define C1 C_FIX(0.6532814824) -#define C2 C_FIX(0.2705980501) - -/* row idct is multiple by 16 * sqrt(2.0), col idct4 is normalized, - and the butterfly must be multiplied by 0.5 * sqrt(2.0) */ -#define C_SHIFT (4+1+12) - -static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col) -{ - int c0, c1, c2, c3, a0, a1, a2, a3; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - a0 = col[8*0]; - a1 = col[8*2]; - a2 = col[8*4]; - a3 = col[8*6]; - c0 = ((a0 + a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1)); - c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1)); - c1 = a1 * C1 + a3 * C2; - c3 = a1 * C2 - a3 * C1; - dest[0] = cm[(c0 + c1) >> C_SHIFT]; - dest += line_size; - dest[0] = cm[(c2 + c3) >> C_SHIFT]; - dest += line_size; - dest[0] = cm[(c2 - c3) >> C_SHIFT]; - dest += line_size; - dest[0] = cm[(c0 - c1) >> C_SHIFT]; -} - -#define BF(k) \ -{\ - int a0, a1;\ - a0 = ptr[k];\ - a1 = ptr[8 + k];\ - ptr[k] = a0 + a1;\ - ptr[8 + k] = a0 - a1;\ -} - -/* only used by DV codec. The input must be interlaced. 128 is added - to the pixels before clamping to avoid systematic error - (1024*sqrt(2)) offset would be needed otherwise. */ -/* XXX: I think a 1.0/sqrt(2) normalization should be needed to - compensate the extra butterfly stage - I don't have the full DV - specification */ -void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - DCTELEM *ptr; - - /* butterfly */ - ptr = block; - for(i=0;i<4;i++) { - BF(0); - BF(1); - BF(2); - BF(3); - BF(4); - BF(5); - BF(6); - BF(7); - ptr += 2 * 8; - } - - /* IDCT8 on each line */ - for(i=0; i<8; i++) { - idctRowCondDC(block + i*8); - } - - /* IDCT4 and store */ - for(i=0;i<8;i++) { - idct4col_put(dest + i, 2 * line_size, block + i); - idct4col_put(dest + line_size + i, 2 * line_size, block + 8 + i); - } -} - -/* 8x4 & 4x8 WMV2 IDCT */ -#undef CN_SHIFT -#undef C_SHIFT -#undef C_FIX -#undef C1 -#undef C2 -#define CN_SHIFT 12 -#define C_FIX(x) ((int)((x) * 1.414213562 * (1 << CN_SHIFT) + 0.5)) -#define C1 C_FIX(0.6532814824) -#define C2 C_FIX(0.2705980501) -#define C3 C_FIX(0.5) -#define C_SHIFT (4+1+12) -static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col) -{ - int c0, c1, c2, c3, a0, a1, a2, a3; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - a0 = col[8*0]; - a1 = col[8*1]; - a2 = col[8*2]; - a3 = col[8*3]; - c0 = (a0 + a2)*C3 + (1 << (C_SHIFT - 1)); - c2 = (a0 - a2)*C3 + (1 << (C_SHIFT - 1)); - c1 = a1 * C1 + a3 * C2; - c3 = a1 * C2 - a3 * C1; - dest[0] = cm[dest[0] + ((c0 + c1) >> C_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((c2 + c3) >> C_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((c2 - c3) >> C_SHIFT)]; - dest += line_size; - dest[0] = cm[dest[0] + ((c0 - c1) >> C_SHIFT)]; -} - -#define RN_SHIFT 15 -#define R_FIX(x) ((int)((x) * 1.414213562 * (1 << RN_SHIFT) + 0.5)) -#define R1 R_FIX(0.6532814824) -#define R2 R_FIX(0.2705980501) -#define R3 R_FIX(0.5) -#define R_SHIFT 11 -static inline void idct4row(DCTELEM *row) -{ - int c0, c1, c2, c3, a0, a1, a2, a3; - //const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - a0 = row[0]; - a1 = row[1]; - a2 = row[2]; - a3 = row[3]; - c0 = (a0 + a2)*R3 + (1 << (R_SHIFT - 1)); - c2 = (a0 - a2)*R3 + (1 << (R_SHIFT - 1)); - c1 = a1 * R1 + a3 * R2; - c3 = a1 * R2 - a3 * R1; - row[0]= (c0 + c1) >> R_SHIFT; - row[1]= (c2 + c3) >> R_SHIFT; - row[2]= (c2 - c3) >> R_SHIFT; - row[3]= (c0 - c1) >> R_SHIFT; -} - -void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - - /* IDCT8 on each line */ - for(i=0; i<4; i++) { - idctRowCondDC(block + i*8); - } - - /* IDCT4 and store */ - for(i=0;i<8;i++) { - idct4col_add(dest + i, line_size, block + i); - } -} - -void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - - /* IDCT4 on each line */ - for(i=0; i<8; i++) { - idct4row(block + i*8); - } - - /* IDCT8 and store */ - for(i=0; i<4; i++){ - idctSparseColAdd(dest + i, line_size, block + i); - } -} - -void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - int i; - - /* IDCT4 on each line */ - for(i=0; i<4; i++) { - idct4row(block + i*8); - } - - /* IDCT4 and store */ - for(i=0; i<4; i++){ - idct4col_add(dest + i, line_size, block + i); - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/simple_idct.h b/tizen/distrib/ffmpeg/libavcodec/simple_idct.h deleted file mode 100644 index 24f6a6d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/simple_idct.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Simple IDCT - * - * Copyright (c) 2001 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * simple idct header. - */ - -#ifndef AVCODEC_SIMPLE_IDCT_H -#define AVCODEC_SIMPLE_IDCT_H - -#include -#include "dsputil.h" - -void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block); -void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block); -void ff_simple_idct_mmx(int16_t *block); -void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block); -void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block); -void ff_simple_idct(DCTELEM *block); - -void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block); - -void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block); -void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block); -void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block); - -#endif /* AVCODEC_SIMPLE_IDCT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sipr.c b/tizen/distrib/ffmpeg/libavcodec/sipr.c deleted file mode 100644 index b76e891..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sipr.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * SIPR / ACELP.NET decoder - * - * Copyright (c) 2008 Vladimir Voroshilov - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "libavutil/mathematics.h" -#include "avcodec.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" -#include "dsputil.h" - -#include "lsp.h" -#include "celp_math.h" -#include "acelp_vectors.h" -#include "acelp_pitch_delay.h" -#include "acelp_filters.h" -#include "celp_filters.h" - -#define MAX_SUBFRAME_COUNT 5 - -#include "sipr.h" -#include "siprdata.h" - -typedef struct { - const char *mode_name; - uint16_t bits_per_frame; - uint8_t subframe_count; - uint8_t frames_per_packet; - float pitch_sharp_factor; - - /* bitstream parameters */ - uint8_t number_of_fc_indexes; - uint8_t ma_predictor_bits; ///< size in bits of the switched MA predictor - - /** size in bits of the i-th stage vector of quantizer */ - uint8_t vq_indexes_bits[5]; - - /** size in bits of the adaptive-codebook index for every subframe */ - uint8_t pitch_delay_bits[5]; - - uint8_t gp_index_bits; - uint8_t fc_index_bits[10]; ///< size in bits of the fixed codebook indexes - uint8_t gc_index_bits; ///< size in bits of the gain codebook indexes -} SiprModeParam; - -static const SiprModeParam modes[MODE_COUNT] = { - [MODE_16k] = { - .mode_name = "16k", - .bits_per_frame = 160, - .subframe_count = SUBFRAME_COUNT_16k, - .frames_per_packet = 1, - .pitch_sharp_factor = 0.00, - - .number_of_fc_indexes = 10, - .ma_predictor_bits = 1, - .vq_indexes_bits = {7, 8, 7, 7, 7}, - .pitch_delay_bits = {9, 6}, - .gp_index_bits = 4, - .fc_index_bits = {4, 5, 4, 5, 4, 5, 4, 5, 4, 5}, - .gc_index_bits = 5 - }, - - [MODE_8k5] = { - .mode_name = "8k5", - .bits_per_frame = 152, - .subframe_count = 3, - .frames_per_packet = 1, - .pitch_sharp_factor = 0.8, - - .number_of_fc_indexes = 3, - .ma_predictor_bits = 0, - .vq_indexes_bits = {6, 7, 7, 7, 5}, - .pitch_delay_bits = {8, 5, 5}, - .gp_index_bits = 0, - .fc_index_bits = {9, 9, 9}, - .gc_index_bits = 7 - }, - - [MODE_6k5] = { - .mode_name = "6k5", - .bits_per_frame = 232, - .subframe_count = 3, - .frames_per_packet = 2, - .pitch_sharp_factor = 0.8, - - .number_of_fc_indexes = 3, - .ma_predictor_bits = 0, - .vq_indexes_bits = {6, 7, 7, 7, 5}, - .pitch_delay_bits = {8, 5, 5}, - .gp_index_bits = 0, - .fc_index_bits = {5, 5, 5}, - .gc_index_bits = 7 - }, - - [MODE_5k0] = { - .mode_name = "5k0", - .bits_per_frame = 296, - .subframe_count = 5, - .frames_per_packet = 2, - .pitch_sharp_factor = 0.85, - - .number_of_fc_indexes = 1, - .ma_predictor_bits = 0, - .vq_indexes_bits = {6, 7, 7, 7, 5}, - .pitch_delay_bits = {8, 5, 8, 5, 5}, - .gp_index_bits = 0, - .fc_index_bits = {10}, - .gc_index_bits = 7 - } -}; - -const float ff_pow_0_5[] = { - 1.0/(1 << 1), 1.0/(1 << 2), 1.0/(1 << 3), 1.0/(1 << 4), - 1.0/(1 << 5), 1.0/(1 << 6), 1.0/(1 << 7), 1.0/(1 << 8), - 1.0/(1 << 9), 1.0/(1 << 10), 1.0/(1 << 11), 1.0/(1 << 12), - 1.0/(1 << 13), 1.0/(1 << 14), 1.0/(1 << 15), 1.0/(1 << 16) -}; - -static void dequant(float *out, const int *idx, const float *cbs[]) -{ - int i; - int stride = 2; - int num_vec = 5; - - for (i = 0; i < num_vec; i++) - memcpy(out + stride*i, cbs[i] + stride*idx[i], stride*sizeof(float)); - -} - -static void lsf_decode_fp(float *lsfnew, float *lsf_history, - const SiprParameters *parm) -{ - int i; - float lsf_tmp[LP_FILTER_ORDER]; - - dequant(lsf_tmp, parm->vq_indexes, lsf_codebooks); - - for (i = 0; i < LP_FILTER_ORDER; i++) - lsfnew[i] = lsf_history[i] * 0.33 + lsf_tmp[i] + mean_lsf[i]; - - ff_sort_nearly_sorted_floats(lsfnew, LP_FILTER_ORDER - 1); - - /* Note that a minimum distance is not enforced between the last value and - the previous one, contrary to what is done in ff_acelp_reorder_lsf() */ - ff_set_min_dist_lsf(lsfnew, LSFQ_DIFF_MIN, LP_FILTER_ORDER - 1); - lsfnew[9] = FFMIN(lsfnew[LP_FILTER_ORDER - 1], 1.3 * M_PI); - - memcpy(lsf_history, lsf_tmp, LP_FILTER_ORDER * sizeof(*lsf_history)); - - for (i = 0; i < LP_FILTER_ORDER - 1; i++) - lsfnew[i] = cos(lsfnew[i]); - lsfnew[LP_FILTER_ORDER - 1] *= 6.153848 / M_PI; -} - -/** Apply pitch lag to the fixed vector (AMR section 6.1.2). */ -static void pitch_sharpening(int pitch_lag_int, float beta, - float *fixed_vector) -{ - int i; - - for (i = pitch_lag_int; i < SUBFR_SIZE; i++) - fixed_vector[i] += beta * fixed_vector[i - pitch_lag_int]; -} - -/** - * Extracts decoding parameters from the input bitstream. - * @param parms parameters structure - * @param pgb pointer to initialized GetBitContext structure - */ -static void decode_parameters(SiprParameters* parms, GetBitContext *pgb, - const SiprModeParam *p) -{ - int i, j; - - parms->ma_pred_switch = get_bits(pgb, p->ma_predictor_bits); - - for (i = 0; i < 5; i++) - parms->vq_indexes[i] = get_bits(pgb, p->vq_indexes_bits[i]); - - for (i = 0; i < p->subframe_count; i++) { - parms->pitch_delay[i] = get_bits(pgb, p->pitch_delay_bits[i]); - parms->gp_index[i] = get_bits(pgb, p->gp_index_bits); - - for (j = 0; j < p->number_of_fc_indexes; j++) - parms->fc_indexes[i][j] = get_bits(pgb, p->fc_index_bits[j]); - - parms->gc_index[i] = get_bits(pgb, p->gc_index_bits); - } -} - -static void lsp2lpc_sipr(const double *lsp, float *Az) -{ - int lp_half_order = LP_FILTER_ORDER >> 1; - double buf[(LP_FILTER_ORDER >> 1) + 1]; - double pa[(LP_FILTER_ORDER >> 1) + 1]; - double *qa = buf + 1; - int i,j; - - qa[-1] = 0.0; - - ff_lsp2polyf(lsp , pa, lp_half_order ); - ff_lsp2polyf(lsp + 1, qa, lp_half_order - 1); - - for (i = 1, j = LP_FILTER_ORDER - 1; i < lp_half_order; i++, j--) { - double paf = pa[i] * (1 + lsp[LP_FILTER_ORDER - 1]); - double qaf = (qa[i] - qa[i-2]) * (1 - lsp[LP_FILTER_ORDER - 1]); - Az[i-1] = (paf + qaf) * 0.5; - Az[j-1] = (paf - qaf) * 0.5; - } - - Az[lp_half_order - 1] = (1.0 + lsp[LP_FILTER_ORDER - 1]) * - pa[lp_half_order] * 0.5; - - Az[LP_FILTER_ORDER - 1] = lsp[LP_FILTER_ORDER - 1]; -} - -static void sipr_decode_lp(float *lsfnew, const float *lsfold, float *Az, - int num_subfr) -{ - double lsfint[LP_FILTER_ORDER]; - int i,j; - float t, t0 = 1.0 / num_subfr; - - t = t0 * 0.5; - for (i = 0; i < num_subfr; i++) { - for (j = 0; j < LP_FILTER_ORDER; j++) - lsfint[j] = lsfold[j] * (1 - t) + t * lsfnew[j]; - - lsp2lpc_sipr(lsfint, Az); - Az += LP_FILTER_ORDER; - t += t0; - } -} - -/** - * Evaluates the adaptive impulse response. - */ -static void eval_ir(const float *Az, int pitch_lag, float *freq, - float pitch_sharp_factor) -{ - float tmp1[SUBFR_SIZE+1], tmp2[LP_FILTER_ORDER+1]; - int i; - - tmp1[0] = 1.; - for (i = 0; i < LP_FILTER_ORDER; i++) { - tmp1[i+1] = Az[i] * ff_pow_0_55[i]; - tmp2[i ] = Az[i] * ff_pow_0_7 [i]; - } - memset(tmp1 + 11, 0, 37 * sizeof(float)); - - ff_celp_lp_synthesis_filterf(freq, tmp2, tmp1, SUBFR_SIZE, - LP_FILTER_ORDER); - - pitch_sharpening(pitch_lag, pitch_sharp_factor, freq); -} - -/** - * Evaluates the convolution of a vector with a sparse vector. - */ -static void convolute_with_sparse(float *out, const AMRFixed *pulses, - const float *shape, int length) -{ - int i, j; - - memset(out, 0, length*sizeof(float)); - for (i = 0; i < pulses->n; i++) - for (j = pulses->x[i]; j < length; j++) - out[j] += pulses->y[i] * shape[j - pulses->x[i]]; -} - -/** - * Apply postfilter, very similar to AMR one. - */ -static void postfilter_5k0(SiprContext *ctx, const float *lpc, float *samples) -{ - float buf[SUBFR_SIZE + LP_FILTER_ORDER]; - float *pole_out = buf + LP_FILTER_ORDER; - float lpc_n[LP_FILTER_ORDER]; - float lpc_d[LP_FILTER_ORDER]; - int i; - - for (i = 0; i < LP_FILTER_ORDER; i++) { - lpc_d[i] = lpc[i] * ff_pow_0_75[i]; - lpc_n[i] = lpc[i] * ff_pow_0_5 [i]; - }; - - memcpy(pole_out - LP_FILTER_ORDER, ctx->postfilter_mem, - LP_FILTER_ORDER*sizeof(float)); - - ff_celp_lp_synthesis_filterf(pole_out, lpc_d, samples, SUBFR_SIZE, - LP_FILTER_ORDER); - - memcpy(ctx->postfilter_mem, pole_out + SUBFR_SIZE - LP_FILTER_ORDER, - LP_FILTER_ORDER*sizeof(float)); - - ff_tilt_compensation(&ctx->tilt_mem, 0.4, pole_out, SUBFR_SIZE); - - memcpy(pole_out - LP_FILTER_ORDER, ctx->postfilter_mem5k0, - LP_FILTER_ORDER*sizeof(*pole_out)); - - memcpy(ctx->postfilter_mem5k0, pole_out + SUBFR_SIZE - LP_FILTER_ORDER, - LP_FILTER_ORDER*sizeof(*pole_out)); - - ff_celp_lp_zero_synthesis_filterf(samples, lpc_n, pole_out, SUBFR_SIZE, - LP_FILTER_ORDER); - -} - -static void decode_fixed_sparse(AMRFixed *fixed_sparse, const int16_t *pulses, - SiprMode mode, int low_gain) -{ - int i; - - switch (mode) { - case MODE_6k5: - for (i = 0; i < 3; i++) { - fixed_sparse->x[i] = 3 * (pulses[i] & 0xf) + i; - fixed_sparse->y[i] = pulses[i] & 0x10 ? -1 : 1; - } - fixed_sparse->n = 3; - break; - case MODE_8k5: - for (i = 0; i < 3; i++) { - fixed_sparse->x[2*i ] = 3 * ((pulses[i] >> 4) & 0xf) + i; - fixed_sparse->x[2*i + 1] = 3 * ( pulses[i] & 0xf) + i; - - fixed_sparse->y[2*i ] = (pulses[i] & 0x100) ? -1.0: 1.0; - - fixed_sparse->y[2*i + 1] = - (fixed_sparse->x[2*i + 1] < fixed_sparse->x[2*i]) ? - -fixed_sparse->y[2*i ] : fixed_sparse->y[2*i]; - } - - fixed_sparse->n = 6; - break; - case MODE_5k0: - default: - if (low_gain) { - int offset = (pulses[0] & 0x200) ? 2 : 0; - int val = pulses[0]; - - for (i = 0; i < 3; i++) { - int index = (val & 0x7) * 6 + 4 - i*2; - - fixed_sparse->y[i] = (offset + index) & 0x3 ? -1 : 1; - fixed_sparse->x[i] = index; - - val >>= 3; - } - fixed_sparse->n = 3; - } else { - int pulse_subset = (pulses[0] >> 8) & 1; - - fixed_sparse->x[0] = ((pulses[0] >> 4) & 15) * 3 + pulse_subset; - fixed_sparse->x[1] = ( pulses[0] & 15) * 3 + pulse_subset + 1; - - fixed_sparse->y[0] = pulses[0] & 0x200 ? -1 : 1; - fixed_sparse->y[1] = -fixed_sparse->y[0]; - fixed_sparse->n = 2; - } - break; - } -} - -static void decode_frame(SiprContext *ctx, SiprParameters *params, - float *out_data) -{ - int i, j; - int subframe_count = modes[ctx->mode].subframe_count; - int frame_size = subframe_count * SUBFR_SIZE; - float Az[LP_FILTER_ORDER * MAX_SUBFRAME_COUNT]; - float *excitation; - float ir_buf[SUBFR_SIZE + LP_FILTER_ORDER]; - float lsf_new[LP_FILTER_ORDER]; - float *impulse_response = ir_buf + LP_FILTER_ORDER; - float *synth = ctx->synth_buf + 16; // 16 instead of LP_FILTER_ORDER for - // memory alignment - int t0_first = 0; - AMRFixed fixed_cb; - - memset(ir_buf, 0, LP_FILTER_ORDER * sizeof(float)); - lsf_decode_fp(lsf_new, ctx->lsf_history, params); - - sipr_decode_lp(lsf_new, ctx->lsp_history, Az, subframe_count); - - memcpy(ctx->lsp_history, lsf_new, LP_FILTER_ORDER * sizeof(float)); - - excitation = ctx->excitation + PITCH_DELAY_MAX + L_INTERPOL; - - for (i = 0; i < subframe_count; i++) { - float *pAz = Az + i*LP_FILTER_ORDER; - float fixed_vector[SUBFR_SIZE]; - int T0,T0_frac; - float pitch_gain, gain_code, avg_energy; - - ff_decode_pitch_lag(&T0, &T0_frac, params->pitch_delay[i], t0_first, i, - ctx->mode == MODE_5k0, 6); - - if (i == 0 || (i == 2 && ctx->mode == MODE_5k0)) - t0_first = T0; - - ff_acelp_interpolatef(excitation, excitation - T0 + (T0_frac <= 0), - ff_b60_sinc, 6, - 2 * ((2 + T0_frac)%3 + 1), LP_FILTER_ORDER, - SUBFR_SIZE); - - decode_fixed_sparse(&fixed_cb, params->fc_indexes[i], ctx->mode, - ctx->past_pitch_gain < 0.8); - - eval_ir(pAz, T0, impulse_response, modes[ctx->mode].pitch_sharp_factor); - - convolute_with_sparse(fixed_vector, &fixed_cb, impulse_response, - SUBFR_SIZE); - - avg_energy = - (0.01 + ff_dot_productf(fixed_vector, fixed_vector, SUBFR_SIZE))/ - SUBFR_SIZE; - - ctx->past_pitch_gain = pitch_gain = gain_cb[params->gc_index[i]][0]; - - gain_code = ff_amr_set_fixed_gain(gain_cb[params->gc_index[i]][1], - avg_energy, ctx->energy_history, - 34 - 15.0/(0.05*M_LN10/M_LN2), - pred); - - ff_weighted_vector_sumf(excitation, excitation, fixed_vector, - pitch_gain, gain_code, SUBFR_SIZE); - - pitch_gain *= 0.5 * pitch_gain; - pitch_gain = FFMIN(pitch_gain, 0.4); - - ctx->gain_mem = 0.7 * ctx->gain_mem + 0.3 * pitch_gain; - ctx->gain_mem = FFMIN(ctx->gain_mem, pitch_gain); - gain_code *= ctx->gain_mem; - - for (j = 0; j < SUBFR_SIZE; j++) - fixed_vector[j] = excitation[j] - gain_code * fixed_vector[j]; - - if (ctx->mode == MODE_5k0) { - postfilter_5k0(ctx, pAz, fixed_vector); - - ff_celp_lp_synthesis_filterf(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i*SUBFR_SIZE, - pAz, excitation, SUBFR_SIZE, - LP_FILTER_ORDER); - } - - ff_celp_lp_synthesis_filterf(synth + i*SUBFR_SIZE, pAz, fixed_vector, - SUBFR_SIZE, LP_FILTER_ORDER); - - excitation += SUBFR_SIZE; - } - - memcpy(synth - LP_FILTER_ORDER, synth + frame_size - LP_FILTER_ORDER, - LP_FILTER_ORDER * sizeof(float)); - - if (ctx->mode == MODE_5k0) { - for (i = 0; i < subframe_count; i++) { - float energy = ff_dot_productf(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i*SUBFR_SIZE, - ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i*SUBFR_SIZE, - SUBFR_SIZE); - ff_adaptive_gain_control(&synth[i * SUBFR_SIZE], - &synth[i * SUBFR_SIZE], energy, - SUBFR_SIZE, 0.9, &ctx->postfilter_agc); - } - - memcpy(ctx->postfilter_syn5k0, ctx->postfilter_syn5k0 + frame_size, - LP_FILTER_ORDER*sizeof(float)); - } - memcpy(ctx->excitation, excitation - PITCH_DELAY_MAX - L_INTERPOL, - (PITCH_DELAY_MAX + L_INTERPOL) * sizeof(float)); - - ff_acelp_apply_order_2_transfer_function(out_data, synth, - (const float[2]) {-1.99997 , 1.000000000}, - (const float[2]) {-1.93307352, 0.935891986}, - 0.939805806, - ctx->highpass_filt_mem, - frame_size); -} - -static av_cold int sipr_decoder_init(AVCodecContext * avctx) -{ - SiprContext *ctx = avctx->priv_data; - int i; - - if (avctx->bit_rate > 12200) ctx->mode = MODE_16k; - else if (avctx->bit_rate > 7500 ) ctx->mode = MODE_8k5; - else if (avctx->bit_rate > 5750 ) ctx->mode = MODE_6k5; - else ctx->mode = MODE_5k0; - - av_log(avctx, AV_LOG_DEBUG, "Mode: %s\n", modes[ctx->mode].mode_name); - - if (ctx->mode == MODE_16k) - ff_sipr_init_16k(ctx); - - for (i = 0; i < LP_FILTER_ORDER; i++) - ctx->lsp_history[i] = cos((i+1) * M_PI / (LP_FILTER_ORDER + 1)); - - for (i = 0; i < 4; i++) - ctx->energy_history[i] = -14; - - avctx->sample_fmt = SAMPLE_FMT_FLT; - - dsputil_init(&ctx->dsp, avctx); - - return 0; -} - -static int sipr_decode_frame(AVCodecContext *avctx, void *datap, - int *data_size, AVPacket *avpkt) -{ - SiprContext *ctx = avctx->priv_data; - const uint8_t *buf=avpkt->data; - SiprParameters parm; - const SiprModeParam *mode_par = &modes[ctx->mode]; - GetBitContext gb; - float *data = datap; - int subframe_size = ctx->mode == MODE_16k ? L_SUBFR_16k : SUBFR_SIZE; - int i; - - ctx->avctx = avctx; - if (avpkt->size < (mode_par->bits_per_frame >> 3)) { - av_log(avctx, AV_LOG_ERROR, - "Error processing packet: packet size (%d) too small\n", - avpkt->size); - - *data_size = 0; - return -1; - } - if (*data_size < subframe_size * mode_par->subframe_count * sizeof(float)) { - av_log(avctx, AV_LOG_ERROR, - "Error processing packet: output buffer (%d) too small\n", - *data_size); - - *data_size = 0; - return -1; - } - - init_get_bits(&gb, buf, mode_par->bits_per_frame); - - for (i = 0; i < mode_par->frames_per_packet; i++) { - decode_parameters(&parm, &gb, mode_par); - - if (ctx->mode == MODE_16k) - ff_sipr_decode_frame_16k(ctx, &parm, data); - else - decode_frame(ctx, &parm, data); - - data += subframe_size * mode_par->subframe_count; - } - - *data_size = mode_par->frames_per_packet * subframe_size * - mode_par->subframe_count * sizeof(float); - - return mode_par->bits_per_frame >> 3; -}; - -AVCodec sipr_decoder = { - "sipr", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_SIPR, - sizeof(SiprContext), - sipr_decoder_init, - NULL, - NULL, - sipr_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("RealAudio SIPR / ACELP.NET"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/sipr.h b/tizen/distrib/ffmpeg/libavcodec/sipr.h deleted file mode 100644 index 66e7696..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sipr.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * SIPR / ACELP.NET decoder - * - * Copyright (c) 2008 Vladimir Voroshilov - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SIPR_H -#define AVCODEC_SIPR_H - -#include "avcodec.h" -#include "dsputil.h" -#include "acelp_pitch_delay.h" - -#define LP_FILTER_ORDER_16k 16 -#define L_SUBFR_16k 80 -#define PITCH_MIN 30 -#define PITCH_MAX 281 - -#define LSFQ_DIFF_MIN (0.0125 * M_PI) - -#define LP_FILTER_ORDER 10 - -/** Number of past samples needed for excitation interpolation */ -#define L_INTERPOL (LP_FILTER_ORDER + 1) - -/** Subframe size for all modes except 16k */ -#define SUBFR_SIZE 48 - -#define SUBFRAME_COUNT_16k 2 - -typedef enum { - MODE_16k, - MODE_8k5, - MODE_6k5, - MODE_5k0, - MODE_COUNT -} SiprMode; - -typedef struct { - AVCodecContext *avctx; - DSPContext dsp; - - SiprMode mode; - - float past_pitch_gain; - float lsf_history[LP_FILTER_ORDER_16k]; - - float excitation[L_INTERPOL + PITCH_MAX + 2 * L_SUBFR_16k]; - - DECLARE_ALIGNED(16, float, synth_buf)[LP_FILTER_ORDER + 5*SUBFR_SIZE + 6]; - - float lsp_history[LP_FILTER_ORDER]; - float gain_mem; - float energy_history[4]; - float highpass_filt_mem[2]; - float postfilter_mem[PITCH_DELAY_MAX + LP_FILTER_ORDER]; - - /* 5k0 */ - float tilt_mem; - float postfilter_agc; - float postfilter_mem5k0[PITCH_DELAY_MAX + LP_FILTER_ORDER]; - float postfilter_syn5k0[LP_FILTER_ORDER + SUBFR_SIZE*5]; - - /* 16k */ - int pitch_lag_prev; - float iir_mem[LP_FILTER_ORDER_16k+1]; - float filt_buf[2][LP_FILTER_ORDER_16k+1]; - float *filt_mem[2]; - float mem_preemph[LP_FILTER_ORDER_16k]; - float synth[LP_FILTER_ORDER_16k]; - double lsp_history_16k[16]; -} SiprContext; - -typedef struct { - int ma_pred_switch; ///< switched moving average predictor - int vq_indexes[5]; - int pitch_delay[5]; ///< pitch delay - int gp_index[5]; ///< adaptive-codebook gain indexes - int16_t fc_indexes[5][10]; ///< fixed-codebook indexes - int gc_index[5]; ///< fixed-codebook gain indexes -} SiprParameters; - -extern const float ff_pow_0_5[16]; - -void ff_sipr_init_16k(SiprContext *ctx); - -void ff_sipr_decode_frame_16k(SiprContext *ctx, SiprParameters *params, - float *out_data); - -#endif /* AVCODEC_SIPR_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sipr16k.c b/tizen/distrib/ffmpeg/libavcodec/sipr16k.c deleted file mode 100644 index 7fb9252..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sipr16k.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * SIPR decoder for the 16k mode - * - * Copyright (c) 2008 Vladimir Voroshilov - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "sipr.h" -#include "libavutil/mathematics.h" -#include "lsp.h" -#include "celp_math.h" -#include "acelp_vectors.h" -#include "acelp_pitch_delay.h" -#include "acelp_filters.h" -#include "celp_filters.h" - -#include "sipr16kdata.h" - -/** - * Convert an lsf vector into an lsp vector. - * - * @param lsf input lsf vector - * @param lsp output lsp vector - */ -static void lsf2lsp(const float *lsf, double *lsp) -{ - int i; - - for (i = 0; i < LP_FILTER_ORDER_16k; i++) - lsp[i] = cosf(lsf[i]); -} - -static void dequant(float *out, const int *idx, const float *cbs[]) -{ - int i; - - for (i = 0; i < 4; i++) - memcpy(out + 3*i, cbs[i] + 3*idx[i], 3*sizeof(float)); - - memcpy(out + 12, cbs[4] + 4*idx[4], 4*sizeof(float)); -} - -static void lsf_decode_fp_16k(float* lsf_history, float* isp_new, - const int* parm, int ma_pred) -{ - int i; - float isp_q[LP_FILTER_ORDER_16k]; - - dequant(isp_q, parm, lsf_codebooks_16k); - - for (i = 0; i < LP_FILTER_ORDER_16k; i++) { - isp_new[i] = (1 - qu[ma_pred]) * isp_q[i] - + qu[ma_pred] * lsf_history[i] - + mean_lsf_16k[i]; - } - - memcpy(lsf_history, isp_q, LP_FILTER_ORDER_16k * sizeof(float)); -} - -static int dec_delay3_1st(int index) -{ - if (index < 390) { - return index + 88; - } else - return 3 * index - 690; -} - -static int dec_delay3_2nd(int index, int pit_min, int pit_max, - int pitch_lag_prev) -{ - if (index < 62) { - int pitch_delay_min = av_clip(pitch_lag_prev - 10, - pit_min, pit_max - 19); - return 3 * pitch_delay_min + index - 2; - } else - return 3 * pitch_lag_prev; -} - -static void postfilter(float *out_data, float* synth, float* iir_mem, - float* filt_mem[2], float* mem_preemph) -{ - float buf[30 + LP_FILTER_ORDER_16k]; - float *tmpbuf = buf + LP_FILTER_ORDER_16k; - float s; - int i; - - for (i = 0; i < LP_FILTER_ORDER_16k; i++) - filt_mem[0][i] = iir_mem[i] * ff_pow_0_5[i]; - - memcpy(tmpbuf - LP_FILTER_ORDER_16k, mem_preemph, - LP_FILTER_ORDER_16k*sizeof(*buf)); - - ff_celp_lp_synthesis_filterf(tmpbuf, filt_mem[1], synth, 30, - LP_FILTER_ORDER_16k); - - memcpy(synth - LP_FILTER_ORDER_16k, mem_preemph, - LP_FILTER_ORDER_16k * sizeof(*synth)); - - ff_celp_lp_synthesis_filterf(synth, filt_mem[0], synth, 30, - LP_FILTER_ORDER_16k); - - memcpy(out_data + 30 - LP_FILTER_ORDER_16k, - synth + 30 - LP_FILTER_ORDER_16k, - LP_FILTER_ORDER_16k * sizeof(*synth)); - - ff_celp_lp_synthesis_filterf(out_data + 30, filt_mem[0], - synth + 30, 2 * L_SUBFR_16k - 30, - LP_FILTER_ORDER_16k); - - - memcpy(mem_preemph, out_data + 2*L_SUBFR_16k - LP_FILTER_ORDER_16k, - LP_FILTER_ORDER_16k * sizeof(*synth)); - - FFSWAP(float *, filt_mem[0], filt_mem[1]); - for (i = 0, s = 0; i < 30; i++, s += 1.0/30) - out_data[i] = tmpbuf[i] + s * (synth[i] - tmpbuf[i]); -} - -/** - * Floating point version of ff_acelp_lp_decode(). - */ -static void acelp_lp_decodef(float *lp_1st, float *lp_2nd, - const double *lsp_2nd, const double *lsp_prev) -{ - double lsp_1st[LP_FILTER_ORDER_16k]; - int i; - - /* LSP values for first subframe (3.2.5 of G.729, Equation 24) */ - for (i = 0; i < LP_FILTER_ORDER_16k; i++) - lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) * 0.5; - - ff_acelp_lspd2lpc(lsp_1st, lp_1st, LP_FILTER_ORDER_16k >> 1); - - /* LSP values for second subframe (3.2.5 of G.729) */ - ff_acelp_lspd2lpc(lsp_2nd, lp_2nd, LP_FILTER_ORDER_16k >> 1); -} - -/** - * Floating point version of ff_acelp_decode_gain_code(). - */ -static float acelp_decode_gain_codef(float gain_corr_factor, const float *fc_v, - float mr_energy, const float *quant_energy, - const float *ma_prediction_coeff, - int subframe_size, int ma_pred_order) -{ - mr_energy += - ff_dot_productf(quant_energy, ma_prediction_coeff, ma_pred_order); - - mr_energy = gain_corr_factor * exp(M_LN10 / 20. * mr_energy) / - sqrt((0.01 + ff_dot_productf(fc_v, fc_v, subframe_size))); - return mr_energy; -} - -#define DIVIDE_BY_3(x) ((x) * 10923 >> 15) - -void ff_sipr_decode_frame_16k(SiprContext *ctx, SiprParameters *params, - float *out_data) -{ - int frame_size = SUBFRAME_COUNT_16k * L_SUBFR_16k; - float *synth = ctx->synth_buf + LP_FILTER_ORDER_16k; - float lsf_new[LP_FILTER_ORDER_16k]; - double lsp_new[LP_FILTER_ORDER_16k]; - float Az[2][LP_FILTER_ORDER_16k]; - float fixed_vector[L_SUBFR_16k]; - float pitch_fac, gain_code; - - int i; - int pitch_delay_3x; - - float *excitation = ctx->excitation + 292; - - lsf_decode_fp_16k(ctx->lsf_history, lsf_new, params->vq_indexes, - params->ma_pred_switch); - - ff_set_min_dist_lsf(lsf_new, LSFQ_DIFF_MIN / 2, LP_FILTER_ORDER_16k); - - lsf2lsp(lsf_new, lsp_new); - - acelp_lp_decodef(Az[0], Az[1], lsp_new, ctx->lsp_history_16k); - - memcpy(ctx->lsp_history_16k, lsp_new, LP_FILTER_ORDER_16k * sizeof(double)); - - memcpy(synth - LP_FILTER_ORDER_16k, ctx->synth, - LP_FILTER_ORDER_16k * sizeof(*synth)); - - for (i = 0; i < SUBFRAME_COUNT_16k; i++) { - int i_subfr = i * L_SUBFR_16k; - AMRFixed f; - float gain_corr_factor; - int pitch_delay_int; - int pitch_delay_frac; - - if (!i) { - pitch_delay_3x = dec_delay3_1st(params->pitch_delay[i]); - } else - pitch_delay_3x = dec_delay3_2nd(params->pitch_delay[i], - PITCH_MIN, PITCH_MAX, - ctx->pitch_lag_prev); - - pitch_fac = gain_pitch_cb_16k[params->gp_index[i]]; - f.pitch_fac = FFMIN(pitch_fac, 1.0); - f.pitch_lag = DIVIDE_BY_3(pitch_delay_3x+1); - ctx->pitch_lag_prev = f.pitch_lag; - - pitch_delay_int = DIVIDE_BY_3(pitch_delay_3x + 2); - pitch_delay_frac = pitch_delay_3x + 2 - 3*pitch_delay_int; - - ff_acelp_interpolatef(&excitation[i_subfr], - &excitation[i_subfr] - pitch_delay_int + 1, - sinc_win, 3, pitch_delay_frac + 1, - LP_FILTER_ORDER, L_SUBFR_16k); - - - memset(fixed_vector, 0, sizeof(fixed_vector)); - - ff_decode_10_pulses_35bits(params->fc_indexes[i], &f, - ff_fc_4pulses_8bits_tracks_13, 5, 4); - - ff_set_fixed_vector(fixed_vector, &f, 1.0, L_SUBFR_16k); - - gain_corr_factor = gain_cb_16k[params->gc_index[i]]; - gain_code = gain_corr_factor * - acelp_decode_gain_codef(sqrt(L_SUBFR_16k), fixed_vector, - 19.0 - 15.0/(0.05*M_LN10/M_LN2), - pred_16k, ctx->energy_history, - L_SUBFR_16k, 2); - - ctx->energy_history[1] = ctx->energy_history[0]; - ctx->energy_history[0] = 20.0 * log10f(gain_corr_factor); - - ff_weighted_vector_sumf(&excitation[i_subfr], &excitation[i_subfr], - fixed_vector, pitch_fac, - gain_code, L_SUBFR_16k); - - ff_celp_lp_synthesis_filterf(synth + i_subfr, Az[i], - &excitation[i_subfr], L_SUBFR_16k, - LP_FILTER_ORDER_16k); - - } - memcpy(ctx->synth, synth + frame_size - LP_FILTER_ORDER_16k, - LP_FILTER_ORDER_16k * sizeof(*synth)); - - memmove(ctx->excitation, ctx->excitation + 2 * L_SUBFR_16k, - (L_INTERPOL+PITCH_MAX) * sizeof(float)); - - postfilter(out_data, synth, ctx->iir_mem, ctx->filt_mem, ctx->mem_preemph); - - memcpy(ctx->iir_mem, Az[1], LP_FILTER_ORDER_16k * sizeof(float)); -} - -void ff_sipr_init_16k(SiprContext *ctx) -{ - int i; - - for (i = 0; i < LP_FILTER_ORDER_16k; i++) - ctx->lsp_history_16k[i] = cos((i + 1) * M_PI/(LP_FILTER_ORDER_16k + 1)); - - ctx->filt_mem[0] = ctx->filt_buf[0]; - ctx->filt_mem[1] = ctx->filt_buf[1]; - - ctx->pitch_lag_prev = 180; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/sipr16kdata.h b/tizen/distrib/ffmpeg/libavcodec/sipr16kdata.h deleted file mode 100644 index 96bf0e9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sipr16kdata.h +++ /dev/null @@ -1,533 +0,0 @@ -/* - * SIPR decoder for the 16k mode - * - * Copyright (c) 2008 Vladimir Voroshilov - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SIPR16KDATA_H -#define AVCODEC_SIPR16KDATA_H - -static const float pred_16k[2] = {0.8, 0.6}; -static const float qu[2] = { 0.12, 0.5}; - -static const float gain_cb_16k[32] = { - 0.07499, 0.10593, 0.14125, 0.18836, - 0.23714, 0.28184, 0.32734, 0.37584, - 0.42170, 0.47315, 0.53088, 0.59566, - 0.66834, 0.74989, 0.84140, 0.94406, - 1.05925, 1.18850, 1.33352, 1.49624, - 1.67880, 1.88365, 2.11349, 2.37137, - 2.66073, 3.05492, 3.54813, 4.21697, - 5.30884, 7.07946, 9.44061, 13.33521, -}; - -static const float gain_pitch_cb_16k[16] = { - 0.00, 0.2, 0.40, 0.5, 0.60, 0.7, 0.75, 0.8, - 0.85, 0.9, 0.95, 1.0, 1.05, 1.1, 1.15, 1.2, -}; - - -static const float mean_lsf_16k[16] = { - 0.131554, 0.246615, 0.435896, 0.644419, - 0.827810, 1.017876, 1.198910, 1.379159, - 1.562157, 1.736908, 1.940719, 2.131963, - 2.347162, 2.521521, 2.717870, 2.847068 -}; - -/** - * Hamming windowed sinc function, like in AMR - */ -static const float sinc_win[40] = { - 0.874475, 0.755101, 0.455962, 0.118807, -0.114223, -0.176778, - -0.101923, 0.015553, 0.086555, 0.078193, 0.018660, -0.037513, - -0.052733, -0.027459, 0.009967, 0.030278, 0.024050, 0.003055, - -0.013862, -0.016162, -0.006725, 0.004212, 0.008634, 0.005721, - -0.000000, -0.003710, -0.003690, -0.001228, 0.001409, 0.002610, -}; - -static const float lsf_cb1_16k[128][3] = { - {-0.089990, -0.172485, -0.203391}, {-0.094710, -0.178687, -0.134483}, - {-0.056398, -0.131952, -0.154500}, {-0.051362, -0.128138, -0.198549}, - {-0.061700, -0.142830, -0.251623}, {-0.041512, -0.115637, -0.229420}, - {-0.036544, -0.107512, -0.173125}, {-0.024158, -0.088450, -0.204144}, - {-0.038690, -0.103368, -0.132674}, {-0.056954, -0.128472, -0.104669}, - {-0.020963, -0.076785, -0.163199}, {-0.012952, -0.077249, -0.128385}, - {-0.032787, -0.097044, -0.093967}, {-0.035214, -0.053838, -0.111940}, - {-0.013850, -0.036926, -0.139328}, {-0.004956, -0.065092, -0.087709}, - {-0.065354, -0.065595, -0.079064}, {-0.023627, -0.081457, -0.054195}, - {-0.027335, -0.035244, -0.068034}, { 0.016555, -0.047075, -0.128286}, - { 0.021066, -0.037252, -0.092041}, { 0.014681, -0.043044, -0.057739}, - {-0.008493, -0.008143, -0.102486}, {-0.002303, -0.061540, -0.022952}, - {-0.006061, -0.014278, -0.033652}, {-0.005276, 0.011246, -0.062762}, - { 0.043411, -0.006303, -0.063730}, { 0.035885, -0.010052, -0.115290}, - { 0.030628, -0.031538, -0.017807}, { 0.022345, 0.028210, -0.032335}, - { 0.026535, 0.027536, -0.091150}, {-0.003365, -0.008077, 0.015687}, - {-0.026013, 0.017493, -0.010355}, { 0.059069, 0.010634, -0.007530}, - { 0.044038, -0.019424, 0.030453}, {-0.036065, -0.034215, -0.007758}, - { 0.022486, 0.042543, 0.027870}, {-0.049985, -0.016085, 0.021768}, - {-0.021715, 0.021168, 0.052076}, {-0.004243, -0.061228, 0.027640}, - {-0.033950, -0.017287, 0.064656}, { 0.016151, 0.000727, 0.062757}, - {-0.063456, -0.043152, 0.056707}, {-0.067715, 0.006126, 0.058178}, - {-0.038931, 0.051673, 0.030636}, {-0.073017, -0.074716, 0.026387}, - {-0.039893, -0.104629, 0.039616}, {-0.073179, -0.074601, 0.082069}, - {-0.066154, -0.027180, 0.099439}, {-0.075167, -0.121149, 0.071938}, - {-0.030382, -0.092582, 0.091067}, {-0.084519, -0.137542, 0.023626}, - {-0.060956, -0.121259, -0.015264}, {-0.030069, -0.093823, -0.008692}, - {-0.063564, -0.065225, -0.025820}, {-0.052074, -0.117595, -0.059689}, - {-0.091652, -0.165173, -0.045573}, {-0.070167, -0.121342, 0.131707}, - {-0.061024, -0.005833, -0.051035}, { 0.007837, -0.051816, 0.074575}, - {-0.070643, -0.053927, 0.149498}, {-0.014358, -0.066681, 0.139708}, - {-0.058186, 0.029576, 0.092923}, {-0.023371, 0.007058, 0.112484}, - {-0.057969, 0.022786, 0.148420}, { 0.029439, -0.017673, 0.121423}, - {-0.015811, 0.056785, 0.091594}, { 0.004347, 0.056680, 0.137848}, - {-0.004464, 0.002342, 0.184013}, { 0.029660, 0.046870, 0.082654}, - { 0.059408, 0.001016, 0.086063}, { 0.055263, 0.027574, 0.155037}, - { 0.062166, 0.064323, 0.117371}, { 0.022967, 0.100050, 0.077227}, - { 0.041795, 0.096343, 0.170421}, { 0.053189, 0.122931, 0.118549}, - { 0.094247, 0.094448, 0.078395}, { 0.082407, 0.033408, 0.041085}, - { 0.096820, 0.115960, 0.149433}, { 0.067804, 0.121849, 0.025336}, - {-0.008421, 0.104316, 0.032314}, { 0.031013, 0.073218, -0.004899}, - { 0.085079, 0.060323, -0.009687}, { 0.028174, 0.092766, -0.055590}, - { 0.070133, 0.039160, -0.061035}, {-0.039211, 0.072517, -0.028756}, - { 0.129686, 0.100233, -0.046998}, { 0.154189, 0.107616, 0.022791}, - {-0.049331, 0.094184, 0.087984}, {-0.013179, 0.126552, 0.125099}, - {-0.058716, 0.098524, 0.150886}, {-0.022753, 0.080011, 0.191127}, - { 0.013451, 0.164593, 0.153768}, { 0.074818, 0.181214, 0.108211}, - { 0.091323, 0.169249, 0.168460}, { 0.033885, 0.155516, 0.213745}, - {-0.032128, 0.227238, 0.135815}, {-0.059176, 0.168980, 0.229110}, - { 0.033917, 0.229753, 0.222264}, { 0.082702, 0.116370, 0.224697}, - { 0.127737, 0.186658, 0.212783}, { 0.047528, 0.063920, 0.216856}, - {-0.002446, 0.114174, 0.263289}, {-0.077783, 0.082523, 0.249697}, - { 0.010023, 0.024267, 0.256874}, { 0.053190, 0.111422, 0.310407}, - {-0.078804, 0.004444, 0.224078}, {-0.055253, -0.059180, 0.217892}, - {-0.065371, 0.008124, 0.333405}, {-0.076188, -0.098767, 0.286983}, - {-0.071911, -0.115804, 0.198031}, {-0.062473, 0.183639, 0.370162}, - {-0.042666, 0.255210, 0.262720}, { 0.011999, 0.217530, 0.318291}, - {-0.042144, 0.322087, 0.326387}, { 0.090663, 0.205835, 0.294784}, - { 0.058218, 0.293649, 0.277927}, { 0.157506, 0.282870, 0.294610}, - { 0.118248, 0.261007, 0.148614}, { 0.065261, 0.332362, 0.411912}, - { 0.141269, 0.451850, 0.315726}, { 0.001706, 0.456301, 0.357590}, - {-0.052947, 0.356559, 0.456944}, { 0.247707, 0.263837, 0.152591}, - { 0.306847, 0.417373, 0.258553}, { 0.166347, 0.149222, 0.118973}, - { 0.379709, 0.292172, 0.139875}, { 0.010171, -0.055170, -0.174523} -}; - -static const float lsf_cb2_16k[256][3] = { - {-0.213011, -0.293385, -0.330597}, {-0.212582, -0.240992, -0.338239}, - {-0.223373, -0.306214, -0.277192}, {-0.231138, -0.287729, -0.229412}, - {-0.238466, -0.228571, -0.260954}, {-0.140931, -0.247018, -0.258566}, - {-0.136239, -0.249669, -0.350143}, {-0.149738, -0.192970, -0.281475}, - {-0.167058, -0.261052, -0.196301}, {-0.177049, -0.201324, -0.207897}, - {-0.116915, -0.200629, -0.212526}, {-0.162247, -0.143805, -0.245093}, - {-0.082042, -0.191842, -0.266338}, {-0.098846, -0.208511, -0.320481}, - {-0.113510, -0.152470, -0.222474}, {-0.066197, -0.179112, -0.207813}, - {-0.129490, -0.169320, -0.155238}, {-0.078843, -0.190292, -0.155172}, - {-0.087790, -0.147729, -0.169351}, {-0.141037, -0.127207, -0.177910}, - {-0.126525, -0.223961, -0.153639}, {-0.101464, -0.189953, -0.114559}, - {-0.102450, -0.106303, -0.151171}, {-0.103208, -0.144457, -0.105378}, - {-0.170794, -0.140525, -0.136428}, {-0.168641, -0.203064, -0.135368}, - {-0.138193, -0.116042, -0.111905}, {-0.145085, -0.168581, -0.092613}, - {-0.126379, -0.220431, -0.091327}, {-0.212934, -0.184797, -0.101632}, - {-0.193711, -0.140556, -0.078304}, {-0.173674, -0.197276, -0.060140}, - {-0.197897, -0.241907, -0.091997}, {-0.156037, -0.258519, -0.111628}, - {-0.241964, -0.191124, -0.063140}, {-0.261340, -0.240847, -0.103132}, - {-0.221621, -0.242972, -0.041255}, {-0.224166, -0.232742, -0.161568}, - {-0.203591, -0.294470, -0.126035}, {-0.209540, -0.303149, -0.053170}, - {-0.253859, -0.295066, -0.156050}, {-0.278143, -0.331105, -0.085237}, - {-0.300273, -0.198750, -0.094834}, {-0.260477, -0.169713, -0.132476}, - {-0.211889, -0.172454, -0.164281}, {-0.228370, -0.122149, -0.124178}, - {-0.254629, -0.135668, -0.081692}, {-0.263813, -0.154928, -0.213596}, - {-0.308224, -0.106877, -0.084404}, {-0.242644, -0.082862, -0.085835}, - {-0.252084, -0.064888, -0.146498}, {-0.198162, -0.105721, -0.188887}, - {-0.189238, -0.088028, -0.109736}, {-0.197598, -0.099831, -0.044030}, - {-0.269017, -0.105991, -0.021513}, {-0.231349, -0.058825, -0.041407}, - {-0.225589, -0.027501, -0.087160}, {-0.160347, -0.058341, -0.079789}, - {-0.158729, -0.108951, -0.067262}, {-0.170483, -0.053023, -0.017561}, - {-0.175207, -0.013649, -0.049513}, {-0.156004, -0.108378, -0.004052}, - {-0.219958, -0.082362, 0.014950}, {-0.217785, -0.012981, -0.009410}, - {-0.123290, -0.040849, -0.040910}, {-0.119861, -0.095078, -0.060246}, - {-0.117537, -0.065479, 0.002968}, {-0.103231, -0.113298, -0.023282}, - {-0.136365, -0.149524, -0.051387}, {-0.119332, -0.164400, -0.009103}, - {-0.104522, -0.060948, -0.083056}, {-0.071461, -0.070787, -0.037347}, - {-0.081116, -0.149015, -0.056740}, {-0.069561, -0.108099, -0.069167}, - {-0.055624, -0.117369, -0.025091}, {-0.091941, -0.190091, -0.060020}, - {-0.072003, -0.168433, -0.006540}, {-0.033305, -0.154427, -0.054608}, - {-0.062988, -0.127093, -0.108307}, {-0.056690, -0.170813, -0.102834}, - {-0.018273, -0.127863, -0.094998}, {-0.056239, -0.123678, -0.146262}, - {-0.023442, -0.154617, -0.137417}, {-0.051903, -0.078379, -0.093395}, - {-0.014599, -0.104412, -0.135959}, {-0.051582, -0.081280, -0.140643}, - {-0.092727, -0.091930, -0.107816}, {-0.024814, -0.140993, -0.183243}, - {-0.064307, -0.113024, -0.194788}, {-0.000118, -0.098858, -0.195336}, - {-0.028090, -0.048258, -0.164101}, {-0.093414, -0.055969, -0.172743}, - {-0.114445, -0.104336, -0.215204}, {-0.048518, -0.132063, -0.242991}, - {-0.159620, -0.060240, -0.178592}, {-0.135728, -0.067473, -0.131876}, - {-0.078464, -0.038040, -0.125105}, {-0.011061, -0.064011, -0.102496}, - {-0.033887, -0.026485, -0.109493}, {-0.129128, -0.014216, -0.111329}, - {-0.190687, -0.030660, -0.135825}, {-0.082037, 0.010997, -0.100167}, - {-0.183403, 0.001651, -0.098962}, {-0.074775, -0.030335, -0.062217}, - {-0.031759, -0.050551, -0.059420}, {-0.051439, 0.010827, -0.052148}, - {-0.126744, 0.008689, -0.047785}, {-0.145916, 0.042019, -0.077431}, - {-0.093552, 0.054143, -0.060473}, {-0.090660, 0.012868, -0.018195}, - {-0.079783, -0.033071, 0.001482}, {-0.033010, -0.022331, -0.014506}, - {-0.004798, -0.017339, -0.060120}, {-0.025021, 0.026390, -0.003263}, - {-0.001437, 0.025994, -0.040892}, {-0.074821, 0.019005, 0.027549}, - {-0.030811, -0.012114, 0.034284}, { 0.006785, 0.004618, 0.018717}, - { 0.013392, -0.032597, -0.023731}, { 0.035994, 0.005963, -0.011757}, - { 0.008071, -0.045750, 0.024889}, { 0.013055, 0.017040, 0.054121}, - {-0.012989, 0.044864, 0.036327}, { 0.025054, 0.047137, 0.009974}, - { 0.053801, 0.024178, 0.031774}, { 0.056442, -0.030647, 0.021291}, - { 0.032247, 0.052680, 0.049886}, { 0.035369, 0.090207, 0.031394}, - { 0.064720, 0.070390, 0.040938}, { 0.022112, 0.054834, 0.091059}, - { 0.041765, 0.086248, 0.070196}, { 0.070645, 0.060852, 0.078825}, - { 0.058506, 0.016920, 0.081612}, { 0.000009, 0.086500, 0.059849}, - { 0.071253, 0.107392, 0.059046}, { 0.094702, 0.096160, 0.090982}, - { 0.047639, 0.110877, 0.111227}, { 0.122444, 0.090909, 0.057396}, - { 0.101916, 0.052299, 0.029909}, { 0.076560, 0.086094, -0.007252}, - { 0.123411, 0.030769, 0.082749}, { 0.135579, 0.103022, 0.009540}, - { 0.120576, 0.065284, -0.024095}, { 0.077483, 0.028526, -0.012369}, - { 0.128747, 0.017901, -0.003874}, { 0.158254, 0.046962, 0.029577}, - { 0.102287, -0.002211, 0.037329}, { 0.089654, -0.021372, -0.006857}, - { 0.137917, 0.027228, -0.053223}, { 0.098728, -0.012192, -0.048518}, - { 0.083974, 0.036153, -0.062266}, { 0.048230, -0.010241, -0.052293}, - { 0.110135, 0.007715, -0.095233}, { 0.068294, -0.014317, -0.104029}, - { 0.063909, -0.056416, -0.063023}, { 0.059133, -0.044675, -0.023780}, - { 0.030748, 0.021845, -0.086332}, { 0.023994, -0.045574, -0.076232}, - { 0.052147, -0.059825, -0.109667}, { 0.013087, -0.020420, -0.121945}, - { 0.018163, -0.096765, -0.088758}, { 0.020196, -0.076470, -0.048112}, - { 0.020282, -0.084204, -0.135535}, { 0.040076, -0.053464, -0.161949}, - {-0.017796, -0.103070, -0.059559}, {-0.016484, -0.070138, -0.016866}, - { 0.004849, -0.112481, -0.017731}, { 0.040160, -0.073873, -0.005327}, - { 0.002202, -0.094723, 0.045366}, {-0.056918, -0.081578, 0.017875}, - {-0.031099, -0.141708, 0.009186}, {-0.102802, -0.122675, 0.030060}, - {-0.061717, -0.145116, 0.076680}, {-0.073607, -0.050464, 0.072853}, - {-0.117403, -0.194921, 0.040101}, {-0.185236, -0.133620, 0.045939}, - {-0.160174, -0.057226, 0.056641}, {-0.178489, -0.173435, -0.007806}, - {-0.199916, -0.204866, 0.047342}, {-0.152337, -0.249651, 0.034656}, - {-0.185637, -0.230942, -0.002072}, {-0.122548, -0.215209, -0.024552}, - {-0.249578, -0.209714, 0.009470}, {-0.160108, -0.257702, -0.040992}, - {-0.216694, -0.289353, 0.027182}, {-0.226390, -0.147844, -0.022742}, - {-0.288737, -0.272150, -0.013948}, {-0.262554, -0.237035, 0.072473}, - {-0.306267, -0.188335, -0.032894}, {-0.259666, -0.345816, 0.024138}, - {-0.271093, -0.137143, 0.040404}, {-0.201317, -0.286782, 0.107615}, - {-0.235725, -0.163396, 0.113844}, {-0.159988, -0.209788, 0.112140}, - {-0.262985, -0.056741, 0.093506}, {-0.277226, -0.037306, 0.016008}, - {-0.293486, -0.040422, -0.062018}, {-0.214921, 0.022900, 0.055295}, - {-0.253889, 0.058575, -0.000151}, {-0.246689, 0.024242, -0.058488}, - {-0.143790, 0.006767, 0.014061}, {-0.187077, 0.048882, -0.035625}, - {-0.196369, 0.112085, 0.031546}, {-0.124264, 0.086197, -0.020800}, - {-0.126249, 0.016960, 0.095741}, {-0.079816, 0.080398, 0.051038}, - {-0.056269, 0.075380, -0.028262}, {-0.120493, 0.148495, 0.028430}, - {-0.161750, 0.101290, 0.117806}, {-0.003247, 0.083393, -0.017061}, - {-0.034007, 0.142542, 0.007402}, {-0.037618, 0.025871, 0.089496}, - {-0.082819, 0.184435, 0.073224}, { 0.006448, 0.167015, 0.080548}, - { 0.035315, 0.144022, 0.003218}, {-0.023459, 0.088147, 0.152604}, - { 0.006247, -0.024099, 0.077792}, { 0.039894, 0.057586, -0.042455}, - {-0.020417, 0.035400, -0.093971}, { 0.075465, 0.052063, 0.145582}, - { 0.078027, 0.184720, 0.092096}, { 0.107295, 0.148380, 0.022264}, - { 0.066928, -0.052831, 0.065108}, { 0.093295, 0.118157, 0.149815}, - { 0.119373, 0.137114, 0.099536}, { 0.138653, 0.075509, 0.121545}, - { 0.174025, 0.077531, 0.077169}, { 0.165839, 0.150080, 0.133423}, - { 0.173276, 0.155887, 0.048150}, { 0.162910, 0.095898, 0.171896}, - { 0.214577, 0.112888, 0.115579}, { 0.204755, 0.106392, 0.032337}, - { 0.178853, 0.205034, 0.114760}, { 0.177401, 0.070504, -0.013778}, - { 0.241624, 0.166921, 0.066087}, { 0.219595, 0.183553, 0.172332}, - { 0.123671, 0.170842, 0.167216}, { 0.177104, 0.240197, 0.186359}, - { 0.272003, 0.220214, 0.126073}, { 0.093748, 0.235843, 0.160998}, - { 0.141510, 0.190012, 0.240416}, { 0.046878, 0.168984, 0.190412}, - { 0.094898, 0.107038, 0.235003}, { 0.108592, 0.269536, 0.262528}, - {-0.027754, 0.234355, 0.134544}, { 0.265127, 0.267540, 0.199041}, - { 0.199523, 0.291507, 0.265171}, { 0.266177, 0.209339, 0.350369}, - { 0.322159, 0.344794, 0.270823}, { 0.399957, 0.264065, 0.110387}, - { 0.277817, 0.127407, -0.035625}, {-0.177038, 0.208155, 0.119077}, - { 0.049075, -0.076294, 0.145711}, { 0.187246, 0.042865, -0.127097}, - { 0.117885, -0.023489, -0.138658}, {-0.284256, 0.068153, 0.124259} -}; - -static const float lsf_cb3_16k[128][3] = { - {-0.223412, -0.236300, -0.188067}, {-0.202286, -0.218711, -0.102947}, - {-0.251652, -0.161020, -0.125280}, {-0.169223, -0.138155, -0.140430}, - {-0.176427, -0.146628, -0.222632}, {-0.120584, -0.187276, -0.180164}, - {-0.195559, -0.074225, -0.169109}, {-0.144551, -0.142774, -0.073340}, - {-0.111001, -0.111310, -0.130696}, {-0.095221, -0.174684, -0.111841}, - {-0.112158, -0.103049, -0.195130}, {-0.059989, -0.142170, -0.157850}, - {-0.127598, -0.051759, -0.153109}, {-0.063753, -0.067898, -0.164117}, - {-0.141753, -0.068274, -0.091999}, {-0.060482, -0.101054, -0.099475}, - {-0.104699, -0.104456, -0.066496}, {-0.073649, -0.052614, -0.091612}, - {-0.088268, -0.019072, -0.129956}, {-0.018837, -0.104115, -0.127837}, - {-0.021630, -0.033055, -0.129868}, {-0.083768, -0.047549, -0.041407}, - {-0.055892, -0.108526, -0.043200}, {-0.027816, -0.062499, -0.048190}, - {-0.002248, -0.110428, -0.062868}, { 0.001270, -0.033245, -0.072404}, - {-0.042747, -0.013835, -0.033829}, {-0.037615, -0.147833, -0.083912}, - {-0.045023, 0.006011, -0.092182}, {-0.050411, -0.081832, 0.005787}, - { 0.000357, -0.104282, -0.009428}, {-0.003893, -0.047892, -0.001506}, - {-0.040077, -0.147110, -0.009065}, {-0.060858, -0.030972, 0.012999}, - {-0.014674, 0.001370, 0.005554}, {-0.101362, -0.126061, -0.001898}, - {-0.102519, -0.000390, -0.015721}, {-0.132687, -0.069608, -0.019928}, - {-0.102227, -0.076131, 0.043306}, {-0.055193, 0.027001, 0.011857}, - {-0.156427, -0.016629, 0.017480}, {-0.078736, 0.002809, 0.057979}, - {-0.157789, -0.016693, -0.055073}, {-0.179397, -0.095520, 0.022065}, - {-0.110219, 0.010408, -0.081927}, {-0.125392, 0.049111, 0.044595}, - {-0.112528, 0.063173, -0.024954}, {-0.185525, 0.053093, -0.032102}, - {-0.176887, -0.019379, -0.115125}, {-0.249706, -0.017664, -0.059188}, - {-0.200243, -0.103311, -0.066846}, {-0.055404, 0.045106, -0.046991}, - {-0.000544, 0.022690, -0.044831}, { 0.022298, -0.016367, -0.022509}, - { 0.028278, 0.017585, -0.100612}, { 0.061781, -0.020826, -0.068190}, - { 0.029157, -0.074477, -0.098898}, { 0.043073, -0.067234, -0.032293}, - { 0.060157, 0.034636, -0.034885}, { 0.071153, -0.013881, -0.009036}, - { 0.054196, -0.029989, -0.131139}, { 0.030193, 0.024976, 0.009861}, - { 0.055943, -0.045304, 0.031927}, { 0.033217, -0.002418, 0.038165}, - { 0.063814, 0.045625, 0.025309}, { 0.033689, 0.038819, 0.049700}, - { 0.073582, 0.028527, 0.060200}, {-0.007957, 0.022531, 0.043687}, - {-0.000984, 0.054518, 0.018742}, { 0.057004, 0.060916, 0.060573}, - { 0.009883, 0.015238, 0.080211}, { 0.022742, 0.070832, 0.068855}, - { 0.053001, 0.029790, 0.091446}, {-0.042447, 0.060379, 0.061462}, - { 0.076826, 0.062468, 0.089653}, { 0.039065, 0.069768, 0.119128}, - { 0.064145, 0.095353, 0.071621}, { 0.094411, 0.069527, 0.054197}, - { 0.042812, 0.093060, 0.027980}, { 0.094791, 0.099189, 0.101112}, - { 0.117611, 0.048601, 0.093111}, { 0.119951, 0.122758, 0.051546}, - { 0.103558, 0.085245, -0.010700}, { 0.150126, 0.059766, 0.020280}, - { 0.108066, 0.017170, 0.008606}, { 0.108422, 0.023253, -0.063942}, - { 0.019652, 0.072284, -0.030331}, { 0.192719, 0.075624, 0.071156}, - { 0.221140, 0.069191, -0.035085}, { 0.188367, 0.126200, 0.035225}, - { 0.185760, 0.043537, -0.101714}, {-0.042518, 0.099646, 0.003244}, - {-0.015308, -0.027521, 0.046006}, { 0.034086, -0.045777, 0.095989}, - { 0.007174, -0.093358, 0.046459}, {-0.051248, -0.062095, 0.083161}, - {-0.045626, -0.133301, 0.052997}, {-0.037840, 0.024042, 0.131097}, - {-0.020217, -0.115942, 0.126170}, {-0.134550, -0.036291, 0.111322}, - {-0.110576, -0.160024, 0.091841}, {-0.093308, -0.184958, 0.013939}, - {-0.082735, -0.167417, -0.051725}, {-0.169934, -0.173003, -0.007155}, - {-0.128244, -0.213123, -0.053337}, {-0.079852, -0.154116, -0.246546}, - {-0.032242, -0.108756, -0.204133}, {-0.140117, -0.199495, -0.284505}, - { 0.010842, -0.074979, -0.166333}, {-0.093313, 0.145006, 0.034110}, - {-0.039236, 0.113213, 0.111053}, { 0.040613, -0.031783, 0.174058}, - {-0.164232, 0.131421, 0.149842}, { 0.026893, 0.107281, 0.179297}, - { 0.047086, 0.158606, 0.103267}, {-0.070567, 0.210459, 0.134734}, - { 0.094392, 0.137050, 0.166892}, { 0.086039, 0.063657, 0.168825}, - { 0.159371, 0.120897, 0.154357}, { 0.147101, 0.160684, 0.114882}, - { 0.120158, 0.199650, 0.180948}, { 0.191417, 0.174500, 0.170734}, - { 0.159153, 0.142165, 0.233347}, { 0.232002, 0.150181, 0.102736}, - { 0.188299, 0.221738, 0.228748}, { 0.256786, 0.209685, 0.161534}, - { 0.257861, 0.247793, 0.250516}, {-0.164461, -0.000143, 0.232461} -}; - -static const float lsf_cb4_16k[128][3] = { - {-0.193369, -0.304643, -0.253777}, {-0.164125, -0.277786, -0.153116}, - {-0.135681, -0.209120, -0.211724}, {-0.121822, -0.215734, -0.292207}, - {-0.198781, -0.161674, -0.242538}, {-0.164147, -0.180570, -0.138070}, - {-0.095915, -0.198695, -0.154309}, {-0.248386, -0.234462, -0.136984}, - {-0.164968, -0.108318, -0.175635}, {-0.124171, -0.111809, -0.224402}, - {-0.067398, -0.157017, -0.195759}, {-0.090132, -0.119174, -0.165253}, - {-0.099460, -0.146895, -0.106799}, {-0.141493, -0.108103, -0.108880}, - {-0.085088, -0.098340, -0.109953}, {-0.105526, -0.054463, -0.154315}, - {-0.040480, -0.144285, -0.124042}, {-0.040969, -0.084039, -0.142880}, - {-0.049082, -0.118553, -0.066686}, {-0.096336, -0.087515, -0.055741}, - {-0.058605, -0.059327, -0.089275}, {-0.121842, -0.058681, -0.086949}, - {-0.053792, -0.022025, -0.124451}, {-0.036744, -0.068891, -0.045865}, - { 0.003900, -0.098237, -0.091158}, {-0.001664, -0.045089, -0.081353}, - {-0.072829, -0.034087, -0.038416}, {-0.100822, -0.007330, -0.088715}, - {-0.035911, -0.005864, -0.062577}, {-0.020205, -0.026547, -0.019634}, - { 0.004291, -0.041290, -0.138181}, { 0.023404, -0.010932, -0.044904}, - { 0.013557, 0.014823, -0.092943}, { 0.059673, -0.031024, -0.095739}, - { 0.021130, -0.080607, -0.034594}, { 0.024655, -0.035564, 0.003243}, - { 0.017106, 0.006952, -0.000308}, { 0.075208, -0.030910, -0.031181}, - { 0.024965, 0.048632, -0.039448}, { 0.057028, 0.021547, -0.009418}, - {-0.018577, 0.023697, -0.009759}, { 0.024077, 0.033053, 0.024324}, - { 0.037052, -0.003436, 0.044530}, {-0.012871, -0.007179, 0.031795}, - { 0.077877, 0.021547, 0.023131}, { 0.053365, 0.052078, 0.029433}, - { 0.011429, 0.070426, 0.028734}, {-0.001827, 0.033115, 0.061505}, - {-0.044870, 0.038568, 0.026239}, { 0.061633, 0.034799, 0.059784}, - { 0.034261, 0.060342, 0.065185}, { 0.058981, 0.082481, 0.047252}, - { 0.090008, 0.065942, 0.044470}, { 0.066961, 0.073728, -0.000428}, - { 0.074763, 0.060293, 0.085632}, { 0.066366, 0.103375, 0.079642}, - { 0.122297, 0.036558, 0.058745}, { 0.111042, 0.092093, 0.085412}, - { 0.099243, 0.115476, 0.039254}, { 0.019973, 0.122844, 0.050255}, - { 0.159571, 0.098965, 0.051740}, { 0.137624, 0.072405, -0.006922}, - { 0.130240, 0.146091, 0.089698}, { 0.138335, 0.092968, 0.136193}, - { 0.066031, 0.149304, 0.125476}, { 0.202749, 0.145751, 0.077122}, - { 0.002224, 0.082811, 0.131200}, { 0.124476, 0.178073, 0.162336}, - { 0.174722, 0.190298, 0.127106}, { 0.202193, 0.153569, 0.163840}, - { 0.242604, 0.197796, 0.136929}, { 0.185809, 0.229348, 0.193353}, - {-0.058814, 0.195178, 0.141821}, { 0.253646, 0.247175, 0.205766}, - { 0.061433, -0.025542, 0.119311}, {-0.057816, 0.082445, 0.073243}, - {-0.069239, 0.148678, 0.031146}, {-0.030217, -0.008503, 0.106194}, - {-0.026708, 0.087469, -0.009589}, {-0.090418, 0.000265, 0.056807}, - {-0.050607, -0.019383, 0.010494}, {-0.079397, 0.008233, -0.011469}, - {-0.072634, -0.061165, 0.046917}, {-0.075741, -0.072343, -0.007557}, - {-0.025162, -0.073363, 0.005173}, {-0.123371, -0.041257, -0.008375}, - {-0.139904, 0.018285, 0.009920}, {-0.143421, -0.104238, 0.033457}, - {-0.100923, -0.134400, -0.023257}, {-0.157791, -0.095042, -0.036959}, - {-0.219890, -0.078637, 0.001815}, {-0.183607, -0.023053, -0.043678}, - {-0.145303, -0.158923, -0.059045}, {-0.197615, -0.165199, 0.028099}, - {-0.225131, -0.167756, -0.056401}, {-0.216572, -0.104751, -0.102964}, - {-0.171336, -0.241967, -0.063404}, {-0.134035, -0.205614, 0.011831}, - {-0.297116, -0.211173, -0.015352}, {-0.086464, -0.200592, -0.070454}, - {-0.217777, -0.278403, 0.030398}, {-0.236248, -0.323694, -0.087588}, - {-0.222074, -0.210785, 0.106210}, {-0.283400, -0.097077, 0.041303}, - {-0.078417, -0.154464, 0.062956}, {-0.214417, -0.100695, 0.121909}, - {-0.178576, -0.028847, 0.061042}, {-0.037999, -0.144233, -0.010546}, - {-0.086695, -0.070996, 0.125282}, { 0.010788, -0.085006, 0.058527}, - {-0.154015, 0.066560, 0.071038}, {-0.143503, 0.033260, 0.154393}, - {-0.134069, 0.032420, -0.056293}, {-0.110851, 0.086908, 0.003920}, - {-0.057254, 0.047674, -0.055571}, {-0.214206, 0.068784, -0.004735}, - {-0.257264, 0.050468, 0.081702}, {-0.291834, 0.004120, -0.022366}, - {-0.173309, -0.029081, -0.115901}, {-0.207622, 0.168664, 0.136030}, - { 0.090541, 0.032754, -0.057330}, { 0.140219, -0.000735, -0.015633}, - { 0.136697, -0.017163, -0.100909}, { 0.029838, -0.089515, -0.147130}, - {-0.055367, -0.072683, -0.214015}, { 0.048680, -0.057633, -0.212429}, - {-0.013134, -0.113898, -0.196403}, {-0.071702, -0.159408, -0.254895} -}; - -static const float lsf_cb5_16k[128][4] = { - {-0.201277, -0.278679, -0.173262, -0.198580}, - {-0.214667, -0.151922, -0.117551, -0.192713}, - {-0.160962, -0.207728, -0.124750, -0.129749}, - {-0.131043, -0.137818, -0.155281, -0.166308}, - {-0.179134, -0.169602, -0.165223, -0.066293}, - {-0.136474, -0.177035, -0.250127, -0.134370}, - {-0.066970, -0.146274, -0.170638, -0.134436}, - {-0.083288, -0.165860, -0.103437, -0.140361}, - {-0.130474, -0.119317, -0.124393, -0.086408}, - {-0.127609, -0.134415, -0.073592, -0.116103}, - {-0.113027, -0.091756, -0.107786, -0.131935}, - {-0.125530, -0.182152, -0.093796, -0.045088}, - {-0.077122, -0.138052, -0.166271, -0.038886}, - {-0.073027, -0.106845, -0.067073, -0.113910}, - {-0.049146, -0.107019, -0.112531, -0.063388}, - {-0.101539, -0.119586, -0.050297, -0.040670}, - {-0.107784, -0.066913, -0.080993, -0.052352}, - {-0.152155, -0.103010, -0.090461, -0.015526}, - {-0.153087, -0.087656, -0.029889, -0.037367}, - {-0.215281, -0.138062, -0.089162, -0.050839}, - {-0.053350, -0.060169, -0.063459, -0.024499}, - {-0.051674, -0.076355, -0.033733, -0.077211}, - {-0.045047, -0.107006, -0.020880, -0.024525}, - {-0.083003, -0.063672, -0.013243, -0.028324}, - {-0.104104, -0.075450, -0.032746, 0.024480}, - {-0.085695, -0.019502, -0.045121, -0.025016}, - {-0.123120, -0.030844, -0.003533, -0.016224}, - {-0.025568, -0.049172, -0.003911, -0.027522}, - {-0.039029, -0.019857, -0.043211, -0.058087}, - {-0.040122, -0.023067, -0.001356, 0.008607}, - {-0.063351, -0.001776, 0.016015, -0.027088}, - {-0.068110, -0.038838, 0.042525, 0.001076}, - {-0.043623, -0.020736, -0.047862, 0.037710}, - {-0.041052, 0.021954, -0.025660, 0.000758}, - {-0.013035, 0.002583, -0.008233, -0.037300}, - {-0.005523, -0.014670, 0.019651, -0.012667}, - {-0.004409, -0.014437, -0.059412, -0.019701}, - { 0.024946, -0.011663, -0.014351, -0.028762}, - { 0.012660, 0.018489, -0.010205, 0.012695}, - {-0.004423, 0.017827, 0.040544, 0.003629}, - { 0.020684, 0.026743, 0.007752, -0.025595}, - { 0.032071, 0.000043, 0.026188, -0.006444}, - { 0.058793, 0.015820, -0.001119, -0.017415}, - { 0.020156, -0.047590, 0.004227, 0.008670}, - { 0.054770, 0.032135, 0.029770, -0.009767}, - { 0.030884, 0.047757, 0.033068, 0.006866}, - { 0.062039, 0.011646, 0.056037, 0.016859}, - { 0.013798, -0.028196, 0.060710, 0.014299}, - { 0.100043, 0.041445, 0.023379, -0.014889}, - { 0.062728, -0.042821, 0.002180, -0.055380}, - { 0.061663, 0.018767, -0.015571, -0.074095}, - { 0.062980, 0.080497, 0.011808, -0.031787}, - { 0.084964, 0.043100, -0.025877, 0.020309}, - { 0.014707, 0.035421, -0.041440, -0.053373}, - { 0.081268, 0.005791, -0.066290, -0.039825}, - { 0.017691, -0.020401, -0.040513, -0.083960}, - { 0.120874, 0.055753, -0.025988, -0.059552}, - { 0.079912, 0.007894, -0.085380, -0.114587}, - { 0.036856, -0.039331, -0.104237, -0.069116}, - { 0.008526, -0.064273, -0.048312, -0.038595}, - { 0.033461, -0.028956, -0.066505, 0.038722}, - {-0.042064, -0.043989, -0.100653, -0.071550}, - {-0.015342, -0.064850, -0.065675, -0.122769}, - {-0.006581, -0.004919, -0.113564, -0.145753}, - { 0.008273, -0.070702, -0.164998, -0.095541}, - {-0.001698, -0.063744, -0.129971, -0.011162}, - {-0.048471, -0.087500, -0.111006, -0.161823}, - {-0.032193, -0.091955, -0.080642, 0.012288}, - {-0.095873, -0.015986, -0.072722, -0.101745}, - {-0.079477, -0.082060, -0.203008, -0.100297}, - {-0.023883, -0.064022, -0.168341, -0.211739}, - {-0.070530, -0.103547, -0.123858, 0.055049}, - {-0.033503, -0.076812, -0.016287, 0.044159}, - {-0.088427, -0.161682, -0.058579, 0.013873}, - {-0.083068, -0.168222, -0.016773, -0.080209}, - {-0.080548, -0.139090, 0.030544, 0.007171}, - {-0.117482, -0.083718, 0.027074, -0.003674}, - {-0.163085, -0.156856, -0.012618, -0.022329}, - {-0.176540, -0.113042, -0.020148, 0.051770}, - {-0.153891, -0.199293, -0.043244, 0.028331}, - {-0.107822, -0.150615, 0.016430, 0.092919}, - {-0.137676, -0.183224, 0.066026, 0.029343}, - {-0.191106, -0.099250, 0.045370, 0.004084}, - {-0.237042, -0.130815, -0.022543, -0.029428}, - {-0.201014, -0.053591, -0.007305, -0.033547}, - {-0.249286, -0.228408, 0.005002, 0.007146}, - {-0.206509, -0.211998, -0.061352, -0.047233}, - {-0.255702, -0.135114, 0.076375, 0.036630}, - {-0.296271, -0.073946, -0.007273, -0.019601}, - {-0.302917, -0.175111, -0.070024, -0.043905}, - {-0.239275, -0.043962, -0.084982, -0.067446}, - {-0.254583, -0.294720, -0.088762, -0.070451}, - {-0.205583, -0.238996, -0.124753, 0.033076}, - {-0.205583, -0.215882, -0.028472, 0.118679}, - {-0.153640, -0.204464, -0.039654, -0.134441}, - {-0.145929, -0.191970, -0.175308, 0.021366}, - {-0.149348, -0.212569, -0.118324, 0.103812}, - {-0.166397, -0.220581, -0.265260, -0.029113}, - {-0.164171, -0.231262, -0.258828, 0.061427}, - {-0.200198, -0.263453, -0.212016, 0.115359}, - {-0.130088, -0.212168, -0.202368, 0.118563}, - {-0.206387, -0.078075, -0.227856, -0.111165}, - {-0.129605, -0.176848, -0.241584, -0.259900}, - {-0.176826, -0.045901, -0.141712, -0.209345}, - {-0.351173, -0.031097, -0.133935, -0.182412}, - {-0.164232, 0.027006, -0.014039, -0.053567}, - {-0.171037, -0.025924, 0.030972, 0.017329}, - {-0.080862, -0.021577, 0.007652, 0.063968}, - {-0.061788, 0.042024, -0.018783, -0.057979}, - {-0.110311, 0.054760, 0.031446, -0.006710}, - {-0.136637, 0.022171, 0.084991, 0.028039}, - {-0.254471, -0.004376, 0.078034, 0.033649}, - {-0.234464, 0.088157, 0.040999, 0.002639}, - {-0.037095, 0.059443, 0.072180, 0.015027}, - {-0.046841, -0.004813, 0.088266, 0.038786}, - {-0.086782, 0.120100, 0.082655, 0.020271}, - {-0.118361, -0.069242, 0.094867, 0.039200}, - {-0.023342, -0.084303, 0.052684, 0.017093}, - {-0.014194, 0.001012, 0.011946, 0.074125}, - {-0.015342, 0.076396, 0.022365, -0.028001}, - { 0.027706, 0.037047, 0.107573, 0.060815}, - { 0.030615, 0.040664, 0.010467, 0.074289}, - { 0.038646, 0.115584, 0.069627, 0.007642}, - { 0.096463, 0.069818, 0.062494, 0.015413}, - { 0.054834, 0.065232, 0.054286, 0.110088}, - { 0.152312, 0.092371, 0.026420, -0.013184}, - { 0.144264, 0.123438, 0.080131, 0.023233}, - { 0.124405, 0.009943, -0.148477, -0.205184} -}; - -static const float *lsf_codebooks_16k[] = { - lsf_cb1_16k[0], lsf_cb2_16k[0], lsf_cb3_16k[0], lsf_cb4_16k[0], - lsf_cb5_16k[0] -}; - -#endif /* AVCODEC_SIPR16KDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/siprdata.h b/tizen/distrib/ffmpeg/libavcodec/siprdata.h deleted file mode 100644 index ed804ee..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/siprdata.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * SIPR / ACELP.NET decoder - * - * Copyright (c) 2008 Vladimir Voroshilov - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SIPRDATA_H -#define AVCODEC_SIPRDATA_H - -static const float mean_lsf[10] = { - 0.297151, 0.452308, 0.765443, 1.134803, 1.421125, - 1.773822, 2.049173, 2.375914, 2.585097, 0.075756 -}; - -static const float lsf_cb1[64][2] = { - { 0.007587, -0.005843}, { 0.042163, -0.028048}, {-0.017147, -0.060705}, - { 0.013773, -0.038108}, {-0.041563, -0.078571}, {-0.076928, -0.119343}, - { 0.012654, 0.176005}, { 0.059737, 0.156869}, { 0.171767, 0.231837}, - { 0.114030, 0.242047}, { 0.168977, 0.283101}, { 0.146210, 0.397961}, - { 0.249446, 0.268421}, { 0.137074, 0.186724}, {-0.057736, -0.135638}, - {-0.109664, -0.124611}, {-0.021234, -0.031174}, {-0.013990, -0.091819}, - {-0.040046, -0.111426}, {-0.016830, 0.055361}, { 0.057815, 0.071606}, - { 0.060670, 0.114436}, { 0.106695, 0.140838}, { 0.093601, 0.092793}, - { 0.039593, 0.006142}, {-0.066589, -0.092463}, {-0.102589, -0.171380}, - {-0.059621, -0.050671}, { 0.166131, 0.139773}, { 0.213069, 0.190761}, - { 0.061820, 0.037661}, { 0.136471, 0.090823}, {-0.019789, 0.013515}, - { 0.022280, 0.079473}, { 0.215281, 0.461959}, { 0.206497, 0.340077}, - { 0.012249, -0.065596}, { 0.091345, 0.190871}, { 0.019506, 0.037266}, - {-0.050702, -0.013223}, {-0.057334, 0.028943}, { 0.291512, 0.371415}, - {-0.053467, 0.084160}, { 0.025372, 0.375310}, { 0.269995, 0.566520}, - {-0.095259, -0.012353}, { 0.050479, 0.212893}, { 0.101219, 0.049320}, - { 0.072426, 0.283362}, {-0.084116, -0.150542}, {-0.031485, 0.144922}, - { 0.012714, 0.256910}, {-0.009528, 0.102768}, {-0.039572, 0.204967}, - {-0.098800, 0.055038}, { 0.020719, 0.128387}, {-0.045559, -0.178373}, - {-0.082338, 0.136933}, {-0.058270, 0.292806}, { 0.084242, 0.505112}, - { 0.121825, 0.326386}, {-0.102658, -0.069341}, { 0.071675, 0.004744}, - {-0.117763, -0.202608} -}; - -static const float lsf_cb2[128][2] = { - { 0.025412, 0.006095}, {-0.069803, 0.010650}, {-0.175957, -0.185800}, - {-0.139298, -0.048013}, {-0.156150, -0.129688}, {-0.160523, 0.068022}, - { 0.199683, 0.259982}, { 0.258038, 0.236147}, { 0.367089, 0.304716}, - { 0.251764, 0.305853}, { 0.394314, 0.382153}, { 0.448579, 0.337438}, - { 0.323286, 0.425563}, { 0.015369, 0.123820}, {-0.026770, 0.083881}, - {-0.112161, -0.097993}, {-0.221847, -0.161311}, {-0.050014, -0.092862}, - {-0.214960, -0.398498}, {-0.114062, -0.241381}, { 0.137950, 0.138852}, - { 0.031529, 0.065719}, { 0.208734, 0.084760}, { 0.157862, 0.057535}, - { 0.124750, 0.011922}, {-0.035227, -0.154397}, {-0.105523, -0.291427}, - {-0.073488, -0.201948}, {-0.224184, -0.273290}, {-0.168019, -0.240297}, - {-0.271591, -0.384682}, {-0.124784, 0.014253}, { 0.004210, -0.110418}, - { 0.074270, -0.014272}, { 0.053058, -0.068672}, {-0.090098, -0.145019}, - { 0.303214, 0.210323}, { 0.413443, 0.272002}, { 0.356904, 0.230646}, - {-0.035186, -0.028579}, {-0.117558, 0.115105}, {-0.159225, 0.218385}, - {-0.230178, 0.172901}, {-0.216148, -0.110195}, { 0.309444, 0.101508}, - { 0.250489, 0.118338}, { 0.293324, 0.151205}, {-0.023634, 0.033084}, - { 0.076708, 0.114024}, { 0.123119, 0.087704}, {-0.060265, 0.126543}, - {-0.223766, -0.021903}, {-0.241987, -0.328089}, { 0.205598, 0.147925}, - {-0.087010, 0.064601}, {-0.287892, -0.286099}, {-0.179451, -0.350781}, - {-0.219572, 0.043816}, {-0.217263, 0.245550}, {-0.286743, -0.180981}, - { 0.172659, 0.112620}, {-0.105422, 0.176856}, { 0.006176, -0.051491}, - { 0.099802, 0.176322}, {-0.186620, -0.068980}, { 0.164689, 0.185018}, - { 0.519877, 0.376111}, { 0.521941, 0.533731}, { 0.473375, 0.439534}, - { 0.214235, 0.202476}, { 0.579215, 0.466969}, { 0.310414, 0.271057}, - { 0.257450, 0.058939}, { 0.023936, -0.169464}, {-0.268817, -0.064531}, - {-0.174182, -0.000198}, {-0.268405, -0.234529}, {-0.296522, 0.247140}, - { 0.115950, -0.072194}, {-0.303666, 0.149084}, {-0.347762, -0.011002}, - {-0.223829, -0.214137}, {-0.278958, -0.457975}, { 0.135500, 0.238466}, - { 0.312730, 0.342760}, { 0.071754, -0.125912}, { 0.485938, 0.260429}, - { 0.037536, 0.179771}, { 0.391493, 0.156938}, { 0.397320, 0.484446}, - {-0.308630, -0.342418}, {-0.269599, -0.128453}, {-0.086683, -0.043863}, - { 0.421115, 0.213521}, { 0.082417, 0.049006}, {-0.087873, 0.238126}, - { 0.338899, 0.166131}, {-0.166988, 0.147105}, {-0.167214, -0.294075}, - { 0.588706, 0.328303}, { 0.207270, 0.017671}, {-0.141658, 0.291147}, - {-0.140850, 0.374321}, { 0.028180, 0.322510}, {-0.229858, 0.328036}, - {-0.060743, -0.260916}, {-0.011131, 0.246442}, {-0.058151, 0.310760}, - {-0.127536, -0.186432}, {-0.128523, -0.334884}, {-0.283899, 0.077729}, - {-0.031595, 0.181015}, {-0.329330, -0.108630}, {-0.215739, 0.107458}, - { 0.175734, 0.327134}, { 0.255801, 0.176077}, { 0.228265, 0.396859}, - {-0.370909, -0.185081}, {-0.355138, -0.300405}, { 0.061669, 0.242616}, - { 0.104489, 0.307995}, {-0.320021, -0.234002}, { 0.077349, 0.416286}, - {-0.339471, -0.407609}, {-0.019384, -0.215111}, { 0.168229, -0.032453}, - {-0.040140, 0.399658}, {-0.275141, 0.008218} -}; - -static const float lsf_cb3[128][2] = { - { 0.024608, 0.006198}, {-0.216616, -0.398169}, {-0.089601, -0.201370}, - {-0.121878, -0.305281}, { 0.037913, 0.059320}, { 0.245126, 0.244089}, - { 0.266853, 0.182476}, { 0.319362, 0.203481}, { 0.349945, 0.252644}, - { 0.393849, 0.279272}, { 0.445707, 0.258063}, { 0.387321, 0.200855}, - {-0.038818, 0.129603}, {-0.009510, 0.076441}, {-0.023892, -0.028199}, - {-0.117134, -0.145990}, {-0.186585, -0.052886}, {-0.034250, -0.084547}, - {-0.087443, -0.095426}, {-0.453322, -0.174493}, {-0.363975, -0.148186}, - {-0.334413, -0.202479}, {-0.221313, -0.181320}, {-0.131146, -0.050611}, - {-0.104706, 0.115139}, { 0.192765, 0.275417}, { 0.014184, 0.194251}, - { 0.154215, 0.226949}, { 0.084031, 0.221759}, { 0.189438, 0.164566}, - { 0.130737, 0.170962}, {-0.066815, 0.062954}, {-0.177176, -0.145167}, - {-0.247608, -0.129767}, {-0.187886, -0.293720}, {-0.244036, -0.344655}, - {-0.203063, -0.234947}, {-0.292715, -0.158421}, { 0.064990, -0.028164}, - { 0.147664, 0.085995}, { 0.107977, 0.002253}, { 0.071286, 0.027533}, - { 0.021017, -0.049807}, {-0.272056, -0.217857}, {-0.065596, 0.008375}, - {-0.150818, -0.195514}, {-0.012767, -0.150787}, { 0.238541, 0.136606}, - { 0.291741, 0.114024}, { 0.202677, 0.103701}, { 0.140985, 0.037759}, - {-0.257347, -0.442383}, {-0.320666, -0.319742}, {-0.488725, -0.603660}, - {-0.319170, -0.469806}, { 0.014970, -0.101074}, { 0.102209, 0.066790}, - {-0.076202, -0.044884}, { 0.073868, 0.152565}, { 0.070755, -0.091358}, - {-0.016751, 0.027216}, { 0.071201, 0.096981}, {-0.060975, -0.145638}, - { 0.114156, 0.117587}, {-0.284757, -0.029101}, {-0.253005, -0.073645}, - {-0.204028, -0.098492}, {-0.114508, 0.001219}, {-0.225284, -0.011998}, - {-0.235670, 0.084330}, { 0.161921, 0.128334}, { 0.025717, 0.119456}, - {-0.255292, -0.281471}, {-0.392803, -0.095809}, { 0.039229, -0.152110}, - {-0.310905, -0.099233}, {-0.268773, 0.032308}, {-0.340150, 0.013129}, - {-0.344890, -0.045157}, {-0.188423, 0.265603}, {-0.168235, -0.000936}, - { 0.000462, 0.297000}, { 0.263674, 0.371214}, {-0.146797, -0.098225}, - {-0.386557, -0.282426}, {-0.070940, -0.255550}, { 0.293258, 0.252785}, - { 0.408332, 0.387751}, {-0.381914, -0.358918}, {-0.463621, -0.315560}, - {-0.323681, -0.258465}, { 0.250055, 0.071195}, {-0.405256, -0.429754}, - {-0.135748, -0.251274}, { 0.186827, 0.060177}, { 0.116742, -0.053526}, - {-0.403321, -0.220339}, {-0.414144, -0.021108}, {-0.416877, 0.050184}, - {-0.470083, -0.079564}, {-0.315554, 0.219217}, {-0.273183, 0.138437}, - { 0.253231, 0.306374}, { 0.177802, 0.346298}, { 0.210358, 0.207697}, - {-0.323480, 0.077519}, {-0.193136, 0.048170}, { 0.114492, 0.292778}, - {-0.130766, 0.056677}, {-0.171572, -0.349267}, {-0.370076, -0.536392}, - {-0.311109, -0.389953}, { 0.334928, 0.367664}, { 0.351246, 0.438664}, - { 0.518803, 0.331253}, { 0.437061, 0.327257}, { 0.318906, 0.307389}, - {-0.025972, -0.206758}, { 0.373278, 0.325438}, { 0.473488, 0.389441}, - { 0.478553, 0.477990}, { 0.332783, 0.153825}, { 0.212098, 0.452336}, - { 0.161522, -0.011212}, { 0.209368, 0.020687}, {-0.086262, 0.204493}, - {-0.388643, 0.133640}, {-0.177016, 0.134404} -}; - -static const float lsf_cb4[128][2] = { - {-0.003594, -0.022447}, { 0.070651, 0.028334}, {-0.290374, -0.018347}, - {-0.224495, -0.370312}, {-0.269555, -0.131227}, {-0.122714, -0.267733}, - { 0.173325, 0.138698}, { 0.161946, 0.020687}, { 0.111706, 0.022510}, - { 0.097638, 0.056049}, { 0.139754, 0.059920}, { 0.056549, -0.050586}, - { 0.036301, 0.021501}, {-0.066347, 0.012324}, {-0.066972, 0.096136}, - {-0.120062, -0.084201}, { 0.011225, 0.047425}, {-0.012846, -0.067390}, - {-0.116201, 0.122874}, {-0.027819, 0.035453}, {-0.024743, 0.072835}, - {-0.034061, -0.001310}, { 0.077469, 0.081609}, { 0.128347, 0.139584}, - { 0.183416, 0.086563}, {-0.155839, -0.053775}, {-0.190403, -0.018639}, - {-0.202548, -0.062841}, {-0.373733, -0.275094}, {-0.394260, -0.186513}, - {-0.465700, -0.220031}, { 0.064400, -0.095825}, {-0.262053, -0.199837}, - {-0.167233, -0.094402}, { 0.048600, 0.057567}, {-0.007122, 0.168506}, - { 0.050938, 0.156451}, {-0.060828, 0.147083}, {-0.171889, 0.195822}, - {-0.218934, 0.138431}, {-0.270532, 0.195775}, {-0.405818, 0.075643}, - {-0.440187, 0.193387}, {-0.484968, 0.157607}, {-0.480560, 0.067230}, - {-0.436757, -0.111847}, {-0.040731, -0.040363}, {-0.202319, -0.170457}, - {-0.158515, -0.134551}, {-0.356709, -0.378549}, {-0.268820, -0.289831}, - {-0.188486, -0.289306}, {-0.148139, -0.177616}, {-0.071591, -0.191128}, - {-0.052270, -0.150589}, {-0.020543, -0.116220}, { 0.039584, -0.012592}, - {-0.268226, 0.042704}, {-0.209755, 0.069423}, {-0.168964, 0.124504}, - {-0.363240, 0.188266}, {-0.524935, -0.025010}, {-0.105894, -0.002699}, - {-0.251830, -0.062018}, {-0.310480, -0.082325}, { 0.014652, 0.083127}, - {-0.136512, 0.033116}, {-0.073755, -0.025236}, { 0.110766, 0.095954}, - { 0.002878, 0.011838}, {-0.074977, -0.244586}, {-0.047023, -0.081339}, - {-0.183249, 0.029525}, { 0.263435, 0.206934}, {-0.156721, -0.229993}, - {-0.112224, -0.208941}, {-0.116534, -0.123191}, {-0.073988, -0.111668}, - { 0.029484, -0.137573}, {-0.009802, -0.161685}, {-0.023273, 0.114043}, - {-0.332651, 0.049072}, {-0.394009, 0.018608}, {-0.433543, -0.035318}, - {-0.368459, -0.108024}, {-0.350215, -0.037617}, {-0.321140, -0.178537}, - { 0.020307, -0.048487}, {-0.210512, -0.232274}, {-0.082140, -0.065443}, - { 0.081961, -0.009340}, { 0.146794, 0.101973}, { 0.213999, 0.124687}, - { 0.100217, -0.054095}, {-0.114411, -0.041403}, {-0.097631, 0.037061}, - {-0.099651, -0.157978}, {-0.215790, -0.116550}, {-0.107100, 0.076300}, - { 0.084653, 0.126088}, { 0.246439, 0.091442}, { 0.160077, 0.188536}, - { 0.273900, 0.279190}, { 0.320417, 0.232550}, { 0.132710, -0.018988}, - { 0.018950, -0.091681}, {-0.032073, -0.202906}, { 0.212789, 0.178188}, - { 0.208580, 0.239726}, { 0.049420, 0.099840}, {-0.145695, -0.010619}, - {-0.132525, -0.322660}, { 0.019666, 0.126603}, { 0.260809, 0.147727}, - {-0.232795, -0.001090}, {-0.049826, 0.225987}, {-0.154774, 0.076614}, - { 0.045032, 0.221397}, { 0.321014, 0.161632}, {-0.062379, 0.053586}, - { 0.132252, 0.246675}, { 0.392627, 0.271905}, {-0.264585, 0.102344}, - {-0.327200, 0.121624}, {-0.399642, 0.124445}, {-0.108335, 0.179171}, - { 0.100374, 0.182731}, { 0.203852, 0.049505} -}; - -static const float lsf_cb5[32][2] = { - {-0.047705, 0.008002}, { 0.011332, 0.065028}, {-0.021796, -0.034777}, - {-0.147394, -0.001241}, {-0.001577, 0.020599}, {-0.083827, -0.028975}, - {-0.177707, 0.066046}, {-0.043241, -0.165144}, { 0.053322, 0.096519}, - {-0.097688, 0.106484}, {-0.023392, 0.111234}, {-0.146747, -0.159360}, - { 0.027241, -0.011806}, {-0.043156, 0.057667}, { 0.019516, -0.062116}, - { 0.025990, 0.162533}, { 0.091888, 0.009720}, {-0.098511, 0.036414}, - { 0.013722, -0.116512}, { 0.054833, -0.180975}, { 0.119497, 0.128774}, - { 0.118378, -0.125997}, { 0.065882, -0.030932}, { 0.120581, -0.039964}, - {-0.050561, -0.088577}, { 0.050134, 0.033194}, {-0.129654, -0.075112}, - {-0.225334, -0.040234}, { 0.070629, -0.084455}, { 0.095508, 0.063548}, - { 0.150514, 0.034366}, { 0.186092, -0.069272} -}; - -static const float *lsf_codebooks[] = { - lsf_cb1[0], lsf_cb2[0], lsf_cb3[0], lsf_cb4[0], lsf_cb5[0] -}; - -static const float gain_cb[128][2] = { - {0.035230, 0.161540}, {0.049223, 0.448359}, {0.057443, 0.809043}, - {0.072434, 1.760306}, {0.111491, 0.566418}, {0.112820, 1.098524}, - {0.143493, 0.726856}, {0.144840, 0.347800}, {0.180341, 1.050010}, - {0.188171, 2.197256}, {0.189771, 0.256947}, {0.198260, 0.484678}, - {0.210622, 0.755825}, {0.220694, 0.590788}, {0.237062, 1.322214}, - {0.255175, 0.338710}, {0.298980, 0.919051}, {0.314627, 0.520961}, - {0.337106, 1.469863}, {0.341422, 2.804546}, {0.363257, 0.736222}, - {0.363881, 0.367640}, {0.369850, 1.937934}, {0.370136, 1.075201}, - {0.397152, 0.549410}, {0.426557, 0.876015}, {0.450686, 0.215588}, - {0.468116, 0.671848}, {0.470495, 1.242034}, {0.474180, 1.739845}, - {0.484875, 0.490564}, {0.498917, 0.971238}, {0.530996, 0.785765}, - {0.539768, 2.130689}, {0.546021, 0.589544}, {0.546632, 3.050846}, - {0.552336, 0.389775}, {0.556302, 1.400103}, {0.559688, 1.105421}, - {0.574140, 0.667513}, {0.595547, 0.828943}, {0.597771, 0.496929}, - {0.617079, 1.863075}, {0.619657, 1.221713}, {0.621172, 0.950275}, - {0.628426, 0.630766}, {0.628689, 4.242164}, {0.640899, 1.529846}, - {0.645813, 0.331127}, {0.653056, 0.748168}, {0.662909, 1.077438}, - {0.669505, 2.631114}, {0.681570, 1.839298}, {0.687844, 0.903400}, - {0.688660, 1.270830}, {0.695070, 0.578227}, {0.697926, 0.428440}, - {0.715454, 0.812355}, {0.729981, 1.539357}, {0.737434, 1.106765}, - {0.740241, 2.033374}, {0.740871, 0.568460}, {0.752689, 0.698461}, - {0.756587, 0.893078}, {0.767797, 0.499246}, {0.768516, 3.712434}, - {0.773153, 1.332360}, {0.786125, 1.042996}, {0.788792, 0.238388}, - {0.790861, 2.273229}, {0.795338, 1.582767}, {0.809621, 0.595501}, - {0.821032, 0.756460}, {0.824590, 0.922925}, {0.826019, 1.186793}, - {0.827426, 1.885076}, {0.830080, 6.088666}, {0.837028, 2.819993}, - {0.845561, 1.490623}, {0.848323, 0.410436}, {0.856522, 0.729725}, - {0.862636, 0.966880}, {0.874561, 1.681660}, {0.874751, 1.177630}, - {0.879289, 2.301300}, {0.886671, 0.613068}, {0.896729, 0.781097}, - {0.904777, 3.484111}, {0.906098, 1.330892}, {0.919182, 1.877203}, - {0.919901, 0.569511}, {0.921772, 1.034126}, {0.922439, 0.376000}, - {0.934221, 1.485214}, {0.938842, 0.869135}, {0.939166, 2.378294}, - {0.958933, 1.122722}, {0.959042, 0.694098}, {0.960995, 1.743430}, - {0.970763, 2.884897}, {0.982881, 0.814506}, {0.990141, 1.330022}, - {0.996447, 1.823381}, {1.000013, 0.967498}, {1.000743, 0.480597}, - {1.008020, 5.095226}, {1.013883, 2.105435}, {1.026438, 0.691312}, - {1.027361, 1.558169}, {1.030123, 3.586526}, {1.033916, 1.118036}, - {1.039315, 2.543360}, {1.068596, 0.836380}, {1.081023, 1.318768}, - {1.093150, 2.267843}, {1.095607, 1.712383}, {1.102816, 1.037334}, - {1.103231, 3.536292}, {1.107320, 0.508615}, {1.150000, 7.999000}, - {1.156731, 1.236772}, {1.168428, 2.268084}, {1.184130, 0.775839}, - {1.210609, 1.511840}, {1.220663, 4.365683}, {1.224016, 0.983179}, - {1.252236, 2.778535}, {1.301176, 1.923126} -}; - -static const float pred[4] = { - 0.200, 0.334, 0.504, 0.691 -}; - -#endif /* AVCODEC_SIPRDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/smacker.c b/tizen/distrib/ffmpeg/libavcodec/smacker.c deleted file mode 100644 index 1d85f68..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/smacker.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Smacker decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Smacker decoder - */ - -/* - * Based on http://wiki.multimedia.cx/index.php?title=Smacker - */ - -#include -#include - -#include "avcodec.h" - -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" -#include "bytestream.h" - -#define SMKTREE_BITS 9 -#define SMK_NODE 0x80000000 - -/* - * Decoder context - */ -typedef struct SmackVContext { - AVCodecContext *avctx; - AVFrame pic; - - int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl; - int mmap_last[3], mclr_last[3], full_last[3], type_last[3]; -} SmackVContext; - -/** - * Context used for code reconstructing - */ -typedef struct HuffContext { - int length; - int maxlength; - int current; - uint32_t *bits; - int *lengths; - int *values; -} HuffContext; - -/* common parameters used for decode_bigtree */ -typedef struct DBCtx { - VLC *v1, *v2; - int *recode1, *recode2; - int escapes[3]; - int *last; - int lcur; -} DBCtx; - -/* possible runs of blocks */ -static const int block_runs[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, 128, 256, 512, 1024, 2048 }; - -enum SmkBlockTypes { - SMK_BLK_MONO = 0, - SMK_BLK_FULL = 1, - SMK_BLK_SKIP = 2, - SMK_BLK_FILL = 3 }; - -/** - * Decode local frame tree - */ -static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) -{ - if(!get_bits1(gb)){ //Leaf - if(hc->current >= 256){ - av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); - return -1; - } - if(length){ - hc->bits[hc->current] = prefix; - hc->lengths[hc->current] = length; - } else { - hc->bits[hc->current] = 0; - hc->lengths[hc->current] = 0; - } - hc->values[hc->current] = get_bits(gb, 8); - hc->current++; - if(hc->maxlength < length) - hc->maxlength = length; - return 0; - } else { //Node - int r; - length++; - r = smacker_decode_tree(gb, hc, prefix, length); - if(r) - return r; - return smacker_decode_tree(gb, hc, prefix | (1 << (length - 1)), length); - } -} - -/** - * Decode header tree - */ -static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) -{ - if(!get_bits1(gb)){ //Leaf - int val, i1, i2, b1, b2; - if(hc->current >= hc->length){ - av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); - return -1; - } - b1 = get_bits_count(gb); - i1 = get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3); - b1 = get_bits_count(gb) - b1; - b2 = get_bits_count(gb); - i2 = get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3); - b2 = get_bits_count(gb) - b2; - val = ctx->recode1[i1] | (ctx->recode2[i2] << 8); - if(val == ctx->escapes[0]) { - ctx->last[0] = hc->current; - val = 0; - } else if(val == ctx->escapes[1]) { - ctx->last[1] = hc->current; - val = 0; - } else if(val == ctx->escapes[2]) { - ctx->last[2] = hc->current; - val = 0; - } - - hc->values[hc->current++] = val; - return 1; - } else { //Node - int r = 0, t; - - t = hc->current++; - r = smacker_decode_bigtree(gb, hc, ctx); - if(r < 0) - return r; - hc->values[t] = SMK_NODE | r; - r++; - r += smacker_decode_bigtree(gb, hc, ctx); - return r; - } -} - -/** - * Store large tree as FFmpeg's vlc codes - */ -static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) -{ - int res; - HuffContext huff; - HuffContext tmp1, tmp2; - VLC vlc[2]; - int escapes[3]; - DBCtx ctx; - - if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow - av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); - return -1; - } - - tmp1.length = 256; - tmp1.maxlength = 0; - tmp1.current = 0; - tmp1.bits = av_mallocz(256 * 4); - tmp1.lengths = av_mallocz(256 * sizeof(int)); - tmp1.values = av_mallocz(256 * sizeof(int)); - - tmp2.length = 256; - tmp2.maxlength = 0; - tmp2.current = 0; - tmp2.bits = av_mallocz(256 * 4); - tmp2.lengths = av_mallocz(256 * sizeof(int)); - tmp2.values = av_mallocz(256 * sizeof(int)); - - memset(&vlc[0], 0, sizeof(VLC)); - memset(&vlc[1], 0, sizeof(VLC)); - - if(get_bits1(gb)) { - smacker_decode_tree(gb, &tmp1, 0, 0); - skip_bits1(gb); - res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length, - tmp1.lengths, sizeof(int), sizeof(int), - tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); - if(res < 0) { - av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return -1; - } - } else { - av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n"); - } - if(get_bits1(gb)){ - smacker_decode_tree(gb, &tmp2, 0, 0); - skip_bits1(gb); - res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length, - tmp2.lengths, sizeof(int), sizeof(int), - tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); - if(res < 0) { - av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return -1; - } - } else { - av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n"); - } - - escapes[0] = get_bits(gb, 8); - escapes[0] |= get_bits(gb, 8) << 8; - escapes[1] = get_bits(gb, 8); - escapes[1] |= get_bits(gb, 8) << 8; - escapes[2] = get_bits(gb, 8); - escapes[2] |= get_bits(gb, 8) << 8; - - last[0] = last[1] = last[2] = -1; - - ctx.escapes[0] = escapes[0]; - ctx.escapes[1] = escapes[1]; - ctx.escapes[2] = escapes[2]; - ctx.v1 = &vlc[0]; - ctx.v2 = &vlc[1]; - ctx.recode1 = tmp1.values; - ctx.recode2 = tmp2.values; - ctx.last = last; - - huff.length = ((size + 3) >> 2) + 3; - huff.maxlength = 0; - huff.current = 0; - huff.values = av_mallocz(huff.length * sizeof(int)); - - smacker_decode_bigtree(gb, &huff, &ctx); - skip_bits1(gb); - if(ctx.last[0] == -1) ctx.last[0] = huff.current++; - if(ctx.last[1] == -1) ctx.last[1] = huff.current++; - if(ctx.last[2] == -1) ctx.last[2] = huff.current++; - - *recodes = huff.values; - - if(vlc[0].table) - free_vlc(&vlc[0]); - if(vlc[1].table) - free_vlc(&vlc[1]); - av_free(tmp1.bits); - av_free(tmp1.lengths); - av_free(tmp1.values); - av_free(tmp2.bits); - av_free(tmp2.lengths); - av_free(tmp2.values); - - return 0; -} - -static int decode_header_trees(SmackVContext *smk) { - GetBitContext gb; - int mmap_size, mclr_size, full_size, type_size; - - mmap_size = AV_RL32(smk->avctx->extradata); - mclr_size = AV_RL32(smk->avctx->extradata + 4); - full_size = AV_RL32(smk->avctx->extradata + 8); - type_size = AV_RL32(smk->avctx->extradata + 12); - - init_get_bits(&gb, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8); - - if(!get_bits1(&gb)) { - av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); - smk->mmap_tbl = av_malloc(sizeof(int) * 2); - smk->mmap_tbl[0] = 0; - smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; - } else { - smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); - } - if(!get_bits1(&gb)) { - av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); - smk->mclr_tbl = av_malloc(sizeof(int) * 2); - smk->mclr_tbl[0] = 0; - smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; - } else { - smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); - } - if(!get_bits1(&gb)) { - av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); - smk->full_tbl = av_malloc(sizeof(int) * 2); - smk->full_tbl[0] = 0; - smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; - } else { - smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); - } - if(!get_bits1(&gb)) { - av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); - smk->type_tbl = av_malloc(sizeof(int) * 2); - smk->type_tbl[0] = 0; - smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; - } else { - smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size); - } - - return 0; -} - -static av_always_inline void last_reset(int *recode, int *last) { - recode[last[0]] = recode[last[1]] = recode[last[2]] = 0; -} - -/* get code and update history */ -static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) { - register int *table = recode; - int v, b; - - b = get_bits_count(gb); - while(*table & SMK_NODE) { - if(get_bits1(gb)) - table += (*table) & (~SMK_NODE); - table++; - } - v = *table; - b = get_bits_count(gb) - b; - - if(v != recode[last[0]]) { - recode[last[2]] = recode[last[1]]; - recode[last[1]] = recode[last[0]]; - recode[last[0]] = v; - } - return v; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - SmackVContext * const smk = avctx->priv_data; - uint8_t *out; - uint32_t *pal; - GetBitContext gb; - int blocks, blk, bw, bh; - int i; - int stride; - - if(buf_size <= 769) - return 0; - if(smk->pic.data[0]) - avctx->release_buffer(avctx, &smk->pic); - - smk->pic.reference = 1; - smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if(avctx->reget_buffer(avctx, &smk->pic) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - /* make the palette available on the way out */ - pal = (uint32_t*)smk->pic.data[1]; - smk->pic.palette_has_changed = buf[0] & 1; - smk->pic.key_frame = !!(buf[0] & 2); - if(smk->pic.key_frame) - smk->pic.pict_type = FF_I_TYPE; - else - smk->pic.pict_type = FF_P_TYPE; - - buf++; - for(i = 0; i < 256; i++) - *pal++ = bytestream_get_be24(&buf); - buf_size -= 769; - - last_reset(smk->mmap_tbl, smk->mmap_last); - last_reset(smk->mclr_tbl, smk->mclr_last); - last_reset(smk->full_tbl, smk->full_last); - last_reset(smk->type_tbl, smk->type_last); - init_get_bits(&gb, buf, buf_size * 8); - - blk = 0; - bw = avctx->width >> 2; - bh = avctx->height >> 2; - blocks = bw * bh; - out = smk->pic.data[0]; - stride = smk->pic.linesize[0]; - while(blk < blocks) { - int type, run, mode; - uint16_t pix; - - type = smk_get_code(&gb, smk->type_tbl, smk->type_last); - run = block_runs[(type >> 2) & 0x3F]; - switch(type & 3){ - case SMK_BLK_MONO: - while(run-- && blk < blocks){ - int clr, map; - int hi, lo; - clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); - map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); - out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; - hi = clr >> 8; - lo = clr & 0xFF; - for(i = 0; i < 4; i++) { - if(map & 1) out[0] = hi; else out[0] = lo; - if(map & 2) out[1] = hi; else out[1] = lo; - if(map & 4) out[2] = hi; else out[2] = lo; - if(map & 8) out[3] = hi; else out[3] = lo; - map >>= 4; - out += stride; - } - blk++; - } - break; - case SMK_BLK_FULL: - mode = 0; - if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes - if(get_bits1(&gb)) mode = 1; - else if(get_bits1(&gb)) mode = 2; - } - while(run-- && blk < blocks){ - out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; - switch(mode){ - case 0: - for(i = 0; i < 4; i++) { - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); - AV_WL16(out+2,pix); - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); - AV_WL16(out,pix); - out += stride; - } - break; - case 1: - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); - out[0] = out[1] = pix & 0xFF; - out[2] = out[3] = pix >> 8; - out += stride; - out[0] = out[1] = pix & 0xFF; - out[2] = out[3] = pix >> 8; - out += stride; - pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); - out[0] = out[1] = pix & 0xFF; - out[2] = out[3] = pix >> 8; - out += stride; - out[0] = out[1] = pix & 0xFF; - out[2] = out[3] = pix >> 8; - out += stride; - break; - case 2: - for(i = 0; i < 2; i++) { - uint16_t pix1, pix2; - pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); - pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); - AV_WL16(out,pix1); - AV_WL16(out+2,pix2); - out += stride; - AV_WL16(out,pix1); - AV_WL16(out+2,pix2); - out += stride; - } - break; - } - blk++; - } - break; - case SMK_BLK_SKIP: - while(run-- && blk < blocks) - blk++; - break; - case SMK_BLK_FILL: - mode = type >> 8; - while(run-- && blk < blocks){ - uint32_t col; - out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; - col = mode * 0x01010101; - for(i = 0; i < 4; i++) { - *((uint32_t*)out) = col; - out += stride; - } - blk++; - } - break; - } - - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = smk->pic; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - - - -/* - * - * Init smacker decoder - * - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - SmackVContext * const c = avctx->priv_data; - - c->avctx = avctx; - - avctx->pix_fmt = PIX_FMT_PAL8; - - - /* decode huffman trees from extradata */ - if(avctx->extradata_size < 16){ - av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); - return -1; - } - - decode_header_trees(c); - - - return 0; -} - - - -/* - * - * Uninit smacker decoder - * - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - SmackVContext * const smk = avctx->priv_data; - - av_freep(&smk->mmap_tbl); - av_freep(&smk->mclr_tbl); - av_freep(&smk->full_tbl); - av_freep(&smk->type_tbl); - - if (smk->pic.data[0]) - avctx->release_buffer(avctx, &smk->pic); - - return 0; -} - - -static av_cold int smka_decode_init(AVCodecContext *avctx) -{ - avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; - avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? SAMPLE_FMT_U8 : SAMPLE_FMT_S16; - return 0; -} - -/** - * Decode Smacker audio data - */ -static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - GetBitContext gb; - HuffContext h[4]; - VLC vlc[4]; - int16_t *samples = data; - int8_t *samples8 = data; - int val; - int i, res; - int unp_size; - int bits, stereo; - int pred[2] = {0, 0}; - - unp_size = AV_RL32(buf); - - init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); - - if(!get_bits1(&gb)){ - av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); - *data_size = 0; - return 1; - } - stereo = get_bits1(&gb); - bits = get_bits1(&gb); - if (unp_size & 0xC0000000 || unp_size > *data_size) { - av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); - return -1; - } - - memset(vlc, 0, sizeof(VLC) * 4); - memset(h, 0, sizeof(HuffContext) * 4); - // Initialize - for(i = 0; i < (1 << (bits + stereo)); i++) { - h[i].length = 256; - h[i].maxlength = 0; - h[i].current = 0; - h[i].bits = av_mallocz(256 * 4); - h[i].lengths = av_mallocz(256 * sizeof(int)); - h[i].values = av_mallocz(256 * sizeof(int)); - skip_bits1(&gb); - smacker_decode_tree(&gb, &h[i], 0, 0); - skip_bits1(&gb); - if(h[i].current > 1) { - res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, - h[i].lengths, sizeof(int), sizeof(int), - h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); - if(res < 0) { - av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - return -1; - } - } - } - if(bits) { //decode 16-bit data - for(i = stereo; i >= 0; i--) - pred[i] = bswap_16(get_bits(&gb, 16)); - for(i = 0; i < stereo; i++) - *samples++ = pred[i]; - for(i = 0; i < unp_size / 2; i++) { - if(i & stereo) { - if(vlc[2].table) - res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); - else - res = 0; - val = h[2].values[res]; - if(vlc[3].table) - res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); - else - res = 0; - val |= h[3].values[res] << 8; - pred[1] += (int16_t)val; - *samples++ = pred[1]; - } else { - if(vlc[0].table) - res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); - else - res = 0; - val = h[0].values[res]; - if(vlc[1].table) - res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); - else - res = 0; - val |= h[1].values[res] << 8; - pred[0] += val; - *samples++ = pred[0]; - } - } - } else { //8-bit data - for(i = stereo; i >= 0; i--) - pred[i] = get_bits(&gb, 8); - for(i = 0; i < stereo; i++) - *samples8++ = pred[i]; - for(i = 0; i < unp_size; i++) { - if(i & stereo){ - if(vlc[1].table) - res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); - else - res = 0; - pred[1] += (int8_t)h[1].values[res]; - *samples8++ = pred[1]; - } else { - if(vlc[0].table) - res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); - else - res = 0; - pred[0] += (int8_t)h[0].values[res]; - *samples8++ = pred[0]; - } - } - } - - for(i = 0; i < 4; i++) { - if(vlc[i].table) - free_vlc(&vlc[i]); - if(h[i].bits) - av_free(h[i].bits); - if(h[i].lengths) - av_free(h[i].lengths); - if(h[i].values) - av_free(h[i].values); - } - - *data_size = unp_size; - return buf_size; -} - -AVCodec smacker_decoder = { - "smackvid", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SMACKVIDEO, - sizeof(SmackVContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), -}; - -AVCodec smackaud_decoder = { - "smackaud", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_SMACKAUDIO, - 0, - smka_decode_init, - NULL, - NULL, - smka_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/smc.c b/tizen/distrib/ffmpeg/libavcodec/smc.c deleted file mode 100644 index 2e2dffd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/smc.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Quicktime Graphics (SMC) Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QT SMC Video Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the SMC format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * The SMC decoder outputs PAL8 colorspace data. - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#define CPAIR 2 -#define CQUAD 4 -#define COCTET 8 - -#define COLORS_PER_TABLE 256 - -typedef struct SmcContext { - - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *buf; - int size; - - /* SMC color tables */ - unsigned char color_pairs[COLORS_PER_TABLE * CPAIR]; - unsigned char color_quads[COLORS_PER_TABLE * CQUAD]; - unsigned char color_octets[COLORS_PER_TABLE * COCTET]; - -} SmcContext; - -#define GET_BLOCK_COUNT() \ - (opcode & 0x10) ? (1 + s->buf[stream_ptr++]) : 1 + (opcode & 0x0F); - -#define ADVANCE_BLOCK() \ -{ \ - pixel_ptr += 4; \ - if (pixel_ptr >= width) \ - { \ - pixel_ptr = 0; \ - row_ptr += stride * 4; \ - } \ - total_blocks--; \ - if (total_blocks < 0) \ - { \ - av_log(s->avctx, AV_LOG_INFO, "warning: block counter just went negative (this should not happen)\n"); \ - return; \ - } \ -} - -static void smc_decode_stream(SmcContext *s) -{ - int width = s->avctx->width; - int height = s->avctx->height; - int stride = s->frame.linesize[0]; - int i; - int stream_ptr = 0; - int chunk_size; - unsigned char opcode; - int n_blocks; - unsigned int color_flags; - unsigned int color_flags_a; - unsigned int color_flags_b; - unsigned int flag_mask; - - unsigned char *pixels = s->frame.data[0]; - - int image_size = height * s->frame.linesize[0]; - int row_ptr = 0; - int pixel_ptr = 0; - int pixel_x, pixel_y; - int row_inc = stride - 4; - int block_ptr; - int prev_block_ptr; - int prev_block_ptr1, prev_block_ptr2; - int prev_block_flag; - int total_blocks; - int color_table_index; /* indexes to color pair, quad, or octet tables */ - int pixel; - - int color_pair_index = 0; - int color_quad_index = 0; - int color_octet_index = 0; - - /* make the palette available */ - memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); - if (s->avctx->palctrl->palette_changed) { - s->frame.palette_has_changed = 1; - s->avctx->palctrl->palette_changed = 0; - } - - chunk_size = AV_RB32(&s->buf[stream_ptr]) & 0x00FFFFFF; - stream_ptr += 4; - if (chunk_size != s->size) - av_log(s->avctx, AV_LOG_INFO, "warning: MOV chunk size != encoded chunk size (%d != %d); using MOV chunk size\n", - chunk_size, s->size); - - chunk_size = s->size; - total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4); - - /* traverse through the blocks */ - while (total_blocks) { - /* sanity checks */ - /* make sure stream ptr hasn't gone out of bounds */ - if (stream_ptr > chunk_size) { - av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (stream ptr = %d, chunk size = %d)\n", - stream_ptr, chunk_size); - return; - } - /* make sure the row pointer hasn't gone wild */ - if (row_ptr >= image_size) { - av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (row ptr = %d, height = %d)\n", - row_ptr, image_size); - return; - } - - opcode = s->buf[stream_ptr++]; - switch (opcode & 0xF0) { - /* skip n blocks */ - case 0x00: - case 0x10: - n_blocks = GET_BLOCK_COUNT(); - while (n_blocks--) { - ADVANCE_BLOCK(); - } - break; - - /* repeat last block n times */ - case 0x20: - case 0x30: - n_blocks = GET_BLOCK_COUNT(); - - /* sanity check */ - if ((row_ptr == 0) && (pixel_ptr == 0)) { - av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but no blocks rendered yet\n", - opcode & 0xF0); - break; - } - - /* figure out where the previous block started */ - if (pixel_ptr == 0) - prev_block_ptr1 = - (row_ptr - s->avctx->width * 4) + s->avctx->width - 4; - else - prev_block_ptr1 = row_ptr + pixel_ptr - 4; - - while (n_blocks--) { - block_ptr = row_ptr + pixel_ptr; - prev_block_ptr = prev_block_ptr1; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) { - pixels[block_ptr++] = pixels[prev_block_ptr++]; - } - block_ptr += row_inc; - prev_block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* repeat previous pair of blocks n times */ - case 0x40: - case 0x50: - n_blocks = GET_BLOCK_COUNT(); - n_blocks *= 2; - - /* sanity check */ - if ((row_ptr == 0) && (pixel_ptr < 2 * 4)) { - av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but not enough blocks rendered yet\n", - opcode & 0xF0); - break; - } - - /* figure out where the previous 2 blocks started */ - if (pixel_ptr == 0) - prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + - s->avctx->width - 4 * 2; - else if (pixel_ptr == 4) - prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + row_inc; - else - prev_block_ptr1 = row_ptr + pixel_ptr - 4 * 2; - - if (pixel_ptr == 0) - prev_block_ptr2 = (row_ptr - s->avctx->width * 4) + row_inc; - else - prev_block_ptr2 = row_ptr + pixel_ptr - 4; - - prev_block_flag = 0; - while (n_blocks--) { - block_ptr = row_ptr + pixel_ptr; - if (prev_block_flag) - prev_block_ptr = prev_block_ptr2; - else - prev_block_ptr = prev_block_ptr1; - prev_block_flag = !prev_block_flag; - - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) { - pixels[block_ptr++] = pixels[prev_block_ptr++]; - } - block_ptr += row_inc; - prev_block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* 1-color block encoding */ - case 0x60: - case 0x70: - n_blocks = GET_BLOCK_COUNT(); - pixel = s->buf[stream_ptr++]; - - while (n_blocks--) { - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) { - pixels[block_ptr++] = pixel; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* 2-color block encoding */ - case 0x80: - case 0x90: - n_blocks = (opcode & 0x0F) + 1; - - /* figure out which color pair to use to paint the 2-color block */ - if ((opcode & 0xF0) == 0x80) { - /* fetch the next 2 colors from bytestream and store in next - * available entry in the color pair table */ - for (i = 0; i < CPAIR; i++) { - pixel = s->buf[stream_ptr++]; - color_table_index = CPAIR * color_pair_index + i; - s->color_pairs[color_table_index] = pixel; - } - /* this is the base index to use for this block */ - color_table_index = CPAIR * color_pair_index; - color_pair_index++; - /* wraparound */ - if (color_pair_index == COLORS_PER_TABLE) - color_pair_index = 0; - } else - color_table_index = CPAIR * s->buf[stream_ptr++]; - - while (n_blocks--) { - color_flags = AV_RB16(&s->buf[stream_ptr]); - stream_ptr += 2; - flag_mask = 0x8000; - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) { - if (color_flags & flag_mask) - pixel = color_table_index + 1; - else - pixel = color_table_index; - flag_mask >>= 1; - pixels[block_ptr++] = s->color_pairs[pixel]; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* 4-color block encoding */ - case 0xA0: - case 0xB0: - n_blocks = (opcode & 0x0F) + 1; - - /* figure out which color quad to use to paint the 4-color block */ - if ((opcode & 0xF0) == 0xA0) { - /* fetch the next 4 colors from bytestream and store in next - * available entry in the color quad table */ - for (i = 0; i < CQUAD; i++) { - pixel = s->buf[stream_ptr++]; - color_table_index = CQUAD * color_quad_index + i; - s->color_quads[color_table_index] = pixel; - } - /* this is the base index to use for this block */ - color_table_index = CQUAD * color_quad_index; - color_quad_index++; - /* wraparound */ - if (color_quad_index == COLORS_PER_TABLE) - color_quad_index = 0; - } else - color_table_index = CQUAD * s->buf[stream_ptr++]; - - while (n_blocks--) { - color_flags = AV_RB32(&s->buf[stream_ptr]); - stream_ptr += 4; - /* flag mask actually acts as a bit shift count here */ - flag_mask = 30; - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) { - pixel = color_table_index + - ((color_flags >> flag_mask) & 0x03); - flag_mask -= 2; - pixels[block_ptr++] = s->color_quads[pixel]; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* 8-color block encoding */ - case 0xC0: - case 0xD0: - n_blocks = (opcode & 0x0F) + 1; - - /* figure out which color octet to use to paint the 8-color block */ - if ((opcode & 0xF0) == 0xC0) { - /* fetch the next 8 colors from bytestream and store in next - * available entry in the color octet table */ - for (i = 0; i < COCTET; i++) { - pixel = s->buf[stream_ptr++]; - color_table_index = COCTET * color_octet_index + i; - s->color_octets[color_table_index] = pixel; - } - /* this is the base index to use for this block */ - color_table_index = COCTET * color_octet_index; - color_octet_index++; - /* wraparound */ - if (color_octet_index == COLORS_PER_TABLE) - color_octet_index = 0; - } else - color_table_index = COCTET * s->buf[stream_ptr++]; - - while (n_blocks--) { - /* - For this input of 6 hex bytes: - 01 23 45 67 89 AB - Mangle it to this output: - flags_a = xx012456, flags_b = xx89A37B - */ - /* build the color flags */ - color_flags_a = - ((AV_RB16(s->buf + stream_ptr ) & 0xFFF0) << 8) | - (AV_RB16(s->buf + stream_ptr + 2) >> 4); - color_flags_b = - ((AV_RB16(s->buf + stream_ptr + 4) & 0xFFF0) << 8) | - ((s->buf[stream_ptr + 1] & 0x0F) << 8) | - ((s->buf[stream_ptr + 3] & 0x0F) << 4) | - (s->buf[stream_ptr + 5] & 0x0F); - stream_ptr += 6; - - color_flags = color_flags_a; - /* flag mask actually acts as a bit shift count here */ - flag_mask = 21; - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - /* reload flags at third row (iteration pixel_y == 2) */ - if (pixel_y == 2) { - color_flags = color_flags_b; - flag_mask = 21; - } - for (pixel_x = 0; pixel_x < 4; pixel_x++) { - pixel = color_table_index + - ((color_flags >> flag_mask) & 0x07); - flag_mask -= 3; - pixels[block_ptr++] = s->color_octets[pixel]; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - /* 16-color block encoding (every pixel is a different color) */ - case 0xE0: - n_blocks = (opcode & 0x0F) + 1; - - while (n_blocks--) { - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++) { - pixels[block_ptr++] = s->buf[stream_ptr++]; - } - block_ptr += row_inc; - } - ADVANCE_BLOCK(); - } - break; - - case 0xF0: - av_log(s->avctx, AV_LOG_INFO, "0xF0 opcode seen in SMC chunk (contact the developers)\n"); - break; - } - } -} - -static av_cold int smc_decode_init(AVCodecContext *avctx) -{ - SmcContext *s = avctx->priv_data; - - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - s->frame.data[0] = NULL; - - return 0; -} - -static int smc_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - SmcContext *s = avctx->priv_data; - - s->buf = 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 | FF_BUFFER_HINTS_READABLE; - if (avctx->reget_buffer(avctx, &s->frame)) { - av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - - smc_decode_stream(s); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int smc_decode_end(AVCodecContext *avctx) -{ - SmcContext *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec smc_decoder = { - "smc", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SMC, - sizeof(SmcContext), - smc_decode_init, - NULL, - smc_decode_end, - smc_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/snow.c b/tizen/distrib/ffmpeg/libavcodec/snow.c deleted file mode 100644 index 5ef9e5e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/snow.c +++ /dev/null @@ -1,4150 +0,0 @@ -/* - * Copyright (C) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intmath.h" -#include "avcodec.h" -#include "dsputil.h" -#include "dwt.h" -#include "snow.h" - -#include "rangecoder.h" -#include "mathops.h" - -#include "mpegvideo.h" -#include "h263.h" - -#undef NDEBUG -#include - -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 quant3b[256]={ - 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,-1,-1, -}; -static const int8_t quant3bA[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,-1, -}; -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, -}; - -#if 0 //64*cubic -static const uint8_t obmc32[1024]={ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, - 0, 0, 4, 4, 8, 8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12, 8, 8, 4, 4, 0, 0, - 0, 0, 4, 8, 8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12, 8, 8, 4, 0, 0, - 0, 4, 4, 8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12, 8, 4, 4, 0, - 0, 4, 4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12, 4, 4, 0, - 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16, 8, 4, 0, - 0, 4, 8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16, 8, 4, 0, - 0, 4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12, 4, 0, - 0, 4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12, 4, 0, - 0, 4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12, 4, 0, - 0, 4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16, 4, 0, - 0, 8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16, 8, 0, - 0, 4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16, 4, 0, - 1, 8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16, 8, 1, - 1, 8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16, 8, 1, - 0, 4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16, 4, 0, - 0, 8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16, 8, 0, - 0, 4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16, 4, 0, - 0, 4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12, 4, 0, - 0, 4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12, 4, 0, - 0, 4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12, 4, 0, - 0, 4, 8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16, 8, 4, 0, - 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16, 8, 4, 0, - 0, 4, 4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12, 4, 4, 0, - 0, 4, 4, 8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12, 8, 4, 4, 0, - 0, 0, 4, 8, 8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12, 8, 8, 4, 0, 0, - 0, 0, 4, 4, 8, 8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12, 8, 8, 4, 4, 0, 0, - 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//error:0.000022 -}; -static const uint8_t obmc16[256]={ - 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, - 0, 4, 4, 8, 16, 20, 20, 24, 24, 20, 20, 16, 8, 4, 4, 0, - 0, 4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16, 4, 0, - 0, 8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24, 8, 0, - 0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16, 0, - 0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20, 0, - 4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20, 4, - 4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24, 4, - 4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24, 4, - 4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20, 4, - 0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20, 0, - 0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16, 0, - 0, 8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24, 8, 0, - 0, 4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16, 4, 0, - 0, 4, 4, 8, 16, 20, 20, 24, 24, 20, 20, 16, 8, 4, 4, 0, - 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, -//error:0.000033 -}; -#elif 1 // 64*linear -static const uint8_t obmc32[1024]={ - 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, - 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0, - 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0, - 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0, - 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4, - 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4, - 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4, - 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4, - 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4, - 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4, - 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4, - 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4, - 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8, - 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8, - 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8, - 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8, - 8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8, - 8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8, - 8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8, - 8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8, - 4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4, - 4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4, - 4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4, - 4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4, - 4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4, - 4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4, - 4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4, - 4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4, - 0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0, - 0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0, - 0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0, - 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, - //error:0.000020 -}; -static const uint8_t obmc16[256]={ - 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0, - 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4, - 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4, - 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8, - 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8, - 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12, - 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12, - 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16, - 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16, - 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12, - 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12, - 8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8, - 8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8, - 4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4, - 4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4, - 0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0, -//error:0.000015 -}; -#else //64*cos -static const uint8_t obmc32[1024]={ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, - 0, 0, 4, 4, 4, 8, 8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12, 8, 8, 4, 4, 4, 0, 0, - 0, 0, 4, 4, 8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12, 8, 4, 4, 0, 0, - 0, 0, 4, 8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12, 8, 4, 0, 0, - 0, 4, 4, 8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16, 8, 4, 4, 0, - 0, 4, 8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12, 8, 4, 0, - 0, 4, 8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16, 8, 4, 0, - 0, 4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12, 4, 0, - 0, 4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12, 4, 0, - 0, 4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12, 4, 0, - 0, 4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12, 4, 0, - 0, 4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12, 4, 0, - 0, 4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16, 4, 0, - 1, 4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16, 4, 1, - 1, 4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16, 4, 1, - 0, 4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16, 4, 0, - 0, 4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12, 4, 0, - 0, 4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12, 4, 0, - 0, 4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12, 4, 0, - 0, 4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12, 4, 0, - 0, 4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12, 4, 0, - 0, 4, 8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16, 8, 4, 0, - 0, 4, 8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12, 8, 4, 0, - 0, 4, 4, 8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16, 8, 4, 4, 0, - 0, 0, 4, 8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12, 8, 4, 0, 0, - 0, 0, 4, 4, 8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12, 8, 4, 4, 0, 0, - 0, 0, 4, 4, 4, 8, 8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12, 8, 8, 4, 4, 4, 0, 0, - 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//error:0.000022 -}; -static const uint8_t obmc16[256]={ - 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, - 0, 0, 4, 8, 12, 16, 20, 20, 20, 20, 16, 12, 8, 4, 0, 0, - 0, 4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12, 4, 0, - 0, 8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24, 8, 0, - 0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12, 0, - 4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16, 4, - 4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20, 4, - 0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20, 0, - 0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20, 0, - 4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20, 4, - 4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16, 4, - 0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12, 0, - 0, 8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24, 8, 0, - 0, 4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12, 4, 0, - 0, 0, 4, 8, 12, 16, 20, 20, 20, 20, 16, 12, 8, 4, 0, 0, - 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, -//error:0.000022 -}; -#endif /* 0 */ - -//linear *64 -static const uint8_t obmc8[64]={ - 4, 12, 20, 28, 28, 20, 12, 4, - 12, 36, 60, 84, 84, 60, 36, 12, - 20, 60,100,140,140,100, 60, 20, - 28, 84,140,196,196,140, 84, 28, - 28, 84,140,196,196,140, 84, 28, - 20, 60,100,140,140,100, 60, 20, - 12, 36, 60, 84, 84, 60, 36, 12, - 4, 12, 20, 28, 28, 20, 12, 4, -//error:0.000000 -}; - -//linear *64 -static const uint8_t obmc4[16]={ - 16, 48, 48, 16, - 48,144,144, 48, - 48,144,144, 48, - 16, 48, 48, 16, -//error:0.000000 -}; - -static const uint8_t * const obmc_tab[4]={ - obmc32, obmc16, obmc8, obmc4 -}; - -static int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES]; - -typedef struct BlockNode{ - int16_t mx; - int16_t my; - uint8_t ref; - uint8_t color[3]; - uint8_t type; -//#define TYPE_SPLIT 1 -#define BLOCK_INTRA 1 -#define BLOCK_OPT 2 -//#define TYPE_NOCOLOR 4 - uint8_t level; //FIXME merge into type? -}BlockNode; - -static const BlockNode null_block= { //FIXME add border maybe - .color= {128,128,128}, - .mx= 0, - .my= 0, - .ref= 0, - .type= 0, - .level= 0, -}; - -#define LOG2_MB_SIZE 4 -#define MB_SIZE (1<=el; i--){ - put_rac(c, state+22+9, (a>>i)&1); //22..31 - } - for(; i>=0; i--){ - put_rac(c, state+22+i, (a>>i)&1); //22..31 - } - - if(is_signed) - put_rac(c, state+11 + el, v < 0); //11..21 -#else - - put_rac(c, state+0, 0); - if(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{ - for(i=0; i=0; i--){ - put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 - } - - if(is_signed) - put_rac(c, state+11 + 10, v < 0); //11..21 - } -#endif /* 1 */ - }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 + FFMIN(e,9))){ //1..10 - e++; - } - - a= 1; - for(i=e-1; i>=0; i--){ - a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 - } - - e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21 - return (a^e)-e; - } -} - -static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){ - int i; - int r= log2>=0 ? 1<=0); - assert(log2>=-4); - - while(v >= r){ - put_rac(c, state+4+log2, 1); - v -= r; - log2++; - if(log2>0) r+=r; - } - put_rac(c, state+4+log2, 0); - - for(i=log2-1; i>=0; i--){ - put_rac(c, state+31-i, (v>>i)&1); - } -} - -static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){ - int i; - int r= log2>=0 ? 1<=-4); - - while(get_rac(c, state+4+log2)){ - v+= r; - log2++; - if(log2>0) r+=r; - } - - for(i=log2-1; i>=0; i--){ - v+= get_rac(c, state+31-i)<width; - const int h= b->height; - int x,y; - - int run, runs; - x_and_coeff *xc= b->x_coeff; - x_and_coeff *prev_xc= NULL; - x_and_coeff *prev2_xc= xc; - x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL; - x_and_coeff *prev_parent_xc= parent_xc; - - runs= get_symbol2(&s->c, b->state[30], 0); - if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3); - else run= INT_MAX; - - for(y=0; yx == 0){ - rt= prev_xc->coeff; - } - for(x=0; xx <= x) - prev_xc++; - if(prev_xc->x == x + 1) - rt= prev_xc->coeff; - else - rt=0; - } - if(parent_xc){ - if(x>>1 > parent_xc->x){ - parent_xc++; - } - if(x>>1 == parent_xc->x){ - p= parent_xc->coeff; - } - } - if(/*ll|*/l|lt|t|rt|p){ - int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1)); - - v=get_rac(&s->c, &b->state[0][context]); - if(v){ - v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1); - v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l&0xFF] + 3*quant3bA[t&0xFF]]); - - xc->x=x; - (xc++)->coeff= v; - } - }else{ - if(!run){ - if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3); - else run= INT_MAX; - v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1); - v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]); - - xc->x=x; - (xc++)->coeff= v; - }else{ - int max_run; - run--; - v=0; - - if(y) max_run= FFMIN(run, prev_xc->x - x - 2); - else max_run= FFMIN(run, w-x-1); - if(parent_xc) - max_run= FFMIN(max_run, 2*parent_xc->x - x - 1); - x+= max_run; - run-= max_run; - } - } - } - (xc++)->x= w+1; //end marker - prev_xc= prev2_xc; - prev2_xc= xc; - - if(parent_xc){ - if(y&1){ - while(parent_xc->x != parent->width+1) - parent_xc++; - parent_xc++; - prev_parent_xc= parent_xc; - }else{ - parent_xc= prev_parent_xc; - } - } - } - - (xc++)->x= w+1; //end marker -} - -static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){ - const int w= b->width; - int y; - const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); - int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); - int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; - int new_index = 0; - - if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){ - qadd= 0; - qmul= 1<stride_line + b->buf_y_offset) + b->buf_x_offset; - memset(line, 0, b->width*sizeof(IDWTELEM)); - v = b->x_coeff[new_index].coeff; - x = b->x_coeff[new_index++].x; - while(x < w){ - register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT; - register int u= -(v&1); - line[x] = (t^u) - u; - - v = b->x_coeff[new_index].coeff; - x = b->x_coeff[new_index++].x; - } - } - - /* Save our variables for the next slice. */ - save_state[0] = new_index; - - return; -} - -static void reset_contexts(SnowContext *s){ //FIXME better initial contexts - int plane_index, level, orientation; - - for(plane_index=0; plane_index<3; plane_index++){ - for(level=0; levelplane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].state)); - } - } - } - memset(s->header_state, MID_STATE, sizeof(s->header_state)); - memset(s->block_state, MID_STATE, sizeof(s->block_state)); -} - -static int alloc_blocks(SnowContext *s){ - int w= -((-s->avctx->width )>>LOG2_MB_SIZE); - int h= -((-s->avctx->height)>>LOG2_MB_SIZE); - - s->b_width = w; - s->b_height= h; - - av_free(s->block); - s->block= av_mallocz(w * h * sizeof(BlockNode) << (s->block_max_depth*2)); - return 0; -} - -static inline void copy_rac_state(RangeCoder *d, RangeCoder *s){ - uint8_t *bytestream= d->bytestream; - uint8_t *bytestream_start= d->bytestream_start; - *d= *s; - d->bytestream= bytestream; - d->bytestream_start= bytestream_start; -} - -static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){ - const int w= s->b_width << s->block_max_depth; - const int rem_depth= s->block_max_depth - level; - const int index= (x + y*w) << rem_depth; - const int block_w= 1<block[index + i + j*w]= block; - } - } -} - -static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){ - const int offset[3]= { - y*c-> stride + x, - ((y*c->uvstride + x)>>1), - ((y*c->uvstride + x)>>1), - }; - int i; - for(i=0; i<3; i++){ - c->src[0][i]= src [i]; - c->ref[0][i]= ref [i] + offset[i]; - } - assert(!ref_index); -} - -static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref, - const BlockNode *left, const BlockNode *top, const BlockNode *tr){ - if(s->ref_frames == 1){ - *mx = mid_pred(left->mx, top->mx, tr->mx); - *my = mid_pred(left->my, top->my, tr->my); - }else{ - const int *scale = scale_mv_ref[ref]; - *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8, - (top ->mx * scale[top ->ref] + 128) >>8, - (tr ->mx * scale[tr ->ref] + 128) >>8); - *my = mid_pred((left->my * scale[left->ref] + 128) >>8, - (top ->my * scale[top ->ref] + 128) >>8, - (tr ->my * scale[tr ->ref] + 128) >>8); - } -} - -static av_always_inline int same_block(BlockNode *a, BlockNode *b){ - if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){ - return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2])); - }else{ - return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA)); - } -} - -static void decode_q_branch(SnowContext *s, int level, int x, int y){ - const int w= s->b_width << s->block_max_depth; - const int rem_depth= s->block_max_depth - level; - const int index= (x + y*w) << rem_depth; - int trx= (x+1)<block[index-1] : &null_block; - const BlockNode *top = y ? &s->block[index-w] : &null_block; - const BlockNode *tl = y && x ? &s->block[index-w-1] : left; - const BlockNode *tr = y && trxblock[index-w+(1<level + 2*top->level + tl->level + tr->level; - - if(s->keyframe){ - set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA); - return; - } - - if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){ - int type, mx, my; - int l = left->color[0]; - int cb= left->color[1]; - int cr= left->color[2]; - int ref = 0; - int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); - int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx)); - int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my)); - - type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0; - - if(type){ - pred_mv(s, &mx, &my, 0, left, top, tr); - l += get_symbol(&s->c, &s->block_state[32], 1); - cb+= get_symbol(&s->c, &s->block_state[64], 1); - cr+= get_symbol(&s->c, &s->block_state[96], 1); - }else{ - if(s->ref_frames > 1) - ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0); - pred_mv(s, &mx, &my, ref, left, top, tr); - mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1); - my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1); - } - set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type); - }else{ - decode_q_branch(s, level+1, 2*x+0, 2*y+0); - decode_q_branch(s, level+1, 2*x+1, 2*y+0); - decode_q_branch(s, level+1, 2*x+0, 2*y+1); - decode_q_branch(s, level+1, 2*x+1, 2*y+1); - } -} - -static void decode_blocks(SnowContext *s){ - int x, y; - int w= s->b_width; - int h= s->b_height; - - for(y=0; y>4; - - b= needs[l] | needs[r]; - if(p && !p->diag_mc) - b= 15; - - if(b&5){ - for(y=0; y < b_h+HTAPS_MAX-1; y++){ - for(x=0; x < b_w; x++){ - int a_1=src[x + HTAPS_MAX/2-4]; - int a0= src[x + HTAPS_MAX/2-3]; - int a1= src[x + HTAPS_MAX/2-2]; - int a2= src[x + HTAPS_MAX/2-1]; - int a3= src[x + HTAPS_MAX/2+0]; - int a4= src[x + HTAPS_MAX/2+1]; - int a5= src[x + HTAPS_MAX/2+2]; - int a6= src[x + HTAPS_MAX/2+3]; - int am=0; - if(!p || p->fast_mc){ - am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5); - tmpI[x]= am; - am= (am+16)>>5; - }else{ - am= p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6); - tmpI[x]= am; - am= (am+32)>>6; - } - - if(am&(~255)) am= ~(am>>31); - tmp2[x]= am; - } - tmpI+= 64; - tmp2+= stride; - src += stride; - } - src -= stride*y; - } - src += HTAPS_MAX/2 - 1; - tmp2= tmp2t[1]; - - if(b&2){ - for(y=0; y < b_h; y++){ - for(x=0; x < b_w+1; x++){ - int a_1=src[x + (HTAPS_MAX/2-4)*stride]; - int a0= src[x + (HTAPS_MAX/2-3)*stride]; - int a1= src[x + (HTAPS_MAX/2-2)*stride]; - int a2= src[x + (HTAPS_MAX/2-1)*stride]; - int a3= src[x + (HTAPS_MAX/2+0)*stride]; - int a4= src[x + (HTAPS_MAX/2+1)*stride]; - int a5= src[x + (HTAPS_MAX/2+2)*stride]; - int a6= src[x + (HTAPS_MAX/2+3)*stride]; - int am=0; - if(!p || p->fast_mc) - am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 16)>>5; - else - am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 32)>>6; - - if(am&(~255)) am= ~(am>>31); - tmp2[x]= am; - } - src += stride; - tmp2+= stride; - } - src -= stride*y; - } - src += stride*(HTAPS_MAX/2 - 1); - tmp2= tmp2t[2]; - tmpI= tmpIt; - if(b&4){ - for(y=0; y < b_h; y++){ - for(x=0; x < b_w; x++){ - int a_1=tmpI[x + (HTAPS_MAX/2-4)*64]; - int a0= tmpI[x + (HTAPS_MAX/2-3)*64]; - int a1= tmpI[x + (HTAPS_MAX/2-2)*64]; - int a2= tmpI[x + (HTAPS_MAX/2-1)*64]; - int a3= tmpI[x + (HTAPS_MAX/2+0)*64]; - int a4= tmpI[x + (HTAPS_MAX/2+1)*64]; - int a5= tmpI[x + (HTAPS_MAX/2+2)*64]; - int a6= tmpI[x + (HTAPS_MAX/2+3)*64]; - int am=0; - if(!p || p->fast_mc) - am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 512)>>10; - else - am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 2048)>>12; - if(am&(~255)) am= ~(am>>31); - tmp2[x]= am; - } - tmpI+= 64; - tmp2+= stride; - } - } - - hpel[ 0]= src; - hpel[ 1]= tmp2t[0] + stride*(HTAPS_MAX/2-1); - hpel[ 2]= src + 1; - - hpel[ 4]= tmp2t[1]; - hpel[ 5]= tmp2t[2]; - hpel[ 6]= tmp2t[1] + 1; - - hpel[ 8]= src + stride; - hpel[ 9]= hpel[1] + stride; - hpel[10]= hpel[8] + 1; - - if(b==15){ - const uint8_t *src1= hpel[dx/8 + dy/8*4 ]; - const uint8_t *src2= hpel[dx/8 + dy/8*4+1]; - const uint8_t *src3= hpel[dx/8 + dy/8*4+4]; - const uint8_t *src4= hpel[dx/8 + dy/8*4+5]; - dx&=7; - dy&=7; - for(y=0; y < b_h; y++){ - for(x=0; x < b_w; x++){ - dst[x]= ((8-dx)*(8-dy)*src1[x] + dx*(8-dy)*src2[x]+ - (8-dx)* dy *src3[x] + dx* dy *src4[x]+32)>>6; - } - src1+=stride; - src2+=stride; - src3+=stride; - src4+=stride; - dst +=stride; - } - }else{ - const uint8_t *src1= hpel[l]; - const uint8_t *src2= hpel[r]; - int a= weight[((dx&7) + (8*(dy&7)))]; - int b= 8-a; - for(y=0; y < b_h; y++){ - for(x=0; x < b_w; x++){ - dst[x]= (a*src1[x] + b*src2[x] + 4)>>3; - } - src1+=stride; - src2+=stride; - dst +=stride; - } - } -} - -#define mca(dx,dy,b_w)\ -static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\ - uint8_t tmp[stride*(b_w+HTAPS_MAX-1)];\ - assert(h==b_w);\ - mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, tmp, stride, b_w, b_w, dx, dy);\ -} - -mca( 0, 0,16) -mca( 8, 0,16) -mca( 0, 8,16) -mca( 8, 8,16) -mca( 0, 0,8) -mca( 8, 0,8) -mca( 0, 8,8) -mca( 8, 8,8) - -static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){ - if(block->type & BLOCK_INTRA){ - int x, y; - const int color = block->color[plane_index]; - const int color4= color*0x01010101; - if(b_w==32){ - for(y=0; y < b_h; y++){ - *(uint32_t*)&dst[0 + y*stride]= color4; - *(uint32_t*)&dst[4 + y*stride]= color4; - *(uint32_t*)&dst[8 + y*stride]= color4; - *(uint32_t*)&dst[12+ y*stride]= color4; - *(uint32_t*)&dst[16+ y*stride]= color4; - *(uint32_t*)&dst[20+ y*stride]= color4; - *(uint32_t*)&dst[24+ y*stride]= color4; - *(uint32_t*)&dst[28+ y*stride]= color4; - } - }else if(b_w==16){ - for(y=0; y < b_h; y++){ - *(uint32_t*)&dst[0 + y*stride]= color4; - *(uint32_t*)&dst[4 + y*stride]= color4; - *(uint32_t*)&dst[8 + y*stride]= color4; - *(uint32_t*)&dst[12+ y*stride]= color4; - } - }else if(b_w==8){ - for(y=0; y < b_h; y++){ - *(uint32_t*)&dst[0 + y*stride]= color4; - *(uint32_t*)&dst[4 + y*stride]= color4; - } - }else if(b_w==4){ - for(y=0; y < b_h; y++){ - *(uint32_t*)&dst[0 + y*stride]= color4; - } - }else{ - for(y=0; y < b_h; y++){ - for(x=0; x < b_w; x++){ - dst[x + y*stride]= color; - } - } - } - }else{ - uint8_t *src= s->last_picture[block->ref].data[plane_index]; - const int scale= plane_index ? s->mv_scale : 2*s->mv_scale; - int mx= block->mx*scale; - int my= block->my*scale; - const int dx= mx&15; - const int dy= my&15; - const int tab_index= 3 - (b_w>>2) + (b_w>>4); - sx += (mx>>4) - (HTAPS_MAX/2-1); - sy += (my>>4) - (HTAPS_MAX/2-1); - src += sx + sy*stride; - if( (unsigned)sx >= w - b_w - (HTAPS_MAX-2) - || (unsigned)sy >= h - b_h - (HTAPS_MAX-2)){ - ff_emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h); - src= tmp + MB_SIZE; - } -// assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h); -// assert(!(b_w&(b_w-1))); - assert(b_w>1 && b_h>1); - assert((tab_index>=0 && tab_index<4) || b_w==32); - if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc ) - mc_block(&s->plane[plane_index], dst, src, tmp, stride, b_w, b_h, dx, dy); - else if(b_w==32){ - int y; - for(y=0; ydsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride); - s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride); - } - }else if(b_w==b_h) - s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride); - else if(b_w==2*b_h){ - s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst ,src + 3 + 3*stride,stride); - s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride); - }else{ - assert(2*b_w==b_h); - s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst ,src + 3 + 3*stride ,stride); - s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride); - } - } -} - -void ff_snow_inner_add_yblock(const 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){ - int y, x; - IDWTELEM * dst; - for(y=0; y>1); - const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); - const uint8_t *obmc4= obmc3+ (obmc_stride>>1); - dst = slice_buffer_get_line(sb, src_y + y); - for(x=0; x>= 8 - FRAC_BITS; - } - if(add){ - v += dst[x + src_x]; - v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS; - if(v&(~255)) v= ~(v>>31); - dst8[x + y*src_stride] = v; - }else{ - dst[x + src_x] -= v; - } - } - } -} - -//FIXME name cleanup (b_w, block_w, b_width stuff) -static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){ - const int b_width = s->b_width << s->block_max_depth; - const int b_height= s->b_height << s->block_max_depth; - const int b_stride= b_width; - BlockNode *lt= &s->block[b_x + b_y*b_stride]; - BlockNode *rt= lt+1; - BlockNode *lb= lt+b_stride; - BlockNode *rb= lb+1; - uint8_t *block[4]; - int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride; - uint8_t *tmp = s->scratchbuf; - uint8_t *ptmp; - int x,y; - - if(b_x<0){ - lt= rt; - lb= rb; - }else if(b_x + 1 >= b_width){ - rt= lt; - rb= lb; - } - if(b_y<0){ - lt= lb; - rt= rb; - }else if(b_y + 1 >= b_height){ - lb= lt; - rb= rt; - } - - if(src_x<0){ //FIXME merge with prev & always round internal width up to *16 - obmc -= src_x; - b_w += src_x; - if(!sliced && !offset_dst) - dst -= src_x; - src_x=0; - }else if(src_x + b_w > w){ - b_w = w - src_x; - } - if(src_y<0){ - obmc -= src_y*obmc_stride; - b_h += src_y; - if(!sliced && !offset_dst) - dst -= src_y*dst_stride; - src_y=0; - }else if(src_y + b_h> h){ - b_h = h - src_y; - } - - if(b_w<=0 || b_h<=0) return; - - assert(src_stride > 2*MB_SIZE + 5); - - if(!sliced && offset_dst) - dst += src_x + src_y*dst_stride; - dst8+= src_x + src_y*src_stride; -// src += src_x + src_y*src_stride; - - ptmp= tmp + 3*tmp_step; - block[0]= ptmp; - ptmp+=tmp_step; - pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); - - if(same_block(lt, rt)){ - block[1]= block[0]; - }else{ - block[1]= ptmp; - ptmp+=tmp_step; - pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); - } - - if(same_block(lt, lb)){ - block[2]= block[0]; - }else if(same_block(rt, lb)){ - block[2]= block[1]; - }else{ - block[2]= ptmp; - ptmp+=tmp_step; - pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); - } - - if(same_block(lt, rb) ){ - block[3]= block[0]; - }else if(same_block(rt, rb)){ - block[3]= block[1]; - }else if(same_block(lb, rb)){ - block[3]= block[2]; - }else{ - block[3]= ptmp; - pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); - } -#if 0 - for(y=0; y>1); - for(x=0; x>1); - for(x=0; x>1); - uint8_t *obmc4= obmc3+ (obmc_stride>>1); - for(x=0; xdwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); - }else{ - for(y=0; y>1); - const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); - const uint8_t *obmc4= obmc3+ (obmc_stride>>1); - for(x=0; x>= 8 - FRAC_BITS; - } - if(add){ - v += dst[x + y*dst_stride]; - v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS; - if(v&(~255)) v= ~(v>>31); - dst8[x + y*src_stride] = v; - }else{ - dst[x + y*dst_stride] -= v; - } - } - } - } -#endif /* 0 */ -} - -static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){ - Plane *p= &s->plane[plane_index]; - const int mb_w= s->b_width << s->block_max_depth; - const int mb_h= s->b_height << s->block_max_depth; - int x, y, mb_x; - int block_size = MB_SIZE >> s->block_max_depth; - int block_w = plane_index ? block_size/2 : block_size; - const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; - int obmc_stride= plane_index ? block_size : 2*block_size; - int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst8= s->current_picture.data[plane_index]; - int w= p->width; - int h= p->height; - - if(s->keyframe || (s->avctx->debug&512)){ - if(mb_y==mb_h) - return; - - if(add){ - for(y=block_w*mb_y; yline[y]; - for(x=0; x>= FRAC_BITS; - if(v&(~255)) v= ~(v>>31); - dst8[x + y*ref_stride]= v; - } - } - }else{ - for(y=block_w*mb_y; yline[y]; - for(x=0; xplane[plane_index]; - const int mb_w= s->b_width << s->block_max_depth; - const int mb_h= s->b_height << s->block_max_depth; - int x, y, mb_x; - int block_size = MB_SIZE >> s->block_max_depth; - int block_w = plane_index ? block_size/2 : block_size; - const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; - const int obmc_stride= plane_index ? block_size : 2*block_size; - int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst8= s->current_picture.data[plane_index]; - int w= p->width; - int h= p->height; - - if(s->keyframe || (s->avctx->debug&512)){ - if(mb_y==mb_h) - return; - - if(add){ - for(y=block_w*mb_y; y>= FRAC_BITS; - if(v&(~255)) v= ~(v>>31); - dst8[x + y*ref_stride]= v; - } - } - }else{ - for(y=block_w*mb_y; yb_height << s->block_max_depth; - int mb_y; - for(mb_y=0; mb_y<=mb_h; mb_y++) - predict_slice(s, buf, plane_index, add, mb_y); -} - -static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){ - const int w= b->width; - const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); - const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); - const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; - int x,y; - - if(s->qlog == LOSSLESS_QLOG) return; - - for(y=start_y; ystride_line) + b->buf_y_offset) + b->buf_x_offset; - for(x=0; x>(QEXPSHIFT)); //FIXME try different bias - }else if(i>0){ - line[x]= (( i*qmul + qadd)>>(QEXPSHIFT)); - } - } - } -} - -static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){ - const int w= b->width; - int x,y; - - IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning - IDWTELEM * prev; - - if (start_y != 0) - line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset; - - for(y=start_y; ystride_line) + b->buf_y_offset) + b->buf_x_offset; - for(x=0; xspatial_decomposition_count; level++){ - for(orientation=level ? 1:0; orientation<4; orientation++){ - int q; - if (plane_index==2) q= s->plane[1].band[level][orientation].qlog; - else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog; - else q= get_symbol(&s->c, s->header_state, 1); - s->plane[plane_index].band[level][orientation].qlog= q; - } - } - } -} - -#define GET_S(dst, check) \ - tmp= get_symbol(&s->c, s->header_state, 0);\ - if(!(check)){\ - av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\ - return -1;\ - }\ - dst= tmp; - -static int decode_header(SnowContext *s){ - int plane_index, tmp; - uint8_t kstate[32]; - - memset(kstate, MID_STATE, sizeof(kstate)); - - s->keyframe= get_rac(&s->c, kstate); - if(s->keyframe || s->always_reset){ - reset_contexts(s); - s->spatial_decomposition_type= - s->qlog= - s->qbias= - s->mv_scale= - s->block_max_depth= 0; - } - if(s->keyframe){ - GET_S(s->version, tmp <= 0U) - s->always_reset= get_rac(&s->c, s->header_state); - s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0); - s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0); - GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS) - s->colorspace_type= get_symbol(&s->c, s->header_state, 0); - s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0); - s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0); - s->spatial_scalability= get_rac(&s->c, s->header_state); -// s->rate_scalability= get_rac(&s->c, s->header_state); - GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES) - s->max_ref_frames++; - - decode_qlogs(s); - } - - if(!s->keyframe){ - if(get_rac(&s->c, s->header_state)){ - for(plane_index=0; plane_index<2; plane_index++){ - int htaps, i, sum=0; - Plane *p= &s->plane[plane_index]; - p->diag_mc= get_rac(&s->c, s->header_state); - htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2; - if((unsigned)htaps > HTAPS_MAX || htaps==0) - return -1; - p->htaps= htaps; - for(i= htaps/2; i; i--){ - p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1)); - sum += p->hcoeff[i]; - } - p->hcoeff[0]= 32-sum; - } - s->plane[2].diag_mc= s->plane[1].diag_mc; - s->plane[2].htaps = s->plane[1].htaps; - memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff)); - } - if(get_rac(&s->c, s->header_state)){ - GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS) - decode_qlogs(s); - } - } - - s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1); - if(s->spatial_decomposition_type > 1U){ - av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported", s->spatial_decomposition_type); - return -1; - } - if(FFMIN(s->avctx-> width>>s->chroma_h_shift, - s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 0){ - av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size", s->spatial_decomposition_count); - return -1; - } - - s->qlog += get_symbol(&s->c, s->header_state, 1); - s->mv_scale += get_symbol(&s->c, s->header_state, 1); - s->qbias += get_symbol(&s->c, s->header_state, 1); - s->block_max_depth+= get_symbol(&s->c, s->header_state, 1); - if(s->block_max_depth > 1 || s->block_max_depth < 0){ - av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large", s->block_max_depth); - s->block_max_depth= 0; - return -1; - } - - return 0; -} - -static void init_qexp(void){ - int i; - double v=128; - - for(i=0; ipriv_data; - int width, height; - int i, j; - - s->avctx= avctx; - s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe - - dsputil_init(&s->dsp, avctx); - ff_dwt_init(&s->dwt); - -#define mcf(dx,dy)\ - s->dsp.put_qpel_pixels_tab [0][dy+dx/4]=\ - s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\ - s->dsp.put_h264_qpel_pixels_tab[0][dy+dx/4];\ - s->dsp.put_qpel_pixels_tab [1][dy+dx/4]=\ - s->dsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\ - s->dsp.put_h264_qpel_pixels_tab[1][dy+dx/4]; - - mcf( 0, 0) - mcf( 4, 0) - mcf( 8, 0) - mcf(12, 0) - mcf( 0, 4) - mcf( 4, 4) - mcf( 8, 4) - mcf(12, 4) - mcf( 0, 8) - mcf( 4, 8) - mcf( 8, 8) - mcf(12, 8) - mcf( 0,12) - mcf( 4,12) - mcf( 8,12) - mcf(12,12) - -#define mcfh(dx,dy)\ - s->dsp.put_pixels_tab [0][dy/4+dx/8]=\ - s->dsp.put_no_rnd_pixels_tab[0][dy/4+dx/8]=\ - mc_block_hpel ## dx ## dy ## 16;\ - s->dsp.put_pixels_tab [1][dy/4+dx/8]=\ - s->dsp.put_no_rnd_pixels_tab[1][dy/4+dx/8]=\ - mc_block_hpel ## dx ## dy ## 8; - - mcfh(0, 0) - mcfh(8, 0) - mcfh(0, 8) - mcfh(8, 8) - - if(!qexp[0]) - init_qexp(); - -// dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift); - - width= s->avctx->width; - height= s->avctx->height; - - s->spatial_idwt_buffer= av_mallocz(width*height*sizeof(IDWTELEM)); - s->spatial_dwt_buffer= av_mallocz(width*height*sizeof(DWTELEM)); //FIXME this does not belong here - - for(i=0; iavctx->get_buffer(s->avctx, &s->mconly_picture); - s->scratchbuf = av_malloc(s->mconly_picture.linesize[0]*7*MB_SIZE); - - return 0; -} - -static int common_init_after_header(AVCodecContext *avctx){ - SnowContext *s = avctx->priv_data; - int plane_index, level, orientation; - - for(plane_index=0; plane_index<3; plane_index++){ - int w= s->avctx->width; - int h= s->avctx->height; - - if(plane_index){ - w>>= s->chroma_h_shift; - h>>= s->chroma_v_shift; - } - s->plane[plane_index].width = w; - s->plane[plane_index].height= h; - - for(level=s->spatial_decomposition_count-1; level>=0; level--){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &s->plane[plane_index].band[level][orientation]; - - b->buf= s->spatial_dwt_buffer; - b->level= level; - b->stride= s->plane[plane_index].width << (s->spatial_decomposition_count - level); - b->width = (w + !(orientation&1))>>1; - b->height= (h + !(orientation>1))>>1; - - b->stride_line = 1 << (s->spatial_decomposition_count - level); - b->buf_x_offset = 0; - b->buf_y_offset = 0; - - if(orientation&1){ - b->buf += (w+1)>>1; - b->buf_x_offset = (w+1)>>1; - } - if(orientation>1){ - b->buf += b->stride>>1; - b->buf_y_offset = b->stride_line >> 1; - } - b->ibuf= s->spatial_idwt_buffer + (b->buf - s->spatial_dwt_buffer); - - if(level) - b->parent= &s->plane[plane_index].band[level-1][orientation]; - //FIXME avoid this realloc - av_freep(&b->x_coeff); - b->x_coeff=av_mallocz(((b->width+1) * b->height+1)*sizeof(x_and_coeff)); - } - w= (w+1)>>1; - h= (h+1)>>1; - } - } - - return 0; -} - -#define QUANTIZE2 0 - -#if QUANTIZE2==1 -#define Q2_STEP 8 - -static void find_sse(SnowContext *s, Plane *p, int *score, int score_stride, IDWTELEM *r0, IDWTELEM *r1, int level, int orientation){ - SubBand *b= &p->band[level][orientation]; - int x, y; - int xo=0; - int yo=0; - int step= 1 << (s->spatial_decomposition_count - level); - - if(orientation&1) - xo= step>>1; - if(orientation&2) - yo= step>>1; - - //FIXME bias for nonzero ? - //FIXME optimize - memset(score, 0, sizeof(*score)*score_stride*((p->height + Q2_STEP-1)/Q2_STEP)); - for(y=0; yheight; y++){ - for(x=0; xwidth; x++){ - int sx= (x-xo + step/2) / step / Q2_STEP; - int sy= (y-yo + step/2) / step / Q2_STEP; - int v= r0[x + y*p->width] - r1[x + y*p->width]; - assert(sx>=0 && sy>=0 && sx < score_stride); - v= ((v+8)>>4)<<4; - score[sx + sy*score_stride] += v*v; - assert(score[sx + sy*score_stride] >= 0); - } - } -} - -static void dequantize_all(SnowContext *s, Plane *p, IDWTELEM *buffer, int width, int height){ - int level, orientation; - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - IDWTELEM *dst= buffer + (b->ibuf - s->spatial_idwt_buffer); - - dequantize(s, b, dst, b->stride); - } - } -} - -static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, int height, int stride, int type){ - int level, orientation, ys, xs, x, y, pass; - IDWTELEM best_dequant[height * stride]; - IDWTELEM idwt2_buffer[height * stride]; - const int score_stride= (width + 10)/Q2_STEP; - int best_score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size - int score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size - int threshold= (s->m.lambda * s->m.lambda) >> 6; - - //FIXME pass the copy cleanly ? - -// memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM)); - ff_spatial_dwt(buffer, width, height, stride, type, s->spatial_decomposition_count); - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - IDWTELEM *dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer); - DWTELEM *src= buffer + (b-> buf - s->spatial_dwt_buffer); - assert(src == b->buf); // code does not depend on this but it is true currently - - quantize(s, b, dst, src, b->stride, s->qbias); - } - } - for(pass=0; pass<1; pass++){ - if(s->qbias == 0) //keyframe - continue; - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - IDWTELEM *dst= idwt2_buffer + (b->ibuf - s->spatial_idwt_buffer); - IDWTELEM *best_dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer); - - for(ys= 0; ysspatial_decomposition_count); - find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation); - memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); - for(y=ys; yheight; y+= Q2_STEP){ - for(x=xs; xwidth; x+= Q2_STEP){ - if(dst[x + y*b->stride]<0) dst[x + y*b->stride]++; - if(dst[x + y*b->stride]>0) dst[x + y*b->stride]--; - //FIXME try more than just -- - } - } - dequantize_all(s, p, idwt2_buffer, width, height); - ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count); - find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation); - for(y=ys; yheight; y+= Q2_STEP){ - for(x=xs; xwidth; x+= Q2_STEP){ - int score_idx= x/Q2_STEP + (y/Q2_STEP)*score_stride; - if(score[score_idx] <= best_score[score_idx] + threshold){ - best_score[score_idx]= score[score_idx]; - if(best_dst[x + y*b->stride]<0) best_dst[x + y*b->stride]++; - if(best_dst[x + y*b->stride]>0) best_dst[x + y*b->stride]--; - //FIXME copy instead - } - } - } - } - } - } - } - } - memcpy(s->spatial_idwt_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); //FIXME work with that directly instead of copy at the end -} - -#endif /* QUANTIZE2==1 */ - -#define USE_HALFPEL_PLANE 0 - -static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){ - int p,x,y; - - assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE)); - - for(p=0; p<3; p++){ - int is_chroma= !!p; - int w= s->avctx->width >>is_chroma; - int h= s->avctx->height >>is_chroma; - int ls= frame->linesize[p]; - uint8_t *src= frame->data[p]; - - halfpel[1][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls); - halfpel[2][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls); - halfpel[3][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls); - - halfpel[0][p]= src; - for(y=0; y>5; - } - } - for(y=0; y>5; - } - } - src= halfpel[1][p]; - for(y=0; y>5; - } - } - -//FIXME border! - } -} - -static void release_buffer(AVCodecContext *avctx){ - SnowContext *s = avctx->priv_data; - int i; - - if(s->last_picture[s->max_ref_frames-1].data[0]){ - avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]); - for(i=0; i<9; i++) - if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3]) - av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3])); - } -} - -static int frame_start(SnowContext *s){ - AVFrame tmp; - int w= s->avctx->width; //FIXME round up to x16 ? - int h= s->avctx->height; - - if(s->current_picture.data[0]){ - s->dsp.draw_edges(s->current_picture.data[0], s->current_picture.linesize[0], w , h , EDGE_WIDTH ); - s->dsp.draw_edges(s->current_picture.data[1], s->current_picture.linesize[1], w>>1, h>>1, EDGE_WIDTH/2); - s->dsp.draw_edges(s->current_picture.data[2], s->current_picture.linesize[2], w>>1, h>>1, EDGE_WIDTH/2); - } - - release_buffer(s->avctx); - - tmp= s->last_picture[s->max_ref_frames-1]; - memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame)); - memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4); - if(USE_HALFPEL_PLANE && s->current_picture.data[0]) - halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture); - s->last_picture[0]= s->current_picture; - s->current_picture= tmp; - - if(s->keyframe){ - s->ref_frames= 0; - }else{ - int i; - for(i=0; imax_ref_frames && s->last_picture[i].data[0]; i++) - if(i && s->last_picture[i-1].key_frame) - break; - s->ref_frames= i; - if(s->ref_frames==0){ - av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n"); - return -1; - } - } - - s->current_picture.reference= 1; - if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - s->current_picture.key_frame= s->keyframe; - - return 0; -} - -static av_cold void common_end(SnowContext *s){ - int plane_index, level, orientation, i; - - av_freep(&s->spatial_dwt_buffer); - av_freep(&s->spatial_idwt_buffer); - - s->m.me.temp= NULL; - av_freep(&s->m.me.scratchpad); - av_freep(&s->m.me.map); - av_freep(&s->m.me.score_map); - av_freep(&s->m.obmc_scratchpad); - - av_freep(&s->block); - av_freep(&s->scratchbuf); - - for(i=0; iref_mvs[i]); - av_freep(&s->ref_scores[i]); - if(s->last_picture[i].data[0]) - s->avctx->release_buffer(s->avctx, &s->last_picture[i]); - } - - for(plane_index=0; plane_index<3; plane_index++){ - for(level=s->spatial_decomposition_count-1; level>=0; level--){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &s->plane[plane_index].band[level][orientation]; - - av_freep(&b->x_coeff); - } - } - } - if (s->mconly_picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->mconly_picture); - if (s->current_picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->current_picture); -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - avctx->pix_fmt= PIX_FMT_YUV420P; - - common_init(avctx); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - SnowContext *s = avctx->priv_data; - RangeCoder * const c= &s->c; - int bytes_read; - AVFrame *picture = data; - int level, orientation, plane_index; - - ff_init_range_decoder(c, buf, buf_size); - ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); - - s->current_picture.pict_type= FF_I_TYPE; //FIXME I vs. P - if(decode_header(s)<0) - return -1; - common_init_after_header(avctx); - - // realloc slice buffer for the case that spatial_decomposition_count changed - ff_slice_buffer_destroy(&s->sb); - ff_slice_buffer_init(&s->sb, s->plane[0].height, (MB_SIZE >> s->block_max_depth) + s->spatial_decomposition_count * 8 + 1, s->plane[0].width, s->spatial_idwt_buffer); - - for(plane_index=0; plane_index<3; plane_index++){ - Plane *p= &s->plane[plane_index]; - p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40 - && p->hcoeff[1]==-10 - && p->hcoeff[2]==2; - } - - alloc_blocks(s); - - if(frame_start(s) < 0) - return -1; - //keyframe flag duplication mess FIXME - if(avctx->debug&FF_DEBUG_PICT_INFO) - av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog); - - decode_blocks(s); - - for(plane_index=0; plane_index<3; plane_index++){ - Plane *p= &s->plane[plane_index]; - int w= p->width; - int h= p->height; - int x, y; - int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */ - - if(s->avctx->debug&2048){ - memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h); - predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); - - for(y=0; ycurrent_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]; - s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v; - } - } - } - - { - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - unpack_coeffs(s, b, b->parent, orientation); - } - } - } - - { - const int mb_h= s->b_height << s->block_max_depth; - const int block_size = MB_SIZE >> s->block_max_depth; - const int block_w = plane_index ? block_size/2 : block_size; - int mb_y; - DWTCompose cs[MAX_DECOMPOSITIONS]; - int yd=0, yq=0; - int y; - int end_y; - - ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count); - for(mb_y=0; mb_y<=mb_h; mb_y++){ - - int slice_starty = block_w*mb_y; - int slice_h = block_w*(mb_y+1); - if (!(s->keyframe || s->avctx->debug&512)){ - slice_starty = FFMAX(0, slice_starty - (block_w >> 1)); - slice_h -= (block_w >> 1); - } - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - int start_y; - int end_y; - int our_mb_start = mb_y; - int our_mb_end = (mb_y + 1); - const int extra= 3; - start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0); - end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra); - if (!(s->keyframe || s->avctx->debug&512)){ - start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level))); - end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level))); - } - start_y = FFMIN(b->height, start_y); - end_y = FFMIN(b->height, end_y); - - if (start_y != end_y){ - if (orientation == 0){ - SubBand * correlate_band = &p->band[0][0]; - int correlate_end_y = FFMIN(b->height, end_y + 1); - int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0)); - decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]); - correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y); - dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y); - } - else - decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]); - } - } - } - - for(; yddwt, cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd); - } - - if(s->qlog == LOSSLESS_QLOG){ - for(; yqsb, yq); - for(x=0; xsb, s->spatial_idwt_buffer, plane_index, 1, mb_y); - - y = FFMIN(p->height, slice_starty); - end_y = FFMIN(p->height, slice_h); - while(y < end_y) - ff_slice_buffer_release(&s->sb, y++); - } - - ff_slice_buffer_flush(&s->sb); - } - - } - - emms_c(); - - release_buffer(avctx); - - if(!(s->avctx->debug&2048)) - *picture= s->current_picture; - else - *picture= s->mconly_picture; - - *data_size = sizeof(AVFrame); - - bytes_read= c->bytestream - c->bytestream_start; - if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME - - return bytes_read; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - SnowContext *s = avctx->priv_data; - - ff_slice_buffer_destroy(&s->sb); - - common_end(s); - - return 0; -} - -AVCodec snow_decoder = { - "snow", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SNOW, - sizeof(SnowContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Snow"), -}; - -#if CONFIG_SNOW_ENCODER -static av_cold int encode_init(AVCodecContext *avctx) -{ - SnowContext *s = avctx->priv_data; - int plane_index; - - if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n" - "Use vstrict=-2 / -strict -2 to use it anyway.\n"); - return -1; - } - - if(avctx->prediction_method == DWT_97 - && (avctx->flags & CODEC_FLAG_QSCALE) - && avctx->global_quality == 0){ - av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n"); - return -1; - } - - s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type - - s->mv_scale = (avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4; - s->block_max_depth= (avctx->flags & CODEC_FLAG_4MV ) ? 1 : 0; - - for(plane_index=0; plane_index<3; plane_index++){ - s->plane[plane_index].diag_mc= 1; - s->plane[plane_index].htaps= 6; - s->plane[plane_index].hcoeff[0]= 40; - s->plane[plane_index].hcoeff[1]= -10; - s->plane[plane_index].hcoeff[2]= 2; - s->plane[plane_index].fast_mc= 1; - } - - common_init(avctx); - alloc_blocks(s); - - s->version=0; - - s->m.avctx = avctx; - s->m.flags = avctx->flags; - s->m.bit_rate= avctx->bit_rate; - - s->m.me.temp = - s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t)); - s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); - s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); - s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t)); - h263_encode_init(&s->m); //mv_penalty - - s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1); - - if(avctx->flags&CODEC_FLAG_PASS1){ - if(!avctx->stats_out) - avctx->stats_out = av_mallocz(256); - } - if((avctx->flags&CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){ - if(ff_rate_control_init(&s->m) < 0) - return -1; - } - s->pass1_rc= !(avctx->flags & (CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2)); - - avctx->coded_frame= &s->current_picture; - switch(avctx->pix_fmt){ -// case PIX_FMT_YUV444P: -// case PIX_FMT_YUV422P: - case PIX_FMT_YUV420P: - case PIX_FMT_GRAY8: -// case PIX_FMT_YUV411P: -// case PIX_FMT_YUV410P: - s->colorspace_type= 0; - break; -/* case PIX_FMT_RGB32: - s->colorspace= 1; - break;*/ - default: - av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n"); - return -1; - } -// avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); - s->chroma_h_shift= 1; - s->chroma_v_shift= 1; - - ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp); - ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp); - - s->avctx->get_buffer(s->avctx, &s->input_picture); - - if(s->avctx->me_method == ME_ITER){ - int i; - int size= s->b_width * s->b_height << 2*s->block_max_depth; - for(i=0; imax_ref_frames; i++){ - s->ref_mvs[i]= av_mallocz(size*sizeof(int16_t[2])); - s->ref_scores[i]= av_mallocz(size*sizeof(uint32_t)); - } - } - - return 0; -} - -//near copy & paste from dsputil, FIXME -static int pix_sum(uint8_t * pix, int line_size, int w) -{ - int s, i, j; - - s = 0; - for (i = 0; i < w; i++) { - for (j = 0; j < w; j++) { - s += pix[0]; - pix ++; - } - pix += line_size - w; - } - return s; -} - -//near copy & paste from dsputil, FIXME -static int pix_norm1(uint8_t * pix, int line_size, int w) -{ - int s, i, j; - uint32_t *sq = ff_squareTbl + 256; - - s = 0; - for (i = 0; i < w; i++) { - for (j = 0; j < w; j ++) { - s += sq[pix[0]]; - pix ++; - } - pix += line_size - w; - } - return s; -} - -//FIXME copy&paste -#define P_LEFT P[1] -#define P_TOP P[2] -#define P_TOPRIGHT P[3] -#define P_MEDIAN P[4] -#define P_MV1 P[9] -#define FLAG_QPEL 1 //must be 1 - -static int encode_q_branch(SnowContext *s, int level, int x, int y){ - uint8_t p_buffer[1024]; - uint8_t i_buffer[1024]; - uint8_t p_state[sizeof(s->block_state)]; - uint8_t i_state[sizeof(s->block_state)]; - RangeCoder pc, ic; - uint8_t *pbbak= s->c.bytestream; - uint8_t *pbbak_start= s->c.bytestream_start; - int score, score2, iscore, i_len, p_len, block_s, sum, base_bits; - const int w= s->b_width << s->block_max_depth; - const int h= s->b_height << s->block_max_depth; - const int rem_depth= s->block_max_depth - level; - const int index= (x + y*w) << rem_depth; - const int block_w= 1<<(LOG2_MB_SIZE - level); - int trx= (x+1)<block[index-1] : &null_block; - const BlockNode *top = y ? &s->block[index-w] : &null_block; - const BlockNode *right = trxblock[index+1] : &null_block; - const BlockNode *bottom= tryblock[index+w] : &null_block; - const BlockNode *tl = y && x ? &s->block[index-w-1] : left; - const BlockNode *tr = y && trxblock[index-w+(1<color[0]; - int pcb= left->color[1]; - int pcr= left->color[2]; - int pmx, pmy; - int mx=0, my=0; - int l,cr,cb; - const int stride= s->current_picture.linesize[0]; - const int uvstride= s->current_picture.linesize[1]; - uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w, - s->input_picture.data[1] + (x + y*uvstride)*block_w/2, - s->input_picture.data[2] + (x + y*uvstride)*block_w/2}; - int P[10][2]; - int16_t last_mv[3][2]; - int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused - const int shift= 1+qpel; - MotionEstContext *c= &s->m.me; - int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); - int mx_context= av_log2(2*FFABS(left->mx - top->mx)); - int my_context= av_log2(2*FFABS(left->my - top->my)); - int s_context= 2*left->level + 2*top->level + tl->level + tr->level; - int ref, best_ref, ref_score, ref_mx, ref_my; - - assert(sizeof(s->block_state) >= 256); - if(s->keyframe){ - set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA); - return 0; - } - -// clip predictors / edge ? - - P_LEFT[0]= left->mx; - P_LEFT[1]= left->my; - P_TOP [0]= top->mx; - P_TOP [1]= top->my; - P_TOPRIGHT[0]= tr->mx; - P_TOPRIGHT[1]= tr->my; - - last_mv[0][0]= s->block[index].mx; - last_mv[0][1]= s->block[index].my; - last_mv[1][0]= right->mx; - last_mv[1][1]= right->my; - last_mv[2][0]= bottom->mx; - last_mv[2][1]= bottom->my; - - s->m.mb_stride=2; - s->m.mb_x= - s->m.mb_y= 0; - c->skip= 0; - - assert(c-> stride == stride); - assert(c->uvstride == uvstride); - - c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); - c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); - c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); - c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_MV; - - c->xmin = - x*block_w - 16+3; - c->ymin = - y*block_w - 16+3; - c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3; - c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3; - - if(P_LEFT[0] > (c->xmax<xmax< (c->ymax<ymax< (c->xmax<xmax< (c->ymax<ymax<xmin<xmin< (c->xmax<xmax< (c->ymax<ymax<pred_x= P_LEFT[0]; - c->pred_y= P_LEFT[1]; - } else { - c->pred_x = P_MEDIAN[0]; - c->pred_y = P_MEDIAN[1]; - } - - score= INT_MAX; - best_ref= 0; - for(ref=0; refref_frames; ref++){ - init_ref(c, current_data, s->last_picture[ref].data, NULL, block_w*x, block_w*y, 0); - - ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv, - (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w); - - assert(ref_mx >= c->xmin); - assert(ref_mx <= c->xmax); - assert(ref_my >= c->ymin); - assert(ref_my <= c->ymax); - - ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w); - ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0); - ref_score+= 2*av_log2(2*ref)*c->penalty_factor; - if(s->ref_mvs[ref]){ - s->ref_mvs[ref][index][0]= ref_mx; - s->ref_mvs[ref][index][1]= ref_my; - s->ref_scores[ref][index]= ref_score; - } - if(score > ref_score){ - score= ref_score; - best_ref= ref; - mx= ref_mx; - my= ref_my; - } - } - //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2 - - // subpel search - base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start); - pc= s->c; - pc.bytestream_start= - pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo - memcpy(p_state, s->block_state, sizeof(s->block_state)); - - if(level!=s->block_max_depth) - put_rac(&pc, &p_state[4 + s_context], 1); - put_rac(&pc, &p_state[1 + left->type + top->type], 0); - if(s->ref_frames > 1) - put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0); - pred_mv(s, &pmx, &pmy, best_ref, left, top, tr); - put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1); - put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1); - p_len= pc.bytestream - pc.bytestream_start; - score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT; - - block_s= block_w*block_w; - sum = pix_sum(current_data[0], stride, block_w); - l= (sum + block_s/2)/block_s; - iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s; - - block_s= block_w*block_w>>2; - sum = pix_sum(current_data[1], uvstride, block_w>>1); - cb= (sum + block_s/2)/block_s; -// iscore += pix_norm1(¤t_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s; - sum = pix_sum(current_data[2], uvstride, block_w>>1); - cr= (sum + block_s/2)/block_s; -// iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s; - - ic= s->c; - ic.bytestream_start= - ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo - memcpy(i_state, s->block_state, sizeof(s->block_state)); - if(level!=s->block_max_depth) - put_rac(&ic, &i_state[4 + s_context], 1); - put_rac(&ic, &i_state[1 + left->type + top->type], 1); - put_symbol(&ic, &i_state[32], l-pl , 1); - put_symbol(&ic, &i_state[64], cb-pcb, 1); - put_symbol(&ic, &i_state[96], cr-pcr, 1); - i_len= ic.bytestream - ic.bytestream_start; - iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT; - -// assert(score==256*256*256*64-1); - assert(iscore < 255*255*256 + s->lambda2*10); - assert(iscore >= 0); - assert(l>=0 && l<=255); - assert(pl>=0 && pl<=255); - - if(level==0){ - int varc= iscore >> 8; - int vard= score >> 8; - if (vard <= 64 || vard < varc) - c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); - else - c->scene_change_score+= s->m.qscale; - } - - if(level!=s->block_max_depth){ - put_rac(&s->c, &s->block_state[4 + s_context], 0); - score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0); - score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0); - score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1); - score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1); - score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead - - if(score2 < score && score2 < iscore) - return score2; - } - - if(iscore < score){ - pred_mv(s, &pmx, &pmy, 0, left, top, tr); - memcpy(pbbak, i_buffer, i_len); - s->c= ic; - s->c.bytestream_start= pbbak_start; - s->c.bytestream= pbbak + i_len; - set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA); - memcpy(s->block_state, i_state, sizeof(s->block_state)); - return iscore; - }else{ - memcpy(pbbak, p_buffer, p_len); - s->c= pc; - s->c.bytestream_start= pbbak_start; - s->c.bytestream= pbbak + p_len; - set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0); - memcpy(s->block_state, p_state, sizeof(s->block_state)); - return score; - } -} - -static void encode_q_branch2(SnowContext *s, int level, int x, int y){ - const int w= s->b_width << s->block_max_depth; - const int rem_depth= s->block_max_depth - level; - const int index= (x + y*w) << rem_depth; - int trx= (x+1)<block[index]; - const BlockNode *left = x ? &s->block[index-1] : &null_block; - const BlockNode *top = y ? &s->block[index-w] : &null_block; - const BlockNode *tl = y && x ? &s->block[index-w-1] : left; - const BlockNode *tr = y && trxblock[index-w+(1<color[0]; - int pcb= left->color[1]; - int pcr= left->color[2]; - int pmx, pmy; - int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); - int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 16*!!b->ref; - int my_context= av_log2(2*FFABS(left->my - top->my)) + 16*!!b->ref; - int s_context= 2*left->level + 2*top->level + tl->level + tr->level; - - if(s->keyframe){ - set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA); - return; - } - - if(level!=s->block_max_depth){ - if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){ - put_rac(&s->c, &s->block_state[4 + s_context], 1); - }else{ - put_rac(&s->c, &s->block_state[4 + s_context], 0); - encode_q_branch2(s, level+1, 2*x+0, 2*y+0); - encode_q_branch2(s, level+1, 2*x+1, 2*y+0); - encode_q_branch2(s, level+1, 2*x+0, 2*y+1); - encode_q_branch2(s, level+1, 2*x+1, 2*y+1); - return; - } - } - if(b->type & BLOCK_INTRA){ - pred_mv(s, &pmx, &pmy, 0, left, top, tr); - put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1); - put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1); - put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1); - put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1); - set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA); - }else{ - pred_mv(s, &pmx, &pmy, b->ref, left, top, tr); - put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0); - if(s->ref_frames > 1) - put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0); - put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1); - put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1); - set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0); - } -} - -static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ - int i, x2, y2; - Plane *p= &s->plane[plane_index]; - const int block_size = MB_SIZE >> s->block_max_depth; - const int block_w = plane_index ? block_size/2 : block_size; - const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; - const int obmc_stride= plane_index ? block_size : 2*block_size; - const int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *src= s-> input_picture.data[plane_index]; - IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned - const int b_stride = s->b_width << s->block_max_depth; - const int w= p->width; - const int h= p->height; - int index= mb_x + mb_y*b_stride; - BlockNode *b= &s->block[index]; - BlockNode backup= *b; - int ab=0; - int aa=0; - - b->type|= BLOCK_INTRA; - b->color[plane_index]= 0; - memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM)); - - for(i=0; i<4; i++){ - int mb_x2= mb_x + (i &1) - 1; - int mb_y2= mb_y + (i>>1) - 1; - int x= block_w*mb_x2 + block_w/2; - int y= block_w*mb_y2 + block_w/2; - - add_yblock(s, 0, NULL, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, obmc, - x, y, block_w, block_w, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index); - - for(y2= FFMAX(y, 0); y2h) obmc_v += obmc[index - block_w*obmc_stride]; - if(x+block_w>w) obmc_v += obmc[index - block_w]; - //FIXME precalculate this or simplify it somehow else - - d = -dst[index] + (1<<(FRAC_BITS-1)); - dst[index] = d; - ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v; - aa += obmc_v * obmc_v; //FIXME precalculate this - } - } - } - *b= backup; - - return av_clip(((ab<b_width << s->block_max_depth; - const int b_height = s->b_height<< s->block_max_depth; - int index= x + y*b_stride; - const BlockNode *b = &s->block[index]; - const BlockNode *left = x ? &s->block[index-1] : &null_block; - const BlockNode *top = y ? &s->block[index-b_stride] : &null_block; - const BlockNode *tl = y && x ? &s->block[index-b_stride-1] : left; - const BlockNode *tr = y && x+wblock[index-b_stride+w] : tl; - int dmx, dmy; -// int mx_context= av_log2(2*FFABS(left->mx - top->mx)); -// int my_context= av_log2(2*FFABS(left->my - top->my)); - - if(x<0 || x>=b_stride || y>=b_height) - return 0; -/* -1 0 0 -01X 1-2 1 -001XX 3-6 2-3 -0001XXX 7-14 4-7 -00001XXXX 15-30 8-15 -*/ -//FIXME try accurate rate -//FIXME intra and inter predictors if surrounding blocks are not the same type - if(b->type & BLOCK_INTRA){ - return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0])) - + av_log2(2*FFABS(left->color[1] - b->color[1])) - + av_log2(2*FFABS(left->color[2] - b->color[2]))); - }else{ - pred_mv(s, &dmx, &dmy, b->ref, left, top, tr); - dmx-= b->mx; - dmy-= b->my; - return 2*(1 + av_log2(2*FFABS(dmx)) //FIXME kill the 2* can be merged in lambda - + av_log2(2*FFABS(dmy)) - + av_log2(2*b->ref)); - } -} - -static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){ - Plane *p= &s->plane[plane_index]; - const int block_size = MB_SIZE >> s->block_max_depth; - const int block_w = plane_index ? block_size/2 : block_size; - const int obmc_stride= plane_index ? block_size : 2*block_size; - const int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst= s->current_picture.data[plane_index]; - uint8_t *src= s-> input_picture.data[plane_index]; - IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; - uint8_t *cur = s->scratchbuf; - uint8_t tmp[ref_stride*(2*MB_SIZE+HTAPS_MAX-1)]; - const int b_stride = s->b_width << s->block_max_depth; - const int b_height = s->b_height<< s->block_max_depth; - const int w= p->width; - const int h= p->height; - int distortion; - int rate= 0; - const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); - int sx= block_w*mb_x - block_w/2; - int sy= block_w*mb_y - block_w/2; - int x0= FFMAX(0,-sx); - int y0= FFMAX(0,-sy); - int x1= FFMIN(block_w*2, w-sx); - int y1= FFMIN(block_w*2, h-sy); - int i,x,y; - - pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h); - - for(y=y0; y= LOG2_OBMC_MAX - int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX); -#else - int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS); -#endif - v = (v + pred1[x]) >> FRAC_BITS; - if(v&(~255)) v= ~(v>>31); - dst1[x] = v; - } - } - - /* copy the regions where obmc[] = (uint8_t)256 */ - if(LOG2_OBMC_MAX == 8 - && (mb_x == 0 || mb_x == b_stride-1) - && (mb_y == 0 || mb_y == b_height-1)){ - if(mb_x == 0) - x1 = block_w; - else - x0 = block_w; - if(mb_y == 0) - y1 = block_w; - else - y0 = block_w; - for(y=y0; yavctx->me_cmp == FF_CMP_W97) - distortion = ff_w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32); - else if(s->avctx->me_cmp == FF_CMP_W53) - distortion = ff_w53_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32); - else{ - distortion = 0; - for(i=0; i<4; i++){ - int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride; - distortion += s->dsp.me_cmp[0](&s->m, src + off, dst + off, ref_stride, 16); - } - } - }else{ - assert(block_w==8); - distortion = s->dsp.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2); - } - - if(plane_index==0){ - for(i=0; i<4; i++){ -/* ..RRr - * .RXx. - * rxx.. - */ - rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1); - } - if(mb_x == b_stride-2) - rate += get_block_bits(s, mb_x + 1, mb_y + 1, 1); - } - return distortion + rate*penalty_factor; -} - -static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ - int i, y2; - Plane *p= &s->plane[plane_index]; - const int block_size = MB_SIZE >> s->block_max_depth; - const int block_w = plane_index ? block_size/2 : block_size; - const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; - const int obmc_stride= plane_index ? block_size : 2*block_size; - const int ref_stride= s->current_picture.linesize[plane_index]; - uint8_t *dst= s->current_picture.data[plane_index]; - uint8_t *src= s-> input_picture.data[plane_index]; - //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst - // const has only been removed from zero_dst to suppress a warning - static IDWTELEM zero_dst[4096]; //FIXME - const int b_stride = s->b_width << s->block_max_depth; - const int w= p->width; - const int h= p->height; - int distortion= 0; - int rate= 0; - const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); - - for(i=0; i<9; i++){ - int mb_x2= mb_x + (i%3) - 1; - int mb_y2= mb_y + (i/3) - 1; - int x= block_w*mb_x2 + block_w/2; - int y= block_w*mb_y2 + block_w/2; - - add_yblock(s, 0, NULL, zero_dst, dst, obmc, - x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index); - - //FIXME find a cleaner/simpler way to skip the outside stuff - for(y2= y; y2<0; y2++) - memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w); - for(y2= h; y2 w){ - for(y2= y; y2dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_w); - } - - if(plane_index==0){ - BlockNode *b= &s->block[mb_x+mb_y*b_stride]; - int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1); - -/* ..RRRr - * .RXXx. - * .RXXx. - * rxxx. - */ - if(merged) - rate = get_block_bits(s, mb_x, mb_y, 2); - for(i=merged?4:0; i<9; i++){ - static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}}; - rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1); - } - } - return distortion + rate*penalty_factor; -} - -static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){ - const int w= b->width; - const int h= b->height; - int x, y; - - if(1){ - int run=0; - int runs[w*h]; - int run_index=0; - int max_index; - - for(y=0; y 1){ - if(orientation==1) ll= src[y + (x-2)*stride]; - else ll= src[x - 2 + y*stride]; - }*/ - } - if(parent){ - int px= x>>1; - int py= y>>1; - if(pxparent->width && pyparent->height) - p= parent[px + py*2*stride]; - } - if(!(/*ll|*/l|lt|t|rt|p)){ - if(v){ - runs[run_index++]= run; - run=0; - }else{ - run++; - } - } - } - } - max_index= run_index; - runs[run_index++]= run; - run_index=0; - run= runs[run_index++]; - - put_symbol2(&s->c, b->state[30], max_index, 0); - if(run_index <= max_index) - put_symbol2(&s->c, b->state[1], run, 3); - - for(y=0; yc.bytestream_end - s->c.bytestream < w*40){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - for(x=0; x 1){ - if(orientation==1) ll= src[y + (x-2)*stride]; - else ll= src[x - 2 + y*stride]; - }*/ - } - if(parent){ - int px= x>>1; - int py= y>>1; - if(pxparent->width && pyparent->height) - p= parent[px + py*2*stride]; - } - if(/*ll|*/l|lt|t|rt|p){ - int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p)); - - put_rac(&s->c, &b->state[0][context], !!v); - }else{ - if(!run){ - run= runs[run_index++]; - - if(run_index <= max_index) - put_symbol2(&s->c, b->state[1], run, 3); - assert(v); - }else{ - run--; - assert(!v); - } - } - if(v){ - int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p)); - int l2= 2*FFABS(l) + (l<0); - int t2= 2*FFABS(t) + (t<0); - - put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4); - put_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l2&0xFF] + 3*quant3bA[t2&0xFF]], v<0); - } - } - } - } - return 0; -} - -static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){ -// encode_subband_qtree(s, b, src, parent, stride, orientation); -// encode_subband_z0run(s, b, src, parent, stride, orientation); - return encode_subband_c0run(s, b, src, parent, stride, orientation); -// encode_subband_dzr(s, b, src, parent, stride, orientation); -} - -static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, const uint8_t *obmc_edged, int *best_rd){ - const int b_stride= s->b_width << s->block_max_depth; - BlockNode *block= &s->block[mb_x + mb_y * b_stride]; - BlockNode backup= *block; - int rd, index, value; - - assert(mb_x>=0 && mb_y>=0); - assert(mb_xcolor[0] = p[0]; - block->color[1] = p[1]; - block->color[2] = p[2]; - block->type |= BLOCK_INTRA; - }else{ - index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1); - value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12); - if(s->me_cache[index] == value) - return 0; - s->me_cache[index]= value; - - block->mx= p[0]; - block->my= p[1]; - block->type &= ~BLOCK_INTRA; - } - - rd= get_block_rd(s, mb_x, mb_y, 0, obmc_edged); - -//FIXME chroma - if(rd < *best_rd){ - *best_rd= rd; - return 1; - }else{ - *block= backup; - return 0; - } -} - -/* special case for int[2] args we discard afterwards, - * fixes compilation problem with gcc 2.95 */ -static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, const uint8_t *obmc_edged, int *best_rd){ - int p[2] = {p0, p1}; - return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd); -} - -static av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){ - const int b_stride= s->b_width << s->block_max_depth; - BlockNode *block= &s->block[mb_x + mb_y * b_stride]; - BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]}; - int rd, index, value; - - assert(mb_x>=0 && mb_y>=0); - assert(mb_xme_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12); - if(s->me_cache[index] == value) - return 0; - s->me_cache[index]= value; - - block->mx= p0; - block->my= p1; - block->ref= ref; - block->type &= ~BLOCK_INTRA; - block[1]= block[b_stride]= block[b_stride+1]= *block; - - rd= get_4block_rd(s, mb_x, mb_y, 0); - -//FIXME chroma - if(rd < *best_rd){ - *best_rd= rd; - return 1; - }else{ - block[0]= backup[0]; - block[1]= backup[1]; - block[b_stride]= backup[2]; - block[b_stride+1]= backup[3]; - return 0; - } -} - -static void iterative_me(SnowContext *s){ - int pass, mb_x, mb_y; - const int b_width = s->b_width << s->block_max_depth; - const int b_height= s->b_height << s->block_max_depth; - const int b_stride= b_width; - int color[3]; - - { - RangeCoder r = s->c; - uint8_t state[sizeof(s->block_state)]; - memcpy(state, s->block_state, sizeof(s->block_state)); - for(mb_y= 0; mb_yb_height; mb_y++) - for(mb_x= 0; mb_xb_width; mb_x++) - encode_q_branch(s, 0, mb_x, mb_y); - s->c = r; - memcpy(s->block_state, state, sizeof(s->block_state)); - } - - for(pass=0; pass<25; pass++){ - int change= 0; - - for(mb_y= 0; mb_yblock[index]; - BlockNode *tb = mb_y ? &s->block[index-b_stride ] : NULL; - BlockNode *lb = mb_x ? &s->block[index -1] : NULL; - BlockNode *rb = mb_x+1block[index +1] : NULL; - BlockNode *bb = mb_y+1block[index+b_stride ] : NULL; - BlockNode *tlb= mb_x && mb_y ? &s->block[index-b_stride-1] : NULL; - BlockNode *trb= mb_x+1block[index-b_stride+1] : NULL; - BlockNode *blb= mb_x && mb_y+1block[index+b_stride-1] : NULL; - BlockNode *brb= mb_x+1block[index+b_stride+1] : NULL; - const int b_w= (MB_SIZE >> s->block_max_depth); - uint8_t obmc_edged[b_w*2][b_w*2]; - - if(pass && (block->type & BLOCK_OPT)) - continue; - block->type |= BLOCK_OPT; - - backup= *block; - - if(!s->me_cache_generation) - memset(s->me_cache, 0, sizeof(s->me_cache)); - s->me_cache_generation += 1<<22; - - //FIXME precalculate - { - int x, y; - memcpy(obmc_edged, obmc_tab[s->block_max_depth], b_w*b_w*4); - if(mb_x==0) - for(y=0; y input_picture.data[0]; - uint8_t *dst= s->current_picture.data[0]; - const int stride= s->current_picture.linesize[0]; - const int block_w= MB_SIZE >> s->block_max_depth; - const int sx= block_w*mb_x - block_w/2; - const int sy= block_w*mb_y - block_w/2; - const int w= s->plane[0].width; - const int h= s->plane[0].height; - int y; - - for(y=sy; y<0; y++) - memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2); - for(y=h; y w){ - for(y=sy; y 0 && (block->type&BLOCK_INTRA)){ - int color0[3]= {block->color[0], block->color[1], block->color[2]}; - check_block(s, mb_x, mb_y, color0, 1, *obmc_edged, &best_rd); - }else - check_block_inter(s, mb_x, mb_y, block->mx, block->my, *obmc_edged, &best_rd); - - ref_b= *block; - ref_rd= best_rd; - for(ref=0; ref < s->ref_frames; ref++){ - int16_t (*mvr)[2]= &s->ref_mvs[ref][index]; - if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold - continue; - block->ref= ref; - best_rd= INT_MAX; - - check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], *obmc_edged, &best_rd); - check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd); - if(tb) - check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], *obmc_edged, &best_rd); - if(lb) - check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], *obmc_edged, &best_rd); - if(rb) - check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], *obmc_edged, &best_rd); - if(bb) - check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd); - - /* fullpel ME */ - //FIXME avoid subpel interpolation / round to nearest integer - do{ - dia_change=0; - for(i=0; iavctx->dia_size, 1); i++){ - for(j=0; jmx+4*(i-j), block->my+(4*j), *obmc_edged, &best_rd); - dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), *obmc_edged, &best_rd); - dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), *obmc_edged, &best_rd); - dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), *obmc_edged, &best_rd); - } - } - }while(dia_change); - /* subpel ME */ - do{ - static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},}; - dia_change=0; - for(i=0; i<8; i++) - dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], *obmc_edged, &best_rd); - }while(dia_change); - //FIXME or try the standard 2 pass qpel or similar - - mvr[0][0]= block->mx; - mvr[0][1]= block->my; - if(ref_rd > best_rd){ - ref_rd= best_rd; - ref_b= *block; - } - } - best_rd= ref_rd; - *block= ref_b; -#if 1 - check_block(s, mb_x, mb_y, color, 1, *obmc_edged, &best_rd); - //FIXME RD style color selection -#endif - if(!same_block(block, &backup)){ - if(tb ) tb ->type &= ~BLOCK_OPT; - if(lb ) lb ->type &= ~BLOCK_OPT; - if(rb ) rb ->type &= ~BLOCK_OPT; - if(bb ) bb ->type &= ~BLOCK_OPT; - if(tlb) tlb->type &= ~BLOCK_OPT; - if(trb) trb->type &= ~BLOCK_OPT; - if(blb) blb->type &= ~BLOCK_OPT; - if(brb) brb->type &= ~BLOCK_OPT; - change ++; - } - } - } - av_log(s->avctx, AV_LOG_ERROR, "pass:%d changed:%d\n", pass, change); - if(!change) - break; - } - - if(s->block_max_depth == 1){ - int change= 0; - for(mb_y= 0; mb_yblock[index]; - b[1]= b[0]+1; - b[2]= b[0]+b_stride; - b[3]= b[2]+1; - if(same_block(b[0], b[1]) && - same_block(b[0], b[2]) && - same_block(b[0], b[3])) - continue; - - if(!s->me_cache_generation) - memset(s->me_cache, 0, sizeof(s->me_cache)); - s->me_cache_generation += 1<<22; - - init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0); - - //FIXME more multiref search? - check_4block_inter(s, mb_x, mb_y, - (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2, - (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd); - - for(i=0; i<4; i++) - if(!(b[i]->type&BLOCK_INTRA)) - check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd); - - if(init_rd != best_rd) - change++; - } - } - av_log(s->avctx, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4); - } -} - -static void encode_blocks(SnowContext *s, int search){ - int x, y; - int w= s->b_width; - int h= s->b_height; - - if(s->avctx->me_method == ME_ITER && !s->keyframe && search) - iterative_me(s); - - for(y=0; yc.bytestream_end - s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return; - } - for(x=0; xavctx->me_method == ME_ITER || !search) - encode_q_branch2(s, 0, x, y); - else - encode_q_branch (s, 0, x, y); - } - } -} - -static void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){ - const int w= b->width; - const int h= b->height; - const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); - const int qmul= qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS); - int x,y, thres1, thres2; - - if(s->qlog == LOSSLESS_QLOG){ - for(y=0; y>3; - thres1= ((qmul - bias)>>QEXPSHIFT) - 1; - thres2= 2*thres1; - - if(!bias){ - for(y=0; y thres2){ - if(i>=0){ - i<<= QEXPSHIFT; - i/= qmul; //FIXME optimize - dst[x + y*stride]= i; - }else{ - i= -i; - i<<= QEXPSHIFT; - i/= qmul; //FIXME optimize - dst[x + y*stride]= -i; - } - }else - dst[x + y*stride]= 0; - } - } - }else{ - for(y=0; y thres2){ - if(i>=0){ - i<<= QEXPSHIFT; - i= (i + bias) / qmul; //FIXME optimize - dst[x + y*stride]= i; - }else{ - i= -i; - i<<= QEXPSHIFT; - i= (i + bias) / qmul; //FIXME optimize - dst[x + y*stride]= -i; - } - }else - dst[x + y*stride]= 0; - } - } - } -} - -static void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){ - const int w= b->width; - const int h= b->height; - const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); - const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); - const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; - int x,y; - - if(s->qlog == LOSSLESS_QLOG) return; - - for(y=0; y>(QEXPSHIFT)); //FIXME try different bias - }else if(i>0){ - src[x + y*stride]= (( i*qmul + qadd)>>(QEXPSHIFT)); - } - } - } -} - -static void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){ - const int w= b->width; - const int h= b->height; - int x,y; - - for(y=h-1; y>=0; y--){ - for(x=w-1; x>=0; x--){ - int i= x + y*stride; - - if(x){ - if(use_median){ - if(y && x+1width; - const int h= b->height; - int x,y; - - for(y=0; yspatial_decomposition_count; level++){ - for(orientation=level ? 1:0; orientation<4; orientation++){ - if(orientation==2) continue; - put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1); - } - } - } -} - -static void encode_header(SnowContext *s){ - int plane_index, i; - uint8_t kstate[32]; - - memset(kstate, MID_STATE, sizeof(kstate)); - - put_rac(&s->c, kstate, s->keyframe); - if(s->keyframe || s->always_reset){ - reset_contexts(s); - s->last_spatial_decomposition_type= - s->last_qlog= - s->last_qbias= - s->last_mv_scale= - s->last_block_max_depth= 0; - for(plane_index=0; plane_index<2; plane_index++){ - Plane *p= &s->plane[plane_index]; - p->last_htaps=0; - p->last_diag_mc=0; - memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff)); - } - } - if(s->keyframe){ - put_symbol(&s->c, s->header_state, s->version, 0); - put_rac(&s->c, s->header_state, s->always_reset); - put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0); - put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0); - put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0); - put_symbol(&s->c, s->header_state, s->colorspace_type, 0); - put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0); - put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0); - put_rac(&s->c, s->header_state, s->spatial_scalability); -// put_rac(&s->c, s->header_state, s->rate_scalability); - put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0); - - encode_qlogs(s); - } - - if(!s->keyframe){ - int update_mc=0; - for(plane_index=0; plane_index<2; plane_index++){ - Plane *p= &s->plane[plane_index]; - update_mc |= p->last_htaps != p->htaps; - update_mc |= p->last_diag_mc != p->diag_mc; - update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff)); - } - put_rac(&s->c, s->header_state, update_mc); - if(update_mc){ - for(plane_index=0; plane_index<2; plane_index++){ - Plane *p= &s->plane[plane_index]; - put_rac(&s->c, s->header_state, p->diag_mc); - put_symbol(&s->c, s->header_state, p->htaps/2-1, 0); - for(i= p->htaps/2; i; i--) - put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0); - } - } - if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){ - put_rac(&s->c, s->header_state, 1); - put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0); - encode_qlogs(s); - }else - put_rac(&s->c, s->header_state, 0); - } - - put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1); - put_symbol(&s->c, s->header_state, s->qlog - s->last_qlog , 1); - put_symbol(&s->c, s->header_state, s->mv_scale - s->last_mv_scale, 1); - put_symbol(&s->c, s->header_state, s->qbias - s->last_qbias , 1); - put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1); - -} - -static void update_last_header_values(SnowContext *s){ - int plane_index; - - if(!s->keyframe){ - for(plane_index=0; plane_index<2; plane_index++){ - Plane *p= &s->plane[plane_index]; - p->last_diag_mc= p->diag_mc; - p->last_htaps = p->htaps; - memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff)); - } - } - - s->last_spatial_decomposition_type = s->spatial_decomposition_type; - s->last_qlog = s->qlog; - s->last_qbias = s->qbias; - s->last_mv_scale = s->mv_scale; - s->last_block_max_depth = s->block_max_depth; - s->last_spatial_decomposition_count = s->spatial_decomposition_count; -} - -static int qscale2qlog(int qscale){ - return rint(QROOT*log(qscale / (float)FF_QP2LAMBDA)/log(2)) - + 61*QROOT/8; //<64 >60 -} - -static int ratecontrol_1pass(SnowContext *s, AVFrame *pict) -{ - /* Estimate the frame's complexity as a sum of weighted dwt coefficients. - * FIXME we know exact mv bits at this point, - * but ratecontrol isn't set up to include them. */ - uint32_t coef_sum= 0; - int level, orientation, delta_qlog; - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &s->plane[0].band[level][orientation]; - IDWTELEM *buf= b->ibuf; - const int w= b->width; - const int h= b->height; - const int stride= b->stride; - const int qlog= av_clip(2*QROOT + b->qlog, 0, QROOT*16); - const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); - const int qdiv= (1<<16)/qmul; - int x, y; - //FIXME this is ugly - for(y=0; ybuf[x+y*stride]; - if(orientation==0) - decorrelate(s, b, buf, stride, 1, 0); - for(y=0; y> 16; - } - } - - /* ugly, ratecontrol just takes a sqrt again */ - coef_sum = (uint64_t)coef_sum * coef_sum >> 16; - assert(coef_sum < INT_MAX); - - if(pict->pict_type == FF_I_TYPE){ - s->m.current_picture.mb_var_sum= coef_sum; - s->m.current_picture.mc_mb_var_sum= 0; - }else{ - s->m.current_picture.mc_mb_var_sum= coef_sum; - s->m.current_picture.mb_var_sum= 0; - } - - pict->quality= ff_rate_estimate_qscale(&s->m, 1); - if (pict->quality < 0) - return INT_MIN; - s->lambda= pict->quality * 3/2; - delta_qlog= qscale2qlog(pict->quality) - s->qlog; - s->qlog+= delta_qlog; - return delta_qlog; -} - -static void calculate_visual_weight(SnowContext *s, Plane *p){ - int width = p->width; - int height= p->height; - int level, orientation, x, y; - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - IDWTELEM *ibuf= b->ibuf; - int64_t error=0; - - memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height); - ibuf[b->width/2 + b->height/2*b->stride]= 256*16; - ff_spatial_idwt(s->spatial_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count); - for(y=0; yspatial_idwt_buffer[x + y*width]*16; - error += d*d; - } - } - - b->qlog= (int)(log(352256.0/sqrt(error)) / log(pow(2.0, 1.0/QROOT))+0.5); - } - } -} - -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - SnowContext *s = avctx->priv_data; - RangeCoder * const c= &s->c; - AVFrame *pict = data; - const int width= s->avctx->width; - const int height= s->avctx->height; - int level, orientation, plane_index, i, y; - uint8_t rc_header_bak[sizeof(s->header_state)]; - uint8_t rc_block_bak[sizeof(s->block_state)]; - - ff_init_range_encoder(c, buf, buf_size); - ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); - - for(i=0; i<3; i++){ - int shift= !!i; - for(y=0; y<(height>>shift); y++) - memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]], - &pict->data[i][y * pict->linesize[i]], - width>>shift); - } - s->new_picture = *pict; - - s->m.picture_number= avctx->frame_number; - if(avctx->flags&CODEC_FLAG_PASS2){ - s->m.pict_type = - pict->pict_type= s->m.rc_context.entry[avctx->frame_number].new_pict_type; - s->keyframe= pict->pict_type==FF_I_TYPE; - if(!(avctx->flags&CODEC_FLAG_QSCALE)) { - pict->quality= ff_rate_estimate_qscale(&s->m, 0); - if (pict->quality < 0) - return -1; - } - }else{ - s->keyframe= avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0; - s->m.pict_type= - pict->pict_type= s->keyframe ? FF_I_TYPE : FF_P_TYPE; - } - - if(s->pass1_rc && avctx->frame_number == 0) - pict->quality= 2*FF_QP2LAMBDA; - if(pict->quality){ - s->qlog= qscale2qlog(pict->quality); - s->lambda = pict->quality * 3/2; - } - if(s->qlog < 0 || (!pict->quality && (avctx->flags & CODEC_FLAG_QSCALE))){ - s->qlog= LOSSLESS_QLOG; - s->lambda = 0; - }//else keep previous frame's qlog until after motion estimation - - frame_start(s); - - s->m.current_picture_ptr= &s->m.current_picture; - s->m.last_picture.pts= s->m.current_picture.pts; - s->m.current_picture.pts= pict->pts; - if(pict->pict_type == FF_P_TYPE){ - int block_width = (width +15)>>4; - int block_height= (height+15)>>4; - int stride= s->current_picture.linesize[0]; - - assert(s->current_picture.data[0]); - assert(s->last_picture[0].data[0]); - - s->m.avctx= s->avctx; - s->m.current_picture.data[0]= s->current_picture.data[0]; - s->m. last_picture.data[0]= s->last_picture[0].data[0]; - s->m. new_picture.data[0]= s-> input_picture.data[0]; - s->m. last_picture_ptr= &s->m. last_picture; - s->m.linesize= - s->m. last_picture.linesize[0]= - s->m. new_picture.linesize[0]= - s->m.current_picture.linesize[0]= stride; - s->m.uvlinesize= s->current_picture.linesize[1]; - s->m.width = width; - s->m.height= height; - s->m.mb_width = block_width; - s->m.mb_height= block_height; - s->m.mb_stride= s->m.mb_width+1; - s->m.b8_stride= 2*s->m.mb_width+1; - s->m.f_code=1; - s->m.pict_type= pict->pict_type; - s->m.me_method= s->avctx->me_method; - s->m.me.scene_change_score=0; - s->m.flags= s->avctx->flags; - s->m.quarter_sample= (s->avctx->flags & CODEC_FLAG_QPEL)!=0; - s->m.out_format= FMT_H263; - s->m.unrestricted_mv= 1; - - s->m.lambda = s->lambda; - s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); - s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; - - s->m.dsp= s->dsp; //move - ff_init_me(&s->m); - s->dsp= s->m.dsp; - } - - if(s->pass1_rc){ - memcpy(rc_header_bak, s->header_state, sizeof(s->header_state)); - memcpy(rc_block_bak, s->block_state, sizeof(s->block_state)); - } - -redo_frame: - - if(pict->pict_type == FF_I_TYPE) - s->spatial_decomposition_count= 5; - else - s->spatial_decomposition_count= 5; - - s->m.pict_type = pict->pict_type; - s->qbias= pict->pict_type == FF_P_TYPE ? 2 : 0; - - common_init_after_header(avctx); - - if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){ - for(plane_index=0; plane_index<3; plane_index++){ - calculate_visual_weight(s, &s->plane[plane_index]); - } - } - - encode_header(s); - s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start); - encode_blocks(s, 1); - s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits; - - for(plane_index=0; plane_index<3; plane_index++){ - Plane *p= &s->plane[plane_index]; - int w= p->width; - int h= p->height; - int x, y; -// int bits= put_bits_count(&s->c.pb); - - if(!(avctx->flags2 & CODEC_FLAG2_MEMC_ONLY)){ - //FIXME optimize - if(pict->data[plane_index]) //FIXME gray hack - for(y=0; yspatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<spatial_idwt_buffer, plane_index, 0); - - if( plane_index==0 - && pict->pict_type == FF_P_TYPE - && !(avctx->flags&CODEC_FLAG_PASS2) - && s->m.me.scene_change_score > s->avctx->scenechange_threshold){ - ff_init_range_encoder(c, buf, buf_size); - ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); - pict->pict_type= FF_I_TYPE; - s->keyframe=1; - s->current_picture.key_frame=1; - goto redo_frame; - } - - if(s->qlog == LOSSLESS_QLOG){ - for(y=0; yspatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS; - } - } - }else{ - for(y=0; yspatial_dwt_buffer[y*w + x]=s->spatial_idwt_buffer[y*w + x]<spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type); - else*/ - ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); - - if(s->pass1_rc && plane_index==0){ - int delta_qlog = ratecontrol_1pass(s, pict); - if (delta_qlog <= INT_MIN) - return -1; - if(delta_qlog){ - //reordering qlog in the bitstream would eliminate this reset - ff_init_range_encoder(c, buf, buf_size); - memcpy(s->header_state, rc_header_bak, sizeof(s->header_state)); - memcpy(s->block_state, rc_block_bak, sizeof(s->block_state)); - encode_header(s); - encode_blocks(s, 0); - } - } - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - - if(!QUANTIZE2) - quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias); - if(orientation==0) - decorrelate(s, b, b->ibuf, b->stride, pict->pict_type == FF_P_TYPE, 0); - encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation); - assert(b->parent==NULL || b->parent->stride == b->stride*2); - if(orientation==0) - correlate(s, b, b->ibuf, b->stride, 1, 0); - } - } - - for(level=0; levelspatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - - dequantize(s, b, b->ibuf, b->stride); - } - } - - ff_spatial_idwt(s->spatial_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); - if(s->qlog == LOSSLESS_QLOG){ - for(y=0; yspatial_idwt_buffer[y*w + x]<<=FRAC_BITS; - } - } - } - predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); - }else{ - //ME/MC only - if(pict->pict_type == FF_I_TYPE){ - for(y=0; ycurrent_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]= - pict->data[plane_index][y*pict->linesize[plane_index] + x]; - } - } - }else{ - memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h); - predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); - } - } - if(s->avctx->flags&CODEC_FLAG_PSNR){ - int64_t error= 0; - - if(pict->data[plane_index]) //FIXME gray hack - for(y=0; ycurrent_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x]; - error += d*d; - } - } - s->avctx->error[plane_index] += error; - s->current_picture.error[plane_index] = error; - } - - } - - update_last_header_values(s); - - release_buffer(avctx); - - s->current_picture.coded_picture_number = avctx->frame_number; - s->current_picture.pict_type = pict->pict_type; - s->current_picture.quality = pict->quality; - s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start); - s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits; - s->m.current_picture.display_picture_number = - s->m.current_picture.coded_picture_number = avctx->frame_number; - s->m.current_picture.quality = pict->quality; - s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start); - if(s->pass1_rc) - if (ff_rate_estimate_qscale(&s->m, 0) < 0) - return -1; - if(avctx->flags&CODEC_FLAG_PASS1) - ff_write_pass1_stats(&s->m); - s->m.last_pict_type = s->m.pict_type; - avctx->frame_bits = s->m.frame_bits; - avctx->mv_bits = s->m.mv_bits; - avctx->misc_bits = s->m.misc_bits; - avctx->p_tex_bits = s->m.p_tex_bits; - - emms_c(); - - return ff_rac_terminate(c); -} - -static av_cold int encode_end(AVCodecContext *avctx) -{ - SnowContext *s = avctx->priv_data; - - common_end(s); - if (s->input_picture.data[0]) - avctx->release_buffer(avctx, &s->input_picture); - av_free(avctx->stats_out); - - return 0; -} - -AVCodec snow_encoder = { - "snow", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SNOW, - sizeof(SnowContext), - encode_init, - encode_frame, - encode_end, - .long_name = NULL_IF_CONFIG_SMALL("Snow"), -}; -#endif - - -#ifdef TEST -#undef malloc -#undef free -#undef printf - -#include "libavutil/lfg.h" - -int main(void){ - int width=256; - int height=256; - int buffer[2][width*height]; - SnowContext s; - int i; - AVLFG prng; - s.spatial_decomposition_count=6; - s.spatial_decomposition_type=1; - - av_lfg_init(&prng, 1); - - printf("testing 5/3 DWT\n"); - for(i=0; i20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]); - -#if 0 - printf("testing AC coder\n"); - memset(s.header_state, 0, sizeof(s.header_state)); - ff_init_range_encoder(&s.c, buffer[0], 256*256); - ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); - - for(i=-256; i<256; i++){ - put_symbol(&s.c, s.header_state, i*i*i/3*FFABS(i), 1); - } - ff_rac_terminate(&s.c); - - memset(s.header_state, 0, sizeof(s.header_state)); - ff_init_range_decoder(&s.c, buffer[0], 256*256); - ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); - - for(i=-256; i<256; i++){ - int j; - j= get_symbol(&s.c, s.header_state, 1); - if(j!=i*i*i/3*FFABS(i)) printf("fsck: %d != %d\n", i, j); - } -#endif - { - int level, orientation, x, y; - int64_t errors[8][4]; - int64_t g=0; - - memset(errors, 0, sizeof(errors)); - s.spatial_decomposition_count=3; - s.spatial_decomposition_type=0; - for(level=0; level> (s.spatial_decomposition_count-level); - int h= height >> (s.spatial_decomposition_count-level); - int stride= width << (s.spatial_decomposition_count-level); - DWTELEM *buf= buffer[0]; - int64_t error=0; - - if(orientation&1) buf+=w; - if(orientation>1) buf+=stride>>1; - - memset(buffer[0], 0, sizeof(int)*width*height); - buf[w/2 + h/2*stride]= 256*256; - ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); - for(y=0; y> (s.spatial_decomposition_count-level); - //int h= height >> (s.spatial_decomposition_count-level); - int stride= width << (s.spatial_decomposition_count-level); - DWTELEM *buf= buffer[0]; - int64_t error=0; - - buf+=w; - buf+=stride>>1; - - memset(buffer[0], 0, sizeof(int)*width*height); -#if 1 - for(y=0; y - * Copyright (C) 2006 Robert Edele - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SNOW_H -#define AVCODEC_SNOW_H - -#include "dsputil.h" -#include "dwt.h" - -#define MID_STATE 128 - -#define MAX_PLANES 4 -#define QSHIFT 5 -#define QROOT (1<>1]; - (*i)--; - } -} - -static av_always_inline void snow_interleave_line_footer(int * i, IDWTELEM * low, IDWTELEM * high){ - for (; (*i)>=0; (*i)-=2){ - low[(*i)+1] = high[(*i)>>1]; - low[*i] = low[(*i)>>1]; - } -} - -static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){ - for(; i> shift); - } - - if((width^lift_high)&1){ - dst[w] = src[w] - ((mul * 2 * ref[w] + add) >> shift); - } -} - -static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w){ - for(; i> W_BS); - } - - if(width&1){ - dst[w] = src[w] + ((2 * ref[w] + W_BO + 4 * src[w]) >> W_BS); - } -} - -#endif /* AVCODEC_SNOW_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sonic.c b/tizen/distrib/ffmpeg/libavcodec/sonic.c deleted file mode 100644 index d24931f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sonic.c +++ /dev/null @@ -1,977 +0,0 @@ -/* - * Simple free lossless/lossy audio codec - * Copyright (c) 2004 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "get_bits.h" -#include "golomb.h" - -/** - * @file - * Simple free lossless/lossy audio codec - * Based on Paul Francis Harrison's Bonk (http://www.logarithmic.net/pfh/bonk) - * Written and designed by Alex Beregszaszi - * - * TODO: - * - CABAC put/get_symbol - * - independent quantizer for channels - * - >2 channels support - * - more decorrelation types - * - more tap_quant tests - * - selectable intlist writers/readers (bonk-style, golomb, cabac) - */ - -#define MAX_CHANNELS 2 - -#define MID_SIDE 0 -#define LEFT_SIDE 1 -#define RIGHT_SIDE 2 - -typedef struct SonicContext { - int lossless, decorrelation; - - int num_taps, downsampling; - double quantization; - - int channels, samplerate, block_align, frame_size; - - int *tap_quant; - int *int_samples; - int *coded_samples[MAX_CHANNELS]; - - // for encoding - int *tail; - int tail_size; - int *window; - int window_size; - - // for decoding - int *predictor_k; - int *predictor_state[MAX_CHANNELS]; -} SonicContext; - -#define LATTICE_SHIFT 10 -#define SAMPLE_SHIFT 4 -#define LATTICE_FACTOR (1 << LATTICE_SHIFT) -#define SAMPLE_FACTOR (1 << SAMPLE_SHIFT) - -#define BASE_QUANT 0.6 -#define RATE_VARIATION 3.0 - -static inline int divide(int a, int b) -{ - if (a < 0) - return -( (-a + b/2)/b ); - else - return (a + b/2)/b; -} - -static inline int shift(int a,int b) -{ - return (a+(1<<(b-1))) >> b; -} - -static inline int shift_down(int a,int b) -{ - return (a>>b)+((a<0)?1:0); -} - -#if 1 -static inline int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part) -{ - int i; - - for (i = 0; i < entries; i++) - set_se_golomb(pb, buf[i]); - - return 1; -} - -static inline int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part) -{ - int i; - - for (i = 0; i < entries; i++) - buf[i] = get_se_golomb(gb); - - return 1; -} - -#else - -#define ADAPT_LEVEL 8 - -static int bits_to_store(uint64_t x) -{ - int res = 0; - - while(x) - { - res++; - x >>= 1; - } - return res; -} - -static void write_uint_max(PutBitContext *pb, unsigned int value, unsigned int max) -{ - int i, bits; - - if (!max) - return; - - bits = bits_to_store(max); - - for (i = 0; i < bits-1; i++) - put_bits(pb, 1, value & (1 << i)); - - if ( (value | (1 << (bits-1))) <= max) - put_bits(pb, 1, value & (1 << (bits-1))); -} - -static unsigned int read_uint_max(GetBitContext *gb, int max) -{ - int i, bits, value = 0; - - if (!max) - return 0; - - bits = bits_to_store(max); - - for (i = 0; i < bits-1; i++) - if (get_bits1(gb)) - value += 1 << i; - - if ( (value | (1<<(bits-1))) <= max) - if (get_bits1(gb)) - value += 1 << (bits-1); - - return value; -} - -static int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part) -{ - int i, j, x = 0, low_bits = 0, max = 0; - int step = 256, pos = 0, dominant = 0, any = 0; - int *copy, *bits; - - copy = av_mallocz(4* entries); - if (!copy) - return -1; - - if (base_2_part) - { - int energy = 0; - - for (i = 0; i < entries; i++) - energy += abs(buf[i]); - - low_bits = bits_to_store(energy / (entries * 2)); - if (low_bits > 15) - low_bits = 15; - - put_bits(pb, 4, low_bits); - } - - for (i = 0; i < entries; i++) - { - put_bits(pb, low_bits, abs(buf[i])); - copy[i] = abs(buf[i]) >> low_bits; - if (copy[i] > max) - max = abs(copy[i]); - } - - bits = av_mallocz(4* entries*max); - if (!bits) - { -// av_free(copy); - return -1; - } - - for (i = 0; i <= max; i++) - { - for (j = 0; j < entries; j++) - if (copy[j] >= i) - bits[x++] = copy[j] > i; - } - - // store bitstream - while (pos < x) - { - int steplet = step >> 8; - - if (pos + steplet > x) - steplet = x - pos; - - for (i = 0; i < steplet; i++) - if (bits[i+pos] != dominant) - any = 1; - - put_bits(pb, 1, any); - - if (!any) - { - pos += steplet; - step += step / ADAPT_LEVEL; - } - else - { - int interloper = 0; - - while (((pos + interloper) < x) && (bits[pos + interloper] == dominant)) - interloper++; - - // note change - write_uint_max(pb, interloper, (step >> 8) - 1); - - pos += interloper + 1; - step -= step / ADAPT_LEVEL; - } - - if (step < 256) - { - step = 65536 / step; - dominant = !dominant; - } - } - - // store signs - for (i = 0; i < entries; i++) - if (buf[i]) - put_bits(pb, 1, buf[i] < 0); - -// av_free(bits); -// av_free(copy); - - return 0; -} - -static int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part) -{ - int i, low_bits = 0, x = 0; - int n_zeros = 0, step = 256, dominant = 0; - int pos = 0, level = 0; - int *bits = av_mallocz(4* entries); - - if (!bits) - return -1; - - if (base_2_part) - { - low_bits = get_bits(gb, 4); - - if (low_bits) - for (i = 0; i < entries; i++) - buf[i] = get_bits(gb, low_bits); - } - -// av_log(NULL, AV_LOG_INFO, "entries: %d, low bits: %d\n", entries, low_bits); - - while (n_zeros < entries) - { - int steplet = step >> 8; - - if (!get_bits1(gb)) - { - for (i = 0; i < steplet; i++) - bits[x++] = dominant; - - if (!dominant) - n_zeros += steplet; - - step += step / ADAPT_LEVEL; - } - else - { - int actual_run = read_uint_max(gb, steplet-1); - -// av_log(NULL, AV_LOG_INFO, "actual run: %d\n", actual_run); - - for (i = 0; i < actual_run; i++) - bits[x++] = dominant; - - bits[x++] = !dominant; - - if (!dominant) - n_zeros += actual_run; - else - n_zeros++; - - step -= step / ADAPT_LEVEL; - } - - if (step < 256) - { - step = 65536 / step; - dominant = !dominant; - } - } - - // reconstruct unsigned values - n_zeros = 0; - for (i = 0; n_zeros < entries; i++) - { - while(1) - { - if (pos >= entries) - { - pos = 0; - level += 1 << low_bits; - } - - if (buf[pos] >= level) - break; - - pos++; - } - - if (bits[i]) - buf[pos] += 1 << low_bits; - else - n_zeros++; - - pos++; - } -// av_free(bits); - - // read signs - for (i = 0; i < entries; i++) - if (buf[i] && get_bits1(gb)) - buf[i] = -buf[i]; - -// av_log(NULL, AV_LOG_INFO, "zeros: %d pos: %d\n", n_zeros, pos); - - return 0; -} -#endif - -static void predictor_init_state(int *k, int *state, int order) -{ - int i; - - for (i = order-2; i >= 0; i--) - { - int j, p, x = state[i]; - - for (j = 0, p = i+1; p < order; j++,p++) - { - int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT); - state[p] += shift_down(k[j]*x, LATTICE_SHIFT); - x = tmp; - } - } -} - -static int predictor_calc_error(int *k, int *state, int order, int error) -{ - int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT); - -#if 1 - int *k_ptr = &(k[order-2]), - *state_ptr = &(state[order-2]); - for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--) - { - int k_value = *k_ptr, state_value = *state_ptr; - x -= shift_down(k_value * state_value, LATTICE_SHIFT); - state_ptr[1] = state_value + shift_down(k_value * x, LATTICE_SHIFT); - } -#else - for (i = order-2; i >= 0; i--) - { - x -= shift_down(k[i] * state[i], LATTICE_SHIFT); - state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT); - } -#endif - - // don't drift too far, to avoid overflows - if (x > (SAMPLE_FACTOR<<16)) x = (SAMPLE_FACTOR<<16); - if (x < -(SAMPLE_FACTOR<<16)) x = -(SAMPLE_FACTOR<<16); - - state[0] = x; - - return x; -} - -#if CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER -// Heavily modified Levinson-Durbin algorithm which -// copes better with quantization, and calculates the -// actual whitened result as it goes. - -static void modified_levinson_durbin(int *window, int window_entries, - int *out, int out_entries, int channels, int *tap_quant) -{ - int i; - int *state = av_mallocz(4* window_entries); - - memcpy(state, window, 4* window_entries); - - for (i = 0; i < out_entries; i++) - { - int step = (i+1)*channels, k, j; - double xx = 0.0, xy = 0.0; -#if 1 - int *x_ptr = &(window[step]), *state_ptr = &(state[0]); - j = window_entries - step; - for (;j>=0;j--,x_ptr++,state_ptr++) - { - double x_value = *x_ptr, state_value = *state_ptr; - xx += state_value*state_value; - xy += x_value*state_value; - } -#else - for (j = 0; j <= (window_entries - step); j++); - { - double stepval = window[step+j], stateval = window[j]; -// xx += (double)window[j]*(double)window[j]; -// xy += (double)window[step+j]*(double)window[j]; - xx += stateval*stateval; - xy += stepval*stateval; - } -#endif - if (xx == 0.0) - k = 0; - else - k = (int)(floor(-xy/xx * (double)LATTICE_FACTOR / (double)(tap_quant[i]) + 0.5)); - - if (k > (LATTICE_FACTOR/tap_quant[i])) - k = LATTICE_FACTOR/tap_quant[i]; - if (-k > (LATTICE_FACTOR/tap_quant[i])) - k = -(LATTICE_FACTOR/tap_quant[i]); - - out[i] = k; - k *= tap_quant[i]; - -#if 1 - x_ptr = &(window[step]); - state_ptr = &(state[0]); - j = window_entries - step; - for (;j>=0;j--,x_ptr++,state_ptr++) - { - int x_value = *x_ptr, state_value = *state_ptr; - *x_ptr = x_value + shift_down(k*state_value,LATTICE_SHIFT); - *state_ptr = state_value + shift_down(k*x_value, LATTICE_SHIFT); - } -#else - for (j=0; j <= (window_entries - step); j++) - { - int stepval = window[step+j], stateval=state[j]; - window[step+j] += shift_down(k * stateval, LATTICE_SHIFT); - state[j] += shift_down(k * stepval, LATTICE_SHIFT); - } -#endif - } - - av_free(state); -} - -static inline int code_samplerate(int samplerate) -{ - switch (samplerate) - { - case 44100: return 0; - case 22050: return 1; - case 11025: return 2; - case 96000: return 3; - case 48000: return 4; - case 32000: return 5; - case 24000: return 6; - case 16000: return 7; - case 8000: return 8; - } - return -1; -} - -static av_cold int sonic_encode_init(AVCodecContext *avctx) -{ - SonicContext *s = avctx->priv_data; - PutBitContext pb; - int i, version = 0; - - if (avctx->channels > MAX_CHANNELS) - { - av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n"); - return -1; /* only stereo or mono for now */ - } - - if (avctx->channels == 2) - s->decorrelation = MID_SIDE; - - if (avctx->codec->id == CODEC_ID_SONIC_LS) - { - s->lossless = 1; - s->num_taps = 32; - s->downsampling = 1; - s->quantization = 0.0; - } - else - { - s->num_taps = 128; - s->downsampling = 2; - s->quantization = 1.0; - } - - // max tap 2048 - if ((s->num_taps < 32) || (s->num_taps > 1024) || - ((s->num_taps>>5)<<5 != s->num_taps)) - { - av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n"); - return -1; - } - - // generate taps - s->tap_quant = av_mallocz(4* s->num_taps); - for (i = 0; i < s->num_taps; i++) - s->tap_quant[i] = (int)(sqrt(i+1)); - - s->channels = avctx->channels; - s->samplerate = avctx->sample_rate; - - s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling; - s->frame_size = s->channels*s->block_align*s->downsampling; - - s->tail = av_mallocz(4* s->num_taps*s->channels); - if (!s->tail) - return -1; - s->tail_size = s->num_taps*s->channels; - - s->predictor_k = av_mallocz(4 * s->num_taps); - if (!s->predictor_k) - return -1; - - for (i = 0; i < s->channels; i++) - { - s->coded_samples[i] = av_mallocz(4* s->block_align); - if (!s->coded_samples[i]) - return -1; - } - - s->int_samples = av_mallocz(4* s->frame_size); - - s->window_size = ((2*s->tail_size)+s->frame_size); - s->window = av_mallocz(4* s->window_size); - if (!s->window) - return -1; - - avctx->extradata = av_mallocz(16); - if (!avctx->extradata) - return -1; - init_put_bits(&pb, avctx->extradata, 16*8); - - put_bits(&pb, 2, version); // version - if (version == 1) - { - put_bits(&pb, 2, s->channels); - put_bits(&pb, 4, code_samplerate(s->samplerate)); - } - put_bits(&pb, 1, s->lossless); - if (!s->lossless) - put_bits(&pb, 3, SAMPLE_SHIFT); // XXX FIXME: sample precision - put_bits(&pb, 2, s->decorrelation); - put_bits(&pb, 2, s->downsampling); - put_bits(&pb, 5, (s->num_taps >> 5)-1); // 32..1024 - put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table - - flush_put_bits(&pb); - avctx->extradata_size = put_bits_count(&pb)/8; - - av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", - version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); - - avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return AVERROR(ENOMEM); - avctx->coded_frame->key_frame = 1; - avctx->frame_size = s->block_align*s->downsampling; - - return 0; -} - -static av_cold int sonic_encode_close(AVCodecContext *avctx) -{ - SonicContext *s = avctx->priv_data; - int i; - - av_freep(&avctx->coded_frame); - - for (i = 0; i < s->channels; i++) - av_free(s->coded_samples[i]); - - av_free(s->predictor_k); - av_free(s->tail); - av_free(s->tap_quant); - av_free(s->window); - av_free(s->int_samples); - - return 0; -} - -static int sonic_encode_frame(AVCodecContext *avctx, - uint8_t *buf, int buf_size, void *data) -{ - SonicContext *s = avctx->priv_data; - PutBitContext pb; - int i, j, ch, quant = 0, x = 0; - short *samples = data; - - init_put_bits(&pb, buf, buf_size*8); - - // short -> internal - for (i = 0; i < s->frame_size; i++) - s->int_samples[i] = samples[i]; - - if (!s->lossless) - for (i = 0; i < s->frame_size; i++) - s->int_samples[i] = s->int_samples[i] << SAMPLE_SHIFT; - - switch(s->decorrelation) - { - case MID_SIDE: - for (i = 0; i < s->frame_size; i += s->channels) - { - s->int_samples[i] += s->int_samples[i+1]; - s->int_samples[i+1] -= shift(s->int_samples[i], 1); - } - break; - case LEFT_SIDE: - for (i = 0; i < s->frame_size; i += s->channels) - s->int_samples[i+1] -= s->int_samples[i]; - break; - case RIGHT_SIDE: - for (i = 0; i < s->frame_size; i += s->channels) - s->int_samples[i] -= s->int_samples[i+1]; - break; - } - - memset(s->window, 0, 4* s->window_size); - - for (i = 0; i < s->tail_size; i++) - s->window[x++] = s->tail[i]; - - for (i = 0; i < s->frame_size; i++) - s->window[x++] = s->int_samples[i]; - - for (i = 0; i < s->tail_size; i++) - s->window[x++] = 0; - - for (i = 0; i < s->tail_size; i++) - s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i]; - - // generate taps - modified_levinson_durbin(s->window, s->window_size, - s->predictor_k, s->num_taps, s->channels, s->tap_quant); - if (intlist_write(&pb, s->predictor_k, s->num_taps, 0) < 0) - return -1; - - for (ch = 0; ch < s->channels; ch++) - { - x = s->tail_size+ch; - for (i = 0; i < s->block_align; i++) - { - int sum = 0; - for (j = 0; j < s->downsampling; j++, x += s->channels) - sum += s->window[x]; - s->coded_samples[ch][i] = sum; - } - } - - // simple rate control code - if (!s->lossless) - { - double energy1 = 0.0, energy2 = 0.0; - for (ch = 0; ch < s->channels; ch++) - { - for (i = 0; i < s->block_align; i++) - { - double sample = s->coded_samples[ch][i]; - energy2 += sample*sample; - energy1 += fabs(sample); - } - } - - energy2 = sqrt(energy2/(s->channels*s->block_align)); - energy1 = sqrt(2.0)*energy1/(s->channels*s->block_align); - - // increase bitrate when samples are like a gaussian distribution - // reduce bitrate when samples are like a two-tailed exponential distribution - - if (energy2 > energy1) - energy2 += (energy2-energy1)*RATE_VARIATION; - - quant = (int)(BASE_QUANT*s->quantization*energy2/SAMPLE_FACTOR); -// av_log(avctx, AV_LOG_DEBUG, "quant: %d energy: %f / %f\n", quant, energy1, energy2); - - if (quant < 1) - quant = 1; - if (quant > 65535) - quant = 65535; - - set_ue_golomb(&pb, quant); - - quant *= SAMPLE_FACTOR; - } - - // write out coded samples - for (ch = 0; ch < s->channels; ch++) - { - if (!s->lossless) - for (i = 0; i < s->block_align; i++) - s->coded_samples[ch][i] = divide(s->coded_samples[ch][i], quant); - - if (intlist_write(&pb, s->coded_samples[ch], s->block_align, 1) < 0) - return -1; - } - -// av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8); - - flush_put_bits(&pb); - return (put_bits_count(&pb)+7)/8; -} -#endif /* CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER */ - -#if CONFIG_SONIC_DECODER -static const int samplerate_table[] = - { 44100, 22050, 11025, 96000, 48000, 32000, 24000, 16000, 8000 }; - -static av_cold int sonic_decode_init(AVCodecContext *avctx) -{ - SonicContext *s = avctx->priv_data; - GetBitContext gb; - int i, version; - - s->channels = avctx->channels; - s->samplerate = avctx->sample_rate; - - if (!avctx->extradata) - { - av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n"); - return -1; - } - - init_get_bits(&gb, avctx->extradata, avctx->extradata_size); - - version = get_bits(&gb, 2); - if (version > 1) - { - av_log(avctx, AV_LOG_ERROR, "Unsupported Sonic version, please report\n"); - return -1; - } - - if (version == 1) - { - s->channels = get_bits(&gb, 2); - s->samplerate = samplerate_table[get_bits(&gb, 4)]; - av_log(avctx, AV_LOG_INFO, "Sonicv2 chans: %d samprate: %d\n", - s->channels, s->samplerate); - } - - if (s->channels > MAX_CHANNELS) - { - av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n"); - return -1; - } - - s->lossless = get_bits1(&gb); - if (!s->lossless) - skip_bits(&gb, 3); // XXX FIXME - s->decorrelation = get_bits(&gb, 2); - - s->downsampling = get_bits(&gb, 2); - s->num_taps = (get_bits(&gb, 5)+1)<<5; - if (get_bits1(&gb)) // XXX FIXME - av_log(avctx, AV_LOG_INFO, "Custom quant table\n"); - - s->block_align = (int)(2048.0*(s->samplerate/44100))/s->downsampling; - s->frame_size = s->channels*s->block_align*s->downsampling; -// avctx->frame_size = s->block_align; - - av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", - version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); - - // generate taps - s->tap_quant = av_mallocz(4* s->num_taps); - for (i = 0; i < s->num_taps; i++) - s->tap_quant[i] = (int)(sqrt(i+1)); - - s->predictor_k = av_mallocz(4* s->num_taps); - - for (i = 0; i < s->channels; i++) - { - s->predictor_state[i] = av_mallocz(4* s->num_taps); - if (!s->predictor_state[i]) - return -1; - } - - for (i = 0; i < s->channels; i++) - { - s->coded_samples[i] = av_mallocz(4* s->block_align); - if (!s->coded_samples[i]) - return -1; - } - s->int_samples = av_mallocz(4* s->frame_size); - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -static av_cold int sonic_decode_close(AVCodecContext *avctx) -{ - SonicContext *s = avctx->priv_data; - int i; - - av_free(s->int_samples); - av_free(s->tap_quant); - av_free(s->predictor_k); - - for (i = 0; i < s->channels; i++) - { - av_free(s->predictor_state[i]); - av_free(s->coded_samples[i]); - } - - return 0; -} - -static int sonic_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - SonicContext *s = avctx->priv_data; - GetBitContext gb; - int i, quant, ch, j; - short *samples = data; - - if (buf_size == 0) return 0; - -// av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size); - - init_get_bits(&gb, buf, buf_size*8); - - intlist_read(&gb, s->predictor_k, s->num_taps, 0); - - // dequantize - for (i = 0; i < s->num_taps; i++) - s->predictor_k[i] *= s->tap_quant[i]; - - if (s->lossless) - quant = 1; - else - quant = get_ue_golomb(&gb) * SAMPLE_FACTOR; - -// av_log(NULL, AV_LOG_INFO, "quant: %d\n", quant); - - for (ch = 0; ch < s->channels; ch++) - { - int x = ch; - - predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps); - - intlist_read(&gb, s->coded_samples[ch], s->block_align, 1); - - for (i = 0; i < s->block_align; i++) - { - for (j = 0; j < s->downsampling - 1; j++) - { - s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, 0); - x += s->channels; - } - - s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, s->coded_samples[ch][i] * quant); - x += s->channels; - } - - for (i = 0; i < s->num_taps; i++) - s->predictor_state[ch][i] = s->int_samples[s->frame_size - s->channels + ch - i*s->channels]; - } - - switch(s->decorrelation) - { - case MID_SIDE: - for (i = 0; i < s->frame_size; i += s->channels) - { - s->int_samples[i+1] += shift(s->int_samples[i], 1); - s->int_samples[i] -= s->int_samples[i+1]; - } - break; - case LEFT_SIDE: - for (i = 0; i < s->frame_size; i += s->channels) - s->int_samples[i+1] += s->int_samples[i]; - break; - case RIGHT_SIDE: - for (i = 0; i < s->frame_size; i += s->channels) - s->int_samples[i] += s->int_samples[i+1]; - break; - } - - if (!s->lossless) - for (i = 0; i < s->frame_size; i++) - s->int_samples[i] = shift(s->int_samples[i], SAMPLE_SHIFT); - - // internal -> short - for (i = 0; i < s->frame_size; i++) - samples[i] = av_clip_int16(s->int_samples[i]); - - align_get_bits(&gb); - - *data_size = s->frame_size * 2; - - return (get_bits_count(&gb)+7)/8; -} - -AVCodec sonic_decoder = { - "sonic", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_SONIC, - sizeof(SonicContext), - sonic_decode_init, - NULL, - sonic_decode_close, - sonic_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Sonic"), -}; -#endif /* CONFIG_SONIC_DECODER */ - -#if CONFIG_SONIC_ENCODER -AVCodec sonic_encoder = { - "sonic", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_SONIC, - sizeof(SonicContext), - sonic_encode_init, - sonic_encode_frame, - sonic_encode_close, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Sonic"), -}; -#endif - -#if CONFIG_SONIC_LS_ENCODER -AVCodec sonic_ls_encoder = { - "sonicls", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_SONIC_LS, - sizeof(SonicContext), - sonic_encode_init, - sonic_encode_frame, - sonic_encode_close, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/sp5x.h b/tizen/distrib/ffmpeg/libavcodec/sp5x.h deleted file mode 100644 index b2c53cc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sp5x.h +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Sunplus JPEG tables - * Copyright (c) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SP5X_H -#define AVCODEC_SP5X_H - -#include - -static const uint8_t sp5x_data_sof[] = -{ - 0xFF, 0xC0, /* SOF */ - 0x00, 0x11, /* len */ - 0x08, /* bits */ - 0x00, 0xf0, /* height (default: 240) */ - 0x01, 0x40, /* width (default: 240) */ - 0x03, /* nb components */ - 0x01, 0x22, 0x00, /* 21 vs 22 ? */ - 0x02, 0x11, 0x01, - 0x03, 0x11, 0x01 -}; - -static const uint8_t sp5x_data_sos[] = -{ - 0xFF, 0xDA, /* SOS */ - 0x00, 0x0C, /* len */ - 0x03, /* nb components */ - 0x01, 0x00, - 0x02, 0x11, - 0x03, 0x11, - 0x00, /* Ss */ - 0x3F, /* Se */ - 0x00 /* Ah/Al */ -}; - -static const uint8_t sp5x_data_dqt[] = -{ - 0xFF, 0xDB, /* DQT */ - 0x00, 0x84, /* len */ - 0x00, - 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, - 0x04, 0x04, 0x06, 0x05, 0x05, 0x06, 0x08, 0x0D, - 0x08, 0x08, 0x07, 0x07, 0x08, 0x10, 0x0C, 0x0C, - 0x0A, 0x0D, 0x14, 0x11, 0x15, 0x14, 0x13, 0x11, - 0x13, 0x13, 0x16, 0x18, 0x1F, 0x1A, 0x16, 0x17, - 0x1E, 0x17, 0x13, 0x13, 0x1B, 0x25, 0x1C, 0x1E, - 0x20, 0x21, 0x23, 0x23, 0x23, 0x15, 0x1A, 0x27, - 0x29, 0x26, 0x22, 0x29, 0x1F, 0x22, 0x23, 0x22, - 0x01, - 0x05, 0x06, 0x06, 0x08, 0x07, 0x08, 0x10, 0x08, - 0x08, 0x10, 0x22, 0x16, 0x13, 0x16, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 -}; - -static const uint8_t sp5x_data_dht[] = { - 0xFF, 0xC4, /* DHT */ - 0x01, 0xA2, /* len */ - 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x01, 0x00, 0x03, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, - 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, - 0x00, 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, - 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, - 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, - 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, - 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, - 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, - 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, - 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, - 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, - 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, - 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, - 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, - 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x11, 0x00, 0x02, - 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, - 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, - 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, - 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, - 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, - 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, - 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, - 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, - 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, - 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, - 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, - 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, - 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, - 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, - 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, - 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, - 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, - 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA -}; - - -static const uint8_t sp5x_quant_table[20][64]= -{ - /* index 0, Q50 */ - { 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, - 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51, - 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80,109, 81, 87, - 95, 98,103,104,103, 62, 77,113,121,112,100,120, 92,101,103, 99 }, - { 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }, - - /* index 1, Q70 */ - { 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24, - 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31, - 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52, - 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59 }, - { 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59 }, - - /* index 2, Q80 */ - { 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16, - 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20, - 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35, - 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40 }, - { 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 }, - - /* index 3, Q85 */ - { 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12, - 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15, - 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26, - 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30 }, - { 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }, - - /* index 4, Q90 */ - { 3, 2, 2, 3, 2, 2, 3, 3, 3, 3, 4, 3, 3, 4, 5, 8, - 5, 5, 4, 4, 5, 10, 7, 7, 6, 8, 12, 10, 12, 12, 11, 10, - 11, 11, 13, 14, 18, 16, 13, 14, 17, 14, 11, 11, 16, 22, 16, 17, - 19, 20, 21, 21, 21, 12, 15, 23, 24, 22, 20, 24, 18, 20, 21, 20 }, - { 3, 4, 4, 5, 4, 5, 9, 5, 5, 9, 20, 13, 11, 13, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 }, - - /* index 5, Q60 */ - { 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32, - 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41, - 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70, - 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79 }, - { 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79 }, - - /* index 6, Q25 */ - { 32, 22, 24, 28, 24, 20, 32, 28, 26, 28, 36, 34, 32, 38, 48, 80, - 52, 48, 44, 44, 48, 98, 70, 74, 58, 80,116,102,122,120,114,102, - 112,110,128,144,184,156,128,136,174,138,110,112,160,218,162,174, - 190,196,206,208,206,124,154,226,242,224,200,240,184,202,206,198 }, - { 34, 36, 36, 48, 42, 48, 94, 52, 52, 94,198,132,112,132,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198 }, - - /* index 7, Q95 */ - { 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 4, - 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, - 6, 6, 6, 7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, - 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10, 10, 10 }, - { 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 }, - - /* index 8, Q93 */ - { 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 3, 2, 2, 3, 3, 6, - 4, 3, 3, 3, 3, 7, 5, 5, 4, 6, 8, 7, 9, 8, 8, 7, - 8, 8, 9, 10, 13, 11, 9, 10, 12, 10, 8, 8, 11, 15, 11, 12, - 13, 14, 14, 15, 14, 9, 11, 16, 17, 16, 14, 17, 13, 14, 14, 14 }, - { 2, 3, 3, 3, 3, 3, 7, 4, 4, 7, 14, 9, 8, 9, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 }, - - /* index 9, Q40 */ - { 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50, - 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64, - 70, 69, 80, 90,115, 98, 80, 85,109, 86, 69, 70,100,136,101,109, - 119,123,129,130,129, 78, 96,141,151,140,125,150,115,126,129,124 }, - { 21, 23, 23, 30, 26, 30, 59, 33, 33, 59,124, 83, 70, 83,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, - 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124 } -}; - -#if 0 -/* 4NF-M, not ZigZag */ -static const uint8_t sp5x_quant_table_orig[18][64] = -{ - /* index 0, Q50 */ - { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 56, 68,109,103, 77, 24, 35, 55, 64, 81,104,113, 92, - 49, 64, 78, 87,103,121,120,101, 72, 92, 95, 98,112,100,103, 99 }, - { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }, - - /* index 1, Q70 */ - { 10, 7, 6, 10, 14, 24, 31, 37, 7, 7, 8, 11, 16, 35, 36, 33, - 8, 8, 10, 14, 24, 34, 41, 34, 8, 10, 13, 17, 31, 52, 48, 37, - 11, 13, 22, 34, 41, 65, 62, 46, 14, 21, 33, 38, 49, 62, 68, 55, - 29, 38, 47, 52, 62, 73, 72, 61, 43, 55, 57, 59, 67, 60, 62, 59 }, - { 10, 11, 14, 28, 59, 59, 59, 59, 11, 13, 16, 40, 59, 59, 59, 59, - 14, 16, 34, 59, 59, 59, 59, 59, 28, 40, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59 }, - - /* index 2, Q80 */ - { 6, 4, 4, 6, 10, 16, 20, 24, 5, 5, 6, 8, 10, 23, 24, 22, - 6, 5, 6, 10, 16, 23, 28, 22, 6, 7, 9, 12, 20, 35, 32, 25, - 7, 9, 15, 22, 27, 44, 41, 31, 10, 14, 22, 26, 32, 42, 45, 37, - 20, 26, 31, 35, 41, 48, 48, 40, 29, 37, 38, 39, 45, 40, 41, 40 }, - { 7, 7, 10, 19, 40, 40, 40, 40, 7, 8, 10, 26, 40, 40, 40, 40, - 10, 10, 22, 40, 40, 40, 40, 40, 19, 26, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 }, - - /* index 3, Q85 */ - { 5, 3, 3, 5, 7, 12, 15, 18, 4, 4, 4, 6, 8, 17, 18, 17, - 4, 4, 5, 7, 12, 17, 21, 17, 4, 5, 7, 9, 15, 26, 24, 19, - 5, 7, 11, 17, 20, 33, 31, 23, 7, 11, 17, 19, 24, 31, 34, 28, - 15, 19, 23, 26, 31, 36, 36, 30, 22, 28, 29, 29, 34, 30, 31, 30 }, - { 5, 5, 7, 14, 30, 30, 30, 30, 5, 6, 8, 20, 30, 30, 30, 30, - 7, 8, 17, 30, 30, 30, 30, 30, 14, 20, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }, - - /* index 4, Q90 */ - { 3, 2, 2, 3, 5, 8, 10, 12, 2, 2, 3, 4, 5, 12, 12, 11, - 3, 3, 3, 5, 8, 11, 14, 11, 3, 3, 4, 6, 10, 17, 16, 12, - 4, 4, 7, 11, 14, 22, 21, 15, 5, 7, 11, 13, 16, 21, 23, 18, - 10, 13, 16, 17, 21, 24, 24, 20, 14, 18, 19, 20, 22, 20, 21, 20 }, - { 3, 4, 5, 9, 20, 20, 20, 20, 4, 4, 5, 13, 20, 20, 20, 20, - 5, 5, 11, 20, 20, 20, 20, 20, 9, 13, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 }, - - /* index 5, Q60 */ - { 13, 9, 8, 13, 19, 32, 41, 49, 10, 10, 11, 15, 21, 46, 48, 44, - 11, 10, 13, 19, 32, 46, 55, 45, 11, 14, 18, 23, 41, 70, 64, 50, - 14, 18, 30, 45, 54, 87, 82, 62, 19, 28, 44, 51, 65, 83, 90, 74, - 39, 51, 62, 70, 82, 97, 96, 81, 58, 74, 76, 78, 90, 80, 82, 79 }, - { 14, 14, 19, 38, 79, 79, 79, 79, 14, 17, 21, 53, 79, 79, 79, 79, - 19, 21, 45, 79, 79, 79, 79, 79, 38, 53, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79 }, - - /* index 6, Q25 */ - { 32, 22, 20, 32, 48, 80,102,122, 24, 24, 28, 38, 52,116,120,110, - 28, 26, 32, 48, 80,114,138,112, 28, 34, 44, 58,102,174,160,124, - 36, 44, 74,112,136,218,206,154, 48, 70,110,128,162,208,226,184, - 98,128,156,174,206,242,240,202,144,184,190,196,224,200,206,198 }, - { 34, 36, 48, 94,198,198,198,198, 36, 42, 52,132,198,198,198,198, - 48, 52,112,198,198,198,198,198, 94,132,198,198,198,198,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, - 198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198 }, - - /* index 7, Q95 */ - { 2, 1, 1, 2, 2, 4, 5, 6, 1, 1, 1, 2, 3, 6, 6, 6, - 1, 1, 2, 2, 4, 6, 7, 6, 1, 2, 2, 3, 5, 9, 8, 6, - 2, 2, 4, 6, 7, 11, 10, 8, 2, 4, 6, 6, 8, 10, 11, 9, - 5, 6, 8, 9, 10, 12, 12, 10, 7, 9, 10, 10, 11, 10, 10, 10 }, - { 2, 2, 2, 5, 10, 10, 10, 10, 2, 2, 3, 7, 10, 10, 10, 10, - 2, 3, 6, 10, 10, 10, 10, 10, 5, 7, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 }, - - /* index 8, Q93 */ - { 2, 2, 1, 2, 3, 6, 7, 9, 2, 2, 2, 3, 4, 8, 8, 8, - 2, 2, 2, 3, 6, 8, 10, 8, 2, 2, 3, 4, 7, 12, 11, 9, - 3, 3, 5, 8, 10, 15, 14, 11, 3, 5, 8, 9, 11, 15, 16, 13, - 7, 9, 11, 12, 14, 17, 17, 14, 10, 13, 13, 14, 16, 14, 14, 14 }, - { 2, 3, 3, 7, 14, 14, 14, 14, 3, 3, 4, 9, 14, 14, 14, 14, - 3, 4, 8, 14, 14, 14, 14, 14, 7, 9, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 } -}; -#endif - -#endif /* AVCODEC_SP5X_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sp5xdec.c b/tizen/distrib/ffmpeg/libavcodec/sp5xdec.c deleted file mode 100644 index 754926a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sp5xdec.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Sunplus JPEG decoder (SP5X) - * Copyright (c) 2003 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sunplus JPEG decoder (SP5X). - */ - -#include "avcodec.h" -#include "mjpeg.h" -#include "mjpegdec.h" -#include "sp5x.h" - - -static int sp5x_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AVPacket avpkt_recoded; -#if 0 - MJpegDecodeContext *s = avctx->priv_data; -#endif - const int qscale = 5; - const uint8_t *buf_ptr; - uint8_t *recoded; - int i = 0, j = 0; - - if (!avctx->width || !avctx->height) - return -1; - - buf_ptr = buf; - -#if 1 - recoded = av_mallocz(buf_size + 1024); - if (!recoded) - return -1; - - /* SOI */ - recoded[j++] = 0xFF; - recoded[j++] = 0xD8; - - memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt)); - memcpy(recoded+j+5, &sp5x_quant_table[qscale * 2], 64); - memcpy(recoded+j+70, &sp5x_quant_table[(qscale * 2) + 1], 64); - j += sizeof(sp5x_data_dqt); - - memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht)); - j += sizeof(sp5x_data_dht); - - memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof)); - AV_WB16(recoded+j+5, avctx->coded_height); - AV_WB16(recoded+j+7, avctx->coded_width); - j += sizeof(sp5x_data_sof); - - memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos)); - j += sizeof(sp5x_data_sos); - - if(avctx->codec_id==CODEC_ID_AMV) - for (i = 2; i < buf_size-2 && j < buf_size+1024-2; i++) - recoded[j++] = buf[i]; - else - for (i = 14; i < buf_size && j < buf_size+1024-2; i++) - { - recoded[j++] = buf[i]; - if (buf[i] == 0xff) - recoded[j++] = 0; - } - - /* EOI */ - recoded[j++] = 0xFF; - recoded[j++] = 0xD9; - - avctx->flags &= ~CODEC_FLAG_EMU_EDGE; - av_init_packet(&avpkt_recoded); - avpkt_recoded.data = recoded; - avpkt_recoded.size = j; - i = ff_mjpeg_decode_frame(avctx, data, data_size, &avpkt_recoded); - - av_free(recoded); - -#else - /* SOF */ - s->bits = 8; - s->width = avctx->coded_width; - s->height = avctx->coded_height; - s->nb_components = 3; - s->component_id[0] = 0; - s->h_count[0] = 2; - s->v_count[0] = 2; - s->quant_index[0] = 0; - s->component_id[1] = 1; - s->h_count[1] = 1; - s->v_count[1] = 1; - s->quant_index[1] = 1; - s->component_id[2] = 2; - s->h_count[2] = 1; - s->v_count[2] = 1; - s->quant_index[2] = 1; - s->h_max = 2; - s->v_max = 2; - - s->qscale_table = av_mallocz((s->width+15)/16); - avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420; - s->interlaced = 0; - - s->picture.reference = 0; - if (avctx->get_buffer(avctx, &s->picture) < 0) - { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - s->picture.pict_type = FF_I_TYPE; - s->picture.key_frame = 1; - - for (i = 0; i < 3; i++) - s->linesize[i] = s->picture.linesize[i] << s->interlaced; - - /* DQT */ - for (i = 0; i < 64; i++) - { - j = s->scantable.permutated[i]; - s->quant_matrixes[0][j] = sp5x_quant_table[(qscale * 2) + i]; - } - s->qscale[0] = FFMAX( - s->quant_matrixes[0][s->scantable.permutated[1]], - s->quant_matrixes[0][s->scantable.permutated[8]]) >> 1; - - for (i = 0; i < 64; i++) - { - j = s->scantable.permutated[i]; - s->quant_matrixes[1][j] = sp5x_quant_table[(qscale * 2) + 1 + i]; - } - s->qscale[1] = FFMAX( - s->quant_matrixes[1][s->scantable.permutated[1]], - s->quant_matrixes[1][s->scantable.permutated[8]]) >> 1; - - /* DHT */ - - /* SOS */ - s->comp_index[0] = 0; - s->nb_blocks[0] = s->h_count[0] * s->v_count[0]; - s->h_scount[0] = s->h_count[0]; - s->v_scount[0] = s->v_count[0]; - s->dc_index[0] = 0; - s->ac_index[0] = 0; - - s->comp_index[1] = 1; - s->nb_blocks[1] = s->h_count[1] * s->v_count[1]; - s->h_scount[1] = s->h_count[1]; - s->v_scount[1] = s->v_count[1]; - s->dc_index[1] = 1; - s->ac_index[1] = 1; - - s->comp_index[2] = 2; - s->nb_blocks[2] = s->h_count[2] * s->v_count[2]; - s->h_scount[2] = s->h_count[2]; - s->v_scount[2] = s->v_count[2]; - s->dc_index[2] = 1; - s->ac_index[2] = 1; - - for (i = 0; i < 3; i++) - s->last_dc[i] = 1024; - - s->mb_width = (s->width * s->h_max * 8 -1) / (s->h_max * 8); - s->mb_height = (s->height * s->v_max * 8 -1) / (s->v_max * 8); - - init_get_bits(&s->gb, buf+14, (buf_size-14)*8); - - return mjpeg_decode_scan(s); -#endif - - return i; -} - -AVCodec sp5x_decoder = { - "sp5x", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SP5X, - sizeof(MJpegDecodeContext), - ff_mjpeg_decode_init, - NULL, - ff_mjpeg_decode_end, - sp5x_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"), -}; - -AVCodec amv_decoder = { - "amv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_AMV, - sizeof(MJpegDecodeContext), - ff_mjpeg_decode_init, - NULL, - ff_mjpeg_decode_end, - sp5x_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("AMV Video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/sparc/Makefile b/tizen/distrib/ffmpeg/libavcodec/sparc/Makefile deleted file mode 100644 index 4b38746..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sparc/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -OBJS-$(HAVE_VIS) += sparc/dsputil_vis.o \ - sparc/simple_idct_vis.o \ diff --git a/tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.c b/tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.c deleted file mode 100644 index a39096c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.c +++ /dev/null @@ -1,4005 +0,0 @@ -/* - * Copyright (C) 2003 David S. Miller - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* The *no_round* functions have been added by James A. Morrison, 2003,2004. - The vis code from libmpeg2 was adapted for ffmpeg by James A. Morrison. - */ - -#include "config.h" - -#include - -#include "libavcodec/dsputil.h" -#include "dsputil_vis.h" - -#include "vis.h" - -/* The trick used in some of this file is the formula from the MMX - * motion comp code, which is: - * - * (x+y+1)>>1 == (x|y)-((x^y)>>1) - * - * This allows us to average 8 bytes at a time in a 64-bit FPU reg. - * We avoid overflows by masking before we do the shift, and we - * implement the shift by multiplying by 1/2 using mul8x16. So in - * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask - * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and - * the value 0x80808080 is in f8): - * - * fxor f0, f2, f10 - * fand f10, f4, f10 - * fmul8x16 f8, f10, f10 - * fand f10, f6, f10 - * for f0, f2, f12 - * fpsub16 f12, f10, f10 - */ - -#define DUP4(x) {x, x, x, x} -#define DUP8(x) {x, x, x, x, x, x, x, x} -DECLARE_ALIGNED(8, static const int16_t, constants1)[] = DUP4 (1); -DECLARE_ALIGNED(8, static const int16_t, constants2)[] = DUP4 (2); -DECLARE_ALIGNED(8, static const int16_t, constants3)[] = DUP4 (3); -DECLARE_ALIGNED(8, static const int16_t, constants6)[] = DUP4 (6); -DECLARE_ALIGNED(8, static const int8_t, constants_fe)[] = DUP8 (0xfe); -DECLARE_ALIGNED(8, static const int8_t, constants_7f)[] = DUP8 (0x7f); -DECLARE_ALIGNED(8, static const int8_t, constants128)[] = DUP8 (128); -DECLARE_ALIGNED(8, static const int16_t, constants256_512)[] = - {256, 512, 256, 512}; -DECLARE_ALIGNED(8, static const int16_t, constants256_1024)[] = - {256, 1024, 256, 1024}; - -#define REF_0 0 -#define REF_0_1 1 -#define REF_2 2 -#define REF_2_1 3 -#define REF_4 4 -#define REF_4_1 5 -#define REF_6 6 -#define REF_6_1 7 -#define REF_S0 8 -#define REF_S0_1 9 -#define REF_S2 10 -#define REF_S2_1 11 -#define REF_S4 12 -#define REF_S4_1 13 -#define REF_S6 14 -#define REF_S6_1 15 -#define DST_0 16 -#define DST_1 17 -#define DST_2 18 -#define DST_3 19 -#define CONST_1 20 -#define CONST_2 20 -#define CONST_3 20 -#define CONST_6 20 -#define MASK_fe 20 -#define CONST_128 22 -#define CONST_256 22 -#define CONST_512 22 -#define CONST_1024 22 -#define TMP0 24 -#define TMP1 25 -#define TMP2 26 -#define TMP3 27 -#define TMP4 28 -#define TMP5 29 -#define ZERO 30 -#define MASK_7f 30 - -#define TMP6 32 -#define TMP8 34 -#define TMP10 36 -#define TMP12 38 -#define TMP14 40 -#define TMP16 42 -#define TMP18 44 -#define TMP20 46 -#define TMP22 48 -#define TMP24 50 -#define TMP26 52 -#define TMP28 54 -#define TMP30 56 -#define TMP32 58 - -static void MC_put_o_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - do { /* 5 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - - vis_faligndata(TMP0, TMP2, REF_0); - vis_st64(REF_0, dest[0]); - - vis_faligndata(TMP2, TMP4, REF_2); - vis_st64_2(REF_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_put_o_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - do { /* 4 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - ref += stride; - - /* stall */ - - vis_faligndata(TMP0, TMP2, REF_0); - vis_st64(REF_0, dest[0]); - dest += stride; - } while (--height); -} - - -static void MC_avg_o_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - int stride_8 = stride + 8; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(dest[0], DST_0); - - vis_ld64(dest[8], DST_2); - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP2, TMP4, REF_2); - - vis_ld64(constants128[0], CONST_128); - - ref += stride; - height = (height >> 1) - 1; - - do { /* 24 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP6, MASK_fe, TMP6); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_xor(DST_2, REF_2, TMP8); - - vis_and(TMP8, MASK_fe, TMP8); - - vis_or(DST_0, REF_0, TMP10); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP8, TMP8); - - vis_or(DST_2, REF_2, TMP12); - vis_ld64_2(dest, stride_8, DST_2); - - vis_ld64(ref[0], TMP14); - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - - dest += stride; - vis_ld64_2(ref, 8, TMP16); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 16, TMP18); - vis_faligndata(TMP2, TMP4, REF_2); - ref += stride; - - vis_xor(DST_0, REF_0, TMP20); - - vis_and(TMP20, MASK_fe, TMP20); - - vis_xor(DST_2, REF_2, TMP22); - vis_mul8x16(CONST_128, TMP20, TMP20); - - vis_and(TMP22, MASK_fe, TMP22); - - vis_or(DST_0, REF_0, TMP24); - vis_mul8x16(CONST_128, TMP22, TMP22); - - vis_or(DST_2, REF_2, TMP26); - - vis_ld64_2(dest, stride, DST_0); - vis_faligndata(TMP14, TMP16, REF_0); - - vis_ld64_2(dest, stride_8, DST_2); - vis_faligndata(TMP16, TMP18, REF_2); - - vis_and(TMP20, MASK_7f, TMP20); - - vis_and(TMP22, MASK_7f, TMP22); - - vis_psub16(TMP24, TMP20, TMP20); - vis_st64(TMP20, dest[0]); - - vis_psub16(TMP26, TMP22, TMP22); - vis_st64_2(TMP22, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP6, MASK_fe, TMP6); - - vis_ld64_2(ref, 16, TMP4); - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_xor(DST_2, REF_2, TMP8); - - vis_and(TMP8, MASK_fe, TMP8); - - vis_or(DST_0, REF_0, TMP10); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP8, TMP8); - - vis_or(DST_2, REF_2, TMP12); - vis_ld64_2(dest, stride_8, DST_2); - - vis_ld64(ref[0], TMP14); - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - - dest += stride; - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_2); - - vis_xor(DST_0, REF_0, TMP20); - - vis_and(TMP20, MASK_fe, TMP20); - - vis_xor(DST_2, REF_2, TMP22); - vis_mul8x16(CONST_128, TMP20, TMP20); - - vis_and(TMP22, MASK_fe, TMP22); - - vis_or(DST_0, REF_0, TMP24); - vis_mul8x16(CONST_128, TMP22, TMP22); - - vis_or(DST_2, REF_2, TMP26); - - vis_and(TMP20, MASK_7f, TMP20); - - vis_and(TMP22, MASK_7f, TMP22); - - vis_psub16(TMP24, TMP20, TMP20); - vis_st64(TMP20, dest[0]); - - vis_psub16(TMP26, TMP22, TMP22); - vis_st64_2(TMP22, dest, 8); -} - -static void MC_avg_o_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64(dest[0], DST_0); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants128[0], CONST_128); - - ref += stride; - height = (height >> 1) - 1; - - do { /* 12 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP4); - - vis_ld64(ref[8], TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - ref += stride; - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_ld64(ref[0], TMP12); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(ref[8], TMP2); - vis_xor(DST_0, REF_0, TMP0); - ref += stride; - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_or(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - - vis_faligndata(TMP12, TMP2, REF_0); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_psub16(TMP6, TMP0, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP4); - - vis_ld64(ref[8], TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_xor(DST_0, REF_0, TMP0); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_or(DST_0, REF_0, TMP6); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_psub16(TMP6, TMP0, TMP4); - vis_st64(TMP4, dest[0]); -} - -static void MC_put_x_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, 16, TMP4); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants128[0], CONST_128); - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - ref += stride; - height = (height >> 1) - 1; - - do { /* 34 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP8); - - vis_ld64_2(ref, 16, TMP4); - vis_and(TMP6, MASK_fe, TMP6); - ref += stride; - - vis_ld64(ref[0], TMP14); - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_ld64_2(ref, 8, TMP16); - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_ld64_2(ref, 16, TMP18); - ref += stride; - vis_or(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - - vis_xor(REF_0, REF_2, TMP6); - - vis_xor(REF_4, REF_6, TMP8); - - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_or(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP14, TMP16, REF_0); - - vis_faligndata(TMP16, TMP18, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP14, TMP16, REF_2); - vis_faligndata(TMP16, TMP18, REF_6); - } else { - vis_src1(TMP16, REF_2); - vis_src1(TMP18, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP8); - - vis_ld64_2(ref, 16, TMP4); - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_or(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - - vis_xor(REF_0, REF_2, TMP6); - - vis_xor(REF_4, REF_6, TMP8); - - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_or(REF_0, REF_2, TMP10); - - vis_or(REF_4, REF_6, TMP12); - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_psub16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_psub16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); -} - -static void MC_put_x_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - - vis_ld64(constants128[0], CONST_128); - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - ref += stride; - height = (height >> 1) - 1; - - do { /* 20 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - ref += stride; - - vis_ld64(ref[0], TMP8); - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, 8, TMP10); - ref += stride; - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_or(REF_0, REF_2, TMP14); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_alignaddr_g0((void *)off); - vis_faligndata(TMP8, TMP10, REF_0); - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP8, TMP10, REF_2); - } else { - vis_src1(TMP10, REF_2); - } - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - vis_and(TMP4, MASK_7f, TMP4); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_or(REF_0, REF_2, TMP14); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; -} - -static void MC_avg_x_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - vis_ld64(constants3[0], CONST_3); - vis_fzero(ZERO); - vis_ld64(constants256_512[0], CONST_256); - - ref = vis_alignaddr(ref); - do { /* 26 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_alignaddr_g0((void *)off); - - vis_ld64(ref[16], TMP4); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(dest[8], DST_2); - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_mul8x16au(REF_0, CONST_256, TMP0); - - vis_pmerge(ZERO, REF_2, TMP4); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_mul8x16al(DST_0, CONST_512, TMP4); - vis_padd16(TMP2, TMP6, TMP2); - - vis_mul8x16al(DST_1, CONST_512, TMP6); - - vis_mul8x16au(REF_6, CONST_256, TMP12); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_6_1, CONST_256, TMP14); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4, CONST_256, TMP16); - - vis_padd16(TMP0, CONST_3, TMP8); - vis_mul8x16au(REF_4_1, CONST_256, TMP18); - - vis_padd16(TMP2, CONST_3, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_padd16(TMP16, TMP12, TMP0); - - vis_st64(DST_0, dest[0]); - vis_mul8x16al(DST_2, CONST_512, TMP4); - vis_padd16(TMP18, TMP14, TMP2); - - vis_mul8x16al(DST_3, CONST_512, TMP6); - vis_padd16(TMP0, CONST_3, TMP0); - - vis_padd16(TMP2, CONST_3, TMP2); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_padd16(TMP2, TMP6, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64(DST_2, dest[8]); - - ref += stride; - dest += stride; - } while (--height); -} - -static void MC_avg_x_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_times_2 = stride << 1; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - vis_ld64(constants3[0], CONST_3); - vis_fzero(ZERO); - vis_ld64(constants256_512[0], CONST_256); - - ref = vis_alignaddr(ref); - height >>= 2; - do { /* 47 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - - vis_alignaddr_g0((void *)off); - - vis_ld64(ref[0], TMP4); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 8, TMP6); - ref += stride; - - vis_ld64(ref[0], TMP8); - - vis_ld64_2(ref, 8, TMP10); - ref += stride; - vis_faligndata(TMP4, TMP6, REF_4); - - vis_ld64(ref[0], TMP12); - - vis_ld64_2(ref, 8, TMP14); - ref += stride; - vis_faligndata(TMP8, TMP10, REF_S0); - - vis_faligndata(TMP12, TMP14, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64_2(dest, stride, DST_2); - vis_faligndata(TMP4, TMP6, REF_6); - - vis_faligndata(TMP8, TMP10, REF_S2); - - vis_faligndata(TMP12, TMP14, REF_S6); - } else { - vis_ld64(dest[0], DST_0); - vis_src1(TMP2, REF_2); - - vis_ld64_2(dest, stride, DST_2); - vis_src1(TMP6, REF_6); - - vis_src1(TMP10, REF_S2); - - vis_src1(TMP14, REF_S6); - } - - vis_pmerge(ZERO, REF_0, TMP0); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_pmerge(ZERO, REF_2, TMP4); - vis_mul8x16au(REF_2_1, CONST_256, TMP6); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16al(DST_0, CONST_512, TMP16); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16al(DST_1, CONST_512, TMP18); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_4, CONST_256, TMP8); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4_1, CONST_256, TMP10); - - vis_padd16(TMP0, TMP16, TMP0); - vis_mul8x16au(REF_6, CONST_256, TMP12); - - vis_padd16(TMP2, TMP18, TMP2); - vis_mul8x16au(REF_6_1, CONST_256, TMP14); - - vis_padd16(TMP8, CONST_3, TMP8); - vis_mul8x16al(DST_2, CONST_512, TMP16); - - vis_padd16(TMP8, TMP12, TMP8); - vis_mul8x16al(DST_3, CONST_512, TMP18); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP0, DST_0); - - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP10, CONST_3, TMP10); - - vis_ld64_2(dest, stride, DST_0); - vis_padd16(TMP8, TMP16, TMP8); - - vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/); - vis_padd16(TMP10, TMP18, TMP10); - vis_pack16(TMP8, DST_2); - - vis_pack16(TMP10, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - - vis_mul8x16au(REF_S0_1, CONST_256, TMP2); - vis_pmerge(ZERO, REF_S0, TMP0); - - vis_pmerge(ZERO, REF_S2, TMP24); - vis_mul8x16au(REF_S2_1, CONST_256, TMP6); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16au(REF_S4, CONST_256, TMP8); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16au(REF_S4_1, CONST_256, TMP10); - - vis_padd16(TMP0, TMP24, TMP0); - vis_mul8x16au(REF_S6, CONST_256, TMP12); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_S6_1, CONST_256, TMP14); - - vis_padd16(TMP8, CONST_3, TMP8); - vis_mul8x16al(DST_0, CONST_512, TMP16); - - vis_padd16(TMP10, CONST_3, TMP10); - vis_mul8x16al(DST_1, CONST_512, TMP18); - - vis_padd16(TMP8, TMP12, TMP8); - vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20); - - vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22); - vis_padd16(TMP0, TMP16, TMP0); - - vis_padd16(TMP2, TMP18, TMP2); - vis_pack16(TMP0, DST_0); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_padd16(TMP8, TMP20, TMP8); - - vis_padd16(TMP10, TMP22, TMP10); - vis_pack16(TMP8, DST_2); - - vis_pack16(TMP10, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_put_y_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - - vis_ld64(ref[0], TMP6); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 8, TMP8); - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64_2(ref, 16, TMP10); - ref += stride; - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP6, TMP8, REF_2); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP8, TMP10, REF_6); - - vis_ld64(constants128[0], CONST_128); - height = (height >> 1) - 1; - do { /* 24 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP12); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP16); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - vis_or(REF_0, REF_2, TMP14); - - vis_ld64(ref[0], TMP6); - vis_or(REF_4, REF_6, TMP18); - - vis_ld64_2(ref, 8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(TMP16, MASK_fe, TMP16); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_mul8x16(CONST_128, TMP16, TMP16); - vis_xor(REF_0, REF_2, TMP0); - - vis_xor(REF_4, REF_6, TMP2); - - vis_or(REF_0, REF_2, TMP20); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_and(TMP16, MASK_7f, TMP16); - - vis_psub16(TMP14, TMP12, TMP12); - vis_st64(TMP12, dest[0]); - - vis_psub16(TMP18, TMP16, TMP16); - vis_st64_2(TMP16, dest, 8); - dest += stride; - - vis_or(REF_4, REF_6, TMP18); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP2, MASK_fe, TMP2); - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_faligndata(TMP6, TMP8, REF_2); - vis_mul8x16(CONST_128, TMP2, TMP2); - - vis_faligndata(TMP8, TMP10, REF_6); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_and(TMP2, MASK_7f, TMP2); - - vis_psub16(TMP20, TMP0, TMP0); - vis_st64(TMP0, dest[0]); - - vis_psub16(TMP18, TMP2, TMP2); - vis_st64_2(TMP2, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP12); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP16); - - vis_ld64_2(ref, 16, TMP4); - vis_or(REF_0, REF_2, TMP14); - - vis_or(REF_4, REF_6, TMP18); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(TMP16, MASK_fe, TMP16); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_mul8x16(CONST_128, TMP16, TMP16); - vis_xor(REF_0, REF_2, TMP0); - - vis_xor(REF_4, REF_6, TMP2); - - vis_or(REF_0, REF_2, TMP20); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_and(TMP16, MASK_7f, TMP16); - - vis_psub16(TMP14, TMP12, TMP12); - vis_st64(TMP12, dest[0]); - - vis_psub16(TMP18, TMP16, TMP16); - vis_st64_2(TMP16, dest, 8); - dest += stride; - - vis_or(REF_4, REF_6, TMP18); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP2, MASK_fe, TMP2); - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_mul8x16(CONST_128, TMP2, TMP2); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_and(TMP2, MASK_7f, TMP2); - - vis_psub16(TMP20, TMP0, TMP0); - vis_st64(TMP0, dest[0]); - - vis_psub16(TMP18, TMP2, TMP2); - vis_st64_2(TMP2, dest, 8); -} - -static void MC_put_y_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - - vis_ld64(ref[0], TMP4); - - vis_ld64_2(ref, 8, TMP6); - ref += stride; - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP4, TMP6, REF_2); - - vis_ld64(constants128[0], CONST_128); - height = (height >> 1) - 1; - do { /* 12 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_mul8x16(CONST_128, TMP12, TMP12); - vis_or(REF_0, REF_2, TMP14); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_faligndata(TMP0, TMP2, REF_2); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_or(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_mul8x16(CONST_128, TMP12, TMP12); - vis_or(REF_0, REF_2, TMP14); - - vis_psub16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_and(TMP12, MASK_7f, TMP12); - - vis_psub16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); -} - -static void MC_avg_y_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants3[0], CONST_3); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_6); - height >>= 1; - - do { /* 31 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_pmerge(ZERO, REF_2, TMP12); - vis_mul8x16au(REF_2_1, CONST_256, TMP14); - - vis_ld64_2(ref, stride_8, TMP2); - vis_pmerge(ZERO, REF_6, TMP16); - vis_mul8x16au(REF_6_1, CONST_256, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(dest, 8, DST_2); - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64_2(ref, stride, TMP6); - vis_pmerge(ZERO, REF_0, TMP0); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_ld64_2(ref, stride_8, TMP8); - vis_pmerge(ZERO, REF_4, TMP4); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - - vis_ld64_2(dest, stride, REF_S0/*DST_4*/); - vis_faligndata(TMP6, TMP8, REF_2); - vis_mul8x16au(REF_4_1, CONST_256, TMP6); - - vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/); - vis_faligndata(TMP8, TMP10, REF_6); - vis_mul8x16al(DST_0, CONST_512, TMP20); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16al(DST_1, CONST_512, TMP22); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16al(DST_2, CONST_512, TMP24); - - vis_padd16(TMP4, CONST_3, TMP4); - vis_mul8x16al(DST_3, CONST_512, TMP26); - - vis_padd16(TMP6, CONST_3, TMP6); - - vis_padd16(TMP12, TMP20, TMP12); - vis_mul8x16al(REF_S0, CONST_512, TMP20); - - vis_padd16(TMP14, TMP22, TMP14); - vis_mul8x16al(REF_S0_1, CONST_512, TMP22); - - vis_padd16(TMP16, TMP24, TMP16); - vis_mul8x16al(REF_S2, CONST_512, TMP24); - - vis_padd16(TMP18, TMP26, TMP18); - vis_mul8x16al(REF_S2_1, CONST_512, TMP26); - - vis_padd16(TMP12, TMP0, TMP12); - vis_mul8x16au(REF_2, CONST_256, TMP28); - - vis_padd16(TMP14, TMP2, TMP14); - vis_mul8x16au(REF_2_1, CONST_256, TMP30); - - vis_padd16(TMP16, TMP4, TMP16); - vis_mul8x16au(REF_6, CONST_256, REF_S4); - - vis_padd16(TMP18, TMP6, TMP18); - vis_mul8x16au(REF_6_1, CONST_256, REF_S6); - - vis_pack16(TMP12, DST_0); - vis_padd16(TMP28, TMP0, TMP12); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP30, TMP2, TMP14); - - vis_pack16(TMP16, DST_2); - vis_padd16(REF_S4, TMP4, TMP16); - - vis_pack16(TMP18, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - vis_padd16(REF_S6, TMP6, TMP18); - - vis_padd16(TMP12, TMP20, TMP12); - - vis_padd16(TMP14, TMP22, TMP14); - vis_pack16(TMP12, DST_0); - - vis_padd16(TMP16, TMP24, TMP16); - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - - vis_padd16(TMP18, TMP26, TMP18); - vis_pack16(TMP16, DST_2); - - vis_pack16(TMP18, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_avg_y_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - int stride_8 = stride + 8; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(constants3[0], CONST_3); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64(constants256_512[0], CONST_256); - - height >>= 1; - do { /* 20 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_pmerge(ZERO, REF_2, TMP8); - vis_mul8x16au(REF_2_1, CONST_256, TMP10); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - - vis_ld64(dest[0], DST_0); - - vis_ld64_2(dest, stride, DST_2); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride, TMP4); - vis_mul8x16al(DST_0, CONST_512, TMP16); - vis_pmerge(ZERO, REF_0, TMP12); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - vis_mul8x16al(DST_1, CONST_512, TMP18); - vis_pmerge(ZERO, REF_0_1, TMP14); - - vis_padd16(TMP12, CONST_3, TMP12); - vis_mul8x16al(DST_2, CONST_512, TMP24); - - vis_padd16(TMP14, CONST_3, TMP14); - vis_mul8x16al(DST_3, CONST_512, TMP26); - - vis_faligndata(TMP4, TMP6, REF_2); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - vis_mul8x16au(REF_2, CONST_256, TMP20); - - vis_padd16(TMP8, TMP16, TMP0); - vis_mul8x16au(REF_2_1, CONST_256, TMP22); - - vis_padd16(TMP10, TMP18, TMP2); - vis_pack16(TMP0, DST_0); - - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP12, TMP20, TMP12); - - vis_padd16(TMP14, TMP22, TMP14); - - vis_padd16(TMP12, TMP24, TMP0); - - vis_padd16(TMP14, TMP26, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_put_xy_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants2[0], CONST_2); - vis_faligndata(TMP0, TMP2, REF_S0); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - vis_faligndata(TMP2, TMP4, REF_S6); - } else { - vis_src1(TMP2, REF_S2); - vis_src1(TMP4, REF_S6); - } - - height >>= 1; - do { - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S0_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - vis_mul8x16au(REF_S2, CONST_256, TMP16); - vis_pmerge(ZERO, REF_S2_1, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - vis_mul8x16au(REF_S4, CONST_256, TMP20); - vis_pmerge(ZERO, REF_S4_1, TMP22); - - vis_ld64_2(ref, stride, TMP6); - vis_mul8x16au(REF_S6, CONST_256, TMP24); - vis_pmerge(ZERO, REF_S6_1, TMP26); - - vis_ld64_2(ref, stride_8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_faligndata(TMP6, TMP8, REF_S0); - - vis_faligndata(TMP8, TMP10, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - vis_faligndata(TMP6, TMP8, REF_S2); - vis_faligndata(TMP8, TMP10, REF_S6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - vis_src1(TMP8, REF_S2); - vis_src1(TMP10, REF_S6); - } - - vis_mul8x16au(REF_0, CONST_256, TMP0); - vis_pmerge(ZERO, REF_0_1, TMP2); - - vis_mul8x16au(REF_2, CONST_256, TMP4); - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_padd16(TMP0, CONST_2, TMP8); - vis_mul8x16au(REF_4, CONST_256, TMP0); - - vis_padd16(TMP2, CONST_2, TMP10); - vis_mul8x16au(REF_4_1, CONST_256, TMP2); - - vis_padd16(TMP8, TMP4, TMP8); - vis_mul8x16au(REF_6, CONST_256, TMP4); - - vis_padd16(TMP10, TMP6, TMP10); - vis_mul8x16au(REF_6_1, CONST_256, TMP6); - - vis_padd16(TMP12, TMP8, TMP12); - - vis_padd16(TMP14, TMP10, TMP14); - - vis_padd16(TMP12, TMP16, TMP12); - - vis_padd16(TMP14, TMP18, TMP14); - vis_pack16(TMP12, DST_0); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP0, CONST_2, TMP12); - - vis_mul8x16au(REF_S0, CONST_256, TMP0); - vis_padd16(TMP2, CONST_2, TMP14); - - vis_mul8x16au(REF_S0_1, CONST_256, TMP2); - vis_padd16(TMP12, TMP4, TMP12); - - vis_mul8x16au(REF_S2, CONST_256, TMP4); - vis_padd16(TMP14, TMP6, TMP14); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP6); - vis_padd16(TMP20, TMP12, TMP20); - - vis_padd16(TMP22, TMP14, TMP22); - - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP22, TMP26, TMP22); - vis_pack16(TMP20, DST_2); - - vis_pack16(TMP22, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - vis_padd16(TMP0, TMP4, TMP24); - - vis_mul8x16au(REF_S4, CONST_256, TMP0); - vis_padd16(TMP2, TMP6, TMP26); - - vis_mul8x16au(REF_S4_1, CONST_256, TMP2); - vis_padd16(TMP24, TMP8, TMP24); - - vis_padd16(TMP26, TMP10, TMP26); - vis_pack16(TMP24, DST_0); - - vis_pack16(TMP26, DST_1); - vis_st64(DST_0, dest[0]); - vis_pmerge(ZERO, REF_S6, TMP4); - - vis_pmerge(ZERO, REF_S6_1, TMP6); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_padd16(TMP2, TMP6, TMP2); - - vis_padd16(TMP0, TMP12, TMP0); - - vis_padd16(TMP2, TMP14, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_put_xy_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(constants2[0], CONST_2); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP0, TMP2, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - } else { - vis_src1(TMP2, REF_S2); - } - - height >>= 1; - do { /* 26 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP8); - vis_pmerge(ZERO, REF_S2, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - vis_mul8x16au(REF_S0_1, CONST_256, TMP10); - vis_pmerge(ZERO, REF_S2_1, TMP14); - - vis_ld64_2(ref, stride, TMP4); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - vis_faligndata(TMP0, TMP2, REF_S4); - - vis_pmerge(ZERO, REF_S4, TMP18); - - vis_pmerge(ZERO, REF_S4_1, TMP20); - - vis_faligndata(TMP4, TMP6, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S6); - vis_faligndata(TMP4, TMP6, REF_S2); - } else { - vis_src1(TMP2, REF_S6); - vis_src1(TMP6, REF_S2); - } - - vis_padd16(TMP18, CONST_2, TMP18); - vis_mul8x16au(REF_S6, CONST_256, TMP22); - - vis_padd16(TMP20, CONST_2, TMP20); - vis_mul8x16au(REF_S6_1, CONST_256, TMP24); - - vis_mul8x16au(REF_S0, CONST_256, TMP26); - vis_pmerge(ZERO, REF_S0_1, TMP28); - - vis_mul8x16au(REF_S2, CONST_256, TMP30); - vis_padd16(TMP18, TMP22, TMP18); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP32); - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP8, TMP18, TMP8); - - vis_padd16(TMP10, TMP20, TMP10); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP18, TMP26, TMP18); - - vis_padd16(TMP20, TMP28, TMP20); - - vis_padd16(TMP18, TMP30, TMP18); - - vis_padd16(TMP20, TMP32, TMP20); - vis_pack16(TMP18, DST_2); - - vis_pack16(TMP20, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_avg_xy_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants6[0], CONST_6); - vis_faligndata(TMP0, TMP2, REF_S0); - - vis_ld64(constants256_1024[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - vis_faligndata(TMP2, TMP4, REF_S6); - } else { - vis_src1(TMP2, REF_S2); - vis_src1(TMP4, REF_S6); - } - - height >>= 1; - do { /* 55 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S0_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - vis_mul8x16au(REF_S2, CONST_256, TMP16); - vis_pmerge(ZERO, REF_S2_1, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - vis_mul8x16au(REF_S4, CONST_256, TMP20); - vis_pmerge(ZERO, REF_S4_1, TMP22); - - vis_ld64_2(ref, stride, TMP6); - vis_mul8x16au(REF_S6, CONST_256, TMP24); - vis_pmerge(ZERO, REF_S6_1, TMP26); - - vis_ld64_2(ref, stride_8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP6, TMP8, REF_S0); - - vis_ld64_2(dest, 8, DST_2); - vis_faligndata(TMP8, TMP10, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - vis_faligndata(TMP6, TMP8, REF_S2); - vis_faligndata(TMP8, TMP10, REF_S6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - vis_src1(TMP8, REF_S2); - vis_src1(TMP10, REF_S6); - } - - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_0, TMP0); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_pmerge(ZERO, REF_0_1, TMP2); - - vis_mul8x16au(REF_2, CONST_256, TMP4); - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_mul8x16al(DST_2, CONST_1024, REF_0); - vis_padd16(TMP0, CONST_6, TMP0); - - vis_mul8x16al(DST_3, CONST_1024, REF_2); - vis_padd16(TMP2, CONST_6, TMP2); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_4, CONST_256, TMP4); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4_1, CONST_256, TMP6); - - vis_padd16(TMP12, TMP0, TMP12); - vis_mul8x16au(REF_6, CONST_256, TMP8); - - vis_padd16(TMP14, TMP2, TMP14); - vis_mul8x16au(REF_6_1, CONST_256, TMP10); - - vis_padd16(TMP12, TMP16, TMP12); - vis_mul8x16au(REF_S0, CONST_256, REF_4); - - vis_padd16(TMP14, TMP18, TMP14); - vis_mul8x16au(REF_S0_1, CONST_256, REF_6); - - vis_padd16(TMP12, TMP30, TMP12); - - vis_padd16(TMP14, TMP32, TMP14); - vis_pack16(TMP12, DST_0); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP4, CONST_6, TMP4); - - vis_ld64_2(dest, stride, DST_0); - vis_padd16(TMP6, CONST_6, TMP6); - vis_mul8x16au(REF_S2, CONST_256, TMP12); - - vis_padd16(TMP4, TMP8, TMP4); - vis_mul8x16au(REF_S2_1, CONST_256, TMP14); - - vis_padd16(TMP6, TMP10, TMP6); - - vis_padd16(TMP20, TMP4, TMP20); - - vis_padd16(TMP22, TMP6, TMP22); - - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP22, TMP26, TMP22); - - vis_padd16(TMP20, REF_0, TMP20); - vis_mul8x16au(REF_S4, CONST_256, REF_0); - - vis_padd16(TMP22, REF_2, TMP22); - vis_pack16(TMP20, DST_2); - - vis_pack16(TMP22, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - - vis_ld64_2(dest, 8, DST_2); - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_S4_1, REF_2); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_padd16(REF_4, TMP0, TMP8); - - vis_mul8x16au(REF_S6, CONST_256, REF_4); - vis_padd16(REF_6, TMP2, TMP10); - - vis_mul8x16au(REF_S6_1, CONST_256, REF_6); - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - - vis_padd16(TMP8, TMP30, TMP8); - - vis_padd16(TMP10, TMP32, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - - vis_padd16(REF_0, TMP4, REF_0); - - vis_mul8x16al(DST_2, CONST_1024, TMP30); - vis_padd16(REF_2, TMP6, REF_2); - - vis_mul8x16al(DST_3, CONST_1024, TMP32); - vis_padd16(REF_0, REF_4, REF_0); - - vis_padd16(REF_2, REF_6, REF_2); - - vis_padd16(REF_0, TMP30, REF_0); - - /* stall */ - - vis_padd16(REF_2, TMP32, REF_2); - vis_pack16(REF_0, DST_2); - - vis_pack16(REF_2, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - - vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - vis_fzero(ZERO); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64(constants6[0], CONST_6); - - vis_ld64(constants256_1024[0], CONST_256); - vis_faligndata(TMP0, TMP2, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - } else { - vis_src1(TMP2, REF_S2); - } - - height >>= 1; - do { /* 31 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP8); - vis_pmerge(ZERO, REF_S0_1, TMP10); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - vis_mul8x16au(REF_S2, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S2_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride, TMP4); - vis_faligndata(TMP0, TMP2, REF_S4); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP4, TMP6, REF_S0); - - vis_ld64_2(dest, stride, DST_2); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S6); - vis_faligndata(TMP4, TMP6, REF_S2); - } else { - vis_src1(TMP2, REF_S6); - vis_src1(TMP6, REF_S2); - } - - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_S4, TMP22); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_pmerge(ZERO, REF_S4_1, TMP24); - - vis_mul8x16au(REF_S6, CONST_256, TMP26); - vis_pmerge(ZERO, REF_S6_1, TMP28); - - vis_mul8x16au(REF_S0, CONST_256, REF_S4); - vis_padd16(TMP22, CONST_6, TMP22); - - vis_mul8x16au(REF_S0_1, CONST_256, REF_S6); - vis_padd16(TMP24, CONST_6, TMP24); - - vis_mul8x16al(DST_2, CONST_1024, REF_0); - vis_padd16(TMP22, TMP26, TMP22); - - vis_mul8x16al(DST_3, CONST_1024, REF_2); - vis_padd16(TMP24, TMP28, TMP24); - - vis_mul8x16au(REF_S2, CONST_256, TMP26); - vis_padd16(TMP8, TMP22, TMP8); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP28); - vis_padd16(TMP10, TMP24, TMP10); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - - vis_padd16(TMP8, TMP30, TMP8); - - vis_padd16(TMP10, TMP32, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_padd16(REF_S4, TMP22, TMP12); - - vis_padd16(REF_S6, TMP24, TMP14); - - vis_padd16(TMP12, TMP26, TMP12); - - vis_padd16(TMP14, TMP28, TMP14); - - vis_padd16(TMP12, REF_0, TMP12); - - vis_padd16(TMP14, REF_2, TMP14); - vis_pack16(TMP12, DST_2); - - vis_pack16(TMP14, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -/* End of rounding code */ - -/* Start of no rounding code */ -/* The trick used in some of this file is the formula from the MMX - * motion comp code, which is: - * - * (x+y)>>1 == (x&y)+((x^y)>>1) - * - * This allows us to average 8 bytes at a time in a 64-bit FPU reg. - * We avoid overflows by masking before we do the shift, and we - * implement the shift by multiplying by 1/2 using mul8x16. So in - * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask - * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and - * the value 0x80808080 is in f8): - * - * fxor f0, f2, f10 - * fand f10, f4, f10 - * fmul8x16 f8, f10, f10 - * fand f10, f6, f10 - * fand f0, f2, f12 - * fpadd16 f12, f10, f10 - */ - -static void MC_put_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - do { /* 5 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - - vis_faligndata(TMP0, TMP2, REF_0); - vis_st64(REF_0, dest[0]); - - vis_faligndata(TMP2, TMP4, REF_2); - vis_st64_2(REF_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_put_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - do { /* 4 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - ref += stride; - - /* stall */ - - vis_faligndata(TMP0, TMP2, REF_0); - vis_st64(REF_0, dest[0]); - dest += stride; - } while (--height); -} - - -static void MC_avg_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - int stride_8 = stride + 8; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(dest[0], DST_0); - - vis_ld64(dest[8], DST_2); - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP2, TMP4, REF_2); - - vis_ld64(constants128[0], CONST_128); - - ref += stride; - height = (height >> 1) - 1; - - do { /* 24 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP6, MASK_fe, TMP6); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_xor(DST_2, REF_2, TMP8); - - vis_and(TMP8, MASK_fe, TMP8); - - vis_and(DST_0, REF_0, TMP10); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP8, TMP8); - - vis_and(DST_2, REF_2, TMP12); - vis_ld64_2(dest, stride_8, DST_2); - - vis_ld64(ref[0], TMP14); - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_padd16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_padd16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - - dest += stride; - vis_ld64_2(ref, 8, TMP16); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 16, TMP18); - vis_faligndata(TMP2, TMP4, REF_2); - ref += stride; - - vis_xor(DST_0, REF_0, TMP20); - - vis_and(TMP20, MASK_fe, TMP20); - - vis_xor(DST_2, REF_2, TMP22); - vis_mul8x16(CONST_128, TMP20, TMP20); - - vis_and(TMP22, MASK_fe, TMP22); - - vis_and(DST_0, REF_0, TMP24); - vis_mul8x16(CONST_128, TMP22, TMP22); - - vis_and(DST_2, REF_2, TMP26); - - vis_ld64_2(dest, stride, DST_0); - vis_faligndata(TMP14, TMP16, REF_0); - - vis_ld64_2(dest, stride_8, DST_2); - vis_faligndata(TMP16, TMP18, REF_2); - - vis_and(TMP20, MASK_7f, TMP20); - - vis_and(TMP22, MASK_7f, TMP22); - - vis_padd16(TMP24, TMP20, TMP20); - vis_st64(TMP20, dest[0]); - - vis_padd16(TMP26, TMP22, TMP22); - vis_st64_2(TMP22, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP6, MASK_fe, TMP6); - - vis_ld64_2(ref, 16, TMP4); - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_xor(DST_2, REF_2, TMP8); - - vis_and(TMP8, MASK_fe, TMP8); - - vis_and(DST_0, REF_0, TMP10); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP8, TMP8); - - vis_and(DST_2, REF_2, TMP12); - vis_ld64_2(dest, stride_8, DST_2); - - vis_ld64(ref[0], TMP14); - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_padd16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_padd16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - - dest += stride; - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_2); - - vis_xor(DST_0, REF_0, TMP20); - - vis_and(TMP20, MASK_fe, TMP20); - - vis_xor(DST_2, REF_2, TMP22); - vis_mul8x16(CONST_128, TMP20, TMP20); - - vis_and(TMP22, MASK_fe, TMP22); - - vis_and(DST_0, REF_0, TMP24); - vis_mul8x16(CONST_128, TMP22, TMP22); - - vis_and(DST_2, REF_2, TMP26); - - vis_and(TMP20, MASK_7f, TMP20); - - vis_and(TMP22, MASK_7f, TMP22); - - vis_padd16(TMP24, TMP20, TMP20); - vis_st64(TMP20, dest[0]); - - vis_padd16(TMP26, TMP22, TMP22); - vis_st64_2(TMP22, dest, 8); -} - -static void MC_avg_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64(dest[0], DST_0); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants128[0], CONST_128); - - ref += stride; - height = (height >> 1) - 1; - - do { /* 12 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP4); - - vis_ld64(ref[8], TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_and(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - ref += stride; - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_ld64(ref[0], TMP12); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(ref[8], TMP2); - vis_xor(DST_0, REF_0, TMP0); - ref += stride; - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_padd16(TMP6, TMP4, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_and(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - - vis_faligndata(TMP12, TMP2, REF_0); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_padd16(TMP6, TMP0, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(DST_0, REF_0, TMP4); - - vis_ld64(ref[8], TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_and(DST_0, REF_0, TMP6); - vis_ld64_2(dest, stride, DST_0); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_xor(DST_0, REF_0, TMP0); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_padd16(TMP6, TMP4, TMP4); - vis_st64(TMP4, dest[0]); - dest += stride; - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_and(DST_0, REF_0, TMP6); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_padd16(TMP6, TMP0, TMP4); - vis_st64(TMP4, dest[0]); -} - -static void MC_put_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, 16, TMP4); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants128[0], CONST_128); - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - ref += stride; - height = (height >> 1) - 1; - - do { /* 34 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP8); - - vis_ld64_2(ref, 16, TMP4); - vis_and(TMP6, MASK_fe, TMP6); - ref += stride; - - vis_ld64(ref[0], TMP14); - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_ld64_2(ref, 8, TMP16); - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_and(REF_0, REF_2, TMP10); - - vis_ld64_2(ref, 16, TMP18); - ref += stride; - vis_and(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_padd16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_padd16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - - vis_xor(REF_0, REF_2, TMP6); - - vis_xor(REF_4, REF_6, TMP8); - - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_and(REF_0, REF_2, TMP10); - - vis_and(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP14, TMP16, REF_0); - - vis_faligndata(TMP16, TMP18, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP14, TMP16, REF_2); - vis_faligndata(TMP16, TMP18, REF_6); - } else { - vis_src1(TMP16, REF_2); - vis_src1(TMP18, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_padd16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_padd16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP6); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP8); - - vis_ld64_2(ref, 16, TMP4); - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_and(REF_0, REF_2, TMP10); - - vis_and(REF_4, REF_6, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_padd16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_padd16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); - dest += stride; - - vis_xor(REF_0, REF_2, TMP6); - - vis_xor(REF_4, REF_6, TMP8); - - vis_and(TMP6, MASK_fe, TMP6); - - vis_mul8x16(CONST_128, TMP6, TMP6); - vis_and(TMP8, MASK_fe, TMP8); - - vis_mul8x16(CONST_128, TMP8, TMP8); - vis_and(REF_0, REF_2, TMP10); - - vis_and(REF_4, REF_6, TMP12); - - vis_and(TMP6, MASK_7f, TMP6); - - vis_and(TMP8, MASK_7f, TMP8); - - vis_padd16(TMP10, TMP6, TMP6); - vis_st64(TMP6, dest[0]); - - vis_padd16(TMP12, TMP8, TMP8); - vis_st64_2(TMP8, dest, 8); -} - -static void MC_put_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_ld64(constants_fe[0], MASK_fe); - - vis_ld64(constants_7f[0], MASK_7f); - - vis_ld64(constants128[0], CONST_128); - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - ref += stride; - height = (height >> 1) - 1; - - do { /* 20 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - ref += stride; - - vis_ld64(ref[0], TMP8); - vis_and(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, 8, TMP10); - ref += stride; - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - vis_and(TMP4, MASK_7f, TMP4); - - vis_padd16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(REF_0, REF_2, TMP14); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_alignaddr_g0((void *)off); - vis_faligndata(TMP8, TMP10, REF_0); - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP8, TMP10, REF_2); - } else { - vis_src1(TMP10, REF_2); - } - - vis_and(TMP12, MASK_7f, TMP12); - - vis_padd16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_and(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_alignaddr_g0((void *)off); - - vis_faligndata(TMP0, TMP2, REF_0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - } else { - vis_src1(TMP2, REF_2); - } - - vis_and(TMP4, MASK_7f, TMP4); - - vis_padd16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(REF_0, REF_2, TMP14); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_padd16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; -} - -static void MC_avg_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - vis_ld64(constants3[0], CONST_3); - vis_fzero(ZERO); - vis_ld64(constants256_512[0], CONST_256); - - ref = vis_alignaddr(ref); - do { /* 26 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64(ref[8], TMP2); - - vis_alignaddr_g0((void *)off); - - vis_ld64(ref[16], TMP4); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(dest[8], DST_2); - vis_faligndata(TMP2, TMP4, REF_4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - } - - vis_mul8x16au(REF_0, CONST_256, TMP0); - - vis_pmerge(ZERO, REF_2, TMP4); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_mul8x16al(DST_0, CONST_512, TMP4); - vis_padd16(TMP2, TMP6, TMP2); - - vis_mul8x16al(DST_1, CONST_512, TMP6); - - vis_mul8x16au(REF_6, CONST_256, TMP12); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_6_1, CONST_256, TMP14); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4, CONST_256, TMP16); - - vis_padd16(TMP0, CONST_3, TMP8); - vis_mul8x16au(REF_4_1, CONST_256, TMP18); - - vis_padd16(TMP2, CONST_3, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_padd16(TMP16, TMP12, TMP0); - - vis_st64(DST_0, dest[0]); - vis_mul8x16al(DST_2, CONST_512, TMP4); - vis_padd16(TMP18, TMP14, TMP2); - - vis_mul8x16al(DST_3, CONST_512, TMP6); - vis_padd16(TMP0, CONST_3, TMP0); - - vis_padd16(TMP2, CONST_3, TMP2); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_padd16(TMP2, TMP6, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64(DST_2, dest[8]); - - ref += stride; - dest += stride; - } while (--height); -} - -static void MC_avg_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_times_2 = stride << 1; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - vis_ld64(constants3[0], CONST_3); - vis_fzero(ZERO); - vis_ld64(constants256_512[0], CONST_256); - - ref = vis_alignaddr(ref); - height >>= 2; - do { /* 47 cycles */ - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - - vis_alignaddr_g0((void *)off); - - vis_ld64(ref[0], TMP4); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 8, TMP6); - ref += stride; - - vis_ld64(ref[0], TMP8); - - vis_ld64_2(ref, 8, TMP10); - ref += stride; - vis_faligndata(TMP4, TMP6, REF_4); - - vis_ld64(ref[0], TMP12); - - vis_ld64_2(ref, 8, TMP14); - ref += stride; - vis_faligndata(TMP8, TMP10, REF_S0); - - vis_faligndata(TMP12, TMP14, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64_2(dest, stride, DST_2); - vis_faligndata(TMP4, TMP6, REF_6); - - vis_faligndata(TMP8, TMP10, REF_S2); - - vis_faligndata(TMP12, TMP14, REF_S6); - } else { - vis_ld64(dest[0], DST_0); - vis_src1(TMP2, REF_2); - - vis_ld64_2(dest, stride, DST_2); - vis_src1(TMP6, REF_6); - - vis_src1(TMP10, REF_S2); - - vis_src1(TMP14, REF_S6); - } - - vis_pmerge(ZERO, REF_0, TMP0); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_pmerge(ZERO, REF_2, TMP4); - vis_mul8x16au(REF_2_1, CONST_256, TMP6); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16al(DST_0, CONST_512, TMP16); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16al(DST_1, CONST_512, TMP18); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_4, CONST_256, TMP8); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4_1, CONST_256, TMP10); - - vis_padd16(TMP0, TMP16, TMP0); - vis_mul8x16au(REF_6, CONST_256, TMP12); - - vis_padd16(TMP2, TMP18, TMP2); - vis_mul8x16au(REF_6_1, CONST_256, TMP14); - - vis_padd16(TMP8, CONST_3, TMP8); - vis_mul8x16al(DST_2, CONST_512, TMP16); - - vis_padd16(TMP8, TMP12, TMP8); - vis_mul8x16al(DST_3, CONST_512, TMP18); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP0, DST_0); - - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP10, CONST_3, TMP10); - - vis_ld64_2(dest, stride, DST_0); - vis_padd16(TMP8, TMP16, TMP8); - - vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/); - vis_padd16(TMP10, TMP18, TMP10); - vis_pack16(TMP8, DST_2); - - vis_pack16(TMP10, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - - vis_mul8x16au(REF_S0_1, CONST_256, TMP2); - vis_pmerge(ZERO, REF_S0, TMP0); - - vis_pmerge(ZERO, REF_S2, TMP24); - vis_mul8x16au(REF_S2_1, CONST_256, TMP6); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16au(REF_S4, CONST_256, TMP8); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16au(REF_S4_1, CONST_256, TMP10); - - vis_padd16(TMP0, TMP24, TMP0); - vis_mul8x16au(REF_S6, CONST_256, TMP12); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_S6_1, CONST_256, TMP14); - - vis_padd16(TMP8, CONST_3, TMP8); - vis_mul8x16al(DST_0, CONST_512, TMP16); - - vis_padd16(TMP10, CONST_3, TMP10); - vis_mul8x16al(DST_1, CONST_512, TMP18); - - vis_padd16(TMP8, TMP12, TMP8); - vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20); - - vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22); - vis_padd16(TMP0, TMP16, TMP0); - - vis_padd16(TMP2, TMP18, TMP2); - vis_pack16(TMP0, DST_0); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_padd16(TMP8, TMP20, TMP8); - - vis_padd16(TMP10, TMP22, TMP10); - vis_pack16(TMP8, DST_2); - - vis_pack16(TMP10, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_put_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - - vis_ld64(ref[0], TMP6); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 8, TMP8); - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64_2(ref, 16, TMP10); - ref += stride; - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP6, TMP8, REF_2); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP8, TMP10, REF_6); - - vis_ld64(constants128[0], CONST_128); - height = (height >> 1) - 1; - do { /* 24 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP12); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP16); - - vis_ld64_2(ref, 16, TMP4); - ref += stride; - vis_and(REF_0, REF_2, TMP14); - - vis_ld64(ref[0], TMP6); - vis_and(REF_4, REF_6, TMP18); - - vis_ld64_2(ref, 8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, 16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(TMP16, MASK_fe, TMP16); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_mul8x16(CONST_128, TMP16, TMP16); - vis_xor(REF_0, REF_2, TMP0); - - vis_xor(REF_4, REF_6, TMP2); - - vis_and(REF_0, REF_2, TMP20); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_and(TMP16, MASK_7f, TMP16); - - vis_padd16(TMP14, TMP12, TMP12); - vis_st64(TMP12, dest[0]); - - vis_padd16(TMP18, TMP16, TMP16); - vis_st64_2(TMP16, dest, 8); - dest += stride; - - vis_and(REF_4, REF_6, TMP18); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP2, MASK_fe, TMP2); - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_faligndata(TMP6, TMP8, REF_2); - vis_mul8x16(CONST_128, TMP2, TMP2); - - vis_faligndata(TMP8, TMP10, REF_6); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_and(TMP2, MASK_7f, TMP2); - - vis_padd16(TMP20, TMP0, TMP0); - vis_st64(TMP0, dest[0]); - - vis_padd16(TMP18, TMP2, TMP2); - vis_st64_2(TMP2, dest, 8); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP12); - - vis_ld64_2(ref, 8, TMP2); - vis_xor(REF_4, REF_6, TMP16); - - vis_ld64_2(ref, 16, TMP4); - vis_and(REF_0, REF_2, TMP14); - - vis_and(REF_4, REF_6, TMP18); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_faligndata(TMP2, TMP4, REF_4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_and(TMP16, MASK_fe, TMP16); - vis_mul8x16(CONST_128, TMP12, TMP12); - - vis_mul8x16(CONST_128, TMP16, TMP16); - vis_xor(REF_0, REF_2, TMP0); - - vis_xor(REF_4, REF_6, TMP2); - - vis_and(REF_0, REF_2, TMP20); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_and(TMP16, MASK_7f, TMP16); - - vis_padd16(TMP14, TMP12, TMP12); - vis_st64(TMP12, dest[0]); - - vis_padd16(TMP18, TMP16, TMP16); - vis_st64_2(TMP16, dest, 8); - dest += stride; - - vis_and(REF_4, REF_6, TMP18); - - vis_and(TMP0, MASK_fe, TMP0); - - vis_and(TMP2, MASK_fe, TMP2); - vis_mul8x16(CONST_128, TMP0, TMP0); - - vis_mul8x16(CONST_128, TMP2, TMP2); - - vis_and(TMP0, MASK_7f, TMP0); - - vis_and(TMP2, MASK_7f, TMP2); - - vis_padd16(TMP20, TMP0, TMP0); - vis_st64(TMP0, dest[0]); - - vis_padd16(TMP18, TMP2, TMP2); - vis_st64_2(TMP2, dest, 8); -} - -static void MC_put_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - ref = vis_alignaddr(ref); - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - - vis_ld64(ref[0], TMP4); - - vis_ld64_2(ref, 8, TMP6); - ref += stride; - - vis_ld64(constants_fe[0], MASK_fe); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64(constants_7f[0], MASK_7f); - vis_faligndata(TMP4, TMP6, REF_2); - - vis_ld64(constants128[0], CONST_128); - height = (height >> 1) - 1; - do { /* 12 cycles */ - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - vis_and(TMP4, MASK_fe, TMP4); - - vis_and(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - vis_ld64(ref[0], TMP0); - - vis_ld64_2(ref, 8, TMP2); - ref += stride; - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_mul8x16(CONST_128, TMP12, TMP12); - vis_and(REF_0, REF_2, TMP14); - - vis_padd16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_faligndata(TMP0, TMP2, REF_2); - - vis_and(TMP12, MASK_7f, TMP12); - - vis_padd16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - } while (--height); - - vis_ld64(ref[0], TMP0); - vis_xor(REF_0, REF_2, TMP4); - - vis_ld64_2(ref, 8, TMP2); - vis_and(TMP4, MASK_fe, TMP4); - - vis_and(REF_0, REF_2, TMP6); - vis_mul8x16(CONST_128, TMP4, TMP4); - - vis_faligndata(TMP0, TMP2, REF_0); - - vis_xor(REF_0, REF_2, TMP12); - - vis_and(TMP4, MASK_7f, TMP4); - - vis_and(TMP12, MASK_fe, TMP12); - - vis_mul8x16(CONST_128, TMP12, TMP12); - vis_and(REF_0, REF_2, TMP14); - - vis_padd16(TMP6, TMP4, DST_0); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_and(TMP12, MASK_7f, TMP12); - - vis_padd16(TMP14, TMP12, DST_0); - vis_st64(DST_0, dest[0]); -} - -static void MC_avg_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants3[0], CONST_3); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_6); - height >>= 1; - - do { /* 31 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_pmerge(ZERO, REF_2, TMP12); - vis_mul8x16au(REF_2_1, CONST_256, TMP14); - - vis_ld64_2(ref, stride_8, TMP2); - vis_pmerge(ZERO, REF_6, TMP16); - vis_mul8x16au(REF_6_1, CONST_256, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(dest, 8, DST_2); - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64_2(ref, stride, TMP6); - vis_pmerge(ZERO, REF_0, TMP0); - vis_mul8x16au(REF_0_1, CONST_256, TMP2); - - vis_ld64_2(ref, stride_8, TMP8); - vis_pmerge(ZERO, REF_4, TMP4); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - - vis_ld64_2(dest, stride, REF_S0/*DST_4*/); - vis_faligndata(TMP6, TMP8, REF_2); - vis_mul8x16au(REF_4_1, CONST_256, TMP6); - - vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/); - vis_faligndata(TMP8, TMP10, REF_6); - vis_mul8x16al(DST_0, CONST_512, TMP20); - - vis_padd16(TMP0, CONST_3, TMP0); - vis_mul8x16al(DST_1, CONST_512, TMP22); - - vis_padd16(TMP2, CONST_3, TMP2); - vis_mul8x16al(DST_2, CONST_512, TMP24); - - vis_padd16(TMP4, CONST_3, TMP4); - vis_mul8x16al(DST_3, CONST_512, TMP26); - - vis_padd16(TMP6, CONST_3, TMP6); - - vis_padd16(TMP12, TMP20, TMP12); - vis_mul8x16al(REF_S0, CONST_512, TMP20); - - vis_padd16(TMP14, TMP22, TMP14); - vis_mul8x16al(REF_S0_1, CONST_512, TMP22); - - vis_padd16(TMP16, TMP24, TMP16); - vis_mul8x16al(REF_S2, CONST_512, TMP24); - - vis_padd16(TMP18, TMP26, TMP18); - vis_mul8x16al(REF_S2_1, CONST_512, TMP26); - - vis_padd16(TMP12, TMP0, TMP12); - vis_mul8x16au(REF_2, CONST_256, TMP28); - - vis_padd16(TMP14, TMP2, TMP14); - vis_mul8x16au(REF_2_1, CONST_256, TMP30); - - vis_padd16(TMP16, TMP4, TMP16); - vis_mul8x16au(REF_6, CONST_256, REF_S4); - - vis_padd16(TMP18, TMP6, TMP18); - vis_mul8x16au(REF_6_1, CONST_256, REF_S6); - - vis_pack16(TMP12, DST_0); - vis_padd16(TMP28, TMP0, TMP12); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP30, TMP2, TMP14); - - vis_pack16(TMP16, DST_2); - vis_padd16(REF_S4, TMP4, TMP16); - - vis_pack16(TMP18, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - vis_padd16(REF_S6, TMP6, TMP18); - - vis_padd16(TMP12, TMP20, TMP12); - - vis_padd16(TMP14, TMP22, TMP14); - vis_pack16(TMP12, DST_0); - - vis_padd16(TMP16, TMP24, TMP16); - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - - vis_padd16(TMP18, TMP26, TMP18); - vis_pack16(TMP16, DST_2); - - vis_pack16(TMP18, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_avg_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - int stride_8 = stride + 8; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(constants3[0], CONST_3); - vis_faligndata(TMP0, TMP2, REF_2); - - vis_ld64(constants256_512[0], CONST_256); - - height >>= 1; - do { /* 20 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_pmerge(ZERO, REF_2, TMP8); - vis_mul8x16au(REF_2_1, CONST_256, TMP10); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - - vis_ld64(dest[0], DST_0); - - vis_ld64_2(dest, stride, DST_2); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride, TMP4); - vis_mul8x16al(DST_0, CONST_512, TMP16); - vis_pmerge(ZERO, REF_0, TMP12); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - vis_mul8x16al(DST_1, CONST_512, TMP18); - vis_pmerge(ZERO, REF_0_1, TMP14); - - vis_padd16(TMP12, CONST_3, TMP12); - vis_mul8x16al(DST_2, CONST_512, TMP24); - - vis_padd16(TMP14, CONST_3, TMP14); - vis_mul8x16al(DST_3, CONST_512, TMP26); - - vis_faligndata(TMP4, TMP6, REF_2); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - vis_mul8x16au(REF_2, CONST_256, TMP20); - - vis_padd16(TMP8, TMP16, TMP0); - vis_mul8x16au(REF_2_1, CONST_256, TMP22); - - vis_padd16(TMP10, TMP18, TMP2); - vis_pack16(TMP0, DST_0); - - vis_pack16(TMP2, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP12, TMP20, TMP12); - - vis_padd16(TMP14, TMP22, TMP14); - - vis_padd16(TMP12, TMP24, TMP0); - - vis_padd16(TMP14, TMP26, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_put_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants1[0], CONST_1); - vis_faligndata(TMP0, TMP2, REF_S0); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - vis_faligndata(TMP2, TMP4, REF_S6); - } else { - vis_src1(TMP2, REF_S2); - vis_src1(TMP4, REF_S6); - } - - height >>= 1; - do { - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S0_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - vis_mul8x16au(REF_S2, CONST_256, TMP16); - vis_pmerge(ZERO, REF_S2_1, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - vis_mul8x16au(REF_S4, CONST_256, TMP20); - vis_pmerge(ZERO, REF_S4_1, TMP22); - - vis_ld64_2(ref, stride, TMP6); - vis_mul8x16au(REF_S6, CONST_256, TMP24); - vis_pmerge(ZERO, REF_S6_1, TMP26); - - vis_ld64_2(ref, stride_8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_faligndata(TMP6, TMP8, REF_S0); - - vis_faligndata(TMP8, TMP10, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - vis_faligndata(TMP6, TMP8, REF_S2); - vis_faligndata(TMP8, TMP10, REF_S6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - vis_src1(TMP8, REF_S2); - vis_src1(TMP10, REF_S6); - } - - vis_mul8x16au(REF_0, CONST_256, TMP0); - vis_pmerge(ZERO, REF_0_1, TMP2); - - vis_mul8x16au(REF_2, CONST_256, TMP4); - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_padd16(TMP0, CONST_2, TMP8); - vis_mul8x16au(REF_4, CONST_256, TMP0); - - vis_padd16(TMP2, CONST_1, TMP10); - vis_mul8x16au(REF_4_1, CONST_256, TMP2); - - vis_padd16(TMP8, TMP4, TMP8); - vis_mul8x16au(REF_6, CONST_256, TMP4); - - vis_padd16(TMP10, TMP6, TMP10); - vis_mul8x16au(REF_6_1, CONST_256, TMP6); - - vis_padd16(TMP12, TMP8, TMP12); - - vis_padd16(TMP14, TMP10, TMP14); - - vis_padd16(TMP12, TMP16, TMP12); - - vis_padd16(TMP14, TMP18, TMP14); - vis_pack16(TMP12, DST_0); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP0, CONST_1, TMP12); - - vis_mul8x16au(REF_S0, CONST_256, TMP0); - vis_padd16(TMP2, CONST_1, TMP14); - - vis_mul8x16au(REF_S0_1, CONST_256, TMP2); - vis_padd16(TMP12, TMP4, TMP12); - - vis_mul8x16au(REF_S2, CONST_256, TMP4); - vis_padd16(TMP14, TMP6, TMP14); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP6); - vis_padd16(TMP20, TMP12, TMP20); - - vis_padd16(TMP22, TMP14, TMP22); - - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP22, TMP26, TMP22); - vis_pack16(TMP20, DST_2); - - vis_pack16(TMP22, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - vis_padd16(TMP0, TMP4, TMP24); - - vis_mul8x16au(REF_S4, CONST_256, TMP0); - vis_padd16(TMP2, TMP6, TMP26); - - vis_mul8x16au(REF_S4_1, CONST_256, TMP2); - vis_padd16(TMP24, TMP8, TMP24); - - vis_padd16(TMP26, TMP10, TMP26); - vis_pack16(TMP24, DST_0); - - vis_pack16(TMP26, DST_1); - vis_st64(DST_0, dest[0]); - vis_pmerge(ZERO, REF_S6, TMP4); - - vis_pmerge(ZERO, REF_S6_1, TMP6); - - vis_padd16(TMP0, TMP4, TMP0); - - vis_padd16(TMP2, TMP6, TMP2); - - vis_padd16(TMP0, TMP12, TMP0); - - vis_padd16(TMP2, TMP14, TMP2); - vis_pack16(TMP0, DST_2); - - vis_pack16(TMP2, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_put_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - - vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(constants1[0], CONST_1); - - vis_ld64(constants256_512[0], CONST_256); - vis_faligndata(TMP0, TMP2, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - } else { - vis_src1(TMP2, REF_S2); - } - - height >>= 1; - do { /* 26 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP8); - vis_pmerge(ZERO, REF_S2, TMP12); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - vis_mul8x16au(REF_S0_1, CONST_256, TMP10); - vis_pmerge(ZERO, REF_S2_1, TMP14); - - vis_ld64_2(ref, stride, TMP4); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - vis_faligndata(TMP0, TMP2, REF_S4); - - vis_pmerge(ZERO, REF_S4, TMP18); - - vis_pmerge(ZERO, REF_S4_1, TMP20); - - vis_faligndata(TMP4, TMP6, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S6); - vis_faligndata(TMP4, TMP6, REF_S2); - } else { - vis_src1(TMP2, REF_S6); - vis_src1(TMP6, REF_S2); - } - - vis_padd16(TMP18, CONST_1, TMP18); - vis_mul8x16au(REF_S6, CONST_256, TMP22); - - vis_padd16(TMP20, CONST_1, TMP20); - vis_mul8x16au(REF_S6_1, CONST_256, TMP24); - - vis_mul8x16au(REF_S0, CONST_256, TMP26); - vis_pmerge(ZERO, REF_S0_1, TMP28); - - vis_mul8x16au(REF_S2, CONST_256, TMP30); - vis_padd16(TMP18, TMP22, TMP18); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP32); - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP8, TMP18, TMP8); - - vis_padd16(TMP10, TMP20, TMP10); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - vis_padd16(TMP18, TMP26, TMP18); - - vis_padd16(TMP20, TMP28, TMP20); - - vis_padd16(TMP18, TMP30, TMP18); - - vis_padd16(TMP20, TMP32, TMP20); - vis_pack16(TMP18, DST_2); - - vis_pack16(TMP20, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -static void MC_avg_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - int stride_16 = stride + 16; - - vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[ 0], TMP0); - vis_fzero(ZERO); - - vis_ld64(ref[ 8], TMP2); - - vis_ld64(ref[16], TMP4); - - vis_ld64(constants6[0], CONST_6); - vis_faligndata(TMP0, TMP2, REF_S0); - - vis_ld64(constants256_1024[0], CONST_256); - vis_faligndata(TMP2, TMP4, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - vis_faligndata(TMP2, TMP4, REF_S6); - } else { - vis_src1(TMP2, REF_S2); - vis_src1(TMP4, REF_S6); - } - - height >>= 1; - do { /* 55 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S0_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride_8, TMP2); - vis_mul8x16au(REF_S2, CONST_256, TMP16); - vis_pmerge(ZERO, REF_S2_1, TMP18); - - vis_ld64_2(ref, stride_16, TMP4); - ref += stride; - vis_mul8x16au(REF_S4, CONST_256, TMP20); - vis_pmerge(ZERO, REF_S4_1, TMP22); - - vis_ld64_2(ref, stride, TMP6); - vis_mul8x16au(REF_S6, CONST_256, TMP24); - vis_pmerge(ZERO, REF_S6_1, TMP26); - - vis_ld64_2(ref, stride_8, TMP8); - vis_faligndata(TMP0, TMP2, REF_0); - - vis_ld64_2(ref, stride_16, TMP10); - ref += stride; - vis_faligndata(TMP2, TMP4, REF_4); - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP6, TMP8, REF_S0); - - vis_ld64_2(dest, 8, DST_2); - vis_faligndata(TMP8, TMP10, REF_S4); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_2); - vis_faligndata(TMP2, TMP4, REF_6); - vis_faligndata(TMP6, TMP8, REF_S2); - vis_faligndata(TMP8, TMP10, REF_S6); - } else { - vis_src1(TMP2, REF_2); - vis_src1(TMP4, REF_6); - vis_src1(TMP8, REF_S2); - vis_src1(TMP10, REF_S6); - } - - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_0, TMP0); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_pmerge(ZERO, REF_0_1, TMP2); - - vis_mul8x16au(REF_2, CONST_256, TMP4); - vis_pmerge(ZERO, REF_2_1, TMP6); - - vis_mul8x16al(DST_2, CONST_1024, REF_0); - vis_padd16(TMP0, CONST_6, TMP0); - - vis_mul8x16al(DST_3, CONST_1024, REF_2); - vis_padd16(TMP2, CONST_6, TMP2); - - vis_padd16(TMP0, TMP4, TMP0); - vis_mul8x16au(REF_4, CONST_256, TMP4); - - vis_padd16(TMP2, TMP6, TMP2); - vis_mul8x16au(REF_4_1, CONST_256, TMP6); - - vis_padd16(TMP12, TMP0, TMP12); - vis_mul8x16au(REF_6, CONST_256, TMP8); - - vis_padd16(TMP14, TMP2, TMP14); - vis_mul8x16au(REF_6_1, CONST_256, TMP10); - - vis_padd16(TMP12, TMP16, TMP12); - vis_mul8x16au(REF_S0, CONST_256, REF_4); - - vis_padd16(TMP14, TMP18, TMP14); - vis_mul8x16au(REF_S0_1, CONST_256, REF_6); - - vis_padd16(TMP12, TMP30, TMP12); - - vis_padd16(TMP14, TMP32, TMP14); - vis_pack16(TMP12, DST_0); - - vis_pack16(TMP14, DST_1); - vis_st64(DST_0, dest[0]); - vis_padd16(TMP4, CONST_6, TMP4); - - vis_ld64_2(dest, stride, DST_0); - vis_padd16(TMP6, CONST_6, TMP6); - vis_mul8x16au(REF_S2, CONST_256, TMP12); - - vis_padd16(TMP4, TMP8, TMP4); - vis_mul8x16au(REF_S2_1, CONST_256, TMP14); - - vis_padd16(TMP6, TMP10, TMP6); - - vis_padd16(TMP20, TMP4, TMP20); - - vis_padd16(TMP22, TMP6, TMP22); - - vis_padd16(TMP20, TMP24, TMP20); - - vis_padd16(TMP22, TMP26, TMP22); - - vis_padd16(TMP20, REF_0, TMP20); - vis_mul8x16au(REF_S4, CONST_256, REF_0); - - vis_padd16(TMP22, REF_2, TMP22); - vis_pack16(TMP20, DST_2); - - vis_pack16(TMP22, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - - vis_ld64_2(dest, 8, DST_2); - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_S4_1, REF_2); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_padd16(REF_4, TMP0, TMP8); - - vis_mul8x16au(REF_S6, CONST_256, REF_4); - vis_padd16(REF_6, TMP2, TMP10); - - vis_mul8x16au(REF_S6_1, CONST_256, REF_6); - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - - vis_padd16(TMP8, TMP30, TMP8); - - vis_padd16(TMP10, TMP32, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - - vis_padd16(REF_0, TMP4, REF_0); - - vis_mul8x16al(DST_2, CONST_1024, TMP30); - vis_padd16(REF_2, TMP6, REF_2); - - vis_mul8x16al(DST_3, CONST_1024, TMP32); - vis_padd16(REF_0, REF_4, REF_0); - - vis_padd16(REF_2, REF_6, REF_2); - - vis_padd16(REF_0, TMP30, REF_0); - - /* stall */ - - vis_padd16(REF_2, TMP32, REF_2); - vis_pack16(REF_0, DST_2); - - vis_pack16(REF_2, DST_3); - vis_st64_2(DST_2, dest, 8); - dest += stride; - } while (--height); -} - -static void MC_avg_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref, - const int stride, int height) -{ - unsigned long off = (unsigned long) ref & 0x7; - unsigned long off_plus_1 = off + 1; - int stride_8 = stride + 8; - - vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); - - ref = vis_alignaddr(ref); - - vis_ld64(ref[0], TMP0); - vis_fzero(ZERO); - - vis_ld64_2(ref, 8, TMP2); - - vis_ld64(constants6[0], CONST_6); - - vis_ld64(constants256_1024[0], CONST_256); - vis_faligndata(TMP0, TMP2, REF_S0); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S2); - } else { - vis_src1(TMP2, REF_S2); - } - - height >>= 1; - do { /* 31 cycles */ - vis_ld64_2(ref, stride, TMP0); - vis_mul8x16au(REF_S0, CONST_256, TMP8); - vis_pmerge(ZERO, REF_S0_1, TMP10); - - vis_ld64_2(ref, stride_8, TMP2); - ref += stride; - vis_mul8x16au(REF_S2, CONST_256, TMP12); - vis_pmerge(ZERO, REF_S2_1, TMP14); - - vis_alignaddr_g0((void *)off); - - vis_ld64_2(ref, stride, TMP4); - vis_faligndata(TMP0, TMP2, REF_S4); - - vis_ld64_2(ref, stride_8, TMP6); - ref += stride; - - vis_ld64(dest[0], DST_0); - vis_faligndata(TMP4, TMP6, REF_S0); - - vis_ld64_2(dest, stride, DST_2); - - if (off != 0x7) { - vis_alignaddr_g0((void *)off_plus_1); - vis_faligndata(TMP0, TMP2, REF_S6); - vis_faligndata(TMP4, TMP6, REF_S2); - } else { - vis_src1(TMP2, REF_S6); - vis_src1(TMP6, REF_S2); - } - - vis_mul8x16al(DST_0, CONST_1024, TMP30); - vis_pmerge(ZERO, REF_S4, TMP22); - - vis_mul8x16al(DST_1, CONST_1024, TMP32); - vis_pmerge(ZERO, REF_S4_1, TMP24); - - vis_mul8x16au(REF_S6, CONST_256, TMP26); - vis_pmerge(ZERO, REF_S6_1, TMP28); - - vis_mul8x16au(REF_S0, CONST_256, REF_S4); - vis_padd16(TMP22, CONST_6, TMP22); - - vis_mul8x16au(REF_S0_1, CONST_256, REF_S6); - vis_padd16(TMP24, CONST_6, TMP24); - - vis_mul8x16al(DST_2, CONST_1024, REF_0); - vis_padd16(TMP22, TMP26, TMP22); - - vis_mul8x16al(DST_3, CONST_1024, REF_2); - vis_padd16(TMP24, TMP28, TMP24); - - vis_mul8x16au(REF_S2, CONST_256, TMP26); - vis_padd16(TMP8, TMP22, TMP8); - - vis_mul8x16au(REF_S2_1, CONST_256, TMP28); - vis_padd16(TMP10, TMP24, TMP10); - - vis_padd16(TMP8, TMP12, TMP8); - - vis_padd16(TMP10, TMP14, TMP10); - - vis_padd16(TMP8, TMP30, TMP8); - - vis_padd16(TMP10, TMP32, TMP10); - vis_pack16(TMP8, DST_0); - - vis_pack16(TMP10, DST_1); - vis_st64(DST_0, dest[0]); - dest += stride; - - vis_padd16(REF_S4, TMP22, TMP12); - - vis_padd16(REF_S6, TMP24, TMP14); - - vis_padd16(TMP12, TMP26, TMP12); - - vis_padd16(TMP14, TMP28, TMP14); - - vis_padd16(TMP12, REF_0, TMP12); - - vis_padd16(TMP14, REF_2, TMP14); - vis_pack16(TMP12, DST_2); - - vis_pack16(TMP14, DST_3); - vis_st64(DST_2, dest[0]); - dest += stride; - } while (--height); -} - -/* End of no rounding code */ - -#define ACCEL_SPARC_VIS 1 -#define ACCEL_SPARC_VIS2 2 - -static int vis_level(void) -{ - int accel = 0; - accel |= ACCEL_SPARC_VIS; - accel |= ACCEL_SPARC_VIS2; - return accel; -} - -/* libavcodec initialization code */ -void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx) -{ - /* VIS-specific optimizations */ - int accel = vis_level (); - - if (accel & ACCEL_SPARC_VIS) { - if(avctx->idct_algo==FF_IDCT_SIMPLEVIS){ - c->idct_put = ff_simple_idct_put_vis; - c->idct_add = ff_simple_idct_add_vis; - c->idct = ff_simple_idct_vis; - c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; - } - - c->put_pixels_tab[0][0] = MC_put_o_16_vis; - c->put_pixels_tab[0][1] = MC_put_x_16_vis; - c->put_pixels_tab[0][2] = MC_put_y_16_vis; - c->put_pixels_tab[0][3] = MC_put_xy_16_vis; - - c->put_pixels_tab[1][0] = MC_put_o_8_vis; - c->put_pixels_tab[1][1] = MC_put_x_8_vis; - c->put_pixels_tab[1][2] = MC_put_y_8_vis; - c->put_pixels_tab[1][3] = MC_put_xy_8_vis; - - c->avg_pixels_tab[0][0] = MC_avg_o_16_vis; - c->avg_pixels_tab[0][1] = MC_avg_x_16_vis; - c->avg_pixels_tab[0][2] = MC_avg_y_16_vis; - c->avg_pixels_tab[0][3] = MC_avg_xy_16_vis; - - c->avg_pixels_tab[1][0] = MC_avg_o_8_vis; - c->avg_pixels_tab[1][1] = MC_avg_x_8_vis; - c->avg_pixels_tab[1][2] = MC_avg_y_8_vis; - c->avg_pixels_tab[1][3] = MC_avg_xy_8_vis; - - c->put_no_rnd_pixels_tab[0][0] = MC_put_no_round_o_16_vis; - c->put_no_rnd_pixels_tab[0][1] = MC_put_no_round_x_16_vis; - c->put_no_rnd_pixels_tab[0][2] = MC_put_no_round_y_16_vis; - c->put_no_rnd_pixels_tab[0][3] = MC_put_no_round_xy_16_vis; - - c->put_no_rnd_pixels_tab[1][0] = MC_put_no_round_o_8_vis; - c->put_no_rnd_pixels_tab[1][1] = MC_put_no_round_x_8_vis; - c->put_no_rnd_pixels_tab[1][2] = MC_put_no_round_y_8_vis; - c->put_no_rnd_pixels_tab[1][3] = MC_put_no_round_xy_8_vis; - - c->avg_no_rnd_pixels_tab[0][0] = MC_avg_no_round_o_16_vis; - c->avg_no_rnd_pixels_tab[0][1] = MC_avg_no_round_x_16_vis; - c->avg_no_rnd_pixels_tab[0][2] = MC_avg_no_round_y_16_vis; - c->avg_no_rnd_pixels_tab[0][3] = MC_avg_no_round_xy_16_vis; - - c->avg_no_rnd_pixels_tab[1][0] = MC_avg_no_round_o_8_vis; - c->avg_no_rnd_pixels_tab[1][1] = MC_avg_no_round_x_8_vis; - c->avg_no_rnd_pixels_tab[1][2] = MC_avg_no_round_y_8_vis; - c->avg_no_rnd_pixels_tab[1][3] = MC_avg_no_round_xy_8_vis; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.h b/tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.h deleted file mode 100644 index 97ff965..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sparc/dsputil_vis.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SPARC_DSPUTIL_VIS_H -#define AVCODEC_SPARC_DSPUTIL_VIS_H - -#include -#include "libavcodec/dsputil.h" - -void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data); -void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data); -void ff_simple_idct_vis(DCTELEM *data); - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/sparc/simple_idct_vis.c b/tizen/distrib/ffmpeg/libavcodec/sparc/simple_idct_vis.c deleted file mode 100644 index d98bf37..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sparc/simple_idct_vis.c +++ /dev/null @@ -1,529 +0,0 @@ -/* - * SPARC VIS optimized inverse DCT - * Copyright (c) 2007 Denes Balatoni < dbalatoni XatX interware XdotX hu > - * - * I did consult the following fine web page about dct - * http://www.geocities.com/ssavekar/dct.htm - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_vis.h" - -static const DECLARE_ALIGNED(8, int16_t, coeffs)[28] = { - - 1259,- 1259,- 1259,- 1259, - - 4989,- 4989,- 4989,- 4989, - -11045,-11045,-11045,-11045, - -19195,-19195,-19195,-19195, - -29126,-29126,-29126,-29126, - 25080, 25080, 25080, 25080, - 12785, 12785, 12785, 12785 -}; -static const DECLARE_ALIGNED(8, uint16_t, scale)[4] = { - 65536>>6, 65536>>6, 65536>>6, 65536>>6 -}; -static const DECLARE_ALIGNED(8, uint16_t, rounder)[4] = { - 1<<5, 1<<5, 1<<5, 1<<5 -}; -static const DECLARE_ALIGNED(8, uint16_t, expand)[4] = { - 1<<14, 1<<14, 1<<14, 1<<14 -}; - -#define INIT_IDCT \ - "ldd [%1], %%f32 \n\t"\ - "ldd [%1+8], %%f34 \n\t"\ - "ldd [%1+16], %%f36 \n\t"\ - "ldd [%1+24], %%f38 \n\t"\ - "ldd [%1+32], %%f40 \n\t"\ - "ldd [%1+40], %%f42 \n\t"\ - "ldd [%1+48], %%f44 \n\t"\ - "ldd [%0], %%f46 \n\t"\ - "fzero %%f62 \n\t"\ - -#define LOADSCALE(in) \ - "ldd [" in "], %%f0 \n\t"\ - "ldd [" in "+16], %%f2 \n\t"\ - "ldd [" in "+32], %%f4 \n\t"\ - "ldd [" in "+48], %%f6 \n\t"\ - "ldd [" in "+64], %%f8 \n\t"\ - "ldd [" in "+80], %%f10 \n\t"\ - "ldd [" in "+96], %%f12 \n\t"\ - "ldd [" in "+112], %%f14 \n\t"\ - "fpadd16 %%f0, %%f0, %%f0 \n\t"\ - "fpadd16 %%f2, %%f2, %%f2 \n\t"\ - "fpadd16 %%f4, %%f4, %%f4 \n\t"\ - "fpadd16 %%f6, %%f6, %%f6 \n\t"\ - "fpadd16 %%f8, %%f8, %%f8 \n\t"\ - "fpadd16 %%f10, %%f10, %%f10 \n\t"\ - "fpadd16 %%f12, %%f12, %%f12 \n\t"\ - "fpadd16 %%f14, %%f14, %%f14 \n\t"\ -\ - "fpadd16 %%f0, %%f0, %%f0 \n\t"\ - "fpadd16 %%f2, %%f2, %%f2 \n\t"\ - "fpadd16 %%f4, %%f4, %%f4 \n\t"\ - "fpadd16 %%f6, %%f6, %%f6 \n\t"\ - "fpadd16 %%f8, %%f8, %%f8 \n\t"\ - "fpadd16 %%f10, %%f10, %%f10 \n\t"\ - "fpadd16 %%f12, %%f12, %%f12 \n\t"\ - "fpadd16 %%f14, %%f14, %%f14 \n\t"\ -\ - "fpadd16 %%f0, %%f0, %%f0 \n\t"\ - "fpadd16 %%f2, %%f2, %%f2 \n\t"\ - "fpadd16 %%f4, %%f4, %%f4 \n\t"\ - "fpadd16 %%f6, %%f6, %%f6 \n\t"\ - "fpadd16 %%f8, %%f8, %%f8 \n\t"\ - "fpadd16 %%f10, %%f10, %%f10 \n\t"\ - "fpadd16 %%f12, %%f12, %%f12 \n\t"\ - "fpadd16 %%f14, %%f14, %%f14 \n\t"\ -\ - "fpadd16 %%f0, %%f0, %%f0 \n\t"\ - "fpadd16 %%f2, %%f2, %%f2 \n\t"\ - "fpadd16 %%f4, %%f4, %%f4 \n\t"\ - "fpadd16 %%f6, %%f6, %%f6 \n\t"\ - "fpadd16 %%f8, %%f8, %%f8 \n\t"\ - "fpadd16 %%f10, %%f10, %%f10 \n\t"\ - "fpadd16 %%f12, %%f12, %%f12 \n\t"\ - "fpadd16 %%f14, %%f14, %%f14 \n\t"\ - -#define LOAD(in) \ - "ldd [" in "], %%f16 \n\t"\ - "ldd [" in "+8], %%f18 \n\t"\ - "ldd [" in "+16], %%f20 \n\t"\ - "ldd [" in "+24], %%f22 \n\t"\ - "ldd [" in "+32], %%f24 \n\t"\ - "ldd [" in "+40], %%f26 \n\t"\ - "ldd [" in "+48], %%f28 \n\t"\ - "ldd [" in "+56], %%f30 \n\t"\ - -#define TRANSPOSE \ - "fpmerge %%f16, %%f24, %%f0 \n\t"\ - "fpmerge %%f20, %%f28, %%f2 \n\t"\ - "fpmerge %%f17, %%f25, %%f4 \n\t"\ - "fpmerge %%f21, %%f29, %%f6 \n\t"\ - "fpmerge %%f18, %%f26, %%f8 \n\t"\ - "fpmerge %%f22, %%f30, %%f10 \n\t"\ - "fpmerge %%f19, %%f27, %%f12 \n\t"\ - "fpmerge %%f23, %%f31, %%f14 \n\t"\ -\ - "fpmerge %%f0, %%f2, %%f16 \n\t"\ - "fpmerge %%f1, %%f3, %%f18 \n\t"\ - "fpmerge %%f4, %%f6, %%f20 \n\t"\ - "fpmerge %%f5, %%f7, %%f22 \n\t"\ - "fpmerge %%f8, %%f10, %%f24 \n\t"\ - "fpmerge %%f9, %%f11, %%f26 \n\t"\ - "fpmerge %%f12, %%f14, %%f28 \n\t"\ - "fpmerge %%f13, %%f15, %%f30 \n\t"\ -\ - "fpmerge %%f16, %%f17, %%f0 \n\t"\ - "fpmerge %%f18, %%f19, %%f2 \n\t"\ - "fpmerge %%f20, %%f21, %%f4 \n\t"\ - "fpmerge %%f22, %%f23, %%f6 \n\t"\ - "fpmerge %%f24, %%f25, %%f8 \n\t"\ - "fpmerge %%f26, %%f27, %%f10 \n\t"\ - "fpmerge %%f28, %%f29, %%f12 \n\t"\ - "fpmerge %%f30, %%f31, %%f14 \n\t"\ - -#define IDCT4ROWS \ - /* 1. column */\ - "fmul8ulx16 %%f0, %%f38, %%f28 \n\t"\ - "for %%f4, %%f6, %%f60 \n\t"\ - "fmul8ulx16 %%f2, %%f32, %%f18 \n\t"\ - "fmul8ulx16 %%f2, %%f36, %%f22 \n\t"\ - "fmul8ulx16 %%f2, %%f40, %%f26 \n\t"\ - "fmul8ulx16 %%f2, %%f44, %%f30 \n\t"\ -\ - ADDROUNDER\ -\ - "fmul8sux16 %%f0, %%f38, %%f48 \n\t"\ - "fcmpd %%fcc0, %%f62, %%f60 \n\t"\ - "for %%f8, %%f10, %%f60 \n\t"\ - "fmul8sux16 %%f2, %%f32, %%f50 \n\t"\ - "fmul8sux16 %%f2, %%f36, %%f52 \n\t"\ - "fmul8sux16 %%f2, %%f40, %%f54 \n\t"\ - "fmul8sux16 %%f2, %%f44, %%f56 \n\t"\ -\ - "fpadd16 %%f48, %%f28, %%f28 \n\t"\ - "fcmpd %%fcc1, %%f62, %%f60 \n\t"\ - "for %%f12, %%f14, %%f60 \n\t"\ - "fpadd16 %%f50, %%f18, %%f18 \n\t"\ - "fpadd16 %%f52, %%f22, %%f22 \n\t"\ - "fpadd16 %%f54, %%f26, %%f26 \n\t"\ - "fpadd16 %%f56, %%f30, %%f30 \n\t"\ -\ - "fpadd16 %%f28, %%f0, %%f16 \n\t"\ - "fcmpd %%fcc2, %%f62, %%f60 \n\t"\ - "fpadd16 %%f28, %%f0, %%f20 \n\t"\ - "fpadd16 %%f28, %%f0, %%f24 \n\t"\ - "fpadd16 %%f28, %%f0, %%f28 \n\t"\ - "fpadd16 %%f18, %%f2, %%f18 \n\t"\ - "fpadd16 %%f22, %%f2, %%f22 \n\t"\ - /* 2. column */\ - "fbe %%fcc0, 3f \n\t"\ - "fpadd16 %%f26, %%f2, %%f26 \n\t"\ - "fmul8ulx16 %%f4, %%f34, %%f48 \n\t"\ - "fmul8ulx16 %%f4, %%f42, %%f50 \n\t"\ - "fmul8ulx16 %%f6, %%f36, %%f52 \n\t"\ - "fmul8ulx16 %%f6, %%f44, %%f54 \n\t"\ - "fmul8ulx16 %%f6, %%f32, %%f56 \n\t"\ - "fmul8ulx16 %%f6, %%f40, %%f58 \n\t"\ -\ - "fpadd16 %%f16, %%f48, %%f16 \n\t"\ - "fpadd16 %%f20, %%f50, %%f20 \n\t"\ - "fpsub16 %%f24, %%f50, %%f24 \n\t"\ - "fpsub16 %%f28, %%f48, %%f28 \n\t"\ - "fpadd16 %%f18, %%f52, %%f18 \n\t"\ - "fpsub16 %%f22, %%f54, %%f22 \n\t"\ - "fpsub16 %%f26, %%f56, %%f26 \n\t"\ - "fpsub16 %%f30, %%f58, %%f30 \n\t"\ -\ - "fmul8sux16 %%f4, %%f34, %%f48 \n\t"\ - "fmul8sux16 %%f4, %%f42, %%f50 \n\t"\ - "fmul8sux16 %%f6, %%f36, %%f52 \n\t"\ - "fmul8sux16 %%f6, %%f44, %%f54 \n\t"\ - "fmul8sux16 %%f6, %%f32, %%f56 \n\t"\ - "fmul8sux16 %%f6, %%f40, %%f58 \n\t"\ -\ - "fpadd16 %%f16, %%f48, %%f16 \n\t"\ - "fpadd16 %%f20, %%f50, %%f20 \n\t"\ - "fpsub16 %%f24, %%f50, %%f24 \n\t"\ - "fpsub16 %%f28, %%f48, %%f28 \n\t"\ - "fpadd16 %%f18, %%f52, %%f18 \n\t"\ - "fpsub16 %%f22, %%f54, %%f22 \n\t"\ - "fpsub16 %%f26, %%f56, %%f26 \n\t"\ - "fpsub16 %%f30, %%f58, %%f30 \n\t"\ -\ - "fpadd16 %%f16, %%f4, %%f16 \n\t"\ - "fpsub16 %%f28, %%f4, %%f28 \n\t"\ - "fpadd16 %%f18, %%f6, %%f18 \n\t"\ - "fpsub16 %%f26, %%f6, %%f26 \n\t"\ - /* 3. column */\ - "3: \n\t"\ - "fbe %%fcc1, 4f \n\t"\ - "fpsub16 %%f30, %%f6, %%f30 \n\t"\ - "fmul8ulx16 %%f8, %%f38, %%f48 \n\t"\ - "fmul8ulx16 %%f10, %%f40, %%f50 \n\t"\ - "fmul8ulx16 %%f10, %%f32, %%f52 \n\t"\ - "fmul8ulx16 %%f10, %%f44, %%f54 \n\t"\ - "fmul8ulx16 %%f10, %%f36, %%f56 \n\t"\ -\ - "fpadd16 %%f16, %%f48, %%f16 \n\t"\ - "fpsub16 %%f20, %%f48, %%f20 \n\t"\ - "fpsub16 %%f24, %%f48, %%f24 \n\t"\ - "fpadd16 %%f28, %%f48, %%f28 \n\t"\ - "fpadd16 %%f18, %%f50, %%f18 \n\t"\ - "fpsub16 %%f22, %%f52, %%f22 \n\t"\ - "fpadd16 %%f26, %%f54, %%f26 \n\t"\ - "fpadd16 %%f30, %%f56, %%f30 \n\t"\ -\ - "fmul8sux16 %%f8, %%f38, %%f48 \n\t"\ - "fmul8sux16 %%f10, %%f40, %%f50 \n\t"\ - "fmul8sux16 %%f10, %%f32, %%f52 \n\t"\ - "fmul8sux16 %%f10, %%f44, %%f54 \n\t"\ - "fmul8sux16 %%f10, %%f36, %%f56 \n\t"\ -\ - "fpadd16 %%f16, %%f48, %%f16 \n\t"\ - "fpsub16 %%f20, %%f48, %%f20 \n\t"\ - "fpsub16 %%f24, %%f48, %%f24 \n\t"\ - "fpadd16 %%f28, %%f48, %%f28 \n\t"\ - "fpadd16 %%f18, %%f50, %%f18 \n\t"\ - "fpsub16 %%f22, %%f52, %%f22 \n\t"\ - "fpadd16 %%f26, %%f54, %%f26 \n\t"\ - "fpadd16 %%f30, %%f56, %%f30 \n\t"\ -\ - "fpadd16 %%f16, %%f8, %%f16 \n\t"\ - "fpsub16 %%f20, %%f8, %%f20 \n\t"\ - "fpsub16 %%f24, %%f8, %%f24 \n\t"\ - "fpadd16 %%f28, %%f8, %%f28 \n\t"\ - "fpadd16 %%f18, %%f10, %%f18 \n\t"\ - "fpsub16 %%f22, %%f10, %%f22 \n\t"\ - /* 4. column */\ - "4: \n\t"\ - "fbe %%fcc2, 5f \n\t"\ - "fpadd16 %%f30, %%f10, %%f30 \n\t"\ - "fmul8ulx16 %%f12, %%f42, %%f48 \n\t"\ - "fmul8ulx16 %%f12, %%f34, %%f50 \n\t"\ - "fmul8ulx16 %%f14, %%f44, %%f52 \n\t"\ - "fmul8ulx16 %%f14, %%f40, %%f54 \n\t"\ - "fmul8ulx16 %%f14, %%f36, %%f56 \n\t"\ - "fmul8ulx16 %%f14, %%f32, %%f58 \n\t"\ -\ - "fpadd16 %%f16, %%f48, %%f16 \n\t"\ - "fpsub16 %%f20, %%f50, %%f20 \n\t"\ - "fpadd16 %%f24, %%f50, %%f24 \n\t"\ - "fpsub16 %%f28, %%f48, %%f28 \n\t"\ - "fpadd16 %%f18, %%f52, %%f18 \n\t"\ - "fpsub16 %%f22, %%f54, %%f22 \n\t"\ - "fpadd16 %%f26, %%f56, %%f26 \n\t"\ - "fpsub16 %%f30, %%f58, %%f30 \n\t"\ -\ - "fmul8sux16 %%f12, %%f42, %%f48 \n\t"\ - "fmul8sux16 %%f12, %%f34, %%f50 \n\t"\ - "fmul8sux16 %%f14, %%f44, %%f52 \n\t"\ - "fmul8sux16 %%f14, %%f40, %%f54 \n\t"\ - "fmul8sux16 %%f14, %%f36, %%f56 \n\t"\ - "fmul8sux16 %%f14, %%f32, %%f58 \n\t"\ -\ - "fpadd16 %%f16, %%f48, %%f16 \n\t"\ - "fpsub16 %%f20, %%f50, %%f20 \n\t"\ - "fpadd16 %%f24, %%f50, %%f24 \n\t"\ - "fpsub16 %%f28, %%f48, %%f28 \n\t"\ - "fpadd16 %%f18, %%f52, %%f18 \n\t"\ - "fpsub16 %%f22, %%f54, %%f22 \n\t"\ - "fpadd16 %%f26, %%f56, %%f26 \n\t"\ - "fpsub16 %%f30, %%f58, %%f30 \n\t"\ -\ - "fpsub16 %%f20, %%f12, %%f20 \n\t"\ - "fpadd16 %%f24, %%f12, %%f24 \n\t"\ - "fpsub16 %%f22, %%f14, %%f22 \n\t"\ - "fpadd16 %%f26, %%f14, %%f26 \n\t"\ - "fpsub16 %%f30, %%f14, %%f30 \n\t"\ - /* final butterfly */\ - "5: \n\t"\ - "fpsub16 %%f16, %%f18, %%f48 \n\t"\ - "fpsub16 %%f20, %%f22, %%f50 \n\t"\ - "fpsub16 %%f24, %%f26, %%f52 \n\t"\ - "fpsub16 %%f28, %%f30, %%f54 \n\t"\ - "fpadd16 %%f16, %%f18, %%f16 \n\t"\ - "fpadd16 %%f20, %%f22, %%f20 \n\t"\ - "fpadd16 %%f24, %%f26, %%f24 \n\t"\ - "fpadd16 %%f28, %%f30, %%f28 \n\t"\ - -#define STOREROWS(out) \ - "std %%f48, [" out "+112] \n\t"\ - "std %%f50, [" out "+96] \n\t"\ - "std %%f52, [" out "+80] \n\t"\ - "std %%f54, [" out "+64] \n\t"\ - "std %%f16, [" out "] \n\t"\ - "std %%f20, [" out "+16] \n\t"\ - "std %%f24, [" out "+32] \n\t"\ - "std %%f28, [" out "+48] \n\t"\ - -#define SCALEROWS \ - "fmul8sux16 %%f46, %%f48, %%f48 \n\t"\ - "fmul8sux16 %%f46, %%f50, %%f50 \n\t"\ - "fmul8sux16 %%f46, %%f52, %%f52 \n\t"\ - "fmul8sux16 %%f46, %%f54, %%f54 \n\t"\ - "fmul8sux16 %%f46, %%f16, %%f16 \n\t"\ - "fmul8sux16 %%f46, %%f20, %%f20 \n\t"\ - "fmul8sux16 %%f46, %%f24, %%f24 \n\t"\ - "fmul8sux16 %%f46, %%f28, %%f28 \n\t"\ - -#define PUTPIXELSCLAMPED(dest) \ - "fpack16 %%f48, %%f14 \n\t"\ - "fpack16 %%f50, %%f12 \n\t"\ - "fpack16 %%f16, %%f0 \n\t"\ - "fpack16 %%f20, %%f2 \n\t"\ - "fpack16 %%f24, %%f4 \n\t"\ - "fpack16 %%f28, %%f6 \n\t"\ - "fpack16 %%f54, %%f8 \n\t"\ - "fpack16 %%f52, %%f10 \n\t"\ - "st %%f0, [%3+" dest "] \n\t"\ - "st %%f2, [%5+" dest "] \n\t"\ - "st %%f4, [%6+" dest "] \n\t"\ - "st %%f6, [%7+" dest "] \n\t"\ - "st %%f8, [%8+" dest "] \n\t"\ - "st %%f10, [%9+" dest "] \n\t"\ - "st %%f12, [%10+" dest "] \n\t"\ - "st %%f14, [%11+" dest "] \n\t"\ - -#define ADDPIXELSCLAMPED(dest) \ - "ldd [%5], %%f18 \n\t"\ - "ld [%3+" dest"], %%f0 \n\t"\ - "ld [%6+" dest"], %%f2 \n\t"\ - "ld [%7+" dest"], %%f4 \n\t"\ - "ld [%8+" dest"], %%f6 \n\t"\ - "ld [%9+" dest"], %%f8 \n\t"\ - "ld [%10+" dest"], %%f10 \n\t"\ - "ld [%11+" dest"], %%f12 \n\t"\ - "ld [%12+" dest"], %%f14 \n\t"\ - "fmul8x16 %%f0, %%f18, %%f0 \n\t"\ - "fmul8x16 %%f2, %%f18, %%f2 \n\t"\ - "fmul8x16 %%f4, %%f18, %%f4 \n\t"\ - "fmul8x16 %%f6, %%f18, %%f6 \n\t"\ - "fmul8x16 %%f8, %%f18, %%f8 \n\t"\ - "fmul8x16 %%f10, %%f18, %%f10 \n\t"\ - "fmul8x16 %%f12, %%f18, %%f12 \n\t"\ - "fmul8x16 %%f14, %%f18, %%f14 \n\t"\ - "fpadd16 %%f0, %%f16, %%f0 \n\t"\ - "fpadd16 %%f2, %%f20, %%f2 \n\t"\ - "fpadd16 %%f4, %%f24, %%f4 \n\t"\ - "fpadd16 %%f6, %%f28, %%f6 \n\t"\ - "fpadd16 %%f8, %%f54, %%f8 \n\t"\ - "fpadd16 %%f10, %%f52, %%f10 \n\t"\ - "fpadd16 %%f12, %%f50, %%f12 \n\t"\ - "fpadd16 %%f14, %%f48, %%f14 \n\t"\ - "fpack16 %%f0, %%f0 \n\t"\ - "fpack16 %%f2, %%f2 \n\t"\ - "fpack16 %%f4, %%f4 \n\t"\ - "fpack16 %%f6, %%f6 \n\t"\ - "fpack16 %%f8, %%f8 \n\t"\ - "fpack16 %%f10, %%f10 \n\t"\ - "fpack16 %%f12, %%f12 \n\t"\ - "fpack16 %%f14, %%f14 \n\t"\ - "st %%f0, [%3+" dest "] \n\t"\ - "st %%f2, [%6+" dest "] \n\t"\ - "st %%f4, [%7+" dest "] \n\t"\ - "st %%f6, [%8+" dest "] \n\t"\ - "st %%f8, [%9+" dest "] \n\t"\ - "st %%f10, [%10+" dest "] \n\t"\ - "st %%f12, [%11+" dest "] \n\t"\ - "st %%f14, [%12+" dest "] \n\t"\ - - -void ff_simple_idct_vis(DCTELEM *data) { - int out1, out2, out3, out4; - DECLARE_ALIGNED(8, int16_t, temp)[8*8]; - - __asm__ volatile( - INIT_IDCT - -#define ADDROUNDER - - // shift right 16-4=12 - LOADSCALE("%2+8") - IDCT4ROWS - STOREROWS("%3+8") - LOADSCALE("%2+0") - IDCT4ROWS - "std %%f48, [%3+112] \n\t" - "std %%f50, [%3+96] \n\t" - "std %%f52, [%3+80] \n\t" - "std %%f54, [%3+64] \n\t" - - // shift right 16+4 - "ldd [%3+8], %%f18 \n\t" - "ldd [%3+24], %%f22 \n\t" - "ldd [%3+40], %%f26 \n\t" - "ldd [%3+56], %%f30 \n\t" - TRANSPOSE - IDCT4ROWS - SCALEROWS - STOREROWS("%2+0") - LOAD("%3+64") - TRANSPOSE - IDCT4ROWS - SCALEROWS - STOREROWS("%2+8") - - : "=r" (out1), "=r" (out2), "=r" (out3), "=r" (out4) - : "0" (scale), "1" (coeffs), "2" (data), "3" (temp) - ); -} - -void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data) { - int out1, out2, out3, out4, out5; - int r1, r2, r3, r4, r5, r6, r7; - - __asm__ volatile( - "wr %%g0, 0x8, %%gsr \n\t" - - INIT_IDCT - - "add %3, %4, %5 \n\t" - "add %5, %4, %6 \n\t" - "add %6, %4, %7 \n\t" - "add %7, %4, %8 \n\t" - "add %8, %4, %9 \n\t" - "add %9, %4, %10 \n\t" - "add %10, %4, %11 \n\t" - - // shift right 16-4=12 - LOADSCALE("%2+8") - IDCT4ROWS - STOREROWS("%2+8") - LOADSCALE("%2+0") - IDCT4ROWS - "std %%f48, [%2+112] \n\t" - "std %%f50, [%2+96] \n\t" - "std %%f52, [%2+80] \n\t" - "std %%f54, [%2+64] \n\t" - -#undef ADDROUNDER -#define ADDROUNDER "fpadd16 %%f28, %%f46, %%f28 \n\t" - - // shift right 16+4 - "ldd [%2+8], %%f18 \n\t" - "ldd [%2+24], %%f22 \n\t" - "ldd [%2+40], %%f26 \n\t" - "ldd [%2+56], %%f30 \n\t" - TRANSPOSE - IDCT4ROWS - PUTPIXELSCLAMPED("0") - LOAD("%2+64") - TRANSPOSE - IDCT4ROWS - PUTPIXELSCLAMPED("4") - - : "=r" (out1), "=r" (out2), "=r" (out3), "=r" (out4), "=r" (out5), - "=r" (r1), "=r" (r2), "=r" (r3), "=r" (r4), "=r" (r5), "=r" (r6), "=r" (r7) - : "0" (rounder), "1" (coeffs), "2" (data), "3" (dest), "4" (line_size) - ); -} - -void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data) { - int out1, out2, out3, out4, out5, out6; - int r1, r2, r3, r4, r5, r6, r7; - - __asm__ volatile( - "wr %%g0, 0x8, %%gsr \n\t" - - INIT_IDCT - - "add %3, %4, %6 \n\t" - "add %6, %4, %7 \n\t" - "add %7, %4, %8 \n\t" - "add %8, %4, %9 \n\t" - "add %9, %4, %10 \n\t" - "add %10, %4, %11 \n\t" - "add %11, %4, %12 \n\t" - -#undef ADDROUNDER -#define ADDROUNDER - - // shift right 16-4=12 - LOADSCALE("%2+8") - IDCT4ROWS - STOREROWS("%2+8") - LOADSCALE("%2+0") - IDCT4ROWS - "std %%f48, [%2+112] \n\t" - "std %%f50, [%2+96] \n\t" - "std %%f52, [%2+80] \n\t" - "std %%f54, [%2+64] \n\t" - -#undef ADDROUNDER -#define ADDROUNDER "fpadd16 %%f28, %%f46, %%f28 \n\t" - - // shift right 16+4 - "ldd [%2+8], %%f18 \n\t" - "ldd [%2+24], %%f22 \n\t" - "ldd [%2+40], %%f26 \n\t" - "ldd [%2+56], %%f30 \n\t" - TRANSPOSE - IDCT4ROWS - ADDPIXELSCLAMPED("0") - LOAD("%2+64") - TRANSPOSE - IDCT4ROWS - ADDPIXELSCLAMPED("4") - - : "=r" (out1), "=r" (out2), "=r" (out3), "=r" (out4), "=r" (out5), "=r" (out6), - "=r" (r1), "=r" (r2), "=r" (r3), "=r" (r4), "=r" (r5), "=r" (r6), "=r" (r7) - : "0" (rounder), "1" (coeffs), "2" (data), "3" (dest), "4" (line_size), "5" (expand) - ); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/sparc/vis.h b/tizen/distrib/ffmpeg/libavcodec/sparc/vis.h deleted file mode 100644 index adee91b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sparc/vis.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2003 David S. Miller - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* You may be asking why I hard-code the instruction opcodes and don't - * use the normal VIS assembler mnenomics for the VIS instructions. - * - * The reason is that Sun, in their infinite wisdom, decided that a binary - * using a VIS instruction will cause it to be marked (in the ELF headers) - * as doing so, and this prevents the OS from loading such binaries if the - * current cpu doesn't have VIS. There is no way to easily override this - * behavior of the assembler that I am aware of. - * - * This totally defeats what libmpeg2 is trying to do which is allow a - * single binary to be created, and then detect the availability of VIS - * at runtime. - * - * I'm not saying that tainting the binary by default is bad, rather I'm - * saying that not providing a way to override this easily unnecessarily - * ties people's hands. - * - * Thus, we do the opcode encoding by hand and output 32-bit words in - * the assembler to keep the binary from becoming tainted. - */ - -#ifndef AVCODEC_SPARC_VIS_H -#define AVCODEC_SPARC_VIS_H - -#define vis_opc_base ((0x1 << 31) | (0x36 << 19)) -#define vis_opf(X) ((X) << 5) -#define vis_sreg(X) (X) -#define vis_dreg(X) (((X)&0x1f)|((X)>>5)) -#define vis_rs1_s(X) (vis_sreg(X) << 14) -#define vis_rs1_d(X) (vis_dreg(X) << 14) -#define vis_rs2_s(X) (vis_sreg(X) << 0) -#define vis_rs2_d(X) (vis_dreg(X) << 0) -#define vis_rd_s(X) (vis_sreg(X) << 25) -#define vis_rd_d(X) (vis_dreg(X) << 25) - -#define vis_ss2s(opf,rs1,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rs2_s(rs2) | \ - vis_rd_s(rd))) - -#define vis_dd2d(opf,rs1,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_d(rs1) | \ - vis_rs2_d(rs2) | \ - vis_rd_d(rd))) - -#define vis_ss2d(opf,rs1,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rs2_s(rs2) | \ - vis_rd_d(rd))) - -#define vis_sd2d(opf,rs1,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rs2_d(rs2) | \ - vis_rd_d(rd))) - -#define vis_d2s(opf,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_d(rs2) | \ - vis_rd_s(rd))) - -#define vis_s2d(opf,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_s(rs2) | \ - vis_rd_d(rd))) - -#define vis_d12d(opf,rs1,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_d(rs1) | \ - vis_rd_d(rd))) - -#define vis_d22d(opf,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_d(rs2) | \ - vis_rd_d(rd))) - -#define vis_s12s(opf,rs1,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs1_s(rs1) | \ - vis_rd_s(rd))) - -#define vis_s22s(opf,rs2,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rs2_s(rs2) | \ - vis_rd_s(rd))) - -#define vis_s(opf,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rd_s(rd))) - -#define vis_d(opf,rd) \ - __asm__ volatile (".word %0" \ - : : "i" (vis_opc_base | vis_opf(opf) | \ - vis_rd_d(rd))) - -#define vis_r2m(op,rd,mem) \ - __asm__ volatile (#op "\t%%f" #rd ", [%0]" : : "r" (&(mem)) ) - -#define vis_r2m_2(op,rd,mem1,mem2) \ - __asm__ volatile (#op "\t%%f" #rd ", [%0 + %1]" : : "r" (mem1), "r" (mem2) ) - -#define vis_m2r(op,mem,rd) \ - __asm__ volatile (#op "\t[%0], %%f" #rd : : "r" (&(mem)) ) - -#define vis_m2r_2(op,mem1,mem2,rd) \ - __asm__ volatile (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) ) - -static inline void vis_set_gsr(unsigned int _val) -{ - register unsigned int val __asm__("g1"); - - val = _val; - __asm__ volatile(".word 0xa7804000" - : : "r" (val)); -} - -#define VIS_GSR_ALIGNADDR_MASK 0x0000007 -#define VIS_GSR_ALIGNADDR_SHIFT 0 -#define VIS_GSR_SCALEFACT_MASK 0x0000078 -#define VIS_GSR_SCALEFACT_SHIFT 3 - -#define vis_ld32(mem,rs1) vis_m2r(ld, mem, rs1) -#define vis_ld32_2(mem1,mem2,rs1) vis_m2r_2(ld, mem1, mem2, rs1) -#define vis_st32(rs1,mem) vis_r2m(st, rs1, mem) -#define vis_st32_2(rs1,mem1,mem2) vis_r2m_2(st, rs1, mem1, mem2) -#define vis_ld64(mem,rs1) vis_m2r(ldd, mem, rs1) -#define vis_ld64_2(mem1,mem2,rs1) vis_m2r_2(ldd, mem1, mem2, rs1) -#define vis_st64(rs1,mem) vis_r2m(std, rs1, mem) -#define vis_st64_2(rs1,mem1,mem2) vis_r2m_2(std, rs1, mem1, mem2) - -#define vis_ldblk(mem, rd) \ -do { register void *__mem __asm__("g1"); \ - __mem = &(mem); \ - __asm__ volatile(".word 0xc1985e00 | %1" \ - : \ - : "r" (__mem), \ - "i" (vis_rd_d(rd)) \ - : "memory"); \ -} while (0) - -#define vis_stblk(rd, mem) \ -do { register void *__mem __asm__("g1"); \ - __mem = &(mem); \ - __asm__ volatile(".word 0xc1b85e00 | %1" \ - : \ - : "r" (__mem), \ - "i" (vis_rd_d(rd)) \ - : "memory"); \ -} while (0) - -#define vis_membar_storestore() \ - __asm__ volatile(".word 0x8143e008" : : : "memory") - -#define vis_membar_sync() \ - __asm__ volatile(".word 0x8143e040" : : : "memory") - -/* 16 and 32 bit partitioned addition and subtraction. The normal - * versions perform 4 16-bit or 2 32-bit additions or subtractions. - * The 's' versions perform 2 16-bit or 1 32-bit additions or - * subtractions. - */ - -#define vis_padd16(rs1,rs2,rd) vis_dd2d(0x50, rs1, rs2, rd) -#define vis_padd16s(rs1,rs2,rd) vis_ss2s(0x51, rs1, rs2, rd) -#define vis_padd32(rs1,rs2,rd) vis_dd2d(0x52, rs1, rs2, rd) -#define vis_padd32s(rs1,rs2,rd) vis_ss2s(0x53, rs1, rs2, rd) -#define vis_psub16(rs1,rs2,rd) vis_dd2d(0x54, rs1, rs2, rd) -#define vis_psub16s(rs1,rs2,rd) vis_ss2s(0x55, rs1, rs2, rd) -#define vis_psub32(rs1,rs2,rd) vis_dd2d(0x56, rs1, rs2, rd) -#define vis_psub32s(rs1,rs2,rd) vis_ss2s(0x57, rs1, rs2, rd) - -/* Pixel formatting instructions. */ - -#define vis_pack16(rs2,rd) vis_d2s( 0x3b, rs2, rd) -#define vis_pack32(rs1,rs2,rd) vis_dd2d(0x3a, rs1, rs2, rd) -#define vis_packfix(rs2,rd) vis_d2s( 0x3d, rs2, rd) -#define vis_expand(rs2,rd) vis_s2d( 0x4d, rs2, rd) -#define vis_pmerge(rs1,rs2,rd) vis_ss2d(0x4b, rs1, rs2, rd) - -/* Partitioned multiply instructions. */ - -#define vis_mul8x16(rs1,rs2,rd) vis_sd2d(0x31, rs1, rs2, rd) -#define vis_mul8x16au(rs1,rs2,rd) vis_ss2d(0x33, rs1, rs2, rd) -#define vis_mul8x16al(rs1,rs2,rd) vis_ss2d(0x35, rs1, rs2, rd) -#define vis_mul8sux16(rs1,rs2,rd) vis_dd2d(0x36, rs1, rs2, rd) -#define vis_mul8ulx16(rs1,rs2,rd) vis_dd2d(0x37, rs1, rs2, rd) -#define vis_muld8sux16(rs1,rs2,rd) vis_ss2d(0x38, rs1, rs2, rd) -#define vis_muld8ulx16(rs1,rs2,rd) vis_ss2d(0x39, rs1, rs2, rd) - -/* Alignment instructions. */ - -static inline const void *vis_alignaddr(const void *_ptr) -{ - register const void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x18) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(1))); - - return ptr; -} - -static inline void vis_alignaddr_g0(void *_ptr) -{ - register void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x18) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(0))); -} - -static inline void *vis_alignaddrl(void *_ptr) -{ - register void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x19) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(1))); - - return ptr; -} - -static inline void vis_alignaddrl_g0(void *_ptr) -{ - register void *ptr __asm__("g1"); - - ptr = _ptr; - - __asm__ volatile(".word %2" - : "=&r" (ptr) - : "0" (ptr), - "i" (vis_opc_base | vis_opf(0x19) | - vis_rs1_s(1) | - vis_rs2_s(0) | - vis_rd_s(0))); -} - -#define vis_faligndata(rs1,rs2,rd) vis_dd2d(0x48, rs1, rs2, rd) - -/* Logical operate instructions. */ - -#define vis_fzero(rd) vis_d( 0x60, rd) -#define vis_fzeros(rd) vis_s( 0x61, rd) -#define vis_fone(rd) vis_d( 0x7e, rd) -#define vis_fones(rd) vis_s( 0x7f, rd) -#define vis_src1(rs1,rd) vis_d12d(0x74, rs1, rd) -#define vis_src1s(rs1,rd) vis_s12s(0x75, rs1, rd) -#define vis_src2(rs2,rd) vis_d22d(0x78, rs2, rd) -#define vis_src2s(rs2,rd) vis_s22s(0x79, rs2, rd) -#define vis_not1(rs1,rd) vis_d12d(0x6a, rs1, rd) -#define vis_not1s(rs1,rd) vis_s12s(0x6b, rs1, rd) -#define vis_not2(rs2,rd) vis_d22d(0x66, rs2, rd) -#define vis_not2s(rs2,rd) vis_s22s(0x67, rs2, rd) -#define vis_or(rs1,rs2,rd) vis_dd2d(0x7c, rs1, rs2, rd) -#define vis_ors(rs1,rs2,rd) vis_ss2s(0x7d, rs1, rs2, rd) -#define vis_nor(rs1,rs2,rd) vis_dd2d(0x62, rs1, rs2, rd) -#define vis_nors(rs1,rs2,rd) vis_ss2s(0x63, rs1, rs2, rd) -#define vis_and(rs1,rs2,rd) vis_dd2d(0x70, rs1, rs2, rd) -#define vis_ands(rs1,rs2,rd) vis_ss2s(0x71, rs1, rs2, rd) -#define vis_nand(rs1,rs2,rd) vis_dd2d(0x6e, rs1, rs2, rd) -#define vis_nands(rs1,rs2,rd) vis_ss2s(0x6f, rs1, rs2, rd) -#define vis_xor(rs1,rs2,rd) vis_dd2d(0x6c, rs1, rs2, rd) -#define vis_xors(rs1,rs2,rd) vis_ss2s(0x6d, rs1, rs2, rd) -#define vis_xnor(rs1,rs2,rd) vis_dd2d(0x72, rs1, rs2, rd) -#define vis_xnors(rs1,rs2,rd) vis_ss2s(0x73, rs1, rs2, rd) -#define vis_ornot1(rs1,rs2,rd) vis_dd2d(0x7a, rs1, rs2, rd) -#define vis_ornot1s(rs1,rs2,rd) vis_ss2s(0x7b, rs1, rs2, rd) -#define vis_ornot2(rs1,rs2,rd) vis_dd2d(0x76, rs1, rs2, rd) -#define vis_ornot2s(rs1,rs2,rd) vis_ss2s(0x77, rs1, rs2, rd) -#define vis_andnot1(rs1,rs2,rd) vis_dd2d(0x68, rs1, rs2, rd) -#define vis_andnot1s(rs1,rs2,rd) vis_ss2s(0x69, rs1, rs2, rd) -#define vis_andnot2(rs1,rs2,rd) vis_dd2d(0x64, rs1, rs2, rd) -#define vis_andnot2s(rs1,rs2,rd) vis_ss2s(0x65, rs1, rs2, rd) - -/* Pixel component distance. */ - -#define vis_pdist(rs1,rs2,rd) vis_dd2d(0x3e, rs1, rs2, rd) - -#endif /* AVCODEC_SPARC_VIS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/sunrast.c b/tizen/distrib/ffmpeg/libavcodec/sunrast.c deleted file mode 100644 index 456ab85..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/sunrast.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image decoder - * Copyright (c) 2007, 2008 Ivo van Poorten - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#define RT_OLD 0 -#define RT_STANDARD 1 -#define RT_BYTE_ENCODED 2 -#define RT_FORMAT_RGB 3 -#define RT_FORMAT_TIFF 4 -#define RT_FORMAT_IFF 5 - -typedef struct SUNRASTContext { - AVFrame picture; -} SUNRASTContext; - -static av_cold int sunrast_init(AVCodecContext *avctx) { - SUNRASTContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; - - return 0; -} - -static int sunrast_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - SUNRASTContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; - unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen; - uint8_t *ptr; - const uint8_t *bufstart = buf; - - if (AV_RB32(buf) != 0x59a66a95) { - av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n"); - return -1; - } - - w = AV_RB32(buf+4); - h = AV_RB32(buf+8); - depth = AV_RB32(buf+12); - type = AV_RB32(buf+20); - maptype = AV_RB32(buf+24); - maplength = AV_RB32(buf+28); - - if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) { - av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); - return -1; - } - if (type > RT_FORMAT_IFF) { - av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); - return -1; - } - if (maptype & ~1) { - av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n"); - return -1; - } - - buf += 32; - - switch (depth) { - case 1: - avctx->pix_fmt = PIX_FMT_MONOWHITE; - break; - case 8: - avctx->pix_fmt = PIX_FMT_PAL8; - break; - case 24: - avctx->pix_fmt = (type == RT_FORMAT_RGB) ? PIX_FMT_RGB24 : PIX_FMT_BGR24; - break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid depth\n"); - return -1; - } - - if (p->data[0]) - avctx->release_buffer(avctx, p); - - if (avcodec_check_dimensions(avctx, w, h)) - return -1; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - 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; - - if (depth != 8 && maplength) { - av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n"); - - } else if (depth == 8) { - unsigned int len = maplength / 3; - - if (!maplength) { - av_log(avctx, AV_LOG_ERROR, "colormap expected\n"); - return -1; - } - if (maplength % 3 || maplength > 768) { - av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); - return -1; - } - - ptr = p->data[1]; - for (x=0; xdata[0]; - stride = p->linesize[0]; - - /* scanlines are aligned on 16 bit boundaries */ - len = (depth * w + 7) >> 3; - alen = len + (len&1); - - if (type == RT_BYTE_ENCODED) { - int value, run; - uint8_t *end = ptr + h*stride; - - x = 0; - while (ptr != end) { - run = 1; - if ((value = *buf++) == 0x80) { - run = *buf++ + 1; - if (run != 1) - value = *buf++; - } - while (run--) { - if (x < len) - ptr[x] = value; - if (++x >= alen) { - x = 0; - ptr += stride; - if (ptr == end) - break; - } - } - } - } else { - for (y=0; ypicture; - *data_size = sizeof(AVFrame); - - return buf - bufstart; -} - -static av_cold int sunrast_end(AVCodecContext *avctx) { - SUNRASTContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec sunrast_decoder = { - "sunrast", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SUNRAST, - sizeof(SUNRASTContext), - sunrast_init, - NULL, - sunrast_end, - sunrast_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/svq1.c b/tizen/distrib/ffmpeg/libavcodec/svq1.c deleted file mode 100644 index d0e1132..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq1.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SVQ1 decoder - * ported to MPlayer by Arpi - * ported to libavcodec by Nick Kurshev - * - * Copyright (C) 2002 the xine project - * Copyright (C) 2002 the ffmpeg project - * - * SVQ1 Encoder (c) 2004 Mike Melanson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sorenson Vector Quantizer #1 (SVQ1) video codec. - * For more information of the SVQ1 algorithm, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - -#include "svq1.h" -#include "svq1_cb.h" -#include "svq1_vlc.h" - -/* standard video sizes */ -const struct svq1_frame_size ff_svq1_frame_size_table[7] = { - { 160, 120 }, { 128, 96 }, { 176, 144 }, { 352, 288 }, - { 704, 576 }, { 240, 180 }, { 320, 240 } -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/svq1.h b/tizen/distrib/ffmpeg/libavcodec/svq1.h deleted file mode 100644 index 3ade05d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq1.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SVQ1 decoder - * ported to MPlayer by Arpi - * ported to libavcodec by Nick Kurshev - * - * Copyright (C) 2002 the xine project - * Copyright (C) 2002 the ffmpeg project - * - * SVQ1 Encoder (c) 2004 Mike Melanson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sorenson Vector Quantizer #1 (SVQ1) video codec. - * For more information of the SVQ1 algorithm, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - -#ifndef AVCODEC_SVQ1_H -#define AVCODEC_SVQ1_H - -#include - -#define SVQ1_BLOCK_SKIP 0 -#define SVQ1_BLOCK_INTER 1 -#define SVQ1_BLOCK_INTER_4V 2 -#define SVQ1_BLOCK_INTRA 3 - -struct svq1_frame_size { - uint16_t width; - uint16_t height; -}; - -uint16_t ff_svq1_packet_checksum (const uint8_t *data, const int length, - int value); - -extern const int8_t* const ff_svq1_inter_codebooks[6]; -extern const int8_t* const ff_svq1_intra_codebooks[6]; - -extern const uint8_t ff_svq1_block_type_vlc[4][2]; -extern const uint8_t ff_svq1_intra_multistage_vlc[6][8][2]; -extern const uint8_t ff_svq1_inter_multistage_vlc[6][8][2]; -extern const uint16_t ff_svq1_intra_mean_vlc[256][2]; -extern const uint16_t ff_svq1_inter_mean_vlc[512][2]; - -extern const struct svq1_frame_size ff_svq1_frame_size_table[7]; - -#endif /* AVCODEC_SVQ1_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/svq1_cb.h b/tizen/distrib/ffmpeg/libavcodec/svq1_cb.h deleted file mode 100644 index 7926ce1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq1_cb.h +++ /dev/null @@ -1,1525 +0,0 @@ -/* - * SVQ1 decoder - * ported to MPlayer by Arpi - * ported to libavcodec by Nick Kurshev - * - * Copyright (C) 2002 the xine project - * Copyright (C) 2002 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * svq1 code books. - */ - -#ifndef AVCODEC_SVQ1_CB_H -#define AVCODEC_SVQ1_CB_H - -#include -#include - -#include "libavutil/mem.h" - -/* 6x16-entry codebook for inter-coded 4x2 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_inter_codebook_4x2)[768] = { - 7, 2, -6, -7, 7, 3, -3, -4, -7, -2, 7, 8, -8, -4, 3, 4, - 19, 17, 9, 3,-14,-16,-12, -8,-18,-16, -8, -3, 11, 14, 12, 8, - 7,-16,-10, 20, 7,-17,-10, 20, -6, 18, 8,-21, -7, 18, 9,-20, - 25, 3,-20,-14, 29, 7,-18,-13,-29, -4, 21, 14,-31, -6, 20, 14, - -19,-26,-28,-24, 31, 32, 22, 10, 15, 24, 31, 28,-32,-32,-22,-13, - 2, -8,-23,-26, -9, 3, 27, 35, 3, 11, 21, 21, 8, -4,-27,-34, - -30,-31, 12, 47,-29,-30, 13, 47, 38, 30,-17,-46, 34, 26,-19,-46, - -42,-50,-51,-43, 34, 48, 55, 48, 48, 54, 51, 42,-44,-52,-53,-47, - 4, 5, 0, -6, -2, -2, 0, 1,-11, -6, -1, -2, 1, 8, 9, 1, - 0, 1, -6, 5, 8, 1,-12, 2, 7,-14, -7, 8, 5, -8, 0, 8, - 1, 4, 11, 8,-12, -8, 0, -5, -1, 1, 0, 4,-15, -8, 3, 16, - 17, 8, -4, -6, 9, -4,-13, -8, 2, 6, 1,-18, -1, 11, 11,-12, - 6, 0, 2, 0, 14, 6, -7,-21, 1, -1,-13,-20, 1, 1, 10, 21, - -22, -5, 7, 13,-11, -1, 4, 12, -7, 0, 14, 19, -4, 3, -5,-19, - -26,-14, 10, 15, 18, 4, -6, -2, 25, 19, -5,-18,-20, -7, 4, 2, - -13, -6, -1, -4, 25, 37, -2,-35, 5, 4, 1, 1,-21,-36, 2, 43, - 2, -2, -1, 3, 8, -2, -6, -1, -2, -3, 2, 12, -5, -2, -2, -1, - -3, -1, -1, -5, -1, 7, 8, -2, 2, 7, 5, -3, 1, 1, -3, -8, - -3, -1, -3, -2, -2, -3, 2, 13, 15, 0,-11, -6, 3, 0, 0, 0, - -6, -9, -5, -4, 18, 4, 1, 3, 12, 3, 0, 4,-16, -3, 3, -3, - -17, 3, 18, 2, -1, -3, -1, -1, -6, 16, -8, 0, -9, 14, -7, 0, - 3,-13, 14, -5, 3,-13, 14, -4, -7, 20, 14,-23, 8, -7, -8, 4, - 8,-15,-19, 16,-10, 13, 11, -3, 9, -1, 1, 26, 5,-15,-27, 2, - -20, 7, 16, -4,-40, 9, 31, 1, 26,-12,-30, -7, 40, -2,-19, 4, - 6, 0, 0, 0, -6, -2, 1, 2, 0, -1, 0, -6, 9, 0, -2, -1, - -7, 8, 2, -3, -1, 2, -3, 2, 7, -4, -2, 4, 2, 0, 0, -6, - -3, -2, 9, 2, -2, -1, 0, -4, -3, -3, 0, -3, -6, 2, 10, 4, - 3, 0,-10, 8, 0, 0, -4, 4, -1, 1, 4, 2, 3, -7, -9, 7, - 2, 1, -9, -4, -1, 12, 0, 0, 3, -1, 7, -4, 3,-14, 4, 2, - -12, -9, 1, 11, 2, 5, 1, 0, 3, 1, 0, 2, 0, 8, 6,-19, - -6,-10, -7, -4, 9, 7, 5, 7, 6, 21, 3, -3,-11, -9, -5, -2, - -4, -9,-16, -1, -2, -5, 1, 36, 8, 11, 19, 0, 2, 5, -4,-41, - -1, -1, -2, -1, -2, -2, 1, 6, 0, 4, 1, -8, 1, 1, 1, 0, - -2, -3, 4, 0, 2, -1, 3, -3, 1, 3, -4, 1, -1, 3, 0, -5, - 3, 4, 2, 3, -2, -3, -6, -1, -2, -3, -2, 2, -4, 8, 1, 0, - -7, 4, 2, 6, -7, -1, 1, 0, -2, 2, -4, 1, 8, -6, 2, -1, - -6, 2, 0, 2, 5, 4, -8, -1, -1,-11, 0, 9, 0, -2, 2, 2, - 17, -5, -4, -1, -1, -4, -2, -2, 0,-13, 9, -3, -1, 12, -7, 2, - 0, -2, -5, 2, -7, -5, 20, -3, 7, 7, -1,-30, 3, 5, 8, 1, - -6, 3, -1, -4, 2, -2,-11, 18, 0, -7, 3, 14, 20, -3,-18, -9, - 7, -2, 0, -1, -2, 0, 0, -1, -4, -1, 1, 0, -2, 2, 0, 4, - 1, -3, 2, 1, 3, 1, -5, 1, -3, 0, -1, -2, 7, 1, 0, -3, - 2, 5, 0, -2, 2, -5, -1, 1, -1, -2, 4, -1, 0, -3, 5, 0, - 0, 3, -1, -2, -4, 1, 5, -1, -1, 0, -1, 9, -1, -2, -1, -1, - -2, 5, 5, -1, -2, 2, -3, -2, 1, 2,-11, 1, 2, 1, 3, 2, - 2,-10, -1, -2, 4, 2, 4, 1, 4, 5, -5, 1, 0, 6,-11, 1, - 1, 0, 6, 6, 0, 2, 1,-15, 7, 3, 5, 9,-30, 2, 2, 2, - -34, 1, 9, 2, 5, 8, 8, 2, 7, 2, 6, 6, 2,-27, 1, 4 -}; - -/* 6x16-entry codebook for inter-coded 4x4 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_inter_codebook_4x4)[1536] = { - 4, 0, -6, -7, -4, -8,-13, -9, -8, -8, -1, 6, -2, 5, 22, 27, - -16, -7, 11, 10,-18, -7, 13, 10,-15, -4, 12, 8, -9, -1, 9, 5, - -2, 2, 15,-16, -3, 2, 19,-19, -3, 2, 19,-19, -2, 3, 15,-14, - 17, 22, 22, 16, -6, -7, -5, -2,-12,-16,-16,-12, 1, 1, -1, -3, - 11,-17, 0, 8, 14,-21, -1, 9, 14,-21, -2, 8, 11,-16, -2, 6, - 7, -2,-16, 11, 9, -2,-21, 14, 10, -1,-22, 14, 8, -1,-18, 10, - -10, 16, 3, -9,-13, 20, 4,-11,-14, 21, 4,-10,-11, 16, 3, -8, - 11, 4, -9, -9, 15, 6,-12,-14, 17, 8,-12,-14, 16, 10, -7,-11, - 4, 10, 14, 13, -1, 7, 15, 16,-12, -7, 3, 8,-20,-23,-18,-10, - -10,-18,-26,-25, 4, 1, -6,-11, 13, 15, 11, 3, 12, 15, 13, 8, - -16,-19,-16,-11, 7, 12, 15, 11, 11, 16, 16, 11, -6, -9,-11,-10, - 18, 19, 12, 5, 18, 16, 5, -4, 6, 0,-10,-15, -9,-17,-23,-22, - -10,-14, -1, 21,-11,-17, 0, 29,-11,-16, 1, 30,-10,-14, 0, 23, - -16,-17,-12, -6,-19,-19,-14, -7, -3, -1, 1, 2, 27, 35, 29, 19, - -37, -8, 23, 23,-42, -9, 28, 29,-43,-10, 26, 28,-38,-11, 19, 22, - 32, 16,-16,-33, 39, 20,-18,-37, 38, 19,-19,-38, 32, 15,-17,-34, - 24, 9, -6, -4, -1,-10, -6, 3, -8, -9, -1, 3, 3, 7, 2, -6, - -1, -3, -1, 0, -1, 4, 2, -7, -3, 11, 3,-16, 1, 20, 9,-18, - -3, -8, 6, 12, -5,-10, 7, 13, -6, -9, 5, 7, -5, -5, 2, -1, - -8, 12, -3, -1,-10, 15, -3, 1,-11, 13, -4, 1,-11, 8, -3, 2, - 9, 6, -5,-12, 3, 0, -8,-13, -4, -4, -1, -1, -4, 1, 15, 18, - 9, 13, 14, 12, 4, 3, -1, -2, -2, -5, -8, -5, -7,-11, -9, -4, - 7, -5, -7, -4, 14, -2, -7, -4, 17, 0, -8, -5, 15, 1, -7, -5, - -10, -1, 6, 4,-15, -9, 2, 4, 2, -1, -3, 0, 25, 13, -8,-10, - 7, 11, -3,-16, 7, 11, -3,-15, 6, 7, -2, -9, 4, 2, -3, -5, - -7, -1, -1, 0, -9, -2, 2, 6,-12, -4, 6, 14,-13, -6, 8, 19, - -18,-18,-11, -5, -3, 0, 3, 4, 6, 8, 6, 6, 6, 6, 6, 6, - -5, 3, 13,-10, -6, 1, 15, -9, -6, -3, 15, -6, -6, -6, 10, -3, - 9, 1, -9, -9, 11, 9, 6, 5, 0, 3, 8, 7,-15,-14, -6, -5, - -11, -6, 11, 19, -2, -5, -9, -8, 6, 2, -9,-10, 6, 5, 4, 5, - -7, -3, 8, 15, -1, 3, 10, 15, 5, 5, -1, -2, 4, -2,-21,-25, - 6, -6, -6, 5, 8, -9, -7, 9, 8,-12, -7, 13, 4,-14, -7, 14, - -4, -3, 1, 1, -3, -5, -2, -3, 7, 0, -2, -4, 20, 7, -4, -4, - -3,-20, -6, 10, 6, 0, 0, 1, 5, 8, 5, -1, -3, 0, 0, -2, - 13, 6, -1, 2, 5, 3, 2, 3, -3, 0, 3, 0,-16, -8, -2, -5, - -2, -7, -6, 0, -3, -6, -3, 1, -5, -1, 2, -1, -1, 12, 16, 5, - -7, 1, 9, 8,-10, -2, 5, 3, -6, 2, 7, 3, -4, 0, -1, -7, - 3, 4, -9,-24, 0, 2, 6, 3, -1, -1, 4, 7, 5, 3, -1, -2, - 3, 6, -9, 2, 1, 6,-13, 1, 1, 8,-10, 2, 1, 8, -7, 1, - -3, -3, 2, 22, -2, -3, -5, 12, -2, -3,-10, 2, -3, -1, -4, 2, - 11, 12, 8, 2, -5, -5, -5, -8, -6, -4, 0, -3, -2, -1, 3, 3, - 12, -6, -2, -1, 12, -8, -2, -2, 9, -7, 0, -3, 4, -6, 2, -2, - -19, 1, 12, -3, -4, 4, 5, -4, 6, 1, -2, -1, 4, -4, -2, 7, - -3, -4, -7, -8, -4, -4, -2, 0, -1, 2, 14, 16, -4, -2, 4, 4, - -1, 7, 2, -5, -2, 0, -1, 1, 4, -3, -1, 13, 6,-12,-14, 8, - -1, 5, 4, -5, -2, 5, 3, -9, -2, 7, 4,-12, -1, 7, 4, -9, - -6, -3, 1, 1, 11, 11, 0, -6, 6, 4, -2, -7,-12,-10, 3, 10, - -2, -3, -3, -2, 6, 11, 14, 10, -9,-11,-10,-10, 2, 2, 3, 2, - -7, -5, -7, -1, -1, 2, 0, 7, -1, 1, 0, 9, 3, 4, -5, -1, - 10, -1,-15, -1, 4, 1, -5, 2, -3, 1, -1, 1, -3, 1, 4, 4, - 2, -1, 4, 10, 6, 2, -1, 0, 2, 2, -7,-12, -4, 2, 0, -3, - -1, -4, -1, -8, 3, -1, 2, -9, 4, 0, 5, -5, 2, 0, 8, 3, - 3, 2, 1, 1, 4, -2, 0, 3, 2, -1, 4, 1, 0, 6, -1,-25, - -1, -2, -2, -4, -3, 0, -1, -4, -1, -1, -4, 2, 0, -6, 2, 25, - -11, -1, 5, 0, 7, 0, -2, 2, 10, -1, -3, 4, -5, -5, -2, -1, - 0, 6, 3, -1, -2, -1, -1, 1, -1, -7,-12, -5, 8, 6, 2, 4, - 2, 6, -1, -6, 9, 10, -1, -4, 1, 0, -4, 0, 3, -2, -9, -5, - -4, 3, 4, 0, -4, 3, 3, 0,-11, 0, 3, 2,-11, 3, 7, 2, - 2, -4, 7, 3, 1, -8, 7, 1, -1,-12, 4, 1, 3, -9, 2, 2, - 2, -2, -2, 9,-17, -3, 3, 1, -4, 7, 1, -6, 5, 4, -1, 3, - -1, 2, 0, -4, -7, 8, 12, -1, -2, 5, 4, -5, 3, -5, -8, -2, - 0, 0, -5, -2, -2, -8, 3, 27, -1, -4, -3, 6, -3, 1, -2, -7, - 4, 4, 1, -1, -7,-10, -7, -3, 10, 10, 5, 3, -2, -2, -4, -3, - 0, 1, 5, 7, 4, -2,-16,-20, 0, 4, 7, 8, 2, 0, -2, -1, - -2, 1, 3, 17, -3, 1, -2, -1, -1, -2, -1, -2, -1, -5, -1, 0, - 5, -3, 1, 0, 6, -2, 0, 0, -1, -2, 0, -3,-11, 1, 8, -1, - 3, 0, 0, 0, 0, 2, 4, 1, 2, 0, 6, 1, -2,-18, -3, 2, - -14, 0, 6, 1, -5, -2, -1, 1, -1, 1, 0, 1, 1, 7, 4, 0, - -1, 0, 1, -4, 1, 8, 3, -4, -3, 4, 1, 3, -6, 1, -4, 1, - 1,-12, 3, 3, -1,-10, 0, -1, 2, 0, 2, 1, 3, 2, 2, 4, - 3, 0, 0, 3, 2, 0, -2, 1, 5, 2, -5, 0, 6, -1,-14, -1, - -2, -6, -3, -3, 2, -1, 4, 5, 6, -1, -2, 0, 4, 4, -1, -5, - -4, 1,-11, 0, -1, 2, -4, 1, 2, -3, 3, -1, 1, -2, 15, 0, - 1, -1, 0, -2, 1, -4, -7, 1, -2, -6, -1, 21, -2, 2, -1, 1, - 21, -1, -2, 0, -1, -3, 1, -2, -9, -2, 2, -1, 2, 1, -4, -1, - 1, 8, 2, -6,-10, -1, 4, 0, -4, -3, 3, 3, 5, 0, -1, -1, - 3, 2, 1, -2, -2, -2, 4, 3, 5, 2, -4,-17, 0, -2, 4, 3, - -7, -4, 0, 3, 9, 9, 2, -1,-11, -6, 0, -1, 5, 1, 0, 1, - 0, 17, 5,-11, 3, -2, -6, 0, 2, -2, -4, 1, -4, 1, 2, -1, - -5, -1, -5, -3, -3, 5, -3, -2, 4, 16, 2, -5, -2, 5, -1, -1, - 0, 0, -4, 1, -1, 2, 5, 11, -1, -1, -2, 1, -4, -2, -3, -1, - -5, -1, 10, 0, 6, 1, 0, -3, 0, -4, 1, 0, -2, -4, 3, -1, - 6, 9, 3, 0, -2, 1, -2, 0, -2, -3, -2, -2, 1, 0, 1, -6, - 1, 0, 2, 1, -1, 3, -2, 1, 0, -1,-15, 0, -1, 5, 2, 6, - 2, 0, 2, 2, 0,-12, -4, 6, 0, 1, 4, -1, 1, 2, 1, -4, - 1, -2, -7, 0, 0, 0, 0, -1, -5, 2, 11, 3, 1, 3, 0, -6, - 0, -3, -9, -4, 1, 3, -1, 0, 4, 1, -2, 0, 7, -3, -1, 6, - 1, -2, 6, 2, 0, -1, 3, -2, -2, 4, 0, 2, -1, 2,-14, 2, - 2, 2, 0, -1, -2, 3, -3,-14, 0, 2, 3, -3, 5, 1, 3, 2, - 1, -3, 4,-14, 1, -2, 11, -1, 0, -1, 3, 0, -1, 1, 0, 2, - -2, 3, -3, 2, -4, -1, -4, 3, -1, 2, 1, 3, -6, -2, 2, 7, - -2, 1, 2, 0, -2, 0, 0, -1, 12, 5, -1, 2, -8, -1, 1, -7, - 2, -2, -4, 2, 11, 0,-11, -2, 3, 1, -3, -1, 0, 3, 1, -1, - 0, 3, 0, -2, 0, -6, -1, -3, 12, -7, -2, 0, 7, -2, 1, 1, - 1, 2, 2, 2, -1, 2, 0, 2,-23, 0, 4, 0, 3, 2, 1, 3, - -4, -5, -1, 5, -3, 5, 10, -1, 0, 0, 3, -4, 1, -1, 2, -5 -}; - -/* 6x16-entry codebook for inter-coded 8x4 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_inter_codebook_8x4)[3072] = { - 9, 8, 4, 0, -3, -4, -4, -3, 9, 8, 4, -1, -4, -5, -5, -3, - 8, 7, 3, -2, -5, -5, -5, -4, 6, 4, 1, -2, -4, -5, -4, -3, - -12,-14,-11, -4, 1, 5, 6, 6, -8,-10, -7, -5, -2, 1, 1, 1, - 5, 4, 3, 1, 0, 0, -1, -1, 13, 13, 9, 6, 3, 0, -1, -2, - -4, -4, -3, -1, 1, 4, 8, 11, -5, -6, -4, -2, 0, 3, 8, 12, - -7, -7, -6, -4, -2, 2, 7, 10, -7, -7, -5, -4, -2, 1, 5, 8, - -3, -2, -1, 1, 3, 6, 7, 6, 2, 3, 5, 7, 8, 8, 6, 4, - 4, 5, 4, 3, 1, -2, -6, -7, 1, 0, -2, -7,-10,-14,-17,-16, - -5, -4, 1, 8, 9, 3, -3, -7, -7, -6, 1, 11, 12, 5, -3, -8, - -8, -7, 0, 9, 11, 5, -3, -7, -8, -6, -1, 5, 8, 4, -2, -6, - -4, -5, -7, -8, -9, -9, -8, -6, -4, -5, -6, -7, -7, -6, -4, -2, - 0, 1, 2, 3, 5, 8, 10, 9, 1, 2, 3, 6, 9, 12, 14, 13, - 5, 6, 6, 5, 4, 3, 2, 1, 5, 6, 7, 7, 6, 6, 6, 4, - -1, 0, 1, 1, 3, 5, 5, 5,-13,-16,-17,-17,-14,-10, -6, -4, - 9, 11, 13, 16, 15, 13, 12, 10, -4, -5, -6, -7, -7, -7, -6, -5, - -6, -6, -7, -7, -7, -7, -6, -5, -2, -1, 0, 0, 0, 0, 0, -1, - -11,-13,-15,-16,-16,-14,-12,-10, 2, 3, 4, 5, 4, 3, 3, 3, - 6, 7, 8, 8, 8, 7, 6, 5, 3, 4, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 1, -2, -7,-13,-17, 5, 7, 7, 5, 1, -5,-13,-19, - 6, 8, 9, 8, 5, -1, -9,-16, 6, 8, 10, 10, 7, 2, -4,-11, - 18, 9, -1,-10,-13, -9, -4, 0, 22, 12, -1,-12,-15,-10, -4, 2, - 23, 13, 0,-10,-13, -9, -3, 2, 20, 12, 2, -6, -9, -6, -2, 2, - -6, -6, -6, -7, -7, -7, -7, -6, -6, -7, -8, -8, -9, -9, -9, -8, - -3, -3, -3, -3, -3, -3, -3, -3, 12, 15, 18, 21, 21, 19, 17, 14, - 14, 16, 18, 18, 18, 16, 15, 13, 5, 6, 6, 5, 5, 4, 4, 3, - -6, -7, -9,-10,-10,-10, -9, -7,-10,-11,-13,-14,-14,-13,-12,-10, - -27,-17, -4, 5, 9, 10, 10, 7,-32,-19, -3, 7, 11, 12, 11, 8, - -30,-16, -2, 8, 12, 12, 10, 7,-23,-12, 0, 7, 10, 11, 9, 6, - 16, 17, 16, 12, 6, -1, -8,-12, 17, 18, 15, 10, 1, -8,-15,-18, - 15, 14, 10, 4, -5,-14,-20,-23, 10, 8, 4, -1, -9,-16,-21,-22, - -10,-12,-12,-11, -5, 4, 14, 20,-11,-13,-15,-12, -4, 7, 19, 27, - -11,-13,-14,-11, -3, 8, 21, 28,-10,-11,-12, -9, -2, 8, 18, 25, - -1, -1, -1, 1, 4, 6, 6, 5, 0, 0, 0, 2, 4, 3, 1, -2, - 0, 0, 2, 4, 4, -1, -7,-10, 0, 0, 3, 5, 3, -3,-11,-15, - -14,-13, -8, -1, 3, 3, -1, -4, -5, -4, -1, 4, 8, 8, 3, 0, - 3, 2, 2, 3, 4, 5, 3, 1, 5, 3, 0, -2, -2, -1, -1, -1, - 9, 1, -6, -6, -5, -3, -2, -1, 12, 1, -6, -6, -4, -2, -1, 0, - 14, 4, -4, -4, -2, -2, -1, -1, 14, 6, -1, -1, -1, -1, -1, -1, - 4, 6, 8, 10, 11, 9, 7, 5, -1, -1, -1, 0, 0, -1, -1, -2, - -2, -4, -4, -5, -5, -5, -5, -4, -2, -3, -3, -4, -4, -3, -2, -1, - 2, 3, 4, 4, 3, 1, 0, 0, -1, 1, 4, 5, 6, 5, 4, 3, - -8, -6, -2, 2, 3, 4, 4, 3,-14,-13, -9, -5, -2, -1, 0, 0, - -3, -4, -5, -4, 0, 7, 12, 13, -3, -4, -5, -5, -2, 4, 9, 10, - -2, -3, -4, -5, -4, -1, 3, 4, -1, -1, -2, -3, -3, -2, 0, 1, - 9, 5, -2, -8,-11,-10, -7, -4, 12, 10, 6, 2, 0, -1, 0, 0, - 2, 2, 3, 4, 3, 1, 1, 1, -9, -8, -4, 0, 1, 2, 1, 0, - 6, 8, 8, 5, 1, -5,-11,-13, 0, 1, 2, 2, -1, -4, -8,-11, - -3, -2, 1, 3, 3, 1, -1, -4, -2, -1, 2, 5, 6, 6, 4, 1, - 3, 4, 5, 5, 4, 1, -3, -6, 5, 6, 4, 2, 2, 2, 0, -3, - 6, 5, 0, -5, -5, -2, -1, -2, 7, 4, -3,-11,-12, -7, -3, -2, - 1, 0, -1, -1, -1, 0, 0, 0, 2, 3, 4, 4, 5, 5, 4, 3, - -7, -9, -9,-10,-10, -9, -7, -6, 3, 4, 5, 6, 5, 5, 5, 5, - -7, -7, -7, -7, -6, -6, -5, -4, -5, -4, -3, -1, -1, -1, 0, 0, - -3, -2, 1, 4, 5, 5, 5, 5, -2, -1, 3, 6, 9, 10, 10, 9, - -14, 1, 10, 3, -2, 0, 1, 1,-16, 2, 13, 3, -3, -1, 1, 0, - -15, 2, 12, 3, -4, -2, 1, 1,-10, 3, 10, 2, -3, -1, 1, 1, - 0, 1, 4, 2, -5,-10, -3, 11, -1, 1, 4, 2, -6,-13, -2, 15, - -1, 0, 3, 1, -6,-12, -1, 15, -1, 1, 2, 1, -4, -8, 0, 11, - 10, 5, -2, -2, 2, 5, 1, -4, 7, 0, -8, -6, 1, 5, 2, -4, - 2, -5,-12, -7, 2, 7, 4, -1, -1, -7,-10, -4, 4, 9, 7, 2, - -5, -5, -4, -6, -6, -5, -5, -3, -1, -2, -2, -4, -5, -6, -5, -4, - 6, 7, 7, 4, 0, -2, -3, -3, 13, 14, 13, 10, 5, 1, -1, -2, - 1, 1, 2, 2, 2, 2, 2, 2, -5, -6, -8, -9, -9, -8, -7, -6, - 7, 9, 10, 11, 11, 9, 7, 5, -1, -2, -3, -3, -4, -4, -4, -3, - -1, -1, 0, 0, 0, 0, -1, -1, -3, -3, -4, -5, -4, -3, -3, -2, - 2, 1, -1, -3, -3, -2, -1, 0, 12, 12, 8, 3, 1, 0, 0, 1, - -6, -8, -8, -6, -2, 2, 6, 8, 1, 1, -1, -2, 0, 3, 5, 7, - 3, 3, 1, -1, -1, 0, 0, 2, 0, 1, 0, -1, -1, -1, -2, -1, - 1, 0, 0, 0, 0, 0, 2, 4, 2, 1, 3, 4, 3, 1, 0, 2, - 2, 1, 0, 0, -1, -1, 0, 3, 5, 1, -6,-12,-13, -8, -1, 4, - -2, 0, -1, -2, -1, 0, 2, 3, -6, -3, -2, 0, 1, 1, 1, 1, - -9, -5, 0, 4, 5, 3, 1, 0, -8, -3, 3, 7, 8, 4, 1, 0, - 1, 2, 2, 3, 3, 1, -1, -3, 4, 5, 5, 6, 6, 5, 2, 0, - 0, 0, 0, 0, 1, 0, -2, -4, -3, -3, -4, -3, -3, -4, -7, -8, - 14, 12, 6, -1, -3, -3, 0, 0, 7, 5, 1, -3, -5, -4, -2, -1, - -2, -2, -2, -2, -2, -2, -1, -1, -6, -4, -1, 1, 1, 1, 0, -1, - 2, 2, 1, -3, -6, -7, -6, -3, 1, 0, -1, -3, -2, 1, 4, 6, - 0, 0, 1, 2, 4, 7, 8, 7, 0, 0, 0, 0, -1, -4, -7, -8, - 0, 2, 1, -2, -3, -3, -2, -1, -1, 1, 0, -3, -5, -2, 0, 2, - -2, -1, -2, -5, -4, 1, 6, 9, -3, -2, -3, -4, -2, 5, 11, 13, - -4, -2, 2, 6, 4, -3,-10,-14, -2, -1, 1, 4, 4, 1, -1, -2, - 0, 0, -1, -2, -2, 0, 4, 6, 2, 2, 0, -3, -3, 0, 5, 9, - -4, -4, -2, 1, 6, 9, 3, -7, -2, -2, -2, -1, 4, 8, 0,-11, - 1, 1, 0, 0, 2, 6, -1,-10, 2, 2, 1, 0, 2, 4, 0, -7, - -1, -2, -3, -6, -7, -8, -8, -8, 2, 3, 3, 1, -1, -2, -3, -4, - 5, 5, 5, 4, 3, 2, 0, -1, 3, 3, 3, 3, 2, 2, 1, 1, - 3, 3, 2, -2, -3, 0, 7, 10, 1, 2, 2, -2, -5, -4, 0, 3, - 0, 3, 4, 2, -3, -5, -6, -4, 0, 2, 4, 4, 1, -4, -7, -7, - 2, 4, 5, 5, 5, 5, 6, 6, -4, -4, -3, -5, -5, -3, -3, -2, - -3, -4, -4, -5, -4, -2, -2, -2, 1, 1, 0, 0, 2, 4, 5, 4, - -2, 0, 3, 4, 4, 3, 2, 2, -9, -7, -4, 0, 3, 6, 6, 6, - -5, -5, -3, -2, 0, 1, 3, 4, 5, 5, 2, -2, -4, -6, -5, -3, - 1, -6, -4, 7, 5, -2, -2, 1, 5, -5, -4, 6, 4, -5, -4, 1, - 5, -5, -4, 6, 4, -5, -3, 1, 1, -7, -3, 8, 7, -1, -3, 1, - -8, -7, -4, 0, 2, 4, 5, 5, 5, 6, 5, 2, -1, -5, -7, -7, - 5, 6, 4, 1, -3, -5, -6, -5, -7, -7, -5, -2, 1, 6, 9, 10, - 6, 3, 0, 1, 3, 0, -8,-14, 3, 0, -1, 1, 4, 3, 0, -4, - 1, 0, 0, 1, 2, 1, 1, 1, -1, -1, 1, 2, 1, -1, -1, 0, - 1, 1, 1, 1, 0, -2, -3, 0, 1, 2, 1, 0, -2, -8, -9, -4, - 1, 3, 3, 2, 1, -3, -3, 1, 0, 1, 1, 1, 1, 1, 4, 8, - 2, 5, 9, 7, 2, -1, -1, 1, -4, -1, 1, 0, -3, -4, -1, 2, - -3, 0, 3, 3, 0, -1, 0, 2, -4, -1, 1, 1, -2, -4, -5, -4, - 1, -1, -2, -2, -1, 2, 4, 5, 2, 1, 1, 0, -1, -1, 0, 0, - 2, 3, 4, 5, 4, 2, 1, 0, -9, -9, -6, -3, -1, -1, -1, -1, - -6, -6, 4, 7, 0, -2, -1, -2, -1, -2, 5, 6, -1, -2, 0, -1, - 4, -1, 1, 0, -4, -2, 0, -2, 7, 1, -1, -2, -3, 1, 3, 1, - 4, 2, 1, 3, 3, 1, 1, 2, 2, -2, -4, 0, 3, 1, 0, 0, - 1, -4, -8, -4, 1, 2, 1, 0, 2, -3, -9, -6, 0, 3, 3, 2, - -1, -1, 0, -1, -1, 0, 1, 2, 3, 1, -4, -8, -7, -3, 1, 2, - 2, -1, -3, -2, -1, 0, 1, 0, -1, 0, 5, 11, 9, 3, -1, -3, - -1, -2, -2, -1, 1, 1, 1, 1, 0, -1, 0, 3, 6, 6, 5, 5, - 2, 1, -1, -1, -2, -5, -6, -4, 2, 2, 2, 1, -1, -4, -5, -5, - -1, -3, -6, -7, -6, -4, -1, 1, 5, 5, 3, 4, 4, 3, 4, 5, - -1, -2, -3, -2, -2, -2, 0, 1, 0, 0, 0, 0, 0, 1, 2, 3, - -6, -6, -4, -1, 2, 2, 2, 2, -6, -7, -5, -2, 0, -1, -1, 0, - 2, 2, 2, 4, 4, 3, 3, 4, 2, 1, 0, -1, 0, 0, 2, 4, - 12, 5, -5, -8, -5, 0, 2, 2, 2, -3, -6, -3, 0, 0, -1, -2, - -2, -3, -1, 3, 4, 1, -2, -3, 2, 2, 3, 4, 3, 1, -1, -1, - 3, 2, 1, 0, 1, 4, 3, 0, 4, 3, 0, -5, -6, 0, 3, 3, - 2, 3, 1, -7,-12, -6, 1, 3, 1, 3, 4, -1, -6, -4, 0, 1, - -9, -4, 2, 6, 7, 4, 1, 0, -7, -1, 4, 6, 4, 0, -3, -3, - -6, 0, 4, 4, 1, -2, -3, -2, -4, 1, 3, 2, 0, -2, -1, 0, - 0, 5, 2, -5, -3, 3, 1, -4, -2, 4, 2, -6, -3, 6, 4, -3, - -1, 5, 3, -5, -1, 7, 3, -4, -1, 2, 0, -6, -3, 5, 3, -3, - -8, -3, 3, 5, 3, 1, -2, -2, 2, 4, 4, -2, -4, -3, 1, 3, - 2, 1, -3, -5, -3, 3, 4, 3, -5, -6, -5, 3, 10, 8, -1, -5, - 0, 3, 2, -4, -9, -7, 0, 6, -5, -1, 5, 7, 4, -1, -3, -3, - -5, -5, -2, 3, 6, 5, -1, -4, 9, 6, 0, -4, -2, 1, 1, -1, - -1, -1, -1, 1, 1, 0, -1, 0, -1, 0, 0, 0, 0, -1, -1, 0, - 2, 1, -2, -1, 1, 1, 0, 0, 12, 8, 2, -1, -1, -4, -7, -7, - 2, 1, 3, 6, 7, 4, 2, 0, 1, 0, -1, 0, -1, -4, -7, -8, - 0, 0, -1, 0, 0, 0, -1, -3, 0, 0, 0, 0, 1, 1, 0, -2, - -1, 0, 1, 1, 0, 0, -1, -2, 0, 0, -1, -3, -4, -3, -1, 1, - -1, 0, 0, 0, 1, 4, 10, 12, -1, 0, -2, -2, -3, -3, -1, 1, - -3, -1, -2, -4, 2, 9, 9, 7, -3, 0, -1, -3, 0, 2, -1, 1, - -1, 1, -2, -3, 0, -1, -3, 0, 0, 0, -3, -2, 0, -1, -1, 1, - -1, -2, -1, -1, -2, -1, -1, -2, 2, -1, -2, -1, 0, 1, 0, -2, - 3, -1, -2, 2, 5, 3, -1, -3, 1, -5, -5, 1, 6, 6, 2, 0, - 1, 2, 0, -1, 0, 1, 0, -2, -5, -3, -1, 0, 1, 2, 1, -2, - -7, -5, -2, -2, -2, -2, 0, 1, -1, 0, 1, 1, 0, 3, 9, 12, - 0, 6, 5, 1, -2, -3, 0, 3, 0, 6, 5, 1, 1, 1, 2, 3, - -5, -2, -2, -3, 0, 0, 0, 0, -6, -3, -3, -2, 0, 0, -1, -2, - 4, 4, 2, 1, 0, -1, -1, 0, -2, -2, 0, 1, 2, 1, 1, 0, - 2, 2, 1, -1, -3, -5, -9,-10, 2, 1, -1, -1, 1, 4, 4, 1, - 4, 0, -2, -2, -2, -2, -1, 0, 7, 1, -4, -3, -2, 0, 1, 1, - 10, 5, -1, -2, 0, 1, 1, 0, 5, 1, -3, -4, -3, -1, -1, -2, - 2, 1, -1, -3, -3, 1, 1, -1, -2, -1, 3, 0, -1, 1, 1, 0, - -3, 1, 7, 2, -3, -2, -1, 0, -2, 4, 8, -1, -8, -5, 0, 2, - -4, -1, 1, 2, 1, -3, -4, -2, -5, -3, -2, 1, 4, 4, 4, 6, - -3, -2, -4, -3, 0, 1, 1, 2, 2, 2, 2, 1, 2, 1, -1, -1, - -4, -1, 0, -1, -3, -3, -1, -1, 1, 4, 4, 2, 0, -1, -2, -3, - 4, 6, 5, 3, 2, 1, -2, -4, 0, 1, 1, 1, 1, -1, -4, -6, - 1, 2, 2, -1, -6, -5, -1, 2, -3, -2, 1, 1, -4, -3, 2, 5, - -2, -1, 2, 2, -3, -4, 0, 3, -2, -2, 2, 6, 5, 2, 1, 2, - 2, -3, -3, 0, 0, 2, 3, 1, 3, -1, 1, 3, 1, 2, -1, -5, - -5, -7, -4, -2, 1, 8, 8, 1, -1, 0, 2, 0, -3, 0, 1, -3, - -2, -5, -5, -2, -3, -1, 0, -2, -1, -4, 0, 4, 0, 2, 4, 0, - 0, 0, 8, 10, 2, 1, 3, -1, -4, -3, 2, 3, -3, -3, 1, -1, - 1, -2, -4, 2, 7, 3, -2, -1, 6, 4, -2, -1, 2, 0, -1, 3, - 1, 1, -2, -2, -2, -5, -3, 4, -6, -2, 1, 1, -1, -4, -2, 4, - -2, -1, -2, -2, 0, 1, 0, -2, -1, 1, 0, -1, 0, 0, -1, -3, - 0, 1, -2, -4, -3, -1, 0, 0, 6, 8, 5, 0, 0, 1, 2, 3, - -2, -2, 2, 5, 2, 0, 0, 1, 2, -2, -2, -1, -1, 1, 2, 4, - 2, -1, 0, 1, 0, 0, 0, 1, -8, -7, -1, 1, -1, -1, 1, 3, - 0, 3, 6, 2, -2, 1, 2, 0,-10, -7, -1, 0, -3, -1, 2, 1, - 0, 0, 2, 2, 1, 1, 1, -1, 3, 0, -2, -2, 0, 2, 1, 0, - 8, 1, 0, 0, -2, -3, -1, 0, 2, -2, 2, 5, 1, -2, -1, 1, - -3, -6, -3, -1, -3, -3, -1, 2, 2, 0, 1, 2, 2, 1, 0, 0, - 1, -1, -1, -2, -1, 0, 1, 0, 15, 9, 2, -1, -2, -3, -3, -3, - 0, -3, -2, 0, 0, -1, -1, -1, 1, 0, 1, 0, 0, -1, -1, -1, - 0, 2, 2, -2, -3, -3, -7, -8, 0, 2, 2, 0, 1, 2, 1, 1, - 1, 2, 2, 2, 3, 1, 0, 3, 1, 0, -1, -2, -1, -2, 0, 5, - -11, -6, -1, 1, 2, 3, 1, -3, 1, 4, 3, -1, -2, 1, 2, -1, - 2, 2, 1, -1, -2, 0, 1, -1, 0, 0, -1, -1, 0, 2, 3, 2, - 1, 1, 2, 1, -1, 1, 0, -4, 0, 0, 0, -2, -2, 2, 4, -2, - -2, -3, 0, 0, -1, 2, 1, -6, 0, 2, 5, 5, 3, 2, -1, -7, - 4, 2, 0, 0, 3, 3, 1, -1, 0, -1, -1, 3, 6, 4, 1, -1, - -2, -2, 0, 2, 2, 0, -2, -2, -1, 0, -1, -5, -7, -5, -1, 1, - 5, -1, -2, 0, 2, 4, 2, -5, 0, -5, -2, 2, 1, 2, 0, -6, - 6, 1, 0, 1, -2, -1, 4, 2, 2, -3, -3, 0, -1, -2, 0, 0, - 1, -1, 0, 2, 0, 0, 6, 11, 2, -1, -1, 0, -3, -2, 3, 5, - 0, -2, -1, 0, -1, 0, 0, -3, 1, -1, -1, -1, -2, -1, -3, -7, - 1, 1, -2, -2, 1, 3, 1, -2, -1, 2, 0, -1, -1, 1, 0, 0, - -4, 2, 3, -1, -2, -2, 0, 1,-11, -2, 4, 5, 6, 2, -1, -2, - -6, -2, 1, -1, -3, -4, 1, 9, -3, 0, 3, 3, 2, -3, -3, 3, - 1, 1, 0, 0, 1, -1, -2, 3, 2, 0, -3, -3, 0, -1, -1, 3, - 1, -1, -3, 1, 2, -6, -4, 6, 0, -2, -5, -2, 0, -3, -2, 3, - 2, 2, 1, -2, -2, 1, 2, -1, -1, 1, 1, -2, -1, 6, 7, -1, - 1, 0, -4, -2, 1, -2, -3, 1, -4, 0, -3, -2, 2, 0, -3, 0, - -3, 4, 3, 1, 8, 7, 0, -1, -3, 4, 1, -4, 2, 3, -2, -3, - -3, 6, 1, -4, 1, 1, -1, -1, -2, 4, -3, -3, 3, 0, -1, -1, - 1, 2, -4, 2, 4, -3, -1, 2, 3, -1, -4, 5, 4, -6, -3, 2 -}; - -/* 6x16-entry codebook for inter-coded 8x8 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_inter_codebook_8x8)[6144] = { - -4, -3, 4, 5, 2, 1, 1, 0, -5, -3, 5, 5, 2, 1, 0, 0, - -6, -4, 5, 5, 2, 1, 0, 0, -7, -4, 4, 5, 2, 1, 0, 0, - -8, -5, 3, 4, 2, 1, 0, 0, -8, -6, 3, 4, 1, 1, 1, 0, - -8, -6, 2, 4, 2, 1, 1, 0, -8, -6, 2, 4, 1, 1, 1, 1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, - -2, -3, -3, -3, -3, -3, -3, -3, -2, -3, -3, -3, -3, -3, -4, -3, - -2, -2, -2, -2, -2, -3, -3, -2, 1, 1, 1, 1, 1, 0, -1, -1, - 4, 5, 5, 5, 4, 3, 3, 2, 7, 7, 8, 8, 8, 7, 6, 5, - 2, 1, 2, 4, 4, 0, -4, -6, 1, 1, 2, 5, 5, 1, -5, -7, - 1, 2, 1, 4, 5, 1, -5, -8, 1, 1, 1, 5, 5, 0, -6, -8, - 0, 1, 1, 5, 6, 1, -6, -9, 0, 0, 1, 4, 5, 0, -5, -8, - 0, 0, 1, 4, 5, 0, -5, -7, 0, 0, 1, 4, 4, 1, -4, -7, - 1, 2, 3, 0, -3, -4, -3, -1, 1, 3, 4, 0, -3, -4, -3, -1, - 2, 4, 5, 1, -3, -4, -3, -2, 2, 5, 6, 1, -3, -5, -4, -2, - 3, 6, 6, 1, -3, -5, -4, -2, 3, 6, 6, 1, -3, -5, -4, -2, - 3, 6, 6, 1, -3, -5, -4, -2, 3, 5, 5, 1, -3, -4, -4, -2, - 2, 2, 2, 2, 1, 0, 0, -1, 4, 4, 4, 3, 2, 1, 1, 0, - 4, 5, 4, 4, 3, 3, 2, 1, 4, 4, 4, 4, 4, 3, 2, 2, - 2, 3, 3, 3, 3, 3, 2, 1, -1, -1, -1, -1, 0, 0, 0, 0, - -5, -6, -6, -5, -5, -4, -3, -3, -7, -9, -9, -8, -7, -6, -6, -5, - 6, 6, 6, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2, - 0, -1, -1, -1, -2, -2, -1, -1, -3, -5, -6, -6, -6, -6, -5, -4, - -3, -5, -6, -7, -6, -6, -5, -4, -1, -2, -2, -2, -2, -2, -1, -1, - 0, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 1, -2, -5, -4, 0, 2, 5, 2, 1, -2, -6, -5, 0, 3, 5, - 2, 1, -2, -6, -6, -1, 3, 6, 3, 2, -2, -7, -6, 0, 4, 7, - 2, 1, -2, -7, -5, 0, 5, 7, 2, 1, -2, -6, -5, 0, 4, 7, - 2, 1, -2, -6, -4, 0, 4, 6, 1, 1, -2, -5, -4, 0, 3, 6, - -10, -9, -6, -4, -1, 2, 3, 2,-10, -9, -5, -3, 0, 4, 4, 3, - -9, -7, -3, -1, 2, 5, 5, 3, -7, -5, -2, 0, 3, 5, 5, 3, - -6, -3, 0, 1, 4, 6, 5, 3, -4, -2, 1, 2, 3, 5, 4, 2, - -2, 0, 1, 2, 2, 4, 3, 1, -1, 1, 2, 2, 2, 3, 3, 1, - -4, -5, -5, -6, -6, -6, -6, -5, -3, -3, -4, -4, -4, -4, -4, -4, - 0, 0, 0, 0, -1, -1, -1, -1, 5, 5, 6, 5, 5, 4, 3, 2, - 5, 6, 7, 7, 7, 6, 5, 4, 3, 3, 4, 4, 4, 4, 3, 2, - 0, -1, 0, 0, -1, -1, 0, -1, -3, -3, -4, -4, -4, -4, -3, -3, - 1, -2, -5, 1, 5, 4, 2, 0, 1, -3, -6, 1, 6, 5, 2, 0, - 0, -4, -7, 0, 6, 6, 2, 1, -1, -5, -9, -1, 6, 6, 3, 1, - -1, -6,-10, -2, 6, 6, 3, 1, -1, -6, -9, -2, 5, 6, 3, 1, - -2, -6, -9, -2, 5, 5, 3, 1, -2, -6, -7, -2, 4, 4, 2, 1, - -5, -7, -8, -9, -9, -8, -7, -6, -5, -6, -6, -7, -7, -6, -6, -5, - -3, -3, -3, -4, -5, -5, -4, -4, -1, 0, 0, -1, -1, -1, -1, -1, - 0, 1, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 5, 5, 5, 4, - 3, 4, 5, 6, 8, 8, 8, 7, 3, 4, 5, 6, 7, 7, 7, 6, - 5, 6, 7, 8, 9, 10, 10, 9, 3, 4, 6, 7, 8, 9, 9, 8, - 0, 1, 2, 3, 4, 5, 5, 5, -1, -2, -1, -1, 0, 1, 2, 2, - -2, -3, -3, -3, -3, -2, -1, 0, -3, -4, -5, -5, -5, -5, -5, -4, - -4, -5, -5, -6, -7, -7, -6, -5, -3, -4, -5, -6, -7, -7, -6, -6, - 13, 7, 0, -3, -3, -4, -4, -5, 14, 7, 0, -3, -3, -4, -4, -4, - 15, 8, -1, -4, -4, -4, -5, -4, 15, 8, -1, -4, -4, -5, -4, -3, - 15, 7, -1, -4, -5, -5, -5, -4, 14, 7, -1, -4, -4, -4, -4, -3, - 12, 6, -1, -4, -4, -4, -4, -3, 11, 5, -1, -4, -4, -4, -4, -3, - -17, -4, 5, 4, 4, 4, 3, 3,-18, -5, 5, 4, 4, 4, 3, 3, - -19, -5, 6, 4, 4, 4, 3, 2,-20, -5, 6, 4, 4, 4, 3, 3, - -20, -4, 6, 4, 4, 5, 3, 3,-19, -5, 6, 4, 4, 5, 3, 3, - -18, -4, 5, 4, 4, 4, 3, 2,-17, -5, 4, 3, 4, 4, 3, 3, - -6, -6, -6, -4, -2, 1, 6, 11, -6, -7, -7, -4, -2, 2, 8, 13, - -8, -8, -7, -4, -2, 3, 9, 14, -8, -8, -7, -5, -1, 4, 10, 16, - -8, -8, -7, -5, -1, 4, 10, 17, -8, -8, -7, -4, 0, 5, 10, 16, - -8, -8, -6, -3, 0, 4, 9, 15, -7, -7, -5, -3, 0, 4, 8, 12, - 8, 7, 7, 5, 2, -2, -8,-14, 8, 8, 7, 5, 2, -2, -8,-15, - 8, 8, 7, 5, 1, -3, -9,-16, 8, 8, 7, 5, 1, -3,-10,-17, - 8, 9, 8, 5, 1, -3,-10,-17, 8, 8, 7, 4, 1, -4,-10,-16, - 7, 7, 7, 4, 1, -3, -9,-14, 6, 7, 6, 3, 0, -3, -9,-13, - 5, 1, -4, -4, -3, -1, 0, 0, 7, 2, -3, -3, -2, -1, 1, 0, - 7, 1, -3, -3, -1, 0, 1, 1, 6, 1, -3, -2, -1, 1, 1, 0, - 6, 0, -4, -2, -1, 0, 1, 0, 5, 0, -4, -3, -1, 0, 0, -1, - 5, 0, -3, -1, 0, 0, 0, -2, 4, 1, -2, -1, 0, 1, 0, -1, - 2, 2, 1, 1, -2, -6, -8, -8, 1, 1, 1, 1, -2, -5, -8, -8, - 1, 1, 1, 0, -1, -3, -5, -5, 0, 0, 0, 0, -1, -1, -1, -2, - 0, -1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 3, 2, - 2, 1, 1, 1, 2, 3, 4, 3, 3, 3, 3, 3, 4, 4, 5, 4, - -4, -4, -3, -2, 0, 0, 1, 1, -4, -4, -3, -2, -1, 0, 0, 1, - -2, -2, -2, -1, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1, - 2, 2, 2, 2, 2, 2, 1, 1, 3, 4, 4, 4, 4, 4, 4, 3, - 1, 1, 1, 3, 3, 4, 3, 3, -5, -6, -5, -4, -3, -3, -2, -2, - -4, -2, -1, -1, -1, -1, 0, 1, -4, -2, -1, -1, -1, -1, 0, 1, - -3, -2, -1, -1, -1, 0, 1, 2, -4, -3, -2, -1, -1, 1, 3, 3, - -4, -3, -3, -1, -1, 1, 4, 5, -4, -3, -2, -2, -1, 1, 4, 7, - -2, -2, -1, -1, 0, 2, 6, 8, -1, 0, 0, 1, 1, 4, 7, 8, - -3, -3, -3, -2, -2, -1, -1, 0, -1, -1, 0, 1, 2, 2, 3, 3, - 0, 1, 2, 4, 5, 6, 6, 5, -1, 0, 2, 3, 5, 6, 5, 3, - -1, -1, 0, 2, 3, 3, 2, 1, -2, -2, -1, 0, -1, -3, -4, -4, - 0, 0, -1, -1, -2, -4, -8, -7, 1, 2, 1, 0, -1, -4, -6, -7, - -2, 4, 1, -6, 0, 3, 0, 0, -2, 5, 1, -7, 0, 3, 0, 0, - -3, 5, 1, -8, 0, 3, -1, -1, -2, 6, 1, -9, 0, 3, 0, -1, - -2, 6, 2, -8, 0, 4, 0, -1, -3, 5, 1, -7, 1, 4, 0, 0, - -2, 4, 1, -7, 0, 4, 1, 0, -1, 4, 1, -6, 0, 3, 1, 0, - 0, 0, 0, 3, 4, 5, 4, 1, 1, 1, 1, 2, 3, 3, 2, 0, - 2, 2, 1, 2, 2, 1, -1, -2, 4, 3, 1, 1, 0, -1, -3, -5, - 5, 3, 1, -1, -2, -3, -4, -6, 5, 3, 0, -2, -3, -5, -6, -7, - 4, 3, 0, -2, -3, -4, -5, -5, 4, 3, 0, -1, -2, -2, -3, -3, - 0, 0, 0, 0, -1, -5, -2, 6, 0, 0, 0, 1, -1, -6, -2, 8, - 0, 0, 0, 2, 0, -6, -3, 9, 0, -1, 0, 2, 0, -7, -2, 10, - 0, -1, 0, 2, -1, -8, -3, 10, 0, -1, -1, 2, -1, -7, -3, 9, - 0, -1, 0, 1, -1, -6, -3, 8, 0, 0, 0, 1, 0, -5, -2, 7, - 2, 3, 3, 2, 1, 0, -1, -1, 3, 4, 3, 2, 1, 0, -1, -2, - 3, 4, 4, 2, 1, -1, -2, -3, 2, 3, 3, 2, 0, -1, -2, -3, - -1, 0, 1, 1, 0, -1, -2, -2, -5, -4, -3, -1, 0, 1, 1, 1, - -8, -8, -5, -1, 1, 3, 4, 3,-10, -9, -5, 0, 3, 5, 6, 5, - -5, -1, 4, 5, 3, 1, 0, 0, -6, -1, 4, 5, 2, 0, -1, -2, - -6, -1, 5, 4, 2, -1, -2, -2, -7, -1, 4, 4, 1, -2, -3, -3, - -6, -1, 5, 4, 1, -2, -3, -3, -5, 0, 4, 4, 1, -1, -2, -2, - -4, 0, 5, 4, 1, -1, -1, -2, -3, 1, 4, 3, 1, -1, -1, -2, - -2, -3, -2, 1, 4, 6, 5, 3, -3, -4, -4, 0, 3, 5, 4, 2, - -3, -5, -5, -1, 2, 4, 3, 1, -4, -6, -4, -1, 2, 4, 2, -1, - -2, -4, -3, 1, 2, 4, 2, -1, -2, -4, -2, 1, 3, 3, 1, -2, - -2, -3, -2, 1, 3, 3, 1, -2, -2, -2, -1, 1, 3, 3, 0, -2, - -4, -4, -3, -2, -1, 2, 5, 7, -4, -4, -3, -3, -2, 1, 5, 7, - -2, -3, -2, -3, -3, -1, 3, 5, -1, -1, 0, -2, -3, -2, 2, 4, - 1, 1, 1, -1, -4, -3, 1, 3, 4, 3, 2, -1, -4, -3, -1, 1, - 6, 4, 3, 0, -3, -3, -2, 0, 6, 5, 3, 1, -2, -3, -2, -1, - 12, 11, 8, 4, 0, -2, -2, -1, 10, 9, 6, 2, -1, -2, -1, 0, - 4, 3, 2, 0, -1, -1, 0, 1, -1, -1, -1, -1, -2, 0, 1, 2, - -3, -5, -4, -2, -2, 0, 2, 3, -5, -5, -4, -2, -1, 0, 1, 2, - -5, -5, -4, -2, -1, 0, 1, 1, -4, -4, -3, -2, -2, -1, 0, 0, - 3, 3, 2, -1, -3, -4, -3, -2, 3, 2, 0, -2, -4, -4, -3, -2, - 2, 2, 1, -1, -3, -5, -4, -3, 3, 3, 3, 1, -2, -3, -3, -3, - 4, 4, 4, 3, 0, -2, -2, -2, 5, 5, 5, 3, 0, -1, -2, -2, - 5, 5, 4, 2, -1, -2, -3, -2, 3, 3, 3, 0, -2, -4, -4, -4, - -1, -1, 4, -2, -2, 6, 2, -5, -1, 0, 4, -2, -3, 6, 2, -6, - -1, 0, 4, -2, -3, 7, 3, -7, -1, -1, 4, -3, -4, 8, 3, -7, - 0, -1, 4, -3, -4, 7, 3, -6, -1, -1, 4, -3, -4, 7, 3, -6, - -1, -1, 3, -3, -4, 6, 3, -6, -1, 0, 3, -2, -3, 6, 3, -5, - 1, -2, -7, 2, 5, -2, -1, 1, 1, -2, -8, 3, 6, -3, -1, 2, - 2, -2, -9, 4, 7, -4, -2, 2, 3, -1, -9, 5, 7, -4, -1, 3, - 3, -1, -9, 4, 7, -4, -2, 2, 3, -1, -7, 4, 6, -4, -2, 1, - 2, 0, -6, 4, 6, -4, -1, 1, 2, 0, -5, 3, 4, -3, -1, 1, - -2, 2, 2, 0, 0, -1, -3, -4, -2, 2, 2, 1, 1, 0, -2, -4, - -2, 2, 2, 2, 2, 1, -1, -2, -3, 2, 3, 3, 4, 2, 0, -2, - -3, 2, 3, 2, 4, 2, 0, -3, -4, 1, 2, 1, 2, 1, -1, -3, - -5, 0, 1, 0, 1, 1, -2, -3, -4, 0, 0, 0, 1, 0, -2, -3, - 0, 0, -1, -2, -2, 2, 7, 8, 0, 0, -1, -3, -2, 1, 6, 7, - 0, 1, -1, -3, -3, 0, 4, 5, 0, 1, 0, -1, -1, 0, 1, 3, - 0, 2, 1, 1, 0, -1, 0, 1, -2, 0, 1, 2, 1, 0, -1, -1, - -5, -2, 0, 1, 1, 0, -3, -3, -6, -4, -1, 1, 1, -1, -3, -4, - -4, -2, 2, 5, 6, 4, 3, 2, -5, -3, 1, 4, 4, 2, 0, 0, - -4, -2, 0, 2, 1, -1, -2, -2, -2, -1, 0, 1, 0, -2, -3, -2, - -2, 0, 0, 0, -1, -1, -2, -1, -2, -1, -1, 0, 0, 0, 1, 2, - -2, -2, -1, -1, 0, 1, 3, 4, -2, -3, -2, -1, 0, 2, 4, 5, - 2, 1, -2, -2, -1, 0, 1, 0, 1, 0, -3, -3, -1, 0, 1, 0, - 0, -1, -3, -3, -1, 1, 1, 1, 0, 0, -3, -1, 1, 2, 3, 3, - 0, -1, -3, -1, 1, 3, 3, 3, -2, -2, -4, -2, 1, 3, 4, 4, - -3, -3, -4, -2, 1, 3, 3, 4, -2, -3, -5, -2, 1, 2, 3, 3, - 4, 5, 3, 4, 4, 4, 4, 5, 3, 3, 1, 0, 0, 0, 0, 1, - 1, 1, -1, -2, -3, -4, -3, -2, 2, 2, 0, -2, -2, -4, -3, -2, - 2, 3, 1, -1, -1, -3, -3, -2, 1, 2, 0, 0, -1, -2, -2, -1, - 0, 1, 0, -1, -1, -3, -2, -1, 1, 1, 0, -1, -1, -2, -2, -2, - -2, -1, -1, 0, 1, 2, 1, 0, 1, 2, 3, 5, 6, 5, 5, 3, - 1, 2, 3, 4, 5, 5, 4, 3, -2, -2, -3, -3, -2, -1, 0, 0, - -3, -3, -4, -5, -4, -3, -2, -1, -1, -1, -2, -2, -2, -1, 0, 0, - 0, 1, 0, -1, -1, 0, 0, 1, -1, 0, -1, -2, -3, -2, -2, -1, - 7, 7, 6, 5, 4, 2, -1, -2, 3, 3, 2, 2, 1, 0, -2, -3, - 0, -1, -1, -1, 0, -1, -2, -2, -1, -3, -2, -1, 0, 0, 0, 1, - 0, -2, -2, -1, -1, 1, 2, 2, 3, 1, -1, -1, -1, 1, 2, 2, - 3, 1, -2, -3, -2, -1, 1, 2, 1, -2, -5, -6, -5, -3, -2, 0, - 0, -1, -2, -3, -1, 0, -2, -2, 0, 0, -1, -1, 0, 1, -1, -2, - 0, 0, -2, -1, 0, 0, 0, -2, -1, -2, -3, -3, -2, -1, -3, -3, - -1, -2, -3, -3, -2, -2, -3, -4, 2, 2, 0, 0, 0, 0, -1, -2, - 5, 5, 3, 2, 2, 2, 0, -1, 8, 8, 6, 5, 4, 4, 2, 1, - -7, -8, -6, -3, -1, -1, -2, -1, -5, -5, -3, 0, 2, 1, 0, 0, - -1, -1, 0, 3, 4, 3, 1, 1, 2, 1, 1, 3, 4, 3, 2, 2, - 3, 2, 0, 2, 3, 2, 1, 2, 4, 2, -1, -1, 0, 1, 1, 1, - 3, 2, -2, -3, -2, -1, 0, 1, 3, 1, -3, -4, -3, -2, 0, 1, - -4, -2, -1, 2, 3, 3, 1, 0, -7, -5, -4, -2, 0, 0, -1, -2, - -6, -5, -5, -4, -2, -2, -2, -3, -1, 0, -1, -1, 0, 0, 0, -1, - 2, 3, 2, 2, 2, 2, 1, 0, 3, 5, 4, 3, 1, 0, 1, 0, - 3, 4, 3, 2, 0, -1, -1, -1, 5, 5, 3, 1, 0, -1, -1, -1, - 1, 1, 0, -1, -3, -5, -6, -4, 1, 1, 0, 0, 0, -3, -3, -1, - 0, -1, -1, 0, 1, 0, 1, 3, -2, -2, -3, -1, 2, 2, 4, 7, - -2, -2, -2, 0, 2, 2, 3, 6, -1, 0, 0, 1, 1, 0, 0, 3, - 0, 3, 3, 3, 1, -2, -3, -1, 1, 3, 4, 3, 0, -3, -5, -4, - 0, 2, 0, -1, -3, -4, -2, -2, 1, 4, 2, 0, -2, -3, -2, -1, - 3, 6, 3, 1, -2, -2, 0, -1, 4, 7, 4, 1, -2, -3, -1, 0, - 3, 6, 3, 0, -3, -3, -1, 0, 1, 3, 0, -1, -3, -2, 1, 1, - 0, 1, -1, -2, -3, -1, 2, 2, -2, -1, -3, -3, -3, -1, 1, 2, - 3, 1, -1, 0, 1, 0, 0, 0, 2, -1, -2, -1, 1, 0, -1, -1, - 1, -1, -2, 0, 1, 0, -2, -3, 0, -2, -1, 1, 3, 1, -3, -5, - 0, -2, -1, 2, 5, 2, -3, -5, 0, -2, -1, 4, 6, 3, -2, -5, - 0, -2, 0, 4, 7, 4, -2, -4, 0, -2, 0, 4, 6, 4, -2, -4, - -2, -2, -3, -4, -3, -2, -1, 0, 1, 1, 0, -1, -1, -1, 0, 1, - 3, 3, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 1, - 0, 0, 0, 0, -1, -1, -1, -1, -4, -4, -4, -4, -4, -4, -4, -3, - -3, -3, -2, -3, -2, -1, -1, 0, 3, 4, 4, 5, 5, 6, 6, 7, - -1, -2, 7, -2, -4, -1, -1, 0, -1, -2, 9, -1, -4, -1, -1, 0, - -1, -3, 10, -1, -4, -1, -1, 1, -1, -3, 10, -2, -3, -1, -1, 2, - -1, -2, 10, -2, -4, -1, -1, 2, -1, -2, 9, -2, -4, -1, -1, 2, - -1, -2, 8, -2, -4, 0, -1, 1, 0, -2, 7, -2, -3, -1, 0, 2, - 3, -4, 1, 3, -3, -2, 1, 0, 3, -5, 1, 4, -3, -2, 1, 0, - 3, -6, 2, 5, -3, -1, 3, 0, 3, -6, 2, 5, -3, -1, 2, 0, - 3, -6, 1, 5, -4, -2, 3, 0, 3, -6, 1, 5, -3, -2, 2, 0, - 2, -6, 1, 4, -3, -1, 1, 0, 2, -6, 1, 4, -2, -1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, 2, 0, -1, 1, 1, 1, 0, 0, 2, - 0, -1, 0, 0, 0, 0, 0, 2, 0, -1, 0, 0, 0, 0, -1, 0, - 1, 0, 1, 0, 0, -1, -2, -1, 3, 1, 1, 0, 0, -2, -4, -3, - 5, 3, 2, 1, 0, -3, -5, -4, 5, 4, 2, 0, -1, -4, -5, -5, - 1, 0, -1, -2, -2, -3, -6, -9, 2, 0, -1, -1, 0, 0, -3, -6, - 1, 0, 0, -1, 0, 0, -2, -5, 2, 1, 1, 1, 1, 2, -1, -3, - 1, 1, 2, 1, 2, 2, 1, -1, 1, 1, 2, 1, 1, 1, 1, 1, - 0, 0, 2, 1, 0, 0, 2, 2, 0, 1, 2, 2, 0, 0, 2, 2, - -4, -3, 0, 1, 4, 6, 4, 3, -3, -2, 0, 0, 2, 4, 1, 0, - -1, -1, 0, 0, 1, 1, -2, -3, 1, 1, 1, 0, 1, 1, -3, -5, - 1, 1, 1, 0, 1, 1, -3, -5, -1, 0, 0, -1, 1, 1, -2, -4, - -1, 0, 0, -1, 1, 2, 0, -2, -1, 0, 0, 0, 2, 3, 1, 0, - -1, 0, 3, 4, 0, -4, -5, -5, 0, 0, 4, 5, 2, -2, -3, -2, - 0, -1, 2, 4, 2, -1, -1, 0, 0, -2, -1, 1, 0, -2, 0, 1, - 1, -2, -2, 0, 0, -1, -1, 1, 1, -2, -3, 0, 1, 0, -1, 0, - 1, -2, -2, 1, 3, 1, 0, 0, 1, -2, -1, 2, 4, 2, 0, 0, - 1, 2, 3, 2, 0, 2, 2, 1, -1, 0, 1, 0, -3, 1, 1, 1, - -1, 0, 0, -2, -4, 0, 2, 1, -1, 2, 2, -1, -5, 0, 2, 1, - -1, 3, 4, -1, -5, 0, 2, 1, -2, 2, 4, 0, -4, -1, 0, 0, - -4, 0, 2, 0, -4, -2, 0, 0, -5, -1, 2, 1, -2, 1, 3, 2, - 1, 0, 1, 0, 1, 2, -1, -2, 2, 0, -1, -2, 1, 3, 0, -1, - 3, 0, -2, -4, 0, 3, 1, 0, 5, 1, -3, -5, -2, 2, 1, 1, - 6, 1, -2, -5, -2, 1, 0, 1, 5, 1, -1, -5, -2, 0, -1, 0, - 3, 0, -2, -4, -2, 0, -1, 0, 1, -1, 0, -2, 0, 1, 0, 1, - 1, 1, 2, 3, 2, 1, 1, 2, -1, -1, 0, 1, 1, 0, 1, 1, - -4, -3, 0, 0, 1, 1, 1, 2, -4, -3, 0, 2, 2, 2, 3, 2, - -5, -4, 0, 1, 1, 1, 1, 2, -5, -4, -1, -1, -2, -2, -1, 0, - -3, -2, 0, 0, -2, -3, -2, -1, 2, 3, 4, 4, 2, 0, 0, 0, - -4, -2, 0, 1, 0, 0, 0, 0, -3, -1, 1, 1, 0, 0, 0, 0, - -2, 0, 2, 2, 0, 0, 0, 2, -1, 1, 2, 1, -1, 0, 3, 5, - 0, 2, 1, -1, -2, 0, 5, 6, 0, 1, 0, -3, -3, 0, 4, 6, - 1, 1, -2, -4, -4, -3, 1, 2, 1, 0, -2, -4, -5, -4, -2, 0, - -1, -3, -3, -3, -3, -2, -1, -1, 3, 2, 1, 0, 0, 1, 1, 1, - 5, 4, 3, 2, 1, 1, 2, 2, 2, 1, 0, -2, -2, -2, -1, -1, - 0, 0, 0, -1, -2, -2, -2, -2, 0, 1, 3, 3, 2, 1, -1, -1, - 0, 1, 3, 4, 3, 2, 1, -1, -4, -3, -1, 1, 0, -2, -3, -3, - -3, -4, -7, -8, -7, -4, -1, 2, 0, -1, -3, -4, -4, -2, 0, 2, - 1, 0, 0, -1, -3, -2, 0, 2, 2, 1, 1, 0, -1, -1, 0, 2, - 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 2, 3, 3, 2, 2, 0, 0, 1, 3, 4, 4, 3, 2, - 3, 3, 3, 0, -1, 0, 1, 2, 1, 1, 1, -1, -2, -1, -1, 1, - -2, -2, -1, -3, -3, -2, -2, 0, -4, -4, -2, -2, -2, -2, -3, 0, - -4, -4, -1, 1, 1, 0, -1, 2, -3, -1, 2, 3, 4, 3, 3, 5, - -2, 0, 2, 3, 3, 3, 3, 3, -2, -2, 0, 0, 0, 0, 0, 1, - 0, 2, 1, -1, -3, -1, 3, -2, -1, 0, -1, -1, -3, 0, 4, -2, - -2, -2, -2, -2, -2, 1, 5, -2, -3, -2, -3, -1, -2, 1, 4, -3, - -2, 0, -1, 0, -1, 0, 3, -5, 1, 2, 1, 2, 0, 0, 2, -5, - 2, 4, 2, 3, 1, 1, 3, -3, 1, 2, 1, 1, 0, 1, 4, -2, - 4, -3, -4, -1, 3, 3, 1, 3, 4, -4, -4, -1, 3, 2, 0, 2, - 4, -3, -4, 0, 2, 2, -1, 1, 4, -3, -2, 1, 2, 1, -2, 0, - 2, -4, -2, 1, 2, 0, -3, 0, 2, -3, -2, 0, 1, 0, -2, 2, - 3, -1, -1, 0, 0, 0, 0, 3, 2, -2, -2, -2, -1, -1, -1, 2, - 2, 2, 3, 4, 3, 1, 0, -1, 1, 0, 1, 2, 1, -1, -2, -2, - 2, 1, 2, 1, 1, 0, -1, -1, 4, 3, 4, 3, 2, 1, 1, 1, - 3, 2, 2, 2, 1, 1, 1, 1, -1, -2, -1, 0, -1, -1, -1, -1, - -3, -3, -2, -1, -2, -2, -2, -2, -4, -4, -3, -3, -4, -4, -3, -3, - 2, 1, -1, -3, -4, -2, 3, 4, 2, 2, 1, -1, -3, -2, 1, 2, - 1, 2, 3, 3, 0, -2, -1, -2, -1, 0, 2, 4, 2, 0, -1, -3, - -2, -2, 0, 3, 3, 2, 0, -3, 0, -2, -3, -1, 1, 2, 2, -1, - 3, -1, -4, -5, -3, 0, 2, 0, 6, 3, -2, -6, -5, 0, 3, 1, - -2, 3, -2, 0, 3, -2, -2, 1, -3, 4, -3, 0, 3, -2, -1, 2, - -3, 5, -3, 0, 4, -2, -1, 2, -2, 4, -4, -1, 3, -3, -2, 2, - -3, 4, -3, 0, 3, -3, -1, 2, -2, 5, -2, 0, 3, -3, -1, 2, - -2, 4, -3, 1, 3, -2, -1, 2, -2, 3, -2, 1, 3, -2, 0, 2, - 1, 0, 0, -1, 1, 2, -4, -1, 2, 0, 0, -1, 1, 2, -4, -2, - 1, 1, 1, -1, 2, 4, -2, 0, 0, -1, 1, -1, 2, 5, -1, 1, - 0, -1, 0, -2, 1, 5, -1, 1, 0, -1, -1, -2, 0, 3, -3, -1, - 1, 1, 0, -2, 0, 3, -3, -1, 1, 1, 0, -3, 0, 3, -2, 0, - 1, 0, -1, 1, 1, 2, 4, 5, 1, 0, -1, 1, 1, 1, 5, 7, - 0, 0, -2, -1, -1, 0, 3, 5, 0, -1, -2, -1, -1, -1, 2, 3, - 0, -1, -3, -1, -1, -1, 1, 2, -1, -2, -4, -2, -2, -2, 0, 0, - -1, -2, -2, -1, -2, -2, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, - 3, 3, 0, -1, -1, 1, 4, 4, 2, 3, 0, -2, -2, 0, 1, 1, - 2, 3, 1, -1, -1, 0, 1, 0, 1, 2, 0, -1, -1, -1, 0, -2, - 0, 1, 0, -1, -2, -1, 0, -2, 0, 1, 0, -1, -2, -1, 1, 0, - 1, 1, -1, -3, -4, -3, 1, 3, 1, 2, -1, -3, -5, -4, 1, 3, - -3, -2, 0, 1, 1, 1, 0, -2, 0, 1, 1, 1, 0, 0, -1, -3, - 1, 2, 1, 1, 0, -1, -1, -2, 0, -1, -3, -1, -1, -1, 0, -1, - 0, -3, -6, -3, -2, -1, 1, 1, 2, -1, -4, -3, -2, 0, 2, 2, - 5, 4, 1, 1, 0, 1, 3, 2, 5, 4, 2, 1, 0, -1, 0, 1, - -2, 0, -2, -5, -6, -3, 0, 0, -2, 0, 1, 0, -1, 1, 2, 2, - -2, 0, 1, 3, 2, 2, 2, 1, -2, 0, 2, 4, 3, 2, 1, 1, - -2, 0, 2, 3, 2, 0, -1, 0, -3, -1, 1, 1, 0, -1, -1, 1, - -4, -1, 1, 0, -1, -2, 0, 2, -4, -1, 0, -1, -1, -2, 1, 4, - -3, 0, 0, -1, 1, 1, 1, 0, -3, 1, 0, -1, 0, 0, -1, -1, - -1, 3, 3, 0, 1, 0, 0, 1, -3, 2, 2, -2, -1, 0, 0, 1, - -5, 0, 0, -2, -1, 1, 0, 2, -7, -2, 1, 0, 1, 2, 2, 2, - -5, 0, 3, 2, 3, 3, 2, 2, -3, 2, 4, 1, 0, 0, -2, -3, - 5, 2, -2, -2, 0, -1, -1, -1, 2, -1, -4, -3, -1, -2, -1, -1, - 0, -2, -2, 1, 2, -1, 0, 1, -1, -2, -1, 3, 3, -1, 0, 2, - 1, 0, 0, 3, 3, -2, -1, 2, 2, 1, 1, 3, 2, -2, -2, 0, - 1, 0, -1, 1, 1, -3, -3, -2, 1, 0, 1, 2, 3, 0, 0, 0, - -4, -5, -3, 0, 1, -1, -2, -1, -2, -3, -1, 1, 2, 0, 0, 0, - 1, 1, 2, 1, 2, 1, 1, 1, 3, 4, 3, 1, 0, -2, -1, -1, - 3, 3, 2, 0, -2, -3, -3, -2, 1, 1, 0, -1, -2, -4, -2, -2, - 2, 1, 0, 0, 0, -1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 3, - 0, 0, 0, -1, -2, -1, 1, 0, -2, -1, -1, -2, -3, -2, 0, 0, - -1, 0, 0, -1, -2, 0, 1, 1, 1, 1, 0, -1, -1, 1, 3, 1, - 2, 2, 0, -2, -1, 2, 3, 0, 3, 1, -1, -1, 1, 4, 2, -2, - 2, 0, -3, -1, 3, 5, 0, -5, 1, -1, -2, 0, 3, 3, -1, -6, - -1, 0, 3, 4, 2, 0, 1, 2, -2, -1, 0, 1, -1, -2, 0, 1, - -2, -3, -2, -3, -6, -7, -6, -3, 2, 2, 3, 1, -1, -2, -3, -2, - 2, 2, 3, 1, 0, 0, 0, 0, 2, 1, 1, 0, 1, 1, 0, 1, - 1, 0, 0, 0, 0, 1, 1, 2, 1, 0, -1, 0, 0, 2, 2, 1, - 1, 1, 3, 1, -1, -1, -1, 1, -2, -1, 0, 0, -2, -2, -1, 2, - -2, -2, 1, 1, 1, 0, 1, 3, -2, -2, 0, -1, 0, -1, 0, 2, - 0, 0, 1, 0, -1, -1, -2, 1, 3, 2, 2, 1, 0, -2, -2, 1, - 5, 3, 3, 2, 1, 1, 1, 4, 0, -3, -4, -5, -4, -3, -1, 1, - -6, -4, -1, 2, 2, 0, 0, -1, -4, -2, 1, 3, 3, 2, 2, 0, - -3, -2, -1, 2, 3, 3, 2, 0, -3, -2, -2, 1, 2, 1, 1, -1, - -2, -2, -2, 0, 2, 2, 1, -1, -1, -1, -1, 1, 2, 3, 2, 0, - -1, -1, -2, 1, 2, 2, 2, -1, 0, -1, -2, 0, 2, 1, 0, -1, - 6, 4, 2, 1, 0, 0, 0, 1, 4, 2, -1, -2, -2, -2, -1, -1, - 2, 1, -1, -2, -2, -2, -2, -1, 2, 2, 0, -2, -2, -2, -1, 0, - 0, 0, -1, -2, -2, -1, 0, 1, -3, -3, -2, -1, -1, -2, -1, 0, - -3, -2, 2, 3, 2, 0, -1, -2, -2, 0, 4, 5, 5, 2, 0, -1, - 5, 4, 2, 0, -1, -2, -1, -1, 4, 3, 2, 1, 0, -1, 0, -1, - 1, 1, 0, 1, 1, 0, 1, -1, -2, -1, -1, 0, 0, -2, -2, -3, - -1, 0, 0, 0, -1, -3, -3, -5, 0, 1, 1, -1, -1, -2, -2, -3, - -1, -1, -1, -2, -1, 1, 3, 1, -1, -2, -2, -1, 2, 5, 6, 5, - -3, -3, -2, 1, 1, -2, -1, -1, 1, 2, 3, 4, 1, -3, -1, -3, - 3, 2, 0, 1, -1, -3, -1, -3, 1, 0, -1, 0, -1, -1, 1, 0, - 1, 1, 0, 1, 2, 2, 5, 3, 1, 1, 1, 2, 2, 2, 3, 0, - -3, -1, -2, -2, -3, -3, -1, -3, -1, 1, 1, 0, -1, -1, 0, -2, - 2, 0, -2, -2, 2, 4, 1, -2, 1, 0, -2, -1, 3, 5, 2, -1, - -1, -2, -3, -2, 1, 3, 1, -2, -1, -2, -1, -1, 0, 2, 1, -1, - 0, 0, 1, 1, 1, 2, 2, 0, 0, 1, 4, 4, 2, 2, 3, 1, - -2, -1, 2, 1, -2, -3, -2, -3, -1, 0, 1, 0, -3, -4, -4, -5, - 4, 0, -3, -4, -4, -4, -2, -1, 5, 0, -1, 0, -1, -3, -2, -1, - 4, 0, 0, 1, 1, 0, 0, 0, 0, -3, -2, -1, 0, 0, 1, 0, - 0, -2, 0, 0, 1, 1, 2, 1, 2, 0, 0, 0, 1, 1, 1, 0, - 2, 0, -1, -1, 1, 1, 1, 0, 1, -1, -2, -2, 0, 2, 2, 2, - -3, -5, -2, 0, -1, -3, -3, 0, 0, -2, 0, 2, 2, 0, 0, 3, - 2, -1, -2, 0, 0, -1, -1, 2, 5, 2, -1, -1, -1, -1, -1, 2, - 5, 2, 0, -1, -1, 0, -1, 2, 2, 1, 0, 0, 0, 1, 0, 2, - -1, -1, 1, 1, 2, 2, 1, 2, -3, -2, 0, 0, 0, 0, -2, -1, - 0, 3, 2, 0, -2, -3, -3, -3, 0, 3, 3, 1, 0, 0, 1, 2, - -1, 0, -1, -2, -1, -1, 1, 3, -1, 0, -1, -2, -1, -1, 0, 2, - -1, 0, -1, -2, 0, 0, -1, 2, -1, 0, -1, -2, -1, -1, -2, 1, - 0, 1, 0, -3, -1, -1, -1, 2, 5, 5, 2, -1, -1, -1, 1, 3, - 0, 0, 1, -1, -3, -2, 0, 2, 1, 1, 3, 0, -2, -2, 0, 1, - 1, 1, 3, 1, 0, 0, -1, -1, 0, -1, 2, 1, 1, 0, -1, -3, - -1, -2, 1, 1, 1, 0, -2, -4, -1, 0, 2, 1, 1, 0, -1, -3, - 1, 1, 3, 2, 1, 0, -2, -3, 2, 2, 4, 2, 1, -1, -2, -4, - 1, 2, 2, 2, 0, -2, 0, 2, -1, -1, -2, -3, -4, -5, -3, 1, - 0, 1, 1, 0, -1, -1, -1, 1, 0, 1, 1, 1, 0, 0, 0, 2, - 0, 1, 1, 2, 1, 1, 1, 2, -1, -1, 0, 2, 2, 2, 2, 3, - -2, -4, -4, -1, -2, -2, -2, 0, 1, 0, 0, 1, 0, 0, 0, 1, - 0, -1, -3, -2, 0, 2, 2, 1, 0, -1, -2, -3, 0, 1, 1, 2, - 1, 0, -2, -3, -1, 0, 0, 1, -1, 0, -1, -2, 0, 0, -1, 0, - -1, 1, 1, 0, 2, 2, 0, 0, 0, 2, 3, 1, 3, 5, 3, 2, - -1, 1, 1, -2, 0, 3, 1, 1, -1, 0, 0, -4, -4, -1, -1, -1, - -1, 1, 1, 0, 1, 2, 1, 2, -3, 0, 1, 0, 1, 1, 0, 2, - -5, -3, -1, -1, 0, 1, 0, 1, -4, -3, -2, -3, -2, -1, -1, 0, - 0, 0, -1, -2, -2, -2, -2, 0, 3, 4, 2, 0, 0, 0, 0, 1, - 2, 1, 0, 0, 0, 0, -1, 0, 0, 1, 2, 3, 4, 4, 3, 2, - -1, 4, 7, 4, 0, 0, 0, 0, -1, 4, 6, 3, 0, 1, 1, 1, - 0, 3, 4, 0, -1, 0, 0, 1, 0, 1, 1, -2, -1, 0, -1, -1, - -1, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, - -1, -3, -3, 0, 1, -1, -2, -1, -3, -4, -4, -2, -1, -2, -2, -1, - 2, 2, 1, 0, 1, 1, 0, -3, -2, -1, 0, 0, 1, 1, 0, -3, - -2, -1, 0, 1, 2, 1, 1, -2, 1, 2, 2, 2, 3, 3, 2, -1, - 1, 2, 1, 0, 1, 1, 2, -1, 0, 1, -2, -4, -2, 0, 1, -1, - 1, 1, -1, -3, -2, 0, -1, -3, 1, 2, 0, -1, 0, 1, -1, -4, - -1, -1, -2, -2, 0, 3, 4, 3, 1, 1, -1, -3, -2, 0, 0, 0, - 2, 2, 2, 2, 2, 1, -1, -1, 1, 1, 1, 3, 3, 0, -2, -2, - 0, -1, -1, -1, 0, -2, -1, -1, -1, -3, -4, -3, -2, -2, 0, 2, - -1, -1, 0, 1, 2, 2, 3, 5, -2, -1, -1, 0, 0, 0, 0, 1, - -2, -3, 2, 0, 0, 1, 1, -1, -1, -4, 1, -2, -1, 2, 2, 0, - 1, -4, 0, -2, -2, 1, 1, -1, 2, -3, 1, -1, -1, 1, 1, -1, - 3, -2, 3, 1, 0, 1, 1, -1, 1, -3, 2, 1, 0, 1, 0, -1, - -1, -5, 1, 0, -1, 0, 1, 1, 0, -3, 3, 3, 1, 2, 3, 3, - 0, -1, -2, 1, 5, 5, 2, -1, 1, -1, -2, -1, 1, 1, -2, -5, - 1, 1, -1, -2, -1, -1, -1, -3, 1, 1, -1, -1, -1, 2, 4, 3, - -1, -1, -1, -1, -1, 0, 4, 3, -1, -1, 0, 1, -1, -3, -1, -1, - 0, 0, 0, 2, 2, 0, 0, -1, 0, -2, -3, 0, 1, 1, 3, 2, - 2, 3, 2, 1, 0, 0, -2, -2, 2, 3, 0, 1, 1, 3, 3, 2, - 0, 0, -3, -1, -1, 2, 2, 3, -2, -2, -3, 1, 1, 2, 1, 1, - -2, -1, -2, 2, 1, 1, -1, -2, 0, 1, 0, 2, 0, 0, -2, -2, - 0, 1, 0, 2, 0, 0, -2, -2, -3, -2, -2, 0, -1, -2, -2, -3, - 0, 1, -1, 3, -1, 1, 3, -1, 0, 1, -1, 3, -1, -1, 2, -3, - 1, 1, -2, 3, -1, -3, 0, -3, 2, 2, -2, 3, 0, -2, 1, -2, - 1, 1, -3, 3, -1, -2, 1, -3, 1, 1, -3, 3, 0, -1, 1, -2, - 1, 2, -1, 4, 0, -1, 1, -2, 0, 1, -1, 3, -1, -3, 0, -3, - -3, -3, -1, 1, 2, 1, -1, -2, -2, -2, 0, 2, 1, 0, -2, -2, - -3, -2, 1, 2, 1, -1, -2, -1, -3, -2, 2, 4, 0, -2, -2, 1, - -3, -1, 2, 4, 0, -2, -2, 2, -1, 1, 4, 3, -1, -3, -2, 2, - 0, 2, 4, 2, -1, -2, -1, 2, 0, 1, 2, 0, -1, 0, 1, 3, - 3, 0, -5, 1, 4, 0, 0, 1, 1, -2, -5, 2, 5, -1, -2, 1, - -1, 0, 0, 3, 3, 1, 0, -1, -2, 3, 4, -2, -3, -1, 0, -2, - -3, 3, 5, -3, -3, 0, 0, -2, -1, 3, 2, -2, -2, 2, 2, -1, - 2, 0, 0, -1, 0, 0, 0, 0, 0, -3, -2, 1, 3, 0, -2, -2 -}; - -/* list of codebooks for inter-coded vectors */ -const int8_t* const ff_svq1_inter_codebooks[6] = { - svq1_inter_codebook_4x2, svq1_inter_codebook_4x4, - svq1_inter_codebook_8x4, svq1_inter_codebook_8x8, - NULL, NULL, -}; - -/* 6x16-entry codebook for intra-coded 4x2 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_intra_codebook_4x2)[768] = { - 12, 13, 13, 11, -7,-10,-15,-17,-16,-15,-12,-10, 11, 15, 15, 12, - 2, 17, 20, 15,-45,-24, 2, 13, 21, 20, -6,-36, 12, 16, -1,-27, - -18,-21, 10, 45,-11,-20, -7, 21, 43, -8,-28, 0, 33,-16,-28, 3, - -12,-18,-18, -6,-20,-10, 28, 55, -5,-18,-21,-18, 56, 30, -6,-20, - -34, 27, 29,-22,-30, 29, 26,-25, 30, 34, 33, 26,-25,-31,-35,-33, - -31,-35,-36,-32, 29, 36, 37, 31,-71,-12, 38, 34,-63, -1, 42, 33, - 58, 37,-31,-60, 55, 34,-33,-61,-57,-57, 22, 93,-57,-58, 21, 93, - 59, 69, 70, 62,-63,-68,-68,-60,-64,-71,-71,-64, 63, 73, 72, 62, - -2, 0, 7, 15,-11,-10, -3, 5, -5, -8,-10,-10, 1, 9, 14, 9, - 15, 8, -4,-11, 12, 2,-11,-12, -8, 0, 19, 28, 4, -1,-15,-26, - -15, 27, 2,-14,-14, 22, 1, -9, -4, -6,-13,-10, -6,-14, 6, 47, - -35,-20, 6, 23, 6, 9, 6, 4, -6, 2, 23,-22, -7, 4, 28,-21, - 20,-22, -2, 6, 22,-28, -5, 8,-10,-18,-16,-12, 36, 19, 2, -1, - -3, 0, 4, 8,-45,-10, 23, 23, 40, 15,-20,-35, -4, -1, 4, 1, - 9, -5,-33, 24, 8, 3,-26, 19, -1, 4, 6, -3, 32, 25,-13,-49, - 24, 24, 15, 7,-17,-27,-19, -7,-47, 0, 39, 24,-21, -6, 7, 4, - -1, 0,-10,-13, 1, 1, 5, 16, 20, 5, -3, -9, -1, -4, -2, -6, - -17, -7, 1, 4, 12, 7, 0, 0, 3, 0, 12, 11, -3, 1, 0,-23, - 4, 17, -6, 0, 6, 3,-25, 0,-17, 10, 8, 5,-14, 4, 1, 4, - 13, 10, 4, 2,-23, -9, 1, 2, 3, -3, 1, 7, 1,-23, -7, 20, - -7,-18, 2, 12, -5, -4, 10, 9, 4, 10, 7,-24, 6, 3, 4,-10, - 22,-14,-22, 6, 0, 5, 5, -1, -4, 3,-11, -4, -7, 31, 7,-14, - -5,-16, -1, 42, -4, -2, -9, -5, 5, -8, -6, -3, 42, -4,-21, -5, - -18, 12, 20,-12, 13,-13,-10, 7, -8, -9, -2,-18,-16, 6, 40, 8, - 10, -1, 0, 4, -3, 4, -1,-13, -2, 6, 1,-15, 5, 3, 1, 2, - -4, -2, 1, 3, 15, 0, -9, -4, -3, -4, -4, -4, -3, 5, 16, -3, - 2, 13, 3, 4, -3, -8,-10, 0, -6, -2, -4, -1, -2, -3, -6, 23, - 6, -6, 7, 1, 4,-18, 5, 1, -1, 1,-15, 14, -5, 6, -4, 4, - 2, 2, 2, 6,-24, 2, 7, 3,-26, 0, 3, 3, 5, 7, 1, 6, - 14, -2,-18, -3, 7, 5, -4, 2, -6, 3, 32, 1, -6, -6, -6,-12, - 5,-36, 7, 6, 9, -1, 11, 0, 4, 4, 5, 3, 4, 15, 3,-38, - 10, 23, -5,-42, 0, 4, 4, 4, 23, 17, -6,-13,-13,-37, 1, 29, - 5,-14, -1, 1, 5, 0, 3, 1, 0, 4, -5, 2, 8, 0, 0,-10, - 4, 7, -2, -3,-10, 3, 1, 1,-12, -1, 13, 3, 0, -1, 1, -3, - 0, -1, 3, 1, -6, -9, 3, 9, -6, 1, -4, -6, 8, -1, 0, 8, - -3, -3, 0, 18, -5, -1, -4, -1, -8, -2, 3, -4, 0, 17, -1, -5, - 5, -2, 9,-10, 1, -5, 6, -5, 4, 2, 2, 3, 10,-14, -8, 1, - -1, -2,-18, -1, -1, 20, 1, 2, -1, 1, -9, 1, -1, -9, 22, -4, - 6, -4, 8, -3, -1, 7,-19, 5, -7, 31, -4, -4, -6, 0, -5, -5, - -7, -8,-19, -4, 1, 1, 4, 32, 38, -1, -8, 4, -7, -8, -6,-12, - -1, 0, -7, 1, -1, 9, -1, 0, 9, -1, -1, 0, 2, -6, 1, -3, - -12, 0, 2, 1, 1, 1, 8, 0, 9, 1, 0, 2, -2, 1,-11, 0, - 0, 8, 2,-10, -1, 2, -1, 0, -2, -4, 0, -5, -2, -1, -1, 14, - -3, 7, -1, 5, 0,-10, 1, 1, -1, -5, 14, -1, -2, 1, -3, -2, - -6, 0, 0, 6, 2, 3, -9, 4, 4, -5, -1, -1, -7, 3, 8, -1, - 2, -4, -1,-11, 11, 2, 1, 0, -1, 2, 3, 9, 0, 2, 0,-15, - 3, 5,-20, 3, 3, -1, 3, 3, 1, -1, 16, 1, 2,-29, 9, 2, - -13, -6, -1, -3, 36, -1, -8, -3, 2, 5, 4, 2,-37, 9, 11, 3 -}; - -/* 6x16-entry codebook for intra-coded 4x4 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_intra_codebook_4x4)[1536] = { - -11, -3, 3, 6,-10, -1, 5, 7, -9, -1, 6, 7, -9, -1, 4, 6, - 5, 7, 0,-14, 6, 9, 2,-15, 6, 9, 2,-15, 4, 6, 0,-14, - 16, 3, -5, -6, 16, 1, -8, -8, 14, -1, -9, -9, 12, 0, -8, -8, - 8, 12, 16, 17, -2, 2, 6, 9,-10, -8, -4, 0,-15,-14,-11, -7, - -7,-10, -2, 16, -7,-11, -3, 18, -7,-11, -1, 20, -6, -8, 1, 19, - -9,-13,-16,-17, 2, -2, -7, -9, 11, 8, 4, -1, 16, 15, 11, 7, - -22, -2, 13, 15,-24, -2, 14, 16,-25, -4, 13, 15,-25, -6, 10, 13, - 26, 26, 22, 16, 17, 15, 9, 3, -2, -6,-11,-14,-20,-25,-28,-28, - -27,-27,-25,-21,-16,-15,-11, -7, 3, 8, 12, 13, 23, 28, 31, 30, - 20, 16, -7,-33, 22, 19, -6,-35, 22, 19, -6,-34, 20, 17, -6,-32, - -20,-20, 2, 38,-21,-22, 2, 40,-21,-22, 2, 40,-20,-20, 3, 38, - -47, -4, 24, 26,-50, -3, 26, 27,-50, -3, 26, 27,-47, -4, 24, 26, - 45, 6,-23,-27, 48, 5,-25,-28, 48, 5,-26,-28, 44, 6,-24,-27, - -30,-36,-10, 76,-31,-37,-11, 78,-31,-37,-11, 78,-31,-36,-10, 77, - -53,-32, 35, 52,-54,-34, 36, 52,-54,-34, 36, 52,-53,-33, 34, 51, - -93,-34, 62, 65,-93,-34, 62, 66,-93,-34, 62, 65,-93,-34, 60, 64, - -7, 0, 2, 2, -8, -1, 3, 3, -8, 0, 4, 5, -6, 1, 5, 5, - 3, 7, 11, 11, 2, 2, 3, 3, 1, -2, -6, -7, 1, -5,-11,-13, - 3, -2, -4, -3, 7, 0, -5, -5, 12, 4, -5, -7, 14, 6, -4, -7, - 18, 14, 3, -2, 6, 4, 0, -3, -8, -5, -2, 0,-16,-11, -2, 2, - -8, -6, 7, 18, -7, -8, 2, 13, -4, -6, -2, 6, 0, -4, -3, 1, - 1, -3,-13,-18, 0, -1, -5, -7, -1, 1, 6, 7, -2, 4, 15, 17, - -15,-14, -7, -2, -6, -5, -1, 0, 6, 6, 3, 1, 15, 13, 6, 1, - 2, -2,-11, 10, 2, -1,-12, 11, 3, -1,-12, 11, 2, -2,-11, 11, - -9, 14, -1, -5, -9, 15, -2, -5, -8, 16, -2, -5, -7, 15, -1, -4, - 2, 6, 8, 8, -2, 3, 9, 12,-11, -5, 4, 10,-19,-16, -8, 0, - 14, 8, -7,-15, 12, 7, -7,-14, 8, 5, -4, -9, 5, 3, -1, -4, - 12,-14, -2, 2, 13,-15, -1, 3, 14,-15, -1, 3, 13,-14, -1, 3, - 0, 6, 10,-13, 0, 6, 10,-15, 0, 7, 9,-17, 1, 6, 8,-16, - -8, -5, 15, -2, -8, -6, 17, -2, -8, -6, 16, -3, -8, -5, 15, -2, - -9,-11,-11,-10, 9, 10, 9, 8, 8, 10, 10, 9, -8, -9, -8, -7, - 9, 10, 9, 7, -8,-10,-10,-10, -7,-10,-11,-11, 11, 12, 11, 8, - 0, 10, 7, 0, 0, 7, 0, -6, 0, 2, -5, -6, -2, -1, -4, -1, - 5, 0, -6, -9, 2, 2, 2, 1, -2, 0, 5, 7, -6, -5, 1, 4, - 3, -8, 2, -1, 4, -9, 3, 0, 5, -7, 3, 0, 7, -5, 3, 0, - -5, -3, 2, 9, -6, -3, 1, 8, -6, -3, 1, 7, -5, -2, 0, 4, - 13, 8, 3, 1, -3, -5, -4, -1, -8, -7, -3, 0, -1, 1, 3, 2, - 3, 2, -5,-12, 4, 3, -2, -9, 3, 4, 1, -4, 3, 5, 4, -1, - -9, -8, -4, 0, 8, 6, 2, 0, 10, 8, 3, 0, -6, -5, -3, -1, - -3, -9,-12, -5, 0, -3, -5, 0, 2, 3, 2, 4, 5, 8, 7, 6, - -1, -2, 5, 12, -1, -1, 5, 9, 2, 1, -1, -2, 2, -1,-11,-17, - -7, 3, 3, -1, -9, 3, 4, -1,-10, 4, 6, -1, -9, 5, 7, 0, - -18, -7, 2, 2, -8, 1, 5, 3, 3, 4, 1, 0, 9, 5, -2, -3, - -2, 0, 6, 8, -4, -5, -5, -3, 1, -2, -6, -8, 10, 9, 3, -1, - 0, -2, -2, 0, 0, -4, -5, 0, -2, -8, -4, 8, -5, -7, 6, 24, - 9, 1, -7, 1, 9, 1, -8, 1, 8, 0,-10, 1, 8, -1,-11, -1, - 8, 8, 6, 3, 5, 4, 3, 2, -2, -3, -1, 0,-10,-13, -8, -4, - 0, 4, 2, -3, 0, 6, 3, -5, 3, 10, 2,-12, 5, 10, -4,-22, - 0, -4, -1, 3, 1, -4, -1, 5, 1, -5, 0, 8, -1, -6, -2, 7, - -1, -1, -2, -4, -1, -2, -4, -6, -1, -1, -1, -2, 1, 5, 10, 9, - 10, 3, 0, -2, 6, -1, -2, -5, 3, -1, -2, -6, 2, 0, 0, -5, - 6, 3, 0, 0, 6, 3, 1, 1, 4, -2, -2, 1, 0, -9, -9, -2, - -11, -3, 1, 2, -6, 2, 4, 5, -3, 2, 3, 4, -2, 1, 1, 2, - -6, -4, -1, -2, 2, -1, -1, -2, 10, 2, -2, -2, 11, 2, -4, -1, - 6, 0, -2, 2, 3, 3, 0, 0, -6, 3, 3, 0,-17, -1, 5, 0, - -1, 4, 10, 11, -3, -2, 0, 1, -3, -4, -5, -3, -1, -2, -2, -1, - 2, -3, -9,-12, 3, 3, 3, 2, 2, 2, 4, 4, 2, 1, -1, -2, - -2, 9, 5,-10, -3, 5, 5, -5, -2, 1, 2, 0, -1, -2, -2, 1, - -2, -3, 7, -2, -1, -3, 7, -3, -1, -2, 8, -4, -2, -2, 7, -3, - 1, -8, -3, 12, 2, -2, -2, 4, 1, 3, 0, -5, -1, 5, 2, -7, - -1, 3, 1, -5, -7, -2, 3, 1, -2, -7, -2, 2, 20, 3, -5, -1, - 5, 0, -3, -2, -7, -7, 0, 6, -6, 0, 7, 6, 2, 6, 0, -7, - -2, 6, -7, 1, -2, 7, -8, 3, -2, 7, -7, 3, -1, 7, -6, 2, - -5, -2, 5, 7, 4, 1, -4, -8, 6, 3, -2, -5, -7, -5, 3, 7, - -1, -1, 6, 5, 0, -1, 1, -4, 2, 1, 0, -7, 1, 0, 0, -4, - -8, 0, 3, 1, -2, 1, -1, -1, 1, -1, -3, 1, 1, -2, 1, 9, - 5, 2, -3, -4, -1, 0, -1, -3, -3, 1, 3, 1, -4, 0, 4, 2, - 2, -2, -2, 12, 0, -2, -5, 3, -1, 0, -3, 1, -3, -1, -2, 1, - 1, 5, 3, 0, -6, -4, -2, 1, 0, -2, -2, 2, 6, 1, -4, -1, - -3, -5, -5, -1, 3, 5, 5, 4, 0, 3, 1, -1, -2, 1, -2, -3, - 2, -4, -5, -3, 4, -2, -3, -2, 6, 0, -1, -1, 7, 1, 0, 0, - -3, -2, -2, 0, -2, -3, -5, -1, -2, 2, 0, -1, -1, 11, 9, -1, - 0, 1, -1,-10, -1, 1, 0, -6, 1, 0, 1, 4, 2, -5, -1, 13, - -2, 4, 5, 0, -5, 1, 6, 3, -6, -2, 3, 2, -5, -2, 0, -2, - -1, 1, 1, -2, -1, -2, 0, 2, 5, 5, 5, 7, 0, -4, -8, -7, - 0, 2, -1, -5, -1, 2, 2, -3, 0, 5, 3, -5, 3, 8, 2,-12, - 8, 4, 0, -2, 10, -1, -4, -1, 3, -6, -3, 0, -4, -5, 0, 0, - 0,-10, -4, 2, -1, -6, 3, 5, -1, -3, 6, 4, 0, -2, 4, 2, - 0, 8, 1, -1, 0, 11, 1, -3, -1, 6, -2, -4, -3, -2, -7, -4, - 0, -1, -1, -1, 4, 5, 6, 5, -5, -9, -8, -5, 2, 2, 3, 2, - 0, 2, 6, 1, 2, 0, 3, 0, 1, -2, -1, -2, 0, -1, -3, -6, - 0, 0, 2, 0, 4, 0, 2, 1, 5, -2, 0, 0, -2, -9, -1, 2, - 0, 1, 0,-10, -1, 1, 8, 0, -1, -2, 4, 0, 1, -1, 2, -1, - -3, -2, 2, -1, -3, -1, 2, -3, 0, -1, 1, 0, 8, 1, -1, 3, - 0, 1, 1, 2, 0, -4, -2, 0, -1, -5, 1, -1, -2, -1, 11, 2, - 1, 5, -2, -2, 0, 2, -4, 0, -2, 1, -5, 1, 0, 5, 0, 1, - -5, -3, 0, 6, -4, 2, 0, 0, -3, 5, 1, 0, -3, 3, 0, 0, - 3, -2, -3, 1, 1, -4, 0, 8, -2, -3, -2, 3, 1, 2, -1, -1, - 1, 1, 0, 2, 2, 0, 1, 6, 1, -1, 2, 1, 0, 3, 0,-19, - 1, -3, -2, 2, 6, 5, -2, -7, -3, 1, 3, 1, -1, -1, 0, 2, - -8, -1, -1, -4, 1, 1, -1, 2, 4, 3, 2, 3, -5, 1, 3, 0, - 0, 2, -1, 1, -3, 0, 0, 5, -5, -2, 0, 8, -4, -4, -4, 6, - 1, 2, 1, 2, 2, 2, -3, 2, 4, 0, -9, 0, 7, 0,-11, 1, - 0, 0, 0, -2, 3, 3, -1, -6, 4, 3, -3,-10, -1, 2, 6, 2, - 7, -2, -3, 5, -4, 0, 3, -1, -4, 2, 1, -7, 2, -1, -1, 3, - 3, 2, 2, 2, -5, -7, -7, -5, 5, 6, 4, 2, -2, -1, 0, 1 -}; - -/* 6x16-entry codebook for intra-coded 8x4 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_intra_codebook_8x4)[3072] = { - 5, 6, 6, 6, 7, 7, 8, 8, 0, 0, 0, 0, 0, 1, 2, 3, - -3, -4, -4, -5, -5, -4, -3, -2, -4, -4, -4, -5, -4, -4, -3, -3, - 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 4, 4, 5, 5, 5, - -1, 0, 1, 1, 2, 3, 4, 4, -9,-10, -9, -9, -8, -7, -6, -5, - -4, -4, -5, -6, -6, -7, -7, -7, 0, -1, -2, -2, -3, -3, -4, -4, - 4, 4, 3, 3, 2, 1, 1, 0, 7, 7, 7, 6, 6, 5, 4, 4, - 2, 4, 5, 6, 4, 1, -3, -6, 3, 4, 5, 5, 4, 0, -5, -8, - 2, 3, 4, 4, 2, -2, -7,-10, 2, 2, 2, 1, 0, -4, -9,-12, - -9, -7, -3, 1, 4, 4, 3, 3,-10, -7, -2, 3, 5, 5, 3, 3, - -9, -6, -2, 3, 6, 5, 4, 3, -8, -6, -1, 3, 4, 4, 3, 2, - -5, -5, -5, -5, -3, 1, 4, 7, -5, -5, -5, -4, -2, 1, 6, 8, - -4, -5, -4, -3, -1, 3, 8, 10, -3, -4, -3, -2, 1, 5, 9, 11, - -2, -2, -2, -2, -2, -2, -2, -2, -4, -5, -5, -5, -5, -5, -5, -4, - -3, -4, -4, -4, -4, -4, -4, -3, 9, 10, 10, 11, 11, 11, 10, 10, - 7, 4, 1, -2, -4, -6, -9,-10, 9, 7, 3, 0, -2, -4, -8, -9, - 11, 8, 4, 2, 0, -3, -6, -8, 11, 9, 5, 3, 1, -2, -5, -7, - -13,-13,-13,-12,-11,-10, -8, -8, 0, 1, 2, 3, 4, 4, 4, 3, - 3, 4, 5, 6, 6, 6, 5, 4, 3, 4, 4, 4, 3, 3, 3, 2, - 10, 10, 11, 10, 9, 9, 8, 7, 6, 6, 6, 6, 5, 4, 3, 2, - 0, 0, 0, -1, -2, -3, -4, -4,-10,-10,-11,-12,-13,-14,-14,-14, - 16, 16, 17, 16, 15, 13, 12, 11, -1, -2, -3, -4, -4, -4, -4, -3, - -4, -5, -6, -6, -6, -6, -6, -6, -5, -6, -6, -6, -6, -6, -5, -5, - -13,-13,-13,-12,-11,-10, -8, -6, -9, -8, -7, -6, -4, -2, 0, 1, - -2, -1, 1, 3, 5, 7, 8, 9, 5, 7, 9, 11, 13, 14, 15, 15, - 16, 14, 11, 7, 2, -3, -7, -9, 14, 12, 8, 3, -1, -6, -9,-11, - 11, 9, 4, 0, -4, -8,-11,-13, 8, 5, 1, -3, -6,-10,-12,-14, - -18,-15, -9, -3, 1, 6, 9, 11,-17,-13, -7, -1, 3, 7, 11, 12, - -15,-11, -5, 1, 5, 9, 12, 13,-13, -9, -3, 2, 5, 9, 11, 13, - 22, 21, 19, 15, 10, 3, -4, -9, 20, 18, 15, 9, 2, -5,-12,-17, - 16, 13, 8, 1, -7,-14,-20,-24, 10, 6, -1, -8,-15,-21,-25,-27, - -25,-23,-20,-14, -7, 1, 9, 14,-23,-21,-16, -9, 0, 9, 16, 21, - -20,-16,-10, -1, 8, 16, 22, 25,-15,-11, -3, 6, 14, 20, 25, 27, - -4, -2, 0, 1, 2, 2, 2, 2, -5, -2, 0, 2, 3, 3, 3, 3, - -6, -4, -1, 1, 2, 3, 3, 3, -7, -5, -2, 0, 1, 1, 2, 2, - 2, 1, 1, 1, 1, 0, -2, -3, 3, 3, 2, 1, 0, -1, -3, -4, - 4, 3, 2, 1, 0, -2, -4, -6, 5, 4, 3, 1, -1, -3, -5, -6, - 5, 6, 6, 4, 2, 0, -2, -3, 3, 4, 4, 4, 3, 1, 0, -1, - -2, -2, -1, -1, -1, -1, -2, -2, -5, -4, -3, -2, -2, -2, -3, -3, - -1, -1, -1, -1, -1, -1, -1, -1, -3, -4, -4, -4, -3, -3, -3, -3, - -1, -1, -1, -1, -1, -1, -1, -2, 5, 6, 6, 6, 6, 5, 4, 3, - 4, 4, 4, 4, 4, 5, 6, 7, 0, -1, -1, -1, -1, 0, 1, 2, - -2, -3, -3, -3, -3, -2, -1, 0, -3, -3, -4, -4, -4, -3, -2, -1, - 0, -2, -4, -4, -2, 0, 2, 3, 0, -2, -3, -3, -1, 2, 4, 5, - -1, -2, -4, -3, 0, 3, 5, 6, -2, -3, -4, -3, -1, 2, 4, 5, - 9, 4, 0, -3, -3, -1, 0, 1, 8, 4, -1, -4, -3, -1, 1, 2, - 6, 2, -3, -5, -4, -2, 0, 1, 5, 1, -3, -4, -4, -2, 0, 1, - 5, 3, 1, -1, -4, -8,-10,-10, 3, 3, 2, 1, 0, -2, -3, -4, - 1, 1, 1, 2, 3, 2, 1, 0, -1, 0, 1, 2, 3, 4, 3, 2, - 0, 1, 2, 2, 1, -1, -3, -3, 0, 1, 1, 1, -1, -2, -4, -3, - -3, -3, -3, -3, -3, -3, -1, 2, -4, -4, -3, 0, 3, 7, 12, 14, - -5, -5, -6, -6, -6, -6, -6, -5, 2, 2, 2, 1, 0, 0, 0, 0, - 4, 4, 3, 2, 1, 0, 0, 0, 6, 6, 5, 4, 2, 2, 1, 1, - -7, -7, -6, -3, 0, 4, 7, 8, -1, -2, -3, -3, -2, -1, 1, 2, - 3, 3, 1, -1, -2, -2, -2, -1, 6, 6, 4, 2, 0, -2, -2, -2, - -6, -5, -2, 2, 5, 9, 11, 12, -4, -4, -2, 0, 2, 4, 5, 6, - -3, -2, -2, -2, -2, -1, 0, 1, -2, -2, -2, -3, -3, -3, -3, -2, - -7, -3, 1, 3, 3, 0, -3, -5, -6, -2, 3, 5, 4, 1, -3, -5, - -5, -1, 4, 6, 5, 2, -3, -4, -4, 0, 5, 7, 6, 3, -1, -3, - 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -3, -3, -3, -3, -2, -1, - 6, 7, 8, 9, 9, 8, 7, 6, -4, -4, -5, -5, -6, -6, -5, -4, - -9, -8, -6, -4, 0, 3, 6, 6, -5, -4, -1, 3, 5, 6, 5, 3, - 1, 3, 6, 6, 4, 1, -2, -5, 6, 7, 5, 1, -3, -7,-10,-11, - 10, 9, 5, 1, -3, -6, -6, -4, 5, 3, -1, -5, -6, -5, -2, 2, - -2, -4, -6, -6, -4, 1, 6, 10, -6, -7, -7, -4, 1, 7, 11, 12, - 6, 5, 3, 2, 0, 0, 0, 0, 2, 1, -1, -2, -3, -2, -1, -1, - 0, -1, -2, -4, -4, -2, -1, 1, 0, 0, -1, -2, -1, 0, 2, 3, - 0, -1, -2, -2, -2, -2, -1, -1, 5, 4, 2, 1, 0, 0, 0, 0, - 6, 5, 3, 1, 0, 0, 0, 0, 2, 0, -2, -4, -4, -3, -2, -2, - -7, -4, 0, 2, 2, 2, 2, 1, -7, -3, 0, 0, 0, 0, 0, 0, - -4, -1, 1, 1, 0, 0, 0, 1, -1, 1, 2, 2, 2, 2, 3, 3, - -2, 0, 2, 2, 1, 1, 1, 1, -1, 1, 2, 2, 1, 0, 0, -1, - 0, 2, 4, 2, 0, -1, -2, -3, 1, 2, 3, 1, -2, -4, -6, -6, - 1, 2, 2, 4, 5, 6, 4, 1, 0, -1, -1, -1, 0, 0, -2, -4, - 0, 0, -1, -2, -2, -2, -4, -6, 2, 1, 0, 0, 1, 1, -1, -3, - 1, 1, 1, 1, 1, 2, 3, 3, 0, 0, 1, 0, 1, 2, 4, 4, - -1, -1, -1, -1, 0, 1, 2, 3, -4, -4, -5, -5, -5, -3, -1, 0, - -6, -5, -5, -4, -3, -2, -1, -1, -1, 0, 0, 1, 1, 2, 3, 3, - 0, 1, 1, 1, 2, 2, 3, 4, 0, 0, -1, -1, 0, 1, 2, 3, - 0, 1, 1, 1, 0, 0, -1, -1, 1, 3, 3, 2, 1, -1, -2, -2, - -2, 0, 2, 2, 2, 2, 1, 1, -9, -8, -4, -2, 1, 3, 3, 3, - -1, -1, -1, -2, -3, -3, -3, -4, 0, 0, 0, -1, -2, -2, -3, -3, - 2, 2, 2, 0, -1, -1, -1, -1, 5, 5, 4, 3, 2, 2, 2, 2, - 6, 3, -1, -4, -3, -1, 1, 1, 2, -1, -3, -4, -1, 2, 2, 0, - -1, -2, -2, 1, 4, 4, 1, -3, -2, -1, 1, 4, 6, 3, -3, -8, - 3, 3, 2, 1, -1, -2, -2, -2, -4, -4, -2, -1, 1, 3, 4, 4, - -4, -5, -5, -4, -2, 0, 2, 2, 7, 7, 4, 1, -1, -2, -3, -2, - -1, 1, 3, 0, -4, -6, 0, 6, -2, 1, 4, 1, -4, -6, -1, 7, - -3, 1, 4, 2, -3, -6, -1, 6, -2, 0, 3, 2, -2, -5, -1, 4, - 1, -1, -2, 1, 4, 4, -1, -7, 1, -1, -4, -1, 5, 6, 0, -6, - 3, 0, -4, -3, 3, 6, 2, -4, 3, 0, -5, -4, 1, 4, 1, -3, - 2, 2, 3, 3, 3, 3, 2, 2, -4, -5, -6, -7, -7, -7, -7, -6, - 1, 2, 3, 3, 3, 3, 2, 2, 0, 0, 1, 1, 1, 2, 2, 1, - 3, -3, -3, 3, 4, -2, -2, 2, 3, -4, -4, 4, 4, -4, -4, 2, - 4, -4, -4, 4, 4, -4, -3, 3, 3, -3, -4, 3, 3, -3, -3, 3, - -2, -2, -2, -2, -2, -2, -1, -1, 6, 7, 8, 8, 8, 7, 6, 5, - -5, -6, -7, -7, -8, -7, -6, -5, 1, 1, 2, 2, 2, 2, 1, 1, - 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, - -2, -3, -2, -2, -2, -3, -3, -3, 2, 3, 5, 6, 4, 2, 1, 0, - 8, 6, 2, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, -1, -1, -1, - 1, -1, 0, 0, 0, -1, -2, -3, -2, -2, -1, 0, 0, -2, -4, -5, - 3, 1, -1, -2, -3, -4, -5, -5, 2, 1, 0, 0, 1, 1, 0, 0, - 0, -1, -1, 0, 2, 2, 2, 2, -1, -2, -1, 1, 2, 2, 2, 2, - 0, -1, -2, -1, -1, -1, -1, 0, -1, -2, -2, -1, -1, 0, 0, 1, - 2, 1, 1, 2, 2, 1, 1, 0, 6, 5, 3, 1, 0, -2, -4, -4, - -3, -2, -1, 0, 1, 1, 0, -1, 0, 1, 3, 4, 5, 5, 3, 1, - -1, -1, -1, 0, 1, 0, -1, -2, -2, -2, -2, -1, 0, -1, -2, -3, - 0, -1, -2, -2, -1, -1, 0, 2, 1, -1, -2, -1, -1, -1, 0, 2, - 1, 0, -2, -2, -2, -2, 1, 5, 1, -1, -2, -2, -2, 0, 5, 10, - 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, 0, 0, 1, 2, - 1, 2, 2, 3, 4, 4, 6, 5, -3, -3, -3, -2, -2, -3, -3, -3, - 1, -1, -2, -2, 0, 3, 5, 7, 2, 0, -2, -3, -2, 0, 2, 3, - 3, 1, -2, -3, -3, -2, -1, -1, 3, 1, 0, -1, -1, -1, -1, -1, - 1, 3, 5, 4, 2, -1, -3, -4, -3, -2, 1, 2, 1, 0, -1, -2, - -5, -3, 0, 2, 2, 1, 0, 0, -3, -1, 1, 2, 2, 1, 0, 0, - 0, -1, -1, -1, 1, 2, 3, 4, -3, -4, -4, -3, -1, 0, 0, 1, - -2, -3, -2, -1, 1, 1, 1, 1, -2, -2, 0, 3, 4, 4, 3, 2, - -4, -4, -3, -2, -1, 1, 2, 3, 0, 1, 1, 1, -1, -2, -3, -3, - 3, 4, 5, 4, 2, -1, -3, -3, -2, -2, 0, 2, 2, 2, 1, 0, - -4, 0, 5, 7, 4, -1, -4, -4, -1, 2, 4, 3, 0, -3, -3, -2, - 2, 1, 0, -1, -2, -2, 0, 1, 0, 0, -1, -2, -2, -1, 1, 2, - -4, -3, -2, -1, 0, 1, 2, 2, 10, 9, 5, 0, -3, -4, -3, -2, - 1, -1, -2, -2, -1, 0, 0, 0, -2, -2, -1, 1, 1, 1, 0, -1, - -5, -3, 0, 3, 4, 2, 0, -2, -2, -1, 0, 1, 1, 0, -1, -1, - 3, 2, -1, -2, -2, -1, 1, 1, 7, 5, -1, -5, -6, -2, 2, 4, - -2, 3, 3, -3, -4, 1, 2, -2, -3, 3, 4, -3, -4, 2, 3, -2, - -3, 3, 4, -3, -4, 2, 3, -2, -4, 2, 4, -2, -3, 1, 2, -1, - 4, 3, -1, -3, -3, -1, 1, 2, -4, -6, -4, 0, 4, 5, 4, 1, - 0, 2, 5, 6, 2, -3, -5, -4, 1, 1, -1, -3, -5, -2, 2, 4, - -1, 0, 1, 2, 2, 3, 3, 4, -1, 0, 1, 1, 0, -1, -1, -1, - -1, 0, 1, 2, 2, 1, -1, -2, -3, -2, -1, 0, 0, -1, -2, -3, - 1, 1, 1, 1, 0, 0, 1, 2, 1, 0, -1, 0, 0, 1, 1, 0, - 1, -2, -4, -1, 1, 2, 1, 0, 1, -4, -7, -3, 1, 3, 2, 1, - 1, 1, 1, 1, 1, 1, 0, -1, 1, 1, 1, 0, 1, 2, 2, 0, - 1, 1, 0, 0, 0, 2, 0, -3, 3, 2, 0, -1, -1, -2, -6, -9, - 0, 0, 0, 1, 0, 0, 1, 2, 1, 0, 0, 0, -1, -1, 0, 2, - 0, 1, 1, 1, -1, -3, -2, 0, -7, -5, 1, 6, 6, 2, -1, -1, - 3, 1, -1, -3, -4, -2, 1, 4, 2, 0, -2, -3, -4, -3, -1, 2, - 2, 2, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, - -1, 1, 1, -2, -5, -6, -4, -1, -1, 1, 4, 3, 2, 0, 1, 2, - -1, 0, 2, 3, 1, 0, 0, 1, -1, 0, 1, 0, 0, -1, -1, 0, - 0, 1, 2, 2, 0, -2, -1, 1, -2, -1, -1, -2, -1, 2, 6, 8, - -1, -1, -2, -3, -2, 0, 1, 2, -1, 0, 0, -1, -1, 0, -1, -1, - 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, -1, -1, 1, - -1, 0, 2, 2, -1, -3, -2, 3, 0, 2, 3, 0, -5, -7, -2, 4, - -1, 0, 0, 0, -1, -2, -3, -3, -1, 0, -1, -2, -2, -2, -2, -2, - 1, 1, 0, 0, 1, 2, 0, -1, 1, 2, 1, 2, 5, 6, 2, 0, - -2, -4, -3, 0, 2, 2, 0, -3, 3, 1, 0, 1, 2, 1, -2, -3, - 3, 1, 0, 0, 0, 0, 0, -1, 1, -1, -2, -2, -1, 1, 3, 3, - 3, 2, 1, 2, 4, 3, 1, -2, -2, -4, -4, -3, -1, 0, -2, -3, - 1, 0, -1, -1, 0, 1, 0, -1, 3, 2, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 2, 3, 3, 2, 2, 2, 1, 1, - 0, -1, -2, -3, -5, -5, -5, -4, 1, 1, 0, -1, 0, 1, 3, 3, - -9, -6, -2, 0, 1, 1, 2, 2, -6, -2, 1, 2, 1, 1, 0, 1, - -2, 1, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 0, 1, 1, 1, - 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -3, -2, 0, - -3, -3, -3, -2, -1, 3, 7, 9, 1, 2, 2, 2, 0, -2, -4, -3, - 2, 0, -2, -1, 3, 4, -1, -6, 1, 0, -2, -3, -1, 3, 3, 0, - 0, 3, 3, 0, -2, -1, 1, 1, -6, -1, 3, 2, -1, -2, 0, 1, - 5, 3, 0, -2, -3, 0, 2, 1, 1, 1, 2, 2, 0, -2, -4, -7, - -3, -2, 1, 2, 2, 1, -1, -4, 2, 2, 0, -2, -2, 0, 2, 2, - 0, 0, -2, -3, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, - -2, -1, 0, 1, 0, 1, 2, 3, -4, -2, 0, 0, -1, 0, 2, 3, - -2, -2, -2, -1, -1, 0, 2, 4, 0, 0, 0, 0, -1, -1, 0, 1, - 0, -1, -1, -1, -1, -1, 0, 0, 6, 4, 2, 0, -1, -2, -1, -1, - 0, 1, 1, 1, 1, -1, -5,-10, 1, 1, 1, 1, 1, 1, 0, -4, - 1, 0, 1, 1, 1, 1, 1, -1, 2, 1, 1, 1, 0, 0, 0, 0, - -3, 1, 4, 3, 3, 1, -1, 0, -4, 0, 1, 0, -1, 0, 0, 0, - -5, 0, 2, 1, 1, 1, 0, -1, -1, 2, 1, -2, -2, -1, 0, -1, - 2, 4, 5, 3, 0, -1, 1, 2, 0, 0, 1, 0, -2, -2, -1, -1, - -2, -2, -2, -2, -3, -2, -1, 0, 0, 0, 1, 0, 0, 0, 1, 2, - 0, -2, -2, -3, -1, 2, 2, -1, 1, 0, 0, 0, 1, 5, 3, -2, - -1, -1, 0, -1, 0, 2, 0, -5, -1, 0, 1, 0, 0, 2, 2, -2, - 3, 1, -1, -1, 0, 1, 1, 2, 1, 0, 0, 1, 1, 1, 1, 1, - -10, -8, -2, 1, 2, 1, 1, 1, -1, 1, 2, 1, 0, 0, 0, 0, - -1, -1, 0, 1, 2, 2, 2, 1, -1, -1, -1, 0, -1, -3, -5, -4, - 1, 1, 2, 1, 1, 0, 0, 2, -1, -2, -1, -1, -1, 0, 2, 4, - -3, -7, -5, 0, 2, 0, 0, 0, 3, -1, -2, 1, 2, 1, 1, 2, - 1, -2, -1, 1, 2, 1, 0, 1, 0, -1, 0, 3, 2, -1, -1, -1, - 2, 1, 1, 0, 0, 0, 0, 0, -9, -7, -2, 3, 3, 2, 1, 1, - 3, 2, 0, -2, -2, -1, 1, 1, 0, -1, 0, 0, 1, 1, 0, 0, - -2, -1, 1, 1, 1, 0, 0, 0, 1, 2, 1, -2, -4, -3, 1, 2, - 1, 2, 1, -2, -3, 0, 3, 1, -1, -1, 0, 0, 1, 3, 0, -4, - 2, 0, -1, 1, 2, -2, -2, 3, 2, 0, -1, 2, 3, -2, -4, 1, - 0, 1, 1, 1, 2, -2, -6, -2, -1, 0, 0, 0, 2, 0, -2, -1, - -1, -1, 1, 2, 1, -2, -3, -2, 3, -1, -2, -1, -1, 0, 1, 2, - 10, 4, 0, 0, -1, -2, -2, -1, 3, -1, -2, -1, 0, -1, -1, 0, - -5, 2, 7, 1, -4, -2, 1, 0, -2, 2, 3, -1, -3, 0, 2, 0, - 2, 1, 0, 0, 1, 1, -1, -2, 1, -2, -2, -1, -1, -2, 0, 0, - 0, 3, -2, -7, -1, 3, 0, 0, 1, 3, -3, -5, 2, 3, -1, 0, - 0, 2, -2, -2, 4, 2, -2, 0, -1, 1, -1, 0, 2, -1, -2, 1, - 4, 0, -3, -4, -2, 1, 2, 1, 0, 0, 3, 5, 3, 1, -1, -2, - 1, 1, 1, -1, -3, -1, 1, 1, 1, -1, -2, -2, 0, 0, -1, -2 -}; - -/* 6x16-entry codebook for intra-coded 8x8 vectors */ -DECLARE_ALIGNED(4, static const int8_t, svq1_intra_codebook_8x8)[6144] = { - 4, 4, 3, 2, 2, 1, 0, -1, 4, 3, 3, 2, 1, 0, -1, -1, - 3, 3, 2, 2, 1, 0, -1, -2, 3, 2, 2, 1, 0, -1, -2, -3, - 2, 2, 1, 0, -1, -1, -2, -3, 2, 1, 0, 0, -1, -2, -3, -4, - 1, 0, 0, -1, -2, -3, -4, -4, 0, 0, -1, -2, -2, -3, -4, -4, - 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, - 1, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, - -1, 0, 0, 0, 0, 0, 1, 1, -2, -2, -1, -1, -1, -1, -1, -1, - -3, -3, -3, -3, -3, -3, -2, -2, -5, -4, -4, -4, -4, -4, -4, -3, - -4, -2, -1, 0, 1, 2, 2, 3, -4, -2, -1, 0, 1, 2, 3, 3, - -4, -3, -1, 0, 1, 2, 3, 3, -4, -3, -1, 0, 1, 2, 3, 3, - -5, -3, -1, 0, 1, 2, 3, 3, -5, -3, -1, 0, 1, 2, 3, 3, - -5, -3, -1, 0, 1, 1, 2, 3, -5, -3, -2, -1, 0, 1, 2, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 2, 2, 2, 3, 3, 4, 4, 4, - 0, 0, 0, 0, 1, 1, 1, 2, -2, -2, -2, -2, -1, -1, -1, 0, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -1, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -2, -2, -2, -2, - 5, 3, 1, -1, -2, -3, -3, -3, 5, 3, 1, -1, -2, -3, -3, -3, - 5, 3, 1, -1, -2, -3, -3, -3, 5, 3, 1, -1, -2, -3, -3, -3, - 5, 4, 1, 0, -2, -3, -3, -3, 6, 4, 2, 0, -2, -2, -3, -3, - 6, 4, 2, 0, -1, -2, -2, -3, 6, 4, 2, 1, -1, -2, -2, -2, - -1, 1, 3, 3, 2, 0, -3, -6, -1, 1, 3, 4, 3, 0, -3, -6, - -1, 1, 4, 4, 3, 1, -3, -6, -1, 1, 3, 4, 3, 1, -3, -6, - -2, 1, 3, 4, 3, 1, -3, -6, -2, 1, 3, 4, 3, 1, -3, -7, - -2, 1, 3, 3, 2, 0, -3, -7, -2, 0, 2, 3, 2, 0, -3, -6, - 10, 9, 8, 6, 6, 5, 4, 4, 6, 5, 4, 3, 2, 2, 2, 1, - 2, 1, 0, -1, -2, -2, -2, -1, -1, -2, -3, -4, -4, -4, -4, -3, - -2, -3, -4, -4, -5, -4, -4, -3, -2, -2, -3, -3, -3, -3, -2, -2, - -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 2, - -2, -1, 1, 2, 4, 5, 7, 8, -3, -2, 0, 1, 3, 5, 7, 8, - -4, -3, -1, 0, 2, 4, 6, 7, -5, -4, -2, -1, 1, 3, 5, 7, - -6, -5, -3, -2, 0, 2, 4, 6, -6, -5, -4, -2, -1, 1, 3, 5, - -7, -6, -5, -3, -2, 0, 2, 3, -8, -7, -5, -4, -3, -1, 1, 2, - 11, 9, 7, 5, 3, 1, -1, -1, 10, 8, 6, 3, 1, 0, -2, -2, - 9, 7, 5, 2, 0, -2, -3, -4, 8, 6, 3, 1, -1, -3, -4, -4, - 6, 4, 2, -1, -3, -4, -5, -5, 5, 3, 0, -2, -4, -5, -6, -6, - 3, 1, -1, -3, -5, -6, -7, -7, 2, 0, -2, -4, -6, -6, -7, -7, - 5, 6, 7, 7, 7, 8, 8, 8, 3, 4, 5, 5, 6, 6, 6, 6, - 0, 2, 2, 3, 4, 4, 4, 5, -2, -1, 0, 1, 2, 2, 3, 3, - -4, -3, -2, -1, 0, 1, 1, 2, -6, -5, -4, -3, -2, -2, -1, 0, - -8, -7, -6, -6, -5, -4, -3, -3,-10, -9, -8, -8, -7, -6, -6, -5, - 6, 5, 3, 1, -1, -3, -6, -8, 6, 5, 4, 2, -1, -3, -6, -8, - 6, 5, 4, 2, 0, -3, -6, -8, 6, 5, 4, 2, 0, -3, -6, -8, - 6, 6, 4, 2, 0, -3, -6, -8, 6, 5, 4, 2, 0, -3, -6, -8, - 6, 5, 4, 2, 0, -3, -6, -8, 6, 5, 4, 2, -1, -3, -5, -8, - 11, 10, 9, 8, 7, 6, 5, 4, 8, 8, 7, 6, 5, 4, 3, 2, - 6, 5, 4, 4, 2, 2, 1, 0, 3, 3, 2, 1, 0, 0, -1, -2, - 1, 1, 0, -1, -2, -2, -3, -3, -1, -1, -2, -3, -4, -4, -5, -5, - -3, -4, -4, -5, -6, -6, -7, -7, -5, -5, -6, -7, -8, -8, -8, -8, - -14,-13,-12,-11, -9, -7, -6, -4,-12,-11,-10, -9, -7, -5, -3, -1, - -10, -9, -7, -6, -3, -2, 0, 2, -8, -6, -4, -2, 0, 2, 4, 5, - -5, -3, 0, 2, 4, 5, 7, 8, -2, 0, 2, 4, 6, 8, 9, 10, - 0, 3, 5, 7, 8, 10, 11, 12, 3, 5, 7, 8, 10, 11, 12, 12, - -19,-19,-18,-18,-17,-16,-15,-14,-15,-15,-14,-13,-12,-11,-10, -9, - -11,-10, -9, -8, -6, -5, -4, -3, -6, -5, -3, -2, -1, 0, 1, 2, - -1, 0, 2, 3, 4, 5, 6, 6, 4, 6, 7, 8, 9, 10, 10, 10, - 9, 10, 11, 12, 13, 14, 14, 14, 12, 14, 14, 15, 16, 16, 16, 16, - 22, 21, 19, 17, 14, 11, 9, 5, 20, 19, 17, 14, 11, 8, 4, 1, - 17, 15, 13, 10, 6, 3, 0, -4, 13, 11, 8, 5, 1, -2, -5, -9, - 9, 6, 3, -1, -4, -7,-11,-13, 4, 0, -3, -6, -9,-12,-15,-17, - -2, -5, -8,-11,-14,-16,-18,-20, -8,-10,-13,-16,-17,-19,-21,-22, - 17, 18, 18, 18, 17, 16, 16, 14, 16, 16, 15, 15, 14, 13, 12, 11, - 12, 12, 11, 10, 9, 8, 7, 5, 7, 6, 6, 4, 3, 2, 1, -1, - 1, 0, -1, -2, -3, -4, -5, -6, -5, -6, -7, -8, -9,-10,-11,-12, - -11,-12,-13,-14,-15,-16,-16,-17,-16,-17,-17,-18,-19,-20,-20,-20, - 0, 0, 0, 0, -1, -1, -2, -3, 1, 0, 0, 0, 0, -1, -2, -3, - 1, 1, 0, 0, -1, -1, -2, -2, 1, 1, 1, 0, 0, -1, -1, -2, - 2, 1, 1, 1, 0, -1, -1, -2, 2, 2, 1, 1, 0, 0, -1, -2, - 2, 2, 1, 1, 1, 0, -1, -1, 2, 2, 1, 1, 1, 0, 0, -2, - 0, -1, -1, 0, 0, 1, 2, 3, 0, -1, -1, 0, 1, 1, 2, 2, - -1, -1, -1, -1, 0, 1, 2, 2, -1, -1, -2, -1, 0, 1, 1, 2, - -1, -2, -2, -1, 0, 0, 1, 2, -1, -2, -2, -2, -1, 0, 1, 2, - -1, -1, -2, -1, 0, 0, 1, 2, -1, -1, -1, -1, 0, 1, 1, 2, - 3, 2, 2, 2, 1, 1, 0, 0, 3, 2, 2, 2, 2, 1, 0, 0, - 2, 2, 2, 1, 1, 1, 0, 0, 2, 2, 1, 1, 1, 0, 0, -1, - 1, 1, 1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -2, -2, -2, -2, - 5, 2, 0, 0, -1, 0, 0, 0, 4, 2, 0, -1, -1, -1, 0, -1, - 4, 1, -1, -1, -2, -1, -1, -1, 4, 1, -1, -1, -2, -1, -1, -1, - 4, 1, -1, -2, -2, -1, -1, -1, 4, 1, -1, -2, -2, -1, -1, -1, - 4, 1, -1, -1, -1, -1, -1, -1, 4, 2, 0, -1, 0, 0, 0, -1, - -2, -1, 0, 1, 1, 1, 1, 1, -3, -1, 0, 1, 1, 1, 1, 1, - -3, -1, 0, 1, 1, 1, 1, 1, -3, -1, 0, 1, 1, 1, 1, 1, - -3, -2, 0, 1, 2, 2, 1, 1, -4, -2, 0, 1, 2, 2, 2, 2, - -5, -3, -1, 1, 1, 2, 1, 2, -5, -3, -2, 0, 1, 1, 1, 1, - 3, 3, 1, 0, -2, -4, -4, -5, 3, 3, 2, 0, -1, -2, -3, -4, - 2, 2, 1, 1, 0, -1, -2, -2, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, -2, -1, -1, 0, 0, 1, 2, 2, - -3, -2, -2, -1, 0, 1, 2, 3, -3, -3, -2, -1, 0, 1, 2, 3, - -3, -3, -3, -3, -3, -2, -2, -2, -3, -3, -2, -2, -2, -1, -1, -1, - -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2, - 1, 1, 1, 2, 2, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, - -8, -7, -5, -3, -2, -1, 0, -1, -4, -3, -1, 0, 1, 2, 1, 1, - -1, 1, 2, 3, 3, 2, 2, 1, 1, 2, 3, 3, 2, 2, 1, 0, - 2, 3, 3, 2, 1, 0, 0, -1, 1, 2, 1, 0, -1, -1, -1, -1, - 1, 1, 0, -1, -1, -2, -2, -1, 1, 1, 0, 0, -1, -1, 0, -1, - -4, -3, -2, 0, 1, 2, 3, 3, -4, -3, -2, 0, 1, 2, 2, 2, - -3, -3, -2, -1, 0, 1, 1, 1, -2, -2, -2, -1, -1, 0, 0, 0, - 0, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 0, 0, -1, -1, -2, - 3, 3, 3, 1, 0, -1, -2, -2, 5, 4, 4, 2, 1, 0, -1, -2, - 0, 0, 0, 0, 1, 2, 3, 3, 0, -1, 0, 0, 1, 2, 3, 3, - 0, -1, 0, 0, 1, 2, 3, 2, 0, 0, 0, 1, 1, 2, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 1, 0, 0, -1, -2, - 2, 1, 0, 0, -2, -3, -5, -6, 0, -1, -1, -3, -5, -6, -8, -9, - -2, 0, 1, 2, 2, 1, -1, -4, -2, 0, 2, 2, 2, 1, -1, -4, - -2, 0, 2, 2, 2, 1, -1, -3, -2, 0, 2, 2, 2, 1, -1, -3, - -2, -1, 2, 2, 2, 1, -1, -3, -2, -1, 1, 2, 2, 1, -1, -3, - -3, -1, 1, 2, 2, 1, -1, -3, -2, -1, 1, 2, 2, 1, -1, -3, - -1, 1, 1, -1, -3, -3, 0, 4, -1, 1, 1, -1, -3, -3, 0, 4, - -1, 1, 1, 0, -3, -3, 0, 4, -1, 1, 2, 0, -3, -3, 0, 5, - 0, 1, 2, 0, -3, -4, 0, 4, 0, 1, 2, 0, -3, -4, 0, 5, - 0, 1, 2, 0, -3, -3, 0, 4, 0, 1, 2, -1, -2, -2, 0, 4, - 6, 6, 5, 6, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -2, -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, - -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 0, 0, 0, 0, 0, - -1, -2, -2, -2, -2, -2, -2, -1, -3, -3, -3, -3, -3, -3, -3, -2, - -3, -4, -4, -3, -3, -3, -2, -2, -2, -2, -2, -2, -1, -1, 0, 0, - 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, - 4, 1, -2, -3, -3, -1, 1, 3, 4, 1, -2, -4, -3, -1, 1, 3, - 5, 1, -2, -4, -3, -1, 1, 4, 5, 1, -2, -3, -3, -1, 2, 4, - 5, 1, -2, -3, -3, -1, 2, 4, 4, 0, -3, -4, -3, -1, 2, 4, - 4, 0, -3, -3, -3, -1, 1, 3, 3, 0, -2, -3, -2, -1, 1, 3, - -3, -4, -4, -4, -4, -4, -4, -4, -1, -1, -1, -1, -1, -1, -2, -2, - 2, 1, 1, 2, 2, 1, 1, 1, 3, 3, 3, 4, 4, 3, 3, 3, - 3, 3, 3, 4, 4, 4, 3, 3, 1, 2, 1, 2, 2, 2, 2, 2, - -2, -2, -2, -1, -1, -1, 0, 0, -4, -4, -4, -4, -3, -3, -3, -3, - -1, -2, -3, -3, -2, -2, -1, 0, 0, -1, -2, -2, -2, -1, 0, 1, - 2, 1, -1, -1, -1, -1, 0, 1, 3, 1, 0, -1, -1, 0, 0, 1, - 3, 2, 0, -1, 0, 0, 0, 1, 3, 1, 0, -1, 0, 0, 0, 1, - 3, 1, 0, -1, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 1, 1, 2, 3, 4, 0, 0, -1, 0, 0, 0, 2, 3, - 0, -1, -1, -1, -1, -1, 0, 1, 0, -1, -1, -1, -1, -1, -1, 0, - 0, 0, -1, -1, -1, -2, -2, -1, 1, 0, 0, -1, -1, -2, -2, -1, - 2, 2, 1, 0, -1, -1, -1, -1, 3, 3, 2, 1, 0, -1, -1, 0, - 1, 0, 1, 0, 0, -1, -2, -1, 0, 0, 0, 0, -1, -1, -2, -1, - 0, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, - -1, -1, -1, 0, 0, 0, 1, 1, -1, -1, -1, 0, 1, 1, 2, 3, - -2, -2, -1, 0, 1, 2, 3, 4, -2, -2, -1, 0, 1, 2, 4, 5, - -3, -1, 1, 0, 0, -1, 0, 1, -3, 0, 1, 0, -1, -1, 0, 2, - -3, 0, 1, 0, -1, -1, 0, 2, -2, 1, 2, 0, -1, -1, 0, 2, - -2, 1, 2, 0, -1, -1, 0, 2, -2, 1, 2, 0, -1, -1, 0, 2, - -1, 2, 2, 0, -1, -1, 0, 2, -1, 1, 1, 0, -1, -1, -1, 1, - -2, -2, -1, 1, 3, 4, 3, 1, -2, -2, -1, 0, 2, 3, 2, 0, - -2, -2, -1, 0, 1, 2, 1, -1, -1, -1, -1, 0, 1, 2, 1, -1, - -1, -1, -1, 0, 1, 1, 0, -2, 0, -1, -1, 0, 1, 1, 0, -1, - 0, -1, -1, 0, 1, 1, 1, -1, 0, -1, -1, 0, 0, 1, 0, -1, - -2, -1, 0, 1, 1, 1, 1, 1, -2, -1, 0, 0, 0, 0, 0, 0, - -2, -1, -1, 0, -1, -1, -2, -2, -2, -1, -1, -1, -1, -2, -2, -3, - -1, 0, 1, 1, 0, -1, -2, -2, 1, 2, 3, 3, 2, 1, 0, 0, - 1, 2, 3, 3, 3, 2, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, -1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, -1, 0, 0, 1, 1, 0, 0, 0, - -3, -2, -1, -1, -1, -1, 0, -1, -5, -5, -4, -3, -2, -2, -2, -1, - 1, 1, 1, 1, 2, 1, 0, -1, 1, 1, 1, 2, 1, 1, 0, -1, - 1, 1, 1, 1, 1, 1, 0, -2, 2, 1, 1, 1, 1, 1, 0, -2, - 1, 1, 0, 0, 0, 0, -1, -3, 1, 1, 0, 0, 0, -1, -2, -3, - 1, 1, 0, 0, -1, -1, -2, -4, 1, 0, 0, -1, -2, -2, -3, -4, - 8, 7, 5, 3, 2, 1, 1, 1, 2, 1, 0, 0, -1, -1, -2, -1, - -1, -1, -1, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, -1, -1, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, - -1, 0, 0, 0, 0, 0, -1, -1, -2, -2, -1, -1, -1, -2, -2, -1, - 9, 4, 0, -2, -2, -2, -1, -1, 7, 2, -1, -2, -2, -1, 0, 0, - 4, 0, -2, -2, -1, 0, 1, 1, 1, -2, -2, -2, -1, 0, 1, 1, - -1, -2, -2, -1, 0, 1, 1, 1, -1, -2, -1, 0, 1, 1, 1, 0, - -1, -1, 0, 1, 1, 1, 0, -1, 0, -1, 0, 1, 0, 0, -1, -1, - 0, 1, 1, 1, 1, 1, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, - 2, 2, 2, 2, 1, 0, -1, -1, 1, 1, 1, 0, -1, -2, -2, -2, - 0, 0, 0, -1, -2, -3, -2, -2, -1, -1, -1, -2, -2, -2, -1, 0, - -1, -1, -1, -1, 0, 0, 1, 2, -1, -1, -1, 0, 1, 2, 3, 4, - -1, -1, 0, 0, -1, -2, -3, -3, -1, -1, 0, 0, 0, -1, -1, -1, - -2, -2, -1, 0, 1, 1, 1, 1, -2, -2, -2, 0, 1, 2, 3, 3, - -1, -1, -1, 0, 1, 3, 3, 3, 1, 0, 0, 0, 1, 1, 2, 2, - 2, 2, 1, 0, 0, -1, -1, -1, 3, 2, 1, 0, -1, -2, -3, -3, - -1, -1, -1, -2, -2, -3, -4, -5, 0, 0, 0, -1, -1, -3, -3, -4, - 1, 1, 1, 0, 0, -1, -2, -3, 2, 2, 2, 1, 1, 0, -1, -1, - 2, 2, 2, 2, 1, 1, 0, -1, 2, 2, 2, 2, 2, 1, 0, 0, - 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, -1, - -2, 2, 3, 1, -1, 1, 1, -1, -3, 2, 3, 0, -1, 1, 1, -1, - -3, 2, 3, 0, -1, 1, 1, -1, -4, 2, 3, 0, -1, 1, 1, -2, - -4, 1, 3, 0, -1, 1, 1, -2, -4, 1, 3, -1, -2, 1, 1, -2, - -3, 1, 2, 0, -1, 1, 1, -2, -3, 1, 2, 0, -1, 1, 1, -1, - -1, -1, -1, -2, -2, -2, -2, -2, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 1, 2, 2, 2, - -2, -2, -1, -1, -1, 0, 0, 0, -3, -3, -3, -3, -3, -3, -3, -2, - -1, -1, -1, -1, -2, -2, -2, -2, 4, 4, 4, 4, 4, 3, 3, 2, - -3, -3, -2, -1, 0, 1, 2, 5, -3, -3, -3, -2, -1, 1, 3, 6, - -3, -3, -2, -2, 0, 2, 3, 5, -3, -2, -2, -2, 0, 1, 3, 5, - -2, -2, -2, -1, -1, 1, 3, 5, -2, -2, -1, -1, 0, 1, 2, 4, - -1, -1, -1, -1, 0, 1, 1, 4, -1, -1, -1, -1, 0, 1, 2, 3, - 0, -1, 0, 1, 1, 0, -1, -1, 0, 0, 0, 1, 2, 0, -1, -1, - 1, 0, -1, 0, 1, 0, 0, 0, 1, -1, -2, -1, 0, 0, 0, 0, - 1, -2, -3, -1, 0, 0, 0, 1, 1, -1, -3, -2, 0, 1, 1, 2, - 1, -1, -2, -1, 0, 1, 1, 2, 2, 0, -1, 0, 1, 1, 2, 2, - 1, 1, 1, 1, 0, 0, 1, 2, -1, 0, 0, -1, 0, 0, 0, 1, - -3, -2, -1, -1, -1, 0, 1, 1, -4, -2, -1, 0, 0, 1, 1, 1, - -3, -2, 0, 0, 1, 1, 1, 1, -3, -1, 0, 1, 1, 1, 0, 0, - -1, 0, 1, 1, 1, 0, 0, -1, 0, 1, 2, 2, 1, 0, 0, -1, - -4, -4, -4, -3, -2, -1, -1, -1, -2, -2, -2, -1, 0, 0, 0, 0, - -1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 2, 2, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 0, -1, 0, 0, 1, 1, 1, 0, 0, - 1, 2, 2, 2, 1, -1, -2, -4, 1, 1, 2, 2, 1, 0, -2, -4, - 0, 1, 1, 1, 1, 0, -1, -3, -1, 0, 1, 1, 0, 0, -1, -2, - -1, 0, 1, 1, 1, 0, 0, -1, -2, -1, 0, 0, 0, 0, 0, -1, - -1, -1, 0, 1, 1, 0, 0, 0, -1, 0, 1, 1, 1, 1, 1, 0, - 2, 2, 0, -1, -2, -1, -1, -2, 1, 1, -1, -2, -2, -1, -1, -2, - 1, 1, -1, -2, -2, 0, 0, -1, 1, 1, 0, -2, -1, 1, 1, 0, - 1, 1, 0, -1, -1, 1, 2, 1, 1, 1, 0, -1, -1, 1, 2, 1, - 1, 1, 0, -1, -1, 1, 1, 1, 1, 1, 0, -1, 0, 1, 1, 1, - 0, 0, -1, -2, -4, -4, -4, -4, 3, 3, 3, 2, 1, 0, 0, 0, - 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, - -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, - -1, -1, 0, -1, -1, 1, 2, -1, 1, 1, 0, 0, 0, 2, 3, -1, - 1, 1, 0, -1, -1, 1, 3, -1, 1, 1, 0, -2, -2, 0, 1, -2, - 1, 0, 0, -2, -2, 0, 1, -3, 0, 0, 0, 0, -1, 1, 1, -3, - 0, 1, 1, 0, 1, 2, 1, -3, -1, 0, 1, 1, 1, 2, 1, -4, - -4, -3, 0, 1, 1, 1, 0, 0, -4, -2, 0, 1, 1, 1, 0, -1, - -3, -1, 1, 1, 1, 0, -1, -1, -1, 1, 1, 1, 1, 0, -1, 0, - 1, 2, 2, 1, 0, -1, 0, 0, 2, 2, 1, 0, -1, -1, 0, 1, - 2, 1, 0, -1, -2, -1, 0, 1, 2, 2, 0, -1, -2, -1, 1, 1, - 1, 1, 0, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, - 1, 0, 0, -1, -1, -1, -1, -1, 2, 1, 0, 0, -1, -1, -1, -1, - 5, 3, 2, 1, 0, 0, 0, 0, 6, 5, 3, 2, 1, 0, 0, 0, - 4, 4, 3, 1, 0, 0, 0, 1, 3, 3, 2, 1, 0, 0, 0, 1, - 2, 2, 1, 0, -1, -1, 0, 1, 0, 0, 0, -1, -1, -1, 0, 1, - 0, 0, -1, -1, -2, -1, 0, 2, 0, -1, -1, -2, -2, -2, 0, 1, - 0, -1, -1, -2, -2, -2, -1, 0, 0, 0, -1, -2, -2, -2, -1, 0, - 0, 0, -1, -1, -1, 0, 2, 3, 0, -1, -2, -2, -1, -1, 1, 2, - 1, 0, -1, -1, -1, 0, 0, 0, 1, 1, 1, 0, 0, 0, -1, -1, - 1, 2, 1, 0, 0, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, - -3, -2, -1, -1, 0, 1, 1, 2, -4, -3, -1, 1, 2, 3, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, -1, 0, 0, 0, 1, -1, -1, -2, -2, -2, -1, -1, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, - 1, 1, 1, 1, 2, 2, 1, 1, -4, -3, -4, -4, -4, -4, -3, -3, - -1, 0, 1, 2, 2, 3, 3, 3, -1, -1, -1, -1, 0, 0, 0, 0, - 0, 0, -1, -2, -2, -3, -3, -2, 3, 2, 1, 0, -1, -2, -2, -2, - 4, 3, 2, 1, 1, 0, 0, 0, 2, 2, 1, 1, 0, 1, 1, 1, - 0, -1, -1, -1, -1, 0, 0, 1, -2, -2, -2, -2, -2, -1, 0, 0, - 1, -1, 0, 2, 1, -2, -1, 1, 1, -1, 0, 2, 1, -2, -2, 1, - 1, -1, 0, 3, 2, -2, -1, 1, 0, -2, 0, 3, 2, -2, -2, 1, - 0, -2, 0, 3, 2, -2, -2, 1, 0, -2, 0, 3, 1, -2, -1, 1, - 0, -2, 0, 2, 1, -2, -2, 1, 0, -1, 0, 2, 1, -2, -1, 1, - 0, 1, 2, 2, 3, 3, 2, 2, 0, 1, 1, 2, 3, 3, 2, 1, - 0, 0, 1, 2, 2, 2, 2, 1, -1, 0, 0, 1, 1, 1, 1, 1, - -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, - -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -2, -2, -2, -2, -2, -1, - 0, 0, -1, -2, -1, 0, 3, 5, 0, 0, -1, -1, -1, 0, 2, 4, - 1, 1, 0, 0, -1, -1, 1, 2, 1, 2, 1, 1, 0, -1, -1, 0, - 0, 1, 2, 1, 0, -1, -2, -2, -1, 0, 1, 2, 1, 0, -3, -3, - -2, -1, 1, 2, 2, 0, -2, -4, -2, -1, 0, 2, 2, 1, -1, -3, - 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0, - -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, - -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, -1, 0, - 0, 0, 1, 1, 0, 0, 0, 1, 3, 3, 3, 4, 3, 3, 3, 3, - 5, 1, -2, -2, 0, 0, 0, -1, 4, -1, -3, -1, 0, 0, 0, -1, - 3, -1, -1, 0, 1, 1, 0, -1, 2, 0, 0, 1, 1, 1, 0, -2, - 1, 0, 0, 1, 1, 1, 0, -2, 0, -1, -1, -1, 0, 0, 0, -1, - 0, -1, -1, -1, -1, 0, 0, -1, 2, 1, 0, 0, 0, 1, 0, 0, - 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, - 1, -1, -1, 0, 0, 0, 0, 0, 2, 0, -1, -1, -1, -1, -1, 0, - 3, 1, -1, -1, -2, -2, -2, -1, 4, 2, 1, 0, -1, -2, -2, -1, - 2, 1, 0, 0, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 1, 1, - 0, 1, 2, 2, 2, 1, -1, -3, 0, 0, 1, 1, 1, 0, -1, -2, - 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, 1, 1, 0, - 0, 0, -1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 2, 1, -1, -3, 0, 0, 0, 1, 1, -1, -4, -5, - -2, -2, -2, -1, 0, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, -2, -3, 0, 0, 1, 1, 0, -1, -3, -4, - -1, -1, 0, 1, 0, 0, -2, -3, -1, -1, 0, 1, 1, 1, 0, -1, - 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 0, 0, 1, 1, 1, 2, 1, 2, 0, 0, 0, 0, -1, 1, - 0, 2, 0, -1, 1, 0, -1, 0, 0, 1, 0, 0, 2, 1, 0, 1, - 0, 1, -1, 0, 2, 2, 0, 1, -1, 0, -1, -1, 2, 1, 1, 2, - -2, -2, -3, -2, 0, 1, 1, 1, -2, -2, -3, -3, -1, -1, -1, 0, - -3, -1, 0, 1, 2, 1, 1, 0, -3, -1, 0, 1, 2, 1, 1, 1, - -2, 0, 0, 1, 1, 1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0, - -2, 0, 0, 0, 0, -1, -1, 0, -2, 0, 0, 0, 0, 0, -1, -1, - -3, 0, 1, 1, 1, 1, 0, 1, -5, -2, 0, 1, 2, 2, 1, 2, - -2, -1, -1, 0, 0, 1, 2, 3, 0, 0, 1, 1, 0, 0, 1, 2, - 0, 0, 1, 0, -1, -1, 0, 1, -1, -1, -1, -1, -2, -2, -1, 0, - -2, -2, -2, -2, -2, -1, 0, 1, 0, 0, 0, -1, 0, 1, 2, 2, - 2, 1, 0, 0, 0, 1, 2, 2, 2, 1, 0, -1, -1, -1, 0, 0, - 0, 1, 1, 1, 1, 1, -1, -4, -1, -1, 0, 1, 1, 1, 0, -3, - -2, -1, 0, 0, 1, 2, 2, -2, -1, 0, 0, 0, 0, 2, 3, -1, - -1, 0, 0, 0, 0, 1, 2, 0, 0, 0, -1, -2, -1, 1, 1, 0, - 0, 0, -1, -2, -2, 0, 2, 1, 0, 0, -1, -2, -1, 1, 2, 2, - 1, 0, 0, 0, -2, -3, -2, -3, 0, 0, 1, 0, -2, -2, -1, -1, - 0, -1, 1, 1, -1, -1, 0, 0, 0, -1, 1, 1, -1, -1, 0, 0, - 0, 1, 2, 1, -1, -1, 0, 1, 1, 2, 3, 2, 0, 0, 1, 2, - -1, 0, 2, 1, 0, 0, 2, 3, -2, -1, 0, 0, -1, 0, 1, 2, - 1, 1, 0, -1, -2, -2, -1, 1, 1, 1, 1, -1, -2, -2, 0, 2, - 1, 1, 1, -1, -1, -1, 0, 2, 0, 0, 0, 0, 0, 0, 1, 2, - -1, -1, -1, 0, 0, 0, 1, 2, -1, -2, -1, 1, 1, 1, 0, 0, - -1, -2, -1, 1, 2, 2, 0, -1, -1, -2, -1, 2, 2, 2, 0, -1, - -1, -1, -1, -2, -1, -1, 0, 1, 0, 0, -1, -1, -1, 0, 1, 2, - 1, 0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, - 1, 2, 1, 0, -1, -2, -2, -3, 2, 2, 1, 0, -2, -3, -4, -4, - -4, -2, 1, 1, 1, 1, 0, 0, -2, 0, 1, 0, 0, 0, 0, 0, - 0, 1, 1, -2, -2, -1, 0, 1, 2, 2, 1, -2, -2, -1, 1, 2, - 1, 2, 1, -2, -2, -1, 1, 2, -1, 1, 1, -1, -1, -1, 0, 1, - -2, 0, 1, 1, 0, -1, -1, 0, -2, 0, 2, 2, 1, -1, -1, 0, - 1, 1, 0, 0, 0, 1, 0, 0, -2, -3, -3, -2, -2, -1, 0, 0, - -3, -4, -3, -2, -1, 0, 0, 0, -1, -1, 0, 1, 2, 3, 2, 1, - 0, 1, 2, 3, 3, 3, 2, 1, 1, 1, 1, 2, 1, 0, 0, -1, - 0, 0, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, -1, -1, 0, 2, 0, 0, 1, 0, -1, -1, 1, 1, - -2, -1, 0, 1, 1, 1, 1, 1, -3, -3, 0, 2, 2, 1, 1, 0, - -2, -2, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, -1, - 3, 1, -1, -3, -2, -1, 0, 1, 4, 2, -1, -3, -3, -1, 1, 2, - 0, 0, 0, -1, -1, -1, -1, -1, 1, 2, 1, 0, 0, 0, -1, -1, - 2, 3, 3, 2, 1, 0, -1, -1, 3, 4, 4, 2, 1, 0, -1, -2, - 3, 3, 2, 1, 0, -1, -2, -2, 1, 1, 0, -1, -1, -2, -2, -3, - 0, 0, 0, -1, -1, -2, -2, -2, -1, -1, -1, -1, -1, -2, -2, -1, - 1, 2, 2, 2, 2, 1, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 0, -1, -2, 0, 0, 0, 0, 1, 0, -1, -4, - 1, 0, 0, 0, 0, 0, -2, -5, 1, 0, 0, 0, 0, 0, -1, -4, - 1, 0, -1, 0, 0, 0, -1, -3, 0, -1, -1, 0, 1, 1, 1, -1, - -2, -1, 0, 0, -1, -1, -1, -2, -1, 0, 0, 0, -1, -1, -2, -2, - 0, 1, 1, 0, -1, -1, -1, -2, 0, 1, 1, 0, 0, 0, -1, -1, - 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 2, 2, 1, - 1, 1, 0, 0, 1, 2, 2, 1, 1, 1, 0, -1, 0, 1, 1, 0, - 4, 2, 1, 0, 0, 1, 1, 1, 4, 2, 1, 0, 0, 0, 0, 1, - 3, 1, 0, 0, -1, -1, -1, 0, 1, 0, 0, -1, -1, -2, -1, 0, - 0, 0, 0, 0, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, 0, 1, - -2, -1, 0, -1, -1, 0, 0, 1, -2, -2, -1, -2, -1, 0, 0, 1, - 0, 1, 1, 1, 2, 1, 0, -1, -1, -1, -1, 0, 0, -1, -2, -2, - -1, 0, -1, 0, 0, -1, -2, -1, 0, 0, 0, 0, 0, 0, 1, 2, - 0, 0, 0, 0, 0, 0, 2, 3, -1, 0, -1, -1, -1, -1, 0, 3, - -1, 0, 0, -1, -1, -2, 0, 3, 0, 0, 0, 0, -1, -1, 1, 4, - 2, 2, 0, 0, 0, 0, 0, 1, 1, 1, -1, -2, -1, -2, -1, 1, - -1, -1, -2, -2, -2, -3, -2, 0, -1, 0, -1, -1, -1, -2, -1, 1, - 1, 1, 0, 0, 1, 0, 0, 1, 2, 2, 0, 0, 1, 0, 0, 1, - 2, 2, 0, 0, 0, 0, -1, -1, 2, 2, 0, 0, 1, 0, -1, -1, - -1, 0, 1, 1, 0, -1, -1, -1, 1, 2, 3, 2, 1, 0, 0, 0, - 0, 1, 1, 1, 0, -1, 0, 0, -2, -2, -1, 0, 1, 0, 0, 0, - -2, -2, -1, 2, 2, 2, 1, 0, -2, -1, 0, 1, 1, 0, 0, -1, - -1, -1, 0, 0, -1, -2, -1, -2, 0, 1, 1, 1, 0, 0, 1, 1, - -3, -3, -3, -2, -1, -1, -2, -2, -1, -1, 0, 1, 2, 1, 0, 0, - 1, 1, 1, 2, 2, 1, 0, 0, 1, 1, 1, 1, 1, 0, -1, 1, - 1, 0, -1, -1, 0, 0, -1, 1, 0, -1, -1, -1, 0, -1, -1, 1, - 1, 0, -1, 0, 0, -1, 0, 2, 2, 0, -1, 0, 0, 0, 0, 2, - 1, 0, -2, -1, 0, 1, 1, 0, 2, 0, -1, -1, 0, 1, 1, 0, - 1, 0, -2, -1, 0, 1, 0, -1, 1, 0, -1, -1, 0, 1, 0, -1, - 0, 1, 1, 0, 1, 1, 0, 0, -2, 1, 2, 1, 0, 0, 0, 1, - -5, 0, 2, 1, 0, -1, 0, 1, -6, -1, 2, 1, 0, -1, 0, 0, - 5, 3, 0, -1, -2, -1, -1, -1, 1, 1, 0, -1, -1, 0, -1, -1, - -1, 0, 1, 1, 2, 2, 1, 0, -2, -1, 0, 1, 2, 1, 1, 1, - -2, -1, -1, -1, 0, -1, 0, 1, 0, 1, 0, 0, -1, -1, 0, 0, - 0, 1, 1, 1, 1, 0, 0, 0, -3, -2, 0, 1, 1, 0, 0, -1, - -1, 0, 1, 0, -1, 0, 2, 3, -1, 0, 0, -2, -4, -2, -1, 0, - 0, 1, 1, 0, -2, -1, 0, -1, 1, 2, 3, 1, 0, 1, 1, 0, - -1, 0, 1, 1, 1, 1, 1, 0, -2, -3, -2, 0, 0, 0, 1, 0, - -1, -2, -2, 0, 1, 0, 0, -1, 3, 1, 0, 0, 1, 0, -1, -1, - -2, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, 0, 1, 1, 1, - -1, -1, -1, 0, 1, 1, 1, 1, 0, -2, -3, -1, 1, 0, 0, 0, - 1, -1, -3, -1, 1, 1, 0, -1, 3, 1, -1, 1, 2, 2, 0, -1, - 3, 1, 0, 1, 2, 1, 1, 0, 0, -2, -2, -1, -1, 0, 0, 0, - 1, 0, -1, -1, 1, 2, 1, 0, 0, -1, -2, -1, 1, 2, 2, 1, - -1, -1, -1, 0, 0, 1, 2, 0, -2, 0, 0, 0, 0, 0, 1, -1, - -1, 0, 1, 0, -1, -1, -1, -1, 0, 1, 1, 2, 0, -2, -1, 0, - 1, 2, 2, 2, 1, -1, -1, 0, 0, 1, 1, 1, 0, -2, -2, -1, - 0, 0, -1, -1, -1, -1, -2, -2, 0, 0, -1, 0, 1, 2, 2, 1, - 0, 0, -1, -1, 0, 1, 2, 2, 1, 1, -1, -2, -1, -1, -1, -1, - 2, 2, 1, 0, 0, -1, -2, -2, 1, 2, 2, 1, 0, 0, -2, -2, - 0, 0, 0, 0, 1, 1, 0, -1, 0, -1, -1, -1, 2, 3, 2, 1, - 0, -2, 1, 2, -1, 0, 0, 1, -1, -2, 2, 3, -1, 0, 0, 0, - 0, -2, 2, 3, -1, -1, 0, 0, 0, -1, 3, 2, -2, 0, 1, 0, - 0, -1, 3, 1, -2, 0, 1, 0, 0, -1, 2, 1, -1, 1, 0, -1, - 0, 0, 1, -1, -2, 0, 0, -1, 1, 0, 0, -2, -2, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -2, 0, 0, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 2, 3, 1, 0, 0, -1, 0, 0, 1, 2, - 0, -1, -1, -2, -1, 0, 1, 2, -2, -2, -2, -2, -1, 0, 1, 1, - -1, -1, -1, -1, 0, 0, 0, -1, 2, 2, 2, 0, -1, -1, -2, -4, - -1, -2, -1, -1, 0, 1, 2, 3, -1, -1, -1, -1, 0, 1, 2, 3, - 1, 0, -1, 0, -1, 0, 1, 2, 1, 0, 0, 0, -1, 0, 2, 2, - 1, 0, -1, -1, -2, 0, 1, 2, 0, -2, -2, -2, -3, -1, 0, 1, - 0, -2, -2, -2, -2, -1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 2 -}; - -/* list of codebooks for intra-coded vectors */ -const int8_t* const ff_svq1_intra_codebooks[6] = { - svq1_intra_codebook_4x2, svq1_intra_codebook_4x4, - svq1_intra_codebook_8x4, svq1_intra_codebook_8x8, - NULL, NULL, -}; - -#endif /* AVCODEC_SVQ1_CB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/svq1_vlc.h b/tizen/distrib/ffmpeg/libavcodec/svq1_vlc.h deleted file mode 100644 index 272597e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq1_vlc.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SVQ1_VLC_H -#define AVCODEC_SVQ1_VLC_H - -#include - -/* values in this table range from 0..3; adjust retrieved value by +0 */ -const uint8_t ff_svq1_block_type_vlc[4][2] = { - /* { code, length } */ - { 0x1, 1 }, { 0x1, 2 }, { 0x1, 3 }, { 0x0, 3 } - -}; - -/* values in this table range from -1..6; adjust retrieved value by -1 */ -const uint8_t ff_svq1_intra_multistage_vlc[6][8][2] = { - /* { code, length } */ -{ - { 0x1, 5 }, { 0x1, 1 }, { 0x3, 3 }, { 0x2, 3 }, - { 0x3, 4 }, { 0x2, 4 }, { 0x0, 5 }, { 0x1, 4 } -},{ - { 0x1, 4 }, { 0x3, 2 }, { 0x5, 3 }, { 0x4, 3 }, - { 0x3, 3 }, { 0x2, 3 }, { 0x0, 4 }, { 0x1, 3 } -},{ - { 0x1, 5 }, { 0x1, 1 }, { 0x3, 3 }, { 0x0, 5 }, - { 0x3, 4 }, { 0x2, 3 }, { 0x2, 4 }, { 0x1, 4 } -},{ - { 0x1, 6 }, { 0x1, 1 }, { 0x1, 2 }, { 0x0, 6 }, - { 0x3, 4 }, { 0x2, 4 }, { 0x1, 5 }, { 0x1, 4 } -},{ - { 0x1, 6 }, { 0x1, 1 }, { 0x1, 2 }, { 0x3, 5 }, - { 0x2, 5 }, { 0x0, 6 }, { 0x1, 5 }, { 0x1, 3 } -},{ - { 0x1, 7 }, { 0x1, 1 }, { 0x1, 2 }, { 0x1, 3 }, - { 0x1, 4 }, { 0x1, 6 }, { 0x0, 7 }, { 0x1, 5 } -} -}; - -/* values in this table range from -1..6; adjust retrieved value by -1 */ -const uint8_t ff_svq1_inter_multistage_vlc[6][8][2] = { - /* { code, length } */ -{ - { 0x3, 2 }, { 0x5, 3 }, { 0x4, 3 }, { 0x3, 3 }, - { 0x2, 3 }, { 0x1, 3 }, { 0x1, 4 }, { 0x0, 4 } -},{ - { 0x3, 2 }, { 0x5, 3 }, { 0x4, 3 }, { 0x3, 3 }, - { 0x2, 3 }, { 0x1, 3 }, { 0x1, 4 }, { 0x0, 4 } -},{ - { 0x1, 1 }, { 0x3, 3 }, { 0x2, 3 }, { 0x3, 4 }, - { 0x2, 4 }, { 0x1, 4 }, { 0x1, 5 }, { 0x0, 5 } -},{ - { 0x1, 1 }, { 0x3, 3 }, { 0x2, 3 }, { 0x3, 4 }, - { 0x2, 4 }, { 0x1, 4 }, { 0x1, 5 }, { 0x0, 5 } -},{ - { 0x1, 1 }, { 0x3, 3 }, { 0x2, 3 }, { 0x3, 4 }, - { 0x2, 4 }, { 0x1, 4 }, { 0x1, 5 }, { 0x0, 5 } -},{ - { 0x1, 1 }, { 0x1, 2 }, { 0x1, 3 }, { 0x3, 5 }, - { 0x2, 5 }, { 0x1, 5 }, { 0x1, 6 }, { 0x0, 6 } -} -}; - -/* values in this table range from 0..255; adjust retrieved value by +0 */ -const uint16_t ff_svq1_intra_mean_vlc[256][2] = { - /* { code, length } */ - { 0x37, 6 }, { 0x56, 7 }, { 0x1, 17 }, { 0x1, 20 }, - { 0x2, 20 }, { 0x3, 20 }, { 0x0, 20 }, { 0x4, 20 }, - { 0x5, 20 }, { 0x3, 19 }, { 0x15, 11 }, { 0x42, 9 }, - { 0x14, 11 }, { 0x3, 14 }, { 0x2, 14 }, { 0x1, 15 }, - { 0x1, 16 }, { 0x1, 12 }, { 0x2B, 10 }, { 0x18, 11 }, - { 0xC, 11 }, { 0x41, 9 }, { 0x78, 8 }, { 0x6C, 8 }, - { 0x55, 7 }, { 0xF, 4 }, { 0xE, 4 }, { 0x34, 6 }, - { 0x51, 7 }, { 0x72, 8 }, { 0x6E, 8 }, { 0x40, 9 }, - { 0x3F, 9 }, { 0x3E, 9 }, { 0x3D, 9 }, { 0x3C, 9 }, - { 0x3B, 9 }, { 0x3A, 9 }, { 0x39, 9 }, { 0x38, 9 }, - { 0x37, 9 }, { 0x43, 9 }, { 0x46, 9 }, { 0x47, 9 }, - { 0x45, 9 }, { 0x44, 9 }, { 0x49, 9 }, { 0x48, 9 }, - { 0x4A, 8 }, { 0x79, 8 }, { 0x76, 8 }, { 0x77, 8 }, - { 0x71, 8 }, { 0x75, 8 }, { 0x74, 8 }, { 0x73, 8 }, - { 0x6A, 8 }, { 0x55, 8 }, { 0x70, 8 }, { 0x6F, 8 }, - { 0x52, 8 }, { 0x6D, 8 }, { 0x4C, 8 }, { 0x6B, 8 }, - { 0x40, 7 }, { 0x69, 8 }, { 0x68, 8 }, { 0x67, 8 }, - { 0x66, 8 }, { 0x65, 8 }, { 0x64, 8 }, { 0x63, 8 }, - { 0x62, 8 }, { 0x61, 8 }, { 0x60, 8 }, { 0x5F, 8 }, - { 0x5E, 8 }, { 0x5D, 8 }, { 0x5C, 8 }, { 0x5B, 8 }, - { 0x5A, 8 }, { 0x59, 8 }, { 0x58, 8 }, { 0x57, 8 }, - { 0x56, 8 }, { 0x3D, 7 }, { 0x54, 8 }, { 0x53, 8 }, - { 0x3F, 7 }, { 0x51, 8 }, { 0x50, 8 }, { 0x4F, 8 }, - { 0x4E, 8 }, { 0x4D, 8 }, { 0x41, 7 }, { 0x4B, 8 }, - { 0x53, 7 }, { 0x3E, 7 }, { 0x48, 8 }, { 0x4F, 7 }, - { 0x52, 7 }, { 0x45, 8 }, { 0x50, 7 }, { 0x43, 8 }, - { 0x42, 8 }, { 0x41, 8 }, { 0x42, 7 }, { 0x43, 7 }, - { 0x3E, 8 }, { 0x44, 7 }, { 0x3C, 8 }, { 0x45, 7 }, - { 0x46, 7 }, { 0x47, 7 }, { 0x48, 7 }, { 0x49, 7 }, - { 0x4A, 7 }, { 0x4B, 7 }, { 0x4C, 7 }, { 0x4D, 7 }, - { 0x4E, 7 }, { 0x58, 7 }, { 0x59, 7 }, { 0x5A, 7 }, - { 0x5B, 7 }, { 0x5C, 7 }, { 0x5D, 7 }, { 0x44, 8 }, - { 0x49, 8 }, { 0x29, 8 }, { 0x3F, 8 }, { 0x3D, 8 }, - { 0x3B, 8 }, { 0x2C, 8 }, { 0x28, 8 }, { 0x25, 8 }, - { 0x26, 8 }, { 0x5E, 7 }, { 0x57, 7 }, { 0x54, 7 }, - { 0x5F, 7 }, { 0x62, 7 }, { 0x63, 7 }, { 0x64, 7 }, - { 0x61, 7 }, { 0x65, 7 }, { 0x67, 7 }, { 0x66, 7 }, - { 0x35, 6 }, { 0x36, 6 }, { 0x60, 7 }, { 0x39, 8 }, - { 0x3A, 8 }, { 0x38, 8 }, { 0x37, 8 }, { 0x36, 8 }, - { 0x35, 8 }, { 0x34, 8 }, { 0x33, 8 }, { 0x32, 8 }, - { 0x31, 8 }, { 0x30, 8 }, { 0x2D, 8 }, { 0x2B, 8 }, - { 0x2A, 8 }, { 0x27, 8 }, { 0x40, 8 }, { 0x46, 8 }, - { 0x47, 8 }, { 0x26, 9 }, { 0x25, 9 }, { 0x24, 9 }, - { 0x23, 9 }, { 0x22, 9 }, { 0x2E, 8 }, { 0x2F, 8 }, - { 0x1F, 9 }, { 0x36, 9 }, { 0x1D, 9 }, { 0x21, 9 }, - { 0x1B, 9 }, { 0x1C, 9 }, { 0x19, 9 }, { 0x1A, 9 }, - { 0x18, 9 }, { 0x17, 9 }, { 0x16, 9 }, { 0x1E, 9 }, - { 0x20, 9 }, { 0x27, 9 }, { 0x28, 9 }, { 0x29, 9 }, - { 0x2A, 9 }, { 0x2B, 9 }, { 0x2C, 9 }, { 0x2D, 9 }, - { 0x2E, 9 }, { 0x2F, 9 }, { 0x30, 9 }, { 0x35, 9 }, - { 0x31, 9 }, { 0x32, 9 }, { 0x33, 9 }, { 0x34, 9 }, - { 0x19, 10 }, { 0x2A, 10 }, { 0x17, 10 }, { 0x16, 10 }, - { 0x15, 10 }, { 0x28, 10 }, { 0x26, 10 }, { 0x25, 10 }, - { 0x22, 10 }, { 0x21, 10 }, { 0x18, 10 }, { 0x14, 10 }, - { 0x29, 10 }, { 0x12, 10 }, { 0xD, 10 }, { 0xE, 10 }, - { 0xF, 10 }, { 0x10, 10 }, { 0x11, 10 }, { 0x1A, 10 }, - { 0x1B, 10 }, { 0x1C, 10 }, { 0x1D, 10 }, { 0x1E, 10 }, - { 0x1F, 10 }, { 0x20, 10 }, { 0x13, 10 }, { 0x23, 10 }, - { 0x24, 10 }, { 0x9, 11 }, { 0x8, 11 }, { 0x7, 11 }, - { 0x27, 10 }, { 0x5, 11 }, { 0xB, 11 }, { 0x6, 11 }, - { 0x4, 11 }, { 0x3, 11 }, { 0x2, 11 }, { 0x1, 11 }, - { 0xA, 11 }, { 0x16, 11 }, { 0x19, 11 }, { 0x17, 11 }, - { 0xD, 11 }, { 0xE, 11 }, { 0xF, 11 }, { 0x10, 11 }, - { 0x11, 11 }, { 0x12, 11 }, { 0x13, 11 }, { 0x1, 14 } -}; - -/* values in this table range from -256..255; adjust retrieved value by -256 */ -const uint16_t ff_svq1_inter_mean_vlc[512][2] = { - /* { code, length } */ - { 0x5A, 22 }, { 0xD4, 22 }, { 0xD5, 22 }, { 0xD6, 22 }, - { 0xD7, 22 }, { 0xD8, 22 }, { 0xD9, 22 }, { 0xDA, 22 }, - { 0xDB, 22 }, { 0xDC, 22 }, { 0xDD, 22 }, { 0xDE, 22 }, - { 0xDF, 22 }, { 0xE0, 22 }, { 0xE1, 22 }, { 0xE2, 22 }, - { 0xE3, 22 }, { 0xE4, 22 }, { 0xE5, 22 }, { 0xE6, 22 }, - { 0xE8, 22 }, { 0xCB, 22 }, { 0xE9, 22 }, { 0xEA, 22 }, - { 0xE7, 22 }, { 0xEC, 22 }, { 0xED, 22 }, { 0xEE, 22 }, - { 0xEF, 22 }, { 0xF0, 22 }, { 0xF1, 22 }, { 0xF2, 22 }, - { 0xF3, 22 }, { 0xF4, 22 }, { 0xF5, 22 }, { 0xF6, 22 }, - { 0xF7, 22 }, { 0xF8, 22 }, { 0x102, 22 }, { 0xEB, 22 }, - { 0xF9, 22 }, { 0xFC, 22 }, { 0xFD, 22 }, { 0xFE, 22 }, - { 0x100, 22 }, { 0x5C, 22 }, { 0x60, 22 }, { 0x101, 22 }, - { 0x71, 22 }, { 0x104, 22 }, { 0x105, 22 }, { 0xFB, 22 }, - { 0xFF, 22 }, { 0x86, 21 }, { 0xFA, 22 }, { 0x7C, 22 }, - { 0x75, 22 }, { 0x103, 22 }, { 0x78, 22 }, { 0xD3, 22 }, - { 0x7B, 22 }, { 0x82, 22 }, { 0xD2, 22 }, { 0xD1, 22 }, - { 0xD0, 22 }, { 0xCF, 22 }, { 0xCE, 22 }, { 0xCD, 22 }, - { 0xCC, 22 }, { 0xC3, 22 }, { 0xCA, 22 }, { 0xC9, 22 }, - { 0xC8, 22 }, { 0xC7, 22 }, { 0xC6, 22 }, { 0xC5, 22 }, - { 0x8B, 22 }, { 0xC4, 22 }, { 0xC2, 22 }, { 0xC1, 22 }, - { 0xC0, 22 }, { 0xBF, 22 }, { 0xBE, 22 }, { 0xBD, 22 }, - { 0xBC, 22 }, { 0xBB, 22 }, { 0xBA, 22 }, { 0xB9, 22 }, - { 0x61, 22 }, { 0x84, 22 }, { 0x85, 22 }, { 0x86, 22 }, - { 0x87, 22 }, { 0x88, 22 }, { 0x89, 22 }, { 0x8A, 22 }, - { 0x8C, 22 }, { 0x8D, 22 }, { 0x8E, 22 }, { 0x8F, 22 }, - { 0x90, 22 }, { 0x91, 22 }, { 0x92, 22 }, { 0x93, 22 }, - { 0x94, 22 }, { 0x95, 22 }, { 0x96, 22 }, { 0x97, 22 }, - { 0x98, 22 }, { 0x99, 22 }, { 0x9A, 22 }, { 0x9B, 22 }, - { 0x9C, 22 }, { 0x9D, 22 }, { 0x9E, 22 }, { 0x9F, 22 }, - { 0xA0, 22 }, { 0xA1, 22 }, { 0xA2, 22 }, { 0xA3, 22 }, - { 0xA4, 22 }, { 0xA5, 22 }, { 0xA6, 22 }, { 0xA7, 22 }, - { 0xA8, 22 }, { 0xA9, 22 }, { 0xAA, 22 }, { 0xAB, 22 }, - { 0x7F, 22 }, { 0x8F, 21 }, { 0xAC, 22 }, { 0xAD, 22 }, - { 0xAE, 22 }, { 0xAF, 22 }, { 0xB0, 22 }, { 0xB1, 22 }, - { 0x53, 20 }, { 0x90, 21 }, { 0xB2, 22 }, { 0x91, 21 }, - { 0xB3, 22 }, { 0xB4, 22 }, { 0x54, 20 }, { 0xB5, 22 }, - { 0xB6, 22 }, { 0x8C, 21 }, { 0x34, 19 }, { 0x3D, 18 }, - { 0x55, 20 }, { 0xB7, 22 }, { 0xB8, 22 }, { 0x8B, 21 }, - { 0x56, 20 }, { 0x3D, 19 }, { 0x57, 20 }, { 0x58, 20 }, - { 0x40, 19 }, { 0x43, 19 }, { 0x47, 19 }, { 0x2A, 18 }, - { 0x2E, 19 }, { 0x2C, 18 }, { 0x46, 19 }, { 0x59, 20 }, - { 0x49, 19 }, { 0x2D, 19 }, { 0x38, 18 }, { 0x36, 18 }, - { 0x39, 18 }, { 0x45, 19 }, { 0x28, 18 }, { 0x30, 18 }, - { 0x35, 18 }, { 0x20, 17 }, { 0x44, 19 }, { 0x32, 18 }, - { 0x31, 18 }, { 0x1F, 17 }, { 0x2F, 18 }, { 0x2E, 18 }, - { 0x2D, 18 }, { 0x21, 17 }, { 0x22, 17 }, { 0x23, 17 }, - { 0x24, 17 }, { 0x27, 16 }, { 0x23, 16 }, { 0x20, 16 }, - { 0x1D, 16 }, { 0x25, 16 }, { 0x1E, 16 }, { 0x24, 16 }, - { 0x2A, 16 }, { 0x26, 16 }, { 0x21, 15 }, { 0x29, 16 }, - { 0x22, 15 }, { 0x23, 15 }, { 0x24, 15 }, { 0x1B, 15 }, - { 0x1A, 15 }, { 0x1D, 15 }, { 0x1F, 15 }, { 0x27, 15 }, - { 0x17, 14 }, { 0x18, 14 }, { 0x19, 14 }, { 0x1B, 14 }, - { 0x1C, 14 }, { 0x1E, 14 }, { 0x25, 14 }, { 0x20, 14 }, - { 0x21, 14 }, { 0x13, 13 }, { 0x14, 13 }, { 0x15, 13 }, - { 0x16, 13 }, { 0x17, 13 }, { 0x18, 13 }, { 0x19, 13 }, - { 0x1A, 13 }, { 0x18, 12 }, { 0x17, 12 }, { 0x15, 12 }, - { 0x14, 12 }, { 0x13, 12 }, { 0x12, 12 }, { 0xF, 11 }, - { 0x10, 11 }, { 0x12, 11 }, { 0x13, 11 }, { 0x1B, 11 }, - { 0x1A, 11 }, { 0xE, 10 }, { 0x13, 10 }, { 0xF, 10 }, - { 0x10, 10 }, { 0x11, 10 }, { 0x12, 10 }, { 0xD, 9 }, - { 0x14, 9 }, { 0x15, 9 }, { 0xC, 9 }, { 0x13, 9 }, - { 0xF, 8 }, { 0xE, 8 }, { 0x10, 8 }, { 0x11, 8 }, - { 0xC, 7 }, { 0x9, 7 }, { 0xA, 7 }, { 0x8, 6 }, - { 0x9, 6 }, { 0x9, 5 }, { 0x8, 5 }, { 0x5, 4 }, - { 0x1, 1 }, { 0x3, 3 }, { 0x7, 5 }, { 0x6, 5 }, - { 0xB, 6 }, { 0xA, 6 }, { 0xE, 7 }, { 0xF, 7 }, - { 0xB, 7 }, { 0xD, 7 }, { 0xB, 8 }, { 0xD, 8 }, - { 0xC, 8 }, { 0xF, 9 }, { 0x10, 9 }, { 0x11, 9 }, - { 0xE, 9 }, { 0x12, 9 }, { 0x17, 10 }, { 0x14, 10 }, - { 0x16, 10 }, { 0x15, 10 }, { 0x19, 11 }, { 0x18, 11 }, - { 0x17, 11 }, { 0x16, 11 }, { 0x15, 11 }, { 0x14, 11 }, - { 0x11, 11 }, { 0x19, 12 }, { 0x1A, 12 }, { 0x16, 12 }, - { 0x1D, 12 }, { 0x1B, 12 }, { 0x1C, 12 }, { 0x20, 13 }, - { 0x1C, 13 }, { 0x23, 13 }, { 0x22, 13 }, { 0x21, 13 }, - { 0x1F, 13 }, { 0x1E, 13 }, { 0x1B, 13 }, { 0x1D, 13 }, - { 0x24, 14 }, { 0x16, 14 }, { 0x1A, 14 }, { 0x22, 14 }, - { 0x1D, 14 }, { 0x1F, 14 }, { 0x15, 14 }, { 0x23, 14 }, - { 0x18, 15 }, { 0x20, 15 }, { 0x29, 15 }, { 0x28, 15 }, - { 0x26, 15 }, { 0x25, 15 }, { 0x19, 15 }, { 0x1C, 15 }, - { 0x1E, 15 }, { 0x17, 15 }, { 0x2C, 16 }, { 0x2B, 16 }, - { 0x1C, 16 }, { 0x21, 16 }, { 0x2D, 16 }, { 0x28, 16 }, - { 0x1F, 16 }, { 0x1B, 16 }, { 0x1A, 16 }, { 0x22, 16 }, - { 0x2D, 17 }, { 0x32, 17 }, { 0x2C, 17 }, { 0x27, 17 }, - { 0x31, 17 }, { 0x33, 17 }, { 0x2F, 17 }, { 0x2B, 17 }, - { 0x37, 18 }, { 0x2A, 17 }, { 0x2E, 17 }, { 0x30, 17 }, - { 0x29, 17 }, { 0x28, 17 }, { 0x26, 17 }, { 0x25, 17 }, - { 0x2F, 19 }, { 0x33, 18 }, { 0x34, 18 }, { 0x30, 19 }, - { 0x3A, 18 }, { 0x3B, 18 }, { 0x31, 19 }, { 0x3C, 18 }, - { 0x2B, 18 }, { 0x29, 18 }, { 0x48, 19 }, { 0x27, 18 }, - { 0x42, 19 }, { 0x41, 19 }, { 0x26, 18 }, { 0x52, 20 }, - { 0x51, 20 }, { 0x3F, 19 }, { 0x3E, 19 }, { 0x39, 19 }, - { 0x3C, 19 }, { 0x3B, 19 }, { 0x3A, 19 }, { 0x25, 18 }, - { 0x38, 19 }, { 0x50, 20 }, { 0x37, 19 }, { 0x36, 19 }, - { 0x87, 21 }, { 0x4F, 20 }, { 0x35, 19 }, { 0x4E, 20 }, - { 0x33, 19 }, { 0x32, 19 }, { 0x4D, 20 }, { 0x4C, 20 }, - { 0x83, 22 }, { 0x4B, 20 }, { 0x81, 22 }, { 0x80, 22 }, - { 0x8E, 21 }, { 0x7E, 22 }, { 0x7D, 22 }, { 0x84, 21 }, - { 0x8D, 21 }, { 0x7A, 22 }, { 0x79, 22 }, { 0x4A, 20 }, - { 0x77, 22 }, { 0x76, 22 }, { 0x89, 21 }, { 0x74, 22 }, - { 0x73, 22 }, { 0x72, 22 }, { 0x49, 20 }, { 0x70, 22 }, - { 0x6F, 22 }, { 0x6E, 22 }, { 0x6D, 22 }, { 0x6C, 22 }, - { 0x6B, 22 }, { 0x6A, 22 }, { 0x69, 22 }, { 0x68, 22 }, - { 0x67, 22 }, { 0x66, 22 }, { 0x65, 22 }, { 0x64, 22 }, - { 0x63, 22 }, { 0x62, 22 }, { 0x8A, 21 }, { 0x88, 21 }, - { 0x5F, 22 }, { 0x5E, 22 }, { 0x5D, 22 }, { 0x85, 21 }, - { 0x5B, 22 }, { 0x83, 21 }, { 0x59, 22 }, { 0x58, 22 }, - { 0x57, 22 }, { 0x56, 22 }, { 0x55, 22 }, { 0x54, 22 }, - { 0x53, 22 }, { 0x52, 22 }, { 0x51, 22 }, { 0x50, 22 }, - { 0x4F, 22 }, { 0x4E, 22 }, { 0x4D, 22 }, { 0x4C, 22 }, - { 0x4B, 22 }, { 0x4A, 22 }, { 0x49, 22 }, { 0x48, 22 }, - { 0x47, 22 }, { 0x46, 22 }, { 0x45, 22 }, { 0x44, 22 }, - { 0x43, 22 }, { 0x42, 22 }, { 0x41, 22 }, { 0x40, 22 }, - { 0x3F, 22 }, { 0x3E, 22 }, { 0x3D, 22 }, { 0x3C, 22 }, - { 0x3B, 22 }, { 0x3A, 22 }, { 0x39, 22 }, { 0x38, 22 }, - { 0x37, 22 }, { 0x36, 22 }, { 0x35, 22 }, { 0x34, 22 }, - { 0x33, 22 }, { 0x32, 22 }, { 0x31, 22 }, { 0x30, 22 }, - { 0x2F, 22 }, { 0x2E, 22 }, { 0x2D, 22 }, { 0x2C, 22 }, - { 0x2B, 22 }, { 0x2A, 22 }, { 0x29, 22 }, { 0x28, 22 }, - { 0x27, 22 }, { 0x26, 22 }, { 0x25, 22 }, { 0x24, 22 }, - { 0x23, 22 }, { 0x22, 22 }, { 0x21, 22 }, { 0x20, 22 }, - { 0x1F, 22 }, { 0x1E, 22 }, { 0x1D, 22 }, { 0x1C, 22 }, - { 0x1B, 22 }, { 0x1A, 22 }, { 0x19, 22 }, { 0x18, 22 }, - { 0x17, 22 }, { 0x16, 22 }, { 0x15, 22 }, { 0x14, 22 }, - { 0x13, 22 }, { 0x12, 22 }, { 0x11, 22 }, { 0x10, 22 }, - { 0xF, 22 }, { 0xE, 22 }, { 0xD, 22 }, { 0xC, 22 }, - { 0xB, 22 }, { 0xA, 22 }, { 0x9, 22 }, { 0x8, 22 }, - { 0x7, 22 }, { 0x6, 22 }, { 0x5, 22 }, { 0x4, 22 }, - { 0x3, 22 }, { 0x2, 22 }, { 0x1, 22 }, { 0x0, 22 } -}; - -#endif /* AVCODEC_SVQ1_VLC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/svq1dec.c b/tizen/distrib/ffmpeg/libavcodec/svq1dec.c deleted file mode 100644 index 2aa28ab..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq1dec.c +++ /dev/null @@ -1,842 +0,0 @@ -/* - * SVQ1 decoder - * ported to MPlayer by Arpi - * ported to libavcodec by Nick Kurshev - * - * Copyright (C) 2002 the xine project - * Copyright (C) 2002 the ffmpeg project - * - * SVQ1 Encoder (c) 2004 Mike Melanson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sorenson Vector Quantizer #1 (SVQ1) video codec. - * For more information of the SVQ1 algorithm, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - - -//#define DEBUG_SVQ1 -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "mathops.h" - -#include "svq1.h" - -#undef NDEBUG -#include - -extern const uint8_t mvtab[33][2]; - -static VLC svq1_block_type; -static VLC svq1_motion_component; -static VLC svq1_intra_multistage[6]; -static VLC svq1_inter_multistage[6]; -static VLC svq1_intra_mean; -static VLC svq1_inter_mean; - -/* motion vector (prediction) */ -typedef struct svq1_pmv_s { - int x; - int y; -} svq1_pmv; - -static const uint16_t checksum_table[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, - 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, - 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, - 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, - 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, - 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, - 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, - 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, - 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, - 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, - 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, - 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, - 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, - 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, - 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, - 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, - 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, - 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, - 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, - 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, - 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, - 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, - 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 -}; - -static const uint8_t string_table[256] = { - 0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, - 0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D, - 0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, - 0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F, - 0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0, - 0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9, - 0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2, - 0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B, - 0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9, - 0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0, - 0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B, - 0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2, - 0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D, - 0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44, - 0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F, - 0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16, - 0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB, - 0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92, - 0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9, - 0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0, - 0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F, - 0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36, - 0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D, - 0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64, - 0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26, - 0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F, - 0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74, - 0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D, - 0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82, - 0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB, - 0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0, - 0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9 -}; - -#define SVQ1_PROCESS_VECTOR()\ - for (; level > 0; i++) {\ - /* process next depth */\ - if (i == m) {\ - m = n;\ - if (--level == 0)\ - break;\ - }\ - /* divide block if next bit set */\ - if (get_bits1 (bitbuf) == 0)\ - break;\ - /* add child nodes */\ - list[n++] = list[i];\ - list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level / 2) + 1));\ - } - -#define SVQ1_ADD_CODEBOOK()\ - /* add codebook entries to vector */\ - for (j=0; j < stages; j++) {\ - n3 = codebook[entries[j]] ^ 0x80808080;\ - n1 += ((n3 & 0xFF00FF00) >> 8);\ - n2 += (n3 & 0x00FF00FF);\ - }\ -\ - /* clip to [0..255] */\ - if (n1 & 0xFF00FF00) {\ - n3 = ((( n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n1 += 0x7F007F00;\ - n1 |= (((~n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n1 &= (n3 & 0x00FF00FF);\ - }\ -\ - if (n2 & 0xFF00FF00) {\ - n3 = ((( n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n2 += 0x7F007F00;\ - n2 |= (((~n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n2 &= (n3 & 0x00FF00FF);\ - } - -#define SVQ1_DO_CODEBOOK_INTRA()\ - for (y=0; y < height; y++) {\ - for (x=0; x < (width / 4); x++, codebook++) {\ - n1 = n4;\ - n2 = n4;\ - SVQ1_ADD_CODEBOOK()\ - /* store result */\ - dst[x] = (n1 << 8) | n2;\ - }\ - dst += (pitch / 4);\ - } - -#define SVQ1_DO_CODEBOOK_NONINTRA()\ - for (y=0; y < height; y++) {\ - for (x=0; x < (width / 4); x++, codebook++) {\ - n3 = dst[x];\ - /* add mean value to vector */\ - n1 = ((n3 & 0xFF00FF00) >> 8) + n4;\ - n2 = (n3 & 0x00FF00FF) + n4;\ - SVQ1_ADD_CODEBOOK()\ - /* store result */\ - dst[x] = (n1 << 8) | n2;\ - }\ - dst += (pitch / 4);\ - } - -#define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)\ - codebook = (const uint32_t *) cbook[level];\ - bit_cache = get_bits (bitbuf, 4*stages);\ - /* calculate codebook entries for this vector */\ - for (j=0; j < stages; j++) {\ - entries[j] = (((bit_cache >> (4*(stages - j - 1))) & 0xF) + 16*j) << (level + 1);\ - }\ - mean -= (stages * 128);\ - n4 = ((mean + (mean >> 31)) << 16) | (mean & 0xFFFF); - -static int svq1_decode_block_intra (GetBitContext *bitbuf, uint8_t *pixels, int pitch ) { - uint32_t bit_cache; - uint8_t *list[63]; - uint32_t *dst; - const uint32_t *codebook; - int entries[6]; - int i, j, m, n; - int mean, stages; - unsigned x, y, width, height, level; - uint32_t n1, n2, n3, n4; - - /* initialize list for breadth first processing of vectors */ - list[0] = pixels; - - /* recursively process vector */ - for (i=0, m=1, n=1, level=5; i < n; i++) { - SVQ1_PROCESS_VECTOR(); - - /* destination address and vector size */ - dst = (uint32_t *) list[i]; - width = 1 << ((4 + level) /2); - height = 1 << ((3 + level) /2); - - /* get number of stages (-1 skips vector, 0 for mean only) */ - stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1; - - if (stages == -1) { - for (y=0; y < height; y++) { - memset (&dst[y*(pitch / 4)], 0, width); - } - continue; /* skip vector */ - } - - if ((stages > 0) && (level >= 4)) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",stages,level); -#endif - return -1; /* invalid vector */ - } - - mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3); - - if (stages == 0) { - for (y=0; y < height; y++) { - memset (&dst[y*(pitch / 4)], mean, width); - } - } else { - SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_intra_codebooks); - SVQ1_DO_CODEBOOK_INTRA() - } - } - - return 0; -} - -static int svq1_decode_block_non_intra (GetBitContext *bitbuf, uint8_t *pixels, int pitch ) { - uint32_t bit_cache; - uint8_t *list[63]; - uint32_t *dst; - const uint32_t *codebook; - int entries[6]; - int i, j, m, n; - int mean, stages; - int x, y, width, height, level; - uint32_t n1, n2, n3, n4; - - /* initialize list for breadth first processing of vectors */ - list[0] = pixels; - - /* recursively process vector */ - for (i=0, m=1, n=1, level=5; i < n; i++) { - SVQ1_PROCESS_VECTOR(); - - /* destination address and vector size */ - dst = (uint32_t *) list[i]; - width = 1 << ((4 + level) /2); - height = 1 << ((3 + level) /2); - - /* get number of stages (-1 skips vector, 0 for mean only) */ - stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1; - - if (stages == -1) continue; /* skip vector */ - - if ((stages > 0) && (level >= 4)) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",stages,level); -#endif - return -1; /* invalid vector */ - } - - mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256; - - SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks); - SVQ1_DO_CODEBOOK_NONINTRA() - } - return 0; -} - -static int svq1_decode_motion_vector (GetBitContext *bitbuf, svq1_pmv *mv, svq1_pmv **pmv) { - int diff; - int i; - - for (i=0; i < 2; i++) { - - /* get motion code */ - diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2); - if(diff<0) - return -1; - else if(diff){ - if(get_bits1(bitbuf)) diff= -diff; - } - - /* add median of motion vector predictors and clip result */ - if (i == 1) - mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; - else - mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; - } - - return 0; -} - -static void svq1_skip_block (uint8_t *current, uint8_t *previous, int pitch, int x, int y) { - uint8_t *src; - uint8_t *dst; - int i; - - src = &previous[x + y*pitch]; - dst = current; - - for (i=0; i < 16; i++) { - memcpy (dst, src, 16); - src += pitch; - dst += pitch; - } -} - -static int svq1_motion_inter_block (MpegEncContext *s, GetBitContext *bitbuf, - uint8_t *current, uint8_t *previous, int pitch, - svq1_pmv *motion, int x, int y) { - uint8_t *src; - uint8_t *dst; - svq1_pmv mv; - svq1_pmv *pmv[3]; - int result; - - /* predict and decode motion vector */ - pmv[0] = &motion[0]; - if (y == 0) { - pmv[1] = - pmv[2] = pmv[0]; - } - else { - pmv[1] = &motion[(x / 8) + 2]; - pmv[2] = &motion[(x / 8) + 4]; - } - - result = svq1_decode_motion_vector (bitbuf, &mv, pmv); - - if (result != 0) - return result; - - motion[0].x = - motion[(x / 8) + 2].x = - motion[(x / 8) + 3].x = mv.x; - motion[0].y = - motion[(x / 8) + 2].y = - motion[(x / 8) + 3].y = mv.y; - - if(y + (mv.y >> 1)<0) - mv.y= 0; - if(x + (mv.x >> 1)<0) - mv.x= 0; - -#if 0 - int w= (s->width+15)&~15; - int h= (s->height+15)&~15; - if(x + (mv.x >> 1)<0 || y + (mv.y >> 1)<0 || x + (mv.x >> 1) + 16 > w || y + (mv.y >> 1) + 16> h) - av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mv.x >> 1), y + (mv.y >> 1)); -#endif - - src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1))*pitch]; - dst = current; - - s->dsp.put_pixels_tab[0][((mv.y & 1) << 1) | (mv.x & 1)](dst,src,pitch,16); - - return 0; -} - -static int svq1_motion_inter_4v_block (MpegEncContext *s, GetBitContext *bitbuf, - uint8_t *current, uint8_t *previous, int pitch, - svq1_pmv *motion,int x, int y) { - uint8_t *src; - uint8_t *dst; - svq1_pmv mv; - svq1_pmv *pmv[4]; - int i, result; - - /* predict and decode motion vector (0) */ - pmv[0] = &motion[0]; - if (y == 0) { - pmv[1] = - pmv[2] = pmv[0]; - } - else { - pmv[1] = &motion[(x / 8) + 2]; - pmv[2] = &motion[(x / 8) + 4]; - } - - result = svq1_decode_motion_vector (bitbuf, &mv, pmv); - - if (result != 0) - return result; - - /* predict and decode motion vector (1) */ - pmv[0] = &mv; - if (y == 0) { - pmv[1] = - pmv[2] = pmv[0]; - } - else { - pmv[1] = &motion[(x / 8) + 3]; - } - result = svq1_decode_motion_vector (bitbuf, &motion[0], pmv); - - if (result != 0) - return result; - - /* predict and decode motion vector (2) */ - pmv[1] = &motion[0]; - pmv[2] = &motion[(x / 8) + 1]; - - result = svq1_decode_motion_vector (bitbuf, &motion[(x / 8) + 2], pmv); - - if (result != 0) - return result; - - /* predict and decode motion vector (3) */ - pmv[2] = &motion[(x / 8) + 2]; - pmv[3] = &motion[(x / 8) + 3]; - - result = svq1_decode_motion_vector (bitbuf, pmv[3], pmv); - - if (result != 0) - return result; - - /* form predictions */ - for (i=0; i < 4; i++) { - int mvx= pmv[i]->x + (i&1)*16; - int mvy= pmv[i]->y + (i>>1)*16; - - ///XXX /FIXME clipping or padding? - if(y + (mvy >> 1)<0) - mvy= 0; - if(x + (mvx >> 1)<0) - mvx= 0; - -#if 0 - int w= (s->width+15)&~15; - int h= (s->height+15)&~15; - if(x + (mvx >> 1)<0 || y + (mvy >> 1)<0 || x + (mvx >> 1) + 8 > w || y + (mvy >> 1) + 8> h) - av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mvx >> 1), y + (mvy >> 1)); -#endif - src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1))*pitch]; - dst = current; - - s->dsp.put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst,src,pitch,8); - - /* select next block */ - if (i & 1) { - current += 8*(pitch - 1); - } else { - current += 8; - } - } - - return 0; -} - -static int svq1_decode_delta_block (MpegEncContext *s, GetBitContext *bitbuf, - uint8_t *current, uint8_t *previous, int pitch, - svq1_pmv *motion, int x, int y) { - uint32_t block_type; - int result = 0; - - /* get block type */ - block_type = get_vlc2(bitbuf, svq1_block_type.table, 2, 2); - - /* reset motion vectors */ - if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) { - motion[0].x = - motion[0].y = - motion[(x / 8) + 2].x = - motion[(x / 8) + 2].y = - motion[(x / 8) + 3].x = - motion[(x / 8) + 3].y = 0; - } - - switch (block_type) { - case SVQ1_BLOCK_SKIP: - svq1_skip_block (current, previous, pitch, x, y); - break; - - case SVQ1_BLOCK_INTER: - result = svq1_motion_inter_block (s, bitbuf, current, previous, pitch, motion, x, y); - - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_block %i\n",result); -#endif - break; - } - result = svq1_decode_block_non_intra (bitbuf, current, pitch); - break; - - case SVQ1_BLOCK_INTER_4V: - result = svq1_motion_inter_4v_block (s, bitbuf, current, previous, pitch, motion, x, y); - - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_4v_block %i\n",result); -#endif - break; - } - result = svq1_decode_block_non_intra (bitbuf, current, pitch); - break; - - case SVQ1_BLOCK_INTRA: - result = svq1_decode_block_intra (bitbuf, current, pitch); - break; - } - - return result; -} - -uint16_t ff_svq1_packet_checksum (const uint8_t *data, const int length, int value) { - int i; - - for (i=0; i < length; i++) { - value = checksum_table[data[i] ^ (value >> 8)] ^ ((value & 0xFF) << 8); - } - - return value; -} - -static void svq1_parse_string (GetBitContext *bitbuf, uint8_t *out) { - uint8_t seed; - int i; - - out[0] = get_bits (bitbuf, 8); - - seed = string_table[out[0]]; - - for (i=1; i <= out[0]; i++) { - out[i] = get_bits (bitbuf, 8) ^ seed; - seed = string_table[out[i] ^ seed]; - } -} - -static int svq1_decode_frame_header (GetBitContext *bitbuf,MpegEncContext *s) { - int frame_size_code; - int temporal_reference; - - temporal_reference = get_bits (bitbuf, 8); - - /* frame type */ - s->pict_type= get_bits (bitbuf, 2)+1; - if(s->pict_type==4) - return -1; - - if (s->pict_type == FF_I_TYPE) { - - /* unknown fields */ - if (s->f_code == 0x50 || s->f_code == 0x60) { - int csum = get_bits (bitbuf, 16); - - csum = ff_svq1_packet_checksum (bitbuf->buffer, bitbuf->size_in_bits>>3, csum); - -// av_log(s->avctx, AV_LOG_INFO, "%s checksum (%02x) for packet data\n", -// (csum == 0) ? "correct" : "incorrect", csum); - } - - if ((s->f_code ^ 0x10) >= 0x50) { - uint8_t msg[256]; - - svq1_parse_string (bitbuf, msg); - - av_log(s->avctx, AV_LOG_INFO, "embedded message: \"%s\"\n", (char *) msg); - } - - skip_bits (bitbuf, 2); - skip_bits (bitbuf, 2); - skip_bits1 (bitbuf); - - /* load frame size */ - frame_size_code = get_bits (bitbuf, 3); - - if (frame_size_code == 7) { - /* load width, height (12 bits each) */ - s->width = get_bits (bitbuf, 12); - s->height = get_bits (bitbuf, 12); - - if (!s->width || !s->height) - return -1; - } else { - /* get width, height from table */ - s->width = ff_svq1_frame_size_table[frame_size_code].width; - s->height = ff_svq1_frame_size_table[frame_size_code].height; - } - } - - /* unknown fields */ - if (get_bits1 (bitbuf) == 1) { - skip_bits1 (bitbuf); /* use packet checksum if (1) */ - skip_bits1 (bitbuf); /* component checksums after image data if (1) */ - - if (get_bits (bitbuf, 2) != 0) - return -1; - } - - if (get_bits1 (bitbuf) == 1) { - skip_bits1 (bitbuf); - skip_bits (bitbuf, 4); - skip_bits1 (bitbuf); - skip_bits (bitbuf, 2); - - while (get_bits1 (bitbuf) == 1) { - skip_bits (bitbuf, 8); - } - } - - return 0; -} - -static int svq1_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MpegEncContext *s=avctx->priv_data; - uint8_t *current, *previous; - int result, i, x, y, width, height; - AVFrame *pict = data; - - /* initialize bit buffer */ - init_get_bits(&s->gb,buf,buf_size*8); - - /* decode frame header */ - s->f_code = get_bits (&s->gb, 22); - - if ((s->f_code & ~0x70) || !(s->f_code & 0x60)) - return -1; - - /* swap some header bytes (why?) */ - if (s->f_code != 0x20) { - uint32_t *src = (uint32_t *) (buf + 4); - - for (i=0; i < 4; i++) { - src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; - } - } - - result = svq1_decode_frame_header (&s->gb, s); - - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_frame_header %i\n",result); -#endif - return result; - } - - //FIXME this avoids some confusion for "B frames" without 2 references - //this should be removed after libavcodec can handle more flexible picture types & ordering - if(s->pict_type==FF_B_TYPE && s->last_picture_ptr==NULL) return buf_size; - - if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return buf_size; - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE) - || avctx->skip_frame >= AVDISCARD_ALL) - return buf_size; - - if(MPV_frame_start(s, avctx) < 0) - return -1; - - /* decode y, u and v components */ - for (i=0; i < 3; i++) { - int linesize; - if (i == 0) { - width = FFALIGN(s->width, 16); - height = FFALIGN(s->height, 16); - linesize= s->linesize; - } else { - if(s->flags&CODEC_FLAG_GRAY) break; - width = FFALIGN(s->width/4, 16); - height = FFALIGN(s->height/4, 16); - linesize= s->uvlinesize; - } - - current = s->current_picture.data[i]; - - if(s->pict_type==FF_B_TYPE){ - previous = s->next_picture.data[i]; - }else{ - previous = s->last_picture.data[i]; - } - - if (s->pict_type == FF_I_TYPE) { - /* keyframe */ - for (y=0; y < height; y+=16) { - for (x=0; x < width; x+=16) { - result = svq1_decode_block_intra (&s->gb, ¤t[x], linesize); - if (result != 0) - { -//#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_block %i (keyframe)\n",result); -//#endif - return result; - } - } - current += 16*linesize; - } - } else { - svq1_pmv pmv[width/8+3]; - /* delta frame */ - memset (pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv)); - - for (y=0; y < height; y+=16) { - for (x=0; x < width; x+=16) { - result = svq1_decode_delta_block (s, &s->gb, ¤t[x], previous, - linesize, pmv, x, y); - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_delta_block %i\n",result); -#endif - return result; - } - } - - pmv[0].x = - pmv[0].y = 0; - - current += 16*linesize; - } - } - } - - *pict = *(AVFrame*)&s->current_picture; - - - MPV_frame_end(s); - - *data_size=sizeof(AVFrame); - return buf_size; -} - -static av_cold int svq1_decode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - int i; - int offset = 0; - - MPV_decode_defaults(s); - - s->avctx = avctx; - s->width = (avctx->width+3)&~3; - s->height = (avctx->height+3)&~3; - s->codec_id= avctx->codec->id; - avctx->pix_fmt = PIX_FMT_YUV410P; - avctx->has_b_frames= 1; // not true, but DP frames and these behave like unidirectional b frames - s->flags= avctx->flags; - if (MPV_common_init(s) < 0) return -1; - - INIT_VLC_STATIC(&svq1_block_type, 2, 4, - &ff_svq1_block_type_vlc[0][1], 2, 1, - &ff_svq1_block_type_vlc[0][0], 2, 1, 6); - - INIT_VLC_STATIC(&svq1_motion_component, 7, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 176); - - for (i = 0; i < 6; i++) { - static const uint8_t sizes[2][6] = {{14, 10, 14, 18, 16, 18}, {10, 10, 14, 14, 14, 16}}; - static VLC_TYPE table[168][2]; - svq1_intra_multistage[i].table = &table[offset]; - svq1_intra_multistage[i].table_allocated = sizes[0][i]; - offset += sizes[0][i]; - init_vlc(&svq1_intra_multistage[i], 3, 8, - &ff_svq1_intra_multistage_vlc[i][0][1], 2, 1, - &ff_svq1_intra_multistage_vlc[i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC); - svq1_inter_multistage[i].table = &table[offset]; - svq1_inter_multistage[i].table_allocated = sizes[1][i]; - offset += sizes[1][i]; - init_vlc(&svq1_inter_multistage[i], 3, 8, - &ff_svq1_inter_multistage_vlc[i][0][1], 2, 1, - &ff_svq1_inter_multistage_vlc[i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC); - } - - INIT_VLC_STATIC(&svq1_intra_mean, 8, 256, - &ff_svq1_intra_mean_vlc[0][1], 4, 2, - &ff_svq1_intra_mean_vlc[0][0], 4, 2, 632); - - INIT_VLC_STATIC(&svq1_inter_mean, 9, 512, - &ff_svq1_inter_mean_vlc[0][1], 4, 2, - &ff_svq1_inter_mean_vlc[0][0], 4, 2, 1434); - - return 0; -} - -static av_cold int svq1_decode_end(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - - MPV_common_end(s); - return 0; -} - - -AVCodec svq1_decoder = { - "svq1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SVQ1, - sizeof(MpegEncContext), - svq1_decode_init, - NULL, - svq1_decode_end, - svq1_decode_frame, - CODEC_CAP_DR1, - .flush= ff_mpeg_flush, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV410P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/svq1enc.c b/tizen/distrib/ffmpeg/libavcodec/svq1enc.c deleted file mode 100644 index c89be25..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq1enc.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * SVQ1 Encoder - * Copyright (C) 2004 Mike Melanson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sorenson Vector Quantizer #1 (SVQ1) video codec. - * For more information of the SVQ1 algorithm, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "h263.h" -#include "internal.h" - -#include "svq1.h" -#include "svq1enc_cb.h" - -#undef NDEBUG -#include - - -typedef struct SVQ1Context { - MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independent of MpegEncContext, so this will be removed then (FIXME/XXX) - AVCodecContext *avctx; - DSPContext dsp; - AVFrame picture; - AVFrame current_picture; - AVFrame last_picture; - PutBitContext pb; - GetBitContext gb; - - PutBitContext reorder_pb[6]; //why ooh why this sick breadth first order, everything is slower and more complex - - int frame_width; - int frame_height; - - /* Y plane block dimensions */ - int y_block_width; - int y_block_height; - - /* U & V plane (C planes) block dimensions */ - int c_block_width; - int c_block_height; - - uint16_t *mb_type; - uint32_t *dummy; - int16_t (*motion_val8[3])[2]; - int16_t (*motion_val16[3])[2]; - - int64_t rd_total; - - uint8_t *scratchbuf; -} SVQ1Context; - -static void svq1_write_header(SVQ1Context *s, int frame_type) -{ - int i; - - /* frame code */ - put_bits(&s->pb, 22, 0x20); - - /* temporal reference (sure hope this is a "don't care") */ - put_bits(&s->pb, 8, 0x00); - - /* frame type */ - put_bits(&s->pb, 2, frame_type - 1); - - if (frame_type == FF_I_TYPE) { - - /* no checksum since frame code is 0x20 */ - - /* no embedded string either */ - - /* output 5 unknown bits (2 + 2 + 1) */ - put_bits(&s->pb, 5, 2); /* 2 needed by quicktime decoder */ - - i= ff_match_2uint16(ff_svq1_frame_size_table, FF_ARRAY_ELEMS(ff_svq1_frame_size_table), s->frame_width, s->frame_height); - put_bits(&s->pb, 3, i); - - if (i == 7) - { - put_bits(&s->pb, 12, s->frame_width); - put_bits(&s->pb, 12, s->frame_height); - } - } - - /* no checksum or extra data (next 2 bits get 0) */ - put_bits(&s->pb, 2, 0); -} - - -#define QUALITY_THRESHOLD 100 -#define THRESHOLD_MULTIPLIER 0.6 - -#if HAVE_ALTIVEC -#undef vector -#endif - -static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){ - int count, y, x, i, j, split, best_mean, best_score, best_count; - int best_vector[6]; - int block_sum[7]= {0, 0, 0, 0, 0, 0}; - int w= 2<<((level+2)>>1); - int h= 2<<((level+1)>>1); - int size=w*h; - int16_t block[7][256]; - const int8_t *codebook_sum, *codebook; - const uint16_t (*mean_vlc)[2]; - const uint8_t (*multistage_vlc)[2]; - - best_score=0; - //FIXME optimize, this doenst need to be done multiple times - if(intra){ - codebook_sum= svq1_intra_codebook_sum[level]; - codebook= ff_svq1_intra_codebooks[level]; - mean_vlc= ff_svq1_intra_mean_vlc; - multistage_vlc= ff_svq1_intra_multistage_vlc[level]; - for(y=0; y>(level+3)); - best_mean= (block_sum[0] + (size>>1)) >> (level+3); - - if(level<4){ - for(count=1; count<7; count++){ - int best_vector_score= INT_MAX; - int best_vector_sum=-999, best_vector_mean=-999; - const int stage= count-1; - const int8_t *vector; - - for(i=0; i<16; i++){ - int sum= codebook_sum[stage*16 + i]; - int sqr, diff, score; - - vector = codebook + stage*size*16 + i*size; - sqr = s->dsp.ssd_int8_vs_int16(vector, block[stage], size); - diff= block_sum[stage] - sum; - score= sqr - ((diff*(int64_t)diff)>>(level+3)); //FIXME 64bit slooow - if(score < best_vector_score){ - int mean= (diff + (size>>1)) >> (level+3); - assert(mean >-300 && mean<300); - mean= av_clip(mean, intra?0:-256, 255); - best_vector_score= score; - best_vector[stage]= i; - best_vector_sum= sum; - best_vector_mean= mean; - } - } - assert(best_vector_mean != -999); - vector= codebook + stage*size*16 + best_vector[stage]*size; - for(j=0; j threshold && level){ - int score=0; - int offset= (level&1) ? stride*h/2 : w/2; - PutBitContext backup[6]; - - for(i=level-1; i>=0; i--){ - backup[i]= s->reorder_pb[i]; - } - score += encode_block(s, src , ref , decoded , stride, level-1, threshold>>1, lambda, intra); - score += encode_block(s, src + offset, ref + offset, decoded + offset, stride, level-1, threshold>>1, lambda, intra); - score += lambda; - - if(score < best_score){ - best_score= score; - split=1; - }else{ - for(i=level-1; i>=0; i--){ - s->reorder_pb[i]= backup[i]; - } - } - } - if (level > 0) - put_bits(&s->reorder_pb[level], 1, split); - - if(!split){ - assert((best_mean >= 0 && best_mean<256) || !intra); - assert(best_mean >= -256 && best_mean<256); - assert(best_count >=0 && best_count<7); - assert(level<4 || best_count==0); - - /* output the encoding */ - put_bits(&s->reorder_pb[level], - multistage_vlc[1 + best_count][1], - multistage_vlc[1 + best_count][0]); - put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1], - mean_vlc[best_mean][0]); - - for (i = 0; i < best_count; i++){ - assert(best_vector[i]>=0 && best_vector[i]<16); - put_bits(&s->reorder_pb[level], 4, best_vector[i]); - } - - for(y=0; yscratchbuf + stride * 16; - const int lambda= (s->picture.quality*s->picture.quality) >> (2*FF_LAMBDA_SHIFT); - - /* figure out the acceptable level thresholds in advance */ - threshold[5] = QUALITY_THRESHOLD; - for (level = 4; level >= 0; level--) - threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER; - - block_width = (width + 15) / 16; - block_height = (height + 15) / 16; - - if(s->picture.pict_type == FF_P_TYPE){ - s->m.avctx= s->avctx; - s->m.current_picture_ptr= &s->m.current_picture; - s->m.last_picture_ptr = &s->m.last_picture; - s->m.last_picture.data[0]= ref_plane; - s->m.linesize= - s->m.last_picture.linesize[0]= - s->m.new_picture.linesize[0]= - s->m.current_picture.linesize[0]= stride; - s->m.width= width; - s->m.height= height; - s->m.mb_width= block_width; - s->m.mb_height= block_height; - s->m.mb_stride= s->m.mb_width+1; - s->m.b8_stride= 2*s->m.mb_width+1; - s->m.f_code=1; - s->m.pict_type= s->picture.pict_type; - s->m.me_method= s->avctx->me_method; - s->m.me.scene_change_score=0; - s->m.flags= s->avctx->flags; -// s->m.out_format = FMT_H263; -// s->m.unrestricted_mv= 1; - - s->m.lambda= s->picture.quality; - s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); - s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; - - if(!s->motion_val8[plane]){ - s->motion_val8 [plane]= av_mallocz((s->m.b8_stride*block_height*2 + 2)*2*sizeof(int16_t)); - s->motion_val16[plane]= av_mallocz((s->m.mb_stride*(block_height + 2) + 1)*2*sizeof(int16_t)); - } - - s->m.mb_type= s->mb_type; - - //dummies, to avoid segfaults - s->m.current_picture.mb_mean= (uint8_t *)s->dummy; - s->m.current_picture.mb_var= (uint16_t*)s->dummy; - s->m.current_picture.mc_mb_var= (uint16_t*)s->dummy; - s->m.current_picture.mb_type= s->dummy; - - s->m.current_picture.motion_val[0]= s->motion_val8[plane] + 2; - s->m.p_mv_table= s->motion_val16[plane] + s->m.mb_stride + 1; - s->m.dsp= s->dsp; //move - ff_init_me(&s->m); - - s->m.me.dia_size= s->avctx->dia_size; - s->m.first_slice_line=1; - for (y = 0; y < block_height; y++) { - s->m.new_picture.data[0]= src - y*16*stride; //ugly - s->m.mb_y= y; - - for(i=0; i<16 && i + 16*ym.mb_x= x; - ff_init_block_index(&s->m); - ff_update_block_index(&s->m); - - ff_estimate_p_frame_motion(&s->m, x, y); - } - s->m.first_slice_line=0; - } - - ff_fix_long_p_mvs(&s->m); - ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code, CANDIDATE_MB_TYPE_INTER, 0); - } - - s->m.first_slice_line=1; - for (y = 0; y < block_height; y++) { - for(i=0; i<16 && i + 16*ym.mb_y= y; - for (x = 0; x < block_width; x++) { - uint8_t reorder_buffer[3][6][7*32]; - int count[3][6]; - int offset = y * 16 * stride + x * 16; - uint8_t *decoded= decoded_plane + offset; - uint8_t *ref= ref_plane + offset; - int score[4]={0,0,0,0}, best; - uint8_t *temp = s->scratchbuf; - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3000){ //FIXME check size - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - s->m.mb_x= x; - ff_init_block_index(&s->m); - ff_update_block_index(&s->m); - - if(s->picture.pict_type == FF_I_TYPE || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){ - for(i=0; i<6; i++){ - init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32); - } - if(s->picture.pict_type == FF_P_TYPE){ - const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; - put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); - score[0]= vlc[1]*lambda; - } - score[0]+= encode_block(s, src+16*x, NULL, temp, stride, 5, 64, lambda, 1); - for(i=0; i<6; i++){ - count[0][i]= put_bits_count(&s->reorder_pb[i]); - flush_put_bits(&s->reorder_pb[i]); - } - }else - score[0]= INT_MAX; - - best=0; - - if(s->picture.pict_type == FF_P_TYPE){ - const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER]; - int mx, my, pred_x, pred_y, dxy; - int16_t *motion_ptr; - - motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); - if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){ - for(i=0; i<6; i++) - init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); - - put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); - - s->m.pb= s->reorder_pb[5]; - mx= motion_ptr[0]; - my= motion_ptr[1]; - assert(mx>=-32 && mx<=31); - assert(my>=-32 && my<=31); - assert(pred_x>=-32 && pred_x<=31); - assert(pred_y>=-32 && pred_y<=31); - ff_h263_encode_motion(&s->m, mx - pred_x, 1); - ff_h263_encode_motion(&s->m, my - pred_y, 1); - s->reorder_pb[5]= s->m.pb; - score[1] += lambda*put_bits_count(&s->reorder_pb[5]); - - dxy= (mx&1) + 2*(my&1); - - s->dsp.put_pixels_tab[0][dxy](temp+16, ref + (mx>>1) + stride*(my>>1), stride, 16); - - score[1]+= encode_block(s, src+16*x, temp+16, decoded, stride, 5, 64, lambda, 0); - best= score[1] <= score[0]; - - vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_SKIP]; - score[2]= s->dsp.sse[0](NULL, src+16*x, ref, stride, 16); - score[2]+= vlc[1]*lambda; - if(score[2] < score[best] && mx==0 && my==0){ - best=2; - s->dsp.put_pixels_tab[0][0](decoded, ref, stride, 16); - for(i=0; i<6; i++){ - count[2][i]=0; - } - put_bits(&s->pb, vlc[1], vlc[0]); - } - } - - if(best==1){ - for(i=0; i<6; i++){ - count[1][i]= put_bits_count(&s->reorder_pb[i]); - flush_put_bits(&s->reorder_pb[i]); - } - }else{ - motion_ptr[0 ] = motion_ptr[1 ]= - motion_ptr[2 ] = motion_ptr[3 ]= - motion_ptr[0+2*s->m.b8_stride] = motion_ptr[1+2*s->m.b8_stride]= - motion_ptr[2+2*s->m.b8_stride] = motion_ptr[3+2*s->m.b8_stride]=0; - } - } - - s->rd_total += score[best]; - - for(i=5; i>=0; i--){ - ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); - } - if(best==0){ - s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16); - } - } - s->m.first_slice_line=0; - } - return 0; -} - -static av_cold int svq1_encode_init(AVCodecContext *avctx) -{ - SVQ1Context * const s = avctx->priv_data; - - dsputil_init(&s->dsp, avctx); - avctx->coded_frame= (AVFrame*)&s->picture; - - s->frame_width = avctx->width; - s->frame_height = avctx->height; - - s->y_block_width = (s->frame_width + 15) / 16; - s->y_block_height = (s->frame_height + 15) / 16; - - s->c_block_width = (s->frame_width / 4 + 15) / 16; - s->c_block_height = (s->frame_height / 4 + 15) / 16; - - s->avctx= avctx; - s->m.avctx= avctx; - s->m.me.temp = - s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t)); - s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); - s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); - s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t)); - s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t)); - h263_encode_init(&s->m); //mv_penalty - - return 0; -} - -static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf, - int buf_size, void *data) -{ - SVQ1Context * const s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; - AVFrame temp; - int i; - - if(avctx->pix_fmt != PIX_FMT_YUV410P){ - av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); - return -1; - } - - if(!s->current_picture.data[0]){ - avctx->get_buffer(avctx, &s->current_picture); - avctx->get_buffer(avctx, &s->last_picture); - s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2); - } - - temp= s->current_picture; - s->current_picture= s->last_picture; - s->last_picture= temp; - - init_put_bits(&s->pb, buf, buf_size); - - *p = *pict; - p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? FF_P_TYPE : FF_I_TYPE; - p->key_frame = p->pict_type == FF_I_TYPE; - - svq1_write_header(s, p->pict_type); - for(i=0; i<3; i++){ - if(svq1_encode_plane(s, i, - s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i], - s->frame_width / (i?4:1), s->frame_height / (i?4:1), - s->picture.linesize[i], s->current_picture.linesize[i]) < 0) - return -1; - } - -// align_put_bits(&s->pb); - while(put_bits_count(&s->pb) & 31) - put_bits(&s->pb, 1, 0); - - flush_put_bits(&s->pb); - - return put_bits_count(&s->pb) / 8; -} - -static av_cold int svq1_encode_end(AVCodecContext *avctx) -{ - SVQ1Context * const s = avctx->priv_data; - int i; - - av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", s->rd_total/(double)(avctx->width*avctx->height*avctx->frame_number)); - - av_freep(&s->m.me.scratchpad); - av_freep(&s->m.me.map); - av_freep(&s->m.me.score_map); - av_freep(&s->mb_type); - av_freep(&s->dummy); - av_freep(&s->scratchbuf); - - for(i=0; i<3; i++){ - av_freep(&s->motion_val8[i]); - av_freep(&s->motion_val16[i]); - } - - return 0; -} - - -AVCodec svq1_encoder = { - "svq1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SVQ1, - sizeof(SVQ1Context), - svq1_encode_init, - svq1_encode_frame, - svq1_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV410P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/svq1enc_cb.h b/tizen/distrib/ffmpeg/libavcodec/svq1enc_cb.h deleted file mode 100644 index 7eff82e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq1enc_cb.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SVQ1 Encoder - * Copyright (C) 2004 Mike Melanson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * svq1 code books. - */ - -#ifndef AVCODEC_SVQ1ENC_CB_H -#define AVCODEC_SVQ1ENC_CB_H - -#include - -static const int8_t svq1_inter_codebook_sum[4][16*6] = { - { - -1, 1, -2, 0, 1, -1, -1, -1, -2, -1, 1, -1, -1, 0, -1, -1, - 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, -3, 1, -1, 0, 1, -1, - 1, -1, 2, 2, 1, 1, 2, 0, 0, 0, -1, 1, 1, 0, 0, 0, - 1, -1, 0, 1, -1, 1, 1, 0, 1, 0, -1, 1, 1, 0, 0, 0, - -2, 0, 0, -2, 0, 0, -2, 0, -2, -1, -2, -1, 0, 0, -1, 0, - 1, 0, 1, -1, 2, 2, 1, 2, 2, 1, 0, 1, 1, 0, 1, 1, - },{ - -2, 1, -1, -1, 1, 0, 1, -1, -1, -1, 1, -1, 0, -1, 0, -1, - 0, 0, 0, -2, 0, 1, 0, -1, -1, 0, 2, -3, 1, -2, 3, -1, - 2, 0, 2, 1, 1, -1, 1, 1, 0, 0, 1, 1, 2, -2, 1, 0, - -2, -1, 2, -2, -2, 0, -3, 0, -1, 0, -1, 0, -1, 0, -2, -3, - 1, -2, -2, -1, 1, -1, -1, 1, -1, 1, 1, 0, -2, 0, 1, 1, - 1, 1, 2, 1, 0, 0, -1, 0, 0, 1, 0, 1, -1, 1, 0, 2, - },{ - 0, 0, 0, -3, 1, 1, 1, -3, 0, -1, 0, -3, 1, -3, 0, -2, - 1, 2, -1, -3, 0, -3, 1, -1, 0, -1, 0, 0, 1, 2, 1, 1, - -1, 2, -3, 3, 1, 0, -5, 1, 0, -1, -3, 1, 0, 2, 0, -3, - 4, 2, 0, -2, 1, -2, 3, -2, 1, 1, 0, -1, 2, 5, 3, 1, - -1, 0, 2, -3, -2, 0, 0, -2, 2, -3, -1, -1, 2, 1, 0, -2, - 3, -1, 1, -1, 2, 4, 0, 1, 0, 1, 0, -1, -3, -2, -1, 0, - },{ - 0, 2, -1, -1, 2, -4, -2, 3, 0, -1, -5, 1, 0, 1, 0, 6, - -2, 2, 0, 1, 1, -1, -1, -2, 1, -2, -1, 0, 2, -2, -2, -1, - -4, 2, -1, -3, -1, -2, 2, -1, 2, -1, 2, 0, 3, -3, -3, 0, - -3, 0, 0, -2, 4, -4, 0, -1, 4, 0, -2, -2, 3, -2, 0, 4, - 5, 0, 1, 0, -3, 3, 3, 2, 0, 0, 1, 2, -5, -2, -3, 0, - -3, 2, -2, 2, -2, 4, 7, -3, 4, 2, 3, 2, -1, 0, -3, 1, - } -}; - -static const int8_t svq1_intra_codebook_sum[4][16*6] = { - { - 0, 0, 0, -1, -1, -1, -1, -2, 0, -1, -1, 0, -1, 0, 1, 0, - 1, 0, -1, 1, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, 0, 0, - -1, 0, 0, 1, -1, 1, 0, -1, -1, 0, 1, 1, 0, 0, -1, 1, - 0, 1, 0, 0, 1, -1, 0, 0, 0, -1, 1, 0, 1, 0, -2, 1, - 0, -1, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 0, 0, - 0, 1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 1, 1, -1, - },{ - -1, -2, 0, -1, 1, 0, -1, 0, -1, -4, -1, -2, -1, -2, 1, -2, - 0, 0, 4, -2, -1, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 0, - 1, 1, 0, -1, -1, -1, 1, 0, -1, -3, -3, 1, -1, 1, -2, -1, - 1, -1, 0, 1, 2, 1, -1, -1, 1, 1, 1, 2, 1, 0, 1, -2, - -2, 0, -1, -2, -2, 0, -1, -1, -1, 0, 1, 0, -1, -1, 0, -1, - 0, 2, 1, 2, 2, 1, -1, 1, 0, 2, 0, -1, 1, 0, 0, 0, - },{ - -2, 0, -1, -1, 1, 1, -2, 0, -2, 0, 1, -2, -2, 1, -1, -1, - 3, -2, 0, -3, -4, -3, 2, 1, 0, 3, -2, 2, 3, 2, 2, -1, - -3, 1, 0, 1, 0, 0, 0, 1, -2, 1, -2, -2, -1, -2, -2, 2, - 0, -4, 0, 2, -1, 0, 2, 2, 2, 1, 0, -1, -1, 1, -3, 2, - 2, 1, 0, 3, 1, -1, 1, 3, 1, 0, 1, 1, 2, -1, 1, -1, - -2, -1, 0, -1, 1, -1, 1, -2, -2, -1, -1, -3, 1, -4, -3, 1, - },{ - -2, 0, -2, 3, -1, -1, 0, 2, 2, -1, -3, 2, 1, 0, -2, -1, - -3, -2, -2, 1, 2, -3, 0, 1, -5, -2, -3, 0, -2, -1, 2, 0, - -1, -1, 0, -2, 1, 3, -7, -2, -2, -1, 2, -1, 0, 3, 1, 3, - 1, 0, 0, 1, 2, 3, 1, 2, 0, -2, -2, 1, 1, 2, 2, 3, - 4, 1, -1, 2, -2, 4, 0, 0, 0, 4, 2, 0, -2, -2, 2, -4, - -1, 5, -2, -2, -3, 2, -3, -1, 3, -3, 0, 4, 3, 0, 1, -2, - } -}; - -#endif /* AVCODEC_SVQ1ENC_CB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/svq3.c b/tizen/distrib/ffmpeg/libavcodec/svq3.c deleted file mode 100644 index bf7659a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/svq3.c +++ /dev/null @@ -1,1084 +0,0 @@ -/* - * Copyright (c) 2003 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * How to use this decoder: - * SVQ3 data is transported within Apple Quicktime files. Quicktime files - * have stsd atoms to describe media trak properties. A stsd atom for a - * video trak contains 1 or more ImageDescription atoms. These atoms begin - * with the 4-byte length of the atom followed by the codec fourcc. Some - * decoders need information in this atom to operate correctly. Such - * is the case with SVQ3. In order to get the best use out of this decoder, - * the calling app must make the SVQ3 ImageDescription atom available - * via the AVCodecContext's extradata[_size] field: - * - * AVCodecContext.extradata = pointer to ImageDescription, first characters - * are expected to be 'S', 'V', 'Q', and '3', NOT the 4-byte atom length - * AVCodecContext.extradata_size = size of ImageDescription atom memory - * buffer (which will be the same as the ImageDescription atom size field - * from the QT file, minus 4 bytes since the length is missing) - * - * You will know you have these parameters passed correctly when the decoder - * correctly decodes this file: - * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov - */ -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h264.h" - -#include "h264data.h" //FIXME FIXME FIXME - -#include "h264_mvpred.h" -#include "golomb.h" -#include "rectangle.h" -#include "vdpau_internal.h" - -#if CONFIG_ZLIB -#include -#endif - -#include "svq1.h" - -/** - * @file - * svq3 decoder. - */ - -#define FULLPEL_MODE 1 -#define HALFPEL_MODE 2 -#define THIRDPEL_MODE 3 -#define PREDICT_MODE 4 - -/* dual scan (from some older h264 draft) - o-->o-->o o - | /| - o o o / o - | / | |/ | - o o o o - / - o-->o-->o-->o -*/ -static const uint8_t svq3_scan[16] = { - 0+0*4, 1+0*4, 2+0*4, 2+1*4, - 2+2*4, 3+0*4, 3+1*4, 3+2*4, - 0+1*4, 0+2*4, 1+1*4, 1+2*4, - 0+3*4, 1+3*4, 2+3*4, 3+3*4, -}; - -static const uint8_t svq3_pred_0[25][2] = { - { 0, 0 }, - { 1, 0 }, { 0, 1 }, - { 0, 2 }, { 1, 1 }, { 2, 0 }, - { 3, 0 }, { 2, 1 }, { 1, 2 }, { 0, 3 }, - { 0, 4 }, { 1, 3 }, { 2, 2 }, { 3, 1 }, { 4, 0 }, - { 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 }, - { 2, 4 }, { 3, 3 }, { 4, 2 }, - { 4, 3 }, { 3, 4 }, - { 4, 4 } -}; - -static const int8_t svq3_pred_1[6][6][5] = { - { { 2,-1,-1,-1,-1 }, { 2, 1,-1,-1,-1 }, { 1, 2,-1,-1,-1 }, - { 2, 1,-1,-1,-1 }, { 1, 2,-1,-1,-1 }, { 1, 2,-1,-1,-1 } }, - { { 0, 2,-1,-1,-1 }, { 0, 2, 1, 4, 3 }, { 0, 1, 2, 4, 3 }, - { 0, 2, 1, 4, 3 }, { 2, 0, 1, 3, 4 }, { 0, 4, 2, 1, 3 } }, - { { 2, 0,-1,-1,-1 }, { 2, 1, 0, 4, 3 }, { 1, 2, 4, 0, 3 }, - { 2, 1, 0, 4, 3 }, { 2, 1, 4, 3, 0 }, { 1, 2, 4, 0, 3 } }, - { { 2, 0,-1,-1,-1 }, { 2, 0, 1, 4, 3 }, { 1, 2, 0, 4, 3 }, - { 2, 1, 0, 4, 3 }, { 2, 1, 3, 4, 0 }, { 2, 4, 1, 0, 3 } }, - { { 0, 2,-1,-1,-1 }, { 0, 2, 1, 3, 4 }, { 1, 2, 3, 0, 4 }, - { 2, 0, 1, 3, 4 }, { 2, 1, 3, 0, 4 }, { 2, 0, 4, 3, 1 } }, - { { 0, 2,-1,-1,-1 }, { 0, 2, 4, 1, 3 }, { 1, 4, 2, 0, 3 }, - { 4, 2, 0, 1, 3 }, { 2, 0, 1, 4, 3 }, { 4, 2, 1, 0, 3 } }, -}; - -static const struct { uint8_t run; uint8_t level; } svq3_dct_tables[2][16] = { - { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 0, 2 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, - { 0, 3 }, { 1, 2 }, { 2, 2 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 0, 4 } }, - { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 }, { 2, 1 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, - { 3, 1 }, { 4, 1 }, { 1, 2 }, { 1, 3 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 } } -}; - -static const uint32_t svq3_dequant_coeff[32] = { - 3881, 4351, 4890, 5481, 6154, 6914, 7761, 8718, - 9781, 10987, 12339, 13828, 15523, 17435, 19561, 21873, - 24552, 27656, 30847, 34870, 38807, 43747, 49103, 54683, - 61694, 68745, 77615, 89113,100253,109366,126635,141533 -}; - - -void ff_svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp) -{ - const int qmul = svq3_dequant_coeff[qp]; -#define stride 16 - int i; - int temp[16]; - 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 = 13*(block[offset+stride*0] + block[offset+stride*4]); - const int z1 = 13*(block[offset+stride*0] - block[offset+stride*4]); - const int z2 = 7* block[offset+stride*1] - 17*block[offset+stride*5]; - const int z3 = 17* block[offset+stride*1] + 7*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 = 13*(temp[4*0+i] + temp[4*2+i]); - const int z1 = 13*(temp[4*0+i] - temp[4*2+i]); - const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i]; - const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i]; - - block[stride*0 +offset] = ((z0 + z3)*qmul + 0x80000) >> 20; - block[stride*2 +offset] = ((z1 + z2)*qmul + 0x80000) >> 20; - block[stride*8 +offset] = ((z1 - z2)*qmul + 0x80000) >> 20; - block[stride*10+offset] = ((z0 - z3)*qmul + 0x80000) >> 20; - } -} -#undef stride - -void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, - int dc) -{ - const int qmul = svq3_dequant_coeff[qp]; - int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - if (dc) { - dc = 13*13*((dc == 1) ? 1538*block[0] : ((qmul*(block[0] >> 3)) / 2)); - block[0] = 0; - } - - for (i = 0; i < 4; i++) { - const int z0 = 13*(block[0 + 4*i] + block[2 + 4*i]); - const int z1 = 13*(block[0 + 4*i] - block[2 + 4*i]); - const int z2 = 7* block[1 + 4*i] - 17*block[3 + 4*i]; - const int z3 = 17* block[1 + 4*i] + 7*block[3 + 4*i]; - - block[0 + 4*i] = z0 + z3; - block[1 + 4*i] = z1 + z2; - block[2 + 4*i] = z1 - z2; - block[3 + 4*i] = z0 - z3; - } - - for (i = 0; i < 4; i++) { - const int z0 = 13*(block[i + 4*0] + block[i + 4*2]); - const int z1 = 13*(block[i + 4*0] - block[i + 4*2]); - const int z2 = 7* block[i + 4*1] - 17*block[i + 4*3]; - const int z3 = 17* block[i + 4*1] + 7*block[i + 4*3]; - const int rr = (dc + 0x80000); - - dst[i + stride*0] = cm[ dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ]; - dst[i + stride*1] = cm[ dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ]; - dst[i + stride*2] = cm[ dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ]; - dst[i + stride*3] = cm[ dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ]; - } -} - -static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block, - int index, const int type) -{ - static const uint8_t *const scan_patterns[4] = - { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan }; - - int run, level, sign, vlc, limit; - const int intra = (3 * type) >> 2; - const uint8_t *const scan = scan_patterns[type]; - - for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { - for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) { - - if (vlc == INVALID_VLC) - return -1; - - sign = (vlc & 0x1) - 1; - vlc = (vlc + 1) >> 1; - - if (type == 3) { - if (vlc < 3) { - run = 0; - level = vlc; - } else if (vlc < 4) { - run = 1; - level = 1; - } else { - run = (vlc & 0x3); - level = ((vlc + 9) >> 2) - run; - } - } else { - if (vlc < 16) { - run = svq3_dct_tables[intra][vlc].run; - level = svq3_dct_tables[intra][vlc].level; - } else if (intra) { - run = (vlc & 0x7); - level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1))); - } else { - run = (vlc & 0xF); - level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0))); - } - } - - if ((index += run) >= limit) - return -1; - - block[scan[index]] = (level ^ sign) - sign; - } - - if (type != 2) { - break; - } - } - - return 0; -} - -static inline void svq3_mc_dir_part(MpegEncContext *s, - int x, int y, int width, int height, - int mx, int my, int dxy, - int thirdpel, int dir, int avg) -{ - const Picture *pic = (dir == 0) ? &s->last_picture : &s->next_picture; - uint8_t *src, *dest; - int i, emu = 0; - int blocksize = 2 - (width>>3); //16->0, 8->1, 4->2 - - mx += x; - my += y; - - if (mx < 0 || mx >= (s->h_edge_pos - width - 1) || - my < 0 || my >= (s->v_edge_pos - height - 1)) { - - if ((s->flags & CODEC_FLAG_EMU_EDGE)) { - emu = 1; - } - - mx = av_clip (mx, -16, (s->h_edge_pos - width + 15)); - my = av_clip (my, -16, (s->v_edge_pos - height + 15)); - } - - /* form component predictions */ - dest = s->current_picture.data[0] + x + y*s->linesize; - src = pic->data[0] + mx + my*s->linesize; - - if (emu) { - ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, (width + 1), (height + 1), - mx, my, s->h_edge_pos, s->v_edge_pos); - src = s->edge_emu_buffer; - } - if (thirdpel) - (avg ? s->dsp.avg_tpel_pixels_tab : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->linesize, width, height); - else - (avg ? s->dsp.avg_pixels_tab : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->linesize, height); - - if (!(s->flags & CODEC_FLAG_GRAY)) { - mx = (mx + (mx < (int) x)) >> 1; - my = (my + (my < (int) y)) >> 1; - width = (width >> 1); - height = (height >> 1); - blocksize++; - - for (i = 1; i < 3; i++) { - dest = s->current_picture.data[i] + (x >> 1) + (y >> 1)*s->uvlinesize; - src = pic->data[i] + mx + my*s->uvlinesize; - - if (emu) { - ff_emulated_edge_mc(s->edge_emu_buffer, src, s->uvlinesize, (width + 1), (height + 1), - mx, my, (s->h_edge_pos >> 1), (s->v_edge_pos >> 1)); - src = s->edge_emu_buffer; - } - if (thirdpel) - (avg ? s->dsp.avg_tpel_pixels_tab : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->uvlinesize, width, height); - else - (avg ? s->dsp.avg_pixels_tab : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->uvlinesize, height); - } - } -} - -static inline int svq3_mc_dir(H264Context *h, int size, int mode, int dir, - int avg) -{ - int i, j, k, mx, my, dx, dy, x, y; - MpegEncContext *const s = (MpegEncContext *) h; - const int part_width = ((size & 5) == 4) ? 4 : 16 >> (size & 1); - const int part_height = 16 >> ((unsigned) (size + 1) / 3); - const int extra_width = (mode == PREDICT_MODE) ? -16*6 : 0; - const int h_edge_pos = 6*(s->h_edge_pos - part_width ) - extra_width; - const int v_edge_pos = 6*(s->v_edge_pos - part_height) - extra_width; - - for (i = 0; i < 16; i += part_height) { - for (j = 0; j < 16; j += part_width) { - const int b_xy = (4*s->mb_x + (j >> 2)) + (4*s->mb_y + (i >> 2))*h->b_stride; - int dxy; - x = 16*s->mb_x + j; - y = 16*s->mb_y + i; - k = ((j >> 2) & 1) + ((i >> 1) & 2) + ((j >> 1) & 4) + (i & 8); - - if (mode != PREDICT_MODE) { - pred_motion(h, k, (part_width >> 2), dir, 1, &mx, &my); - } else { - mx = s->next_picture.motion_val[0][b_xy][0]<<1; - my = s->next_picture.motion_val[0][b_xy][1]<<1; - - if (dir == 0) { - mx = ((mx * h->frame_num_offset) / h->prev_frame_num_offset + 1) >> 1; - my = ((my * h->frame_num_offset) / h->prev_frame_num_offset + 1) >> 1; - } else { - mx = ((mx * (h->frame_num_offset - h->prev_frame_num_offset)) / h->prev_frame_num_offset + 1) >> 1; - my = ((my * (h->frame_num_offset - h->prev_frame_num_offset)) / h->prev_frame_num_offset + 1) >> 1; - } - } - - /* clip motion vector prediction to frame border */ - mx = av_clip(mx, extra_width - 6*x, h_edge_pos - 6*x); - my = av_clip(my, extra_width - 6*y, v_edge_pos - 6*y); - - /* get (optional) motion vector differential */ - if (mode == PREDICT_MODE) { - dx = dy = 0; - } else { - dy = svq3_get_se_golomb(&s->gb); - dx = svq3_get_se_golomb(&s->gb); - - if (dx == INVALID_VLC || dy == INVALID_VLC) { - av_log(h->s.avctx, AV_LOG_ERROR, "invalid MV vlc\n"); - return -1; - } - } - - /* compute motion vector */ - if (mode == THIRDPEL_MODE) { - int fx, fy; - mx = ((mx + 1)>>1) + dx; - my = ((my + 1)>>1) + dy; - fx = ((unsigned)(mx + 0x3000))/3 - 0x1000; - fy = ((unsigned)(my + 0x3000))/3 - 0x1000; - dxy = (mx - 3*fx) + 4*(my - 3*fy); - - svq3_mc_dir_part(s, x, y, part_width, part_height, fx, fy, dxy, 1, dir, avg); - mx += mx; - my += my; - } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) { - mx = ((unsigned)(mx + 1 + 0x3000))/3 + dx - 0x1000; - my = ((unsigned)(my + 1 + 0x3000))/3 + dy - 0x1000; - dxy = (mx&1) + 2*(my&1); - - svq3_mc_dir_part(s, x, y, part_width, part_height, mx>>1, my>>1, dxy, 0, dir, avg); - mx *= 3; - my *= 3; - } else { - mx = ((unsigned)(mx + 3 + 0x6000))/6 + dx - 0x1000; - my = ((unsigned)(my + 3 + 0x6000))/6 + dy - 0x1000; - - svq3_mc_dir_part(s, x, y, part_width, part_height, mx, my, 0, 0, dir, avg); - mx *= 6; - my *= 6; - } - - /* update mv_cache */ - if (mode != PREDICT_MODE) { - int32_t mv = pack16to32(mx,my); - - if (part_height == 8 && i < 8) { - *(int32_t *) h->mv_cache[dir][scan8[k] + 1*8] = mv; - - if (part_width == 8 && j < 8) { - *(int32_t *) h->mv_cache[dir][scan8[k] + 1 + 1*8] = mv; - } - } - if (part_width == 8 && j < 8) { - *(int32_t *) h->mv_cache[dir][scan8[k] + 1] = mv; - } - if (part_width == 4 || part_height == 4) { - *(int32_t *) h->mv_cache[dir][scan8[k]] = mv; - } - } - - /* write back motion vectors */ - fill_rectangle(s->current_picture.motion_val[dir][b_xy], part_width>>2, part_height>>2, h->b_stride, pack16to32(mx,my), 4); - } - } - - return 0; -} - -static int svq3_decode_mb(H264Context *h, unsigned int mb_type) -{ - int i, j, k, m, dir, mode; - int cbp = 0; - uint32_t vlc; - int8_t *top, *left; - MpegEncContext *const s = (MpegEncContext *) h; - const int mb_xy = h->mb_xy; - const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; - - h->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; - h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; - h->topright_samples_available = 0xFFFF; - - if (mb_type == 0) { /* SKIP */ - if (s->pict_type == FF_P_TYPE || s->next_picture.mb_type[mb_xy] == -1) { - svq3_mc_dir_part(s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 0, 0); - - if (s->pict_type == FF_B_TYPE) { - svq3_mc_dir_part(s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 1, 1); - } - - mb_type = MB_TYPE_SKIP; - } else { - mb_type = FFMIN(s->next_picture.mb_type[mb_xy], 6); - if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 0, 0) < 0) - return -1; - if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 1, 1) < 0) - return -1; - - mb_type = MB_TYPE_16x16; - } - } else if (mb_type < 8) { /* INTER */ - if (h->thirdpel_flag && h->halfpel_flag == !get_bits1 (&s->gb)) { - mode = THIRDPEL_MODE; - } else if (h->halfpel_flag && h->thirdpel_flag == !get_bits1 (&s->gb)) { - mode = HALFPEL_MODE; - } else { - mode = FULLPEL_MODE; - } - - /* fill caches */ - /* note ref_cache should contain here: - ???????? - ???11111 - N??11111 - N??11111 - N??11111 - */ - - for (m = 0; m < 2; m++) { - if (s->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1]+6] != -1) { - for (i = 0; i < 4; i++) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - 1 + i*h->b_stride]; - } - } else { - for (i = 0; i < 4; i++) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = 0; - } - } - if (s->mb_y > 0) { - memcpy(h->mv_cache[m][scan8[0] - 1*8], s->current_picture.motion_val[m][b_xy - h->b_stride], 4*2*sizeof(int16_t)); - memset(&h->ref_cache[m][scan8[0] - 1*8], (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4); - - if (s->mb_x < (s->mb_width - 1)) { - *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride + 4]; - h->ref_cache[m][scan8[0] + 4 - 1*8] = - (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride + 1]+6] == -1 || - h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride ] ] == -1) ? PART_NOT_AVAILABLE : 1; - }else - h->ref_cache[m][scan8[0] + 4 - 1*8] = PART_NOT_AVAILABLE; - if (s->mb_x > 0) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride - 1]; - h->ref_cache[m][scan8[0] - 1 - 1*8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1]+3] == -1) ? PART_NOT_AVAILABLE : 1; - }else - h->ref_cache[m][scan8[0] - 1 - 1*8] = PART_NOT_AVAILABLE; - }else - memset(&h->ref_cache[m][scan8[0] - 1*8 - 1], PART_NOT_AVAILABLE, 8); - - if (s->pict_type != FF_B_TYPE) - break; - } - - /* decode motion vector(s) and form prediction(s) */ - if (s->pict_type == FF_P_TYPE) { - if (svq3_mc_dir(h, (mb_type - 1), mode, 0, 0) < 0) - return -1; - } else { /* FF_B_TYPE */ - if (mb_type != 2) { - if (svq3_mc_dir(h, 0, mode, 0, 0) < 0) - return -1; - } else { - for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); - } - } - if (mb_type != 1) { - if (svq3_mc_dir(h, 0, mode, 1, (mb_type == 3)) < 0) - return -1; - } else { - for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); - } - } - } - - mb_type = MB_TYPE_16x16; - } else if (mb_type == 8 || mb_type == 33) { /* INTRA4x4 */ - memset(h->intra4x4_pred_mode_cache, -1, 8*5*sizeof(int8_t)); - - if (mb_type == 8) { - if (s->mb_x > 0) { - for (i = 0; i < 4; i++) { - h->intra4x4_pred_mode_cache[scan8[0] - 1 + i*8] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1]+6-i]; - } - if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1) { - h->left_samples_available = 0x5F5F; - } - } - if (s->mb_y > 0) { - h->intra4x4_pred_mode_cache[4+8*0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]+0]; - h->intra4x4_pred_mode_cache[5+8*0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]+1]; - h->intra4x4_pred_mode_cache[6+8*0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]+2]; - h->intra4x4_pred_mode_cache[7+8*0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]+3]; - - if (h->intra4x4_pred_mode_cache[4+8*0] == -1) { - h->top_samples_available = 0x33FF; - } - } - - /* decode prediction codes for luma blocks */ - for (i = 0; i < 16; i+=2) { - vlc = svq3_get_ue_golomb(&s->gb); - - if (vlc >= 25){ - av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc); - return -1; - } - - left = &h->intra4x4_pred_mode_cache[scan8[i] - 1]; - top = &h->intra4x4_pred_mode_cache[scan8[i] - 8]; - - left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]]; - left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]]; - - if (left[1] == -1 || left[2] == -1){ - av_log(h->s.avctx, AV_LOG_ERROR, "weird prediction\n"); - return -1; - } - } - } else { /* mb_type == 33, DC_128_PRED block type */ - for (i = 0; i < 4; i++) { - memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_PRED, 4); - } - } - - ff_h264_write_back_intra_pred_mode(h); - - if (mb_type == 8) { - ff_h264_check_intra4x4_pred_mode(h); - - h->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; - h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; - } else { - for (i = 0; i < 4; i++) { - memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_128_PRED, 4); - } - - h->top_samples_available = 0x33FF; - h->left_samples_available = 0x5F5F; - } - - mb_type = MB_TYPE_INTRA4x4; - } else { /* INTRA16x16 */ - dir = i_mb_type_info[mb_type - 8].pred_mode; - dir = (dir >> 1) ^ 3*(dir & 1) ^ 1; - - if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir)) == -1){ - av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); - return -1; - } - - cbp = i_mb_type_info[mb_type - 8].cbp; - mb_type = MB_TYPE_INTRA16x16; - } - - if (!IS_INTER(mb_type) && s->pict_type != FF_I_TYPE) { - for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); - } - if (s->pict_type == FF_B_TYPE) { - for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); - } - } - } - if (!IS_INTRA4x4(mb_type)) { - memset(h->intra4x4_pred_mode+h->mb2br_xy[mb_xy], DC_PRED, 8); - } - if (!IS_SKIP(mb_type) || s->pict_type == FF_B_TYPE) { - memset(h->non_zero_count_cache + 8, 0, 4*9*sizeof(uint8_t)); - s->dsp.clear_blocks(h->mb); - } - - if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == FF_B_TYPE)) { - if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48){ - av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc); - return -1; - } - - cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc] : golomb_to_inter_cbp[vlc]; - } - if (IS_INTRA16x16(mb_type) || (s->pict_type != FF_I_TYPE && s->adaptive_quant && cbp)) { - s->qscale += svq3_get_se_golomb(&s->gb); - - if (s->qscale > 31){ - av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); - return -1; - } - } - if (IS_INTRA16x16(mb_type)) { - if (svq3_decode_block(&s->gb, h->mb, 0, 0)){ - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n"); - return -1; - } - } - - if (cbp) { - const int index = IS_INTRA16x16(mb_type) ? 1 : 0; - const int type = ((s->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1); - - for (i = 0; i < 4; i++) { - if ((cbp & (1 << i))) { - for (j = 0; j < 4; j++) { - k = index ? ((j&1) + 2*(i&1) + 2*(j&2) + 4*(i&2)) : (4*i + j); - h->non_zero_count_cache[ scan8[k] ] = 1; - - if (svq3_decode_block(&s->gb, &h->mb[16*k], index, type)){ - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding block\n"); - return -1; - } - } - } - } - - if ((cbp & 0x30)) { - for (i = 0; i < 2; ++i) { - if (svq3_decode_block(&s->gb, &h->mb[16*(16 + 4*i)], 0, 3)){ - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma dc block\n"); - return -1; - } - } - - if ((cbp & 0x20)) { - for (i = 0; i < 8; i++) { - h->non_zero_count_cache[ scan8[16+i] ] = 1; - - if (svq3_decode_block(&s->gb, &h->mb[16*(16 + i)], 1, 1)){ - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n"); - return -1; - } - } - } - } - } - - h->cbp= cbp; - s->current_picture.mb_type[mb_xy] = mb_type; - - if (IS_INTRA(mb_type)) { - h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8); - } - - return 0; -} - -static int svq3_decode_slice_header(H264Context *h) -{ - MpegEncContext *const s = (MpegEncContext *) h; - const int mb_xy = h->mb_xy; - int i, header; - - header = get_bits(&s->gb, 8); - - if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { - /* TODO: what? */ - av_log(h->s.avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); - return -1; - } else { - int length = (header >> 5) & 3; - - h->next_slice_index = get_bits_count(&s->gb) + 8*show_bits(&s->gb, 8*length) + 8*length; - - if (h->next_slice_index > s->gb.size_in_bits) { - av_log(h->s.avctx, AV_LOG_ERROR, "slice after bitstream end\n"); - return -1; - } - - s->gb.size_in_bits = h->next_slice_index - 8*(length - 1); - skip_bits(&s->gb, 8); - - if (h->svq3_watermark_key) { - uint32_t header = AV_RL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1]); - AV_WL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1], header ^ h->svq3_watermark_key); - } - if (length > 0) { - memcpy((uint8_t *) &s->gb.buffer[get_bits_count(&s->gb) >> 3], - &s->gb.buffer[s->gb.size_in_bits >> 3], (length - 1)); - } - skip_bits_long(&s->gb, 0); - } - - if ((i = svq3_get_ue_golomb(&s->gb)) == INVALID_VLC || i >= 3){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i); - return -1; - } - - h->slice_type = golomb_to_pict_type[i]; - - if ((header & 0x9F) == 2) { - i = (s->mb_num < 64) ? 6 : (1 + av_log2 (s->mb_num - 1)); - s->mb_skip_run = get_bits(&s->gb, i) - (s->mb_x + (s->mb_y * s->mb_width)); - } else { - skip_bits1(&s->gb); - s->mb_skip_run = 0; - } - - h->slice_num = get_bits(&s->gb, 8); - s->qscale = get_bits(&s->gb, 5); - s->adaptive_quant = get_bits1(&s->gb); - - /* unknown fields */ - skip_bits1(&s->gb); - - if (h->unknown_svq3_flag) { - skip_bits1(&s->gb); - } - - skip_bits1(&s->gb); - skip_bits(&s->gb, 2); - - while (get_bits1(&s->gb)) { - skip_bits(&s->gb, 8); - } - - /* reset intra predictors and invalidate motion vector references */ - if (s->mb_x > 0) { - memset(h->intra4x4_pred_mode+h->mb2br_xy[mb_xy - 1 ]+3, -1, 4*sizeof(int8_t)); - memset(h->intra4x4_pred_mode+h->mb2br_xy[mb_xy - s->mb_x] , -1, 8*sizeof(int8_t)*s->mb_x); - } - if (s->mb_y > 0) { - memset(h->intra4x4_pred_mode+h->mb2br_xy[mb_xy - s->mb_stride], -1, 8*sizeof(int8_t)*(s->mb_width - s->mb_x)); - - if (s->mb_x > 0) { - h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1]+3] = -1; - } - } - - return 0; -} - -static av_cold int svq3_decode_init(AVCodecContext *avctx) -{ - MpegEncContext *const s = avctx->priv_data; - H264Context *const h = avctx->priv_data; - int m; - unsigned char *extradata; - unsigned int size; - - if(avctx->thread_count > 1){ - av_log(avctx, AV_LOG_ERROR, "SVQ3 does not support multithreaded decoding, patch welcome! (check latest SVN too)\n"); - return -1; - } - - if (ff_h264_decode_init(avctx) < 0) - return -1; - - s->flags = avctx->flags; - s->flags2 = avctx->flags2; - s->unrestricted_mv = 1; - h->is_complex=1; - avctx->pix_fmt = avctx->codec->pix_fmts[0]; - - if (!s->context_initialized) { - s->width = avctx->width; - s->height = avctx->height; - h->halfpel_flag = 1; - h->thirdpel_flag = 1; - h->unknown_svq3_flag = 0; - h->chroma_qp[0] = h->chroma_qp[1] = 4; - - if (MPV_common_init(s) < 0) - return -1; - - h->b_stride = 4*s->mb_width; - - ff_h264_alloc_tables(h); - - /* prowl for the "SEQH" marker in the extradata */ - extradata = (unsigned char *)avctx->extradata; - for (m = 0; m < avctx->extradata_size; m++) { - if (!memcmp(extradata, "SEQH", 4)) - break; - extradata++; - } - - /* if a match was found, parse the extra data */ - if (extradata && !memcmp(extradata, "SEQH", 4)) { - - GetBitContext gb; - int frame_size_code; - - size = AV_RB32(&extradata[4]); - init_get_bits(&gb, extradata + 8, size*8); - - /* 'frame size code' and optional 'width, height' */ - frame_size_code = get_bits(&gb, 3); - switch (frame_size_code) { - case 0: avctx->width = 160; avctx->height = 120; break; - case 1: avctx->width = 128; avctx->height = 96; break; - case 2: avctx->width = 176; avctx->height = 144; break; - case 3: avctx->width = 352; avctx->height = 288; break; - case 4: avctx->width = 704; avctx->height = 576; break; - case 5: avctx->width = 240; avctx->height = 180; break; - case 6: avctx->width = 320; avctx->height = 240; break; - case 7: - avctx->width = get_bits(&gb, 12); - avctx->height = get_bits(&gb, 12); - break; - } - - h->halfpel_flag = get_bits1(&gb); - h->thirdpel_flag = get_bits1(&gb); - - /* unknown fields */ - skip_bits1(&gb); - skip_bits1(&gb); - skip_bits1(&gb); - skip_bits1(&gb); - - s->low_delay = get_bits1(&gb); - - /* unknown field */ - skip_bits1(&gb); - - while (get_bits1(&gb)) { - skip_bits(&gb, 8); - } - - h->unknown_svq3_flag = get_bits1(&gb); - avctx->has_b_frames = !s->low_delay; - if (h->unknown_svq3_flag) { -#if CONFIG_ZLIB - unsigned watermark_width = svq3_get_ue_golomb(&gb); - unsigned watermark_height = svq3_get_ue_golomb(&gb); - int u1 = svq3_get_ue_golomb(&gb); - int u2 = get_bits(&gb, 8); - int u3 = get_bits(&gb, 2); - int u4 = svq3_get_ue_golomb(&gb); - unsigned buf_len = watermark_width*watermark_height*4; - int offset = (get_bits_count(&gb)+7)>>3; - uint8_t *buf; - - if ((uint64_t)watermark_width*4 > UINT_MAX/watermark_height) - return -1; - - buf = av_malloc(buf_len); - av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n", watermark_width, watermark_height); - av_log(avctx, AV_LOG_DEBUG, "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n", u1, u2, u3, u4, offset); - if (uncompress(buf, (uLong*)&buf_len, extradata + 8 + offset, size - offset) != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "could not uncompress watermark logo\n"); - av_free(buf); - return -1; - } - h->svq3_watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0); - h->svq3_watermark_key = h->svq3_watermark_key << 16 | h->svq3_watermark_key; - av_log(avctx, AV_LOG_DEBUG, "watermark key %#x\n", h->svq3_watermark_key); - av_free(buf); -#else - av_log(avctx, AV_LOG_ERROR, "this svq3 file contains watermark which need zlib support compiled in\n"); - return -1; -#endif - } - } - } - - return 0; -} - -static int svq3_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - MpegEncContext *const s = avctx->priv_data; - H264Context *const h = avctx->priv_data; - int m, mb_type; - - /* special case for last picture */ - if (buf_size == 0) { - if (s->next_picture_ptr && !s->low_delay) { - *(AVFrame *) data = *(AVFrame *) &s->next_picture; - s->next_picture_ptr = NULL; - *data_size = sizeof(AVFrame); - } - return 0; - } - - init_get_bits (&s->gb, buf, 8*buf_size); - - s->mb_x = s->mb_y = h->mb_xy = 0; - - if (svq3_decode_slice_header(h)) - return -1; - - s->pict_type = h->slice_type; - s->picture_number = h->slice_num; - - if (avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n", - av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag, - s->adaptive_quant, s->qscale, h->slice_num); - } - - /* for hurry_up == 5 */ - s->current_picture.pict_type = s->pict_type; - s->current_picture.key_frame = (s->pict_type == FF_I_TYPE); - - /* Skip B-frames if we do not have reference frames. */ - if (s->last_picture_ptr == NULL && s->pict_type == FF_B_TYPE) - return 0; - /* Skip B-frames if we are in a hurry. */ - if (avctx->hurry_up && s->pict_type == FF_B_TYPE) - return 0; - /* Skip everything if we are in a hurry >= 5. */ - if (avctx->hurry_up >= 5) - return 0; - if ( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == FF_B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != FF_I_TYPE) - || avctx->skip_frame >= AVDISCARD_ALL) - return 0; - - if (s->next_p_frame_damaged) { - if (s->pict_type == FF_B_TYPE) - return 0; - else - s->next_p_frame_damaged = 0; - } - - if (ff_h264_frame_start(h) < 0) - return -1; - - if (s->pict_type == FF_B_TYPE) { - h->frame_num_offset = (h->slice_num - h->prev_frame_num); - - if (h->frame_num_offset < 0) { - h->frame_num_offset += 256; - } - if (h->frame_num_offset == 0 || h->frame_num_offset >= h->prev_frame_num_offset) { - av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n"); - return -1; - } - } else { - h->prev_frame_num = h->frame_num; - h->frame_num = h->slice_num; - h->prev_frame_num_offset = (h->frame_num - h->prev_frame_num); - - if (h->prev_frame_num_offset < 0) { - h->prev_frame_num_offset += 256; - } - } - - for (m = 0; m < 2; m++){ - int i; - for (i = 0; i < 4; i++){ - int j; - for (j = -1; j < 4; j++) - h->ref_cache[m][scan8[0] + 8*i + j]= 1; - if (i < 3) - h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE; - } - } - - for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { - for (s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) { - h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; - - if ( (get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits && - ((get_bits_count(&s->gb) & 7) == 0 || show_bits(&s->gb, (-get_bits_count(&s->gb) & 7)) == 0)) { - - skip_bits(&s->gb, h->next_slice_index - get_bits_count(&s->gb)); - s->gb.size_in_bits = 8*buf_size; - - if (svq3_decode_slice_header(h)) - return -1; - - /* TODO: support s->mb_skip_run */ - } - - mb_type = svq3_get_ue_golomb(&s->gb); - - if (s->pict_type == FF_I_TYPE) { - mb_type += 8; - } else if (s->pict_type == FF_B_TYPE && mb_type >= 4) { - mb_type += 4; - } - if (mb_type > 33 || svq3_decode_mb(h, mb_type)) { - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - if (mb_type != 0) { - ff_h264_hl_decode_mb (h); - } - - if (s->pict_type != FF_B_TYPE && !s->low_delay) { - s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] = - (s->pict_type == FF_P_TYPE && mb_type < 8) ? (mb_type - 1) : -1; - } - } - - ff_draw_horiz_band(s, 16*s->mb_y, 16); - } - - MPV_frame_end(s); - - if (s->pict_type == FF_B_TYPE || s->low_delay) { - *(AVFrame *) data = *(AVFrame *) &s->current_picture; - } else { - *(AVFrame *) data = *(AVFrame *) &s->last_picture; - } - - /* Do not output the last pic after seeking. */ - if (s->last_picture_ptr || s->low_delay) { - *data_size = sizeof(AVFrame); - } - - return buf_size; -} - - -AVCodec svq3_decoder = { - "svq3", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SVQ3, - sizeof(H264Context), - svq3_decode_init, - NULL, - ff_h264_decode_end, - svq3_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_NONE}, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/synth_filter.c b/tizen/distrib/ffmpeg/libavcodec/synth_filter.c deleted file mode 100644 index a0ae364..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/synth_filter.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * copyright (c) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "fft.h" -#include "synth_filter.h" - -static void synth_filter_float(FFTContext *imdct, - float *synth_buf_ptr, int *synth_buf_offset, - float synth_buf2[32], const float window[512], - float out[32], const float in[32], float scale, float bias) -{ - float *synth_buf= synth_buf_ptr + *synth_buf_offset; - int i, j; - - ff_imdct_half(imdct, synth_buf, in); - - for (i = 0; i < 16; i++){ - float a= synth_buf2[i ]; - float b= synth_buf2[i + 16]; - float c= 0; - float d= 0; - for (j = 0; j < 512 - *synth_buf_offset; j += 64){ - a += window[i + j ]*(-synth_buf[15 - i + j ]); - b += window[i + j + 16]*( synth_buf[ i + j ]); - c += window[i + j + 32]*( synth_buf[16 + i + j ]); - d += window[i + j + 48]*( synth_buf[31 - i + j ]); - } - for ( ; j < 512; j += 64){ - a += window[i + j ]*(-synth_buf[15 - i + j - 512]); - b += window[i + j + 16]*( synth_buf[ i + j - 512]); - c += window[i + j + 32]*( synth_buf[16 + i + j - 512]); - d += window[i + j + 48]*( synth_buf[31 - i + j - 512]); - } - out[i ] = a*scale + bias; - out[i + 16] = b*scale + bias; - synth_buf2[i ] = c; - synth_buf2[i + 16] = d; - } - *synth_buf_offset= (*synth_buf_offset - 32)&511; -} - -av_cold void ff_synth_filter_init(SynthFilterContext *c) -{ - c->synth_filter_float = synth_filter_float; - - if (ARCH_ARM) ff_synth_filter_init_arm(c); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/synth_filter.h b/tizen/distrib/ffmpeg/libavcodec/synth_filter.h deleted file mode 100644 index d6209d5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/synth_filter.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * copyright (c) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_SYNTH_FILTER_H -#define AVCODEC_SYNTH_FILTER_H - -#include "fft.h" - -typedef struct SynthFilterContext { - void (*synth_filter_float)(FFTContext *imdct, - float *synth_buf_ptr, int *synth_buf_offset, - float synth_buf2[32], const float window[512], - float out[32], const float in[32], - float scale, float bias); -} SynthFilterContext; - -void ff_synth_filter_init(SynthFilterContext *c); -void ff_synth_filter_init_arm(SynthFilterContext *c); - -#endif /* AVCODEC_SYNTH_FILTER_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/tableprint.c b/tizen/distrib/ffmpeg/libavcodec/tableprint.c deleted file mode 100644 index e39606b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tableprint.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Generate a file for hardcoded tables - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "tableprint.h" - -WRITE_1D_FUNC(int8, int8_t, "%3"PRIi8, 15) -WRITE_1D_FUNC(uint8, uint8_t, "0x%02"PRIx8, 15) -WRITE_1D_FUNC(uint16, uint16_t, "0x%08"PRIx16, 7) -WRITE_1D_FUNC(uint32, uint32_t, "0x%08"PRIx32, 7) -WRITE_1D_FUNC(float, float, "%.18e", 3) - -WRITE_2D_FUNC(int8, int8_t) -WRITE_2D_FUNC(uint8, uint8_t) -WRITE_2D_FUNC(uint32, uint32_t) - -void write_fileheader(void) { - printf("/* This file was generated by libavcodec/tableprint */\n"); - printf("#include \n"); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/tableprint.h b/tizen/distrib/ffmpeg/libavcodec/tableprint.h deleted file mode 100644 index d81af97..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tableprint.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Generate a file for hardcoded tables - * - * Copyright (c) 2009 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_TABLEPRINT_H -#define AVCODEC_TABLEPRINT_H - -#include -#include - -#define WRITE_1D_FUNC_ARGV(name, type, linebrk, fmtstr, ...)\ -void write_##name##_array(const type *data, int len)\ -{\ - int i;\ - printf(" ");\ - for (i = 0; i < len - 1; i++) {\ - printf(" "fmtstr",", __VA_ARGS__);\ - if ((i & linebrk) == linebrk) printf("\n ");\ - }\ - printf(" "fmtstr"\n", __VA_ARGS__);\ -} - -#define WRITE_1D_FUNC(name, type, fmtstr, linebrk)\ - WRITE_1D_FUNC_ARGV(name, type, linebrk, fmtstr, data[i]) - -#define WRITE_2D_FUNC(name, type)\ -void write_##name##_2d_array(const void *arg, int len, int len2)\ -{\ - const type *data = arg;\ - int i;\ - printf(" {\n");\ - for (i = 0; i < len; i++) {\ - write_##name##_array(data + i * len2, len2);\ - printf(i == len - 1 ? " }\n" : " }, {\n");\ - }\ -} - -/** - * \defgroup printfuncs Predefined functions for printing tables - * - * \{ - */ -void write_int8_array (const int8_t *, int); -void write_uint8_array (const uint8_t *, int); -void write_uint16_array (const uint16_t *, int); -void write_uint32_array (const uint32_t *, int); -void write_float_array (const float *, int); -void write_int8_2d_array (const void *, int, int); -void write_uint8_2d_array (const void *, int, int); -void write_uint32_2d_array(const void *, int, int); -/** \} */ // end of printfuncs group - -/** Write a standard file header */ -void write_fileheader(void); - -#endif /* AVCODEC_TABLEPRINT_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/targa.c b/tizen/distrib/ffmpeg/libavcodec/targa.c deleted file mode 100644 index 50fe107..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/targa.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Targa (.tga) image decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -enum TargaCompr{ - TGA_NODATA = 0, // no image data - TGA_PAL = 1, // palettized - TGA_RGB = 2, // true-color - TGA_BW = 3, // black & white or grayscale - TGA_RLE = 8, // flag pointing that data is RLE-coded -}; - -typedef struct TargaContext { - AVFrame picture; - - int width, height; - int bpp; - int color_type; - int compression_type; -} TargaContext; - -static void targa_decode_rle(AVCodecContext *avctx, TargaContext *s, const uint8_t *src, uint8_t *dst, int w, int h, int stride, int bpp) -{ - int i, x, y; - int depth = (bpp + 1) >> 3; - int type, count; - int diff; - - diff = stride - w * depth; - x = y = 0; - while(y < h){ - type = *src++; - count = (type & 0x7F) + 1; - type &= 0x80; - if((x + count > w) && (x + count + 1 > (h - y) * w)){ - av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count); - return; - } - for(i = 0; i < count; i++){ - switch(depth){ - case 1: - *dst = *src; - break; - case 2: - *((uint16_t*)dst) = AV_RL16(src); - break; - case 3: - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - break; - case 4: - *((uint32_t*)dst) = AV_RL32(src); - break; - } - dst += depth; - if(!type) - src += depth; - - x++; - if(x == w){ - x = 0; - y++; - dst += diff; - } - } - if(type) - src += depth; - } -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TargaContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; - uint8_t *dst; - int stride; - int idlen, pal, compr, x, y, w, h, bpp, flags; - int first_clr, colors, csize; - - /* parse image header */ - idlen = *buf++; - pal = *buf++; - compr = *buf++; - first_clr = AV_RL16(buf); buf += 2; - colors = AV_RL16(buf); buf += 2; - csize = *buf++; - x = AV_RL16(buf); buf += 2; - y = AV_RL16(buf); buf += 2; - w = AV_RL16(buf); buf += 2; - h = AV_RL16(buf); buf += 2; - bpp = *buf++; - flags = *buf++; - //skip identifier if any - buf += idlen; - s->bpp = bpp; - s->width = w; - s->height = h; - switch(s->bpp){ - case 8: - avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? PIX_FMT_GRAY8 : PIX_FMT_PAL8; - break; - case 15: - avctx->pix_fmt = PIX_FMT_RGB555; - break; - case 16: - avctx->pix_fmt = PIX_FMT_RGB555; - break; - case 24: - avctx->pix_fmt = PIX_FMT_BGR24; - break; - case 32: - avctx->pix_fmt = PIX_FMT_RGB32; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Bit depth %i is not supported\n", s->bpp); - return -1; - } - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - if(avcodec_check_dimensions(avctx, w, h)) - return -1; - if(w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - if(avctx->get_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - if(flags & 0x20){ - dst = p->data[0]; - stride = p->linesize[0]; - }else{ //image is upside-down - dst = p->data[0] + p->linesize[0] * (h - 1); - stride = -p->linesize[0]; - } - - if(avctx->pix_fmt == PIX_FMT_PAL8 && avctx->palctrl){ - memcpy(p->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); - if(avctx->palctrl->palette_changed){ - p->palette_has_changed = 1; - avctx->palctrl->palette_changed = 0; - } - } - if(colors){ - if((colors + first_clr) > 256){ - av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr); - return -1; - } - if(csize != 24){ - av_log(avctx, AV_LOG_ERROR, "Palette entry size %i bits is not supported\n", csize); - return -1; - } - if(avctx->pix_fmt != PIX_FMT_PAL8)//should not occur but skip palette anyway - buf += colors * ((csize + 1) >> 3); - else{ - int r, g, b, t; - int32_t *pal = ((int32_t*)p->data[1]) + first_clr; - for(t = 0; t < colors; t++){ - r = *buf++; - g = *buf++; - b = *buf++; - *pal++ = (b << 16) | (g << 8) | r; - } - p->palette_has_changed = 1; - } - } - if((compr & (~TGA_RLE)) == TGA_NODATA) - memset(p->data[0], 0, p->linesize[0] * s->height); - else{ - if(compr & TGA_RLE) - targa_decode_rle(avctx, s, buf, dst, avctx->width, avctx->height, stride, bpp); - else{ - for(y = 0; y < s->height; y++){ -#if HAVE_BIGENDIAN - if((s->bpp + 1) >> 3 == 2){ - uint16_t *dst16 = (uint16_t*)dst; - for(x = 0; x < s->width; x++) - dst16[x] = AV_RL16(buf + x * 2); - }else if((s->bpp + 1) >> 3 == 4){ - uint32_t *dst32 = (uint32_t*)dst; - for(x = 0; x < s->width; x++) - dst32[x] = AV_RL32(buf + x * 4); - }else -#endif - memcpy(dst, buf, s->width * ((s->bpp + 1) >> 3)); - - dst += stride; - buf += s->width * ((s->bpp + 1) >> 3); - } - } - } - - *picture= *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); - - return buf_size; -} - -static av_cold int targa_init(AVCodecContext *avctx){ - TargaContext *s = avctx->priv_data; - - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; - - return 0; -} - -static av_cold int targa_end(AVCodecContext *avctx){ - TargaContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec targa_decoder = { - "targa", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TARGA, - sizeof(TargaContext), - targa_init, - NULL, - targa_end, - decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/targaenc.c b/tizen/distrib/ffmpeg/libavcodec/targaenc.c deleted file mode 100644 index e5d0042..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/targaenc.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Targa (.tga) image encoder - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "rle.h" - -typedef struct TargaContext { - AVFrame picture; -} TargaContext; - -/** - * RLE compress the image, with maximum size of out_size - * @param outbuf Output buffer - * @param out_size Maximum output size - * @param pic Image to compress - * @param bpp Bytes per pixel - * @param w Image width - * @param h Image height - * @return Size of output in bytes, or -1 if larger than out_size - */ -static int targa_encode_rle(uint8_t *outbuf, int out_size, AVFrame *pic, - int bpp, int w, int h) -{ - int y,ret; - uint8_t *out; - - out = outbuf; - - for(y = 0; y < h; y ++) { - ret = ff_rle_encode(out, out_size, pic->data[0] + pic->linesize[0] * y, bpp, w, 0x7f, 0, -1, 0); - if(ret == -1){ - return -1; - } - out+= ret; - out_size -= ret; - } - - return out - outbuf; -} - -static int targa_encode_normal(uint8_t *outbuf, AVFrame *pic, int bpp, int w, int h) -{ - int i, n = bpp * w; - uint8_t *out = outbuf; - uint8_t *ptr = pic->data[0]; - - for(i=0; i < h; i++) { - memcpy(out, ptr, n); - out += n; - ptr += pic->linesize[0]; - } - - return out - outbuf; -} - -static int targa_encode_frame(AVCodecContext *avctx, - unsigned char *outbuf, - int buf_size, void *data){ - AVFrame *p = data; - int bpp, picsize, datasize = -1; - uint8_t *out; - - if(avctx->width > 0xffff || avctx->height > 0xffff) { - av_log(avctx, AV_LOG_ERROR, "image dimensions too large\n"); - return -1; - } - picsize = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); - if(buf_size < picsize + 45) { - av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - /* zero out the header and only set applicable fields */ - memset(outbuf, 0, 12); - AV_WL16(outbuf+12, avctx->width); - AV_WL16(outbuf+14, avctx->height); - outbuf[17] = 0x20; /* origin is top-left. no alpha */ - - /* TODO: support alpha channel */ - switch(avctx->pix_fmt) { - case PIX_FMT_GRAY8: - outbuf[2] = 3; /* uncompressed grayscale image */ - outbuf[16] = 8; /* bpp */ - break; - case PIX_FMT_RGB555LE: - outbuf[2] = 2; /* uncompresses true-color image */ - outbuf[16] = 16; /* bpp */ - break; - case PIX_FMT_BGR24: - outbuf[2] = 2; /* uncompressed true-color image */ - outbuf[16] = 24; /* bpp */ - break; - default: - return -1; - } - bpp = outbuf[16] >> 3; - - out = outbuf + 18; /* skip past the header we just output */ - - /* try RLE compression */ - if (avctx->coder_type != FF_CODER_TYPE_RAW) - datasize = targa_encode_rle(out, picsize, p, bpp, avctx->width, avctx->height); - - /* if that worked well, mark the picture as RLE compressed */ - if(datasize >= 0) - outbuf[2] |= 8; - - /* if RLE didn't make it smaller, go back to no compression */ - else datasize = targa_encode_normal(out, p, bpp, avctx->width, avctx->height); - - out += datasize; - - /* The standard recommends including this section, even if we don't use - * any of the features it affords. TODO: take advantage of the pixel - * aspect ratio and encoder ID fields available? */ - memcpy(out, "\0\0\0\0\0\0\0\0TRUEVISION-XFILE.", 26); - - return out + 26 - outbuf; -} - -static av_cold int targa_encode_init(AVCodecContext *avctx) -{ - TargaContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - s->picture.key_frame= 1; - avctx->coded_frame= &s->picture; - - return 0; -} - -AVCodec targa_encoder = { - .name = "targa", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_TARGA, - .priv_data_size = sizeof(TargaContext), - .init = targa_encode_init, - .encode = targa_encode_frame, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB555LE, PIX_FMT_GRAY8, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Truevision Targa image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/tiertexseqv.c b/tizen/distrib/ffmpeg/libavcodec/tiertexseqv.c deleted file mode 100644 index c5f632e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tiertexseqv.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Tiertex Limited SEQ Video Decoder - * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Tiertex Limited SEQ video decoder - */ - -#include "avcodec.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" - - -typedef struct SeqVideoContext { - AVCodecContext *avctx; - AVFrame frame; -} SeqVideoContext; - - -static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size) -{ - int i, len, sz; - GetBitContext gb; - int code_table[64]; - - /* get the rle codes (at most 64 bytes) */ - init_get_bits(&gb, src, 64 * 8); - for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) { - code_table[i] = get_sbits(&gb, 4); - sz += FFABS(code_table[i]); - } - src += (get_bits_count(&gb) + 7) / 8; - - /* do the rle unpacking */ - for (i = 0; i < 64 && dst_size > 0; i++) { - len = code_table[i]; - if (len < 0) { - len = -len; - memset(dst, *src++, FFMIN(len, dst_size)); - } else { - memcpy(dst, src, FFMIN(len, dst_size)); - src += len; - } - dst += len; - dst_size -= len; - } - return src; -} - -static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) -{ - const unsigned char *color_table; - int b, i, len, bits; - GetBitContext gb; - unsigned char block[8 * 8]; - - len = *src++; - if (len & 0x80) { - switch (len & 3) { - case 1: - src = seq_unpack_rle_block(src, block, sizeof(block)); - for (b = 0; b < 8; b++) { - memcpy(dst, &block[b * 8], 8); - dst += seq->frame.linesize[0]; - } - break; - case 2: - src = seq_unpack_rle_block(src, block, sizeof(block)); - for (i = 0; i < 8; i++) { - for (b = 0; b < 8; b++) - dst[b * seq->frame.linesize[0]] = block[i * 8 + b]; - ++dst; - } - break; - } - } else { - color_table = src; - src += len; - bits = ff_log2_tab[len - 1] + 1; - init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8; - for (b = 0; b < 8; b++) { - for (i = 0; i < 8; i++) - dst[i] = color_table[get_bits(&gb, bits)]; - dst += seq->frame.linesize[0]; - } - } - - return src; -} - -static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) -{ - int i; - - for (i = 0; i < 8; i++) { - memcpy(dst, src, 8); - src += 8; - dst += seq->frame.linesize[0]; - } - - return src; -} - -static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) -{ - int pos, offset; - - do { - pos = *src++; - offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7); - dst[offset] = *src++; - } while (!(pos & 0x80)); - - return src; -} - -static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size) -{ - GetBitContext gb; - int flags, i, j, x, y, op; - unsigned char c[3]; - unsigned char *dst; - uint32_t *palette; - - flags = *data++; - - if (flags & 1) { - palette = (uint32_t *)seq->frame.data[1]; - for (i = 0; i < 256; i++) { - for (j = 0; j < 3; j++, data++) - c[j] = (*data << 2) | (*data >> 4); - palette[i] = AV_RB24(c); - } - seq->frame.palette_has_changed = 1; - } - - if (flags & 2) { - init_get_bits(&gb, data, 128 * 8); data += 128; - for (y = 0; y < 128; y += 8) - for (x = 0; x < 256; x += 8) { - dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x]; - op = get_bits(&gb, 2); - switch (op) { - case 1: - data = seq_decode_op1(seq, data, dst); - break; - case 2: - data = seq_decode_op2(seq, data, dst); - break; - case 3: - data = seq_decode_op3(seq, data, dst); - break; - } - } - } -} - -static av_cold int seqvideo_decode_init(AVCodecContext *avctx) -{ - SeqVideoContext *seq = avctx->priv_data; - - seq->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - seq->frame.data[0] = NULL; - - return 0; -} - -static int seqvideo_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - - SeqVideoContext *seq = avctx->priv_data; - - seq->frame.reference = 1; - seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &seq->frame)) { - av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n"); - return -1; - } - - seqvideo_decode(seq, buf, buf_size); - - *data_size = sizeof(AVFrame); - *(AVFrame *)data = seq->frame; - - return buf_size; -} - -static av_cold int seqvideo_decode_end(AVCodecContext *avctx) -{ - SeqVideoContext *seq = avctx->priv_data; - - if (seq->frame.data[0]) - avctx->release_buffer(avctx, &seq->frame); - - return 0; -} - -AVCodec tiertexseqvideo_decoder = { - "tiertexseqvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TIERTEXSEQVIDEO, - sizeof(SeqVideoContext), - seqvideo_decode_init, - NULL, - seqvideo_decode_end, - seqvideo_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/tiff.c b/tizen/distrib/ffmpeg/libavcodec/tiff.c deleted file mode 100644 index 2f3cef2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tiff.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * TIFF image decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * TIFF image decoder - * @file - * @author Konstantin Shishkov - */ -#include "avcodec.h" -#if CONFIG_ZLIB -#include -#endif -#include "lzw.h" -#include "tiff.h" -#include "faxcompr.h" -#include "libavutil/common.h" -#include "libavutil/intreadwrite.h" - -typedef struct TiffContext { - AVCodecContext *avctx; - AVFrame picture; - - int width, height; - unsigned int bpp; - int le; - int compr; - int invert; - int fax_opts; - int predictor; - int fill_order; - - int strips, rps, sstype; - int sot; - const uint8_t* stripdata; - const uint8_t* stripsizes; - int stripsize, stripoff; - LZWState *lzw; -} TiffContext; - -static int tget_short(const uint8_t **p, int le){ - int v = le ? AV_RL16(*p) : AV_RB16(*p); - *p += 2; - return v; -} - -static int tget_long(const uint8_t **p, int le){ - int v = le ? AV_RL32(*p) : AV_RB32(*p); - *p += 4; - return v; -} - -static int tget(const uint8_t **p, int type, int le){ - switch(type){ - case TIFF_BYTE : return *(*p)++; - case TIFF_SHORT: return tget_short(p, le); - case TIFF_LONG : return tget_long (p, le); - default : return -1; - } -} - -#if CONFIG_ZLIB -static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, int size) -{ - z_stream zstream; - int zret; - - memset(&zstream, 0, sizeof(zstream)); - zstream.next_in = src; - zstream.avail_in = size; - zstream.next_out = dst; - zstream.avail_out = *len; - zret = inflateInit(&zstream); - if (zret != Z_OK) { - av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret); - return zret; - } - zret = inflate(&zstream, Z_SYNC_FLUSH); - inflateEnd(&zstream); - *len = zstream.total_out; - return zret == Z_STREAM_END ? Z_OK : zret; -} -#endif - -static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){ - int c, line, pixels, code; - const uint8_t *ssrc = src; - int width = s->width * s->bpp >> 3; -#if CONFIG_ZLIB - uint8_t *zbuf; unsigned long outlen; - - if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){ - int ret; - outlen = width * lines; - zbuf = av_malloc(outlen); - ret = tiff_uncompress(zbuf, &outlen, src, size); - if(ret != Z_OK){ - av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu) with error %d\n", outlen, (unsigned long)width * lines, ret); - av_free(zbuf); - return -1; - } - src = zbuf; - for(line = 0; line < lines; line++){ - memcpy(dst, src, width); - dst += stride; - src += width; - } - av_free(zbuf); - return 0; - } -#endif - if(s->compr == TIFF_LZW){ - if(ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n"); - return -1; - } - } - if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){ - int i, ret = 0; - uint8_t *src2 = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(!src2 || (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE < (unsigned)size){ - av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); - return -1; - } - if(s->fax_opts & 2){ - av_log(s->avctx, AV_LOG_ERROR, "Uncompressed fax mode is not supported (yet)\n"); - av_free(src2); - return -1; - } - if(!s->fill_order){ - memcpy(src2, src, size); - }else{ - for(i = 0; i < size; i++) - src2[i] = av_reverse[src[i]]; - } - memset(src2+size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - switch(s->compr){ - case TIFF_CCITT_RLE: - case TIFF_G3: - case TIFF_G4: - ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts); - break; - } - av_free(src2); - return ret; - } - for(line = 0; line < lines; line++){ - if(src - ssrc > size){ - av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n"); - return -1; - } - switch(s->compr){ - case TIFF_RAW: - memcpy(dst, src, width); - src += width; - break; - case TIFF_PACKBITS: - for(pixels = 0; pixels < width;){ - code = (int8_t)*src++; - if(code >= 0){ - code++; - if(pixels + code > width){ - av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); - return -1; - } - memcpy(dst + pixels, src, code); - src += code; - pixels += code; - }else if(code != -128){ // -127..-1 - code = (-code) + 1; - if(pixels + code > width){ - av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - c = *src++; - memset(dst + pixels, c, code); - pixels += code; - } - } - break; - case TIFF_LZW: - pixels = ff_lzw_decode(s->lzw, dst, width); - if(pixels < width){ - av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width); - return -1; - } - break; - } - dst += stride; - } - return 0; -} - - -static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf) -{ - int tag, type, count, off, value = 0; - int i, j; - uint32_t *pal; - const uint8_t *rp, *gp, *bp; - - tag = tget_short(&buf, s->le); - type = tget_short(&buf, s->le); - count = tget_long(&buf, s->le); - off = tget_long(&buf, s->le); - - if(count == 1){ - switch(type){ - case TIFF_BYTE: - case TIFF_SHORT: - buf -= 4; - value = tget(&buf, type, s->le); - buf = NULL; - break; - case TIFF_LONG: - value = off; - buf = NULL; - break; - case TIFF_STRING: - if(count <= 4){ - buf -= 4; - break; - } - default: - value = -1; - buf = start + off; - } - }else if(type_sizes[type] * count <= 4){ - buf -= 4; - }else{ - buf = start + off; - } - - if(buf && (buf < start || buf > end_buf)){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } - - switch(tag){ - case TIFF_WIDTH: - s->width = value; - break; - case TIFF_HEIGHT: - s->height = value; - break; - case TIFF_BPP: - if(count == 1) s->bpp = value; - else{ - switch(type){ - case TIFF_BYTE: - s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF); - break; - case TIFF_SHORT: - case TIFF_LONG: - s->bpp = 0; - for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le); - break; - default: - s->bpp = -1; - } - } - if(count > 4){ - av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count); - return -1; - } - switch(s->bpp*10 + count){ - case 11: - s->avctx->pix_fmt = PIX_FMT_MONOBLACK; - break; - case 81: - s->avctx->pix_fmt = PIX_FMT_PAL8; - break; - case 243: - s->avctx->pix_fmt = PIX_FMT_RGB24; - break; - case 161: - s->avctx->pix_fmt = PIX_FMT_GRAY16BE; - break; - case 324: - s->avctx->pix_fmt = PIX_FMT_RGBA; - break; - case 483: - s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count); - return -1; - } - if(s->width != s->avctx->width || s->height != s->avctx->height){ - if(avcodec_check_dimensions(s->avctx, s->width, s->height)) - return -1; - avcodec_set_dimensions(s->avctx, s->width, s->height); - } - if(s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - if(s->bpp == 8){ - /* make default grayscale pal */ - pal = (uint32_t *) s->picture.data[1]; - for(i = 0; i < 256; i++) - pal[i] = i * 0x010101; - } - break; - case TIFF_COMPR: - s->compr = value; - s->predictor = 0; - switch(s->compr){ - case TIFF_RAW: - case TIFF_PACKBITS: - case TIFF_LZW: - case TIFF_CCITT_RLE: - break; - case TIFF_G3: - case TIFF_G4: - s->fax_opts = 0; - break; - case TIFF_DEFLATE: - case TIFF_ADOBE_DEFLATE: -#if CONFIG_ZLIB - break; -#else - av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n"); - return -1; -#endif - case TIFF_JPEG: - case TIFF_NEWJPEG: - av_log(s->avctx, AV_LOG_ERROR, "JPEG compression is not supported\n"); - return -1; - default: - av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr); - return -1; - } - break; - case TIFF_ROWSPERSTRIP: - if(type == TIFF_LONG && value == -1) - value = s->avctx->height; - if(value < 1){ - av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n"); - return -1; - } - s->rps = value; - break; - case TIFF_STRIP_OFFS: - if(count == 1){ - s->stripdata = NULL; - s->stripoff = value; - }else - s->stripdata = start + off; - s->strips = count; - if(s->strips == 1) s->rps = s->height; - s->sot = type; - if(s->stripdata > end_buf){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } - break; - case TIFF_STRIP_SIZE: - if(count == 1){ - s->stripsizes = NULL; - s->stripsize = value; - s->strips = 1; - }else{ - s->stripsizes = start + off; - } - s->strips = count; - s->sstype = type; - if(s->stripsizes > end_buf){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } - break; - case TIFF_PREDICTOR: - s->predictor = value; - break; - case TIFF_INVERT: - switch(value){ - case 0: - s->invert = 1; - break; - case 1: - s->invert = 0; - break; - case 2: - case 3: - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n", value); - return -1; - } - break; - case TIFF_FILL_ORDER: - if(value < 1 || value > 2){ - av_log(s->avctx, AV_LOG_ERROR, "Unknown FillOrder value %d, trying default one\n", value); - value = 1; - } - s->fill_order = value - 1; - break; - case TIFF_PAL: - if(s->avctx->pix_fmt != PIX_FMT_PAL8){ - av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n"); - return -1; - } - pal = (uint32_t *) s->picture.data[1]; - off = type_sizes[type]; - rp = buf; - gp = buf + count / 3 * off; - bp = buf + count / 3 * off * 2; - off = (type_sizes[type] - 1) << 3; - for(i = 0; i < count / 3; i++){ - j = (tget(&rp, type, s->le) >> off) << 16; - j |= (tget(&gp, type, s->le) >> off) << 8; - j |= tget(&bp, type, s->le) >> off; - pal[i] = j; - } - break; - case TIFF_PLANAR: - if(value == 2){ - av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n"); - return -1; - } - break; - case TIFF_T4OPTIONS: - if(s->compr == TIFF_G3) - s->fax_opts = value; - break; - case TIFF_T6OPTIONS: - if(s->compr == TIFF_G4) - s->fax_opts = value; - break; - } - return 0; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TiffContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; - const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; - int id, le, off; - int i, j, entries; - int stride, soff, ssize; - uint8_t *dst; - - //parse image header - id = AV_RL16(buf); buf += 2; - if(id == 0x4949) le = 1; - else if(id == 0x4D4D) le = 0; - else{ - av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n"); - return -1; - } - s->le = le; - s->invert = 0; - s->compr = TIFF_RAW; - s->fill_order = 0; - // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number - // that further identifies the file as a TIFF file" - if(tget_short(&buf, le) != 42){ - av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n"); - return -1; - } - /* parse image file directory */ - off = tget_long(&buf, le); - if(orig_buf + off + 14 >= end_buf){ - av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); - return -1; - } - buf = orig_buf + off; - entries = tget_short(&buf, le); - for(i = 0; i < entries; i++){ - if(tiff_decode_tag(s, orig_buf, buf, end_buf) < 0) - return -1; - buf += 12; - } - if(!s->stripdata && !s->stripoff){ - av_log(avctx, AV_LOG_ERROR, "Image data is missing\n"); - return -1; - } - /* now we have the data and may start decoding */ - if(!p->data[0]){ - s->bpp = 1; - avctx->pix_fmt = PIX_FMT_MONOBLACK; - if(s->width != s->avctx->width || s->height != s->avctx->height){ - if(avcodec_check_dimensions(s->avctx, s->width, s->height)) - return -1; - avcodec_set_dimensions(s->avctx, s->width, s->height); - } - if(s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - } - if(s->strips == 1 && !s->stripsize){ - av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); - s->stripsize = buf_size - s->stripoff; - } - stride = p->linesize[0]; - dst = p->data[0]; - for(i = 0; i < s->height; i += s->rps){ - if(s->stripsizes) - ssize = tget(&s->stripsizes, s->sstype, s->le); - else - ssize = s->stripsize; - - if(s->stripdata){ - soff = tget(&s->stripdata, s->sot, s->le); - }else - soff = s->stripoff; - if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0) - break; - dst += s->rps * stride; - } - if(s->predictor == 2){ - dst = p->data[0]; - soff = s->bpp >> 3; - ssize = s->width * soff; - for(i = 0; i < s->height; i++) { - for(j = soff; j < ssize; j++) - dst[j] += dst[j - soff]; - dst += stride; - } - } - - if(s->invert){ - uint8_t *src; - int j; - - src = s->picture.data[0]; - for(j = 0; j < s->height; j++){ - for(i = 0; i < s->picture.linesize[0]; i++) - src[i] = 255 - src[i]; - src += s->picture.linesize[0]; - } - } - *picture= *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); - - return buf_size; -} - -static av_cold int tiff_init(AVCodecContext *avctx){ - TiffContext *s = avctx->priv_data; - - s->width = 0; - s->height = 0; - s->avctx = avctx; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; - ff_lzw_decode_open(&s->lzw); - ff_ccitt_unpack_init(); - - return 0; -} - -static av_cold int tiff_end(AVCodecContext *avctx) -{ - TiffContext * const s = avctx->priv_data; - - ff_lzw_decode_close(&s->lzw); - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - return 0; -} - -AVCodec tiff_decoder = { - "tiff", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TIFF, - sizeof(TiffContext), - tiff_init, - NULL, - tiff_end, - decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/tiff.h b/tizen/distrib/ffmpeg/libavcodec/tiff.h deleted file mode 100644 index 235a998..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tiff.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * TIFF tables - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * TIFF tables - * @file - * @author Konstantin Shishkov - */ -#ifndef AVCODEC_TIFF_H -#define AVCODEC_TIFF_H - -#include - -/** abridged list of TIFF tags */ -enum TiffTags{ - TIFF_SUBFILE = 0xfe, - TIFF_WIDTH = 0x100, - TIFF_HEIGHT, - TIFF_BPP, - TIFF_COMPR, - TIFF_INVERT = 0x106, - TIFF_FILL_ORDER = 0x10A, - TIFF_STRIP_OFFS = 0x111, - TIFF_SAMPLES_PER_PIXEL = 0x115, - TIFF_ROWSPERSTRIP = 0x116, - TIFF_STRIP_SIZE, - TIFF_XRES = 0x11A, - TIFF_YRES = 0x11B, - TIFF_PLANAR = 0x11C, - TIFF_XPOS = 0x11E, - TIFF_YPOS = 0x11F, - TIFF_T4OPTIONS = 0x124, - TIFF_T6OPTIONS, - TIFF_RES_UNIT = 0x128, - TIFF_SOFTWARE_NAME = 0x131, - TIFF_PREDICTOR = 0x13D, - TIFF_PAL = 0x140, - TIFF_YCBCR_COEFFICIENTS = 0x211, - TIFF_YCBCR_SUBSAMPLING = 0x212, - TIFF_YCBCR_POSITIONING = 0x213, - TIFF_REFERENCE_BW = 0x214, -}; - -/** list of TIFF compression types */ -enum TiffCompr{ - TIFF_RAW = 1, - TIFF_CCITT_RLE, - TIFF_G3, - TIFF_G4, - TIFF_LZW, - TIFF_JPEG, - TIFF_NEWJPEG, - TIFF_ADOBE_DEFLATE, - TIFF_PACKBITS = 0x8005, - TIFF_DEFLATE = 0x80B2 -}; - -enum TiffTypes{ - TIFF_BYTE = 1, - TIFF_STRING, - TIFF_SHORT, - TIFF_LONG, - TIFF_RATIONAL, -}; - -/** sizes of various TIFF field types (string size = 100)*/ -static const uint8_t type_sizes[6] = { - 0, 1, 100, 2, 4, 8 -}; - -#endif /* AVCODEC_TIFF_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/tiffenc.c b/tizen/distrib/ffmpeg/libavcodec/tiffenc.c deleted file mode 100644 index 0905cea..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tiffenc.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * TIFF image encoder - * Copyright (c) 2007 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * TIFF image encoder - * @file - * @author Bartlomiej Wolowiec - */ -#include "avcodec.h" -#if CONFIG_ZLIB -#include -#endif -#include "bytestream.h" -#include "tiff.h" -#include "rle.h" -#include "lzw.h" -#include "put_bits.h" - -#define TIFF_MAX_ENTRY 32 - -/** sizes of various TIFF field types (string size = 1)*/ -static const uint8_t type_sizes2[6] = { - 0, 1, 1, 2, 4, 8 -}; - -typedef struct TiffEncoderContext { - AVCodecContext *avctx; - AVFrame picture; - - int width; ///< picture width - int height; ///< picture height - unsigned int bpp; ///< bits per pixel - int compr; ///< compression level - int bpp_tab_size; ///< bpp_tab size - int photometric_interpretation; ///< photometric interpretation - int strips; ///< number of strips - int rps; ///< row per strip - uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header - int num_entries; ///< number of entires - uint8_t **buf; ///< actual position in buffer - uint8_t *buf_start; ///< pointer to first byte in buffer - int buf_size; ///< buffer size - uint16_t subsampling[2]; ///< YUV subsampling factors - struct LZWEncodeState *lzws; ///< LZW Encode state -} TiffEncoderContext; - - -/** - * Check free space in buffer - * @param s Tiff context - * @param need Needed bytes - * @return 0 - ok, 1 - no free space - */ -inline static int check_size(TiffEncoderContext * s, uint64_t need) -{ - if (s->buf_size < *s->buf - s->buf_start + need) { - *s->buf = s->buf_start + s->buf_size + 1; - av_log(s->avctx, AV_LOG_ERROR, "Buffer is too small\n"); - return 1; - } - return 0; -} - -/** - * Put n values to buffer - * - * @param p Pointer to pointer to output buffer - * @param n Number of values - * @param val Pointer to values - * @param type Type of values - * @param flip =0 - normal copy, >0 - flip - */ -static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type, - int flip) -{ - int i; -#if HAVE_BIGENDIAN - flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type]; -#endif - for (i = 0; i < n * type_sizes2[type]; i++) - *(*p)++ = val[i ^ flip]; -} - -/** - * Add entry to directory in tiff header. - * @param s Tiff context - * @param tag Tag that identifies the entry - * @param type Entry type - * @param count The number of values - * @param ptr_val Pointer to values - */ -static void add_entry(TiffEncoderContext * s, - enum TiffTags tag, enum TiffTypes type, int count, - const void *ptr_val) -{ - uint8_t *entries_ptr = s->entries + 12 * s->num_entries; - - assert(s->num_entries < TIFF_MAX_ENTRY); - - bytestream_put_le16(&entries_ptr, tag); - bytestream_put_le16(&entries_ptr, type); - bytestream_put_le32(&entries_ptr, count); - - if (type_sizes[type] * count <= 4) { - tnput(&entries_ptr, count, ptr_val, type, 0); - } else { - bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start); - check_size(s, count * type_sizes2[type]); - tnput(s->buf, count, ptr_val, type, 0); - } - - s->num_entries++; -} - -static void add_entry1(TiffEncoderContext * s, - enum TiffTags tag, enum TiffTypes type, int val){ - uint16_t w = val; - uint32_t dw= val; - add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw); -} - -/** - * Encode one strip in tiff file - * - * @param s Tiff context - * @param src Input buffer - * @param dst Output buffer - * @param n Size of input buffer - * @param compr Compression method - * @return Number of output bytes. If an output error is encountered, -1 returned - */ -static int encode_strip(TiffEncoderContext * s, const int8_t * src, - uint8_t * dst, int n, int compr) -{ - - switch (compr) { -#if CONFIG_ZLIB - case TIFF_DEFLATE: - case TIFF_ADOBE_DEFLATE: - { - unsigned long zlen = s->buf_size - (*s->buf - s->buf_start); - if (compress(dst, &zlen, src, n) != Z_OK) { - av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n"); - return -1; - } - return zlen; - } -#endif - case TIFF_RAW: - if (check_size(s, n)) - return -1; - memcpy(dst, src, n); - return n; - case TIFF_PACKBITS: - return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0); - case TIFF_LZW: - return ff_lzw_encode(s->lzws, src, n); - default: - return -1; - } -} - -static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum) -{ - AVFrame *p = &s->picture; - int i, j, k; - int w = (s->width - 1) / s->subsampling[0] + 1; - uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]]; - uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]]; - for (i = 0; i < w; i++){ - for (j = 0; j < s->subsampling[1]; j++) - for (k = 0; k < s->subsampling[0]; k++) - *dst++ = p->data[0][(lnum + j) * p->linesize[0] + - i * s->subsampling[0] + k]; - *dst++ = *pu++; - *dst++ = *pv++; - } -} - -static int encode_frame(AVCodecContext * avctx, unsigned char *buf, - int buf_size, void *data) -{ - TiffEncoderContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame *const p = (AVFrame *) & s->picture; - int i; - int n; - uint8_t *ptr = buf; - uint8_t *offset; - uint32_t strips; - uint32_t *strip_sizes = NULL; - uint32_t *strip_offsets = NULL; - int bytes_per_row; - uint32_t res[2] = { 72, 1 }; // image resolution (72/1) - static const uint16_t bpp_tab[] = { 8, 8, 8, 8 }; - int ret = -1; - int is_yuv = 0; - uint8_t *yuv_line = NULL; - int shift_h, shift_v; - - s->buf_start = buf; - s->buf = &ptr; - s->buf_size = buf_size; - - *p = *pict; - p->pict_type = FF_I_TYPE; - p->key_frame = 1; - avctx->coded_frame= &s->picture; - - s->compr = TIFF_PACKBITS; - if (avctx->compression_level == 0) { - s->compr = TIFF_RAW; - } else if(avctx->compression_level == 2) { - s->compr = TIFF_LZW; -#if CONFIG_ZLIB - } else if ((avctx->compression_level >= 3)) { - s->compr = TIFF_DEFLATE; -#endif - } - - s->width = avctx->width; - s->height = avctx->height; - s->subsampling[0] = 1; - s->subsampling[1] = 1; - - switch (avctx->pix_fmt) { - case PIX_FMT_RGB24: - s->bpp = 24; - s->photometric_interpretation = 2; - break; - case PIX_FMT_GRAY8: - s->bpp = 8; - s->photometric_interpretation = 1; - break; - case PIX_FMT_PAL8: - s->bpp = 8; - s->photometric_interpretation = 3; - break; - case PIX_FMT_MONOBLACK: - s->bpp = 1; - s->photometric_interpretation = 1; - break; - case PIX_FMT_MONOWHITE: - s->bpp = 1; - s->photometric_interpretation = 0; - break; - case PIX_FMT_YUV420P: - case PIX_FMT_YUV422P: - case PIX_FMT_YUV444P: - case PIX_FMT_YUV410P: - case PIX_FMT_YUV411P: - s->photometric_interpretation = 6; - avcodec_get_chroma_sub_sample(avctx->pix_fmt, - &shift_h, &shift_v); - s->bpp = 8 + (16 >> (shift_h + shift_v)); - s->subsampling[0] = 1 << shift_h; - s->subsampling[1] = 1 << shift_v; - s->bpp_tab_size = 3; - is_yuv = 1; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, - "This colors format is not supported\n"); - return -1; - } - if (!is_yuv) - s->bpp_tab_size = (s->bpp >> 3); - - if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW) - //best choose for DEFLATE - s->rps = s->height; - else - s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1); // suggest size of strip - s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up - - strips = (s->height - 1) / s->rps + 1; - - if (check_size(s, 8)) - goto fail; - - // write header - bytestream_put_le16(&ptr, 0x4949); - bytestream_put_le16(&ptr, 42); - - offset = ptr; - bytestream_put_le32(&ptr, 0); - - strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips); - strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips); - - bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp - * s->subsampling[0] * s->subsampling[1] + 7) >> 3; - if (is_yuv){ - yuv_line = av_malloc(bytes_per_row); - if (yuv_line == NULL){ - av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n"); - goto fail; - } - } - -#if CONFIG_ZLIB - if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) { - uint8_t *zbuf; - int zlen, zn; - int j; - - zlen = bytes_per_row * s->rps; - zbuf = av_malloc(zlen); - strip_offsets[0] = ptr - buf; - zn = 0; - for (j = 0; j < s->rps; j++) { - if (is_yuv){ - pack_yuv(s, yuv_line, j); - memcpy(zbuf + zn, yuv_line, bytes_per_row); - j += s->subsampling[1] - 1; - } - else - memcpy(zbuf + j * bytes_per_row, - p->data[0] + j * p->linesize[0], bytes_per_row); - zn += bytes_per_row; - } - n = encode_strip(s, zbuf, ptr, zn, s->compr); - av_free(zbuf); - if (n<0) { - av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); - goto fail; - } - ptr += n; - strip_sizes[0] = ptr - buf - strip_offsets[0]; - } else -#endif - { - if(s->compr == TIFF_LZW) - s->lzws = av_malloc(ff_lzw_encode_state_size); - for (i = 0; i < s->height; i++) { - if (strip_sizes[i / s->rps] == 0) { - if(s->compr == TIFF_LZW){ - ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start), - 12, FF_LZW_TIFF, put_bits); - } - strip_offsets[i / s->rps] = ptr - buf; - } - if (is_yuv){ - pack_yuv(s, yuv_line, i); - n = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr); - i += s->subsampling[1] - 1; - } - else - n = encode_strip(s, p->data[0] + i * p->linesize[0], - ptr, bytes_per_row, s->compr); - if (n < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); - goto fail; - } - strip_sizes[i / s->rps] += n; - ptr += n; - if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){ - int ret; - ret = ff_lzw_encode_flush(s->lzws, flush_put_bits); - strip_sizes[(i / s->rps )] += ret ; - ptr += ret; - } - } - if(s->compr == TIFF_LZW) - av_free(s->lzws); - } - - s->num_entries = 0; - - add_entry1(s,TIFF_SUBFILE, TIFF_LONG, 0); - add_entry1(s,TIFF_WIDTH, TIFF_LONG, s->width); - add_entry1(s,TIFF_HEIGHT, TIFF_LONG, s->height); - - if (s->bpp_tab_size) - add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab); - - add_entry1(s,TIFF_COMPR, TIFF_SHORT, s->compr); - add_entry1(s,TIFF_INVERT, TIFF_SHORT, s->photometric_interpretation); - add_entry(s, TIFF_STRIP_OFFS, TIFF_LONG, strips, strip_offsets); - - if (s->bpp_tab_size) - add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size); - - add_entry1(s,TIFF_ROWSPERSTRIP, TIFF_LONG, s->rps); - add_entry(s, TIFF_STRIP_SIZE, TIFF_LONG, strips, strip_sizes); - add_entry(s, TIFF_XRES, TIFF_RATIONAL, 1, res); - add_entry(s, TIFF_YRES, TIFF_RATIONAL, 1, res); - add_entry1(s,TIFF_RES_UNIT, TIFF_SHORT, 2); - - if(!(avctx->flags & CODEC_FLAG_BITEXACT)) - add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING, - strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT); - - if (avctx->pix_fmt == PIX_FMT_PAL8) { - uint16_t pal[256 * 3]; - for (i = 0; i < 256; i++) { - uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4); - pal[i] = ((rgb >> 16) & 0xff) * 257; - pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257; - pal[i + 512] = ( rgb & 0xff) * 257; - } - add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal); - } - if (is_yuv){ - /** according to CCIR Recommendation 601.1 */ - uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1}; - add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT, 2, s->subsampling); - add_entry(s, TIFF_REFERENCE_BW, TIFF_RATIONAL, 6, refbw); - } - bytestream_put_le32(&offset, ptr - buf); // write offset to dir - - if (check_size(s, 6 + s->num_entries * 12)) - goto fail; - bytestream_put_le16(&ptr, s->num_entries); // write tag count - bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12); - bytestream_put_le32(&ptr, 0); - - ret = ptr - buf; - -fail: - av_free(strip_sizes); - av_free(strip_offsets); - av_free(yuv_line); - return ret; -} - -AVCodec tiff_encoder = { - "tiff", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TIFF, - sizeof(TiffEncoderContext), - NULL, - encode_frame, - NULL, - NULL, - 0, - NULL, - .pix_fmts = - (const enum PixelFormat[]) {PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8, - PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE, - PIX_FMT_YUV420P, PIX_FMT_YUV422P, - PIX_FMT_YUV444P, PIX_FMT_YUV410P, - PIX_FMT_YUV411P, - PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/tmv.c b/tizen/distrib/ffmpeg/libavcodec/tmv.c deleted file mode 100644 index 5117cd0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tmv.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 8088flex TMV video decoder - * Copyright (c) 2009 Daniel Verkamp - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * 8088flex TMV video decoder - * @file - * @author Daniel Verkamp - * @sa http://www.oldskool.org/pc/8088_Corruption - */ - -#include "avcodec.h" - -#include "cga_data.h" - -typedef struct TMVContext { - AVFrame pic; -} TMVContext; - -static int tmv_decode_frame(AVCodecContext *avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - TMVContext *tmv = avctx->priv_data; - const uint8_t *src = avpkt->data; - uint8_t *dst, *dst_char; - unsigned char_cols = avctx->width >> 3; - unsigned char_rows = avctx->height >> 3; - unsigned x, y, mask, char_y, fg, bg, c; - - if (tmv->pic.data[0]) - avctx->release_buffer(avctx, &tmv->pic); - - if (avctx->get_buffer(avctx, &tmv->pic) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if (avpkt->size < 2*char_rows*char_cols) { - av_log(avctx, AV_LOG_ERROR, - "Input buffer too small, truncated sample?\n"); - *data_size = 0; - return -1; - } - - tmv->pic.pict_type = FF_I_TYPE; - tmv->pic.key_frame = 1; - dst = tmv->pic.data[0]; - - tmv->pic.palette_has_changed = 1; - memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4); - - for (y = 0; y < char_rows; y++) { - for (x = 0; x < char_cols; x++) { - c = *src++ * 8; - bg = *src >> 4; - fg = *src++ & 0xF; - - dst_char = dst + x * 8; - for (char_y = 0; char_y < 8; char_y++) { - for (mask = 0x80; mask; mask >>= 1) { - *dst_char++ = ff_cga_font[c + char_y] & mask ? fg : bg; - } - dst_char += tmv->pic.linesize[0] - 8; - } - } - dst += tmv->pic.linesize[0] * 8; - } - - *data_size = sizeof(AVFrame); - *(AVFrame *)data = tmv->pic; - return avpkt->size; -} - -static av_cold int tmv_decode_close(AVCodecContext *avctx) -{ - TMVContext *tmv = avctx->priv_data; - - if (tmv->pic.data[0]) - avctx->release_buffer(avctx, &tmv->pic); - - return 0; -} - -AVCodec tmv_decoder = { - .name = "tmv", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_TMV, - .priv_data_size = sizeof(TMVContext), - .close = tmv_decode_close, - .decode = tmv_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/truemotion1.c b/tizen/distrib/ffmpeg/libavcodec/truemotion1.c deleted file mode 100644 index 4306917..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/truemotion1.c +++ /dev/null @@ -1,904 +0,0 @@ -/* - * Duck TrueMotion 1.0 Decoder - * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Duck TrueMotion v1 Video Decoder by - * Alex Beregszaszi and - * Mike Melanson (melanson@pcisys.net) - * - * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and - * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet. - */ - -#include -#include -#include - -#include "avcodec.h" -#include "dsputil.h" - -#include "truemotion1data.h" - -typedef struct TrueMotion1Context { - AVCodecContext *avctx; - AVFrame frame; - - const uint8_t *buf; - int size; - - const uint8_t *mb_change_bits; - int mb_change_bits_row_size; - const uint8_t *index_stream; - int index_stream_size; - - int flags; - int x, y, w, h; - - uint32_t y_predictor_table[1024]; - uint32_t c_predictor_table[1024]; - uint32_t fat_y_predictor_table[1024]; - uint32_t fat_c_predictor_table[1024]; - - int compression; - int block_type; - int block_width; - int block_height; - - int16_t ydt[8]; - int16_t cdt[8]; - int16_t fat_ydt[8]; - int16_t fat_cdt[8]; - - int last_deltaset, last_vectable; - - unsigned int *vert_pred; - -} TrueMotion1Context; - -#define FLAG_SPRITE 32 -#define FLAG_KEYFRAME 16 -#define FLAG_INTERFRAME 8 -#define FLAG_INTERPOLATED 4 - -struct frame_header { - uint8_t header_size; - uint8_t compression; - uint8_t deltaset; - uint8_t vectable; - uint16_t ysize; - uint16_t xsize; - uint16_t checksum; - uint8_t version; - uint8_t header_type; - uint8_t flags; - uint8_t control; - uint16_t xoffset; - uint16_t yoffset; - uint16_t width; - uint16_t height; -}; - -#define ALGO_NOP 0 -#define ALGO_RGB16V 1 -#define ALGO_RGB16H 2 -#define ALGO_RGB24H 3 - -/* these are the various block sizes that can occupy a 4x4 block */ -#define BLOCK_2x2 0 -#define BLOCK_2x4 1 -#define BLOCK_4x2 2 -#define BLOCK_4x4 3 - -typedef struct comp_types { - int algorithm; - int block_width; // vres - int block_height; // hres - int block_type; -} comp_types; - -/* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */ -static const comp_types compression_types[17] = { - { ALGO_NOP, 0, 0, 0 }, - - { ALGO_RGB16V, 4, 4, BLOCK_4x4 }, - { ALGO_RGB16H, 4, 4, BLOCK_4x4 }, - { ALGO_RGB16V, 4, 2, BLOCK_4x2 }, - { ALGO_RGB16H, 4, 2, BLOCK_4x2 }, - - { ALGO_RGB16V, 2, 4, BLOCK_2x4 }, - { ALGO_RGB16H, 2, 4, BLOCK_2x4 }, - { ALGO_RGB16V, 2, 2, BLOCK_2x2 }, - { ALGO_RGB16H, 2, 2, BLOCK_2x2 }, - - { ALGO_NOP, 4, 4, BLOCK_4x4 }, - { ALGO_RGB24H, 4, 4, BLOCK_4x4 }, - { ALGO_NOP, 4, 2, BLOCK_4x2 }, - { ALGO_RGB24H, 4, 2, BLOCK_4x2 }, - - { ALGO_NOP, 2, 4, BLOCK_2x4 }, - { ALGO_RGB24H, 2, 4, BLOCK_2x4 }, - { ALGO_NOP, 2, 2, BLOCK_2x2 }, - { ALGO_RGB24H, 2, 2, BLOCK_2x2 } -}; - -static void select_delta_tables(TrueMotion1Context *s, int delta_table_index) -{ - int i; - - if (delta_table_index > 3) - return; - - memcpy(s->ydt, ydts[delta_table_index], 8 * sizeof(int16_t)); - memcpy(s->cdt, cdts[delta_table_index], 8 * sizeof(int16_t)); - memcpy(s->fat_ydt, fat_ydts[delta_table_index], 8 * sizeof(int16_t)); - memcpy(s->fat_cdt, fat_cdts[delta_table_index], 8 * sizeof(int16_t)); - - /* Y skinny deltas need to be halved for some reason; maybe the - * skinny Y deltas should be modified */ - for (i = 0; i < 8; i++) - { - /* drop the lsb before dividing by 2-- net effect: round down - * when dividing a negative number (e.g., -3/2 = -2, not -1) */ - s->ydt[i] &= 0xFFFE; - s->ydt[i] /= 2; - } -} - -#if HAVE_BIGENDIAN -static int make_ydt15_entry(int p2, int p1, int16_t *ydt) -#else -static int make_ydt15_entry(int p1, int p2, int16_t *ydt) -#endif -{ - int lo, hi; - - lo = ydt[p1]; - lo += (lo << 5) + (lo << 10); - hi = ydt[p2]; - hi += (hi << 5) + (hi << 10); - return (lo + (hi << 16)) << 1; -} - -#if HAVE_BIGENDIAN -static int make_cdt15_entry(int p2, int p1, int16_t *cdt) -#else -static int make_cdt15_entry(int p1, int p2, int16_t *cdt) -#endif -{ - int r, b, lo; - - b = cdt[p2]; - r = cdt[p1] << 10; - lo = b + r; - return (lo + (lo << 16)) << 1; -} - -#if HAVE_BIGENDIAN -static int make_ydt16_entry(int p2, int p1, int16_t *ydt) -#else -static int make_ydt16_entry(int p1, int p2, int16_t *ydt) -#endif -{ - int lo, hi; - - lo = ydt[p1]; - lo += (lo << 6) + (lo << 11); - hi = ydt[p2]; - hi += (hi << 6) + (hi << 11); - return (lo + (hi << 16)) << 1; -} - -#if HAVE_BIGENDIAN -static int make_cdt16_entry(int p2, int p1, int16_t *cdt) -#else -static int make_cdt16_entry(int p1, int p2, int16_t *cdt) -#endif -{ - int r, b, lo; - - b = cdt[p2]; - r = cdt[p1] << 11; - lo = b + r; - return (lo + (lo << 16)) << 1; -} - -#if HAVE_BIGENDIAN -static int make_ydt24_entry(int p2, int p1, int16_t *ydt) -#else -static int make_ydt24_entry(int p1, int p2, int16_t *ydt) -#endif -{ - int lo, hi; - - lo = ydt[p1]; - hi = ydt[p2]; - return (lo + (hi << 8) + (hi << 16)) << 1; -} - -#if HAVE_BIGENDIAN -static int make_cdt24_entry(int p2, int p1, int16_t *cdt) -#else -static int make_cdt24_entry(int p1, int p2, int16_t *cdt) -#endif -{ - int r, b; - - b = cdt[p2]; - r = cdt[p1]<<16; - return (b+r) << 1; -} - -static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table) -{ - int len, i, j; - unsigned char delta_pair; - - for (i = 0; i < 1024; i += 4) - { - len = *sel_vector_table++ / 2; - for (j = 0; j < len; j++) - { - delta_pair = *sel_vector_table++; - s->y_predictor_table[i+j] = 0xfffffffe & - make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); - s->c_predictor_table[i+j] = 0xfffffffe & - make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); - } - s->y_predictor_table[i+(j-1)] |= 1; - s->c_predictor_table[i+(j-1)] |= 1; - } -} - -static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table) -{ - int len, i, j; - unsigned char delta_pair; - - for (i = 0; i < 1024; i += 4) - { - len = *sel_vector_table++ / 2; - for (j = 0; j < len; j++) - { - delta_pair = *sel_vector_table++; - s->y_predictor_table[i+j] = 0xfffffffe & - make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); - s->c_predictor_table[i+j] = 0xfffffffe & - make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); - } - s->y_predictor_table[i+(j-1)] |= 1; - s->c_predictor_table[i+(j-1)] |= 1; - } -} - -static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table) -{ - int len, i, j; - unsigned char delta_pair; - - for (i = 0; i < 1024; i += 4) - { - len = *sel_vector_table++ / 2; - for (j = 0; j < len; j++) - { - delta_pair = *sel_vector_table++; - s->y_predictor_table[i+j] = 0xfffffffe & - make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); - s->c_predictor_table[i+j] = 0xfffffffe & - make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); - s->fat_y_predictor_table[i+j] = 0xfffffffe & - make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt); - s->fat_c_predictor_table[i+j] = 0xfffffffe & - make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt); - } - s->y_predictor_table[i+(j-1)] |= 1; - s->c_predictor_table[i+(j-1)] |= 1; - s->fat_y_predictor_table[i+(j-1)] |= 1; - s->fat_c_predictor_table[i+(j-1)] |= 1; - } -} - -/* Returns the number of bytes consumed from the bytestream. Returns -1 if - * there was an error while decoding the header */ -static int truemotion1_decode_header(TrueMotion1Context *s) -{ - int i; - struct frame_header header; - uint8_t header_buffer[128]; /* logical maximum size of the header */ - const uint8_t *sel_vector_table; - - /* There is 1 change bit per 4 pixels, so each change byte represents - * 32 pixels; divide width by 4 to obtain the number of change bits and - * then round up to the nearest byte. */ - s->mb_change_bits_row_size = ((s->avctx->width >> 2) + 7) >> 3; - - header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f; - if (s->buf[0] < 0x10) - { - av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]); - return -1; - } - - /* unscramble the header bytes with a XOR operation */ - memset(header_buffer, 0, 128); - for (i = 1; i < header.header_size; i++) - header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1]; - - header.compression = header_buffer[0]; - header.deltaset = header_buffer[1]; - header.vectable = header_buffer[2]; - header.ysize = AV_RL16(&header_buffer[3]); - header.xsize = AV_RL16(&header_buffer[5]); - header.checksum = AV_RL16(&header_buffer[7]); - header.version = header_buffer[9]; - header.header_type = header_buffer[10]; - header.flags = header_buffer[11]; - header.control = header_buffer[12]; - - /* Version 2 */ - if (header.version >= 2) - { - if (header.header_type > 3) - { - av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type); - return -1; - } else if ((header.header_type == 2) || (header.header_type == 3)) { - s->flags = header.flags; - if (!(s->flags & FLAG_INTERFRAME)) - s->flags |= FLAG_KEYFRAME; - } else - s->flags = FLAG_KEYFRAME; - } else /* Version 1 */ - s->flags = FLAG_KEYFRAME; - - if (s->flags & FLAG_SPRITE) { - av_log(s->avctx, AV_LOG_INFO, "SPRITE frame found, please report the sample to the developers\n"); - /* FIXME header.width, height, xoffset and yoffset aren't initialized */ -#if 0 - s->w = header.width; - s->h = header.height; - s->x = header.xoffset; - s->y = header.yoffset; -#else - return -1; -#endif - } else { - s->w = header.xsize; - s->h = header.ysize; - if (header.header_type < 2) { - if ((s->w < 213) && (s->h >= 176)) - { - s->flags |= FLAG_INTERPOLATED; - av_log(s->avctx, AV_LOG_INFO, "INTERPOLATION selected, please report the sample to the developers\n"); - } - } - } - - if (header.compression >= 17) { - av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression); - return -1; - } - - if ((header.deltaset != s->last_deltaset) || - (header.vectable != s->last_vectable)) - select_delta_tables(s, header.deltaset); - - if ((header.compression & 1) && header.header_type) - sel_vector_table = pc_tbl2; - else { - if (header.vectable < 4) - sel_vector_table = tables[header.vectable - 1]; - else { - av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable); - return -1; - } - } - - // FIXME: where to place this ?!?! - if (compression_types[header.compression].algorithm == ALGO_RGB24H) - s->avctx->pix_fmt = PIX_FMT_RGB32; - else - s->avctx->pix_fmt = PIX_FMT_RGB555; // RGB565 is supported as well - - if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable)) - { - if (compression_types[header.compression].algorithm == ALGO_RGB24H) - gen_vector_table24(s, sel_vector_table); - else - if (s->avctx->pix_fmt == PIX_FMT_RGB555) - gen_vector_table15(s, sel_vector_table); - else - gen_vector_table16(s, sel_vector_table); - } - - /* set up pointers to the other key data chunks */ - s->mb_change_bits = s->buf + header.header_size; - if (s->flags & FLAG_KEYFRAME) { - /* no change bits specified for a keyframe; only index bytes */ - s->index_stream = s->mb_change_bits; - } else { - /* one change bit per 4x4 block */ - s->index_stream = s->mb_change_bits + - (s->mb_change_bits_row_size * (s->avctx->height >> 2)); - } - s->index_stream_size = s->size - (s->index_stream - s->buf); - - s->last_deltaset = header.deltaset; - s->last_vectable = header.vectable; - s->compression = header.compression; - s->block_width = compression_types[header.compression].block_width; - s->block_height = compression_types[header.compression].block_height; - s->block_type = compression_types[header.compression].block_type; - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n", - s->last_deltaset, s->last_vectable, s->compression, s->block_width, - s->block_height, s->block_type, - s->flags & FLAG_KEYFRAME ? " KEY" : "", - s->flags & FLAG_INTERFRAME ? " INTER" : "", - s->flags & FLAG_SPRITE ? " SPRITE" : "", - s->flags & FLAG_INTERPOLATED ? " INTERPOL" : ""); - - return header.header_size; -} - -static av_cold int truemotion1_decode_init(AVCodecContext *avctx) -{ - TrueMotion1Context *s = avctx->priv_data; - - s->avctx = avctx; - - // FIXME: it may change ? -// if (avctx->bits_per_sample == 24) -// avctx->pix_fmt = PIX_FMT_RGB24; -// else -// avctx->pix_fmt = PIX_FMT_RGB555; - - s->frame.data[0] = NULL; - - /* there is a vertical predictor for each pixel in a line; each vertical - * predictor is 0 to start with */ - s->vert_pred = - (unsigned int *)av_malloc(s->avctx->width * sizeof(unsigned int)); - - return 0; -} - -/* -Block decoding order: - -dxi: Y-Y -dxic: Y-C-Y -dxic2: Y-C-Y-C - -hres,vres,i,i%vres (0 < i < 4) -2x2 0: 0 dxic2 -2x2 1: 1 dxi -2x2 2: 0 dxic2 -2x2 3: 1 dxi -2x4 0: 0 dxic2 -2x4 1: 1 dxi -2x4 2: 2 dxi -2x4 3: 3 dxi -4x2 0: 0 dxic -4x2 1: 1 dxi -4x2 2: 0 dxic -4x2 3: 1 dxi -4x4 0: 0 dxic -4x4 1: 1 dxi -4x4 2: 2 dxi -4x4 3: 3 dxi -*/ - -#define GET_NEXT_INDEX() \ -{\ - if (index_stream_index >= s->index_stream_size) { \ - av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \ - return; \ - } \ - index = s->index_stream[index_stream_index++] * 4; \ -} - -#define APPLY_C_PREDICTOR() \ - predictor_pair = s->c_predictor_table[index]; \ - horiz_pred += (predictor_pair >> 1); \ - if (predictor_pair & 1) { \ - GET_NEXT_INDEX() \ - if (!index) { \ - GET_NEXT_INDEX() \ - predictor_pair = s->c_predictor_table[index]; \ - horiz_pred += ((predictor_pair >> 1) * 5); \ - if (predictor_pair & 1) \ - GET_NEXT_INDEX() \ - else \ - index++; \ - } \ - } else \ - index++; - -#define APPLY_C_PREDICTOR_24() \ - predictor_pair = s->c_predictor_table[index]; \ - horiz_pred += (predictor_pair >> 1); \ - if (predictor_pair & 1) { \ - GET_NEXT_INDEX() \ - if (!index) { \ - GET_NEXT_INDEX() \ - predictor_pair = s->fat_c_predictor_table[index]; \ - horiz_pred += (predictor_pair >> 1); \ - if (predictor_pair & 1) \ - GET_NEXT_INDEX() \ - else \ - index++; \ - } \ - } else \ - index++; - - -#define APPLY_Y_PREDICTOR() \ - predictor_pair = s->y_predictor_table[index]; \ - horiz_pred += (predictor_pair >> 1); \ - if (predictor_pair & 1) { \ - GET_NEXT_INDEX() \ - if (!index) { \ - GET_NEXT_INDEX() \ - predictor_pair = s->y_predictor_table[index]; \ - horiz_pred += ((predictor_pair >> 1) * 5); \ - if (predictor_pair & 1) \ - GET_NEXT_INDEX() \ - else \ - index++; \ - } \ - } else \ - index++; - -#define APPLY_Y_PREDICTOR_24() \ - predictor_pair = s->y_predictor_table[index]; \ - horiz_pred += (predictor_pair >> 1); \ - if (predictor_pair & 1) { \ - GET_NEXT_INDEX() \ - if (!index) { \ - GET_NEXT_INDEX() \ - predictor_pair = s->fat_y_predictor_table[index]; \ - horiz_pred += (predictor_pair >> 1); \ - if (predictor_pair & 1) \ - GET_NEXT_INDEX() \ - else \ - index++; \ - } \ - } else \ - index++; - -#define OUTPUT_PIXEL_PAIR() \ - *current_pixel_pair = *vert_pred + horiz_pred; \ - *vert_pred++ = *current_pixel_pair++; - -static void truemotion1_decode_16bit(TrueMotion1Context *s) -{ - int y; - int pixels_left; /* remaining pixels on this line */ - unsigned int predictor_pair; - unsigned int horiz_pred; - unsigned int *vert_pred; - unsigned int *current_pixel_pair; - unsigned char *current_line = s->frame.data[0]; - int keyframe = s->flags & FLAG_KEYFRAME; - - /* these variables are for managing the stream of macroblock change bits */ - const unsigned char *mb_change_bits = s->mb_change_bits; - unsigned char mb_change_byte; - unsigned char mb_change_byte_mask; - int mb_change_index; - - /* these variables are for managing the main index stream */ - int index_stream_index = 0; /* yes, the index into the index stream */ - int index; - - /* clean out the line buffer */ - memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int)); - - GET_NEXT_INDEX(); - - for (y = 0; y < s->avctx->height; y++) { - - /* re-init variables for the next line iteration */ - horiz_pred = 0; - current_pixel_pair = (unsigned int *)current_line; - vert_pred = s->vert_pred; - mb_change_index = 0; - mb_change_byte = mb_change_bits[mb_change_index++]; - mb_change_byte_mask = 0x01; - pixels_left = s->avctx->width; - - while (pixels_left > 0) { - - if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) { - - switch (y & 3) { - case 0: - /* if macroblock width is 2, apply C-Y-C-Y; else - * apply C-Y-Y */ - if (s->block_width == 2) { - APPLY_C_PREDICTOR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - APPLY_C_PREDICTOR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - } else { - APPLY_C_PREDICTOR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - } - break; - - case 1: - case 3: - /* always apply 2 Y predictors on these iterations */ - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - break; - - case 2: - /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y - * depending on the macroblock type */ - if (s->block_type == BLOCK_2x2) { - APPLY_C_PREDICTOR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - APPLY_C_PREDICTOR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - } else if (s->block_type == BLOCK_4x2) { - APPLY_C_PREDICTOR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - } else { - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR(); - OUTPUT_PIXEL_PAIR(); - } - break; - } - - } else { - - /* skip (copy) four pixels, but reassign the horizontal - * predictor */ - *vert_pred++ = *current_pixel_pair++; - horiz_pred = *current_pixel_pair - *vert_pred; - *vert_pred++ = *current_pixel_pair++; - - } - - if (!keyframe) { - mb_change_byte_mask <<= 1; - - /* next byte */ - if (!mb_change_byte_mask) { - mb_change_byte = mb_change_bits[mb_change_index++]; - mb_change_byte_mask = 0x01; - } - } - - pixels_left -= 4; - } - - /* next change row */ - if (((y + 1) & 3) == 0) - mb_change_bits += s->mb_change_bits_row_size; - - current_line += s->frame.linesize[0]; - } -} - -static void truemotion1_decode_24bit(TrueMotion1Context *s) -{ - int y; - int pixels_left; /* remaining pixels on this line */ - unsigned int predictor_pair; - unsigned int horiz_pred; - unsigned int *vert_pred; - unsigned int *current_pixel_pair; - unsigned char *current_line = s->frame.data[0]; - int keyframe = s->flags & FLAG_KEYFRAME; - - /* these variables are for managing the stream of macroblock change bits */ - const unsigned char *mb_change_bits = s->mb_change_bits; - unsigned char mb_change_byte; - unsigned char mb_change_byte_mask; - int mb_change_index; - - /* these variables are for managing the main index stream */ - int index_stream_index = 0; /* yes, the index into the index stream */ - int index; - - /* clean out the line buffer */ - memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int)); - - GET_NEXT_INDEX(); - - for (y = 0; y < s->avctx->height; y++) { - - /* re-init variables for the next line iteration */ - horiz_pred = 0; - current_pixel_pair = (unsigned int *)current_line; - vert_pred = s->vert_pred; - mb_change_index = 0; - mb_change_byte = mb_change_bits[mb_change_index++]; - mb_change_byte_mask = 0x01; - pixels_left = s->avctx->width; - - while (pixels_left > 0) { - - if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) { - - switch (y & 3) { - case 0: - /* if macroblock width is 2, apply C-Y-C-Y; else - * apply C-Y-Y */ - if (s->block_width == 2) { - APPLY_C_PREDICTOR_24(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - APPLY_C_PREDICTOR_24(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - } else { - APPLY_C_PREDICTOR_24(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - } - break; - - case 1: - case 3: - /* always apply 2 Y predictors on these iterations */ - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - break; - - case 2: - /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y - * depending on the macroblock type */ - if (s->block_type == BLOCK_2x2) { - APPLY_C_PREDICTOR_24(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - APPLY_C_PREDICTOR_24(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - } else if (s->block_type == BLOCK_4x2) { - APPLY_C_PREDICTOR_24(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - } else { - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - APPLY_Y_PREDICTOR_24(); - OUTPUT_PIXEL_PAIR(); - } - break; - } - - } else { - - /* skip (copy) four pixels, but reassign the horizontal - * predictor */ - *vert_pred++ = *current_pixel_pair++; - horiz_pred = *current_pixel_pair - *vert_pred; - *vert_pred++ = *current_pixel_pair++; - - } - - if (!keyframe) { - mb_change_byte_mask <<= 1; - - /* next byte */ - if (!mb_change_byte_mask) { - mb_change_byte = mb_change_bits[mb_change_index++]; - mb_change_byte_mask = 0x01; - } - } - - pixels_left -= 4; - } - - /* next change row */ - if (((y + 1) & 3) == 0) - mb_change_bits += s->mb_change_bits_row_size; - - current_line += s->frame.linesize[0]; - } -} - - -static int truemotion1_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TrueMotion1Context *s = avctx->priv_data; - - s->buf = buf; - s->size = buf_size; - - if (truemotion1_decode_header(s) == -1) - return -1; - - 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(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if (compression_types[s->compression].algorithm == ALGO_RGB24H) { - truemotion1_decode_24bit(s); - } else if (compression_types[s->compression].algorithm != ALGO_NOP) { - truemotion1_decode_16bit(s); - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; - - /* report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int truemotion1_decode_end(AVCodecContext *avctx) -{ - TrueMotion1Context *s = avctx->priv_data; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - av_free(s->vert_pred); - - return 0; -} - -AVCodec truemotion1_decoder = { - "truemotion1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TRUEMOTION1, - sizeof(TrueMotion1Context), - truemotion1_decode_init, - NULL, - truemotion1_decode_end, - truemotion1_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/truemotion1data.h b/tizen/distrib/ffmpeg/libavcodec/truemotion1data.h deleted file mode 100644 index 6a9822a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/truemotion1data.h +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Duck Truemotion v1 Decoding Tables - * - * Data in this file was originally part of VpVision from On2 which is - * distributed under the GNU GPL. It is redistributed with ffmpeg under the - * GNU LGPL using the common understanding that data tables necessary for - * decoding algorithms are not necessarily licensable. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVCODEC_TRUEMOTION1DATA_H -#define AVCODEC_TRUEMOTION1DATA_H - -#include -#include - -/* Y delta tables, skinny and fat */ -static const int16_t ydt1[8] = { 0, -2, 2, -6, 6, -12, 12, -12 }; -static const int16_t ydt2[8] = { 0, -2, 4, -6, 8, -12, 12, -12 }; -static const int16_t ydt3[8] = { 4, -6, 20, -20, 46, -46, 94, -94 }; -static const int16_t fat_ydt3[8] = { 0, -15, 50, -50, 115, -115, 235, -235 }; -static const int16_t ydt4[8] = { 0, -4, 4, -16, 16, -36, 36, -80 }; -/* NOTE: This table breaks the [+,-] pattern that the rest of the - * tables maintain. Is this intentional? */ -static const int16_t fat_ydt4[8] = { 0, 40, 80, -76, 160, -154, 236, -236 }; - -/* C delta tables, skinny and fat */ -static const int16_t cdt1[8] = { 0, -1, 1, -2, 3, -4, 5, -4 }; -static const int16_t cdt2[8] = { 0, -4, 3, -16, 20, -32, 36, -32 }; -static const int16_t fat_cdt2[8] = { 0, -20, 15, -80, 100, -160, 180, -160 }; -static const int16_t cdt3[8] = { 0, -2, 2, -8, 8, -18, 18, -40 }; - -/* all the delta tables to choose from, at all 4 delta levels */ -static const int16_t * const ydts[] = { ydt1, ydt2, ydt3, ydt4, NULL }; -static const int16_t * const fat_ydts[] = { fat_ydt3, fat_ydt3, fat_ydt3, fat_ydt4, NULL }; -static const int16_t * const cdts[] = { cdt1, cdt1, cdt2, cdt3, NULL }; -static const int16_t * const fat_cdts[] = { fat_cdt2, fat_cdt2, fat_cdt2, fat_ydt4, NULL }; - -static const uint8_t pc_tbl2[] = { -0x8,0x00,0x00,0x00,0x00, -0x8,0x00,0x00,0x00,0x00, -0x8,0x10,0x00,0x00,0x00, -0x8,0x01,0x00,0x00,0x00, -0x8,0x00,0x10,0x00,0x00, -0x8,0x00,0x01,0x00,0x00, -0x8,0x00,0x00,0x10,0x00, -0x8,0x00,0x00,0x01,0x00, -0x8,0x00,0x00,0x00,0x10, -0x8,0x00,0x00,0x00,0x01, -0x6,0x00,0x00,0x00, -0x6,0x10,0x00,0x00, -0x6,0x01,0x00,0x00, -0x6,0x00,0x10,0x00, -0x6,0x00,0x01,0x00, -0x6,0x00,0x00,0x01, -0x6,0x00,0x00,0x10, -0x6,0x00,0x00,0x02, -0x6,0x00,0x00,0x20, -0x6,0x20,0x10,0x00, -0x6,0x00,0x02,0x01, -0x6,0x00,0x20,0x10, -0x6,0x02,0x01,0x00, -0x6,0x11,0x00,0x00, -0x6,0x00,0x20,0x00, -0x6,0x00,0x02,0x00, -0x6,0x20,0x00,0x00, -0x6,0x01,0x10,0x00, -0x6,0x02,0x00,0x00, -0x6,0x01,0x00,0x02, -0x6,0x10,0x00,0x20, -0x6,0x00,0x01,0x02, -0x6,0x10,0x01,0x00, -0x6,0x00,0x10,0x20, -0x6,0x10,0x10,0x00, -0x6,0x10,0x00,0x01, -0x6,0x20,0x00,0x10, -0x6,0x02,0x00,0x01, -0x6,0x01,0x01,0x00, -0x6,0x01,0x00,0x10, -0x6,0x00,0x11,0x00, -0x6,0x10,0x00,0x02, -0x6,0x00,0x01,0x10, -0x6,0x00,0x00,0x11, -0x6,0x10,0x00,0x10, -0x6,0x01,0x00,0x01, -0x6,0x00,0x00,0x22, -0x6,0x02,0x01,0x01, -0x6,0x10,0x20,0x10, -0x6,0x01,0x02,0x01, -0x6,0x20,0x10,0x10, -0x6,0x01,0x00,0x20, -0x6,0x00,0x10,0x01, -0x6,0x21,0x10,0x00, -0x6,0x10,0x02,0x01, -0x6,0x12,0x01,0x00, -0x6,0x01,0x20,0x10, -0x6,0x01,0x02,0x00, -0x6,0x10,0x20,0x00, -0x6,0x00,0x10,0x02, -0x6,0x00,0x01,0x20, -0x6,0x00,0x02,0x21, -0x6,0x00,0x02,0x20, -0x6,0x00,0x00,0x12, -0x6,0x00,0x00,0x21, -0x6,0x20,0x11,0x00, -0x6,0x00,0x01,0x01, -0x6,0x11,0x10,0x00, -0x6,0x00,0x20,0x12, -0x6,0x00,0x20,0x11, -0x6,0x20,0x10,0x02, -0x6,0x02,0x01,0x20, -0x6,0x00,0x22,0x11, -0x6,0x00,0x10,0x10, -0x6,0x02,0x11,0x00, -0x6,0x00,0x21,0x10, -0x6,0x00,0x02,0x03, -0x6,0x20,0x10,0x01, -0x6,0x00,0x12,0x01, -0x4,0x11,0x00, -0x4,0x00,0x22, -0x4,0x20,0x00, -0x4,0x01,0x10, -0x4,0x02,0x20, -0x4,0x00,0x20, -0x4,0x02,0x00, -0x4,0x10,0x01, -0x4,0x00,0x11, -0x4,0x02,0x01, -0x4,0x02,0x21, -0x4,0x00,0x02, -0x4,0x20,0x02, -0x4,0x01,0x01, -0x4,0x10,0x10, -0x4,0x10,0x02, -0x4,0x22,0x00, -0x4,0x10,0x00, -0x4,0x01,0x00, -0x4,0x21,0x00, -0x4,0x12,0x00, -0x4,0x00,0x10, -0x4,0x20,0x12, -0x4,0x01,0x11, -0x4,0x00,0x01, -0x4,0x01,0x02, -0x4,0x11,0x02, -0x4,0x11,0x01, -0x4,0x10,0x20, -0x4,0x20,0x01, -0x4,0x22,0x11, -0x4,0x00,0x12, -0x4,0x20,0x10, -0x4,0x22,0x01, -0x4,0x01,0x20, -0x4,0x00,0x21, -0x4,0x10,0x11, -0x4,0x21,0x10, -0x4,0x10,0x22, -0x4,0x02,0x03, -0x4,0x12,0x01, -0x4,0x20,0x11, -0x4,0x11,0x10, -0x4,0x20,0x30, -0x4,0x11,0x20, -0x4,0x02,0x10, -0x4,0x22,0x10, -0x4,0x11,0x11, -0x4,0x30,0x20, -0x4,0x30,0x00, -0x4,0x01,0x22, -0x4,0x01,0x12, -0x4,0x02,0x11, -0x4,0x03,0x02, -0x4,0x03,0x00, -0x4,0x10,0x21, -0x4,0x12,0x20, -0x4,0x00,0x00, -0x4,0x12,0x21, -0x4,0x21,0x11, -0x4,0x02,0x22, -0x4,0x10,0x12, -0x4,0x31,0x00, -0x4,0x20,0x20, -0x4,0x00,0x03, -0x4,0x02,0x02, -0x4,0x22,0x20, -0x4,0x01,0x21, -0x4,0x21,0x02, -0x4,0x21,0x12, -0x4,0x11,0x22, -0x4,0x00,0x30, -0x4,0x12,0x11, -0x4,0x20,0x22, -0x4,0x31,0x20, -0x4,0x21,0x30, -0x4,0x22,0x02, -0x4,0x22,0x22, -0x4,0x20,0x31, -0x4,0x13,0x02, -0x4,0x03,0x10, -0x4,0x11,0x12, -0x4,0x00,0x13, -0x4,0x21,0x01, -0x4,0x12,0x03, -0x4,0x13,0x00, -0x4,0x13,0x10, -0x4,0x02,0x13, -0x4,0x30,0x01, -0x4,0x12,0x10, -0x4,0x22,0x13, -0x4,0x03,0x12, -0x4,0x31,0x01, -0x4,0x30,0x22, -0x4,0x00,0x31, -0x4,0x01,0x31, -0x4,0x02,0x23, -0x4,0x01,0x30, -0x4,0x11,0x21, -0x4,0x22,0x21, -0x4,0x01,0x13, -0x4,0x10,0x03, -0x4,0x22,0x03, -0x4,0x30,0x21, -0x4,0x21,0x31, -0x4,0x33,0x00, -0x4,0x13,0x12, -0x4,0x11,0x31, -0x4,0x30,0x02, -0x4,0x12,0x02, -0x4,0x11,0x13, -0x4,0x12,0x22, -0x4,0x20,0x32, -0x4,0x10,0x13, -0x4,0x22,0x31, -0x4,0x21,0x20, -0x4,0x01,0x33, -0x4,0x33,0x10, -0x4,0x20,0x13, -0x4,0x31,0x22, -0x4,0x13,0x30, -0x4,0x01,0x03, -0x4,0x11,0x33, -0x4,0x20,0x21, -0x4,0x13,0x31, -0x4,0x03,0x22, -0x4,0x31,0x02, -0x4,0x00,0x24, -0x2,0x00, -0x2,0x10, -0x2,0x20, -0x2,0x30, -0x2,0x40, -0x2,0x50, -0x2,0x60, -0x2,0x01, -0x2,0x11, -0x2,0x21, -0x2,0x31, -0x2,0x41, -0x2,0x51, -0x2,0x61, -0x2,0x02, -0x2,0x12, -0x2,0x22, -0x2,0x32, -0x2,0x42, -0x2,0x52, -0x2,0x62, -0x2,0x03, -0x2,0x13, -0x2,0x23, -0x2,0x33, -0x2,0x43, -0x2,0x53, -0x2,0x63, -0x2,0x04, -0x2,0x14, -0x2,0x24, -0x2,0x34, -0x2,0x44, -0x2,0x54, -0x2,0x64, -0x2,0x05, -0x2,0x15, -0x2,0x25, -0x2,0x35, -0x2,0x45, -0x2,0x55, -0x2,0x65, -0x2,0x06, -0x2,0x16, -0x2,0x26, -0x2,0x36, -0x2,0x46, -0x2,0x56, -0x2,0x66 -}; - -static const uint8_t pc_tbl3[] = { -0x6,0x00,0x00,0x00, -0x6,0x00,0x00,0x00, -0x6,0x00,0x00,0x01, -0x6,0x00,0x00,0x10, -0x6,0x00,0x00,0x11, -0x6,0x00,0x01,0x00, -0x6,0x00,0x01,0x01, -0x6,0x00,0x01,0x10, -0x6,0x00,0x01,0x11, -0x6,0x00,0x10,0x00, -0x6,0x00,0x10,0x01, -0x6,0x00,0x10,0x10, -0x6,0x00,0x10,0x11, -0x6,0x00,0x11,0x00, -0x6,0x00,0x11,0x01, -0x6,0x00,0x11,0x10, -0x6,0x00,0x11,0x11, -0x6,0x01,0x00,0x00, -0x6,0x01,0x00,0x01, -0x6,0x01,0x00,0x10, -0x6,0x01,0x00,0x11, -0x6,0x01,0x01,0x00, -0x6,0x01,0x01,0x01, -0x6,0x01,0x01,0x10, -0x6,0x01,0x01,0x11, -0x6,0x01,0x10,0x00, -0x6,0x01,0x10,0x01, -0x6,0x01,0x10,0x10, -0x6,0x01,0x10,0x11, -0x6,0x01,0x11,0x00, -0x6,0x01,0x11,0x01, -0x6,0x01,0x11,0x10, -0x6,0x01,0x11,0x11, -0x6,0x10,0x00,0x00, -0x6,0x10,0x00,0x01, -0x6,0x10,0x00,0x10, -0x6,0x10,0x00,0x11, -0x6,0x10,0x01,0x00, -0x6,0x10,0x01,0x01, -0x6,0x10,0x01,0x10, -0x6,0x10,0x01,0x11, -0x6,0x10,0x10,0x00, -0x6,0x10,0x10,0x01, -0x6,0x10,0x10,0x10, -0x6,0x10,0x10,0x11, -0x6,0x10,0x11,0x00, -0x6,0x10,0x11,0x01, -0x6,0x10,0x11,0x10, -0x6,0x10,0x11,0x11, -0x6,0x11,0x00,0x00, -0x6,0x11,0x00,0x01, -0x6,0x11,0x00,0x10, -0x6,0x11,0x00,0x11, -0x6,0x11,0x01,0x00, -0x6,0x11,0x01,0x01, -0x6,0x11,0x01,0x10, -0x6,0x11,0x01,0x11, -0x6,0x11,0x10,0x00, -0x6,0x11,0x10,0x01, -0x6,0x11,0x10,0x10, -0x6,0x11,0x10,0x11, -0x6,0x11,0x11,0x00, -0x6,0x11,0x11,0x01, -0x6,0x11,0x11,0x10, -0x4,0x00,0x00, -0x4,0x00,0x01, -0x4,0x00,0x02, -0x4,0x00,0x03, -0x4,0x00,0x10, -0x4,0x00,0x11, -0x4,0x00,0x12, -0x4,0x00,0x13, -0x4,0x00,0x20, -0x4,0x00,0x21, -0x4,0x00,0x22, -0x4,0x00,0x23, -0x4,0x00,0x30, -0x4,0x00,0x31, -0x4,0x00,0x32, -0x4,0x00,0x33, -0x4,0x01,0x00, -0x4,0x01,0x01, -0x4,0x01,0x02, -0x4,0x01,0x03, -0x4,0x01,0x10, -0x4,0x01,0x11, -0x4,0x01,0x12, -0x4,0x01,0x13, -0x4,0x01,0x20, -0x4,0x01,0x21, -0x4,0x01,0x22, -0x4,0x01,0x23, -0x4,0x01,0x30, -0x4,0x01,0x31, -0x4,0x01,0x32, -0x4,0x01,0x33, -0x4,0x02,0x00, -0x4,0x02,0x01, -0x4,0x02,0x02, -0x4,0x02,0x03, -0x4,0x02,0x10, -0x4,0x02,0x11, -0x4,0x02,0x12, -0x4,0x02,0x13, -0x4,0x02,0x20, -0x4,0x02,0x21, -0x4,0x02,0x22, -0x4,0x02,0x23, -0x4,0x02,0x30, -0x4,0x02,0x31, -0x4,0x02,0x32, -0x4,0x02,0x33, -0x4,0x03,0x00, -0x4,0x03,0x01, -0x4,0x03,0x02, -0x4,0x03,0x03, -0x4,0x03,0x10, -0x4,0x03,0x11, -0x4,0x03,0x12, -0x4,0x03,0x13, -0x4,0x03,0x20, -0x4,0x03,0x21, -0x4,0x03,0x22, -0x4,0x03,0x23, -0x4,0x03,0x30, -0x4,0x03,0x31, -0x4,0x03,0x32, -0x4,0x03,0x33, -0x4,0x10,0x00, -0x4,0x10,0x01, -0x4,0x10,0x02, -0x4,0x10,0x03, -0x4,0x10,0x10, -0x4,0x10,0x11, -0x4,0x10,0x12, -0x4,0x10,0x13, -0x4,0x10,0x20, -0x4,0x10,0x21, -0x4,0x10,0x22, -0x4,0x10,0x23, -0x4,0x10,0x30, -0x4,0x10,0x31, -0x4,0x10,0x32, -0x4,0x10,0x33, -0x4,0x11,0x00, -0x4,0x11,0x01, -0x4,0x11,0x02, -0x4,0x11,0x03, -0x4,0x11,0x10, -0x4,0x11,0x11, -0x4,0x11,0x12, -0x4,0x11,0x13, -0x4,0x11,0x20, -0x4,0x11,0x21, -0x4,0x11,0x22, -0x4,0x11,0x23, -0x4,0x11,0x30, -0x4,0x11,0x31, -0x4,0x11,0x32, -0x4,0x11,0x33, -0x4,0x12,0x00, -0x4,0x12,0x01, -0x4,0x12,0x02, -0x4,0x12,0x03, -0x4,0x12,0x10, -0x4,0x12,0x11, -0x4,0x12,0x12, -0x4,0x12,0x13, -0x4,0x12,0x20, -0x4,0x12,0x21, -0x4,0x12,0x22, -0x4,0x12,0x23, -0x4,0x12,0x30, -0x4,0x12,0x31, -0x4,0x12,0x32, -0x4,0x12,0x33, -0x4,0x13,0x00, -0x4,0x13,0x01, -0x4,0x13,0x02, -0x4,0x13,0x03, -0x4,0x13,0x10, -0x4,0x13,0x11, -0x4,0x13,0x12, -0x4,0x13,0x13, -0x4,0x13,0x20, -0x4,0x13,0x21, -0x4,0x13,0x22, -0x4,0x13,0x23, -0x4,0x13,0x30, -0x4,0x13,0x31, -0x4,0x13,0x32, -0x4,0x13,0x33, -0x2,0x00, -0x2,0x10, -0x2,0x20, -0x2,0x30, -0x2,0x40, -0x2,0x50, -0x2,0x60, -0x2,0x70, -0x2,0x01, -0x2,0x11, -0x2,0x21, -0x2,0x31, -0x2,0x41, -0x2,0x51, -0x2,0x61, -0x2,0x71, -0x2,0x02, -0x2,0x12, -0x2,0x22, -0x2,0x32, -0x2,0x42, -0x2,0x52, -0x2,0x62, -0x2,0x72, -0x2,0x03, -0x2,0x13, -0x2,0x23, -0x2,0x33, -0x2,0x43, -0x2,0x53, -0x2,0x63, -0x2,0x73, -0x2,0x04, -0x2,0x14, -0x2,0x24, -0x2,0x34, -0x2,0x44, -0x2,0x54, -0x2,0x64, -0x2,0x74, -0x2,0x05, -0x2,0x15, -0x2,0x25, -0x2,0x35, -0x2,0x45, -0x2,0x55, -0x2,0x65, -0x2,0x75, -0x2,0x06, -0x2,0x16, -0x2,0x26, -0x2,0x36, -0x2,0x46, -0x2,0x56, -0x2,0x66, -0x2,0x76, -0x2,0x07, -0x2,0x17, -0x2,0x27, -0x2,0x37, -0x2,0x47, -0x2,0x57, -0x2,0x67, -0x2,0x77 -}; - -static const uint8_t pc_tbl4[] = { -0x8,0x00,0x00,0x00,0x00, -0x8,0x00,0x00,0x00,0x00, -0x8,0x20,0x00,0x00,0x00, -0x8,0x00,0x00,0x00,0x01, -0x8,0x10,0x00,0x00,0x00, -0x8,0x00,0x00,0x00,0x02, -0x8,0x01,0x00,0x00,0x00, -0x8,0x00,0x00,0x00,0x10, -0x8,0x02,0x00,0x00,0x00, -0x6,0x00,0x00,0x00, -0x6,0x20,0x00,0x00, -0x6,0x00,0x00,0x01, -0x6,0x10,0x00,0x00, -0x6,0x00,0x00,0x02, -0x6,0x00,0x10,0x00, -0x6,0x00,0x20,0x00, -0x6,0x00,0x02,0x00, -0x6,0x00,0x01,0x00, -0x6,0x01,0x00,0x00, -0x6,0x00,0x00,0x20, -0x6,0x02,0x00,0x00, -0x6,0x00,0x00,0x10, -0x6,0x10,0x00,0x20, -0x6,0x01,0x00,0x02, -0x6,0x20,0x00,0x10, -0x6,0x02,0x00,0x01, -0x6,0x20,0x10,0x00, -0x6,0x00,0x12,0x00, -0x6,0x00,0x02,0x01, -0x6,0x02,0x01,0x00, -0x6,0x00,0x21,0x00, -0x6,0x00,0x01,0x02, -0x6,0x00,0x20,0x10, -0x6,0x00,0x00,0x21, -0x6,0x00,0x00,0x12, -0x6,0x00,0x01,0x20, -0x6,0x12,0x00,0x00, -0x6,0x00,0x10,0x20, -0x6,0x01,0x20,0x00, -0x6,0x02,0x10,0x00, -0x6,0x10,0x20,0x00, -0x6,0x01,0x02,0x00, -0x6,0x21,0x00,0x00, -0x6,0x00,0x02,0x10, -0x6,0x20,0x01,0x00, -0x6,0x00,0x22,0x00, -0x6,0x10,0x02,0x00, -0x6,0x00,0x10,0x02, -0x6,0x11,0x00,0x00, -0x6,0x00,0x11,0x00, -0x6,0x22,0x00,0x00, -0x6,0x20,0x00,0x02, -0x6,0x10,0x00,0x01, -0x6,0x00,0x20,0x01, -0x6,0x02,0x20,0x00, -0x6,0x01,0x10,0x00, -0x6,0x01,0x00,0x20, -0x6,0x00,0x20,0x02, -0x6,0x01,0x20,0x02, -0x6,0x10,0x01,0x00, -0x6,0x02,0x00,0x10, -0x6,0x00,0x10,0x01, -0x6,0x10,0x01,0x20, -0x6,0x20,0x02,0x10, -0x6,0x00,0x00,0x22, -0x6,0x10,0x00,0x02, -0x6,0x00,0x02,0x20, -0x6,0x20,0x02,0x00, -0x6,0x00,0x00,0x11, -0x6,0x02,0x10,0x01, -0x6,0x00,0x01,0x10, -0x6,0x00,0x02,0x11, -0x4,0x01,0x02, -0x4,0x02,0x01, -0x4,0x01,0x00, -0x4,0x10,0x20, -0x4,0x20,0x10, -0x4,0x20,0x00, -0x4,0x11,0x00, -0x4,0x02,0x00, -0x4,0x12,0x00, -0x4,0x00,0x21, -0x4,0x22,0x00, -0x4,0x00,0x12, -0x4,0x21,0x00, -0x4,0x02,0x11, -0x4,0x00,0x01, -0x4,0x10,0x02, -0x4,0x02,0x20, -0x4,0x20,0x11, -0x4,0x01,0x10, -0x4,0x21,0x10, -0x4,0x10,0x00, -0x4,0x10,0x22, -0x4,0x20,0x20, -0x4,0x00,0x22, -0x4,0x01,0x22, -0x4,0x20,0x01, -0x4,0x02,0x02, -0x4,0x00,0x20, -0x4,0x00,0x10, -0x4,0x00,0x11, -0x4,0x22,0x01, -0x4,0x11,0x20, -0x4,0x12,0x01, -0x4,0x12,0x20, -0x4,0x11,0x02, -0x4,0x10,0x10, -0x4,0x01,0x01, -0x4,0x02,0x21, -0x4,0x20,0x12, -0x4,0x01,0x12, -0x4,0x22,0x11, -0x4,0x21,0x12, -0x4,0x22,0x10, -0x4,0x21,0x02, -0x4,0x20,0x02, -0x4,0x10,0x01, -0x4,0x00,0x02, -0x4,0x10,0x21, -0x4,0x01,0x20, -0x4,0x11,0x22, -0x4,0x12,0x21, -0x4,0x22,0x20, -0x4,0x02,0x10, -0x4,0x02,0x22, -0x4,0x11,0x10, -0x4,0x22,0x02, -0x4,0x20,0x21, -0x4,0x01,0x11, -0x4,0x11,0x01, -0x4,0x10,0x12, -0x4,0x02,0x12, -0x4,0x20,0x22, -0x4,0x21,0x20, -0x4,0x01,0x21, -0x4,0x12,0x02, -0x4,0x21,0x11, -0x4,0x12,0x22, -0x4,0x12,0x10, -0x4,0x22,0x21, -0x4,0x10,0x11, -0x4,0x21,0x01, -0x4,0x11,0x12, -0x4,0x12,0x11, -0x4,0x66,0x66, -0x4,0x22,0x22, -0x4,0x11,0x21, -0x4,0x11,0x11, -0x4,0x21,0x22, -0x4,0x00,0x00, -0x4,0x22,0x12, -0x4,0x12,0x12, -0x4,0x21,0x21, -0x4,0x42,0x00, -0x4,0x00,0x04, -0x4,0x40,0x00, -0x4,0x30,0x00, -0x4,0x31,0x00, -0x4,0x00,0x03, -0x4,0x00,0x14, -0x4,0x00,0x13, -0x4,0x01,0x24, -0x4,0x20,0x13, -0x4,0x01,0x42, -0x4,0x14,0x20, -0x4,0x42,0x02, -0x4,0x13,0x00, -0x4,0x00,0x24, -0x4,0x31,0x20, -0x4,0x22,0x13, -0x4,0x11,0x24, -0x4,0x12,0x66, -0x4,0x30,0x01, -0x4,0x02,0x13, -0x4,0x12,0x42, -0x4,0x40,0x10, -0x4,0x40,0x02, -0x4,0x01,0x04, -0x4,0x24,0x00, -0x4,0x42,0x10, -0x4,0x21,0x13, -0x4,0x13,0x12, -0x4,0x31,0x21, -0x4,0x21,0x24, -0x4,0x00,0x40, -0x4,0x10,0x24, -0x4,0x10,0x42, -0x4,0x32,0x01, -0x4,0x11,0x42, -0x4,0x20,0x31, -0x4,0x12,0x40, -0x2,0x00, -0x2,0x10, -0x2,0x20, -0x2,0x30, -0x2,0x40, -0x2,0x50, -0x2,0x60, -0x2,0x70, -0x2,0x01, -0x2,0x11, -0x2,0x21, -0x2,0x31, -0x2,0x41, -0x2,0x51, -0x2,0x61, -0x2,0x71, -0x2,0x02, -0x2,0x12, -0x2,0x22, -0x2,0x32, -0x2,0x42, -0x2,0x52, -0x2,0x62, -0x2,0x72, -0x2,0x03, -0x2,0x13, -0x2,0x23, -0x2,0x33, -0x2,0x43, -0x2,0x53, -0x2,0x63, -0x2,0x73, -0x2,0x04, -0x2,0x14, -0x2,0x24, -0x2,0x34, -0x2,0x44, -0x2,0x54, -0x2,0x64, -0x2,0x74, -0x2,0x05, -0x2,0x15, -0x2,0x25, -0x2,0x35, -0x2,0x45, -0x2,0x55, -0x2,0x65, -0x2,0x75, -0x2,0x06, -0x2,0x16, -0x2,0x26, -0x2,0x36, -0x2,0x46, -0x2,0x56, -0x2,0x66, -0x2,0x76, -0x2,0x07, -0x2,0x17, -0x2,0x27, -0x2,0x37, -0x2,0x47, -0x2,0x57, -0x2,0x67, -0x2,0x77 -}; - -static const uint8_t * const tables[] = { pc_tbl2, pc_tbl3, pc_tbl4 }; - -#endif /* AVCODEC_TRUEMOTION1DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/truemotion2.c b/tizen/distrib/ffmpeg/libavcodec/truemotion2.c deleted file mode 100644 index 5013a9e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/truemotion2.c +++ /dev/null @@ -1,884 +0,0 @@ -/* - * Duck/ON2 TrueMotion 2 Decoder - * Copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Duck TrueMotion2 decoder. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" - -#define TM2_ESCAPE 0x80000000 -#define TM2_DELTAS 64 -/* Huffman-coded streams of different types of blocks */ -enum TM2_STREAMS{ TM2_C_HI = 0, TM2_C_LO, TM2_L_HI, TM2_L_LO, - TM2_UPD, TM2_MOT, TM2_TYPE, TM2_NUM_STREAMS}; -/* Block types */ -enum TM2_BLOCKS{ TM2_HI_RES = 0, TM2_MED_RES, TM2_LOW_RES, TM2_NULL_RES, - TM2_UPDATE, TM2_STILL, TM2_MOTION}; - -typedef struct TM2Context{ - AVCodecContext *avctx; - AVFrame pic; - - GetBitContext gb; - DSPContext dsp; - - /* TM2 streams */ - int *tokens[TM2_NUM_STREAMS]; - int tok_lens[TM2_NUM_STREAMS]; - int tok_ptrs[TM2_NUM_STREAMS]; - int deltas[TM2_NUM_STREAMS][TM2_DELTAS]; - /* for blocks decoding */ - int D[4]; - int CD[4]; - int *last; - int *clast; - - /* data for current and previous frame */ - int *Y1, *U1, *V1, *Y2, *U2, *V2; - int cur; -} TM2Context; - -/** -* Huffman codes for each of streams -*/ -typedef struct TM2Codes{ - VLC vlc; ///< table for FFmpeg bitstream reader - int bits; - int *recode; ///< table for converting from code indexes to values - int length; -} TM2Codes; - -/** -* structure for gathering Huffman codes information -*/ -typedef struct TM2Huff{ - int val_bits; ///< length of literal - int max_bits; ///< maximum length of code - int min_bits; ///< minimum length of code - int nodes; ///< total number of nodes in tree - int num; ///< current number filled - int max_num; ///< total number of codes - int *nums; ///< literals - uint32_t *bits; ///< codes - int *lens; ///< codelengths -} TM2Huff; - -static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff) -{ - if(length > huff->max_bits) { - av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n", huff->max_bits); - return -1; - } - - if(!get_bits1(&ctx->gb)) { /* literal */ - if (length == 0) { - length = 1; - } - if(huff->num >= huff->max_num) { - av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n"); - return -1; - } - huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits); - huff->bits[huff->num] = prefix; - huff->lens[huff->num] = length; - huff->num++; - return 0; - } else { /* non-terminal node */ - if(tm2_read_tree(ctx, prefix << 1, length + 1, huff) == -1) - return -1; - if(tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff) == -1) - return -1; - } - return 0; -} - -static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) -{ - TM2Huff huff; - int res = 0; - - huff.val_bits = get_bits(&ctx->gb, 5); - huff.max_bits = get_bits(&ctx->gb, 5); - huff.min_bits = get_bits(&ctx->gb, 5); - huff.nodes = get_bits_long(&ctx->gb, 17); - huff.num = 0; - - /* check for correct codes parameters */ - if((huff.val_bits < 1) || (huff.val_bits > 32) || - (huff.max_bits < 0) || (huff.max_bits > 32)) { - av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal length: %i, max code length: %i\n", - huff.val_bits, huff.max_bits); - return -1; - } - if((huff.nodes < 0) || (huff.nodes > 0x10000)) { - av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes); - return -1; - } - /* one-node tree */ - if(huff.max_bits == 0) - huff.max_bits = 1; - - /* allocate space for codes - it is exactly ceil(nodes / 2) entries */ - huff.max_num = (huff.nodes + 1) >> 1; - huff.nums = av_mallocz(huff.max_num * sizeof(int)); - huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t)); - huff.lens = av_mallocz(huff.max_num * sizeof(int)); - - if(tm2_read_tree(ctx, 0, 0, &huff) == -1) - res = -1; - - if(huff.num != huff.max_num) { - av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n", - huff.num, huff.max_num); - res = -1; - } - - /* convert codes to vlc_table */ - if(res != -1) { - int i; - - res = init_vlc(&code->vlc, huff.max_bits, huff.max_num, - huff.lens, sizeof(int), sizeof(int), - huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0); - if(res < 0) { - av_log(ctx->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); - res = -1; - } else - res = 0; - if(res != -1) { - code->bits = huff.max_bits; - code->length = huff.max_num; - code->recode = av_malloc(code->length * sizeof(int)); - for(i = 0; i < code->length; i++) - code->recode[i] = huff.nums[i]; - } - } - /* free allocated memory */ - av_free(huff.nums); - av_free(huff.bits); - av_free(huff.lens); - - return res; -} - -static void tm2_free_codes(TM2Codes *code) -{ - if(code->recode) - av_free(code->recode); - if(code->vlc.table) - free_vlc(&code->vlc); -} - -static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code) -{ - int val; - val = get_vlc2(gb, code->vlc.table, code->bits, 1); - return code->recode[val]; -} - -static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf) -{ - uint32_t magic; - const uint8_t *obuf; - int length; - - obuf = buf; - - magic = AV_RL32(buf); - buf += 4; - - if(magic == 0x00000100) { /* old header */ -/* av_log (ctx->avctx, AV_LOG_ERROR, "TM2 old header: not implemented (yet)\n"); */ - return 40; - } else if(magic == 0x00000101) { /* new header */ - int w, h, size, flags, xr, yr; - - length = AV_RL32(buf); - buf += 4; - - init_get_bits(&ctx->gb, buf, 32 * 8); - size = get_bits_long(&ctx->gb, 31); - h = get_bits(&ctx->gb, 15); - w = get_bits(&ctx->gb, 15); - flags = get_bits_long(&ctx->gb, 31); - yr = get_bits(&ctx->gb, 9); - xr = get_bits(&ctx->gb, 9); - - return 40; - } else { - av_log (ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic); - return -1; - } - - return buf - obuf; -} - -static int tm2_read_deltas(TM2Context *ctx, int stream_id) { - int d, mb; - int i, v; - - d = get_bits(&ctx->gb, 9); - mb = get_bits(&ctx->gb, 5); - - if((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) { - av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb); - return -1; - } - - for(i = 0; i < d; i++) { - v = get_bits_long(&ctx->gb, mb); - if(v & (1 << (mb - 1))) - ctx->deltas[stream_id][i] = v - (1 << mb); - else - ctx->deltas[stream_id][i] = v; - } - for(; i < TM2_DELTAS; i++) - ctx->deltas[stream_id][i] = 0; - - return 0; -} - -static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id) { - int i; - int cur = 0; - int skip = 0; - int len, toks; - TM2Codes codes; - - /* get stream length in dwords */ - len = AV_RB32(buf); buf += 4; cur += 4; - skip = len * 4 + 4; - - if(len == 0) - return 4; - - toks = AV_RB32(buf); buf += 4; cur += 4; - if(toks & 1) { - len = AV_RB32(buf); buf += 4; cur += 4; - if(len == TM2_ESCAPE) { - len = AV_RB32(buf); buf += 4; cur += 4; - } - if(len > 0) { - init_get_bits(&ctx->gb, buf, (skip - cur) * 8); - if(tm2_read_deltas(ctx, stream_id) == -1) - return -1; - buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; - cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; - } - } - /* skip unused fields */ - if(AV_RB32(buf) == TM2_ESCAPE) { - buf += 4; cur += 4; /* some unknown length - could be escaped too */ - } - buf += 4; cur += 4; - buf += 4; cur += 4; /* unused by decoder */ - - init_get_bits(&ctx->gb, buf, (skip - cur) * 8); - if(tm2_build_huff_table(ctx, &codes) == -1) - return -1; - buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; - cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; - - toks >>= 1; - /* check if we have sane number of tokens */ - if((toks < 0) || (toks > 0xFFFFFF)){ - av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); - tm2_free_codes(&codes); - return -1; - } - ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int)); - ctx->tok_lens[stream_id] = toks; - len = AV_RB32(buf); buf += 4; cur += 4; - if(len > 0) { - init_get_bits(&ctx->gb, buf, (skip - cur) * 8); - for(i = 0; i < toks; i++) - ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes); - } else { - for(i = 0; i < toks; i++) - ctx->tokens[stream_id][i] = codes.recode[0]; - } - tm2_free_codes(&codes); - - return skip; -} - -static inline int GET_TOK(TM2Context *ctx,int type) { - if(ctx->tok_ptrs[type] >= ctx->tok_lens[type]) { - av_log(ctx->avctx, AV_LOG_ERROR, "Read token from stream %i out of bounds (%i>=%i)\n", type, ctx->tok_ptrs[type], ctx->tok_lens[type]); - return 0; - } - if(type <= TM2_MOT) - return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]]; - return ctx->tokens[type][ctx->tok_ptrs[type]++]; -} - -/* blocks decoding routines */ - -/* common Y, U, V pointers initialisation */ -#define TM2_INIT_POINTERS() \ - int *last, *clast; \ - int *Y, *U, *V;\ - int Ystride, Ustride, Vstride;\ -\ - Ystride = ctx->avctx->width;\ - Vstride = (ctx->avctx->width + 1) >> 1;\ - Ustride = (ctx->avctx->width + 1) >> 1;\ - Y = (ctx->cur?ctx->Y2:ctx->Y1) + by * 4 * Ystride + bx * 4;\ - V = (ctx->cur?ctx->V2:ctx->V1) + by * 2 * Vstride + bx * 2;\ - U = (ctx->cur?ctx->U2:ctx->U1) + by * 2 * Ustride + bx * 2;\ - last = ctx->last + bx * 4;\ - clast = ctx->clast + bx * 4; - -#define TM2_INIT_POINTERS_2() \ - int *Yo, *Uo, *Vo;\ - int oYstride, oUstride, oVstride;\ -\ - TM2_INIT_POINTERS();\ - oYstride = Ystride;\ - oVstride = Vstride;\ - oUstride = Ustride;\ - Yo = (ctx->cur?ctx->Y1:ctx->Y2) + by * 4 * oYstride + bx * 4;\ - Vo = (ctx->cur?ctx->V1:ctx->V2) + by * 2 * oVstride + bx * 2;\ - Uo = (ctx->cur?ctx->U1:ctx->U2) + by * 2 * oUstride + bx * 2; - -/* recalculate last and delta values for next blocks */ -#define TM2_RECALC_BLOCK(CHR, stride, last, CD) {\ - CD[0] = CHR[1] - last[1];\ - CD[1] = (int)CHR[stride + 1] - (int)CHR[1];\ - last[0] = (int)CHR[stride + 0];\ - last[1] = (int)CHR[stride + 1];} - -/* common operations - add deltas to 4x4 block of luma or 2x2 blocks of chroma */ -static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *deltas, int *last) -{ - int ct, d; - int i, j; - - for(j = 0; j < 4; j++){ - ct = ctx->D[j]; - for(i = 0; i < 4; i++){ - d = deltas[i + j * 4]; - ct += d; - last[i] += ct; - Y[i] = av_clip_uint8(last[i]); - } - Y += stride; - ctx->D[j] = ct; - } -} - -static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas) -{ - int i, j; - for(j = 0; j < 2; j++){ - for(i = 0; i < 2; i++){ - CD[j] += deltas[i + j * 2]; - last[i] += CD[j]; - data[i] = last[i]; - } - data += stride; - } -} - -static inline void tm2_low_chroma(int *data, int stride, int *clast, int *CD, int *deltas, int bx) -{ - int t; - int l; - int prev; - - if(bx > 0) - prev = clast[-3]; - else - prev = 0; - t = (CD[0] + CD[1]) >> 1; - l = (prev - CD[0] - CD[1] + clast[1]) >> 1; - CD[1] = CD[0] + CD[1] - t; - CD[0] = t; - clast[0] = l; - - tm2_high_chroma(data, stride, clast, CD, deltas); -} - -static inline void tm2_hi_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) -{ - int i; - int deltas[16]; - TM2_INIT_POINTERS(); - - /* hi-res chroma */ - for(i = 0; i < 4; i++) { - deltas[i] = GET_TOK(ctx, TM2_C_HI); - deltas[i + 4] = GET_TOK(ctx, TM2_C_HI); - } - tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas); - tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4); - - /* hi-res luma */ - for(i = 0; i < 16; i++) - deltas[i] = GET_TOK(ctx, TM2_L_HI); - - tm2_apply_deltas(ctx, Y, Ystride, deltas, last); -} - -static inline void tm2_med_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) -{ - int i; - int deltas[16]; - TM2_INIT_POINTERS(); - - /* low-res chroma */ - deltas[0] = GET_TOK(ctx, TM2_C_LO); - deltas[1] = deltas[2] = deltas[3] = 0; - tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx); - - deltas[0] = GET_TOK(ctx, TM2_C_LO); - deltas[1] = deltas[2] = deltas[3] = 0; - tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx); - - /* hi-res luma */ - for(i = 0; i < 16; i++) - deltas[i] = GET_TOK(ctx, TM2_L_HI); - - tm2_apply_deltas(ctx, Y, Ystride, deltas, last); -} - -static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) -{ - int i; - int t1, t2; - int deltas[16]; - TM2_INIT_POINTERS(); - - /* low-res chroma */ - deltas[0] = GET_TOK(ctx, TM2_C_LO); - deltas[1] = deltas[2] = deltas[3] = 0; - tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx); - - deltas[0] = GET_TOK(ctx, TM2_C_LO); - deltas[1] = deltas[2] = deltas[3] = 0; - tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx); - - /* low-res luma */ - for(i = 0; i < 16; i++) - deltas[i] = 0; - - deltas[ 0] = GET_TOK(ctx, TM2_L_LO); - deltas[ 2] = GET_TOK(ctx, TM2_L_LO); - deltas[ 8] = GET_TOK(ctx, TM2_L_LO); - deltas[10] = GET_TOK(ctx, TM2_L_LO); - - if(bx > 0) - last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1; - else - last[0] = (last[1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1; - last[2] = (last[1] + last[3]) >> 1; - - t1 = ctx->D[0] + ctx->D[1]; - ctx->D[0] = t1 >> 1; - ctx->D[1] = t1 - (t1 >> 1); - t2 = ctx->D[2] + ctx->D[3]; - ctx->D[2] = t2 >> 1; - ctx->D[3] = t2 - (t2 >> 1); - - tm2_apply_deltas(ctx, Y, Ystride, deltas, last); -} - -static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) -{ - int i; - int ct; - int left, right, diff; - int deltas[16]; - TM2_INIT_POINTERS(); - - /* null chroma */ - deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0; - tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx); - - deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0; - tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx); - - /* null luma */ - for(i = 0; i < 16; i++) - deltas[i] = 0; - - ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3]; - - if(bx > 0) - left = last[-1] - ct; - else - left = 0; - - right = last[3]; - diff = right - left; - last[0] = left + (diff >> 2); - last[1] = left + (diff >> 1); - last[2] = right - (diff >> 2); - last[3] = right; - { - int tp = left; - - ctx->D[0] = (tp + (ct >> 2)) - left; - left += ctx->D[0]; - ctx->D[1] = (tp + (ct >> 1)) - left; - left += ctx->D[1]; - ctx->D[2] = ((tp + ct) - (ct >> 2)) - left; - left += ctx->D[2]; - ctx->D[3] = (tp + ct) - left; - } - tm2_apply_deltas(ctx, Y, Ystride, deltas, last); -} - -static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by) -{ - int i, j; - TM2_INIT_POINTERS_2(); - - /* update chroma */ - for(j = 0; j < 2; j++){ - for(i = 0; i < 2; i++){ - U[i] = Uo[i]; - V[i] = Vo[i]; - } - U += Ustride; V += Vstride; - Uo += oUstride; Vo += oVstride; - } - U -= Ustride * 2; - V -= Vstride * 2; - TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD); - TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2)); - - /* update deltas */ - ctx->D[0] = Yo[3] - last[3]; - ctx->D[1] = Yo[3 + oYstride] - Yo[3]; - ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride]; - ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2]; - - for(j = 0; j < 4; j++){ - for(i = 0; i < 4; i++){ - Y[i] = Yo[i]; - last[i] = Yo[i]; - } - Y += Ystride; - Yo += oYstride; - } -} - -static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int by) -{ - int i, j; - int d; - TM2_INIT_POINTERS_2(); - - /* update chroma */ - for(j = 0; j < 2; j++){ - for(i = 0; i < 2; i++){ - U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD); - V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD); - } - U += Ustride; V += Vstride; - Uo += oUstride; Vo += oVstride; - } - U -= Ustride * 2; - V -= Vstride * 2; - TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD); - TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2)); - - /* update deltas */ - ctx->D[0] = Yo[3] - last[3]; - ctx->D[1] = Yo[3 + oYstride] - Yo[3]; - ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride]; - ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2]; - - for(j = 0; j < 4; j++){ - d = last[3]; - for(i = 0; i < 4; i++){ - Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD); - last[i] = Y[i]; - } - ctx->D[j] = last[3] - d; - Y += Ystride; - Yo += oYstride; - } -} - -static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int by) -{ - int i, j; - int mx, my; - TM2_INIT_POINTERS_2(); - - mx = GET_TOK(ctx, TM2_MOT); - my = GET_TOK(ctx, TM2_MOT); - - Yo += my * oYstride + mx; - Uo += (my >> 1) * oUstride + (mx >> 1); - Vo += (my >> 1) * oVstride + (mx >> 1); - - /* copy chroma */ - for(j = 0; j < 2; j++){ - for(i = 0; i < 2; i++){ - U[i] = Uo[i]; - V[i] = Vo[i]; - } - U += Ustride; V += Vstride; - Uo += oUstride; Vo += oVstride; - } - U -= Ustride * 2; - V -= Vstride * 2; - TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD); - TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2)); - - /* copy luma */ - for(j = 0; j < 4; j++){ - for(i = 0; i < 4; i++){ - Y[i] = Yo[i]; - } - Y += Ystride; - Yo += oYstride; - } - /* calculate deltas */ - Y -= Ystride * 4; - ctx->D[0] = Y[3] - last[3]; - ctx->D[1] = Y[3 + Ystride] - Y[3]; - ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride]; - ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2]; - for(i = 0; i < 4; i++) - last[i] = Y[i + Ystride * 3]; -} - -static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p) -{ - int i, j; - int bw, bh; - int type; - int keyframe = 1; - int *Y, *U, *V; - uint8_t *dst; - - bw = ctx->avctx->width >> 2; - bh = ctx->avctx->height >> 2; - - for(i = 0; i < TM2_NUM_STREAMS; i++) - ctx->tok_ptrs[i] = 0; - - if (ctx->tok_lens[TM2_TYPE]avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh); - return -1; - } - - memset(ctx->last, 0, 4 * bw * sizeof(int)); - memset(ctx->clast, 0, 4 * bw * sizeof(int)); - - for(j = 0; j < bh; j++) { - memset(ctx->D, 0, 4 * sizeof(int)); - memset(ctx->CD, 0, 4 * sizeof(int)); - for(i = 0; i < bw; i++) { - type = GET_TOK(ctx, TM2_TYPE); - switch(type) { - case TM2_HI_RES: - tm2_hi_res_block(ctx, p, i, j); - break; - case TM2_MED_RES: - tm2_med_res_block(ctx, p, i, j); - break; - case TM2_LOW_RES: - tm2_low_res_block(ctx, p, i, j); - break; - case TM2_NULL_RES: - tm2_null_res_block(ctx, p, i, j); - break; - case TM2_UPDATE: - tm2_update_block(ctx, p, i, j); - keyframe = 0; - break; - case TM2_STILL: - tm2_still_block(ctx, p, i, j); - keyframe = 0; - break; - case TM2_MOTION: - tm2_motion_block(ctx, p, i, j); - keyframe = 0; - break; - default: - av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\n", type); - } - } - } - - /* copy data from our buffer to AVFrame */ - Y = (ctx->cur?ctx->Y2:ctx->Y1); - U = (ctx->cur?ctx->U2:ctx->U1); - V = (ctx->cur?ctx->V2:ctx->V1); - dst = p->data[0]; - for(j = 0; j < ctx->avctx->height; j++){ - for(i = 0; i < ctx->avctx->width; i++){ - int y = Y[i], u = U[i >> 1], v = V[i >> 1]; - dst[3*i+0] = av_clip_uint8(y + v); - dst[3*i+1] = av_clip_uint8(y); - dst[3*i+2] = av_clip_uint8(y + u); - } - Y += ctx->avctx->width; - if (j & 1) { - U += ctx->avctx->width >> 1; - V += ctx->avctx->width >> 1; - } - dst += p->linesize[0]; - } - - return keyframe; -} - -static const int tm2_stream_order[TM2_NUM_STREAMS] = { - TM2_C_HI, TM2_C_LO, TM2_L_HI, TM2_L_LO, TM2_UPD, TM2_MOT, TM2_TYPE -}; - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TM2Context * const l = avctx->priv_data; - AVFrame * const p= (AVFrame*)&l->pic; - int i, skip, t; - uint8_t *swbuf; - - swbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if(!swbuf){ - av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); - return -1; - } - p->reference = 1; - p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if(avctx->reget_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - av_free(swbuf); - return -1; - } - - l->dsp.bswap_buf((uint32_t*)swbuf, (const uint32_t*)buf, buf_size >> 2); - skip = tm2_read_header(l, swbuf); - - if(skip == -1){ - av_free(swbuf); - return -1; - } - - for(i = 0; i < TM2_NUM_STREAMS; i++){ - t = tm2_read_stream(l, swbuf + skip, tm2_stream_order[i]); - if(t == -1){ - av_free(swbuf); - return -1; - } - skip += t; - } - p->key_frame = tm2_decode_blocks(l, p); - if(p->key_frame) - p->pict_type = FF_I_TYPE; - else - p->pict_type = FF_P_TYPE; - - l->cur = !l->cur; - *data_size = sizeof(AVFrame); - *(AVFrame*)data = l->pic; - av_free(swbuf); - - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - TM2Context * const l = avctx->priv_data; - int i; - - if((avctx->width & 3) || (avctx->height & 3)){ - av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n"); - return -1; - } - - l->avctx = avctx; - l->pic.data[0]=NULL; - avctx->pix_fmt = PIX_FMT_BGR24; - - dsputil_init(&l->dsp, avctx); - - l->last = av_malloc(4 * sizeof(int) * (avctx->width >> 2)); - l->clast = av_malloc(4 * sizeof(int) * (avctx->width >> 2)); - - for(i = 0; i < TM2_NUM_STREAMS; i++) { - l->tokens[i] = NULL; - l->tok_lens[i] = 0; - } - - l->Y1 = av_malloc(sizeof(int) * avctx->width * avctx->height); - l->U1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); - l->V1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); - l->Y2 = av_malloc(sizeof(int) * avctx->width * avctx->height); - l->U2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); - l->V2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); - l->cur = 0; - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - TM2Context * const l = avctx->priv_data; - AVFrame *pic = &l->pic; - int i; - - if(l->last) - av_free(l->last); - if(l->clast) - av_free(l->clast); - for(i = 0; i < TM2_NUM_STREAMS; i++) - if(l->tokens[i]) - av_free(l->tokens[i]); - if(l->Y1){ - av_free(l->Y1); - av_free(l->U1); - av_free(l->V1); - av_free(l->Y2); - av_free(l->U2); - av_free(l->V2); - } - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - -AVCodec truemotion2_decoder = { - "truemotion2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TRUEMOTION2, - sizeof(TM2Context), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/truespeech.c b/tizen/distrib/ffmpeg/libavcodec/truespeech.c deleted file mode 100644 index 37fbef9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/truespeech.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * DSP Group TrueSpeech compatible decoder - * Copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#include "truespeech_data.h" -/** - * @file - * TrueSpeech decoder. - */ - -/** - * TrueSpeech decoder context - */ -typedef struct { - /* input data */ - int16_t vector[8]; //< input vector: 5/5/4/4/4/3/3/3 - int offset1[2]; //< 8-bit value, used in one copying offset - int offset2[4]; //< 7-bit value, encodes offsets for copying and for two-point filter - int pulseoff[4]; //< 4-bit offset of pulse values block - int pulsepos[4]; //< 27-bit variable, encodes 7 pulse positions - int pulseval[4]; //< 7x2-bit pulse values - int flag; //< 1-bit flag, shows how to choose filters - /* temporary data */ - int filtbuf[146]; // some big vector used for storing filters - int prevfilt[8]; // filter from previous frame - int16_t tmp1[8]; // coefficients for adding to out - int16_t tmp2[8]; // coefficients for adding to out - int16_t tmp3[8]; // coefficients for adding to out - int16_t cvector[8]; // correlated input vector - int filtval; // gain value for one function - int16_t newvec[60]; // tmp vector - int16_t filters[32]; // filters for every subframe -} TSContext; - -static av_cold int truespeech_decode_init(AVCodecContext * avctx) -{ -// TSContext *c = avctx->priv_data; - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -static void truespeech_read_frame(TSContext *dec, const uint8_t *input) -{ - uint32_t t; - - /* first dword */ - t = AV_RL32(input); - input += 4; - - dec->flag = t & 1; - - dec->vector[0] = ts_codebook[0][(t >> 1) & 0x1F]; - dec->vector[1] = ts_codebook[1][(t >> 6) & 0x1F]; - dec->vector[2] = ts_codebook[2][(t >> 11) & 0xF]; - dec->vector[3] = ts_codebook[3][(t >> 15) & 0xF]; - dec->vector[4] = ts_codebook[4][(t >> 19) & 0xF]; - dec->vector[5] = ts_codebook[5][(t >> 23) & 0x7]; - dec->vector[6] = ts_codebook[6][(t >> 26) & 0x7]; - dec->vector[7] = ts_codebook[7][(t >> 29) & 0x7]; - - /* second dword */ - t = AV_RL32(input); - input += 4; - - dec->offset2[0] = (t >> 0) & 0x7F; - dec->offset2[1] = (t >> 7) & 0x7F; - dec->offset2[2] = (t >> 14) & 0x7F; - dec->offset2[3] = (t >> 21) & 0x7F; - - dec->offset1[0] = ((t >> 28) & 0xF) << 4; - - /* third dword */ - t = AV_RL32(input); - input += 4; - - dec->pulseval[0] = (t >> 0) & 0x3FFF; - dec->pulseval[1] = (t >> 14) & 0x3FFF; - - dec->offset1[1] = (t >> 28) & 0x0F; - - /* fourth dword */ - t = AV_RL32(input); - input += 4; - - dec->pulseval[2] = (t >> 0) & 0x3FFF; - dec->pulseval[3] = (t >> 14) & 0x3FFF; - - dec->offset1[1] |= ((t >> 28) & 0x0F) << 4; - - /* fifth dword */ - t = AV_RL32(input); - input += 4; - - dec->pulsepos[0] = (t >> 4) & 0x7FFFFFF; - - dec->pulseoff[0] = (t >> 0) & 0xF; - - dec->offset1[0] |= (t >> 31) & 1; - - /* sixth dword */ - t = AV_RL32(input); - input += 4; - - dec->pulsepos[1] = (t >> 4) & 0x7FFFFFF; - - dec->pulseoff[1] = (t >> 0) & 0xF; - - dec->offset1[0] |= ((t >> 31) & 1) << 1; - - /* seventh dword */ - t = AV_RL32(input); - input += 4; - - dec->pulsepos[2] = (t >> 4) & 0x7FFFFFF; - - dec->pulseoff[2] = (t >> 0) & 0xF; - - dec->offset1[0] |= ((t >> 31) & 1) << 2; - - /* eighth dword */ - t = AV_RL32(input); - input += 4; - - dec->pulsepos[3] = (t >> 4) & 0x7FFFFFF; - - dec->pulseoff[3] = (t >> 0) & 0xF; - - dec->offset1[0] |= ((t >> 31) & 1) << 3; - -} - -static void truespeech_correlate_filter(TSContext *dec) -{ - int16_t tmp[8]; - int i, j; - - for(i = 0; i < 8; i++){ - if(i > 0){ - memcpy(tmp, dec->cvector, i * 2); - for(j = 0; j < i; j++) - dec->cvector[j] = ((tmp[i - j - 1] * dec->vector[i]) + - (dec->cvector[j] << 15) + 0x4000) >> 15; - } - dec->cvector[i] = (8 - dec->vector[i]) >> 3; - } - for(i = 0; i < 8; i++) - dec->cvector[i] = (dec->cvector[i] * ts_230[i]) >> 15; - - dec->filtval = dec->vector[0]; -} - -static void truespeech_filters_merge(TSContext *dec) -{ - int i; - - if(!dec->flag){ - for(i = 0; i < 8; i++){ - dec->filters[i + 0] = dec->prevfilt[i]; - dec->filters[i + 8] = dec->prevfilt[i]; - } - }else{ - for(i = 0; i < 8; i++){ - dec->filters[i + 0]=(dec->cvector[i] * 21846 + dec->prevfilt[i] * 10923 + 16384) >> 15; - dec->filters[i + 8]=(dec->cvector[i] * 10923 + dec->prevfilt[i] * 21846 + 16384) >> 15; - } - } - for(i = 0; i < 8; i++){ - dec->filters[i + 16] = dec->cvector[i]; - dec->filters[i + 24] = dec->cvector[i]; - } -} - -static void truespeech_apply_twopoint_filter(TSContext *dec, int quart) -{ - int16_t tmp[146 + 60], *ptr0, *ptr1; - const int16_t *filter; - int i, t, off; - - t = dec->offset2[quart]; - if(t == 127){ - memset(dec->newvec, 0, 60 * 2); - return; - } - for(i = 0; i < 146; i++) - tmp[i] = dec->filtbuf[i]; - off = (t / 25) + dec->offset1[quart >> 1] + 18; - ptr0 = tmp + 145 - off; - ptr1 = tmp + 146; - filter = (const int16_t*)ts_240 + (t % 25) * 2; - for(i = 0; i < 60; i++){ - t = (ptr0[0] * filter[0] + ptr0[1] * filter[1] + 0x2000) >> 14; - ptr0++; - dec->newvec[i] = t; - ptr1[i] = t; - } -} - -static void truespeech_place_pulses(TSContext *dec, int16_t *out, int quart) -{ - int16_t tmp[7]; - int i, j, t; - const int16_t *ptr1; - int16_t *ptr2; - int coef; - - memset(out, 0, 60 * 2); - for(i = 0; i < 7; i++) { - t = dec->pulseval[quart] & 3; - dec->pulseval[quart] >>= 2; - tmp[6 - i] = ts_562[dec->pulseoff[quart] * 4 + t]; - } - - coef = dec->pulsepos[quart] >> 15; - ptr1 = (const int16_t*)ts_140 + 30; - ptr2 = tmp; - for(i = 0, j = 3; (i < 30) && (j > 0); i++){ - t = *ptr1++; - if(coef >= t) - coef -= t; - else{ - out[i] = *ptr2++; - ptr1 += 30; - j--; - } - } - coef = dec->pulsepos[quart] & 0x7FFF; - ptr1 = (const int16_t*)ts_140; - for(i = 30, j = 4; (i < 60) && (j > 0); i++){ - t = *ptr1++; - if(coef >= t) - coef -= t; - else{ - out[i] = *ptr2++; - ptr1 += 30; - j--; - } - } - -} - -static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart) -{ - int i; - - for(i = 0; i < 86; i++) - dec->filtbuf[i] = dec->filtbuf[i + 60]; - for(i = 0; i < 60; i++){ - dec->filtbuf[i + 86] = out[i] + dec->newvec[i] - (dec->newvec[i] >> 3); - out[i] += dec->newvec[i]; - } -} - -static void truespeech_synth(TSContext *dec, int16_t *out, int quart) -{ - int i,k; - int t[8]; - int16_t *ptr0, *ptr1; - - ptr0 = dec->tmp1; - ptr1 = dec->filters + quart * 8; - for(i = 0; i < 60; i++){ - int sum = 0; - for(k = 0; k < 8; k++) - sum += ptr0[k] * ptr1[k]; - sum = (sum + (out[i] << 12) + 0x800) >> 12; - out[i] = av_clip(sum, -0x7FFE, 0x7FFE); - for(k = 7; k > 0; k--) - ptr0[k] = ptr0[k - 1]; - ptr0[0] = out[i]; - } - - for(i = 0; i < 8; i++) - t[i] = (ts_5E2[i] * ptr1[i]) >> 15; - - ptr0 = dec->tmp2; - for(i = 0; i < 60; i++){ - int sum = 0; - for(k = 0; k < 8; k++) - sum += ptr0[k] * t[k]; - for(k = 7; k > 0; k--) - ptr0[k] = ptr0[k - 1]; - ptr0[0] = out[i]; - out[i] = ((out[i] << 12) - sum) >> 12; - } - - for(i = 0; i < 8; i++) - t[i] = (ts_5F2[i] * ptr1[i]) >> 15; - - ptr0 = dec->tmp3; - for(i = 0; i < 60; i++){ - int sum = out[i] << 12; - for(k = 0; k < 8; k++) - sum += ptr0[k] * t[k]; - for(k = 7; k > 0; k--) - ptr0[k] = ptr0[k - 1]; - ptr0[0] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE); - - sum = ((ptr0[1] * (dec->filtval - (dec->filtval >> 2))) >> 4) + sum; - sum = sum - (sum >> 3); - out[i] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE); - } -} - -static void truespeech_save_prevvec(TSContext *c) -{ - int i; - - for(i = 0; i < 8; i++) - c->prevfilt[i] = c->cvector[i]; -} - -static int truespeech_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TSContext *c = avctx->priv_data; - - int i, j; - short *samples = data; - int consumed = 0; - int16_t out_buf[240]; - int iterations; - - if (!buf_size) - return 0; - - iterations = FFMIN(buf_size / 32, *data_size / 480); - for(j = 0; j < iterations; j++) { - truespeech_read_frame(c, buf + consumed); - consumed += 32; - - truespeech_correlate_filter(c); - truespeech_filters_merge(c); - - memset(out_buf, 0, 240 * 2); - for(i = 0; i < 4; i++) { - truespeech_apply_twopoint_filter(c, i); - truespeech_place_pulses(c, out_buf + i * 60, i); - truespeech_update_filters(c, out_buf + i * 60, i); - truespeech_synth(c, out_buf + i * 60, i); - } - - truespeech_save_prevvec(c); - - /* finally output decoded frame */ - for(i = 0; i < 240; i++) - *samples++ = out_buf[i]; - - } - - *data_size = consumed * 15; - - return consumed; -} - -AVCodec truespeech_decoder = { - "truespeech", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_TRUESPEECH, - sizeof(TSContext), - truespeech_decode_init, - NULL, - NULL, - truespeech_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/truespeech_data.h b/tizen/distrib/ffmpeg/libavcodec/truespeech_data.h deleted file mode 100644 index eef7da8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/truespeech_data.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * DSP Group TrueSpeech compatible decoder - * copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_TRUESPEECH_DATA_H -#define AVCODEC_TRUESPEECH_DATA_H - -#include - -/* codebooks fo expanding input filter */ -static const int16_t ts_cb_0[32] = { - 0x8240, 0x8364, 0x84CE, 0x865D, 0x8805, 0x89DE, 0x8BD7, 0x8DF4, - 0x9051, 0x92E2, 0x95DE, 0x990F, 0x9C81, 0xA079, 0xA54C, 0xAAD2, - 0xB18A, 0xB90A, 0xC124, 0xC9CC, 0xD339, 0xDDD3, 0xE9D6, 0xF893, - 0x096F, 0x1ACA, 0x29EC, 0x381F, 0x45F9, 0x546A, 0x63C3, 0x73B5, -}; - -static const int16_t ts_cb_1[32] = { - 0x9F65, 0xB56B, 0xC583, 0xD371, 0xE018, 0xEBB4, 0xF61C, 0xFF59, - 0x085B, 0x1106, 0x1952, 0x214A, 0x28C9, 0x2FF8, 0x36E6, 0x3D92, - 0x43DF, 0x49BB, 0x4F46, 0x5467, 0x5930, 0x5DA3, 0x61EC, 0x65F9, - 0x69D4, 0x6D5A, 0x709E, 0x73AD, 0x766B, 0x78F0, 0x7B5A, 0x7DA5, -}; - -static const int16_t ts_cb_2[16] = { - 0x96F8, 0xA3B4, 0xAF45, 0xBA53, 0xC4B1, 0xCECC, 0xD86F, 0xE21E, - 0xEBF3, 0xF640, 0x00F7, 0x0C20, 0x1881, 0x269A, 0x376B, 0x4D60, -}; - -static const int16_t ts_cb_3[16] = { - 0xC654, 0xDEF2, 0xEFAA, 0xFD94, 0x096A, 0x143F, 0x1E7B, 0x282C, - 0x3176, 0x3A89, 0x439F, 0x4CA2, 0x557F, 0x5E50, 0x6718, 0x6F8D, -}; - -static const int16_t ts_cb_4[16] = { - 0xABE7, 0xBBA8, 0xC81C, 0xD326, 0xDD0E, 0xE5D4, 0xEE22, 0xF618, - 0xFE28, 0x064F, 0x0EB7, 0x17B8, 0x21AA, 0x2D8B, 0x3BA2, 0x4DF9, -}; - -static const int16_t ts_cb_5[8] = { - 0xD51B, 0xF12E, 0x042E, 0x13C7, 0x2260, 0x311B, 0x40DE, 0x5385, -}; - -static const int16_t ts_cb_6[8] = { - 0xB550, 0xC825, 0xD980, 0xE997, 0xF883, 0x0752, 0x1811, 0x2E18, -}; - -static const int16_t ts_cb_7[8] = { - 0xCEF0, 0xE4F9, 0xF6BB, 0x0646, 0x14F5, 0x23FF, 0x356F, 0x4A8D, -}; - -static const int16_t * const ts_codebook[8] = { - ts_cb_0, ts_cb_1, ts_cb_2, ts_cb_3, ts_cb_4, ts_cb_5, ts_cb_6, ts_cb_7 -}; - -/* table used for decoding pulse positions */ -static const int16_t ts_140[120] = { - 0x0E46, 0x0CCC, 0x0B6D, 0x0A28, 0x08FC, 0x07E8, 0x06EB, 0x0604, - 0x0532, 0x0474, 0x03C9, 0x0330, 0x02A8, 0x0230, 0x01C7, 0x016C, - 0x011E, 0x00DC, 0x00A5, 0x0078, 0x0054, 0x0038, 0x0023, 0x0014, - 0x000A, 0x0004, 0x0001, 0x0000, 0x0000, 0x0000, - - 0x0196, 0x017A, 0x015F, 0x0145, 0x012C, 0x0114, 0x00FD, 0x00E7, - 0x00D2, 0x00BE, 0x00AB, 0x0099, 0x0088, 0x0078, 0x0069, 0x005B, - 0x004E, 0x0042, 0x0037, 0x002D, 0x0024, 0x001C, 0x0015, 0x000F, - 0x000A, 0x0006, 0x0003, 0x0001, 0x0000, 0x0000, - - 0x001D, 0x001C, 0x001B, 0x001A, 0x0019, 0x0018, 0x0017, 0x0016, - 0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000F, 0x000E, - 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x0008, 0x0007, 0x0006, - 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0000, - - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 -}; - -/* filter for correlated input filter */ -static const int16_t ts_230[8] = - { 0x7F3B, 0x7E78, 0x7DB6, 0x7CF5, 0x7C35, 0x7B76, 0x7AB8, 0x79FC }; - -/* two-point filters table */ -static const int16_t ts_240[25 * 2] = { - 0xED2F, 0x5239, - 0x54F1, 0xE4A9, - 0x2620, 0xEE3E, - 0x09D6, 0x2C40, - 0xEFB5, 0x2BE0, - - 0x3FE1, 0x3339, - 0x442F, 0xE6FE, - 0x4458, 0xF9DF, - 0xF231, 0x43DB, - 0x3DB0, 0xF705, - - 0x4F7B, 0xFEFB, - 0x26AD, 0x0CDC, - 0x33C2, 0x0739, - 0x12BE, 0x43A2, - 0x1BDF, 0x1F3E, - - 0x0211, 0x0796, - 0x2AEB, 0x163F, - 0x050D, 0x3A38, - 0x0D1E, 0x0D78, - 0x150F, 0x3346, - - 0x38A4, 0x0B7D, - 0x2D5D, 0x1FDF, - 0x19B7, 0x2822, - 0x0D99, 0x1F12, - 0x194C, 0x0CE6 -}; - -/* possible pulse values */ -static const int16_t ts_562[64] = { - 0x0002, 0x0006, 0xFFFE, 0xFFFA, - 0x0004, 0x000C, 0xFFFC, 0xFFF4, - 0x0006, 0x0012, 0xFFFA, 0xFFEE, - 0x000A, 0x001E, 0xFFF6, 0xFFE2, - 0x0010, 0x0030, 0xFFF0, 0xFFD0, - 0x0019, 0x004B, 0xFFE7, 0xFFB5, - 0x0028, 0x0078, 0xFFD8, 0xFF88, - 0x0040, 0x00C0, 0xFFC0, 0xFF40, - 0x0065, 0x012F, 0xFF9B, 0xFED1, - 0x00A1, 0x01E3, 0xFF5F, 0xFE1D, - 0x0100, 0x0300, 0xFF00, 0xFD00, - 0x0196, 0x04C2, 0xFE6A, 0xFB3E, - 0x0285, 0x078F, 0xFD7B, 0xF871, - 0x0400, 0x0C00, 0xFC00, 0xF400, - 0x0659, 0x130B, 0xF9A7, 0xECF5, - 0x0A14, 0x1E3C, 0xF5EC, 0xE1C4 -}; - -/* filters used in final output calculations */ -static const int16_t ts_5E2[8] = - { 0x4666, 0x26B8, 0x154C, 0x0BB6, 0x0671, 0x038B, 0x01F3, 0x0112 }; -static const int16_t ts_5F2[8] = - { 0x6000, 0x4800, 0x3600, 0x2880, 0x1E60, 0x16C8, 0x1116, 0x0CD1 }; - -#endif /* AVCODEC_TRUESPEECH_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/tscc.c b/tizen/distrib/ffmpeg/libavcodec/tscc.c deleted file mode 100644 index 2b717c1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tscc.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * TechSmith Camtasia decoder - * Copyright (c) 2004 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * TechSmith Camtasia decoder - * - * Fourcc: TSCC - * - * Codec is very simple: - * it codes picture (picture difference, really) - * with algorithm almost identical to Windows RLE8, - * only without padding and with greater pixel sizes, - * then this coded picture is packed with ZLib - * - * Supports: BGR8,BGR555,BGR24 - only BGR8 and BGR555 tested - * - */ - -#include -#include - -#include "avcodec.h" -#include "msrledec.h" - -#include - - -/* - * Decoder context - */ -typedef struct TsccContext { - - AVCodecContext *avctx; - AVFrame pic; - - // Bits per pixel - int bpp; - // Decompressed data size - unsigned int decomp_size; - // Decompression buffer - unsigned char* decomp_buf; - int height; - z_stream zstream; -} CamtasiaContext; - -/* - * - * Decode a frame - * - */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - CamtasiaContext * const c = avctx->priv_data; - const unsigned char *encoded = buf; - unsigned char *outptr; - int zret; // Zlib return code - int len = buf_size; - - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 1; - 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 - - zret = inflateReset(&(c->zstream)); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); - return -1; - } - 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); - // Z_DATA_ERROR means empty picture - if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) { - av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); - return -1; - } - - - if(zret != Z_DATA_ERROR) - ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, c->decomp_buf, c->decomp_size - c->zstream.avail_out); - - /* make the palette available on the way out */ - if (c->avctx->pix_fmt == PIX_FMT_PAL8) { - memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE); - if (c->avctx->palctrl->palette_changed) { - c->pic.palette_has_changed = 1; - c->avctx->palctrl->palette_changed = 0; - } - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - - - -/* - * - * Init tscc decoder - * - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - CamtasiaContext * const c = avctx->priv_data; - int zret; // Zlib return code - - c->avctx = avctx; - - c->height = avctx->height; - - // Needed if zlib unused or init aborted before inflateInit - memset(&(c->zstream), 0, sizeof(z_stream)); - switch(avctx->bits_per_coded_sample){ - case 8: avctx->pix_fmt = PIX_FMT_PAL8; break; - case 16: avctx->pix_fmt = PIX_FMT_RGB555; break; - case 24: - avctx->pix_fmt = PIX_FMT_BGR24; - break; - case 32: avctx->pix_fmt = PIX_FMT_RGB32; break; - default: av_log(avctx, AV_LOG_ERROR, "Camtasia error: unknown depth %i bpp\n", avctx->bits_per_coded_sample); - return -1; - } - c->bpp = avctx->bits_per_coded_sample; - // buffer size for RLE 'best' case when 2-byte code preceeds each pixel and there may be padding after it too - c->decomp_size = (((avctx->width * c->bpp + 7) >> 3) + 3 * avctx->width + 2) * avctx->height + 2; - - /* Allocate decompression buffer */ - if (c->decomp_size) { - if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; - } - } - - 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; - } - - return 0; -} - - - -/* - * - * Uninit tscc decoder - * - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - CamtasiaContext * const c = avctx->priv_data; - - av_freep(&c->decomp_buf); - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - inflateEnd(&(c->zstream)); - - return 0; -} - -AVCodec tscc_decoder = { - "camtasia", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TSCC, - sizeof(CamtasiaContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/tta.c b/tizen/distrib/ffmpeg/libavcodec/tta.c deleted file mode 100644 index 4bdfd73..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/tta.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * TTA (The Lossless True Audio) decoder - * Copyright (c) 2006 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * TTA (The Lossless True Audio) decoder - * (www.true-audio.com or tta.corecodec.org) - * @author Alex Beregszaszi - * - */ - -#define ALT_BITSTREAM_READER_LE -//#define DEBUG -#include -#include "avcodec.h" -#include "get_bits.h" - -#define FORMAT_INT 1 -#define FORMAT_FLOAT 3 - -typedef struct TTAContext { - AVCodecContext *avctx; - GetBitContext gb; - - int flags, channels, bps, is_float, data_length; - int frame_length, last_frame_length, total_frames; - - int32_t *decode_buffer; -} TTAContext; - -#if 0 -static inline int shift_1(int i) -{ - if (i < 32) - return 1 << i; - else - return 0x80000000; // 16 << 31 -} - -static inline int shift_16(int i) -{ - if (i < 28) - return 16 << i; - else - return 0x80000000; // 16 << 27 -} -#else -static const uint32_t shift_1[] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, - 0x00010000, 0x00020000, 0x00040000, 0x00080000, - 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x80000000, 0x80000000, 0x80000000, 0x80000000, - 0x80000000, 0x80000000, 0x80000000, 0x80000000 -}; - -static const uint32_t * const shift_16 = shift_1 + 4; -#endif - -#define MAX_ORDER 16 -typedef struct TTAFilter { - int32_t shift, round, error, mode; - int32_t qm[MAX_ORDER]; - int32_t dx[MAX_ORDER]; - int32_t dl[MAX_ORDER]; -} TTAFilter; - -static const int32_t ttafilter_configs[4][2] = { - {10, 1}, - {9, 1}, - {10, 1}, - {12, 0} -}; - -static void ttafilter_init(TTAFilter *c, int32_t shift, int32_t mode) { - memset(c, 0, sizeof(TTAFilter)); - c->shift = shift; - c->round = shift_1[shift-1]; -// c->round = 1 << (shift - 1); - c->mode = mode; -} - -// FIXME: copy paste from original -static inline void memshl(register int32_t *a, register int32_t *b) { - *a++ = *b++; - *a++ = *b++; - *a++ = *b++; - *a++ = *b++; - *a++ = *b++; - *a++ = *b++; - *a++ = *b++; - *a = *b; -} - -// FIXME: copy paste from original -// mode=1 encoder, mode=0 decoder -static inline void ttafilter_process(TTAFilter *c, int32_t *in, int32_t mode) { - register int32_t *dl = c->dl, *qm = c->qm, *dx = c->dx, sum = c->round; - - if (!c->error) { - sum += *dl++ * *qm, qm++; - sum += *dl++ * *qm, qm++; - sum += *dl++ * *qm, qm++; - sum += *dl++ * *qm, qm++; - sum += *dl++ * *qm, qm++; - sum += *dl++ * *qm, qm++; - sum += *dl++ * *qm, qm++; - sum += *dl++ * *qm, qm++; - dx += 8; - } else if(c->error < 0) { - sum += *dl++ * (*qm -= *dx++), qm++; - sum += *dl++ * (*qm -= *dx++), qm++; - sum += *dl++ * (*qm -= *dx++), qm++; - sum += *dl++ * (*qm -= *dx++), qm++; - sum += *dl++ * (*qm -= *dx++), qm++; - sum += *dl++ * (*qm -= *dx++), qm++; - sum += *dl++ * (*qm -= *dx++), qm++; - sum += *dl++ * (*qm -= *dx++), qm++; - } else { - sum += *dl++ * (*qm += *dx++), qm++; - sum += *dl++ * (*qm += *dx++), qm++; - sum += *dl++ * (*qm += *dx++), qm++; - sum += *dl++ * (*qm += *dx++), qm++; - sum += *dl++ * (*qm += *dx++), qm++; - sum += *dl++ * (*qm += *dx++), qm++; - sum += *dl++ * (*qm += *dx++), qm++; - sum += *dl++ * (*qm += *dx++), qm++; - } - - *(dx-0) = ((*(dl-1) >> 30) | 1) << 2; - *(dx-1) = ((*(dl-2) >> 30) | 1) << 1; - *(dx-2) = ((*(dl-3) >> 30) | 1) << 1; - *(dx-3) = ((*(dl-4) >> 30) | 1); - - // compress - if (mode) { - *dl = *in; - *in -= (sum >> c->shift); - c->error = *in; - } else { - c->error = *in; - *in += (sum >> c->shift); - *dl = *in; - } - - if (c->mode) { - *(dl-1) = *dl - *(dl-1); - *(dl-2) = *(dl-1) - *(dl-2); - *(dl-3) = *(dl-2) - *(dl-3); - } - - memshl(c->dl, c->dl + 1); - memshl(c->dx, c->dx + 1); -} - -typedef struct TTARice { - uint32_t k0, k1, sum0, sum1; -} TTARice; - -static void rice_init(TTARice *c, uint32_t k0, uint32_t k1) -{ - c->k0 = k0; - c->k1 = k1; - c->sum0 = shift_16[k0]; - c->sum1 = shift_16[k1]; -} - -static int tta_get_unary(GetBitContext *gb) -{ - int ret = 0; - - // count ones - while(get_bits1(gb)) - ret++; - return ret; -} - -static av_cold int tta_decode_init(AVCodecContext * avctx) -{ - TTAContext *s = avctx->priv_data; - int i; - - s->avctx = avctx; - - // 30bytes includes a seektable with one frame - if (avctx->extradata_size < 30) - return -1; - - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size); - if (show_bits_long(&s->gb, 32) == AV_RL32("TTA1")) - { - /* signature */ - skip_bits(&s->gb, 32); -// if (get_bits_long(&s->gb, 32) != bswap_32(AV_RL32("TTA1"))) { -// av_log(s->avctx, AV_LOG_ERROR, "Missing magic\n"); -// return -1; -// } - - s->flags = get_bits(&s->gb, 16); - if (s->flags != 1 && s->flags != 3) - { - av_log(s->avctx, AV_LOG_ERROR, "Invalid flags\n"); - return -1; - } - s->is_float = (s->flags == FORMAT_FLOAT); - avctx->channels = s->channels = get_bits(&s->gb, 16); - avctx->bits_per_coded_sample = get_bits(&s->gb, 16); - s->bps = (avctx->bits_per_coded_sample + 7) / 8; - avctx->sample_rate = get_bits_long(&s->gb, 32); - if(avctx->sample_rate > 1000000){ //prevent FRAME_TIME * avctx->sample_rate from overflowing and sanity check - av_log(avctx, AV_LOG_ERROR, "sample_rate too large\n"); - return -1; - } - s->data_length = get_bits_long(&s->gb, 32); - skip_bits(&s->gb, 32); // CRC32 of header - - if (s->is_float) - { - avctx->sample_fmt = SAMPLE_FMT_FLT; - av_log(s->avctx, AV_LOG_ERROR, "Unsupported sample format. Please contact the developers.\n"); - return -1; - } - else switch(s->bps) { -// case 1: avctx->sample_fmt = SAMPLE_FMT_U8; break; - case 2: avctx->sample_fmt = SAMPLE_FMT_S16; break; -// case 3: avctx->sample_fmt = SAMPLE_FMT_S24; break; - case 4: avctx->sample_fmt = SAMPLE_FMT_S32; break; - default: - av_log(s->avctx, AV_LOG_ERROR, "Invalid/unsupported sample format. Please contact the developers.\n"); - return -1; - } - - // FIXME: horribly broken, but directly from reference source -#define FRAME_TIME 1.04489795918367346939 - s->frame_length = (int)(FRAME_TIME * avctx->sample_rate); - - s->last_frame_length = s->data_length % s->frame_length; - s->total_frames = s->data_length / s->frame_length + - (s->last_frame_length ? 1 : 0); - - av_log(s->avctx, AV_LOG_DEBUG, "flags: %x chans: %d bps: %d rate: %d block: %d\n", - s->flags, avctx->channels, avctx->bits_per_coded_sample, avctx->sample_rate, - avctx->block_align); - av_log(s->avctx, AV_LOG_DEBUG, "data_length: %d frame_length: %d last: %d total: %d\n", - s->data_length, s->frame_length, s->last_frame_length, s->total_frames); - - // FIXME: seek table - for (i = 0; i < s->total_frames; i++) - skip_bits(&s->gb, 32); - skip_bits(&s->gb, 32); // CRC32 of seektable - - if(s->frame_length >= UINT_MAX / (s->channels * sizeof(int32_t))){ - av_log(avctx, AV_LOG_ERROR, "frame_length too large\n"); - return -1; - } - - s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels); - } else { - av_log(avctx, AV_LOG_ERROR, "Wrong extradata present\n"); - return -1; - } - - return 0; -} - -static int tta_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TTAContext *s = avctx->priv_data; - int i; - - init_get_bits(&s->gb, buf, buf_size*8); - { - int32_t predictors[s->channels]; - TTAFilter filters[s->channels]; - TTARice rices[s->channels]; - int cur_chan = 0, framelen = s->frame_length; - int32_t *p; - - if (*data_size < (framelen * s->channels * 2)) { - av_log(avctx, AV_LOG_ERROR, "Output buffer size is too small.\n"); - return -1; - } - // FIXME: seeking - s->total_frames--; - if (!s->total_frames && s->last_frame_length) - framelen = s->last_frame_length; - - // init per channel states - for (i = 0; i < s->channels; i++) { - predictors[i] = 0; - ttafilter_init(&(filters[i]), ttafilter_configs[s->bps-1][0], ttafilter_configs[s->bps-1][1]); - rice_init(&(rices[i]), 10, 10); - } - - for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) { - int32_t *predictor = &(predictors[cur_chan]); - TTAFilter *filter = &(filters[cur_chan]); - TTARice *rice = &(rices[cur_chan]); - uint32_t unary, depth, k; - int32_t value; - - unary = tta_get_unary(&s->gb); - - if (unary == 0) { - depth = 0; - k = rice->k0; - } else { - depth = 1; - k = rice->k1; - unary--; - } - - if (get_bits_left(&s->gb) < k) - return -1; - - if (k) { - if (k > MIN_CACHE_BITS) - return -1; - value = (unary << k) + get_bits(&s->gb, k); - } else - value = unary; - - // FIXME: copy paste from original - switch (depth) { - case 1: - rice->sum1 += value - (rice->sum1 >> 4); - if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1]) - rice->k1--; - else if(rice->sum1 > shift_16[rice->k1 + 1]) - rice->k1++; - value += shift_1[rice->k0]; - default: - rice->sum0 += value - (rice->sum0 >> 4); - if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0]) - rice->k0--; - else if(rice->sum0 > shift_16[rice->k0 + 1]) - rice->k0++; - } - - // extract coded value -#define UNFOLD(x) (((x)&1) ? (++(x)>>1) : (-(x)>>1)) - *p = UNFOLD(value); - - // run hybrid filter - ttafilter_process(filter, p, 0); - - // fixed order prediction -#define PRED(x, k) (int32_t)((((uint64_t)x << k) - x) >> k) - switch (s->bps) { - case 1: *p += PRED(*predictor, 4); break; - case 2: - case 3: *p += PRED(*predictor, 5); break; - case 4: *p += *predictor; break; - } - *predictor = *p; - -#if 0 - // extract 32bit float from last two int samples - if (s->is_float && ((p - data) & 1)) { - uint32_t neg = *p & 0x80000000; - uint32_t hi = *(p - 1); - uint32_t lo = abs(*p) - 1; - - hi += (hi || lo) ? 0x3f80 : 0; - // SWAP16: swap all the 16 bits - *(p - 1) = (hi << 16) | SWAP16(lo) | neg; - } -#endif - - /*if ((get_bits_count(&s->gb)+7)/8 > buf_size) - { - av_log(NULL, AV_LOG_INFO, "overread!!\n"); - break; - }*/ - - // flip channels - if (cur_chan < (s->channels-1)) - cur_chan++; - else { - // decorrelate in case of stereo integer - if (!s->is_float && (s->channels > 1)) { - int32_t *r = p - 1; - for (*p += *r / 2; r > p - s->channels; r--) - *r = *(r + 1) - *r; - } - cur_chan = 0; - } - } - - if (get_bits_left(&s->gb) < 32) - return -1; - skip_bits(&s->gb, 32); // frame crc - - // convert to output buffer - switch(s->bps) { - case 2: { - uint16_t *samples = data; - for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) { -// *samples++ = (unsigned char)*p; -// *samples++ = (unsigned char)(*p >> 8); - *samples++ = *p; - } - *data_size = (uint8_t *)samples - (uint8_t *)data; - break; - } - default: - av_log(s->avctx, AV_LOG_ERROR, "Error, only 16bit samples supported!\n"); - } - } - -// return get_bits_count(&s->gb)+7)/8; - return buf_size; -} - -static av_cold int tta_decode_close(AVCodecContext *avctx) { - TTAContext *s = avctx->priv_data; - - if (s->decode_buffer) - av_free(s->decode_buffer); - - return 0; -} - -AVCodec tta_decoder = { - "tta", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_TTA, - sizeof(TTAContext), - tta_decode_init, - NULL, - tta_decode_close, - tta_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("True Audio (TTA)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/twinvq.c b/tizen/distrib/ffmpeg/libavcodec/twinvq.c deleted file mode 100644 index 6ab3a46..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/twinvq.c +++ /dev/null @@ -1,1127 +0,0 @@ -/* - * TwinVQ decoder - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" -#include "lsp.h" - -#include -#include - -#include "twinvq_data.h" - -enum FrameType { - FT_SHORT = 0, ///< Short frame (divided in n sub-blocks) - FT_MEDIUM, ///< Medium frame (divided in mmtab; - int size_s = mtab->size / mtab->fmode[FT_SHORT].sub; - - for (i = 0; i < size_s/2; i++) { - float cos_i = tctx->cos_tabs[0][i]; - lpc[i] = eval_lpc_spectrum(cos_vals, cos_i, mtab->n_lsp); - lpc[size_s-i-1] = eval_lpc_spectrum(cos_vals, -cos_i, mtab->n_lsp); - } -} - -static void interpolate(float *out, float v1, float v2, int size) -{ - int i; - float step = (v1 - v2)/(size + 1); - - for (i = 0; i < size; i++) { - v2 += step; - out[i] = v2; - } -} - -static inline float get_cos(int idx, int part, const float *cos_tab, int size) -{ - return part ? -cos_tab[size - idx - 1] : - cos_tab[ idx ]; -} - -/** - * Evaluates the LPC amplitude spectrum envelope from the line spectrum pairs. - * Probably for speed reasons, the coefficients are evaluated as - * siiiibiiiisiiiibiiiisiiiibiiiisiiiibiiiis ... - * where s is an evaluated value, i is a value interpolated from the others - * and b might be either calculated or interpolated, depending on an - * unexplained condition. - * - * @param step the size of a block "siiiibiiii" - * @param in the cosinus of the LSP data - * @param part is 0 for 0...PI (positive cossinus values) and 1 for PI...2PI - (negative cossinus values) - * @param size the size of the whole output - */ -static inline void eval_lpcenv_or_interp(TwinContext *tctx, - enum FrameType ftype, - float *out, const float *in, - int size, int step, int part) -{ - int i; - const ModeTab *mtab = tctx->mtab; - const float *cos_tab = tctx->cos_tabs[ftype]; - - // Fill the 's' - for (i = 0; i < size; i += step) - out[i] = - eval_lpc_spectrum(in, - get_cos(i, part, cos_tab, size), - mtab->n_lsp); - - // Fill the 'iiiibiiii' - for (i = step; i <= size - 2*step; i += step) { - if (out[i + step] + out[i - step] > 1.95*out[i] || - out[i + step] >= out[i - step]) { - interpolate(out + i - step + 1, out[i], out[i-step], step - 1); - } else { - out[i - step/2] = - eval_lpc_spectrum(in, - get_cos(i-step/2, part, cos_tab, size), - mtab->n_lsp); - interpolate(out + i - step + 1, out[i-step/2], out[i-step ], step/2 - 1); - interpolate(out + i - step/2 + 1, out[i ], out[i-step/2], step/2 - 1); - } - } - - interpolate(out + size - 2*step + 1, out[size-step], out[size - 2*step], step - 1); -} - -static void eval_lpcenv_2parts(TwinContext *tctx, enum FrameType ftype, - const float *buf, float *lpc, - int size, int step) -{ - eval_lpcenv_or_interp(tctx, ftype, lpc , buf, size/2, step, 0); - eval_lpcenv_or_interp(tctx, ftype, lpc + size/2, buf, size/2, 2*step, 1); - - interpolate(lpc+size/2-step+1, lpc[size/2], lpc[size/2-step], step); - - memset_float(lpc + size - 2*step + 1, lpc[size - 2*step], 2*step - 1); -} - -/** - * Inverse quantization. Read CB coefficients for cb1 and cb2 from the - * bitstream, sum the corresponding vectors and write the result to *out - * after permutation. - */ -static void dequant(TwinContext *tctx, GetBitContext *gb, float *out, - enum FrameType ftype, - const int16_t *cb0, const int16_t *cb1, int cb_len) -{ - int pos = 0; - int i, j; - - for (i = 0; i < tctx->n_div[ftype]; i++) { - int tmp0, tmp1; - int sign0 = 1; - int sign1 = 1; - const int16_t *tab0, *tab1; - int length = tctx->length[ftype][i >= tctx->length_change[ftype]]; - int bitstream_second_part = (i >= tctx->bits_main_spec_change[ftype]); - - int bits = tctx->bits_main_spec[0][ftype][bitstream_second_part]; - if (bits == 7) { - if (get_bits1(gb)) - sign0 = -1; - bits = 6; - } - tmp0 = get_bits(gb, bits); - - bits = tctx->bits_main_spec[1][ftype][bitstream_second_part]; - - if (bits == 7) { - if (get_bits1(gb)) - sign1 = -1; - - bits = 6; - } - tmp1 = get_bits(gb, bits); - - tab0 = cb0 + tmp0*cb_len; - tab1 = cb1 + tmp1*cb_len; - - for (j = 0; j < length; j++) - out[tctx->permut[ftype][pos+j]] = sign0*tab0[j] + sign1*tab1[j]; - - pos += length; - } - -} - -static inline float mulawinv(float y, float clip, float mu) -{ - y = av_clipf(y/clip, -1, 1); - return clip * FFSIGN(y) * (exp(log(1+mu) * fabs(y)) - 1) / mu; -} - -/** - * Evaluate a*b/400 rounded to the nearest integer. When, for example, - * a*b == 200 and the nearest integer is ill-defined, use a table to emulate - * the following broken float-based implementation used by the binary decoder: - * - * \code - * static int very_broken_op(int a, int b) - * { - * static float test; // Ugh, force gcc to do the division first... - * - * test = a/400.; - * return b * test + 0.5; - * } - * \endcode - * - * @note if this function is replaced by just ROUNDED_DIV(a*b,400.), the stddev - * between the original file (before encoding with Yamaha encoder) and the - * decoded output increases, which leads one to believe that the encoder expects - * exactly this broken calculation. - */ -static int very_broken_op(int a, int b) -{ - int x = a*b + 200; - int size; - const uint8_t *rtab; - - if (x%400 || b%5) - return x/400; - - x /= 400; - - size = tabs[b/5].size; - rtab = tabs[b/5].tab; - return x - rtab[size*av_log2(2*(x - 1)/size)+(x - 1)%size]; -} - -/** - * Sum to data a periodic peak of a given period, width and shape. - * - * @param period the period of the peak divised by 400.0 - */ -static void add_peak(int period, int width, const float *shape, - float ppc_gain, float *speech, int len) -{ - int i, j; - - const float *shape_end = shape + len; - int center; - - // First peak centered around zero - for (i = 0; i < width/2; i++) - speech[i] += ppc_gain * *shape++; - - for (i = 1; i < ROUNDED_DIV(len,width) ; i++) { - center = very_broken_op(period, i); - for (j = -width/2; j < (width+1)/2; j++) - speech[j+center] += ppc_gain * *shape++; - } - - // For the last block, be careful not to go beyond the end of the buffer - center = very_broken_op(period, i); - for (j = -width/2; j < (width + 1)/2 && shape < shape_end; j++) - speech[j+center] += ppc_gain * *shape++; -} - -static void decode_ppc(TwinContext *tctx, int period_coef, const float *shape, - float ppc_gain, float *speech) -{ - const ModeTab *mtab = tctx->mtab; - int isampf = tctx->avctx->sample_rate/1000; - int ibps = tctx->avctx->bit_rate/(1000 * tctx->avctx->channels); - int min_period = ROUNDED_DIV( 40*2*mtab->size, isampf); - int max_period = ROUNDED_DIV(6*40*2*mtab->size, isampf); - int period_range = max_period - min_period; - - // This is actually the period multiplied by 400. It is just linearly coded - // between its maximum and minimum value. - int period = min_period + - ROUNDED_DIV(period_coef*period_range, (1 << mtab->ppc_period_bit) - 1); - int width; - - if (isampf == 22 && ibps == 32) { - // For some unknown reason, NTT decided to code this case differently... - width = ROUNDED_DIV((period + 800)* mtab->peak_per2wid, 400*mtab->size); - } else - width = (period )* mtab->peak_per2wid/(400*mtab->size); - - add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len); -} - -static void dec_gain(TwinContext *tctx, GetBitContext *gb, enum FrameType ftype, - float *out) -{ - const ModeTab *mtab = tctx->mtab; - int i, j; - int sub = mtab->fmode[ftype].sub; - float step = AMP_MAX / ((1 << GAIN_BITS) - 1); - float sub_step = SUB_AMP_MAX / ((1 << SUB_GAIN_BITS) - 1); - - if (ftype == FT_LONG) { - for (i = 0; i < tctx->avctx->channels; i++) - out[i] = (1./(1<<13)) * - mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS), - AMP_MAX, MULAW_MU); - } else { - for (i = 0; i < tctx->avctx->channels; i++) { - float val = (1./(1<<23)) * - mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS), - AMP_MAX, MULAW_MU); - - for (j = 0; j < sub; j++) { - out[i*sub + j] = - val*mulawinv(sub_step* 0.5 + - sub_step* get_bits(gb, SUB_GAIN_BITS), - SUB_AMP_MAX, MULAW_MU); - } - } - } -} - -/** - * Rearrange the LSP coefficients so that they have a minimum distance of - * min_dist. This function does it exactly as described in section of 3.2.4 - * of the G.729 specification (but interestingly is different from what the - * reference decoder actually does). - */ -static void rearrange_lsp(int order, float *lsp, float min_dist) -{ - int i; - float min_dist2 = min_dist * 0.5; - for (i = 1; i < order; i++) - if (lsp[i] - lsp[i-1] < min_dist) { - float avg = (lsp[i] + lsp[i-1]) * 0.5; - - lsp[i-1] = avg - min_dist2; - lsp[i ] = avg + min_dist2; - } -} - -static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2, - int lpc_hist_idx, float *lsp, float *hist) -{ - const ModeTab *mtab = tctx->mtab; - int i, j; - - const float *cb = mtab->lspcodebook; - const float *cb2 = cb + (1 << mtab->lsp_bit1)*mtab->n_lsp; - const float *cb3 = cb2 + (1 << mtab->lsp_bit2)*mtab->n_lsp; - - const int8_t funny_rounding[4] = { - -2, - mtab->lsp_split == 4 ? -2 : 1, - mtab->lsp_split == 4 ? -2 : 1, - 0 - }; - - j = 0; - for (i = 0; i < mtab->lsp_split; i++) { - int chunk_end = ((i + 1)*mtab->n_lsp + funny_rounding[i])/mtab->lsp_split; - for (; j < chunk_end; j++) - lsp[j] = cb [lpc_idx1 * mtab->n_lsp + j] + - cb2[lpc_idx2[i] * mtab->n_lsp + j]; - } - - rearrange_lsp(mtab->n_lsp, lsp, 0.0001); - - for (i = 0; i < mtab->n_lsp; i++) { - float tmp1 = 1. - cb3[lpc_hist_idx*mtab->n_lsp + i]; - float tmp2 = hist[i] * cb3[lpc_hist_idx*mtab->n_lsp + i]; - hist[i] = lsp[i]; - lsp[i] = lsp[i] * tmp1 + tmp2; - } - - rearrange_lsp(mtab->n_lsp, lsp, 0.0001); - rearrange_lsp(mtab->n_lsp, lsp, 0.000095); - ff_sort_nearly_sorted_floats(lsp, mtab->n_lsp); -} - -static void dec_lpc_spectrum_inv(TwinContext *tctx, float *lsp, - enum FrameType ftype, float *lpc) -{ - int i; - int size = tctx->mtab->size / tctx->mtab->fmode[ftype].sub; - - for (i = 0; i < tctx->mtab->n_lsp; i++) - lsp[i] = 2*cos(lsp[i]); - - switch (ftype) { - case FT_LONG: - eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 8); - break; - case FT_MEDIUM: - eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 2); - break; - case FT_SHORT: - eval_lpcenv(tctx, lsp, lpc); - break; - } -} - -static void imdct_and_window(TwinContext *tctx, enum FrameType ftype, int wtype, - float *in, float *prev, int ch) -{ - const ModeTab *mtab = tctx->mtab; - int bsize = mtab->size / mtab->fmode[ftype].sub; - int size = mtab->size; - float *buf1 = tctx->tmp_buf; - int j; - int wsize; // Window size - float *out = tctx->curr_frame + 2*ch*mtab->size; - float *out2 = out; - float *prev_buf; - int first_wsize; - - static const uint8_t wtype_to_wsize[] = {0, 0, 2, 2, 2, 1, 0, 1, 1}; - int types_sizes[] = { - mtab->size / mtab->fmode[FT_LONG ].sub, - mtab->size / mtab->fmode[FT_MEDIUM].sub, - mtab->size / (2*mtab->fmode[FT_SHORT ].sub), - }; - - wsize = types_sizes[wtype_to_wsize[wtype]]; - first_wsize = wsize; - prev_buf = prev + (size - bsize)/2; - - for (j = 0; j < mtab->fmode[ftype].sub; j++) { - int sub_wtype = ftype == FT_MEDIUM ? 8 : wtype; - - if (!j && wtype == 4) - sub_wtype = 4; - else if (j == mtab->fmode[ftype].sub-1 && wtype == 7) - sub_wtype = 7; - - wsize = types_sizes[wtype_to_wsize[sub_wtype]]; - - ff_imdct_half(&tctx->mdct_ctx[ftype], buf1 + bsize*j, in + bsize*j); - - tctx->dsp.vector_fmul_window(out2, - prev_buf + (bsize-wsize)/2, - buf1 + bsize*j, - ff_sine_windows[av_log2(wsize)], - 0.0, - wsize/2); - out2 += wsize; - - memcpy(out2, buf1 + bsize*j + wsize/2, (bsize - wsize/2)*sizeof(float)); - - out2 += ftype == FT_MEDIUM ? (bsize-wsize)/2 : bsize - wsize; - - prev_buf = buf1 + bsize*j + bsize/2; - } - - tctx->last_block_pos[ch] = (size + first_wsize)/2; -} - -static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, - float *out) -{ - const ModeTab *mtab = tctx->mtab; - float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0]; - int i, j; - - for (i = 0; i < tctx->avctx->channels; i++) { - imdct_and_window(tctx, ftype, wtype, - tctx->spectrum + i*mtab->size, - prev_buf + 2*i*mtab->size, - i); - } - - if (tctx->avctx->channels == 2) { - for (i = 0; i < mtab->size - tctx->last_block_pos[0]; i++) { - float f1 = prev_buf[ i]; - float f2 = prev_buf[2*mtab->size + i]; - out[2*i ] = f1 + f2; - out[2*i + 1] = f1 - f2; - } - for (j = 0; i < mtab->size; j++,i++) { - float f1 = tctx->curr_frame[ j]; - float f2 = tctx->curr_frame[2*mtab->size + j]; - out[2*i ] = f1 + f2; - out[2*i + 1] = f1 - f2; - } - } else { - memcpy(out, prev_buf, - (mtab->size - tctx->last_block_pos[0]) * sizeof(*out)); - - out += mtab->size - tctx->last_block_pos[0]; - - memcpy(out, tctx->curr_frame, - (tctx->last_block_pos[0]) * sizeof(*out)); - } - -} - -static void dec_bark_env(TwinContext *tctx, const uint8_t *in, int use_hist, - int ch, float *out, float gain, enum FrameType ftype) -{ - const ModeTab *mtab = tctx->mtab; - int i,j; - float *hist = tctx->bark_hist[ftype][ch]; - float val = ((const float []) {0.4, 0.35, 0.28})[ftype]; - int bark_n_coef = mtab->fmode[ftype].bark_n_coef; - int fw_cb_len = mtab->fmode[ftype].bark_env_size / bark_n_coef; - int idx = 0; - - for (i = 0; i < fw_cb_len; i++) - for (j = 0; j < bark_n_coef; j++, idx++) { - float tmp2 = - mtab->fmode[ftype].bark_cb[fw_cb_len*in[j] + i] * (1./4096); - float st = use_hist ? - (1. - val) * tmp2 + val*hist[idx] + 1. : tmp2 + 1.; - - hist[idx] = tmp2; - if (st < -1.) st = 1.; - - memset_float(out, st * gain, mtab->fmode[ftype].bark_tab[idx]); - out += mtab->fmode[ftype].bark_tab[idx]; - } - -} - -static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb, - float *out, enum FrameType ftype) -{ - const ModeTab *mtab = tctx->mtab; - int channels = tctx->avctx->channels; - int sub = mtab->fmode[ftype].sub; - int block_size = mtab->size / sub; - float gain[channels*sub]; - float ppc_shape[mtab->ppc_shape_len * channels * 4]; - uint8_t bark1[channels][sub][mtab->fmode[ftype].bark_n_coef]; - uint8_t bark_use_hist[channels][sub]; - - uint8_t lpc_idx1[channels]; - uint8_t lpc_idx2[channels][tctx->mtab->lsp_split]; - uint8_t lpc_hist_idx[channels]; - - int i, j, k; - - dequant(tctx, gb, out, ftype, - mtab->fmode[ftype].cb0, mtab->fmode[ftype].cb1, - mtab->fmode[ftype].cb_len_read); - - for (i = 0; i < channels; i++) - for (j = 0; j < sub; j++) - for (k = 0; k < mtab->fmode[ftype].bark_n_coef; k++) - bark1[i][j][k] = - get_bits(gb, mtab->fmode[ftype].bark_n_bit); - - for (i = 0; i < channels; i++) - for (j = 0; j < sub; j++) - bark_use_hist[i][j] = get_bits1(gb); - - dec_gain(tctx, gb, ftype, gain); - - for (i = 0; i < channels; i++) { - lpc_hist_idx[i] = get_bits(gb, tctx->mtab->lsp_bit0); - lpc_idx1 [i] = get_bits(gb, tctx->mtab->lsp_bit1); - - for (j = 0; j < tctx->mtab->lsp_split; j++) - lpc_idx2[i][j] = get_bits(gb, tctx->mtab->lsp_bit2); - } - - if (ftype == FT_LONG) { - int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len*channels - 1)/ - tctx->n_div[3]; - dequant(tctx, gb, ppc_shape, FT_PPC, mtab->ppc_shape_cb, - mtab->ppc_shape_cb + cb_len_p*PPC_SHAPE_CB_SIZE, cb_len_p); - } - - for (i = 0; i < channels; i++) { - float *chunk = out + mtab->size * i; - float lsp[tctx->mtab->n_lsp]; - - for (j = 0; j < sub; j++) { - dec_bark_env(tctx, bark1[i][j], bark_use_hist[i][j], i, - tctx->tmp_buf, gain[sub*i+j], ftype); - - tctx->dsp.vector_fmul(chunk + block_size*j, tctx->tmp_buf, - block_size); - - } - - if (ftype == FT_LONG) { - float pgain_step = 25000. / ((1 << mtab->pgain_bit) - 1); - int p_coef = get_bits(gb, tctx->mtab->ppc_period_bit); - int g_coef = get_bits(gb, tctx->mtab->pgain_bit); - float v = 1./8192* - mulawinv(pgain_step*g_coef+ pgain_step/2, 25000., PGAIN_MU); - - decode_ppc(tctx, p_coef, ppc_shape + i*mtab->ppc_shape_len, v, - chunk); - } - - decode_lsp(tctx, lpc_idx1[i], lpc_idx2[i], lpc_hist_idx[i], lsp, - tctx->lsp_hist[i]); - - dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf); - - for (j = 0; j < mtab->fmode[ftype].sub; j++) { - tctx->dsp.vector_fmul(chunk, tctx->tmp_buf, block_size); - chunk += block_size; - } - } -} - -static int twin_decode_frame(AVCodecContext * avctx, void *data, - int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - TwinContext *tctx = avctx->priv_data; - GetBitContext gb; - const ModeTab *mtab = tctx->mtab; - float *out = data; - enum FrameType ftype; - int window_type; - static const enum FrameType wtype_to_ftype_table[] = { - FT_LONG, FT_LONG, FT_SHORT, FT_LONG, - FT_MEDIUM, FT_LONG, FT_LONG, FT_MEDIUM, FT_MEDIUM - }; - - if (buf_size*8 < avctx->bit_rate*mtab->size/avctx->sample_rate + 8) { - av_log(avctx, AV_LOG_ERROR, - "Frame too small (%d bytes). Truncated file?\n", buf_size); - *data_size = 0; - return buf_size; - } - - init_get_bits(&gb, buf, buf_size * 8); - skip_bits(&gb, get_bits(&gb, 8)); - window_type = get_bits(&gb, WINDOW_TYPE_BITS); - - if (window_type > 8) { - av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n"); - return -1; - } - - ftype = wtype_to_ftype_table[window_type]; - - read_and_decode_spectrum(tctx, &gb, tctx->spectrum, ftype); - - imdct_output(tctx, ftype, window_type, out); - - FFSWAP(float*, tctx->curr_frame, tctx->prev_frame); - - if (tctx->avctx->frame_number < 2) { - *data_size=0; - return buf_size; - } - - *data_size = mtab->size*avctx->channels*4; - - return buf_size; -} - -/** - * Init IMDCT and windowing tables - */ -static av_cold void init_mdct_win(TwinContext *tctx) -{ - int i,j; - const ModeTab *mtab = tctx->mtab; - int size_s = mtab->size / mtab->fmode[FT_SHORT].sub; - int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub; - int channels = tctx->avctx->channels; - float norm = channels == 1 ? 2. : 1.; - - for (i = 0; i < 3; i++) { - int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub; - ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1, - -sqrt(norm/bsize) / (1<<15)); - } - - tctx->tmp_buf = av_malloc(mtab->size * sizeof(*tctx->tmp_buf)); - - tctx->spectrum = av_malloc(2*mtab->size*channels*sizeof(float)); - tctx->curr_frame = av_malloc(2*mtab->size*channels*sizeof(float)); - tctx->prev_frame = av_malloc(2*mtab->size*channels*sizeof(float)); - - for (i = 0; i < 3; i++) { - int m = 4*mtab->size/mtab->fmode[i].sub; - double freq = 2*M_PI/m; - tctx->cos_tabs[i] = av_malloc((m/4)*sizeof(*tctx->cos_tabs)); - - for (j = 0; j <= m/8; j++) - tctx->cos_tabs[i][j] = cos((2*j + 1)*freq); - for (j = 1; j < m/8; j++) - tctx->cos_tabs[i][m/4-j] = tctx->cos_tabs[i][j]; - } - - - ff_init_ff_sine_windows(av_log2(size_m)); - ff_init_ff_sine_windows(av_log2(size_s/2)); - ff_init_ff_sine_windows(av_log2(mtab->size)); -} - -/** - * Interpret the data as if it were a num_blocks x line_len[0] matrix and for - * each line do a cyclic permutation, i.e. - * abcdefghijklm -> defghijklmabc - * where the amount to be shifted is evaluated depending on the column. - */ -static void permutate_in_line(int16_t *tab, int num_vect, int num_blocks, - int block_size, - const uint8_t line_len[2], int length_div, - enum FrameType ftype) - -{ - int i,j; - - for (i = 0; i < line_len[0]; i++) { - int shift; - - if (num_blocks == 1 || - (ftype == FT_LONG && num_vect % num_blocks) || - (ftype != FT_LONG && num_vect & 1 ) || - i == line_len[1]) { - shift = 0; - } else if (ftype == FT_LONG) { - shift = i; - } else - shift = i*i; - - for (j = 0; j < num_vect && (j+num_vect*i < block_size*num_blocks); j++) - tab[i*num_vect+j] = i*num_vect + (j + shift) % num_vect; - } -} - -/** - * Interpret the input data as in the following table: - * - * \verbatim - * - * abcdefgh - * ijklmnop - * qrstuvw - * x123456 - * - * \endverbatim - * - * and transpose it, giving the output - * aiqxbjr1cks2dlt3emu4fvn5gow6hp - */ -static void transpose_perm(int16_t *out, int16_t *in, int num_vect, - const uint8_t line_len[2], int length_div) -{ - int i,j; - int cont= 0; - for (i = 0; i < num_vect; i++) - for (j = 0; j < line_len[i >= length_div]; j++) - out[cont++] = in[j*num_vect + i]; -} - -static void linear_perm(int16_t *out, int16_t *in, int n_blocks, int size) -{ - int block_size = size/n_blocks; - int i; - - for (i = 0; i < size; i++) - out[i] = block_size * (in[i] % n_blocks) + in[i] / n_blocks; -} - -static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype) -{ - int block_size; - const ModeTab *mtab = tctx->mtab; - int size = tctx->avctx->channels*mtab->fmode[ftype].sub; - int16_t *tmp_perm = (int16_t *) tctx->tmp_buf; - - if (ftype == FT_PPC) { - size = tctx->avctx->channels; - block_size = mtab->ppc_shape_len; - } else - block_size = mtab->size / mtab->fmode[ftype].sub; - - permutate_in_line(tmp_perm, tctx->n_div[ftype], size, - block_size, tctx->length[ftype], - tctx->length_change[ftype], ftype); - - transpose_perm(tctx->permut[ftype], tmp_perm, tctx->n_div[ftype], - tctx->length[ftype], tctx->length_change[ftype]); - - linear_perm(tctx->permut[ftype], tctx->permut[ftype], size, - size*block_size); -} - -static av_cold void init_bitstream_params(TwinContext *tctx) -{ - const ModeTab *mtab = tctx->mtab; - int n_ch = tctx->avctx->channels; - int total_fr_bits = tctx->avctx->bit_rate*mtab->size/ - tctx->avctx->sample_rate; - - int lsp_bits_per_block = n_ch*(mtab->lsp_bit0 + mtab->lsp_bit1 + - mtab->lsp_split*mtab->lsp_bit2); - - int ppc_bits = n_ch*(mtab->pgain_bit + mtab->ppc_shape_bit + - mtab->ppc_period_bit); - - int bsize_no_main_cb[3]; - int bse_bits[3]; - int i; - enum FrameType frametype; - - for (i = 0; i < 3; i++) - // +1 for history usage switch - bse_bits[i] = n_ch * - (mtab->fmode[i].bark_n_coef * mtab->fmode[i].bark_n_bit + 1); - - bsize_no_main_cb[2] = bse_bits[2] + lsp_bits_per_block + ppc_bits + - WINDOW_TYPE_BITS + n_ch*GAIN_BITS; - - for (i = 0; i < 2; i++) - bsize_no_main_cb[i] = - lsp_bits_per_block + n_ch*GAIN_BITS + WINDOW_TYPE_BITS + - mtab->fmode[i].sub*(bse_bits[i] + n_ch*SUB_GAIN_BITS); - - // The remaining bits are all used for the main spectrum coefficients - for (i = 0; i < 4; i++) { - int bit_size; - int vect_size; - int rounded_up, rounded_down, num_rounded_down, num_rounded_up; - if (i == 3) { - bit_size = n_ch * mtab->ppc_shape_bit; - vect_size = n_ch * mtab->ppc_shape_len; - } else { - bit_size = total_fr_bits - bsize_no_main_cb[i]; - vect_size = n_ch * mtab->size; - } - - tctx->n_div[i] = (bit_size + 13) / 14; - - rounded_up = (bit_size + tctx->n_div[i] - 1)/tctx->n_div[i]; - rounded_down = (bit_size )/tctx->n_div[i]; - num_rounded_down = rounded_up * tctx->n_div[i] - bit_size; - num_rounded_up = tctx->n_div[i] - num_rounded_down; - tctx->bits_main_spec[0][i][0] = (rounded_up + 1)/2; - tctx->bits_main_spec[1][i][0] = (rounded_up )/2; - tctx->bits_main_spec[0][i][1] = (rounded_down + 1)/2; - tctx->bits_main_spec[1][i][1] = (rounded_down )/2; - tctx->bits_main_spec_change[i] = num_rounded_up; - - rounded_up = (vect_size + tctx->n_div[i] - 1)/tctx->n_div[i]; - rounded_down = (vect_size )/tctx->n_div[i]; - num_rounded_down = rounded_up * tctx->n_div[i] - vect_size; - num_rounded_up = tctx->n_div[i] - num_rounded_down; - tctx->length[i][0] = rounded_up; - tctx->length[i][1] = rounded_down; - tctx->length_change[i] = num_rounded_up; - } - - for (frametype = FT_SHORT; frametype <= FT_PPC; frametype++) - construct_perm_table(tctx, frametype); -} - -static av_cold int twin_decode_init(AVCodecContext *avctx) -{ - TwinContext *tctx = avctx->priv_data; - int isampf = avctx->sample_rate/1000; - int ibps = avctx->bit_rate/(1000 * avctx->channels); - - tctx->avctx = avctx; - avctx->sample_fmt = SAMPLE_FMT_FLT; - - if (avctx->channels > 2) { - av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n", - avctx->channels); - return -1; - } - - switch ((isampf << 8) + ibps) { - case (8 <<8) + 8: tctx->mtab = &mode_08_08; break; - case (11<<8) + 8: tctx->mtab = &mode_11_08; break; - case (11<<8) + 10: tctx->mtab = &mode_11_10; break; - case (16<<8) + 16: tctx->mtab = &mode_16_16; break; - case (22<<8) + 20: tctx->mtab = &mode_22_20; break; - case (22<<8) + 24: tctx->mtab = &mode_22_24; break; - case (22<<8) + 32: tctx->mtab = &mode_22_32; break; - case (44<<8) + 40: tctx->mtab = &mode_44_40; break; - case (44<<8) + 48: tctx->mtab = &mode_44_48; break; - default: - av_log(avctx, AV_LOG_ERROR, "This version does not support %d kHz - %d kbit/s/ch mode.\n", isampf, isampf); - return -1; - } - - dsputil_init(&tctx->dsp, avctx); - init_mdct_win(tctx); - init_bitstream_params(tctx); - - memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist)); - - return 0; -} - -static av_cold int twin_decode_close(AVCodecContext *avctx) -{ - TwinContext *tctx = avctx->priv_data; - int i; - - for (i = 0; i < 3; i++) { - ff_mdct_end(&tctx->mdct_ctx[i]); - av_free(tctx->cos_tabs[i]); - } - - - av_free(tctx->curr_frame); - av_free(tctx->spectrum); - av_free(tctx->prev_frame); - av_free(tctx->tmp_buf); - - return 0; -} - -AVCodec twinvq_decoder = -{ - "twinvq", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_TWINVQ, - sizeof(TwinContext), - twin_decode_init, - NULL, - twin_decode_close, - twin_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("VQF TwinVQ"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/twinvq_data.h b/tizen/distrib/ffmpeg/libavcodec/twinvq_data.h deleted file mode 100644 index 3042cd1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/twinvq_data.h +++ /dev/null @@ -1,11137 +0,0 @@ -/* - * TwinVQ decoder - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_TWINVQ_DATA_H -#define AVCODEC_TWINVQ_DATA_H - -#include -#include - -/* - * The bark_tab_* tables are constructed so that - * - * /i-1 \ - * |-- | - * bark |\ bark_tab[j] | == i - * |/ | - * |-- | - * \j=0 / - * - * - * for some slightly nonconventional bark-scale function - */ -static const uint16_t bark_tab_l08_512[] = { - 7, 8, 7, 8, 8, 8, 8, 8, 8, 9, - 9, 10, 10, 11, 11, 12, 12, 14, 15, 16, - 18, 19, 21, 24, 27, 30, 35, 40, 46, 53 -}; - -static const uint16_t bark_tab_l11_512[] = { - 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, - 8, 8, 8, 9, 10, 10, 11, 13, 13, 15, - 17, 18, 21, 25, 27, 33, 38, 45, 54, 66 -}; - -static const uint16_t bark_tab_l16_1024[] = { - 9, 9, 8, 9, 10, 9, 10, 10, 10, 12, - 11, 13, 13, 14, 16, 17, 19, 20, 24, 26, - 30, 35, 40, 48, 56, 68, 83, 102, 128, 165 -}; - -static const uint16_t bark_tab_l22_1024[] = { - 6, 7, 6, 6, 7, 7, 7, 7, 7, 8, - 9, 8, 10, 10, 11, 12, 13, 15, 16, 18, - 21, 24, 27, 33, 38, 46, 55, 68, 84, 107, - 140, 191 -}; - -static const uint16_t bark_tab_l22_512[] = { - 3, 3, 3, 4, 3, 3, 4, 3, 4, 4, - 4, 5, 4, 5, 6, 6, 7, 7, 8, 9, - 10, 12, 14, 16, 20, 22, 28, 34, 42, 53, - 71, 95 -}; - -static const uint16_t bark_tab_l44_2048[] = { - 5, 6, 5, 6, 5, 6, 6, 6, 6, 6, - 7, 7, 7, 8, 8, 9, 9, 10, 11, 11, - 13, 14, 16, 17, 19, 22, 25, 29, 33, 39, - 46, 54, 64, 79, 98, 123, 161, 220, 320, 512 -}; - -static const uint16_t bark_tab_m08_256[] = { - 6, 5, 6, 6, 6, 6, 7, 7, 8, 8, - 9, 10, 11, 13, 15, 18, 20, 25, 31, 39 -}; - -static const uint16_t bark_tab_m11_256[] = { - 4, 5, 4, 5, 5, 5, 6, 5, 7, 7, - 8, 9, 10, 12, 15, 17, 22, 28, 35, 47 -}; - -static const uint16_t bark_tab_m16_512[] = { - 7, 6, 7, 7, 7, 8, 9, 9, 10, 11, - 14, 15, 18, 22, 27, 34, 44, 59, 81, 117 -}; - -static const uint16_t bark_tab_m22_256[] = { - 3, 2, 3, 2, 3, 3, 4, 3, 4, 5, - 5, 7, 8, 9, 13, 16, 22, 30, 44, 70 -}; - -static const uint16_t bark_tab_m22_512[] = { - 5, 5, 5, 6, 5, 7, 6, 7, 9, 9, - 11, 13, 15, 20, 24, 33, 43, 61, 88, 140 -}; - -static const uint16_t bark_tab_m44_512[] = { - 3, 2, 3, 3, 3, 4, 3, 5, 4, 6, - 7, 8, 10, 14, 18, 25, 36, 55, 95, 208 -}; - -static const uint16_t bark_tab_s08_64[] = { - 3, 3, 3, 3, 4, 5, 6, 8, 12, 17 -}; - -static const uint16_t bark_tab_s11_64[] = { - 2, 3, 2, 3, 3, 4, 6, 8, 12, 21 -}; - -static const uint16_t bark_tab_s16_128[] = { - 3, 4, 4, 4, 5, 7, 10, 16, 26, 49 -}; - -static const uint16_t bark_tab_s22_128[] = { - 3, 2, 3, 4, 4, 6, 9, 14, 26, 57 -}; - -static const uint16_t bark_tab_s44_128[] = { - 1, 2, 1, 2, 3, 4, 6, 10, 23, 76 -}; - - -/** - * TwinVQ codebooks. They are coded in a struct so we can use code such as - * - * float val = tab.fcb0808l[get_bits(gb, 12)]; - * - * without risking a segfault on malformed files. - */ -static const struct { - float lsp08[504]; - int16_t fcb08l[640]; - int16_t fcb08m[320]; - int16_t fcb08s[320]; - int16_t shape08[1280]; - - int16_t cb0808l0[1088]; - int16_t cb0808l1[1088]; - int16_t cb0808s0[1152]; - int16_t cb0808s1[1152]; - int16_t cb0808m0[1024]; - int16_t cb0808m1[1024]; - - int16_t cb1108l0[1728]; - int16_t cb1108l1[1728]; - int16_t cb1108m0[1536]; - int16_t cb1108m1[1536]; - int16_t cb1108s0[1856]; - int16_t cb1108s1[1856]; - - int16_t fcb11l[640]; - int16_t fcb11m[320]; - int16_t fcb11s[320]; - int16_t shape11[1280]; - float lsp11[1312]; - - int16_t cb1110l0[1280]; - int16_t cb1110l1[1280]; - int16_t cb1110m0[1152]; - int16_t cb1110m1[1152]; - int16_t cb1110s0[1344]; - int16_t cb1110s1[1344]; - - int16_t fcb16l[640]; - int16_t fcb16m[320]; - int16_t fcb16s[320]; - int16_t shape16[1920]; - float lsp16[1400]; - - int16_t cb1616l0[1024]; - int16_t cb1616l1[1024]; - int16_t cb1616m0[960]; - int16_t cb1616m1[960]; - int16_t cb1616s0[1024]; - int16_t cb1616s1[1024]; - - int16_t cb2220l0[1152]; - int16_t cb2220l1[1152]; - int16_t cb2220m0[1088]; - int16_t cb2220m1[1088]; - int16_t cb2220s0[1152]; - int16_t cb2220s1[1152]; - - int16_t fcb22l_1[512]; - int16_t fcb22m_1[640]; - int16_t fcb22s_1[640]; - int16_t shape22_1[1152]; - float lsp22_1[1312]; - - int16_t cb2224l0[960]; - int16_t cb2224l1[960]; - int16_t cb2224m0[896]; - int16_t cb2224m1[896]; - int16_t cb2224s0[960]; - int16_t cb2224s1[960]; - - int16_t fcb22l_2[512]; - int16_t fcb22m_2[640]; - int16_t fcb22s_2[640]; - int16_t shape22_2[1152]; - float lsp22_2[1312]; - - int16_t cb2232l0[768]; - int16_t cb2232l1[768]; - int16_t cb2232m0[704]; - int16_t cb2232m1[704]; - int16_t cb2232s0[704]; - int16_t cb2232s1[704]; - - int16_t cb4440l0[1088]; - int16_t cb4440l1[1088]; - int16_t cb4440m0[1088]; - int16_t cb4440m1[1088]; - int16_t cb4440s0[1152]; - int16_t cb4440s1[1152]; - - int16_t fcb44l[640]; - int16_t fcb44m[640]; - int16_t fcb44s[640]; - int16_t shape44[1152]; - float lsp44[1640]; - - int16_t cb4448l0[896]; - int16_t cb4448l1[896]; - int16_t cb4448m0[896]; - int16_t cb4448m1[896]; - int16_t cb4448s0[960]; - int16_t cb4448s1[960]; -} tab = { -.cb0808l0 = { - 96, -12592, -12443, 425, 182, -456, -341, -843, - 615, 689, 982, 1470, -518, 231, -538, 282, - 409, -600, -303, -29, 51, -4, -115, 79, - -27, 450, -937, -461, -554, -159, 426, 710, --29106, -2148, 99, 3426, 1838, 12427, 585, -2080, - -2524, -474, 1572, 718, 578, -344, 188, 328, - 12125, 112, 654, -1232, -1644, 288, 553, 1513, - 966, 1012, 49, 631, -111, -238, -116, -182, - -21, -46, 334, 11013, -454, -261, 12, 21, - 52, -20440, -295, -502, -516, -329, -230, 465, - 59, 270, 971, -127, 505, -194, 43, -30, - 300, 38, 665, -613, 33, -172, -153, 323, - -166, 54, 399, 109, 186, -1765, -222, 138, - 16, 204, 30111, 208, -564, -612, 156, -146, - -345, 321, -138, 202, -184, 93, 710, -15945, --13401, 234, -1113, 146, -9, 56, -628, -834, - -1268, 872, 61, -1184, -126, -205, 145, -109, - -8248, 113, -146, 1288, 9142, 857, -782, -686, - -256, -650, 1061, -202, 12, -709, -88, 273, - 497, 150, -59, -8807, 240, 532, 16, 1482, - 11012, -444, 1918, -1786, 1934, 172, 598, -1324, - 5638, -3166, 492, -545, -770, 1067, 0, -356, - -421, 1684, 273, -502, 316, 1116, 807, -529, - -831, -13379, -420, 236, 470, -2590, -193, -47, - 580, -1613, 798, 27, -16, -12768, -893, 256, - 0, 1659, 1463, 544, 196, -30444, 314, -421, - 508, -276, -173, 414, -380, -371, -40, -121, - 375, 432, -438, 1, -350, -280, 1198, -373, - 452, 100, -68, 9053, 165, 770, 73, 291, - 717, 515, 596, -323, -4, -2, 803, 738, - 2605, 30, 73, 455, 11280, 1534, -283, 1502, - -9126, -4760, -570, 483, -179, -8628, -1639, 322, - -56, 6149, -3330, 114, 4598, -1976, -34, -56, - 840, 753, 12292, -7100, -492, 320, -412, 908, - 1186, 444, 6546, -788, 5394, 697, 13105, 194, - -394, 294, 2639, 12, -1009, -1426, -36, 2106, - -252, -31979, -66, 341, 996, 298, 105, 6, - 10, 106, -498, -244, -105, -574, 16, -206, - 24, -2067, -381, 10265, -103, -762, -785, -2036, --11927, 16, -710, -35, -270, -99, 4, 772, - -272, -186, -328, -14936, -57, -1357, -175, -606, - 220, 918, -11, 398, -189, -278, 138, 429, - 509, -701, -43, -42, -630, -560, 11736, -528, - 10286, -633, -870, 423, 550, -888, 297, -170, - 258, 2234, 486, 292, -446, -11858, 10008, 52, - 1203, -164, 810, -1527, -604, -883, -588, -96, - 332, 148, -180, 223, 356, 285, 434, -57, - -172, -520, -432, -72, 294, -93, -134, 316, - 30647, -351, 278, 84, -439, 589, 105, 1001, - 297, 660, 196, 171, 178, -90, -55, 1172, - 21100, 227, -288, 372, 162, 458, -555, -1329, - 380, 366, -104, 105, 674, -378, 1328, 283, - -1928, 549, 762, 454, 55, 606, 12499, 24, - 435, 23, 29, 6170, 1129, -95, 97, 569, - 132, 491, 164, -288, -1011, -134, 1234, -427, - -254, -524, 226, -14114, 328, -70, 1666, -189, - -2352, 1097, 619, 632, -981, 745, 587, -27, - -200, -871, 50, 470, -246, 2610, 581, 254, - 9893, -586, 880, -11894, 386, 1135, 117, 1072, - 116, -830, -160, -1002, -699, -66, -230, -260, - 112, 106, 221, 297, -47, 7642, 170, -330, - -599, -51, -476, 33, 475, 624, 6199, -350, - -406, 184, 906, -528, 382, 401, 348, 26, - -186, 33, -130, -62, -50, 1268, -132, -109, - 1164, -354, 675, 3, -402, -244, 644, 648, - -132, -4, 45, 20386, -136, 568, 126, 376, - 14476, -376, 267, 13518, -260, 111, 1014, 758, - 439, 551, -164, 207, 128, -416, 616, 690, - -9460, -1856, 1123, 826, -265, -762, 1596, -632, - 52, -622, -894, 367, -433, -100, 1873, 756, --17436, 168, -541, 550, 145, -5612, -1057, -1344, - -656, -194, 216, -500, -245, 246, 64, 688, - 727, 12538, -5492, 252, -908, -424, -532, -659, - -277, -230, -736, -183, 35, -228, 200, -12, - -248, -60, -493, 433, 446, 366, -644, 92, - -324, 29, 833, -21542, -977, 94, 379, 49, - -1058, 248, -178, 85, -961, -1198, -48, 467, - -242, -10202, 1556, 11263, -716, 814, -1686, 3594, - -27, 694, -802, 390, 4144, -663, 44, -546, - 312, -28, -484, 981, -307, 496, 408, 203, - 12543, 296, -1240, 159, 846, -957, -1493, -618, - 1593, 11868, 2616, 1954, 412, -922, -1320, 3325, - -254, -1892, 607, -2223, -8745, -1486, 17, 343, - -50, -562, 22011, -350, -491, -70, -60, 617, - 768, -346, 387, 660, 1409, 222, 616, 173, - -1323, 4017, -207, -525, -13243, 11, 440, -614, - -280, 549, -670, -79, 459, 560, -102, -214, - -54, -1201, 230, -526, 857, 1044, -369, 2470, --11010, -12586, 243, -205, 838, -920, 348, -738, - 1319, 86, -78, -428, -1909, -155, 2, 508, - 711, -292, 1699, 225, -101, -163, 540, 9692, - 235, -183, -38, 198, -466, -204, -8957, -914, - -299, 193, 10, 723, 643, -533, -1418, 323, - 20, 334, -886, -331, 368, 130, -30233, -152, - -14, 637, 132, -232, -149, -430, 64, -243, - -376, 370, 388, 196, -1098, 117, -794, -16, - -274, 348, 464, -28156, 184, 322, -101, 2, - -27, -183, 610, 256, -160, -573, -226, 588, - 1613, 1028, 9518, -2151, -1602, -528, -356, -116, --11511, 1828, -2206, -47, -757, -1479, -1429, -14717, - 1686, 253, 802, 462, -37, -916, -289, -401, - 13383, 353, -74, 114, -189, 636, 434, -639, - 1013, 234, 11752, 219, 1464, -132, -12838, 125, - -592, -40, -162, -1772, 506, 479, 422, 36, - 15, -960, 799, 517, 1311, -409, 748, 729, - 446, 11029, -13039, 1257, -651, -13, -742, 1416, - -388, -274, -795, 163, -572, 74, 430, -90, - -126, -74, -598, 140, 125, -20, -20332, 208, - 37, 19, -174, -209, 305, 28, -402, 28, - -315, -1, -134, 440, -832, 79, -635, -304, - 8, -32768, 625, 470, -1224, -351, 546, -1171, - -706, 652, 31, 7484, -448, 916, 1244, -379, - -300, 68, 868, 607, 247, 70, -984, 14314, - 21, -350, -82, 368, 456, -742, 472, 34, - 782, -498, -879, 700, 417, 216, 415, -161, - -181, -608, 1570, 862, -96, -114, 8095, -26, - 168, -363, -804, -36, -770, 139, -171, 6645, - -1425, 4826, -5288, 1358, -11747, -64, 650, -3206, - -1692, 789, -2047, -279, 916, -1648, 1164, 2044, - -144, -717, -392, -216, 372, 348, 1052, -175, - 668, 308, -15, 29112, -406, -774, 365, -1006, - -526, 1076, 59, -672, -87, -106, 174, 96, - 615, 462, -43, -496, 112, 149, -56, -182, - -268, -32768, -205, -676, 165, -1210, -325, 7964, - -44, 546, -699, 285, -418, 355, 238, 550, - 67, 425, 384, -950, -330, -208, -452, 212, - 11610, -190, 37, -907, -11137, -982, 585, -783, - -864, 164, -24, -514, -211, 2, -510, -580, - 595, 128, 100, -229, -55, 290, -539, 40, - -7786, -270, 295, -508, 562, -1196, 218, 33, - 3788, -8954, -1082, 297, -906, -322, 123, 1162, - -343, -11655, 88, -28, 1173, 9, -99, 36, --11987, 356, 12630, 767, -183, -983, -559, 186, - 1148, 530, -440, 1230, -456, -133, -424, 35, - -357, 418, 1457, -687, 740, -242, 17855, -368, - -1057, -262, -646, 406, -712, -1058, -84, 454 -}, - -.cb0808l1 = { - 982, -26, -721, 359, 509, 13290, 2391, 727, - 325, 328, 269, -156, 346, -242, -31, -356, - 741, 396, -98, 108, 35, -237, -29684, 196, - -69, 462, -339, 24, -1221, 352, -658, 396, - 243, -1658, -458, -1153, 5, -662, -47, 18, - -572, -567, -2084, -980, -210, 150, -396, 14836, - -210, 0, -162, -539, 588, -868, 248, -8576, - 1020, 526, 1056, 262, -149, 818, -1353, -1120, - 767, -738, -634, -14742, -105, 811, 1718, -116, - -64, 307, 920, -1244, 2388, 10213, -4505, -250, - 617, -1725, -645, 1258, 1146, -590, 707, -12, - 372, 1794, 1012, -149, 404, -978, -306, 168, - -1536, 89, 142, 938, -19891, 973, -481, -419, - -904, -455, -1821, -1617, 654, -2022, 1906, -497, --11346, -330, -11679, -14, 1, 535, -377, 1057, - -214, -213, 430, -13, -3379, -11250, 911, -716, - -240, -10, 260, 132, -611, -64, -594, -8540, - 837, -3717, -1154, 906, 10623, -502, -167, 67, - 119, 13501, -1469, 213, -1048, -1403, 432, -1079, - 45, -230, -730, -203, -595, -1150, -460, -97, - 395, -304, 27816, -300, -16, 153, -671, 551, - 436, -956, -182, 194, 113, -5504, 194, 263, - -332, -517, -244, -396, 540, 56, -371, 446, - 147, -66, 7, -306, 1440, -308, 327, 645, - 597, -6642, 72, 392, -138, -50, -144, -262, - 504, -230, 114, 2076, 8175, 1188, 290, -872, - 202, 69, 82, -281, -126, -291, -158, -152, - -45, 239, 153, -516, -422, -691, 801, 28, - 496, -298, -11118, 10430, -227, -851, 214, -801, - 538, 834, -137, 942, 573, 405, 1308, 2234, - 300, 1269, 12361, -752, 2177, -743, 60, 464, - 946, 302, -422, 116, -1200, -110, -843, 284, - -578, 732, -308, 153, -64, 156, 225, -29232, - -452, -466, -130, 888, 240, 305, -83, 236, - 208, 417, 1530, 294, 594, 351, 508, 137, - -7274, -184, 201, 44, -635, -891, -652, -596, - 380, -652, -8670, -76, -3746, -732, 262, -1860, - -1030, 1366, -279, 444, 911, 209, 330, 251, - -208, -747, 65, -10154, -204, 12960, -325, 347, - -465, -730, -727, 385, -89, -763, -427, 868, - -39, -859, 34, -29, -388, -1324, -218, 2051, - -1593, 5511, 10507, -8516, 2254, 5847, -1474, 1994, - 4704, -1876, 880, -3810, -489, -946, -1225, -1104, - 125, 139, -668, 2232, -537, 179, -215, 63, - 144, 72, 1198, 9750, 248, -709, 308, 10552, - -434, -462, 13569, 1096, -491, -262, 804, -1599, - 679, 569, 604, 1326, 213, -2026, 324, -2612, - -373, -12818, -20, 38, -171, 316, 15516, 306, - 763, 97, 91, -832, 23, -437, -390, 505, - -1226, 2518, 106, -2065, 315, 86, 523, 172, - -1012, -13851, 3358, 2610, -381, -194, 1200, -4106, - -1298, -3637, -1534, 780, 1367, -544, -770, 1690, - 1047, -54, 2136, 12502, 32, 6689, 706, -1172, - 846, -4853, 2146, 2548, -39, -465, -596, 177, - 213, 421, 28, -388, 11, 69, 31, -83, - -28, -166, -150, -19836, -323, 3, 659, 783, - 390, 139, -138, 31, -111, 453, -80, 432, - -519, -259, 686, 11431, 163, -13179, 554, 40, - -379, -120, -692, 340, 169, 120, -476, 643, - 778, 501, -128, 543, 1275, -134, 20568, 201, - 401, 512, -362, -210, -269, -812, 112, 75, - 149, -547, -494, -418, -100, -13621, -1002, 1176, - 1634, -395, -4289, -1531, -47, 850, -1102, 13558, - -403, 683, -164, -2215, -1180, -1750, 344, 630, - -968, 669, 540, 26, -594, 192, -17, -336, - 19645, 1133, 18, -56, 418, -426, -1535, 409, - 732, 186, 268, -20422, -22, 62, -621, 722, - 440, 96, -307, -128, 480, 5, 87, 668, - -361, -599, -22, 652, -176, -114, 214, -12233, - -698, 232, 608, -126, -714, -488, -228, 929, - -1582, -19845, 245, -460, 124, 57, 328, -436, - -158, 236, -196, -534, 209, 69, 229, 210, - -251, 1100, 583, 415, 210, 189, -219, 1242, - 19482, -105, 190, -374, -43, -232, 253, 561, - -297, -376, -1077, -308, 13486, -12462, 64, -190, - -298, -643, 460, 232, -987, -478, 1596, 168, - -722, 616, -873, -98, -948, 231, -1102, 11915, - 746, -495, 1248, 1203, 11067, -32, 160, -94, - -24, -153, -209, -1453, -1059, -313, -922, 1143, - -538, -1348, -323, 679, -54, -232, -470, 2075, --19135, 628, -774, 35, 247, -86, 721, 512, - 1305, 850, 9760, 248, -2404, -220, 6, -73, - -1370, 567, 1432, -2529, -1508, 14358, -992, -1111, - -940, -111, 968, -530, 576, 102, -1045, 453, - 180, -94, -7936, -310, 512, 996, -32, -1062, - -150, -26, -6687, -181, -336, -1510, 616, 70, - -332, -175, 624, -546, 171, 364, 1011, 68, - -284, -368, 711, 46, 73, -34, -419, 404, - 28270, 283, -324, 335, -131, 316, 212, -27, - -342, -1062, 470, 1269, 454, 286, -1928, -1674, - -739, -389, 1073, -6172, -317, -586, -194, -182, --13034, -848, 4596, -659, 709, -630, -310, 400, - 344, -276, 430, 876, -2047, -1012, -1672, -180, - 64, 22005, -736, 829, 266, 182, 436, -112, - -36, 131, 252, -63, 154, 368, 107, 93, - -42, -32768, 0, 200, -230, 271, -1776, 4329, - 986, -553, 481, 1888, -2770, 848, -6305, 264, - 12244, 1610, -640, 1348, -2742, -2078, 907, -1115, - 370, -16539, -1571, -176, 24, -515, 234, 954, - 605, 613, -154, 463, 535, -160, 684, 470, - 827, 10458, 150, -669, -6684, 339, -542, -730, - -351, 984, 212, 116, -7, 62, 926, 2175, - -185, -552, 489, -209, 5247, 38, 366, 53, - 16, 263, -142, -535, -224, 338, -174, -125, - 113, -12750, 400, -410, 281, -12, 744, -173, - 486, -12159, -107, -183, -484, 2, 150, 1, - -239, 7, -399, -608, -873, 698, -1623, 701, - -773, 272, -832, -94, -921, 885, 13588, 178, - 192, 148, 1346, 44, 59, -275, -14, -328, - 212, 133, -223, 300, -394, -275, -43, -76, - -47, 322, -208, 21713, 484, 329, 1860, 40, - -916, 502, 130, 477, 1754, 503, 7984, -338, - -323, -230, 354, 928, 430, -89, -94, 108, - -543, 365, -130, 70, 902, -131, 58, 469, - 580, -30949, 36, 232, -410, -451, 104, -8698, - 113, -1682, -42, -279, -92, -280, -477, -386, - -531, 832, 80, -15002, -56, 93, 164, -721, - 8388, -412, -2396, 584, 1004, -310, -2229, -304, - -383, 275, 1062, 1266, 297, -70, -909, 891, - 131, -1046, 539, 32502, 1000, -21, -229, 138, - 1528, -175, 546, 326, 168, -320, 716, -291, - -298, -227, 1094, -59, -12561, 12943, 786, 600, - -206, 889, -761, 54, 332, -1253, -597, 357, - -1124, -50, -168, 1172, 2266, 75, -174, 583, - 408, -157, 14666, 378, 302, -5, 48, 109, - 28, -21, 1044, 529, -859, -1182, -202, 1984, - 308, 402, 66, -1139, 2595, -380, 1119, 309, - 482, -10705, 100, -4591, 11646, -1364, -365, 9521, - -318, -23, 1076, -135, -2742, -833, 78, 910, - 96, -20, -599, 46, 855, -1265, 4748, 2394, - -250, -9096, -962, 191, -346, 348, 342, 1909, - 15330, 266, 540, 271, 2986, 1356, 1542, -1019, - -895, 737, 281, 684, -538, 10414, -922, 287, - 679, 204, -11142, -2321, -346, -1572, -250, -315, - -604, 1336, 311, 1317, -1111, 409, -104, -221, --14125, -1511, -990, 705, -808, 587, 676, 348 -}, - -.cb0808s0 = { - -7488, -1327, -5244, -2049, -3736, -45, 446, 1558, - -755, -6052, 6034, -4326, 740, -348, 12369, 2115, - -662, -685, -6592, 10176, 8575, -1035, -2752, -4453, - -283, 1547, 4776, -2932, 700, 3425, -3905, 1073, - 2356, -7094, -1705, -435, 4840, -1944, 1188, 780, - -3963, -6170, -1726, 4759, -4356, -2124, -1686, 321, - -901, 1414, -923, -2678, -1198, -14777, -2038, -3528, - 123, 11216, 1904, -1914, 7588, 2744, -4265, -4886, - -3530, -1495, -1709, -5857, 3829, 2196, -4842, -817, - -874, -5649, -2181, -3871, 3774, -1368, 322, -1126, - -996, -3873, 13698, -9369, -848, 3797, -667, -1083, - 2429, -3351, -1672, -3562, -1590, -3507, 552, 6610, - -4137, -10061, -5452, -6142, -1454, 1726, -1298, -4479, - 6126, 1626, -2791, 1584, 1300, 5726, 2584, 11109, - 696, -3344, -2418, 9029, 4346, -3554, 1393, 144, - 2051, 8916, 6174, 5170, 376, 9778, -2298, -4119, - 3733, -35, -2673, 2222, 1383, 2046, 2859, -16131, - 1637, -1195, -662, 2800, -2241, 3801, -5062, -978, - 5670, -5449, -79, 3479, 606, 3766, -1325, -265, - 907, -745, 1005, -14528, -4227, -3955, -7194, 3690, - 2166, -2520, 11555, -511, 5900, -388, -3854, -3440, - 2136, -868, -2986, 722, 1286, -4027, 10382, -1646, - 5193, 2539, 1239, 7819, -67, 3382, -3297, -46, - -3808, 830, 1313, -2188, -4346, 5922, -1057, -6294, - 14317, 2001, 968, 4150, -4121, 1412, -302, -8401, - -1388, 10649, -9513, 1042, 840, -4606, 2098, 1166, - 1472, -802, -2810, 420, -561, -325, 2652, -2866, - 1334, 4878, 958, 83, 456, 1203, -7594, 14590, - -1210, 2202, -1954, -1938, -3413, -1096, 6036, -1675, - -1320, -4485, -10665, 10026, -2484, -3273, 4753, -275, - -3542, 924, 1262, 7348, -2959, -749, -408, 4594, - 4876, -491, 3409, 4616, 110, 557, -1378, -1616, - -4532, 1699, 1412, 579, -494, 716, 197, -23346, - -2284, 156, 1096, -151, -1827, 688, -322, 2371, - -7909, -1324, -1683, 7861, 7074, -451, 258, 9088, - 1900, 8660, 840, 3491, -3275, 3029, -475, -2122, - -5725, -8668, -6069, -3458, 4240, -3007, -5463, 9395, - -2686, 4718, -717, 42, -1802, 3122, -3197, -5212, - -1572, -243, -451, 8213, -2199, -3372, 4110, -8176, --10525, -5551, 4312, 682, 2069, 1985, -3713, -6780, - 1193, 2831, -2228, 486, -3667, -789, -1691, 4567, - 464, -2114, -2340, -1881, 1921, 1602, 18418, 1535, - -567, 228, -9359, -6027, -267, 3628, 32767, 1423, - -74, -2817, 2112, -128, -1516, -2446, 1673, 2812, - -1582, 2125, 618, 2569, 2714, -1710, 340, 3255, - 848, 3379, -2317, -2361, -1823, 412, -2496, -18164, - -1224, 2552, -3040, 144, -597, 7716, 4916, -2867, - -2172, 2120, -2776, 675, -11985, 1692, -1384, -3588, - 4310, 1020, -4215, -251, -7090, -1916, 1914, -2804, - 6189, -6732, -1370, -3704, 450, -2652, 6553, -38, - 10348, 1244, -2246, -3729, -2158, -1340, 2357, 3118, - 9378, -1727, 3150, -3867, 1277, -15, 769, -2352, - -411, 1428, -14032, -1029, 2828, -1894, 6084, -36, - 518, 13159, 1095, -1185, -3207, -555, -3256, -76, - 3884, 3394, 1010, 1946, 160, -4863, 4714, -7087, - -3985, 5602, 3350, 7822, -5729, -7701, 9296, 3067, - 3582, 5256, 13629, -4012, -2206, -3867, -664, -104, - 4397, -7862, 36, 955, -38, -973, 3458, 5004, - 364, -9116, -2764, -2168, -1892, -7632, -4834, -5788, - -3565, -1245, -4544, 6552, 4601, 2342, 6625, 1040, - 2154, -6985, 5838, -1912, -3439, 1189, -2422, -555, - 3286, -14872, -776, 1228, 2434, 120, 13673, 904, - -1354, 645, -1550, -1377, -1888, 1416, -679, -1685, - 1731, 2404, -5786, 3285, -193, -123, 1973, 3663, - -1388, -14961, -3597, 5555, -1420, 284, 1527, -2575, - 1941, 871, 3900, -2168, -12763, 2970, -408, -3131, - -6426, 1892, 782, 6768, -284, 1034, 9785, 6029, - -3873, -4102, -4349, 2548, -3686, -5622, 4769, -351, - 8178, -7253, 3687, 624, -4386, 4028, -2780, -1938, - -4061, -1872, -1264, 7300, 760, 8530, -821, -874, --14225, -1143, -5400, -850, -2537, 478, 1668, -1244, - -362, 877, 3481, -1338, -5218, 2091, 3996, -577, - 390, 8626, 820, 181, -988, 5604, 9694, 1112, - -3064, -266, 1234, -486, 1264, -2173, -13671, 3729, - -3212, 2548, 1745, -9363, 8065, 3713, -3343, -4847, - 2808, -4716, -2175, 25, -5718, 4056, 1855, 4663, - 2324, -1166, 543, 2, 3931, -3196, 2771, -920, - -2907, -746, -1241, -306, 2793, -22, -2642, 3048, - 3256, 1804, -1310, 17876, -1816, 56, -1694, -465, - -534, -2274, 6139, -2247, -2515, -1077, 3305, 1519, - 273, 1128, -1637, 2561, -1534, 874, -22808, -1119, - -2551, -10344, -2229, -3510, 194, 2594, 1737, 4713, - 13767, 3532, -311, 8097, -1012, -841, -4360, 793, - -267, -206, 12905, -2683, -6424, 196, 7098, -1690, - -690, 1236, -2882, -2668, -2020, 8291, -2714, -4607, - -923, -2077, -2878, 1687, -10457, -1575, 2172, -3974, - 5795, 1748, -1852, -5143, 4763, -5097, -2840, -1851, - 2634, 5970, 180, -3326, -1655, 1226, 375, 5137, - -2678, -5246, 4327, -3670, 9956, -1976, 2189, 2952, - -6785, -697, 1129, -5768, -5819, 6532, 3650, -1711, - 3857, 47, -9618, -1941, 2524, -1244, 7242, 11646, - -64, 2304, 201, -3707, -700, 149, 2692, -805, - 3978, 2738, -977, -1004, -5776, 12779, 7454, -353, - -4731, -3866, 7076, 146, -3302, 3065, 1955, -343, - -1459, -426, -5906, -1318, 500, -1014, -1002, -2090, - -2924, -20521, 2610, 1581, 397, -3380, -2885, 510, - -1147, 3398, 1914, 99, -119, 144, -3128, 2445, - 1791, 397, 3734, -80, -3410, -3798, -1142, -1515, - -2615, -1540, 5193, 2187, 940, 4969, -2334, -16589, - 325, -2186, -4567, 5121, -894, -6848, -6002, 1832, - -568, 8259, 833, 3420, -4459, -748, 3442, 4358, - -3041, -10203, 9303, -1511, -4821, 1950, -966, 3573, - 453, 705, 16238, -901, -163, -2866, -104, -1767, - -1779, -1249, 3251, 1975, 1254, -838, -390, -3150, - 1020, 2526, -2025, 662, -2817, -1338, -855, -3442, --21123, 241, -134, -952, -588, 2572, 2080, 8153, - 114, 9732, -6774, -5266, -2462, 2286, -599, -426, - 1396, -7051, -1228, 312, -4495, -2525, 4649, -1305, - -1106, -2366, 2232, 4065, -18674, -1295, -3259, -1004, - -5136, 206, 1177, -5130, 2394, 2518, -1381, 2564, - -138, 4341, 16988, 2546, 6782, -3433, 850, -970, - -255, 1308, 2228, 1704, -1283, 1452, -2608, 1487, - 3106, -2267, -2998, -6814, 1654, 21195, 1555, 968, - 154, 124, -1258, 714, -407, 44, 247, 992, - 2228, 2824, 1435, -341, 1212, -1612, 6126, 1636, - -8368, 578, -5418, 217, -191, 204, -7147, 5110, - 3766, 5055, -5979, 6683, 368, -3597, -4595, 7630, - -3611, -2384, 1369, 6995, -3299, -53, 2036, -4654, - 4259, 9618, -1012, -2964, 4397, -2112, 11885, -1648, - -942, -3474, -544, -1410, -1958, -1535, 2981, -1591, --16787, 335, 4609, -1990, 3821, -645, 1842, -64, - -3485, 3202, -374, -58, -1410, 7304, -1958, -2142, --11412, -2533, 513, -6149, -6679, 2152, 3153, 5102, - 2216, -1361, 2260, 4863, -7031, 1538, -5250, -2511, - 96, 3339, -3447, -3708, 7168, -4168, 838, -3134, - 3228, -1531, -5598, 14125, 208, -2150, 819, -1085, - 12282, 6714, -2778, -9252, -5117, -6623, -1711, -4253, - -6306, -1292, -1370, -1027, -908, -2863, -1832, 4645, - -722, -284, -161, -5106, 7110, -12494, -1514, -5453, - -3308, 3520, 1101, -1096, -2325, -746, -33, 2645, - -4458, -797, -684, 1514, 1716, -6204, 6580, -3427, - -650, -10493, 4868, 5833, -2385, -274, 1530, 3892, - -1940, -1415, -2389, -11499, -2064, 937, -333, 1361, - -1583, 5458, -2296, -3263, -8344, -4236, -6357, -2372, - -3115, 1336, -2184, 194, -4262, -7838, 6946, 4535, - 749, 7332, 67, -327, 273, 3211, -1825, -357, - 7039, 3346, 6282, 488, -3940, 10196, 6463, 327, - 4407, 909, 889, -4943, -622, -4049, 2532, 1870, - 652, 1778, 663, 3063, -1012, -1390, 4162, 20486, - -86, 3166, 325, -1912, 511, -634, 1262, -4719, - -1490, 6767, -3314, -125, 4490, -10334, 5386, 9932, - 781, 290, 2198, 1695, 3790, -1878, 7760, -300, - 2021, 5508, 2200, 232, 7138, 1370, -3268, 3496, - 13934, -1230, -2303, 958, 141, 3348, -2867, -987 -}, - -.cb0808s1 = { - 9313, 734, 6610, -3629, -12020, 5317, -244, -1858, - 2, -1812, -6486, 892, 926, -236, 1016, -1249, - -469, -238, -1908, -10594, -4704, -907, -7746, 3847, - 564, -5956, 3395, 371, -5136, 4001, 1180, 769, - -555, -1872, -2943, -1744, 8620, 1485, 9901, -1392, - 3425, -7940, 151, 376, 1984, 3031, 3815, -974, - 537, -7038, 1964, -5625, 4457, -10214, -1787, -2768, - -8514, 176, -3692, 6441, 3148, 602, -2000, 13769, - -2792, 1104, -2067, -6219, 1515, -288, 3240, -5490, - 11589, 3742, -2343, -1752, 3701, 7525, -1676, 845, - 6895, 2884, 3540, 2454, 1010, 2454, -5761, 2035, - 3369, -9628, -862, -7060, 1802, 5676, 2396, 2757, - 5891, -701, -11896, -4061, 7932, -272, 2562, 83, - 560, -5180, -2223, -356, -3343, 2874, -1370, -7612, - 1773, 2006, -4258, 5312, 342, 8196, 4939, 519, - 3568, 4420, 2768, -11872, -3021, 1893, 1690, -5483, - -8129, 7540, -116, -2064, -4473, 1141, 1930, 656, - -7728, -2742, -3276, 2782, 2860, -6082, 5198, -4751, - -486, -789, -16932, -566, 5116, 1196, 832, 4282, - 78, 3088, 2768, 2125, 1027, 1712, 310, 808, - -1595, -106, 3174, 4598, -2945, 1551, -7688, 620, - -1640, 339, 4538, 3339, 532, -351, 260, 249, - -2135, -543, -18362, -648, -3871, 5514, -1782, -11301, - -374, -2078, 1610, 50, -4439, -2546, -3058, 839, - -9221, 2618, 1790, 103, -1061, -363, 285, -3542, - 503, -437, 30, 1382, 75, -2852, -1028, 3095, - 4318, -2316, 739, 801, -22765, 2162, 913, 1698, - 149, 2049, -313, -803, 3393, -1476, 4396, -4003, - 854, -1344, 1062, 10009, 6332, -8522, -2616, -9904, - -390, -3146, -2951, 4222, 5538, 495, 3776, -13684, - 4687, -2187, -905, 4997, 6209, 4775, -1234, 1956, - -4607, 3006, -370, -670, -12448, -5802, 8151, 140, - 1485, -6340, 2139, 1231, 22, -212, 2090, -676, - 2366, -701, -4113, 365, 2970, -577, 918, 7324, - -709, 2035, 5162, 7232, -13287, -3259, -908, -1900, - -4255, -2590, 318, 4891, 696, -40, -1647, 1572, - -1221, 4896, 5241, 49, -2083, -5068, 7645, 8978, - 1628, 2895, -4930, -8068, 2266, 2025, -1868, 3250, - 2642, -785, -14571, 9979, 3481, -2246, 1154, 2646, - 2616, -2033, -2936, -1300, 2490, 879, -1237, -1228, - -724, -1780, 524, -6619, -3339, -2526, 3533, 844, - 2946, 2208, -3522, -12411, -3062, 2380, 448, 604, - -4708, 2403, 1914, -58, 149, -3704, -2019, 4246, - -7020, -3197, -712, -2219, 10036, -2776, -3166, 2648, - 2947, 3386, 6445, 1587, -268, -536, 1895, -9005, - 10791, -982, 8215, 6414, 5166, 4751, 160, 3050, - -865, 6216, -1187, -7077, 1640, 5078, 4354, 1762, - -3869, 1174, -149, 1078, 1884, 5149, 15091, -432, - -2441, -1102, -1194, 1078, -1535, 8289, -2702, 4007, - 694, 72, 685, 2816, 13244, -422, -7094, 432, - 2044, -12004, -276, 2174, -908, -4784, 5725, -250, - 22, 5116, -2, 2686, 955, -8509, -7697, -3735, - 672, -1202, 4299, 4284, 12352, -2362, 5757, 1317, - 4293, 508, 3050, -524, 1097, 3346, -537, -2440, - -1596, -5659, 4188, -625, 1659, 3061, 2791, 1712, - -2991, 966, -16903, 610, -3314, 4160, -3750, 580, - -3407, -340, -11829, -520, -1625, 2905, 674, -147, - -5284, -4278, -5021, 4635, 6299, 2207, 2595, -7811, - -68, 4107, 4314, -1540, -11044, -2214, -803, 232, - -7602, -95, 1130, 4991, -361, 1675, 4487, 3607, - -6192, -130, 137, -1440, 2826, 178, -13834, -984, - 1149, 1230, 1587, 1571, 3286, 5293, -2259, 2021, - -6211, -7608, -2710, 2502, 4315, -539, -8530, -746, - -654, -4003, -5917, -3728, 4522, -10350, -1266, 210, - 5078, -2988, -3866, 3919, 969, -1063, -6300, -4584, - -2420, -2094, -884, 2338, -3150, 5461, -1145, -734, - 1644, 2183, 19114, -1144, -2313, -404, 1236, 3583, - 134, 1802, -4088, -2795, 681, 3738, 1831, 16571, - 917, -2290, -3648, -1588, -158, -528, -792, 394, - -7432, 2446, 402, -391, -73, -1398, 1286, -6503, - 5216, 1094, -939, 1673, -2038, 15842, -1971, 4160, - -1664, 7231, 642, 5770, 4209, -1839, 220, -266, - 165, 2055, 5222, -3344, -6544, 5412, 1514, 586, - 1591, -15256, -2715, 941, 1308, -9170, -2863, 4935, - -2913, -1291, 2791, 7967, 14, -1101, 3774, 3580, - 848, 1337, 1138, -2839, -3564, -5300, 12429, 14, - 1466, -7114, 1198, -3474, -237, -2577, -1305, 445, - 1069, -174, 1684, 3902, 229, 5842, -690, 978, - -754, 1182, -859, 21078, -185, 710, 797, -2155, - 367, -2168, 1002, 3805, -924, 468, -2322, -3590, - 1608, 3387, 18, 1536, -858, 642, -7964, 17689, - 9843, -4878, -3003, 7373, 5934, 4286, 10484, -63, - -4629, 974, -2227, 2602, 3810, 1905, -1668, -2130, - 2020, -2360, 2853, 612, 5070, -1248, -868, -497, - 3478, -1937, -3006, -645, 3589, 3019, -3293, 16469, - -5243, -2918, 1788, -2569, 3717, -9630, -1352, -3870, - -416, -4190, -8863, -6888, -498, -814, -783, -4625, - 5841, 1562, -2173, 481, 280, 816, 4742, -9962, - 11799, -2029, -2460, 4972, -600, -1452, -1901, -2122, - 3130, 2686, -819, -2366, 866, -2093, 1052, -58, - 284, 3830, -4738, -4114, -1321, 1307, -2820, 4915, --11701, 522, -1982, 7024, 8403, 1762, -46, 532, - 5097, 5013, -615, 3086, 2089, 6899, -1107, -4047, - -2903, 5356, -4802, -965, 6706, 3895, 9022, 1388, - 10971, 5927, -2954, -965, -3473, -5177, -2654, 3418, - -5315, -16695, -6587, -416, 404, 1230, -2586, -3292, - 1390, 14, -481, -4446, 1335, 109, 1060, 3958, - 1275, -5655, 1253, -2411, 207, -12550, 6208, -2447, - -3415, 2503, 848, 3094, 9336, 2647, 2455, 2238, - 2356, -2132, 5347, 915, 2227, -103, 5832, -2504, - 7562, 9568, -6100, 4091, 2668, -1722, 287, 6763, - 4058, -387, -2060, 5522, 3184, 4766, -158, 650, --11284, 11841, 6230, -4232, 5308, 3174, 4926, -2970, - -4761, -980, 117, 1944, -1974, -5484, 6534, -266, - -7222, 924, -2654, -588, 9609, -2337, 1892, -2110, - 5088, 1856, 7964, -4029, -940, 1429, 805, -4705, - -1362, 892, -189, -8354, 3259, 194, 767, -2877, - -4165, -990, 12185, -160, -2002, -1384, -5388, -1604, - 226, -6353, -4157, 1773, 2360, -4356, -730, -5462, - -4054, -15669, -1528, -394, 4101, -203, 2792, -787, - 3391, -299, 6384, -1630, -7186, -12765, 4618, 934, - -401, 2790, 2284, -4932, -1260, -6009, -2590, -2285, - -1289, 3366, -4192, -4462, 32767, -3135, -1888, 67, - -2874, 150, 4760, -1571, 584, -2187, 358, -1733, - -1286, -4573, -2003, 1872, 940, -1942, -255, -8856, - -1320, -3348, 4854, -509, 2836, -14, 2490, -1537, - 882, 1188, -3132, -15209, -1633, -44, -2827, 368, - -1099, -1073, -467, 6318, 5863, 2840, -5200, 569, - -2984, 6587, 9596, -4924, 457, 4879, -4449, 3528, - 1868, -3894, -3905, 15420, -2590, -599, -4975, 3892, - -1454, -616, 1890, -2700, -3268, -1386, -1065, -3078, - -2454, -1902, 4726, -34, -4218, 1619, -3074, 5540, - -6392, -3570, 2687, -8742, 333, -106, 2326, -1737, - -3775, 397, -3553, -6632, -6066, 9567, 2904, -889, - 1136, 1295, 19390, -268, -3127, -180, 1696, -814, - -775, -4914, -456, -758, -866, 1102, -3740, -374, - 469, -6902, 1440, -10243, -6221, -4797, -3074, -1142, - 297, 5069, -1547, 5474, 716, -454, 3806, 4100, - 2901, -2169, -744, 5032, -5586, -2986, 2286, 2414, - 7860, -2672, -46, -10046, 5348, -1018, 1016, 9142, - 4543, 5587, 2228, -2684, -4594, -2457, -1850, -3651, - -1806, 4826, -11686, 1940, -3529, 1078, -5234, -2420, - -83, -2322, -5134, -775, 677, -9257, -864, -915, - 4494, 411, -4820, 5999, 4472, 5823, -4597, 3121, - -1868, -1539, 2338, -4249, 1154, -13422, 791, -1235, - -1240, 364, 177, -1508, -2527, -2949, -2062, 118, - -3115, 293, -1927, 18644, -1100, 152, -2528, 1914, - -1380, -1624, 302, -831, -920, 320, -879, -1252, - 813, -11, 6960, -522, 3092, -119, 1486, 3068, - 6690, -3079, 13305, 6342, 937, 1632, -1026, 1896, - -2335, -3961, 5510, 2782, 187, -2448, -1251, 756, --15856, 3179, -1155, 808, -1748, -6593, 1494, -3122, - -98, -3808, 491, 1752, 3188, 2158, -1924, 763, - 1165, 148, -3161, -1284, 18082, -195, -1125, 845 -}, - -.cb0808m0 = { --18656, -461, 236, -1122, -796, -101, 851, -3748, - 1374, -8549, -3366, -1482, 1026, 2046, 4394, -521, - 232, -486, -1656, 32767, 1954, -1183, -130, 392, - 194, -868, 2883, -168, -1674, -910, -34, 819, - -1105, 1628, -4871, -585, -1170, -572, 451, 3911, - 10770, -35, -4126, 7124, 7110, -860, -3914, -3294, - 272, -647, 220, 11965, -3378, 2726, 1990, 1624, - -3689, 9884, 2394, 3096, -518, 5169, -4018, 3108, - 168, 1256, -410, -3851, -11176, -10479, 2042, 1421, - 1488, -992, -1562, -653, -1191, 2246, 467, 4732, - 154, 729, 7244, -18, 1313, -51, -1824, 1218, - 1473, -6763, -11270, -4295, 4118, 1043, -5782, 1370, - 46, -11027, 4086, -1501, -11, -621, 464, 781, - 13680, 257, 554, 3119, 750, -1857, 1046, -1252, - -512, 739, 14811, 12642, 3841, 2824, 163, 1620, - 39, 4766, 1411, -2197, 525, 658, 419, 5, - 92, 1544, 290, -2038, 10603, -5764, -3335, -6629, - -2579, 4020, -3107, 2779, 849, 5678, 260, 2804, - 99, 1339, 544, 1438, -450, -598, 764, 1568, - -1034, -4560, 2604, -18205, 1644, 1003, -675, 3217, - -334, -832, -1452, 322, 608, 300, -4776, -812, - -36, 627, 1654, -248, -838, 21571, -89, -1626, - 530, -1151, 9440, 522, -6138, 2213, -10095, -562, - 1000, 5037, -122, -3, 7064, 397, -2118, 362, - 15791, -1047, -15010, -1527, -1356, -2805, -560, -3148, - 266, -45, 1324, -3312, -1772, 2382, 189, 6537, - 124, -1272, 156, 588, -2678, -3106, 2828, -3684, - 689, 3884, 4650, 192, -323, -5426, -722, 11486, - -607, 3591, 4299, 2117, 362, -9114, 11700, -3391, - 2357, 7639, 2197, 4350, 2970, -2525, 169, -6112, - 91, 1520, -19, 1558, -4588, -837, -8163, 897, - -7992, 2080, -3102, 774, -10592, -314, -137, -524, - 87, -799, -111, 74, 1312, 862, 266, 243, - 199, -288, 1205, -829, 1650, 2880, -24776, 3867, --13101, 597, -9778, -2084, -3089, -1112, 548, -638, - 3727, -446, 4877, 2099, 68, -2736, -4914, -7103, - 263, -9228, -782, -2109, 1088, -1881, -1424, -30, - -1353, 586, 4085, -3573, -11921, 2366, 516, -1028, - 834, -234, 2150, -15893, 2305, -3619, -2567, -8366, - 610, 2946, -2383, 2293, 946, -3550, -6770, -1481, - -758, -864, -232, 2855, 40, -2330, 2069, -345, - 1801, -589, -1241, 647, 6988, -2625, 14308, 2801, - 759, -2740, -680, 964, 365, -506, 22268, 1766, - -202, -2751, -293, 3754, 1280, -521, -3355, 4615, - 594, -1783, -39, -46, 48, -2638, -551, 2548, - -1880, 3730, -1726, 939, -345, -7, -1630, -23405, - -1002, 5655, 2100, 440, 1682, 1020, -594, 344, - 1511, -1286, 5518, 473, -11398, -4552, 720, 4701, - 7726, 126, -1953, -484, -1648, -1766, 1589, 996, - -688, -381, 1678, 1498, -528, -860, -667, -823, - 32767, -463, -243, -1242, 1074, 2460, -1411, -459, - -1533, 1462, -2603, -784, -391, 338, 3444, 2170, - -924, 949, 1972, 1520, -3062, -671, 12908, 2636, - 2805, 722, -12016, -26, 616, 1192, 1193, -1028, - -128, -22850, 191, 408, -3105, -592, -440, 1264, - -2580, 847, 850, 2300, -278, 126, 2214, -2693, - -21, -194, -594, -533, 45, 570, 38, 636, - 1276, 171, 29846, 648, 911, -358, 300, 602, - 413, -10167, -54, -1353, 42, -1770, 491, -12154, - -1808, 26, 425, 2009, 910, -8134, 362, 2001, - -114, -2586, -1049, -249, -312, 160, 1677, 27043, - -44, 160, 834, 243, -606, -272, -979, -1605, - 105, -491, 754, -230, 2442, 24, -5139, -395, - -3562, 14436, -1208, -3232, 2555, -12980, -906, 429, - 217, -432, -1263, -244, -225, 912, -64, 780, - 1101, 854, -240, 308, -28630, 518, 32, 976, - -8642, -3041, 1801, -742, -1513, 128, -3189, 857, --14277, -1802, 1229, -68, -565, 65, 4094, 1614, - -8254, -1153, -640, 16225, 3508, -1383, -3882, -347, - 1346, 3845, 2665, 2340, -1862, -5318, 1402, -1352, --21682, -694, -1182, 286, -806, 2133, 1848, -532, - -3750, 7564, 1054, 284, -3742, 2559, 2748, 3408, - -1544, -342, -22578, 1225, 958, 2559, 267, 378, - -3608, -1404, -1669, -13, 1135, 153, -625, 1436, - 211, 556, 739, 1094, 10452, 850, 5128, 11469, - 121, 4937, -3643, 1371, -373, -6686, 229, -3256, - -75, 1304, -1023, -452, 288, 12709, 13572, -501, - 1840, -1044, -2014, -4077, -2726, -1010, -3826, -629, - -466, -923, -847, 5784, 898, -12036, 1253, -1741, - 1546, -3710, 2782, -3430, -1810, 263, -8254, 3126, - 55, -376, 202, 968, -1686, 944, -15300, -2664, - 1393, 783, -11080, 1714, -1666, -1064, -4859, -2344, - 334, 1313, -1209, 877, -1828, -2130, -3057, 340, - 8030, -3222, 11622, -5620, 1469, 3340, 2862, -3945, - -868, 351, -1314, 2277, -2346, 12384, 996, -2460, - 1810, 703, -2158, 3168, -9887, 8754, 3503, -1414, - 445, 850, -30, 2389, -617, 3271, -1606, -5633, - 2993, 10009, 5704, -11589, 4278, 1304, -2418, 479, --16596, -12349, 2915, 327, 895, 1278, 1412, -310, - -653, -1287, 880, -4294, 38, 2179, -2074, -1810, - 198, -1544, -8008, 2456, -2821, -3223, -3713, 11763, - -2081, -141, 4833, 1652, 3598, 551, -1655, -1154, - -60, -302, 739, -1494, 2595, -1006, 2665, 10834, --11270, -2996, -636, -446, 1816, -1539, 4149, -184, - -100, -55, 265, 2207, 639, -162, -2210, -626, - 605, -21149, 2163, -970, -330, -4655, 3396, -3092, - -544, -650, -304, 93, -1484, -888, -8982, 1871, - 1701, -1423, 1671, -11, -1287, -14292, 592, 1040, - -622, 13202, -660, -12745, -2836, -1832, 3481, 1546, - 235, -646, 2132, -602, 2391, 1534, 3599, -4932, - -296, -1855, -2075, -2646, -219, -10248, 1161, 5955, - 6954, 9109, 3498, -5932, -1787, 373, 1234, 1244, - -813, -76, 9083, -5120, -499, -1774, -2150, 10601, - -170, 1160, 982, -597, 95, 151, -534, 6554, - 840, -958, -720, 2066, -50, -2877, -74, -2068, --24760, -725, -357, 1273, 1941, 2525, 46, -819, - -230, 1030, 2291, -287, 1092, -2315, 427, -19, - 448, 1698, 9797, 10962, 3034, 2622, -2652, -1128, - -194, -180, -1176, -1794, -22248, 244, -3, -1856, - -1054, -2751, -459, -62, -433, -2274, -1790, -192, - -720, -421, 55, -721, 1960, 1094, 2500, -2353, - -480, -784, -1221, -505, 1738, -9960, -10772, -13657, - 122, 387, -667, -454, 988, 30780, -757, -2319, - 878, 962, 753, 1306, 716, -771, 539, -705, - 508, 1915, 2114, 937, 447, 935, -1432, -1143, - 4435, 11759, -2442, -53, -10601, 1979, 5419, -2296, - -172, -5987, -1168, -2012, 2257, -1451, 97, -1253, - 5548, 884, -14448, 3134, 2549, 172, 5404, 869, - -83, 597, -12416, 762, -1035, -805, -1369, -804, - 664, 9644, -4329, 1130, -1526, -2900, 628, 620, - -6436, -2370, 2107, -11836, 37, 864, 2105, 314, - 216, -529, 810, 3141, 3716, 7019, -2653, 1466, --14940, 13128, 1218, 2287, -145, -443, -923, 476, - 2411, 5428, -611, 2212, 1450, -3042, -4750, 3562, - 587, -15378, -15151, 600, 1029, -2353, -934, 1986, - 1444, -2171, 1020, -700, -1508, 195, -2466, -798, - 16460, -2164, 520, 2711, -13832, -2024, -871, -5268, - 3556, 117, -416, -8, 2128, -1570, 2052, -3169 -}, - -.cb0808m1 = { - 16492, -295, 2556, 1303, -440, 7584, 3305, -3422, - -1196, -1809, 2142, -1292, 1048, 314, 1945, 578, - 1080, -255, 1109, 617, 1597, 198, -29081, -243, - 54, -33, 76, -418, 1332, 475, 1495, 1554, - -782, 308, -1286, 1044, 300, 1544, 646, 9441, - 2577, -11140, 1421, 1107, -483, -590, 625, 8544, - 446, -1814, 1714, 685, 9620, -4981, -3100, -724, - 8439, -2333, 506, 3557, -1160, -2199, -659, 4107, - 8620, -1406, -3745, 1729, 10756, 868, -82, 2584, - -3140, 3632, 2617, 3880, -1175, -163, 1864, -980, - 551, 201, -433, -1464, 708, 1926, -8471, 3870, - -2376, 15567, 2112, 753, -2450, 72, 1131, 2932, - -139, 6392, 1547, 3, 625, -823, -1750, 811, - -977, -1389, 1300, 1184, 399, 4684, 196, 3679, - -1672, -218, -11023, 98, 492, 4072, 1213, -2004, - 3602, -1787, 1288, -9442, 4157, -4267, 3509, 5317, - -574, -11094, 1078, 6240, 1593, -12773, 408, 3960, - 1116, 1517, -816, -577, -696, 554, 1645, -936, - 83, -20255, -754, 1460, 1110, 1412, -757, 377, - 2373, -1608, -1414, -1028, -3152, 1534, -4145, 2274, - -286, -7058, 2286, 4013, 2515, 2681, -5602, 0, - -1740, 257, 756, 11496, 954, 4513, 3968, 4851, - 278, -511, 829, 2853, -9743, -3723, -1550, -444, - 4256, -679, -11411, -4290, -1470, -4191, -952, -239, - -198, 1361, 9527, 1481, -981, 1403, 991, -255, - 9326, 1832, -1936, -135, 1123, 2756, 1932, 2543, - 795, 12612, 2429, -498, -13185, 3812, -1628, 196, - 1822, 4333, 2760, -676, -2902, 1244, -1974, -7046, --12216, 1503, -2176, 1916, 365, 636, -11348, -5030, - -3319, -3794, -1016, 1157, -4158, 3424, 344, 4494, - 812, -3074, 4356, 293, -3463, 1232, 1746, 2696, - -8269, -961, -4316, 130, -4278, -14007, 3025, -2703, - 179, -10176, 1511, -1460, -1100, -1171, -1575, -2596, - -2026, -11400, 2689, 1480, 743, -1669, 2728, 742, - -60, 11452, 84, -662, 1424, -15103, -410, 2141, - -1664, -1378, -122, 97, -358, -820, 382, -3865, - 374, 1698, -21, -752, 595, -8771, -731, 9368, - 1698, -2586, -6790, -2507, -1776, 4993, -3867, -2807, - -190, 14465, -13938, 3095, -1198, 374, 1682, 1888, - 286, -576, -2094, 454, -690, 1396, -1139, -422, - 405, 238, 1718, 2048, 13448, -151, -247, 202, - -900, -5630, 3121, -10988, -1615, 1955, -3901, 3360, - 1429, 3928, 1951, -1099, -435, 1572, 1500, 19176, - 731, -439, 3686, -3039, 244, -4270, -34, 1289, - 296, -406, 2216, -1400, -1946, 264, 1536, 2992, - 54, 892, -181, -1545, 278, 24923, 989, 1301, - -1279, -188, -198, -661, 612, -1520, 2355, -12972, - -694, -560, 1364, -2988, -6236, 2555, -6630, 1423, - 440, -598, -1092, 304, -2529, -1698, -909, 2560, - 844, 768, -2988, -661, 18432, 1158, -639, 5070, - 11015, -14, 2313, 756, -1941, -10986, -490, -5235, - 2646, 2406, 170, -546, 337, 6499, -4450, 5598, - 299, -504, 14322, -972, 9356, -2056, 8812, -1599, - -1931, 2084, 119, -983, -305, 1437, 403, 2651, - -159, 229, 209, 1438, -1789, -1159, 1017, 416, - 408, 454, 858, -652, -1554, 1198, 18278, 122, - 433, -165, 162, -10532, 11563, 4754, -2022, 4246, - -1396, -2417, -1796, -1496, -1279, 3877, -1217, -770, - 983, -609, 1766, -184, -5664, 546, 7948, 1978, - -250, 4350, 3498, 2797, 802, 846, -12628, -1092, - -240, 781, -11252, -955, 9944, -222, 1177, 1262, - -534, 1790, -7396, 1452, 4251, 303, -3714, -2295, - -290, -227, 672, 22690, -622, -466, 1599, -496, - 326, 871, -1948, 148, 449, 214, -2175, 713, - 394, 1921, -28716, -786, 1083, -641, 1232, -246, - 1572, 1575, -879, -2962, -57, 369, 1633, -1457, - 1194, -1222, 304, -955, 104, -1249, -935, 135, - -758, 3483, -1190, 1457, 1130, -1284, -3709, 18042, - 6, 25, 1233, -328, 347, -512, 2071, 328, --18037, 4582, 3841, -434, -745, 332, -576, 3006, - 336, -11505, -646, 3509, -996, 1270, 2041, 1353, - 1193, 2976, 11569, -3165, 1450, 4351, 2522, -10022, - -6, 12602, 874, 518, 475, 1251, -3290, -2674, - 4802, -11794, -946, -426, -2846, 1619, 1105, -1022, - -1, 1759, 646, 10347, -2937, 13505, 1104, 614, - 1149, -800, 2377, -115, 792, -948, -2431, -1779, - -1142, 809, -3130, 447, -15516, 313, 11235, -1346, - -2426, -2737, -1738, 2236, 1094, 802, 1323, 3612, - -213, 1383, 2800, 10394, 1210, -2360, -10203, -1991, - -102, -2669, 2303, -2184, 1830, -1158, -5633, -4083, - -252, 311, 612, -331, -2786, -12421, 9994, -6006, - -4996, -954, 1014, -1147, 860, 1252, 1114, -2069, - 266, -230, -591, -4442, 230, 20603, 1386, 1130, - -1468, -3600, 2168, 836, -1754, -511, -542, 216, - 26, 3476, 1165, -4293, 3098, -245, -579, 1830, - 2248, 5326, -18357, 397, 5466, 734, 3920, -3678, - 319, -1062, -610, -7509, -1064, 1456, -5729, 1088, - 9099, 2266, 241, 201, -10017, -1545, -2799, 1491, - 27098, -60, -1736, 1387, 859, -1474, -79, -1122, - -971, -1302, 906, -1133, -2659, -296, 1344, -2698, - -448, -1476, -212, -1585, 1310, 14353, -2165, -2229, - -656, 5219, -3266, -1850, 7942, 4997, -2295, 519, - 608, -9498, -1700, 1770, -15308, 1286, -2914, 2252, - -717, 2136, 2478, -3747, 2362, -5, -237, 2334, - 701, -774, -672, -20, -599, 623, -700, -713, - -979, -29926, -1090, 848, -141, 1273, -711, 1782, - -221, -103, 170, -185, -1059, 3066, 1321, 1182, - 3641, -217, 1959, 11806, 2390, -10312, -2575, 1612, - 596, -352, 2197, -2041, 2385, -898, -9363, -1144, --10896, 20, -7842, -1047, 3687, 2147, 2584, -249, - -72, 32767, 1936, 446, -889, -845, -896, 1269, - 448, 327, -3411, 4, 702, -1900, -646, 799, - -770, 662, -911, -856, 287, 1667, -108, -64, - 16, 1578, -2059, -27327, 112, -188, 2504, -692, - 250, 360, 564, 868, 4147, 1340, 18080, -3584, - 445, 364, -2623, -412, -2918, -116, 2611, -2396, - -44, 10934, -1512, -1166, 239, 913, 190, -14681, - -767, 2610, 2931, -2389, 3590, -1680, 6287, -531, - -616, 1317, -1034, -900, 871, -329, 467, 1200, - -1914, 1108, 3150, -6878, 544, -14411, 2807, 5427, - 13361, 1448, -1753, 524, -5851, 1467, -1866, 6888, - -8742, 1372, -1515, 4883, -2248, -1042, 4628, 10768, - 149, -358, -1287, -1289, 32767, -1137, 941, -2112, - 451, -1436, 174, 294, 475, -3667, 1610, 1641, - -599, 626, 2058, 671, 1626, -985, -123, 2040, - 421, 1797, 18448, 2538, -359, -5042, 3096, -1136, - -320, 1823, 30, -12002, -1297, -850, -418, -1497, - -1761, 5073, 10944, 212, -4713, -1614, -1752, -2135, - 483, 1043, -1989, -293, 39, -1049, 67, -7482, - 712, -5358, 896, 12460, -1744, -1793, 1538, 3577, - -6, 418, -72, 1072, 1367, 1080, 3564, 1468, - 482, -1298, -6442, -299, -12934, -757, -4199, 3842, --11331, -1216, -206, 1598, -1135, -3240, 3294, -286, - -540, 777, 1188, -1189, 4516, 2638, 2071, 9702, - -900, 1002, 18707, -705, -1856, 1185, -4832, -1694, - -3502, -2324, -2826, -4600, 1996, -3110, 110, 117, - 405, -16854, -510, -14725, 1699, 1922, -2117, -2718, - 45, 1064, 507, -1781, 2106, -2310, 1239, 5860 -}, - -.cb1108l0 = { - 2354, 8016, 12528, -947, -348, 1760, 2054, -3960, - -2125, -3578, 3932, 1647, -3316, 6053, 392, -3128, - 3209, -2445, 463, -2835, -1555, 1259, 296, -1465, - 1839, -4811, 420, -215, 469, -1013, -272, 185, --27061, -1154, 8, 298, 259, -953, -555, 472, - 617, -1127, -673, 982, -398, -1681, 328, 882, - 614, 800, 431, 84, 880, -240, 15758, -14324, - 1301, 1578, 932, -694, -1456, 2435, -1651, 1464, - 227, 1527, 527, -128, 698, 2405, -726, 1489, - 1016, 1938, -1897, -1478, -238, 932, 2507, -519, - -1147, 557, 2334, 700, -12914, 14861, 158, 255, - 1195, -883, 3359, -1045, 2095, 520, 249, 926, - 789, 1392, -185, -1654, 902, 9, -2166, -1916, - 543, -2126, 2842, -332, 1356, -344, 436, -404, - -174, -489, 858, 258, 229, -45, 327, -316, - -1176, -454, 115, -220, -458, -194, 271, -530, - 1572, -574, -25068, 167, 601, -1027, -1705, -3144, - -4231, -1636, -1012, -1002, -519, -825, -458, 945, - 546, 193, -17909, -156, -1067, 826, 338, 1152, - 562, -506, 848, 239, 188, 656, 97, -174, - -59, 242, 1946, -67, 745, 2043, 424, -192, - 574, -524, 1553, 566, 1480, -747, 487, -20623, - 872, -1089, 1034, 1357, 919, 153, 154, 498, - 54, 555, -989, 707, -85, -21, 700, -1424, - 90, 655, -399, 123, -709, 117, 438, 330, - -720, 190, 812, -138, 460, -32768, -162, -410, - -327, -122, -1208, -554, -502, -178, -309, 373, - 4295, -945, -5502, -2752, -6615, -1241, 1278, -1315, - -7683, -986, -419, -50, 2384, -4640, -6246, -11804, - -308, -446, 3486, -4824, 1736, -590, 960, 195, - 593, 164, 3355, 1655, 1233, 66, -787, -347, --13751, 74, -1209, -812, -4098, -102, 910, -1659, - -2036, -3147, -2075, -2605, -1240, 4499, 1727, -9484, - 549, 728, 3411, 1958, -4439, -1064, 5690, -1600, - -1984, 1695, -588, 4815, -138, -3380, -512, 1553, - 1978, 4310, -730, -402, 828, 2124, 14216, -222, - 2757, -8686, 523, 2516, 1017, 790, -136, -470, - -252, -717, 808, -1113, 13766, -114, -1182, 3053, - -5238, -2231, 1720, -511, -987, 1592, -1257, -2578, - 1777, 1075, 2367, -227, 2330, -672, -2620, -1449, - 2122, 362, 1249, 1338, -327, -21631, -1540, 24, - -2356, -656, 1981, -92, -207, -2188, 34, -457, - -1291, 1231, -460, -128, -396, 593, -671, -1513, - 136, -335, 560, -1121, 490, 1008, 948, 8629, - -3344, 467, 881, -5731, 1120, -300, -1432, 1227, - 1558, 990, -1078, 214, -922, -81, 1120, -15586, - -1176, 1203, -1911, 151, 1484, 1555, -421, -420, - -428, -762, 292, -59, 1075, -649, -841, 494, - 194, 27, -768, -356, 54, 163, -73, 293, - -1717, -392, 750, 234, 751, -111, 26858, 911, - -389, 451, 442, 260, -117, 270, 19, -2429, - 618, -962, 378, 10, -1954, -1336, 525, -258, - -693, -4155, 10265, 2924, -1361, 3197, 10199, 6870, - -2608, -5792, 619, -1994, -2035, -701, 2598, 465, - -575, 311, 175, 162, -1191, 162, -157, -147, - 325, 551, 536, -188, -290, -165, 343, 14, - -268, -27113, 278, 127, -233, -68, 606, 125, - 665, 438, -442, 2510, 800, -1991, -641, -386, - -1574, 78, 946, 189, 106, -2249, -268, -1708, - -1192, 986, 3076, 1807, 21, -5884, -964, 256, --15916, -1320, -2867, -3562, 491, 3502, -337, -1542, - 496, -3182, 1676, -2371, -4264, -2053, 14342, -5674, - 1744, 1813, -3731, -3761, 1350, 1783, -438, -920, - 2366, 1438, -687, 512, -1934, 323, -3158, 1775, - 1964, -6742, 10162, 7763, 1469, 1967, 851, 2742, - 7413, -3338, 742, 1854, 310, -192, -936, -1770, - -775, -976, -1532, -1436, -670, -4032, 1194, -1336, - -4369, 332, 604, 962, -27563, -972, 842, -743, - 275, 713, -251, -799, -1190, 372, -213, -423, - 202, 1189, -31, 1084, -974, 756, -148, -1669, - 640, -549, -339, -1506, -112, -598, -870, 410, --13307, 13141, -1911, 2308, -92, -776, 221, 1503, - 1578, 803, -308, -1672, -404, -83, -3517, -1327, - -606, -2426, -61, -513, 318, -1805, 2049, 1887, - -777, 1268, -542, -116, 3550, -18840, -2986, -979, - 2653, -2875, -922, -10520, 804, 107, 3234, -1270, - -608, 1042, 3599, 965, -342, -2096, -267, 1704, - -3939, 791, 2180, -985, 816, -716, -2661, 99, - 1523, 11902, -1782, 775, -12517, 3244, -3762, 2046, - -278, 1539, 2895, -2425, -10, 990, 1484, -1377, - -3399, -984, 3171, 1513, 696, -785, 155, -1072, - 414, 2016, -1932, -3124, -1126, 68, 3855, 1360, - 4074, 17596, 1714, -596, 4000, 1656, 230, -258, - 2266, 843, -1720, 4624, -714, 854, 696, 636, - -1357, 350, -1256, -523, 168, -9933, -766, 198, - 2680, 8060, 2168, -2789, -14255, 1444, -520, 169, - 1032, 1478, 294, -644, -320, 856, 1282, -216, - -1000, -925, 2, -890, 679, -629, 1152, -1329, --13941, -16385, -1050, -1022, 106, -1151, -41, -709, - 1771, -882, -729, -1420, 1544, -120, 386, -838, - -2744, 1559, 904, 273, -4221, -1065, -312, -1046, - 234, 830, 387, 172, -956, -332, 360, 408, - 125, 90, 348, 915, -264, 911, 263, 124, - -620, -612, 220, 164, 202, 124, -30252, -159, - 1006, -320, 283, -1641, -1312, -9057, 5525, 7520, - -2884, -12194, 2771, -1164, 1842, 1261, -582, 766, - 2498, 393, 953, -617, -756, -323, -1862, 1195, - -1326, -436, -965, 366, -6727, -1226, 9014, 400, - -1258, -812, -279, -404, 1621, 86, 1622, -16, - 96, -515, -257, -39, -134, 1843, -294, -491, - -908, -120, -720, -1162, -1555, 405, -134, 528, - 23596, -77, 183, -444, 2077, 955, 649, 2246, - 3236, 735, -1202, 7954, 9440, 6134, -7267, 28, - -3398, 500, 4965, -1230, 306, 357, 2942, -906, - -4733, 903, -3945, 4447, 1046, -1125, 465, 1183, --12710, -1018, -11302, 5177, -219, -6232, 1552, 2061, - -1372, -1290, -822, 295, 814, -3003, -527, -614, - -856, 802, 167, 1178, -494, -1625, 754, -1550, - 682, -1286, -480, -694, 86, -67, -1429, -1235, - -559, -311, 322, -308, -56, 296, -158, -24, - -748, -197, 26954, 1054, 209, -226, 165, 681, - -131, 341, 341, 1510, 615, 907, -264, 1355, - 388, 198, -5, 418, -783, 28539, 82, -559, - -459, -344, 279, -114, 966, -529, -423, 286, - -418, -766, 42, 186, 461, 418, -688, 2937, - 2793, 146, 1709, -665, 2022, 293, -1522, -2740, --15926, -600, -1503, -1732, -2827, -1027, 1702, 252, - -643, 470, -815, 858, -1954, 1190, 1847, -16, - 266, 29, 486, 25985, 139, 220, 433, -330, - 168, -362, -562, 180, 906, 386, -845, 664, - 1064, -616, -1498, -335, -164, -930, -854, -869, - -101, -204, 835, 117, -16034, -4478, 2634, 1629, - -1873, -1156, -373, -526, 2537, 967, -2433, -857, - 1264, -1670, 113, 845, 7654, -1343, 5245, -1605, - 2236, -1190, -48, 3340, -1981, -1606, -1369, -227, - -727, -570, 1136, 1868, 667, 92, -144, 531, - 949, -1086, 530, 1764, 302, 190, -28036, 182, - 825, 229, -656, 585, 444, 200, -1195, -1855, - -387, -781, 1156, 692, -1164, -517, -464, -275, - -328, 218, -970, 174, -384, -561, -38, -720, - -140, 1021, -271, -57, 463, -25313, -342, -40, - 26, 159, -854, 916, -1532, -1033, 265, 105, - -719, -588, 96, -435, -296, -226, 224, 357, - 30, 576, -66, -30037, -72, 374, 32, 256, - 304, -852, -706, 248, -741, -379, 980, 629, - 1344, 3858, -2211, -153, -3914, -3775, 1570, 718, - -1042, -1338, -4409, 1338, 5118, 5186, 3619, 2142, - 9081, -2784, 4169, 3598, 6621, 4562, -170, -614, - 1196, -1174, 5024, 721, -71, 267, 4, 25598, - -369, 356, 331, 1099, 377, -356, -938, 1161, - -863, 1107, -132, 222, 148, 1410, 908, 60, - 377, 1280, 468, 690, 454, 247, -4552, 6122, - -267, 2973, -5932, -6424, -4983, -4193, -3386, 1691, - 1349, 1419, -3730, 300, 12150, -2927, 1588, -34, - -2435, -271, -961, -1744, 1881, -73, -453, -788, - -798, 9166, 2744, 858, 342, 991, -287, 822, - -37, 1156, -1493, 723, -14127, -1755, 2029, -933, - -1276, 632, -5249, 464, -272, 1149, -290, 4693, - -728, -1475, 841, 10, -283, 92, -268, -295, - 358, 160, 405, 2, -381, 679, 716, -190, - 128, 275, 255, 123, -412, -453, -273, 26, - -174, -340, 644, -376, 27584, -25, 66, 3107, - -1707, 911, 500, -1029, 1029, -1557, 9020, -398, - -2512, -582, 1131, -16696, -429, -1284, -3, 2320, - -532, -302, -174, -146, -413, 2152, 1009, 42, - 402, -1471, 157, 5742, -782, -229, 2379, 646, - 2842, -1776, -463, -2749, -3617, -1710, -12281, -566, - 263, -3174, -2337, 9590, -1150, 2465, 4577, 2064, - -648, -2175, -1877, -674, -634, -338, 343, -1492, - 878, -530, 1072, 13670, -4542, 746, 9704, -4188, - -7076, 1179, -740, -589, -876, 268, -1080, -986, - -4584, 2692, 3032, -2067, 230, -3533, 944, -4950, - -1908, 1452, -255, -698, 1460, -606, -250, -154, --22303, -945, 1626, -588, -482, -1549, -129, 978, - -631, -722, 1094, 1771, -311, 532, -508, 696, - -1128, 1270, 854, -84, 4290, 414, 3351, 1061, - 931, -2936, -9606, -35, 2514, -1095, 567, -452, - -8520, 4037, -431, 2744, -2276, 2647, -1188, -454, - -400, -3698, -315, 11558, -667, 512, 162, -395, --13015, -11, -1944, -890, -14358, -3850, -4296, 1310, - -580, -248, 1305, 402, -1049, 115, 2085, -1797, - -1172, -321, -919, -313, -512, -131, 1619, 576, - 499, -2024, 130, 14, -76, -6324, 495, 2445, --16757, -2348, -2706, -1906, 2377, -2252, -619, -2579, - 643, -661, -1276, 935, 893, 992, -2204, -2451, - -395, -508, 1163, -216, -13034, -718, -1018, -1675, - -698, 710, -257, 2658, 1178, 2046, -2270, -2588, --14442, -1142, -1026, 2247, -536, 314, 123, -1175, - -673, 1576, -2600, 5, 964, 619, -1714, -14811, - -1502, -1646, -1151, -93, -11652, -222, 343, -2203, - -351, -928, -289, 2679, 2101, 742, 747, -2245, - 146, -1828, -2728, 1058, 1048, 3046, 242, 4432, - 246, 350, -13419, 768, -805, 1819, 14332, 1316, - -370, 391, -1421, -1426, -355, -812, -64, 196, - -2917, 1097, -1550, -1246, 436, -62, -813, 1350, - 555, -2236, -1589, 980, -1483, 10122, -2434, 7236, --15225, 1513, 2090, -1224, -83, -2821, 664, 658, - -3242, -1031, 1509, 2667, -160, -1315, 1060, 891, - 432, -1311, -2503, 1304, 1295, 1745, -722, -2496, - -4409, -3360, -2776, -2793, -4921, 12616, -1031, -443, - 1495, -2416, -4640, 4508, -2944, 2608, 1323, -394, - -415, -2111, -2065, 1030, -3636, -1338, 2916, -3007, - -3680, -3152, -115, 577, 2742, 785, -4429, -1945, - -304, -4883, -133, -3136, -1927, -576, 618, 1780, - 2568, -2102, -158, -3986, -1187, 280, 655, 162, - -1352, -5730, 15372, -1314, 1553, 274, -2873, 4221, - 4610, -4143, -13699, 2760, -1255, -238, 1487, 1583, - 1422, -2272, 4734, -6368, 795, -406, 1498, 1588, - -500, -2744, -875, 2080, 1901, 960, 344, 979, - -258, 952, 2526, -11785, 893, 669, 1361, 518, - -1368, 3854, 2539, 623, -1835, -4177, 2686, -2956, - -2804, 1121, -8890, 1377, 1125, -3990, 140, 3594, - 1757, 2271, 366, 1723, 2150, 13557, -1768, -1433, - -6632, -578, 3266, 2509, 7142, 680, 1532, 1318, - -1123, 5668, 1283, -412, -5404, 2893, -2647, -2695, - -1412, 340, -650, 863, 1895, 2867, 384, 626, - 856, 508, 1365, -295, 960, -26080, 234, -4, - 239, -412, -6, -765, 736, -30, 136, 912, - 538, -792, 413, 871, -437, 305, 30, -194, - 1105, -1113, 3550, -4854, 449, -549, -7626, 3706, - -3698, 1778, 1441, 2240, 73, 513, -3383, -2346, - -1372, 3955, 2973, 1175, -6087, 5071, -2135, 8552, - 4961, -1201, -1458, -2627, -730, 515, -756, 476, - -1104, 2115, -1276, 498, 336, -451, 809, -1030, - 556, -211, -70, -93, 89, -755, 296, 872, - -282, 380, -298, 2774, 660, 1339, -545, 429 -}, - -.cb1108l1 = { --13570, -9232, -673, 267, -819, 1633, -33, 623, - -850, -4376, -1135, 999, -262, 1928, 695, -1751, - -2793, 772, 5064, -1158, 280, -2144, 1313, 888, - -2482, 469, 2996, -1406, 12525, -1200, -1202, 939, - -3, 847, 818, -924, 135, -1308, -12000, -544, - -592, -3914, 441, 3372, 3188, 1314, -1836, -706, - -844, -1319, 1029, -1754, 172, 2468, -903, -889, --14602, -2054, 11694, -1980, -730, -1661, 214, 1243, - -337, -646, -95, 1432, -854, -236, 88, -2, - 514, -1643, -84, 3561, 302, 770, -1248, 480, - 664, 738, 1728, -1783, -2227, -702, -3582, -16641, - 1713, 1506, 660, -2471, 2061, -48, -3161, 1697, - 900, -1477, 558, 287, -5515, 1023, -1972, 999, - -1856, -3022, -228, 711, 1270, 2644, -648, 1064, - 3899, -1205, -754, 1080, 1262, 18, 860, 2274, - 655, 494, -221, -15647, 1334, -473, -1648, -341, - 3541, 3109, -1671, 639, -2491, 185, 477, -388, - 5198, -5680, 812, 700, 2180, -536, -19468, -2508, - 2592, 2901, 32, -1165, 1500, -422, -790, -1914, - 971, 111, 1226, -1302, 541, -3862, -832, 642, - 305, -3870, 8921, 570, 180, 1734, -1572, -891, - 17672, -756, 702, 2740, -647, 2122, 102, -1371, - 461, 454, 204, -307, -1248, -2330, 1353, -1783, - -1939, -601, 512, 2118, -2178, 254, 1190, -1252, - 923, 1166, 360, 320, 320, 1210, -142, -416, - 1260, -205, 1403, -1025, 19252, 328, 58, 21, - -1044, 1786, 2153, 697, -436, -1617, -869, -493, - -2419, -3102, 1995, 1519, -1799, -153, 2689, -665, - -1371, -915, 18486, 941, -2612, -1057, 1076, -3351, - -48, -1478, 575, 728, 130, -168, 40, 898, - 2141, 1518, -965, -1910, 896, 838, 1220, 416, - -1494, 1404, -126, 21472, 604, 1740, 102, -812, - -796, -734, 1082, -507, -468, -1732, 1171, 252, - 359, 436, -765, 791, 726, -810, 1838, -1798, - 5662, -2362, 1275, -2829, -4041, 1398, 2681, 480, - 13740, -752, 2252, 1306, -1026, 1834, 54, 9993, - 559, 1370, 711, 1918, -1757, 646, 16, -3262, - 2676, 1751, -2595, 4782, -1050, 2401, -15131, 1100, - 386, 708, -359, 455, -25, -950, 241, -482, - 268, 2327, -2766, -142, -1992, -566, -36, 990, - -6302, 3245, -1394, -1579, 760, -757, -2115, -8542, - -2945, -800, -4027, -3102, -1319, -1989, -1787, -426, - 590, 1031, 467, 31, 2674, 1686, -14352, 1174, - -1446, -813, -1267, 2919, 2052, -1574, -753, 3369, - -1090, 3830, 2042, 11376, 1140, 895, 1130, -720, - -1284, -2277, 49, -724, 397, 13201, -985, 1599, - -365, 1517, -496, 978, 2152, 1391, 1777, 3032, - -936, 280, 1719, -4551, 4874, -941, -160, 956, - -676, -229, -548, 183, -16606, -855, -3433, 1248, - -578, 2254, -532, 3081, -1406, -1859, -605, 1809, - -1001, -114, -1222, 3890, -609, 3114, -2430, -2142, - 440, 1780, 1606, -4211, 1047, -456, 8280, 9, - 5866, -1718, -932, -13049, -562, 3097, -583, -21, - -1972, 1254, -172, 527, 2282, 5064, -5391, 1074, - 357, 1845, 24, -996, 100, -50, 1098, 2905, - -417, -937, -439, 247, 18502, -2380, -2088, -402, - -580, 83, -282, -70, 969, 540, -219, -1132, - -1701, -195, -3030, -2748, -1974, -1304, -1909, 1080, - 1042, 1124, -128, 5816, 2303, 2840, -2420, 35, - 16550, 721, -2079, -1489, 1023, -654, 2025, 1479, - -185, -2449, 500, 3034, 2663, 3911, 1203, 998, - 594, -533, -163, -262, 739, 13, -426, 182, - 394, 350, -30055, -371, 150, -430, 147, -1122, - 43, -390, 298, 831, -194, 158, -114, -257, - -1346, -585, 206, -456, 478, -502, -1710, -1719, - -581, -536, 45, -861, 825, 1093, -255, -685, - 38, -20, 419, -594, 10, -1408, -526, -19191, - 196, -1496, 255, 1844, -8759, -3565, -1009, -926, - -818, -1195, 236, 2898, -182, 14344, -1384, 1064, - 1181, -1846, 543, -583, 170, -3305, -1187, -2406, - -40, -1051, -1071, -28, 1482, -1060, -1057, 3028, - -2023, 913, 1052, 980, -5158, 4642, -14067, 3920, - 1450, -4497, -1591, 842, -2222, -392, -42, -3546, - -258, -3566, 2595, 225, -2696, 4624, 2283, 1483, - -1506, 2164, 151, 380, -3207, -1086, -10594, 2005, - 2379, -2567, -925, -363, -1261, 13174, -73, 1168, - 2215, -1721, 726, 525, 1048, 322, -827, 2117, - 3890, 1346, -3512, 2243, 638, 2259, -1371, -2260, - 10590, 851, -1247, -894, 1871, -882, -1955, 3822, - -3654, -1730, 906, 2074, -548, 885, -2501, -1316, - -3275, -10694, 2031, 1077, 3013, -1105, 2951, 1907, - 1218, 194, 1860, -1662, 178, 915, 1092, 809, - -451, -610, -728, 799, -129, -101, -905, -2, - 2470, 1292, -137, 544, -18795, -1081, -300, -59, - 282, -329, -544, -1324, 2155, 9326, 462, -388, - -303, -2940, -608, -13652, 532, -1350, -1026, 1330, - 5559, -333, 4961, 707, -1832, 1070, 2483, -2016, - -315, 2197, 849, -348, 379, -2179, -15691, 903, - 3192, 3888, 396, 4610, 3261, -2589, -4903, -643, - 3604, -1380, 1524, -2155, 469, -3528, -790, 429, - -3862, 1797, -104, 2364, -1162, -1559, 1011, 1849, - -235, -1952, -2088, 1436, 2502, -3862, -1704, -14859, - -2863, 710, 624, 4373, -6302, -616, -807, -1577, - -2492, -620, -917, 948, 4957, -848, -863, 514, - -2210, 2162, -753, -15168, -2068, 12472, -2611, -723, - 2797, -8573, -2270, 978, -2597, 2215, -684, 2535, - 3114, -261, -178, 2385, -4869, 1161, -32, -1469, - 2074, -1407, 3226, -992, 4546, -3158, 1044, 463, - -5285, 4, -1396, -1395, 1770, -1767, -860, -6, - -2242, -1548, -667, 587, -982, -2246, -1312, 1550, - -542, 5302, -716, 135, -15895, 3382, -478, 1279, - 615, 3365, 1620, -12613, -230, 3101, 3230, -1307, - 2860, 628, 647, -3595, -214, -1631, 2783, 748, - 1088, -57, -6014, 2496, 359, 719, 1476, -750, - -1644, -2125, 3913, -3788, 565, -1118, -1411, 1377, - -1020, -246, 18851, -1438, -1150, -1492, -681, -798, - -776, 960, 911, -1449, 336, -1114, -2111, -877, - -532, 668, 1018, 1098, 408, 2032, -607, -656, - -5997, 3089, 2462, -18368, -1027, 78, -4066, 439, - -845, 1476, 290, 490, -452, 1638, -3381, 80, - 1699, 458, 260, 1215, -516, 1883, -62, 35, - -2540, -1703, -1042, 1751, -422, 1222, 207, -104, - 1112, 151, -473, -522, 26426, 562, 884, -2201, - -281, 238, -839, 1037, -588, 81, -109, -2, - -32, 75, 654, 489, 524, -388, -1408, -906, - -1193, -936, -273, -40, -100, -662, -522, -145, - 119, 614, -922, -25329, -180, -668, -574, 161, - -448, 173, 750, -609, -812, -125, 814, 572, - 2602, 20372, 244, 1820, 724, 515, 932, -1290, - -712, -990, -305, -13, -763, -1157, 481, -764, - 320, 624, -620, 642, -1494, -568, -601, -655, - -790, -1348, 334, -1302, 382, 782, -1122, -641, --23549, 180, 463, -634, -666, 599, -356, -1071, - 816, -576, 1208, 912, -377, 624, 1049, 42, - -95, 370, 1932, -167, -275, 142, -159, -410, - 595, -562, -632, 748, 1192, 614, -41, -18, - -156, -61, 1280, -686, 363, 759, 756, -19362, - -614, 2151, -1185, 169, 327, 1494, 782, -1313, - -134, 841, 218, -76, -2980, 202, 80, 281, - 89, -61, -1678, 59, -125, 195, 320, -1310, - -56, 806, 47, -65, 249, 18432, -666, -506, - -204, -194, -560, -416, -3641, 330, -268, 842, - 10600, -176, 424, -1744, -3609, -1682, -844, -309, - -538, 435, 14251, -1281, 373, 2748, -702, -1358, - -766, 3480, -679, 4039, 529, -5698, -38, -813, - 1203, 4734, 318, -1044, -5109, 2187, -3474, 415, - 2436, -3021, -1628, -456, -1451, 3406, -1798, 1001, - -8648, 468, 1188, 497, 4628, -948, -4073, -11894, - -2750, -738, 1520, -4070, -810, -5755, -1370, 2978, - 4460, 917, 1221, -324, -1166, 2339, -1221, -2048, - 714, 6884, 3096, 6998, 13, -275, -3879, 790, - 104, 1383, 2056, 1957, -9216, -430, -199, 261, - 764, -109, -210, 795, 884, -334, 1546, -272, - -35, 738, -268, -13, -448, 645, 97, 76, - 1284, -343, -654, 112, 643, 22846, 634, -597, - -621, -784, -380, 951, -452, -685, 140, 688, - -770, 247, -679, -228, -26856, 311, -546, -444, - 606, 69, -195, 18, -220, -334, -42, 543, - -28, 492, 766, 208, -1206, -554, 213, -1112, - -1675, -608, 382, 2011, 5077, -17442, 1367, -702, - -856, -416, -1728, -1987, 2966, -1952, 38, 152, - 712, 210, -589, 3029, -1189, -2016, -8071, 10746, - -2143, -556, -1964, 162, -504, 995, 982, -2565, - -634, -985, -1668, 444, -2098, -411, 488, 1397, - -1134, 1888, -920, -279, 15057, -757, -1258, -3040, - -890, -105, -670, -490, -238, -2419, -1302, 915, - -784, -929, 1653, -89, 1076, 445, 2538, -1424, - 19175, -91, 437, 752, 254, 935, 854, -1666, - -86, -543, 1053, 664, -155, -485, -3994, -50, - 50, -58, -2626, 1801, -314, -16052, -1831, 1009, - 2344, -3030, -938, 1761, -1283, -150, -425, -6660, - -900, 1374, 803, 549, -2683, 837, 483, -655, - 4610, 1259, -45, 834, 1103, -3250, -3604, -2882, - -2463, -5331, 11312, -1653, -3505, -1855, -4962, 8579, - 2370, -2474, 501, -1282, 985, -924, 3452, 456, - -242, 3878, -2095, 2994, 7076, -459, 2574, 16116, - 8277, -88, 572, -38, 0, 1664, -553, 1820, - -2096, 1076, 415, -420, 1900, -1696, -130, 298, - -1555, 201, -404, -1831, -932, 844, 9606, -497, --16304, 3278, 918, -523, -1573, 2488, -813, 147, - 1540, 3795, 1390, 1061, -78, -10, 574, 2620, - -1143, -512, -582, -1496, 736, -4323, 786, -2873, - -1342, 3932, 14508, 12635, -899, 1730, -673, 386, - -676, 2787, -2780, -2960, 375, 475, -2188, 2250, - 851, 788, 268, 1264, 2973, -94, 1062, 1006, - -697, 669, -635, -986, -4848, -1486, -6, -3914, - 6267, -1560, 8, -503, 5273, -3545, 69, 15146, - 2263, -1490, -548, 1740, 1636, -892, -895, 769, - -471, 226, 6497, -2466, -2037, -1068, 1075, -902, - 13668, -1213, 12424, -3523, -124, -1090, 972, -1134, - -494, -2568, 881, -3081, 369, -254, -618, -914, - 443, -1254, 658, 1322, 546, -14, 778, -116, - -378, -802, -268, 48, 1140, 25942, 503, -637, - -871, 1050, 298, -187, 387, -406, 343, 212, - 110, 723, 695, -47, -50, -568, -66, 347, - -1588, 20, 701, -485, -98, -787, 4502, 1046, - -1628, -2526, 185, 1016, -256, -700, -403, -154, - 103, -752, -689, 2084, -1463, 2294, 360, 17590, - -698, -1262, 788, 116, 755, 751, -440, -610, - -469, 1235, -2314, 1240, -308, 553, 1065, 24442, - -733, 667, 4, -484, 93, -263, -361, -278, - -1524, 176, 1311, 1561, 435, -436, -1079, 260, - -366, 472, -1049, 647, 158, 302, -931, -36, - -990, 736, -444, 1077, -1560, -251, 148, 1000, - 1096, -300, -224, -307, -17646, 39, 206, 74, - 505, -3051, -1285, -793, -724, 718, 324, 803, - 874, 6062, -2235, -3321, -550, 9264, 3483, -4172, - -4024, -471, 858, 2682, -1078, -1922, 2088, 1135, - -878, 545, 2205, 836, -1088, 547, 12461, 2222, - -828, -3841, 4797, -2360, -2510, -4029, -2213, 13736, - 1032, -958, 1895, 264, -1499, -2066, -241, 1324, - -224, -792, 776, 2130, 2600, -2276, -4239, 3260, - 1610, -1620, -1220, -2752, 979, -2028, 19626, -2146, - 684, -729, -235, -289, 588, -600, 245, -879, - -816, 413, -87, -1158, -246, 69, 970, -111, - 500, 1097, 1087, -138, -1356, 30, -434, -452, --22802, 177, 492, 206, -257, -854, 1445, 37, - 1384, 97, -258, 811, -222, 53, 548, 1744, - 124, -1031, 1076, 186, 453, -173, 1180, -2235, - 583, -392, -1542, -726, 2937, -3635, -856, 1446, - 7796, -2779, -962, -2277, 1651, 1960, -1460, -1277, - -9794, -288, 2459, 2350, -2521, 84, 578, 2286, - 480, 1620, 6421, -200, 170, 1513, 198, -1001, - -491, -1000, 161, -482, 607, 214, 743, -292, - -394, -192, 92, 73, -415, -316, 593, -42, - -346, 456, 44, 950, 129, -189, 806, -221 -}, - -.cb1108s0 = { --32768, -828, 9569, 331, 6938, 3122, -1008, 2847, - 646, -5690, 1712, -795, -4406, 1368, 307, -526, - -2206, 26, -210, 1358, 746, 1920, 667, 3866, - -413, -720, -4328, -2475, -1189, -863, -3809, -5052, - -8567, 2859, 1915, 4895, 12440, -13002, 2757, -5969, - 4054, 1100, -9430, 4930, 10266, -1522, 7092, -8778, - -1968, 4325, 8440, 3888, -1966, -688, -2455, 2966, - -2380, 1682, 4956, -2310, -3706, 404, 6774, 17562, --12437, -2667, 4864, -9411, -6436, -9316, -903, -5526, - 3463, -1690, -5250, -12568, 2338, -1310, -3019, 776, - -641, 3483, 54, -10732, -3878, -691, -17615, 4530, - 10267, 7830, 8488, -12624, -4514, -17183, 7070, 3115, - 4176, 383, -4558, 410, 6379, 6242, 4702, 4853, - -217, 446, -3811, -2396, 244, -2120, 3275, 5122, - 180, 4523, 8680, -1868, -6164, 2636, -5056, -4039, --11618, 4014, 11349, -2616, 8240, -5119, 1988, -2552, - 6060, 3206, -662, 2686, 1116, -10447, -3004, 650, - 7811, -12148, -327, 856, -916, -397, -600, 4621, - 3011, 5539, 5417, -2374, 9667, -4714, 7821, -2819, - 573, 4492, 1882, -26770, 1486, -6963, 1103, 2515, - 8196, 1849, -7492, -5243, 2106, -5290, -11000, -1410, - -3448, -8548, -4536, -7730, 3083, 6109, -14458, -8624, - -381, 7840, 4694, -3906, 8223, 3315, 5849, 13112, --13132, 6081, 11801, -7624, -376, -6372, -6817, 6834, - 1760, -1435, 1072, 3505, -1494, -709, 5786, 454, - 1807, 2650, 7728, 1357, -1002, -5366, -2368, 2052, - 333, 6312, -336, 8274, -1653, -4309, -6630, 2841, - 2448, 8398, 5376, -7248, -1474, -1842, -4119, 838, - 501, -4206, 4052, -1250, -20943, -3338, -592, -2973, - 7057, -128, -3235, -4313, -2510, -11313, -4925, 3103, - 1448, -5186, -1322, -16815, 1956, -7950, 2641, -2890, - 4396, 2322, -1381, -1911, 448, 2543, 3535, 782, - 3719, -624, 1610, -2843, 7583, 1794, 700, 3107, - 4528, 5461, 2540, -1074, 5976, 741, 576, 4426, - 4400, -4920, 5724, -3734, -1186, 10645, 1100, 10537, - 2828, 11670, -8391, -32572, -9405, -6807, -875, 2277, - 736, -4546, -18693, 1204, -1083, 3422, -3328, 6013, - -2992, 5812, 2744, -11668, -2519, -2384, -3635, 6532, - 6874, -2820, -5222, -12261, -14266, -6663, -1150, -2032, - 2099, 4642, 1638, -4162, -644, 249, -3133, 11830, --10712, 12370, 4818, -1924, -5639, -6448, 2455, -4898, - -613, 1760, 2393, 1414, 7039, -7018, 5901, -2900, - 3786, -3230, -3718, 3514, -4040, -4676, 6367, -1449, - -2758, -2888, 4066, -7140, 408, -7656, 3156, 19919, - -1858, 6671, 352, -3355, 3074, 5524, -1429, 1954, - -6664, -10082, 4405, -1598, -806, 1779, -6913, 7062, - 5064, 6518, -1042, 3400, -5530, -1192, 590, -3298, - -772, 571, -6239, 9810, -12380, 1302, 1344, -3430, - 3830, 4106, 5792, -6196, 224, -2604, 3954, -12551, - -5539, -8306, 1801, -4521, 3578, -4349, -5716, 4960, - 3620, 1516, 5779, 5550, -3710, 3329, 10542, 4198, - 5148, -3291, 196, 6232, 6943, -1303, -10306, 1862, - 6547, -1544, -2996, 2868, -4389, -6894, 28557, -13130, - 1397, -2331, -4076, 2870, 3592, 6613, 265, -4790, - -3514, -3152, 8710, 230, 3142, -1264, 1822, -769, - 6168, -1792, 2189, 2660, -2664, 3402, -533, -3100, - -476, -1164, 6092, -2930, 3372, -5895, 8507, -918, - -4716, -1582, 23959, 1506, 2360, -117, 2029, -452, - -6575, 964, -13132, -2838, 3800, -3355, 3168, 5230, - 11116, 826, -1711, -3546, 7398, -4092, -2884, 743, - -1784, -3824, -3437, 1050, -3306, 928, -5109, -7999, - 1581, 8609, -4662, -3594, -1618, 9929, -3982, -5591, - -8789, -1444, -12011, 1304, 12668, -5138, 10837, -7951, - -4089, 3921, -5375, -2486, -2590, 11398, -80, 7734, - -4547, -11286, -7098, -7758, 5303, 7380, -11266, -11138, - -8676, 30, 6328, 597, 7852, 3144, -3933, 15142, - 3954, 12197, -507, -1667, 5517, -4187, 709, -1330, - 2094, 4739, 1341, 8276, 8544, -10107, -10151, 3641, - 771, 4798, 4839, -3254, -9246, -7304, 14850, -18155, - 3068, 4993, -4930, 10985, 6270, 8528, 5904, -13010, - -7824, 1300, -706, -156, -4228, 302, 9962, -3087, - 4472, 4541, 13179, -6576, -2541, 8284, -51, 5366, - -4369, 289, 3890, -3671, 1894, 21820, -3031, 5336, - -8412, 2487, -1211, -6759, 1292, 3749, -8904, 638, - 6863, 154, 1145, -684, 6648, -3874, 2005, 4670, - 4408, 4191, 3984, 632, 2957, -1532, -3974, -2576, - -1636, -3714, -136, -4946, 3900, 367, 27072, 1864, - 1426, -3321, 860, -1768, -2009, -3436, 2666, -9899, - -1328, -2330, -3078, -3258, -4600, 5604, -5248, 1703, - 4403, -4781, -8275, 6717, -3860, 10980, -10634, -8360, - -2291, 20311, 7602, -4028, 483, -4886, 2677, -4921, - 6065, 5393, -2145, 6201, -472, 1796, 2869, -3578, - 3053, -2342, -3193, -2589, -3215, 1322, 536, -164, - -314, 4800, -1903, -1338, -11833, -23399, 5562, 4440, - -1864, 2520, -4251, -1464, 5053, -8553, -3852, -5932, - -849, -7113, -3493, -5338, -1671, 1496, 4504, -1830, - 5716, -210, 1397, -2060, 2242, -583, 2604, 5355, - 13938, 13150, 1346, 2649, -1527, -4568, 8891, 7399, - -6492, -10371, -4885, 13056, -8262, -1267, -2959, -868, - 5941, 299, -601, 8834, 1436, 5404, 1914, -3775, - 980, 8848, -2270, -1952, 6902, 8642, -25725, 9556, - 14540, 1998, -13157, 308, -13844, -10126, -2147, 8296, - 1772, 1094, -9712, -8560, -7552, 5527, -1446, -1097, - -5798, -17270, 2860, -210, 2136, 175, 729, 11775, - -5154, -4202, 13342, 3977, 14494, -5659, 9105, -11067, - -3694, 4794, -593, 6817, 1875, -4975, 3663, 4141, - -8317, -8932, 2127, -4176, 1136, -148, 7640, 8127, - -744, 2354, 389, 1600, -6475, -4558, 10735, 11407, - 3896, 13098, 1814, 5191, -3850, 2629, 18430, 8343, - 4630, -4624, -702, -3834, -2276, -2894, -1556, 1437, - 424, 5652, -6260, 2387, -5845, 7496, 10657, -2754, - 4806, 1169, 1308, -4114, -5347, 15076, 5686, 7287, - 3004, -6254, 5186, -14096, 10323, -1974, -9355, -5544, - -986, -5998, 261, 4494, 2467, -1911, -603, -4548, - -1344, 1995, -1603, 10464, 5222, 3714, -5342, -8039, - 12530, -26465, -1813, 4044, 746, 8123, -12078, -4703, - 2971, -4487, 2556, 3904, -2518, 1504, 5774, 5431, - 1120, -934, -5202, -6826, -8774, 7156, -2392, 10643, - -2918, -4298, 3361, -3758, -894, 5828, -203, -4905, - 6480, 11771, -19830, -17545, -4920, -17263, 10066, 10125, - -8980, -19719, 23554, 27907, 2607, -7014, 6128, -23759, - -4802, -7099, 874, 13103, 21667, -8475, -12938, -13122, - -3694, -18860, -3518, -3586, 12658, -793, 10661, 6925, - -730, -11373, -7845, 94, -2627, -6044, -2213, -4381, --10198, -5816, -56, -4349, 3722, 3911, -1719, -2513, --13290, 3218, 105, 1876, -76, -1107, 2563, 4520, - 10288, 5862, -7738, 6180, 9863, 1380, 6756, 2632, --18798, 9314, 7190, -7454, 432, -15141, 8462, 2128, - -2386, -2710, 292, -751, -3125, 6147, 4941, 3146, - 3046, 120, 321, -5884, 5105, -4300, 6264, -317, - 1667, -694, 7950, 5639, -3284, 1089, -6456, -14694, - -3527, -1104, 4313, -20858, 7920, -10782, -13536, 933, - 4523, 2640, 2118, 97, -614, 9834, -9515, 232, - 5086, -6720, -1529, 568, 3139, -3665, -8567, -13771, - 6274, -4370, -5653, -8920, -7667, -9391, -6653, 12489, - -3666, -5103, -12324, 4796, -540, 10396, 3668, -3467, - 7124, -4398, 87, -12139, -204, 1213, -2190, 11948, - -2641, -2434, -5647, 2819, 3148, 3558, -6455, 3705, - 1644, -3090, -4225, -5998, 112, 17789, -7220, 2166, - 4153, 4516, -1100, -1667, -1402, -8837, 6344, -1586, - -3451, 2357, 616, -392, -8163, -11579, 6160, -2783, - 7895, 11321, -11847, 8070, 5231, -6496, -3172, -3470, - -2960, -11437, 465, -470, -2568, 11197, -9417, -4117, - -1162, -1893, -2361, 551, 14478, 3510, -1372, 3117, - -8236, -2904, 14556, 3191, 200, 2166, -13974, 2718, - 3946, 2444, 1982, 5320, 2087, -2222, 1573, 742, - -8828, -3917, -11080, -241, -8472, 6119, 290, -2364, - -3163, 1923, -1964, -582, 2564, -5566, -6411, 2069, - 7392, 9115, 25316, 1504, 2540, -814, -1746, 566, - -1580, -2290, 170, 698, 105, 9567, -6714, -584, - -4934, -379, -491, -978, 4580, 1180, -3355, 1882, - -4343, 4817, 1503, 9968, -8878, -4908, 3419, -4818, - -2254, 6694, -4368, -10849, -5093, 4510, -3129, 152, - 1926, -4490, 1510, -17764, -6699, 962, 3474, 4981, - 25, -7128, 1432, 5386, 3108, -4545, 1092, 1663, - -1363, 3076, -8916, 6158, 244, -1181, -825, -933, - -5570, 17221, -535, -2892, -5031, -1297, -3010, 5840, - 678, 748, 3944, 1630, -3648, -5457, -2618, 876, - 6655, -2834, 2597, -6667, 1330, -40, -4423, 6257, - 743, 6083, -584, -3742, -1401, 1779, -5166, 4559, - 5558, 8588, -6476, 7521, -1561, 4950, -778, 3564, - 11403, -1010, -3151, -14151, -1020, 2595, -3278, 24555, - -4859, -909, 2314, 1301, 2098, -5664, 3938, -4050, - -203, 3368, -2580, 3061, -9266, -6263, -6748, 3890, - 1950, -329, 1050, -1106, 588, 23705, -661, 6913, - 722, -5820, 2147, 3789, -1689, 661, 5389, -8519, - 1152, 3800, 7160, 5234, 1343, 3218, -2900, -391, - -4258, 5084, -4783, 7262, -10013, -811, -5252, 6474, --17338, -2388, -2596, -8715, 5836, 9523, 639, 4652, - 3071, 3114, -1648, 1563, -931, -10143, 4394, -2838, --11900, -1012, 841, -5812, -3048, -2715, -196, -5794, --20022, 1949, 3464, -770, 2200, -3564, 1975, -6242, - -1937, 3954, 5678, -2744, 1888, -3825, 5770, 3869, - 8315, -7386, 1318, 1302, -5534, -4554, 924, -3804, - -4292, -22757, -7972, -7469, -3543, 7858, -10125, -2637, - -4765, -10644, -5944, 1159, -3293, 4363, -1219, -12248, - 5060, -7232, 6947, -1609, -3037, -5084, 6580, 15873, - 5336, 7295, 2386, 2961, 4655, 9714, 5080, 11635, - 1790, 2897, 687, -914, -692, -6653, -8562, -1412, - 244, 4478, 1650, 7175, 1046, -6689, 3693, -3520, - 6046, -1336, 1976, 16822, -1176, 792, -1733, 8286, - -7359, -2402, -8536, 1392, -3271, 6580, -4939, 1562, - 595, -4237, 4872, 4266, -1798, -6589, 7457, 4207, - 9978, -3996, -2236, -3078, 1861, 10101, -2394, -3250, - -7619, -7082, -14305, 5664, -1337, -11019, -3839, 10190, - 7249, 3086, -1782, 24, -3566, 10769, -4102, -6408, - -688, -8987, 3018, -5942, 7478, -368, -7931, -3018, - 6766, -78, 5705, -3264, -1100, 4850, 4518, -28, - -6276, 4905, 7094, -4394, -2846, -88, 434, 2039, - 352, 9827, 12372, 1207, -8561, -4476, 1496, -4927, - 2087, -6730, 1134, -81, 57, -8701, -2918, 3953, - -2844, -1842, 4804, -5315, -401, 7060, -16397, -4802, - -9849, 17542, -11715, -12432, -6676, 9323, -13189, -5761, - 8054, -620, -7431, 3726, 17790, 7880, 251, 2983, - 3736, 7118, 17197, 8613, 1445, -15290, -16184, 11084, - -4971, -5922, -1893, 9067, 9321, -8139, 714, 182, - -3138, 7258, -1874, -2781, 10800, 2915, 5316, -5206, - -2581, 10219, -484, 862, 119, 6628, 1514, 3883, - -880, 7586, -2573, 3279, 3801, 4492, -3850, 9416, - -38, 7518, -574, 4052, -1136, -668, 9672, -9536, - 2551, -4223, -1074, -3616, 8446, 158, 3262, 7965, - 1311, -8634, -6786, 700, 4973, 917, -754, -1156, - 6054, 2067, 10757, 421, 1030, 11351, 2149, -4286, - 12075, 4593, 1193, -5290, -8566, -2965, 6824, -6238, - 2392, -3395, 5350, -2789, 7529, -1873, 3032, -1494, - -2703, -18535, 1583, 9539, 2556, -4422, -6079, -2699, - -7860, -4573, -8236, 4281, -1079, -17578, -2840, 7468, - 4675, -5002, -1268, -1529, -8222, 8285, -766, -4314, - 6048, 11507, 5046, -2444, 3186, 1732, 7872, 6598, - 2828, -2920, 8278, 13263, -10204, 1334, -5552, 10532, - 5412, 2554, -10076, 1128, -3959, -3210, 4091, 1824, - 4984, 5558, -2204, 2080, -3802, 6614, -7380, 3612, - -4624, 6366, -1795, 4038, 6227, -4312, -4910, -2127, - 15077, 4144, -16885, 3757, 2303, -670, 5625, -2590, - -2594, 2491, -3174, 4199, 1152, -1532, -7308, -8578, - 6431, 2975, 6032, 3037, -7451, -2643, 5503, -7856, - -2451, 5309, -3678, 8145, 1864, -8341, -15575, 7716, --10337, 8935, 12350, -10418, -4092, 734, 10400, 10934, - 5724, 1778, 5836, -3203, -10700, 2766, 4178, -18135, --16589, -5465, -5005, 7239, 25480, 7310, -6408, 6142, - -7748, -1423, -4318, -321, -2899, 3728, -3184, -3578, --11598, -1223, -8554, 656, -3945, -4084, -724, 301, - 9539, 9695, -1799, -2602, -1379, -5282, -4709, 11858, - 9562, -7508, 4886, 896, 5780, -160, -12724, -9598, - 1220, -5411, -5072, -6476, -11763, -104, 9311, 5230, - 591, 4342, 263, 13198, -17801, -1892, 2619, 18194, - -2080, 16536, 18497, -25926, 25541, 66, -6648, 1627, - 2794, -3790, 9424, 1387, 20702, 5260, 5211, 1702, - 1019, -11143, -6501, -18711, 10869, -4204, 4994, 1722, - 8569, 3670, 4386, -16874, 8876, -2297, -2743, -4562, - -9207, 8033, -346, -3586, -9451, 3242, 1552, 4278, - -6787, 7118, 3630, 4602, -7371, -12789, -10424, -14922, - -3010, 1885, 4144, -4490, 4074, 7796, -1201, -7244, - 2675, 1221, -7060, -12828, -3520, 1983, -4615, 8207, - 1606, 517, 3646, -7252, 816, -3690, -674, 13100, --16254, 4727, -8184, -968, -5366, -2288, -20260, 1174, --19384, -4199, -5292, 582, -13118, 1836, 1698, -2034, --14601, 6642, -10530, 482, -851, 9968, 7050, -13366, - -8354, 4740, -20050, -193, -1881, -1205, -4042, 7067, - 12872, 5846, -4792, -1833, 2504, -3222, -1607, 2634, - 4587, 6761, 1549, 1124, 9427, 3978, -8305, 7524, - 2507, -5744, 3238, 5238, -3664, 694, -28496, -1674 -}, - -.cb1108s1 = { --10979, 8698, -630, 4660, 3060, -7292, 10140, 11942, - 1448, -5820, -3144, 3100, 10575, 6888, 3505, 9996, - 2787, -484, 8057, 1503, 6329, 3074, 3954, 9419, - -736, 2333, -1858, 3264, -4026, 16130, -14501, -5284, - -472, 850, -7258, 1542, 1473, -2348, -7055, -9574, - -2275, -4383, 7542, -360, -2945, -3878, 28, 809, - 600, 2246, 587, -1779, -3456, -737, 3242, -2523, - -1862, 6127, 899, 1070, -15614, 10990, -3084, 9546, - 7339, 8899, -1490, -10379, -9193, -3857, 8289, 7261, - 12489, 7814, -6458, 1223, 15486, -10960, -1880, 4922, - -7819, -527, -2370, 3687, 1358, 10367, -14266, -1496, - 1060, -9325, -5582, -3947, -17536, 1470, 4878, 10793, - 2904, -2566, -4995, 6549, 6141, 11048, 3177, -494, - 9087, 797, -2575, -5616, 1197, 2966, -11287, 4658, - -504, 4571, 1814, 18830, 26254, 2399, 8750, 2656, - 8206, -12987, -9119, -1027, -457, 1228, 6137, 2322, - 1732, -5694, -892, -249, -178, -7009, -4368, 402, - -5564, -5183, 2470, -4745, 2788, -3255, -5181, -706, - 40, -4915, 8926, -3633, -2455, 15054, 5376, -867, - -7270, -979, 7053, -7433, 13749, 5039, -2234, 8474, - 7031, -3917, 5127, -7602, 580, 12067, 2252, 149, - 86, -582, -5729, 2193, 4178, -9195, -11824, 3897, - 1298, -1044, 6450, 1885, -19562, 6205, -4610, -2544, - 5192, -4885, 5021, -2373, -102, 7358, -2434, -3512, - -4048, 3070, 45, -1344, 202, -2189, 448, 1172, - 2939, -547, 1003, -6370, 3643, -1157, 3932, -6044, --12882, 1959, -1574, 2574, 14854, -16317, -6627, 505, - 1102, -9361, -8087, 7525, -1466, 284, 3756, -383, - 5147, 5060, -474, 531, -6144, -1872, -1206, 527, - -4861, -12410, 7508, -7226, 5046, -12233, -4153, 4628, --14402, -5265, 534, 1528, -13408, -62, -18757, -1280, - -9301, -10254, -8990, -6335, -7724, -3394, 1951, -13271, - -1389, -5274, -4616, -9643, -10295, 1332, -5618, -10737, - -7536, -9314, -7006, -760, 7694, 2955, -404, -2800, - 15250, -3828, 5994, 5408, 8411, 16568, -7280, -6901, - -222, -1554, -862, -1871, 939, -3678, -4348, -3200, - 3220, 1614, 8598, 8162, 1749, -7378, -1658, 931, - 3870, 9183, 1509, -5068, -17, 5733, -8121, 2769, - -3195, -3296, 8940, 2828, -2470, -2448, 7413, -2851, - -1058, -4505, -9653, -5074, 73, -3286, -4014, -1760, - 2562, 13690, -3464, 5438, -3394, 16997, -2944, 291, - 4224, 1175, -2237, -6894, -5479, -1291, 3390, 5455, - 898, 3461, -7914, -4785, 1879, 1059, -3721, -5796, - 5054, -3931, 6315, -2460, 1909, 573, -3373, 3052, - -178, 986, 572, -5976, 5781, -4928, -10539, 580, --18727, 757, 1759, -4049, 2232, 1890, 4115, 699, - -2934, 4926, 2391, 10848, 5103, 4340, -1518, 2288, - 2283, 8886, -5131, -4429, -4384, -3265, 11933, 3993, - 11474, 3721, 1532, 976, 6112, 1954, -2360, -1783, - 2080, -6356, 2482, -4646, -1992, 1590, 1790, 3290, - -2312, -564, 508, -1688, -7522, -9263, 3059, 1883, - -3005, -1303, -9146, 10282, 1333, 4692, -2083, -15792, - 2208, 1128, -11574, -7149, -1126, -4995, 18963, -6262, - 5045, 2179, -822, -1249, 10092, -338, 5744, 1635, - 2535, 6114, -1339, -8337, -4370, 4288, 2468, 3051, - 12491, -9554, -4034, 522, -1085, 5852, -2759, 4918, --10717, -194, -11376, 3059, 12075, 1037, 5260, 816, - 5918, -1987, 7924, -6022, -10374, 11607, 25035, -11598, - 16894, 2458, -5461, -2039, 385, 6002, 7574, 1229, - -834, -1032, -7453, 2694, -1447, 3632, 4215, 3541, - 2936, -3294, 1001, -6451, -4595, -11682, 7880, 2261, - 3786, -2849, 2276, -826, 3742, 7586, -334, 2837, - -2331, -12849, 1170, -1150, -5253, -997, -8996, 8124, - 2234, 904, -2294, 3144, 7352, -5452, 1536, -8800, - 1886, -18282, -9787, -8066, -12066, 1536, 4460, -1345, - 1418, 7471, 13451, -7299, 5507, 6795, -184, 8905, - -2040, -4933, 4998, 7317, -6667, -5134, 9094, -8561, - -2534, 3422, 2278, 3118, 205, 5811, 2247, 5946, - 1078, -2105, -6946, 170, -1625, -4734, -1447, -4329, - -4553, -2230, -8738, -15289, 7311, 6665, 5047, 1984, - 11896, 13922, -10490, -9313, 1424, -2991, 1408, 335, - 8914, 3773, 8814, 7917, -4560, -114, -624, 8984, - -1598, -580, 3233, 590, -2172, -3162, -3985, 5394, - 13842, -11625, 73, 12826, -1204, 5119, 10304, -10006, - -2695, 1318, 156, 84, -760, -4638, -3804, 3041, - -782, -2994, -3113, 637, -3256, -5831, 452, -1204, - 1614, -11626, -4769, 10612, -8710, -20019, 10542, -4279, - 6912, -1429, 3812, 2844, 3903, -11622, -8954, 180, - 3898, 3858, 119, 1385, 4038, -5899, -969, -5454, - 13305, -6748, 5934, 8027, -7348, -3797, -29781, -4956, - 2037, -2331, -3292, 8254, 6597, 4446, -7848, 6250, - 1400, -1182, -4966, -3490, -1410, -2286, 3334, 350, - 9271, 2987, -934, -5702, -3881, -97, -671, 5108, - -133, 1302, 11630, -8858, -3027, -42, 3682, -1507, - 3992, 5641, 2778, -8698, -2509, -1360, 77, 2116, - 98, 2853, -6334, 5915, -1214, -2721, 8921, 1380, - -4158, -4315, -4740, -21049, 7044, 866, 2094, -9442, - 9003, -5147, -4897, 3407, -11558, 4280, 4508, 6697, - 1612, 1508, 8547, -14257, -151, -9530, -7250, 11321, --14430, -4944, -2488, 1349, -248, -1490, 1749, 3970, - -5830, 20767, 4642, 3236, 36, -17079, -11099, 5996, --10759, -39, 7822, -7527, -1431, 179, -3841, 2298, - 1407, -241, -2303, 9244, -3626, 6609, 1959, -518, - 368, 1678, -5334, -5849, -4986, -2363, 607, 2809, - -1006, -7695, 10022, 2216, -8992, 4282, 807, 14707, - 9528, -11065, 3014, 3157, 5597, 1139, -1298, -3642, - 7839, 860, -4336, 2624, -4171, 1791, -2825, 5362, - -529, 1494, 337, -4487, -671, 5360, 3283, 4933, --14692, 4033, -4365, 2713, -6903, -1784, -10862, 6173, - 5278, 14859, -852, 10020, 12304, 8898, -3089, 9183, - 1841, 8276, 4929, -261, -1264, 615, 3615, 14535, - 6557, 519, 4228, 7382, -1805, -4529, 4992, 4277, - -342, -9610, -5193, -7022, -23264, 2402, -740, 2875, - -5052, 1983, 4987, 3336, -3806, 1335, -2868, 846, - 7652, 936, 3510, -4570, -3010, -8805, 6177, -4413, - 5879, -15204, -1632, 13416, -4543, 3838, -9293, 1744, - 920, 15544, 3820, -5852, 3935, 2357, -6486, 1932, - 12044, -6374, -2545, -2389, 2755, -8073, -8203, 4659, - 4286, 16128, -987, 434, -4495, -4428, -4816, -10329, - -4529, -13408, -13283, -1136, 4002, -1271, 3547, -5274, - -5577, 701, -365, -2764, 370, -369, 2611, -832, - 3862, 4604, -7786, 11170, -1453, -1568, 10758, 168, - 402, -1985, 1436, -8858, 10080, -8559, 3998, -4310, --13478, -3104, -11458, 506, -18194, -3724, -6768, 7960, - -4213, 1121, -1658, -1141, -1874, -383, -5090, 748, - -1032, -1207, 1046, -1865, -2387, 2126, -3672, 6733, - -2794, 3797, 15562, -11989, 170, 6129, 658, 929, - 4800, -4296, -955, -2189, -188, 3180, -118, -766, - -2182, -6928, -2254, 6615, -4422, 6324, -31, 3742, - -5832, -5022, 4671, 1574, -6309, 288, -2768, -2492, - -4818, -5192, -248, -3236, -429, 120, 1182, -10486, - -2964, -3713, -5978, 11817, -20052, -6525, 2054, -879, - -602, -2843, 7244, -1372, 417, -172, 3322, -6556, - -7021, 5842, 7357, -2799, 3660, 7579, 4682, -2242, - 73, -9247, 21061, -2060, -3614, 2486, 4793, -2959, - -510, -74, -5982, 2274, -4147, 3260, 1994, -1678, - -7494, -13624, 2560, -7375, -896, -4945, -2838, -11096, - -1969, 5879, 444, -3220, 14630, 4915, -2376, -8475, - 9854, 11380, 11060, 1534, -14413, 4366, -9544, -10646, - -7654, -17916, 3481, -3240, 1776, -2436, -8403, 3679, - -1914, 12537, -5540, -5294, 5995, 5968, -2609, -16882, - 789, -9506, -10075, -12142, -7580, -7090, -2046, 11065, - 7617, -3503, -2013, 3516, 6347, -195, -3119, 2444, - 14, -4998, 767, 4976, -3974, 9038, 579, 1804, - -8206, 32767, -5633, 1018, 13388, 996, -12737, -3179, - -2058, 13663, 1274, -4475, 7386, -1698, 17927, -6118, - 15942, -2922, -3434, 5903, 6333, -9149, 14140, -1488, - 2999, 1151, 2361, -1935, -10243, -11566, -5319, 965, - 5146, 3652, -441, -2173, -3484, 3685, -13595, -1703, - -78, -1408, 18517, -3788, -3266, 3162, 996, 19950, - -8560, 4989, 6593, -5329, 2950, -13896, -3524, 5590, - 4055, 6084, 2493, 12659, -5786, 4858, 7252, -7111, - -7318, 5411, 7393, -8714, -3454, -1562, 1919, -49, - -680, 7285, -398, -2956, 7100, 5563, -538, 1719, - -16, -3824, 437, -6842, 1504, 5694, 1214, 3209, --15562, -4365, 9329, -25577, 1425, -2598, -8389, -6891, - -3275, 3304, -3993, -6391, -934, 7862, 4844, -134, - 9890, -4646, 2468, -9901, -4111, -3080, -5056, 476, --13099, 1447, 205, -2424, 7098, -12075, -4646, -13725, - 8367, -2910, -8461, 1387, 3553, -10228, -2771, 4698, - -6483, 12234, -8086, 3329, 2374, 452, -1805, 5083, - 2014, 164, 7143, 81, 6062, 2838, 5318, -4982, - 1440, 2014, -3273, -6658, -798, -3204, 1398, -599, - -5834, 2070, 4644, -17238, 390, -1684, -4932, 8961, --12217, -3079, 6574, 1387, -5991, -7803, 1285, 7439, - -395, -3048, 2038, -847, -690, -5127, 2228, -4180, - -3499, 530, -584, 9884, -323, 446, -15644, -9162, - -1683, 3643, -3578, 2634, 496, 8097, 109, 1056, - 1422, 5452, 6517, -449, -2389, 302, 6827, 1507, - -3106, -7188, -4909, -441, 12955, -3933, -5322, 5155, --23171, -2780, -2655, -4048, 12844, -3709, 6555, -5700, - 3780, -6566, -4415, 11091, 11291, 6443, 9146, -796, - -1420, 5600, 12098, -5790, 6619, -10474, -12177, -5890, - 21700, 11148, 3427, 3130, -5727, 14646, 13953, -2721, - 1404, -3102, -4693, 4762, 1757, 2533, 3998, -530, - -758, 5301, -1426, 8948, -720, 6877, -3863, 2396, - 5266, -685, 890, -7188, 2742, -270, 8125, -804, - 32292, 6964, 8599, -3466, -1080, -8423, 2070, -295, - -157, -5432, 152, 2478, -3738, 1104, 1500, -5290, - -2463, -6386, -2537, -2331, -3290, -2398, 159, 6588, - -2547, -2424, -2184, 8316, 5670, -5608, -2600, 2659, - 166, 14828, 2622, -10490, -16378, 64, 434, 4576, - -3010, 2479, -6798, 3431, 360, -1067, 3421, 664, - 4029, -4050, -240, 3875, 672, 3587, 501, 2494, - -48, 9997, 3259, 8551, -7624, 17342, 10765, 4328, - -3721, 1729, -2844, -6330, 5114, 15589, -261, -7554, - 2708, 7260, 5852, -8736, 436, -6160, -588, -5919, - 5752, 3127, -4558, 540, 74, -4048, 3735, 7873, - -2869, -544, -111, 5182, 1032, 2315, -159, 5105, - 4106, -494, 678, -4756, -3865, -7389, -2492, 7193, - 5146, -7926, 12043, 11137, 1719, 2307, -5476, 12679, - 7996, 726, 933, 3222, 7515, 678, -5858, -2716, - 1503, -3014, -2125, 4982, -4984, 467, 986, 5450, - -1472, 5314, -1285, 218, -3411, 4511, 8047, 4268, - -8307, -10587, 17200, 3303, 7553, 5361, 1108, -7982, - 8240, -5856, -3376, -3952, -2884, 4401, -7252, 4078, - 7538, 3420, -13834, -1139, 10742, -2536, 636, 7758, - 4282, -3505, 1190, -7382, -8164, 5306, -408, -5005, - 2776, 7806, 4781, -7903, -2370, 13884, 542, 5643, - 6948, 6471, 2699, 815, 4454, 1882, 2290, -3856, - -3086, 8215, 3234, 4444, -1580, 2835, -3083, 6706, - 7409, 4626, 2658, 2308, 7965, -1034, -2584, 344, - 704, 12280, 10344, -8032, -4410, -6168, 6860, 7977, - -5630, -6680, -5001, -6199, -10378, -1764, -3322, -4284, - -1048, 2721, -11738, -11800, -7975, 2754, 3424, -7641, - -2245, -4945, -194, -1948, -2850, 4111, -21846, -8750, - 4306, 24494, 10428, 26998, 4976, -2701, -3283, -723, - -1539, 6758, -9730, -3517, 6401, -4546, -410, -9900, - -4947, 6996, 10983, 5110, 19948, -78, -1794, 11051, - -14, 316, 6447, -20430, 9363, 9062, -2134, 13711, - 6448, 6655, -5232, 4610, -10352, -3042, -8713, 5777, - -2438, -2602, -7293, -755, 6736, 2960, -3676, -2882, - -9806, 1342, 1242, 2122, 2749, 631, 6502, 2266, --12996, 13620, 19762, 8096, 702, -4394, -8668, -1460, - -3228, -173, -6239, 4643, -1916, 4098, -2234, 1202, - 1763, 6170, -6320, 12984, -5936, 8301, 6021, 2191, - 466, -4044, -1913, -3458, 8197, -3249, -5935, 2383, - -4241, 4977, -4415, 704, 3488, -8356, 10229, 562, - 14, -4828, -3890, -7599, -4208, -3166, 1132, -16584, - -506, 1397, 6266, 3307, 5782, 2349, 3257, -3017, - 7814, 1216, 7440, -10096, 12698, 944, 1221, -1683, - 152, 6020, -7910, 3897, -6954, -9439, -9838, -3860, - -5383, -4228, -1980, -4045, 7442, -5504, 2145, 636, - 2857, -4538, -820, 4275, -2104, 5076, 5191, -363, --23254, 1962, -66, 7550, 88, 8721, -1361, 7733, - -2661, 5282, -5112, -24, -975, -3200, -2235, 5144, - 213, -6340, -3974, 1266, -2383, 2432, -124, -233, - -3504, 10604, 806, -918, 11601, 19332, 206, 7456, - -8885, -9692, 3087, 3685, -2183, -7538, 11970, -5098, - -7364, -1173, -3099, 6532, -6850, 4622, -828, 390, - 467, -5364, 4442, -1878, 8949, -4340, -261, -2720, - 6659, 16184, -6552, -3736, -15416, 15774, -306, -4240, - -1807, -10304, 11073, 2743, 3974, -5557, -3499, 5315, --10742, -378, -4517, -5949, -7664, -2830, -6510, -6096, - 2052, 3425, 1971, -3328, 5326, -1362, 1806, -14286, --12774, 6058, -3365, -735, -2586, -18658, 6664, 9502, - -1590, 323, 6445, -17766, 14694, -9786, 3696, -4547, - 1601, 3645, -584, 910, 2516, 8197, 3898, 4306, - 631, -2020, 4309, -765, -6591, 2083, 8969, -1474, - -27, 9130, -5808, 8492, -135, 2230, 2296, -4509, - 4600, 4951, 1930, -2564, -5889, -1338, -11737, 6387, - -3649, -5447, -2462, -4751, -1012, 3523, -3504, -9510 -}, - -.cb1108m0 = { - -2417, 4623, 2916, -4257, 120, -10323, 1198, -10252, - -117, 8767, 3160, 2323, 1162, -650, 2237, -4171, - 2386, 432, 1627, -7255, 38, 124, -3658, -1558, --11711, 10, 8146, 1700, -1975, -16731, 2397, 1056, - -2502, -2660, -2731, -2477, 1488, 1220, 4880, -1156, - 1805, -3, -3009, -6233, -2216, 3440, -3082, 2124, - 70, -2461, 1125, 1919, 11949, -2506, -622, 2209, - -702, 2685, 9183, -510, -2806, -1129, -1823, -1746, - -3600, 2298, -3360, 10793, -1714, 1662, -62, 395, - 14142, -261, -144, -9896, 11481, -884, -2197, 352, - -326, -453, -1984, 2027, -1466, 3290, 94, 3481, - 2533, 4401, 5492, 3803, 247, -896, -1688, -3166, - 1130, -1125, -1973, 322, 867, -1936, 714, -880, - 8, 2313, 23418, -1682, -677, 384, -2140, -386, - 920, -2523, -495, -1494, 3027, -707, 1172, -1403, - 2177, -2137, -885, -1035, -1637, 375, 2452, -3709, - -1171, 2069, 1095, -1937, -686, -956, 2034, 3410, - -3075, -359, -598, -2084, 18550, 1781, -45, 1400, - -1580, -13180, -609, -1376, -3145, -248, 5661, 6886, - -3915, -194, 9876, 1065, 3879, -1726, -837, -660, - -7467, -3055, 3516, 283, -1604, -625, 1165, 3023, - -1531, -1825, 1430, -561, -881, 1346, -129, -1817, - 851, -32768, -294, -188, -116, -646, 1176, 630, - 903, 417, -2487, 352, -789, 571, -127, -2054, - -2112, 418, 1631, 266, -270, 362, -2765, -1198, - -182, 3586, -1272, 1470, -66, -18384, -1230, 823, - 1171, 1350, 1101, 1410, -3730, 1535, -101, -3234, - 2315, -34, -458, 1361, -16497, -990, 1438, 2542, - -1193, 586, -1708, 2689, 2741, 6010, 4209, -5974, - -628, 1556, 2238, 6134, -3040, -2937, 2188, -1660, - 1137, 1316, -2650, 905, -502, -93, -1177, -31964, - -1170, 1504, -1284, -104, 168, 55, 3478, -161, - 2818, -484, -32, -1536, 1218, -854, -351, 4465, - 16922, 681, 4198, 419, -414, 6824, -3906, 11598, - 75, 4904, 1374, 64, -2692, -3759, 3065, -1397, - -202, -347, -2466, 96, 1035, -765, -258, 3711, - 1437, -18250, 566, 976, 2483, 4, -1096, 1906, - 3745, -2621, -2756, 1864, -560, 98, 821, -4094, - 5349, 1369, -5245, -2170, 2932, -1052, 3932, -413, - -400, 31206, 1125, 1631, 43, -764, 1666, 780, - 2036, -564, 64, 1311, -202, 843, -2030, 856, - 1766, -3163, -1158, -626, 316, 127, 1783, 1918, - 3384, -2887, -5885, 1763, 4910, -248, 17100, -3022, - -1880, -2927, -1287, -3308, -1767, -2622, -1460, -250, - 3597, -4526, 946, -1533, 1059, -8, -807, -1283, - 1436, -11184, 643, 398, -1565, 1983, -60, -9862, - 1219, 322, 3132, -2043, 1138, 6258, -3540, 790, - -923, -4692, -1401, 2733, -8918, 4905, 6181, 192, - 82, -1094, 4, -634, -1323, -2865, 1036, 1484, - -2461, -937, 414, 221, 2179, -438, 1273, -2690, - 18442, 2781, 1788, 2264, -1230, 4284, -4708, 1190, - -4810, -975, 230, -3728, 2504, 3602, 3488, 88, - 1322, 487, 2965, -3731, -2341, 5937, 8545, 1716, - 7308, 9017, 6426, 727, 3992, -4584, 388, 3714, - 1164, 18, 445, 1253, 398, -1989, -824, -430, - 745, -5447, 2176, -1986, -3963, 2861, 194, 17739, - 1891, -5368, 4172, 125, 530, -2766, 1179, 401, - 1759, -1609, 31234, 910, 1100, 1036, -948, -1101, - -614, 1768, -344, 840, -696, -842, 320, -1444, - -2560, -3199, 58, -2172, 1375, -3002, -821, -863, --12096, -2484, -677, -2130, 4450, 3568, -3192, -1114, - -3218, 3121, -503, 5570, -561, 3896, 10566, -3065, - -2768, 1398, 1719, -2708, 1952, -142, 4777, -978, - 2238, -5780, -430, 1228, -1298, -2923, 4353, -1621, - -2368, -2908, -8012, 4398, -502, 518, -6964, 622, - -377, 3758, 6598, 4438, 6849, -7696, 470, 3585, - 466, -14664, 3438, 14706, -1944, -2544, -785, 3653, - 1274, 443, -694, 1968, -3499, 2855, -3930, -1210, - -528, 1931, 3849, -772, -2659, 4499, -3624, -540, - -1645, -949, -382, 979, 595, 165, 429, -80, --20468, 1040, 544, 2545, -5010, -2122, -2840, -335, - -405, 404, -50, -2996, 1226, 519, -1046, 3745, - -2317, 6211, -14500, 9754, -5802, 5230, -3112, 1506, - 3741, 664, -902, 197, 2476, -3618, 2040, -1066, - 2338, -257, -2580, -293, 2740, -576, 2050, -865, - -3666, -2090, -1831, -32056, 658, 1549, 1602, 1728, - -534, 390, -1517, -627, -4025, -797, -2351, 2759, - -102, 2574, -56, 796, -232, -886, 1639, -2773, - 1007, 830, 5880, -2220, 762, -3834, -2865, -415, - 584, -3498, -4546, -16108, 344, -4072, 551, -5435, - 2007, -1418, 3838, -1662, 1981, 3545, 1424, 769, - 2135, 1705, -15076, -636, 283, 3386, 97, -1048, - -3933, 204, -8616, -556, -2936, 4241, 5100, 1777, - 98, 719, 6202, -1496, 708, 2160, -2396, 4060, - 1513, 2253, -46, -1823, -132, 709, -756, -944, - 575, 1070, -1583, 587, -24575, -1989, 874, -568, - 1040, 1116, -4002, 3196, 2826, 117, 1590, 2456, - 938, 112, -938, -1268, 5056, -2851, 2995, 2559, --13121, -8374, 3593, -6684, 3663, 766, 747, 1016, - -921, 2241, -1942, 4269, -3312, -1012, 2340, 2781, - -3881, 2532, -1976, -1436, -3219, 420, 22088, -742, - -640, 3270, 1446, 1935, 1279, 1913, 1377, -3297, - -751, 4209, -1052, 2381, 2938, -1330, 2154, 2784, - -2420, 1270, 2334, -526, 1480, -435, 2206, 252, - -510, -1018, -1469, -1294, -950, 424, 1058, -2317, - -846, -20737, -1877, 88, -431, -1268, 116, -378, - -2326, 3115, -246, 30, -4725, 648, 2084, 14286, - -817, 2496, -1947, -4869, -9703, 1505, -2476, -2108, - 747, -449, 3002, -5464, -514, 1805, 2559, 2494, - 12782, -1232, 12091, 2118, 3996, 2592, 1058, 510, - -1384, -3050, 2533, -408, 5219, 3044, 3242, -185, - 2654, -3723, 16, -1723, 1823, 6144, -4806, 182, - 1772, 4841, 16390, -96, 2505, -7713, -5244, -3316, - -6776, 1448, -1470, 4238, 294, 889, -2372, -6281, - -2423, 5423, 2119, 2897, 1378, 817, -993, -1599, --14662, 3014, -3397, -6182, -245, 4897, 5116, 2285, - -2863, 1174, 415, -6777, 3863, -6009, -4722, -119, - 606, -2247, 4447, 1064, -1935, 2705, -2629, -1144, --11980, 3805, 882, 1634, 5446, -4300, 643, 3436, - 7632, 592, 998, 674, -2647, 4644, -6854, 1368, - -146, -3395, 10599, 1369, 3852, 1689, 2437, -3937, - 3405, 2517, 1895, -14092, -1142, 2570, 10163, 1608, - -2445, 850, -1678, 3112, -3465, 3138, 4413, -1973, - -4151, 1163, 1822, -3819, -1568, -407, -2642, 424, - 365, -3599, 164, -1448, 1062, 1536, 1590, -1982, - 200, 18572, -230, -638, -1253, 1650, 2280, 4945, - 4527, -2353, -4216, 3752, -3807, 3686, -4816, 2382, --14833, 1306, 17246, -739, 2012, 3521, 1473, -1436, - 1514, -142, -461, 1038, 2462, 971, 1354, 1272, - 1787, 2420, -922, 3364, 2250, 497, 1349, 2795, --32768, 425, 1874, -72, 2461, 389, -306, -1180, - -646, 251, 299, -2735, 577, 1055, 1826, 1620, - -1214, 1422, -901, -1273, -2367, -1241, 366, 521, - -433, 55, 4000, 3035, -1390, 2505, 1786, -15397, - 413, -5916, -234, 3559, -6776, -5068, 2251, 36, - -180, 596, 5744, -2450, -1276, -4786, -1872, 24, - 252, 464, 2833, -136, -25600, -33, 873, 2646, - 1471, -1336, -1330, -276, 1778, -242, -951, 1580, - -79, -858, -927, -4310, -604, 7568, -1713, -948, - 192, -260, -1334, -1116, -705, 638, 132, 1186, - -952, 1157, 428, 2039, 1568, 1778, 22453, -2190, - 2176, 1674, -3996, 1294, 1162, 274, 415, -2877, - 464, 505, -1842, -1066, -2241, -761, -291, 8, - -987, -104, 796, -32768, 1302, -809, 571, 1214, - 455, 686, 656, -1752, 886, -790, 644, -1114, - 2358, 11452, -4398, 1334, 13095, 3230, -1818, 4053, - -1990, -1093, 878, 3796, 2712, -1523, -1229, 1077, - 960, 1250, -75, -3233, -7734, 2783, 8430, -327, - -1428, -1687, -4092, 269, 3161, -569, -1267, 1774, - 2772, -2033, 171, -520, 1551, 3719, -3364, -220, - 1904, -1282, -2008, -818, 4261, -886, -19201, -3454, - -478, -2645, -2601, -2124, -3977, 2960, 1563, -432, - -989, 2682, 1734, -9085, 4614, -4454, 2535, -7201, - -220, -10022, -431, -7907, 889, -9658, 6653, 762, - -1827, 5886, 862, -1836, -430, -16363, 5709, 851, - 1814, 304, 5045, 1685, -1004, 5108, -5936, -3143, - 940, 1832, -270, -674, 1441, -241, 3222, -551, - -434, -69, -3584, 349, -1354, -12080, 3639, 5219, - 7583, -1023, 2078, 3263, -5807, -873, 4085, -5153, - -3623, -436, -4717, -1803, -6274, -2049, -247, 2516, - 1922, 10204, 2194, -1574, -535, 656, 1638, -3091, - 1156, 1377, -1220, 4956, -221, 4984, -1154, 4603, - -1618, -5655, -2583, 13494, -2442, -3968, 3086, 1098, - -1625, -13781, -12826, 2659, 3604, -702, -1900, -3508, - -6283, 2320, 1979, -2823, -4890, -1728, 2, -4402, - -437, 1932, -3272, 2853, -3018, 840, -632, -6691, - -484, 9579, 1008, 11677, -2814, -2029, 8048, -1170, - -7366, -2664, 3349, 1319, -1160, -1864, 606, 1568, - 5428, -4763, -2470, 2145, 1798, -502, -1538, -3736, - -1376, 1330, -3567, -78, 478, -743, 890, -800, - -44, -1832, -1761, -1022, -996, -846, 1188, -1042, - -3202, -2439, 1602, 3601, 564, 18338, -17, 1327, - -387, -1998, -1260, 3352, 849, -4780, 1932, -56, - 2625, 10753, -1676, -10536, 2980, 1542, 1177, -3113, - -859, 522, 3092, 9588, 2882, -4540, -1406, -5183, - 50, -4245, 3649, -420, -3612, -5290, -1919, 14559, - -2605, 1169, -2009, 10760, -2372, 339, -2538, 4476, - 3001, -4570, -3158, -3465, 2873, 650, -2099, 76, - 1166, -1469, -2769, -391, 4215, -630, -1448, -1796, - -1573, 5914, 807, -1580, 2072, 99, 580, -2999, - 1079, -202, 17940, -1233, -4909, 1079, 390, -891, - 1834, -2155, -2642, -1703, 1856, -14125, 2081, 3178, - -2480, -4342, -11991, -2050, 1046, 2412, 436, 1046, - -2291, -1718, -3087, 1710, -963, -1914, -3423, 6190, - -1238, -4333, 115, -10550, -2742, -919, -4849, 1502, - -3054, -3304, 2300, -1850, 2337, -6643, 1995, -1279, - -238, 738, -124, 13593, 252, -1424, -165, 2786, - -1717, -838, -11244, -10971, -902, -3330, -2580, -2735, - -171, 4041, -2149, 2502, 6726, -738, -4235, 368, - 6144, -1718, -8620, -1888, 112, -282, -19, 4126, - 10797, 610, -3097, 7783, -2974, -2058, -3558, 470, - -5914, 10322, -20, 85, -1652, 6111, -1398, 2613, - 3733, -3716, 1930, -4325, -1199, -921, -446, 1095, - 1006, 910, -2323, -351, 808, -32768, 274, 1346, - 105, 2360, -1184, 2249, -970, 153, 3180, 1307, - 2207, -962, 2209, -921, 1504, -117, -2111, -3734, - 5738, 8014, 76, 1566, 3013, -462, -3600, 3939, - 4862, 1038, 4312, -790, -426, -1656, 20, -10568, - -6389, -6597, 4230, 2910, 2504, -2962, 256, 814, - -488, 824, -355, 3574, -1890, -2657, -767, 2730, - -1087, -2538, -3522, -4067, 6249, -3354, 13923, 4070, --11004, 4703, 909, -5968, -5483, -4242, -780, -2489 -}, - -.cb1108m1 = { - 752, -4098, 7726, 592, -9487, 2004, 318, -4322, - 6989, -3350, -478, -4308, 2023, 753, -7081, -3934, - -866, 6267, -5710, 2100, -8467, 100, -4654, -6773, - 4271, 10728, 11618, 1128, 12733, 1471, -5518, -1162, - -2159, -402, -632, -4720, -28, -1412, -1037, 897, - -1242, -1735, -2632, -3460, 3389, -582, 206, 325, - -2547, 46, 1340, -4424, -13408, -4918, -2832, 1454, - 2127, 1276, 2292, -3973, -3230, -7810, 542, 4227, - 2673, -8490, -902, 1361, -1398, -1986, -991, -680, - 602, -2887, -557, 2656, 3214, 1794, 31241, 1462, - -1457, -3750, -1923, -2381, 1313, -128, -172, -647, - -574, 1045, 2438, 1662, 503, 288, 1535, -1016, - 2487, -820, 4692, 2799, -31949, 166, -1655, -2192, - -636, 1357, -2361, -459, -1752, 2782, -293, -144, - 1900, 685, 1766, 1900, -347, -4488, 590, 915, - 798, 1133, -4494, -1388, 75, 884, 13088, -2392, - 679, -315, -7520, 1086, 3873, 3297, -812, -626, - -9443, 2548, -6417, 1619, 7196, -57, 5, 3594, - -1922, 184, 2784, -261, -3310, 2779, 174, 2814, - -965, -2912, -1835, 425, -4285, 896, 2001, 3717, - 775, -1192, 22365, -175, 1522, -711, -1135, 5123, - -517, 870, 4323, 585, -437, 260, -1737, -1984, - 2522, -2539, -973, -8812, -16173, 4678, -4107, 130, - -7832, 1140, 2792, 3394, -692, -4105, -299, 1488, - 1246, 604, 2796, -3767, 579, 188, -1544, 86, - 424, 1204, 4441, -1000, 15227, 3459, -3444, -1631, - -2177, 3497, 1684, 925, 2872, -3905, 5729, 647, - 913, -758, -547, 566, 1787, 792, -1509, -1641, - -926, -1515, -116, 1266, 481, -3944, 28526, -2279, - 5577, 1026, 4082, -605, 696, 1094, -478, 5732, - 7247, 1461, 1521, -234, -42, -878, 270, -554, - 3702, -71, 1362, 7719, 305, -13654, -4985, -1072, - -2044, 6851, 438, -8435, 923, -537, 1511, -1003, - 2056, -2299, -15578, 503, 1944, 3188, 2318, 1761, - 1290, -2322, -568, -1591, -2746, -1966, -9784, 1514, - -5596, 4070, -181, -3006, -1903, -240, -1143, 393, - -1530, -822, 520, 989, -1600, -3374, 946, 678, - 86, -1957, 1947, 1188, 356, 719, -2874, -2245, --19010, 547, 9067, 439, -2384, 847, -3307, -116, - -1114, -445, -3505, -967, -1252, 4880, 625, 1478, - -2970, -2275, 1337, 422, 3870, -1906, -1033, 1724, - -532, 1734, 1011, -21848, -477, -251, -615, 770, - 7520, 1030, -4372, -446, -3156, -2314, 172, 901, - 70, 1837, 1205, -1344, 2933, 1080, -1290, 1353, - 10205, 1158, 11135, 560, -3480, -2376, 7539, -5418, --14092, 2138, -253, -9344, -1907, 2177, 687, 2772, - -2730, -546, -4180, 2021, -577, 2530, -3822, -7080, - 971, 2083, -1220, 203, 3187, 3705, -752, -2591, - -704, -17469, -1168, -214, 2518, 308, -585, 1117, - -1893, 2488, 1856, -23, 2418, -2922, 1960, 235, - -1629, -8277, 1088, 2032, 874, 2763, -1867, 60, - 1684, 834, -2676, 1574, -3098, 3250, -3723, -126, - 59, -787, 2710, 930, 1384, 475, -3915, -1162, - 1640, -16818, 2356, -70, 761, 4151, -778, 523, - -183, 19374, -4223, -1379, -1667, -1690, -512, 8742, - -34, 3816, -678, 2749, 2418, -341, -1216, 4280, - -2208, -264, -2884, 4679, -821, 1824, -6724, -1528, --12042, -9908, 935, 4338, -116, 612, 6, -161, - 1935, 1600, -442, 4059, 2510, 2186, -7678, 3600, - -2460, -1072, -122, -1817, -246, 2786, 9079, 525, - -226, 2628, -2549, 1459, 4533, 1111, -17410, 4529, - -2545, -3272, 403, -2758, -1876, 2734, 2136, -6171, - -2055, 1163, -2820, 2992, 2978, 1458, 1572, 2508, - 13576, -1545, 14861, -796, -6444, 4022, -4358, -529, - 3439, -2630, -2457, 3030, -2972, -398, 471, 2547, - 1127, 1344, 202, 420, -1858, -589, 594, 1478, - 5590, 1682, -1560, -378, -2198, 400, 2231, 566, - -80, -2042, -4557, -2309, 8743, -4258, 1291, 11770, - 718, 2342, 2912, 5170, 2470, 6832, 833, 4990, - 2009, -1258, -898, -1414, 1214, 670, -2104, -5068, - 788, -18997, -743, -864, -356, 1592, -5786, 652, - 4952, -2319, -1097, 2177, -1654, 2879, -1645, -172, - -1581, -3062, -805, -1065, -2222, 20857, -1146, 864, - 1690, -1794, 855, 307, 2320, 3618, 6184, -4129, - 187, -2423, 4946, -3072, -213, -2621, -2026, -5793, - -986, -1597, 2125, 1474, 1766, 360, -4652, -1030, - 1546, -1085, -253, 1016, -96, -1608, -7017, -4855, - 1295, -271, 3751, 341, 19804, -2006, 2322, -2298, - 353, -2077, -764, 212, 150, -1140, 564, -614, - 268, -2023, -332, -699, -937, 1684, -1617, -22863, - 1202, -144, 62, 373, -598, 184, 987, 3721, - -611, 86, 3676, 362, -652, -214, -311, -694, - -1973, 2351, -733, -1601, -1189, 28227, -154, 10, - -347, 3400, 1333, -1695, -773, 1362, -447, -2999, - -626, -1776, 2474, 2195, -1041, -797, 1828, 62, - 3397, -1779, -2924, 1740, -1694, 4083, 15100, 3871, - -7821, -108, 292, 998, 3141, 5813, -918, -1290, - -902, 895, -1336, -50, 2014, -2066, 2383, 68, - 31769, -334, 1243, 1981, -715, 125, -380, -1272, - 1068, -357, -1734, -1138, -630, 1042, 688, -438, - -558, -2460, -2894, 4196, -1004, -2177, -2291, -4701, --13990, 747, -5558, -2754, 1950, -2780, 8414, -1286, - -946, 220, -2507, -192, 3726, -1361, 1296, -2215, - 872, 8270, -2797, -6732, 1256, -1957, -2916, 107, --14847, 1868, 4638, 1292, -1006, 5285, 2947, -5028, - 942, 153, 420, -1152, -391, 3612, 4621, 172, - 762, -876, -3561, -14406, -552, -2570, -4448, -15704, - -806, -928, 3380, -686, -2604, -3895, -714, -626, - -1763, 1144, 485, 34, -1922, 1528, -213, 5050, - -804, 185, 96, 3320, -621, -329, -1444, 864, - -1684, 16583, 1872, 3327, 2146, 1132, -8216, 73, - 6524, 1623, -4147, -4985, 1450, -646, -7189, 4524, - -1596, 2120, 3913, 680, 2094, 1660, 752, -1221, - 2414, 3986, -10314, 2096, 129, -5458, 634, -5426, - -594, -9731, 2083, -2284, -5085, -4777, -1323, -1740, - 6157, -841, -126, 247, -1163, -7005, 3863, -764, - -1552, 1356, 10788, -745, -12481, -73, 5234, -3220, - 2979, 635, 3372, -540, -36, 2887, 5221, 931, - -1724, -4824, 780, -49, 120, -739, 890, 714, - -1438, -458, -1861, -16732, -1858, -13282, 2182, -6796, - -3307, 556, -2968, 542, -2358, 1463, -3536, 1866, - 2833, -1369, -1576, -2825, 3561, -1625, 1858, -1052, - -1079, 1302, -2049, 19052, -1188, -4137, 1592, -4705, - 1082, -1168, 2355, 649, -1900, -2582, 1000, -3065, - -2399, 3625, 1062, 860, 2586, -2645, 14755, 3147, - 5002, -6720, 1728, -2114, 5090, -2838, 3020, -5048, - 4182, 2237, 706, -4945, -86, -1908, -1207, 135, - 675, -200, -22134, 1492, 2490, -1324, -1135, -842, - 1457, 185, 1342, 3516, -882, 1069, 1159, -52, - 1844, -1186, 554, 3860, 1824, -2136, -881, -1281, --13259, -705, -90, 2150, 573, 2787, 1068, -1968, - 121, 805, 4382, -1033, -9220, -744, -1446, 7180, - 257, -5983, -1643, -6198, 1854, -3524, 1060, -118, - 56, -843, 2832, -98, -3493, 368, 6, -1877, - -3615, -1954, 17971, 962, 1532, -1754, 3776, 661, - -2025, -60, -1013, -1222, -3062, -69, -4933, 3064, - -1176, 213, 477, 1081, 1679, -2328, 1984, -21759, - -881, -54, -1101, -1092, 598, 1648, -3384, -213, - 379, -1318, -1972, 630, -536, -1970, -461, -356, --22416, -1855, -113, 876, -2809, -587, -2323, -56, - 2177, -797, 1649, -4069, 1350, -2075, 101, -1384, - 1703, 1085, 471, 8093, 1020, -4112, 970, 866, - -1456, -341, 1418, -12938, 379, 9787, 1814, 2337, - -1705, 9913, 1026, 1962, -744, -2900, -1690, 1534, - -959, -629, 2330, 3735, 4742, -3139, -2135, 2298, - -2765, -1389, -3634, 27139, 671, 2208, 494, 1015, - -1197, -239, -321, -1145, -679, -637, -3116, 544, - -952, 882, 396, 1087, -3163, -2684, 759, -725, - -2186, -542, 2545, 3669, 24, 1689, 10473, 1836, - -419, 322, 2475, 1908, -1346, 50, -6401, -3644, - 552, 2348, 1327, 11853, 2467, 5493, 1544, 464, - 1796, -2801, 8217, 1014, -2103, 3764, 8091, 170, --12422, 1708, -2438, -1873, 1970, 2160, -5027, -647, - -118, 2830, 2379, -1091, -5723, 124, 3017, 417, - 55, 1376, -1079, 7122, 3086, 17847, 2468, 3273, - -599, 3302, -922, -2073, -1696, 805, 2022, -1899, - 3188, 1425, -4364, -140, -3760, 437, 1393, -1298, - 17166, -1283, -2904, -692, 518, -404, 944, -1990, - -968, 1323, 2376, -11708, 2187, 3164, -559, 2212, - 1598, -1741, 360, 633, 3075, -660, -1012, 778, - 565, -2020, -123, 5, -2217, -2967, 374, 272, - 336, -1725, -408, -2270, -2645, -1044, -517, 1911, - -386, -4439, -7603, -1000, 7660, 589, 14931, 2901, - 11998, -13102, -1919, 3904, 86, 1617, 7324, 3078, - 1714, 4636, -2504, -194, -3274, -710, 33, -1965, - -2298, 2513, 726, 75, 67, 884, 2104, 4110, - 1936, 10387, 2722, -1970, -12496, 4799, 3086, -2938, - 1719, -2138, -338, -1124, 971, -4200, 480, -3361, - 6220, 5954, 1830, 1001, 2996, 4166, -2854, -437, - -1430, 1072, -312, -12949, 3113, -2479, -2034, 6956, - 2805, 2128, 856, -8803, -4709, -1274, -120, 1252, - 3898, 6526, -3914, -2276, 2754, -2604, -3038, 4136, - 2598, -2172, 4861, -2457, 2, -2693, -808, 3527, - -1184, 392, -2202, 2406, 960, -1064, -2589, 1161, - 2418, 728, -466, -4865, 211, 14720, -2093, -1977, - 85, -12618, -2073, -3028, -1067, 1734, -2491, 9506, - -422, -2718, -2966, 3883, -2852, 336, 1306, -2297, - 2009, 2589, 3071, 192, -1239, -10553, 2, -1174, - -3036, 9939, -27, -1278, 1448, 18655, 761, 931, - 445, -94, 206, 448, -1865, 232, -4353, 4596, - -260, -976, 594, 648, 796, -1376, -1186, 3056, - 3171, -5675, 6179, -1287, 16934, -1478, 1090, 577, - 8075, 1119, 2943, -3208, 1852, 1986, 6003, 901, - -962, -3196, -1907, 392, -2605, 2796, 4082, -456, - -3109, -1219, 123, 2470, 174, -1254, -1350, -4919, - 1271, 12302, -1154, -6317, -3346, -1315, -144, 1214, - -49, 3491, -1029, -2043, -8373, 4197, 4971, 9808, - 9732, 700, 2247, -2755, -2034, 3260, 839, -10554, - 1661, 11484, -3180, -1909, 1089, -813, 3116, -2103, - -3726, -4514, 663, 1152, 3902, 4862, 2739, -3828, - 707, 2712, -8009, -832, -16492, -1472, -2422, -5593, - 322, -1894, 2810, 109, -1788, 2050, 3539, -3112, - -6178, 2487, 2102, -135, 3163, 2096, 4123, -310, - -1090, -2, -2662, -17087, 1373, 1448, 162, 527, - 655, -2248, -3530, 194, 1305, 7590, -5515, 1225, - 1607, -3816, 2185, -2679, -4486, -582, 4981, -1675, - 147, 14790, 119, 11771, -1228, 1012, -6133, -2247, - -3913, 1348, -1846, -513, -6386, -749, 6726, 745, - -809, -799, 3224, 43, -2230, 2598, 2994, -1590, --11198, -14476, -256, 695, 877, -3680, -2734, -1448, - 1336, -1633, 3327, 3497, 2956, -782, 2958, -1866, - 2876, 2003, -856, 1282, 5068, 391, -10539, 1703 -}, - -.cb1110l0 = { --14944, -14950, -73, -1141, 1532, -575, -620, -816, - 1185, -1597, -2651, 1426, -1458, 1317, -1320, -19, - -209, -352, -163, 912, -85, -180, -546, -1121, - -435, -345, 229, 364, -850, 632, -426, -359, --32768, 278, -1021, 310, -31, -355, -442, -234, - 415, -202, -10393, 1645, -378, -2270, 837, -1857, - 556, -935, -1344, 3016, 3452, 1597, 1378, 466, --13740, -878, 1475, 237, -1301, 9756, -592, 23, - -192, 335, -58, 285, 376, 40, 24, 292, - 426, -1962, -798, 745, 1379, -34, 397, -14748, - -6285, 7343, -6374, 4442, -14800, 1878, -24, 1606, - -728, -476, 1754, -1052, 911, 3139, -1444, -222, - -1968, 1858, 1330, 244, 213, 935, -92, -348, - 155, 418, 29128, 236, -190, -226, -309, -178, - -690, 46, 716, -534, 147, -630, -75, -826, - 37, 4745, -1056, 2400, 1398, 1494, 460, -221, - 2908, -656, -15611, -2940, 2342, -98, 581, -3144, - -471, 3772, 2057, 1583, 13738, -139, 330, 1175, - 429, 63, -14544, -374, 1439, -1226, -422, -690, - 816, 1279, -592, 1642, 700, 1338, 0, -714, - 46, 377, -188, -366, -197, -637, -622, -262, - -69, -637, -1266, 257, 620, -1040, 324, -19064, - -602, -463, -1329, 513, 2699, -421, -1918, 2250, - -404, 403, -1514, 134, 147, 3, 426, 605, - 276, 561, -26, -294, 630, -500, -480, -133, - -712, -1144, 238, -633, 173, -29164, -1182, -274, - -138, -271, -232, 30, 706, -168, -848, 704, - -2132, -248, -108, 669, 1165, 234, 1243, -12201, - 2208, -1971, -829, 10305, -3964, -1502, -409, -3918, - 4520, -2259, -797, 2235, -5560, -1710, -2472, 280, - -1747, -980, -4529, -5208, -1813, 330, 890, -6220, - -710, -5583, -4704, -913, 2920, -12484, -4340, 334, - -1303, 283, -740, -1261, 3556, 3210, -11640, -14438, - -2557, -795, 747, 546, -2488, 1891, 485, 725, - 338, 1579, 2092, 2354, 284, 2812, 490, 1442, - 187, -2699, 1196, -1783, 1228, 2364, 13364, 258, - 2102, -6163, -200, -5475, 2804, -576, 6878, -2852, - 2246, 1186, 584, -136, 5258, 3825, 3045, -1661, - -5246, 2548, -5054, -4383, -1542, 12912, -1580, 1268, - -1415, -2012, 1021, -2106, 979, 2390, 3411, -1076, - -439, 5416, 1333, 440, 3422, -13384, 2540, 2544, - -3668, -2308, 1042, 589, 4166, 5090, 1539, -3447, - 7003, -4396, 319, -590, 481, -471, 22260, -1936, - -297, 1302, 1163, 937, -164, 847, 768, 827, - -430, 792, 472, -1557, 712, -602, -1007, -278, - -974, -3198, 10560, -2124, 335, -1206, 629, -13712, - 12, -1673, -691, -666, -2890, 826, 1792, -1547, - -2016, 807, 1810, 841, -814, 1214, 760, -1056, - 404, -94, 144, 297, -584, 106, 116, -132, - 236, -507, 86, 853, -670, 413, 32767, 730, - 10835, -502, 1297, -3857, -1035, -1602, -164, -1721, - 1468, 507, 1064, 1478, 4323, -760, -882, -4331, - 2564, -10933, 3000, 2101, -2492, -72, 12636, 2743, - -1113, -8334, 6720, 2348, 491, -23, -1065, 1506, - 2090, -1731, -1997, 675, 425, 8165, 695, 2285, - -433, 515, -465, -347, -1006, 357, -55, 57, - 481, -31494, -816, 60, 76, -439, -328, -217, - 265, 123, 839, 218, 1355, 243, -878, -12819, - 5168, 318, 1376, -2931, 12689, -83, -220, 2848, - -770, 150, 1631, 1955, 1552, -1371, -3053, 1752, - -7250, -24, -514, -5568, -1529, -112, 419, -1136, - -672, -1847, -1136, 90, 453, 4810, 13012, -2355, - -2477, 1393, 451, 3390, 12, -2228, 1840, -2543, - -2404, -2969, 186, -444, 204, -265, -11467, 2204, - 1821, 3591, 67, 8821, 4015, -183, -5902, -1468, - 11394, 3062, -128, -476, 2495, -2888, 13482, 686, - -1320, 371, -884, 1829, -1810, 337, -1124, -1442, - 432, 1950, -1203, 663, -10445, 2310, 766, 137, - 4418, 2821, 135, 116, -12164, -3592, 686, 2310, - 1229, 1930, -1756, -1309, 1439, -3741, -305, 1547, - -9940, 3198, 1333, 2403, -2847, -3892, -259, -1766, - 881, 14310, -1711, -840, 2259, 3027, -1527, 1156, - 2904, -75, -728, 1536, -127, 152, -3240, -726, --11914, 1037, -851, -1893, -748, -3294, -1114, 6072, - 103, -1539, 4573, -1637, 5242, 2705, -9890, 254, - -1565, -407, 1818, -23004, 1110, 119, 256, -707, - -451, -679, 374, -935, -669, 403, -10, -594, - -525, 1403, -1016, -553, 595, -169, 2523, -82, - 947, 11572, -1166, 11668, -4962, 842, -860, 89, - -3308, -640, 558, -851, 622, -1002, -4933, 2762, - 1991, -121, 1401, -111, -49, 868, 135, -1392, - -279, -560, 412, -241, 1414, -802, -1256, -298, - 447, 17738, -320, -1150, 1650, -398, 5626, 6076, - -8919, 455, 12716, -2094, 157, 1361, -1515, 1494, - -6210, -553, -1785, -424, -3049, -4066, -1188, -732, - 1992, -1926, 1495, 1085, -22434, 1187, 391, -1512, - 747, -313, -502, 1331, 456, -323, 246, -581, - 56, 1448, 2071, 535, 782, 520, -136, -290, --12350, -11858, -456, 2340, -310, 22, 2210, -2531, - -392, -898, 3919, 1354, -332, -4255, 169, 425, - -476, 2577, -1172, 1984, 266, 514, -516, 2481, - 81, 2103, -710, 273, 1405, -14811, 5858, 3621, - -982, 345, 2044, 158, -2050, -602, 954, 342, - 239, 157, -317, -35, -260, 307, -31972, 228, - -77, 225, -154, 643, -883, -518, 32, 372, - 208, -22488, -458, 530, 104, 254, -775, -1264, - -571, 900, -263, -323, -296, 962, 520, 548, - -2196, 42, 1408, -211, -16117, 2052, 12656, -822, - 507, 321, -772, -786, -144, -3539, 892, -3430, - 19, -1831, 1161, 1836, 988, -1134, -704, -2994, - 692, 765, 457, 1624, 502, 13, 364, 337, - 32108, 1517, -225, 189, 141, 985, -572, 262, - -146, 31, 236, 269, -278, -1686, -13968, 1247, - -1009, 1046, 13467, 1276, -268, 307, -1383, 1544, - 136, 949, 70, 446, 1391, -2188, 745, -374, --14231, -712, -15202, -533, -108, -2244, -1232, 450, - -895, 1086, -782, -1082, -718, -660, 796, -2095, - 2722, -468, -1717, 147, -23566, 377, -220, -1731, - -1416, 486, -241, 266, -802, -322, 1066, -544, - -167, 520, -1297, -100, 622, 670, -188, 711, - 32, 1155, 628, 350, -112, -154, -1048, -44, - 36, -454, 304, 32767, 356, 462, -1194, 549, - 138, 0, 1044, -119, 195, 1098, 521, 3294, - -3776, -224, 4297, -1256, -303, 2107, 300, -13283, - 2933, -3194, -1408, -4152, 4195, 287, -932, 1247, - 13453, 277, 418, -598, 87, 1132, -80, -405, --13400, 656, -1310, -1447, -3974, 1719, 313, 500, - 1078, -114, 1449, -293, -120, -4754, 5583, 235, - -5140, -865, -484, 15572, 336, -1854, -154, -454, - -1475, -726, -3718, -4048, 1575, 480, 1094, -2209, - -3202, 420, -564, -48, 964, -2667, 2172, -1666, - 112, -730, 203, 3618, -15857, -4853, 48, -1084, - 1512, -937, 3353, -453, 223, 2267, 139, 190, - 1959, -720, 4389, 681, 10383, -112, 12390, -882, - 1695, 3539, -169, 3131, -122, 3627, 252, 185, - -523, 112, -219, 214, -182, -102, 118, 230, - -60, -801, -25, 42, -279, 262, -32358, 344, - -542, 382, -223, -404, 1201, -2646, -163, -803, - 3041, -1009, 3818, 756, 5834, 14249, -1828, 139, - -218, -658, -1314, -4980, -3322, -1461, -1598, -91, - 2464, -954, -5203, -791, 1339, -13598, 594, 702, - -388, -1115, -2377, -370, -3658, -3322, 1871, 2513, - 2910, 4095, -2195, 4291, 886, -567, 1182, -302, - -672, -21, -268, -29244, -199, -1024, -1284, 485, - 1432, -1086, 119, 1030, 418, -643, -1165, 1847, - -30, -844, -909, -416, -604, -609, -289, -391, - -238, -94, -391, -810, 413, 356, 954, -1935, - 30996, 441, 138, 1381, 1130, -2313, 558, -203, - -248, -951, 408, 1815, 256, -429, -892, -695, - 1138, 439, -760, -63, 6498, 570, 15252, -3397, - 170, 935, 338, 1, -528, 524, -541, -281, - -3, 499, -333, 685, 436, 32176, 389, -153, - 572, 256, 53, 16, -902, 724, 2849, 2503, - 80, 667, -1867, 742, 15205, -8715, -2588, -476, - -450, -733, -891, 1178, -1751, -1630, -114, 144, - -138, 10145, -188, -1608, -131, -247, -544, 9774, - -610, -2868, -3472, 345, -9294, 3724, 2634, -5124, - -392, 2551, -649, 782, -18, -160, -351, 12074, - 13865, -1294, 1262, -3135, -2861, 18, 753, 167, - 620, -2432, 1998, 740, 1902, 400, -206, 3518, - -3563, -632, 72, -1810, 1520, -827, -572, 1604, - -613, 3704, -736, 11100, 12702, -3189, -792, -3552, - 1621, 1841, 1236, 1215, -457, 9542, 9278, 2633, - -8801, 862, 1741, -4840, -2620, 616, 324, 2152, - 3632, 880, -472, 1927, -3456, -2105, -965, 3426, - -1893, 3095, -1152, -3542, 182, 998, -386, 1202, - 481, -1951, -510, -931, 1688, 151, -13664, -3894, - -973, -906, 1524, 9576, 2607, 12497, -819, -5214, - 5936, -634, -610, -4148, -421, -486, -1864, -306, - 2421, 724, -219, -1304, -2106, -504, 6762, 5266 -}, - -.cb1110l1 = { - -2972, -1201, -1388, -1762, 340, 21127, -999, 126, - 111, -1224, -1738, 311, -712, -450, -114, -648, - -752, -172, 67, 375, -967, -1032, -10763, -1885, - -2223, -3258, 480, -228, -143, -1299, 13128, -3062, - 1418, 6, -649, -1816, -288, 767, 345, 876, - -491, 948, 540, -167, 1969, -1883, -455, 20584, - -656, 114, 308, 279, 1105, -594, 1332, 255, - -356, -186, -540, 1898, -873, -477, 1404, 30475, - 370, -322, -337, -206, -440, -894, -54, -466, - -640, -408, -256, -560, -1503, 626, -573, -1684, - 419, 407, 2076, 5022, 3143, -1135, -12118, -12082, - -1462, -2060, -5432, -1092, 1575, 1958, -968, 122, - 958, -5312, 677, -1952, -12276, -1594, 1211, -1094, - 1992, -11032, -2993, -834, -1297, -1139, 312, -1546, - -4253, 1191, 21, 2771, 639, -2514, 6623, 746, - 1830, 2967, 1688, -14893, 7988, 4099, -97, 1165, - -2350, 65, -1308, 1834, -2084, 1683, 5118, -1633, - -10, -5282, 403, -1489, -264, 398, -2420, 12854, - -1498, -2642, -1486, 826, 699, -2213, -2296, 11849, - 478, -2202, -561, -250, 199, -2433, -948, -402, - 433, 403, 13031, -124, -180, 1499, -643, 527, - 11368, 5833, 938, 3202, -452, 2875, -1163, -117, - -2047, -1068, 211, 3122, -236, 13548, -702, 352, - -312, -1901, -2145, 2334, -12100, -76, -419, 362, - 3501, -220, -3086, 572, 1537, 3240, -1489, -1012, - 640, -513, 930, 390, 31019, 724, -78, -706, - 183, -157, -122, -847, -1156, 301, 508, -456, - 321, 317, 1300, -512, -1743, 10190, -294, -116, - 4183, 1374, 13360, -1339, 1832, 2547, -702, -2782, - -1464, 1176, -1287, 2256, 2169, 836, 2096, -248, - 1777, 11306, -211, 265, -3834, 336, 1936, -586, - 633, 1037, -1915, 12862, 930, -273, 2333, -3239, - 429, 374, 2518, -671, 570, -2208, 385, -284, --15613, -1752, 1341, -531, -744, -1111, 290, -2302, - -1012, -2933, -366, -30, -4595, 1400, 560, 48, - 15739, -945, 411, 1876, 2441, -2144, -1222, 12448, - 54, -726, -2743, 2548, 2100, 1307, 408, -198, - -1802, -63, -1919, 933, -329, -528, -15918, 1704, - 3028, 217, 606, -2804, 2052, 9320, 592, 969, - 6836, 647, -671, 584, -1, 3564, -2575, 436, - -2195, 414, -201, 1099, -772, -220, -578, -467, - 125, -934, 271, -21476, 288, 215, 216, 476, - -560, 768, 1142, -169, -1112, -14096, -14436, 2769, - -1464, -61, 1373, -3539, -1067, 1175, -1549, -861, - -332, -1876, 3159, 340, 1711, -2453, 457, 2536, - 1114, -2278, 2464, -3253, -466, 12291, 12484, -2868, - -800, 1142, -4244, -178, 3781, 1542, -663, 1976, - 3105, 145, -100, -1774, -1039, 1627, 15540, 4194, - 5392, 741, 1816, -544, -9100, 4255, -1083, -1266, - 2580, -4200, 1934, 1721, 129, 2276, -2704, -1341, - -1310, -11926, -1478, 199, 755, 619, 4231, -478, - -1627, -1242, 1842, 13170, -2416, 778, 192, 273, - 782, 774, 2188, -838, 3139, -1532, -1639, -1073, - -596, 770, -353, -53, 82, -322, -20584, -344, - -443, 158, -144, -554, 50, 954, -145, -336, - -2050, 596, -950, -2690, 13908, -13783, 4792, 879, - 584, -2987, 967, 192, -585, -783, -1341, -3108, - -1622, 2478, -1362, -1470, -1556, -430, -110, -736, - -8097, 2073, 964, -417, 1669, -5425, -7846, 536, - 12883, -1690, 1143, -242, -438, -2274, 57, 302, - -574, 637, 2816, -1642, 2166, -172, 893, 421, - -614, -565, -338, -526, -1085, -939, -1138, -991, - 1919, 1720, -18845, -1950, -342, 1930, 321, 184, - -956, -374, -462, -216, -6, 26, 386, -50, - 603, -720, 634, -252, 261, -860, 218, 22846, - 11544, -459, -946, 452, -102, -1203, -1802, -1105, - -310, 787, -220, -1113, -2043, 650, 13767, -3638, - -296, -902, -413, 252, -816, -172, -505, -1335, - 890, 768, -523, 808, -331, 20000, -264, 1763, - 133, -1, -464, 949, -954, -147, 1780, -190, - 30, -7422, -4615, -1006, -470, -742, 500, 7509, - 1500, 1550, -3614, 810, 2595, 1506, -12926, 3588, - 402, -2547, 1505, 65, 4, 3382, -2201, -2441, - -1521, -5450, -3820, 282, 5212, 1186, -1056, -2334, - 988, 12987, 390, 4141, -2680, 1663, -8034, -1792, - -225, -674, -7147, 13254, 1631, 10163, -3332, -7, - -675, -735, 772, -2299, -326, 1641, -1174, -1911, - 82, 776, 891, -445, 18590, 238, 1417, -2372, - -9718, -2682, 600, -1401, 604, -1791, -22, 1546, - -1764, 525, -1355, 348, 3260, 1115, 204, 524, - 225, -12776, -679, -15595, -1188, 1078, 82, -859, - 28, 819, -1220, 563, 2309, 331, -1158, -2010, - -264, -383, 1732, -424, -2742, -775, -329, 132, - 391, 1261, 1033, -9812, -11829, 2433, 2690, 606, - -2724, 7216, -296, -1834, -1694, 456, -4732, -400, - -3192, 1428, -316, -13674, -2702, 2320, -6548, -2025, - 1222, 1749, 4005, 2924, -3539, -5104, -2333, -1438, - 2598, 62, -757, 760, 343, 154, -31947, -534, - 1296, 697, 88, 345, -577, -500, -174, -326, - -198, 272, 157, -815, -636, -1163, -867, -273, - 1054, 774, 1624, 989, 107, -1088, -673, 2143, --22962, -566, 151, 72, -27, 1034, -444, 501, - 1905, -1455, 21, 289, -10670, -789, -2421, -2686, - -327, 804, -3009, 907, 960, 1379, -43, -552, - 2203, -1406, -911, -11094, -529, 4458, -4152, -70, - 3162, -12546, 326, 874, 1426, 3019, 2315, 104, --12516, -1591, -2877, 772, 1982, 1160, -4491, 3417, - -1524, -2139, 130, 930, 9359, -18308, -376, 4090, - -468, 156, -216, 60, -643, -3440, 256, -835, - -2389, 1660, -542, -1628, 4270, 3574, -3136, 433, - 1069, 30024, 561, 268, 790, 294, 207, -1552, - -736, -97, -215, -98, 690, 686, -202, -736, - -453, 655, 511, -156, 1006, 361, 1424, -1254, - -361, -1253, -1419, -290, 78, 555, 565, -488, - -923, -18193, -630, -908, 188, 925, -1684, 241, - -319, -14478, 17007, -1415, 274, 592, 1344, 1784, - -731, 344, 992, 141, 290, 481, 628, 623, - -1166, -2092, 140, -1056, 13736, 754, 1980, -238, - 2132, -1372, -2216, -12057, -1662, 66, 1742, 2209, - -962, -1574, -3044, 173, -3066, 183, -4476, -1016, - 6160, 780, -1193, -3334, 179, -371, 244, 160, - -686, 669, 330, 426, 65, 159, -664, -186, - 479, -742, 54, 605, 32603, -941, 370, -91, - 856, 825, 1042, 374, 651, 313, 734, -240, - -49, -685, -1994, -604, -875, 44, -884, 886, - 13012, -1506, -4317, -1926, 3050, -1027, -482, -40, - 137, -2560, 1366, -11812, 2112, 2266, -2690, -1339, - -700, -243, 2322, -1042, 4635, -3210, 4281, 47, - 670, 9218, 1165, 814, -62, -2276, 12987, -714, - 2481, 1355, 896, 2840, -1664, 2048, -345, 2285, - 1754, -669, 2284, -288, -575, 944, -1528, 44, - 1071, -706, -543, -1347, 880, 257, 1364, 1444, --17896, 99, 1539, 1813, -611, 355, -2290, 980, - -787, 132, 300, 2353, 204, -798, -296, -594, - 895, 842, 18755, 1129, 79, -189, 515, 882, - -286, 109, 305, 374, 1323, 861, -18, -78, - 294, -320, 674, 504, -159, -549, -95, -32403, - -90, 658, 1082, 1611, -137, -74, 1160, -794, - -55, 822, 2627, 1203, -3540, 9829, -7860, -9063, - -4015, -894, -2218, 729, -879, -1869, -2446, 4050, - -488, 13211, -290, -820, 371, 14196, 866, -891, - 218, -1838, 2162, 1144, -186, 512, 1416, 546, - 3298, -1253, 128, 1202, 557, -1967, 680, 545, - -139, -3008, 18453, -3322, -137, 163, 1377, 1116, - 2572, -1577, -1846, 651, -1319, 796, -862, 331, - 4383, 2453, -1894, 3264, 14137, 842, -3087, 3740, - -1100, -2400, -1364, 2406, 417, -2393, -868, -3158, - -9712, 3480, -1403, 1896, 201, 1285, -593, -11718, - 99, -539, -186, 45, -2266, -12228, -2658, 2802, - -1198, 1022, -3840, 1401, -1918, 1655, 1725, 96, - -205, -913, 1629, 568, -1285, 1264, -1160, 594, - 223, -336, -1436, -472, -19792, 553, 1494, -195, - 570, 282, -653, -54, -1115, 153, -484, 141, - -188, -278, -173, 464, 13, -634, -42, 390, - -464, -246, 622, 1229, -692, 29175, -574, 1150, - -135, 2685, 2452, 63, -962, -918, -1657, -1978, - -172, -677, -3414, 1345, -3964, 2875, -1412, -654, - -3000, 10739, 11348, -2232, 516, 8303, -189, 2564, - -150, -373, 903, -275, 2394, -1135, 508, 424, - -1704, -2222, -3789, 1938, 216, -12702, 2488, -1364, - -2175, 1114, -819, -2756, 1564, 952, 36, 609, - -933, -1568, 110, 143, -1575, -4236, 528, 15042, - -1920, 348, -2623, 5217, 1911, -1088, 259, -590, - 364, 2081, -3585, 662, 249, -119, -111, 778, - 2167, 11, 2500, 7182, 14452, 4388, 4121, 3623, - 1598, 532, -507, 877, 3830, 372, -2184, -2810, - 11748, -2095, -1079, -3070, -768, 2901, -3587, -2572, - 10008, 563, -4588, 1026, 1117, 1879, -12004, -416, - 317, 2032, 1800, 1058, -84, -296, -1748, 2588, --11019, -1627, -3264, 2480, 96, 2146, -2672, 2418 -}, - -.cb1110s0 = { --32746, 360, -2774, -672, -1808, -14, -1037, -1327, - 1409, -2215, 172, 1557, 945, 2031, -702, 1844, - -1106, 472, 2603, -978, 2782, -5691, 1473, -5668, - 7129, 6600, -2160, 108, -1844, 2062, -2395, -740, - 1690, -45, -725, 77, 7236, -12903, -3356, -764, - 1870, 720, -2201, 790, 9950, -3694, -5340, -4031, - 4115, 6863, 2352, 1484, 3606, -4855, 714, 4104, - 6240, 7261, -6855, 4919, -2847, 6701, 7469, -616, --11442, -1935, 9157, -4072, 133, -5976, 2455, -9360, - -2898, -4353, -7721, -3098, -3505, 2568, -5432, -576, --10072, 250, 2173, -4196, -4322, 2688, 5220, -6026, - -346, 11678, 2071, -7344, -2182, -530, -180, -2568, - 1524, -1617, -8825, -4845, 2794, -2813, -2669, -2423, - -2709, -8985, 2105, -4629, 708, 2040, -5680, -2470, - -7277, 6841, 6523, 4196, -6788, -1982, 3844, -5000, - 156, 1930, 1780, -3824, -286, 3908, 1703, 7304, - 1145, 144, 1180, 7145, 3175, -13823, 6580, -3066, - -6321, -9739, 4432, -1145, 2923, -2636, 3838, -7037, - -3913, 1262, -1398, 363, -141, -886, -5667, -212, - -2118, -2717, 2724, -18802, -2098, -155, -1399, 782, - 797, 766, 2613, 5374, -3767, -1711, 624, 693, - 2544, -6153, 7179, 6835, -762, 5061, 655, 2600, - 9208, -7030, 7047, 1654, -3404, 176, -5486, 1374, --15378, -487, 7456, -1954, 2404, -2994, -1608, 2362, - -498, -7952, -6143, -3996, 1596, -3013, 1181, -1534, - -5265, 220, -2677, 1047, -4629, -15066, 3966, -446, --11713, -5694, -393, -250, -1336, -7394, 1508, 6239, - 3788, 6273, 6215, 822, 2657, 8057, 8391, -658, - -2561, -11587, -2589, -6702, -9227, -1016, -2220, -9702, - 5988, 1859, -6100, -4594, 221, 2529, 2217, 8273, - 1804, -6128, -2859, -8259, -4707, -2494, 1913, -352, - -4561, -289, -1801, -994, -4445, -1001, 5422, 10868, - -7366, 1679, -5195, -6859, 2982, -406, 2400, 4520, - -3611, -1892, 4900, -3504, 771, 2774, -772, -1929, - -7354, 375, 628, 4522, 1069, -969, 8083, -155, - 3178, -1138, 1752, -17288, 4390, -2483, -2071, -1353, - -1155, -456, -2683, 6798, -1908, 1797, -6657, -2770, - 5610, -14518, 5922, -3964, -938, -853, 1416, -1077, - -4562, -160, 5820, -3031, 5091, 1987, -2746, -3779, - 238, -264, -3074, -11718, 9370, 9806, -6302, 3979, - -2938, 4034, 393, -1399, -4466, 2181, 756, 394, - 2264, -3664, 78, 470, -3228, 3942, -1714, 708, - 4988, 1938, -2722, 4555, -5054, -1026, 19312, 354, - 107, -5357, -4364, 597, -2566, -2812, -2278, -446, - 1384, -371, -2566, -388, -3964, -8989, 9136, 3389, - 8440, -5570, -1262, -5874, 2056, -5973, -185, 4540, - -4924, 154, -3653, -1113, -3048, 7099, -2734, 2940, - -6704, 1543, -8120, 10134, -9485, -6645, 4816, -442, - -32, -2430, 4932, -6129, -5050, 6120, -2147, -6910, - -1342, 1075, -2458, 50, -4747, -3080, 1886, 1490, - 18972, 48, 787, 2441, -405, 1668, -1399, 2202, - 2175, -3592, 1548, -2728, -4864, 504, 383, 376, - -1073, 2142, 504, -3114, 6378, -5516, 13462, 196, - 1840, 7087, 792, -3583, 302, 1012, -5504, 270, - 3354, -4486, -2312, -2522, -2872, -3899, -2261, 5211, - 1417, -3075, -151, -985, -772, -1630, 164, 659, - 1496, -349, -621, -32, -2982, -1720, -3475, -7370, - -1541, 1122, 20474, 1726, 4474, -3228, 7024, 3265, - 522, -2193, -2113, 5388, 1912, 5929, 11768, -1162, - 2600, 4048, 652, 3360, -3215, 376, 10028, 6054, - -3814, -1155, 93, 4512, -3581, -4037, 7484, -1481, - 2797, 2635, -12275, -2780, -6235, 5739, 2687, 376, - 5984, -2547, -8834, 4332, 2752, 1942, 1002, -3312, - 5251, -86, -7794, 918, -2413, 3131, -3316, 2095, - -4569, -15382, -5534, 1290, 5179, 2928, 3034, 2365, - 270, -7476, -3024, 6910, 1355, -6262, -2040, 10490, - 1432, 12284, 1125, -3160, 4518, 973, -2351, -1726, - 1967, 1488, 382, 3559, -3742, -2908, -944, -1662, - 682, 902, -4360, 5026, -4252, -1212, -3269, -6024, - -3788, 9128, -2638, -1625, 315, 3087, -3265, -10441, - -7207, -4078, -3266, -7543, -5223, 5460, 2496, -9258, - -227, 4048, 860, -520, 13616, -3458, 3837, 809, - -104, -4062, -4846, -136, -1631, 13977, -1136, 3380, - 1099, -4022, 1831, 3360, -9034, -52, -516, 10144, - 5074, 4866, 8282, -972, 2496, 2336, 8766, 2881, - 2417, -5588, 3064, 3934, -4202, 627, -986, 1750, - 958, -2348, 5006, -2597, -90, 133, 23271, 2431, - -3984, 1894, -2094, -1816, 5007, -3164, 2526, -1862, - 2651, 1809, 7173, 3410, 154, 14930, 3032, -5314, - 44, 8868, -543, -2158, 5341, 258, -8188, 3772, - 2804, 7544, 8339, -3560, -63, -735, 1300, -4308, - -1085, -4986, 1564, -6744, -2605, -310, 1275, 1166, - -640, 4814, 4373, 3103, -1242, 6049, -4786, 597, - 182, 2371, 6950, -2265, 389, -14669, -1942, -2733, - -485, -865, -597, -1376, 1626, -3956, -1244, 1532, - 3918, -3311, 1574, -88, -20573, -5471, -71, -1731, - 1436, 2428, 3982, -4576, -914, 5460, -4973, 1650, - -2364, -2486, 3212, 5424, -2501, 4595, -937, 728, - -5140, -9948, 1437, 10560, -5704, -264, -2752, 949, - 5229, -1445, 430, 827, 4103, -1999, -4625, -4171, - -8769, -8927, 7161, 4539, 6968, 5975, -4626, -2793, - 10080, -10386, -2479, 1724, 2992, 354, 3650, 3328, - 4490, -1931, 7348, 7283, -3304, 4446, -1698, -1224, - -3002, 4340, 1041, 607, -454, -4261, -18071, -1199, - -3902, 570, 5808, 5582, 6710, 235, -205, -4288, - 3472, -686, -103, -3658, -436, -9680, -190, 275, - -919, 2522, -2087, 9096, 5060, -6450, 10282, 3344, - -8167, -7688, 11881, 3101, -1280, -9942, -11741, 2213, - 712, 3976, -4218, -5285, 2797, 2996, 4006, 2053, - 2344, 6200, 141, 2616, -3981, 6970, -4194, -1621, --13724, 7772, 2800, 2220, 445, -266, 4030, 444, - -228, 2642, 1617, -2511, 1699, 8740, 3438, -2063, - -2093, 1806, 950, -7112, -1513, -2886, -8789, 870, - 3456, -4126, -3330, 541, -10173, -1789, 3156, 4466, - -5965, 479, 5177, -2806, 2506, -1646, -3609, 1617, - -7373, -3146, -2389, 3601, 7850, 89, -3373, 4670, - -4180, -3186, 3056, -1691, 1314, 9234, -7799, 1323, - -4360, -9866, -1930, 8091, -13452, 8503, 1980, 11247, - 7688, -5953, -4165, -3192, 540, 1631, 131, 2250, - 5330, -146, -8724, -3148, 2834, 1148, -3886, 374, - -1836, -3898, 9649, 1119, 10221, 128, 8868, -7301, - 2601, 1252, 2340, -3789, 4682, 181, 4434, -1740, - 4368, 879, -620, 2046, 1842, 844, -925, -2506, - -3344, -8820, -722, -451, 521, 903, -1286, -3059, - -5308, -4759, -2706, -1429, 2762, 927, -1459, -7274, --12028, 8838, 3987, 2406, 8626, -3128, 6505, -4322, - -197, -2464, 2738, -46, 161, 13919, 2252, 2059, - 981, 204, 1161, 4910, 683, -4311, 2081, -1932, - 1119, -6067, -5325, 8528, -4704, -5522, -6183, 5744, - -3407, -2021, 2688, -3230, 2490, -976, -500, -7834, - 2064, 3191, 4740, 3686, 1762, 2604, -2442, -5720, - -7550, 457, -3478, -8097, -6510, -9105, 8031, -4895, - 500, -2436, 1483, -4415, -2023, -3768, -2497, -1911, - 789, 566, -969, -4204, 6128, -5076, 2664, -4222, - 6755, 1774, 6881, 64, 1205, -9243, 4782, 4432, - 5193, -2258, -4787, -7433, 1755, -794, 1297, -7535, - 12773, 9124, 806, 2348, -8112, 7874, -4348, -1410, - -350, -2528, 576, 661, 272, 4598, 691, 1913, - -3349, -1881, -1854, -779, -821, 8444, 60, 2570, - -1813, -1354, -4512, -5471, 4728, 3289, 2617, -9326, - -6670, -859, -2713, -9839, 4676, -2657, 3106, -1393, - 10278, -3069, -2253, 1015, 2246, -2227, 16, -388, - 7962, 1493, -3122, -2707, 7982, -6106, -1462, -1665, - -1302, 2347, 3640, -15122, -2211, 417, 6819, 959, - -2876, -6868, 11060, -2329, -302, 1595, -4610, 9514, - 12677, -4614, -2899, -141, -4857, 1447, 6400, -2894, - 1696, -2888, 1889, 3489, 2775, -504, -6597, -5258, - -7256, -379, -1249, -136, 3118, -3537, 3295, -3458, - 2103, -399, 15281, -222, -1809, 172, 2257, 1947, - 707, 3562, -5691, 3575, -2210, 5750, 815, 4059, - -16, 1306, -13308, -1733, -1338, -3477, 5247, -1950, - -5148, -678, 8074, 1740, 290, 2033, 4639, -4240, - -536, -5214, -1366, 2491, 501, -59, -4480, 430, - -285, -5947, -755, -14559, 5696, 6960, 4462, 2317, - 6414, -13174, 4962, -899, 5924, 11100, 5303, -970, - -2528, -6239, 2253, 2236, 553, 458, -2229, 8016, - -7082, 2869, -4209, -4460, -6536, 3557, -1766, 7815, - -655, -6029, -5250, -1627, 2646, -3466, -3584, 901, - 10305, -895, -427, 949, -2776, 3436, 769, -4131, - 9019, -4898, -3562, -7978, -359, 1358, -1528, -3095, - 5840, -6214, 2591, -2086, 9480, 640, 2858, 216, - -3625, 5740, -7008, -1097, -2091, -143, 4832, 6210, - -1358, 3998, -714, 835, -4004, 3664, 1980, 1240, - 2902, 510, -1565, 427, -2052, -4208, -1505, 1187, - -1229, 3732, -932, -1014, 4784, 18474, -5111, 3047, - -54, -1547, -3892, 8612, 274, 1446, -3548, -7689, - -423, 1192, -4508, -10403, -8735, -446, 444, -6353, - 4008, -1462, -8906, -1161, -2395, 2442, 2204, -5472, --17376, 2471, -689, 1394, -3657, -2119, -769, 2872, - 1393, -2701, -3536, 3650, -378, 859, -3338, 1412, - 3010, -3243, -335, -3619, -511, -1931, -7126, -5018, - -9332, -4440, 1906, -2265, 1386, 8072, -6576, -1300, - 5458, -4894, 630, -7146, 2263, 810, 2968, 1124, - -2219, 2292, -3914, -1836, -6683, 1511, -2755, 1396, - 2425, -23842, 2249, -53, -891, -1678, -1766, -1788, - 502, -4210, 211, 10376, -5507, 837, -6196, 2132, - -472, -10153, 7234, -1456, -148, 4886, 2427, 2371, - 1234, -962, 6298, 1016, 1735, -566, -878, -8071 -}, - -.cb1110s1 = { - 2525, 12164, 4861, 9505, -7371, -414, 3002, 576, - -347, -998, 2861, -804, 3034, 810, -788, -539, - -2092, 4970, 1828, -2869, -2802, 6649, 3673, -193, - -4034, 722, 1642, 3792, 8770, 10428, -3303, -3849, - -4520, -234, -4190, -1219, -1300, -4128, 8384, -1150, - 1578, -6174, -1072, -4871, -8180, -6698, 3806, -7386, - -2545, 1052, -550, -1148, -1308, -8834, -2654, 1982, - 8716, 6579, 1360, -2404, 1893, 2680, 3801, 11097, - 1455, 2453, -7585, -7503, -12710, -420, 2023, -656, - 1124, 2872, 9676, -4309, -202, 1458, -6526, -534, - -1535, 924, 3068, -1142, 5073, 1284, -5632, 869, - -1637, -2898, 4900, -10202, -10488, -1097, 1890, 11006, - -44, 1368, -1979, 6507, 316, 961, 8, -4085, - 2561, -2034, -1077, 2594, -465, -5134, -868, 54, - -6694, 9608, -3516, 7165, 11011, 9542, 4780, -2800, - -1130, -1714, -2684, -369, 4746, -2688, 4146, -7652, - 984, -3263, -276, -9134, -2848, -3983, 9994, 3608, - 3234, -596, 263, 3102, -178, -2264, 3820, -4293, - -5752, -3577, -3914, 1095, -1562, 22110, 4610, 69, - -2999, 254, 2178, -2901, -1203, -1292, 2642, -3254, - -1389, 2955, 1340, 542, 810, 1369, 3208, -795, - -3272, -2717, -1129, 8781, -6854, -3028, -616, 729, - 529, -6946, 1621, 9574, -14909, 5398, 854, -774, - -9978, -5417, -2516, -4683, 5715, -66, 3336, -5040, - 640, -7566, 3494, 7016, -2269, 1376, -13994, 6448, - -3948, -1697, -3988, -6559, 2376, 4231, -3131, 2045, - -2417, -5919, -7016, -1695, 9046, -7966, 5187, -2553, - 1402, -2351, -220, 5931, -1823, -2270, 584, -3784, - 2924, 6166, -3035, 2370, 4923, -1080, 682, -7899, --10827, -1824, -908, 1568, -3565, 4033, -4266, -1948, - 923, 5488, -203, -2396, -907, 2783, -3278, 1415, - 7710, -190, -5208, -2279, 1266, -1132, -3392, 10251, - -1064, 11283, 2162, 2213, -5088, 4479, -4658, -1803, - 1534, -4233, -4073, 6938, 3966, -4878, -332, 5961, - 9217, 488, 6520, 4430, 7988, 9383, -2586, 1206, - -6983, -873, 1251, 1849, 5945, -2144, -2032, -1852, - 416, 3720, 2419, 8462, 3173, 11524, -2894, -5517, - -211, 17830, 3170, 1098, -721, -2066, -1956, -3097, - -1061, 2815, 447, 701, 449, -485, 2609, 1239, - 2257, -1760, 3091, 7538, 3710, -2689, -3092, 6903, - -2457, 3271, 6355, -1486, -828, 1994, -3575, 3949, - 3185, 2606, -4912, -16039, -8833, 1831, 2580, 1993, - -1117, -3408, -7590, -7278, -141, 2696, 805, 1896, - 308, 378, 9308, 2894, -4324, 1042, 837, 4716, - -4702, 2493, -5173, 8616, -468, -14829, 3759, 3251, - -4237, -1340, 5224, 2099, -764, -8263, -1699, 76, - -1464, 2115, -582, 3286, -3653, 1017, 1696, -1414, - -668, -9748, -5730, 2413, -1270, -6070, 17002, 2164, - -5440, 1801, -2123, 800, 2135, 4801, -887, -2141, - -647, -4846, -463, -577, -1846, -555, -1929, 2046, - 8272, -8399, 3886, -5950, -4202, -12600, -2805, 477, - 65, 6140, 1089, -4737, 8967, 1952, -1968, -3660, - 6641, 850, -3304, -1775, 4010, 10819, 14365, -696, - -1331, -1724, -237, -3611, 244, 3005, 4349, -182, - -4124, 2466, 2746, -61, 3391, -1392, 3788, 1582, - 3723, 7140, -2207, -3678, -2675, -252, -7476, 9426, - -6196, 3226, 3554, -6326, -4284, 6346, -4432, 5199, - -2633, -2499, 1200, -1140, -3910, 6624, 16732, 5946, - -766, 2630, -1200, 1988, 5510, -1199, 4126, 1287, - 454, -1795, 2664, 5001, 1058, 500, -437, 2992, - -2012, -160, 796, -4846, -6572, -10088, 603, 483, - -4510, -12799, 3502, -1784, 3510, -3956, 6038, 9044, - -6029, 7170, -1608, 120, 914, -200, 3939, -6274, - 3020, 6235, -2754, 5368, -1693, -6028, 386, -2006, - 1898, -11704, -9973, -525, -2624, 1799, 4140, 3248, - -57, -3731, 3764, 5582, -3830, -2484, -2066, 1517, - -900, -8250, -8191, 2676, 1147, 6752, 6908, 1196, - -2634, 3408, 2980, -1042, 3971, 632, -4946, -5690, - 133, 2445, -446, -1294, -777, 3356, -5628, -6020, - -8042, 5069, -1421, -2701, -15117, 3074, -912, -2574, - 2643, 5252, -2118, 3849, -3793, -850, 4170, 6240, - -697, 6976, -3752, 1155, 7769, -8912, -7728, 4224, - -2362, -3760, 3688, 2402, -3411, -3165, -2550, -8, - -209, -334, -837, 5688, 3425, -4564, 9999, -4780, - 3093, 4346, -5556, 1636, 1755, -14696, 1810, 6547, - -60, 4054, 10539, 6118, -4414, 1760, 3581, -841, - 4471, -23, 180, 259, -4439, -13230, -1326, 1913, - -621, -1641, -2882, -4934, 516, -3886, -4468, -110, - -4526, -5157, 7550, -4449, 813, -4364, 1768, -8829, - 2003, -1372, 1873, -209, 1539, 1076, -12408, -1464, - -1878, 1563, 2020, 704, 1425, -275, -3718, 4618, - -1120, -5057, -3590, 4022, -1977, 620, 143, -2507, - 3697, -3263, 616, -3002, -3347, 21051, -4398, 364, - -1924, 284, -2724, -2297, 4916, 2702, 4866, 4293, - -2781, 1094, -1525, -562, 5487, -2098, 4658, 1362, - -597, -3426, 3173, -5174, 3922, -3844, 1482, 4711, - 5853, 1490, 5499, -17537, 956, 544, 268, -4782, - -504, -4003, -911, 599, 1746, -7322, 1907, 1990, - 16985, 3171, -2645, 1040, -7239, 5618, 304, 3606, - -3377, 3630, 7319, 108, -496, 1026, 3062, -392, - 2366, 1948, -530, 806, 2700, -2676, -2717, 5238, --16008, -823, -264, -1560, -1014, -760, -3684, -330, - 5644, -1668, -10239, -2583, 7411, -593, 2193, -1479, - -2892, 3834, -3625, -12234, -1103, 1868, -5121, 3879, - 2748, 1936, 2026, 4572, -6037, 3310, -8678, 11724, - 5290, -2316, 4131, 834, -3915, 869, -1734, -5752, - 1255, 9534, -3625, -115, -5912, -125, 2298, -1494, - 5910, -496, -2719, 1320, 3175, -3012, -3906, 4602, - -4760, -5918, -2568, 6632, -8802, -5876, 6358, 2349, - 207, 5191, 8369, -5932, 2710, 7950, 3673, -2592, - 1311, 8384, -4360, 8614, -5662, 1180, 2147, 1044, - 1591, -5555, -1597, 4418, 38, -1579, 4675, -1725, - -1693, -6470, 3066, -7601, -12822, 524, -2986, -3406, - 8860, -1266, -930, 4316, 1171, -2908, 199, -1785, - -2851, -3588, 3072, -3585, -2668, -1123, 1508, 460, - 6780, -19480, 2854, -1574, 1004, 5074, 1907, -1988, - 1177, 74, -1436, 2224, 1232, -3008, -3454, -862, - 604, -653, 2778, 2349, 3242, 8426, -430, 3684, - 4814, -1886, 5118, 1487, 442, -2322, -900, -2854, - -234, -10350, -7922, -745, -1490, -5638, -6014, -4079, - -2979, -351, 9493, -2274, -11362, -8166, -7364, 8261, - 1554, -1722, 4651, -831, 2276, 1502, 2600, 1266, - 4456, -4145, -3837, -3584, 4242, 4058, -2395, -6971, - 4486, 3233, 6226, 1306, -11506, -6223, -5132, 1537, - -4407, 1510, 5732, 2808, 5817, -4972, -2900, 897, - -2441, -1819, 5651, -6988, -10063, -2288, -5820, -1250, - 925, 3120, 6125, -9901, -137, 3684, -6601, 1077, - 3272, 21, 3341, -838, -3643, -1727, -4417, 660, - -6551, -184, -8125, -1780, 5232, 6077, -7968, 6423, - 3823, 3026, 4555, 464, 3318, -5504, 837, -3571, - 3853, -2277, -1864, -742, -5380, 6096, 6856, 1076, - 877, -642, 1926, -4712, -14482, -3323, -2672, 7485, - -2116, -3932, 2233, -3270, 326, 2221, 132, -1893, - -748, 453, 3597, -2308, -4371, 5632, 3609, -1033, - -444, -2591, 17359, -3120, -2604, 3157, -370, 9242, - -1606, 2675, -853, 1475, -416, -3280, -1159, 191, - -3670, 282, 4282, -957, -2978, 3564, 91, -20520, - -3046, 1248, 1277, 3368, 1118, 311, -598, 1406, - -2377, -1444, 1417, -3626, 167, -6440, 3341, 629, - -2523, 4398, -1187, 4322, -383, 1934, -3298, -8530, - 2195, 5220, 510, -1256, -6932, -1061, 5141, -16242, - -1390, -546, -3760, -2029, -929, -6044, -3503, 312, - 8478, 701, 8865, 4715, 1987, 1342, 1400, -71, - -5229, -1547, -8827, 2349, 12836, -1479, 4621, 6003, - -6749, -3184, -5667, -2930, -1074, 3204, 330, 4692, - 2872, -10808, 75, -1260, 18003, 4100, -1462, 1391, - -1667, -2039, -687, -4806, 5913, 2682, 7730, 7034, - 2703, 1666, 120, 1601, 2123, 1402, -4702, -11229, - 7875, -5591, 4634, -2274, 3015, -597, -7520, -1095, - -4814, -173, 5562, 1533, 2807, 8466, 5195, 7806, - 2585, -2877, 6938, -3942, 402, -3825, 4162, 9149, - -6423, 2447, 7041, 2932, -9813, 2124, -58, -3, --12856, -7973, 1484, 907, 180, 8042, -2124, 4356, - -4117, 1126, -9706, -2101, 3957, -1877, 1139, 7148, - 3707, -1341, 4509, -1220, 4570, -1650, -6504, 7036, --10268, -328, 4678, -12205, 5062, 6089, -496, -7740, - 2207, 4489, -205, 1386, -2695, -1442, 4730, 892, - 12061, 3818, -3305, 4431, 9300, 3470, 4608, 4315, - 892, 866, -1714, 1529, 2569, -11398, -3068, -282, - 1626, 587, -1568, -1630, -220, -2033, 7141, -2732, - -3541, 3404, 15514, 1883, -2697, -926, 5972, 6485, - -6794, 2111, 2490, 1201, 5467, -2352, 3264, -97, - 2400, -728, -3364, 3417, 1481, 2862, 462, 2855, - -5233, 5740, 7208, -10508, -3254, 1450, -1270, -293, - 3400, -6978, 10035, -1213, 4308, 2641, 8579, 8518, - -2919, -351, -459, -2069, -617, 638, -1347, 107, - 6009, 2035, -280, 2009, 3280, -1236, -14960, -5177, - -2440, 965, -2646, -2095, 5274, 1825, 3705, 3831, - -446, -4018, 7178, -2415, 4344, 1850, -509, -500, - 1056, -4374, 5709, 1336, 3352, 7915, -2302, 12209, --14362, 6429, 1423, 2912, 6474, -1599, 1116, 2280, - -1738, 3108, -5792, -3554, 623, -1110, -6114, 4488, - 8941, -3176, 13670, -3320, -327, -2657, -7349, 3782, - -1481, 5737, -200, 2968, -9474, 5752, 5056, 4688, - -5352, -432, -906, -3832, -8519, -7, 3667, 3583, - 6250, 8724, 10737, 9371, 950, -1630, -10740, 5788, - 4111, -2910, 437, -2482, 1910, 185, -2168, -3155, - -3515, -1754, 4978, 4298, -6921, 476, -2778, 546 -}, - -.cb1110m0 = { - 3666, -1078, -175, 1370, 2491, -10050, -685, -7617, - 4002, 11104, 903, 5948, 2821, 3050, -2465, 1151, - -848, -2139, 12321, -1408, -1469, 2046, -2693, 2479, - -3498, 3077, -3822, 1841, -2404, -11172, -407, -3062, - -1725, -5475, 597, 1924, -197, 434, -1648, 2678, - -2462, 1148, 599, 1284, -13171, -949, -6508, 754, - 7466, 5924, 1411, -536, 10825, 588, 297, -310, - -593, -896, 784, -242, 716, 501, -52, 4043, - -755, -690, 2630, 17762, -2159, 2126, 954, -1316, - 11129, 1570, 387, -2639, 13953, -311, 5231, -2297, - -3612, -678, -1117, 690, -279, 2403, -1541, 493, - -1692, -2048, -771, -933, 423, 700, 840, 739, - 1956, -944, 612, -2678, 101, 245, -786, 850, - 269, 1355, 21773, 463, -2589, 596, -519, 788, - -43, 1220, 10674, 4847, 1192, 335, 875, -106, - 10644, 2600, 5391, -262, 2296, -5928, -1072, -122, - 2504, 1313, 1117, -981, 350, 375, -810, 8, - 1462, -2020, -2368, 8, 22663, 1537, 87, 908, - 832, -4884, 312, 620, 1042, -4444, 660, 1582, - -2710, -2954, 10012, -9580, 8102, 5696, -1371, -3035, - -3347, 402, 218, 1096, -1924, 88, -2270, 4175, - -1083, -497, -2437, -3332, -824, 212, -2362, 4600, - -7800, -11501, 7795, 236, -1336, -12920, 705, 4532, - -1488, 11746, -3213, -2650, 2524, -2638, -128, -328, - 3402, 453, -242, -2500, 2224, 708, 450, -3014, - -132, 1251, -131, -831, -710, -21985, 222, -2132, - -3261, 490, -3020, -860, 2550, 892, -623, -3666, - -664, -131, 2018, 2817, -12005, 496, -610, -7238, - -3909, -2867, 6872, 1903, 848, 6644, 3812, -5686, - -4055, -377, -2096, -10247, -1068, 1486, 415, -253, - -2186, 1050, 771, -6856, 1044, 7466, 2953, -7514, - 1601, 7015, -1778, -1622, -3364, -1755, 2835, 176, - 2700, 991, 2560, -554, 4867, 1571, -5610, 2610, - 12438, -3751, -9964, -2753, 4856, -2595, -5423, 10025, - 812, 687, 2715, 4013, 3086, -12039, 328, -3992, - 4044, -3920, -111, -553, -1720, 2454, 1706, -1365, - 804, -32329, -471, 897, -4670, 780, -3680, -1409, - -2630, 20, 184, -157, -290, 2794, -546, -160, - 1564, 1146, 628, -4787, -239, 11233, -492, 1955, - 608, 9273, -3220, 3830, 390, -5982, -3342, -3384, - 2356, 1820, -3473, 979, -40, -20190, 47, -200, - 5106, -381, 1824, -197, 2280, 2434, -2633, -1409, - -1109, -1072, 857, 1554, 7459, 6, 12130, -1078, - 1038, -300, -13748, 3201, -762, 2670, -1051, -445, - 914, -172, -558, 2634, -1158, 3129, -74, -3415, - 1086, -8892, 118, -647, 285, 186, 3022, -5077, - 1342, 3453, -7991, -65, 4690, 944, 3717, -1909, - -9783, -367, -1699, -772, -32768, 1286, -408, 340, - -340, 430, 1274, 596, -109, -727, 276, -946, - 139, 1804, -1050, -3562, -1392, -1179, 257, 1639, - 25708, 2278, 2415, 2174, 153, 126, -60, 592, - 994, -334, -268, 1826, -306, -2241, 2774, -3188, - 758, -450, 8023, 542, 6819, -1712, 14195, -2198, - 281, -12, -590, -1153, 4568, -3676, 1973, -5221, - -1839, -603, 3324, 2492, -3070, -846, 123, -1184, - 667, -10886, -65, -2615, 971, 10219, -1245, 7378, - -2122, -2306, 571, -2298, 1958, -4356, -9210, 4321, - 2805, 1888, 11129, 1282, -5819, -2528, -873, 1123, - -5968, -2644, -5515, -2151, -944, -7712, -2007, -2260, - -1920, 2100, -325, 153, 1050, 10, 1462, 650, --12559, 3530, 754, 4493, 1528, -6991, -4842, 1483, - -2408, 2785, -1651, -830, 1433, -2464, 18899, -1891, - -3137, 996, 2485, 3056, -1061, -4015, -2282, 1356, - -2572, -490, 1209, 1137, 4, -636, -1282, 1001, - -1190, -172, -14049, -4256, -1972, 2225, -4738, -1054, - 5254, 8113, 4294, 36, 11765, -3993, -1084, 3864, - -3016, -10356, 353, 2963, -1228, 536, 609, -343, - 1246, 3617, -3667, 4794, -20360, 473, 725, -1246, - -1649, 1900, -2589, -2869, -2550, -886, -1164, -1876, - 307, 3784, -4782, -476, -700, 2118, -1860, 1533, - -5013, 2356, 3305, 3338, -14312, -1278, -322, 1950, - -954, -1990, 1438, 3358, 7479, 3046, -6677, -3078, - 1717, 3113, -12484, -1302, -221, -510, 10423, -3497, - 4170, -3606, 6983, -2902, 458, 667, 566, 2415, - -403, -2898, -44, -1832, -110, 1799, 1172, 7, - -1534, 90, 686, -26902, 1601, -822, 658, 182, - -151, 345, 1488, 1416, -272, 1560, 9774, 2084, - 16, -14344, 1428, 514, 2658, -1312, 2095, 454, - -1783, -2056, 4529, 1154, -2239, 956, 668, -1396, - -2898, 405, -12659, -12556, -650, -587, 3461, -2470, - 0, -3156, 3186, -4104, 1729, 1438, -1842, -422, - 4476, 1945, -932, -1439, -702, -1398, 3349, 1876, - -999, -2086, -17879, -432, 4036, -2299, 1133, 88, - -2221, -2730, -938, -998, -132, -426, 2084, 2060, - -1134, -313, 402, -538, -2593, 2022, 725, 1566, - -2070, 21622, 1767, -424, -32672, 205, -1239, -3253, - 198, -1257, 2342, -1918, 1505, 452, 1348, -604, - 978, 1079, -4, 2476, -1247, -146, -861, -1928, --12222, -13042, -1384, -1971, -1428, 1224, -639, -83, - 1034, 3488, -2310, -565, 74, -335, 2774, 602, - 872, -2132, -147, 2160, 244, 162, 12600, 628, --10194, -1296, 1068, -1824, -4945, 3194, 2066, -895, - -784, 2347, -1982, 73, 1030, 12589, -62, -2272, - 3827, -1776, 2546, -1417, 3310, 4726, -3078, -548, - -8522, 1632, -6667, 1008, 1128, 805, 954, 616, - 499, -31526, -1327, 790, -190, 1058, -1157, 1432, - -16, 411, -3180, 827, 327, 914, 1716, 1442, - 1052, -1635, -1805, -4145, -13678, 3597, -2273, -5920, - 3592, 1136, -211, 717, 3901, -5132, 3036, -601, - 12976, 1633, 10316, -1674, -468, 905, 2331, 841, - -247, -6053, -593, -3281, 4291, 5159, -1053, -1814, - 2613, 2221, 1146, 871, -421, -542, 923, -3567, - -1138, 10051, 10860, -6121, -661, -5677, -890, -266, - 2100, 6223, -70, -2658, -78, 3424, 714, 2138, - -1355, -981, 1990, 772, 938, 1311, -1963, 924, --22516, 260, -341, 1251, -1578, 23, 1375, 1068, - 2688, -3965, 713, -5342, -257, 37, -6034, -276, - 228, -1240, -7171, -3402, -14677, 1708, -317, -2880, - 874, 1466, 524, 2091, 565, -4220, -265, 52, - -3373, -220, -3175, 2646, 448, -1628, -1986, 2200, - 3722, -15752, 7120, -2036, -2170, -627, -1079, -4060, - 2257, -925, -3418, -13488, -1308, 3476, -783, -3924, - -820, -860, 2418, 2982, -8753, 9001, 294, -11915, - -969, 3329, -761, 1459, -5308, 1811, 379, 306, - 632, -2732, 2512, 1188, -3470, -2167, -572, -2274, - -1657, 24074, -159, -138, -1826, -2527, -3117, -906, - -1770, -1182, 1240, -3064, 2313, -790, 336, -3843, --13384, -423, 13066, -14, -1908, -32, 2607, 487, - -2426, 195, 135, 2742, 1540, -1034, 856, -2288, - -287, -774, 497, 1760, 191, 178, 298, 38, --30898, 801, -1456, 2311, 1272, -1845, 334, -933, - 183, -1614, 739, 1881, -13548, -13589, 1496, -2075, - -1281, -1510, 108, 3683, -1120, 752, -980, -277, - -1289, 2016, -290, 1838, -321, -139, -881, -12391, --14713, 1906, 990, -3202, 2320, 749, 1872, -2545, - -1457, -1727, 734, -327, -316, 1062, -3149, -2959, - 2210, 912, 952, 1926, -8918, 1098, 594, -1439, - -1402, 11097, 3482, -472, 219, -3845, -662, 9715, - 3928, 1254, -2009, 12375, -1724, 13938, 1892, -1390, - 686, 2174, 1010, -1297, -199, 1855, 463, 2601, - 4408, 1978, 1679, -1614, -3, -11965, 16220, 828, - 1497, -747, -484, 519, -1804, -3814, 3287, 2104, - 1149, 478, -3918, 1504, 2376, -316, -520, -1449, - -3918, 664, 2772, -16434, 334, -540, -778, -2812, - -6026, -4392, -2446, 3479, 3742, -624, 3895, 1145, - -344, 333, 11898, -2725, 12873, -1145, -1807, -279, - -452, -1581, 548, -5180, -2012, 3411, 1188, -1407, - -4016, -468, 1904, -1724, -11390, -30, 14402, 1610, - -2138, 1249, 346, 6097, -1433, -655, -174, 3652, - 4010, 954, -1458, -354, -1872, -2689, 880, -846, - -1304, -1725, 1750, -1186, 1520, 499, -583, 18201, - -1083, -3323, 3072, -5440, -182, 1065, -1112, -984, - 2501, -529, 613, 2054, 460, -5245, 2827, -1445, - -2403, -12898, 1504, -8428, -1035, -4620, 1704, -2586 -}, - -.cb1110m1 = { - 1442, 12425, -2072, 741, -3624, 12979, 2031, -364, - 3750, -5082, -1968, 146, 670, -3988, -831, 3962, - 397, 6213, -1178, 816, -88, -432, -9620, 11572, - 194, 289, -1958, -2115, -871, 5372, -3145, 3612, - 1644, 826, 525, -2545, -514, -537, 2485, -1014, - 1276, 541, -936, -302, -1172, 183, 827, 23939, - 1120, -346, -313, 2759, 3934, -3082, -2260, -906, - -967, 1496, 102, -2782, 323, -1109, -37, 2554, - -2920, 998, -930, -1952, -1138, 1842, -1593, 17345, - -1214, -1065, 2182, -1169, 11745, 278, 8310, 1491, - -564, 1169, 8406, 1359, -1249, -2094, -1365, 4069, - 1828, 897, 1258, 1083, 4319, 610, 766, 2273, - 4057, 621, 338, 1317, -20941, 548, -2012, 563, - 1102, -27, 3007, 1129, -1068, 1282, -2939, 2983, - 1958, 1800, 1912, 1728, -606, 1804, -4768, 5068, - -1365, 4543, 399, -14152, -6206, 6187, -2205, 1174, - -1892, -3284, -206, 2872, -2622, -43, 11268, -104, - 292, -1836, -6276, 725, 2066, -604, 11382, -448, - 742, 2854, -910, -838, -1802, 3678, -397, -530, --10647, 2356, 12161, 1506, 2649, -3335, 3128, 2169, - 5942, 2152, 14124, 428, 187, 248, 1592, -44, - -59, -2934, 1883, -923, 2673, -847, 150, -2142, - -7620, 11078, -595, 6490, -13673, 948, 219, -1314, - -3080, 1339, 11020, 1362, 247, -1863, 1069, -3786, - 1706, 1064, 320, 4535, 136, 3795, 1465, -1356, - -449, 13, -421, 1769, 20470, 2181, -371, 2444, - -744, 2263, -155, -688, -236, -4481, 1551, 2812, - 2476, -1436, -470, -272, 2276, 594, -858, -978, - 1122, 2468, -9350, -353, -1020, 494, 13167, 1770, - 1734, -70, -4630, 12358, -818, -979, -3931, 1000, - -4343, 2570, 5567, 3322, 2930, -236, -4796, 6987, - -1658, 4291, 1118, 1710, -2050, -13566, -2, -23, - 2104, 1101, -316, 1906, 1643, 340, 5940, 3180, - -837, 1978, -10514, 1466, -6936, 3600, 1205, 957, - -211, -8272, 1611, 5330, -5217, -2264, -5681, -3085, - -9201, -62, 3366, 1370, -9494, 244, -5516, 1210, - 2930, -432, -1265, 376, -1910, -1016, -845, 3228, - 1094, -3168, 634, -265, -3426, 4367, -4004, -277, --15081, 3998, 9671, 3418, 691, 9124, -2723, 1939, - 2311, 581, -4980, 3381, -1502, 878, -1037, 1496, - 3002, 904, -5388, -3300, 263, 1277, -694, 766, - 1781, 1134, 250, -32602, -285, 210, 2550, -383, - 908, 302, 292, -352, 2615, -97, -1863, 1908, - 2685, -502, -3767, 416, 990, -602, -1533, 43, - 1288, 1326, 16638, 433, -1204, 1850, -1609, 1407, - -7196, 2319, 5770, 1584, 1150, -634, -1686, 1359, - -1396, 438, 246, 186, -11262, -1194, -3790, -3267, - 2692, 755, 142, 16276, -2338, -1341, 10433, 38, - -1510, -2520, -3205, 913, 3783, -1622, -4744, 1891, - 2502, -8, -2962, 2091, 14986, 1270, 2931, 682, - 1073, -10215, 1606, -1010, -822, 1168, -1403, 254, - 1156, 3206, 3958, 1739, -402, -654, -4862, -1869, - 2643, -2858, 658, -910, -2548, 5428, -1992, -208, - 1950, -15526, 520, -4212, 3182, 4160, 1524, -2916, - 586, 3213, 675, 185, -629, 669, -838, 502, - -4065, 353, -4072, -1832, -2108, 5034, 2484, 15386, - -2102, 4988, 70, 1011, 2568, 1360, -2821, 3352, --11074, -2686, 611, 460, 1811, 3093, 34, -9140, - -1163, 26, -875, 2510, 1134, -1322, 2274, -960, - -823, -510, 1092, 1490, 1466, -1978, 32767, -2379, - -1019, -633, -1306, -242, 2050, 1336, -2668, -2195, - -442, 8, 2292, 4344, -2439, -1472, 1035, -14443, - -1820, 6309, -2096, 45, 3617, 1561, 1252, 2828, - 10682, -894, 10841, 2373, -101, 913, 2160, 2653, - 2960, -4433, 1193, 4892, -2123, -7911, 991, -2643, - -1364, -3641, -9736, 444, 869, 2990, 926, -1220, - -1676, 7492, 4376, -3742, -6964, 4531, 7522, -2686, - 164, 1070, -7305, 1863, 542, 146, -800, 18492, - -4849, -3876, 2162, 5111, 2606, 4243, -3035, -2990, - -1710, -426, -5315, -2332, -1020, -268, -1242, -39, - -1684, -32768, 1288, -726, -1768, 304, 702, -2969, - -700, 586, 1541, -1099, -348, -2816, -2181, -1260, - -1658, 2278, 323, -1548, 2513, 11816, -2416, -5837, - -118, 6770, 3360, -4097, -264, -1270, 1064, -9862, - -3669, -56, 603, -1475, 1464, -9553, 6, -3091, - 5331, -396, 892, -2774, -4674, 3667, -9982, -5160, - -1146, -4026, -2032, 2936, 1805, -1026, 1065, -420, - -572, 1756, -479, -583, 30760, -732, 750, 270, - -1541, 28, -1114, -96, -264, 1167, 548, 570, - 84, -1981, -2110, -1136, 358, -6337, -257, -14658, - 1144, -9032, 322, -3730, -3086, -1351, -3320, -4116, - -396, -129, -3202, 1403, -347, 2400, -371, 532, - 1555, -2760, 1078, 804, -1314, 21956, 2231, -2808, - -1947, 838, 12428, -14514, -384, -1554, -675, -885, - 1358, 1612, -3266, -98, 1876, -447, 2241, 3375, - -1765, 2792, 674, -1513, -1132, -3696, 11368, -1916, - -2778, -466, -377, 2090, 3897, 5422, -2550, 2360, - 3279, 8657, 990, -2128, 2592, -970, -2397, -269, - 22742, 694, 310, -2433, 920, -690, 1478, 1370, - -450, 445, -1379, -1244, 2374, 1400, -1040, -5692, - -1700, -1630, -4068, -1193, -719, -2953, -3562, 264, --13247, -4629, 5, 3245, -5724, 2449, 3190, -5375, - -3560, -3834, 1271, 1568, -762, 2938, 782, -1390, - 243, -466, 1376, 974, -1646, -1784, 249, -514, --13543, 1904, 10778, -772, -155, 7838, -30, 3634, - -473, -9100, -112, -3990, -840, 1495, -2346, -326, - 3655, 1292, -292, -10972, 3431, -262, 171, -9775, - -985, 578, 312, -2553, 3375, -8316, 1410, -1326, - 2459, -3116, 1079, 7194, 2720, 1998, 2742, 4672, - -1589, -8932, -124, -652, -72, 2409, -926, -3661, - -3762, 14832, -1350, -2234, 1258, -1604, 169, 103, - 1263, -400, -765, 144, 824, 855, -13344, -1629, - 1977, 2995, -1964, -650, -219, -11607, -6062, -792, - -1243, -1438, 1757, 1436, -3739, 812, -856, -9603, - -2428, -11372, 3273, -2318, -8263, 1551, -2054, -3646, - 3149, 2255, 594, -412, -3030, 1558, 694, -1211, - 618, 3256, 6526, -1572, -9054, 6655, -3208, 3616, - 2162, 3137, 4254, 4610, -10040, 1188, 335, -615, - 640, -1990, -314, 6014, -2392, -2174, 343, 6730, - -1320, 183, -97, -3566, 2988, -13343, -1573, -9070, - 428, 2839, 6728, -1109, -1113, -1102, 5012, 1308, - -3943, 3207, 764, -2928, 1144, -3044, 4033, 1846, - 6460, -4165, 8509, 9824, 15708, -642, 748, 124, - -406, 13033, 807, -299, 1319, 1499, -1206, -1102, - -3129, 3795, 47, -2483, -2470, 2287, 4028, 1656, - -364, -1712, -1568, -3940, -2770, -13688, 796, 3380, - 363, 1673, 1160, -3934, 2884, -5060, 832, 4799, - 364, -3030, -10596, -1805, -3256, -2492, -1831, 1088, - 11108, 3236, 5128, 3052, 4486, 84, 2078, 200, - -4071, 1713, 1539, 24597, -1019, 32, -48, 82, - 81, 1171, -1261, -1783, -1693, 2194, 1714, -225, - -1989, 402, 2611, -708, -15901, 222, -507, 12855, - 1162, -1536, -2884, 1911, -1256, -926, -1875, -1448, - -2730, 3059, -1231, 1680, 1824, 1288, -215, -9, - 40, -957, 27662, -1844, -1927, -846, -1144, -439, - -3507, -2844, -1880, 637, 1042, 237, 1007, -387, --11913, -2584, -142, 624, -494, 1439, 2225, -13017, - -1901, -1253, -1071, -7083, -2154, 814, 3867, 1130, - -2611, -2260, 1548, -12389, -1018, 102, 1178, 1058, --14863, 2020, 4094, -1259, -861, -886, -3119, 2638, - 1725, -1364, -2086, 183, 507, -978, -3086, -14966, - 759, -1341, -70, 8538, 2974, -140, 2509, -4460, - 2724, -1372, 491, -6138, -345, -2170, -1187, -330, --11090, 15657, -300, 2105, 496, -2093, -447, 2000, - 3451, 1482, 758, 4142, 562, -4042, 1491, 3183, - 1685, -2729, 1611, 11698, 14918, 25, 842, -2766, - -667, -1564, -2619, 646, 1391, 862, -909, -2141, - -589, 1468, -755, 1324, -765, 634, 195, -19622, - -1006, -1161, 2434, -1808, 4168, 4108, -2580, -635, - -2533, -2170, -3701, -1047, -363, 769, 5064, -8, - -654, 2346, 752, 13736, -4056, 7, 5492, 7326, - -4894, -3860, 3325, -3947, 4721, 5557, -3699, 194, --12957, 1052, -1317, -2642, -2931, 1050, -3951, 2392, - -9683, 2519, 2880, -3700, -1820, 831, 4370, -1177 -}, - -.cb1616l0 = { - -185, -20290, 476, -272, 31, -638, 806, -61, - 220, 176, 178, -788, -441, -333, -360, -263, - -116, -512, 9794, -727, 8904, 1192, -277, 756, - -670, 795, -311, 240, -617, -675, -970, 756, - 857, 529, -166, 674, 890, -522, 837, 79, - -618, -1308, -13832, 744, 5422, 2688, 531, 398, - 1500, -1965, -209, -346, 613, 2147, 10053, -1398, - 189, -108, 471, -1202, 999, 178, 762, -601, - 1116, 9468, -281, 763, -1204, -822, -20, -160, - -806, 14720, -269, 143, -1362, -532, -788, -1532, - -405, 85, -271, -4959, 276, -34, -28, -66, - 112, -188, -582, -678, 128, 680, 982, 596, - 12154, -10468, -167, -380, 734, -296, 282, -223, - -86, -342, -812, 514, 387, -418, -364, -1216, - 14, 373, 357, 10897, 11235, -714, 206, -618, - -607, 596, 190, 726, 496, -300, 95, 1022, - -153, 212, -540, 252, 281, 238, -234, 28, - 24, 184, 32767, -627, 569, 323, 486, 544, - -348, -589, -284, 238, 228, 475, 83, -7753, - 182, 745, 400, -633, -207, 137, 382, 90, - 78, 715, 448, 463, 937, 10203, -12047, -667, - -370, -1516, -360, 94, 832, 1027, 1013, 92, - -5446, 834, 302, 764, -94, -462, 8095, 1057, - 308, -635, 308, -877, -946, -616, 51, 1090, --13351, 490, -819, 15182, -384, 411, -546, -242, - 460, -323, 76, 277, 1582, 900, -1119, 345, - 1316, 1138, 2020, 1612, -148, 812, 1241, -10350, - -9495, -965, -69, 1967, -168, -128, 1042, 447, - 491, -133, -5083, -450, -164, 50, 326, 269, - -283, 226, -40, -334, -110, 60, -47, 169, - 9166, 1188, -942, -14, 2112, -230, 634, -741, - -214, -336, -606, 3102, 59, 216, 1805, -1176, - 211, -8, 564, 156, -261, 300, 597, -21842, - 66, -232, -506, -1126, 1057, 603, 1448, -391, - 249, -9445, -10240, 694, 167, -1158, -645, -385, - -209, 330, 519, -345, -600, 192, 78, -229, - 208, -9053, -383, 10646, -264, 84, 295, -148, - 87, 1292, 257, 1080, -564, -2395, -1200, -484, - -48, -513, -383, -11, -516, -17356, -1172, -218, - 124, -327, 31, 328, -80, 231, 58, -951, - 560, -501, -392, 30528, -56, 382, -515, -50, - -155, 338, 0, -414, -899, 95, 11, 378, - -350, 459, 673, 76, 86, 379, 32222, 143, - -48, 425, -394, -60, -348, 450, -489, 220, - 56, 1129, -125, 322, 168, -16, 322, -293, - 294, -38, 328, 141, 692, -82, -160, -32768, - -140, -1543, 1079, 1052, -924, -569, 168, -1782, - 815, 706, -1318, -3436, 2860, 10922, 236, 10311, - 882, -1911, 11, 1638, -189, 245, -858, 11060, - -826, 696, 224, 1707, 1766, 472, 10832, -265, - -161, 163, 478, -258, -284, -86, 496, 425, - -71, -10344, -141, 425, -1457, 1145, -63, -713, - -583, -327, 628, 368, -18, -1746, -525, -338, - -110, -359, 92, -233, -21328, 460, -275, -98, - -58, 51, 208, 56, -1145, -51, -242, 65, - 76, 214, 141, 28, -86, 26, 925, 193, - 9980, -326, 11342, 176, -534, -303, 130, -1575, - 189, -496, -699, 381, 411, 644, 229, -147, - 694, -1998, 523, -1576, 8028, -10385, -1924, 1174, - 608, 2402, 575, -1753, 437, -816, 1267, 147, - 1448, -614, 865, 1076, -156, 5000, 2020, 2021, - 10283, -460, -2381, -3226, -3991, 4904, -284, 105, - -268, 1049, 203, -646, 732, 6490, -128, 932, - 10, -866, 74, -64, 834, 204, 159, -162, - -170, -110, -28908, 52, -512, -72, 327, 615, - 534, -484, 131, -262, 31, -407, 284, 33, - 11118, -170, 318, 12848, -1126, -659, 500, 310, - -403, -234, 237, -544, 1232, -243, -1178, -965, - -117, 108, -1304, 11728, -2254, 1231, -1077, -136, - -632, -103, -256, -1644, -300, 1680, -1175, -956, - -43, 1718, 175, 144, 275, -802, -223, 1116, - 321, -871, -1174, -1175, 1008, 255, 31172, 28, - -621, -222, -12473, -10995, -712, 247, 1762, 418, - -181, 90, 92, -406, -435, -105, -596, 2262, - -116, -1574, -3402, 6796, 7944, 973, -2661, 2260, - 621, -6984, 382, -1375, -2604, 1550, -1453, 1133, - 966, 403, 284, -72, -36, 174, 457, -90, - 38, -437, -476, -370, 469, 32767, -267, 350, - 694, -169, -782, 2110, -620, -782, -669, -6478, - 10550, -3294, 485, 177, 553, -3232, 1628, 2335, - -870, -360, -1112, 2197, -474, -5113, 3346, 878, - 566, -3823, -1175, 357, 10509, 1077, -514, 1012, - 38, 59, 669, 654, 349, -1046, 355, 192, - 57, 95, 11869, -702, 10201, 204, 45, -608, - -444, 921, -1070, -316, 1286, -2566, 2026, -127, - -79, -954, 93, -1288, -10024, 693, 8820, -366, - -84, -6378, 1682, -627, 386, 254, 503, -152, - -336, 38, -341, 373, -85, 1088, -1707, 119, - -242, 242, -326, -162, 109, 70, -114, -831, - -279, -32768, 62, 58, 214, 136, 194, -103, --10047, -610, 91, -310, 12059, 346, -656, 986, - 478, 364, 1777, -173, -663, -103, 1011, -373, - 200, 1632, -13098, 3651, 418, 478, 68, -217, - 169, 78, -1176, -1191, -1664, -328, 152, -1053, - 547, 527, -10435, -176, 11131, -137, -36, 1062, - 33, 71, -730, 2080, 2061, -372, -637, -84, - 744, 109, -357, 550, 309, -239, -134, 135, --20461, -177, -690, -488, -36, -415, 275, 64, - 378, 11250, -802, -569, -200, 1499, 13103, -1090, - -175, 189, -162, -751, 1052, -949, -98, 1249, - 479, -1304, 3293, 771, 1642, -381, 1423, 2258, - 1184, 4806, -10950, -3873, 348, -815, -5315, -3306, - -3307, 2337, 776, -125, -48, -435, -155, -30, - 294, 116, 96, -47, 1022, -391, -183, 252, - 826, -32, 293, -1369, 18310, -146, 239, -266, - 34, -154, -704, -498, -135, 228, -563, -210, - -158, -514, -201, -571, -341, -428, 74, -152, - 297, -162, -644, -216, -252, -13810, 705, 464, - 21097, 74, -169, 792, 12, 131, 320, -398, - -446, 44, -362, 388, -22, -13, -209, 1205, - 9341, 590, -683, -351, 177, -1618, 495, 14, - -319, 755, 11352, 249, -989, 1574, -922, -364, - 366, -10348, 337, -558, -124, 12056, 102, 802, - -548, -254, 1532, 7, -282, -459, -839, 171, - -4445, -1610, -1515, -37, 970, 306, -881, -238, - -154, -58, 27, 435, 166, 571, 225, -844, - -9967, -192, -874, -459, -1283, -1431, 1552, -38, - -686, -207, 709, 11982, -383, 1922, -92, -60, - 708, -900, 867, 39, 1470, 517, -182, -456, - 90, 1026, -192, 9988, 942, 48, 789, 981, - 74, -692, -1283, 1239, 1625, -1121, -286, -1115, - 294, 13228, 980, 312, -745, 11711, 1055, 1052, - -907, 201, 688, 364, 1171, 96, -591, -981, - -246, 875, -352, 677, 881, -397, 12890, 10, - 0, 412, 76, 464, 275, -721, -28, -197, - 104, -238, -372, -272, 490, 1426, 963, -13232, - -1190, 790, 161, -321, 1138, 646, 359, -183, - -659, -129, 348, -22703, 1016, -147, 26, -80 -}, - -.cb1616l1 = { - 292, 310, -255, 305, 69, 25001, -16, -668, - 210, 17, -12, 45, -758, -76, -544, -882, - 61, 26, -1682, -8820, 154, -11775, 64, 472, - -464, 245, 478, -1560, 869, 2192, 98, 645, - -95, -9369, -594, -635, -11132, 900, 1606, -904, - 841, 2570, -1464, 961, 1056, 669, 461, 3307, - -157, -644, 121, -694, 170, 116, 393, 1507, - -233, -654, -162, 108, 98, 17471, 347, -11344, - -701, -284, -246, -337, -1903, 14, 9865, 453, --11318, -3662, 2373, 1106, -1424, -1709, -2743, -860, - 11008, 1579, -38, -1381, 467, -487, -1306, 369, - 426, -424, 128, 1078, 1085, 683, 12552, 792, - -184, -278, 186, 2006, 363, 310, -75, 862, - 377, 490, -256, -1568, -124, -10785, -1456, -524, - -1259, 517, -1844, 914, 769, 945, 739, -1053, - -691, 177, 96, -1070, -162, -707, -594, -9885, - 103, 452, -734, -6774, -753, 192, 88, -292, - 201, -532, 231, -281, -691, -1232, -1768, -753, - 369, 1556, -139, 668, 941, 264, 10372, 9740, - 976, 2519, -88, 941, 446, -130, 2131, -631, - 325, 285, 176, -236, -634, -91, 112, 32767, - -233, -726, 156, 881, -217, -497, -236, -1106, - 283, 164, -328, -629, -27442, -17, 176, -338, - -192, 538, -773, 634, -180, 872, -190, -530, - 586, 6994, 3060, -336, 736, -1268, -1142, -69, - -1359, -1047, -975, -86, 12489, 1162, -509, -478, - 717, -514, -502, -1755, 11064, 7668, 340, 230, - -127, 1490, -63, 680, -297, 125, 1700, 2505, - 3, -2043, 255, 1547, 569, -2483, 733, -896, - 881, 4780, 1544, -13442, 1328, 1937, -4448, -384, - 749, 173, 7350, 156, -144, 52, -527, -34, - -3, -173, 118, -528, -75, 39, 42, -874, --14636, 474, -413, -106, -115, -431, 54, 722, - 156, -468, 369, 149, -68, -791, 1318, 2150, - 69, 454, 19032, 3, 111, -40, 349, 88, - 385, -54, -395, -224, -519, 0, -219, 179, - -253, -11379, 11005, 1857, -126, -248, 304, -616, - 351, 324, 500, 1494, -1390, 2349, -1257, -1114, - -213, 8156, -2066, 9746, 763, -848, 349, -7, - 723, -966, 469, 91, -252, 1336, 579, 1816, - 1372, -941, 364, 276, -33, 7, -425, -433, - -21, 546, -671, -31271, -926, 101, 147, 302, - -552, 224, 568, -2386, 519, -458, 13171, -1464, - 1161, 639, -10, -877, 331, 3372, -72, 5158, - -706, 906, 2668, 1008, -2732, 3264, 105, 630, - 673, -1948, -196, -13130, 1726, 737, 4829, 93, - 654, 2175, 3858, -5, 245, -471, 369, 5435, - 356, -12934, 61, 1984, 975, 706, -2454, -642, - -93, -780, -443, -1487, -460, 1112, 385, 309, --10268, 197, -1692, -1870, 50, -1934, 5380, -1193, - 775, -493, -992, -557, 2952, 408, 4616, -1341, - 10774, 5305, 854, 3031, 67, 617, 2436, -2072, - -1469, 804, -578, 243, 264, 9150, 200, 10753, - -350, 182, -52, -406, 508, -761, -161, -1142, - 25, 484, 127, 126, 477, -341, 110, 371, - 32767, 1090, 678, 175, 146, 1020, -897, 878, - -137, -507, -534, 658, 678, 505, -753, -207, - 391, 60, -23279, -772, -1323, -1578, -3, 196, - -749, 220, -482, -785, 456, 38, 1034, -579, - -58, -1539, 421, -746, 238, 1531, 21290, 586, - -441, -276, 1512, 553, -1407, -276, 60, -1068, - 299, 650, -25, 12590, 2058, 925, -295, -1744, - 5152, 4935, -419, 272, -383, -665, -194, -255, - 574, -267, 541, 1031, -282, -648, 622, -1464, - -28, -269, -533, -80, -476, 282, -336, 125, - 104, 464, -8948, 849, 171, 1518, -296, 51, - -27, 3097, -5103, -412, -494, -194, -713, -1277, - 102, 1740, -445, 3432, 1180, 6404, -10908, -970, - 31, 142, -242, -79, -78, -76, 124, 1031, - 83, -55, 1522, -613, -32768, -394, 1306, 287, - 701, -4725, -1085, 415, -122, -538, -675, 82, - 116, -728, -99, 500, 659, -329, 292, -106, - 9243, -340, -11933, -498, 341, -825, -401, -402, - 142, -13, -309, -722, 141, 0, -681, 494, - 671, -1210, 1466, -1335, 11743, -280, 1616, -11481, - 52, 317, 902, -653, -967, -494, -162, -685, - -438, 756, 81, -207, 577, -7476, -353, 918, - -31, -107, 181, 523, -46, -752, 373, -908, - -1808, -916, 632, 1508, -35, -6943, 64, 13072, - -655, 163, 1221, -1655, -2568, -446, -401, 470, - -622, -944, 3744, -458, 203, 125, 238, 5196, - 21, 12193, 1095, 1091, -787, -1157, -980, -1154, - 7707, -29, 106, 1226, 696, -974, -379, -537, - 56, 95, -477, -528, -11245, -1014, 140, 380, - 89, 540, 84, -619, -322, -572, -240, -26, - 727, 310, 43, -790, -31, -24318, 110, 618, - 44, -108, 89, -191, -33, -201, -490, 43, - -136, 1366, -2, 162, -832, 469, -140, -278, - 600, -15775, -1699, 184, 1825, 728, -1803, -876, - 152, 60, -813, 3063, -929, 972, -282, 718, - 8426, -888, 1383, -664, 571, 958, 982, 236, - -548, 66, 1898, -274, 10715, -1693, 79, -1254, - 296, 609, 682, -1074, 272, 157, -18972, 377, - -12, 438, 536, -672, 292, 719, -464, 1106, - -296, -812, 6, -334, 67, 678, 382, 678, - 301, -22165, 184, 80, -671, -86, 139, -298, - 416, -610, 1057, 15, -230, 376, -768, 643, - 58, 27, 178, -742, 60, -500, 485, -19923, - -1016, 717, 1126, 287, 2171, -388, 1453, -21, - -268, -1555, -263, 713, 1709, -1103, -10699, 1788, - -8, -501, -892, 11476, -2006, 466, 8070, -286, - 163, 35, 494, 76, 1428, -2249, 100, -1542, - 319, -214, -701, 10130, -294, -11962, -656, 227, - -512, -1014, 213, -600, -720, 63, -180, 1286, - 1063, -9671, -1056, 1269, 1484, 20, 790, 29, - -9906, -373, 608, 361, -659, 43, -1034, -96, - -219, -65, 392, -19615, -464, 212, 820, -182, - -227, 463, 301, 642, -219, 386, -1170, 108, - -5583, 422, -507, 530, -1058, -131, 20, -14487, - 101, -14, -415, 32, -1133, -917, 944, -832, - 580, 2509, -959, 470, 1184, 432, -1238, 193, --13382, 2329, 1993, 1035, 80, 3139, -553, 1683, - 390, 1480, 642, 564, -11173, 422, -984, -559, - -686, 168, -777, -810, -1278, -427, -96, 1691, - 29172, -435, -50, -968, 221, 685, 52, -373, - 525, -563, 350, 528, 305, 705, 313, 612, - -254, -220, -1638, -156, 24, 109, -893, -697, - 245, 2579, 667, -142, 12315, -694, 3799, 5, - -438, -473, -426, 59, -5381, -56, 200, -280, - -276, 96, 435, 729, 336, 123, -714, -372, --12609, -12053, -238, 223, -242, 230, 663, -645, - 98, 515, 3, 724, 510, -48, 1090, -173, - -5024, 536, 635, -143, 702, 172, -196, 164, - 190, -152, -180, 238, -142, -329, 191, -296, - -416, 11775, -496, -95, 392, 994, -584, -925, - -963, 286, -458, 3104, -1990, 968, -1430, 998, - -407, 28485, 436, 42, 378, -210, 148, -149, - -532, 94, -628, 186, -186, -274, 250, -316 -}, - -.cb1616s0 = { - 5604, 1491, -2064, 1321, -2846, -3007, -1899, -896, - 556, 1969, -2225, 18515, 4156, 1333, 3489, -2168, - 1897, -1440, -1514, -13837, 1017, 4797, 453, -2101, - -6822, 923, 185, 754, -201, -4151, 126, -793, - -437, 2474, 4286, -6405, 4007, -1644, -757, -13106, - 2460, -1874, -1867, -1099, -5146, 2945, 2162, -4427, - 1692, 763, 1756, -821, 66, -348, 2001, 702, - 1046, -1365, -570, 1073, 32655, -9, 450, -761, - 908, -200, -572, -1306, 2589, 2406, 1926, 1772, - 11042, -1989, 3914, -1192, 1817, -11710, 2985, -2942, - 15684, 1919, -667, -1267, 5212, 444, 864, -3844, - 438, -2382, 974, 983, -887, -822, 185, 245, - -3192, 1030, 1441, -28152, -2616, -380, 300, 1990, - -94, -999, 285, 553, 2107, 960, -859, 1001, - -1632, 2208, -1302, 1331, -3956, 10593, -1931, -4486, - 9376, -6587, -463, -3605, 2460, 1306, 2, 1987, - 1643, -552, 1327, 1124, -581, 1347, 650, -29514, - 278, 1062, 1459, 951, 2416, 396, -594, 930, - 434, 3308, -2816, 5466, 4831, -2869, -68, -894, - 58, -13036, 210, -1940, -2524, 1139, 2044, -32, - 969, 2187, 516, 581, 8185, 2080, 176, -708, - 1529, 1132, -675, -1384, -10949, 1174, -5245, 580, - 7490, 3258, 4314, 2706, -13676, -1735, 1937, 577, - -108, 2676, 612, -966, -966, 3255, 1401, 1443, - -1850, -252, 9270, 5037, -1492, -1957, -2134, 1198, - 3470, 10482, -468, -671, -1655, -955, 3248, 3360, - 448, -1854, -25145, -2771, -3318, 561, -672, 1791, - 2194, -598, 1673, -420, 547, 122, -160, -172, - 1686, -397, 1187, 11, -879, -58, 323, 180, - -2588, -2139, -1794, -2924, 999, -26969, -1280, -1401, - -770, 6159, -4449, -4174, 5270, -4813, 4139, -2023, - 2694, 2884, 3418, -5948, 3118, -1176, 4691, 8566, --32768, -681, -553, -216, -216, -931, -507, 579, - -932, -740, 349, 81, 2120, -1222, 564, -1576, - 1241, 159, 2579, 3236, 19205, -744, -1727, -1803, - 1247, -575, -261, 261, 540, -255, -60, -1428, --14184, -5194, 863, 997, 1043, -828, 466, -12553, - 2106, 56, -566, 1142, 401, 1360, 2322, 629, - 937, 2954, -10086, -12, 2554, -5760, 523, -15184, - 636, 156, 165, -2638, 1134, 658, 4398, -1385, - -1924, 1179, 3222, -908, -1153, 18082, 1011, 1948, - -1007, 352, -172, -6446, -22, -228, -264, 73, - 76, 2229, -1349, 6103, -11588, 576, 3374, -1616, - 7904, 3146, 984, 1056, -1626, 3113, -3674, 203, - -452, -938, 2074, 2409, -1228, -8186, -2766, 11098, - 1598, -8658, -735, 556, 1610, -7419, -5267, 1158, - 2841, 4497, 7551, -2066, 1105, 761, 2549, -1764, - 2870, 3889, -1478, 1912, 2504, -1417, 963, -14602, - 579, 28, -2953, 1589, 3962, -1372, -3304, 566, - 2687, 9700, -2464, -13110, 3005, -772, -3775, -138, - -4244, 5031, 2523, -2883, 582, -446, -274, 3311, - -157, -784, -948, -292, 3085, -781, 954, -2133, - -6693, 13909, -2236, 416, -2589, -3194, 668, -1988, - -2234, 2365, 1034, 1201, -100, 1688, 372, 156, - -254, 931, 576, -4680, 566, -1823, 294, 1645, - 27678, -1353, -1230, 1744, 570, 1679, 608, -35, - -7150, -4383, -11992, -2910, -2096, 512, 1838, 3129, - -410, -2306, -551, -3904, 4140, -12782, -1743, -106, - -4190, -5554, 12975, -573, -3532, -4050, 15, 1307, - 62, 1643, -1988, 5774, 2064, 4734, 1009, 2038, - -2794, -2704, 2275, -279, -1588, -910, 31315, 1249, - -1642, 78, 164, -260, -878, 698, 1189, 159, - -6137, -1994, 775, 3484, 1635, 1121, 4391, -5883, --11300, 3722, -422, -2180, -3206, -3181, -1490, 291, - 1326, 399, 1952, -8405, 2240, 175, 3541, 4258, - 1518, -781, 1105, 498, -348, 771, 15918, 120, - 379, -2036, -3723, 10948, -1827, 3220, 40, 210, - -294, -813, -2349, -707, 967, 953, 2625, -13614, - -1519, 9454, 11606, -903, 817, 6237, -8878, -160, - -1768, 444, -2812, -1697, -1010, -964, 1846, 2997, - 2633, -1924, 501, -1464, 2402, -986, -1143, 527, - 1187, -929, 20923, -563, 785, -486, -940, 1625, - -796, -697, 348, -428, 1451, 1087, -2252, -2481, - 939, 890, -2508, -1357, -1868, 1395, -6386, -21986, - 2574, -384, -324, 7752, 2996, -641, -7903, -5745, - -4226, -4178, -4394, 9307, 3906, -227, -496, 4556, - 1099, -838, -2546, 1190, 9937, 11057, 3846, -156, - 433, -2873, -1769, 36, 3188, 4490, 4369, 4714, - -4681, -2804, -1525, -947, -5064, -4180, -1348, -1404, - -1097, -3922, -1088, -444, -13636, -1547, 1685, -1625, - -8494, 2492, -72, 9893, 2470, 705, 105, 5609, - -5403, 846, 90, -688, 1184, 6286, -253, -1610, - 3348, -2082, 8838, -2453, -1315, -1235, -719, -4607, - -2138, -5522, -10466, 1900, 1541, -2688, 729, 368, - -8845, 1282, 438, -2532, -2328, 4833, -6145, 4037, - 3584, 7965, -1495, 6999, -5037, -1364, 7095, 4253, - 2711, -8336, 3946, -1347, 192, -820, -328, -1152, - 1554, 869, 5053, 9707, -5888, -4294, -3858, -3344, - 8344, -644, 1750, -1796, -149, -3706, -14823, 656, - -1487, -2466, 640, -2286, -2902, 2906, 44, 211, - -336, 29976, -298, 2092, -688, 1857, 1807, -1705, - 3211, 425, -1046, 128, 1191, -1966, -726, -3040, - -3632, 1212, 2986, 5266, 1086, 3624, 3068, 422, - 989, 24479, 3791, -2229, -3713, -2379, -1370, -1799, - 2742, -3259, -4973, -626, 2287, 5655, 663, -918, - 13266, 7762, -1131, 2490, -3123, 2869, -846, -2828, - 119, 14540, 4588, -2784, -3713, -2547, 3698, 3189, - 3372, -5436, 856, 4382, 4124, 3406, -336, -911, - -137, 4268, -4436, 1566, 1169, -3020, 13980, -162, - -7226, -2550, -946, -2408, -1056, -587, -273, -932, - -219, -8021, -1086, -2587, 3852, 1235, -22, 222, - -1100, -1594, 137, -1985, 10225, 4998, -348, -450, - 6651, -2217, -7705, 2508, 10061, -4512, -2262, 6156, - 2962, 150, -2456, 1089, -927, -609, -3130, -1682, - -1215, -9251, -130, -3776, -309, -13872, -276, -6922, - -82, 2660, -1255, -6562, 2640, 2646, 422, -84, - -6020, -11551, -1710, -3462, -2666, 12510, 3145, -218, - 2956, 447, 30, 2268, -2410, -1400, 660, 431, - 3068, 258, -2862, 3919, 2693, -744, 3070, -2179, - -1192, -932, -2095, -279, 2045, -8205, 15263, -4415, - 2116, 4047, 10308, 3110, 1368, -1547, 10919, 988, - -81, -907, -1728, -1052, -3539, -4769, -2576, -1038, - 9255, 152, 431, 2455, -1544, 1880, -312, 2724, --13336, -4197, -1199, 709, -695, -1687, 442, -2564, - -1626, -1888, 1870, 3539, -2922, -3506, -7890, -5486, - -1640, 2178, 2173, -3200, -4626, 1116, 13161, -5221, - -852, -1047, -3328, -3975, -4441, 2870, -1458, 5664, - -28, 3853, 1809, 2721, 658, -15262, 3611, 3223, - 595, 44, -5327, -2486, -1806, 606, -2474, -1236, - 983, 1741, -8390, 1948, 1875, -1806, -6294, -814, - -747, 2209, -1332, 2058, -1326, 5808, 1113, -10765, - -584, 4038, 1412, -3356, 24, -12826, -4322, -2287, --10793, 3008, -6903, -1273, 1590, -608, -514, -309, - -144, -2024, 1822, 4375, 1122, -631, -76, -595, - 192, -11323, 8168, 10180, -646, 2478, 4516, 1095, - 94, 6, 1251, -658, 2620, 626, 3078, 727, - 7769, 966, -3593, -6990, -2358, 1022, 1288, 2733, - -259, -291, 2482, 297, -1268, 10338, 739, -1862 -}, - -.cb1616s1 = { --12873, -2429, 6659, 4401, -2250, 1684, 1508, 1780, - -1081, -10, -6012, 895, -2373, -1263, 125, 1448, - 4744, 1556, -7267, 2354, -11368, 1155, -7699, -1424, - -914, -591, 2472, 538, 1431, 953, 5, -3066, - -1063, 3, 406, 979, 922, -668, 1633, 2, - 649, -139, 964, 860, -18807, 1944, 2183, -1358, - 1395, -1167, 5369, -3525, 735, -2698, 10556, -1137, - -3979, 1383, -1997, 5995, 6465, 2310, 1781, -311, - 3376, 7199, -2745, -1656, -5702, 3180, 3017, -5673, - -712, -8902, 2058, -570, 170, 2276, 3869, -9332, - -7965, 1130, 2111, 5638, -1507, 2944, 1574, -919, - -1459, -970, 11093, 544, -2952, -146, -4684, -303, - -528, -1199, -890, -2720, -1665, -10952, 373, 1657, - 1960, -1386, 299, -4356, -4527, 8948, 7378, 1580, - 1301, -6057, 7650, -7399, 4646, -1768, 2756, -263, - -286, -334, 1369, -786, -3760, 824, -13524, -5099, - -1693, -347, -1821, 1992, 3462, 1421, 4900, -462, --13331, -1617, -2350, 4083, -8721, -5880, 4900, 2912, - 235, 10369, -1340, 776, -2598, 14344, -3805, -568, - -3788, 3591, -394, -1077, 3908, 6080, 1953, -1454, - -1013, 507, 10097, 3396, -4662, -763, 2506, 1486, - 3088, 580, -86, 1117, 1606, -3454, -10782, 4870, - 6170, 4020, -5675, 6848, 439, -8765, 3877, 6250, - 734, 3245, -874, -4312, -879, -4368, -1287, 3212, - -2130, -1435, 1619, -280, -3082, -1070, -18921, 940, - -2428, -1548, -1142, -271, 193, -240, -890, 918, - -4350, -5042, -8994, 5060, -6495, 3455, -259, 892, - -1290, 1348, -1049, -12681, -49, 18286, 75, 791, - 1830, -4116, 10240, -12, -459, 2477, -2582, -3344, - -1598, 982, -324, -48, -4229, -8476, 11120, 100, - -6238, 1164, 2369, -2052, 247, 626, 2213, 2279, - -2627, 289, -471, -1136, -1818, 15413, 579, 1034, - -6835, -8645, -12667, 758, -932, -4398, 565, 458, - -2024, -4050, -3100, 1897, 1324, 3191, 1876, 7660, - 385, -1066, -1539, -1317, -2632, 766, 63, 389, - -189, 1136, -653, 802, 755, 70, -29812, 640, --11953, 10901, 2078, -529, 10373, 2509, -2776, -104, - -2232, 174, -837, 158, 1507, 1963, -273, 1534, - 1084, 8469, 2568, 12662, -2276, 2808, 2052, -7430, - 434, 3777, 991, 664, 2724, 1631, -3632, 2099, - -582, 4140, 757, 11248, 540, -1425, -10204, 1604, - 600, -2034, -1060, 977, 1843, 3831, -933, -816, - 2975, -6413, 1589, -915, -696, 2155, -556, -17893, - 3348, -1239, 1014, -2539, 1588, -320, 2402, -1485, - -8062, -1046, -1458, 200, 1323, 357, -3752, 2836, - 5774, -11638, -913, -648, 1676, 246, -1277, -1065, - 2334, 14911, 228, 880, -2172, 3072, -2520, 1445, - 1442, 2568, -1254, 730, -1950, -192, 12003, -1587, - 2558, 714, 33, 4324, -4642, -231, -279, -255, - 17824, 1292, 3530, -766, -64, 245, 1677, 1716, - 2507, -3594, -3532, 3000, 1996, -5342, -1868, -5642, - -21, 1132, -1202, 1104, -6543, 1242, 457, -1711, --32768, 49, -458, 295, 858, 2043, 1268, -1257, - -346, 793, 554, 1260, -1082, 985, -1453, 1704, - 2431, -2858, 1466, -5424, -8870, 4714, -1539, 5767, - 110, -2568, -1482, -348, -11580, -2838, 1213, -599, - -1591, -3472, -6907, 6191, 3928, 4708, 1326, -1510, - 6322, 3849, -4112, 7689, 5976, -3298, 372, -5450, - -2208, 6564, -6915, 911, 4216, 1682, -739, -2146, - 203, 350, -816, 351, -3386, -3016, -15045, -10824, - -553, -4969, 138, 256, 1672, -1840, 2851, 15838, - 2934, 1871, -600, -3293, -845, -2696, 1463, -1075, - 720, -1177, -1538, 2415, 7315, -484, 1082, 962, - 766, -845, -10687, -5932, -4410, 3840, 362, 194, - -4576, 10209, -3548, -127, -1202, 246, -734, 770, - 311, -3126, 772, -2422, -1141, -12330, 960, 1567, - 2816, 80, -4414, -778, 665, 2308, -420, -180, - -1242, -423, 12138, 113, -1477, 2899, 214, 348, - -927, -764, 26, -1127, -2288, -32768, 1302, 394, - 646, -453, -946, -838, 1649, -2292, 1182, -1558, - -6413, -265, -1942, -3467, 1863, -3526, 3446, -863, - 886, 202, -202, 15706, 2226, 1763, 894, 936, - 16191, -693, 1682, 6678, 1742, 1365, 700, -1765, - -803, 299, -2194, 1259, 689, 1670, -635, 28, - 11890, -14, -878, -5439, 103, 11124, 528, 1179, - -62, 868, -664, 749, -1128, 1429, -485, 1920, - -866, 1176, 1051, 379, -29470, 2354, -252, -1648, - -412, -804, 1339, -383, -812, 959, 893, -1741, - 1462, -1868, 470, 2112, -1889, -2236, -1668, -755, - -2562, 1354, 6183, -10964, 5651, -1062, 2550, -6225, - -194, 1687, -782, 1568, -85, 10, -8, 1128, - -521, -1090, -1933, -3441, -2698, 3049, -5822, 20847, - 710, 789, -1872, 1082, -1242, 4152, 1624, 10795, - -2149, -134, 1087, 900, -7943, 5178, -3429, -11622, - -3617, -7444, -824, 3462, -579, -830, 1010, -3301, - 12202, -5446, -1763, 340, -744, -509, 554, 1140, - 12266, -1328, 4652, 992, -1931, -708, 1074, 2762, - 2931, -414, -217, 10166, -4167, -903, 660, 1000, - 27, -1037, -1532, 1308, 8655, 9087, -2998, 9928, - -3722, -556, 4812, 3062, 600, 1281, 3879, 114, - -5404, 1869, 2174, 2083, -11631, -301, -3609, 2443, - 2300, 4863, -838, -29, 2166, 1319, 2110, 1387, - -741, -1225, -1729, -13536, -7376, -1520, 619, -4919, - 2517, -4338, -1650, 475, 456, 4372, 792, 3224, - 1963, -547, -2071, 2142, -254, 1549, -6846, 2430, - -96, 19844, 595, 1197, -1367, 2019, 2014, -1547, - -3775, -1186, -9690, -394, -4106, -1728, -1036, 2945, - 509, 14242, -1893, -2494, -3004, 458, -1753, 2628, - 9790, 3450, -1652, -322, 8263, 3952, -2156, -2110, - -442, 1256, 1561, -4913, -3452, 74, 3051, 8907, - -3376, -96, 16654, 557, 520, -446, -2520, -1712, - 2151, -2423, 3761, -3507, 487, 2103, 777, -416, - 509, 468, 3629, -3155, 11460, 2106, -2191, -1014, - 1154, 9317, 704, -282, 3098, 2722, 84, 150, - -5922, 3063, 8373, -11896, -1157, -2286, -1781, 7331, - 1331, -334, -974, -1653, 752, -1970, -89, -3470, - 2418, -1334, 3615, 12770, -116, 1965, -1643, 1480, - -2225, -10686, -1174, 530, -972, -933, 719, 722, - 1530, -317, 105, -14155, 2569, 4506, -8502, -681, - -1544, -542, -2814, -1161, -629, -1776, -3540, -1366, - -3681, 1838, -1630, -703, 12613, -12335, -2020, 2173, - 27, 315, 4766, 4590, -1603, -68, 1154, -2940, - 1198, 7884, 2502, -586, 440, -5124, -2454, -2597, - -826, 7401, 2803, 4552, -3212, 2966, -5567, 588, - 2216, 7444, -2633, -5922, 434, 3423, 4084, 2296, - 13258, 2070, -4624, -1226, 166, -367, -527, 1110, - -1407, -150, 140, 584, -373, -2649, 862, 500, - 3292, -3506, -679, -20109, 1775, -726, 3378, 754, - -1962, -5764, -1338, -3628, -691, 4554, -1890, -6021, - -6566, 2590, 262, 2509, 257, -4386, -2480, 6352, - -2026, 1234, -399, 22808, -2221, -626, -714, -339, - -1196, -455, -80, 713, 1662, 474, -2324, -527, - 4101, -10526, -4617, 10492, -1143, 805, 1360, 3796, - 942, 684, 2596, 1313, 1589, -570, 5476, -27, - 9220, -1493, 2631, -6726, -2976, -14295, 137, -734, - -2015, 658, 323, 83, 2539, -1230, 1714, -2080, - 658, -18803, 2978, 996, -3374, -28, -1335, 150, - 2154, 1069, -852, 293, 535, -1004, -993, -3692 -}, - -.cb1616m0 = { --16476, -11442, -305, -196, -767, -2167, -1, 378, - -2200, 22, 2405, 944, -1786, -806, 669, 952, - 10435, -2752, -1625, 1060, -12314, 1283, 234, -2405, - 627, 798, -1058, 311, -2794, -2715, 73, -214, - 813, -2749, 10732, -445, -12147, -2507, -1972, 1652, - -1920, 215, 298, 1106, 826, -7445, 69, -1679, - -675, 1249, 1444, -1109, -48, -1452, -2368, 3034, - -492, 13068, 311, -3446, 326, -1426, 2384, -2146, - 2916, 8957, -196, 2212, 447, 1775, 2607, -11962, - -278, 4335, -1743, 135, 212, -41, -92, 164, - -11, -504, 828, -519, -834, 251, 1919, 762, - 24917, -180, -132, -330, 138, 225, 1038, 3, - 32138, -388, 208, -638, -1338, -165, 200, -230, - 225, -777, -2270, 8198, 583, 3946, -1534, 1666, - -1032, 11384, 202, 30, 2758, -505, -2815, 1265, - 64, -17, -360, 636, 134, 502, 259, 872, --28148, -1046, -348, -86, -739, 55, 448, 168, - -656, 1094, -1074, 4552, -834, 2296, 2356, -572, - -1917, 10979, 3127, -52, -9969, -527, 1994, -1626, - 1041, 3310, -2319, 2232, -11444, -2400, -1788, -1254, - 5265, 3198, 7088, 4522, 1292, -191, -15886, 2787, - 22, -1610, 184, 380, 521, 336, -158, 877, - 468, 6515, -756, -5484, 100, -464, 9244, -2726, - -1644, -2741, -5362, -1635, 894, -1849, 10118, -3264, - -4472, 1255, -3571, -437, -1050, 1505, -11178, -193, --11513, -24, 719, 212, -1999, -725, 502, -1164, - -1060, -618, -91, -738, 740, -2254, -4635, 2700, - 95, -853, 1093, -11620, -968, 9492, -25, -664, - 367, 1105, 5501, -112, 7516, 10286, 821, -484, - 204, 1425, -3491, -1234, -4240, 3807, 2877, 1824, - 423, 466, -428, -845, -86, 13276, 8436, -690, - -688, 574, -2874, -552, 4540, 926, -5443, 629, - -395, 2090, -17468, 335, 2419, 1275, -3750, -1589, - 470, -1735, 330, 2532, 1094, -6218, -884, -236, - -9678, -9945, -447, 542, -728, -1922, 108, -2193, - -946, 3270, 2121, 2624, 1010, -10742, -102, 2813, --13070, 1523, -1532, -1291, 420, -1999, 262, -1194, - -4226, -1450, -275, 83, 1168, 1590, -1517, -426, - -1424, 152, 676, 11463, 824, -2092, -1106, -11502, - -2327, -278, 2597, -11, 793, -118, 393, 580, - -499, -743, -77, -427, -408, -692, -29195, -247, - -2014, -922, 97, 581, 5469, -1419, -698, 1490, - -3814, -2818, -13816, 680, 3595, 1544, 2366, -3018, - 2479, 323, 346, -260, 337, 2730, 12214, -1118, --11301, -3028, 212, -41, 1764, -580, 553, 5454, - -8, -366, -1202, 901, -796, -8350, 4380, -1452, - -300, 1152, 3058, -3476, -27, 13046, 34, -11438, - -1321, -1528, 13237, 114, 2514, 976, -571, -1192, - -2050, -1635, -964, 416, -23, -1083, -9, 32767, - -548, 556, -1217, -56, 325, 1048, -145, 202, - 1520, 44, 402, 400, -611, 8667, -1083, 1068, - 1224, -12031, 2318, -1109, 1266, 1306, 4673, 285, - -5603, 1555, -100, -1059, 403, -213, -680, -904, - 11443, 581, 12160, -638, 309, -65, 933, -2280, - 1958, 2642, 1808, 7945, -2088, 850, -428, 785, - -989, 1234, -1413, 745, -10756, 1943, -184, 3252, - -96, 932, -664, 13222, 11326, -1374, -327, 1901, - 1069, -1540, 104, -139, -904, 106, 1664, 925, - 46, 353, -835, -554, 1618, -956, -437, -727, - -3403, 1038, 968, 436, 46, -4385, 340, -16903, - -498, 47, -554, -399, -2418, -347, 358, 23280, - 234, -172, -338, 1058, -2172, -1, 1710, -64, - -583, -2224, -780, -637, 3500, 108, 1045, 828, - -728, 9466, -2487, -12773, 1924, -1158, 208, 49, - 136, 12055, 42, -1381, -375, -11534, -249, 1602, - 996, 204, -710, 4761, -511, -15761, 166, -1184, - -192, 50, -105, 890, -9566, 2062, -1536, 133, - -185, -643, -172, -894, -355, -16, -1395, 542, - 2160, -481, -1104, -793, 517, -20454, 698, -181, - -135, -434, 1677, -181, -415, -738, -1574, 1664, --14058, 597, -12354, -460, -313, 1724, -686, 85, - -1162, -648, 865, 165, -225, -1947, 2818, -778, - -4010, 402, 686, 11170, -332, 10336, -757, 4794, - 2204, -477, -292, -366, 8412, -2476, 494, 510, - 10514, 769, 642, -441, 1079, 6954, 4246, -2272, - -290, -224, 1312, 398, 1536, -692, 330, 157, - -946, -100, -1830, 214, -25652, 1382, -1836, -440, - 110, -506, -438, -2370, 126, 562, -3515, 1014, - 8526, -1641, -2493, 4411, -9210, 2110, 625, 114, - 323, 2450, 2407, 682, 1999, -9424, 2480, 69, - -2091, -11845, -3684, -429, -1622, -919, -518, 70, - 1450, -3523, 5126, 5706, -1451, 2633, 820, -204, - 11338, -8014, 753, -103, 290, -923, 1408, 298, - -1962, -887, 9691, -1366, -11048, -55, -223, -1040, - -163, 132, 676, -760, 4990, -310, -9286, -2427, - 14442, -418, -802, -359, -323, 2877, -210, -1436, - 1574, -1206, 265, -155, -225, -32768, 347, 222, - -1165, 200, 924, 1135, -843, -66, -343, -334, - -113, 209, 14, -203, 1214, -896, 910, -1496, - 1831, -7833, -841, -10453, 1605, -8514, -477, -48, - -241, -58, -32768, 213, 108, 450, 1155, -30, - 89, 240, -768, 1332, 290, -1377, 951, 586, - -8939, 1298, 496, 705, -1661, 1798, -1906, -2233, - -1716, -986, -2204, -1149, 2686, 8578, 32767, 645, - -661, -135, 770, -432, -550, -385, -272, 625, - 1234, -729, 19, 1753, -284, -106, -655, 750, - -442, 23143, -328, -520, -506, 790, -1048, -730, - -471, -438, 483, -374, 939, -226, -397, -849, --12054, -772, -40, -11776, 232, -540, -2497, -679, - 337, 1357, 458, -341, -7542, 1001, 492, -416, - -1496, -8966, 9814, -1752, -674, 2526, -544, -2900, - -1318, -1578, -238, 75, 11181, 1750, -3182, 564, - -570, 528, 1004, 146, 1144, 7430, 158, 9524, - -36, -340, -441, 596, -1659, 1420, -686, -36, - -596, 2215, -1295, -19722, -2149, -1046, -2339, -1166, - 3057, -370, -556, -33, -322, 260, -23, -106, - -323, 147, -57, 179, 458, 684, -1283, 1251, - 1231, -18548, -513, -480, -695, 593, 3072, 1960, - 322, -702, -1043, -544, 6005, 1378, 100, -225, - -848, -1294, -3346, 828, -2610, -3010, 9623, -1329, - 1956, -1098, -3730, 1137, 12413, -1260, 2457, -10844, - 6824, -4289, -653, -302, -4415, 650, -1684, 6129, - -370, -652, -3245, -473, -150, -3018, 1864, -1258, - 928, -2379, 14451, -119, 2282, -248, 3139, 6502, - 4318, 2214, -1627, 126, -422, 326, -622, -302, - 32252, -268, 456, -260, -260, -968, 391, -497, - 152, 1764, -10580, -369, 277, 70, -13137, -1114, - -1111, 464, 2266, -2968, 728, -1216, 1726, 1044, - 344, -16436, 1558, 3178, -551, 604, 442, -891, - 9570, 1596, -541, -2182, 730, -906, 242, 935 -}, - -.cb1616m1 = { - -116, -53, -24868, -544, -783, 97, -912, -1202, - -622, -147, -215, -362, -16, -522, -1694, -358, - -724, 2628, 439, -18106, -1566, 3048, 4133, -1238, - -3233, -1130, -2884, -2762, 1031, -1037, 63, -2219, - 10701, -1518, -10322, 1425, 792, -1820, 380, -777, - -3017, 1531, -1052, -3491, 1085, -428, -765, -113, - 42, -265, 365, 99, -859, 35, 610, 44, - -495, 262, 1689, 2082, 21605, 412, -717, -1163, - -3285, -5062, -1583, 599, -277, -62, 615, 6014, - -1781, 465, -544, -14114, 11277, -20, 696, 663, - 1156, -240, 631, -2802, 333, -2544, -1628, 775, - -960, -553, 496, -378, 526, -421, -426, 290, - 555, 403, 390, -31714, 25, 449, 654, -334, - -1317, 165, 496, 1554, -88, -777, 626, -1511, - -9020, -1725, 12705, -798, -1240, 195, 1932, -833, - -939, 43, 182, 2547, 4879, 9234, 370, 2058, - -7757, 544, 1106, -660, 546, 9983, 225, 124, - 952, -2153, -1732, 2760, -1270, -176, 3334, -6735, - -526, 10475, -627, 7835, -2263, 475, 731, 908, - 8264, 1605, -192, 5026, 2414, 5223, 595, 1093, - 2345, -796, 8663, 1028, 8188, -185, -1506, -3044, - -100, -1818, -6369, -170, 1728, -9249, 886, -2111, - -349, -1146, 2127, 11622, -8043, 2880, 2215, 1693, - -2303, 1698, 1121, -3575, -927, -716, 1940, 2514, --11672, 1619, 916, -7, -585, 508, -1316, -972, - 778, 9774, -2126, 2368, -56, 6716, 1169, -3656, - -1330, 9530, -12158, 1188, -11426, -353, 945, -1941, - 1750, 962, -1133, 1793, 2318, -2641, 1109, 933, - 804, 505, 60, -1642, -2238, -2328, -1558, -1568, - -27, 952, 4, 1376, -862, -18404, -1828, 4107, - -454, 52, -1202, 1150, 686, -1950, -497, -10883, - 400, -422, 1734, -54, 11165, -3309, 6402, -877, --19967, -400, 1642, 1305, -2432, -3115, 375, 3898, - 1812, -5305, -946, 1717, -757, 3322, 126, 747, - 1836, 9957, 1904, 658, 13043, -1779, 675, 716, - -453, 670, -1572, 210, -1533, -133, 294, 546, --24084, -1036, -485, -117, -184, -624, 273, -901, - 866, 609, -1119, 28, 250, 13, 70, 1178, - 882, -632, -21624, -1339, 926, -1814, -1279, 1868, - -181, 383, -679, -1070, 5091, 1148, 1034, 2144, - -2779, -3810, 4536, 1713, 1003, 13322, 2866, -3217, - 2508, 4395, 480, 14, 167, 763, -34, 1034, - -1342, -1349, -100, -225, 464, -914, -1403, -1851, - 23767, 770, -457, -257, -1072, 1201, 583, -59, - 2627, 1469, -7, -11642, 3352, -1003, -6, 11588, - -311, -2435, -2180, -2352, 1952, 5532, 1945, 7281, - 504, 11882, -603, 45, 42, -1396, -1115, -1041, - -1061, 566, -2733, -765, 687, 118, -1174, -20412, - -244, -986, -151, 2888, 1102, -1303, -135, 529, - 1186, 13220, -183, 906, -4209, -4455, 2247, 246, - -6474, 2794, 1450, -6495, -1819, 598, -438, 244, - -1064, -673, -672, -1563, 543, -2278, -3087, -811, - 1866, 80, -18987, -682, 569, -551, 514, 6876, - 7582, 839, -4031, 823, 2342, -1300, 1180, 702, --10168, -1957, 485, -374, -151, -11066, -461, -12824, - -1221, 1281, -718, 2012, 330, -289, -487, -207, - -722, 394, 156, -2023, -11006, -373, -4, -238, - 10581, 991, -1236, -814, 553, 1295, -2269, 2783, - -1973, 681, 9759, 3674, -1680, -12118, -1340, -2372, - -288, 2143, -328, 809, 312, 2038, 736, -10, - 908, -11319, 74, 6362, -1122, 1546, -184, 1630, - -1851, -2143, 1048, 8858, -462, -6458, -1540, 811, - 130, -3542, -10424, 9353, 388, 1168, -1797, 1796, - -4151, -2329, 1, -272, 846, -642, 248, -1144, - -9863, -1684, -190, 7611, -4147, -692, 5354, -2363, - 609, -4926, 3166, 2094, 857, -369, 118, 725, - -899, -601, -6, 556, -32540, 950, -478, 757, - 136, -560, -754, 562, -448, 223, -704, 616, - 365, 22610, 1191, -1264, -94, 927, -294, -1270, - -16, -2520, -2026, 420, -6621, -504, 9666, 452, - -379, -1888, 536, 1161, -3021, 609, -4890, -231, - 3926, -943, 32767, -615, 300, 870, -742, 429, - -42, 155, 1060, -900, -347, 34, 491, -3625, - -1529, 10175, 178, -7938, -406, 1628, -362, -7340, - -433, 489, 568, 674, 536, -2886, -6118, -16, - -531, 182, 1498, -4194, -306, 63, -1429, 1109, - 631, -10386, -16, -5938, -52, 10638, -793, 35, - -874, 1633, -252, 709, -286, -780, 17172, -32, - 912, 137, -1684, 2781, -5637, 338, 10961, 1401, - 176, 1890, 563, -371, 578, -235, -882, -616, - -591, -672, -821, 12194, 917, 778, -427, 358, - -1411, 2032, -1372, 1891, -1784, 1830, -1808, -464, - 13973, 2016, 8606, -914, -7329, -1853, -2627, 2219, - 2628, 2161, 2185, 2414, 8857, -273, 1016, 2253, - 1070, 907, 367, -430, 574, 1039, 93, 170, - 255, -267, 550, -668, 287, 1827, 19833, 244, - -3731, 4, 21365, -127, 356, 643, 2016, 3290, - 1242, 46, -734, -2298, -316, -6618, -296, -1465, - 657, -1451, 469, 212, 2823, -2803, -11862, 931, - 44, 660, 1576, 1848, -10529, 2813, -1163, -260, - -195, 16320, -3447, -262, -76, -439, -3487, 1292, - 3330, -616, 1477, 1900, 8843, 81, -846, 6845, - -95, -112, -231, 129, 6982, 165, -3115, 2456, - 2032, 12201, 2747, 1691, -728, -1935, -239, 968, - 15578, -2260, -1813, 440, 2188, -3845, 1278, -136, - -1388, -7850, -462, 2921, -1740, -136, 164, 103, - -206, 32767, -459, 1249, 736, -590, -797, 628, - 612, 327, 396, 552, -128, -76, -258, -557, - 429, 170, 532, -347, 169, -593, 28319, -633, - -1339, -997, -258, 324, 628, 3254, -1118, 8902, - -63, 4762, -2820, 2429, 820, -46, -5366, -2193, - -9005, -1304, -597, -10143, 555, -3000, 294, -1577, - -871, -140, 726, 3700, -2226, 903, -253, 10330, - -2946, 656, 725, -668, -920, 1653, 1312, 1623, - -1150, -11970, 2157, 4532, -340, -8648, -616, -1429, - -980, -30, 647, -474, 442, 5098, 188, -1258, - -8172, -10927, -4207, -112, 2501, -3241, -1949, 159, - -525, 1090, 420, 10418, -11897, 1072, -78, -1028, - 3367, -2647, 3421, 2021, 2358, -973, 272, 27911, - 472, -402, 1397, -927, -1032, -1274, 848, 221, - -2745, -710, -692, -409, 1922, 142, 594, 1053, --11350, -791, 3767, 1569, 541, 11921, 134, 368, - -948, -2689, 896, -1193, 1190, 8514, 1436, 1017, - 599, -3358, 4002, 12936, -675, 1044, -1210, 296, - -1109, 1992, 1282, 774, -13102, -608, -11145, 134, - 278, 944, -888, 350, -1574, 189, -2542, 3476, - -3018, 3368, -9304, -1839, 533, -2, 1057, 686, --11819, -1146, -973, 1594, 3526, -2890, -1528, 3489, - -475, -259, -9610, -475, -984, -3559, -742, 408, - -130, -2291, 899, 12177, -1934, -162, -3238, 1610 -}, - -.cb2220l0 = { --12528, 350, 1782, -474, 1439, -14269, -8, -1782, - -753, -1720, 167, -440, -2706, 222, -1629, -288, - 671, -111, 10270, 878, 152, 330, -1000, 639, - -1280, 1111, -2072, 1439, -476, 553, -2974, -614, - 1666, -466, 11811, -1393, 154, 624, -697, 176, - 1108, 504, 250, 572, -6, 704, 16, 647, - -1143, -1407, -411, 23745, 319, -189, -404, -641, - -86, -707, -770, -302, 13, -398, 76, -681, - -525, 354, -1225, -757, -23170, -484, -965, -430, - 13477, 898, 505, -17, 13812, -890, 357, 662, - 1000, -935, -60, 944, 400, -432, -221, 1047, - 307, -180, 5260, 16509, 650, -269, 1563, -6002, - -3082, 186, -3334, -5770, 1010, -394, 128, -699, - 537, -27, 1014, -531, -50, -163, -1664, -1026, - 732, -1296, 21856, 574, 416, -745, -443, -1382, - 272, 791, 1308, -308, -1636, 168, -10922, 119, - -1190, 1123, 1492, 1706, 1076, -2016, 3270, -994, - 876, -2316, -2992, 12625, -412, -159, 5249, 1424, - -304, 557, -431, -360, -340, -561, -292, 1748, - -224, 1789, -352, 386, 136, 76, 1309, -270, --24204, -515, 1142, 2119, 1144, -173, 1008, -693, - -430, -1052, 1890, -12483, -11416, 2918, 1591, -1202, - -1782, -1335, 1354, 1703, -510, 4287, -854, 1153, - 2018, -518, -960, 11825, 1295, -563, 11252, 190, - 4078, 222, -3115, 3306, 747, 2638, 1015, -1674, - 8032, -2386, 573, -349, -832, 96, 9564, 11708, - -483, 1326, 1804, -2903, -2024, -234, 1009, 3229, - -232, 803, 275, 444, -629, -192, 381, -1289, - -109, -29019, 270, -420, -408, -466, 113, -537, - -266, 296, 180, 506, 1015, -565, -517, 1494, --11053, 3968, -1735, 3474, -1991, -8326, 8075, 1740, - -3995, -1287, -2558, 1030, 3742, -618, -2600, -1783, - 2696, 1480, 1054, 341, 3762, 4225, -1742, -11582, - 4348, -8756, 493, -404, 3840, -1049, -683, -962, - 163, 10997, -97, -848, -4632, 2794, 2684, 2540, - 739, 8534, 3688, -878, 3138, 2576, 6444, 3674, - -2371, -218, 2864, 12270, 2866, 189, 4549, 4894, - -6378, -1050, -3166, -5897, 2245, 2803, -70, -1909, - 2783, 3951, 153, 11221, -658, 12780, -238, 3418, - -2235, 754, 311, -739, -2414, 702, 1076, 303, - -320, 47, -3288, -234, -1376, 3022, -103, -1780, - 716, 11886, 10942, -5402, -5431, 1196, -624, -885, - -652, -3248, 74, -435, -686, 154, 8675, 3325, - -1779, -341, 564, -901, 1335, -639, 3494, -1820, - 290, -92, -3088, 4775, -2140, 2334, 710, 10536, --15042, 14823, -1082, -1045, 1008, 734, 241, -1048, - -933, 245, 913, 114, 322, -1798, 246, 1067, - 348, 408, -183, -728, -12915, 685, 1525, 1694, - 183, -168, 12703, -1268, 1613, -2072, 1546, 743, - 2356, 2135, -550, -153, 1327, 2, 12487, -3111, - 2347, -1722, -300, -193, 2222, -1928, -658, -384, - -5738, -1141, 3634, 10312, -69, -1549, 10879, 1795, - -361, -1838, 143, 1202, 327, -15549, -1268, -194, - 3284, -12, -344, -2042, 1663, 334, -798, -873, - 1736, -324, 195, -417, -382, -22936, 812, -478, - -962, -451, 730, 382, -135, 1311, -290, 122, - 148, -775, -305, -32218, -84, 98, 374, 369, - -44, 923, -432, 156, -1471, 236, -39, 143, - -146, 835, 135, 229, -297, 1690, 6786, -12169, - 815, -176, 1868, -9, -3052, 108, 114, 260, - 11337, -2689, -132, 765, -239, 54, 691, -9737, - -627, -474, 12212, 2222, -7595, -239, 1793, 2115, - 563, -2390, -1991, 2906, 675, 923, 146, -3605, - 981, -1725, 92, -562, -21192, 304, -450, -323, - -889, -726, 688, -1186, 2590, 466, 326, -734, - 308, -782, -3219, 963, 454, 1348, -513, 953, - -1414, -320, 1012, -1148, 1185, -17356, -15, 1546, - 1346, 2182, -2457, 1426, -1690, 155, 8793, 1394, - 510, 2608, -203, 2697, 608, 2612, -13542, 177, - 4642, -824, 1877, -1864, 1681, -1033, 1487, -749, - 356, -11, -1, -366, -215, 1531, -38, -922, - -378, -296, 1245, 19967, -2389, -459, -3729, -163, - 6578, 354, -1471, 195, 353, 1831, -605, -2291, - -359, 947, 8409, 3454, 12416, 2434, 3485, 40, - 350, 1640, 738, -9827, 935, -171, -944, 1407, - -399, 571, 2805, -13108, 784, 678, 2405, 328, - -417, 1188, -1596, -649, -1358, -1130, 341, 202, - -2459, 11307, -2250, -3518, -1812, 3338, -924, 10027, - 3004, 703, -184, -666, 223, -1644, -7221, 3507, - 10108, 1324, -412, -371, -92, 2496, 3182, 10, - 10269, -998, -1010, 610, 3296, -1842, 407, 406, - -1609, -181, 2202, -662, -1450, 1360, 1488, -212, - 1501, -214, -555, 168, 275, 301, -950, 3272, - -323, 20632, -21, -1729, 11013, 2149, -9278, 6735, - -593, -7374, -430, -2776, 2343, -1374, 519, -4876, - 827, -2477, -1971, 1249, -23380, -1810, 199, -761, - 2182, 1654, 447, -488, -1219, 364, -53, -382, - -989, 154, -545, -872, 776, -211, 7706, -767, - 8006, -138, 1989, -180, 306, 486, 1112, -648, - -12, 1538, -300, 2458, -5833, -1181, -7680, -6700, - -621, -308, -29995, 602, -24, 94, 752, 517, - 86, -249, 1058, 704, -404, -387, 106, -632, - -159, 1275, -197, -1263, -1210, -1689, -10488, 1950, - -2037, 5974, -3960, 38, 1284, 2851, -2813, -1613, - -1646, 10164, 138, -2956, 196, -118, -484, 860, - 124, -262, 30, -1448, 128, 287, 327, 590, - 27272, 391, -738, -1631, -481, -1511, 82, -574, - -737, -614, -447, -80, 292, -19, 252, -2, --28117, 332, 141, 1485, -154, 1382, -1755, -422, - -1692, -2144, 910, 1004, 1894, -1537, 897, -458, - 19483, -1321, 2280, 622, 288, -2253, -1001, -976, - -408, -394, 132, -250, -428, -22, 140, 287, - -141, 30981, -293, 631, 729, -2, -231, -127, - 377, -879, -294, -107, 253, -964, 1258, 570, - 71, 9421, 8358, 9295, 8354, -546, 1153, -1807, - 1577, 2911, -1808, 1808, -1631, -1348, -6977, -382, - 1625, -2793, 10633, 1977, -1793, -12480, 1, 2010, - 23, 423, 1102, -1920, -478, 1845, 1016, 465, - 758, 800, -1540, 5448, -10472, -2749, -989, -6362, - 9283, 373, -2560, -5478, -1618, 20, -564, -1074, - 4075, -471, -515, 409, -2069, 359, -788, -11618, - 2524, 917, 2757, 243, -3261, 6922, 6268, -3148, - -2804, -3412, -4262, -1903, 1043, -12255, -162, 1598, - 496, 454, 1401, -1635, -12711, -673, 3392, 1255, - 1602, -1206, -297, -2066, 3009, 1149, 1285, -1307, - 412, 27971, 183, 569, 1304, -706, 824, -635, - -358, -340, -28, -1344, 955, 14, 676, -243, - -20, -11947, 1350, 8122, 196, -10161, 4925, -3764, - 1661, -401, 145, 253, 680, 718, -614, -613, - 498, -293, -4257, -684, -14853, -10522, 698, 1537, - -2016, 1162, -2684, -1578, 8, -238, -3214, -2749, - -1577, -1187, 113, -1457, 1068, 590, 25, -644, - 1000, 2430, -1612, 13246, -2684, -1642, -4648, 816, - -1103, -7556, 5753, -3998, -1338, -776, -1958, -9652, - -1288, -290, -4240, -2788, -8191, 1625, 2558, 1238, - -1824, -39, -3129, -8916, -3302, -5632, -1768, 866, - 708, 684, 3530, -8772, 1485, 677, -10398, 686, - -852, -6974, 5286, -2658, 612, 1180, -3367, 4285, - 5708, 1416, 166, 2787, -3697, 1431, 1648, 7942, - -544, -1064, -514, -840, -870, 1246, -3582, -9310, - -3802, 4025, -8251, 5978, 132, -619, 2792, 9786, - 1244, 242, -1948, -4701, -5904, 951, 7486, -3494, - 48, -4468, -2403, 6090, -2343, -4175, 1336, -2546, - -281, -736, -1758, -1720, 11066, -918, -1354, 3885, - -33, -4116, 1246, -218, -8082, -766, 7796, 1505, - 1559, -964, 1741, -454, -1628, -762, 3034, -804, - -888, -9682, 9603, -2556, 2874, -5456, 3066, -7747, - 956, -660, -1538, -381, -760, 1747, 547, -517, - -697, -1411, 410, -514, -3988, -219, 13358, -2393, - -280, 11230, 2640, 795, 2534, -8094, -1838, 71, - 16, -203, 4224, -96, -2829, 2010, 1961, -1312, - -1266, 3952, 6894, 6996, -8062, 4708, 1193, -3439, - 1549, 935, 170, 614, -868, 43, -246, -188, - -940, 130, 126, -736, 697, -510, -56, 1596 -}, - -.cb2220l1 = { --13582, 1049, 15596, -101, 707, 2677, 542, -522, - -636, 194, -2361, -1252, 524, -32, 227, -419, - -652, -601, 84, -10428, -1417, 13117, -573, 3774, - -3632, 2025, -1237, -692, -1486, 192, 1221, 452, - 436, -764, -2636, -153, -685, 118, -424, -635, - -458, 209, -577, -12042, 4240, -10861, 49, -1534, - -991, -2416, -280, 2095, -1841, 1278, -94, -423, - -572, -949, 734, -1087, 12449, 6514, -4582, -7845, - -3722, 1446, 2531, -1238, -2070, 1515, -1331, 2382, - 1066, -1298, -1189, 6811, -1868, -1082, -1732, 356, - -2622, 493, -3345, 1367, 1737, 4497, -14734, -1350, - -354, -1340, 8478, -1152, 1832, 1793, 830, 974, --13918, 522, -1472, -2502, -2625, -157, -360, -17, - -830, 673, 36, -1339, -14860, 522, -13377, 851, - 937, -1103, -44, 408, -364, -953, -392, 1837, - 2342, 1236, 111, -218, -919, 985, 10077, -1065, - 1840, -124, 3780, -11015, 204, 437, -830, 6712, - -1720, 288, -991, 1094, 5647, -1296, -2284, 1642, - 1000, -35, -115, 208, -244, -1099, -832, -2092, - 802, -163, 3343, -964, 314, 126, -1204, 754, --17838, -826, 4414, 8331, -770, 1246, -3500, 1680, - 833, -108, 494, -910, -6314, -2832, 2553, -6230, - 1165, 3631, -1717, 2404, -32768, 520, -38, 1228, - -708, 58, 260, 771, 588, -448, 389, 156, - 606, -830, 400, -488, -188, 536, -1428, 11982, - -156, -1407, 1796, 1036, 905, 1371, -1472, 325, - 3098, -1436, 6449, 2105, -11183, 1632, -1848, 1019, - 1247, 1308, -1351, -823, 1679, -651, 978, 296, - 1088, 3965, -1414, -11838, 139, 8664, -3452, -1804, - 3088, -2044, -221, -1347, 1232, -909, -1323, -1409, - 1399, 2557, 14552, 1535, -5088, 1699, 1012, 3333, - 3940, 2294, 1189, -2256, -484, -3307, -1333, 464, - -305, -744, -24, -20464, 332, 2968, 308, -649, - 292, -402, 1226, -2575, -1505, -100, 1413, 733, - -1024, 616, -121, -322, 67, -161, -708, 251, - 462, -26697, -1112, -1381, -324, -286, 1091, 662, - 15830, 13124, -1049, -1816, -355, 1848, -801, -1710, - 2513, 458, -798, 386, -726, -356, -1240, -1133, - -388, 631, 91, 1867, 2511, -306, 3097, 14399, - -571, 2191, -2916, 2850, 761, -2442, 698, -2193, - -2739, -1914, -4077, -4631, 12702, 333, 1162, -6248, --12466, -310, -107, -2465, -163, 1970, -998, -1253, - 2007, 79, -426, -276, 365, 568, -520, 23642, - 276, 1059, 184, 1081, 650, 2286, -191, 883, - -1946, 246, 64, -225, 800, 910, -136, 1187, - 955, -15604, 12847, -747, 874, 506, -646, 1920, - -449, -321, 1152, 1341, 1653, 341, -32, 907, - 673, 1045, 1245, -499, -10331, 4683, -1121, -3164, - 3382, 6397, -1341, -769, 1186, 229, -1354, -7370, - 155, 1858, 5617, -3487, -247, -783, 724, 508, - 14029, -528, 1853, 1572, 580, -708, 528, -1394, - 8922, 2284, 550, 3084, -1726, -3235, -700, 7132, - -3540, -200, 3288, -815, -2189, 1232, 2412, 2088, - -1101, 12592, 806, 1508, 1741, 13, 1124, -3883, - -687, -8180, -3094, -3346, 1781, 11836, -657, -3469, - 1429, -1822, -3433, 87, 3871, 651, -965, -1757, - 6778, 109, 112, -131, 710, 11943, -12107, -3460, - -726, 1002, -3803, 580, 2756, -1293, 116, 457, - 581, 3834, -1678, -977, 1242, -2040, 232, -10034, - 1644, -2290, 1368, 172, -3012, 1423, -2620, 3608, --10831, -303, -1610, 3246, 562, 5212, 448, -877, - 954, 688, -8981, 579, 717, 1315, -952, 6817, - 662, 3218, 7213, -2116, 10446, 1012, 2270, -858, - 10, -1066, 10618, 6108, -547, 3221, -893, 3888, - -1088, -10085, -247, 1064, -3500, 3123, -2480, -2128, - 2788, -2253, -9756, -472, -166, -680, 727, 74, --14151, -189, -1734, 610, -1169, 845, 94, -786, - 394, -581, 500, 1981, -10940, 354, 500, 399, - -1952, -373, 2197, -4712, -2582, 2751, 654, 613, - -1254, 1406, 2056, -12518, 1583, -582, 4834, -1541, - 508, -20580, 270, 1214, 515, -1082, 5, 7, - -533, -28, 1270, -1307, 497, -57, -331, 933, - 92, -856, -10458, -4576, -9991, 2426, 6552, -3022, - 279, -562, -192, 1878, -2237, 4978, -1753, 332, - -1462, -853, 238, 478, 9746, -7385, -10290, -8278, - 457, 3121, 841, 48, -3745, -1298, -637, -1820, - -468, -248, 1400, 394, -125, -950, 11524, -1860, - 426, -773, 12669, -1620, -158, 1625, 1045, 768, - -66, -12, 1625, -770, 559, 54, 593, 14468, - 14994, 490, 543, -811, 700, -277, 900, -178, - -2000, 475, 241, 950, 106, -1260, 874, -862, - 18907, -1947, -844, 205, 1253, -83, 1966, 2300, - -2694, 852, 2450, 661, -334, -518, -1136, -2377, - 325, 1152, 511, 881, -22205, 898, 574, -582, - -265, -1362, -253, -40, -780, -1967, 469, 1484, - -818, -926, 958, -415, -7934, -330, 330, 1439, - 1643, 77, 1034, -156, -12094, 3782, -5725, -520, - -598, 2345, 3506, 5333, -322, 99, -48, 1490, - 20, 11393, 3468, -1144, 7013, -3728, 7145, 1432, - 1810, 26, -912, -6530, -1079, 1771, 95, 4007, --11346, -43, 249, -14616, -249, 1, -725, 244, - 1053, 1815, -626, 408, -344, 1972, 2222, 2288, - -2324, -411, -3993, 494, -706, -5078, -11695, -3645, - -2090, 2465, 5893, -5096, 6815, -537, 5003, 1258, - 185, -1555, -875, -2047, -170, -433, -194, -1020, - 349, -724, -31811, 197, 251, -418, -222, -618, - 278, 554, 363, 183, -898, 14, 350, 745, - -2054, -1623, 806, -770, -1246, 1594, -54, -18501, - 1516, 840, -86, 484, 514, 1209, 978, 564, - -537, 34, -431, 128, 938, -1807, 832, -90, --29509, -642, 1397, -52, 523, -393, 216, 908, - 9, -63, 710, -949, 3, -184, 175, 613, - -687, -408, 27, -855, 18258, 1282, -948, -219, - 2374, 1668, -4567, 1063, -2045, 12026, 461, 3074, - 1050, -1788, 169, -13442, 612, 19, -2019, 685, - 452, -152, 299, 310, -2327, 348, -215, 1634, - -201, 2162, -10300, 12452, -3733, -420, 2388, 518, - -2308, -160, 1552, 3347, 1650, 3293, -1108, 2065, --12618, 20, -42, -643, 202, -1298, 251, 2489, - 1322, 2362, 3698, -190, 592, -12484, -937, 2072, - 1531, 302, -409, -899, -1016, -388, 1103, 30006, - 789, -1609, -548, -1002, 1055, 605, -955, 1557, - 452, -623, 810, 597, -696, 10628, -1174, 606, - 2628, -553, -2297, 6668, -2600, 787, 3504, -3606, - 4087, 1052, 6276, -7619, 337, 2565, -13, 1205, - -124, 1222, -28082, -79, -553, 628, 542, 1315, - -609, 322, -895, -377, -694, 610, 239, -152, - -2901, 9890, 716, 1030, -3306, 988, -738, 562, - -2209, -1676, 4507, 1165, -12924, 866, -154, 3664, - -367, -2580, -7286, -572, 2167, 118, 508, -4429, - -480, 842, 2489, -1636, -2042, 1125, 1847, 2586, - -5639, 3361, -760, 11189, 623, -282, 1353, -279, - 515, -816, 713, 322, 417, -2820, -1114, -1563, - 401, -21604, -1300, -972, -2298, -483, 2176, -830, - 2135, -4084, 1095, 1950, -1937, 539, -374, 3197, - 682, 472, -1368, -8095, -12026, 4833, 5586, 467, - 2400, 148, 381, -138, 954, -459, -724, 970, - 156, -1955, -1363, 560, -761, -1708, -1599, -17408, - -1064, -1372, -500, 1160, 735, 441, -773, -228, - 420, -1128, 260, 930, 12879, -926, -231, 1355, - -850, 559, 11377, -1729, 2478, 961, 336, 1056, - 5081, 9788, -555, 4067, 8664, -2720, -1462, 3012, - -7280, 965, 1462, -4703, 3649, 2084, -699, -262, - 408, -188, 2193, -2216, -4509, -736, -1039, -4848, - -8243, -7958, -172, -1318, 9566, 4665, 3363, -3672, - 1581, -551, -2024, 1630, 1543, 90, -1728, -792, - -1799, 2571, 80, -412, -301, -2870, 1796, -5327, - 111, 17342, 592, -2108, 477, 1541, 1266, -1062, - -215, -2210, 223, 1215, -197, 87, -18340, -67, - 804, -398, -118, -3457, -741, -1935, -704, -274, - 566, -872, -1821, 12874, 5057, 2069, 1742, -6205, - -6115, -1614, -294, 187, -5210, 1734, -1466, -2162, - -2266, -642, -148, 440, 2, 233, -319, -637, - -734, -230, 301, 508, -433, 311, -313, -1206 -}, - -.cb2220s0 = { --15119, 7508, 1337, 4182, -2914, -3733, 2686, -470, - 2249, -3901, 1444, 3805, 99, -1771, -354, -903, - -2755, -709, -4980, 214, -2750, -652, -1042, 1434, - -1090, -612, -2574, 1274, 1310, -760, 1420, -112, - 2776, -4843, 15060, -4929, -3942, -5721, -1628, -1142, - 3023, -1435, 1402, 1010, 623, -3527, 2624, 184, - 988, 98, 340, 16676, -1262, -1162, 3183, -4816, - -592, 1019, -1406, -2478, 2371, -1004, 3944, 803, - 5665, -2261, 16427, 349, 3113, -916, 442, -1754, - -3551, -1351, 1563, -1316, 532, 343, -392, 1509, - -717, -122, 2462, -929, -185, -683, -18780, 2682, - -123, 518, -379, -5160, 245, 1940, 13964, -12311, - 590, -30, 159, -1558, -1940, 36, -1528, -515, - -1178, 856, -395, 29, -5854, -12943, 13286, -2572, - 1049, 768, 3292, -3921, -52, -462, 1968, 4933, - 630, 930, 1026, 2606, 319, -277, 6333, -2119, - -4700, 2164, 1583, 154, 2107, -1467, 339, 634, --17240, -595, -3525, -2690, -1788, -476, -41, 165, - -1016, -1456, -348, 11289, -2920, -3804, 2357, 12012, - 3848, 1796, 2164, -5555, 4527, -201, 965, -4893, - 3419, 6441, 1691, -77, 348, -769, 27319, -345, - -336, -541, -320, 972, 926, -1026, 1052, 702, - 224, 76, 742, 220, 6292, 8625, -3742, 4139, - -5989, -5615, -641, -231, -837, 6156, 4141, 3792, - 4746, 9972, 1800, -397, -2237, -2218, -7595, -2761, - -496, -1451, 1178, -970, -1226, 2527, -2105, 1778, - 1446, 1986, 9970, -13107, -985, -1142, -1367, -329, - -4498, 590, 36, 2073, -1069, 862, 133, 2516, - -27, 4494, -11602, -1638, 2524, 1449, 5684, -611, - -9452, -2618, 5006, 3481, -639, 379, -2333, -498, - -713, 382, 784, 269, -5692, -350, 524, -18705, - -1042, -1349, 1210, 1770, 3964, 4908, -1131, 17535, - -788, -1896, 30, -2682, 1044, 1604, -3740, 18, - 1771, 331, 4279, 2634, -368, -447, -6995, -1224, - -688, -5368, -236, -8872, 2449, -12189, 4465, 1895, - 2484, 1315, -5446, -457, -575, 101, 2356, -1585, - 3204, -104, -7244, -1678, -801, -2620, -4603, -11876, - -1787, 2962, -1796, -3385, -411, 5796, 2900, -562, - 835, 293, 7127, 4939, 721, -2972, -482, 121, - -2694, -2277, 412, 12770, -342, 718, 3306, 502, - -7281, -307, 552, 7158, 3289, -5051, 5230, -1185, - 3024, -942, -1347, -283, -13937, -208, 2576, -906, - 1848, 5692, -2434, 175, 7837, 1872, -4536, -3341, - -957, 14787, -1598, 9058, 3776, 407, -1734, 1259, - -3011, -131, -3589, -614, 272, -2968, -1611, 3645, - -8126, 2120, 4868, -5462, -13235, -3452, -6077, 5064, - -1593, -1395, -2427, -1139, -958, 1585, -1330, 2178, - -778, 3545, 2836, 7712, 5993, -432, 3575, 929, - -7951, 115, 2180, 3904, -193, 1556, -252, -913, - 2574, 11948, -4525, 1391, -8513, 4540, -12815, -3379, - -4676, 1838, -5676, 1321, -6168, 1397, 1020, 438, - -141, 3424, 392, -512, -1614, -1396, -318, -2451, - 1545, -7132, -1763, -424, 3575, -828, 19216, 1978, - 1624, -1969, -1667, -772, -2031, -781, 1732, 244, - -212, 416, 900, -8960, 1002, -1077, 4667, -3527, - 1586, -13109, -2442, 3829, 4358, 1056, 2960, -1087, - -662, 4775, -6316, 6157, -3736, -2040, -187, 904, - 1254, -636, 2032, -734, -1271, -2691, 3376, 564, - -7769, -5482, 840, 14171, -5828, -966, 1685, -10192, - -388, -434, 3706, 594, 2188, 365, 209, 298, - 1825, -236, 12762, 1644, 3199, -468, 12876, 130, - -2169, -3406, -3571, -4655, 2339, 10757, 1292, 2920, - 289, -314, -591, -1631, -1778, -1296, -254, 469, - -9408, 1154, 334, -4, -1922, 2787, 317, 416, - -1703, 14075, 1601, 638, -2260, -973, -824, 2816, - -2954, 3282, -3716, -882, -3447, 3058, -6701, 1233, - 177, 3579, 3508, -3539, -10511, 7507, 7608, -1928, - 2482, -719, 2278, 5167, 9828, 10572, -3635, -2750, - 3407, -116, 3343, -3432, -3375, 982, 903, -3239, - -444, -1574, -333, 9613, -1914, -532, 1879, -78, --17944, -7029, 1586, -3122, 360, -401, 1219, -2086, - 3066, 878, 5780, -948, 102, 1952, 418, -416, - 1002, 1380, 1297, -92, -640, -555, -1159, -28517, - -1757, -696, 124, -618, 1590, 300, -598, 924, - -190, -1734, -4196, -5345, -14068, 5971, 8293, -3878, - -1448, -1777, -174, 921, -1555, -866, 560, 232, - -1914, -4002, -772, 1960, -4945, 3424, 6492, 3675, - -800, 5346, 4404, -639, 10697, 1631, -1446, -4469, - -7804, 3721, 4824, -620, 1099, -2956, 5175, -2453, - -4894, 2562, -1842, 4940, 1391, 2818, 1095, -4285, - 6469, -1966, -14564, -2232, 592, 5570, -2682, 2651, - 4678, -7444, -2387, 6812, -12757, -5664, -42, 134, - -2861, -1780, -158, 1410, -4990, 673, 2083, -2639, - 3019, -2, 8305, -1981, -2114, -54, 2892, 1659, --14913, -74, -1092, -1187, 2465, -2218, 791, -608, - 3077, 26, -1096, -1692, 3234, -7116, -1835, -5244, - 398, 10137, 698, 2298, 498, 7060, 6430, 1393, - 2540, 487, -1534, -1926, -5139, 3425, 4533, 5067, - -535, -924, 938, -1799, 16120, 2037, -3727, -821, - 2986, 2314, -223, 1358, 9, 2697, -1806, -940, - -3630, -1843, -2776, -2246, 580, -1678, 2427, 2126, - -1935, 2956, 849, 18234, 638, 342, 1036, 249, - -24, 2713, -1973, -134, -4469, -2014, -6162, -19776, - 703, -50, 2295, -2294, 1971, 1179, 1014, 2374, - -1480, 1513, 630, 1542, 24716, 3534, 2926, 662, - -2886, -521, -348, 402, 1112, -371, 1587, 1822, - 1880, 1284, 302, 1873, 1284, -924, 6420, 4650, - 7986, 427, 361, -8276, 304, -11911, -1305, -2018, - 189, 258, 839, -942, 479, -3162, -1195, -1138, - 1560, -1850, -5304, -10132, -10533, -1301, -3147, -680, - 56, 4260, -6867, -1350, -1094, -1385, 1831, -2, - -941, 3740, 7701, -855, 3304, 3444, -4467, 269, - -4092, 588, 13957, -1566, -3561, 1936, 2816, 2982, - 1804, 2710, 419, 685, 4468, 488, -9520, -2738, - 3974, -9978, -1681, -2418, 2340, -717, -899, -2855, --10470, 1030, -2346, -5555, 2559, 2180, -5324, 1832, - 10294, 342, 11318, -2376, -3904, -1524, -3806, 1078, - -1896, 7199, -3522, 1364, 2291, -911, -156, -4327, - -778, -30451, -577, -158, 560, 2749, 799, 2689, - 337, -301, -1218, 1243, 687, -880, -419, 40, - -280, 4, 1834, 9908, 1953, 408, 1080, 8777, - 3861, 552, -6906, -3546, -6666, 35, -1903, 4788, - 5080, 2865, -233, 1031, -4519, -13752, -2417, -1742, - -7389, 3191, -626, -411, -7351, 3063, -1801, -4377, - -2974, -124, 2778, 2733, 349, -1191, -6528, -1699, - 6907, 239, -2765, -5706, 3627, 2096, -20, 2285, - 7164, 3523, -11582, 3616, -614, 6266, -285, 3643, - 1506, 3665, 1261, -2338, 418, -5062, 4893, 2945, - 1923, -2990, -4531, -8858, 2769, -5029, 2202, 3337, - 10703, 716, 5614, -14982, -2366, -5415, 25, -1665, - 4353, 3060, -2159, 1005, -1587, -368, -949, -2788, - 1063, 1307, -59, -46, -6337, 500, -1194, 2914, - 2372, -1393, -1914, 3820, -1160, -135, 3777, -14151, - 5208, -2290, 5738, 1018, 385, 1883, -2626, -9289, - 1082, 1558, -1756, 2720, -519, -13050, -3672, 1759, - -13, 3471, 4071, -5977, 167, -4210, 2219, 1344, - -2412, 4497, -6946, 660, 8774, -3141, 6080, -4478, - 2520, -609, -3080, -741, 7864, 7428, -333, 1154, - -1849, 1478, 460, -338, -6651, -2480, 1692, 2104, - 1642, 2720, 1017, 2759, -1822, -2668, -2265, -1019, - -8926, 1487, 733, -15128, 5543, -4214, -7044, 666, - 7108, 2222, -2454, 4995, 5108, 1481, 2242, 5743, - -487, 9669, 295, 3539, 4836, 487, -1541, 824, - -5946, 6692, -368, -1390, -6103, 4545, 2671, -12272, - 3160, 760, -2080, 3523, -2752, -2940, -718, 2202, - -5523, 2346, -5580, -5007, 6212, -5406, -11348, 1272, - 5389, 2331, 3691, -1184, -3585, -4500, -603, -38, - -5285, -531, 4844, -3850, 3944, -6525, -5723, -2313, - -985, 879, 578, -3217, -3600, -2814, 1432, 11568, - -1461, -1761, -4110, -4104, -103, -1803, 5195, -1477, - 1348, 107, 3902, 1215, 3522, -3404, 9098, -237, - 68, 34, -2524, -12040, -6183, 2122, 470, -1257, - 346, -232, -1725, 5913, -1525, -5873, 1846, -11368, - 1043, -1027, 4201, -3864, -4294, 7756, 1847, -3688 -}, - -.cb2220s1 = { - 32767, -2256, 16, 2156, 267, 1128, 1394, -1936, - -488, -405, -345, 1068, 578, 1504, -1192, -405, - 292, 1149, 4243, 152, 1036, 1782, 2655, -23349, - -1100, -1933, 354, 966, -1554, 1173, -1186, 495, - 618, 1009, -2715, 461, 5974, 939, 3552, 1325, - 3385, -956, 2177, 2101, -145, -1000, 2326, 2466, - 2822, 15822, -581, -713, 4398, 828, -3249, -3942, - 1990, -862, 2272, 348, -2972, 241, -2678, -1881, --22307, 417, -587, 312, 280, -2524, 2380, 299, - 3931, 178, 2910, -2544, -356, -786, 546, -73, - -862, 240, -1653, 1286, -3875, -2072, -1477, 16800, - -1148, 2099, 3216, 5174, 2177, 3042, -796, 414, - -506, 883, 1837, 1451, 2864, 850, 2395, -414, - 3254, -1937, -16379, -3976, 2178, -1473, 4759, -832, - 8890, 3324, -3053, -407, -1530, -431, -1220, 128, - -3472, 980, 52, -14716, 1732, 1931, -6518, -1784, --11113, 4466, -24, -8559, 105, 5478, -4116, -2213, - -3006, 1738, -4189, 3310, -753, 1869, 580, -885, - 3089, 8146, -4990, -1825, -524, 3620, -6920, 621, - -1064, 4633, -1509, 80, -10949, -2752, 476, -3684, - 3547, -1967, 3364, 2887, -729, 7921, -4216, -3681, --14417, -3978, 261, -1146, -1124, -901, 777, 783, - -2, -989, -1582, 3988, 7785, -6371, -2258, 3344, - 354, 13289, 3339, 316, -3186, -2088, -1951, 310, - -545, -704, -40, 4416, -392, -1033, 5650, 99, - -3008, -3716, 2448, -3758, 9463, -1793, -130, 1705, - 6501, -2214, 2970, -10476, 564, -5952, -541, 2077, - -90, 6588, -2858, -1733, -9247, -345, -3170, 4986, - 3353, -4868, 8873, 113, -5223, 1562, -163, -2446, - -4459, -8052, 1106, -10883, 1185, -1756, -152, 3109, - 181, -1427, 8291, 11419, -6265, 2116, -469, 5150, - 1355, 182, -740, 779, -7754, 1868, 144, 3936, - -60, -784, -231, 879, 17032, -2273, 1886, -538, - 1015, 1798, -633, 1090, 1910, 128, -6094, -1946, - -1570, -727, -18457, 498, 784, -4419, 1656, -21, - 154, 2430, 3815, -41, -2708, -1594, 228, -784, - 7284, -452, -7634, -12868, 3564, 5473, -1244, 2231, - 28, 4321, -1464, 1402, -1358, 2241, 656, -1128, - 1160, -2352, 3641, -680, 1816, 6864, -42, 1269, - -280, -1265, -2048, 238, -653, 13571, 3874, -269, - 7977, 2238, -1246, -2066, 4741, 1706, 3498, 595, - 2559, 55, 593, 1681, 1612, 43, -2756, 2702, - 2439, -2471, -809, 1890, 17032, -787, -4280, 1167, - -1926, -4973, -1181, -2764, -4151, 2962, 3444, 844, - 2446, 14013, 3326, -1195, -1829, 1588, 1765, -3140, - 8562, -14425, 4040, 2003, -738, -1032, -3314, -2236, - 548, 768, -2348, 436, 1755, 31, -4616, 1259, - 269, 1543, -1393, 5338, -16463, 2900, -2480, 1659, - 217, -5864, 3878, 5268, 1244, -520, -1202, 1238, - 182, -1049, -695, -320, -6832, -5904, 2914, -2616, - 2586, -10958, -3258, -1846, -4633, 2371, 3251, -3583, - 2631, -4162, 3035, 2718, 616, 2890, 206, 16128, - 979, 3551, -6864, -3221, 5881, 3692, 1718, 234, - -2844, 1668, 102, 2687, -838, 988, 1116, 533, - 4026, -7235, 5972, -13781, -3394, -3518, -294, -6383, - 1675, 4507, 5444, 385, -1931, 930, 699, 1639, - 415, 6720, 7854, 1514, 3192, -2253, -14786, -1307, - 871, 1329, 1881, 6628, 2851, -85, -2284, -4538, - -837, -2232, 269, -2227, 13930, -2063, -7540, 8978, - 1195, 2717, -1282, -972, 1305, 3864, 2412, 2308, - -4824, -3282, -864, -489, -1458, 2192, 15903, 2460, - 2792, -4137, 1034, -359, 5, 2297, -6, -3859, - 478, -1535, 2080, -741, 2030, -603, -2640, -1902, - -8208, 3818, -1273, -8138, 2015, 9169, -3440, -1779, - 4076, -576, -93, -1718, 744, 2563, 6744, -3841, - 1355, 1590, -4196, -13924, 356, 13381, 2552, -2862, - 2790, -578, 3562, 2711, -686, -3783, -489, 1230, - 896, 1208, -1101, -3482, -2478, 772, 1254, 320, - -1825, -327, 1070, -1712, 295, -18141, -2618, 1537, - -603, 3782, -1272, -1901, 414, 169, -6574, -6966, - 2711, -3292, 13204, -1324, 3620, 4962, 2835, 4177, - 4861, -2378, -5534, 3701, -4224, -631, -3199, -653, - 4785, -1045, -2097, 580, 2190, -140, 48, 3075, - -1346, -810, 2016, 566, -2543, 235, -5930, 1956, - 481, 19003, -3938, 6489, 2697, 4796, 3435, 7102, - 3062, 1460, -5814, 2723, 4181, -4979, -2534, -2058, - -136, 3554, -2684, 15252, 4112, -3146, 2812, 7182, - -2642, 5443, -1043, -803, 2786, -1622, 1988, -780, - 1482, -13015, -1762, -1377, -4005, 161, -9568, 8166, - 1832, 330, -6484, 945, -4388, 1090, -524, 1556, - -582, 320, 770, -938, -8757, 977, 1084, -7062, - 3552, 775, -4708, -2281, -552, -10027, 4263, 1197, - -672, -93, 5716, -3825, -4526, 1781, 9799, 4450, - 1981, -3149, -9664, 3119, 3794, -91, 6710, 840, - -1098, 11310, -2933, 785, -2573, 748, 1803, -1401, - -1547, -4118, 849, -580, -1404, 1536, -9382, -1610, - 2335, 403, -2939, -3015, -3753, -7593, 1640, 3346, - -2594, -8028, 5485, 2189, -3369, 2106, 5369, -2573, - -515, 1459, 6996, 1344, -389, -7009, 10332, -840, - -3869, 901, -6449, -2348, -2461, -4103, -810, -2060, - 1040, 117, 32241, -231, 945, 999, -1183, 180, - 1443, 188, 855, -1634, 774, -202, 99, 1714, - 286, -849, 1968, -9743, -15458, -859, -3726, 2257, - 355, -167, -1674, 1808, -488, 1118, -1416, -1685, - 2928, 1471, -1145, -536, 2307, -972, -1191, 1625, - -1436, 378, 20178, -638, 1826, 472, -300, -845, - -1045, 1074, -1041, -510, -39, 516, 4548, 2741, --10197, -2336, 3828, 2093, -4148, -9138, 4239, 2520, - -3536, -3807, 2998, -2226, -6898, 4838, 2552, -2024, - -5579, 1370, 11706, -7626, 1566, 989, -4934, -1345, - -5962, 4259, 1158, -3712, -2710, -1037, 105, -2733, - 1068, 3682, 3904, 2044, 184, 537, -3438, -1376, - 332, 17812, -3170, 2386, -2090, 3481, -1352, 431, - -1016, -1062, -564, -1752, -2602, 1299, 6720, 789, - 1275, -9801, 5320, 2327, -4048, 4443, -7820, 1112, - 1232, -1139, -920, -744, -845, -3754, 5958, -5388, - 3336, -3578, -4027, 688, -7043, -136, -163, -1395, - 13400, 1729, -1862, 2612, 321, -3874, 947, -990, - -3164, 11487, 46, -1978, -2139, 1222, 3897, -9664, - 3692, 5431, -3364, -3706, 180, -4009, 2563, -313, - 3228, -1631, -9763, -9184, -6058, -4594, 1040, -3323, - 321, -3233, 5035, -1919, -5525, 1899, 1196, -1834, - -391, 549, -2114, -1436, -2624, 2441, 618, -27606, - -841, -936, 1067, 1157, 230, 784, -755, 1798, - -219, -1026, -1119, 320, -2611, -1382, 8776, 1151, - 3739, -607, 2997, -7704, -5870, 1800, 1357, 4973, - -9674, -5182, -50, -886, 2056, -802, -1909, 574, - -1716, -6388, -2882, -3526, -3188, -543, 244, 9648, - 5129, -5069, 598, -9049, 1834, -3375, 1369, 1461, - -1295, -380, -274, 7258, -9353, -2401, 11915, -5087, - 1505, 4211, -719, -902, 1762, -168, 642, 699, - -2067, -933, 1092, -958, 715, -1978, -1968, -1613, - -1263, -777, 1170, -9652, -9570, 612, -3935, 237, - 386, 4237, -1468, -10172, -4964, 2919, -6428, -7184, - 119, 3610, 59, 3168, -5474, -853, -5735, -1765, - 3063, -1352, 944, -1934, -3500, 9282, 5920, 784, - 90, 275, 3211, 2418, -8570, -10498, -2026, -1020, - -2989, 1511, -41, -11462, -1980, 5296, 2614, -21, - 770, -156, -2817, -4748, -8672, 3447, -7231, 4598, - -1347, -689, -3198, 434, 56, -2065, 1798, 13761, - -533, -1280, -796, 2481, 56, 1377, -5473, 9116, - -1185, -602, 2547, -3693, -8880, 2978, 9093, 1829, - 4844, -649, 316, -162, 1520, -5814, 4860, 199, - -1330, -5182, -6269, 2642, 1220, 2816, -4098, -3981, --13264, -398, 361, 2768, -4786, 1023, -97, 655, - -397, 2403, -1576, -386, -1112, 792, -1195, -759, - 742, 729, -2916, -1020, 21350, -26, -3577, 659, - -1263, 1378, -4339, 1880, 4842, -669, -1203, 5936, - 816, -8356, 3660, 1673, -677, -2370, 1652, 8710, - -1254, 6171, -6868, -891, -6752, -169, -5678, -7588, - -3247, 2982, 5281, -4941, -359, -3354, 851, -1609, --11194, 610, 261, -1936, 2715, -3540, -2488, 2086, - 6110, 914, -3224, 1777, -1558, 937, 3736, -3109, - 1903, 4250, -4478, 2636, 2292, -1451, 10231, 7600 -}, - -.cb2220m0 = { --26430, -533, 1599, 208, -293, 2303, 704, 1586, - -1064, -1630, 690, 1697, 623, 1786, 332, 682, - 199, 12695, 475, 1288, -2471, -797, -68, 9659, - -816, -2465, 546, -1421, 1596, -926, 4471, 2360, - 5551, -900, 297, 96, 400, 936, 1548, -1066, - -1625, 652, 1416, -118, -525, 683, 1545, 1340, - 20684, 936, -1033, -773, 8416, 954, -4822, 4223, --10815, -312, -896, 531, 3140, -1649, 508, 10294, - -315, -2078, 584, 1523, 118, 997, -11837, -605, - -262, -1732, -613, 12220, -2666, -1802, -507, -4410, - -100, 2127, -114, -886, -2806, 500, 1034, -2811, - 12642, 1015, -9193, -4201, 238, 1096, -1159, 1619, - 2534, 1644, -3465, 4797, 639, 2583, -1316, -9884, - 948, 1479, 1186, -1760, -343, -1286, -1653, 678, - -7439, 4542, -6295, -1600, -6978, 48, 448, 369, - 1597, -3696, -2121, 1002, 2428, -11368, 5385, 827, --10674, -2252, 2240, 1230, -3074, -1894, 296, -2216, - 571, 114, -497, -1675, 1311, -2297, 1843, -350, - -856, 2067, 1198, -588, 270, -470, 2640, 274, - 19586, -762, -11471, -623, -506, 4236, -10981, -214, - -1856, 409, -1276, -935, -1681, 5116, 774, 3008, - 4388, -112, -9493, -1108, 1454, 1385, 1065, 519, - -486, 308, -1141, 289, 1424, -3672, -15989, -3738, - -1592, -258, 3304, 62, 1441, 45, -686, -1070, - -1616, -701, 2313, 1918, 4843, 654, -16902, 263, - 1837, -4062, 2727, -709, 1524, -1628, 2025, -281, - 264, 1238, -1023, -11981, -2990, -1293, 801, -9606, - -604, -210, 1248, 4014, 3652, -11286, -2094, -470, - -1330, 14523, -2388, 1413, -3968, 641, 2936, 161, - -1687, -1260, 1722, -1968, 364, -854, -14386, 10146, - 792, 133, 1746, 261, 3345, -408, 2036, 272, - 1412, 720, -3302, -1495, -4334, 2210, 799, 17546, - 2600, 1314, 764, 1327, 3433, -377, 4296, 2402, - -1074, 470, 7220, -2556, 3326, -4338, -2086, -1945, - 11865, 3525, 1513, 1520, -1814, -13020, -929, -2001, - -1496, 580, -3293, -3146, -2185, 1442, 390, -2026, - -2141, -192, -18700, -2039, -4330, 1691, -250, 1451, - -2913, 2832, -3284, 2899, 1529, -888, 486, -2381, - -1459, -2663, 530, -717, -248, -1714, 12662, 1820, --11488, -1044, 3035, 3872, -2430, 679, 1075, 475, - -593, 930, -1751, 405, -2308, 2148, 510, -2798, - 445, -240, -6865, 2106, -11323, 670, 4342, 154, - -7748, -1805, 5381, -842, -697, -709, 688, -498, - 5525, 15212, -2006, -4146, -2452, 2392, -3522, -2023, - 1306, 5522, 916, -3616, -287, -653, 333, -330, - 4, -24886, 635, 119, -1949, 899, -36, -37, - 2658, -133, 2064, -534, -549, -1745, -70, 32767, - 1089, -869, 150, -599, -1146, -574, -424, 377, - -648, -303, 590, 453, 1910, -351, 553, 304, - -752, -752, -502, -42, -31211, -634, 449, 638, - 1086, -1406, 1220, 802, -924, -1874, -212, 86, - -200, -1140, 618, -621, -605, -10976, 1699, -603, - 2056, -4448, -1519, 2564, -743, 12304, 1482, 547, - -1589, -817, -217, -1633, -1089, -2270, 181, -634, - 3890, 734, -1319, -2035, 3304, 13144, -9076, -4067, - 70, 1309, 1067, -354, 1529, 1379, -1002, -3324, - -525, -817, -1438, 10834, 1036, 12441, 1242, 2461, - 2858, 2257, 430, -1177, 1142, -870, 844, 1102, - 1208, -1482, 830, 17622, -2753, 6, 174, 4385, - -339, 2157, -155, -68, -190, -1181, 29, -2046, - -2140, 27, 949, 1889, 446, -54, 16696, -49, - -3304, -1929, 1833, 3735, -495, -1225, -11743, -2259, - 891, -1954, 2848, -504, 1164, -2489, 861, 579, --11547, 976, -42, 1477, -2428, -1561, 112, 74, - -2721, 12046, 632, 1283, -1900, 1990, -1193, 1606, - -1370, -2812, -1309, -1419, -12526, 3391, -4213, -2710, - 269, 90, 14575, -345, 820, 6118, 892, 6302, - -2825, 332, -3071, 2279, 3756, 185, -3029, 2402, - 245, 1010, -273, -32751, -140, -600, 482, 1516, - -462, 1931, 1941, 272, -310, 544, -422, -815, - -1116, 803, -617, -1640, -4336, -11735, 3656, -1176, - 1170, -6209, 2139, -1571, 2067, 1011, 9842, 790, - 1702, -191, 911, 2771, -253, 794, -3862, -1885, - -494, 2070, -2682, 772, 763, 4304, -15657, -2194, - -1998, -963, -5222, -175, 238, 32, 10067, -692, - 2824, -474, 3016, -11994, -51, 713, 2423, 2864, - -338, 4838, -1095, 215, -13471, -2, 704, 752, --14654, 1396, 484, 564, -886, -775, -1099, 775, - -1035, 1661, -1013, -1118, 449, 822, 14253, -13238, - -1084, -1107, -1672, 996, 472, 2237, -440, 1186, - 1200, -2112, -1388, -1093, -1902, 555, -328, -1493, - -2034, 426, -2144, -388, -20028, 1285, 1122, 730, - 1661, -1576, -2084, 2930, 337, -66, 1591, 8685, - 2361, 146, 1370, 22, 1371, -105, -4190, 371, --13252, 328, 1301, -995, 3689, 6422, -79, -1407, - -384, 828, 840, 854, 266, 1222, 796, -550, - -729, -1213, -87, 524, 1070, 22334, -2333, 574, - 680, -624, 463, 4047, -236, 114, 1020, -692, - 1575, -320, -3229, 222, 520, 996, 2104, -5404, --18197, -1105, -184, -1057, 10712, -2509, -7140, -2307, - 1333, 3041, 183, 1241, -7861, -3060, 1432, 9, - -1431, -2605, 2663, 273, 250, 770, -740, 6699, --10929, -7227, 105, -2983, -1203, 1637, -6072, -6630, - 933, -1526, 658, 2612, 5377, -91, -66, 4944, - 3025, 2723, -869, 142, 10532, 9858, -207, 3072, - -2610, 0, 81, 1078, 2136, -266, 223, 931, - -385, 983, 1029, 108, 2290, -491, 26685, 565, - -140, -662, 680, -2206, -803, -777, -250, -467, - 98, 2944, -12296, -4190, -2254, -748, -2076, 4780, - -510, -221, 1428, -6162, 2693, 6238, -4030, 266, - 6540, 2502, 5147, -4649, 1804, -10514, -3413, 2503, - 2143, -1924, -3811, 3674, 4341, -1054, -3130, -1260, - -576, 887, 25908, -773, 1186, 548, -606, -744, - -995, 1320, -507, 279, 1803, -2451, 880, -31, - -5, 1615, 770, -11818, 1062, -1126, 472, -297, --12126, -1197, 1912, -962, 1241, 2348, 2332, -3047, - 1561, 3844, 720, -387, 371, 2942, 1174, -2347, - 1244, 10148, -1620, -11788, 1315, -31, -1867, 3450, - -1589, 5180, 3184, -2614, -13, 130, 107, 297, - 113, -1407, 29190, -544, -173, 990, 913, -1848, - -990, 1230, 264, 1896, -6974, -102, -2232, 3826, - -2269, -5027, 94, -12612, 436, -5979, 1757, 1757, - -724, 2378, 2584, 728, -1022, -7274, 668, 744, - -516, 420, -11866, 246, -1357, 2406, 3674, -2594, - 1638, -3037, -2402, 1525, -7304, -1078, 1772, 9264, - 12366, 202, 2, -728, 684, -437, 1446, -3546, - 828, -2106, -2736, 964, -180, 6524, 2250, 514, - -782, 675, 1418, -11225, 2760, -3970, -545, 9128, - -6601, -556, -1966, -4625, -149, -198, -3330, -1575, - -6198, 656, 674, 367, 1809, 155, -5126, 6109, - -572, 4927, 1448, -1855, 1636, 8648, 2010, 8973, - 3087, 10172, 34, -1183, -12, -1057, 192, -2955, - 1034, -374, 2500, 9318, -4090, -5220, -404, -1022, - -1458, -1367, 765, -1193, 1542, 302, -1337, -34, - 1449, 1434, 2210, 404, -3277, -8024, 1363, -7591, - 9096, -9179, 1176, -7311, 544, -8942, -713, -56, - 2623, -35, 1623, 2212, 1733, -712, -1327, -320, - -1966, 11352, -1276, -3804, -550, 520, -4848, 550, - 1488, 944, 10756, -782, 5643, -2647, -6513, -3500, - -2877, 1880, -6634, 2349, 256, 440, 188, -8428, - -4580, 2479, 4763, -1807, -513, -4292, -1729, -6878, - 448, -6706, -1162, 4938, -721, 5465, 1409, -8759, - -898, -4254, -5230, -3886, -7969, 1730, 3656, 1198, - 3537, 33, 4091, -2088, -7646, 1160, 2922, 855, - -1254, -2616, -770, -685, -100, -577, -4927, -792, - -2107, 9613, 2563, 5096, 6143, -3404, -8630, 4164 -}, - -.cb2220m1 = { - 32524, -324, 411, -34, -697, 818, -71, 2326, - -142, -989, -1512, 358, -260, 3791, -575, 93, - 224, 208, -1101, 32767, 1147, -203, 2015, 461, - 668, -296, -3340, -38, 720, -993, 1765, -1344, - 1323, 648, -997, 729, 581, 349, 861, -2035, - 1791, -2142, -822, -1425, 820, -6555, -811, -15708, - -912, 4835, 1500, -604, 527, -937, -640, -1240, - 4692, 1259, 174, -12040, 450, 8196, 2796, -5123, - 1595, 538, -101, -218, 5581, 367, -2700, 277, - 2111, 2718, 1458, 155, -100, 3284, -498, 9961, - -1505, -10336, -1170, 5337, 1032, -14947, 1154, -578, --11773, -945, -660, 669, 2340, -1038, 1520, 713, - 2663, 422, -1242, 1918, -234, -1793, -1580, -271, - -5628, -2010, -12209, -1784, -4417, -2804, -3123, -4316, - 126, 6353, -2391, -2088, 836, -2550, 521, -1258, - 918, 4471, -528, 4243, -615, 3453, -6683, 1784, - 790, 13200, 700, 322, -815, 6049, -290, 928, - -1121, -1531, -878, -1150, 1404, 325, -530, -435, - -254, -804, -2536, 589, 8439, -1087, -16248, -637, - -1528, 305, -1577, 642, -22699, -139, 1319, 588, - -3079, 800, -597, -1408, -1150, 3145, -868, 3244, - -1004, 1004, -1459, -11618, -4557, -3643, -914, 4238, - -626, 4025, 3227, 537, -4285, 2010, 747, 1595, - 1599, 5994, -797, -911, 2854, -3426, -8488, -1899, - -301, -2146, -111, -522, -1852, 3075, -3864, -1531, - 654, 193, -11264, 5561, 304, 525, 346, -2761, - -1124, 1134, 8354, -12460, -1023, -7634, -2750, -1518, - 5001, 1480, -1039, -502, 1455, 586, 1012, -1270, - 12435, 895, 1169, 466, -10696, -3861, 4381, 1790, - 767, -1808, -537, -1057, -2374, -2058, 9992, -858, - -1568, -678, -3812, -1520, 1521, 230, -1716, 13418, - -1930, -979, 3272, 1116, -4555, -559, -320, 12080, - 13696, -286, 652, 2420, 1725, -277, 213, -1046, - 1642, -576, -1514, -973, -1501, 77, 537, -606, - 1144, -680, -568, 1104, 2176, -969, 1657, -784, - 1107, -1056, -59, -5607, 64, 11913, -178, 8703, - 3744, 276, -50, -12807, 1122, -6138, 1901, -439, - 733, 6829, 3001, -61, -1005, 3816, 3987, -3588, - -778, 2257, 12101, 196, 13796, 355, 1407, 989, - 101, 1041, 988, 1274, -1478, -1127, 1320, -442, - 3452, -1717, 1244, -466, -868, -323, 502, 1243, - -70, 897, 958, 2781, -2492, 788, 744, -12324, - 1111, -11704, -452, -734, 19574, -45, -584, -2387, - -830, 603, 380, 787, -2962, 2046, 2524, -2403, - 699, -4144, 1587, 573, 588, 238, -88, 31, - -278, -32768, -1173, -745, 667, -188, 1221, -369, - -261, 322, -2054, 651, 100, -2092, 315, 1558, - 596, -407, -146, -1234, -30970, -71, 633, 536, - -1345, 1819, 655, 680, -1453, 492, -1265, -1292, - 1780, -68, 1008, 215, -19980, -521, -3148, -256, - 193, 916, 453, 86, 116, 108, 1518, -1420, - -1501, 688, 669, 1196, -1579, -942, 868, 804, - 110, 1126, 202, 1086, 23516, 1070, -1623, 747, - -38, -116, 1176, 554, -2361, 1008, 1085, 1972, - -1794, -96, 464, -20910, -1208, -3857, -466, -2173, - 2461, 2364, -931, -684, 3056, -719, -936, 887, - -3149, 1004, 7085, -2985, -9393, 5142, -9621, 150, - 174, 572, -2232, -390, 1356, 160, -10796, 2256, - 2238, 242, 1663, 485, 12378, 1236, 688, -2908, - 1084, 1047, 4850, -72, -642, 1604, 152, -850, - 670, 968, -3207, 1690, 105, -2516, 11539, 390, - -1117, -588, -10771, 2879, 4742, -8351, 1571, -850, - -605, -1959, 395, 12324, 1750, 2290, -92, 774, - -2897, 1025, -1841, 546, 3904, 3908, 11494, 9, - 1340, -11976, -525, 1522, -43, -43, -1860, -6160, - -199, 2479, 4593, -2876, -2985, 1044, -62, -812, - 10424, -2489, -1098, 796, -1292, -2070, 1096, -1944, - -2145, -4374, 1041, -1014, 9036, -2142, 328, -8232, - 152, -13336, -2225, 13716, -367, -558, -1942, 161, - -472, 2224, -748, 3550, -809, -493, 2121, 1234, - 772, 5146, 2485, -2282, 7546, -1441, 1595, 9176, - 6208, 1292, 1704, 3968, -1500, -1974, -3519, -2826, - 149, -903, 504, -187, -940, 121, -215, -615, - -257, -1954, 958, 2057, -191, 21258, -726, 2081, - 1278, 1670, -854, 2730, -8132, -530, 1004, 2574, - 1430, -2536, -10851, 1389, 155, -140, 2158, 2762, - 3807, 3850, -3728, -954, -11366, 709, 14727, 514, - 694, -87, 857, -249, -419, 617, -418, -1144, - -32, -2182, -839, 1449, -1072, -785, -246, 13634, - 12488, 358, -447, -2262, 926, 1023, -901, -345, - 2260, -1530, -1466, -2973, -2170, 2090, 44, -23476, - 603, -1740, -345, -438, -3004, 1322, -3088, 1274, - 341, -348, -534, 1055, 3026, -932, 514, 8958, --15489, -374, 1077, 1166, 48, 1016, -918, -27, - -410, -266, -1401, -3888, -2918, -2146, 2815, 1834, - -875, 162, -678, 1876, -2033, 1999, -12854, -1563, - 192, 414, 782, -3109, 1432, -4197, 2358, 8517, - 784, 1256, -1362, 2938, -11355, -5184, -10314, -39, - -2182, -1686, 241, -195, -232, -6169, 206, 181, - -470, 1008, -599, -284, 733, -836, 648, -138, - 2078, 313, 24432, 548, -441, 1446, -1628, -1218, - -64, -716, -2456, 1987, -352, -1025, -1951, 1320, - 350, 744, 2598, -984, -18328, 622, -4, -1572, - 893, -3043, -4365, 127, -1, -226, -1696, 1332, - -1360, 6756, 2596, 12059, 370, -3690, 497, 585, - 1619, -778, 9174, -2046, 2214, 2004, 1133, 1069, - 132, -250, -1555, -906, 561, -12904, -1039, -8006, - 1876, 2300, -1116, 1895, 1782, 3734, -1108, 1338, - -1409, -248, 16117, -1458, 156, -2626, 64, -1199, - -3544, 4283, -3390, -404, 1426, -907, -2768, -780, - -34, -18656, 2003, 515, 3171, -653, 762, -3352, - -154, -1171, -452, -1590, -5936, 519, 1210, 502, - -409, 2262, 695, 1028, 8652, 2532, -2636, 3472, - -1186, 1350, -651, -639, 8382, -3234, 630, -10323, - -2285, -1916, 826, -1449, -738, -344, 1022, -3248, --20921, -200, 568, -84, 777, -1570, -2756, 2834, - 26, 3878, -1709, 101, 1433, -2238, 305, 61, - -1041, 2399, 628, -1509, -388, 946, 733, -1538, - -650, 19935, 478, -10696, 850, -682, 447, 2311, - 35, -1258, 2332, -11417, 1743, -834, 660, 3170, - 2378, -2734, -762, -1151, -1802, -9324, 4625, 2304, - -1186, 1180, 4894, 662, -7067, 869, 613, 1802, - 4839, 3412, -5460, -862, -4202, 7876, -1057, 2872, - -1336, 1731, -10788, 1088, 3433, 42, -939, 2479, - 6425, 991, -1621, 3222, -2464, 2988, -29, 481, - 11606, -2800, -8315, 7660, -3385, 1217, -728, -3670, - 684, -2295, -724, -567, -2150, -106, -1920, -2143, - 3465, 1968, -1089, -11953, -2704, 3049, -1351, 7225, - 5727, -525, 2639, 1955, 2259, 6489, -1867, 1544, - -3199, -4992, 2420, 4119, -2860, -9505, -2152, 10204, - -1133, -1201, -1468, -2989, 4658, 578, 1115, 368, - 1570, -776, -503, 1554, 1329, -696, -760, 575, - -1527, -3865, 8372, -3378, -8137, -8392, -3471, -1854, - -4852, 5270, -634, 608, 1289, -7660, 4983, -1266, - -2070, -906, 3291, 2459, 4807, -4241, 5773, -2258, - -4500, 2634, -13176, 6412, 282, -5849, 294, -626, - 888, -1088, 656, 192, -630, -3405, -12469, 2882, - 2184, 3920, 2715, -6852, -1111, 869, -161, 341, - 1856, -9450, 2719, -579, -3840, -8763, 1153, -3532, - -571, -766, 8301, 2936, -10501, -1073, 10068, -2930, - 6308, -2747, 3093, -1710, -3865, -1464, -4447, 446, - 898, 5386, -1074, -4651, 6205, 455, -1773, -1270, - 6986, -2493, 4076, 10605, -2522, 977, 4098, 1153, - -434, 4071, -2890, 2920, 9175, 2276, 4699, 642, - -1067, -968, 508, -1752, 728, 3260, -500, 1414, - 5554, 2761, 1973, -4704, 2127, 1397, -1070, -14536 -}, - -.cb2224l0 = { --12451, 389, 917, 1238, -626, -904, -1877, 2328, --12808, -1345, 406, 80, 383, -3841, 1188, -907, - 2369, -13409, 11191, -2547, -532, 762, -1627, 680, - -2305, -811, -1118, 3232, 3413, -2010, -453, -6816, - -4100, 1643, 11209, 933, -2272, 1440, -2465, -6862, - 186, 1563, -8468, -1832, -1166, -596, -326, 105, - -115, -352, -624, 31621, 129, -301, -615, -313, - -176, 620, -5, -1354, -3563, 678, -301, 621, - 904, -769, -1314, -956, -2294, -362, 381, -2398, - 17085, 100, 3962, -830, 18705, 237, -1296, 3534, - 1452, 259, 1690, -3106, -3624, -316, -16, 5900, - 2195, -1008, 14335, 14173, -1637, 1130, 1110, 499, - -1516, 500, -720, -494, -1010, -1264, -773, 1389, - 212, 8036, 780, 608, -415, 931, -301, -2186, - 2256, -706, 12972, -3461, -3695, 2073, -2768, -1525, - -7539, -441, -753, 4558, -8171, -1751, -6885, 4077, - 6714, 53, 1090, -3006, 3688, -1162, -59, 302, - 928, -450, 238, 10809, 353, 698, -476, 172, - -2198, -4377, -7518, 1605, 6348, 5147, -165, 165, - -463, -93, 1251, 671, 587, -402, -227, -462, --27960, 215, -56, -958, -657, 508, 98, -2811, - -1443, 3076, 6218, -9760, -10465, -770, 345, 3076, - -116, -2884, 2215, -2652, 1306, 2638, -124, -317, - 366, 1461, -295, 5073, 460, 1920, 12216, -7032, - 6816, 3037, -2630, -1087, -1315, 123, -582, -2137, - 5061, 291, 1740, -214, 1920, -3470, 10895, 9491, - 3558, -1256, -448, -10304, -2391, 1890, 484, 11057, - 6636, 422, 2316, -1663, -348, 633, 1200, 1788, - -1124, -24435, 140, 869, 738, 223, -1429, 602, - 433, -196, -1127, -1937, -879, -310, -564, 1022, - -4380, 7247, -3938, 4461, 2219, -8465, 9266, -4564, - -3169, -3463, -477, 749, 2460, -776, 294, -171, - 1072, 1748, 1000, -208, 1908, -998, -1898, -10485, - 2360, -11950, -2412, -2609, 3885, -2738, 1348, -559, - -1342, 9366, 1560, -816, 1178, 342, -175, 1286, - 3014, 10641, 246, 3128, 6618, -305, 10906, 6359, - -4395, 1415, 196, 11136, 1772, -3047, 3313, -1231, - -1974, -3021, -1480, -1345, -830, 1551, 2521, -506, - 7821, 7715, 5078, 8215, 2102, 1552, 2247, 3766, - -3158, -1811, 631, 3980, -397, 9030, -1267, -1974, - 1539, -360, -315, 796, -4749, 2076, -1017, 717, - 2290, 11212, 9365, 1626, 379, 2060, 1329, 4, - -25, -1348, 566, -1266, 1670, 2166, 13123, 42, - 2416, -2170, -6380, 172, 316, 40, 300, -487, - 402, -220, 846, -894, -1413, -2227, 1962, 19478, --14756, 14377, -582, -770, -186, -1008, -1520, -722, - -885, 2622, 311, -753, 480, 539, -1011, -1748, - -832, -603, -2015, 869, -14860, -600, 2110, 484, - -5874, 1532, 3290, -222, -4670, -33, -794, -2061, - -1185, -96, 337, 515, -1887, 26, 20283, -455, - -799, -62, -1083, 236, -1721, -569, -1259, 361, - 1090, -226, 1480, 13367, -638, 940, 3736, 6419, - -5995, 830, -6599, 4549, 1583, -9001, 1104, -1281, - -1270, -94, 1104, -2076, 652, 2263, 1465, -25, - 9046, -8139, -2646, -13200, -534, -15244, -1448, -1390, - 452, 584, -314, -1192, 951, 885, 396, 776, - 1303, 1298, -448, -32641, -234, -62, 31, -164, - -1042, -82, -26, -272, -559, -164, 669, -500, - 516, 1347, 9615, 1123, -1346, -1898, 8341, -10583, - 2286, -5233, 1503, 454, -2024, 4248, -2298, -2117, - 13390, -849, 2078, 1096, -651, -12232, -374, -812, - -3729, -829, -144, 1213, -469, 1112, 1146, 816, - 818, -912, -967, 907, 12, 2443, -759, -1833, - -174, -838, 488, -1560, -18242, -558, 5510, -1316, - 1758, 3957, -7130, -1394, 4962, 3870, -1907, -9247, - 2217, -3880, -4413, 1893, -3085, -202, 599, 1307, - 1574, -1070, -2593, -2722, 9506, -10170, 1105, 4879, - 2208, 38, 5596, -5990, -3205, 35, 9405, -219, - 618, 1308, 353, 3457, 1712, 717, -12937, 25, - 2176, -2590, -1223, 528, 1318, 4588, 7678, 5743, - -8430, -4487, 1364, 8082, -1727, -387, 469, 3172, - 401, -2771, 694, 14554, -2278, 3640, -11084, 924, - -593, -3841, -4338, 227, 750, 2974, -2834, -1765, - 2133, -1181, 5149, 11758, 11949, 3538, 2442, 2801, - 1457, -822, -3419, -2468, 191, -646, -975, -1271, - 832, 3088, -495, -10022, 1817, 1319, -880, 1342, - -1448, -3597, -3310, 8753, -161, -6550, 1422, -640, - -508, 11542, -277, -165, 837, 7389, -942, 11009, - -97, 1548, 1418, -445, 2105, -946, -8676, 5274, - 8842, 576, -1392, -1737, -1276, 5491, 312, 3624, - 2806, 2157, -537, 1656, 1982, -1300, -146, 463, - 496, 16792, -140, -1755, -832, -2123, -399, 5811, - -702, 2891, -3630, -1843, 346, 508, -364, -498, - -558, 32048, -744, 90, -372, 430, 704, 871, - 139, 772, 696, -108, -18, 310, -411, -798, - 465, -165, -321, 745, -27861, -752, 499, -215, - 172, 35, -196, -770, 274, -546, -96, -470, - -8976, 9156, 581, 904, -4644, -7801, 3525, -607, - 6444, 4058, -696, -1107, -632, 1475, 196, -933, - 883, 1101, 278, 433, 544, -497, 4, -1882, - 1504, 594, -30386, 218, 211, 850, -989, 319, - -867, -42, 754, 498, -70, -562, 660, -11561, - 54, 803, 425, 966, -1017, -1224, -12630, 1834, - -41, 98, -1083, 3508, 1750, -1751, 72, -503, - -38, 22211, 252, 88, 221, 690, 82, -1340, - 508, 638, 832, 482, 51, 7954, 2702, -1176, - 8830, -311, 2536, -6072, -4147, 5234, 494, -157, - -1289, -5678, -1617, 1508, -140, -55, 713, 440, --32583, 105, -394, -613, -972, 578, 1122, -32, - 114, -228, 342, -1237, 1123, 1126, -188, -106, - 11308, -3787, 563, 3423, -9926, 1623, -2551, -1448, - -4125, 918, -1366, -476, -66, 4, 761, 164, - -61, 20445, 238, 296, 492, -1126, -98, -1201, - 14, -1840, -865, 1178, -869, 105, 907, 248, - 1538, 2990, 11691, 7783, 1566, -6704, 2397, 594, - -1825, -383, 4264, 1911, 468, 1018, -676, -2676, - -7756, -2623, 10705, 2710, -8078, -5256, 1699, -2100, - -355, -2086, 10828, 611, 18, -830, 978, -4181, - 1324, -5262, -327, 1796, -9777, 1306, -1934, -8930, - 9520, -2364, -3997, -10209, -6326, 1394, -1758, 868, - 1192, -2916, -23, -1586, -296, 438, -279, -14171, - -1554, -206, 2383, 506, 1181, 8298, -491, -2771, - -4286, -7116, -1680, 506, 1729, -12965, -925, -985, - 420, -1746, -267, -478, -11763, -1030, 187, -3878, - 1516, 2472, -371, 29, 809, -1700, -152, 560, - 1833, 14397, 968, -96, -3242, -2497, -76, 2096, - 9593, -1200, 446, 1505, 8058, 1722, 501, 923, - -1171, -9516, -2536, 7368, -2, -5304, -2440, -352, - 510, 320, 301, 120, 687, -942, 137, 824, - -316, 1312, 510, -1133, -27448, -404, 1041, 272 -}, - -.cb2224l1 = { --14840, -1361, 12733, 798, -496, 1691, -1668, -1730, - 928, -3233, 338, -578, 156, 784, -787, -242, - -618, -853, -1282, -11766, 3970, 12178, -2034, 244, - -3411, 300, 159, 3494, -3060, -1459, -2484, -10680, - 752, 227, -1612, -922, -549, 158, 2260, -7640, - -4479, -4075, -2412, -7707, 600, -12358, 93, -1666, - -795, -13060, 61, 511, -2102, -2122, 364, -157, - 2310, -1552, 1260, 158, 9503, 7050, 7, -5902, - -7098, 444, 3736, -1836, 3109, -2328, 457, -871, - -327, -780, 661, 8684, 2530, -268, 954, 1380, - -1029, 418, -136, -3515, 1953, -1688, -8623, -3292, - 7758, 2796, 11643, -931, -501, -873, -444, -1342, --13900, -246, -283, -1779, 998, -1318, 408, 1505, - -462, 10667, -1813, 78, -16514, 360, -2029, 942, - 1674, 171, 317, 244, 1183, 724, 760, 1634, - 863, 793, 126, -326, 980, -629, 22219, -649, - 1274, 717, 1355, -1853, -1792, -1017, -2104, -768, - -1708, 2302, 2353, 11167, 10734, -3412, -2266, 75, - -104, 425, -880, 2072, 2934, -930, 270, -2414, - -925, 1023, -746, -236, -1620, 825, 1324, -101, --19348, -1291, 585, 2165, 2891, 3662, -577, 1800, - 408, -1486, 107, 351, -319, 1104, 956, 403, - 628, -277, -57, 938, -32768, -71, -441, -208, - -32, 191, 314, -171, 613, 749, 844, -472, - -444, 952, 42, -8026, 2720, 1911, -2780, 12311, - -122, 3569, -91, 6048, -776, 1694, -63, -1272, - 3581, 1622, 2538, 190, -13108, -820, -3056, 1189, - -1428, -244, -752, -6187, -3473, -697, 1368, 1043, - 7702, 352, -140, -12999, -80, 12672, -1473, 3113, - 1505, 667, 2392, 1767, 537, 1949, 657, -130, - 980, 1743, 8269, 2380, -2311, 197, -651, 2531, - 553, -1117, -396, 472, 4565, -12672, 2322, -360, --12766, 2205, -2651, -10690, -218, 586, 5229, 34, - 59, 1730, 1226, 2106, 4008, -1878, -9520, -1366, - -1174, -290, -1037, 1642, 1234, 305, -1279, -642, - 1126, -13199, -29, 642, 2928, 1936, -260, 588, - 11690, 9282, -3362, 7732, 1073, 2738, 4688, -1507, - -1461, -2271, -1131, 1969, -2152, 1637, -774, 66, - -1190, -206, -491, -1080, 644, -378, 367, 17980, - -1583, 2162, 918, -121, -432, 115, 5, 791, - 1968, -2287, -1574, -9545, 11146, 3540, -4700, -515, - -4548, 881, 591, 1044, -259, -978, 2, 232, - 778, -198, -1161, -378, -83, 421, 282, 26564, - -801, -1628, -1983, -301, 931, 886, 2196, 1453, - 752, 2956, -3478, 490, -1420, 13303, 1293, -9466, - 462, -12829, 11130, 8061, 593, 3697, -611, -534, - -698, -1148, 1598, 293, -726, -698, 289, 180, - 876, -369, -43, 234, -21629, -1448, -753, -480, - 956, 994, 531, -916, 630, 720, -2300, -9544, - -1418, 993, 2130, -2359, 2460, -339, -277, 1577, - 12206, -3507, -1280, 1938, 871, -1850, -809, -3364, - 6918, 1134, 5010, 8772, 2103, -9775, -1404, 5148, - -1494, 1549, 1761, -812, 654, -611, 822, -229, - -384, 10466, -337, 2207, 131, 2818, -2925, -3374, - -8786, -8552, -2282, 88, -1058, 8571, 2900, -529, - -1569, 1882, -981, 204, 2955, -4227, 4196, -3041, - 10804, 1822, 82, 1936, 2380, 12992, -5659, -3449, - 1329, -1668, 1291, -1726, 8328, 314, 2737, -677, - 2384, -910, -878, 687, 640, -721, -912, -12772, - -2079, -398, -1788, -2516, -8711, -1038, -985, -7151, - -9057, 890, 459, -298, 918, -10061, 848, -716, - 1822, 836, -9516, -985, -1379, -409, -2237, 1036, - -1082, -1704, 1333, -1432, 11463, -2355, -5975, -1674, - -640, -554, 8352, 2732, -5251, 4243, -354, 3662, - -592, -9317, -1205, -1084, -995, 11288, -2098, -1620, - 2367, -1286, -5312, -64, 540, -2327, -2703, -2013, - -8649, -1306, -948, 1443, 664, 2400, 4706, 4061, - 387, -20, 1859, 9283, -18175, 806, -1401, 1253, - 596, 2176, -1682, 2209, 733, 1404, -6652, 2754, - 950, 2346, 3629, -6875, 5069, -9302, 1472, 942, - 1184, -10432, 960, 3987, 1985, 421, 300, -716, - 938, 500, -160, 226, -87, -1648, -1857, -1977, - -323, 2305, -13843, -4148, -2978, 5430, -3422, -1138, - -2146, 1548, -1430, 734, -339, 8598, -4568, -496, - 477, 4969, 2593, 2842, 8645, -2365, -7455, -2687, - 249, 7516, -53, 219, 1139, -668, 566, -522, - 1289, 33, -141, -920, 2526, -2797, 16456, -2000, - -758, -194, 10984, 187, 1686, -4799, 9671, 1838, - -1224, 1325, 656, -5434, 3207, 1813, 1833, 14375, - 12259, -95, -536, -1746, -3568, -442, 964, -1472, - 1345, 2692, -589, 520, 616, 357, 326, -1363, - 28603, 700, 473, -908, -1129, 1046, 1106, -471, - -472, -980, 29, 574, -350, -545, -585, -1936, - 279, 882, -880, -52, -30552, 371, -154, -1275, - -1914, 104, -110, 1122, -719, 729, -743, 360, - 766, 198, -11674, 612, -10602, 1157, 186, -3132, - 3070, 1535, 155, 774, -9432, 4966, -6717, 320, - 5167, 112, 2727, 11228, 1368, 1864, 1197, -1519, - 1504, 17863, 49, 2212, 611, -1788, 2932, 395, - 32, -566, 2425, -9457, 673, 670, -247, 1617, --12578, 1408, 462, -14935, 1438, -808, -1850, -784, - 1856, -1648, 767, -1452, -1652, -1621, 1016, 1428, --11203, 4217, -6410, 2570, -1016, -1720, -9036, -390, - 62, -1245, 3027, -255, 1646, 1358, -907, -864, - -118, 874, 268, 252, 104, -926, -552, -1206, - 965, -208, -24472, 890, -1516, -630, -885, -804, - -374, -22520, -1143, -777, 532, 185, 603, 1775, - -1887, 413, -458, -1036, -211, 2693, 6976, -9498, - 1437, 10163, 2450, -1574, 4941, 884, -470, -3366, - 4664, 420, -568, 5703, 10, -1692, 143, 1592, --10966, 2891, -2961, 3938, 1990, 1726, -5247, 3326, - -6575, 584, -277, -441, 1679, -520, 1339, 1077, --11462, -267, -351, 201, 10939, 4150, 3890, 1484, - 2615, -676, -448, 2316, -1278, 9734, -3039, 2841, - 964, -7557, 156, -7228, -120, 5533, -4322, 1796, - 2555, -9912, -3038, 2236, 1190, 222, -1684, 3273, - -1768, 6233, -6442, 8545, -49, -45, 2366, 293, - 308, -689, 308, 368, -452, 1125, 2326, -2335, --17793, 2027, -779, 734, -2032, 1246, -2898, 4174, - -74, -40, -3105, -2135, 996, -12714, 3614, 4936, - -1928, 1528, -4158, -1791, -2318, 907, -326, 22513, - -660, 1022, 434, -564, 28, -112, 252, 372, - -842, -2, 648, 2323, -614, 23377, -263, 486, - -408, -362, -821, -724, 972, 1248, 444, -1741, - -420, -1371, 1088, -565, 22, -394, -64, -292, - -103, -501, -30510, -294, -266, 433, -700, 742, - -756, -407, -961, -148, -1416, -1041, -481, 121, - 346, 10240, 12629, 1476, -2647, 1350, -2012, -262, - -5621, 714, 4398, -2732, -10473, 9834, -5165, -991, - -557, -2733, -3460, 5779, 659, 1472, 2029, -2339 -}, - -.cb2224s0 = { --27522, 2628, -2486, 277, 874, -2351, 2725, 915, - 994, -1209, -439, 2936, 46, 1014, -1816, -3561, --14386, 3113, -10400, -1025, 2114, 1328, -278, 1182, - -1820, 3928, -1062, -282, -1327, -1468, 5975, 2342, - -630, -4217, 10116, -1254, -2646, -5210, -9942, 1904, - 21, 504, 2325, 1443, 6470, 2598, 8130, 810, - 304, -1059, -645, 14634, -3198, 4277, -669, -7170, - 1554, -2321, 2386, -1072, 2483, -4141, 2841, 3414, - 8014, -3141, 10857, 6634, 3138, 3199, -320, 36, - -1366, -4129, 3157, 2602, 4273, -2435, 2645, 2986, - -3712, -3995, -5476, -4693, -1664, 6384, -11201, 1320, - 2184, -5102, -2984, -1569, -2116, -1513, 14284, -11182, - -2925, -731, -1321, -6363, 1483, 3463, 1292, -2065, - -357, 9108, 6371, 3840, -6905, -8918, 2906, -1658, - 757, 1998, -580, -708, 2198, 1867, 960, 4522, - 1896, -1674, -4943, 2695, -2465, -2078, 9755, -4853, - -2602, 3466, 3897, -3633, 4918, -2049, 3730, -1982, --10085, -3458, -1866, 32, -1706, 3648, -308, -942, - -1630, 1730, 512, 14612, 3415, 974, 3079, 765, - 897, -270, -1813, -1533, 1118, -2805, -2764, 1130, - -1798, 4594, -3134, 964, -20082, 2574, 32450, -1379, - 52, 358, -226, 1902, 257, -1071, -650, -399, - -381, 2073, 2310, 2164, 8221, 1433, -629, 1440, - 1120, -3362, -4642, 2000, 378, 1208, -2648, 4534, - 3307, 13200, 2780, 3100, -3194, -10606, -11563, -4491, - 2218, -4500, 622, 1313, 2682, 3003, -1387, -3886, - -1567, -4864, 10899, -20606, -1606, -60, 602, 125, - -730, -1112, 979, 325, -13, -185, 1241, -288, - -552, 6042, -7049, -7359, -1456, 493, 11204, -65, - -2170, -5248, 2248, -1046, 591, 2085, -2844, 244, - -3454, 581, 1315, 3043, 304, -620, 405, -19944, - 769, 1076, -1456, -694, 2560, -1046, 2514, 14552, - 1586, -7027, -4710, 1366, 1552, 4354, 3296, 462, - 600, 500, 3225, 5083, -792, 3199, -698, -3589, - -2596, -3350, 2758, -3019, 5664, -9387, 4716, -3125, - 3306, 6268, -592, -622, -4144, -6290, 4990, -748, - 1854, -1042, -2996, -4279, 338, -1864, -8639, -11208, - 932, -722, 1788, -1927, 450, 2191, 11828, -6400, - 5364, -2236, 3212, 8340, -3229, -2846, -4676, -1825, - 2628, -303, -589, 7728, -4216, -3866, -4400, -194, --11316, 5646, 3716, 4827, 232, -583, 308, -1833, - 2153, -2508, -46, 857, -9587, 2768, 5136, 1462, - 5142, 7990, -3424, 1067, 7462, 4944, 98, 1014, - -4750, 13824, 1130, 2334, 9393, 2416, -4519, 27, - 2000, 929, -204, 481, -2780, -3720, 1267, 269, - -5383, -1999, 1249, -4238, -9351, -7440, -5964, 6154, - -6827, 3112, -2613, -164, 1604, 1245, -50, 8619, - -4044, 4652, 2846, 8359, 5345, -2902, 2295, 4801, - -5016, -6270, 2893, 2732, -3510, -2613, 4548, -6376, - 4510, 10566, 1859, 1038, -8381, 2782, -1622, 159, - -1035, -3232, -3766, 1580, -720, -4476, -3863, -920, - -2135, -458, 352, -2645, 3029, 301, -1145, -478, - 3696, -11700, 9930, 6649, 7290, 2362, 17226, 3238, - 1786, 662, 971, -736, -647, 1745, -506, -777, - 1458, 2406, -1417, -7933, -846, -2654, 1104, 618, - -2783, -10168, -3322, 9498, -939, -2342, -1876, -1914, - 84, 3468, -6533, 7796, -3797, -1318, -2183, 1310, - -895, 4943, 1062, -4468, 142, -244, 884, 613, --13963, -5853, -947, 18703, -964, 1090, 1070, 1388, - -1572, -1110, 671, 1706, 620, -262, -2421, -2277, - -5665, -5212, 4994, 2379, -593, 2048, 14489, 1165, - -1775, -2093, 2466, 419, 404, 5429, 3089, -1350, - 1975, 2281, 60, 599, -1600, 2286, 2358, 6698, --16423, 3760, 666, -1309, -1346, 2786, 2364, 1448, - 1114, 17956, -5301, 2430, 1178, -164, 2195, 3927, - -122, -737, 1468, 307, -1863, 1592, -7714, -2428, - 958, 220, 59, 4124, -1945, 11151, 8604, -2077, - -4787, -4578, 1096, 2685, 6478, 8314, -6221, -3842, - 2173, -43, 104, -2510, 3109, -2324, -4238, -4709, - -3233, 3228, 11454, 2428, 578, 780, -1096, 72, --22624, -1421, -4104, 226, 464, -1726, -1971, 2068, - 1142, 1412, 1412, 798, -2605, -3451, -1104, -2224, - -2250, -3470, -572, -1420, -1292, -58, -217, -21417, - -172, -6368, 30, -2170, 95, 378, -2926, -2180, - 2820, -683, 2018, -4313, -13469, 5396, 1808, -592, - 4732, -6602, -5602, -983, -4130, -477, -1236, -2263, - 3992, -12962, -1778, -2631, -2421, -746, 1964, 1754, - -760, 2753, -116, -3860, 10246, -448, -1318, -100, --10372, 1420, -210, 2768, 48, -2373, 7721, -3217, - -328, 1543, -2527, 3709, 4024, -916, -4588, -726, - -4302, -982, -14714, 3615, -1190, 9051, 199, 2252, - 1348, -4204, 693, 1241, -14160, -2460, -2017, 2997, - 766, -360, -450, -2919, -7976, 3210, -179, 8935, - 670, 1155, 6888, -2249, 2729, 1810, 6283, 684, - -9717, -1763, -921, -4578, 3941, -6408, 1431, -2742, - -91, -2094, -2118, -9752, 2801, -2497, 147, -5901, - -5270, 13170, 2810, 1576, -3191, 10253, 4226, -1340, - 2456, 1079, 12541, -5124, -8356, -1000, -558, 180, - -2070, -1880, -5718, -687, 10549, 1066, 220, -4147, - -695, 3648, -3460, -3143, -1623, 2150, -11222, -2566, - -6395, 3552, -4176, -698, 1248, 112, -4628, -960, - -724, 1191, 2084, 15207, -346, 371, 190, 5345, - -4283, -7482, 1354, -4424, -3775, -4143, 1444, -14876, - -589, 2498, 1305, -486, 1628, -867, 1584, 1094, - -10, -1260, -1046, 2528, 27472, 910, -1069, 829, - -117, -1097, 770, 252, -1412, 2353, 2200, -11, - 624, 8459, 6320, -9465, 1225, 2532, 5415, 9252, - -1441, -1378, 1081, -1997, -3904, -14740, -5220, 3627, - 5725, 6180, -5336, 72, 4638, 915, -496, 628, - 1880, -420, 2800, -7143, -7578, 3180, -4210, -1111, - 2979, -442, -182, 2778, 2398, -13878, 2209, -282, - -888, 180, 3584, -1005, 2, 999, -3074, 1205, - -4605, 5250, 17255, 2839, 2718, -678, -2651, 160, - 1596, 4685, 2324, 3100, 3744, -1954, -11674, 621, - -678, -6242, -3449, -1890, 3134, -289, -7162, 2268, - -8437, -624, 4999, -5946, 13013, 244, -200, -1494, - -1108, 3768, 445, 2429, -1264, 786, -2993, 3482, - 2448, -968, -1184, 213, -772, 4931, 42, -3850, - 2020, -17970, 84, 3016, -602, 1805, 731, 3522, - -2606, -637, 25535, 680, 1083, 4138, 1602, 190, - -1854, -962, -379, -2499, 2453, -362, -4552, 4689, - 2168, -5930, -10552, -5585, -4694, 2447, 2047, 5420, - 3908, -1449, -90, -68, 496, -12713, -2127, 1406, --10766, 2438, 2278, 2962, -6411, -22, -1966, 2814, - -1746, -383, -2381, -5981, 10920, -12354, -656, 2260, - 5200, -1908, -2275, 4276, 1174, -932, -532, 2832, - 601, 1551, -8434, -4170, -6411, 9099, -6886, 2243, - 561, 2026, -3598, -1125, 646, -5188, 6017, -632, - 772, -2919, -3776, -9938, 2461, -122, 128, -1416, - -1533, 343, 1318, -13738, -1528, -6418, -1196, 832 -}, - -.cb2224s1 = { - 32767, -749, -1885, -806, 739, -1858, 3902, 1029, - 332, -2122, 1240, 2705, 1362, 190, 1058, -1404, - 1224, 1122, 1208, 190, 1984, -1355, 1694, -21000, - -1012, 2418, -1269, -1154, 1113, 2291, -2317, 315, - 12872, -2296, -1510, 1104, 11324, -1146, -1018, 1326, - -902, 168, 647, -1828, -3838, -5682, 2732, -238, - -134, 13450, 1570, 2424, 996, -3494, -3720, 4897, - 5875, 149, -6367, 6659, -2329, 6916, 1134, 425, --19014, -479, -1900, 3470, -1777, -811, 1723, -46, - -2103, -1298, 2929, -4279, -639, -2443, 7231, -1187, - -2145, -777, -3287, 4895, 8878, -9318, 289, 4015, - -3148, -598, 2226, 11700, 114, 3237, 9586, -4570, - 2592, 3614, -2272, -2829, -3356, -1095, -5290, 4709, - -1867, -1930, -20722, 937, 892, 1415, 1544, 2950, - 5090, 937, -1411, 123, -31, -1568, 338, -938, - 5465, 5796, 480, -2782, 3351, -2489, -383, 1529, - -5686, 2446, -693, -12796, -599, 1894, -1576, -2244, - -4686, 10165, -1085, 10050, 2681, 1138, 2544, -1809, - -806, 5278, -8730, -3740, -2343, 971, -3254, -165, - -212, -4164, 850, 233, -13694, 442, 1073, 3854, --12926, -2001, 3468, -765, 829, 2174, 1531, -6036, --10848, -11009, 803, 1713, 2884, 1992, 75, -2989, - 268, 346, 1998, 4798, 8976, -4632, 1863, -4127, - -612, 4790, 10946, -1296, 8009, -1351, 356, -1711, - 313, 2301, 1318, 8050, 700, 1218, 2270, -2156, - 67, 1537, 1941, 3442, 13321, 691, 2344, 2594, - 1551, 3853, 7279, -10441, 1006, -11862, 5532, -611, - -582, 2257, -2873, 3993, -5133, -2264, -2478, 1576, - 1834, -4931, 10264, -1429, -10404, 393, -3715, -1470, - -2003, 384, 4869, -6780, -1297, 1572, 1043, 6980, - -4382, -3005, 3698, 4176, -1348, -4972, 1574, 9815, - -5995, -979, 3609, 3702, -8503, 668, 3354, 2552, - 9183, -1175, 1224, -2859, 11176, 6088, -1355, 84, - 1271, -380, 5336, 299, -690, -365, -8047, -3679, - -3204, 1334, -13451, -1392, 2200, -3646, -1046, -4292, - 741, -1701, 1722, 2061, -1358, 7266, -6356, 963, - 2190, -1349, -1882, -14128, -4662, 3552, 565, -1109, - 5413, 1239, -2618, 794, -2064, 11805, 9004, -2134, - 2804, 946, 80, -2387, -1205, 11, 1642, -1825, - -2324, -5018, 4208, 5285, 661, 12430, 1907, 784, - 10864, 340, 18, -138, 2885, -2247, 17, 334, - -3172, 2977, 970, 536, -1540, -516, -488, -512, - -1334, -1930, -2418, 1078, 24837, 12, 2060, -252, - -2536, -2206, -3179, -6785, -8842, 8736, 1393, 119, - 1652, 10126, 856, 855, -742, -289, -2208, 3831, - 6909, -6556, 2472, -245, -1729, 1460, -3014, 59, - -58, 132, 3903, -3762, -1419, 13273, 2708, -7752, - 84, 3525, -1305, -334, -13421, 5931, -4845, -2697, - 666, 558, -1102, 632, -2946, 4153, -4018, 4516, - 4875, 4460, -1567, 2233, 386, -754, 1256, 2145, - -1692, -13046, 1581, -518, 4397, 1215, -723, 3413, - -640, -5088, 1711, -714, 2536, 2433, -691, 10758, - -8764, 5541, -2071, -1662, 12955, 12998, 1252, -94, - 802, 2573, -2557, -66, -832, 106, -728, 1050, - -811, -2684, 629, -16524, 1531, -1617, 1348, 204, - 1722, 368, 554, -1752, 114, 1349, 1952, -1007, - 2626, 2035, 8148, -2539, -4296, -4460, -8542, -3089, - -1543, -857, -2617, -1765, 6642, 2167, -1531, -6881, - 86, -414, -5896, -5152, 17445, 1129, -5006, 2936, - -3432, -2226, 1176, 972, 1170, 530, 3390, 260, - -2909, -3550, -5255, 1771, -382, -1690, 17070, 2688, - 566, 2430, -1768, 3373, 1460, -3464, -629, 3119, - 430, -3554, 8357, 7075, 293, 2955, -61, -6919, - -4939, 3678, -6852, 652, 2206, 5918, -2768, -3022, - 5721, -770, -1102, -1057, -2760, 3086, 5611, -160, - 2714, -1042, 2569, -14248, 3846, 8212, 5392, 144, --11896, 618, 1212, 3283, -3777, -715, -3870, 2528, - -2900, 1645, -1786, -1852, 2776, -1348, -586, 234, - -4, -1666, 46, 2095, -1987, -18728, -2980, 2501, - 4042, 79, -1849, -2013, 8047, -1898, -108, 340, - -4760, 2134, 9000, 347, 10365, 4779, 6660, 1694, - -3253, -2282, -1488, 10406, -8054, -3414, -2934, -1611, - 3172, -2195, 4973, 1249, 2888, -4054, -5738, -2995, - -2282, 1977, -353, -516, 5322, 3225, -4907, 1303, - -4656, 9947, -236, 9382, 2332, 2076, 1470, 3173, - 4712, 2645, 559, 4904, 1511, -1715, -4856, 5750, - -1276, -306, -5980, 14393, 1443, 85, 156, 7718, - 793, 4199, 2122, 1098, 128, -1996, -1397, -20, - -534, -13296, -1518, -2970, -1001, -6474, -6146, 8337, - 5476, 3058, -526, -1295, 1623, -8791, 1257, 2006, - -5725, 3035, -2917, 1280, -8479, 5934, 9870, -13131, - 14, 1088, -9, 1969, 366, -3214, 192, 2764, - 1499, 346, -2031, -2900, -2529, 1072, 11717, 5206, - -44, -2514, -8900, 2892, 2132, 3635, 3735, 2726, - 1398, 6035, -2830, -4568, 424, -8696, 1368, -3860, - 1823, -2620, 4546, -2210, 1660, -1672, -10524, -484, - 950, 11, -4494, -6220, -5653, -13332, 2868, 460, - -4120, -4030, -3277, 522, -3403, 1126, -170, -1892, - -4366, 1304, 3477, -1507, 1111, -594, 1670, -8416, - -1690, 2492, -7109, 2531, 4131, -8123, -4884, 16505, - -240, -63, 32099, 974, -1360, -2395, -2005, -1156, - -877, -416, -922, 1857, 766, 71, 1380, -259, - -272, -1924, 2498, -3290, -16045, -2064, 2966, 2936, - -1265, 2121, 488, 3781, 1484, -1193, 4776, -1001, - -669, 1569, -379, -604, -5, -1943, 757, 359, - -560, 118, 17941, 2323, 215, 7621, -3582, -8130, - -698, 9893, -2752, -417, -1262, -1504, 3319, 1186, - -2192, 3014, 781, -3602, -6190, -7725, 3169, 2038, - 1175, 612, 2477, -4136, -12152, 4538, 567, -116, - -3222, -470, -118, -9257, -635, 3078, -11596, 93, - -4178, 4150, 5985, 4414, -2110, 542, -1125, -1242, - -234, 807, -1385, -2448, 824, 109, -1826, 3032, - 269, 14188, 3468, 908, -12, 2290, 5758, 1685, - 680, 5963, -2763, -173, -34, 3135, 1230, 2226, - 2471, -9546, 2266, -1583, 729, 3506, -10664, -652, - 2212, -620, 2762, -751, -6337, -4339, 4131, -1234, - 5423, -2279, -2884, -929, -12582, 416, 2046, -3854, - 11130, -2738, -670, -202, 6216, -7266, 9726, 1308, - -1761, 4696, -1061, -144, 482, -1586, 4377, -5016, - -3894, 2296, 4340, -555, -3003, -2117, -962, 100, - 4548, -1870, -13885, 1351, -3226, -8114, 377, -391, - -1344, -2148, 4756, -3518, -14429, -670, -238, 400, - 1234, 4389, 1181, 1046, 425, -32, 840, -29846, - 1580, -992, 1844, 1961, -1305, 1055, 418, 52, - -641, 2430, -1773, -5323, 3341, -5367, 14027, 3051, - 3864, 404, 4186, -1875, -5822, -4321, 112, 395, - -177, 1080, -3008, 520, 8, 226, 1430, -1635, - 8, -2632, -3249, -3595, 622, 564, 8404, 14463, - 160, -7828, -4113, -16547, 848, 6320, 2311, 4074, - -2050, 668, 1463, -2322, 1790, 864, 317, -594 -}, - -.cb2224m0 = { --17338, 5737, -912, 5906, -5315, 920, 2743, -2232, - 1943, -753, 1696, -1818, -2272, -564, -1306, -527, - -156, 9952, 36, 2524, 2053, 1841, -1670, 10622, - 2532, -5616, -324, -1132, -1148, 1920, 10232, -75, - -630, -10796, 1618, 1104, -2557, -603, 2115, 966, - -3763, -3183, -851, 4502, -1565, 10062, 313, -709, - 10707, 867, 3820, -2747, 3470, -1942, -486, 4092, - -6289, -2363, 556, 3190, 5046, -1869, 2886, 10572, - -948, -4191, 1544, -1727, 721, -3153, -712, 934, - 1610, 1070, 1248, 10645, 2340, -11102, -2744, -353, - -65, -4973, -1782, -1037, 1210, 1192, 1138, 1106, - 9422, 652, -9595, -1663, 460, 9107, -2827, 775, - 1131, 4732, 93, 476, 387, 32767, -161, 266, - -406, 604, 675, 83, -589, -639, 220, -830, - 2200, -142, -2000, -128, 902, 823, 287, 717, - 1857, -1626, 208, 2784, -72, -19310, 6190, -2063, - -9101, 3419, 1721, -2092, 332, -6533, -7594, 1138, - 807, -2582, -668, 410, -497, 1526, 96, 944, - 3319, 1294, -335, 1964, -380, -618, 3069, 101, - 18964, -2298, -10304, -1190, -998, -1384, -11466, -256, - -4475, 4027, -3532, 1828, -1311, -3417, -3925, -221, - 27688, 2277, -1227, 1043, -399, -3327, 515, 1665, - -616, 2724, -546, 4608, -576, -103, -9064, -1281, - -563, -3588, 2174, -824, 3379, -2360, 354, 844, - -7044, -2295, -2613, -11152, 1006, -1064, -17007, 1180, - 387, -8448, 836, -578, 2621, -356, -1476, 2362, - 822, 4547, 118, -11628, 352, 367, -958, -12423, - -65, -1591, -2304, -2880, 1684, 1708, -1693, -781, - -71, 10012, -534, -3672, 417, -2048, -1955, 10491, - -1257, 861, -414, -4058, 3042, 1529, -5823, 6877, - -3918, 993, 221, 2576, -7780, 170, -648, -139, - -3410, 7974, -756, 2657, -596, 12527, -199, 13752, - 2198, -938, -2265, 1736, 257, 1517, -676, -1165, - -2874, -2433, 123, -829, 2605, -10270, -3158, 3624, - 2072, 6960, 1490, 4634, 455, -8175, 1139, -4545, - -1491, 3727, -8738, -1951, 593, 14, 2897, 2490, - -2273, -1436, -10992, 3005, -4392, -3434, -4561, -1014, - -9506, -1609, -1248, -1593, -190, -10472, 3264, -2274, - 5097, -633, 473, 427, 725, 1577, 11032, 318, --12228, 78, -1116, 441, 1930, 4041, -648, -4324, - -224, 2738, 8826, -40, 327, 1761, 2371, 171, - 4039, -3411, -2495, 1150, -12181, -1704, 35, 528, - 417, 626, 1866, -472, 466, 905, -854, -875, - 1194, 24371, 488, 26, 695, 1777, 798, -169, - -16, -1252, 395, 871, 1170, -635, -1637, 2094, - -5427, -16393, -384, 3872, 33, -687, -1777, -4160, - 3020, -1906, 3868, 699, -400, 6755, -3253, 12699, - 1474, 7312, 991, -646, 26770, 2524, 2144, -500, - 1096, -1869, 1036, -1707, 521, -2091, 1445, 2335, - 107, 238, -227, -120, -32768, 591, -257, 867, - -1231, 650, -465, 356, 431, 762, -516, -594, - 512, 242, 2298, 1012, -1538, -11748, 3551, -5608, - -2174, -2428, 10557, 625, 1002, 27865, -589, -1527, - -1552, 156, 1905, 1041, -4190, 2300, 1603, -980, - -1764, 484, 1555, -2664, 381, 11676, -8848, -3060, - 675, -646, 736, -1279, -1261, -1988, 543, -1880, - 1917, -2165, 2846, 11863, 2076, 10381, -307, 4354, - 73, -2788, -2464, 964, -218, 1552, 1846, 1470, - 577, -594, 725, 30798, 43, 13, -1474, 260, - 1218, 1433, -114, 1020, -648, -678, -1879, -65, - 791, 366, 8547, 931, 1091, 1018, 16312, -1116, - -777, -1098, 404, 180, -899, -2865, -10089, -751, - 40, -2358, -2980, 3574, 7905, -190, 9207, -18, --18766, -270, -5300, -2023, 2422, -1189, 1267, -1085, - -704, 6823, 2164, 2, 125, -2319, 411, 591, - -488, -566, -3394, 304, -12375, -268, 11098, -150, - -2392, -1255, 3172, 162, 1295, 5897, 7944, 6019, - 3329, -2014, 2957, -4933, 4805, 2780, -5453, 2680, - 3220, 2784, -549, -19908, -1222, 550, -3540, 1822, - 4082, 2399, -6844, 2145, 938, -597, 122, -20, --14986, -1620, 1575, 561, 408, -6305, 760, 1634, - 2652, -8301, -2988, 1864, 2524, 3228, 7466, -2620, - 410, 1364, 1740, 2204, 1999, 1704, -2601, -351, - -104, 10688, -7166, 134, -346, 11852, -13322, -3171, - -1230, 1109, -2336, -962, -563, 1030, 2832, -969, - -1997, 3233, -414, -8246, -2074, 2737, 3557, 1625, - 1036, 845, 1848, 1710, -10388, -4586, 6915, 2734, - -8693, -667, 1568, 1758, 2396, -3262, -2497, -1472, --11848, -689, 3379, 1692, 1449, 2844, 8524, -15598, - 337, 590, 3303, -1594, -2548, 4529, 433, -1921, - 920, 1061, -1693, 191, 44, 957, -2397, -1126, - 41, 2164, -1587, 568, -17290, 4687, -1028, -403, - 1169, -1282, -1602, 242, -1234, 1870, 1067, 2444, - 1752, -2552, 8775, 1384, 5683, -4770, -12436, -680, --13344, -196, -276, -299, 734, 12378, 2364, 327, - -1494, 560, -90, 3394, 496, 2357, 629, -17, - 1040, -706, 589, 294, -1135, 25012, 444, 1206, - -298, 1424, 1524, -2188, -64, -1101, -1998, 374, - 1377, -1382, -11349, 1456, -171, -2369, 6966, -2808, - -8987, 3390, -811, 671, 3032, -3396, -9815, 2246, - 4418, -678, 1851, -1592, -11038, -1194, -3612, 2589, - -250, -495, 1203, 1348, -805, 1853, -345, -555, - -8755, -9695, -3768, -1506, -8172, -322, -7163, -6319, - 2052, 116, -4459, -2328, 4857, -2569, 1419, 959, - 1138, 7034, 4836, 3449, 6826, 13411, -893, 981, - -2060, -3710, 3177, -761, -1128, 4386, -127, 6698, - 3426, -2922, -61, 408, 1426, -1238, 15468, 94, - 373, 3597, -2432, -1989, -859, -8976, 2938, -777, - 409, -206, -7758, 3384, 295, -466, 29, 7925, - 2048, 930, 2296, -10030, 330, 7864, -1004, -385, - 2130, 388, 3587, -4480, 1560, -12768, -2606, 8178, - 771, -3519, -1590, -592, 2192, -1126, -77, -3947, - 1868, -1304, 11107, 781, 6240, 4134, -3314, 407, - -6125, 5168, -503, 2155, -990, 143, 219, -9950, - -1186, -1446, 1930, -8963, -4084, -6141, -976, 153, --13665, 564, 13631, 138, -269, 379, 1333, -1710, - -940, -511, 1214, -2190, 1347, -1397, -1321, 94, - -1802, 6627, 1306, -12347, 2780, -1091, -4362, 5047, - -446, -3472, 6064, 1075, 478, 769, 58, 802, - 562, -1581, 28580, 194, 1338, 573, -555, 617, - -409, -1249, -8, 1133, 952, -120, 2502, 5313, - 969, -1664, 1769, -12199, 5551, -402, 4862, 3270 -}, - -.cb2224m1 = { - 32767, -54, 1385, -206, 19, 522, -1176, -667, - -260, -1388, -1751, -2234, 228, -343, -893, -898, - -1004, 2517, -232, 20996, 507, -1857, 2574, 840, - -615, -1922, 660, 844, 52, 1272, 609, -692, - 21805, 938, 678, -399, -22, -1839, -996, 1560, - 218, 3973, -6547, -1151, -3914, -789, 938, -11509, - -2282, -606, -327, 3088, 797, -1540, -7598, 1378, - -100, 2108, -1907, -11671, 1538, 11136, 310, -2096, - -3037, 3181, 1731, 2043, 3424, -1098, 2046, 545, - -1778, 605, 932, 832, -2356, -1498, 1129, 11542, - 119, -10994, -3720, 4316, 346, -9141, 3921, -918, - -5476, 372, -318, 9254, -681, 4896, 1587, 1620, - 1850, 4057, -1507, -362, -1074, -328, -1502, -3092, - 2735, -378, -11572, -1292, -2575, -3397, -7566, -8977, - 1670, 8659, -655, 884, 1815, -9348, 570, 394, - 1670, 1942, -195, 386, 553, 8885, -9206, -624, - -2312, 15852, 782, 562, -1497, 720, 1804, 1415, - -3809, 3783, -1918, -3496, -637, 581, 1161, 961, - -960, -930, -1673, 904, 11510, -2286, -9964, 2964, - -5752, 2229, 786, -1479, -18882, 1517, 128, 3282, - 157, -2178, -564, -6029, 766, -4599, 3620, -4380, --20114, -677, 2134, -93, 1486, 648, -4790, 1862, - -1476, -56, -3443, -2622, -2806, -1185, 122, 1801, - -1547, 12241, -2785, 2386, 56, -4075, -10964, -832, - -4744, -1350, 2849, -255, -1375, 163, 1306, 37, - 2304, -1396, -11234, 9712, 1732, -2262, 3632, -431, - -579, -4045, 806, -12168, -1309, 840, -1474, 918, - -1240, -1601, 48, -4137, 6934, 3968, 7370, 4088, - 8648, 2351, 1466, 615, -12314, -2347, 4382, 862, - -4288, -3138, 1886, -4357, 375, 1949, 73, 287, - 135, -60, -1498, -2427, 1263, 3322, -582, 17508, - -1202, 1558, 3351, 484, -439, -571, -370, 11952, - 11656, -1407, -1410, -2976, -459, 397, 1980, -1374, - 1237, 5044, -2074, 405, -10650, -174, -12556, -1962, - 4569, -1293, -200, 3106, 343, 748, 1918, 1084, - -670, 3, -1070, -397, 3965, 9966, -609, 9691, - -900, 137, 2305, -5944, -944, -1500, 638, -703, - -582, 10098, -523, 776, 1266, 4860, 6213, 1181, - -5634, 518, 9116, -4740, 10683, -547, -1295, -91, - 104, -3115, -1724, -17, 1953, -745, 694, -474, - 12248, -596, -674, 765, 674, 4494, 1205, 5883, - -1638, -3996, -664, 8694, -5620, 3968, -717, -10425, - -285, -12605, 368, -3904, 12363, -1288, 1242, -1497, - -3117, 2396, -220, 1700, -2788, 250, 107, -150, - 345, 681, -44, -2466, -389, 2098, 312, 54, - 2734, -22225, -1232, -1778, 1063, -1586, -6658, 344, - -2889, -4348, -3685, -2100, 12, -1755, -6401, -149, - 8150, -10689, -748, 1443, -32768, 1698, 1461, 216, - 1373, -2814, 1014, 1135, -227, -1309, -616, 1566, - 395, -724, 852, 1579, -9647, -1214, 728, 329, - 9244, 179, 7204, -836, -3954, 168, -5722, 152, - -2886, 472, -651, 5114, 8734, -71, 11406, 1098, - -1452, 1190, 598, -880, 14611, 12540, -1523, 1340, - 1015, 1510, -208, 206, 1314, -1532, -246, -3210, - -1637, -197, 197, -32768, 1448, -191, -1720, -217, - 1021, 973, -2099, 56, 606, 39, -1569, -1205, - -2375, -2156, 4798, 2504, -11914, 933, -6015, 2657, - -2911, -5173, -1964, 1576, 5268, 1190, 675, 856, - -1718, -4332, 166, 1556, 19005, 2040, 1198, -2170, - 1824, -3409, 121, 830, -252, -525, 289, -1701, - 292, 854, -1150, -1108, 171, 511, 22114, 662, - -1263, -540, -2306, -2332, 869, -5191, 186, 536, - 410, -7576, 590, 13625, 3519, 3858, -2787, -376, - -6506, 891, 5025, -2054, 8316, -2115, 7668, -5808, - -2464, -2422, 1541, -3851, 1578, 420, -617, -6507, - -858, 160, 3876, -2830, -5970, -3295, 9829, 1099, - 1617, 3502, -3124, -4116, 138, 287, 914, -548, - 1056, -1546, 1218, -227, 11632, -574, -996, -9894, - 808, -5868, -1457, 8374, -2086, -280, 1038, 528, - 1862, 284, 3926, -144, 7168, 1224, 11628, -221, - 1018, 1683, 922, 561, 6910, 1895, 3044, 12613, - -74, -1424, 1654, 8872, 2255, -990, -2039, 269, - 9558, 10122, 958, 466, -1948, -1242, 1042, 886, - -1143, -3444, -8720, 1918, -300, 19074, -1629, 991, - 908, -896, 1207, 3602, -4802, -2912, 4100, 2936, - -1344, 459, -6904, -714, 524, 171, -1430, 1454, - -2725, 1130, -757, 2861, -11174, -2768, 5466, 3662, - 110, -1999, 12376, -2173, -2508, -2838, -2025, -4378, - 134, -9856, 1738, 1027, 1428, 38, -1560, 12824, - 13932, 549, 586, 720, 923, -1040, -2827, -3272, - 1902, -2113, 2624, 3296, -34, 12291, 1449, -12138, - -796, 186, 2777, -1007, 3276, -587, -1917, -130, - 2120, -564, -364, 1005, -615, 1504, -2412, 9219, --11412, -2490, 1262, -2720, 1608, -3276, 1294, 1882, - -188, 7090, 6029, -4207, -2739, 72, -10035, -1672, - 1509, -124, -1649, 420, -3623, -1069, -11225, -754, - -388, 790, -3209, -330, -2632, -11920, 3178, -1788, - 2585, 4146, 1944, -2757, -10616, 220, -14136, 2158, - -274, 2010, -362, 1107, -348, -1990, 96, -985, - 1599, 1566, 1393, 304, -1380, -924, -285, 620, - -30, -902, 26210, 1485, 1042, -1160, 352, -177, - 1245, 1879, -18, 727, -421, 223, -1298, 1066, - 962, 1306, 3866, 870, -18780, -3873, 107, -1408, - -1261, 808, -818, 1738, 1439, -2156, -1499, -2108, - -4626, 4039, -964, 16682, -1169, 266, 9373, 1238, - -2728, 2381, 12159, 2155, -472, -2293, -513, 3808, - -690, -2190, -1139, -6, 1379, -22803, 1380, -612, - 308, 1394, -902, -1454, -2620, -1080, -2864, -3301, - 108, 218, 8718, -617, -1098, 1436, -2005, -3966, - -2658, 6152, -874, -4636, 8705, -3382, -12072, 418, - -1837, -12582, 270, -788, -1174, 2156, 461, -297, - 478, -632, -356, 5796, -12024, 416, 2602, 3544, - -1240, -970, 4874, 7221, 704, 8940, 2316, 1174, - 2537, 5380, -5, -1818, 3020, -4120, 7042, -9618, - -1622, 3576, 2455, -298, 451, -5298, 7371, -1570, --12956, 9758, -216, 889, 5395, -2779, -4036, 1736, - -1871, -2036, -1119, 1847, 912, 2292, 850, 220, - 1300, 2228, 399, -2885, -2696, 2399, 3179, 6266, - 1629, 13091, -232, -5322, 1397, -724, 1666, -2012, - 3643, 1400, -2724, -18007, -506, -103, 1318, 2473, - 965, -587, 1135, -904, -510, -10767, 1937, -585, - -73, -1662, 3021, 340, -12475, -1618, -1, -1914 -}, - -.cb2232l0 = { - -9947, -673, 522, -36, 396, -433, 949, -442, --12495, -2186, 4280, -997, -1715, -7385, -379, 3498, - -572, -9897, 6686, -4736, 577, 1866, 659, -123, - -1682, 420, -866, 4458, 5821, 3155, 7929, -5562, - -1798, 3086, 8556, -65, -8943, 2354, -4187, -3798, - 627, -1859, -9760, -1811, -1724, -45, -1838, 1638, - 499, 148, -335, 20916, -264, -556, -269, -1014, - -1531, 711, -519, 462, -5117, 3944, -950, 8277, - 878, -4803, -5003, -4402, -4722, 2988, -144, -6887, - 10661, -909, 700, -2287, 12126, -101, -761, 1836, - 827, -609, 538, 442, -4504, 1812, 3818, 7359, - 96, -555, 1598, 10040, -554, 924, 3426, -1786, - 2620, -2132, 867, -519, -2299, -672, -508, 201, - -2457, 10872, -5003, 5422, -8890, -104, 2579, 940, - 401, 871, 11167, 1216, 1054, -2876, -1523, -3950, - -1229, -3410, -428, 3648, -9389, -3025, -1752, 7583, - 3953, 1938, 3899, 1435, 8170, 1019, -2320, 1299, - -1152, 226, 394, 11328, -1471, 604, -184, 567, - -3704, -5723, -5938, 423, 9362, 4546, -3318, -3395, - 5084, -4341, -1781, -2619, 1078, -365, 151, -413, --21591, -968, -202, -183, 849, -481, 407, -11, - -2708, 2472, 2689, -9232, -9482, -1776, 645, -1510, - -1410, -6115, -114, -2550, 1922, 1668, 288, -1302, - 948, 1967, 52, 2393, -1975, 374, 17358, -1332, - 5303, 3195, -2674, 4784, -1418, -1359, -57, -2126, - 4618, 8890, 6455, 1181, 76, 374, 9585, 8762, - 672, -642, 666, -6485, 1751, 3255, -934, 6196, - 892, 171, -102, -44, -326, 1330, -320, -480, - -842, -22376, -561, -141, 635, -6528, 5711, 2400, - 838, 2846, -3212, -5341, -5479, 4961, 2110, -7480, - -4215, 7964, -1308, 1219, 1541, -4418, 6293, -4522, - -4887, -5760, 2790, 1441, 6135, -1133, -1627, 1235, - 914, 572, -1043, -1473, -519, -4618, -1228, -12212, - 1101, -10794, -4292, -4355, 6431, -588, -992, 612, - -1771, 6751, 4871, 581, 620, -352, 277, 727, - 2226, 8552, -43, 2295, 9409, 1122, 7618, 1885, - 1192, -1432, -1103, 8666, -2078, -403, -1787, 1572, - -2200, -7705, -6743, -1277, -1228, 955, 7613, -1536, - 8530, 5703, 5446, 4251, -853, 4910, 1578, 2832, - 1274, -2610, 243, 2820, 951, 9240, 1617, 605, - -6755, -2728, -5658, 3866, -157, 1215, -8470, -2038, - -189, 10411, 7444, -376, 407, -1128, 770, -410, - 503, 1707, 786, -529, 82, -27, 21512, -282, - 81, -1129, -686, -555, 2674, -99, 1284, 2216, - 1238, 404, -3398, 1010, 3966, -1134, -2682, 14222, - -1581, 9779, -1114, 848, 1905, 2129, -3937, -4742, - 1229, 8051, -4344, 3914, 4273, -659, 159, -1188, - -1844, 912, -1256, -478, -16158, -2869, 959, -2096, - -2166, 2360, 7861, -2718, -6358, 7653, 6639, -3239, - -1690, -1242, 3439, 1254, -954, 604, 17512, -288, - 2412, 211, -298, 2656, -5217, -1770, 892, 1979, - -1482, 3498, -40, 10424, -1038, -1862, 9905, 298, - 77, 2179, -4444, 2580, -2069, -6473, 61, 84, - 1035, -645, -662, -824, -743, -104, -1962, -124, - 4976, -5378, -1254, -7055, -3474, -10695, -1254, 2547, - -694, 3194, -82, -2634, 230, 358, -12, 1594, - -90, 598, -76, -21136, -1278, 846, -84, 259, - -2536, -4442, 2337, -1606, -3264, -3126, -591, -1295, - -2440, -2592, 10888, 5821, -862, -5070, 10402, -10633, - 159, -2660, 894, -2112, -1774, 3732, -1020, 422, - 9487, 1608, -992, 2046, 275, -10676, 2606, -999, - 477, -1868, -1690, 4764, -6419, -7550, 8159, 529, - 2308, -394, -2394, 2826, 6680, 496, 3628, -646, - 3186, -657, -2260, -1416, -9202, 496, 6624, 2441, - 1554, -2195, -8458, -3459, 466, 6706, 1056, -8777, - 5436, -4000, -3130, 4794, -6127, 2008, 1602, 195, - 558, -1362, -880, -2662, 9726, -9793, 2989, -3182, - -2378, -1338, 1086, -4682, 372, -399, 11129, -601, - -666, 5206, -1106, 362, 3155, 328, -9862, 719, - 1602, 998, -2342, 857, 1510, 476, 7256, 4652, - -5750, -4991, 4611, 8718, -4434, -4119, -351, -1606, - -1033, -3717, 3585, 9381, -1594, 5052, -7414, -205, - 2356, -5949, -8738, 1526, -1838, 4760, -5444, 623, - 112, -2863, 5710, 4920, 9497, 3759, 10748, -201, - 716, 747, -2559, -4077, -449, -741, -136, -1303, - -572, 1886, -986, -10529, -51, 1360, 2418, 116, - -1490, 1928, -9977, 4720, 227, -11212, 3730, -2996, - 1300, 9935, 356, -4618, -384, 972, 3174, 3732, - -803, 2666, 790, 2067, 2343, -1209, -10147, 21, - 9066, -4564, 2508, -176, 264, 9834, 3360, 7278, - 9386, -1274, 522, -50, 4150, -884, 592, -688, - 309, 20750, 672, -1326, -346, 366, 2058, -607, - 633, 620, -677, 330, 69, 432, 319, 436, - -300, 21845, -318, -676, 320, -386, 889, -724, - -1394, -2664, -431, 2046, -136, 5520, 6700, 1192, - 5779, 9386, -3541, -5638, -16125, -259, 545, -267, - 1972, -2366, -43, 615, 251, 1003, -980, 2262, --10519, 12166, 2007, -884, -1560, -1250, -491, -438, - 820, 1212, 3512, 354, -1066, -46, 98, 315, - 8532, 944, -1297, 8011, 1029, -383, -1606, -8381, - -1650, 2852, -958, 1757, -4270, 2160, -9283, 2918, - -3718, -224, 6154, -5671, 3764, -554, 5214, -2526, - -31, 547, 6, 1633, -4562, 1424, 1177, -866, - 1648, 653, 6056, -1845, -1271, -350, 596, -2286, - 9893, -6594, 1099, 630, -537, 230, 972, -134, - -491, 79, 306, -74, 253, 208, -1804, 73 -}, - -.cb2232l1 = { --11397, 378, 12845, -1813, 342, 329, 1165, 550, - 556, -115, 755, 117, 2511, 260, -1189, -1406, - -1528, 1866, 3300, -9678, 1025, 10413, 199, 2878, - -3572, 8701, -1895, -1189, -576, -3384, -162, -10866, - 3253, -1267, 91, 2277, -86, -3394, 6576, -2475, - -1136, -4295, -1610, -8064, 297, -8908, -4433, -2954, - -82, -11426, -4610, 2063, 1522, -7972, -495, 1799, - 2922, -5179, -865, 4739, 11072, 3927, -483, -11111, - -2375, -1432, 1210, -1342, 2418, 1688, 852, -64, - 133, -4582, -7136, 10558, -3417, -3162, 2033, 3149, - -3050, 2532, 568, -2444, 4082, -2859, -10350, -4983, - 6633, 230, 5954, -1140, -657, -998, 1156, 736, - -8894, 64, 939, -260, -1704, -526, -1330, -869, - -2427, 12377, 1296, -120, -10560, 1794, -9090, 1487, - 7162, 519, -382, -3234, -66, 1294, 2363, 1482, - 498, -4053, -752, -154, -587, -293, 16533, 65, - -1211, 1666, 291, 2820, 2222, 2, 865, 344, - -1206, -1214, -2162, 8842, 11063, -2093, 1896, -857, - -144, 321, -9548, 4464, 5038, -282, 1160, -194, - 823, 3479, -8234, 5834, -320, 7114, -184, -2663, --11670, 472, -2013, -1282, 4390, 4453, -2126, -2483, - -900, -6262, -2237, -539, -1134, 164, 426, -8969, - -1746, -1960, 8172, -2127, -19948, 657, -712, 344, - -443, 458, -564, 56, 756, -157, 274, -1324, - -3372, 2981, 635, -9454, -4916, 2884, 2316, 8200, - -1452, 2135, 1785, -1054, 82, 5007, -4164, 642, - 9241, 5091, 1002, 2467, -8409, -854, -861, -2317, - 405, -1810, -793, -7907, 496, -1005, 3373, -1016, - 9527, -542, 1672, -9105, 280, 11170, 273, 908, - 89, -233, 10850, 870, 436, 1630, 3328, -499, - 5091, 1224, 9135, -480, -1134, 2428, -2904, 5077, - 2014, 2859, 4277, 7763, 8719, -11474, 1619, 1167, - -3188, -1063, -433, -4291, 2646, 1024, 2008, 317, - 746, 327, 6824, 1174, 8978, 5254, -8948, -136, - -2602, -1442, -698, -950, 1800, 296, -1016, 1653, - 3771, -9326, 4536, 7033, 4729, 6630, 1042, 167, - 11485, 12338, -147, 2834, 611, 1844, -313, 486, - -916, -887, -1423, 642, 242, 75, -1875, -645, - -1239, -2118, 1458, -272, -1703, 949, 778, 21826, - 214, -1320, 310, 2680, -1542, -2202, 1072, -132, - -2067, -3593, -8293, -10331, 9030, 402, -2702, 2984, --12068, 3170, -1098, -1175, -1188, 2998, 1159, -1712, - -904, 236, 42, 823, 548, -546, -1954, 15989, - -2212, 1886, 2300, 2293, 2606, 2905, 2365, -1214, - 1592, 1362, -2210, 1674, -1892, 15049, -1012, -2824, - -792, -11447, 11144, 4853, -357, -1230, 748, 1212, - -294, -424, -2720, 78, -2149, 966, 7794, 1645, - 138, -709, 464, 3614, -10308, 310, -4726, -3694, - 1088, -576, 690, 68, -145, -3282, -9280, -9537, - -1274, 3202, 588, 1790, 1437, 3880, -1803, -1154, - 15082, -2388, -1746, -885, 2267, 1813, 1688, -1039, - 9775, 350, 3218, 10550, 1048, -3731, -3748, 3517, - -910, -663, -413, -1045, -1236, -248, -132, -1196, - 12, 15815, 653, 1429, -371, 4094, -3050, 567, - -5524, -11128, -4261, 1929, -1719, 8236, 686, 1309, - -1057, -715, -2586, 1327, -38, -6180, 3499, -2080, - 8980, -1890, 62, -1004, 3308, 5809, -5778, -3865, - -610, 180, -519, 3129, 9000, 1607, 8484, -4056, - 4741, -4491, -355, -1324, 1203, -1864, -811, -15995, - -121, 1325, -817, -2170, -5753, 731, -1875, -2286, - -9193, -307, 247, 2469, -1738, -12290, 31, 1028, - 670, -66, -1856, 570, -3542, -3401, 144, -320, - -524, 184, -928, -1606, 10978, -3114, -8861, 1467, - 1156, 872, 8276, 5655, -695, 2788, 3733, 2155, - -2044, -10260, 1683, 1859, -263, 17966, -19, 1621, - 50, -261, -4143, 1245, -22, -1564, 809, 2462, - -8005, 1247, -1471, -763, -1686, -698, 2868, 796, - 4036, -3672, 11209, 1102, -9369, -1008, 1273, -906, - -4458, 1642, -3254, 3563, -94, -6267, -604, 8687, - 2388, 2214, 1759, -7788, 4296, -7467, 3547, 3248, - 845, -7784, -2195, -42, 5327, -1002, -3915, -4581, - -1215, -919, -3444, 5142, -1874, -3020, -2627, 1129, - -4456, 1840, -11472, -914, -6366, 3495, -2775, 484, - -5859, 980, -1967, 1350, 929, 6856, -3952, -3365, - 1514, 7423, -675, -2260, 6027, -3072, -6388, -3716, - -2398, 5564, 1447, -86, 1180, -1239, -1372, -435, - -1314, -1978, 942, -2018, 1027, 704, 20417, -94, - -1239, 252, -171, -1100, 1684, 1401, 623, -354, - -2674, -5042, -734, -6631, 7587, 4901, -1596, 6806, - 4230, -859, -867, 1266, -3869, -3972, 1548, -4889, - 2811, 2263, 2468, 354, -6197, -1278, 1947, 5675, - 10612, -1730, 2056, -70, 3034, -583, 879, -3719, - -8623, -1241, 822, 5832, 163, -1075, -784, 398, - 1170, -717, -374, 856, -21602, 89, -513, 260, - 854, 1152, 762, -601, 523, -107, 1033, 1877, - -1456, 226, -20758, 365, -8943, 1305, 193, 948, - 295, 2696, -3165, -1982, -2439, 1067, -12266, -1018, - 3400, -178, 1995, 11745, 1833, 9785, 1171, 582, - -1844, 157, -1242, -4080, 864, -1771, -4257, 721, - -4010, 7990, 142, 730, 1976, -6623, 4637, -7394, - -1143, -835, 3341, 1732, -7266, -448, 5379, 290, - 1855, 6977, 6637, -6561, -1370, -1767, -2769, -1189, - 3872, -4895, -4679, 3906, -1664, 1514, 7908, -7960, - -4147, -1235, -1706, 3314, 144, 1668, -9505, 2268, - 4147, 2515, -1451, 6475, 1675, 106, 981, 201, - 309, 60, -133, -472, 561, -380, 1130, 91 -}, - -.cb2232s0 = { --26218, 1606, -390, -696, 266, -947, 561, -1526, - -8, 1080, -187, 5671, 2249, -30, -4129, -768, --10908, 3826, -10422, -144, -1259, -1372, -3553, 1287, - -5151, 6442, -5101, 1386, 791, -1593, 12942, -764, - 424, -6212, 9733, 702, -9721, 524, -4818, -1232, - 6, -484, -818, 955, 6425, 3594, 5156, -286, - 1514, 4466, -1756, 11321, -679, -1481, -477, -8015, - -3059, 4476, 679, -1143, 2877, 2581, 3230, 239, - 12018, -1597, 13431, 11852, 260, 3306, -714, 1299, - -4375, -778, 170, -565, -3510, -6632, 3354, 5901, - -1070, -5912, -3430, -4970, -4712, 2648, -9113, 1561, - 1002, -5659, -3177, 638, 2289, -1050, 12310, -10364, - 2830, -961, -194, -6442, 2206, 3454, -2087, 4327, - 1080, 10257, 8107, 4904, -3141, -2339, 7568, -363, - 3765, 7960, 7067, 1496, -3842, 1805, 2415, 913, - -1641, -5411, -7583, 4597, -1324, 2882, 11310, -2570, - -2877, 3544, 4642, -2249, 7110, -307, -3413, -2871, - -8974, -6358, -5703, 4046, 83, 1887, -3476, -4346, - -2995, -346, -46, 22143, -576, 2597, 696, 1520, - 140, 2937, -3356, -988, 4090, -1246, -3347, 1387, - 2264, 1282, 7040, -806, -12810, -1105, 32767, -4266, - 108, -1998, -680, -1279, -467, -110, 462, 768, - 1678, 1408, -1888, -1115, 9430, 5852, -3578, 5367, - -1096, -4310, -9588, 4350, 6048, 2516, 3214, 4468, - -276, 15175, -848, -2875, -314, -6002, -11743, 448, - 9238, -3026, -3934, 2840, -2070, 1850, 444, 511, - -542, -7382, 6002, -14447, -1498, 176, 812, -2632, - -2291, -3312, 3953, 370, -2154, 1678, -1186, -6382, - 1544, 3534, -3767, -7459, 7265, -3272, 10669, -1677, - -7046, -1679, -132, 2108, -1948, -2938, -5393, -6222, --11293, 2066, 981, -731, 1869, -2211, 3558, -21513, - -678, -493, -2087, 245, 635, -2011, -3316, 13445, - 2089, -10186, 1114, -1241, 2121, -2305, 3316, -1282, - 2733, 318, 3534, 4844, -1439, 8932, -7649, -556, - -7519, -3442, 5068, -3546, 8586, -8425, 7146, -683, - 665, 3052, -2581, 248, -8320, 2270, 7045, -800, - 5890, 2187, -251, -2552, -3867, 3665, -1643, -11757, - -5542, 1806, 3669, -508, -3436, 600, 10412, -5426, - 1680, -4545, 11536, -1859, -5446, -4594, -4300, -1173, - 282, 2100, -2556, 9486, -7325, -7252, -3155, -775, --13674, 4272, 3066, 9352, 1647, 1136, 794, -520, - -654, 1539, -2244, 3155, -12039, 731, 3379, -1904, - 6866, 9669, -2384, 2099, -2426, 1633, -3358, -5662, - 2164, 10679, -5330, 7066, 5826, -187, -4840, -1174, - -3694, 976, -2548, 2292, -3517, -1007, -4041, 684, --14986, -4789, -4135, -4376, -10678, -1482, -10466, 3575, - -1960, 3185, 1198, -196, -892, -5424, 4802, 13608, - -7772, 3952, 4404, -52, 1097, 3182, -2699, 900, - -1258, -8055, -3102, 784, -2574, 1556, 1060, -5417, - 537, 11991, -650, -487, -10250, 6766, -3716, 1062, - 2525, 1039, -3002, 5742, -502, -4583, -144, -144, - -5896, -978, 1786, -1420, 1944, -130, -5202, -1578, - 7821, -11675, 9980, 5065, 5942, -362, 16344, -801, - 1932, 1242, -10, 791, -170, -2468, -479, 3297, - 4328, 11473, -1549, -12316, 209, 1739, 1875, 1305, - -4310, -13049, -4913, 9208, -966, 2570, -138, 890, - 1373, -1324, -965, 8563, -7560, 490, -1392, 5695, - -5656, 5431, 3974, -1131, -1246, -1334, -3859, -3150, --12976, -6929, 665, 9393, 490, 2212, 18, 542, - 229, -3925, 1836, 4223, 5268, 1200, 471, 20, - -9914, -5774, 8362, 5929, -7087, 2005, 15624, 1626, - 5419, -1492, -1536, -417, 1957, 2585, -404, -1125, - 2296, 596, 836, -356, 745, -2810, 2879, -2354, --21682, -108, 726, -862, 593, -42, 266, -1356, - -2119, 19613, 814, 2462, -2940, 222, 3595, 5634, - -807, 1219, 2446, 5666, -1839, 7092, -10581, -5136, - -2408, 5726, -1116, -2348, -6318, 8991, 6750, -5321, - -7344, -2194, -5544, 1705, 12500, 9069, -1966, -4914, - 2225, 3537, -1485, -5141, 434, -1620, -5383, -710, - -5443, 3930, 7082, 667, -3289, -3202, -2097, 1970, --11647, -2927, -2098, -1345, 3449, -2075, 262, -756, - 1829, -271, -1292, 1079, -5746, -344, 3660, -4456, - 3593, -7652, -1367, -828, -2290, 1063, 4234, -17596, - -911, -6068, 1040, -2956, 2704, 1763, 974, 3132, - 697, 1267, 240, -5520, -12368, 10830, -633, -5939, - 2307, 1868, -2216, -1261, 597, -6302, -5145, 3550, - 7519, -6963, 3752, 876, -1912, 30, -9192, 1075, - -4632, 9108, 1139, 911, 9290, 1268, -1006, -1718, - -6668, 3294, -1510, 6527, 456, -1400, 11424, -4168, - -3940, 4738, -4863, 2990, 3202, -441, -4744, 4623, - -4351, 3997, -11016, -737, 136, 7978, -3801, 4170, - 3602, -2217, 849, -2552, -22232, 323, 193, -4, - -1030, 590, 1625, 3208, -10595, 2624, -741, 13121, - -1044, 1601, 5175, 2199, -3833, 1804, -2314, 793, --11486, -655, -3320, -2975, 4065, -3124, -706, -7264, - -1038, -3082, -5503, -7147, 8367, 1205, -1092, -1694, - -1078, 11584, 8, -1237, -2077, 9732, 4963, 2780, - 674, 581, 8226, -1231, -9252, 644, -3284, -744 -}, - -.cb2232s1 = { - 32767, -45, 422, -1139, -1052, -2085, -695, -612, - 1451, -288, 58, -878, 53, 2912, -1891, -7148, - 1893, 3028, 165, 963, 2260, -7904, 5857, -18824, - -2617, -1030, -872, 1500, 1118, -745, 143, -436, - 1239, -3840, 1785, -2506, 20237, -1026, -1556, -1371, - -660, -1185, 939, 1315, -3658, -5428, 587, -4105, - 1596, 12612, 5781, 1172, -3490, -1182, -333, 6258, - -2594, 2144, -4830, -190, 1972, 2687, 1327, -987, --15046, 4659, -71, 6890, 1588, -4787, 4318, -3704, - 496, -5601, 1954, -1250, -3389, -5156, 9238, 2298, - -4945, 183, -2036, 114, 12250, -2330, 71, -3395, - -1402, 3668, 531, 10915, 1162, 7738, 9089, -1250, - 1500, 6357, 1155, -5094, -2641, 1657, 470, 2022, - 535, -306, -18031, -903, 2913, -5486, 1769, -1419, - 9082, 2149, 3516, 6960, 833, 1123, 1266, 1672, - -690, 9634, -2986, -4675, 1006, -2205, -2919, -3205, - -2759, 107, -931, -9694, 2340, -862, -2782, -3636, - -9414, 9564, 1057, 8664, 1326, 3928, 1452, -4692, - -3437, 8610, -10466, -6638, -2879, 3408, 861, -3057, - -823, 164, 3153, -3698, -15693, -886, 1456, 3278, - -6160, -57, 1110, 22, -2985, 7299, -1082, -7921, --12212, 480, -7645, -211, 1586, 3874, 3242, -883, - 6730, -1597, -506, 3744, 7552, -7607, -65, -1442, - 266, 10012, 1594, -2628, 6988, -1049, -516, -691, - 672, 4913, 1788, 14973, 342, 962, 7212, 1124, - 500, 1135, -311, 3886, 12548, 5432, 6219, 3341, - -122, 5636, 6871, -10831, 4010, -10084, 1456, 5216, - -1013, 1102, 4164, -1490, -5186, -242, -4498, 3322, - 3584, -2176, 5704, 515, -11556, 1446, 4303, -3928, - -4227, -7268, 6069, -11330, 822, -2054, -3035, -2516, - -1816, -3796, 8408, 8849, -3030, -8201, 1149, 7388, - 1036, 2586, 5618, -2274, -5037, -1497, 384, 1454, - 8154, 1672, -2409, 3347, 13258, -979, 513, 7826, - 2662, 1818, 5537, -1104, 2645, -10632, -8767, -5667, - -1029, 806, -9040, -4684, 792, -5008, -5807, -3924, - 964, 313, -2521, 1106, -5728, 13534, -8078, 4216, - -1388, -2588, 986, -14536, -1410, 3461, 1360, -1348, - -104, 1493, -2858, -2860, 2045, 18330, 4814, -3628, - -705, -3228, -660, -2664, 2616, 4548, 3753, 1574, - -1319, -1110, 556, 3304, -2803, 13052, 4592, 2922, - 13667, -2322, -3056, -2717, 174, -4222, -4296, -7695, - 1366, 1786, 1041, -110, -1997, 4102, -1855, -900, - 203, 1311, 3412, 4107, 22609, -4112, 427, -2488, - 257, -1267, -1277, -6430, -7193, 10667, 4495, -4317, - 6846, 13213, 7335, -972, -3137, 335, -609, 3131, - 2406, -3762, 2151, -5188, -7675, 2068, -2027, 3722, - -773, -3276, 1539, -7886, 1005, 13693, 4601, -8386, - -508, 5662, -4889, 93, -10603, 4051, -2, 1094, - -4897, -2274, -2377, 2228, -5507, -464, -3455, -227, - 9433, 8093, -2245, 3701, -1047, -6827, 2037, 1926, - -3610, -15420, -581, -6127, -2075, 2501, -2216, 5385, - -2297, -2660, 1563, 3244, 1418, -2012, 2964, 12235, - -8595, 2728, -3541, -6511, 11038, 11326, -183, -1102, - 1038, 1224, 20, 1441, -349, 1240, -7737, -930, - 1411, 6945, 4130, -13544, -2625, 3550, 3149, -730, - 7658, 3098, 673, -2259, 2556, 1543, 1478, -951, - -8128, 4951, 11919, 4588, -8448, 784, -11498, -1908, - 2578, 2936, -7496, -5834, 1987, 3407, -4133, -4924, - -1348, -1300, 916, 899, 20257, 2027, 1450, 4388, - -3748, 3846, 2187, -1158, 4720, -3613, 5312, 4055, - 448, -6383, -8794, -2232, 1920, 834, 27087, -754, - 90, 1410, -985, -1381, -61, 650, 1080, 7035, - -2772, -1233, 13410, 4494, -472, -2896, -5083, -2217, - -5778, 437, -6853, 4996, 3442, 6092, -6497, -3871, - 4024, -898, -73, -3067, -2793, 5640, 6076, -2454, - 3598, -277, 1672, -6858, 2419, 9753, 6292, 8835, - -9909, -4724, -618, 7266, -416, 1965, -4968, 2421, - 1155, 3815, -116, -3725, 7872, -4901, 2383, 1612, - -2186, -2302, 2791, -2226, 1144, -13379, -6602, -806, - 7099, -2098, 4194, -2128, 8663, -4275, 452, -135, - -6053, 1280, 12815, 3278, 8452, 4479, -1648, 1453, - 1407, -966, -1016, 3173, -7333, -4552, -13176, -1744, - 577, -1572, 611, 1202, -146, -5773, 3012, -3016, - -1581, 3162, 3818, -1970, 6195, 1946, -9656, 2861, - -7875, 3133, -7840, 10951, -1684, -306, -227, 9776, - -82, 1736, 1180, 3457, -2874, 5365, -7428, 7604, - 2623, -2998, -2270, 10410, 1252, -2725, -4433, 1758, - -5225, 6522, 6698, 712, 4694, -2392, 240, 423, - -3030, -12708, -3136, -5176, 480, -1624, -12900, 7537, - 4371, 1186, -1828, -757, -1850, -974, -3755, 1415, - -6302, 2642, -3823, -1570, -8090, 8251, 1945, -9213, - 1147, 4128, -4301, 806, -1745, 704, -2496, 1375, - -802, 9, -808, -252, -5453, 3857, 10353, -536, - 1875, -2896, -10792, 3358, 1063, -890, 7200, 3660, - 406, 2840, -6973, -4469, 4638, -8091, 2772, -8035, - 1728, -5315, 7234, -2718, 3707, -1226, -11858, -2397, - 772, 3285, -4089, -1400, 1113, -16680, 1885, -435, - -959, 242, -817, 259, -2010, -1857, -557, -914 -}, - -.cb2232m0 = { --13394, 14382, -488, -1088, -817, 100, 305, 2267, - 2527, -1584, 995, -5781, -3585, -1826, 803, -4108, - -3137, 12111, -211, 838, 4879, -1964, -1728, 13830, - 2084, -11535, 664, -2499, -3421, -703, 4528, 968, - 1008, -12010, 984, 2658, 422, 1412, 10772, 2216, - -4291, 1329, -2324, 2392, -2029, 12322, 1053, 169, - 12635, -902, -62, -670, -3007, -3322, -2948, 1817, --10688, -1264, 1949, 2734, 1072, -1429, 2085, 10312, - -1685, -4433, -1287, -9620, -1132, 20, 614, 2470, - 2821, 5934, 3526, 11292, 50, -12970, -11948, 1114, - 1980, -945, -713, -5357, 3766, -447, 969, 2247, - 11854, 2148, -12393, 1518, 610, 4527, 1164, 1347, - -1422, 649, 653, 855, -24, 30152, 20, -564, - -2825, -11, -1408, -80, 239, 305, -3163, -854, - 568, -18, -4212, -403, 288, -3009, 229, -1152, - 16390, -877, -458, 316, -128, -12165, 1088, -828, --10886, -269, 747, -1026, 1716, -10920, -9204, -3123, - 958, -6128, -260, -851, -1524, -2386, -6472, 228, - 2667, 3158, -140, 1719, 2330, -2730, 3080, 44, - 15743, -2167, -11637, -607, 476, 408, -12505, -1862, - -1892, -440, -3785, -2348, 1229, -338, -438, -797, - 29933, -715, 366, -197, 576, -188, 484, 240, - -4844, 1168, -1054, 863, 875, -295, -16091, -1972, - 3976, 3833, 3056, -770, 1011, -3098, 165, 3973, - -9367, -18, -299, -11254, 1005, 8644, -14788, -2268, - 2644, -8410, 578, 2169, -766, 2764, 2378, 3282, - -2710, 7612, -542, -12062, -2437, -414, -506, -10332, - 2732, 839, -2593, 923, 1159, -1057, -7333, -86, - 2832, 11328, -1616, -302, 4399, -547, 6107, 9983, - -6901, -85, -544, -4916, 366, 4878, -8662, 7313, - -3056, -1027, 2381, 8906, -7270, 509, -1124, -2512, - -1636, 5830, -5868, 2369, -3236, 12557, -2713, 12793, - -2957, 1688, -852, 4723, -122, -2336, -4698, -1306, - -7399, -2090, -1953, -1505, 3335, -10906, -2598, 1322, - 2556, 7210, -1553, 1262, 1878, -10719, 1746, -2736, - 1448, 8734, -9602, 828, 1752, -1632, 8037, 2728, - 562, -1879, -10572, -544, -2254, -1997, -6384, -87, - -5878, -473, 498, -2960, -5698, -11500, 1815, 2050, - 7388, 5230, 2782, 5602, 514, -306, 13022, 523, --10776, -846, 716, 270, 3350, -6021, 1420, -6175, - -1978, 3967, 11612, 3320, -4100, -2468, 4595, -5338, - 65, 3478, 19, 3501, -15896, -1335, -1861, -1944, - 3935, 3630, 4627, -5892, -458, 383, -211, -594, - -165, 24865, -656, 2300, -404, 257, 214, -643, - 2298, -180, 35, 4974, 834, -998, -1738, 5449, - -9222, -10858, 4188, 9147, -5639, -1691, 990, -1945, - 3421, -3527, 9005, -2038, -2369, 5098, 967, 15840, - 196, -3204, -1079, -776, 11806, -1352, -2053, 2011, - 309, 642, 1541, -1466, -4465, 6679, 5756, 7474, - -58, -1864, 5908, -1576, -30374, -904, -571, -1136, - 425, -22, 666, 1150, -734, 82, 1254, -226, - -437, -890, 1464, -3368, 987, -11885, 1127, -7224, - 1872, -8198, 8775, -2695, 1457, 15102, -899, -1384, - -1975, 1891, 3128, 1465, -1649, -1363, 1483, 303, - -534, -7, -1710, -1377, 769, 12698, -8987, -802, - 4636, 572, 2004, -3513, 442, -9863, 3215, -4550, - 2138, -4346, 5682, 11053, 7220, 9842, 797, -1399, - -2679, -5857, -2143, 3241, 2330, 248, -630, 1044, - 639, -3432, 125, 22083, 1976, -1003, 813, 552, - -571, 4358, -6200, 3635, 5439, -636, 233, -4856, - -3519, -460, 6956, -4215, 1537, 7895, 13910, -7637, - 1392, 1572, 648, 3690, -1988, -2463, -3302, 677, - -924, -535, -6025, 4126, 7178, -4145, 4960, -1860, --10926, -1470, -9506, -226, -258, 32, -479, 2222, - 94, 11358, 3984, -2732, 2111, -590, -2444, -344, - -425, 598, -1382, -1213, -17632, 1566, 1387, -3521, - -57, -1829, 4788, 574, -206, 7962, 9157, 6459, - -1594, -1355, 4874, 1066, 2006, 1793, -7569, 2369, - 1108, 1305, -3046, -14052, -1736, -4045, -4328, 7497, - 3304, 1518, -5666, -529, 4256, 4667, 932, -1495, --10414, -414, -2110, -3150, -1250, -8799, -419, 5162, - 8497, -8720, -746, -3015, 6403, 3855, 7350, 165, - -59, -958, 5780, 6044, 1736, 3016, 31, 1012, - 3422, 7598, -6837, -2092, 2262, 6171, -10362, -2108, - -1352, 1798, -4872, -6369, 2507, 2640, 6074, 1835, - 2948, 388, 398, -9295, -5384, -2088, 2096, 742, - 3286, 441, 7135, -2112, -9958, -5612, 2479, 5427, --10114, -674, 308, -1037, 770, 514, 1868, -252, --11901, -984, 670, 2506, 5396, -1047, 9113, -10865, - 4872, 1720, 2226, 947, -2336, 2649, 173, -1464, - -2874, 4463, -1270, 3429, 6242, -5380, -7772, -4550, - -8451, 2045, -2855, 5336, -15066, -418, -4886, -648, - 3736, 945, -956, -4825, -116, 130, 1889, 9642, - 3790, -4371, 7180, -1556, 6562, -2207, -7910, 506, --21594, 662, -338, -943, -1022, 6453, 301, -464, - -457, 840, 3313, 10946, -294, 8156, 138, -1425, - 2397, -792, 6468, 4615, -511, 15938, 494, 274, - -5976, -660, 3894, -2140, 1424, 2003, 4101, 2823 -}, - -.cb2232m1 = { - 20456, -1952, -1581, 869, 628, 76, 1404, 4060, - 508, -3177, -946, -2992, 2422, 1139, -1931, -240, - 1011, 365, -1106, 20973, -1438, 372, 137, -1058, - 1171, -1252, 2794, 1434, 1814, 482, 3948, -2704, - 20422, -241, 441, -1121, 499, 1036, -918, 9708, - -3166, -488, -10379, -3201, -5254, -1871, 5665, -12622, - -7591, 127, 1469, -2267, 1813, -4197, 2065, -602, - -395, -652, 333, -19114, -1092, 4310, 1590, 1688, - -1453, 177, 4402, 1168, 5972, -1295, -3258, 1542, - -4832, 3377, -5545, -3622, -4944, 2064, -2846, 8118, - -845, -6778, -3640, 5729, -907, -11007, -5, 2634, --11118, 2108, 144, 13299, 251, 336, 563, -75, - 3004, 169, -3892, 1477, 1066, -1571, -1113, -1088, - 517, 465, -21841, -1541, -1094, 1841, -9213, -17478, - 1662, 8, 1192, 1174, 1014, -5659, -695, 316, - -5161, 1803, -1056, -2369, -2919, 2941, -9712, 1975, - 426, 11214, 2288, 6186, -7348, -3062, 3341, 3252, - -4102, -346, -876, -7088, -3330, 4507, 310, -1632, - 299, -2636, -2740, -752, 10159, -7201, -9568, 3134, - -4002, -41, 2479, -1816, -14099, 3575, 1161, 6427, - -2466, 390, -1883, -6265, -1266, -263, 1474, -592, --21234, 94, 4187, 1, 3227, -3273, 1950, 406, - 543, 1661, -2648, -9252, -2048, -5987, -722, 4932, - -4410, 12504, -1572, 2244, 5610, 307, -9710, -3642, - -6436, 4368, 2956, -2269, -6196, 4069, -766, -3695, - 3416, -5786, -9668, 11677, 1208, -965, 1516, 1132, - 1018, -6168, 1970, -10357, 1379, -725, -8789, 3730, - -65, -4758, -1818, -1050, 9641, 4519, 2886, 2667, - 6348, 2436, -438, 1978, -9374, -1286, 3893, -2073, --11199, -2081, 3345, -3444, -9480, 2410, 1986, -1869, - 3252, 5949, -2119, -401, -214, 3416, -1067, 18510, - -2986, 3510, 508, -357, -837, -1205, 2884, 11587, - 11565, -555, -2664, -873, 3642, -2068, 1734, -4408, - 330, -181, -1358, 1407, -9739, 809, -10203, -2066, - 3440, -2063, 3238, 3734, 1671, 750, 6890, 4068, - 1238, 493, -1330, 76, 8918, 10855, 85, 12236, - 3570, -1074, 3008, -9424, -3186, 1271, -380, -157, - -4974, 10575, -1378, -219, 1354, -1589, 10936, 2268, - -3787, -1040, 7567, 924, 10490, -806, -1318, -1576, - -209, 93, -3745, -3820, 439, -9828, -6265, -864, - 31342, 35, 1332, 443, -590, 846, 104, 868, - -863, 1526, -1088, 11494, -7055, 3564, 109, -3072, - -2234, -4530, 1866, -3425, 9940, 3158, -1821, -680, - -1124, 2884, 1191, -61, -9698, 7596, -558, -9019, - -1181, 208, -1342, -68, -312, 294, -1468, 1410, - 39, -21081, 724, -2137, 935, -8, -10297, 3509, - -6510, -6558, -6906, -1905, 1915, 5920, -8983, 3416, - 7300, -1372, -1422, 1822, -10433, -2530, 1669, 554, - -3008, -3351, -922, 8279, -5184, 5520, 4785, 683, - -506, -4558, 1938, 8442, -12639, -54, -2907, -820, - 10004, 1780, 485, 1401, -3786, 786, -5937, 2632, - -1540, 972, -3342, 2294, 8076, -1006, 11731, -1825, - 3036, 1085, 1160, -9680, 11111, 7838, -2504, -2112, - 2376, 2534, 3624, 555, 3610, -520, -831, -15, - -498, 167, 711, -22685, -999, -1466, -1643, -394, - 5404, -4247, -2307, 4052, -1156, -1240, -490, -1598, - -4365, -8382, 10493, 464, -16592, 3723, -7709, -821, - -4218, -922, 398, 5635, 2184, 5090, -7144, 2420, - 792, -324, -1278, 3172, 13101, 1608, -3996, -2219, - 2995, -6924, 816, -2482, -406, 3458, 503, -8154, - 3460, 2542, -3703, 8524, -61, -430, 23212, 1203, - 2335, 5556, -476, 923, -565, 593, -1611, 1814, - -1614, -7067, -1957, 10166, -4306, -421, -4026, 1854, - -9881, 667, 7720, -2906, 7003, -1823, 6344, -8614, - -2965, -2720, -62, -802, 1945, 4574, -4604, -8341, - 518, -3543, 95, -4262, -5220, -133, 10270, 1999, - 3234, 8900, -4866, -3708, -4465, 4542, 2545, 1770, - 6995, 3559, 1133, -1152, 14680, 1002, 634, -12913, - 1686, -1645, -1796, -50, 112, -1108, 1070, 686, - 1068, 1555, 896, 3498, 10458, -32, 12017, -737, - 650, -432, 404, 170, 10873, 1864, -1718, 11061, - -1556, -3766, 225, 6999, 1730, -6919, -1895, -2919, - 8250, 10050, -4631, -1488, -4801, -1504, -2736, -110, - -3630, -2752, -11162, 1128, -2580, 11692, -678, 1338, - 2175, -6030, 616, 1651, -7034, -3057, 2420, 1998, - 4383, -1721, -10762, -428, 2902, -906, -4298, 2141, - -1242, 5464, -607, 5389, -8946, -3890, 10884, 1544, - 628, -1969, 13902, -1570, -1080, -689, -4676, -3642, - 753, -11351, -110, -744, 4286, 1163, 3105, 9752, - 11143, 4296, -1698, 1012, 2284, -989, -958, -9481, - 738, 24, 426, 1638, 3898, 8885, 2938, -8826, - 2982, -1679, 8466, -651, 5144, 2736, 751, -84, - 7710, 3077, 2885, 146, -1102, -2569, -2039, 11059, - -9950, -1048, -1031, -33, -5118, -1096, -1986, 2306, - 2400, 9320, 6188, 500, 2090, 61, -11357, 118, - 1505, 1032, -1920, -164, -9744, -4670, -11029, -102, - -960, -1023, -2570, 4102, -3989, -11478, 772, -1515, - -1102, -2194, 1722, -1195, -8144, 746, -9534, 3250 -}, - -.cb4440l0 = { --14497, -1982, 631, -984, -2115, -3252, 2755, 2017, - -2110, -8864, -792, -1291, -2761, -2365, 698, 1047, - 972, -14703, 10590, -3945, 663, 972, 1204, -2801, - 1295, -1296, 50, 1448, 888, -1879, 122, 78, - -183, -588, 16202, -388, -2240, 1136, 1266, -6445, - 2619, -1664, -6329, -2700, 1557, -497, 598, -110, - 1298, -334, 191, 29897, 387, 419, 76, 152, - 533, 78, 112, 101, 158, 136, -236, 88, - 43, 107, 84, 21, -6385, -1711, 1757, 1411, - 9152, -72, 1428, -1098, 10328, -506, -360, 285, - -36, -2816, 819, 88, 176, -481, -172, 2067, - 3268, 5479, 8605, 11272, -1880, 361, 1582, -4973, - -1379, 3835, 74, -3, 493, -431, 1390, 101, - -550, 59, 476, -469, -583, 568, 732, -1015, - -1104, -698, 23922, 1130, -1268, 280, 204, -59, - -9789, -317, 935, 2944, -10402, -2564, -4648, 1506, - 3834, -1002, 2805, -158, -409, 814, -150, -97, - -3573, -1550, 1356, 5350, -365, -2622, -3454, 310, - 1194, 911, -10928, 937, 7980, -5286, -554, 1999, - -1263, -562, 10, -321, 744, 44, 64, -274, --30136, 340, -1051, 756, -30, -6, -269, -273, - 12, 95, 1565, -13194, -11810, -485, -1574, 414, - -240, -452, 564, 740, -476, 959, 1079, -1568, - -422, 37, -154, 10117, -68, 1412, 11862, -3420, - 4169, 5178, 527, -1027, -1030, -1985, 448, -716, - 1696, 1942, -254, 308, 1100, -790, 8102, 6630, - 3653, -1018, -587, -6990, -19, 1671, 1425, 8089, - 3708, -1182, 774, 659, 113, 437, 50, 835, - -532, -11209, 1682, -7490, -2592, 1234, -4689, -7301, - -143, 3361, 1121, 177, -473, 513, 136, 965, - -4020, 4639, -1212, 1271, 2905, -6865, 10499, -3800, - -3354, -5029, -3606, -950, 4490, 526, 1006, 2, - 1760, 5819, -55, -1098, -1843, 348, -2062, -9196, - 3712, -11466, -3218, -858, 2720, 589, 320, 861, - 59, 5357, 564, -380, 538, -142, 490, 212, - 1716, 670, 1904, -181, 2979, 943, 16916, 1271, - 988, -802, -1490, 9154, 643, 1725, 1347, -2827, - -4096, 485, -7091, -3180, -4747, -1604, 1576, -5724, - 6104, -139, 1726, 11715, 360, 7519, 2513, 5192, - -2208, -1993, 829, -387, -5724, 4418, 116, -2955, - -226, 249, 377, 2149, -2929, 5021, -3064, 800, - -1459, 11384, 8556, 1740, 368, -2839, -2049, 1438, - -1357, 4084, 1896, -528, 1621, -1760, 13741, 302, - -1018, -9774, -3521, 1302, 1374, 1139, 918, -1724, - -764, 858, 804, -1772, 372, -322, -526, 11924, --11944, 4012, 1749, 1737, -1545, 68, 889, 280, - 690, -2200, 1068, -484, -171, 455, -44, -3178, - 2243, -590, 749, -792, -19876, 198, 236, 2695, - -3413, 652, 284, -820, -1134, -199, -112, -5650, - -418, 1047, 1090, 2260, -3297, -2164, 13524, 1720, - -326, 910, -1706, 3912, -1175, 1687, -2152, 50, - 35, 1718, 721, 9316, -2256, -4330, 6961, 4432, - -8043, 45, 1370, 3472, 2892, -3224, 1368, 1355, - -562, -694, 746, 198, 1188, 2819, 3131, -2371, - 6438, 847, 2111, -10187, -3451, -9826, -3502, 655, - 649, 1460, 270, 118, 45, 192, 188, -1139, - -258, 663, -84, -27519, -765, -905, 357, -4, - 89, -372, -24, 178, 1127, 209, 1177, -2762, - -587, 1488, 8989, 3217, -2550, 215, 9540, -7196, - 1259, -3716, 2767, -261, -216, 872, -3008, -2076, - 8682, 709, 3629, 87, -3114, -10624, 246, -1670, - -1738, 1229, 7624, -1120, 784, 305, 233, -185, - 280, -1466, -268, 198, 499, 308, -2187, -1149, - -388, -38, -338, -1084, -19424, 40, 1958, -2240, - -86, 264, -9876, -1287, 4086, 3742, 2502, -10078, - 4574, -1493, 1078, 3218, 2410, -364, 1049, 2638, - 35, -1295, 200, -2847, 10818, -12064, 2375, 348, - -353, 2788, -821, -3196, -511, 146, 2015, 235, - -1094, 2622, 2688, -79, 5176, -884, -11814, 794, - 2696, -6704, 3452, 1295, 3872, 2924, 4498, -166, - -598, -1213, 891, 5478, -266, -777, -5, -776, - 1003, -1837, -156, 17910, 453, -297, -1545, 857, - -288, -308, -6373, 2045, -1846, 3007, -2236, -1904, - 815, -2889, 4200, 8320, 9872, -614, -834, 3856, - 414, -234, 1559, -7451, 3641, -1230, 837, -127, - 2652, 411, -532, -12548, -1692, 1034, -2418, -968, - 558, -1564, -1952, 307, -1064, -6776, 1588, -2636, - 949, 8272, -12, -3468, 3481, 6588, 2580, 7393, - 272, 1528, 1818, -2206, -349, -396, -11704, 1487, - 9753, -4665, -24, 2084, -780, 5036, -647, 3668, - 561, 1099, -1094, 534, 1270, -99, 1006, -476, - -528, 12481, 1589, 1593, -1682, 7022, 2664, 8702, - -563, 1082, -206, 87, -1978, -144, 228, 1232, - 889, 14340, 65, -1061, 10510, -95, 649, 53, - -962, -383, 2479, 1322, -1798, 2840, -492, -419, - 90, -680, 79, 1026, -20912, 1593, -742, 1086, - 516, 699, 2393, -64, -2010, 46, -859, 111, - -440, 14281, 272, 797, -10141, -3734, 3126, -3050, - 1300, 73, -1754, -1278, 1890, -2710, 704, 1160, - 1, 269, -24, -622, 124, 138, -522, -510, - 95, -402, -27306, -470, -214, -159, 396, -201, - -372, 122, 136, -1005, 744, 1949, -810, -2648, - -726, -384, 955, 1232, 1354, -345, -19485, 1056, - -193, 1257, -263, 398, -752, 602, 98, 793, - 17, 20186, -189, -2615, -174, 166, 436, 411, - -1046, 374, -471, -253, 233, 8352, 1342, -1279, - 9305, 2190, -3239, -5262, -3454, 1844, 684, 303, - -4434, -6041, -3495, -2482, 389, 353, 159, -14, --29179, -511, -158, 92, -401, -36, -297, 447, - -605, 269, 85, 212, 8, -118, -130, 207, - 13150, -8712, 2504, 1355, -3268, 1396, -4748, -2200, - -1560, 228, -162, 1179, 3024, 742, -860, 69, - 10, 30006, -538, -489, -125, -214, 364, -682, - -283, 532, -134, 227, -448, -20, -266, 70, - 2, 9310, 14858, 856, -493, -3357, 36, -248, - 214, 281, -73, 3268, 745, -245, -1007, 146, - 392, 36, 8042, 2953, -6603, -7697, 4425, -2498, - 571, -2194, 3388, -794, -561, -2763, 1912, -3030, - 225, 214, -27, 834, -10661, 437, -506, -535, - 8397, 1332, -2406, -8868, -2972, 1385, 296, 865, - 2318, 890, 244, -121, 226, 375, 896, -10381, - -2266, -3404, 983, 1255, 259, 11427, 455, -3041, - 307, -2446, 476, 723, 18, -10224, 510, 552, - -654, -876, -465, 628, -12572, 786, -393, -4162, - 938, -1327, -1695, -608, -1352, -131, -880, 830, - 1016, 21875, -408, -1560, -500, -1682, 453, -930, - 1316, -136, 434, -683, 412, 202, 233, 382, - -2002, -9267, -1034, 8710, 434, -8121, 3035, -3121, - 1792, 2712, -1537, -1082, 854, 1337, -1084, 91, - -4485, 2545, -4412, -1930, -12234, -4802, 4641, 437, - -928, 2163, -3154, 521, -665, -1200, 2654, 931, - -388, -118, -1144, 133, 5089, -1194, -1528, -967, - -795, 188, 1918, 897, -7046, -7617, 7118, 5755, - -2724, -7894, -472, -360, -591, 990, -3032, 7742, - 726, 5490, 9383, 479, -3032, -1904, 7158, 4706, - 2442, -1576, -58, -156, -3977, -2696, 4195, -166, - 3342, -1566, 3767, -4159, -5750, 5505, -7663, 4516, - -4073, -2612, 5136, -290, -666, 1282, 776, -566, - -602, -310, 1003, -648, 2928, -3159, 427, -1168, - -2702, -16990, -205, -343, -1196, -1980, 1653, -512, - -1820, -418, -3368, 3522, -1966, 4964, -5728, -5185, - -210, -1721, 10131, -7060, 3351, 334, -96, -3193, - -1713, -614, -2633, 147, -1552, -2363, -3724, -1731, - -7350, 5453, -2732, -2867, 12458, 416, 0, 4414, - 833, 590, 1617, 405, 73, 868, 232, 195, - 15, -196, -782, 749, -955, -84, 1176, -553 -}, - -.cb4440l1 = { --12227, -3413, 12848, -1336, 20, 894, 254, -1001, - -1381, -406, -1157, -458, 300, -395, 825, -34, - 74, 382, -1018, -10266, 1338, 11091, 544, 797, - -4304, 1389, -747, 1924, -257, 2615, -37, -4375, - 782, 158, -378, 19, 652, -539, 1012, -4211, - 1263, -925, 96, -9226, 5921, -8209, -71, -1838, - -2201, -7441, -60, 393, -5626, -264, -1002, 85, - 1989, -1616, -216, -914, 9907, 8044, -578, -7830, - -1705, -3624, 2430, 59, 5813, 870, -317, -2545, - -4020, -1330, 1215, 9352, 5425, 324, -4803, -681, - -506, -4710, -6574, -4184, 65, 729, -1310, -1387, - 1385, 2364, 1672, 2493, -438, -1367, -907, 38, --20220, -1644, 512, -413, 348, -112, -532, 785, - 1332, 7140, -1916, -1766, -11570, 1811, -9167, -76, - -1531, -175, -1739, -771, 2014, 519, 15, 576, - 8736, -979, -28, 1830, 329, -302, 12206, -1501, - 5195, -305, 1456, -581, 1488, 142, 235, -157, - 192, 1540, -922, 11056, 11823, -2964, -1488, 1712, - -2018, -880, -3282, -190, -198, 2436, -248, 222, - 22, 863, 1504, 2078, -2047, 216, -1270, -732, --18252, 1186, 3178, -730, 432, 934, 1617, 873, - -491, -70, -768, 679, 1398, 537, -364, 172, - -541, -94, -24, -129, -26725, 201, -554, -357, - -71, 60, 96, -1665, 1425, 1244, 332, -1068, - 326, 834, -620, -1473, 1585, 1432, 928, 18782, - -1388, 2897, 448, 40, 1323, 1433, 787, 215, - 3297, 2586, -856, 451, -17700, 735, -43, 405, - -1252, 744, 1012, 677, 312, 206, -279, -432, - 6677, -87, -72, -10400, -106, 11224, 1152, -422, - 2024, 704, 2462, -1197, 232, -119, 4, -879, - 1600, -708, 3496, 279, -143, -1096, -555, 4594, - 1486, 161, 942, 2018, 2474, -16010, -380, -193, --11415, 457, -276, -11220, -1604, -38, 813, -4044, - 1888, -4265, 1647, -882, 981, -734, -110, 140, - -3050, 1248, -549, -1167, -967, 3586, 688, -1380, - 424, -17959, 2022, 2274, -44, -1406, -432, 1335, - -659, 9555, -3581, 11045, 1870, 806, 599, -2065, - 156, -4420, 16, 2349, -609, -3058, -738, -60, - -548, -119, -49, 26, 1528, -1842, 6306, 14078, - -692, 5480, 321, 1996, 1376, -3086, 490, -54, - 1151, 932, 445, -9887, 15808, 3085, 866, -2020, - -1785, 2126, -920, 414, -290, 138, 244, 994, - -702, 1410, 330, 202, 675, -389, -241, 31306, - 380, 300, -53, 804, -109, 413, -44, 6, - 14, 486, -293, -112, 26, 11632, -836, -3948, - -518, -1364, 11360, 3558, -588, -2084, 490, 381, - -955, 2207, -2953, 1115, -265, 2, 65, 464, - -180, -111, -174, -152, -30508, 121, -207, -835, - 1126, -185, 91, -96, 222, -99, -93, -10138, - -430, -184, -372, -194, 953, -100, 382, -1422, - 13931, -1835, -1657, 821, 408, 808, -601, -463, - 7142, 5596, 3171, 2174, 2740, -11350, 1019, 1449, - -386, 1642, 3703, 4271, 1664, 2232, -674, 983, - 551, 8543, 154, -383, -2419, 1117, -520, -10966, - -4406, -3742, -79, -909, 1813, 5043, 412, 1099, - 1434, 173, 788, -92, -1004, 1288, -87, 931, - 10241, -855, 6, -405, 2580, 11455, 1150, -1916, - 3614, -262, 292, 897, 9673, -381, 1711, -2713, - -1111, 282, -2180, -2282, -2266, -724, -849, -11787, - 888, 3120, -1459, 495, -10812, -792, -274, -984, --12223, -737, -2394, -299, -578, -2758, 1521, 774, - 1938, 857, -1935, 217, 654, 1452, -3695, 6734, - 804, 134, 946, -2156, 9495, -600, -1962, -5252, - -246, 1269, 8492, 1261, -2205, -106, -1314, 828, - 1013, -12059, 663, 436, -2648, 9863, -630, -2961, - 3004, 1015, -3153, -1475, -25, 399, -846, 430, - -1237, -156, -187, 1115, -502, -363, 386, -2820, - 942, -926, 727, 1130, -20388, -274, 1140, 198, - 199, 2548, 442, 157, -1546, 3693, 892, 460, - 6552, 4858, -2560, -8673, 1930, -8913, 3427, 686, - 61, -8830, -358, 1338, -74, 1180, 2871, -3822, - 104, 2414, -1742, 11425, -4522, 393, -3016, 972, - 34, 117, -16113, -6900, -6964, 1726, -843, -242, - -2141, 803, -1093, 442, 1776, 2429, -1000, 489, - 393, 635, 389, 1126, 12285, -1648, -11396, -2885, - -56, 3840, -174, 3177, -1708, 1189, 1914, 1514, - -189, -88, 276, -240, -120, -2929, 9823, 678, - 568, 26, 10080, -2575, -806, -64, 6406, -82, - -1171, 2169, -1804, -667, -37, 54, 4208, 10829, - 11920, -468, 1916, -809, -370, 144, 3616, -263, - -4352, -124, 300, -246, -440, -115, 447, -407, - 20869, -340, 54, -764, -807, -699, -283, 727, - -922, 1098, 577, -6, -809, -50, -115, -75, - 280, 156, 182, 225, -30432, -212, -417, -245, - 177, 94, 4, -627, 167, 47, 152, 148, - 1325, -2436, -10063, -696, -9966, 1032, -1024, -3702, - 3933, 400, 333, 692, -3858, 2599, -1215, -389, - 393, -666, 2135, 10280, -2443, 1972, 410, -392, - 590, 12322, -523, 1141, 52, -1468, 819, -213, - 162, 116, -614, -10630, -204, -1247, 535, 199, - -6058, 2538, 1644, -11539, -1562, 1462, -1493, -218, - -296, -605, 321, 607, -366, -257, -837, 4536, --11683, 1266, -3805, 4496, 2854, 8, -8848, 124, - 656, -1041, 411, 144, 916, 445, -91, -260, - -149, -882, -433, -121, 345, 68, 349, 821, - 652, 251, -23053, 1015, 712, -73, 7038, -1520, - 5810, -12604, 2841, 425, 265, 1546, 938, 1851, - -1180, 2751, -498, 1289, -774, 327, 4047, -8132, - -2622, 5449, 3221, -2990, 10107, 1880, 173, -4006, - 399, -332, 642, 297, -4513, -1230, -330, -788, --21881, 903, -1308, 547, -522, 1885, -1730, -63, - 973, 897, 670, -657, -232, 498, 92, -8, --11010, 1072, -368, -1864, 11505, 3497, 730, 2158, - -1629, -1351, -1583, 2247, -1506, 2144, -902, 639, - 175, -6006, -986, -4246, -1510, 1785, -9792, -495, - 1995, -9189, -1414, -2550, 1578, 2390, -2989, 1673, - -1980, 21, -4054, 8552, 1155, -301, 1204, 3776, - 262, -1828, -1837, -1014, -9, 2711, 1467, 463, --11605, 1743, -956, -1213, -3892, 1534, -10298, 22, - -902, -658, -1759, 2507, 1552, -12298, -1050, 623, - -3221, 1522, -36, -446, -5925, 2144, -2844, 15080, - -1984, 3631, 1931, 1894, 1193, -1694, -3172, -813, - -1336, 534, -365, 833, -293, 21759, -1266, -1216, - 996, -2, -393, -858, 759, 969, -230, -151, - 977, -874, 119, -896, 262, -118, 89, 95, - 94, -437, -30375, -462, 360, -588, -334, 86, - -1027, -208, 536, -196, 367, -467, 119, -32, - -2544, 6204, 8830, -264, -7847, 848, 2267, 3877, - -6378, -2249, 1420, -1868, -3443, 3747, -590, 58, - -274, -6065, -8472, 5906, 3109, 5834, 3905, 2086, - 1300, 3828, -518, -528, -3672, 1794, 4353, 408, - 566, -2577, -1137, 2749, -2662, -528, -7479, 5550, - 2932, -336, 3681, -2034, 212, -8733, 1017, 2258, - 8225, 387, 227, 877, 2752, -1375, 2636, 8131, - 3850, -6870, -1158, -3736, -8478, 228, -5809, 97, - -2555, -2956, -928, 678, 112, 1434, -1250, 1240, - -412, -4267, -3811, 4322, -3430, 7705, 5456, -6876, - -3452, 7329, 3142, 220, 662, 1531, -5492, -1388, - 6842, -3631, 362, 5029, 8052, -2367, -5346, 5724, - -358, 2469, 2196, -1426, -272, 534, -192, -531, - -705, -70, -259, 93, 335, -94, -145, -17, - 920, 1186, -818, -599, 343, -19859, 2968, 161, - 128, -4282, 598, 152, 1210, -1317, -1545, -229, - 181, -6488, 5699, 7270, 6271, 8809, 27, -4770, - -804, -168, -247, -680, -129, -470, -152, 915, - 176, -904, 622, 280, 2986, 1034, -1046, -482 -}, - -.cb4440s0 = { --12085, 8192, -1802, 4587, 5947, -3183, -2629, 1837, - 2434, 252, -612, -4697, -576, 150, -704, -640, - 174, -126, -10309, 350, -3187, 4714, -2829, 12618, - -2172, 3502, 465, -159, -601, 1306, 1174, -448, - -292, -136, 242, 31, -9005, -6203, -10027, 25, - -209, -20, -1292, -1252, 4304, 3681, 4462, -4401, - 4412, 1240, -576, 3618, 595, -237, 2544, -6032, - -1511, 1523, -3668, -3472, 5552, -4901, -272, 5963, - 2740, -878, 13010, 191, -2017, 768, 455, -45, - -6873, -3664, 2639, -961, 3068, -4242, 1327, 2362, - -1909, -1114, 100, -5940, 220, 865, -12952, -76, - -1279, -591, 1092, -3502, 88, -2118, 13053, -10141, - -3024, -533, -1923, -4097, 135, 1672, -1661, 1646, - -370, -361, 644, -197, -6796, -10948, 11692, -974, - 488, 349, 3936, -1506, -149, 513, 1401, -1776, - -391, -210, 57, -56, -344, 1018, 7989, -4957, - 167, 987, -60, 62, 1622, 1207, -69, 338, --16133, -46, 1018, -1460, -821, -646, 1316, 126, - -4631, -842, -1505, 15833, -6404, -4514, 2946, 2923, - 1198, -3141, -3109, -1613, 1853, -906, -436, -1110, - -282, -214, -3424, -3141, -3988, 284, 22262, 1269, - 1787, -1116, -1429, 1017, 371, -187, -825, 534, - 350, 1088, 26, 176, 8914, 6662, 935, 2074, - -7986, -4780, 2194, 1796, 697, -4040, 2486, 1700, - 9150, -37, -1560, 2449, -162, 128, -7469, -2690, - -281, -4698, 424, 535, 1416, 243, -575, -1160, - 326, -2417, 808, -15816, 994, -302, 26, 894, - -7376, 395, -586, 823, -1341, 972, 100, 241, - 743, 470, 267, -550, 474, 182, 18252, 178, - -182, -7, 3496, 2132, 863, -151, 741, -2158, - -763, -652, -503, -434, -736, 770, -156, -19071, - 443, -354, -243, 66, 4258, 6714, 3577, 17338, - 556, -3570, 1269, -1406, 1668, -349, -90, 781, - 82, 558, 936, -788, -1072, -21, -6472, -3022, - -475, -6997, -2816, -3774, 1683, -13950, 3482, -1872, - 2624, 1064, -318, 1300, -1214, 179, -11, -124, - 4560, -2827, -6314, -5736, 1159, 1309, -5462, -11652, - 4192, 151, -543, -3484, -2288, -119, 745, 1373, - -121, -629, 5204, 7650, -2062, -3370, -2894, -338, - -1361, 1080, -3674, 12852, -6119, -1578, -736, -241, - -1564, -109, -441, 335, 416, 1678, 4802, -3239, - 6182, 154, -3656, -1337, -17027, 1707, -381, -1704, - -377, 1022, -592, 983, -321, 37, -1846, -4500, - 2575, 14162, -560, 9385, 4179, -1340, -3466, 3235, - 1727, 1545, -23, 636, 280, -39, 871, 173, - -8915, -2427, 2146, -3698, -12153, -3773, -3873, 5042, - 112, 788, -1139, 245, 546, 278, -8, -1005, - 443, -76, -1256, 8255, 3841, 6116, 4226, 3705, - -1278, -6470, 5220, 5892, -3468, 2736, 5427, -3336, - -264, 1906, 294, -60, -7078, 7699, -9792, -7108, - -2030, 1055, -6962, 702, -2074, -232, 127, -430, - 658, -272, 757, 138, 159, -340, -4606, 1021, - 146, -7690, 6001, 5660, 3363, -367, 13222, -441, - 13, -874, 668, 2293, 875, 1238, 110, 778, - 1434, -976, 2151, -8169, 1421, 2622, 206, -795, - -816, -14443, -1583, 3356, 2971, -964, -321, -841, - -404, 111, -5595, 4248, -3819, 214, -2520, -712, - -1505, 849, 947, -876, 188, 3221, 863, 105, --17336, 1818, 14, 17, -6349, 379, 4746, -12405, - -560, -3448, 3664, 8251, 845, 383, 1348, -739, - -780, 1695, 4828, -123, -647, 823, 9940, -183, - -1804, -7112, -161, 578, -619, 11534, 3214, 1586, - 4784, -2540, 1188, -304, -485, -648, -824, -595, - -8817, 4138, 927, -3259, -198, 4022, 2213, -1627, - 645, 14602, -1058, 1481, -1670, -113, 564, -710, - -451, -360, -1261, 2504, 247, 5566, -7262, 1344, - -5106, -1608, 1946, -4240, -7393, 10440, 3306, 1940, - -999, 155, 832, 55, 10218, 11475, -3252, -8295, - 1347, 2405, 3421, -2619, 2262, -2829, 754, -307, - 548, -2040, -1130, 317, 170, 292, 248, 2601, --18930, -1942, 1417, 1678, 3310, -2578, -1969, 1550, - 3010, 70, 8, 3064, -848, 504, -172, 180, - 1787, -1133, 2427, 1002, -664, -40, 192, -23400, - -1004, 513, -818, -382, 360, 360, 268, 98, - -202, -192, -668, -12924, -11702, 7325, 797, 1937, - 674, -2458, -541, -1497, -1673, -955, -356, -486, - 182, 299, -46, 65, -4232, 1418, 6532, 2356, - -4894, 4870, 3369, -4585, 8743, 1497, -1451, 862, - -8612, -1718, 1716, -2389, 371, 592, 7397, -3188, - -649, 126, -1300, 1374, -1292, 645, -1494, 2736, - -1468, -1808, -17223, -352, 111, -222, -236, 171, - -198, -7994, -3822, 5324, -16856, -517, 119, 314, - -360, -515, 435, 520, -638, 1635, 420, 1191, - 830, 710, 6897, 2925, 3091, 510, 3268, -1702, --16186, 718, -3127, -463, 763, -1035, 725, -122, - 646, 172, -164, -277, 5853, -7074, -10, -1770, - -2544, 5978, -874, -494, -232, 14465, 1815, -1902, - 987, -1533, 1216, 741, 620, 161, 4414, 4184, - -32, -2944, -4619, -462, 15701, -1026, -140, -2396, - -1747, -538, -1024, 219, 854, -351, 860, -226, - -4390, 732, -2003, -2430, -540, 592, 1622, 1180, - 385, -2052, 4050, 17401, -650, -243, 1709, 1261, - 95, -307, -5110, -666, -7094, -533, -1293, -17357, - 2929, 2389, -119, -413, 317, -962, 709, -1552, - 26, 175, 700, -570, 20120, 1107, 232, 169, - -889, -533, -1276, 22, 959, 866, -954, -792, - 873, -172, 1757, 195, 148, 423, 4490, 8782, - 631, 682, 1832, -3728, -1742, -11130, -1201, 1776, - 9268, -586, -1358, -646, 626, -866, 5, 263, - 3950, -760, -2914, -12751, -12669, 1513, -4, 631, - 1835, 312, -167, 1546, -532, 619, 1176, 1436, - -116, 312, 7054, 3120, 4075, -1320, 715, -206, - -1572, 1350, 17688, -1182, -1568, 680, 6, 207, - 1010, 600, -766, 554, -1483, 644, -8810, 624, - 148, -4015, -1536, -1863, 92, 730, -14806, 386, - -5174, -1420, -331, -254, -104, 275, -7268, 2563, - 11983, -65, 8043, -1623, -2589, -2610, 1328, 3154, - 1935, 3672, -1761, 4984, 661, 209, -1038, 122, - -1019, -28948, 55, 358, -539, 488, 55, 618, - 20, -314, 446, -1016, 618, -93, -94, -331, - -36, 194, -1706, 6628, 396, -146, -765, 10500, - 2619, -82, -10894, -3908, -888, -192, 620, 163, - 78, 774, -293, -104, -4826, -14066, -1883, -3258, - -4577, -1484, 5412, -4274, -4951, 3316, -907, 1948, - -1187, -404, 3654, 400, -70, 459, -3224, -3194, - 2338, 4390, -5, -3167, 3273, 116, -1026, -1668, - 3767, 272, -16662, 137, -1634, -1007, 220, -310, - 982, 8220, -16, -1251, -2644, -3344, 2236, -1573, - 8174, 612, 1142, -10799, 393, -707, 4804, 397, - 1232, -292, 5762, -15608, 2921, -6440, 3544, -2395, - -504, 1890, 172, -1010, 178, 380, -1163, 404, - -1230, 1034, -596, 105, -2038, 1991, 5613, -312, - -4156, -10205, 3092, -4704, -6101, -1620, -1037, -1130, - 1590, 8321, -797, 247, 954, -103, 3838, 2330, - 10064, 3197, -8508, 1300, -1012, -6607, -3861, 5651, - 31, -475, 1582, -1370, 1107, 2164, 743, -567, - 4842, -2930, 3191, -190, -2230, -47, 254, 2147, - 591, -512, 1312, 1159, 811, 1444, -1312, -257, - 16016, 789, -2562, 3983, -373, -9255, 302, -3655, - 5750, -3856, -6941, 3934, -2314, 5556, -4099, -265, - -479, -4843, -130, 20, -4859, 3083, 6482, -3738, - -3936, 590, -6368, -1784, 75, -3903, -6834, -4452, - -871, 764, -1118, 8731, 38, -148, -3368, -6330, - -370, 2234, 907, -2809, -1458, -2306, -402, 2679, - -1222, 1138, 192, -1317, 1012, 15514, 624, 279, - -4032, 2565, 6162, -938, 5760, 1685, 4350, 2939, - -825, -331, 1840, -556, 427, -4642, -23, 8346, - 7577, -467, 3848, 454, -3962, 373, -116, 2314, - 4868, -208, -1367, -1803, 2681, 806, -4279, 3348, - -528, 14027, -238, -457, -2764, 832, -4680, 4354, - 1219, -801, 2414, -5204, -3768, -6524, 5163, -10909, - 1656, 321, 3260, -1773, 214, -135, -4563, 5206, - -4794, 1486, 406, -1026, 281, 1799, -218, 320, - -908, 872, 1056, 2955, -208, -799, 15492, 334 -}, - -.cb4440s1 = { - 27498, -414, -266, 646, 229, 94, -15, 302, - -489, -401, 125, 752, -476, -200, -976, 195, - 4, -402, 2220, 1012, 1731, 2530, -652, -21380, - -679, -867, -195, -114, 1326, 2531, -348, -185, - -114, 178, -694, -298, 8752, 1735, 2640, -2374, - 6191, 1516, 5771, 6705, -253, -8502, 986, 2134, - -1854, 3490, -678, -48, 133, 844, -1635, 1630, - 6056, -756, -1109, 1563, -1445, -139, 580, -1448, --18675, 846, -390, -259, 1548, -324, 281, 142, - 1792, 1211, 1328, -4308, -1032, -5412, 4742, -201, - -47, -297, -8403, 9715, 7268, -3756, 1573, 677, - -88, -145, 4877, 12946, 3264, 1809, 7230, -2583, - 1627, -1786, -7113, -1480, -2111, -508, 415, 1664, - -483, -538, -249, 80, 7005, -2562, -887, 3801, - 6411, 2222, 36, 875, -5089, 10897, 4014, 4948, - -1580, 1425, -1814, -391, -96, 322, -6484, 1896, - -7790, -950, -4235, -8362, 3118, 4843, 3754, 1070, - -1648, 7692, -1675, 3405, 918, 2270, 573, 193, - 6024, 8912, -4905, -1810, 985, 1877, 2158, -2150, - -386, 3908, 2030, 419, -12599, -570, -150, 1580, - 36, -152, 2, -538, -1565, 6809, -715, -6266, --12725, -6718, 810, -603, 1547, 1001, 2250, 810, - 1773, -672, 327, 246, 6414, -7511, 916, -327, - 830, 11862, 4373, 1003, 6370, -1730, -2127, 613, - 1627, 626, 763, -864, 207, -233, 3738, -8644, - -1634, -2050, 3906, -451, 12986, -4828, -2973, -4714, - 545, 822, 735, -3539, -256, 65, -93, -94, - 2923, 7075, -3763, 6172, -9544, -2675, -3833, 930, - 418, -4496, 3790, 386, -7797, 234, -609, -259, - 454, 330, 1546, -7634, -1966, 515, -2496, 374, - 2633, -3014, 4126, 9920, -7103, 1441, -150, 7695, - 670, -48, -41, -512, -6849, -1785, 3755, 1860, - 2418, -2346, -1194, -1574, 15510, 444, -1515, 585, - 742, -199, -1115, -122, -11, 140, -7763, 1438, - -317, -444, -17149, -24, 2685, -856, -3166, 1109, - 308, 233, 30, 63, 530, 645, 84, 133, - 6139, -1183, -10673, -12790, -112, -1544, 4623, 576, - -804, 1023, -1646, 1192, 269, 2681, 44, -909, - -14, -414, 48, -4002, 4768, 3440, 3252, 1441, - 101, 372, 3166, -1398, 325, 16184, -711, 486, - 1328, 114, -450, -31, 1152, 2154, -69, -252, - 32, 922, 219, -2055, 421, -1377, 1006, -614, - 234, -40, -84, 204, 27171, 182, 1034, 1536, - 834, -8038, 1243, -3074, -7829, 11165, -1854, -1173, - -871, 4105, 3588, -3191, 188, -2102, 124, -166, - 8070, -11066, 6632, 2739, -7787, 184, -5872, 1360, - -1089, 1273, 84, -1683, -1584, 975, -206, 1160, - 180, 12, -6121, 5436, -14726, 5949, -6756, 834, - 1750, -3142, -878, 7, -220, -1933, -141, 160, - 26, 756, -800, 6, -8104, -6989, 3353, -3518, - 4510, -12430, 736, -2685, -1042, 32, 1184, -519, - -312, -1073, -402, 71, -422, -35, 1791, 12735, - -2281, 2623, -1502, -3878, 6727, 10541, -1110, 2308, - 870, 1124, 874, -1406, 123, 254, 405, 328, - 3828, -7541, 3096, -14145, -672, -1725, -423, -1918, - 4164, -411, 3094, -568, 3575, -2895, -378, -3065, - -232, 449, 8110, 2264, -1383, -557, -10683, -7628, - 4155, 754, -134, 6759, 1051, -2054, -900, -948, - 579, -1277, 151, 462, 11562, -310, -8260, 10238, - -1309, -3052, 345, -689, -1133, -588, 548, 980, - -1332, 881, 368, 776, -704, 422, 12433, 1314, - -1487, -4753, 2679, 3092, -939, 136, -586, 3504, - -1034, -6318, 3506, 420, 2326, 1034, -252, -398, - -6232, 4488, -6166, -1754, 908, 4884, -5188, -2985, - 10793, -116, 4674, 3980, -9, 805, 1568, -1620, - -88, -146, 3027, -16154, 2899, 7839, 5912, -427, - 270, -1467, -387, -351, 615, -322, -2, -1061, - -654, 56, -438, 132, 2388, 460, 2172, 1874, - -3028, 3302, 2035, -704, -1222, -19835, -472, -1858, - -1686, -286, 5, -748, 491, -350, -4344, 103, - 1473, 2440, 13575, -1350, 1456, 10377, 1962, 3036, - -1238, 1580, 607, 1352, 997, 1212, -489, 251, - 4075, -3457, 6186, 786, 300, -2532, -373, -2522, - 3108, -294, 4938, -2980, 1509, 12450, -695, -1128, - -96, 354, -3678, 8494, 2480, 2264, 5162, 11907, - 4721, 1111, 752, 2999, 3924, -1429, 321, 276, - 309, -603, 601, -62, 3337, -3570, 3273, 6618, - -2001, 950, 532, 972, 1619, 956, 65, -609, - -281, -14769, -438, 580, 230, -228, -10108, 12289, - 8904, 872, -3296, 1535, -384, 477, -913, -777, - 546, 445, -1004, -435, -716, -138, 572, 435, - 4626, -864, -5716, -2810, 1291, -4796, -241, 2527, - -2342, -1360, 4161, 1886, -128, -1521, 13726, 1818, - -554, -157, -9665, 2607, -1013, 579, 1122, 1571, - -2684, 11364, -6464, -184, -1542, -5670, -1091, -670, - 1273, -1051, -7, -278, -2551, -548, -10673, -1434, - -343, 317, -3108, -1615, -2239, -14132, 490, -454, - 2467, 1990, 470, -1072, 440, 290, 3006, -4420, - -2083, 3050, 2779, -2349, -590, -4941, 7464, -9000, - -2686, -2045, -8712, -3281, -2476, 648, -148, 408, - -1367, -1113, 27347, -1113, 739, 39, 1443, -208, - -686, 986, 735, -702, 76, 665, -194, -165, - 366, -606, -4908, -3932, -15941, -2810, 4572, 816, - -2092, 4213, -2492, 4006, 926, 210, -1110, -1635, - -270, -226, -362, -187, 1790, 3016, 2216, 3890, - 2018, -1325, 19784, -771, 356, 2118, -98, -688, - 1016, 978, 559, -39, 160, -310, 6622, -1754, --11104, 204, -2212, 2370, -11610, 1119, 3216, 3102, - 524, 278, -829, 524, 28, 838, 374, -76, - -4593, -2933, 10697, -6510, -4970, -2025, -9383, -3428, - -4112, 2665, 1459, -1411, 421, 481, 842, -341, - 147, -158, 4108, 45, 4935, -21, -7905, 2058, - 1158, 15260, -567, -752, -992, -1094, -1059, 2370, - 820, 655, -261, 280, -3969, 6342, 8521, 3114, - 369, -12269, 1684, 4, 4686, 1985, -3668, -3040, - 677, -254, 57, -161, -989, -379, 7075, -580, - 2846, -3177, -2285, 958, -7096, -154, -515, -3345, - 13487, 3548, -1804, 290, -430, 726, 399, 54, - -2814, 10235, 1958, -3356, -1330, 536, 3218, -14194, - 200, -796, -862, -1480, 1811, -346, 604, -391, - -231, 513, -10495, -6029, -6492, -8746, -357, -221, - -1890, -2669, 8, -1756, -5812, -1048, 2258, 223, - -474, 1154, -226, 348, -1590, 2915, 158, -24059, - 875, -846, 1150, -1000, -844, -116, -246, -219, - -482, -367, 120, 517, -489, 442, 8148, 5040, - 3770, -1006, -51, -3175, -10278, -4468, 1188, 1497, - -6515, -5, -1628, -2387, -1297, -717, 1630, 232, - -3608, -6688, 2444, -792, -246, 411, 1464, 3661, - 3244, -1121, -1602, -15398, -443, 882, 1412, 926, - 16, -73, 2693, 7168, -9399, 528, 7916, -9270, - -1669, -2756, 1304, 3074, -1510, -2089, 1491, -1556, - -422, -414, 132, -192, 5988, 4500, 7572, -10978, - -4875, 3685, 1888, -660, -1750, -515, -2728, -3133, - -2742, 666, -2861, 626, 256, 243, 4587, -3567, - -288, 2314, 4765, -11036, 7322, 7581, 2651, 3264, - -394, -246, -891, -1464, -1717, 123, -517, -486, - -1019, 7215, 554, 722, -4253, 2393, 3053, 2881, - 1538, -2104, 573, 321, 673, 3902, -2855, 944, --12816, 370, 3496, 952, -1435, 6379, 766, 2273, - -729, 80, -2432, -1150, 2408, -895, 15497, -1231, - -282, -3306, -435, -167, -3528, -5683, -6413, 2501, - -4825, 124, 3128, -425, -2800, -986, -2283, -495, - -3392, -1560, -2093, -11613, -37, 157, -438, -794, - 1988, -45, 1508, 20, 98, -458, -245, 1130, - 110, -525, -771, 1120, 710, -21758, 174, -210, - -4839, -2468, -648, -4388, -11, 2990, -181, -4790, - -4232, 3634, 6427, 2772, 166, -2996, -12005, 1630, - -249, 179, 856, -1250, -4216, 1993, 5164, 4757, - -5071, 4331, -3029, -1276, -11184, -2864, 1238, 6332, - -2431, 1276, -338, -476, -5659, -2410, 2510, 1853, - -4853, -3175, -1896, 10728, 3724, 960, 9963, 305, - -938, -646, -2760, 1436, 113, -74, -3098, -4090, - 2950, 2701, 992, 206, -1393, -2179, -10862, -2396, - -1008, 2639, -1547, -416, 9264, 1824, -360, 401 -}, - -.cb4440m0 = { --25793, -238, 1193, -2635, -238, 1315, -2277, 1588, - -896, 512, -864, 611, -398, 1277, -212, -358, - 202, 13250, 16, -860, 1618, -1024, 310, 11560, - -746, -3876, 780, -4087, -475, 857, 1017, -1439, - -890, 155, 8556, 362, -1158, 2116, -291, -66, - -1272, 510, -1394, 2259, -4761, 808, -740, -937, - 13993, 191, 273, -7670, 6776, 846, -1907, 955, --13206, -1956, 1697, 1670, -329, -244, 2395, 6119, - -802, -1007, 649, -974, 170, -2136, -10780, 1020, - 1270, 1954, 1118, 13348, 983, -1394, -594, -514, - -586, 1026, -1821, 548, -298, 3342, 837, -1395, - 13977, 1021, -7792, -2930, 1466, 5494, -843, 2432, - 1378, -68, 174, 407, 76, -877, 691, -9445, - 522, -3448, 2549, -412, -2358, 875, -5044, -952, --10113, 6574, -6347, -2760, -662, 29, -227, 4884, - 1304, 411, -3320, 2434, 785, -14822, 4412, 2272, - -6407, 2172, -613, -1665, 296, 742, 624, 135, - 5316, -3191, -855, -2061, 485, -3188, 2998, 1382, - 2516, -2438, -3506, -238, 737, -629, 1001, 773, - 17540, 1478, -724, -764, -1231, -1254, -1582, -692, - -351, -1551, -171, 183, 38, -668, 756, -770, - 24344, -905, -7182, 502, -3766, -1690, 1588, 1522, - 1844, 1276, 1458, -777, 1731, 4856, -14860, -1097, - 36, -1310, 846, -1500, 521, -3669, -252, 4480, - -2602, -845, 597, -4512, 1062, -292, -18518, 1972, - -334, -80, -1256, -366, 3640, -436, -12, -1670, - -435, 1496, 1429, -11092, 1012, -936, -1224, -12240, - -3048, 210, 1905, -1197, -357, -9759, -2632, -332, - -3417, 15078, 1496, 2206, 1800, 205, 1384, 3546, - -1853, 755, 1016, 726, 58, -150, -13053, 10375, - -2589, -330, 1616, 3081, 2763, -2617, -1204, 324, - -53, 2968, 1485, 214, 124, -334, -237, 16784, - 2612, 1023, -4298, -2156, 4336, -4307, 4952, 1036, - 81, -762, 3416, 714, -187, -4100, -757, 1124, - 10224, 7059, 424, -316, 1281, -12262, 912, -1999, - 2, -731, -184, 879, -934, -202, -391, -1046, - -338, -101, -17511, -1712, -5580, -2327, -2478, 1770, - -5825, 1499, 578, -130, 1424, -1818, 110, 542, - 22, 988, -4227, 2836, -1447, 1170, 12335, 2179, --11216, -2500, 64, -912, -954, 654, -802, -455, - -597, 234, -296, 811, 1083, 1848, 4148, 637, - -6608, -2362, -3382, -664, -13088, 2839, 3090, 3294, - -4554, 2518, -55, 837, 1392, 5905, 1287, -1484, - 965, 16533, -3507, -1903, -1562, 2408, 5037, -4816, - 1409, 361, -1890, 170, -610, -1755, -524, -867, - -6238, -20117, -745, -956, -176, 2998, 130, -668, - -843, -267, -364, -573, 495, 127, -66, 32767, - 271, -408, 654, -123, 1831, 151, 996, 82, - 628, -251, 144, 198, -88, 357, 37, 612, - 184, 238, -584, -52, -30025, -415, 404, -566, - 100, 659, -336, 877, 211, -730, -377, 184, - -5256, -1484, -1191, -2108, 24, -7821, 209, -2856, - -1844, 697, 5798, -1191, 427, 11858, 1000, -261, - 184, -686, 1182, -3142, -3138, 139, 144, 117, - 3658, -3566, -1562, 672, 2036, 15051, -5069, -551, - 529, 1696, -214, -2678, -5966, -3707, 2847, -2554, - -1760, -1196, 2088, 6372, 1778, 12935, 2189, 1992, - 1761, 578, -542, -753, -1182, 4321, 1871, 309, - 704, -1259, 884, 19136, -2665, 1096, 3048, -167, - 872, -344, -1092, 464, 3255, -86, 1608, -1062, - -1569, -1699, 4504, -274, 568, 1428, 20571, 1452, - -894, -791, 459, -882, -1048, -2944, -11095, -783, - -832, -2450, 650, 2784, 3156, 529, 457, 483, --12553, 655, 686, -757, 929, 212, 1242, -201, - -1627, 4826, -1895, 997, -3225, 84, 80, 287, - -2136, 405, -188, -890, -18272, -511, -118, -3642, - -1018, 420, 12650, -474, -540, 6978, 6977, 4418, - 1162, -1332, -1112, -1765, 2640, 562, -1164, 1256, - 595, 567, -483, -31511, -960, -816, 756, 1505, - 12, -518, 234, 184, 679, 328, -600, -137, - 267, -440, 2540, 593, 1023, -11756, 626, -2034, - 5756, -9882, 3175, -1190, 1628, 3920, 3219, 1394, - 834, -140, 4036, 4722, -455, 3105, -1355, -3106, - 1000, 7806, -2227, 687, -1580, 3180, -12302, -1394, - -425, 488, -187, -36, 219, 158, 12006, 1683, - 2151, -2, -1110, -12250, -59, 672, 1844, 2084, - -2101, 1652, -783, 634, -13257, -339, 3932, 2260, --12452, 152, 316, -688, 79, -912, -2081, 1384, - 188, 1942, -706, 204, 700, 1776, 13901, -13666, - -324, 472, 1055, -646, 82, -769, -877, -443, - -227, -900, 636, -870, 470, -112, -598, -4402, - -2726, 1775, -216, -43, -18675, -863, -4604, 3433, - 674, -155, 208, 1546, 294, -157, -616, 11070, - 1229, -528, 2124, 699, 3624, 54, -516, 194, --13556, 1902, -506, -1317, 1916, 471, -342, 836, - 18, 906, 614, -8, -951, 1052, -97, 2212, - -924, 310, 6, -733, 122, 23731, 468, 345, - 1545, 1434, 611, 403, -3136, -2214, -54, 1023, - -1390, -5243, -3744, -258, 6871, -1778, 673, -2362, --13007, -776, -974, -1077, 8386, -3978, -4325, 1236, - 4011, 1161, -263, 1224, -12957, -100, 2801, 1458, - -3081, 578, 17, 1037, -742, 5972, -632, 2904, --12721, -6733, -478, 182, -1973, -820, -6911, -4904, - -942, -348, -353, -350, 7864, 34, 568, 1985, - 956, 3310, 118, -2067, 12600, 9063, 1609, -1261, - 296, -1248, -1656, -65, 1832, 1525, 1503, 5149, - 4370, -1638, -3868, 320, 1527, -424, 17676, 1780, - 1172, -1132, 1128, 1294, -322, -101, 462, -6668, - -3024, 7573, -11088, 1581, 13, -1398, 550, 4376, - 1623, 1727, 857, -5310, 2528, -529, -401, 539, - 6508, 4246, 4105, -5363, 96, -13407, -694, 5061, - 3445, -3283, -348, -1470, 1114, 602, -404, -129, - 642, 1547, 23110, -2255, 1969, 333, 1297, 116, - -1691, 364, -528, 758, -1239, -1826, -249, -395, - 684, -856, -638, -10000, -2773, -6151, -1244, -3138, - -9688, -1994, 7124, 1368, -1870, -312, 1863, -1006, - 963, 789, 743, -4158, -760, 1384, -7525, -959, - -262, 5752, 4005, -12037, -210, 886, -1961, 4895, - -251, -158, 212, 677, 518, 342, -226, -360, - 466, 17, 28392, -20, 246, -686, -258, 640, - -378, -120, -443, 1078, -2612, 2084, -1706, 4334, - -4675, -4634, 2336, -9998, 9975, -1285, 2778, 3292, - -1717, 138, 2114, -1120, -180, -1146, 11988, 829, - -2530, -8827, 6833, -1191, -1653, 2691, -4067, 1166, - 1971, 303, -544, -1459, -261, 1065, 3410, 2050, - 3163, -515, 5456, -4261, 5483, 1531, -2098, 2020, - 3773, 588, 915, 158, -11876, 282, -1180, 265, - 11036, -66, -1741, -1894, -4234, 3048, 218, -1030, - 2240, -12666, -2290, -1673, -1911, 1480, 287, -81, - 1182, 216, -10734, 2201, -58, -619, 8585, -574, - -4576, 1852, -468, -6759, -7667, 167, 995, -1114, - -1276, -2053, 2178, -8133, -1270, -7822, -10582, 5380, - 3037, 1071, 827, 4972, 1024, -129, -180, -3002, - -846, -736, 9587, 1890, 10287, -1954, 1042, 1558, - -950, 2406, -1852, 2275, 6694, -703, -910, 3854, - 812, 521, -1075, -761, 5357, -3911, 3892, 7944, - 4580, 5031, 1088, 7116, -1746, -5223, 2607, 3227, - 2296, 5603, 211, -731, 6450, -3312, -12378, -326, - 4245, 4168, -799, -3563, -505, 725, -5297, 2196, - 2221, -16, -3472, 315, 626, -6131, 71, 920, - -4383, -1340, -2675, -664, 7412, -1240, -1361, 997, - -3817, -2377, -11717, 1661, 22, 540, -5261, -950, - 7472, 3148, 7647, -4400, 4558, -4412, -869, -1528, - -2618, 8311, 2110, 534, -460, -223, -162, -828, - 274, 1844, 1861, -1583, 6899, 5222, -1772, -2880, - -6400, 4703, 2606, -3990, -1224, -4160, 9032, -299 -}, - -.cb4440m1 = { - 32767, 383, 857, -1579, -423, 1164, -1606, 1218, - -410, 777, -292, 122, 282, -74, -1394, 259, - -734, 102, -82, 32616, 427, -545, -146, -141, - 340, 506, -808, 171, -778, 900, -204, -277, - -228, -426, 566, -481, -1138, -907, 112, 2722, - 871, 115, -7202, 1953, -826, -1812, -396, -14722, - -840, 155, 1114, 5624, 1112, -147, -6383, 926, - 1505, 360, 937, -13391, 969, 7062, 2218, -3531, - 471, 458, 191, -465, 8664, -1168, 546, 2109, - -944, -74, 1644, -81, -760, -1920, 2659, 13330, - 1511, -1148, 1346, 796, -20, -15616, 1246, -1190, --10882, -774, -70, 3643, -896, 1830, -192, 1018, - 1085, -95, -309, 659, 91, 727, -4486, 486, - -2078, 1235, -14415, -4053, -1619, -2589, -582, -4650, - 4076, -762, -1111, 277, 1448, -742, -314, -979, - 1889, 2679, -1972, 2480, 302, 2869, -9183, -445, - -1817, 12894, 106, 187, -1406, -615, -1174, 746, - -371, 382, 350, -1811, -527, 36, 500, -835, - -106, 1134, -2207, 1021, 348, 908, -21780, 448, - 688, -60, -1790, 1901, -22990, 1467, 596, -912, - -3190, 1484, 269, -409, -474, -1670, 1328, 152, - -402, 359, -734, -13208, 62, -4197, -6242, 5195, - -2841, 5030, 2794, 1264, -1130, 3821, 961, 729, - 1075, 49, -148, 7267, 2596, -5093, -8284, -6875, - -3059, 3909, -4635, 1402, -6334, -342, -3083, -861, - 490, 1257, -630, 128, 2240, 832, 1060, -1802, - -1652, 128, 7816, -14391, -6722, -3328, -2586, 3044, - 1088, 1577, 852, -142, -176, 1371, 1236, 976, - 12165, -1596, -199, -504, -11020, -582, 972, -1468, - -2402, -666, -3327, -2148, 1078, -194, 9675, -2102, - -1236, -70, -942, 291, 1364, 1403, -3362, 12963, - -375, -1728, 1615, -2354, 633, -506, -194, 13037, - 14172, 534, -1026, -425, 2488, -180, -678, -436, - 272, 1507, -334, 840, -1000, -1068, 1029, -306, - 24, -4435, -5994, -1307, 4251, 3968, 2527, -981, - -2626, -4400, -242, -1823, -679, 12831, -22, 51, - -381, 2422, -2376, -8156, -1477, -6974, 1102, -373, - 467, 11314, -554, -432, 824, 7277, 393, -178, - 179, -653, 11848, -1593, 14143, -731, -1036, -2322, - 261, -1992, -1152, -1430, -1354, -51, -285, -1637, - 144, -59, -2182, 5731, 538, -880, 397, 3010, - 707, -1822, -1006, 4686, -5096, 4246, -3096, -3997, - -254, -11025, 394, -345, 18780, -686, -517, -3422, - 104, -2173, 2439, -5400, -10, 1084, 1821, -602, - 1431, 405, 2143, 499, 405, 351, -62, -47, - 1954, -29915, 440, 1054, 559, -1210, 442, 928, - -1, 59, 279, -112, -110, -440, -396, 805, - 311, 858, -431, -1070, -30192, 135, 1246, -345, - 790, 498, 319, -302, -469, -10, 512, -829, - -526, -2052, 2456, 134, -19375, -1210, -1292, 640, - 3232, 2580, 973, -2412, 271, -282, 632, -523, - -847, -138, -990, 2501, 536, -166, 2100, -357, - 122, 466, -4, 2034, 20083, 1578, 444, -344, - -689, 5733, -456, -503, -592, -1350, -1038, 932, - -1916, 1098, -990, -22687, 1544, -442, -396, -570, - -683, -616, -1431, 118, 4113, -312, 2300, 2093, - -2344, -2955, 6343, 4306, -10078, 6286, -5794, -806, - 664, -217, 548, 5072, 4626, -1643, -11619, 779, - 1956, -2960, 614, 2087, 9104, -2418, 775, -4447, - 768, 1599, -1084, 999, 1652, 1090, 630, -1197, - -3495, -912, -9817, 648, 3278, 1828, 13605, 2757, - -831, -1191, -1846, -1441, -278, -8530, -455, -495, - 323, -911, 2500, 14100, 3635, 1016, -936, 5265, - -3092, 2125, -121, -64, -656, -337, 9438, -7600, - 1403, -11917, 2180, 2612, 1664, 1091, -318, -3300, - -427, 282, 1979, 894, -703, 514, 160, 1697, - 6508, 828, 187, -34, -1094, -2861, 240, -5013, - 6004, -4796, -991, 158, 11437, -1730, 354, 1195, - 3790, -10432, -3584, 13872, 336, 2043, 221, 604, - 2930, 1080, -1417, 1878, -878, -459, -419, 364, - -1037, 7764, 3100, 48, 11057, 1936, 2229, 9150, - -472, 1178, -129, 2876, -249, -258, -1181, -329, - -581, -1140, -1967, 347, -539, -394, 775, -1151, - -31, 1052, -1900, -213, -1552, 22484, 164, -113, - 135, -1294, 550, 7738, -7223, -739, 1362, 5518, - 193, -2170, -11861, -1357, 351, 2215, 165, 16, - -606, 727, -158, -772, -13420, -1248, 12422, -812, - 1768, -442, 1269, -1076, 899, 124, -249, -1110, - 653, -3064, -1632, 839, -230, 512, 642, 13230, - 13285, -552, -1113, -595, 864, 537, -1012, -539, - -615, -491, 1014, 800, -10, 534, -1227, -25011, - 1239, -26, 3834, 104, 762, 1259, 2112, -300, - -920, -812, 612, -1061, -378, -246, -7, 11042, --18492, -1411, -77, 407, -556, 218, 1751, 1069, - -294, 1789, 904, 285, -76, 300, -160, -128, - -3398, -2001, 1689, 4946, -2750, 1427, -12632, -1873, - -1802, -1115, -2777, -4436, 2937, -6408, -467, 487, - 1043, 3914, -81, 1540, -11718, 1368, -12656, -583, - 1009, -416, 249, 1874, 1157, 994, -858, -154, - 294, 333, -26, 73, -1576, -20, -560, -1068, - 1325, -588, 26161, 1580, -411, -587, -1083, -79, - 762, 292, -622, 788, 284, 2014, 78, 554, - -516, 1340, 835, 300, -24827, 558, -705, -22, - 139, -159, -246, -585, 4318, 234, 1308, -198, - -3370, 5724, 2381, 13843, 4, 569, 8002, 1188, - -63, -1698, 4624, -405, -218, 4238, -888, -1180, - 3750, -4848, -9497, 293, -1087, -13274, -33, -2870, - 457, -618, 338, -34, 286, 345, -5321, 904, - -5656, -2082, 12644, -7423, 532, 958, -1997, -1483, - -2982, 3115, -1851, -2025, 1853, -918, -903, 1554, - 540, -16549, 1441, 2939, -1272, 3106, 2374, 3906, - -697, 1144, 750, -379, -6502, 980, 386, 36, - 1109, 1195, 6272, 4264, 1501, 5369, -1560, 3535, - 1084, 739, -1031, -4400, 8452, -430, -1787, -7669, - -231, -115, 4324, -1820, -2098, -786, 7478, -2709, --14255, 5771, 115, -1700, -111, -1482, -1369, -112, - 122, -472, 233, 2427, 1816, 180, -481, 928, - 82, 84, -700, -448, -946, 1968, 1644, 168, - -167, 16164, 155, -10316, 941, -584, 488, 96, - 5205, 491, -1844, -13055, 1266, -352, -836, 558, - 1546, -1720, 313, 2033, 597, -14351, 4426, 3281, - -559, 2614, 3248, -2265, -10312, -1614, -288, 480, - 1419, -546, -485, 835, 960, 462, 923, 6518, - 834, -711, -12639, 8811, -207, 1806, 337, -1240, - -4796, 2383, 277, 1141, 969, 59, 197, 1365, - -614, -9144, 4824, -436, 4191, -2588, 4509, 391, - -5055, -3231, 6978, -6388, 51, 105, -863, 1050, - 13103, 12769, -420, -1562, -123, 2702, 292, 1061, - 123, 405, 1917, -275, 493, -95, -195, 130, - -2613, 9010, 196, -1382, 5903, 7281, 1585, 2557, - -876, 3166, 6910, 590, -3060, -559, 4722, 393, - 613, -392, -3022, 9892, 1808, 923, 8123, 9873, - -1665, 2349, 2894, 591, 2000, -3734, -917, 220, - 408, 296, -656, 2608, -1700, 400, -10734, 5434, - 6504, -1399, 2175, -1203, -6358, -1221, -5062, 45, - 970, -500, -1322, 1176, 5882, -11687, 6324, -2183, - 2327, 922, -5628, -3507, 2406, 874, 1399, 4518, - -343, 857, -224, 802, -725, -8561, 4432, 1974, - 1825, -2168, -451, -3408, 6587, 7589, 3361, -4711, - -1474, 3151, 1950, 1022, 1466, 9192, 4666, -822, - 1024, 2342, -2220, 1169, 10460, 2993, -988, -4407, - -6727, 902, 1659, 80, 106, 400, 34, 1746, - -6982, 10484, 6333, -845, -3333, 1764, 217, -4730, - -3306, -3664, -2830, 2254, -927, -55, 587, 1812, - 281, 4375, -3614, -1349, 1802, -6184, -2648, -4189, - -9381, -3243, -4147, 384, 2241, 5524, -478, -1534 -}, - -.cb4448l0 = { --15402, -5156, -1798, -144, -4711, -4700, 2819, -389, - 148, -2600, 1706, -1906, -578, 495, 24, 829, - -383, -12581, 11667, -1039, 1395, 2670, -288, 23, - 628, -248, -512, 79, -326, -5428, -2830, -2476, - -1253, -915, 12042, -674, -110, 2950, 3885, -5799, - 983, 616, -652, -60, -372, 22, -141, -167, - 98, 125, -100, 27211, 133, -127, -271, -272, - -176, 1268, 173, -422, 2431, -3998, -2797, 2328, - 182, 6526, 3318, -6282, -10580, 3966, 8504, 527, - 9507, 6203, 990, -989, 6030, -136, 647, -1100, - -324, -2618, -2499, 500, -132, -842, 1237, 3599, - 2285, 2906, 10766, 11284, -2794, 242, 184, -1934, - 55, -839, -1181, 406, 855, 902, 10490, -327, - -1561, 5742, 428, 2218, 1523, 5229, 9130, -760, - 108, -140, 22229, 1132, 411, 720, 414, -356, - -745, -1276, -899, -562, 369, 5, -7770, 4101, - 3626, 126, -13, -4356, 728, -3197, 1930, -1470, - -6936, -410, 6720, 1897, -530, -4267, -2181, -876, - -472, -2540, -10234, 4008, 10217, -2561, -2021, 716, - -1378, -325, 427, -245, 314, -48, -118, -150, --30295, -368, 256, 369, -656, -78, -246, -140, - -1250, -635, 1332, -13604, -10383, -1375, 353, 2417, - 2140, -349, 1460, -51, -309, 523, 509, 2352, - 1208, -377, -2023, 9708, 397, 1216, 10610, -4416, - 5520, 3902, -2119, -480, -420, 1170, 36, -3304, - 1550, -266, 1682, -808, 2420, 2700, 16239, 3910, - 572, -375, 85, -9775, -120, 2214, 2779, 11510, - 2628, -416, -1740, -1305, 1226, 78, 78, 635, - 422, -13892, 1302, -4117, -1218, 2681, -8436, -1723, - 2290, 2815, 1172, -181, -675, -475, -763, 2394, - -3639, 7903, -659, 2323, 4837, -6758, 9460, -1480, - -2403, -2783, 1496, 806, -458, -246, 12, -254, - 121, 1477, -633, -513, 791, 208, -390, -177, - -1292, -20471, -4401, -2678, 9026, 128, -265, 822, - 260, 11202, 3132, -1879, -3891, 1884, -842, -107, - 7516, 1208, -1552, -995, 1203, 2150, 11044, 1285, - 2282, 80, 1348, 5342, 2089, 924, 1472, -1454, - -8259, -226, -10259, -2335, -2442, 224, 3257, -1528, - 6685, 1630, 1969, 48, 4802, 6051, 987, 8662, - -2368, -4984, -1974, -4049, -5320, 5003, 299, -400, - 727, 208, -187, 2838, -4547, 9682, -2238, 1065, - -3206, 10091, 4915, 2945, -1635, -198, 1074, -698, - -716, -96, 1390, -2644, 1006, -4154, 10587, 1132, - 2912, -7399, -8350, 785, 156, -290, -142, -374, - -2161, 1066, 1358, -1798, 3050, -19, 452, 10470, --10948, 4190, -984, -2089, -728, 1503, 4273, 812, - 4950, -3750, 844, -1231, -1582, -2517, 2385, -10537, - 5807, -4621, 332, -357, -12484, 1676, 160, 10762, - -1225, -1374, 14, -1389, -2900, -467, -1260, 459, - -861, 102, 1715, 4295, -7324, -7400, 10435, 287, - 1866, 765, 1730, 3430, -744, -2, -1773, -96, - 2001, 2165, 118, 9296, -4640, -4612, 7134, 5128, - -7967, 404, -433, -433, 2222, -8050, 2023, 2766, - -260, -2440, 1607, 2442, 7763, -486, 3766, 2355, - 7515, 230, 1248, -8873, -8224, -9135, -1402, -1812, - 1223, 152, -2316, -739, -405, -784, -598, 625, - 503, -175, -573, -31693, 502, -478, -554, -934, - 387, -80, -484, -701, -34, -51, -494, -1461, - 1005, 2920, 11532, 2667, -1674, -832, 8680, -5767, - 786, -1558, -2062, 1009, -392, 2099, -7277, -2587, - 6302, 3070, 4496, -1713, -4042, -8109, 1642, -1894, - 3450, 840, 3632, 160, 578, 149, 767, 754, - 208, -870, -672, 252, -30, -213, -482, 50, - -578, -2, -148, 246, -31918, -568, 130, 472, - 761, -27, -51, 454, 144, 124, 5844, -8354, - 9562, -3755, -262, 3286, 1120, 983, -628, -734, - -1732, -1424, 353, -403, 15877, -13552, -335, 337, - 519, 140, 297, 150, 725, -780, 876, -116, - -91, -128, 275, 2499, 9313, -768, -10469, 1148, - 2172, -6417, 3292, -2187, -1108, 3055, 1105, 625, - 794, 68, 337, 1384, -106, -516, 574, 868, - 849, -997, 81, 25796, 28, 206, -3556, -351, - 1058, 1126, -7826, 5310, -4102, 5352, -6835, -4032, - 1487, 230, 5617, 937, 10484, -71, 2653, 1203, - -1, 667, -1489, -10136, 7782, -763, 792, 1434, - -170, 367, 96, -21992, -252, 756, 145, -1476, - 1408, 1523, -819, -576, -476, -1068, -241, -39, - 1547, 9553, -622, -1799, 1861, 6115, -864, 10690, - -586, 470, 200, 1162, 586, 44, -11650, 3453, - 8734, -2754, -178, 236, -2650, 2654, 2699, 1180, - 5325, -458, -40, -218, -6, 126, 6794, 506, - 860, 11863, 652, 1665, -4213, 4863, 1424, 5712, - -663, -688, -10, -1421, -676, -1325, -378, -311, - -490, 19501, 1242, 268, 4581, 1587, -1153, 848, - -1378, -1159, 505, 63, 704, 1942, 2204, -2106, - 44, 479, -1098, 333, -21595, -617, -6444, 3547, - 1282, -1784, 4664, -1330, 2607, 1241, -3579, 247, - -875, 11359, -3013, -136, -12813, -14400, 1857, -998, - 1342, 1187, -338, 1263, 575, 1226, -995, 596, - 446, 293, 767, -356, 70, 786, 466, 202, - 149, 849, -28991, 652, 124, -209, -124, -406, - -5463, -1413, -1300, -5339, -1761, 4770, 2680, -10542, - 3486, 5601, 2932, 1581, 489, 521, -16583, 1, - -1529, 5942, 1234, 4714, -1647, 1150, 2802, 642, - 586, 3836, 240, 307, -490, 67, 771, 816, - -906, 1554, 1090, -2353, -629, 11291, 2941, -2982, - 9473, 1434, -4351, -8017, -5173, 8071, 1931, 1281, - -4055, -3224, -1918, -271, -204, 670, 3491, 107, --31624, 227, 75, -91, 108, 171, -53, -201, - 373, 63, 118, 126, -104, 127, -88, 1810, - 11688, -10240, 550, 3692, -4978, -1619, 40, 911, - -1080, 580, -767, 333, 192, 403, 308, -904, - 142, 31169, 503, -1101, -146, -144, 35, 181, - -355, 54, 590, 499, 95, -1767, 444, -49, - 2160, 7176, 12032, 6478, -741, -5576, -644, -101, - -1251, -1268, 2365, 10029, 537, -1476, 307, 2108, - -2478, -944, 10725, 349, -4242, -135, 7577, -4492, - 1492, -2512, 7736, -5118, -6756, -2436, -1890, -2390, - 1620, 914, 1658, 47, -11692, -134, -1740, -196, - 9521, -136, -1376, -8682, -1136, 1096, 903, -1148, - -334, -228, -4, -675, -199, 1914, 2827, -11098, - -2129, -2559, -978, 175, 1832, 10075, -2358, -1888 -}, - -.cb4448l1 = { --11514, -2858, 12392, -305, -206, 929, 473, -3120, - -2766, -1068, -1237, 420, -718, -21, -336, -45, - -478, -1517, 1830, -12644, 259, 11978, 257, 1494, - -1759, 247, -733, 112, -2242, 290, 234, -10260, - 1781, -1806, -4104, 1747, 38, -692, 4971, -9113, - -1925, -1580, -615, -9608, 3779, -11158, 469, -4736, - 299, -2815, 2108, 1910, -2356, 66, 523, -440, - 2298, -4219, -2512, -1110, 11192, 5932, -2629, -7985, - -992, 775, -1134, 3287, 900, -681, -39, -1206, - -1708, -6800, -361, 11024, 8496, -198, -3855, 1486, - -2547, 1773, 50, -276, -286, 785, -7884, 438, - 4590, 2794, 5333, 5476, 2108, 660, 3610, 2308, - -8538, 224, -132, 134, 731, 988, -1368, 3894, - 4318, 9911, -104, 320, -9506, 1721, -5690, 1712, - -8747, -1876, -5122, -1304, -162, 752, 3646, 1621, - 11089, 1117, -1971, 1058, 3070, 180, 23112, 175, - 483, -1028, -538, 497, 1053, 61, 788, -455, - 22, -55, -32, -326, 15956, -2045, 788, 9784, - -1170, -819, -3677, 647, -484, 578, -160, 286, - -421, 289, 8140, 3838, -578, -1866, -2074, 667, --11951, 1684, 3439, 1280, 158, -1784, 1276, 638, - 562, 2045, -220, 852, -594, -2109, -2665, 2748, - 38, 91, 1377, -624, -18586, -498, -882, 36, - 536, -99, 62, -5275, 3051, 231, -6343, -1751, - 1206, -1646, -1347, -13590, 1431, -271, -442, 21934, - -143, -1824, -378, -463, 816, 379, 336, -291, - -652, 275, -758, 257, -14866, -1304, 7260, -3373, - 1249, -1992, 2734, -2565, -3064, -416, 2424, 279, - 10518, 206, -681, -14338, 666, 1843, -648, 526, - 1982, 366, 684, 1019, 192, 8, -482, -4785, - 2134, -1722, 10674, -1613, 33, 1148, -1566, 10226, - 3397, 667, -1100, -738, 2420, -14282, 451, 90, --10346, 2673, 1175, -3639, 266, -566, 0, 1672, - 1082, 298, 359, -497, 1784, -570, -2538, 2522, - -3825, 6265, 99, -7927, 3160, 11079, 131, -2080, - 92, -29951, 268, -293, 240, 254, -182, -145, - 303, 12, 86, 596, 246, 136, 1020, -1521, - -1134, -10125, -5691, 6028, -3703, -4295, -3718, -5719, - -564, 660, -321, -1073, 83, -3068, 6167, 12788, - -762, 8057, -1215, 2379, 2142, -3625, -503, -1418, - -304, -649, -501, -12558, 12787, 3737, 1465, -3692, - -1321, 1106, -1136, -651, -50, 1608, 59, -583, - 82, 331, 443, 782, 93, 285, 310, 29149, - -698, -52, -909, -238, -222, -114, 4, 650, - -200, 235, 2541, 598, 378, 11000, 3101, -8228, - 1690, -4313, 6996, -11, -2620, -1458, -1428, 579, - -304, 20, -372, 897, 602, 432, -138, 690, - 593, -1485, 136, 191, -32147, 260, 199, 412, - -168, -41, -384, -362, -14, 242, 366, -318, - -304, 1544, 458, -7790, 3332, -5117, -1937, 868, - 12622, 906, 1941, 4763, 1698, 351, -234, -973, - 9166, 6726, 2686, 248, 3597, -9812, -400, 4155, - 2852, -415, 2218, 876, 1423, 3852, 2965, -410, - 1820, 8268, -1296, 686, 114, 3087, 3007, -9402, - -5751, -3459, -6674, 418, 4137, 4778, 56, -1399, - -1698, -2590, 8343, -2130, 2535, 6148, -134, -2393, - 11551, -338, 735, 630, -658, 13358, 949, -1136, - -217, -985, 182, -1014, 1459, 221, 7713, -1386, - -1427, 1326, 555, 66, 2694, -1535, -268, -13596, - 658, 305, 858, 548, -12748, -582, -1055, -659, --12155, 940, -2164, -2518, -126, -132, -842, 641, - -483, -446, -5184, -186, -511, 1169, -6092, 6161, - 3082, -664, -2037, 847, 11032, -1306, -1673, -1219, - -36, 1862, 10053, 780, -282, -837, -263, 509, - -588, -12646, -769, -2164, -2219, 524, -3433, -6437, - 3890, -623, -7509, 241, 4042, 264, -1394, 3646, - -6925, -5184, 1218, -1476, -2240, 1882, 182, -3450, - -497, -148, 160, -1579, -19545, -80, 886, 913, - 708, 728, 393, -603, -778, 3414, -778, -1495, - 1205, 2342, 232, -3634, -76, -16792, -684, 1322, - 192, -13248, -658, 7650, 4731, -169, 5148, -1413, - 3026, 2480, -2190, 1004, -2082, 237, 171, -717, - -766, -525, -11802, -3776, -9914, 1374, -3250, 415, - -2787, -175, -1081, 792, 980, 11464, 834, 714, - -993, 150, 77, 2306, 11249, -3058, -3418, -1758, - -239, -119, -1408, 6083, -4276, 1827, 1660, 2287, - -2997, -576, 400, 2062, -3174, -6215, 10026, -1082, - 41, 249, 10026, -6199, -301, 280, 10120, 2249, - 527, -564, 1002, 622, 3341, 408, 2870, 12902, - 13307, 689, 336, -819, -43, 832, -1242, 657, - -106, 42, 1123, 149, -2072, 78, -303, 329, - 21745, -2172, -1204, 448, 1437, -560, -376, 311, - -73, 153, -785, -368, 54, -445, -92, 120, - -59, -377, 402, 567, -25820, 1284, 1288, 200, - -865, -1286, -41, -1862, 402, 179, -2338, -3876, - 4992, -1824, -10092, -3407, -8516, -3556, 130, -5695, - 5846, 2333, 2995, 2110, -6946, 5049, -2377, 1655, - -859, -4737, 1648, 7031, -7344, 4992, 1760, -711, - 3134, 14363, -907, 171, -1971, -3062, -1079, 600, - 603, -224, -440, -11328, -291, -663, 1878, -715, - -2724, 284, -456, -10970, -3225, -2240, 252, -977, - -360, 729, -572, 3981, 1615, -52, -5372, 6095, - -9888, 6873, -3830, 4916, 1834, -1581, -11268, -2316, - -398, 1361, 6151, 2736, -1968, 4624, -180, -260, - -1221, -5633, -1300, -1081, -1433, -509, 366, -388, - 1660, 340, -18997, 694, -1184, -813, 1324, 1261, - 735, -186, 5258, -583, -221, 1707, 149, 1022, - -835, 1089, 2939, 2025, 421, 411, 3609, -13797, - 464, 9214, 2462, -6257, 6032, 1911, 1282, -9673, - 974, -703, -128, 950, 369, 1160, -674, -312, --13858, 1078, -7606, 8, 2786, 367, -6441, -824, - -195, 714, 484, 108, 475, 289, -1012, -1591, --10880, -324, -647, -2199, 10378, 5781, 995, -416, - 871, -1240, -380, 70, -1893, 7632, 1727, -908, - -672, -10901, -962, -7322, 794, 1748, -5568, 1215, - 5845, -9575, -2413, -2159, 3077, 1359, -416, 6277, - -85, 1352, -3498, 6130, 1125, -236, 1950, 8481, - 716, -560, -1311, -228, 250, -440, -5320, -1941, - -9710, 4637, 1420, -102, -8222, 616, -2254, -528, - 196, -1315, -749, -97, -285, -15880, 1105, 630, - 368, -809, 29, -1688, -2314, 745, -1627, 19840, - -2380, 4108, 1670, 2763, 275, 530, 492, -589 -}, - -.cb4448s0 = { --10720, 9997, -1313, 8849, 5152, -226, -2908, 303, - -842, -870, 165, -1372, -105, -154, 170, 2424, - -2476, -2126, -8329, 349, -4509, 5128, -92, 9086, - -7263, 416, -124, 341, -88, 239, 5172, 553, - 1526, 1728, 1955, -1489, -6595, -11237, -10224, -394, - -927, -932, 674, 743, 317, 4628, 8453, -3768, - 2545, 3506, -2406, 9108, 5643, 4660, 4116, -2452, - -1391, -154, -74, 180, 5270, -7922, 46, 11046, - 6076, 735, 7922, -196, -1080, 1445, -687, -2403, - -784, 742, -269, -498, 6010, -4045, 1053, 891, - -1538, 613, -84, -4254, -957, 4682, -14004, 2050, - -647, -718, 557, -2720, 2437, -7675, 11874, -9284, - -734, 775, -2231, 105, 366, 1360, -98, -126, - 508, 2647, 729, 762, -8806, -10413, 9008, -2093, - 1107, 201, 1421, 1181, -259, 1420, 828, 327, - -1956, -573, -874, 354, 2662, -1437, 10864, -9240, - -7648, 1670, 1598, 173, 438, -373, -566, 246, --11999, 1817, -611, 1, -1652, 1876, 1354, 1270, - -789, 300, -321, 11577, -516, 329, 5723, 4732, - 1717, -6224, -5356, -6292, -370, -3644, -922, -50, - -14, -581, -1554, -1675, -20, -965, 28479, 658, - -498, -488, 504, -601, 437, -585, -245, -196, - 186, 281, -174, 159, 7469, 5890, -5112, 4918, - -9023, -360, 40, -2975, 4784, -437, 1609, 1032, - 2759, -297, 106, 5176, -4315, 568, -9536, -1297, - -6783, -10965, 1285, 264, 330, -508, -522, 624, - 662, 539, 7248, -13780, 40, 2140, -2188, 1925, - -8972, 1147, -1340, 870, 779, -4, -101, -374, - 781, 5733, -5712, -5777, 2080, 875, 13450, -1551, - -3229, -1818, -114, 1265, 501, 636, -576, -623, - -1269, 3006, 1023, 862, 1359, 1950, 588, -22648, - 218, -438, 1547, -408, -844, -263, -106, 14754, - -689, -9466, -978, -21, 1412, 43, 2012, 352, - 908, 277, -960, -747, -230, -1557, -7132, -5707, - 79, -2474, 2177, -5349, 2510, -12720, 2833, -2152, - -1693, 458, 197, -643, 735, -2728, -893, 2758, - 5196, -3566, -4294, -4914, -1222, 188, -8884, -6234, - 2391, -1518, 663, 572, -1465, 1147, 8486, 2037, - 2516, 941, 6092, 11602, -2559, -1702, -1848, -924, - -210, -108, -1052, 8360, -7567, -4588, -169, 3464, - -9206, 1842, -4329, -2499, -341, 592, 918, -102, - 340, 214, 1037, -324, -16289, 10308, -47, -29, - 1340, -603, -2763, -548, 392, 1489, -149, -769, - -67, 13270, -2233, 8257, 1582, 1034, -4270, 916, - 4486, 1191, -102, 159, 109, -536, -664, -987, - -8041, -1759, 4264, -5600, -13815, -1158, 1712, 2516, - -634, 504, 515, 732, -46, -685, -481, 1685, - -1782, 262, -3600, 14721, 6334, 7941, 101, 914, - -2141, -2, 182, 829, -215, -122, 6325, -3752, - -2812, 1618, 3512, -1591, -4276, 6994, -10349, -5675, - -1501, -1766, -1949, 436, 82, -5596, 2592, -1086, - -2804, 2540, 458, -550, -1834, -2401, -7563, 2340, - 1678, -7666, 4538, 27, 6337, 3642, 17068, 5310, - 1115, 1579, -142, -397, -670, 2010, 863, -504, - 845, 848, 770, -8821, 1963, 2782, 162, 1130, - 2597, -13699, -3996, 800, 2499, -1045, -1512, -186, - -59, -119, -5048, 6800, -8766, 784, -7091, -1002, - 335, 1993, -1045, 601, 1804, 166, 1343, 110, - -224, 2247, -344, -5, -4292, 5846, 8591, -11846, - -1303, -1027, 1759, -168, -194, -1281, 489, 378, - -5069, -3321, 11238, -375, -806, 3962, 9660, -2960, - -664, -1067, -627, 271, 1205, 1160, 261, 3725, - 7877, -679, 22, 598, -1086, -420, 2168, -46, --15552, 420, 1220, 1332, -58, -156, 7777, -4657, - 352, 15316, -4760, -2140, -2577, -1321, 2037, -371, - -1254, -912, -1177, -1367, -103, 4572, -9482, -1599, - 294, 403, -272, -2331, -4365, 13467, 4585, -2554, - -1743, 545, 162, -369, 6074, 11273, -8856, -8175, - 2543, -7, 314, -2033, 2704, -1755, -1431, -791, - -276, 1085, 236, 6553, 1872, 387, 1056, -31, --20610, -609, 608, 1007, 1604, -1501, -68, -527, - 204, 252, 2533, -721, 1468, 444, -72, 61, - -209, 512, -216, 42, 385, -490, -104, -29030, - -166, -4883, -2754, 788, -430, -867, 565, -1155, - 562, 1076, 1757, -2990, -14971, 8392, 902, 550, - 102, -6579, -6939, -319, 172, -863, 979, 2178, - 630, 160, 952, 946, -3955, 1515, 352, 2557, - -5339, 6166, 4588, -2040, 4031, -535, -2504, 2782, --12136, 1338, -2758, 458, -671, 155, 6998, -2598, - -931, -396, -922, 2060, 447, -42, -649, -532, - -552, -1945, -16548, 815, -408, 3469, -4118, 875, - -1017, -11150, -511, 3846, -11349, -1928, -781, 2765, - -681, -713, 655, -218, -8032, -465, 295, 1591, - -383, -1889, 1627, 108, 1149, 2513, 388, -5702, --15693, 24, 470, -4322, 3721, 1584, 1808, 350, - -1765, -620, -2953, 4354, 8512, -12533, -86, -2490, - -192, -507, 2024, 3942, -801, 13444, 738, -2086, - 162, 2013, 837, 56, -384, 3164, 5052, 1158, - -403, -6913, -4290, -2068, 16622, -2738, 856, -2884, - -2432, -410, -1179, -456, 504, -1359, 436, 352, - -6351, 327, -2196, -1502, 302, 338, -839, 235, - -520, 1283, 2710, 18814, 2256, -2, 400, 1300, - -1185, 1024, -3744, -3542, -4350, -763, 1902, -14737, - 5437, 48, -1589, -280, -67, 232, 2276, 1413, - 3284, -308, 1013, 610, 22787, -685, 724, 12, - -359, -1651, -1060, 569, 248, 3836, 605, -413, - 3380, -1360, -1120, -2933, -2368, -977, 10135, 12356, - 3739, -1571, -418, 580, -2662, -11460, -6128, 2867, - 11468, 825, -3201, -501, -138, -755, -554, 168, - 757, -564, 428, -12118, -15179, -1978, 432, -597, - 1528, 3038, -568, 1349, -3377, 914, 498, 928, - -91, -5, 9192, 3000, 2542, -1411, 626, 2705, - -763, 3247, 13736, 3034, 2170, -67, -852, -378, - 1264, -2771, -2415, -4236, 126, -1984, -13336, -1088, - -416, -1979, -520, 2506, -1505, 294, -2398, 218, - -8740, -3873, 2069, -1374, 86, -998, -3851, 1070, - 13357, 955, 3085, -536, 166, 926, 299, 6532, - 1324, -502, -1658, 1829, -1263, 445, -1902, 1452, - -2747, -16422, 1875, 1773, 452, 288, 5992, 1626, - 3659, -917, 2255, -1508, 356, 547, 158, 9, - -117, -1665, -595, 14392, -1013, 49, -4060, 12064, - 3666, -2903, -9145, -396, -4341, -953, 2758, -178, - -204, -462, 98, 222, -3622, -12200, -4484, -94, - -8642, -5694, 4034, -720, -1695, 751, -1668, -266, - -343, 296, -112, -900, -3750, -360, 1002, -7402, - 7758, 7370, 3332, -7517, -769, -1272, 412, -1451, - -89, -227, -11332, -472, -1108, -394, -339, -1981, - -3494, 12110, -564, -5958, -690, -1066, -130, 762, - -50, -1456, -1521, -8428, 994, -867, 2650, -2335, - 354, -2253, 4612, -12364, -2626, 1853, 577, -103 -}, - -.cb4448s1 = { - 25901, -239, 648, 167, -284, 198, -340, -1112, - -55, -242, -214, 528, 112, -259, -284, -250, - 23, 475, 780, -558, 111, 148, -2411, -19826, - -1158, 2799, -964, 44, -1204, 1187, -4036, 1872, - 3541, 768, 159, 1979, 3382, -113, 804, -1021, - 3708, -2577, 9697, 11527, -326, -7058, 4306, 1260, - 3782, 3370, 1595, 705, 2268, 2182, 1509, 1131, - 9877, -7260, -258, 49, 1686, -1472, -2556, -1973, --22425, 338, 486, 963, 1069, -34, -1027, -90, - -881, -473, 554, -6326, -873, -9744, 10157, -1079, - 584, -1047, -1954, 6204, 2416, -899, 1452, 938, - -439, -664, 4231, 9370, 7800, 170, 9448, -4756, - 1967, 686, -1186, 636, -1719, -1244, -540, -728, - 306, -1778, -7980, -3418, 8318, -1828, 1556, 3487, - 10195, 3741, -510, 2077, -1496, 1241, 384, 477, - -1051, 7922, -4077, -2513, 849, -693, -9170, 4264, - -7940, -1703, 460, -2986, 586, 13, 377, 781, - -7047, 6852, -1350, 7537, -493, -1919, 379, 3108, - 4293, 8467, -3875, 63, 44, 493, 1496, -1577, - -5676, 3318, 6628, 5177, -11082, 1146, 3251, -1159, - -461, 442, 1250, 212, 176, 3586, 137, -9153, --13772, -8211, 393, 1170, 1717, -671, 298, -233, - 883, -1533, 401, 254, 7700, -4827, 794, 377, - -376, 12240, 7298, 2445, 1168, -562, 1528, 563, - 421, -606, 0, 5792, -1069, 824, 3728, -2729, - 1005, -730, 4318, 644, 17336, -1588, 2100, -365, - 509, -415, 3684, -9128, -1096, -4278, 1549, -1247, - 5519, 11075, -2216, 6004, -3683, 409, -730, -414, - -263, -6623, 8194, 489, -9085, 334, -1104, -814, - 1412, 1522, -1657, -7029, -4142, -1274, -520, -40, - 650, -1886, 9701, 11456, -7567, 1176, 3268, 3016, - 1109, -117, -858, -155, -1249, -230, -216, 3945, - 9142, -2297, 134, -2563, 15131, 857, -1597, -618, - 150, -590, -166, -357, 388, -69, -8767, 2914, - 1087, 4673, -14373, 600, 382, -1893, 844, -242, - 544, -106, 568, -1141, 371, 2663, -1860, -725, - 8066, -1353, -8743, -10433, -1796, 427, -73, 178, - 96, 980, -478, 978, 1767, 6034, 633, 966, - 677, -65, -884, 417, 461, 62, -868, 93, - -100, 519, 16304, 2646, -1260, 12271, -140, 142, - 11138, -892, -2114, -629, 172, 744, -2056, -960, - 61, -980, 2082, -439, -3126, -2564, 1174, -78, - 254, -178, 1599, -436, 19023, 5335, -1686, -782, - 520, -8727, 256, -3588, -5694, 12323, -2091, 1511, - -656, 3872, 2370, -770, 282, 455, -573, -39, - 7845, -12566, 12690, -156, -442, -227, 575, -274, - -1717, 120, -40, 1866, 635, 161, 270, 1039, - 3256, -673, -3343, 4292, -14247, 7142, -4821, -591, - -418, 376, 21, 572, 551, 70, -5536, 79, - 2540, -505, -283, -350, -1279, -1630, 2234, -604, - 5246, -17580, -3022, -1052, -307, 6626, 2794, 1702, - 1875, -1876, 1011, -320, 1268, -282, 1072, 14370, - -8206, 1218, 630, 173, 7486, 15176, -6146, 4903, - -636, -1341, 1360, -1541, -1012, -778, 84, 426, - -124, -746, -252, -11085, 1783, -2833, 809, -744, - 2194, 3328, 7029, -5097, 4934, -3025, -641, 303, - -328, 258, 8674, 53, -3395, 975, -9944, -8550, - 3376, -714, 1078, 1186, 598, 808, -166, -752, - 484, -5088, 1484, -1278, 11394, -1876, -8236, 5159, - -1830, -1520, 2761, 592, -204, -1360, 454, 230, - -5038, -1582, -5617, 1346, -2045, 2306, 17764, 494, - 572, -1930, 339, 550, 784, 151, -753, 4708, - -3058, -8267, 3281, -1054, 870, -1201, -2005, -920, --10115, 5395, -6423, -798, 367, -221, -5296, -2808, - 8313, -5077, 1655, -200, 114, 46, 350, -2374, - 868, -327, 377, -9570, 1231, 9258, 8752, 3074, - -4411, -308, 2315, 6824, -3303, -896, -1186, 579, - -2561, 2280, 586, -798, 4747, -3487, 1306, -1241, - -487, -90, -52, 3231, -555, -17702, -2681, 1649, - -17, -278, -647, -4225, 2740, -1248, -3826, 1356, - 3572, -1010, 16160, -422, 304, 3970, 1124, -317, - -554, 673, -1191, 3180, -4429, 1581, 1543, -2097, - 4208, -9363, 10146, 1896, 2904, -4112, -1428, -207, - 459, -35, 5395, -8960, 3141, 11004, 308, 3687, - 1540, -2156, -592, 1640, 1003, -280, 797, 204, - 6910, -824, 4724, 4729, 5553, -3165, 483, -12, - 33, -588, -379, 402, 3543, -9646, 74, 9603, - -465, 2872, -2367, -885, 2894, -133, 2758, -721, - 3473, -13322, 1506, -1344, 512, 1066, -8300, 11391, - 11976, -1201, 13, -612, 165, -1823, 154, -123, - 1234, -423, -367, -58, 384, 2687, 2536, 826, - 6223, 1750, -8589, 1126, 9772, -6646, 2043, 1826, - -1037, -2018, 692, -818, -3431, -467, 11006, 3407, - 880, -2047, -10303, 6168, 1428, -307, -18, 661, - -252, 754, 1207, -2797, -3057, -6235, 99, -931, - 1618, 692, 2790, -294, -1200, -5768, -11691, -5305, - -100, 390, -783, -11660, -4675, -13570, 2764, 1414, - -786, 385, 163, 718, 794, 1118, 827, -634, - -75, 6224, 3965, -2092, -1120, -6395, 5474, -12986, - -3985, 635, -544, -1877, -191, 0, 121, 379, - -3059, 132, 26320, -721, 1262, -706, 421, -85, - -38, 665, 590, -208, -196, 168, 10, 1271, - -218, -365, -5843, -5897, -12346, -3026, 5916, -115, - -2671, -1022, -203, 962, 995, -850, 527, -516, - -1641, 452, 68, 1204, 740, 385, 38, 752, - 150, -3088, 20608, -54, -39, 6109, 3224, -92, - -315, 4407, -306, 1317, -395, -1617, 9104, -3493, --10724, -3059, 283, 81, -9791, -3210, 7307, 4459, - -639, -61, 1152, -184, 2290, 398, -2902, -2776, - -1624, 1153, 242, -8865, -3617, 309, -11933, -3847, - -5750, 3235, -153, -315, 382, 209, -923, 2072, - 458, 164, 3631, 3121, 3220, -828, -8644, 2215, - 3873, 12445, 533, -631, -53, -136, -728, -240, - 420, 2870, -4981, 906, -3272, 4735, 3613, 2412, - -3951, -10587, 7389, 564, 3266, -1348, 524, 1570, - 6611, 3354, -1042, 1862, 1860, -1187, 5761, -1722, - 8231, -7428, -5662, 1239, -2887, -218, 810, -1063, - 15078, 686, -2374, -293, -2031, -245, 4441, 5045, - 1100, 6722, 1787, -587, -380, 132, 5124, -12478, - 95, -1230, 1464, -1871, 929, 1430, 2666, -3768, - 2784, -3697, -8238, -247, 603, -8406, 1330, 1033, - -743, -2546, 2739, 856, -12698, -4970, 2290, -1104, - 34, -1048, -80, 634, -695, -84, 2374, -24793, - -1064, -1080, -254, -812, 252, -1582, -401, 765, - 847, 340, 479, -3163, 150, -187, 8432, 2607, - 2075, 1384, 423, -7361, -10262, -2254, 54, 1065, - 40, 857, 2014, -5076, 198, 657, 482, -422, - -2185, -850, -318, 164, -684, 2698, -1008, 17493, - -64, -6788, -5966, -14352, -2349, 2492, 266, 1077, - 1935, -99, 4270, 2319, -2391, 779, 187, -70 -}, - -.cb4448m0 = { --20455, 663, -3140, 2540, -2110, -406, 1078, 1968, - -741, -2458, 490, -496, 338, 581, 1079, -616, - 154, 10097, 231, -228, 477, 20, 1372, 11492, - -1112, -3148, 547, 248, -676, 8197, 5902, -1299, - 519, -2808, 11529, -76, 1239, -1032, -542, 353, - -1071, 278, 274, 2781, -7741, 3260, 2711, 175, - 12340, 1110, -2348, -5303, 1440, 581, -70, 262, - -9902, -2375, 530, 1433, 1624, -1475, -947, 13450, - 1318, -1696, 207, 198, 1162, -944, -9329, -1046, - 195, -106, 682, 14624, -854, -2410, 1054, 242, - -348, 581, 463, 716, 760, 2714, 1356, -1359, - 13089, 2565, -10523, 1934, 637, 1218, 1160, 830, - 905, 272, 408, -581, -1426, 613, 2586, -8186, - 3748, -6663, 4372, -114, -4644, 2998, -9440, 685, - -8741, 3363, -5623, -4229, -7058, -1201, -822, 1806, - 8671, -856, -612, 1165, -426, 317, 6867, -80, - -7084, 1143, -1862, 2742, 669, 550, 22, 173, - 4301, -10406, 1042, -346, -1334, -2897, 647, 744, - 14, -1338, -1648, -1235, 3550, -455, 2125, 1188, - 17136, 1188, -6782, -849, 298, -1054, -9254, 409, - -1736, 1410, -7254, -1889, 457, -740, 22, 262, - 32242, 1657, -2308, 2688, -607, 609, 4, 150, - -264, 192, -140, 246, -393, -76, -15050, 390, - 969, 457, 1436, -649, 460, -12150, 1359, 1014, - -2103, -576, 55, -590, 113, -1410, -23431, 182, - -2386, -1568, 904, -218, -281, -188, -178, 63, - 211, 549, 687, -12069, -88, -654, -1070, -13155, - -124, -697, 438, 3174, 1700, 270, 234, -289, - -625, 15749, -2340, 8466, 397, -4460, -1030, 3206, - 1081, -1317, -1030, -72, 487, -1477, -8782, 6984, - -1221, 2395, 3198, 2995, 5862, -1195, -6075, -1020, - -934, 868, -470, -1024, 1202, -998, -1306, 22118, - 344, 540, -3137, -547, 2440, -28, 222, 372, - -424, -199, 1068, -917, -105, -4278, 52, -299, - 6933, 11715, -520, -2853, 58, -8575, 416, -1272, - 1128, -32, -1140, -1873, -495, 235, 2079, -314, - -1328, -2615, -20194, 848, -1553, 387, -6091, 906, --10180, 8634, -506, 4078, 318, -2657, 1612, -126, - -1424, -4, -1745, -343, 302, 2439, 12190, 941, --12534, -4756, -176, -90, -1295, 1041, 1875, -450, - 89, 212, 2098, 1708, 1876, 4065, 1682, 1972, - -4916, -951, -10683, 1443, -10978, 772, -1013, -235, - 59, 213, -230, 142, -576, 506, 101, 44, - -137, 26238, -47, -322, -289, 281, 2614, -4538, - 634, 1116, 1191, 2985, -759, -5527, 550, 2107, - -6018, -11013, -425, -221, 901, 217, 546, 213, - 2026, 695, 1074, -2132, -173, -1664, -783, 25065, - -326, 86, -632, 1398, 4708, -2911, 2376, 135, - -1471, -904, -2338, 987, 3216, -4564, 314, 15692, - -214, 1238, 230, -181, -30537, -294, 155, -607, - 218, -309, -180, -246, -102, -988, -644, 111, --10517, -1604, -1180, -2748, 1191, -12959, -2, -1004, - 28, -196, 1974, -790, 809, 8802, -1204, 332, - 180, -3857, 1025, -5998, -9578, 94, -1069, -2398, - 185, 643, -1479, 322, 2544, 12584, -8308, -3856, - 1286, 1600, -2539, -2752, -2520, -367, -942, 417, - -309, -2162, 2044, 10886, 1764, 11028, 3810, 2955, - -1028, -1017, -1752, -487, -605, 48, 2312, -368, - -1758, -252, 371, 19882, -1994, 1675, 5494, -660, - -1669, 256, -54, -941, 4318, -306, 2143, 273, - -3367, -3088, 6509, -1884, -5400, -576, 11394, 875, - 455, 271, -218, 1401, -44, -5336, -12170, 4664, - -589, -3562, -1934, 5842, 1357, 3232, 1449, -402, --11228, -96, -1509, 2073, -1751, 776, -439, 775, - -3302, 13521, -325, -118, -172, 411, -396, 6154, - -2455, -52, -4616, 783, -12488, -2085, 5817, -1278, - 635, -1713, 2888, -830, 649, 7482, 10134, 9147, - 3784, 1046, -1934, -2580, 102, -679, -124, 68, - 657, 417, -175, -32768, -80, 375, -941, 224, - 271, -232, 1519, -99, -680, 67, 66, -618, - 252, 1907, 5121, 2456, -2117, -9388, -1441, 636, - 7868, -8340, 1939, 1340, 1511, 711, 6530, -1748, - -183, 90, 2561, 5860, -364, 5117, -4101, -4028, - -944, 10526, -1028, 1047, 707, 12116, -12596, -4006, - 922, -1047, 348, -971, -272, -2388, 435, 246, - -1055, 148, -1852, -12418, -2531, 3524, 4103, -344, - 1667, 2818, -4576, -273, -8337, 183, 497, -144, - -9845, -292, -503, -1212, 4316, -1434, -11058, -3043, - -5817, -981, 813, 0, -718, -467, 10285, -19005, - -82, 776, 1192, 1030, 1560, 1080, -144, 729, - 606, -225, -389, -187, 552, -930, -444, -5959, - -1960, -1315, 2650, -1282, -18790, 1772, 263, 1410, - 812, -458, -476, 744, 2595, -426, -19, 9119, - 4529, -1502, 4673, 3675, 7430, 1084, -6966, -518, --13552, 1054, 2474, -9499, 1041, 5114, 442, 2927, - 511, -1492, 217, -726, 398, -522, 35, 119, - -332, 106, 816, 437, -1223, 27612, 521, -29, - -462, 367, -966, 476, -2559, -3485, -160, 1487, - -272, -586, -6014, -232, 3679, -1864, 1244, 575, --14591, -483, -1428, 20, 7874, -2948, -5965, 2383, - 3270, 490, 2750, -547, -9658, -1473, 943, 285, - -2388, -772, -1582, 3181, 3419, 2628, -197, 3376, --13282, -7684, 3383, 70, -1174, -70, -6703, -7305, - -553, 3588, -826, -12, 7350, -3604, 345, 1098, - 3856, 918, 2038, -39, 11514, 15798, 1327, 1158, - 436, -918, 71, 953, 975, 1147, 174, 411, - 1467, 83, -4536, -1511, 5350, -3314, 13999, 18, - 4107, 1901, 834, 2614, 2356, -369, 943, -341, - -460, 4380, -10014, 3308, -3541, -3225, -621, 8449, - -1383, 4481, -1399, -3646, -936, 923, 221, 346, - 7828, 2406, 3021, -4993, 3012, -10903, -1925, 8153, - 382, -1453, 1238, 601, 1195, -2245, -2792, -4118, - 473, 4898, 12961, -6094, 5905, 1368, -2754, -303, - 768, -31, -1275, 1400, 596, -1326, 619, -1744, - 1145, -3977, 639, -10785, -1693, -11192, -541, -434, --11384, -1017, 14361, 1398, 521, -3239, 1851, -491, - 237, -1024, 1002, -3002, -303, -33, -6532, 601, - -3726, 7832, 6090, -10107, 957, -1149, 689, 1327, - -51, 1945, 990, -106, 595, 234, 518, 1060, - 77, 837, 28880, -91, -395, -275, -265, -279, - -217, -300, 240, -1055, -406, 4314, -2139, 6349, - -2227, -5996, 963, -10386, 4629, -560, 1080, 134 -}, - -.cb4448m1 = { - 31577, -1322, 1533, -2224, 253, -1485, -92, 294, - 183, -580, 420, 172, -794, -206, -342, -338, - 53, -85, -920, 29517, 1073, -972, -1839, 1004, - 290, 46, 460, -71, -988, 1731, -362, -2070, - 3848, -2, -3842, 734, -1221, -8012, 1104, 6782, - 9673, 1082, -8561, -860, -2135, -1557, -1613, -13999, - 1664, 2268, -1570, -732, 1010, -402, -1139, -428, - 400, 1123, -2108, -11776, -345, 10608, 1245, -3142, - -3244, -1132, 1700, -308, 1573, 543, 678, 5160, - -3062, 433, 2703, -852, -4903, -1880, 1706, 13995, - 2465, -4844, -904, -148, 350, -11168, 1406, 312, --11900, 397, 769, 5558, -1354, 187, -30, 231, - -1020, 202, 884, -198, -3151, -830, -8490, -670, - -2767, 1517, -12957, -3861, -2794, -1854, -180, 135, - 7140, 4103, -4427, 450, 494, -1033, -1110, -2857, - 11056, -711, -800, 3628, -180, -852, -10300, -2120, - -450, 14464, -511, 303, -1464, -542, -89, -204, - 500, -400, -318, 569, 216, 428, 350, 1973, - -137, -885, -1794, -974, 3977, 3382, -18624, -420, - -1947, 165, -449, 1395, -17313, -286, 2054, -447, - -2740, -1881, -550, -2166, 1360, -6021, -94, 148, - 676, -1619, -1737, -11977, -169, -1664, -7709, 6202, - -5954, 1681, 715, -263, 56, 369, 589, 564, - 1989, 1617, -1648, 9205, 1343, -11508, -7379, -3791, - -3136, 1049, -844, 24, -6714, -1736, -5734, -2907, - 5016, 2167, -5722, -1210, 6232, 428, 2467, -3334, - -1477, -711, 6728, -10274, -4930, -6224, -349, -710, - 1598, -713, -1708, -497, -254, 567, -884, 131, - 11520, -908, -1425, -1862, -13449, -1590, -669, 657, - 505, 236, -4, 21, 846, 100, 8248, -1847, - -131, -186, 181, -806, 3293, -1072, -1208, 14492, - 1555, 1527, 544, -120, -258, 6, -2401, 12455, - 10880, 1091, -2350, -939, -1252, -564, 150, -114, - 1419, 737, -1732, -440, -2303, -226, 536, -2492, - -1085, -10117, -11013, 3786, 5275, -10, 2479, 143, - -1647, -7945, 884, -1618, 2056, 12890, -424, 5986, - -1471, -666, -570, -1466, -499, 64, 566, -1738, - -639, 11380, -612, 1879, 1550, 12469, -299, -1501, - 2634, 1036, 3020, -13, 14974, -2066, -5786, -2667, - 5487, -6768, 468, -385, 778, -805, -536, -304, - 718, 386, 285, 7546, 643, 1462, 913, 4707, - 941, -3338, -194, 6669, -4493, 8869, -837, 400, - -877, -11113, 326, -2318, 13683, -1304, -1966, -933, - 312, 128, 470, -296, -322, 340, -1126, 1811, - 1999, 2885, 3201, 331, -2494, 3999, 660, -80, - -2063, -16771, -1337, 426, 4884, -6026, -40, 2093, - 342, -176, 83, 134, 796, -425, -8934, 2100, - 8550, 160, -221, -252, -32714, 1306, 1332, -609, - -109, 547, 848, 518, -40, 303, -246, -451, - -2177, -716, -750, 1, -21232, 1287, -1303, 2051, - 1659, 1501, -369, -1415, 274, 308, 260, 371, - -1409, -662, -7347, 7161, 3656, -1104, 8862, -5671, - 1370, 1122, 16, 1132, 17593, 6778, -993, 613, - -665, 3004, 3288, -1625, -1823, -1003, 740, -1002, - -888, -677, -1065, -25294, 997, -160, -180, -811, - 188, -333, -2483, -696, 1309, 120, 456, -116, - -2020, -896, 7216, 6328, -9170, 8407, -2986, -1684, - 680, 1752, -684, 613, 337, -629, -11750, -493, - -324, -907, -391, 1053, 14125, 142, 420, -1917, - -378, -1428, -90, -497, 1116, -464, 2170, 805, - -1572, -904, -9020, -534, 6450, -490, 10750, 279, - 765, 961, -3985, -2702, 2423, -4981, -1222, 1654, - -1089, -2157, 1940, 14331, -895, 1726, 1555, 122, - -3552, 1274, -598, -910, 3056, -1704, 6430, -10626, - 1014, -8773, 1009, 1936, -360, -468, -1029, -8841, - -625, 2212, 2234, 2720, 1190, -64, -2078, 4688, - 8690, 5150, -450, 744, -796, -5661, -332, -7938, - 2670, -4054, 1377, -1594, 11554, -4702, -3631, 745, - 742, -90, -1311, 12528, -4664, 834, -853, 1542, - 8560, 2209, 4091, 2876, 2117, -678, 1684, 785, - 304, 7980, 2126, -302, 8239, -2105, 1584, 11894, - -1055, -1391, 596, 2343, 86, 388, -1348, -1007, - 1428, 413, -9231, -10312, -7346, -1108, 1385, -1255, - -3954, 738, -1258, 410, 226, 15115, -1059, -4117, - -50, -504, -1726, 1425, -9974, -346, 688, 464, - 244, -586, -8880, 845, -659, 932, -1309, 290, - -29, -417, -2184, 1011, -9622, 1443, 9009, 1945, - 2698, -708, 10572, 2410, 1200, 4492, -2569, 1444, - 2735, -8604, 2274, -4057, 478, -199, 1285, 12695, - 12321, -2933, -1708, 1198, 675, -492, -560, -52, - -1261, 85, -480, -96, 696, -764, -1402, -31368, - -580, -675, -1678, -58, 600, -522, -292, 647, - -36, 154, -1148, 437, 1561, 588, 603, 7629, --16973, 29, -828, -589, -919, -1372, -470, -445, - 428, 528, 5828, -353, -32, -1781, -702, -690, - -7196, -3253, 1942, 4600, -12102, -674, -10480, -2336, - 711, -2174, -7474, -1436, -451, -7133, 856, -2652, - 1892, 3464, -546, 676, -13296, -516, -13618, -997, - 938, 1686, 1006, 1358, -1371, 922, 534, -170, - 126, 255, -835, 50, 945, -1066, -1676, 3, - 1038, -437, 26030, 418, 27, -1092, -493, -428, - -606, -1097, -628, 298, 295, -806, 183, 146, - 1352, -84, -722, 833, -25667, 3176, 1001, -322, - -2339, 15, -475, -1257, 2116, 876, 637, -529, - -1108, 302, -2452, 19734, 58, 851, 9845, 1142, - 2168, 706, 11070, 1556, 544, 3002, 2238, -3974, - 2738, -48, -8324, -2186, -355, -14933, 2192, -2481, - 2700, 473, -486, 761, -208, 76, -78, 102, - -4896, 1378, 12377, -8269, 28, 1092, -5071, -1500, - -1190, -804, 1085, -766, 493, 22, -1041, 9136, - -1234, -12247, 967, 2672, -883, 4582, 4871, 1891, - -532, 329, 226, 446, -6710, 312, -914, 1416, - -1852, 3052, 6512, 8971, 5544, 6519, -579, 1021, - -241, 911, 782, -3456, 10158, -1865, 3941, -12300, - 8, 472, 882, -1580, -1799, -1025, -631, -127, --15316, 8047, -200, -1860, 582, -4363, -1274, 1085, - -48, 2383, 638, 480, 369, -838, -1341, 414, - -114, 2757, 1222, -2194, -3394, 6469, 2418, 738, - -1656, 15594, -1090, 202, 727, -769, 484, 2462, - 4875, 1656, -3835, -16877, 5276, 239, 982, -1872, - -130, 901, 1352, -155, 4939, -8317, 9000, 2503, - 485, 1184, -548, -1356, -7482, -188, -1587, 496 -}, - -.fcb08l = { - -2539, -3275, -2699, -3345, -2843, 5501, 426, 7127, - -149, 3111, -2991, -2297, -2345, 2702, -969, -946, - 2837, 1114, 1800, 1271, 12249, -2282, -2309, 1566, - -2889, -3020, -2083, 3586, 8919, 2651, 4111, -1842, - -1588, -1428, 3251, -102, 156, -320, 722, 1711, - 20565, -3068, -2211, -3164, -3410, -3396, -2882, -2002, - 1730, 4077, -2696, -1694, -2839, 2948, -2739, -2380, - -2252, -1311, -269, 1900, -2796, -444, -2996, -2525, - 5194, 1459, 5042, -1089, 914, 4116, 7644, -3137, - -3156, 4028, -3435, -3240, -2585, 5542, 5119, 9885, - -2995, -3153, -3449, -3101, -3551, -3469, -2196, -1271, - 3869, 5413, -2800, -1990, 3371, -2286, -1022, 3190, - -550, 1723, 968, 1916, -2749, -1530, -2211, -2987, - -3357, -3262, -1042, 10277, 107, 2662, 9819, -2753, - 4269, -3277, 3125, -3131, -2974, -3251, 6466, 9484, - -2034, -2707, -2424, -3170, -2619, -2278, -143, -1641, - 11856, 5975, -1282, -2629, -2396, -2364, -2012, -1085, - -2576, -2422, -2206, 13731, -2261, 2751, -1768, 2482, - -1065, -347, -137, 31, 619, 385, -2257, -2215, - -1698, -2686, 4468, -2563, -1071, -1359, 7757, 3732, - -2856, 9018, -2046, -1494, -2234, -2209, -67, 1340, - 2433, 2965, -2722, -2151, -2966, -2780, -2732, -1509, - -2085, -1532, 6934, -1248, -1936, -2203, -787, -1781, - -895, -1990, 4693, -1818, -1569, 1954, -2283, -2403, - 10514, -3105, -1074, -2838, -1, 1192, 1113, 3309, - -2249, -2451, -1660, 2535, -1439, 3582, -1093, -594, - 1956, 758, 5349, -2524, -2320, -1903, -2055, 5075, - -941, -721, -536, 2197, -2309, -3027, -1460, -2911, - 11344, -2474, -1601, -1749, 3260, 2547, 3819, -1247, - -1449, 2835, -1118, -652, -516, -379, 531, 440, - -569, -2606, -2545, -2447, -1685, 8678, -1868, -2003, - -992, 5888, 8591, -1848, -2010, -2196, -2049, -658, - 3473, 214, 905, 317, -2050, -1083, -2593, 8754, - -2234, -2449, -1688, 2194, 2244, 2502, -1659, -2748, - 4584, -3011, 3702, -2307, -1887, -1960, -1068, 2889, - -3022, -2989, -2295, -2794, 3071, -1588, -43, 2627, - 1278, 2031, -2145, -2551, -2333, -3205, -3237, -2760, - 9082, -454, 4339, 1776, -2738, 4785, -2176, -1896, - 2148, 1350, 768, 249, 1001, 1499, 797, -2182, - -1443, -229, -32, 827, 401, 270, 581, 380, - -2370, -2376, -2679, -3099, -1742, -1149, 4666, -693, - 1109, 7547, -2496, -3063, -2818, -2621, -2016, 5722, - 4932, 1217, 2161, 2449, -2207, -2954, 3769, -2824, - -1809, -2946, -1693, -377, 1565, 4100, -2947, 3063, - -3062, -2919, -3093, -2520, -1712, 2383, 1305, 1867, - 10145, -2912, -3307, 7519, -3502, -1063, -2782, 8595, - -750, -1503, -3141, -2486, 2923, -2574, -1826, -1244, - 3537, 2494, 2583, 1560, -2722, 3284, 2245, -1258, - -658, -394, 483, 719, 1121, 1073, -2949, -1013, - -3048, 597, -3103, -2510, -1970, 7207, 8635, 1917, - -1772, -483, -2318, -1860, -2500, 2981, -1651, 550, - 696, 615, -2121, -2055, -1619, -2126, 3108, 3417, - -485, -47, 848, 1608, -2636, -1707, 3142, 3798, - 479, -1112, 597, -323, 1555, 1531, -2930, 2106, - -2398, -2314, -1835, 0, 2920, 896, 2356, 1259, - -2911, -3184, 593, -3570, -3389, -3263, 7340, 7640, - 6874, 6549, -1912, -1334, -1749, -568, -1718, -405, - -1375, 3456, -1024, -1903, 9384, -2721, -2485, -2377, - -3026, -899, -3133, -3032, -2452, 7715, 2492, -2450, - -1721, -2138, -1497, -55, 760, 2382, 1183, 1105, - -2782, 389, -1528, -927, 664, -531, 1405, 363, - 582, -292, -1678, -2718, -2763, -3140, -2799, -2178, - -2715, -2592, -972, -1226, 3278, -1173, 2916, -1548, - -446, -1241, -209, 379, 689, 538, 3110, 2857, - -1735, -1244, -589, -413, 65, 471, 522, 323, - -2043, -212, 1309, -471, -564, -16, 378, -320, - -437, 228, -2194, -2637, -2513, -2670, -1863, -954, - -2082, -2398, -2270, 5563, -2959, -2444, -2794, -1736, - -1631, -1324, 1482, -481, 2317, 1470, -2871, -2007, - 702, -1980, -491, -146, -695, -145, 2817, 1268, - -3395, -3456, -3069, -3433, -2874, -205, 806, 3038, - 3806, 2623, -2954, -1861, -712, 1017, -326, 44, - -93, 910, 775, 346, -2625, -2570, -2974, -2344, - -2712, -1930, -2213, 3521, -1341, 4327, -141, 835, - -1119, -1336, -1092, -1891, -860, -727, 315, 2562, - 4119, -2638, -2584, -1951, -2710, -2499, -1561, -952, - 2821, 2505, -2388, -1855, -2926, 1742, -2563, -2655, - -1802, 3082, 3063, 2456, -3304, -2670, -2147, -1504, - -309, 1421, 1661, 1546, 560, 615, -2590, -1593, - -1523, 2025, 3167, -841, -356, -648, 309, 1165 -}, - -.fcb08m = { - -2962, -2140, -2166, -1454, -1638, -1100, -835, 686, - 978, 550, -1630, -1021, -1424, -1867, -1118, -474, - 66, 6104, 904, 603, -829, -475, -1368, -1199, - 7255, -890, -465, 114, 118, 224, -2453, -1279, - 8192, -1289, -452, -47, 180, 324, 627, 209, - -2770, 11214, -857, -1720, -895, -531, -291, -264, - 232, -402, -2699, -2561, -2433, -2093, -1315, 86, - 2666, 1663, 1351, 2349, -2788, 4576, 3680, -1365, - -995, -513, 46, 44, 522, 142, -2739, -1654, - -1950, 4573, -659, -536, 285, 72, 875, 627, - 3142, 105, -941, 1245, -489, -495, -229, 44, - -236, -1083, -2336, -1193, -1620, -1859, -1339, -655, - 205, 1032, 5581, 1195, -2635, -1740, 2656, 1976, - -52, 784, -96, -165, 419, -486, 8850, -624, - -792, -1531, -765, -674, -730, -829, -150, -27, - 2255, -1177, 2727, -1430, 737, -902, -780, -729, - 169, 278, 3729, 3763, -32, -1581, -563, -573, - 77, -372, -64, -477, -2500, 526, -1682, 1464, - -830, -124, -548, 561, 202, 1115, -1682, -1552, - -2014, -2127, -1374, -749, -720, 64, 2097, 6944, - -2771, 4929, -1680, -2212, -1430, -801, 114, 891, - 1176, 855, 3571, -2187, -1566, -1694, 84, -46, - 932, 786, 765, 856, -1038, -498, -117, -1582, - -1379, -1162, 6293, -367, 594, 132, -2487, 2119, - -2153, -1749, 833, 1089, 507, 133, 337, 423, - -2777, 2507, 277, -1455, -1019, 1811, 639, -595, - 136, -1050, -2941, 4474, -176, 1095, 1113, -479, - 182, -295, -229, -605, -2035, -1649, -1171, 51, - 0, 125, 2844, -310, -82, -640, -2251, -2138, - -2270, -1567, 2260, 92, 368, 95, 1433, 1346, - 820, -2339, -1822, -895, -69, 158, 190, 911, - 1008, 764, 684, -1756, -1013, -1625, -1610, 6062, - -499, -1036, -139, 1129, 488, 524, -665, -870, - -347, -76, 123, 91, -12, 14, -2867, -2019, - 2858, -1903, -1165, 309, 287, 1250, 767, 776, - -2784, -2446, -1157, 460, 2589, 437, -285, 711, - -299, 402, -2683, -2271, -1714, -1535, -547, 4118, - 510, 1158, 700, 631, -2084, -1236, 509, -1009, - -510, -193, -1075, -793, 727, 2150, -2722, 968, - 1077, -1579, -1410, -894, 401, 1043, 427, 182 -}, - -.fcb08s = { - -2368, -2340, -1735, -1897, -1493, 984, 3062, 2826, - 1049, 164, 1181, -1990, -1833, -1720, -1360, 24, - 1485, 1923, 460, 511, 69, 78, -353, -3, - 3761, -480, -1538, -1063, 540, -64, -1546, -988, - 1514, -1167, -1354, -563, 1435, 880, 1123, 182, - -2243, -2109, -2378, -2201, -1491, -836, -124, 605, - 6159, 3636, -2770, -2959, -2956, -3019, -2154, -648, - 1805, 4698, 2929, 2078, -975, -360, -895, -623, - -593, -879, -345, 4333, 492, -56, -2102, -781, - -476, 1268, 606, -670, 1686, -105, 370, 461, - -221, -868, -1381, 297, 128, -578, -809, -938, - 3896, 490, 4032, 2675, -684, -1108, -1235, -915, - -874, -919, -802, -1040, -1324, -16, 2156, 1943, - -652, -666, -47, -1499, 168, -210, 4213, -1895, - -1734, -1767, -1412, -867, -71, 329, 855, 1294, - -1849, 4393, -1312, -1597, -564, 434, -454, 269, - 892, -31, -1170, 67, 370, -1144, -320, 3706, - -811, -190, -123, -166, -659, -1033, -789, -902, - -347, -280, -108, -313, 452, 3701, -1505, -2610, - -2758, -2550, -2034, -1361, -676, 713, 2263, 8286, - -2241, -2508, -2540, -1721, 182, 1947, 306, 1773, - 1220, 2909, -60, 73, -235, -1631, -1302, -692, - 4171, -830, 49, -188, -471, -2208, -2265, -1518, - -196, 2995, 2571, -579, -68, 805, -1294, 1274, - 4294, -1356, -702, -532, -465, -123, -400, -719, - 336, 3093, 1634, -906, -71, -502, -938, -982, - -742, -1187, -1757, 2890, -1591, 1303, 216, -311, - -404, -29, 501, -543, -1466, 1587, 309, -578, - -173, 34, 1116, 1286, -1184, -1174, -175, -732, - -619, 3508, -80, 191, -1059, -174, -429, -470, - 10000, -933, -1511, -1601, -1571, -1445, -1065, -1407, - -1053, -932, 1183, 7875, -460, -1609, -1618, -1398, - -1154, -1227, -1012, -1450, 20, 28, -235, -110, - 203, 105, 252, -154, -51, -58, 2940, -490, - 17, -51, 131, -106, -526, -566, -822, -1177, - -1335, 2749, 608, -1575, -1322, -1351, 111, 641, - 1441, -9, 733, -207, -273, -665, -630, -588, - -78, 254, 304, 762, -2661, -2677, -1238, -82, - 2569, 3001, 932, -1032, 211, -324, 40, 1395, - -836, -1119, -635, -1425, -1514, -1135, 1509, 2963 -}, - -.fcb11l = { - -3004, -2927, -2672, -2356, -735, 179, 950, 1734, - 1101, 1641, -1610, -1161, -1606, -179, -1634, 3383, - -610, 240, 73, 1128, 818, -1052, -1641, 724, - -1938, -1741, -1211, 3967, 1988, 1445, 3010, 2203, - -1685, -1698, -1838, -759, -144, 515, 999, 1215, - 3239, -1912, -2048, -1739, -1488, -148, 1590, 1370, - 1066, 1270, -2721, -1637, 99, -1964, 224, -946, - -1437, -954, 755, 1420, -2800, -2211, -2304, -2048, - 4853, -714, -383, 2159, 1823, 2328, -1619, -1584, - -1839, 5462, -1703, -802, -227, 485, 1017, 1695, - -2459, 2399, -1820, 2254, -1373, -767, 53, 705, - 1074, 1293, -1582, -2486, -2208, -2341, -2264, -2132, - -1578, -1043, 322, 7685, -2198, -1768, -2106, 16, - -2207, -1495, -1106, -961, -482, 1642, 6785, -1540, - -1540, -1449, -1177, -854, -307, 853, 1279, 1449, - 3253, -1427, 2314, -1473, -985, -1025, -321, 923, - 1140, 1166, -2704, 2664, -2444, -2717, 481, 3083, - -1449, 1225, 3168, 2389, -2124, -1981, -1342, -1939, - -1904, 4736, -885, -826, 3866, 2046, -290, -567, - -1986, -1880, 1966, -465, 1638, 683, 1005, 1099, - -2842, -2537, -2559, -2427, -1243, 4039, 1371, 3897, - 2529, 2400, -2586, -1328, 785, -1697, 1733, 2382, - -442, 190, 901, 1281, -2669, 2198, -1502, -1404, - 2593, -694, -186, 466, 1065, 1199, -1905, -1389, - 6171, -1817, -513, -989, -356, 246, 1619, 1883, - 36, -2178, -1602, 608, -1523, 23, 1265, 578, - 953, 1038, -483, -2278, -2138, -1740, 584, 244, - -54, -192, 915, 1097, -213, -1569, 1861, -1401, - 3686, -1625, -1234, -614, 860, 1311, -1397, 2315, - 1896, -1608, -1326, -1487, -99, 2241, 697, 1156, - 1711, -2099, -1507, -135, 1422, -695, -57, 1390, - 823, 937, -122, 479, 47, -2144, -1514, 955, - -1317, -726, 480, 1153, -2959, -2558, -2573, -1355, - -1879, -1446, 6435, 677, 3124, 3134, 1850, 1834, - -1396, -1417, 1290, -896, -561, 1428, 1007, 1105, - -2101, -2044, 1779, -1913, -1868, 1410, 916, 1232, - 1112, 1335, -2663, -104, -513, -96, -470, 480, - 1516, -150, 298, 714, -2558, 3076, 468, -745, - -945, -443, -849, -989, 341, 1102, 433, 588, - -1772, 462, -527, 670, -128, -108, 583, 701, - -2281, -2149, -2398, -2749, -2557, -1691, -1095, 1336, - 9088, 3844, -1799, -1861, -1908, -2242, -2184, 2313, - 3779, -809, 519, 2229, -1914, -1673, 1764, -634, - -1955, -1721, 405, -499, 243, 1632, -2377, 7289, - -1659, -1752, -1341, -948, -323, 841, 1703, 1774, - -2029, 2384, -1877, -1918, -1729, 1483, 483, 1916, - 576, 1258, -2310, -1796, 2208, -1579, 57, -1735, - -1161, 5177, 1674, 2468, -1907, -1499, 1868, 2275, - -620, -356, -228, 489, 1064, 849, -683, -1204, - -1761, -2211, -606, -764, -1056, 3888, 253, 1518, - -2555, -2075, 119, -1567, 971, -1178, 2683, 1476, - 978, 1419, -2947, -2418, -2164, 1178, 1582, 1470, - 896, 645, 1671, 1462, -2234, -1363, -1184, 1408, - 1042, -1091, -208, -49, 527, 917, 1266, -1444, - -2174, -2447, -2300, -1732, 3076, 5631, 248, 2195, - -2477, -1724, -2434, -2477, -2524, -1828, 2331, 845, - 1423, 1767, -2393, -1946, -857, -462, 344, 17, - -896, 2391, 892, 882, -828, -280, -752, -1136, - -1563, -1040, 1222, -1173, 1763, 1179, -1448, 1946, - -1815, -1588, -1638, -1282, 3302, 132, 509, 1408, - -2760, -2338, -1935, 1353, -1531, -1074, 1156, 3086, - 1374, 1667, 2302, -1623, -1897, -1991, -494, 2603, - -754, 524, 1265, 1304, 3062, -1359, -1365, 1987, - -1334, -916, -146, -40, 635, 1033, 1724, -1057, - 49, -1159, -774, 106, 1053, -153, 134, 691, - -119, -1226, 332, -363, -197, -69, -133, 573, - 190, 216, -2236, -294, 1288, -2110, -1537, -1005, - -1175, 56, 4227, 1623, -2440, -1894, -1623, -2377, - 2287, -1220, -1506, 177, 5689, 2849, -2857, -2166, - -2546, 2174, -2414, -2343, 559, -1020, 4650, 3514, - -2875, 1309, -2557, -2534, -2235, -1901, 1559, 4412, - 2301, 2204, -2969, -2018, -2399, -2834, -2431, 1316, - -1474, 1269, 2533, 3485, -2892, -2387, -2716, -2317, - -2031, -1992, -1311, 8071, 3933, 3807, -2139, 1909, - -2200, -2344, -2060, -1638, -1154, -210, 2781, 2139, - 1119, -1828, -2069, -2306, -1975, -1165, -444, 789, - 2409, 1551, -2929, -103, -1920, -2010, -904, 694, - -188, 4, 1051, 1190, -2649, -2454, -2205, -1651, - -1856, -1552, -1165, 352, 3351, 1266, -1719, 57, - -1828, -420, -938, -1251, -461, 1294, 1158, 893 -}, - -.fcb11m = { - -2704, -2459, -2349, -1535, 2807, 365, 1064, 892, - 830, 1222, -2190, -1542, -2285, 6443, -1607, -1362, - -605, 637, 883, 877, -2378, 2292, 3106, -1057, - 1776, -1094, -859, 249, 199, 256, -1537, 2098, - -1126, 2243, -1186, -193, -211, 211, 502, 308, - 3369, 3197, -1271, -1370, -355, -423, -537, 468, - -237, -99, -1439, -1748, -2185, -1972, -1357, -814, - -470, 815, 1306, 6390, 1983, -1169, -1749, -29, - -1368, 5929, -1539, -900, 576, 701, 1708, -1608, - -1148, 3522, -822, -120, -461, -158, -43, 39, - -2543, 8872, -1347, -1580, 222, -488, -162, 295, - 382, 291, 11143, -1223, -1270, -1399, -392, -563, - -500, -604, -544, -135, -1787, -1313, -1490, -1395, - -1100, -1278, -818, 6172, 768, 1597, -623, -681, - -1128, -1575, 7257, -665, -1021, -439, 932, 703, - -1496, -2168, -1945, -1454, -808, -1261, -354, 875, - 6706, 1956, -1773, -1503, -1536, -1162, -1386, -1885, - -1607, -318, -72, -7, -1932, -1349, 6150, -1852, - -345, -18, -81, 223, 339, 425, 362, -1623, - -1432, -1973, -1042, -1373, 7830, 38, -116, 1000, - 421, -2375, -1808, -1832, -1046, 2077, 955, 1576, - 581, 824, -2021, -1582, -1402, -1420, 69, 3549, - -513, 192, 262, 483, -2503, 4173, -11, -1532, - -893, 282, 187, 320, 176, 259, -2308, 2342, - -2385, -2147, -784, -375, 413, 833, 889, 1297, - 1415, -1085, -1009, -1501, -1246, -1298, 1553, 1384, - 332, 662, 2226, -2399, -1752, -857, 1899, 131, - 501, 209, 217, 346, 4294, -1811, -1694, -1080, - -752, -263, -228, 249, 628, 971, 2508, -1031, - 2871, -1054, 42, -202, -738, -170, -239, -290, - -2751, -2379, -2379, -1999, -1448, -380, 1594, 1279, - 1399, 1633, -2376, -1839, 1367, 1685, 356, -126, - -50, 143, 31, 33, 314, 160, -663, -687, - 25, 388, -267, -188, -188, -129, -2614, 1063, - -1835, -285, 2549, 205, -30, 370, 319, 297, - -87, -2208, -1164, -839, 894, -266, -410, 375, - 1263, 924, -2606, -2325, -1854, 1792, 407, 328, - -110, 575, 1090, 971, -2517, -1583, 1355, -1892, - -490, -203, 846, 724, 597, 779, -1650, -1281, - -1294, 549, -146, -548, 2947, -28, 265, 339 -}, - -.fcb11s = { - -1536, -2360, -2378, -2138, -1380, -346, 1575, 2779, - 3247, 1689, -340, -1788, -1839, 103, 31, 853, - -653, 3159, 365, 154, 404, -835, -716, -35, - 4309, -155, -1214, -1180, -750, -522, -753, 350, - -1660, -1603, -1159, -582, -489, 1067, 2615, 1747, - -1755, -2351, -2314, -1453, 922, 3458, 867, 439, - 493, 1212, -1584, -1655, 1300, 1783, 1641, 1442, - 816, -1283, -1456, -1417, 4998, 1923, -200, -1086, - -1060, -1016, -1074, -1217, -1285, -1245, 633, 390, - -1443, -1099, -507, 3041, 343, -163, -745, -667, - 2333, -2144, -2460, -2247, -2063, -1736, -742, 418, - 3124, 3504, 227, -735, 799, -1326, -20, -543, - 1900, 237, -671, -545, -1727, 121, -1750, 3700, - -485, -553, -77, -212, 942, 62, 1647, -688, - -1506, -1429, -619, -839, 172, 3209, -500, -371, - -1680, -1408, -1122, -563, 3627, -115, 510, 534, - -65, 199, 800, 5040, 631, -744, -612, -1023, - -1099, -1319, -1520, -1460, -1120, -274, -1220, 349, - 1848, -620, -1411, -616, 1771, 1024, -1223, -2195, - -2345, -2144, -1517, -1055, -385, 557, 1482, 6797, - -2274, 818, -460, -707, -274, 646, 654, 731, - 268, 347, 4583, -1289, -1452, -1193, -1072, -681, - -178, -131, -108, 547, -1521, -781, -1298, 239, - -486, -445, 3453, -226, 90, 653, -1237, 624, - 4692, -482, -798, -799, -766, -645, -890, -915, - 3748, -909, -1012, 85, 963, 375, -100, -1010, - -1269, -1508, 2106, -1194, 2632, 595, -826, -221, - -411, -1104, -1365, -1050, -2112, -863, 1943, -727, - -1079, -733, 78, 1990, 363, 953, 1325, 459, - -891, 3364, -410, -362, -547, -994, -1371, -1258, - 12270, -43, -1668, -1868, -2004, -2133, -1863, -1949, - -1805, -1288, -1640, 3783, -1414, -578, -505, -464, - -158, 252, 71, 76, 22, -20, -72, -13, - -19, -95, -14, 2, 23, -5, 1289, 630, - 291, -707, -794, -857, -715, -122, 551, 219, - -2358, -1905, -1397, 277, 572, 343, 789, 526, - 1629, 991, -980, 222, 740, 1199, 19, 1200, - -864, -467, -656, -138, 820, -2005, -924, 154, - 195, 393, 267, -183, 1024, 100, 1243, -872, - -705, -781, -422, -377, -910, -637, 89, 2849 -}, - -.fcb16l = { - -2676, -2246, -3119, -2904, -2707, -1946, 7718, 2292, - 2451, 4206, -1214, -362, 1116, -860, 30, -993, - -888, -1046, -3732, -2268, -2541, 6060, -2220, -1597, - -1650, -1320, 88, 1229, 2118, 2348, 1430, -1865, - -2190, -2122, -1844, -2069, -1746, 15, -1746, 1321, - -2671, -2993, -3247, -2811, -2141, -1360, 1886, 270, - -381, 5676, -2070, -444, -674, -1082, -1144, -346, - -823, 4630, -224, 1940, -2441, -2072, -2194, -295, - 2175, 1209, -734, 168, 923, 1359, -2667, 389, - -2585, -2279, -2195, -1141, -1016, -218, 109, 1926, - 5184, -2226, -1888, -1273, -1044, 25, 461, 886, - 1125, 1249, -2215, -2381, 3109, -1963, 3015, -2027, - -790, 1192, 1646, 2188, -2906, -2598, 484, -2372, - -1372, -1082, 1718, 664, 1391, 2396, -2518, 1937, - -2362, -2510, -1504, 2947, 446, 684, 1947, 2059, - -3263, -3001, -3240, -3034, -2598, 3367, 4407, 2327, - 2450, 2994, -2379, -1875, -1862, 6387, -1956, -1417, - -525, 1098, 1836, 2932, 1408, -1130, -1417, 1693, - -262, -645, -515, 443, 735, 619, -2834, -2246, - -2646, -2521, -811, 6608, -421, 1572, 2015, 3234, - -2086, -1435, 89, 1648, 838, -986, -1159, -1208, - -32, 1354, -2135, -2159, 7796, -2424, -949, -2040, - -1179, 228, 1187, 3008, -2963, -2500, -2074, -2025, - -1439, 1692, -378, -596, -62, 2419, -3522, -3132, - -2899, -3290, -2929, 2844, 49, 4307, 2754, 3897, - -2960, 1305, -1858, -831, -1379, -773, 3257, 979, - 975, 1513, -2849, -1610, 2483, 456, -1395, -634, - 847, 1320, 1116, 1175, 2497, -1554, 2176, -1697, - -997, -799, -120, 339, 996, 1379, 11359, -1557, - -2219, -2237, -1792, -2084, -1009, 781, 3341, 939, - 1954, -1860, -2347, -2117, -2000, -1394, 3825, 106, - 2595, 2162, -2938, -2488, -2112, 772, -1059, 1822, - 159, 1017, 2452, 1506, 1313, -2615, -2479, -2941, - -2220, -2510, -726, 4703, 1778, 3375, -3133, -2664, - -2821, -2771, 1559, -1000, -434, 1874, 4130, 2987, - -2998, -2692, -2326, 1580, -2231, -1347, 4166, 2021, - 1177, 2531, -2880, -2337, -2589, 1505, -2843, -2468, - -339, -1059, 3212, 4264, -3112, -2885, -2889, 975, - -2522, -2278, 721, 5057, 3989, 3373, -3098, -2947, - -1128, -2251, 1935, 2981, 3007, 975, 1983, 2048, - -2861, -2302, -2431, -1460, -1492, -1524, -944, 1556, - 1778, 1549, -2658, -2259, 2768, -2460, -1447, 2957, - 759, 324, 2533, 2477, -2935, -1687, -2554, -2647, - -1431, 118, -365, 10280, 1526, 3447, -2570, 2268, - -2351, -2115, 2588, -9, -834, 1115, 1878, 2365, - 79, 1132, -1619, -1406, -1568, -1766, -224, 825, - 2113, 1382, -548, -2669, -1797, -2691, -2139, -2495, - -210, 1276, 13623, 2315, 1965, -1713, -1610, -2187, - 2534, -1495, -1301, 622, 563, 2154, 2743, 3230, - -1784, -1774, -792, -493, -131, 156, 944, 1211, - -1886, 357, -1018, 225, -285, 1025, -134, 218, - 290, 153, 5869, -2407, -2856, -3051, -2540, -3238, - -2260, -370, -451, 6314, -500, -2554, -2110, -879, - -323, -537, 570, 1228, 1556, 1342, -2486, 3366, - 1838, -937, -959, -683, 63, 937, 652, 1212, - -2164, -1448, 166, -799, -550, -1317, 481, 299, - 5494, 1360, -3147, -2574, -989, 1550, 1952, -1502, - -96, 3517, 1304, 2311, -2931, -2146, -2174, -2052, - 579, 680, 896, 2697, 703, 1365, 4130, -2367, - -2627, -3125, -934, -3093, -2155, -955, 6025, 5024, - -3121, -3064, -2883, -2458, 1723, -842, 3032, 4391, - 2327, 2837, -2536, -2208, -1610, -2189, 6509, -1424, - -1116, 1427, 2830, 3370, 1084, -1562, -1655, -1628, - -491, 2260, -321, 421, 774, 1237, -3267, 977, - -3170, -3144, -2698, -1324, 1424, 3034, 3323, 3347, - -3021, -3061, 2027, -2345, 852, -2832, -1714, 5926, - 4517, 3839, -1490, -2416, -1726, -1268, -1458, -2137, - -1715, -580, 1403, 13408, -3005, -2706, -3063, -2745, - -2777, -2136, 2786, 202, 5141, 3407, -3104, -3001, - -3176, -3388, -3507, -2863, -2097, 2325, 2618, 6146, - -1997, -3152, -1036, -2694, -2587, -2986, -2750, -2219, - -1607, 5944, -2893, -2633, -2229, -2811, -2482, -2115, - -2219, -1180, 5246, 3252, -3111, -2052, -2693, -2934, - -1805, 2583, 353, 1262, 8588, 3900, -2468, -2726, - -1861, -2352, -2237, -2750, -2345, -1936, 9793, 8392, - -3490, -3124, -3596, -3630, -3154, -2390, 743, 6652, - 6366, 6143, -2852, -3547, -3124, -2718, -1094, -494, - 49, -1053, -3005, 32767, -1721, -1229, -1715, -1590, - 1587, -1233, 3384, -252, 312, 1120, -3287, -2926, - -3048, -2828, -2502, -1185, 2028, 3778, 487, 2083 -}, - -.fcb16m = { - 616, -1065, -1622, -1949, -1283, -863, 6819, 517, - 1135, 1282, 2631, -1447, -1477, -1004, 286, 1358, - -135, -340, 147, -130, 5435, -1609, -1916, -1758, - -1066, -1126, 478, 995, 1098, 1437, -1737, -1339, - -1864, -2009, -1038, -1004, -573, 810, 5974, 2840, - 349, -1559, -1496, -1151, -307, -82, 681, 827, - 550, 776, 1930, 166, -1100, -1489, -1185, -1182, - -1210, -326, 858, 1688, -2561, 3514, -736, 1555, - -59, -906, -123, 87, 102, 274, 1902, -459, - 3008, -984, -707, -334, -571, -317, -190, -371, - -2862, 607, 1346, -1517, -1220, -617, 2494, 697, - 190, 64, 3264, 3926, -1249, -1542, -933, -302, - -246, -248, 69, -283, -1766, -750, -1898, -1259, - 6841, -1546, -785, -64, 1208, 1294, -1522, -1742, - -1873, -1898, -1455, 7128, -752, 1718, 1398, 1123, - -2742, 4733, -1552, -2483, -2210, -495, 355, 864, - 830, 759, -2721, -2115, -1891, -1696, -1137, -1559, - -1265, -658, -591, 850, -699, 1262, -551, -1055, - 877, 96, -388, -192, -479, -1091, -2763, -1379, - 3290, 2331, -874, -307, -386, 615, 366, 133, - -2671, 5181, 4339, -894, -871, -634, -165, 409, - 91, -291, -2649, -411, 8039, -1947, -1156, 57, - 351, 1014, 472, -198, -1816, -590, 2887, -1702, - -1113, 3414, -556, 117, 483, -377, -1707, -1146, - -1155, 2518, 2014, -382, 3, -6, 206, -98, - 10770, 274, -1415, -1670, -1020, -1036, -786, -782, - -463, -552, -2500, 10460, -1624, -1787, -707, -1327, - -59, 375, 91, 22, -2776, -2343, -2104, 825, - -759, -823, 482, 1149, 1265, 570, -1676, -1826, - -1848, 6125, -1391, -820, -449, 844, 586, 535, - -2873, -2475, -2607, -2611, -1830, -487, 1643, 1680, - 2088, 2570, -2357, -993, 3189, -1473, 3506, -1203, - -793, 662, 464, 98, -2507, 1617, -1793, -1935, - -1307, -169, 9, 885, 728, 1178, -2010, -1346, - -1375, -187, -548, 2753, -464, -105, 799, 511, - -2170, -2428, -2177, -1497, 2072, 828, 441, 1020, - 873, 1000, -1297, -1531, -1863, -1967, -1516, -1088, - -758, -230, 1561, 6655, -2173, -1787, -1548, -1763, - -1366, -24, -645, 6836, 1480, 1923, -2728, -1859, - 1798, -2010, -1585, -677, -371, 1405, 1254, 1278 -}, - -.fcb16s = { - -2250, -2771, -2879, -2775, -2240, -1363, -272, 1233, - 6172, 5074, -2882, -2419, -2054, -2420, -1252, 347, - 1325, 1799, 1723, 4361, 774, 2066, 1874, 280, - -707, -605, -581, -662, -1104, -2038, 7111, -137, - -883, -1079, -1001, -54, -847, -1013, -1045, -832, - 4696, 3781, -624, -1485, -1360, -1359, -1307, -1219, - -866, -945, 5419, -1512, -2307, -2134, -2056, -1724, - -1653, -630, 157, 3399, -727, -860, -1381, -380, - -716, -1335, 3819, 78, -2, 277, -3185, -3118, - -2715, -3110, -1500, 1626, 3352, 3075, 1956, -539, - 16640, -1204, -2281, -2307, -2272, -2349, -2009, -2184, - -2777, -2375, -1015, 6208, -402, -1331, -1182, -763, - -730, -81, -591, -1184, -1927, 543, 4464, -1095, - -131, -542, -129, 486, -366, -1097, -1594, -554, - -15, -337, 3152, -723, 71, -40, 385, -309, - -769, 290, -853, -1058, -1196, -1557, -595, 3695, - 1129, 438, 1729, -1309, -971, -871, 90, 1418, - 1261, -23, -1382, -223, -1551, -713, -1044, 4495, - -160, -867, -1242, 1188, 159, 120, -1657, -951, - 1536, -159, -1310, 1101, -404, 155, 1717, -24, - -1607, 2347, 2056, -1943, -1313, -1297, -81, 34, - 1441, 354, -2110, -1873, -516, 1102, 2174, 2131, - 0, -946, -729, 61, 107, -14, -108, -50, - 42, -164, -177, -92, -29, 162, 1349, -2380, - -2099, -1692, -980, -49, -94, 331, 1317, 3819, - -482, -782, -775, -909, -640, -1099, -615, -225, - 1556, 2973, -630, 70, -186, -1599, -1076, 4440, - -890, 78, -76, -517, -855, -1886, -1521, -1206, - -1152, -900, 753, 1338, 1758, 2431, -2433, -1569, - -1294, -583, 552, 2040, -154, 250, 513, 2333, - -820, -1987, -2291, -2238, -1880, -1651, -1120, -262, - 2013, 9756, -2803, -2574, -2634, -2789, 356, -1838, - 325, 4584, 3584, 2486, -1524, 1874, -337, -1800, - -1659, 406, 2450, 1252, -245, -1030, 1985, -397, - -1565, -51, 148, 2039, -1212, -729, -700, -11, - 904, 649, 531, -2287, -1640, 766, -725, 171, - -1596, 1387, 3189, -672, -459, -794, -422, -714, - -195, -231, 185, 99, -952, -2248, -2170, -1190, - -457, 1458, 34, 1179, 2427, 1683, -1658, 3749, - -1816, -2000, 2823, -1243, -1415, 713, 875, 75 -}, - -.fcb22l_1 = { - 2198, -2215, -2251, -1966, -1540, -467, 403, 1647, - -2867, -2589, -34, -2314, -602, 2371, 2614, 2218, - -2494, 3659, 2708, -1076, -914, 233, 1149, 1425, - 319, -979, 1023, -682, 110, 239, 427, 703, - -2979, -2513, -2649, -2265, 7420, 526, 2174, 2932, - -2868, -2056, -2232, 1651, -1325, -856, -218, 2091, - 458, 1508, -1208, -845, 244, -441, 558, 752, - -700, -1370, -395, 980, -321, -232, -241, 293, - 10391, -1792, -1948, -1518, -1049, 43, 1524, 2033, - -2434, 303, 1730, -1205, -1432, -1183, -694, 1185, - -2531, -2656, -2751, -1756, -1321, -1100, 287, 8605, - -2868, -2554, 721, -2065, -1671, -771, 675, 2223, - -2690, -2501, -2313, 1829, 3189, 45, 1825, 2024, - -3153, -2824, -2729, -2308, 1686, -370, 482, 2606, - -2972, -2324, 2492, -1762, -1662, 28, 4976, 3214, - -2769, -316, -1146, -1954, 86, -60, -370, 1144, - 5519, -1785, -1538, -1044, -580, -89, 704, 1151, - -2586, -1094, 7473, -1220, -1076, -50, 1029, 1850, - 3546, 3279, -1806, -1191, -528, 682, 1160, 1341, - -2852, 1541, -2358, -1841, -2317, -1351, 993, 2417, - -2675, 2482, -2061, -2089, 3681, 626, 1619, 1818, - -2916, 2821, -2482, -2166, -1084, 1137, 5537, 2864, - -2499, -1782, 2156, 2558, -1117, 127, 1147, 1556, - -2572, 3865, -2008, -1805, -679, 119, 35, 1319, - -2704, -1872, -1756, 6843, -911, 322, 1641, 2461, - -2652, -1957, 1972, -1582, 3082, 84, 1086, 1487, - -2983, -2325, -2780, -2532, -1858, -279, 10092, 4519, - -2364, 2718, -1907, 2678, -1005, 246, 1499, 1679, - -2570, 8779, -2004, -1627, -844, 89, 1712, 2145, - 3316, -1763, -1642, 2819, -599, 9, 906, 1401, - -2289, -2224, 2462, -1580, -843, 2501, -24, 1310, - 3091, -1745, 2398, -1264, -731, 113, 831, 1328, - -2803, -2380, -2808, -2379, -2290, -1376, -234, 2242, - 3537, -2137, -2050, -1260, 2881, 177, 1158, 1424, - -3303, -3123, -3130, -2861, -2075, 2528, -43, 3890, - -3106, -2672, -2554, 1833, -826, 55, 4910, 3324, - 3993, -2176, -2446, -1848, -786, 3346, 1590, 2034, - -2725, -265, 303, 1076, -1985, 3661, 1556, 1983, - -3182, -2712, -2988, -2841, -1332, 4816, 6422, 4184, - -2230, -1248, -2176, -1806, -1617, -878, 3764, 1309, - -2280, 509, -211, 426, 773, 99, 513, 628, - 167, 196, -2256, -1802, -1157, 724, 1405, 1383, - 2384, -409, -672, -453, -205, -89, -12, 240, - 114, -2220, -807, -1302, -1612, -405, 1134, 1381, - 699, -1816, -2151, -1883, 2975, 928, 1527, 1565, - 775, -2141, -1981, -1532, -591, 3338, 683, 1763, - 466, -2028, -2086, 1448, -622, 589, 1294, 1150, - 145, -2382, -1093, -367, 986, 323, 404, 931, - -371, -2868, -2737, -2103, 129, 771, 1498, 1974, - -1481, -1060, -2398, -1125, 285, 2777, 2975, 1431, - -2720, 1748, -2375, -1847, -912, 3829, 808, 2034, - -2492, -2447, -1248, -991, 1449, 1304, 867, 1171, - -2999, -2556, -2763, -2298, 3359, 4277, 1991, 2850, - -2692, -2640, -2593, 1813, -458, 3068, 1012, 2049, - -3258, -2820, -2845, -2395, 2787, -45, 5457, 3568, - -2491, -2114, -1884, 6, -332, -232, 1680, 1139, - 2032, -2383, -2183, -1725, -914, 192, 4175, 2059, - -2922, -2972, -2920, -2210, -1143, 1850, 2468, 1871, - -3138, -99, -2651, -2510, -129, 631, 1677, 1925, - -3302, -3124, -3214, -3143, -2616, -761, 3978, 4234, - -1698, -824, -1975, -742, 2449, -610, 21, 998, - -3047, -2697, -2747, -1919, -1545, 7534, 1243, 3548, - -1863, -1257, 339, -1027, 122, -613, 1989, 953, - -2232, -1759, -1751, -969, -1591, 1917, -325, 889 -}, - -.fcb22m_1 = { - 13531, -1278, -2217, -1956, -1360, -892, -650, -866, - -255, 192, -1139, -1242, -2101, -1682, -1601, 2950, - 2340, 121, 662, 446, -2636, 1711, 615, -1864, - -1297, -1098, -296, 1070, 1284, 891, 7332, -2292, - -2334, -1889, -1170, 1884, -570, 52, 1146, 944, - -2083, -2192, -2420, -2165, -1542, -1474, -278, 4147, - 1506, 1666, 1014, -1657, -2225, -2261, 8568, -1445, - -523, -115, 999, 602, -2762, -2261, 271, -1797, - -1633, -790, 391, 907, 1302, 1076, -1907, -2219, - -2443, -1963, -1495, -1294, 4722, 935, 1691, 1370, - -2355, -1585, -2510, -2297, 2690, -1491, -647, 360, - 1460, 1479, -2041, 368, 10454, -1277, -716, -172, - -538, -287, 169, -232, 960, -1087, -2459, -2196, - -1189, -1967, -1586, -783, 5275, 2811, -1523, -1733, - -2373, -1946, -1586, -1280, -442, -205, 2330, 6319, - -2483, -2115, -2645, -2016, -1464, 89, 529, 1338, - 5291, 3186, 5770, -2311, -2696, -2420, -619, -2322, - 8434, -129, 1661, 1232, -1377, -1277, -1193, 406, - -1332, -1246, -999, -497, 1024, 1500, -2791, -1417, - -2173, 2419, -1492, -734, 2795, 559, 750, 519, - -2714, -509, 4622, 3679, -294, 73, -805, 602, - -99, 94, -2658, -1984, 6907, -1780, -1244, 272, - 874, 140, 1326, 693, -2679, -2274, -2551, 13351, - -2619, 4570, -1739, 2309, 1280, 1235, -1011, -2084, - -1968, -1404, 2568, 3147, -336, 270, 499, 506, - -1567, -2240, -2685, -1951, -2254, 2783, -1411, 8878, - 2321, 1691, -2567, -2450, -2572, -2286, -2038, -1803, - -1316, -315, 464, 1223, -1988, -927, -2035, 2165, - 3663, -919, -328, 229, -2, 217, -2773, -2160, - -2637, -2183, 5081, -1434, 1526, 2830, 1698, 1153, - -2810, -1132, 5408, -1992, 4267, -1357, 809, 563, - 9, -64, -2949, 7061, 4604, -1424, -1839, -610, - -251, 370, 901, 147, -2264, 3135, 3241, -1102, - -397, -1292, 39, 17, 380, 383, -1483, -1458, - 820, 2135, -646, -479, 173, 23, -274, -442, - -978, -1216, -1928, 7260, -1249, -956, -24, 250, - 438, 128, 4080, 152, 2677, -587, -667, -672, - -662, -492, -722, -688, -1907, -787, 3101, -1404, - -1234, -508, 3817, 424, 657, -86, -2179, -599, - 2141, -1446, -1847, 4341, -801, -26, -57, 216, - -1625, -802, 1752, -1301, 2617, -1545, -513, -401, - 234, 658, 1299, -1279, 874, -1408, -1135, -40, - -423, 394, 660, 684, 3341, -937, -1842, -1177, - 1945, -621, 19, -93, 141, -59, -2626, 3368, - -1588, -1959, -1506, 3729, -347, 218, 497, 585, - -2495, -2452, -2118, 578, -225, 378, 40, 1080, - 908, 761, -2070, -1607, 2534, -1535, 1493, 2664, - 215, 634, 317, -233, 4188, -1446, -2129, -1812, - -1428, -1579, -1038, 97, 989, 2038, 3671, -2707, - -2608, -2198, -1119, 1601, 1042, 1325, 1230, 1149, - -2566, -1054, 3659, -2173, -1772, -713, -1080, -101, - 987, 805, -1555, -749, -1510, 3443, -1402, 4172, - -696, 437, 276, 219, -2735, -2453, -2082, 3898, - -867, -582, -726, 1134, 1227, 1121, 2333, -963, - -1474, 2386, -959, -327, -138, 4, 268, 479, - -2889, -2896, -2701, -1975, -593, 1212, 1511, 1087, - 1482, 1612, -1703, 4874, 46, -1364, -1342, -544, - -879, -455, -488, -396, -2616, 849, -2424, -1976, - -1491, -739, 325, 1284, 1831, 1223, -48, -1457, - -2123, -1318, 1617, -1064, 2484, -467, 533, 707, - 351, 422, -525, -657, 202, -476, 133, -679, - -945, -832, 1906, -2981, -2605, -1911, -2541, 11553, - -1585, 1555, 2196, 1616, -2669, -2345, -2423, -1848, - -1756, 4918, -711, 1186, 1873, 1399, -672, -1401, - -1524, -1138, -674, 1285, 195, 884, -377, -1067, - -2125, 377, -1747, -1604, 837, -334, -115, -59, - 160, 483, -2220, 12861, -1633, -1616, -926, -1203, - -113, -90, 378, 148, 5740, 88, -2246, -1598, - -1546, -1694, 2790, -72, 590, 28, -2608, 4312, - -1068, 3091, -632, -651, 366, 63, 744, 375, - 1746, 2753, -2075, -1621, -1033, -471, 972, 199, - 575, 655, -2148, 2407, -2180, -1764, -1030, -1089, - 4083, -80, 417, 384, 1196, -2284, -2549, -1771, - -773, 213, 1188, 788, 1343, 1358, -2584, 7723, - -2171, -2301, -1497, -438, 1001, 110, 671, 939, - 6435, 5777, -1765, -1287, -1181, -1014, 87, -919, - -422, -444, -1930, 4906, -1660, -1558, 3617, -1177, - 261, 9, 261, -47, -2539, 2749, -2476, -2298, - -1047, -1319, -341, -604, 2111, 2779, -2935, 5011, - -1860, -2363, -1686, -1033, 800, 1774, 1700, 1478 -}, - -.fcb22s_1 = { - 11523, -796, -1488, -1897, -1888, -1691, -1767, -1794, - -1622, -1210, -2284, -2777, -2382, -1371, -238, 2997, - 3182, 588, 1129, 704, 248, 1703, -264, -1306, - -1147, -560, -1513, -956, 1667, 1340, 5220, -2276, - -2215, -2049, -1479, -1294, -774, 66, 1270, 2075, - -1435, -1981, -2322, -1896, -1321, -462, 138, 5022, - 2549, 1683, -100, -1744, -1528, -423, 6093, -61, - -288, -623, -650, -828, -1521, 134, 1240, -1399, - -1450, 612, -969, 2585, 945, -312, -1138, -2488, - -2513, -1988, -1607, -773, 3384, 1192, 2651, 2580, - -984, -2015, -1465, -1576, 2273, -1221, 91, 2615, - 840, 1299, -1069, -2151, -1899, -735, 440, 888, - -241, 502, 953, 3613, 1806, -1855, -2303, -1758, - -1318, -1484, -10, 597, 3723, 1992, -488, -2063, - -2284, -2172, -1905, -1547, -937, -18, 3276, 7184, - -1942, -2302, -2399, -1972, -1378, -635, 302, 1081, - 5454, 3358, -447, -807, 205, -1805, -1546, -446, - 6364, -916, 151, -377, -582, -856, -204, -731, - -884, -674, -257, -67, 1564, 2486, 1003, -1508, - -1692, 1515, -889, -622, 2366, 9, -17, -245, - 3733, -1057, -284, 3197, -31, -440, -1115, -1609, - -1834, -1930, 230, 262, 7344, -39, -1746, -562, - -1554, -1838, -1648, -1310, 2157, 80, -102, 238, - -823, -622, -720, -115, -274, 16, -1562, -1785, - -1535, -334, 2604, 3388, -410, -103, -348, -142, - 1676, -441, -2267, -1988, -1421, -680, 1302, 2682, - 383, -10, 1487, -1086, -251, -1134, 141, -84, - -1003, -898, 95, 2304, 802, -1549, -1562, 2650, - 2180, 64, -512, -832, -705, -429, 1826, -2283, - -1976, -1277, 2699, 504, 249, -9, 178, -33, - -1357, -1138, 3005, 293, 229, 1633, -197, -540, - -1245, -1617, -1269, 6639, 2437, -647, -1501, -1097, - -1051, -1150, -1183, -1461, 71, 1529, 2847, 1149, - -705, -1345, -1605, -629, -617, -60, -2081, -1435, - 938, 844, -1055, -841, 1179, 392, 1112, 946, - -1252, -1728, -266, 7063, -1335, -920, -1048, 206, - 48, -619, 4764, 274, 2394, -799, -798, -1003, - -1278, -1800, -1626, -1415, -498, 1439, 1643, -1978, - -1258, -1136, 1285, -9, 596, 141, -2211, 908, - 802, -470, -1125, 3216, -234, -412, 3, -980, - 15, -1047, 1530, 660, 1986, -480, -499, -550, - -733, -531, 1326, -1607, 787, -1136, -1002, -65, - 358, 743, 253, -294, 3498, -1033, -1270, -790, - 537, 1788, 309, -72, -1241, -1999, 609, 2981, - -1025, -1642, -958, 3845, -1221, -962, -965, -1612, - -1993, -33, -1136, 1086, -46, 1178, -229, 139, - 644, 718, -1696, 2411, 1019, -1056, 52, 224, - -487, -395, -40, 125, 3001, -1955, -1950, -784, - -1111, 897, -514, 159, 785, 1095, 2944, -2554, - -2407, -1975, -632, 1030, 1712, 366, 463, 125, - -2354, -796, 5663, -1055, -1151, -870, 348, -676, - 1447, 215, -1005, -1531, -910, 2249, -438, 2889, - 107, -404, -271, -534, -1022, -2117, -1738, 2261, - -257, -788, 32, 1747, 1196, 910, 33, 1, - -23, 28, -25, 19, 13, -29, -23, -48, - -907, -2113, -1978, -1426, -535, 1589, 1908, 2724, - 1646, -897, 758, 2326, 674, -1449, 111, 220, - 475, -162, -1465, -2036, -528, 1308, -2087, -2031, - -1308, 183, 35, 1097, 1008, 1864, -2116, -2303, - -1928, -261, 2342, -292, 1480, 268, 1582, 1079, - -1183, -1154, -777, 309, 1218, 683, 1314, 1677, - -758, -1745, 1422, -1331, -1638, -1100, -303, 5003, - -57, -379, -511, -756, -727, -2315, -1860, -1775, - -676, 3854, -67, -52, 2018, 1532, -160, -197, - -75, -1934, -1134, 2025, 1810, -491, 83, 646, - 390, -297, -441, -342, -479, -486, -296, -30, - 443, 1151, 3508, 6119, -493, -1427, -1393, -1273, - -1280, -1687, -1683, -1511, 5109, -1008, -1137, -638, - -649, -342, -590, -478, -577, -349, -579, 2548, - -463, 2107, -568, -678, -788, -454, -608, -452, - 1934, 1485, -1746, -1007, -1174, -573, 239, -119, - 679, -76, -1687, 1956, -898, -477, 456, -156, - 1460, 13, 92, -987, 554, -2772, -2578, -1694, - -235, 753, 1527, 1106, 1539, 1342, -1305, 6560, - -1526, -1765, -793, -600, 248, -542, -63, -421, - 4828, 1288, -1580, -1826, -1163, -1014, -221, -818, - -109, -61, 1265, 1939, -1265, -414, 1912, -190, - -1157, -675, -756, -935, 2529, 136, -1709, -1727, - -1819, -1504, -1232, -959, 1128, 4142, -1945, 2958, - -900, -1432, -1720, -1380, 381, 1473, 1235, 1062 -}, - -.fcb22l_2 = { - 2441, -2086, -2129, -2146, -1839, -1035, 295, 2465, - -2785, -2597, -81, -2162, -991, 3060, 3056, 2985, - -2415, 4009, 3058, -1165, -1281, -322, 629, 2232, - 481, -2255, 1165, -1455, -621, -29, 923, 1371, - -2822, -2421, -2596, -1908, 6338, 279, 1845, 3532, - -2955, -2571, -2554, 744, -1785, -909, 775, 3156, - 738, 1760, -458, -590, -73, 22, -91, 326, - -1098, -1511, -1000, 1741, -1024, -562, -399, 736, - 9669, -2109, -1872, -1539, -1208, -265, 994, 2364, - -2121, -98, 1523, -1427, -1450, -1157, -294, 1375, - -3007, -2669, -2847, -1777, -1196, -1257, 1065, 9128, - -2948, -2509, 470, -2521, -1947, -728, 503, 3810, - -2538, -2469, -2217, 1957, 2580, -229, 1212, 2263, - -3174, -2660, -2792, -2692, 1226, -512, 555, 3960, - -2979, -2426, 1978, -2182, -1868, -455, 4681, 4580, - -2514, -1642, -1029, -1712, 416, -838, -362, 1208, - 5211, -2128, -1867, -1337, -549, -70, 828, 1508, - -2272, -1611, 7307, -1612, -1244, -461, 749, 2510, - 3669, 3236, -1845, -1333, -866, 268, 850, 1686, - -2805, 1079, -2258, -2075, -2017, -1115, 214, 2735, - -2719, 2676, -2154, -1976, 2884, 393, 1247, 2382, - -3043, 2188, -2703, -2353, -1861, -208, 4419, 4511, - -2187, -1630, 2246, 2331, -1105, -198, 818, 1721, - -2180, 3571, -1841, -1738, -1020, 14, 407, 1028, - -2536, -2171, -2115, 6630, -968, -306, 1438, 3574, - -2411, -1857, 1911, -1546, 2709, 57, 910, 1727, - -3159, -2565, -2675, -2746, -2017, -534, 8461, 6103, - -2299, 2912, -1851, 2660, -1479, -97, 1148, 2204, - -2510, 8781, -2194, -1790, -1114, -110, 1140, 2885, - 3261, -1921, -1633, 2766, -788, -403, 610, 1651, - -2515, -2021, 2415, -1606, -1149, 2479, 297, 1693, - 3823, -1538, 2514, -1261, -904, -236, 550, 1581, - -2903, -2440, -2922, -2749, -2480, -1849, -423, 3613, - 3420, -1876, -1929, -1537, 2955, 58, 1014, 1950, - -3295, -3009, -3161, -2926, -2353, 2355, 351, 5502, - -3140, -2745, -2781, 1247, -1037, 538, 4939, 4382, - 3584, -2284, -2321, -1844, -743, 3156, 1546, 2358, - -562, -101, -497, -1196, -1023, 1972, 1255, 1374, - -3146, -2824, -3057, -2757, -1736, 3746, 5609, 5118, - -2155, -1665, -1701, -1780, -1975, -1127, 3185, 2036, - -2540, 324, -481, 311, 624, 719, 543, 1030, - 550, 513, -2430, -1817, -1129, 62, 1526, 1809, - 2172, -1314, -1035, -586, -292, 233, 209, 543, - -252, -2372, -1961, -1629, -1306, -408, 451, 1339, - 792, -2619, -2316, -1624, 1941, 678, 977, 1710, - 428, -2499, -2369, -2101, -1448, 2988, 874, 2497, - 451, -2263, -2204, 1403, -631, 694, 1424, 1658, - -243, -2104, -378, 355, 1446, 373, 377, 973, - -756, -2802, -2508, -2081, 177, 352, 2428, 2359, - -1533, -2710, -2544, -1102, 419, 3132, 1222, 1942, - -2756, 1844, -2429, -1854, -1283, 3960, 1633, 2917, - -2858, -2784, -2106, -1025, 1588, 905, 1092, 1657, - -3028, -2715, -2782, -2218, 2852, 4006, 2534, 3726, - -2783, -2355, -2146, 2113, -1201, 3361, 1178, 2670, - -3199, -2796, -2682, -2489, 1905, -471, 5097, 4436, - -2197, -1078, -2327, 420, -637, 10, 1647, 1362, - 1815, -2519, -2363, -2174, -1454, -31, 4125, 3446, - -3054, -2953, -2738, -2328, -1636, 1086, 2238, 2132, - -3089, -432, -2674, -2515, -168, 745, 2236, 2305, - -3214, -2953, -3159, -3086, -2748, -1200, 3346, 5127, - -1150, -501, -2109, -1662, 2301, -401, 651, 1320, - -3072, -2608, -2833, -2249, -1387, 7704, 1811, 4960, - -2474, -2589, 83, -499, -785, 194, 1312, 1442, - -2716, -1663, -2088, -1812, -1396, 1862, -369, 1397 -}, - -.fcb22m_2 = { - 8809, -2291, -2452, -1982, -1356, -423, 419, 588, - 897, 1086, 79, -2155, -1957, 367, 1080, 233, - 718, 441, 515, 642, 730, 2454, 774, -2299, - -1526, -784, -359, 96, 385, 482, 4905, -2501, - -2431, -2047, -1139, 131, 743, 999, 1243, 1294, - -2154, -433, -2461, -2201, -1552, -163, -200, 4009, - 1731, 1652, -2381, 5295, -1457, -895, 3480, -1230, - -94, 471, 554, 669, -2458, -1271, 278, -2238, - -1852, -813, 888, 1032, 801, 1008, -258, -538, - -1744, -2087, -1651, -1239, 2222, -4, 783, 882, - 478, 782, -1335, -1453, 1728, -627, -387, -205, - 221, 193, -2282, -518, 7464, -1808, -1134, -199, - 340, 321, 410, 617, 2278, -436, -2082, -1958, - -1493, -885, 628, 794, 855, 989, 232, -1115, - -2617, -2152, -1290, -1299, -458, 222, 3936, 3349, - -2240, -2787, -2689, -2255, -1241, 816, 2307, 1566, - 1685, 1723, 2960, -2134, -2532, -1798, -1128, -1073, - 5380, 1013, 1525, 1415, -1976, 456, -538, -1433, - -1347, 22, -496, 284, 387, 465, -2214, -1863, - -2261, 1049, -1487, -1222, 1610, 621, 1000, 1116, - -2393, -731, 4075, 2375, -1178, -908, -383, 327, - 543, 572, -2071, -2039, 3310, -1903, -1502, -72, - 123, 693, 721, 918, -1866, -1251, -1065, 5630, - -1574, -541, 1, 1014, 813, 887, -2145, -2421, - -2176, -1756, 1856, 408, -1, 759, 1109, 1276, - 3053, -2705, -2467, -2068, -1160, 1405, 459, 1167, - 1219, 1318, -2198, -2037, -2005, -2204, -2039, -1473, - -1529, 264, 1333, 1822, -2121, -1434, -472, 1901, - 2448, -589, -424, 248, 376, 602, -1571, -1032, - -1243, -1619, 5682, -1162, 362, 570, 865, 852, - -1875, -805, 4258, -1569, 2992, -1175, 51, 164, - 314, 648, -2083, 5574, 2553, -1866, -1156, -642, - -198, 330, 446, 602, -2365, 1601, 2873, -2043, - -1510, -1142, -20, 588, 535, 676, -2207, -1637, - 626, 745, -1548, -590, 745, 540, 505, 618, - 749, -1389, 857, 1387, -398, -606, -75, -86, - 11, 78, 3322, -1347, 1978, -1431, -745, -280, - -42, 135, 350, 376, -508, -1349, 2961, -1184, - -647, -1257, 3009, -374, 523, 616, -1848, -41, - 2652, -1609, -1603, 3284, -24, 502, 122, 448, - -2337, -1029, 734, -1533, 1523, -1312, -754, 335, - 510, 774, 769, -117, 139, -1254, -1468, -965, - -375, 2, 227, 518, 3187, -1524, -776, -1253, - 2977, -530, 319, -61, 244, 413, -2290, 3085, - -1763, -1480, -1374, 3272, -87, 323, 421, 652, - -2317, -2182, -1604, -1, -801, 1320, -156, 907, - 799, 918, -1494, -2205, 1137, 69, 1249, 3437, - 925, 29, 419, 448, 3574, -1564, -1713, 2374, - -941, -252, 123, 263, 366, 539, 1059, -1856, - -1753, 766, -1704, 106, 262, 596, 684, 820, - -2503, -1878, 1835, -594, -1024, -2105, -1567, 488, - 794, 883, -1626, -613, -1410, 2846, -1413, 3557, - -348, 460, 332, 577, -907, 700, -1680, 1130, - -1637, -793, -160, -38, 473, 630, 1487, 1872, - -1526, 1379, -806, 121, -383, 149, 259, 413, - 759, -2817, -2758, -2290, -1348, 460, 1782, 1536, - 1513, 1503, -2265, 3193, 117, -1704, -1367, -487, - 125, 365, 594, 651, -2287, 1272, -2537, -2038, - -1515, -578, 2994, 582, 941, 1058, -1556, -1583, - -720, -1584, 956, -1032, 1861, 146, 402, 429, - -2184, 1667, 1241, 289, 52, -232, -265, 210, - 248, 331, 1133, -1813, -1869, -1429, -1484, 5620, - -400, 1316, 1146, 1150, -1975, -818, -1921, -2054, - -1768, 2953, -544, 426, 856, 1107, 493, -2019, - 176, -1915, -1040, 717, -91, 728, 647, 776, - -2360, 739, -2136, 30, 636, -447, -116, 498, - 531, 775, -2250, 8607, -2075, -1928, -1072, -450, - 38, 439, 558, 778, 4484, 1056, -1830, -1716, - -988, -412, 260, 56, 425, 579, -2243, 4094, - -1267, 2172, -990, -562, 97, 304, 533, 609, - 790, 780, -2029, -1947, -1327, 1224, 255, 344, - 516, 660, -591, 1702, -118, -1402, 396, -1387, - 2268, -247, 177, 355, 1393, -2318, -1975, -1563, - 863, -939, -365, 411, 800, 1019, -2370, 4656, - -2301, -2111, -1679, -698, 458, 788, 1004, 1138, - 2285, 4924, -1940, -1955, -1159, -436, 237, 5, - 300, 364, -2492, 2165, -2021, -2072, 1504, -612, - -93, 249, 676, 799, -2411, 1952, -1752, -2418, - -2285, -1323, -621, 837, 1043, 1266, 76, 3160, - -2176, -2176, -1717, -1105, 1045, 410, 728, 940 -}, - -.fcb22s_2 = { - 6946, -1850, -1986, -1590, -1276, -1063, -1026, -1017, - -805, -346, 9, -2911, -2843, -1899, -198, 2193, - 3325, 1315, 37, -528, -371, 599, -751, -2157, - -1912, -855, 988, 1222, 1085, 953, 3212, -2793, - -2564, -1707, -657, 683, 1109, 683, 647, 446, - -1906, -2315, -2569, -2428, -1698, -600, 1100, 3790, - 3368, 2172, 2017, -895, -1354, -734, 2552, -403, - -68, -402, -752, -932, -1205, -1937, 572, -1434, - -500, -579, 291, 1723, 1312, 1695, -238, -1715, - -2029, -1525, -816, -363, 2816, 167, 2196, 1793, - 897, -1081, -262, -1338, 1052, -1231, -94, 1296, - 503, 184, 588, -2057, -911, -1933, -1769, 167, - 1013, 1774, 1414, 1289, 2406, -1906, -2055, -1952, - -1726, -1618, -451, 575, 3021, 2569, -776, -1649, - -2111, -1930, -1499, -1349, -595, 329, 3090, 5458, - -1954, -1309, -1554, -1159, -1132, 329, 714, 760, - 2529, 2417, 1046, -1025, -1114, -1325, -154, -1501, - 4160, -696, 230, 398, -2010, 385, -1344, 36, - -1269, -987, 1009, 1453, 1163, 1591, 916, -1534, - -508, 221, -1596, -1130, 1394, 539, 676, 676, - 1263, 2029, 284, 1592, 161, -124, -572, -1362, - -1946, -2148, -1488, -222, 4967, -1202, -939, -375, - -80, -593, -445, -418, -781, -1560, 31, 4757, - -1417, -954, -402, 193, -316, -278, -926, -895, - -1024, -436, 2673, 1991, 254, 28, -861, -1291, - 1475, -2708, -2689, -2118, -703, 290, 1841, 2048, - 1213, 594, 132, -2598, -2427, -988, -1111, -158, - 478, 2118, 2571, 830, -1430, -678, -773, 1340, - 2473, -798, -751, 215, 274, -65, 335, -1947, - -1796, -1436, 3862, -611, 105, -31, 775, 669, - 1439, -1266, 1670, -739, -1259, -572, -17, -107, - 176, 130, 3899, 3478, -548, -1429, -1176, -1104, - -1147, -1503, -1277, -1068, -258, 2645, 1753, -333, - -827, -1306, -827, -502, -306, -119, -1602, -1644, - 1922, 1127, -628, -1073, 348, 195, 616, 685, - 1750, -898, -1852, 1813, -700, 254, 598, -234, - -433, -1035, 2502, 94, 467, -1672, -905, 776, - 679, -11, -1071, -1845, -1083, -320, 690, 110, - -708, -1077, 2514, 70, -412, -300, -371, -717, - 1700, -1625, -1346, 1954, 14, -64, -121, 181, - -673, -909, 2274, -1389, 2058, -1503, 306, -187, - -209, -69, 1523, -632, -695, -1283, -988, -569, - -798, -521, 398, 2834, 1953, -2215, -1626, 106, - 6, -498, -57, 173, 731, 1002, -1706, 1701, - -328, -1745, -1398, 2176, -19, 311, 492, 667, - -1073, -1803, -1684, 703, -1316, 1803, 659, 913, - 906, 1033, -1982, -102, 945, -1620, 718, 555, - 613, 38, 394, 421, 2738, -1159, -2248, -1852, - -1568, 33, 363, 1490, 935, 561, 1464, -2466, - -1209, -1204, -692, 2009, 129, 354, 372, 380, - -2053, 1122, 2272, -824, -1355, -926, -122, 567, - 526, 923, -1320, 59, -226, 1674, -1512, 1498, - -631, 221, 26, -247, -40, -1615, -1597, 2111, - 34, -813, 200, 219, 758, 1000, 306, 394, - -430, -117, -409, -81, -207, 16, 36, 176, - -1737, -2898, -3005, -2214, -568, 2140, 4132, 2592, - 504, -521, -1509, 3610, 1070, -1890, -1319, -11, - 174, -148, -212, -347, -464, -1068, -2568, -2532, - -1973, -519, 2104, 3713, 1882, -145, -1319, -2375, - -1862, -843, 2061, -266, 1465, 866, 912, 1183, - -1784, 2072, 205, -375, 1112, -374, -534, -430, - -162, -204, 375, 82, -823, -1148, -752, 4681, - -339, -247, -790, -1088, -494, -2302, -2310, -1603, - 46, 3367, -50, 393, 1383, 1457, -1377, -2005, - 643, 326, 312, 1189, -225, 563, 261, -70, - -667, -1191, -2255, -470, 1000, 142, -525, 2285, - 756, 2061, -953, 5888, -1339, -1534, -1252, -16, - -116, -305, -375, -596, 3611, -889, -511, 43, - -809, -659, -737, -510, -258, -108, -1515, 2806, - -1555, 1025, -932, -601, 146, 164, 207, 71, - 1606, 93, -2420, -2311, -1641, -244, 1785, 804, - 1040, 427, -1510, 38, -2490, -1987, 44, 699, - 1407, 988, 1061, 411, 1162, -1382, -2669, -1635, - -905, 1503, 674, 1357, 869, 244, 411, 2612, - -1792, -2147, -1693, 1434, 281, 38, 228, 424, - 2291, 1354, -2128, -1377, -1014, -609, 131, -151, - 418, 602, 111, 2200, -1547, -1153, 1435, -1282, - 6, -111, -1, 92, 238, 613, -2271, -1181, - -1455, -919, -182, 1066, 1932, 1679, -1715, 2825, - -1764, -1759, -741, -829, 501, 746, 1056, 1416 -}, - -.fcb44l = { - 4868, -1851, -2031, -2019, -1751, -552, 756, 929, - 1389, 1590, -2090, -1202, -1317, 516, -1798, -1020, - -694, 4322, 1388, 1904, -2605, -1239, 1005, -757, - -1248, -358, 699, -201, 409, 1093, -2901, -2254, - -2605, -2595, -2104, -1681, 6854, 2692, 3155, 3446, - -2535, -1421, -1745, 898, -2046, -1457, -1044, -269, - 1748, 1873, -2268, -1098, 407, -1865, -2103, 1510, - -1217, -399, 1718, 2017, 3638, -1685, -1547, -1480, - 1637, -744, 580, 586, 1313, 1409, 617, -2020, - -1919, -2179, 932, -937, 559, 1795, 1528, 1596, - -2867, -2553, -2507, -2653, -2365, -1985, -170, 8679, - 4271, 4273, 2263, -1835, -1934, -1719, -1778, 2357, - 125, 1319, 1543, 1765, 3689, -1215, 2369, -1533, - -1611, -771, -123, 1005, 1297, 1465, -2491, 2631, - -1636, -1655, 1244, -1178, 386, 961, 1300, 1553, - -2357, -2404, -2305, -2177, -1714, -383, -98, 258, - 3902, 2475, -2923, -2580, -2685, -2803, -2678, -2428, - -1247, 450, 8174, 5035, -2302, -1629, -1495, 1832, - 1616, -577, 639, 872, 1122, 1437, 785, -1947, - -1976, 823, -1909, -1005, 430, 1244, 1713, 1664, - -2537, 8025, -1705, -2005, -2030, -1155, 64, 1106, - 1975, 2277, -2410, -2639, -2292, -1858, 162, 744, - 555, 1559, 1719, 1806, -2282, -1982, -1914, 1415, - -1785, 2197, 254, 763, 1338, 1741, -2509, -1991, - -2328, -1853, -2299, 5145, -34, 1495, 2913, 3018, - -2009, -1736, 2411, -1595, 1877, -1316, 693, 1042, - 1565, 1744, -2657, -2161, -2222, -2135, 4454, -1784, - 1331, 3208, 2852, 2955, 3738, -1338, -1425, 2090, - -1601, -279, -2, 712, 1220, 1436, -2385, -1265, - 7093, -1561, -1742, -1003, 283, 1009, 1843, 2055, - -2251, -2175, 2310, -1321, -1976, 1874, 164, 2781, - 2721, 2487, 2519, -1101, -1539, -1575, -1487, -724, - -25, 355, 643, 1011, -2296, -1799, -1895, -1700, - 2743, -924, -254, 32, 1504, 1910, -2811, 898, - -2363, -2518, -2408, -1737, -936, 221, 2588, 2527, - -2535, -2360, -2477, -1861, -1882, 1833, 3587, 1307, - 2141, 2274, -433, -1994, -1692, -1318, -1398, -350, - 1518, 1923, 835, 1262, -2246, 3383, 2458, -1464, - -1874, -983, -157, 531, 1490, 1729, 9543, -1713, - -2011, -2015, -1870, -969, -34, 1160, 1724, 1919, - -2530, 140, -1923, -1730, -1720, -605, 629, 1577, - 974, 1373, -2268, -1582, -933, 1124, -1624, -514, - 4156, -118, 1515, 1907, -2267, -574, -1311, -954, - -47, -1259, 15, 364, 854, 1009, -2221, 629, - 994, -1646, -1324, -1509, 2359, 3453, 1393, 1912, - 3586, -2286, -2537, -2560, -2415, -1748, -368, 3093, - 2881, 2611, -2556, 2792, -1558, 1117, -1681, -65, - -36, 516, 1233, 1514, 531, -1814, 998, -1795, - -1693, -871, 725, 868, 1504, 1465, 907, 300, - -2060, -2366, -2392, -1881, -596, 1754, 2169, 2104, - -2755, 2709, -2298, -2627, -2423, -1875, -733, 3886, - 2648, 2821, 623, -541, -163, -319, 85, 84, - 15, 716, 511, 572, 3948, 2773, -1504, -1746, - -1832, -934, -78, 988, 1277, 1518, -2678, 2216, - -2162, -2331, -2076, -968, 3445, 1070, 2077, 2206, - -2892, -2425, -2674, -2905, -2844, -2584, -1381, 3269, - 2696, 3281, -2090, -369, -1515, -1367, -200, 2089, - 739, 700, 866, 1169, -2276, -1057, 2851, 2589, - -1686, -515, -65, 579, 1278, 1593, -2837, -2458, - -2565, -2783, -2843, -2468, -1704, -1531, 1475, 4153, - -2209, -1857, -1873, -2177, 758, -1531, 3207, 1163, - 1506, 1851, -2383, -1683, -1839, 5772, -1815, -465, - 361, 1086, 1912, 2140, -2629, -1688, 1608, -2190, - -2419, -2064, -1253, 1397, 2099, 2306, 513, 1664, - -1683, -1629, -1682, -109, 269, 695, 1072, 1317, - 208, -1602, -1918, -1038, -813, 312, 24, 26, - 761, 990, -2288, -2225, -1948, -1932, -1832, -949, - -450, 920, 805, 1468, -2897, -2633, -2557, 464, - -2174, -1157, 1170, 2230, 2550, 2522, -2643, -1928, - -2255, -2578, 82, -2206, -63, 2663, 2007, 2292, - 226, -2541, -2687, -2753, -2229, -1556, 785, 3837, - 2331, 2492, -2496, -1740, -2465, -2295, -2151, 1142, - 363, 3967, 1943, 2432, -2619, -2400, 520, -2274, - -1900, -1486, 2135, 1407, 2300, 2288, -2811, -3066, - -3128, -3098, -2529, -1475, 2172, 3413, 3613, 3571, - 564, -2347, -2257, -2377, -1944, -1771, -582, 509, - 1683, 1975, -285, -2136, -2529, -2464, -2117, 278, - 1094, 1042, 2192, 1976, 1781, -1874, -2042, -2103, - -1744, -1044, 3373, 1252, 1861, 1873, -2688, -1849, - -2462, -2494, -2105, -1903, 2221, 250, 1653, 2233 -}, - -.fcb44m = { - 13151, -1763, -2583, -2518, -2181, -1036, -537, -112, - 214, 590, -608, -2270, -2228, -1301, -1018, 3687, - -471, -282, 909, 1665, -2426, 1713, -808, -1240, - -1366, -976, -140, 1730, 683, 191, 7253, -2076, - -2733, -2698, -2253, -1116, 376, 687, 1314, 1532, - -820, -1471, -2092, -2047, -1796, -1347, -732, 6348, - 2529, 1441, -1460, -1845, -1046, -1643, 8086, -928, - 90, 660, 428, -188, 604, -2022, 556, -1680, - -1641, -902, 834, 941, 1480, 1906, -2439, -2573, - -3091, -2853, -2419, -1606, 2312, 2624, 2659, 2659, - -1286, -2273, -2400, -1826, 2443, -1391, 685, 1822, - 1810, 1625, -1993, -731, 9737, -1476, -1183, -1244, - 34, -85, 0, 201, 4171, -2430, -2869, -2866, - -2488, -1154, -1253, 282, 2715, 3643, -2130, -2522, - -3259, -3051, -2977, -2204, -1264, 1103, 7113, 7948, - -1271, -1694, -2011, -1294, -1607, 247, -303, 715, - 4276, 1908, -2337, -2111, -2232, -2123, -1648, -1302, - 7686, 1213, 982, 984, -2594, -2127, -1981, -2104, - -2405, -1966, -936, -95, 326, 672, -2263, -893, - -1367, 1288, -1321, -1351, 2503, 747, 390, -247, - -2220, -860, 3641, 3766, -1724, -1487, -531, 239, - 134, -82, -2563, -1537, 3883, -1911, -2109, -1713, - 1056, 726, 977, 1091, -1874, -1366, -1628, 11069, - -1653, -696, 118, -78, 337, 29, 2449, -1438, - -601, -1533, -816, 1262, 540, 79, -460, -1403, - 3204, -1918, -1892, -1911, -1468, -976, -42, 2785, - 1088, 564, -236, -2267, -2324, -2130, -1880, -427, - -258, -543, 903, 5142, -1791, -1611, -1073, 2911, - 2993, -1295, -400, 229, 192, -85, 4461, -1711, - -1431, -1640, 3525, -1398, -101, -219, 327, 415, - -669, -1520, 6595, -1291, 5123, 155, -480, -518, - -552, -890, -2609, 7074, 3220, -1054, -1852, -1165, - -25, 89, -361, -140, -1610, 2214, 2903, -1737, - -1704, -1178, -708, -171, 177, 674, -1075, -890, - 82, 463, -1432, -1048, -703, -759, -247, 344, - 2448, -656, -1135, 4366, -583, -705, 40, -314, - -676, -1271, 4389, -952, 3249, -1606, -1524, -1172, - -490, 97, 128, -91, -66, -1293, 1696, -1114, - -1455, -519, 2620, 479, -257, -1512, -2037, -1281, - 1752, -1285, -1812, 2789, -52, 676, 409, 296, - -1977, -1043, 270, -1615, 2131, -1051, -161, -498, - 767, 1673, 1044, 27, -1107, -1730, -1856, -1264, - -275, -167, 893, 443, 3850, 97, -1244, -1691, - -1566, -1088, -1062, -837, -159, 1830, -1424, 2494, - -1878, -1532, -1991, 2919, 62, 399, 524, 381, - -1340, -2415, -2028, 218, -1342, 410, 815, 533, - 948, 1998, -1213, -1847, 3691, -2123, 1822, -1548, - 537, 987, 356, 123, 3876, -2476, -2021, -2195, - -1562, -737, 2250, 709, 797, 1102, 2065, -2258, - -2394, -1816, -1536, 1059, 4653, 1457, 456, -27, - -2226, -736, 765, -1879, -2188, -1793, -928, 892, - 1793, 2257, -1182, -1646, -1789, 6105, -1936, 4316, - -307, -143, 223, 236, -2213, -1862, -1823, 3326, - -1810, -1384, -453, 1007, 1331, 1405, 4135, -2298, - -1657, 1981, -1702, -853, -318, 298, 760, 1025, - -2537, -2782, -2985, -2687, -2839, 4493, -448, 4249, - 3048, 2678, 1045, 3227, -690, -1390, -976, -652, - 587, 194, -749, -1358, -730, 250, -2404, -2548, - -2157, -1027, 32, 2091, 1059, 1360, 262, -2135, - -2061, -1777, -1614, -246, 2004, 2605, 1516, -948, - -1060, -1076, -1643, -748, 144, 1595, 1730, 531, - -1086, -2182, -483, -2191, -2411, -1983, -2345, 10051, - -841, 1456, 924, 207, 4652, -1831, -2026, -1710, - -2235, 4036, -755, -70, 533, 887, -1899, -2326, - -2129, -2115, -1606, 1443, 2557, 941, 618, 527, - 949, -1547, -2067, -1785, 455, -60, 79, 202, - 912, 954, -2527, 14551, -1893, -2315, -2609, -1844, - 497, 287, -197, 626, 6839, -804, -1299, -1259, - -1109, -97, 976, 144, -343, -1375, -2334, 3740, - -1049, 2980, -1739, -474, 223, 137, 155, -171, - 2962, 1814, -2378, -2643, -2249, -1109, 858, 643, - 1630, 1399, -2098, 974, -1718, -2193, -2146, -1488, - 3353, -147, 1187, 1266, 1559, -2532, -2941, -2759, - -2101, -1098, 1562, 1049, 2045, 2159, -2298, 7439, - -2129, -2361, -2318, -1552, -422, 482, 985, 1111, - 6050, 5657, -1698, -2267, -2127, -1135, -140, -286, - -352, -124, -1230, 3492, -1370, -1221, 2958, -1239, - -472, -722, -169, -89, -2310, 2988, -2367, -2421, - -2589, -2034, -662, 421, 1863, 2736, -2612, 5429, - -2104, -2257, -2440, -1817, 4819, 883, 622, 636 -}, - -.fcb44s = { - 11239, -328, -2011, -1713, -1662, -1290, -1225, -1520, - -1541, -912, 400, -1103, -2698, -162, 263, -964, - 668, 405, 732, 2493, -2491, 1000, -2910, -793, - -1351, -515, 1051, 2002, 1757, 2150, -2010, -2021, - -2254, -1896, -1953, 664, 7067, 2632, 531, -1367, - -2228, 2113, -2019, 2309, -1458, -426, 1242, 338, - 205, -222, -1317, -1806, -2477, -2427, -2477, -1852, - -1472, -911, 2261, 10280, -2369, 382, 3180, -1210, - -1601, -748, -732, 504, 1440, 1142, -13, 610, - -2457, -739, -1318, -1013, -52, -470, 627, 4734, - 1248, 2947, -631, 1560, 2096, -833, -1173, -1475, - -2060, -2189, 967, -1451, -1544, -758, -538, -31, - 1395, 3550, -3, -1999, -1975, -1734, -2680, -2512, - -2037, -1306, -252, 1288, 6012, 4834, -1087, 3259, - 3115, -1369, -1136, -948, -264, -582, -677, -643, - -2500, 1284, -317, -1872, -1150, -1150, 310, 832, - 1597, 2842, 6295, 3806, -671, -1536, -1460, -1256, - -1223, -1504, -1672, -1471, 1358, 1004, -1893, 1114, - -1643, -103, -513, 189, 303, 140, -1618, -648, - -720, 7274, 573, -180, -731, -1226, -1564, -1742, - 151, 2103, -1562, -974, 94, 546, 3536, -205, - -1657, -2534, -2187, 2840, -1248, 451, 2615, 171, - 479, -305, -1299, -1708, -2144, -1593, -1289, 2766, - 2287, -400, 188, -51, 141, 105, -2128, 4976, - -1690, -1216, -1175, 297, 1454, 449, -478, -970, - -1914, -1459, 3036, 2668, -950, -634, -507, -374, - 4, 34, -1664, 2901, 847, 2817, -1154, -1651, - -1262, -1160, -624, 629, 1578, 765, -2002, -2121, - -1527, 1938, -272, 113, 287, 955, -1473, 60, - 8047, 137, -534, -841, -1077, -1504, -1788, -1758, - -1871, 119, 931, 1775, -704, 2792, 354, -501, - -1370, -2038, -1031, -1631, -1914, -879, 377, 7589, - 173, -196, -491, -1658, 3790, -773, -1731, 3028, - 49, -1013, -563, -1232, -953, -730, -2568, -1926, - -679, -267, -324, -962, 51, 461, 2728, 3631, - 3533, -1690, -2846, -2370, -1945, -917, -551, 276, - 2634, 3558, -2592, -1750, -2422, -1586, -1204, -1001, - 4603, 1802, 2673, 1685, 2710, -853, -2321, -1919, - -1603, -868, 3706, 290, 570, 338, -2245, -1704, - -1915, 545, -787, 1635, 1725, 526, 666, 1604, - 642, -1154, 3231, -1232, -1772, -623, 217, 27, - 3, 641, -2411, 1924, -967, -1583, -1499, 2316, - 1354, -115, 333, 559, -1721, 2475, -1942, -2114, - -1196, -571, 1769, 2350, 1315, -607, 4510, -1414, - -2228, -1312, 1439, 469, -248, -399, -270, -721, - -1517, -1247, -771, -36, 6488, 942, -279, -572, - -1041, -1908, -2388, -2281, -2595, -2275, -1529, 51, - 471, 4435, 3002, 2738, 4049, 1562, -2706, -1672, - -1649, -1204, -518, -280, 774, 1344, 6, -1950, - -1521, -1768, -972, 1420, 3011, -191, 644, 1478, - 3220, -313, 3030, -153, -841, -739, -378, -1013, - -1410, -1815, -2104, -1033, -2097, -1992, -943, 2391, - 424, 369, 1601, 3331, 1494, -2060, -2027, 1579, - -1407, 1120, -280, -197, 761, 1048, -710, 4094, - -1533, -1984, -1620, -1132, -515, -485, 971, 2644, - 3979, -661, -1891, -1120, -897, 2484, 1623, 21, - -1534, -2438, 3201, -1510, 858, -1459, -711, -1332, - -833, -240, 763, 1096, -1435, -29, 3174, -1773, - -19, 708, 1680, 403, -910, -2224, -2670, -619, - 1320, -751, -1323, -1022, 2875, 1080, 985, 1, - 191, 7823, -475, -604, -1126, -967, -1139, -1600, - -1767, -1161, -1342, -1960, -2112, -1793, -1596, 3103, - 535, 2001, 3235, 151, -2266, -807, -1977, -1661, - -1255, 2328, 2632, 3189, 621, -1130, -2183, -1127, - 2391, -884, 2173, -690, -354, -516, 352, 954, - 1847, -74, -1260, -1839, 2557, -1221, 228, -630, - -162, 386, 1462, -1889, -2596, -2216, -1869, -518, - 1281, 2329, 2653, 1117, -1535, -1038, -1752, -1862, - -1635, -1067, 994, 5212, 2719, -264, -2021, 1824, - -2110, -619, 1538, -397, -332, -153, 860, 1281, - 6568, -1790, -2459, -1707, -1708, -799, 294, 89, - 475, 992, -1668, -1819, -2010, -1623, 2079, 3255, - -388, 591, 1477, 581, -1544, 476, -1825, -959, - -1296, -1037, -453, 1146, 4693, 839, 2027, 3021, - -1731, -1746, -1964, -1115, 1197, 102, 164, -162, - -2301, -1281, -2022, 3983, -1122, -281, 85, 352, - 1042, 1599, 6463, -93, -2010, -1988, -2282, -2189, - -1915, -1721, 17, 4694, 424, -998, -111, -1995, - -1246, -1176, 78, -116, 1951, 3059, -1974, -1783, - -2243, -1238, 3935, -928, -15, 1265, 1536, 1907 -}, - -.shape08 = { - 5279, 1101, 12974, 5624, 2029, 3853, 5918, 1516, - -2905, -224, -92, -819, 803, 1091, 3091, -3355, - 152, -1214, -7317, -738, -8973, 546, 12035, -937, - 2216, 2113, 1214, -6577, 2006, -1661, -673, -5880, - 496, 454, 3400, 676, -322, 11388, 634, -1169, - 12556, -5804, -7724, 588, -6801, 1080, 354, -1681, - -942, 1926, -487, -580, 156, 79, 15253, 667, - 1155, 655, -719, 1999, -785, 214, 2822, 1020, - -1967, 73, -387, -137, -15225, -1552, -357, 2830, - 2140, 3070, -2552, 2410, 1230, 4131, 999, 248, - 531, -909, 3948, 12858, -8056, 2205, -2837, -171, - -1633, -129, -93, 1852, -1920, 157, 9647, -84, - -150, -1365, -1522, -13197, 6168, -3195, 5890, -1724, - -6407, -1340, -7435, -621, -5732, -2895, 145, 3974, - 728, 9840, -494, 7357, -394, -13614, -256, -1930, - 468, -266, 8001, -153, -365, 7652, 135, 1400, - -3869, 1091, -4935, -2884, 1259, 6819, 1025, -6667, - 1079, -9794, 6827, -4166, 1108, 1149, 18861, 593, - -177, -1067, -644, -2164, 4727, 85, -101, -10805, - -247, 8918, 2261, 5475, 756, 3018, -6535, 1941, - 359, -4229, 1206, 958, -878, 554, -18780, 2289, - 4906, -7412, -7685, 7932, 965, 2460, 4423, -563, - -3668, -3482, 3307, -1737, 971, -7480, 10742, 1978, - 2365, 20, -3625, 466, 2056, -6602, 9396, 3145, - 3162, 1857, -630, -6905, 1660, -3024, -2159, 1109, - 1282, 2767, 210, -2203, 3099, -7889, 1805, -13115, - 988, -6235, 1566, -1399, -9612, 1821, -519, -57, - 3428, -14024, 1141, -2542, -9396, -17, 440, -8591, - 2271, -7811, 1891, -935, -4330, -1303, 362, 426, - 319, 1176, 3176, 2202, -14308, -619, -2942, -2271, - -531, -652, 345, 17681, 1453, -1561, 341, -2077, - 933, 433, 1529, 463, -1095, 4912, -840, 16266, - 973, 1732, -718, 6702, -3659, 4037, -704, -2707, - 1423, 1291, 2300, 149, -933, -1338, 2019, 6173, - 481, 14937, -364, 3896, -443, 992, -896, 378, - -226, -1505, 268, -428, -2622, -289, -2069, 10472, - -3880, -5330, 385, 3053, -4642, 1525, -1557, 716, - 2504, 848, -450, -2018, -458, -705, -7120, -543, - -2138, 2548, -351, 737, 12906, -1012, 63, 15357, - 332, -837, -225, -1299, 2843, 1334, -669, 2083, - -707, 1171, 8219, 2190, 10567, 1370, -1376, -2919, - 2108, 10098, -388, 4442, 164, 490, 7580, 26, - -1848, -2919, 640, 4758, -108, 8194, -1325, -2314, - 447, 5178, -1095, 9902, -693, -3624, -223, 690, - 10495, 776, -919, -1621, 2046, 469, 1454, 3681, - -1090, -1776, 1457, 212, 2054, -994, 698, -496, - 22347, -623, 254, 960, -4073, 531, -2572, -14393, - -1022, 258, -3667, 994, 15242, 5078, -3618, 1925, - -1229, -1754, 1715, 4358, 1286, -2360, -4590, 1824, - 7864, 1423, -2146, -2763, -10635, 474, -829, 1159, - -157, -54, -158, -29, 202, -383, 285, -2, - 862, -364, 415, -123, -145, -9733, 1167, 10199, - -1408, -2992, 2131, -412, 4743, 2992, 3555, -617, - 9606, -2831, 2357, 5300, 625, -678, -500, -128, - -56, -6327, -1122, -2567, 1904, -1804, 709, 3194, - -148, -1371, -6534, -1748, -1490, 14159, 1466, 1395, - 1101, -2725, 503, 68, -1486, 0, 211, -1218, - -3, 20920, 1709, -208, -839, 4574, -6084, -6557, - -103, -984, -375, 8409, 1715, -2170, -5003, -3296, - 13482, 1211, -4159, 3496, 1040, 6925, 213, -1398, - 441, -1231, -814, 842, 1574, 1145, 1359, 437, - -1777, 20566, 259, -4573, -1412, -158, 10144, 1269, - 1405, -12631, -1104, -615, -15892, 355, -3795, -1158, - 3241, 252, 232, -179, -617, -2038, 285, -1014, - -1248, 1835, -1558, 1266, -10207, 629, -312, 11376, - 154, -288, 5915, -353, 60, 2695, -853, -103, - 15659, 2403, -1184, 3, 9236, -10953, 4434, 829, - 2563, -164, -848, -646, 7247, 895, 1726, -752, - -979, 1053, -971, 318, 2180, 927, 804, -262, - 446, 3261, -4926, -4523, 1247, 2039, 12770, -1191, - -1310, -5574, 4763, 657, -4139, 10821, -805, -1109, - -3189, -1721, 167, -10022, -1877, 2123, 328, -7048, - -2130, 2431, 1522, 3209, -8448, 1810, -5412, 9815, - -3677, 6575, -6237, -929, -434, -2375, -13586, 3497, - -1140, 1227, -6354, -507, 329, -1690, 1079, -880, - -3743, -4021, -4645, -6053, 958, 4594, -1122, -11628, - 1537, -3418, -1242, 133, -9335, 1611, -432, 10733, - -885, -468, -13466, 690, 214, 8968, 3441, 5451, - -219, 5492, -377, 409, 3812, 2450, 508, 6542, - 3824, -3705, -514, -8262, 1537, 7969, 946, -2869, - 8762, 417, 5094, 2104, 6694, -342, 1259, -4779, - -1445, -1519, 333, 4385, 652, -386, -580, -1892, - -873, 1862, 2704, 13837, -5415, -1975, 5881, 7150, - 8272, -6412, 704, 1854, 257, -3746, -9789, -9634, - -924, 1393, -3237, 259, -56, 4390, 4902, 1172, - 5114, -2616, -4409, -1180, 4691, 7400, -625, 8873, - 6846, -1224, -213, -5296, -3504, -147, 17828, -1347, - 3251, 1702, 1440, -2364, -491, -227, 1765, -446, - -9746, -2019, 11287, -195, -9559, -312, 888, 5789, - -1753, -11069, 2537, -265, -1762, -779, -8501, -308, - -89, 1973, 3640, 17344, 1326, -689, -398, -3820, - 2167, 229, -636, 2142, -6587, -751, 13243, 465, - -5946, -202, -968, -1060, -240, -10626, 3405, 1302, - -1263, 972, 11351, 100, 2266, -930, -2108, 5350, - -3186, 11130, 2073, -5616, 650, 2000, 1048, 5628, - -531, 674, 8453, 1030, 1152, 12095, 352, 409, - -1029, -1236, -190, -5724, -589, 3550, 1958, -14081, - -339, 1672, -1659, 4518, -75, -638, 5501, 277, - -578, -2185, 157, 2066, 8634, -2403, 1617, -12487, - -1881, 8273, 179, -2152, -1294, -512, -415, 456, - -141, -125, -405, 132, 49, -1978, -19085, -451, - -1480, 324, -5397, 235, -1217, 346, -1258, 3540, - 10075, 10291, 5060, -2057, 6156, -992, 9344, -3718, - 4296, 895, -8464, 341, 1426, 648, 1494, 2895, - -3760, 10139, 15531, -984, -1550, -1319, -1542, -119, - -517, -185, -3368, -9279, -3455, -4257, 1092, -10120, - 5072, 3099, 986, -2562, -12068, 1932, 6489, 950, - -2417, 1362, -567, 591, -715, -515, 3506, -726, - 6319, 214, -364, 3611, 1895, -2005, -273, 1513, - 2379, 475, -4855, -527, -11493, 27, 4343, -2394, - -639, -744, -2601, 10917, 1910, 2449, 1238, -2175, - 5322, -4054, -40, 4274, 684, 8152, 966, 10882, - -13, 4253, -287, -3192, 548, 2020, 189, -6894, - 797, 2160, 579, 4084, 1767, -4011, -640, 7697, - 791, 945, 1230, 6491, 1508, -3762, -433, 11340, - -129, -1131, -5121, 3148, 1544, -7648, 1866, 9660, - 2365, -2110, 782, -82, 3666, -701, 303, 298, - -1934, -125, -1427, -17589, -1188, 175, -7046, -488, - 1121, -6594, 489, -1551, 14349, 1499, -544, 17132, - 198, 2516, 2479, -978, -214, -3399, -1223, 2094, - 130, -1020, 1049, -710, 12801, -498, 297, -1365, - -187, -3169, -123, 9019, 958, 221, 14234, -590, - 961, 3092, 8, 255, -4586, 1789, 2522, -12577, - -91, -822, -805, -714, 5298, 1299, 3306, -1288, - 13176, 235, 1754, -67, 1912, -604, 3240, -2048, - -200, 772, -173, -996, 1368, 2380, 294, 763, - 19665, -196, 528, 182, -2394, 923, 749, -13578, - 855, 589, -9553, 0, 5737, 10399, 9147, -1655, - -3735, 1246, -2429, -1147, -2199, -2953, 614, -1404, - -449, -8524, -2271, 5001, -9517, 2940, -204, 3625, - -258, 32, 1521, -299, -1786, -2836, 1523, 2427, - -835, 3139, -197, 3351, -279, -14766, -1267, 5169, - -1039, -10967, 58, 641, -767, -1193, -591, -716, - -834, 8109, -915, -711, -10427, -1680, -638, 2643, - -850, -258, 10452, 362, -5394, -349, -14727, -655, - 1040, 1722, -10265, 551, -283, 9888, 408, -400, - 5980, 1878, 781, -923, -667, -789, -348, 624, - -260, 14515, -804, 1721, -2, 5356, 1802, 1218, - 498, 1871, -988, 16295, 4163, -2342, -4290, 3121, - 3269, 112, -3492, 1124, -1496, 1863, -1426, -1090, - 1598, -197, 1160, -1660, -1094, 477, -4104, -396, - 1605, 26134, 746, -12876, 2320, -1690, 8626, 39, - 1341, -1254, -1890, 2555, -13996, -1218, 3827, 1216, - -909, -180, 1720, -87, -143, 989, 340, -1426, - -4029, 3141, -9424, 466, -8227, 422, -7379, 2038, - 401, 98, 3602, -1223, -946, 2469, 1159, 727, - -268, 467, 203, -11079, 3850, -3469, -1965, -1857, - -1415, -2477, 3173, 7352, 9483, -5541, 6212, 1886, - -3868, 2728, 577, -5057, 321, 972, -77, 47, - 227, -38, -1037, -222, -347, -341, 1179, -948, - 592, -7485, 2218, -5955, 2698, 11798, 197, 6260, - 1711, 998, 8, -6223, -1184, 1145, -1781, 1376, - 1394, 388, -689, 2279, 6511, 2542, -4903, 3917, - -790, 535, -1903, -4448, 4216, -22, -6715, 5204, - 4807, 3193, -1064, 5403, 4503, -2434, -4296, 1383, - -1514, -4103, 747, 3928, 2987, 9513, 2492, -8691, - -993, -2667, -40, -170, -3116, 611, 2367, 16297, - -1256, -1404, -3462, 466, -524, 5464, 491, 706, - -7491, 2027, 373, -4086, 1620, -7789, 704, 5002, - 1706, 8325, -851, -9883, -3072, 4475, 2696, -8549 -}, - -.shape11 = { - 44, -10592, -832, -413, 612, 530, 379, 753, - 1442, -3006, -858, -1077, -12018, -196, -771, -1142, - -628, -2938, -439, -3323, 20, 12513, -2462, -1270, - -57, -8417, -690, 790, 276, 2349, -341, -1644, - 230, -2176, -202, -14725, 170, 1725, 3030, 683, - -231, 641, -242, -3252, 110, -1440, 2886, -1467, - -1155, 14395, 297, 52, 240, 3938, 9880, -7555, - -1214, 3351, 129, -1269, -168, 669, 13765, -1289, - -465, 10017, -632, -328, -276, -33, 31, 18883, - -148, -131, 525, 1669, 2288, -203, 868, -660, - 248, -409, -91, 295, -9174, -1484, 929, 2824, - 1097, -3205, -113, 2712, -1544, 527, 1419, -963, - -388, 691, -16791, -84, 72, -3802, -357, 1633, --15182, 62, -6024, -742, -5396, 4470, -198, 1, - 1428, -1691, 18715, 1402, -2539, -375, -8455, -901, - -147, -3274, 9359, -277, -8941, 714, 2834, 2924, - -6326, 907, -123, 10487, -484, -4772, 877, 9840, - -505, -7562, 301, 671, 116, -371, 3740, 359, - 385, -5145, -908, 156, 9639, 3782, -9688, -4214, - -945, -7685, 334, 2185, -1342, 388, -1741, 278, - -231, -912, 905, -1039, 598, 2049, 662, -198, - 22378, 166, 116, -1699, 335, -8380, 1279, 1536, - 14955, 1254, 190, -2519, -608, 364, -561, 5748, - -1178, -923, 3183, -59, 13880, -2530, 241, -564, - -319, -7510, -9, -124, -20346, 305, -25, -400, - 222, -16943, -488, 802, -1685, 3323, -6198, 1000, - -903, -846, -387, 462, 847, 526, 10024, 2020, - 2090, -9563, 1416, 169, -12182, -428, 10388, 869, - 1068, 2201, -1041, -3180, 152, -646, 4, 4017, - -1069, 307, 5283, 3021, -13662, -493, 9, 542, - 152, -2617, -3870, -514, 13497, 1180, -603, 1255, - 2396, 7418, 8902, -11165, -2626, -5719, 1764, 858, - 1105, 1476, -1764, 1969, 977, -1738, -928, -13940, - 1444, -4157, 836, -12243, -369, -256, -15681, 5320, - -5170, -509, 353, -1581, -1455, 965, 716, 209, - -883, -317, -1961, 9128, -8197, 2173, -2434, -1126, - 4066, 1025, -16663, -7013, -147, 1617, -745, -3205, - 1496, 1822, -1199, -2999, 117, 619, -20002, -232, - 142, 3207, 561, -292, -1635, 1035, 37, 2712, - -243, -8269, 305, -2601, 495, 14516, 831, 260, - -54, 4217, 675, -1632, 4962, 793, 1066, 133, - -344, -12428, 95, 6164, -1298, -1860, 3622, -467, - -867, -1178, 11053, 118, -36, -6997, -763, 16019, - 16, 2459, 306, -820, -1135, 847, -709, 928, - -164, -293, -5736, 543, -11548, 5389, -2012, 300, - -228, -1043, 5107, -558, 1187, -140, -13034, -1571, - 740, -4967, -432, -6289, -1778, 3449, -337, -12607, - 344, -3790, -1598, -274, -346, -1494, -108, 325, - -1215, 819, 404, -568, -286, -21364, 15495, -2297, - 606, 117, 10, -193, -972, -292, -573, -1155, - -1289, -1025, 472, 1154, 843, 187, 586, 20569, - -5, -236, -1181, -1092, 700, 891, -603, -601, - 21648, -449, -193, -1103, -298, 2084, -251, 449, - -1414, 17168, -391, 104, -5465, 401, 8839, 781, - 1741, 201, -369, 466, 12358, -636, -945, 3928, - -605, -17445, 5020, -1289, 977, -6202, 1783, -507, - -76, 267, -31, -2731, -1560, -1225, 1348, 11176, - 1669, 754, 1671, -4038, 151, -371, 7283, 243, - 1387, 126, 1007, 1292, -15, 696, 282, -2623, - 1065, -1026, 191, -632, -132, -12957, -32, -1697, - -422, -240, 1352, 10252, 1067, 8296, -1244, -9, - -301, -3014, -249, -372, 10731, 535, 2147, -8959, - 346, -408, -8329, -1905, -48, -8176, 2782, 412, - 1425, -946, -748, 1095, -1370, 9086, -99, -143, - 68, -544, 264, 494, -377, 13, -618, 237, - 193, 3549, 317, -168, -7148, 2351, -244, -13240, - -3355, -2322, -533, 9554, 6906, 124, -694, -901, - -2762, 207, -915, -2520, -143, 8544, -678, -2788, - 12926, 791, 1296, 4861, -1470, 889, 3675, 806, - 290, -11146, 422, 9217, -31, 1608, 140, 3939, - -6903, -276, -704, 2353, -344, -1038, -230, -177, - 670, -617, -129, -857, -8231, 638, -411, -252, --15709, -1218, 210, 288, 542, 533, -9087, -10493, - -624, 1175, 611, -230, 746, 1455, -590, 830, - 1756, -15800, 823, -1077, 788, 1071, 468, -1654, - 660, 983, -9697, -1300, 662, 2053, -281, 12949, - 389, -915, 197, -1742, -4587, 1746, 707, 1625, - 9021, 2204, 759, 1303, -428, -220, 41, -5499, --16080, -193, 443, 443, -78, 889, -561, 5629, - -1073, 7019, 222, 1661, 1190, 1108, 94, 5624, - -3796, 407, -706, -122, 744, 363, 1648, -10896, - 595, 953, 85, -267, 195, 851, 17173, -636, - 243, 907, 2029, -700, 351, 1495, -157, -575, --11664, 1252, 8341, -616, 3708, 5693, -6, -1753, - 1072, 863, -823, -4278, -12043, 750, 597, 3145, - 38, -8140, 3136, 290, 7, 11084, -876, 1842, - 175, 3458, 460, 1615, 11698, -827, 16, -12482, - 428, 411, 2625, -1352, 142, 529, 229, -48, - -965, -145, -592, 655, 499, 22095, 22141, 37, - -1875, 701, 45, 724, 1111, 1631, 262, -252, - -9092, 5325, 408, -637, -612, 647, 1268, 834, - -510, 603, 199, 816, -9904, 9533, -1580, 2669, - 1824, -2092, -701, -271, 7489, 46, -3295, -844, - -304, -226, -260, -692, -5, -527, 37, -49, - -1542, -69, -1087, 20519, 367, 1, 3487, 2535, - -5110, 642, 1223, -2130, -2894, 1752, -1618, 9732, - -1633, 6904, 137, 654, -358, 355, -21, -277, - -68, -188, 132, 530, 372, -315, -11498, 221, - 815, 2480, -1398, -123, 353, 3114, -12025, -1212, - -1111, 916, 6452, -1880, 1867, 307, -66, 1857, - 138, -980, -3088, -174, -41, -393, -656, 847, - 15824, -379, 358, 672, -389, 920, -21145, -393, - 350, -574, 1005, -2083, 26, 79, -203, -7967, - -3302, -5805, 772, -302, 2104, -1240, 13710, 6816, - 2282, -3709, -1512, -81, -2216, -3005, 444, -795, - 751, 2163, 20751, 780, 542, -480, 624, -425, - 769, 2474, -5903, 399, 10564, -112, 69, -1409, - 1885, 2339, 67, -620, 196, -2432, 6046, -1673, - 6512, 809, 7904, -516, 4278, 223, 359, 16512, - 1224, -480, -505, -735, -502, -593, -4565, 1914, - 122, -531, 1442, 464, 69, 292, 410, -581, --19848, 1059, 132, 1392, 5917, 705, -7706, 2496, - -1487, -791, 11939, 185, -265, -2412, 630, -8028, - 1434, 10315, -1541, -3756, -2403, -1918, 1050, 8057, - 234, 13546, -92, -2172, -671, 11631, 103, 116, - -171, -4604, -267, -602, 15, 454, 6859, -2151, - -8707, -1664, 61, 2518, -969, 903, 1209, -1435, - 13531, 590, 236, -821, 598, 1186, -7690, 134, - -1005, -18177, -148, 519, 900, 951, 406, -3584, - 47, 9439, 1418, -797, -3353, -703, -1798, -1244, - 291, -2784, 14612, 2029, -161, 1040, -4130, 3064, - 1721, -2898, 269, 3367, 1379, 14359, -690, -655, - 2010, -4935, -681, -2606, 11651, 748, 101, 13593, - 629, 28, -540, -854, 1405, 558, -8785, -1016, --13043, 121, -556, 4959, 1694, -720, -138, -3897, - 182, 1938, 844, 919, -683, 12042, -1101, -155, - -1375, -1509, 11, 220, 821, 21721, -367, -634, - -1468, -174, 1002, -1203, 318, 11672, -2114, 2472, - -1701, 5932, -661, 1094, 2500, -5609, 254, 437, - -911, -1611, -8005, 217, -1139, 1321, -10713, -2183, - 1163, -890, -622, 12820, 1021, -13578, 1040, 3216, - 592, 686, 737, -2881, -1693, 3995, -455, 4666, - -4124, -9316, 2061, 10645, 271, 264, -6829, 641, - 2061, -6683, -512, -747, -9131, 2445, 343, -9944, - -2888, 607, -10855, 871, 418, 504, 936, 1079, - 273, 400, -17752, -391, -1543, -6193, 1482, 737, - 2096, -982, 167, 972, 336, 1063, -1272, -1602, - -1907, 9, -191, -15207, -119, 4047, 1479, -1405, - 526, -18462, -627, -1996, -1022, -1544, 312, 7972, - -227, 797, -5204, -2160, 391, -423, 257, 3836, - 442, -1931, 22, 143, -203, 362, -73, 15679, - -289, -1445, 577, 858, 11408, -1970, -1022, 1550, - 882, -3699, -2697, 3978, 600, 86, 3858, 8683, - -7681, -4856, 4051, -1321, -587, 46, -499, -354, - -655, -15717, 67, 490, -2670, 474, -1374, 5601, - 60, -17615, -808, 87, 367, 579, 1057, 1020, - -394, 1181, -189, -10846, 763, 2635, 282, -3279, - -866, -15257, -449, 112, -15577, 227, 269, 13964, - -1273, 1513, -1487, 195, 319, 2527, -286, -5883, - -5360, -959, 2791, -3335, -945, -1985, -903, -11418, - 8525, 669, 6106, 153, -1169, -1198, -553, 7037, - 528, -4237, 717, -214, 1824, 10108, 961, 9077, - 1899, 10407, -207, -29, 355, -6794, 111, -13627, - 1361, -3577, 291, 4534, 2209, -1579, 109, 523, - 456, 10990, 31, -448, 385, 1481, 2, 15266, - 798, 5759, 860, -16424, -1315, 1631, -456, -977, - -180, -2593, 1191, 5959, -32, 8112, -506, -7766, - -1871, -15310, 662, 196, -20401, 925, 446, -2035, - -620, -686, -249, -2517, 423, 703, 633, 828, - -182, -37, -406, -149, 821, -22255, 652, 522 -}, - -.shape16 = { - -786, 193, -15441, 200, 1050, -16545, -41, 329, - -869, -170, -858, 2725, 217, 447, 2107, -23, - -387, -10280, -383, -320, 387, 16012, -79, -967, - 3528, -2123, -537, -636, -1761, 949, 100, -17, - -446, 261, 22527, 331, 26, -87, -206, -2292, - -1178, -164, 598, 147, 889, -14487, -2823, -1280, - -1892, 33, -1763, 993, 4807, -953, 2181, -588, - 59, -296, 218, 291, -104, 495, -1092, 2232, --14904, -983, -2919, 795, -17207, -2045, 2988, 597, --10312, -718, -2196, -5822, 847, 1304, -757, -4714, - -148, 831, -734, 806, 4348, -308, 244, 566, - 2706, 604, -748, -864, -568, -219, -128, -688, - -218, 110, -29289, 482, 76, -1447, -142, -417, - -253, 8124, -19775, 990, 4546, -1012, -8082, 133, - -1612, -2243, -3788, 1568, -2892, 852, -1642, -3479, - -23, 1300, -564, -1037, 249, -14533, -43, 321, - -680, 10, -417, 23426, 397, -108, 1843, 180, - 11976, -9613, 353, 3768, 130, -1035, 4340, 218, - 596, -224, -779, -1680, 1326, 152, -971, -9725, - -355, 5328, -459, 16242, -438, 926, 6210, 1912, - 769, 2621, -148, -1008, 517, 341, -3594, -965, - 11383, -874, -16949, 1167, -3371, -1655, 586, -132, - 3990, -770, 211, 246, 514, -166, -734, 30408, - -258, -521, -20, 339, 499, -2572, 2110, 272, - 1357, 123, 2841, -320, -31, -444, -501, 215, - -42, 595, 108, 484, -223, 937, 475, -72, - -319, 75, -205, -978, -9155, 145, 2020, -3, - 2438, 4046, -1281, -875, 1532, -598, 12288, 369, - -2046, 343, -778, 1769, -2589, -641, 17437, 1793, - -592, -1954, -1607, 6184, 3440, -512, -2710, -1330, - -127, 8765, 83, -243, -315, 709, 256, 1176, - -1198, -463, 970, -302, -568, -997, -1022, 159, - 11008, 27, 13074, 1523, -3239, 2330, -4808, 6115, - -9933, 1449, 2153, -3111, 1780, -731, 121, -881, --14289, -265, 566, -611, -253, -2965, 250, -105, - -66, 2570, -1922, 2712, 1907, -2025, -454, 173, - 1463, -29, -31955, -113, -1751, -3353, 254, 1001, - 6781, -29, -639, -1289, 288, 498, -21505, 48, - 109, -2151, -223, 1360, -3430, 658, -4185, -1706, - 1244, 1899, 124, 12, -35, 289, 382, 433, - 261, -131, 54, -646, -280, 86, 180, 153, - -169, -20242, -95, 734, -524, 77, 102, 8468, - -421, 29, -3, 51, 1526, -600, -264, 355, - 1949, -985, -291, -86, 10212, -789, -393, -182, - -51, 946, -16716, -954, 1179, -2745, -509, -4774, - -587, -608, 7657, -509, -388, 987, 109, -218, --17579, -524, -467, -1643, -444, 1430, 2541, -124, - 1785, 27, 7905, -73, -3135, -1241, -254, -2114, - 1175, 780, -50, 4055, 535, 438, 32, -113, - -260, 81, 1102, -59, 29188, -48, 212, -29, - -344, 559, 856, -483, 608, -40, -1498, 112, - 10374, 1198, -434, 4053, 1286, 236, 1823, 16046, - 592, 1583, 78, -5243, 1311, 456, -1342, -546, - -353, 13289, -333, -529, -20859, 183, -167, -1368, - -338, -690, 4248, -205, -666, -634, -1653, 1174, - 234, -18622, 891, 284, -2632, -1516, 289, 11242, - 727, 133, 284, -323, -1370, 908, -13169, -412, - 1155, 410, 610, -3072, -8220, -637, 242, -647, - -2072, 16041, 2292, -8009, 351, -3137, -3075, -1051, - 4569, 125, 23, 1281, 2487, 520, -209, -688, - 205, -1248, 246, -601, 533, -12209, -2298, 826, - -2762, 45, 15123, 721, 1128, 798, -676, 349, - -153, 263, 89, -854, -24, -350, -227, 157, - 587, -240, -185, 663, -32328, -148, -204, -2396, - -597, -344, 8104, -280, -375, 264, 648, 741, - -290, -321, 263, -569, -381, 167, 1757, -29636, - 30, 393, 398, 590, -242, 81, 1601, 3683, - 787, -336, 675, -1080, -713, 261, 18420, 1760, - 609, -4610, -551, 2790, 19807, 1347, -125, -9412, - -261, 548, 1056, 179, -917, -181, 12637, -267, - 621, -11908, 1366, 76, 5875, -742, 394, 155, - -370, 2481, 46, -15392, -344, -9750, -1353, -2242, - -1685, -1286, 2320, -2176, -1729, 705, -1582, 1590, - 1603, 21129, -3555, 2192, -883, 3438, 233, 1965, - -537, 399, -4818, -4085, 559, -292, 1290, -2700, - 10, -301, -1865, 226, 52, -1346, 306, 316, --12281, -525, 285, 9631, -2, -849, 1620, 128, - 176, -1021, -473, 7929, -133, 2459, -33, -1517, --22047, -2300, 98, -3513, 334, 4617, -193, -1309, - -1279, 738, -443, 95, 406, 660, -705, -54, - -39, 26396, -766, 249, -2423, 7759, -689, -3909, --17404, 65, 1849, 945, 15907, 1386, -433, -831, - -6349, -3919, 1870, 8096, 311, 15043, 1709, -315, - 1288, 7522, -215, -5072, 1246, -1486, 3762, 4526, - 1517, -1936, -543, -263, 771, -10215, -425, -5098, - 59, -266, -1012, -380, -2131, 630, 405, 665, - -4550, 1403, 8, -46, -879, 398, -532, -185, - -286, 921, -65, 378, 669, 174, -15280, 91, - -776, 8480, 2463, 184, 2065, -666, -561, 4122, - 594, 732, 4007, -852, -71, 194, -126, 1765, - -1570, 968, -257, -288, 950, 27482, -333, 370, - -1429, 285, 558, 11245, -135, 565, 1296, -261, - -62, 600, 1455, 1457, 820, 357, -1203, 169, - 16611, -893, 359, 231, 418, -547, -95, 3866, - -511, -6344, -205, 923, -239, -16205, -1619, 217, - -3362, -6342, -1551, 649, -492, 264, -55, 170, - 16992, -91, 306, 43, -2770, 582, -1740, 77, - -882, 268, -515, -45, -6093, 24, -5596, 9034, - 284, 3211, 846, 1158, -1118, -604, -514, 1402, - -493, -938, -3892, 242, 643, 1421, -434, -406, - -102, -88, -11733, 161, 518, 978, 1508, 248, - -1036, 1407, -396, 293, 1154, -1435, 495, 8243, - 20, -845, -5373, 659, 2366, 29148, 145, 603, - 4088, -251, -2841, -2526, 20682, -1357, -2454, 660, - -125, 347, 11772, -113, -357, -2181, -1234, 1908, - -432, 16555, -248, 822, 15516, -158, -653, 1573, - 93, -2730, -1111, 958, -1550, -1153, 17, 610, - 781, -372, -1640, 144, -135, -1171, 22140, -427, - -26, 690, -800, -1497, -300, 5438, 390, 11304, - 9253, 1098, 5564, -9, 3856, 965, 2016, -12797, - 1687, 915, 3687, 539, 2496, 702, -1324, -71, --12955, 7456, 4626, -848, -1815, 831, 2151, 7921, - -3000, 123, 1189, -1489, 222, 4973, 1936, 54, --10527, -1238, -1157, 628, 14112, -2164, 1478, -985, - -4102, 635, 225, -311, -609, -1015, 301, 507, - -85, 443, 186, -552, -711, -16988, -1327, 220, - 565, -1673, -543, 18633, 331, 127, -342, 22, - -77, -360, -439, -501, -1848, -1147, -483, 1133, - -351, 41, 908, 502, -658, 474, -430, -11348, - -1, -531, 451, 709, 227, -978, 348, -265, - 269, -376, 2511, -188, -111, -387, 809, 1009, - 1570, -755, -11463, 667, -895, 446, 276, 145, - -513, -117, -462, -340, 1457, -963, 191, -788, - -150, -979, -507, -27540, 122, 368, -73, 10051, - -465, 642, 507, -6828, 241, -5025, 1598, -1174, - 2373, -2272, -1910, -108, 15, 166, 2, 10518, - 933, -12716, 510, 778, -424, 414, 4899, 759, - 862, -438, -886, 457, 304, 23639, 136, -203, - 478, -565, 244, -541, 2419, -773, 1107, -217, - 1579, -1037, 476, -97, 995, 17973, 161, 16466, - -178, -718, -1606, 947, 1991, 2266, 1249, 2708, - -611, 1424, -142, -53, 36, 509, 26159, -144, - 357, -37, -234, 587, 311, -509, -1639, -332, - -1618, -382, 302, -8657, -68, -30, 545, -12834, - 158, 158, 135, 621, -354, -871, 451, 1220, - -31, 2, -13414, 60, 3, -380, 541, -44, - 552, -366, 155, -462, 61, -232, -15426, 317, - 688, 1121, 2933, 7151, -168, -9167, -2521, 745, - 2792, -10448, 569, -3823, 630, -4626, -95, -416, - 828, 259, 72, 171, 635, -250, -128, -426, - -153, 260, -771, 314, 235, 26, 32281, -343, - 751, -1443, 324, -684, 1900, -1334, 2022, 30, - 1073, -2406, 2080, -485, -320, 15328, -860, -529, --16444, -219, 1736, -149, -160, -828, 1089, 413, - 241, 3720, -90, 146, 1109, 243, -321, -256, - -68, 88, -50, 571, 1179, -25030, 104, 929, - 35, 529, 117, -13724, 734, -1344, 456, 5586, - 1566, -12573, -840, -1617, -2494, 1791, 1901, 3066, - -2159, -414, -3856, -9894, -1608, -657, 15355, -773, - -9217, -658, -972, 4730, -2986, -3478, -757, -1416, - -3702, 18089, 629, 7061, 124, 5843, 158, 19017, - -2204, -6976, 1629, -5657, 1101, -1859, -1425, -548, - -1132, -5043, 1074, -592, -196, 1902, 22705, -1228, - 214, -685, -2036, -2368, -315, -914, 533, 218, - 1091, -627, 2031, 13922, 104, -450, 4494, -498, - -361, 24734, 623, 1029, 2437, -1123, -5092, -6551, - 438, 16562, 375, -13102, -193, -2004, 3556, 179, - 1832, 2086, 798, -534, -195, -7105, 796, 3969, --12269, 1570, 4273, -2692, 1240, -2901, -2045, -2453, - 372, 613, -548, -245, 687, 258, -8964, -1500, - -1519, -993, 17571, -357, 916, -1202, 1752, 2081, - -536, -3185, -1062, 19335, 721, -9958, 1052, -872, - 248, -3133, 456, 1641, 149, -11, 2955, 310, - -3178, -18823, 497, -971, -6587, -1380, 351, 106, - -43, 607, -4754, 213, 1030, 5377, -804, -2557, - 850, 1081, -706, 1325, -14922, -794, -14060, -1953, - 891, -3296, 329, -510, -1126, 1113, 1753, -411, - 1769, 429, -185, -1020, 194, -106, 11470, -591, - -272, 422, 337, 524, -150, 822, 51, -120, - 7193, 802, 640, -140, -42, 28125, -1020, 285, - -465, 3195, 69, 482, -953, 262, -7672, -373, - 5158, 5625, -3003, 550, 5371, 5619, -2200, 5392, - -804, 135, 1300, -3610, -23, -433, 13503, 224, - 911, -14421, -502, -2151, -1667, -1933, 2888, -277, - 547, -989, 3115, -32, -680, -164, 804, 412, - 62, -154, -190, 156, -10938, -360, -88, 843, - 328, -773, -267, -12668, 856, 1496, -243, -586, - 736, -2175, -677, -3069, 7480, -1764, -4024, -2569, - 1805, 194, -6814, -1135, -237, 2682, -156, -890, - 1285, 368, 1802, -683, -163, 1191, -13063, -496, - -335, 17482, 746, 818, 48, 21419, -598, -1753, - -1169, -2135, 40, -9114, 592, -3912, 1980, -264, - -304, 8138, -185, 286, -3024, 48, -1630, 909, - 661, -662, 18085, 240, -201, 69, 192, 305, --22167, 692, -1135, -996, 398, -74, 18553, -958, - 1223, -5578, 508, -352, 1234, -450, 497, 780, - 79, 51, -221, 255, -26, 13352, -170, 231, - 590, 169, -733, -812, -65, -219, -20939, 200, - 35, -177, -454, 632, -267, -407, -120, 623, - -176, -664, 715, -23, 318, 148, 1125, 16, - 709, -21687, -230, -413, 1398, -1235, -283, 1615, - 175, -299, 349, 400, -112, 21762, -665, 364, - 1089, 1303, -54, 523, -381, -1312, 48, -886, - -1260, 408, 415, -8349, 7115, 180, -774, 3508, - -971, -255, -195, 81, -2674, -977, -355, -1500, - 178, -2081, -4432, -1014, 340, 5818, 138, -106, - 16917, 1203, 349, 3271, 961, 363, 6008, -6043, - 3736, -730, -4201, -514, -6131, -68, -14935, -1781, - -3898, -40, -18944, -461, -1694, -1269, -755, -81, - 2369, 484, 531, 14114, 85, 32, -10142, -142, - 600, -2374, 375, 675, -2663, 155, -947, 6427, - 11476, 1253, 5049, 1063, 2003, -1608, 2463, -2168, - -1128, 1079, 383, -996, 368, 1208, -3554, -959, - 4596, -1209, -4154, 1270, 9365, -2775, -1751, 998, --20023, -347, 1505, 218, -142, 342, -128, -523, - -159, 75, -467, 257, -133, -142, 712, -621, - 428, -29584, 13, 402, -455, 119, -483, 1121, - -461, 960, 807, -46, 297, 14856, 221, -356, - 221, 15037, -4744, -2555, 447, -1418, 1464, 1391, - -1404, -5812, 512, -2321, 9882, 242, -2298, -137, - -849, -3182, 9394, 1412, 1052, 1369, -904, -494, - -231, 1113, 1087, -13317, 768, -1178, -3011, 24, - 229, 164, -10170, 328, 308, -591, 213, -543, - -82, -790, -875, 794, -558, -7651, -573, 1266, - -2084, 2275, -187, 97, 384, -11830, -185, -472, - 1365, 11636, -1405, 360, -487, -440, -1820, -349, - -293, 285, 25, -139, -415, -540, -108, 1136, - -673, 230, 19202, -545, -542, 919, 1221, -518, - 196, -21900, 795, 115, -16, 459, 3339, -347, - -346, -186, -695, -267, -714, 185, 266, -1218, - 120, -249, 233, -110, -30412, 285, 219, 2256, - 536, -442, 673, -1487, -477, -60, -1806, 183, - -7195, -577, 2230, -7594, -3230, 65, 22963, 111, - 390, 7134, -3716, -5123, -475, -32, -98, -466, - -118, -43, 74, -1071, -902, 1714, 4004, 26, - 97, 1680, 423, 252, 9667, 550, 354, -222, - 19, -224, -807, 365, 593, 363, -851, -28, - 553, 238, -481, 769, 279, 18367, -462, 286, - 4825, -141, 500, 20383, 1618, -31, -514, -2484, - -327, -8506, -705, -872, 530, -9997, -36, -431, - 2824, 3185, 1712, -318, 9513, -10065, 614, -503, - 389, 12830, -113, -15, -1007, -523, -1293, -2102, - -543, -1157, -583, 1228, 262, -674, -1847, -242, - 299, -12025, 547, -591, -9173, 275, 412, 2493, - 997, 1229, 1982, 27554, 245, 106, -1320, -153, - -423, -955, -449, 392, 824, 796, -1181, 1640, - -884, -70, 8789, 10021, -1806, 1019, 90, 1494, - 2071, -911, -1159, 212, 2207, -994, -2500, -497, - 92, -11544, -398, -774, 1474, 32, -671, -171, - -1250, -249, 1161, -654, -205, -36, 1733, 763 -}, - -.shape22_1 = { - 987, -6, -621, -220, -2438, -387, -535, -23, - -934, -68, -4985, 575, 483, 7243, -1075, 917, - 1739, -1832, -580, 1564, 131, -180, -1271, 3672, - 161, 1040, 1737, 2719, 1101, -185, -1410, 221, - -422, -8675, -753, -401, -5388, 13, 762, 1378, - 1113, 1768, -177, 3397, 2162, 267, 2261, -156, - 1708, -848, -79, -1819, -3159, -5548, -745, 7208, - -1039, 7555, -134, 2661, -2112, 2270, -1991, 441, - -6248, 246, 166, 2092, -1402, -242, -13600, -539, - 391, 2395, 11001, -981, 10906, -403, 823, 1647, - -294, 93, 504, -5448, 1213, -1849, -3077, 790, - -841, 12812, -11266, -1882, -805, -274, 1968, -49, - 1189, -80, -281, -40, 409, 2423, 581, -1362, - 207, -869, -589, 3294, -318, -4592, -476, 1014, - -135, -17999, -194, 807, -2946, -222, 44, -514, - -4407, -1201, 1155, -235, 98, 4432, -342, 2386, - 1402, -956, 3357, 1959, 4790, -139, -3494, -4280, - -589, -8422, 363, -746, 640, -360, -1007, -1100, - -7989, -12630, 1006, -1608, -864, -226, -915, -2032, - 1274, 596, 1864, 1067, 1597, 460, -2003, -5560, - -8020, 2354, 379, -3151, 44, 7024, -698, -2901, - 4976, 927, 1223, -93, 172, 189, 6639, -6082, - -726, -524, -3068, -3802, 16, -1039, -105, 2333, - -350, -306, -379, -832, 1282, 56, 3529, 562, - -603, 5954, 294, -1265, 8045, -3990, -169, -123, - -3267, 572, -879, 1562, -1185, 799, -9589, 407, - -590, 65, -2848, 433, -5547, -19, 7180, -7904, - -392, 323, -448, -4481, -3773, -5286, 1957, 226, - -2040, 3292, 2987, -1704, 2835, -149, 1435, 823, - 1775, -2769, 146, 234, -131, -15, 268, 37, - 139, 22, -196, 91, -3503, -5421, 24, -280, - 58, 370, 655, 1412, 113, 306, 16404, -234, - 315, -957, 72, -1129, 1993, -18719, -1415, 1349, - 2340, 541, 313, -1360, 31, 1441, -78, -9905, - -393, 367, -712, -2009, 372, -297, -123, 303, - -458, -323, 46, 8701, -1301, -8768, -43, 1818, - 212, -543, -5077, -8037, -2536, 702, 792, -381, - -272, 1941, 6320, -1871, -13938, -262, -2063, 108, - -861, 485, -440, 768, 5665, -302, 305, -13784, - 2889, -127, -94, 145, 1308, 7911, -8376, -643, - -596, 1357, -943, 1329, -84, -62, 1651, 391, - -2295, -5456, -357, -4611, 1361, 3961, -295, 642, - -698, 8614, 1613, -526, -120, -205, 17, -20171, - 1252, -261, 535, -1244, 92, -315, 878, 380, - 157, 3217, -493, -773, 513, -510, 11304, -899, - -27, 398, -6386, 659, -1001, -2737, -13295, 1219, - -1014, -193, 445, -2393, 344, -25, -599, -2848, - 884, 94, -11, -564, -36, 9939, -3530, 462, - -942, 10089, 824, 2994, -293, 71, 10167, -457, - 711, -964, -2128, 2530, 160, -2558, 2451, 1654, - -3828, 1560, 879, -1023, -8354, 851, -77, -112, - 19572, 2010, -1077, -1329, -1282, 1277, 252, -5622, - 4617, 58, -2315, -459, -1249, 92, 708, -737, - -3323, 182, 1557, -657, 546, -447, 19117, 1645, - -336, -26, -2041, 5926, 4746, -1866, 3922, 2798, - 5320, 7, 470, 842, 229, -567, 742, -3306, - 659, -871, -226, -2593, -1003, -1373, 595, -768, - 20658, 944, 1228, 279, -1531, -618, 361, -4019, - -343, -351, 7143, 293, 92, -2713, -269, -30, - -332, 4093, 216, 239, -563, 1943, -944, -2268, - 70, -209, 440, 1493, -446, 491, -362, 25, - -331, 433, -1585, 173, 1126, -3614, -234, -2649, - 1181, -641, -160, 3727, -841, -2134, -1396, -5758, - -14, 364, -4651, 1151, 194, -5234, 5878, -1348, - -1388, -233, 3810, -860, 9479, -24, -6616, 1387, - -455, 447, -224, -2997, 12, 3502, -73, 470, - -9170, 1677, -740, -592, -1638, 675, -93, -17842, - 1750, -847, 993, -2393, -49, -2029, 1940, 588, - 475, -3467, 55, 5087, 2989, 380, 915, -2782, - 2418, 11303, 1098, 1009, 1372, -5780, -303, 1451, - 972, -7433, -571, 1661, 64, 10265, 1541, -50, - -964, -738, -253, -3105, -695, -546, -775, -18971, - -3094, -2379, 738, 1625, 623, 1073, 782, 723, - -3417, -578, -189, 4108, 1115, -1222, -9102, -4736, - 347, 946, 322, -3699, 193, -15139, 367, 969, - -788, -694, -620, -26, -16, 4, -478, 20792, - -1175, -231, 2566, -1270, 162, 181, -1451, -5370, - -2429, -8910, -3794, -5807, -1655, 248, 4432, 1393, - -2451, -2706, -744, 687, 842, -1281, 2960, -2348, - 153, -1671, -1433, -1250, -1096, 2501, -5393, 4266, - -1098, 880, -1215, 817, -443, 10053, 705, -689, - -2679, -1205, -3302, -809, -918, -1005, 124, -329, - 108, -52, -5305, -419, 128, -8137, 1427, 387, - -235, -2582, 190, -173, -1031, 2672, -985, 3309, - -5927, 7327, -8463, -2, 6035, 743, 552, -14, - -580, -68, -11886, 476, 61, 1172, -529, -988, - 871, -776, -332, 20870, 384, 7795, -10830, 723, - 1690, -519, 962, 663, 1300, -465, 47, -3578, - 56, -8131, 2041, -8524, -1303, 6349, 1903, -6726, - 1156, -224, 1286, -2355, -3415, 985, -502, -2474, - 49, -2789, -3616, -1707, 3363, -140, 1702, -1919, --11518, -404, 62, -6933, -1187, 10830, 132, 284, - -639, 1349, 2367, -311, -626, 745, 5660, -152, - -121, -5236, -481, 5889, -1263, -8443, -33, 936, - 423, -117, 111, -1055, -103, -321, 1286, -611, - 777, 827, 422, -162, -6767, -241, 289, -441, - -1344, 2706, -1260, -4649, -847, -16107, -263, -1826, - -521, -760, 942, 309, -2692, -4835, -853, -806, - -276, -322, 5647, 1219, -433, -346, -1171, -1028, - 191, -406, 444, 33, 272, 3502, 475, -2178, - 1915, -290, -1037, 833, -695, -121, 415, 556, - 1025, -2268, 334, 2847, -1768, -389, -14034, -3878, - 836, 4605, -1985, -359, 1478, -149, 823, -926, - -828, 135, 469, -645, -328, -94, -178, 2820, - 781, -2361, -5778, 1312, 3918, -1, -3654, -942, - -2495, 615, 210, -17006, -396, -445, 382, 563, - -1738, 95, -9107, 4869, 348, 527, 5688, -145, - -1195, -2367, -749, -187, 6697, 27, 347, 12571, - -64, -427, 3765, 824, -1216, -1126, 5997, 586, - 110, -294, -240, 1646, -186, 1360, 413, -6459, - -1535, -3208, -520, -621, 8613, 1098, -19, -199, --11446, -657, -353, 906, 678, -19375, -126, 1688, - 644, 1231, -2151, -742, 320, -68, -12426, -2750, - 1483, -1603, -2639, 3028, 2662, -140, 5405, -917, - -407, 207, 9392, -569, 931, -124, -82, 6370, - 477, -12264, 1093, 3427, -732, -50, 232, -67, - 609, 1615, -463, 583, 1808, 1499, -509, -24431, - 231, -72, -192, -333, -7554, -342, -9036, -304, - 136, -15450, 1333, -1147, -1488, -1440, 75, 63, - 747, 297, -251, 30, -301, -1810, -86, 544, --10446, 1300, 10468, 218, -2471, 1982, 423, 3046, - -1112, -657, -104, 10671, -46, -10953, -6205, -1275, - 1972, 937, -75, -330, -529, -2581, 1510, -1881, - -1372, -1725, 14541, -560, -884, 946, -307, -5031, - 7798, -190, 720, 1525, 29, 868, 1238, 372, - -462, 2467, -2661, 2721, -1514, 723, -2782, -494, - 240, -7147, 587, 751, 1613, 11054, 1074, 275, - 972, -970, 27, -75, 24, -9, 163, 88, - 21, 87, -78, -743, -128, -2336, -235, -743, - -3918, -333, 1088, -195, -166, 782, -119, -3263, - 604, 2155, -258, -1282, -129, 43, -5124, -472, - 685, -14243, -1294, -99, -1922, -284, -422, -1112, - -3194, -1977, 1448, -419, -7172, 20, -70, 2102, - 0, 278, 1882, -10005, 1612, 6020, 71, -141, - 1027, -43, -864, -448, -21257, -336, -2090, 5207, - 674, 722, 1030, 1367, 1963, 6057, 984, -1087, - -3690, 47, -61, 104, -81, 895, 22, 728, - -191, 3219, 5228, -27, -802, 1438, -9026, -1352, - -581, 912, -664, -23, -522, -912, 178, -603, - 571, 574, 406, 564, 175, -405, -2965, -1072, - 1749, -957, -402, 9431, 1649, -409, 291, 5765, - 808, 6754, 727, -37, -254, 1530, 213, 3253, - 357, 371, 45, -1276, -12432, 2799, -1924, -176, - -1107, -183, 198, 3662, 20, -1166, 2507, -3484 -}, - -.shape22_2 = { - 1688, -307, -590, 971, -3616, -1632, -218, 1861, - -1479, -367, -6584, 487, -951, 10808, -232, 444, - 89, -1216, -1577, 1283, 249, -3, -3646, 2205, - -1116, 2630, 2110, 3193, 270, -189, 78, -826, - 1010, -10520, -370, 1234, -5604, -262, 1277, 1440, - 2225, 2466, 305, 2469, -740, 120, 3184, 2125, - 1185, -3230, 1597, -1670, -8283, -9857, -129, 8932, - -1355, 8755, 707, -256, -135, 423, 1543, 1782, - -4875, 403, 373, 1570, -183, 782, -9617, -2539, - 1090, 523, 6929, -1226, 10329, -278, -999, -260, - -1810, 666, -463, -6100, 2040, 256, 532, -1475, - 383, 13137, -10953, -2226, -1243, 1584, -2348, -809, - 3602, -816, 194, 480, 84, 2297, 344, -5181, - -6243, -2616, 2093, 7112, -2373, -1346, 291, -372, - -863, -16911, -1878, 378, -826, 579, 737, -468, - -2288, 264, 634, 108, -254, 4717, -1286, 2885, - 986, -4944, -98, 2007, 991, -2252, -2887, -6141, - -605, -10474, 896, 6, 235, -407, -70, 478, - -8392, -10870, 575, -672, 103, 320, -179, -229, - 445, -380, 1124, 3271, -1327, -275, -239, -10381, - -9102, 1361, 96, -1255, -277, 9316, -415, -2258, - 8992, -117, 1625, -704, -980, 752, 9133, -8792, - -423, -272, -865, -2285, 443, -2014, -2592, 3180, - 1198, 2570, 3360, -7090, 3311, 697, 2229, 46, - -472, 6984, -140, -780, 10391, -1078, 48, -564, - -5073, 1576, -826, -483, 952, 1099, -11536, -652, - 375, 440, -7319, 2646, -2089, 2804, 3795, -6704, - 251, 811, -1224, -1976, -4943, -6671, 780, -2856, - -7907, 2447, 3755, -135, 1127, 328, 553, 3450, - 351, -5054, -5, 1077, 109, -254, -391, -511, - 404, -61, 510, 395, -6044, -7454, 364, -575, - 65, -410, -1921, -248, 128, 311, 17131, -2135, - -563, -884, 2356, -3951, -1176, -16695, -1534, 1977, - 626, 2478, 1554, -1070, 38, -551, 370, -11053, - -331, 1062, -1385, -1681, 1028, 3350, 239, -76, - -156, 49, 397, 7060, -2834, -6527, 22, 1920, - -951, 356, -7674, -8903, -120, 317, -303, 160, - 530, 4611, 1083, 514, -12207, -283, 1413, -848, - -645, -432, 0, -192, 4780, -3485, -1192, -10574, - 1274, -3057, 475, -188, 183, 7865, -11214, -268, - 491, 1422, -28, 149, 515, -1651, 670, -450, - -958, -4288, 567, -182, 668, 4069, -213, -1176, - 148, 8854, -151, 474, 599, 1297, 237, -19186, - 2993, -482, -591, -1322, 25, -628, -828, -203, - -1500, 5519, -84, 723, -1137, 1217, 13045, -707, - -372, -200, -4142, -790, 188, -6760, -8288, 766, - 366, 444, -517, -2679, -1470, -61, 161, -3734, - 3053, 2012, 439, 627, 524, 5538, 549, -473, - -2244, 8399, -6395, 5811, 851, 58, 11376, -6, - -337, -689, -1510, -690, -388, -3587, 2665, 3371, - -1850, -953, -513, 581, -10296, 548, 1092, 565, - 18045, 215, -1486, -1270, 450, -880, 407, -6547, - 8393, 206, -515, -1565, -219, -1872, 1479, 382, - -569, -5002, -1247, -45, -740, -1791, 17177, -1210, - 761, 132, -1627, 4970, 5563, 722, 5614, 430, - 5659, 139, 1193, 1513, 1144, -1319, 561, -5145, - 1010, 199, 656, -3958, 3544, -1758, 810, -1578, - 15976, -139, -1035, -416, -543, -418, 2824, -6541, - 94, -673, 11741, 426, -15, -5280, 780, 1795, - -4616, 8192, -297, -206, 883, 2369, -395, -4266, - -3120, -199, 985, 1240, 352, 232, -170, 176, - 413, -495, -1399, 754, 618, -6103, -179, -2546, - 965, -1362, -806, 838, -3912, -1346, -3135, -937, - 219, 307, -3509, 1210, 2381, -7923, 6358, -885, - 2902, 284, 2560, 1789, 6878, 6, -4418, -2206, - -1091, 1840, -118, -2659, 1008, 2192, 1651, 1363, - -7772, 1252, -1200, 133, -757, 501, -98, -17197, - 98, -543, 1743, 621, -809, -1950, -793, 1168, - -743, -7124, 166, 7875, -4466, 356, -1430, -467, - 8589, 9931, 520, -866, 1945, -599, -434, 113, - 589, -3456, 597, 6076, 1114, 9660, 1532, 2073, - -138, -721, -1030, -1309, 625, -4040, 1211, -18836, - -3963, -4468, 197, 600, -1004, -816, -560, -476, - -2160, -2, 26, 8162, 1057, -178, -11739, -1882, - 1000, -227, 109, -1852, -1163, -17143, 140, -718, - -1150, 33, 1397, -45, -205, 153, -1494, 20509, - -51, -904, -599, 1915, 884, 504, -1819, -4487, - 1252, -1259, -2200, -5601, -448, -686, 5778, 873, - -4282, -533, 295, -450, 1422, 2393, 3267, -3911, - 249, -3605, -3190, -1096, -2422, 274, -1918, 4070, - -206, -432, 1919, -645, -275, 12954, 311, 1479, - -2664, -852, -4809, 1102, -375, 20, 1659, -1179, - 1199, 44, -5590, -1112, -566, -11369, -125, -871, - 158, 1208, 265, -519, -405, 2439, -1129, 1827, - -9461, 8548, -1606, 380, 4924, 662, 1314, -391, - -2024, 827, -13381, -198, -142, 1600, 3329, 125, - -672, -220, 557, 18642, 60, 7296, -10472, -712, - 1188, 808, 64, 479, 555, 264, 394, -611, - -810, -7943, -235, -6889, -1575, 1320, -381, -7414, - 1740, -744, 369, -626, -6899, -2144, -593, 668, - -351, -3756, -5143, -1814, 806, -475, 588, -507, - -9088, -629, 154, -6945, -1105, 10658, -435, 384, - -757, 1183, 3806, -747, -378, 535, 10224, 626, - -866, -1931, -1484, 5818, -750, -9628, -250, 589, - -653, -198, 104, -934, 1207, 46, 960, -1032, - 4236, 4471, -2896, 1551, -7714, -1921, 746, -671, - 5114, 5482, -522, -3344, -1905, -9220, -663, -1355, - -611, 65, 1368, 628, -1276, -6780, -2623, -661, - -117, -437, 5507, 3205, 928, 537, -9487, 80, - -102, -538, -277, 863, -1421, 6054, 1227, 696, - 3582, -508, -1757, 145, -1705, -1201, 4157, -3314, - 2291, -834, 821, 552, -724, 513, -9730, -8944, - 1913, 501, -216, 716, 2766, -823, 2535, 314, - 1774, -3372, 235, 244, -1216, -710, 689, 6736, - -52, 218, -8382, -444, 920, 569, -4890, -2050, - -612, 1708, -481, -15500, -2878, -691, 538, -125, - -81, -862, -10094, 12050, -1392, -326, 133, 61, - -50, 715, -6662, -673, 10745, -596, 44, 3906, - 247, -745, 4950, -210, 497, -1875, 8197, 2141, - 1454, -23, -1480, 2184, -804, 5515, -1311, -8893, - -2880, -3606, -282, -116, 8084, 618, -403, 1106, --14405, 1159, 229, 742, -184, -19445, -329, -747, - -1240, 1487, -1670, -839, -77, -882, -10986, -2851, - -24, -747, -3615, 1939, 1389, 132, 5367, 1355, - 408, -1272, 11388, 153, 2708, -1503, 169, 7357, - 51, -13586, -404, -304, 626, 163, -1814, -515, - 445, 589, -1194, 770, 555, 246, -165, -21192, - 184, -265, -1116, -485, -8107, -1992, -10805, -880, - -1455, -15154, 2312, -1712, -11, -1899, -400, -2, - 314, -318, -280, -658, -1066, -2584, 1027, 801, --11960, 1519, 8873, 465, -3229, 1801, -348, 749, - 7, 1079, -2051, 11521, -831, -13425, -6315, -1135, - 1088, 1056, -46, -1006, 374, -5065, 1163, -402, - -50, -1459, 9586, 514, -1439, -638, -155, -5289, - 8043, -612, 739, 1084, -60, 891, 786, -6, - -1078, 2097, -5333, 3497, 23, -913, 1303, 957, - -35, -6418, -146, -971, 2738, 9695, -1722, -2002, - 905, -1749, -917, 122, 379, -325, -455, 230, - 825, -137, -335, -96, -160, 390, 731, -2621, - -5889, -3949, 5138, 839, -1190, -66, 961, -4600, - 2345, 1607, -2448, -6653, -592, -106, -7619, -794, - -1186, -12587, -11, -2224, -225, -2903, 534, 1355, - -7002, 314, 494, 1950, -8545, -2531, -2438, -77, - 886, -1851, 944, -10156, 3003, 1846, 1919, 2019, - 471, 451, -436, -1012, -20121, 275, 98, 1776, - 578, 96, -16, 1156, 3689, 7, -207, 920, - 105, -58, -175, 163, 697, -407, -61, 1261, - 1297, 5061, 5326, -1126, 516, 1208, -11108, 441, - 7, -899, -19, -368, 438, -1911, 602, 716, - 313, 853, 1448, -817, -1453, 1384, -4371, 1043, - 1884, 1619, 2196, 10075, -1548, -1201, -796, 5228, - 2657, 8244, -605, 422, -693, 3171, 657, 5438, - -171, 633, 1579, -1718, -12265, 1083, -976, -293, - -3802, -306, -668, 7818, -1340, -402, 2231, -4472 -}, - -.shape44 = { - -40, -282, 1366, -1173, -3484, 355, -1078, 3800, - 4386, -35, -4192, 523, 1291, 678, 156, 2272, - -1043, 1075, -1849, -314, -522, 392, 2098, -79, - 473, -275, 2, 6398, 451, 94, 173, -431, - 1115, -10788, 35, 1823, -3380, -97, -98, -350, - -23, -1264, -308, 8948, -695, -79, 3520, 308, - 340, -362, -547, 1207, -1182, -10392, -148, 3580, - 481, -425, 862, 4894, 736, -152, -626, 23, - -5853, 39, -143, 418, -103, -1457, -12826, -122, - 283, -225, 10561, -153, 8872, -806, -51, 93, - 420, -209, 345, -7661, -732, -48, 479, -225, - 276, 13385, -12578, -1440, -265, -274, 1105, -3376, - -691, -579, -972, 300, 349, 362, 722, -472, - 185, 814, 14, 4746, 761, -336, 1691, 888, - -1669, -18717, 827, -2605, 921, 155, 68, 112, - -3032, -287, 414, -86, -62, -213, -106, 807, - -619, 598, -178, 3104, -481, -1553, 1250, -8363, - -686, -9608, 116, -47, 321, -89, 939, -35, - -7995, -10159, -526, 145, 363, 2170, 1077, -1223, - -738, 120, -408, -390, -80, -404, -1607, -10187, - -6432, 961, 94, -1459, 489, 6641, 372, 1007, - 5958, -834, 222, 51, 282, -1005, 4473, -8841, - -73, -477, -557, 121, -165, -1195, 438, 139, - -190, -4205, -4278, -4617, -7592, 40, -422, -459, - 594, 7331, 164, 297, 2631, -9075, -78, 372, - -6213, -1053, 182, -71, -386, -604, -11720, 552, - -617, 413, 1292, 4, -485, 1162, 6051, -5168, - -181, 1024, -630, -275, -4067, -8627, 1386, 970, - -423, 2973, 2360, 363, -274, 410, 48, 768, - 2958, -427, 86, 64, -128, -273, -182, -292, - 868, 463, 73, -116, -6509, -5295, -37, 691, - 344, -120, 168, 419, 494, -1175, 18896, -135, - -376, -218, -453, -916, -1040, -22179, -846, -1005, - 264, 159, 597, -952, -825, 393, -328, -14694, - 371, -263, 740, 38, -1001, 1289, -668, 187, - -155, 143, 683, 7133, -563, -8383, -291, 176, - 75, 613, -6965, -11480, 324, -490, 586, 416, - 762, 5777, 64, -47, -4124, -1196, -113, 701, - -211, 2335, 130, 684, 7278, -158, -213, 297, - 10845, -1439, -465, 17, -792, 6499, -10187, -444, - -1416, 482, 636, 1472, 752, 157, -334, -3230, - -19, -6747, 660, -3082, 4057, 6801, -19, 635, - 19, 9807, 526, 126, 444, -190, -418, -26754, - -202, 243, 597, 10, 345, 814, -330, 160, - 344, 3986, 470, 459, 2387, -549, 11889, -1837, - -30, 2608, 615, 2301, -771, -1589, -6935, 1321, - 4287, 295, -558, -1503, -611, 2104, 411, -218, - 1145, -426, 58, -102, 13, 7499, 476, -4032, - -2237, -2658, -1943, 5268, 1039, 389, 7091, -22, - 156, -186, 2432, -878, 305, -1726, 3209, 361, - -1030, 505, 618, -262, -1877, 268, 757, 24, - 24306, 102, 973, 142, -953, -1199, 116, -255, - 5370, -347, -365, 937, -6939, -1189, -760, 531, - -1759, -705, -557, -620, 1151, 250, 21629, -1532, - -128, 1421, -211, 592, 5126, 197, -716, 1113, - 5844, -266, -12, -813, 85, 994, -2106, -3915, - 1402, 533, 521, -883, 87, -386, -2, -4350, - 19790, -180, -363, 60, 101, -1717, 119, -381, - 100, -565, 3264, 3052, 200, -7319, 26, 347, - -482, 10609, -766, 526, -623, 3495, 339, -4406, - -59, -213, 686, -603, 133, 99, 48, 1716, - -1214, 1397, -2396, -384, -901, -3750, -660, -4314, - 313, 192, 292, 259, -644, 176, 2099, 7961, - -29, 642, -2970, 1792, -61, -4348, 578, 1867, - -1868, 32, 5262, 137, 6109, 443, -176, 351, - 400, 1874, -175, -4065, 697, 292, -744, 121, - -5134, 6996, -198, 628, 1073, -599, -116, -17900, - 647, -1049, -663, 1427, -94, 721, 311, 337, - 1376, -2784, 3947, 1342, 1577, -406, -260, -10228, - 109, 2358, 2437, 346, 1261, -308, -2094, 1682, - 144, -675, 183, 428, -950, 1249, -1546, 33, - -254, 681, -1264, -964, -310, 838, 100, -21952, - -1484, -1564, 339, 298, 67, -338, 89, 709, - 53, 258, -359, 2803, 1553, -312, -7993, -1627, - 1189, 476, -123, 336, -767, -18522, 589, 942, - -645, -381, -1913, -582, 55, -876, -509, 25143, - 690, -787, -1136, 114, 162, 342, -231, -8742, - 99, -646, -474, -1384, -110, -98, 8634, -14, - -9676, -312, 358, 496, -676, -97, 1904, -2124, - -66, -1868, 502, -513, -3244, 2079, -1476, 5440, - -40, -381, 500, -238, -471, 12160, 248, -1005, - -2886, 173, -3369, -355, -256, -117, -474, -1282, - -355, 130, -4833, 31, -232, -12931, -826, 322, - 839, 1537, 73, 226, -1888, -483, -2848, -190, - 1271, 3597, -4514, -38, 6093, 347, -68, -415, - -105, -1664, -11461, -110, -399, 389, -511, 935, - -424, -1708, -1026, 23239, 298, 7363, -9206, -566, - 259, -412, -1213, 335, 614, 928, 972, -1919, - -407, 509, 303, -13762, -524, 10360, 1318, -2758, - 2350, -106, -119, -68, -6155, -255, -448, -34, - -64, -4382, 47, 635, -339, 406, -447, -445, --10592, 233, 160, -5515, -1333, 6755, -952, 172, - -1260, -294, 3480, -352, -231, 415, 482, -498, - -191, -2034, 7934, 7997, -688, -9503, 376, -228, - -500, 222, -1021, -407, 261, 179, 622, 1217, - -443, -763, -508, -719, -4509, 91, 449, -283, - 91, -39, 961, -10148, 1596, -9161, -327, 221, - -470, 676, 12, 1416, 984, -10988, -5500, -189, - -727, 226, 4691, 688, 759, 930, -6444, -114, - -539, -526, -21, -1218, 650, 6088, 419, 6185, - -1200, 84, -1232, -34, -107, 60, 2248, 450, - 1187, 1264, -181, 857, 2235, -2859, -13483, -192, - -586, -207, -5569, 503, 3376, 1243, -700, 2119, - -2186, -296, 896, 299, 177, 184, 1375, 2498, - 161, 579, -3683, 443, -21, -186, -3474, 238, - 274, 277, -325, -8325, -223, 125, 191, 333, - -345, -1391, -7372, 11389, -1055, 4066, -1098, 87, - -203, 443, 363, -959, 15395, 4016, -254, 1611, - -168, -1070, 2709, -768, 506, -1245, 5821, 2499, - 1564, 27, 85, 1989, -1092, 150, -972, 660, - -33, 687, 545, -1564, 720, -196, -52, -1751, --25380, -1246, -615, 391, -512, -23289, 460, 360, - -85, -723, -250, -163, -48, -921, -3988, 425, - -1268, -1695, 3233, -1093, -1166, 198, 7602, 21, - 354, 733, 12213, -347, 532, -427, 22, 2218, - -578, -3382, -474, -625, 78, -4546, 863, -53, - -357, -1529, 1014, 710, 1356, -430, -1633, -24823, - 95, 26, 590, -591, -7833, -1355, -9771, -502, - -907, -15433, 957, 463, 35, -496, 294, 2129, - 1274, -160, -83, 531, -767, 285, 232, 5983, - -6122, 1620, 4112, -239, -1733, -46, -1321, 467, - 613, -3747, -2284, 13991, 373, -17357, -219, -80, - -210, 1462, 37, -1692, 548, -5845, 420, 54, - -350, -285, 1981, 262, -874, 2844, -435, -6305, - 6449, 72, 631, -94, 96, -442, 1137, 89, - 364, 3392, -3512, -387, 1055, 318, -1111, -6971, - 344, -9105, -96, -9362, 190, -225, 370, 161, - -73, -1830, 174, 48, -518, -3486, 137, -235, - 810, 23, 80, -642, -35, -316, -269, -373, - -2413, -933, 2525, 267, -508, -200, 422, -3470, - -1273, 640, -1956, 139, 394, -1043, -11008, -158, - -1089, -2023, 202, -979, -744, -159, -392, -37, - -1679, 2183, 1365, -2883, -4752, -2255, 109, 1660, - -613, -511, 1284, -7331, 947, 7009, -2072, -321, - -936, -551, -875, 160, -27027, 654, 265, 164, - 376, 726, -149, 2813, -94, 5728, 702, -1118, - -2555, 217, -186, -107, 146, -83, -62, -196, - 708, 146, 3729, -416, 212, -163, -7861, 347, - 83, -1079, -994, 271, -1054, -1647, 139, -20, - 354, 1298, -3420, 1130, 161, 475, -3913, 468, - 23, 285, -1699, 8234, -947, 222, 260, 4276, - -341, 6387, 21, 490, -1908, -1654, -60, 2471, - 733, -135, 109, -1136, -14756, 4922, 1165, 149, - -3976, -66, -594, 6181, -110, 292, 1129, -591 -}, - -.lsp08 = { - 0.2702, 0.5096, 0.6437, 0.7672, 0.9639, 1.0696, 1.2625, 1.5789, - 1.9285, 2.2383, 2.5129, 2.8470, 0.1740, 0.3677, 0.6082, 0.8387, - 1.1084, 1.3721, 1.6362, 1.8733, 2.0640, 2.3442, 2.6087, 2.8548, - 0.1536, 0.3279, 0.5143, 0.6859, 0.9763, 1.2744, 1.5605, 1.8566, - 2.1007, 2.3450, 2.6075, 2.8850, 0.2075, 0.4533, 0.7709, 1.0377, - 1.2953, 1.5132, 1.7826, 2.0351, 2.2590, 2.4996, 2.6795, 2.8748, - 0.1393, 0.2453, 0.3754, 0.5453, 0.8148, 1.1289, 1.4389, 1.7592, - 2.0353, 2.3215, 2.5934, 2.8588, 0.1250, 0.3627, 0.7613, 1.1380, - 1.4163, 1.5565, 1.6920, 1.8130, 1.8678, 2.0427, 2.4318, 2.8544, - 0.2256, 0.4223, 0.6452, 0.8599, 1.0673, 1.3118, 1.5486, 1.8366, - 2.0759, 2.3026, 2.5284, 2.8030, 0.2304, 0.4404, 0.6891, 0.8964, - 1.1510, 1.4202, 1.6483, 1.8580, 2.1181, 2.3686, 2.6078, 2.9128, - 0.2230, 0.3816, 0.5520, 0.6062, 0.7909, 1.0988, 1.4330, 1.7846, - 2.0713, 2.3457, 2.6048, 2.8708, 0.2447, 0.5800, 0.8249, 0.9905, - 1.1721, 1.3990, 1.6694, 1.9064, 2.1307, 2.4255, 2.6815, 2.9117, - 0.1974, 0.3812, 0.5802, 0.7759, 0.9280, 1.1547, 1.4170, 1.6369, - 1.8890, 2.2587, 2.5626, 2.8239, 0.1209, 0.2510, 0.4841, 0.8048, - 1.1197, 1.3563, 1.6073, 1.8926, 2.1350, 2.3669, 2.6291, 2.8985, - 0.2352, 0.4347, 0.6582, 0.8178, 0.9548, 1.1654, 1.4942, 1.8812, - 2.1703, 2.3779, 2.6412, 2.8871, 0.2091, 0.4084, 0.6730, 0.9151, - 1.1259, 1.3262, 1.5937, 1.8129, 2.0237, 2.3317, 2.5778, 2.8620, - 0.1167, 0.2406, 0.4520, 0.7298, 0.9848, 1.2448, 1.5137, 1.7874, - 2.0280, 2.3020, 2.5914, 2.8794, 0.3003, 0.4966, 0.6520, 0.8505, - 1.1600, 1.3981, 1.5805, 1.8346, 2.0757, 2.3102, 2.5760, 2.8499, - 0.2451, 0.4163, 0.5960, 0.7805, 0.9507, 1.2438, 1.5587, 1.8581, - 2.0735, 2.3198, 2.5704, 2.8220, 0.3112, 0.5517, 0.7032, 0.8528, - 1.1489, 1.4257, 1.6848, 1.9388, 2.1577, 2.4265, 2.6678, 2.9051, - 0.2249, 0.3897, 0.5559, 0.7473, 1.0158, 1.3581, 1.6914, 1.9930, - 2.1843, 2.3534, 2.5512, 2.8065, 0.2600, 0.4574, 0.7349, 0.9691, - 1.1696, 1.3848, 1.6335, 1.9021, 2.1174, 2.3481, 2.5902, 2.8390, - 0.2246, 0.3372, 0.4560, 0.5249, 0.7056, 1.0273, 1.3810, 1.7132, - 1.9819, 2.2574, 2.5410, 2.8491, 0.1419, 0.4834, 0.8835, 1.1453, - 1.2839, 1.4224, 1.5593, 1.7877, 2.1285, 2.4070, 2.6043, 2.8511, - 0.1886, 0.3677, 0.5617, 0.8099, 1.1277, 1.3841, 1.5804, 1.8136, - 2.0307, 2.2805, 2.5399, 2.8322, 0.2351, 0.4151, 0.6675, 0.8713, - 1.0464, 1.3292, 1.6586, 1.9281, 2.1355, 2.3495, 2.6222, 2.8782, - 0.2700, 0.4489, 0.6206, 0.7121, 0.7737, 0.9848, 1.3658, 1.7433, - 2.0139, 2.2243, 2.4806, 2.8175, 0.2479, 0.4425, 0.6490, 0.8745, - 1.1161, 1.3849, 1.6773, 1.9566, 2.1491, 2.3624, 2.5685, 2.8114, - 0.2035, 0.3701, 0.5567, 0.7953, 1.0082, 1.2758, 1.5373, 1.7822, - 2.0175, 2.2601, 2.4759, 2.7771, 0.1856, 0.3461, 0.5998, 0.9041, - 1.2383, 1.4612, 1.6667, 1.9305, 2.1617, 2.4107, 2.6477, 2.8656, - 0.2107, 0.3715, 0.5289, 0.6651, 0.8420, 1.1168, 1.4401, 1.7230, - 1.9901, 2.2687, 2.5452, 2.8655, 0.1218, 0.2999, 0.6348, 0.9482, - 1.2745, 1.5876, 1.9129, 2.2348, 2.4020, 2.4922, 2.6351, 2.8357, - 0.1617, 0.3483, 0.5869, 0.8163, 1.0366, 1.2344, 1.4609, 1.7029, - 1.9476, 2.2337, 2.5258, 2.8442, 0.2505, 0.4894, 0.7510, 0.9152, - 1.0845, 1.3657, 1.6528, 1.8346, 2.0160, 2.2811, 2.5338, 2.8136, - 0.0947, 0.1158, 0.0578, -0.0337, -0.0066, 0.0104, -0.0447, -0.0505, --0.0778, -0.0293, 0.0251, -0.0143, 0.0349, -0.0227, -0.0909, 0.0523, - 0.0325, -0.0410, -0.1045, -0.0899, -0.0009, 0.0075, -0.0575, -0.0855, --0.0129, 0.0575, 0.0597, 0.0391, 0.0371, -0.0184, -0.0083, 0.0287, - 0.0143, 0.0167, 0.0120, -0.0168, 0.0452, 0.0223, -0.0352, 0.0119, --0.0496, -0.0965, -0.0661, -0.0072, 0.1099, 0.0843, -0.0087, -0.0478, --0.0128, -0.0120, -0.0004, 0.0731, 0.1047, 0.0630, 0.0196, -0.0103, --0.0399, -0.0986, -0.0912, -0.0390, -0.0247, -0.0694, -0.0749, -0.0066, - 0.0223, 0.0634, 0.0343, -0.0134, 0.0727, 0.0241, 0.0066, 0.0437, - 0.0610, 0.0364, 0.0248, -0.0358, -0.0686, -0.0104, 0.0426, 0.0088, --0.0137, -0.0165, 0.0671, 0.0815, -0.0863, -0.0644, -0.0088, 0.0023, - 0.0482, 0.1174, 0.1270, 0.0594, 0.0165, 0.0949, 0.1098, 0.0137, - 0.4951, 0.4999, 0.4958, 0.4907, 0.4984, 0.4965, 0.4958, 0.4996, - 0.4987, 0.4958, 0.4986, 0.4977, 0.2841, 0.2186, 0.1474, 0.1687, - 0.2217, 0.2632, 0.2706, 0.2624, 0.2162, 0.2453, 0.2460, 0.2531 -}, - -.lsp11 = { - 0.1103, 0.3862, 0.6863, 0.8447, 0.9231, 1.0261, 1.1248, 1.4057, - 1.6621, 1.8010, 1.8692, 2.0704, 2.3490, 2.6060, 2.7539, 2.8977, - 0.1273, 0.2407, 0.3812, 0.6004, 0.7767, 0.9383, 1.1344, 1.3351, - 1.5233, 1.7262, 1.9466, 2.1739, 2.3495, 2.5162, 2.7164, 2.9202, - 0.2010, 0.3330, 0.4488, 0.6465, 0.8046, 0.9889, 1.1479, 1.2964, - 1.4770, 1.6606, 1.8789, 2.1155, 2.3287, 2.5199, 2.7101, 2.9119, - 0.1168, 0.2197, 0.3279, 0.4691, 0.6268, 0.8251, 1.0533, 1.2714, - 1.4712, 1.6762, 1.8831, 2.1114, 2.3230, 2.5297, 2.7365, 2.9270, - 0.1405, 0.3109, 0.4986, 0.6891, 0.8634, 1.0583, 1.2594, 1.4349, - 1.6232, 1.8116, 1.9905, 2.1935, 2.3799, 2.5656, 2.7661, 2.9486, - 0.1703, 0.3057, 0.4403, 0.5225, 0.5969, 0.8110, 1.0729, 1.3215, - 1.5407, 1.7381, 1.9477, 2.1680, 2.3586, 2.5612, 2.7630, 2.9410, - 0.1128, 0.2628, 0.4523, 0.6495, 0.8176, 0.9816, 1.1746, 1.3710, - 1.5568, 1.7518, 1.9497, 2.1452, 2.3346, 2.5389, 2.7362, 2.9264, - 0.1809, 0.3287, 0.5205, 0.7264, 0.9298, 1.1217, 1.2970, 1.4894, - 1.6874, 1.8493, 2.0576, 2.2382, 2.4097, 2.6041, 2.7796, 2.9389, - 0.2502, 0.4709, 0.6892, 0.8346, 0.9209, 1.0455, 1.2399, 1.4616, - 1.6463, 1.8380, 2.0475, 2.2397, 2.4665, 2.6550, 2.7701, 2.8895, - 0.1040, 0.2340, 0.3964, 0.5740, 0.7764, 0.9941, 1.2000, 1.4014, - 1.6024, 1.7974, 1.9939, 2.1959, 2.3783, 2.5663, 2.7613, 2.9484, - 0.1912, 0.3393, 0.4743, 0.6313, 0.8014, 0.9879, 1.1855, 1.3922, - 1.5678, 1.7289, 1.9271, 2.1165, 2.3089, 2.5414, 2.7448, 2.9269, - 0.0965, 0.2025, 0.3398, 0.4990, 0.6934, 0.9386, 1.1730, 1.3766, - 1.5783, 1.7783, 1.9790, 2.1831, 2.3670, 2.5578, 2.7641, 2.9516, - 0.2126, 0.3652, 0.5545, 0.7170, 0.8674, 1.0640, 1.2558, 1.4061, - 1.5904, 1.8095, 1.9760, 2.1505, 2.3549, 2.5575, 2.7023, 2.8877, - 0.1827, 0.3426, 0.4894, 0.6488, 0.7960, 0.9535, 1.1217, 1.2798, - 1.4566, 1.6453, 1.8044, 2.0042, 2.2379, 2.4611, 2.6697, 2.8966, - 0.2034, 0.3822, 0.5231, 0.6960, 0.9200, 1.0394, 1.1616, 1.3772, - 1.5493, 1.7330, 1.9646, 2.1233, 2.3334, 2.5361, 2.7087, 2.9470, - 0.1050, 0.2060, 0.3705, 0.5998, 0.8337, 1.0577, 1.2559, 1.4327, - 1.6334, 1.8165, 1.9853, 2.2058, 2.4063, 2.5818, 2.7625, 2.9458, - 0.1419, 0.4053, 0.6660, 0.8911, 1.0405, 1.1547, 1.2506, 1.3926, - 1.5669, 1.7527, 1.9694, 2.2054, 2.3889, 2.5743, 2.7586, 2.9174, - 0.1514, 0.2825, 0.4309, 0.5772, 0.7470, 0.9703, 1.1462, 1.3316, - 1.5321, 1.7259, 1.9282, 2.1266, 2.3106, 2.5064, 2.7067, 2.9094, - 0.1693, 0.3156, 0.4878, 0.6635, 0.8206, 0.9569, 1.1154, 1.3064, - 1.5109, 1.7184, 1.9179, 2.1036, 2.2763, 2.4820, 2.6949, 2.9105, - 0.1432, 0.2718, 0.4241, 0.5564, 0.6939, 0.9011, 1.1582, 1.3948, - 1.6181, 1.8024, 1.9814, 2.1740, 2.3459, 2.5456, 2.7491, 2.9307, - 0.2294, 0.3857, 0.5590, 0.7434, 0.9189, 1.0941, 1.2740, 1.4456, - 1.6178, 1.7994, 1.9689, 2.1644, 2.3525, 2.5385, 2.7468, 2.9405, - 0.1667, 0.3109, 0.4612, 0.6032, 0.7375, 0.8866, 1.0840, 1.3053, - 1.4982, 1.7044, 1.9146, 2.1117, 2.2942, 2.4983, 2.7084, 2.9132, - 0.1810, 0.3205, 0.4696, 0.6231, 0.7641, 0.9959, 1.2427, 1.4361, - 1.5889, 1.7544, 1.9083, 2.0733, 2.2457, 2.4461, 2.6793, 2.9098, - 0.1164, 0.3753, 0.6068, 0.7503, 1.0100, 1.2131, 1.3793, 1.5302, - 1.6300, 1.7950, 1.9057, 2.1031, 2.3830, 2.5745, 2.6949, 2.8779, - 0.1571, 0.4378, 0.6735, 0.8312, 0.8944, 0.9818, 1.1622, 1.4094, - 1.6423, 1.8066, 1.9258, 2.1838, 2.4363, 2.6279, 2.7358, 2.8790, - 0.1398, 0.2686, 0.4248, 0.6156, 0.7870, 1.0035, 1.2012, 1.3689, - 1.5363, 1.7398, 1.9604, 2.1619, 2.3345, 2.5097, 2.7271, 2.9368, - 0.1913, 0.3338, 0.4987, 0.6446, 0.7852, 1.0163, 1.1886, 1.3610, - 1.5379, 1.7230, 1.8880, 2.0862, 2.2960, 2.4928, 2.7122, 2.9151, - 0.0908, 0.1752, 0.2899, 0.5365, 0.7761, 1.0100, 1.2124, 1.4060, - 1.6019, 1.8010, 1.9774, 2.1905, 2.3733, 2.5623, 2.7660, 2.9565, - 0.1773, 0.3179, 0.4925, 0.6864, 0.8452, 0.9897, 1.1860, 1.3722, - 1.5515, 1.7658, 1.9802, 2.1819, 2.3620, 2.5442, 2.7250, 2.9220, - 0.1286, 0.2341, 0.3689, 0.5364, 0.7176, 0.9350, 1.1083, 1.2943, - 1.4974, 1.7059, 1.9047, 2.1145, 2.3242, 2.5361, 2.7453, 2.9329, - 0.2273, 0.3834, 0.5565, 0.7192, 0.8431, 0.9962, 1.1763, 1.3571, - 1.5774, 1.7419, 1.9202, 2.1131, 2.2919, 2.4898, 2.6895, 2.9180, - 0.1775, 0.3058, 0.4274, 0.6023, 0.8151, 1.0734, 1.3211, 1.5178, - 1.6706, 1.8154, 1.9686, 2.1537, 2.3461, 2.5276, 2.7181, 2.9121, - 0.1653, 0.4304, 0.6361, 0.7824, 0.9183, 1.0452, 1.2071, 1.4077, - 1.6206, 1.8299, 2.0089, 2.1948, 2.3900, 2.5982, 2.7844, 2.9487, - 0.1492, 0.2609, 0.3820, 0.5485, 0.7243, 0.9319, 1.1538, 1.3579, - 1.5266, 1.7002, 1.8873, 2.1016, 2.3175, 2.5221, 2.7241, 2.9243, - 0.2074, 0.3781, 0.5209, 0.6869, 0.8577, 0.9875, 1.1849, 1.3568, - 1.4907, 1.7335, 1.8902, 2.1224, 2.3099, 2.4918, 2.7023, 2.8765, - 0.1359, 0.2254, 0.3286, 0.4432, 0.6586, 0.8964, 1.1125, 1.3523, - 1.5626, 1.7579, 1.9846, 2.1905, 2.3548, 2.5542, 2.7663, 2.9346, - 0.1430, 0.2966, 0.4685, 0.6493, 0.8315, 1.0304, 1.2220, 1.4082, - 1.5995, 1.7888, 1.9774, 2.1737, 2.3607, 2.5577, 2.7558, 2.9405, - 0.1477, 0.2694, 0.4056, 0.5626, 0.7051, 0.8647, 1.0491, 1.2488, - 1.4814, 1.7072, 1.9150, 2.1147, 2.3038, 2.5144, 2.7184, 2.9202, - 0.1690, 0.3033, 0.4580, 0.6686, 0.8536, 1.0293, 1.2124, 1.3998, - 1.5718, 1.7607, 1.9580, 2.1245, 2.2971, 2.4762, 2.6896, 2.9177, - 0.1092, 0.2779, 0.4853, 0.6880, 0.9011, 1.0953, 1.2752, 1.4618, - 1.6623, 1.8484, 2.0264, 2.2152, 2.4017, 2.5835, 2.7671, 2.9436, - 0.1497, 0.3637, 0.6014, 0.8032, 0.9963, 1.1835, 1.3741, 1.5698, - 1.7382, 1.9094, 2.0710, 2.2392, 2.4082, 2.5926, 2.7762, 2.9536, - 0.1434, 0.2492, 0.3966, 0.5934, 0.8033, 1.0657, 1.2796, 1.4276, - 1.5745, 1.7833, 1.9288, 2.1247, 2.3543, 2.5412, 2.7049, 2.8872, - 0.1612, 0.2926, 0.4574, 0.6387, 0.8265, 1.0180, 1.1808, 1.3526, - 1.5564, 1.7536, 1.9187, 2.1192, 2.3149, 2.5006, 2.7101, 2.9217, - 0.0828, 0.1863, 0.3235, 0.5050, 0.7250, 0.9867, 1.2093, 1.3941, - 1.5980, 1.7932, 1.9809, 2.1894, 2.3918, 2.5773, 2.7540, 2.9329, - 0.2001, 0.3655, 0.5290, 0.6761, 0.8027, 0.9972, 1.2090, 1.4255, - 1.6085, 1.7825, 1.9804, 2.1681, 2.3457, 2.5325, 2.7319, 2.9196, - 0.1505, 0.2767, 0.4254, 0.6054, 0.7821, 0.9567, 1.1294, 1.3080, - 1.4984, 1.6954, 1.8666, 2.0736, 2.2875, 2.4969, 2.7072, 2.9163, - 0.1589, 0.4151, 0.5749, 0.6651, 0.8061, 1.0470, 1.2616, 1.3690, - 1.4985, 1.7808, 1.9825, 2.1068, 2.2751, 2.5448, 2.7133, 2.8689, - 0.0916, 0.1846, 0.3788, 0.6329, 0.8774, 1.0687, 1.2653, 1.4561, - 1.6573, 1.8449, 2.0402, 2.2254, 2.3968, 2.5861, 2.7792, 2.9508, - 0.2282, 0.4159, 0.5834, 0.6899, 0.8108, 1.0321, 1.2795, 1.5262, - 1.6936, 1.8469, 2.0922, 2.2607, 2.3795, 2.5301, 2.7386, 2.9530, - 0.1651, 0.3004, 0.4555, 0.6179, 0.7891, 0.9584, 1.1372, 1.3707, - 1.5951, 1.7880, 1.9434, 2.1465, 2.3311, 2.5081, 2.6977, 2.8970, - 0.1279, 0.3828, 0.6330, 0.8323, 0.9652, 1.1175, 1.2319, 1.3511, - 1.5115, 1.6392, 1.7835, 1.9558, 2.2008, 2.4635, 2.6910, 2.9058, - 0.1193, 0.2185, 0.3521, 0.5311, 0.7378, 0.9239, 1.1105, 1.3217, - 1.5362, 1.7504, 1.9536, 2.1627, 2.3560, 2.5506, 2.7548, 2.9453, - 0.1806, 0.3432, 0.4981, 0.6948, 0.8928, 1.0527, 1.2467, 1.4140, - 1.6326, 1.7950, 1.9935, 2.1969, 2.3512, 2.5682, 2.7445, 2.9277, - 0.1846, 0.3112, 0.4568, 0.5891, 0.7317, 0.8493, 1.0204, 1.2022, - 1.3688, 1.6020, 1.8428, 2.0710, 2.2725, 2.4879, 2.7057, 2.9160, - 0.0880, 0.2514, 0.5332, 0.7272, 0.8906, 1.1354, 1.3199, 1.4941, - 1.6010, 1.7151, 1.8712, 2.0643, 2.2755, 2.5375, 2.7054, 2.8891, - 0.1382, 0.2833, 0.4658, 0.6897, 0.9071, 1.0716, 1.2469, 1.4143, - 1.5910, 1.7947, 1.9805, 2.1581, 2.3338, 2.5215, 2.7292, 2.9211, - 0.1061, 0.3494, 0.6327, 0.8570, 0.9748, 1.0560, 1.1529, 1.3250, - 1.6032, 1.8340, 1.9711, 2.1157, 2.3011, 2.5464, 2.8078, 2.9803, - 0.1603, 0.2839, 0.4307, 0.5980, 0.7980, 1.0399, 1.1971, 1.3524, - 1.5715, 1.7838, 1.9468, 2.1498, 2.3627, 2.5514, 2.7327, 2.9148, - 0.1691, 0.3117, 0.4796, 0.6895, 0.8732, 1.0164, 1.1916, 1.3707, - 1.5384, 1.7202, 1.8857, 2.0672, 2.2487, 2.4593, 2.6789, 2.8940, - 0.0965, 0.1702, 0.3191, 0.5721, 0.8100, 1.0241, 1.2272, 1.4196, - 1.6093, 1.8057, 1.9884, 2.2037, 2.3925, 2.5805, 2.7578, 2.9366, - 0.1950, 0.3519, 0.5272, 0.6973, 0.8732, 1.0656, 1.2112, 1.3959, - 1.6116, 1.7821, 1.9445, 2.1592, 2.3348, 2.5142, 2.7440, 2.9297, - 0.1388, 0.2557, 0.4120, 0.5727, 0.7354, 0.9196, 1.0985, 1.2805, - 1.4643, 1.6535, 1.8340, 2.0546, 2.2758, 2.4778, 2.6921, 2.9122, - 0.1823, 0.3336, 0.4957, 0.6771, 0.8563, 1.0137, 1.2299, 1.3849, - 1.5718, 1.7667, 1.9193, 2.1326, 2.3135, 2.5268, 2.7133, 2.8998, - 0.0790, 0.1901, 0.4083, 0.6456, 0.8463, 1.0285, 1.2297, 1.4181, - 1.6159, 1.8056, 1.9971, 2.1912, 2.3816, 2.5746, 2.7692, 2.9497, - 0.0049, 0.0116, 0.0045, 0.0039, -0.0010, -0.0122, -0.0205, -0.0034, --0.0140, -0.0041, 0.0191, -0.0322, 0.0002, -0.0124, -0.0269, 0.0059, - 0.0586, 0.0339, -0.0389, -0.0319, -0.0079, -0.0205, -0.0363, -0.0211, - 0.0241, 0.0595, 0.0469, 0.0283, 0.0176, -0.0183, -0.0173, -0.0004, - 0.0024, 0.0145, 0.0534, 0.0197, -0.0065, -0.0067, 0.0133, 0.0358, --0.0104, -0.0386, -0.0109, -0.0078, 0.0275, 0.0565, 0.0251, -0.0027, --0.0053, 0.0171, 0.0088, 0.0495, 0.0141, 0.0039, -0.0445, -0.0426, --0.0184, -0.0280, -0.0223, 0.0039, -0.0171, -0.0606, -0.0786, -0.0430, - 0.0544, 0.0595, 0.0320, -0.0012, 0.0108, 0.0185, 0.0066, 0.0408, - 0.0552, -0.0073, -0.0247, -0.0480, -0.0288, 0.0186, 0.0212, -0.0013, - 0.0403, 0.0598, 0.0690, 0.0516, -0.0298, -0.0177, 0.0278, 0.0168, --0.0106, 0.0251, 0.0386, 0.0331, -0.0052, 0.0133, 0.0291, -0.0158, --0.0329, -0.0367, 0.0287, 0.0462, -0.0176, 0.0049, 0.0242, -0.0034, - 0.0135, 0.0086, -0.0149, 0.0241, 0.0504, 0.0246, -0.0273, -0.0369, --0.0108, -0.0449, -0.0625, -0.0414, -0.0292, -0.0571, -0.0440, -0.0088, - 0.0098, 0.0009, -0.0004, 0.0007, -0.0314, -0.0208, -0.0138, -0.0277, --0.0044, 0.0522, 0.0315, -0.0270, -0.0277, -0.0256, -0.0103, -0.0201, --0.0287, -0.0279, -0.0182, 0.0472, 0.0613, 0.0450, 0.0413, 0.0333, - 0.0444, 0.0223, 0.0061, 0.0316, 0.0321, 0.0501, 0.0460, 0.0250, - 0.0227, 0.0235, 0.0099, 0.0185, -0.0347, -0.0684, -0.0189, 0.0242, --0.0190, -0.0273, -0.0012, -0.0253, 0.0293, -0.0231, -0.0219, -0.0010, - 0.0153, 0.0128, -0.0166, -0.0435, -0.0417, -0.0121, -0.0351, -0.0390, - 0.0077, -0.0278, -0.0355, 0.0092, -0.0063, 0.0005, 0.0216, 0.0461, - 0.0538, 0.0451, 0.0298, -0.0130, 0.0058, 0.0206, 0.0471, 0.0499, - 0.0280, 0.0086, -0.0007, -0.0317, 0.0259, 0.0176, 0.0043, 0.0212, - 0.0138, 0.0106, 0.0220, -0.0025, 0.0050, 0.0122, -0.0051, -0.0086, --0.0472, -0.0005, 0.0193, 0.0032, 0.0246, 0.0222, 0.0090, -0.0320, --0.0713, -0.0526, -0.0151, -0.0440, -0.0648, -0.0466, -0.0092, 0.0115, --0.0129, 0.0053, -0.0344, -0.0385, 0.0392, 0.0599, 0.0414, 0.0165, --0.0098, -0.0320, -0.0261, -0.0055, -0.0139, -0.0110, 0.0084, 0.0172, --0.0492, -0.0537, -0.0320, -0.0036, 0.0265, 0.0385, 0.0064, -0.0280, --0.0230, 0.0134, 0.0241, 0.0106, 0.0387, 0.0105, 0.0068, 0.0260, - 0.4940, 0.4911, 0.4849, 0.4820, 0.4837, 0.4839, 0.4824, 0.4799, - 0.4812, 0.4782, 0.4788, 0.4711, 0.4706, 0.4671, 0.4601, 0.4578, - 0.2954, 0.2121, 0.1859, 0.1958, 0.1474, 0.1086, 0.1351, 0.1362, - 0.1486, 0.1342, 0.1215, 0.1423, 0.1634, 0.1588, 0.1539, 0.1857 -}, - -.lsp16 = { - 0.1813, 0.3911, 0.6301, 0.8012, 1.0057, 1.2041, 1.4271, 1.6943, - 1.9402, 2.1733, 2.3521, 2.4989, 2.5839, 2.6846, 2.7634, 2.8950, - 0.1311, 0.3183, 0.4659, 0.5601, 0.6658, 0.7828, 1.0065, 1.2717, - 1.5185, 1.7339, 1.9530, 2.2189, 2.3739, 2.4991, 2.6984, 2.9256, - 0.1627, 0.4519, 0.6323, 0.7012, 0.7848, 0.9801, 1.1810, 1.3222, - 1.5413, 1.8129, 1.9338, 2.0809, 2.3180, 2.5189, 2.7066, 2.9514, - 0.1475, 0.2447, 0.4240, 0.5669, 0.7872, 0.9838, 1.1823, 1.3814, - 1.5358, 1.6820, 1.8794, 2.1419, 2.4132, 2.6112, 2.7911, 2.9511, - 0.1224, 0.2876, 0.5013, 0.6985, 0.8902, 1.0901, 1.2835, 1.4768, - 1.6596, 1.8538, 2.0467, 2.2304, 2.4124, 2.5942, 2.7729, 2.9531, - 0.1741, 0.3034, 0.4677, 0.5879, 0.7258, 0.9648, 1.1417, 1.3220, - 1.5081, 1.7151, 1.9212, 2.1286, 2.3208, 2.4938, 2.6765, 2.8891, - 0.1657, 0.3174, 0.4907, 0.6559, 0.8295, 1.0254, 1.2071, 1.3880, - 1.5737, 1.7845, 1.9027, 2.1139, 2.3323, 2.5157, 2.7323, 2.9015, - 0.1592, 0.2758, 0.4417, 0.6315, 0.8257, 0.9873, 1.1277, 1.2830, - 1.4337, 1.6315, 1.8899, 2.1356, 2.3572, 2.5632, 2.7468, 2.9420, - 0.1524, 0.4325, 0.5931, 0.7036, 0.7696, 0.8923, 1.1739, 1.4773, - 1.6609, 1.7911, 1.9666, 2.1972, 2.3754, 2.5045, 2.6613, 2.8882, - 0.2130, 0.3013, 0.3721, 0.4257, 0.5079, 0.7015, 0.9815, 1.2554, - 1.4648, 1.6966, 1.9138, 2.1075, 2.3318, 2.5292, 2.7453, 2.9347, - 0.1142, 0.3748, 0.6205, 0.7642, 0.8121, 0.9022, 0.9843, 1.1558, - 1.4467, 1.7422, 1.9574, 2.1302, 2.3812, 2.5898, 2.7720, 2.9583, - 0.1255, 0.2339, 0.3570, 0.5323, 0.7458, 1.0003, 1.1729, 1.3567, - 1.5217, 1.6977, 1.8924, 2.0942, 2.3145, 2.5408, 2.7553, 2.9337, - 0.1316, 0.2289, 0.4327, 0.6663, 0.8509, 0.9994, 1.1697, 1.3804, - 1.5609, 1.6903, 1.8572, 2.1019, 2.3687, 2.5789, 2.7715, 2.9472, - 0.1502, 0.2546, 0.3883, 0.5333, 0.6976, 0.9163, 1.1071, 1.3364, - 1.5420, 1.7525, 1.8948, 2.0839, 2.2819, 2.4651, 2.6875, 2.8987, - 0.1593, 0.3014, 0.4573, 0.6354, 0.8157, 0.9805, 1.1783, 1.3747, - 1.5678, 1.7326, 1.9286, 2.1340, 2.3253, 2.5280, 2.7180, 2.9298, - 0.1811, 0.3167, 0.4655, 0.6507, 0.8198, 1.0075, 1.1892, 1.3743, - 1.5227, 1.7090, 1.8849, 2.0743, 2.2750, 2.4830, 2.6896, 2.8953, - 0.1846, 0.3577, 0.5315, 0.7290, 0.9176, 1.1016, 1.2654, 1.4525, - 1.6315, 1.8268, 2.0238, 2.1934, 2.3868, 2.5753, 2.7682, 2.9469, - 0.0876, 0.1439, 0.2048, 0.3654, 0.6281, 0.8853, 1.0907, 1.2992, - 1.5227, 1.7373, 1.9395, 2.1419, 2.3488, 2.5486, 2.7466, 2.9348, - 0.1391, 0.4170, 0.6561, 0.7953, 0.8734, 0.9986, 1.1870, 1.4520, - 1.6042, 1.7910, 2.0135, 2.1870, 2.3358, 2.5066, 2.7409, 2.9955, - 0.0804, 0.1355, 0.2599, 0.4998, 0.7408, 0.9474, 1.1276, 1.3428, - 1.5556, 1.7712, 1.9699, 2.1535, 2.3605, 2.5548, 2.7489, 2.9325, - 0.1304, 0.3087, 0.4979, 0.6584, 0.8414, 1.0329, 1.2244, 1.4189, - 1.6118, 1.8200, 1.9985, 2.1893, 2.3915, 2.5794, 2.7647, 2.9344, - 0.1895, 0.2849, 0.3705, 0.4126, 0.6265, 0.9207, 1.1774, 1.3762, - 1.5757, 1.7728, 1.9568, 2.1662, 2.3615, 2.5575, 2.7561, 2.9416, - 0.1800, 0.3078, 0.4805, 0.6796, 0.8503, 1.0046, 1.1703, 1.3269, - 1.4862, 1.6502, 1.8454, 2.0873, 2.3175, 2.5356, 2.7516, 2.9469, - 0.1950, 0.3233, 0.4568, 0.5940, 0.7589, 0.9978, 1.1701, 1.3383, - 1.5017, 1.6565, 1.8243, 2.0605, 2.2938, 2.5147, 2.7419, 2.9396, - 0.2531, 0.4391, 0.5790, 0.7170, 0.8998, 1.1430, 1.3577, 1.5326, - 1.6328, 1.7627, 1.9726, 2.1762, 2.3563, 2.5478, 2.7385, 2.9067, - 0.1805, 0.2788, 0.3591, 0.3881, 0.5441, 0.8055, 1.0766, 1.3165, - 1.5316, 1.7508, 1.9477, 2.1374, 2.3438, 2.5484, 2.7501, 2.9410, - 0.2044, 0.3671, 0.5396, 0.7042, 0.8582, 0.9831, 1.1261, 1.3194, - 1.4769, 1.6979, 1.8717, 2.0463, 2.2620, 2.4739, 2.7054, 2.9208, - 0.1048, 0.2175, 0.4206, 0.5923, 0.7483, 0.9400, 1.1356, 1.3799, - 1.5958, 1.7320, 1.8984, 2.1296, 2.3594, 2.5492, 2.7387, 2.9305, - 0.0842, 0.1729, 0.3951, 0.6447, 0.8688, 1.0605, 1.2472, 1.4330, - 1.6232, 1.8144, 2.0216, 2.1915, 2.3878, 2.5763, 2.7685, 2.9464, - 0.1461, 0.2593, 0.4105, 0.5677, 0.7328, 0.8919, 1.0484, 1.2302, - 1.4386, 1.6635, 1.8873, 2.1024, 2.3116, 2.5268, 2.7273, 2.9269, - 0.1503, 0.3108, 0.4756, 0.6731, 0.8600, 1.0233, 1.2115, 1.3971, - 1.5915, 1.7892, 1.9517, 2.1603, 2.3487, 2.5460, 2.7308, 2.8998, - 0.2163, 0.3669, 0.5125, 0.6709, 0.8143, 0.9930, 1.2095, 1.4205, - 1.6176, 1.7112, 1.8398, 2.0896, 2.3513, 2.5290, 2.6667, 2.8960, - 0.2133, 0.4382, 0.6287, 0.8702, 1.1088, 1.3749, 1.6062, 1.7446, - 1.8333, 1.9122, 1.9614, 2.0669, 2.1789, 2.3449, 2.6038, 2.8849, - 0.1598, 0.2719, 0.3877, 0.4815, 0.5926, 0.7795, 1.0449, 1.3045, - 1.5210, 1.7391, 1.9462, 2.1397, 2.3553, 2.5458, 2.7540, 2.9392, - 0.2918, 0.5607, 0.6801, 0.7404, 0.8285, 0.9431, 1.1579, 1.4080, - 1.6332, 1.8472, 1.9738, 2.0771, 2.2890, 2.5178, 2.7445, 2.9830, - 0.1664, 0.2842, 0.3965, 0.5463, 0.8162, 1.0346, 1.1849, 1.3446, - 1.5122, 1.7563, 1.9960, 2.2002, 2.3796, 2.5689, 2.7712, 2.9550, - 0.0911, 0.2397, 0.5052, 0.7868, 1.0299, 1.1311, 1.2244, 1.3333, - 1.4395, 1.6790, 1.9369, 2.1717, 2.3689, 2.5538, 2.7340, 2.9326, - 0.1647, 0.2931, 0.3836, 0.4978, 0.6255, 0.9243, 1.1339, 1.3001, - 1.5269, 1.8010, 1.9715, 2.1419, 2.3784, 2.5503, 2.6719, 2.8745, - 0.2440, 0.3802, 0.4756, 0.6613, 0.8627, 1.0292, 1.2291, 1.4060, - 1.5198, 1.7354, 1.9044, 2.1010, 2.3147, 2.4996, 2.7171, 2.9041, - 0.1590, 0.2876, 0.4572, 0.5996, 0.7713, 0.9490, 1.1205, 1.2815, - 1.4516, 1.6385, 1.8179, 2.0457, 2.2759, 2.4785, 2.6861, 2.9080, - 0.2297, 0.4309, 0.5712, 0.6717, 0.8138, 1.0463, 1.2492, 1.4560, - 1.6796, 1.8458, 1.9642, 2.1452, 2.3636, 2.5395, 2.7456, 2.9495, - 0.2975, 0.4678, 0.4996, 0.5809, 0.6279, 0.6884, 0.8606, 1.1386, - 1.4412, 1.6876, 1.8760, 2.0932, 2.3178, 2.5166, 2.7345, 2.9280, - 0.1278, 0.3737, 0.6004, 0.7069, 0.8147, 1.0180, 1.2581, 1.3812, - 1.4855, 1.7268, 1.9970, 2.1258, 2.2936, 2.5702, 2.7563, 2.8983, - 0.1314, 0.2508, 0.3999, 0.5680, 0.7424, 0.9367, 1.1286, 1.3175, - 1.5336, 1.7404, 1.9317, 2.1404, 2.3514, 2.5562, 2.7510, 2.9402, - 0.1043, 0.2367, 0.4293, 0.6376, 0.8160, 0.9836, 1.1779, 1.3850, - 1.5835, 1.7875, 1.9765, 2.1593, 2.3654, 2.5577, 2.7465, 2.9398, - 0.1529, 0.2515, 0.3454, 0.4374, 0.7011, 0.9015, 1.0744, 1.3532, - 1.5699, 1.7545, 2.0021, 2.1259, 2.2278, 2.4546, 2.7264, 2.9425, - 0.1429, 0.2808, 0.4395, 0.6334, 0.8069, 0.9705, 1.1520, 1.3250, - 1.5109, 1.7285, 1.9356, 2.1469, 2.3479, 2.5554, 2.7512, 2.9348, - 0.1625, 0.3022, 0.4756, 0.6315, 0.8032, 0.9924, 1.1596, 1.3204, - 1.4994, 1.6929, 1.8955, 2.1090, 2.3025, 2.5018, 2.6908, 2.8980, - 0.1692, 0.3427, 0.5228, 0.7756, 0.9688, 1.0950, 1.3056, 1.4360, - 1.5675, 1.8049, 1.9376, 2.1151, 2.3407, 2.5012, 2.7192, 2.9258, - 0.0474, 0.1251, 0.1939, 0.3841, 0.6501, 0.9231, 1.1153, 1.3240, - 1.5478, 1.7599, 1.9651, 2.1510, 2.3645, 2.5552, 2.7542, 2.9393, - 0.2196, 0.4656, 0.7492, 0.9922, 1.1678, 1.2489, 1.3112, 1.3657, - 1.4223, 1.5302, 1.7212, 1.9996, 2.2523, 2.4844, 2.7036, 2.9145, - 0.1128, 0.2368, 0.3704, 0.5476, 0.7723, 0.9968, 1.1930, 1.3992, - 1.6013, 1.7957, 1.9888, 2.1857, 2.3825, 2.5705, 2.7616, 2.9434, - 0.1341, 0.2768, 0.4510, 0.6359, 0.8332, 1.0335, 1.2004, 1.3952, - 1.5762, 1.7681, 1.9815, 2.1735, 2.3657, 2.5552, 2.7514, 2.9498, - 0.1247, 0.2559, 0.3516, 0.4726, 0.6861, 0.9483, 1.1852, 1.3858, - 1.5851, 1.7815, 1.9778, 2.1737, 2.3729, 2.5664, 2.7620, 2.9429, - 0.1988, 0.3320, 0.4777, 0.6737, 0.8425, 1.0265, 1.1694, 1.3655, - 1.5463, 1.7135, 1.9385, 2.1650, 2.3529, 2.5367, 2.7545, 2.9585, - 0.1376, 0.2620, 0.4273, 0.6169, 0.7755, 0.9441, 1.1169, 1.3157, - 1.5179, 1.7020, 1.8931, 2.1059, 2.3112, 2.5136, 2.7169, 2.9198, - 0.2112, 0.4385, 0.6091, 0.7618, 0.9553, 1.1543, 1.3445, 1.5396, - 1.7153, 1.9192, 2.1263, 2.3593, 2.5958, 2.8171, 2.9394, 3.0409, - 0.1347, 0.2099, 0.2646, 0.3453, 0.5266, 0.7869, 1.0513, 1.2795, - 1.4880, 1.7181, 1.9294, 2.1332, 2.3362, 2.5442, 2.7433, 2.9362, - 0.3141, 0.5935, 0.7517, 0.8313, 0.8568, 0.9570, 1.0250, 1.1275, - 1.3422, 1.6303, 1.8577, 2.0705, 2.2957, 2.5095, 2.7244, 2.9262, - 0.0962, 0.2116, 0.3961, 0.5641, 0.7122, 0.8883, 1.1023, 1.3481, - 1.5623, 1.7554, 1.9618, 2.1675, 2.3706, 2.5556, 2.7430, 2.9337, - 0.0898, 0.1510, 0.3060, 0.5820, 0.8221, 1.0388, 1.2261, 1.4289, - 1.6054, 1.8103, 1.9941, 2.1844, 2.3742, 2.5711, 2.7632, 2.9474, - 0.1326, 0.2316, 0.3761, 0.5177, 0.6782, 0.8761, 1.0952, 1.3175, - 1.5078, 1.7034, 1.9051, 2.1245, 2.3424, 2.5484, 2.7444, 2.9389, - 0.1740, 0.3293, 0.5174, 0.6824, 0.8394, 1.0372, 1.2046, 1.3723, - 1.5656, 1.7444, 1.9442, 2.1386, 2.3139, 2.4960, 2.7071, 2.9297, - 0.2304, 0.3775, 0.4865, 0.6182, 0.7842, 0.9208, 1.1151, 1.2843, - 1.4641, 1.6988, 1.9209, 2.1260, 2.3099, 2.5229, 2.7414, 2.9276, - 0.0094, 0.0261, -0.0037, 0.0041, -0.0092, -0.0044, -0.0232, -0.0073, --0.0047, -0.0021, 0.0250, -0.0580, -0.0140, -0.0342, -0.0586, 0.0020, - 0.0449, 0.0155, -0.0523, -0.0279, 0.0299, -0.0183, -0.0736, -0.0639, --0.0017, 0.0336, 0.0209, 0.0046, 0.0077, -0.0148, -0.0114, -0.0120, - 0.0115, -0.0050, 0.0445, 0.0048, 0.0188, -0.0137, -0.0080, 0.0239, --0.0184, -0.0524, -0.0195, -0.0126, 0.0284, 0.0632, 0.0141, -0.0093, --0.0096, 0.0196, 0.0230, 0.0379, 0.0308, 0.0237, -0.0224, -0.0600, --0.0755, -0.1074, -0.0988, -0.0606, -0.1038, -0.1552, -0.1480, -0.0672, - 0.0504, 0.0676, 0.0336, -0.0042, 0.0729, 0.1013, 0.0868, 0.0846, - 0.0954, 0.0515, -0.0066, -0.0851, -0.0485, 0.0294, 0.0395, 0.0087, - 0.0078, 0.0446, 0.0881, 0.0672, -0.0384, -0.0025, 0.0415, 0.0353, - 0.0080, 0.0052, 0.0190, 0.0182, 0.0069, 0.0168, 0.0374, 0.0037, --0.0292, -0.0429, 0.0302, 0.0681, -0.0233, -0.0238, -0.0003, -0.0043, - 0.0054, -0.0029, -0.0149, 0.0642, 0.0622, 0.0341, -0.0232, -0.0461, --0.0082, -0.0469, -0.0618, -0.0326, -0.0452, -0.0649, -0.0597, -0.0398, --0.0318, -0.0116, 0.0011, 0.0009, -0.0384, -0.0384, -0.0156, -0.0260, --0.0007, 0.0473, 0.0111, -0.0358, -0.0484, -0.0204, -0.0029, -0.0090, --0.0285, -0.0495, -0.0376, 0.0917, 0.1192, 0.1026, 0.0745, 0.0397, - 0.0463, 0.0253, 0.0025, 0.0465, 0.0100, 0.0488, 0.0416, 0.0223, - 0.0263, 0.0072, -0.0053, 0.0595, 0.0060, -0.0518, -0.0316, -0.0043, --0.0133, -0.0233, -0.0075, -0.0251, 0.0277, -0.0067, -0.0136, -0.0004, - 0.0235, 0.0112, -0.0182, -0.0324, -0.0210, -0.0035, -0.0395, -0.0384, - 0.0005, -0.0150, -0.0356, 0.0127, -0.0033, -0.0034, 0.0205, 0.0747, - 0.1138, 0.1015, 0.0995, -0.0161, -0.0045, 0.0129, 0.0472, 0.0575, - 0.0222, 0.0091, 0.0037, -0.0471, 0.0371, 0.0132, 0.0208, 0.0247, - 0.0117, 0.0164, 0.0225, 0.0124, -0.0023, 0.0088, -0.0046, 0.0047, --0.0393, 0.0018, 0.0148, 0.0020, 0.0044, 0.0165, 0.0229, -0.0208, --0.0477, -0.0310, -0.0164, -0.0390, -0.0764, -0.0525, -0.0094, 0.0075, --0.0102, -0.0045, -0.0504, -0.0709, 0.0822, 0.0710, 0.0426, 0.0014, --0.0371, -0.0400, -0.0157, -0.0155, -0.0173, -0.0138, -0.0015, 0.0134, --0.0418, -0.0682, -0.0256, 0.0050, 0.0360, 0.0354, 0.0074, -0.0396, --0.0235, 0.0284, 0.0494, 0.0153, 0.0448, 0.0025, -0.0061, 0.0252, - 0.1000, 0.2260, 0.2158, 0.2116, 0.2198, 0.2055, 0.2110, 0.1873, - 0.1907, 0.2071, 0.2164, 0.2009, 0.2059, 0.2124, 0.2141, 0.2093, - 0.0875, 0.0981, 0.1177, 0.1071, 0.1033, 0.1248, 0.1048, 0.1238, - 0.1166, 0.1008, 0.1062, 0.0992, 0.0994, 0.1067, 0.0999, 0.1187, - 0.0750, 0.0794, 0.0828, 0.0854, 0.0859, 0.0801, 0.0891, 0.0933, - 0.0969, 0.0920, 0.0915, 0.0862, 0.0868, 0.0891, 0.0842, 0.0824, - 0.0625, 0.0930, 0.0815, 0.0853, 0.0898, 0.0828, 0.0822, 0.0910, - 0.0873, 0.0906, 0.0856, 0.0840, 0.0774, 0.0785, 0.0684, 0.0711, - 0.3319, 0.4219, 0.4588, 0.4090, 0.4092, 0.4014, 0.3548, 0.3353, - 0.3708, 0.3352, 0.3720, 0.3538, 0.4084, 0.4289, 0.4060, 0.4210, - 0.0588, 0.0209, -0.0082, -0.0115, -0.0343, -0.0621, -0.0541, -0.0346, --0.0346, -0.0366, -0.0220, -0.0265, -0.0102, 0.0374, 0.0306, 0.0404, - 0.0306, 0.0090, -0.0054, 0.0333, 0.0047, 0.0238, 0.0141, 0.0165, - 0.0306, 0.0420, 0.0159, 0.0124, 0.0414, 0.0158, -0.0237, 0.0141, - 0.0765, 0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417 -}, - -.lsp22_1 = { - 0.0664, 0.1875, 0.4300, 0.6730, 0.8793, 1.0640, 1.2563, 1.4433, - 1.6394, 1.8176, 2.0029, 2.1921, 2.3796, 2.5671, 2.7595, 2.9536, - 0.2128, 0.4052, 0.5311, 0.6404, 0.7875, 0.8775, 1.0974, 1.3261, - 1.5563, 1.6790, 1.8339, 2.1195, 2.3226, 2.4609, 2.6440, 2.8947, - 0.2024, 0.3362, 0.4834, 0.6784, 0.9088, 1.0850, 1.2188, 1.4054, - 1.6102, 1.7767, 1.9679, 2.1436, 2.3445, 2.5467, 2.7429, 2.9320, - 0.1181, 0.2279, 0.4413, 0.6114, 0.7710, 0.9427, 1.1142, 1.2707, - 1.4892, 1.7416, 1.9526, 2.1466, 2.3629, 2.5445, 2.7293, 2.9205, - 0.1155, 0.2720, 0.4886, 0.6812, 0.8594, 1.0422, 1.2315, 1.4116, - 1.6137, 1.8020, 1.9758, 2.1743, 2.3602, 2.5568, 2.7472, 2.9374, - 0.1110, 0.3312, 0.4735, 0.5612, 0.7129, 0.8146, 1.0233, 1.3155, - 1.5765, 1.7746, 1.9574, 2.1416, 2.3220, 2.5384, 2.7334, 2.9318, - 0.1656, 0.3350, 0.4215, 0.5609, 0.6759, 0.8503, 1.1405, 1.4094, - 1.6057, 1.6860, 1.7639, 2.0031, 2.2680, 2.5076, 2.7263, 2.9368, - 0.1466, 0.3638, 0.4587, 0.5674, 0.7381, 0.8669, 0.9619, 1.1658, - 1.4667, 1.7440, 1.9335, 2.1018, 2.3022, 2.5281, 2.7359, 2.9261, - 0.1061, 0.2566, 0.4739, 0.6751, 0.8711, 1.0704, 1.2720, 1.4655, - 1.6605, 1.8494, 2.0290, 2.2197, 2.4008, 2.5912, 2.7772, 2.9513, - 0.1116, 0.2364, 0.3971, 0.6316, 0.8583, 1.0335, 1.1686, 1.3302, - 1.5612, 1.7877, 1.9829, 2.2052, 2.3596, 2.5460, 2.7341, 2.9290, - 0.2661, 0.4186, 0.5126, 0.6477, 0.8818, 1.1045, 1.2852, 1.4128, - 1.5851, 1.7593, 1.9399, 2.1757, 2.3684, 2.5136, 2.6927, 2.9064, - 0.1495, 0.2749, 0.4391, 0.6304, 0.8239, 1.0181, 1.1995, 1.3759, - 1.5669, 1.7722, 1.9671, 2.1635, 2.3586, 2.5528, 2.7445, 2.9311, - 0.0912, 0.1759, 0.3066, 0.5660, 0.8005, 0.9568, 1.1832, 1.4504, - 1.6259, 1.7948, 2.0113, 2.2002, 2.3654, 2.5583, 2.7929, 2.9735, - 0.1353, 0.2747, 0.4078, 0.5977, 0.7658, 0.9124, 1.1081, 1.3630, - 1.5875, 1.7847, 1.9323, 2.1181, 2.3321, 2.5046, 2.7183, 2.9225, - 0.1938, 0.4063, 0.4982, 0.6002, 0.7702, 0.9071, 1.1631, 1.3885, - 1.6043, 1.8118, 1.9306, 2.0893, 2.2724, 2.4609, 2.6283, 2.8802, - 0.1857, 0.3351, 0.4381, 0.6101, 0.7561, 0.8555, 1.0384, 1.3171, - 1.5667, 1.6904, 1.7552, 1.9689, 2.2597, 2.5260, 2.7272, 2.9337, - 0.1037, 0.2159, 0.4188, 0.6174, 0.8035, 1.0285, 1.2256, 1.4230, - 1.6400, 1.8322, 2.0144, 2.1988, 2.3810, 2.5682, 2.7613, 2.9438, - 0.1625, 0.2776, 0.4225, 0.6001, 0.7879, 0.9087, 1.0801, 1.2759, - 1.4899, 1.7448, 1.9911, 2.1770, 2.3723, 2.5777, 2.7971, 2.9444, - 0.2111, 0.3640, 0.5839, 0.7290, 0.8051, 1.0023, 1.2315, 1.4143, - 1.5878, 1.7755, 1.9804, 2.1498, 2.3312, 2.5350, 2.7613, 2.9472, - 0.1423, 0.2646, 0.4136, 0.6350, 0.8070, 0.9514, 1.1168, 1.3213, - 1.5776, 1.7721, 1.9404, 2.1545, 2.3385, 2.5137, 2.7396, 2.9553, - 0.1132, 0.2386, 0.4103, 0.5931, 0.7808, 0.9881, 1.1840, 1.3860, - 1.6021, 1.7990, 1.9922, 2.1885, 2.3852, 2.5717, 2.7640, 2.9510, - 0.1267, 0.2602, 0.3913, 0.5944, 0.7598, 0.9198, 1.0781, 1.2715, - 1.5299, 1.7573, 1.9308, 2.1346, 2.3267, 2.5419, 2.7466, 2.9320, - 0.2023, 0.3417, 0.4392, 0.6141, 0.7439, 0.8593, 1.1096, 1.3543, - 1.5185, 1.6553, 1.7862, 2.0341, 2.2718, 2.4834, 2.7103, 2.9466, - 0.1113, 0.2470, 0.3677, 0.5686, 0.7700, 0.9356, 1.0806, 1.2452, - 1.4830, 1.7344, 1.9268, 2.1404, 2.3371, 2.5169, 2.7329, 2.9012, - 0.1664, 0.3554, 0.5573, 0.7471, 0.9245, 1.0998, 1.2787, 1.4655, - 1.6654, 1.8346, 2.0179, 2.2159, 2.4096, 2.5946, 2.7790, 2.9530, - 0.1313, 0.2625, 0.4731, 0.6444, 0.8110, 0.9878, 1.1493, 1.3212, - 1.5719, 1.8138, 1.9861, 2.1943, 2.3714, 2.5578, 2.7346, 2.9296, - 0.1186, 0.3035, 0.5049, 0.6860, 0.8670, 0.9975, 1.1364, 1.3471, - 1.5695, 1.7412, 1.9346, 2.1506, 2.3413, 2.5531, 2.7794, 2.9627, - 0.1108, 0.2697, 0.4787, 0.6344, 0.7909, 0.9586, 1.1440, 1.3511, - 1.5686, 1.7601, 1.9246, 2.1241, 2.3293, 2.5390, 2.7315, 2.9333, - 0.0985, 0.2302, 0.3544, 0.5759, 0.7620, 0.9651, 1.1497, 1.3080, - 1.5500, 1.7845, 1.9518, 2.1734, 2.3565, 2.5665, 2.7605, 2.9102, - 0.1208, 0.2727, 0.4381, 0.5736, 0.7382, 0.8390, 1.0102, 1.2648, - 1.5100, 1.7440, 1.9619, 2.1430, 2.3307, 2.5159, 2.7264, 2.9211, - 0.1582, 0.2777, 0.4475, 0.6551, 0.8591, 1.0084, 1.1414, 1.3291, - 1.5902, 1.7826, 1.9543, 2.1659, 2.3233, 2.5044, 2.6935, 2.9199, - 0.1360, 0.2873, 0.4585, 0.6295, 0.7592, 0.9089, 1.0492, 1.2733, - 1.5391, 1.7768, 1.9372, 2.1329, 2.3168, 2.5015, 2.6857, 2.8837, - 0.0886, 0.1829, 0.3696, 0.6126, 0.8334, 1.0135, 1.2303, 1.4674, - 1.6743, 1.8564, 2.0530, 2.2370, 2.3960, 2.5787, 2.7756, 2.9377, - 0.2005, 0.3537, 0.4700, 0.6249, 0.7385, 0.9097, 1.1759, 1.3811, - 1.5314, 1.6705, 1.8546, 2.1229, 2.3292, 2.5251, 2.7951, 2.9646, - 0.1999, 0.3112, 0.4722, 0.7146, 0.8908, 1.0028, 1.1831, 1.3903, - 1.6125, 1.7514, 1.9083, 2.1248, 2.3271, 2.5339, 2.6945, 2.8918, - 0.1243, 0.2606, 0.4382, 0.5850, 0.7705, 0.9727, 1.1214, 1.3059, - 1.5218, 1.7406, 1.9137, 2.1353, 2.3354, 2.5299, 2.7287, 2.9068, - 0.1039, 0.2426, 0.4265, 0.6284, 0.8152, 0.9941, 1.2004, 1.4038, - 1.5912, 1.7763, 1.9650, 2.1598, 2.3474, 2.5488, 2.7419, 2.9322, - 0.1364, 0.2420, 0.3886, 0.5864, 0.7663, 0.8844, 1.0860, 1.3242, - 1.5518, 1.7893, 2.0004, 2.1562, 2.3619, 2.5516, 2.7687, 2.9181, - 0.1483, 0.2851, 0.4479, 0.6312, 0.7924, 0.9821, 1.1705, 1.3386, - 1.5375, 1.7226, 1.9053, 2.0991, 2.2898, 2.4953, 2.7000, 2.9146, - 0.2332, 0.4561, 0.5407, 0.6212, 0.7524, 0.8215, 0.9522, 1.1685, - 1.5216, 1.7132, 1.8291, 2.0647, 2.2811, 2.4857, 2.7071, 2.9281, - 0.1348, 0.3126, 0.5179, 0.7192, 0.9227, 1.1363, 1.3223, 1.4756, - 1.6509, 1.8191, 1.9991, 2.1976, 2.3877, 2.5768, 2.7590, 2.9386, - 0.1093, 0.2211, 0.4763, 0.6703, 0.8282, 0.9536, 1.1202, 1.3796, - 1.6043, 1.8031, 1.9832, 2.1604, 2.3578, 2.5856, 2.7650, 2.9291, - 0.1865, 0.3027, 0.4580, 0.6719, 0.8400, 1.0082, 1.1901, 1.3782, - 1.5448, 1.6885, 1.9477, 2.1381, 2.2797, 2.5113, 2.7465, 2.9414, - 0.1575, 0.3124, 0.4649, 0.6262, 0.8095, 0.9858, 1.1676, 1.3602, - 1.5646, 1.7582, 1.9550, 2.1671, 2.3628, 2.5734, 2.7670, 2.9519, - 0.1174, 0.2777, 0.4663, 0.6333, 0.8169, 1.0096, 1.1885, 1.3847, - 1.5803, 1.7571, 1.9380, 2.1398, 2.3414, 2.5407, 2.7360, 2.9375, - 0.1073, 0.2264, 0.4083, 0.5973, 0.7474, 0.9514, 1.1349, 1.3337, - 1.5433, 1.7348, 1.9380, 2.1436, 2.3441, 2.5438, 2.7457, 2.9383, - 0.1472, 0.2880, 0.4793, 0.6268, 0.8015, 1.0063, 1.1715, 1.3644, - 1.5525, 1.7410, 1.9258, 2.1227, 2.3214, 2.5149, 2.7148, 2.9196, - 0.1414, 0.2565, 0.4349, 0.6111, 0.7695, 0.9496, 1.1212, 1.3265, - 1.5218, 1.7209, 1.9015, 2.0887, 2.3158, 2.5077, 2.7233, 2.9421, - 0.1252, 0.2667, 0.4454, 0.6431, 0.8371, 1.0124, 1.2110, 1.4160, - 1.6240, 1.8242, 2.0047, 2.1974, 2.3902, 2.5778, 2.7637, 2.9481, - 0.1321, 0.2565, 0.3846, 0.5847, 0.7578, 0.9259, 1.0637, 1.2239, - 1.4690, 1.7346, 1.9750, 2.1882, 2.3712, 2.5509, 2.7280, 2.8885, - 0.1437, 0.2930, 0.4428, 0.6156, 0.8045, 0.9638, 1.1450, 1.3138, - 1.5144, 1.7355, 1.9469, 2.1534, 2.3414, 2.5452, 2.7353, 2.9334, - 0.1692, 0.2770, 0.3831, 0.6100, 0.7825, 0.9302, 1.0690, 1.2481, - 1.4615, 1.6799, 1.9165, 2.1739, 2.3435, 2.5349, 2.7520, 2.9163, - 0.1235, 0.2489, 0.4354, 0.6343, 0.8236, 1.0066, 1.1908, 1.3474, - 1.5656, 1.8275, 2.0620, 2.2548, 2.4135, 2.5913, 2.7639, 2.9334, - 0.1090, 0.1961, 0.3854, 0.5701, 0.7024, 0.8843, 1.1393, 1.3785, - 1.5940, 1.7797, 1.9442, 2.1740, 2.3853, 2.5773, 2.7727, 2.9406, - 0.1560, 0.3477, 0.5011, 0.6287, 0.7612, 0.9896, 1.1510, 1.3420, - 1.5435, 1.6816, 1.8731, 2.0651, 2.2613, 2.4999, 2.7027, 2.8971, - 0.1459, 0.2416, 0.3833, 0.5450, 0.7916, 0.9223, 1.0662, 1.1953, - 1.4029, 1.6616, 1.9320, 2.1459, 2.3386, 2.5081, 2.6799, 2.9195, - 0.1546, 0.3854, 0.6184, 0.8460, 1.0599, 1.2428, 1.3906, 1.5550, - 1.7388, 1.8945, 2.0757, 2.2386, 2.4014, 2.5705, 2.7574, 2.9400, - 0.1080, 0.2307, 0.4112, 0.6067, 0.7725, 0.9467, 1.1285, 1.3205, - 1.5348, 1.7609, 1.9937, 2.1878, 2.3583, 2.5515, 2.7199, 2.9049, - 0.1482, 0.3178, 0.4983, 0.6342, 0.7783, 0.9880, 1.2019, 1.3404, - 1.5223, 1.7296, 1.9211, 2.0943, 2.2928, 2.5008, 2.7136, 2.9224, - 0.1145, 0.2910, 0.4891, 0.6492, 0.8126, 0.9530, 1.1180, 1.3155, - 1.5054, 1.6893, 1.8899, 2.1188, 2.3389, 2.5512, 2.7313, 2.9224, - 0.0939, 0.1689, 0.3250, 0.5792, 0.7698, 0.9245, 1.1574, 1.3865, - 1.5959, 1.7977, 1.9821, 2.1528, 2.3326, 2.5540, 2.7553, 2.9179, - 0.1243, 0.2474, 0.3923, 0.6199, 0.7908, 0.9379, 1.1497, 1.3734, - 1.5582, 1.7420, 1.9539, 2.1385, 2.3240, 2.5277, 2.7311, 2.9178, - 0.1961, 0.3748, 0.5176, 0.6387, 0.8169, 1.0477, 1.2124, 1.3869, - 1.5604, 1.7225, 1.8770, 2.0837, 2.2960, 2.5103, 2.6945, 2.8862, - 0.1295, 0.2403, 0.4149, 0.6189, 0.7913, 0.9130, 1.0832, 1.2787, - 1.4860, 1.7112, 1.9502, 2.1348, 2.2776, 2.4982, 2.7431, 2.9522, - 0.0160, 0.0362, 0.0097, 0.0057, -0.0014, -0.0073, -0.0046, -0.0064, --0.0121, 0.0019, 0.0149, -0.0440, -0.0479, -0.0382, -0.0480, -0.0182, - 0.0170, 0.0114, -0.0298, -0.0175, -0.0033, -0.0354, -0.0510, -0.0025, - 0.0307, 0.0351, 0.0338, 0.0420, 0.0138, -0.0175, -0.0102, 0.0053, - 0.0084, -0.0003, 0.0412, -0.0027, 0.0145, -0.0039, 0.0083, 0.0400, - 0.0001, -0.0262, 0.0055, -0.0082, 0.0348, 0.0433, 0.0137, -0.0024, --0.0055, 0.0262, 0.0521, 0.0349, 0.0185, 0.0076, -0.0319, -0.0561, --0.0460, -0.0253, -0.0097, 0.0163, 0.0184, -0.0037, -0.0480, -0.0371, - 0.0628, 0.0665, 0.0296, -0.0057, 0.0253, 0.0227, 0.0350, 0.0692, - 0.0545, 0.0218, 0.0094, -0.0449, -0.0372, 0.0005, 0.0258, 0.0118, - 0.0285, 0.0760, 0.0822, 0.0527, -0.0299, -0.0049, 0.0170, 0.0195, - 0.0136, 0.0286, 0.0289, 0.0139, 0.0054, 0.0152, 0.0244, 0.0028, --0.0056, -0.0260, 0.0307, 0.0572, -0.0087, 0.0088, 0.0062, 0.0000, - 0.0125, 0.0000, -0.0292, 0.0820, 0.0872, 0.0646, 0.0346, 0.0076, --0.0022, -0.0253, -0.0567, -0.0188, -0.0336, -0.0673, -0.0549, -0.0166, --0.0259, -0.0140, 0.0040, -0.0029, -0.0430, -0.0531, -0.0253, -0.0019, --0.0071, 0.0393, 0.0072, -0.0327, -0.0236, -0.0235, -0.0177, -0.0186, --0.0280, -0.0201, -0.0077, 0.0383, 0.0418, 0.0321, 0.0294, 0.0169, - 0.0468, 0.0301, 0.0133, 0.0363, 0.0516, 0.0937, 0.1240, 0.1404, - 0.1325, 0.1178, 0.0999, 0.0251, -0.0037, -0.0495, -0.0703, -0.0219, --0.0261, -0.0304, -0.0204, -0.0372, 0.0355, 0.0131, -0.0093, -0.0099, --0.0069, -0.0034, -0.0065, -0.0208, -0.0231, -0.0117, -0.0211, -0.0243, - 0.0046, -0.0107, -0.0070, 0.0123, 0.0230, 0.0152, 0.0164, 0.0412, - 0.0619, 0.0858, 0.0862, -0.0056, 0.0125, 0.0182, 0.0347, 0.0388, - 0.0456, 0.0407, -0.0249, -0.0460, 0.0206, 0.0299, 0.0253, 0.0207, - 0.0177, 0.0238, 0.0253, 0.0030, 0.0042, 0.0020, -0.0081, -0.0136, --0.0290, -0.0042, 0.0122, 0.0051, 0.0107, 0.0228, 0.0211, -0.0068, --0.0436, -0.0299, -0.0078, -0.0779, -0.1157, -0.0679, 0.0172, 0.0150, --0.0051, 0.0081, -0.0512, -0.0616, 0.0576, 0.0799, 0.0803, 0.0336, - 0.0001, -0.0298, -0.0747, -0.0115, -0.0101, -0.0170, -0.0050, 0.0174, --0.0290, -0.0601, -0.0150, 0.0121, 0.0165, 0.0230, 0.0028, -0.0317, --0.0165, 0.0356, 0.0451, 0.0120, 0.0321, 0.0084, -0.0058, 0.0122, - 0.1935, 0.1802, 0.2195, 0.2410, 0.2201, 0.1915, 0.1840, 0.1935, - 0.2213, 0.2079, 0.1858, 0.1974, 0.2239, 0.2173, 0.1840, 0.2120, - 0.4912, 0.4777, 0.4607, 0.4395, 0.4426, 0.4388, 0.4416, 0.4345, - 0.4239, 0.4331, 0.4522, 0.4423, 0.4475, 0.4387, 0.4525, 0.4446 -}, - -.lsp22_2 = { - 0.0712, 0.1830, 0.4167, 0.6669, 0.8738, 1.0696, 1.2555, 1.4426, - 1.6427, 1.8138, 1.9966, 2.1925, 2.3872, 2.5748, 2.7713, 2.9597, - 0.1894, 0.3942, 0.5418, 0.6747, 0.7517, 0.8763, 1.1189, 1.3072, - 1.5011, 1.6790, 1.8342, 2.0781, 2.2929, 2.4566, 2.6613, 2.9204, - 0.1767, 0.3403, 0.5173, 0.7055, 0.8899, 1.0696, 1.2302, 1.4111, - 1.5989, 1.7751, 1.9618, 2.1544, 2.3454, 2.5356, 2.7362, 2.9315, - 0.1240, 0.2361, 0.4423, 0.6326, 0.7729, 0.9387, 1.1142, 1.2847, - 1.4746, 1.7126, 1.9482, 2.1642, 2.3536, 2.5506, 2.7593, 2.9197, - 0.1213, 0.2782, 0.5011, 0.6910, 0.8564, 1.0462, 1.2315, 1.4232, - 1.6178, 1.8028, 1.9813, 2.1766, 2.3670, 2.5591, 2.7475, 2.9403, - 0.1382, 0.2995, 0.4693, 0.5874, 0.6929, 0.8102, 1.0094, 1.2960, - 1.5511, 1.7607, 1.9699, 2.1680, 2.3367, 2.5459, 2.7370, 2.9105, - 0.1428, 0.2690, 0.3713, 0.4757, 0.6664, 0.9019, 1.1276, 1.3674, - 1.5471, 1.6695, 1.8261, 2.0572, 2.2753, 2.4963, 2.7187, 2.9114, - 0.1669, 0.3085, 0.4489, 0.5724, 0.6934, 0.8465, 0.9680, 1.1641, - 1.4320, 1.6841, 1.8977, 2.1061, 2.3118, 2.5152, 2.7329, 2.9274, - 0.1128, 0.2709, 0.4803, 0.6878, 0.8673, 1.0693, 1.2749, 1.4657, - 1.6650, 1.8434, 2.0339, 2.2300, 2.4003, 2.5951, 2.7762, 2.9465, - 0.1201, 0.2345, 0.4021, 0.6379, 0.8651, 1.0256, 1.1630, 1.3250, - 1.5395, 1.7808, 2.0011, 2.1997, 2.3618, 2.5505, 2.7561, 2.9351, - 0.2575, 0.4163, 0.5081, 0.6484, 0.8570, 1.0832, 1.2732, 1.3933, - 1.5497, 1.7725, 1.9945, 2.2098, 2.3514, 2.5216, 2.7146, 2.8969, - 0.1367, 0.2656, 0.4470, 0.6398, 0.8146, 1.0125, 1.2142, 1.3960, - 1.5558, 1.7338, 1.9465, 2.1769, 2.4031, 2.5746, 2.7335, 2.9046, - 0.0868, 0.1723, 0.2785, 0.5071, 0.7732, 1.0024, 1.1924, 1.4220, - 1.6149, 1.8064, 1.9951, 2.1935, 2.3777, 2.5748, 2.7661, 2.9488, - 0.1428, 0.2592, 0.3875, 0.5810, 0.7513, 0.9334, 1.1096, 1.3565, - 1.5869, 1.7788, 1.9036, 2.0893, 2.3332, 2.5289, 2.7204, 2.9053, - 0.2313, 0.4066, 0.4960, 0.5853, 0.7799, 0.9201, 1.1365, 1.3499, - 1.5119, 1.7641, 1.9095, 2.0911, 2.2653, 2.4587, 2.7010, 2.8900, - 0.1927, 0.3424, 0.4682, 0.6035, 0.7330, 0.8492, 1.0477, 1.3083, - 1.5602, 1.6945, 1.7806, 2.0066, 2.2566, 2.4864, 2.7021, 2.9180, - 0.0962, 0.1933, 0.3968, 0.6077, 0.8083, 1.0224, 1.2307, 1.4344, - 1.6350, 1.8173, 2.0024, 2.1894, 2.3812, 2.5648, 2.7535, 2.9483, - 0.1469, 0.2679, 0.4272, 0.6080, 0.7949, 0.9247, 1.0741, 1.2722, - 1.5144, 1.7679, 2.0030, 2.1944, 2.3890, 2.5928, 2.8116, 2.9555, - 0.1618, 0.3917, 0.6111, 0.7511, 0.8325, 1.0010, 1.2397, 1.4147, - 1.5764, 1.7359, 1.9300, 2.1325, 2.3096, 2.5480, 2.7725, 2.9697, - 0.1561, 0.2634, 0.4062, 0.6139, 0.8059, 0.9618, 1.0948, 1.3179, - 1.5846, 1.7622, 1.9399, 2.1476, 2.3330, 2.5232, 2.7412, 2.9554, - 0.1076, 0.2320, 0.3977, 0.5798, 0.7707, 0.9975, 1.1884, 1.3793, - 1.6059, 1.8038, 1.9928, 2.1942, 2.3881, 2.5742, 2.7717, 2.9547, - 0.1360, 0.2493, 0.3827, 0.5644, 0.7384, 0.9087, 1.0865, 1.2902, - 1.5185, 1.7246, 1.9170, 2.1175, 2.3324, 2.5442, 2.7441, 2.9437, - 0.1684, 0.2990, 0.4406, 0.5834, 0.7305, 0.9028, 1.0801, 1.2756, - 1.4646, 1.6514, 1.8346, 2.0493, 2.2594, 2.4765, 2.6985, 2.9089, - 0.1145, 0.2295, 0.3421, 0.5032, 0.7007, 0.9057, 1.0830, 1.2733, - 1.4885, 1.6897, 1.8933, 2.1128, 2.3188, 2.5271, 2.7284, 2.9266, - 0.1705, 0.3815, 0.6120, 0.7964, 0.9342, 1.0926, 1.2741, 1.4645, - 1.6552, 1.8040, 1.9778, 2.1931, 2.3836, 2.5827, 2.7905, 2.9494, - 0.1284, 0.2622, 0.4714, 0.6559, 0.8004, 1.0005, 1.1416, 1.3163, - 1.5773, 1.8144, 1.9947, 2.2001, 2.3836, 2.5710, 2.7447, 2.9262, - 0.1164, 0.2882, 0.5349, 0.7310, 0.8483, 0.9729, 1.1331, 1.3350, - 1.5307, 1.7306, 1.9409, 2.1275, 2.3229, 2.5358, 2.7455, 2.9447, - 0.1159, 0.2646, 0.4677, 0.6375, 0.7771, 0.9557, 1.1398, 1.3514, - 1.5717, 1.7512, 1.9337, 2.1323, 2.3272, 2.5409, 2.7377, 2.9212, - 0.1080, 0.2143, 0.3475, 0.5307, 0.7358, 0.9681, 1.1489, 1.3289, - 1.5553, 1.7664, 1.9696, 2.1780, 2.3676, 2.5568, 2.7493, 2.9347, - 0.1331, 0.2430, 0.3879, 0.5092, 0.6324, 0.8119, 1.0327, 1.2657, - 1.4999, 1.7107, 1.9178, 2.1272, 2.3296, 2.5340, 2.7372, 2.9353, - 0.1557, 0.2873, 0.4558, 0.6548, 0.8472, 1.0106, 1.1480, 1.3281, - 1.5856, 1.7740, 1.9564, 2.1651, 2.3295, 2.5207, 2.7005, 2.9151, - 0.1397, 0.2761, 0.4533, 0.6374, 0.7510, 0.8767, 1.0408, 1.2909, - 1.5368, 1.7560, 1.9424, 2.1332, 2.3210, 2.5116, 2.6924, 2.8886, - 0.0945, 0.1653, 0.3601, 0.6129, 0.8378, 1.0333, 1.2417, 1.4539, - 1.6507, 1.8304, 2.0286, 2.2157, 2.3975, 2.5865, 2.7721, 2.9426, - 0.1892, 0.3863, 0.4896, 0.5909, 0.7294, 0.9483, 1.1575, 1.3542, - 1.4796, 1.6535, 1.9070, 2.1435, 2.3281, 2.4967, 2.7039, 2.9222, - 0.1614, 0.3129, 0.5086, 0.7048, 0.8730, 1.0239, 1.1905, 1.3799, - 1.5697, 1.7503, 1.9103, 2.1115, 2.3235, 2.5234, 2.6973, 2.8957, - 0.1199, 0.2590, 0.4273, 0.5935, 0.7542, 0.9625, 1.1225, 1.2998, - 1.5361, 1.7102, 1.9097, 2.1269, 2.3157, 2.5304, 2.7212, 2.9175, - 0.1087, 0.2373, 0.4261, 0.6277, 0.8092, 0.9884, 1.1954, 1.4077, - 1.6048, 1.7799, 1.9693, 2.1662, 2.3426, 2.5501, 2.7459, 2.9257, - 0.1262, 0.2216, 0.3857, 0.5799, 0.7148, 0.8610, 1.0752, 1.3306, - 1.5549, 1.7605, 1.9727, 2.1580, 2.3612, 2.5602, 2.7554, 2.9372, - 0.1445, 0.2832, 0.4469, 0.6283, 0.7991, 0.9796, 1.1504, 1.3323, - 1.5313, 1.7140, 1.8968, 2.0990, 2.2826, 2.4903, 2.7003, 2.9031, - 0.1647, 0.4068, 0.5428, 0.6539, 0.7682, 0.8479, 0.9372, 1.1691, - 1.4776, 1.7314, 1.9071, 2.0918, 2.2774, 2.5029, 2.7152, 2.9221, - 0.1274, 0.3052, 0.5238, 0.7280, 0.9229, 1.1211, 1.3071, 1.4784, - 1.6564, 1.8235, 2.0028, 2.1999, 2.3763, 2.5608, 2.7510, 2.9356, - 0.1076, 0.2195, 0.4815, 0.6873, 0.8241, 0.9443, 1.1066, 1.3687, - 1.6087, 1.8105, 1.9857, 2.1486, 2.3505, 2.5854, 2.7785, 2.9376, - 0.1755, 0.3089, 0.4695, 0.6648, 0.8315, 1.0202, 1.1774, 1.3554, - 1.5393, 1.7141, 1.9247, 2.1284, 2.2983, 2.4975, 2.7296, 2.9401, - 0.1636, 0.3166, 0.4594, 0.6199, 0.8161, 0.9879, 1.1738, 1.3642, - 1.5680, 1.7633, 1.9598, 2.1695, 2.3692, 2.5846, 2.7809, 2.9563, - 0.1219, 0.2662, 0.4620, 0.6491, 0.8353, 1.0150, 1.2065, 1.3944, - 1.5785, 1.7631, 1.9389, 2.1434, 2.3400, 2.5316, 2.7359, 2.9513, - 0.1072, 0.2258, 0.3968, 0.5642, 0.7222, 0.9367, 1.1458, 1.3347, - 1.5424, 1.7373, 1.9303, 2.1432, 2.3451, 2.5415, 2.7444, 2.9394, - 0.1393, 0.2950, 0.4724, 0.6407, 0.8034, 1.0031, 1.1712, 1.3552, - 1.5519, 1.7411, 1.9198, 2.1160, 2.3238, 2.5119, 2.7134, 2.9205, - 0.1358, 0.2613, 0.4239, 0.5991, 0.7643, 0.9379, 1.1213, 1.3115, - 1.5067, 1.7031, 1.8768, 2.0836, 2.3092, 2.5134, 2.7237, 2.9286, - 0.1267, 0.2695, 0.4524, 0.6591, 0.8396, 1.0173, 1.2183, 1.4205, - 1.6306, 1.8162, 2.0106, 2.2082, 2.3773, 2.5787, 2.7551, 2.9387, - 0.1314, 0.2529, 0.3837, 0.5494, 0.7446, 0.9097, 1.0489, 1.2385, - 1.4691, 1.7170, 1.9600, 2.1770, 2.3594, 2.5356, 2.7215, 2.9088, - 0.1538, 0.2931, 0.4449, 0.6041, 0.7959, 0.9666, 1.1355, 1.3214, - 1.5150, 1.7230, 1.9433, 2.1408, 2.3459, 2.5476, 2.7273, 2.9330, - 0.1771, 0.2834, 0.4136, 0.5856, 0.7516, 0.9363, 1.0596, 1.2462, - 1.4737, 1.6627, 1.8810, 2.1150, 2.3202, 2.5274, 2.7403, 2.9490, - 0.1248, 0.2494, 0.4397, 0.6352, 0.8226, 1.0015, 1.1799, 1.3458, - 1.5654, 1.8228, 2.0646, 2.2550, 2.4161, 2.5964, 2.7675, 2.9383, - 0.0933, 0.1993, 0.3105, 0.4371, 0.6417, 0.8935, 1.1244, 1.3508, - 1.5649, 1.7595, 1.9581, 2.1648, 2.3639, 2.5569, 2.7573, 2.9468, - 0.1794, 0.3229, 0.4758, 0.6238, 0.7821, 0.9640, 1.1205, 1.3116, - 1.5054, 1.6803, 1.8658, 2.0651, 2.2793, 2.4856, 2.6867, 2.9105, - 0.1252, 0.2397, 0.3844, 0.5398, 0.7044, 0.8799, 1.0526, 1.2270, - 1.4269, 1.6412, 1.8532, 2.0784, 2.2957, 2.5051, 2.7139, 2.9210, - 0.1391, 0.3494, 0.5738, 0.8024, 1.0098, 1.2094, 1.3830, 1.5509, - 1.7222, 1.8782, 2.0604, 2.2479, 2.4154, 2.5968, 2.7767, 2.9450, - 0.1122, 0.2180, 0.4175, 0.6074, 0.7559, 0.9465, 1.1513, 1.3340, - 1.5215, 1.7491, 1.9911, 2.1894, 2.3433, 2.5377, 2.7380, 2.9183, - 0.1595, 0.3029, 0.4842, 0.6324, 0.7874, 0.9814, 1.1992, 1.3554, - 1.5017, 1.7274, 1.9168, 2.0853, 2.2964, 2.5300, 2.7187, 2.9041, - 0.1350, 0.2747, 0.4791, 0.6638, 0.8050, 0.9644, 1.1238, 1.2987, - 1.4844, 1.6754, 1.8778, 2.0987, 2.3279, 2.5424, 2.7410, 2.9356, - 0.0914, 0.1727, 0.3143, 0.5124, 0.7123, 0.9323, 1.1706, 1.3821, - 1.5864, 1.7828, 1.9701, 2.1560, 2.3445, 2.5486, 2.7433, 2.9372, - 0.1222, 0.2359, 0.3931, 0.5912, 0.7776, 0.9505, 1.1623, 1.3723, - 1.5484, 1.7316, 1.9321, 2.1283, 2.3148, 2.5269, 2.7299, 2.9213, - 0.2089, 0.3872, 0.5090, 0.6413, 0.7967, 1.0226, 1.1897, 1.3908, - 1.5954, 1.7202, 1.8614, 2.1030, 2.2973, 2.5079, 2.7491, 2.8944, - 0.1288, 0.2423, 0.4108, 0.6062, 0.7688, 0.9188, 1.0876, 1.2866, - 1.4897, 1.6910, 1.9219, 2.1076, 2.2805, 2.5023, 2.7155, 2.9203, - 0.0192, 0.0462, 0.0128, 0.0054, -0.0156, -0.0118, -0.0135, 0.0030, --0.0120, 0.0031, 0.0240, -0.0451, -0.0439, -0.0432, -0.0527, -0.0207, - 0.0253, 0.0084, -0.0305, -0.0144, 0.0046, -0.0378, -0.0467, -0.0102, - 0.0280, 0.0540, 0.0151, 0.0437, 0.0141, -0.0257, -0.0058, 0.0073, - 0.0107, 0.0054, 0.0371, -0.0105, 0.0165, -0.0143, 0.0148, 0.0382, --0.0054, -0.0284, 0.0001, -0.0218, 0.0258, 0.0517, 0.0157, -0.0032, --0.0190, 0.0343, 0.0576, 0.0346, 0.0392, -0.0158, -0.0323, -0.0578, --0.0617, -0.0242, -0.0144, 0.0188, 0.0249, 0.0021, -0.0422, -0.0420, - 0.0750, 0.0762, 0.0325, -0.0066, 0.0332, 0.0376, 0.0388, 0.0630, - 0.0525, 0.0196, 0.0051, -0.0484, -0.0322, 0.0059, 0.0132, 0.0079, - 0.0237, 0.0774, 0.0697, 0.0184, -0.0321, -0.0327, 0.0274, 0.0284, - 0.0057, 0.0289, 0.0478, 0.0142, -0.0053, 0.0114, 0.0292, -0.0032, --0.0111, -0.0389, 0.0282, 0.0613, 0.0200, -0.0006, 0.0111, 0.0048, - 0.0273, 0.0017, -0.0369, 0.0655, 0.0758, 0.0555, 0.0238, -0.0024, --0.0100, -0.0419, -0.0696, -0.0158, -0.0479, -0.0744, -0.0356, -0.0245, --0.0400, -0.0112, 0.0134, 0.0001, -0.0422, -0.0514, -0.0081, 0.0083, --0.0151, 0.0323, -0.0001, -0.0444, -0.0406, -0.0214, -0.0050, -0.0235, --0.0205, -0.0264, -0.0324, 0.0334, 0.0392, 0.0265, 0.0289, 0.0180, - 0.0493, 0.0227, 0.0194, 0.0365, 0.0544, 0.0674, 0.0559, 0.0732, - 0.0911, 0.0942, 0.0735, 0.0174, -0.0113, -0.0553, -0.0665, -0.0227, --0.0259, -0.0266, -0.0239, -0.0379, 0.0329, 0.0173, -0.0210, -0.0114, --0.0063, 0.0060, -0.0089, -0.0198, -0.0282, -0.0080, -0.0179, -0.0290, - 0.0046, -0.0126, -0.0066, 0.0350, 0.0532, 0.0235, 0.0198, 0.0212, - 0.0449, 0.0681, 0.0677, -0.0049, 0.0086, 0.0120, 0.0356, 0.0454, - 0.0592, 0.0449, -0.0271, -0.0510, -0.0110, 0.0234, 0.0203, 0.0243, - 0.0242, 0.0133, 0.0098, 0.0040, 0.0024, -0.0005, -0.0075, -0.0126, --0.0393, -0.0052, 0.0165, 0.0016, -0.0193, 0.0239, 0.0336, 0.0029, --0.0586, -0.0539, -0.0094, -0.0664, -0.0898, -0.0540, -0.0066, 0.0134, --0.0074, 0.0067, -0.0521, -0.0431, 0.0104, 0.0690, 0.0663, 0.0197, --0.0017, -0.0518, -0.0597, -0.0171, -0.0054, -0.0140, -0.0080, 0.0172, --0.0362, -0.0713, -0.0310, 0.0096, 0.0243, 0.0381, -0.0062, -0.0392, --0.0281, 0.0386, 0.0461, 0.0069, 0.0384, 0.0080, -0.0141, 0.0171, - 0.3368, 0.3128, 0.3304, 0.3392, 0.3185, 0.3037, 0.2789, 0.2692, - 0.2779, 0.2796, 0.2891, 0.2643, 0.2647, 0.2593, 0.2927, 0.3283, - 0.4978, 0.4988, 0.4969, 0.4997, 0.4957, 0.4985, 0.4970, 0.4978, - 0.4938, 0.4951, 0.4994, 0.4971, 0.4981, 0.4983, 0.4967, 0.4789 -}, - -.lsp44 = { - 0.0927, 0.2291, 0.4059, 0.5779, 0.7288, 0.8821, 1.0377, 1.1915, - 1.3433, 1.4931, 1.6475, 1.7989, 1.9381, 2.0858, 2.2321, 2.3765, - 2.5187, 2.6530, 2.7895, 2.9354, 0.0944, 0.1974, 0.3046, 0.4714, - 0.6116, 0.7829, 0.9027, 1.0375, 1.1869, 1.3488, 1.5036, 1.6781, - 1.8276, 1.9983, 2.1449, 2.3089, 2.4534, 2.6113, 2.7553, 2.9062, - 0.1168, 0.2843, 0.4907, 0.6706, 0.8100, 0.9417, 1.0753, 1.2014, - 1.3151, 1.4496, 1.5832, 1.7379, 1.8642, 2.0230, 2.1681, 2.3250, - 2.4676, 2.6242, 2.7602, 2.9066, 0.1353, 0.2335, 0.3370, 0.4380, - 0.5819, 0.7353, 0.8671, 1.0160, 1.1435, 1.2977, 1.4860, 1.6739, - 1.8412, 2.0028, 2.1537, 2.3124, 2.4741, 2.6272, 2.7862, 2.9536, - 0.1003, 0.2226, 0.3584, 0.4971, 0.6291, 0.7710, 0.9157, 1.0669, - 1.2143, 1.3624, 1.5104, 1.6681, 1.8164, 1.9823, 2.1394, 2.3082, - 2.4677, 2.6306, 2.7909, 2.9382, 0.1056, 0.2027, 0.2956, 0.4005, - 0.5215, 0.6708, 0.8545, 1.0557, 1.2344, 1.4023, 1.5676, 1.7278, - 1.8808, 2.0381, 2.1846, 2.3376, 2.4887, 2.6377, 2.7878, 2.9504, - 0.1015, 0.2462, 0.4122, 0.5783, 0.7233, 0.8833, 1.0377, 1.1903, - 1.3341, 1.4727, 1.6138, 1.7582, 1.8912, 2.0370, 2.1701, 2.3125, - 2.4500, 2.6006, 2.7507, 2.9166, 0.1787, 0.2418, 0.3265, 0.5379, - 0.6584, 0.7681, 0.9545, 1.1050, 1.2125, 1.3528, 1.4763, 1.6705, - 1.8136, 1.9594, 2.0936, 2.2724, 2.4394, 2.5919, 2.7037, 2.8747, - 0.0859, 0.1600, 0.2980, 0.4933, 0.6696, 0.8285, 0.9958, 1.1545, - 1.3107, 1.4591, 1.6127, 1.7652, 1.9143, 2.0680, 2.2171, 2.3643, - 2.5141, 2.6611, 2.8143, 2.9691, 0.0910, 0.2110, 0.3364, 0.4718, - 0.5856, 0.7298, 0.8910, 1.0514, 1.1988, 1.3572, 1.5178, 1.6861, - 1.8399, 2.0099, 2.1639, 2.3225, 2.4774, 2.6321, 2.7863, 2.9412, - 0.1904, 0.2874, 0.3681, 0.4981, 0.6248, 0.7880, 0.9121, 1.0750, - 1.2185, 1.3809, 1.5296, 1.7007, 1.8592, 2.0470, 2.1913, 2.3250, - 2.4519, 2.5984, 2.7408, 2.9023, 0.0917, 0.2067, 0.3246, 0.4961, - 0.6310, 0.8024, 0.9438, 1.1008, 1.2362, 1.3892, 1.5407, 1.7033, - 1.8427, 2.0061, 2.1498, 2.3117, 2.4550, 2.6053, 2.7462, 2.9029, - 0.0989, 0.2193, 0.3756, 0.5410, 0.6929, 0.8368, 0.9801, 1.1250, - 1.2677, 1.4184, 1.5677, 1.7292, 1.8770, 2.0311, 2.1803, 2.3306, - 2.4836, 2.6339, 2.7943, 2.9549, 0.0861, 0.1943, 0.3057, 0.4867, - 0.6194, 0.7592, 0.9184, 1.1052, 1.2486, 1.4064, 1.5609, 1.7273, - 1.8703, 2.0291, 2.1686, 2.3225, 2.4628, 2.6115, 2.7471, 2.9005, - 0.0932, 0.2110, 0.3737, 0.5479, 0.7120, 0.8570, 0.9975, 1.1364, - 1.2772, 1.4220, 1.5612, 1.7089, 1.8410, 1.9827, 2.1263, 2.2859, - 2.4459, 2.6172, 2.7788, 2.9395, 0.1193, 0.2341, 0.3523, 0.5029, - 0.6437, 0.7803, 0.9367, 1.1007, 1.2392, 1.3869, 1.5425, 1.7168, - 1.8709, 2.0248, 2.1584, 2.2949, 2.4308, 2.5823, 2.7235, 2.9034, - 0.0834, 0.1988, 0.3557, 0.5261, 0.6767, 0.8427, 1.0029, 1.1683, - 1.3138, 1.4527, 1.6046, 1.7583, 1.9011, 2.0517, 2.1928, 2.3397, - 2.4839, 2.6291, 2.7771, 2.9329, 0.0938, 0.1967, 0.3213, 0.4675, - 0.6068, 0.7664, 0.9418, 1.1120, 1.2535, 1.3932, 1.5243, 1.6801, - 1.8346, 1.9931, 2.1376, 2.3035, 2.4636, 2.6244, 2.7829, 2.9371, - 0.1017, 0.2552, 0.4327, 0.6017, 0.7467, 0.8797, 1.0097, 1.1442, - 1.2628, 1.4049, 1.5541, 1.7090, 1.8461, 1.9982, 2.1486, 2.3029, - 2.4513, 2.6075, 2.7594, 2.9209, 0.1031, 0.2295, 0.3747, 0.5122, - 0.6596, 0.7935, 0.9345, 1.1050, 1.2384, 1.3543, 1.4739, 1.6136, - 1.7447, 1.8914, 2.0434, 2.1916, 2.3557, 2.5396, 2.7419, 2.9401, - 0.1007, 0.2374, 0.3715, 0.5173, 0.6465, 0.8069, 0.9553, 1.1145, - 1.2594, 1.4143, 1.5617, 1.7166, 1.8457, 2.0012, 2.1462, 2.2864, - 2.4258, 2.5910, 2.7372, 2.9018, 0.0808, 0.1726, 0.2849, 0.4592, - 0.6118, 0.7853, 0.9588, 1.1256, 1.2751, 1.4392, 1.5898, 1.7514, - 1.8977, 2.0554, 2.1937, 2.3430, 2.4831, 2.6249, 2.7601, 2.9155, - 0.1669, 0.2574, 0.3694, 0.5569, 0.6773, 0.8061, 1.0160, 1.1667, - 1.2791, 1.4041, 1.5452, 1.7207, 1.8524, 2.0038, 2.1414, 2.3338, - 2.4747, 2.6157, 2.7303, 2.8848, 0.1598, 0.2521, 0.3416, 0.5149, - 0.6703, 0.7941, 0.9408, 1.1164, 1.2017, 1.3293, 1.4908, 1.6783, - 1.8438, 1.9927, 2.1149, 2.2698, 2.4420, 2.6193, 2.7583, 2.9103, - 0.0902, 0.1978, 0.3265, 0.4578, 0.5878, 0.7439, 0.9110, 1.0906, - 1.2556, 1.4125, 1.5688, 1.7295, 1.8829, 2.0472, 2.2058, 2.3537, - 2.5075, 2.6548, 2.8058, 2.9538, 0.0818, 0.1695, 0.2794, 0.4470, - 0.6069, 0.7641, 0.9313, 1.0946, 1.2411, 1.4072, 1.5640, 1.7186, - 1.8651, 2.0254, 2.1726, 2.3286, 2.4784, 2.6287, 2.7750, 2.9339, - 0.1980, 0.3134, 0.4099, 0.4975, 0.6491, 0.8376, 0.9441, 1.0298, - 1.1795, 1.3866, 1.5784, 1.7209, 1.8137, 1.9271, 2.0863, 2.2930, - 2.4696, 2.6184, 2.7587, 2.9251, 0.1338, 0.2341, 0.3566, 0.4797, - 0.6129, 0.7580, 0.9093, 1.0491, 1.1911, 1.3313, 1.4841, 1.6503, - 1.8035, 1.9685, 2.1128, 2.2694, 2.4093, 2.5728, 2.7206, 2.8994, - 0.0937, 0.2034, 0.3447, 0.5032, 0.6370, 0.7993, 0.9674, 1.1323, - 1.2830, 1.4199, 1.5492, 1.7010, 1.8513, 2.0087, 2.1550, 2.3115, - 2.4643, 2.6237, 2.7812, 2.9392, 0.1085, 0.2152, 0.3126, 0.4569, - 0.5718, 0.7213, 0.8837, 1.0604, 1.2053, 1.3755, 1.5397, 1.7001, - 1.8409, 2.0039, 2.1498, 2.3080, 2.4535, 2.6063, 2.7505, 2.9110, - 0.0562, 0.2066, 0.4034, 0.5490, 0.6682, 0.7924, 0.9495, 1.0800, - 1.1869, 1.3156, 1.4834, 1.6619, 1.8404, 2.0199, 2.1509, 2.2755, - 2.4072, 2.5580, 2.6993, 2.8913, 0.0939, 0.2303, 0.3742, 0.5260, - 0.6662, 0.8294, 0.9769, 1.1315, 1.2792, 1.4153, 1.5436, 1.6701, - 1.8215, 1.9920, 2.1310, 2.3005, 2.4534, 2.5786, 2.7204, 2.9068, - 0.1005, 0.2442, 0.3898, 0.5398, 0.6958, 0.8474, 1.0008, 1.1556, - 1.3020, 1.4456, 1.5954, 1.7470, 1.8922, 2.0500, 2.2019, 2.3492, - 2.4963, 2.6412, 2.7890, 2.9423, 0.1022, 0.2031, 0.3213, 0.4402, - 0.5637, 0.7117, 0.8673, 1.0242, 1.1727, 1.3206, 1.4846, 1.6465, - 1.8015, 1.9655, 2.1233, 2.2873, 2.4464, 2.6074, 2.7685, 2.9409, - 0.1985, 0.3497, 0.4622, 0.5982, 0.7489, 0.8752, 0.9925, 1.1679, - 1.3288, 1.4606, 1.5820, 1.7492, 1.8922, 2.0511, 2.1780, 2.3373, - 2.4760, 2.6233, 2.7466, 2.8978, 0.1284, 0.2433, 0.3630, 0.4852, - 0.6117, 0.7460, 0.8904, 1.0360, 1.1738, 1.3142, 1.4696, 1.6185, - 1.7719, 1.9318, 2.0961, 2.2697, 2.4408, 2.6046, 2.7681, 2.9451, - 0.1042, 0.2286, 0.3598, 0.5064, 0.6438, 0.7899, 0.9350, 1.0891, - 1.2323, 1.3807, 1.5225, 1.6747, 1.8153, 1.9669, 2.1145, 2.2832, - 2.4430, 2.6085, 2.7748, 2.9346, 0.0780, 0.1724, 0.2440, 0.3489, - 0.5280, 0.7426, 0.9272, 1.0914, 1.2562, 1.4188, 1.5804, 1.7376, - 1.8909, 2.0473, 2.1946, 2.3457, 2.4950, 2.6424, 2.7926, 2.9549, - 0.1103, 0.2608, 0.4087, 0.5538, 0.6923, 0.8418, 0.9940, 1.1507, - 1.2919, 1.4406, 1.5802, 1.7262, 1.8638, 2.0085, 2.1572, 2.2975, - 2.4329, 2.5866, 2.7380, 2.9107, 0.1297, 0.2532, 0.4003, 0.5329, - 0.6733, 0.7950, 0.9557, 1.0859, 1.2235, 1.3538, 1.5037, 1.6389, - 1.7964, 1.9285, 2.0898, 2.2541, 2.4231, 2.5711, 2.6875, 2.8947, - 0.0871, 0.1968, 0.3425, 0.4949, 0.6424, 0.7959, 0.9534, 1.1132, - 1.2656, 1.4229, 1.5785, 1.7271, 1.8729, 2.0355, 2.1998, 2.3562, - 2.5151, 2.6663, 2.8145, 2.9534, 0.1038, 0.2204, 0.3248, 0.4566, - 0.5947, 0.7443, 0.8811, 1.0379, 1.2031, 1.3772, 1.5430, 1.7092, - 1.8625, 2.0322, 2.1904, 2.3417, 2.4960, 2.6458, 2.7979, 2.9485, - 0.1329, 0.2763, 0.3943, 0.5147, 0.6512, 0.8071, 0.9410, 1.0879, - 1.2298, 1.3850, 1.5282, 1.6674, 1.8137, 1.9993, 2.1344, 2.2749, - 2.4257, 2.5863, 2.7410, 2.9184, 0.1052, 0.2142, 0.3584, 0.5033, - 0.6387, 0.7804, 0.9320, 1.0780, 1.2172, 1.3764, 1.5421, 1.6887, - 1.8246, 1.9833, 2.1245, 2.2797, 2.4237, 2.5779, 2.7257, 2.9097, - 0.1092, 0.2676, 0.4071, 0.5355, 0.6661, 0.8142, 0.9621, 1.1173, - 1.2628, 1.4185, 1.5696, 1.7220, 1.8595, 2.0178, 2.1720, 2.3221, - 2.4718, 2.6259, 2.7775, 2.9334, 0.0929, 0.2017, 0.3073, 0.4570, - 0.5775, 0.7635, 0.9299, 1.0832, 1.2334, 1.3935, 1.5420, 1.7112, - 1.8601, 2.0309, 2.1735, 2.3230, 2.4543, 2.6034, 2.7418, 2.8988, - 0.0775, 0.2005, 0.3490, 0.5200, 0.6747, 0.8383, 0.9885, 1.1738, - 1.3141, 1.4236, 1.5892, 1.7402, 1.8474, 2.0210, 2.1593, 2.2730, - 2.4235, 2.5604, 2.7128, 2.9005, 0.1104, 0.2292, 0.3353, 0.4732, - 0.6152, 0.7675, 0.9164, 1.0907, 1.2594, 1.4064, 1.5218, 1.6426, - 1.8018, 1.9937, 2.1362, 2.2961, 2.4523, 2.6083, 2.7613, 2.9202, - 0.0826, 0.2000, 0.3384, 0.5144, 0.6694, 0.8377, 0.9870, 1.1461, - 1.2950, 1.4495, 1.5872, 1.7387, 1.8793, 2.0329, 2.1723, 2.3114, - 2.4415, 2.5908, 2.7354, 2.9028, 0.1063, 0.2268, 0.3442, 0.4735, - 0.6116, 0.7507, 0.9028, 1.0768, 1.2426, 1.4052, 1.5566, 1.7015, - 1.8243, 1.9742, 2.1276, 2.2824, 2.4262, 2.5953, 2.7627, 2.9290, - 0.1150, 0.2814, 0.4543, 0.6095, 0.7373, 0.8592, 0.9908, 1.1108, - 1.2339, 1.3590, 1.4864, 1.6168, 1.7392, 1.8752, 2.0212, 2.1688, - 2.3128, 2.4869, 2.7019, 2.9239, 0.0948, 0.2074, 0.3433, 0.4943, - 0.6346, 0.7645, 0.8809, 1.0610, 1.2307, 1.3487, 1.4655, 1.6186, - 1.7534, 1.8859, 2.0486, 2.2200, 2.3835, 2.5581, 2.7565, 2.9502, - 0.1062, 0.2239, 0.3683, 0.5197, 0.6704, 0.8184, 0.9642, 1.1127, - 1.2556, 1.3976, 1.5405, 1.6940, 1.8375, 1.9888, 2.1377, 2.2980, - 2.4555, 2.6184, 2.7849, 2.9452, 0.0888, 0.2005, 0.2847, 0.4322, - 0.5763, 0.7577, 0.9262, 1.1095, 1.2719, 1.4331, 1.5843, 1.7452, - 1.8845, 2.0385, 2.1805, 2.3345, 2.4750, 2.6217, 2.7555, 2.9013, - 0.1713, 0.2617, 0.3868, 0.5859, 0.7073, 0.8535, 1.0593, 1.1778, - 1.3109, 1.4508, 1.5910, 1.7463, 1.8911, 2.0651, 2.2035, 2.3355, - 2.4947, 2.6440, 2.7424, 2.8943, 0.1346, 0.2549, 0.4089, 0.5488, - 0.6949, 0.8394, 0.9810, 1.1145, 1.2528, 1.4044, 1.5423, 1.6872, - 1.8274, 1.9726, 2.1403, 2.2809, 2.4128, 2.5564, 2.6887, 2.8895, - 0.0776, 0.1621, 0.2553, 0.4191, 0.5988, 0.7921, 0.9651, 1.1350, - 1.2930, 1.4475, 1.6011, 1.7585, 1.9068, 2.0638, 2.2102, 2.3594, - 2.5096, 2.6581, 2.8099, 2.9654, 0.0864, 0.1778, 0.2854, 0.4235, - 0.5568, 0.7220, 0.8963, 1.0609, 1.2217, 1.3830, 1.5422, 1.7018, - 1.8551, 2.0206, 2.1783, 2.3328, 2.4869, 2.6366, 2.7923, 2.9539, - 0.1144, 0.2576, 0.4186, 0.5594, 0.6875, 0.8221, 0.9598, 1.0944, - 1.2273, 1.3713, 1.5152, 1.6628, 1.8070, 1.9525, 2.0965, 2.2535, - 2.4132, 2.5725, 2.7250, 2.9150, 0.1079, 0.2221, 0.3334, 0.4845, - 0.6083, 0.7516, 0.9018, 1.0594, 1.2060, 1.3673, 1.5212, 1.6880, - 1.8208, 1.9831, 2.1269, 2.2909, 2.4366, 2.6027, 2.7339, 2.8924, - 0.0994, 0.2233, 0.3634, 0.5145, 0.6568, 0.8131, 0.9746, 1.1296, - 1.2666, 1.4116, 1.5748, 1.7264, 1.8649, 2.0217, 2.1716, 2.3293, - 2.4900, 2.6455, 2.7818, 2.9362, 0.1120, 0.2079, 0.3128, 0.4124, - 0.5291, 0.6816, 0.8478, 1.0150, 1.1772, 1.3456, 1.5208, 1.6882, - 1.8458, 2.0078, 2.1627, 2.3198, 2.4733, 2.6251, 2.7796, 2.9489, - 0.0853, 0.2030, 0.3669, 0.5326, 0.6678, 0.8086, 0.9526, 1.1142, - 1.2551, 1.4158, 1.5694, 1.7073, 1.8431, 1.9686, 2.1153, 2.2376, - 2.3686, 2.5591, 2.7320, 2.9104, 0.0905, 0.2166, 0.3539, 0.5201, - 0.6700, 0.8346, 0.9883, 1.1457, 1.2714, 1.3845, 1.5172, 1.6688, - 1.8008, 1.9535, 2.1019, 2.2708, 2.4135, 2.5974, 2.7486, 2.9033, - 0.0084, 0.0374, 0.0164, -0.0153, 0.0288, 0.0107, -0.0255, -0.0242, - 0.0000, -0.0055, -0.0081, -0.0075, -0.0022, -0.0052, -0.0069, -0.0017, - 0.0003, 0.0091, 0.0028, -0.0027, 0.0085, 0.0043, -0.0235, -0.0411, - 0.0202, 0.0359, 0.0376, 0.0321, 0.0306, -0.0358, -0.0276, -0.0090, - 0.0032, 0.0048, 0.0309, 0.0332, 0.0284, 0.0237, 0.0051, -0.0101, --0.0233, -0.0428, -0.0585, -0.0387, 0.0039, 0.0081, 0.0029, -0.0017, --0.0006, -0.0068, 0.0044, 0.0182, 0.0376, 0.0387, -0.0334, -0.0269, --0.0182, -0.0069, -0.0026, 0.0035, -0.0049, -0.0212, -0.0408, -0.0245, - 0.0186, 0.0189, 0.0153, 0.0120, 0.0157, 0.0055, -0.0046, 0.0179, - 0.0284, -0.0032, -0.0261, -0.0205, -0.0039, 0.0174, 0.0299, 0.0207, - 0.0012, -0.0056, 0.0010, 0.0141, -0.0119, 0.0190, 0.0315, 0.0033, --0.0128, 0.0300, 0.0328, 0.0308, 0.0353, 0.0266, 0.0066, -0.0328, --0.0273, 0.0054, 0.0145, 0.0175, 0.0015, -0.0171, 0.0062, -0.0164, - 0.0045, -0.0071, 0.0025, 0.0278, 0.0283, 0.0117, -0.0026, -0.0285, --0.0408, -0.0366, -0.0059, -0.0208, -0.0354, -0.0334, -0.0263, -0.0064, - 0.0072, -0.0006, -0.0235, -0.0037, -0.0307, -0.0294, -0.0163, -0.0197, --0.0235, 0.0192, 0.0013, -0.0219, -0.0123, -0.0004, -0.0081, -0.0096, --0.0123, -0.0101, 0.0021, 0.0151, 0.0106, 0.0151, 0.0292, 0.0033, - 0.0283, 0.0124, 0.0058, -0.0017, -0.0038, 0.0152, 0.0141, 0.0132, - 0.0178, 0.0157, 0.0073, 0.0176, 0.0141, 0.0097, -0.0092, -0.0163, --0.0230, -0.0134, -0.0099, -0.0147, 0.0040, -0.0183, -0.0175, -0.0080, --0.0083, -0.0290, -0.0417, -0.0398, -0.0269, -0.0199, -0.0143, -0.0053, --0.0099, -0.0054, -0.0199, -0.0219, -0.0170, 0.0107, 0.0194, 0.0035, - 0.0437, 0.0406, 0.0215, 0.0120, 0.0053, -0.0028, 0.0238, 0.0337, - 0.0217, 0.0011, 0.0227, 0.0244, 0.0327, 0.0378, 0.0437, 0.0356, --0.0033, 0.0113, 0.0407, 0.0334, -0.0125, -0.0003, -0.0141, -0.0273, --0.0137, -0.0079, -0.0145, -0.0071, 0.0114, 0.0181, 0.0150, 0.0085, --0.0077, -0.0038, -0.0219, -0.0263, -0.0187, -0.0233, 0.0133, 0.0265, --0.0156, -0.0091, -0.0110, -0.0016, 0.0143, 0.0177, 0.0240, 0.0082, --0.0143, -0.0257, -0.0014, 0.0002, 0.0082, 0.0180, 0.0325, 0.0340, --0.0153, -0.0389, -0.0240, 0.0082, 0.0140, 0.0046, -0.0138, -0.0378, --0.0366, 0.0297, 0.0252, 0.0078, 0.0063, 0.0006, 0.0044, 0.0074, - 0.0094, 0.0113, 0.0105, 0.0137, 0.0438, 0.0262, -0.0078, -0.0185, --0.0215, -0.0407, -0.0435, -0.0208, -0.0004, -0.0144, -0.0205, -0.0248, --0.0159, -0.0069, -0.0153, 0.0132, 0.0355, 0.0298, 0.0120, 0.0072, - 0.0236, 0.0526, 0.0479, 0.0233, -0.0133, -0.0283, -0.0468, -0.0549, --0.0370, 0.0032, 0.0056, 0.0023, 0.0050, 0.0024, 0.0279, 0.0116, --0.0045, -0.0012, 0.0107, 0.0190, 0.0253, 0.0191, 0.0043, 0.0193, --0.0348, -0.0246, 0.0123, 0.0210, 0.0135, -0.0096, -0.0109, -0.0076, --0.0156, -0.0290, 0.0160, 0.0194, 0.0219, 0.0259, 0.0250, 0.0195, - 0.4948, 0.4961, 0.4940, 0.4878, 0.4849, 0.4727, 0.4571, 0.4551, - 0.4534, 0.4468, 0.4412, 0.4354, 0.4298, 0.4272, 0.4498, 0.4506, - 0.4560, 0.4592, 0.4758, 0.4941, 0.2476, 0.1771, 0.1974, 0.1881, - 0.1667, 0.1826, 0.2067, 0.2031, 0.1734, 0.1534, 0.1415, 0.1761, - 0.1897, 0.1772, 0.1651, 0.1247, 0.1041, 0.1231, 0.1809, 0.2234 - }, -}; - - -static const uint8_t tab7[][35] = { - {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,0,0,0,0,1,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}, - {0,0,0,1,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}, - {0,0,0,1,0,0,0,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}, - {0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,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,1,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0} -}; - -static const uint8_t tab8[][5] = { - {0, 0, 0, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 0, 0, 0}, - {1, 0, 0, 1, 0}, - {0, 0, 0, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 0, 0, 0}, - {1, 0, 0, 1, 0}, - {0, 0, 0, 1, 1}, - {0, 1, 0, 0, 1}, - {1, 1, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 1, 0, 1, 0} -}; - -static const uint8_t tab9[][45] = { - { - 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 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, 0, 0, 0 - },{ - 0, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 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, 0, 0, 0 - },{ - 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, - 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } -}; - -static const uint8_t tab10[][25] = -{ - {1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0}, - {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, - {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0}, - {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}, - {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}, - {1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}, - {0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1} -}; - -static const uint8_t tab11[][55] = { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 - },{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - },{ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - },{ - 0, 0, 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, 0, 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, 0, 0, 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, 0, 0, 0, - 0, 0, 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, 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, 1, 0, 0, 0, 0, 0, - },{ - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - },{ - 0, 0, 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, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - },{ - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - } -}; - -static const uint8_t tab12[][15] = { - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}, -}; - -static const struct { - int size; - const uint8_t *tab; -} tabs[] = { - {0 , NULL}, - {5 , &tab8 [0][0]},{5 , &tab8 [0][0]}, {15, &tab12[0][0]}, - {5 , &tab8 [0][0]},{25, &tab10[0][0]}, {15, &tab12[0][0]}, - {35, &tab7 [0][0]},{5 , &tab8 [0][0]}, {45, &tab9 [0][0]}, - {25, &tab10[0][0]},{55, &tab11[0][0]}, {15, &tab12[0][0]} -}; - -#endif /* AVCODEC_TWINVQ_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/txd.c b/tizen/distrib/ffmpeg/libavcodec/txd.c deleted file mode 100644 index ac8229f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/txd.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Renderware TeXture Dictionary (.txd) image decoder - * Copyright (c) 2007 Ivo van Poorten - * - * See also: http://wiki.multimedia.cx/index.php?title=TXD - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "s3tc.h" - -typedef struct TXDContext { - AVFrame picture; -} TXDContext; - -static av_cold int txd_init(AVCodecContext *avctx) { - TXDContext *s = avctx->priv_data; - - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; - - return 0; -} - -static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - TXDContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p = &s->picture; - unsigned int version, w, h, d3d_format, depth, stride, mipmap_count, flags; - unsigned int y, v; - uint8_t *ptr; - const uint8_t *cur = buf; - const uint32_t *palette = (const uint32_t *)(cur + 88); - uint32_t *pal; - - version = AV_RL32(cur); - d3d_format = AV_RL32(cur+76); - w = AV_RL16(cur+80); - h = AV_RL16(cur+82); - depth = AV_RL8 (cur+84); - mipmap_count = AV_RL8 (cur+85); - flags = AV_RL8 (cur+87); - cur += 92; - - if (version < 8 || version > 9) { - av_log(avctx, AV_LOG_ERROR, "texture data version %i is unsupported\n", - version); - return -1; - } - - if (depth == 8) { - avctx->pix_fmt = PIX_FMT_PAL8; - cur += 1024; - } else if (depth == 16 || depth == 32) - avctx->pix_fmt = PIX_FMT_RGB32; - else { - av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth); - return -1; - } - - if (p->data[0]) - avctx->release_buffer(avctx, p); - - if (avcodec_check_dimensions(avctx, w, h)) - return -1; - if (w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - 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; - - ptr = p->data[0]; - stride = p->linesize[0]; - - if (depth == 8) { - pal = (uint32_t *) p->data[1]; - for (y=0; y<256; y++) { - v = AV_RB32(palette+y); - pal[y] = (v>>8) + (v<<24); - } - for (y=0; y 1; mipmap_count--) - cur += AV_RL32(cur) + 4; - - *picture = s->picture; - *data_size = sizeof(AVPicture); - - return cur - buf; - -unsupported: - av_log(avctx, AV_LOG_ERROR, "unsupported d3d format (%08x)\n", d3d_format); - return -1; -} - -static av_cold int txd_end(AVCodecContext *avctx) { - TXDContext *s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec txd_decoder = { - "txd", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_TXD, - sizeof(TXDContext), - txd_init, - NULL, - txd_end, - txd_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ulti.c b/tizen/distrib/ffmpeg/libavcodec/ulti.c deleted file mode 100644 index 1d04c80..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ulti.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * IBM Ultimotion Video Decoder - * Copyright (C) 2004 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * IBM Ultimotion Video Decoder. - */ - -#include -#include -#include - -#include "avcodec.h" -#include "bytestream.h" - -#include "ulti_cb.h" - -typedef struct UltimotionDecodeContext { - AVCodecContext *avctx; - int width, height, blocks; - AVFrame frame; - const uint8_t *ulti_codebook; -} UltimotionDecodeContext; - -static av_cold int ulti_decode_init(AVCodecContext *avctx) -{ - UltimotionDecodeContext *s = avctx->priv_data; - - s->avctx = avctx; - s->width = avctx->width; - s->height = avctx->height; - s->blocks = (s->width / 8) * (s->height / 8); - avctx->pix_fmt = PIX_FMT_YUV410P; - avctx->coded_frame = (AVFrame*) &s->frame; - s->ulti_codebook = ulti_codebook; - - return 0; -} - -static av_cold int ulti_decode_end(AVCodecContext *avctx){ - UltimotionDecodeContext *s = avctx->priv_data; - AVFrame *pic = &s->frame; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - -static const int block_coords[8] = // 4x4 block coords in 8x8 superblock - { 0, 0, 0, 4, 4, 4, 4, 0}; - -static const int angle_by_index[4] = { 0, 2, 6, 12}; - -/* Lookup tables for luma and chroma - used by ulti_convert_yuv() */ -static const uint8_t ulti_lumas[64] = - { 0x10, 0x13, 0x17, 0x1A, 0x1E, 0x21, 0x25, 0x28, - 0x2C, 0x2F, 0x33, 0x36, 0x3A, 0x3D, 0x41, 0x44, - 0x48, 0x4B, 0x4F, 0x52, 0x56, 0x59, 0x5C, 0x60, - 0x63, 0x67, 0x6A, 0x6E, 0x71, 0x75, 0x78, 0x7C, - 0x7F, 0x83, 0x86, 0x8A, 0x8D, 0x91, 0x94, 0x98, - 0x9B, 0x9F, 0xA2, 0xA5, 0xA9, 0xAC, 0xB0, 0xB3, - 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8, 0xCC, 0xCF, - 0xD3, 0xD6, 0xDA, 0xDD, 0xE1, 0xE4, 0xE8, 0xEB}; - -static const uint8_t ulti_chromas[16] = - { 0x60, 0x67, 0x6D, 0x73, 0x7A, 0x80, 0x86, 0x8D, - 0x93, 0x99, 0xA0, 0xA6, 0xAC, 0xB3, 0xB9, 0xC0}; - -/* convert Ultimotion YUV block (sixteen 6-bit Y samples and - two 4-bit chroma samples) into standard YUV and put it into frame */ -static void ulti_convert_yuv(AVFrame *frame, int x, int y, - uint8_t *luma,int chroma) -{ - uint8_t *y_plane, *cr_plane, *cb_plane; - int i; - - y_plane = frame->data[0] + x + y * frame->linesize[0]; - cr_plane = frame->data[1] + (x / 4) + (y / 4) * frame->linesize[1]; - cb_plane = frame->data[2] + (x / 4) + (y / 4) * frame->linesize[2]; - - cr_plane[0] = ulti_chromas[chroma >> 4]; - - cb_plane[0] = ulti_chromas[chroma & 0xF]; - - - for(i = 0; i < 16; i++){ - y_plane[i & 3] = ulti_lumas[luma[i]]; - if((i & 3) == 3) { //next row - y_plane += frame->linesize[0]; - } - } -} - -/* generate block like in MS Video1 */ -static void ulti_pattern(AVFrame *frame, int x, int y, - int f0, int f1, int Y0, int Y1, int chroma) -{ - uint8_t Luma[16]; - int mask, i; - for(mask = 0x80, i = 0; mask; mask >>= 1, i++) { - if(f0 & mask) - Luma[i] = Y1; - else - Luma[i] = Y0; - } - - for(mask = 0x80, i = 8; mask; mask >>= 1, i++) { - if(f1 & mask) - Luma[i] = Y1; - else - Luma[i] = Y0; - } - - ulti_convert_yuv(frame, x, y, Luma, chroma); -} - -/* fill block with some gradient */ -static void ulti_grad(AVFrame *frame, int x, int y, uint8_t *Y, int chroma, int angle) -{ - uint8_t Luma[16]; - if(angle & 8) { //reverse order - int t; - angle &= 0x7; - t = Y[0]; - Y[0] = Y[3]; - Y[3] = t; - t = Y[1]; - Y[1] = Y[2]; - Y[2] = t; - } - switch(angle){ - case 0: - Luma[0] = Y[0]; Luma[1] = Y[1]; Luma[2] = Y[2]; Luma[3] = Y[3]; - Luma[4] = Y[0]; Luma[5] = Y[1]; Luma[6] = Y[2]; Luma[7] = Y[3]; - Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[2]; Luma[11] = Y[3]; - Luma[12] = Y[0]; Luma[13] = Y[1]; Luma[14] = Y[2]; Luma[15] = Y[3]; - break; - case 1: - Luma[0] = Y[1]; Luma[1] = Y[2]; Luma[2] = Y[3]; Luma[3] = Y[3]; - Luma[4] = Y[0]; Luma[5] = Y[1]; Luma[6] = Y[2]; Luma[7] = Y[3]; - Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[2]; Luma[11] = Y[3]; - Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[1]; Luma[15] = Y[2]; - break; - case 2: - Luma[0] = Y[1]; Luma[1] = Y[2]; Luma[2] = Y[3]; Luma[3] = Y[3]; - Luma[4] = Y[1]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[3]; - Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[2]; - Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[1]; Luma[15] = Y[2]; - break; - case 3: - Luma[0] = Y[2]; Luma[1] = Y[3]; Luma[2] = Y[3]; Luma[3] = Y[3]; - Luma[4] = Y[1]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[3]; - Luma[8] = Y[0]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[2]; - Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[0]; Luma[15] = Y[1]; - break; - case 4: - Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[3]; Luma[3] = Y[3]; - Luma[4] = Y[2]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[2]; - Luma[8] = Y[1]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[1]; - Luma[12] = Y[0]; Luma[13] = Y[0]; Luma[14] = Y[0]; Luma[15] = Y[0]; - break; - case 5: - Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[3]; Luma[3] = Y[2]; - Luma[4] = Y[3]; Luma[5] = Y[2]; Luma[6] = Y[2]; Luma[7] = Y[1]; - Luma[8] = Y[2]; Luma[9] = Y[1]; Luma[10] = Y[1]; Luma[11] = Y[0]; - Luma[12] = Y[1]; Luma[13] = Y[0]; Luma[14] = Y[0]; Luma[15] = Y[0]; - break; - case 6: - Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[2]; Luma[3] = Y[2]; - Luma[4] = Y[3]; Luma[5] = Y[2]; Luma[6] = Y[1]; Luma[7] = Y[1]; - Luma[8] = Y[2]; Luma[9] = Y[2]; Luma[10] = Y[1]; Luma[11] = Y[0]; - Luma[12] = Y[1]; Luma[13] = Y[1]; Luma[14] = Y[0]; Luma[15] = Y[0]; - break; - case 7: - Luma[0] = Y[3]; Luma[1] = Y[3]; Luma[2] = Y[2]; Luma[3] = Y[1]; - Luma[4] = Y[3]; Luma[5] = Y[2]; Luma[6] = Y[1]; Luma[7] = Y[0]; - Luma[8] = Y[3]; Luma[9] = Y[2]; Luma[10] = Y[1]; Luma[11] = Y[0]; - Luma[12] = Y[2]; Luma[13] = Y[1]; Luma[14] = Y[0]; Luma[15] = Y[0]; - break; - default: - Luma[0] = Y[0]; Luma[1] = Y[0]; Luma[2] = Y[1]; Luma[3] = Y[1]; - Luma[4] = Y[0]; Luma[5] = Y[0]; Luma[6] = Y[1]; Luma[7] = Y[1]; - Luma[8] = Y[2]; Luma[9] = Y[2]; Luma[10] = Y[3]; Luma[11] = Y[3]; - Luma[12] = Y[2]; Luma[13] = Y[2]; Luma[14] = Y[3]; Luma[15] = Y[3]; - break; - } - - ulti_convert_yuv(frame, x, y, Luma, chroma); -} - -static int ulti_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - UltimotionDecodeContext *s=avctx->priv_data; - int modifier = 0; - int uniq = 0; - int mode = 0; - int blocks = 0; - int done = 0; - int x = 0, y = 0; - int i; - int skip; - int tmp; - - if(s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if(avctx->get_buffer(avctx, &s->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - while(!done) { - int idx; - if(blocks >= s->blocks || y >= s->height) - break;//all blocks decoded - - idx = *buf++; - if((idx & 0xF8) == 0x70) { - switch(idx) { - case 0x70: //change modifier - modifier = *buf++; - if(modifier>1) - av_log(avctx, AV_LOG_INFO, "warning: modifier must be 0 or 1, got %i\n", modifier); - break; - case 0x71: // set uniq flag - uniq = 1; - break; - case 0x72: //toggle mode - mode = !mode; - break; - case 0x73: //end-of-frame - done = 1; - break; - case 0x74: //skip some blocks - skip = *buf++; - if ((blocks + skip) >= s->blocks) - break; - blocks += skip; - x += skip * 8; - while(x >= s->width) { - x -= s->width; - y += 8; - } - break; - default: - av_log(avctx, AV_LOG_INFO, "warning: unknown escape 0x%02X\n", idx); - } - } else { //handle one block - int code; - int cf; - int angle = 0; - uint8_t Y[4]; // luma samples of block - int tx = 0, ty = 0; //coords of subblock - int chroma = 0; - if (mode || uniq) { - uniq = 0; - cf = 1; - chroma = 0; - } else { - cf = 0; - if (idx) - chroma = *buf++; - } - for (i = 0; i < 4; i++) { // for every subblock - code = (idx >> (6 - i*2)) & 3; //extract 2 bits - if(!code) //skip subblock - continue; - if(cf) - chroma = *buf++; - tx = x + block_coords[i * 2]; - ty = y + block_coords[(i * 2) + 1]; - switch(code) { - case 1: - tmp = *buf++; - - angle = angle_by_index[(tmp >> 6) & 0x3]; - - Y[0] = tmp & 0x3F; - Y[1] = Y[0]; - - if (angle) { - Y[2] = Y[0]+1; - if (Y[2] > 0x3F) - Y[2] = 0x3F; - Y[3] = Y[2]; - } else { - Y[2] = Y[0]; - Y[3] = Y[0]; - } - break; - - case 2: - if (modifier) { // unpack four luma samples - tmp = bytestream_get_be24(&buf); - - Y[0] = (tmp >> 18) & 0x3F; - Y[1] = (tmp >> 12) & 0x3F; - Y[2] = (tmp >> 6) & 0x3F; - Y[3] = tmp & 0x3F; - angle = 16; - } else { // retrieve luma samples from codebook - tmp = bytestream_get_be16(&buf); - - angle = (tmp >> 12) & 0xF; - tmp &= 0xFFF; - tmp <<= 2; - Y[0] = s->ulti_codebook[tmp]; - Y[1] = s->ulti_codebook[tmp + 1]; - Y[2] = s->ulti_codebook[tmp + 2]; - Y[3] = s->ulti_codebook[tmp + 3]; - } - break; - - case 3: - if (modifier) { // all 16 luma samples - uint8_t Luma[16]; - - tmp = bytestream_get_be24(&buf); - Luma[0] = (tmp >> 18) & 0x3F; - Luma[1] = (tmp >> 12) & 0x3F; - Luma[2] = (tmp >> 6) & 0x3F; - Luma[3] = tmp & 0x3F; - - tmp = bytestream_get_be24(&buf); - Luma[4] = (tmp >> 18) & 0x3F; - Luma[5] = (tmp >> 12) & 0x3F; - Luma[6] = (tmp >> 6) & 0x3F; - Luma[7] = tmp & 0x3F; - - tmp = bytestream_get_be24(&buf); - Luma[8] = (tmp >> 18) & 0x3F; - Luma[9] = (tmp >> 12) & 0x3F; - Luma[10] = (tmp >> 6) & 0x3F; - Luma[11] = tmp & 0x3F; - - tmp = bytestream_get_be24(&buf); - Luma[12] = (tmp >> 18) & 0x3F; - Luma[13] = (tmp >> 12) & 0x3F; - Luma[14] = (tmp >> 6) & 0x3F; - Luma[15] = tmp & 0x3F; - - ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma); - } else { - tmp = *buf++; - if(tmp & 0x80) { - angle = (tmp >> 4) & 0x7; - tmp = (tmp << 8) + *buf++; - Y[0] = (tmp >> 6) & 0x3F; - Y[1] = tmp & 0x3F; - Y[2] = (*buf++) & 0x3F; - Y[3] = (*buf++) & 0x3F; - ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block - } else { // some patterns - int f0, f1; - f0 = *buf++; - f1 = tmp; - Y[0] = (*buf++) & 0x3F; - Y[1] = (*buf++) & 0x3F; - ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma); - } - } - break; - } - if(code != 3) - ulti_grad(&s->frame, tx, ty, Y, chroma, angle); // draw block - } - blocks++; - x += 8; - if(x >= s->width) { - x = 0; - y += 8; - } - } - } - - *data_size=sizeof(AVFrame); - *(AVFrame*)data= s->frame; - - return buf_size; -} - -AVCodec ulti_decoder = { - "ultimotion", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ULTI, - sizeof(UltimotionDecodeContext), - ulti_decode_init, - NULL, - ulti_decode_end, - ulti_decode_frame, - CODEC_CAP_DR1, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("IBM UltiMotion"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/ulti_cb.h b/tizen/distrib/ffmpeg/libavcodec/ulti_cb.h deleted file mode 100644 index 7061d83..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ulti_cb.h +++ /dev/null @@ -1,4124 +0,0 @@ -/* - * IBM Ultimotion Video Decoder - * copyright (C) 2004 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_ULTI_CB_H -#define AVCODEC_ULTI_CB_H - -static const unsigned char ulti_codebook[16384]={ - 0x00, 0x01, 0x01, 0x02, - 0x00, 0x01, 0x02, 0x03, - 0x00, 0x02, 0x03, 0x04, - 0x00, 0x01, 0x03, 0x04, - 0x00, 0x01, 0x02, 0x04, - 0x00, 0x02, 0x03, 0x05, - 0x00, 0x02, 0x04, 0x05, - 0x00, 0x01, 0x04, 0x05, - 0x00, 0x01, 0x03, 0x05, - 0x00, 0x02, 0x04, 0x06, - 0x00, 0x03, 0x05, 0x06, - 0x00, 0x01, 0x05, 0x06, - 0x00, 0x01, 0x03, 0x06, - 0x00, 0x06, 0x06, 0x06, - 0x00, 0x00, 0x06, 0x06, - 0x00, 0x00, 0x00, 0x06, - 0x00, 0x03, 0x04, 0x07, - 0x00, 0x03, 0x06, 0x07, - 0x00, 0x01, 0x06, 0x07, - 0x00, 0x01, 0x04, 0x07, - 0x00, 0x03, 0x05, 0x08, - 0x00, 0x04, 0x06, 0x08, - 0x00, 0x02, 0x06, 0x08, - 0x00, 0x02, 0x04, 0x08, - 0x00, 0x08, 0x08, 0x08, - 0x00, 0x00, 0x08, 0x08, - 0x00, 0x00, 0x00, 0x08, - 0x00, 0x04, 0x07, 0x0B, - 0x00, 0x05, 0x09, 0x0B, - 0x00, 0x02, 0x09, 0x0B, - 0x00, 0x02, 0x06, 0x0B, - 0x00, 0x0B, 0x0B, 0x0B, - 0x00, 0x00, 0x0B, 0x0B, - 0x00, 0x00, 0x00, 0x0B, - 0x00, 0x05, 0x09, 0x0E, - 0x00, 0x07, 0x0B, 0x0E, - 0x00, 0x03, 0x0B, 0x0E, - 0x00, 0x03, 0x07, 0x0E, - 0x00, 0x0E, 0x0E, 0x0E, - 0x00, 0x00, 0x0E, 0x0E, - 0x00, 0x00, 0x00, 0x0E, - 0x00, 0x06, 0x0B, 0x11, - 0x00, 0x08, 0x0D, 0x11, - 0x00, 0x04, 0x0D, 0x11, - 0x00, 0x04, 0x09, 0x11, - 0x00, 0x11, 0x11, 0x11, - 0x00, 0x00, 0x11, 0x11, - 0x00, 0x00, 0x00, 0x11, - 0x00, 0x07, 0x0D, 0x14, - 0x00, 0x0A, 0x0F, 0x14, - 0x00, 0x05, 0x0F, 0x14, - 0x00, 0x05, 0x0A, 0x14, - 0x00, 0x14, 0x14, 0x14, - 0x00, 0x00, 0x14, 0x14, - 0x00, 0x00, 0x00, 0x14, - 0x00, 0x0B, 0x12, 0x17, - 0x00, 0x05, 0x12, 0x17, - 0x00, 0x05, 0x0C, 0x17, - 0x00, 0x17, 0x17, 0x17, - 0x00, 0x00, 0x17, 0x17, - 0x00, 0x00, 0x00, 0x17, - 0x00, 0x0D, 0x14, 0x1A, - 0x00, 0x06, 0x14, 0x1A, - 0x00, 0x06, 0x0D, 0x1A, - 0x00, 0x1A, 0x1A, 0x1A, - 0x00, 0x00, 0x1A, 0x1A, - 0x00, 0x00, 0x00, 0x1A, - 0x00, 0x0E, 0x16, 0x1D, - 0x00, 0x07, 0x16, 0x1D, - 0x00, 0x07, 0x0F, 0x1D, - 0x00, 0x1D, 0x1D, 0x1D, - 0x00, 0x00, 0x1D, 0x1D, - 0x00, 0x00, 0x00, 0x1D, - 0x00, 0x10, 0x18, 0x20, - 0x00, 0x08, 0x18, 0x20, - 0x00, 0x08, 0x10, 0x20, - 0x00, 0x20, 0x20, 0x20, - 0x00, 0x00, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x20, - 0x00, 0x23, 0x23, 0x23, - 0x00, 0x00, 0x23, 0x23, - 0x00, 0x00, 0x00, 0x23, - 0x00, 0x12, 0x1B, 0x24, - 0x00, 0x09, 0x1B, 0x24, - 0x00, 0x09, 0x12, 0x24, - 0x00, 0x28, 0x28, 0x28, - 0x00, 0x00, 0x28, 0x28, - 0x00, 0x00, 0x00, 0x28, - 0x00, 0x2E, 0x2E, 0x2E, - 0x00, 0x00, 0x2E, 0x2E, - 0x00, 0x00, 0x00, 0x2E, - 0x01, 0x02, 0x02, 0x03, - 0x01, 0x02, 0x03, 0x04, - 0x01, 0x03, 0x04, 0x05, - 0x01, 0x02, 0x04, 0x05, - 0x01, 0x02, 0x03, 0x05, - 0x01, 0x03, 0x04, 0x06, - 0x01, 0x03, 0x05, 0x06, - 0x01, 0x02, 0x05, 0x06, - 0x01, 0x02, 0x04, 0x06, - 0x01, 0x03, 0x05, 0x07, - 0x01, 0x04, 0x06, 0x07, - 0x01, 0x02, 0x06, 0x07, - 0x01, 0x02, 0x04, 0x07, - 0x01, 0x07, 0x07, 0x07, - 0x01, 0x01, 0x07, 0x07, - 0x01, 0x01, 0x01, 0x07, - 0x01, 0x04, 0x05, 0x08, - 0x01, 0x04, 0x07, 0x08, - 0x01, 0x02, 0x07, 0x08, - 0x01, 0x02, 0x05, 0x08, - 0x01, 0x04, 0x06, 0x09, - 0x01, 0x05, 0x07, 0x09, - 0x01, 0x03, 0x07, 0x09, - 0x01, 0x03, 0x05, 0x09, - 0x01, 0x09, 0x09, 0x09, - 0x01, 0x01, 0x09, 0x09, - 0x01, 0x01, 0x01, 0x09, - 0x01, 0x05, 0x08, 0x0C, - 0x01, 0x06, 0x0A, 0x0C, - 0x01, 0x03, 0x0A, 0x0C, - 0x01, 0x03, 0x07, 0x0C, - 0x01, 0x0C, 0x0C, 0x0C, - 0x01, 0x01, 0x0C, 0x0C, - 0x01, 0x01, 0x01, 0x0C, - 0x01, 0x06, 0x0A, 0x0F, - 0x01, 0x08, 0x0C, 0x0F, - 0x01, 0x04, 0x0C, 0x0F, - 0x01, 0x04, 0x08, 0x0F, - 0x01, 0x0F, 0x0F, 0x0F, - 0x01, 0x01, 0x0F, 0x0F, - 0x01, 0x01, 0x01, 0x0F, - 0x01, 0x07, 0x0C, 0x12, - 0x01, 0x09, 0x0E, 0x12, - 0x01, 0x05, 0x0E, 0x12, - 0x01, 0x05, 0x0A, 0x12, - 0x01, 0x12, 0x12, 0x12, - 0x01, 0x01, 0x12, 0x12, - 0x01, 0x01, 0x01, 0x12, - 0x01, 0x08, 0x0E, 0x15, - 0x01, 0x0B, 0x10, 0x15, - 0x01, 0x06, 0x10, 0x15, - 0x01, 0x06, 0x0B, 0x15, - 0x01, 0x15, 0x15, 0x15, - 0x01, 0x01, 0x15, 0x15, - 0x01, 0x01, 0x01, 0x15, - 0x01, 0x0C, 0x13, 0x18, - 0x01, 0x06, 0x13, 0x18, - 0x01, 0x06, 0x0D, 0x18, - 0x01, 0x18, 0x18, 0x18, - 0x01, 0x01, 0x18, 0x18, - 0x01, 0x01, 0x01, 0x18, - 0x01, 0x0E, 0x15, 0x1B, - 0x01, 0x07, 0x15, 0x1B, - 0x01, 0x07, 0x0E, 0x1B, - 0x01, 0x1B, 0x1B, 0x1B, - 0x01, 0x01, 0x1B, 0x1B, - 0x01, 0x01, 0x01, 0x1B, - 0x01, 0x0F, 0x17, 0x1E, - 0x01, 0x08, 0x17, 0x1E, - 0x01, 0x08, 0x10, 0x1E, - 0x01, 0x1E, 0x1E, 0x1E, - 0x01, 0x01, 0x1E, 0x1E, - 0x01, 0x01, 0x01, 0x1E, - 0x01, 0x11, 0x19, 0x21, - 0x01, 0x09, 0x19, 0x21, - 0x01, 0x09, 0x11, 0x21, - 0x01, 0x21, 0x21, 0x21, - 0x01, 0x01, 0x21, 0x21, - 0x01, 0x01, 0x01, 0x21, - 0x01, 0x24, 0x24, 0x24, - 0x01, 0x01, 0x24, 0x24, - 0x01, 0x01, 0x01, 0x24, - 0x01, 0x13, 0x1C, 0x25, - 0x01, 0x0A, 0x1C, 0x25, - 0x01, 0x0A, 0x13, 0x25, - 0x01, 0x29, 0x29, 0x29, - 0x01, 0x01, 0x29, 0x29, - 0x01, 0x01, 0x01, 0x29, - 0x01, 0x2F, 0x2F, 0x2F, - 0x01, 0x01, 0x2F, 0x2F, - 0x01, 0x01, 0x01, 0x2F, - 0x02, 0x03, 0x03, 0x04, - 0x02, 0x03, 0x04, 0x05, - 0x02, 0x04, 0x05, 0x06, - 0x02, 0x03, 0x05, 0x06, - 0x02, 0x03, 0x04, 0x06, - 0x02, 0x04, 0x05, 0x07, - 0x02, 0x04, 0x06, 0x07, - 0x02, 0x03, 0x06, 0x07, - 0x02, 0x03, 0x05, 0x07, - 0x02, 0x04, 0x06, 0x08, - 0x02, 0x05, 0x07, 0x08, - 0x02, 0x03, 0x07, 0x08, - 0x02, 0x03, 0x05, 0x08, - 0x02, 0x08, 0x08, 0x08, - 0x02, 0x02, 0x08, 0x08, - 0x02, 0x02, 0x02, 0x08, - 0x02, 0x05, 0x06, 0x09, - 0x02, 0x05, 0x08, 0x09, - 0x02, 0x03, 0x08, 0x09, - 0x02, 0x03, 0x06, 0x09, - 0x02, 0x05, 0x07, 0x0A, - 0x02, 0x06, 0x08, 0x0A, - 0x02, 0x04, 0x08, 0x0A, - 0x02, 0x04, 0x06, 0x0A, - 0x02, 0x0A, 0x0A, 0x0A, - 0x02, 0x02, 0x0A, 0x0A, - 0x02, 0x02, 0x02, 0x0A, - 0x02, 0x06, 0x09, 0x0D, - 0x02, 0x07, 0x0B, 0x0D, - 0x02, 0x04, 0x0B, 0x0D, - 0x02, 0x04, 0x08, 0x0D, - 0x02, 0x0D, 0x0D, 0x0D, - 0x02, 0x02, 0x0D, 0x0D, - 0x02, 0x02, 0x02, 0x0D, - 0x02, 0x07, 0x0B, 0x10, - 0x02, 0x09, 0x0D, 0x10, - 0x02, 0x05, 0x0D, 0x10, - 0x02, 0x05, 0x09, 0x10, - 0x02, 0x10, 0x10, 0x10, - 0x02, 0x02, 0x10, 0x10, - 0x02, 0x02, 0x02, 0x10, - 0x02, 0x08, 0x0D, 0x13, - 0x02, 0x0A, 0x0F, 0x13, - 0x02, 0x06, 0x0F, 0x13, - 0x02, 0x06, 0x0B, 0x13, - 0x02, 0x13, 0x13, 0x13, - 0x02, 0x02, 0x13, 0x13, - 0x02, 0x02, 0x02, 0x13, - 0x02, 0x09, 0x0F, 0x16, - 0x02, 0x0C, 0x11, 0x16, - 0x02, 0x07, 0x11, 0x16, - 0x02, 0x07, 0x0C, 0x16, - 0x02, 0x16, 0x16, 0x16, - 0x02, 0x02, 0x16, 0x16, - 0x02, 0x02, 0x02, 0x16, - 0x02, 0x0D, 0x14, 0x19, - 0x02, 0x07, 0x14, 0x19, - 0x02, 0x07, 0x0E, 0x19, - 0x02, 0x19, 0x19, 0x19, - 0x02, 0x02, 0x19, 0x19, - 0x02, 0x02, 0x02, 0x19, - 0x02, 0x0F, 0x16, 0x1C, - 0x02, 0x08, 0x16, 0x1C, - 0x02, 0x08, 0x0F, 0x1C, - 0x02, 0x1C, 0x1C, 0x1C, - 0x02, 0x02, 0x1C, 0x1C, - 0x02, 0x02, 0x02, 0x1C, - 0x02, 0x10, 0x18, 0x1F, - 0x02, 0x09, 0x18, 0x1F, - 0x02, 0x09, 0x11, 0x1F, - 0x02, 0x1F, 0x1F, 0x1F, - 0x02, 0x02, 0x1F, 0x1F, - 0x02, 0x02, 0x02, 0x1F, - 0x02, 0x12, 0x1A, 0x22, - 0x02, 0x0A, 0x1A, 0x22, - 0x02, 0x0A, 0x12, 0x22, - 0x02, 0x22, 0x22, 0x22, - 0x02, 0x02, 0x22, 0x22, - 0x02, 0x02, 0x02, 0x22, - 0x02, 0x25, 0x25, 0x25, - 0x02, 0x02, 0x25, 0x25, - 0x02, 0x02, 0x02, 0x25, - 0x02, 0x14, 0x1D, 0x26, - 0x02, 0x0B, 0x1D, 0x26, - 0x02, 0x0B, 0x14, 0x26, - 0x02, 0x2A, 0x2A, 0x2A, - 0x02, 0x02, 0x2A, 0x2A, - 0x02, 0x02, 0x02, 0x2A, - 0x02, 0x30, 0x30, 0x30, - 0x02, 0x02, 0x30, 0x30, - 0x02, 0x02, 0x02, 0x30, - 0x03, 0x04, 0x04, 0x05, - 0x03, 0x04, 0x05, 0x06, - 0x03, 0x05, 0x06, 0x07, - 0x03, 0x04, 0x06, 0x07, - 0x03, 0x04, 0x05, 0x07, - 0x03, 0x05, 0x06, 0x08, - 0x03, 0x05, 0x07, 0x08, - 0x03, 0x04, 0x07, 0x08, - 0x03, 0x04, 0x06, 0x08, - 0x03, 0x05, 0x07, 0x09, - 0x03, 0x06, 0x08, 0x09, - 0x03, 0x04, 0x08, 0x09, - 0x03, 0x04, 0x06, 0x09, - 0x03, 0x09, 0x09, 0x09, - 0x03, 0x03, 0x09, 0x09, - 0x03, 0x03, 0x03, 0x09, - 0x03, 0x06, 0x07, 0x0A, - 0x03, 0x06, 0x09, 0x0A, - 0x03, 0x04, 0x09, 0x0A, - 0x03, 0x04, 0x07, 0x0A, - 0x03, 0x06, 0x08, 0x0B, - 0x03, 0x07, 0x09, 0x0B, - 0x03, 0x05, 0x09, 0x0B, - 0x03, 0x05, 0x07, 0x0B, - 0x03, 0x0B, 0x0B, 0x0B, - 0x03, 0x03, 0x0B, 0x0B, - 0x03, 0x03, 0x03, 0x0B, - 0x03, 0x07, 0x0A, 0x0E, - 0x03, 0x08, 0x0C, 0x0E, - 0x03, 0x05, 0x0C, 0x0E, - 0x03, 0x05, 0x09, 0x0E, - 0x03, 0x0E, 0x0E, 0x0E, - 0x03, 0x03, 0x0E, 0x0E, - 0x03, 0x03, 0x03, 0x0E, - 0x03, 0x08, 0x0C, 0x11, - 0x03, 0x0A, 0x0E, 0x11, - 0x03, 0x06, 0x0E, 0x11, - 0x03, 0x06, 0x0A, 0x11, - 0x03, 0x11, 0x11, 0x11, - 0x03, 0x03, 0x11, 0x11, - 0x03, 0x03, 0x03, 0x11, - 0x03, 0x09, 0x0E, 0x14, - 0x03, 0x0B, 0x10, 0x14, - 0x03, 0x07, 0x10, 0x14, - 0x03, 0x07, 0x0C, 0x14, - 0x03, 0x14, 0x14, 0x14, - 0x03, 0x03, 0x14, 0x14, - 0x03, 0x03, 0x03, 0x14, - 0x03, 0x0A, 0x10, 0x17, - 0x03, 0x0D, 0x12, 0x17, - 0x03, 0x08, 0x12, 0x17, - 0x03, 0x08, 0x0D, 0x17, - 0x03, 0x17, 0x17, 0x17, - 0x03, 0x03, 0x17, 0x17, - 0x03, 0x03, 0x03, 0x17, - 0x03, 0x0E, 0x15, 0x1A, - 0x03, 0x08, 0x15, 0x1A, - 0x03, 0x08, 0x0F, 0x1A, - 0x03, 0x1A, 0x1A, 0x1A, - 0x03, 0x03, 0x1A, 0x1A, - 0x03, 0x03, 0x03, 0x1A, - 0x03, 0x10, 0x17, 0x1D, - 0x03, 0x09, 0x17, 0x1D, - 0x03, 0x09, 0x10, 0x1D, - 0x03, 0x1D, 0x1D, 0x1D, - 0x03, 0x03, 0x1D, 0x1D, - 0x03, 0x03, 0x03, 0x1D, - 0x03, 0x11, 0x19, 0x20, - 0x03, 0x0A, 0x19, 0x20, - 0x03, 0x0A, 0x12, 0x20, - 0x03, 0x20, 0x20, 0x20, - 0x03, 0x03, 0x20, 0x20, - 0x03, 0x03, 0x03, 0x20, - 0x03, 0x13, 0x1B, 0x23, - 0x03, 0x0B, 0x1B, 0x23, - 0x03, 0x0B, 0x13, 0x23, - 0x03, 0x23, 0x23, 0x23, - 0x03, 0x03, 0x23, 0x23, - 0x03, 0x03, 0x03, 0x23, - 0x03, 0x26, 0x26, 0x26, - 0x03, 0x03, 0x26, 0x26, - 0x03, 0x03, 0x03, 0x26, - 0x03, 0x15, 0x1E, 0x27, - 0x03, 0x0C, 0x1E, 0x27, - 0x03, 0x0C, 0x15, 0x27, - 0x03, 0x2B, 0x2B, 0x2B, - 0x03, 0x03, 0x2B, 0x2B, - 0x03, 0x03, 0x03, 0x2B, - 0x03, 0x31, 0x31, 0x31, - 0x03, 0x03, 0x31, 0x31, - 0x03, 0x03, 0x03, 0x31, - 0x04, 0x05, 0x05, 0x06, - 0x04, 0x05, 0x06, 0x07, - 0x04, 0x06, 0x07, 0x08, - 0x04, 0x05, 0x07, 0x08, - 0x04, 0x05, 0x06, 0x08, - 0x04, 0x06, 0x07, 0x09, - 0x04, 0x06, 0x08, 0x09, - 0x04, 0x05, 0x08, 0x09, - 0x04, 0x05, 0x07, 0x09, - 0x04, 0x06, 0x08, 0x0A, - 0x04, 0x07, 0x09, 0x0A, - 0x04, 0x05, 0x09, 0x0A, - 0x04, 0x05, 0x07, 0x0A, - 0x04, 0x0A, 0x0A, 0x0A, - 0x04, 0x04, 0x0A, 0x0A, - 0x04, 0x04, 0x04, 0x0A, - 0x04, 0x07, 0x08, 0x0B, - 0x04, 0x07, 0x0A, 0x0B, - 0x04, 0x05, 0x0A, 0x0B, - 0x04, 0x05, 0x08, 0x0B, - 0x04, 0x07, 0x09, 0x0C, - 0x04, 0x08, 0x0A, 0x0C, - 0x04, 0x06, 0x0A, 0x0C, - 0x04, 0x06, 0x08, 0x0C, - 0x04, 0x0C, 0x0C, 0x0C, - 0x04, 0x04, 0x0C, 0x0C, - 0x04, 0x04, 0x04, 0x0C, - 0x04, 0x08, 0x0B, 0x0F, - 0x04, 0x09, 0x0D, 0x0F, - 0x04, 0x06, 0x0D, 0x0F, - 0x04, 0x06, 0x0A, 0x0F, - 0x04, 0x0F, 0x0F, 0x0F, - 0x04, 0x04, 0x0F, 0x0F, - 0x04, 0x04, 0x04, 0x0F, - 0x04, 0x09, 0x0D, 0x12, - 0x04, 0x0B, 0x0F, 0x12, - 0x04, 0x07, 0x0F, 0x12, - 0x04, 0x07, 0x0B, 0x12, - 0x04, 0x12, 0x12, 0x12, - 0x04, 0x04, 0x12, 0x12, - 0x04, 0x04, 0x04, 0x12, - 0x04, 0x0A, 0x0F, 0x15, - 0x04, 0x0C, 0x11, 0x15, - 0x04, 0x08, 0x11, 0x15, - 0x04, 0x08, 0x0D, 0x15, - 0x04, 0x15, 0x15, 0x15, - 0x04, 0x04, 0x15, 0x15, - 0x04, 0x04, 0x04, 0x15, - 0x04, 0x0B, 0x11, 0x18, - 0x04, 0x0E, 0x13, 0x18, - 0x04, 0x09, 0x13, 0x18, - 0x04, 0x09, 0x0E, 0x18, - 0x04, 0x18, 0x18, 0x18, - 0x04, 0x04, 0x18, 0x18, - 0x04, 0x04, 0x04, 0x18, - 0x04, 0x0F, 0x16, 0x1B, - 0x04, 0x09, 0x16, 0x1B, - 0x04, 0x09, 0x10, 0x1B, - 0x04, 0x1B, 0x1B, 0x1B, - 0x04, 0x04, 0x1B, 0x1B, - 0x04, 0x04, 0x04, 0x1B, - 0x04, 0x11, 0x18, 0x1E, - 0x04, 0x0A, 0x18, 0x1E, - 0x04, 0x0A, 0x11, 0x1E, - 0x04, 0x1E, 0x1E, 0x1E, - 0x04, 0x04, 0x1E, 0x1E, - 0x04, 0x04, 0x04, 0x1E, - 0x04, 0x12, 0x1A, 0x21, - 0x04, 0x0B, 0x1A, 0x21, - 0x04, 0x0B, 0x13, 0x21, - 0x04, 0x21, 0x21, 0x21, - 0x04, 0x04, 0x21, 0x21, - 0x04, 0x04, 0x04, 0x21, - 0x04, 0x14, 0x1C, 0x24, - 0x04, 0x0C, 0x1C, 0x24, - 0x04, 0x0C, 0x14, 0x24, - 0x04, 0x24, 0x24, 0x24, - 0x04, 0x04, 0x24, 0x24, - 0x04, 0x04, 0x04, 0x24, - 0x04, 0x27, 0x27, 0x27, - 0x04, 0x04, 0x27, 0x27, - 0x04, 0x04, 0x04, 0x27, - 0x04, 0x16, 0x1F, 0x28, - 0x04, 0x0D, 0x1F, 0x28, - 0x04, 0x0D, 0x16, 0x28, - 0x04, 0x2C, 0x2C, 0x2C, - 0x04, 0x04, 0x2C, 0x2C, - 0x04, 0x04, 0x04, 0x2C, - 0x04, 0x32, 0x32, 0x32, - 0x04, 0x04, 0x32, 0x32, - 0x04, 0x04, 0x04, 0x32, - 0x05, 0x06, 0x06, 0x07, - 0x05, 0x06, 0x07, 0x08, - 0x05, 0x07, 0x08, 0x09, - 0x05, 0x06, 0x08, 0x09, - 0x05, 0x06, 0x07, 0x09, - 0x05, 0x07, 0x08, 0x0A, - 0x05, 0x07, 0x09, 0x0A, - 0x05, 0x06, 0x09, 0x0A, - 0x05, 0x06, 0x08, 0x0A, - 0x05, 0x07, 0x09, 0x0B, - 0x05, 0x08, 0x0A, 0x0B, - 0x05, 0x06, 0x0A, 0x0B, - 0x05, 0x06, 0x08, 0x0B, - 0x05, 0x0B, 0x0B, 0x0B, - 0x05, 0x05, 0x0B, 0x0B, - 0x05, 0x05, 0x05, 0x0B, - 0x05, 0x08, 0x09, 0x0C, - 0x05, 0x08, 0x0B, 0x0C, - 0x05, 0x06, 0x0B, 0x0C, - 0x05, 0x06, 0x09, 0x0C, - 0x05, 0x08, 0x0A, 0x0D, - 0x05, 0x09, 0x0B, 0x0D, - 0x05, 0x07, 0x0B, 0x0D, - 0x05, 0x07, 0x09, 0x0D, - 0x05, 0x0D, 0x0D, 0x0D, - 0x05, 0x05, 0x0D, 0x0D, - 0x05, 0x05, 0x05, 0x0D, - 0x05, 0x09, 0x0C, 0x10, - 0x05, 0x0A, 0x0E, 0x10, - 0x05, 0x07, 0x0E, 0x10, - 0x05, 0x07, 0x0B, 0x10, - 0x05, 0x10, 0x10, 0x10, - 0x05, 0x05, 0x10, 0x10, - 0x05, 0x05, 0x05, 0x10, - 0x05, 0x0A, 0x0E, 0x13, - 0x05, 0x0C, 0x10, 0x13, - 0x05, 0x08, 0x10, 0x13, - 0x05, 0x08, 0x0C, 0x13, - 0x05, 0x13, 0x13, 0x13, - 0x05, 0x05, 0x13, 0x13, - 0x05, 0x05, 0x05, 0x13, - 0x05, 0x0B, 0x10, 0x16, - 0x05, 0x0D, 0x12, 0x16, - 0x05, 0x09, 0x12, 0x16, - 0x05, 0x09, 0x0E, 0x16, - 0x05, 0x16, 0x16, 0x16, - 0x05, 0x05, 0x16, 0x16, - 0x05, 0x05, 0x05, 0x16, - 0x05, 0x0C, 0x12, 0x19, - 0x05, 0x0F, 0x14, 0x19, - 0x05, 0x0A, 0x14, 0x19, - 0x05, 0x0A, 0x0F, 0x19, - 0x05, 0x19, 0x19, 0x19, - 0x05, 0x05, 0x19, 0x19, - 0x05, 0x05, 0x05, 0x19, - 0x05, 0x10, 0x17, 0x1C, - 0x05, 0x0A, 0x17, 0x1C, - 0x05, 0x0A, 0x11, 0x1C, - 0x05, 0x1C, 0x1C, 0x1C, - 0x05, 0x05, 0x1C, 0x1C, - 0x05, 0x05, 0x05, 0x1C, - 0x05, 0x12, 0x19, 0x1F, - 0x05, 0x0B, 0x19, 0x1F, - 0x05, 0x0B, 0x12, 0x1F, - 0x05, 0x1F, 0x1F, 0x1F, - 0x05, 0x05, 0x1F, 0x1F, - 0x05, 0x05, 0x05, 0x1F, - 0x05, 0x13, 0x1B, 0x22, - 0x05, 0x0C, 0x1B, 0x22, - 0x05, 0x0C, 0x14, 0x22, - 0x05, 0x22, 0x22, 0x22, - 0x05, 0x05, 0x22, 0x22, - 0x05, 0x05, 0x05, 0x22, - 0x05, 0x15, 0x1D, 0x25, - 0x05, 0x0D, 0x1D, 0x25, - 0x05, 0x0D, 0x15, 0x25, - 0x05, 0x25, 0x25, 0x25, - 0x05, 0x05, 0x25, 0x25, - 0x05, 0x05, 0x05, 0x25, - 0x05, 0x28, 0x28, 0x28, - 0x05, 0x05, 0x28, 0x28, - 0x05, 0x05, 0x05, 0x28, - 0x05, 0x17, 0x20, 0x29, - 0x05, 0x0E, 0x20, 0x29, - 0x05, 0x0E, 0x17, 0x29, - 0x05, 0x2D, 0x2D, 0x2D, - 0x05, 0x05, 0x2D, 0x2D, - 0x05, 0x05, 0x05, 0x2D, - 0x05, 0x33, 0x33, 0x33, - 0x05, 0x05, 0x33, 0x33, - 0x05, 0x05, 0x05, 0x33, - 0x06, 0x07, 0x07, 0x08, - 0x06, 0x07, 0x08, 0x09, - 0x06, 0x08, 0x09, 0x0A, - 0x06, 0x07, 0x09, 0x0A, - 0x06, 0x07, 0x08, 0x0A, - 0x06, 0x08, 0x09, 0x0B, - 0x06, 0x08, 0x0A, 0x0B, - 0x06, 0x07, 0x0A, 0x0B, - 0x06, 0x07, 0x09, 0x0B, - 0x06, 0x08, 0x0A, 0x0C, - 0x06, 0x09, 0x0B, 0x0C, - 0x06, 0x07, 0x0B, 0x0C, - 0x06, 0x07, 0x09, 0x0C, - 0x06, 0x0C, 0x0C, 0x0C, - 0x06, 0x06, 0x0C, 0x0C, - 0x06, 0x06, 0x06, 0x0C, - 0x06, 0x09, 0x0A, 0x0D, - 0x06, 0x09, 0x0C, 0x0D, - 0x06, 0x07, 0x0C, 0x0D, - 0x06, 0x07, 0x0A, 0x0D, - 0x06, 0x09, 0x0B, 0x0E, - 0x06, 0x0A, 0x0C, 0x0E, - 0x06, 0x08, 0x0C, 0x0E, - 0x06, 0x08, 0x0A, 0x0E, - 0x06, 0x0E, 0x0E, 0x0E, - 0x06, 0x06, 0x0E, 0x0E, - 0x06, 0x06, 0x06, 0x0E, - 0x06, 0x0A, 0x0D, 0x11, - 0x06, 0x0B, 0x0F, 0x11, - 0x06, 0x08, 0x0F, 0x11, - 0x06, 0x08, 0x0C, 0x11, - 0x06, 0x11, 0x11, 0x11, - 0x06, 0x06, 0x11, 0x11, - 0x06, 0x06, 0x06, 0x11, - 0x06, 0x0B, 0x0F, 0x14, - 0x06, 0x0D, 0x11, 0x14, - 0x06, 0x09, 0x11, 0x14, - 0x06, 0x09, 0x0D, 0x14, - 0x06, 0x14, 0x14, 0x14, - 0x06, 0x06, 0x14, 0x14, - 0x06, 0x06, 0x06, 0x14, - 0x06, 0x0C, 0x11, 0x17, - 0x06, 0x0E, 0x13, 0x17, - 0x06, 0x0A, 0x13, 0x17, - 0x06, 0x0A, 0x0F, 0x17, - 0x06, 0x17, 0x17, 0x17, - 0x06, 0x06, 0x17, 0x17, - 0x06, 0x06, 0x06, 0x17, - 0x06, 0x0D, 0x13, 0x1A, - 0x06, 0x10, 0x15, 0x1A, - 0x06, 0x0B, 0x15, 0x1A, - 0x06, 0x0B, 0x10, 0x1A, - 0x06, 0x1A, 0x1A, 0x1A, - 0x06, 0x06, 0x1A, 0x1A, - 0x06, 0x06, 0x06, 0x1A, - 0x06, 0x11, 0x18, 0x1D, - 0x06, 0x0B, 0x18, 0x1D, - 0x06, 0x0B, 0x12, 0x1D, - 0x06, 0x1D, 0x1D, 0x1D, - 0x06, 0x06, 0x1D, 0x1D, - 0x06, 0x06, 0x06, 0x1D, - 0x06, 0x13, 0x1A, 0x20, - 0x06, 0x0C, 0x1A, 0x20, - 0x06, 0x0C, 0x13, 0x20, - 0x06, 0x20, 0x20, 0x20, - 0x06, 0x06, 0x20, 0x20, - 0x06, 0x06, 0x06, 0x20, - 0x06, 0x14, 0x1C, 0x23, - 0x06, 0x0D, 0x1C, 0x23, - 0x06, 0x0D, 0x15, 0x23, - 0x06, 0x23, 0x23, 0x23, - 0x06, 0x06, 0x23, 0x23, - 0x06, 0x06, 0x06, 0x23, - 0x06, 0x16, 0x1E, 0x26, - 0x06, 0x0E, 0x1E, 0x26, - 0x06, 0x0E, 0x16, 0x26, - 0x06, 0x26, 0x26, 0x26, - 0x06, 0x06, 0x26, 0x26, - 0x06, 0x06, 0x06, 0x26, - 0x06, 0x29, 0x29, 0x29, - 0x06, 0x06, 0x29, 0x29, - 0x06, 0x06, 0x06, 0x29, - 0x06, 0x18, 0x21, 0x2A, - 0x06, 0x0F, 0x21, 0x2A, - 0x06, 0x0F, 0x18, 0x2A, - 0x06, 0x2E, 0x2E, 0x2E, - 0x06, 0x06, 0x2E, 0x2E, - 0x06, 0x06, 0x06, 0x2E, - 0x06, 0x34, 0x34, 0x34, - 0x06, 0x06, 0x34, 0x34, - 0x06, 0x06, 0x06, 0x34, - 0x07, 0x08, 0x08, 0x09, - 0x07, 0x08, 0x09, 0x0A, - 0x07, 0x09, 0x0A, 0x0B, - 0x07, 0x08, 0x0A, 0x0B, - 0x07, 0x08, 0x09, 0x0B, - 0x07, 0x09, 0x0A, 0x0C, - 0x07, 0x09, 0x0B, 0x0C, - 0x07, 0x08, 0x0B, 0x0C, - 0x07, 0x08, 0x0A, 0x0C, - 0x07, 0x09, 0x0B, 0x0D, - 0x07, 0x0A, 0x0C, 0x0D, - 0x07, 0x08, 0x0C, 0x0D, - 0x07, 0x08, 0x0A, 0x0D, - 0x07, 0x0D, 0x0D, 0x0D, - 0x07, 0x07, 0x0D, 0x0D, - 0x07, 0x07, 0x07, 0x0D, - 0x07, 0x0A, 0x0B, 0x0E, - 0x07, 0x0A, 0x0D, 0x0E, - 0x07, 0x08, 0x0D, 0x0E, - 0x07, 0x08, 0x0B, 0x0E, - 0x07, 0x0A, 0x0C, 0x0F, - 0x07, 0x0B, 0x0D, 0x0F, - 0x07, 0x09, 0x0D, 0x0F, - 0x07, 0x09, 0x0B, 0x0F, - 0x07, 0x0F, 0x0F, 0x0F, - 0x07, 0x07, 0x0F, 0x0F, - 0x07, 0x07, 0x07, 0x0F, - 0x07, 0x0B, 0x0E, 0x12, - 0x07, 0x0C, 0x10, 0x12, - 0x07, 0x09, 0x10, 0x12, - 0x07, 0x09, 0x0D, 0x12, - 0x07, 0x12, 0x12, 0x12, - 0x07, 0x07, 0x12, 0x12, - 0x07, 0x07, 0x07, 0x12, - 0x07, 0x0C, 0x10, 0x15, - 0x07, 0x0E, 0x12, 0x15, - 0x07, 0x0A, 0x12, 0x15, - 0x07, 0x0A, 0x0E, 0x15, - 0x07, 0x15, 0x15, 0x15, - 0x07, 0x07, 0x15, 0x15, - 0x07, 0x07, 0x07, 0x15, - 0x07, 0x0D, 0x12, 0x18, - 0x07, 0x0F, 0x14, 0x18, - 0x07, 0x0B, 0x14, 0x18, - 0x07, 0x0B, 0x10, 0x18, - 0x07, 0x18, 0x18, 0x18, - 0x07, 0x07, 0x18, 0x18, - 0x07, 0x07, 0x07, 0x18, - 0x07, 0x0E, 0x14, 0x1B, - 0x07, 0x11, 0x16, 0x1B, - 0x07, 0x0C, 0x16, 0x1B, - 0x07, 0x0C, 0x11, 0x1B, - 0x07, 0x1B, 0x1B, 0x1B, - 0x07, 0x07, 0x1B, 0x1B, - 0x07, 0x07, 0x07, 0x1B, - 0x07, 0x12, 0x19, 0x1E, - 0x07, 0x0C, 0x19, 0x1E, - 0x07, 0x0C, 0x13, 0x1E, - 0x07, 0x1E, 0x1E, 0x1E, - 0x07, 0x07, 0x1E, 0x1E, - 0x07, 0x07, 0x07, 0x1E, - 0x07, 0x14, 0x1B, 0x21, - 0x07, 0x0D, 0x1B, 0x21, - 0x07, 0x0D, 0x14, 0x21, - 0x07, 0x21, 0x21, 0x21, - 0x07, 0x07, 0x21, 0x21, - 0x07, 0x07, 0x07, 0x21, - 0x07, 0x15, 0x1D, 0x24, - 0x07, 0x0E, 0x1D, 0x24, - 0x07, 0x0E, 0x16, 0x24, - 0x07, 0x24, 0x24, 0x24, - 0x07, 0x07, 0x24, 0x24, - 0x07, 0x07, 0x07, 0x24, - 0x07, 0x17, 0x1F, 0x27, - 0x07, 0x0F, 0x1F, 0x27, - 0x07, 0x0F, 0x17, 0x27, - 0x07, 0x27, 0x27, 0x27, - 0x07, 0x07, 0x27, 0x27, - 0x07, 0x07, 0x07, 0x27, - 0x07, 0x2A, 0x2A, 0x2A, - 0x07, 0x07, 0x2A, 0x2A, - 0x07, 0x07, 0x07, 0x2A, - 0x07, 0x19, 0x22, 0x2B, - 0x07, 0x10, 0x22, 0x2B, - 0x07, 0x10, 0x19, 0x2B, - 0x07, 0x2F, 0x2F, 0x2F, - 0x07, 0x07, 0x2F, 0x2F, - 0x07, 0x07, 0x07, 0x2F, - 0x07, 0x35, 0x35, 0x35, - 0x07, 0x07, 0x35, 0x35, - 0x07, 0x07, 0x07, 0x35, - 0x08, 0x09, 0x09, 0x0A, - 0x08, 0x09, 0x0A, 0x0B, - 0x08, 0x0A, 0x0B, 0x0C, - 0x08, 0x09, 0x0B, 0x0C, - 0x08, 0x09, 0x0A, 0x0C, - 0x08, 0x0A, 0x0B, 0x0D, - 0x08, 0x0A, 0x0C, 0x0D, - 0x08, 0x09, 0x0C, 0x0D, - 0x08, 0x09, 0x0B, 0x0D, - 0x08, 0x0A, 0x0C, 0x0E, - 0x08, 0x0B, 0x0D, 0x0E, - 0x08, 0x09, 0x0D, 0x0E, - 0x08, 0x09, 0x0B, 0x0E, - 0x08, 0x0E, 0x0E, 0x0E, - 0x08, 0x08, 0x0E, 0x0E, - 0x08, 0x08, 0x08, 0x0E, - 0x08, 0x0B, 0x0C, 0x0F, - 0x08, 0x0B, 0x0E, 0x0F, - 0x08, 0x09, 0x0E, 0x0F, - 0x08, 0x09, 0x0C, 0x0F, - 0x08, 0x0B, 0x0D, 0x10, - 0x08, 0x0C, 0x0E, 0x10, - 0x08, 0x0A, 0x0E, 0x10, - 0x08, 0x0A, 0x0C, 0x10, - 0x08, 0x10, 0x10, 0x10, - 0x08, 0x08, 0x10, 0x10, - 0x08, 0x08, 0x08, 0x10, - 0x08, 0x0C, 0x0F, 0x13, - 0x08, 0x0D, 0x11, 0x13, - 0x08, 0x0A, 0x11, 0x13, - 0x08, 0x0A, 0x0E, 0x13, - 0x08, 0x13, 0x13, 0x13, - 0x08, 0x08, 0x13, 0x13, - 0x08, 0x08, 0x08, 0x13, - 0x08, 0x0D, 0x11, 0x16, - 0x08, 0x0F, 0x13, 0x16, - 0x08, 0x0B, 0x13, 0x16, - 0x08, 0x0B, 0x0F, 0x16, - 0x08, 0x16, 0x16, 0x16, - 0x08, 0x08, 0x16, 0x16, - 0x08, 0x08, 0x08, 0x16, - 0x08, 0x0E, 0x13, 0x19, - 0x08, 0x10, 0x15, 0x19, - 0x08, 0x0C, 0x15, 0x19, - 0x08, 0x0C, 0x11, 0x19, - 0x08, 0x19, 0x19, 0x19, - 0x08, 0x08, 0x19, 0x19, - 0x08, 0x08, 0x08, 0x19, - 0x08, 0x0F, 0x15, 0x1C, - 0x08, 0x12, 0x17, 0x1C, - 0x08, 0x0D, 0x17, 0x1C, - 0x08, 0x0D, 0x12, 0x1C, - 0x08, 0x1C, 0x1C, 0x1C, - 0x08, 0x08, 0x1C, 0x1C, - 0x08, 0x08, 0x08, 0x1C, - 0x08, 0x13, 0x1A, 0x1F, - 0x08, 0x0D, 0x1A, 0x1F, - 0x08, 0x0D, 0x14, 0x1F, - 0x08, 0x1F, 0x1F, 0x1F, - 0x08, 0x08, 0x1F, 0x1F, - 0x08, 0x08, 0x08, 0x1F, - 0x08, 0x15, 0x1C, 0x22, - 0x08, 0x0E, 0x1C, 0x22, - 0x08, 0x0E, 0x15, 0x22, - 0x08, 0x22, 0x22, 0x22, - 0x08, 0x08, 0x22, 0x22, - 0x08, 0x08, 0x08, 0x22, - 0x08, 0x16, 0x1E, 0x25, - 0x08, 0x0F, 0x1E, 0x25, - 0x08, 0x0F, 0x17, 0x25, - 0x08, 0x25, 0x25, 0x25, - 0x08, 0x08, 0x25, 0x25, - 0x08, 0x08, 0x08, 0x25, - 0x08, 0x18, 0x20, 0x28, - 0x08, 0x10, 0x20, 0x28, - 0x08, 0x10, 0x18, 0x28, - 0x08, 0x28, 0x28, 0x28, - 0x08, 0x08, 0x28, 0x28, - 0x08, 0x08, 0x08, 0x28, - 0x08, 0x2B, 0x2B, 0x2B, - 0x08, 0x08, 0x2B, 0x2B, - 0x08, 0x08, 0x08, 0x2B, - 0x08, 0x1A, 0x23, 0x2C, - 0x08, 0x11, 0x23, 0x2C, - 0x08, 0x11, 0x1A, 0x2C, - 0x08, 0x30, 0x30, 0x30, - 0x08, 0x08, 0x30, 0x30, - 0x08, 0x08, 0x08, 0x30, - 0x08, 0x36, 0x36, 0x36, - 0x08, 0x08, 0x36, 0x36, - 0x08, 0x08, 0x08, 0x36, - 0x09, 0x0A, 0x0A, 0x0B, - 0x09, 0x0A, 0x0B, 0x0C, - 0x09, 0x0B, 0x0C, 0x0D, - 0x09, 0x0A, 0x0C, 0x0D, - 0x09, 0x0A, 0x0B, 0x0D, - 0x09, 0x0B, 0x0C, 0x0E, - 0x09, 0x0B, 0x0D, 0x0E, - 0x09, 0x0A, 0x0D, 0x0E, - 0x09, 0x0A, 0x0C, 0x0E, - 0x09, 0x0B, 0x0D, 0x0F, - 0x09, 0x0C, 0x0E, 0x0F, - 0x09, 0x0A, 0x0E, 0x0F, - 0x09, 0x0A, 0x0C, 0x0F, - 0x09, 0x0F, 0x0F, 0x0F, - 0x09, 0x09, 0x0F, 0x0F, - 0x09, 0x09, 0x09, 0x0F, - 0x09, 0x0C, 0x0D, 0x10, - 0x09, 0x0C, 0x0F, 0x10, - 0x09, 0x0A, 0x0F, 0x10, - 0x09, 0x0A, 0x0D, 0x10, - 0x09, 0x0C, 0x0E, 0x11, - 0x09, 0x0D, 0x0F, 0x11, - 0x09, 0x0B, 0x0F, 0x11, - 0x09, 0x0B, 0x0D, 0x11, - 0x09, 0x11, 0x11, 0x11, - 0x09, 0x09, 0x11, 0x11, - 0x09, 0x09, 0x09, 0x11, - 0x09, 0x0D, 0x10, 0x14, - 0x09, 0x0E, 0x12, 0x14, - 0x09, 0x0B, 0x12, 0x14, - 0x09, 0x0B, 0x0F, 0x14, - 0x09, 0x14, 0x14, 0x14, - 0x09, 0x09, 0x14, 0x14, - 0x09, 0x09, 0x09, 0x14, - 0x09, 0x0E, 0x12, 0x17, - 0x09, 0x10, 0x14, 0x17, - 0x09, 0x0C, 0x14, 0x17, - 0x09, 0x0C, 0x10, 0x17, - 0x09, 0x17, 0x17, 0x17, - 0x09, 0x09, 0x17, 0x17, - 0x09, 0x09, 0x09, 0x17, - 0x09, 0x0F, 0x14, 0x1A, - 0x09, 0x11, 0x16, 0x1A, - 0x09, 0x0D, 0x16, 0x1A, - 0x09, 0x0D, 0x12, 0x1A, - 0x09, 0x1A, 0x1A, 0x1A, - 0x09, 0x09, 0x1A, 0x1A, - 0x09, 0x09, 0x09, 0x1A, - 0x09, 0x10, 0x16, 0x1D, - 0x09, 0x13, 0x18, 0x1D, - 0x09, 0x0E, 0x18, 0x1D, - 0x09, 0x0E, 0x13, 0x1D, - 0x09, 0x1D, 0x1D, 0x1D, - 0x09, 0x09, 0x1D, 0x1D, - 0x09, 0x09, 0x09, 0x1D, - 0x09, 0x14, 0x1B, 0x20, - 0x09, 0x0E, 0x1B, 0x20, - 0x09, 0x0E, 0x15, 0x20, - 0x09, 0x20, 0x20, 0x20, - 0x09, 0x09, 0x20, 0x20, - 0x09, 0x09, 0x09, 0x20, - 0x09, 0x16, 0x1D, 0x23, - 0x09, 0x0F, 0x1D, 0x23, - 0x09, 0x0F, 0x16, 0x23, - 0x09, 0x23, 0x23, 0x23, - 0x09, 0x09, 0x23, 0x23, - 0x09, 0x09, 0x09, 0x23, - 0x09, 0x17, 0x1F, 0x26, - 0x09, 0x10, 0x1F, 0x26, - 0x09, 0x10, 0x18, 0x26, - 0x09, 0x26, 0x26, 0x26, - 0x09, 0x09, 0x26, 0x26, - 0x09, 0x09, 0x09, 0x26, - 0x09, 0x19, 0x21, 0x29, - 0x09, 0x11, 0x21, 0x29, - 0x09, 0x11, 0x19, 0x29, - 0x09, 0x29, 0x29, 0x29, - 0x09, 0x09, 0x29, 0x29, - 0x09, 0x09, 0x09, 0x29, - 0x09, 0x2C, 0x2C, 0x2C, - 0x09, 0x09, 0x2C, 0x2C, - 0x09, 0x09, 0x09, 0x2C, - 0x09, 0x1B, 0x24, 0x2D, - 0x09, 0x12, 0x24, 0x2D, - 0x09, 0x12, 0x1B, 0x2D, - 0x09, 0x31, 0x31, 0x31, - 0x09, 0x09, 0x31, 0x31, - 0x09, 0x09, 0x09, 0x31, - 0x09, 0x37, 0x37, 0x37, - 0x09, 0x09, 0x37, 0x37, - 0x09, 0x09, 0x09, 0x37, - 0x0A, 0x0B, 0x0B, 0x0C, - 0x0A, 0x0B, 0x0C, 0x0D, - 0x0A, 0x0C, 0x0D, 0x0E, - 0x0A, 0x0B, 0x0D, 0x0E, - 0x0A, 0x0B, 0x0C, 0x0E, - 0x0A, 0x0C, 0x0D, 0x0F, - 0x0A, 0x0C, 0x0E, 0x0F, - 0x0A, 0x0B, 0x0E, 0x0F, - 0x0A, 0x0B, 0x0D, 0x0F, - 0x0A, 0x0C, 0x0E, 0x10, - 0x0A, 0x0D, 0x0F, 0x10, - 0x0A, 0x0B, 0x0F, 0x10, - 0x0A, 0x0B, 0x0D, 0x10, - 0x0A, 0x10, 0x10, 0x10, - 0x0A, 0x0A, 0x10, 0x10, - 0x0A, 0x0A, 0x0A, 0x10, - 0x0A, 0x0D, 0x0E, 0x11, - 0x0A, 0x0D, 0x10, 0x11, - 0x0A, 0x0B, 0x10, 0x11, - 0x0A, 0x0B, 0x0E, 0x11, - 0x0A, 0x0D, 0x0F, 0x12, - 0x0A, 0x0E, 0x10, 0x12, - 0x0A, 0x0C, 0x10, 0x12, - 0x0A, 0x0C, 0x0E, 0x12, - 0x0A, 0x12, 0x12, 0x12, - 0x0A, 0x0A, 0x12, 0x12, - 0x0A, 0x0A, 0x0A, 0x12, - 0x0A, 0x0E, 0x11, 0x15, - 0x0A, 0x0F, 0x13, 0x15, - 0x0A, 0x0C, 0x13, 0x15, - 0x0A, 0x0C, 0x10, 0x15, - 0x0A, 0x15, 0x15, 0x15, - 0x0A, 0x0A, 0x15, 0x15, - 0x0A, 0x0A, 0x0A, 0x15, - 0x0A, 0x0F, 0x13, 0x18, - 0x0A, 0x11, 0x15, 0x18, - 0x0A, 0x0D, 0x15, 0x18, - 0x0A, 0x0D, 0x11, 0x18, - 0x0A, 0x18, 0x18, 0x18, - 0x0A, 0x0A, 0x18, 0x18, - 0x0A, 0x0A, 0x0A, 0x18, - 0x0A, 0x10, 0x15, 0x1B, - 0x0A, 0x12, 0x17, 0x1B, - 0x0A, 0x0E, 0x17, 0x1B, - 0x0A, 0x0E, 0x13, 0x1B, - 0x0A, 0x1B, 0x1B, 0x1B, - 0x0A, 0x0A, 0x1B, 0x1B, - 0x0A, 0x0A, 0x0A, 0x1B, - 0x0A, 0x11, 0x17, 0x1E, - 0x0A, 0x14, 0x19, 0x1E, - 0x0A, 0x0F, 0x19, 0x1E, - 0x0A, 0x0F, 0x14, 0x1E, - 0x0A, 0x1E, 0x1E, 0x1E, - 0x0A, 0x0A, 0x1E, 0x1E, - 0x0A, 0x0A, 0x0A, 0x1E, - 0x0A, 0x15, 0x1C, 0x21, - 0x0A, 0x0F, 0x1C, 0x21, - 0x0A, 0x0F, 0x16, 0x21, - 0x0A, 0x21, 0x21, 0x21, - 0x0A, 0x0A, 0x21, 0x21, - 0x0A, 0x0A, 0x0A, 0x21, - 0x0A, 0x17, 0x1E, 0x24, - 0x0A, 0x10, 0x1E, 0x24, - 0x0A, 0x10, 0x17, 0x24, - 0x0A, 0x24, 0x24, 0x24, - 0x0A, 0x0A, 0x24, 0x24, - 0x0A, 0x0A, 0x0A, 0x24, - 0x0A, 0x18, 0x20, 0x27, - 0x0A, 0x11, 0x20, 0x27, - 0x0A, 0x11, 0x19, 0x27, - 0x0A, 0x27, 0x27, 0x27, - 0x0A, 0x0A, 0x27, 0x27, - 0x0A, 0x0A, 0x0A, 0x27, - 0x0A, 0x1A, 0x22, 0x2A, - 0x0A, 0x12, 0x22, 0x2A, - 0x0A, 0x12, 0x1A, 0x2A, - 0x0A, 0x2A, 0x2A, 0x2A, - 0x0A, 0x0A, 0x2A, 0x2A, - 0x0A, 0x0A, 0x0A, 0x2A, - 0x0A, 0x2D, 0x2D, 0x2D, - 0x0A, 0x0A, 0x2D, 0x2D, - 0x0A, 0x0A, 0x0A, 0x2D, - 0x0A, 0x1C, 0x25, 0x2E, - 0x0A, 0x13, 0x25, 0x2E, - 0x0A, 0x13, 0x1C, 0x2E, - 0x0A, 0x32, 0x32, 0x32, - 0x0A, 0x0A, 0x32, 0x32, - 0x0A, 0x0A, 0x0A, 0x32, - 0x0A, 0x38, 0x38, 0x38, - 0x0A, 0x0A, 0x38, 0x38, - 0x0A, 0x0A, 0x0A, 0x38, - 0x0B, 0x0C, 0x0C, 0x0D, - 0x0B, 0x0C, 0x0D, 0x0E, - 0x0B, 0x0D, 0x0E, 0x0F, - 0x0B, 0x0C, 0x0E, 0x0F, - 0x0B, 0x0C, 0x0D, 0x0F, - 0x0B, 0x0D, 0x0E, 0x10, - 0x0B, 0x0D, 0x0F, 0x10, - 0x0B, 0x0C, 0x0F, 0x10, - 0x0B, 0x0C, 0x0E, 0x10, - 0x0B, 0x0D, 0x0F, 0x11, - 0x0B, 0x0E, 0x10, 0x11, - 0x0B, 0x0C, 0x10, 0x11, - 0x0B, 0x0C, 0x0E, 0x11, - 0x0B, 0x11, 0x11, 0x11, - 0x0B, 0x0B, 0x11, 0x11, - 0x0B, 0x0B, 0x0B, 0x11, - 0x0B, 0x0E, 0x0F, 0x12, - 0x0B, 0x0E, 0x11, 0x12, - 0x0B, 0x0C, 0x11, 0x12, - 0x0B, 0x0C, 0x0F, 0x12, - 0x0B, 0x0E, 0x10, 0x13, - 0x0B, 0x0F, 0x11, 0x13, - 0x0B, 0x0D, 0x11, 0x13, - 0x0B, 0x0D, 0x0F, 0x13, - 0x0B, 0x13, 0x13, 0x13, - 0x0B, 0x0B, 0x13, 0x13, - 0x0B, 0x0B, 0x0B, 0x13, - 0x0B, 0x0F, 0x12, 0x16, - 0x0B, 0x10, 0x14, 0x16, - 0x0B, 0x0D, 0x14, 0x16, - 0x0B, 0x0D, 0x11, 0x16, - 0x0B, 0x16, 0x16, 0x16, - 0x0B, 0x0B, 0x16, 0x16, - 0x0B, 0x0B, 0x0B, 0x16, - 0x0B, 0x10, 0x14, 0x19, - 0x0B, 0x12, 0x16, 0x19, - 0x0B, 0x0E, 0x16, 0x19, - 0x0B, 0x0E, 0x12, 0x19, - 0x0B, 0x19, 0x19, 0x19, - 0x0B, 0x0B, 0x19, 0x19, - 0x0B, 0x0B, 0x0B, 0x19, - 0x0B, 0x11, 0x16, 0x1C, - 0x0B, 0x13, 0x18, 0x1C, - 0x0B, 0x0F, 0x18, 0x1C, - 0x0B, 0x0F, 0x14, 0x1C, - 0x0B, 0x1C, 0x1C, 0x1C, - 0x0B, 0x0B, 0x1C, 0x1C, - 0x0B, 0x0B, 0x0B, 0x1C, - 0x0B, 0x12, 0x18, 0x1F, - 0x0B, 0x15, 0x1A, 0x1F, - 0x0B, 0x10, 0x1A, 0x1F, - 0x0B, 0x10, 0x15, 0x1F, - 0x0B, 0x1F, 0x1F, 0x1F, - 0x0B, 0x0B, 0x1F, 0x1F, - 0x0B, 0x0B, 0x0B, 0x1F, - 0x0B, 0x16, 0x1D, 0x22, - 0x0B, 0x10, 0x1D, 0x22, - 0x0B, 0x10, 0x17, 0x22, - 0x0B, 0x22, 0x22, 0x22, - 0x0B, 0x0B, 0x22, 0x22, - 0x0B, 0x0B, 0x0B, 0x22, - 0x0B, 0x18, 0x1F, 0x25, - 0x0B, 0x11, 0x1F, 0x25, - 0x0B, 0x11, 0x18, 0x25, - 0x0B, 0x25, 0x25, 0x25, - 0x0B, 0x0B, 0x25, 0x25, - 0x0B, 0x0B, 0x0B, 0x25, - 0x0B, 0x19, 0x21, 0x28, - 0x0B, 0x12, 0x21, 0x28, - 0x0B, 0x12, 0x1A, 0x28, - 0x0B, 0x28, 0x28, 0x28, - 0x0B, 0x0B, 0x28, 0x28, - 0x0B, 0x0B, 0x0B, 0x28, - 0x0B, 0x1B, 0x23, 0x2B, - 0x0B, 0x13, 0x23, 0x2B, - 0x0B, 0x13, 0x1B, 0x2B, - 0x0B, 0x2B, 0x2B, 0x2B, - 0x0B, 0x0B, 0x2B, 0x2B, - 0x0B, 0x0B, 0x0B, 0x2B, - 0x0B, 0x2E, 0x2E, 0x2E, - 0x0B, 0x0B, 0x2E, 0x2E, - 0x0B, 0x0B, 0x0B, 0x2E, - 0x0B, 0x1D, 0x26, 0x2F, - 0x0B, 0x14, 0x26, 0x2F, - 0x0B, 0x14, 0x1D, 0x2F, - 0x0B, 0x33, 0x33, 0x33, - 0x0B, 0x0B, 0x33, 0x33, - 0x0B, 0x0B, 0x0B, 0x33, - 0x0B, 0x39, 0x39, 0x39, - 0x0B, 0x0B, 0x39, 0x39, - 0x0B, 0x0B, 0x0B, 0x39, - 0x0C, 0x0D, 0x0D, 0x0E, - 0x0C, 0x0D, 0x0E, 0x0F, - 0x0C, 0x0E, 0x0F, 0x10, - 0x0C, 0x0D, 0x0F, 0x10, - 0x0C, 0x0D, 0x0E, 0x10, - 0x0C, 0x0E, 0x0F, 0x11, - 0x0C, 0x0E, 0x10, 0x11, - 0x0C, 0x0D, 0x10, 0x11, - 0x0C, 0x0D, 0x0F, 0x11, - 0x0C, 0x0E, 0x10, 0x12, - 0x0C, 0x0F, 0x11, 0x12, - 0x0C, 0x0D, 0x11, 0x12, - 0x0C, 0x0D, 0x0F, 0x12, - 0x0C, 0x12, 0x12, 0x12, - 0x0C, 0x0C, 0x12, 0x12, - 0x0C, 0x0C, 0x0C, 0x12, - 0x0C, 0x0F, 0x10, 0x13, - 0x0C, 0x0F, 0x12, 0x13, - 0x0C, 0x0D, 0x12, 0x13, - 0x0C, 0x0D, 0x10, 0x13, - 0x0C, 0x0F, 0x11, 0x14, - 0x0C, 0x10, 0x12, 0x14, - 0x0C, 0x0E, 0x12, 0x14, - 0x0C, 0x0E, 0x10, 0x14, - 0x0C, 0x14, 0x14, 0x14, - 0x0C, 0x0C, 0x14, 0x14, - 0x0C, 0x0C, 0x0C, 0x14, - 0x0C, 0x10, 0x13, 0x17, - 0x0C, 0x11, 0x15, 0x17, - 0x0C, 0x0E, 0x15, 0x17, - 0x0C, 0x0E, 0x12, 0x17, - 0x0C, 0x17, 0x17, 0x17, - 0x0C, 0x0C, 0x17, 0x17, - 0x0C, 0x0C, 0x0C, 0x17, - 0x0C, 0x11, 0x15, 0x1A, - 0x0C, 0x13, 0x17, 0x1A, - 0x0C, 0x0F, 0x17, 0x1A, - 0x0C, 0x0F, 0x13, 0x1A, - 0x0C, 0x1A, 0x1A, 0x1A, - 0x0C, 0x0C, 0x1A, 0x1A, - 0x0C, 0x0C, 0x0C, 0x1A, - 0x0C, 0x12, 0x17, 0x1D, - 0x0C, 0x14, 0x19, 0x1D, - 0x0C, 0x10, 0x19, 0x1D, - 0x0C, 0x10, 0x15, 0x1D, - 0x0C, 0x1D, 0x1D, 0x1D, - 0x0C, 0x0C, 0x1D, 0x1D, - 0x0C, 0x0C, 0x0C, 0x1D, - 0x0C, 0x13, 0x19, 0x20, - 0x0C, 0x16, 0x1B, 0x20, - 0x0C, 0x11, 0x1B, 0x20, - 0x0C, 0x11, 0x16, 0x20, - 0x0C, 0x20, 0x20, 0x20, - 0x0C, 0x0C, 0x20, 0x20, - 0x0C, 0x0C, 0x0C, 0x20, - 0x0C, 0x17, 0x1E, 0x23, - 0x0C, 0x11, 0x1E, 0x23, - 0x0C, 0x11, 0x18, 0x23, - 0x0C, 0x23, 0x23, 0x23, - 0x0C, 0x0C, 0x23, 0x23, - 0x0C, 0x0C, 0x0C, 0x23, - 0x0C, 0x19, 0x20, 0x26, - 0x0C, 0x12, 0x20, 0x26, - 0x0C, 0x12, 0x19, 0x26, - 0x0C, 0x26, 0x26, 0x26, - 0x0C, 0x0C, 0x26, 0x26, - 0x0C, 0x0C, 0x0C, 0x26, - 0x0C, 0x1A, 0x22, 0x29, - 0x0C, 0x13, 0x22, 0x29, - 0x0C, 0x13, 0x1B, 0x29, - 0x0C, 0x29, 0x29, 0x29, - 0x0C, 0x0C, 0x29, 0x29, - 0x0C, 0x0C, 0x0C, 0x29, - 0x0C, 0x1C, 0x24, 0x2C, - 0x0C, 0x14, 0x24, 0x2C, - 0x0C, 0x14, 0x1C, 0x2C, - 0x0C, 0x2C, 0x2C, 0x2C, - 0x0C, 0x0C, 0x2C, 0x2C, - 0x0C, 0x0C, 0x0C, 0x2C, - 0x0C, 0x2F, 0x2F, 0x2F, - 0x0C, 0x0C, 0x2F, 0x2F, - 0x0C, 0x0C, 0x0C, 0x2F, - 0x0C, 0x1E, 0x27, 0x30, - 0x0C, 0x15, 0x27, 0x30, - 0x0C, 0x15, 0x1E, 0x30, - 0x0C, 0x34, 0x34, 0x34, - 0x0C, 0x0C, 0x34, 0x34, - 0x0C, 0x0C, 0x0C, 0x34, - 0x0C, 0x3A, 0x3A, 0x3A, - 0x0C, 0x0C, 0x3A, 0x3A, - 0x0C, 0x0C, 0x0C, 0x3A, - 0x0D, 0x0E, 0x0E, 0x0F, - 0x0D, 0x0E, 0x0F, 0x10, - 0x0D, 0x0F, 0x10, 0x11, - 0x0D, 0x0E, 0x10, 0x11, - 0x0D, 0x0E, 0x0F, 0x11, - 0x0D, 0x0F, 0x10, 0x12, - 0x0D, 0x0F, 0x11, 0x12, - 0x0D, 0x0E, 0x11, 0x12, - 0x0D, 0x0E, 0x10, 0x12, - 0x0D, 0x0F, 0x11, 0x13, - 0x0D, 0x10, 0x12, 0x13, - 0x0D, 0x0E, 0x12, 0x13, - 0x0D, 0x0E, 0x10, 0x13, - 0x0D, 0x13, 0x13, 0x13, - 0x0D, 0x0D, 0x13, 0x13, - 0x0D, 0x0D, 0x0D, 0x13, - 0x0D, 0x10, 0x11, 0x14, - 0x0D, 0x10, 0x13, 0x14, - 0x0D, 0x0E, 0x13, 0x14, - 0x0D, 0x0E, 0x11, 0x14, - 0x0D, 0x10, 0x12, 0x15, - 0x0D, 0x11, 0x13, 0x15, - 0x0D, 0x0F, 0x13, 0x15, - 0x0D, 0x0F, 0x11, 0x15, - 0x0D, 0x15, 0x15, 0x15, - 0x0D, 0x0D, 0x15, 0x15, - 0x0D, 0x0D, 0x0D, 0x15, - 0x0D, 0x11, 0x14, 0x18, - 0x0D, 0x12, 0x16, 0x18, - 0x0D, 0x0F, 0x16, 0x18, - 0x0D, 0x0F, 0x13, 0x18, - 0x0D, 0x18, 0x18, 0x18, - 0x0D, 0x0D, 0x18, 0x18, - 0x0D, 0x0D, 0x0D, 0x18, - 0x0D, 0x12, 0x16, 0x1B, - 0x0D, 0x14, 0x18, 0x1B, - 0x0D, 0x10, 0x18, 0x1B, - 0x0D, 0x10, 0x14, 0x1B, - 0x0D, 0x1B, 0x1B, 0x1B, - 0x0D, 0x0D, 0x1B, 0x1B, - 0x0D, 0x0D, 0x0D, 0x1B, - 0x0D, 0x13, 0x18, 0x1E, - 0x0D, 0x15, 0x1A, 0x1E, - 0x0D, 0x11, 0x1A, 0x1E, - 0x0D, 0x11, 0x16, 0x1E, - 0x0D, 0x1E, 0x1E, 0x1E, - 0x0D, 0x0D, 0x1E, 0x1E, - 0x0D, 0x0D, 0x0D, 0x1E, - 0x0D, 0x14, 0x1A, 0x21, - 0x0D, 0x17, 0x1C, 0x21, - 0x0D, 0x12, 0x1C, 0x21, - 0x0D, 0x12, 0x17, 0x21, - 0x0D, 0x21, 0x21, 0x21, - 0x0D, 0x0D, 0x21, 0x21, - 0x0D, 0x0D, 0x0D, 0x21, - 0x0D, 0x18, 0x1F, 0x24, - 0x0D, 0x12, 0x1F, 0x24, - 0x0D, 0x12, 0x19, 0x24, - 0x0D, 0x24, 0x24, 0x24, - 0x0D, 0x0D, 0x24, 0x24, - 0x0D, 0x0D, 0x0D, 0x24, - 0x0D, 0x1A, 0x21, 0x27, - 0x0D, 0x13, 0x21, 0x27, - 0x0D, 0x13, 0x1A, 0x27, - 0x0D, 0x27, 0x27, 0x27, - 0x0D, 0x0D, 0x27, 0x27, - 0x0D, 0x0D, 0x0D, 0x27, - 0x0D, 0x1B, 0x23, 0x2A, - 0x0D, 0x14, 0x23, 0x2A, - 0x0D, 0x14, 0x1C, 0x2A, - 0x0D, 0x2A, 0x2A, 0x2A, - 0x0D, 0x0D, 0x2A, 0x2A, - 0x0D, 0x0D, 0x0D, 0x2A, - 0x0D, 0x1D, 0x25, 0x2D, - 0x0D, 0x15, 0x25, 0x2D, - 0x0D, 0x15, 0x1D, 0x2D, - 0x0D, 0x2D, 0x2D, 0x2D, - 0x0D, 0x0D, 0x2D, 0x2D, - 0x0D, 0x0D, 0x0D, 0x2D, - 0x0D, 0x30, 0x30, 0x30, - 0x0D, 0x0D, 0x30, 0x30, - 0x0D, 0x0D, 0x0D, 0x30, - 0x0D, 0x1F, 0x28, 0x31, - 0x0D, 0x16, 0x28, 0x31, - 0x0D, 0x16, 0x1F, 0x31, - 0x0D, 0x35, 0x35, 0x35, - 0x0D, 0x0D, 0x35, 0x35, - 0x0D, 0x0D, 0x0D, 0x35, - 0x0D, 0x3B, 0x3B, 0x3B, - 0x0D, 0x0D, 0x3B, 0x3B, - 0x0D, 0x0D, 0x0D, 0x3B, - 0x0E, 0x0F, 0x0F, 0x10, - 0x0E, 0x0F, 0x10, 0x11, - 0x0E, 0x10, 0x11, 0x12, - 0x0E, 0x0F, 0x11, 0x12, - 0x0E, 0x0F, 0x10, 0x12, - 0x0E, 0x10, 0x11, 0x13, - 0x0E, 0x10, 0x12, 0x13, - 0x0E, 0x0F, 0x12, 0x13, - 0x0E, 0x0F, 0x11, 0x13, - 0x0E, 0x10, 0x12, 0x14, - 0x0E, 0x11, 0x13, 0x14, - 0x0E, 0x0F, 0x13, 0x14, - 0x0E, 0x0F, 0x11, 0x14, - 0x0E, 0x14, 0x14, 0x14, - 0x0E, 0x0E, 0x14, 0x14, - 0x0E, 0x0E, 0x0E, 0x14, - 0x0E, 0x11, 0x12, 0x15, - 0x0E, 0x11, 0x14, 0x15, - 0x0E, 0x0F, 0x14, 0x15, - 0x0E, 0x0F, 0x12, 0x15, - 0x0E, 0x11, 0x13, 0x16, - 0x0E, 0x12, 0x14, 0x16, - 0x0E, 0x10, 0x14, 0x16, - 0x0E, 0x10, 0x12, 0x16, - 0x0E, 0x16, 0x16, 0x16, - 0x0E, 0x0E, 0x16, 0x16, - 0x0E, 0x0E, 0x0E, 0x16, - 0x0E, 0x12, 0x15, 0x19, - 0x0E, 0x13, 0x17, 0x19, - 0x0E, 0x10, 0x17, 0x19, - 0x0E, 0x10, 0x14, 0x19, - 0x0E, 0x19, 0x19, 0x19, - 0x0E, 0x0E, 0x19, 0x19, - 0x0E, 0x0E, 0x0E, 0x19, - 0x0E, 0x13, 0x17, 0x1C, - 0x0E, 0x15, 0x19, 0x1C, - 0x0E, 0x11, 0x19, 0x1C, - 0x0E, 0x11, 0x15, 0x1C, - 0x0E, 0x1C, 0x1C, 0x1C, - 0x0E, 0x0E, 0x1C, 0x1C, - 0x0E, 0x0E, 0x0E, 0x1C, - 0x0E, 0x14, 0x19, 0x1F, - 0x0E, 0x16, 0x1B, 0x1F, - 0x0E, 0x12, 0x1B, 0x1F, - 0x0E, 0x12, 0x17, 0x1F, - 0x0E, 0x1F, 0x1F, 0x1F, - 0x0E, 0x0E, 0x1F, 0x1F, - 0x0E, 0x0E, 0x0E, 0x1F, - 0x0E, 0x15, 0x1B, 0x22, - 0x0E, 0x18, 0x1D, 0x22, - 0x0E, 0x13, 0x1D, 0x22, - 0x0E, 0x13, 0x18, 0x22, - 0x0E, 0x22, 0x22, 0x22, - 0x0E, 0x0E, 0x22, 0x22, - 0x0E, 0x0E, 0x0E, 0x22, - 0x0E, 0x19, 0x20, 0x25, - 0x0E, 0x13, 0x20, 0x25, - 0x0E, 0x13, 0x1A, 0x25, - 0x0E, 0x25, 0x25, 0x25, - 0x0E, 0x0E, 0x25, 0x25, - 0x0E, 0x0E, 0x0E, 0x25, - 0x0E, 0x1B, 0x22, 0x28, - 0x0E, 0x14, 0x22, 0x28, - 0x0E, 0x14, 0x1B, 0x28, - 0x0E, 0x28, 0x28, 0x28, - 0x0E, 0x0E, 0x28, 0x28, - 0x0E, 0x0E, 0x0E, 0x28, - 0x0E, 0x1C, 0x24, 0x2B, - 0x0E, 0x15, 0x24, 0x2B, - 0x0E, 0x15, 0x1D, 0x2B, - 0x0E, 0x2B, 0x2B, 0x2B, - 0x0E, 0x0E, 0x2B, 0x2B, - 0x0E, 0x0E, 0x0E, 0x2B, - 0x0E, 0x1E, 0x26, 0x2E, - 0x0E, 0x16, 0x26, 0x2E, - 0x0E, 0x16, 0x1E, 0x2E, - 0x0E, 0x2E, 0x2E, 0x2E, - 0x0E, 0x0E, 0x2E, 0x2E, - 0x0E, 0x0E, 0x0E, 0x2E, - 0x0E, 0x31, 0x31, 0x31, - 0x0E, 0x0E, 0x31, 0x31, - 0x0E, 0x0E, 0x0E, 0x31, - 0x0E, 0x20, 0x29, 0x32, - 0x0E, 0x17, 0x29, 0x32, - 0x0E, 0x17, 0x20, 0x32, - 0x0E, 0x36, 0x36, 0x36, - 0x0E, 0x0E, 0x36, 0x36, - 0x0E, 0x0E, 0x0E, 0x36, - 0x0E, 0x3C, 0x3C, 0x3C, - 0x0E, 0x0E, 0x3C, 0x3C, - 0x0E, 0x0E, 0x0E, 0x3C, - 0x0F, 0x10, 0x10, 0x11, - 0x0F, 0x10, 0x11, 0x12, - 0x0F, 0x11, 0x12, 0x13, - 0x0F, 0x10, 0x12, 0x13, - 0x0F, 0x10, 0x11, 0x13, - 0x0F, 0x11, 0x12, 0x14, - 0x0F, 0x11, 0x13, 0x14, - 0x0F, 0x10, 0x13, 0x14, - 0x0F, 0x10, 0x12, 0x14, - 0x0F, 0x11, 0x13, 0x15, - 0x0F, 0x12, 0x14, 0x15, - 0x0F, 0x10, 0x14, 0x15, - 0x0F, 0x10, 0x12, 0x15, - 0x0F, 0x15, 0x15, 0x15, - 0x0F, 0x0F, 0x15, 0x15, - 0x0F, 0x0F, 0x0F, 0x15, - 0x0F, 0x12, 0x13, 0x16, - 0x0F, 0x12, 0x15, 0x16, - 0x0F, 0x10, 0x15, 0x16, - 0x0F, 0x10, 0x13, 0x16, - 0x0F, 0x12, 0x14, 0x17, - 0x0F, 0x13, 0x15, 0x17, - 0x0F, 0x11, 0x15, 0x17, - 0x0F, 0x11, 0x13, 0x17, - 0x0F, 0x17, 0x17, 0x17, - 0x0F, 0x0F, 0x17, 0x17, - 0x0F, 0x0F, 0x0F, 0x17, - 0x0F, 0x13, 0x16, 0x1A, - 0x0F, 0x14, 0x18, 0x1A, - 0x0F, 0x11, 0x18, 0x1A, - 0x0F, 0x11, 0x15, 0x1A, - 0x0F, 0x1A, 0x1A, 0x1A, - 0x0F, 0x0F, 0x1A, 0x1A, - 0x0F, 0x0F, 0x0F, 0x1A, - 0x0F, 0x14, 0x18, 0x1D, - 0x0F, 0x16, 0x1A, 0x1D, - 0x0F, 0x12, 0x1A, 0x1D, - 0x0F, 0x12, 0x16, 0x1D, - 0x0F, 0x1D, 0x1D, 0x1D, - 0x0F, 0x0F, 0x1D, 0x1D, - 0x0F, 0x0F, 0x0F, 0x1D, - 0x0F, 0x15, 0x1A, 0x20, - 0x0F, 0x17, 0x1C, 0x20, - 0x0F, 0x13, 0x1C, 0x20, - 0x0F, 0x13, 0x18, 0x20, - 0x0F, 0x20, 0x20, 0x20, - 0x0F, 0x0F, 0x20, 0x20, - 0x0F, 0x0F, 0x0F, 0x20, - 0x0F, 0x16, 0x1C, 0x23, - 0x0F, 0x19, 0x1E, 0x23, - 0x0F, 0x14, 0x1E, 0x23, - 0x0F, 0x14, 0x19, 0x23, - 0x0F, 0x23, 0x23, 0x23, - 0x0F, 0x0F, 0x23, 0x23, - 0x0F, 0x0F, 0x0F, 0x23, - 0x0F, 0x1A, 0x21, 0x26, - 0x0F, 0x14, 0x21, 0x26, - 0x0F, 0x14, 0x1B, 0x26, - 0x0F, 0x26, 0x26, 0x26, - 0x0F, 0x0F, 0x26, 0x26, - 0x0F, 0x0F, 0x0F, 0x26, - 0x0F, 0x1C, 0x23, 0x29, - 0x0F, 0x15, 0x23, 0x29, - 0x0F, 0x15, 0x1C, 0x29, - 0x0F, 0x29, 0x29, 0x29, - 0x0F, 0x0F, 0x29, 0x29, - 0x0F, 0x0F, 0x0F, 0x29, - 0x0F, 0x1D, 0x25, 0x2C, - 0x0F, 0x16, 0x25, 0x2C, - 0x0F, 0x16, 0x1E, 0x2C, - 0x0F, 0x2C, 0x2C, 0x2C, - 0x0F, 0x0F, 0x2C, 0x2C, - 0x0F, 0x0F, 0x0F, 0x2C, - 0x0F, 0x1F, 0x27, 0x2F, - 0x0F, 0x17, 0x27, 0x2F, - 0x0F, 0x17, 0x1F, 0x2F, - 0x0F, 0x2F, 0x2F, 0x2F, - 0x0F, 0x0F, 0x2F, 0x2F, - 0x0F, 0x0F, 0x0F, 0x2F, - 0x0F, 0x32, 0x32, 0x32, - 0x0F, 0x0F, 0x32, 0x32, - 0x0F, 0x0F, 0x0F, 0x32, - 0x0F, 0x21, 0x2A, 0x33, - 0x0F, 0x18, 0x2A, 0x33, - 0x0F, 0x18, 0x21, 0x33, - 0x0F, 0x37, 0x37, 0x37, - 0x0F, 0x0F, 0x37, 0x37, - 0x0F, 0x0F, 0x0F, 0x37, - 0x0F, 0x3D, 0x3D, 0x3D, - 0x0F, 0x0F, 0x3D, 0x3D, - 0x0F, 0x0F, 0x0F, 0x3D, - 0x10, 0x11, 0x11, 0x12, - 0x10, 0x11, 0x12, 0x13, - 0x10, 0x12, 0x13, 0x14, - 0x10, 0x11, 0x13, 0x14, - 0x10, 0x11, 0x12, 0x14, - 0x10, 0x12, 0x13, 0x15, - 0x10, 0x12, 0x14, 0x15, - 0x10, 0x11, 0x14, 0x15, - 0x10, 0x11, 0x13, 0x15, - 0x10, 0x12, 0x14, 0x16, - 0x10, 0x13, 0x15, 0x16, - 0x10, 0x11, 0x15, 0x16, - 0x10, 0x11, 0x13, 0x16, - 0x10, 0x16, 0x16, 0x16, - 0x10, 0x10, 0x16, 0x16, - 0x10, 0x10, 0x10, 0x16, - 0x10, 0x13, 0x14, 0x17, - 0x10, 0x13, 0x16, 0x17, - 0x10, 0x11, 0x16, 0x17, - 0x10, 0x11, 0x14, 0x17, - 0x10, 0x13, 0x15, 0x18, - 0x10, 0x14, 0x16, 0x18, - 0x10, 0x12, 0x16, 0x18, - 0x10, 0x12, 0x14, 0x18, - 0x10, 0x18, 0x18, 0x18, - 0x10, 0x10, 0x18, 0x18, - 0x10, 0x10, 0x10, 0x18, - 0x10, 0x14, 0x17, 0x1B, - 0x10, 0x15, 0x19, 0x1B, - 0x10, 0x12, 0x19, 0x1B, - 0x10, 0x12, 0x16, 0x1B, - 0x10, 0x1B, 0x1B, 0x1B, - 0x10, 0x10, 0x1B, 0x1B, - 0x10, 0x10, 0x10, 0x1B, - 0x10, 0x15, 0x19, 0x1E, - 0x10, 0x17, 0x1B, 0x1E, - 0x10, 0x13, 0x1B, 0x1E, - 0x10, 0x13, 0x17, 0x1E, - 0x10, 0x1E, 0x1E, 0x1E, - 0x10, 0x10, 0x1E, 0x1E, - 0x10, 0x10, 0x10, 0x1E, - 0x10, 0x16, 0x1B, 0x21, - 0x10, 0x18, 0x1D, 0x21, - 0x10, 0x14, 0x1D, 0x21, - 0x10, 0x14, 0x19, 0x21, - 0x10, 0x21, 0x21, 0x21, - 0x10, 0x10, 0x21, 0x21, - 0x10, 0x10, 0x10, 0x21, - 0x10, 0x17, 0x1D, 0x24, - 0x10, 0x1A, 0x1F, 0x24, - 0x10, 0x15, 0x1F, 0x24, - 0x10, 0x15, 0x1A, 0x24, - 0x10, 0x24, 0x24, 0x24, - 0x10, 0x10, 0x24, 0x24, - 0x10, 0x10, 0x10, 0x24, - 0x10, 0x1B, 0x22, 0x27, - 0x10, 0x15, 0x22, 0x27, - 0x10, 0x15, 0x1C, 0x27, - 0x10, 0x27, 0x27, 0x27, - 0x10, 0x10, 0x27, 0x27, - 0x10, 0x10, 0x10, 0x27, - 0x10, 0x1D, 0x24, 0x2A, - 0x10, 0x16, 0x24, 0x2A, - 0x10, 0x16, 0x1D, 0x2A, - 0x10, 0x2A, 0x2A, 0x2A, - 0x10, 0x10, 0x2A, 0x2A, - 0x10, 0x10, 0x10, 0x2A, - 0x10, 0x1E, 0x26, 0x2D, - 0x10, 0x17, 0x26, 0x2D, - 0x10, 0x17, 0x1F, 0x2D, - 0x10, 0x2D, 0x2D, 0x2D, - 0x10, 0x10, 0x2D, 0x2D, - 0x10, 0x10, 0x10, 0x2D, - 0x10, 0x20, 0x28, 0x30, - 0x10, 0x18, 0x28, 0x30, - 0x10, 0x18, 0x20, 0x30, - 0x10, 0x30, 0x30, 0x30, - 0x10, 0x10, 0x30, 0x30, - 0x10, 0x10, 0x10, 0x30, - 0x10, 0x33, 0x33, 0x33, - 0x10, 0x10, 0x33, 0x33, - 0x10, 0x10, 0x10, 0x33, - 0x10, 0x22, 0x2B, 0x34, - 0x10, 0x19, 0x2B, 0x34, - 0x10, 0x19, 0x22, 0x34, - 0x10, 0x38, 0x38, 0x38, - 0x10, 0x10, 0x38, 0x38, - 0x10, 0x10, 0x10, 0x38, - 0x10, 0x3E, 0x3E, 0x3E, - 0x10, 0x10, 0x3E, 0x3E, - 0x10, 0x10, 0x10, 0x3E, - 0x11, 0x12, 0x12, 0x13, - 0x11, 0x12, 0x13, 0x14, - 0x11, 0x13, 0x14, 0x15, - 0x11, 0x12, 0x14, 0x15, - 0x11, 0x12, 0x13, 0x15, - 0x11, 0x13, 0x14, 0x16, - 0x11, 0x13, 0x15, 0x16, - 0x11, 0x12, 0x15, 0x16, - 0x11, 0x12, 0x14, 0x16, - 0x11, 0x13, 0x15, 0x17, - 0x11, 0x14, 0x16, 0x17, - 0x11, 0x12, 0x16, 0x17, - 0x11, 0x12, 0x14, 0x17, - 0x11, 0x17, 0x17, 0x17, - 0x11, 0x11, 0x17, 0x17, - 0x11, 0x11, 0x11, 0x17, - 0x11, 0x14, 0x15, 0x18, - 0x11, 0x14, 0x17, 0x18, - 0x11, 0x12, 0x17, 0x18, - 0x11, 0x12, 0x15, 0x18, - 0x11, 0x14, 0x16, 0x19, - 0x11, 0x15, 0x17, 0x19, - 0x11, 0x13, 0x17, 0x19, - 0x11, 0x13, 0x15, 0x19, - 0x11, 0x19, 0x19, 0x19, - 0x11, 0x11, 0x19, 0x19, - 0x11, 0x11, 0x11, 0x19, - 0x11, 0x15, 0x18, 0x1C, - 0x11, 0x16, 0x1A, 0x1C, - 0x11, 0x13, 0x1A, 0x1C, - 0x11, 0x13, 0x17, 0x1C, - 0x11, 0x1C, 0x1C, 0x1C, - 0x11, 0x11, 0x1C, 0x1C, - 0x11, 0x11, 0x11, 0x1C, - 0x11, 0x16, 0x1A, 0x1F, - 0x11, 0x18, 0x1C, 0x1F, - 0x11, 0x14, 0x1C, 0x1F, - 0x11, 0x14, 0x18, 0x1F, - 0x11, 0x1F, 0x1F, 0x1F, - 0x11, 0x11, 0x1F, 0x1F, - 0x11, 0x11, 0x11, 0x1F, - 0x11, 0x17, 0x1C, 0x22, - 0x11, 0x19, 0x1E, 0x22, - 0x11, 0x15, 0x1E, 0x22, - 0x11, 0x15, 0x1A, 0x22, - 0x11, 0x22, 0x22, 0x22, - 0x11, 0x11, 0x22, 0x22, - 0x11, 0x11, 0x11, 0x22, - 0x11, 0x18, 0x1E, 0x25, - 0x11, 0x1B, 0x20, 0x25, - 0x11, 0x16, 0x20, 0x25, - 0x11, 0x16, 0x1B, 0x25, - 0x11, 0x25, 0x25, 0x25, - 0x11, 0x11, 0x25, 0x25, - 0x11, 0x11, 0x11, 0x25, - 0x11, 0x1C, 0x23, 0x28, - 0x11, 0x16, 0x23, 0x28, - 0x11, 0x16, 0x1D, 0x28, - 0x11, 0x28, 0x28, 0x28, - 0x11, 0x11, 0x28, 0x28, - 0x11, 0x11, 0x11, 0x28, - 0x11, 0x1E, 0x25, 0x2B, - 0x11, 0x17, 0x25, 0x2B, - 0x11, 0x17, 0x1E, 0x2B, - 0x11, 0x2B, 0x2B, 0x2B, - 0x11, 0x11, 0x2B, 0x2B, - 0x11, 0x11, 0x11, 0x2B, - 0x11, 0x1F, 0x27, 0x2E, - 0x11, 0x18, 0x27, 0x2E, - 0x11, 0x18, 0x20, 0x2E, - 0x11, 0x2E, 0x2E, 0x2E, - 0x11, 0x11, 0x2E, 0x2E, - 0x11, 0x11, 0x11, 0x2E, - 0x11, 0x21, 0x29, 0x31, - 0x11, 0x19, 0x29, 0x31, - 0x11, 0x19, 0x21, 0x31, - 0x11, 0x31, 0x31, 0x31, - 0x11, 0x11, 0x31, 0x31, - 0x11, 0x11, 0x11, 0x31, - 0x11, 0x34, 0x34, 0x34, - 0x11, 0x11, 0x34, 0x34, - 0x11, 0x11, 0x11, 0x34, - 0x11, 0x23, 0x2C, 0x35, - 0x11, 0x1A, 0x2C, 0x35, - 0x11, 0x1A, 0x23, 0x35, - 0x11, 0x39, 0x39, 0x39, - 0x11, 0x11, 0x39, 0x39, - 0x11, 0x11, 0x11, 0x39, - 0x11, 0x3F, 0x3F, 0x3F, - 0x11, 0x11, 0x3F, 0x3F, - 0x11, 0x11, 0x11, 0x3F, - 0x12, 0x13, 0x13, 0x14, - 0x12, 0x13, 0x14, 0x15, - 0x12, 0x14, 0x15, 0x16, - 0x12, 0x13, 0x15, 0x16, - 0x12, 0x13, 0x14, 0x16, - 0x12, 0x14, 0x15, 0x17, - 0x12, 0x14, 0x16, 0x17, - 0x12, 0x13, 0x16, 0x17, - 0x12, 0x13, 0x15, 0x17, - 0x12, 0x14, 0x16, 0x18, - 0x12, 0x15, 0x17, 0x18, - 0x12, 0x13, 0x17, 0x18, - 0x12, 0x13, 0x15, 0x18, - 0x12, 0x18, 0x18, 0x18, - 0x12, 0x12, 0x18, 0x18, - 0x12, 0x12, 0x12, 0x18, - 0x12, 0x15, 0x16, 0x19, - 0x12, 0x15, 0x18, 0x19, - 0x12, 0x13, 0x18, 0x19, - 0x12, 0x13, 0x16, 0x19, - 0x12, 0x15, 0x17, 0x1A, - 0x12, 0x16, 0x18, 0x1A, - 0x12, 0x14, 0x18, 0x1A, - 0x12, 0x14, 0x16, 0x1A, - 0x12, 0x1A, 0x1A, 0x1A, - 0x12, 0x12, 0x1A, 0x1A, - 0x12, 0x12, 0x12, 0x1A, - 0x12, 0x16, 0x19, 0x1D, - 0x12, 0x17, 0x1B, 0x1D, - 0x12, 0x14, 0x1B, 0x1D, - 0x12, 0x14, 0x18, 0x1D, - 0x12, 0x1D, 0x1D, 0x1D, - 0x12, 0x12, 0x1D, 0x1D, - 0x12, 0x12, 0x12, 0x1D, - 0x12, 0x17, 0x1B, 0x20, - 0x12, 0x19, 0x1D, 0x20, - 0x12, 0x15, 0x1D, 0x20, - 0x12, 0x15, 0x19, 0x20, - 0x12, 0x20, 0x20, 0x20, - 0x12, 0x12, 0x20, 0x20, - 0x12, 0x12, 0x12, 0x20, - 0x12, 0x18, 0x1D, 0x23, - 0x12, 0x1A, 0x1F, 0x23, - 0x12, 0x16, 0x1F, 0x23, - 0x12, 0x16, 0x1B, 0x23, - 0x12, 0x23, 0x23, 0x23, - 0x12, 0x12, 0x23, 0x23, - 0x12, 0x12, 0x12, 0x23, - 0x12, 0x19, 0x1F, 0x26, - 0x12, 0x1C, 0x21, 0x26, - 0x12, 0x17, 0x21, 0x26, - 0x12, 0x17, 0x1C, 0x26, - 0x12, 0x26, 0x26, 0x26, - 0x12, 0x12, 0x26, 0x26, - 0x12, 0x12, 0x12, 0x26, - 0x12, 0x1D, 0x24, 0x29, - 0x12, 0x17, 0x24, 0x29, - 0x12, 0x17, 0x1E, 0x29, - 0x12, 0x29, 0x29, 0x29, - 0x12, 0x12, 0x29, 0x29, - 0x12, 0x12, 0x12, 0x29, - 0x12, 0x1F, 0x26, 0x2C, - 0x12, 0x18, 0x26, 0x2C, - 0x12, 0x18, 0x1F, 0x2C, - 0x12, 0x2C, 0x2C, 0x2C, - 0x12, 0x12, 0x2C, 0x2C, - 0x12, 0x12, 0x12, 0x2C, - 0x12, 0x20, 0x28, 0x2F, - 0x12, 0x19, 0x28, 0x2F, - 0x12, 0x19, 0x21, 0x2F, - 0x12, 0x2F, 0x2F, 0x2F, - 0x12, 0x12, 0x2F, 0x2F, - 0x12, 0x12, 0x12, 0x2F, - 0x12, 0x22, 0x2A, 0x32, - 0x12, 0x1A, 0x2A, 0x32, - 0x12, 0x1A, 0x22, 0x32, - 0x12, 0x32, 0x32, 0x32, - 0x12, 0x12, 0x32, 0x32, - 0x12, 0x12, 0x12, 0x32, - 0x12, 0x35, 0x35, 0x35, - 0x12, 0x12, 0x35, 0x35, - 0x12, 0x12, 0x12, 0x35, - 0x12, 0x24, 0x2D, 0x36, - 0x12, 0x1B, 0x2D, 0x36, - 0x12, 0x1B, 0x24, 0x36, - 0x12, 0x3A, 0x3A, 0x3A, - 0x12, 0x12, 0x3A, 0x3A, - 0x12, 0x12, 0x12, 0x3A, - 0x13, 0x14, 0x14, 0x15, - 0x13, 0x14, 0x15, 0x16, - 0x13, 0x15, 0x16, 0x17, - 0x13, 0x14, 0x16, 0x17, - 0x13, 0x14, 0x15, 0x17, - 0x13, 0x15, 0x16, 0x18, - 0x13, 0x15, 0x17, 0x18, - 0x13, 0x14, 0x17, 0x18, - 0x13, 0x14, 0x16, 0x18, - 0x13, 0x15, 0x17, 0x19, - 0x13, 0x16, 0x18, 0x19, - 0x13, 0x14, 0x18, 0x19, - 0x13, 0x14, 0x16, 0x19, - 0x13, 0x19, 0x19, 0x19, - 0x13, 0x13, 0x19, 0x19, - 0x13, 0x13, 0x13, 0x19, - 0x13, 0x16, 0x17, 0x1A, - 0x13, 0x16, 0x19, 0x1A, - 0x13, 0x14, 0x19, 0x1A, - 0x13, 0x14, 0x17, 0x1A, - 0x13, 0x16, 0x18, 0x1B, - 0x13, 0x17, 0x19, 0x1B, - 0x13, 0x15, 0x19, 0x1B, - 0x13, 0x15, 0x17, 0x1B, - 0x13, 0x1B, 0x1B, 0x1B, - 0x13, 0x13, 0x1B, 0x1B, - 0x13, 0x13, 0x13, 0x1B, - 0x13, 0x17, 0x1A, 0x1E, - 0x13, 0x18, 0x1C, 0x1E, - 0x13, 0x15, 0x1C, 0x1E, - 0x13, 0x15, 0x19, 0x1E, - 0x13, 0x1E, 0x1E, 0x1E, - 0x13, 0x13, 0x1E, 0x1E, - 0x13, 0x13, 0x13, 0x1E, - 0x13, 0x18, 0x1C, 0x21, - 0x13, 0x1A, 0x1E, 0x21, - 0x13, 0x16, 0x1E, 0x21, - 0x13, 0x16, 0x1A, 0x21, - 0x13, 0x21, 0x21, 0x21, - 0x13, 0x13, 0x21, 0x21, - 0x13, 0x13, 0x13, 0x21, - 0x13, 0x19, 0x1E, 0x24, - 0x13, 0x1B, 0x20, 0x24, - 0x13, 0x17, 0x20, 0x24, - 0x13, 0x17, 0x1C, 0x24, - 0x13, 0x24, 0x24, 0x24, - 0x13, 0x13, 0x24, 0x24, - 0x13, 0x13, 0x13, 0x24, - 0x13, 0x1A, 0x20, 0x27, - 0x13, 0x1D, 0x22, 0x27, - 0x13, 0x18, 0x22, 0x27, - 0x13, 0x18, 0x1D, 0x27, - 0x13, 0x27, 0x27, 0x27, - 0x13, 0x13, 0x27, 0x27, - 0x13, 0x13, 0x13, 0x27, - 0x13, 0x1E, 0x25, 0x2A, - 0x13, 0x18, 0x25, 0x2A, - 0x13, 0x18, 0x1F, 0x2A, - 0x13, 0x2A, 0x2A, 0x2A, - 0x13, 0x13, 0x2A, 0x2A, - 0x13, 0x13, 0x13, 0x2A, - 0x13, 0x20, 0x27, 0x2D, - 0x13, 0x19, 0x27, 0x2D, - 0x13, 0x19, 0x20, 0x2D, - 0x13, 0x2D, 0x2D, 0x2D, - 0x13, 0x13, 0x2D, 0x2D, - 0x13, 0x13, 0x13, 0x2D, - 0x13, 0x21, 0x29, 0x30, - 0x13, 0x1A, 0x29, 0x30, - 0x13, 0x1A, 0x22, 0x30, - 0x13, 0x30, 0x30, 0x30, - 0x13, 0x13, 0x30, 0x30, - 0x13, 0x13, 0x13, 0x30, - 0x13, 0x23, 0x2B, 0x33, - 0x13, 0x1B, 0x2B, 0x33, - 0x13, 0x1B, 0x23, 0x33, - 0x13, 0x33, 0x33, 0x33, - 0x13, 0x13, 0x33, 0x33, - 0x13, 0x13, 0x13, 0x33, - 0x13, 0x36, 0x36, 0x36, - 0x13, 0x13, 0x36, 0x36, - 0x13, 0x13, 0x13, 0x36, - 0x13, 0x25, 0x2E, 0x37, - 0x13, 0x1C, 0x2E, 0x37, - 0x13, 0x1C, 0x25, 0x37, - 0x13, 0x3B, 0x3B, 0x3B, - 0x13, 0x13, 0x3B, 0x3B, - 0x13, 0x13, 0x13, 0x3B, - 0x14, 0x15, 0x15, 0x16, - 0x14, 0x15, 0x16, 0x17, - 0x14, 0x16, 0x17, 0x18, - 0x14, 0x15, 0x17, 0x18, - 0x14, 0x15, 0x16, 0x18, - 0x14, 0x16, 0x17, 0x19, - 0x14, 0x16, 0x18, 0x19, - 0x14, 0x15, 0x18, 0x19, - 0x14, 0x15, 0x17, 0x19, - 0x14, 0x16, 0x18, 0x1A, - 0x14, 0x17, 0x19, 0x1A, - 0x14, 0x15, 0x19, 0x1A, - 0x14, 0x15, 0x17, 0x1A, - 0x14, 0x1A, 0x1A, 0x1A, - 0x14, 0x14, 0x1A, 0x1A, - 0x14, 0x14, 0x14, 0x1A, - 0x14, 0x17, 0x18, 0x1B, - 0x14, 0x17, 0x1A, 0x1B, - 0x14, 0x15, 0x1A, 0x1B, - 0x14, 0x15, 0x18, 0x1B, - 0x14, 0x17, 0x19, 0x1C, - 0x14, 0x18, 0x1A, 0x1C, - 0x14, 0x16, 0x1A, 0x1C, - 0x14, 0x16, 0x18, 0x1C, - 0x14, 0x1C, 0x1C, 0x1C, - 0x14, 0x14, 0x1C, 0x1C, - 0x14, 0x14, 0x14, 0x1C, - 0x14, 0x18, 0x1B, 0x1F, - 0x14, 0x19, 0x1D, 0x1F, - 0x14, 0x16, 0x1D, 0x1F, - 0x14, 0x16, 0x1A, 0x1F, - 0x14, 0x1F, 0x1F, 0x1F, - 0x14, 0x14, 0x1F, 0x1F, - 0x14, 0x14, 0x14, 0x1F, - 0x14, 0x19, 0x1D, 0x22, - 0x14, 0x1B, 0x1F, 0x22, - 0x14, 0x17, 0x1F, 0x22, - 0x14, 0x17, 0x1B, 0x22, - 0x14, 0x22, 0x22, 0x22, - 0x14, 0x14, 0x22, 0x22, - 0x14, 0x14, 0x14, 0x22, - 0x14, 0x1A, 0x1F, 0x25, - 0x14, 0x1C, 0x21, 0x25, - 0x14, 0x18, 0x21, 0x25, - 0x14, 0x18, 0x1D, 0x25, - 0x14, 0x25, 0x25, 0x25, - 0x14, 0x14, 0x25, 0x25, - 0x14, 0x14, 0x14, 0x25, - 0x14, 0x1B, 0x21, 0x28, - 0x14, 0x1E, 0x23, 0x28, - 0x14, 0x19, 0x23, 0x28, - 0x14, 0x19, 0x1E, 0x28, - 0x14, 0x28, 0x28, 0x28, - 0x14, 0x14, 0x28, 0x28, - 0x14, 0x14, 0x14, 0x28, - 0x14, 0x1F, 0x26, 0x2B, - 0x14, 0x19, 0x26, 0x2B, - 0x14, 0x19, 0x20, 0x2B, - 0x14, 0x2B, 0x2B, 0x2B, - 0x14, 0x14, 0x2B, 0x2B, - 0x14, 0x14, 0x14, 0x2B, - 0x14, 0x21, 0x28, 0x2E, - 0x14, 0x1A, 0x28, 0x2E, - 0x14, 0x1A, 0x21, 0x2E, - 0x14, 0x2E, 0x2E, 0x2E, - 0x14, 0x14, 0x2E, 0x2E, - 0x14, 0x14, 0x14, 0x2E, - 0x14, 0x22, 0x2A, 0x31, - 0x14, 0x1B, 0x2A, 0x31, - 0x14, 0x1B, 0x23, 0x31, - 0x14, 0x31, 0x31, 0x31, - 0x14, 0x14, 0x31, 0x31, - 0x14, 0x14, 0x14, 0x31, - 0x14, 0x24, 0x2C, 0x34, - 0x14, 0x1C, 0x2C, 0x34, - 0x14, 0x1C, 0x24, 0x34, - 0x14, 0x34, 0x34, 0x34, - 0x14, 0x14, 0x34, 0x34, - 0x14, 0x14, 0x14, 0x34, - 0x14, 0x37, 0x37, 0x37, - 0x14, 0x14, 0x37, 0x37, - 0x14, 0x14, 0x14, 0x37, - 0x14, 0x26, 0x2F, 0x38, - 0x14, 0x1D, 0x2F, 0x38, - 0x14, 0x1D, 0x26, 0x38, - 0x14, 0x3C, 0x3C, 0x3C, - 0x14, 0x14, 0x3C, 0x3C, - 0x14, 0x14, 0x14, 0x3C, - 0x15, 0x16, 0x16, 0x17, - 0x15, 0x16, 0x17, 0x18, - 0x15, 0x17, 0x18, 0x19, - 0x15, 0x16, 0x18, 0x19, - 0x15, 0x16, 0x17, 0x19, - 0x15, 0x17, 0x18, 0x1A, - 0x15, 0x17, 0x19, 0x1A, - 0x15, 0x16, 0x19, 0x1A, - 0x15, 0x16, 0x18, 0x1A, - 0x15, 0x17, 0x19, 0x1B, - 0x15, 0x18, 0x1A, 0x1B, - 0x15, 0x16, 0x1A, 0x1B, - 0x15, 0x16, 0x18, 0x1B, - 0x15, 0x1B, 0x1B, 0x1B, - 0x15, 0x15, 0x1B, 0x1B, - 0x15, 0x15, 0x15, 0x1B, - 0x15, 0x18, 0x19, 0x1C, - 0x15, 0x18, 0x1B, 0x1C, - 0x15, 0x16, 0x1B, 0x1C, - 0x15, 0x16, 0x19, 0x1C, - 0x15, 0x18, 0x1A, 0x1D, - 0x15, 0x19, 0x1B, 0x1D, - 0x15, 0x17, 0x1B, 0x1D, - 0x15, 0x17, 0x19, 0x1D, - 0x15, 0x1D, 0x1D, 0x1D, - 0x15, 0x15, 0x1D, 0x1D, - 0x15, 0x15, 0x15, 0x1D, - 0x15, 0x19, 0x1C, 0x20, - 0x15, 0x1A, 0x1E, 0x20, - 0x15, 0x17, 0x1E, 0x20, - 0x15, 0x17, 0x1B, 0x20, - 0x15, 0x20, 0x20, 0x20, - 0x15, 0x15, 0x20, 0x20, - 0x15, 0x15, 0x15, 0x20, - 0x15, 0x1A, 0x1E, 0x23, - 0x15, 0x1C, 0x20, 0x23, - 0x15, 0x18, 0x20, 0x23, - 0x15, 0x18, 0x1C, 0x23, - 0x15, 0x23, 0x23, 0x23, - 0x15, 0x15, 0x23, 0x23, - 0x15, 0x15, 0x15, 0x23, - 0x15, 0x1B, 0x20, 0x26, - 0x15, 0x1D, 0x22, 0x26, - 0x15, 0x19, 0x22, 0x26, - 0x15, 0x19, 0x1E, 0x26, - 0x15, 0x26, 0x26, 0x26, - 0x15, 0x15, 0x26, 0x26, - 0x15, 0x15, 0x15, 0x26, - 0x15, 0x1C, 0x22, 0x29, - 0x15, 0x1F, 0x24, 0x29, - 0x15, 0x1A, 0x24, 0x29, - 0x15, 0x1A, 0x1F, 0x29, - 0x15, 0x29, 0x29, 0x29, - 0x15, 0x15, 0x29, 0x29, - 0x15, 0x15, 0x15, 0x29, - 0x15, 0x20, 0x27, 0x2C, - 0x15, 0x1A, 0x27, 0x2C, - 0x15, 0x1A, 0x21, 0x2C, - 0x15, 0x2C, 0x2C, 0x2C, - 0x15, 0x15, 0x2C, 0x2C, - 0x15, 0x15, 0x15, 0x2C, - 0x15, 0x22, 0x29, 0x2F, - 0x15, 0x1B, 0x29, 0x2F, - 0x15, 0x1B, 0x22, 0x2F, - 0x15, 0x2F, 0x2F, 0x2F, - 0x15, 0x15, 0x2F, 0x2F, - 0x15, 0x15, 0x15, 0x2F, - 0x15, 0x23, 0x2B, 0x32, - 0x15, 0x1C, 0x2B, 0x32, - 0x15, 0x1C, 0x24, 0x32, - 0x15, 0x32, 0x32, 0x32, - 0x15, 0x15, 0x32, 0x32, - 0x15, 0x15, 0x15, 0x32, - 0x15, 0x25, 0x2D, 0x35, - 0x15, 0x1D, 0x2D, 0x35, - 0x15, 0x1D, 0x25, 0x35, - 0x15, 0x35, 0x35, 0x35, - 0x15, 0x15, 0x35, 0x35, - 0x15, 0x15, 0x15, 0x35, - 0x15, 0x38, 0x38, 0x38, - 0x15, 0x15, 0x38, 0x38, - 0x15, 0x15, 0x15, 0x38, - 0x15, 0x27, 0x30, 0x39, - 0x15, 0x1E, 0x30, 0x39, - 0x15, 0x1E, 0x27, 0x39, - 0x15, 0x3D, 0x3D, 0x3D, - 0x15, 0x15, 0x3D, 0x3D, - 0x15, 0x15, 0x15, 0x3D, - 0x16, 0x17, 0x17, 0x18, - 0x16, 0x17, 0x18, 0x19, - 0x16, 0x18, 0x19, 0x1A, - 0x16, 0x17, 0x19, 0x1A, - 0x16, 0x17, 0x18, 0x1A, - 0x16, 0x18, 0x19, 0x1B, - 0x16, 0x18, 0x1A, 0x1B, - 0x16, 0x17, 0x1A, 0x1B, - 0x16, 0x17, 0x19, 0x1B, - 0x16, 0x18, 0x1A, 0x1C, - 0x16, 0x19, 0x1B, 0x1C, - 0x16, 0x17, 0x1B, 0x1C, - 0x16, 0x17, 0x19, 0x1C, - 0x16, 0x1C, 0x1C, 0x1C, - 0x16, 0x16, 0x1C, 0x1C, - 0x16, 0x16, 0x16, 0x1C, - 0x16, 0x19, 0x1A, 0x1D, - 0x16, 0x19, 0x1C, 0x1D, - 0x16, 0x17, 0x1C, 0x1D, - 0x16, 0x17, 0x1A, 0x1D, - 0x16, 0x19, 0x1B, 0x1E, - 0x16, 0x1A, 0x1C, 0x1E, - 0x16, 0x18, 0x1C, 0x1E, - 0x16, 0x18, 0x1A, 0x1E, - 0x16, 0x1E, 0x1E, 0x1E, - 0x16, 0x16, 0x1E, 0x1E, - 0x16, 0x16, 0x16, 0x1E, - 0x16, 0x1A, 0x1D, 0x21, - 0x16, 0x1B, 0x1F, 0x21, - 0x16, 0x18, 0x1F, 0x21, - 0x16, 0x18, 0x1C, 0x21, - 0x16, 0x21, 0x21, 0x21, - 0x16, 0x16, 0x21, 0x21, - 0x16, 0x16, 0x16, 0x21, - 0x16, 0x1B, 0x1F, 0x24, - 0x16, 0x1D, 0x21, 0x24, - 0x16, 0x19, 0x21, 0x24, - 0x16, 0x19, 0x1D, 0x24, - 0x16, 0x24, 0x24, 0x24, - 0x16, 0x16, 0x24, 0x24, - 0x16, 0x16, 0x16, 0x24, - 0x16, 0x1C, 0x21, 0x27, - 0x16, 0x1E, 0x23, 0x27, - 0x16, 0x1A, 0x23, 0x27, - 0x16, 0x1A, 0x1F, 0x27, - 0x16, 0x27, 0x27, 0x27, - 0x16, 0x16, 0x27, 0x27, - 0x16, 0x16, 0x16, 0x27, - 0x16, 0x1D, 0x23, 0x2A, - 0x16, 0x20, 0x25, 0x2A, - 0x16, 0x1B, 0x25, 0x2A, - 0x16, 0x1B, 0x20, 0x2A, - 0x16, 0x2A, 0x2A, 0x2A, - 0x16, 0x16, 0x2A, 0x2A, - 0x16, 0x16, 0x16, 0x2A, - 0x16, 0x21, 0x28, 0x2D, - 0x16, 0x1B, 0x28, 0x2D, - 0x16, 0x1B, 0x22, 0x2D, - 0x16, 0x2D, 0x2D, 0x2D, - 0x16, 0x16, 0x2D, 0x2D, - 0x16, 0x16, 0x16, 0x2D, - 0x16, 0x23, 0x2A, 0x30, - 0x16, 0x1C, 0x2A, 0x30, - 0x16, 0x1C, 0x23, 0x30, - 0x16, 0x30, 0x30, 0x30, - 0x16, 0x16, 0x30, 0x30, - 0x16, 0x16, 0x16, 0x30, - 0x16, 0x24, 0x2C, 0x33, - 0x16, 0x1D, 0x2C, 0x33, - 0x16, 0x1D, 0x25, 0x33, - 0x16, 0x33, 0x33, 0x33, - 0x16, 0x16, 0x33, 0x33, - 0x16, 0x16, 0x16, 0x33, - 0x16, 0x26, 0x2E, 0x36, - 0x16, 0x1E, 0x2E, 0x36, - 0x16, 0x1E, 0x26, 0x36, - 0x16, 0x36, 0x36, 0x36, - 0x16, 0x16, 0x36, 0x36, - 0x16, 0x16, 0x16, 0x36, - 0x16, 0x39, 0x39, 0x39, - 0x16, 0x16, 0x39, 0x39, - 0x16, 0x16, 0x16, 0x39, - 0x16, 0x28, 0x31, 0x3A, - 0x16, 0x1F, 0x31, 0x3A, - 0x16, 0x1F, 0x28, 0x3A, - 0x16, 0x3E, 0x3E, 0x3E, - 0x16, 0x16, 0x3E, 0x3E, - 0x16, 0x16, 0x16, 0x3E, - 0x17, 0x18, 0x18, 0x19, - 0x17, 0x18, 0x19, 0x1A, - 0x17, 0x19, 0x1A, 0x1B, - 0x17, 0x18, 0x1A, 0x1B, - 0x17, 0x18, 0x19, 0x1B, - 0x17, 0x19, 0x1A, 0x1C, - 0x17, 0x19, 0x1B, 0x1C, - 0x17, 0x18, 0x1B, 0x1C, - 0x17, 0x18, 0x1A, 0x1C, - 0x17, 0x19, 0x1B, 0x1D, - 0x17, 0x1A, 0x1C, 0x1D, - 0x17, 0x18, 0x1C, 0x1D, - 0x17, 0x18, 0x1A, 0x1D, - 0x17, 0x1D, 0x1D, 0x1D, - 0x17, 0x17, 0x1D, 0x1D, - 0x17, 0x17, 0x17, 0x1D, - 0x17, 0x1A, 0x1B, 0x1E, - 0x17, 0x1A, 0x1D, 0x1E, - 0x17, 0x18, 0x1D, 0x1E, - 0x17, 0x18, 0x1B, 0x1E, - 0x17, 0x1A, 0x1C, 0x1F, - 0x17, 0x1B, 0x1D, 0x1F, - 0x17, 0x19, 0x1D, 0x1F, - 0x17, 0x19, 0x1B, 0x1F, - 0x17, 0x1F, 0x1F, 0x1F, - 0x17, 0x17, 0x1F, 0x1F, - 0x17, 0x17, 0x17, 0x1F, - 0x17, 0x1B, 0x1E, 0x22, - 0x17, 0x1C, 0x20, 0x22, - 0x17, 0x19, 0x20, 0x22, - 0x17, 0x19, 0x1D, 0x22, - 0x17, 0x22, 0x22, 0x22, - 0x17, 0x17, 0x22, 0x22, - 0x17, 0x17, 0x17, 0x22, - 0x17, 0x1C, 0x20, 0x25, - 0x17, 0x1E, 0x22, 0x25, - 0x17, 0x1A, 0x22, 0x25, - 0x17, 0x1A, 0x1E, 0x25, - 0x17, 0x25, 0x25, 0x25, - 0x17, 0x17, 0x25, 0x25, - 0x17, 0x17, 0x17, 0x25, - 0x17, 0x1D, 0x22, 0x28, - 0x17, 0x1F, 0x24, 0x28, - 0x17, 0x1B, 0x24, 0x28, - 0x17, 0x1B, 0x20, 0x28, - 0x17, 0x28, 0x28, 0x28, - 0x17, 0x17, 0x28, 0x28, - 0x17, 0x17, 0x17, 0x28, - 0x17, 0x1E, 0x24, 0x2B, - 0x17, 0x21, 0x26, 0x2B, - 0x17, 0x1C, 0x26, 0x2B, - 0x17, 0x1C, 0x21, 0x2B, - 0x17, 0x2B, 0x2B, 0x2B, - 0x17, 0x17, 0x2B, 0x2B, - 0x17, 0x17, 0x17, 0x2B, - 0x17, 0x22, 0x29, 0x2E, - 0x17, 0x1C, 0x29, 0x2E, - 0x17, 0x1C, 0x23, 0x2E, - 0x17, 0x2E, 0x2E, 0x2E, - 0x17, 0x17, 0x2E, 0x2E, - 0x17, 0x17, 0x17, 0x2E, - 0x17, 0x24, 0x2B, 0x31, - 0x17, 0x1D, 0x2B, 0x31, - 0x17, 0x1D, 0x24, 0x31, - 0x17, 0x31, 0x31, 0x31, - 0x17, 0x17, 0x31, 0x31, - 0x17, 0x17, 0x17, 0x31, - 0x17, 0x25, 0x2D, 0x34, - 0x17, 0x1E, 0x2D, 0x34, - 0x17, 0x1E, 0x26, 0x34, - 0x17, 0x34, 0x34, 0x34, - 0x17, 0x17, 0x34, 0x34, - 0x17, 0x17, 0x17, 0x34, - 0x17, 0x27, 0x2F, 0x37, - 0x17, 0x1F, 0x2F, 0x37, - 0x17, 0x1F, 0x27, 0x37, - 0x17, 0x37, 0x37, 0x37, - 0x17, 0x17, 0x37, 0x37, - 0x17, 0x17, 0x17, 0x37, - 0x17, 0x3A, 0x3A, 0x3A, - 0x17, 0x17, 0x3A, 0x3A, - 0x17, 0x17, 0x17, 0x3A, - 0x17, 0x29, 0x32, 0x3B, - 0x17, 0x20, 0x32, 0x3B, - 0x17, 0x20, 0x29, 0x3B, - 0x17, 0x3F, 0x3F, 0x3F, - 0x17, 0x17, 0x3F, 0x3F, - 0x17, 0x17, 0x17, 0x3F, - 0x18, 0x19, 0x19, 0x1A, - 0x18, 0x19, 0x1A, 0x1B, - 0x18, 0x1A, 0x1B, 0x1C, - 0x18, 0x19, 0x1B, 0x1C, - 0x18, 0x19, 0x1A, 0x1C, - 0x18, 0x1A, 0x1B, 0x1D, - 0x18, 0x1A, 0x1C, 0x1D, - 0x18, 0x19, 0x1C, 0x1D, - 0x18, 0x19, 0x1B, 0x1D, - 0x18, 0x1A, 0x1C, 0x1E, - 0x18, 0x1B, 0x1D, 0x1E, - 0x18, 0x19, 0x1D, 0x1E, - 0x18, 0x19, 0x1B, 0x1E, - 0x18, 0x1E, 0x1E, 0x1E, - 0x18, 0x18, 0x1E, 0x1E, - 0x18, 0x18, 0x18, 0x1E, - 0x18, 0x1B, 0x1C, 0x1F, - 0x18, 0x1B, 0x1E, 0x1F, - 0x18, 0x19, 0x1E, 0x1F, - 0x18, 0x19, 0x1C, 0x1F, - 0x18, 0x1B, 0x1D, 0x20, - 0x18, 0x1C, 0x1E, 0x20, - 0x18, 0x1A, 0x1E, 0x20, - 0x18, 0x1A, 0x1C, 0x20, - 0x18, 0x20, 0x20, 0x20, - 0x18, 0x18, 0x20, 0x20, - 0x18, 0x18, 0x18, 0x20, - 0x18, 0x1C, 0x1F, 0x23, - 0x18, 0x1D, 0x21, 0x23, - 0x18, 0x1A, 0x21, 0x23, - 0x18, 0x1A, 0x1E, 0x23, - 0x18, 0x23, 0x23, 0x23, - 0x18, 0x18, 0x23, 0x23, - 0x18, 0x18, 0x18, 0x23, - 0x18, 0x1D, 0x21, 0x26, - 0x18, 0x1F, 0x23, 0x26, - 0x18, 0x1B, 0x23, 0x26, - 0x18, 0x1B, 0x1F, 0x26, - 0x18, 0x26, 0x26, 0x26, - 0x18, 0x18, 0x26, 0x26, - 0x18, 0x18, 0x18, 0x26, - 0x18, 0x1E, 0x23, 0x29, - 0x18, 0x20, 0x25, 0x29, - 0x18, 0x1C, 0x25, 0x29, - 0x18, 0x1C, 0x21, 0x29, - 0x18, 0x29, 0x29, 0x29, - 0x18, 0x18, 0x29, 0x29, - 0x18, 0x18, 0x18, 0x29, - 0x18, 0x1F, 0x25, 0x2C, - 0x18, 0x22, 0x27, 0x2C, - 0x18, 0x1D, 0x27, 0x2C, - 0x18, 0x1D, 0x22, 0x2C, - 0x18, 0x2C, 0x2C, 0x2C, - 0x18, 0x18, 0x2C, 0x2C, - 0x18, 0x18, 0x18, 0x2C, - 0x18, 0x23, 0x2A, 0x2F, - 0x18, 0x1D, 0x2A, 0x2F, - 0x18, 0x1D, 0x24, 0x2F, - 0x18, 0x2F, 0x2F, 0x2F, - 0x18, 0x18, 0x2F, 0x2F, - 0x18, 0x18, 0x18, 0x2F, - 0x18, 0x25, 0x2C, 0x32, - 0x18, 0x1E, 0x2C, 0x32, - 0x18, 0x1E, 0x25, 0x32, - 0x18, 0x32, 0x32, 0x32, - 0x18, 0x18, 0x32, 0x32, - 0x18, 0x18, 0x18, 0x32, - 0x18, 0x26, 0x2E, 0x35, - 0x18, 0x1F, 0x2E, 0x35, - 0x18, 0x1F, 0x27, 0x35, - 0x18, 0x35, 0x35, 0x35, - 0x18, 0x18, 0x35, 0x35, - 0x18, 0x18, 0x18, 0x35, - 0x18, 0x28, 0x30, 0x38, - 0x18, 0x20, 0x30, 0x38, - 0x18, 0x20, 0x28, 0x38, - 0x18, 0x38, 0x38, 0x38, - 0x18, 0x18, 0x38, 0x38, - 0x18, 0x18, 0x18, 0x38, - 0x18, 0x3B, 0x3B, 0x3B, - 0x18, 0x18, 0x3B, 0x3B, - 0x18, 0x18, 0x18, 0x3B, - 0x18, 0x2A, 0x33, 0x3C, - 0x18, 0x21, 0x33, 0x3C, - 0x18, 0x21, 0x2A, 0x3C, - 0x19, 0x1A, 0x1A, 0x1B, - 0x19, 0x1A, 0x1B, 0x1C, - 0x19, 0x1B, 0x1C, 0x1D, - 0x19, 0x1A, 0x1C, 0x1D, - 0x19, 0x1A, 0x1B, 0x1D, - 0x19, 0x1B, 0x1C, 0x1E, - 0x19, 0x1B, 0x1D, 0x1E, - 0x19, 0x1A, 0x1D, 0x1E, - 0x19, 0x1A, 0x1C, 0x1E, - 0x19, 0x1B, 0x1D, 0x1F, - 0x19, 0x1C, 0x1E, 0x1F, - 0x19, 0x1A, 0x1E, 0x1F, - 0x19, 0x1A, 0x1C, 0x1F, - 0x19, 0x1F, 0x1F, 0x1F, - 0x19, 0x19, 0x1F, 0x1F, - 0x19, 0x19, 0x19, 0x1F, - 0x19, 0x1C, 0x1D, 0x20, - 0x19, 0x1C, 0x1F, 0x20, - 0x19, 0x1A, 0x1F, 0x20, - 0x19, 0x1A, 0x1D, 0x20, - 0x19, 0x1C, 0x1E, 0x21, - 0x19, 0x1D, 0x1F, 0x21, - 0x19, 0x1B, 0x1F, 0x21, - 0x19, 0x1B, 0x1D, 0x21, - 0x19, 0x21, 0x21, 0x21, - 0x19, 0x19, 0x21, 0x21, - 0x19, 0x19, 0x19, 0x21, - 0x19, 0x1D, 0x20, 0x24, - 0x19, 0x1E, 0x22, 0x24, - 0x19, 0x1B, 0x22, 0x24, - 0x19, 0x1B, 0x1F, 0x24, - 0x19, 0x24, 0x24, 0x24, - 0x19, 0x19, 0x24, 0x24, - 0x19, 0x19, 0x19, 0x24, - 0x19, 0x1E, 0x22, 0x27, - 0x19, 0x20, 0x24, 0x27, - 0x19, 0x1C, 0x24, 0x27, - 0x19, 0x1C, 0x20, 0x27, - 0x19, 0x27, 0x27, 0x27, - 0x19, 0x19, 0x27, 0x27, - 0x19, 0x19, 0x19, 0x27, - 0x19, 0x1F, 0x24, 0x2A, - 0x19, 0x21, 0x26, 0x2A, - 0x19, 0x1D, 0x26, 0x2A, - 0x19, 0x1D, 0x22, 0x2A, - 0x19, 0x2A, 0x2A, 0x2A, - 0x19, 0x19, 0x2A, 0x2A, - 0x19, 0x19, 0x19, 0x2A, - 0x19, 0x20, 0x26, 0x2D, - 0x19, 0x23, 0x28, 0x2D, - 0x19, 0x1E, 0x28, 0x2D, - 0x19, 0x1E, 0x23, 0x2D, - 0x19, 0x2D, 0x2D, 0x2D, - 0x19, 0x19, 0x2D, 0x2D, - 0x19, 0x19, 0x19, 0x2D, - 0x19, 0x24, 0x2B, 0x30, - 0x19, 0x1E, 0x2B, 0x30, - 0x19, 0x1E, 0x25, 0x30, - 0x19, 0x30, 0x30, 0x30, - 0x19, 0x19, 0x30, 0x30, - 0x19, 0x19, 0x19, 0x30, - 0x19, 0x26, 0x2D, 0x33, - 0x19, 0x1F, 0x2D, 0x33, - 0x19, 0x1F, 0x26, 0x33, - 0x19, 0x33, 0x33, 0x33, - 0x19, 0x19, 0x33, 0x33, - 0x19, 0x19, 0x19, 0x33, - 0x19, 0x27, 0x2F, 0x36, - 0x19, 0x20, 0x2F, 0x36, - 0x19, 0x20, 0x28, 0x36, - 0x19, 0x36, 0x36, 0x36, - 0x19, 0x19, 0x36, 0x36, - 0x19, 0x19, 0x19, 0x36, - 0x19, 0x29, 0x31, 0x39, - 0x19, 0x21, 0x31, 0x39, - 0x19, 0x21, 0x29, 0x39, - 0x19, 0x39, 0x39, 0x39, - 0x19, 0x19, 0x39, 0x39, - 0x19, 0x19, 0x19, 0x39, - 0x19, 0x3C, 0x3C, 0x3C, - 0x19, 0x19, 0x3C, 0x3C, - 0x19, 0x19, 0x19, 0x3C, - 0x19, 0x2B, 0x34, 0x3D, - 0x19, 0x22, 0x34, 0x3D, - 0x19, 0x22, 0x2B, 0x3D, - 0x1A, 0x1B, 0x1B, 0x1C, - 0x1A, 0x1B, 0x1C, 0x1D, - 0x1A, 0x1C, 0x1D, 0x1E, - 0x1A, 0x1B, 0x1D, 0x1E, - 0x1A, 0x1B, 0x1C, 0x1E, - 0x1A, 0x1C, 0x1D, 0x1F, - 0x1A, 0x1C, 0x1E, 0x1F, - 0x1A, 0x1B, 0x1E, 0x1F, - 0x1A, 0x1B, 0x1D, 0x1F, - 0x1A, 0x1C, 0x1E, 0x20, - 0x1A, 0x1D, 0x1F, 0x20, - 0x1A, 0x1B, 0x1F, 0x20, - 0x1A, 0x1B, 0x1D, 0x20, - 0x1A, 0x20, 0x20, 0x20, - 0x1A, 0x1A, 0x20, 0x20, - 0x1A, 0x1A, 0x1A, 0x20, - 0x1A, 0x1D, 0x1E, 0x21, - 0x1A, 0x1D, 0x20, 0x21, - 0x1A, 0x1B, 0x20, 0x21, - 0x1A, 0x1B, 0x1E, 0x21, - 0x1A, 0x1D, 0x1F, 0x22, - 0x1A, 0x1E, 0x20, 0x22, - 0x1A, 0x1C, 0x20, 0x22, - 0x1A, 0x1C, 0x1E, 0x22, - 0x1A, 0x22, 0x22, 0x22, - 0x1A, 0x1A, 0x22, 0x22, - 0x1A, 0x1A, 0x1A, 0x22, - 0x1A, 0x1E, 0x21, 0x25, - 0x1A, 0x1F, 0x23, 0x25, - 0x1A, 0x1C, 0x23, 0x25, - 0x1A, 0x1C, 0x20, 0x25, - 0x1A, 0x25, 0x25, 0x25, - 0x1A, 0x1A, 0x25, 0x25, - 0x1A, 0x1A, 0x1A, 0x25, - 0x1A, 0x1F, 0x23, 0x28, - 0x1A, 0x21, 0x25, 0x28, - 0x1A, 0x1D, 0x25, 0x28, - 0x1A, 0x1D, 0x21, 0x28, - 0x1A, 0x28, 0x28, 0x28, - 0x1A, 0x1A, 0x28, 0x28, - 0x1A, 0x1A, 0x1A, 0x28, - 0x1A, 0x20, 0x25, 0x2B, - 0x1A, 0x22, 0x27, 0x2B, - 0x1A, 0x1E, 0x27, 0x2B, - 0x1A, 0x1E, 0x23, 0x2B, - 0x1A, 0x2B, 0x2B, 0x2B, - 0x1A, 0x1A, 0x2B, 0x2B, - 0x1A, 0x1A, 0x1A, 0x2B, - 0x1A, 0x21, 0x27, 0x2E, - 0x1A, 0x24, 0x29, 0x2E, - 0x1A, 0x1F, 0x29, 0x2E, - 0x1A, 0x1F, 0x24, 0x2E, - 0x1A, 0x2E, 0x2E, 0x2E, - 0x1A, 0x1A, 0x2E, 0x2E, - 0x1A, 0x1A, 0x1A, 0x2E, - 0x1A, 0x25, 0x2C, 0x31, - 0x1A, 0x1F, 0x2C, 0x31, - 0x1A, 0x1F, 0x26, 0x31, - 0x1A, 0x31, 0x31, 0x31, - 0x1A, 0x1A, 0x31, 0x31, - 0x1A, 0x1A, 0x1A, 0x31, - 0x1A, 0x27, 0x2E, 0x34, - 0x1A, 0x20, 0x2E, 0x34, - 0x1A, 0x20, 0x27, 0x34, - 0x1A, 0x34, 0x34, 0x34, - 0x1A, 0x1A, 0x34, 0x34, - 0x1A, 0x1A, 0x1A, 0x34, - 0x1A, 0x28, 0x30, 0x37, - 0x1A, 0x21, 0x30, 0x37, - 0x1A, 0x21, 0x29, 0x37, - 0x1A, 0x37, 0x37, 0x37, - 0x1A, 0x1A, 0x37, 0x37, - 0x1A, 0x1A, 0x1A, 0x37, - 0x1A, 0x2A, 0x32, 0x3A, - 0x1A, 0x22, 0x32, 0x3A, - 0x1A, 0x22, 0x2A, 0x3A, - 0x1A, 0x3A, 0x3A, 0x3A, - 0x1A, 0x1A, 0x3A, 0x3A, - 0x1A, 0x1A, 0x1A, 0x3A, - 0x1A, 0x3D, 0x3D, 0x3D, - 0x1A, 0x1A, 0x3D, 0x3D, - 0x1A, 0x1A, 0x1A, 0x3D, - 0x1A, 0x2C, 0x35, 0x3E, - 0x1A, 0x23, 0x35, 0x3E, - 0x1A, 0x23, 0x2C, 0x3E, - 0x1B, 0x1C, 0x1C, 0x1D, - 0x1B, 0x1C, 0x1D, 0x1E, - 0x1B, 0x1D, 0x1E, 0x1F, - 0x1B, 0x1C, 0x1E, 0x1F, - 0x1B, 0x1C, 0x1D, 0x1F, - 0x1B, 0x1D, 0x1E, 0x20, - 0x1B, 0x1D, 0x1F, 0x20, - 0x1B, 0x1C, 0x1F, 0x20, - 0x1B, 0x1C, 0x1E, 0x20, - 0x1B, 0x1D, 0x1F, 0x21, - 0x1B, 0x1E, 0x20, 0x21, - 0x1B, 0x1C, 0x20, 0x21, - 0x1B, 0x1C, 0x1E, 0x21, - 0x1B, 0x21, 0x21, 0x21, - 0x1B, 0x1B, 0x21, 0x21, - 0x1B, 0x1B, 0x1B, 0x21, - 0x1B, 0x1E, 0x1F, 0x22, - 0x1B, 0x1E, 0x21, 0x22, - 0x1B, 0x1C, 0x21, 0x22, - 0x1B, 0x1C, 0x1F, 0x22, - 0x1B, 0x1E, 0x20, 0x23, - 0x1B, 0x1F, 0x21, 0x23, - 0x1B, 0x1D, 0x21, 0x23, - 0x1B, 0x1D, 0x1F, 0x23, - 0x1B, 0x23, 0x23, 0x23, - 0x1B, 0x1B, 0x23, 0x23, - 0x1B, 0x1B, 0x1B, 0x23, - 0x1B, 0x1F, 0x22, 0x26, - 0x1B, 0x20, 0x24, 0x26, - 0x1B, 0x1D, 0x24, 0x26, - 0x1B, 0x1D, 0x21, 0x26, - 0x1B, 0x26, 0x26, 0x26, - 0x1B, 0x1B, 0x26, 0x26, - 0x1B, 0x1B, 0x1B, 0x26, - 0x1B, 0x20, 0x24, 0x29, - 0x1B, 0x22, 0x26, 0x29, - 0x1B, 0x1E, 0x26, 0x29, - 0x1B, 0x1E, 0x22, 0x29, - 0x1B, 0x29, 0x29, 0x29, - 0x1B, 0x1B, 0x29, 0x29, - 0x1B, 0x1B, 0x1B, 0x29, - 0x1B, 0x21, 0x26, 0x2C, - 0x1B, 0x23, 0x28, 0x2C, - 0x1B, 0x1F, 0x28, 0x2C, - 0x1B, 0x1F, 0x24, 0x2C, - 0x1B, 0x2C, 0x2C, 0x2C, - 0x1B, 0x1B, 0x2C, 0x2C, - 0x1B, 0x1B, 0x1B, 0x2C, - 0x1B, 0x22, 0x28, 0x2F, - 0x1B, 0x25, 0x2A, 0x2F, - 0x1B, 0x20, 0x2A, 0x2F, - 0x1B, 0x20, 0x25, 0x2F, - 0x1B, 0x2F, 0x2F, 0x2F, - 0x1B, 0x1B, 0x2F, 0x2F, - 0x1B, 0x1B, 0x1B, 0x2F, - 0x1B, 0x26, 0x2D, 0x32, - 0x1B, 0x20, 0x2D, 0x32, - 0x1B, 0x20, 0x27, 0x32, - 0x1B, 0x32, 0x32, 0x32, - 0x1B, 0x1B, 0x32, 0x32, - 0x1B, 0x1B, 0x1B, 0x32, - 0x1B, 0x28, 0x2F, 0x35, - 0x1B, 0x21, 0x2F, 0x35, - 0x1B, 0x21, 0x28, 0x35, - 0x1B, 0x35, 0x35, 0x35, - 0x1B, 0x1B, 0x35, 0x35, - 0x1B, 0x1B, 0x1B, 0x35, - 0x1B, 0x29, 0x31, 0x38, - 0x1B, 0x22, 0x31, 0x38, - 0x1B, 0x22, 0x2A, 0x38, - 0x1B, 0x38, 0x38, 0x38, - 0x1B, 0x1B, 0x38, 0x38, - 0x1B, 0x1B, 0x1B, 0x38, - 0x1B, 0x2B, 0x33, 0x3B, - 0x1B, 0x23, 0x33, 0x3B, - 0x1B, 0x23, 0x2B, 0x3B, - 0x1B, 0x3B, 0x3B, 0x3B, - 0x1B, 0x1B, 0x3B, 0x3B, - 0x1B, 0x1B, 0x1B, 0x3B, - 0x1B, 0x3E, 0x3E, 0x3E, - 0x1B, 0x1B, 0x3E, 0x3E, - 0x1B, 0x1B, 0x1B, 0x3E, - 0x1B, 0x2D, 0x36, 0x3F, - 0x1B, 0x24, 0x36, 0x3F, - 0x1B, 0x24, 0x2D, 0x3F, - 0x1C, 0x1D, 0x1D, 0x1E, - 0x1C, 0x1D, 0x1E, 0x1F, - 0x1C, 0x1E, 0x1F, 0x20, - 0x1C, 0x1D, 0x1F, 0x20, - 0x1C, 0x1D, 0x1E, 0x20, - 0x1C, 0x1E, 0x1F, 0x21, - 0x1C, 0x1E, 0x20, 0x21, - 0x1C, 0x1D, 0x20, 0x21, - 0x1C, 0x1D, 0x1F, 0x21, - 0x1C, 0x1E, 0x20, 0x22, - 0x1C, 0x1F, 0x21, 0x22, - 0x1C, 0x1D, 0x21, 0x22, - 0x1C, 0x1D, 0x1F, 0x22, - 0x1C, 0x22, 0x22, 0x22, - 0x1C, 0x1C, 0x22, 0x22, - 0x1C, 0x1C, 0x1C, 0x22, - 0x1C, 0x1F, 0x20, 0x23, - 0x1C, 0x1F, 0x22, 0x23, - 0x1C, 0x1D, 0x22, 0x23, - 0x1C, 0x1D, 0x20, 0x23, - 0x1C, 0x1F, 0x21, 0x24, - 0x1C, 0x20, 0x22, 0x24, - 0x1C, 0x1E, 0x22, 0x24, - 0x1C, 0x1E, 0x20, 0x24, - 0x1C, 0x24, 0x24, 0x24, - 0x1C, 0x1C, 0x24, 0x24, - 0x1C, 0x1C, 0x1C, 0x24, - 0x1C, 0x20, 0x23, 0x27, - 0x1C, 0x21, 0x25, 0x27, - 0x1C, 0x1E, 0x25, 0x27, - 0x1C, 0x1E, 0x22, 0x27, - 0x1C, 0x27, 0x27, 0x27, - 0x1C, 0x1C, 0x27, 0x27, - 0x1C, 0x1C, 0x1C, 0x27, - 0x1C, 0x21, 0x25, 0x2A, - 0x1C, 0x23, 0x27, 0x2A, - 0x1C, 0x1F, 0x27, 0x2A, - 0x1C, 0x1F, 0x23, 0x2A, - 0x1C, 0x2A, 0x2A, 0x2A, - 0x1C, 0x1C, 0x2A, 0x2A, - 0x1C, 0x1C, 0x1C, 0x2A, - 0x1C, 0x22, 0x27, 0x2D, - 0x1C, 0x24, 0x29, 0x2D, - 0x1C, 0x20, 0x29, 0x2D, - 0x1C, 0x20, 0x25, 0x2D, - 0x1C, 0x2D, 0x2D, 0x2D, - 0x1C, 0x1C, 0x2D, 0x2D, - 0x1C, 0x1C, 0x1C, 0x2D, - 0x1C, 0x23, 0x29, 0x30, - 0x1C, 0x26, 0x2B, 0x30, - 0x1C, 0x21, 0x2B, 0x30, - 0x1C, 0x21, 0x26, 0x30, - 0x1C, 0x30, 0x30, 0x30, - 0x1C, 0x1C, 0x30, 0x30, - 0x1C, 0x1C, 0x1C, 0x30, - 0x1C, 0x27, 0x2E, 0x33, - 0x1C, 0x21, 0x2E, 0x33, - 0x1C, 0x21, 0x28, 0x33, - 0x1C, 0x33, 0x33, 0x33, - 0x1C, 0x1C, 0x33, 0x33, - 0x1C, 0x1C, 0x1C, 0x33, - 0x1C, 0x29, 0x30, 0x36, - 0x1C, 0x22, 0x30, 0x36, - 0x1C, 0x22, 0x29, 0x36, - 0x1C, 0x36, 0x36, 0x36, - 0x1C, 0x1C, 0x36, 0x36, - 0x1C, 0x1C, 0x1C, 0x36, - 0x1C, 0x2A, 0x32, 0x39, - 0x1C, 0x23, 0x32, 0x39, - 0x1C, 0x23, 0x2B, 0x39, - 0x1C, 0x39, 0x39, 0x39, - 0x1C, 0x1C, 0x39, 0x39, - 0x1C, 0x1C, 0x1C, 0x39, - 0x1C, 0x2C, 0x34, 0x3C, - 0x1C, 0x24, 0x34, 0x3C, - 0x1C, 0x24, 0x2C, 0x3C, - 0x1C, 0x3C, 0x3C, 0x3C, - 0x1C, 0x1C, 0x3C, 0x3C, - 0x1C, 0x1C, 0x1C, 0x3C, - 0x1C, 0x3F, 0x3F, 0x3F, - 0x1C, 0x1C, 0x3F, 0x3F, - 0x1C, 0x1C, 0x1C, 0x3F, - 0x1D, 0x1E, 0x1E, 0x1F, - 0x1D, 0x1E, 0x1F, 0x20, - 0x1D, 0x1F, 0x20, 0x21, - 0x1D, 0x1E, 0x20, 0x21, - 0x1D, 0x1E, 0x1F, 0x21, - 0x1D, 0x1F, 0x20, 0x22, - 0x1D, 0x1F, 0x21, 0x22, - 0x1D, 0x1E, 0x21, 0x22, - 0x1D, 0x1E, 0x20, 0x22, - 0x1D, 0x1F, 0x21, 0x23, - 0x1D, 0x20, 0x22, 0x23, - 0x1D, 0x1E, 0x22, 0x23, - 0x1D, 0x1E, 0x20, 0x23, - 0x1D, 0x23, 0x23, 0x23, - 0x1D, 0x1D, 0x23, 0x23, - 0x1D, 0x1D, 0x1D, 0x23, - 0x1D, 0x20, 0x21, 0x24, - 0x1D, 0x20, 0x23, 0x24, - 0x1D, 0x1E, 0x23, 0x24, - 0x1D, 0x1E, 0x21, 0x24, - 0x1D, 0x20, 0x22, 0x25, - 0x1D, 0x21, 0x23, 0x25, - 0x1D, 0x1F, 0x23, 0x25, - 0x1D, 0x1F, 0x21, 0x25, - 0x1D, 0x25, 0x25, 0x25, - 0x1D, 0x1D, 0x25, 0x25, - 0x1D, 0x1D, 0x1D, 0x25, - 0x1D, 0x21, 0x24, 0x28, - 0x1D, 0x22, 0x26, 0x28, - 0x1D, 0x1F, 0x26, 0x28, - 0x1D, 0x1F, 0x23, 0x28, - 0x1D, 0x28, 0x28, 0x28, - 0x1D, 0x1D, 0x28, 0x28, - 0x1D, 0x1D, 0x1D, 0x28, - 0x1D, 0x22, 0x26, 0x2B, - 0x1D, 0x24, 0x28, 0x2B, - 0x1D, 0x20, 0x28, 0x2B, - 0x1D, 0x20, 0x24, 0x2B, - 0x1D, 0x2B, 0x2B, 0x2B, - 0x1D, 0x1D, 0x2B, 0x2B, - 0x1D, 0x1D, 0x1D, 0x2B, - 0x1D, 0x23, 0x28, 0x2E, - 0x1D, 0x25, 0x2A, 0x2E, - 0x1D, 0x21, 0x2A, 0x2E, - 0x1D, 0x21, 0x26, 0x2E, - 0x1D, 0x2E, 0x2E, 0x2E, - 0x1D, 0x1D, 0x2E, 0x2E, - 0x1D, 0x1D, 0x1D, 0x2E, - 0x1D, 0x24, 0x2A, 0x31, - 0x1D, 0x27, 0x2C, 0x31, - 0x1D, 0x22, 0x2C, 0x31, - 0x1D, 0x22, 0x27, 0x31, - 0x1D, 0x31, 0x31, 0x31, - 0x1D, 0x1D, 0x31, 0x31, - 0x1D, 0x1D, 0x1D, 0x31, - 0x1D, 0x28, 0x2F, 0x34, - 0x1D, 0x22, 0x2F, 0x34, - 0x1D, 0x22, 0x29, 0x34, - 0x1D, 0x34, 0x34, 0x34, - 0x1D, 0x1D, 0x34, 0x34, - 0x1D, 0x1D, 0x1D, 0x34, - 0x1D, 0x2A, 0x31, 0x37, - 0x1D, 0x23, 0x31, 0x37, - 0x1D, 0x23, 0x2A, 0x37, - 0x1D, 0x37, 0x37, 0x37, - 0x1D, 0x1D, 0x37, 0x37, - 0x1D, 0x1D, 0x1D, 0x37, - 0x1D, 0x2B, 0x33, 0x3A, - 0x1D, 0x24, 0x33, 0x3A, - 0x1D, 0x24, 0x2C, 0x3A, - 0x1D, 0x3A, 0x3A, 0x3A, - 0x1D, 0x1D, 0x3A, 0x3A, - 0x1D, 0x1D, 0x1D, 0x3A, - 0x1D, 0x2D, 0x35, 0x3D, - 0x1D, 0x25, 0x35, 0x3D, - 0x1D, 0x25, 0x2D, 0x3D, - 0x1D, 0x3D, 0x3D, 0x3D, - 0x1D, 0x1D, 0x3D, 0x3D, - 0x1D, 0x1D, 0x1D, 0x3D, - 0x1E, 0x1F, 0x1F, 0x20, - 0x1E, 0x1F, 0x20, 0x21, - 0x1E, 0x20, 0x21, 0x22, - 0x1E, 0x1F, 0x21, 0x22, - 0x1E, 0x1F, 0x20, 0x22, - 0x1E, 0x20, 0x21, 0x23, - 0x1E, 0x20, 0x22, 0x23, - 0x1E, 0x1F, 0x22, 0x23, - 0x1E, 0x1F, 0x21, 0x23, - 0x1E, 0x20, 0x22, 0x24, - 0x1E, 0x21, 0x23, 0x24, - 0x1E, 0x1F, 0x23, 0x24, - 0x1E, 0x1F, 0x21, 0x24, - 0x1E, 0x24, 0x24, 0x24, - 0x1E, 0x1E, 0x24, 0x24, - 0x1E, 0x1E, 0x1E, 0x24, - 0x1E, 0x21, 0x22, 0x25, - 0x1E, 0x21, 0x24, 0x25, - 0x1E, 0x1F, 0x24, 0x25, - 0x1E, 0x1F, 0x22, 0x25, - 0x1E, 0x21, 0x23, 0x26, - 0x1E, 0x22, 0x24, 0x26, - 0x1E, 0x20, 0x24, 0x26, - 0x1E, 0x20, 0x22, 0x26, - 0x1E, 0x26, 0x26, 0x26, - 0x1E, 0x1E, 0x26, 0x26, - 0x1E, 0x1E, 0x1E, 0x26, - 0x1E, 0x22, 0x25, 0x29, - 0x1E, 0x23, 0x27, 0x29, - 0x1E, 0x20, 0x27, 0x29, - 0x1E, 0x20, 0x24, 0x29, - 0x1E, 0x29, 0x29, 0x29, - 0x1E, 0x1E, 0x29, 0x29, - 0x1E, 0x1E, 0x1E, 0x29, - 0x1E, 0x23, 0x27, 0x2C, - 0x1E, 0x25, 0x29, 0x2C, - 0x1E, 0x21, 0x29, 0x2C, - 0x1E, 0x21, 0x25, 0x2C, - 0x1E, 0x2C, 0x2C, 0x2C, - 0x1E, 0x1E, 0x2C, 0x2C, - 0x1E, 0x1E, 0x1E, 0x2C, - 0x1E, 0x24, 0x29, 0x2F, - 0x1E, 0x26, 0x2B, 0x2F, - 0x1E, 0x22, 0x2B, 0x2F, - 0x1E, 0x22, 0x27, 0x2F, - 0x1E, 0x2F, 0x2F, 0x2F, - 0x1E, 0x1E, 0x2F, 0x2F, - 0x1E, 0x1E, 0x1E, 0x2F, - 0x1E, 0x25, 0x2B, 0x32, - 0x1E, 0x28, 0x2D, 0x32, - 0x1E, 0x23, 0x2D, 0x32, - 0x1E, 0x23, 0x28, 0x32, - 0x1E, 0x32, 0x32, 0x32, - 0x1E, 0x1E, 0x32, 0x32, - 0x1E, 0x1E, 0x1E, 0x32, - 0x1E, 0x29, 0x30, 0x35, - 0x1E, 0x23, 0x30, 0x35, - 0x1E, 0x23, 0x2A, 0x35, - 0x1E, 0x35, 0x35, 0x35, - 0x1E, 0x1E, 0x35, 0x35, - 0x1E, 0x1E, 0x1E, 0x35, - 0x1E, 0x2B, 0x32, 0x38, - 0x1E, 0x24, 0x32, 0x38, - 0x1E, 0x24, 0x2B, 0x38, - 0x1E, 0x38, 0x38, 0x38, - 0x1E, 0x1E, 0x38, 0x38, - 0x1E, 0x1E, 0x1E, 0x38, - 0x1E, 0x2C, 0x34, 0x3B, - 0x1E, 0x25, 0x34, 0x3B, - 0x1E, 0x25, 0x2D, 0x3B, - 0x1E, 0x3B, 0x3B, 0x3B, - 0x1E, 0x1E, 0x3B, 0x3B, - 0x1E, 0x1E, 0x1E, 0x3B, - 0x1E, 0x2E, 0x36, 0x3E, - 0x1E, 0x26, 0x36, 0x3E, - 0x1E, 0x26, 0x2E, 0x3E, - 0x1E, 0x3E, 0x3E, 0x3E, - 0x1E, 0x1E, 0x3E, 0x3E, - 0x1E, 0x1E, 0x1E, 0x3E, - 0x1F, 0x20, 0x20, 0x21, - 0x1F, 0x20, 0x21, 0x22, - 0x1F, 0x21, 0x22, 0x23, - 0x1F, 0x20, 0x22, 0x23, - 0x1F, 0x20, 0x21, 0x23, - 0x1F, 0x21, 0x22, 0x24, - 0x1F, 0x21, 0x23, 0x24, - 0x1F, 0x20, 0x23, 0x24, - 0x1F, 0x20, 0x22, 0x24, - 0x1F, 0x21, 0x23, 0x25, - 0x1F, 0x22, 0x24, 0x25, - 0x1F, 0x20, 0x24, 0x25, - 0x1F, 0x20, 0x22, 0x25, - 0x1F, 0x25, 0x25, 0x25, - 0x1F, 0x1F, 0x25, 0x25, - 0x1F, 0x1F, 0x1F, 0x25, - 0x1F, 0x22, 0x23, 0x26, - 0x1F, 0x22, 0x25, 0x26, - 0x1F, 0x20, 0x25, 0x26, - 0x1F, 0x20, 0x23, 0x26, - 0x1F, 0x22, 0x24, 0x27, - 0x1F, 0x23, 0x25, 0x27, - 0x1F, 0x21, 0x25, 0x27, - 0x1F, 0x21, 0x23, 0x27, - 0x1F, 0x27, 0x27, 0x27, - 0x1F, 0x1F, 0x27, 0x27, - 0x1F, 0x1F, 0x1F, 0x27, - 0x1F, 0x23, 0x26, 0x2A, - 0x1F, 0x24, 0x28, 0x2A, - 0x1F, 0x21, 0x28, 0x2A, - 0x1F, 0x21, 0x25, 0x2A, - 0x1F, 0x2A, 0x2A, 0x2A, - 0x1F, 0x1F, 0x2A, 0x2A, - 0x1F, 0x1F, 0x1F, 0x2A, - 0x1F, 0x24, 0x28, 0x2D, - 0x1F, 0x26, 0x2A, 0x2D, - 0x1F, 0x22, 0x2A, 0x2D, - 0x1F, 0x22, 0x26, 0x2D, - 0x1F, 0x2D, 0x2D, 0x2D, - 0x1F, 0x1F, 0x2D, 0x2D, - 0x1F, 0x1F, 0x1F, 0x2D, - 0x1F, 0x25, 0x2A, 0x30, - 0x1F, 0x27, 0x2C, 0x30, - 0x1F, 0x23, 0x2C, 0x30, - 0x1F, 0x23, 0x28, 0x30, - 0x1F, 0x30, 0x30, 0x30, - 0x1F, 0x1F, 0x30, 0x30, - 0x1F, 0x1F, 0x1F, 0x30, - 0x1F, 0x26, 0x2C, 0x33, - 0x1F, 0x29, 0x2E, 0x33, - 0x1F, 0x24, 0x2E, 0x33, - 0x1F, 0x24, 0x29, 0x33, - 0x1F, 0x33, 0x33, 0x33, - 0x1F, 0x1F, 0x33, 0x33, - 0x1F, 0x1F, 0x1F, 0x33, - 0x1F, 0x2A, 0x31, 0x36, - 0x1F, 0x24, 0x31, 0x36, - 0x1F, 0x24, 0x2B, 0x36, - 0x1F, 0x36, 0x36, 0x36, - 0x1F, 0x1F, 0x36, 0x36, - 0x1F, 0x1F, 0x1F, 0x36, - 0x1F, 0x2C, 0x33, 0x39, - 0x1F, 0x25, 0x33, 0x39, - 0x1F, 0x25, 0x2C, 0x39, - 0x1F, 0x39, 0x39, 0x39, - 0x1F, 0x1F, 0x39, 0x39, - 0x1F, 0x1F, 0x1F, 0x39, - 0x1F, 0x2D, 0x35, 0x3C, - 0x1F, 0x26, 0x35, 0x3C, - 0x1F, 0x26, 0x2E, 0x3C, - 0x1F, 0x3C, 0x3C, 0x3C, - 0x1F, 0x1F, 0x3C, 0x3C, - 0x1F, 0x1F, 0x1F, 0x3C, - 0x1F, 0x2F, 0x37, 0x3F, - 0x1F, 0x27, 0x37, 0x3F, - 0x1F, 0x27, 0x2F, 0x3F, - 0x1F, 0x3F, 0x3F, 0x3F, - 0x1F, 0x1F, 0x3F, 0x3F, - 0x1F, 0x1F, 0x1F, 0x3F, - 0x20, 0x21, 0x21, 0x22, - 0x20, 0x21, 0x22, 0x23, - 0x20, 0x22, 0x23, 0x24, - 0x20, 0x21, 0x23, 0x24, - 0x20, 0x21, 0x22, 0x24, - 0x20, 0x22, 0x23, 0x25, - 0x20, 0x22, 0x24, 0x25, - 0x20, 0x21, 0x24, 0x25, - 0x20, 0x21, 0x23, 0x25, - 0x20, 0x22, 0x24, 0x26, - 0x20, 0x23, 0x25, 0x26, - 0x20, 0x21, 0x25, 0x26, - 0x20, 0x21, 0x23, 0x26, - 0x20, 0x26, 0x26, 0x26, - 0x20, 0x20, 0x26, 0x26, - 0x20, 0x20, 0x20, 0x26, - 0x20, 0x23, 0x24, 0x27, - 0x20, 0x23, 0x26, 0x27, - 0x20, 0x21, 0x26, 0x27, - 0x20, 0x21, 0x24, 0x27, - 0x20, 0x23, 0x25, 0x28, - 0x20, 0x24, 0x26, 0x28, - 0x20, 0x22, 0x26, 0x28, - 0x20, 0x22, 0x24, 0x28, - 0x20, 0x28, 0x28, 0x28, - 0x20, 0x20, 0x28, 0x28, - 0x20, 0x20, 0x20, 0x28, - 0x20, 0x24, 0x27, 0x2B, - 0x20, 0x25, 0x29, 0x2B, - 0x20, 0x22, 0x29, 0x2B, - 0x20, 0x22, 0x26, 0x2B, - 0x20, 0x2B, 0x2B, 0x2B, - 0x20, 0x20, 0x2B, 0x2B, - 0x20, 0x20, 0x20, 0x2B, - 0x20, 0x25, 0x29, 0x2E, - 0x20, 0x27, 0x2B, 0x2E, - 0x20, 0x23, 0x2B, 0x2E, - 0x20, 0x23, 0x27, 0x2E, - 0x20, 0x2E, 0x2E, 0x2E, - 0x20, 0x20, 0x2E, 0x2E, - 0x20, 0x20, 0x20, 0x2E, - 0x20, 0x26, 0x2B, 0x31, - 0x20, 0x28, 0x2D, 0x31, - 0x20, 0x24, 0x2D, 0x31, - 0x20, 0x24, 0x29, 0x31, - 0x20, 0x31, 0x31, 0x31, - 0x20, 0x20, 0x31, 0x31, - 0x20, 0x20, 0x20, 0x31, - 0x20, 0x27, 0x2D, 0x34, - 0x20, 0x2A, 0x2F, 0x34, - 0x20, 0x25, 0x2F, 0x34, - 0x20, 0x25, 0x2A, 0x34, - 0x20, 0x34, 0x34, 0x34, - 0x20, 0x20, 0x34, 0x34, - 0x20, 0x20, 0x20, 0x34, - 0x20, 0x2B, 0x32, 0x37, - 0x20, 0x25, 0x32, 0x37, - 0x20, 0x25, 0x2C, 0x37, - 0x20, 0x37, 0x37, 0x37, - 0x20, 0x20, 0x37, 0x37, - 0x20, 0x20, 0x20, 0x37, - 0x20, 0x2D, 0x34, 0x3A, - 0x20, 0x26, 0x34, 0x3A, - 0x20, 0x26, 0x2D, 0x3A, - 0x20, 0x3A, 0x3A, 0x3A, - 0x20, 0x20, 0x3A, 0x3A, - 0x20, 0x20, 0x20, 0x3A, - 0x20, 0x2E, 0x36, 0x3D, - 0x20, 0x27, 0x36, 0x3D, - 0x20, 0x27, 0x2F, 0x3D, - 0x20, 0x3D, 0x3D, 0x3D, - 0x20, 0x20, 0x3D, 0x3D, - 0x20, 0x20, 0x20, 0x3D, - 0x21, 0x22, 0x22, 0x23, - 0x21, 0x22, 0x23, 0x24, - 0x21, 0x23, 0x24, 0x25, - 0x21, 0x22, 0x24, 0x25, - 0x21, 0x22, 0x23, 0x25, - 0x21, 0x23, 0x24, 0x26, - 0x21, 0x23, 0x25, 0x26, - 0x21, 0x22, 0x25, 0x26, - 0x21, 0x22, 0x24, 0x26, - 0x21, 0x23, 0x25, 0x27, - 0x21, 0x24, 0x26, 0x27, - 0x21, 0x22, 0x26, 0x27, - 0x21, 0x22, 0x24, 0x27, - 0x21, 0x27, 0x27, 0x27, - 0x21, 0x21, 0x27, 0x27, - 0x21, 0x21, 0x21, 0x27, - 0x21, 0x24, 0x25, 0x28, - 0x21, 0x24, 0x27, 0x28, - 0x21, 0x22, 0x27, 0x28, - 0x21, 0x22, 0x25, 0x28, - 0x21, 0x24, 0x26, 0x29, - 0x21, 0x25, 0x27, 0x29, - 0x21, 0x23, 0x27, 0x29, - 0x21, 0x23, 0x25, 0x29, - 0x21, 0x29, 0x29, 0x29, - 0x21, 0x21, 0x29, 0x29, - 0x21, 0x21, 0x21, 0x29, - 0x21, 0x25, 0x28, 0x2C, - 0x21, 0x26, 0x2A, 0x2C, - 0x21, 0x23, 0x2A, 0x2C, - 0x21, 0x23, 0x27, 0x2C, - 0x21, 0x2C, 0x2C, 0x2C, - 0x21, 0x21, 0x2C, 0x2C, - 0x21, 0x21, 0x21, 0x2C, - 0x21, 0x26, 0x2A, 0x2F, - 0x21, 0x28, 0x2C, 0x2F, - 0x21, 0x24, 0x2C, 0x2F, - 0x21, 0x24, 0x28, 0x2F, - 0x21, 0x2F, 0x2F, 0x2F, - 0x21, 0x21, 0x2F, 0x2F, - 0x21, 0x21, 0x21, 0x2F, - 0x21, 0x27, 0x2C, 0x32, - 0x21, 0x29, 0x2E, 0x32, - 0x21, 0x25, 0x2E, 0x32, - 0x21, 0x25, 0x2A, 0x32, - 0x21, 0x32, 0x32, 0x32, - 0x21, 0x21, 0x32, 0x32, - 0x21, 0x21, 0x21, 0x32, - 0x21, 0x28, 0x2E, 0x35, - 0x21, 0x2B, 0x30, 0x35, - 0x21, 0x26, 0x30, 0x35, - 0x21, 0x26, 0x2B, 0x35, - 0x21, 0x35, 0x35, 0x35, - 0x21, 0x21, 0x35, 0x35, - 0x21, 0x21, 0x21, 0x35, - 0x21, 0x2C, 0x33, 0x38, - 0x21, 0x26, 0x33, 0x38, - 0x21, 0x26, 0x2D, 0x38, - 0x21, 0x38, 0x38, 0x38, - 0x21, 0x21, 0x38, 0x38, - 0x21, 0x21, 0x21, 0x38, - 0x21, 0x2E, 0x35, 0x3B, - 0x21, 0x27, 0x35, 0x3B, - 0x21, 0x27, 0x2E, 0x3B, - 0x21, 0x3B, 0x3B, 0x3B, - 0x21, 0x21, 0x3B, 0x3B, - 0x21, 0x21, 0x21, 0x3B, - 0x21, 0x2F, 0x37, 0x3E, - 0x21, 0x28, 0x37, 0x3E, - 0x21, 0x28, 0x30, 0x3E, - 0x21, 0x3E, 0x3E, 0x3E, - 0x21, 0x21, 0x3E, 0x3E, - 0x21, 0x21, 0x21, 0x3E, - 0x22, 0x23, 0x23, 0x24, - 0x22, 0x23, 0x24, 0x25, - 0x22, 0x24, 0x25, 0x26, - 0x22, 0x23, 0x25, 0x26, - 0x22, 0x23, 0x24, 0x26, - 0x22, 0x24, 0x25, 0x27, - 0x22, 0x24, 0x26, 0x27, - 0x22, 0x23, 0x26, 0x27, - 0x22, 0x23, 0x25, 0x27, - 0x22, 0x24, 0x26, 0x28, - 0x22, 0x25, 0x27, 0x28, - 0x22, 0x23, 0x27, 0x28, - 0x22, 0x23, 0x25, 0x28, - 0x22, 0x28, 0x28, 0x28, - 0x22, 0x22, 0x28, 0x28, - 0x22, 0x22, 0x22, 0x28, - 0x22, 0x25, 0x26, 0x29, - 0x22, 0x25, 0x28, 0x29, - 0x22, 0x23, 0x28, 0x29, - 0x22, 0x23, 0x26, 0x29, - 0x22, 0x25, 0x27, 0x2A, - 0x22, 0x26, 0x28, 0x2A, - 0x22, 0x24, 0x28, 0x2A, - 0x22, 0x24, 0x26, 0x2A, - 0x22, 0x2A, 0x2A, 0x2A, - 0x22, 0x22, 0x2A, 0x2A, - 0x22, 0x22, 0x22, 0x2A, - 0x22, 0x26, 0x29, 0x2D, - 0x22, 0x27, 0x2B, 0x2D, - 0x22, 0x24, 0x2B, 0x2D, - 0x22, 0x24, 0x28, 0x2D, - 0x22, 0x2D, 0x2D, 0x2D, - 0x22, 0x22, 0x2D, 0x2D, - 0x22, 0x22, 0x22, 0x2D, - 0x22, 0x27, 0x2B, 0x30, - 0x22, 0x29, 0x2D, 0x30, - 0x22, 0x25, 0x2D, 0x30, - 0x22, 0x25, 0x29, 0x30, - 0x22, 0x30, 0x30, 0x30, - 0x22, 0x22, 0x30, 0x30, - 0x22, 0x22, 0x22, 0x30, - 0x22, 0x28, 0x2D, 0x33, - 0x22, 0x2A, 0x2F, 0x33, - 0x22, 0x26, 0x2F, 0x33, - 0x22, 0x26, 0x2B, 0x33, - 0x22, 0x33, 0x33, 0x33, - 0x22, 0x22, 0x33, 0x33, - 0x22, 0x22, 0x22, 0x33, - 0x22, 0x29, 0x2F, 0x36, - 0x22, 0x2C, 0x31, 0x36, - 0x22, 0x27, 0x31, 0x36, - 0x22, 0x27, 0x2C, 0x36, - 0x22, 0x36, 0x36, 0x36, - 0x22, 0x22, 0x36, 0x36, - 0x22, 0x22, 0x22, 0x36, - 0x22, 0x2D, 0x34, 0x39, - 0x22, 0x27, 0x34, 0x39, - 0x22, 0x27, 0x2E, 0x39, - 0x22, 0x39, 0x39, 0x39, - 0x22, 0x22, 0x39, 0x39, - 0x22, 0x22, 0x22, 0x39, - 0x22, 0x2F, 0x36, 0x3C, - 0x22, 0x28, 0x36, 0x3C, - 0x22, 0x28, 0x2F, 0x3C, - 0x22, 0x3C, 0x3C, 0x3C, - 0x22, 0x22, 0x3C, 0x3C, - 0x22, 0x22, 0x22, 0x3C, - 0x22, 0x30, 0x38, 0x3F, - 0x22, 0x29, 0x38, 0x3F, - 0x22, 0x29, 0x31, 0x3F, - 0x22, 0x3F, 0x3F, 0x3F, - 0x22, 0x22, 0x3F, 0x3F, - 0x22, 0x22, 0x22, 0x3F, - 0x23, 0x24, 0x24, 0x25, - 0x23, 0x24, 0x25, 0x26, - 0x23, 0x25, 0x26, 0x27, - 0x23, 0x24, 0x26, 0x27, - 0x23, 0x24, 0x25, 0x27, - 0x23, 0x25, 0x26, 0x28, - 0x23, 0x25, 0x27, 0x28, - 0x23, 0x24, 0x27, 0x28, - 0x23, 0x24, 0x26, 0x28, - 0x23, 0x25, 0x27, 0x29, - 0x23, 0x26, 0x28, 0x29, - 0x23, 0x24, 0x28, 0x29, - 0x23, 0x24, 0x26, 0x29, - 0x23, 0x29, 0x29, 0x29, - 0x23, 0x23, 0x29, 0x29, - 0x23, 0x23, 0x23, 0x29, - 0x23, 0x26, 0x27, 0x2A, - 0x23, 0x26, 0x29, 0x2A, - 0x23, 0x24, 0x29, 0x2A, - 0x23, 0x24, 0x27, 0x2A, - 0x23, 0x26, 0x28, 0x2B, - 0x23, 0x27, 0x29, 0x2B, - 0x23, 0x25, 0x29, 0x2B, - 0x23, 0x25, 0x27, 0x2B, - 0x23, 0x2B, 0x2B, 0x2B, - 0x23, 0x23, 0x2B, 0x2B, - 0x23, 0x23, 0x23, 0x2B, - 0x23, 0x27, 0x2A, 0x2E, - 0x23, 0x28, 0x2C, 0x2E, - 0x23, 0x25, 0x2C, 0x2E, - 0x23, 0x25, 0x29, 0x2E, - 0x23, 0x2E, 0x2E, 0x2E, - 0x23, 0x23, 0x2E, 0x2E, - 0x23, 0x23, 0x23, 0x2E, - 0x23, 0x28, 0x2C, 0x31, - 0x23, 0x2A, 0x2E, 0x31, - 0x23, 0x26, 0x2E, 0x31, - 0x23, 0x26, 0x2A, 0x31, - 0x23, 0x31, 0x31, 0x31, - 0x23, 0x23, 0x31, 0x31, - 0x23, 0x23, 0x23, 0x31, - 0x23, 0x29, 0x2E, 0x34, - 0x23, 0x2B, 0x30, 0x34, - 0x23, 0x27, 0x30, 0x34, - 0x23, 0x27, 0x2C, 0x34, - 0x23, 0x34, 0x34, 0x34, - 0x23, 0x23, 0x34, 0x34, - 0x23, 0x23, 0x23, 0x34, - 0x23, 0x2A, 0x30, 0x37, - 0x23, 0x2D, 0x32, 0x37, - 0x23, 0x28, 0x32, 0x37, - 0x23, 0x28, 0x2D, 0x37, - 0x23, 0x37, 0x37, 0x37, - 0x23, 0x23, 0x37, 0x37, - 0x23, 0x23, 0x23, 0x37, - 0x23, 0x2E, 0x35, 0x3A, - 0x23, 0x28, 0x35, 0x3A, - 0x23, 0x28, 0x2F, 0x3A, - 0x23, 0x3A, 0x3A, 0x3A, - 0x23, 0x23, 0x3A, 0x3A, - 0x23, 0x23, 0x23, 0x3A, - 0x23, 0x30, 0x37, 0x3D, - 0x23, 0x29, 0x37, 0x3D, - 0x23, 0x29, 0x30, 0x3D, - 0x23, 0x3D, 0x3D, 0x3D, - 0x23, 0x23, 0x3D, 0x3D, - 0x23, 0x23, 0x23, 0x3D, - 0x24, 0x25, 0x25, 0x26, - 0x24, 0x25, 0x26, 0x27, - 0x24, 0x26, 0x27, 0x28, - 0x24, 0x25, 0x27, 0x28, - 0x24, 0x25, 0x26, 0x28, - 0x24, 0x26, 0x27, 0x29, - 0x24, 0x26, 0x28, 0x29, - 0x24, 0x25, 0x28, 0x29, - 0x24, 0x25, 0x27, 0x29, - 0x24, 0x26, 0x28, 0x2A, - 0x24, 0x27, 0x29, 0x2A, - 0x24, 0x25, 0x29, 0x2A, - 0x24, 0x25, 0x27, 0x2A, - 0x24, 0x2A, 0x2A, 0x2A, - 0x24, 0x24, 0x2A, 0x2A, - 0x24, 0x24, 0x24, 0x2A, - 0x24, 0x27, 0x28, 0x2B, - 0x24, 0x27, 0x2A, 0x2B, - 0x24, 0x25, 0x2A, 0x2B, - 0x24, 0x25, 0x28, 0x2B, - 0x24, 0x27, 0x29, 0x2C, - 0x24, 0x28, 0x2A, 0x2C, - 0x24, 0x26, 0x2A, 0x2C, - 0x24, 0x26, 0x28, 0x2C, - 0x24, 0x2C, 0x2C, 0x2C, - 0x24, 0x24, 0x2C, 0x2C, - 0x24, 0x24, 0x24, 0x2C, - 0x24, 0x28, 0x2B, 0x2F, - 0x24, 0x29, 0x2D, 0x2F, - 0x24, 0x26, 0x2D, 0x2F, - 0x24, 0x26, 0x2A, 0x2F, - 0x24, 0x2F, 0x2F, 0x2F, - 0x24, 0x24, 0x2F, 0x2F, - 0x24, 0x24, 0x24, 0x2F, - 0x24, 0x29, 0x2D, 0x32, - 0x24, 0x2B, 0x2F, 0x32, - 0x24, 0x27, 0x2F, 0x32, - 0x24, 0x27, 0x2B, 0x32, - 0x24, 0x32, 0x32, 0x32, - 0x24, 0x24, 0x32, 0x32, - 0x24, 0x24, 0x24, 0x32, - 0x24, 0x2A, 0x2F, 0x35, - 0x24, 0x2C, 0x31, 0x35, - 0x24, 0x28, 0x31, 0x35, - 0x24, 0x28, 0x2D, 0x35, - 0x24, 0x35, 0x35, 0x35, - 0x24, 0x24, 0x35, 0x35, - 0x24, 0x24, 0x24, 0x35, - 0x24, 0x2B, 0x31, 0x38, - 0x24, 0x2E, 0x33, 0x38, - 0x24, 0x29, 0x33, 0x38, - 0x24, 0x29, 0x2E, 0x38, - 0x24, 0x38, 0x38, 0x38, - 0x24, 0x24, 0x38, 0x38, - 0x24, 0x24, 0x24, 0x38, - 0x24, 0x2F, 0x36, 0x3B, - 0x24, 0x29, 0x36, 0x3B, - 0x24, 0x29, 0x30, 0x3B, - 0x24, 0x3B, 0x3B, 0x3B, - 0x24, 0x24, 0x3B, 0x3B, - 0x24, 0x24, 0x24, 0x3B, - 0x24, 0x31, 0x38, 0x3E, - 0x24, 0x2A, 0x38, 0x3E, - 0x24, 0x2A, 0x31, 0x3E, - 0x24, 0x3E, 0x3E, 0x3E, - 0x24, 0x24, 0x3E, 0x3E, - 0x24, 0x24, 0x24, 0x3E, - 0x25, 0x26, 0x26, 0x27, - 0x25, 0x26, 0x27, 0x28, - 0x25, 0x27, 0x28, 0x29, - 0x25, 0x26, 0x28, 0x29, - 0x25, 0x26, 0x27, 0x29, - 0x25, 0x27, 0x28, 0x2A, - 0x25, 0x27, 0x29, 0x2A, - 0x25, 0x26, 0x29, 0x2A, - 0x25, 0x26, 0x28, 0x2A, - 0x25, 0x27, 0x29, 0x2B, - 0x25, 0x28, 0x2A, 0x2B, - 0x25, 0x26, 0x2A, 0x2B, - 0x25, 0x26, 0x28, 0x2B, - 0x25, 0x2B, 0x2B, 0x2B, - 0x25, 0x25, 0x2B, 0x2B, - 0x25, 0x25, 0x25, 0x2B, - 0x25, 0x28, 0x29, 0x2C, - 0x25, 0x28, 0x2B, 0x2C, - 0x25, 0x26, 0x2B, 0x2C, - 0x25, 0x26, 0x29, 0x2C, - 0x25, 0x28, 0x2A, 0x2D, - 0x25, 0x29, 0x2B, 0x2D, - 0x25, 0x27, 0x2B, 0x2D, - 0x25, 0x27, 0x29, 0x2D, - 0x25, 0x2D, 0x2D, 0x2D, - 0x25, 0x25, 0x2D, 0x2D, - 0x25, 0x25, 0x25, 0x2D, - 0x25, 0x29, 0x2C, 0x30, - 0x25, 0x2A, 0x2E, 0x30, - 0x25, 0x27, 0x2E, 0x30, - 0x25, 0x27, 0x2B, 0x30, - 0x25, 0x30, 0x30, 0x30, - 0x25, 0x25, 0x30, 0x30, - 0x25, 0x25, 0x25, 0x30, - 0x25, 0x2A, 0x2E, 0x33, - 0x25, 0x2C, 0x30, 0x33, - 0x25, 0x28, 0x30, 0x33, - 0x25, 0x28, 0x2C, 0x33, - 0x25, 0x33, 0x33, 0x33, - 0x25, 0x25, 0x33, 0x33, - 0x25, 0x25, 0x25, 0x33, - 0x25, 0x2B, 0x30, 0x36, - 0x25, 0x2D, 0x32, 0x36, - 0x25, 0x29, 0x32, 0x36, - 0x25, 0x29, 0x2E, 0x36, - 0x25, 0x36, 0x36, 0x36, - 0x25, 0x25, 0x36, 0x36, - 0x25, 0x25, 0x25, 0x36, - 0x25, 0x2C, 0x32, 0x39, - 0x25, 0x2F, 0x34, 0x39, - 0x25, 0x2A, 0x34, 0x39, - 0x25, 0x2A, 0x2F, 0x39, - 0x25, 0x39, 0x39, 0x39, - 0x25, 0x25, 0x39, 0x39, - 0x25, 0x25, 0x25, 0x39, - 0x25, 0x30, 0x37, 0x3C, - 0x25, 0x2A, 0x37, 0x3C, - 0x25, 0x2A, 0x31, 0x3C, - 0x25, 0x3C, 0x3C, 0x3C, - 0x25, 0x25, 0x3C, 0x3C, - 0x25, 0x25, 0x25, 0x3C, - 0x25, 0x32, 0x39, 0x3F, - 0x25, 0x2B, 0x39, 0x3F, - 0x25, 0x2B, 0x32, 0x3F, - 0x25, 0x3F, 0x3F, 0x3F, - 0x25, 0x25, 0x3F, 0x3F, - 0x25, 0x25, 0x25, 0x3F, - 0x26, 0x27, 0x27, 0x28, - 0x26, 0x27, 0x28, 0x29, - 0x26, 0x28, 0x29, 0x2A, - 0x26, 0x27, 0x29, 0x2A, - 0x26, 0x27, 0x28, 0x2A, - 0x26, 0x28, 0x29, 0x2B, - 0x26, 0x28, 0x2A, 0x2B, - 0x26, 0x27, 0x2A, 0x2B, - 0x26, 0x27, 0x29, 0x2B, - 0x26, 0x28, 0x2A, 0x2C, - 0x26, 0x29, 0x2B, 0x2C, - 0x26, 0x27, 0x2B, 0x2C, - 0x26, 0x27, 0x29, 0x2C, - 0x26, 0x2C, 0x2C, 0x2C, - 0x26, 0x26, 0x2C, 0x2C, - 0x26, 0x26, 0x26, 0x2C, - 0x26, 0x29, 0x2A, 0x2D, - 0x26, 0x29, 0x2C, 0x2D, - 0x26, 0x27, 0x2C, 0x2D, - 0x26, 0x27, 0x2A, 0x2D, - 0x26, 0x29, 0x2B, 0x2E, - 0x26, 0x2A, 0x2C, 0x2E, - 0x26, 0x28, 0x2C, 0x2E, - 0x26, 0x28, 0x2A, 0x2E, - 0x26, 0x2E, 0x2E, 0x2E, - 0x26, 0x26, 0x2E, 0x2E, - 0x26, 0x26, 0x26, 0x2E, - 0x26, 0x2A, 0x2D, 0x31, - 0x26, 0x2B, 0x2F, 0x31, - 0x26, 0x28, 0x2F, 0x31, - 0x26, 0x28, 0x2C, 0x31, - 0x26, 0x31, 0x31, 0x31, - 0x26, 0x26, 0x31, 0x31, - 0x26, 0x26, 0x26, 0x31, - 0x26, 0x2B, 0x2F, 0x34, - 0x26, 0x2D, 0x31, 0x34, - 0x26, 0x29, 0x31, 0x34, - 0x26, 0x29, 0x2D, 0x34, - 0x26, 0x34, 0x34, 0x34, - 0x26, 0x26, 0x34, 0x34, - 0x26, 0x26, 0x26, 0x34, - 0x26, 0x2C, 0x31, 0x37, - 0x26, 0x2E, 0x33, 0x37, - 0x26, 0x2A, 0x33, 0x37, - 0x26, 0x2A, 0x2F, 0x37, - 0x26, 0x37, 0x37, 0x37, - 0x26, 0x26, 0x37, 0x37, - 0x26, 0x26, 0x26, 0x37, - 0x26, 0x2D, 0x33, 0x3A, - 0x26, 0x30, 0x35, 0x3A, - 0x26, 0x2B, 0x35, 0x3A, - 0x26, 0x2B, 0x30, 0x3A, - 0x26, 0x3A, 0x3A, 0x3A, - 0x26, 0x26, 0x3A, 0x3A, - 0x26, 0x26, 0x26, 0x3A, - 0x26, 0x31, 0x38, 0x3D, - 0x26, 0x2B, 0x38, 0x3D, - 0x26, 0x2B, 0x32, 0x3D, - 0x26, 0x3D, 0x3D, 0x3D, - 0x26, 0x26, 0x3D, 0x3D, - 0x26, 0x26, 0x26, 0x3D, - 0x27, 0x28, 0x28, 0x29, - 0x27, 0x28, 0x29, 0x2A, - 0x27, 0x29, 0x2A, 0x2B, - 0x27, 0x28, 0x2A, 0x2B, - 0x27, 0x28, 0x29, 0x2B, - 0x27, 0x29, 0x2A, 0x2C, - 0x27, 0x29, 0x2B, 0x2C, - 0x27, 0x28, 0x2B, 0x2C, - 0x27, 0x28, 0x2A, 0x2C, - 0x27, 0x29, 0x2B, 0x2D, - 0x27, 0x2A, 0x2C, 0x2D, - 0x27, 0x28, 0x2C, 0x2D, - 0x27, 0x28, 0x2A, 0x2D, - 0x27, 0x2D, 0x2D, 0x2D, - 0x27, 0x27, 0x2D, 0x2D, - 0x27, 0x27, 0x27, 0x2D, - 0x27, 0x2A, 0x2B, 0x2E, - 0x27, 0x2A, 0x2D, 0x2E, - 0x27, 0x28, 0x2D, 0x2E, - 0x27, 0x28, 0x2B, 0x2E, - 0x27, 0x2A, 0x2C, 0x2F, - 0x27, 0x2B, 0x2D, 0x2F, - 0x27, 0x29, 0x2D, 0x2F, - 0x27, 0x29, 0x2B, 0x2F, - 0x27, 0x2F, 0x2F, 0x2F, - 0x27, 0x27, 0x2F, 0x2F, - 0x27, 0x27, 0x27, 0x2F, - 0x27, 0x2B, 0x2E, 0x32, - 0x27, 0x2C, 0x30, 0x32, - 0x27, 0x29, 0x30, 0x32, - 0x27, 0x29, 0x2D, 0x32, - 0x27, 0x32, 0x32, 0x32, - 0x27, 0x27, 0x32, 0x32, - 0x27, 0x27, 0x27, 0x32, - 0x27, 0x2C, 0x30, 0x35, - 0x27, 0x2E, 0x32, 0x35, - 0x27, 0x2A, 0x32, 0x35, - 0x27, 0x2A, 0x2E, 0x35, - 0x27, 0x35, 0x35, 0x35, - 0x27, 0x27, 0x35, 0x35, - 0x27, 0x27, 0x27, 0x35, - 0x27, 0x2D, 0x32, 0x38, - 0x27, 0x2F, 0x34, 0x38, - 0x27, 0x2B, 0x34, 0x38, - 0x27, 0x2B, 0x30, 0x38, - 0x27, 0x38, 0x38, 0x38, - 0x27, 0x27, 0x38, 0x38, - 0x27, 0x27, 0x27, 0x38, - 0x27, 0x2E, 0x34, 0x3B, - 0x27, 0x31, 0x36, 0x3B, - 0x27, 0x2C, 0x36, 0x3B, - 0x27, 0x2C, 0x31, 0x3B, - 0x27, 0x3B, 0x3B, 0x3B, - 0x27, 0x27, 0x3B, 0x3B, - 0x27, 0x27, 0x27, 0x3B, - 0x27, 0x32, 0x39, 0x3E, - 0x27, 0x2C, 0x39, 0x3E, - 0x27, 0x2C, 0x33, 0x3E, - 0x27, 0x3E, 0x3E, 0x3E, - 0x27, 0x27, 0x3E, 0x3E, - 0x27, 0x27, 0x27, 0x3E, - 0x28, 0x29, 0x29, 0x2A, - 0x28, 0x29, 0x2A, 0x2B, - 0x28, 0x2A, 0x2B, 0x2C, - 0x28, 0x29, 0x2B, 0x2C, - 0x28, 0x29, 0x2A, 0x2C, - 0x28, 0x2A, 0x2B, 0x2D, - 0x28, 0x2A, 0x2C, 0x2D, - 0x28, 0x29, 0x2C, 0x2D, - 0x28, 0x29, 0x2B, 0x2D, - 0x28, 0x2A, 0x2C, 0x2E, - 0x28, 0x2B, 0x2D, 0x2E, - 0x28, 0x29, 0x2D, 0x2E, - 0x28, 0x29, 0x2B, 0x2E, - 0x28, 0x2E, 0x2E, 0x2E, - 0x28, 0x28, 0x2E, 0x2E, - 0x28, 0x28, 0x28, 0x2E, - 0x28, 0x2B, 0x2C, 0x2F, - 0x28, 0x2B, 0x2E, 0x2F, - 0x28, 0x29, 0x2E, 0x2F, - 0x28, 0x29, 0x2C, 0x2F, - 0x28, 0x2B, 0x2D, 0x30, - 0x28, 0x2C, 0x2E, 0x30, - 0x28, 0x2A, 0x2E, 0x30, - 0x28, 0x2A, 0x2C, 0x30, - 0x28, 0x30, 0x30, 0x30, - 0x28, 0x28, 0x30, 0x30, - 0x28, 0x28, 0x28, 0x30, - 0x28, 0x2C, 0x2F, 0x33, - 0x28, 0x2D, 0x31, 0x33, - 0x28, 0x2A, 0x31, 0x33, - 0x28, 0x2A, 0x2E, 0x33, - 0x28, 0x33, 0x33, 0x33, - 0x28, 0x28, 0x33, 0x33, - 0x28, 0x28, 0x28, 0x33, - 0x28, 0x2D, 0x31, 0x36, - 0x28, 0x2F, 0x33, 0x36, - 0x28, 0x2B, 0x33, 0x36, - 0x28, 0x2B, 0x2F, 0x36, - 0x28, 0x36, 0x36, 0x36, - 0x28, 0x28, 0x36, 0x36, - 0x28, 0x28, 0x28, 0x36, - 0x28, 0x2E, 0x33, 0x39, - 0x28, 0x30, 0x35, 0x39, - 0x28, 0x2C, 0x35, 0x39, - 0x28, 0x2C, 0x31, 0x39, - 0x28, 0x39, 0x39, 0x39, - 0x28, 0x28, 0x39, 0x39, - 0x28, 0x28, 0x28, 0x39, - 0x28, 0x2F, 0x35, 0x3C, - 0x28, 0x32, 0x37, 0x3C, - 0x28, 0x2D, 0x37, 0x3C, - 0x28, 0x2D, 0x32, 0x3C, - 0x28, 0x3C, 0x3C, 0x3C, - 0x28, 0x28, 0x3C, 0x3C, - 0x28, 0x28, 0x28, 0x3C, - 0x28, 0x33, 0x3A, 0x3F, - 0x28, 0x2D, 0x3A, 0x3F, - 0x28, 0x2D, 0x34, 0x3F, - 0x28, 0x3F, 0x3F, 0x3F, - 0x28, 0x28, 0x3F, 0x3F, - 0x28, 0x28, 0x28, 0x3F, - 0x29, 0x2A, 0x2A, 0x2B, - 0x29, 0x2A, 0x2B, 0x2C, - 0x29, 0x2B, 0x2C, 0x2D, - 0x29, 0x2A, 0x2C, 0x2D, - 0x29, 0x2A, 0x2B, 0x2D, - 0x29, 0x2B, 0x2C, 0x2E, - 0x29, 0x2B, 0x2D, 0x2E, - 0x29, 0x2A, 0x2D, 0x2E, - 0x29, 0x2A, 0x2C, 0x2E, - 0x29, 0x2B, 0x2D, 0x2F, - 0x29, 0x2C, 0x2E, 0x2F, - 0x29, 0x2A, 0x2E, 0x2F, - 0x29, 0x2A, 0x2C, 0x2F, - 0x29, 0x2F, 0x2F, 0x2F, - 0x29, 0x29, 0x2F, 0x2F, - 0x29, 0x29, 0x29, 0x2F, - 0x29, 0x2C, 0x2D, 0x30, - 0x29, 0x2C, 0x2F, 0x30, - 0x29, 0x2A, 0x2F, 0x30, - 0x29, 0x2A, 0x2D, 0x30, - 0x29, 0x2C, 0x2E, 0x31, - 0x29, 0x2D, 0x2F, 0x31, - 0x29, 0x2B, 0x2F, 0x31, - 0x29, 0x2B, 0x2D, 0x31, - 0x29, 0x31, 0x31, 0x31, - 0x29, 0x29, 0x31, 0x31, - 0x29, 0x29, 0x29, 0x31, - 0x29, 0x2D, 0x30, 0x34, - 0x29, 0x2E, 0x32, 0x34, - 0x29, 0x2B, 0x32, 0x34, - 0x29, 0x2B, 0x2F, 0x34, - 0x29, 0x34, 0x34, 0x34, - 0x29, 0x29, 0x34, 0x34, - 0x29, 0x29, 0x29, 0x34, - 0x29, 0x2E, 0x32, 0x37, - 0x29, 0x30, 0x34, 0x37, - 0x29, 0x2C, 0x34, 0x37, - 0x29, 0x2C, 0x30, 0x37, - 0x29, 0x37, 0x37, 0x37, - 0x29, 0x29, 0x37, 0x37, - 0x29, 0x29, 0x29, 0x37, - 0x29, 0x2F, 0x34, 0x3A, - 0x29, 0x31, 0x36, 0x3A, - 0x29, 0x2D, 0x36, 0x3A, - 0x29, 0x2D, 0x32, 0x3A, - 0x29, 0x3A, 0x3A, 0x3A, - 0x29, 0x29, 0x3A, 0x3A, - 0x29, 0x29, 0x29, 0x3A, - 0x29, 0x30, 0x36, 0x3D, - 0x29, 0x33, 0x38, 0x3D, - 0x29, 0x2E, 0x38, 0x3D, - 0x29, 0x2E, 0x33, 0x3D, - 0x29, 0x3D, 0x3D, 0x3D, - 0x29, 0x29, 0x3D, 0x3D, - 0x29, 0x29, 0x29, 0x3D, - 0x2A, 0x2B, 0x2B, 0x2C, - 0x2A, 0x2B, 0x2C, 0x2D, - 0x2A, 0x2C, 0x2D, 0x2E, - 0x2A, 0x2B, 0x2D, 0x2E, - 0x2A, 0x2B, 0x2C, 0x2E, - 0x2A, 0x2C, 0x2D, 0x2F, - 0x2A, 0x2C, 0x2E, 0x2F, - 0x2A, 0x2B, 0x2E, 0x2F, - 0x2A, 0x2B, 0x2D, 0x2F, - 0x2A, 0x2C, 0x2E, 0x30, - 0x2A, 0x2D, 0x2F, 0x30, - 0x2A, 0x2B, 0x2F, 0x30, - 0x2A, 0x2B, 0x2D, 0x30, - 0x2A, 0x30, 0x30, 0x30, - 0x2A, 0x2A, 0x30, 0x30, - 0x2A, 0x2A, 0x2A, 0x30, - 0x2A, 0x2D, 0x2E, 0x31, - 0x2A, 0x2D, 0x30, 0x31, - 0x2A, 0x2B, 0x30, 0x31, - 0x2A, 0x2B, 0x2E, 0x31, - 0x2A, 0x2D, 0x2F, 0x32, - 0x2A, 0x2E, 0x30, 0x32, - 0x2A, 0x2C, 0x30, 0x32, - 0x2A, 0x2C, 0x2E, 0x32, - 0x2A, 0x32, 0x32, 0x32, - 0x2A, 0x2A, 0x32, 0x32, - 0x2A, 0x2A, 0x2A, 0x32, - 0x2A, 0x2E, 0x31, 0x35, - 0x2A, 0x2F, 0x33, 0x35, - 0x2A, 0x2C, 0x33, 0x35, - 0x2A, 0x2C, 0x30, 0x35, - 0x2A, 0x35, 0x35, 0x35, - 0x2A, 0x2A, 0x35, 0x35, - 0x2A, 0x2A, 0x2A, 0x35, - 0x2A, 0x2F, 0x33, 0x38, - 0x2A, 0x31, 0x35, 0x38, - 0x2A, 0x2D, 0x35, 0x38, - 0x2A, 0x2D, 0x31, 0x38, - 0x2A, 0x38, 0x38, 0x38, - 0x2A, 0x2A, 0x38, 0x38, - 0x2A, 0x2A, 0x2A, 0x38, - 0x2A, 0x30, 0x35, 0x3B, - 0x2A, 0x32, 0x37, 0x3B, - 0x2A, 0x2E, 0x37, 0x3B, - 0x2A, 0x2E, 0x33, 0x3B, - 0x2A, 0x3B, 0x3B, 0x3B, - 0x2A, 0x2A, 0x3B, 0x3B, - 0x2A, 0x2A, 0x2A, 0x3B, - 0x2A, 0x31, 0x37, 0x3E, - 0x2A, 0x34, 0x39, 0x3E, - 0x2A, 0x2F, 0x39, 0x3E, - 0x2A, 0x2F, 0x34, 0x3E, - 0x2A, 0x3E, 0x3E, 0x3E, - 0x2A, 0x2A, 0x3E, 0x3E, - 0x2A, 0x2A, 0x2A, 0x3E, - 0x2B, 0x2C, 0x2C, 0x2D, - 0x2B, 0x2C, 0x2D, 0x2E, - 0x2B, 0x2D, 0x2E, 0x2F, - 0x2B, 0x2C, 0x2E, 0x2F, - 0x2B, 0x2C, 0x2D, 0x2F, - 0x2B, 0x2D, 0x2E, 0x30, - 0x2B, 0x2D, 0x2F, 0x30, - 0x2B, 0x2C, 0x2F, 0x30, - 0x2B, 0x2C, 0x2E, 0x30, - 0x2B, 0x2D, 0x2F, 0x31, - 0x2B, 0x2E, 0x30, 0x31, - 0x2B, 0x2C, 0x30, 0x31, - 0x2B, 0x2C, 0x2E, 0x31, - 0x2B, 0x31, 0x31, 0x31, - 0x2B, 0x2B, 0x31, 0x31, - 0x2B, 0x2B, 0x2B, 0x31, - 0x2B, 0x2E, 0x2F, 0x32, - 0x2B, 0x2E, 0x31, 0x32, - 0x2B, 0x2C, 0x31, 0x32, - 0x2B, 0x2C, 0x2F, 0x32, - 0x2B, 0x2E, 0x30, 0x33, - 0x2B, 0x2F, 0x31, 0x33, - 0x2B, 0x2D, 0x31, 0x33, - 0x2B, 0x2D, 0x2F, 0x33, - 0x2B, 0x33, 0x33, 0x33, - 0x2B, 0x2B, 0x33, 0x33, - 0x2B, 0x2B, 0x2B, 0x33, - 0x2B, 0x2F, 0x32, 0x36, - 0x2B, 0x30, 0x34, 0x36, - 0x2B, 0x2D, 0x34, 0x36, - 0x2B, 0x2D, 0x31, 0x36, - 0x2B, 0x36, 0x36, 0x36, - 0x2B, 0x2B, 0x36, 0x36, - 0x2B, 0x2B, 0x2B, 0x36, - 0x2B, 0x30, 0x34, 0x39, - 0x2B, 0x32, 0x36, 0x39, - 0x2B, 0x2E, 0x36, 0x39, - 0x2B, 0x2E, 0x32, 0x39, - 0x2B, 0x39, 0x39, 0x39, - 0x2B, 0x2B, 0x39, 0x39, - 0x2B, 0x2B, 0x2B, 0x39, - 0x2B, 0x31, 0x36, 0x3C, - 0x2B, 0x33, 0x38, 0x3C, - 0x2B, 0x2F, 0x38, 0x3C, - 0x2B, 0x2F, 0x34, 0x3C, - 0x2B, 0x3C, 0x3C, 0x3C, - 0x2B, 0x2B, 0x3C, 0x3C, - 0x2B, 0x2B, 0x2B, 0x3C, - 0x2B, 0x32, 0x38, 0x3F, - 0x2B, 0x35, 0x3A, 0x3F, - 0x2B, 0x30, 0x3A, 0x3F, - 0x2B, 0x30, 0x35, 0x3F, - 0x2B, 0x3F, 0x3F, 0x3F, - 0x2B, 0x2B, 0x3F, 0x3F, - 0x2B, 0x2B, 0x2B, 0x3F, - 0x2C, 0x2D, 0x2D, 0x2E, - 0x2C, 0x2D, 0x2E, 0x2F, - 0x2C, 0x2E, 0x2F, 0x30, - 0x2C, 0x2D, 0x2F, 0x30, - 0x2C, 0x2D, 0x2E, 0x30, - 0x2C, 0x2E, 0x2F, 0x31, - 0x2C, 0x2E, 0x30, 0x31, - 0x2C, 0x2D, 0x30, 0x31, - 0x2C, 0x2D, 0x2F, 0x31, - 0x2C, 0x2E, 0x30, 0x32, - 0x2C, 0x2F, 0x31, 0x32, - 0x2C, 0x2D, 0x31, 0x32, - 0x2C, 0x2D, 0x2F, 0x32, - 0x2C, 0x32, 0x32, 0x32, - 0x2C, 0x2C, 0x32, 0x32, - 0x2C, 0x2C, 0x2C, 0x32, - 0x2C, 0x2F, 0x30, 0x33, - 0x2C, 0x2F, 0x32, 0x33, - 0x2C, 0x2D, 0x32, 0x33, - 0x2C, 0x2D, 0x30, 0x33, - 0x2C, 0x2F, 0x31, 0x34, - 0x2C, 0x30, 0x32, 0x34, - 0x2C, 0x2E, 0x32, 0x34, - 0x2C, 0x2E, 0x30, 0x34, - 0x2C, 0x34, 0x34, 0x34, - 0x2C, 0x2C, 0x34, 0x34, - 0x2C, 0x2C, 0x2C, 0x34, - 0x2C, 0x30, 0x33, 0x37, - 0x2C, 0x31, 0x35, 0x37, - 0x2C, 0x2E, 0x35, 0x37, - 0x2C, 0x2E, 0x32, 0x37, - 0x2C, 0x37, 0x37, 0x37, - 0x2C, 0x2C, 0x37, 0x37, - 0x2C, 0x2C, 0x2C, 0x37, - 0x2C, 0x31, 0x35, 0x3A, - 0x2C, 0x33, 0x37, 0x3A, - 0x2C, 0x2F, 0x37, 0x3A, - 0x2C, 0x2F, 0x33, 0x3A, - 0x2C, 0x3A, 0x3A, 0x3A, - 0x2C, 0x2C, 0x3A, 0x3A, - 0x2C, 0x2C, 0x2C, 0x3A, - 0x2C, 0x32, 0x37, 0x3D, - 0x2C, 0x34, 0x39, 0x3D, - 0x2C, 0x30, 0x39, 0x3D, - 0x2C, 0x30, 0x35, 0x3D, - 0x2C, 0x3D, 0x3D, 0x3D, - 0x2C, 0x2C, 0x3D, 0x3D, - 0x2C, 0x2C, 0x2C, 0x3D, - 0x2D, 0x2E, 0x2E, 0x2F, - 0x2D, 0x2E, 0x2F, 0x30, - 0x2D, 0x2F, 0x30, 0x31, - 0x2D, 0x2E, 0x30, 0x31, - 0x2D, 0x2E, 0x2F, 0x31, - 0x2D, 0x2F, 0x30, 0x32, - 0x2D, 0x2F, 0x31, 0x32, - 0x2D, 0x2E, 0x31, 0x32, - 0x2D, 0x2E, 0x30, 0x32, - 0x2D, 0x2F, 0x31, 0x33, - 0x2D, 0x30, 0x32, 0x33, - 0x2D, 0x2E, 0x32, 0x33, - 0x2D, 0x2E, 0x30, 0x33, - 0x2D, 0x33, 0x33, 0x33, - 0x2D, 0x2D, 0x33, 0x33, - 0x2D, 0x2D, 0x2D, 0x33, - 0x2D, 0x30, 0x31, 0x34, - 0x2D, 0x30, 0x33, 0x34, - 0x2D, 0x2E, 0x33, 0x34, - 0x2D, 0x2E, 0x31, 0x34, - 0x2D, 0x30, 0x32, 0x35, - 0x2D, 0x31, 0x33, 0x35, - 0x2D, 0x2F, 0x33, 0x35, - 0x2D, 0x2F, 0x31, 0x35, - 0x2D, 0x35, 0x35, 0x35, - 0x2D, 0x2D, 0x35, 0x35, - 0x2D, 0x2D, 0x2D, 0x35, - 0x2D, 0x31, 0x34, 0x38, - 0x2D, 0x32, 0x36, 0x38, - 0x2D, 0x2F, 0x36, 0x38, - 0x2D, 0x2F, 0x33, 0x38, - 0x2D, 0x38, 0x38, 0x38, - 0x2D, 0x2D, 0x38, 0x38, - 0x2D, 0x2D, 0x2D, 0x38, - 0x2D, 0x32, 0x36, 0x3B, - 0x2D, 0x34, 0x38, 0x3B, - 0x2D, 0x30, 0x38, 0x3B, - 0x2D, 0x30, 0x34, 0x3B, - 0x2D, 0x3B, 0x3B, 0x3B, - 0x2D, 0x2D, 0x3B, 0x3B, - 0x2D, 0x2D, 0x2D, 0x3B, - 0x2D, 0x33, 0x38, 0x3E, - 0x2D, 0x35, 0x3A, 0x3E, - 0x2D, 0x31, 0x3A, 0x3E, - 0x2D, 0x31, 0x36, 0x3E, - 0x2D, 0x3E, 0x3E, 0x3E, - 0x2D, 0x2D, 0x3E, 0x3E, - 0x2D, 0x2D, 0x2D, 0x3E, - 0x2E, 0x2F, 0x2F, 0x30, - 0x2E, 0x2F, 0x30, 0x31, - 0x2E, 0x30, 0x31, 0x32, - 0x2E, 0x2F, 0x31, 0x32, - 0x2E, 0x2F, 0x30, 0x32, - 0x2E, 0x30, 0x31, 0x33, - 0x2E, 0x30, 0x32, 0x33, - 0x2E, 0x2F, 0x32, 0x33, - 0x2E, 0x2F, 0x31, 0x33, - 0x2E, 0x30, 0x32, 0x34, - 0x2E, 0x31, 0x33, 0x34, - 0x2E, 0x2F, 0x33, 0x34, - 0x2E, 0x2F, 0x31, 0x34, - 0x2E, 0x34, 0x34, 0x34, - 0x2E, 0x2E, 0x34, 0x34, - 0x2E, 0x2E, 0x2E, 0x34, - 0x2E, 0x31, 0x32, 0x35, - 0x2E, 0x31, 0x34, 0x35, - 0x2E, 0x2F, 0x34, 0x35, - 0x2E, 0x2F, 0x32, 0x35, - 0x2E, 0x31, 0x33, 0x36, - 0x2E, 0x32, 0x34, 0x36, - 0x2E, 0x30, 0x34, 0x36, - 0x2E, 0x30, 0x32, 0x36, - 0x2E, 0x36, 0x36, 0x36, - 0x2E, 0x2E, 0x36, 0x36, - 0x2E, 0x2E, 0x2E, 0x36, - 0x2E, 0x32, 0x35, 0x39, - 0x2E, 0x33, 0x37, 0x39, - 0x2E, 0x30, 0x37, 0x39, - 0x2E, 0x30, 0x34, 0x39, - 0x2E, 0x39, 0x39, 0x39, - 0x2E, 0x2E, 0x39, 0x39, - 0x2E, 0x2E, 0x2E, 0x39, - 0x2E, 0x33, 0x37, 0x3C, - 0x2E, 0x35, 0x39, 0x3C, - 0x2E, 0x31, 0x39, 0x3C, - 0x2E, 0x31, 0x35, 0x3C, - 0x2E, 0x3C, 0x3C, 0x3C, - 0x2E, 0x2E, 0x3C, 0x3C, - 0x2E, 0x2E, 0x2E, 0x3C, - 0x2E, 0x34, 0x39, 0x3F, - 0x2E, 0x36, 0x3B, 0x3F, - 0x2E, 0x32, 0x3B, 0x3F, - 0x2E, 0x32, 0x37, 0x3F, - 0x2E, 0x3F, 0x3F, 0x3F, - 0x2E, 0x2E, 0x3F, 0x3F, - 0x2E, 0x2E, 0x2E, 0x3F, - 0x2F, 0x30, 0x30, 0x31, - 0x2F, 0x30, 0x31, 0x32, - 0x2F, 0x31, 0x32, 0x33, - 0x2F, 0x30, 0x32, 0x33, - 0x2F, 0x30, 0x31, 0x33, - 0x2F, 0x31, 0x32, 0x34, - 0x2F, 0x31, 0x33, 0x34, - 0x2F, 0x30, 0x33, 0x34, - 0x2F, 0x30, 0x32, 0x34, - 0x2F, 0x31, 0x33, 0x35, - 0x2F, 0x32, 0x34, 0x35, - 0x2F, 0x30, 0x34, 0x35, - 0x2F, 0x30, 0x32, 0x35, - 0x2F, 0x35, 0x35, 0x35, - 0x2F, 0x2F, 0x35, 0x35, - 0x2F, 0x2F, 0x2F, 0x35, - 0x2F, 0x32, 0x33, 0x36, - 0x2F, 0x32, 0x35, 0x36, - 0x2F, 0x30, 0x35, 0x36, - 0x2F, 0x30, 0x33, 0x36, - 0x2F, 0x32, 0x34, 0x37, - 0x2F, 0x33, 0x35, 0x37, - 0x2F, 0x31, 0x35, 0x37, - 0x2F, 0x31, 0x33, 0x37, - 0x2F, 0x37, 0x37, 0x37, - 0x2F, 0x2F, 0x37, 0x37, - 0x2F, 0x2F, 0x2F, 0x37, - 0x2F, 0x33, 0x36, 0x3A, - 0x2F, 0x34, 0x38, 0x3A, - 0x2F, 0x31, 0x38, 0x3A, - 0x2F, 0x31, 0x35, 0x3A, - 0x2F, 0x3A, 0x3A, 0x3A, - 0x2F, 0x2F, 0x3A, 0x3A, - 0x2F, 0x2F, 0x2F, 0x3A, - 0x2F, 0x34, 0x38, 0x3D, - 0x2F, 0x36, 0x3A, 0x3D, - 0x2F, 0x32, 0x3A, 0x3D, - 0x2F, 0x32, 0x36, 0x3D, - 0x2F, 0x3D, 0x3D, 0x3D, - 0x2F, 0x2F, 0x3D, 0x3D, - 0x2F, 0x2F, 0x2F, 0x3D, - 0x30, 0x31, 0x31, 0x32, - 0x30, 0x31, 0x32, 0x33, - 0x30, 0x32, 0x33, 0x34, - 0x30, 0x31, 0x33, 0x34, - 0x30, 0x31, 0x32, 0x34, - 0x30, 0x32, 0x33, 0x35, - 0x30, 0x32, 0x34, 0x35, - 0x30, 0x31, 0x34, 0x35, - 0x30, 0x31, 0x33, 0x35, - 0x30, 0x32, 0x34, 0x36, - 0x30, 0x33, 0x35, 0x36, - 0x30, 0x31, 0x35, 0x36, - 0x30, 0x31, 0x33, 0x36, - 0x30, 0x36, 0x36, 0x36, - 0x30, 0x30, 0x36, 0x36, - 0x30, 0x30, 0x30, 0x36, - 0x30, 0x33, 0x34, 0x37, - 0x30, 0x33, 0x36, 0x37, - 0x30, 0x31, 0x36, 0x37, - 0x30, 0x31, 0x34, 0x37, - 0x30, 0x33, 0x35, 0x38, - 0x30, 0x34, 0x36, 0x38, - 0x30, 0x32, 0x36, 0x38, - 0x30, 0x32, 0x34, 0x38, - 0x30, 0x38, 0x38, 0x38, - 0x30, 0x30, 0x38, 0x38, - 0x30, 0x30, 0x30, 0x38, - 0x30, 0x34, 0x37, 0x3B, - 0x30, 0x35, 0x39, 0x3B, - 0x30, 0x32, 0x39, 0x3B, - 0x30, 0x32, 0x36, 0x3B, - 0x30, 0x3B, 0x3B, 0x3B, - 0x30, 0x30, 0x3B, 0x3B, - 0x30, 0x30, 0x30, 0x3B, - 0x30, 0x35, 0x39, 0x3E, - 0x30, 0x37, 0x3B, 0x3E, - 0x30, 0x33, 0x3B, 0x3E, - 0x30, 0x33, 0x37, 0x3E, - 0x30, 0x3E, 0x3E, 0x3E, - 0x30, 0x30, 0x3E, 0x3E, - 0x30, 0x30, 0x30, 0x3E, - 0x31, 0x32, 0x32, 0x33, - 0x31, 0x32, 0x33, 0x34, - 0x31, 0x33, 0x34, 0x35, - 0x31, 0x32, 0x34, 0x35, - 0x31, 0x32, 0x33, 0x35, - 0x31, 0x33, 0x34, 0x36, - 0x31, 0x33, 0x35, 0x36, - 0x31, 0x32, 0x35, 0x36, - 0x31, 0x32, 0x34, 0x36, - 0x31, 0x33, 0x35, 0x37, - 0x31, 0x34, 0x36, 0x37, - 0x31, 0x32, 0x36, 0x37, - 0x31, 0x32, 0x34, 0x37, - 0x31, 0x37, 0x37, 0x37, - 0x31, 0x31, 0x37, 0x37, - 0x31, 0x31, 0x31, 0x37, - 0x31, 0x34, 0x35, 0x38, - 0x31, 0x34, 0x37, 0x38, - 0x31, 0x32, 0x37, 0x38, - 0x31, 0x32, 0x35, 0x38, - 0x31, 0x34, 0x36, 0x39, - 0x31, 0x35, 0x37, 0x39, - 0x31, 0x33, 0x37, 0x39, - 0x31, 0x33, 0x35, 0x39, - 0x31, 0x39, 0x39, 0x39, - 0x31, 0x31, 0x39, 0x39, - 0x31, 0x31, 0x31, 0x39, - 0x31, 0x35, 0x38, 0x3C, - 0x31, 0x36, 0x3A, 0x3C, - 0x31, 0x33, 0x3A, 0x3C, - 0x31, 0x33, 0x37, 0x3C, - 0x31, 0x3C, 0x3C, 0x3C, - 0x31, 0x31, 0x3C, 0x3C, - 0x31, 0x31, 0x31, 0x3C, - 0x31, 0x36, 0x3A, 0x3F, - 0x31, 0x38, 0x3C, 0x3F, - 0x31, 0x34, 0x3C, 0x3F, - 0x31, 0x34, 0x38, 0x3F, - 0x31, 0x3F, 0x3F, 0x3F, - 0x31, 0x31, 0x3F, 0x3F, - 0x31, 0x31, 0x31, 0x3F, - 0x32, 0x33, 0x33, 0x34, - 0x32, 0x33, 0x34, 0x35, - 0x32, 0x34, 0x35, 0x36, - 0x32, 0x33, 0x35, 0x36, - 0x32, 0x33, 0x34, 0x36, - 0x32, 0x34, 0x35, 0x37, - 0x32, 0x34, 0x36, 0x37, - 0x32, 0x33, 0x36, 0x37, - 0x32, 0x33, 0x35, 0x37, - 0x32, 0x34, 0x36, 0x38, - 0x32, 0x35, 0x37, 0x38, - 0x32, 0x33, 0x37, 0x38, - 0x32, 0x33, 0x35, 0x38, - 0x32, 0x38, 0x38, 0x38, - 0x32, 0x32, 0x38, 0x38, - 0x32, 0x32, 0x32, 0x38, - 0x32, 0x35, 0x36, 0x39, - 0x32, 0x35, 0x38, 0x39, - 0x32, 0x33, 0x38, 0x39, - 0x32, 0x33, 0x36, 0x39, - 0x32, 0x35, 0x37, 0x3A, - 0x32, 0x36, 0x38, 0x3A, - 0x32, 0x34, 0x38, 0x3A, - 0x32, 0x34, 0x36, 0x3A, - 0x32, 0x3A, 0x3A, 0x3A, - 0x32, 0x32, 0x3A, 0x3A, - 0x32, 0x32, 0x32, 0x3A, - 0x32, 0x36, 0x39, 0x3D, - 0x32, 0x37, 0x3B, 0x3D, - 0x32, 0x34, 0x3B, 0x3D, - 0x32, 0x34, 0x38, 0x3D, - 0x32, 0x3D, 0x3D, 0x3D, - 0x32, 0x32, 0x3D, 0x3D, - 0x32, 0x32, 0x32, 0x3D, - 0x33, 0x34, 0x34, 0x35, - 0x33, 0x34, 0x35, 0x36, - 0x33, 0x35, 0x36, 0x37, - 0x33, 0x34, 0x36, 0x37, - 0x33, 0x34, 0x35, 0x37, - 0x33, 0x35, 0x36, 0x38, - 0x33, 0x35, 0x37, 0x38, - 0x33, 0x34, 0x37, 0x38, - 0x33, 0x34, 0x36, 0x38, - 0x33, 0x35, 0x37, 0x39, - 0x33, 0x36, 0x38, 0x39, - 0x33, 0x34, 0x38, 0x39, - 0x33, 0x34, 0x36, 0x39, - 0x33, 0x39, 0x39, 0x39, - 0x33, 0x33, 0x39, 0x39, - 0x33, 0x33, 0x33, 0x39, - 0x33, 0x36, 0x37, 0x3A, - 0x33, 0x36, 0x39, 0x3A, - 0x33, 0x34, 0x39, 0x3A, - 0x33, 0x34, 0x37, 0x3A, - 0x33, 0x36, 0x38, 0x3B, - 0x33, 0x37, 0x39, 0x3B, - 0x33, 0x35, 0x39, 0x3B, - 0x33, 0x35, 0x37, 0x3B, - 0x33, 0x3B, 0x3B, 0x3B, - 0x33, 0x33, 0x3B, 0x3B, - 0x33, 0x33, 0x33, 0x3B, - 0x33, 0x37, 0x3A, 0x3E, - 0x33, 0x38, 0x3C, 0x3E, - 0x33, 0x35, 0x3C, 0x3E, - 0x33, 0x35, 0x39, 0x3E, - 0x33, 0x3E, 0x3E, 0x3E, - 0x33, 0x33, 0x3E, 0x3E, - 0x33, 0x33, 0x33, 0x3E, - 0x34, 0x35, 0x35, 0x36, - 0x34, 0x35, 0x36, 0x37, - 0x34, 0x36, 0x37, 0x38, - 0x34, 0x35, 0x37, 0x38, - 0x34, 0x35, 0x36, 0x38, - 0x34, 0x36, 0x37, 0x39, - 0x34, 0x36, 0x38, 0x39, - 0x34, 0x35, 0x38, 0x39, - 0x34, 0x35, 0x37, 0x39, - 0x34, 0x36, 0x38, 0x3A, - 0x34, 0x37, 0x39, 0x3A, - 0x34, 0x35, 0x39, 0x3A, - 0x34, 0x35, 0x37, 0x3A, - 0x34, 0x3A, 0x3A, 0x3A, - 0x34, 0x34, 0x3A, 0x3A, - 0x34, 0x34, 0x34, 0x3A, - 0x34, 0x37, 0x38, 0x3B, - 0x34, 0x37, 0x3A, 0x3B, - 0x34, 0x35, 0x3A, 0x3B, - 0x34, 0x35, 0x38, 0x3B, - 0x34, 0x37, 0x39, 0x3C, - 0x34, 0x38, 0x3A, 0x3C, - 0x34, 0x36, 0x3A, 0x3C, - 0x34, 0x36, 0x38, 0x3C, - 0x34, 0x3C, 0x3C, 0x3C, - 0x34, 0x34, 0x3C, 0x3C, - 0x34, 0x34, 0x34, 0x3C, - 0x34, 0x38, 0x3B, 0x3F, - 0x34, 0x39, 0x3D, 0x3F, - 0x34, 0x36, 0x3D, 0x3F, - 0x34, 0x36, 0x3A, 0x3F, - 0x34, 0x3F, 0x3F, 0x3F, - 0x34, 0x34, 0x3F, 0x3F, - 0x34, 0x34, 0x34, 0x3F, - 0x35, 0x36, 0x36, 0x37, - 0x35, 0x36, 0x37, 0x38, - 0x35, 0x37, 0x38, 0x39, - 0x35, 0x36, 0x38, 0x39, - 0x35, 0x36, 0x37, 0x39, - 0x35, 0x37, 0x38, 0x3A, - 0x35, 0x37, 0x39, 0x3A, - 0x35, 0x36, 0x39, 0x3A, - 0x35, 0x36, 0x38, 0x3A, - 0x35, 0x37, 0x39, 0x3B, - 0x35, 0x38, 0x3A, 0x3B, - 0x35, 0x36, 0x3A, 0x3B, - 0x35, 0x36, 0x38, 0x3B, - 0x35, 0x3B, 0x3B, 0x3B, - 0x35, 0x35, 0x3B, 0x3B, - 0x35, 0x35, 0x35, 0x3B, - 0x35, 0x38, 0x39, 0x3C, - 0x35, 0x38, 0x3B, 0x3C, - 0x35, 0x36, 0x3B, 0x3C, - 0x35, 0x36, 0x39, 0x3C, - 0x35, 0x38, 0x3A, 0x3D, - 0x35, 0x39, 0x3B, 0x3D, - 0x35, 0x37, 0x3B, 0x3D, - 0x35, 0x37, 0x39, 0x3D, - 0x35, 0x3D, 0x3D, 0x3D, - 0x35, 0x35, 0x3D, 0x3D, - 0x35, 0x35, 0x35, 0x3D, - 0x36, 0x37, 0x37, 0x38, - 0x36, 0x37, 0x38, 0x39, - 0x36, 0x38, 0x39, 0x3A, - 0x36, 0x37, 0x39, 0x3A, - 0x36, 0x37, 0x38, 0x3A, - 0x36, 0x38, 0x39, 0x3B, - 0x36, 0x38, 0x3A, 0x3B, - 0x36, 0x37, 0x3A, 0x3B, - 0x36, 0x37, 0x39, 0x3B, - 0x36, 0x38, 0x3A, 0x3C, - 0x36, 0x39, 0x3B, 0x3C, - 0x36, 0x37, 0x3B, 0x3C, - 0x36, 0x37, 0x39, 0x3C, - 0x36, 0x3C, 0x3C, 0x3C, - 0x36, 0x36, 0x3C, 0x3C, - 0x36, 0x36, 0x36, 0x3C, - 0x36, 0x39, 0x3A, 0x3D, - 0x36, 0x39, 0x3C, 0x3D, - 0x36, 0x37, 0x3C, 0x3D, - 0x36, 0x37, 0x3A, 0x3D, - 0x36, 0x39, 0x3B, 0x3E, - 0x36, 0x3A, 0x3C, 0x3E, - 0x36, 0x38, 0x3C, 0x3E, - 0x36, 0x38, 0x3A, 0x3E, - 0x36, 0x3E, 0x3E, 0x3E, - 0x36, 0x36, 0x3E, 0x3E, - 0x36, 0x36, 0x36, 0x3E, - 0x37, 0x38, 0x38, 0x39, - 0x37, 0x38, 0x39, 0x3A, - 0x37, 0x39, 0x3A, 0x3B, - 0x37, 0x38, 0x3A, 0x3B, - 0x37, 0x38, 0x39, 0x3B, - 0x37, 0x39, 0x3A, 0x3C, - 0x37, 0x39, 0x3B, 0x3C, - 0x37, 0x38, 0x3B, 0x3C, - 0x37, 0x38, 0x3A, 0x3C, - 0x37, 0x39, 0x3B, 0x3D, - 0x37, 0x3A, 0x3C, 0x3D, - 0x37, 0x38, 0x3C, 0x3D, - 0x37, 0x38, 0x3A, 0x3D, - 0x37, 0x3D, 0x3D, 0x3D, - 0x37, 0x37, 0x3D, 0x3D, - 0x37, 0x37, 0x37, 0x3D, - 0x37, 0x3A, 0x3B, 0x3E, - 0x37, 0x3A, 0x3D, 0x3E, - 0x37, 0x38, 0x3D, 0x3E, - 0x37, 0x38, 0x3B, 0x3E, - 0x37, 0x3A, 0x3C, 0x3F, - 0x37, 0x3B, 0x3D, 0x3F, - 0x37, 0x39, 0x3D, 0x3F, - 0x37, 0x39, 0x3B, 0x3F, - 0x37, 0x3F, 0x3F, 0x3F, - 0x37, 0x37, 0x3F, 0x3F, - 0x37, 0x37, 0x37, 0x3F, - 0x38, 0x39, 0x39, 0x3A, - 0x38, 0x39, 0x3A, 0x3B, - 0x38, 0x3A, 0x3B, 0x3C, - 0x38, 0x39, 0x3B, 0x3C, - 0x38, 0x39, 0x3A, 0x3C, - 0x38, 0x3A, 0x3B, 0x3D, - 0x38, 0x3A, 0x3C, 0x3D, - 0x38, 0x39, 0x3C, 0x3D, - 0x38, 0x39, 0x3B, 0x3D, - 0x38, 0x3A, 0x3C, 0x3E, - 0x38, 0x3B, 0x3D, 0x3E, - 0x38, 0x39, 0x3D, 0x3E, - 0x38, 0x39, 0x3B, 0x3E, - 0x38, 0x3E, 0x3E, 0x3E, - 0x38, 0x38, 0x3E, 0x3E, - 0x38, 0x38, 0x38, 0x3E, - 0x38, 0x3B, 0x3C, 0x3F, - 0x38, 0x3B, 0x3E, 0x3F, - 0x38, 0x39, 0x3E, 0x3F, - 0x38, 0x39, 0x3C, 0x3F, - 0x39, 0x3A, 0x3A, 0x3B, - 0x39, 0x3A, 0x3B, 0x3C, - 0x39, 0x3B, 0x3C, 0x3D, - 0x39, 0x3A, 0x3C, 0x3D, - 0x39, 0x3A, 0x3B, 0x3D, - 0x39, 0x3B, 0x3C, 0x3E, - 0x39, 0x3B, 0x3D, 0x3E, - 0x39, 0x3A, 0x3D, 0x3E, - 0x39, 0x3A, 0x3C, 0x3E, - 0x39, 0x3B, 0x3D, 0x3F, - 0x39, 0x3C, 0x3E, 0x3F, - 0x39, 0x3A, 0x3E, 0x3F, - 0x39, 0x3A, 0x3C, 0x3F, - 0x39, 0x3F, 0x3F, 0x3F, - 0x39, 0x39, 0x3F, 0x3F, - 0x39, 0x39, 0x39, 0x3F, - 0x3A, 0x3B, 0x3B, 0x3C, - 0x3A, 0x3B, 0x3C, 0x3D, - 0x3A, 0x3C, 0x3D, 0x3E, - 0x3A, 0x3B, 0x3D, 0x3E, - 0x3A, 0x3B, 0x3C, 0x3E, - 0x3A, 0x3C, 0x3D, 0x3F, - 0x3A, 0x3C, 0x3E, 0x3F, - 0x3A, 0x3B, 0x3E, 0x3F, - 0x3A, 0x3B, 0x3D, 0x3F, - 0x3B, 0x3C, 0x3C, 0x3D, - 0x3B, 0x3C, 0x3D, 0x3E, - 0x3B, 0x3D, 0x3E, 0x3F, - 0x3B, 0x3C, 0x3E, 0x3F, - 0x3B, 0x3C, 0x3D, 0x3F, - 0x3C, 0x3D, 0x3D, 0x3E, - 0x3C, 0x3D, 0x3E, 0x3F, - 0x3D, 0x3E, 0x3E, 0x3F -}; - -#endif /* AVCODEC_ULTI_CB_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/unary.h b/tizen/distrib/ffmpeg/libavcodec/unary.h deleted file mode 100644 index 908dc93..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/unary.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_UNARY_H -#define AVCODEC_UNARY_H - -#include "get_bits.h" - -/** - * Get unary code of limited length - * @param gb GetBitContext - * @param[in] stop The bitstop value (unary code of 1's or 0's) - * @param[in] len Maximum length - * @return Unary length/index - */ -static inline int get_unary(GetBitContext *gb, int stop, int len) -{ - int i; - - for(i = 0; i < len && get_bits1(gb) != stop; i++); - return i; -} - -/** - * Get unary code terminated by a 0 with a maximum length of 33 - * @param gb GetBitContext - * @return Unary length/index - */ -static inline int get_unary_0_33(GetBitContext *gb) -{ - return get_unary(gb, 0, 33); -} - -static inline int get_unary_0_9(GetBitContext *gb) -{ - return get_unary(gb, 0, 9); -} - -#endif /* AVCODEC_UNARY_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/utils.c b/tizen/distrib/ffmpeg/libavcodec/utils.c deleted file mode 100644 index 014427d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/utils.c +++ /dev/null @@ -1,1299 +0,0 @@ -/* - * utils for libavcodec - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * utils. - */ - -/* needed for mkstemp() */ -#define _XOPEN_SOURCE 600 - -#include "libavutil/avstring.h" -#include "libavutil/integer.h" -#include "libavutil/crc.h" -#include "libavutil/pixdesc.h" -#include "avcodec.h" -#include "dsputil.h" -#include "opt.h" -#include "imgconvert.h" -#include "audioconvert.h" -#include "libxvid_internal.h" -#include "internal.h" -#include -#include -#include -#include -#if !HAVE_MKSTEMP -#include -#endif - -static int volatile entangled_thread_counter=0; -int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op); -static void *codec_mutex; - -void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size) -{ - if(min_size < *size) - return ptr; - - *size= FFMAX(17*min_size/16 + 32, min_size); - - ptr= av_realloc(ptr, *size); - if(!ptr) //we could set this to the unmodified min_size but this is safer if the user lost the ptr and uses NULL now - *size= 0; - - return ptr; -} - -void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size) -{ - void **p = ptr; - if (min_size < *size) - return; - *size= FFMAX(17*min_size/16 + 32, min_size); - av_free(*p); - *p = av_malloc(*size); - if (!*p) *size = 0; -} - -/* encoder management */ -static AVCodec *first_avcodec = NULL; - -AVCodec *av_codec_next(AVCodec *c){ - if(c) return c->next; - else return first_avcodec; -} - -void avcodec_register(AVCodec *codec) -{ - AVCodec **p; - avcodec_init(); - p = &first_avcodec; - while (*p != NULL) p = &(*p)->next; - *p = codec; - codec->next = NULL; -} - -#if LIBAVCODEC_VERSION_MAJOR < 53 -void register_avcodec(AVCodec *codec) -{ - avcodec_register(codec); -} -#endif - -unsigned avcodec_get_edge_width(void) -{ - return EDGE_WIDTH; -} - -void avcodec_set_dimensions(AVCodecContext *s, int width, int height){ - s->coded_width = width; - s->coded_height= height; - s->width = -((-width )>>s->lowres); - s->height= -((-height)>>s->lowres); -} - -typedef struct InternalBuffer{ - int last_pic_num; - uint8_t *base[4]; - uint8_t *data[4]; - int linesize[4]; - int width, height; - enum PixelFormat pix_fmt; -}InternalBuffer; - -#define INTERNAL_BUFFER_SIZE 32 - -void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){ - int w_align= 1; - int h_align= 1; - - switch(s->pix_fmt){ - case PIX_FMT_YUV420P: - case PIX_FMT_YUYV422: - case PIX_FMT_UYVY422: - case PIX_FMT_YUV422P: - case PIX_FMT_YUV440P: - case PIX_FMT_YUV444P: - case PIX_FMT_GRAY8: - case PIX_FMT_GRAY16BE: - case PIX_FMT_GRAY16LE: - case PIX_FMT_YUVJ420P: - case PIX_FMT_YUVJ422P: - case PIX_FMT_YUVJ440P: - case PIX_FMT_YUVJ444P: - case PIX_FMT_YUVA420P: - w_align= 16; //FIXME check for non mpeg style codecs and use less alignment - h_align= 16; - if(s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id == CODEC_ID_AMV || s->codec_id == CODEC_ID_THP) - h_align= 32; // interlaced is rounded up to 2 MBs - break; - case PIX_FMT_YUV411P: - case PIX_FMT_UYYVYY411: - w_align=32; - h_align=8; - break; - case PIX_FMT_YUV410P: - if(s->codec_id == CODEC_ID_SVQ1){ - w_align=64; - h_align=64; - } - case PIX_FMT_RGB555: - if(s->codec_id == CODEC_ID_RPZA){ - w_align=4; - h_align=4; - } - case PIX_FMT_PAL8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB8: - if(s->codec_id == CODEC_ID_SMC){ - w_align=4; - h_align=4; - } - break; - case PIX_FMT_BGR24: - if((s->codec_id == CODEC_ID_MSZH) || (s->codec_id == CODEC_ID_ZLIB)){ - w_align=4; - h_align=4; - } - break; - default: - w_align= 1; - h_align= 1; - break; - } - - *width = FFALIGN(*width , w_align); - *height= FFALIGN(*height, h_align); - if(s->codec_id == CODEC_ID_H264) - *height+=2; // some of the optimized chroma MC reads one line too much - - linesize_align[0] = - linesize_align[1] = - linesize_align[2] = - linesize_align[3] = STRIDE_ALIGN; -//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes -//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the -//picture size unneccessarily in some cases. The solution here is not -//pretty and better ideas are welcome! -#if HAVE_MMX - if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 || - s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F || - s->codec_id == CODEC_ID_VP6A) { - linesize_align[0] = - linesize_align[1] = - linesize_align[2] = 16; - } -#endif -} - -void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ - int chroma_shift = av_pix_fmt_descriptors[s->pix_fmt].log2_chroma_w; - int linesize_align[4]; - int align; - avcodec_align_dimensions2(s, width, height, linesize_align); - align = FFMAX(linesize_align[0], linesize_align[3]); - linesize_align[1] <<= chroma_shift; - linesize_align[2] <<= chroma_shift; - align = FFMAX3(align, linesize_align[1], linesize_align[2]); - *width=FFALIGN(*width, align); -} - -int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){ - if((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8) - return 0; - - av_log(av_log_ctx, AV_LOG_ERROR, "picture size invalid (%ux%u)\n", w, h); - return AVERROR(EINVAL); -} - -int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ - int i; - int w= s->width; - int h= s->height; - InternalBuffer *buf; - int *picture_number; - - if(pic->data[0]!=NULL) { - av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n"); - return -1; - } - if(s->internal_buffer_count >= INTERNAL_BUFFER_SIZE) { - av_log(s, AV_LOG_ERROR, "internal_buffer_count overflow (missing release_buffer?)\n"); - return -1; - } - - if(avcodec_check_dimensions(s,w,h)) - return -1; - - if(s->internal_buffer==NULL){ - s->internal_buffer= av_mallocz((INTERNAL_BUFFER_SIZE+1)*sizeof(InternalBuffer)); - } -#if 0 - s->internal_buffer= av_fast_realloc( - s->internal_buffer, - &s->internal_buffer_size, - sizeof(InternalBuffer)*FFMAX(99, s->internal_buffer_count+1)/*FIXME*/ - ); -#endif - - buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; - picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack - (*picture_number)++; - - if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ - for(i=0; i<4; i++){ - av_freep(&buf->base[i]); - buf->data[i]= NULL; - } - } - - if(buf->base[0]){ - pic->age= *picture_number - buf->last_pic_num; - buf->last_pic_num= *picture_number; - }else{ - int h_chroma_shift, v_chroma_shift; - int size[4] = {0}; - int tmpsize; - int unaligned; - AVPicture picture; - int stride_align[4]; - - avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); - - avcodec_align_dimensions2(s, &w, &h, stride_align); - - if(!(s->flags&CODEC_FLAG_EMU_EDGE)){ - w+= EDGE_WIDTH*2; - h+= EDGE_WIDTH*2; - } - - do { - // NOTE: do not align linesizes individually, this breaks e.g. assumptions - // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 - ff_fill_linesize(&picture, s->pix_fmt, w); - // increase alignment of w for next try (rhs gives the lowest bit set in w) - w += w & ~(w-1); - - unaligned = 0; - for (i=0; i<4; i++){ - unaligned |= picture.linesize[i] % stride_align[i]; - } - } while (unaligned); - - tmpsize = ff_fill_pointer(&picture, NULL, s->pix_fmt, h); - if (tmpsize < 0) - return -1; - - for (i=0; i<3 && picture.data[i+1]; i++) - size[i] = picture.data[i+1] - picture.data[i]; - size[i] = tmpsize - (picture.data[i] - picture.data[0]); - - buf->last_pic_num= -256*256*256*64; - memset(buf->base, 0, sizeof(buf->base)); - memset(buf->data, 0, sizeof(buf->data)); - - for(i=0; i<4 && size[i]; i++){ - const int h_shift= i==0 ? 0 : h_chroma_shift; - const int v_shift= i==0 ? 0 : v_chroma_shift; - - buf->linesize[i]= picture.linesize[i]; - - buf->base[i]= av_malloc(size[i]+16); //FIXME 16 - if(buf->base[i]==NULL) return -1; - memset(buf->base[i], 128, size[i]); - - // no edge if EDEG EMU or not planar YUV - if((s->flags&CODEC_FLAG_EMU_EDGE) || !size[2]) - buf->data[i] = buf->base[i]; - else - buf->data[i] = buf->base[i] + FFALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), stride_align[i]); - } - if(size[1] && !size[2]) - ff_set_systematic_pal((uint32_t*)buf->data[1], s->pix_fmt); - buf->width = s->width; - buf->height = s->height; - buf->pix_fmt= s->pix_fmt; - pic->age= 256*256*256*64; - } - pic->type= FF_BUFFER_TYPE_INTERNAL; - - for(i=0; i<4; i++){ - pic->base[i]= buf->base[i]; - pic->data[i]= buf->data[i]; - pic->linesize[i]= buf->linesize[i]; - } - s->internal_buffer_count++; - - pic->reordered_opaque= s->reordered_opaque; - - if(s->debug&FF_DEBUG_BUFFERS) - av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count); - - return 0; -} - -void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ - int i; - InternalBuffer *buf, *last; - - assert(pic->type==FF_BUFFER_TYPE_INTERNAL); - assert(s->internal_buffer_count); - - buf = NULL; /* avoids warning */ - for(i=0; iinternal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize - buf= &((InternalBuffer*)s->internal_buffer)[i]; - if(buf->data[0] == pic->data[0]) - break; - } - assert(i < s->internal_buffer_count); - s->internal_buffer_count--; - last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; - - FFSWAP(InternalBuffer, *buf, *last); - - for(i=0; i<4; i++){ - pic->data[i]=NULL; -// pic->base[i]=NULL; - } -//printf("R%X\n", pic->opaque); - - if(s->debug&FF_DEBUG_BUFFERS) - av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count); -} - -int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ - AVFrame temp_pic; - int i; - - /* If no picture return a new buffer */ - if(pic->data[0] == NULL) { - /* We will copy from buffer, so must be readable */ - pic->buffer_hints |= FF_BUFFER_HINTS_READABLE; - return s->get_buffer(s, pic); - } - - /* If internal buffer type return the same buffer */ - if(pic->type == FF_BUFFER_TYPE_INTERNAL) { - pic->reordered_opaque= s->reordered_opaque; - return 0; - } - - /* - * Not internal type and reget_buffer not overridden, emulate cr buffer - */ - temp_pic = *pic; - for(i = 0; i < 4; i++) - pic->data[i] = pic->base[i] = NULL; - pic->opaque = NULL; - /* Allocate new frame */ - if (s->get_buffer(s, pic)) - return -1; - /* Copy image data from old buffer to new buffer */ - av_picture_copy((AVPicture*)pic, (AVPicture*)&temp_pic, s->pix_fmt, s->width, - s->height); - s->release_buffer(s, &temp_pic); // Release old frame - return 0; -} - -int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size){ - int i; - - for(i=0; ipts= AV_NOPTS_VALUE; - pic->key_frame= 1; -} - -AVFrame *avcodec_alloc_frame(void){ - AVFrame *pic= av_malloc(sizeof(AVFrame)); - - if(pic==NULL) return NULL; - - avcodec_get_frame_defaults(pic); - - return pic; -} - -int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) -{ - int ret= -1; - - /* If there is a user-supplied mutex locking routine, call it. */ - if (ff_lockmgr_cb) { - if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN)) - return -1; - } - - entangled_thread_counter++; - if(entangled_thread_counter != 1){ - av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n"); - goto end; - } - - if(avctx->codec || !codec) - goto end; - - if (codec->priv_data_size > 0) { - avctx->priv_data = av_mallocz(codec->priv_data_size); - if (!avctx->priv_data) { - ret = AVERROR(ENOMEM); - goto end; - } - } else { - avctx->priv_data = NULL; - } - - if(avctx->coded_width && avctx->coded_height) - avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); - else if(avctx->width && avctx->height) - avcodec_set_dimensions(avctx, avctx->width, avctx->height); - -#define SANE_NB_CHANNELS 128U - if (((avctx->coded_width || avctx->coded_height) - && avcodec_check_dimensions(avctx, avctx->coded_width, avctx->coded_height)) - || avctx->channels > SANE_NB_CHANNELS) { - ret = AVERROR(EINVAL); - goto free_and_end; - } - - avctx->codec = codec; - if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type == codec->type) && - avctx->codec_id == CODEC_ID_NONE) { - avctx->codec_type = codec->type; - avctx->codec_id = codec->id; - } - if(avctx->codec_id != codec->id || avctx->codec_type != codec->type){ - av_log(avctx, AV_LOG_ERROR, "codec type or id mismatches\n"); - goto free_and_end; - } - avctx->frame_number = 0; - if(avctx->codec->init){ - ret = avctx->codec->init(avctx); - if (ret < 0) { - goto free_and_end; - } - } - ret=0; -end: - entangled_thread_counter--; - - /* Release any user-supplied mutex. */ - if (ff_lockmgr_cb) { - (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE); - } - return ret; -free_and_end: - av_freep(&avctx->priv_data); - avctx->codec= NULL; - goto end; -} - -int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const short *samples) -{ - if(buf_size < FF_MIN_BUFFER_SIZE && 0){ - av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n"); - return -1; - } - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || samples){ - int ret = avctx->codec->encode(avctx, buf, buf_size, samples); - avctx->frame_number++; - return ret; - }else - return 0; -} - -int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVFrame *pict) -{ - if(buf_size < FF_MIN_BUFFER_SIZE){ - av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n"); - return -1; - } - if(avcodec_check_dimensions(avctx,avctx->width,avctx->height)) - return -1; - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || pict){ - int ret = avctx->codec->encode(avctx, buf, buf_size, pict); - avctx->frame_number++; - emms_c(); //needed to avoid an emms_c() call before every return; - - return ret; - }else - return 0; -} - -int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub) -{ - int ret; - if(sub->start_display_time) { - av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); - return -1; - } - if(sub->num_rects == 0 || !sub->rects) - return -1; - ret = avctx->codec->encode(avctx, buf, buf_size, sub); - avctx->frame_number++; - return ret; -} - -#if LIBAVCODEC_VERSION_MAJOR < 53 -int attribute_align_arg avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - const uint8_t *buf, int buf_size) -{ - AVPacket avpkt; - av_init_packet(&avpkt); - avpkt.data = buf; - avpkt.size = buf_size; - // HACK for CorePNG to decode as normal PNG by default - avpkt.flags = AV_PKT_FLAG_KEY; - - return avcodec_decode_video2(avctx, picture, got_picture_ptr, &avpkt); -} -#endif - -int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - AVPacket *avpkt) -{ - int ret; - - *got_picture_ptr= 0; - if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)) - return -1; - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ - ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - avpkt); - - emms_c(); //needed to avoid an emms_c() call before every return; - - if (*got_picture_ptr) - avctx->frame_number++; - }else - ret= 0; - - return ret; -} - -#if LIBAVCODEC_VERSION_MAJOR < 53 -int attribute_align_arg avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - const uint8_t *buf, int buf_size) -{ - AVPacket avpkt; - av_init_packet(&avpkt); - avpkt.data = buf; - avpkt.size = buf_size; - - return avcodec_decode_audio3(avctx, samples, frame_size_ptr, &avpkt); -} -#endif - -int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - AVPacket *avpkt) -{ - int ret; - - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ - //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough - if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){ - av_log(avctx, AV_LOG_ERROR, "buffer smaller than AVCODEC_MAX_AUDIO_FRAME_SIZE\n"); - return -1; - } - if(*frame_size_ptr < FF_MIN_BUFFER_SIZE || - *frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t)){ - av_log(avctx, AV_LOG_ERROR, "buffer %d too small\n", *frame_size_ptr); - return -1; - } - - ret = avctx->codec->decode(avctx, samples, frame_size_ptr, avpkt); - avctx->frame_number++; - }else{ - ret= 0; - *frame_size_ptr=0; - } - return ret; -} - -#if LIBAVCODEC_VERSION_MAJOR < 53 -int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - const uint8_t *buf, int buf_size) -{ - AVPacket avpkt; - av_init_packet(&avpkt); - avpkt.data = buf; - avpkt.size = buf_size; - - return avcodec_decode_subtitle2(avctx, sub, got_sub_ptr, &avpkt); -} -#endif - -int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - AVPacket *avpkt) -{ - int ret; - - *got_sub_ptr = 0; - ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); - if (*got_sub_ptr) - avctx->frame_number++; - return ret; -} - -av_cold int avcodec_close(AVCodecContext *avctx) -{ - /* If there is a user-supplied mutex locking routine, call it. */ - if (ff_lockmgr_cb) { - if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN)) - return -1; - } - - entangled_thread_counter++; - if(entangled_thread_counter != 1){ - av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n"); - entangled_thread_counter--; - return -1; - } - - if (HAVE_THREADS && avctx->thread_opaque) - avcodec_thread_free(avctx); - if (avctx->codec && avctx->codec->close) - avctx->codec->close(avctx); - avcodec_default_free_buffers(avctx); - av_freep(&avctx->priv_data); - if(avctx->codec && avctx->codec->encode) - av_freep(&avctx->extradata); - avctx->codec = NULL; - entangled_thread_counter--; - - /* Release any user-supplied mutex. */ - if (ff_lockmgr_cb) { - (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE); - } - return 0; -} - -AVCodec *avcodec_find_encoder(enum CodecID id) -{ - AVCodec *p, *experimental=NULL; - p = first_avcodec; - while (p) { - if (p->encode != NULL && p->id == id) { - if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) { - experimental = p; - } else - return p; - } - p = p->next; - } - return experimental; -} - -AVCodec *avcodec_find_encoder_by_name(const char *name) -{ - AVCodec *p; - if (!name) - return NULL; - p = first_avcodec; - while (p) { - if (p->encode != NULL && strcmp(name,p->name) == 0) - return p; - p = p->next; - } - return NULL; -} - -AVCodec *avcodec_find_decoder(enum CodecID id) -{ - AVCodec *p; - p = first_avcodec; - while (p) { - if (p->decode != NULL && p->id == id) - return p; - p = p->next; - } - return NULL; -} - -AVCodec *avcodec_find_decoder_by_name(const char *name) -{ - AVCodec *p; - if (!name) - return NULL; - p = first_avcodec; - while (p) { - if (p->decode != NULL && strcmp(name,p->name) == 0) - return p; - p = p->next; - } - return NULL; -} - -static int get_bit_rate(AVCodecContext *ctx) -{ - int bit_rate; - int bits_per_sample; - - switch(ctx->codec_type) { - case AVMEDIA_TYPE_VIDEO: - case AVMEDIA_TYPE_DATA: - case AVMEDIA_TYPE_SUBTITLE: - case AVMEDIA_TYPE_ATTACHMENT: - bit_rate = ctx->bit_rate; - break; - case AVMEDIA_TYPE_AUDIO: - bits_per_sample = av_get_bits_per_sample(ctx->codec_id); - bit_rate = bits_per_sample ? ctx->sample_rate * ctx->channels * bits_per_sample : ctx->bit_rate; - break; - default: - bit_rate = 0; - break; - } - return bit_rate; -} - -void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) -{ - const char *codec_name; - AVCodec *p; - char buf1[32]; - int bitrate; - AVRational display_aspect_ratio; - - if (encode) - p = avcodec_find_encoder(enc->codec_id); - else - p = avcodec_find_decoder(enc->codec_id); - - if (p) { - codec_name = p->name; - } else if (enc->codec_id == CODEC_ID_MPEG2TS) { - /* fake mpeg2 transport stream codec (currently not - registered) */ - codec_name = "mpeg2ts"; - } else if (enc->codec_name[0] != '\0') { - codec_name = enc->codec_name; - } else { - /* output avi tags */ - if( isprint(enc->codec_tag&0xFF) && isprint((enc->codec_tag>>8)&0xFF) - && isprint((enc->codec_tag>>16)&0xFF) && isprint((enc->codec_tag>>24)&0xFF)){ - snprintf(buf1, sizeof(buf1), "%c%c%c%c / 0x%04X", - enc->codec_tag & 0xff, - (enc->codec_tag >> 8) & 0xff, - (enc->codec_tag >> 16) & 0xff, - (enc->codec_tag >> 24) & 0xff, - enc->codec_tag); - } else { - snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag); - } - codec_name = buf1; - } - - switch(enc->codec_type) { - case AVMEDIA_TYPE_VIDEO: - snprintf(buf, buf_size, - "Video: %s%s", - codec_name, enc->mb_decision ? " (hq)" : ""); - if (enc->pix_fmt != PIX_FMT_NONE) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %s", - avcodec_get_pix_fmt_name(enc->pix_fmt)); - } - if (enc->width) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %dx%d", - enc->width, enc->height); - if (enc->sample_aspect_ratio.num) { - av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, - enc->width*enc->sample_aspect_ratio.num, - enc->height*enc->sample_aspect_ratio.den, - 1024*1024); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " [PAR %d:%d DAR %d:%d]", - enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den, - display_aspect_ratio.num, display_aspect_ratio.den); - } - if(av_log_get_level() >= AV_LOG_DEBUG){ - int g= av_gcd(enc->time_base.num, enc->time_base.den); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d/%d", - enc->time_base.num/g, enc->time_base.den/g); - } - } - if (encode) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", q=%d-%d", enc->qmin, enc->qmax); - } - break; - case AVMEDIA_TYPE_AUDIO: - snprintf(buf, buf_size, - "Audio: %s", - codec_name); - if (enc->sample_rate) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d Hz", enc->sample_rate); - } - av_strlcat(buf, ", ", buf_size); - avcodec_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout); - if (enc->sample_fmt != SAMPLE_FMT_NONE) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %s", avcodec_get_sample_fmt_name(enc->sample_fmt)); - } - break; - case AVMEDIA_TYPE_DATA: - snprintf(buf, buf_size, "Data: %s", codec_name); - break; - case AVMEDIA_TYPE_SUBTITLE: - snprintf(buf, buf_size, "Subtitle: %s", codec_name); - break; - case AVMEDIA_TYPE_ATTACHMENT: - snprintf(buf, buf_size, "Attachment: %s", codec_name); - break; - default: - snprintf(buf, buf_size, "Invalid Codec type %d", enc->codec_type); - return; - } - if (encode) { - if (enc->flags & CODEC_FLAG_PASS1) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", pass 1"); - if (enc->flags & CODEC_FLAG_PASS2) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", pass 2"); - } - bitrate = get_bit_rate(enc); - if (bitrate != 0) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d kb/s", bitrate / 1000); - } -} - -unsigned avcodec_version( void ) -{ - return LIBAVCODEC_VERSION_INT; -} - -const char *avcodec_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *avcodec_license(void) -{ -#define LICENSE_PREFIX "libavcodec license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} - -void avcodec_init(void) -{ - static int initialized = 0; - - if (initialized != 0) - return; - initialized = 1; - - dsputil_static_init(); -} - -void avcodec_flush_buffers(AVCodecContext *avctx) -{ - if(avctx->codec->flush) - avctx->codec->flush(avctx); -} - -void avcodec_default_free_buffers(AVCodecContext *s){ - int i, j; - - if(s->internal_buffer==NULL) return; - - if (s->internal_buffer_count) - av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n", s->internal_buffer_count); - for(i=0; iinternal_buffer)[i]; - for(j=0; j<4; j++){ - av_freep(&buf->base[j]); - buf->data[j]= NULL; - } - } - av_freep(&s->internal_buffer); - - s->internal_buffer_count=0; -} - -char av_get_pict_type_char(int pict_type){ - switch(pict_type){ - case FF_I_TYPE: return 'I'; - case FF_P_TYPE: return 'P'; - case FF_B_TYPE: return 'B'; - case FF_S_TYPE: return 'S'; - case FF_SI_TYPE:return 'i'; - case FF_SP_TYPE:return 'p'; - case FF_BI_TYPE:return 'b'; - default: return '?'; - } -} - -int av_get_bits_per_sample(enum CodecID codec_id){ - switch(codec_id){ - case CODEC_ID_ADPCM_SBPRO_2: - return 2; - case CODEC_ID_ADPCM_SBPRO_3: - return 3; - case CODEC_ID_ADPCM_SBPRO_4: - case CODEC_ID_ADPCM_CT: - case CODEC_ID_ADPCM_IMA_WAV: - case CODEC_ID_ADPCM_MS: - case CODEC_ID_ADPCM_YAMAHA: - return 4; - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_ZORK: - return 8; - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16LE_PLANAR: - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_U16LE: - return 16; - case CODEC_ID_PCM_S24DAUD: - case CODEC_ID_PCM_S24BE: - case CODEC_ID_PCM_S24LE: - case CODEC_ID_PCM_U24BE: - case CODEC_ID_PCM_U24LE: - return 24; - case CODEC_ID_PCM_S32BE: - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_U32BE: - case CODEC_ID_PCM_U32LE: - case CODEC_ID_PCM_F32BE: - case CODEC_ID_PCM_F32LE: - return 32; - case CODEC_ID_PCM_F64BE: - case CODEC_ID_PCM_F64LE: - return 64; - default: - return 0; - } -} - -int av_get_bits_per_sample_format(enum SampleFormat sample_fmt) { - switch (sample_fmt) { - case SAMPLE_FMT_U8: - return 8; - case SAMPLE_FMT_S16: - return 16; - case SAMPLE_FMT_S32: - case SAMPLE_FMT_FLT: - return 32; - case SAMPLE_FMT_DBL: - return 64; - default: - return 0; - } -} - -#if !HAVE_THREADS -int avcodec_thread_init(AVCodecContext *s, int thread_count){ - s->thread_count = thread_count; - return -1; -} -#endif - -unsigned int av_xiphlacing(unsigned char *s, unsigned int v) -{ - unsigned int n = 0; - - while(v >= 0xff) { - *s++ = 0xff; - v -= 0xff; - n++; - } - *s = v; - n++; - return n; -} - -/* Wrapper to work around the lack of mkstemp() on mingw/cygin. - * Also, tries to create file in /tmp first, if possible. - * *prefix can be a character constant; *filename will be allocated internally. - * Returns file descriptor of opened file (or -1 on error) - * and opened file name in **filename. */ -int av_tempfile(char *prefix, char **filename) { - int fd=-1; -#if !HAVE_MKSTEMP - *filename = tempnam(".", prefix); -#else - size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ - *filename = av_malloc(len); -#endif - /* -----common section-----*/ - if (*filename == NULL) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); - return -1; - } -#if !HAVE_MKSTEMP - fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); -#else - snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); - fd = mkstemp(*filename); - if (fd < 0) { - snprintf(*filename, len, "./%sXXXXXX", prefix); - fd = mkstemp(*filename); - } -#endif - /* -----common section-----*/ - if (fd < 0) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); - return -1; - } - return fd; /* success */ -} - -typedef struct { - const char *abbr; - int width, height; -} VideoFrameSizeAbbr; - -typedef struct { - const char *abbr; - int rate_num, rate_den; -} VideoFrameRateAbbr; - -static const VideoFrameSizeAbbr video_frame_size_abbrs[] = { - { "ntsc", 720, 480 }, - { "pal", 720, 576 }, - { "qntsc", 352, 240 }, /* VCD compliant NTSC */ - { "qpal", 352, 288 }, /* VCD compliant PAL */ - { "sntsc", 640, 480 }, /* square pixel NTSC */ - { "spal", 768, 576 }, /* square pixel PAL */ - { "film", 352, 240 }, - { "ntsc-film", 352, 240 }, - { "sqcif", 128, 96 }, - { "qcif", 176, 144 }, - { "cif", 352, 288 }, - { "4cif", 704, 576 }, - { "16cif", 1408,1152 }, - { "qqvga", 160, 120 }, - { "qvga", 320, 240 }, - { "vga", 640, 480 }, - { "svga", 800, 600 }, - { "xga", 1024, 768 }, - { "uxga", 1600,1200 }, - { "qxga", 2048,1536 }, - { "sxga", 1280,1024 }, - { "qsxga", 2560,2048 }, - { "hsxga", 5120,4096 }, - { "wvga", 852, 480 }, - { "wxga", 1366, 768 }, - { "wsxga", 1600,1024 }, - { "wuxga", 1920,1200 }, - { "woxga", 2560,1600 }, - { "wqsxga", 3200,2048 }, - { "wquxga", 3840,2400 }, - { "whsxga", 6400,4096 }, - { "whuxga", 7680,4800 }, - { "cga", 320, 200 }, - { "ega", 640, 350 }, - { "hd480", 852, 480 }, - { "hd720", 1280, 720 }, - { "hd1080", 1920,1080 }, -}; - -static const VideoFrameRateAbbr video_frame_rate_abbrs[]= { - { "ntsc", 30000, 1001 }, - { "pal", 25, 1 }, - { "qntsc", 30000, 1001 }, /* VCD compliant NTSC */ - { "qpal", 25, 1 }, /* VCD compliant PAL */ - { "sntsc", 30000, 1001 }, /* square pixel NTSC */ - { "spal", 25, 1 }, /* square pixel PAL */ - { "film", 24, 1 }, - { "ntsc-film", 24000, 1001 }, -}; - -int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str) -{ - int i; - int n = FF_ARRAY_ELEMS(video_frame_size_abbrs); - char *p; - int frame_width = 0, frame_height = 0; - - for(i=0;inum = video_frame_rate_abbrs[i].rate_num; - frame_rate->den = video_frame_rate_abbrs[i].rate_den; - return 0; - } - - /* Then, we try to parse it as fraction */ - cp = strchr(arg, '/'); - if (!cp) - cp = strchr(arg, ':'); - if (cp) { - char* cpp; - frame_rate->num = strtol(arg, &cpp, 10); - if (cpp != arg || cpp == cp) - frame_rate->den = strtol(cp+1, &cpp, 10); - else - frame_rate->num = 0; - } - else { - /* Finally we give up and parse it as double */ - AVRational time_base = av_d2q(strtod(arg, 0), 1001000); - frame_rate->den = time_base.den; - frame_rate->num = time_base.num; - } - if (!frame_rate->num || !frame_rate->den) - return -1; - else - return 0; -} - -int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b){ - int i; - for(i=0; inext; - *p = hwaccel; - hwaccel->next = NULL; -} - -AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel) -{ - return hwaccel ? hwaccel->next : first_hwaccel; -} - -AVHWAccel *ff_find_hwaccel(enum CodecID codec_id, enum PixelFormat pix_fmt) -{ - AVHWAccel *hwaccel=NULL; - - while((hwaccel= av_hwaccel_next(hwaccel))){ - if ( hwaccel->id == codec_id - && hwaccel->pix_fmt == pix_fmt) - return hwaccel; - } - return NULL; -} - -int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)) -{ - if (ff_lockmgr_cb) { - if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY)) - return -1; - } - - ff_lockmgr_cb = cb; - - if (ff_lockmgr_cb) { - if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_CREATE)) - return -1; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/v210dec.c b/tizen/distrib/ffmpeg/libavcodec/v210dec.c deleted file mode 100644 index a1a0827..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/v210dec.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * V210 decoder - * - * Copyright (C) 2009 Michael Niedermayer - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "libavutil/bswap.h" - -static av_cold int decode_init(AVCodecContext *avctx) -{ - if (avctx->width & 1) { - av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n"); - return -1; - } - avctx->pix_fmt = PIX_FMT_YUV422P16; - avctx->bits_per_raw_sample = 10; - - avctx->coded_frame = avcodec_alloc_frame(); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - int h, w; - AVFrame *pic = avctx->coded_frame; - const uint8_t *psrc = avpkt->data; - uint16_t *y, *u, *v; - int aligned_width = ((avctx->width + 47) / 48) * 48; - int stride = aligned_width * 8 / 3; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - if (avpkt->size < stride * avctx->height) { - av_log(avctx, AV_LOG_ERROR, "packet too small\n"); - return -1; - } - - pic->reference = 0; - if (avctx->get_buffer(avctx, pic) < 0) - return -1; - - y = (uint16_t*)pic->data[0]; - u = (uint16_t*)pic->data[1]; - v = (uint16_t*)pic->data[2]; - pic->pict_type = FF_I_TYPE; - pic->key_frame = 1; - -#define READ_PIXELS(a, b, c) \ - do { \ - val = le2me_32(*src++); \ - *a++ = val << 6; \ - *b++ = (val >> 4) & 0xFFC0; \ - *c++ = (val >> 14) & 0xFFC0; \ - } while (0) - - for (h = 0; h < avctx->height; h++) { - const uint32_t *src = (const uint32_t*)psrc; - uint32_t val; - for (w = 0; w < avctx->width - 5; w += 6) { - READ_PIXELS(u, y, v); - READ_PIXELS(y, u, y); - READ_PIXELS(v, y, u); - READ_PIXELS(y, v, y); - } - if (w < avctx->width - 1) { - READ_PIXELS(u, y, v); - - val = le2me_32(*src++); - *y++ = val << 6; - } - if (w < avctx->width - 3) { - *u++ = (val >> 4) & 0xFFC0; - *y++ = (val >> 14) & 0xFFC0; - - val = le2me_32(*src++); - *v++ = val << 6; - *y++ = (val >> 4) & 0xFFC0; - } - - psrc += stride; - y += pic->linesize[0] / 2 - avctx->width; - u += pic->linesize[1] / 2 - avctx->width / 2; - v += pic->linesize[2] / 2 - avctx->width / 2; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = *avctx->coded_frame; - - return avpkt->size; -} - -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - -AVCodec v210_decoder = { - "v210", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_V210, - 0, - decode_init, - NULL, - decode_close, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/v210enc.c b/tizen/distrib/ffmpeg/libavcodec/v210enc.c deleted file mode 100644 index 11e0e0e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/v210enc.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * V210 encoder - * - * Copyright (C) 2009 Michael Niedermayer - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "libavcodec/bytestream.h" - -static av_cold int encode_init(AVCodecContext *avctx) -{ - if (avctx->width & 1) { - av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n"); - return -1; - } - - if (avctx->pix_fmt != PIX_FMT_YUV422P16) { - av_log(avctx, AV_LOG_ERROR, "v210 needs YUV422P16\n"); - return -1; - } - - if (avctx->bits_per_raw_sample != 10) - av_log(avctx, AV_LOG_WARNING, "bits per raw sample: %d != 10-bit\n", - avctx->bits_per_raw_sample); - - avctx->coded_frame = avcodec_alloc_frame(); - - avctx->coded_frame->key_frame = 1; - avctx->coded_frame->pict_type = FF_I_TYPE; - - return 0; -} - -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, - int buf_size, void *data) -{ - const AVFrame *pic = data; - int aligned_width = ((avctx->width + 47) / 48) * 48; - int stride = aligned_width * 8 / 3; - int h, w; - const uint16_t *y = (const uint16_t*)pic->data[0]; - const uint16_t *u = (const uint16_t*)pic->data[1]; - const uint16_t *v = (const uint16_t*)pic->data[2]; - uint8_t *p = buf; - uint8_t *pdst = buf; - - if (buf_size < aligned_width * avctx->height * 8 / 3) { - av_log(avctx, AV_LOG_ERROR, "output buffer too small\n"); - return -1; - } - -#define WRITE_PIXELS(a, b, c) \ - do { \ - val = (*a++ >> 6) | \ - ((*b++ & 0xFFC0) << 4); \ - val|= (*c++ & 0xFFC0) << 14; \ - bytestream_put_le32(&p, val); \ - } while (0) - - for (h = 0; h < avctx->height; h++) { - uint32_t val; - for (w = 0; w < avctx->width - 5; w += 6) { - WRITE_PIXELS(u, y, v); - WRITE_PIXELS(y, u, y); - WRITE_PIXELS(v, y, u); - WRITE_PIXELS(y, v, y); - } - if (w < avctx->width - 1) { - WRITE_PIXELS(u, y, v); - - val = *y++ >> 6; - if (w == avctx->width - 2) - bytestream_put_le32(&p, val); - } - if (w < avctx->width - 3) { - val |=((*u++ & 0xFFC0) << 4) | - ((*y++ & 0xFFC0) << 14); - bytestream_put_le32(&p, val); - - val = (*v++ >> 6) | - (*y++ & 0xFFC0) << 4; - bytestream_put_le32(&p, val); - } - - pdst += stride; - memset(p, 0, pdst - p); - p = pdst; - y += pic->linesize[0] / 2 - avctx->width; - u += pic->linesize[1] / 2 - avctx->width / 2; - v += pic->linesize[2] / 2 - avctx->width / 2; - } - - return p - buf; -} - -static av_cold int encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - - return 0; -} - -AVCodec v210_encoder = { - "v210", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_V210, - 0, - encode_init, - encode_frame, - encode_close, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P16, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/v210x.c b/tizen/distrib/ffmpeg/libavcodec/v210x.c deleted file mode 100644 index d869d64..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/v210x.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2009 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "libavutil/bswap.h" - -static av_cold int decode_init(AVCodecContext *avctx) -{ - if(avctx->width & 1){ - av_log(avctx, AV_LOG_ERROR, "v210x needs even width\n"); - return -1; - } - avctx->pix_fmt = PIX_FMT_YUV422P16; - avctx->bits_per_raw_sample= 10; - - avctx->coded_frame= avcodec_alloc_frame(); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - int y=0; - int width= avctx->width; - AVFrame *pic= avctx->coded_frame; - const uint32_t *src= (const uint32_t *)avpkt->data; - uint16_t *ydst, *udst, *vdst, *yend; - - if(pic->data[0]) - avctx->release_buffer(avctx, pic); - - if(avpkt->size < avctx->width * avctx->height * 8 / 3){ - av_log(avctx, AV_LOG_ERROR, "Packet too small\n"); - return -1; - } - - if(avpkt->size > avctx->width * avctx->height * 8 / 3){ - av_log(avctx, AV_LOG_ERROR, "Probably padded data, need sample!\n"); - } - - pic->reference= 0; - if(avctx->get_buffer(avctx, pic) < 0) - return -1; - - ydst= (uint16_t *)pic->data[0]; - udst= (uint16_t *)pic->data[1]; - vdst= (uint16_t *)pic->data[2]; - yend= ydst + width; - pic->pict_type= FF_I_TYPE; - pic->key_frame= 1; - - for(;;){ - uint32_t v= be2me_32(*src++); - *udst++= (v>>16) & 0xFFC0; - *ydst++= (v>>6 ) & 0xFFC0; - *vdst++= (v<<4 ) & 0xFFC0; - - v= be2me_32(*src++); - *ydst++= (v>>16) & 0xFFC0; - - if(ydst >= yend){ - ydst+= pic->linesize[0]/2 - width; - udst+= pic->linesize[1]/2 - width/2; - vdst+= pic->linesize[2]/2 - width/2; - yend= ydst + width; - if(++y >= avctx->height) - break; - } - - *udst++= (v>>6 ) & 0xFFC0; - *ydst++= (v<<4 ) & 0xFFC0; - - v= be2me_32(*src++); - *vdst++= (v>>16) & 0xFFC0; - *ydst++= (v>>6 ) & 0xFFC0; - - if(ydst >= yend){ - ydst+= pic->linesize[0]/2 - width; - udst+= pic->linesize[1]/2 - width/2; - vdst+= pic->linesize[2]/2 - width/2; - yend= ydst + width; - if(++y >= avctx->height) - break; - } - - *udst++= (v<<4 ) & 0xFFC0; - - v= be2me_32(*src++); - *ydst++= (v>>16) & 0xFFC0; - *vdst++= (v>>6 ) & 0xFFC0; - *ydst++= (v<<4 ) & 0xFFC0; - if(ydst >= yend){ - ydst+= pic->linesize[0]/2 - width; - udst+= pic->linesize[1]/2 - width/2; - vdst+= pic->linesize[2]/2 - width/2; - yend= ydst + width; - if(++y >= avctx->height) - break; - } - } - - *data_size=sizeof(AVFrame); - *(AVFrame*)data= *avctx->coded_frame; - - return avpkt->size; -} - -static av_cold int decode_close(AVCodecContext *avctx) -{ - AVFrame *pic = avctx->coded_frame; - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - av_freep(&avctx->coded_frame); - - return 0; -} - -AVCodec v210x_decoder = { - "v210x", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_V210X, - 0, - decode_init, - NULL, - decode_close, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vaapi.c b/tizen/distrib/ffmpeg/libavcodec/vaapi.c deleted file mode 100644 index 10f9054..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vaapi.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Video Acceleration API (video decoding) - * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "vaapi_internal.h" - -/** - * \addtogroup VAAPI_Decoding - * - * @{ - */ - -static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers) -{ - unsigned int i; - for (i = 0; i < n_buffers; i++) { - if (buffers[i]) { - vaDestroyBuffer(display, buffers[i]); - buffers[i] = 0; - } - } -} - -static int render_picture(struct vaapi_context *vactx, VASurfaceID surface) -{ - VABufferID va_buffers[3]; - unsigned int n_va_buffers = 0; - - vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id); - va_buffers[n_va_buffers++] = vactx->pic_param_buf_id; - - if (vactx->iq_matrix_buf_id) { - vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id); - va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id; - } - - if (vactx->bitplane_buf_id) { - vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id); - va_buffers[n_va_buffers++] = vactx->bitplane_buf_id; - } - - if (vaBeginPicture(vactx->display, vactx->context_id, - surface) != VA_STATUS_SUCCESS) - return -1; - - if (vaRenderPicture(vactx->display, vactx->context_id, - va_buffers, n_va_buffers) != VA_STATUS_SUCCESS) - return -1; - - if (vaRenderPicture(vactx->display, vactx->context_id, - vactx->slice_buf_ids, - vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS) - return -1; - - if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS) - return -1; - - return 0; -} - -static int commit_slices(struct vaapi_context *vactx) -{ - VABufferID *slice_buf_ids; - VABufferID slice_param_buf_id, slice_data_buf_id; - - if (vactx->slice_count == 0) - return 0; - - slice_buf_ids = - av_fast_realloc(vactx->slice_buf_ids, - &vactx->slice_buf_ids_alloc, - (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0])); - if (!slice_buf_ids) - return -1; - vactx->slice_buf_ids = slice_buf_ids; - - slice_param_buf_id = 0; - if (vaCreateBuffer(vactx->display, vactx->context_id, - VASliceParameterBufferType, - vactx->slice_param_size, - vactx->slice_count, vactx->slice_params, - &slice_param_buf_id) != VA_STATUS_SUCCESS) - return -1; - vactx->slice_count = 0; - - slice_data_buf_id = 0; - if (vaCreateBuffer(vactx->display, vactx->context_id, - VASliceDataBufferType, - vactx->slice_data_size, - 1, (void *)vactx->slice_data, - &slice_data_buf_id) != VA_STATUS_SUCCESS) - return -1; - vactx->slice_data = NULL; - vactx->slice_data_size = 0; - - slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id; - slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id; - return 0; -} - -static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id) -{ - void *data = NULL; - - *buf_id = 0; - if (vaCreateBuffer(vactx->display, vactx->context_id, - type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS) - vaMapBuffer(vactx->display, *buf_id, &data); - - return data; -} - -void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size) -{ - return alloc_buffer(vactx, VAPictureParameterBufferType, size, &vactx->pic_param_buf_id); -} - -void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size) -{ - return alloc_buffer(vactx, VAIQMatrixBufferType, size, &vactx->iq_matrix_buf_id); -} - -uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size) -{ - return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id); -} - -VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size) -{ - uint8_t *slice_params; - VASliceParameterBufferBase *slice_param; - - if (!vactx->slice_data) - vactx->slice_data = buffer; - if (vactx->slice_data + vactx->slice_data_size != buffer) { - if (commit_slices(vactx) < 0) - return NULL; - vactx->slice_data = buffer; - } - - slice_params = - av_fast_realloc(vactx->slice_params, - &vactx->slice_params_alloc, - (vactx->slice_count + 1) * vactx->slice_param_size); - if (!slice_params) - return NULL; - vactx->slice_params = slice_params; - - slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size); - slice_param->slice_data_size = size; - slice_param->slice_data_offset = vactx->slice_data_size; - slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; - - vactx->slice_count++; - vactx->slice_data_size += size; - return slice_param; -} - -int ff_vaapi_common_end_frame(MpegEncContext *s) -{ - struct vaapi_context * const vactx = s->avctx->hwaccel_context; - int ret = -1; - - dprintf(s->avctx, "ff_vaapi_common_end_frame()\n"); - - if (commit_slices(vactx) < 0) - goto done; - if (vactx->n_slice_buf_ids > 0) { - if (render_picture(vactx, ff_vaapi_get_surface_id(s->current_picture_ptr)) < 0) - goto done; - ff_draw_horiz_band(s, 0, s->avctx->height); - } - ret = 0; - -done: - destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1); - destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1); - destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1); - destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids); - av_freep(&vactx->slice_buf_ids); - av_freep(&vactx->slice_params); - vactx->n_slice_buf_ids = 0; - vactx->slice_buf_ids_alloc = 0; - vactx->slice_count = 0; - vactx->slice_params_alloc = 0; - return ret; -} - -/* @} */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vaapi.h b/tizen/distrib/ffmpeg/libavcodec/vaapi.h deleted file mode 100644 index 07568a4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vaapi.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Video Acceleration API (shared data between FFmpeg and the video player) - * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VAAPI_H -#define AVCODEC_VAAPI_H - -#include - -/** - * \defgroup VAAPI_Decoding VA API Decoding - * \ingroup Decoder - * @{ - */ - -/** - * This structure is used to share data between the FFmpeg library and - * the client video application. - * This shall be zero-allocated and available as - * AVCodecContext.hwaccel_context. All user members can be set once - * during initialization or through each AVCodecContext.get_buffer() - * function call. In any case, they must be valid prior to calling - * decoding functions. - */ -struct vaapi_context { - /** - * Window system dependent data - * - * - encoding: unused - * - decoding: Set by user - */ - void *display; - - /** - * Configuration ID - * - * - encoding: unused - * - decoding: Set by user - */ - uint32_t config_id; - - /** - * Context ID (video decode pipeline) - * - * - encoding: unused - * - decoding: Set by user - */ - uint32_t context_id; - - /** - * VAPictureParameterBuffer ID - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t pic_param_buf_id; - - /** - * VAIQMatrixBuffer ID - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t iq_matrix_buf_id; - - /** - * VABitPlaneBuffer ID (for VC-1 decoding) - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t bitplane_buf_id; - - /** - * Slice parameter/data buffer IDs - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t *slice_buf_ids; - - /** - * Number of effective slice buffer IDs to send to the HW - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int n_slice_buf_ids; - - /** - * Size of pre-allocated slice_buf_ids - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_buf_ids_alloc; - - /** - * Pointer to VASliceParameterBuffers - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - void *slice_params; - - /** - * Size of a VASliceParameterBuffer element - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_param_size; - - /** - * Size of pre-allocated slice_params - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_params_alloc; - - /** - * Number of slices currently filled in - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - unsigned int slice_count; - - /** - * Pointer to slice data buffer base - * - encoding: unused - * - decoding: Set by libavcodec - */ - const uint8_t *slice_data; - - /** - * Current size of slice data - * - * - encoding: unused - * - decoding: Set by libavcodec - */ - uint32_t slice_data_size; -}; - -/* @} */ - -#endif /* AVCODEC_VAAPI_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vaapi_h264.c b/tizen/distrib/ffmpeg/libavcodec/vaapi_h264.c deleted file mode 100644 index 6d4251a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vaapi_h264.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * H.264 HW decode acceleration through VA API - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "vaapi_internal.h" -#include "h264.h" - -/** @file - * This file implements the glue code between FFmpeg's and VA API's - * structures for H.264 decoding. - */ - -/** - * Initializes an empty VA API picture. - * - * VA API requires a fixed-size reference picture array. - */ -static void init_vaapi_pic(VAPictureH264 *va_pic) -{ - va_pic->picture_id = VA_INVALID_ID; - va_pic->flags = VA_PICTURE_H264_INVALID; - va_pic->TopFieldOrderCnt = 0; - va_pic->BottomFieldOrderCnt = 0; -} - -/** - * Translates an FFmpeg Picture into its VA API form. - * - * @param[out] va_pic A pointer to VA API's own picture struct - * @param[in] pic A pointer to the FFmpeg picture struct to convert - * @param[in] pic_structure The picture field type (as defined in mpegvideo.h), - * supersedes pic's field type if nonzero. - */ -static void fill_vaapi_pic(VAPictureH264 *va_pic, - Picture *pic, - int pic_structure) -{ - if (pic_structure == 0) - pic_structure = pic->reference; - - va_pic->picture_id = ff_vaapi_get_surface_id(pic); - va_pic->frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num; - - va_pic->flags = 0; - if (pic_structure != PICT_FRAME) - va_pic->flags |= (pic_structure & PICT_TOP_FIELD) ? VA_PICTURE_H264_TOP_FIELD : VA_PICTURE_H264_BOTTOM_FIELD; - if (pic->reference) - va_pic->flags |= pic->long_ref ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE; - - va_pic->TopFieldOrderCnt = 0; - if (pic->field_poc[0] != INT_MAX) - va_pic->TopFieldOrderCnt = pic->field_poc[0]; - - va_pic->BottomFieldOrderCnt = 0; - if (pic->field_poc[1] != INT_MAX) - va_pic->BottomFieldOrderCnt = pic->field_poc[1]; -} - -/** Decoded Picture Buffer (DPB). */ -typedef struct DPB { - int size; ///< Current number of reference frames in the DPB - int max_size; ///< Max number of reference frames. This is FF_ARRAY_ELEMS(VAPictureParameterBufferH264.ReferenceFrames) - VAPictureH264 *va_pics; ///< Pointer to VAPictureParameterBufferH264.ReferenceFrames array -} DPB; - -/** - * Appends picture to the decoded picture buffer, in a VA API form that - * merges the second field picture attributes with the first, if - * available. The decoded picture buffer's size must be large enough - * to receive the new VA API picture object. - */ -static int dpb_add(DPB *dpb, Picture *pic) -{ - int i; - - if (dpb->size >= dpb->max_size) - return -1; - - for (i = 0; i < dpb->size; i++) { - VAPictureH264 * const va_pic = &dpb->va_pics[i]; - if (va_pic->picture_id == ff_vaapi_get_surface_id(pic)) { - VAPictureH264 temp_va_pic; - fill_vaapi_pic(&temp_va_pic, pic, 0); - - if ((temp_va_pic.flags ^ va_pic->flags) & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) { - va_pic->flags |= temp_va_pic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD); - /* Merge second field */ - if (temp_va_pic.flags & VA_PICTURE_H264_TOP_FIELD) { - va_pic->TopFieldOrderCnt = temp_va_pic.TopFieldOrderCnt; - } else { - va_pic->BottomFieldOrderCnt = temp_va_pic.BottomFieldOrderCnt; - } - } - return 0; - } - } - - fill_vaapi_pic(&dpb->va_pics[dpb->size++], pic, 0); - return 0; -} - -/** Fills in VA API reference frames array. */ -static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param, - H264Context *h) -{ - DPB dpb; - int i; - - dpb.size = 0; - dpb.max_size = FF_ARRAY_ELEMS(pic_param->ReferenceFrames); - dpb.va_pics = pic_param->ReferenceFrames; - for (i = 0; i < dpb.max_size; i++) - init_vaapi_pic(&dpb.va_pics[i]); - - for (i = 0; i < h->short_ref_count; i++) { - Picture * const pic = h->short_ref[i]; - if (pic && pic->reference && dpb_add(&dpb, pic) < 0) - return -1; - } - - for (i = 0; i < 16; i++) { - Picture * const pic = h->long_ref[i]; - if (pic && pic->reference && dpb_add(&dpb, pic) < 0) - return -1; - } - return 0; -} - -/** - * Fills in VA API reference picture lists from the FFmpeg reference - * picture list. - * - * @param[out] RefPicList VA API internal reference picture list - * @param[in] ref_list A pointer to the FFmpeg reference list - * @param[in] ref_count The number of reference pictures in ref_list - */ -static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32], - Picture *ref_list, - unsigned int ref_count) -{ - unsigned int i, n = 0; - for (i = 0; i < ref_count; i++) - if (ref_list[i].reference) - fill_vaapi_pic(&RefPicList[n++], &ref_list[i], 0); - - for (; n < 32; n++) - init_vaapi_pic(&RefPicList[n]); -} - -/** - * Fills in prediction weight table. - * - * VA API requires a plain prediction weight table as it does not infer - * any value. - * - * @param[in] h A pointer to the current H.264 context - * @param[in] list The reference frame list index to use - * @param[out] luma_weight_flag VA API plain luma weight flag - * @param[out] luma_weight VA API plain luma weight table - * @param[out] luma_offset VA API plain luma offset table - * @param[out] chroma_weight_flag VA API plain chroma weight flag - * @param[out] chroma_weight VA API plain chroma weight table - * @param[out] chroma_offset VA API plain chroma offset table - */ -static void fill_vaapi_plain_pred_weight_table(H264Context *h, - int list, - unsigned char *luma_weight_flag, - short luma_weight[32], - short luma_offset[32], - unsigned char *chroma_weight_flag, - short chroma_weight[32][2], - short chroma_offset[32][2]) -{ - unsigned int i, j; - - *luma_weight_flag = h->luma_weight_flag[list]; - *chroma_weight_flag = h->chroma_weight_flag[list]; - - for (i = 0; i < h->ref_count[list]; i++) { - /* VA API also wants the inferred (default) values, not - only what is available in the bitstream (7.4.3.2). */ - if (h->luma_weight_flag[list]) { - luma_weight[i] = h->luma_weight[i][list][0]; - luma_offset[i] = h->luma_weight[i][list][1]; - } else { - luma_weight[i] = 1 << h->luma_log2_weight_denom; - luma_offset[i] = 0; - } - for (j = 0; j < 2; j++) { - if (h->chroma_weight_flag[list]) { - chroma_weight[i][j] = h->chroma_weight[i][list][j][0]; - chroma_offset[i][j] = h->chroma_weight[i][list][j][1]; - } else { - chroma_weight[i][j] = 1 << h->chroma_log2_weight_denom; - chroma_offset[i][j] = 0; - } - } - } -} - -/** Initializes and starts decoding a frame with VA API. */ -static int start_frame(AVCodecContext *avctx, - av_unused const uint8_t *buffer, - av_unused uint32_t size) -{ - H264Context * const h = avctx->priv_data; - MpegEncContext * const s = &h->s; - struct vaapi_context * const vactx = avctx->hwaccel_context; - VAPictureParameterBufferH264 *pic_param; - VAIQMatrixBufferH264 *iq_matrix; - - dprintf(avctx, "start_frame()\n"); - - vactx->slice_param_size = sizeof(VASliceParameterBufferH264); - - /* Fill in VAPictureParameterBufferH264. */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferH264)); - if (!pic_param) - return -1; - fill_vaapi_pic(&pic_param->CurrPic, s->current_picture_ptr, s->picture_structure); - if (fill_vaapi_ReferenceFrames(pic_param, h) < 0) - return -1; - pic_param->picture_width_in_mbs_minus1 = s->mb_width - 1; - pic_param->picture_height_in_mbs_minus1 = s->mb_height - 1; - pic_param->bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8; - pic_param->bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; - pic_param->num_ref_frames = h->sps.ref_frame_count; - pic_param->seq_fields.value = 0; /* reset all bits */ - pic_param->seq_fields.bits.chroma_format_idc = h->sps.chroma_format_idc; - pic_param->seq_fields.bits.residual_colour_transform_flag = h->sps.residual_color_transform_flag; /* XXX: only for 4:4:4 high profile? */ - pic_param->seq_fields.bits.gaps_in_frame_num_value_allowed_flag = h->sps.gaps_in_frame_num_allowed_flag; - pic_param->seq_fields.bits.frame_mbs_only_flag = h->sps.frame_mbs_only_flag; - pic_param->seq_fields.bits.mb_adaptive_frame_field_flag = h->sps.mb_aff; - pic_param->seq_fields.bits.direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag; - pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = h->sps.level_idc >= 31; /* A.3.3.2 */ - pic_param->seq_fields.bits.log2_max_frame_num_minus4 = h->sps.log2_max_frame_num - 4; - pic_param->seq_fields.bits.pic_order_cnt_type = h->sps.poc_type; - pic_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4; - pic_param->seq_fields.bits.delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag; - pic_param->num_slice_groups_minus1 = h->pps.slice_group_count - 1; - pic_param->slice_group_map_type = h->pps.mb_slice_group_map_type; - pic_param->slice_group_change_rate_minus1 = 0; /* XXX: unimplemented in FFmpeg */ - pic_param->pic_init_qp_minus26 = h->pps.init_qp - 26; - pic_param->pic_init_qs_minus26 = h->pps.init_qs - 26; - pic_param->chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0]; - pic_param->second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1]; - pic_param->pic_fields.value = 0; /* reset all bits */ - pic_param->pic_fields.bits.entropy_coding_mode_flag = h->pps.cabac; - pic_param->pic_fields.bits.weighted_pred_flag = h->pps.weighted_pred; - pic_param->pic_fields.bits.weighted_bipred_idc = h->pps.weighted_bipred_idc; - pic_param->pic_fields.bits.transform_8x8_mode_flag = h->pps.transform_8x8_mode; - pic_param->pic_fields.bits.field_pic_flag = s->picture_structure != PICT_FRAME; - pic_param->pic_fields.bits.constrained_intra_pred_flag = h->pps.constrained_intra_pred; - pic_param->pic_fields.bits.pic_order_present_flag = h->pps.pic_order_present; - pic_param->pic_fields.bits.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; - pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = h->pps.redundant_pic_cnt_present; - pic_param->pic_fields.bits.reference_pic_flag = h->nal_ref_idc != 0; - pic_param->frame_num = h->frame_num; - - /* Fill in VAIQMatrixBufferH264. */ - iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferH264)); - if (!iq_matrix) - return -1; - memcpy(iq_matrix->ScalingList4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->ScalingList4x4)); - memcpy(iq_matrix->ScalingList8x8, h->pps.scaling_matrix8, sizeof(iq_matrix->ScalingList8x8)); - return 0; -} - -/** Ends a hardware decoding based frame. */ -static int end_frame(AVCodecContext *avctx) -{ - H264Context * const h = avctx->priv_data; - - dprintf(avctx, "end_frame()\n"); - return ff_vaapi_common_end_frame(&h->s); -} - -/** Decodes the given H.264 slice with VA API. */ -static int decode_slice(AVCodecContext *avctx, - const uint8_t *buffer, - uint32_t size) -{ - H264Context * const h = avctx->priv_data; - MpegEncContext * const s = &h->s; - VASliceParameterBufferH264 *slice_param; - - dprintf(avctx, "decode_slice(): buffer %p, size %d\n", buffer, size); - - /* Fill in VASliceParameterBufferH264. */ - slice_param = (VASliceParameterBufferH264 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->slice_data_bit_offset = get_bits_count(&h->s.gb) + 8; /* bit buffer started beyond nal_unit_type */ - slice_param->first_mb_in_slice = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x; - slice_param->slice_type = ff_h264_get_slice_type(h); - slice_param->direct_spatial_mv_pred_flag = h->slice_type == FF_B_TYPE ? h->direct_spatial_mv_pred : 0; - slice_param->num_ref_idx_l0_active_minus1 = h->list_count > 0 ? h->ref_count[0] - 1 : 0; - slice_param->num_ref_idx_l1_active_minus1 = h->list_count > 1 ? h->ref_count[1] - 1 : 0; - slice_param->cabac_init_idc = h->cabac_init_idc; - slice_param->slice_qp_delta = s->qscale - h->pps.init_qp; - slice_param->disable_deblocking_filter_idc = h->deblocking_filter < 2 ? !h->deblocking_filter : h->deblocking_filter; - slice_param->slice_alpha_c0_offset_div2 = h->slice_alpha_c0_offset / 2 - 26; - slice_param->slice_beta_offset_div2 = h->slice_beta_offset / 2 - 26; - slice_param->luma_log2_weight_denom = h->luma_log2_weight_denom; - slice_param->chroma_log2_weight_denom = h->chroma_log2_weight_denom; - - fill_vaapi_RefPicList(slice_param->RefPicList0, h->ref_list[0], h->list_count > 0 ? h->ref_count[0] : 0); - fill_vaapi_RefPicList(slice_param->RefPicList1, h->ref_list[1], h->list_count > 1 ? h->ref_count[1] : 0); - - fill_vaapi_plain_pred_weight_table(h, 0, - &slice_param->luma_weight_l0_flag, slice_param->luma_weight_l0, slice_param->luma_offset_l0, - &slice_param->chroma_weight_l0_flag, slice_param->chroma_weight_l0, slice_param->chroma_offset_l0); - fill_vaapi_plain_pred_weight_table(h, 1, - &slice_param->luma_weight_l1_flag, slice_param->luma_weight_l1, slice_param->luma_offset_l1, - &slice_param->chroma_weight_l1_flag, slice_param->chroma_weight_l1, slice_param->chroma_offset_l1); - return 0; -} - -AVHWAccel h264_vaapi_hwaccel = { - .name = "h264_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_H264, - .pix_fmt = PIX_FMT_VAAPI_VLD, - .capabilities = 0, - .start_frame = start_frame, - .end_frame = end_frame, - .decode_slice = decode_slice, - .priv_data_size = 0, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vaapi_internal.h b/tizen/distrib/ffmpeg/libavcodec/vaapi_internal.h deleted file mode 100644 index 2c0fdf9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vaapi_internal.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Video Acceleration API (video decoding) - * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VAAPI_INTERNAL_H -#define AVCODEC_VAAPI_INTERNAL_H - -#include -#include "vaapi.h" -#include "avcodec.h" -#include "mpegvideo.h" - -/** - * \addtogroup VAAPI_Decoding - * - * @{ - */ - -/** Extract VASurfaceID from a Picture */ -static inline VASurfaceID ff_vaapi_get_surface_id(Picture *pic) -{ - return (uintptr_t)pic->data[3]; -} - -/** Common AVHWAccel.end_frame() implementation */ -int ff_vaapi_common_end_frame(MpegEncContext *s); - -/** Allocate a new picture parameter buffer */ -void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size); - -/** Allocate a new IQ matrix buffer */ -void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size); - -/** Allocate a new bit-plane buffer */ -uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size); - -/** - * Allocate a new slice descriptor for the input slice. - * - * @param vactx the VA API context - * @param buffer the slice data buffer base - * @param size the size of the slice in bytes - * @return the newly allocated slice parameter - */ -VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size); - -/* @} */ - -#endif /* AVCODEC_VAAPI_INTERNAL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg2.c b/tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg2.c deleted file mode 100644 index 2e870dc..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg2.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * MPEG-2 HW decode acceleration through VA API - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "vaapi_internal.h" -#include "dsputil.h" - -/** Reconstruct bitstream f_code */ -static inline int mpeg2_get_f_code(MpegEncContext *s) -{ - return ((s->mpeg_f_code[0][0] << 12) | (s->mpeg_f_code[0][1] << 8) | - (s->mpeg_f_code[1][0] << 4) | s->mpeg_f_code[1][1]); -} - -/** Determine frame start: first field for field picture or frame picture */ -static inline int mpeg2_get_is_frame_start(MpegEncContext *s) -{ - return s->first_field || s->picture_structure == PICT_FRAME; -} - -static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) -{ - struct MpegEncContext * const s = avctx->priv_data; - struct vaapi_context * const vactx = avctx->hwaccel_context; - VAPictureParameterBufferMPEG2 *pic_param; - VAIQMatrixBufferMPEG2 *iq_matrix; - int i; - - dprintf(avctx, "vaapi_mpeg2_start_frame()\n"); - - vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG2); - - /* Fill in VAPictureParameterBufferMPEG2 */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG2)); - if (!pic_param) - return -1; - pic_param->horizontal_size = s->width; - pic_param->vertical_size = s->height; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->picture_coding_type = s->pict_type; - pic_param->f_code = mpeg2_get_f_code(s); - pic_param->picture_coding_extension.value = 0; /* reset all bits */ - pic_param->picture_coding_extension.bits.intra_dc_precision = s->intra_dc_precision; - pic_param->picture_coding_extension.bits.picture_structure = s->picture_structure; - pic_param->picture_coding_extension.bits.top_field_first = s->top_field_first; - pic_param->picture_coding_extension.bits.frame_pred_frame_dct = s->frame_pred_frame_dct; - pic_param->picture_coding_extension.bits.concealment_motion_vectors = s->concealment_motion_vectors; - pic_param->picture_coding_extension.bits.q_scale_type = s->q_scale_type; - pic_param->picture_coding_extension.bits.intra_vlc_format = s->intra_vlc_format; - pic_param->picture_coding_extension.bits.alternate_scan = s->alternate_scan; - pic_param->picture_coding_extension.bits.repeat_first_field = s->repeat_first_field; - pic_param->picture_coding_extension.bits.progressive_frame = s->progressive_frame; - pic_param->picture_coding_extension.bits.is_first_field = mpeg2_get_is_frame_start(s); - - switch (s->pict_type) { - case FF_B_TYPE: - pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture); - // fall-through - case FF_P_TYPE: - pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture); - break; - } - - /* Fill in VAIQMatrixBufferMPEG2 */ - iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG2)); - if (!iq_matrix) - return -1; - iq_matrix->load_intra_quantiser_matrix = 1; - iq_matrix->load_non_intra_quantiser_matrix = 1; - iq_matrix->load_chroma_intra_quantiser_matrix = 1; - iq_matrix->load_chroma_non_intra_quantiser_matrix = 1; - - for (i = 0; i < 64; i++) { - int n = s->dsp.idct_permutation[ff_zigzag_direct[i]]; - iq_matrix->intra_quantiser_matrix[i] = s->intra_matrix[n]; - iq_matrix->non_intra_quantiser_matrix[i] = s->inter_matrix[n]; - iq_matrix->chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n]; - iq_matrix->chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n]; - } - return 0; -} - -static int vaapi_mpeg2_end_frame(AVCodecContext *avctx) -{ - return ff_vaapi_common_end_frame(avctx->priv_data); -} - -static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) -{ - MpegEncContext * const s = avctx->priv_data; - VASliceParameterBufferMPEG2 *slice_param; - GetBitContext gb; - uint32_t start_code, quantiser_scale_code, intra_slice_flag, macroblock_offset; - - dprintf(avctx, "vaapi_mpeg2_decode_slice(): buffer %p, size %d\n", buffer, size); - - /* Determine macroblock_offset */ - init_get_bits(&gb, buffer, 8 * size); - start_code = get_bits(&gb, 32); - assert((start_code & 0xffffff00) == 0x00000100); - quantiser_scale_code = get_bits(&gb, 5); - intra_slice_flag = get_bits1(&gb); - if (intra_slice_flag) { - skip_bits(&gb, 8); - while (get_bits1(&gb) != 0) - skip_bits(&gb, 8); - } - macroblock_offset = get_bits_count(&gb); - - /* Fill in VASliceParameterBufferMPEG2 */ - slice_param = (VASliceParameterBufferMPEG2 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->macroblock_offset = macroblock_offset; - slice_param->slice_horizontal_position = s->mb_x; - slice_param->slice_vertical_position = s->mb_y; - slice_param->quantiser_scale_code = quantiser_scale_code; - slice_param->intra_slice_flag = intra_slice_flag; - return 0; -} - -AVHWAccel mpeg2_vaapi_hwaccel = { - .name = "mpeg2_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_MPEG2VIDEO, - .pix_fmt = PIX_FMT_VAAPI_VLD, - .capabilities = 0, - .start_frame = vaapi_mpeg2_start_frame, - .end_frame = vaapi_mpeg2_end_frame, - .decode_slice = vaapi_mpeg2_decode_slice, - .priv_data_size = 0, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg4.c b/tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg4.c deleted file mode 100644 index 466ce2f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vaapi_mpeg4.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * MPEG-4 / H.263 HW decode acceleration through VA API - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "vaapi_internal.h" - -/** Reconstruct bitstream intra_dc_vlc_thr */ -static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s) -{ - switch (s->intra_dc_threshold) { - case 99: return 0; - case 13: return 1; - case 15: return 2; - case 17: return 3; - case 19: return 4; - case 21: return 5; - case 23: return 6; - case 0: return 7; - } - return 0; -} - -static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) -{ - MpegEncContext * const s = avctx->priv_data; - struct vaapi_context * const vactx = avctx->hwaccel_context; - VAPictureParameterBufferMPEG4 *pic_param; - VAIQMatrixBufferMPEG4 *iq_matrix; - int i; - - dprintf(avctx, "vaapi_mpeg4_start_frame()\n"); - - vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG4); - - /* Fill in VAPictureParameterBufferMPEG4 */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferMPEG4)); - if (!pic_param) - return -1; - pic_param->vop_width = s->width; - pic_param->vop_height = s->height; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->vol_fields.value = 0; /* reset all bits */ - pic_param->vol_fields.bits.short_video_header = avctx->codec->id == CODEC_ID_H263; - pic_param->vol_fields.bits.chroma_format = CHROMA_420; - pic_param->vol_fields.bits.interlaced = !s->progressive_sequence; - pic_param->vol_fields.bits.obmc_disable = 1; - pic_param->vol_fields.bits.sprite_enable = s->vol_sprite_usage; - pic_param->vol_fields.bits.sprite_warping_accuracy = s->sprite_warping_accuracy; - pic_param->vol_fields.bits.quant_type = s->mpeg_quant; - pic_param->vol_fields.bits.quarter_sample = s->quarter_sample; - pic_param->vol_fields.bits.data_partitioned = s->data_partitioning; - pic_param->vol_fields.bits.reversible_vlc = s->rvlc; - pic_param->vol_fields.bits.resync_marker_disable = !s->resync_marker; - pic_param->no_of_sprite_warping_points = s->num_sprite_warping_points; - for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) { - pic_param->sprite_trajectory_du[i] = s->sprite_traj[i][0]; - pic_param->sprite_trajectory_dv[i] = s->sprite_traj[i][1]; - } - pic_param->quant_precision = s->quant_precision; - pic_param->vop_fields.value = 0; /* reset all bits */ - pic_param->vop_fields.bits.vop_coding_type = s->pict_type - FF_I_TYPE; - pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == FF_B_TYPE ? s->next_picture.pict_type - FF_I_TYPE : 0; - pic_param->vop_fields.bits.vop_rounding_type = s->no_rounding; - pic_param->vop_fields.bits.intra_dc_vlc_thr = mpeg4_get_intra_dc_vlc_thr(s); - pic_param->vop_fields.bits.top_field_first = s->top_field_first; - pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan; - pic_param->vop_fcode_forward = s->f_code; - pic_param->vop_fcode_backward = s->b_code; - pic_param->vop_time_increment_resolution = avctx->time_base.den; - pic_param->num_macroblocks_in_gob = s->mb_width * ff_h263_get_gob_height(s); - pic_param->num_gobs_in_vop = (s->mb_width * s->mb_height) / pic_param->num_macroblocks_in_gob; - pic_param->TRB = s->pb_time; - pic_param->TRD = s->pp_time; - - if (s->pict_type == FF_B_TYPE) - pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture); - if (s->pict_type != FF_I_TYPE) - pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture); - - /* Fill in VAIQMatrixBufferMPEG4 */ - /* Only the first inverse quantisation method uses the weighthing matrices */ - if (pic_param->vol_fields.bits.quant_type) { - iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG4)); - if (!iq_matrix) - return -1; - iq_matrix->load_intra_quant_mat = 1; - iq_matrix->load_non_intra_quant_mat = 1; - - for (i = 0; i < 64; i++) { - int n = s->dsp.idct_permutation[ff_zigzag_direct[i]]; - iq_matrix->intra_quant_mat[i] = s->intra_matrix[n]; - iq_matrix->non_intra_quant_mat[i] = s->inter_matrix[n]; - } - } - return 0; -} - -static int vaapi_mpeg4_end_frame(AVCodecContext *avctx) -{ - return ff_vaapi_common_end_frame(avctx->priv_data); -} - -static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) -{ - MpegEncContext * const s = avctx->priv_data; - VASliceParameterBufferMPEG4 *slice_param; - - dprintf(avctx, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer, size); - - /* video_plane_with_short_video_header() contains all GOBs - * in-order, and this is what VA API (Intel backend) expects: only - * a single slice param. So fake macroblock_number for FFmpeg so - * that we don't call vaapi_mpeg4_decode_slice() again - */ - if (avctx->codec->id == CODEC_ID_H263) - size = s->gb.buffer_end - buffer; - - /* Fill in VASliceParameterBufferMPEG4 */ - slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->macroblock_offset = get_bits_count(&s->gb) % 8; - slice_param->macroblock_number = s->mb_y * s->mb_width + s->mb_x; - slice_param->quant_scale = s->qscale; - - if (avctx->codec->id == CODEC_ID_H263) - s->mb_y = s->mb_height; - - return 0; -} - -#if CONFIG_MPEG4_VAAPI_HWACCEL -AVHWAccel mpeg4_vaapi_hwaccel = { - .name = "mpeg4_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_MPEG4, - .pix_fmt = PIX_FMT_VAAPI_VLD, - .capabilities = 0, - .start_frame = vaapi_mpeg4_start_frame, - .end_frame = vaapi_mpeg4_end_frame, - .decode_slice = vaapi_mpeg4_decode_slice, - .priv_data_size = 0, -}; -#endif - -#if CONFIG_H263_VAAPI_HWACCEL -AVHWAccel h263_vaapi_hwaccel = { - .name = "h263_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_H263, - .pix_fmt = PIX_FMT_VAAPI_VLD, - .capabilities = 0, - .start_frame = vaapi_mpeg4_start_frame, - .end_frame = vaapi_mpeg4_end_frame, - .decode_slice = vaapi_mpeg4_decode_slice, - .priv_data_size = 0, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/vaapi_vc1.c b/tizen/distrib/ffmpeg/libavcodec/vaapi_vc1.c deleted file mode 100644 index 992e1da..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vaapi_vc1.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * VC-1 HW decode acceleration through VA API - * - * Copyright (C) 2008-2009 Splitted-Desktop Systems - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "vaapi_internal.h" -#include "vc1.h" -#include "vc1data.h" - -/** Translates FFmpeg MV modes to VA API */ -static int get_VAMvModeVC1(enum MVModes mv_mode) -{ - switch (mv_mode) { - case MV_PMODE_1MV_HPEL_BILIN: return VAMvMode1MvHalfPelBilinear; - case MV_PMODE_1MV: return VAMvMode1Mv; - case MV_PMODE_1MV_HPEL: return VAMvMode1MvHalfPel; - case MV_PMODE_MIXED_MV: return VAMvModeMixedMv; - case MV_PMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation; - } - return 0; -} - -/** Checks whether the MVTYPEMB bitplane is present */ -static inline int vc1_has_MVTYPEMB_bitplane(VC1Context *v) -{ - if (v->mv_type_is_raw) - return 0; - return (v->s.pict_type == FF_P_TYPE && - (v->mv_mode == MV_PMODE_MIXED_MV || - (v->mv_mode == MV_PMODE_INTENSITY_COMP && - v->mv_mode2 == MV_PMODE_MIXED_MV))); -} - -/** Checks whether the SKIPMB bitplane is present */ -static inline int vc1_has_SKIPMB_bitplane(VC1Context *v) -{ - if (v->skip_is_raw) - return 0; - return (v->s.pict_type == FF_P_TYPE || - (v->s.pict_type == FF_B_TYPE && !v->bi_type)); -} - -/** Checks whether the DIRECTMB bitplane is present */ -static inline int vc1_has_DIRECTMB_bitplane(VC1Context *v) -{ - if (v->dmb_is_raw) - return 0; - return v->s.pict_type == FF_B_TYPE && !v->bi_type; -} - -/** Checks whether the ACPRED bitplane is present */ -static inline int vc1_has_ACPRED_bitplane(VC1Context *v) -{ - if (v->acpred_is_raw) - return 0; - return (v->profile == PROFILE_ADVANCED && - (v->s.pict_type == FF_I_TYPE || - (v->s.pict_type == FF_B_TYPE && v->bi_type))); -} - -/** Check whether the OVERFLAGS bitplane is present */ -static inline int vc1_has_OVERFLAGS_bitplane(VC1Context *v) -{ - if (v->overflg_is_raw) - return 0; - return (v->profile == PROFILE_ADVANCED && - (v->s.pict_type == FF_I_TYPE || - (v->s.pict_type == FF_B_TYPE && v->bi_type)) && - (v->overlap && v->pq <= 8) && - v->condover == CONDOVER_SELECT); -} - -/** Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */ -static int vc1_get_PTYPE(VC1Context *v) -{ - MpegEncContext * const s = &v->s; - switch (s->pict_type) { - case FF_I_TYPE: return 0; - case FF_P_TYPE: return v->p_frame_skipped ? 4 : 1; - case FF_B_TYPE: return v->bi_type ? 3 : 2; - } - return 0; -} - -/** Reconstruct bitstream MVMODE (7.1.1.32) */ -static inline VAMvModeVC1 vc1_get_MVMODE(VC1Context *v) -{ - if (v->s.pict_type == FF_P_TYPE || - (v->s.pict_type == FF_B_TYPE && !v->bi_type)) - return get_VAMvModeVC1(v->mv_mode); - return 0; -} - -/** Reconstruct bitstream MVMODE2 (7.1.1.33) */ -static inline VAMvModeVC1 vc1_get_MVMODE2(VC1Context *v) -{ - if (v->s.pict_type == FF_P_TYPE && v->mv_mode == MV_PMODE_INTENSITY_COMP) - return get_VAMvModeVC1(v->mv_mode2); - return 0; -} - -/** Pack FFmpeg bitplanes into a VABitPlaneBuffer element */ -static inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *ff_bp[3], int x, int y, int stride) -{ - const int bitplane_index = n / 2; - const int ff_bp_index = y * stride + x; - uint8_t v = 0; - if (ff_bp[0]) - v = ff_bp[0][ff_bp_index]; - if (ff_bp[1]) - v |= ff_bp[1][ff_bp_index] << 1; - if (ff_bp[2]) - v |= ff_bp[2][ff_bp_index] << 2; - bitplane[bitplane_index] = (bitplane[bitplane_index] << 4) | v; -} - -static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) -{ - VC1Context * const v = avctx->priv_data; - MpegEncContext * const s = &v->s; - struct vaapi_context * const vactx = avctx->hwaccel_context; - VAPictureParameterBufferVC1 *pic_param; - - dprintf(avctx, "vaapi_vc1_start_frame()\n"); - - vactx->slice_param_size = sizeof(VASliceParameterBufferVC1); - - /* Fill in VAPictureParameterBufferVC1 */ - pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferVC1)); - if (!pic_param) - return -1; - pic_param->forward_reference_picture = VA_INVALID_ID; - pic_param->backward_reference_picture = VA_INVALID_ID; - pic_param->inloop_decoded_picture = VA_INVALID_ID; - pic_param->sequence_fields.value = 0; /* reset all bits */ - pic_param->sequence_fields.bits.pulldown = v->broadcast; - pic_param->sequence_fields.bits.interlace = v->interlace; - pic_param->sequence_fields.bits.tfcntrflag = v->tfcntrflag; - pic_param->sequence_fields.bits.finterpflag = v->finterpflag; - pic_param->sequence_fields.bits.psf = v->psf; - pic_param->sequence_fields.bits.multires = v->multires; - pic_param->sequence_fields.bits.overlap = v->overlap; - pic_param->sequence_fields.bits.syncmarker = s->resync_marker; - pic_param->sequence_fields.bits.rangered = v->rangered; - pic_param->sequence_fields.bits.max_b_frames = s->avctx->max_b_frames; - pic_param->coded_width = s->avctx->coded_width; - pic_param->coded_height = s->avctx->coded_height; - pic_param->entrypoint_fields.value = 0; /* reset all bits */ - pic_param->entrypoint_fields.bits.broken_link = v->broken_link; - pic_param->entrypoint_fields.bits.closed_entry = v->closed_entry; - pic_param->entrypoint_fields.bits.panscan_flag = v->panscanflag; - pic_param->entrypoint_fields.bits.loopfilter = s->loop_filter; - pic_param->conditional_overlap_flag = v->condover; - pic_param->fast_uvmc_flag = v->fastuvmc; - pic_param->range_mapping_fields.value = 0; /* reset all bits */ - pic_param->range_mapping_fields.bits.luma_flag = v->range_mapy_flag; - pic_param->range_mapping_fields.bits.luma = v->range_mapy; - pic_param->range_mapping_fields.bits.chroma_flag = v->range_mapuv_flag; - pic_param->range_mapping_fields.bits.chroma = v->range_mapuv; - pic_param->b_picture_fraction = v->bfraction_lut_index; - pic_param->cbp_table = v->cbpcy_vlc ? v->cbpcy_vlc - ff_vc1_cbpcy_p_vlc : 0; - pic_param->mb_mode_table = 0; /* XXX: interlaced frame */ - pic_param->range_reduction_frame = v->rangeredfrm; - pic_param->rounding_control = v->rnd; - pic_param->post_processing = v->postproc; - pic_param->picture_resolution_index = v->respic; - pic_param->luma_scale = v->lumscale; - pic_param->luma_shift = v->lumshift; - pic_param->picture_fields.value = 0; /* reset all bits */ - pic_param->picture_fields.bits.picture_type = vc1_get_PTYPE(v); - pic_param->picture_fields.bits.frame_coding_mode = v->fcm; - pic_param->picture_fields.bits.top_field_first = v->tff; - pic_param->picture_fields.bits.is_first_field = v->fcm == 0; /* XXX: interlaced frame */ - pic_param->picture_fields.bits.intensity_compensation = v->mv_mode == MV_PMODE_INTENSITY_COMP; - pic_param->raw_coding.value = 0; /* reset all bits */ - pic_param->raw_coding.flags.mv_type_mb = v->mv_type_is_raw; - pic_param->raw_coding.flags.direct_mb = v->dmb_is_raw; - pic_param->raw_coding.flags.skip_mb = v->skip_is_raw; - pic_param->raw_coding.flags.field_tx = 0; /* XXX: interlaced frame */ - pic_param->raw_coding.flags.forward_mb = 0; /* XXX: interlaced frame */ - pic_param->raw_coding.flags.ac_pred = v->acpred_is_raw; - pic_param->raw_coding.flags.overflags = v->overflg_is_raw; - pic_param->bitplane_present.value = 0; /* reset all bits */ - pic_param->bitplane_present.flags.bp_mv_type_mb = vc1_has_MVTYPEMB_bitplane(v); - pic_param->bitplane_present.flags.bp_direct_mb = vc1_has_DIRECTMB_bitplane(v); - pic_param->bitplane_present.flags.bp_skip_mb = vc1_has_SKIPMB_bitplane(v); - pic_param->bitplane_present.flags.bp_field_tx = 0; /* XXX: interlaced frame */ - pic_param->bitplane_present.flags.bp_forward_mb = 0; /* XXX: interlaced frame */ - pic_param->bitplane_present.flags.bp_ac_pred = vc1_has_ACPRED_bitplane(v); - pic_param->bitplane_present.flags.bp_overflags = vc1_has_OVERFLAGS_bitplane(v); - pic_param->reference_fields.value = 0; /* reset all bits */ - pic_param->reference_fields.bits.reference_distance_flag = v->refdist_flag; - pic_param->reference_fields.bits.reference_distance = 0; /* XXX: interlaced frame */ - pic_param->reference_fields.bits.num_reference_pictures = 0; /* XXX: interlaced frame */ - pic_param->reference_fields.bits.reference_field_pic_indicator = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.value = 0; /* reset all bits */ - pic_param->mv_fields.bits.mv_mode = vc1_get_MVMODE(v); - pic_param->mv_fields.bits.mv_mode2 = vc1_get_MVMODE2(v); - pic_param->mv_fields.bits.mv_table = s->mv_table_index; - pic_param->mv_fields.bits.two_mv_block_pattern_table = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.bits.four_mv_switch = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.bits.four_mv_block_pattern_table = 0; /* XXX: interlaced frame */ - pic_param->mv_fields.bits.extended_mv_flag = v->extended_mv; - pic_param->mv_fields.bits.extended_mv_range = v->mvrange; - pic_param->mv_fields.bits.extended_dmv_flag = v->extended_dmv; - pic_param->mv_fields.bits.extended_dmv_range = 0; /* XXX: interlaced frame */ - pic_param->pic_quantizer_fields.value = 0; /* reset all bits */ - pic_param->pic_quantizer_fields.bits.dquant = v->dquant; - pic_param->pic_quantizer_fields.bits.quantizer = v->quantizer_mode; - pic_param->pic_quantizer_fields.bits.half_qp = v->halfpq; - pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = v->pq; - pic_param->pic_quantizer_fields.bits.pic_quantizer_type = v->pquantizer; - pic_param->pic_quantizer_fields.bits.dq_frame = v->dquantfrm; - pic_param->pic_quantizer_fields.bits.dq_profile = v->dqprofile; - pic_param->pic_quantizer_fields.bits.dq_sb_edge = v->dqprofile == DQPROFILE_SINGLE_EDGE ? v->dqsbedge : 0; - pic_param->pic_quantizer_fields.bits.dq_db_edge = v->dqprofile == DQPROFILE_DOUBLE_EDGES ? v->dqsbedge : 0; - pic_param->pic_quantizer_fields.bits.dq_binary_level = v->dqbilevel; - pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = v->altpq; - pic_param->transform_fields.value = 0; /* reset all bits */ - pic_param->transform_fields.bits.variable_sized_transform_flag = v->vstransform; - pic_param->transform_fields.bits.mb_level_transform_type_flag = v->ttmbf; - pic_param->transform_fields.bits.frame_level_transform_type = v->ttfrm; - pic_param->transform_fields.bits.transform_ac_codingset_idx1 = v->c_ac_table_index; - pic_param->transform_fields.bits.transform_ac_codingset_idx2 = v->y_ac_table_index; - pic_param->transform_fields.bits.intra_transform_dc_table = v->s.dc_table_index; - - switch (s->pict_type) { - case FF_B_TYPE: - pic_param->backward_reference_picture = ff_vaapi_get_surface_id(&s->next_picture); - // fall-through - case FF_P_TYPE: - pic_param->forward_reference_picture = ff_vaapi_get_surface_id(&s->last_picture); - break; - } - - if (pic_param->bitplane_present.value) { - uint8_t *bitplane; - const uint8_t *ff_bp[3]; - int x, y, n; - - switch (s->pict_type) { - case FF_P_TYPE: - ff_bp[0] = pic_param->bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; - ff_bp[1] = pic_param->bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; - ff_bp[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? v->mv_type_mb_plane : NULL; - break; - case FF_B_TYPE: - if (!v->bi_type) { - ff_bp[0] = pic_param->bitplane_present.flags.bp_direct_mb ? v->direct_mb_plane : NULL; - ff_bp[1] = pic_param->bitplane_present.flags.bp_skip_mb ? s->mbskip_table : NULL; - ff_bp[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */ - break; - } - /* fall-through (BI-type) */ - case FF_I_TYPE: - ff_bp[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */ - ff_bp[1] = pic_param->bitplane_present.flags.bp_ac_pred ? v->acpred_plane : NULL; - ff_bp[2] = pic_param->bitplane_present.flags.bp_overflags ? v->over_flags_plane : NULL; - break; - default: - ff_bp[0] = NULL; - ff_bp[1] = NULL; - ff_bp[2] = NULL; - break; - } - - bitplane = ff_vaapi_alloc_bitplane(vactx, (s->mb_width * s->mb_height + 1) / 2); - if (!bitplane) - return -1; - - n = 0; - for (y = 0; y < s->mb_height; y++) - for (x = 0; x < s->mb_width; x++, n++) - vc1_pack_bitplanes(bitplane, n, ff_bp, x, y, s->mb_stride); - if (n & 1) /* move last nibble to the high order */ - bitplane[n/2] <<= 4; - } - return 0; -} - -static int vaapi_vc1_end_frame(AVCodecContext *avctx) -{ - VC1Context * const v = avctx->priv_data; - - return ff_vaapi_common_end_frame(&v->s); -} - -static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) -{ - VC1Context * const v = avctx->priv_data; - MpegEncContext * const s = &v->s; - VASliceParameterBufferVC1 *slice_param; - - dprintf(avctx, "vaapi_vc1_decode_slice(): buffer %p, size %d\n", buffer, size); - - /* Current bit buffer is beyond any marker for VC-1, so skip it */ - if (avctx->codec_id == CODEC_ID_VC1 && IS_MARKER(AV_RB32(buffer))) { - buffer += 4; - size -= 4; - } - - /* Fill in VASliceParameterBufferVC1 */ - slice_param = (VASliceParameterBufferVC1 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); - if (!slice_param) - return -1; - slice_param->macroblock_offset = get_bits_count(&s->gb); - slice_param->slice_vertical_position = s->mb_y; - return 0; -} - -#if CONFIG_WMV3_VAAPI_HWACCEL -AVHWAccel wmv3_vaapi_hwaccel = { - .name = "wmv3_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_WMV3, - .pix_fmt = PIX_FMT_VAAPI_VLD, - .capabilities = 0, - .start_frame = vaapi_vc1_start_frame, - .end_frame = vaapi_vc1_end_frame, - .decode_slice = vaapi_vc1_decode_slice, - .priv_data_size = 0, -}; -#endif - -AVHWAccel vc1_vaapi_hwaccel = { - .name = "vc1_vaapi", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_VC1, - .pix_fmt = PIX_FMT_VAAPI_VLD, - .capabilities = 0, - .start_frame = vaapi_vc1_start_frame, - .end_frame = vaapi_vc1_end_frame, - .decode_slice = vaapi_vc1_decode_slice, - .priv_data_size = 0, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vb.c b/tizen/distrib/ffmpeg/libavcodec/vb.c deleted file mode 100644 index 13c4b0a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vb.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Beam Software VB decoder - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VB Video decoder - */ - -#include -#include - -#include "avcodec.h" -#include "bytestream.h" - -enum VBFlags{ - VB_HAS_GMC = 0x01, - VB_HAS_AUDIO = 0x04, - VB_HAS_VIDEO = 0x08, - VB_HAS_PALETTE = 0x10, - VB_HAS_LENGTH = 0x20 -}; - -typedef struct VBDecContext { - AVCodecContext *avctx; - AVFrame pic; - - uint8_t *frame, *prev_frame; - uint32_t pal[AVPALETTE_COUNT]; - const uint8_t *stream; -} VBDecContext; - -static const uint16_t vb_patterns[64] = { - 0x0660, 0xFF00, 0xCCCC, 0xF000, 0x8888, 0x000F, 0x1111, 0xFEC8, - 0x8CEF, 0x137F, 0xF731, 0xC800, 0x008C, 0x0013, 0x3100, 0xCC00, - 0x00CC, 0x0033, 0x3300, 0x0FF0, 0x6666, 0x00F0, 0x0F00, 0x2222, - 0x4444, 0xF600, 0x8CC8, 0x006F, 0x1331, 0x318C, 0xC813, 0x33CC, - 0x6600, 0x0CC0, 0x0066, 0x0330, 0xF900, 0xC88C, 0x009F, 0x3113, - 0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC, - 0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63, - 0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C -}; - -static void vb_decode_palette(VBDecContext *c, int data_size) -{ - int start, size, i; - - start = bytestream_get_byte(&c->stream); - size = (bytestream_get_byte(&c->stream) - 1) & 0xFF; - if(start + size > 255){ - av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n"); - return; - } - if(size*3+2 > data_size){ - av_log(c->avctx, AV_LOG_ERROR, "Palette data runs beyond chunk size\n"); - return; - } - for(i = start; i <= start + size; i++) - c->pal[i] = bytestream_get_be24(&c->stream); -} - -static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end) -{ - return buf >= start && buf < end; -} - -static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end) -{ - return buf >= start && (buf + 4) <= end; -} - -static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int data_size, int offset) -{ - uint8_t *prev, *cur; - const uint8_t* data_end = buf + data_size; - int blk, blocks, t, blk2; - int blocktypes = 0; - int x, y, a, b; - int pattype, pattern; - const int width = c->avctx->width; - uint8_t *pstart = c->prev_frame; - uint8_t *pend = c->prev_frame + width*c->avctx->height; - - prev = c->prev_frame + offset; - cur = c->frame; - - blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2); - blk2 = 0; - for(blk = 0; blk < blocks; blk++){ - if(!(blk & 3)) { - if(buf >= data_end){ - av_log(c->avctx, AV_LOG_ERROR, "Data pointer out of bounds\n"); - return -1; - } - blocktypes = bytestream_get_byte(&buf); - } - switch(blocktypes & 0xC0){ - case 0x00: //skip - for(y = 0; y < 4; y++) - if(check_line(prev + y*width, pstart, pend)) - memcpy(cur + y*width, prev + y*width, 4); - else - memset(cur + y*width, 0, 4); - break; - case 0x40: - t = bytestream_get_byte(&buf); - if(!t){ //raw block - if(buf + 16 > data_end){ - av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n"); - return -1; - } - for(y = 0; y < 4; y++) - memcpy(cur + y*width, buf + y*4, 4); - buf += 16; - }else{ // motion compensation - x = ((t & 0xF)^8) - 8; - y = ((t >> 4) ^8) - 8; - t = x + y*width; - for(y = 0; y < 4; y++) - if(check_line(prev + t + y*width, pstart, pend)) - memcpy(cur + y*width, prev + t + y*width, 4); - else - memset(cur + y*width, 0, 4); - } - break; - case 0x80: // fill - t = bytestream_get_byte(&buf); - for(y = 0; y < 4; y++) - memset(cur + y*width, t, 4); - break; - case 0xC0: // pattern fill - if(buf + 2 > data_end){ - av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n"); - return -1; - } - t = bytestream_get_byte(&buf); - pattype = t >> 6; - pattern = vb_patterns[t & 0x3F]; - switch(pattype){ - case 0: - a = bytestream_get_byte(&buf); - b = bytestream_get_byte(&buf); - for(y = 0; y < 4; y++) - for(x = 0; x < 4; x++, pattern >>= 1) - cur[x + y*width] = (pattern & 1) ? b : a; - break; - case 1: - pattern = ~pattern; - case 2: - a = bytestream_get_byte(&buf); - for(y = 0; y < 4; y++) - for(x = 0; x < 4; x++, pattern >>= 1) - if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend)) - cur[x + y*width] = prev[x + y*width]; - else - cur[x + y*width] = a; - break; - case 3: - av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n",blk); - return -1; - } - break; - } - blocktypes <<= 2; - cur += 4; - prev += 4; - blk2++; - if(blk2 == (width >> 2)){ - blk2 = 0; - cur += width * 3; - prev += width * 3; - } - } - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VBDecContext * const c = avctx->priv_data; - uint8_t *outptr, *srcptr; - int i, j; - int flags; - uint32_t size; - int rest = buf_size; - int offset = 0; - - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; - if(avctx->get_buffer(avctx, &c->pic) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - c->stream = buf; - flags = bytestream_get_le16(&c->stream); - rest -= 2; - - if(flags & VB_HAS_GMC){ - i = (int16_t)bytestream_get_le16(&c->stream); - j = (int16_t)bytestream_get_le16(&c->stream); - offset = i + j * avctx->width; - rest -= 4; - } - if(flags & VB_HAS_VIDEO){ - size = bytestream_get_le32(&c->stream); - if(size > rest){ - av_log(avctx, AV_LOG_ERROR, "Frame size is too big\n"); - return -1; - } - vb_decode_framedata(c, c->stream, size, offset); - c->stream += size - 4; - rest -= size; - } - if(flags & VB_HAS_PALETTE){ - size = bytestream_get_le32(&c->stream); - if(size > rest){ - av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n"); - return -1; - } - vb_decode_palette(c, size); - rest -= size; - } - - memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); - c->pic.palette_has_changed = flags & VB_HAS_PALETTE; - - outptr = c->pic.data[0]; - srcptr = c->frame; - - for(i = 0; i < avctx->height; i++){ - memcpy(outptr, srcptr, avctx->width); - srcptr += avctx->width; - outptr += c->pic.linesize[0]; - } - - FFSWAP(uint8_t*, c->frame, c->prev_frame); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx) -{ - VBDecContext * const c = avctx->priv_data; - - c->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - c->frame = av_mallocz(avctx->width * avctx->height); - c->prev_frame = av_mallocz(avctx->width * avctx->height); - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx) -{ - VBDecContext *c = avctx->priv_data; - - av_freep(&c->frame); - av_freep(&c->prev_frame); - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - -AVCodec vb_decoder = { - "vb", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VB, - sizeof(VBDecContext), - decode_init, - NULL, - decode_end, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Beam Software VB"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/vc1.c b/tizen/distrib/ffmpeg/libavcodec/vc1.c deleted file mode 100644 index 7d00072..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vc1.c +++ /dev/null @@ -1,1033 +0,0 @@ -/* - * VC-1 and WMV3 decoder common code - * Copyright (c) 2006-2007 Konstantin Shishkov - * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VC-1 and WMV3 decoder common code - * - */ -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "vc1.h" -#include "vc1data.h" -#include "msmpeg4data.h" -#include "unary.h" -#include "simple_idct.h" - -#undef NDEBUG -#include - -/***********************************************************************/ -/** - * @defgroup vc1bitplane VC-1 Bitplane decoding - * @see 8.7, p56 - * @{ - */ - -/** - * Imode types - * @{ - */ -enum Imode { - IMODE_RAW, - IMODE_NORM2, - IMODE_DIFF2, - IMODE_NORM6, - IMODE_DIFF6, - IMODE_ROWSKIP, - IMODE_COLSKIP -}; -/** @} */ //imode defines - -/** Decode rows by checking if they are skipped - * @param plane Buffer to store decoded bits - * @param[in] width Width of this buffer - * @param[in] height Height of this buffer - * @param[in] stride of this buffer - */ -static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){ - int x, y; - - for (y=0; ys.gb; - - int imode, x, y, code, offset; - uint8_t invert, *planep = data; - int width, height, stride; - - width = v->s.mb_width; - height = v->s.mb_height; - stride = v->s.mb_stride; - invert = get_bits1(gb); - imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1); - - *raw_flag = 0; - switch (imode) - { - case IMODE_RAW: - //Data is actually read in the MB layer (same for all tests == "raw") - *raw_flag = 1; //invert ignored - return invert; - case IMODE_DIFF2: - case IMODE_NORM2: - if ((height * width) & 1) - { - *planep++ = get_bits1(gb); - offset = 1; - } - else offset = 0; - // decode bitplane as one long line - for (y = offset; y < height * width; y += 2) { - code = get_vlc2(gb, ff_vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1); - *planep++ = code & 1; - offset++; - if(offset == width) { - offset = 0; - planep += stride - width; - } - *planep++ = code >> 1; - offset++; - if(offset == width) { - offset = 0; - planep += stride - width; - } - } - break; - case IMODE_DIFF6: - case IMODE_NORM6: - if(!(height % 3) && (width % 3)) { // use 2x3 decoding - for(y = 0; y < height; y+= 3) { - for(x = width & 1; x < width; x += 2) { - code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); - if(code < 0){ - av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); - return -1; - } - planep[x + 0] = (code >> 0) & 1; - planep[x + 1] = (code >> 1) & 1; - planep[x + 0 + stride] = (code >> 2) & 1; - planep[x + 1 + stride] = (code >> 3) & 1; - planep[x + 0 + stride * 2] = (code >> 4) & 1; - planep[x + 1 + stride * 2] = (code >> 5) & 1; - } - planep += stride * 3; - } - if(width & 1) decode_colskip(data, 1, height, stride, &v->s.gb); - } else { // 3x2 - planep += (height & 1) * stride; - for(y = height & 1; y < height; y += 2) { - for(x = width % 3; x < width; x += 3) { - code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); - if(code < 0){ - av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); - return -1; - } - planep[x + 0] = (code >> 0) & 1; - planep[x + 1] = (code >> 1) & 1; - planep[x + 2] = (code >> 2) & 1; - planep[x + 0 + stride] = (code >> 3) & 1; - planep[x + 1 + stride] = (code >> 4) & 1; - planep[x + 2 + stride] = (code >> 5) & 1; - } - planep += stride * 2; - } - x = width % 3; - if(x) decode_colskip(data , x, height , stride, &v->s.gb); - if(height & 1) decode_rowskip(data+x, width - x, 1, stride, &v->s.gb); - } - break; - case IMODE_ROWSKIP: - decode_rowskip(data, width, height, stride, &v->s.gb); - break; - case IMODE_COLSKIP: - decode_colskip(data, width, height, stride, &v->s.gb); - break; - default: break; - } - - /* Applying diff operator */ - if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) - { - planep = data; - planep[0] ^= invert; - for (x=1; xs.gb; - int pqdiff; - - //variable size - if (v->dquant == 2) - { - pqdiff = get_bits(gb, 3); - if (pqdiff == 7) v->altpq = get_bits(gb, 5); - else v->altpq = v->pq + pqdiff + 1; - } - else - { - v->dquantfrm = get_bits1(gb); - if ( v->dquantfrm ) - { - v->dqprofile = get_bits(gb, 2); - switch (v->dqprofile) - { - case DQPROFILE_SINGLE_EDGE: - case DQPROFILE_DOUBLE_EDGES: - v->dqsbedge = get_bits(gb, 2); - break; - case DQPROFILE_ALL_MBS: - v->dqbilevel = get_bits1(gb); - if(!v->dqbilevel) - v->halfpq = 0; - default: break; //Forbidden ? - } - if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) - { - pqdiff = get_bits(gb, 3); - if (pqdiff == 7) v->altpq = get_bits(gb, 5); - else v->altpq = v->pq + pqdiff + 1; - } - } - } - return 0; -} - -static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb); - -/** - * Decode Simple/Main Profiles sequence header - * @see Figure 7-8, p16-17 - * @param avctx Codec context - * @param gb GetBit context initialized from Codec context extra_data - * @return Status - */ -int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitContext *gb) -{ - av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32)); - v->profile = get_bits(gb, 2); - if (v->profile == PROFILE_COMPLEX) - { - av_log(avctx, AV_LOG_ERROR, "WMV3 Complex Profile is not fully supported\n"); - } - - if (v->profile == PROFILE_ADVANCED) - { - v->zz_8x4 = ff_vc1_adv_progressive_8x4_zz; - v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz; - return decode_sequence_header_adv(v, gb); - } - else - { - v->zz_8x4 = wmv2_scantableA; - v->zz_4x8 = wmv2_scantableB; - v->res_sm = get_bits(gb, 2); //reserved - if (v->res_sm) - { - av_log(avctx, AV_LOG_ERROR, - "Reserved RES_SM=%i is forbidden\n", v->res_sm); - return -1; - } - } - - // (fps-2)/4 (->30) - v->frmrtq_postproc = get_bits(gb, 3); //common - // (bitrate-32kbps)/64kbps - v->bitrtq_postproc = get_bits(gb, 5); //common - v->s.loop_filter = get_bits1(gb); //common - if(v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE) - { - av_log(avctx, AV_LOG_ERROR, - "LOOPFILTER shall not be enabled in Simple Profile\n"); - } - if(v->s.avctx->skip_loop_filter >= AVDISCARD_ALL) - v->s.loop_filter = 0; - - v->res_x8 = get_bits1(gb); //reserved - v->multires = get_bits1(gb); - v->res_fasttx = get_bits1(gb); - if (!v->res_fasttx) - { - v->s.dsp.vc1_inv_trans_8x8 = ff_simple_idct; - v->s.dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add; - v->s.dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add; - v->s.dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add; - v->s.dsp.vc1_inv_trans_8x8_dc = ff_simple_idct_add; - v->s.dsp.vc1_inv_trans_8x4_dc = ff_simple_idct84_add; - v->s.dsp.vc1_inv_trans_4x8_dc = ff_simple_idct48_add; - v->s.dsp.vc1_inv_trans_4x4_dc = ff_simple_idct44_add; - } - - v->fastuvmc = get_bits1(gb); //common - if (!v->profile && !v->fastuvmc) - { - av_log(avctx, AV_LOG_ERROR, - "FASTUVMC unavailable in Simple Profile\n"); - return -1; - } - v->extended_mv = get_bits1(gb); //common - if (!v->profile && v->extended_mv) - { - av_log(avctx, AV_LOG_ERROR, - "Extended MVs unavailable in Simple Profile\n"); - return -1; - } - v->dquant = get_bits(gb, 2); //common - v->vstransform = get_bits1(gb); //common - - v->res_transtab = get_bits1(gb); - if (v->res_transtab) - { - av_log(avctx, AV_LOG_ERROR, - "1 for reserved RES_TRANSTAB is forbidden\n"); - return -1; - } - - v->overlap = get_bits1(gb); //common - - v->s.resync_marker = get_bits1(gb); - v->rangered = get_bits1(gb); - if (v->rangered && v->profile == PROFILE_SIMPLE) - { - av_log(avctx, AV_LOG_INFO, - "RANGERED should be set to 0 in Simple Profile\n"); - } - - v->s.max_b_frames = avctx->max_b_frames = get_bits(gb, 3); //common - v->quantizer_mode = get_bits(gb, 2); //common - - v->finterpflag = get_bits1(gb); //common - v->res_rtm_flag = get_bits1(gb); //reserved - if (!v->res_rtm_flag) - { -// av_log(avctx, AV_LOG_ERROR, -// "0 for reserved RES_RTM_FLAG is forbidden\n"); - av_log(avctx, AV_LOG_ERROR, - "Old WMV3 version detected, only I-frames will be decoded\n"); - //return -1; - } - //TODO: figure out what they mean (always 0x402F) - if(!v->res_fasttx) skip_bits(gb, 16); - av_log(avctx, AV_LOG_DEBUG, - "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n" - "LoopFilter=%i, MultiRes=%i, FastUVMC=%i, Extended MV=%i\n" - "Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n" - "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n", - v->profile, v->frmrtq_postproc, v->bitrtq_postproc, - v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv, - v->rangered, v->vstransform, v->overlap, v->s.resync_marker, - v->dquant, v->quantizer_mode, avctx->max_b_frames - ); - return 0; -} - -static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) -{ - v->res_rtm_flag = 1; - v->level = get_bits(gb, 3); - if(v->level >= 5) - { - av_log(v->s.avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level); - } - v->chromaformat = get_bits(gb, 2); - if (v->chromaformat != 1) - { - av_log(v->s.avctx, AV_LOG_ERROR, - "Only 4:2:0 chroma format supported\n"); - return -1; - } - - // (fps-2)/4 (->30) - v->frmrtq_postproc = get_bits(gb, 3); //common - // (bitrate-32kbps)/64kbps - v->bitrtq_postproc = get_bits(gb, 5); //common - v->postprocflag = get_bits1(gb); //common - - v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1; - v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1; - v->s.avctx->width = v->s.avctx->coded_width; - v->s.avctx->height = v->s.avctx->coded_height; - v->broadcast = get_bits1(gb); - v->interlace = get_bits1(gb); - v->tfcntrflag = get_bits1(gb); - v->finterpflag = get_bits1(gb); - skip_bits1(gb); // reserved - - v->s.h_edge_pos = v->s.avctx->coded_width; - v->s.v_edge_pos = v->s.avctx->coded_height; - - av_log(v->s.avctx, AV_LOG_DEBUG, - "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n" - "LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n" - "TFCTRflag=%i, FINTERPflag=%i\n", - v->level, v->frmrtq_postproc, v->bitrtq_postproc, - v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace, - v->tfcntrflag, v->finterpflag - ); - - v->psf = get_bits1(gb); - if(v->psf) { //PsF, 6.1.13 - av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n"); - return -1; - } - v->s.max_b_frames = v->s.avctx->max_b_frames = 7; - if(get_bits1(gb)) { //Display Info - decoding is not affected by it - int w, h, ar = 0; - av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n"); - v->s.avctx->width = w = get_bits(gb, 14) + 1; - v->s.avctx->height = h = get_bits(gb, 14) + 1; - av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h); - if(get_bits1(gb)) - ar = get_bits(gb, 4); - if(ar && ar < 14){ - v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar]; - }else if(ar == 15){ - w = get_bits(gb, 8); - h = get_bits(gb, 8); - v->s.avctx->sample_aspect_ratio = (AVRational){w, h}; - } - av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den); - - if(get_bits1(gb)){ //framerate stuff - if(get_bits1(gb)) { - v->s.avctx->time_base.num = 32; - v->s.avctx->time_base.den = get_bits(gb, 16) + 1; - } else { - int nr, dr; - nr = get_bits(gb, 8); - dr = get_bits(gb, 4); - if(nr && nr < 8 && dr && dr < 3){ - v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1]; - v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000; - } - } - } - - if(get_bits1(gb)){ - v->color_prim = get_bits(gb, 8); - v->transfer_char = get_bits(gb, 8); - v->matrix_coef = get_bits(gb, 8); - } - } - - v->hrd_param_flag = get_bits1(gb); - if(v->hrd_param_flag) { - int i; - v->hrd_num_leaky_buckets = get_bits(gb, 5); - skip_bits(gb, 4); //bitrate exponent - skip_bits(gb, 4); //buffer size exponent - for(i = 0; i < v->hrd_num_leaky_buckets; i++) { - skip_bits(gb, 16); //hrd_rate[n] - skip_bits(gb, 16); //hrd_buffer[n] - } - } - return 0; -} - -int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *gb) -{ - int i; - - av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32)); - v->broken_link = get_bits1(gb); - v->closed_entry = get_bits1(gb); - v->panscanflag = get_bits1(gb); - v->refdist_flag = get_bits1(gb); - v->s.loop_filter = get_bits1(gb); - v->fastuvmc = get_bits1(gb); - v->extended_mv = get_bits1(gb); - v->dquant = get_bits(gb, 2); - v->vstransform = get_bits1(gb); - v->overlap = get_bits1(gb); - v->quantizer_mode = get_bits(gb, 2); - - if(v->hrd_param_flag){ - for(i = 0; i < v->hrd_num_leaky_buckets; i++) { - skip_bits(gb, 8); //hrd_full[n] - } - } - - if(get_bits1(gb)){ - avctx->coded_width = (get_bits(gb, 12)+1)<<1; - avctx->coded_height = (get_bits(gb, 12)+1)<<1; - } - if(v->extended_mv) - v->extended_dmv = get_bits1(gb); - if((v->range_mapy_flag = get_bits1(gb))) { - av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n"); - v->range_mapy = get_bits(gb, 3); - } - if((v->range_mapuv_flag = get_bits1(gb))) { - av_log(avctx, AV_LOG_ERROR, "Chroma scaling is not supported, expect wrong picture\n"); - v->range_mapuv = get_bits(gb, 3); - } - - av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n" - "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n" - "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n" - "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n", - v->broken_link, v->closed_entry, v->panscanflag, v->refdist_flag, v->s.loop_filter, - v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode); - - return 0; -} - -int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) -{ - int pqindex, lowquant, status; - - if(v->finterpflag) v->interpfrm = get_bits1(gb); - skip_bits(gb, 2); //framecnt unused - v->rangeredfrm = 0; - if (v->rangered) v->rangeredfrm = get_bits1(gb); - v->s.pict_type = get_bits1(gb); - if (v->s.avctx->max_b_frames) { - if (!v->s.pict_type) { - if (get_bits1(gb)) v->s.pict_type = FF_I_TYPE; - else v->s.pict_type = FF_B_TYPE; - } else v->s.pict_type = FF_P_TYPE; - } else v->s.pict_type = v->s.pict_type ? FF_P_TYPE : FF_I_TYPE; - - v->bi_type = 0; - if(v->s.pict_type == FF_B_TYPE) { - v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; - if(v->bfraction == 0) { - v->s.pict_type = FF_BI_TYPE; - } - } - if(v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_BI_TYPE) - skip_bits(gb, 7); // skip buffer fullness - - if(v->parse_only) - return 0; - - /* calculate RND */ - if(v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_BI_TYPE) - v->rnd = 1; - if(v->s.pict_type == FF_P_TYPE) - v->rnd ^= 1; - - /* Quantizer stuff */ - pqindex = get_bits(gb, 5); - if(!pqindex) return -1; - if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) - v->pq = ff_vc1_pquant_table[0][pqindex]; - else - v->pq = ff_vc1_pquant_table[1][pqindex]; - - v->pquantizer = 1; - if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) - v->pquantizer = pqindex < 9; - if (v->quantizer_mode == QUANT_NON_UNIFORM) - v->pquantizer = 0; - v->pqindex = pqindex; - if (pqindex < 9) v->halfpq = get_bits1(gb); - else v->halfpq = 0; - if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits1(gb); - v->dquantfrm = 0; - if (v->extended_mv == 1) v->mvrange = get_unary(gb, 0, 3); - v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 - v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 - v->range_x = 1 << (v->k_x - 1); - v->range_y = 1 << (v->k_y - 1); - if (v->multires && v->s.pict_type != FF_B_TYPE) v->respic = get_bits(gb, 2); - - if(v->res_x8 && (v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_BI_TYPE)){ - v->x8_type = get_bits1(gb); - }else v->x8_type = 0; -//av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n", -// (v->s.pict_type == FF_P_TYPE) ? 'P' : ((v->s.pict_type == FF_I_TYPE) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm); - - if(v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_P_TYPE) v->use_ic = 0; - - switch(v->s.pict_type) { - case FF_P_TYPE: - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; - - lowquant = (v->pq > 12) ? 0 : 1; - v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)]; - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) - { - int scale, shift, i; - v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)]; - v->lumscale = get_bits(gb, 6); - v->lumshift = get_bits(gb, 6); - v->use_ic = 1; - /* fill lookup tables for intensity compensation */ - if(!v->lumscale) { - scale = -64; - shift = (255 - v->lumshift * 2) << 6; - if(v->lumshift > 31) - shift += 128 << 6; - } else { - scale = v->lumscale + 32; - if(v->lumshift > 31) - shift = (v->lumshift - 64) << 6; - else - shift = v->lumshift << 6; - } - for(i = 0; i < 256; i++) { - v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); - v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); - } - } - if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) - v->s.quarter_sample = 0; - else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) - v->s.quarter_sample = 0; - else - v->s.quarter_sample = 1; - } else - v->s.quarter_sample = 1; - v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)); - - if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && - v->mv_mode2 == MV_PMODE_MIXED_MV) - || v->mv_mode == MV_PMODE_MIXED_MV) - { - status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - } else { - v->mv_type_is_raw = 0; - memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height); - } - status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - - /* Hopefully this is correct for P frames */ - v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; - - if (v->dquant) - { - av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); - vop_dquant_decoding(v); - } - - v->ttfrm = 0; //FIXME Is that so ? - if (v->vstransform) - { - v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { - v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; - } - } else { - v->ttmbf = 1; - v->ttfrm = TT_8X8; - } - break; - case FF_B_TYPE: - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; - - v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; - v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV); - v->s.mspel = v->s.quarter_sample; - - status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - - v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; - - if (v->dquant) - { - av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); - vop_dquant_decoding(v); - } - - v->ttfrm = 0; - if (v->vstransform) - { - v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { - v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; - } - } else { - v->ttmbf = 1; - v->ttfrm = TT_8X8; - } - break; - } - - if(!v->x8_type) - { - /* AC Syntax */ - v->c_ac_table_index = decode012(gb); - if (v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_BI_TYPE) - { - v->y_ac_table_index = decode012(gb); - } - /* DC Syntax */ - v->s.dc_table_index = get_bits1(gb); - } - - if(v->s.pict_type == FF_BI_TYPE) { - v->s.pict_type = FF_B_TYPE; - v->bi_type = 1; - } - return 0; -} - -int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) -{ - int pqindex, lowquant; - int status; - - v->p_frame_skipped = 0; - - if(v->interlace){ - v->fcm = decode012(gb); - if(v->fcm){ - if(!v->warn_interlaced++) - av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced frames/fields support is not implemented\n"); - return -1; - } - } - switch(get_unary(gb, 0, 4)) { - case 0: - v->s.pict_type = FF_P_TYPE; - break; - case 1: - v->s.pict_type = FF_B_TYPE; - break; - case 2: - v->s.pict_type = FF_I_TYPE; - break; - case 3: - v->s.pict_type = FF_BI_TYPE; - break; - case 4: - v->s.pict_type = FF_P_TYPE; // skipped pic - v->p_frame_skipped = 1; - return 0; - } - if(v->tfcntrflag) - skip_bits(gb, 8); - if(v->broadcast) { - if(!v->interlace || v->psf) { - v->rptfrm = get_bits(gb, 2); - } else { - v->tff = get_bits1(gb); - v->rptfrm = get_bits1(gb); - } - } - if(v->panscanflag) { - //... - } - v->rnd = get_bits1(gb); - if(v->interlace) - v->uvsamp = get_bits1(gb); - if(v->finterpflag) v->interpfrm = get_bits1(gb); - if(v->s.pict_type == FF_B_TYPE) { - v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; - if(v->bfraction == 0) { - v->s.pict_type = FF_BI_TYPE; /* XXX: should not happen here */ - } - } - pqindex = get_bits(gb, 5); - if(!pqindex) return -1; - v->pqindex = pqindex; - if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) - v->pq = ff_vc1_pquant_table[0][pqindex]; - else - v->pq = ff_vc1_pquant_table[1][pqindex]; - - v->pquantizer = 1; - if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) - v->pquantizer = pqindex < 9; - if (v->quantizer_mode == QUANT_NON_UNIFORM) - v->pquantizer = 0; - v->pqindex = pqindex; - if (pqindex < 9) v->halfpq = get_bits1(gb); - else v->halfpq = 0; - if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits1(gb); - if(v->postprocflag) - v->postproc = get_bits(gb, 2); - - if(v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_P_TYPE) v->use_ic = 0; - - if(v->parse_only) - return 0; - - switch(v->s.pict_type) { - case FF_I_TYPE: - case FF_BI_TYPE: - status = bitplane_decoding(v->acpred_plane, &v->acpred_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "ACPRED plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - v->condover = CONDOVER_NONE; - if(v->overlap && v->pq <= 8) { - v->condover = decode012(gb); - if(v->condover == CONDOVER_SELECT) { - status = bitplane_decoding(v->over_flags_plane, &v->overflg_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "CONDOVER plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - } - } - break; - case FF_P_TYPE: - if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3); - else v->mvrange = 0; - v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 - v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 - v->range_x = 1 << (v->k_x - 1); - v->range_y = 1 << (v->k_y - 1); - - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; - - lowquant = (v->pq > 12) ? 0 : 1; - v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)]; - if (v->mv_mode == MV_PMODE_INTENSITY_COMP) - { - int scale, shift, i; - v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)]; - v->lumscale = get_bits(gb, 6); - v->lumshift = get_bits(gb, 6); - /* fill lookup tables for intensity compensation */ - if(!v->lumscale) { - scale = -64; - shift = (255 - v->lumshift * 2) << 6; - if(v->lumshift > 31) - shift += 128 << 6; - } else { - scale = v->lumscale + 32; - if(v->lumshift > 31) - shift = (v->lumshift - 64) << 6; - else - shift = v->lumshift << 6; - } - for(i = 0; i < 256; i++) { - v->luty[i] = av_clip_uint8((scale * i + shift + 32) >> 6); - v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6); - } - v->use_ic = 1; - } - if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) - v->s.quarter_sample = 0; - else if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - if(v->mv_mode2 == MV_PMODE_1MV_HPEL || v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN) - v->s.quarter_sample = 0; - else - v->s.quarter_sample = 1; - } else - v->s.quarter_sample = 1; - v->s.mspel = !(v->mv_mode == MV_PMODE_1MV_HPEL_BILIN || (v->mv_mode == MV_PMODE_INTENSITY_COMP && v->mv_mode2 == MV_PMODE_1MV_HPEL_BILIN)); - - if ((v->mv_mode == MV_PMODE_INTENSITY_COMP && - v->mv_mode2 == MV_PMODE_MIXED_MV) - || v->mv_mode == MV_PMODE_MIXED_MV) - { - status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - } else { - v->mv_type_is_raw = 0; - memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height); - } - status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - - /* Hopefully this is correct for P frames */ - v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; - if (v->dquant) - { - av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); - vop_dquant_decoding(v); - } - - v->ttfrm = 0; //FIXME Is that so ? - if (v->vstransform) - { - v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { - v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; - } - } else { - v->ttmbf = 1; - v->ttfrm = TT_8X8; - } - break; - case FF_B_TYPE: - if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3); - else v->mvrange = 0; - v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 - v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 - v->range_x = 1 << (v->k_x - 1); - v->range_y = 1 << (v->k_y - 1); - - if (v->pq < 5) v->tt_index = 0; - else if(v->pq < 13) v->tt_index = 1; - else v->tt_index = 2; - - v->mv_mode = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN; - v->s.quarter_sample = (v->mv_mode == MV_PMODE_1MV); - v->s.mspel = v->s.quarter_sample; - - status = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v); - if (status < 0) return -1; - av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " - "Imode: %i, Invert: %i\n", status>>1, status&1); - - v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; - - if (v->dquant) - { - av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); - vop_dquant_decoding(v); - } - - v->ttfrm = 0; - if (v->vstransform) - { - v->ttmbf = get_bits1(gb); - if (v->ttmbf) - { - v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; - } - } else { - v->ttmbf = 1; - v->ttfrm = TT_8X8; - } - break; - } - - /* AC Syntax */ - v->c_ac_table_index = decode012(gb); - if (v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_BI_TYPE) - { - v->y_ac_table_index = decode012(gb); - } - /* DC Syntax */ - v->s.dc_table_index = get_bits1(gb); - if ((v->s.pict_type == FF_I_TYPE || v->s.pict_type == FF_BI_TYPE) && v->dquant) { - av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); - vop_dquant_decoding(v); - } - - v->bi_type = 0; - if(v->s.pict_type == FF_BI_TYPE) { - v->s.pict_type = FF_B_TYPE; - v->bi_type = 1; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/vc1.h b/tizen/distrib/ffmpeg/libavcodec/vc1.h deleted file mode 100644 index d5f0e05..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vc1.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * VC-1 and WMV3 decoder - * Copyright (c) 2006-2007 Konstantin Shishkov - * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VC1_H -#define AVCODEC_VC1_H - -#include "avcodec.h" -#include "mpegvideo.h" -#include "intrax8.h" - -/** Markers used in VC-1 AP frame data */ -//@{ -enum VC1Code{ - VC1_CODE_RES0 = 0x00000100, - VC1_CODE_ENDOFSEQ = 0x0000010A, - VC1_CODE_SLICE, - VC1_CODE_FIELD, - VC1_CODE_FRAME, - VC1_CODE_ENTRYPOINT, - VC1_CODE_SEQHDR, -}; -//@} - -#define IS_MARKER(x) (((x) & ~0xFF) == VC1_CODE_RES0) - -/** Available Profiles */ -//@{ -enum Profile { - PROFILE_SIMPLE, - PROFILE_MAIN, - PROFILE_COMPLEX, ///< TODO: WMV9 specific - PROFILE_ADVANCED -}; -//@} - -/** Sequence quantizer mode */ -//@{ -enum QuantMode { - QUANT_FRAME_IMPLICIT, ///< Implicitly specified at frame level - QUANT_FRAME_EXPLICIT, ///< Explicitly specified at frame level - QUANT_NON_UNIFORM, ///< Non-uniform quant used for all frames - QUANT_UNIFORM ///< Uniform quant used for all frames -}; -//@} - -/** Where quant can be changed */ -//@{ -enum DQProfile { - DQPROFILE_FOUR_EDGES, - DQPROFILE_DOUBLE_EDGES, - DQPROFILE_SINGLE_EDGE, - DQPROFILE_ALL_MBS -}; -//@} - -/** @name Where quant can be changed - */ -//@{ -enum DQSingleEdge { - DQSINGLE_BEDGE_LEFT, - DQSINGLE_BEDGE_TOP, - DQSINGLE_BEDGE_RIGHT, - DQSINGLE_BEDGE_BOTTOM -}; -//@} - -/** Which pair of edges is quantized with ALTPQUANT */ -//@{ -enum DQDoubleEdge { - DQDOUBLE_BEDGE_TOPLEFT, - DQDOUBLE_BEDGE_TOPRIGHT, - DQDOUBLE_BEDGE_BOTTOMRIGHT, - DQDOUBLE_BEDGE_BOTTOMLEFT -}; -//@} - -/** MV modes for P frames */ -//@{ -enum MVModes { - MV_PMODE_1MV_HPEL_BILIN, - MV_PMODE_1MV, - MV_PMODE_1MV_HPEL, - MV_PMODE_MIXED_MV, - MV_PMODE_INTENSITY_COMP -}; -//@} - -/** @name MV types for B frames */ -//@{ -enum BMVTypes { - BMV_TYPE_BACKWARD, - BMV_TYPE_FORWARD, - BMV_TYPE_INTERPOLATED -}; -//@} - -/** @name Block types for P/B frames */ -//@{ -enum TransformTypes { - TT_8X8, - TT_8X4_BOTTOM, - TT_8X4_TOP, - TT_8X4, //Both halves - TT_4X8_RIGHT, - TT_4X8_LEFT, - TT_4X8, //Both halves - TT_4X4 -}; -//@} - -enum CodingSet { - CS_HIGH_MOT_INTRA = 0, - CS_HIGH_MOT_INTER, - CS_LOW_MOT_INTRA, - CS_LOW_MOT_INTER, - CS_MID_RATE_INTRA, - CS_MID_RATE_INTER, - CS_HIGH_RATE_INTRA, - CS_HIGH_RATE_INTER -}; - -/** @name Overlap conditions for Advanced Profile */ -//@{ -enum COTypes { - CONDOVER_NONE = 0, - CONDOVER_ALL, - CONDOVER_SELECT -}; -//@} - - -/** The VC1 Context - * @todo Change size wherever another size is more efficient - * Many members are only used for Advanced Profile - */ -typedef struct VC1Context{ - MpegEncContext s; - IntraX8Context x8; - - int bits; - - /** Simple/Main Profile sequence header */ - //@{ - int res_sm; ///< reserved, 2b - int res_x8; ///< reserved - int multires; ///< frame-level RESPIC syntax element present - int res_fasttx; ///< reserved, always 1 - int res_transtab; ///< reserved, always 0 - int rangered; ///< RANGEREDFRM (range reduction) syntax element present - ///< at frame level - int res_rtm_flag; ///< reserved, set to 1 - int reserved; ///< reserved - //@} - - /** Advanced Profile */ - //@{ - int level; ///< 3bits, for Advanced/Simple Profile, provided by TS layer - int chromaformat; ///< 2bits, 2=4:2:0, only defined - int postprocflag; ///< Per-frame processing suggestion flag present - int broadcast; ///< TFF/RFF present - int interlace; ///< Progressive/interlaced (RPTFTM syntax element) - int tfcntrflag; ///< TFCNTR present - int panscanflag; ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present - int refdist_flag; ///< REFDIST syntax element present in II, IP, PI or PP field picture headers - int extended_dmv; ///< Additional extended dmv range at P/B frame-level - int color_prim; ///< 8bits, chroma coordinates of the color primaries - int transfer_char; ///< 8bits, Opto-electronic transfer characteristics - int matrix_coef; ///< 8bits, Color primaries->YCbCr transform matrix - int hrd_param_flag; ///< Presence of Hypothetical Reference - ///< Decoder parameters - int psf; ///< Progressive Segmented Frame - //@} - - /** Sequence header data for all Profiles - * TODO: choose between ints, uint8_ts and monobit flags - */ - //@{ - int profile; ///< 2bits, Profile - int frmrtq_postproc; ///< 3bits, - int bitrtq_postproc; ///< 5bits, quantized framerate-based postprocessing strength - int fastuvmc; ///< Rounding of qpel vector to hpel ? (not in Simple) - int extended_mv; ///< Ext MV in P/B (not in Simple) - int dquant; ///< How qscale varies with MBs, 2bits (not in Simple) - int vstransform; ///< variable-size [48]x[48] transform type + info - int overlap; ///< overlapped transforms in use - int quantizer_mode; ///< 2bits, quantizer mode used for sequence, see QUANT_* - int finterpflag; ///< INTERPFRM present - //@} - - /** Frame decoding info for all profiles */ - //@{ - uint8_t mv_mode; ///< MV coding monde - uint8_t mv_mode2; ///< Secondary MV coding mode (B frames) - int k_x; ///< Number of bits for MVs (depends on MV range) - int k_y; ///< Number of bits for MVs (depends on MV range) - int range_x, range_y; ///< MV range - uint8_t pq, altpq; ///< Current/alternate frame quantizer scale - const uint8_t* zz_8x4;///< Zigzag scan table for TT_8x4 coding mode - const uint8_t* zz_4x8;///< Zigzag scan table for TT_4x8 coding mode - /** pquant parameters */ - //@{ - uint8_t dquantfrm; - uint8_t dqprofile; - uint8_t dqsbedge; - uint8_t dqbilevel; - //@} - /** AC coding set indexes - * @see 8.1.1.10, p(1)10 - */ - //@{ - int c_ac_table_index; ///< Chroma index from ACFRM element - int y_ac_table_index; ///< Luma index from AC2FRM element - //@} - int ttfrm; ///< Transform type info present at frame level - uint8_t ttmbf; ///< Transform type flag - uint8_t ttblk4x4; ///< Value of ttblk which indicates a 4x4 transform - int codingset; ///< index of current table set from 11.8 to use for luma block decoding - int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding - int pqindex; ///< raw pqindex used in coding set selection - int a_avail, c_avail; - uint8_t *mb_type_base, *mb_type[3]; - - - /** Luma compensation parameters */ - //@{ - uint8_t lumscale; - uint8_t lumshift; - //@} - int16_t bfraction; ///< Relative position % anchors=> how to scale MVs - uint8_t halfpq; ///< Uniform quant over image and qp+.5 - uint8_t respic; ///< Frame-level flag for resized images - int buffer_fullness; ///< HRD info - /** Ranges: - * -# 0 -> [-64n 63.f] x [-32, 31.f] - * -# 1 -> [-128, 127.f] x [-64, 63.f] - * -# 2 -> [-512, 511.f] x [-128, 127.f] - * -# 3 -> [-1024, 1023.f] x [-256, 255.f] - */ - uint8_t mvrange; - uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use - VLC *cbpcy_vlc; ///< CBPCY VLC table - int tt_index; ///< Index for Transform Type tables - uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV) - uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs - int mv_type_is_raw; ///< mv type mb plane is not coded - int dmb_is_raw; ///< direct mb plane is raw - int skip_is_raw; ///< skip mb plane is not coded - uint8_t luty[256], lutuv[256]; // lookup tables used for intensity compensation - int use_ic; ///< use intensity compensation in B-frames - int rnd; ///< rounding control - - /** Frame decoding info for S/M profiles only */ - //@{ - uint8_t rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128) - uint8_t interpfrm; - //@} - - /** Frame decoding info for Advanced profile */ - //@{ - uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace - uint8_t numpanscanwin; - uint8_t tfcntr; - uint8_t rptfrm, tff, rff; - uint16_t topleftx; - uint16_t toplefty; - uint16_t bottomrightx; - uint16_t bottomrighty; - uint8_t uvsamp; - uint8_t postproc; - int hrd_num_leaky_buckets; - uint8_t bit_rate_exponent; - uint8_t buffer_size_exponent; - uint8_t* acpred_plane; ///< AC prediction flags bitplane - int acpred_is_raw; - uint8_t* over_flags_plane; ///< Overflags bitplane - int overflg_is_raw; - uint8_t condover; - uint16_t *hrd_rate, *hrd_buffer; - uint8_t *hrd_fullness; - uint8_t range_mapy_flag; - uint8_t range_mapuv_flag; - uint8_t range_mapy; - uint8_t range_mapuv; - //@} - - int p_frame_skipped; - int bi_type; - int x8_type; - - uint32_t *cbp_base, *cbp; - uint8_t bfraction_lut_index;///< Index for BFRACTION value (see Table 40, reproduced into ff_vc1_bfraction_lut[]) - uint8_t broken_link; ///< Broken link flag (BROKEN_LINK syntax element) - uint8_t closed_entry; ///< Closed entry point flag (CLOSED_ENTRY syntax element) - - int parse_only; ///< Context is used within parser - - int warn_interlaced; -} VC1Context; - -/** Find VC-1 marker in buffer - * @return position where next marker starts or end of buffer if no marker found - */ -static av_always_inline const uint8_t* find_next_marker(const uint8_t *src, const uint8_t *end) -{ - uint32_t mrk = 0xFFFFFFFF; - - if(end-src < 4) return end; - while(src < end){ - mrk = (mrk << 8) | *src++; - if(IS_MARKER(mrk)) - return src-4; - } - return end; -} - -static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, uint8_t *dst) -{ - int dsize = 0, i; - - if(size < 4){ - for(dsize = 0; dsize < size; dsize++) *dst++ = *src++; - return size; - } - for(i = 0; i < size; i++, src++) { - if(src[0] == 3 && i >= 2 && !src[-1] && !src[-2] && i < size-1 && src[1] < 4) { - dst[dsize++] = src[1]; - src++; - i++; - } else - dst[dsize++] = *src; - } - return dsize; -} - -/** - * Decode Simple/Main Profiles sequence header - * @see Figure 7-8, p16-17 - * @param avctx Codec context - * @param gb GetBit context initialized from Codec context extra_data - * @return Status - */ -int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitContext *gb); - -int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *gb); - -int vc1_parse_frame_header (VC1Context *v, GetBitContext *gb); -int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb); - -#endif /* AVCODEC_VC1_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vc1_parser.c b/tizen/distrib/ffmpeg/libavcodec/vc1_parser.c deleted file mode 100644 index 6e559de..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vc1_parser.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * VC-1 and WMV3 parser - * Copyright (c) 2006-2007 Konstantin Shishkov - * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VC-1 and WMV3 parser - */ - -#include "parser.h" -#include "vc1.h" -#include "get_bits.h" - -typedef struct { - ParseContext pc; - VC1Context v; -} VC1ParseContext; - -static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - VC1ParseContext *vpc = s->priv_data; - GetBitContext gb; - const uint8_t *start, *end, *next; - uint8_t *buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - vpc->v.s.avctx = avctx; - vpc->v.parse_only = 1; - next = buf; - - for(start = buf, end = buf + buf_size; next < end; start = next){ - int buf2_size, size; - - next = find_next_marker(start + 4, end); - size = next - start - 4; - buf2_size = vc1_unescape_buffer(start + 4, size, buf2); - init_get_bits(&gb, buf2, buf2_size * 8); - if(size <= 0) continue; - switch(AV_RB32(start)){ - case VC1_CODE_SEQHDR: - vc1_decode_sequence_header(avctx, &vpc->v, &gb); - break; - case VC1_CODE_ENTRYPOINT: - vc1_decode_entry_point(avctx, &vpc->v, &gb); - break; - case VC1_CODE_FRAME: - if(vpc->v.profile < PROFILE_ADVANCED) - vc1_parse_frame_header (&vpc->v, &gb); - else - vc1_parse_frame_header_adv(&vpc->v, &gb); - - /* keep FF_BI_TYPE internal to VC1 */ - if (vpc->v.s.pict_type == FF_BI_TYPE) - s->pict_type = FF_B_TYPE; - else - s->pict_type = vpc->v.s.pict_type; - - break; - } - } - - av_free(buf2); -} - -/** - * 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 vc1_find_frame_end(ParseContext *pc, const uint8_t *buf, - int buf_size) { - int pic_found, i; - uint32_t state; - - pic_found= pc->frame_start_found; - state= pc->state; - - i=0; - if(!pic_found){ - for(i=0; iframe_start_found=0; - pc->state=-1; - return i-3; - } - } - } - pc->frame_start_found= pic_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int vc1_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - VC1ParseContext *vpc = s->priv_data; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= vc1_find_frame_end(&vpc->pc, buf, buf_size); - - if (ff_combine_frame(&vpc->pc, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - - vc1_extract_headers(s, avctx, buf, buf_size); - - *poutbuf = buf; - *poutbuf_size = buf_size; - return next; -} - -static int vc1_split(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - int i; - uint32_t state= -1; - int charged=0; - - for(i=0; i - -#define AC_MODES 8 - -static const int vc1_ac_sizes[AC_MODES] = { - 186, 169, 133, 149, 103, 103, 163, 175 -}; - -static const uint32_t vc1_ac_tables[AC_MODES][186][2] = { -{ -{ 0x0001, 2}, { 0x0005, 3}, { 0x000D, 4}, { 0x0012, 5}, { 0x000E, 6}, { 0x0015, 7}, -{ 0x0013, 8}, { 0x003F, 8}, { 0x004B, 9}, { 0x011F, 9}, { 0x00B8, 10}, { 0x03E3, 10}, -{ 0x0172, 11}, { 0x024D, 12}, { 0x03DA, 12}, { 0x02DD, 13}, { 0x1F55, 13}, { 0x05B9, 14}, -{ 0x3EAE, 14}, { 0x0000, 4}, { 0x0010, 5}, { 0x0008, 7}, { 0x0020, 8}, { 0x0029, 9}, -{ 0x01F4, 9}, { 0x0233, 10}, { 0x01E0, 11}, { 0x012A, 12}, { 0x03DD, 12}, { 0x050A, 13}, -{ 0x1F29, 13}, { 0x0A42, 14}, { 0x1272, 15}, { 0x1737, 15}, { 0x0003, 5}, { 0x0011, 7}, -{ 0x00C4, 8}, { 0x004B, 10}, { 0x00B4, 11}, { 0x07D4, 11}, { 0x0345, 12}, { 0x02D7, 13}, -{ 0x07BF, 13}, { 0x0938, 14}, { 0x0BBB, 14}, { 0x095E, 15}, { 0x0013, 5}, { 0x0078, 7}, -{ 0x0069, 9}, { 0x0232, 10}, { 0x0461, 11}, { 0x03EC, 12}, { 0x0520, 13}, { 0x1F2A, 13}, -{ 0x3E50, 14}, { 0x3E51, 14}, { 0x1486, 15}, { 0x000C, 6}, { 0x0024, 9}, { 0x0094, 11}, -{ 0x08C0, 12}, { 0x0F09, 14}, { 0x1EF0, 15}, { 0x003D, 6}, { 0x0053, 9}, { 0x01A0, 11}, -{ 0x02D6, 13}, { 0x0F08, 14}, { 0x0013, 7}, { 0x007C, 9}, { 0x07C1, 11}, { 0x04AC, 14}, -{ 0x001B, 7}, { 0x00A0, 10}, { 0x0344, 12}, { 0x0F79, 14}, { 0x0079, 7}, { 0x03E1, 10}, -{ 0x02D4, 13}, { 0x2306, 14}, { 0x0021, 8}, { 0x023C, 10}, { 0x0FAE, 12}, { 0x23DE, 14}, -{ 0x0035, 8}, { 0x0175, 11}, { 0x07B3, 13}, { 0x00C5, 8}, { 0x0174, 11}, { 0x0785, 13}, -{ 0x0048, 9}, { 0x01A3, 11}, { 0x049E, 13}, { 0x002C, 9}, { 0x00FA, 10}, { 0x07D6, 11}, -{ 0x0092, 10}, { 0x05CC, 13}, { 0x1EF1, 15}, { 0x00A3, 10}, { 0x03ED, 12}, { 0x093E, 14}, -{ 0x01E2, 11}, { 0x1273, 15}, { 0x07C4, 11}, { 0x1487, 15}, { 0x0291, 12}, { 0x0293, 12}, -{ 0x0F8A, 12}, { 0x0509, 13}, { 0x0508, 13}, { 0x078D, 13}, { 0x07BE, 13}, { 0x078C, 13}, -{ 0x04AE, 14}, { 0x0BBA, 14}, { 0x2307, 14}, { 0x0B9A, 14}, { 0x1736, 15}, { 0x000E, 4}, -{ 0x0045, 7}, { 0x01F3, 9}, { 0x047A, 11}, { 0x05DC, 13}, { 0x23DF, 14}, { 0x0019, 5}, -{ 0x0028, 9}, { 0x0176, 11}, { 0x049D, 13}, { 0x23DD, 14}, { 0x0030, 6}, { 0x00A2, 10}, -{ 0x02EF, 12}, { 0x05B8, 14}, { 0x003F, 6}, { 0x00A5, 10}, { 0x03DB, 12}, { 0x093F, 14}, -{ 0x0044, 7}, { 0x07CB, 11}, { 0x095F, 15}, { 0x0063, 7}, { 0x03C3, 12}, { 0x0015, 8}, -{ 0x08F6, 12}, { 0x0017, 8}, { 0x0498, 13}, { 0x002C, 8}, { 0x07B2, 13}, { 0x002F, 8}, -{ 0x1F54, 13}, { 0x008D, 8}, { 0x07BD, 13}, { 0x008E, 8}, { 0x1182, 13}, { 0x00FB, 8}, -{ 0x050B, 13}, { 0x002D, 8}, { 0x07C0, 11}, { 0x0079, 9}, { 0x1F5F, 13}, { 0x007A, 9}, -{ 0x1F56, 13}, { 0x0231, 10}, { 0x03E4, 10}, { 0x01A1, 11}, { 0x0143, 11}, { 0x01F7, 11}, -{ 0x016F, 12}, { 0x0292, 12}, { 0x02E7, 12}, { 0x016C, 12}, { 0x016D, 12}, { 0x03DC, 12}, -{ 0x0F8B, 12}, { 0x0499, 13}, { 0x03D8, 12}, { 0x078E, 13}, { 0x02D5, 13}, { 0x1F5E, 13}, -{ 0x1F2B, 13}, { 0x078F, 13}, { 0x04AD, 14}, { 0x3EAF, 14}, { 0x23DC, 14}, { 0x004A, 9} -}, -{ -{ 0x0000, 3}, { 0x0003, 4}, { 0x000B, 5}, { 0x0014, 6}, { 0x003F, 6}, { 0x005D, 7}, -{ 0x00A2, 8}, { 0x00AC, 9}, { 0x016E, 9}, { 0x020A, 10}, { 0x02E2, 10}, { 0x0432, 11}, -{ 0x05C9, 11}, { 0x0827, 12}, { 0x0B54, 12}, { 0x04E6, 13}, { 0x105F, 13}, { 0x172A, 13}, -{ 0x20B2, 14}, { 0x2D4E, 14}, { 0x39F0, 14}, { 0x4175, 15}, { 0x5A9E, 15}, { 0x0004, 4}, -{ 0x001E, 5}, { 0x0042, 7}, { 0x00B6, 8}, { 0x0173, 9}, { 0x0395, 10}, { 0x072E, 11}, -{ 0x0B94, 12}, { 0x16A4, 13}, { 0x20B3, 14}, { 0x2E45, 14}, { 0x0005, 5}, { 0x0040, 7}, -{ 0x0049, 9}, { 0x028F, 10}, { 0x05CB, 11}, { 0x048A, 13}, { 0x09DD, 14}, { 0x73E2, 15}, -{ 0x0018, 5}, { 0x0025, 8}, { 0x008A, 10}, { 0x051B, 11}, { 0x0E5F, 12}, { 0x09C9, 14}, -{ 0x139C, 15}, { 0x0029, 6}, { 0x004F, 9}, { 0x0412, 11}, { 0x048D, 13}, { 0x2E41, 14}, -{ 0x0038, 6}, { 0x010E, 9}, { 0x05A8, 11}, { 0x105C, 13}, { 0x39F2, 14}, { 0x0058, 7}, -{ 0x021F, 10}, { 0x0E7E, 12}, { 0x39FF, 14}, { 0x0023, 8}, { 0x02E3, 10}, { 0x04E5, 13}, -{ 0x2E40, 14}, { 0x00A1, 8}, { 0x05BE, 11}, { 0x09C8, 14}, { 0x0083, 8}, { 0x013A, 11}, -{ 0x1721, 13}, { 0x0044, 9}, { 0x0276, 12}, { 0x39F6, 14}, { 0x008B, 10}, { 0x04EF, 13}, -{ 0x5A9B, 15}, { 0x0208, 10}, { 0x1CFE, 13}, { 0x0399, 10}, { 0x1CB4, 13}, { 0x039E, 10}, -{ 0x39F3, 14}, { 0x05AB, 11}, { 0x73E3, 15}, { 0x0737, 11}, { 0x5A9F, 15}, { 0x082D, 12}, -{ 0x0E69, 12}, { 0x0E68, 12}, { 0x0433, 11}, { 0x0B7B, 12}, { 0x2DF8, 14}, { 0x2E56, 14}, -{ 0x2E57, 14}, { 0x39F7, 14}, { 0x51A5, 15}, { 0x0003, 3}, { 0x002A, 6}, { 0x00E4, 8}, -{ 0x028E, 10}, { 0x0735, 11}, { 0x1058, 13}, { 0x1CFA, 13}, { 0x2DF9, 14}, { 0x4174, 15}, -{ 0x0009, 4}, { 0x0054, 8}, { 0x0398, 10}, { 0x048B, 13}, { 0x139D, 15}, { 0x000D, 4}, -{ 0x00AD, 9}, { 0x0826, 12}, { 0x2D4C, 14}, { 0x0011, 5}, { 0x016B, 9}, { 0x0B7F, 12}, -{ 0x51A4, 15}, { 0x0019, 5}, { 0x021B, 10}, { 0x16FD, 13}, { 0x001D, 5}, { 0x0394, 10}, -{ 0x28D3, 14}, { 0x002B, 6}, { 0x05BC, 11}, { 0x5A9A, 15}, { 0x002F, 6}, { 0x0247, 12}, -{ 0x0010, 7}, { 0x0A35, 12}, { 0x003E, 6}, { 0x0B7A, 12}, { 0x0059, 7}, { 0x105E, 13}, -{ 0x0026, 8}, { 0x09CF, 14}, { 0x0055, 8}, { 0x1CB5, 13}, { 0x0057, 8}, { 0x0E5B, 12}, -{ 0x00A0, 8}, { 0x1468, 13}, { 0x0170, 9}, { 0x0090, 10}, { 0x01CE, 9}, { 0x021A, 10}, -{ 0x0218, 10}, { 0x0168, 9}, { 0x021E, 10}, { 0x0244, 12}, { 0x0736, 11}, { 0x0138, 11}, -{ 0x0519, 11}, { 0x0E5E, 12}, { 0x072C, 11}, { 0x0B55, 12}, { 0x09DC, 14}, { 0x20BB, 14}, -{ 0x048C, 13}, { 0x1723, 13}, { 0x2E44, 14}, { 0x16A5, 13}, { 0x0518, 11}, { 0x39FE, 14}, -{ 0x0169, 9} -}, -{ -{ 0x0001, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x0016, 5}, { 0x0020, 6}, { 0x0018, 7}, -{ 0x0008, 8}, { 0x009A, 8}, { 0x0056, 9}, { 0x013E, 9}, { 0x00F0, 10}, { 0x03A5, 10}, -{ 0x0077, 11}, { 0x01EF, 11}, { 0x009A, 12}, { 0x005D, 13}, { 0x0001, 4}, { 0x0011, 5}, -{ 0x0002, 7}, { 0x000B, 8}, { 0x0012, 9}, { 0x01D6, 9}, { 0x027E, 10}, { 0x0191, 11}, -{ 0x00EA, 12}, { 0x03DC, 12}, { 0x013B, 13}, { 0x0004, 5}, { 0x0014, 7}, { 0x009E, 8}, -{ 0x0009, 10}, { 0x01AC, 11}, { 0x01E2, 11}, { 0x03CA, 12}, { 0x005F, 13}, { 0x0017, 5}, -{ 0x004E, 7}, { 0x005E, 9}, { 0x00F3, 10}, { 0x01AD, 11}, { 0x00EC, 12}, { 0x05F0, 13}, -{ 0x000E, 6}, { 0x00E1, 8}, { 0x03A4, 10}, { 0x009C, 12}, { 0x013D, 13}, { 0x003B, 6}, -{ 0x001C, 9}, { 0x0014, 11}, { 0x09BE, 12}, { 0x0006, 7}, { 0x007A, 9}, { 0x0190, 11}, -{ 0x0137, 13}, { 0x001B, 7}, { 0x0008, 10}, { 0x075C, 11}, { 0x0071, 7}, { 0x00D7, 10}, -{ 0x09BF, 12}, { 0x0007, 8}, { 0x00AF, 10}, { 0x04CC, 11}, { 0x0034, 8}, { 0x0265, 10}, -{ 0x009F, 12}, { 0x00E0, 8}, { 0x0016, 11}, { 0x0327, 12}, { 0x0015, 9}, { 0x017D, 11}, -{ 0x0EBB, 12}, { 0x0014, 9}, { 0x00F6, 10}, { 0x01E4, 11}, { 0x00CB, 10}, { 0x099D, 12}, -{ 0x00CA, 10}, { 0x02FC, 12}, { 0x017F, 11}, { 0x04CD, 11}, { 0x02FD, 12}, { 0x04FE, 11}, -{ 0x013A, 13}, { 0x000A, 4}, { 0x0042, 7}, { 0x01D3, 9}, { 0x04DD, 11}, { 0x0012, 5}, -{ 0x00E8, 8}, { 0x004C, 11}, { 0x0136, 13}, { 0x0039, 6}, { 0x0264, 10}, { 0x0EBA, 12}, -{ 0x0000, 7}, { 0x00AE, 10}, { 0x099C, 12}, { 0x001F, 7}, { 0x04DE, 11}, { 0x0043, 7}, -{ 0x04DC, 11}, { 0x0003, 8}, { 0x03CB, 12}, { 0x0006, 8}, { 0x099E, 12}, { 0x002A, 8}, -{ 0x05F1, 13}, { 0x000F, 8}, { 0x09FE, 12}, { 0x0033, 8}, { 0x09FF, 12}, { 0x0098, 8}, -{ 0x099F, 12}, { 0x00EA, 8}, { 0x013C, 13}, { 0x002E, 8}, { 0x0192, 11}, { 0x0136, 9}, -{ 0x006A, 9}, { 0x0015, 11}, { 0x03AF, 10}, { 0x01E3, 11}, { 0x0074, 11}, { 0x00EB, 12}, -{ 0x02F9, 12}, { 0x005C, 13}, { 0x00ED, 12}, { 0x03DD, 12}, { 0x0326, 12}, { 0x005E, 13}, -{ 0x0016, 7} -}, -{ -{ 0x0004, 3}, { 0x0014, 5}, { 0x0017, 7}, { 0x007F, 8}, { 0x0154, 9}, { 0x01F2, 10}, -{ 0x00BF, 11}, { 0x0065, 12}, { 0x0AAA, 12}, { 0x0630, 13}, { 0x1597, 13}, { 0x03B7, 14}, -{ 0x2B22, 14}, { 0x0BE6, 15}, { 0x000B, 4}, { 0x0037, 7}, { 0x0062, 9}, { 0x0007, 11}, -{ 0x0166, 12}, { 0x00CE, 13}, { 0x1590, 13}, { 0x05F6, 14}, { 0x0BE7, 15}, { 0x0007, 5}, -{ 0x006D, 8}, { 0x0003, 11}, { 0x031F, 12}, { 0x05F2, 14}, { 0x0002, 6}, { 0x0061, 9}, -{ 0x0055, 12}, { 0x01DF, 14}, { 0x001A, 6}, { 0x001E, 10}, { 0x0AC9, 12}, { 0x2B23, 14}, -{ 0x001E, 6}, { 0x001F, 10}, { 0x0AC3, 12}, { 0x2B2B, 14}, { 0x0006, 7}, { 0x0004, 11}, -{ 0x02F8, 13}, { 0x0019, 7}, { 0x0006, 11}, { 0x063D, 13}, { 0x0057, 7}, { 0x0182, 11}, -{ 0x2AA2, 14}, { 0x0004, 8}, { 0x0180, 11}, { 0x059C, 14}, { 0x007D, 8}, { 0x0164, 12}, -{ 0x076D, 15}, { 0x0002, 9}, { 0x018D, 11}, { 0x1581, 13}, { 0x00AD, 8}, { 0x0060, 12}, -{ 0x0C67, 14}, { 0x001C, 9}, { 0x00EE, 13}, { 0x0003, 9}, { 0x02CF, 13}, { 0x00D9, 9}, -{ 0x1580, 13}, { 0x0002, 11}, { 0x0183, 11}, { 0x0057, 12}, { 0x0061, 12}, { 0x0031, 11}, -{ 0x0066, 12}, { 0x0631, 13}, { 0x0632, 13}, { 0x00AC, 13}, { 0x031D, 12}, { 0x0076, 12}, -{ 0x003A, 11}, { 0x0165, 12}, { 0x0C66, 14}, { 0x0003, 2}, { 0x0054, 7}, { 0x02AB, 10}, -{ 0x0016, 13}, { 0x05F7, 14}, { 0x0005, 4}, { 0x00F8, 9}, { 0x0AA9, 12}, { 0x005F, 15}, -{ 0x0004, 4}, { 0x001C, 10}, { 0x1550, 13}, { 0x0004, 5}, { 0x0077, 11}, { 0x076C, 15}, -{ 0x000E, 5}, { 0x000A, 12}, { 0x000C, 5}, { 0x0562, 11}, { 0x0004, 6}, { 0x031C, 12}, -{ 0x0006, 6}, { 0x00C8, 13}, { 0x000D, 6}, { 0x01DA, 13}, { 0x0007, 6}, { 0x00C9, 13}, -{ 0x0001, 7}, { 0x002E, 14}, { 0x0014, 7}, { 0x1596, 13}, { 0x000A, 7}, { 0x0AC2, 12}, -{ 0x0016, 7}, { 0x015B, 14}, { 0x0015, 7}, { 0x015A, 14}, { 0x000F, 8}, { 0x005E, 15}, -{ 0x007E, 8}, { 0x00AB, 8}, { 0x002D, 9}, { 0x00D8, 9}, { 0x000B, 9}, { 0x0014, 10}, -{ 0x02B3, 10}, { 0x01F3, 10}, { 0x003A, 10}, { 0x0000, 10}, { 0x0058, 10}, { 0x002E, 9}, -{ 0x005E, 10}, { 0x0563, 11}, { 0x00EC, 12}, { 0x0054, 12}, { 0x0AC1, 12}, { 0x1556, 13}, -{ 0x02FA, 13}, { 0x0181, 11}, { 0x1557, 13}, { 0x059D, 14}, { 0x2AA3, 14}, { 0x2B2A, 14}, -{ 0x01DE, 14}, { 0x063C, 13}, { 0x00CF, 13}, { 0x1594, 13}, { 0x000D, 9} -}, -{ -{ 0x0002, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x000D, 5}, { 0x000C, 5}, { 0x0015, 6}, -{ 0x0013, 6}, { 0x0012, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x001E, 8}, { 0x001D, 8}, -{ 0x0025, 9}, { 0x0024, 9}, { 0x0023, 9}, { 0x0021, 9}, { 0x0021, 10}, { 0x0020, 10}, -{ 0x000F, 10}, { 0x000E, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, { 0x0021, 11}, -{ 0x0050, 12}, { 0x0051, 12}, { 0x0052, 12}, { 0x000E, 4}, { 0x0014, 6}, { 0x0016, 7}, -{ 0x001C, 8}, { 0x0020, 9}, { 0x001F, 9}, { 0x000D, 10}, { 0x0022, 11}, { 0x0053, 12}, -{ 0x0055, 12}, { 0x000B, 5}, { 0x0015, 7}, { 0x001E, 9}, { 0x000C, 10}, { 0x0056, 12}, -{ 0x0011, 6}, { 0x001B, 8}, { 0x001D, 9}, { 0x000B, 10}, { 0x0010, 6}, { 0x0022, 9}, -{ 0x000A, 10}, { 0x000D, 6}, { 0x001C, 9}, { 0x0008, 10}, { 0x0012, 7}, { 0x001B, 9}, -{ 0x0054, 12}, { 0x0014, 7}, { 0x001A, 9}, { 0x0057, 12}, { 0x0019, 8}, { 0x0009, 10}, -{ 0x0018, 8}, { 0x0023, 11}, { 0x0017, 8}, { 0x0019, 9}, { 0x0018, 9}, { 0x0007, 10}, -{ 0x0058, 12}, { 0x0007, 4}, { 0x000C, 6}, { 0x0016, 8}, { 0x0017, 9}, { 0x0006, 10}, -{ 0x0005, 11}, { 0x0004, 11}, { 0x0059, 12}, { 0x000F, 6}, { 0x0016, 9}, { 0x0005, 10}, -{ 0x000E, 6}, { 0x0004, 10}, { 0x0011, 7}, { 0x0024, 11}, { 0x0010, 7}, { 0x0025, 11}, -{ 0x0013, 7}, { 0x005A, 12}, { 0x0015, 8}, { 0x005B, 12}, { 0x0014, 8}, { 0x0013, 8}, -{ 0x001A, 8}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, { 0x0012, 9}, { 0x0011, 9}, -{ 0x0026, 11}, { 0x0027, 11}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12}, -{ 0x0003, 7} -}, -{ -{ 0x0002, 2}, { 0x000F, 4}, { 0x0015, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x0025, 9}, -{ 0x0024, 9}, { 0x0021, 10}, { 0x0020, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, -{ 0x0006, 3}, { 0x0014, 6}, { 0x001E, 8}, { 0x000F, 10}, { 0x0021, 11}, { 0x0050, 12}, -{ 0x000E, 4}, { 0x001D, 8}, { 0x000E, 10}, { 0x0051, 12}, { 0x000D, 5}, { 0x0023, 9}, -{ 0x000D, 10}, { 0x000C, 5}, { 0x0022, 9}, { 0x0052, 12}, { 0x000B, 5}, { 0x000C, 10}, -{ 0x0053, 12}, { 0x0013, 6}, { 0x000B, 10}, { 0x0054, 12}, { 0x0012, 6}, { 0x000A, 10}, -{ 0x0011, 6}, { 0x0009, 10}, { 0x0010, 6}, { 0x0008, 10}, { 0x0016, 7}, { 0x0055, 12}, -{ 0x0015, 7}, { 0x0014, 7}, { 0x001C, 8}, { 0x001B, 8}, { 0x0021, 9}, { 0x0020, 9}, -{ 0x001F, 9}, { 0x001E, 9}, { 0x001D, 9}, { 0x001C, 9}, { 0x001B, 9}, { 0x001A, 9}, -{ 0x0022, 11}, { 0x0023, 11}, { 0x0056, 12}, { 0x0057, 12}, { 0x0007, 4}, { 0x0019, 9}, -{ 0x0005, 11}, { 0x000F, 6}, { 0x0004, 11}, { 0x000E, 6}, { 0x000D, 6}, { 0x000C, 6}, -{ 0x0013, 7}, { 0x0012, 7}, { 0x0011, 7}, { 0x0010, 7}, { 0x001A, 8}, { 0x0019, 8}, -{ 0x0018, 8}, { 0x0017, 8}, { 0x0016, 8}, { 0x0015, 8}, { 0x0014, 8}, { 0x0013, 8}, -{ 0x0018, 9}, { 0x0017, 9}, { 0x0016, 9}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, -{ 0x0012, 9}, { 0x0011, 9}, { 0x0007, 10}, { 0x0006, 10}, { 0x0005, 10}, { 0x0004, 10}, -{ 0x0024, 11}, { 0x0025, 11}, { 0x0026, 11}, { 0x0027, 11}, { 0x0058, 12}, { 0x0059, 12}, -{ 0x005A, 12}, { 0x005B, 12}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12}, -{ 0x0003, 7} -}, -{ -{ 0x0000, 2}, { 0x0003, 3}, { 0x000D, 4}, { 0x0005, 4}, { 0x001C, 5}, { 0x0016, 5}, -{ 0x003F, 6}, { 0x003A, 6}, { 0x002E, 6}, { 0x0022, 6}, { 0x007B, 7}, { 0x0067, 7}, -{ 0x005F, 7}, { 0x0047, 7}, { 0x0026, 7}, { 0x00EF, 8}, { 0x00CD, 8}, { 0x00C1, 8}, -{ 0x00A9, 8}, { 0x004F, 8}, { 0x01F2, 9}, { 0x01DD, 9}, { 0x0199, 9}, { 0x0185, 9}, -{ 0x015D, 9}, { 0x011B, 9}, { 0x03EF, 10}, { 0x03E1, 10}, { 0x03C8, 10}, { 0x0331, 10}, -{ 0x0303, 10}, { 0x02F1, 10}, { 0x02A0, 10}, { 0x0233, 10}, { 0x0126, 10}, { 0x07C0, 11}, -{ 0x076F, 11}, { 0x076C, 11}, { 0x0661, 11}, { 0x0604, 11}, { 0x0572, 11}, { 0x0551, 11}, -{ 0x046A, 11}, { 0x0274, 11}, { 0x0F27, 12}, { 0x0F24, 12}, { 0x0EDB, 12}, { 0x0C8E, 12}, -{ 0x0C0B, 12}, { 0x0C0A, 12}, { 0x0AE3, 12}, { 0x08D6, 12}, { 0x0490, 12}, { 0x0495, 12}, -{ 0x1F19, 13}, { 0x1DB5, 13}, { 0x0009, 4}, { 0x0010, 5}, { 0x0029, 6}, { 0x0062, 7}, -{ 0x00F3, 8}, { 0x00AD, 8}, { 0x01E5, 9}, { 0x0179, 9}, { 0x009C, 9}, { 0x03B1, 10}, -{ 0x02AE, 10}, { 0x0127, 10}, { 0x076E, 11}, { 0x0570, 11}, { 0x0275, 11}, { 0x0F25, 12}, -{ 0x0EC0, 12}, { 0x0AA0, 12}, { 0x08D7, 12}, { 0x1E4C, 13}, { 0x0008, 5}, { 0x0063, 7}, -{ 0x00AF, 8}, { 0x017B, 9}, { 0x03B3, 10}, { 0x07DD, 11}, { 0x0640, 11}, { 0x0F8D, 12}, -{ 0x0BC1, 12}, { 0x0491, 12}, { 0x0028, 6}, { 0x00C3, 8}, { 0x0151, 9}, { 0x02A1, 10}, -{ 0x0573, 11}, { 0x0EC3, 12}, { 0x1F35, 13}, { 0x0065, 7}, { 0x01DA, 9}, { 0x02AF, 10}, -{ 0x0277, 11}, { 0x08C9, 12}, { 0x1781, 13}, { 0x0025, 7}, { 0x0118, 9}, { 0x0646, 11}, -{ 0x0AA6, 12}, { 0x1780, 13}, { 0x00C9, 8}, { 0x0321, 10}, { 0x0F9B, 12}, { 0x191E, 13}, -{ 0x0048, 8}, { 0x07CC, 11}, { 0x0AA1, 12}, { 0x0180, 9}, { 0x0465, 11}, { 0x1905, 13}, -{ 0x03E2, 10}, { 0x0EC1, 12}, { 0x3C9B, 14}, { 0x02F4, 10}, { 0x08C8, 12}, { 0x07C1, 11}, -{ 0x0928, 13}, { 0x05E1, 11}, { 0x320D, 14}, { 0x0EC2, 12}, { 0x6418, 15}, { 0x1F34, 13}, -{ 0x0078, 7}, { 0x0155, 9}, { 0x0552, 11}, { 0x191F, 13}, { 0x00FA, 8}, { 0x07DC, 11}, -{ 0x1907, 13}, { 0x00AC, 8}, { 0x0249, 11}, { 0x13B1, 14}, { 0x01F6, 9}, { 0x0AE2, 12}, -{ 0x01DC, 9}, { 0x04ED, 12}, { 0x0184, 9}, { 0x1904, 13}, { 0x0156, 9}, { 0x09D9, 13}, -{ 0x03E7, 10}, { 0x0929, 13}, { 0x03B2, 10}, { 0x3B68, 14}, { 0x02F5, 10}, { 0x13B0, 14}, -{ 0x0322, 10}, { 0x3B69, 14}, { 0x0234, 10}, { 0x7935, 15}, { 0x07C7, 11}, { 0xC833, 16}, -{ 0x0660, 11}, { 0x7934, 15}, { 0x024B, 11}, { 0xC832, 16}, { 0x0AA7, 12}, { 0x1F18, 13}, -{ 0x007A, 7} -}, -{ -{ 0x0002, 2}, { 0x0000, 3}, { 0x001E, 5}, { 0x0004, 5}, { 0x0012, 6}, { 0x0070, 7}, -{ 0x001A, 7}, { 0x005F, 8}, { 0x0047, 8}, { 0x01D3, 9}, { 0x00B5, 9}, { 0x0057, 9}, -{ 0x03B5, 10}, { 0x016D, 10}, { 0x0162, 10}, { 0x07CE, 11}, { 0x0719, 11}, { 0x0691, 11}, -{ 0x02C6, 11}, { 0x0156, 11}, { 0x0F92, 12}, { 0x0D2E, 12}, { 0x0D20, 12}, { 0x059E, 12}, -{ 0x0468, 12}, { 0x02A6, 12}, { 0x1DA2, 13}, { 0x1C60, 13}, { 0x1A43, 13}, { 0x0B1D, 13}, -{ 0x08C0, 13}, { 0x055D, 13}, { 0x0003, 3}, { 0x000A, 5}, { 0x0077, 7}, { 0x00E5, 8}, -{ 0x01D9, 9}, { 0x03E5, 10}, { 0x0166, 10}, { 0x0694, 11}, { 0x0152, 11}, { 0x059F, 12}, -{ 0x1F3C, 13}, { 0x1A4B, 13}, { 0x055E, 13}, { 0x000C, 4}, { 0x007D, 7}, { 0x0044, 8}, -{ 0x03E0, 10}, { 0x0769, 11}, { 0x0E31, 12}, { 0x1F26, 13}, { 0x055C, 13}, { 0x001B, 5}, -{ 0x00E2, 8}, { 0x03A5, 10}, { 0x02C9, 11}, { 0x1F23, 13}, { 0x3B47, 14}, { 0x0007, 5}, -{ 0x01D8, 9}, { 0x02D8, 11}, { 0x1F27, 13}, { 0x3494, 14}, { 0x0035, 6}, { 0x03E1, 10}, -{ 0x059C, 12}, { 0x38C3, 14}, { 0x000C, 6}, { 0x0165, 10}, { 0x1D23, 13}, { 0x1638, 14}, -{ 0x0068, 7}, { 0x0693, 11}, { 0x3A45, 14}, { 0x0020, 7}, { 0x0F90, 12}, { 0x7CF6, 15}, -{ 0x00E8, 8}, { 0x058F, 12}, { 0x2CEF, 15}, { 0x0045, 8}, { 0x0B3A, 13}, { 0x01F1, 9}, -{ 0x3B46, 14}, { 0x01A7, 9}, { 0x1676, 14}, { 0x0056, 9}, { 0x692A, 15}, { 0x038D, 10}, -{ 0xE309, 16}, { 0x00AA, 10}, { 0x1C611, 17}, { 0x02DF, 11}, { 0xB3B9, 17}, { 0x02C8, 11}, -{ 0x38C20, 18}, { 0x01B0, 11}, { 0x16390, 18}, { 0x0F9F, 12}, { 0x16771, 18}, { 0x0ED0, 12}, -{ 0x71843, 19}, { 0x0D2A, 12}, { 0xF9E8C, 20}, { 0x0461, 12}, { 0xF9E8E, 20}, { 0x0B67, 13}, -{ 0x055F, 13}, { 0x003F, 6}, { 0x006D, 9}, { 0x0E90, 12}, { 0x054E, 13}, { 0x0013, 6}, -{ 0x0119, 10}, { 0x0B66, 13}, { 0x000B, 6}, { 0x0235, 11}, { 0x7CF5, 15}, { 0x0075, 7}, -{ 0x0D24, 12}, { 0xF9E9, 16}, { 0x002E, 7}, { 0x1F22, 13}, { 0x0021, 7}, { 0x054F, 13}, -{ 0x0014, 7}, { 0x3A44, 14}, { 0x00E4, 8}, { 0x7CF7, 15}, { 0x005E, 8}, { 0x7185, 15}, -{ 0x0037, 8}, { 0x2C73, 15}, { 0x01DB, 9}, { 0x59DD, 16}, { 0x01C7, 9}, { 0x692B, 15}, -{ 0x01A6, 9}, { 0x58E5, 16}, { 0x00B4, 9}, { 0x1F3D0, 17}, { 0x00B0, 9}, { 0xB1C9, 17}, -{ 0x03E6, 10}, { 0x16770, 18}, { 0x016E, 10}, { 0x3E7A2, 18}, { 0x011B, 10}, { 0xF9E8D, 20}, -{ 0x00D9, 10}, { 0xF9E8F, 20}, { 0x00A8, 10}, { 0x2C723, 19}, { 0x0749, 11}, { 0xE3084, 20}, -{ 0x0696, 11}, { 0x58E45, 20}, { 0x02DE, 11}, { 0xB1C88, 21}, { 0x0231, 11}, { 0x1C610A, 21}, -{ 0x01B1, 11}, { 0x71842D, 23}, { 0x0D2B, 12}, { 0x38C217, 22}, { 0x0D2F, 12}, { 0x163913, 22}, -{ 0x05B2, 12}, { 0x163912, 22}, { 0x0469, 12}, { 0x71842C, 23}, { 0x1A42, 13}, { 0x08C1, 13}, -{ 0x0073, 7} -} -}; - -/* which indexes point to last=1 entries in tables */ -static const int vc1_last_decode_table[AC_MODES] = { - 119, 99, 85, 81, 67, 58, 126, 109 -}; - -static const uint8_t vc1_index_decode_table[AC_MODES][185][2] = { -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16}, -{ 0, 17}, { 0, 18}, { 0, 19}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, -{ 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13}, -{ 1, 14}, { 1, 15}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 2, 6}, -{ 2, 7}, { 2, 8}, { 2, 9}, { 2, 10}, { 2, 11}, { 2, 12}, { 3, 1}, { 3, 2}, -{ 3, 3}, { 3, 4}, { 3, 5}, { 3, 6}, { 3, 7}, { 3, 8}, { 3, 9}, { 3, 10}, -{ 3, 11}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 4, 6}, { 5, 1}, -{ 5, 2}, { 5, 3}, { 5, 4}, { 5, 5}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, -{ 7, 1}, { 7, 2}, { 7, 3}, { 7, 4}, { 8, 1}, { 8, 2}, { 8, 3}, { 8, 4}, -{ 9, 1}, { 9, 2}, { 9, 3}, { 9, 4}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, -{ 11, 2}, { 11, 3}, { 12, 1}, { 12, 2}, { 12, 3}, { 13, 1}, { 13, 2}, { 13, 3}, -{ 14, 1}, { 14, 2}, { 14, 3}, { 15, 1}, { 15, 2}, { 15, 3}, { 16, 1}, { 16, 2}, -{ 17, 1}, { 17, 2}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, -{ 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 0, 1}, -{ 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 1, 1}, { 1, 2}, { 1, 3}, -{ 1, 4}, { 1, 5}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2}, -{ 3, 3}, { 3, 4}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 6, 1}, -{ 6, 2}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, -{ 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, -{ 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, -{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, -{ 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1}, -{ 37, 1} -}, -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16}, -{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 1, 1}, -{ 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, -{ 1, 10}, { 1, 11}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 2, 6}, -{ 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5}, { 3, 6}, -{ 3, 7}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 5, 1}, { 5, 2}, -{ 5, 3}, { 5, 4}, { 5, 5}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1}, -{ 7, 2}, { 7, 3}, { 7, 4}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, -{ 9, 3}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, { 11, 2}, { 11, 3}, { 12, 1}, -{ 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, -{ 16, 2}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, -{ 24, 1}, { 25, 1}, { 26, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, -{ 0, 6}, { 0, 7}, { 0, 8}, { 0, 9}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, -{ 1, 5}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2}, { 3, 3}, -{ 3, 4}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1}, -{ 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, -{ 10, 1}, { 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, -{ 14, 1}, { 14, 2}, { 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, -{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, -{ 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1} -}, -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16}, -{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, -{ 1, 9}, { 1, 10}, { 1, 11}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, -{ 2, 6}, { 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 3, 5}, -{ 3, 6}, { 3, 7}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, { 5, 1}, -{ 5, 2}, { 5, 3}, { 5, 4}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1}, -{ 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, { 9, 3}, -{ 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, { 11, 2}, { 11, 3}, { 12, 1}, { 12, 2}, -{ 12, 3}, { 13, 1}, { 13, 2}, { 13, 3}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, -{ 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 0, 1}, { 0, 2}, { 0, 3}, -{ 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 2, 1}, { 2, 2}, { 2, 3}, -{ 3, 1}, { 3, 2}, { 3, 3}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, -{ 6, 2}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, -{ 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, -{ 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, -{ 23, 1}, { 24, 1}, { 25, 1}, { 26, 1} -}, -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 1, 1}, { 1, 2}, -{ 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 2, 1}, -{ 2, 2}, { 2, 3}, { 2, 4}, { 2, 5}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, -{ 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, -{ 6, 1}, { 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, -{ 8, 3}, { 9, 1}, { 9, 2}, { 9, 3}, { 10, 1}, { 10, 2}, { 10, 3}, { 11, 1}, -{ 11, 2}, { 11, 3}, { 12, 1}, { 12, 2}, { 12, 3}, { 13, 1}, { 13, 2}, { 14, 1}, -{ 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, -{ 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, -{ 29, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 1, 1}, { 1, 2}, -{ 1, 3}, { 1, 4}, { 2, 1}, { 2, 2}, { 2, 3}, { 3, 1}, { 3, 2}, { 3, 3}, -{ 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2}, { 7, 1}, { 7, 2}, -{ 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2}, { 11, 1}, { 11, 2}, -{ 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, -{ 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, -{ 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 31, 1}, -{ 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1}, { 37, 1}, { 38, 1}, { 39, 1}, -{ 40, 1}, { 41, 1}, { 42, 1}, { 43, 1} -}, -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16}, -{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24}, -{ 0, 25}, { 0, 26}, { 0, 27}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, -{ 1, 6}, { 1, 7}, { 1, 8}, { 1, 9}, { 1, 10}, { 2, 1}, { 2, 2}, { 2, 3}, -{ 2, 4}, { 2, 5}, { 3, 1}, { 3, 2}, { 3, 3}, { 3, 4}, { 4, 1}, { 4, 2}, -{ 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1}, { 6, 2}, { 6, 3}, { 7, 1}, -{ 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 11, 1}, -{ 12, 1}, { 13, 1}, { 14, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, -{ 0, 6}, { 0, 7}, { 0, 8}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2}, -{ 3, 1}, { 3, 2}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2}, -{ 7, 1}, { 8, 1}, { 9, 1}, { 10, 1}, { 11, 1}, { 12, 1}, { 13, 1}, { 14, 1}, -{ 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1} -}, -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, -{ 1, 5}, { 1, 6}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, { 3, 1}, { 3, 2}, -{ 3, 3}, { 4, 1}, { 4, 2}, { 4, 3}, { 5, 1}, { 5, 2}, { 5, 3}, { 6, 1}, -{ 6, 2}, { 6, 3}, { 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, -{ 10, 1}, { 10, 2}, { 11, 1}, { 12, 1}, { 13, 1}, { 14, 1}, { 15, 1}, { 16, 1}, -{ 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, -{ 25, 1}, { 26, 1}, { 0, 1}, { 0, 2}, { 0, 3}, { 1, 1}, { 1, 2}, { 2, 1}, -{ 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1}, { 8, 1}, { 9, 1}, { 10, 1}, -{ 11, 1}, { 12, 1}, { 13, 1}, { 14, 1}, { 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, -{ 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, -{ 27, 1}, { 28, 1}, { 29, 1}, { 30, 1}, { 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, -{ 35, 1}, { 36, 1}, { 37, 1}, { 38, 1}, { 39, 1}, { 40, 1} -}, -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16}, -{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24}, -{ 0, 25}, { 0, 26}, { 0, 27}, { 0, 28}, { 0, 29}, { 0, 30}, { 0, 31}, { 0, 32}, -{ 0, 33}, { 0, 34}, { 0, 35}, { 0, 36}, { 0, 37}, { 0, 38}, { 0, 39}, { 0, 40}, -{ 0, 41}, { 0, 42}, { 0, 43}, { 0, 44}, { 0, 45}, { 0, 46}, { 0, 47}, { 0, 48}, -{ 0, 49}, { 0, 50}, { 0, 51}, { 0, 52}, { 0, 53}, { 0, 54}, { 0, 55}, { 0, 56}, -{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, -{ 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13}, { 1, 14}, { 1, 15}, { 1, 16}, -{ 1, 17}, { 1, 18}, { 1, 19}, { 1, 20}, { 2, 1}, { 2, 2}, { 2, 3}, { 2, 4}, -{ 2, 5}, { 2, 6}, { 2, 7}, { 2, 8}, { 2, 9}, { 2, 10}, { 3, 1}, { 3, 2}, -{ 3, 3}, { 3, 4}, { 3, 5}, { 3, 6}, { 3, 7}, { 4, 1}, { 4, 2}, { 4, 3}, -{ 4, 4}, { 4, 5}, { 4, 6}, { 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 5, 5}, -{ 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, { 7, 1}, { 7, 2}, { 7, 3}, { 8, 1}, -{ 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, { 9, 3}, { 10, 1}, { 10, 2}, { 11, 1}, -{ 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 0, 1}, { 0, 2}, -{ 0, 3}, { 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2}, { 2, 3}, -{ 3, 1}, { 3, 2}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2}, -{ 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2}, -{ 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, -{ 15, 1}, { 16, 1} -}, -{ -{ 0, 1}, { 0, 2}, { 0, 3}, { 0, 4}, { 0, 5}, { 0, 6}, { 0, 7}, { 0, 8}, -{ 0, 9}, { 0, 10}, { 0, 11}, { 0, 12}, { 0, 13}, { 0, 14}, { 0, 15}, { 0, 16}, -{ 0, 17}, { 0, 18}, { 0, 19}, { 0, 20}, { 0, 21}, { 0, 22}, { 0, 23}, { 0, 24}, -{ 0, 25}, { 0, 26}, { 0, 27}, { 0, 28}, { 0, 29}, { 0, 30}, { 0, 31}, { 0, 32}, -{ 1, 1}, { 1, 2}, { 1, 3}, { 1, 4}, { 1, 5}, { 1, 6}, { 1, 7}, { 1, 8}, -{ 1, 9}, { 1, 10}, { 1, 11}, { 1, 12}, { 1, 13}, { 2, 1}, { 2, 2}, { 2, 3}, -{ 2, 4}, { 2, 5}, { 2, 6}, { 2, 7}, { 2, 8}, { 3, 1}, { 3, 2}, { 3, 3}, -{ 3, 4}, { 3, 5}, { 3, 6}, { 4, 1}, { 4, 2}, { 4, 3}, { 4, 4}, { 4, 5}, -{ 5, 1}, { 5, 2}, { 5, 3}, { 5, 4}, { 6, 1}, { 6, 2}, { 6, 3}, { 6, 4}, -{ 7, 1}, { 7, 2}, { 7, 3}, { 8, 1}, { 8, 2}, { 8, 3}, { 9, 1}, { 9, 2}, -{ 9, 3}, { 10, 1}, { 10, 2}, { 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, -{ 13, 2}, { 14, 1}, { 14, 2}, { 15, 1}, { 15, 2}, { 16, 1}, { 16, 2}, { 17, 1}, -{ 17, 2}, { 18, 1}, { 18, 2}, { 19, 1}, { 19, 2}, { 20, 1}, { 20, 2}, { 21, 1}, -{ 21, 2}, { 22, 1}, { 22, 2}, { 23, 1}, { 24, 1}, { 0, 1}, { 0, 2}, { 0, 3}, -{ 0, 4}, { 1, 1}, { 1, 2}, { 1, 3}, { 2, 1}, { 2, 2}, { 2, 3}, { 3, 1}, -{ 3, 2}, { 3, 3}, { 4, 1}, { 4, 2}, { 5, 1}, { 5, 2}, { 6, 1}, { 6, 2}, -{ 7, 1}, { 7, 2}, { 8, 1}, { 8, 2}, { 9, 1}, { 9, 2}, { 10, 1}, { 10, 2}, -{ 11, 1}, { 11, 2}, { 12, 1}, { 12, 2}, { 13, 1}, { 13, 2}, { 14, 1}, { 14, 2}, -{ 15, 1}, { 15, 2}, { 16, 1}, { 16, 2}, { 17, 1}, { 17, 2}, { 18, 1}, { 18, 2}, -{ 19, 1}, { 19, 2}, { 20, 1}, { 20, 2}, { 21, 1}, { 21, 2}, { 22, 1}, { 22, 2}, -{ 23, 1}, { 23, 2}, { 24, 1}, { 24, 2}, { 25, 1}, { 25, 2}, { 26, 1}, { 26, 2}, -{ 27, 1}, { 27, 2}, { 28, 1}, { 28, 2}, { 29, 1}, { 30, 1} -} -}; - -static const uint8_t vc1_delta_level_table[AC_MODES][31] = { -{ - 19, 15, 12, 11, 6, 5, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1 -}, -{ - 23, 11, 8, 7, 5, 5, 4, 4, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 -}, -{ - 16, 11, 8, 7, 5, 4, 4, 3, 3, 3, - 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, - 1 -}, -{ - 14, 9, 5, 4, 4, 4, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1 -}, -{ - 27, 10, 5, 4, 3, 3, 3, 3, 2, 2, - 1, 1, 1, 1, 1 -}, -{ - 12, 6, 4, 3, 3, 3, 3, 2, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 -}, -{ - 56, 20, 10, 7, 6, 5, 4, 3, 3, 3, - 2, 2, 2, 2, 1 -}, -{ - 32, 13, 8, 6, 5, 4, 4, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 1 -} -}; - -static const uint8_t vc1_last_delta_level_table[AC_MODES][44] = { -{ - 6, 5, 4, 4, 3, 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 -}, -{ - 9, 5, 4, 4, 3, 3, 3, 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 -}, -{ - 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 -}, -{ - 5, 4, 3, 3, 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 -}, -{ - 8, 3, 2, 2, 2, 2, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1 -}, -{ - 3, 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 -}, -{ - 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 1 -}, -{ - 4, 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, 1, - 1 -} -}; - -static const uint8_t vc1_delta_run_table[AC_MODES][57] = { -{ - -1, 30, 17, 15, 9, 5, 4, 3, 3, 3, - 3, 3, 2, 1, 1, 1, 0, 0, 0, - 0 -}, -{ - -1, 26, 16, 11, 7, 5, 3, 3, 2, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}, -{ - -1, 20, 15, 13, 6, 4, 3, 3, 2, 1, - 1, 1, 0, 0, 0, 0, 0 -}, -{ - -1, 29, 15, 12, 5, 2, 1, 1, 1, 1, - 0, 0, 0, 0, 0 -}, -{ - -1, 14, 9, 7, 3, 2, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}, -{ - -1, 26, 10, 6, 2, 1, 1, 0, 0, 0, - 0, 0, 0 -}, -{ - -1, 14, 13, 9, 6, 5, 4, 3, 2, 2, - 2, 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 -}, -{ - -1, 24, 22, 9, 6, 4, 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 -} -}; - -static const uint8_t vc1_last_delta_run_table[AC_MODES][10] = { -{ - -1, 37, 15, 4, 3, 1, 0 -}, -{ - -1, 36, 14, 6, 3, 1, 0, 0, 0, - 0 -}, -{ - -1, 26, 13, 3, 1 -}, -{ - -1, 43, 15, 3, 1, 0 -}, -{ - -1, 20, 6, 1, 0, 0, 0, 0, 0 -}, -{ - -1, 40, 1, 0 -}, -{ - -1, 16, 14, 2, 0 -}, -{ - -1, 30, 28, 3, 0 -} -}; - -#endif /* AVCODEC_VC1ACDATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vc1data.c b/tizen/distrib/ffmpeg/libavcodec/vc1data.c deleted file mode 100644 index 5298079..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vc1data.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * VC-1 and WMV3 decoder - * copyright (c) 2006 Konstantin Shishkov - * (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VC-1 tables. - */ - -#include "avcodec.h" -#include "vc1.h" -#include "vc1data.h" - -/** Table for conversion between TTBLK and TTMB */ -const int ff_vc1_ttblk_to_tt[3][8] = { - { TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT }, - { TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP }, - { TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP } -}; - -const int ff_vc1_ttfrm_to_tt[4] = { TT_8X8, TT_8X4, TT_4X8, TT_4X4 }; - -/** MV P mode - the 5th element is only used for mode 1 */ -const uint8_t ff_vc1_mv_pmode_table[2][5] = { - { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV }, - { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN } -}; -const uint8_t ff_vc1_mv_pmode_table2[2][4] = { - { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV }, - { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN } -}; - -const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 }, - ff_vc1_fps_dr[2] = { 1000, 1001 }; -const uint8_t ff_vc1_pquant_table[3][32] = { - { /* Implicit quantizer */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31 - }, - { /* Explicit quantizer, pquantizer uniform */ - 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 - }, - { /* Explicit quantizer, pquantizer non-uniform */ - 0, 1, 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, 29, 31 - } -}; - -/** @name VC-1 VLC tables and defines - * @todo TODO move this into the context - */ -//@{ -#define VC1_BFRACTION_VLC_BITS 7 -VLC ff_vc1_bfraction_vlc; -#define VC1_IMODE_VLC_BITS 4 -VLC ff_vc1_imode_vlc; -#define VC1_NORM2_VLC_BITS 3 -VLC ff_vc1_norm2_vlc; -#define VC1_NORM6_VLC_BITS 9 -VLC ff_vc1_norm6_vlc; -/* Could be optimized, one table only needs 8 bits */ -#define VC1_TTMB_VLC_BITS 9 //12 -VLC ff_vc1_ttmb_vlc[3]; -#define VC1_MV_DIFF_VLC_BITS 9 //15 -VLC ff_vc1_mv_diff_vlc[4]; -#define VC1_CBPCY_P_VLC_BITS 9 //14 -VLC ff_vc1_cbpcy_p_vlc[4]; -#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6 -VLC ff_vc1_4mv_block_pattern_vlc[4]; -#define VC1_TTBLK_VLC_BITS 5 -VLC ff_vc1_ttblk_vlc[3]; -#define VC1_SUBBLKPAT_VLC_BITS 6 -VLC ff_vc1_subblkpat_vlc[3]; - -VLC ff_vc1_ac_coeff_table[8]; -//@} - - -#if B_FRACTION_DEN==840 //original bfraction from vc9data.h, not conforming to standard -/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */ -const int16_t ff_vc1_bfraction_lut[23] = { - 420 /*1/2*/, 280 /*1/3*/, 560 /*2/3*/, 210 /*1/4*/, - 630 /*3/4*/, 168 /*1/5*/, 336 /*2/5*/, - 504 /*3/5*/, 672 /*4/5*/, 140 /*1/6*/, 700 /*5/6*/, - 120 /*1/7*/, 240 /*2/7*/, 360 /*3/7*/, 480 /*4/7*/, - 600 /*5/7*/, 720 /*6/7*/, 105 /*1/8*/, 315 /*3/8*/, - 525 /*5/8*/, 735 /*7/8*/, - -1 /*inv.*/, 0 /*BI fm*/ -}; -#else -/* pre-computed scales for all bfractions and base=256 */ -const int16_t ff_vc1_bfraction_lut[23] = { - 128 /*1/2*/, 85 /*1/3*/, 170 /*2/3*/, 64 /*1/4*/, - 192 /*3/4*/, 51 /*1/5*/, 102 /*2/5*/, - 153 /*3/5*/, 204 /*4/5*/, 43 /*1/6*/, 215 /*5/6*/, - 37 /*1/7*/, 74 /*2/7*/, 111 /*3/7*/, 148 /*4/7*/, - 185 /*5/7*/, 222 /*6/7*/, 32 /*1/8*/, 96 /*3/8*/, - 160 /*5/8*/, 224 /*7/8*/, - -1 /*inv.*/, 0 /*BI fm*/ -}; -#endif - -const uint8_t ff_vc1_bfraction_bits[23] = { - 3, 3, 3, 3, - 3, 3, 3, - 7, 7, 7, 7, - 7, 7, 7, 7, - 7, 7, 7, 7, - 7, 7, - 7, 7 -}; -const uint8_t ff_vc1_bfraction_codes[23] = { - 0, 1, 2, 3, - 4, 5, 6, - 112, 113, 114, 115, - 116, 117, 118, 119, - 120, 121, 122, 123, - 124, 125, - 126, 127 -}; - -//Same as H.264 -const AVRational ff_vc1_pixel_aspect[16]={ - {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}, - {0, 1}, - {0, 1} -}; - -/* BitPlane IMODE - such a small table... */ -const uint8_t ff_vc1_imode_codes[7] = { - 0, 2, 1, 3, 1, 2, 3 -}; -const uint8_t ff_vc1_imode_bits[7] = { - 4, 2, 3, 2, 4, 3, 3 -}; - -/* Normal-2 imode */ -const uint8_t ff_vc1_norm2_codes[4] = { - 0, 4, 5, 3 -}; -const uint8_t ff_vc1_norm2_bits[4] = { - 1, 3, 3, 2 -}; - -const uint16_t ff_vc1_norm6_codes[64] = { -0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E, -0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037, -0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036, -0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007, -}; - -const uint8_t ff_vc1_norm6_bits[64] = { - 1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13, - 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, - 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, - 8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6, -}; -#if 0 -/* Normal-6 imode */ -const uint8_t ff_vc1_norm6_spec[64][5] = { -{ 0, 1, 1 }, -{ 1, 2, 4 }, -{ 2, 3, 4 }, -{ 3, 0, 8 }, -{ 4, 4, 4 }, -{ 5, 1, 8 }, -{ 6, 2, 8 }, -{ 7, 2, 5, 7, 5 }, -{ 8, 5, 4 }, -{ 9, 3, 8 }, -{10, 4, 8 }, -{11, 2, 5, 11, 5 }, -{12, 5, 8 }, -{13, 2, 5, 13, 5 }, -{14, 2, 5, 14, 5 }, -{15, 3, 5, 14, 8 }, -{16, 6, 4 }, -{17, 6, 8 }, -{18, 7, 8 }, -{19, 2, 5, 19, 5 }, -{20, 8, 8 }, -{21, 2, 5, 21, 5 }, -{22, 2, 5, 22, 5 }, -{23, 3, 5, 13, 8 }, -{24, 9, 8 }, -{25, 2, 5, 25, 5 }, -{26, 2, 5, 26, 5 }, -{27, 3, 5, 12, 8 }, -{28, 2, 5, 28, 5 }, -{29, 3, 5, 11, 8 }, -{30, 3, 5, 10, 8 }, -{31, 3, 5, 7, 4 }, -{32, 7, 4 }, -{33, 10, 8 }, -{34, 11, 8 }, -{35, 2, 5, 3, 5 }, -{36, 12, 8 }, -{37, 2, 5, 5, 5 }, -{38, 2, 5, 6, 5 }, -{39, 3, 5, 9, 8 }, -{40, 13, 8 }, -{41, 2, 5, 9, 5 }, -{42, 2, 5, 10, 5 }, -{43, 3, 5, 8, 8 }, -{44, 2, 5, 12, 5 }, -{45, 3, 5, 7, 8 }, -{46, 3, 5, 6, 8 }, -{47, 3, 5, 6, 4 }, -{48, 14, 8 }, -{49, 2, 5, 17, 5 }, -{50, 2, 5, 18, 5 }, -{51, 3, 5, 5, 8 }, -{52, 2, 5, 20, 5 }, -{53, 3, 5, 4, 8 }, -{54, 3, 5, 3, 8 }, -{55, 3, 5, 5, 4 }, -{56, 2, 5, 24, 5 }, -{57, 3, 5, 2, 8 }, -{58, 3, 5, 1, 8 }, -{59, 3, 5, 4, 4 }, -{60, 3, 5, 0, 8 }, -{61, 3, 5, 3, 4 }, -{62, 3, 5, 2, 4 }, -{63, 3, 5, 1, 1 }, -}; -#endif - -/* 4MV Block pattern VLC tables */ -const uint8_t ff_vc1_4mv_block_pattern_codes[4][16] = { - { 14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2}, - { 8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0}, - { 15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0}, - { 0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10} -}; -const uint8_t ff_vc1_4mv_block_pattern_bits[4][16] = { - { 5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2}, - { 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2}, - { 4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3}, - { 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4} -}; - -const uint8_t wmv3_dc_scale_table[32]={ - 0, 2, 4, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 -}; - -/* P-Picture CBPCY VLC tables */ -#if 1 // Looks like original tables are not conforming to standard at all. Are they used for old WMV? -const uint16_t ff_vc1_cbpcy_p_codes[4][64] = { - { - 0, 6, 15, 13, 13, 11, 3, 13, 5, 8, 49, 10, 12, 114, 102, 119, - 1, 54, 96, 8, 10, 111, 5, 15, 12, 10, 2, 12, 13, 115, 53, 63, - 1, 7, 1, 7, 14, 12, 4, 14, 1, 9, 97, 11, 7, 58, 52, 62, - 4, 103, 1, 9, 11, 56, 101, 118, 4, 110, 100, 30, 2, 5, 4, 3 - }, - { - 0, 9, 1, 18, 5, 14, 237, 26, 3, 121, 3, 22, 13, 16, 6, 30, - 2, 10, 1, 20, 12, 241, 5, 28, 16, 12, 3, 24, 28, 124, 239, 247, - 1, 240, 1, 19, 18, 15, 4, 27, 1, 122, 2, 23, 1, 17, 7, 31, - 1, 11, 2, 21, 19, 246, 238, 29, 17, 13, 236, 25, 58, 63, 8, 125 - }, - { - 0, 201, 25, 231, 5, 221, 1, 3, 2, 414, 2, 241, 16, 225, 195, 492, - 2, 412, 1, 240, 7, 224, 98, 245, 1, 220, 96, 5, 9, 230, 101, 247, - 1, 102, 1, 415, 24, 3, 2, 244, 3, 54, 3, 484, 17, 114, 200, 493, - 3, 413, 1, 4, 13, 113, 99, 485, 4, 111, 194, 243, 5, 29, 26, 31 - }, - { - 0, 28, 12, 44, 3, 36, 20, 52, 2, 32, 16, 48, 8, 40, 24, 28, - 1, 30, 14, 46, 6, 38, 22, 54, 3, 34, 18, 50, 10, 42, 26, 30, - 1, 29, 13, 45, 5, 37, 21, 53, 2, 33, 17, 49, 9, 41, 25, 29, - 1, 31, 15, 47, 7, 39, 23, 55, 4, 35, 19, 51, 11, 43, 27, 31 - } -}; - -const uint8_t ff_vc1_cbpcy_p_bits[4][64] = { - { - 13, 13, 7, 13, 7, 13, 13, 12, 6, 13, 7, 12, 6, 8, 8, 8, - 5, 7, 8, 12, 6, 8, 13, 12, 7, 13, 13, 12, 6, 8, 7, 7, - 6, 13, 8, 12, 7, 13, 13, 12, 7, 13, 8, 12, 5, 7, 7, 7, - 6, 8, 13, 12, 6, 7, 8, 8, 5, 8, 8, 6, 3, 3, 3, 2 - }, - { - 14, 13, 8, 13, 3, 13, 8, 13, 3, 7, 8, 13, 4, 13, 13, 13, - 3, 13, 13, 13, 4, 8, 13, 13, 5, 13, 13, 13, 5, 7, 8, 8, - 3, 8, 14, 13, 5, 13, 13, 13, 4, 7, 13, 13, 6, 13, 13, 13, - 5, 13, 8, 13, 5, 8, 8, 13, 5, 13, 8, 13, 6, 6, 13, 7 - }, - { - 13, 8, 6, 8, 4, 8, 13, 12, 4, 9, 8, 8, 5, 8, 8, 9, - 5, 9, 10, 8, 4, 8, 7, 8, 6, 8, 7, 13, 4, 8, 7, 8, - 5, 7, 8, 9, 6, 13, 13, 8, 4, 6, 8, 9, 5, 7, 8, 9, - 5, 9, 9, 13, 5, 7, 7, 9, 4, 7, 8, 8, 3, 5, 5, 5 - }, - { - 9, 9, 9, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 8, - 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, - 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8 - } -}; -#else -const uint16_t ff_vc1_cbpcy_p_codes[4][64] = { - { - 0, 1, 1, 4, 5, 1, 12, 4, 13, 14, 10, 11, 12, 7, 13, 2, - 15, 1, 96, 1, 49, 97, 2, 100, 3, 4, 5, 101, 102, 52, 53, 4, - 6, 7, 54, 103, 8, 9, 10, 110, 11, 12, 111, 56, 114, 58, 115, 5, - 13, 7, 8, 9, 10, 11, 12, 30, 13, 14, 15, 118, 119, 62, 63, 3 - }, - { - 0, 1, 2, 1, 3, 1, 16, 17, 5, 18, 12, 19, 13, 1, 28, 58, - 1, 1, 1, 2, 3, 2, 3, 236, 237, 4, 5, 238, 6, 7, 239, 8, - 9, 240, 10, 11, 121, 122, 12, 13, 14, 15, 241, 246, 16, 17, 124, 63, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 247, 125 - }, - { - 0, 1, 2, 3, 2, 3, 1, 4, 5, 24, 7, 13, 16, 17, 9, 5, - 25, 1, 1, 1, 2, 3, 96, 194, 1, 2, 98, 99, 195, 200, 101, 26, - 201, 102, 412, 413, 414, 54, 220, 111, 221, 3, 224, 113, 225, 114, 230, 29, - 231, 415, 240, 4, 241, 484, 5, 243, 3, 244, 245, 485, 492, 493, 247, 31 - }, - { - 0, 1, 1, 1, 2, 2, 3, 4, 3, 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, 28, 29, 30, 31 - } -}; -const uint8_t ff_vc1_cbpcy_p_bits[4][64] = { - { - 13, 6, 5, 6, 6, 7, 7, 5, 7, 7, 6, 6, 6, 5, 6, 3, - 7, 8, 8, 13, 7, 8, 13, 8, 13, 13, 13, 8, 8, 7, 7, 3, - 13, 13, 7, 8, 13, 13, 13, 8, 13, 13, 8, 7, 8, 7, 8, 3, - 13, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 8, 8, 7, 7, 2 - }, - { - 14, 3, 3, 5, 3, 4, 5, 5, 3, 5, 4, 5, 4, 6, 5, 6, - 8, 14, 13, 8, 8, 13, 13, 8, 8, 13, 13, 8, 13, 13, 8, 13, - 13, 8, 13, 13, 7, 7, 13, 13, 13, 13, 8, 8, 13, 13, 7, 6, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 7 - }, - { - 13, 5, 5, 5, 4, 4, 6, 4, 4, 6, 4, 5, 5, 5, 4, 3, - 6, 8, 10, 9, 8, 8, 7, 8, 13, 13, 7, 7, 8, 8, 7, 5, - 8, 7, 9, 9, 9, 6, 8, 7, 8, 13, 8, 7, 8, 7, 8, 5, - 8, 9, 8, 13, 8, 9, 13, 8, 12, 8, 8, 9, 9, 9, 8, 5 - }, - { - 9, 2, 3, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8 - } -}; -#endif - -/* MacroBlock Transform Type: 7.1.3.11, p89 - * 8x8:B - * 8x4:B:btm 8x4:B:top 8x4:B:both, - * 4x8:B:right 4x8:B:left 4x8:B:both - * 4x4:B 8x8:MB - * 8x4:MB:btm 8x4:MB:top 8x4,MB,both - * 4x8,MB,right 4x8,MB,left - * 4x4,MB */ -const uint16_t ff_vc1_ttmb_codes[3][16] = { - { - 0x0003, - 0x002E, 0x005F, 0x0000, - 0x0016, 0x0015, 0x0001, - 0x0004, 0x0014, - 0x02F1, 0x0179, 0x017B, - 0x0BC0, 0x0BC1, 0x05E1, - 0x017A - }, - { - 0x0006, - 0x0006, 0x0003, 0x0007, - 0x000F, 0x000E, 0x0000, - 0x0002, 0x0002, - 0x0014, 0x0011, 0x000B, - 0x0009, 0x0021, 0x0015, - 0x0020 - }, - { - 0x0006, - 0x0000, 0x000E, 0x0005, - 0x0002, 0x0003, 0x0003, - 0x000F, 0x0002, - 0x0081, 0x0021, 0x0009, - 0x0101, 0x0041, 0x0011, - 0x0100 - } -}; - -const uint8_t ff_vc1_ttmb_bits[3][16] = { - { - 2, - 6, 7, 2, - 5, 5, 2, - 3, 5, - 10, 9, 9, - 12, 12, 11, - 9 - }, - { - 3, - 4, 4, 4, - 4, 4, 3, - 3, 2, - 7, 7, 6, - 6, 8, 7, - 8 - }, - { - 3, - 3, 4, 5, - 3, 3, 4, - 4, 2, - 10, 8, 6, - 11, 9, 7, - 11 - } -}; - -/* TTBLK (Transform Type per Block) tables */ -const uint8_t ff_vc1_ttblk_codes[3][8] = { - { 0, 1, 3, 5, 16, 17, 18, 19}, - { 3, 0, 1, 2, 3, 5, 8, 9}, - { 1, 0, 1, 4, 6, 7, 10, 11} -}; -const uint8_t ff_vc1_ttblk_bits[3][8] = { - { 2, 2, 2, 3, 5, 5, 5, 5}, - { 2, 3, 3, 3, 3, 3, 4, 4}, - { 2, 3, 3, 3, 3, 3, 4, 4} -}; - -/* SUBBLKPAT tables, p93-94, reordered */ -const uint8_t ff_vc1_subblkpat_codes[3][15] = { - { 14, 12, 7, 11, 9, 26, 2, 10, 27, 8, 0, 6, 1, 15, 1}, - { 14, 0, 8, 15, 10, 4, 23, 13, 5, 9, 25, 3, 24, 22, 1}, - { 5, 6, 2, 2, 8, 0, 28, 3, 1, 3, 29, 1, 19, 18, 15} -}; -const uint8_t ff_vc1_subblkpat_bits[3][15] = { - { 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 4, 5, 1}, - { 4, 3, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 2}, - { 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4} -}; - -/* MV differential tables, p265 */ -const uint16_t ff_vc1_mv_diff_codes[4][73] = { - { - 0, 2, 3, 8, 576, 3, 2, 6, - 5, 577, 578, 7, 8, 9, 40, 19, - 37, 82, 21, 22, 23, 579, 580, 166, - 96, 167, 49, 194, 195, 581, 582, 583, - 292, 293, 294, 13, 2, 7, 24, 50, - 102, 295, 13, 7, 8, 18, 50, 103, - 38, 20, 21, 22, 39, 204, 103, 23, - 24, 25, 104, 410, 105, 106, 107, 108, - 109, 220, 411, 442, 222, 443, 446, 447, - 7 /* 73 elements */ - }, - { - 0, 4, 5, 3, 4, 3, 4, 5, - 20, 6, 21, 44, 45, 46, 3008, 95, - 112, 113, 57, 3009, 3010, 116, 117, 3011, - 118, 3012, 3013, 3014, 3015, 3016, 3017, 3018, - 3019, 3020, 3021, 3022, 1, 4, 15, 160, - 161, 41, 6, 11, 42, 162, 43, 119, - 56, 57, 58, 163, 236, 237, 3023, 119, - 120, 242, 122, 486, 1512, 487, 246, 494, - 1513, 495, 1514, 1515, 1516, 1517, 1518, 1519, - 31 /* 73 elements */ - }, - { - 0, 512, 513, 514, 515, 2, 3, 258, - 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 1, 5, 287, 288, - 289, 290, 6, 7, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, - 319 /* 73 elements */ - }, - { - 0, 1, 1, 2, 3, 4, 1, 5, - 4, 3, 5, 8, 6, 9, 10, 11, - 12, 7, 104, 14, 105, 4, 10, 15, - 11, 6, 14, 8, 106, 107, 108, 15, - 109, 9, 55, 10, 1, 2, 1, 2, - 3, 12, 6, 2, 6, 7, 28, 7, - 15, 8, 5, 18, 29, 152, 77, 24, - 25, 26, 39, 108, 13, 109, 55, 56, - 57, 116, 11, 153, 234, 235, 118, 119, - 15 /* 73 elements */ - } -}; -const uint8_t ff_vc1_mv_diff_bits[4][73] = { - { - 6, 7, 7, 8, 14, 6, 5, 6, 7, 14, 14, 6, 6, 6, 8, 9, - 10, 9, 7, 7, 7, 14, 14, 10, 9, 10, 8, 10, 10, 14, 14, 14, - 13, 13, 13, 6, 3, 5, 6, 8, 9, 13, 5, 4, 4, 5, 7, 9, - 6, 5, 5, 5, 6, 9, 8, 5, 5, 5, 7, 10, 7, 7, 7, 7, - 7, 8, 10, 9, 8, 9, 9, 9, 3 /* 73 elements */ - }, - { - 5, 7, 7, 6, 6, 5, 5, 6, 7, 5, 7, 8, 8, 8, 14, 9, - 9, 9, 8, 14, 14, 9, 9, 14, 9, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 2, 3, 6, 8, 8, 6, 3, 4, 6, 8, 6, 9, - 6, 6, 6, 8, 8, 8, 14, 7, 7, 8, 7, 9, 13, 9, 8, 9, - 13, 9, 13, 13, 13, 13, 13, 13, 5 /* 73 elements */ - - }, - { - 3, 12, 12, 12, 12, 3, 4, 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, 1, 5, 11, 11, 11, 11, 4, 4, 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 /* 73 elements */ - }, - { - 15, 11, 15, 15, 15, 15, 12, 15, 12, 11, 12, 12, 15, 12, 12, 12, - 12, 15, 15, 12, 15, 10, 11, 12, 11, 10, 11, 10, 15, 15, 15, 11, - 15, 10, 14, 10, 4, 4, 5, 7, 8, 9, 5, 3, 4, 5, 6, 8, - 5, 4, 3, 5, 6, 8, 7, 5, 5, 5, 6, 7, 9, 7, 6, 6, - 6, 7, 10, 8, 8, 8, 7, 7, 4 /* 73 elements */ - } -}; - -/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ - -/* Table 232 */ -const int8_t ff_vc1_simple_progressive_4x4_zz [16] = -{ - 0, 8, 16, 1, - 9, 24, 17, 2, - 10, 18, 25, 3, - 11, 26, 19, 27 -}; - -const int8_t ff_vc1_adv_progressive_8x4_zz [32] = /* Table 233 */ -{ - 0, 8, 1, 16, 2, 9, 10, 3, - 24, 17, 4, 11, 18, 12, 5, 19, - 25, 13, 20, 26, 27, 6, 21, 28, - 14, 22, 29, 7, 30, 15, 23, 31 -}; - -const int8_t ff_vc1_adv_progressive_4x8_zz [32] = /* Table 234 */ -{ - 0, 1, 8, 2, - 9, 16, 17, 24, - 10, 32, 25, 18, - 40, 3, 33, 26, - 48, 11, 56, 41, - 34, 49, 57, 42, - 19, 50, 27, 58, - 35, 43, 51, 59 -}; - -const int8_t ff_vc1_adv_interlaced_8x8_zz [64] = /* Table 235 */ -{ - 0, 8, 1, 16, 24, 9, 2, 32, - 40, 48, 56, 17, 10, 3, 25, 18, - 11, 4, 33, 41, 49, 57, 26, 34, - 42, 50, 58, 19, 12, 5, 27, 20, - 13, 6, 35, 28, 21, 14, 7, 15, - 22, 29, 36, 43, 51, 59, 60, 52, - 44, 37, 30, 23, 31, 38, 45, 53, - 61, 62, 54, 46, 39, 47, 55, 63 -}; - -const int8_t ff_vc1_adv_interlaced_8x4_zz [32] = /* Table 236 */ -{ - 0, 8, 16, 24, 1, 9, 2, 17, - 25, 10, 3, 18, 26, 4, 11, 19, - 12, 5, 13, 20, 27, 6, 21, 28, - 14, 22, 29, 7, 30, 15, 23, 31 -}; - -const int8_t ff_vc1_adv_interlaced_4x8_zz [32] = /* Table 237 */ -{ - 0, 1, 2, 8, - 16, 9, 24, 17, - 10, 3, 32, 40, - 48, 56, 25, 18, - 33, 26, 41, 34, - 49, 57, 11, 42, - 19, 50, 27, 58, - 35, 43, 51, 59 -}; - -const int8_t ff_vc1_adv_interlaced_4x4_zz [16] = /* Table 238 */ -{ - 0, 8, 16, 24, - 1, 9, 17, 2, - 25, 10, 18, 3, - 26, 11, 19, 27 -}; - - -/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */ -const int32_t ff_vc1_dqscale[63] = { -0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000, - 0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000, - 0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB, - 0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000, - 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A, - 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555, - 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249, - 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000 -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vc1data.h b/tizen/distrib/ffmpeg/libavcodec/vc1data.h deleted file mode 100644 index 934627a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vc1data.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * VC-1 and WMV3 decoder - * copyright (c) 2006 Konstantin Shishkov - * (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VC-1 tables. - */ - -#ifndef AVCODEC_VC1DATA_H -#define AVCODEC_VC1DATA_H - -#include -#include "libavutil/rational.h" -#include "get_bits.h" - -/** Table for conversion between TTBLK and TTMB */ -extern const int ff_vc1_ttblk_to_tt[3][8]; - -extern const int ff_vc1_ttfrm_to_tt[4]; - -/** MV P mode - the 5th element is only used for mode 1 */ -extern const uint8_t ff_vc1_mv_pmode_table[2][5]; -extern const uint8_t ff_vc1_mv_pmode_table2[2][4]; - -extern const int ff_vc1_fps_nr[5], ff_vc1_fps_dr[2]; -extern const uint8_t ff_vc1_pquant_table[3][32]; - -/** @name VC-1 VLC tables and defines - * @todo TODO move this into the context - */ -//@{ -#define VC1_BFRACTION_VLC_BITS 7 -extern VLC ff_vc1_bfraction_vlc; -#define VC1_IMODE_VLC_BITS 4 -extern VLC ff_vc1_imode_vlc; -#define VC1_NORM2_VLC_BITS 3 -extern VLC ff_vc1_norm2_vlc; -#define VC1_NORM6_VLC_BITS 9 -extern VLC ff_vc1_norm6_vlc; -/* Could be optimized, one table only needs 8 bits */ -#define VC1_TTMB_VLC_BITS 9 //12 -extern VLC ff_vc1_ttmb_vlc[3]; -#define VC1_MV_DIFF_VLC_BITS 9 //15 -extern VLC ff_vc1_mv_diff_vlc[4]; -#define VC1_CBPCY_P_VLC_BITS 9 //14 -extern VLC ff_vc1_cbpcy_p_vlc[4]; -#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6 -extern VLC ff_vc1_4mv_block_pattern_vlc[4]; -#define VC1_TTBLK_VLC_BITS 5 -extern VLC ff_vc1_ttblk_vlc[3]; -#define VC1_SUBBLKPAT_VLC_BITS 6 -extern VLC ff_vc1_subblkpat_vlc[3]; - -extern VLC ff_vc1_ac_coeff_table[8]; -//@} - - -#if 0 //original bfraction from vc9data.h, not conforming to standard -/* Denominator used for ff_vc1_bfraction_lut */ -#define B_FRACTION_DEN 840 - -/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */ -extern const int16_t ff_vc1_bfraction_lut[23]; -#else -/* Denominator used for ff_vc1_bfraction_lut */ -#define B_FRACTION_DEN 256 - -/* pre-computed scales for all bfractions and base=256 */ -extern const int16_t ff_vc1_bfraction_lut[23]; -#endif - -extern const uint8_t ff_vc1_bfraction_bits[23]; -extern const uint8_t ff_vc1_bfraction_codes[23]; - -//Same as H.264 -extern const AVRational ff_vc1_pixel_aspect[16]; - -/* BitPlane IMODE - such a small table... */ -extern const uint8_t ff_vc1_imode_codes[7]; -extern const uint8_t ff_vc1_imode_bits[7]; - -/* Normal-2 imode */ -extern const uint8_t ff_vc1_norm2_codes[4]; -extern const uint8_t ff_vc1_norm2_bits[4]; -extern const uint16_t ff_vc1_norm6_codes[64]; -extern const uint8_t ff_vc1_norm6_bits[64]; -/* Normal-6 imode */ -extern const uint8_t ff_vc1_norm6_spec[64][5]; - -/* 4MV Block pattern VLC tables */ -extern const uint8_t ff_vc1_4mv_block_pattern_codes[4][16]; -extern const uint8_t ff_vc1_4mv_block_pattern_bits[4][16]; - -extern const uint8_t wmv3_dc_scale_table[32]; - -/* P-Picture CBPCY VLC tables */ -extern const uint16_t ff_vc1_cbpcy_p_codes[4][64]; -extern const uint8_t ff_vc1_cbpcy_p_bits[4][64]; - -/* MacroBlock Transform Type: 7.1.3.11, p89 - * 8x8:B - * 8x4:B:btm 8x4:B:top 8x4:B:both, - * 4x8:B:right 4x8:B:left 4x8:B:both - * 4x4:B 8x8:MB - * 8x4:MB:btm 8x4:MB:top 8x4,MB,both - * 4x8,MB,right 4x8,MB,left - * 4x4,MB */ -extern const uint16_t ff_vc1_ttmb_codes[3][16]; - -extern const uint8_t ff_vc1_ttmb_bits[3][16]; - -/* TTBLK (Transform Type per Block) tables */ -extern const uint8_t ff_vc1_ttblk_codes[3][8]; -extern const uint8_t ff_vc1_ttblk_bits[3][8]; - -/* SUBBLKPAT tables, p93-94, reordered */ -extern const uint8_t ff_vc1_subblkpat_codes[3][15]; -extern const uint8_t ff_vc1_subblkpat_bits[3][15]; - -/* MV differential tables, p265 */ -extern const uint16_t ff_vc1_mv_diff_codes[4][73]; -extern const uint8_t ff_vc1_mv_diff_bits[4][73]; - -/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ - -/* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */ -extern const int8_t ff_vc1_simple_progressive_4x4_zz [16]; -extern const int8_t ff_vc1_adv_progressive_8x4_zz [32]; -extern const int8_t ff_vc1_adv_progressive_4x8_zz [32]; -extern const int8_t ff_vc1_adv_interlaced_8x8_zz [64]; -extern const int8_t ff_vc1_adv_interlaced_8x4_zz [32]; -extern const int8_t ff_vc1_adv_interlaced_4x8_zz [32]; -extern const int8_t ff_vc1_adv_interlaced_4x4_zz [16]; - -/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */ -extern const int32_t ff_vc1_dqscale[63]; - -#endif /* AVCODEC_VC1DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vc1dec.c b/tizen/distrib/ffmpeg/libavcodec/vc1dec.c deleted file mode 100644 index 52392c3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vc1dec.c +++ /dev/null @@ -1,3384 +0,0 @@ -/* - * VC-1 and WMV3 decoder - * Copyright (c) 2006-2007 Konstantin Shishkov - * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VC-1 and WMV3 decoder - * - */ -#include "internal.h" -#include "dsputil.h" -#include "avcodec.h" -#include "mpegvideo.h" -#include "h263.h" -#include "vc1.h" -#include "vc1data.h" -#include "vc1acdata.h" -#include "msmpeg4data.h" -#include "unary.h" -#include "simple_idct.h" -#include "mathops.h" -#include "vdpau_internal.h" - -#undef NDEBUG -#include - -#define MB_INTRA_VLC_BITS 9 -#define DC_VLC_BITS 9 -#define AC_VLC_BITS 9 -static const uint16_t table_mb_intra[64][2]; - - -static const uint16_t vlc_offs[] = { - 0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436, - 2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8620, - 9262, 10202, 10756, 11310, 12228, 15078 -}; - -/** - * Init VC-1 specific tables and VC1Context members - * @param v The VC1Context to initialize - * @return Status - */ -static int vc1_init_common(VC1Context *v) -{ - static int done = 0; - int i = 0; - static VLC_TYPE vlc_table[15078][2]; - - v->hrd_rate = v->hrd_buffer = NULL; - - /* VLC tables */ - if(!done) - { - INIT_VLC_STATIC(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, - ff_vc1_bfraction_bits, 1, 1, - ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS); - INIT_VLC_STATIC(&ff_vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4, - ff_vc1_norm2_bits, 1, 1, - ff_vc1_norm2_codes, 1, 1, 1 << VC1_NORM2_VLC_BITS); - INIT_VLC_STATIC(&ff_vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64, - ff_vc1_norm6_bits, 1, 1, - ff_vc1_norm6_codes, 2, 2, 556); - INIT_VLC_STATIC(&ff_vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7, - ff_vc1_imode_bits, 1, 1, - ff_vc1_imode_codes, 1, 1, 1 << VC1_IMODE_VLC_BITS); - for (i=0; i<3; i++) - { - ff_vc1_ttmb_vlc[i].table = &vlc_table[vlc_offs[i*3+0]]; - ff_vc1_ttmb_vlc[i].table_allocated = vlc_offs[i*3+1] - vlc_offs[i*3+0]; - init_vlc(&ff_vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16, - ff_vc1_ttmb_bits[i], 1, 1, - ff_vc1_ttmb_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - ff_vc1_ttblk_vlc[i].table = &vlc_table[vlc_offs[i*3+1]]; - ff_vc1_ttblk_vlc[i].table_allocated = vlc_offs[i*3+2] - vlc_offs[i*3+1]; - init_vlc(&ff_vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8, - ff_vc1_ttblk_bits[i], 1, 1, - ff_vc1_ttblk_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - ff_vc1_subblkpat_vlc[i].table = &vlc_table[vlc_offs[i*3+2]]; - ff_vc1_subblkpat_vlc[i].table_allocated = vlc_offs[i*3+3] - vlc_offs[i*3+2]; - init_vlc(&ff_vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15, - ff_vc1_subblkpat_bits[i], 1, 1, - ff_vc1_subblkpat_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - for(i=0; i<4; i++) - { - ff_vc1_4mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i*3+9]]; - ff_vc1_4mv_block_pattern_vlc[i].table_allocated = vlc_offs[i*3+10] - vlc_offs[i*3+9]; - init_vlc(&ff_vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16, - ff_vc1_4mv_block_pattern_bits[i], 1, 1, - ff_vc1_4mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - ff_vc1_cbpcy_p_vlc[i].table = &vlc_table[vlc_offs[i*3+10]]; - ff_vc1_cbpcy_p_vlc[i].table_allocated = vlc_offs[i*3+11] - vlc_offs[i*3+10]; - init_vlc(&ff_vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64, - ff_vc1_cbpcy_p_bits[i], 1, 1, - ff_vc1_cbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i*3+11]]; - ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i*3+12] - vlc_offs[i*3+11]; - init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, - ff_vc1_mv_diff_bits[i], 1, 1, - ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - for(i=0; i<8; i++){ - ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i+21]]; - ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i+22] - vlc_offs[i+21]; - init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i], - &vc1_ac_tables[i][0][1], 8, 4, - &vc1_ac_tables[i][0][0], 8, 4, INIT_VLC_USE_NEW_STATIC); - } - done = 1; - } - - /* Other defaults */ - v->pq = -1; - v->mvrange = 0; /* 7.1.1.18, p80 */ - - return 0; -} - -/***********************************************************************/ -/** - * @defgroup vc1bitplane VC-1 Bitplane decoding - * @see 8.7, p56 - * @{ - */ - -/** - * Imode types - * @{ - */ -enum Imode { - IMODE_RAW, - IMODE_NORM2, - IMODE_DIFF2, - IMODE_NORM6, - IMODE_DIFF6, - IMODE_ROWSKIP, - IMODE_COLSKIP -}; -/** @} */ //imode defines - - -/** @} */ //Bitplane group - -static void vc1_loop_filter_iblk(MpegEncContext *s, int pq) -{ - int i, j; - if(!s->first_slice_line) - s->dsp.vc1_v_loop_filter16(s->dest[0], s->linesize, pq); - s->dsp.vc1_v_loop_filter16(s->dest[0] + 8*s->linesize, s->linesize, pq); - for(i = !s->mb_x*8; i < 16; i += 8) - s->dsp.vc1_h_loop_filter16(s->dest[0] + i, s->linesize, pq); - for(j = 0; j < 2; j++){ - if(!s->first_slice_line) - s->dsp.vc1_v_loop_filter8(s->dest[j+1], s->uvlinesize, pq); - if(s->mb_x) - s->dsp.vc1_h_loop_filter8(s->dest[j+1], s->uvlinesize, pq); - } -} - -/** Put block onto picture - */ -static void vc1_put_block(VC1Context *v, DCTELEM block[6][64]) -{ - uint8_t *Y; - int ys, us, vs; - DSPContext *dsp = &v->s.dsp; - - if(v->rangeredfrm) { - int i, j, k; - for(k = 0; k < 6; k++) - for(j = 0; j < 8; j++) - for(i = 0; i < 8; i++) - block[k][i + j*8] = ((block[k][i + j*8] - 128) << 1) + 128; - - } - ys = v->s.current_picture.linesize[0]; - us = v->s.current_picture.linesize[1]; - vs = v->s.current_picture.linesize[2]; - Y = v->s.dest[0]; - - dsp->put_pixels_clamped(block[0], Y, ys); - dsp->put_pixels_clamped(block[1], Y + 8, ys); - Y += ys * 8; - dsp->put_pixels_clamped(block[2], Y, ys); - dsp->put_pixels_clamped(block[3], Y + 8, ys); - - if(!(v->s.flags & CODEC_FLAG_GRAY)) { - dsp->put_pixels_clamped(block[4], v->s.dest[1], us); - dsp->put_pixels_clamped(block[5], v->s.dest[2], vs); - } -} - -/** Do motion compensation over 1 macroblock - * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c - */ -static void vc1_mc_1mv(VC1Context *v, int dir) -{ - MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; - uint8_t *srcY, *srcU, *srcV; - int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; - - if(!v->s.last_picture.data[0])return; - - mx = s->mv[dir][0][0]; - my = s->mv[dir][0][1]; - - // store motion vectors for further use in B frames - if(s->pict_type == FF_P_TYPE) { - s->current_picture.motion_val[1][s->block_index[0]][0] = mx; - s->current_picture.motion_val[1][s->block_index[0]][1] = my; - } - uvmx = (mx + ((mx & 3) == 3)) >> 1; - uvmy = (my + ((my & 3) == 3)) >> 1; - if(v->fastuvmc) { - uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1)); - uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1)); - } - if(!dir) { - srcY = s->last_picture.data[0]; - srcU = s->last_picture.data[1]; - srcV = s->last_picture.data[2]; - } else { - srcY = s->next_picture.data[0]; - srcU = s->next_picture.data[1]; - srcV = s->next_picture.data[2]; - } - - src_x = s->mb_x * 16 + (mx >> 2); - src_y = s->mb_y * 16 + (my >> 2); - uvsrc_x = s->mb_x * 8 + (uvmx >> 2); - uvsrc_y = s->mb_y * 8 + (uvmy >> 2); - - if(v->profile != PROFILE_ADVANCED){ - src_x = av_clip( src_x, -16, s->mb_width * 16); - src_y = av_clip( src_y, -16, s->mb_height * 16); - uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); - uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); - }else{ - src_x = av_clip( src_x, -17, s->avctx->coded_width); - src_y = av_clip( src_y, -18, s->avctx->coded_height + 1); - uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); - uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); - } - - srcY += src_y * s->linesize + src_x; - srcU += uvsrc_y * s->uvlinesize + uvsrc_x; - srcV += uvsrc_y * s->uvlinesize + uvsrc_x; - - /* for grayscale we should not try to read from unknown area */ - if(s->flags & CODEC_FLAG_GRAY) { - srcU = s->edge_emu_buffer + 18 * s->linesize; - srcV = s->edge_emu_buffer + 18 * s->linesize; - } - - if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) - || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3 - || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){ - uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize; - - srcY -= s->mspel * (1 + s->linesize); - ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2, - src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos); - srcY = s->edge_emu_buffer; - ff_emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - srcU = uvbuf; - srcV = uvbuf + 16; - /* if we deal with range reduction we need to scale source blocks */ - if(v->rangeredfrm) { - int i, j; - uint8_t *src, *src2; - - src = srcY; - for(j = 0; j < 17 + s->mspel*2; j++) { - for(i = 0; i < 17 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128; - src += s->linesize; - } - src = srcU; src2 = srcV; - for(j = 0; j < 9; j++) { - for(i = 0; i < 9; i++) { - src[i] = ((src[i] - 128) >> 1) + 128; - src2[i] = ((src2[i] - 128) >> 1) + 128; - } - src += s->uvlinesize; - src2 += s->uvlinesize; - } - } - /* if we deal with intensity compensation we need to scale source blocks */ - if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - int i, j; - uint8_t *src, *src2; - - src = srcY; - for(j = 0; j < 17 + s->mspel*2; j++) { - for(i = 0; i < 17 + s->mspel*2; i++) src[i] = v->luty[src[i]]; - src += s->linesize; - } - src = srcU; src2 = srcV; - for(j = 0; j < 9; j++) { - for(i = 0; i < 9; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; - } - src += s->uvlinesize; - src2 += s->uvlinesize; - } - } - srcY += s->mspel * (1 + s->linesize); - } - - if(s->mspel) { - dxy = ((my & 3) << 2) | (mx & 3); - dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd); - dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd); - srcY += s->linesize * 8; - dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd); - dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); - } else { // hpel mc - always used for luma - dxy = (my & 2) | ((mx & 2) >> 1); - - if(!v->rnd) - dsp->put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); - else - dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); - } - - if(s->flags & CODEC_FLAG_GRAY) return; - /* Chroma MC always uses qpel bilinear */ - uvmx = (uvmx&3)<<1; - uvmy = (uvmy&3)<<1; - if(!v->rnd){ - dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); - }else{ - dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); - } -} - -/** Do motion compensation for 4-MV macroblock - luminance block - */ -static void vc1_mc_4mv_luma(VC1Context *v, int n) -{ - MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; - uint8_t *srcY; - int dxy, mx, my, src_x, src_y; - int off; - - if(!v->s.last_picture.data[0])return; - mx = s->mv[0][n][0]; - my = s->mv[0][n][1]; - srcY = s->last_picture.data[0]; - - off = s->linesize * 4 * (n&2) + (n&1) * 8; - - src_x = s->mb_x * 16 + (n&1) * 8 + (mx >> 2); - src_y = s->mb_y * 16 + (n&2) * 4 + (my >> 2); - - if(v->profile != PROFILE_ADVANCED){ - src_x = av_clip( src_x, -16, s->mb_width * 16); - src_y = av_clip( src_y, -16, s->mb_height * 16); - }else{ - src_x = av_clip( src_x, -17, s->avctx->coded_width); - src_y = av_clip( src_y, -18, s->avctx->coded_height + 1); - } - - srcY += src_y * s->linesize + src_x; - - if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) - || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 8 - s->mspel*2 - || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 8 - s->mspel*2){ - srcY -= s->mspel * (1 + s->linesize); - ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 9+s->mspel*2, 9+s->mspel*2, - src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos); - srcY = s->edge_emu_buffer; - /* if we deal with range reduction we need to scale source blocks */ - if(v->rangeredfrm) { - int i, j; - uint8_t *src; - - src = srcY; - for(j = 0; j < 9 + s->mspel*2; j++) { - for(i = 0; i < 9 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128; - src += s->linesize; - } - } - /* if we deal with intensity compensation we need to scale source blocks */ - if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - int i, j; - uint8_t *src; - - src = srcY; - for(j = 0; j < 9 + s->mspel*2; j++) { - for(i = 0; i < 9 + s->mspel*2; i++) src[i] = v->luty[src[i]]; - src += s->linesize; - } - } - srcY += s->mspel * (1 + s->linesize); - } - - if(s->mspel) { - dxy = ((my & 3) << 2) | (mx & 3); - dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, v->rnd); - } else { // hpel mc - always used for luma - dxy = (my & 2) | ((mx & 2) >> 1); - if(!v->rnd) - dsp->put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); - else - dsp->put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8); - } -} - -static inline int median4(int a, int b, int c, int d) -{ - if(a < b) { - if(c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2; - else return (FFMIN(b, c) + FFMAX(a, d)) / 2; - } else { - if(c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2; - else return (FFMIN(a, c) + FFMAX(b, d)) / 2; - } -} - - -/** Do motion compensation for 4-MV macroblock - both chroma blocks - */ -static void vc1_mc_4mv_chroma(VC1Context *v) -{ - MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; - uint8_t *srcU, *srcV; - int uvmx, uvmy, uvsrc_x, uvsrc_y; - int i, idx, tx = 0, ty = 0; - int mvx[4], mvy[4], intra[4]; - static const int count[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; - - if(!v->s.last_picture.data[0])return; - if(s->flags & CODEC_FLAG_GRAY) return; - - for(i = 0; i < 4; i++) { - mvx[i] = s->mv[0][i][0]; - mvy[i] = s->mv[0][i][1]; - intra[i] = v->mb_type[0][s->block_index[i]]; - } - - /* calculate chroma MV vector from four luma MVs */ - idx = (intra[3] << 3) | (intra[2] << 2) | (intra[1] << 1) | intra[0]; - if(!idx) { // all blocks are inter - tx = median4(mvx[0], mvx[1], mvx[2], mvx[3]); - ty = median4(mvy[0], mvy[1], mvy[2], mvy[3]); - } else if(count[idx] == 1) { // 3 inter blocks - switch(idx) { - case 0x1: - tx = mid_pred(mvx[1], mvx[2], mvx[3]); - ty = mid_pred(mvy[1], mvy[2], mvy[3]); - break; - case 0x2: - tx = mid_pred(mvx[0], mvx[2], mvx[3]); - ty = mid_pred(mvy[0], mvy[2], mvy[3]); - break; - case 0x4: - tx = mid_pred(mvx[0], mvx[1], mvx[3]); - ty = mid_pred(mvy[0], mvy[1], mvy[3]); - break; - case 0x8: - tx = mid_pred(mvx[0], mvx[1], mvx[2]); - ty = mid_pred(mvy[0], mvy[1], mvy[2]); - break; - } - } else if(count[idx] == 2) { - int t1 = 0, t2 = 0; - for(i=0; i<3;i++) if(!intra[i]) {t1 = i; break;} - for(i= t1+1; i<4; i++)if(!intra[i]) {t2 = i; break;} - tx = (mvx[t1] + mvx[t2]) / 2; - ty = (mvy[t1] + mvy[t2]) / 2; - } else { - s->current_picture.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.motion_val[1][s->block_index[0]][1] = 0; - return; //no need to do MC for inter blocks - } - - s->current_picture.motion_val[1][s->block_index[0]][0] = tx; - s->current_picture.motion_val[1][s->block_index[0]][1] = ty; - uvmx = (tx + ((tx&3) == 3)) >> 1; - uvmy = (ty + ((ty&3) == 3)) >> 1; - if(v->fastuvmc) { - uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1)); - uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1)); - } - - uvsrc_x = s->mb_x * 8 + (uvmx >> 2); - uvsrc_y = s->mb_y * 8 + (uvmy >> 2); - - if(v->profile != PROFILE_ADVANCED){ - uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); - uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); - }else{ - uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); - uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); - } - - srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x; - srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; - if(v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) - || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9 - || (unsigned)uvsrc_y > (s->v_edge_pos >> 1) - 9){ - ff_emulated_edge_mc(s->edge_emu_buffer , srcU, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - ff_emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - srcU = s->edge_emu_buffer; - srcV = s->edge_emu_buffer + 16; - - /* if we deal with range reduction we need to scale source blocks */ - if(v->rangeredfrm) { - int i, j; - uint8_t *src, *src2; - - src = srcU; src2 = srcV; - for(j = 0; j < 9; j++) { - for(i = 0; i < 9; i++) { - src[i] = ((src[i] - 128) >> 1) + 128; - src2[i] = ((src2[i] - 128) >> 1) + 128; - } - src += s->uvlinesize; - src2 += s->uvlinesize; - } - } - /* if we deal with intensity compensation we need to scale source blocks */ - if(v->mv_mode == MV_PMODE_INTENSITY_COMP) { - int i, j; - uint8_t *src, *src2; - - src = srcU; src2 = srcV; - for(j = 0; j < 9; j++) { - for(i = 0; i < 9; i++) { - src[i] = v->lutuv[src[i]]; - src2[i] = v->lutuv[src2[i]]; - } - src += s->uvlinesize; - src2 += s->uvlinesize; - } - } - } - - /* Chroma MC always uses qpel bilinear */ - uvmx = (uvmx&3)<<1; - uvmy = (uvmy&3)<<1; - if(!v->rnd){ - dsp->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); - }else{ - dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); - } -} - -/***********************************************************************/ -/** - * @defgroup vc1block VC-1 Block-level functions - * @see 7.1.4, p91 and 8.1.1.7, p(1)04 - * @{ - */ - -/** - * @def GET_MQUANT - * @brief Get macroblock-level quantizer scale - */ -#define GET_MQUANT() \ - if (v->dquantfrm) \ - { \ - int edges = 0; \ - if (v->dqprofile == DQPROFILE_ALL_MBS) \ - { \ - if (v->dqbilevel) \ - { \ - mquant = (get_bits1(gb)) ? v->altpq : v->pq; \ - } \ - else \ - { \ - mqdiff = get_bits(gb, 3); \ - if (mqdiff != 7) mquant = v->pq + mqdiff; \ - else mquant = get_bits(gb, 5); \ - } \ - } \ - if(v->dqprofile == DQPROFILE_SINGLE_EDGE) \ - edges = 1 << v->dqsbedge; \ - else if(v->dqprofile == DQPROFILE_DOUBLE_EDGES) \ - edges = (3 << v->dqsbedge) % 15; \ - else if(v->dqprofile == DQPROFILE_FOUR_EDGES) \ - edges = 15; \ - if((edges&1) && !s->mb_x) \ - mquant = v->altpq; \ - if((edges&2) && s->first_slice_line) \ - mquant = v->altpq; \ - if((edges&4) && s->mb_x == (s->mb_width - 1)) \ - mquant = v->altpq; \ - if((edges&8) && s->mb_y == (s->mb_height - 1)) \ - mquant = v->altpq; \ - } - -/** - * @def GET_MVDATA(_dmv_x, _dmv_y) - * @brief Get MV differentials - * @see MVDATA decoding from 8.3.5.2, p(1)20 - * @param _dmv_x Horizontal differential for decoded MV - * @param _dmv_y Vertical differential for decoded MV - */ -#define GET_MVDATA(_dmv_x, _dmv_y) \ - index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table,\ - VC1_MV_DIFF_VLC_BITS, 2); \ - if (index > 36) \ - { \ - mb_has_coeffs = 1; \ - index -= 37; \ - } \ - else mb_has_coeffs = 0; \ - s->mb_intra = 0; \ - if (!index) { _dmv_x = _dmv_y = 0; } \ - else if (index == 35) \ - { \ - _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample); \ - _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample); \ - } \ - else if (index == 36) \ - { \ - _dmv_x = 0; \ - _dmv_y = 0; \ - s->mb_intra = 1; \ - } \ - else \ - { \ - index1 = index%6; \ - if (!s->quarter_sample && index1 == 5) val = 1; \ - else val = 0; \ - if(size_table[index1] - val > 0) \ - val = get_bits(gb, size_table[index1] - val); \ - else val = 0; \ - sign = 0 - (val&1); \ - _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign; \ - \ - index1 = index/6; \ - if (!s->quarter_sample && index1 == 5) val = 1; \ - else val = 0; \ - if(size_table[index1] - val > 0) \ - val = get_bits(gb, size_table[index1] - val); \ - else val = 0; \ - sign = 0 - (val&1); \ - _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign; \ - } - -/** Predict and set motion vector - */ -static inline void vc1_pred_mv(MpegEncContext *s, int n, int dmv_x, int dmv_y, int mv1, int r_x, int r_y, uint8_t* is_intra) -{ - int xy, wrap, off = 0; - int16_t *A, *B, *C; - int px, py; - int sum; - - /* scale MV difference to be quad-pel */ - dmv_x <<= 1 - s->quarter_sample; - dmv_y <<= 1 - s->quarter_sample; - - wrap = s->b8_stride; - xy = s->block_index[n]; - - if(s->mb_intra){ - s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0; - s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0; - s->current_picture.motion_val[1][xy][0] = 0; - s->current_picture.motion_val[1][xy][1] = 0; - if(mv1) { /* duplicate motion data for 1-MV block */ - s->current_picture.motion_val[0][xy + 1][0] = 0; - s->current_picture.motion_val[0][xy + 1][1] = 0; - s->current_picture.motion_val[0][xy + wrap][0] = 0; - s->current_picture.motion_val[0][xy + wrap][1] = 0; - s->current_picture.motion_val[0][xy + wrap + 1][0] = 0; - s->current_picture.motion_val[0][xy + wrap + 1][1] = 0; - s->current_picture.motion_val[1][xy + 1][0] = 0; - s->current_picture.motion_val[1][xy + 1][1] = 0; - s->current_picture.motion_val[1][xy + wrap][0] = 0; - s->current_picture.motion_val[1][xy + wrap][1] = 0; - s->current_picture.motion_val[1][xy + wrap + 1][0] = 0; - s->current_picture.motion_val[1][xy + wrap + 1][1] = 0; - } - return; - } - - C = s->current_picture.motion_val[0][xy - 1]; - A = s->current_picture.motion_val[0][xy - wrap]; - if(mv1) - off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2; - else { - //in 4-MV mode different blocks have different B predictor position - switch(n){ - case 0: - off = (s->mb_x > 0) ? -1 : 1; - break; - case 1: - off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1; - break; - case 2: - off = 1; - break; - case 3: - off = -1; - } - } - B = s->current_picture.motion_val[0][xy - wrap + off]; - - if(!s->first_slice_line || (n==2 || n==3)) { // predictor A is not out of bounds - if(s->mb_width == 1) { - px = A[0]; - py = A[1]; - } else { - px = mid_pred(A[0], B[0], C[0]); - py = mid_pred(A[1], B[1], C[1]); - } - } else if(s->mb_x || (n==1 || n==3)) { // predictor C is not out of bounds - px = C[0]; - py = C[1]; - } else { - px = py = 0; - } - /* Pullback MV as specified in 8.3.5.3.4 */ - { - int qx, qy, X, Y; - qx = (s->mb_x << 6) + ((n==1 || n==3) ? 32 : 0); - qy = (s->mb_y << 6) + ((n==2 || n==3) ? 32 : 0); - X = (s->mb_width << 6) - 4; - Y = (s->mb_height << 6) - 4; - if(mv1) { - if(qx + px < -60) px = -60 - qx; - if(qy + py < -60) py = -60 - qy; - } else { - if(qx + px < -28) px = -28 - qx; - if(qy + py < -28) py = -28 - qy; - } - if(qx + px > X) px = X - qx; - if(qy + py > Y) py = Y - qy; - } - /* Calculate hybrid prediction as specified in 8.3.5.3.5 */ - if((!s->first_slice_line || (n==2 || n==3)) && (s->mb_x || (n==1 || n==3))) { - if(is_intra[xy - wrap]) - sum = FFABS(px) + FFABS(py); - else - sum = FFABS(px - A[0]) + FFABS(py - A[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; - } else { - px = C[0]; - py = C[1]; - } - } else { - if(is_intra[xy - 1]) - sum = FFABS(px) + FFABS(py); - else - sum = FFABS(px - C[0]) + FFABS(py - C[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; - } else { - px = C[0]; - py = C[1]; - } - } - } - } - /* store MV using signed modulus of MV range defined in 4.11 */ - s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x; - s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y; - if(mv1) { /* duplicate motion data for 1-MV block */ - s->current_picture.motion_val[0][xy + 1][0] = s->current_picture.motion_val[0][xy][0]; - s->current_picture.motion_val[0][xy + 1][1] = s->current_picture.motion_val[0][xy][1]; - s->current_picture.motion_val[0][xy + wrap][0] = s->current_picture.motion_val[0][xy][0]; - s->current_picture.motion_val[0][xy + wrap][1] = s->current_picture.motion_val[0][xy][1]; - s->current_picture.motion_val[0][xy + wrap + 1][0] = s->current_picture.motion_val[0][xy][0]; - s->current_picture.motion_val[0][xy + wrap + 1][1] = s->current_picture.motion_val[0][xy][1]; - } -} - -/** Motion compensation for direct or interpolated blocks in B-frames - */ -static void vc1_interp_mc(VC1Context *v) -{ - MpegEncContext *s = &v->s; - DSPContext *dsp = &v->s.dsp; - uint8_t *srcY, *srcU, *srcV; - int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; - - if(!v->s.next_picture.data[0])return; - - mx = s->mv[1][0][0]; - my = s->mv[1][0][1]; - uvmx = (mx + ((mx & 3) == 3)) >> 1; - uvmy = (my + ((my & 3) == 3)) >> 1; - if(v->fastuvmc) { - uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1)); - uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1)); - } - srcY = s->next_picture.data[0]; - srcU = s->next_picture.data[1]; - srcV = s->next_picture.data[2]; - - src_x = s->mb_x * 16 + (mx >> 2); - src_y = s->mb_y * 16 + (my >> 2); - uvsrc_x = s->mb_x * 8 + (uvmx >> 2); - uvsrc_y = s->mb_y * 8 + (uvmy >> 2); - - if(v->profile != PROFILE_ADVANCED){ - src_x = av_clip( src_x, -16, s->mb_width * 16); - src_y = av_clip( src_y, -16, s->mb_height * 16); - uvsrc_x = av_clip(uvsrc_x, -8, s->mb_width * 8); - uvsrc_y = av_clip(uvsrc_y, -8, s->mb_height * 8); - }else{ - src_x = av_clip( src_x, -17, s->avctx->coded_width); - src_y = av_clip( src_y, -18, s->avctx->coded_height + 1); - uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width >> 1); - uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1); - } - - srcY += src_y * s->linesize + src_x; - srcU += uvsrc_y * s->uvlinesize + uvsrc_x; - srcV += uvsrc_y * s->uvlinesize + uvsrc_x; - - /* for grayscale we should not try to read from unknown area */ - if(s->flags & CODEC_FLAG_GRAY) { - srcU = s->edge_emu_buffer + 18 * s->linesize; - srcV = s->edge_emu_buffer + 18 * s->linesize; - } - - if(v->rangeredfrm - || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel*3 - || (unsigned)(src_y - s->mspel) > s->v_edge_pos - (my&3) - 16 - s->mspel*3){ - uint8_t *uvbuf= s->edge_emu_buffer + 19 * s->linesize; - - srcY -= s->mspel * (1 + s->linesize); - ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17+s->mspel*2, 17+s->mspel*2, - src_x - s->mspel, src_y - s->mspel, s->h_edge_pos, s->v_edge_pos); - srcY = s->edge_emu_buffer; - ff_emulated_edge_mc(uvbuf , srcU, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1, - uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - srcU = uvbuf; - srcV = uvbuf + 16; - /* if we deal with range reduction we need to scale source blocks */ - if(v->rangeredfrm) { - int i, j; - uint8_t *src, *src2; - - src = srcY; - for(j = 0; j < 17 + s->mspel*2; j++) { - for(i = 0; i < 17 + s->mspel*2; i++) src[i] = ((src[i] - 128) >> 1) + 128; - src += s->linesize; - } - src = srcU; src2 = srcV; - for(j = 0; j < 9; j++) { - for(i = 0; i < 9; i++) { - src[i] = ((src[i] - 128) >> 1) + 128; - src2[i] = ((src2[i] - 128) >> 1) + 128; - } - src += s->uvlinesize; - src2 += s->uvlinesize; - } - } - srcY += s->mspel * (1 + s->linesize); - } - - if(s->mspel) { - dxy = ((my & 3) << 2) | (mx & 3); - dsp->avg_vc1_mspel_pixels_tab[dxy](s->dest[0] , srcY , s->linesize, v->rnd); - dsp->avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd); - srcY += s->linesize * 8; - dsp->avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize , srcY , s->linesize, v->rnd); - dsp->avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd); - } else { // hpel mc - dxy = (my & 2) | ((mx & 2) >> 1); - - if(!v->rnd) - dsp->avg_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); - else - dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16); - } - - if(s->flags & CODEC_FLAG_GRAY) return; - /* Chroma MC always uses qpel blilinear */ - uvmx = (uvmx&3)<<1; - uvmy = (uvmy&3)<<1; - if(!v->rnd){ - dsp->avg_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); - }else{ - dsp->avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy); - dsp->avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy); - } -} - -static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs) -{ - int n = bfrac; - -#if B_FRACTION_DEN==256 - if(inv) - n -= 256; - if(!qs) - return 2 * ((value * n + 255) >> 9); - return (value * n + 128) >> 8; -#else - if(inv) - n -= B_FRACTION_DEN; - if(!qs) - return 2 * ((value * n + B_FRACTION_DEN - 1) / (2 * B_FRACTION_DEN)); - return (value * n + B_FRACTION_DEN/2) / B_FRACTION_DEN; -#endif -} - -/** Reconstruct motion vector for B-frame and do motion compensation - */ -static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mode) -{ - if(v->use_ic) { - v->mv_mode2 = v->mv_mode; - v->mv_mode = MV_PMODE_INTENSITY_COMP; - } - if(direct) { - vc1_mc_1mv(v, 0); - vc1_interp_mc(v); - if(v->use_ic) v->mv_mode = v->mv_mode2; - return; - } - if(mode == BMV_TYPE_INTERPOLATED) { - vc1_mc_1mv(v, 0); - vc1_interp_mc(v); - if(v->use_ic) v->mv_mode = v->mv_mode2; - return; - } - - if(v->use_ic && (mode == BMV_TYPE_BACKWARD)) v->mv_mode = v->mv_mode2; - vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD)); - if(v->use_ic) v->mv_mode = v->mv_mode2; -} - -static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int direct, int mvtype) -{ - MpegEncContext *s = &v->s; - int xy, wrap, off = 0; - int16_t *A, *B, *C; - int px, py; - int sum; - int r_x, r_y; - const uint8_t *is_intra = v->mb_type[0]; - - r_x = v->range_x; - r_y = v->range_y; - /* scale MV difference to be quad-pel */ - dmv_x[0] <<= 1 - s->quarter_sample; - dmv_y[0] <<= 1 - s->quarter_sample; - dmv_x[1] <<= 1 - s->quarter_sample; - dmv_y[1] <<= 1 - s->quarter_sample; - - wrap = s->b8_stride; - xy = s->block_index[0]; - - if(s->mb_intra) { - s->current_picture.motion_val[0][xy][0] = - s->current_picture.motion_val[0][xy][1] = - s->current_picture.motion_val[1][xy][0] = - s->current_picture.motion_val[1][xy][1] = 0; - return; - } - s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample); - s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample); - s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample); - s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample); - - /* Pullback predicted motion vectors as specified in 8.4.5.4 */ - s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); - s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); - s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); - s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); - if(direct) { - s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0]; - s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1]; - s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0]; - s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1]; - return; - } - - if((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) { - C = s->current_picture.motion_val[0][xy - 2]; - A = s->current_picture.motion_val[0][xy - wrap*2]; - off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; - B = s->current_picture.motion_val[0][xy - wrap*2 + off]; - - if(!s->mb_x) C[0] = C[1] = 0; - if(!s->first_slice_line) { // predictor A is not out of bounds - if(s->mb_width == 1) { - px = A[0]; - py = A[1]; - } else { - px = mid_pred(A[0], B[0], C[0]); - py = mid_pred(A[1], B[1], C[1]); - } - } else if(s->mb_x) { // predictor C is not out of bounds - px = C[0]; - py = C[1]; - } else { - px = py = 0; - } - /* Pullback MV as specified in 8.3.5.3.4 */ - { - int qx, qy, X, Y; - if(v->profile < PROFILE_ADVANCED) { - qx = (s->mb_x << 5); - qy = (s->mb_y << 5); - X = (s->mb_width << 5) - 4; - Y = (s->mb_height << 5) - 4; - if(qx + px < -28) px = -28 - qx; - if(qy + py < -28) py = -28 - qy; - if(qx + px > X) px = X - qx; - if(qy + py > Y) py = Y - qy; - } else { - qx = (s->mb_x << 6); - qy = (s->mb_y << 6); - X = (s->mb_width << 6) - 4; - Y = (s->mb_height << 6) - 4; - if(qx + px < -60) px = -60 - qx; - if(qy + py < -60) py = -60 - qy; - if(qx + px > X) px = X - qx; - if(qy + py > Y) py = Y - qy; - } - } - /* Calculate hybrid prediction as specified in 8.3.5.3.5 */ - if(0 && !s->first_slice_line && s->mb_x) { - if(is_intra[xy - wrap]) - sum = FFABS(px) + FFABS(py); - else - sum = FFABS(px - A[0]) + FFABS(py - A[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; - } else { - px = C[0]; - py = C[1]; - } - } else { - if(is_intra[xy - 2]) - sum = FFABS(px) + FFABS(py); - else - sum = FFABS(px - C[0]) + FFABS(py - C[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; - } else { - px = C[0]; - py = C[1]; - } - } - } - } - /* store MV using signed modulus of MV range defined in 4.11 */ - s->mv[0][0][0] = ((px + dmv_x[0] + r_x) & ((r_x << 1) - 1)) - r_x; - s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y; - } - if((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) { - C = s->current_picture.motion_val[1][xy - 2]; - A = s->current_picture.motion_val[1][xy - wrap*2]; - off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; - B = s->current_picture.motion_val[1][xy - wrap*2 + off]; - - if(!s->mb_x) C[0] = C[1] = 0; - if(!s->first_slice_line) { // predictor A is not out of bounds - if(s->mb_width == 1) { - px = A[0]; - py = A[1]; - } else { - px = mid_pred(A[0], B[0], C[0]); - py = mid_pred(A[1], B[1], C[1]); - } - } else if(s->mb_x) { // predictor C is not out of bounds - px = C[0]; - py = C[1]; - } else { - px = py = 0; - } - /* Pullback MV as specified in 8.3.5.3.4 */ - { - int qx, qy, X, Y; - if(v->profile < PROFILE_ADVANCED) { - qx = (s->mb_x << 5); - qy = (s->mb_y << 5); - X = (s->mb_width << 5) - 4; - Y = (s->mb_height << 5) - 4; - if(qx + px < -28) px = -28 - qx; - if(qy + py < -28) py = -28 - qy; - if(qx + px > X) px = X - qx; - if(qy + py > Y) py = Y - qy; - } else { - qx = (s->mb_x << 6); - qy = (s->mb_y << 6); - X = (s->mb_width << 6) - 4; - Y = (s->mb_height << 6) - 4; - if(qx + px < -60) px = -60 - qx; - if(qy + py < -60) py = -60 - qy; - if(qx + px > X) px = X - qx; - if(qy + py > Y) py = Y - qy; - } - } - /* Calculate hybrid prediction as specified in 8.3.5.3.5 */ - if(0 && !s->first_slice_line && s->mb_x) { - if(is_intra[xy - wrap]) - sum = FFABS(px) + FFABS(py); - else - sum = FFABS(px - A[0]) + FFABS(py - A[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; - } else { - px = C[0]; - py = C[1]; - } - } else { - if(is_intra[xy - 2]) - sum = FFABS(px) + FFABS(py); - else - sum = FFABS(px - C[0]) + FFABS(py - C[1]); - if(sum > 32) { - if(get_bits1(&s->gb)) { - px = A[0]; - py = A[1]; - } else { - px = C[0]; - py = C[1]; - } - } - } - } - /* store MV using signed modulus of MV range defined in 4.11 */ - - s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x; - s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y; - } - s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0]; - s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1]; - s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0]; - s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1]; -} - -/** Get predicted DC value for I-frames only - * prediction dir: left=0, top=1 - * @param s MpegEncContext - * @param overlap flag indicating that overlap filtering is used - * @param pq integer part of picture quantizer - * @param[in] n block index in the current MB - * @param dc_val_ptr Pointer to DC predictor - * @param dir_ptr Prediction direction for use in AC prediction - */ -static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n, - int16_t **dc_val_ptr, int *dir_ptr) -{ - int a, b, c, wrap, pred, scale; - int16_t *dc_val; - static const uint16_t dcpred[32] = { - -1, 1024, 512, 341, 256, 205, 171, 146, 128, - 114, 102, 93, 85, 79, 73, 68, 64, - 60, 57, 54, 51, 49, 47, 45, 43, - 41, 39, 38, 37, 35, 34, 33 - }; - - /* find prediction - wmv3_dc_scale always used here in fact */ - if (n < 4) scale = s->y_dc_scale; - else scale = s->c_dc_scale; - - wrap = s->block_wrap[n]; - dc_val= s->dc_val[0] + s->block_index[n]; - - /* B A - * C X - */ - c = dc_val[ - 1]; - b = dc_val[ - 1 - wrap]; - a = dc_val[ - wrap]; - - if (pq < 9 || !overlap) - { - /* Set outer values */ - if (s->first_slice_line && (n!=2 && n!=3)) b=a=dcpred[scale]; - if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=dcpred[scale]; - } - else - { - /* Set outer values */ - if (s->first_slice_line && (n!=2 && n!=3)) b=a=0; - if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=0; - } - - if (abs(a - b) <= abs(b - c)) { - pred = c; - *dir_ptr = 1;//left - } else { - pred = a; - *dir_ptr = 0;//top - } - - /* update predictor */ - *dc_val_ptr = &dc_val[0]; - return pred; -} - - -/** Get predicted DC value - * prediction dir: left=0, top=1 - * @param s MpegEncContext - * @param overlap flag indicating that overlap filtering is used - * @param pq integer part of picture quantizer - * @param[in] n block index in the current MB - * @param a_avail flag indicating top block availability - * @param c_avail flag indicating left block availability - * @param dc_val_ptr Pointer to DC predictor - * @param dir_ptr Prediction direction for use in AC prediction - */ -static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, - int a_avail, int c_avail, - int16_t **dc_val_ptr, int *dir_ptr) -{ - int a, b, c, wrap, pred; - int16_t *dc_val; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int q1, q2 = 0; - - wrap = s->block_wrap[n]; - dc_val= s->dc_val[0] + s->block_index[n]; - - /* B A - * C X - */ - c = dc_val[ - 1]; - b = dc_val[ - 1 - wrap]; - a = dc_val[ - wrap]; - /* scale predictors if needed */ - q1 = s->current_picture.qscale_table[mb_pos]; - if(c_avail && (n!= 1 && n!=3)) { - q2 = s->current_picture.qscale_table[mb_pos - 1]; - if(q2 && q2 != q1) - c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; - } - if(a_avail && (n!= 2 && n!=3)) { - q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; - if(q2 && q2 != q1) - a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; - } - if(a_avail && c_avail && (n!=3)) { - int off = mb_pos; - if(n != 1) off--; - if(n != 2) off -= s->mb_stride; - q2 = s->current_picture.qscale_table[off]; - if(q2 && q2 != q1) - b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; - } - - if(a_avail && c_avail) { - if(abs(a - b) <= abs(b - c)) { - pred = c; - *dir_ptr = 1;//left - } else { - pred = a; - *dir_ptr = 0;//top - } - } else if(a_avail) { - pred = a; - *dir_ptr = 0;//top - } else if(c_avail) { - pred = c; - *dir_ptr = 1;//left - } else { - pred = 0; - *dir_ptr = 1;//left - } - - /* update predictor */ - *dc_val_ptr = &dc_val[0]; - return pred; -} - -/** @} */ // Block group - -/** - * @defgroup vc1_std_mb VC1 Macroblock-level functions in Simple/Main Profiles - * @see 7.1.4, p91 and 8.1.1.7, p(1)04 - * @{ - */ - -static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) -{ - int xy, wrap, pred, a, b, c; - - xy = s->block_index[n]; - wrap = s->b8_stride; - - /* B C - * A X - */ - a = s->coded_block[xy - 1 ]; - b = s->coded_block[xy - 1 - wrap]; - c = s->coded_block[xy - wrap]; - - if (b == c) { - pred = a; - } else { - pred = c; - } - - /* store value */ - *coded_block_ptr = &s->coded_block[xy]; - - return pred; -} - -/** - * Decode one AC coefficient - * @param v The VC1 context - * @param last Last coefficient - * @param skip How much zero coefficients to skip - * @param value Decoded AC coefficient value - * @param codingset set of VLC to decode data - * @see 8.1.3.4 - */ -static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, int codingset) -{ - GetBitContext *gb = &v->s.gb; - int index, escape, run = 0, level = 0, lst = 0; - - index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); - if (index != vc1_ac_sizes[codingset] - 1) { - run = vc1_index_decode_table[codingset][index][0]; - level = vc1_index_decode_table[codingset][index][1]; - lst = index >= vc1_last_decode_table[codingset]; - if(get_bits1(gb)) - level = -level; - } else { - escape = decode210(gb); - if (escape != 2) { - index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); - run = vc1_index_decode_table[codingset][index][0]; - level = vc1_index_decode_table[codingset][index][1]; - lst = index >= vc1_last_decode_table[codingset]; - if(escape == 0) { - if(lst) - level += vc1_last_delta_level_table[codingset][run]; - else - level += vc1_delta_level_table[codingset][run]; - } else { - if(lst) - run += vc1_last_delta_run_table[codingset][level] + 1; - else - run += vc1_delta_run_table[codingset][level] + 1; - } - if(get_bits1(gb)) - level = -level; - } else { - int sign; - lst = get_bits1(gb); - if(v->s.esc3_level_length == 0) { - if(v->pq < 8 || v->dquantfrm) { // table 59 - v->s.esc3_level_length = get_bits(gb, 3); - if(!v->s.esc3_level_length) - v->s.esc3_level_length = get_bits(gb, 2) + 8; - } else { //table 60 - v->s.esc3_level_length = get_unary(gb, 1, 6) + 2; - } - v->s.esc3_run_length = 3 + get_bits(gb, 2); - } - run = get_bits(gb, v->s.esc3_run_length); - sign = get_bits1(gb); - level = get_bits(gb, v->s.esc3_level_length); - if(sign) - level = -level; - } - } - - *last = lst; - *skip = run; - *value = level; -} - -/** Decode intra block in intra frames - should be faster than decode_intra_block - * @param v VC1Context - * @param block block to decode - * @param[in] n subblock index - * @param coded are AC coeffs present or not - * @param codingset set of VLC to decode data - */ -static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset) -{ - GetBitContext *gb = &v->s.gb; - MpegEncContext *s = &v->s; - int dc_pred_dir = 0; /* Direction of the DC prediction used */ - int i; - int16_t *dc_val; - int16_t *ac_val, *ac_val2; - int dcdiff; - - /* Get DC differential */ - if (n < 4) { - dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } else { - dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } - if (dcdiff < 0){ - av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n"); - return -1; - } - if (dcdiff) - { - if (dcdiff == 119 /* ESC index value */) - { - /* TODO: Optimize */ - if (v->pq == 1) dcdiff = get_bits(gb, 10); - else if (v->pq == 2) dcdiff = get_bits(gb, 9); - else dcdiff = get_bits(gb, 8); - } - else - { - if (v->pq == 1) - dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; - else if (v->pq == 2) - dcdiff = (dcdiff<<1) + get_bits1(gb) - 1; - } - if (get_bits1(gb)) - dcdiff = -dcdiff; - } - - /* Prediction */ - dcdiff += vc1_i_pred_dc(&v->s, v->overlap, v->pq, n, &dc_val, &dc_pred_dir); - *dc_val = dcdiff; - - /* Store the quantized DC coeff, used for prediction */ - if (n < 4) { - block[0] = dcdiff * s->y_dc_scale; - } else { - block[0] = dcdiff * s->c_dc_scale; - } - /* Skip ? */ - if (!coded) { - goto not_coded; - } - - //AC Decoding - i = 1; - - { - int last = 0, skip, value; - const int8_t *zz_table; - int scale; - int k; - - scale = v->pq * 2 + v->halfpq; - - if(v->s.ac_pred) { - if(!dc_pred_dir) - zz_table = wmv1_scantable[2]; - else - zz_table = wmv1_scantable[3]; - } else - zz_table = wmv1_scantable[1]; - - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; - ac_val2 = ac_val; - if(dc_pred_dir) //left - ac_val -= 16; - else //top - ac_val -= 16 * s->block_wrap[n]; - - while (!last) { - vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); - i += skip; - if(i > 63) - break; - block[zz_table[i++]] = value; - } - - /* apply AC prediction if needed */ - if(s->ac_pred) { - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) - block[k << 3] += ac_val[k]; - } else { //top - for(k = 1; k < 8; k++) - block[k] += ac_val[k + 8]; - } - } - /* save AC coeffs for further prediction */ - for(k = 1; k < 8; k++) { - ac_val2[k] = block[k << 3]; - ac_val2[k + 8] = block[k]; - } - - /* scale AC coeffs */ - for(k = 1; k < 64; k++) - if(block[k]) { - block[k] *= scale; - if(!v->pquantizer) - block[k] += (block[k] < 0) ? -v->pq : v->pq; - } - - if(s->ac_pred) i = 63; - } - -not_coded: - if(!coded) { - int k, scale; - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; - ac_val2 = ac_val; - - i = 0; - scale = v->pq * 2 + v->halfpq; - memset(ac_val2, 0, 16 * 2); - if(dc_pred_dir) {//left - ac_val -= 16; - if(s->ac_pred) - memcpy(ac_val2, ac_val, 8 * 2); - } else {//top - ac_val -= 16 * s->block_wrap[n]; - if(s->ac_pred) - memcpy(ac_val2 + 8, ac_val + 8, 8 * 2); - } - - /* apply AC prediction if needed */ - if(s->ac_pred) { - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) { - block[k << 3] = ac_val[k] * scale; - if(!v->pquantizer && block[k << 3]) - block[k << 3] += (block[k << 3] < 0) ? -v->pq : v->pq; - } - } else { //top - for(k = 1; k < 8; k++) { - block[k] = ac_val[k + 8] * scale; - if(!v->pquantizer && block[k]) - block[k] += (block[k] < 0) ? -v->pq : v->pq; - } - } - i = 63; - } - } - s->block_last_index[n] = i; - - return 0; -} - -/** Decode intra block in intra frames - should be faster than decode_intra_block - * @param v VC1Context - * @param block block to decode - * @param[in] n subblock number - * @param coded are AC coeffs present or not - * @param codingset set of VLC to decode data - * @param mquant quantizer value for this macroblock - */ -static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset, int mquant) -{ - GetBitContext *gb = &v->s.gb; - MpegEncContext *s = &v->s; - int dc_pred_dir = 0; /* Direction of the DC prediction used */ - int i; - int16_t *dc_val; - int16_t *ac_val, *ac_val2; - int dcdiff; - int a_avail = v->a_avail, c_avail = v->c_avail; - int use_pred = s->ac_pred; - int scale; - int q1, q2 = 0; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - - /* Get DC differential */ - if (n < 4) { - dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } else { - dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } - if (dcdiff < 0){ - av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n"); - return -1; - } - if (dcdiff) - { - if (dcdiff == 119 /* ESC index value */) - { - /* TODO: Optimize */ - if (mquant == 1) dcdiff = get_bits(gb, 10); - else if (mquant == 2) dcdiff = get_bits(gb, 9); - else dcdiff = get_bits(gb, 8); - } - else - { - if (mquant == 1) - dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; - else if (mquant == 2) - dcdiff = (dcdiff<<1) + get_bits1(gb) - 1; - } - if (get_bits1(gb)) - dcdiff = -dcdiff; - } - - /* Prediction */ - dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, v->a_avail, v->c_avail, &dc_val, &dc_pred_dir); - *dc_val = dcdiff; - - /* Store the quantized DC coeff, used for prediction */ - if (n < 4) { - block[0] = dcdiff * s->y_dc_scale; - } else { - block[0] = dcdiff * s->c_dc_scale; - } - - //AC Decoding - i = 1; - - /* check if AC is needed at all */ - if(!a_avail && !c_avail) use_pred = 0; - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; - ac_val2 = ac_val; - - scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0); - - if(dc_pred_dir) //left - ac_val -= 16; - else //top - ac_val -= 16 * s->block_wrap[n]; - - q1 = s->current_picture.qscale_table[mb_pos]; - if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1]; - if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; - if(dc_pred_dir && n==1) q2 = q1; - if(!dc_pred_dir && n==2) q2 = q1; - if(n==3) q2 = q1; - - if(coded) { - int last = 0, skip, value; - const int8_t *zz_table; - int k; - - if(v->s.ac_pred) { - if(!dc_pred_dir) - zz_table = wmv1_scantable[2]; - else - zz_table = wmv1_scantable[3]; - } else - zz_table = wmv1_scantable[1]; - - while (!last) { - vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); - i += skip; - if(i > 63) - break; - block[zz_table[i++]] = value; - } - - /* apply AC prediction if needed */ - if(use_pred) { - /* scale predictors if needed*/ - if(q2 && q1!=q2) { - q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; - q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; - - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) - block[k << 3] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } else { //top - for(k = 1; k < 8; k++) - block[k] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } - } else { - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) - block[k << 3] += ac_val[k]; - } else { //top - for(k = 1; k < 8; k++) - block[k] += ac_val[k + 8]; - } - } - } - /* save AC coeffs for further prediction */ - for(k = 1; k < 8; k++) { - ac_val2[k] = block[k << 3]; - ac_val2[k + 8] = block[k]; - } - - /* scale AC coeffs */ - for(k = 1; k < 64; k++) - if(block[k]) { - block[k] *= scale; - if(!v->pquantizer) - block[k] += (block[k] < 0) ? -mquant : mquant; - } - - if(use_pred) i = 63; - } else { // no AC coeffs - int k; - - memset(ac_val2, 0, 16 * 2); - if(dc_pred_dir) {//left - if(use_pred) { - memcpy(ac_val2, ac_val, 8 * 2); - if(q2 && q1!=q2) { - q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; - q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; - for(k = 1; k < 8; k++) - ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } - } - } else {//top - if(use_pred) { - memcpy(ac_val2 + 8, ac_val + 8, 8 * 2); - if(q2 && q1!=q2) { - q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; - q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; - for(k = 1; k < 8; k++) - ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } - } - } - - /* apply AC prediction if needed */ - if(use_pred) { - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) { - block[k << 3] = ac_val2[k] * scale; - if(!v->pquantizer && block[k << 3]) - block[k << 3] += (block[k << 3] < 0) ? -mquant : mquant; - } - } else { //top - for(k = 1; k < 8; k++) { - block[k] = ac_val2[k + 8] * scale; - if(!v->pquantizer && block[k]) - block[k] += (block[k] < 0) ? -mquant : mquant; - } - } - i = 63; - } - } - s->block_last_index[n] = i; - - return 0; -} - -/** Decode intra block in inter frames - more generic version than vc1_decode_i_block - * @param v VC1Context - * @param block block to decode - * @param[in] n subblock index - * @param coded are AC coeffs present or not - * @param mquant block quantizer - * @param codingset set of VLC to decode data - */ -static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int coded, int mquant, int codingset) -{ - GetBitContext *gb = &v->s.gb; - MpegEncContext *s = &v->s; - int dc_pred_dir = 0; /* Direction of the DC prediction used */ - int i; - int16_t *dc_val; - int16_t *ac_val, *ac_val2; - int dcdiff; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int a_avail = v->a_avail, c_avail = v->c_avail; - int use_pred = s->ac_pred; - int scale; - int q1, q2 = 0; - - s->dsp.clear_block(block); - - /* XXX: Guard against dumb values of mquant */ - mquant = (mquant < 1) ? 0 : ( (mquant>31) ? 31 : mquant ); - - /* Set DC scale - y and c use the same */ - s->y_dc_scale = s->y_dc_scale_table[mquant]; - s->c_dc_scale = s->c_dc_scale_table[mquant]; - - /* Get DC differential */ - if (n < 4) { - dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } else { - dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); - } - if (dcdiff < 0){ - av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n"); - return -1; - } - if (dcdiff) - { - if (dcdiff == 119 /* ESC index value */) - { - /* TODO: Optimize */ - if (mquant == 1) dcdiff = get_bits(gb, 10); - else if (mquant == 2) dcdiff = get_bits(gb, 9); - else dcdiff = get_bits(gb, 8); - } - else - { - if (mquant == 1) - dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; - else if (mquant == 2) - dcdiff = (dcdiff<<1) + get_bits1(gb) - 1; - } - if (get_bits1(gb)) - dcdiff = -dcdiff; - } - - /* Prediction */ - dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir); - *dc_val = dcdiff; - - /* Store the quantized DC coeff, used for prediction */ - - if (n < 4) { - block[0] = dcdiff * s->y_dc_scale; - } else { - block[0] = dcdiff * s->c_dc_scale; - } - - //AC Decoding - i = 1; - - /* check if AC is needed at all and adjust direction if needed */ - if(!a_avail) dc_pred_dir = 1; - if(!c_avail) dc_pred_dir = 0; - if(!a_avail && !c_avail) use_pred = 0; - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; - ac_val2 = ac_val; - - scale = mquant * 2 + v->halfpq; - - if(dc_pred_dir) //left - ac_val -= 16; - else //top - ac_val -= 16 * s->block_wrap[n]; - - q1 = s->current_picture.qscale_table[mb_pos]; - if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1]; - if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; - if(dc_pred_dir && n==1) q2 = q1; - if(!dc_pred_dir && n==2) q2 = q1; - if(n==3) q2 = q1; - - if(coded) { - int last = 0, skip, value; - const int8_t *zz_table; - int k; - - zz_table = wmv1_scantable[0]; - - while (!last) { - vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); - i += skip; - if(i > 63) - break; - block[zz_table[i++]] = value; - } - - /* apply AC prediction if needed */ - if(use_pred) { - /* scale predictors if needed*/ - if(q2 && q1!=q2) { - q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; - q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; - - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) - block[k << 3] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } else { //top - for(k = 1; k < 8; k++) - block[k] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } - } else { - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) - block[k << 3] += ac_val[k]; - } else { //top - for(k = 1; k < 8; k++) - block[k] += ac_val[k + 8]; - } - } - } - /* save AC coeffs for further prediction */ - for(k = 1; k < 8; k++) { - ac_val2[k] = block[k << 3]; - ac_val2[k + 8] = block[k]; - } - - /* scale AC coeffs */ - for(k = 1; k < 64; k++) - if(block[k]) { - block[k] *= scale; - if(!v->pquantizer) - block[k] += (block[k] < 0) ? -mquant : mquant; - } - - if(use_pred) i = 63; - } else { // no AC coeffs - int k; - - memset(ac_val2, 0, 16 * 2); - if(dc_pred_dir) {//left - if(use_pred) { - memcpy(ac_val2, ac_val, 8 * 2); - if(q2 && q1!=q2) { - q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; - q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; - for(k = 1; k < 8; k++) - ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } - } - } else {//top - if(use_pred) { - memcpy(ac_val2 + 8, ac_val + 8, 8 * 2); - if(q2 && q1!=q2) { - q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; - q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; - for(k = 1; k < 8; k++) - ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; - } - } - } - - /* apply AC prediction if needed */ - if(use_pred) { - if(dc_pred_dir) { //left - for(k = 1; k < 8; k++) { - block[k << 3] = ac_val2[k] * scale; - if(!v->pquantizer && block[k << 3]) - block[k << 3] += (block[k << 3] < 0) ? -mquant : mquant; - } - } else { //top - for(k = 1; k < 8; k++) { - block[k] = ac_val2[k + 8] * scale; - if(!v->pquantizer && block[k]) - block[k] += (block[k] < 0) ? -mquant : mquant; - } - } - i = 63; - } - } - s->block_last_index[n] = i; - - return 0; -} - -/** Decode P block - */ -static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block, - uint8_t *dst, int linesize, int skip_block, int apply_filter, int cbp_top, int cbp_left) -{ - MpegEncContext *s = &v->s; - GetBitContext *gb = &s->gb; - int i, j; - int subblkpat = 0; - int scale, off, idx, last, skip, value; - int ttblk = ttmb & 7; - int pat = 0; - - s->dsp.clear_block(block); - - if(ttmb == -1) { - ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)]; - } - if(ttblk == TT_4X4) { - subblkpat = ~(get_vlc2(gb, ff_vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1); - } - if((ttblk != TT_8X8 && ttblk != TT_4X4) && (v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))) { - subblkpat = decode012(gb); - if(subblkpat) subblkpat ^= 3; //swap decoded pattern bits - if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4; - if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8; - } - scale = 2 * mquant + ((v->pq == mquant) ? v->halfpq : 0); - - // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT - if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) { - subblkpat = 2 - (ttblk == TT_8X4_TOP); - ttblk = TT_8X4; - } - if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) { - subblkpat = 2 - (ttblk == TT_4X8_LEFT); - ttblk = TT_4X8; - } - switch(ttblk) { - case TT_8X8: - pat = 0xF; - i = 0; - last = 0; - while (!last) { - vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2); - i += skip; - if(i > 63) - break; - idx = wmv1_scantable[0][i++]; - block[idx] = value * scale; - if(!v->pquantizer) - block[idx] += (block[idx] < 0) ? -mquant : mquant; - } - if(!skip_block){ - if(i==1) - s->dsp.vc1_inv_trans_8x8_dc(dst, linesize, block); - else{ - s->dsp.vc1_inv_trans_8x8(block); - s->dsp.add_pixels_clamped(block, dst, linesize); - } - if(apply_filter && cbp_top & 0xC) - s->dsp.vc1_v_loop_filter8(dst, linesize, v->pq); - if(apply_filter && cbp_left & 0xA) - s->dsp.vc1_h_loop_filter8(dst, linesize, v->pq); - } - break; - case TT_4X4: - pat = ~subblkpat & 0xF; - for(j = 0; j < 4; j++) { - last = subblkpat & (1 << (3 - j)); - i = 0; - off = (j & 1) * 4 + (j & 2) * 16; - while (!last) { - vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2); - i += skip; - if(i > 15) - break; - idx = ff_vc1_simple_progressive_4x4_zz[i++]; - block[idx + off] = value * scale; - if(!v->pquantizer) - block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant; - } - if(!(subblkpat & (1 << (3 - j))) && !skip_block){ - if(i==1) - s->dsp.vc1_inv_trans_4x4_dc(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off); - else - s->dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off); - if(apply_filter && (j&2 ? pat & (1<<(j-2)) : (cbp_top & (1 << (j + 2))))) - s->dsp.vc1_v_loop_filter4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, v->pq); - if(apply_filter && (j&1 ? pat & (1<<(j-1)) : (cbp_left & (1 << (j + 1))))) - s->dsp.vc1_h_loop_filter4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, v->pq); - } - } - break; - case TT_8X4: - pat = ~((subblkpat & 2)*6 + (subblkpat & 1)*3) & 0xF; - for(j = 0; j < 2; j++) { - last = subblkpat & (1 << (1 - j)); - i = 0; - off = j * 32; - while (!last) { - vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2); - i += skip; - if(i > 31) - break; - idx = v->zz_8x4[i++]+off; - block[idx] = value * scale; - if(!v->pquantizer) - block[idx] += (block[idx] < 0) ? -mquant : mquant; - } - if(!(subblkpat & (1 << (1 - j))) && !skip_block){ - if(i==1) - s->dsp.vc1_inv_trans_8x4_dc(dst + j*4*linesize, linesize, block + off); - else - s->dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off); - if(apply_filter && j ? pat & 0x3 : (cbp_top & 0xC)) - s->dsp.vc1_v_loop_filter8(dst + j*4*linesize, linesize, v->pq); - if(apply_filter && cbp_left & (2 << j)) - s->dsp.vc1_h_loop_filter4(dst + j*4*linesize, linesize, v->pq); - } - } - break; - case TT_4X8: - pat = ~(subblkpat*5) & 0xF; - for(j = 0; j < 2; j++) { - last = subblkpat & (1 << (1 - j)); - i = 0; - off = j * 4; - while (!last) { - vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2); - i += skip; - if(i > 31) - break; - idx = v->zz_4x8[i++]+off; - block[idx] = value * scale; - if(!v->pquantizer) - block[idx] += (block[idx] < 0) ? -mquant : mquant; - } - if(!(subblkpat & (1 << (1 - j))) && !skip_block){ - if(i==1) - s->dsp.vc1_inv_trans_4x8_dc(dst + j*4, linesize, block + off); - else - s->dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off); - if(apply_filter && cbp_top & (2 << j)) - s->dsp.vc1_v_loop_filter4(dst + j*4, linesize, v->pq); - if(apply_filter && j ? pat & 0x5 : (cbp_left & 0xA)) - s->dsp.vc1_h_loop_filter8(dst + j*4, linesize, v->pq); - } - } - break; - } - return pat; -} - -/** @} */ // Macroblock group - -static const int size_table [6] = { 0, 2, 3, 4, 5, 8 }; -static const int offset_table[6] = { 0, 1, 3, 7, 15, 31 }; - -/** Decode one P-frame MB (in Simple/Main profile) - */ -static int vc1_decode_p_mb(VC1Context *v) -{ - MpegEncContext *s = &v->s; - GetBitContext *gb = &s->gb; - int i, j; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int cbp; /* cbp decoding stuff */ - int mqdiff, mquant; /* MB quantization */ - int ttmb = v->ttfrm; /* MB Transform type */ - - int mb_has_coeffs = 1; /* last_flag */ - int dmv_x, dmv_y; /* Differential MV components */ - int index, index1; /* LUT indexes */ - int val, sign; /* temp values */ - int first_block = 1; - int dst_idx, off; - int skipped, fourmv; - int block_cbp = 0, pat; - int apply_loop_filter; - - mquant = v->pq; /* Loosy initialization */ - - if (v->mv_type_is_raw) - fourmv = get_bits1(gb); - else - fourmv = v->mv_type_mb_plane[mb_pos]; - if (v->skip_is_raw) - skipped = get_bits1(gb); - else - skipped = v->s.mbskip_table[mb_pos]; - - apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY); - if (!fourmv) /* 1MV mode */ - { - if (!skipped) - { - GET_MVDATA(dmv_x, dmv_y); - - if (s->mb_intra) { - s->current_picture.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.motion_val[1][s->block_index[0]][1] = 0; - } - s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16; - vc1_pred_mv(s, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]); - - /* FIXME Set DC val for inter block ? */ - if (s->mb_intra && !mb_has_coeffs) - { - GET_MQUANT(); - s->ac_pred = get_bits1(gb); - cbp = 0; - } - else if (mb_has_coeffs) - { - if (s->mb_intra) s->ac_pred = get_bits1(gb); - cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); - GET_MQUANT(); - } - else - { - mquant = v->pq; - cbp = 0; - } - s->current_picture.qscale_table[mb_pos] = mquant; - - if (!v->ttmbf && !s->mb_intra && mb_has_coeffs) - ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, - VC1_TTMB_VLC_BITS, 2); - if(!s->mb_intra) vc1_mc_1mv(v, 0); - dst_idx = 0; - for (i=0; i<6; i++) - { - s->dc_val[0][s->block_index[i]] = 0; - dst_idx += i >> 2; - val = ((cbp >> (5 - i)) & 1); - off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - v->mb_type[0][s->block_index[i]] = s->mb_intra; - if(s->mb_intra) { - /* check if prediction blocks A and C are available */ - v->a_avail = v->c_avail = 0; - if(i == 2 || i == 3 || !s->first_slice_line) - v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; - if(i == 1 || i == 3 || s->mb_x) - v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - - vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset); - if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; - s->dsp.vc1_inv_trans_8x8(s->block[i]); - if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; - s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); - if(v->pq >= 9 && v->overlap) { - if(v->c_avail) - s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); - if(v->a_avail) - s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); - } - if(apply_loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - int left_cbp, top_cbp; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - s->dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - s->dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } - block_cbp |= 0xF << (i << 2); - } else if(val) { - int left_cbp = 0, top_cbp = 0, filter = 0; - if(apply_loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - filter = 1; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - s->dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - s->dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } - pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); - block_cbp |= pat << (i << 2); - if(!v->ttmbf && ttmb < 8) ttmb = -1; - first_block = 0; - } - } - } - else //Skipped - { - s->mb_intra = 0; - for(i = 0; i < 6; i++) { - v->mb_type[0][s->block_index[i]] = 0; - s->dc_val[0][s->block_index[i]] = 0; - } - s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP; - s->current_picture.qscale_table[mb_pos] = 0; - vc1_pred_mv(s, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]); - vc1_mc_1mv(v, 0); - return 0; - } - } //1MV mode - else //4MV mode - { - if (!skipped /* unskipped MB */) - { - int intra_count = 0, coded_inter = 0; - int is_intra[6], is_coded[6]; - /* Get CBPCY */ - cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); - for (i=0; i<6; i++) - { - val = ((cbp >> (5 - i)) & 1); - s->dc_val[0][s->block_index[i]] = 0; - s->mb_intra = 0; - if(i < 4) { - dmv_x = dmv_y = 0; - s->mb_intra = 0; - mb_has_coeffs = 0; - if(val) { - GET_MVDATA(dmv_x, dmv_y); - } - vc1_pred_mv(s, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]); - if(!s->mb_intra) vc1_mc_4mv_luma(v, i); - intra_count += s->mb_intra; - is_intra[i] = s->mb_intra; - is_coded[i] = mb_has_coeffs; - } - if(i&4){ - is_intra[i] = (intra_count >= 3); - is_coded[i] = val; - } - if(i == 4) vc1_mc_4mv_chroma(v); - v->mb_type[0][s->block_index[i]] = is_intra[i]; - if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i]; - } - // if there are no coded blocks then don't do anything more - if(!intra_count && !coded_inter) return 0; - dst_idx = 0; - GET_MQUANT(); - s->current_picture.qscale_table[mb_pos] = mquant; - /* test if block is intra and has pred */ - { - int intrapred = 0; - for(i=0; i<6; i++) - if(is_intra[i]) { - if(((!s->first_slice_line || (i==2 || i==3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]]) - || ((s->mb_x || (i==1 || i==3)) && v->mb_type[0][s->block_index[i] - 1])) { - intrapred = 1; - break; - } - } - if(intrapred)s->ac_pred = get_bits1(gb); - else s->ac_pred = 0; - } - if (!v->ttmbf && coded_inter) - ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); - for (i=0; i<6; i++) - { - dst_idx += i >> 2; - off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - s->mb_intra = is_intra[i]; - if (is_intra[i]) { - /* check if prediction blocks A and C are available */ - v->a_avail = v->c_avail = 0; - if(i == 2 || i == 3 || !s->first_slice_line) - v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; - if(i == 1 || i == 3 || s->mb_x) - v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - - vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant, (i&4)?v->codingset2:v->codingset); - if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; - s->dsp.vc1_inv_trans_8x8(s->block[i]); - if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; - s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize); - if(v->pq >= 9 && v->overlap) { - if(v->c_avail) - s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); - if(v->a_avail) - s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); - } - if(v->s.loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - int left_cbp, top_cbp; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - s->dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - s->dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } - block_cbp |= 0xF << (i << 2); - } else if(is_coded[i]) { - int left_cbp = 0, top_cbp = 0, filter = 0; - if(v->s.loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ - filter = 1; - if(i & 4){ - left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); - top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); - }else{ - left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); - top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); - } - if(left_cbp & 0xC) - s->dsp.vc1_v_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - if(top_cbp & 0xA) - s->dsp.vc1_h_loop_filter8(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, v->pq); - } - pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); - block_cbp |= pat << (i << 2); - if(!v->ttmbf && ttmb < 8) ttmb = -1; - first_block = 0; - } - } - return 0; - } - else //Skipped MB - { - s->mb_intra = 0; - s->current_picture.qscale_table[mb_pos] = 0; - for (i=0; i<6; i++) { - v->mb_type[0][s->block_index[i]] = 0; - s->dc_val[0][s->block_index[i]] = 0; - } - for (i=0; i<4; i++) - { - vc1_pred_mv(s, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]); - vc1_mc_4mv_luma(v, i); - } - vc1_mc_4mv_chroma(v); - s->current_picture.qscale_table[mb_pos] = 0; - return 0; - } - } - v->cbp[s->mb_x] = block_cbp; - - /* Should never happen */ - return -1; -} - -/** Decode one B-frame MB (in Main profile) - */ -static void vc1_decode_b_mb(VC1Context *v) -{ - MpegEncContext *s = &v->s; - GetBitContext *gb = &s->gb; - int i, j; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int cbp = 0; /* cbp decoding stuff */ - int mqdiff, mquant; /* MB quantization */ - int ttmb = v->ttfrm; /* MB Transform type */ - int mb_has_coeffs = 0; /* last_flag */ - int index, index1; /* LUT indexes */ - int val, sign; /* temp values */ - int first_block = 1; - int dst_idx, off; - int skipped, direct; - int dmv_x[2], dmv_y[2]; - int bmvtype = BMV_TYPE_BACKWARD; - - mquant = v->pq; /* Loosy initialization */ - s->mb_intra = 0; - - if (v->dmb_is_raw) - direct = get_bits1(gb); - else - direct = v->direct_mb_plane[mb_pos]; - if (v->skip_is_raw) - skipped = get_bits1(gb); - else - skipped = v->s.mbskip_table[mb_pos]; - - dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0; - for(i = 0; i < 6; i++) { - v->mb_type[0][s->block_index[i]] = 0; - s->dc_val[0][s->block_index[i]] = 0; - } - s->current_picture.qscale_table[mb_pos] = 0; - - if (!direct) { - if (!skipped) { - GET_MVDATA(dmv_x[0], dmv_y[0]); - dmv_x[1] = dmv_x[0]; - dmv_y[1] = dmv_y[0]; - } - if(skipped || !s->mb_intra) { - bmvtype = decode012(gb); - switch(bmvtype) { - case 0: - bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD; - break; - case 1: - bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD; - break; - case 2: - bmvtype = BMV_TYPE_INTERPOLATED; - dmv_x[0] = dmv_y[0] = 0; - } - } - } - for(i = 0; i < 6; i++) - v->mb_type[0][s->block_index[i]] = s->mb_intra; - - if (skipped) { - if(direct) bmvtype = BMV_TYPE_INTERPOLATED; - vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); - vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype); - return; - } - if (direct) { - cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); - GET_MQUANT(); - s->mb_intra = 0; - s->current_picture.qscale_table[mb_pos] = mquant; - if(!v->ttmbf) - ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); - dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0; - vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); - vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype); - } else { - if(!mb_has_coeffs && !s->mb_intra) { - /* no coded blocks - effectively skipped */ - vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); - vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype); - return; - } - if(s->mb_intra && !mb_has_coeffs) { - GET_MQUANT(); - s->current_picture.qscale_table[mb_pos] = mquant; - s->ac_pred = get_bits1(gb); - cbp = 0; - vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); - } else { - if(bmvtype == BMV_TYPE_INTERPOLATED) { - GET_MVDATA(dmv_x[0], dmv_y[0]); - if(!mb_has_coeffs) { - /* interpolated skipped block */ - vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); - vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype); - return; - } - } - vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); - if(!s->mb_intra) { - vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype); - } - if(s->mb_intra) - s->ac_pred = get_bits1(gb); - cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); - GET_MQUANT(); - s->current_picture.qscale_table[mb_pos] = mquant; - if(!v->ttmbf && !s->mb_intra && mb_has_coeffs) - ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); - } - } - dst_idx = 0; - for (i=0; i<6; i++) - { - s->dc_val[0][s->block_index[i]] = 0; - dst_idx += i >> 2; - val = ((cbp >> (5 - i)) & 1); - off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - v->mb_type[0][s->block_index[i]] = s->mb_intra; - if(s->mb_intra) { - /* check if prediction blocks A and C are available */ - v->a_avail = v->c_avail = 0; - if(i == 2 || i == 3 || !s->first_slice_line) - v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; - if(i == 1 || i == 3 || s->mb_x) - v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - - vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset); - if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; - s->dsp.vc1_inv_trans_8x8(s->block[i]); - if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; - s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); - } else if(val) { - vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), 0, 0, 0); - if(!v->ttmbf && ttmb < 8) ttmb = -1; - first_block = 0; - } - } -} - -/** Decode blocks of I-frame - */ -static void vc1_decode_i_blocks(VC1Context *v) -{ - int k, j; - MpegEncContext *s = &v->s; - int cbp, val; - uint8_t *coded_val; - int mb_pos; - - /* select codingmode used for VLC tables selection */ - switch(v->y_ac_table_index){ - case 0: - v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA; - break; - case 1: - v->codingset = CS_HIGH_MOT_INTRA; - break; - case 2: - v->codingset = CS_MID_RATE_INTRA; - break; - } - - switch(v->c_ac_table_index){ - case 0: - v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER; - break; - case 1: - v->codingset2 = CS_HIGH_MOT_INTER; - break; - case 2: - v->codingset2 = CS_MID_RATE_INTER; - break; - } - - /* Set DC scale - y and c use the same */ - s->y_dc_scale = s->y_dc_scale_table[v->pq]; - s->c_dc_scale = s->c_dc_scale_table[v->pq]; - - //do frame decode - s->mb_x = s->mb_y = 0; - s->mb_intra = 1; - s->first_slice_line = 1; - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { - s->mb_x = 0; - ff_init_block_index(s); - for(; s->mb_x < s->mb_width; s->mb_x++) { - ff_update_block_index(s); - s->dsp.clear_blocks(s->block[0]); - mb_pos = s->mb_x + s->mb_y * s->mb_width; - s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; - s->current_picture.qscale_table[mb_pos] = v->pq; - s->current_picture.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.motion_val[1][s->block_index[0]][1] = 0; - - // do actual MB decoding and displaying - cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - v->s.ac_pred = get_bits1(&v->s.gb); - - for(k = 0; k < 6; k++) { - val = ((cbp >> (5 - k)) & 1); - - if (k < 4) { - int pred = vc1_coded_block_pred(&v->s, k, &coded_val); - val = val ^ pred; - *coded_val = val; - } - cbp |= val << (5 - k); - - vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2); - - s->dsp.vc1_inv_trans_8x8(s->block[k]); - if(v->pq >= 9 && v->overlap) { - for(j = 0; j < 64; j++) s->block[k][j] += 128; - } - } - - vc1_put_block(v, s->block); - if(v->pq >= 9 && v->overlap) { - if(s->mb_x) { - s->dsp.vc1_h_overlap(s->dest[0], s->linesize); - s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize); - if(!(s->flags & CODEC_FLAG_GRAY)) { - s->dsp.vc1_h_overlap(s->dest[1], s->uvlinesize); - s->dsp.vc1_h_overlap(s->dest[2], s->uvlinesize); - } - } - s->dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize); - s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); - if(!s->first_slice_line) { - s->dsp.vc1_v_overlap(s->dest[0], s->linesize); - s->dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize); - if(!(s->flags & CODEC_FLAG_GRAY)) { - s->dsp.vc1_v_overlap(s->dest[1], s->uvlinesize); - s->dsp.vc1_v_overlap(s->dest[2], s->uvlinesize); - } - } - s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize); - s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); - } - if(v->s.loop_filter) vc1_loop_filter_iblk(s, v->pq); - - if(get_bits_count(&s->gb) > v->bits) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); - av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); - return; - } - } - ff_draw_horiz_band(s, s->mb_y * 16, 16); - s->first_slice_line = 0; - } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); -} - -/** Decode blocks of I-frame for advanced profile - */ -static void vc1_decode_i_blocks_adv(VC1Context *v) -{ - int k, j; - MpegEncContext *s = &v->s; - int cbp, val; - uint8_t *coded_val; - int mb_pos; - int mquant = v->pq; - int mqdiff; - int overlap; - GetBitContext *gb = &s->gb; - - /* select codingmode used for VLC tables selection */ - switch(v->y_ac_table_index){ - case 0: - v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA; - break; - case 1: - v->codingset = CS_HIGH_MOT_INTRA; - break; - case 2: - v->codingset = CS_MID_RATE_INTRA; - break; - } - - switch(v->c_ac_table_index){ - case 0: - v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER; - break; - case 1: - v->codingset2 = CS_HIGH_MOT_INTER; - break; - case 2: - v->codingset2 = CS_MID_RATE_INTER; - break; - } - - //do frame decode - s->mb_x = s->mb_y = 0; - s->mb_intra = 1; - s->first_slice_line = 1; - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { - s->mb_x = 0; - ff_init_block_index(s); - for(;s->mb_x < s->mb_width; s->mb_x++) { - ff_update_block_index(s); - s->dsp.clear_blocks(s->block[0]); - mb_pos = s->mb_x + s->mb_y * s->mb_stride; - s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA; - s->current_picture.motion_val[1][s->block_index[0]][0] = 0; - s->current_picture.motion_val[1][s->block_index[0]][1] = 0; - - // do actual MB decoding and displaying - cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if(v->acpred_is_raw) - v->s.ac_pred = get_bits1(&v->s.gb); - else - v->s.ac_pred = v->acpred_plane[mb_pos]; - - if(v->condover == CONDOVER_SELECT) { - if(v->overflg_is_raw) - overlap = get_bits1(&v->s.gb); - else - overlap = v->over_flags_plane[mb_pos]; - } else - overlap = (v->condover == CONDOVER_ALL); - - GET_MQUANT(); - - s->current_picture.qscale_table[mb_pos] = mquant; - /* Set DC scale - y and c use the same */ - s->y_dc_scale = s->y_dc_scale_table[mquant]; - s->c_dc_scale = s->c_dc_scale_table[mquant]; - - for(k = 0; k < 6; k++) { - val = ((cbp >> (5 - k)) & 1); - - if (k < 4) { - int pred = vc1_coded_block_pred(&v->s, k, &coded_val); - val = val ^ pred; - *coded_val = val; - } - cbp |= val << (5 - k); - - v->a_avail = !s->first_slice_line || (k==2 || k==3); - v->c_avail = !!s->mb_x || (k==1 || k==3); - - vc1_decode_i_block_adv(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2, mquant); - - s->dsp.vc1_inv_trans_8x8(s->block[k]); - for(j = 0; j < 64; j++) s->block[k][j] += 128; - } - - vc1_put_block(v, s->block); - if(overlap) { - if(s->mb_x) { - s->dsp.vc1_h_overlap(s->dest[0], s->linesize); - s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize, s->linesize); - if(!(s->flags & CODEC_FLAG_GRAY)) { - s->dsp.vc1_h_overlap(s->dest[1], s->uvlinesize); - s->dsp.vc1_h_overlap(s->dest[2], s->uvlinesize); - } - } - s->dsp.vc1_h_overlap(s->dest[0] + 8, s->linesize); - s->dsp.vc1_h_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); - if(!s->first_slice_line) { - s->dsp.vc1_v_overlap(s->dest[0], s->linesize); - s->dsp.vc1_v_overlap(s->dest[0] + 8, s->linesize); - if(!(s->flags & CODEC_FLAG_GRAY)) { - s->dsp.vc1_v_overlap(s->dest[1], s->uvlinesize); - s->dsp.vc1_v_overlap(s->dest[2], s->uvlinesize); - } - } - s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize, s->linesize); - s->dsp.vc1_v_overlap(s->dest[0] + 8 * s->linesize + 8, s->linesize); - } - if(v->s.loop_filter) vc1_loop_filter_iblk(s, v->pq); - - if(get_bits_count(&s->gb) > v->bits) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); - av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); - return; - } - } - ff_draw_horiz_band(s, s->mb_y * 16, 16); - s->first_slice_line = 0; - } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); -} - -static void vc1_decode_p_blocks(VC1Context *v) -{ - MpegEncContext *s = &v->s; - - /* select codingmode used for VLC tables selection */ - switch(v->c_ac_table_index){ - case 0: - v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA; - break; - case 1: - v->codingset = CS_HIGH_MOT_INTRA; - break; - case 2: - v->codingset = CS_MID_RATE_INTRA; - break; - } - - switch(v->c_ac_table_index){ - case 0: - v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER; - break; - case 1: - v->codingset2 = CS_HIGH_MOT_INTER; - break; - case 2: - v->codingset2 = CS_MID_RATE_INTER; - break; - } - - s->first_slice_line = 1; - memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride); - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { - s->mb_x = 0; - ff_init_block_index(s); - for(; s->mb_x < s->mb_width; s->mb_x++) { - ff_update_block_index(s); - - vc1_decode_p_mb(v); - if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); - av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); - return; - } - } - memmove(v->cbp_base, v->cbp, sizeof(v->cbp_base[0])*s->mb_stride); - ff_draw_horiz_band(s, s->mb_y * 16, 16); - s->first_slice_line = 0; - } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); -} - -static void vc1_decode_b_blocks(VC1Context *v) -{ - MpegEncContext *s = &v->s; - - /* select codingmode used for VLC tables selection */ - switch(v->c_ac_table_index){ - case 0: - v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA; - break; - case 1: - v->codingset = CS_HIGH_MOT_INTRA; - break; - case 2: - v->codingset = CS_MID_RATE_INTRA; - break; - } - - switch(v->c_ac_table_index){ - case 0: - v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER; - break; - case 1: - v->codingset2 = CS_HIGH_MOT_INTER; - break; - case 2: - v->codingset2 = CS_MID_RATE_INTER; - break; - } - - s->first_slice_line = 1; - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { - s->mb_x = 0; - ff_init_block_index(s); - for(; s->mb_x < s->mb_width; s->mb_x++) { - ff_update_block_index(s); - - vc1_decode_b_mb(v); - if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { - ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); - av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); - return; - } - if(v->s.loop_filter) vc1_loop_filter_iblk(s, v->pq); - } - ff_draw_horiz_band(s, s->mb_y * 16, 16); - s->first_slice_line = 0; - } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); -} - -static void vc1_decode_skip_blocks(VC1Context *v) -{ - MpegEncContext *s = &v->s; - - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); - s->first_slice_line = 1; - for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { - s->mb_x = 0; - ff_init_block_index(s); - ff_update_block_index(s); - memcpy(s->dest[0], s->last_picture.data[0] + s->mb_y * 16 * s->linesize, s->linesize * 16); - memcpy(s->dest[1], s->last_picture.data[1] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); - memcpy(s->dest[2], s->last_picture.data[2] + s->mb_y * 8 * s->uvlinesize, s->uvlinesize * 8); - ff_draw_horiz_band(s, s->mb_y * 16, 16); - s->first_slice_line = 0; - } - s->pict_type = FF_P_TYPE; -} - -static void vc1_decode_blocks(VC1Context *v) -{ - - v->s.esc3_level_length = 0; - if(v->x8_type){ - ff_intrax8_decode_picture(&v->x8, 2*v->pq+v->halfpq, v->pq*(!v->pquantizer) ); - }else{ - - switch(v->s.pict_type) { - case FF_I_TYPE: - if(v->profile == PROFILE_ADVANCED) - vc1_decode_i_blocks_adv(v); - else - vc1_decode_i_blocks(v); - break; - case FF_P_TYPE: - if(v->p_frame_skipped) - vc1_decode_skip_blocks(v); - else - vc1_decode_p_blocks(v); - break; - case FF_B_TYPE: - if(v->bi_type){ - if(v->profile == PROFILE_ADVANCED) - vc1_decode_i_blocks_adv(v); - else - vc1_decode_i_blocks(v); - }else - vc1_decode_b_blocks(v); - break; - } - } -} - -/** Initialize a VC1/WMV3 decoder - * @todo TODO: Handle VC-1 IDUs (Transport level?) - * @todo TODO: Decypher remaining bits in extra_data - */ -static av_cold int vc1_decode_init(AVCodecContext *avctx) -{ - VC1Context *v = avctx->priv_data; - MpegEncContext *s = &v->s; - GetBitContext gb; - - if (!avctx->extradata_size || !avctx->extradata) return -1; - if (!(avctx->flags & CODEC_FLAG_GRAY)) - avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts); - else - avctx->pix_fmt = PIX_FMT_GRAY8; - avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); - v->s.avctx = avctx; - avctx->flags |= CODEC_FLAG_EMU_EDGE; - v->s.flags |= CODEC_FLAG_EMU_EDGE; - - if(avctx->idct_algo==FF_IDCT_AUTO){ - avctx->idct_algo=FF_IDCT_WMV2; - } - - if(ff_msmpeg4_decode_init(avctx) < 0) - return -1; - if (vc1_init_common(v) < 0) return -1; - - avctx->coded_width = avctx->width; - avctx->coded_height = avctx->height; - if (avctx->codec_id == CODEC_ID_WMV3) - { - int count = 0; - - // looks like WMV3 has a sequence header stored in the extradata - // advanced sequence header may be before the first frame - // the last byte of the extradata is a version number, 1 for the - // samples we can decode - - init_get_bits(&gb, avctx->extradata, avctx->extradata_size*8); - - if (vc1_decode_sequence_header(avctx, v, &gb) < 0) - return -1; - - count = avctx->extradata_size*8 - get_bits_count(&gb); - if (count>0) - { - av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n", - count, get_bits(&gb, count)); - } - else if (count < 0) - { - av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); - } - } else { // VC1/WVC1 - const uint8_t *start = avctx->extradata; - uint8_t *end = avctx->extradata + avctx->extradata_size; - const uint8_t *next; - int size, buf2_size; - uint8_t *buf2 = NULL; - int seq_initialized = 0, ep_initialized = 0; - - if(avctx->extradata_size < 16) { - av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", avctx->extradata_size); - return -1; - } - - buf2 = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - start = find_next_marker(start, end); // in WVC1 extradata first byte is its size, but can be 0 in mkv - next = start; - for(; next < end; start = next){ - next = find_next_marker(start + 4, end); - size = next - start - 4; - if(size <= 0) continue; - buf2_size = vc1_unescape_buffer(start + 4, size, buf2); - init_get_bits(&gb, buf2, buf2_size * 8); - switch(AV_RB32(start)){ - case VC1_CODE_SEQHDR: - if(vc1_decode_sequence_header(avctx, v, &gb) < 0){ - av_free(buf2); - return -1; - } - seq_initialized = 1; - break; - case VC1_CODE_ENTRYPOINT: - if(vc1_decode_entry_point(avctx, v, &gb) < 0){ - av_free(buf2); - return -1; - } - ep_initialized = 1; - break; - } - } - av_free(buf2); - if(!seq_initialized || !ep_initialized){ - av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n"); - return -1; - } - } - avctx->has_b_frames= !!(avctx->max_b_frames); - s->low_delay = !avctx->has_b_frames; - - s->mb_width = (avctx->coded_width+15)>>4; - s->mb_height = (avctx->coded_height+15)>>4; - - /* Allocate mb bitplanes */ - v->mv_type_mb_plane = av_malloc(s->mb_stride * s->mb_height); - v->direct_mb_plane = av_malloc(s->mb_stride * s->mb_height); - v->acpred_plane = av_malloc(s->mb_stride * s->mb_height); - v->over_flags_plane = av_malloc(s->mb_stride * s->mb_height); - - v->cbp_base = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride); - v->cbp = v->cbp_base + s->mb_stride; - - /* allocate block type info in that way so it could be used with s->block_index[] */ - v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2); - v->mb_type[0] = v->mb_type_base + s->b8_stride + 1; - v->mb_type[1] = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1; - v->mb_type[2] = v->mb_type[1] + s->mb_stride * (s->mb_height + 1); - - /* Init coded blocks info */ - if (v->profile == PROFILE_ADVANCED) - { -// if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0) -// return -1; -// if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0) -// return -1; - } - - ff_intrax8_common_init(&v->x8,s); - return 0; -} - - -/** Decode a VC1/WMV3 frame - * @todo TODO: Handle VC-1 IDUs (Transport level?) - */ -static int vc1_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VC1Context *v = avctx->priv_data; - MpegEncContext *s = &v->s; - AVFrame *pict = data; - uint8_t *buf2 = NULL; - const uint8_t *buf_start = buf; - - /* 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; - } - - /* We need to set current_picture_ptr before reading the header, - * otherwise we cannot store anything in 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]; - } - - if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){ - if (v->profile < PROFILE_ADVANCED) - avctx->pix_fmt = PIX_FMT_VDPAU_WMV3; - else - avctx->pix_fmt = PIX_FMT_VDPAU_VC1; - } - - //for advanced profile we may need to parse and unescape data - if (avctx->codec_id == CODEC_ID_VC1) { - int buf_size2 = 0; - buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(IS_MARKER(AV_RB32(buf))){ /* frame starts with marker and needs to be parsed */ - const uint8_t *start, *end, *next; - int size; - - next = buf; - for(start = buf, end = buf + buf_size; next < end; start = next){ - next = find_next_marker(start + 4, end); - size = next - start - 4; - if(size <= 0) continue; - switch(AV_RB32(start)){ - case VC1_CODE_FRAME: - if (avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - buf_start = start; - buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); - break; - case VC1_CODE_ENTRYPOINT: /* it should be before frame data */ - buf_size2 = vc1_unescape_buffer(start + 4, size, buf2); - init_get_bits(&s->gb, buf2, buf_size2*8); - vc1_decode_entry_point(avctx, v, &s->gb); - break; - case VC1_CODE_SLICE: - av_log(avctx, AV_LOG_ERROR, "Sliced decoding is not implemented (yet)\n"); - av_free(buf2); - return -1; - } - } - }else if(v->interlace && ((buf[0] & 0xC0) == 0xC0)){ /* WVC1 interlaced stores both fields divided by marker */ - const uint8_t *divider; - - divider = find_next_marker(buf, buf + buf_size); - if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){ - av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); - av_free(buf2); - return -1; - } - - buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2); - // TODO - if(!v->warn_interlaced++) - av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced WVC1 support is not implemented\n"); - av_free(buf2);return -1; - }else{ - buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2); - } - init_get_bits(&s->gb, buf2, buf_size2*8); - } else - init_get_bits(&s->gb, buf, buf_size*8); - // do parse frame header - if(v->profile < PROFILE_ADVANCED) { - if(vc1_parse_frame_header(v, &s->gb) == -1) { - av_free(buf2); - return -1; - } - } else { - if(vc1_parse_frame_header_adv(v, &s->gb) == -1) { - av_free(buf2); - return -1; - } - } - - if(s->pict_type != FF_I_TYPE && !v->res_rtm_flag){ - av_free(buf2); - return -1; - } - - // for hurry_up==5 - s->current_picture.pict_type= s->pict_type; - s->current_picture.key_frame= s->pict_type == FF_I_TYPE; - - /* skip B-frames if we don't have reference frames */ - if(s->last_picture_ptr==NULL && (s->pict_type==FF_B_TYPE || s->dropable)){ - av_free(buf2); - return -1;//buf_size; - } - /* skip b frames if we are in a hurry */ - if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return -1;//buf_size; - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE) - || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE) - || avctx->skip_frame >= AVDISCARD_ALL) { - av_free(buf2); - return buf_size; - } - /* skip everything if we are in a hurry>=5 */ - if(avctx->hurry_up>=5) { - av_free(buf2); - return -1;//buf_size; - } - - if(s->next_p_frame_damaged){ - if(s->pict_type==FF_B_TYPE) - return buf_size; - else - s->next_p_frame_damaged=0; - } - - if(MPV_frame_start(s, avctx) < 0) { - av_free(buf2); - return -1; - } - - s->me.qpel_put= s->dsp.put_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; - - if ((CONFIG_VC1_VDPAU_DECODER) - &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) - ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start); - else if (avctx->hwaccel) { - if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0) - return -1; - if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0) - return -1; - if (avctx->hwaccel->end_frame(avctx) < 0) - return -1; - } else { - ff_er_frame_start(s); - - v->bits = buf_size * 8; - vc1_decode_blocks(v); -//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), buf_size*8); -// if(get_bits_count(&s->gb) > buf_size * 8) -// return -1; - 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 == FF_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); - } - - av_free(buf2); - return buf_size; -} - - -/** Close a VC1/WMV3 decoder - * @warning Initial try at using MpegEncContext stuff - */ -static av_cold int vc1_decode_end(AVCodecContext *avctx) -{ - VC1Context *v = avctx->priv_data; - - av_freep(&v->hrd_rate); - av_freep(&v->hrd_buffer); - MPV_common_end(&v->s); - av_freep(&v->mv_type_mb_plane); - av_freep(&v->direct_mb_plane); - av_freep(&v->acpred_plane); - av_freep(&v->over_flags_plane); - av_freep(&v->mb_type_base); - av_freep(&v->cbp_base); - ff_intrax8_common_end(&v->x8); - return 0; -} - - -AVCodec vc1_decoder = { - "vc1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VC1, - sizeof(VC1Context), - vc1_decode_init, - NULL, - vc1_decode_end, - vc1_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), - .pix_fmts = ff_hwaccel_pixfmt_list_420 -}; - -#if CONFIG_WMV3_DECODER -AVCodec wmv3_decoder = { - "wmv3", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WMV3, - sizeof(VC1Context), - vc1_decode_init, - NULL, - vc1_decode_end, - vc1_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), - .pix_fmts = ff_hwaccel_pixfmt_list_420 -}; -#endif - -#if CONFIG_WMV3_VDPAU_DECODER -AVCodec wmv3_vdpau_decoder = { - "wmv3_vdpau", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WMV3, - sizeof(VC1Context), - vc1_decode_init, - NULL, - vc1_decode_end, - vc1_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"), - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_WMV3, PIX_FMT_NONE} -}; -#endif - -#if CONFIG_VC1_VDPAU_DECODER -AVCodec vc1_vdpau_decoder = { - "vc1_vdpau", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VC1, - sizeof(VC1Context), - vc1_decode_init, - NULL, - vc1_decode_end, - vc1_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"), - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_VC1, PIX_FMT_NONE} -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/vc1dsp.c b/tizen/distrib/ffmpeg/libavcodec/vc1dsp.c deleted file mode 100644 index 47b69c8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vc1dsp.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * VC-1 and WMV3 decoder - DSP functions - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file - * VC-1 and WMV3 decoder - * - */ - -#include "dsputil.h" - - -/** Apply overlap transform to horizontal edge -*/ -static void vc1_v_overlap_c(uint8_t* src, int stride) -{ - int i; - int a, b, c, d; - int d1, d2; - int rnd = 1; - for(i = 0; i < 8; i++) { - a = src[-2*stride]; - b = src[-stride]; - c = src[0]; - d = src[stride]; - d1 = (a - d + 3 + rnd) >> 3; - d2 = (a - d + b - c + 4 - rnd) >> 3; - - src[-2*stride] = a - d1; - src[-stride] = av_clip_uint8(b - d2); - src[0] = av_clip_uint8(c + d2); - src[stride] = d + d1; - src++; - rnd = !rnd; - } -} - -/** Apply overlap transform to vertical edge -*/ -static void vc1_h_overlap_c(uint8_t* src, int stride) -{ - int i; - int a, b, c, d; - int d1, d2; - int rnd = 1; - for(i = 0; i < 8; i++) { - a = src[-2]; - b = src[-1]; - c = src[0]; - d = src[1]; - d1 = (a - d + 3 + rnd) >> 3; - d2 = (a - d + b - c + 4 - rnd) >> 3; - - src[-2] = a - d1; - src[-1] = av_clip_uint8(b - d2); - src[0] = av_clip_uint8(c + d2); - src[1] = d + d1; - src += stride; - rnd = !rnd; - } -} - -/** - * VC-1 in-loop deblocking filter for one line - * @param src source block type - * @param stride block stride - * @param pq block quantizer - * @return whether other 3 pairs should be filtered or not - * @see 8.6 - */ -static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3; - int a0_sign = a0 >> 31; /* Store sign */ - a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */ - if(a0 < pq){ - int a1 = FFABS((2*(src[-4*stride] - src[-1*stride]) - 5*(src[-3*stride] - src[-2*stride]) + 4) >> 3); - int a2 = FFABS((2*(src[ 0*stride] - src[ 3*stride]) - 5*(src[ 1*stride] - src[ 2*stride]) + 4) >> 3); - if(a1 < a0 || a2 < a0){ - int clip = src[-1*stride] - src[ 0*stride]; - int clip_sign = clip >> 31; - clip = ((clip ^ clip_sign) - clip_sign)>>1; - if(clip){ - int a3 = FFMIN(a1, a2); - int d = 5 * (a3 - a0); - int d_sign = (d >> 31); - d = ((d ^ d_sign) - d_sign) >> 3; - d_sign ^= a0_sign; - - if( d_sign ^ clip_sign ) - d = 0; - else{ - d = FFMIN(d, clip); - d = (d ^ d_sign) - d_sign; /* Restore sign */ - src[-1*stride] = cm[src[-1*stride] - d]; - src[ 0*stride] = cm[src[ 0*stride] + d]; - } - return 1; - } - } - } - return 0; -} - -/** - * VC-1 in-loop deblocking filter - * @param src source block type - * @param step distance between horizontally adjacent elements - * @param stride distance between vertically adjacent elements - * @param len edge length to filter (4 or 8 pixels) - * @param pq block quantizer - * @see 8.6 - */ -static inline void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq) -{ - int i; - int filt3; - - for(i = 0; i < len; i += 4){ - filt3 = vc1_filter_line(src + 2*step, stride, pq); - if(filt3){ - vc1_filter_line(src + 0*step, stride, pq); - vc1_filter_line(src + 1*step, stride, pq); - vc1_filter_line(src + 3*step, stride, pq); - } - src += step * 4; - } -} - -static void vc1_v_loop_filter4_c(uint8_t *src, int stride, int pq) -{ - vc1_loop_filter(src, 1, stride, 4, pq); -} - -static void vc1_h_loop_filter4_c(uint8_t *src, int stride, int pq) -{ - vc1_loop_filter(src, stride, 1, 4, pq); -} - -static void vc1_v_loop_filter8_c(uint8_t *src, int stride, int pq) -{ - vc1_loop_filter(src, 1, stride, 8, pq); -} - -static void vc1_h_loop_filter8_c(uint8_t *src, int stride, int pq) -{ - vc1_loop_filter(src, stride, 1, 8, pq); -} - -static void vc1_v_loop_filter16_c(uint8_t *src, int stride, int pq) -{ - vc1_loop_filter(src, 1, stride, 16, pq); -} - -static void vc1_h_loop_filter16_c(uint8_t *src, int stride, int pq) -{ - vc1_loop_filter(src, stride, 1, 16, pq); -} - -/** Do inverse transform on 8x8 block -*/ -static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - int dc = block[0]; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - dc = (3 * dc + 1) >> 1; - dc = (3 * dc + 16) >> 5; - for(i = 0; i < 8; i++){ - dest[0] = cm[dest[0]+dc]; - dest[1] = cm[dest[1]+dc]; - dest[2] = cm[dest[2]+dc]; - dest[3] = cm[dest[3]+dc]; - dest[4] = cm[dest[4]+dc]; - dest[5] = cm[dest[5]+dc]; - dest[6] = cm[dest[6]+dc]; - dest[7] = cm[dest[7]+dc]; - dest += linesize; - } -} - -static void vc1_inv_trans_8x8_c(DCTELEM block[64]) -{ - int i; - register int t1,t2,t3,t4,t5,t6,t7,t8; - DCTELEM *src, *dst; - - src = block; - dst = block; - for(i = 0; i < 8; i++){ - t1 = 12 * (src[0] + src[4]) + 4; - t2 = 12 * (src[0] - src[4]) + 4; - t3 = 16 * src[2] + 6 * src[6]; - t4 = 6 * src[2] - 16 * src[6]; - - t5 = t1 + t3; - t6 = t2 + t4; - t7 = t2 - t4; - t8 = t1 - t3; - - t1 = 16 * src[1] + 15 * src[3] + 9 * src[5] + 4 * src[7]; - t2 = 15 * src[1] - 4 * src[3] - 16 * src[5] - 9 * src[7]; - t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7]; - t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7]; - - dst[0] = (t5 + t1) >> 3; - dst[1] = (t6 + t2) >> 3; - dst[2] = (t7 + t3) >> 3; - dst[3] = (t8 + t4) >> 3; - dst[4] = (t8 - t4) >> 3; - dst[5] = (t7 - t3) >> 3; - dst[6] = (t6 - t2) >> 3; - dst[7] = (t5 - t1) >> 3; - - src += 8; - dst += 8; - } - - src = block; - dst = block; - for(i = 0; i < 8; i++){ - t1 = 12 * (src[ 0] + src[32]) + 64; - t2 = 12 * (src[ 0] - src[32]) + 64; - t3 = 16 * src[16] + 6 * src[48]; - t4 = 6 * src[16] - 16 * src[48]; - - t5 = t1 + t3; - t6 = t2 + t4; - t7 = t2 - t4; - t8 = t1 - t3; - - t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56]; - t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56]; - t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56]; - t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56]; - - dst[ 0] = (t5 + t1) >> 7; - dst[ 8] = (t6 + t2) >> 7; - dst[16] = (t7 + t3) >> 7; - dst[24] = (t8 + t4) >> 7; - dst[32] = (t8 - t4 + 1) >> 7; - dst[40] = (t7 - t3 + 1) >> 7; - dst[48] = (t6 - t2 + 1) >> 7; - dst[56] = (t5 - t1 + 1) >> 7; - - src++; - dst++; - } -} - -/** Do inverse transform on 8x4 part of block -*/ -static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - int dc = block[0]; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - dc = ( 3 * dc + 1) >> 1; - dc = (17 * dc + 64) >> 7; - for(i = 0; i < 4; i++){ - dest[0] = cm[dest[0]+dc]; - dest[1] = cm[dest[1]+dc]; - dest[2] = cm[dest[2]+dc]; - dest[3] = cm[dest[3]+dc]; - dest[4] = cm[dest[4]+dc]; - dest[5] = cm[dest[5]+dc]; - dest[6] = cm[dest[6]+dc]; - dest[7] = cm[dest[7]+dc]; - dest += linesize; - } -} - -static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - register int t1,t2,t3,t4,t5,t6,t7,t8; - DCTELEM *src, *dst; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - src = block; - dst = block; - for(i = 0; i < 4; i++){ - t1 = 12 * (src[0] + src[4]) + 4; - t2 = 12 * (src[0] - src[4]) + 4; - t3 = 16 * src[2] + 6 * src[6]; - t4 = 6 * src[2] - 16 * src[6]; - - t5 = t1 + t3; - t6 = t2 + t4; - t7 = t2 - t4; - t8 = t1 - t3; - - t1 = 16 * src[1] + 15 * src[3] + 9 * src[5] + 4 * src[7]; - t2 = 15 * src[1] - 4 * src[3] - 16 * src[5] - 9 * src[7]; - t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7]; - t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7]; - - dst[0] = (t5 + t1) >> 3; - dst[1] = (t6 + t2) >> 3; - dst[2] = (t7 + t3) >> 3; - dst[3] = (t8 + t4) >> 3; - dst[4] = (t8 - t4) >> 3; - dst[5] = (t7 - t3) >> 3; - dst[6] = (t6 - t2) >> 3; - dst[7] = (t5 - t1) >> 3; - - src += 8; - dst += 8; - } - - src = block; - for(i = 0; i < 8; i++){ - t1 = 17 * (src[ 0] + src[16]) + 64; - t2 = 17 * (src[ 0] - src[16]) + 64; - t3 = 22 * src[ 8] + 10 * src[24]; - t4 = 22 * src[24] - 10 * src[ 8]; - - dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)]; - dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)]; - dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)]; - dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)]; - - src ++; - dest++; - } -} - -/** Do inverse transform on 4x8 parts of block -*/ -static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - int dc = block[0]; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - dc = (17 * dc + 4) >> 3; - dc = (12 * dc + 64) >> 7; - for(i = 0; i < 8; i++){ - dest[0] = cm[dest[0]+dc]; - dest[1] = cm[dest[1]+dc]; - dest[2] = cm[dest[2]+dc]; - dest[3] = cm[dest[3]+dc]; - dest += linesize; - } -} - -static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - register int t1,t2,t3,t4,t5,t6,t7,t8; - DCTELEM *src, *dst; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - src = block; - dst = block; - for(i = 0; i < 8; i++){ - t1 = 17 * (src[0] + src[2]) + 4; - t2 = 17 * (src[0] - src[2]) + 4; - t3 = 22 * src[1] + 10 * src[3]; - t4 = 22 * src[3] - 10 * src[1]; - - dst[0] = (t1 + t3) >> 3; - dst[1] = (t2 - t4) >> 3; - dst[2] = (t2 + t4) >> 3; - dst[3] = (t1 - t3) >> 3; - - src += 8; - dst += 8; - } - - src = block; - for(i = 0; i < 4; i++){ - t1 = 12 * (src[ 0] + src[32]) + 64; - t2 = 12 * (src[ 0] - src[32]) + 64; - t3 = 16 * src[16] + 6 * src[48]; - t4 = 6 * src[16] - 16 * src[48]; - - t5 = t1 + t3; - t6 = t2 + t4; - t7 = t2 - t4; - t8 = t1 - t3; - - t1 = 16 * src[ 8] + 15 * src[24] + 9 * src[40] + 4 * src[56]; - t2 = 15 * src[ 8] - 4 * src[24] - 16 * src[40] - 9 * src[56]; - t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56]; - t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56]; - - dest[0*linesize] = cm[dest[0*linesize] + ((t5 + t1) >> 7)]; - dest[1*linesize] = cm[dest[1*linesize] + ((t6 + t2) >> 7)]; - dest[2*linesize] = cm[dest[2*linesize] + ((t7 + t3) >> 7)]; - dest[3*linesize] = cm[dest[3*linesize] + ((t8 + t4) >> 7)]; - dest[4*linesize] = cm[dest[4*linesize] + ((t8 - t4 + 1) >> 7)]; - dest[5*linesize] = cm[dest[5*linesize] + ((t7 - t3 + 1) >> 7)]; - dest[6*linesize] = cm[dest[6*linesize] + ((t6 - t2 + 1) >> 7)]; - dest[7*linesize] = cm[dest[7*linesize] + ((t5 - t1 + 1) >> 7)]; - - src ++; - dest++; - } -} - -/** Do inverse transform on 4x4 part of block -*/ -static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - int dc = block[0]; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - dc = (17 * dc + 4) >> 3; - dc = (17 * dc + 64) >> 7; - for(i = 0; i < 4; i++){ - dest[0] = cm[dest[0]+dc]; - dest[1] = cm[dest[1]+dc]; - dest[2] = cm[dest[2]+dc]; - dest[3] = cm[dest[3]+dc]; - dest += linesize; - } -} - -static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, DCTELEM *block) -{ - int i; - register int t1,t2,t3,t4; - DCTELEM *src, *dst; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - src = block; - dst = block; - for(i = 0; i < 4; i++){ - t1 = 17 * (src[0] + src[2]) + 4; - t2 = 17 * (src[0] - src[2]) + 4; - t3 = 22 * src[1] + 10 * src[3]; - t4 = 22 * src[3] - 10 * src[1]; - - dst[0] = (t1 + t3) >> 3; - dst[1] = (t2 - t4) >> 3; - dst[2] = (t2 + t4) >> 3; - dst[3] = (t1 - t3) >> 3; - - src += 8; - dst += 8; - } - - src = block; - for(i = 0; i < 4; i++){ - t1 = 17 * (src[ 0] + src[16]) + 64; - t2 = 17 * (src[ 0] - src[16]) + 64; - t3 = 22 * src[ 8] + 10 * src[24]; - t4 = 22 * src[24] - 10 * src[ 8]; - - dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)]; - dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)]; - dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)]; - dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)]; - - src ++; - dest++; - } -} - -/* motion compensation functions */ -/** Filter in case of 2 filters */ -#define VC1_MSPEL_FILTER_16B(DIR, TYPE) \ -static av_always_inline int vc1_mspel_ ## DIR ## _filter_16bits(const TYPE *src, int stride, int mode) \ -{ \ - switch(mode){ \ - case 0: /* no shift - should not occur */ \ - return 0; \ - case 1: /* 1/4 shift */ \ - return -4*src[-stride] + 53*src[0] + 18*src[stride] - 3*src[stride*2]; \ - case 2: /* 1/2 shift */ \ - return -src[-stride] + 9*src[0] + 9*src[stride] - src[stride*2]; \ - case 3: /* 3/4 shift */ \ - return -3*src[-stride] + 18*src[0] + 53*src[stride] - 4*src[stride*2]; \ - } \ - return 0; /* should not occur */ \ -} - -VC1_MSPEL_FILTER_16B(ver, uint8_t); -VC1_MSPEL_FILTER_16B(hor, int16_t); - - -/** Filter used to interpolate fractional pel values - */ -static av_always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int mode, int r) -{ - switch(mode){ - case 0: //no shift - return src[0]; - case 1: // 1/4 shift - return (-4*src[-stride] + 53*src[0] + 18*src[stride] - 3*src[stride*2] + 32 - r) >> 6; - case 2: // 1/2 shift - return (-src[-stride] + 9*src[0] + 9*src[stride] - src[stride*2] + 8 - r) >> 4; - case 3: // 3/4 shift - return (-3*src[-stride] + 18*src[0] + 53*src[stride] - 4*src[stride*2] + 32 - r) >> 6; - } - return 0; //should not occur -} - -/** Function used to do motion compensation with bicubic interpolation - */ -#define VC1_MSPEL_MC(OP, OPNAME)\ -static void OPNAME ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int hmode, int vmode, int rnd)\ -{\ - int i, j;\ -\ - if (vmode) { /* Horizontal filter to apply */\ - int r;\ -\ - if (hmode) { /* Vertical filter to apply, output to tmp */\ - static const int shift_value[] = { 0, 5, 1, 5 };\ - int shift = (shift_value[hmode]+shift_value[vmode])>>1;\ - int16_t tmp[11*8], *tptr = tmp;\ -\ - r = (1<<(shift-1)) + rnd-1;\ -\ - src -= 1;\ - for(j = 0; j < 8; j++) {\ - for(i = 0; i < 11; i++)\ - tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode)+r)>>shift;\ - src += stride;\ - tptr += 11;\ - }\ -\ - r = 64-rnd;\ - tptr = tmp+1;\ - for(j = 0; j < 8; j++) {\ - for(i = 0; i < 8; i++)\ - OP(dst[i], (vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode)+r)>>7);\ - dst += stride;\ - tptr += 11;\ - }\ -\ - return;\ - }\ - else { /* No horizontal filter, output 8 lines to dst */\ - r = 1-rnd;\ -\ - for(j = 0; j < 8; j++) {\ - for(i = 0; i < 8; i++)\ - OP(dst[i], vc1_mspel_filter(src + i, stride, vmode, r));\ - src += stride;\ - dst += stride;\ - }\ - return;\ - }\ - }\ -\ - /* Horizontal mode with no vertical mode */\ - for(j = 0; j < 8; j++) {\ - for(i = 0; i < 8; i++)\ - OP(dst[i], vc1_mspel_filter(src + i, 1, hmode, rnd));\ - dst += stride;\ - src += stride;\ - }\ -} - -#define op_put(a, b) a = av_clip_uint8(b) -#define op_avg(a, b) a = (a + av_clip_uint8(b) + 1) >> 1 - -VC1_MSPEL_MC(op_put, put_) -VC1_MSPEL_MC(op_avg, avg_) - -/* pixel functions - really are entry points to vc1_mspel_mc */ - -#define PUT_VC1_MSPEL(a, b)\ -static void put_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \ - put_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ -}\ -static void avg_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \ - avg_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ -} - -PUT_VC1_MSPEL(1, 0) -PUT_VC1_MSPEL(2, 0) -PUT_VC1_MSPEL(3, 0) - -PUT_VC1_MSPEL(0, 1) -PUT_VC1_MSPEL(1, 1) -PUT_VC1_MSPEL(2, 1) -PUT_VC1_MSPEL(3, 1) - -PUT_VC1_MSPEL(0, 2) -PUT_VC1_MSPEL(1, 2) -PUT_VC1_MSPEL(2, 2) -PUT_VC1_MSPEL(3, 2) - -PUT_VC1_MSPEL(0, 3) -PUT_VC1_MSPEL(1, 3) -PUT_VC1_MSPEL(2, 3) -PUT_VC1_MSPEL(3, 3) - -av_cold void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) { - dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c; - dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c; - dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_c; - dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c; - dsp->vc1_inv_trans_8x8_dc = vc1_inv_trans_8x8_dc_c; - dsp->vc1_inv_trans_4x8_dc = vc1_inv_trans_4x8_dc_c; - dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_c; - dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_c; - dsp->vc1_h_overlap = vc1_h_overlap_c; - dsp->vc1_v_overlap = vc1_v_overlap_c; - dsp->vc1_v_loop_filter4 = vc1_v_loop_filter4_c; - dsp->vc1_h_loop_filter4 = vc1_h_loop_filter4_c; - dsp->vc1_v_loop_filter8 = vc1_v_loop_filter8_c; - dsp->vc1_h_loop_filter8 = vc1_h_loop_filter8_c; - dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_c; - dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_c; - - dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c; - dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c; - dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_c; - dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_c; - dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_c; - dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_c; - dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_c; - dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_c; - dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_c; - dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_c; - dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_c; - dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_c; - dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_c; - dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_c; - dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_c; - dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_c; - - dsp->avg_vc1_mspel_pixels_tab[ 0] = ff_avg_vc1_mspel_mc00_c; - dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_c; - dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_c; - dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_c; - dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_c; - dsp->avg_vc1_mspel_pixels_tab[ 5] = avg_vc1_mspel_mc11_c; - dsp->avg_vc1_mspel_pixels_tab[ 6] = avg_vc1_mspel_mc21_c; - dsp->avg_vc1_mspel_pixels_tab[ 7] = avg_vc1_mspel_mc31_c; - dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_c; - dsp->avg_vc1_mspel_pixels_tab[ 9] = avg_vc1_mspel_mc12_c; - dsp->avg_vc1_mspel_pixels_tab[10] = avg_vc1_mspel_mc22_c; - dsp->avg_vc1_mspel_pixels_tab[11] = avg_vc1_mspel_mc32_c; - dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_c; - dsp->avg_vc1_mspel_pixels_tab[13] = avg_vc1_mspel_mc13_c; - dsp->avg_vc1_mspel_pixels_tab[14] = avg_vc1_mspel_mc23_c; - dsp->avg_vc1_mspel_pixels_tab[15] = avg_vc1_mspel_mc33_c; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/vcr1.c b/tizen/distrib/ffmpeg/libavcodec/vcr1.c deleted file mode 100644 index 31da94f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vcr1.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * ATI VCR1 codec - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * ati vcr1 codec. - */ - -#include "avcodec.h" -#include "dsputil.h" - -//#undef NDEBUG -//#include - -/* Disable the encoder. */ -#undef CONFIG_VCR1_ENCODER -#define CONFIG_VCR1_ENCODER 0 - -typedef struct VCR1Context{ - AVCodecContext *avctx; - AVFrame picture; - int delta[16]; - int offset[4]; -} VCR1Context; - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VCR1Context * const a = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&a->picture; - const uint8_t *bytestream= buf; - int i, 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= FF_I_TYPE; - p->key_frame= 1; - - for(i=0; i<16; i++){ - a->delta[i]= *(bytestream++); - bytestream++; - } - - for(y=0; yheight; y++){ - int offset; - uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ]; - - if((y&3) == 0){ - uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ]; - uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ]; - - for(i=0; i<4; i++) - a->offset[i]= *(bytestream++); - - offset= a->offset[0] - a->delta[ bytestream[2]&0xF ]; - for(x=0; xwidth; x+=4){ - luma[0]=( offset += a->delta[ bytestream[2]&0xF ]); - luma[1]=( offset += a->delta[ bytestream[2]>>4 ]); - luma[2]=( offset += a->delta[ bytestream[0]&0xF ]); - luma[3]=( offset += a->delta[ bytestream[0]>>4 ]); - luma += 4; - - *(cb++) = bytestream[3]; - *(cr++) = bytestream[1]; - - bytestream+= 4; - } - }else{ - offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ]; - - for(x=0; xwidth; x+=8){ - luma[0]=( offset += a->delta[ bytestream[2]&0xF ]); - luma[1]=( offset += a->delta[ bytestream[2]>>4 ]); - luma[2]=( offset += a->delta[ bytestream[3]&0xF ]); - luma[3]=( offset += a->delta[ bytestream[3]>>4 ]); - luma[4]=( offset += a->delta[ bytestream[0]&0xF ]); - luma[5]=( offset += a->delta[ bytestream[0]>>4 ]); - luma[6]=( offset += a->delta[ bytestream[1]&0xF ]); - luma[7]=( offset += a->delta[ bytestream[1]>>4 ]); - luma += 8; - bytestream+= 4; - } - } - } - - *picture= *(AVFrame*)&a->picture; - *data_size = sizeof(AVPicture); - - emms_c(); - - return buf_size; -} - -#if CONFIG_VCR1_ENCODER -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - VCR1Context * const a = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&a->picture; - int size; - - *p = *pict; - p->pict_type= FF_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 av_cold void common_init(AVCodecContext *avctx){ - VCR1Context * const a = avctx->priv_data; - - avctx->coded_frame= (AVFrame*)&a->picture; - a->avctx= avctx; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - - common_init(avctx); - - avctx->pix_fmt= PIX_FMT_YUV410P; - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - VCR1Context *s = avctx->priv_data; - - if (s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -#if CONFIG_VCR1_ENCODER -static av_cold int encode_init(AVCodecContext *avctx){ - - common_init(avctx); - - return 0; -} -#endif - -AVCodec vcr1_decoder = { - "vcr1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VCR1, - sizeof(VCR1Context), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"), -}; - -#if CONFIG_VCR1_ENCODER -AVCodec vcr1_encoder = { - "vcr1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VCR1, - sizeof(VCR1Context), - encode_init, - encode_frame, - //encode_end, - .long_name = NULL_IF_CONFIG_SMALL("ATI VCR1"), -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/vdpau.c b/tizen/distrib/ffmpeg/libavcodec/vdpau.c deleted file mode 100644 index bd721e8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vdpau.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Video Decode and Presentation API for UNIX (VDPAU) is used for - * HW decode acceleration for MPEG-1/2, MPEG-4 ASP, H.264 and VC-1. - * - * Copyright (c) 2008 NVIDIA - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avcodec.h" -#include "h264.h" -#include "vc1.h" - -#undef NDEBUG -#include - -#include "vdpau.h" -#include "vdpau_internal.h" - -/** - * \addtogroup VDPAU_Decoding - * - * @{ - */ - -void ff_vdpau_h264_set_reference_frames(MpegEncContext *s) -{ - H264Context *h = s->avctx->priv_data; - struct vdpau_render_state *render, *render_ref; - VdpReferenceFrameH264 *rf, *rf2; - Picture *pic; - int i, list, pic_frame_idx; - - render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; - assert(render); - - rf = &render->info.h264.referenceFrames[0]; -#define H264_RF_COUNT FF_ARRAY_ELEMS(render->info.h264.referenceFrames) - - for (list = 0; list < 2; ++list) { - Picture **lp = list ? h->long_ref : h->short_ref; - int ls = list ? 16 : h->short_ref_count; - - for (i = 0; i < ls; ++i) { - pic = lp[i]; - if (!pic || !pic->reference) - continue; - pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num; - - render_ref = (struct vdpau_render_state *)pic->data[0]; - assert(render_ref); - - rf2 = &render->info.h264.referenceFrames[0]; - while (rf2 != rf) { - if ( - (rf2->surface == render_ref->surface) - && (rf2->is_long_term == pic->long_ref) - && (rf2->frame_idx == pic_frame_idx) - ) - break; - ++rf2; - } - if (rf2 != rf) { - rf2->top_is_reference |= (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; - rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; - continue; - } - - if (rf >= &render->info.h264.referenceFrames[H264_RF_COUNT]) - continue; - - rf->surface = render_ref->surface; - rf->is_long_term = pic->long_ref; - rf->top_is_reference = (pic->reference & PICT_TOP_FIELD) ? VDP_TRUE : VDP_FALSE; - rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE; - rf->field_order_cnt[0] = pic->field_poc[0]; - rf->field_order_cnt[1] = pic->field_poc[1]; - rf->frame_idx = pic_frame_idx; - - ++rf; - } - } - - for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf) { - rf->surface = VDP_INVALID_HANDLE; - rf->is_long_term = 0; - rf->top_is_reference = 0; - rf->bottom_is_reference = 0; - rf->field_order_cnt[0] = 0; - rf->field_order_cnt[1] = 0; - rf->frame_idx = 0; - } -} - -void ff_vdpau_add_data_chunk(MpegEncContext *s, - const uint8_t *buf, int buf_size) -{ - struct vdpau_render_state *render; - - render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; - assert(render); - - render->bitstream_buffers= av_fast_realloc( - render->bitstream_buffers, - &render->bitstream_buffers_allocated, - sizeof(*render->bitstream_buffers)*(render->bitstream_buffers_used + 1) - ); - - render->bitstream_buffers[render->bitstream_buffers_used].struct_version = VDP_BITSTREAM_BUFFER_VERSION; - render->bitstream_buffers[render->bitstream_buffers_used].bitstream = buf; - render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = buf_size; - render->bitstream_buffers_used++; -} - -void ff_vdpau_h264_picture_start(MpegEncContext *s) -{ - H264Context *h = s->avctx->priv_data; - struct vdpau_render_state *render; - int i; - - render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; - assert(render); - - for (i = 0; i < 2; ++i) { - int foc = s->current_picture_ptr->field_poc[i]; - if (foc == INT_MAX) - foc = 0; - render->info.h264.field_order_cnt[i] = foc; - } - - render->info.h264.frame_num = h->frame_num; -} - -void ff_vdpau_h264_picture_complete(MpegEncContext *s) -{ - H264Context *h = s->avctx->priv_data; - struct vdpau_render_state *render; - - render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; - assert(render); - - render->info.h264.slice_count = h->slice_num; - if (render->info.h264.slice_count < 1) - return; - - render->info.h264.is_reference = (s->current_picture_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE; - render->info.h264.field_pic_flag = s->picture_structure != PICT_FRAME; - render->info.h264.bottom_field_flag = s->picture_structure == PICT_BOTTOM_FIELD; - render->info.h264.num_ref_frames = h->sps.ref_frame_count; - render->info.h264.mb_adaptive_frame_field_flag = h->sps.mb_aff && !render->info.h264.field_pic_flag; - render->info.h264.constrained_intra_pred_flag = h->pps.constrained_intra_pred; - render->info.h264.weighted_pred_flag = h->pps.weighted_pred; - render->info.h264.weighted_bipred_idc = h->pps.weighted_bipred_idc; - render->info.h264.frame_mbs_only_flag = h->sps.frame_mbs_only_flag; - render->info.h264.transform_8x8_mode_flag = h->pps.transform_8x8_mode; - render->info.h264.chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0]; - render->info.h264.second_chroma_qp_index_offset = h->pps.chroma_qp_index_offset[1]; - render->info.h264.pic_init_qp_minus26 = h->pps.init_qp - 26; - render->info.h264.num_ref_idx_l0_active_minus1 = h->pps.ref_count[0] - 1; - render->info.h264.num_ref_idx_l1_active_minus1 = h->pps.ref_count[1] - 1; - render->info.h264.log2_max_frame_num_minus4 = h->sps.log2_max_frame_num - 4; - render->info.h264.pic_order_cnt_type = h->sps.poc_type; - render->info.h264.log2_max_pic_order_cnt_lsb_minus4 = h->sps.poc_type ? 0 : h->sps.log2_max_poc_lsb - 4; - render->info.h264.delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag; - render->info.h264.direct_8x8_inference_flag = h->sps.direct_8x8_inference_flag; - render->info.h264.entropy_coding_mode_flag = h->pps.cabac; - render->info.h264.pic_order_present_flag = h->pps.pic_order_present; - render->info.h264.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; - render->info.h264.redundant_pic_cnt_present_flag = h->pps.redundant_pic_cnt_present; - memcpy(render->info.h264.scaling_lists_4x4, h->pps.scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4)); - memcpy(render->info.h264.scaling_lists_8x8, h->pps.scaling_matrix8, sizeof(render->info.h264.scaling_lists_8x8)); - - ff_draw_horiz_band(s, 0, s->avctx->height); - render->bitstream_buffers_used = 0; -} - -void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, - int buf_size, int slice_count) -{ - struct vdpau_render_state *render, *last, *next; - int i; - - if (!s->current_picture_ptr) return; - - render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; - assert(render); - - /* fill VdpPictureInfoMPEG1Or2 struct */ - render->info.mpeg.picture_structure = s->picture_structure; - render->info.mpeg.picture_coding_type = s->pict_type; - render->info.mpeg.intra_dc_precision = s->intra_dc_precision; - render->info.mpeg.frame_pred_frame_dct = s->frame_pred_frame_dct; - render->info.mpeg.concealment_motion_vectors = s->concealment_motion_vectors; - render->info.mpeg.intra_vlc_format = s->intra_vlc_format; - render->info.mpeg.alternate_scan = s->alternate_scan; - render->info.mpeg.q_scale_type = s->q_scale_type; - render->info.mpeg.top_field_first = s->top_field_first; - render->info.mpeg.full_pel_forward_vector = s->full_pel[0]; // MPEG-1 only. Set 0 for MPEG-2 - render->info.mpeg.full_pel_backward_vector = s->full_pel[1]; // MPEG-1 only. Set 0 for MPEG-2 - render->info.mpeg.f_code[0][0] = s->mpeg_f_code[0][0]; // For MPEG-1 fill both horiz. & vert. - render->info.mpeg.f_code[0][1] = s->mpeg_f_code[0][1]; - render->info.mpeg.f_code[1][0] = s->mpeg_f_code[1][0]; - render->info.mpeg.f_code[1][1] = s->mpeg_f_code[1][1]; - for (i = 0; i < 64; ++i) { - render->info.mpeg.intra_quantizer_matrix[i] = s->intra_matrix[i]; - render->info.mpeg.non_intra_quantizer_matrix[i] = s->inter_matrix[i]; - } - - render->info.mpeg.forward_reference = VDP_INVALID_HANDLE; - render->info.mpeg.backward_reference = VDP_INVALID_HANDLE; - - switch(s->pict_type){ - case FF_B_TYPE: - next = (struct vdpau_render_state *)s->next_picture.data[0]; - assert(next); - render->info.mpeg.backward_reference = next->surface; - // no return here, going to set forward prediction - case FF_P_TYPE: - last = (struct vdpau_render_state *)s->last_picture.data[0]; - if (!last) // FIXME: Does this test make sense? - last = render; // predict second field from the first - render->info.mpeg.forward_reference = last->surface; - } - - ff_vdpau_add_data_chunk(s, buf, buf_size); - - render->info.mpeg.slice_count = slice_count; - - if (slice_count) - ff_draw_horiz_band(s, 0, s->avctx->height); - render->bitstream_buffers_used = 0; -} - -void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, - int buf_size) -{ - VC1Context *v = s->avctx->priv_data; - struct vdpau_render_state *render, *last, *next; - - render = (struct vdpau_render_state *)s->current_picture.data[0]; - assert(render); - - /* fill LvPictureInfoVC1 struct */ - render->info.vc1.frame_coding_mode = v->fcm; - render->info.vc1.postprocflag = v->postprocflag; - render->info.vc1.pulldown = v->broadcast; - render->info.vc1.interlace = v->interlace; - render->info.vc1.tfcntrflag = v->tfcntrflag; - render->info.vc1.finterpflag = v->finterpflag; - render->info.vc1.psf = v->psf; - render->info.vc1.dquant = v->dquant; - render->info.vc1.panscan_flag = v->panscanflag; - render->info.vc1.refdist_flag = v->refdist_flag; - render->info.vc1.quantizer = v->quantizer_mode; - render->info.vc1.extended_mv = v->extended_mv; - render->info.vc1.extended_dmv = v->extended_dmv; - render->info.vc1.overlap = v->overlap; - render->info.vc1.vstransform = v->vstransform; - render->info.vc1.loopfilter = v->s.loop_filter; - render->info.vc1.fastuvmc = v->fastuvmc; - render->info.vc1.range_mapy_flag = v->range_mapy_flag; - render->info.vc1.range_mapy = v->range_mapy; - render->info.vc1.range_mapuv_flag = v->range_mapuv_flag; - render->info.vc1.range_mapuv = v->range_mapuv; - /* Specific to simple/main profile only */ - render->info.vc1.multires = v->multires; - render->info.vc1.syncmarker = v->s.resync_marker; - render->info.vc1.rangered = v->rangered | (v->rangeredfrm << 1); - render->info.vc1.maxbframes = v->s.max_b_frames; - - render->info.vc1.deblockEnable = v->postprocflag & 1; - render->info.vc1.pquant = v->pq; - - render->info.vc1.forward_reference = VDP_INVALID_HANDLE; - render->info.vc1.backward_reference = VDP_INVALID_HANDLE; - - if (v->bi_type) - render->info.vc1.picture_type = 4; - else - render->info.vc1.picture_type = s->pict_type - 1 + s->pict_type / 3; - - switch(s->pict_type){ - case FF_B_TYPE: - next = (struct vdpau_render_state *)s->next_picture.data[0]; - assert(next); - render->info.vc1.backward_reference = next->surface; - // no break here, going to set forward prediction - case FF_P_TYPE: - last = (struct vdpau_render_state *)s->last_picture.data[0]; - if (!last) // FIXME: Does this test make sense? - last = render; // predict second field from the first - render->info.vc1.forward_reference = last->surface; - } - - ff_vdpau_add_data_chunk(s, buf, buf_size); - - render->info.vc1.slice_count = 1; - - ff_draw_horiz_band(s, 0, s->avctx->height); - render->bitstream_buffers_used = 0; -} - -void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, - int buf_size) -{ - struct vdpau_render_state *render, *last, *next; - int i; - - if (!s->current_picture_ptr) return; - - render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; - assert(render); - - /* fill VdpPictureInfoMPEG4Part2 struct */ - render->info.mpeg4.trd[0] = s->pp_time; - render->info.mpeg4.trb[0] = s->pb_time; - render->info.mpeg4.trd[1] = s->pp_field_time >> 1; - render->info.mpeg4.trb[1] = s->pb_field_time >> 1; - render->info.mpeg4.vop_time_increment_resolution = s->avctx->time_base.den; - render->info.mpeg4.vop_coding_type = 0; - render->info.mpeg4.vop_fcode_forward = s->f_code; - render->info.mpeg4.vop_fcode_backward = s->b_code; - render->info.mpeg4.resync_marker_disable = !s->resync_marker; - render->info.mpeg4.interlaced = !s->progressive_sequence; - render->info.mpeg4.quant_type = s->mpeg_quant; - render->info.mpeg4.quarter_sample = s->quarter_sample; - render->info.mpeg4.short_video_header = s->avctx->codec->id == CODEC_ID_H263; - render->info.mpeg4.rounding_control = s->no_rounding; - render->info.mpeg4.alternate_vertical_scan_flag = s->alternate_scan; - render->info.mpeg4.top_field_first = s->top_field_first; - for (i = 0; i < 64; ++i) { - render->info.mpeg4.intra_quantizer_matrix[i] = s->intra_matrix[i]; - render->info.mpeg4.non_intra_quantizer_matrix[i] = s->inter_matrix[i]; - } - render->info.mpeg4.forward_reference = VDP_INVALID_HANDLE; - render->info.mpeg4.backward_reference = VDP_INVALID_HANDLE; - - switch (s->pict_type) { - case FF_B_TYPE: - next = (struct vdpau_render_state *)s->next_picture.data[0]; - assert(next); - render->info.mpeg4.backward_reference = next->surface; - render->info.mpeg4.vop_coding_type = 2; - // no break here, going to set forward prediction - case FF_P_TYPE: - last = (struct vdpau_render_state *)s->last_picture.data[0]; - assert(last); - render->info.mpeg4.forward_reference = last->surface; - } - - ff_vdpau_add_data_chunk(s, buf, buf_size); - - ff_draw_horiz_band(s, 0, s->avctx->height); - render->bitstream_buffers_used = 0; -} - -/* @}*/ diff --git a/tizen/distrib/ffmpeg/libavcodec/vdpau.h b/tizen/distrib/ffmpeg/libavcodec/vdpau.h deleted file mode 100644 index a8fa4d3..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vdpau.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * The Video Decode and Presentation API for UNIX (VDPAU) is used for - * hardware-accelerated decoding of MPEG-1/2, H.264 and VC-1. - * - * Copyright (C) 2008 NVIDIA - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VDPAU_H -#define AVCODEC_VDPAU_H - -/** - * \defgroup Decoder VDPAU Decoder and Renderer - * - * VDPAU hardware acceleration has two modules - * - VDPAU decoding - * - VDPAU presentation - * - * The VDPAU decoding module parses all headers using FFmpeg - * parsing mechanisms and uses VDPAU for the actual decoding. - * - * As per the current implementation, the actual decoding - * and rendering (API calls) are done as part of the VDPAU - * presentation (vo_vdpau.c) module. - * - * @{ - * \defgroup VDPAU_Decoding VDPAU Decoding - * \ingroup Decoder - * @{ - */ - -#include -#include - -/** \brief The videoSurface is used for rendering. */ -#define FF_VDPAU_STATE_USED_FOR_RENDER 1 - -/** - * \brief The videoSurface is needed for reference/prediction. - * The codec manipulates this. - */ -#define FF_VDPAU_STATE_USED_FOR_REFERENCE 2 - -/** - * \brief This structure is used as a callback between the FFmpeg - * decoder (vd_) and presentation (vo_) module. - * This is used for defining a video frame containing surface, - * picture parameter, bitstream information etc which are passed - * between the FFmpeg decoder and its clients. - */ -struct vdpau_render_state { - VdpVideoSurface surface; ///< Used as rendered surface, never changed. - - int state; ///< Holds FF_VDPAU_STATE_* values. - - /** picture parameter information for all supported codecs */ - union VdpPictureInfo { - VdpPictureInfoH264 h264; - VdpPictureInfoMPEG1Or2 mpeg; - VdpPictureInfoVC1 vc1; - VdpPictureInfoMPEG4Part2 mpeg4; - } info; - - /** Describe size/location of the compressed video data. - Set to 0 when freeing bitstream_buffers. */ - int bitstream_buffers_allocated; - int bitstream_buffers_used; - /** The user is responsible for freeing this buffer using av_freep(). */ - VdpBitstreamBuffer *bitstream_buffers; -}; - -/* @}*/ - -#endif /* AVCODEC_VDPAU_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vdpau_internal.h b/tizen/distrib/ffmpeg/libavcodec/vdpau_internal.h deleted file mode 100644 index 0a8d0b6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vdpau_internal.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Video Decode and Presentation API for UNIX (VDPAU) is used for - * HW decode acceleration for MPEG-1/2, H.264 and VC-1. - * - * Copyright (C) 2008 NVIDIA - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VDPAU_INTERNAL_H -#define AVCODEC_VDPAU_INTERNAL_H - -#include -#include "mpegvideo.h" - -void ff_vdpau_add_data_chunk(MpegEncContext *s, const uint8_t *buf, - int buf_size); - -void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf, - int buf_size, int slice_count); - -void ff_vdpau_h264_picture_start(MpegEncContext *s); -void ff_vdpau_h264_set_reference_frames(MpegEncContext *s); -void ff_vdpau_h264_picture_complete(MpegEncContext *s); - -void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf, - int buf_size); - -void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, - int buf_size); - -#endif /* AVCODEC_VDPAU_INTERNAL_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vmdav.c b/tizen/distrib/ffmpeg/libavcodec/vmdav.c deleted file mode 100644 index 4914d2a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vmdav.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Sierra VMD Audio & Video Decoders - * Copyright (C) 2004 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sierra VMD audio & video decoders - * by Vladimir "VAG" Gneushev (vagsoft at mail.ru) - * for more information on the Sierra VMD format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * The video decoder outputs PAL8 colorspace data. The decoder expects - * a 0x330-byte VMD file header to be transmitted via extradata during - * codec initialization. Each encoded frame that is sent to this decoder - * is expected to be prepended with the appropriate 16-byte frame - * information record from the VMD file. - * - * The audio decoder, like the video decoder, expects each encoded data - * chunk to be prepended with the appropriate 16-byte frame information - * record from the VMD file. It does not require the 0x330-byte VMD file - * header, but it does need the audio setup parameters passed in through - * normal libavcodec API means. - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#define VMD_HEADER_SIZE 0x330 -#define PALETTE_COUNT 256 - -/* - * Video Decoder - */ - -typedef struct VmdVideoContext { - - AVCodecContext *avctx; - AVFrame frame; - AVFrame prev_frame; - - const unsigned char *buf; - int size; - - unsigned char palette[PALETTE_COUNT * 4]; - unsigned char *unpack_buffer; - int unpack_buffer_size; - - int x_off, y_off; -} VmdVideoContext; - -#define QUEUE_SIZE 0x1000 -#define QUEUE_MASK 0x0FFF - -static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len) -{ - const unsigned char *s; - unsigned char *d; - unsigned char *d_end; - unsigned char queue[QUEUE_SIZE]; - unsigned int qpos; - unsigned int dataleft; - unsigned int chainofs; - unsigned int chainlen; - unsigned int speclen; - unsigned char tag; - unsigned int i, j; - - s = src; - d = dest; - d_end = d + dest_len; - dataleft = AV_RL32(s); - s += 4; - memset(queue, 0x20, QUEUE_SIZE); - if (AV_RL32(s) == 0x56781234) { - s += 4; - qpos = 0x111; - speclen = 0xF + 3; - } else { - qpos = 0xFEE; - speclen = 100; /* no speclen */ - } - - while (dataleft > 0) { - tag = *s++; - if ((tag == 0xFF) && (dataleft > 8)) { - if (d + 8 > d_end) - return; - for (i = 0; i < 8; i++) { - queue[qpos++] = *d++ = *s++; - qpos &= QUEUE_MASK; - } - dataleft -= 8; - } else { - for (i = 0; i < 8; i++) { - if (dataleft == 0) - break; - if (tag & 0x01) { - if (d + 1 > d_end) - return; - queue[qpos++] = *d++ = *s++; - qpos &= QUEUE_MASK; - dataleft--; - } else { - chainofs = *s++; - chainofs |= ((*s & 0xF0) << 4); - chainlen = (*s++ & 0x0F) + 3; - if (chainlen == speclen) - chainlen = *s++ + 0xF + 3; - if (d + chainlen > d_end) - return; - for (j = 0; j < chainlen; j++) { - *d = queue[chainofs++ & QUEUE_MASK]; - queue[qpos++] = *d++; - qpos &= QUEUE_MASK; - } - dataleft -= chainlen; - } - tag >>= 1; - } - } - } -} - -static int rle_unpack(const unsigned char *src, unsigned char *dest, - int src_len, int dest_len) -{ - const unsigned char *ps; - unsigned char *pd; - int i, l; - unsigned char *dest_end = dest + dest_len; - - ps = src; - pd = dest; - if (src_len & 1) - *pd++ = *ps++; - - src_len >>= 1; - i = 0; - do { - l = *ps++; - if (l & 0x80) { - l = (l & 0x7F) * 2; - if (pd + l > dest_end) - return ps - src; - memcpy(pd, ps, l); - ps += l; - pd += l; - } else { - if (pd + i > dest_end) - return ps - src; - for (i = 0; i < l; i++) { - *pd++ = ps[0]; - *pd++ = ps[1]; - } - ps += 2; - } - i += l; - } while (i < src_len); - - return ps - src; -} - -static void vmd_decode(VmdVideoContext *s) -{ - int i; - unsigned int *palette32; - unsigned char r, g, b; - - /* point to the start of the encoded data */ - const unsigned char *p = s->buf + 16; - - const unsigned char *pb; - unsigned char meth; - unsigned char *dp; /* pointer to current frame */ - unsigned char *pp; /* pointer to previous frame */ - unsigned char len; - int ofs; - - int frame_x, frame_y; - int frame_width, frame_height; - int dp_size; - - frame_x = AV_RL16(&s->buf[6]); - frame_y = AV_RL16(&s->buf[8]); - frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; - frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; - - if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && - (frame_x || frame_y)) { - - s->x_off = frame_x; - s->y_off = frame_y; - } - frame_x -= s->x_off; - frame_y -= s->y_off; - - /* if only a certain region will be updated, copy the entire previous - * frame before the decode */ - if (frame_x || frame_y || (frame_width != s->avctx->width) || - (frame_height != s->avctx->height)) { - - memcpy(s->frame.data[0], s->prev_frame.data[0], - s->avctx->height * s->frame.linesize[0]); - } - - /* check if there is a new palette */ - if (s->buf[15] & 0x02) { - p += 2; - palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *p++ * 4; - g = *p++ * 4; - b = *p++ * 4; - palette32[i] = (r << 16) | (g << 8) | (b); - } - s->size -= (256 * 3 + 2); - } - if (s->size >= 0) { - /* originally UnpackFrame in VAG's code */ - pb = p; - meth = *pb++; - if (meth & 0x80) { - lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size); - meth &= 0x7F; - pb = s->unpack_buffer; - } - - dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; - dp_size = s->frame.linesize[0] * s->avctx->height; - pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; - switch (meth) { - case 1: - for (i = 0; i < frame_height; i++) { - ofs = 0; - do { - len = *pb++; - if (len & 0x80) { - len = (len & 0x7F) + 1; - if (ofs + len > frame_width) - return; - memcpy(&dp[ofs], pb, len); - pb += len; - ofs += len; - } else { - /* interframe pixel copy */ - if (ofs + len + 1 > frame_width) - return; - memcpy(&dp[ofs], &pp[ofs], len + 1); - ofs += len + 1; - } - } while (ofs < frame_width); - if (ofs > frame_width) { - av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", - ofs, frame_width); - break; - } - dp += s->frame.linesize[0]; - pp += s->prev_frame.linesize[0]; - } - break; - - case 2: - for (i = 0; i < frame_height; i++) { - memcpy(dp, pb, frame_width); - pb += frame_width; - dp += s->frame.linesize[0]; - pp += s->prev_frame.linesize[0]; - } - break; - - case 3: - for (i = 0; i < frame_height; i++) { - ofs = 0; - do { - len = *pb++; - if (len & 0x80) { - len = (len & 0x7F) + 1; - if (*pb++ == 0xFF) - len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); - else - memcpy(&dp[ofs], pb, len); - pb += len; - ofs += len; - } else { - /* interframe pixel copy */ - if (ofs + len + 1 > frame_width) - return; - memcpy(&dp[ofs], &pp[ofs], len + 1); - ofs += len + 1; - } - } while (ofs < frame_width); - if (ofs > frame_width) { - av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", - ofs, frame_width); - } - dp += s->frame.linesize[0]; - pp += s->prev_frame.linesize[0]; - } - break; - } - } -} - -static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) -{ - VmdVideoContext *s = avctx->priv_data; - int i; - unsigned int *palette32; - int palette_index = 0; - unsigned char r, g, b; - unsigned char *vmd_header; - unsigned char *raw_palette; - - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - /* make sure the VMD header made it */ - if (s->avctx->extradata_size != VMD_HEADER_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n", - VMD_HEADER_SIZE); - return -1; - } - vmd_header = (unsigned char *)avctx->extradata; - - s->unpack_buffer_size = AV_RL32(&vmd_header[800]); - s->unpack_buffer = av_malloc(s->unpack_buffer_size); - if (!s->unpack_buffer) - return -1; - - /* load up the initial palette */ - raw_palette = &vmd_header[28]; - palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = raw_palette[palette_index++] * 4; - g = raw_palette[palette_index++] * 4; - b = raw_palette[palette_index++] * 4; - palette32[i] = (r << 16) | (g << 8) | (b); - } - - return 0; -} - -static int vmdvideo_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VmdVideoContext *s = avctx->priv_data; - - s->buf = buf; - s->size = buf_size; - - if (buf_size < 16) - return buf_size; - - s->frame.reference = 1; - if (avctx->get_buffer(avctx, &s->frame)) { - av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); - return -1; - } - - vmd_decode(s); - - /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); - - /* shuffle frames */ - FFSWAP(AVFrame, s->frame, s->prev_frame); - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->prev_frame; - - /* report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) -{ - VmdVideoContext *s = avctx->priv_data; - - if (s->prev_frame.data[0]) - avctx->release_buffer(avctx, &s->prev_frame); - av_free(s->unpack_buffer); - - return 0; -} - - -/* - * Audio Decoder - */ - -typedef struct VmdAudioContext { - AVCodecContext *avctx; - int channels; - int bits; - int block_align; - int predictors[2]; -} VmdAudioContext; - -static const uint16_t vmdaudio_table[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 av_cold int vmdaudio_decode_init(AVCodecContext *avctx) -{ - VmdAudioContext *s = avctx->priv_data; - - s->avctx = avctx; - s->channels = avctx->channels; - s->bits = avctx->bits_per_coded_sample; - s->block_align = avctx->block_align; - avctx->sample_fmt = SAMPLE_FMT_S16; - - av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", - s->channels, s->bits, s->block_align, avctx->sample_rate); - - return 0; -} - -static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, - const uint8_t *buf, int buf_size, int stereo) -{ - int i; - int chan = 0; - int16_t *out = (int16_t*)data; - - for(i = 0; i < buf_size; i++) { - if(buf[i] & 0x80) - s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; - else - s->predictors[chan] += vmdaudio_table[buf[i]]; - s->predictors[chan] = av_clip_int16(s->predictors[chan]); - out[i] = s->predictors[chan]; - chan ^= stereo; - } -} - -static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, - const uint8_t *buf, int silence, int data_size) -{ - int bytes_decoded = 0; - int i; - -// if (silence) -// av_log(s->avctx, AV_LOG_INFO, "silent block!\n"); - if (s->channels == 2) { - - /* stereo handling */ - if (silence) { - memset(data, 0, data_size * 2); - } else { - if (s->bits == 16) - vmdaudio_decode_audio(s, data, buf, data_size, 1); - else { - /* copy the data but convert it to signed */ - for (i = 0; i < data_size; i++){ - *data++ = buf[i] + 0x80; - *data++ = buf[i] + 0x80; - } - } - } - } else { - bytes_decoded = data_size * 2; - - /* mono handling */ - if (silence) { - memset(data, 0, data_size * 2); - } else { - if (s->bits == 16) { - vmdaudio_decode_audio(s, data, buf, data_size, 0); - } else { - /* copy the data but convert it to signed */ - for (i = 0; i < data_size; i++){ - *data++ = buf[i] + 0x80; - *data++ = buf[i] + 0x80; - } - } - } - } - - return data_size * 2; -} - -static int vmdaudio_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VmdAudioContext *s = avctx->priv_data; - unsigned char *output_samples = (unsigned char *)data; - - /* point to the start of the encoded data */ - const unsigned char *p = buf + 16; - - if (buf_size < 16) - return buf_size; - - if (buf[6] == 1) { - /* the chunk contains audio */ - *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16); - } else if (buf[6] == 2) { - /* initial chunk, may contain audio and silence */ - uint32_t flags = AV_RB32(p); - int raw_block_size = s->block_align * s->bits / 8; - int silent_chunks; - if(flags == 0xFFFFFFFF) - silent_chunks = 32; - else - silent_chunks = av_log2(flags + 1); - if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2) - return -1; - *data_size = 0; - memset(output_samples, 0, raw_block_size * silent_chunks); - output_samples += raw_block_size * silent_chunks; - *data_size = raw_block_size * silent_chunks; - *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20); - } else if (buf[6] == 3) { - /* silent chunk */ - *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0); - } - - return buf_size; -} - - -/* - * Public Data Structures - */ - -AVCodec vmdvideo_decoder = { - "vmdvideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VMDVIDEO, - sizeof(VmdVideoContext), - vmdvideo_decode_init, - NULL, - vmdvideo_decode_end, - vmdvideo_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), -}; - -AVCodec vmdaudio_decoder = { - "vmdaudio", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_VMDAUDIO, - sizeof(VmdAudioContext), - vmdaudio_decode_init, - NULL, - NULL, - vmdaudio_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vmnc.c b/tizen/distrib/ffmpeg/libavcodec/vmnc.c deleted file mode 100644 index 49aaeb2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vmnc.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * VMware Screen Codec (VMnc) decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VMware Screen Codec (VMnc) decoder - * As Alex Beregszaszi discovered, this is effectively RFB data dump - */ - -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -enum EncTypes { - MAGIC_WMVd = 0x574D5664, - MAGIC_WMVe, - MAGIC_WMVf, - MAGIC_WMVg, - MAGIC_WMVh, - MAGIC_WMVi, - MAGIC_WMVj -}; - -enum HexTile_Flags { - HT_RAW = 1, // tile is raw - HT_BKG = 2, // background color is present - HT_FG = 4, // foreground color is present - HT_SUB = 8, // subrects are present - HT_CLR = 16 // each subrect has own color -}; - -/* - * Decoder context - */ -typedef struct VmncContext { - AVCodecContext *avctx; - AVFrame pic; - - int bpp; - int bpp2; - int bigendian; - uint8_t pal[768]; - int width, height; - - /* cursor data */ - int cur_w, cur_h; - int cur_x, cur_y; - int cur_hx, cur_hy; - uint8_t* curbits, *curmask; - uint8_t* screendta; -} VmncContext; - -/* read pixel value from stream */ -static av_always_inline int vmnc_get_pixel(const uint8_t* buf, int bpp, int be) { - switch(bpp * 2 + be) { - case 2: - case 3: return *buf; - case 4: return AV_RL16(buf); - case 5: return AV_RB16(buf); - case 8: return AV_RL32(buf); - case 9: return AV_RB32(buf); - default: return 0; - } -} - -static void load_cursor(VmncContext *c, const uint8_t *src) -{ - int i, j, p; - const int bpp = c->bpp2; - uint8_t *dst8 = c->curbits; - uint16_t *dst16 = (uint16_t*)c->curbits; - uint32_t *dst32 = (uint32_t*)c->curbits; - - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { - p = vmnc_get_pixel(src, bpp, c->bigendian); - src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; - } - } - dst8 = c->curmask; - dst16 = (uint16_t*)c->curmask; - dst32 = (uint32_t*)c->curmask; - for(j = 0; j < c->cur_h; j++) { - for(i = 0; i < c->cur_w; i++) { - p = vmnc_get_pixel(src, bpp, c->bigendian); - src += bpp; - if(bpp == 1) *dst8++ = p; - if(bpp == 2) *dst16++ = p; - if(bpp == 4) *dst32++ = p; - } - } -} - -static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy) -{ - int i, j; - int w, h, x, y; - w = c->cur_w; - if(c->width < c->cur_x + c->cur_w) w = c->width - c->cur_x; - h = c->cur_h; - if(c->height < c->cur_y + c->cur_h) h = c->height - c->cur_y; - x = c->cur_x; - y = c->cur_y; - if(x < 0) { - w += x; - x = 0; - } - if(y < 0) { - h += y; - y = 0; - } - - if((w < 1) || (h < 1)) return; - dst += x * c->bpp2 + y * stride; - - if(c->bpp2 == 1) { - uint8_t* cd = c->curbits, *msk = c->curmask; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) - dst[i] = (dst[i] & cd[i]) ^ msk[i]; - msk += c->cur_w; - cd += c->cur_w; - dst += stride; - } - } else if(c->bpp2 == 2) { - uint16_t* cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask; - uint16_t* dst2; - for(j = 0; j < h; j++) { - dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) - dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; - msk += c->cur_w; - cd += c->cur_w; - dst += stride; - } - } else if(c->bpp2 == 4) { - uint32_t* cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask; - uint32_t* dst2; - for(j = 0; j < h; j++) { - dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) - dst2[i] = (dst2[i] & cd[i]) ^ msk[i]; - msk += c->cur_w; - cd += c->cur_w; - dst += stride; - } - } -} - -/* fill rectangle with given color */ -static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride) -{ - int i, j; - dst += dx * bpp + dy * stride; - if(bpp == 1){ - for(j = 0; j < h; j++) { - memset(dst, color, w); - dst += stride; - } - }else if(bpp == 2){ - uint16_t* dst2; - for(j = 0; j < h; j++) { - dst2 = (uint16_t*)dst; - for(i = 0; i < w; i++) { - *dst2++ = color; - } - dst += stride; - } - }else if(bpp == 4){ - uint32_t* dst2; - for(j = 0; j < h; j++) { - dst2 = (uint32_t*)dst; - for(i = 0; i < w; i++) { - dst2[i] = color; - } - dst += stride; - } - } -} - -static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t* src, int bpp, int be, int stride) -{ - int i, j, p; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) { - p = vmnc_get_pixel(src, bpp, be); - src += bpp; - switch(bpp){ - case 1: - dst[i] = p; - break; - case 2: - ((uint16_t*)dst)[i] = p; - break; - case 4: - ((uint32_t*)dst)[i] = p; - break; - } - } - dst += stride; - } -} - -static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int ssize, int w, int h, int stride) -{ - int i, j, k; - int bg = 0, fg = 0, rects, color, flags, xy, wh; - const int bpp = c->bpp2; - uint8_t *dst2; - int bw = 16, bh = 16; - const uint8_t *ssrc=src; - - for(j = 0; j < h; j += 16) { - dst2 = dst; - bw = 16; - if(j + 16 > h) bh = h - j; - for(i = 0; i < w; i += 16, dst2 += 16 * bpp) { - if(src - ssrc >= ssize) { - av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); - return -1; - } - if(i + 16 > w) bw = w - i; - flags = *src++; - if(flags & HT_RAW) { - if(src - ssrc > ssize - bw * bh * bpp) { - av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); - return -1; - } - paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride); - src += bw * bh * bpp; - } else { - if(flags & HT_BKG) { - bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } - if(flags & HT_FG) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } - rects = 0; - if(flags & HT_SUB) - rects = *src++; - color = !!(flags & HT_CLR); - - paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride); - - if(src - ssrc > ssize - rects * (color * bpp + 2)) { - av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n"); - return -1; - } - for(k = 0; k < rects; k++) { - if(color) { - fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp; - } - xy = *src++; - wh = *src++; - paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); - } - } - } - dst += stride * 16; - } - return src - ssrc; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VmncContext * const c = avctx->priv_data; - uint8_t *outptr; - const uint8_t *src = buf; - int dx, dy, w, h, depth, enc, chunks, res, size_left; - - c->pic.reference = 1; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if(avctx->reget_buffer(avctx, &c->pic) < 0){ - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - - c->pic.key_frame = 0; - c->pic.pict_type = FF_P_TYPE; - - //restore screen after cursor - if(c->screendta) { - int i; - w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; - h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; - dx = c->cur_x; - if(dx < 0) { - w += dx; - dx = 0; - } - dy = c->cur_y; - if(dy < 0) { - h += dy; - dy = 0; - } - if((w > 0) && (h > 0)) { - outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2); - outptr += c->pic.linesize[0]; - } - } - } - src += 2; - chunks = AV_RB16(src); src += 2; - while(chunks--) { - dx = AV_RB16(src); src += 2; - dy = AV_RB16(src); src += 2; - w = AV_RB16(src); src += 2; - h = AV_RB16(src); src += 2; - enc = AV_RB32(src); src += 4; - outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - size_left = buf_size - (src - buf); - switch(enc) { - case MAGIC_WMVd: // cursor - if(size_left < 2 + w * h * c->bpp2 * 2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left); - return -1; - } - src += 2; - c->cur_w = w; - c->cur_h = h; - c->cur_hx = dx; - c->cur_hy = dy; - if((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) { - av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h); - c->cur_hx = c->cur_hy = 0; - } - c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2); - c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2); - c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2); - load_cursor(c, src); - src += w * h * c->bpp2 * 2; - break; - case MAGIC_WMVe: // unknown - src += 2; - break; - case MAGIC_WMVf: // update cursor position - c->cur_x = dx - c->cur_hx; - c->cur_y = dy - c->cur_hy; - break; - case MAGIC_WMVg: // unknown - src += 10; - break; - case MAGIC_WMVh: // unknown - src += 4; - break; - case MAGIC_WMVi: // ServerInitialization struct - c->pic.key_frame = 1; - c->pic.pict_type = FF_I_TYPE; - depth = *src++; - if(depth != c->bpp) { - av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth); - } - src++; - c->bigendian = *src++; - if(c->bigendian & (~1)) { - av_log(avctx, AV_LOG_INFO, "Invalid header: bigendian flag = %i\n", c->bigendian); - return -1; - } - //skip the rest of pixel format data - src += 13; - break; - case MAGIC_WMVj: // unknown - src += 2; - break; - case 0x00000000: // raw rectangle data - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); - return -1; - } - if(size_left < w * h * c->bpp2) { - av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left); - return -1; - } - paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]); - src += w * h * c->bpp2; - break; - case 0x00000005: // HexTile encoded rectangle - if((dx + w > c->width) || (dy + h > c->height)) { - av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height); - return -1; - } - res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]); - if(res < 0) - return -1; - src += res; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc); - chunks = 0; // leave chunks decoding loop - } - } - if(c->screendta){ - int i; - //save screen data before painting cursor - w = c->cur_w; - if(c->width < c->cur_x + w) w = c->width - c->cur_x; - h = c->cur_h; - if(c->height < c->cur_y + h) h = c->height - c->cur_y; - dx = c->cur_x; - if(dx < 0) { - w += dx; - dx = 0; - } - dy = c->cur_y; - if(dy < 0) { - h += dy; - dy = 0; - } - if((w > 0) && (h > 0)) { - outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0]; - for(i = 0; i < h; i++) { - memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2); - outptr += c->pic.linesize[0]; - } - outptr = c->pic.data[0]; - put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y); - } - } - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - - - -/* - * - * Init VMnc decoder - * - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - VmncContext * const c = avctx->priv_data; - - c->avctx = avctx; - - c->width = avctx->width; - c->height = avctx->height; - - c->bpp = avctx->bits_per_coded_sample; - c->bpp2 = c->bpp/8; - - switch(c->bpp){ - case 8: - avctx->pix_fmt = PIX_FMT_PAL8; - break; - case 16: - avctx->pix_fmt = PIX_FMT_RGB555; - break; - case 32: - avctx->pix_fmt = PIX_FMT_RGB32; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp); - } - - return 0; -} - - - -/* - * - * Uninit VMnc decoder - * - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - VmncContext * const c = avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - av_free(c->curbits); - av_free(c->curmask); - av_free(c->screendta); - return 0; -} - -AVCodec vmnc_decoder = { - "vmnc", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VMNC, - sizeof(VmncContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/vorbis.c b/tizen/distrib/ffmpeg/libavcodec/vorbis.c deleted file mode 100644 index 47388d8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vorbis.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file - * Common code for Vorbis I encoder and decoder - * @author Denes Balatoni ( dbalatoni programozo hu ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#undef V_DEBUG -//#define V_DEBUG - -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "get_bits.h" - -#include "vorbis.h" - - -/* Helper functions */ - -// x^(1/n) -unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) -{ - unsigned int ret = 0, i, j; - - do { - ++ret; - for (i = 0, j = ret; i < n - 1; i++) - j *= ret; - } while (j <= x); - - return ret - 1; -} - -// Generate vlc codes from vorbis huffman code lengths - -// the two bits[p] > 32 checks should be redundant, all calling code should -// already ensure that, but since it allows overwriting the stack it seems -// reasonable to check redundantly. -int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, uint_fast32_t num) -{ - uint_fast32_t exit_at_level[33] = { - 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - uint_fast8_t i, j; - uint_fast32_t code, p; - -#ifdef V_DEBUG - GetBitContext gb; -#endif - - for (p = 0; (bits[p] == 0) && (p < num); ++p) - ; - if (p == num) { -// av_log(vc->avccontext, AV_LOG_INFO, "An empty codebook. Heh?! \n"); - return 0; - } - - codes[p] = 0; - if (bits[p] > 32) - return 1; - for (i = 0; i < bits[p]; ++i) - exit_at_level[i+1] = 1 << i; - -#ifdef V_DEBUG - av_log(NULL, AV_LOG_INFO, " %d. of %d code len %d code %d - ", p, num, bits[p], codes[p]); - init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]); - for (i = 0; i < bits[p]; ++i) - av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0"); - av_log(NULL, AV_LOG_INFO, "\n"); -#endif - - ++p; - - for (; p < num; ++p) { - if (bits[p] > 32) - return 1; - if (bits[p] == 0) - continue; - // find corresponding exit(node which the tree can grow further from) - for (i = bits[p]; i > 0; --i) - if (exit_at_level[i]) - break; - if (!i) // overspecified tree - return 1; - code = exit_at_level[i]; - exit_at_level[i] = 0; - // construct code (append 0s to end) and introduce new exits - for (j = i + 1 ;j <= bits[p]; ++j) - exit_at_level[j] = code + (1 << (j - 1)); - codes[p] = code; - -#ifdef V_DEBUG - av_log(NULL, AV_LOG_INFO, " %d. code len %d code %d - ", p, bits[p], codes[p]); - init_get_bits(&gb, (uint_fast8_t *)&codes[p], bits[p]); - for (i = 0; i < bits[p]; ++i) - av_log(NULL, AV_LOG_INFO, "%s", get_bits1(&gb) ? "1" : "0"); - av_log(NULL, AV_LOG_INFO, "\n"); -#endif - - } - - //no exits should be left (underspecified tree - ie. unused valid vlcs - not allowed by SPEC) - for (p = 1; p < 33; p++) - if (exit_at_level[p]) - return 1; - - return 0; -} - -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) -{ - int i; - list[0].sort = 0; - list[1].sort = 1; - for (i = 2; i < values; i++) { - int j; - list[i].low = 0; - list[i].high = 1; - list[i].sort = i; - for (j = 2; j < i; j++) { - int tmp = list[j].x; - if (tmp < list[i].x) { - if (tmp > list[list[i].low].x) - list[i].low = j; - } else { - if (tmp < list[list[i].high].x) - list[i].high = j; - } - } - } - for (i = 0; i < values - 1; i++) { - int j; - for (j = i + 1; j < values; j++) { - if (list[list[i].sort].x > list[list[j].sort].x) { - int tmp = list[i].sort; - list[i].sort = list[j].sort; - list[j].sort = tmp; - } - } - } -} - -static inline void render_line_unrolled(intptr_t x, intptr_t y, int x1, - intptr_t sy, int ady, int adx, - float *buf) -{ - int err = -adx; - x -= x1 - 1; - buf += x1 - 1; - while (++x < 0) { - err += ady; - if (err >= 0) { - err += ady - adx; - y += sy; - buf[x++] = ff_vorbis_floor1_inverse_db_table[y]; - } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; - } - if (x <= 0) { - if (err + ady >= 0) - y += sy; - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; - } -} - -static void render_line(int x0, int y0, int x1, int y1, float *buf) -{ - int dy = y1 - y0; - int adx = x1 - x0; - int ady = FFABS(dy); - int sy = dy < 0 ? -1 : 1; - buf[x0] = ff_vorbis_floor1_inverse_db_table[y0]; - if (ady*2 <= adx) { // optimized common case - render_line_unrolled(x0, y0, x1, sy, ady, adx, buf); - } else { - int base = dy / adx; - int x = x0; - int y = y0; - int err = -adx; - ady -= FFABS(base) * adx; - while (++x < x1) { - y += base; - err += ady; - if (err >= 0) { - err -= adx; - y += sy; - } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; - } - } -} - -void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, - uint_fast16_t *y_list, int *flag, - int multiplier, float *out, int samples) -{ - int lx, ly, i; - lx = 0; - ly = y_list[0] * multiplier; - for (i = 1; i < values; i++) { - int pos = list[i].sort; - if (flag[pos]) { - int x1 = list[pos].x; - int y1 = y_list[pos] * multiplier; - if (lx < samples) - render_line(lx, ly, FFMIN(x1,samples), y1, out); - lx = x1; - ly = y1; - } - if (lx >= samples) - break; - } - if (lx < samples) - render_line(lx, ly, samples, ly, out); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/vorbis.h b/tizen/distrib/ffmpeg/libavcodec/vorbis.h deleted file mode 100644 index ce9bead..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vorbis.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * copyright (c) 2006 Oded Shimon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VORBIS_H -#define AVCODEC_VORBIS_H - -#include "avcodec.h" - -extern const float ff_vorbis_floor1_inverse_db_table[256]; -extern const float * const ff_vorbis_vwin[8]; -extern const uint8_t ff_vorbis_channel_layout_offsets[8][8]; -extern const int64_t ff_vorbis_channel_layouts[9]; - -typedef struct { - uint_fast16_t x; - uint_fast16_t sort; - uint_fast16_t low; - uint_fast16_t high; -} vorbis_floor1_entry; - -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values); -unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n) -int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, uint_fast32_t num); -void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, - uint_fast16_t * y_list, int * flag, - int multiplier, float * out, int samples); -void vorbis_inverse_coupling(float *mag, float *ang, int blocksize); - -#define ilog(i) av_log2(2*(i)) - -#endif /* AVCODEC_VORBIS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vorbis_data.c b/tizen/distrib/ffmpeg/libavcodec/vorbis_data.c deleted file mode 100644 index 9bc7979..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vorbis_data.c +++ /dev/null @@ -1,2181 +0,0 @@ -/* - * copyright (c) 2005 Denes Balatoni ( dbalatoni programozo hu ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dsputil.h" -#include "vorbis.h" - -const uint8_t ff_vorbis_channel_layout_offsets[8][8] = { - { 0, }, - { 0, 1, }, - { 0, 2, 1, }, - { 0, 1, 2, 3, }, - { 0, 2, 1, 3, 4, }, - { 0, 2, 1, 5, 3, 4, }, - { 0, 2, 1, 6, 5, 3, 4, }, - { 0, 2, 1, 7, 5, 6, 3, 4}, -}; - -const int64_t ff_vorbis_channel_layouts[9] = { - CH_LAYOUT_MONO, - CH_LAYOUT_STEREO, - CH_LAYOUT_SURROUND, - CH_LAYOUT_QUAD, - CH_LAYOUT_5POINT0_BACK, - CH_LAYOUT_5POINT1_BACK, - CH_LAYOUT_5POINT1|CH_BACK_CENTER, - CH_LAYOUT_7POINT1, - 0 -}; - -DECLARE_ALIGNED(16, static const float, vwin64)[32] = { - 0.0009460463F, 0.0085006468F, 0.0235352254F, 0.0458950567F, - 0.0753351908F, 0.1115073077F, 0.1539457973F, 0.2020557475F, - 0.2551056759F, 0.3122276645F, 0.3724270287F, 0.4346027792F, - 0.4975789974F, 0.5601459521F, 0.6211085051F, 0.6793382689F, - 0.7338252629F, 0.7837245849F, 0.8283939355F, 0.8674186656F, - 0.9006222429F, 0.9280614787F, 0.9500073081F, 0.9669131782F, - 0.9793740220F, 0.9880792941F, 0.9937636139F, 0.9971582668F, - 0.9989462667F, 0.9997230082F, 0.9999638688F, 0.9999995525F, -}; - -DECLARE_ALIGNED(16, static const float, vwin128)[64] = { - 0.0002365472F, 0.0021280687F, 0.0059065254F, 0.0115626550F, - 0.0190823442F, 0.0284463735F, 0.0396300935F, 0.0526030430F, - 0.0673285281F, 0.0837631763F, 0.1018564887F, 0.1215504095F, - 0.1427789367F, 0.1654677960F, 0.1895342001F, 0.2148867160F, - 0.2414252576F, 0.2690412240F, 0.2976177952F, 0.3270303960F, - 0.3571473350F, 0.3878306189F, 0.4189369387F, 0.4503188188F, - 0.4818259135F, 0.5133064334F, 0.5446086751F, 0.5755826278F, - 0.6060816248F, 0.6359640047F, 0.6650947483F, 0.6933470543F, - 0.7206038179F, 0.7467589810F, 0.7717187213F, 0.7954024542F, - 0.8177436264F, 0.8386902831F, 0.8582053981F, 0.8762669622F, - 0.8928678298F, 0.9080153310F, 0.9217306608F, 0.9340480615F, - 0.9450138200F, 0.9546851041F, 0.9631286621F, 0.9704194171F, - 0.9766389810F, 0.9818741197F, 0.9862151938F, 0.9897546035F, - 0.9925852598F, 0.9947991032F, 0.9964856900F, 0.9977308602F, - 0.9986155015F, 0.9992144193F, 0.9995953200F, 0.9998179155F, - 0.9999331503F, 0.9999825563F, 0.9999977357F, 0.9999999720F, -}; - -DECLARE_ALIGNED(16, static const float, vwin256)[128] = { - 0.0000591390F, 0.0005321979F, 0.0014780301F, 0.0028960636F, - 0.0047854363F, 0.0071449926F, 0.0099732775F, 0.0132685298F, - 0.0170286741F, 0.0212513119F, 0.0259337111F, 0.0310727950F, - 0.0366651302F, 0.0427069140F, 0.0491939614F, 0.0561216907F, - 0.0634851102F, 0.0712788035F, 0.0794969160F, 0.0881331402F, - 0.0971807028F, 0.1066323515F, 0.1164803426F, 0.1267164297F, - 0.1373318534F, 0.1483173323F, 0.1596630553F, 0.1713586755F, - 0.1833933062F, 0.1957555184F, 0.2084333404F, 0.2214142599F, - 0.2346852280F, 0.2482326664F, 0.2620424757F, 0.2761000481F, - 0.2903902813F, 0.3048975959F, 0.3196059553F, 0.3344988887F, - 0.3495595160F, 0.3647705766F, 0.3801144597F, 0.3955732382F, - 0.4111287047F, 0.4267624093F, 0.4424557009F, 0.4581897696F, - 0.4739456913F, 0.4897044744F, 0.5054471075F, 0.5211546088F, - 0.5368080763F, 0.5523887395F, 0.5678780103F, 0.5832575361F, - 0.5985092508F, 0.6136154277F, 0.6285587300F, 0.6433222619F, - 0.6578896175F, 0.6722449294F, 0.6863729144F, 0.7002589187F, - 0.7138889597F, 0.7272497662F, 0.7403288154F, 0.7531143679F, - 0.7655954985F, 0.7777621249F, 0.7896050322F, 0.8011158947F, - 0.8122872932F, 0.8231127294F, 0.8335866365F, 0.8437043850F, - 0.8534622861F, 0.8628575905F, 0.8718884835F, 0.8805540765F, - 0.8888543947F, 0.8967903616F, 0.9043637797F, 0.9115773078F, - 0.9184344360F, 0.9249394562F, 0.9310974312F, 0.9369141608F, - 0.9423961446F, 0.9475505439F, 0.9523851406F, 0.9569082947F, - 0.9611289005F, 0.9650563408F, 0.9687004405F, 0.9720714191F, - 0.9751798427F, 0.9780365753F, 0.9806527301F, 0.9830396204F, - 0.9852087111F, 0.9871715701F, 0.9889398207F, 0.9905250941F, - 0.9919389832F, 0.9931929973F, 0.9942985174F, 0.9952667537F, - 0.9961087037F, 0.9968351119F, 0.9974564312F, 0.9979827858F, - 0.9984239359F, 0.9987892441F, 0.9990876435F, 0.9993276081F, - 0.9995171241F, 0.9996636648F, 0.9997741654F, 0.9998550016F, - 0.9999119692F, 0.9999502656F, 0.9999744742F, 0.9999885497F, - 0.9999958064F, 0.9999989077F, 0.9999998584F, 0.9999999983F, -}; - -DECLARE_ALIGNED(16, static const float, vwin512)[256] = { - 0.0000147849F, 0.0001330607F, 0.0003695946F, 0.0007243509F, - 0.0011972759F, 0.0017882983F, 0.0024973285F, 0.0033242588F, - 0.0042689632F, 0.0053312973F, 0.0065110982F, 0.0078081841F, - 0.0092223540F, 0.0107533880F, 0.0124010466F, 0.0141650703F, - 0.0160451800F, 0.0180410758F, 0.0201524373F, 0.0223789233F, - 0.0247201710F, 0.0271757958F, 0.0297453914F, 0.0324285286F, - 0.0352247556F, 0.0381335972F, 0.0411545545F, 0.0442871045F, - 0.0475306997F, 0.0508847676F, 0.0543487103F, 0.0579219038F, - 0.0616036982F, 0.0653934164F, 0.0692903546F, 0.0732937809F, - 0.0774029356F, 0.0816170305F, 0.0859352485F, 0.0903567428F, - 0.0948806375F, 0.0995060259F, 0.1042319712F, 0.1090575056F, - 0.1139816300F, 0.1190033137F, 0.1241214941F, 0.1293350764F, - 0.1346429333F, 0.1400439046F, 0.1455367974F, 0.1511203852F, - 0.1567934083F, 0.1625545735F, 0.1684025537F, 0.1743359881F, - 0.1803534820F, 0.1864536069F, 0.1926349000F, 0.1988958650F, - 0.2052349715F, 0.2116506555F, 0.2181413191F, 0.2247053313F, - 0.2313410275F, 0.2380467105F, 0.2448206500F, 0.2516610835F, - 0.2585662164F, 0.2655342226F, 0.2725632448F, 0.2796513950F, - 0.2867967551F, 0.2939973773F, 0.3012512852F, 0.3085564739F, - 0.3159109111F, 0.3233125375F, 0.3307592680F, 0.3382489922F, - 0.3457795756F, 0.3533488602F, 0.3609546657F, 0.3685947904F, - 0.3762670121F, 0.3839690896F, 0.3916987634F, 0.3994537572F, - 0.4072317788F, 0.4150305215F, 0.4228476653F, 0.4306808783F, - 0.4385278181F, 0.4463861329F, 0.4542534630F, 0.4621274424F, - 0.4700057001F, 0.4778858615F, 0.4857655502F, 0.4936423891F, - 0.5015140023F, 0.5093780165F, 0.5172320626F, 0.5250737772F, - 0.5329008043F, 0.5407107971F, 0.5485014192F, 0.5562703465F, - 0.5640152688F, 0.5717338914F, 0.5794239366F, 0.5870831457F, - 0.5947092801F, 0.6023001235F, 0.6098534829F, 0.6173671907F, - 0.6248391059F, 0.6322671161F, 0.6396491384F, 0.6469831217F, - 0.6542670475F, 0.6614989319F, 0.6686768267F, 0.6757988210F, - 0.6828630426F, 0.6898676592F, 0.6968108799F, 0.7036909564F, - 0.7105061843F, 0.7172549043F, 0.7239355032F, 0.7305464154F, - 0.7370861235F, 0.7435531598F, 0.7499461068F, 0.7562635986F, - 0.7625043214F, 0.7686670148F, 0.7747504721F, 0.7807535410F, - 0.7866751247F, 0.7925141825F, 0.7982697296F, 0.8039408387F, - 0.8095266395F, 0.8150263196F, 0.8204391248F, 0.8257643590F, - 0.8310013848F, 0.8361496236F, 0.8412085555F, 0.8461777194F, - 0.8510567129F, 0.8558451924F, 0.8605428730F, 0.8651495278F, - 0.8696649882F, 0.8740891432F, 0.8784219392F, 0.8826633797F, - 0.8868135244F, 0.8908724888F, 0.8948404441F, 0.8987176157F, - 0.9025042831F, 0.9062007791F, 0.9098074886F, 0.9133248482F, - 0.9167533451F, 0.9200935163F, 0.9233459472F, 0.9265112712F, - 0.9295901680F, 0.9325833632F, 0.9354916263F, 0.9383157705F, - 0.9410566504F, 0.9437151618F, 0.9462922398F, 0.9487888576F, - 0.9512060252F, 0.9535447882F, 0.9558062262F, 0.9579914516F, - 0.9601016078F, 0.9621378683F, 0.9641014348F, 0.9659935361F, - 0.9678154261F, 0.9695683830F, 0.9712537071F, 0.9728727198F, - 0.9744267618F, 0.9759171916F, 0.9773453842F, 0.9787127293F, - 0.9800206298F, 0.9812705006F, 0.9824637665F, 0.9836018613F, - 0.9846862258F, 0.9857183066F, 0.9866995544F, 0.9876314227F, - 0.9885153662F, 0.9893528393F, 0.9901452948F, 0.9908941823F, - 0.9916009470F, 0.9922670279F, 0.9928938570F, 0.9934828574F, - 0.9940354423F, 0.9945530133F, 0.9950369595F, 0.9954886562F, - 0.9959094633F, 0.9963007242F, 0.9966637649F, 0.9969998925F, - 0.9973103939F, 0.9975965351F, 0.9978595598F, 0.9981006885F, - 0.9983211172F, 0.9985220166F, 0.9987045311F, 0.9988697776F, - 0.9990188449F, 0.9991527924F, 0.9992726499F, 0.9993794157F, - 0.9994740570F, 0.9995575079F, 0.9996306699F, 0.9996944099F, - 0.9997495605F, 0.9997969190F, 0.9998372465F, 0.9998712678F, - 0.9998996704F, 0.9999231041F, 0.9999421807F, 0.9999574732F, - 0.9999695157F, 0.9999788026F, 0.9999857885F, 0.9999908879F, - 0.9999944746F, 0.9999968817F, 0.9999984010F, 0.9999992833F, - 0.9999997377F, 0.9999999317F, 0.9999999911F, 0.9999999999F, -}; - -DECLARE_ALIGNED(16, static const float, vwin1024)[512] = { - 0.0000036962F, 0.0000332659F, 0.0000924041F, 0.0001811086F, - 0.0002993761F, 0.0004472021F, 0.0006245811F, 0.0008315063F, - 0.0010679699F, 0.0013339631F, 0.0016294757F, 0.0019544965F, - 0.0023090133F, 0.0026930125F, 0.0031064797F, 0.0035493989F, - 0.0040217533F, 0.0045235250F, 0.0050546946F, 0.0056152418F, - 0.0062051451F, 0.0068243817F, 0.0074729278F, 0.0081507582F, - 0.0088578466F, 0.0095941655F, 0.0103596863F, 0.0111543789F, - 0.0119782122F, 0.0128311538F, 0.0137131701F, 0.0146242260F, - 0.0155642855F, 0.0165333111F, 0.0175312640F, 0.0185581042F, - 0.0196137903F, 0.0206982797F, 0.0218115284F, 0.0229534910F, - 0.0241241208F, 0.0253233698F, 0.0265511886F, 0.0278075263F, - 0.0290923308F, 0.0304055484F, 0.0317471241F, 0.0331170013F, - 0.0345151222F, 0.0359414274F, 0.0373958560F, 0.0388783456F, - 0.0403888325F, 0.0419272511F, 0.0434935347F, 0.0450876148F, - 0.0467094213F, 0.0483588828F, 0.0500359261F, 0.0517404765F, - 0.0534724575F, 0.0552317913F, 0.0570183983F, 0.0588321971F, - 0.0606731048F, 0.0625410369F, 0.0644359070F, 0.0663576272F, - 0.0683061077F, 0.0702812571F, 0.0722829821F, 0.0743111878F, - 0.0763657775F, 0.0784466526F, 0.0805537129F, 0.0826868561F, - 0.0848459782F, 0.0870309736F, 0.0892417345F, 0.0914781514F, - 0.0937401128F, 0.0960275056F, 0.0983402145F, 0.1006781223F, - 0.1030411101F, 0.1054290568F, 0.1078418397F, 0.1102793336F, - 0.1127414119F, 0.1152279457F, 0.1177388042F, 0.1202738544F, - 0.1228329618F, 0.1254159892F, 0.1280227980F, 0.1306532471F, - 0.1333071937F, 0.1359844927F, 0.1386849970F, 0.1414085575F, - 0.1441550230F, 0.1469242403F, 0.1497160539F, 0.1525303063F, - 0.1553668381F, 0.1582254875F, 0.1611060909F, 0.1640084822F, - 0.1669324936F, 0.1698779549F, 0.1728446939F, 0.1758325362F, - 0.1788413055F, 0.1818708232F, 0.1849209084F, 0.1879913785F, - 0.1910820485F, 0.1941927312F, 0.1973232376F, 0.2004733764F, - 0.2036429541F, 0.2068317752F, 0.2100396421F, 0.2132663552F, - 0.2165117125F, 0.2197755102F, 0.2230575422F, 0.2263576007F, - 0.2296754753F, 0.2330109540F, 0.2363638225F, 0.2397338646F, - 0.2431208619F, 0.2465245941F, 0.2499448389F, 0.2533813719F, - 0.2568339669F, 0.2603023956F, 0.2637864277F, 0.2672858312F, - 0.2708003718F, 0.2743298135F, 0.2778739186F, 0.2814324472F, - 0.2850051576F, 0.2885918065F, 0.2921921485F, 0.2958059366F, - 0.2994329219F, 0.3030728538F, 0.3067254799F, 0.3103905462F, - 0.3140677969F, 0.3177569747F, 0.3214578205F, 0.3251700736F, - 0.3288934718F, 0.3326277513F, 0.3363726468F, 0.3401278914F, - 0.3438932168F, 0.3476683533F, 0.3514530297F, 0.3552469734F, - 0.3590499106F, 0.3628615659F, 0.3666816630F, 0.3705099239F, - 0.3743460698F, 0.3781898204F, 0.3820408945F, 0.3858990095F, - 0.3897638820F, 0.3936352274F, 0.3975127601F, 0.4013961936F, - 0.4052852405F, 0.4091796123F, 0.4130790198F, 0.4169831732F, - 0.4208917815F, 0.4248045534F, 0.4287211965F, 0.4326414181F, - 0.4365649248F, 0.4404914225F, 0.4444206167F, 0.4483522125F, - 0.4522859146F, 0.4562214270F, 0.4601584538F, 0.4640966984F, - 0.4680358644F, 0.4719756548F, 0.4759157726F, 0.4798559209F, - 0.4837958024F, 0.4877351199F, 0.4916735765F, 0.4956108751F, - 0.4995467188F, 0.5034808109F, 0.5074128550F, 0.5113425550F, - 0.5152696149F, 0.5191937395F, 0.5231146336F, 0.5270320028F, - 0.5309455530F, 0.5348549910F, 0.5387600239F, 0.5426603597F, - 0.5465557070F, 0.5504457754F, 0.5543302752F, 0.5582089175F, - 0.5620814145F, 0.5659474793F, 0.5698068262F, 0.5736591704F, - 0.5775042283F, 0.5813417176F, 0.5851713571F, 0.5889928670F, - 0.5928059689F, 0.5966103856F, 0.6004058415F, 0.6041920626F, - 0.6079687761F, 0.6117357113F, 0.6154925986F, 0.6192391705F, - 0.6229751612F, 0.6267003064F, 0.6304143441F, 0.6341170137F, - 0.6378080569F, 0.6414872173F, 0.6451542405F, 0.6488088741F, - 0.6524508681F, 0.6560799742F, 0.6596959469F, 0.6632985424F, - 0.6668875197F, 0.6704626398F, 0.6740236662F, 0.6775703649F, - 0.6811025043F, 0.6846198554F, 0.6881221916F, 0.6916092892F, - 0.6950809269F, 0.6985368861F, 0.7019769510F, 0.7054009085F, - 0.7088085484F, 0.7121996632F, 0.7155740484F, 0.7189315023F, - 0.7222718263F, 0.7255948245F, 0.7289003043F, 0.7321880760F, - 0.7354579530F, 0.7387097518F, 0.7419432921F, 0.7451583966F, - 0.7483548915F, 0.7515326059F, 0.7546913723F, 0.7578310265F, - 0.7609514077F, 0.7640523581F, 0.7671337237F, 0.7701953535F, - 0.7732371001F, 0.7762588195F, 0.7792603711F, 0.7822416178F, - 0.7852024259F, 0.7881426654F, 0.7910622097F, 0.7939609356F, - 0.7968387237F, 0.7996954579F, 0.8025310261F, 0.8053453193F, - 0.8081382324F, 0.8109096638F, 0.8136595156F, 0.8163876936F, - 0.8190941071F, 0.8217786690F, 0.8244412960F, 0.8270819086F, - 0.8297004305F, 0.8322967896F, 0.8348709171F, 0.8374227481F, - 0.8399522213F, 0.8424592789F, 0.8449438672F, 0.8474059356F, - 0.8498454378F, 0.8522623306F, 0.8546565748F, 0.8570281348F, - 0.8593769787F, 0.8617030779F, 0.8640064080F, 0.8662869477F, - 0.8685446796F, 0.8707795899F, 0.8729916682F, 0.8751809079F, - 0.8773473059F, 0.8794908626F, 0.8816115819F, 0.8837094713F, - 0.8857845418F, 0.8878368079F, 0.8898662874F, 0.8918730019F, - 0.8938569760F, 0.8958182380F, 0.8977568194F, 0.8996727552F, - 0.9015660837F, 0.9034368465F, 0.9052850885F, 0.9071108577F, - 0.9089142057F, 0.9106951869F, 0.9124538591F, 0.9141902832F, - 0.9159045233F, 0.9175966464F, 0.9192667228F, 0.9209148257F, - 0.9225410313F, 0.9241454187F, 0.9257280701F, 0.9272890704F, - 0.9288285075F, 0.9303464720F, 0.9318430576F, 0.9333183603F, - 0.9347724792F, 0.9362055158F, 0.9376175745F, 0.9390087622F, - 0.9403791881F, 0.9417289644F, 0.9430582055F, 0.9443670283F, - 0.9456555521F, 0.9469238986F, 0.9481721917F, 0.9494005577F, - 0.9506091252F, 0.9517980248F, 0.9529673894F, 0.9541173540F, - 0.9552480557F, 0.9563596334F, 0.9574522282F, 0.9585259830F, - 0.9595810428F, 0.9606175542F, 0.9616356656F, 0.9626355274F, - 0.9636172915F, 0.9645811114F, 0.9655271425F, 0.9664555414F, - 0.9673664664F, 0.9682600774F, 0.9691365355F, 0.9699960034F, - 0.9708386448F, 0.9716646250F, 0.9724741103F, 0.9732672685F, - 0.9740442683F, 0.9748052795F, 0.9755504729F, 0.9762800205F, - 0.9769940950F, 0.9776928703F, 0.9783765210F, 0.9790452223F, - 0.9796991504F, 0.9803384823F, 0.9809633954F, 0.9815740679F, - 0.9821706784F, 0.9827534063F, 0.9833224312F, 0.9838779332F, - 0.9844200928F, 0.9849490910F, 0.9854651087F, 0.9859683274F, - 0.9864589286F, 0.9869370940F, 0.9874030054F, 0.9878568447F, - 0.9882987937F, 0.9887290343F, 0.9891477481F, 0.9895551169F, - 0.9899513220F, 0.9903365446F, 0.9907109658F, 0.9910747662F, - 0.9914281260F, 0.9917712252F, 0.9921042433F, 0.9924273593F, - 0.9927407516F, 0.9930445982F, 0.9933390763F, 0.9936243626F, - 0.9939006331F, 0.9941680631F, 0.9944268269F, 0.9946770982F, - 0.9949190498F, 0.9951528537F, 0.9953786808F, 0.9955967011F, - 0.9958070836F, 0.9960099963F, 0.9962056061F, 0.9963940787F, - 0.9965755786F, 0.9967502693F, 0.9969183129F, 0.9970798704F, - 0.9972351013F, 0.9973841640F, 0.9975272151F, 0.9976644103F, - 0.9977959036F, 0.9979218476F, 0.9980423932F, 0.9981576901F, - 0.9982678862F, 0.9983731278F, 0.9984735596F, 0.9985693247F, - 0.9986605645F, 0.9987474186F, 0.9988300248F, 0.9989085193F, - 0.9989830364F, 0.9990537085F, 0.9991206662F, 0.9991840382F, - 0.9992439513F, 0.9993005303F, 0.9993538982F, 0.9994041757F, - 0.9994514817F, 0.9994959330F, 0.9995376444F, 0.9995767286F, - 0.9996132960F, 0.9996474550F, 0.9996793121F, 0.9997089710F, - 0.9997365339F, 0.9997621003F, 0.9997857677F, 0.9998076311F, - 0.9998277836F, 0.9998463156F, 0.9998633155F, 0.9998788692F, - 0.9998930603F, 0.9999059701F, 0.9999176774F, 0.9999282586F, - 0.9999377880F, 0.9999463370F, 0.9999539749F, 0.9999607685F, - 0.9999667820F, 0.9999720773F, 0.9999767136F, 0.9999807479F, - 0.9999842344F, 0.9999872249F, 0.9999897688F, 0.9999919127F, - 0.9999937009F, 0.9999951749F, 0.9999963738F, 0.9999973342F, - 0.9999980900F, 0.9999986724F, 0.9999991103F, 0.9999994297F, - 0.9999996543F, 0.9999998049F, 0.9999999000F, 0.9999999552F, - 0.9999999836F, 0.9999999957F, 0.9999999994F, 1.0000000000F, -}; - -DECLARE_ALIGNED(16, static const float, vwin2048)[1024] = { - 0.0000009241F, 0.0000083165F, 0.0000231014F, 0.0000452785F, - 0.0000748476F, 0.0001118085F, 0.0001561608F, 0.0002079041F, - 0.0002670379F, 0.0003335617F, 0.0004074748F, 0.0004887765F, - 0.0005774661F, 0.0006735427F, 0.0007770054F, 0.0008878533F, - 0.0010060853F, 0.0011317002F, 0.0012646969F, 0.0014050742F, - 0.0015528307F, 0.0017079650F, 0.0018704756F, 0.0020403610F, - 0.0022176196F, 0.0024022497F, 0.0025942495F, 0.0027936173F, - 0.0030003511F, 0.0032144490F, 0.0034359088F, 0.0036647286F, - 0.0039009061F, 0.0041444391F, 0.0043953253F, 0.0046535621F, - 0.0049191472F, 0.0051920781F, 0.0054723520F, 0.0057599664F, - 0.0060549184F, 0.0063572052F, 0.0066668239F, 0.0069837715F, - 0.0073080449F, 0.0076396410F, 0.0079785566F, 0.0083247884F, - 0.0086783330F, 0.0090391871F, 0.0094073470F, 0.0097828092F, - 0.0101655700F, 0.0105556258F, 0.0109529726F, 0.0113576065F, - 0.0117695237F, 0.0121887200F, 0.0126151913F, 0.0130489335F, - 0.0134899422F, 0.0139382130F, 0.0143937415F, 0.0148565233F, - 0.0153265536F, 0.0158038279F, 0.0162883413F, 0.0167800889F, - 0.0172790660F, 0.0177852675F, 0.0182986882F, 0.0188193231F, - 0.0193471668F, 0.0198822141F, 0.0204244594F, 0.0209738974F, - 0.0215305225F, 0.0220943289F, 0.0226653109F, 0.0232434627F, - 0.0238287784F, 0.0244212519F, 0.0250208772F, 0.0256276481F, - 0.0262415582F, 0.0268626014F, 0.0274907711F, 0.0281260608F, - 0.0287684638F, 0.0294179736F, 0.0300745833F, 0.0307382859F, - 0.0314090747F, 0.0320869424F, 0.0327718819F, 0.0334638860F, - 0.0341629474F, 0.0348690586F, 0.0355822122F, 0.0363024004F, - 0.0370296157F, 0.0377638502F, 0.0385050960F, 0.0392533451F, - 0.0400085896F, 0.0407708211F, 0.0415400315F, 0.0423162123F, - 0.0430993552F, 0.0438894515F, 0.0446864926F, 0.0454904698F, - 0.0463013742F, 0.0471191969F, 0.0479439288F, 0.0487755607F, - 0.0496140836F, 0.0504594879F, 0.0513117642F, 0.0521709031F, - 0.0530368949F, 0.0539097297F, 0.0547893979F, 0.0556758894F, - 0.0565691941F, 0.0574693019F, 0.0583762026F, 0.0592898858F, - 0.0602103410F, 0.0611375576F, 0.0620715250F, 0.0630122324F, - 0.0639596688F, 0.0649138234F, 0.0658746848F, 0.0668422421F, - 0.0678164838F, 0.0687973985F, 0.0697849746F, 0.0707792005F, - 0.0717800645F, 0.0727875547F, 0.0738016591F, 0.0748223656F, - 0.0758496620F, 0.0768835359F, 0.0779239751F, 0.0789709668F, - 0.0800244985F, 0.0810845574F, 0.0821511306F, 0.0832242052F, - 0.0843037679F, 0.0853898056F, 0.0864823050F, 0.0875812525F, - 0.0886866347F, 0.0897984378F, 0.0909166480F, 0.0920412513F, - 0.0931722338F, 0.0943095813F, 0.0954532795F, 0.0966033140F, - 0.0977596702F, 0.0989223336F, 0.1000912894F, 0.1012665227F, - 0.1024480185F, 0.1036357616F, 0.1048297369F, 0.1060299290F, - 0.1072363224F, 0.1084489014F, 0.1096676504F, 0.1108925534F, - 0.1121235946F, 0.1133607577F, 0.1146040267F, 0.1158533850F, - 0.1171088163F, 0.1183703040F, 0.1196378312F, 0.1209113812F, - 0.1221909370F, 0.1234764815F, 0.1247679974F, 0.1260654674F, - 0.1273688740F, 0.1286781995F, 0.1299934263F, 0.1313145365F, - 0.1326415121F, 0.1339743349F, 0.1353129866F, 0.1366574490F, - 0.1380077035F, 0.1393637315F, 0.1407255141F, 0.1420930325F, - 0.1434662677F, 0.1448452004F, 0.1462298115F, 0.1476200814F, - 0.1490159906F, 0.1504175195F, 0.1518246482F, 0.1532373569F, - 0.1546556253F, 0.1560794333F, 0.1575087606F, 0.1589435866F, - 0.1603838909F, 0.1618296526F, 0.1632808509F, 0.1647374648F, - 0.1661994731F, 0.1676668546F, 0.1691395880F, 0.1706176516F, - 0.1721010238F, 0.1735896829F, 0.1750836068F, 0.1765827736F, - 0.1780871610F, 0.1795967468F, 0.1811115084F, 0.1826314234F, - 0.1841564689F, 0.1856866221F, 0.1872218600F, 0.1887621595F, - 0.1903074974F, 0.1918578503F, 0.1934131947F, 0.1949735068F, - 0.1965387630F, 0.1981089393F, 0.1996840117F, 0.2012639560F, - 0.2028487479F, 0.2044383630F, 0.2060327766F, 0.2076319642F, - 0.2092359007F, 0.2108445614F, 0.2124579211F, 0.2140759545F, - 0.2156986364F, 0.2173259411F, 0.2189578432F, 0.2205943168F, - 0.2222353361F, 0.2238808751F, 0.2255309076F, 0.2271854073F, - 0.2288443480F, 0.2305077030F, 0.2321754457F, 0.2338475493F, - 0.2355239869F, 0.2372047315F, 0.2388897560F, 0.2405790329F, - 0.2422725350F, 0.2439702347F, 0.2456721043F, 0.2473781159F, - 0.2490882418F, 0.2508024539F, 0.2525207240F, 0.2542430237F, - 0.2559693248F, 0.2576995986F, 0.2594338166F, 0.2611719498F, - 0.2629139695F, 0.2646598466F, 0.2664095520F, 0.2681630564F, - 0.2699203304F, 0.2716813445F, 0.2734460691F, 0.2752144744F, - 0.2769865307F, 0.2787622079F, 0.2805414760F, 0.2823243047F, - 0.2841106637F, 0.2859005227F, 0.2876938509F, 0.2894906179F, - 0.2912907928F, 0.2930943447F, 0.2949012426F, 0.2967114554F, - 0.2985249520F, 0.3003417009F, 0.3021616708F, 0.3039848301F, - 0.3058111471F, 0.3076405901F, 0.3094731273F, 0.3113087266F, - 0.3131473560F, 0.3149889833F, 0.3168335762F, 0.3186811024F, - 0.3205315294F, 0.3223848245F, 0.3242409552F, 0.3260998886F, - 0.3279615918F, 0.3298260319F, 0.3316931758F, 0.3335629903F, - 0.3354354423F, 0.3373104982F, 0.3391881247F, 0.3410682882F, - 0.3429509551F, 0.3448360917F, 0.3467236642F, 0.3486136387F, - 0.3505059811F, 0.3524006575F, 0.3542976336F, 0.3561968753F, - 0.3580983482F, 0.3600020179F, 0.3619078499F, 0.3638158096F, - 0.3657258625F, 0.3676379737F, 0.3695521086F, 0.3714682321F, - 0.3733863094F, 0.3753063055F, 0.3772281852F, 0.3791519134F, - 0.3810774548F, 0.3830047742F, 0.3849338362F, 0.3868646053F, - 0.3887970459F, 0.3907311227F, 0.3926667998F, 0.3946040417F, - 0.3965428125F, 0.3984830765F, 0.4004247978F, 0.4023679403F, - 0.4043124683F, 0.4062583455F, 0.4082055359F, 0.4101540034F, - 0.4121037117F, 0.4140546246F, 0.4160067058F, 0.4179599190F, - 0.4199142277F, 0.4218695956F, 0.4238259861F, 0.4257833627F, - 0.4277416888F, 0.4297009279F, 0.4316610433F, 0.4336219983F, - 0.4355837562F, 0.4375462803F, 0.4395095337F, 0.4414734797F, - 0.4434380815F, 0.4454033021F, 0.4473691046F, 0.4493354521F, - 0.4513023078F, 0.4532696345F, 0.4552373954F, 0.4572055533F, - 0.4591740713F, 0.4611429123F, 0.4631120393F, 0.4650814151F, - 0.4670510028F, 0.4690207650F, 0.4709906649F, 0.4729606651F, - 0.4749307287F, 0.4769008185F, 0.4788708972F, 0.4808409279F, - 0.4828108732F, 0.4847806962F, 0.4867503597F, 0.4887198264F, - 0.4906890593F, 0.4926580213F, 0.4946266753F, 0.4965949840F, - 0.4985629105F, 0.5005304176F, 0.5024974683F, 0.5044640255F, - 0.5064300522F, 0.5083955114F, 0.5103603659F, 0.5123245790F, - 0.5142881136F, 0.5162509328F, 0.5182129997F, 0.5201742774F, - 0.5221347290F, 0.5240943178F, 0.5260530070F, 0.5280107598F, - 0.5299675395F, 0.5319233095F, 0.5338780330F, 0.5358316736F, - 0.5377841946F, 0.5397355596F, 0.5416857320F, 0.5436346755F, - 0.5455823538F, 0.5475287304F, 0.5494737691F, 0.5514174337F, - 0.5533596881F, 0.5553004962F, 0.5572398218F, 0.5591776291F, - 0.5611138821F, 0.5630485449F, 0.5649815818F, 0.5669129570F, - 0.5688426349F, 0.5707705799F, 0.5726967564F, 0.5746211290F, - 0.5765436624F, 0.5784643212F, 0.5803830702F, 0.5822998743F, - 0.5842146984F, 0.5861275076F, 0.5880382669F, 0.5899469416F, - 0.5918534968F, 0.5937578981F, 0.5956601107F, 0.5975601004F, - 0.5994578326F, 0.6013532732F, 0.6032463880F, 0.6051371429F, - 0.6070255039F, 0.6089114372F, 0.6107949090F, 0.6126758856F, - 0.6145543334F, 0.6164302191F, 0.6183035092F, 0.6201741706F, - 0.6220421700F, 0.6239074745F, 0.6257700513F, 0.6276298674F, - 0.6294868903F, 0.6313410873F, 0.6331924262F, 0.6350408745F, - 0.6368864001F, 0.6387289710F, 0.6405685552F, 0.6424051209F, - 0.6442386364F, 0.6460690702F, 0.6478963910F, 0.6497205673F, - 0.6515415682F, 0.6533593625F, 0.6551739194F, 0.6569852082F, - 0.6587931984F, 0.6605978593F, 0.6623991609F, 0.6641970728F, - 0.6659915652F, 0.6677826081F, 0.6695701718F, 0.6713542268F, - 0.6731347437F, 0.6749116932F, 0.6766850461F, 0.6784547736F, - 0.6802208469F, 0.6819832374F, 0.6837419164F, 0.6854968559F, - 0.6872480275F, 0.6889954034F, 0.6907389556F, 0.6924786566F, - 0.6942144788F, 0.6959463950F, 0.6976743780F, 0.6993984008F, - 0.7011184365F, 0.7028344587F, 0.7045464407F, 0.7062543564F, - 0.7079581796F, 0.7096578844F, 0.7113534450F, 0.7130448359F, - 0.7147320316F, 0.7164150070F, 0.7180937371F, 0.7197681970F, - 0.7214383620F, 0.7231042077F, 0.7247657098F, 0.7264228443F, - 0.7280755871F, 0.7297239147F, 0.7313678035F, 0.7330072301F, - 0.7346421715F, 0.7362726046F, 0.7378985069F, 0.7395198556F, - 0.7411366285F, 0.7427488034F, 0.7443563584F, 0.7459592717F, - 0.7475575218F, 0.7491510873F, 0.7507399471F, 0.7523240803F, - 0.7539034661F, 0.7554780839F, 0.7570479136F, 0.7586129349F, - 0.7601731279F, 0.7617284730F, 0.7632789506F, 0.7648245416F, - 0.7663652267F, 0.7679009872F, 0.7694318044F, 0.7709576599F, - 0.7724785354F, 0.7739944130F, 0.7755052749F, 0.7770111035F, - 0.7785118815F, 0.7800075916F, 0.7814982170F, 0.7829837410F, - 0.7844641472F, 0.7859394191F, 0.7874095408F, 0.7888744965F, - 0.7903342706F, 0.7917888476F, 0.7932382124F, 0.7946823501F, - 0.7961212460F, 0.7975548855F, 0.7989832544F, 0.8004063386F, - 0.8018241244F, 0.8032365981F, 0.8046437463F, 0.8060455560F, - 0.8074420141F, 0.8088331080F, 0.8102188253F, 0.8115991536F, - 0.8129740810F, 0.8143435957F, 0.8157076861F, 0.8170663409F, - 0.8184195489F, 0.8197672994F, 0.8211095817F, 0.8224463853F, - 0.8237777001F, 0.8251035161F, 0.8264238235F, 0.8277386129F, - 0.8290478750F, 0.8303516008F, 0.8316497814F, 0.8329424083F, - 0.8342294731F, 0.8355109677F, 0.8367868841F, 0.8380572148F, - 0.8393219523F, 0.8405810893F, 0.8418346190F, 0.8430825345F, - 0.8443248294F, 0.8455614974F, 0.8467925323F, 0.8480179285F, - 0.8492376802F, 0.8504517822F, 0.8516602292F, 0.8528630164F, - 0.8540601391F, 0.8552515928F, 0.8564373733F, 0.8576174766F, - 0.8587918990F, 0.8599606368F, 0.8611236868F, 0.8622810460F, - 0.8634327113F, 0.8645786802F, 0.8657189504F, 0.8668535195F, - 0.8679823857F, 0.8691055472F, 0.8702230025F, 0.8713347503F, - 0.8724407896F, 0.8735411194F, 0.8746357394F, 0.8757246489F, - 0.8768078479F, 0.8778853364F, 0.8789571146F, 0.8800231832F, - 0.8810835427F, 0.8821381942F, 0.8831871387F, 0.8842303777F, - 0.8852679127F, 0.8862997456F, 0.8873258784F, 0.8883463132F, - 0.8893610527F, 0.8903700994F, 0.8913734562F, 0.8923711263F, - 0.8933631129F, 0.8943494196F, 0.8953300500F, 0.8963050083F, - 0.8972742985F, 0.8982379249F, 0.8991958922F, 0.9001482052F, - 0.9010948688F, 0.9020358883F, 0.9029712690F, 0.9039010165F, - 0.9048251367F, 0.9057436357F, 0.9066565195F, 0.9075637946F, - 0.9084654678F, 0.9093615456F, 0.9102520353F, 0.9111369440F, - 0.9120162792F, 0.9128900484F, 0.9137582595F, 0.9146209204F, - 0.9154780394F, 0.9163296248F, 0.9171756853F, 0.9180162296F, - 0.9188512667F, 0.9196808057F, 0.9205048559F, 0.9213234270F, - 0.9221365285F, 0.9229441704F, 0.9237463629F, 0.9245431160F, - 0.9253344404F, 0.9261203465F, 0.9269008453F, 0.9276759477F, - 0.9284456648F, 0.9292100080F, 0.9299689889F, 0.9307226190F, - 0.9314709103F, 0.9322138747F, 0.9329515245F, 0.9336838721F, - 0.9344109300F, 0.9351327108F, 0.9358492275F, 0.9365604931F, - 0.9372665208F, 0.9379673239F, 0.9386629160F, 0.9393533107F, - 0.9400385220F, 0.9407185637F, 0.9413934501F, 0.9420631954F, - 0.9427278141F, 0.9433873208F, 0.9440417304F, 0.9446910576F, - 0.9453353176F, 0.9459745255F, 0.9466086968F, 0.9472378469F, - 0.9478619915F, 0.9484811463F, 0.9490953274F, 0.9497045506F, - 0.9503088323F, 0.9509081888F, 0.9515026365F, 0.9520921921F, - 0.9526768723F, 0.9532566940F, 0.9538316742F, 0.9544018300F, - 0.9549671786F, 0.9555277375F, 0.9560835241F, 0.9566345562F, - 0.9571808513F, 0.9577224275F, 0.9582593027F, 0.9587914949F, - 0.9593190225F, 0.9598419038F, 0.9603601571F, 0.9608738012F, - 0.9613828546F, 0.9618873361F, 0.9623872646F, 0.9628826591F, - 0.9633735388F, 0.9638599227F, 0.9643418303F, 0.9648192808F, - 0.9652922939F, 0.9657608890F, 0.9662250860F, 0.9666849046F, - 0.9671403646F, 0.9675914861F, 0.9680382891F, 0.9684807937F, - 0.9689190202F, 0.9693529890F, 0.9697827203F, 0.9702082347F, - 0.9706295529F, 0.9710466953F, 0.9714596828F, 0.9718685362F, - 0.9722732762F, 0.9726739240F, 0.9730705005F, 0.9734630267F, - 0.9738515239F, 0.9742360134F, 0.9746165163F, 0.9749930540F, - 0.9753656481F, 0.9757343198F, 0.9760990909F, 0.9764599829F, - 0.9768170175F, 0.9771702164F, 0.9775196013F, 0.9778651941F, - 0.9782070167F, 0.9785450909F, 0.9788794388F, 0.9792100824F, - 0.9795370437F, 0.9798603449F, 0.9801800080F, 0.9804960554F, - 0.9808085092F, 0.9811173916F, 0.9814227251F, 0.9817245318F, - 0.9820228343F, 0.9823176549F, 0.9826090160F, 0.9828969402F, - 0.9831814498F, 0.9834625674F, 0.9837403156F, 0.9840147169F, - 0.9842857939F, 0.9845535692F, 0.9848180654F, 0.9850793052F, - 0.9853373113F, 0.9855921062F, 0.9858437127F, 0.9860921535F, - 0.9863374512F, 0.9865796287F, 0.9868187085F, 0.9870547136F, - 0.9872876664F, 0.9875175899F, 0.9877445067F, 0.9879684396F, - 0.9881894112F, 0.9884074444F, 0.9886225619F, 0.9888347863F, - 0.9890441404F, 0.9892506468F, 0.9894543284F, 0.9896552077F, - 0.9898533074F, 0.9900486502F, 0.9902412587F, 0.9904311555F, - 0.9906183633F, 0.9908029045F, 0.9909848019F, 0.9911640779F, - 0.9913407550F, 0.9915148557F, 0.9916864025F, 0.9918554179F, - 0.9920219241F, 0.9921859437F, 0.9923474989F, 0.9925066120F, - 0.9926633054F, 0.9928176012F, 0.9929695218F, 0.9931190891F, - 0.9932663254F, 0.9934112527F, 0.9935538932F, 0.9936942686F, - 0.9938324012F, 0.9939683126F, 0.9941020248F, 0.9942335597F, - 0.9943629388F, 0.9944901841F, 0.9946153170F, 0.9947383593F, - 0.9948593325F, 0.9949782579F, 0.9950951572F, 0.9952100516F, - 0.9953229625F, 0.9954339111F, 0.9955429186F, 0.9956500062F, - 0.9957551948F, 0.9958585056F, 0.9959599593F, 0.9960595769F, - 0.9961573792F, 0.9962533869F, 0.9963476206F, 0.9964401009F, - 0.9965308483F, 0.9966198833F, 0.9967072261F, 0.9967928971F, - 0.9968769164F, 0.9969593041F, 0.9970400804F, 0.9971192651F, - 0.9971968781F, 0.9972729391F, 0.9973474680F, 0.9974204842F, - 0.9974920074F, 0.9975620569F, 0.9976306521F, 0.9976978122F, - 0.9977635565F, 0.9978279039F, 0.9978908736F, 0.9979524842F, - 0.9980127547F, 0.9980717037F, 0.9981293499F, 0.9981857116F, - 0.9982408073F, 0.9982946554F, 0.9983472739F, 0.9983986810F, - 0.9984488947F, 0.9984979328F, 0.9985458132F, 0.9985925534F, - 0.9986381711F, 0.9986826838F, 0.9987261086F, 0.9987684630F, - 0.9988097640F, 0.9988500286F, 0.9988892738F, 0.9989275163F, - 0.9989647727F, 0.9990010597F, 0.9990363938F, 0.9990707911F, - 0.9991042679F, 0.9991368404F, 0.9991685244F, 0.9991993358F, - 0.9992292905F, 0.9992584038F, 0.9992866914F, 0.9993141686F, - 0.9993408506F, 0.9993667526F, 0.9993918895F, 0.9994162761F, - 0.9994399273F, 0.9994628576F, 0.9994850815F, 0.9995066133F, - 0.9995274672F, 0.9995476574F, 0.9995671978F, 0.9995861021F, - 0.9996043841F, 0.9996220573F, 0.9996391352F, 0.9996556310F, - 0.9996715579F, 0.9996869288F, 0.9997017568F, 0.9997160543F, - 0.9997298342F, 0.9997431088F, 0.9997558905F, 0.9997681914F, - 0.9997800236F, 0.9997913990F, 0.9998023292F, 0.9998128261F, - 0.9998229009F, 0.9998325650F, 0.9998418296F, 0.9998507058F, - 0.9998592044F, 0.9998673362F, 0.9998751117F, 0.9998825415F, - 0.9998896358F, 0.9998964047F, 0.9999028584F, 0.9999090066F, - 0.9999148590F, 0.9999204253F, 0.9999257148F, 0.9999307368F, - 0.9999355003F, 0.9999400144F, 0.9999442878F, 0.9999483293F, - 0.9999521472F, 0.9999557499F, 0.9999591457F, 0.9999623426F, - 0.9999653483F, 0.9999681708F, 0.9999708175F, 0.9999732959F, - 0.9999756132F, 0.9999777765F, 0.9999797928F, 0.9999816688F, - 0.9999834113F, 0.9999850266F, 0.9999865211F, 0.9999879009F, - 0.9999891721F, 0.9999903405F, 0.9999914118F, 0.9999923914F, - 0.9999932849F, 0.9999940972F, 0.9999948336F, 0.9999954989F, - 0.9999960978F, 0.9999966349F, 0.9999971146F, 0.9999975411F, - 0.9999979185F, 0.9999982507F, 0.9999985414F, 0.9999987944F, - 0.9999990129F, 0.9999992003F, 0.9999993596F, 0.9999994939F, - 0.9999996059F, 0.9999996981F, 0.9999997732F, 0.9999998333F, - 0.9999998805F, 0.9999999170F, 0.9999999444F, 0.9999999643F, - 0.9999999784F, 0.9999999878F, 0.9999999937F, 0.9999999972F, - 0.9999999990F, 0.9999999997F, 1.0000000000F, 1.0000000000F, -}; - -DECLARE_ALIGNED(16, static const float, vwin4096)[2048] = { - 0.0000002310F, 0.0000020791F, 0.0000057754F, 0.0000113197F, - 0.0000187121F, 0.0000279526F, 0.0000390412F, 0.0000519777F, - 0.0000667623F, 0.0000833949F, 0.0001018753F, 0.0001222036F, - 0.0001443798F, 0.0001684037F, 0.0001942754F, 0.0002219947F, - 0.0002515616F, 0.0002829761F, 0.0003162380F, 0.0003513472F, - 0.0003883038F, 0.0004271076F, 0.0004677584F, 0.0005102563F, - 0.0005546011F, 0.0006007928F, 0.0006488311F, 0.0006987160F, - 0.0007504474F, 0.0008040251F, 0.0008594490F, 0.0009167191F, - 0.0009758351F, 0.0010367969F, 0.0010996044F, 0.0011642574F, - 0.0012307558F, 0.0012990994F, 0.0013692880F, 0.0014413216F, - 0.0015151998F, 0.0015909226F, 0.0016684898F, 0.0017479011F, - 0.0018291565F, 0.0019122556F, 0.0019971983F, 0.0020839845F, - 0.0021726138F, 0.0022630861F, 0.0023554012F, 0.0024495588F, - 0.0025455588F, 0.0026434008F, 0.0027430847F, 0.0028446103F, - 0.0029479772F, 0.0030531853F, 0.0031602342F, 0.0032691238F, - 0.0033798538F, 0.0034924239F, 0.0036068338F, 0.0037230833F, - 0.0038411721F, 0.0039610999F, 0.0040828664F, 0.0042064714F, - 0.0043319145F, 0.0044591954F, 0.0045883139F, 0.0047192696F, - 0.0048520622F, 0.0049866914F, 0.0051231569F, 0.0052614583F, - 0.0054015953F, 0.0055435676F, 0.0056873748F, 0.0058330166F, - 0.0059804926F, 0.0061298026F, 0.0062809460F, 0.0064339226F, - 0.0065887320F, 0.0067453738F, 0.0069038476F, 0.0070641531F, - 0.0072262899F, 0.0073902575F, 0.0075560556F, 0.0077236838F, - 0.0078931417F, 0.0080644288F, 0.0082375447F, 0.0084124891F, - 0.0085892615F, 0.0087678614F, 0.0089482885F, 0.0091305422F, - 0.0093146223F, 0.0095005281F, 0.0096882592F, 0.0098778153F, - 0.0100691958F, 0.0102624002F, 0.0104574281F, 0.0106542791F, - 0.0108529525F, 0.0110534480F, 0.0112557651F, 0.0114599032F, - 0.0116658618F, 0.0118736405F, 0.0120832387F, 0.0122946560F, - 0.0125078917F, 0.0127229454F, 0.0129398166F, 0.0131585046F, - 0.0133790090F, 0.0136013292F, 0.0138254647F, 0.0140514149F, - 0.0142791792F, 0.0145087572F, 0.0147401481F, 0.0149733515F, - 0.0152083667F, 0.0154451932F, 0.0156838304F, 0.0159242777F, - 0.0161665345F, 0.0164106001F, 0.0166564741F, 0.0169041557F, - 0.0171536443F, 0.0174049393F, 0.0176580401F, 0.0179129461F, - 0.0181696565F, 0.0184281708F, 0.0186884883F, 0.0189506084F, - 0.0192145303F, 0.0194802535F, 0.0197477772F, 0.0200171008F, - 0.0202882236F, 0.0205611449F, 0.0208358639F, 0.0211123801F, - 0.0213906927F, 0.0216708011F, 0.0219527043F, 0.0222364019F, - 0.0225218930F, 0.0228091769F, 0.0230982529F, 0.0233891203F, - 0.0236817782F, 0.0239762259F, 0.0242724628F, 0.0245704880F, - 0.0248703007F, 0.0251719002F, 0.0254752858F, 0.0257804565F, - 0.0260874117F, 0.0263961506F, 0.0267066722F, 0.0270189760F, - 0.0273330609F, 0.0276489263F, 0.0279665712F, 0.0282859949F, - 0.0286071966F, 0.0289301753F, 0.0292549303F, 0.0295814607F, - 0.0299097656F, 0.0302398442F, 0.0305716957F, 0.0309053191F, - 0.0312407135F, 0.0315778782F, 0.0319168122F, 0.0322575145F, - 0.0325999844F, 0.0329442209F, 0.0332902231F, 0.0336379900F, - 0.0339875208F, 0.0343388146F, 0.0346918703F, 0.0350466871F, - 0.0354032640F, 0.0357616000F, 0.0361216943F, 0.0364835458F, - 0.0368471535F, 0.0372125166F, 0.0375796339F, 0.0379485046F, - 0.0383191276F, 0.0386915020F, 0.0390656267F, 0.0394415008F, - 0.0398191231F, 0.0401984927F, 0.0405796086F, 0.0409624698F, - 0.0413470751F, 0.0417334235F, 0.0421215141F, 0.0425113457F, - 0.0429029172F, 0.0432962277F, 0.0436912760F, 0.0440880610F, - 0.0444865817F, 0.0448868370F, 0.0452888257F, 0.0456925468F, - 0.0460979992F, 0.0465051816F, 0.0469140931F, 0.0473247325F, - 0.0477370986F, 0.0481511902F, 0.0485670064F, 0.0489845458F, - 0.0494038074F, 0.0498247899F, 0.0502474922F, 0.0506719131F, - 0.0510980514F, 0.0515259060F, 0.0519554756F, 0.0523867590F, - 0.0528197550F, 0.0532544624F, 0.0536908800F, 0.0541290066F, - 0.0545688408F, 0.0550103815F, 0.0554536274F, 0.0558985772F, - 0.0563452297F, 0.0567935837F, 0.0572436377F, 0.0576953907F, - 0.0581488412F, 0.0586039880F, 0.0590608297F, 0.0595193651F, - 0.0599795929F, 0.0604415117F, 0.0609051202F, 0.0613704170F, - 0.0618374009F, 0.0623060704F, 0.0627764243F, 0.0632484611F, - 0.0637221795F, 0.0641975781F, 0.0646746555F, 0.0651534104F, - 0.0656338413F, 0.0661159469F, 0.0665997257F, 0.0670851763F, - 0.0675722973F, 0.0680610873F, 0.0685515448F, 0.0690436684F, - 0.0695374567F, 0.0700329081F, 0.0705300213F, 0.0710287947F, - 0.0715292269F, 0.0720313163F, 0.0725350616F, 0.0730404612F, - 0.0735475136F, 0.0740562172F, 0.0745665707F, 0.0750785723F, - 0.0755922207F, 0.0761075143F, 0.0766244515F, 0.0771430307F, - 0.0776632505F, 0.0781851092F, 0.0787086052F, 0.0792337371F, - 0.0797605032F, 0.0802889018F, 0.0808189315F, 0.0813505905F, - 0.0818838773F, 0.0824187903F, 0.0829553277F, 0.0834934881F, - 0.0840332697F, 0.0845746708F, 0.0851176899F, 0.0856623252F, - 0.0862085751F, 0.0867564379F, 0.0873059119F, 0.0878569954F, - 0.0884096867F, 0.0889639840F, 0.0895198858F, 0.0900773902F, - 0.0906364955F, 0.0911972000F, 0.0917595019F, 0.0923233995F, - 0.0928888909F, 0.0934559745F, 0.0940246485F, 0.0945949110F, - 0.0951667604F, 0.0957401946F, 0.0963152121F, 0.0968918109F, - 0.0974699893F, 0.0980497454F, 0.0986310773F, 0.0992139832F, - 0.0997984614F, 0.1003845098F, 0.1009721267F, 0.1015613101F, - 0.1021520582F, 0.1027443692F, 0.1033382410F, 0.1039336718F, - 0.1045306597F, 0.1051292027F, 0.1057292990F, 0.1063309466F, - 0.1069341435F, 0.1075388878F, 0.1081451776F, 0.1087530108F, - 0.1093623856F, 0.1099732998F, 0.1105857516F, 0.1111997389F, - 0.1118152597F, 0.1124323121F, 0.1130508939F, 0.1136710032F, - 0.1142926379F, 0.1149157960F, 0.1155404755F, 0.1161666742F, - 0.1167943901F, 0.1174236211F, 0.1180543652F, 0.1186866202F, - 0.1193203841F, 0.1199556548F, 0.1205924300F, 0.1212307078F, - 0.1218704860F, 0.1225117624F, 0.1231545349F, 0.1237988013F, - 0.1244445596F, 0.1250918074F, 0.1257405427F, 0.1263907632F, - 0.1270424667F, 0.1276956512F, 0.1283503142F, 0.1290064537F, - 0.1296640674F, 0.1303231530F, 0.1309837084F, 0.1316457312F, - 0.1323092193F, 0.1329741703F, 0.1336405820F, 0.1343084520F, - 0.1349777782F, 0.1356485582F, 0.1363207897F, 0.1369944704F, - 0.1376695979F, 0.1383461700F, 0.1390241842F, 0.1397036384F, - 0.1403845300F, 0.1410668567F, 0.1417506162F, 0.1424358061F, - 0.1431224240F, 0.1438104674F, 0.1444999341F, 0.1451908216F, - 0.1458831274F, 0.1465768492F, 0.1472719844F, 0.1479685308F, - 0.1486664857F, 0.1493658468F, 0.1500666115F, 0.1507687775F, - 0.1514723422F, 0.1521773031F, 0.1528836577F, 0.1535914035F, - 0.1543005380F, 0.1550110587F, 0.1557229631F, 0.1564362485F, - 0.1571509124F, 0.1578669524F, 0.1585843657F, 0.1593031499F, - 0.1600233024F, 0.1607448205F, 0.1614677017F, 0.1621919433F, - 0.1629175428F, 0.1636444975F, 0.1643728047F, 0.1651024619F, - 0.1658334665F, 0.1665658156F, 0.1672995067F, 0.1680345371F, - 0.1687709041F, 0.1695086050F, 0.1702476372F, 0.1709879978F, - 0.1717296843F, 0.1724726938F, 0.1732170237F, 0.1739626711F, - 0.1747096335F, 0.1754579079F, 0.1762074916F, 0.1769583819F, - 0.1777105760F, 0.1784640710F, 0.1792188642F, 0.1799749529F, - 0.1807323340F, 0.1814910049F, 0.1822509628F, 0.1830122046F, - 0.1837747277F, 0.1845385292F, 0.1853036062F, 0.1860699558F, - 0.1868375751F, 0.1876064613F, 0.1883766114F, 0.1891480226F, - 0.1899206919F, 0.1906946164F, 0.1914697932F, 0.1922462194F, - 0.1930238919F, 0.1938028079F, 0.1945829643F, 0.1953643583F, - 0.1961469868F, 0.1969308468F, 0.1977159353F, 0.1985022494F, - 0.1992897859F, 0.2000785420F, 0.2008685145F, 0.2016597005F, - 0.2024520968F, 0.2032457005F, 0.2040405084F, 0.2048365175F, - 0.2056337247F, 0.2064321269F, 0.2072317211F, 0.2080325041F, - 0.2088344727F, 0.2096376240F, 0.2104419547F, 0.2112474618F, - 0.2120541420F, 0.2128619923F, 0.2136710094F, 0.2144811902F, - 0.2152925315F, 0.2161050301F, 0.2169186829F, 0.2177334866F, - 0.2185494381F, 0.2193665340F, 0.2201847712F, 0.2210041465F, - 0.2218246565F, 0.2226462981F, 0.2234690680F, 0.2242929629F, - 0.2251179796F, 0.2259441147F, 0.2267713650F, 0.2275997272F, - 0.2284291979F, 0.2292597739F, 0.2300914518F, 0.2309242283F, - 0.2317581001F, 0.2325930638F, 0.2334291160F, 0.2342662534F, - 0.2351044727F, 0.2359437703F, 0.2367841431F, 0.2376255875F, - 0.2384681001F, 0.2393116776F, 0.2401563165F, 0.2410020134F, - 0.2418487649F, 0.2426965675F, 0.2435454178F, 0.2443953122F, - 0.2452462474F, 0.2460982199F, 0.2469512262F, 0.2478052628F, - 0.2486603262F, 0.2495164129F, 0.2503735194F, 0.2512316421F, - 0.2520907776F, 0.2529509222F, 0.2538120726F, 0.2546742250F, - 0.2555373760F, 0.2564015219F, 0.2572666593F, 0.2581327845F, - 0.2589998939F, 0.2598679840F, 0.2607370510F, 0.2616070916F, - 0.2624781019F, 0.2633500783F, 0.2642230173F, 0.2650969152F, - 0.2659717684F, 0.2668475731F, 0.2677243257F, 0.2686020226F, - 0.2694806601F, 0.2703602344F, 0.2712407419F, 0.2721221789F, - 0.2730045417F, 0.2738878265F, 0.2747720297F, 0.2756571474F, - 0.2765431760F, 0.2774301117F, 0.2783179508F, 0.2792066895F, - 0.2800963240F, 0.2809868505F, 0.2818782654F, 0.2827705647F, - 0.2836637447F, 0.2845578016F, 0.2854527315F, 0.2863485307F, - 0.2872451953F, 0.2881427215F, 0.2890411055F, 0.2899403433F, - 0.2908404312F, 0.2917413654F, 0.2926431418F, 0.2935457567F, - 0.2944492061F, 0.2953534863F, 0.2962585932F, 0.2971645230F, - 0.2980712717F, 0.2989788356F, 0.2998872105F, 0.3007963927F, - 0.3017063781F, 0.3026171629F, 0.3035287430F, 0.3044411145F, - 0.3053542736F, 0.3062682161F, 0.3071829381F, 0.3080984356F, - 0.3090147047F, 0.3099317413F, 0.3108495414F, 0.3117681011F, - 0.3126874163F, 0.3136074830F, 0.3145282972F, 0.3154498548F, - 0.3163721517F, 0.3172951841F, 0.3182189477F, 0.3191434385F, - 0.3200686525F, 0.3209945856F, 0.3219212336F, 0.3228485927F, - 0.3237766585F, 0.3247054271F, 0.3256348943F, 0.3265650560F, - 0.3274959081F, 0.3284274465F, 0.3293596671F, 0.3302925657F, - 0.3312261382F, 0.3321603804F, 0.3330952882F, 0.3340308574F, - 0.3349670838F, 0.3359039634F, 0.3368414919F, 0.3377796651F, - 0.3387184789F, 0.3396579290F, 0.3405980113F, 0.3415387216F, - 0.3424800556F, 0.3434220091F, 0.3443645779F, 0.3453077578F, - 0.3462515446F, 0.3471959340F, 0.3481409217F, 0.3490865036F, - 0.3500326754F, 0.3509794328F, 0.3519267715F, 0.3528746873F, - 0.3538231759F, 0.3547722330F, 0.3557218544F, 0.3566720357F, - 0.3576227727F, 0.3585740610F, 0.3595258964F, 0.3604782745F, - 0.3614311910F, 0.3623846417F, 0.3633386221F, 0.3642931280F, - 0.3652481549F, 0.3662036987F, 0.3671597548F, 0.3681163191F, - 0.3690733870F, 0.3700309544F, 0.3709890167F, 0.3719475696F, - 0.3729066089F, 0.3738661299F, 0.3748261285F, 0.3757866002F, - 0.3767475406F, 0.3777089453F, 0.3786708100F, 0.3796331302F, - 0.3805959014F, 0.3815591194F, 0.3825227796F, 0.3834868777F, - 0.3844514093F, 0.3854163698F, 0.3863817549F, 0.3873475601F, - 0.3883137810F, 0.3892804131F, 0.3902474521F, 0.3912148933F, - 0.3921827325F, 0.3931509650F, 0.3941195865F, 0.3950885925F, - 0.3960579785F, 0.3970277400F, 0.3979978725F, 0.3989683716F, - 0.3999392328F, 0.4009104516F, 0.4018820234F, 0.4028539438F, - 0.4038262084F, 0.4047988125F, 0.4057717516F, 0.4067450214F, - 0.4077186172F, 0.4086925345F, 0.4096667688F, 0.4106413155F, - 0.4116161703F, 0.4125913284F, 0.4135667854F, 0.4145425368F, - 0.4155185780F, 0.4164949044F, 0.4174715116F, 0.4184483949F, - 0.4194255498F, 0.4204029718F, 0.4213806563F, 0.4223585987F, - 0.4233367946F, 0.4243152392F, 0.4252939281F, 0.4262728566F, - 0.4272520202F, 0.4282314144F, 0.4292110345F, 0.4301908760F, - 0.4311709343F, 0.4321512047F, 0.4331316828F, 0.4341123639F, - 0.4350932435F, 0.4360743168F, 0.4370555794F, 0.4380370267F, - 0.4390186540F, 0.4400004567F, 0.4409824303F, 0.4419645701F, - 0.4429468716F, 0.4439293300F, 0.4449119409F, 0.4458946996F, - 0.4468776014F, 0.4478606418F, 0.4488438162F, 0.4498271199F, - 0.4508105483F, 0.4517940967F, 0.4527777607F, 0.4537615355F, - 0.4547454165F, 0.4557293991F, 0.4567134786F, 0.4576976505F, - 0.4586819101F, 0.4596662527F, 0.4606506738F, 0.4616351687F, - 0.4626197328F, 0.4636043614F, 0.4645890499F, 0.4655737936F, - 0.4665585880F, 0.4675434284F, 0.4685283101F, 0.4695132286F, - 0.4704981791F, 0.4714831570F, 0.4724681577F, 0.4734531766F, - 0.4744382089F, 0.4754232501F, 0.4764082956F, 0.4773933406F, - 0.4783783806F, 0.4793634108F, 0.4803484267F, 0.4813334237F, - 0.4823183969F, 0.4833033419F, 0.4842882540F, 0.4852731285F, - 0.4862579608F, 0.4872427462F, 0.4882274802F, 0.4892121580F, - 0.4901967751F, 0.4911813267F, 0.4921658083F, 0.4931502151F, - 0.4941345427F, 0.4951187863F, 0.4961029412F, 0.4970870029F, - 0.4980709667F, 0.4990548280F, 0.5000385822F, 0.5010222245F, - 0.5020057505F, 0.5029891553F, 0.5039724345F, 0.5049555834F, - 0.5059385973F, 0.5069214716F, 0.5079042018F, 0.5088867831F, - 0.5098692110F, 0.5108514808F, 0.5118335879F, 0.5128155277F, - 0.5137972956F, 0.5147788869F, 0.5157602971F, 0.5167415215F, - 0.5177225555F, 0.5187033945F, 0.5196840339F, 0.5206644692F, - 0.5216446956F, 0.5226247086F, 0.5236045035F, 0.5245840759F, - 0.5255634211F, 0.5265425344F, 0.5275214114F, 0.5285000474F, - 0.5294784378F, 0.5304565781F, 0.5314344637F, 0.5324120899F, - 0.5333894522F, 0.5343665461F, 0.5353433670F, 0.5363199102F, - 0.5372961713F, 0.5382721457F, 0.5392478287F, 0.5402232159F, - 0.5411983027F, 0.5421730845F, 0.5431475569F, 0.5441217151F, - 0.5450955548F, 0.5460690714F, 0.5470422602F, 0.5480151169F, - 0.5489876368F, 0.5499598155F, 0.5509316484F, 0.5519031310F, - 0.5528742587F, 0.5538450271F, 0.5548154317F, 0.5557854680F, - 0.5567551314F, 0.5577244174F, 0.5586933216F, 0.5596618395F, - 0.5606299665F, 0.5615976983F, 0.5625650302F, 0.5635319580F, - 0.5644984770F, 0.5654645828F, 0.5664302709F, 0.5673955370F, - 0.5683603765F, 0.5693247850F, 0.5702887580F, 0.5712522912F, - 0.5722153800F, 0.5731780200F, 0.5741402069F, 0.5751019362F, - 0.5760632034F, 0.5770240042F, 0.5779843341F, 0.5789441889F, - 0.5799035639F, 0.5808624549F, 0.5818208575F, 0.5827787673F, - 0.5837361800F, 0.5846930910F, 0.5856494961F, 0.5866053910F, - 0.5875607712F, 0.5885156324F, 0.5894699703F, 0.5904237804F, - 0.5913770586F, 0.5923298004F, 0.5932820016F, 0.5942336578F, - 0.5951847646F, 0.5961353179F, 0.5970853132F, 0.5980347464F, - 0.5989836131F, 0.5999319090F, 0.6008796298F, 0.6018267713F, - 0.6027733292F, 0.6037192993F, 0.6046646773F, 0.6056094589F, - 0.6065536400F, 0.6074972162F, 0.6084401833F, 0.6093825372F, - 0.6103242736F, 0.6112653884F, 0.6122058772F, 0.6131457359F, - 0.6140849604F, 0.6150235464F, 0.6159614897F, 0.6168987862F, - 0.6178354318F, 0.6187714223F, 0.6197067535F, 0.6206414213F, - 0.6215754215F, 0.6225087501F, 0.6234414028F, 0.6243733757F, - 0.6253046646F, 0.6262352654F, 0.6271651739F, 0.6280943862F, - 0.6290228982F, 0.6299507057F, 0.6308778048F, 0.6318041913F, - 0.6327298612F, 0.6336548105F, 0.6345790352F, 0.6355025312F, - 0.6364252945F, 0.6373473211F, 0.6382686070F, 0.6391891483F, - 0.6401089409F, 0.6410279808F, 0.6419462642F, 0.6428637869F, - 0.6437805452F, 0.6446965350F, 0.6456117524F, 0.6465261935F, - 0.6474398544F, 0.6483527311F, 0.6492648197F, 0.6501761165F, - 0.6510866174F, 0.6519963186F, 0.6529052162F, 0.6538133064F, - 0.6547205854F, 0.6556270492F, 0.6565326941F, 0.6574375162F, - 0.6583415117F, 0.6592446769F, 0.6601470079F, 0.6610485009F, - 0.6619491521F, 0.6628489578F, 0.6637479143F, 0.6646460177F, - 0.6655432643F, 0.6664396505F, 0.6673351724F, 0.6682298264F, - 0.6691236087F, 0.6700165157F, 0.6709085436F, 0.6717996889F, - 0.6726899478F, 0.6735793167F, 0.6744677918F, 0.6753553697F, - 0.6762420466F, 0.6771278190F, 0.6780126832F, 0.6788966357F, - 0.6797796728F, 0.6806617909F, 0.6815429866F, 0.6824232562F, - 0.6833025961F, 0.6841810030F, 0.6850584731F, 0.6859350031F, - 0.6868105894F, 0.6876852284F, 0.6885589168F, 0.6894316510F, - 0.6903034275F, 0.6911742430F, 0.6920440939F, 0.6929129769F, - 0.6937808884F, 0.6946478251F, 0.6955137837F, 0.6963787606F, - 0.6972427525F, 0.6981057560F, 0.6989677678F, 0.6998287845F, - 0.7006888028F, 0.7015478194F, 0.7024058309F, 0.7032628340F, - 0.7041188254F, 0.7049738019F, 0.7058277601F, 0.7066806969F, - 0.7075326089F, 0.7083834929F, 0.7092333457F, 0.7100821640F, - 0.7109299447F, 0.7117766846F, 0.7126223804F, 0.7134670291F, - 0.7143106273F, 0.7151531721F, 0.7159946602F, 0.7168350885F, - 0.7176744539F, 0.7185127534F, 0.7193499837F, 0.7201861418F, - 0.7210212247F, 0.7218552293F, 0.7226881526F, 0.7235199914F, - 0.7243507428F, 0.7251804039F, 0.7260089715F, 0.7268364426F, - 0.7276628144F, 0.7284880839F, 0.7293122481F, 0.7301353040F, - 0.7309572487F, 0.7317780794F, 0.7325977930F, 0.7334163868F, - 0.7342338579F, 0.7350502033F, 0.7358654202F, 0.7366795059F, - 0.7374924573F, 0.7383042718F, 0.7391149465F, 0.7399244787F, - 0.7407328655F, 0.7415401041F, 0.7423461920F, 0.7431511261F, - 0.7439549040F, 0.7447575227F, 0.7455589797F, 0.7463592723F, - 0.7471583976F, 0.7479563532F, 0.7487531363F, 0.7495487443F, - 0.7503431745F, 0.7511364244F, 0.7519284913F, 0.7527193726F, - 0.7535090658F, 0.7542975683F, 0.7550848776F, 0.7558709910F, - 0.7566559062F, 0.7574396205F, 0.7582221314F, 0.7590034366F, - 0.7597835334F, 0.7605624194F, 0.7613400923F, 0.7621165495F, - 0.7628917886F, 0.7636658072F, 0.7644386030F, 0.7652101735F, - 0.7659805164F, 0.7667496292F, 0.7675175098F, 0.7682841556F, - 0.7690495645F, 0.7698137341F, 0.7705766622F, 0.7713383463F, - 0.7720987844F, 0.7728579741F, 0.7736159132F, 0.7743725994F, - 0.7751280306F, 0.7758822046F, 0.7766351192F, 0.7773867722F, - 0.7781371614F, 0.7788862848F, 0.7796341401F, 0.7803807253F, - 0.7811260383F, 0.7818700769F, 0.7826128392F, 0.7833543230F, - 0.7840945263F, 0.7848334471F, 0.7855710833F, 0.7863074330F, - 0.7870424941F, 0.7877762647F, 0.7885087428F, 0.7892399264F, - 0.7899698137F, 0.7906984026F, 0.7914256914F, 0.7921516780F, - 0.7928763607F, 0.7935997375F, 0.7943218065F, 0.7950425661F, - 0.7957620142F, 0.7964801492F, 0.7971969692F, 0.7979124724F, - 0.7986266570F, 0.7993395214F, 0.8000510638F, 0.8007612823F, - 0.8014701754F, 0.8021777413F, 0.8028839784F, 0.8035888849F, - 0.8042924592F, 0.8049946997F, 0.8056956048F, 0.8063951727F, - 0.8070934020F, 0.8077902910F, 0.8084858381F, 0.8091800419F, - 0.8098729007F, 0.8105644130F, 0.8112545774F, 0.8119433922F, - 0.8126308561F, 0.8133169676F, 0.8140017251F, 0.8146851272F, - 0.8153671726F, 0.8160478598F, 0.8167271874F, 0.8174051539F, - 0.8180817582F, 0.8187569986F, 0.8194308741F, 0.8201033831F, - 0.8207745244F, 0.8214442966F, 0.8221126986F, 0.8227797290F, - 0.8234453865F, 0.8241096700F, 0.8247725781F, 0.8254341097F, - 0.8260942636F, 0.8267530385F, 0.8274104334F, 0.8280664470F, - 0.8287210782F, 0.8293743259F, 0.8300261889F, 0.8306766662F, - 0.8313257566F, 0.8319734591F, 0.8326197727F, 0.8332646963F, - 0.8339082288F, 0.8345503692F, 0.8351911167F, 0.8358304700F, - 0.8364684284F, 0.8371049907F, 0.8377401562F, 0.8383739238F, - 0.8390062927F, 0.8396372618F, 0.8402668305F, 0.8408949977F, - 0.8415217626F, 0.8421471245F, 0.8427710823F, 0.8433936354F, - 0.8440147830F, 0.8446345242F, 0.8452528582F, 0.8458697844F, - 0.8464853020F, 0.8470994102F, 0.8477121084F, 0.8483233958F, - 0.8489332718F, 0.8495417356F, 0.8501487866F, 0.8507544243F, - 0.8513586479F, 0.8519614568F, 0.8525628505F, 0.8531628283F, - 0.8537613897F, 0.8543585341F, 0.8549542611F, 0.8555485699F, - 0.8561414603F, 0.8567329315F, 0.8573229832F, 0.8579116149F, - 0.8584988262F, 0.8590846165F, 0.8596689855F, 0.8602519327F, - 0.8608334577F, 0.8614135603F, 0.8619922399F, 0.8625694962F, - 0.8631453289F, 0.8637197377F, 0.8642927222F, 0.8648642821F, - 0.8654344172F, 0.8660031272F, 0.8665704118F, 0.8671362708F, - 0.8677007039F, 0.8682637109F, 0.8688252917F, 0.8693854460F, - 0.8699441737F, 0.8705014745F, 0.8710573485F, 0.8716117953F, - 0.8721648150F, 0.8727164073F, 0.8732665723F, 0.8738153098F, - 0.8743626197F, 0.8749085021F, 0.8754529569F, 0.8759959840F, - 0.8765375835F, 0.8770777553F, 0.8776164996F, 0.8781538162F, - 0.8786897054F, 0.8792241670F, 0.8797572013F, 0.8802888082F, - 0.8808189880F, 0.8813477407F, 0.8818750664F, 0.8824009653F, - 0.8829254375F, 0.8834484833F, 0.8839701028F, 0.8844902961F, - 0.8850090636F, 0.8855264054F, 0.8860423218F, 0.8865568131F, - 0.8870698794F, 0.8875815212F, 0.8880917386F, 0.8886005319F, - 0.8891079016F, 0.8896138479F, 0.8901183712F, 0.8906214719F, - 0.8911231503F, 0.8916234067F, 0.8921222417F, 0.8926196556F, - 0.8931156489F, 0.8936102219F, 0.8941033752F, 0.8945951092F, - 0.8950854244F, 0.8955743212F, 0.8960618003F, 0.8965478621F, - 0.8970325071F, 0.8975157359F, 0.8979975490F, 0.8984779471F, - 0.8989569307F, 0.8994345004F, 0.8999106568F, 0.9003854005F, - 0.9008587323F, 0.9013306526F, 0.9018011623F, 0.9022702619F, - 0.9027379521F, 0.9032042337F, 0.9036691074F, 0.9041325739F, - 0.9045946339F, 0.9050552882F, 0.9055145376F, 0.9059723828F, - 0.9064288246F, 0.9068838638F, 0.9073375013F, 0.9077897379F, - 0.9082405743F, 0.9086900115F, 0.9091380503F, 0.9095846917F, - 0.9100299364F, 0.9104737854F, 0.9109162397F, 0.9113573001F, - 0.9117969675F, 0.9122352430F, 0.9126721275F, 0.9131076219F, - 0.9135417273F, 0.9139744447F, 0.9144057750F, 0.9148357194F, - 0.9152642787F, 0.9156914542F, 0.9161172468F, 0.9165416576F, - 0.9169646877F, 0.9173863382F, 0.9178066102F, 0.9182255048F, - 0.9186430232F, 0.9190591665F, 0.9194739359F, 0.9198873324F, - 0.9202993574F, 0.9207100120F, 0.9211192973F, 0.9215272147F, - 0.9219337653F, 0.9223389504F, 0.9227427713F, 0.9231452290F, - 0.9235463251F, 0.9239460607F, 0.9243444371F, 0.9247414557F, - 0.9251371177F, 0.9255314245F, 0.9259243774F, 0.9263159778F, - 0.9267062270F, 0.9270951264F, 0.9274826774F, 0.9278688814F, - 0.9282537398F, 0.9286372540F, 0.9290194254F, 0.9294002555F, - 0.9297797458F, 0.9301578976F, 0.9305347125F, 0.9309101919F, - 0.9312843373F, 0.9316571503F, 0.9320286323F, 0.9323987849F, - 0.9327676097F, 0.9331351080F, 0.9335012816F, 0.9338661320F, - 0.9342296607F, 0.9345918694F, 0.9349527596F, 0.9353123330F, - 0.9356705911F, 0.9360275357F, 0.9363831683F, 0.9367374905F, - 0.9370905042F, 0.9374422108F, 0.9377926122F, 0.9381417099F, - 0.9384895057F, 0.9388360014F, 0.9391811985F, 0.9395250989F, - 0.9398677043F, 0.9402090165F, 0.9405490371F, 0.9408877680F, - 0.9412252110F, 0.9415613678F, 0.9418962402F, 0.9422298301F, - 0.9425621392F, 0.9428931695F, 0.9432229226F, 0.9435514005F, - 0.9438786050F, 0.9442045381F, 0.9445292014F, 0.9448525971F, - 0.9451747268F, 0.9454955926F, 0.9458151963F, 0.9461335399F, - 0.9464506253F, 0.9467664545F, 0.9470810293F, 0.9473943517F, - 0.9477064238F, 0.9480172474F, 0.9483268246F, 0.9486351573F, - 0.9489422475F, 0.9492480973F, 0.9495527087F, 0.9498560837F, - 0.9501582243F, 0.9504591325F, 0.9507588105F, 0.9510572603F, - 0.9513544839F, 0.9516504834F, 0.9519452609F, 0.9522388186F, - 0.9525311584F, 0.9528222826F, 0.9531121932F, 0.9534008923F, - 0.9536883821F, 0.9539746647F, 0.9542597424F, 0.9545436171F, - 0.9548262912F, 0.9551077667F, 0.9553880459F, 0.9556671309F, - 0.9559450239F, 0.9562217272F, 0.9564972429F, 0.9567715733F, - 0.9570447206F, 0.9573166871F, 0.9575874749F, 0.9578570863F, - 0.9581255236F, 0.9583927890F, 0.9586588849F, 0.9589238134F, - 0.9591875769F, 0.9594501777F, 0.9597116180F, 0.9599719003F, - 0.9602310267F, 0.9604889995F, 0.9607458213F, 0.9610014942F, - 0.9612560206F, 0.9615094028F, 0.9617616433F, 0.9620127443F, - 0.9622627083F, 0.9625115376F, 0.9627592345F, 0.9630058016F, - 0.9632512411F, 0.9634955555F, 0.9637387471F, 0.9639808185F, - 0.9642217720F, 0.9644616100F, 0.9647003349F, 0.9649379493F, - 0.9651744556F, 0.9654098561F, 0.9656441534F, 0.9658773499F, - 0.9661094480F, 0.9663404504F, 0.9665703593F, 0.9667991774F, - 0.9670269071F, 0.9672535509F, 0.9674791114F, 0.9677035909F, - 0.9679269921F, 0.9681493174F, 0.9683705694F, 0.9685907506F, - 0.9688098636F, 0.9690279108F, 0.9692448948F, 0.9694608182F, - 0.9696756836F, 0.9698894934F, 0.9701022503F, 0.9703139569F, - 0.9705246156F, 0.9707342291F, 0.9709428000F, 0.9711503309F, - 0.9713568243F, 0.9715622829F, 0.9717667093F, 0.9719701060F, - 0.9721724757F, 0.9723738210F, 0.9725741446F, 0.9727734490F, - 0.9729717369F, 0.9731690109F, 0.9733652737F, 0.9735605279F, - 0.9737547762F, 0.9739480212F, 0.9741402656F, 0.9743315120F, - 0.9745217631F, 0.9747110216F, 0.9748992901F, 0.9750865714F, - 0.9752728681F, 0.9754581829F, 0.9756425184F, 0.9758258775F, - 0.9760082627F, 0.9761896768F, 0.9763701224F, 0.9765496024F, - 0.9767281193F, 0.9769056760F, 0.9770822751F, 0.9772579193F, - 0.9774326114F, 0.9776063542F, 0.9777791502F, 0.9779510023F, - 0.9781219133F, 0.9782918858F, 0.9784609226F, 0.9786290264F, - 0.9787962000F, 0.9789624461F, 0.9791277676F, 0.9792921671F, - 0.9794556474F, 0.9796182113F, 0.9797798615F, 0.9799406009F, - 0.9801004321F, 0.9802593580F, 0.9804173813F, 0.9805745049F, - 0.9807307314F, 0.9808860637F, 0.9810405046F, 0.9811940568F, - 0.9813467232F, 0.9814985065F, 0.9816494095F, 0.9817994351F, - 0.9819485860F, 0.9820968650F, 0.9822442750F, 0.9823908186F, - 0.9825364988F, 0.9826813184F, 0.9828252801F, 0.9829683868F, - 0.9831106413F, 0.9832520463F, 0.9833926048F, 0.9835323195F, - 0.9836711932F, 0.9838092288F, 0.9839464291F, 0.9840827969F, - 0.9842183351F, 0.9843530464F, 0.9844869337F, 0.9846199998F, - 0.9847522475F, 0.9848836798F, 0.9850142993F, 0.9851441090F, - 0.9852731117F, 0.9854013101F, 0.9855287073F, 0.9856553058F, - 0.9857811087F, 0.9859061188F, 0.9860303388F, 0.9861537717F, - 0.9862764202F, 0.9863982872F, 0.9865193756F, 0.9866396882F, - 0.9867592277F, 0.9868779972F, 0.9869959993F, 0.9871132370F, - 0.9872297131F, 0.9873454304F, 0.9874603918F, 0.9875746001F, - 0.9876880581F, 0.9878007688F, 0.9879127348F, 0.9880239592F, - 0.9881344447F, 0.9882441941F, 0.9883532104F, 0.9884614962F, - 0.9885690546F, 0.9886758883F, 0.9887820001F, 0.9888873930F, - 0.9889920697F, 0.9890960331F, 0.9891992859F, 0.9893018312F, - 0.9894036716F, 0.9895048100F, 0.9896052493F, 0.9897049923F, - 0.9898040418F, 0.9899024006F, 0.9900000717F, 0.9900970577F, - 0.9901933616F, 0.9902889862F, 0.9903839343F, 0.9904782087F, - 0.9905718122F, 0.9906647477F, 0.9907570180F, 0.9908486259F, - 0.9909395742F, 0.9910298658F, 0.9911195034F, 0.9912084899F, - 0.9912968281F, 0.9913845208F, 0.9914715708F, 0.9915579810F, - 0.9916437540F, 0.9917288928F, 0.9918134001F, 0.9918972788F, - 0.9919805316F, 0.9920631613F, 0.9921451707F, 0.9922265626F, - 0.9923073399F, 0.9923875052F, 0.9924670615F, 0.9925460114F, - 0.9926243577F, 0.9927021033F, 0.9927792508F, 0.9928558032F, - 0.9929317631F, 0.9930071333F, 0.9930819167F, 0.9931561158F, - 0.9932297337F, 0.9933027728F, 0.9933752362F, 0.9934471264F, - 0.9935184462F, 0.9935891985F, 0.9936593859F, 0.9937290112F, - 0.9937980771F, 0.9938665864F, 0.9939345418F, 0.9940019460F, - 0.9940688018F, 0.9941351118F, 0.9942008789F, 0.9942661057F, - 0.9943307950F, 0.9943949494F, 0.9944585717F, 0.9945216645F, - 0.9945842307F, 0.9946462728F, 0.9947077936F, 0.9947687957F, - 0.9948292820F, 0.9948892550F, 0.9949487174F, 0.9950076719F, - 0.9950661212F, 0.9951240679F, 0.9951815148F, 0.9952384645F, - 0.9952949196F, 0.9953508828F, 0.9954063568F, 0.9954613442F, - 0.9955158476F, 0.9955698697F, 0.9956234132F, 0.9956764806F, - 0.9957290746F, 0.9957811978F, 0.9958328528F, 0.9958840423F, - 0.9959347688F, 0.9959850351F, 0.9960348435F, 0.9960841969F, - 0.9961330977F, 0.9961815486F, 0.9962295521F, 0.9962771108F, - 0.9963242274F, 0.9963709043F, 0.9964171441F, 0.9964629494F, - 0.9965083228F, 0.9965532668F, 0.9965977840F, 0.9966418768F, - 0.9966855479F, 0.9967287998F, 0.9967716350F, 0.9968140559F, - 0.9968560653F, 0.9968976655F, 0.9969388591F, 0.9969796485F, - 0.9970200363F, 0.9970600250F, 0.9970996170F, 0.9971388149F, - 0.9971776211F, 0.9972160380F, 0.9972540683F, 0.9972917142F, - 0.9973289783F, 0.9973658631F, 0.9974023709F, 0.9974385042F, - 0.9974742655F, 0.9975096571F, 0.9975446816F, 0.9975793413F, - 0.9976136386F, 0.9976475759F, 0.9976811557F, 0.9977143803F, - 0.9977472521F, 0.9977797736F, 0.9978119470F, 0.9978437748F, - 0.9978752593F, 0.9979064029F, 0.9979372079F, 0.9979676768F, - 0.9979978117F, 0.9980276151F, 0.9980570893F, 0.9980862367F, - 0.9981150595F, 0.9981435600F, 0.9981717406F, 0.9981996035F, - 0.9982271511F, 0.9982543856F, 0.9982813093F, 0.9983079246F, - 0.9983342336F, 0.9983602386F, 0.9983859418F, 0.9984113456F, - 0.9984364522F, 0.9984612638F, 0.9984857825F, 0.9985100108F, - 0.9985339507F, 0.9985576044F, 0.9985809743F, 0.9986040624F, - 0.9986268710F, 0.9986494022F, 0.9986716583F, 0.9986936413F, - 0.9987153535F, 0.9987367969F, 0.9987579738F, 0.9987788864F, - 0.9987995366F, 0.9988199267F, 0.9988400587F, 0.9988599348F, - 0.9988795572F, 0.9988989278F, 0.9989180487F, 0.9989369222F, - 0.9989555501F, 0.9989739347F, 0.9989920780F, 0.9990099820F, - 0.9990276487F, 0.9990450803F, 0.9990622787F, 0.9990792460F, - 0.9990959841F, 0.9991124952F, 0.9991287812F, 0.9991448440F, - 0.9991606858F, 0.9991763084F, 0.9991917139F, 0.9992069042F, - 0.9992218813F, 0.9992366471F, 0.9992512035F, 0.9992655525F, - 0.9992796961F, 0.9992936361F, 0.9993073744F, 0.9993209131F, - 0.9993342538F, 0.9993473987F, 0.9993603494F, 0.9993731080F, - 0.9993856762F, 0.9993980559F, 0.9994102490F, 0.9994222573F, - 0.9994340827F, 0.9994457269F, 0.9994571918F, 0.9994684793F, - 0.9994795910F, 0.9994905288F, 0.9995012945F, 0.9995118898F, - 0.9995223165F, 0.9995325765F, 0.9995426713F, 0.9995526029F, - 0.9995623728F, 0.9995719829F, 0.9995814349F, 0.9995907304F, - 0.9995998712F, 0.9996088590F, 0.9996176954F, 0.9996263821F, - 0.9996349208F, 0.9996433132F, 0.9996515609F, 0.9996596656F, - 0.9996676288F, 0.9996754522F, 0.9996831375F, 0.9996906862F, - 0.9996981000F, 0.9997053804F, 0.9997125290F, 0.9997195474F, - 0.9997264371F, 0.9997331998F, 0.9997398369F, 0.9997463500F, - 0.9997527406F, 0.9997590103F, 0.9997651606F, 0.9997711930F, - 0.9997771089F, 0.9997829098F, 0.9997885973F, 0.9997941728F, - 0.9997996378F, 0.9998049936F, 0.9998102419F, 0.9998153839F, - 0.9998204211F, 0.9998253550F, 0.9998301868F, 0.9998349182F, - 0.9998395503F, 0.9998440847F, 0.9998485226F, 0.9998528654F, - 0.9998571146F, 0.9998612713F, 0.9998653370F, 0.9998693130F, - 0.9998732007F, 0.9998770012F, 0.9998807159F, 0.9998843461F, - 0.9998878931F, 0.9998913581F, 0.9998947424F, 0.9998980473F, - 0.9999012740F, 0.9999044237F, 0.9999074976F, 0.9999104971F, - 0.9999134231F, 0.9999162771F, 0.9999190601F, 0.9999217733F, - 0.9999244179F, 0.9999269950F, 0.9999295058F, 0.9999319515F, - 0.9999343332F, 0.9999366519F, 0.9999389088F, 0.9999411050F, - 0.9999432416F, 0.9999453196F, 0.9999473402F, 0.9999493044F, - 0.9999512132F, 0.9999530677F, 0.9999548690F, 0.9999566180F, - 0.9999583157F, 0.9999599633F, 0.9999615616F, 0.9999631116F, - 0.9999646144F, 0.9999660709F, 0.9999674820F, 0.9999688487F, - 0.9999701719F, 0.9999714526F, 0.9999726917F, 0.9999738900F, - 0.9999750486F, 0.9999761682F, 0.9999772497F, 0.9999782941F, - 0.9999793021F, 0.9999802747F, 0.9999812126F, 0.9999821167F, - 0.9999829878F, 0.9999838268F, 0.9999846343F, 0.9999854113F, - 0.9999861584F, 0.9999868765F, 0.9999875664F, 0.9999882287F, - 0.9999888642F, 0.9999894736F, 0.9999900577F, 0.9999906172F, - 0.9999911528F, 0.9999916651F, 0.9999921548F, 0.9999926227F, - 0.9999930693F, 0.9999934954F, 0.9999939015F, 0.9999942883F, - 0.9999946564F, 0.9999950064F, 0.9999953390F, 0.9999956547F, - 0.9999959541F, 0.9999962377F, 0.9999965062F, 0.9999967601F, - 0.9999969998F, 0.9999972260F, 0.9999974392F, 0.9999976399F, - 0.9999978285F, 0.9999980056F, 0.9999981716F, 0.9999983271F, - 0.9999984724F, 0.9999986081F, 0.9999987345F, 0.9999988521F, - 0.9999989613F, 0.9999990625F, 0.9999991562F, 0.9999992426F, - 0.9999993223F, 0.9999993954F, 0.9999994625F, 0.9999995239F, - 0.9999995798F, 0.9999996307F, 0.9999996768F, 0.9999997184F, - 0.9999997559F, 0.9999997895F, 0.9999998195F, 0.9999998462F, - 0.9999998698F, 0.9999998906F, 0.9999999088F, 0.9999999246F, - 0.9999999383F, 0.9999999500F, 0.9999999600F, 0.9999999684F, - 0.9999999754F, 0.9999999811F, 0.9999999858F, 0.9999999896F, - 0.9999999925F, 0.9999999948F, 0.9999999965F, 0.9999999978F, - 0.9999999986F, 0.9999999992F, 0.9999999996F, 0.9999999998F, - 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, -}; - -DECLARE_ALIGNED(16, static const float, vwin8192)[4096] = { - 0.0000000578F, 0.0000005198F, 0.0000014438F, 0.0000028299F, - 0.0000046780F, 0.0000069882F, 0.0000097604F, 0.0000129945F, - 0.0000166908F, 0.0000208490F, 0.0000254692F, 0.0000305515F, - 0.0000360958F, 0.0000421021F, 0.0000485704F, 0.0000555006F, - 0.0000628929F, 0.0000707472F, 0.0000790635F, 0.0000878417F, - 0.0000970820F, 0.0001067842F, 0.0001169483F, 0.0001275744F, - 0.0001386625F, 0.0001502126F, 0.0001622245F, 0.0001746984F, - 0.0001876343F, 0.0002010320F, 0.0002148917F, 0.0002292132F, - 0.0002439967F, 0.0002592421F, 0.0002749493F, 0.0002911184F, - 0.0003077493F, 0.0003248421F, 0.0003423967F, 0.0003604132F, - 0.0003788915F, 0.0003978316F, 0.0004172335F, 0.0004370971F, - 0.0004574226F, 0.0004782098F, 0.0004994587F, 0.0005211694F, - 0.0005433418F, 0.0005659759F, 0.0005890717F, 0.0006126292F, - 0.0006366484F, 0.0006611292F, 0.0006860716F, 0.0007114757F, - 0.0007373414F, 0.0007636687F, 0.0007904576F, 0.0008177080F, - 0.0008454200F, 0.0008735935F, 0.0009022285F, 0.0009313250F, - 0.0009608830F, 0.0009909025F, 0.0010213834F, 0.0010523257F, - 0.0010837295F, 0.0011155946F, 0.0011479211F, 0.0011807090F, - 0.0012139582F, 0.0012476687F, 0.0012818405F, 0.0013164736F, - 0.0013515679F, 0.0013871235F, 0.0014231402F, 0.0014596182F, - 0.0014965573F, 0.0015339576F, 0.0015718190F, 0.0016101415F, - 0.0016489251F, 0.0016881698F, 0.0017278754F, 0.0017680421F, - 0.0018086698F, 0.0018497584F, 0.0018913080F, 0.0019333185F, - 0.0019757898F, 0.0020187221F, 0.0020621151F, 0.0021059690F, - 0.0021502837F, 0.0021950591F, 0.0022402953F, 0.0022859921F, - 0.0023321497F, 0.0023787679F, 0.0024258467F, 0.0024733861F, - 0.0025213861F, 0.0025698466F, 0.0026187676F, 0.0026681491F, - 0.0027179911F, 0.0027682935F, 0.0028190562F, 0.0028702794F, - 0.0029219628F, 0.0029741066F, 0.0030267107F, 0.0030797749F, - 0.0031332994F, 0.0031872841F, 0.0032417289F, 0.0032966338F, - 0.0033519988F, 0.0034078238F, 0.0034641089F, 0.0035208539F, - 0.0035780589F, 0.0036357237F, 0.0036938485F, 0.0037524331F, - 0.0038114775F, 0.0038709817F, 0.0039309456F, 0.0039913692F, - 0.0040522524F, 0.0041135953F, 0.0041753978F, 0.0042376599F, - 0.0043003814F, 0.0043635624F, 0.0044272029F, 0.0044913028F, - 0.0045558620F, 0.0046208806F, 0.0046863585F, 0.0047522955F, - 0.0048186919F, 0.0048855473F, 0.0049528619F, 0.0050206356F, - 0.0050888684F, 0.0051575601F, 0.0052267108F, 0.0052963204F, - 0.0053663890F, 0.0054369163F, 0.0055079025F, 0.0055793474F, - 0.0056512510F, 0.0057236133F, 0.0057964342F, 0.0058697137F, - 0.0059434517F, 0.0060176482F, 0.0060923032F, 0.0061674166F, - 0.0062429883F, 0.0063190183F, 0.0063955066F, 0.0064724532F, - 0.0065498579F, 0.0066277207F, 0.0067060416F, 0.0067848205F, - 0.0068640575F, 0.0069437523F, 0.0070239051F, 0.0071045157F, - 0.0071855840F, 0.0072671102F, 0.0073490940F, 0.0074315355F, - 0.0075144345F, 0.0075977911F, 0.0076816052F, 0.0077658768F, - 0.0078506057F, 0.0079357920F, 0.0080214355F, 0.0081075363F, - 0.0081940943F, 0.0082811094F, 0.0083685816F, 0.0084565108F, - 0.0085448970F, 0.0086337401F, 0.0087230401F, 0.0088127969F, - 0.0089030104F, 0.0089936807F, 0.0090848076F, 0.0091763911F, - 0.0092684311F, 0.0093609276F, 0.0094538805F, 0.0095472898F, - 0.0096411554F, 0.0097354772F, 0.0098302552F, 0.0099254894F, - 0.0100211796F, 0.0101173259F, 0.0102139281F, 0.0103109863F, - 0.0104085002F, 0.0105064700F, 0.0106048955F, 0.0107037766F, - 0.0108031133F, 0.0109029056F, 0.0110031534F, 0.0111038565F, - 0.0112050151F, 0.0113066289F, 0.0114086980F, 0.0115112222F, - 0.0116142015F, 0.0117176359F, 0.0118215252F, 0.0119258695F, - 0.0120306686F, 0.0121359225F, 0.0122416312F, 0.0123477944F, - 0.0124544123F, 0.0125614847F, 0.0126690116F, 0.0127769928F, - 0.0128854284F, 0.0129943182F, 0.0131036623F, 0.0132134604F, - 0.0133237126F, 0.0134344188F, 0.0135455790F, 0.0136571929F, - 0.0137692607F, 0.0138817821F, 0.0139947572F, 0.0141081859F, - 0.0142220681F, 0.0143364037F, 0.0144511927F, 0.0145664350F, - 0.0146821304F, 0.0147982791F, 0.0149148808F, 0.0150319355F, - 0.0151494431F, 0.0152674036F, 0.0153858168F, 0.0155046828F, - 0.0156240014F, 0.0157437726F, 0.0158639962F, 0.0159846723F, - 0.0161058007F, 0.0162273814F, 0.0163494142F, 0.0164718991F, - 0.0165948361F, 0.0167182250F, 0.0168420658F, 0.0169663584F, - 0.0170911027F, 0.0172162987F, 0.0173419462F, 0.0174680452F, - 0.0175945956F, 0.0177215974F, 0.0178490504F, 0.0179769545F, - 0.0181053098F, 0.0182341160F, 0.0183633732F, 0.0184930812F, - 0.0186232399F, 0.0187538494F, 0.0188849094F, 0.0190164200F, - 0.0191483809F, 0.0192807923F, 0.0194136539F, 0.0195469656F, - 0.0196807275F, 0.0198149394F, 0.0199496012F, 0.0200847128F, - 0.0202202742F, 0.0203562853F, 0.0204927460F, 0.0206296561F, - 0.0207670157F, 0.0209048245F, 0.0210430826F, 0.0211817899F, - 0.0213209462F, 0.0214605515F, 0.0216006057F, 0.0217411086F, - 0.0218820603F, 0.0220234605F, 0.0221653093F, 0.0223076066F, - 0.0224503521F, 0.0225935459F, 0.0227371879F, 0.0228812779F, - 0.0230258160F, 0.0231708018F, 0.0233162355F, 0.0234621169F, - 0.0236084459F, 0.0237552224F, 0.0239024462F, 0.0240501175F, - 0.0241982359F, 0.0243468015F, 0.0244958141F, 0.0246452736F, - 0.0247951800F, 0.0249455331F, 0.0250963329F, 0.0252475792F, - 0.0253992720F, 0.0255514111F, 0.0257039965F, 0.0258570281F, - 0.0260105057F, 0.0261644293F, 0.0263187987F, 0.0264736139F, - 0.0266288747F, 0.0267845811F, 0.0269407330F, 0.0270973302F, - 0.0272543727F, 0.0274118604F, 0.0275697930F, 0.0277281707F, - 0.0278869932F, 0.0280462604F, 0.0282059723F, 0.0283661287F, - 0.0285267295F, 0.0286877747F, 0.0288492641F, 0.0290111976F, - 0.0291735751F, 0.0293363965F, 0.0294996617F, 0.0296633706F, - 0.0298275231F, 0.0299921190F, 0.0301571583F, 0.0303226409F, - 0.0304885667F, 0.0306549354F, 0.0308217472F, 0.0309890017F, - 0.0311566989F, 0.0313248388F, 0.0314934211F, 0.0316624459F, - 0.0318319128F, 0.0320018220F, 0.0321721732F, 0.0323429663F, - 0.0325142013F, 0.0326858779F, 0.0328579962F, 0.0330305559F, - 0.0332035570F, 0.0333769994F, 0.0335508829F, 0.0337252074F, - 0.0338999728F, 0.0340751790F, 0.0342508259F, 0.0344269134F, - 0.0346034412F, 0.0347804094F, 0.0349578178F, 0.0351356663F, - 0.0353139548F, 0.0354926831F, 0.0356718511F, 0.0358514588F, - 0.0360315059F, 0.0362119924F, 0.0363929182F, 0.0365742831F, - 0.0367560870F, 0.0369383297F, 0.0371210113F, 0.0373041315F, - 0.0374876902F, 0.0376716873F, 0.0378561226F, 0.0380409961F, - 0.0382263077F, 0.0384120571F, 0.0385982443F, 0.0387848691F, - 0.0389719315F, 0.0391594313F, 0.0393473683F, 0.0395357425F, - 0.0397245537F, 0.0399138017F, 0.0401034866F, 0.0402936080F, - 0.0404841660F, 0.0406751603F, 0.0408665909F, 0.0410584576F, - 0.0412507603F, 0.0414434988F, 0.0416366731F, 0.0418302829F, - 0.0420243282F, 0.0422188088F, 0.0424137246F, 0.0426090755F, - 0.0428048613F, 0.0430010819F, 0.0431977371F, 0.0433948269F, - 0.0435923511F, 0.0437903095F, 0.0439887020F, 0.0441875285F, - 0.0443867889F, 0.0445864830F, 0.0447866106F, 0.0449871717F, - 0.0451881661F, 0.0453895936F, 0.0455914542F, 0.0457937477F, - 0.0459964738F, 0.0461996326F, 0.0464032239F, 0.0466072475F, - 0.0468117032F, 0.0470165910F, 0.0472219107F, 0.0474276622F, - 0.0476338452F, 0.0478404597F, 0.0480475056F, 0.0482549827F, - 0.0484628907F, 0.0486712297F, 0.0488799994F, 0.0490891998F, - 0.0492988306F, 0.0495088917F, 0.0497193830F, 0.0499303043F, - 0.0501416554F, 0.0503534363F, 0.0505656468F, 0.0507782867F, - 0.0509913559F, 0.0512048542F, 0.0514187815F, 0.0516331376F, - 0.0518479225F, 0.0520631358F, 0.0522787775F, 0.0524948475F, - 0.0527113455F, 0.0529282715F, 0.0531456252F, 0.0533634066F, - 0.0535816154F, 0.0538002515F, 0.0540193148F, 0.0542388051F, - 0.0544587222F, 0.0546790660F, 0.0548998364F, 0.0551210331F, - 0.0553426561F, 0.0555647051F, 0.0557871801F, 0.0560100807F, - 0.0562334070F, 0.0564571587F, 0.0566813357F, 0.0569059378F, - 0.0571309649F, 0.0573564168F, 0.0575822933F, 0.0578085942F, - 0.0580353195F, 0.0582624689F, 0.0584900423F, 0.0587180396F, - 0.0589464605F, 0.0591753049F, 0.0594045726F, 0.0596342635F, - 0.0598643774F, 0.0600949141F, 0.0603258735F, 0.0605572555F, - 0.0607890597F, 0.0610212862F, 0.0612539346F, 0.0614870049F, - 0.0617204968F, 0.0619544103F, 0.0621887451F, 0.0624235010F, - 0.0626586780F, 0.0628942758F, 0.0631302942F, 0.0633667331F, - 0.0636035923F, 0.0638408717F, 0.0640785710F, 0.0643166901F, - 0.0645552288F, 0.0647941870F, 0.0650335645F, 0.0652733610F, - 0.0655135765F, 0.0657542108F, 0.0659952636F, 0.0662367348F, - 0.0664786242F, 0.0667209316F, 0.0669636570F, 0.0672068000F, - 0.0674503605F, 0.0676943384F, 0.0679387334F, 0.0681835454F, - 0.0684287742F, 0.0686744196F, 0.0689204814F, 0.0691669595F, - 0.0694138536F, 0.0696611637F, 0.0699088894F, 0.0701570307F, - 0.0704055873F, 0.0706545590F, 0.0709039458F, 0.0711537473F, - 0.0714039634F, 0.0716545939F, 0.0719056387F, 0.0721570975F, - 0.0724089702F, 0.0726612565F, 0.0729139563F, 0.0731670694F, - 0.0734205956F, 0.0736745347F, 0.0739288866F, 0.0741836510F, - 0.0744388277F, 0.0746944166F, 0.0749504175F, 0.0752068301F, - 0.0754636543F, 0.0757208899F, 0.0759785367F, 0.0762365946F, - 0.0764950632F, 0.0767539424F, 0.0770132320F, 0.0772729319F, - 0.0775330418F, 0.0777935616F, 0.0780544909F, 0.0783158298F, - 0.0785775778F, 0.0788397349F, 0.0791023009F, 0.0793652755F, - 0.0796286585F, 0.0798924498F, 0.0801566492F, 0.0804212564F, - 0.0806862712F, 0.0809516935F, 0.0812175231F, 0.0814837597F, - 0.0817504031F, 0.0820174532F, 0.0822849097F, 0.0825527724F, - 0.0828210412F, 0.0830897158F, 0.0833587960F, 0.0836282816F, - 0.0838981724F, 0.0841684682F, 0.0844391688F, 0.0847102740F, - 0.0849817835F, 0.0852536973F, 0.0855260150F, 0.0857987364F, - 0.0860718614F, 0.0863453897F, 0.0866193211F, 0.0868936554F, - 0.0871683924F, 0.0874435319F, 0.0877190737F, 0.0879950175F, - 0.0882713632F, 0.0885481105F, 0.0888252592F, 0.0891028091F, - 0.0893807600F, 0.0896591117F, 0.0899378639F, 0.0902170165F, - 0.0904965692F, 0.0907765218F, 0.0910568740F, 0.0913376258F, - 0.0916187767F, 0.0919003268F, 0.0921822756F, 0.0924646230F, - 0.0927473687F, 0.0930305126F, 0.0933140545F, 0.0935979940F, - 0.0938823310F, 0.0941670653F, 0.0944521966F, 0.0947377247F, - 0.0950236494F, 0.0953099704F, 0.0955966876F, 0.0958838007F, - 0.0961713094F, 0.0964592136F, 0.0967475131F, 0.0970362075F, - 0.0973252967F, 0.0976147805F, 0.0979046585F, 0.0981949307F, - 0.0984855967F, 0.0987766563F, 0.0990681093F, 0.0993599555F, - 0.0996521945F, 0.0999448263F, 0.1002378506F, 0.1005312671F, - 0.1008250755F, 0.1011192757F, 0.1014138675F, 0.1017088505F, - 0.1020042246F, 0.1022999895F, 0.1025961450F, 0.1028926909F, - 0.1031896268F, 0.1034869526F, 0.1037846680F, 0.1040827729F, - 0.1043812668F, 0.1046801497F, 0.1049794213F, 0.1052790813F, - 0.1055791294F, 0.1058795656F, 0.1061803894F, 0.1064816006F, - 0.1067831991F, 0.1070851846F, 0.1073875568F, 0.1076903155F, - 0.1079934604F, 0.1082969913F, 0.1086009079F, 0.1089052101F, - 0.1092098975F, 0.1095149699F, 0.1098204270F, 0.1101262687F, - 0.1104324946F, 0.1107391045F, 0.1110460982F, 0.1113534754F, - 0.1116612359F, 0.1119693793F, 0.1122779055F, 0.1125868142F, - 0.1128961052F, 0.1132057781F, 0.1135158328F, 0.1138262690F, - 0.1141370863F, 0.1144482847F, 0.1147598638F, 0.1150718233F, - 0.1153841631F, 0.1156968828F, 0.1160099822F, 0.1163234610F, - 0.1166373190F, 0.1169515559F, 0.1172661714F, 0.1175811654F, - 0.1178965374F, 0.1182122874F, 0.1185284149F, 0.1188449198F, - 0.1191618018F, 0.1194790606F, 0.1197966960F, 0.1201147076F, - 0.1204330953F, 0.1207518587F, 0.1210709976F, 0.1213905118F, - 0.1217104009F, 0.1220306647F, 0.1223513029F, 0.1226723153F, - 0.1229937016F, 0.1233154615F, 0.1236375948F, 0.1239601011F, - 0.1242829803F, 0.1246062319F, 0.1249298559F, 0.1252538518F, - 0.1255782195F, 0.1259029586F, 0.1262280689F, 0.1265535501F, - 0.1268794019F, 0.1272056241F, 0.1275322163F, 0.1278591784F, - 0.1281865099F, 0.1285142108F, 0.1288422805F, 0.1291707190F, - 0.1294995259F, 0.1298287009F, 0.1301582437F, 0.1304881542F, - 0.1308184319F, 0.1311490766F, 0.1314800881F, 0.1318114660F, - 0.1321432100F, 0.1324753200F, 0.1328077955F, 0.1331406364F, - 0.1334738422F, 0.1338074129F, 0.1341413479F, 0.1344756472F, - 0.1348103103F, 0.1351453370F, 0.1354807270F, 0.1358164801F, - 0.1361525959F, 0.1364890741F, 0.1368259145F, 0.1371631167F, - 0.1375006805F, 0.1378386056F, 0.1381768917F, 0.1385155384F, - 0.1388545456F, 0.1391939129F, 0.1395336400F, 0.1398737266F, - 0.1402141724F, 0.1405549772F, 0.1408961406F, 0.1412376623F, - 0.1415795421F, 0.1419217797F, 0.1422643746F, 0.1426073268F, - 0.1429506358F, 0.1432943013F, 0.1436383231F, 0.1439827008F, - 0.1443274342F, 0.1446725229F, 0.1450179667F, 0.1453637652F, - 0.1457099181F, 0.1460564252F, 0.1464032861F, 0.1467505006F, - 0.1470980682F, 0.1474459888F, 0.1477942620F, 0.1481428875F, - 0.1484918651F, 0.1488411942F, 0.1491908748F, 0.1495409065F, - 0.1498912889F, 0.1502420218F, 0.1505931048F, 0.1509445376F, - 0.1512963200F, 0.1516484516F, 0.1520009321F, 0.1523537612F, - 0.1527069385F, 0.1530604638F, 0.1534143368F, 0.1537685571F, - 0.1541231244F, 0.1544780384F, 0.1548332987F, 0.1551889052F, - 0.1555448574F, 0.1559011550F, 0.1562577978F, 0.1566147853F, - 0.1569721173F, 0.1573297935F, 0.1576878135F, 0.1580461771F, - 0.1584048838F, 0.1587639334F, 0.1591233255F, 0.1594830599F, - 0.1598431361F, 0.1602035540F, 0.1605643131F, 0.1609254131F, - 0.1612868537F, 0.1616486346F, 0.1620107555F, 0.1623732160F, - 0.1627360158F, 0.1630991545F, 0.1634626319F, 0.1638264476F, - 0.1641906013F, 0.1645550926F, 0.1649199212F, 0.1652850869F, - 0.1656505892F, 0.1660164278F, 0.1663826024F, 0.1667491127F, - 0.1671159583F, 0.1674831388F, 0.1678506541F, 0.1682185036F, - 0.1685866872F, 0.1689552044F, 0.1693240549F, 0.1696932384F, - 0.1700627545F, 0.1704326029F, 0.1708027833F, 0.1711732952F, - 0.1715441385F, 0.1719153127F, 0.1722868175F, 0.1726586526F, - 0.1730308176F, 0.1734033121F, 0.1737761359F, 0.1741492886F, - 0.1745227698F, 0.1748965792F, 0.1752707164F, 0.1756451812F, - 0.1760199731F, 0.1763950918F, 0.1767705370F, 0.1771463083F, - 0.1775224054F, 0.1778988279F, 0.1782755754F, 0.1786526477F, - 0.1790300444F, 0.1794077651F, 0.1797858094F, 0.1801641771F, - 0.1805428677F, 0.1809218810F, 0.1813012165F, 0.1816808739F, - 0.1820608528F, 0.1824411530F, 0.1828217739F, 0.1832027154F, - 0.1835839770F, 0.1839655584F, 0.1843474592F, 0.1847296790F, - 0.1851122175F, 0.1854950744F, 0.1858782492F, 0.1862617417F, - 0.1866455514F, 0.1870296780F, 0.1874141211F, 0.1877988804F, - 0.1881839555F, 0.1885693461F, 0.1889550517F, 0.1893410721F, - 0.1897274068F, 0.1901140555F, 0.1905010178F, 0.1908882933F, - 0.1912758818F, 0.1916637828F, 0.1920519959F, 0.1924405208F, - 0.1928293571F, 0.1932185044F, 0.1936079625F, 0.1939977308F, - 0.1943878091F, 0.1947781969F, 0.1951688939F, 0.1955598998F, - 0.1959512141F, 0.1963428364F, 0.1967347665F, 0.1971270038F, - 0.1975195482F, 0.1979123990F, 0.1983055561F, 0.1986990190F, - 0.1990927873F, 0.1994868607F, 0.1998812388F, 0.2002759212F, - 0.2006709075F, 0.2010661974F, 0.2014617904F, 0.2018576862F, - 0.2022538844F, 0.2026503847F, 0.2030471865F, 0.2034442897F, - 0.2038416937F, 0.2042393982F, 0.2046374028F, 0.2050357071F, - 0.2054343107F, 0.2058332133F, 0.2062324145F, 0.2066319138F, - 0.2070317110F, 0.2074318055F, 0.2078321970F, 0.2082328852F, - 0.2086338696F, 0.2090351498F, 0.2094367255F, 0.2098385962F, - 0.2102407617F, 0.2106432213F, 0.2110459749F, 0.2114490220F, - 0.2118523621F, 0.2122559950F, 0.2126599202F, 0.2130641373F, - 0.2134686459F, 0.2138734456F, 0.2142785361F, 0.2146839168F, - 0.2150895875F, 0.2154955478F, 0.2159017972F, 0.2163083353F, - 0.2167151617F, 0.2171222761F, 0.2175296780F, 0.2179373670F, - 0.2183453428F, 0.2187536049F, 0.2191621529F, 0.2195709864F, - 0.2199801051F, 0.2203895085F, 0.2207991961F, 0.2212091677F, - 0.2216194228F, 0.2220299610F, 0.2224407818F, 0.2228518850F, - 0.2232632699F, 0.2236749364F, 0.2240868839F, 0.2244991121F, - 0.2249116204F, 0.2253244086F, 0.2257374763F, 0.2261508229F, - 0.2265644481F, 0.2269783514F, 0.2273925326F, 0.2278069911F, - 0.2282217265F, 0.2286367384F, 0.2290520265F, 0.2294675902F, - 0.2298834292F, 0.2302995431F, 0.2307159314F, 0.2311325937F, - 0.2315495297F, 0.2319667388F, 0.2323842207F, 0.2328019749F, - 0.2332200011F, 0.2336382988F, 0.2340568675F, 0.2344757070F, - 0.2348948166F, 0.2353141961F, 0.2357338450F, 0.2361537629F, - 0.2365739493F, 0.2369944038F, 0.2374151261F, 0.2378361156F, - 0.2382573720F, 0.2386788948F, 0.2391006836F, 0.2395227380F, - 0.2399450575F, 0.2403676417F, 0.2407904902F, 0.2412136026F, - 0.2416369783F, 0.2420606171F, 0.2424845185F, 0.2429086820F, - 0.2433331072F, 0.2437577936F, 0.2441827409F, 0.2446079486F, - 0.2450334163F, 0.2454591435F, 0.2458851298F, 0.2463113747F, - 0.2467378779F, 0.2471646389F, 0.2475916573F, 0.2480189325F, - 0.2484464643F, 0.2488742521F, 0.2493022955F, 0.2497305940F, - 0.2501591473F, 0.2505879549F, 0.2510170163F, 0.2514463311F, - 0.2518758989F, 0.2523057193F, 0.2527357916F, 0.2531661157F, - 0.2535966909F, 0.2540275169F, 0.2544585931F, 0.2548899193F, - 0.2553214948F, 0.2557533193F, 0.2561853924F, 0.2566177135F, - 0.2570502822F, 0.2574830981F, 0.2579161608F, 0.2583494697F, - 0.2587830245F, 0.2592168246F, 0.2596508697F, 0.2600851593F, - 0.2605196929F, 0.2609544701F, 0.2613894904F, 0.2618247534F, - 0.2622602586F, 0.2626960055F, 0.2631319938F, 0.2635682230F, - 0.2640046925F, 0.2644414021F, 0.2648783511F, 0.2653155391F, - 0.2657529657F, 0.2661906305F, 0.2666285329F, 0.2670666725F, - 0.2675050489F, 0.2679436616F, 0.2683825101F, 0.2688215940F, - 0.2692609127F, 0.2697004660F, 0.2701402532F, 0.2705802739F, - 0.2710205278F, 0.2714610142F, 0.2719017327F, 0.2723426830F, - 0.2727838644F, 0.2732252766F, 0.2736669191F, 0.2741087914F, - 0.2745508930F, 0.2749932235F, 0.2754357824F, 0.2758785693F, - 0.2763215837F, 0.2767648251F, 0.2772082930F, 0.2776519870F, - 0.2780959066F, 0.2785400513F, 0.2789844207F, 0.2794290143F, - 0.2798738316F, 0.2803188722F, 0.2807641355F, 0.2812096211F, - 0.2816553286F, 0.2821012574F, 0.2825474071F, 0.2829937773F, - 0.2834403673F, 0.2838871768F, 0.2843342053F, 0.2847814523F, - 0.2852289174F, 0.2856765999F, 0.2861244996F, 0.2865726159F, - 0.2870209482F, 0.2874694962F, 0.2879182594F, 0.2883672372F, - 0.2888164293F, 0.2892658350F, 0.2897154540F, 0.2901652858F, - 0.2906153298F, 0.2910655856F, 0.2915160527F, 0.2919667306F, - 0.2924176189F, 0.2928687171F, 0.2933200246F, 0.2937715409F, - 0.2942232657F, 0.2946751984F, 0.2951273386F, 0.2955796856F, - 0.2960322391F, 0.2964849986F, 0.2969379636F, 0.2973911335F, - 0.2978445080F, 0.2982980864F, 0.2987518684F, 0.2992058534F, - 0.2996600409F, 0.3001144305F, 0.3005690217F, 0.3010238139F, - 0.3014788067F, 0.3019339995F, 0.3023893920F, 0.3028449835F, - 0.3033007736F, 0.3037567618F, 0.3042129477F, 0.3046693306F, - 0.3051259102F, 0.3055826859F, 0.3060396572F, 0.3064968236F, - 0.3069541847F, 0.3074117399F, 0.3078694887F, 0.3083274307F, - 0.3087855653F, 0.3092438920F, 0.3097024104F, 0.3101611199F, - 0.3106200200F, 0.3110791103F, 0.3115383902F, 0.3119978592F, - 0.3124575169F, 0.3129173627F, 0.3133773961F, 0.3138376166F, - 0.3142980238F, 0.3147586170F, 0.3152193959F, 0.3156803598F, - 0.3161415084F, 0.3166028410F, 0.3170643573F, 0.3175260566F, - 0.3179879384F, 0.3184500023F, 0.3189122478F, 0.3193746743F, - 0.3198372814F, 0.3203000685F, 0.3207630351F, 0.3212261807F, - 0.3216895048F, 0.3221530069F, 0.3226166865F, 0.3230805430F, - 0.3235445760F, 0.3240087849F, 0.3244731693F, 0.3249377285F, - 0.3254024622F, 0.3258673698F, 0.3263324507F, 0.3267977045F, - 0.3272631306F, 0.3277287286F, 0.3281944978F, 0.3286604379F, - 0.3291265482F, 0.3295928284F, 0.3300592777F, 0.3305258958F, - 0.3309926821F, 0.3314596361F, 0.3319267573F, 0.3323940451F, - 0.3328614990F, 0.3333291186F, 0.3337969033F, 0.3342648525F, - 0.3347329658F, 0.3352012427F, 0.3356696825F, 0.3361382849F, - 0.3366070492F, 0.3370759749F, 0.3375450616F, 0.3380143087F, - 0.3384837156F, 0.3389532819F, 0.3394230071F, 0.3398928905F, - 0.3403629317F, 0.3408331302F, 0.3413034854F, 0.3417739967F, - 0.3422446638F, 0.3427154860F, 0.3431864628F, 0.3436575938F, - 0.3441288782F, 0.3446003158F, 0.3450719058F, 0.3455436478F, - 0.3460155412F, 0.3464875856F, 0.3469597804F, 0.3474321250F, - 0.3479046189F, 0.3483772617F, 0.3488500527F, 0.3493229914F, - 0.3497960774F, 0.3502693100F, 0.3507426887F, 0.3512162131F, - 0.3516898825F, 0.3521636965F, 0.3526376545F, 0.3531117559F, - 0.3535860003F, 0.3540603870F, 0.3545349157F, 0.3550095856F, - 0.3554843964F, 0.3559593474F, 0.3564344381F, 0.3569096680F, - 0.3573850366F, 0.3578605432F, 0.3583361875F, 0.3588119687F, - 0.3592878865F, 0.3597639402F, 0.3602401293F, 0.3607164533F, - 0.3611929117F, 0.3616695038F, 0.3621462292F, 0.3626230873F, - 0.3631000776F, 0.3635771995F, 0.3640544525F, 0.3645318360F, - 0.3650093496F, 0.3654869926F, 0.3659647645F, 0.3664426648F, - 0.3669206930F, 0.3673988484F, 0.3678771306F, 0.3683555390F, - 0.3688340731F, 0.3693127322F, 0.3697915160F, 0.3702704237F, - 0.3707494549F, 0.3712286091F, 0.3717078857F, 0.3721872840F, - 0.3726668037F, 0.3731464441F, 0.3736262047F, 0.3741060850F, - 0.3745860843F, 0.3750662023F, 0.3755464382F, 0.3760267915F, - 0.3765072618F, 0.3769878484F, 0.3774685509F, 0.3779493686F, - 0.3784303010F, 0.3789113475F, 0.3793925076F, 0.3798737809F, - 0.3803551666F, 0.3808366642F, 0.3813182733F, 0.3817999932F, - 0.3822818234F, 0.3827637633F, 0.3832458124F, 0.3837279702F, - 0.3842102360F, 0.3846926093F, 0.3851750897F, 0.3856576764F, - 0.3861403690F, 0.3866231670F, 0.3871060696F, 0.3875890765F, - 0.3880721870F, 0.3885554007F, 0.3890387168F, 0.3895221349F, - 0.3900056544F, 0.3904892748F, 0.3909729955F, 0.3914568160F, - 0.3919407356F, 0.3924247539F, 0.3929088702F, 0.3933930841F, - 0.3938773949F, 0.3943618021F, 0.3948463052F, 0.3953309035F, - 0.3958155966F, 0.3963003838F, 0.3967852646F, 0.3972702385F, - 0.3977553048F, 0.3982404631F, 0.3987257127F, 0.3992110531F, - 0.3996964838F, 0.4001820041F, 0.4006676136F, 0.4011533116F, - 0.4016390976F, 0.4021249710F, 0.4026109313F, 0.4030969779F, - 0.4035831102F, 0.4040693277F, 0.4045556299F, 0.4050420160F, - 0.4055284857F, 0.4060150383F, 0.4065016732F, 0.4069883899F, - 0.4074751879F, 0.4079620665F, 0.4084490252F, 0.4089360635F, - 0.4094231807F, 0.4099103763F, 0.4103976498F, 0.4108850005F, - 0.4113724280F, 0.4118599315F, 0.4123475107F, 0.4128351648F, - 0.4133228934F, 0.4138106959F, 0.4142985716F, 0.4147865201F, - 0.4152745408F, 0.4157626330F, 0.4162507963F, 0.4167390301F, - 0.4172273337F, 0.4177157067F, 0.4182041484F, 0.4186926583F, - 0.4191812359F, 0.4196698805F, 0.4201585915F, 0.4206473685F, - 0.4211362108F, 0.4216251179F, 0.4221140892F, 0.4226031241F, - 0.4230922221F, 0.4235813826F, 0.4240706050F, 0.4245598887F, - 0.4250492332F, 0.4255386379F, 0.4260281022F, 0.4265176256F, - 0.4270072075F, 0.4274968473F, 0.4279865445F, 0.4284762984F, - 0.4289661086F, 0.4294559743F, 0.4299458951F, 0.4304358704F, - 0.4309258996F, 0.4314159822F, 0.4319061175F, 0.4323963050F, - 0.4328865441F, 0.4333768342F, 0.4338671749F, 0.4343575654F, - 0.4348480052F, 0.4353384938F, 0.4358290306F, 0.4363196149F, - 0.4368102463F, 0.4373009241F, 0.4377916478F, 0.4382824168F, - 0.4387732305F, 0.4392640884F, 0.4397549899F, 0.4402459343F, - 0.4407369212F, 0.4412279499F, 0.4417190198F, 0.4422101305F, - 0.4427012813F, 0.4431924717F, 0.4436837010F, 0.4441749686F, - 0.4446662742F, 0.4451576169F, 0.4456489963F, 0.4461404118F, - 0.4466318628F, 0.4471233487F, 0.4476148690F, 0.4481064230F, - 0.4485980103F, 0.4490896302F, 0.4495812821F, 0.4500729654F, - 0.4505646797F, 0.4510564243F, 0.4515481986F, 0.4520400021F, - 0.4525318341F, 0.4530236942F, 0.4535155816F, 0.4540074959F, - 0.4544994365F, 0.4549914028F, 0.4554833941F, 0.4559754100F, - 0.4564674499F, 0.4569595131F, 0.4574515991F, 0.4579437074F, - 0.4584358372F, 0.4589279881F, 0.4594201595F, 0.4599123508F, - 0.4604045615F, 0.4608967908F, 0.4613890383F, 0.4618813034F, - 0.4623735855F, 0.4628658841F, 0.4633581984F, 0.4638505281F, - 0.4643428724F, 0.4648352308F, 0.4653276028F, 0.4658199877F, - 0.4663123849F, 0.4668047940F, 0.4672972143F, 0.4677896451F, - 0.4682820861F, 0.4687745365F, 0.4692669958F, 0.4697594634F, - 0.4702519387F, 0.4707444211F, 0.4712369102F, 0.4717294052F, - 0.4722219056F, 0.4727144109F, 0.4732069204F, 0.4736994336F, - 0.4741919498F, 0.4746844686F, 0.4751769893F, 0.4756695113F, - 0.4761620341F, 0.4766545571F, 0.4771470797F, 0.4776396013F, - 0.4781321213F, 0.4786246392F, 0.4791171544F, 0.4796096663F, - 0.4801021744F, 0.4805946779F, 0.4810871765F, 0.4815796694F, - 0.4820721561F, 0.4825646360F, 0.4830571086F, 0.4835495732F, - 0.4840420293F, 0.4845344763F, 0.4850269136F, 0.4855193407F, - 0.4860117569F, 0.4865041617F, 0.4869965545F, 0.4874889347F, - 0.4879813018F, 0.4884736551F, 0.4889659941F, 0.4894583182F, - 0.4899506268F, 0.4904429193F, 0.4909351952F, 0.4914274538F, - 0.4919196947F, 0.4924119172F, 0.4929041207F, 0.4933963046F, - 0.4938884685F, 0.4943806116F, 0.4948727335F, 0.4953648335F, - 0.4958569110F, 0.4963489656F, 0.4968409965F, 0.4973330032F, - 0.4978249852F, 0.4983169419F, 0.4988088726F, 0.4993007768F, - 0.4997926539F, 0.5002845034F, 0.5007763247F, 0.5012681171F, - 0.5017598801F, 0.5022516132F, 0.5027433157F, 0.5032349871F, - 0.5037266268F, 0.5042182341F, 0.5047098086F, 0.5052013497F, - 0.5056928567F, 0.5061843292F, 0.5066757664F, 0.5071671679F, - 0.5076585330F, 0.5081498613F, 0.5086411520F, 0.5091324047F, - 0.5096236187F, 0.5101147934F, 0.5106059284F, 0.5110970230F, - 0.5115880766F, 0.5120790887F, 0.5125700587F, 0.5130609860F, - 0.5135518700F, 0.5140427102F, 0.5145335059F, 0.5150242566F, - 0.5155149618F, 0.5160056208F, 0.5164962331F, 0.5169867980F, - 0.5174773151F, 0.5179677837F, 0.5184582033F, 0.5189485733F, - 0.5194388931F, 0.5199291621F, 0.5204193798F, 0.5209095455F, - 0.5213996588F, 0.5218897190F, 0.5223797256F, 0.5228696779F, - 0.5233595755F, 0.5238494177F, 0.5243392039F, 0.5248289337F, - 0.5253186063F, 0.5258082213F, 0.5262977781F, 0.5267872760F, - 0.5272767146F, 0.5277660932F, 0.5282554112F, 0.5287446682F, - 0.5292338635F, 0.5297229965F, 0.5302120667F, 0.5307010736F, - 0.5311900164F, 0.5316788947F, 0.5321677079F, 0.5326564554F, - 0.5331451366F, 0.5336337511F, 0.5341222981F, 0.5346107771F, - 0.5350991876F, 0.5355875290F, 0.5360758007F, 0.5365640021F, - 0.5370521327F, 0.5375401920F, 0.5380281792F, 0.5385160939F, - 0.5390039355F, 0.5394917034F, 0.5399793971F, 0.5404670159F, - 0.5409545594F, 0.5414420269F, 0.5419294179F, 0.5424167318F, - 0.5429039680F, 0.5433911261F, 0.5438782053F, 0.5443652051F, - 0.5448521250F, 0.5453389644F, 0.5458257228F, 0.5463123995F, - 0.5467989940F, 0.5472855057F, 0.5477719341F, 0.5482582786F, - 0.5487445387F, 0.5492307137F, 0.5497168031F, 0.5502028063F, - 0.5506887228F, 0.5511745520F, 0.5516602934F, 0.5521459463F, - 0.5526315103F, 0.5531169847F, 0.5536023690F, 0.5540876626F, - 0.5545728649F, 0.5550579755F, 0.5555429937F, 0.5560279189F, - 0.5565127507F, 0.5569974884F, 0.5574821315F, 0.5579666794F, - 0.5584511316F, 0.5589354875F, 0.5594197465F, 0.5599039080F, - 0.5603879716F, 0.5608719367F, 0.5613558026F, 0.5618395689F, - 0.5623232350F, 0.5628068002F, 0.5632902642F, 0.5637736262F, - 0.5642568858F, 0.5647400423F, 0.5652230953F, 0.5657060442F, - 0.5661888883F, 0.5666716272F, 0.5671542603F, 0.5676367870F, - 0.5681192069F, 0.5686015192F, 0.5690837235F, 0.5695658192F, - 0.5700478058F, 0.5705296827F, 0.5710114494F, 0.5714931052F, - 0.5719746497F, 0.5724560822F, 0.5729374023F, 0.5734186094F, - 0.5738997029F, 0.5743806823F, 0.5748615470F, 0.5753422965F, - 0.5758229301F, 0.5763034475F, 0.5767838480F, 0.5772641310F, - 0.5777442960F, 0.5782243426F, 0.5787042700F, 0.5791840778F, - 0.5796637654F, 0.5801433322F, 0.5806227778F, 0.5811021016F, - 0.5815813029F, 0.5820603814F, 0.5825393363F, 0.5830181673F, - 0.5834968737F, 0.5839754549F, 0.5844539105F, 0.5849322399F, - 0.5854104425F, 0.5858885179F, 0.5863664653F, 0.5868442844F, - 0.5873219746F, 0.5877995353F, 0.5882769660F, 0.5887542661F, - 0.5892314351F, 0.5897084724F, 0.5901853776F, 0.5906621500F, - 0.5911387892F, 0.5916152945F, 0.5920916655F, 0.5925679016F, - 0.5930440022F, 0.5935199669F, 0.5939957950F, 0.5944714861F, - 0.5949470396F, 0.5954224550F, 0.5958977317F, 0.5963728692F, - 0.5968478669F, 0.5973227244F, 0.5977974411F, 0.5982720163F, - 0.5987464497F, 0.5992207407F, 0.5996948887F, 0.6001688932F, - 0.6006427537F, 0.6011164696F, 0.6015900405F, 0.6020634657F, - 0.6025367447F, 0.6030098770F, 0.6034828621F, 0.6039556995F, - 0.6044283885F, 0.6049009288F, 0.6053733196F, 0.6058455606F, - 0.6063176512F, 0.6067895909F, 0.6072613790F, 0.6077330152F, - 0.6082044989F, 0.6086758295F, 0.6091470065F, 0.6096180294F, - 0.6100888977F, 0.6105596108F, 0.6110301682F, 0.6115005694F, - 0.6119708139F, 0.6124409011F, 0.6129108305F, 0.6133806017F, - 0.6138502139F, 0.6143196669F, 0.6147889599F, 0.6152580926F, - 0.6157270643F, 0.6161958746F, 0.6166645230F, 0.6171330088F, - 0.6176013317F, 0.6180694910F, 0.6185374863F, 0.6190053171F, - 0.6194729827F, 0.6199404828F, 0.6204078167F, 0.6208749841F, - 0.6213419842F, 0.6218088168F, 0.6222754811F, 0.6227419768F, - 0.6232083032F, 0.6236744600F, 0.6241404465F, 0.6246062622F, - 0.6250719067F, 0.6255373795F, 0.6260026799F, 0.6264678076F, - 0.6269327619F, 0.6273975425F, 0.6278621487F, 0.6283265800F, - 0.6287908361F, 0.6292549163F, 0.6297188201F, 0.6301825471F, - 0.6306460966F, 0.6311094683F, 0.6315726617F, 0.6320356761F, - 0.6324985111F, 0.6329611662F, 0.6334236410F, 0.6338859348F, - 0.6343480472F, 0.6348099777F, 0.6352717257F, 0.6357332909F, - 0.6361946726F, 0.6366558704F, 0.6371168837F, 0.6375777122F, - 0.6380383552F, 0.6384988123F, 0.6389590830F, 0.6394191668F, - 0.6398790631F, 0.6403387716F, 0.6407982916F, 0.6412576228F, - 0.6417167645F, 0.6421757163F, 0.6426344778F, 0.6430930483F, - 0.6435514275F, 0.6440096149F, 0.6444676098F, 0.6449254119F, - 0.6453830207F, 0.6458404356F, 0.6462976562F, 0.6467546820F, - 0.6472115125F, 0.6476681472F, 0.6481245856F, 0.6485808273F, - 0.6490368717F, 0.6494927183F, 0.6499483667F, 0.6504038164F, - 0.6508590670F, 0.6513141178F, 0.6517689684F, 0.6522236185F, - 0.6526780673F, 0.6531323146F, 0.6535863598F, 0.6540402024F, - 0.6544938419F, 0.6549472779F, 0.6554005099F, 0.6558535373F, - 0.6563063598F, 0.6567589769F, 0.6572113880F, 0.6576635927F, - 0.6581155906F, 0.6585673810F, 0.6590189637F, 0.6594703380F, - 0.6599215035F, 0.6603724598F, 0.6608232064F, 0.6612737427F, - 0.6617240684F, 0.6621741829F, 0.6626240859F, 0.6630737767F, - 0.6635232550F, 0.6639725202F, 0.6644215720F, 0.6648704098F, - 0.6653190332F, 0.6657674417F, 0.6662156348F, 0.6666636121F, - 0.6671113731F, 0.6675589174F, 0.6680062445F, 0.6684533538F, - 0.6689002450F, 0.6693469177F, 0.6697933712F, 0.6702396052F, - 0.6706856193F, 0.6711314129F, 0.6715769855F, 0.6720223369F, - 0.6724674664F, 0.6729123736F, 0.6733570581F, 0.6738015194F, - 0.6742457570F, 0.6746897706F, 0.6751335596F, 0.6755771236F, - 0.6760204621F, 0.6764635747F, 0.6769064609F, 0.6773491204F, - 0.6777915525F, 0.6782337570F, 0.6786757332F, 0.6791174809F, - 0.6795589995F, 0.6800002886F, 0.6804413477F, 0.6808821765F, - 0.6813227743F, 0.6817631409F, 0.6822032758F, 0.6826431785F, - 0.6830828485F, 0.6835222855F, 0.6839614890F, 0.6844004585F, - 0.6848391936F, 0.6852776939F, 0.6857159589F, 0.6861539883F, - 0.6865917815F, 0.6870293381F, 0.6874666576F, 0.6879037398F, - 0.6883405840F, 0.6887771899F, 0.6892135571F, 0.6896496850F, - 0.6900855733F, 0.6905212216F, 0.6909566294F, 0.6913917963F, - 0.6918267218F, 0.6922614055F, 0.6926958471F, 0.6931300459F, - 0.6935640018F, 0.6939977141F, 0.6944311825F, 0.6948644066F, - 0.6952973859F, 0.6957301200F, 0.6961626085F, 0.6965948510F, - 0.6970268470F, 0.6974585961F, 0.6978900980F, 0.6983213521F, - 0.6987523580F, 0.6991831154F, 0.6996136238F, 0.7000438828F, - 0.7004738921F, 0.7009036510F, 0.7013331594F, 0.7017624166F, - 0.7021914224F, 0.7026201763F, 0.7030486779F, 0.7034769268F, - 0.7039049226F, 0.7043326648F, 0.7047601531F, 0.7051873870F, - 0.7056143662F, 0.7060410902F, 0.7064675586F, 0.7068937711F, - 0.7073197271F, 0.7077454264F, 0.7081708684F, 0.7085960529F, - 0.7090209793F, 0.7094456474F, 0.7098700566F, 0.7102942066F, - 0.7107180970F, 0.7111417274F, 0.7115650974F, 0.7119882066F, - 0.7124110545F, 0.7128336409F, 0.7132559653F, 0.7136780272F, - 0.7140998264F, 0.7145213624F, 0.7149426348F, 0.7153636433F, - 0.7157843874F, 0.7162048668F, 0.7166250810F, 0.7170450296F, - 0.7174647124F, 0.7178841289F, 0.7183032786F, 0.7187221613F, - 0.7191407765F, 0.7195591239F, 0.7199772030F, 0.7203950135F, - 0.7208125550F, 0.7212298271F, 0.7216468294F, 0.7220635616F, - 0.7224800233F, 0.7228962140F, 0.7233121335F, 0.7237277813F, - 0.7241431571F, 0.7245582604F, 0.7249730910F, 0.7253876484F, - 0.7258019322F, 0.7262159422F, 0.7266296778F, 0.7270431388F, - 0.7274563247F, 0.7278692353F, 0.7282818700F, 0.7286942287F, - 0.7291063108F, 0.7295181160F, 0.7299296440F, 0.7303408944F, - 0.7307518669F, 0.7311625609F, 0.7315729763F, 0.7319831126F, - 0.7323929695F, 0.7328025466F, 0.7332118435F, 0.7336208600F, - 0.7340295955F, 0.7344380499F, 0.7348462226F, 0.7352541134F, - 0.7356617220F, 0.7360690478F, 0.7364760907F, 0.7368828502F, - 0.7372893259F, 0.7376955176F, 0.7381014249F, 0.7385070475F, - 0.7389123849F, 0.7393174368F, 0.7397222029F, 0.7401266829F, - 0.7405308763F, 0.7409347829F, 0.7413384023F, 0.7417417341F, - 0.7421447780F, 0.7425475338F, 0.7429500009F, 0.7433521791F, - 0.7437540681F, 0.7441556674F, 0.7445569769F, 0.7449579960F, - 0.7453587245F, 0.7457591621F, 0.7461593084F, 0.7465591631F, - 0.7469587259F, 0.7473579963F, 0.7477569741F, 0.7481556590F, - 0.7485540506F, 0.7489521486F, 0.7493499526F, 0.7497474623F, - 0.7501446775F, 0.7505415977F, 0.7509382227F, 0.7513345521F, - 0.7517305856F, 0.7521263229F, 0.7525217636F, 0.7529169074F, - 0.7533117541F, 0.7537063032F, 0.7541005545F, 0.7544945076F, - 0.7548881623F, 0.7552815182F, 0.7556745749F, 0.7560673323F, - 0.7564597899F, 0.7568519474F, 0.7572438046F, 0.7576353611F, - 0.7580266166F, 0.7584175708F, 0.7588082235F, 0.7591985741F, - 0.7595886226F, 0.7599783685F, 0.7603678116F, 0.7607569515F, - 0.7611457879F, 0.7615343206F, 0.7619225493F, 0.7623104735F, - 0.7626980931F, 0.7630854078F, 0.7634724171F, 0.7638591209F, - 0.7642455188F, 0.7646316106F, 0.7650173959F, 0.7654028744F, - 0.7657880459F, 0.7661729100F, 0.7665574664F, 0.7669417150F, - 0.7673256553F, 0.7677092871F, 0.7680926100F, 0.7684756239F, - 0.7688583284F, 0.7692407232F, 0.7696228080F, 0.7700045826F, - 0.7703860467F, 0.7707671999F, 0.7711480420F, 0.7715285728F, - 0.7719087918F, 0.7722886989F, 0.7726682938F, 0.7730475762F, - 0.7734265458F, 0.7738052023F, 0.7741835454F, 0.7745615750F, - 0.7749392906F, 0.7753166921F, 0.7756937791F, 0.7760705514F, - 0.7764470087F, 0.7768231508F, 0.7771989773F, 0.7775744880F, - 0.7779496827F, 0.7783245610F, 0.7786991227F, 0.7790733676F, - 0.7794472953F, 0.7798209056F, 0.7801941982F, 0.7805671729F, - 0.7809398294F, 0.7813121675F, 0.7816841869F, 0.7820558873F, - 0.7824272684F, 0.7827983301F, 0.7831690720F, 0.7835394940F, - 0.7839095957F, 0.7842793768F, 0.7846488373F, 0.7850179767F, - 0.7853867948F, 0.7857552914F, 0.7861234663F, 0.7864913191F, - 0.7868588497F, 0.7872260578F, 0.7875929431F, 0.7879595055F, - 0.7883257445F, 0.7886916601F, 0.7890572520F, 0.7894225198F, - 0.7897874635F, 0.7901520827F, 0.7905163772F, 0.7908803468F, - 0.7912439912F, 0.7916073102F, 0.7919703035F, 0.7923329710F, - 0.7926953124F, 0.7930573274F, 0.7934190158F, 0.7937803774F, - 0.7941414120F, 0.7945021193F, 0.7948624991F, 0.7952225511F, - 0.7955822752F, 0.7959416711F, 0.7963007387F, 0.7966594775F, - 0.7970178875F, 0.7973759685F, 0.7977337201F, 0.7980911422F, - 0.7984482346F, 0.7988049970F, 0.7991614292F, 0.7995175310F, - 0.7998733022F, 0.8002287426F, 0.8005838519F, 0.8009386299F, - 0.8012930765F, 0.8016471914F, 0.8020009744F, 0.8023544253F, - 0.8027075438F, 0.8030603298F, 0.8034127831F, 0.8037649035F, - 0.8041166906F, 0.8044681445F, 0.8048192647F, 0.8051700512F, - 0.8055205038F, 0.8058706222F, 0.8062204062F, 0.8065698556F, - 0.8069189702F, 0.8072677499F, 0.8076161944F, 0.8079643036F, - 0.8083120772F, 0.8086595151F, 0.8090066170F, 0.8093533827F, - 0.8096998122F, 0.8100459051F, 0.8103916613F, 0.8107370806F, - 0.8110821628F, 0.8114269077F, 0.8117713151F, 0.8121153849F, - 0.8124591169F, 0.8128025108F, 0.8131455666F, 0.8134882839F, - 0.8138306627F, 0.8141727027F, 0.8145144038F, 0.8148557658F, - 0.8151967886F, 0.8155374718F, 0.8158778154F, 0.8162178192F, - 0.8165574830F, 0.8168968067F, 0.8172357900F, 0.8175744328F, - 0.8179127349F, 0.8182506962F, 0.8185883164F, 0.8189255955F, - 0.8192625332F, 0.8195991295F, 0.8199353840F, 0.8202712967F, - 0.8206068673F, 0.8209420958F, 0.8212769820F, 0.8216115256F, - 0.8219457266F, 0.8222795848F, 0.8226131000F, 0.8229462721F, - 0.8232791009F, 0.8236115863F, 0.8239437280F, 0.8242755260F, - 0.8246069801F, 0.8249380901F, 0.8252688559F, 0.8255992774F, - 0.8259293544F, 0.8262590867F, 0.8265884741F, 0.8269175167F, - 0.8272462141F, 0.8275745663F, 0.8279025732F, 0.8282302344F, - 0.8285575501F, 0.8288845199F, 0.8292111437F, 0.8295374215F, - 0.8298633530F, 0.8301889382F, 0.8305141768F, 0.8308390688F, - 0.8311636141F, 0.8314878124F, 0.8318116637F, 0.8321351678F, - 0.8324583246F, 0.8327811340F, 0.8331035957F, 0.8334257098F, - 0.8337474761F, 0.8340688944F, 0.8343899647F, 0.8347106867F, - 0.8350310605F, 0.8353510857F, 0.8356707624F, 0.8359900904F, - 0.8363090696F, 0.8366276999F, 0.8369459811F, 0.8372639131F, - 0.8375814958F, 0.8378987292F, 0.8382156130F, 0.8385321472F, - 0.8388483316F, 0.8391641662F, 0.8394796508F, 0.8397947853F, - 0.8401095697F, 0.8404240037F, 0.8407380873F, 0.8410518204F, - 0.8413652029F, 0.8416782347F, 0.8419909156F, 0.8423032456F, - 0.8426152245F, 0.8429268523F, 0.8432381289F, 0.8435490541F, - 0.8438596279F, 0.8441698502F, 0.8444797208F, 0.8447892396F, - 0.8450984067F, 0.8454072218F, 0.8457156849F, 0.8460237959F, - 0.8463315547F, 0.8466389612F, 0.8469460154F, 0.8472527170F, - 0.8475590661F, 0.8478650625F, 0.8481707063F, 0.8484759971F, - 0.8487809351F, 0.8490855201F, 0.8493897521F, 0.8496936308F, - 0.8499971564F, 0.8503003286F, 0.8506031474F, 0.8509056128F, - 0.8512077246F, 0.8515094828F, 0.8518108872F, 0.8521119379F, - 0.8524126348F, 0.8527129777F, 0.8530129666F, 0.8533126015F, - 0.8536118822F, 0.8539108087F, 0.8542093809F, 0.8545075988F, - 0.8548054623F, 0.8551029712F, 0.8554001257F, 0.8556969255F, - 0.8559933707F, 0.8562894611F, 0.8565851968F, 0.8568805775F, - 0.8571756034F, 0.8574702743F, 0.8577645902F, 0.8580585509F, - 0.8583521566F, 0.8586454070F, 0.8589383021F, 0.8592308420F, - 0.8595230265F, 0.8598148556F, 0.8601063292F, 0.8603974473F, - 0.8606882098F, 0.8609786167F, 0.8612686680F, 0.8615583636F, - 0.8618477034F, 0.8621366874F, 0.8624253156F, 0.8627135878F, - 0.8630015042F, 0.8632890646F, 0.8635762690F, 0.8638631173F, - 0.8641496096F, 0.8644357457F, 0.8647215257F, 0.8650069495F, - 0.8652920171F, 0.8655767283F, 0.8658610833F, 0.8661450820F, - 0.8664287243F, 0.8667120102F, 0.8669949397F, 0.8672775127F, - 0.8675597293F, 0.8678415894F, 0.8681230929F, 0.8684042398F, - 0.8686850302F, 0.8689654640F, 0.8692455412F, 0.8695252617F, - 0.8698046255F, 0.8700836327F, 0.8703622831F, 0.8706405768F, - 0.8709185138F, 0.8711960940F, 0.8714733174F, 0.8717501840F, - 0.8720266939F, 0.8723028469F, 0.8725786430F, 0.8728540824F, - 0.8731291648F, 0.8734038905F, 0.8736782592F, 0.8739522711F, - 0.8742259261F, 0.8744992242F, 0.8747721653F, 0.8750447496F, - 0.8753169770F, 0.8755888475F, 0.8758603611F, 0.8761315177F, - 0.8764023175F, 0.8766727603F, 0.8769428462F, 0.8772125752F, - 0.8774819474F, 0.8777509626F, 0.8780196209F, 0.8782879224F, - 0.8785558669F, 0.8788234546F, 0.8790906854F, 0.8793575594F, - 0.8796240765F, 0.8798902368F, 0.8801560403F, 0.8804214870F, - 0.8806865768F, 0.8809513099F, 0.8812156863F, 0.8814797059F, - 0.8817433687F, 0.8820066749F, 0.8822696243F, 0.8825322171F, - 0.8827944532F, 0.8830563327F, 0.8833178556F, 0.8835790219F, - 0.8838398316F, 0.8841002848F, 0.8843603815F, 0.8846201217F, - 0.8848795054F, 0.8851385327F, 0.8853972036F, 0.8856555182F, - 0.8859134764F, 0.8861710783F, 0.8864283239F, 0.8866852133F, - 0.8869417464F, 0.8871979234F, 0.8874537443F, 0.8877092090F, - 0.8879643177F, 0.8882190704F, 0.8884734671F, 0.8887275078F, - 0.8889811927F, 0.8892345216F, 0.8894874948F, 0.8897401122F, - 0.8899923738F, 0.8902442798F, 0.8904958301F, 0.8907470248F, - 0.8909978640F, 0.8912483477F, 0.8914984759F, 0.8917482487F, - 0.8919976662F, 0.8922467284F, 0.8924954353F, 0.8927437871F, - 0.8929917837F, 0.8932394252F, 0.8934867118F, 0.8937336433F, - 0.8939802199F, 0.8942264417F, 0.8944723087F, 0.8947178210F, - 0.8949629785F, 0.8952077815F, 0.8954522299F, 0.8956963239F, - 0.8959400634F, 0.8961834486F, 0.8964264795F, 0.8966691561F, - 0.8969114786F, 0.8971534470F, 0.8973950614F, 0.8976363219F, - 0.8978772284F, 0.8981177812F, 0.8983579802F, 0.8985978256F, - 0.8988373174F, 0.8990764556F, 0.8993152405F, 0.8995536720F, - 0.8997917502F, 0.9000294751F, 0.9002668470F, 0.9005038658F, - 0.9007405317F, 0.9009768446F, 0.9012128048F, 0.9014484123F, - 0.9016836671F, 0.9019185693F, 0.9021531191F, 0.9023873165F, - 0.9026211616F, 0.9028546546F, 0.9030877954F, 0.9033205841F, - 0.9035530210F, 0.9037851059F, 0.9040168392F, 0.9042482207F, - 0.9044792507F, 0.9047099293F, 0.9049402564F, 0.9051702323F, - 0.9053998569F, 0.9056291305F, 0.9058580531F, 0.9060866248F, - 0.9063148457F, 0.9065427159F, 0.9067702355F, 0.9069974046F, - 0.9072242233F, 0.9074506917F, 0.9076768100F, 0.9079025782F, - 0.9081279964F, 0.9083530647F, 0.9085777833F, 0.9088021523F, - 0.9090261717F, 0.9092498417F, 0.9094731623F, 0.9096961338F, - 0.9099187561F, 0.9101410295F, 0.9103629540F, 0.9105845297F, - 0.9108057568F, 0.9110266354F, 0.9112471656F, 0.9114673475F, - 0.9116871812F, 0.9119066668F, 0.9121258046F, 0.9123445945F, - 0.9125630367F, 0.9127811314F, 0.9129988786F, 0.9132162785F, - 0.9134333312F, 0.9136500368F, 0.9138663954F, 0.9140824073F, - 0.9142980724F, 0.9145133910F, 0.9147283632F, 0.9149429890F, - 0.9151572687F, 0.9153712023F, 0.9155847900F, 0.9157980319F, - 0.9160109282F, 0.9162234790F, 0.9164356844F, 0.9166475445F, - 0.9168590595F, 0.9170702296F, 0.9172810548F, 0.9174915354F, - 0.9177016714F, 0.9179114629F, 0.9181209102F, 0.9183300134F, - 0.9185387726F, 0.9187471879F, 0.9189552595F, 0.9191629876F, - 0.9193703723F, 0.9195774136F, 0.9197841119F, 0.9199904672F, - 0.9201964797F, 0.9204021495F, 0.9206074767F, 0.9208124616F, - 0.9210171043F, 0.9212214049F, 0.9214253636F, 0.9216289805F, - 0.9218322558F, 0.9220351896F, 0.9222377821F, 0.9224400335F, - 0.9226419439F, 0.9228435134F, 0.9230447423F, 0.9232456307F, - 0.9234461787F, 0.9236463865F, 0.9238462543F, 0.9240457822F, - 0.9242449704F, 0.9244438190F, 0.9246423282F, 0.9248404983F, - 0.9250383293F, 0.9252358214F, 0.9254329747F, 0.9256297896F, - 0.9258262660F, 0.9260224042F, 0.9262182044F, 0.9264136667F, - 0.9266087913F, 0.9268035783F, 0.9269980280F, 0.9271921405F, - 0.9273859160F, 0.9275793546F, 0.9277724566F, 0.9279652221F, - 0.9281576513F, 0.9283497443F, 0.9285415014F, 0.9287329227F, - 0.9289240084F, 0.9291147586F, 0.9293051737F, 0.9294952536F, - 0.9296849987F, 0.9298744091F, 0.9300634850F, 0.9302522266F, - 0.9304406340F, 0.9306287074F, 0.9308164471F, 0.9310038532F, - 0.9311909259F, 0.9313776654F, 0.9315640719F, 0.9317501455F, - 0.9319358865F, 0.9321212951F, 0.9323063713F, 0.9324911155F, - 0.9326755279F, 0.9328596085F, 0.9330433577F, 0.9332267756F, - 0.9334098623F, 0.9335926182F, 0.9337750434F, 0.9339571380F, - 0.9341389023F, 0.9343203366F, 0.9345014409F, 0.9346822155F, - 0.9348626606F, 0.9350427763F, 0.9352225630F, 0.9354020207F, - 0.9355811498F, 0.9357599503F, 0.9359384226F, 0.9361165667F, - 0.9362943830F, 0.9364718716F, 0.9366490327F, 0.9368258666F, - 0.9370023733F, 0.9371785533F, 0.9373544066F, 0.9375299335F, - 0.9377051341F, 0.9378800087F, 0.9380545576F, 0.9382287809F, - 0.9384026787F, 0.9385762515F, 0.9387494993F, 0.9389224223F, - 0.9390950209F, 0.9392672951F, 0.9394392453F, 0.9396108716F, - 0.9397821743F, 0.9399531536F, 0.9401238096F, 0.9402941427F, - 0.9404641530F, 0.9406338407F, 0.9408032061F, 0.9409722495F, - 0.9411409709F, 0.9413093707F, 0.9414774491F, 0.9416452062F, - 0.9418126424F, 0.9419797579F, 0.9421465528F, 0.9423130274F, - 0.9424791819F, 0.9426450166F, 0.9428105317F, 0.9429757274F, - 0.9431406039F, 0.9433051616F, 0.9434694005F, 0.9436333209F, - 0.9437969232F, 0.9439602074F, 0.9441231739F, 0.9442858229F, - 0.9444481545F, 0.9446101691F, 0.9447718669F, 0.9449332481F, - 0.9450943129F, 0.9452550617F, 0.9454154945F, 0.9455756118F, - 0.9457354136F, 0.9458949003F, 0.9460540721F, 0.9462129292F, - 0.9463714719F, 0.9465297003F, 0.9466876149F, 0.9468452157F, - 0.9470025031F, 0.9471594772F, 0.9473161384F, 0.9474724869F, - 0.9476285229F, 0.9477842466F, 0.9479396584F, 0.9480947585F, - 0.9482495470F, 0.9484040243F, 0.9485581906F, 0.9487120462F, - 0.9488655913F, 0.9490188262F, 0.9491717511F, 0.9493243662F, - 0.9494766718F, 0.9496286683F, 0.9497803557F, 0.9499317345F, - 0.9500828047F, 0.9502335668F, 0.9503840209F, 0.9505341673F, - 0.9506840062F, 0.9508335380F, 0.9509827629F, 0.9511316810F, - 0.9512802928F, 0.9514285984F, 0.9515765982F, 0.9517242923F, - 0.9518716810F, 0.9520187646F, 0.9521655434F, 0.9523120176F, - 0.9524581875F, 0.9526040534F, 0.9527496154F, 0.9528948739F, - 0.9530398292F, 0.9531844814F, 0.9533288310F, 0.9534728780F, - 0.9536166229F, 0.9537600659F, 0.9539032071F, 0.9540460470F, - 0.9541885858F, 0.9543308237F, 0.9544727611F, 0.9546143981F, - 0.9547557351F, 0.9548967723F, 0.9550375100F, 0.9551779485F, - 0.9553180881F, 0.9554579290F, 0.9555974714F, 0.9557367158F, - 0.9558756623F, 0.9560143112F, 0.9561526628F, 0.9562907174F, - 0.9564284752F, 0.9565659366F, 0.9567031017F, 0.9568399710F, - 0.9569765446F, 0.9571128229F, 0.9572488061F, 0.9573844944F, - 0.9575198883F, 0.9576549879F, 0.9577897936F, 0.9579243056F, - 0.9580585242F, 0.9581924497F, 0.9583260824F, 0.9584594226F, - 0.9585924705F, 0.9587252264F, 0.9588576906F, 0.9589898634F, - 0.9591217452F, 0.9592533360F, 0.9593846364F, 0.9595156465F, - 0.9596463666F, 0.9597767971F, 0.9599069382F, 0.9600367901F, - 0.9601663533F, 0.9602956279F, 0.9604246143F, 0.9605533128F, - 0.9606817236F, 0.9608098471F, 0.9609376835F, 0.9610652332F, - 0.9611924963F, 0.9613194733F, 0.9614461644F, 0.9615725699F, - 0.9616986901F, 0.9618245253F, 0.9619500757F, 0.9620753418F, - 0.9622003238F, 0.9623250219F, 0.9624494365F, 0.9625735679F, - 0.9626974163F, 0.9628209821F, 0.9629442656F, 0.9630672671F, - 0.9631899868F, 0.9633124251F, 0.9634345822F, 0.9635564585F, - 0.9636780543F, 0.9637993699F, 0.9639204056F, 0.9640411616F, - 0.9641616383F, 0.9642818359F, 0.9644017549F, 0.9645213955F, - 0.9646407579F, 0.9647598426F, 0.9648786497F, 0.9649971797F, - 0.9651154328F, 0.9652334092F, 0.9653511095F, 0.9654685337F, - 0.9655856823F, 0.9657025556F, 0.9658191538F, 0.9659354773F, - 0.9660515263F, 0.9661673013F, 0.9662828024F, 0.9663980300F, - 0.9665129845F, 0.9666276660F, 0.9667420750F, 0.9668562118F, - 0.9669700766F, 0.9670836698F, 0.9671969917F, 0.9673100425F, - 0.9674228227F, 0.9675353325F, 0.9676475722F, 0.9677595422F, - 0.9678712428F, 0.9679826742F, 0.9680938368F, 0.9682047309F, - 0.9683153569F, 0.9684257150F, 0.9685358056F, 0.9686456289F, - 0.9687551853F, 0.9688644752F, 0.9689734987F, 0.9690822564F, - 0.9691907483F, 0.9692989750F, 0.9694069367F, 0.9695146337F, - 0.9696220663F, 0.9697292349F, 0.9698361398F, 0.9699427813F, - 0.9700491597F, 0.9701552754F, 0.9702611286F, 0.9703667197F, - 0.9704720490F, 0.9705771169F, 0.9706819236F, 0.9707864695F, - 0.9708907549F, 0.9709947802F, 0.9710985456F, 0.9712020514F, - 0.9713052981F, 0.9714082859F, 0.9715110151F, 0.9716134862F, - 0.9717156993F, 0.9718176549F, 0.9719193532F, 0.9720207946F, - 0.9721219794F, 0.9722229080F, 0.9723235806F, 0.9724239976F, - 0.9725241593F, 0.9726240661F, 0.9727237183F, 0.9728231161F, - 0.9729222601F, 0.9730211503F, 0.9731197873F, 0.9732181713F, - 0.9733163027F, 0.9734141817F, 0.9735118088F, 0.9736091842F, - 0.9737063083F, 0.9738031814F, 0.9738998039F, 0.9739961760F, - 0.9740922981F, 0.9741881706F, 0.9742837938F, 0.9743791680F, - 0.9744742935F, 0.9745691707F, 0.9746637999F, 0.9747581814F, - 0.9748523157F, 0.9749462029F, 0.9750398435F, 0.9751332378F, - 0.9752263861F, 0.9753192887F, 0.9754119461F, 0.9755043585F, - 0.9755965262F, 0.9756884496F, 0.9757801291F, 0.9758715650F, - 0.9759627575F, 0.9760537071F, 0.9761444141F, 0.9762348789F, - 0.9763251016F, 0.9764150828F, 0.9765048228F, 0.9765943218F, - 0.9766835802F, 0.9767725984F, 0.9768613767F, 0.9769499154F, - 0.9770382149F, 0.9771262755F, 0.9772140976F, 0.9773016815F, - 0.9773890275F, 0.9774761360F, 0.9775630073F, 0.9776496418F, - 0.9777360398F, 0.9778222016F, 0.9779081277F, 0.9779938182F, - 0.9780792736F, 0.9781644943F, 0.9782494805F, 0.9783342326F, - 0.9784187509F, 0.9785030359F, 0.9785870877F, 0.9786709069F, - 0.9787544936F, 0.9788378484F, 0.9789209714F, 0.9790038631F, - 0.9790865238F, 0.9791689538F, 0.9792511535F, 0.9793331232F, - 0.9794148633F, 0.9794963742F, 0.9795776561F, 0.9796587094F, - 0.9797395345F, 0.9798201316F, 0.9799005013F, 0.9799806437F, - 0.9800605593F, 0.9801402483F, 0.9802197112F, 0.9802989483F, - 0.9803779600F, 0.9804567465F, 0.9805353082F, 0.9806136455F, - 0.9806917587F, 0.9807696482F, 0.9808473143F, 0.9809247574F, - 0.9810019778F, 0.9810789759F, 0.9811557519F, 0.9812323064F, - 0.9813086395F, 0.9813847517F, 0.9814606433F, 0.9815363147F, - 0.9816117662F, 0.9816869981F, 0.9817620108F, 0.9818368047F, - 0.9819113801F, 0.9819857374F, 0.9820598769F, 0.9821337989F, - 0.9822075038F, 0.9822809920F, 0.9823542638F, 0.9824273195F, - 0.9825001596F, 0.9825727843F, 0.9826451940F, 0.9827173891F, - 0.9827893700F, 0.9828611368F, 0.9829326901F, 0.9830040302F, - 0.9830751574F, 0.9831460720F, 0.9832167745F, 0.9832872652F, - 0.9833575444F, 0.9834276124F, 0.9834974697F, 0.9835671166F, - 0.9836365535F, 0.9837057806F, 0.9837747983F, 0.9838436071F, - 0.9839122072F, 0.9839805990F, 0.9840487829F, 0.9841167591F, - 0.9841845282F, 0.9842520903F, 0.9843194459F, 0.9843865953F, - 0.9844535389F, 0.9845202771F, 0.9845868101F, 0.9846531383F, - 0.9847192622F, 0.9847851820F, 0.9848508980F, 0.9849164108F, - 0.9849817205F, 0.9850468276F, 0.9851117324F, 0.9851764352F, - 0.9852409365F, 0.9853052366F, 0.9853693358F, 0.9854332344F, - 0.9854969330F, 0.9855604317F, 0.9856237309F, 0.9856868310F, - 0.9857497325F, 0.9858124355F, 0.9858749404F, 0.9859372477F, - 0.9859993577F, 0.9860612707F, 0.9861229871F, 0.9861845072F, - 0.9862458315F, 0.9863069601F, 0.9863678936F, 0.9864286322F, - 0.9864891764F, 0.9865495264F, 0.9866096826F, 0.9866696454F, - 0.9867294152F, 0.9867889922F, 0.9868483769F, 0.9869075695F, - 0.9869665706F, 0.9870253803F, 0.9870839991F, 0.9871424273F, - 0.9872006653F, 0.9872587135F, 0.9873165721F, 0.9873742415F, - 0.9874317222F, 0.9874890144F, 0.9875461185F, 0.9876030348F, - 0.9876597638F, 0.9877163057F, 0.9877726610F, 0.9878288300F, - 0.9878848130F, 0.9879406104F, 0.9879962225F, 0.9880516497F, - 0.9881068924F, 0.9881619509F, 0.9882168256F, 0.9882715168F, - 0.9883260249F, 0.9883803502F, 0.9884344931F, 0.9884884539F, - 0.9885422331F, 0.9885958309F, 0.9886492477F, 0.9887024838F, - 0.9887555397F, 0.9888084157F, 0.9888611120F, 0.9889136292F, - 0.9889659675F, 0.9890181273F, 0.9890701089F, 0.9891219128F, - 0.9891735392F, 0.9892249885F, 0.9892762610F, 0.9893273572F, - 0.9893782774F, 0.9894290219F, 0.9894795911F, 0.9895299853F, - 0.9895802049F, 0.9896302502F, 0.9896801217F, 0.9897298196F, - 0.9897793443F, 0.9898286961F, 0.9898778755F, 0.9899268828F, - 0.9899757183F, 0.9900243823F, 0.9900728753F, 0.9901211976F, - 0.9901693495F, 0.9902173314F, 0.9902651436F, 0.9903127865F, - 0.9903602605F, 0.9904075659F, 0.9904547031F, 0.9905016723F, - 0.9905484740F, 0.9905951086F, 0.9906415763F, 0.9906878775F, - 0.9907340126F, 0.9907799819F, 0.9908257858F, 0.9908714247F, - 0.9909168988F, 0.9909622086F, 0.9910073543F, 0.9910523364F, - 0.9910971552F, 0.9911418110F, 0.9911863042F, 0.9912306351F, - 0.9912748042F, 0.9913188117F, 0.9913626580F, 0.9914063435F, - 0.9914498684F, 0.9914932333F, 0.9915364383F, 0.9915794839F, - 0.9916223703F, 0.9916650981F, 0.9917076674F, 0.9917500787F, - 0.9917923323F, 0.9918344286F, 0.9918763679F, 0.9919181505F, - 0.9919597769F, 0.9920012473F, 0.9920425621F, 0.9920837217F, - 0.9921247263F, 0.9921655765F, 0.9922062724F, 0.9922468145F, - 0.9922872030F, 0.9923274385F, 0.9923675211F, 0.9924074513F, - 0.9924472294F, 0.9924868557F, 0.9925263306F, 0.9925656544F, - 0.9926048275F, 0.9926438503F, 0.9926827230F, 0.9927214461F, - 0.9927600199F, 0.9927984446F, 0.9928367208F, 0.9928748486F, - 0.9929128285F, 0.9929506608F, 0.9929883459F, 0.9930258841F, - 0.9930632757F, 0.9931005211F, 0.9931376207F, 0.9931745747F, - 0.9932113836F, 0.9932480476F, 0.9932845671F, 0.9933209425F, - 0.9933571742F, 0.9933932623F, 0.9934292074F, 0.9934650097F, - 0.9935006696F, 0.9935361874F, 0.9935715635F, 0.9936067982F, - 0.9936418919F, 0.9936768448F, 0.9937116574F, 0.9937463300F, - 0.9937808629F, 0.9938152565F, 0.9938495111F, 0.9938836271F, - 0.9939176047F, 0.9939514444F, 0.9939851465F, 0.9940187112F, - 0.9940521391F, 0.9940854303F, 0.9941185853F, 0.9941516044F, - 0.9941844879F, 0.9942172361F, 0.9942498495F, 0.9942823283F, - 0.9943146729F, 0.9943468836F, 0.9943789608F, 0.9944109047F, - 0.9944427158F, 0.9944743944F, 0.9945059408F, 0.9945373553F, - 0.9945686384F, 0.9945997902F, 0.9946308112F, 0.9946617017F, - 0.9946924621F, 0.9947230926F, 0.9947535937F, 0.9947839656F, - 0.9948142086F, 0.9948443232F, 0.9948743097F, 0.9949041683F, - 0.9949338995F, 0.9949635035F, 0.9949929807F, 0.9950223315F, - 0.9950515561F, 0.9950806549F, 0.9951096282F, 0.9951384764F, - 0.9951671998F, 0.9951957987F, 0.9952242735F, 0.9952526245F, - 0.9952808520F, 0.9953089564F, 0.9953369380F, 0.9953647971F, - 0.9953925340F, 0.9954201491F, 0.9954476428F, 0.9954750153F, - 0.9955022670F, 0.9955293981F, 0.9955564092F, 0.9955833003F, - 0.9956100720F, 0.9956367245F, 0.9956632582F, 0.9956896733F, - 0.9957159703F, 0.9957421494F, 0.9957682110F, 0.9957941553F, - 0.9958199828F, 0.9958456937F, 0.9958712884F, 0.9958967672F, - 0.9959221305F, 0.9959473784F, 0.9959725115F, 0.9959975300F, - 0.9960224342F, 0.9960472244F, 0.9960719011F, 0.9960964644F, - 0.9961209148F, 0.9961452525F, 0.9961694779F, 0.9961935913F, - 0.9962175930F, 0.9962414834F, 0.9962652627F, 0.9962889313F, - 0.9963124895F, 0.9963359377F, 0.9963592761F, 0.9963825051F, - 0.9964056250F, 0.9964286361F, 0.9964515387F, 0.9964743332F, - 0.9964970198F, 0.9965195990F, 0.9965420709F, 0.9965644360F, - 0.9965866946F, 0.9966088469F, 0.9966308932F, 0.9966528340F, - 0.9966746695F, 0.9966964001F, 0.9967180260F, 0.9967395475F, - 0.9967609651F, 0.9967822789F, 0.9968034894F, 0.9968245968F, - 0.9968456014F, 0.9968665036F, 0.9968873037F, 0.9969080019F, - 0.9969285987F, 0.9969490942F, 0.9969694889F, 0.9969897830F, - 0.9970099769F, 0.9970300708F, 0.9970500651F, 0.9970699601F, - 0.9970897561F, 0.9971094533F, 0.9971290522F, 0.9971485531F, - 0.9971679561F, 0.9971872617F, 0.9972064702F, 0.9972255818F, - 0.9972445968F, 0.9972635157F, 0.9972823386F, 0.9973010659F, - 0.9973196980F, 0.9973382350F, 0.9973566773F, 0.9973750253F, - 0.9973932791F, 0.9974114392F, 0.9974295059F, 0.9974474793F, - 0.9974653599F, 0.9974831480F, 0.9975008438F, 0.9975184476F, - 0.9975359598F, 0.9975533806F, 0.9975707104F, 0.9975879495F, - 0.9976050981F, 0.9976221566F, 0.9976391252F, 0.9976560043F, - 0.9976727941F, 0.9976894950F, 0.9977061073F, 0.9977226312F, - 0.9977390671F, 0.9977554152F, 0.9977716759F, 0.9977878495F, - 0.9978039361F, 0.9978199363F, 0.9978358501F, 0.9978516780F, - 0.9978674202F, 0.9978830771F, 0.9978986488F, 0.9979141358F, - 0.9979295383F, 0.9979448566F, 0.9979600909F, 0.9979752417F, - 0.9979903091F, 0.9980052936F, 0.9980201952F, 0.9980350145F, - 0.9980497515F, 0.9980644067F, 0.9980789804F, 0.9980934727F, - 0.9981078841F, 0.9981222147F, 0.9981364649F, 0.9981506350F, - 0.9981647253F, 0.9981787360F, 0.9981926674F, 0.9982065199F, - 0.9982202936F, 0.9982339890F, 0.9982476062F, 0.9982611456F, - 0.9982746074F, 0.9982879920F, 0.9983012996F, 0.9983145304F, - 0.9983276849F, 0.9983407632F, 0.9983537657F, 0.9983666926F, - 0.9983795442F, 0.9983923208F, 0.9984050226F, 0.9984176501F, - 0.9984302033F, 0.9984426827F, 0.9984550884F, 0.9984674208F, - 0.9984796802F, 0.9984918667F, 0.9985039808F, 0.9985160227F, - 0.9985279926F, 0.9985398909F, 0.9985517177F, 0.9985634734F, - 0.9985751583F, 0.9985867727F, 0.9985983167F, 0.9986097907F, - 0.9986211949F, 0.9986325297F, 0.9986437953F, 0.9986549919F, - 0.9986661199F, 0.9986771795F, 0.9986881710F, 0.9986990946F, - 0.9987099507F, 0.9987207394F, 0.9987314611F, 0.9987421161F, - 0.9987527045F, 0.9987632267F, 0.9987736829F, 0.9987840734F, - 0.9987943985F, 0.9988046584F, 0.9988148534F, 0.9988249838F, - 0.9988350498F, 0.9988450516F, 0.9988549897F, 0.9988648641F, - 0.9988746753F, 0.9988844233F, 0.9988941086F, 0.9989037313F, - 0.9989132918F, 0.9989227902F, 0.9989322269F, 0.9989416021F, - 0.9989509160F, 0.9989601690F, 0.9989693613F, 0.9989784931F, - 0.9989875647F, 0.9989965763F, 0.9990055283F, 0.9990144208F, - 0.9990232541F, 0.9990320286F, 0.9990407443F, 0.9990494016F, - 0.9990580008F, 0.9990665421F, 0.9990750257F, 0.9990834519F, - 0.9990918209F, 0.9991001331F, 0.9991083886F, 0.9991165877F, - 0.9991247307F, 0.9991328177F, 0.9991408491F, 0.9991488251F, - 0.9991567460F, 0.9991646119F, 0.9991724232F, 0.9991801801F, - 0.9991878828F, 0.9991955316F, 0.9992031267F, 0.9992106684F, - 0.9992181569F, 0.9992255925F, 0.9992329753F, 0.9992403057F, - 0.9992475839F, 0.9992548101F, 0.9992619846F, 0.9992691076F, - 0.9992761793F, 0.9992832001F, 0.9992901701F, 0.9992970895F, - 0.9993039587F, 0.9993107777F, 0.9993175470F, 0.9993242667F, - 0.9993309371F, 0.9993375583F, 0.9993441307F, 0.9993506545F, - 0.9993571298F, 0.9993635570F, 0.9993699362F, 0.9993762678F, - 0.9993825519F, 0.9993887887F, 0.9993949785F, 0.9994011216F, - 0.9994072181F, 0.9994132683F, 0.9994192725F, 0.9994252307F, - 0.9994311434F, 0.9994370107F, 0.9994428327F, 0.9994486099F, - 0.9994543423F, 0.9994600303F, 0.9994656739F, 0.9994712736F, - 0.9994768294F, 0.9994823417F, 0.9994878105F, 0.9994932363F, - 0.9994986191F, 0.9995039592F, 0.9995092568F, 0.9995145122F, - 0.9995197256F, 0.9995248971F, 0.9995300270F, 0.9995351156F, - 0.9995401630F, 0.9995451695F, 0.9995501352F, 0.9995550604F, - 0.9995599454F, 0.9995647903F, 0.9995695953F, 0.9995743607F, - 0.9995790866F, 0.9995837734F, 0.9995884211F, 0.9995930300F, - 0.9995976004F, 0.9996021324F, 0.9996066263F, 0.9996110822F, - 0.9996155004F, 0.9996198810F, 0.9996242244F, 0.9996285306F, - 0.9996327999F, 0.9996370326F, 0.9996412287F, 0.9996453886F, - 0.9996495125F, 0.9996536004F, 0.9996576527F, 0.9996616696F, - 0.9996656512F, 0.9996695977F, 0.9996735094F, 0.9996773865F, - 0.9996812291F, 0.9996850374F, 0.9996888118F, 0.9996925523F, - 0.9996962591F, 0.9996999325F, 0.9997035727F, 0.9997071798F, - 0.9997107541F, 0.9997142957F, 0.9997178049F, 0.9997212818F, - 0.9997247266F, 0.9997281396F, 0.9997315209F, 0.9997348708F, - 0.9997381893F, 0.9997414767F, 0.9997447333F, 0.9997479591F, - 0.9997511544F, 0.9997543194F, 0.9997574542F, 0.9997605591F, - 0.9997636342F, 0.9997666797F, 0.9997696958F, 0.9997726828F, - 0.9997756407F, 0.9997785698F, 0.9997814703F, 0.9997843423F, - 0.9997871860F, 0.9997900016F, 0.9997927894F, 0.9997955494F, - 0.9997982818F, 0.9998009869F, 0.9998036648F, 0.9998063157F, - 0.9998089398F, 0.9998115373F, 0.9998141082F, 0.9998166529F, - 0.9998191715F, 0.9998216642F, 0.9998241311F, 0.9998265724F, - 0.9998289884F, 0.9998313790F, 0.9998337447F, 0.9998360854F, - 0.9998384015F, 0.9998406930F, 0.9998429602F, 0.9998452031F, - 0.9998474221F, 0.9998496171F, 0.9998517885F, 0.9998539364F, - 0.9998560610F, 0.9998581624F, 0.9998602407F, 0.9998622962F, - 0.9998643291F, 0.9998663394F, 0.9998683274F, 0.9998702932F, - 0.9998722370F, 0.9998741589F, 0.9998760591F, 0.9998779378F, - 0.9998797952F, 0.9998816313F, 0.9998834464F, 0.9998852406F, - 0.9998870141F, 0.9998887670F, 0.9998904995F, 0.9998922117F, - 0.9998939039F, 0.9998955761F, 0.9998972285F, 0.9998988613F, - 0.9999004746F, 0.9999020686F, 0.9999036434F, 0.9999051992F, - 0.9999067362F, 0.9999082544F, 0.9999097541F, 0.9999112354F, - 0.9999126984F, 0.9999141433F, 0.9999155703F, 0.9999169794F, - 0.9999183709F, 0.9999197449F, 0.9999211014F, 0.9999224408F, - 0.9999237631F, 0.9999250684F, 0.9999263570F, 0.9999276289F, - 0.9999288843F, 0.9999301233F, 0.9999313461F, 0.9999325529F, - 0.9999337437F, 0.9999349187F, 0.9999360780F, 0.9999372218F, - 0.9999383503F, 0.9999394635F, 0.9999405616F, 0.9999416447F, - 0.9999427129F, 0.9999437665F, 0.9999448055F, 0.9999458301F, - 0.9999468404F, 0.9999478365F, 0.9999488185F, 0.9999497867F, - 0.9999507411F, 0.9999516819F, 0.9999526091F, 0.9999535230F, - 0.9999544236F, 0.9999553111F, 0.9999561856F, 0.9999570472F, - 0.9999578960F, 0.9999587323F, 0.9999595560F, 0.9999603674F, - 0.9999611666F, 0.9999619536F, 0.9999627286F, 0.9999634917F, - 0.9999642431F, 0.9999649828F, 0.9999657110F, 0.9999664278F, - 0.9999671334F, 0.9999678278F, 0.9999685111F, 0.9999691835F, - 0.9999698451F, 0.9999704960F, 0.9999711364F, 0.9999717662F, - 0.9999723858F, 0.9999729950F, 0.9999735942F, 0.9999741834F, - 0.9999747626F, 0.9999753321F, 0.9999758919F, 0.9999764421F, - 0.9999769828F, 0.9999775143F, 0.9999780364F, 0.9999785495F, - 0.9999790535F, 0.9999795485F, 0.9999800348F, 0.9999805124F, - 0.9999809813F, 0.9999814417F, 0.9999818938F, 0.9999823375F, - 0.9999827731F, 0.9999832005F, 0.9999836200F, 0.9999840316F, - 0.9999844353F, 0.9999848314F, 0.9999852199F, 0.9999856008F, - 0.9999859744F, 0.9999863407F, 0.9999866997F, 0.9999870516F, - 0.9999873965F, 0.9999877345F, 0.9999880656F, 0.9999883900F, - 0.9999887078F, 0.9999890190F, 0.9999893237F, 0.9999896220F, - 0.9999899140F, 0.9999901999F, 0.9999904796F, 0.9999907533F, - 0.9999910211F, 0.9999912830F, 0.9999915391F, 0.9999917896F, - 0.9999920345F, 0.9999922738F, 0.9999925077F, 0.9999927363F, - 0.9999929596F, 0.9999931777F, 0.9999933907F, 0.9999935987F, - 0.9999938018F, 0.9999940000F, 0.9999941934F, 0.9999943820F, - 0.9999945661F, 0.9999947456F, 0.9999949206F, 0.9999950912F, - 0.9999952575F, 0.9999954195F, 0.9999955773F, 0.9999957311F, - 0.9999958807F, 0.9999960265F, 0.9999961683F, 0.9999963063F, - 0.9999964405F, 0.9999965710F, 0.9999966979F, 0.9999968213F, - 0.9999969412F, 0.9999970576F, 0.9999971707F, 0.9999972805F, - 0.9999973871F, 0.9999974905F, 0.9999975909F, 0.9999976881F, - 0.9999977824F, 0.9999978738F, 0.9999979624F, 0.9999980481F, - 0.9999981311F, 0.9999982115F, 0.9999982892F, 0.9999983644F, - 0.9999984370F, 0.9999985072F, 0.9999985750F, 0.9999986405F, - 0.9999987037F, 0.9999987647F, 0.9999988235F, 0.9999988802F, - 0.9999989348F, 0.9999989873F, 0.9999990379F, 0.9999990866F, - 0.9999991334F, 0.9999991784F, 0.9999992217F, 0.9999992632F, - 0.9999993030F, 0.9999993411F, 0.9999993777F, 0.9999994128F, - 0.9999994463F, 0.9999994784F, 0.9999995091F, 0.9999995384F, - 0.9999995663F, 0.9999995930F, 0.9999996184F, 0.9999996426F, - 0.9999996657F, 0.9999996876F, 0.9999997084F, 0.9999997282F, - 0.9999997469F, 0.9999997647F, 0.9999997815F, 0.9999997973F, - 0.9999998123F, 0.9999998265F, 0.9999998398F, 0.9999998524F, - 0.9999998642F, 0.9999998753F, 0.9999998857F, 0.9999998954F, - 0.9999999045F, 0.9999999130F, 0.9999999209F, 0.9999999282F, - 0.9999999351F, 0.9999999414F, 0.9999999472F, 0.9999999526F, - 0.9999999576F, 0.9999999622F, 0.9999999664F, 0.9999999702F, - 0.9999999737F, 0.9999999769F, 0.9999999798F, 0.9999999824F, - 0.9999999847F, 0.9999999868F, 0.9999999887F, 0.9999999904F, - 0.9999999919F, 0.9999999932F, 0.9999999943F, 0.9999999953F, - 0.9999999961F, 0.9999999969F, 0.9999999975F, 0.9999999980F, - 0.9999999985F, 0.9999999988F, 0.9999999991F, 0.9999999993F, - 0.9999999995F, 0.9999999997F, 0.9999999998F, 0.9999999999F, - 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, - 1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F, -}; - -const float ff_vorbis_floor1_inverse_db_table[256]={ - 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, - 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, - 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, - 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, - 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, - 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, - 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, - 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, - 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, - 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, - 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, - 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, - 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, - 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, - 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, - 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, - 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, - 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, - 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, - 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, - 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, - 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, - 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, - 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, - 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, - 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, - 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, - 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, - 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, - 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, - 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, - 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, - 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, - 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, - 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, - 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, - 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, - 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, - 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, - 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, - 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, - 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, - 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, - 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, - 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, - 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, - 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, - 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, - 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, - 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, - 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, - 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, - 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, - 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, - 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, - 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, - 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, - 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, - 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, - 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, - 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, - 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, - 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, - 0.82788260F, 0.88168307F, 0.9389798F, 1.F, -}; - -const float * const ff_vorbis_vwin[8] = { - vwin64, vwin128, vwin256, vwin512, - vwin1024, vwin2048, vwin4096, vwin8192 -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vorbis_dec.c b/tizen/distrib/ffmpeg/libavcodec/vorbis_dec.c deleted file mode 100644 index 8c56400..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vorbis_dec.c +++ /dev/null @@ -1,1658 +0,0 @@ -/** - * @file - * Vorbis I decoder - * @author Denes Balatoni ( dbalatoni programozo hu ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#undef V_DEBUG -//#define V_DEBUG -//#define AV_DEBUG(...) av_log(NULL, AV_LOG_INFO, __VA_ARGS__) - -#include - -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "fft.h" - -#include "vorbis.h" -#include "xiph.h" - -#define V_NB_BITS 8 -#define V_NB_BITS2 11 -#define V_MAX_VLCS (1 << 16) -#define V_MAX_PARTITIONS (1 << 20) - -#ifndef V_DEBUG -#define AV_DEBUG(...) -#endif - -#undef NDEBUG -#include - -typedef struct { - uint_fast8_t dimensions; - uint_fast8_t lookup_type; - uint_fast8_t maxdepth; - VLC vlc; - float *codevectors; - unsigned int nb_bits; -} vorbis_codebook; - -typedef union vorbis_floor_u vorbis_floor_data; -typedef struct vorbis_floor0_s vorbis_floor0; -typedef struct vorbis_floor1_s vorbis_floor1; -struct vorbis_context_s; -typedef -uint_fast8_t (* vorbis_floor_decode_func) - (struct vorbis_context_s *, vorbis_floor_data *, float *); -typedef struct { - uint_fast8_t floor_type; - vorbis_floor_decode_func decode; - union vorbis_floor_u { - struct vorbis_floor0_s { - uint_fast8_t order; - uint_fast16_t rate; - uint_fast16_t bark_map_size; - int_fast32_t *map[2]; - uint_fast32_t map_size[2]; - uint_fast8_t amplitude_bits; - uint_fast8_t amplitude_offset; - uint_fast8_t num_books; - uint_fast8_t *book_list; - float *lsp; - } t0; - struct vorbis_floor1_s { - uint_fast8_t partitions; - uint_fast8_t maximum_class; - uint_fast8_t partition_class[32]; - uint_fast8_t class_dimensions[16]; - uint_fast8_t class_subclasses[16]; - uint_fast8_t class_masterbook[16]; - int_fast16_t subclass_books[16][8]; - uint_fast8_t multiplier; - uint_fast16_t x_list_dim; - vorbis_floor1_entry *list; - } t1; - } data; -} vorbis_floor; - -typedef struct { - uint_fast16_t type; - uint_fast32_t begin; - uint_fast32_t end; - uint_fast32_t partition_size; - uint_fast8_t classifications; - uint_fast8_t classbook; - int_fast16_t books[64][8]; - uint_fast8_t maxpass; -} vorbis_residue; - -typedef struct { - uint_fast8_t submaps; - uint_fast16_t coupling_steps; - uint_fast8_t *magnitude; - uint_fast8_t *angle; - uint_fast8_t *mux; - uint_fast8_t submap_floor[16]; - uint_fast8_t submap_residue[16]; -} vorbis_mapping; - -typedef struct { - uint_fast8_t blockflag; - uint_fast16_t windowtype; - uint_fast16_t transformtype; - uint_fast8_t mapping; -} vorbis_mode; - -typedef struct vorbis_context_s { - AVCodecContext *avccontext; - GetBitContext gb; - DSPContext dsp; - - FFTContext mdct[2]; - uint_fast8_t first_frame; - uint_fast32_t version; - uint_fast8_t audio_channels; - uint_fast32_t audio_samplerate; - uint_fast32_t bitrate_maximum; - uint_fast32_t bitrate_nominal; - uint_fast32_t bitrate_minimum; - uint_fast32_t blocksize[2]; - const float *win[2]; - uint_fast16_t codebook_count; - vorbis_codebook *codebooks; - uint_fast8_t floor_count; - vorbis_floor *floors; - uint_fast8_t residue_count; - vorbis_residue *residues; - uint_fast8_t mapping_count; - vorbis_mapping *mappings; - uint_fast8_t mode_count; - vorbis_mode *modes; - uint_fast8_t mode_number; // mode number for the current packet - uint_fast8_t previous_window; - float *channel_residues; - float *channel_floors; - float *saved; - uint_fast32_t add_bias; // for float->int conversion - uint_fast32_t exp_bias; -} vorbis_context; - -/* Helper functions */ - -#define BARK(x) \ - (13.1f * atan(0.00074f * (x)) + 2.24f * atan(1.85e-8f * (x) * (x)) + 1e-4f * (x)) - -static const char idx_err_str[] = "Index value %d out of range (0 - %d) for %s at %s:%i\n"; -#define VALIDATE_INDEX(idx, limit) \ - if (idx >= limit) {\ - av_log(vc->avccontext, AV_LOG_ERROR,\ - idx_err_str,\ - (int)(idx), (int)(limit - 1), #idx, __FILE__, __LINE__);\ - return -1;\ - } -#define GET_VALIDATED_INDEX(idx, bits, limit) \ - {\ - idx = get_bits(gb, bits);\ - VALIDATE_INDEX(idx, limit)\ - } - -static float vorbisfloat2float(uint_fast32_t val) -{ - double mant = val & 0x1fffff; - long exp = (val & 0x7fe00000L) >> 21; - if (val & 0x80000000) - mant = -mant; - return ldexp(mant, exp - 20 - 768); -} - - -// Free all allocated memory ----------------------------------------- - -static void vorbis_free(vorbis_context *vc) -{ - int_fast16_t i; - - av_freep(&vc->channel_residues); - av_freep(&vc->channel_floors); - av_freep(&vc->saved); - - av_freep(&vc->residues); - av_freep(&vc->modes); - - ff_mdct_end(&vc->mdct[0]); - ff_mdct_end(&vc->mdct[1]); - - for (i = 0; i < vc->codebook_count; ++i) { - av_free(vc->codebooks[i].codevectors); - free_vlc(&vc->codebooks[i].vlc); - } - av_freep(&vc->codebooks); - - for (i = 0; i < vc->floor_count; ++i) { - if (vc->floors[i].floor_type == 0) { - av_free(vc->floors[i].data.t0.map[0]); - av_free(vc->floors[i].data.t0.map[1]); - av_free(vc->floors[i].data.t0.book_list); - av_free(vc->floors[i].data.t0.lsp); - } else { - av_free(vc->floors[i].data.t1.list); - } - } - av_freep(&vc->floors); - - for (i = 0; i < vc->mapping_count; ++i) { - av_free(vc->mappings[i].magnitude); - av_free(vc->mappings[i].angle); - av_free(vc->mappings[i].mux); - } - av_freep(&vc->mappings); -} - -// Parse setup header ------------------------------------------------- - -// Process codebooks part - -static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) -{ - uint_fast16_t cb; - uint8_t *tmp_vlc_bits; - uint32_t *tmp_vlc_codes; - GetBitContext *gb = &vc->gb; - - vc->codebook_count = get_bits(gb, 8) + 1; - - AV_DEBUG(" Codebooks: %d \n", vc->codebook_count); - - vc->codebooks = av_mallocz(vc->codebook_count * sizeof(vorbis_codebook)); - tmp_vlc_bits = av_mallocz(V_MAX_VLCS * sizeof(uint8_t)); - tmp_vlc_codes = av_mallocz(V_MAX_VLCS * sizeof(uint32_t)); - - for (cb = 0; cb < vc->codebook_count; ++cb) { - vorbis_codebook *codebook_setup = &vc->codebooks[cb]; - uint_fast8_t ordered; - uint_fast32_t t, used_entries = 0; - uint_fast32_t entries; - - AV_DEBUG(" %d. Codebook \n", cb); - - if (get_bits(gb, 24) != 0x564342) { - av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook setup data corrupt. \n", cb); - goto error; - } - - codebook_setup->dimensions=get_bits(gb, 16); - if (codebook_setup->dimensions > 16 || codebook_setup->dimensions == 0) { - av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook's dimension is invalid (%d). \n", cb, codebook_setup->dimensions); - goto error; - } - entries = get_bits(gb, 24); - if (entries > V_MAX_VLCS) { - av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook has too many entries (%"PRIdFAST32"). \n", cb, entries); - goto error; - } - - ordered = get_bits1(gb); - - AV_DEBUG(" codebook_dimensions %d, codebook_entries %d \n", codebook_setup->dimensions, entries); - - if (!ordered) { - uint_fast16_t ce; - uint_fast8_t flag; - uint_fast8_t sparse = get_bits1(gb); - - AV_DEBUG(" not ordered \n"); - - if (sparse) { - AV_DEBUG(" sparse \n"); - - used_entries = 0; - for (ce = 0; ce < entries; ++ce) { - flag = get_bits1(gb); - if (flag) { - tmp_vlc_bits[ce] = get_bits(gb, 5) + 1; - ++used_entries; - } else - tmp_vlc_bits[ce] = 0; - } - } else { - AV_DEBUG(" not sparse \n"); - - used_entries = entries; - for (ce = 0; ce < entries; ++ce) - tmp_vlc_bits[ce] = get_bits(gb, 5) + 1; - } - } else { - uint_fast16_t current_entry = 0; - uint_fast8_t current_length = get_bits(gb, 5)+1; - - AV_DEBUG(" ordered, current length: %d \n", current_length); //FIXME - - used_entries = entries; - for (; current_entry < used_entries && current_length <= 32; ++current_length) { - uint_fast16_t i, number; - - AV_DEBUG(" number bits: %d ", ilog(entries - current_entry)); - - number = get_bits(gb, ilog(entries - current_entry)); - - AV_DEBUG(" number: %d \n", number); - - for (i = current_entry; i < number+current_entry; ++i) - if (i < used_entries) - tmp_vlc_bits[i] = current_length; - - current_entry+=number; - } - if (current_entry>used_entries) { - av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n"); - goto error; - } - } - - codebook_setup->lookup_type = get_bits(gb, 4); - - AV_DEBUG(" lookup type: %d : %s \n", codebook_setup->lookup_type, codebook_setup->lookup_type ? "vq" : "no lookup"); - -// If the codebook is used for (inverse) VQ, calculate codevectors. - - if (codebook_setup->lookup_type == 1) { - uint_fast16_t i, j, k; - uint_fast16_t codebook_lookup_values = ff_vorbis_nth_root(entries, codebook_setup->dimensions); - uint_fast16_t codebook_multiplicands[codebook_lookup_values]; - - float codebook_minimum_value = vorbisfloat2float(get_bits_long(gb, 32)); - float codebook_delta_value = vorbisfloat2float(get_bits_long(gb, 32)); - uint_fast8_t codebook_value_bits = get_bits(gb, 4)+1; - uint_fast8_t codebook_sequence_p = get_bits1(gb); - - AV_DEBUG(" We expect %d numbers for building the codevectors. \n", codebook_lookup_values); - AV_DEBUG(" delta %f minmum %f \n", codebook_delta_value, codebook_minimum_value); - - for (i = 0; i < codebook_lookup_values; ++i) { - codebook_multiplicands[i] = get_bits(gb, codebook_value_bits); - - AV_DEBUG(" multiplicands*delta+minmum : %e \n", (float)codebook_multiplicands[i]*codebook_delta_value+codebook_minimum_value); - AV_DEBUG(" multiplicand %d \n", codebook_multiplicands[i]); - } - -// Weed out unused vlcs and build codevector vector - codebook_setup->codevectors = used_entries ? av_mallocz(used_entries*codebook_setup->dimensions * sizeof(float)) : NULL; - for (j = 0, i = 0; i < entries; ++i) { - uint_fast8_t dim = codebook_setup->dimensions; - - if (tmp_vlc_bits[i]) { - float last = 0.0; - uint_fast32_t lookup_offset = i; - -#ifdef V_DEBUG - av_log(vc->avccontext, AV_LOG_INFO, "Lookup offset %d ,", i); -#endif - - for (k = 0; k < dim; ++k) { - uint_fast32_t multiplicand_offset = lookup_offset % codebook_lookup_values; - codebook_setup->codevectors[j * dim + k] = codebook_multiplicands[multiplicand_offset] * codebook_delta_value + codebook_minimum_value + last; - if (codebook_sequence_p) - last = codebook_setup->codevectors[j * dim + k]; - lookup_offset/=codebook_lookup_values; - } - tmp_vlc_bits[j] = tmp_vlc_bits[i]; - -#ifdef V_DEBUG - av_log(vc->avccontext, AV_LOG_INFO, "real lookup offset %d, vector: ", j); - for (k = 0; k < dim; ++k) - av_log(vc->avccontext, AV_LOG_INFO, " %f ", codebook_setup->codevectors[j * dim + k]); - av_log(vc->avccontext, AV_LOG_INFO, "\n"); -#endif - - ++j; - } - } - if (j != used_entries) { - av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n"); - goto error; - } - entries = used_entries; - } else if (codebook_setup->lookup_type >= 2) { - av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n"); - goto error; - } - -// Initialize VLC table - if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n"); - goto error; - } - codebook_setup->maxdepth = 0; - for (t = 0; t < entries; ++t) - if (tmp_vlc_bits[t] >= codebook_setup->maxdepth) - codebook_setup->maxdepth = tmp_vlc_bits[t]; - - if (codebook_setup->maxdepth > 3 * V_NB_BITS) - codebook_setup->nb_bits = V_NB_BITS2; - else - codebook_setup->nb_bits = V_NB_BITS; - - codebook_setup->maxdepth = (codebook_setup->maxdepth+codebook_setup->nb_bits - 1) / codebook_setup->nb_bits; - - if (init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n"); - goto error; - } - } - - av_free(tmp_vlc_bits); - av_free(tmp_vlc_codes); - return 0; - -// Error: -error: - av_free(tmp_vlc_bits); - av_free(tmp_vlc_codes); - return -1; -} - -// Process time domain transforms part (unused in Vorbis I) - -static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - uint_fast8_t i; - uint_fast8_t vorbis_time_count = get_bits(gb, 6) + 1; - - for (i = 0; i < vorbis_time_count; ++i) { - uint_fast16_t vorbis_tdtransform = get_bits(gb, 16); - - AV_DEBUG(" Vorbis time domain transform %d: %d \n", vorbis_time_count, vorbis_tdtransform); - - if (vorbis_tdtransform) { - av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n"); - return -1; - } - } - return 0; -} - -// Process floors part - -static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec); -static void create_map(vorbis_context *vc, uint_fast8_t floor_number); -static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec); -static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - uint_fast16_t i,j,k; - - vc->floor_count = get_bits(gb, 6) + 1; - - vc->floors = av_mallocz(vc->floor_count * sizeof(vorbis_floor)); - - for (i = 0; i < vc->floor_count; ++i) { - vorbis_floor *floor_setup = &vc->floors[i]; - - floor_setup->floor_type = get_bits(gb, 16); - - AV_DEBUG(" %d. floor type %d \n", i, floor_setup->floor_type); - - if (floor_setup->floor_type == 1) { - uint_fast8_t maximum_class = 0; - uint_fast8_t rangebits; - uint_fast16_t floor1_values = 2; - - floor_setup->decode = vorbis_floor1_decode; - - floor_setup->data.t1.partitions = get_bits(gb, 5); - - AV_DEBUG(" %d.floor: %d partitions \n", i, floor_setup->data.t1.partitions); - - for (j = 0; j < floor_setup->data.t1.partitions; ++j) { - floor_setup->data.t1.partition_class[j] = get_bits(gb, 4); - if (floor_setup->data.t1.partition_class[j] > maximum_class) - maximum_class = floor_setup->data.t1.partition_class[j]; - - AV_DEBUG(" %d. floor %d partition class %d \n", i, j, floor_setup->data.t1.partition_class[j]); - - } - - AV_DEBUG(" maximum class %d \n", maximum_class); - - floor_setup->data.t1.maximum_class = maximum_class; - - for (j = 0; j <= maximum_class; ++j) { - floor_setup->data.t1.class_dimensions[j] = get_bits(gb, 3) + 1; - floor_setup->data.t1.class_subclasses[j] = get_bits(gb, 2); - - AV_DEBUG(" %d floor %d class dim: %d subclasses %d \n", i, j, floor_setup->data.t1.class_dimensions[j], floor_setup->data.t1.class_subclasses[j]); - - if (floor_setup->data.t1.class_subclasses[j]) { - GET_VALIDATED_INDEX(floor_setup->data.t1.class_masterbook[j], 8, vc->codebook_count) - - AV_DEBUG(" masterbook: %d \n", floor_setup->data.t1.class_masterbook[j]); - } - - for (k = 0; k < (1 << floor_setup->data.t1.class_subclasses[j]); ++k) { - int16_t bits = get_bits(gb, 8) - 1; - if (bits != -1) - VALIDATE_INDEX(bits, vc->codebook_count) - floor_setup->data.t1.subclass_books[j][k] = bits; - - AV_DEBUG(" book %d. : %d \n", k, floor_setup->data.t1.subclass_books[j][k]); - } - } - - floor_setup->data.t1.multiplier = get_bits(gb, 2) + 1; - floor_setup->data.t1.x_list_dim = 2; - - for (j = 0; j < floor_setup->data.t1.partitions; ++j) - floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; - - floor_setup->data.t1.list = av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(vorbis_floor1_entry)); - - - rangebits = get_bits(gb, 4); - floor_setup->data.t1.list[0].x = 0; - floor_setup->data.t1.list[1].x = (1 << rangebits); - - for (j = 0; j < floor_setup->data.t1.partitions; ++j) { - for (k = 0; k < floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; ++k, ++floor1_values) { - floor_setup->data.t1.list[floor1_values].x = get_bits(gb, rangebits); - - AV_DEBUG(" %d. floor1 Y coord. %d \n", floor1_values, floor_setup->data.t1.list[floor1_values].x); - } - } - -// Precalculate order of x coordinates - needed for decode - ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim); - } else if (floor_setup->floor_type == 0) { - uint_fast8_t max_codebook_dim = 0; - - floor_setup->decode = vorbis_floor0_decode; - - floor_setup->data.t0.order = get_bits(gb, 8); - floor_setup->data.t0.rate = get_bits(gb, 16); - floor_setup->data.t0.bark_map_size = get_bits(gb, 16); - floor_setup->data.t0.amplitude_bits = get_bits(gb, 6); - /* zero would result in a div by zero later * - * 2^0 - 1 == 0 */ - if (floor_setup->data.t0.amplitude_bits == 0) { - av_log(vc->avccontext, AV_LOG_ERROR, - "Floor 0 amplitude bits is 0.\n"); - return -1; - } - floor_setup->data.t0.amplitude_offset = get_bits(gb, 8); - floor_setup->data.t0.num_books = get_bits(gb, 4) + 1; - - /* allocate mem for booklist */ - floor_setup->data.t0.book_list = - av_malloc(floor_setup->data.t0.num_books); - if (!floor_setup->data.t0.book_list) - return -1; - /* read book indexes */ - { - int idx; - uint_fast8_t book_idx; - for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) { - GET_VALIDATED_INDEX(floor_setup->data.t0.book_list[idx], 8, vc->codebook_count) - if (vc->codebooks[book_idx].dimensions > max_codebook_dim) - max_codebook_dim = vc->codebooks[book_idx].dimensions; - } - } - - create_map(vc, i); - - /* allocate mem for lsp coefficients */ - { - /* codebook dim is for padding if codebook dim doesn't * - * divide order+1 then we need to read more data */ - floor_setup->data.t0.lsp = - av_malloc((floor_setup->data.t0.order+1 + max_codebook_dim) - * sizeof(float)); - if (!floor_setup->data.t0.lsp) - return -1; - } - -#ifdef V_DEBUG /* debug output parsed headers */ - AV_DEBUG("floor0 order: %u\n", floor_setup->data.t0.order); - AV_DEBUG("floor0 rate: %u\n", floor_setup->data.t0.rate); - AV_DEBUG("floor0 bark map size: %u\n", - floor_setup->data.t0.bark_map_size); - AV_DEBUG("floor0 amplitude bits: %u\n", - floor_setup->data.t0.amplitude_bits); - AV_DEBUG("floor0 amplitude offset: %u\n", - floor_setup->data.t0.amplitude_offset); - AV_DEBUG("floor0 number of books: %u\n", - floor_setup->data.t0.num_books); - AV_DEBUG("floor0 book list pointer: %p\n", - floor_setup->data.t0.book_list); - { - int idx; - for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) { - AV_DEBUG(" Book %d: %u\n", - idx+1, - floor_setup->data.t0.book_list[idx]); - } - } -#endif - } else { - av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n"); - return -1; - } - } - return 0; -} - -// Process residues part - -static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - uint_fast8_t i, j, k; - - vc->residue_count = get_bits(gb, 6)+1; - vc->residues = av_mallocz(vc->residue_count * sizeof(vorbis_residue)); - - AV_DEBUG(" There are %d residues. \n", vc->residue_count); - - for (i = 0; i < vc->residue_count; ++i) { - vorbis_residue *res_setup = &vc->residues[i]; - uint_fast8_t cascade[64]; - uint_fast8_t high_bits; - uint_fast8_t low_bits; - - res_setup->type = get_bits(gb, 16); - - AV_DEBUG(" %d. residue type %d \n", i, res_setup->type); - - res_setup->begin = get_bits(gb, 24); - res_setup->end = get_bits(gb, 24); - res_setup->partition_size = get_bits(gb, 24) + 1; - /* Validations to prevent a buffer overflow later. */ - if (res_setup->begin>res_setup->end || - res_setup->end>vc->blocksize[1] / (res_setup->type == 2 ? 1 : 2) || - (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) { - av_log(vc->avccontext, AV_LOG_ERROR, "partition out of bounds: type, begin, end, size, blocksize: %"PRIdFAST16", %"PRIdFAST32", %"PRIdFAST32", %"PRIdFAST32", %"PRIdFAST32"\n", res_setup->type, res_setup->begin, res_setup->end, res_setup->partition_size, vc->blocksize[1] / 2); - return -1; - } - - res_setup->classifications = get_bits(gb, 6) + 1; - GET_VALIDATED_INDEX(res_setup->classbook, 8, vc->codebook_count) - - AV_DEBUG(" begin %d end %d part.size %d classif.s %d classbook %d \n", res_setup->begin, res_setup->end, res_setup->partition_size, - res_setup->classifications, res_setup->classbook); - - for (j = 0; j < res_setup->classifications; ++j) { - high_bits = 0; - low_bits = get_bits(gb, 3); - if (get_bits1(gb)) - high_bits = get_bits(gb, 5); - cascade[j] = (high_bits << 3) + low_bits; - - AV_DEBUG(" %d class casscade depth: %d \n", j, ilog(cascade[j])); - } - - res_setup->maxpass = 0; - for (j = 0; j < res_setup->classifications; ++j) { - for (k = 0; k < 8; ++k) { - if (cascade[j]&(1 << k)) { - GET_VALIDATED_INDEX(res_setup->books[j][k], 8, vc->codebook_count) - - AV_DEBUG(" %d class casscade depth %d book: %d \n", j, k, res_setup->books[j][k]); - - if (k>res_setup->maxpass) - res_setup->maxpass = k; - } else { - res_setup->books[j][k] = -1; - } - } - } - } - return 0; -} - -// Process mappings part - -static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - uint_fast8_t i, j; - - vc->mapping_count = get_bits(gb, 6)+1; - vc->mappings = av_mallocz(vc->mapping_count * sizeof(vorbis_mapping)); - - AV_DEBUG(" There are %d mappings. \n", vc->mapping_count); - - for (i = 0; i < vc->mapping_count; ++i) { - vorbis_mapping *mapping_setup = &vc->mappings[i]; - - if (get_bits(gb, 16)) { - av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n"); - return -1; - } - if (get_bits1(gb)) { - mapping_setup->submaps = get_bits(gb, 4) + 1; - } else { - mapping_setup->submaps = 1; - } - - if (get_bits1(gb)) { - mapping_setup->coupling_steps = get_bits(gb, 8) + 1; - mapping_setup->magnitude = av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); - mapping_setup->angle = av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); - for (j = 0; j < mapping_setup->coupling_steps; ++j) { - GET_VALIDATED_INDEX(mapping_setup->magnitude[j], ilog(vc->audio_channels - 1), vc->audio_channels) - GET_VALIDATED_INDEX(mapping_setup->angle[j], ilog(vc->audio_channels - 1), vc->audio_channels) - } - } else { - mapping_setup->coupling_steps = 0; - } - - AV_DEBUG(" %d mapping coupling steps: %d \n", i, mapping_setup->coupling_steps); - - if (get_bits(gb, 2)) { - av_log(vc->avccontext, AV_LOG_ERROR, "%d. mapping setup data invalid. \n", i); - return -1; // following spec. - } - - if (mapping_setup->submaps>1) { - mapping_setup->mux = av_mallocz(vc->audio_channels * sizeof(uint_fast8_t)); - for (j = 0; j < vc->audio_channels; ++j) - mapping_setup->mux[j] = get_bits(gb, 4); - } - - for (j = 0; j < mapping_setup->submaps; ++j) { - skip_bits(gb, 8); // FIXME check? - GET_VALIDATED_INDEX(mapping_setup->submap_floor[j], 8, vc->floor_count) - GET_VALIDATED_INDEX(mapping_setup->submap_residue[j], 8, vc->residue_count) - - AV_DEBUG(" %d mapping %d submap : floor %d, residue %d \n", i, j, mapping_setup->submap_floor[j], mapping_setup->submap_residue[j]); - } - } - return 0; -} - -// Process modes part - -static void create_map(vorbis_context *vc, uint_fast8_t floor_number) -{ - vorbis_floor *floors = vc->floors; - vorbis_floor0 *vf; - int idx; - int_fast8_t blockflag; - int_fast32_t *map; - int_fast32_t n; //TODO: could theoretically be smaller? - - for (blockflag = 0; blockflag < 2; ++blockflag) { - n = vc->blocksize[blockflag] / 2; - floors[floor_number].data.t0.map[blockflag] = - av_malloc((n+1) * sizeof(int_fast32_t)); // n + sentinel - - map = floors[floor_number].data.t0.map[blockflag]; - vf = &floors[floor_number].data.t0; - - for (idx = 0; idx < n; ++idx) { - map[idx] = floor(BARK((vf->rate * idx) / (2.0f * n)) * - ((vf->bark_map_size) / - BARK(vf->rate / 2.0f))); - if (vf->bark_map_size-1 < map[idx]) - map[idx] = vf->bark_map_size - 1; - } - map[n] = -1; - vf->map_size[blockflag] = n; - } - -# ifdef V_DEBUG - for (idx = 0; idx <= n; ++idx) { - AV_DEBUG("floor0 map: map at pos %d is %d\n", - idx, map[idx]); - } -# endif -} - -static int vorbis_parse_setup_hdr_modes(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - uint_fast8_t i; - - vc->mode_count = get_bits(gb, 6) + 1; - vc->modes = av_mallocz(vc->mode_count * sizeof(vorbis_mode)); - - AV_DEBUG(" There are %d modes.\n", vc->mode_count); - - for (i = 0; i < vc->mode_count; ++i) { - vorbis_mode *mode_setup = &vc->modes[i]; - - mode_setup->blockflag = get_bits1(gb); - mode_setup->windowtype = get_bits(gb, 16); //FIXME check - mode_setup->transformtype = get_bits(gb, 16); //FIXME check - GET_VALIDATED_INDEX(mode_setup->mapping, 8, vc->mapping_count); - - AV_DEBUG(" %d mode: blockflag %d, windowtype %d, transformtype %d, mapping %d \n", i, mode_setup->blockflag, mode_setup->windowtype, mode_setup->transformtype, mode_setup->mapping); - } - return 0; -} - -// Process the whole setup header using the functions above - -static int vorbis_parse_setup_hdr(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - - if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') || - (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') || - (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n"); - return -1; - } - - if (vorbis_parse_setup_hdr_codebooks(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n"); - return -2; - } - if (vorbis_parse_setup_hdr_tdtransforms(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n"); - return -3; - } - if (vorbis_parse_setup_hdr_floors(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n"); - return -4; - } - if (vorbis_parse_setup_hdr_residues(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n"); - return -5; - } - if (vorbis_parse_setup_hdr_mappings(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n"); - return -6; - } - if (vorbis_parse_setup_hdr_modes(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n"); - return -7; - } - if (!get_bits1(gb)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n"); - return -8; // framing flag bit unset error - } - - return 0; -} - -// Process the identification header - -static int vorbis_parse_id_hdr(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - uint_fast8_t bl0, bl1; - - if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') || - (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') || - (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n"); - return -1; - } - - vc->version = get_bits_long(gb, 32); //FIXME check 0 - vc->audio_channels = get_bits(gb, 8); - if (vc->audio_channels <= 0) { - av_log(vc->avccontext, AV_LOG_ERROR, "Invalid number of channels\n"); - return -1; - } - vc->audio_samplerate = get_bits_long(gb, 32); - if (vc->audio_samplerate <= 0) { - av_log(vc->avccontext, AV_LOG_ERROR, "Invalid samplerate\n"); - return -1; - } - vc->bitrate_maximum = get_bits_long(gb, 32); - vc->bitrate_nominal = get_bits_long(gb, 32); - vc->bitrate_minimum = get_bits_long(gb, 32); - bl0 = get_bits(gb, 4); - bl1 = get_bits(gb, 4); - vc->blocksize[0] = (1 << bl0); - vc->blocksize[1] = (1 << bl1); - if (bl0 > 13 || bl0 < 6 || bl1 > 13 || bl1 < 6 || bl1 < bl0) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n"); - return -3; - } - // output format int16 - if (vc->blocksize[1] / 2 * vc->audio_channels * 2 > AVCODEC_MAX_AUDIO_FRAME_SIZE) { - av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes " - "output packets too large.\n"); - return -4; - } - vc->win[0] = ff_vorbis_vwin[bl0 - 6]; - vc->win[1] = ff_vorbis_vwin[bl1 - 6]; - - if ((get_bits1(gb)) == 0) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n"); - return -2; - } - - vc->channel_residues = av_malloc((vc->blocksize[1] / 2) * vc->audio_channels * sizeof(float)); - vc->channel_floors = av_malloc((vc->blocksize[1] / 2) * vc->audio_channels * sizeof(float)); - vc->saved = av_mallocz((vc->blocksize[1] / 4) * vc->audio_channels * sizeof(float)); - vc->previous_window = 0; - - ff_mdct_init(&vc->mdct[0], bl0, 1, vc->exp_bias ? -(1 << 15) : -1.0); - ff_mdct_init(&vc->mdct[1], bl1, 1, vc->exp_bias ? -(1 << 15) : -1.0); - - AV_DEBUG(" vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ", - vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]); - -/* - BLK = vc->blocksize[0]; - for (i = 0; i < BLK / 2; ++i) { - vc->win[0][i] = sin(0.5*3.14159265358*(sin(((float)i + 0.5) / (float)BLK*3.14159265358))*(sin(((float)i + 0.5) / (float)BLK*3.14159265358))); - } -*/ - - return 0; -} - -// Process the extradata using the functions above (identification header, setup header) - -static av_cold int vorbis_decode_init(AVCodecContext *avccontext) -{ - vorbis_context *vc = avccontext->priv_data ; - uint8_t *headers = avccontext->extradata; - int headers_len = avccontext->extradata_size; - uint8_t *header_start[3]; - int header_len[3]; - GetBitContext *gb = &(vc->gb); - int hdr_type; - - vc->avccontext = avccontext; - dsputil_init(&vc->dsp, avccontext); - - if (vc->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { - vc->add_bias = 385; - vc->exp_bias = 0; - } else { - vc->add_bias = 0; - vc->exp_bias = 15 << 23; - } - - if (!headers_len) { - av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n"); - return -1; - } - - if (ff_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) { - av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n"); - return -1; - } - - init_get_bits(gb, header_start[0], header_len[0]*8); - hdr_type = get_bits(gb, 8); - if (hdr_type != 1) { - av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n"); - return -1; - } - if (vorbis_parse_id_hdr(vc)) { - av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n"); - vorbis_free(vc); - return -1; - } - - init_get_bits(gb, header_start[2], header_len[2]*8); - hdr_type = get_bits(gb, 8); - if (hdr_type != 5) { - av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n"); - vorbis_free(vc); - return -1; - } - if (vorbis_parse_setup_hdr(vc)) { - av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n"); - vorbis_free(vc); - return -1; - } - - if (vc->audio_channels > 8) - avccontext->channel_layout = 0; - else - avccontext->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1]; - - avccontext->channels = vc->audio_channels; - avccontext->sample_rate = vc->audio_samplerate; - avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2; - avccontext->sample_fmt = SAMPLE_FMT_S16; - - return 0 ; -} - -// Decode audiopackets ------------------------------------------------- - -// Read and decode floor - -static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec) -{ - vorbis_floor0 *vf = &vfu->t0; - float *lsp = vf->lsp; - uint_fast32_t amplitude; - uint_fast32_t book_idx; - uint_fast8_t blockflag = vc->modes[vc->mode_number].blockflag; - - amplitude = get_bits(&vc->gb, vf->amplitude_bits); - if (amplitude > 0) { - float last = 0; - uint_fast16_t lsp_len = 0; - uint_fast16_t idx; - vorbis_codebook codebook; - - book_idx = get_bits(&vc->gb, ilog(vf->num_books)); - if (book_idx >= vf->num_books) { - av_log(vc->avccontext, AV_LOG_ERROR, - "floor0 dec: booknumber too high!\n"); - book_idx = 0; - //FIXME: look above - } - AV_DEBUG("floor0 dec: booknumber: %u\n", book_idx); - codebook = vc->codebooks[vf->book_list[book_idx]]; - - while (lsp_lenorder) { - int vec_off; - - AV_DEBUG("floor0 dec: book dimension: %d\n", codebook.dimensions); - AV_DEBUG("floor0 dec: maximum depth: %d\n", codebook.maxdepth); - /* read temp vector */ - vec_off = get_vlc2(&vc->gb, codebook.vlc.table, - codebook.nb_bits, codebook.maxdepth) - * codebook.dimensions; - AV_DEBUG("floor0 dec: vector offset: %d\n", vec_off); - /* copy each vector component and add last to it */ - for (idx = 0; idx < codebook.dimensions; ++idx) - lsp[lsp_len+idx] = codebook.codevectors[vec_off+idx] + last; - last = lsp[lsp_len+idx-1]; /* set last to last vector component */ - - lsp_len += codebook.dimensions; - } -#ifdef V_DEBUG - /* DEBUG: output lsp coeffs */ - { - int idx; - for (idx = 0; idx < lsp_len; ++idx) - AV_DEBUG("floor0 dec: coeff at %d is %f\n", idx, lsp[idx]); - } -#endif - - /* synthesize floor output vector */ - { - int i; - int order = vf->order; - float wstep = M_PI / vf->bark_map_size; - - for (i = 0; i < order; i++) - lsp[i] = 2.0f * cos(lsp[i]); - - AV_DEBUG("floor0 synth: map_size = %d; m = %d; wstep = %f\n", - vf->map_size, order, wstep); - - i = 0; - while (i < vf->map_size[blockflag]) { - int j, iter_cond = vf->map[blockflag][i]; - float p = 0.5f; - float q = 0.5f; - float two_cos_w = 2.0f * cos(wstep * iter_cond); // needed all times - - /* similar part for the q and p products */ - for (j = 0; j + 1 < order; j += 2) { - q *= lsp[j] - two_cos_w; - p *= lsp[j + 1] - two_cos_w; - } - if (j == order) { // even order - p *= p * (2.0f - two_cos_w); - q *= q * (2.0f + two_cos_w); - } else { // odd order - q *= two_cos_w-lsp[j]; // one more time for q - - /* final step and square */ - p *= p * (4.f - two_cos_w * two_cos_w); - q *= q; - } - - /* calculate linear floor value */ - { - q = exp((((amplitude*vf->amplitude_offset) / - (((1 << vf->amplitude_bits) - 1) * sqrt(p + q))) - - vf->amplitude_offset) * .11512925f); - } - - /* fill vector */ - do { - vec[i] = q; ++i; - } while (vf->map[blockflag][i] == iter_cond); - } - } - } else { - /* this channel is unused */ - return 1; - } - - AV_DEBUG(" Floor0 decoded\n"); - - return 0; -} - -static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec) -{ - vorbis_floor1 *vf = &vfu->t1; - GetBitContext *gb = &vc->gb; - uint_fast16_t range_v[4] = { 256, 128, 86, 64 }; - uint_fast16_t range = range_v[vf->multiplier-1]; - uint_fast16_t floor1_Y[vf->x_list_dim]; - uint_fast16_t floor1_Y_final[vf->x_list_dim]; - int floor1_flag[vf->x_list_dim]; - uint_fast8_t class_; - uint_fast8_t cdim; - uint_fast8_t cbits; - uint_fast8_t csub; - uint_fast8_t cval; - int_fast16_t book; - uint_fast16_t offset; - uint_fast16_t i,j; - /*u*/int_fast16_t adx, ady, off, predicted; // WTF ? dy/adx = (unsigned)dy/adx ? - int_fast16_t dy, err; - - - if (!get_bits1(gb)) // silence - return 1; - -// Read values (or differences) for the floor's points - - floor1_Y[0] = get_bits(gb, ilog(range - 1)); - floor1_Y[1] = get_bits(gb, ilog(range - 1)); - - AV_DEBUG("floor 0 Y %d floor 1 Y %d \n", floor1_Y[0], floor1_Y[1]); - - offset = 2; - for (i = 0; i < vf->partitions; ++i) { - class_ = vf->partition_class[i]; - cdim = vf->class_dimensions[class_]; - cbits = vf->class_subclasses[class_]; - csub = (1 << cbits) - 1; - cval = 0; - - AV_DEBUG("Cbits %d \n", cbits); - - if (cbits) // this reads all subclasses for this partition's class - cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[class_]].vlc.table, - vc->codebooks[vf->class_masterbook[class_]].nb_bits, 3); - - for (j = 0; j < cdim; ++j) { - book = vf->subclass_books[class_][cval & csub]; - - AV_DEBUG("book %d Cbits %d cval %d bits:%d \n", book, cbits, cval, get_bits_count(gb)); - - cval = cval >> cbits; - if (book > -1) { - floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table, - vc->codebooks[book].nb_bits, 3); - } else { - floor1_Y[offset+j] = 0; - } - - AV_DEBUG(" floor(%d) = %d \n", vf->list[offset+j].x, floor1_Y[offset+j]); - } - offset+=cdim; - } - -// Amplitude calculation from the differences - - floor1_flag[0] = 1; - floor1_flag[1] = 1; - floor1_Y_final[0] = floor1_Y[0]; - floor1_Y_final[1] = floor1_Y[1]; - - for (i = 2; i < vf->x_list_dim; ++i) { - uint_fast16_t val, highroom, lowroom, room; - uint_fast16_t high_neigh_offs; - uint_fast16_t low_neigh_offs; - - low_neigh_offs = vf->list[i].low; - high_neigh_offs = vf->list[i].high; - dy = floor1_Y_final[high_neigh_offs] - floor1_Y_final[low_neigh_offs]; // render_point begin - adx = vf->list[high_neigh_offs].x - vf->list[low_neigh_offs].x; - ady = FFABS(dy); - err = ady * (vf->list[i].x - vf->list[low_neigh_offs].x); - off = (int16_t)err / (int16_t)adx; - if (dy < 0) { - predicted = floor1_Y_final[low_neigh_offs] - off; - } else { - predicted = floor1_Y_final[low_neigh_offs] + off; - } // render_point end - - val = floor1_Y[i]; - highroom = range-predicted; - lowroom = predicted; - if (highroom < lowroom) { - room = highroom * 2; - } else { - room = lowroom * 2; // SPEC mispelling - } - if (val) { - floor1_flag[low_neigh_offs] = 1; - floor1_flag[high_neigh_offs] = 1; - floor1_flag[i] = 1; - if (val >= room) { - if (highroom > lowroom) { - floor1_Y_final[i] = val - lowroom + predicted; - } else { - floor1_Y_final[i] = predicted - val + highroom - 1; - } - } else { - if (val & 1) { - floor1_Y_final[i] = predicted - (val + 1) / 2; - } else { - floor1_Y_final[i] = predicted + val / 2; - } - } - } else { - floor1_flag[i] = 0; - floor1_Y_final[i] = predicted; - } - - AV_DEBUG(" Decoded floor(%d) = %d / val %d \n", vf->list[i].x, floor1_Y_final[i], val); - } - -// Curve synth - connect the calculated dots and convert from dB scale FIXME optimize ? - - ff_vorbis_floor1_render_list(vf->list, vf->x_list_dim, floor1_Y_final, floor1_flag, vf->multiplier, vec, vf->list[1].x); - - AV_DEBUG(" Floor decoded\n"); - - return 0; -} - -// Read and decode residue - -static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, - vorbis_residue *vr, - uint_fast8_t ch, - uint_fast8_t *do_not_decode, - float *vec, - uint_fast16_t vlen, - int vr_type) -{ - GetBitContext *gb = &vc->gb; - uint_fast8_t c_p_c = vc->codebooks[vr->classbook].dimensions; - uint_fast16_t n_to_read = vr->end-vr->begin; - uint_fast16_t ptns_to_read = n_to_read/vr->partition_size; - uint_fast8_t classifs[ptns_to_read*vc->audio_channels]; - uint_fast8_t pass; - uint_fast8_t ch_used; - uint_fast8_t i,j,l; - uint_fast16_t k; - - if (vr_type == 2) { - for (j = 1; j < ch; ++j) - do_not_decode[0] &= do_not_decode[j]; // FIXME - clobbering input - if (do_not_decode[0]) - return 0; - ch_used = 1; - } else { - ch_used = ch; - } - - AV_DEBUG(" residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c); - - for (pass = 0; pass <= vr->maxpass; ++pass) { // FIXME OPTIMIZE? - uint_fast16_t voffset; - uint_fast16_t partition_count; - uint_fast16_t j_times_ptns_to_read; - - voffset = vr->begin; - for (partition_count = 0; partition_count < ptns_to_read;) { // SPEC error - if (!pass) { - uint_fast32_t inverse_class = ff_inverse[vr->classifications]; - for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) { - if (!do_not_decode[j]) { - uint_fast32_t temp = get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table, - vc->codebooks[vr->classbook].nb_bits, 3); - - AV_DEBUG("Classword: %d \n", temp); - - assert(vr->classifications > 1 && temp <= 65536); //needed for inverse[] - for (i = 0; i < c_p_c; ++i) { - uint_fast32_t temp2; - - temp2 = (((uint_fast64_t)temp) * inverse_class) >> 32; - if (partition_count + c_p_c - 1 - i < ptns_to_read) - classifs[j_times_ptns_to_read + partition_count + c_p_c - 1 - i] = temp - temp2 * vr->classifications; - temp = temp2; - } - } - j_times_ptns_to_read += ptns_to_read; - } - } - for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) { - for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) { - uint_fast16_t voffs; - - if (!do_not_decode[j]) { - uint_fast8_t vqclass = classifs[j_times_ptns_to_read+partition_count]; - int_fast16_t vqbook = vr->books[vqclass][pass]; - - if (vqbook >= 0 && vc->codebooks[vqbook].codevectors) { - uint_fast16_t coffs; - unsigned dim = vc->codebooks[vqbook].dimensions; // not uint_fast8_t: 64bit is slower here on amd64 - uint_fast16_t step = dim == 1 ? vr->partition_size - : FASTDIV(vr->partition_size, dim); - vorbis_codebook codebook = vc->codebooks[vqbook]; - - if (vr_type == 0) { - - voffs = voffset+j*vlen; - for (k = 0; k < step; ++k) { - coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for (l = 0; l < dim; ++l) - vec[voffs + k + l * step] += codebook.codevectors[coffs + l]; // FPMATH - } - } else if (vr_type == 1) { - voffs = voffset + j * vlen; - for (k = 0; k < step; ++k) { - coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for (l = 0; l < dim; ++l, ++voffs) { - vec[voffs]+=codebook.codevectors[coffs+l]; // FPMATH - - AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d \n", pass, voffs, vec[voffs], codebook.codevectors[coffs+l], coffs); - } - } - } else if (vr_type == 2 && ch == 2 && (voffset & 1) == 0 && (dim & 1) == 0) { // most frequent case optimized - voffs = voffset >> 1; - - if (dim == 2) { - for (k = 0; k < step; ++k) { - coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 2; - vec[voffs + k ] += codebook.codevectors[coffs ]; // FPMATH - vec[voffs + k + vlen] += codebook.codevectors[coffs + 1]; // FPMATH - } - } else if (dim == 4) { - for (k = 0; k < step; ++k, voffs += 2) { - coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 4; - vec[voffs ] += codebook.codevectors[coffs ]; // FPMATH - vec[voffs + 1 ] += codebook.codevectors[coffs + 2]; // FPMATH - vec[voffs + vlen ] += codebook.codevectors[coffs + 1]; // FPMATH - vec[voffs + vlen + 1] += codebook.codevectors[coffs + 3]; // FPMATH - } - } else - for (k = 0; k < step; ++k) { - coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for (l = 0; l < dim; l += 2, voffs++) { - vec[voffs ] += codebook.codevectors[coffs + l ]; // FPMATH - vec[voffs + vlen] += codebook.codevectors[coffs + l + 1]; // FPMATH - - AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d \n", pass, voffset / ch + (voffs % ch) * vlen, vec[voffset / ch + (voffs % ch) * vlen], codebook.codevectors[coffs + l], coffs, l); - } - } - - } else if (vr_type == 2) { - voffs = voffset; - - for (k = 0; k < step; ++k) { - coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for (l = 0; l < dim; ++l, ++voffs) { - vec[voffs / ch + (voffs % ch) * vlen] += codebook.codevectors[coffs + l]; // FPMATH FIXME use if and counter instead of / and % - - AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d \n", pass, voffset / ch + (voffs % ch) * vlen, vec[voffset / ch + (voffs % ch) * vlen], codebook.codevectors[coffs + l], coffs, l); - } - } - } - } - } - j_times_ptns_to_read += ptns_to_read; - } - ++partition_count; - voffset += vr->partition_size; - } - } - } - return 0; -} - -static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, - uint_fast8_t ch, - uint_fast8_t *do_not_decode, - float *vec, uint_fast16_t vlen) -{ - if (vr->type == 2) - return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 2); - else if (vr->type == 1) - return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 1); - else if (vr->type == 0) - return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 0); - else { - av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n"); - return -1; - } -} - -void vorbis_inverse_coupling(float *mag, float *ang, int blocksize) -{ - int i; - for (i = 0; i < blocksize; i++) { - if (mag[i] > 0.0) { - if (ang[i] > 0.0) { - ang[i] = mag[i] - ang[i]; - } else { - float temp = ang[i]; - ang[i] = mag[i]; - mag[i] += temp; - } - } else { - if (ang[i] > 0.0) { - ang[i] += mag[i]; - } else { - float temp = ang[i]; - ang[i] = mag[i]; - mag[i] -= temp; - } - } - } -} - -static void copy_normalize(float *dst, float *src, int len, int exp_bias, - float add_bias) -{ - int i; - if (exp_bias) { - memcpy(dst, src, len * sizeof(float)); - } else { - for (i = 0; i < len; i++) - dst[i] = src[i] + add_bias; - } -} - -// Decode the audio packet using the functions above - -static int vorbis_parse_audio_packet(vorbis_context *vc) -{ - GetBitContext *gb = &vc->gb; - - uint_fast8_t previous_window = vc->previous_window; - uint_fast8_t mode_number; - uint_fast8_t blockflag; - uint_fast16_t blocksize; - int_fast32_t i,j; - uint_fast8_t no_residue[vc->audio_channels]; - uint_fast8_t do_not_decode[vc->audio_channels]; - vorbis_mapping *mapping; - float *ch_res_ptr = vc->channel_residues; - float *ch_floor_ptr = vc->channel_floors; - uint_fast8_t res_chan[vc->audio_channels]; - uint_fast8_t res_num = 0; - int_fast16_t retlen = 0; - float fadd_bias = vc->add_bias; - - if (get_bits1(gb)) { - av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n"); - return -1; // packet type not audio - } - - if (vc->mode_count == 1) { - mode_number = 0; - } else { - GET_VALIDATED_INDEX(mode_number, ilog(vc->mode_count-1), vc->mode_count) - } - vc->mode_number = mode_number; - mapping = &vc->mappings[vc->modes[mode_number].mapping]; - - AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag); - - blockflag = vc->modes[mode_number].blockflag; - blocksize = vc->blocksize[blockflag]; - if (blockflag) - skip_bits(gb, 2); // previous_window, next_window - - memset(ch_res_ptr, 0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ? - memset(ch_floor_ptr, 0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ? - -// Decode floor - - for (i = 0; i < vc->audio_channels; ++i) { - vorbis_floor *floor; - if (mapping->submaps > 1) { - floor = &vc->floors[mapping->submap_floor[mapping->mux[i]]]; - } else { - floor = &vc->floors[mapping->submap_floor[0]]; - } - - no_residue[i] = floor->decode(vc, &floor->data, ch_floor_ptr); - ch_floor_ptr += blocksize / 2; - } - -// Nonzero vector propagate - - for (i = mapping->coupling_steps - 1; i >= 0; --i) { - if (!(no_residue[mapping->magnitude[i]] & no_residue[mapping->angle[i]])) { - no_residue[mapping->magnitude[i]] = 0; - no_residue[mapping->angle[i]] = 0; - } - } - -// Decode residue - - for (i = 0; i < mapping->submaps; ++i) { - vorbis_residue *residue; - uint_fast8_t ch = 0; - - for (j = 0; j < vc->audio_channels; ++j) { - if ((mapping->submaps == 1) || (i == mapping->mux[j])) { - res_chan[j] = res_num; - if (no_residue[j]) { - do_not_decode[ch] = 1; - } else { - do_not_decode[ch] = 0; - } - ++ch; - ++res_num; - } - } - residue = &vc->residues[mapping->submap_residue[i]]; - vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2); - - ch_res_ptr += ch * blocksize / 2; - } - -// Inverse coupling - - for (i = mapping->coupling_steps - 1; i >= 0; --i) { //warning: i has to be signed - float *mag, *ang; - - mag = vc->channel_residues+res_chan[mapping->magnitude[i]] * blocksize / 2; - ang = vc->channel_residues+res_chan[mapping->angle[i]] * blocksize / 2; - vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize / 2); - } - -// Dotproduct, MDCT - - for (j = vc->audio_channels-1;j >= 0; j--) { - ch_floor_ptr = vc->channel_floors + j * blocksize / 2; - ch_res_ptr = vc->channel_residues + res_chan[j] * blocksize / 2; - vc->dsp.vector_fmul(ch_floor_ptr, ch_res_ptr, blocksize / 2); - ff_imdct_half(&vc->mdct[blockflag], ch_res_ptr, ch_floor_ptr); - } - -// Overlap/add, save data for next overlapping FPMATH - - retlen = (blocksize + vc->blocksize[previous_window]) / 4; - for (j = 0; j < vc->audio_channels; j++) { - uint_fast16_t bs0 = vc->blocksize[0]; - uint_fast16_t bs1 = vc->blocksize[1]; - float *residue = vc->channel_residues + res_chan[j] * blocksize / 2; - float *saved = vc->saved + j * bs1 / 4; - float *ret = vc->channel_floors + j * retlen; - float *buf = residue; - const float *win = vc->win[blockflag & previous_window]; - - if (blockflag == previous_window) { - vc->dsp.vector_fmul_window(ret, saved, buf, win, fadd_bias, blocksize / 4); - } else if (blockflag > previous_window) { - vc->dsp.vector_fmul_window(ret, saved, buf, win, fadd_bias, bs0 / 4); - copy_normalize(ret+bs0/2, buf+bs0/4, (bs1-bs0)/4, vc->exp_bias, fadd_bias); - } else { - copy_normalize(ret, saved, (bs1 - bs0) / 4, vc->exp_bias, fadd_bias); - vc->dsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, fadd_bias, bs0 / 4); - } - memcpy(saved, buf + blocksize / 4, blocksize / 4 * sizeof(float)); - } - - vc->previous_window = blockflag; - return retlen; -} - -// Return the decoded audio packet through the standard api - -static int vorbis_decode_frame(AVCodecContext *avccontext, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - vorbis_context *vc = avccontext->priv_data ; - GetBitContext *gb = &(vc->gb); - const float *channel_ptrs[vc->audio_channels]; - int i; - - int_fast16_t len; - - if (!buf_size) - return 0; - - AV_DEBUG("packet length %d \n", buf_size); - - init_get_bits(gb, buf, buf_size*8); - - len = vorbis_parse_audio_packet(vc); - - if (len <= 0) { - *data_size = 0; - return buf_size; - } - - if (!vc->first_frame) { - vc->first_frame = 1; - *data_size = 0; - return buf_size ; - } - - AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb)/8, get_bits_count(gb)%8, len); - - if (vc->audio_channels > 8) { - for (i = 0; i < vc->audio_channels; i++) - channel_ptrs[i] = vc->channel_floors + i * len; - } else { - for (i = 0; i < vc->audio_channels; i++) - channel_ptrs[i] = vc->channel_floors + - len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i]; - } - - vc->dsp.float_to_int16_interleave(data, channel_ptrs, len, vc->audio_channels); - *data_size = len * 2 * vc->audio_channels; - - return buf_size ; -} - -// Close decoder - -static av_cold int vorbis_decode_close(AVCodecContext *avccontext) -{ - vorbis_context *vc = avccontext->priv_data; - - vorbis_free(vc); - - return 0 ; -} - -AVCodec vorbis_decoder = { - "vorbis", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_VORBIS, - sizeof(vorbis_context), - vorbis_decode_init, - NULL, - vorbis_decode_close, - vorbis_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), - .channel_layouts = ff_vorbis_channel_layouts, -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/vorbis_enc.c b/tizen/distrib/ffmpeg/libavcodec/vorbis_enc.c deleted file mode 100644 index 934463d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vorbis_enc.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * copyright (c) 2006 Oded Shimon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Native Vorbis encoder. - * @author Oded Shimon - */ - -#include -#include "avcodec.h" -#include "dsputil.h" -#include "fft.h" -#include "vorbis.h" -#include "vorbis_enc_data.h" - -#define BITSTREAM_WRITER_LE -#include "put_bits.h" - -#undef NDEBUG -#include - -typedef struct { - int nentries; - uint8_t *lens; - uint32_t *codewords; - int ndimentions; - float min; - float delta; - int seq_p; - int lookup; - int *quantlist; - float *dimentions; - float *pow2; -} vorbis_enc_codebook; - -typedef struct { - int dim; - int subclass; - int masterbook; - int *books; -} vorbis_enc_floor_class; - -typedef struct { - int partitions; - int *partition_to_class; - int nclasses; - vorbis_enc_floor_class *classes; - int multiplier; - int rangebits; - int values; - vorbis_floor1_entry *list; -} vorbis_enc_floor; - -typedef struct { - int type; - int begin; - int end; - int partition_size; - int classifications; - int classbook; - int8_t (*books)[8]; - float (*maxes)[2]; -} vorbis_enc_residue; - -typedef struct { - int submaps; - int *mux; - int *floor; - int *residue; - int coupling_steps; - int *magnitude; - int *angle; -} vorbis_enc_mapping; - -typedef struct { - int blockflag; - int mapping; -} vorbis_enc_mode; - -typedef struct { - int channels; - int sample_rate; - int log2_blocksize[2]; - FFTContext mdct[2]; - const float *win[2]; - int have_saved; - float *saved; - float *samples; - float *floor; // also used for tmp values for mdct - float *coeffs; // also used for residue after floor - float quality; - - int ncodebooks; - vorbis_enc_codebook *codebooks; - - int nfloors; - vorbis_enc_floor *floors; - - int nresidues; - vorbis_enc_residue *residues; - - int nmappings; - vorbis_enc_mapping *mappings; - - int nmodes; - vorbis_enc_mode *modes; - - int64_t sample_count; -} vorbis_enc_context; - -static inline void put_codeword(PutBitContext *pb, vorbis_enc_codebook *cb, - int entry) -{ - assert(entry >= 0); - assert(entry < cb->nentries); - assert(cb->lens[entry]); - put_bits(pb, cb->lens[entry], cb->codewords[entry]); -} - -static int cb_lookup_vals(int lookup, int dimentions, int entries) -{ - if (lookup == 1) - return ff_vorbis_nth_root(entries, dimentions); - else if (lookup == 2) - return dimentions *entries; - return 0; -} - -static void ready_codebook(vorbis_enc_codebook *cb) -{ - int i; - - ff_vorbis_len2vlc(cb->lens, cb->codewords, cb->nentries); - - if (!cb->lookup) { - cb->pow2 = cb->dimentions = NULL; - } else { - int vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); - cb->dimentions = av_malloc(sizeof(float) * cb->nentries * cb->ndimentions); - cb->pow2 = av_mallocz(sizeof(float) * cb->nentries); - for (i = 0; i < cb->nentries; i++) { - float last = 0; - int j; - int div = 1; - for (j = 0; j < cb->ndimentions; j++) { - int off; - if (cb->lookup == 1) - off = (i / div) % vals; // lookup type 1 - else - off = i * cb->ndimentions + j; // lookup type 2 - - cb->dimentions[i * cb->ndimentions + j] = last + cb->min + cb->quantlist[off] * cb->delta; - if (cb->seq_p) - last = cb->dimentions[i * cb->ndimentions + j]; - cb->pow2[i] += cb->dimentions[i * cb->ndimentions + j] * cb->dimentions[i * cb->ndimentions + j]; - div *= vals; - } - cb->pow2[i] /= 2.; - } - } -} - -static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) -{ - int i; - assert(rc->type == 2); - rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications); - for (i = 0; i < rc->classifications; i++) { - int j; - vorbis_enc_codebook * cb; - for (j = 0; j < 8; j++) - if (rc->books[i][j] != -1) - break; - if (j == 8) // zero - continue; - cb = &venc->codebooks[rc->books[i][j]]; - assert(cb->ndimentions >= 2); - assert(cb->lookup); - - for (j = 0; j < cb->nentries; j++) { - float a; - if (!cb->lens[j]) - continue; - a = fabs(cb->dimentions[j * cb->ndimentions]); - if (a > rc->maxes[i][0]) - rc->maxes[i][0] = a; - a = fabs(cb->dimentions[j * cb->ndimentions + 1]); - if (a > rc->maxes[i][1]) - rc->maxes[i][1] = a; - } - } - // small bias - for (i = 0; i < rc->classifications; i++) { - rc->maxes[i][0] += 0.8; - rc->maxes[i][1] += 0.8; - } -} - -static void create_vorbis_context(vorbis_enc_context *venc, - AVCodecContext *avccontext) -{ - vorbis_enc_floor *fc; - vorbis_enc_residue *rc; - vorbis_enc_mapping *mc; - int i, book; - - venc->channels = avccontext->channels; - venc->sample_rate = avccontext->sample_rate; - venc->log2_blocksize[0] = venc->log2_blocksize[1] = 11; - - venc->ncodebooks = FF_ARRAY_ELEMS(cvectors); - venc->codebooks = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks); - - // codebook 0..14 - floor1 book, values 0..255 - // codebook 15 residue masterbook - // codebook 16..29 residue - for (book = 0; book < venc->ncodebooks; book++) { - vorbis_enc_codebook *cb = &venc->codebooks[book]; - int vals; - cb->ndimentions = cvectors[book].dim; - cb->nentries = cvectors[book].real_len; - cb->min = cvectors[book].min; - cb->delta = cvectors[book].delta; - cb->lookup = cvectors[book].lookup; - cb->seq_p = 0; - - cb->lens = av_malloc(sizeof(uint8_t) * cb->nentries); - cb->codewords = av_malloc(sizeof(uint32_t) * cb->nentries); - memcpy(cb->lens, cvectors[book].clens, cvectors[book].len); - memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len); - - if (cb->lookup) { - vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); - cb->quantlist = av_malloc(sizeof(int) * vals); - for (i = 0; i < vals; i++) - cb->quantlist[i] = cvectors[book].quant[i]; - } else { - cb->quantlist = NULL; - } - ready_codebook(cb); - } - - venc->nfloors = 1; - venc->floors = av_malloc(sizeof(vorbis_enc_floor) * venc->nfloors); - - // just 1 floor - fc = &venc->floors[0]; - fc->partitions = 8; - fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions); - fc->nclasses = 0; - for (i = 0; i < fc->partitions; i++) { - static const int a[] = {0, 1, 2, 2, 3, 3, 4, 4}; - fc->partition_to_class[i] = a[i]; - fc->nclasses = FFMAX(fc->nclasses, fc->partition_to_class[i]); - } - fc->nclasses++; - fc->classes = av_malloc(sizeof(vorbis_enc_floor_class) * fc->nclasses); - for (i = 0; i < fc->nclasses; i++) { - vorbis_enc_floor_class * c = &fc->classes[i]; - int j, books; - c->dim = floor_classes[i].dim; - c->subclass = floor_classes[i].subclass; - c->masterbook = floor_classes[i].masterbook; - books = (1 << c->subclass); - c->books = av_malloc(sizeof(int) * books); - for (j = 0; j < books; j++) - c->books[j] = floor_classes[i].nbooks[j]; - } - fc->multiplier = 2; - fc->rangebits = venc->log2_blocksize[0] - 1; - - fc->values = 2; - for (i = 0; i < fc->partitions; i++) - fc->values += fc->classes[fc->partition_to_class[i]].dim; - - fc->list = av_malloc(sizeof(vorbis_floor1_entry) * fc->values); - fc->list[0].x = 0; - fc->list[1].x = 1 << fc->rangebits; - for (i = 2; i < fc->values; i++) { - static const int a[] = { - 93, 23,372, 6, 46,186,750, 14, 33, 65, - 130,260,556, 3, 10, 18, 28, 39, 55, 79, - 111,158,220,312,464,650,850 - }; - fc->list[i].x = a[i - 2]; - } - ff_vorbis_ready_floor1_list(fc->list, fc->values); - - venc->nresidues = 1; - venc->residues = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues); - - // single residue - rc = &venc->residues[0]; - rc->type = 2; - rc->begin = 0; - rc->end = 1600; - rc->partition_size = 32; - rc->classifications = 10; - rc->classbook = 15; - rc->books = av_malloc(sizeof(*rc->books) * rc->classifications); - { - static const int8_t a[10][8] = { - { -1, -1, -1, -1, -1, -1, -1, -1, }, - { -1, -1, 16, -1, -1, -1, -1, -1, }, - { -1, -1, 17, -1, -1, -1, -1, -1, }, - { -1, -1, 18, -1, -1, -1, -1, -1, }, - { -1, -1, 19, -1, -1, -1, -1, -1, }, - { -1, -1, 20, -1, -1, -1, -1, -1, }, - { -1, -1, 21, -1, -1, -1, -1, -1, }, - { 22, 23, -1, -1, -1, -1, -1, -1, }, - { 24, 25, -1, -1, -1, -1, -1, -1, }, - { 26, 27, 28, -1, -1, -1, -1, -1, }, - }; - memcpy(rc->books, a, sizeof a); - } - ready_residue(rc, venc); - - venc->nmappings = 1; - venc->mappings = av_malloc(sizeof(vorbis_enc_mapping) * venc->nmappings); - - // single mapping - mc = &venc->mappings[0]; - mc->submaps = 1; - mc->mux = av_malloc(sizeof(int) * venc->channels); - for (i = 0; i < venc->channels; i++) - mc->mux[i] = 0; - mc->floor = av_malloc(sizeof(int) * mc->submaps); - mc->residue = av_malloc(sizeof(int) * mc->submaps); - for (i = 0; i < mc->submaps; i++) { - mc->floor[i] = 0; - mc->residue[i] = 0; - } - mc->coupling_steps = venc->channels == 2 ? 1 : 0; - mc->magnitude = av_malloc(sizeof(int) * mc->coupling_steps); - mc->angle = av_malloc(sizeof(int) * mc->coupling_steps); - if (mc->coupling_steps) { - mc->magnitude[0] = 0; - mc->angle[0] = 1; - } - - venc->nmodes = 1; - venc->modes = av_malloc(sizeof(vorbis_enc_mode) * venc->nmodes); - - // single mode - venc->modes[0].blockflag = 0; - venc->modes[0].mapping = 0; - - venc->have_saved = 0; - venc->saved = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); - venc->samples = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1])); - venc->floor = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); - venc->coeffs = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); - - venc->win[0] = ff_vorbis_vwin[venc->log2_blocksize[0] - 6]; - venc->win[1] = ff_vorbis_vwin[venc->log2_blocksize[1] - 6]; - - ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0); - ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0); -} - -static void put_float(PutBitContext *pb, float f) -{ - int exp, mant; - uint32_t res = 0; - mant = (int)ldexp(frexp(f, &exp), 20); - exp += 788 - 20; - if (mant < 0) { - res |= (1 << 31); - mant = -mant; - } - res |= mant | (exp << 21); - put_bits32(pb, res); -} - -static void put_codebook_header(PutBitContext *pb, vorbis_enc_codebook *cb) -{ - int i; - int ordered = 0; - - put_bits(pb, 24, 0x564342); //magic - put_bits(pb, 16, cb->ndimentions); - put_bits(pb, 24, cb->nentries); - - for (i = 1; i < cb->nentries; i++) - if (cb->lens[i] < cb->lens[i-1]) - break; - if (i == cb->nentries) - ordered = 1; - - put_bits(pb, 1, ordered); - if (ordered) { - int len = cb->lens[0]; - put_bits(pb, 5, len - 1); - i = 0; - while (i < cb->nentries) { - int j; - for (j = 0; j+i < cb->nentries; j++) - if (cb->lens[j+i] != len) - break; - put_bits(pb, ilog(cb->nentries - i), j); - i += j; - len++; - } - } else { - int sparse = 0; - for (i = 0; i < cb->nentries; i++) - if (!cb->lens[i]) - break; - if (i != cb->nentries) - sparse = 1; - put_bits(pb, 1, sparse); - - for (i = 0; i < cb->nentries; i++) { - if (sparse) - put_bits(pb, 1, !!cb->lens[i]); - if (cb->lens[i]) - put_bits(pb, 5, cb->lens[i] - 1); - } - } - - put_bits(pb, 4, cb->lookup); - if (cb->lookup) { - int tmp = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); - int bits = ilog(cb->quantlist[0]); - - for (i = 1; i < tmp; i++) - bits = FFMAX(bits, ilog(cb->quantlist[i])); - - put_float(pb, cb->min); - put_float(pb, cb->delta); - - put_bits(pb, 4, bits - 1); - put_bits(pb, 1, cb->seq_p); - - for (i = 0; i < tmp; i++) - put_bits(pb, bits, cb->quantlist[i]); - } -} - -static void put_floor_header(PutBitContext *pb, vorbis_enc_floor *fc) -{ - int i; - - put_bits(pb, 16, 1); // type, only floor1 is supported - - put_bits(pb, 5, fc->partitions); - - for (i = 0; i < fc->partitions; i++) - put_bits(pb, 4, fc->partition_to_class[i]); - - for (i = 0; i < fc->nclasses; i++) { - int j, books; - - put_bits(pb, 3, fc->classes[i].dim - 1); - put_bits(pb, 2, fc->classes[i].subclass); - - if (fc->classes[i].subclass) - put_bits(pb, 8, fc->classes[i].masterbook); - - books = (1 << fc->classes[i].subclass); - - for (j = 0; j < books; j++) - put_bits(pb, 8, fc->classes[i].books[j] + 1); - } - - put_bits(pb, 2, fc->multiplier - 1); - put_bits(pb, 4, fc->rangebits); - - for (i = 2; i < fc->values; i++) - put_bits(pb, fc->rangebits, fc->list[i].x); -} - -static void put_residue_header(PutBitContext *pb, vorbis_enc_residue *rc) -{ - int i; - - put_bits(pb, 16, rc->type); - - put_bits(pb, 24, rc->begin); - put_bits(pb, 24, rc->end); - put_bits(pb, 24, rc->partition_size - 1); - put_bits(pb, 6, rc->classifications - 1); - put_bits(pb, 8, rc->classbook); - - for (i = 0; i < rc->classifications; i++) { - int j, tmp = 0; - for (j = 0; j < 8; j++) - tmp |= (rc->books[i][j] != -1) << j; - - put_bits(pb, 3, tmp & 7); - put_bits(pb, 1, tmp > 7); - - if (tmp > 7) - put_bits(pb, 5, tmp >> 3); - } - - for (i = 0; i < rc->classifications; i++) { - int j; - for (j = 0; j < 8; j++) - if (rc->books[i][j] != -1) - put_bits(pb, 8, rc->books[i][j]); - } -} - -static int put_main_header(vorbis_enc_context *venc, uint8_t **out) -{ - int i; - PutBitContext pb; - uint8_t buffer[50000] = {0}, *p = buffer; - int buffer_len = sizeof buffer; - int len, hlens[3]; - - // identification header - init_put_bits(&pb, p, buffer_len); - put_bits(&pb, 8, 1); //magic - for (i = 0; "vorbis"[i]; i++) - put_bits(&pb, 8, "vorbis"[i]); - put_bits32(&pb, 0); // version - put_bits(&pb, 8, venc->channels); - put_bits32(&pb, venc->sample_rate); - put_bits32(&pb, 0); // bitrate - put_bits32(&pb, 0); // bitrate - put_bits32(&pb, 0); // bitrate - put_bits(&pb, 4, venc->log2_blocksize[0]); - put_bits(&pb, 4, venc->log2_blocksize[1]); - put_bits(&pb, 1, 1); // framing - - flush_put_bits(&pb); - hlens[0] = put_bits_count(&pb) >> 3; - buffer_len -= hlens[0]; - p += hlens[0]; - - // comment header - init_put_bits(&pb, p, buffer_len); - put_bits(&pb, 8, 3); //magic - for (i = 0; "vorbis"[i]; i++) - put_bits(&pb, 8, "vorbis"[i]); - put_bits32(&pb, 0); // vendor length TODO - put_bits32(&pb, 0); // amount of comments - put_bits(&pb, 1, 1); // framing - - flush_put_bits(&pb); - hlens[1] = put_bits_count(&pb) >> 3; - buffer_len -= hlens[1]; - p += hlens[1]; - - // setup header - init_put_bits(&pb, p, buffer_len); - put_bits(&pb, 8, 5); //magic - for (i = 0; "vorbis"[i]; i++) - put_bits(&pb, 8, "vorbis"[i]); - - // codebooks - put_bits(&pb, 8, venc->ncodebooks - 1); - for (i = 0; i < venc->ncodebooks; i++) - put_codebook_header(&pb, &venc->codebooks[i]); - - // time domain, reserved, zero - put_bits(&pb, 6, 0); - put_bits(&pb, 16, 0); - - // floors - put_bits(&pb, 6, venc->nfloors - 1); - for (i = 0; i < venc->nfloors; i++) - put_floor_header(&pb, &venc->floors[i]); - - // residues - put_bits(&pb, 6, venc->nresidues - 1); - for (i = 0; i < venc->nresidues; i++) - put_residue_header(&pb, &venc->residues[i]); - - // mappings - put_bits(&pb, 6, venc->nmappings - 1); - for (i = 0; i < venc->nmappings; i++) { - vorbis_enc_mapping *mc = &venc->mappings[i]; - int j; - put_bits(&pb, 16, 0); // mapping type - - put_bits(&pb, 1, mc->submaps > 1); - if (mc->submaps > 1) - put_bits(&pb, 4, mc->submaps - 1); - - put_bits(&pb, 1, !!mc->coupling_steps); - if (mc->coupling_steps) { - put_bits(&pb, 8, mc->coupling_steps - 1); - for (j = 0; j < mc->coupling_steps; j++) { - put_bits(&pb, ilog(venc->channels - 1), mc->magnitude[j]); - put_bits(&pb, ilog(venc->channels - 1), mc->angle[j]); - } - } - - put_bits(&pb, 2, 0); // reserved - - if (mc->submaps > 1) - for (j = 0; j < venc->channels; j++) - put_bits(&pb, 4, mc->mux[j]); - - for (j = 0; j < mc->submaps; j++) { - put_bits(&pb, 8, 0); // reserved time configuration - put_bits(&pb, 8, mc->floor[j]); - put_bits(&pb, 8, mc->residue[j]); - } - } - - // modes - put_bits(&pb, 6, venc->nmodes - 1); - for (i = 0; i < venc->nmodes; i++) { - put_bits(&pb, 1, venc->modes[i].blockflag); - put_bits(&pb, 16, 0); // reserved window type - put_bits(&pb, 16, 0); // reserved transform type - put_bits(&pb, 8, venc->modes[i].mapping); - } - - put_bits(&pb, 1, 1); // framing - - flush_put_bits(&pb); - hlens[2] = put_bits_count(&pb) >> 3; - - len = hlens[0] + hlens[1] + hlens[2]; - p = *out = av_mallocz(64 + len + len/255); - - *p++ = 2; - p += av_xiphlacing(p, hlens[0]); - p += av_xiphlacing(p, hlens[1]); - buffer_len = 0; - for (i = 0; i < 3; i++) { - memcpy(p, buffer + buffer_len, hlens[i]); - p += hlens[i]; - buffer_len += hlens[i]; - } - - return p - *out; -} - -static float get_floor_average(vorbis_enc_floor * fc, float *coeffs, int i) -{ - int begin = fc->list[fc->list[FFMAX(i-1, 0)].sort].x; - int end = fc->list[fc->list[FFMIN(i+1, fc->values - 1)].sort].x; - int j; - float average = 0; - - for (j = begin; j < end; j++) - average += fabs(coeffs[j]); - return average / (end - begin); -} - -static void floor_fit(vorbis_enc_context *venc, vorbis_enc_floor *fc, - float *coeffs, uint_fast16_t *posts, int samples) -{ - int range = 255 / fc->multiplier + 1; - int i; - float tot_average = 0.; - float averages[fc->values]; - for (i = 0; i < fc->values; i++) { - averages[i] = get_floor_average(fc, coeffs, i); - tot_average += averages[i]; - } - tot_average /= fc->values; - tot_average /= venc->quality; - - for (i = 0; i < fc->values; i++) { - int position = fc->list[fc->list[i].sort].x; - float average = averages[i]; - int j; - - average *= pow(tot_average / average, 0.5) * pow(1.25, position/200.); // MAGIC! - for (j = 0; j < range - 1; j++) - if (ff_vorbis_floor1_inverse_db_table[j * fc->multiplier] > average) - break; - posts[fc->list[i].sort] = j; - } -} - -static int render_point(int x0, int y0, int x1, int y1, int x) -{ - return y0 + (x - x0) * (y1 - y0) / (x1 - x0); -} - -static void floor_encode(vorbis_enc_context *venc, vorbis_enc_floor *fc, - PutBitContext *pb, uint_fast16_t *posts, - float *floor, int samples) -{ - int range = 255 / fc->multiplier + 1; - int coded[fc->values]; // first 2 values are unused - int i, counter; - - put_bits(pb, 1, 1); // non zero - put_bits(pb, ilog(range - 1), posts[0]); - put_bits(pb, ilog(range - 1), posts[1]); - coded[0] = coded[1] = 1; - - for (i = 2; i < fc->values; i++) { - int predicted = render_point(fc->list[fc->list[i].low].x, - posts[fc->list[i].low], - fc->list[fc->list[i].high].x, - posts[fc->list[i].high], - fc->list[i].x); - int highroom = range - predicted; - int lowroom = predicted; - int room = FFMIN(highroom, lowroom); - if (predicted == posts[i]) { - coded[i] = 0; // must be used later as flag! - continue; - } else { - if (!coded[fc->list[i].low ]) - coded[fc->list[i].low ] = -1; - if (!coded[fc->list[i].high]) - coded[fc->list[i].high] = -1; - } - if (posts[i] > predicted) { - if (posts[i] - predicted > room) - coded[i] = posts[i] - predicted + lowroom; - else - coded[i] = (posts[i] - predicted) << 1; - } else { - if (predicted - posts[i] > room) - coded[i] = predicted - posts[i] + highroom - 1; - else - coded[i] = ((predicted - posts[i]) << 1) - 1; - } - } - - counter = 2; - for (i = 0; i < fc->partitions; i++) { - vorbis_enc_floor_class * c = &fc->classes[fc->partition_to_class[i]]; - int k, cval = 0, csub = 1<subclass; - if (c->subclass) { - vorbis_enc_codebook * book = &venc->codebooks[c->masterbook]; - int cshift = 0; - for (k = 0; k < c->dim; k++) { - int l; - for (l = 0; l < csub; l++) { - int maxval = 1; - if (c->books[l] != -1) - maxval = venc->codebooks[c->books[l]].nentries; - // coded could be -1, but this still works, cause that is 0 - if (coded[counter + k] < maxval) - break; - } - assert(l != csub); - cval |= l << cshift; - cshift += c->subclass; - } - put_codeword(pb, book, cval); - } - for (k = 0; k < c->dim; k++) { - int book = c->books[cval & (csub-1)]; - int entry = coded[counter++]; - cval >>= c->subclass; - if (book == -1) - continue; - if (entry == -1) - entry = 0; - put_codeword(pb, &venc->codebooks[book], entry); - } - } - - ff_vorbis_floor1_render_list(fc->list, fc->values, posts, coded, - fc->multiplier, floor, samples); -} - -static float *put_vector(vorbis_enc_codebook *book, PutBitContext *pb, - float *num) -{ - int i, entry = -1; - float distance = FLT_MAX; - assert(book->dimentions); - for (i = 0; i < book->nentries; i++) { - float * vec = book->dimentions + i * book->ndimentions, d = book->pow2[i]; - int j; - if (!book->lens[i]) - continue; - for (j = 0; j < book->ndimentions; j++) - d -= vec[j] * num[j]; - if (distance > d) { - entry = i; - distance = d; - } - } - put_codeword(pb, book, entry); - return &book->dimentions[entry * book->ndimentions]; -} - -static void residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc, - PutBitContext *pb, float *coeffs, int samples, - int real_ch) -{ - int pass, i, j, p, k; - int psize = rc->partition_size; - int partitions = (rc->end - rc->begin) / psize; - int channels = (rc->type == 2) ? 1 : real_ch; - int classes[channels][partitions]; - int classwords = venc->codebooks[rc->classbook].ndimentions; - - assert(rc->type == 2); - assert(real_ch == 2); - for (p = 0; p < partitions; p++) { - float max1 = 0., max2 = 0.; - int s = rc->begin + p * psize; - for (k = s; k < s + psize; k += 2) { - max1 = FFMAX(max1, fabs(coeffs[ k / real_ch])); - max2 = FFMAX(max2, fabs(coeffs[samples + k / real_ch])); - } - - for (i = 0; i < rc->classifications - 1; i++) - if (max1 < rc->maxes[i][0] && max2 < rc->maxes[i][1]) - break; - classes[0][p] = i; - } - - for (pass = 0; pass < 8; pass++) { - p = 0; - while (p < partitions) { - if (pass == 0) - for (j = 0; j < channels; j++) { - vorbis_enc_codebook * book = &venc->codebooks[rc->classbook]; - int entry = 0; - for (i = 0; i < classwords; i++) { - entry *= rc->classifications; - entry += classes[j][p + i]; - } - put_codeword(pb, book, entry); - } - for (i = 0; i < classwords && p < partitions; i++, p++) { - for (j = 0; j < channels; j++) { - int nbook = rc->books[classes[j][p]][pass]; - vorbis_enc_codebook * book = &venc->codebooks[nbook]; - float *buf = coeffs + samples*j + rc->begin + p*psize; - if (nbook == -1) - continue; - - assert(rc->type == 0 || rc->type == 2); - assert(!(psize % book->ndimentions)); - - if (rc->type == 0) { - for (k = 0; k < psize; k += book->ndimentions) { - float *a = put_vector(book, pb, &buf[k]); - int l; - for (l = 0; l < book->ndimentions; l++) - buf[k + l] -= a[l]; - } - } else { - int s = rc->begin + p * psize, a1, b1; - a1 = (s % real_ch) * samples; - b1 = s / real_ch; - s = real_ch * samples; - for (k = 0; k < psize; k += book->ndimentions) { - int dim, a2 = a1, b2 = b1; - float vec[book->ndimentions], *pv = vec; - for (dim = book->ndimentions; dim--; ) { - *pv++ = coeffs[a2 + b2]; - if ((a2 += samples) == s) { - a2 = 0; - b2++; - } - } - pv = put_vector(book, pb, vec); - for (dim = book->ndimentions; dim--; ) { - coeffs[a1 + b1] -= *pv++; - if ((a1 += samples) == s) { - a1 = 0; - b1++; - } - } - } - } - } - } - } - } -} - -static int apply_window_and_mdct(vorbis_enc_context *venc, signed short *audio, - int samples) -{ - int i, j, channel; - const float * win = venc->win[0]; - int window_len = 1 << (venc->log2_blocksize[0] - 1); - float n = (float)(1 << venc->log2_blocksize[0]) / 4.; - // FIXME use dsp - - if (!venc->have_saved && !samples) - return 0; - - if (venc->have_saved) { - for (channel = 0; channel < venc->channels; channel++) - memcpy(venc->samples + channel * window_len * 2, - venc->saved + channel * window_len, sizeof(float) * window_len); - } else { - for (channel = 0; channel < venc->channels; channel++) - memset(venc->samples + channel * window_len * 2, 0, - sizeof(float) * window_len); - } - - if (samples) { - for (channel = 0; channel < venc->channels; channel++) { - float * offset = venc->samples + channel*window_len*2 + window_len; - j = channel; - for (i = 0; i < samples; i++, j += venc->channels) - offset[i] = -audio[j] / 32768. / n * win[window_len - i - 1]; //FIXME find out why the sign has to be fliped - } - } else { - for (channel = 0; channel < venc->channels; channel++) - memset(venc->samples + channel * window_len * 2 + window_len, - 0, sizeof(float) * window_len); - } - - for (channel = 0; channel < venc->channels; channel++) - ff_mdct_calc(&venc->mdct[0], venc->coeffs + channel * window_len, - venc->samples + channel * window_len * 2); - - if (samples) { - for (channel = 0; channel < venc->channels; channel++) { - float *offset = venc->saved + channel * window_len; - j = channel; - for (i = 0; i < samples; i++, j += venc->channels) - offset[i] = -audio[j] / 32768. / n * win[i]; //FIXME find out why the sign has to be fliped - } - venc->have_saved = 1; - } else { - venc->have_saved = 0; - } - return 1; -} - -static av_cold int vorbis_encode_init(AVCodecContext *avccontext) -{ - vorbis_enc_context *venc = avccontext->priv_data; - - if (avccontext->channels != 2) { - av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n"); - return -1; - } - - create_vorbis_context(venc, avccontext); - - if (avccontext->flags & CODEC_FLAG_QSCALE) - venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.; - else - venc->quality = 1.; - venc->quality *= venc->quality; - - avccontext->extradata_size = put_main_header(venc, (uint8_t**)&avccontext->extradata); - - avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1); - - avccontext->coded_frame = avcodec_alloc_frame(); - avccontext->coded_frame->key_frame = 1; - - return 0; -} - -static int vorbis_encode_frame(AVCodecContext *avccontext, - unsigned char *packets, - int buf_size, void *data) -{ - vorbis_enc_context *venc = avccontext->priv_data; - signed short *audio = data; - int samples = data ? avccontext->frame_size : 0; - vorbis_enc_mode *mode; - vorbis_enc_mapping *mapping; - PutBitContext pb; - int i; - - if (!apply_window_and_mdct(venc, audio, samples)) - return 0; - samples = 1 << (venc->log2_blocksize[0] - 1); - - init_put_bits(&pb, packets, buf_size); - - put_bits(&pb, 1, 0); // magic bit - - put_bits(&pb, ilog(venc->nmodes - 1), 0); // 0 bits, the mode - - mode = &venc->modes[0]; - mapping = &venc->mappings[mode->mapping]; - if (mode->blockflag) { - put_bits(&pb, 1, 0); - put_bits(&pb, 1, 0); - } - - for (i = 0; i < venc->channels; i++) { - vorbis_enc_floor *fc = &venc->floors[mapping->floor[mapping->mux[i]]]; - uint_fast16_t posts[fc->values]; - floor_fit(venc, fc, &venc->coeffs[i * samples], posts, samples); - floor_encode(venc, fc, &pb, posts, &venc->floor[i * samples], samples); - } - - for (i = 0; i < venc->channels * samples; i++) - venc->coeffs[i] /= venc->floor[i]; - - for (i = 0; i < mapping->coupling_steps; i++) { - float *mag = venc->coeffs + mapping->magnitude[i] * samples; - float *ang = venc->coeffs + mapping->angle[i] * samples; - int j; - for (j = 0; j < samples; j++) { - float a = ang[j]; - ang[j] -= mag[j]; - if (mag[j] > 0) - ang[j] = -ang[j]; - if (ang[j] < 0) - mag[j] = a; - } - } - - residue_encode(venc, &venc->residues[mapping->residue[mapping->mux[0]]], - &pb, venc->coeffs, samples, venc->channels); - - avccontext->coded_frame->pts = venc->sample_count; - venc->sample_count += avccontext->frame_size; - flush_put_bits(&pb); - return put_bits_count(&pb) >> 3; -} - - -static av_cold int vorbis_encode_close(AVCodecContext *avccontext) -{ - vorbis_enc_context *venc = avccontext->priv_data; - int i; - - if (venc->codebooks) - for (i = 0; i < venc->ncodebooks; i++) { - av_freep(&venc->codebooks[i].lens); - av_freep(&venc->codebooks[i].codewords); - av_freep(&venc->codebooks[i].quantlist); - av_freep(&venc->codebooks[i].dimentions); - av_freep(&venc->codebooks[i].pow2); - } - av_freep(&venc->codebooks); - - if (venc->floors) - for (i = 0; i < venc->nfloors; i++) { - int j; - if (venc->floors[i].classes) - for (j = 0; j < venc->floors[i].nclasses; j++) - av_freep(&venc->floors[i].classes[j].books); - av_freep(&venc->floors[i].classes); - av_freep(&venc->floors[i].partition_to_class); - av_freep(&venc->floors[i].list); - } - av_freep(&venc->floors); - - if (venc->residues) - for (i = 0; i < venc->nresidues; i++) { - av_freep(&venc->residues[i].books); - av_freep(&venc->residues[i].maxes); - } - av_freep(&venc->residues); - - if (venc->mappings) - for (i = 0; i < venc->nmappings; i++) { - av_freep(&venc->mappings[i].mux); - av_freep(&venc->mappings[i].floor); - av_freep(&venc->mappings[i].residue); - av_freep(&venc->mappings[i].magnitude); - av_freep(&venc->mappings[i].angle); - } - av_freep(&venc->mappings); - - av_freep(&venc->modes); - - av_freep(&venc->saved); - av_freep(&venc->samples); - av_freep(&venc->floor); - av_freep(&venc->coeffs); - - ff_mdct_end(&venc->mdct[0]); - ff_mdct_end(&venc->mdct[1]); - - av_freep(&avccontext->coded_frame); - av_freep(&avccontext->extradata); - - return 0 ; -} - -AVCodec vorbis_encoder = { - "vorbis", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_VORBIS, - sizeof(vorbis_enc_context), - vorbis_encode_init, - vorbis_encode_frame, - vorbis_encode_close, - .capabilities= CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vorbis_enc_data.h b/tizen/distrib/ffmpeg/libavcodec/vorbis_enc_data.h deleted file mode 100644 index affc3d6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vorbis_enc_data.h +++ /dev/null @@ -1,504 +0,0 @@ -/* - * copyright (c) 2006 Oded Shimon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VORBIS_ENC_DATA_H -#define AVCODEC_VORBIS_ENC_DATA_H - -#include - -static const uint8_t codebook0[] = { - 2, 10, 8, 14, 7, 12, 11, 14, 1, 5, 3, 7, 4, 9, 7, 13, -}; - -static const uint8_t codebook1[] = { - 1, 4, 2, 6, 3, 7, 5, 7, -}; - -static const uint8_t codebook2[] = { - 1, 5, 7, 21, 5, 8, 9, 21, 10, 9, 12, 20, 20, 16, 20, - 20, 4, 8, 9, 20, 6, 8, 9, 20, 11, 11, 13, 20, 20, 15, - 17, 20, 9, 11, 14, 20, 8, 10, 15, 20, 11, 13, 15, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 13, 20, 20, 20, 18, 18, 20, 20, - 20, 20, 20, 20, 3, 6, 8, 20, 6, 7, 9, 20, 10, 9, 12, - 20, 20, 20, 20, 20, 5, 7, 9, 20, 6, 6, 9, 20, 10, 9, - 12, 20, 20, 20, 20, 20, 8, 10, 13, 20, 8, 9, 12, 20, 11, - 10, 12, 20, 20, 20, 20, 20, 18, 20, 20, 20, 15, 17, 18, 20, - 18, 17, 18, 20, 20, 20, 20, 20, 7, 10, 12, 20, 8, 9, 11, - 20, 14, 13, 14, 20, 20, 20, 20, 20, 6, 9, 12, 20, 7, 8, - 11, 20, 12, 11, 13, 20, 20, 20, 20, 20, 9, 11, 15, 20, 8, - 10, 14, 20, 12, 11, 14, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 11, 16, 18, - 20, 15, 15, 17, 20, 20, 17, 20, 20, 20, 20, 20, 20, 9, 14, - 16, 20, 12, 12, 15, 20, 17, 15, 18, 20, 20, 20, 20, 20, 16, - 19, 18, 20, 15, 16, 20, 20, 17, 17, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, -}; - -static const uint8_t codebook3[] = { - 2, 3, 7, 13, 4, 4, 7, 15, 8, 6, 9, 17, 21, 16, 15, - 21, 2, 5, 7, 11, 5, 5, 7, 14, 9, 7, 10, 16, 17, 15, - 16, 21, 4, 7, 10, 17, 7, 7, 9, 15, 11, 9, 11, 16, 21, - 18, 15, 21, 18, 21, 21, 21, 15, 17, 17, 19, 21, 19, 18, 20, - 21, 21, 21, 20, -}; - -static const uint8_t codebook4[] = { - 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, - 5, 6, 5, 6, 5, 6, 5, 6, 5, 7, 5, 7, 5, 7, 5, - 7, 5, 8, 6, 8, 6, 8, 6, 9, 6, 9, 6, 10, 6, 10, - 6, 11, 6, 11, 7, 11, 7, 12, 7, 12, 7, 12, 7, 12, 7, - 12, 7, 12, 7, 12, 7, 12, 8, 13, 8, 12, 8, 12, 8, 13, - 8, 13, 9, 13, 9, 13, 9, 13, 9, 12, 10, 12, 10, 13, 10, - 14, 11, 14, 12, 14, 13, 14, 13, 14, 14, 15, 16, 15, 15, 15, - 14, 15, 17, 21, 22, 22, 21, 22, 22, 22, 22, 22, 22, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, -}; - -static const uint8_t codebook5[] = { - 2, 5, 5, 4, 5, 4, 5, 4, 5, 4, 6, 5, 6, 5, 6, - 5, 6, 5, 7, 5, 7, 6, 8, 6, 8, 6, 8, 6, 9, 6, - 9, 6, -}; - -static const uint8_t codebook6[] = { - 8, 5, 8, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, - 4, 9, 4, 9, 4, 9, 4, 8, 4, 8, 4, 9, 5, 9, 5, - 9, 5, 9, 5, 9, 6, 10, 6, 10, 7, 10, 8, 11, 9, 11, - 11, 12, 13, 12, 14, 13, 15, 13, 15, 14, 16, 14, 17, 15, 17, - 15, 15, 16, 16, 15, 16, 16, 16, 15, 18, 16, 15, 17, 17, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, -}; - -static const uint8_t codebook7[] = { - 1, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 6, 5, 6, - 5, 6, 6, 7, 7, 7, 7, 8, 7, 8, 8, 9, 8, 10, 9, - 10, 9, -}; - -static const uint8_t codebook8[] = { - 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 5, 6, 5, 6, - 5, 7, 5, 7, 6, 7, 6, 8, 7, 8, 7, 8, 7, 9, 8, - 9, 9, 9, 9, 10, 10, 10, 11, 9, 12, 9, 12, 9, 15, 10, - 14, 9, 13, 10, 13, 10, 12, 10, 12, 10, 13, 10, 12, 11, 13, - 11, 14, 12, 13, 13, 14, 14, 13, 14, 15, 14, 16, 13, 13, 14, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 15, 15, -}; - -static const uint8_t codebook9[] = { - 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, 4, 4, 4, 5, - 5, 5, -}; - -static const uint8_t codebook10[] = { - 3, 3, 4, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 5, - 7, 5, 8, 6, 8, 6, 9, 7, 10, 7, 10, 8, 10, 8, 11, - 9, 11, -}; - -static const uint8_t codebook11[] = { - 3, 7, 3, 8, 3, 10, 3, 8, 3, 9, 3, 8, 4, 9, 4, - 9, 5, 9, 6, 10, 6, 9, 7, 11, 7, 12, 9, 13, 10, 13, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, -}; - -static const uint8_t codebook12[] = { - 4, 5, 4, 5, 4, 5, 4, 5, 3, 5, 3, 5, 3, 5, 4, - 5, 4, -}; - -static const uint8_t codebook13[] = { - 4, 2, 4, 2, 5, 3, 5, 4, 6, 6, 6, 7, 7, 8, 7, - 8, 7, 8, 7, 9, 8, 9, 8, 9, 8, 10, 8, 11, 9, 12, - 9, 12, -}; - -static const uint8_t codebook14[] = { - 2, 5, 2, 6, 3, 6, 4, 7, 4, 7, 5, 9, 5, 11, 6, - 11, 6, 11, 7, 11, 6, 11, 6, 11, 9, 11, 8, 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, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, - 10, 10, 10, -}; - -static const uint8_t codebook15[] = { - 5, 6, 11, 11, 11, 11, 10, 10, 12, 11, 5, 2, 11, 5, 6, - 6, 7, 9, 11, 13, 13, 10, 7, 11, 6, 7, 8, 9, 10, 12, - 11, 5, 11, 6, 8, 7, 9, 11, 14, 15, 11, 6, 6, 8, 4, - 5, 7, 8, 10, 13, 10, 5, 7, 7, 5, 5, 6, 8, 10, 11, - 10, 7, 7, 8, 6, 5, 5, 7, 9, 9, 11, 8, 8, 11, 8, - 7, 6, 6, 7, 9, 12, 11, 10, 13, 9, 9, 7, 7, 7, 9, - 11, 13, 12, 15, 12, 11, 9, 8, 8, 8, -}; - -static const uint8_t codebook16[] = { - 2, 4, 4, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, - 0, 0, 0, 5, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, - 7, 8, 8, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, - 0, 0, 0, 0, 0, 0, 6, 8, 7, 0, 0, 0, 0, 0, 0, - 7, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, - 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, 7, 8, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 9, 0, 0, 0, - 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, 0, 0, 0, - 7, 9, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 7, 7, 0, 0, 0, 0, 0, 0, 7, 8, 8, - 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 0, 0, 0, - 0, 0, 0, 8, 9, 9, 0, 0, 0, 0, 0, 0, 7, 8, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 8, 8, 0, 0, 0, 0, 0, 0, 8, 9, 9, 0, 0, 0, - 0, 0, 0, 8, 9, 8, -}; - -static const uint8_t codebook17[] = { - 2, 5, 5, 0, 0, 0, 5, 5, 0, 0, 0, 5, 5, 0, 0, - 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, - 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 10, 10, 0, 0, - 0, 0, 0, 0, 0, 5, 6, 6, 0, 0, 0, 7, 7, 0, 0, - 0, 7, 7, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, - 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, - 0, 7, 7, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 5, 7, 7, 0, 0, 0, 7, 7, 0, 0, 0, 7, 7, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 10, 0, 0, - 0, 9, 9, 0, 0, 0, 9, 9, 0, 0, 0, 10, 10, 0, 0, - 0, 0, 0, 0, 0, 8, 10, 10, 0, 0, 0, 9, 9, 0, 0, - 0, 9, 9, 0, 0, 0, 10, 10, -}; - -static const uint8_t codebook18[] = { - 2, 4, 3, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 6, 6, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 7, 9, 9, -}; - -static const uint8_t codebook19[] = { - 2, 3, 3, 6, 6, 0, 0, 0, 0, 0, 4, 4, 6, 6, 0, - 0, 0, 0, 0, 4, 4, 6, 6, 0, 0, 0, 0, 0, 5, 5, - 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, - 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, - 0, 0, 0, 0, 0, 0, 9, 9, -}; - -static const uint8_t codebook20[] = { - 1, 3, 4, 6, 6, 7, 7, 9, 9, 0, 5, 5, 7, 7, 7, - 8, 9, 9, 0, 5, 5, 7, 7, 8, 8, 9, 9, 0, 7, 7, - 8, 8, 8, 8, 10, 10, 0, 0, 0, 8, 8, 8, 8, 10, 10, - 0, 0, 0, 9, 9, 9, 9, 10, 10, 0, 0, 0, 9, 9, 9, - 9, 10, 10, 0, 0, 0, 10, 10, 10, 10, 11, 11, 0, 0, 0, - 0, 0, 10, 10, 11, 11, -}; - -static const uint8_t codebook21[] = { - 2, 3, 3, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, - 11, 10, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 0, 5, 5, 7, 7, 8, 8, 9, 9, 9, 9, - 10, 10, 10, 10, 11, 11, 0, 6, 6, 7, 7, 8, 8, 9, 9, - 9, 9, 10, 10, 11, 11, 11, 11, 0, 0, 0, 7, 7, 8, 8, - 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 0, 0, 0, 8, 8, - 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 0, 0, 0, - 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 12, 12, 0, - 0, 0, 9, 9, 9, 9, 10, 10, 10, 10, 11, 10, 11, 11, 12, - 12, 0, 0, 0, 0, 0, 9, 9, 10, 10, 10, 10, 11, 11, 11, - 11, 12, 12, 0, 0, 0, 0, 0, 9, 8, 9, 9, 10, 10, 11, - 11, 12, 12, 12, 12, 0, 0, 0, 0, 0, 8, 8, 9, 9, 10, - 10, 11, 11, 12, 11, 12, 12, 0, 0, 0, 0, 0, 9, 10, 10, - 10, 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, 0, 0, - 0, 10, 10, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, - 0, 0, 0, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 0, 0, - 0, 0, 0, 0, 0, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, - 0, 0, 0, 0, 0, 0, 0, 11, 11, 12, 12, 12, 12, 13, 13, - 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 12, - 13, 13, 13, 13, -}; - -static const uint8_t codebook22[] = { - 1, 4, 4, 7, 6, 6, 7, 6, 6, 4, 7, 7, 10, 9, 9, - 11, 9, 9, 4, 7, 7, 10, 9, 9, 11, 9, 9, 7, 10, 10, - 11, 11, 10, 12, 11, 11, 6, 9, 9, 11, 10, 10, 11, 10, 10, - 6, 9, 9, 11, 10, 10, 11, 10, 10, 7, 11, 11, 11, 11, 11, - 12, 11, 11, 6, 9, 9, 11, 10, 10, 11, 10, 10, 6, 9, 9, - 11, 10, 10, 11, 10, 10, -}; - -static const uint8_t codebook23[] = { - 2, 4, 4, 6, 6, 7, 7, 7, 7, 8, 8, 10, 5, 5, 6, - 6, 7, 7, 8, 8, 8, 8, 10, 5, 5, 6, 6, 7, 7, 8, - 8, 8, 8, 10, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 10, - 10, 10, 7, 7, 8, 7, 8, 8, 8, 8, 10, 10, 10, 8, 8, - 8, 8, 8, 8, 8, 8, 10, 10, 10, 7, 8, 8, 8, 8, 8, - 8, 8, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 8, 10, 10, - 10, 10, 10, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 9, - 9, 8, 8, 9, 8, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, - 8, -}; - -static const uint8_t codebook24[] = { - 1, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 6, 5, - 5, 7, 7, 8, 8, 8, 8, 9, 9, 10, 10, 7, 5, 5, 7, - 7, 8, 8, 8, 8, 9, 9, 11, 10, 0, 8, 8, 8, 8, 9, - 9, 9, 9, 10, 10, 11, 11, 0, 8, 8, 8, 8, 9, 9, 9, - 9, 10, 10, 11, 11, 0, 12, 12, 9, 9, 10, 10, 10, 10, 11, - 11, 11, 12, 0, 13, 13, 9, 9, 10, 10, 10, 10, 11, 11, 12, - 12, 0, 0, 0, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 0, - 0, 0, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 0, 0, 0, - 14, 14, 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 14, 14, - 11, 11, 11, 11, 12, 12, 13, 13, 0, 0, 0, 0, 0, 12, 12, - 12, 12, 13, 13, 14, 13, 0, 0, 0, 0, 0, 13, 13, 12, 12, - 13, 12, 14, 13, -}; - -static const uint8_t codebook25[] = { - 2, 4, 4, 5, 5, 6, 5, 5, 5, 5, 6, 4, 5, 5, 5, - 6, 5, 5, 5, 5, 6, 6, 6, 5, 5, -}; - -static const uint8_t codebook26[] = { - 1, 4, 4, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 9, - 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 9, 7, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 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, -}; - -static const uint8_t codebook27[] = { - 1, 4, 4, 6, 6, 7, 7, 8, 7, 9, 9, 10, 10, 10, 10, - 6, 5, 5, 7, 7, 8, 8, 10, 8, 11, 10, 12, 12, 13, 13, - 6, 5, 5, 7, 7, 8, 8, 10, 9, 11, 11, 12, 12, 13, 12, - 18, 8, 8, 8, 8, 9, 9, 10, 9, 11, 10, 12, 12, 13, 13, - 18, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 13, 12, 14, 13, - 18, 11, 11, 9, 9, 10, 10, 11, 11, 11, 12, 13, 12, 13, 14, - 18, 11, 11, 9, 8, 11, 10, 11, 11, 11, 11, 12, 12, 14, 13, - 18, 18, 18, 10, 11, 10, 11, 12, 12, 12, 12, 13, 12, 14, 13, - 18, 18, 18, 10, 11, 11, 9, 12, 11, 12, 12, 12, 13, 13, 13, - 18, 18, 17, 14, 14, 11, 11, 12, 12, 13, 12, 14, 12, 14, 13, - 18, 18, 18, 14, 14, 11, 10, 12, 9, 12, 13, 13, 13, 13, 13, - 18, 18, 17, 16, 18, 13, 13, 12, 12, 13, 11, 14, 12, 14, 14, - 17, 18, 18, 17, 18, 13, 12, 13, 10, 12, 11, 14, 14, 14, 14, - 17, 18, 18, 18, 18, 15, 16, 12, 12, 13, 10, 14, 12, 14, 15, - 18, 18, 18, 16, 17, 16, 14, 12, 11, 13, 10, 13, 13, 14, 15, -}; - -static const uint8_t codebook28[] = { - 2, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 10, 6, 6, 7, 7, 8, 7, 8, 8, 8, 8, 8, 9, - 9, 9, 9, 9, 10, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 10, 7, 7, 7, 7, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 7, 7, 8, 8, - 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, - 10, 10, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, - 9, 10, 10, 10, 11, 11, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 11, 10, 11, 11, 11, 9, 9, 9, 9, 9, 9, 10, - 10, 9, 9, 10, 9, 11, 10, 11, 11, 11, 9, 9, 9, 9, 9, - 9, 9, 9, 10, 10, 10, 9, 11, 11, 11, 11, 11, 9, 9, 9, - 9, 10, 10, 9, 9, 9, 9, 10, 9, 11, 11, 11, 11, 11, 11, - 11, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, - 11, 11, 11, 10, 9, 10, 10, 9, 10, 9, 9, 10, 9, 11, 10, - 10, 11, 11, 11, 11, 9, 10, 9, 9, 9, 9, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 10, 10, 10, 9, 9, 10, 9, 10, 9, - 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 9, 9, 9, 9, - 9, 10, 10, 10, -}; - -static const struct { - int dim; - int len; - int real_len; - const uint8_t *clens; - int lookup; - float min; - float delta; - const uint8_t *quant; -} cvectors[] = { - { 2, 16, 16, codebook0, 0 }, - { 2, 8, 8, codebook1, 0 }, - { 2, 256, 256, codebook2, 0 }, - { 2, 64, 64, codebook3, 0 }, - { 2, 128, 128, codebook4, 0 }, - { 2, 32, 32, codebook5, 0 }, - { 2, 96, 96, codebook6, 0 }, - { 2, 32, 32, codebook7, 0 }, - { 2, 96, 96, codebook8, 0 }, - { 2, 17, 17, codebook9, 0 }, - { 2, 32, 32, codebook10, 0 }, - { 2, 78, 78, codebook11, 0 }, - { 2, 17, 17, codebook12, 0 }, - { 2, 32, 32, codebook13, 0 }, - { 2, 78, 78, codebook14, 0 }, - { 2, 100, 100, codebook15, 0 }, - { 8, 1641, 6561, codebook16, 1, -1.0, 1.0, (const uint8_t[]){ 1, 0, 2, } }, - { 4, 443, 625, codebook17, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, - { 4, 105, 625, codebook18, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, - { 2, 68, 81, codebook19, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, - { 2, 81, 81, codebook20, 1, -4.0, 1.0, (const uint8_t[]){ 4, 3, 5, 2, 6, 1, 7, 0, 8, } }, - { 2, 289, 289, codebook21, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, - { 4, 81, 81, codebook22, 1, -11.0, 11.0, (const uint8_t[]){ 1, 0, 2, } }, - { 2, 121, 121, codebook23, 1, -5.0, 1.0, (const uint8_t[]){ 5, 4, 6, 3, 7, 2, 8, 1, 9, 0, 10, } }, - { 2, 169, 169, codebook24, 1, -30.0, 5.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, - { 2, 25, 25, codebook25, 1, -2.0, 1.0, (const uint8_t[]){ 2, 1, 3, 0, 4, } }, - { 2, 169, 169, codebook26, 1, -1530.0, 255.0, (const uint8_t[]){ 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12, } }, - { 2, 225, 225, codebook27, 1, -119.0, 17.0, (const uint8_t[]){ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13, 0, 14, } }, - { 2, 289, 289, codebook28, 1, -8.0, 1.0, (const uint8_t[]){ 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15, 0, 16, } }, -}; - -static const struct { - int dim; - int subclass; - int masterbook; - const int *nbooks; -} floor_classes[] = { - { 3, 0, 0, (const int[]){ 4 } }, - { 4, 1, 0, (const int[]){ 5, 6 } }, - { 3, 1, 1, (const int[]){ 7, 8 } }, - { 4, 2, 2, (const int[]){ -1, 9, 10, 11 } }, - { 3, 2, 3, (const int[]){ -1, 12, 13, 14 } }, -}; - -#endif /* AVCODEC_VORBIS_ENC_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vp3.c b/tizen/distrib/ffmpeg/libavcodec/vp3.c deleted file mode 100644 index c08de6c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp3.c +++ /dev/null @@ -1,2233 +0,0 @@ -/* - * Copyright (C) 2003-2004 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * On2 VP3 Video Decoder - * - * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx) - * For more information about the VP3 coding process, visit: - * http://wiki.multimedia.cx/index.php?title=On2_VP3 - * - * Theora decoder by Alex Beregszaszi - */ - -#include -#include -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" - -#include "vp3data.h" -#include "xiph.h" - -#define FRAGMENT_PIXELS 8 - -static av_cold int vp3_decode_end(AVCodecContext *avctx); - -//FIXME split things out into their own arrays -typedef struct Vp3Fragment { - int16_t dc; - uint8_t coding_method; - uint8_t qpi; -} Vp3Fragment; - -#define SB_NOT_CODED 0 -#define SB_PARTIALLY_CODED 1 -#define SB_FULLY_CODED 2 - -// This is the maximum length of a single long bit run that can be encoded -// for superblock coding or block qps. Theora special-cases this to read a -// bit instead of flipping the current bit to allow for runs longer than 4129. -#define MAXIMUM_LONG_BIT_RUN 4129 - -#define MODE_INTER_NO_MV 0 -#define MODE_INTRA 1 -#define MODE_INTER_PLUS_MV 2 -#define MODE_INTER_LAST_MV 3 -#define MODE_INTER_PRIOR_LAST 4 -#define MODE_USING_GOLDEN 5 -#define MODE_GOLDEN_MV 6 -#define MODE_INTER_FOURMV 7 -#define CODING_MODE_COUNT 8 - -/* special internal mode */ -#define MODE_COPY 8 - -/* There are 6 preset schemes, plus a free-form scheme */ -static const int ModeAlphabet[6][CODING_MODE_COUNT] = -{ - /* scheme 1: Last motion vector dominates */ - { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, - MODE_INTER_PLUS_MV, MODE_INTER_NO_MV, - MODE_INTRA, MODE_USING_GOLDEN, - MODE_GOLDEN_MV, MODE_INTER_FOURMV }, - - /* scheme 2 */ - { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, - MODE_INTER_NO_MV, MODE_INTER_PLUS_MV, - MODE_INTRA, MODE_USING_GOLDEN, - MODE_GOLDEN_MV, MODE_INTER_FOURMV }, - - /* scheme 3 */ - { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, - MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV, - MODE_INTRA, MODE_USING_GOLDEN, - MODE_GOLDEN_MV, MODE_INTER_FOURMV }, - - /* scheme 4 */ - { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV, - MODE_INTER_NO_MV, MODE_INTER_PRIOR_LAST, - MODE_INTRA, MODE_USING_GOLDEN, - MODE_GOLDEN_MV, MODE_INTER_FOURMV }, - - /* scheme 5: No motion vector dominates */ - { MODE_INTER_NO_MV, MODE_INTER_LAST_MV, - MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV, - MODE_INTRA, MODE_USING_GOLDEN, - MODE_GOLDEN_MV, MODE_INTER_FOURMV }, - - /* scheme 6 */ - { MODE_INTER_NO_MV, MODE_USING_GOLDEN, - MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST, - MODE_INTER_PLUS_MV, MODE_INTRA, - MODE_GOLDEN_MV, MODE_INTER_FOURMV }, - -}; - -static const uint8_t hilbert_offset[16][2] = { - {0,0}, {1,0}, {1,1}, {0,1}, - {0,2}, {0,3}, {1,3}, {1,2}, - {2,2}, {2,3}, {3,3}, {3,2}, - {3,1}, {2,1}, {2,0}, {3,0} -}; - -#define MIN_DEQUANT_VAL 2 - -typedef struct Vp3DecodeContext { - AVCodecContext *avctx; - int theora, theora_tables; - int version; - int width, height; - int chroma_x_shift, chroma_y_shift; - AVFrame golden_frame; - AVFrame last_frame; - AVFrame current_frame; - int keyframe; - DSPContext dsp; - int flipped_image; - int last_slice_end; - - int qps[3]; - int nqps; - int last_qps[3]; - - int superblock_count; - int y_superblock_width; - int y_superblock_height; - int y_superblock_count; - int c_superblock_width; - int c_superblock_height; - int c_superblock_count; - int u_superblock_start; - int v_superblock_start; - unsigned char *superblock_coding; - - int macroblock_count; - int macroblock_width; - int macroblock_height; - - int fragment_count; - int fragment_width[2]; - int fragment_height[2]; - - Vp3Fragment *all_fragments; - int fragment_start[3]; - int data_offset[3]; - - int8_t (*motion_val[2])[2]; - - ScanTable scantable; - - /* tables */ - uint16_t coded_dc_scale_factor[64]; - uint32_t coded_ac_scale_factor[64]; - uint8_t base_matrix[384][64]; - uint8_t qr_count[2][3]; - uint8_t qr_size [2][3][64]; - uint16_t qr_base[2][3][64]; - - /** - * This is a list of all tokens in bitstream order. Reordering takes place - * by pulling from each level during IDCT. As a consequence, IDCT must be - * in Hilbert order, making the minimum slice height 64 for 4:2:0 and 32 - * otherwise. The 32 different tokens with up to 12 bits of extradata are - * collapsed into 3 types, packed as follows: - * (from the low to high bits) - * - * 2 bits: type (0,1,2) - * 0: EOB run, 14 bits for run length (12 needed) - * 1: zero run, 7 bits for run length - * 7 bits for the next coefficient (3 needed) - * 2: coefficient, 14 bits (11 needed) - * - * Coefficients are signed, so are packed in the highest bits for automatic - * sign extension. - */ - int16_t *dct_tokens[3][64]; - int16_t *dct_tokens_base; -#define TOKEN_EOB(eob_run) ((eob_run) << 2) -#define TOKEN_ZERO_RUN(coeff, zero_run) (((coeff) << 9) + ((zero_run) << 2) + 1) -#define TOKEN_COEFF(coeff) (((coeff) << 2) + 2) - - /** - * number of blocks that contain DCT coefficients at the given level or higher - */ - int num_coded_frags[3][64]; - int total_num_coded_frags; - - /* this is a list of indexes into the all_fragments array indicating - * which of the fragments are coded */ - int *coded_fragment_list[3]; - - VLC dc_vlc[16]; - VLC ac_vlc_1[16]; - VLC ac_vlc_2[16]; - VLC ac_vlc_3[16]; - VLC ac_vlc_4[16]; - - VLC superblock_run_length_vlc; - VLC fragment_run_length_vlc; - VLC mode_code_vlc; - VLC motion_vector_vlc; - - /* these arrays need to be on 16-byte boundaries since SSE2 operations - * index into them */ - DECLARE_ALIGNED(16, int16_t, qmat)[3][2][3][64]; // fragments, macroblocks <-> fragments, - * superblocks <-> macroblocks - * - * Returns 0 is successful; returns 1 if *anything* went wrong. - */ -static int init_block_mapping(Vp3DecodeContext *s) -{ - int sb_x, sb_y, plane; - int x, y, i, j = 0; - - for (plane = 0; plane < 3; plane++) { - int sb_width = plane ? s->c_superblock_width : s->y_superblock_width; - int sb_height = plane ? s->c_superblock_height : s->y_superblock_height; - int frag_width = s->fragment_width[!!plane]; - int frag_height = s->fragment_height[!!plane]; - - for (sb_y = 0; sb_y < sb_height; sb_y++) - for (sb_x = 0; sb_x < sb_width; sb_x++) - for (i = 0; i < 16; i++) { - x = 4*sb_x + hilbert_offset[i][0]; - y = 4*sb_y + hilbert_offset[i][1]; - - if (x < frag_width && y < frag_height) - s->superblock_fragments[j++] = s->fragment_start[plane] + y*frag_width + x; - else - s->superblock_fragments[j++] = -1; - } - } - - return 0; /* successful path out */ -} - -/* - * This function sets up the dequantization tables used for a particular - * frame. - */ -static void init_dequantizer(Vp3DecodeContext *s, int qpi) -{ - int ac_scale_factor = s->coded_ac_scale_factor[s->qps[qpi]]; - int dc_scale_factor = s->coded_dc_scale_factor[s->qps[qpi]]; - int i, plane, inter, qri, bmi, bmj, qistart; - - for(inter=0; inter<2; inter++){ - for(plane=0; plane<3; plane++){ - int sum=0; - for(qri=0; qriqr_count[inter][plane]; qri++){ - sum+= s->qr_size[inter][plane][qri]; - if(s->qps[qpi] <= sum) - break; - } - qistart= sum - s->qr_size[inter][plane][qri]; - bmi= s->qr_base[inter][plane][qri ]; - bmj= s->qr_base[inter][plane][qri+1]; - for(i=0; i<64; i++){ - int coeff= ( 2*(sum -s->qps[qpi])*s->base_matrix[bmi][i] - - 2*(qistart-s->qps[qpi])*s->base_matrix[bmj][i] - + s->qr_size[inter][plane][qri]) - / (2*s->qr_size[inter][plane][qri]); - - int qmin= 8<<(inter + !i); - int qscale= i ? ac_scale_factor : dc_scale_factor; - - s->qmat[qpi][inter][plane][s->dsp.idct_permutation[i]]= av_clip((qscale * coeff)/100 * 4, qmin, 4096); - } - // all DC coefficients use the same quant so as not to interfere with DC prediction - s->qmat[qpi][inter][plane][0] = s->qmat[0][inter][plane][0]; - } - } - - memset(s->qscale_table, (FFMAX(s->qmat[0][0][0][1], s->qmat[0][0][1][1])+8)/16, 512); //FIXME finetune -} - -/* - * This function initializes the loop filter boundary limits if the frame's - * quality index is different from the previous frame's. - * - * The filter_limit_values may not be larger than 127. - */ -static void init_loop_filter(Vp3DecodeContext *s) -{ - int *bounding_values= s->bounding_values_array+127; - int filter_limit; - int x; - int value; - - filter_limit = s->filter_limit_values[s->qps[0]]; - - /* set up the bounding values */ - memset(s->bounding_values_array, 0, 256 * sizeof(int)); - for (x = 0; x < filter_limit; x++) { - bounding_values[-x] = -x; - bounding_values[x] = x; - } - for (x = value = filter_limit; x < 128 && value; x++, value--) { - bounding_values[ x] = value; - bounding_values[-x] = -value; - } - if (value) - bounding_values[128] = value; - bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202; -} - -/* - * This function unpacks all of the superblock/macroblock/fragment coding - * information from the bitstream. - */ -static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) -{ - int superblock_starts[3] = { 0, s->u_superblock_start, s->v_superblock_start }; - int bit = 0; - int current_superblock = 0; - int current_run = 0; - int num_partial_superblocks = 0; - - int i, j; - int current_fragment; - int plane; - - if (s->keyframe) { - memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count); - - } else { - - /* unpack the list of partially-coded superblocks */ - bit = get_bits1(gb); - while (current_superblock < s->superblock_count && get_bits_left(gb) > 0) { - current_run = get_vlc2(gb, - s->superblock_run_length_vlc.table, 6, 2) + 1; - if (current_run == 34) - current_run += get_bits(gb, 12); - - if (current_superblock + current_run > s->superblock_count) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid partially coded superblock run length\n"); - return -1; - } - - memset(s->superblock_coding + current_superblock, bit, current_run); - - current_superblock += current_run; - if (bit) - num_partial_superblocks += current_run; - - if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN) - bit = get_bits1(gb); - else - bit ^= 1; - } - - /* unpack the list of fully coded superblocks if any of the blocks were - * not marked as partially coded in the previous step */ - if (num_partial_superblocks < s->superblock_count) { - int superblocks_decoded = 0; - - current_superblock = 0; - bit = get_bits1(gb); - while (superblocks_decoded < s->superblock_count - num_partial_superblocks - && get_bits_left(gb) > 0) { - current_run = get_vlc2(gb, - s->superblock_run_length_vlc.table, 6, 2) + 1; - if (current_run == 34) - current_run += get_bits(gb, 12); - - for (j = 0; j < current_run; current_superblock++) { - if (current_superblock >= s->superblock_count) { - av_log(s->avctx, AV_LOG_ERROR, "Invalid fully coded superblock run length\n"); - return -1; - } - - /* skip any superblocks already marked as partially coded */ - if (s->superblock_coding[current_superblock] == SB_NOT_CODED) { - s->superblock_coding[current_superblock] = 2*bit; - j++; - } - } - superblocks_decoded += current_run; - - if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN) - bit = get_bits1(gb); - else - bit ^= 1; - } - } - - /* if there were partial blocks, initialize bitstream for - * unpacking fragment codings */ - if (num_partial_superblocks) { - - current_run = 0; - bit = get_bits1(gb); - /* toggle the bit because as soon as the first run length is - * fetched the bit will be toggled again */ - bit ^= 1; - } - } - - /* figure out which fragments are coded; iterate through each - * superblock (all planes) */ - s->total_num_coded_frags = 0; - memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); - - for (plane = 0; plane < 3; plane++) { - int sb_start = superblock_starts[plane]; - int sb_end = sb_start + (plane ? s->c_superblock_count : s->y_superblock_count); - int num_coded_frags = 0; - - for (i = sb_start; i < sb_end && get_bits_left(gb) > 0; i++) { - - /* iterate through all 16 fragments in a superblock */ - for (j = 0; j < 16; j++) { - - /* if the fragment is in bounds, check its coding status */ - current_fragment = s->superblock_fragments[i * 16 + j]; - if (current_fragment != -1) { - int coded = s->superblock_coding[i]; - - if (s->superblock_coding[i] == SB_PARTIALLY_CODED) { - - /* fragment may or may not be coded; this is the case - * that cares about the fragment coding runs */ - if (current_run-- == 0) { - bit ^= 1; - current_run = get_vlc2(gb, - s->fragment_run_length_vlc.table, 5, 2); - } - coded = bit; - } - - if (coded) { - /* default mode; actual mode will be decoded in - * the next phase */ - s->all_fragments[current_fragment].coding_method = - MODE_INTER_NO_MV; - s->coded_fragment_list[plane][num_coded_frags++] = - current_fragment; - } else { - /* not coded; copy this fragment from the prior frame */ - s->all_fragments[current_fragment].coding_method = - MODE_COPY; - } - } - } - } - s->total_num_coded_frags += num_coded_frags; - for (i = 0; i < 64; i++) - s->num_coded_frags[plane][i] = num_coded_frags; - if (plane < 2) - s->coded_fragment_list[plane+1] = s->coded_fragment_list[plane] + num_coded_frags; - } - return 0; -} - -/* - * This function unpacks all the coding mode data for individual macroblocks - * from the bitstream. - */ -static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb) -{ - int i, j, k, sb_x, sb_y; - int scheme; - int current_macroblock; - int current_fragment; - int coding_mode; - int custom_mode_alphabet[CODING_MODE_COUNT]; - const int *alphabet; - Vp3Fragment *frag; - - if (s->keyframe) { - for (i = 0; i < s->fragment_count; i++) - s->all_fragments[i].coding_method = MODE_INTRA; - - } else { - - /* fetch the mode coding scheme for this frame */ - scheme = get_bits(gb, 3); - - /* is it a custom coding scheme? */ - if (scheme == 0) { - for (i = 0; i < 8; i++) - custom_mode_alphabet[i] = MODE_INTER_NO_MV; - for (i = 0; i < 8; i++) - custom_mode_alphabet[get_bits(gb, 3)] = i; - alphabet = custom_mode_alphabet; - } else - alphabet = ModeAlphabet[scheme-1]; - - /* iterate through all of the macroblocks that contain 1 or more - * coded fragments */ - for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) { - for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) { - if (get_bits_left(gb) <= 0) - return -1; - - for (j = 0; j < 4; j++) { - int mb_x = 2*sb_x + (j>>1); - int mb_y = 2*sb_y + (((j>>1)+j)&1); - current_macroblock = mb_y * s->macroblock_width + mb_x; - - if (mb_x >= s->macroblock_width || mb_y >= s->macroblock_height) - continue; - -#define BLOCK_X (2*mb_x + (k&1)) -#define BLOCK_Y (2*mb_y + (k>>1)) - /* coding modes are only stored if the macroblock has at least one - * luma block coded, otherwise it must be INTER_NO_MV */ - for (k = 0; k < 4; k++) { - current_fragment = BLOCK_Y*s->fragment_width[0] + BLOCK_X; - if (s->all_fragments[current_fragment].coding_method != MODE_COPY) - break; - } - if (k == 4) { - s->macroblock_coding[current_macroblock] = MODE_INTER_NO_MV; - continue; - } - - /* mode 7 means get 3 bits for each coding mode */ - if (scheme == 7) - coding_mode = get_bits(gb, 3); - else - coding_mode = alphabet - [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; - - s->macroblock_coding[current_macroblock] = coding_mode; - for (k = 0; k < 4; k++) { - frag = s->all_fragments + BLOCK_Y*s->fragment_width[0] + BLOCK_X; - if (frag->coding_method != MODE_COPY) - frag->coding_method = coding_mode; - } - -#define SET_CHROMA_MODES \ - if (frag[s->fragment_start[1]].coding_method != MODE_COPY) \ - frag[s->fragment_start[1]].coding_method = coding_mode;\ - if (frag[s->fragment_start[2]].coding_method != MODE_COPY) \ - frag[s->fragment_start[2]].coding_method = coding_mode; - - if (s->chroma_y_shift) { - frag = s->all_fragments + mb_y*s->fragment_width[1] + mb_x; - SET_CHROMA_MODES - } else if (s->chroma_x_shift) { - frag = s->all_fragments + 2*mb_y*s->fragment_width[1] + mb_x; - for (k = 0; k < 2; k++) { - SET_CHROMA_MODES - frag += s->fragment_width[1]; - } - } else { - for (k = 0; k < 4; k++) { - frag = s->all_fragments + BLOCK_Y*s->fragment_width[1] + BLOCK_X; - SET_CHROMA_MODES - } - } - } - } - } - } - - return 0; -} - -/* - * This function unpacks all the motion vectors for the individual - * macroblocks from the bitstream. - */ -static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) -{ - int j, k, sb_x, sb_y; - int coding_mode; - int motion_x[4]; - int motion_y[4]; - int last_motion_x = 0; - int last_motion_y = 0; - int prior_last_motion_x = 0; - int prior_last_motion_y = 0; - int current_macroblock; - int current_fragment; - int frag; - - if (s->keyframe) - return 0; - - /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */ - coding_mode = get_bits1(gb); - - /* iterate through all of the macroblocks that contain 1 or more - * coded fragments */ - for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) { - for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) { - if (get_bits_left(gb) <= 0) - return -1; - - for (j = 0; j < 4; j++) { - int mb_x = 2*sb_x + (j>>1); - int mb_y = 2*sb_y + (((j>>1)+j)&1); - current_macroblock = mb_y * s->macroblock_width + mb_x; - - if (mb_x >= s->macroblock_width || mb_y >= s->macroblock_height || - (s->macroblock_coding[current_macroblock] == MODE_COPY)) - continue; - - switch (s->macroblock_coding[current_macroblock]) { - - case MODE_INTER_PLUS_MV: - case MODE_GOLDEN_MV: - /* all 6 fragments use the same motion vector */ - if (coding_mode == 0) { - motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; - motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; - } else { - motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)]; - motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)]; - } - - /* vector maintenance, only on MODE_INTER_PLUS_MV */ - if (s->macroblock_coding[current_macroblock] == - MODE_INTER_PLUS_MV) { - prior_last_motion_x = last_motion_x; - prior_last_motion_y = last_motion_y; - last_motion_x = motion_x[0]; - last_motion_y = motion_y[0]; - } - break; - - case MODE_INTER_FOURMV: - /* vector maintenance */ - prior_last_motion_x = last_motion_x; - prior_last_motion_y = last_motion_y; - - /* fetch 4 vectors from the bitstream, one for each - * Y fragment, then average for the C fragment vectors */ - for (k = 0; k < 4; k++) { - current_fragment = BLOCK_Y*s->fragment_width[0] + BLOCK_X; - if (s->all_fragments[current_fragment].coding_method != MODE_COPY) { - if (coding_mode == 0) { - motion_x[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; - motion_y[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; - } else { - motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)]; - motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)]; - } - last_motion_x = motion_x[k]; - last_motion_y = motion_y[k]; - } else { - motion_x[k] = 0; - motion_y[k] = 0; - } - } - break; - - case MODE_INTER_LAST_MV: - /* all 6 fragments use the last motion vector */ - motion_x[0] = last_motion_x; - motion_y[0] = last_motion_y; - - /* no vector maintenance (last vector remains the - * last vector) */ - break; - - case MODE_INTER_PRIOR_LAST: - /* all 6 fragments use the motion vector prior to the - * last motion vector */ - motion_x[0] = prior_last_motion_x; - motion_y[0] = prior_last_motion_y; - - /* vector maintenance */ - prior_last_motion_x = last_motion_x; - prior_last_motion_y = last_motion_y; - last_motion_x = motion_x[0]; - last_motion_y = motion_y[0]; - break; - - default: - /* covers intra, inter without MV, golden without MV */ - motion_x[0] = 0; - motion_y[0] = 0; - - /* no vector maintenance */ - break; - } - - /* assign the motion vectors to the correct fragments */ - for (k = 0; k < 4; k++) { - current_fragment = - BLOCK_Y*s->fragment_width[0] + BLOCK_X; - if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) { - s->motion_val[0][current_fragment][0] = motion_x[k]; - s->motion_val[0][current_fragment][1] = motion_y[k]; - } else { - s->motion_val[0][current_fragment][0] = motion_x[0]; - s->motion_val[0][current_fragment][1] = motion_y[0]; - } - } - - if (s->chroma_y_shift) { - if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) { - motion_x[0] = RSHIFT(motion_x[0] + motion_x[1] + motion_x[2] + motion_x[3], 2); - motion_y[0] = RSHIFT(motion_y[0] + motion_y[1] + motion_y[2] + motion_y[3], 2); - } - motion_x[0] = (motion_x[0]>>1) | (motion_x[0]&1); - motion_y[0] = (motion_y[0]>>1) | (motion_y[0]&1); - frag = mb_y*s->fragment_width[1] + mb_x; - s->motion_val[1][frag][0] = motion_x[0]; - s->motion_val[1][frag][1] = motion_y[0]; - } else if (s->chroma_x_shift) { - if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) { - motion_x[0] = RSHIFT(motion_x[0] + motion_x[1], 1); - motion_y[0] = RSHIFT(motion_y[0] + motion_y[1], 1); - motion_x[1] = RSHIFT(motion_x[2] + motion_x[3], 1); - motion_y[1] = RSHIFT(motion_y[2] + motion_y[3], 1); - } else { - motion_x[1] = motion_x[0]; - motion_y[1] = motion_y[0]; - } - motion_x[0] = (motion_x[0]>>1) | (motion_x[0]&1); - motion_x[1] = (motion_x[1]>>1) | (motion_x[1]&1); - - frag = 2*mb_y*s->fragment_width[1] + mb_x; - for (k = 0; k < 2; k++) { - s->motion_val[1][frag][0] = motion_x[k]; - s->motion_val[1][frag][1] = motion_y[k]; - frag += s->fragment_width[1]; - } - } else { - for (k = 0; k < 4; k++) { - frag = BLOCK_Y*s->fragment_width[1] + BLOCK_X; - if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) { - s->motion_val[1][frag][0] = motion_x[k]; - s->motion_val[1][frag][1] = motion_y[k]; - } else { - s->motion_val[1][frag][0] = motion_x[0]; - s->motion_val[1][frag][1] = motion_y[0]; - } - } - } - } - } - } - - return 0; -} - -static int unpack_block_qpis(Vp3DecodeContext *s, GetBitContext *gb) -{ - int qpi, i, j, bit, run_length, blocks_decoded, num_blocks_at_qpi; - int num_blocks = s->total_num_coded_frags; - - for (qpi = 0; qpi < s->nqps-1 && num_blocks > 0; qpi++) { - i = blocks_decoded = num_blocks_at_qpi = 0; - - bit = get_bits1(gb); - - do { - run_length = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2) + 1; - if (run_length == 34) - run_length += get_bits(gb, 12); - blocks_decoded += run_length; - - if (!bit) - num_blocks_at_qpi += run_length; - - for (j = 0; j < run_length; i++) { - if (i >= s->total_num_coded_frags) - return -1; - - if (s->all_fragments[s->coded_fragment_list[0][i]].qpi == qpi) { - s->all_fragments[s->coded_fragment_list[0][i]].qpi += bit; - j++; - } - } - - if (run_length == MAXIMUM_LONG_BIT_RUN) - bit = get_bits1(gb); - else - bit ^= 1; - } while (blocks_decoded < num_blocks && get_bits_left(gb) > 0); - - num_blocks -= num_blocks_at_qpi; - } - - return 0; -} - -/* - * This function is called by unpack_dct_coeffs() to extract the VLCs from - * the bitstream. The VLCs encode tokens which are used to unpack DCT - * data. This function unpacks all the VLCs for either the Y plane or both - * C planes, and is called for DC coefficients or different AC coefficient - * levels (since different coefficient types require different VLC tables. - * - * This function returns a residual eob run. E.g, if a particular token gave - * instructions to EOB the next 5 fragments and there were only 2 fragments - * left in the current fragment range, 3 would be returned so that it could - * be passed into the next call to this same function. - */ -static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, - VLC *table, int coeff_index, - int plane, - int eob_run) -{ - int i, j = 0; - int token; - int zero_run = 0; - DCTELEM coeff = 0; - int bits_to_get; - int blocks_ended; - int coeff_i = 0; - int num_coeffs = s->num_coded_frags[plane][coeff_index]; - int16_t *dct_tokens = s->dct_tokens[plane][coeff_index]; - - /* local references to structure members to avoid repeated deferences */ - int *coded_fragment_list = s->coded_fragment_list[plane]; - Vp3Fragment *all_fragments = s->all_fragments; - VLC_TYPE (*vlc_table)[2] = table->table; - - if (num_coeffs < 0) - av_log(s->avctx, AV_LOG_ERROR, "Invalid number of coefficents at level %d\n", coeff_index); - - if (eob_run > num_coeffs) { - coeff_i = blocks_ended = num_coeffs; - eob_run -= num_coeffs; - } else { - coeff_i = blocks_ended = eob_run; - eob_run = 0; - } - - // insert fake EOB token to cover the split between planes or zzi - if (blocks_ended) - dct_tokens[j++] = blocks_ended << 2; - - while (coeff_i < num_coeffs && get_bits_left(gb) > 0) { - /* decode a VLC into a token */ - token = get_vlc2(gb, vlc_table, 11, 3); - /* use the token to get a zero run, a coefficient, and an eob run */ - if (token <= 6) { - eob_run = eob_run_base[token]; - if (eob_run_get_bits[token]) - eob_run += get_bits(gb, eob_run_get_bits[token]); - - // record only the number of blocks ended in this plane, - // any spill will be recorded in the next plane. - if (eob_run > num_coeffs - coeff_i) { - dct_tokens[j++] = TOKEN_EOB(num_coeffs - coeff_i); - blocks_ended += num_coeffs - coeff_i; - eob_run -= num_coeffs - coeff_i; - coeff_i = num_coeffs; - } else { - dct_tokens[j++] = TOKEN_EOB(eob_run); - blocks_ended += eob_run; - coeff_i += eob_run; - eob_run = 0; - } - } else { - bits_to_get = coeff_get_bits[token]; - if (bits_to_get) - bits_to_get = get_bits(gb, bits_to_get); - coeff = coeff_tables[token][bits_to_get]; - - zero_run = zero_run_base[token]; - if (zero_run_get_bits[token]) - zero_run += get_bits(gb, zero_run_get_bits[token]); - - if (zero_run) { - dct_tokens[j++] = TOKEN_ZERO_RUN(coeff, zero_run); - } else { - // Save DC into the fragment structure. DC prediction is - // done in raster order, so the actual DC can't be in with - // other tokens. We still need the token in dct_tokens[] - // however, or else the structure collapses on itself. - if (!coeff_index) - all_fragments[coded_fragment_list[coeff_i]].dc = coeff; - - dct_tokens[j++] = TOKEN_COEFF(coeff); - } - - if (coeff_index + zero_run > 64) { - av_log(s->avctx, AV_LOG_DEBUG, "Invalid zero run of %d with" - " %d coeffs left\n", zero_run, 64-coeff_index); - zero_run = 64 - coeff_index; - } - - // zero runs code multiple coefficients, - // so don't try to decode coeffs for those higher levels - for (i = coeff_index+1; i <= coeff_index+zero_run; i++) - s->num_coded_frags[plane][i]--; - coeff_i++; - } - } - - if (blocks_ended > s->num_coded_frags[plane][coeff_index]) - av_log(s->avctx, AV_LOG_ERROR, "More blocks ended than coded!\n"); - - // decrement the number of blocks that have higher coeffecients for each - // EOB run at this level - if (blocks_ended) - for (i = coeff_index+1; i < 64; i++) - s->num_coded_frags[plane][i] -= blocks_ended; - - // setup the next buffer - if (plane < 2) - s->dct_tokens[plane+1][coeff_index] = dct_tokens + j; - else if (coeff_index < 63) - s->dct_tokens[0][coeff_index+1] = dct_tokens + j; - - return eob_run; -} - -static void reverse_dc_prediction(Vp3DecodeContext *s, - int first_fragment, - int fragment_width, - int fragment_height); -/* - * This function unpacks all of the DCT coefficient data from the - * bitstream. - */ -static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) -{ - int i; - int dc_y_table; - int dc_c_table; - int ac_y_table; - int ac_c_table; - int residual_eob_run = 0; - VLC *y_tables[64]; - VLC *c_tables[64]; - - s->dct_tokens[0][0] = s->dct_tokens_base; - - /* fetch the DC table indexes */ - dc_y_table = get_bits(gb, 4); - dc_c_table = get_bits(gb, 4); - - /* unpack the Y plane DC coefficients */ - residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, - 0, residual_eob_run); - - /* reverse prediction of the Y-plane DC coefficients */ - reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]); - - /* unpack the C plane DC coefficients */ - residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, - 1, residual_eob_run); - residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, - 2, residual_eob_run); - - /* reverse prediction of the C-plane DC coefficients */ - if (!(s->avctx->flags & CODEC_FLAG_GRAY)) - { - reverse_dc_prediction(s, s->fragment_start[1], - s->fragment_width[1], s->fragment_height[1]); - reverse_dc_prediction(s, s->fragment_start[2], - s->fragment_width[1], s->fragment_height[1]); - } - - /* fetch the AC table indexes */ - ac_y_table = get_bits(gb, 4); - ac_c_table = get_bits(gb, 4); - - /* build tables of AC VLC tables */ - for (i = 1; i <= 5; i++) { - y_tables[i] = &s->ac_vlc_1[ac_y_table]; - c_tables[i] = &s->ac_vlc_1[ac_c_table]; - } - for (i = 6; i <= 14; i++) { - y_tables[i] = &s->ac_vlc_2[ac_y_table]; - c_tables[i] = &s->ac_vlc_2[ac_c_table]; - } - for (i = 15; i <= 27; i++) { - y_tables[i] = &s->ac_vlc_3[ac_y_table]; - c_tables[i] = &s->ac_vlc_3[ac_c_table]; - } - for (i = 28; i <= 63; i++) { - y_tables[i] = &s->ac_vlc_4[ac_y_table]; - c_tables[i] = &s->ac_vlc_4[ac_c_table]; - } - - /* decode all AC coefficents */ - for (i = 1; i <= 63; i++) { - residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i, - 0, residual_eob_run); - - residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, - 1, residual_eob_run); - residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, - 2, residual_eob_run); - } - - return 0; -} - -/* - * This function reverses the DC prediction for each coded fragment in - * the frame. Much of this function is adapted directly from the original - * VP3 source code. - */ -#define COMPATIBLE_FRAME(x) \ - (compatible_frame[s->all_fragments[x].coding_method] == current_frame_type) -#define DC_COEFF(u) s->all_fragments[u].dc - -static void reverse_dc_prediction(Vp3DecodeContext *s, - int first_fragment, - int fragment_width, - int fragment_height) -{ - -#define PUL 8 -#define PU 4 -#define PUR 2 -#define PL 1 - - int x, y; - int i = first_fragment; - - int predicted_dc; - - /* DC values for the left, up-left, up, and up-right fragments */ - int vl, vul, vu, vur; - - /* indexes for the left, up-left, up, and up-right fragments */ - int l, ul, u, ur; - - /* - * The 6 fields mean: - * 0: up-left multiplier - * 1: up multiplier - * 2: up-right multiplier - * 3: left multiplier - */ - static const int predictor_transform[16][4] = { - { 0, 0, 0, 0}, - { 0, 0, 0,128}, // PL - { 0, 0,128, 0}, // PUR - { 0, 0, 53, 75}, // PUR|PL - { 0,128, 0, 0}, // PU - { 0, 64, 0, 64}, // PU|PL - { 0,128, 0, 0}, // PU|PUR - { 0, 0, 53, 75}, // PU|PUR|PL - {128, 0, 0, 0}, // PUL - { 0, 0, 0,128}, // PUL|PL - { 64, 0, 64, 0}, // PUL|PUR - { 0, 0, 53, 75}, // PUL|PUR|PL - { 0,128, 0, 0}, // PUL|PU - {-104,116, 0,116}, // PUL|PU|PL - { 24, 80, 24, 0}, // PUL|PU|PUR - {-104,116, 0,116} // PUL|PU|PUR|PL - }; - - /* This table shows which types of blocks can use other blocks for - * prediction. For example, INTRA is the only mode in this table to - * have a frame number of 0. That means INTRA blocks can only predict - * from other INTRA blocks. There are 2 golden frame coding types; - * blocks encoding in these modes can only predict from other blocks - * that were encoded with these 1 of these 2 modes. */ - static const unsigned char compatible_frame[9] = { - 1, /* MODE_INTER_NO_MV */ - 0, /* MODE_INTRA */ - 1, /* MODE_INTER_PLUS_MV */ - 1, /* MODE_INTER_LAST_MV */ - 1, /* MODE_INTER_PRIOR_MV */ - 2, /* MODE_USING_GOLDEN */ - 2, /* MODE_GOLDEN_MV */ - 1, /* MODE_INTER_FOUR_MV */ - 3 /* MODE_COPY */ - }; - int current_frame_type; - - /* there is a last DC predictor for each of the 3 frame types */ - short last_dc[3]; - - int transform = 0; - - vul = vu = vur = vl = 0; - last_dc[0] = last_dc[1] = last_dc[2] = 0; - - /* for each fragment row... */ - for (y = 0; y < fragment_height; y++) { - - /* for each fragment in a row... */ - for (x = 0; x < fragment_width; x++, i++) { - - /* reverse prediction if this block was coded */ - if (s->all_fragments[i].coding_method != MODE_COPY) { - - current_frame_type = - compatible_frame[s->all_fragments[i].coding_method]; - - transform= 0; - if(x){ - l= i-1; - vl = DC_COEFF(l); - if(COMPATIBLE_FRAME(l)) - transform |= PL; - } - if(y){ - u= i-fragment_width; - vu = DC_COEFF(u); - if(COMPATIBLE_FRAME(u)) - transform |= PU; - if(x){ - ul= i-fragment_width-1; - vul = DC_COEFF(ul); - if(COMPATIBLE_FRAME(ul)) - transform |= PUL; - } - if(x + 1 < fragment_width){ - ur= i-fragment_width+1; - vur = DC_COEFF(ur); - if(COMPATIBLE_FRAME(ur)) - transform |= PUR; - } - } - - if (transform == 0) { - - /* if there were no fragments to predict from, use last - * DC saved */ - predicted_dc = last_dc[current_frame_type]; - } else { - - /* apply the appropriate predictor transform */ - predicted_dc = - (predictor_transform[transform][0] * vul) + - (predictor_transform[transform][1] * vu) + - (predictor_transform[transform][2] * vur) + - (predictor_transform[transform][3] * vl); - - predicted_dc /= 128; - - /* check for outranging on the [ul u l] and - * [ul u ur l] predictors */ - if ((transform == 15) || (transform == 13)) { - if (FFABS(predicted_dc - vu) > 128) - predicted_dc = vu; - else if (FFABS(predicted_dc - vl) > 128) - predicted_dc = vl; - else if (FFABS(predicted_dc - vul) > 128) - predicted_dc = vul; - } - } - - /* at long last, apply the predictor */ - DC_COEFF(i) += predicted_dc; - /* save the DC */ - last_dc[current_frame_type] = DC_COEFF(i); - } - } - } -} - -static void apply_loop_filter(Vp3DecodeContext *s, int plane, int ystart, int yend) -{ - int x, y; - int *bounding_values= s->bounding_values_array+127; - - int width = s->fragment_width[!!plane]; - int height = s->fragment_height[!!plane]; - int fragment = s->fragment_start [plane] + ystart * width; - int stride = s->current_frame.linesize[plane]; - uint8_t *plane_data = s->current_frame.data [plane]; - if (!s->flipped_image) stride = -stride; - plane_data += s->data_offset[plane] + 8*ystart*stride; - - for (y = ystart; y < yend; y++) { - - for (x = 0; x < width; x++) { - /* This code basically just deblocks on the edges of coded blocks. - * However, it has to be much more complicated because of the - * braindamaged deblock ordering used in VP3/Theora. Order matters - * because some pixels get filtered twice. */ - if( s->all_fragments[fragment].coding_method != MODE_COPY ) - { - /* do not perform left edge filter for left columns frags */ - if (x > 0) { - s->dsp.vp3_h_loop_filter( - plane_data + 8*x, - stride, bounding_values); - } - - /* do not perform top edge filter for top row fragments */ - if (y > 0) { - s->dsp.vp3_v_loop_filter( - plane_data + 8*x, - stride, bounding_values); - } - - /* do not perform right edge filter for right column - * fragments or if right fragment neighbor is also coded - * in this frame (it will be filtered in next iteration) */ - if ((x < width - 1) && - (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) { - s->dsp.vp3_h_loop_filter( - plane_data + 8*x + 8, - stride, bounding_values); - } - - /* do not perform bottom edge filter for bottom row - * fragments or if bottom fragment neighbor is also coded - * in this frame (it will be filtered in the next row) */ - if ((y < height - 1) && - (s->all_fragments[fragment + width].coding_method == MODE_COPY)) { - s->dsp.vp3_v_loop_filter( - plane_data + 8*x + 8*stride, - stride, bounding_values); - } - } - - fragment++; - } - plane_data += 8*stride; - } -} - -/** - * Pulls DCT tokens from the 64 levels to decode and dequant the coefficients - * for the next block in coding order - */ -static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag, - int plane, int inter, DCTELEM block[64]) -{ - int16_t *dequantizer = s->qmat[frag->qpi][inter][plane]; - uint8_t *perm = s->scantable.permutated; - int i = 0; - - do { - int token = *s->dct_tokens[plane][i]; - switch (token & 3) { - case 0: // EOB - if (--token < 4) // 0-3 are token types, so the EOB run must now be 0 - s->dct_tokens[plane][i]++; - else - *s->dct_tokens[plane][i] = token & ~3; - goto end; - case 1: // zero run - s->dct_tokens[plane][i]++; - i += (token >> 2) & 0x7f; - block[perm[i]] = (token >> 9) * dequantizer[perm[i]]; - i++; - break; - case 2: // coeff - block[perm[i]] = (token >> 2) * dequantizer[perm[i]]; - s->dct_tokens[plane][i++]++; - break; - default: // shouldn't happen - return i; - } - } while (i < 64); -end: - // the actual DC+prediction is in the fragment structure - block[0] = frag->dc * s->qmat[0][inter][plane][0]; - return i; -} - -/** - * called when all pixels up to row y are complete - */ -static void vp3_draw_horiz_band(Vp3DecodeContext *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->flipped_image) { - if (y == 0) - h -= s->height - s->avctx->height; // account for non-mod16 - y = s->height - y - h; - } - - cy = y >> 1; - offset[0] = s->current_frame.linesize[0]*y; - offset[1] = s->current_frame.linesize[1]*cy; - offset[2] = s->current_frame.linesize[2]*cy; - offset[3] = 0; - - emms_c(); - s->avctx->draw_horiz_band(s->avctx, &s->current_frame, offset, y, 3, h); - s->last_slice_end= y + h; -} - -/* - * Perform the final rendering for a particular slice of data. - * The slice number ranges from 0..(c_superblock_height - 1). - */ -static void render_slice(Vp3DecodeContext *s, int slice) -{ - int x, y, i, j; - LOCAL_ALIGNED_16(DCTELEM, block, [64]); - int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef; - int motion_halfpel_index; - uint8_t *motion_source; - int plane, first_pixel; - - if (slice >= s->c_superblock_height) - return; - - for (plane = 0; plane < 3; plane++) { - uint8_t *output_plane = s->current_frame.data [plane] + s->data_offset[plane]; - uint8_t * last_plane = s-> last_frame.data [plane] + s->data_offset[plane]; - uint8_t *golden_plane = s-> golden_frame.data [plane] + s->data_offset[plane]; - int stride = s->current_frame.linesize[plane]; - int plane_width = s->width >> (plane && s->chroma_x_shift); - int plane_height = s->height >> (plane && s->chroma_y_shift); - int8_t (*motion_val)[2] = s->motion_val[!!plane]; - - int sb_x, sb_y = slice << (!plane && s->chroma_y_shift); - int slice_height = sb_y + 1 + (!plane && s->chroma_y_shift); - int slice_width = plane ? s->c_superblock_width : s->y_superblock_width; - - int fragment_width = s->fragment_width[!!plane]; - int fragment_height = s->fragment_height[!!plane]; - int fragment_start = s->fragment_start[plane]; - - if (!s->flipped_image) stride = -stride; - if (CONFIG_GRAY && plane && (s->avctx->flags & CODEC_FLAG_GRAY)) - continue; - - - if(FFABS(stride) > 2048) - return; //various tables are fixed size - - /* for each superblock row in the slice (both of them)... */ - for (; sb_y < slice_height; sb_y++) { - - /* for each superblock in a row... */ - for (sb_x = 0; sb_x < slice_width; sb_x++) { - - /* for each block in a superblock... */ - for (j = 0; j < 16; j++) { - x = 4*sb_x + hilbert_offset[j][0]; - y = 4*sb_y + hilbert_offset[j][1]; - - i = fragment_start + y*fragment_width + x; - - // bounds check - if (x >= fragment_width || y >= fragment_height) - continue; - - first_pixel = 8*y*stride + 8*x; - - /* transform if this block was coded */ - if (s->all_fragments[i].coding_method != MODE_COPY) { - if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) || - (s->all_fragments[i].coding_method == MODE_GOLDEN_MV)) - motion_source= golden_plane; - else - motion_source= last_plane; - - motion_source += first_pixel; - motion_halfpel_index = 0; - - /* sort out the motion vector if this fragment is coded - * using a motion vector method */ - if ((s->all_fragments[i].coding_method > MODE_INTRA) && - (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) { - int src_x, src_y; - motion_x = motion_val[y*fragment_width + x][0]; - motion_y = motion_val[y*fragment_width + x][1]; - - src_x= (motion_x>>1) + 8*x; - src_y= (motion_y>>1) + 8*y; - - motion_halfpel_index = motion_x & 0x01; - motion_source += (motion_x >> 1); - - motion_halfpel_index |= (motion_y & 0x01) << 1; - motion_source += ((motion_y >> 1) * stride); - - if(src_x<0 || src_y<0 || src_x + 9 >= plane_width || src_y + 9 >= plane_height){ - uint8_t *temp= s->edge_emu_buffer; - if(stride<0) temp -= 9*stride; - else temp += 9*stride; - - ff_emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height); - motion_source= temp; - } - } - - - /* first, take care of copying a block from either the - * previous or the golden frame */ - if (s->all_fragments[i].coding_method != MODE_INTRA) { - /* Note, it is possible to implement all MC cases with - put_no_rnd_pixels_l2 which would look more like the - VP3 source but this would be slower as - put_no_rnd_pixels_tab is better optimzed */ - if(motion_halfpel_index != 3){ - s->dsp.put_no_rnd_pixels_tab[1][motion_halfpel_index]( - output_plane + first_pixel, - motion_source, stride, 8); - }else{ - int d= (motion_x ^ motion_y)>>31; // d is 0 if motion_x and _y have the same sign, else -1 - s->dsp.put_no_rnd_pixels_l2[1]( - output_plane + first_pixel, - motion_source - d, - motion_source + stride + 1 + d, - stride, 8); - } - } - - s->dsp.clear_block(block); - - /* invert DCT and place (or add) in final output */ - - if (s->all_fragments[i].coding_method == MODE_INTRA) { - vp3_dequant(s, s->all_fragments + i, plane, 0, block); - if(s->avctx->idct_algo!=FF_IDCT_VP3) - block[0] += 128<<3; - s->dsp.idct_put( - output_plane + first_pixel, - stride, - block); - } else { - if (vp3_dequant(s, s->all_fragments + i, plane, 1, block)) { - s->dsp.idct_add( - output_plane + first_pixel, - stride, - block); - } else { - s->dsp.vp3_idct_dc_add(output_plane + first_pixel, stride, block); - } - } - } else { - - /* copy directly from the previous frame */ - s->dsp.put_pixels_tab[1][0]( - output_plane + first_pixel, - last_plane + first_pixel, - stride, 8); - - } - } - } - - // Filter up to the last row in the superblock row - apply_loop_filter(s, plane, 4*sb_y - !!sb_y, FFMIN(4*sb_y+3, fragment_height-1)); - } - } - - /* this looks like a good place for slice dispatch... */ - /* algorithm: - * if (slice == s->macroblock_height - 1) - * dispatch (both last slice & 2nd-to-last slice); - * else if (slice > 0) - * dispatch (slice - 1); - */ - - vp3_draw_horiz_band(s, FFMIN(64*slice + 64-16, s->height-16)); -} - -/* - * This is the ffmpeg/libavcodec API init function. - */ -static av_cold int vp3_decode_init(AVCodecContext *avctx) -{ - Vp3DecodeContext *s = avctx->priv_data; - int i, inter, plane; - int c_width; - int c_height; - int y_fragment_count, c_fragment_count; - - if (avctx->codec_tag == MKTAG('V','P','3','0')) - s->version = 0; - else - s->version = 1; - - s->avctx = avctx; - s->width = FFALIGN(avctx->width, 16); - s->height = FFALIGN(avctx->height, 16); - if (avctx->pix_fmt == PIX_FMT_NONE) - avctx->pix_fmt = PIX_FMT_YUV420P; - avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; - if(avctx->idct_algo==FF_IDCT_AUTO) - avctx->idct_algo=FF_IDCT_VP3; - dsputil_init(&s->dsp, avctx); - - ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); - - /* initialize to an impossible value which will force a recalculation - * in the first frame decode */ - for (i = 0; i < 3; i++) - s->qps[i] = -1; - - avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); - - s->y_superblock_width = (s->width + 31) / 32; - s->y_superblock_height = (s->height + 31) / 32; - s->y_superblock_count = s->y_superblock_width * s->y_superblock_height; - - /* work out the dimensions for the C planes */ - c_width = s->width >> s->chroma_x_shift; - c_height = s->height >> s->chroma_y_shift; - s->c_superblock_width = (c_width + 31) / 32; - s->c_superblock_height = (c_height + 31) / 32; - s->c_superblock_count = s->c_superblock_width * s->c_superblock_height; - - s->superblock_count = s->y_superblock_count + (s->c_superblock_count * 2); - s->u_superblock_start = s->y_superblock_count; - s->v_superblock_start = s->u_superblock_start + s->c_superblock_count; - s->superblock_coding = av_malloc(s->superblock_count); - - s->macroblock_width = (s->width + 15) / 16; - s->macroblock_height = (s->height + 15) / 16; - s->macroblock_count = s->macroblock_width * s->macroblock_height; - - s->fragment_width[0] = s->width / FRAGMENT_PIXELS; - s->fragment_height[0] = s->height / FRAGMENT_PIXELS; - s->fragment_width[1] = s->fragment_width[0] >> s->chroma_x_shift; - s->fragment_height[1] = s->fragment_height[0] >> s->chroma_y_shift; - - /* fragment count covers all 8x8 blocks for all 3 planes */ - y_fragment_count = s->fragment_width[0] * s->fragment_height[0]; - c_fragment_count = s->fragment_width[1] * s->fragment_height[1]; - s->fragment_count = y_fragment_count + 2*c_fragment_count; - s->fragment_start[1] = y_fragment_count; - s->fragment_start[2] = y_fragment_count + c_fragment_count; - - s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment)); - s->coded_fragment_list[0] = av_malloc(s->fragment_count * sizeof(int)); - s->dct_tokens_base = av_malloc(64*s->fragment_count * sizeof(*s->dct_tokens_base)); - s->motion_val[0] = av_malloc(y_fragment_count * sizeof(*s->motion_val[0])); - s->motion_val[1] = av_malloc(c_fragment_count * sizeof(*s->motion_val[1])); - - if (!s->superblock_coding || !s->all_fragments || !s->dct_tokens_base || - !s->coded_fragment_list[0] || !s->motion_val[0] || !s->motion_val[1]) { - vp3_decode_end(avctx); - return -1; - } - - if (!s->theora_tables) - { - for (i = 0; i < 64; i++) { - s->coded_dc_scale_factor[i] = vp31_dc_scale_factor[i]; - s->coded_ac_scale_factor[i] = vp31_ac_scale_factor[i]; - s->base_matrix[0][i] = vp31_intra_y_dequant[i]; - s->base_matrix[1][i] = vp31_intra_c_dequant[i]; - s->base_matrix[2][i] = vp31_inter_dequant[i]; - s->filter_limit_values[i] = vp31_filter_limit_values[i]; - } - - for(inter=0; inter<2; inter++){ - for(plane=0; plane<3; plane++){ - s->qr_count[inter][plane]= 1; - s->qr_size [inter][plane][0]= 63; - s->qr_base [inter][plane][0]= - s->qr_base [inter][plane][1]= 2*inter + (!!plane)*!inter; - } - } - - /* init VLC tables */ - for (i = 0; i < 16; i++) { - - /* DC histograms */ - init_vlc(&s->dc_vlc[i], 11, 32, - &dc_bias[i][0][1], 4, 2, - &dc_bias[i][0][0], 4, 2, 0); - - /* group 1 AC histograms */ - init_vlc(&s->ac_vlc_1[i], 11, 32, - &ac_bias_0[i][0][1], 4, 2, - &ac_bias_0[i][0][0], 4, 2, 0); - - /* group 2 AC histograms */ - init_vlc(&s->ac_vlc_2[i], 11, 32, - &ac_bias_1[i][0][1], 4, 2, - &ac_bias_1[i][0][0], 4, 2, 0); - - /* group 3 AC histograms */ - init_vlc(&s->ac_vlc_3[i], 11, 32, - &ac_bias_2[i][0][1], 4, 2, - &ac_bias_2[i][0][0], 4, 2, 0); - - /* group 4 AC histograms */ - init_vlc(&s->ac_vlc_4[i], 11, 32, - &ac_bias_3[i][0][1], 4, 2, - &ac_bias_3[i][0][0], 4, 2, 0); - } - } else { - - for (i = 0; i < 16; i++) { - /* DC histograms */ - if (init_vlc(&s->dc_vlc[i], 11, 32, - &s->huffman_table[i][0][1], 8, 4, - &s->huffman_table[i][0][0], 8, 4, 0) < 0) - goto vlc_fail; - - /* group 1 AC histograms */ - if (init_vlc(&s->ac_vlc_1[i], 11, 32, - &s->huffman_table[i+16][0][1], 8, 4, - &s->huffman_table[i+16][0][0], 8, 4, 0) < 0) - goto vlc_fail; - - /* group 2 AC histograms */ - if (init_vlc(&s->ac_vlc_2[i], 11, 32, - &s->huffman_table[i+16*2][0][1], 8, 4, - &s->huffman_table[i+16*2][0][0], 8, 4, 0) < 0) - goto vlc_fail; - - /* group 3 AC histograms */ - if (init_vlc(&s->ac_vlc_3[i], 11, 32, - &s->huffman_table[i+16*3][0][1], 8, 4, - &s->huffman_table[i+16*3][0][0], 8, 4, 0) < 0) - goto vlc_fail; - - /* group 4 AC histograms */ - if (init_vlc(&s->ac_vlc_4[i], 11, 32, - &s->huffman_table[i+16*4][0][1], 8, 4, - &s->huffman_table[i+16*4][0][0], 8, 4, 0) < 0) - goto vlc_fail; - } - } - - init_vlc(&s->superblock_run_length_vlc, 6, 34, - &superblock_run_length_vlc_table[0][1], 4, 2, - &superblock_run_length_vlc_table[0][0], 4, 2, 0); - - init_vlc(&s->fragment_run_length_vlc, 5, 30, - &fragment_run_length_vlc_table[0][1], 4, 2, - &fragment_run_length_vlc_table[0][0], 4, 2, 0); - - init_vlc(&s->mode_code_vlc, 3, 8, - &mode_code_vlc_table[0][1], 2, 1, - &mode_code_vlc_table[0][0], 2, 1, 0); - - init_vlc(&s->motion_vector_vlc, 6, 63, - &motion_vector_vlc_table[0][1], 2, 1, - &motion_vector_vlc_table[0][0], 2, 1, 0); - - /* work out the block mapping tables */ - s->superblock_fragments = av_malloc(s->superblock_count * 16 * sizeof(int)); - s->macroblock_coding = av_malloc(s->macroblock_count + 1); - if (!s->superblock_fragments || !s->macroblock_coding) { - vp3_decode_end(avctx); - return -1; - } - init_block_mapping(s); - - for (i = 0; i < 3; i++) { - s->current_frame.data[i] = NULL; - s->last_frame.data[i] = NULL; - s->golden_frame.data[i] = NULL; - } - - return 0; - -vlc_fail: - av_log(avctx, AV_LOG_FATAL, "Invalid huffman table\n"); - return -1; -} - -/* - * This is the ffmpeg/libavcodec API frame decode function. - */ -static int vp3_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - Vp3DecodeContext *s = avctx->priv_data; - GetBitContext gb; - static int counter = 0; - int i; - - init_get_bits(&gb, buf, buf_size * 8); - - if (s->theora && get_bits1(&gb)) - { - av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n"); - return -1; - } - - s->keyframe = !get_bits1(&gb); - if (!s->theora) - skip_bits(&gb, 1); - for (i = 0; i < 3; i++) - s->last_qps[i] = s->qps[i]; - - s->nqps=0; - do{ - s->qps[s->nqps++]= get_bits(&gb, 6); - } while(s->theora >= 0x030200 && s->nqps<3 && get_bits1(&gb)); - for (i = s->nqps; i < 3; i++) - s->qps[i] = -1; - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n", - s->keyframe?"key":"", counter, s->qps[0]); - counter++; - - if (s->qps[0] != s->last_qps[0]) - init_loop_filter(s); - - for (i = 0; i < s->nqps; i++) - // reinit all dequantizers if the first one changed, because - // the DC of the first quantizer must be used for all matrices - if (s->qps[i] != s->last_qps[i] || s->qps[0] != s->last_qps[0]) - init_dequantizer(s, i); - - if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe) - return buf_size; - - s->current_frame.reference = 3; - s->current_frame.pict_type = s->keyframe ? FF_I_TYPE : FF_P_TYPE; - if (avctx->get_buffer(avctx, &s->current_frame) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - goto error; - } - - if (s->keyframe) { - if (!s->theora) - { - skip_bits(&gb, 4); /* width code */ - skip_bits(&gb, 4); /* height code */ - if (s->version) - { - s->version = get_bits(&gb, 5); - if (counter == 1) - av_log(s->avctx, AV_LOG_DEBUG, "VP version: %d\n", s->version); - } - } - if (s->version || s->theora) - { - if (get_bits1(&gb)) - av_log(s->avctx, AV_LOG_ERROR, "Warning, unsupported keyframe coding type?!\n"); - skip_bits(&gb, 2); /* reserved? */ - } - } else { - if (!s->golden_frame.data[0]) { - av_log(s->avctx, AV_LOG_WARNING, "vp3: first frame not a keyframe\n"); - - s->golden_frame.reference = 3; - s->golden_frame.pict_type = FF_I_TYPE; - if (avctx->get_buffer(avctx, &s->golden_frame) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - goto error; - } - s->last_frame = s->golden_frame; - s->last_frame.type = FF_BUFFER_TYPE_COPY; - } - } - - s->current_frame.qscale_table= s->qscale_table; //FIXME allocate individual tables per AVFrame - s->current_frame.qstride= 0; - - memset(s->all_fragments, 0, s->fragment_count * sizeof(Vp3Fragment)); - - if (unpack_superblocks(s, &gb)){ - av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n"); - goto error; - } - if (unpack_modes(s, &gb)){ - av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n"); - goto error; - } - if (unpack_vectors(s, &gb)){ - av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n"); - goto error; - } - if (unpack_block_qpis(s, &gb)){ - av_log(s->avctx, AV_LOG_ERROR, "error in unpack_block_qpis\n"); - goto error; - } - if (unpack_dct_coeffs(s, &gb)){ - av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n"); - goto error; - } - - for (i = 0; i < 3; i++) { - int height = s->height >> (i && s->chroma_y_shift); - if (s->flipped_image) - s->data_offset[i] = 0; - else - s->data_offset[i] = (height-1) * s->current_frame.linesize[i]; - } - - s->last_slice_end = 0; - for (i = 0; i < s->c_superblock_height; i++) - render_slice(s, i); - - // filter the last row - for (i = 0; i < 3; i++) { - int row = (s->height >> (3+(i && s->chroma_y_shift))) - 1; - apply_loop_filter(s, i, row, row+1); - } - vp3_draw_horiz_band(s, s->height); - - *data_size=sizeof(AVFrame); - *(AVFrame*)data= s->current_frame; - - /* release the last frame, if it is allocated and if it is not the - * golden frame */ - if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY) - avctx->release_buffer(avctx, &s->last_frame); - - /* shuffle frames (last = current) */ - s->last_frame= s->current_frame; - - if (s->keyframe) { - if (s->golden_frame.data[0]) - avctx->release_buffer(avctx, &s->golden_frame); - s->golden_frame = s->current_frame; - s->last_frame.type = FF_BUFFER_TYPE_COPY; - } - - s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */ - - return buf_size; - -error: - if (s->current_frame.data[0]) - avctx->release_buffer(avctx, &s->current_frame); - return -1; -} - -/* - * This is the ffmpeg/libavcodec API module cleanup function. - */ -static av_cold int vp3_decode_end(AVCodecContext *avctx) -{ - Vp3DecodeContext *s = avctx->priv_data; - int i; - - av_free(s->superblock_coding); - av_free(s->all_fragments); - av_free(s->coded_fragment_list[0]); - av_free(s->dct_tokens_base); - av_free(s->superblock_fragments); - av_free(s->macroblock_coding); - av_free(s->motion_val[0]); - av_free(s->motion_val[1]); - - for (i = 0; i < 16; i++) { - free_vlc(&s->dc_vlc[i]); - free_vlc(&s->ac_vlc_1[i]); - free_vlc(&s->ac_vlc_2[i]); - free_vlc(&s->ac_vlc_3[i]); - free_vlc(&s->ac_vlc_4[i]); - } - - free_vlc(&s->superblock_run_length_vlc); - free_vlc(&s->fragment_run_length_vlc); - free_vlc(&s->mode_code_vlc); - free_vlc(&s->motion_vector_vlc); - - /* release all frames */ - if (s->golden_frame.data[0]) - avctx->release_buffer(avctx, &s->golden_frame); - if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY) - avctx->release_buffer(avctx, &s->last_frame); - /* no need to release the current_frame since it will always be pointing - * to the same frame as either the golden or last frame */ - - return 0; -} - -static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) -{ - Vp3DecodeContext *s = avctx->priv_data; - - if (get_bits1(gb)) { - int token; - if (s->entries >= 32) { /* overflow */ - av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); - return -1; - } - token = get_bits(gb, 5); - //av_log(avctx, AV_LOG_DEBUG, "hti %d hbits %x token %d entry : %d size %d\n", s->hti, s->hbits, token, s->entries, s->huff_code_size); - s->huffman_table[s->hti][token][0] = s->hbits; - s->huffman_table[s->hti][token][1] = s->huff_code_size; - s->entries++; - } - else { - if (s->huff_code_size >= 32) {/* overflow */ - av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); - return -1; - } - s->huff_code_size++; - s->hbits <<= 1; - if (read_huffman_tree(avctx, gb)) - return -1; - s->hbits |= 1; - if (read_huffman_tree(avctx, gb)) - return -1; - s->hbits >>= 1; - s->huff_code_size--; - } - return 0; -} - -#if CONFIG_THEORA_DECODER -static const enum PixelFormat theora_pix_fmts[4] = { - PIX_FMT_YUV420P, PIX_FMT_NONE, PIX_FMT_YUV422P, PIX_FMT_YUV444P -}; - -static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) -{ - Vp3DecodeContext *s = avctx->priv_data; - int visible_width, visible_height, colorspace; - int offset_x = 0, offset_y = 0; - AVRational fps; - - s->theora = get_bits_long(gb, 24); - av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora); - - /* 3.2.0 aka alpha3 has the same frame orientation as original vp3 */ - /* but previous versions have the image flipped relative to vp3 */ - if (s->theora < 0x030200) - { - s->flipped_image = 1; - av_log(avctx, AV_LOG_DEBUG, "Old (width = get_bits(gb, 16) << 4; - visible_height = s->height = get_bits(gb, 16) << 4; - - if(avcodec_check_dimensions(avctx, s->width, s->height)){ - av_log(avctx, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", s->width, s->height); - s->width= s->height= 0; - return -1; - } - - if (s->theora >= 0x030200) { - visible_width = get_bits_long(gb, 24); - visible_height = get_bits_long(gb, 24); - - offset_x = get_bits(gb, 8); /* offset x */ - offset_y = get_bits(gb, 8); /* offset y, from bottom */ - } - - fps.num = get_bits_long(gb, 32); - fps.den = get_bits_long(gb, 32); - if (fps.num && fps.den) { - av_reduce(&avctx->time_base.num, &avctx->time_base.den, - fps.den, fps.num, 1<<30); - } - - avctx->sample_aspect_ratio.num = get_bits_long(gb, 24); - avctx->sample_aspect_ratio.den = get_bits_long(gb, 24); - - if (s->theora < 0x030200) - skip_bits(gb, 5); /* keyframe frequency force */ - colorspace = get_bits(gb, 8); - skip_bits(gb, 24); /* bitrate */ - - skip_bits(gb, 6); /* quality hint */ - - if (s->theora >= 0x030200) - { - skip_bits(gb, 5); /* keyframe frequency force */ - avctx->pix_fmt = theora_pix_fmts[get_bits(gb, 2)]; - skip_bits(gb, 3); /* reserved */ - } - -// align_get_bits(gb); - - if ( visible_width <= s->width && visible_width > s->width-16 - && visible_height <= s->height && visible_height > s->height-16 - && !offset_x && (offset_y == s->height - visible_height)) - avcodec_set_dimensions(avctx, visible_width, visible_height); - else - avcodec_set_dimensions(avctx, s->width, s->height); - - if (colorspace == 1) { - avctx->color_primaries = AVCOL_PRI_BT470M; - } else if (colorspace == 2) { - avctx->color_primaries = AVCOL_PRI_BT470BG; - } - if (colorspace == 1 || colorspace == 2) { - avctx->colorspace = AVCOL_SPC_BT470BG; - avctx->color_trc = AVCOL_TRC_BT709; - } - - return 0; -} - -static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) -{ - Vp3DecodeContext *s = avctx->priv_data; - int i, n, matrices, inter, plane; - - if (s->theora >= 0x030200) { - n = get_bits(gb, 3); - /* loop filter limit values table */ - for (i = 0; i < 64; i++) { - s->filter_limit_values[i] = get_bits(gb, n); - if (s->filter_limit_values[i] > 127) { - av_log(avctx, AV_LOG_ERROR, "filter limit value too large (%i > 127), clamping\n", s->filter_limit_values[i]); - s->filter_limit_values[i] = 127; - } - } - } - - if (s->theora >= 0x030200) - n = get_bits(gb, 4) + 1; - else - n = 16; - /* quality threshold table */ - for (i = 0; i < 64; i++) - s->coded_ac_scale_factor[i] = get_bits(gb, n); - - if (s->theora >= 0x030200) - n = get_bits(gb, 4) + 1; - else - n = 16; - /* dc scale factor table */ - for (i = 0; i < 64; i++) - s->coded_dc_scale_factor[i] = get_bits(gb, n); - - if (s->theora >= 0x030200) - matrices = get_bits(gb, 9) + 1; - else - matrices = 3; - - if(matrices > 384){ - av_log(avctx, AV_LOG_ERROR, "invalid number of base matrixes\n"); - return -1; - } - - for(n=0; nbase_matrix[n][i]= get_bits(gb, 8); - } - - for (inter = 0; inter <= 1; inter++) { - for (plane = 0; plane <= 2; plane++) { - int newqr= 1; - if (inter || plane > 0) - newqr = get_bits1(gb); - if (!newqr) { - int qtj, plj; - if(inter && get_bits1(gb)){ - qtj = 0; - plj = plane; - }else{ - qtj= (3*inter + plane - 1) / 3; - plj= (plane + 2) % 3; - } - s->qr_count[inter][plane]= s->qr_count[qtj][plj]; - memcpy(s->qr_size[inter][plane], s->qr_size[qtj][plj], sizeof(s->qr_size[0][0])); - memcpy(s->qr_base[inter][plane], s->qr_base[qtj][plj], sizeof(s->qr_base[0][0])); - } else { - int qri= 0; - int qi = 0; - - for(;;){ - i= get_bits(gb, av_log2(matrices-1)+1); - if(i>= matrices){ - av_log(avctx, AV_LOG_ERROR, "invalid base matrix index\n"); - return -1; - } - s->qr_base[inter][plane][qri]= i; - if(qi >= 63) - break; - i = get_bits(gb, av_log2(63-qi)+1) + 1; - s->qr_size[inter][plane][qri++]= i; - qi += i; - } - - if (qi > 63) { - av_log(avctx, AV_LOG_ERROR, "invalid qi %d > 63\n", qi); - return -1; - } - s->qr_count[inter][plane]= qri; - } - } - } - - /* Huffman tables */ - for (s->hti = 0; s->hti < 80; s->hti++) { - s->entries = 0; - s->huff_code_size = 1; - if (!get_bits1(gb)) { - s->hbits = 0; - if(read_huffman_tree(avctx, gb)) - return -1; - s->hbits = 1; - if(read_huffman_tree(avctx, gb)) - return -1; - } - } - - s->theora_tables = 1; - - return 0; -} - -static av_cold int theora_decode_init(AVCodecContext *avctx) -{ - Vp3DecodeContext *s = avctx->priv_data; - GetBitContext gb; - int ptype; - uint8_t *header_start[3]; - int header_len[3]; - int i; - - s->theora = 1; - - if (!avctx->extradata_size) - { - av_log(avctx, AV_LOG_ERROR, "Missing extradata!\n"); - return -1; - } - - if (ff_split_xiph_headers(avctx->extradata, avctx->extradata_size, - 42, header_start, header_len) < 0) { - av_log(avctx, AV_LOG_ERROR, "Corrupt extradata\n"); - return -1; - } - - for(i=0;i<3;i++) { - init_get_bits(&gb, header_start[i], header_len[i] * 8); - - ptype = get_bits(&gb, 8); - - if (!(ptype & 0x80)) - { - av_log(avctx, AV_LOG_ERROR, "Invalid extradata!\n"); -// return -1; - } - - // FIXME: Check for this as well. - skip_bits_long(&gb, 6*8); /* "theora" */ - - switch(ptype) - { - case 0x80: - theora_decode_header(avctx, &gb); - break; - case 0x81: -// FIXME: is this needed? it breaks sometimes -// theora_decode_comments(avctx, gb); - break; - case 0x82: - if (theora_decode_tables(avctx, &gb)) - return -1; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown Theora config packet: %d\n", ptype&~0x80); - break; - } - if(ptype != 0x81 && 8*header_len[i] != get_bits_count(&gb)) - av_log(avctx, AV_LOG_WARNING, "%d bits left in packet %X\n", 8*header_len[i] - get_bits_count(&gb), ptype); - if (s->theora < 0x030200) - break; - } - - return vp3_decode_init(avctx); -} - -AVCodec theora_decoder = { - "theora", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_THEORA, - sizeof(Vp3DecodeContext), - theora_decode_init, - NULL, - vp3_decode_end, - vp3_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("Theora"), -}; -#endif - -AVCodec vp3_decoder = { - "vp3", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VP3, - sizeof(Vp3DecodeContext), - vp3_decode_init, - NULL, - vp3_decode_end, - vp3_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vp3_parser.c b/tizen/distrib/ffmpeg/libavcodec/vp3_parser.c deleted file mode 100644 index c22e6dd..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp3_parser.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "parser.h" - -static int parse(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - if(avctx->codec_id == CODEC_ID_THEORA) - s->pict_type= (buf[0]&0x40) ? FF_P_TYPE : FF_I_TYPE; - else - s->pict_type= (buf[0]&0x80) ? FF_P_TYPE : FF_I_TYPE; - - *poutbuf = buf; - *poutbuf_size = buf_size; - return buf_size; -} - -AVCodecParser vp3_parser = { - { CODEC_ID_THEORA, CODEC_ID_VP3, - CODEC_ID_VP6, CODEC_ID_VP6F, CODEC_ID_VP6A }, - 0, - NULL, - parse, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vp3data.h b/tizen/distrib/ffmpeg/libavcodec/vp3data.h deleted file mode 100644 index 904ec6a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp3data.h +++ /dev/null @@ -1,3181 +0,0 @@ -/* - * copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VP3DATA_H -#define AVCODEC_VP3DATA_H - -#include -#include - -/* these coefficients dequantize intraframe Y plane coefficients - * (note: same as JPEG) */ -static const int16_t vp31_intra_y_dequant[64] = -{ 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 58, 68, 109, 103, 77, - 24, 35, 55, 64, 81, 104, 113, 92, - 49, 64, 78, 87, 103, 121, 120, 101, - 72, 92, 95, 98, 112, 100, 103, 99 -}; - -/* these coefficients dequantize intraframe C plane coefficients - * (note: same as JPEG) */ -static const int16_t vp31_intra_c_dequant[64] = -{ 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 -}; - -/* these coefficients dequantize interframe coefficients (all planes) */ -static const int16_t vp31_inter_dequant[64] = -{ 16, 16, 16, 20, 24, 28, 32, 40, - 16, 16, 20, 24, 28, 32, 40, 48, - 16, 20, 24, 28, 32, 40, 48, 64, - 20, 24, 28, 32, 40, 48, 64, 64, - 24, 28, 32, 40, 48, 64, 64, 64, - 28, 32, 40, 48, 64, 64, 64, 96, - 32, 40, 48, 64, 64, 64, 96, 128, - 40, 48, 64, 64, 64, 96, 128, 128 -}; - -static const int16_t vp31_dc_scale_factor[64] = -{ 220, 200, 190, 180, 170, 170, 160, 160, - 150, 150, 140, 140, 130, 130, 120, 120, - 110, 110, 100, 100, 90, 90, 90, 80, - 80, 80, 70, 70, 70, 60, 60, 60, - 60, 50, 50, 50, 50, 40, 40, 40, - 40, 40, 30, 30, 30, 30, 30, 30, - 30, 20, 20, 20, 20, 20, 20, 20, - 20, 10, 10, 10, 10, 10, 10, 10 -}; - -static const uint32_t vp31_ac_scale_factor[64] = -{ 500, 450, 400, 370, 340, 310, 285, 265, - 245, 225, 210, 195, 185, 180, 170, 160, - 150, 145, 135, 130, 125, 115, 110, 107, - 100, 96, 93, 89, 85, 82, 75, 74, - 70, 68, 64, 60, 57, 56, 52, 50, - 49, 45, 44, 43, 40, 38, 37, 35, - 33, 32, 30, 29, 28, 25, 24, 22, - 21, 19, 18, 17, 15, 13, 12, 10 -}; - -static const uint8_t vp31_filter_limit_values[64] = -{ 30, 25, 20, 20, 15, 15, 14, 14, - 13, 13, 12, 12, 11, 11, 10, 10, - 9, 9, 8, 8, 7, 7, 7, 7, - 6, 6, 6, 6, 5, 5, 5, 5, - 4, 4, 4, 4, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static const uint16_t superblock_run_length_vlc_table[34][2] = { - { 0, 1 }, - - { 4, 3 }, { 5, 3 }, - - { 0xC, 4 }, { 0xD, 4 }, - - { 0x38, 6 }, { 0x39, 6 }, { 0x3A, 6 }, { 0x3B, 6 }, - - { 0xF0, 8 }, { 0xF1, 8 }, { 0xF2, 8 }, { 0xF3, 8 }, - { 0xF4, 8 }, { 0xF5, 8 }, { 0xF6, 8 }, { 0xF7, 8 }, - - { 0x3E0, 10 }, { 0x3E1, 10 }, { 0x3E2, 10 }, { 0x3E3, 10 }, - { 0x3E4, 10 }, { 0x3E5, 10 }, { 0x3E6, 10 }, { 0x3E7, 10 }, - { 0x3E8, 10 }, { 0x3E9, 10 }, { 0x3EA, 10 }, { 0x3EB, 10 }, - { 0x3EC, 10 }, { 0x3ED, 10 }, { 0x3EE, 10 }, { 0x3EF, 10 }, - - { 0x3F, 6 } /* this last VLC is a special case for reading 12 more - bits from stream and adding the value 34 */ -}; - -static const uint16_t fragment_run_length_vlc_table[30][2] = { - /* 1 -> 2 */ - { 0x0, 2 }, { 0x1, 2 }, - - /* 3 -> 4 */ - { 0x4, 3 }, { 0x5, 3 }, - - /* 5 -> 6 */ - { 0xC, 4 }, { 0xD, 4 }, - - /* 7 -> 10 */ - { 0x38, 6 }, { 0x39, 6 }, - { 0x3A, 6 }, { 0x3B, 6 }, - - /* 11 -> 14 */ - { 0x78, 7 }, { 0x79, 7 }, - { 0x7A, 7 }, { 0x7B, 7 }, - - /* 15 -> 30 */ - { 0x1F0, 9 }, { 0x1F1, 9 }, { 0x1F2, 9 }, { 0x1F3, 9 }, - { 0x1F4, 9 }, { 0x1F5, 9 }, { 0x1F6, 9 }, { 0x1F7, 9 }, - { 0x1F8, 9 }, { 0x1F9, 9 }, { 0x1FA, 9 }, { 0x1FB, 9 }, - { 0x1FC, 9 }, { 0x1FD, 9 }, { 0x1FE, 9 }, { 0x1FF, 9 } -}; - -static const uint8_t mode_code_vlc_table[8][2] = { - { 0, 1 }, { 2, 2 }, - { 6, 3 }, { 14, 4 }, - { 30, 5 }, { 62, 6 }, - { 126, 7 }, { 127, 7 } -}; - -static const uint8_t motion_vector_vlc_table[63][2] = { - { 0, 3 }, - { 1, 3 }, - { 2, 3 }, - - { 6, 4 }, { 7, 4 }, - - { 8, 4 }, { 9, 4 }, - - { 40, 6 }, { 41, 6 }, { 42, 6 }, { 43, 6 }, - { 44, 6 }, { 45, 6 }, { 46, 6 }, { 47, 6 }, - - { 96, 7 }, { 97, 7 }, { 98, 7 }, { 99, 7 }, - { 100, 7 }, { 101, 7 }, { 102, 7 }, { 103, 7 }, - { 104, 7 }, { 105, 7 }, { 106, 7 }, { 107, 7 }, - { 108, 7 }, { 109, 7 }, { 110, 7 }, { 111, 7 }, - - { 0xE0, 8 }, { 0xE1, 8 }, { 0xE2, 8 }, { 0xE3, 8 }, - { 0xE4, 8 }, { 0xE5, 8 }, { 0xE6, 8 }, { 0xE7, 8 }, - { 0xE8, 8 }, { 0xE9, 8 }, { 0xEA, 8 }, { 0xEB, 8 }, - { 0xEC, 8 }, { 0xED, 8 }, { 0xEE, 8 }, { 0xEF, 8 }, - - { 0xF0, 8 }, { 0xF1, 8 }, { 0xF2, 8 }, { 0xF3, 8 }, - { 0xF4, 8 }, { 0xF5, 8 }, { 0xF6, 8 }, { 0xF7, 8 }, - { 0xF8, 8 }, { 0xF9, 8 }, { 0xFA, 8 }, { 0xFB, 8 }, - { 0xFC, 8 }, { 0xFD, 8 }, { 0xFE, 8 }, { 0xFF, 8 } -}; - -static const int motion_vector_table[63] = { - 0, 1, -1, - 2, -2, - 3, -3, - 4, -4, 5, -5, 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, 19, -19, 20, -20, 21, -21, 22, -22, 23, -23, - 24, -24, 25, -25, 26, -26, 27, -27, 28, -28, 29, -29, 30, -30, 31, -31 -}; - -static const int8_t fixed_motion_vector_table[64] = { - 0, 0, 1, -1, 2, -2, 3, -3, - 4, -4, 5, -5, 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, 19, -19, - 20, -20, 21, -21, 22, -22, 23, -23, - 24, -24, 25, -25, 26, -26, 27, -27, - 28, -28, 29, -29, 30, -30, 31, -31 -}; - -/* only tokens 0..6 indicate eob runs */ -static const int eob_run_base[7] = { - 1, 2, 3, 4, 8, 16, 0 -}; -static const int eob_run_get_bits[7] = { - 0, 0, 0, 2, 3, 4, 12 -}; - -static const int zero_run_base[32] = { - 0, 0, 0, 0, 0, 0, 0, /* 0..6 are never used */ - 0, 0, /* 7..8 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9..22 */ - 1, 2, 3, 4, 5, /* 23..27 */ - 6, 10, 1, 2 /* 28..31 */ -}; -static const int zero_run_get_bits[32] = { - 0, 0, 0, 0, 0, 0, 0, /* 0..6 are never used */ - 3, 6, /* 7..8 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9..22 */ - 0, 0, 0, 0, 0, /* 23..27 */ - 2, 3, 0, 1 /* 28..31 */ -}; - -static const int coeff_get_bits[32] = { - 0, 0, 0, 0, 0, 0, 0, /* 0..6 are never used */ - 0, 0, 0, 0, 0, 0, /* 7..12 use constant coeffs */ - 1, 1, 1, 1, /* 13..16 are constants but still need sign bit */ - 2, 3, 4, 5, 6, 10, /* 17..22, for reading large coeffs */ - 1, 1, 1, 1, 1, 1, 1, /* 23..29 are constants but still need sign bit */ - 2, 2 /* 30..31 */ -}; - -static const int16_t coeff_table_token_7_8[1] = { 0 }; -static const int16_t coeff_table_token_9[1] = { 1 }; -static const int16_t coeff_table_token_10[1] = { -1 }; -static const int16_t coeff_table_token_11[1] = { 2 }; -static const int16_t coeff_table_token_12[1] = { -2 }; - -static const int16_t coeff_table_token_13[2] = { 3, -3 }; -static const int16_t coeff_table_token_14[2] = { 4, -4 }; -static const int16_t coeff_table_token_15[2] = { 5, -5 }; -static const int16_t coeff_table_token_16[2] = { 6, -6 }; - -static const int16_t coeff_table_token_23_24_25_26_27_28_29[2] = { 1, -1 }; -static const int16_t coeff_table_token_30[4] = { 2, 3, -2, -3 }; -static const int16_t coeff_table_token_31[4] = { 2, 3, -2, -3 }; - -static const int16_t coeff_table_token_17[4] = { - 7, 8, -7, -8 -}; - -static const int16_t coeff_table_token_18[8] = { - 9, 10, 11, 12, -9, -10, -11, -12 -}; - -static const int16_t coeff_table_token_19[16] = { - 13, 14, 15, 16, 17, 18, 19, 20, -13, -14, -15, -16, -17, -18, -19, -20 -}; - -static const int16_t coeff_table_token_20[32] = { - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, - -21, -22, -23, -24, -25, -26, -27, -28, - -29, -30, -31, -32, -33, -34, -35, -36 -}; - -static const int16_t coeff_table_token_21[64] = { - 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, - -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 -}; - -static const int16_t coeff_table_token_22[1024] = { - 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, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 388, - 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, - 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, 433, 434, 435, 436, - 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, 484, - 485, 486, 487, 488, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 500, - 501, 502, 503, 504, 505, 506, 507, 508, - 509, 510, 511, 512, 513, 514, 515, 516, - 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 529, 530, 531, 532, - 533, 534, 535, 536, 537, 538, 539, 540, - 541, 542, 543, 544, 545, 546, 547, 548, - 549, 550, 551, 552, 553, 554, 555, 556, - 557, 558, 559, 560, 561, 562, 563, 564, - 565, 566, 567, 568, 569, 570, 571, 572, - 573, 574, 575, 576, 577, 578, 579, 580, - -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, -256, -257, -258, -259, -260, - -261, -262, -263, -264, -265, -266, -267, -268, - -269, -270, -271, -272, -273, -274, -275, -276, - -277, -278, -279, -280, -281, -282, -283, -284, - -285, -286, -287, -288, -289, -290, -291, -292, - -293, -294, -295, -296, -297, -298, -299, -300, - -301, -302, -303, -304, -305, -306, -307, -308, - -309, -310, -311, -312, -313, -314, -315, -316, - -317, -318, -319, -320, -321, -322, -323, -324, - -325, -326, -327, -328, -329, -330, -331, -332, - -333, -334, -335, -336, -337, -338, -339, -340, - -341, -342, -343, -344, -345, -346, -347, -348, - -349, -350, -351, -352, -353, -354, -355, -356, - -357, -358, -359, -360, -361, -362, -363, -364, - -365, -366, -367, -368, -369, -370, -371, -372, - -373, -374, -375, -376, -377, -378, -379, -380, - -381, -382, -383, -384, -385, -386, -387, -388, - -389, -390, -391, -392, -393, -394, -395, -396, - -397, -398, -399, -400, -401, -402, -403, -404, - -405, -406, -407, -408, -409, -410, -411, -412, - -413, -414, -415, -416, -417, -418, -419, -420, - -421, -422, -423, -424, -425, -426, -427, -428, - -429, -430, -431, -432, -433, -434, -435, -436, - -437, -438, -439, -440, -441, -442, -443, -444, - -445, -446, -447, -448, -449, -450, -451, -452, - -453, -454, -455, -456, -457, -458, -459, -460, - -461, -462, -463, -464, -465, -466, -467, -468, - -469, -470, -471, -472, -473, -474, -475, -476, - -477, -478, -479, -480, -481, -482, -483, -484, - -485, -486, -487, -488, -489, -490, -491, -492, - -493, -494, -495, -496, -497, -498, -499, -500, - -501, -502, -503, -504, -505, -506, -507, -508, - -509, -510, -511, -512, -513, -514, -515, -516, - -517, -518, -519, -520, -521, -522, -523, -524, - -525, -526, -527, -528, -529, -530, -531, -532, - -533, -534, -535, -536, -537, -538, -539, -540, - -541, -542, -543, -544, -545, -546, -547, -548, - -549, -550, -551, -552, -553, -554, -555, -556, - -557, -558, -559, -560, -561, -562, -563, -564, - -565, -566, -567, -568, -569, -570, -571, -572, - -573, -574, -575, -576, -577, -578, -579, -580 -}; - -static const int16_t *const coeff_tables[32] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - coeff_table_token_7_8, - - coeff_table_token_7_8, - coeff_table_token_9, - coeff_table_token_10, - coeff_table_token_11, - coeff_table_token_12, - coeff_table_token_13, - coeff_table_token_14, - coeff_table_token_15, - - coeff_table_token_16, - coeff_table_token_17, - coeff_table_token_18, - coeff_table_token_19, - coeff_table_token_20, - coeff_table_token_21, - coeff_table_token_22, - coeff_table_token_23_24_25_26_27_28_29, - - coeff_table_token_23_24_25_26_27_28_29, - coeff_table_token_23_24_25_26_27_28_29, - coeff_table_token_23_24_25_26_27_28_29, - coeff_table_token_23_24_25_26_27_28_29, - coeff_table_token_23_24_25_26_27_28_29, - coeff_table_token_23_24_25_26_27_28_29, - coeff_table_token_30, - coeff_table_token_31 -}; - -static const uint16_t dc_bias[16][32][2] = { - { /* DC bias table 0 */ - { 0x2D, 6 }, - { 0x26, 7 }, - { 0x166, 9 }, - { 0x4E, 8 }, - { 0x2CE, 10 }, - { 0x59E, 11 }, - { 0x27D, 11 }, - { 0x8, 5 }, - { 0x4F9, 12 }, - { 0xF, 4 }, - { 0xE, 4 }, - { 0x1B, 5 }, - { 0x6, 4 }, - { 0x8, 4 }, - { 0x5, 4 }, - { 0x1A, 5 }, - { 0x15, 5 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x17, 5 }, - { 0x29, 6 }, - { 0x28, 6 }, - { 0xB2, 8 }, - { 0x4F8, 12 }, - { 0x59F, 11 }, - { 0x9E, 9 }, - { 0x13F, 10 }, - { 0x12, 6 }, - { 0x58, 7 } - }, - { /* DC bias table 1 */ - { 0x10, 5 }, - { 0x47, 7 }, - { 0x1FF, 9 }, - { 0x8C, 8 }, - { 0x3FC, 10 }, - { 0x46A, 11 }, - { 0x469, 11 }, - { 0x22, 6 }, - { 0x11A1, 13 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0x4, 4 }, - { 0x5, 4 }, - { 0x9, 4 }, - { 0x6, 4 }, - { 0x1E, 5 }, - { 0x16, 5 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xA, 4 }, - { 0x17, 5 }, - { 0x7D, 7 }, - { 0x7E, 7 }, - { 0x11B, 9 }, - { 0x8D1, 12 }, - { 0x3FD, 10 }, - { 0x46B, 11 }, - { 0x11A0, 13 }, - { 0x7C, 7 }, - { 0xFE, 8 } - }, - { /* DC bias table 2 */ - { 0x16, 5 }, - { 0x20, 6 }, - { 0x86, 8 }, - { 0x87, 8 }, - { 0x367, 10 }, - { 0x6CC, 11 }, - { 0x6CB, 11 }, - { 0x6E, 7 }, - { 0x366D, 14 }, - { 0xF, 4 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0x5, 4 }, - { 0xA, 4 }, - { 0x6, 4 }, - { 0x1A, 5 }, - { 0x11, 5 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x17, 5 }, - { 0x6F, 7 }, - { 0x6D, 7 }, - { 0x364, 10 }, - { 0xD9A, 12 }, - { 0x6CA, 11 }, - { 0x1B37, 13 }, - { 0x366C, 14 }, - { 0x42, 7 }, - { 0xD8, 8 } - }, - { /* DC bias table 3 */ - { 0x0, 4 }, - { 0x2D, 6 }, - { 0xF7, 8 }, - { 0x58, 7 }, - { 0x167, 9 }, - { 0x2CB, 10 }, - { 0x2CA, 10 }, - { 0xE, 6 }, - { 0x1661, 13 }, - { 0x3, 3 }, - { 0x2, 3 }, - { 0x8, 4 }, - { 0x9, 4 }, - { 0xD, 4 }, - { 0x2, 4 }, - { 0x1F, 5 }, - { 0x17, 5 }, - { 0x1, 4 }, - { 0xC, 4 }, - { 0xE, 4 }, - { 0xA, 4 }, - { 0x6, 5 }, - { 0x78, 7 }, - { 0xF, 6 }, - { 0x7A, 7 }, - { 0x164, 9 }, - { 0x599, 11 }, - { 0x2CD, 10 }, - { 0xB31, 12 }, - { 0x1660, 13 }, - { 0x79, 7 }, - { 0xF6, 8 } - }, - { /* DC bias table 4 */ - { 0x3, 4 }, - { 0x3C, 6 }, - { 0xF, 7 }, - { 0x7A, 7 }, - { 0x1D, 8 }, - { 0x20, 9 }, - { 0x72, 10 }, - { 0x6, 6 }, - { 0x399, 13 }, - { 0x4, 3 }, - { 0x5, 3 }, - { 0x5, 4 }, - { 0x6, 4 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0x0, 4 }, - { 0x19, 5 }, - { 0x2, 4 }, - { 0xD, 4 }, - { 0x7, 4 }, - { 0x1F, 5 }, - { 0x30, 6 }, - { 0x11, 8 }, - { 0x31, 6 }, - { 0x5, 6 }, - { 0x21, 9 }, - { 0xE7, 11 }, - { 0x38, 9 }, - { 0x1CD, 12 }, - { 0x398, 13 }, - { 0x7B, 7 }, - { 0x9, 7 } - }, - { /* DC bias table 5 */ - { 0x9, 4 }, - { 0x2, 5 }, - { 0x74, 7 }, - { 0x7, 6 }, - { 0xEC, 8 }, - { 0xD1, 9 }, - { 0x1A6, 10 }, - { 0x6, 6 }, - { 0xD21, 13 }, - { 0x5, 3 }, - { 0x6, 3 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0xF, 4 }, - { 0x4, 4 }, - { 0x0, 4 }, - { 0x1C, 5 }, - { 0x2, 4 }, - { 0x5, 4 }, - { 0x3, 4 }, - { 0xC, 5 }, - { 0x35, 7 }, - { 0x1A7, 10 }, - { 0x1B, 6 }, - { 0x77, 7 }, - { 0x1A5, 10 }, - { 0x349, 11 }, - { 0xD0, 9 }, - { 0x691, 12 }, - { 0xD20, 13 }, - { 0x75, 7 }, - { 0xED, 8 } - }, - { /* DC bias table 6 */ - { 0xA, 4 }, - { 0xC, 5 }, - { 0x12, 6 }, - { 0x1B, 6 }, - { 0xB7, 8 }, - { 0x16C, 9 }, - { 0x99, 9 }, - { 0x5A, 7 }, - { 0x16D8, 13 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x0, 3 }, - { 0x5, 4 }, - { 0x17, 5 }, - { 0xE, 5 }, - { 0x2, 4 }, - { 0x3, 4 }, - { 0xF, 5 }, - { 0x1A, 6 }, - { 0x4D, 8 }, - { 0x2DB3, 14 }, - { 0x2C, 6 }, - { 0x11, 6 }, - { 0x2DA, 10 }, - { 0x5B7, 11 }, - { 0x98, 9 }, - { 0xB6D, 12 }, - { 0x2DB2, 14 }, - { 0x10, 6 }, - { 0x27, 7 } - }, - { /* DC bias table 7 */ - { 0xD, 4 }, - { 0xF, 5 }, - { 0x1D, 6 }, - { 0x8, 5 }, - { 0x51, 7 }, - { 0x56, 8 }, - { 0xAF, 9 }, - { 0x2A, 7 }, - { 0x148A, 13 }, - { 0x7, 3 }, - { 0x0, 2 }, - { 0x8, 4 }, - { 0x9, 4 }, - { 0xC, 4 }, - { 0x6, 4 }, - { 0x17, 5 }, - { 0xB, 5 }, - { 0x16, 5 }, - { 0x15, 5 }, - { 0x9, 5 }, - { 0x50, 7 }, - { 0xAE, 9 }, - { 0x2917, 14 }, - { 0x1C, 6 }, - { 0x14, 6 }, - { 0x290, 10 }, - { 0x523, 11 }, - { 0x149, 9 }, - { 0xA44, 12 }, - { 0x2916, 14 }, - { 0x53, 7 }, - { 0xA5, 8 } - }, - { /* DC bias table 8 */ - { 0x1, 4 }, - { 0x1D, 6 }, - { 0xF5, 8 }, - { 0xF4, 8 }, - { 0x24D, 10 }, - { 0x499, 11 }, - { 0x498, 11 }, - { 0x1, 5 }, - { 0x21, 6 }, - { 0x6, 3 }, - { 0x5, 3 }, - { 0x6, 4 }, - { 0x5, 4 }, - { 0x2, 4 }, - { 0x7, 5 }, - { 0x25, 6 }, - { 0x7B, 7 }, - { 0x1C, 6 }, - { 0x20, 6 }, - { 0xD, 6 }, - { 0x48, 7 }, - { 0x92, 8 }, - { 0x127, 9 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0x11, 5 }, - { 0xC, 6 }, - { 0x3C, 6 }, - { 0xF, 5 }, - { 0x0, 5 }, - { 0x1F, 5 }, - { 0x13, 5 } - }, - { /* DC bias table 9 */ - { 0x5, 4 }, - { 0x3C, 6 }, - { 0x40, 7 }, - { 0xD, 7 }, - { 0x31, 9 }, - { 0x61, 10 }, - { 0x60, 10 }, - { 0x2, 5 }, - { 0xF5, 8 }, - { 0x6, 3 }, - { 0x5, 3 }, - { 0x7, 4 }, - { 0x6, 4 }, - { 0x2, 4 }, - { 0x9, 5 }, - { 0x25, 6 }, - { 0x7, 6 }, - { 0x21, 6 }, - { 0x24, 6 }, - { 0x10, 6 }, - { 0x41, 7 }, - { 0xF4, 8 }, - { 0x19, 8 }, - { 0xE, 4 }, - { 0x3, 4 }, - { 0x11, 5 }, - { 0x11, 6 }, - { 0x3F, 6 }, - { 0x3E, 6 }, - { 0x7B, 7 }, - { 0x0, 4 }, - { 0x13, 5 } - }, - { /* DC bias table 10 */ - { 0xA, 4 }, - { 0x7, 5 }, - { 0x1, 6 }, - { 0x9, 6 }, - { 0x131, 9 }, - { 0x261, 10 }, - { 0x260, 10 }, - { 0x15, 6 }, - { 0x1, 7 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0x6, 4 }, - { 0x12, 5 }, - { 0x2F, 6 }, - { 0x14, 6 }, - { 0x27, 6 }, - { 0x2D, 6 }, - { 0x16, 6 }, - { 0x4D, 7 }, - { 0x99, 8 }, - { 0x0, 7 }, - { 0x4, 4 }, - { 0x1, 4 }, - { 0x5, 5 }, - { 0x17, 6 }, - { 0x2E, 6 }, - { 0x2C, 6 }, - { 0x8, 6 }, - { 0x6, 5 }, - { 0x1, 5 } - }, - { /* DC bias table 11 */ - { 0x0, 3 }, - { 0xE, 5 }, - { 0x17, 6 }, - { 0x2A, 6 }, - { 0x10, 7 }, - { 0xF9, 10 }, - { 0xF8, 10 }, - { 0x1E, 7 }, - { 0x3F, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x6, 4 }, - { 0xF, 5 }, - { 0x5, 5 }, - { 0x16, 6 }, - { 0x29, 6 }, - { 0x2B, 6 }, - { 0x15, 6 }, - { 0x50, 7 }, - { 0x11, 7 }, - { 0x7D, 9 }, - { 0x4, 4 }, - { 0x17, 5 }, - { 0x6, 5 }, - { 0x14, 6 }, - { 0x2C, 6 }, - { 0x2D, 6 }, - { 0xE, 6 }, - { 0x9, 6 }, - { 0x51, 7 } - }, - { /* DC bias table 12 */ - { 0x2, 3 }, - { 0x18, 5 }, - { 0x2F, 6 }, - { 0xD, 5 }, - { 0x53, 7 }, - { 0x295, 10 }, - { 0x294, 10 }, - { 0xA4, 8 }, - { 0x7C, 8 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x1B, 5 }, - { 0xC, 5 }, - { 0x28, 6 }, - { 0x6A, 7 }, - { 0x1E, 6 }, - { 0x1D, 6 }, - { 0x69, 7 }, - { 0xD7, 8 }, - { 0x7D, 8 }, - { 0x14B, 9 }, - { 0x19, 5 }, - { 0x16, 5 }, - { 0x2E, 6 }, - { 0x1C, 6 }, - { 0x2B, 6 }, - { 0x2A, 6 }, - { 0x68, 7 }, - { 0x3F, 7 }, - { 0xD6, 8 } - }, - { /* DC bias table 13 */ - { 0x2, 3 }, - { 0x1B, 5 }, - { 0xC, 5 }, - { 0x18, 5 }, - { 0x29, 6 }, - { 0x7F, 8 }, - { 0x2F0, 10 }, - { 0x198, 9 }, - { 0x179, 9 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x1A, 5 }, - { 0xD, 5 }, - { 0x2A, 6 }, - { 0x64, 7 }, - { 0x1E, 6 }, - { 0x67, 7 }, - { 0x5F, 7 }, - { 0xCD, 8 }, - { 0x7E, 8 }, - { 0x2F1, 10 }, - { 0x16, 5 }, - { 0xE, 5 }, - { 0x2E, 6 }, - { 0x65, 7 }, - { 0x2B, 6 }, - { 0x28, 6 }, - { 0x3E, 7 }, - { 0xBD, 8 }, - { 0x199, 9 } - }, - { /* DC bias table 14 */ - { 0x2, 3 }, - { 0x7, 4 }, - { 0x16, 5 }, - { 0x6, 4 }, - { 0x36, 6 }, - { 0x5C, 7 }, - { 0x15D, 9 }, - { 0x15C, 9 }, - { 0x2BF, 10 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x18, 5 }, - { 0x34, 6 }, - { 0x2A, 6 }, - { 0x5E, 7 }, - { 0x6A, 7 }, - { 0x64, 7 }, - { 0x5D, 7 }, - { 0xCB, 8 }, - { 0xAD, 8 }, - { 0x2BE, 10 }, - { 0x14, 5 }, - { 0x33, 6 }, - { 0x6E, 7 }, - { 0x5F, 7 }, - { 0x6F, 7 }, - { 0x6B, 7 }, - { 0xCA, 8 }, - { 0xAC, 8 }, - { 0x15E, 9 } - }, - { /* DC bias table 15 */ - { 0xF, 4 }, - { 0x1D, 5 }, - { 0x18, 5 }, - { 0xB, 4 }, - { 0x19, 5 }, - { 0x29, 6 }, - { 0xD6, 8 }, - { 0x551, 11 }, - { 0xAA1, 12 }, - { 0x1, 2 }, - { 0x0, 2 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x1B, 5 }, - { 0x38, 6 }, - { 0x28, 6 }, - { 0x57, 7 }, - { 0x6A, 7 }, - { 0x68, 7 }, - { 0x56, 7 }, - { 0xE5, 8 }, - { 0x155, 9 }, - { 0xAA0, 12 }, - { 0x73, 7 }, - { 0x69, 7 }, - { 0xD7, 8 }, - { 0xAB, 8 }, - { 0xE4, 8 }, - { 0xA9, 8 }, - { 0x151, 9 }, - { 0x150, 9 }, - { 0x2A9, 10 } - } -}; - -static const uint16_t ac_bias_0[16][32][2] = { - { /* AC bias group 1, table 0 */ - { 0x8, 5 }, - { 0x25, 7 }, - { 0x17A, 9 }, - { 0x2F7, 10 }, - { 0xBDB, 12 }, - { 0x17B4, 13 }, - { 0x2F6B, 14 }, - { 0x1D, 5 }, - { 0x2F6A, 14 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0x1, 4 }, - { 0x2, 4 }, - { 0xA, 4 }, - { 0x6, 4 }, - { 0x0, 4 }, - { 0x1C, 5 }, - { 0x9, 4 }, - { 0xD, 4 }, - { 0xF, 4 }, - { 0xC, 4 }, - { 0x3, 4 }, - { 0xA, 5 }, - { 0x16, 5 }, - { 0x13, 6 }, - { 0x5D, 7 }, - { 0x24, 7 }, - { 0xBC, 8 }, - { 0x5C, 7 }, - { 0x5EC, 11 }, - { 0xB, 5 }, - { 0x5F, 7 } - }, - { /* AC bias group 1, table 1 */ - { 0xF, 5 }, - { 0x10, 6 }, - { 0x4B, 8 }, - { 0xC6, 8 }, - { 0x31D, 10 }, - { 0xC71, 12 }, - { 0xC70, 12 }, - { 0x1, 4 }, - { 0xC73, 12 }, - { 0x8, 4 }, - { 0x9, 4 }, - { 0x2, 4 }, - { 0x3, 4 }, - { 0xB, 4 }, - { 0x6, 4 }, - { 0x0, 4 }, - { 0x1C, 5 }, - { 0x5, 4 }, - { 0xD, 4 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0x19, 5 }, - { 0x13, 6 }, - { 0x1D, 5 }, - { 0x30, 6 }, - { 0x62, 7 }, - { 0x24, 7 }, - { 0x4A, 8 }, - { 0x18F, 9 }, - { 0xC72, 12 }, - { 0xE, 5 }, - { 0x11, 6 } - }, - { /* AC bias group 1, table 2 */ - { 0x1B, 5 }, - { 0x3, 6 }, - { 0x8D, 8 }, - { 0x40, 7 }, - { 0x239, 10 }, - { 0x471, 11 }, - { 0x8E0, 12 }, - { 0x3, 4 }, - { 0x11C3, 13 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0x4, 4 }, - { 0x5, 4 }, - { 0xE, 4 }, - { 0x7, 4 }, - { 0x1, 4 }, - { 0x1E, 5 }, - { 0x6, 4 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x2, 4 }, - { 0x0, 5 }, - { 0x41, 7 }, - { 0x1F, 5 }, - { 0x22, 6 }, - { 0x2, 6 }, - { 0x8F, 8 }, - { 0x8C, 8 }, - { 0x11D, 9 }, - { 0x11C2, 13 }, - { 0x1A, 5 }, - { 0x21, 6 } - }, - { /* AC bias group 1, table 3 */ - { 0x1F, 5 }, - { 0x3, 6 }, - { 0x3, 7 }, - { 0x43, 7 }, - { 0xB, 9 }, - { 0x15, 10 }, - { 0x51, 12 }, - { 0x3, 4 }, - { 0x50, 12 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x4, 4 }, - { 0x6, 4 }, - { 0xE, 4 }, - { 0xA, 4 }, - { 0x1, 4 }, - { 0x1E, 5 }, - { 0x5, 4 }, - { 0x9, 4 }, - { 0x7, 4 }, - { 0x11, 5 }, - { 0x2, 6 }, - { 0x4, 8 }, - { 0x2, 4 }, - { 0x2D, 6 }, - { 0x20, 6 }, - { 0x42, 7 }, - { 0x1, 7 }, - { 0x0, 7 }, - { 0x29, 11 }, - { 0x17, 5 }, - { 0x2C, 6 } - }, - { /* AC bias group 1, table 4 */ - { 0x3, 4 }, - { 0x1F, 6 }, - { 0x3A, 7 }, - { 0x5D, 7 }, - { 0x173, 9 }, - { 0x2E4, 10 }, - { 0x172D, 13 }, - { 0x4, 4 }, - { 0x172C, 13 }, - { 0xF, 4 }, - { 0xE, 4 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0xC, 4 }, - { 0xA, 4 }, - { 0x1, 4 }, - { 0x16, 5 }, - { 0x2, 4 }, - { 0x5, 4 }, - { 0x1A, 5 }, - { 0x2F, 6 }, - { 0x38, 7 }, - { 0x5CA, 11 }, - { 0x6, 4 }, - { 0x37, 6 }, - { 0x1E, 6 }, - { 0x3B, 7 }, - { 0x39, 7 }, - { 0xB8, 8 }, - { 0xB97, 12 }, - { 0x0, 4 }, - { 0x36, 6 } - }, - { /* AC bias group 1, table 5 */ - { 0x6, 4 }, - { 0x37, 6 }, - { 0x5D, 7 }, - { 0xC, 6 }, - { 0xB9, 8 }, - { 0x2E3, 10 }, - { 0x5C4, 11 }, - { 0x4, 4 }, - { 0x1715, 13 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0x8, 4 }, - { 0x7, 4 }, - { 0xC, 4 }, - { 0x9, 4 }, - { 0x1D, 5 }, - { 0x16, 5 }, - { 0x1C, 5 }, - { 0x1A, 5 }, - { 0xB, 5 }, - { 0x5E, 7 }, - { 0x170, 9 }, - { 0x1714, 13 }, - { 0xA, 4 }, - { 0xA, 5 }, - { 0x36, 6 }, - { 0x5F, 7 }, - { 0x1B, 7 }, - { 0x1A, 7 }, - { 0xB8B, 12 }, - { 0x2, 4 }, - { 0x7, 5 } - }, - { /* AC bias group 1, table 6 */ - { 0xC, 4 }, - { 0xB, 5 }, - { 0x79, 7 }, - { 0x22, 6 }, - { 0xF0, 8 }, - { 0x119, 9 }, - { 0x230, 10 }, - { 0x1D, 5 }, - { 0x8C4, 12 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0xB, 4 }, - { 0x7, 4 }, - { 0x1C, 5 }, - { 0x3D, 6 }, - { 0xD, 5 }, - { 0x8, 5 }, - { 0x15, 6 }, - { 0x8D, 8 }, - { 0x118B, 13 }, - { 0x118A, 13 }, - { 0xD, 4 }, - { 0x10, 5 }, - { 0x9, 5 }, - { 0x14, 6 }, - { 0x47, 7 }, - { 0xF1, 8 }, - { 0x463, 11 }, - { 0x1F, 5 }, - { 0xC, 5 } - }, - { /* AC bias group 1, table 7 */ - { 0x0, 3 }, - { 0x1A, 5 }, - { 0x33, 6 }, - { 0xC, 5 }, - { 0x46, 7 }, - { 0x1E3, 9 }, - { 0x3C5, 10 }, - { 0x17, 5 }, - { 0x1E21, 13 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x9, 4 }, - { 0xA, 4 }, - { 0x7, 4 }, - { 0x1B, 5 }, - { 0x3D, 6 }, - { 0x1B, 6 }, - { 0x22, 6 }, - { 0x79, 7 }, - { 0xF0, 8 }, - { 0x1E20, 13 }, - { 0x1E23, 13 }, - { 0x1E22, 13 }, - { 0xE, 4 }, - { 0x16, 5 }, - { 0x18, 5 }, - { 0x32, 6 }, - { 0x1A, 6 }, - { 0x47, 7 }, - { 0x789, 11 }, - { 0x1F, 5 }, - { 0x10, 5 } - }, - { /* AC bias group 1, table 8 */ - { 0x1D, 5 }, - { 0x61, 7 }, - { 0x4E, 8 }, - { 0x9E, 9 }, - { 0x27C, 11 }, - { 0x9F5, 13 }, - { 0x9F4, 13 }, - { 0x3, 4 }, - { 0x60, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0x5, 4 }, - { 0xD, 5 }, - { 0x31, 6 }, - { 0x8, 5 }, - { 0x38, 6 }, - { 0x12, 6 }, - { 0x26, 7 }, - { 0x13F, 10 }, - { 0x4FB, 12 }, - { 0xD, 4 }, - { 0x2, 4 }, - { 0xC, 5 }, - { 0x39, 6 }, - { 0x1C, 6 }, - { 0xF, 5 }, - { 0x1D, 6 }, - { 0x8, 4 }, - { 0x19, 5 } - }, - { /* AC bias group 1, table 9 */ - { 0x7, 4 }, - { 0x19, 6 }, - { 0xAB, 8 }, - { 0xAA, 8 }, - { 0x119, 10 }, - { 0x461, 12 }, - { 0x460, 12 }, - { 0x1B, 5 }, - { 0x47, 8 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x9, 4 }, - { 0x5, 4 }, - { 0xD, 5 }, - { 0x35, 6 }, - { 0x3D, 6 }, - { 0x3C, 6 }, - { 0x18, 6 }, - { 0x22, 7 }, - { 0x8D, 9 }, - { 0x231, 11 }, - { 0xE, 4 }, - { 0x1F, 5 }, - { 0x9, 5 }, - { 0x2B, 6 }, - { 0x10, 6 }, - { 0x34, 6 }, - { 0x54, 7 }, - { 0x8, 4 }, - { 0x14, 5 } - }, - { /* AC bias group 1, table 10 */ - { 0xC, 4 }, - { 0x5, 5 }, - { 0x8, 6 }, - { 0x5B, 7 }, - { 0x4D, 9 }, - { 0x131, 11 }, - { 0x261, 12 }, - { 0x1A, 5 }, - { 0x12, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0x9, 4 }, - { 0x6, 4 }, - { 0x1B, 5 }, - { 0x6, 5 }, - { 0x1C, 6 }, - { 0x2C, 6 }, - { 0x15, 6 }, - { 0x5A, 7 }, - { 0x27, 8 }, - { 0x99, 10 }, - { 0x260, 12 }, - { 0xE, 4 }, - { 0x4, 4 }, - { 0xF, 5 }, - { 0x7, 5 }, - { 0x1D, 6 }, - { 0xB, 5 }, - { 0x14, 6 }, - { 0x8, 4 }, - { 0x17, 5 } - }, - { /* AC bias group 1, table 11 */ - { 0xF, 4 }, - { 0x13, 5 }, - { 0x75, 7 }, - { 0x24, 6 }, - { 0x95, 8 }, - { 0x251, 10 }, - { 0x4A0, 11 }, - { 0x10, 5 }, - { 0xC8, 8 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x1, 4 }, - { 0x0, 4 }, - { 0x1A, 5 }, - { 0x11, 5 }, - { 0x2C, 6 }, - { 0x65, 7 }, - { 0x74, 7 }, - { 0x4B, 7 }, - { 0xC9, 8 }, - { 0x129, 9 }, - { 0x943, 12 }, - { 0x942, 12 }, - { 0x3, 3 }, - { 0xA, 4 }, - { 0x1C, 5 }, - { 0x18, 5 }, - { 0x33, 6 }, - { 0x17, 5 }, - { 0x2D, 6 }, - { 0x1B, 5 }, - { 0x3B, 6 } - }, - { /* AC bias group 1, table 12 */ - { 0x3, 3 }, - { 0x1A, 5 }, - { 0x2D, 6 }, - { 0x38, 6 }, - { 0x28, 7 }, - { 0x395, 10 }, - { 0xE51, 12 }, - { 0x37, 6 }, - { 0xE4, 8 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x1F, 5 }, - { 0x1E, 5 }, - { 0x17, 5 }, - { 0x3A, 6 }, - { 0x73, 7 }, - { 0x2A, 7 }, - { 0x2B, 7 }, - { 0x29, 7 }, - { 0x1CB, 9 }, - { 0x729, 11 }, - { 0x1CA1, 13 }, - { 0x1CA0, 13 }, - { 0x4, 3 }, - { 0xA, 4 }, - { 0x4, 4 }, - { 0x18, 5 }, - { 0x36, 6 }, - { 0xB, 5 }, - { 0x2C, 6 }, - { 0x19, 5 }, - { 0x3B, 6 } - }, - { /* AC bias group 1, table 13 */ - { 0x4, 3 }, - { 0x4, 4 }, - { 0x3F, 6 }, - { 0x17, 5 }, - { 0x75, 7 }, - { 0x1F5, 9 }, - { 0x7D1, 11 }, - { 0x17, 6 }, - { 0x1F6, 9 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x1B, 5 }, - { 0x1A, 5 }, - { 0xA, 5 }, - { 0x32, 6 }, - { 0x74, 7 }, - { 0xF8, 8 }, - { 0xF9, 8 }, - { 0x1F7, 9 }, - { 0x3E9, 10 }, - { 0xFA0, 12 }, - { 0x1F43, 13 }, - { 0x1F42, 13 }, - { 0x3, 3 }, - { 0xA, 4 }, - { 0x1E, 5 }, - { 0x1C, 5 }, - { 0x3B, 6 }, - { 0x18, 5 }, - { 0x16, 6 }, - { 0x16, 5 }, - { 0x33, 6 } - }, - { /* AC bias group 1, table 14 */ - { 0x4, 3 }, - { 0x7, 4 }, - { 0x18, 5 }, - { 0x1E, 5 }, - { 0x36, 6 }, - { 0x31, 7 }, - { 0x177, 9 }, - { 0x77, 7 }, - { 0x176, 9 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0x1A, 5 }, - { 0x19, 5 }, - { 0x3A, 6 }, - { 0x19, 6 }, - { 0x5C, 7 }, - { 0xBA, 8 }, - { 0x61, 8 }, - { 0xC1, 9 }, - { 0x180, 10 }, - { 0x302, 11 }, - { 0x607, 12 }, - { 0x606, 12 }, - { 0x2, 3 }, - { 0xA, 4 }, - { 0x1F, 5 }, - { 0x1C, 5 }, - { 0x37, 6 }, - { 0x16, 5 }, - { 0x76, 7 }, - { 0xD, 5 }, - { 0x2F, 6 } - }, - { /* AC bias group 1, table 15 */ - { 0x0, 3 }, - { 0xA, 4 }, - { 0x1A, 5 }, - { 0xC, 4 }, - { 0x1D, 5 }, - { 0x39, 6 }, - { 0x78, 7 }, - { 0x5E, 7 }, - { 0x393, 11 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x16, 5 }, - { 0xF, 5 }, - { 0x2E, 6 }, - { 0x5F, 7 }, - { 0x73, 8 }, - { 0xE5, 9 }, - { 0x1C8, 10 }, - { 0xE4A, 13 }, - { 0x1C97, 14 }, - { 0x1C96, 14 }, - { 0xE49, 13 }, - { 0xE48, 13 }, - { 0x4, 3 }, - { 0x6, 4 }, - { 0x1F, 5 }, - { 0x1B, 5 }, - { 0x1D, 6 }, - { 0x38, 6 }, - { 0x38, 7 }, - { 0x3D, 6 }, - { 0x79, 7 } - } -}; - -static const uint16_t ac_bias_1[16][32][2] = { - { /* AC bias group 2, table 0 */ - { 0xB, 5 }, - { 0x2B, 7 }, - { 0x54, 8 }, - { 0x1B7, 9 }, - { 0x6D9, 11 }, - { 0xDB1, 12 }, - { 0xDB0, 12 }, - { 0x2, 4 }, - { 0xAB, 9 }, - { 0x9, 4 }, - { 0xA, 4 }, - { 0x7, 4 }, - { 0x8, 4 }, - { 0xF, 4 }, - { 0xC, 4 }, - { 0x3, 4 }, - { 0x1D, 5 }, - { 0x4, 4 }, - { 0xB, 4 }, - { 0x6, 4 }, - { 0x1A, 5 }, - { 0x3, 6 }, - { 0xAA, 9 }, - { 0x1, 4 }, - { 0x0, 5 }, - { 0x14, 6 }, - { 0x6C, 7 }, - { 0xDA, 8 }, - { 0x2, 6 }, - { 0x36D, 10 }, - { 0x1C, 5 }, - { 0x37, 6 } - }, - { /* AC bias group 2, table 1 */ - { 0x1D, 5 }, - { 0x4, 6 }, - { 0xB6, 8 }, - { 0x6A, 8 }, - { 0x5B9, 11 }, - { 0x16E1, 13 }, - { 0x16E0, 13 }, - { 0x7, 4 }, - { 0x16F, 9 }, - { 0xC, 4 }, - { 0xD, 4 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0x3, 4 }, - { 0x17, 5 }, - { 0x2, 4 }, - { 0x4, 4 }, - { 0x1C, 5 }, - { 0x2C, 6 }, - { 0x6B, 8 }, - { 0xB71, 12 }, - { 0x5, 4 }, - { 0x3, 5 }, - { 0x1B, 6 }, - { 0x5A, 7 }, - { 0x34, 7 }, - { 0x5, 6 }, - { 0x2DD, 10 }, - { 0x0, 4 }, - { 0xC, 5 } - }, - { /* AC bias group 2, table 2 */ - { 0x3, 4 }, - { 0x7F, 7 }, - { 0xA1, 8 }, - { 0xA0, 8 }, - { 0x20C, 10 }, - { 0x834, 12 }, - { 0x106B, 13 }, - { 0x7, 4 }, - { 0x82, 8 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x2, 4 }, - { 0x11, 5 }, - { 0x1E, 5 }, - { 0x15, 5 }, - { 0x3E, 6 }, - { 0x40, 7 }, - { 0x41B, 11 }, - { 0x106A, 13 }, - { 0x6, 4 }, - { 0xA, 5 }, - { 0x29, 6 }, - { 0x7E, 7 }, - { 0x51, 7 }, - { 0x21, 6 }, - { 0x107, 9 }, - { 0x4, 4 }, - { 0xB, 5 } - }, - { /* AC bias group 2, table 3 */ - { 0x7, 4 }, - { 0x1B, 6 }, - { 0xF6, 8 }, - { 0xE9, 8 }, - { 0x3A1, 10 }, - { 0x740, 11 }, - { 0xE82, 12 }, - { 0x1F, 5 }, - { 0x1EF, 9 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0xD, 4 }, - { 0x8, 4 }, - { 0x1C, 5 }, - { 0x3, 5 }, - { 0x12, 5 }, - { 0x2, 5 }, - { 0x75, 7 }, - { 0x1D1, 9 }, - { 0x1D07, 13 }, - { 0x1D06, 13 }, - { 0xA, 4 }, - { 0x13, 5 }, - { 0x3B, 6 }, - { 0x1A, 6 }, - { 0x7A, 7 }, - { 0x3C, 6 }, - { 0x1EE, 9 }, - { 0x0, 4 }, - { 0xC, 5 } - }, - { /* AC bias group 2, table 4 */ - { 0xD, 4 }, - { 0x3D, 6 }, - { 0x42, 7 }, - { 0x37, 7 }, - { 0xD9, 9 }, - { 0x362, 11 }, - { 0x6C6, 12 }, - { 0x1F, 5 }, - { 0x86, 8 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0x1, 4 }, - { 0xF, 5 }, - { 0x25, 6 }, - { 0x3C, 6 }, - { 0x1A, 6 }, - { 0x87, 8 }, - { 0x1B0, 10 }, - { 0xD8F, 13 }, - { 0xD8E, 13 }, - { 0xE, 4 }, - { 0x13, 5 }, - { 0xC, 5 }, - { 0x24, 6 }, - { 0x20, 6 }, - { 0x11, 5 }, - { 0x6D, 8 }, - { 0x0, 4 }, - { 0xE, 5 } - }, - { /* AC bias group 2, table 5 */ - { 0x0, 3 }, - { 0x12, 5 }, - { 0x76, 7 }, - { 0x77, 7 }, - { 0x14D, 9 }, - { 0x533, 11 }, - { 0x14C9, 13 }, - { 0x13, 5 }, - { 0xA5, 8 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x8, 4 }, - { 0x1A, 5 }, - { 0x2B, 6 }, - { 0x75, 7 }, - { 0x74, 7 }, - { 0xA7, 8 }, - { 0x298, 10 }, - { 0x14C8, 13 }, - { 0x14CB, 13 }, - { 0x14CA, 13 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0x7, 5 }, - { 0x2A, 6 }, - { 0x28, 6 }, - { 0x1B, 5 }, - { 0xA4, 8 }, - { 0x2, 4 }, - { 0x6, 5 } - }, - { /* AC bias group 2, table 6 */ - { 0x2, 3 }, - { 0x1A, 5 }, - { 0x2B, 6 }, - { 0x3A, 6 }, - { 0xED, 8 }, - { 0x283, 10 }, - { 0xA0A, 12 }, - { 0x4, 5 }, - { 0xA1, 8 }, - { 0x4, 3 }, - { 0x3, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x1F, 5 }, - { 0x6, 5 }, - { 0x77, 7 }, - { 0xA3, 8 }, - { 0xA2, 8 }, - { 0x140, 9 }, - { 0x1417, 13 }, - { 0x1416, 13 }, - { 0xA09, 12 }, - { 0xA08, 12 }, - { 0x0, 3 }, - { 0x1E, 5 }, - { 0x7, 5 }, - { 0x2A, 6 }, - { 0x29, 6 }, - { 0x1C, 5 }, - { 0xEC, 8 }, - { 0x1B, 5 }, - { 0x5, 5 } - }, - { /* AC bias group 2, table 7 */ - { 0x2, 3 }, - { 0x2, 4 }, - { 0x18, 5 }, - { 0x1D, 5 }, - { 0x35, 6 }, - { 0xE4, 8 }, - { 0x1CF, 11 }, - { 0x1D, 7 }, - { 0x72, 9 }, - { 0x4, 3 }, - { 0x5, 3 }, - { 0x6, 4 }, - { 0x7, 4 }, - { 0x6, 5 }, - { 0x73, 7 }, - { 0x38, 8 }, - { 0x1CE, 11 }, - { 0x39B, 12 }, - { 0x398, 12 }, - { 0x733, 13 }, - { 0x732, 13 }, - { 0x735, 13 }, - { 0x734, 13 }, - { 0x0, 3 }, - { 0x1F, 5 }, - { 0x1B, 5 }, - { 0x34, 6 }, - { 0xF, 6 }, - { 0x1E, 5 }, - { 0xE5, 8 }, - { 0x19, 5 }, - { 0x38, 6 } - }, - { /* AC bias group 2, table 8 */ - { 0x16, 5 }, - { 0x50, 7 }, - { 0x172, 9 }, - { 0x2E7, 10 }, - { 0x1732, 13 }, - { 0x2E67, 14 }, - { 0x2E66, 14 }, - { 0x6, 4 }, - { 0x51, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x9, 4 }, - { 0x1C, 5 }, - { 0x9, 5 }, - { 0x1C, 6 }, - { 0x1D, 6 }, - { 0x5D, 7 }, - { 0xB8, 8 }, - { 0x5CD, 11 }, - { 0x1731, 13 }, - { 0x1730, 13 }, - { 0xF, 4 }, - { 0x5, 4 }, - { 0xF, 5 }, - { 0x8, 5 }, - { 0x29, 6 }, - { 0x1D, 5 }, - { 0x2F, 6 }, - { 0x8, 4 }, - { 0x15, 5 } - }, - { /* AC bias group 2, table 9 */ - { 0x9, 4 }, - { 0x21, 6 }, - { 0x40, 7 }, - { 0xAD, 8 }, - { 0x2B0, 10 }, - { 0x1589, 13 }, - { 0x1588, 13 }, - { 0x1C, 5 }, - { 0x5F, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x6, 4 }, - { 0x11, 5 }, - { 0x2A, 6 }, - { 0x57, 7 }, - { 0x5E, 7 }, - { 0x41, 7 }, - { 0x159, 9 }, - { 0x563, 11 }, - { 0x158B, 13 }, - { 0x158A, 13 }, - { 0x1, 3 }, - { 0x5, 4 }, - { 0x14, 5 }, - { 0x3B, 6 }, - { 0x2E, 6 }, - { 0x4, 4 }, - { 0x3A, 6 }, - { 0x7, 4 }, - { 0x16, 5 } - }, - { /* AC bias group 2, table 10 */ - { 0xE, 4 }, - { 0x7, 5 }, - { 0x46, 7 }, - { 0x45, 7 }, - { 0x64, 9 }, - { 0x32A, 12 }, - { 0x657, 13 }, - { 0x18, 5 }, - { 0xD, 6 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xA, 4 }, - { 0xB, 4 }, - { 0x1A, 5 }, - { 0x36, 6 }, - { 0x47, 7 }, - { 0x44, 7 }, - { 0x18, 7 }, - { 0x33, 8 }, - { 0xCB, 10 }, - { 0x656, 13 }, - { 0x329, 12 }, - { 0x328, 12 }, - { 0x2, 3 }, - { 0x6, 4 }, - { 0x19, 5 }, - { 0xE, 5 }, - { 0x37, 6 }, - { 0x9, 4 }, - { 0xF, 5 }, - { 0x2, 4 }, - { 0x10, 5 } - }, - { /* AC bias group 2, table 11 */ - { 0x3, 3 }, - { 0x18, 5 }, - { 0x23, 6 }, - { 0x77, 7 }, - { 0x194, 9 }, - { 0x1956, 13 }, - { 0x32AF, 14 }, - { 0x3A, 6 }, - { 0x76, 7 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x1F, 5 }, - { 0x1E, 5 }, - { 0x14, 5 }, - { 0x22, 6 }, - { 0x64, 7 }, - { 0x197, 9 }, - { 0x196, 9 }, - { 0x32B, 10 }, - { 0x654, 11 }, - { 0x32AE, 14 }, - { 0x1955, 13 }, - { 0x1954, 13 }, - { 0x0, 3 }, - { 0x9, 4 }, - { 0x1C, 5 }, - { 0x15, 5 }, - { 0x10, 5 }, - { 0xD, 4 }, - { 0x17, 5 }, - { 0x16, 5 }, - { 0x33, 6 } - }, - { /* AC bias group 2, table 12 */ - { 0x5, 3 }, - { 0x6, 4 }, - { 0x3E, 6 }, - { 0x10, 5 }, - { 0x48, 7 }, - { 0x93F, 12 }, - { 0x24FA, 14 }, - { 0x32, 6 }, - { 0x67, 7 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x1B, 5 }, - { 0x1E, 5 }, - { 0x34, 6 }, - { 0x66, 7 }, - { 0x92, 8 }, - { 0x126, 9 }, - { 0x24E, 10 }, - { 0x49E, 11 }, - { 0x49F7, 15 }, - { 0x49F6, 15 }, - { 0x24F9, 14 }, - { 0x24F8, 14 }, - { 0x0, 3 }, - { 0x7, 4 }, - { 0x18, 5 }, - { 0x11, 5 }, - { 0x3F, 6 }, - { 0xE, 4 }, - { 0x13, 5 }, - { 0x35, 6 }, - { 0x25, 6 } - }, - { /* AC bias group 2, table 13 */ - { 0x5, 3 }, - { 0x8, 4 }, - { 0x12, 5 }, - { 0x1C, 5 }, - { 0x1C, 6 }, - { 0xEA, 9 }, - { 0x1D75, 14 }, - { 0x1E, 6 }, - { 0x66, 7 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0x1B, 5 }, - { 0x1A, 5 }, - { 0x1F, 6 }, - { 0x3B, 7 }, - { 0x74, 8 }, - { 0x1D6, 10 }, - { 0x3AF, 11 }, - { 0x1D74, 14 }, - { 0x1D77, 14 }, - { 0x1D76, 14 }, - { 0xEB9, 13 }, - { 0xEB8, 13 }, - { 0xF, 4 }, - { 0x6, 4 }, - { 0x13, 5 }, - { 0x3B, 6 }, - { 0x3A, 6 }, - { 0x0, 3 }, - { 0x18, 5 }, - { 0x32, 6 }, - { 0x67, 7 } - }, - { /* AC bias group 2, table 14 */ - { 0x4, 3 }, - { 0xA, 4 }, - { 0x1B, 5 }, - { 0xC, 4 }, - { 0xD, 5 }, - { 0xE6, 8 }, - { 0x684, 11 }, - { 0x72, 7 }, - { 0xE7, 8 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x17, 5 }, - { 0x16, 5 }, - { 0x18, 6 }, - { 0xD1, 8 }, - { 0x1A0, 9 }, - { 0x686, 11 }, - { 0xD0F, 12 }, - { 0xD0A, 12 }, - { 0x1A17, 13 }, - { 0x1A16, 13 }, - { 0x1A1D, 13 }, - { 0x1A1C, 13 }, - { 0xF, 4 }, - { 0x1D, 5 }, - { 0xE, 5 }, - { 0x35, 6 }, - { 0x38, 6 }, - { 0x0, 3 }, - { 0xF, 5 }, - { 0x19, 6 }, - { 0x69, 7 } - }, - { /* AC bias group 2, table 15 */ - { 0x3, 3 }, - { 0xC, 4 }, - { 0x1B, 5 }, - { 0x0, 3 }, - { 0x3, 4 }, - { 0x2E, 6 }, - { 0x51, 9 }, - { 0xBC, 8 }, - { 0x53, 9 }, - { 0x4, 3 }, - { 0x2, 3 }, - { 0x16, 5 }, - { 0x15, 5 }, - { 0x15, 7 }, - { 0x50, 9 }, - { 0xA4, 10 }, - { 0x294, 12 }, - { 0x52B, 13 }, - { 0x52A, 13 }, - { 0x52D, 13 }, - { 0x52C, 13 }, - { 0x52F, 13 }, - { 0x52E, 13 }, - { 0xE, 4 }, - { 0x1A, 5 }, - { 0x4, 5 }, - { 0x28, 6 }, - { 0x29, 6 }, - { 0xF, 4 }, - { 0xB, 6 }, - { 0x5F, 7 }, - { 0xBD, 8 } - } -}; - -static const uint16_t ac_bias_2[16][32][2] = { - { /* AC bias group 3, table 0 */ - { 0x3, 4 }, - { 0x9, 6 }, - { 0xD0, 8 }, - { 0x1A3, 9 }, - { 0x344, 10 }, - { 0xD14, 12 }, - { 0x1A2B, 13 }, - { 0x4, 4 }, - { 0x15, 7 }, - { 0x0, 3 }, - { 0xF, 4 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0xE, 4 }, - { 0x9, 4 }, - { 0x1B, 5 }, - { 0xA, 5 }, - { 0x14, 5 }, - { 0xD, 5 }, - { 0x2A, 6 }, - { 0x14, 7 }, - { 0x68B, 11 }, - { 0x1A2A, 13 }, - { 0x8, 4 }, - { 0xB, 5 }, - { 0x2B, 6 }, - { 0xB, 6 }, - { 0x69, 7 }, - { 0x35, 6 }, - { 0x8, 6 }, - { 0x7, 4 }, - { 0xC, 5 } - }, - { /* AC bias group 3, table 1 */ - { 0xA, 4 }, - { 0x3C, 6 }, - { 0x32, 7 }, - { 0x30, 7 }, - { 0xC5, 9 }, - { 0x621, 12 }, - { 0x620, 12 }, - { 0x1F, 5 }, - { 0x33, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x4, 4 }, - { 0xD, 5 }, - { 0x26, 6 }, - { 0x27, 6 }, - { 0x14, 6 }, - { 0x63, 8 }, - { 0x189, 10 }, - { 0x623, 12 }, - { 0x622, 12 }, - { 0xB, 4 }, - { 0x12, 5 }, - { 0x3D, 6 }, - { 0x22, 6 }, - { 0x15, 6 }, - { 0xB, 5 }, - { 0x23, 6 }, - { 0x7, 4 }, - { 0x10, 5 } - }, - { /* AC bias group 3, table 2 */ - { 0xF, 4 }, - { 0xC, 5 }, - { 0x43, 7 }, - { 0x10, 6 }, - { 0x44, 8 }, - { 0x114, 10 }, - { 0x455, 12 }, - { 0x18, 5 }, - { 0x23, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0x9, 4 }, - { 0x19, 5 }, - { 0x9, 5 }, - { 0x17, 6 }, - { 0x16, 6 }, - { 0x42, 7 }, - { 0x8B, 9 }, - { 0x454, 12 }, - { 0x457, 12 }, - { 0x456, 12 }, - { 0xB, 4 }, - { 0x15, 5 }, - { 0xA, 5 }, - { 0x29, 6 }, - { 0x20, 6 }, - { 0xD, 5 }, - { 0x28, 6 }, - { 0x7, 4 }, - { 0x11, 5 } - }, - { /* AC bias group 3, table 3 */ - { 0x1, 3 }, - { 0x1A, 5 }, - { 0x29, 6 }, - { 0x2A, 6 }, - { 0xA0, 8 }, - { 0x285, 10 }, - { 0x1425, 13 }, - { 0x2, 5 }, - { 0x0, 7 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x8, 4 }, - { 0x12, 5 }, - { 0x1, 6 }, - { 0x51, 7 }, - { 0x1, 7 }, - { 0x143, 9 }, - { 0x508, 11 }, - { 0x1424, 13 }, - { 0x1427, 13 }, - { 0x1426, 13 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0x3, 5 }, - { 0x37, 6 }, - { 0x2B, 6 }, - { 0x13, 5 }, - { 0x36, 6 }, - { 0x1D, 5 }, - { 0x1, 5 } - }, - { /* AC bias group 3, table 4 */ - { 0x4, 3 }, - { 0x1F, 5 }, - { 0x3D, 6 }, - { 0x6, 5 }, - { 0x16, 7 }, - { 0x53, 9 }, - { 0x14A, 11 }, - { 0x34, 6 }, - { 0x2A, 8 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xB, 4 }, - { 0xC, 4 }, - { 0x1C, 5 }, - { 0x37, 6 }, - { 0x17, 7 }, - { 0x2B, 8 }, - { 0x28, 8 }, - { 0xA4, 10 }, - { 0x52D, 13 }, - { 0x52C, 13 }, - { 0x52F, 13 }, - { 0x52E, 13 }, - { 0x0, 3 }, - { 0x1D, 5 }, - { 0x7, 5 }, - { 0x4, 5 }, - { 0x35, 6 }, - { 0x14, 5 }, - { 0x36, 6 }, - { 0x15, 5 }, - { 0x3C, 6 } - }, - { /* AC bias group 3, table 5 */ - { 0x4, 3 }, - { 0xA, 4 }, - { 0x7, 5 }, - { 0x1D, 5 }, - { 0x9, 6 }, - { 0x1F3, 9 }, - { 0x7C7, 11 }, - { 0x8, 6 }, - { 0x1F0, 9 }, - { 0x3, 3 }, - { 0x2, 3 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x17, 5 }, - { 0x7D, 7 }, - { 0x1F2, 9 }, - { 0x7C6, 11 }, - { 0x7C5, 11 }, - { 0x1F12, 13 }, - { 0x3E27, 14 }, - { 0x3E26, 14 }, - { 0x1F11, 13 }, - { 0x1F10, 13 }, - { 0x0, 3 }, - { 0x1E, 5 }, - { 0x6, 5 }, - { 0x39, 6 }, - { 0x38, 6 }, - { 0x3F, 6 }, - { 0x2C, 6 }, - { 0x5, 5 }, - { 0x2D, 6 } - }, - { /* AC bias group 3, table 6 */ - { 0x2, 3 }, - { 0x7, 4 }, - { 0x18, 5 }, - { 0x3, 4 }, - { 0x5, 5 }, - { 0x35, 7 }, - { 0x4F, 9 }, - { 0x12, 7 }, - { 0x4E5, 13 }, - { 0x5, 3 }, - { 0x4, 3 }, - { 0xD, 4 }, - { 0xE, 4 }, - { 0x33, 6 }, - { 0x26, 8 }, - { 0x9D, 10 }, - { 0x4E4, 13 }, - { 0x4E7, 13 }, - { 0x4E6, 13 }, - { 0x4E1, 13 }, - { 0x4E0, 13 }, - { 0x4E3, 13 }, - { 0x4E2, 13 }, - { 0x0, 3 }, - { 0x1F, 5 }, - { 0xC, 5 }, - { 0x3D, 6 }, - { 0x3C, 6 }, - { 0x32, 6 }, - { 0x34, 7 }, - { 0x1B, 6 }, - { 0x8, 6 } - }, - { /* AC bias group 3, table 7 */ - { 0x0, 3 }, - { 0x4, 4 }, - { 0x1C, 5 }, - { 0xF, 4 }, - { 0x2, 4 }, - { 0x7, 5 }, - { 0x75, 7 }, - { 0xE8, 8 }, - { 0x1D2A, 13 }, - { 0x5, 3 }, - { 0x4, 3 }, - { 0xD, 4 }, - { 0xC, 4 }, - { 0x77, 7 }, - { 0xE96, 12 }, - { 0x3A57, 14 }, - { 0x3A56, 14 }, - { 0x3A5D, 14 }, - { 0x3A5C, 14 }, - { 0x3A5F, 14 }, - { 0x3A5E, 14 }, - { 0x1D29, 13 }, - { 0x1D28, 13 }, - { 0x3, 3 }, - { 0x6, 5 }, - { 0xA, 5 }, - { 0x2C, 7 }, - { 0x17, 6 }, - { 0x76, 7 }, - { 0x1D3, 9 }, - { 0x3A4, 10 }, - { 0x2D, 7 } - }, - { /* AC bias group 3, table 8 */ - { 0xA, 4 }, - { 0x24, 6 }, - { 0xBF, 8 }, - { 0x85, 8 }, - { 0x211, 10 }, - { 0x842, 12 }, - { 0x1087, 13 }, - { 0x18, 5 }, - { 0x20, 6 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0x7, 4 }, - { 0x13, 5 }, - { 0x25, 6 }, - { 0x5E, 7 }, - { 0x43, 7 }, - { 0xBE, 8 }, - { 0x109, 9 }, - { 0x1086, 13 }, - { 0x841, 12 }, - { 0x840, 12 }, - { 0xF, 4 }, - { 0x1, 4 }, - { 0x11, 5 }, - { 0x0, 5 }, - { 0x2E, 6 }, - { 0x19, 5 }, - { 0x1, 5 }, - { 0x6, 4 }, - { 0x16, 5 } - }, - { /* AC bias group 3, table 9 */ - { 0x2, 3 }, - { 0xF, 5 }, - { 0x6F, 7 }, - { 0x61, 7 }, - { 0x374, 10 }, - { 0x1BA8, 13 }, - { 0x3753, 14 }, - { 0x12, 5 }, - { 0x36, 6 }, - { 0x0, 3 }, - { 0x1, 3 }, - { 0xA, 4 }, - { 0xB, 4 }, - { 0x1A, 5 }, - { 0x31, 6 }, - { 0x60, 7 }, - { 0xDC, 8 }, - { 0x1BB, 9 }, - { 0x6EB, 11 }, - { 0x1BAB, 13 }, - { 0x3752, 14 }, - { 0x3755, 14 }, - { 0x3754, 14 }, - { 0xE, 4 }, - { 0x6, 4 }, - { 0x13, 5 }, - { 0xE, 5 }, - { 0x3E, 6 }, - { 0x8, 4 }, - { 0x1E, 5 }, - { 0x19, 5 }, - { 0x3F, 6 } - }, - { /* AC bias group 3, table 10 */ - { 0x3, 3 }, - { 0x1C, 5 }, - { 0x25, 6 }, - { 0x24, 6 }, - { 0x1DA, 9 }, - { 0x1DBD, 13 }, - { 0x3B7C, 14 }, - { 0x3C, 6 }, - { 0x3D, 6 }, - { 0x0, 3 }, - { 0x1, 3 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0xB, 5 }, - { 0x77, 7 }, - { 0xEC, 8 }, - { 0x3B6, 10 }, - { 0x76E, 11 }, - { 0x1DBF, 13 }, - { 0x76FB, 15 }, - { 0x76FA, 15 }, - { 0x3B79, 14 }, - { 0x3B78, 14 }, - { 0xD, 4 }, - { 0x1F, 5 }, - { 0x13, 5 }, - { 0xA, 5 }, - { 0x8, 5 }, - { 0xC, 4 }, - { 0x8, 4 }, - { 0x9, 5 }, - { 0x3A, 6 } - }, - { /* AC bias group 3, table 11 */ - { 0x5, 3 }, - { 0x3, 4 }, - { 0x4, 5 }, - { 0x10, 5 }, - { 0x8F, 8 }, - { 0x475, 11 }, - { 0x11D1, 13 }, - { 0x79, 7 }, - { 0x27, 6 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0x1, 4 }, - { 0x0, 4 }, - { 0x26, 6 }, - { 0x46, 7 }, - { 0x11C, 9 }, - { 0x477, 11 }, - { 0x8ED, 12 }, - { 0x11D0, 13 }, - { 0x11D3, 13 }, - { 0x11D2, 13 }, - { 0x11D9, 13 }, - { 0x11D8, 13 }, - { 0xD, 4 }, - { 0x1F, 5 }, - { 0x12, 5 }, - { 0x5, 5 }, - { 0x3D, 6 }, - { 0xC, 4 }, - { 0xE, 4 }, - { 0x22, 6 }, - { 0x78, 7 } - }, - { /* AC bias group 3, table 12 */ - { 0x5, 3 }, - { 0xC, 4 }, - { 0x1B, 5 }, - { 0x0, 4 }, - { 0x6, 6 }, - { 0x3E2, 10 }, - { 0x3E3D, 14 }, - { 0xF, 7 }, - { 0x34, 6 }, - { 0x3, 3 }, - { 0x2, 3 }, - { 0x1E, 5 }, - { 0x1D, 5 }, - { 0x7D, 7 }, - { 0x1F0, 9 }, - { 0x7C6, 11 }, - { 0x3E3C, 14 }, - { 0x3E3F, 14 }, - { 0x3E3E, 14 }, - { 0x3E39, 14 }, - { 0x3E38, 14 }, - { 0x3E3B, 14 }, - { 0x3E3A, 14 }, - { 0x8, 4 }, - { 0x1C, 5 }, - { 0x2, 5 }, - { 0x3F, 6 }, - { 0x35, 6 }, - { 0x9, 4 }, - { 0x1, 3 }, - { 0xE, 7 }, - { 0xF9, 8 } - }, - { /* AC bias group 3, table 13 */ - { 0x4, 3 }, - { 0xB, 4 }, - { 0x1, 4 }, - { 0xA, 4 }, - { 0x1E, 6 }, - { 0xE0, 9 }, - { 0xE1E, 13 }, - { 0x71, 8 }, - { 0x39, 7 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0xD, 5 }, - { 0xC, 5 }, - { 0x20, 7 }, - { 0x1C2, 10 }, - { 0x1C3F, 14 }, - { 0x1C3E, 14 }, - { 0xE19, 13 }, - { 0xE18, 13 }, - { 0xE1B, 13 }, - { 0xE1A, 13 }, - { 0xE1D, 13 }, - { 0xE1C, 13 }, - { 0x0, 4 }, - { 0x9, 5 }, - { 0x1D, 6 }, - { 0x1F, 6 }, - { 0x11, 6 }, - { 0x5, 4 }, - { 0x1, 3 }, - { 0x43, 8 }, - { 0x42, 8 } - }, - { /* AC bias group 3, table 14 */ - { 0x4, 3 }, - { 0xD, 4 }, - { 0x7, 4 }, - { 0x2, 3 }, - { 0x14, 5 }, - { 0x16C, 9 }, - { 0x16D1, 13 }, - { 0x2DF, 10 }, - { 0x16E, 9 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x2C, 6 }, - { 0x2B, 6 }, - { 0x2DE, 10 }, - { 0x16D0, 13 }, - { 0x16D3, 13 }, - { 0x16D2, 13 }, - { 0x2DB5, 14 }, - { 0x2DB4, 14 }, - { 0x2DB7, 14 }, - { 0x2DB6, 14 }, - { 0x16D9, 13 }, - { 0x16D8, 13 }, - { 0xC, 5 }, - { 0x2A, 6 }, - { 0x5A, 7 }, - { 0x1B, 6 }, - { 0x1A, 6 }, - { 0x17, 5 }, - { 0xC, 4 }, - { 0x5B7, 11 }, - { 0x5B5, 11 } - }, - { /* AC bias group 3, table 15 */ - { 0x2, 2 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0xC, 4 }, - { 0x3B, 6 }, - { 0x1AC, 9 }, - { 0x1AD8, 13 }, - { 0x35B3, 14 }, - { 0x35B2, 14 }, - { 0x1, 2 }, - { 0x0, 2 }, - { 0x69, 7 }, - { 0x68, 7 }, - { 0x35BD, 14 }, - { 0x35BC, 14 }, - { 0x35BF, 14 }, - { 0x35BE, 14 }, - { 0x35B9, 14 }, - { 0x35B8, 14 }, - { 0x35BB, 14 }, - { 0x35BA, 14 }, - { 0x35B5, 14 }, - { 0x35B4, 14 }, - { 0x1A9, 9 }, - { 0x1A8, 9 }, - { 0x35A, 10 }, - { 0xD7, 8 }, - { 0xD5, 8 }, - { 0x3A, 6 }, - { 0x1B, 5 }, - { 0x35B7, 14 }, - { 0x35B6, 14 } - } -}; - -static const uint16_t ac_bias_3[16][32][2] = { - { /* AC bias group 4, table 0 */ - { 0x0, 3 }, - { 0x10, 5 }, - { 0x72, 7 }, - { 0x71, 7 }, - { 0x154, 9 }, - { 0xAAB, 12 }, - { 0xAA8, 12 }, - { 0x14, 5 }, - { 0x70, 7 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0xC, 4 }, - { 0xB, 4 }, - { 0x3, 4 }, - { 0x11, 5 }, - { 0x73, 7 }, - { 0x54, 7 }, - { 0xAB, 8 }, - { 0x2AB, 10 }, - { 0x1553, 13 }, - { 0x1552, 13 }, - { 0x1555, 13 }, - { 0x1554, 13 }, - { 0xD, 4 }, - { 0x1E, 5 }, - { 0x12, 5 }, - { 0x3E, 6 }, - { 0x2B, 6 }, - { 0x2, 4 }, - { 0x3F, 6 }, - { 0x1D, 5 }, - { 0x13, 5 } - }, - { /* AC bias group 4, table 1 */ - { 0x3, 3 }, - { 0x1F, 5 }, - { 0x29, 6 }, - { 0x3D, 6 }, - { 0xC, 7 }, - { 0x69, 10 }, - { 0x345, 13 }, - { 0x2, 5 }, - { 0x28, 6 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0xE, 4 }, - { 0xC, 4 }, - { 0x15, 5 }, - { 0x7, 6 }, - { 0x1B, 8 }, - { 0x6B, 10 }, - { 0x6A, 10 }, - { 0x344, 13 }, - { 0x347, 13 }, - { 0x346, 13 }, - { 0x1A1, 12 }, - { 0x1A0, 12 }, - { 0xB, 4 }, - { 0x1A, 5 }, - { 0x12, 5 }, - { 0x0, 5 }, - { 0x3C, 6 }, - { 0x8, 4 }, - { 0x1B, 5 }, - { 0x13, 5 }, - { 0x1, 5 } - }, - { /* AC bias group 4, table 2 */ - { 0x4, 3 }, - { 0x4, 4 }, - { 0x3F, 6 }, - { 0x14, 5 }, - { 0x56, 7 }, - { 0x15C, 9 }, - { 0x15D5, 13 }, - { 0x3C, 6 }, - { 0x2A, 6 }, - { 0x0, 3 }, - { 0x1, 3 }, - { 0xE, 4 }, - { 0xD, 4 }, - { 0xC, 5 }, - { 0xAF, 8 }, - { 0x2BB, 10 }, - { 0x15D4, 13 }, - { 0x15D7, 13 }, - { 0x15D6, 13 }, - { 0x15D1, 13 }, - { 0x15D0, 13 }, - { 0x15D3, 13 }, - { 0x15D2, 13 }, - { 0xB, 4 }, - { 0x19, 5 }, - { 0xD, 5 }, - { 0x3E, 6 }, - { 0x31, 6 }, - { 0x7, 4 }, - { 0x5, 4 }, - { 0x3D, 6 }, - { 0x30, 6 } - }, - { /* AC bias group 4, table 3 */ - { 0x5, 3 }, - { 0x8, 4 }, - { 0x1A, 5 }, - { 0x0, 4 }, - { 0x36, 6 }, - { 0x11, 8 }, - { 0x106, 12 }, - { 0xA, 7 }, - { 0x6E, 7 }, - { 0x2, 3 }, - { 0x3, 3 }, - { 0x3, 4 }, - { 0x2, 4 }, - { 0x6F, 7 }, - { 0x21, 9 }, - { 0x20F, 13 }, - { 0x20E, 13 }, - { 0x101, 12 }, - { 0x100, 12 }, - { 0x103, 12 }, - { 0x102, 12 }, - { 0x105, 12 }, - { 0x104, 12 }, - { 0xC, 4 }, - { 0x1E, 5 }, - { 0x3, 5 }, - { 0x3E, 6 }, - { 0x3F, 6 }, - { 0x9, 4 }, - { 0xE, 4 }, - { 0xB, 7 }, - { 0x9, 7 } - }, - { /* AC bias group 4, table 4 */ - { 0x2, 3 }, - { 0xE, 4 }, - { 0x1E, 5 }, - { 0xC, 4 }, - { 0x1F, 5 }, - { 0x6E, 7 }, - { 0xAD, 10 }, - { 0xAF, 10 }, - { 0x14, 7 }, - { 0x4, 3 }, - { 0x3, 3 }, - { 0x1A, 5 }, - { 0x17, 5 }, - { 0x2A, 8 }, - { 0x576, 13 }, - { 0xAEF, 14 }, - { 0xAEE, 14 }, - { 0x571, 13 }, - { 0x570, 13 }, - { 0x573, 13 }, - { 0x572, 13 }, - { 0x575, 13 }, - { 0x574, 13 }, - { 0x3, 4 }, - { 0x16, 5 }, - { 0x4, 5 }, - { 0x36, 6 }, - { 0xB, 6 }, - { 0xA, 4 }, - { 0x0, 3 }, - { 0x6F, 7 }, - { 0xAC, 10 } - }, - { /* AC bias group 4, table 5 */ - { 0x4, 3 }, - { 0x5, 4 }, - { 0x3, 3 }, - { 0x1, 3 }, - { 0x4, 4 }, - { 0x2F, 6 }, - { 0x526, 11 }, - { 0x1495, 13 }, - { 0xA6, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x2D, 6 }, - { 0x2C, 6 }, - { 0x1494, 13 }, - { 0x1497, 13 }, - { 0x1496, 13 }, - { 0x1491, 13 }, - { 0x1490, 13 }, - { 0x1493, 13 }, - { 0x1492, 13 }, - { 0x293D, 14 }, - { 0x293C, 14 }, - { 0x293F, 14 }, - { 0x0, 3 }, - { 0x28, 6 }, - { 0xA5, 8 }, - { 0x148, 9 }, - { 0xA7, 8 }, - { 0x2E, 6 }, - { 0x15, 5 }, - { 0xA4E, 12 }, - { 0x293E, 14 } - }, - { /* AC bias group 4, table 6 */ - { 0x4, 3 }, - { 0x5, 4 }, - { 0x3, 3 }, - { 0x1, 3 }, - { 0x4, 4 }, - { 0x2F, 6 }, - { 0x526, 11 }, - { 0x1495, 13 }, - { 0xA6, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x2D, 6 }, - { 0x2C, 6 }, - { 0x1494, 13 }, - { 0x1497, 13 }, - { 0x1496, 13 }, - { 0x1491, 13 }, - { 0x1490, 13 }, - { 0x1493, 13 }, - { 0x1492, 13 }, - { 0x293D, 14 }, - { 0x293C, 14 }, - { 0x293F, 14 }, - { 0x0, 3 }, - { 0x28, 6 }, - { 0xA5, 8 }, - { 0x148, 9 }, - { 0xA7, 8 }, - { 0x2E, 6 }, - { 0x15, 5 }, - { 0xA4E, 12 }, - { 0x293E, 14 } - }, - { /* AC bias group 4, table 7 */ - { 0x4, 3 }, - { 0x5, 4 }, - { 0x3, 3 }, - { 0x1, 3 }, - { 0x4, 4 }, - { 0x2F, 6 }, - { 0x526, 11 }, - { 0x1495, 13 }, - { 0xA6, 8 }, - { 0x7, 3 }, - { 0x6, 3 }, - { 0x2D, 6 }, - { 0x2C, 6 }, - { 0x1494, 13 }, - { 0x1497, 13 }, - { 0x1496, 13 }, - { 0x1491, 13 }, - { 0x1490, 13 }, - { 0x1493, 13 }, - { 0x1492, 13 }, - { 0x293D, 14 }, - { 0x293C, 14 }, - { 0x293F, 14 }, - { 0x0, 3 }, - { 0x28, 6 }, - { 0xA5, 8 }, - { 0x148, 9 }, - { 0xA7, 8 }, - { 0x2E, 6 }, - { 0x15, 5 }, - { 0xA4E, 12 }, - { 0x293E, 14 } - }, - { /* AC bias group 4, table 8 */ - { 0x3, 3 }, - { 0x11, 5 }, - { 0x20, 6 }, - { 0x74, 7 }, - { 0x10D, 9 }, - { 0x863, 12 }, - { 0x860, 12 }, - { 0xA, 5 }, - { 0x75, 7 }, - { 0x1, 3 }, - { 0x0, 3 }, - { 0xB, 4 }, - { 0xA, 4 }, - { 0x18, 5 }, - { 0x38, 6 }, - { 0x42, 7 }, - { 0x10F, 9 }, - { 0x10E, 9 }, - { 0x219, 10 }, - { 0x10C3, 13 }, - { 0x10C2, 13 }, - { 0x10C5, 13 }, - { 0x10C4, 13 }, - { 0xF, 4 }, - { 0x4, 4 }, - { 0x19, 5 }, - { 0xB, 5 }, - { 0x39, 6 }, - { 0x9, 4 }, - { 0x1B, 5 }, - { 0x1A, 5 }, - { 0x3B, 6 } - }, - { /* AC bias group 4, table 9 */ - { 0x5, 3 }, - { 0x1, 4 }, - { 0x3E, 6 }, - { 0x1, 5 }, - { 0xE2, 8 }, - { 0x1C6F, 13 }, - { 0x38D9, 14 }, - { 0x39, 6 }, - { 0x1F, 6 }, - { 0x2, 3 }, - { 0x1, 3 }, - { 0x9, 4 }, - { 0x8, 4 }, - { 0x0, 5 }, - { 0x70, 7 }, - { 0x1C7, 9 }, - { 0x38C, 10 }, - { 0x71A, 11 }, - { 0x38D8, 14 }, - { 0x38DB, 14 }, - { 0x38DA, 14 }, - { 0x38DD, 14 }, - { 0x38DC, 14 }, - { 0xD, 4 }, - { 0x1D, 5 }, - { 0xE, 5 }, - { 0x3F, 6 }, - { 0x3C, 6 }, - { 0xC, 4 }, - { 0x6, 4 }, - { 0x3D, 6 }, - { 0x1E, 6 } - }, - { /* AC bias group 4, table 10 */ - { 0x6, 3 }, - { 0xB, 4 }, - { 0x11, 5 }, - { 0x1E, 5 }, - { 0x74, 7 }, - { 0x3AA, 10 }, - { 0x1D5C, 13 }, - { 0x1, 6 }, - { 0x21, 6 }, - { 0x1, 3 }, - { 0x2, 3 }, - { 0x7, 4 }, - { 0x6, 4 }, - { 0x3E, 6 }, - { 0xEB, 8 }, - { 0x1D4, 9 }, - { 0xEAF, 12 }, - { 0x3ABB, 14 }, - { 0x3ABA, 14 }, - { 0x1D59, 13 }, - { 0x1D58, 13 }, - { 0x1D5B, 13 }, - { 0x1D5A, 13 }, - { 0xA, 4 }, - { 0x1C, 5 }, - { 0x1, 5 }, - { 0x3F, 6 }, - { 0x3B, 6 }, - { 0x1, 4 }, - { 0x9, 4 }, - { 0x20, 6 }, - { 0x0, 6 } - }, - { /* AC bias group 4, table 11 */ - { 0x4, 3 }, - { 0xA, 4 }, - { 0x17, 5 }, - { 0x4, 4 }, - { 0x16, 6 }, - { 0x16A, 9 }, - { 0x16B1, 13 }, - { 0x17, 7 }, - { 0x5B, 7 }, - { 0x6, 3 }, - { 0x7, 3 }, - { 0x1, 4 }, - { 0x0, 4 }, - { 0xA, 6 }, - { 0x2D7, 10 }, - { 0xB5A, 12 }, - { 0x16B0, 13 }, - { 0x16B3, 13 }, - { 0x16B2, 13 }, - { 0x2D6D, 14 }, - { 0x2D6C, 14 }, - { 0x2D6F, 14 }, - { 0x2D6E, 14 }, - { 0x6, 4 }, - { 0xA, 5 }, - { 0x4, 5 }, - { 0x2C, 6 }, - { 0x17, 6 }, - { 0x3, 4 }, - { 0x7, 4 }, - { 0x16, 7 }, - { 0xB4, 8 } - }, - { /* AC bias group 4, table 12 */ - { 0x5, 3 }, - { 0xD, 4 }, - { 0x5, 4 }, - { 0x9, 4 }, - { 0x33, 6 }, - { 0x193, 9 }, - { 0x192C, 13 }, - { 0x61, 8 }, - { 0x31, 7 }, - { 0x0, 2 }, - { 0x7, 3 }, - { 0x10, 5 }, - { 0x11, 5 }, - { 0xC8, 8 }, - { 0x192F, 13 }, - { 0x325B, 14 }, - { 0x325A, 14 }, - { 0x1929, 13 }, - { 0x1928, 13 }, - { 0x192B, 13 }, - { 0x192A, 13 }, - { 0x325D, 14 }, - { 0x325C, 14 }, - { 0x18, 5 }, - { 0x1A, 6 }, - { 0x1B, 6 }, - { 0x65, 7 }, - { 0x19, 6 }, - { 0x4, 4 }, - { 0x7, 4 }, - { 0x60, 8 }, - { 0x324, 10 } - }, - { /* AC bias group 4, table 13 */ - { 0x6, 3 }, - { 0x0, 3 }, - { 0x2, 4 }, - { 0xF, 4 }, - { 0x39, 6 }, - { 0x1D9, 9 }, - { 0x1D82, 13 }, - { 0x761, 11 }, - { 0x3BE, 10 }, - { 0x1, 2 }, - { 0x2, 2 }, - { 0xF, 6 }, - { 0xE, 6 }, - { 0x762, 11 }, - { 0x3B07, 14 }, - { 0x3B06, 14 }, - { 0x3B1D, 14 }, - { 0x3B1C, 14 }, - { 0x3B1F, 14 }, - { 0x3B1E, 14 }, - { 0x3B19, 14 }, - { 0x3B18, 14 }, - { 0x3B1B, 14 }, - { 0x38, 6 }, - { 0x1DE, 9 }, - { 0xED, 8 }, - { 0x3BF, 10 }, - { 0xEE, 8 }, - { 0x3A, 6 }, - { 0x6, 5 }, - { 0xEC0, 12 }, - { 0x3B1A, 14 } - }, - { /* AC bias group 4, table 14 */ - { 0x0, 2 }, - { 0x2, 3 }, - { 0xF, 5 }, - { 0x6, 4 }, - { 0x1C, 6 }, - { 0x1D0, 10 }, - { 0xE8C, 13 }, - { 0x1D1B, 14 }, - { 0x1D1A, 14 }, - { 0x3, 2 }, - { 0x2, 2 }, - { 0xEA, 9 }, - { 0xE9, 9 }, - { 0xE89, 13 }, - { 0xE88, 13 }, - { 0xE8B, 13 }, - { 0xE8A, 13 }, - { 0x1D65, 14 }, - { 0x1D64, 14 }, - { 0x1D67, 14 }, - { 0x1D66, 14 }, - { 0x1D61, 14 }, - { 0x1D60, 14 }, - { 0x3AD, 11 }, - { 0x1D63, 14 }, - { 0x1D62, 14 }, - { 0x1D1D, 14 }, - { 0x1D1C, 14 }, - { 0x3B, 7 }, - { 0x1D7, 10 }, - { 0x1D1F, 14 }, - { 0x1D1E, 14 } - }, - { /* AC bias group 4, table 15 */ - { 0x2, 2 }, - { 0xF, 4 }, - { 0x1C, 5 }, - { 0xC, 4 }, - { 0x3B, 6 }, - { 0x1AC, 9 }, - { 0x1AD8, 13 }, - { 0x35B3, 14 }, - { 0x35B2, 14 }, - { 0x1, 2 }, - { 0x0, 2 }, - { 0x69, 7 }, - { 0x68, 7 }, - { 0x35BD, 14 }, - { 0x35BC, 14 }, - { 0x35BF, 14 }, - { 0x35BE, 14 }, - { 0x35B9, 14 }, - { 0x35B8, 14 }, - { 0x35BB, 14 }, - { 0x35BA, 14 }, - { 0x35B5, 14 }, - { 0x35B4, 14 }, - { 0x1A9, 9 }, - { 0x1A8, 9 }, - { 0x35A, 10 }, - { 0xD7, 8 }, - { 0xD5, 8 }, - { 0x3A, 6 }, - { 0x1B, 5 }, - { 0x35B7, 14 }, - { 0x35B6, 14 } - } -}; - -#endif /* AVCODEC_VP3DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vp3dsp.c b/tizen/distrib/ffmpeg/libavcodec/vp3dsp.c deleted file mode 100644 index 058eb56..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp3dsp.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2004 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Standard C DSP-oriented functions cribbed from the original VP3 - * source code. - */ - -#include "avcodec.h" -#include "dsputil.h" - -#define IdctAdjustBeforeShift 8 -#define xC1S7 64277 -#define xC2S6 60547 -#define xC3S5 54491 -#define xC4S4 46341 -#define xC5S3 36410 -#define xC6S2 25080 -#define xC7S1 12785 - -#define M(a,b) (((a) * (b))>>16) - -static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int type) -{ - int16_t *ip = input; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H; - int Ed, Gd, Add, Bdd, Fd, Hd; - - int i; - - /* Inverse DCT on the rows now */ - for (i = 0; i < 8; i++) { - /* Check for non-zero values */ - if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) { - A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]); - B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]); - C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]); - D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]); - - Ad = M(xC4S4, (A - C)); - Bd = M(xC4S4, (B - D)); - - Cd = A + C; - Dd = B + D; - - E = M(xC4S4, (ip[0] + ip[4])); - F = M(xC4S4, (ip[0] - ip[4])); - - G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]); - H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]); - - Ed = E - G; - Gd = E + G; - - Add = F + Ad; - Bdd = Bd - H; - - Fd = F - Ad; - Hd = Bd + H; - - /* Final sequence of operations over-write original inputs. */ - ip[0] = Gd + Cd ; - ip[7] = Gd - Cd ; - - ip[1] = Add + Hd; - ip[2] = Add - Hd; - - ip[3] = Ed + Dd ; - ip[4] = Ed - Dd ; - - ip[5] = Fd + Bdd; - ip[6] = Fd - Bdd; - } - - ip += 8; /* next row */ - } - - ip = input; - - for ( i = 0; i < 8; i++) { - /* Check for non-zero values (bitwise or faster than ||) */ - if ( ip[1 * 8] | ip[2 * 8] | ip[3 * 8] | - ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) { - - A = M(xC1S7, ip[1*8]) + M(xC7S1, ip[7*8]); - B = M(xC7S1, ip[1*8]) - M(xC1S7, ip[7*8]); - C = M(xC3S5, ip[3*8]) + M(xC5S3, ip[5*8]); - D = M(xC3S5, ip[5*8]) - M(xC5S3, ip[3*8]); - - Ad = M(xC4S4, (A - C)); - Bd = M(xC4S4, (B - D)); - - Cd = A + C; - Dd = B + D; - - E = M(xC4S4, (ip[0*8] + ip[4*8])) + 8; - F = M(xC4S4, (ip[0*8] - ip[4*8])) + 8; - - if(type==1){ //HACK - E += 16*128; - F += 16*128; - } - - G = M(xC2S6, ip[2*8]) + M(xC6S2, ip[6*8]); - H = M(xC6S2, ip[2*8]) - M(xC2S6, ip[6*8]); - - Ed = E - G; - Gd = E + G; - - Add = F + Ad; - Bdd = Bd - H; - - Fd = F - Ad; - Hd = Bd + H; - - /* Final sequence of operations over-write original inputs. */ - if(type==0){ - ip[0*8] = (Gd + Cd ) >> 4; - ip[7*8] = (Gd - Cd ) >> 4; - - ip[1*8] = (Add + Hd ) >> 4; - ip[2*8] = (Add - Hd ) >> 4; - - ip[3*8] = (Ed + Dd ) >> 4; - ip[4*8] = (Ed - Dd ) >> 4; - - ip[5*8] = (Fd + Bdd ) >> 4; - ip[6*8] = (Fd - Bdd ) >> 4; - }else if(type==1){ - dst[0*stride] = cm[(Gd + Cd ) >> 4]; - dst[7*stride] = cm[(Gd - Cd ) >> 4]; - - dst[1*stride] = cm[(Add + Hd ) >> 4]; - dst[2*stride] = cm[(Add - Hd ) >> 4]; - - dst[3*stride] = cm[(Ed + Dd ) >> 4]; - dst[4*stride] = cm[(Ed - Dd ) >> 4]; - - dst[5*stride] = cm[(Fd + Bdd ) >> 4]; - dst[6*stride] = cm[(Fd - Bdd ) >> 4]; - }else{ - dst[0*stride] = cm[dst[0*stride] + ((Gd + Cd ) >> 4)]; - dst[7*stride] = cm[dst[7*stride] + ((Gd - Cd ) >> 4)]; - - dst[1*stride] = cm[dst[1*stride] + ((Add + Hd ) >> 4)]; - dst[2*stride] = cm[dst[2*stride] + ((Add - Hd ) >> 4)]; - - dst[3*stride] = cm[dst[3*stride] + ((Ed + Dd ) >> 4)]; - dst[4*stride] = cm[dst[4*stride] + ((Ed - Dd ) >> 4)]; - - dst[5*stride] = cm[dst[5*stride] + ((Fd + Bdd ) >> 4)]; - dst[6*stride] = cm[dst[6*stride] + ((Fd - Bdd ) >> 4)]; - } - - } else { - if(type==0){ - ip[0*8] = - ip[1*8] = - ip[2*8] = - ip[3*8] = - ip[4*8] = - ip[5*8] = - ip[6*8] = - ip[7*8] = ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20); - }else if(type==1){ - dst[0*stride]= - dst[1*stride]= - dst[2*stride]= - dst[3*stride]= - dst[4*stride]= - dst[5*stride]= - dst[6*stride]= - dst[7*stride]= cm[128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)]; - }else{ - if(ip[0*8]){ - int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20); - dst[0*stride] = cm[dst[0*stride] + v]; - dst[1*stride] = cm[dst[1*stride] + v]; - dst[2*stride] = cm[dst[2*stride] + v]; - dst[3*stride] = cm[dst[3*stride] + v]; - dst[4*stride] = cm[dst[4*stride] + v]; - dst[5*stride] = cm[dst[5*stride] + v]; - dst[6*stride] = cm[dst[6*stride] + v]; - dst[7*stride] = cm[dst[7*stride] + v]; - } - } - } - - ip++; /* next column */ - dst++; - } -} - -void ff_vp3_idct_c(DCTELEM *block/* align 16*/){ - idct(NULL, 0, block, 0); -} - -void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){ - idct(dest, line_size, block, 1); -} - -void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){ - idct(dest, line_size, block, 2); -} - -void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/){ - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int i, dc = block[0]; - dc = (46341*dc)>>16; - dc = (46341*dc + (8<<16))>>20; - - for(i = 0; i < 8; i++){ - dest[0] = cm[dest[0]+dc]; - dest[1] = cm[dest[1]+dc]; - dest[2] = cm[dest[2]+dc]; - dest[3] = cm[dest[3]+dc]; - dest[4] = cm[dest[4]+dc]; - dest[5] = cm[dest[5]+dc]; - dest[6] = cm[dest[6]+dc]; - dest[7] = cm[dest[7]+dc]; - dest += line_size; - } -} - -void ff_vp3_v_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values) -{ - unsigned char *end; - int filter_value; - const int nstride= -stride; - - for (end= first_pixel + 8; first_pixel < end; first_pixel++) { - filter_value = - (first_pixel[2 * nstride] - first_pixel[ stride]) - +3*(first_pixel[0 ] - first_pixel[nstride]); - filter_value = bounding_values[(filter_value + 4) >> 3]; - first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value); - first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value); - } -} - -void ff_vp3_h_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values) -{ - unsigned char *end; - int filter_value; - - for (end= first_pixel + 8*stride; first_pixel != end; first_pixel += stride) { - filter_value = - (first_pixel[-2] - first_pixel[ 1]) - +3*(first_pixel[ 0] - first_pixel[-1]); - filter_value = bounding_values[(filter_value + 4) >> 3]; - first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value); - first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value); - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/vp5.c b/tizen/distrib/ffmpeg/libavcodec/vp5.c deleted file mode 100644 index 1479344..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp5.c +++ /dev/null @@ -1,280 +0,0 @@ -/** - * @file - * VP5 compatible video decoder - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" - -#include "vp56.h" -#include "vp56data.h" -#include "vp5data.h" - - -static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, - int *golden_frame) -{ - VP56RangeCoder *c = &s->c; - int rows, cols; - - vp56_init_range_decoder(&s->c, buf, buf_size); - s->framep[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c); - vp56_rac_get(c); - vp56_init_dequant(s, vp56_rac_gets(c, 6)); - if (s->framep[VP56_FRAME_CURRENT]->key_frame) - { - vp56_rac_gets(c, 8); - if(vp56_rac_gets(c, 5) > 5) - return 0; - vp56_rac_gets(c, 2); - if (vp56_rac_get(c)) { - av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); - return 0; - } - rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ - cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */ - vp56_rac_gets(c, 8); /* number of displayed macroblock rows */ - vp56_rac_gets(c, 8); /* number of displayed macroblock cols */ - vp56_rac_gets(c, 2); - if (!s->macroblocks || /* first frame */ - 16*cols != s->avctx->coded_width || - 16*rows != s->avctx->coded_height) { - avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); - return 2; - } - } else if (!s->macroblocks) - return 0; - return 1; -} - -static void vp5_parse_vector_adjustment(VP56Context *s, VP56mv *vect) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - int comp, di; - - for (comp=0; comp<2; comp++) { - int delta = 0; - if (vp56_rac_get_prob(c, model->vector_dct[comp])) { - int sign = vp56_rac_get_prob(c, model->vector_sig[comp]); - di = vp56_rac_get_prob(c, model->vector_pdi[comp][0]); - di |= vp56_rac_get_prob(c, model->vector_pdi[comp][1]) << 1; - delta = vp56_rac_get_tree(c, vp56_pva_tree, - model->vector_pdv[comp]); - delta = di | (delta << 2); - delta = (delta ^ -sign) + sign; - } - if (!comp) - vect->x = delta; - else - vect->y = delta; - } -} - -static void vp5_parse_vector_models(VP56Context *s) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - int comp, node; - - for (comp=0; comp<2; comp++) { - if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0])) - model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); - if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1])) - model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); - if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2])) - model->vector_pdi[comp][0] = vp56_rac_gets_nn(c, 7); - if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3])) - model->vector_pdi[comp][1] = vp56_rac_gets_nn(c, 7); - } - - for (comp=0; comp<2; comp++) - for (node=0; node<7; node++) - if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node])) - model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); -} - -static void vp5_parse_coeff_models(VP56Context *s) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - uint8_t def_prob[11]; - int node, cg, ctx; - int ct; /* code type */ - int pt; /* plane type (0 for Y, 1 for U or V) */ - - memset(def_prob, 0x80, sizeof(def_prob)); - - for (pt=0; pt<2; pt++) - for (node=0; node<11; node++) - if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) { - def_prob[node] = vp56_rac_gets_nn(c, 7); - model->coeff_dccv[pt][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - model->coeff_dccv[pt][node] = def_prob[node]; - } - - for (ct=0; ct<3; ct++) - for (pt=0; pt<2; pt++) - for (cg=0; cg<6; cg++) - for (node=0; node<11; node++) - if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) { - def_prob[node] = vp56_rac_gets_nn(c, 7); - model->coeff_ract[pt][ct][cg][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - model->coeff_ract[pt][ct][cg][node] = def_prob[node]; - } - - /* coeff_dcct is a linear combination of coeff_dccv */ - for (pt=0; pt<2; pt++) - for (ctx=0; ctx<36; ctx++) - for (node=0; node<5; node++) - model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254); - - /* coeff_acct is a linear combination of coeff_ract */ - for (ct=0; ct<3; ct++) - for (pt=0; pt<2; pt++) - for (cg=0; cg<3; cg++) - for (ctx=0; ctx<6; ctx++) - for (node=0; node<5; node++) - model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254); -} - -static void vp5_parse_coeff(VP56Context *s) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - uint8_t *permute = s->scantable.permutated; - uint8_t *model1, *model2; - int coeff, sign, coeff_idx; - int b, i, cg, idx, ctx, ctx_last; - int pt = 0; /* plane type (0 for Y, 1 for U or V) */ - - for (b=0; b<6; b++) { - int ct = 1; /* code type */ - - if (b > 3) pt = 1; - - ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0] - + s->above_blocks[s->above_block_idx[b]].not_null_dc; - model1 = model->coeff_dccv[pt]; - model2 = model->coeff_dcct[pt][ctx]; - - for (coeff_idx=0; coeff_idx<64; ) { - if (vp56_rac_get_prob(c, model2[0])) { - if (vp56_rac_get_prob(c, model2[2])) { - if (vp56_rac_get_prob(c, model2[3])) { - s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4; - idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); - sign = vp56_rac_get(c); - coeff = vp56_coeff_bias[idx+5]; - for (i=vp56_coeff_bit_length[idx]; i>=0; i--) - coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; - } else { - if (vp56_rac_get_prob(c, model2[4])) { - coeff = 3 + vp56_rac_get_prob(c, model1[5]); - s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3; - } else { - coeff = 2; - s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 2; - } - sign = vp56_rac_get(c); - } - ct = 2; - } else { - ct = 1; - s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 1; - sign = vp56_rac_get(c); - coeff = 1; - } - coeff = (coeff ^ -sign) + sign; - if (coeff_idx) - coeff *= s->dequant_ac; - s->block_coeff[b][permute[coeff_idx]] = coeff; - } else { - if (ct && !vp56_rac_get_prob(c, model2[1])) - break; - ct = 0; - s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0; - } - - cg = vp5_coeff_groups[++coeff_idx]; - ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx]; - model1 = model->coeff_ract[pt][ct][cg]; - model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx]; - } - - ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24); - s->coeff_ctx_last[vp56_b6to4[b]] = coeff_idx; - if (coeff_idx < ctx_last) - for (i=coeff_idx; i<=ctx_last; i++) - s->coeff_ctx[vp56_b6to4[b]][i] = 5; - s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[vp56_b6to4[b]][0]; - } -} - -static void vp5_default_models_init(VP56Context *s) -{ - VP56Model *model = s->modelp; - int i; - - for (i=0; i<2; i++) { - model->vector_sig[i] = 0x80; - model->vector_dct[i] = 0x80; - model->vector_pdi[i][0] = 0x55; - model->vector_pdi[i][1] = 0x80; - } - memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); - memset(model->vector_pdv, 0x80, sizeof(model->vector_pdv)); -} - -static av_cold int vp5_decode_init(AVCodecContext *avctx) -{ - VP56Context *s = avctx->priv_data; - - vp56_init(avctx, 1, 0); - s->vp56_coord_div = vp5_coord_div; - s->parse_vector_adjustment = vp5_parse_vector_adjustment; - s->parse_coeff = vp5_parse_coeff; - s->default_models_init = vp5_default_models_init; - s->parse_vector_models = vp5_parse_vector_models; - s->parse_coeff_models = vp5_parse_coeff_models; - s->parse_header = vp5_parse_header; - - return 0; -} - -AVCodec vp5_decoder = { - "vp5", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VP5, - sizeof(VP56Context), - vp5_decode_init, - NULL, - vp56_free, - vp56_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vp56.c b/tizen/distrib/ffmpeg/libavcodec/vp56.c deleted file mode 100644 index 74fe5ff..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp56.c +++ /dev/null @@ -1,696 +0,0 @@ -/** - * @file - * VP5 and VP6 compatible video decoder (common features) - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" - -#include "vp56.h" -#include "vp56data.h" - - -void vp56_init_dequant(VP56Context *s, int quantizer) -{ - s->quantizer = quantizer; - s->dequant_dc = vp56_dc_dequant[quantizer] << 2; - s->dequant_ac = vp56_ac_dequant[quantizer] << 2; - memset(s->qscale_table, quantizer, s->mb_width); -} - -static int vp56_get_vectors_predictors(VP56Context *s, int row, int col, - VP56Frame ref_frame) -{ - int nb_pred = 0; - VP56mv vect[2] = {{0,0}, {0,0}}; - int pos, offset; - VP56mv mvp; - - for (pos=0; pos<12; pos++) { - mvp.x = col + vp56_candidate_predictor_pos[pos][0]; - mvp.y = row + vp56_candidate_predictor_pos[pos][1]; - if (mvp.x < 0 || mvp.x >= s->mb_width || - mvp.y < 0 || mvp.y >= s->mb_height) - continue; - offset = mvp.x + s->mb_width*mvp.y; - - if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame) - continue; - if ((s->macroblocks[offset].mv.x == vect[0].x && - s->macroblocks[offset].mv.y == vect[0].y) || - (s->macroblocks[offset].mv.x == 0 && - s->macroblocks[offset].mv.y == 0)) - continue; - - vect[nb_pred++] = s->macroblocks[offset].mv; - if (nb_pred > 1) { - nb_pred = -1; - break; - } - s->vector_candidate_pos = pos; - } - - s->vector_candidate[0] = vect[0]; - s->vector_candidate[1] = vect[1]; - - return nb_pred+1; -} - -static void vp56_parse_mb_type_models(VP56Context *s) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - int i, ctx, type; - - for (ctx=0; ctx<3; ctx++) { - if (vp56_rac_get_prob(c, 174)) { - int idx = vp56_rac_gets(c, 4); - memcpy(model->mb_types_stats[ctx], - vp56_pre_def_mb_type_stats[idx][ctx], - sizeof(model->mb_types_stats[ctx])); - } - if (vp56_rac_get_prob(c, 254)) { - for (type=0; type<10; type++) { - for(i=0; i<2; i++) { - if (vp56_rac_get_prob(c, 205)) { - int delta, sign = vp56_rac_get(c); - - delta = vp56_rac_get_tree(c, vp56_pmbtm_tree, - vp56_mb_type_model_model); - if (!delta) - delta = 4 * vp56_rac_gets(c, 7); - model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign; - } - } - } - } - } - - /* compute MB type probability tables based on previous MB type */ - for (ctx=0; ctx<3; ctx++) { - int p[10]; - - for (type=0; type<10; type++) - p[type] = 100 * model->mb_types_stats[ctx][type][1]; - - for (type=0; type<10; type++) { - int p02, p34, p0234, p17, p56, p89, p5689, p156789; - - /* conservative MB type probability */ - model->mb_type[ctx][type][0] = 255 - (255 * model->mb_types_stats[ctx][type][0]) / (1 + model->mb_types_stats[ctx][type][0] + model->mb_types_stats[ctx][type][1]); - - p[type] = 0; /* same MB type => weight is null */ - - /* binary tree parsing probabilities */ - p02 = p[0] + p[2]; - p34 = p[3] + p[4]; - p0234 = p02 + p34; - p17 = p[1] + p[7]; - p56 = p[5] + p[6]; - p89 = p[8] + p[9]; - p5689 = p56 + p89; - p156789 = p17 + p5689; - - model->mb_type[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789); - model->mb_type[ctx][type][2] = 1 + 255 * p02 / (1+p0234); - model->mb_type[ctx][type][3] = 1 + 255 * p17 / (1+p156789); - model->mb_type[ctx][type][4] = 1 + 255 * p[0] / (1+p02); - model->mb_type[ctx][type][5] = 1 + 255 * p[3] / (1+p34); - model->mb_type[ctx][type][6] = 1 + 255 * p[1] / (1+p17); - model->mb_type[ctx][type][7] = 1 + 255 * p56 / (1+p5689); - model->mb_type[ctx][type][8] = 1 + 255 * p[5] / (1+p56); - model->mb_type[ctx][type][9] = 1 + 255 * p[8] / (1+p89); - - /* restore initial value */ - p[type] = 100 * model->mb_types_stats[ctx][type][1]; - } - } -} - -static VP56mb vp56_parse_mb_type(VP56Context *s, - VP56mb prev_type, int ctx) -{ - uint8_t *mb_type_model = s->modelp->mb_type[ctx][prev_type]; - VP56RangeCoder *c = &s->c; - - if (vp56_rac_get_prob(c, mb_type_model[0])) - return prev_type; - else - return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model); -} - -static void vp56_decode_4mv(VP56Context *s, int row, int col) -{ - VP56mv mv = {0,0}; - int type[4]; - int b; - - /* parse each block type */ - for (b=0; b<4; b++) { - type[b] = vp56_rac_gets(&s->c, 2); - if (type[b]) - type[b]++; /* only returns 0, 2, 3 or 4 (all INTER_PF) */ - } - - /* get vectors */ - for (b=0; b<4; b++) { - switch (type[b]) { - case VP56_MB_INTER_NOVEC_PF: - s->mv[b] = (VP56mv) {0,0}; - break; - case VP56_MB_INTER_DELTA_PF: - s->parse_vector_adjustment(s, &s->mv[b]); - break; - case VP56_MB_INTER_V1_PF: - s->mv[b] = s->vector_candidate[0]; - break; - case VP56_MB_INTER_V2_PF: - s->mv[b] = s->vector_candidate[1]; - break; - } - mv.x += s->mv[b].x; - mv.y += s->mv[b].y; - } - - /* this is the one selected for the whole MB for prediction */ - s->macroblocks[row * s->mb_width + col].mv = s->mv[3]; - - /* chroma vectors are average luma vectors */ - if (s->avctx->codec->id == CODEC_ID_VP5) { - s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2); - s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2); - } else { - s->mv[4] = s->mv[5] = (VP56mv) {mv.x/4, mv.y/4}; - } -} - -static VP56mb vp56_decode_mv(VP56Context *s, int row, int col) -{ - VP56mv *mv, vect = {0,0}; - int ctx, b; - - ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS); - s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx); - s->macroblocks[row * s->mb_width + col].type = s->mb_type; - - switch (s->mb_type) { - case VP56_MB_INTER_V1_PF: - mv = &s->vector_candidate[0]; - break; - - case VP56_MB_INTER_V2_PF: - mv = &s->vector_candidate[1]; - break; - - case VP56_MB_INTER_V1_GF: - vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); - mv = &s->vector_candidate[0]; - break; - - case VP56_MB_INTER_V2_GF: - vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); - mv = &s->vector_candidate[1]; - break; - - case VP56_MB_INTER_DELTA_PF: - s->parse_vector_adjustment(s, &vect); - mv = &vect; - break; - - case VP56_MB_INTER_DELTA_GF: - vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); - s->parse_vector_adjustment(s, &vect); - mv = &vect; - break; - - case VP56_MB_INTER_4V: - vp56_decode_4mv(s, row, col); - return s->mb_type; - - default: - mv = &vect; - break; - } - - s->macroblocks[row*s->mb_width + col].mv = *mv; - - /* same vector for all blocks */ - for (b=0; b<6; b++) - s->mv[b] = *mv; - - return s->mb_type; -} - -static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame) -{ - int idx = s->scantable.permutated[0]; - int b; - - for (b=0; b<6; b++) { - VP56RefDc *ab = &s->above_blocks[s->above_block_idx[b]]; - VP56RefDc *lb = &s->left_block[vp56_b6to4[b]]; - int count = 0; - int dc = 0; - int i; - - if (ref_frame == lb->ref_frame) { - dc += lb->dc_coeff; - count++; - } - if (ref_frame == ab->ref_frame) { - dc += ab->dc_coeff; - count++; - } - if (s->avctx->codec->id == CODEC_ID_VP5) - for (i=0; i<2; i++) - if (count < 2 && ref_frame == ab[-1+2*i].ref_frame) { - dc += ab[-1+2*i].dc_coeff; - count++; - } - if (count == 0) - dc = s->prev_dc[vp56_b2p[b]][ref_frame]; - else if (count == 2) - dc /= 2; - - s->block_coeff[b][idx] += dc; - s->prev_dc[vp56_b2p[b]][ref_frame] = s->block_coeff[b][idx]; - ab->dc_coeff = s->block_coeff[b][idx]; - ab->ref_frame = ref_frame; - lb->dc_coeff = s->block_coeff[b][idx]; - lb->ref_frame = ref_frame; - s->block_coeff[b][idx] *= s->dequant_dc; - } -} - -static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv, - int stride, int dx, int dy) -{ - int t = vp56_filter_threshold[s->quantizer]; - if (dx) s->vp56dsp.edge_filter_hor(yuv + 10-dx , stride, t); - if (dy) s->vp56dsp.edge_filter_ver(yuv + stride*(10-dy), stride, t); -} - -static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src, - int stride, int x, int y) -{ - uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b]; - uint8_t *src_block; - int src_offset; - int overlap_offset = 0; - int mask = s->vp56_coord_div[b] - 1; - int deblock_filtering = s->deblock_filtering; - int dx; - int dy; - - if (s->avctx->skip_loop_filter >= AVDISCARD_ALL || - (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY - && !s->framep[VP56_FRAME_CURRENT]->key_frame)) - deblock_filtering = 0; - - dx = s->mv[b].x / s->vp56_coord_div[b]; - dy = s->mv[b].y / s->vp56_coord_div[b]; - - if (b >= 4) { - x /= 2; - y /= 2; - } - x += dx - 2; - y += dy - 2; - - if (x<0 || x+12>=s->plane_width[plane] || - y<0 || y+12>=s->plane_height[plane]) { - ff_emulated_edge_mc(s->edge_emu_buffer, - src + s->block_offset[b] + (dy-2)*stride + (dx-2), - stride, 12, 12, x, y, - s->plane_width[plane], - s->plane_height[plane]); - src_block = s->edge_emu_buffer; - src_offset = 2 + 2*stride; - } else if (deblock_filtering) { - /* only need a 12x12 block, but there is no such dsp function, */ - /* so copy a 16x12 block */ - s->dsp.put_pixels_tab[0][0](s->edge_emu_buffer, - src + s->block_offset[b] + (dy-2)*stride + (dx-2), - stride, 12); - src_block = s->edge_emu_buffer; - src_offset = 2 + 2*stride; - } else { - src_block = src; - src_offset = s->block_offset[b] + dy*stride + dx; - } - - if (deblock_filtering) - vp56_deblock_filter(s, src_block, stride, dx&7, dy&7); - - if (s->mv[b].x & mask) - overlap_offset += (s->mv[b].x > 0) ? 1 : -1; - if (s->mv[b].y & mask) - overlap_offset += (s->mv[b].y > 0) ? stride : -stride; - - if (overlap_offset) { - if (s->filter) - s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset, - stride, s->mv[b], mask, s->filter_selection, b<4); - else - s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset, - src_block+src_offset+overlap_offset, - stride, 8); - } else { - s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8); - } -} - -static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha) -{ - AVFrame *frame_current, *frame_ref; - VP56mb mb_type; - VP56Frame ref_frame; - int b, ab, b_max, plane, off; - - if (s->framep[VP56_FRAME_CURRENT]->key_frame) - mb_type = VP56_MB_INTRA; - else - mb_type = vp56_decode_mv(s, row, col); - ref_frame = vp56_reference_frame[mb_type]; - - s->dsp.clear_blocks(*s->block_coeff); - - s->parse_coeff(s); - - vp56_add_predictors_dc(s, ref_frame); - - frame_current = s->framep[VP56_FRAME_CURRENT]; - frame_ref = s->framep[ref_frame]; - - ab = 6*is_alpha; - b_max = 6 - 2*is_alpha; - - switch (mb_type) { - case VP56_MB_INTRA: - for (b=0; bdsp.idct_put(frame_current->data[plane] + s->block_offset[b], - s->stride[plane], s->block_coeff[b]); - } - break; - - case VP56_MB_INTER_NOVEC_PF: - case VP56_MB_INTER_NOVEC_GF: - for (b=0; bblock_offset[b]; - s->dsp.put_pixels_tab[1][0](frame_current->data[plane] + off, - frame_ref->data[plane] + off, - s->stride[plane], 8); - s->dsp.idct_add(frame_current->data[plane] + off, - s->stride[plane], s->block_coeff[b]); - } - break; - - case VP56_MB_INTER_DELTA_PF: - case VP56_MB_INTER_V1_PF: - case VP56_MB_INTER_V2_PF: - case VP56_MB_INTER_DELTA_GF: - case VP56_MB_INTER_4V: - case VP56_MB_INTER_V1_GF: - case VP56_MB_INTER_V2_GF: - for (b=0; bdata[plane], s->stride[plane], - 16*col+x_off, 16*row+y_off); - s->dsp.idct_add(frame_current->data[plane] + s->block_offset[b], - s->stride[plane], s->block_coeff[b]); - } - break; - } -} - -static int vp56_size_changed(AVCodecContext *avctx) -{ - VP56Context *s = avctx->priv_data; - int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; - int i; - - s->plane_width[0] = s->plane_width[3] = avctx->coded_width; - s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2; - s->plane_height[0] = s->plane_height[3] = avctx->coded_height; - s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; - - for (i=0; i<4; i++) - s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i]; - - s->mb_width = (avctx->coded_width +15) / 16; - s->mb_height = (avctx->coded_height+15) / 16; - - if (s->mb_width > 1000 || s->mb_height > 1000) { - av_log(avctx, AV_LOG_ERROR, "picture too big\n"); - return -1; - } - - s->qscale_table = av_realloc(s->qscale_table, s->mb_width); - s->above_blocks = av_realloc(s->above_blocks, - (4*s->mb_width+6) * sizeof(*s->above_blocks)); - s->macroblocks = av_realloc(s->macroblocks, - s->mb_width*s->mb_height*sizeof(*s->macroblocks)); - av_free(s->edge_emu_buffer_alloc); - s->edge_emu_buffer_alloc = av_malloc(16*stride); - s->edge_emu_buffer = s->edge_emu_buffer_alloc; - if (s->flip < 0) - s->edge_emu_buffer += 15 * stride; - - return 0; -} - -int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - VP56Context *s = avctx->priv_data; - AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; - int remaining_buf_size = avpkt->size; - int is_alpha, av_uninit(alpha_offset); - - if (s->has_alpha) { - if (remaining_buf_size < 3) - return -1; - alpha_offset = bytestream_get_be24(&buf); - remaining_buf_size -= 3; - if (remaining_buf_size < alpha_offset) - return -1; - } - - for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) { - int mb_row, mb_col, mb_row_flip, mb_offset = 0; - int block, y, uv, stride_y, stride_uv; - int golden_frame = 0; - int res; - - s->modelp = &s->models[is_alpha]; - - res = s->parse_header(s, buf, remaining_buf_size, &golden_frame); - if (!res) - return -1; - - if (!is_alpha) { - p->reference = 1; - if (avctx->get_buffer(avctx, p) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if (res == 2) - if (vp56_size_changed(avctx)) { - avctx->release_buffer(avctx, p); - return -1; - } - } - - if (p->key_frame) { - p->pict_type = FF_I_TYPE; - s->default_models_init(s); - for (block=0; blockmb_height*s->mb_width; block++) - s->macroblocks[block].type = VP56_MB_INTRA; - } else { - p->pict_type = FF_P_TYPE; - vp56_parse_mb_type_models(s); - s->parse_vector_models(s); - s->mb_type = VP56_MB_INTER_NOVEC_PF; - } - - s->parse_coeff_models(s); - - memset(s->prev_dc, 0, sizeof(s->prev_dc)); - s->prev_dc[1][VP56_FRAME_CURRENT] = 128; - s->prev_dc[2][VP56_FRAME_CURRENT] = 128; - - for (block=0; block < 4*s->mb_width+6; block++) { - s->above_blocks[block].ref_frame = VP56_FRAME_NONE; - s->above_blocks[block].dc_coeff = 0; - s->above_blocks[block].not_null_dc = 0; - } - s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT; - s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT; - - stride_y = p->linesize[0]; - stride_uv = p->linesize[1]; - - if (s->flip < 0) - mb_offset = 7; - - /* main macroblocks loop */ - for (mb_row=0; mb_rowmb_height; mb_row++) { - if (s->flip < 0) - mb_row_flip = s->mb_height - mb_row - 1; - else - mb_row_flip = mb_row; - - for (block=0; block<4; block++) { - s->left_block[block].ref_frame = VP56_FRAME_NONE; - s->left_block[block].dc_coeff = 0; - s->left_block[block].not_null_dc = 0; - } - memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx)); - memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last)); - - s->above_block_idx[0] = 1; - s->above_block_idx[1] = 2; - s->above_block_idx[2] = 1; - s->above_block_idx[3] = 2; - s->above_block_idx[4] = 2*s->mb_width + 2 + 1; - s->above_block_idx[5] = 3*s->mb_width + 4 + 1; - - s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y; - s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y; - s->block_offset[1] = s->block_offset[0] + 8; - s->block_offset[3] = s->block_offset[2] + 8; - s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; - s->block_offset[5] = s->block_offset[4]; - - for (mb_col=0; mb_colmb_width; mb_col++) { - vp56_decode_mb(s, mb_row, mb_col, is_alpha); - - for (y=0; y<4; y++) { - s->above_block_idx[y] += 2; - s->block_offset[y] += 16; - } - - for (uv=4; uv<6; uv++) { - s->above_block_idx[uv] += 1; - s->block_offset[uv] += 8; - } - } - } - - if (p->key_frame || golden_frame) { - if (s->framep[VP56_FRAME_GOLDEN]->data[0] && - s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); - s->framep[VP56_FRAME_GOLDEN] = p; - } - - if (s->has_alpha) { - FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], - s->framep[VP56_FRAME_GOLDEN2]); - buf += alpha_offset; - remaining_buf_size -= alpha_offset; - } - } - - if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] || - s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) { - if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] && - s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2]) - FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], - s->framep[VP56_FRAME_UNUSED]); - else - FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], - s->framep[VP56_FRAME_UNUSED2]); - } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); - FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], - s->framep[VP56_FRAME_PREVIOUS]); - - p->qstride = 0; - p->qscale_table = s->qscale_table; - p->qscale_type = FF_QSCALE_TYPE_VP56; - *(AVFrame*)data = *p; - *data_size = sizeof(AVFrame); - - return avpkt->size; -} - -av_cold void vp56_init(AVCodecContext *avctx, int flip, int has_alpha) -{ - VP56Context *s = avctx->priv_data; - int i; - - s->avctx = avctx; - avctx->pix_fmt = has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; - - if (avctx->idct_algo == FF_IDCT_AUTO) - avctx->idct_algo = FF_IDCT_VP3; - dsputil_init(&s->dsp, avctx); - ff_vp56dsp_init(&s->vp56dsp, avctx->codec->id); - ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); - - for (i=0; i<4; i++) - s->framep[i] = &s->frames[i]; - s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN]; - s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2]; - s->edge_emu_buffer_alloc = NULL; - - s->above_blocks = NULL; - s->macroblocks = NULL; - s->quantizer = -1; - s->deblock_filtering = 1; - - s->filter = NULL; - - s->has_alpha = has_alpha; - if (flip) { - s->flip = -1; - s->frbi = 2; - s->srbi = 0; - } else { - s->flip = 1; - s->frbi = 0; - s->srbi = 2; - } -} - -av_cold int vp56_free(AVCodecContext *avctx) -{ - VP56Context *s = avctx->priv_data; - - av_freep(&s->qscale_table); - av_freep(&s->above_blocks); - av_freep(&s->macroblocks); - av_freep(&s->edge_emu_buffer_alloc); - if (s->framep[VP56_FRAME_GOLDEN]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); - if (s->framep[VP56_FRAME_GOLDEN2]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]); - if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/vp56.h b/tizen/distrib/ffmpeg/libavcodec/vp56.h deleted file mode 100644 index 89eba05..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp56.h +++ /dev/null @@ -1,270 +0,0 @@ -/** - * @file - * VP5 and VP6 compatible video decoder (common features) - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VP56_H -#define AVCODEC_VP56_H - -#include "vp56data.h" -#include "dsputil.h" -#include "get_bits.h" -#include "bytestream.h" -#include "vp56dsp.h" - -typedef struct vp56_context VP56Context; -typedef struct vp56_mv VP56mv; - -typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, - VP56mv *vect); -typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, - int offset1, int offset2, int stride, - VP56mv mv, int mask, int select, int luma); -typedef void (*VP56ParseCoeff)(VP56Context *s); -typedef void (*VP56DefaultModelsInit)(VP56Context *s); -typedef void (*VP56ParseVectorModels)(VP56Context *s); -typedef void (*VP56ParseCoeffModels)(VP56Context *s); -typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf, - int buf_size, int *golden_frame); - -typedef struct { - int high; - int bits; - const uint8_t *buffer; - const uint8_t *end; - unsigned long code_word; -} VP56RangeCoder; - -typedef struct { - uint8_t not_null_dc; - VP56Frame ref_frame; - DCTELEM dc_coeff; -} VP56RefDc; - -struct vp56_mv { - int x; - int y; -}; - -typedef struct { - uint8_t type; - VP56mv mv; -} VP56Macroblock; - -typedef struct { - uint8_t coeff_reorder[64]; /* used in vp6 only */ - uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ - uint8_t vector_sig[2]; /* delta sign */ - uint8_t vector_dct[2]; /* delta coding types */ - uint8_t vector_pdi[2][2]; /* predefined delta init */ - uint8_t vector_pdv[2][7]; /* predefined delta values */ - uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */ - uint8_t coeff_dccv[2][11]; /* DC coeff value */ - uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ - uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ - uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */ - uint8_t coeff_runv[2][14]; /* run value (vp6 only) */ - uint8_t mb_type[3][10][10]; /* model for decoding MB type */ - uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */ -} VP56Model; - -struct vp56_context { - AVCodecContext *avctx; - DSPContext dsp; - VP56DSPContext vp56dsp; - ScanTable scantable; - AVFrame frames[4]; - AVFrame *framep[6]; - uint8_t *edge_emu_buffer_alloc; - uint8_t *edge_emu_buffer; - VP56RangeCoder c; - VP56RangeCoder cc; - VP56RangeCoder *ccp; - int sub_version; - - /* frame info */ - int plane_width[4]; - int plane_height[4]; - int mb_width; /* number of horizontal MB */ - int mb_height; /* number of vertical MB */ - int block_offset[6]; - - int quantizer; - uint16_t dequant_dc; - uint16_t dequant_ac; - int8_t *qscale_table; - - /* DC predictors management */ - VP56RefDc *above_blocks; - VP56RefDc left_block[4]; - int above_block_idx[6]; - DCTELEM prev_dc[3][3]; /* [plan][ref_frame] */ - - /* blocks / macroblock */ - VP56mb mb_type; - VP56Macroblock *macroblocks; - DECLARE_ALIGNED(16, DCTELEM, block_coeff)[6][64]; - - /* motion vectors */ - VP56mv mv[6]; /* vectors for each block in MB */ - VP56mv vector_candidate[2]; - int vector_candidate_pos; - - /* filtering hints */ - int filter_header; /* used in vp6 only */ - int deblock_filtering; - int filter_selection; - int filter_mode; - int max_vector_length; - int sample_variance_threshold; - - uint8_t coeff_ctx[4][64]; /* used in vp5 only */ - uint8_t coeff_ctx_last[4]; /* used in vp5 only */ - - int has_alpha; - - /* upside-down flipping hints */ - int flip; /* are we flipping ? */ - int frbi; /* first row block index in MB */ - int srbi; /* second row block index in MB */ - int stride[4]; /* stride for each plan */ - - const uint8_t *vp56_coord_div; - VP56ParseVectorAdjustment parse_vector_adjustment; - VP56Filter filter; - VP56ParseCoeff parse_coeff; - VP56DefaultModelsInit default_models_init; - VP56ParseVectorModels parse_vector_models; - VP56ParseCoeffModels parse_coeff_models; - VP56ParseHeader parse_header; - - VP56Model *modelp; - VP56Model models[2]; - - /* huffman decoding */ - int use_huffman; - GetBitContext gb; - VLC dccv_vlc[2]; - VLC runv_vlc[2]; - VLC ract_vlc[2][3][6]; - unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ -}; - - -void vp56_init(AVCodecContext *avctx, int flip, int has_alpha); -int vp56_free(AVCodecContext *avctx); -void vp56_init_dequant(VP56Context *s, int quantizer); -int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt); - - -/** - * vp56 specific range coder implementation - */ - -static inline void vp56_init_range_decoder(VP56RangeCoder *c, - const uint8_t *buf, int buf_size) -{ - c->high = 255; - c->bits = 8; - c->buffer = buf; - c->end = buf + buf_size; - c->code_word = bytestream_get_be16(&c->buffer); -} - -static inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) -{ - unsigned int low = 1 + (((c->high - 1) * prob) / 256); - unsigned int low_shift = low << 8; - int bit = c->code_word >= low_shift; - - if (bit) { - c->high -= low; - c->code_word -= low_shift; - } else { - c->high = low; - } - - /* normalize */ - while (c->high < 128) { - c->high <<= 1; - c->code_word <<= 1; - if (--c->bits == 0 && c->buffer < c->end) { - c->bits = 8; - c->code_word |= *c->buffer++; - } - } - return bit; -} - -static inline int vp56_rac_get(VP56RangeCoder *c) -{ - /* equiprobable */ - int low = (c->high + 1) >> 1; - unsigned int low_shift = low << 8; - int bit = c->code_word >= low_shift; - if (bit) { - c->high = (c->high - low) << 1; - c->code_word -= low_shift; - } else { - c->high = low << 1; - } - - /* normalize */ - c->code_word <<= 1; - if (--c->bits == 0 && c->buffer < c->end) { - c->bits = 8; - c->code_word |= *c->buffer++; - } - return bit; -} - -static inline int vp56_rac_gets(VP56RangeCoder *c, int bits) -{ - int value = 0; - - while (bits--) { - value = (value << 1) | vp56_rac_get(c); - } - - return value; -} - -static inline int vp56_rac_gets_nn(VP56RangeCoder *c, int bits) -{ - int v = vp56_rac_gets(c, 7) << 1; - return v + !v; -} - -static inline int vp56_rac_get_tree(VP56RangeCoder *c, - const VP56Tree *tree, - const uint8_t *probs) -{ - while (tree->val > 0) { - if (vp56_rac_get_prob(c, probs[tree->prob_idx])) - tree += tree->val; - else - tree++; - } - return -tree->val; -} - -#endif /* AVCODEC_VP56_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vp56data.c b/tizen/distrib/ffmpeg/libavcodec/vp56data.c deleted file mode 100644 index b0515c2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp56data.c +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file - * VP5 and VP6 compatible video decoder (common data) - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "vp56data.h" - -const uint8_t vp56_b2p[] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3 }; -const uint8_t vp56_b6to4[] = { 0, 0, 1, 1, 2, 3 }; - -const uint8_t vp56_coeff_parse_table[6][11] = { - { 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0 }, - { 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0 }, - { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254 }, -}; - -const uint8_t vp56_def_mb_types_stats[3][10][2] = { - { { 69, 42 }, { 1, 2 }, { 1, 7 }, { 44, 42 }, { 6, 22 }, - { 1, 3 }, { 0, 2 }, { 1, 5 }, { 0, 1 }, { 0, 0 }, }, - { { 229, 8 }, { 1, 1 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, - { 1, 2 }, { 0, 1 }, { 0, 0 }, { 1, 1 }, { 0, 0 }, }, - { { 122, 35 }, { 1, 1 }, { 1, 6 }, { 46, 34 }, { 0, 0 }, - { 1, 2 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, -}; - -const VP56Tree vp56_pva_tree[] = { - { 8, 0}, - { 4, 1}, - { 2, 2}, {-0}, {-1}, - { 2, 3}, {-2}, {-3}, - { 4, 4}, - { 2, 5}, {-4}, {-5}, - { 2, 6}, {-6}, {-7}, -}; - -const VP56Tree vp56_pc_tree[] = { - { 4, 6}, - { 2, 7}, {-0}, {-1}, - { 4, 8}, - { 2, 9}, {-2}, {-3}, - { 2,10}, {-4}, {-5}, -}; - -const uint8_t vp56_coeff_bias[] = { 0, 1, 2, 3, 4, 5, 7, 11, 19, 35, 67 }; -const uint8_t vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 }; diff --git a/tizen/distrib/ffmpeg/libavcodec/vp56data.h b/tizen/distrib/ffmpeg/libavcodec/vp56data.h deleted file mode 100644 index 57b0968..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp56data.h +++ /dev/null @@ -1,252 +0,0 @@ -/** - * @file - * VP5 and VP6 compatible video decoder (common data) - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VP56DATA_H -#define AVCODEC_VP56DATA_H - -#include "libavutil/common.h" - -typedef enum { - VP56_FRAME_NONE =-1, - VP56_FRAME_CURRENT = 0, - VP56_FRAME_PREVIOUS = 1, - VP56_FRAME_GOLDEN = 2, - VP56_FRAME_GOLDEN2 = 3, - VP56_FRAME_UNUSED = 4, - VP56_FRAME_UNUSED2 = 5, -} VP56Frame; - -typedef enum { - VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */ - VP56_MB_INTRA = 1, /**< Intra MB */ - VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */ - VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */ - VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */ - VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */ - VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */ - VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */ - VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */ - VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */ -} VP56mb; - -typedef struct { - int8_t val; - int8_t prob_idx; -} VP56Tree; - -extern const uint8_t vp56_b2p[]; -extern const uint8_t vp56_b6to4[]; -extern const uint8_t vp56_coeff_parse_table[6][11]; -extern const uint8_t vp56_def_mb_types_stats[3][10][2]; -extern const VP56Tree vp56_pva_tree[]; -extern const VP56Tree vp56_pc_tree[]; -extern const uint8_t vp56_coeff_bias[]; -extern const uint8_t vp56_coeff_bit_length[]; - -static const VP56Frame vp56_reference_frame[] = { - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_NOVEC_PF */ - VP56_FRAME_CURRENT, /* VP56_MB_INTRA */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_DELTA_PF */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V1_PF */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V2_PF */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_NOVEC_GF */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_DELTA_GF */ - VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_4V */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V1_GF */ - VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V2_GF */ -}; - -static const uint8_t vp56_ac_dequant[64] = { - 94, 92, 90, 88, 86, 82, 78, 74, - 70, 66, 62, 58, 54, 53, 52, 51, - 50, 49, 48, 47, 46, 45, 44, 43, - 42, 40, 39, 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 const uint8_t vp56_dc_dequant[64] = { - 47, 47, 47, 47, 45, 43, 43, 43, - 43, 43, 42, 41, 41, 40, 40, 40, - 40, 35, 35, 35, 35, 33, 33, 33, - 33, 32, 32, 32, 27, 27, 26, 26, - 25, 25, 24, 24, 23, 23, 19, 19, - 19, 19, 18, 18, 17, 16, 16, 16, - 16, 16, 15, 11, 11, 11, 10, 10, - 9, 8, 7, 5, 3, 3, 2, 2, -}; - -static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = { - { { { 9, 15 }, { 32, 25 }, { 7, 19 }, { 9, 21 }, { 1, 12 }, - { 14, 12 }, { 3, 18 }, { 14, 23 }, { 3, 10 }, { 0, 4 }, }, - { { 41, 22 }, { 1, 0 }, { 1, 31 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 1, 7 }, { 0, 1 }, { 98, 25 }, { 4, 10 }, }, - { { 2, 3 }, { 2, 3 }, { 0, 2 }, { 0, 2 }, { 0, 0 }, - { 11, 4 }, { 1, 4 }, { 0, 2 }, { 3, 2 }, { 0, 4 }, }, }, - { { { 48, 39 }, { 1, 2 }, { 11, 27 }, { 29, 44 }, { 7, 27 }, - { 1, 4 }, { 0, 3 }, { 1, 6 }, { 1, 2 }, { 0, 0 }, }, - { { 123, 37 }, { 6, 4 }, { 1, 27 }, { 0, 0 }, { 0, 0 }, - { 5, 8 }, { 1, 7 }, { 0, 1 }, { 12, 10 }, { 0, 2 }, }, - { { 49, 46 }, { 3, 4 }, { 7, 31 }, { 42, 41 }, { 0, 0 }, - { 2, 6 }, { 1, 7 }, { 1, 4 }, { 2, 4 }, { 0, 1 }, }, }, - { { { 21, 32 }, { 1, 2 }, { 4, 10 }, { 32, 43 }, { 6, 23 }, - { 2, 3 }, { 1, 19 }, { 1, 6 }, { 12, 21 }, { 0, 7 }, }, - { { 26, 14 }, { 14, 12 }, { 0, 24 }, { 0, 0 }, { 0, 0 }, - { 55, 17 }, { 1, 9 }, { 0, 36 }, { 5, 7 }, { 1, 3 }, }, - { { 26, 25 }, { 1, 1 }, { 2, 10 }, { 67, 39 }, { 0, 0 }, - { 1, 1 }, { 0, 14 }, { 0, 2 }, { 31, 26 }, { 1, 6 }, }, }, - { { { 69, 83 }, { 0, 0 }, { 0, 2 }, { 10, 29 }, { 3, 12 }, - { 0, 1 }, { 0, 3 }, { 0, 3 }, { 2, 2 }, { 0, 0 }, }, - { { 209, 5 }, { 0, 0 }, { 0, 27 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, - { { 103, 46 }, { 1, 2 }, { 2, 10 }, { 33, 42 }, { 0, 0 }, - { 1, 4 }, { 0, 3 }, { 0, 1 }, { 1, 3 }, { 0, 0 }, }, }, - { { { 11, 20 }, { 1, 4 }, { 18, 36 }, { 43, 48 }, { 13, 35 }, - { 0, 2 }, { 0, 5 }, { 3, 12 }, { 1, 2 }, { 0, 0 }, }, - { { 2, 5 }, { 4, 5 }, { 0, 121 }, { 0, 0 }, { 0, 0 }, - { 0, 3 }, { 2, 4 }, { 1, 4 }, { 2, 2 }, { 0, 1 }, }, - { { 14, 31 }, { 9, 13 }, { 14, 54 }, { 22, 29 }, { 0, 0 }, - { 2, 6 }, { 4, 18 }, { 6, 13 }, { 1, 5 }, { 0, 1 }, }, }, - { { { 70, 44 }, { 0, 1 }, { 2, 10 }, { 37, 46 }, { 8, 26 }, - { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, - { { 175, 5 }, { 0, 1 }, { 0, 48 }, { 0, 0 }, { 0, 0 }, - { 0, 2 }, { 0, 1 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, - { { 85, 39 }, { 0, 0 }, { 1, 9 }, { 69, 40 }, { 0, 0 }, - { 0, 1 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 0 }, }, }, - { { { 8, 15 }, { 0, 1 }, { 8, 21 }, { 74, 53 }, { 22, 42 }, - { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 0, 0 }, }, - { { 83, 5 }, { 2, 3 }, { 0, 102 }, { 0, 0 }, { 0, 0 }, - { 1, 3 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, - { { 31, 28 }, { 0, 0 }, { 3, 14 }, { 130, 34 }, { 0, 0 }, - { 0, 1 }, { 0, 3 }, { 0, 1 }, { 3, 3 }, { 0, 1 }, }, }, - { { { 141, 42 }, { 0, 0 }, { 1, 4 }, { 11, 24 }, { 1, 11 }, - { 0, 1 }, { 0, 1 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, }, - { { 233, 6 }, { 0, 0 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, - { { 171, 25 }, { 0, 0 }, { 1, 5 }, { 25, 21 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, }, - { { { 8, 19 }, { 4, 10 }, { 24, 45 }, { 21, 37 }, { 9, 29 }, - { 0, 3 }, { 1, 7 }, { 11, 25 }, { 0, 2 }, { 0, 1 }, }, - { { 34, 16 }, { 112, 21 }, { 1, 28 }, { 0, 0 }, { 0, 0 }, - { 6, 8 }, { 1, 7 }, { 0, 3 }, { 2, 5 }, { 0, 2 }, }, - { { 17, 21 }, { 68, 29 }, { 6, 15 }, { 13, 22 }, { 0, 0 }, - { 6, 12 }, { 3, 14 }, { 4, 10 }, { 1, 7 }, { 0, 3 }, }, }, - { { { 46, 42 }, { 0, 1 }, { 2, 10 }, { 54, 51 }, { 10, 30 }, - { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, - { { 159, 35 }, { 2, 2 }, { 0, 25 }, { 0, 0 }, { 0, 0 }, - { 3, 6 }, { 0, 5 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, - { { 51, 39 }, { 0, 1 }, { 2, 12 }, { 91, 44 }, { 0, 0 }, - { 0, 2 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 1 }, }, }, - { { { 28, 32 }, { 0, 0 }, { 3, 10 }, { 75, 51 }, { 14, 33 }, - { 0, 1 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, - { { 75, 39 }, { 5, 7 }, { 2, 48 }, { 0, 0 }, { 0, 0 }, - { 3, 11 }, { 2, 16 }, { 1, 4 }, { 7, 10 }, { 0, 2 }, }, - { { 81, 25 }, { 0, 0 }, { 2, 9 }, { 106, 26 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, - { { { 100, 46 }, { 0, 1 }, { 3, 9 }, { 21, 37 }, { 5, 20 }, - { 0, 1 }, { 0, 2 }, { 1, 2 }, { 0, 1 }, { 0, 0 }, }, - { { 212, 21 }, { 0, 1 }, { 0, 9 }, { 0, 0 }, { 0, 0 }, - { 1, 2 }, { 0, 2 }, { 0, 0 }, { 2, 2 }, { 0, 0 }, }, - { { 140, 37 }, { 0, 1 }, { 1, 8 }, { 24, 33 }, { 0, 0 }, - { 1, 2 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, }, - { { { 27, 29 }, { 0, 1 }, { 9, 25 }, { 53, 51 }, { 12, 34 }, - { 0, 1 }, { 0, 3 }, { 1, 5 }, { 0, 2 }, { 0, 0 }, }, - { { 4, 2 }, { 0, 0 }, { 0, 172 }, { 0, 0 }, { 0, 0 }, - { 0, 1 }, { 0, 2 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, }, - { { 14, 23 }, { 1, 3 }, { 11, 53 }, { 90, 31 }, { 0, 0 }, - { 0, 3 }, { 1, 5 }, { 2, 6 }, { 1, 2 }, { 0, 0 }, }, }, - { { { 80, 38 }, { 0, 0 }, { 1, 4 }, { 69, 33 }, { 5, 16 }, - { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, - { { 187, 22 }, { 1, 1 }, { 0, 17 }, { 0, 0 }, { 0, 0 }, - { 3, 6 }, { 0, 4 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, - { { 123, 29 }, { 0, 0 }, { 1, 7 }, { 57, 30 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, }, - { { { 16, 20 }, { 0, 0 }, { 2, 8 }, { 104, 49 }, { 15, 33 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, - { { 133, 6 }, { 1, 2 }, { 1, 70 }, { 0, 0 }, { 0, 0 }, - { 0, 2 }, { 0, 4 }, { 0, 3 }, { 1, 1 }, { 0, 0 }, }, - { { 13, 14 }, { 0, 0 }, { 4, 20 }, { 175, 20 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, - { { { 194, 16 }, { 0, 0 }, { 1, 1 }, { 1, 9 }, { 1, 3 }, - { 0, 0 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, - { { 251, 1 }, { 0, 0 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, - { { 202, 23 }, { 0, 0 }, { 1, 3 }, { 2, 9 }, { 0, 0 }, - { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, }, -}; - -static const uint8_t vp56_filter_threshold[] = { - 14, 14, 13, 13, 12, 12, 10, 10, - 10, 10, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 7, 7, 7, 7, - 7, 7, 6, 6, 6, 6, 6, 6, - 5, 5, 5, 5, 4, 4, 4, 4, - 4, 4, 4, 3, 3, 3, 3, 2, -}; - -static const uint8_t vp56_mb_type_model_model[] = { - 171, 83, 199, 140, 125, 104, -}; - -static const VP56Tree vp56_pmbtm_tree[] = { - { 4, 0}, - { 2, 1}, {-8}, {-4}, - { 8, 2}, - { 6, 3}, - { 4, 4}, - { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0}, -}; - -static const VP56Tree vp56_pmbt_tree[] = { - { 8, 1}, - { 4, 2}, - { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF}, - { 2, 5}, {-VP56_MB_INTER_V1_PF}, {-VP56_MB_INTER_V2_PF}, - { 4, 3}, - { 2, 6}, {-VP56_MB_INTRA}, {-VP56_MB_INTER_4V}, - { 4, 7}, - { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF}, - { 2, 9}, {-VP56_MB_INTER_V1_GF}, {-VP56_MB_INTER_V2_GF}, -}; - -/* relative pos of surrounding blocks, from closest to farthest */ -static const int8_t vp56_candidate_predictor_pos[12][2] = { - { 0, -1 }, - { -1, 0 }, - { -1, -1 }, - { 1, -1 }, - { 0, -2 }, - { -2, 0 }, - { -2, -1 }, - { -1, -2 }, - { 1, -2 }, - { 2, -1 }, - { -2, -2 }, - { 2, -2 }, -}; - -#endif /* AVCODEC_VP56DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vp56dsp.c b/tizen/distrib/ffmpeg/libavcodec/vp56dsp.c deleted file mode 100644 index 9eb9299..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp56dsp.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2006 Aurelien Jacobs - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avcodec.h" -#include "vp56dsp.h" - -/* Gives very similar result than the vp6 version except in a few cases */ -static int vp5_adjust(int v, int t) -{ - int s2, s1 = v >> 31; - v ^= s1; - v -= s1; - v *= v < 2*t; - v -= t; - s2 = v >> 31; - v ^= s2; - v -= s2; - v = t - v; - v += s1; - v ^= s1; - return v; -} - -static int vp6_adjust(int v, int t) -{ - int V = v, s = v >> 31; - V ^= s; - V -= s; - if (V-t-1 >= (unsigned)(t-1)) - return v; - V = 2*t - V; - V += s; - V ^= s; - return V; -} - - -#define VP56_EDGE_FILTER(pfx, suf, pix_inc, line_inc) \ -static void pfx##_edge_filter_##suf(uint8_t *yuv, int stride, int t) \ -{ \ - int pix2_inc = 2 * pix_inc; \ - int i, v; \ - \ - for (i=0; i<12; i++) { \ - v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4)>>3;\ - v = pfx##_adjust(v, t); \ - yuv[-pix_inc] = av_clip_uint8(yuv[-pix_inc] + v); \ - yuv[0] = av_clip_uint8(yuv[0] - v); \ - yuv += line_inc; \ - } \ -} - -VP56_EDGE_FILTER(vp5, hor, 1, stride) -VP56_EDGE_FILTER(vp5, ver, stride, 1) -VP56_EDGE_FILTER(vp6, hor, 1, stride) -VP56_EDGE_FILTER(vp6, ver, stride, 1) - -void ff_vp56dsp_init(VP56DSPContext *s, enum CodecID codec) -{ - if (codec == CODEC_ID_VP5) { - s->edge_filter_hor = vp5_edge_filter_hor; - s->edge_filter_ver = vp5_edge_filter_ver; - } else { - s->edge_filter_hor = vp6_edge_filter_hor; - s->edge_filter_ver = vp6_edge_filter_ver; - } - - if (ARCH_ARM) ff_vp56dsp_init_arm(s, codec); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/vp56dsp.h b/tizen/distrib/ffmpeg/libavcodec/vp56dsp.h deleted file mode 100644 index 2d6941f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp56dsp.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VP56DSP_H -#define AVCODEC_VP56DSP_H - -#include - -typedef struct VP56DSPContext { - void (*edge_filter_hor)(uint8_t *yuv, int stride, int t); - void (*edge_filter_ver)(uint8_t *yuv, int stride, int t); -} VP56DSPContext; - -void ff_vp56dsp_init(VP56DSPContext *s, enum CodecID codec); -void ff_vp56dsp_init_arm(VP56DSPContext *s, enum CodecID codec); - -#endif /* AVCODEC_VP56DSP_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vp5data.h b/tizen/distrib/ffmpeg/libavcodec/vp5data.h deleted file mode 100644 index 5c2d46c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp5data.h +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @file - * VP5 compatible video decoder - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VP5DATA_H -#define AVCODEC_VP5DATA_H - -#include - -static const uint8_t vp5_coeff_groups[] = { - -1, 0, 1, 1, 2, 1, 1, 2, - 2, 1, 1, 2, 2, 2, 1, 2, - 2, 2, 2, 2, 1, 1, 2, 2, - 3, 3, 4, 3, 4, 4, 4, 3, - 3, 3, 3, 3, 4, 3, 3, 3, - 4, 4, 4, 4, 4, 3, 3, 4, - 4, 4, 3, 4, 4, 4, 4, 4, - 4, 4, 5, 5, 5, 5, 5, 5, -}; - -static const uint8_t vp5_vmc_pct[2][11] = { - { 243, 220, 251, 253, 237, 232, 241, 245, 247, 251, 253 }, - { 235, 211, 246, 249, 234, 231, 248, 249, 252, 252, 254 }, -}; - -static const uint8_t vp5_dccv_pct[2][11] = { - { 146, 197, 181, 207, 232, 243, 238, 251, 244, 250, 249 }, - { 179, 219, 214, 240, 250, 254, 244, 254, 254, 254, 254 }, -}; - -static const uint8_t vp5_ract_pct[3][2][6][11] = { - { { { 227, 246, 230, 247, 244, 254, 254, 254, 254, 254, 254 }, - { 202, 254, 209, 231, 231, 249, 249, 253, 254, 254, 254 }, - { 206, 254, 225, 242, 241, 251, 253, 254, 254, 254, 254 }, - { 235, 254, 241, 253, 252, 254, 254, 254, 254, 254, 254 }, - { 234, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, - { { 240, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 238, 254, 240, 253, 254, 254, 254, 254, 254, 254, 254 }, - { 244, 254, 251, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, - { { { 206, 203, 227, 239, 247, 254, 253, 254, 254, 254, 254 }, - { 207, 199, 220, 236, 243, 252, 252, 254, 254, 254, 254 }, - { 212, 219, 230, 243, 244, 253, 252, 254, 254, 254, 254 }, - { 236, 237, 247, 252, 253, 254, 254, 254, 254, 254, 254 }, - { 240, 240, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, - { { 230, 233, 249, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 238, 238, 250, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 248, 251, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, - { { { 225, 239, 227, 231, 244, 253, 243, 254, 254, 253, 254 }, - { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 254 }, - { 235, 249, 238, 240, 251, 254, 249, 254, 253, 253, 254 }, - { 249, 253, 251, 250, 254, 254, 254, 254, 254, 254, 254 }, - { 251, 250, 249, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, - { { 243, 244, 250, 250, 254, 254, 254, 254, 254, 254, 254 }, - { 249, 248, 250, 253, 254, 254, 254, 254, 254, 254, 254 }, - { 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, - { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, -}; - -static const int16_t vp5_dccv_lc[5][36][2] = { - { {154, 61}, {141, 54}, { 90, 45}, { 54, 34}, { 54, 13}, {128, 109}, - {136, 54}, {148, 45}, { 92, 41}, { 54, 33}, { 51, 15}, { 87, 113}, - { 87, 44}, { 97, 40}, { 67, 36}, { 46, 29}, { 41, 15}, { 64, 80}, - { 59, 33}, { 61, 31}, { 51, 28}, { 44, 22}, { 33, 12}, { 49, 63}, - { 69, 12}, { 59, 16}, { 46, 14}, { 31, 13}, { 26, 6}, { 92, 26}, - {128, 108}, { 77, 119}, { 54, 84}, { 26, 71}, { 87, 19}, { 95, 155} }, - { {154, 4}, {182, 0}, {159, -8}, {128, -5}, {143, -5}, {187, 55}, - {182, 0}, {228, -3}, {187, -7}, {174, -9}, {189, -11}, {169, 79}, - {161, -9}, {192, -8}, {187, -9}, {169, -10}, {136, -9}, {184, 40}, - {164, -11}, {179, -10}, {174, -10}, {161, -10}, {115, -7}, {197, 20}, - {195, -11}, {195, -11}, {146, -10}, {110, -6}, { 95, -4}, {195, 39}, - {182, 55}, {172, 77}, {177, 37}, {169, 29}, {172, 52}, { 92, 162} }, - { {174, 80}, {164, 80}, { 95, 80}, { 46, 66}, { 56, 24}, { 36, 193}, - {164, 80}, {166, 77}, {105, 76}, { 49, 68}, { 46, 31}, { 49, 186}, - { 97, 78}, {110, 74}, { 72, 72}, { 44, 60}, { 33, 30}, { 69, 131}, - { 61, 61}, { 69, 63}, { 51, 57}, { 31, 48}, { 26, 27}, { 64, 89}, - { 67, 23}, { 51, 32}, { 36, 33}, { 26, 28}, { 20, 12}, { 44, 68}, - { 26, 197}, { 41, 189}, { 61, 129}, { 28, 103}, { 49, 52}, {-12, 245} }, - { {102, 141}, { 79, 166}, { 72, 162}, { 97, 125}, {179, 4}, {307, 0}, - { 72, 168}, { 69, 175}, { 84, 160}, {105, 127}, {148, 34}, {310, 0}, - { 84, 151}, { 82, 161}, { 87, 153}, { 87, 135}, {115, 51}, {317, 0}, - { 97, 125}, {102, 131}, {105, 125}, { 87, 122}, { 84, 64}, { 54, 184}, - {166, 18}, {146, 43}, {125, 51}, { 90, 64}, { 95, 7}, { 38, 154}, - {294, 0}, { 13, 225}, { 10, 225}, { 67, 168}, { 0, 167}, {161, 94} }, - { {172, 76}, {172, 75}, {136, 80}, { 64, 98}, { 74, 67}, {315, 0}, - {169, 76}, {207, 56}, {164, 66}, { 97, 80}, { 67, 72}, {328, 0}, - {136, 80}, {187, 53}, {154, 62}, { 72, 85}, { -2, 105}, {305, 0}, - { 74, 91}, {128, 64}, {113, 64}, { 61, 77}, { 41, 75}, {259, 0}, - { 46, 84}, { 51, 81}, { 28, 89}, { 31, 78}, { 23, 77}, {202, 0}, - {323, 0}, {323, 0}, {300, 0}, {236, 0}, {195, 0}, {328, 0} }, -}; - -static const int16_t vp5_ract_lc[3][3][5][6][2] = { - { { { {276, 0}, {238, 0}, {195, 0}, {156, 0}, {113, 0}, {274, 0} }, - { { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, - { {192, 59}, {182, 50}, {141, 48}, {110, 40}, { 92, 19}, {125,128} }, - { {169, 87}, {169, 83}, {184, 62}, {220, 16}, {184, 0}, {264, 0} }, - { {212, 40}, {212, 36}, {169, 49}, {174, 27}, { 8,120}, {182, 71} } }, - { { {259, 10}, {197, 19}, {143, 22}, {123, 16}, {110, 8}, {133, 88} }, - { { 0, 1}, {256, 0}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, - { {207, 46}, {187, 50}, { 97, 83}, { 23,100}, { 41, 56}, { 56,188} }, - { {166, 90}, {146,108}, {161, 88}, {136, 95}, {174, 0}, {266, 0} }, - { {264, 7}, {243, 18}, {184, 43}, {-14,154}, { 20,112}, { 20,199} } }, - { { {230, 26}, {197, 22}, {159, 20}, {146, 12}, {136, 4}, { 54,162} }, - { { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, - { {192, 59}, {156, 72}, { 84,101}, { 49,101}, { 79, 47}, { 79,167} }, - { {138,115}, {136,116}, {166, 80}, {238, 0}, {195, 0}, {261, 0} }, - { {225, 33}, {205, 42}, {159, 61}, { 79, 96}, { 92, 66}, { 28,195} } }, - }, { - { { {200, 37}, {197, 18}, {159, 13}, {143, 7}, {102, 5}, {123,126} }, - { {197, 3}, {220, -9}, {210,-12}, {187, -6}, {151, -2}, {174, 80} }, - { {200, 53}, {187, 47}, {159, 40}, {118, 38}, {100, 18}, {141,111} }, - { {179, 78}, {166, 86}, {197, 50}, {207, 27}, {187, 0}, {115,139} }, - { {218, 34}, {220, 29}, {174, 46}, {128, 61}, { 54, 89}, {187, 65} } }, - { { {238, 14}, {197, 18}, {125, 26}, { 90, 25}, { 82, 13}, {161, 86} }, - { {189, 1}, {205, -2}, {156, -4}, {143, -4}, {146, -4}, {172, 72} }, - { {230, 31}, {192, 45}, {102, 76}, { 38, 85}, { 56, 41}, { 64,173} }, - { {166, 91}, {141,111}, {128,116}, {118,109}, {177, 0}, { 23,222} }, - { {253, 14}, {236, 21}, {174, 49}, { 33,118}, { 44, 93}, { 23,187} } }, - { { {218, 28}, {179, 28}, {118, 35}, { 95, 30}, { 72, 24}, {128,108} }, - { {187, 1}, {174, -1}, {125, -1}, {110, -1}, {108, -1}, {202, 52} }, - { {197, 53}, {146, 75}, { 46,118}, { 33,103}, { 64, 50}, {118,126} }, - { {138,114}, {128,122}, {161, 86}, {243, -6}, {195, 0}, { 38,210} }, - { {215, 39}, {179, 58}, { 97,101}, { 95, 85}, { 87, 70}, { 69,152} } }, - }, { - { { {236, 24}, {205, 18}, {172, 12}, {154, 6}, {125, 1}, {169, 75} }, - { {187, 4}, {230, -2}, {228, -4}, {236, -4}, {241, -2}, {192, 66} }, - { {200, 46}, {187, 42}, {159, 34}, {136, 25}, {105, 10}, {179, 62} }, - { {207, 55}, {192, 63}, {192, 54}, {195, 36}, {177, 1}, {143, 98} }, - { {225, 27}, {207, 34}, {200, 30}, {131, 57}, { 97, 60}, {197, 45} } }, - { { {271, 8}, {218, 13}, {133, 19}, { 90, 19}, { 72, 7}, {182, 51} }, - { {179, 1}, {225, -1}, {154, -2}, {110, -1}, { 92, 0}, {195, 41} }, - { {241, 26}, {189, 40}, { 82, 64}, { 33, 60}, { 67, 17}, {120, 94} }, - { {192, 68}, {151, 94}, {146, 90}, {143, 72}, {161, 0}, {113,128} }, - { {256, 12}, {218, 29}, {166, 48}, { 44, 99}, { 31, 87}, {148, 78} } }, - { { {238, 20}, {184, 22}, {113, 27}, { 90, 22}, { 74, 9}, {192, 37} }, - { {184, 0}, {215, -1}, {141, -1}, { 97, 0}, { 49, 0}, {264, 13} }, - { {182, 51}, {138, 61}, { 95, 63}, { 54, 59}, { 64, 25}, {200, 45} }, - { {179, 75}, {156, 87}, {174, 65}, {177, 44}, {174, 0}, {164, 85} }, - { {195, 45}, {148, 65}, {105, 79}, { 95, 72}, { 87, 60}, {169, 63} } }, - } -}; - -static const uint8_t vp5_coord_div[] = { 2, 2, 2, 2, 4, 4 }; - -#endif /* AVCODEC_VP5DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vp6.c b/tizen/distrib/ffmpeg/libavcodec/vp6.c deleted file mode 100644 index 58c31f9..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp6.c +++ /dev/null @@ -1,647 +0,0 @@ -/** - * @file - * VP6 compatible video decoder - * - * Copyright (C) 2006 Aurelien Jacobs - * - * The VP6F decoder accepts an optional 1 byte extradata. It is composed of: - * - upper 4bits: difference between encoded width and visible width - * - lower 4bits: difference between encoded height and visible height - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "avcodec.h" -#include "dsputil.h" -#include "get_bits.h" -#include "huffman.h" - -#include "vp56.h" -#include "vp56data.h" -#include "vp6data.h" - - -static void vp6_parse_coeff(VP56Context *s); -static void vp6_parse_coeff_huffman(VP56Context *s); - -static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, - int *golden_frame) -{ - VP56RangeCoder *c = &s->c; - int parse_filter_info = 0; - int coeff_offset = 0; - int vrt_shift = 0; - int sub_version; - int rows, cols; - int res = 1; - int separated_coeff = buf[0] & 1; - - s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); - vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); - - if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - sub_version = buf[1] >> 3; - if (sub_version > 8) - return 0; - s->filter_header = buf[1] & 0x06; - if (buf[1] & 1) { - av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); - return 0; - } - if (separated_coeff || !s->filter_header) { - coeff_offset = AV_RB16(buf+2) - 2; - buf += 2; - buf_size -= 2; - } - - rows = buf[2]; /* number of stored macroblock rows */ - cols = buf[3]; /* number of stored macroblock cols */ - /* buf[4] is number of displayed macroblock rows */ - /* buf[5] is number of displayed macroblock cols */ - - if (!s->macroblocks || /* first frame */ - 16*cols != s->avctx->coded_width || - 16*rows != s->avctx->coded_height) { - avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); - if (s->avctx->extradata_size == 1) { - s->avctx->width -= s->avctx->extradata[0] >> 4; - s->avctx->height -= s->avctx->extradata[0] & 0x0F; - } - res = 2; - } - - vp56_init_range_decoder(c, buf+6, buf_size-6); - vp56_rac_gets(c, 2); - - parse_filter_info = s->filter_header; - if (sub_version < 8) - vrt_shift = 5; - s->sub_version = sub_version; - } else { - if (!s->sub_version) - return 0; - - if (separated_coeff || !s->filter_header) { - coeff_offset = AV_RB16(buf+1) - 2; - buf += 2; - buf_size -= 2; - } - vp56_init_range_decoder(c, buf+1, buf_size-1); - - *golden_frame = vp56_rac_get(c); - if (s->filter_header) { - s->deblock_filtering = vp56_rac_get(c); - if (s->deblock_filtering) - vp56_rac_get(c); - if (s->sub_version > 7) - parse_filter_info = vp56_rac_get(c); - } - } - - if (parse_filter_info) { - if (vp56_rac_get(c)) { - s->filter_mode = 2; - s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift; - s->max_vector_length = 2 << vp56_rac_gets(c, 3); - } else if (vp56_rac_get(c)) { - s->filter_mode = 1; - } else { - s->filter_mode = 0; - } - if (s->sub_version > 7) - s->filter_selection = vp56_rac_gets(c, 4); - else - s->filter_selection = 16; - } - - s->use_huffman = vp56_rac_get(c); - - s->parse_coeff = vp6_parse_coeff; - if (coeff_offset) { - buf += coeff_offset; - buf_size -= coeff_offset; - if (buf_size < 0) - return 0; - if (s->use_huffman) { - s->parse_coeff = vp6_parse_coeff_huffman; - init_get_bits(&s->gb, buf, buf_size<<3); - } else { - vp56_init_range_decoder(&s->cc, buf, buf_size); - s->ccp = &s->cc; - } - } else { - s->ccp = &s->c; - } - - return res; -} - -static void vp6_coeff_order_table_init(VP56Context *s) -{ - int i, pos, idx = 1; - - s->modelp->coeff_index_to_pos[0] = 0; - for (i=0; i<16; i++) - for (pos=1; pos<64; pos++) - if (s->modelp->coeff_reorder[pos] == i) - s->modelp->coeff_index_to_pos[idx++] = pos; -} - -static void vp6_default_models_init(VP56Context *s) -{ - VP56Model *model = s->modelp; - - model->vector_dct[0] = 0xA2; - model->vector_dct[1] = 0xA4; - model->vector_sig[0] = 0x80; - model->vector_sig[1] = 0x80; - - memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); - memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv)); - memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv)); - memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv)); - memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder)); - - vp6_coeff_order_table_init(s); -} - -static void vp6_parse_vector_models(VP56Context *s) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - int comp, node; - - for (comp=0; comp<2; comp++) { - if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) - model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); - if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) - model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); - } - - for (comp=0; comp<2; comp++) - for (node=0; node<7; node++) - if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node])) - model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); - - for (comp=0; comp<2; comp++) - for (node=0; node<8; node++) - if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node])) - model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7); -} - -/* nodes must ascend by count, but with descending symbol order */ -static int vp6_huff_cmp(const void *va, const void *vb) -{ - const Node *a = va, *b = vb; - return (a->count - b->count)*16 + (b->sym - a->sym); -} - -static void vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], - const uint8_t *map, unsigned size, VLC *vlc) -{ - Node nodes[2*size], *tmp = &nodes[size]; - int a, b, i; - - /* first compute probabilities from model */ - tmp[0].count = 256; - for (i=0; i> 8; - b = tmp[i].count * (255 - coeff_model[i]) >> 8; - nodes[map[2*i ]].count = a + !a; - nodes[map[2*i+1]].count = b + !b; - } - - free_vlc(vlc); - /* then build the huffman tree accodring to probabilities */ - ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, - FF_HUFFMAN_FLAG_HNODE_FIRST); -} - -static void vp6_parse_coeff_models(VP56Context *s) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - int def_prob[11]; - int node, cg, ctx, pos; - int ct; /* code type */ - int pt; /* plane type (0 for Y, 1 for U or V) */ - - memset(def_prob, 0x80, sizeof(def_prob)); - - for (pt=0; pt<2; pt++) - for (node=0; node<11; node++) - if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { - def_prob[node] = vp56_rac_gets_nn(c, 7); - model->coeff_dccv[pt][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - model->coeff_dccv[pt][node] = def_prob[node]; - } - - if (vp56_rac_get(c)) { - for (pos=1; pos<64; pos++) - if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) - model->coeff_reorder[pos] = vp56_rac_gets(c, 4); - vp6_coeff_order_table_init(s); - } - - for (cg=0; cg<2; cg++) - for (node=0; node<14; node++) - if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) - model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7); - - for (ct=0; ct<3; ct++) - for (pt=0; pt<2; pt++) - for (cg=0; cg<6; cg++) - for (node=0; node<11; node++) - if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { - def_prob[node] = vp56_rac_gets_nn(c, 7); - model->coeff_ract[pt][ct][cg][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - model->coeff_ract[pt][ct][cg][node] = def_prob[node]; - } - - if (s->use_huffman) { - for (pt=0; pt<2; pt++) { - vp6_build_huff_tree(s, model->coeff_dccv[pt], - vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]); - vp6_build_huff_tree(s, model->coeff_runv[pt], - vp6_huff_run_map, 9, &s->runv_vlc[pt]); - for (ct=0; ct<3; ct++) - for (cg = 0; cg < 6; cg++) - vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], - vp6_huff_coeff_map, 12, - &s->ract_vlc[pt][ct][cg]); - } - memset(s->nb_null, 0, sizeof(s->nb_null)); - } else { - /* coeff_dcct is a linear combination of coeff_dccv */ - for (pt=0; pt<2; pt++) - for (ctx=0; ctx<3; ctx++) - for (node=0; node<5; node++) - model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); - } -} - -static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect) -{ - VP56RangeCoder *c = &s->c; - VP56Model *model = s->modelp; - int comp; - - *vect = (VP56mv) {0,0}; - if (s->vector_candidate_pos < 2) - *vect = s->vector_candidate[0]; - - for (comp=0; comp<2; comp++) { - int i, delta = 0; - - if (vp56_rac_get_prob(c, model->vector_dct[comp])) { - static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; - for (i=0; ivector_fdv[comp][j])<vector_fdv[comp][3])<<3; - else - delta |= 8; - } else { - delta = vp56_rac_get_tree(c, vp56_pva_tree, - model->vector_pdv[comp]); - } - - if (delta && vp56_rac_get_prob(c, model->vector_sig[comp])) - delta = -delta; - - if (!comp) - vect->x += delta; - else - vect->y += delta; - } -} - -/** - * Read number of consecutive blocks with null DC or AC. - * This value is < 74. - */ -static unsigned vp6_get_nb_null(VP56Context *s) -{ - unsigned val = get_bits(&s->gb, 2); - if (val == 2) - val += get_bits(&s->gb, 2); - else if (val == 3) { - val = get_bits1(&s->gb) << 2; - val = 6+val + get_bits(&s->gb, 2+val); - } - return val; -} - -static void vp6_parse_coeff_huffman(VP56Context *s) -{ - VP56Model *model = s->modelp; - uint8_t *permute = s->scantable.permutated; - VLC *vlc_coeff; - int coeff, sign, coeff_idx; - int b, cg, idx; - int pt = 0; /* plane type (0 for Y, 1 for U or V) */ - - for (b=0; b<6; b++) { - int ct = 0; /* code type */ - if (b > 3) pt = 1; - vlc_coeff = &s->dccv_vlc[pt]; - - for (coeff_idx=0; coeff_idx<64; ) { - int run = 1; - if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) { - s->nb_null[coeff_idx][pt]--; - if (coeff_idx) - break; - } else { - if (get_bits_count(&s->gb) >= s->gb.size_in_bits) - return; - coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); - if (coeff == 0) { - if (coeff_idx) { - int pt = (coeff_idx >= 6); - run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); - if (run >= 9) - run += get_bits(&s->gb, 6); - } else - s->nb_null[0][pt] = vp6_get_nb_null(s); - ct = 0; - } else if (coeff == 11) { /* end of block */ - if (coeff_idx == 1) /* first AC coeff ? */ - s->nb_null[1][pt] = vp6_get_nb_null(s); - break; - } else { - int coeff2 = vp56_coeff_bias[coeff]; - if (coeff > 4) - coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11); - ct = 1 + (coeff2 > 1); - sign = get_bits1(&s->gb); - coeff2 = (coeff2 ^ -sign) + sign; - if (coeff_idx) - coeff2 *= s->dequant_ac; - idx = model->coeff_index_to_pos[coeff_idx]; - s->block_coeff[b][permute[idx]] = coeff2; - } - } - coeff_idx+=run; - cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); - vlc_coeff = &s->ract_vlc[pt][ct][cg]; - } - } -} - -static void vp6_parse_coeff(VP56Context *s) -{ - VP56RangeCoder *c = s->ccp; - VP56Model *model = s->modelp; - uint8_t *permute = s->scantable.permutated; - uint8_t *model1, *model2, *model3; - int coeff, sign, coeff_idx; - int b, i, cg, idx, ctx; - int pt = 0; /* plane type (0 for Y, 1 for U or V) */ - - for (b=0; b<6; b++) { - int ct = 1; /* code type */ - int run = 1; - - if (b > 3) pt = 1; - - ctx = s->left_block[vp56_b6to4[b]].not_null_dc - + s->above_blocks[s->above_block_idx[b]].not_null_dc; - model1 = model->coeff_dccv[pt]; - model2 = model->coeff_dcct[pt][ctx]; - - for (coeff_idx=0; coeff_idx<64; ) { - if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { - /* parse a coeff */ - if (vp56_rac_get_prob(c, model2[2])) { - if (vp56_rac_get_prob(c, model2[3])) { - idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); - coeff = vp56_coeff_bias[idx+5]; - for (i=vp56_coeff_bit_length[idx]; i>=0; i--) - coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; - } else { - if (vp56_rac_get_prob(c, model2[4])) - coeff = 3 + vp56_rac_get_prob(c, model1[5]); - else - coeff = 2; - } - ct = 2; - } else { - ct = 1; - coeff = 1; - } - sign = vp56_rac_get(c); - coeff = (coeff ^ -sign) + sign; - if (coeff_idx) - coeff *= s->dequant_ac; - idx = model->coeff_index_to_pos[coeff_idx]; - s->block_coeff[b][permute[idx]] = coeff; - run = 1; - } else { - /* parse a run */ - ct = 0; - if (coeff_idx > 0) { - if (!vp56_rac_get_prob(c, model2[1])) - break; - - model3 = model->coeff_runv[coeff_idx >= 6]; - run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); - if (!run) - for (run=9, i=0; i<6; i++) - run += vp56_rac_get_prob(c, model3[i+8]) << i; - } - } - - cg = vp6_coeff_groups[coeff_idx+=run]; - model1 = model2 = model->coeff_ract[pt][ct][cg]; - } - - s->left_block[vp56_b6to4[b]].not_null_dc = - s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0]; - } -} - -static int vp6_block_variance(uint8_t *src, int stride) -{ - int sum = 0, square_sum = 0; - int y, x; - - for (y=0; y<8; y+=2) { - for (x=0; x<8; x+=2) { - sum += src[x]; - square_sum += src[x]*src[x]; - } - src += 2*stride; - } - return (16*square_sum - sum*sum) >> 8; -} - -static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, - int delta, const int16_t *weights) -{ - int x, y; - - for (y=0; y<8; y++) { - for (x=0; x<8; x++) { - dst[x] = av_clip_uint8(( src[x-delta ] * weights[0] - + src[x ] * weights[1] - + src[x+delta ] * weights[2] - + src[x+2*delta] * weights[3] + 64) >> 7); - } - src += stride; - dst += stride; - } -} - -static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, - int stride, int h_weight, int v_weight) -{ - uint8_t *tmp = s->edge_emu_buffer+16; - s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); - s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); -} - -static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, - int offset1, int offset2, int stride, - VP56mv mv, int mask, int select, int luma) -{ - int filter4 = 0; - int x8 = mv.x & mask; - int y8 = mv.y & mask; - - if (luma) { - x8 *= 2; - y8 *= 2; - filter4 = s->filter_mode; - if (filter4 == 2) { - if (s->max_vector_length && - (FFABS(mv.x) > s->max_vector_length || - FFABS(mv.y) > s->max_vector_length)) { - filter4 = 0; - } else if (s->sample_variance_threshold - && (vp6_block_variance(src+offset1, stride) - < s->sample_variance_threshold)) { - filter4 = 0; - } - } - } - - if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { - offset1 = offset2; - } - - if (filter4) { - if (!y8) { /* left or right combine */ - vp6_filter_hv4(dst, src+offset1, stride, 1, - vp6_block_copy_filter[select][x8]); - } else if (!x8) { /* above or below combine */ - vp6_filter_hv4(dst, src+offset1, stride, stride, - vp6_block_copy_filter[select][y8]); - } else { - s->dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride, - vp6_block_copy_filter[select][x8], - vp6_block_copy_filter[select][y8]); - } - } else { - if (!x8 || !y8) { - s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); - } else { - vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); - } - } -} - -static av_cold int vp6_decode_init(AVCodecContext *avctx) -{ - VP56Context *s = avctx->priv_data; - - vp56_init(avctx, avctx->codec->id == CODEC_ID_VP6, - avctx->codec->id == CODEC_ID_VP6A); - s->vp56_coord_div = vp6_coord_div; - s->parse_vector_adjustment = vp6_parse_vector_adjustment; - s->filter = vp6_filter; - s->default_models_init = vp6_default_models_init; - s->parse_vector_models = vp6_parse_vector_models; - s->parse_coeff_models = vp6_parse_coeff_models; - s->parse_header = vp6_parse_header; - - return 0; -} - -static av_cold int vp6_decode_free(AVCodecContext *avctx) -{ - VP56Context *s = avctx->priv_data; - int pt, ct, cg; - - vp56_free(avctx); - - for (pt=0; pt<2; pt++) { - free_vlc(&s->dccv_vlc[pt]); - free_vlc(&s->runv_vlc[pt]); - for (ct=0; ct<3; ct++) - for (cg=0; cg<6; cg++) - free_vlc(&s->ract_vlc[pt][ct][cg]); - } - return 0; -} - -AVCodec vp6_decoder = { - "vp6", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VP6, - sizeof(VP56Context), - vp6_decode_init, - NULL, - vp6_decode_free, - vp56_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), -}; - -/* flash version, not flipped upside-down */ -AVCodec vp6f_decoder = { - "vp6f", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VP6F, - sizeof(VP56Context), - vp6_decode_init, - NULL, - vp6_decode_free, - vp56_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), -}; - -/* flash version, not flipped upside-down, with alpha channel */ -AVCodec vp6a_decoder = { - "vp6a", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VP6A, - sizeof(VP56Context), - vp6_decode_init, - NULL, - vp6_decode_free, - vp56_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/vp6data.h b/tizen/distrib/ffmpeg/libavcodec/vp6data.h deleted file mode 100644 index 1cfdbe7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp6data.h +++ /dev/null @@ -1,308 +0,0 @@ -/** - * @file - * VP6 compatible video decoder - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VP6DATA_H -#define AVCODEC_VP6DATA_H - -#include "vp56data.h" - -static const uint8_t vp6_def_fdv_vector_model[2][8] = { - { 247, 210, 135, 68, 138, 220, 239, 246 }, - { 244, 184, 201, 44, 173, 221, 239, 253 }, -}; - -static const uint8_t vp6_def_pdv_vector_model[2][7] = { - { 225, 146, 172, 147, 214, 39, 156 }, - { 204, 170, 119, 235, 140, 230, 228 }, -}; - -static const uint8_t vp6_def_coeff_reorder[] = { - 0, 0, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 3, 3, 4, 4, 4, - 5, 5, 5, 5, 6, 6, 7, 7, - 7, 7, 7, 8, 8, 9, 9, 9, - 9, 9, 9, 10, 10, 11, 11, 11, - 11, 11, 11, 12, 12, 12, 12, 12, - 12, 13, 13, 13, 13, 13, 14, 14, - 14, 14, 15, 15, 15, 15, 15, 15, -}; - -static const uint8_t vp6_def_runv_coeff_model[2][14] = { - { 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 }, - { 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 }, -}; - -static const uint8_t vp6_sig_dct_pct[2][2] = { - { 237, 246 }, - { 231, 243 }, -}; - -static const uint8_t vp6_pdv_pct[2][7] = { - { 253, 253, 254, 254, 254, 254, 254 }, - { 245, 253, 254, 254, 254, 254, 254 }, -}; - -static const uint8_t vp6_fdv_pct[2][8] = { - { 254, 254, 254, 254, 254, 250, 250, 252 }, - { 254, 254, 254, 254, 254, 251, 251, 254 }, -}; - -static const uint8_t vp6_dccv_pct[2][11] = { - { 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 }, - { 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 }, -}; - -static const uint8_t vp6_coeff_reorder_pct[] = { - 255, 132, 132, 159, 153, 151, 161, 170, - 164, 162, 136, 110, 103, 114, 129, 118, - 124, 125, 132, 136, 114, 110, 142, 135, - 134, 123, 143, 126, 153, 183, 166, 161, - 171, 180, 179, 164, 203, 218, 225, 217, - 215, 206, 203, 217, 229, 241, 248, 243, - 253, 255, 253, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, -}; - -static const uint8_t vp6_runv_pct[2][14] = { - { 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 }, - { 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 }, -}; - -static const uint8_t vp6_ract_pct[3][2][6][11] = { - { { { 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 }, - { 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 }, - { 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, - { { 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, - { { { 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 }, - { 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 }, - { 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 }, - { 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 }, - { 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, - { { 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, - { { { 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 }, - { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 }, - { 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 }, - { 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 }, - { 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, - { { 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 }, - { 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 }, - { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, - { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } } -}; - -static const int vp6_dccv_lc[3][5][2] = { - { { 122, 133 }, { 0, 1 }, { 78, 171 }, { 139, 117 }, { 168, 79 } }, - { { 133, 51 }, { 0, 1 }, { 169, 71 }, { 214, 44 }, { 210, 38 } }, - { { 142, -16 }, { 0, 1 }, { 221, -30 }, { 246, -3 }, { 203, 17 } }, -}; - -static const uint8_t vp6_coeff_groups[] = { - 0, 0, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 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, 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, -}; - -static const int16_t vp6_block_copy_filter[17][8][4] = { - { { 0, 128, 0, 0 }, /* 0 */ - { -3, 122, 9, 0 }, - { -4, 109, 24, -1 }, - { -5, 91, 45, -3 }, - { -4, 68, 68, -4 }, - { -3, 45, 91, -5 }, - { -1, 24, 109, -4 }, - { 0, 9, 122, -3 } }, - { { 0, 128, 0, 0 }, /* 1 */ - { -4, 124, 9, -1 }, - { -5, 110, 25, -2 }, - { -6, 91, 46, -3 }, - { -5, 69, 69, -5 }, - { -3, 46, 91, -6 }, - { -2, 25, 110, -5 }, - { -1, 9, 124, -4 } }, - { { 0, 128, 0, 0 }, /* 2 */ - { -4, 123, 10, -1 }, - { -6, 110, 26, -2 }, - { -7, 92, 47, -4 }, - { -6, 70, 70, -6 }, - { -4, 47, 92, -7 }, - { -2, 26, 110, -6 }, - { -1, 10, 123, -4 } }, - { { 0, 128, 0, 0 }, /* 3 */ - { -5, 124, 10, -1 }, - { -7, 110, 27, -2 }, - { -7, 91, 48, -4 }, - { -6, 70, 70, -6 }, - { -4, 48, 92, -8 }, - { -2, 27, 110, -7 }, - { -1, 10, 124, -5 } }, - { { 0, 128, 0, 0 }, /* 4 */ - { -6, 124, 11, -1 }, - { -8, 111, 28, -3 }, - { -8, 92, 49, -5 }, - { -7, 71, 71, -7 }, - { -5, 49, 92, -8 }, - { -3, 28, 111, -8 }, - { -1, 11, 124, -6 } }, - { { 0, 128, 0, 0 }, /* 5 */ - { -6, 123, 12, -1 }, - { -9, 111, 29, -3 }, - { -9, 93, 50, -6 }, - { -8, 72, 72, -8 }, - { -6, 50, 93, -9 }, - { -3, 29, 111, -9 }, - { -1, 12, 123, -6 } }, - { { 0, 128, 0, 0 }, /* 6 */ - { -7, 124, 12, -1 }, - { -10, 111, 30, -3 }, - { -10, 93, 51, -6 }, - { -9, 73, 73, -9 }, - { -6, 51, 93, -10 }, - { -3, 30, 111, -10 }, - { -1, 12, 124, -7 } }, - { { 0, 128, 0, 0 }, /* 7 */ - { -7, 123, 13, -1 }, - { -11, 112, 31, -4 }, - { -11, 94, 52, -7 }, - { -10, 74, 74, -10 }, - { -7, 52, 94, -11 }, - { -4, 31, 112, -11 }, - { -1, 13, 123, -7 } }, - { { 0, 128, 0, 0 }, /* 8 */ - { -8, 124, 13, -1 }, - { -12, 112, 32, -4 }, - { -12, 94, 53, -7 }, - { -10, 74, 74, -10 }, - { -7, 53, 94, -12 }, - { -4, 32, 112, -12 }, - { -1, 13, 124, -8 } }, - { { 0, 128, 0, 0 }, /* 9 */ - { -9, 124, 14, -1 }, - { -13, 112, 33, -4 }, - { -13, 95, 54, -8 }, - { -11, 75, 75, -11 }, - { -8, 54, 95, -13 }, - { -4, 33, 112, -13 }, - { -1, 14, 124, -9 } }, - { { 0, 128, 0, 0 }, /* 10 */ - { -9, 123, 15, -1 }, - { -14, 113, 34, -5 }, - { -14, 95, 55, -8 }, - { -12, 76, 76, -12 }, - { -8, 55, 95, -14 }, - { -5, 34, 112, -13 }, - { -1, 15, 123, -9 } }, - { { 0, 128, 0, 0 }, /* 11 */ - { -10, 124, 15, -1 }, - { -14, 113, 34, -5 }, - { -15, 96, 56, -9 }, - { -13, 77, 77, -13 }, - { -9, 56, 96, -15 }, - { -5, 34, 113, -14 }, - { -1, 15, 124, -10 } }, - { { 0, 128, 0, 0 }, /* 12 */ - { -10, 123, 16, -1 }, - { -15, 113, 35, -5 }, - { -16, 98, 56, -10 }, - { -14, 78, 78, -14 }, - { -10, 56, 98, -16 }, - { -5, 35, 113, -15 }, - { -1, 16, 123, -10 } }, - { { 0, 128, 0, 0 }, /* 13 */ - { -11, 124, 17, -2 }, - { -16, 113, 36, -5 }, - { -17, 98, 57, -10 }, - { -14, 78, 78, -14 }, - { -10, 57, 98, -17 }, - { -5, 36, 113, -16 }, - { -2, 17, 124, -11 } }, - { { 0, 128, 0, 0 }, /* 14 */ - { -12, 125, 17, -2 }, - { -17, 114, 37, -6 }, - { -18, 99, 58, -11 }, - { -15, 79, 79, -15 }, - { -11, 58, 99, -18 }, - { -6, 37, 114, -17 }, - { -2, 17, 125, -12 } }, - { { 0, 128, 0, 0 }, /* 15 */ - { -12, 124, 18, -2 }, - { -18, 114, 38, -6 }, - { -19, 99, 59, -11 }, - { -16, 80, 80, -16 }, - { -11, 59, 99, -19 }, - { -6, 38, 114, -18 }, - { -2, 18, 124, -12 } }, - { { 0, 128, 0, 0 }, /* 16 */ - { -4, 118, 16, -2 }, - { -7, 106, 34, -5 }, - { -8, 90, 53, -7 }, - { -8, 72, 72, -8 }, - { -7, 53, 90, -8 }, - { -5, 34, 106, -7 }, - { -2, 16, 118, -4 } }, -}; - -static const VP56Tree vp6_pcr_tree[] = { - { 8, 0}, - { 4, 1}, - { 2, 2}, {-1}, {-2}, - { 2, 3}, {-3}, {-4}, - { 8, 4}, - { 4, 5}, - { 2, 6}, {-5}, {-6}, - { 2, 7}, {-7}, {-8}, - {-0}, -}; - -static const uint8_t vp6_coord_div[] = { 4, 4, 4, 4, 8, 8 }; - -static const uint8_t vp6_huff_coeff_map[] = { - 13, 14, 11, 0, 1, 15, 16, 18, 2, 17, 3, 4, 19, 20, 5, 6, 21, 22, 7, 8, 9, 10 -}; - -static const uint8_t vp6_huff_run_map[] = { - 10, 13, 11, 12, 0, 1, 2, 3, 14, 8, 15, 16, 4, 5, 6, 7 -}; - -#endif /* AVCODEC_VP6DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/vp6dsp.c b/tizen/distrib/ffmpeg/libavcodec/vp6dsp.c deleted file mode 100644 index 69a11ee..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vp6dsp.c +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file - * VP6 DSP-oriented functions - * - * Copyright (C) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "dsputil.h" - - -void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights, const int16_t *v_weights) -{ - int x, y; - int tmp[8*11]; - int *t = tmp; - - src -= stride; - - for (y=0; y<11; y++) { - for (x=0; x<8; x++) { - t[x] = av_clip_uint8(( src[x-1] * h_weights[0] - + src[x ] * h_weights[1] - + src[x+1] * h_weights[2] - + src[x+2] * h_weights[3] + 64) >> 7); - } - src += stride; - t += 8; - } - - t = tmp + 8; - for (y=0; y<8; y++) { - for (x=0; x<8; x++) { - dst[x] = av_clip_uint8(( t[x-8 ] * v_weights[0] - + t[x ] * v_weights[1] - + t[x+8 ] * v_weights[2] - + t[x+16] * v_weights[3] + 64) >> 7); - } - dst += stride; - t += 8; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/vqavideo.c b/tizen/distrib/ffmpeg/libavcodec/vqavideo.c deleted file mode 100644 index a169839..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/vqavideo.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Westwood Studios VQA Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VQA Video Decoder by Mike Melanson (melanson@pcisys.net) - * For more information about the VQA format, visit: - * http://wiki.multimedia.cx/index.php?title=VQA - * - * The VQA video decoder outputs PAL8 or RGB555 colorspace data, depending - * on the type of data in the file. - * - * This decoder needs the 42-byte VQHD header from the beginning - * of the VQA file passed through the extradata field. The VQHD header - * is laid out as: - * - * bytes 0-3 chunk fourcc: 'VQHD' - * bytes 4-7 chunk size in big-endian format, should be 0x0000002A - * bytes 8-49 VQHD chunk data - * - * Bytes 8-49 are what this decoder expects to see. - * - * Briefly, VQA is a vector quantized animation format that operates in a - * VGA palettized colorspace. It operates on pixel vectors (blocks) - * of either 4x2 or 4x4 in size. Compressed VQA chunks can contain vector - * codebooks, palette information, and code maps for rendering vectors onto - * frames. Any of these components can also be compressed with a run-length - * encoding (RLE) algorithm commonly referred to as "format80". - * - * VQA takes a novel approach to rate control. Each group of n frames - * (usually, n = 8) relies on a different vector codebook. Rather than - * transporting an entire codebook every 8th frame, the new codebook is - * broken up into 8 pieces and sent along with the compressed video chunks - * for each of the 8 frames preceding the 8 frames which require the - * codebook. A full codebook is also sent on the very first frame of a - * file. This is an interesting technique, although it makes random file - * seeking difficult despite the fact that the frames are all intracoded. - * - * V1,2 VQA uses 12-bit codebook indexes. If the 12-bit indexes were - * packed into bytes and then RLE compressed, bytewise, the results would - * be poor. That is why the coding method divides each index into 2 parts, - * the top 4 bits and the bottom 8 bits, then RL encodes the 4-bit pieces - * together and the 8-bit pieces together. If most of the vectors are - * clustered into one group of 256 vectors, most of the 4-bit index pieces - * should be the same. - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#define PALETTE_COUNT 256 -#define VQA_HEADER_SIZE 0x2A -#define CHUNK_PREAMBLE_SIZE 8 - -/* allocate the maximum vector space, regardless of the file version: - * (0xFF00 codebook vectors + 0x100 solid pixel vectors) * (4x4 pixels/block) */ -#define MAX_CODEBOOK_VECTORS 0xFF00 -#define SOLID_PIXEL_VECTORS 0x100 -#define MAX_VECTORS (MAX_CODEBOOK_VECTORS + SOLID_PIXEL_VECTORS) -#define MAX_CODEBOOK_SIZE (MAX_VECTORS * 4 * 4) - -#define CBF0_TAG MKBETAG('C', 'B', 'F', '0') -#define CBFZ_TAG MKBETAG('C', 'B', 'F', 'Z') -#define CBP0_TAG MKBETAG('C', 'B', 'P', '0') -#define CBPZ_TAG MKBETAG('C', 'B', 'P', 'Z') -#define CPL0_TAG MKBETAG('C', 'P', 'L', '0') -#define CPLZ_TAG MKBETAG('C', 'P', 'L', 'Z') -#define VPTZ_TAG MKBETAG('V', 'P', 'T', 'Z') - -#define VQA_DEBUG 0 - -#if VQA_DEBUG -#define vqa_debug printf -#else -static inline void vqa_debug(const char *format, ...) { } -#endif - -typedef struct VqaContext { - - AVCodecContext *avctx; - AVFrame frame; - - const unsigned char *buf; - int size; - - uint32_t palette[PALETTE_COUNT]; - - int width; /* width of a frame */ - int height; /* height of a frame */ - int vector_width; /* width of individual vector */ - int vector_height; /* height of individual vector */ - int vqa_version; /* this should be either 1, 2 or 3 */ - - unsigned char *codebook; /* the current codebook */ - int codebook_size; - unsigned char *next_codebook_buffer; /* accumulator for next codebook */ - int next_codebook_buffer_index; - - unsigned char *decode_buffer; - int decode_buffer_size; - - /* number of frames to go before replacing codebook */ - int partial_countdown; - int partial_count; - -} VqaContext; - -static av_cold int vqa_decode_init(AVCodecContext *avctx) -{ - VqaContext *s = avctx->priv_data; - unsigned char *vqa_header; - int i, j, codebook_index; - - s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_PAL8; - - /* make sure the extradata made it */ - if (s->avctx->extradata_size != VQA_HEADER_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, " VQA video: expected extradata size of %d\n", VQA_HEADER_SIZE); - return -1; - } - - /* load up the VQA parameters from the header */ - vqa_header = (unsigned char *)s->avctx->extradata; - s->vqa_version = vqa_header[0]; - s->width = AV_RL16(&vqa_header[6]); - s->height = AV_RL16(&vqa_header[8]); - if(avcodec_check_dimensions(avctx, s->width, s->height)){ - s->width= s->height= 0; - return -1; - } - s->vector_width = vqa_header[10]; - s->vector_height = vqa_header[11]; - s->partial_count = s->partial_countdown = vqa_header[13]; - - /* the vector dimensions have to meet very stringent requirements */ - if ((s->vector_width != 4) || - ((s->vector_height != 2) && (s->vector_height != 4))) { - /* return without further initialization */ - return -1; - } - - /* allocate codebooks */ - s->codebook_size = MAX_CODEBOOK_SIZE; - s->codebook = av_malloc(s->codebook_size); - s->next_codebook_buffer = av_malloc(s->codebook_size); - - /* initialize the solid-color vectors */ - if (s->vector_height == 4) { - codebook_index = 0xFF00 * 16; - for (i = 0; i < 256; i++) - for (j = 0; j < 16; j++) - s->codebook[codebook_index++] = i; - } else { - codebook_index = 0xF00 * 8; - for (i = 0; i < 256; i++) - for (j = 0; j < 8; j++) - s->codebook[codebook_index++] = i; - } - s->next_codebook_buffer_index = 0; - - /* allocate decode buffer */ - s->decode_buffer_size = (s->width / s->vector_width) * - (s->height / s->vector_height) * 2; - s->decode_buffer = av_malloc(s->decode_buffer_size); - - s->frame.data[0] = NULL; - - return 0; -} - -#define CHECK_COUNT() \ - if (dest_index + count > dest_size) { \ - av_log(NULL, AV_LOG_ERROR, " VQA video: decode_format80 problem: next op would overflow dest_index\n"); \ - av_log(NULL, AV_LOG_ERROR, " VQA video: current dest_index = %d, count = %d, dest_size = %d\n", \ - dest_index, count, dest_size); \ - return; \ - } - -static void decode_format80(const unsigned char *src, int src_size, - unsigned char *dest, int dest_size, int check_size) { - - int src_index = 0; - int dest_index = 0; - int count; - int src_pos; - unsigned char color; - int i; - - while (src_index < src_size) { - - vqa_debug(" opcode %02X: ", src[src_index]); - - /* 0x80 means that frame is finished */ - if (src[src_index] == 0x80) - return; - - if (dest_index >= dest_size) { - av_log(NULL, AV_LOG_ERROR, " VQA video: decode_format80 problem: dest_index (%d) exceeded dest_size (%d)\n", - dest_index, dest_size); - return; - } - - if (src[src_index] == 0xFF) { - - src_index++; - count = AV_RL16(&src[src_index]); - src_index += 2; - src_pos = AV_RL16(&src[src_index]); - src_index += 2; - vqa_debug("(1) copy %X bytes from absolute pos %X\n", count, src_pos); - CHECK_COUNT(); - for (i = 0; i < count; i++) - dest[dest_index + i] = dest[src_pos + i]; - dest_index += count; - - } else if (src[src_index] == 0xFE) { - - src_index++; - count = AV_RL16(&src[src_index]); - src_index += 2; - color = src[src_index++]; - vqa_debug("(2) set %X bytes to %02X\n", count, color); - CHECK_COUNT(); - memset(&dest[dest_index], color, count); - dest_index += count; - - } else if ((src[src_index] & 0xC0) == 0xC0) { - - count = (src[src_index++] & 0x3F) + 3; - src_pos = AV_RL16(&src[src_index]); - src_index += 2; - vqa_debug("(3) copy %X bytes from absolute pos %X\n", count, src_pos); - CHECK_COUNT(); - for (i = 0; i < count; i++) - dest[dest_index + i] = dest[src_pos + i]; - dest_index += count; - - } else if (src[src_index] > 0x80) { - - count = src[src_index++] & 0x3F; - vqa_debug("(4) copy %X bytes from source to dest\n", count); - CHECK_COUNT(); - memcpy(&dest[dest_index], &src[src_index], count); - src_index += count; - dest_index += count; - - } else { - - count = ((src[src_index] & 0x70) >> 4) + 3; - src_pos = AV_RB16(&src[src_index]) & 0x0FFF; - src_index += 2; - vqa_debug("(5) copy %X bytes from relpos %X\n", count, src_pos); - CHECK_COUNT(); - for (i = 0; i < count; i++) - dest[dest_index + i] = dest[dest_index - src_pos + i]; - dest_index += count; - } - } - - /* validate that the entire destination buffer was filled; this is - * important for decoding frame maps since each vector needs to have a - * codebook entry; it is not important for compressed codebooks because - * not every entry needs to be filled */ - if (check_size) - if (dest_index < dest_size) - av_log(NULL, AV_LOG_ERROR, " VQA video: decode_format80 problem: decode finished with dest_index (%d) < dest_size (%d)\n", - dest_index, dest_size); -} - -static void vqa_decode_chunk(VqaContext *s) -{ - unsigned int chunk_type; - unsigned int chunk_size; - int byte_skip; - unsigned int index = 0; - int i; - unsigned char r, g, b; - int index_shift; - - int cbf0_chunk = -1; - int cbfz_chunk = -1; - int cbp0_chunk = -1; - int cbpz_chunk = -1; - int cpl0_chunk = -1; - int cplz_chunk = -1; - int vptz_chunk = -1; - - int x, y; - int lines = 0; - int pixel_ptr; - int vector_index = 0; - int lobyte = 0; - int hibyte = 0; - int lobytes = 0; - int hibytes = s->decode_buffer_size / 2; - - /* first, traverse through the frame and find the subchunks */ - while (index < s->size) { - - chunk_type = AV_RB32(&s->buf[index]); - chunk_size = AV_RB32(&s->buf[index + 4]); - - switch (chunk_type) { - - case CBF0_TAG: - cbf0_chunk = index; - break; - - case CBFZ_TAG: - cbfz_chunk = index; - break; - - case CBP0_TAG: - cbp0_chunk = index; - break; - - case CBPZ_TAG: - cbpz_chunk = index; - break; - - case CPL0_TAG: - cpl0_chunk = index; - break; - - case CPLZ_TAG: - cplz_chunk = index; - break; - - case VPTZ_TAG: - vptz_chunk = index; - break; - - default: - av_log(s->avctx, AV_LOG_ERROR, " VQA video: Found unknown chunk type: %c%c%c%c (%08X)\n", - (chunk_type >> 24) & 0xFF, - (chunk_type >> 16) & 0xFF, - (chunk_type >> 8) & 0xFF, - (chunk_type >> 0) & 0xFF, - chunk_type); - break; - } - - byte_skip = chunk_size & 0x01; - index += (CHUNK_PREAMBLE_SIZE + chunk_size + byte_skip); - } - - /* next, deal with the palette */ - if ((cpl0_chunk != -1) && (cplz_chunk != -1)) { - - /* a chunk should not have both chunk types */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CPL0 and CPLZ chunks\n"); - return; - } - - /* decompress the palette chunk */ - if (cplz_chunk != -1) { - -/* yet to be handled */ - - } - - /* convert the RGB palette into the machine's endian format */ - if (cpl0_chunk != -1) { - - chunk_size = AV_RB32(&s->buf[cpl0_chunk + 4]); - /* sanity check the palette size */ - if (chunk_size / 3 > 256) { - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found a palette chunk with %d colors\n", - chunk_size / 3); - return; - } - cpl0_chunk += CHUNK_PREAMBLE_SIZE; - for (i = 0; i < chunk_size / 3; i++) { - /* scale by 4 to transform 6-bit palette -> 8-bit */ - r = s->buf[cpl0_chunk++] * 4; - g = s->buf[cpl0_chunk++] * 4; - b = s->buf[cpl0_chunk++] * 4; - s->palette[i] = (r << 16) | (g << 8) | (b); - } - } - - /* next, look for a full codebook */ - if ((cbf0_chunk != -1) && (cbfz_chunk != -1)) { - - /* a chunk should not have both chunk types */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBF0 and CBFZ chunks\n"); - return; - } - - /* decompress the full codebook chunk */ - if (cbfz_chunk != -1) { - - chunk_size = AV_RB32(&s->buf[cbfz_chunk + 4]); - cbfz_chunk += CHUNK_PREAMBLE_SIZE; - decode_format80(&s->buf[cbfz_chunk], chunk_size, - s->codebook, s->codebook_size, 0); - } - - /* copy a full codebook */ - if (cbf0_chunk != -1) { - - chunk_size = AV_RB32(&s->buf[cbf0_chunk + 4]); - /* sanity check the full codebook size */ - if (chunk_size > MAX_CODEBOOK_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: CBF0 chunk too large (0x%X bytes)\n", - chunk_size); - return; - } - cbf0_chunk += CHUNK_PREAMBLE_SIZE; - - memcpy(s->codebook, &s->buf[cbf0_chunk], chunk_size); - } - - /* decode the frame */ - if (vptz_chunk == -1) { - - /* something is wrong if there is no VPTZ chunk */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: no VPTZ chunk found\n"); - return; - } - - chunk_size = AV_RB32(&s->buf[vptz_chunk + 4]); - vptz_chunk += CHUNK_PREAMBLE_SIZE; - decode_format80(&s->buf[vptz_chunk], chunk_size, - s->decode_buffer, s->decode_buffer_size, 1); - - /* render the final PAL8 frame */ - if (s->vector_height == 4) - index_shift = 4; - else - index_shift = 3; - for (y = 0; y < s->frame.linesize[0] * s->height; - y += s->frame.linesize[0] * s->vector_height) { - - for (x = y; x < y + s->width; x += 4, lobytes++, hibytes++) { - pixel_ptr = x; - - /* get the vector index, the method for which varies according to - * VQA file version */ - switch (s->vqa_version) { - - case 1: -/* still need sample media for this case (only one game, "Legend of - * Kyrandia III : Malcolm's Revenge", is known to use this version) */ - lobyte = s->decode_buffer[lobytes * 2]; - hibyte = s->decode_buffer[(lobytes * 2) + 1]; - vector_index = ((hibyte << 8) | lobyte) >> 3; - vector_index <<= index_shift; - lines = s->vector_height; - /* uniform color fill - a quick hack */ - if (hibyte == 0xFF) { - while (lines--) { - s->frame.data[0][pixel_ptr + 0] = 255 - lobyte; - s->frame.data[0][pixel_ptr + 1] = 255 - lobyte; - s->frame.data[0][pixel_ptr + 2] = 255 - lobyte; - s->frame.data[0][pixel_ptr + 3] = 255 - lobyte; - pixel_ptr += s->frame.linesize[0]; - } - lines=0; - } - break; - - case 2: - lobyte = s->decode_buffer[lobytes]; - hibyte = s->decode_buffer[hibytes]; - vector_index = (hibyte << 8) | lobyte; - vector_index <<= index_shift; - lines = s->vector_height; - break; - - case 3: -/* not implemented yet */ - lines = 0; - break; - } - - while (lines--) { - s->frame.data[0][pixel_ptr + 0] = s->codebook[vector_index++]; - s->frame.data[0][pixel_ptr + 1] = s->codebook[vector_index++]; - s->frame.data[0][pixel_ptr + 2] = s->codebook[vector_index++]; - s->frame.data[0][pixel_ptr + 3] = s->codebook[vector_index++]; - pixel_ptr += s->frame.linesize[0]; - } - } - } - - /* handle partial codebook */ - if ((cbp0_chunk != -1) && (cbpz_chunk != -1)) { - /* a chunk should not have both chunk types */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBP0 and CBPZ chunks\n"); - return; - } - - if (cbp0_chunk != -1) { - - chunk_size = AV_RB32(&s->buf[cbp0_chunk + 4]); - cbp0_chunk += CHUNK_PREAMBLE_SIZE; - - /* accumulate partial codebook */ - memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], - &s->buf[cbp0_chunk], chunk_size); - s->next_codebook_buffer_index += chunk_size; - - s->partial_countdown--; - if (s->partial_countdown == 0) { - - /* time to replace codebook */ - memcpy(s->codebook, s->next_codebook_buffer, - s->next_codebook_buffer_index); - - /* reset accounting */ - s->next_codebook_buffer_index = 0; - s->partial_countdown = s->partial_count; - } - } - - if (cbpz_chunk != -1) { - - chunk_size = AV_RB32(&s->buf[cbpz_chunk + 4]); - cbpz_chunk += CHUNK_PREAMBLE_SIZE; - - /* accumulate partial codebook */ - memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], - &s->buf[cbpz_chunk], chunk_size); - s->next_codebook_buffer_index += chunk_size; - - s->partial_countdown--; - if (s->partial_countdown == 0) { - - /* decompress codebook */ - decode_format80(s->next_codebook_buffer, - s->next_codebook_buffer_index, - s->codebook, s->codebook_size, 0); - - /* reset accounting */ - s->next_codebook_buffer_index = 0; - s->partial_countdown = s->partial_count; - } - } -} - -static int vqa_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VqaContext *s = avctx->priv_data; - - 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(s->avctx, AV_LOG_ERROR, " VQA Video: get_buffer() failed\n"); - return -1; - } - - vqa_decode_chunk(s); - - /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); - 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 av_cold int vqa_decode_end(AVCodecContext *avctx) -{ - VqaContext *s = avctx->priv_data; - - av_free(s->codebook); - av_free(s->next_codebook_buffer); - av_free(s->decode_buffer); - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - return 0; -} - -AVCodec vqa_decoder = { - "vqavideo", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WS_VQA, - sizeof(VqaContext), - vqa_decode_init, - NULL, - vqa_decode_end, - vqa_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/w32thread.c b/tizen/distrib/ffmpeg/libavcodec/w32thread.c deleted file mode 100644 index f7a1430..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/w32thread.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -//#define DEBUG - -#include "avcodec.h" - -#define WIN32_LEAN_AND_MEAN -#include -#include - -typedef struct ThreadContext{ - AVCodecContext *avctx; - HANDLE thread; - HANDLE work_sem; - HANDLE job_sem; - HANDLE done_sem; - int (*func)(AVCodecContext *c, void *arg); - int (*func2)(AVCodecContext *c, void *arg, int, int); - void *arg; - int argsize; - int *jobnr; - int *ret; - int threadnr; -}ThreadContext; - - -static unsigned WINAPI attribute_align_arg thread_func(void *v){ - ThreadContext *c= v; - - for(;;){ - int ret, jobnr; -//printf("thread_func %X enter wait\n", (int)v); fflush(stdout); - WaitForSingleObject(c->work_sem, INFINITE); - // avoid trying to access jobnr if we should quit - if (!c->func && !c->func2) - break; - WaitForSingleObject(c->job_sem, INFINITE); - jobnr = (*c->jobnr)++; - ReleaseSemaphore(c->job_sem, 1, 0); -//printf("thread_func %X after wait (func=%X)\n", (int)v, (int)c->func); fflush(stdout); - if(c->func) - ret= c->func(c->avctx, (uint8_t *)c->arg + jobnr*c->argsize); - else - ret= c->func2(c->avctx, c->arg, jobnr, c->threadnr); - if (c->ret) - c->ret[jobnr] = ret; -//printf("thread_func %X signal complete\n", (int)v); fflush(stdout); - ReleaseSemaphore(c->done_sem, 1, 0); - } - - return 0; -} - -/** - * Free what has been allocated by avcodec_thread_init(). - * Must be called after decoding has finished, especially do not call while avcodec_thread_execute() is running. - */ -void avcodec_thread_free(AVCodecContext *s){ - ThreadContext *c= s->thread_opaque; - int i; - - for(i=0; ithread_count; i++){ - - c[i].func= NULL; - c[i].func2= NULL; - } - ReleaseSemaphore(c[0].work_sem, s->thread_count, 0); - for(i=0; ithread_count; i++){ - WaitForSingleObject(c[i].thread, INFINITE); - if(c[i].thread) CloseHandle(c[i].thread); - } - if(c[0].work_sem) CloseHandle(c[0].work_sem); - if(c[0].job_sem) CloseHandle(c[0].job_sem); - if(c[0].done_sem) CloseHandle(c[0].done_sem); - - av_freep(&s->thread_opaque); -} - -static int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size){ - ThreadContext *c= s->thread_opaque; - int i; - int jobnr = 0; - - assert(s == c->avctx); - - /* 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; i++){ - c[i].arg= arg; - c[i].argsize= size; - c[i].func= func; - c[i].ret= ret; - c[i].jobnr = &jobnr; - } - ReleaseSemaphore(c[0].work_sem, count, 0); - for(i=0; ithread_opaque; - int i; - for(i=0; ithread_count; i++) - c[i].func2 = func; - avcodec_thread_execute(s, NULL, arg, ret, count, 0); -} - -int avcodec_thread_init(AVCodecContext *s, int thread_count){ - int i; - ThreadContext *c; - uint32_t threadid; - - s->thread_count= thread_count; - - if (thread_count <= 1) - return 0; - - assert(!s->thread_opaque); - c= av_mallocz(sizeof(ThreadContext)*thread_count); - s->thread_opaque= c; - if(!(c[0].work_sem = CreateSemaphore(NULL, 0, INT_MAX, NULL))) - goto fail; - if(!(c[0].job_sem = CreateSemaphore(NULL, 1, 1, NULL))) - goto fail; - if(!(c[0].done_sem = CreateSemaphore(NULL, 0, INT_MAX, NULL))) - goto fail; - - for(i=0; iexecute= avcodec_thread_execute; - s->execute2= avcodec_thread_execute2; - - return 0; -fail: - avcodec_thread_free(s); - return -1; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/wavpack.c b/tizen/distrib/ffmpeg/libavcodec/wavpack.c deleted file mode 100644 index 7358d29..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wavpack.c +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * WavPack lossless audio decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#define ALT_BITSTREAM_READER_LE -#include "avcodec.h" -#include "get_bits.h" -#include "unary.h" - -/** - * @file - * WavPack lossless audio decoder - */ - -#define WV_MONO 0x00000004 -#define WV_JOINT_STEREO 0x00000010 -#define WV_FALSE_STEREO 0x40000000 - -#define WV_HYBRID_MODE 0x00000008 -#define WV_HYBRID_SHAPE 0x00000008 -#define WV_HYBRID_BITRATE 0x00000200 -#define WV_HYBRID_BALANCE 0x00000400 - -#define WV_FLT_SHIFT_ONES 0x01 -#define WV_FLT_SHIFT_SAME 0x02 -#define WV_FLT_SHIFT_SENT 0x04 -#define WV_FLT_ZERO_SENT 0x08 -#define WV_FLT_ZERO_SIGN 0x10 - -enum WP_ID_Flags{ - WP_IDF_MASK = 0x1F, - WP_IDF_IGNORE = 0x20, - WP_IDF_ODD = 0x40, - WP_IDF_LONG = 0x80 -}; - -enum WP_ID{ - WP_ID_DUMMY = 0, - WP_ID_ENCINFO, - WP_ID_DECTERMS, - WP_ID_DECWEIGHTS, - WP_ID_DECSAMPLES, - WP_ID_ENTROPY, - WP_ID_HYBRID, - WP_ID_SHAPING, - WP_ID_FLOATINFO, - WP_ID_INT32INFO, - WP_ID_DATA, - WP_ID_CORR, - WP_ID_EXTRABITS, - WP_ID_CHANINFO -}; - -typedef struct SavedContext { - int offset; - int size; - int bits_used; - uint32_t crc; -} SavedContext; - -#define MAX_TERMS 16 - -typedef struct Decorr { - int delta; - int value; - int weightA; - int weightB; - int samplesA[8]; - int samplesB[8]; -} Decorr; - -typedef struct WvChannel { - int median[3]; - int slow_level, error_limit; - int bitrate_acc, bitrate_delta; -} WvChannel; - -typedef struct WavpackContext { - AVCodecContext *avctx; - int frame_flags; - int stereo, stereo_in; - int joint; - uint32_t CRC; - GetBitContext gb; - int got_extra_bits; - uint32_t crc_extra_bits; - GetBitContext gb_extra_bits; - int data_size; // in bits - int samples; - int terms; - Decorr decorr[MAX_TERMS]; - int zero, one, zeroes; - int extra_bits; - int and, or, shift; - int post_shift; - int hybrid, hybrid_bitrate; - int float_flag; - int float_shift; - int float_max_exp; - WvChannel ch[2]; - int samples_left; - int max_samples; - int pos; - SavedContext sc, extra_sc; -} WavpackContext; - -// exponent table copied from WavPack source -static const uint8_t wp_exp2_table [256] = { - 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16, - 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d, - 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b, - 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, - 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, - 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, - 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, - 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, - 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4, - 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9, - 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff -}; - -static const uint8_t wp_log2_table [] = { - 0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15, - 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, - 0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51, - 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, - 0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, - 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, - 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, - 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0, - 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce, - 0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb, - 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7, - 0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff -}; - -static av_always_inline int wp_exp2(int16_t val) -{ - int res, neg = 0; - - if(val < 0){ - val = -val; - neg = 1; - } - - res = wp_exp2_table[val & 0xFF] | 0x100; - val >>= 8; - res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); - return neg ? -res : res; -} - -static av_always_inline int wp_log2(int32_t val) -{ - int bits; - - if(!val) - return 0; - if(val == 1) - return 256; - val += val >> 9; - bits = av_log2(val) + 1; - if(bits < 9) - return (bits << 8) + wp_log2_table[(val << (9 - bits)) & 0xFF]; - else - return (bits << 8) + wp_log2_table[(val >> (bits - 9)) & 0xFF]; -} - -#define LEVEL_DECAY(a) ((a + 0x80) >> 8) - -// macros for manipulating median values -#define GET_MED(n) ((c->median[n] >> 4) + 1) -#define DEC_MED(n) c->median[n] -= ((c->median[n] + (128>>n) - 2) / (128>>n)) * 2 -#define INC_MED(n) c->median[n] += ((c->median[n] + (128>>n)) / (128>>n)) * 5 - -// macros for applying weight -#define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \ - if(samples && in){ \ - if((samples ^ in) < 0){ \ - weight -= delta; \ - if(weight < -1024) weight = -1024; \ - }else{ \ - weight += delta; \ - if(weight > 1024) weight = 1024; \ - } \ - } - - -static av_always_inline int get_tail(GetBitContext *gb, int k) -{ - int p, e, res; - - if(k<1)return 0; - p = av_log2(k); - e = (1 << (p + 1)) - k - 1; - res = p ? get_bits(gb, p) : 0; - if(res >= e){ - res = (res<<1) - e + get_bits1(gb); - } - return res; -} - -static void update_error_limit(WavpackContext *ctx) -{ - int i, br[2], sl[2]; - - for(i = 0; i <= ctx->stereo_in; i++){ - ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta; - br[i] = ctx->ch[i].bitrate_acc >> 16; - sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level); - } - if(ctx->stereo_in && ctx->hybrid_bitrate){ - int balance = (sl[1] - sl[0] + br[1] + 1) >> 1; - if(balance > br[0]){ - br[1] = br[0] << 1; - br[0] = 0; - }else if(-balance > br[0]){ - br[0] <<= 1; - br[1] = 0; - }else{ - br[1] = br[0] + balance; - br[0] = br[0] - balance; - } - } - for(i = 0; i <= ctx->stereo_in; i++){ - if(ctx->hybrid_bitrate){ - if(sl[i] - br[i] > -0x100) - ctx->ch[i].error_limit = wp_exp2(sl[i] - br[i] + 0x100); - else - ctx->ch[i].error_limit = 0; - }else{ - ctx->ch[i].error_limit = wp_exp2(br[i]); - } - } -} - -static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int channel, int *last) -{ - int t, t2; - int sign, base, add, ret; - WvChannel *c = &ctx->ch[channel]; - - *last = 0; - - if((ctx->ch[0].median[0] < 2U) && (ctx->ch[1].median[0] < 2U) && !ctx->zero && !ctx->one){ - if(ctx->zeroes){ - ctx->zeroes--; - if(ctx->zeroes){ - c->slow_level -= LEVEL_DECAY(c->slow_level); - return 0; - } - }else{ - t = get_unary_0_33(gb); - if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1)); - ctx->zeroes = t; - if(ctx->zeroes){ - memset(ctx->ch[0].median, 0, sizeof(ctx->ch[0].median)); - memset(ctx->ch[1].median, 0, sizeof(ctx->ch[1].median)); - c->slow_level -= LEVEL_DECAY(c->slow_level); - return 0; - } - } - } - - if(get_bits_count(gb) >= ctx->data_size){ - *last = 1; - return 0; - } - - if(ctx->zero){ - t = 0; - ctx->zero = 0; - }else{ - t = get_unary_0_33(gb); - if(get_bits_count(gb) >= ctx->data_size){ - *last = 1; - return 0; - } - if(t == 16) { - t2 = get_unary_0_33(gb); - if(t2 < 2) t += t2; - else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); - } - - if(ctx->one){ - ctx->one = t&1; - t = (t>>1) + 1; - }else{ - ctx->one = t&1; - t >>= 1; - } - ctx->zero = !ctx->one; - } - - if(ctx->hybrid && !channel) - update_error_limit(ctx); - - if(!t){ - base = 0; - add = GET_MED(0) - 1; - DEC_MED(0); - }else if(t == 1){ - base = GET_MED(0); - add = GET_MED(1) - 1; - INC_MED(0); - DEC_MED(1); - }else if(t == 2){ - base = GET_MED(0) + GET_MED(1); - add = GET_MED(2) - 1; - INC_MED(0); - INC_MED(1); - DEC_MED(2); - }else{ - base = GET_MED(0) + GET_MED(1) + GET_MED(2) * (t - 2); - add = GET_MED(2) - 1; - INC_MED(0); - INC_MED(1); - INC_MED(2); - } - if(!c->error_limit){ - ret = base + get_tail(gb, add); - }else{ - int mid = (base*2 + add + 1) >> 1; - while(add > c->error_limit){ - if(get_bits1(gb)){ - add -= (mid - base); - base = mid; - }else - add = mid - base - 1; - mid = (base*2 + add + 1) >> 1; - } - ret = mid; - } - sign = get_bits1(gb); - if(ctx->hybrid_bitrate) - c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level); - return sign ? ~ret : ret; -} - -static inline int wv_get_value_integer(WavpackContext *s, uint32_t *crc, int S) -{ - int bit; - - if(s->extra_bits){ - S <<= s->extra_bits; - - if(s->got_extra_bits){ - S |= get_bits(&s->gb_extra_bits, s->extra_bits); - *crc = *crc * 9 + (S&0xffff) * 3 + ((unsigned)S>>16); - } - } - bit = (S & s->and) | s->or; - return (((S + bit) << s->shift) - bit) << s->post_shift; -} - -static float wv_get_value_float(WavpackContext *s, uint32_t *crc, int S) -{ - union { - float f; - uint32_t u; - } value; - - int sign; - int exp = s->float_max_exp; - - if(s->got_extra_bits){ - const int max_bits = 1 + 23 + 8 + 1; - const int left_bits = get_bits_left(&s->gb_extra_bits); - - if(left_bits + 8 * FF_INPUT_BUFFER_PADDING_SIZE < max_bits) - return 0.0; - } - - if(S){ - S <<= s->float_shift; - sign = S < 0; - if(sign) - S = -S; - if(S >= 0x1000000){ - if(s->got_extra_bits && get_bits1(&s->gb_extra_bits)){ - S = get_bits(&s->gb_extra_bits, 23); - }else{ - S = 0; - } - exp = 255; - }else if(exp){ - int shift = 23 - av_log2(S); - exp = s->float_max_exp; - if(exp <= shift){ - shift = --exp; - } - exp -= shift; - - if(shift){ - S <<= shift; - if((s->float_flag & WV_FLT_SHIFT_ONES) || - (s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SAME) && get_bits1(&s->gb_extra_bits)) ){ - S |= (1 << shift) - 1; - } else if(s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SENT)){ - S |= get_bits(&s->gb_extra_bits, shift); - } - } - }else{ - exp = s->float_max_exp; - } - S &= 0x7fffff; - }else{ - sign = 0; - exp = 0; - if(s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)){ - if(get_bits1(&s->gb_extra_bits)){ - S = get_bits(&s->gb_extra_bits, 23); - if(s->float_max_exp >= 25) - exp = get_bits(&s->gb_extra_bits, 8); - sign = get_bits1(&s->gb_extra_bits); - }else{ - if(s->float_flag & WV_FLT_ZERO_SIGN) - sign = get_bits1(&s->gb_extra_bits); - } - } - } - - *crc = *crc * 27 + S * 9 + exp * 3 + sign; - - value.u = (sign << 31) | (exp << 23) | S; - return value.f; -} - -static void wv_reset_saved_context(WavpackContext *s) -{ - s->pos = 0; - s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF; -} - -static inline int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, void *dst, const int type) -{ - int i, j, count = 0; - int last, t; - int A, B, L, L2, R, R2; - int pos = s->pos; - uint32_t crc = s->sc.crc; - uint32_t crc_extra_bits = s->extra_sc.crc; - int16_t *dst16 = dst; - int32_t *dst32 = dst; - float *dstfl = dst; - - if(s->samples_left == s->samples) - s->one = s->zero = s->zeroes = 0; - do{ - L = wv_get_value(s, gb, 0, &last); - if(last) break; - R = wv_get_value(s, gb, 1, &last); - if(last) break; - for(i = 0; i < s->terms; i++){ - t = s->decorr[i].value; - if(t > 0){ - if(t > 8){ - if(t & 1){ - A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; - B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]; - }else{ - A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; - B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1; - } - s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; - s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0]; - j = 0; - }else{ - A = s->decorr[i].samplesA[pos]; - B = s->decorr[i].samplesB[pos]; - j = (pos + t) & 7; - } - if(type != SAMPLE_FMT_S16){ - L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10); - R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10); - }else{ - L2 = L + ((s->decorr[i].weightA * A + 512) >> 10); - R2 = R + ((s->decorr[i].weightB * B + 512) >> 10); - } - if(A && L) s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; - if(B && R) s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta; - s->decorr[i].samplesA[j] = L = L2; - s->decorr[i].samplesB[j] = R = R2; - }else if(t == -1){ - if(type != SAMPLE_FMT_S16) - L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10); - else - L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10); - UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L); - L = L2; - if(type != SAMPLE_FMT_S16) - R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10); - else - R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10); - UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R); - R = R2; - s->decorr[i].samplesA[0] = R; - }else{ - if(type != SAMPLE_FMT_S16) - R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10); - else - R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10); - UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R); - R = R2; - - if(t == -3){ - R2 = s->decorr[i].samplesA[0]; - s->decorr[i].samplesA[0] = R; - } - - if(type != SAMPLE_FMT_S16) - L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10); - else - L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10); - UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L); - L = L2; - s->decorr[i].samplesB[0] = L; - } - } - pos = (pos + 1) & 7; - if(s->joint) - L += (R -= (L >> 1)); - crc = (crc * 3 + L) * 3 + R; - - if(type == SAMPLE_FMT_FLT){ - *dstfl++ = wv_get_value_float(s, &crc_extra_bits, L); - *dstfl++ = wv_get_value_float(s, &crc_extra_bits, R); - } else if(type == SAMPLE_FMT_S32){ - *dst32++ = wv_get_value_integer(s, &crc_extra_bits, L); - *dst32++ = wv_get_value_integer(s, &crc_extra_bits, R); - } else { - *dst16++ = wv_get_value_integer(s, &crc_extra_bits, L); - *dst16++ = wv_get_value_integer(s, &crc_extra_bits, R); - } - count++; - }while(!last && count < s->max_samples); - - s->samples_left -= count; - if(!s->samples_left){ - if(crc != s->CRC){ - av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); - return -1; - } - if(s->got_extra_bits && crc_extra_bits != s->crc_extra_bits){ - av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n"); - return -1; - } - wv_reset_saved_context(s); - }else{ - s->pos = pos; - s->sc.crc = crc; - s->sc.bits_used = get_bits_count(&s->gb); - if(s->got_extra_bits){ - s->extra_sc.crc = crc_extra_bits; - s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits); - } - } - return count * 2; -} - -static inline int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, void *dst, const int type) -{ - int i, j, count = 0; - int last, t; - int A, S, T; - int pos = s->pos; - uint32_t crc = s->sc.crc; - uint32_t crc_extra_bits = s->extra_sc.crc; - int16_t *dst16 = dst; - int32_t *dst32 = dst; - float *dstfl = dst; - - if(s->samples_left == s->samples) - s->one = s->zero = s->zeroes = 0; - do{ - T = wv_get_value(s, gb, 0, &last); - S = 0; - if(last) break; - for(i = 0; i < s->terms; i++){ - t = s->decorr[i].value; - if(t > 8){ - if(t & 1) - A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; - else - A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; - s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; - j = 0; - }else{ - A = s->decorr[i].samplesA[pos]; - j = (pos + t) & 7; - } - if(type != SAMPLE_FMT_S16) - S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10); - else - S = T + ((s->decorr[i].weightA * A + 512) >> 10); - if(A && T) s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; - s->decorr[i].samplesA[j] = T = S; - } - pos = (pos + 1) & 7; - crc = crc * 3 + S; - - if(type == SAMPLE_FMT_FLT) - *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S); - else if(type == SAMPLE_FMT_S32) - *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S); - else - *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S); - count++; - }while(!last && count < s->samples); - - s->samples_left -= count; - if(!s->samples_left){ - if(crc != s->CRC){ - av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); - return -1; - } - if(s->got_extra_bits && crc_extra_bits != s->crc_extra_bits){ - av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n"); - return -1; - } - wv_reset_saved_context(s); - }else{ - s->pos = pos; - s->sc.crc = crc; - s->sc.bits_used = get_bits_count(&s->gb); - if(s->got_extra_bits){ - s->extra_sc.crc = crc_extra_bits; - s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits); - } - } - return count; -} - -static av_cold int wavpack_decode_init(AVCodecContext *avctx) -{ - WavpackContext *s = avctx->priv_data; - - s->avctx = avctx; - s->stereo = (avctx->channels == 2); - if(avctx->bits_per_coded_sample <= 16) - avctx->sample_fmt = SAMPLE_FMT_S16; - else - avctx->sample_fmt = SAMPLE_FMT_S32; - avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; - - wv_reset_saved_context(s); - - return 0; -} - -static int wavpack_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - WavpackContext *s = avctx->priv_data; - void *samples = data; - int samplecount; - int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0, got_float = 0; - int got_hybrid = 0; - const uint8_t* buf_end = buf + buf_size; - int i, j, id, size, ssize, weights, t; - int bpp; - - if (buf_size == 0){ - *data_size = 0; - return 0; - } - - if(!s->samples_left){ - memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); - memset(s->ch, 0, sizeof(s->ch)); - s->extra_bits = 0; - s->and = s->or = s->shift = 0; - s->got_extra_bits = 0; - } - - s->samples = AV_RL32(buf); buf += 4; - if(!s->samples){ - *data_size = 0; - return buf_size; - } - s->frame_flags = AV_RL32(buf); buf += 4; - if(s->frame_flags&0x80){ - bpp = sizeof(float); - avctx->sample_fmt = SAMPLE_FMT_FLT; - } else if((s->frame_flags&0x03) <= 1){ - bpp = 2; - avctx->sample_fmt = SAMPLE_FMT_S16; - } else { - bpp = 4; - avctx->sample_fmt = SAMPLE_FMT_S32; - } - s->stereo_in = (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo; - s->joint = s->frame_flags & WV_JOINT_STEREO; - s->hybrid = s->frame_flags & WV_HYBRID_MODE; - s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE; - s->post_shift = 8 * (bpp-1-(s->frame_flags&0x03)) + ((s->frame_flags >> 13) & 0x1f); - s->CRC = AV_RL32(buf); buf += 4; - - s->max_samples = *data_size / (bpp * avctx->channels); - s->max_samples = FFMIN(s->max_samples, s->samples); - if(s->samples_left > 0){ - s->max_samples = FFMIN(s->max_samples, s->samples_left); - buf = buf_end; - } - - // parse metadata blocks - while(buf < buf_end){ - id = *buf++; - size = *buf++; - if(id & WP_IDF_LONG) { - size |= (*buf++) << 8; - size |= (*buf++) << 16; - } - size <<= 1; // size is specified in words - ssize = size; - if(id & WP_IDF_ODD) size--; - if(size < 0){ - av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size); - break; - } - if(buf + ssize > buf_end){ - av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size); - break; - } - if(id & WP_IDF_IGNORE){ - buf += ssize; - continue; - } - switch(id & WP_IDF_MASK){ - case WP_ID_DECTERMS: - s->terms = size; - if(s->terms > MAX_TERMS){ - av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n"); - buf += ssize; - continue; - } - for(i = 0; i < s->terms; i++) { - s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5; - s->decorr[s->terms - i - 1].delta = *buf >> 5; - buf++; - } - got_terms = 1; - break; - case WP_ID_DECWEIGHTS: - if(!got_terms){ - av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); - continue; - } - weights = size >> s->stereo_in; - if(weights > MAX_TERMS || weights > s->terms){ - av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); - buf += ssize; - continue; - } - for(i = 0; i < weights; i++) { - t = (int8_t)(*buf++); - s->decorr[s->terms - i - 1].weightA = t << 3; - if(s->decorr[s->terms - i - 1].weightA > 0) - s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; - if(s->stereo_in){ - t = (int8_t)(*buf++); - s->decorr[s->terms - i - 1].weightB = t << 3; - if(s->decorr[s->terms - i - 1].weightB > 0) - s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7; - } - } - got_weights = 1; - break; - case WP_ID_DECSAMPLES: - if(!got_terms){ - av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); - continue; - } - t = 0; - for(i = s->terms - 1; (i >= 0) && (t < size); i--) { - if(s->decorr[i].value > 8){ - s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2; - if(s->stereo_in){ - s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2; - t += 4; - } - t += 4; - }else if(s->decorr[i].value < 0){ - s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; - s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; - t += 4; - }else{ - for(j = 0; j < s->decorr[i].value; j++){ - s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; - if(s->stereo_in){ - s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; - } - } - t += s->decorr[i].value * 2 * (s->stereo_in + 1); - } - } - got_samples = 1; - break; - case WP_ID_ENTROPY: - if(size != 6 * (s->stereo_in + 1)){ - av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * (s->stereo_in + 1), size); - buf += ssize; - continue; - } - for(j = 0; j <= s->stereo_in; j++){ - for(i = 0; i < 3; i++){ - s->ch[j].median[i] = wp_exp2(AV_RL16(buf)); - buf += 2; - } - } - got_entropy = 1; - break; - case WP_ID_HYBRID: - if(s->hybrid_bitrate){ - for(i = 0; i <= s->stereo_in; i++){ - s->ch[i].slow_level = wp_exp2(AV_RL16(buf)); - buf += 2; - size -= 2; - } - } - for(i = 0; i < (s->stereo_in + 1); i++){ - s->ch[i].bitrate_acc = AV_RL16(buf) << 16; - buf += 2; - size -= 2; - } - if(size > 0){ - for(i = 0; i < (s->stereo_in + 1); i++){ - s->ch[i].bitrate_delta = wp_exp2((int16_t)AV_RL16(buf)); - buf += 2; - } - }else{ - for(i = 0; i < (s->stereo_in + 1); i++) - s->ch[i].bitrate_delta = 0; - } - got_hybrid = 1; - break; - case WP_ID_INT32INFO: - if(size != 4){ - av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf); - buf += ssize; - continue; - } - if(buf[0]) - s->extra_bits = buf[0]; - else if(buf[1]) - s->shift = buf[1]; - else if(buf[2]){ - s->and = s->or = 1; - s->shift = buf[2]; - }else if(buf[3]){ - s->and = 1; - s->shift = buf[3]; - } - buf += 4; - break; - case WP_ID_FLOATINFO: - if(size != 4){ - av_log(avctx, AV_LOG_ERROR, "Invalid FLOATINFO, size = %i\n", size); - buf += ssize; - continue; - } - s->float_flag = buf[0]; - s->float_shift = buf[1]; - s->float_max_exp = buf[2]; - buf += 4; - got_float = 1; - break; - case WP_ID_DATA: - s->sc.offset = buf - avpkt->data; - s->sc.size = size * 8; - init_get_bits(&s->gb, buf, size * 8); - s->data_size = size * 8; - buf += size; - got_bs = 1; - break; - case WP_ID_EXTRABITS: - if(size <= 4){ - av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n", size); - buf += size; - continue; - } - s->extra_sc.offset = buf - avpkt->data; - s->extra_sc.size = size * 8; - init_get_bits(&s->gb_extra_bits, buf, size * 8); - s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32); - buf += size; - s->got_extra_bits = 1; - break; - default: - buf += size; - } - if(id & WP_IDF_ODD) buf++; - } - if(!s->samples_left){ - if(!got_terms){ - av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); - return -1; - } - if(!got_weights){ - av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); - return -1; - } - if(!got_samples){ - av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); - return -1; - } - if(!got_entropy){ - av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); - return -1; - } - if(s->hybrid && !got_hybrid){ - av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n"); - return -1; - } - if(!got_bs){ - av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); - return -1; - } - if(!got_float && avctx->sample_fmt == SAMPLE_FMT_FLT){ - av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); - return -1; - } - if(s->got_extra_bits && avctx->sample_fmt != SAMPLE_FMT_FLT){ - const int size = get_bits_left(&s->gb_extra_bits); - const int wanted = s->samples * s->extra_bits << s->stereo_in; - if(size < wanted){ - av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n"); - s->got_extra_bits = 0; - } - } - s->samples_left = s->samples; - }else{ - init_get_bits(&s->gb, avpkt->data + s->sc.offset, s->sc.size); - skip_bits_long(&s->gb, s->sc.bits_used); - if(s->got_extra_bits){ - init_get_bits(&s->gb_extra_bits, avpkt->data + s->extra_sc.offset, - s->extra_sc.size); - skip_bits_long(&s->gb_extra_bits, s->extra_sc.bits_used); - } - } - - if(s->stereo_in){ - if(avctx->sample_fmt == SAMPLE_FMT_S16) - samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_S16); - else if(avctx->sample_fmt == SAMPLE_FMT_S32) - samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_S32); - else - samplecount = wv_unpack_stereo(s, &s->gb, samples, SAMPLE_FMT_FLT); - - }else{ - if(avctx->sample_fmt == SAMPLE_FMT_S16) - samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_S16); - else if(avctx->sample_fmt == SAMPLE_FMT_S32) - samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_S32); - else - samplecount = wv_unpack_mono(s, &s->gb, samples, SAMPLE_FMT_FLT); - - if(s->stereo && avctx->sample_fmt == SAMPLE_FMT_S16){ - int16_t *dst = (int16_t*)samples + samplecount * 2; - int16_t *src = (int16_t*)samples + samplecount; - int cnt = samplecount; - while(cnt--){ - *--dst = *--src; - *--dst = *src; - } - samplecount *= 2; - }else if(s->stereo && avctx->sample_fmt == SAMPLE_FMT_S32){ - int32_t *dst = (int32_t*)samples + samplecount * 2; - int32_t *src = (int32_t*)samples + samplecount; - int cnt = samplecount; - while(cnt--){ - *--dst = *--src; - *--dst = *src; - } - samplecount *= 2; - }else if(s->stereo){ - float *dst = (float*)samples + samplecount * 2; - float *src = (float*)samples + samplecount; - int cnt = samplecount; - while(cnt--){ - *--dst = *--src; - *--dst = *src; - } - samplecount *= 2; - } - } - *data_size = samplecount * bpp; - - return s->samples_left > 0 ? 0 : buf_size; -} - -AVCodec wavpack_decoder = { - "wavpack", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WAVPACK, - sizeof(WavpackContext), - wavpack_decode_init, - NULL, - NULL, - wavpack_decode_frame, - .capabilities = CODEC_CAP_SUBFRAMES, - .long_name = NULL_IF_CONFIG_SMALL("WavPack"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/wma.c b/tizen/distrib/ffmpeg/libavcodec/wma.c deleted file mode 100644 index 6578045..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wma.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * WMA compatible codec - * Copyright (c) 2002-2007 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "wma.h" -#include "wmadata.h" - -#undef NDEBUG -#include - -/* XXX: use same run/length optimization as mpeg decoders */ -//FIXME maybe split decode / encode or pass flag -static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, - float **plevel_table, uint16_t **pint_table, - const CoefVLCTable *vlc_table) -{ - int n = vlc_table->n; - const uint8_t *table_bits = vlc_table->huffbits; - const uint32_t *table_codes = vlc_table->huffcodes; - const uint16_t *levels_table = vlc_table->levels; - uint16_t *run_table, *level_table, *int_table; - float *flevel_table; - int i, l, j, k, level; - - init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); - - run_table = av_malloc(n * sizeof(uint16_t)); - level_table = av_malloc(n * sizeof(uint16_t)); - flevel_table= av_malloc(n * sizeof(*flevel_table)); - int_table = av_malloc(n * sizeof(uint16_t)); - i = 2; - level = 1; - k = 0; - while (i < n) { - int_table[k] = i; - l = levels_table[k++]; - for (j = 0; j < l; j++) { - run_table[i] = j; - level_table[i] = level; - flevel_table[i]= level; - i++; - } - level++; - } - *prun_table = run_table; - *plevel_table = flevel_table; - *pint_table = int_table; - av_free(level_table); -} - -/** - *@brief Get the samples per frame for this stream. - *@param sample_rate output sample_rate - *@param version wma version - *@param decode_flags codec compression features - *@return log2 of the number of output samples per frame - */ -int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version, - unsigned int decode_flags) -{ - - int frame_len_bits; - - if (sample_rate <= 16000) { - frame_len_bits = 9; - } else if (sample_rate <= 22050 || - (sample_rate <= 32000 && version == 1)) { - frame_len_bits = 10; - } else if (sample_rate <= 48000) { - frame_len_bits = 11; - } else if (sample_rate <= 96000) { - frame_len_bits = 12; - } else { - frame_len_bits = 13; - } - - if (version == 3) { - int tmp = decode_flags & 0x6; - if (tmp == 0x2) { - ++frame_len_bits; - } else if (tmp == 0x4) { - --frame_len_bits; - } else if (tmp == 0x6) { - frame_len_bits -= 2; - } - } - - return frame_len_bits; -} - -int ff_wma_init(AVCodecContext *avctx, int flags2) -{ - WMACodecContext *s = avctx->priv_data; - int i; - float bps1, high_freq; - volatile float bps; - int sample_rate1; - int coef_vlc_table; - - if ( avctx->sample_rate <= 0 || avctx->sample_rate > 50000 - || avctx->channels <= 0 || avctx->channels > 8 - || avctx->bit_rate <= 0) - return -1; - - s->sample_rate = avctx->sample_rate; - s->nb_channels = avctx->channels; - s->bit_rate = avctx->bit_rate; - s->block_align = avctx->block_align; - - dsputil_init(&s->dsp, avctx); - - if (avctx->codec->id == CODEC_ID_WMAV1) { - s->version = 1; - } else { - s->version = 2; - } - - /* compute MDCT block size */ - s->frame_len_bits = ff_wma_get_frame_len_bits(s->sample_rate, s->version, 0); - - s->frame_len = 1 << s->frame_len_bits; - if (s->use_variable_block_len) { - int nb_max, nb; - nb = ((flags2 >> 3) & 3) + 1; - if ((s->bit_rate / s->nb_channels) >= 32000) - nb += 2; - nb_max = s->frame_len_bits - BLOCK_MIN_BITS; - if (nb > nb_max) - nb = nb_max; - s->nb_block_sizes = nb + 1; - } else { - s->nb_block_sizes = 1; - } - - /* init rate dependent parameters */ - s->use_noise_coding = 1; - high_freq = s->sample_rate * 0.5; - - /* if version 2, then the rates are normalized */ - sample_rate1 = s->sample_rate; - if (s->version == 2) { - if (sample_rate1 >= 44100) { - sample_rate1 = 44100; - } else if (sample_rate1 >= 22050) { - sample_rate1 = 22050; - } else if (sample_rate1 >= 16000) { - sample_rate1 = 16000; - } else if (sample_rate1 >= 11025) { - sample_rate1 = 11025; - } else if (sample_rate1 >= 8000) { - sample_rate1 = 8000; - } - } - - bps = (float)s->bit_rate / (float)(s->nb_channels * s->sample_rate); - s->byte_offset_bits = av_log2((int)(bps * s->frame_len / 8.0 + 0.5)) + 2; - - /* compute high frequency value and choose if noise coding should - be activated */ - bps1 = bps; - if (s->nb_channels == 2) - bps1 = bps * 1.6; - if (sample_rate1 == 44100) { - if (bps1 >= 0.61) { - s->use_noise_coding = 0; - } else { - high_freq = high_freq * 0.4; - } - } else if (sample_rate1 == 22050) { - if (bps1 >= 1.16) { - s->use_noise_coding = 0; - } else if (bps1 >= 0.72) { - high_freq = high_freq * 0.7; - } else { - high_freq = high_freq * 0.6; - } - } else if (sample_rate1 == 16000) { - if (bps > 0.5) { - high_freq = high_freq * 0.5; - } else { - high_freq = high_freq * 0.3; - } - } else if (sample_rate1 == 11025) { - high_freq = high_freq * 0.7; - } else if (sample_rate1 == 8000) { - if (bps <= 0.625) { - high_freq = high_freq * 0.5; - } else if (bps > 0.75) { - s->use_noise_coding = 0; - } else { - high_freq = high_freq * 0.65; - } - } else { - if (bps >= 0.8) { - high_freq = high_freq * 0.75; - } else if (bps >= 0.6) { - high_freq = high_freq * 0.6; - } else { - high_freq = high_freq * 0.5; - } - } - dprintf(s->avctx, "flags2=0x%x\n", flags2); - dprintf(s->avctx, "version=%d channels=%d sample_rate=%d bitrate=%d block_align=%d\n", - s->version, s->nb_channels, s->sample_rate, s->bit_rate, - s->block_align); - dprintf(s->avctx, "bps=%f bps1=%f high_freq=%f bitoffset=%d\n", - bps, bps1, high_freq, s->byte_offset_bits); - dprintf(s->avctx, "use_noise_coding=%d use_exp_vlc=%d nb_block_sizes=%d\n", - s->use_noise_coding, s->use_exp_vlc, s->nb_block_sizes); - - /* compute the scale factor band sizes for each MDCT block size */ - { - int a, b, pos, lpos, k, block_len, i, j, n; - const uint8_t *table; - - if (s->version == 1) { - s->coefs_start = 3; - } else { - s->coefs_start = 0; - } - for (k = 0; k < s->nb_block_sizes; k++) { - block_len = s->frame_len >> k; - - if (s->version == 1) { - lpos = 0; - for (i = 0; i < 25; i++) { - a = ff_wma_critical_freqs[i]; - b = s->sample_rate; - pos = ((block_len * 2 * a) + (b >> 1)) / b; - if (pos > block_len) - pos = block_len; - s->exponent_bands[0][i] = pos - lpos; - if (pos >= block_len) { - i++; - break; - } - lpos = pos; - } - s->exponent_sizes[0] = i; - } else { - /* hardcoded tables */ - table = NULL; - a = s->frame_len_bits - BLOCK_MIN_BITS - k; - if (a < 3) { - if (s->sample_rate >= 44100) { - table = exponent_band_44100[a]; - } else if (s->sample_rate >= 32000) { - table = exponent_band_32000[a]; - } else if (s->sample_rate >= 22050) { - table = exponent_band_22050[a]; - } - } - if (table) { - n = *table++; - for (i = 0; i < n; i++) - s->exponent_bands[k][i] = table[i]; - s->exponent_sizes[k] = n; - } else { - j = 0; - lpos = 0; - for (i = 0; i < 25; i++) { - a = ff_wma_critical_freqs[i]; - b = s->sample_rate; - pos = ((block_len * 2 * a) + (b << 1)) / (4 * b); - pos <<= 2; - if (pos > block_len) - pos = block_len; - if (pos > lpos) - s->exponent_bands[k][j++] = pos - lpos; - if (pos >= block_len) - break; - lpos = pos; - } - s->exponent_sizes[k] = j; - } - } - - /* max number of coefs */ - s->coefs_end[k] = (s->frame_len - ((s->frame_len * 9) / 100)) >> k; - /* high freq computation */ - s->high_band_start[k] = (int)((block_len * 2 * high_freq) / - s->sample_rate + 0.5); - n = s->exponent_sizes[k]; - j = 0; - pos = 0; - for (i = 0; i < n; i++) { - int start, end; - start = pos; - pos += s->exponent_bands[k][i]; - end = pos; - if (start < s->high_band_start[k]) - start = s->high_band_start[k]; - if (end > s->coefs_end[k]) - end = s->coefs_end[k]; - if (end > start) - s->exponent_high_bands[k][j++] = end - start; - } - s->exponent_high_sizes[k] = j; -#if 0 - tprintf(s->avctx, "%5d: coefs_end=%d high_band_start=%d nb_high_bands=%d: ", - s->frame_len >> k, - s->coefs_end[k], - s->high_band_start[k], - s->exponent_high_sizes[k]); - for (j = 0; j < s->exponent_high_sizes[k]; j++) - tprintf(s->avctx, " %d", s->exponent_high_bands[k][j]); - tprintf(s->avctx, "\n"); -#endif - } - } - -#ifdef TRACE - { - int i, j; - for (i = 0; i < s->nb_block_sizes; i++) { - tprintf(s->avctx, "%5d: n=%2d:", - s->frame_len >> i, - s->exponent_sizes[i]); - for (j = 0; j < s->exponent_sizes[i]; j++) - tprintf(s->avctx, " %d", s->exponent_bands[i][j]); - tprintf(s->avctx, "\n"); - } - } -#endif - - /* init MDCT windows : simple sinus window */ - for (i = 0; i < s->nb_block_sizes; i++) { - ff_init_ff_sine_windows(s->frame_len_bits - i); - s->windows[i] = ff_sine_windows[s->frame_len_bits - i]; - } - - s->reset_block_lengths = 1; - - if (s->use_noise_coding) { - - /* init the noise generator */ - if (s->use_exp_vlc) { - s->noise_mult = 0.02; - } else { - s->noise_mult = 0.04; - } - -#ifdef TRACE - for (i = 0; i < NOISE_TAB_SIZE; i++) - s->noise_table[i] = 1.0 * s->noise_mult; -#else - { - unsigned int seed; - float norm; - seed = 1; - norm = (1.0 / (float)(1LL << 31)) * sqrt(3) * s->noise_mult; - for (i = 0; i < NOISE_TAB_SIZE; i++) { - seed = seed * 314159 + 1; - s->noise_table[i] = (float)((int)seed) * norm; - } - } -#endif - } - - /* choose the VLC tables for the coefficients */ - coef_vlc_table = 2; - if (s->sample_rate >= 32000) { - if (bps1 < 0.72) { - coef_vlc_table = 0; - } else if (bps1 < 1.16) { - coef_vlc_table = 1; - } - } - s->coef_vlcs[0]= &coef_vlcs[coef_vlc_table * 2 ]; - s->coef_vlcs[1]= &coef_vlcs[coef_vlc_table * 2 + 1]; - init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0], &s->int_table[0], - s->coef_vlcs[0]); - init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], &s->int_table[1], - s->coef_vlcs[1]); - - return 0; -} - -int ff_wma_total_gain_to_bits(int total_gain) -{ - if (total_gain < 15) return 13; - else if (total_gain < 32) return 12; - else if (total_gain < 40) return 11; - else if (total_gain < 45) return 10; - else return 9; -} - -int ff_wma_end(AVCodecContext *avctx) -{ - WMACodecContext *s = avctx->priv_data; - int i; - - for (i = 0; i < s->nb_block_sizes; i++) - ff_mdct_end(&s->mdct_ctx[i]); - - if (s->use_exp_vlc) { - free_vlc(&s->exp_vlc); - } - if (s->use_noise_coding) { - free_vlc(&s->hgain_vlc); - } - for (i = 0; i < 2; i++) { - free_vlc(&s->coef_vlc[i]); - av_free(s->run_table[i]); - av_free(s->level_table[i]); - av_free(s->int_table[i]); - } - - return 0; -} - -/** - * Decode an uncompressed coefficient. - * @param s codec context - * @return the decoded coefficient - */ -unsigned int ff_wma_get_large_val(GetBitContext* gb) -{ - /** consumes up to 34 bits */ - int n_bits = 8; - /** decode length */ - if (get_bits1(gb)) { - n_bits += 8; - if (get_bits1(gb)) { - n_bits += 8; - if (get_bits1(gb)) { - n_bits += 7; - } - } - } - return get_bits_long(gb, n_bits); -} - -/** - * Decode run level compressed coefficients. - * @param avctx codec context - * @param gb bitstream reader context - * @param vlc vlc table for get_vlc2 - * @param level_table level codes - * @param run_table run codes - * @param version 0 for wma1,2 1 for wmapro - * @param ptr output buffer - * @param offset offset in the output buffer - * @param num_coefs number of input coefficents - * @param block_len input buffer length (2^n) - * @param frame_len_bits number of bits for escaped run codes - * @param coef_nb_bits number of bits for escaped level codes - * @return 0 on success, -1 otherwise - */ -int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, - VLC *vlc, - const float *level_table, const uint16_t *run_table, - int version, WMACoef *ptr, int offset, - int num_coefs, int block_len, int frame_len_bits, - int coef_nb_bits) -{ - int code, level, sign; - const uint32_t *ilvl = (const uint32_t*)level_table; - uint32_t *iptr = (uint32_t*)ptr; - const unsigned int coef_mask = block_len - 1; - for (; offset < num_coefs; offset++) { - code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); - if (code > 1) { - /** normal code */ - offset += run_table[code]; - sign = get_bits1(gb) - 1; - iptr[offset & coef_mask] = ilvl[code] ^ sign<<31; - } else if (code == 1) { - /** EOB */ - break; - } else { - /** escape */ - if (!version) { - level = get_bits(gb, coef_nb_bits); - /** NOTE: this is rather suboptimal. reading - block_len_bits would be better */ - offset += get_bits(gb, frame_len_bits); - } else { - level = ff_wma_get_large_val(gb); - /** escape decode */ - if (get_bits1(gb)) { - if (get_bits1(gb)) { - if (get_bits1(gb)) { - av_log(avctx,AV_LOG_ERROR, - "broken escape sequence\n"); - return -1; - } else - offset += get_bits(gb, frame_len_bits) + 4; - } else - offset += get_bits(gb, 2) + 1; - } - } - sign = get_bits1(gb) - 1; - ptr[offset & coef_mask] = (level^sign) - sign; - } - } - /** NOTE: EOB can be omitted */ - if (offset > num_coefs) { - av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); - return -1; - } - - return 0; -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/wma.h b/tizen/distrib/ffmpeg/libavcodec/wma.h deleted file mode 100644 index 11274ad..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wma.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * WMA compatible codec - * Copyright (c) 2002-2007 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_WMA_H -#define AVCODEC_WMA_H - -#include "get_bits.h" -#include "put_bits.h" -#include "dsputil.h" -#include "fft.h" - -/* size of blocks */ -#define BLOCK_MIN_BITS 7 -#define BLOCK_MAX_BITS 11 -#define BLOCK_MAX_SIZE (1 << BLOCK_MAX_BITS) - -#define BLOCK_NB_SIZES (BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) - -/* XXX: find exact max size */ -#define HIGH_BAND_MAX_SIZE 16 - -#define NB_LSP_COEFS 10 - -/* XXX: is it a suitable value ? */ -#define MAX_CODED_SUPERFRAME_SIZE 16384 - -#define MAX_CHANNELS 2 - -#define NOISE_TAB_SIZE 8192 - -#define LSP_POW_BITS 7 - -//FIXME should be in wmadec -#define VLCBITS 9 -#define VLCMAX ((22+VLCBITS-1)/VLCBITS) - -typedef float WMACoef; ///< type for decoded coefficients, int16_t would be enough for wma 1/2 - -typedef struct CoefVLCTable { - int n; ///< total number of codes - int max_level; - const uint32_t *huffcodes; ///< VLC bit values - const uint8_t *huffbits; ///< VLC bit size - const uint16_t *levels; ///< table to build run/level tables -} CoefVLCTable; - -typedef struct WMACodecContext { - AVCodecContext* avctx; - GetBitContext gb; - PutBitContext pb; - int sample_rate; - int nb_channels; - int bit_rate; - int version; ///< 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2) - int block_align; - int use_bit_reservoir; - int use_variable_block_len; - int use_exp_vlc; ///< exponent coding: 0 = lsp, 1 = vlc + delta - int use_noise_coding; ///< true if perceptual noise is added - int byte_offset_bits; - VLC exp_vlc; - int exponent_sizes[BLOCK_NB_SIZES]; - uint16_t exponent_bands[BLOCK_NB_SIZES][25]; - int high_band_start[BLOCK_NB_SIZES]; ///< index of first coef in high band - int coefs_start; ///< first coded coef - int coefs_end[BLOCK_NB_SIZES]; ///< max number of coded coefficients - int exponent_high_sizes[BLOCK_NB_SIZES]; - int exponent_high_bands[BLOCK_NB_SIZES][HIGH_BAND_MAX_SIZE]; - VLC hgain_vlc; - - /* coded values in high bands */ - int high_band_coded[MAX_CHANNELS][HIGH_BAND_MAX_SIZE]; - int high_band_values[MAX_CHANNELS][HIGH_BAND_MAX_SIZE]; - - /* there are two possible tables for spectral coefficients */ -//FIXME the following 3 tables should be shared between decoders - VLC coef_vlc[2]; - uint16_t *run_table[2]; - float *level_table[2]; - uint16_t *int_table[2]; - const CoefVLCTable *coef_vlcs[2]; - /* frame info */ - int frame_len; ///< frame length in samples - int frame_len_bits; ///< frame_len = 1 << frame_len_bits - int nb_block_sizes; ///< number of block sizes - /* block info */ - int reset_block_lengths; - int block_len_bits; ///< log2 of current block length - int next_block_len_bits; ///< log2 of next block length - int prev_block_len_bits; ///< log2 of prev block length - int block_len; ///< block length in samples - int block_num; ///< block number in current frame - int block_pos; ///< current position in frame - uint8_t ms_stereo; ///< true if mid/side stereo mode - uint8_t channel_coded[MAX_CHANNELS]; ///< true if channel is coded - int exponents_bsize[MAX_CHANNELS]; ///< log2 ratio frame/exp. length - DECLARE_ALIGNED(16, float, exponents)[MAX_CHANNELS][BLOCK_MAX_SIZE]; - float max_exponent[MAX_CHANNELS]; - WMACoef coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE]; - DECLARE_ALIGNED(16, float, coefs)[MAX_CHANNELS][BLOCK_MAX_SIZE]; - DECLARE_ALIGNED(16, FFTSample, output)[BLOCK_MAX_SIZE * 2]; - FFTContext mdct_ctx[BLOCK_NB_SIZES]; - float *windows[BLOCK_NB_SIZES]; - /* output buffer for one frame and the last for IMDCT windowing */ - DECLARE_ALIGNED(16, float, frame_out)[MAX_CHANNELS][BLOCK_MAX_SIZE * 2]; - /* last frame info */ - uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */ - int last_bitoffset; - int last_superframe_len; - float noise_table[NOISE_TAB_SIZE]; - int noise_index; - float noise_mult; /* XXX: suppress that and integrate it in the noise array */ - /* lsp_to_curve tables */ - float lsp_cos_table[BLOCK_MAX_SIZE]; - float lsp_pow_e_table[256]; - float lsp_pow_m_table1[(1 << LSP_POW_BITS)]; - float lsp_pow_m_table2[(1 << LSP_POW_BITS)]; - DSPContext dsp; - -#ifdef TRACE - int frame_count; -#endif -} WMACodecContext; - -extern const uint16_t ff_wma_critical_freqs[25]; -extern const uint16_t ff_wma_hgain_huffcodes[37]; -extern const uint8_t ff_wma_hgain_huffbits[37]; -extern const float ff_wma_lsp_codebook[NB_LSP_COEFS][16]; -extern const uint32_t ff_aac_scalefactor_code[121]; -extern const uint8_t ff_aac_scalefactor_bits[121]; - -int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version, - unsigned int decode_flags); -int ff_wma_init(AVCodecContext * avctx, int flags2); -int ff_wma_total_gain_to_bits(int total_gain); -int ff_wma_end(AVCodecContext *avctx); -unsigned int ff_wma_get_large_val(GetBitContext* gb); -int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, - VLC *vlc, - const float *level_table, const uint16_t *run_table, - int version, WMACoef *ptr, int offset, - int num_coefs, int block_len, int frame_len_bits, - int coef_nb_bits); - -#endif /* AVCODEC_WMA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/wmadata.h b/tizen/distrib/ffmpeg/libavcodec/wmadata.h deleted file mode 100644 index 381f182..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmadata.h +++ /dev/null @@ -1,1403 +0,0 @@ -/* - * WMA compatible decoder - * copyright (c) 2002 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Various WMA tables. - */ - -#ifndef AVCODEC_WMADATA_H -#define AVCODEC_WMADATA_H - -#include -#include "wma.h" - -const uint16_t ff_wma_critical_freqs[25] = { - 100, 200, 300, 400, 510, 630, 770, 920, - 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, - 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, - 24500, -}; - -/* first value is number of bands */ -static const uint8_t exponent_band_22050[3][25] = { - { 10, 4, 8, 4, 8, 8, 12, 20, 24, 24, 16, }, - { 14, 4, 8, 8, 4, 12, 12, 16, 24, 16, 20, 24, 32, 40, 36, }, - { 23, 4, 4, 4, 8, 4, 4, 8, 8, 8, 8, 8, 12, 12, 16, 16, 24, 24, 32, 44, 48, 60, 84, 72, }, -}; - -static const uint8_t exponent_band_32000[3][25] = { - { 11, 4, 4, 8, 4, 4, 12, 16, 24, 20, 28, 4, }, - { 15, 4, 8, 4, 4, 8, 8, 16, 20, 12, 20, 20, 28, 40, 56, 8, }, - { 16, 8, 4, 8, 8, 12, 16, 20, 24, 40, 32, 32, 44, 56, 80, 112, 16, }, -}; - -static const uint8_t exponent_band_44100[3][25] = { - { 12, 4, 4, 4, 4, 4, 8, 8, 8, 12, 16, 20, 36, }, - { 15, 4, 8, 4, 8, 8, 4, 8, 8, 12, 12, 12, 24, 28, 40, 76, }, - { 17, 4, 8, 8, 4, 12, 12, 8, 8, 24, 16, 20, 24, 32, 40, 60, 80, 152, }, -}; - -const uint16_t ff_wma_hgain_huffcodes[37] = { - 0x00003, 0x002e7, 0x00001, 0x005cd, 0x0005d, 0x005c9, 0x0005e, 0x00003, - 0x00016, 0x0000b, 0x00001, 0x00006, 0x00001, 0x00006, 0x00004, 0x00005, - 0x00004, 0x00007, 0x00003, 0x00007, 0x00004, 0x0000a, 0x0000a, 0x00002, - 0x00003, 0x00000, 0x00005, 0x00002, 0x0005f, 0x00004, 0x00003, 0x00002, - 0x005c8, 0x000b8, 0x005ca, 0x005cb, 0x005cc, -}; - -const uint8_t ff_wma_hgain_huffbits[37] = { - 10, 12, 10, 13, 9, 13, 9, 8, - 7, 5, 5, 4, 4, 3, 3, 3, - 4, 3, 4, 4, 5, 5, 6, 8, - 7, 10, 8, 10, 9, 8, 9, 9, - 13, 10, 13, 13, 13, -}; - -const float ff_wma_lsp_codebook[NB_LSP_COEFS][16] = { - { 1.98732877, 1.97944528, 1.97179088, 1.96260549, 1.95038374, 1.93336114, 1.90719232, 1.86191415, }, - { 1.97260000, 1.96083160, 1.94982586, 1.93806164, 1.92516608, 1.91010199, 1.89232331, 1.87149812, - 1.84564818, 1.81358067, 1.77620070, 1.73265264, 1.67907855, 1.60959081, 1.50829650, 1.33120330, }, - { 1.90109110, 1.86482426, 1.83419671, 1.80168452, 1.76650116, 1.72816320, 1.68502700, 1.63738256, - 1.58501580, 1.51795181, 1.43679906, 1.33950585, 1.24176208, 1.12260729, 0.96749668, 0.74048265, }, - { 1.76943864, 1.67822463, 1.59946365, 1.53560582, 1.47470796, 1.41210167, 1.34509536, 1.27339507, - 1.19303814, 1.09765169, 0.98818722, 0.87239446, 0.74369172, 0.59768184, 0.43168630, 0.17977021, }, - { 1.43428349, 1.32038354, 1.21074086, 1.10577988, 1.00561746, 0.90335924, 0.80437489, 0.70709671, - 0.60427395, 0.49814048, 0.38509539, 0.27106800, 0.14407416, 0.00219910, -0.16725141, -0.36936085, }, - { 0.99895687, 0.84188166, 0.70753739, 0.57906595, 0.47055563, 0.36966965, 0.26826648, 0.17163380, - 0.07208392, -0.03062936, -1.40037388, -0.25128968, -0.37213937, -0.51075646, -0.64887512, -0.80308031, }, - { 0.26515280, 0.06313551, -0.08872080, -0.21103548, -0.31069678, -0.39680323, -0.47223474, -0.54167135, - -0.61444740, -0.68943343, -0.76580211, -0.85170082, -0.95289061, -1.06514703, -1.20510707, -1.37617746, }, - { -0.53940301, -0.73770929, -0.88424876, -1.01117930, -1.13389091, -1.26830073, -1.42041987, -1.62033919, - -1.10158808, -1.16512566, -1.23337128, -1.30414401, -1.37663312, -1.46853845, -1.57625798, -1.66893638, }, - { -0.38601997, -0.56009350, -0.66978483, -0.76028471, -0.83846064, -0.90868087, -0.97408881, -1.03694962, }, - { -1.56144989, -1.65944032, -1.72689685, -1.77857740, -1.82203011, -1.86220079, -1.90283983, -1.94820479, }, -}; - -static const uint32_t coef0_huffcodes[666] = { - 0x00258, 0x0003d, 0x00000, 0x00005, 0x00008, 0x00008, 0x0000c, 0x0001b, - 0x0001f, 0x00015, 0x00024, 0x00032, 0x0003a, 0x00026, 0x0002c, 0x0002f, - 0x0004a, 0x0004d, 0x00061, 0x00070, 0x00073, 0x00048, 0x00052, 0x0005a, - 0x0005d, 0x0006e, 0x00099, 0x0009e, 0x000c1, 0x000ce, 0x000e4, 0x000f0, - 0x00093, 0x0009e, 0x000a2, 0x000a1, 0x000b8, 0x000d2, 0x000d3, 0x0012e, - 0x00130, 0x000de, 0x0012d, 0x0019b, 0x001e4, 0x00139, 0x0013a, 0x0013f, - 0x0014f, 0x0016d, 0x001a2, 0x0027c, 0x0027e, 0x00332, 0x0033c, 0x0033f, - 0x0038b, 0x00396, 0x003c5, 0x00270, 0x0027c, 0x0025a, 0x00395, 0x00248, - 0x004bd, 0x004fb, 0x00662, 0x00661, 0x0071b, 0x004e6, 0x004ff, 0x00666, - 0x0071c, 0x0071a, 0x0071f, 0x00794, 0x00536, 0x004e2, 0x0078e, 0x004ee, - 0x00518, 0x00535, 0x004fb, 0x0078d, 0x00530, 0x00680, 0x0068f, 0x005cb, - 0x00965, 0x006a6, 0x00967, 0x0097f, 0x00682, 0x006ae, 0x00cd0, 0x00e28, - 0x00f13, 0x00f1f, 0x009f5, 0x00cd3, 0x00f11, 0x00926, 0x00964, 0x00f32, - 0x00f12, 0x00f30, 0x00966, 0x00d0b, 0x00a68, 0x00b91, 0x009c7, 0x00b73, - 0x012fa, 0x0131d, 0x013f9, 0x01ca0, 0x0199c, 0x01c7a, 0x0198c, 0x01248, - 0x01c74, 0x01c64, 0x0139e, 0x012fd, 0x00a77, 0x012fc, 0x01c7b, 0x012ca, - 0x014cc, 0x014d2, 0x014e3, 0x014dc, 0x012dc, 0x03344, 0x02598, 0x0263c, - 0x0333b, 0x025e6, 0x01a1c, 0x01e3c, 0x014e2, 0x033d4, 0x01a11, 0x03349, - 0x03cce, 0x014e1, 0x01a34, 0x0273e, 0x02627, 0x0273f, 0x038ee, 0x03971, - 0x03c67, 0x03c61, 0x0333d, 0x038c2, 0x0263f, 0x038cd, 0x02638, 0x02e41, - 0x0351f, 0x03348, 0x03c66, 0x03562, 0x02989, 0x027d5, 0x0333c, 0x02e4f, - 0x0343b, 0x02ddf, 0x04bc8, 0x029c0, 0x02e57, 0x04c72, 0x025b7, 0x03547, - 0x03540, 0x029d3, 0x04c45, 0x025bb, 0x06600, 0x04c73, 0x04bce, 0x0357b, - 0x029a6, 0x029d2, 0x0263e, 0x0298a, 0x07183, 0x06602, 0x07958, 0x04b66, - 0x0537d, 0x05375, 0x04fe9, 0x04b67, 0x0799f, 0x04bc9, 0x051fe, 0x06a3b, - 0x05bb6, 0x04fa8, 0x0728f, 0x05376, 0x0492c, 0x0537e, 0x0795a, 0x06a3c, - 0x0e515, 0x07887, 0x0683a, 0x051f9, 0x051fd, 0x0cc6a, 0x06a8a, 0x0cc6d, - 0x05bb3, 0x0683b, 0x051fc, 0x05378, 0x0728e, 0x07886, 0x05bb7, 0x0f2a4, - 0x0795b, 0x0683c, 0x09fc1, 0x0683d, 0x0b752, 0x09678, 0x0a3e8, 0x06ac7, - 0x051f0, 0x0b759, 0x06af3, 0x04b6b, 0x0f2a0, 0x0f2ad, 0x096c3, 0x0e518, - 0x0b75c, 0x0d458, 0x0cc6b, 0x0537c, 0x067aa, 0x04fea, 0x0343a, 0x0cc71, - 0x0967f, 0x09fc4, 0x096c2, 0x0e516, 0x0f2a1, 0x0d45c, 0x0d45d, 0x0d45e, - 0x12fb9, 0x0967e, 0x1982f, 0x09883, 0x096c4, 0x0b753, 0x12fb8, 0x0f2a8, - 0x1ca21, 0x096c5, 0x0e51a, 0x1ca27, 0x12f3c, 0x0d471, 0x0f2aa, 0x0b75b, - 0x12fbb, 0x0f2a9, 0x0f2ac, 0x0d45a, 0x0b74f, 0x096c8, 0x16e91, 0x096ca, - 0x12fbf, 0x0d0a7, 0x13103, 0x0d516, 0x16e99, 0x12cbd, 0x0a3ea, 0x19829, - 0x0b755, 0x29ba7, 0x1ca28, 0x29ba5, 0x16e93, 0x1982c, 0x19828, 0x25994, - 0x0a3eb, 0x1ca29, 0x16e90, 0x1ca25, 0x1982d, 0x1ca26, 0x16e9b, 0x0b756, - 0x0967c, 0x25997, 0x0b75f, 0x198d3, 0x0b757, 0x19a2a, 0x0d45b, 0x0e517, - 0x1ca24, 0x1ca23, 0x1ca22, 0x0b758, 0x16e97, 0x0cd14, 0x13100, 0x00007, - 0x0003b, 0x0006b, 0x00097, 0x00138, 0x00125, 0x00173, 0x00258, 0x00335, - 0x0028e, 0x004c6, 0x00715, 0x00729, 0x004ef, 0x00519, 0x004ed, 0x00532, - 0x0068c, 0x00686, 0x00978, 0x00e5d, 0x00e31, 0x009f4, 0x00b92, 0x012f8, - 0x00d06, 0x00a67, 0x00d44, 0x00a76, 0x00d59, 0x012cd, 0x01c78, 0x01c75, - 0x0199f, 0x0198f, 0x01c67, 0x014c6, 0x01c79, 0x01c76, 0x00b94, 0x00d1b, - 0x01e32, 0x01e31, 0x01ab0, 0x01a05, 0x01aa1, 0x0333a, 0x025e5, 0x02626, - 0x03541, 0x03544, 0x03421, 0x03546, 0x02e55, 0x02e56, 0x0492d, 0x02dde, - 0x0299b, 0x02ddc, 0x0357a, 0x0249c, 0x0668b, 0x1c77f, 0x1ca20, 0x0d45f, - 0x09886, 0x16e9a, 0x0f2a7, 0x0b751, 0x0a3ee, 0x0cf59, 0x0cf57, 0x0b754, - 0x0d0a6, 0x16e98, 0x0b760, 0x06ac6, 0x0a3f0, 0x12fbe, 0x13104, 0x0f2a5, - 0x0a3ef, 0x0d472, 0x12cba, 0x1982e, 0x16e9c, 0x1c77e, 0x198d0, 0x13105, - 0x16e92, 0x0b75d, 0x0d459, 0x0001a, 0x000c0, 0x0016c, 0x003cd, 0x00350, - 0x0067b, 0x0051e, 0x006a9, 0x009f4, 0x00b72, 0x00d09, 0x01249, 0x01e3d, - 0x01ca1, 0x01a1f, 0x01721, 0x01a8a, 0x016e8, 0x03347, 0x01a35, 0x0249d, - 0x0299a, 0x02596, 0x02e4e, 0x0298b, 0x07182, 0x04c46, 0x025ba, 0x02e40, - 0x027d6, 0x04fe8, 0x06607, 0x05310, 0x09884, 0x072e1, 0x06a3d, 0x04b6a, - 0x04c7a, 0x06603, 0x04c7b, 0x03428, 0x06605, 0x09664, 0x09fc0, 0x071de, - 0x06601, 0x05bb2, 0x09885, 0x0a3e2, 0x1c61f, 0x12cbb, 0x0b750, 0x0cf58, - 0x0967d, 0x25995, 0x668ad, 0x0b75a, 0x09fc2, 0x0537f, 0x0b75e, 0x13fae, - 0x12fbc, 0x00031, 0x001c4, 0x004c5, 0x005b8, 0x00cf4, 0x0096f, 0x00d46, - 0x01e57, 0x01a04, 0x02625, 0x03346, 0x028f9, 0x04c47, 0x072e0, 0x04b69, - 0x03420, 0x07957, 0x06639, 0x0799e, 0x07959, 0x07881, 0x04b68, 0x09fc3, - 0x09fd6, 0x0cc70, 0x0a3f1, 0x12cbe, 0x0e30e, 0x0e51b, 0x06af2, 0x12cbc, - 0x1c77d, 0x0f2ab, 0x12fbd, 0x1aa2f, 0x0a3ec, 0x0d473, 0x05377, 0x0a3e9, - 0x1982b, 0x0e300, 0x12f3f, 0x0cf5f, 0x096c0, 0x38c3c, 0x16e94, 0x16e95, - 0x12f3d, 0x29ba4, 0x29ba6, 0x1c77c, 0x6a8ba, 0x3545c, 0x33457, 0x668ac, - 0x6a8bb, 0x16e9d, 0x0e519, 0x25996, 0x12f3e, 0x00036, 0x0033e, 0x006ad, - 0x00d03, 0x012c8, 0x0124a, 0x03c42, 0x03ccd, 0x06606, 0x07880, 0x06852, - 0x06a3a, 0x05bb4, 0x0f2a2, 0x09fc7, 0x12cb9, 0x0cc6c, 0x0a6e8, 0x096c1, - 0x0004a, 0x00355, 0x012f9, 0x014e8, 0x01abe, 0x025b6, 0x0492e, 0x09fc6, - 0x051ff, 0x0cc6f, 0x096cb, 0x0d071, 0x198d1, 0x12cb8, 0x38c3d, 0x13faf, - 0x096c9, 0x0009d, 0x00539, 0x012ce, 0x0341f, 0x029c1, 0x04b33, 0x0a3e3, - 0x0d070, 0x16e96, 0x0b763, 0x000a0, 0x009ce, 0x038cc, 0x0343d, 0x051fa, - 0x09888, 0x12fba, 0x000df, 0x00a75, 0x029a7, 0x09fc5, 0x0e301, 0x0967b, - 0x001e7, 0x012c9, 0x051fb, 0x09889, 0x0f2a6, 0x0016f, 0x01cb9, 0x0cf5a, - 0x12cbf, 0x09679, 0x00272, 0x01a15, 0x0967a, 0x003cb, 0x025f6, 0x0b762, - 0x0028d, 0x03c60, 0x0cf5e, 0x00352, 0x03ccc, 0x0072f, 0x07186, 0x004ec, - 0x05379, 0x0068e, 0x09887, 0x006a7, 0x06af1, 0x00e29, 0x0cf5b, 0x00f31, - 0x0d470, 0x009c6, 0x013fb, 0x13102, 0x019a5, 0x13101, 0x01983, 0x01c65, - 0x0124f, 0x014c7, 0x01726, 0x01abf, 0x03304, 0x02624, 0x03c41, 0x027d7, - 0x02ddd, 0x02e54, 0x0343c, 0x06604, 0x07181, 0x0663a, 0x04fa9, 0x0663b, - 0x05311, 0x0537a, 0x06839, 0x05bb5, 0x0492f, 0x06af0, 0x096c7, 0x0cc6e, - 0x0537b, 0x0cf5c, 0x0cf56, 0x198d2, 0x0cf5d, 0x0a3ed, 0x0f2a3, 0x1982a, - 0x0b761, 0x096c6, -}; - -static const uint8_t coef0_huffbits[666] = { - 11, 6, 2, 3, 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, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 11, 11, 11, 10, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 12, 12, 11, 12, - 12, 12, 12, 11, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 13, 13, 12, - 12, 12, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 14, - 13, 13, 13, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 13, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 15, - 15, 14, 14, 15, 15, 15, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 14, 15, 15, 15, 15, 16, - 16, 16, 15, 16, 15, 15, 16, 16, - 16, 16, 15, 16, 16, 16, 15, 16, - 16, 15, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 15, 15, 16, 16, - 15, 16, 16, 16, 17, 17, 17, 16, - 16, 17, 16, 16, 16, 16, 17, 16, - 17, 17, 16, 16, 15, 15, 15, 16, - 17, 16, 17, 16, 16, 17, 17, 17, - 17, 17, 17, 16, 17, 17, 17, 16, - 17, 17, 16, 17, 17, 17, 16, 17, - 17, 16, 16, 17, 17, 17, 18, 17, - 17, 17, 17, 17, 18, 18, 17, 17, - 17, 19, 17, 19, 18, 17, 17, 18, - 17, 17, 18, 17, 17, 17, 18, 17, - 17, 18, 17, 17, 17, 17, 17, 16, - 17, 17, 17, 17, 18, 16, 17, 4, - 6, 8, 9, 9, 10, 10, 10, 10, - 11, 11, 11, 11, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 14, 13, 13, 13, 13, - 13, 13, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 16, 15, - 15, 15, 15, 15, 15, 17, 17, 17, - 16, 18, 16, 17, 17, 16, 16, 17, - 17, 18, 17, 16, 17, 17, 17, 16, - 17, 17, 18, 17, 18, 17, 17, 17, - 18, 17, 17, 5, 8, 10, 10, 11, - 11, 12, 12, 12, 13, 13, 14, 13, - 13, 14, 14, 14, 14, 14, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 16, 16, 15, 16, 16, - 15, 15, 15, 15, 15, 16, 16, 15, - 15, 16, 16, 17, 17, 18, 17, 16, - 17, 18, 19, 17, 16, 16, 17, 17, - 17, 6, 9, 11, 12, 12, 13, 13, - 13, 14, 14, 14, 15, 15, 15, 16, - 15, 15, 15, 15, 15, 15, 16, 16, - 16, 16, 17, 18, 16, 16, 16, 18, - 17, 16, 17, 18, 17, 17, 16, 17, - 17, 16, 17, 16, 17, 18, 18, 18, - 17, 19, 19, 17, 20, 19, 18, 19, - 20, 18, 16, 18, 17, 7, 10, 12, - 13, 13, 14, 14, 14, 15, 15, 16, - 16, 16, 16, 16, 18, 16, 17, 17, - 8, 11, 13, 14, 14, 15, 16, 16, - 16, 16, 17, 17, 17, 18, 18, 17, - 17, 8, 12, 14, 15, 15, 15, 17, - 17, 18, 17, 9, 12, 14, 15, 16, - 16, 17, 9, 13, 15, 16, 16, 17, - 9, 13, 16, 16, 16, 10, 13, 16, - 18, 17, 10, 14, 17, 10, 14, 17, - 11, 14, 16, 11, 14, 11, 15, 12, - 16, 12, 16, 12, 16, 12, 16, 12, - 17, 13, 13, 17, 13, 17, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 15, - 15, 15, 15, 15, 15, 15, 16, 15, - 16, 16, 16, 16, 16, 16, 17, 16, - 16, 16, 16, 17, 16, 17, 16, 17, - 17, 17, -}; - -static const uint32_t coef1_huffcodes[555] = { - 0x00115, 0x00002, 0x00001, 0x00000, 0x0000d, 0x00007, 0x00013, 0x0001d, - 0x00008, 0x0000c, 0x00023, 0x0002b, 0x0003f, 0x00017, 0x0001b, 0x00043, - 0x00049, 0x00050, 0x00055, 0x00054, 0x00067, 0x00064, 0x0007b, 0x0002d, - 0x00028, 0x0002a, 0x00085, 0x00089, 0x0002b, 0x00035, 0x00090, 0x00091, - 0x00094, 0x00088, 0x000c1, 0x000c6, 0x000f2, 0x000e3, 0x000c5, 0x000e2, - 0x00036, 0x000f0, 0x000a7, 0x000cd, 0x000fb, 0x00059, 0x00116, 0x00103, - 0x00108, 0x0012b, 0x0012d, 0x00188, 0x0012e, 0x0014c, 0x001c3, 0x00187, - 0x001e7, 0x0006f, 0x00094, 0x00069, 0x001e6, 0x001ca, 0x00147, 0x00195, - 0x000a7, 0x00213, 0x00209, 0x00303, 0x00295, 0x00289, 0x0028c, 0x0028d, - 0x00312, 0x00330, 0x0029b, 0x00308, 0x00328, 0x0029a, 0x0025e, 0x003c5, - 0x00384, 0x0039f, 0x00397, 0x00296, 0x0032e, 0x00332, 0x003c6, 0x003e6, - 0x0012d, 0x000d1, 0x00402, 0x000dd, 0x00161, 0x0012b, 0x00127, 0x0045d, - 0x00601, 0x004ab, 0x0045f, 0x00410, 0x004bf, 0x00528, 0x0045c, 0x00424, - 0x00400, 0x00511, 0x00618, 0x0073d, 0x0063a, 0x00614, 0x0073c, 0x007c0, - 0x007cf, 0x00802, 0x00966, 0x00964, 0x00951, 0x008a0, 0x00346, 0x00803, - 0x00a52, 0x0024a, 0x007c1, 0x0063f, 0x00126, 0x00406, 0x00789, 0x008a2, - 0x00960, 0x00967, 0x00c05, 0x00c70, 0x00c79, 0x00a5d, 0x00c26, 0x00c4d, - 0x00372, 0x008a5, 0x00c08, 0x002c5, 0x00f11, 0x00cc4, 0x00f8e, 0x00e16, - 0x00496, 0x00e77, 0x00f9c, 0x00c25, 0x00f1e, 0x00c27, 0x00f1f, 0x00e17, - 0x00ccd, 0x00355, 0x00c09, 0x00c78, 0x00f90, 0x00521, 0x00357, 0x00356, - 0x0068e, 0x00f9d, 0x00c04, 0x00e58, 0x00a20, 0x00a2c, 0x00c4c, 0x0052f, - 0x00f8d, 0x01178, 0x01053, 0x01097, 0x0180f, 0x0180d, 0x012fb, 0x012aa, - 0x0202a, 0x00a40, 0x018ed, 0x01ceb, 0x01455, 0x018e3, 0x012a1, 0x00354, - 0x00353, 0x00f1c, 0x00c7b, 0x00c37, 0x0101d, 0x012cb, 0x01142, 0x0197d, - 0x01095, 0x01e3b, 0x0186b, 0x00588, 0x01c2a, 0x014b8, 0x01e3a, 0x018ec, - 0x01f46, 0x012fa, 0x00a53, 0x01ce8, 0x00a55, 0x01c29, 0x0117b, 0x01052, - 0x012a0, 0x00589, 0x00950, 0x01c2b, 0x00a50, 0x0208b, 0x0180e, 0x02027, - 0x02556, 0x01e20, 0x006e7, 0x01c28, 0x0197a, 0x00684, 0x020a2, 0x01f22, - 0x03018, 0x039cf, 0x03e25, 0x02557, 0x0294c, 0x028a6, 0x00d11, 0x028a9, - 0x02979, 0x00d46, 0x00a56, 0x039ce, 0x030cc, 0x0329a, 0x0149d, 0x0510f, - 0x0451c, 0x02028, 0x03299, 0x01ced, 0x014b9, 0x00f85, 0x00c7a, 0x01800, - 0x00341, 0x012ca, 0x039c8, 0x0329d, 0x00d0d, 0x03e20, 0x05144, 0x00d45, - 0x030d0, 0x0186d, 0x030d5, 0x00d0f, 0x00d40, 0x04114, 0x020a1, 0x0297f, - 0x03e24, 0x032f1, 0x04047, 0x030d4, 0x028a8, 0x00d0e, 0x0451d, 0x04044, - 0x0297e, 0x04042, 0x030d2, 0x030cf, 0x03e21, 0x03e26, 0x028a5, 0x0451a, - 0x00d48, 0x01a16, 0x00d44, 0x04518, 0x0149b, 0x039ca, 0x01498, 0x0403d, - 0x0451b, 0x0149c, 0x032f3, 0x030cb, 0x08073, 0x03e22, 0x0529a, 0x020aa, - 0x039cc, 0x0738a, 0x06530, 0x07389, 0x06193, 0x08071, 0x04043, 0x030ce, - 0x05147, 0x07388, 0x05145, 0x08072, 0x04521, 0x00d47, 0x0297c, 0x030cd, - 0x030ca, 0x0000b, 0x0000c, 0x00083, 0x000e4, 0x00048, 0x00102, 0x001cc, - 0x001f5, 0x00097, 0x0020b, 0x00124, 0x00453, 0x00627, 0x00639, 0x00605, - 0x00517, 0x001b8, 0x00663, 0x00667, 0x007c3, 0x00823, 0x00961, 0x00963, - 0x00e5a, 0x00e59, 0x00a2b, 0x00cbf, 0x00292, 0x00a2d, 0x007d0, 0x00953, - 0x00cc5, 0x00f84, 0x004ab, 0x014a7, 0x0068a, 0x0117a, 0x0052e, 0x01442, - 0x0052c, 0x00c77, 0x00f8f, 0x004aa, 0x01094, 0x01801, 0x012c4, 0x0297b, - 0x00952, 0x01f19, 0x006a5, 0x01149, 0x012c5, 0x01803, 0x022f2, 0x0329b, - 0x04520, 0x0149e, 0x00d13, 0x01f16, 0x01ce9, 0x0101c, 0x006e6, 0x039c9, - 0x06191, 0x07c8e, 0x06192, 0x0ca63, 0x039cd, 0x06190, 0x06884, 0x06885, - 0x07382, 0x00d49, 0x00d41, 0x0450c, 0x0149a, 0x030d1, 0x08077, 0x03e23, - 0x01a15, 0x0e701, 0x0e702, 0x08079, 0x0822a, 0x0a218, 0x07887, 0x0403f, - 0x0520b, 0x0529b, 0x0e700, 0x04519, 0x00007, 0x000e0, 0x000d0, 0x0039b, - 0x003e5, 0x00163, 0x0063e, 0x007c9, 0x00806, 0x00954, 0x01044, 0x01f44, - 0x0197c, 0x01f45, 0x00a51, 0x01f47, 0x00951, 0x0052d, 0x02291, 0x0092f, - 0x00a54, 0x00d12, 0x0297d, 0x00d0c, 0x01499, 0x0329e, 0x032f0, 0x02025, - 0x039c6, 0x00a57, 0x03e46, 0x00d42, 0x0738b, 0x05146, 0x04046, 0x08078, - 0x0510e, 0x07886, 0x02904, 0x04156, 0x04157, 0x06032, 0x030d3, 0x08bce, - 0x04040, 0x0403e, 0x0a414, 0x10457, 0x08075, 0x06887, 0x07c8f, 0x039c7, - 0x07387, 0x08070, 0x08bcf, 0x1482a, 0x10456, 0x1482b, 0x01a17, 0x06886, - 0x0450d, 0x00013, 0x0006b, 0x00615, 0x0080b, 0x0082b, 0x00952, 0x00e5b, - 0x018e2, 0x0186c, 0x01f18, 0x0329f, 0x00d43, 0x03e29, 0x05140, 0x05141, - 0x0ca62, 0x06033, 0x03c42, 0x03e28, 0x0450f, 0x0a21a, 0x07384, 0x0a219, - 0x0e703, 0x0a21b, 0x01a14, 0x07383, 0x045e6, 0x0007a, 0x0012c, 0x00ccc, - 0x0068f, 0x01802, 0x00a52, 0x00953, 0x04045, 0x01a20, 0x0451f, 0x000a4, - 0x00735, 0x01cec, 0x02029, 0x020a3, 0x0451e, 0x00069, 0x00c24, 0x02024, - 0x032f2, 0x05142, 0x00196, 0x00523, 0x000a6, 0x0197b, 0x0030b, 0x0092e, - 0x003e9, 0x03e27, 0x00160, 0x05143, 0x00652, 0x04041, 0x00734, 0x028a7, - 0x0080f, 0x01483, 0x0097c, 0x00340, 0x0068b, 0x00522, 0x01054, 0x01096, - 0x01f17, 0x0202b, 0x01cea, 0x020a0, 0x02978, 0x02026, 0x0297a, 0x039cb, - 0x03e2b, 0x0149f, 0x0329c, 0x07385, 0x08074, 0x0450e, 0x03e2a, 0x05149, - 0x08076, 0x07386, 0x05148, -}; - -static const uint8_t coef1_huffbits[555] = { - 9, 5, 2, 4, 4, 5, 5, 5, - 6, 6, 6, 6, 6, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 9, 8, 8, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 10, 10, 10, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 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, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 11, 11, 11, 11, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 13, 12, 12, 12, 12, 12, 12, 12, - 13, 12, 12, 12, 12, 12, 12, 12, - 12, 13, 12, 12, 12, 13, 13, 13, - 13, 12, 12, 12, 12, 12, 12, 13, - 12, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 13, 13, 13, 13, 13, 13, - 13, 12, 12, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 14, 13, 14, 13, 13, 13, - 13, 13, 14, 13, 14, 14, 13, 14, - 14, 13, 14, 13, 13, 14, 14, 13, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 15, 14, 14, 14, 14, 15, 15, - 15, 14, 14, 13, 13, 12, 12, 13, - 13, 13, 14, 14, 15, 14, 15, 15, - 14, 13, 14, 15, 15, 15, 14, 14, - 14, 14, 15, 14, 14, 15, 15, 15, - 14, 15, 14, 14, 14, 14, 14, 15, - 15, 16, 15, 15, 15, 14, 15, 15, - 15, 15, 14, 14, 16, 14, 15, 14, - 14, 15, 15, 15, 15, 16, 15, 14, - 15, 15, 15, 16, 15, 15, 14, 14, - 14, 4, 7, 8, 8, 9, 9, 9, - 9, 10, 10, 11, 11, 11, 11, 11, - 11, 12, 11, 11, 11, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 11, 12, - 12, 12, 13, 13, 13, 13, 13, 13, - 13, 12, 12, 13, 13, 13, 13, 14, - 14, 13, 14, 13, 13, 13, 14, 14, - 15, 15, 14, 13, 13, 13, 14, 14, - 15, 15, 15, 16, 14, 15, 17, 17, - 15, 15, 15, 15, 15, 14, 16, 14, - 16, 16, 16, 16, 16, 16, 15, 15, - 17, 15, 16, 15, 6, 8, 10, 10, - 10, 11, 11, 11, 12, 12, 13, 13, - 13, 13, 14, 13, 14, 13, 14, 14, - 14, 14, 14, 15, 15, 14, 14, 14, - 14, 14, 14, 15, 15, 15, 15, 16, - 15, 15, 16, 15, 15, 15, 14, 16, - 15, 15, 18, 17, 16, 17, 15, 14, - 15, 16, 16, 19, 17, 19, 16, 17, - 15, 7, 10, 11, 12, 12, 12, 12, - 13, 13, 13, 14, 15, 14, 15, 15, - 16, 15, 14, 14, 15, 16, 15, 16, - 16, 16, 16, 15, 15, 7, 11, 12, - 13, 13, 14, 14, 15, 15, 15, 8, - 11, 13, 14, 14, 15, 9, 12, 14, - 14, 15, 9, 13, 10, 13, 10, 14, - 10, 14, 11, 15, 11, 15, 11, 14, - 12, 15, 12, 13, 13, 13, 13, 13, - 13, 14, 13, 14, 14, 14, 14, 14, - 14, 15, 14, 15, 16, 15, 14, 15, - 16, 15, 15, -}; - -static const uint32_t coef2_huffcodes[1336] = { - 0x003e6, 0x000f6, 0x00000, 0x00002, 0x00006, 0x0000f, 0x0001b, 0x00028, - 0x00039, 0x0003f, 0x0006b, 0x00076, 0x000b7, 0x000e8, 0x000ef, 0x00169, - 0x001a7, 0x001d4, 0x001dc, 0x002c4, 0x00349, 0x00355, 0x00391, 0x003dc, - 0x00581, 0x005b2, 0x00698, 0x0070c, 0x00755, 0x0073a, 0x00774, 0x007cf, - 0x00b0a, 0x00b66, 0x00d2e, 0x00d5e, 0x00e1b, 0x00eac, 0x00e5a, 0x00f7e, - 0x00fa1, 0x0163e, 0x01a37, 0x01a52, 0x01c39, 0x01ab3, 0x01d5f, 0x01cb6, - 0x01f52, 0x01dd9, 0x02c04, 0x02c2e, 0x02c2d, 0x02c23, 0x03467, 0x034a3, - 0x0351b, 0x03501, 0x03a5d, 0x0351c, 0x03875, 0x03dea, 0x0397b, 0x039db, - 0x03df1, 0x039d8, 0x03bb4, 0x0580a, 0x0584d, 0x05842, 0x05b13, 0x058ea, - 0x0697d, 0x06a06, 0x068cc, 0x06ac7, 0x06a96, 0x072f4, 0x07543, 0x072b4, - 0x07d20, 0x0b003, 0x073b5, 0x07be6, 0x0d180, 0x07bd1, 0x07cb8, 0x07d06, - 0x07d25, 0x0d2f2, 0x0d19a, 0x0d334, 0x0e1dc, 0x0d529, 0x0d584, 0x0e1d2, - 0x0e5e3, 0x0eec4, 0x0e564, 0x0fa49, 0x16001, 0x0eedc, 0x0f7fa, 0x1a32c, - 0x16131, 0x16003, 0x0f9c8, 0x1ef80, 0x1d2a0, 0x1aa4b, 0x0f7ce, 0x1abfe, - 0x1aa50, 0x1a458, 0x1a816, 0x1cae4, 0x1d2fe, 0x1d52e, 0x1aa4c, 0x2c245, - 0x1d2a1, 0x1a35d, 0x1ca1b, 0x1d5d8, 0x1f531, 0x1ca1c, 0x1f389, 0x1f4af, - 0x3a5e7, 0x351fb, 0x2c24b, 0x34bce, 0x2c24d, 0x2c249, 0x2c24a, 0x72dfc, - 0x357ef, 0x35002, 0x3a5e6, 0x39431, 0x5843b, 0x34a77, 0x58431, 0x3a5f3, - 0x3a5dd, 0x3e5e5, 0x356bd, 0x3976e, 0x6a3d2, 0x3500d, 0x694c4, 0x580bd, - 0x3e5e8, 0x74b95, 0x34a6e, 0x3977c, 0x39432, 0x5b0d2, 0x6a3d8, 0x580b8, - 0x5b0cb, 0x5b0d7, 0x72dee, 0x72ded, 0x72dec, 0x74b9c, 0x3977f, 0x72dea, - 0x74b9e, 0x7be7d, 0x580bf, 0x5b0d5, 0x7cba8, 0x74b91, 0x3e5dd, 0xb6171, - 0xd46b3, 0xd46b9, 0x7cba1, 0x74b9f, 0x72de1, 0xe59f5, 0x3e5eb, 0x00004, - 0x00015, 0x00038, 0x00075, 0x000e8, 0x001d3, 0x00347, 0x0039c, 0x00690, - 0x0074a, 0x00b60, 0x00e93, 0x00f74, 0x0163d, 0x01a5a, 0x01d24, 0x01cbe, - 0x01f4b, 0x03468, 0x03562, 0x03947, 0x03e82, 0x05804, 0x05b12, 0x05803, - 0x0696d, 0x06a9e, 0x0697c, 0x06978, 0x06afb, 0x074b2, 0x072f5, 0x073c0, - 0x07541, 0x06944, 0x074b7, 0x070d3, 0x07ba9, 0x0b0b1, 0x0d1af, 0x0e1dd, - 0x0e5e2, 0x0e1a3, 0x0eec3, 0x1612f, 0x0e961, 0x0eeda, 0x0e78e, 0x0fa48, - 0x1612c, 0x0e511, 0x0e565, 0x0e953, 0x1aa4a, 0x0e59d, 0x1d52c, 0x1a811, - 0x1cae7, 0x1abfc, 0x1d52d, 0x1cacf, 0x1cf05, 0x2c254, 0x34a72, 0x1f4ac, - 0x3976b, 0x34a71, 0x2c6d9, 0x2d873, 0x34a6a, 0x357e7, 0x3464c, 0x3e5f5, - 0x58433, 0x1f53a, 0x3500a, 0x357ea, 0x34a73, 0x3942f, 0x357e5, 0x39775, - 0x694cd, 0x39772, 0x7cba5, 0x6a3ef, 0x35483, 0x74b98, 0x5b0c1, 0x39770, - 0x3a5d7, 0x39433, 0x39434, 0x694ce, 0x580be, 0x3e5ff, 0x6a3ec, 0xb616f, - 0xd46b1, 0x6a3d1, 0x72de5, 0x74b6e, 0x72de9, 0x3e700, 0xd46b6, 0x6a3e9, - 0x74b69, 0xe5675, 0xd46b8, 0x7cbaa, 0x3a5d1, 0x0000c, 0x0003c, 0x000eb, - 0x001f1, 0x003a4, 0x006a8, 0x007d5, 0x00d43, 0x00e77, 0x016c5, 0x01cb1, - 0x02c5d, 0x03a55, 0x03a56, 0x03e51, 0x03bb5, 0x05b0a, 0x06a9f, 0x074b8, - 0x07d28, 0x0d187, 0x0d40e, 0x0d52e, 0x0d425, 0x0eae3, 0x0e1d3, 0x1612e, - 0x0e59e, 0x0eec2, 0x0e578, 0x0e51a, 0x0e579, 0x0e515, 0x0e960, 0x0d183, - 0x0d220, 0x0d2cb, 0x0e512, 0x16c3e, 0x16002, 0x16c42, 0x1cae9, 0x3461a, - 0x1d2fa, 0x1a308, 0x1a849, 0x1cf07, 0x1f38f, 0x34b65, 0x2c253, 0x1ef9e, - 0x1cbc3, 0x1cbc1, 0x2c255, 0x1f384, 0x58435, 0x2c5cd, 0x3a5f7, 0x2c252, - 0x3959c, 0x2c6d8, 0x3a5d3, 0x6ad78, 0x6a3f2, 0x7cba9, 0xb6176, 0x72deb, - 0x39764, 0x3e5f6, 0x3a5d8, 0x74a8c, 0x6a3e6, 0x694d1, 0x6ad79, 0x1a4592, - 0xe59fb, 0x7cbb3, 0x5b0cd, 0x00017, 0x000b5, 0x002c3, 0x005b7, 0x00b1c, - 0x00e5c, 0x0163f, 0x01ab2, 0x01efa, 0x0348a, 0x0396e, 0x058da, 0x06963, - 0x06a30, 0x072cd, 0x073cf, 0x07ce7, 0x0d2ca, 0x0d2d8, 0x0e764, 0x0e794, - 0x16008, 0x16167, 0x1617e, 0x1aa49, 0x1a30b, 0x1a813, 0x2c6da, 0x1a580, - 0x1cbc2, 0x0f9ca, 0x1617f, 0x1d2fe, 0x0f7fc, 0x16c40, 0x0e513, 0x0eec5, - 0x0f7c3, 0x1d508, 0x1a81e, 0x1d2fd, 0x39430, 0x35486, 0x3e5fd, 0x2c24c, - 0x2c75a, 0x34a74, 0x3a5f4, 0x3464d, 0x694ca, 0x3a5f1, 0x1d509, 0x1d5c0, - 0x34648, 0x3464e, 0x6a3d5, 0x6a3e8, 0x6a3e7, 0x5b0c3, 0x2c248, 0x1f38a, - 0x3a5f2, 0x6a3e5, 0x00029, 0x00168, 0x0058c, 0x00b67, 0x00f9d, 0x01c3d, - 0x01cbf, 0x02c20, 0x0351d, 0x03df6, 0x06af9, 0x072b5, 0x0b1d7, 0x0b0b2, - 0x0d40a, 0x0d52b, 0x0e952, 0x0e797, 0x163c3, 0x1c3a0, 0x1f386, 0x1ca21, - 0x34655, 0x2c247, 0x1f53b, 0x2c250, 0x2c24f, 0x1f385, 0x1ef5d, 0x1cf15, - 0x1caea, 0x1ab0a, 0x1cf19, 0x1f53d, 0x1d5c2, 0x1d2fb, 0x1ef58, 0x34a78, - 0x357ec, 0x1f533, 0x3a5e1, 0x694d2, 0x58482, 0x3a5ee, 0x2c6dc, 0x357eb, - 0x5b0c4, 0x39778, 0x6a3e1, 0x7cbb4, 0x3a5e1, 0x74b68, 0x3a5ef, 0x3a5d2, - 0x39424, 0x72de2, 0xe59f6, 0xe59f7, 0x3e702, 0x3e5ec, 0x1f38b, 0x0003b, - 0x001f0, 0x00777, 0x00fa8, 0x01cb2, 0x02d84, 0x03a57, 0x03dd6, 0x06917, - 0x06a11, 0x07d07, 0x0eae2, 0x0e796, 0x0f9c9, 0x0f7fb, 0x16166, 0x16160, - 0x1ab1b, 0x1abfa, 0x2d87b, 0x1d2f7, 0x39768, 0x1f38c, 0x34653, 0x34651, - 0x6a3d9, 0x35001, 0x3abbd, 0x38742, 0x39426, 0x34a76, 0x3a5ec, 0x34a75, - 0x35000, 0x35488, 0x1cf10, 0x2c6db, 0x357ed, 0x357e8, 0x357e9, 0x3a5f0, - 0x694c2, 0xb6178, 0x72df5, 0x39425, 0x3942b, 0x74b6d, 0x74b6f, 0xb6177, - 0xb6179, 0x74b6a, 0xb6172, 0x58487, 0x3e5ee, 0x3e5ed, 0x72df2, 0x72df4, - 0x7cbae, 0x6a3ca, 0x70e86, 0x34bcf, 0x6a3c8, 0x00059, 0x00384, 0x00d5b, - 0x01c38, 0x03560, 0x0395b, 0x0584e, 0x06964, 0x073cd, 0x0b1e7, 0x0e798, - 0x0e78d, 0x0fa43, 0x1a848, 0x1a32f, 0x1aa4e, 0x3464a, 0x1f4ab, 0x1f38d, - 0x3a5eb, 0x3a5d4, 0x3548a, 0x6a3c7, 0x5b0d0, 0x6a3c5, 0x7cbb0, 0x694cb, - 0x3a5e5, 0x3e5e2, 0x3942c, 0x2d872, 0x1f4ae, 0x3a5d5, 0x694d3, 0x58481, - 0x35009, 0x39774, 0x58432, 0xb616c, 0x5b0db, 0x3548b, 0xb6174, 0x1d5d95, - 0xb004c, 0x7cbb2, 0x3a5e5, 0x74a8f, 0xe59f9, 0x72df6, 0xe59fd, 0x7cbad, - 0xd427d, 0x72cff, 0x3977a, 0x5b0d9, 0xb616d, 0xb616b, 0x1a4593, 0x7cbaf, - 0x5b0da, 0x00071, 0x003eb, 0x01603, 0x02c6c, 0x03961, 0x068c8, 0x06a31, - 0x072bd, 0x0d2c2, 0x0e51b, 0x0e5e6, 0x1abfb, 0x1d2ff, 0x1cae5, 0x1ef5c, - 0x1ef5e, 0x1cf13, 0x34a6d, 0x3976d, 0xb616a, 0x3e5f2, 0x6a3c4, 0xb6169, - 0x3e5dc, 0x580b9, 0x74b99, 0x75764, 0x58434, 0x3a5d9, 0x6945a, 0x69459, - 0x3548c, 0x3a5e9, 0x69457, 0x72df1, 0x6945e, 0x6a35e, 0x3e701, 0xb6168, - 0x5b0dd, 0x3a5de, 0x6a3c2, 0xd4278, 0x6a3cc, 0x72dfd, 0xb6165, 0x16009a, - 0x7cbb1, 0xd427c, 0xb6162, 0xe765e, 0x1cecbe, 0x7cbb6, 0x69454, 0xb6160, - 0xd427a, 0x1d5d96, 0xb1d6d, 0xe59f4, 0x72de8, 0x3a5db, 0x0007a, 0x006ae, - 0x01c3c, 0x03aba, 0x058e9, 0x072cc, 0x0d2dd, 0x0d22d, 0x0eec1, 0x0eedb, - 0x1d2a2, 0x1ef5b, 0x357e2, 0x3abbf, 0x1d2f9, 0x35004, 0x3a5dc, 0x351fc, - 0x3976c, 0x6a3c6, 0x6a3cb, 0x3e5ea, 0xe59f3, 0x6a3ce, 0x69452, 0xe59f0, - 0x74b90, 0xd4279, 0xd427b, 0x7cbb5, 0x5b0c5, 0x3a5e3, 0x3a5e2, 0x000d0, - 0x00775, 0x01efe, 0x03dd5, 0x0728c, 0x07cb9, 0x0e1a2, 0x0ea85, 0x0eed8, - 0x1a30a, 0x1aa4f, 0x3a5df, 0x35008, 0x3a5e0, 0x3e5f4, 0x3e5f7, 0xb1d6c, - 0x5843e, 0x34a70, 0x72df8, 0x74b6b, 0xd427f, 0x72df0, 0x5b0bf, 0x5b0c0, - 0xd46b0, 0x72def, 0xe59f8, 0x162e64, 0xb1d6f, 0x3a5e0, 0x39427, 0x69166, - 0x6a3e2, 0x6a3e3, 0x74a8d, 0xd427e, 0x1d5d97, 0xd46b4, 0x5b0d8, 0x6a3d3, - 0x000e0, 0x00b63, 0x034cc, 0x06a33, 0x073c9, 0x0e1a0, 0x0f7fd, 0x0f9cc, - 0x1617d, 0x1caeb, 0x1f4a9, 0x3abb3, 0x69450, 0x39420, 0x39777, 0x3e5e0, - 0x6a3d4, 0x6a3ed, 0xb6166, 0xe59f1, 0xb1d6e, 0xe5676, 0x6a3ea, 0xe5674, - 0xb6163, 0xd46b7, 0x7cba6, 0xd46ba, 0x1d5d94, 0xb6164, 0x6a3f1, 0x7cba2, - 0x69451, 0x72dfa, 0xd46bb, 0x72df7, 0x74b94, 0x1cecbf, 0xe59fa, 0x16009b, - 0x6a3e4, 0x000e6, 0x00e94, 0x03876, 0x070ef, 0x0d52a, 0x16015, 0x16014, - 0x1abf9, 0x1cf17, 0x34a79, 0x34650, 0x3e705, 0x6a3d0, 0x58430, 0x74b9d, - 0x7be7e, 0x5b0be, 0x39773, 0x6a3de, 0x000fb, 0x00f7b, 0x03dd7, 0x07bd0, - 0x0e59c, 0x0f9cd, 0x1cf18, 0x1d2ff, 0x34a7a, 0x39429, 0x3500c, 0x72de0, - 0x69456, 0x7be7c, 0xd46b5, 0xd46b2, 0x6a3dd, 0x001a2, 0x0163b, 0x06913, - 0x0b016, 0x0fa42, 0x1a32d, 0x1cf06, 0x34a7c, 0x34a7d, 0xb6161, 0x35481, - 0x3e5fa, 0x7cba0, 0x7be7f, 0x7cba3, 0x7cba7, 0x5b0d3, 0x72de6, 0x6a3dc, - 0x001a9, 0x01ab4, 0x06a34, 0x0d46a, 0x16130, 0x1ef5f, 0x1f532, 0x1f536, - 0x3942e, 0x58436, 0x6a3db, 0x6945b, 0x001c9, 0x01ca0, 0x0728b, 0x0eed9, - 0x1f539, 0x1ca1d, 0x39765, 0x39766, 0x58439, 0x6945d, 0x39767, 0x001d3, - 0x01f2c, 0x07bfc, 0x16161, 0x34652, 0x3a5ed, 0x3548d, 0x58438, 0x6a3da, - 0x002c1, 0x02c5e, 0x0d335, 0x1ab1a, 0x2d874, 0x35006, 0x35484, 0x5b0cc, - 0x74b9a, 0x72df3, 0x6a3d6, 0x002da, 0x034b3, 0x0d5ae, 0x1caee, 0x2d871, - 0x357e3, 0x74b97, 0x72df9, 0x580ba, 0x5b0d4, 0x0034d, 0x0354e, 0x0f750, - 0x1cbc0, 0x3a5e7, 0x3a5e4, 0x00385, 0x03a58, 0x16c41, 0x2c5cf, 0x3e5e1, - 0x74b6c, 0xe5677, 0x6a3df, 0x00390, 0x03e50, 0x163c2, 0x2d876, 0x35482, - 0x5b0d6, 0x5843a, 0x0039f, 0x0585e, 0x1a583, 0x3500f, 0x74b93, 0x39771, - 0x003e4, 0x06912, 0x16c43, 0x357e1, 0x0058a, 0x0696f, 0x1f538, 0x5b0c9, - 0x6a3cf, 0x005b6, 0x06af8, 0x1f534, 0x58483, 0x6a3e0, 0x00695, 0x07d02, - 0x1cae8, 0x58485, 0x006a2, 0x0754a, 0x357ee, 0x3977b, 0x00748, 0x074b2, - 0x34a7b, 0x00729, 0x0b1e0, 0x34649, 0x3e5e3, 0x0073d, 0x0d2c4, 0x3e5e6, - 0x007bb, 0x0b099, 0x39762, 0x5b0ce, 0x6945f, 0x007d1, 0x0d5ab, 0x39779, - 0x007d3, 0x0d52f, 0x39763, 0x6945c, 0x00b1a, 0x0d2c5, 0x35489, 0x00d23, - 0x0eaed, 0x3e5f8, 0x00d32, 0x16016, 0x3e5fb, 0x00d41, 0x0e768, 0x3a5ed, - 0x00e1f, 0x16017, 0x58027, 0x00ead, 0x0fa07, 0x69455, 0x00e54, 0x1612b, - 0x00e55, 0x1a581, 0x00f78, 0x1a32b, 0x580bc, 0x6a3ee, 0x00f79, 0x1abfd, - 0x00f95, 0x1ab18, 0x6a3f0, 0x01637, 0x1aa4d, 0x0162d, 0x1f53c, 0x6a3f3, - 0x01a31, 0x1a810, 0x39769, 0x01a50, 0x1caef, 0x01a36, 0x1a32e, 0x01a67, - 0x1f38e, 0x01a85, 0x1ef59, 0x01aa6, 0x1ef83, 0x01d51, 0x2c012, 0x01d53, - 0x2d879, 0x01d5e, 0x35005, 0x01cba, 0x1cf04, 0x69453, 0x01d2d, 0x351ff, - 0x01f2d, 0x2d86f, 0x01f29, 0x35007, 0x02c22, 0x351fa, 0x02c03, 0x3a5ec, - 0x02c5f, 0x3a5eb, 0x02c58, 0x34a6b, 0x03469, 0x356be, 0x02c59, 0x34a6c, - 0x0346a, 0x3a5ea, 0x034bd, 0x034bf, 0x356bf, 0x0386a, 0x03ab9, 0x5843f, - 0x0386b, 0x3a5f5, 0x03a4b, 0x39421, 0x03aa4, 0x3a5e9, 0x03a5a, 0x03960, - 0x3977e, 0x03de9, 0x03958, 0x03df7, 0x039e1, 0x3e5e4, 0x0395f, 0x69458, - 0x03e91, 0x03df2, 0x39428, 0x058f2, 0x03e80, 0x6a3c3, 0x03e93, 0x694c0, - 0x058b8, 0x5b0ca, 0x0584f, 0x694c1, 0x058f1, 0x068d6, 0x06a10, 0x06ac3, - 0x06a32, 0x070d2, 0x06911, 0x074b1, 0x07494, 0x06ad4, 0x06ad6, 0x072b8, - 0x06afa, 0x074b3, 0x07540, 0x073ce, 0x0b005, 0x074b3, 0x07495, 0x074b9, - 0x0d336, 0x07bff, 0x07763, 0x073c8, 0x07d29, 0x0b622, 0x0d221, 0x0d181, - 0x0b1d1, 0x074b8, 0x0b1d0, 0x0d19b, 0x0d2c3, 0x0b172, 0x0d2dc, 0x0b623, - 0x0d5aa, 0x0d426, 0x0d182, 0x0e795, 0x0e1d1, 0x0d337, 0x0e96c, 0x0e5e4, - 0x0e514, 0x0eaee, 0x16000, 0x0e767, 0x0e1a1, 0x0e78f, 0x16004, 0x0f7c2, - 0x0e799, 0x0e5e7, 0x0e566, 0x0e769, 0x0f751, 0x0eede, 0x0fa06, 0x16005, - 0x0fa9f, 0x1a5e6, 0x0e766, 0x1636f, 0x0eedd, 0x0eec0, 0x1a309, 0x1ceca, - 0x163cd, 0x0f9cb, 0x0eedf, 0x1a582, 0x1612d, 0x0e5e5, 0x1abf8, 0x1a30c, - 0x1ca1f, 0x163cc, 0x1a35c, 0x1ca1e, 0x1aa51, 0x163ac, 0x1a84e, 0x1a53f, - 0x1cf16, 0x1d2fc, 0x1a5b3, 0x1ab19, 0x1a81f, 0x1d5c3, 0x16c3f, 0x1d5c1, - 0x1d2fc, 0x1f4aa, 0x1a812, 0x1f535, 0x1cf12, 0x1a817, 0x1617c, 0x1ab0b, - 0x1d2f8, 0x1ef82, 0x2d87a, 0x1d52f, 0x1f530, 0x1aa48, 0x35487, 0x1d2fd, - 0x1f4ad, 0x1cf11, 0x3461b, 0x35485, 0x1ca20, 0x1caed, 0x1cae6, 0x1abff, - 0x3464f, 0x34a6f, 0x1ef81, 0x3464b, 0x39d96, 0x1f383, 0x1f537, 0x1cf14, - 0x2c5ce, 0x3500e, 0x2c251, 0x1caec, 0x1f387, 0x34654, 0x357e4, 0x2d878, - 0x3500b, 0x35480, 0x3a5e8, 0x3548e, 0x34b64, 0x1f4a8, 0x35003, 0x3e5df, - 0x2d870, 0x357e6, 0x3e5f0, 0x1ef5a, 0x3a5ea, 0x1f388, 0x3e703, 0x2c24e, - 0x3a5e2, 0x351fd, 0x2c6dd, 0x3e704, 0x351fe, 0x2d875, 0x5b0c7, 0x3976a, - 0x3a5e6, 0x39423, 0x58480, 0x2c246, 0x3a5e3, 0x2d877, 0x3e5f1, 0x3abbe, - 0x58489, 0x3e5f9, 0x357e0, 0x3abbc, 0x5b0c6, 0x69167, 0x69165, 0x3e5e9, - 0x39422, 0x3976f, 0x3977d, 0x3e5de, 0x6a3c9, 0x58b98, 0x3a5f6, 0x3a5d0, - 0x58486, 0x6a3c1, 0x3e5fc, 0x5b0dc, 0x3548f, 0x3942d, 0x694c9, 0x58484, - 0x3a5e8, 0x74b9b, 0x74b96, 0x694d0, 0x58488, 0x3a5e4, 0x3942a, 0x72ec2, - 0x39776, 0x5b0d1, 0x5b0cf, 0x3a5d6, 0xe59fc, 0x5b0c8, 0x3e5e7, 0x7cbb7, - 0x70e87, 0x7cbab, 0x5b0c2, 0x694c3, 0x74a8e, 0x3e5f3, 0x6a3cd, 0x72dfe, - 0x73b2e, 0x72ec0, 0x694c5, 0x58437, 0x694c8, 0x72dff, 0x39435, 0x5843d, - 0x6a3d7, 0x72ec1, 0xd22c8, 0x694cf, 0xb6173, 0x3e5fe, 0x580bb, 0xe59f2, - 0xb616e, 0xb6175, 0x3a5da, 0x5b0bd, 0x694cc, 0x5843c, 0x694c7, 0x74b92, - 0x72ec3, 0x694c6, 0xb6170, 0x7cbac, 0xb1733, 0x7cba4, 0xb6167, 0x72de7, - 0x72de4, 0x6a3c0, 0x3e5ef, 0x162e65, 0x72de3, 0x72dfb, 0x6a35f, 0x6a3eb, -}; - -static const uint8_t coef2_huffbits[1336] = { - 11, 9, 2, 3, 4, 4, 5, 6, - 6, 7, 7, 8, 8, 8, 9, 9, - 9, 9, 10, 10, 10, 10, 11, 11, - 11, 11, 11, 11, 11, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 16, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 18, 17, 17, 17, 17, - 17, 17, 17, 18, 18, 17, 17, 18, - 17, 17, 18, 17, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 20, - 18, 18, 18, 19, 19, 18, 19, 18, - 19, 19, 18, 19, 19, 18, 19, 19, - 19, 19, 18, 19, 19, 19, 19, 19, - 19, 19, 20, 20, 20, 19, 19, 20, - 19, 20, 19, 19, 20, 19, 19, 20, - 20, 20, 20, 19, 20, 21, 19, 3, - 5, 7, 8, 9, 9, 10, 11, 11, - 12, 12, 12, 13, 13, 13, 13, 14, - 14, 14, 14, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 16, 16, - 15, 15, 15, 15, 16, 16, 16, 16, - 17, 16, 17, 17, 16, 17, 17, 17, - 17, 17, 17, 16, 17, 17, 17, 17, - 18, 17, 17, 18, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 19, - 19, 18, 18, 18, 18, 19, 18, 19, - 19, 19, 20, 19, 18, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 20, - 20, 19, 20, 19, 20, 19, 20, 19, - 19, 21, 20, 20, 19, 4, 7, 8, - 10, 11, 11, 12, 12, 13, 13, 14, - 14, 14, 14, 15, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 17, - 17, 17, 17, 17, 17, 17, 16, 16, - 16, 16, 17, 17, 17, 17, 18, 18, - 18, 17, 17, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 19, 18, 18, 18, - 19, 18, 19, 19, 19, 20, 20, 20, - 19, 19, 19, 19, 19, 19, 19, 21, - 21, 20, 19, 5, 8, 10, 11, 12, - 13, 13, 13, 14, 14, 15, 15, 15, - 15, 16, 16, 16, 16, 16, 17, 17, - 17, 17, 17, 17, 17, 17, 18, 17, - 18, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 19, 18, 19, 18, - 18, 18, 18, 18, 19, 18, 17, 17, - 18, 18, 19, 19, 19, 19, 18, 18, - 18, 19, 6, 9, 11, 12, 13, 13, - 14, 14, 14, 15, 15, 16, 16, 16, - 16, 16, 16, 17, 17, 17, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 17, 18, 18, 17, 18, 18, 18, - 18, 18, 18, 19, 19, 18, 18, 18, - 19, 19, 19, 20, 19, 19, 18, 19, - 19, 20, 21, 21, 19, 19, 18, 6, - 10, 12, 13, 14, 14, 14, 15, 15, - 15, 16, 16, 17, 17, 17, 17, 17, - 17, 17, 18, 18, 19, 18, 18, 18, - 19, 18, 18, 18, 19, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 19, 20, 20, 19, 19, 19, 19, 20, - 20, 19, 20, 19, 19, 19, 20, 20, - 20, 19, 19, 18, 19, 7, 10, 12, - 13, 14, 15, 15, 15, 16, 16, 17, - 17, 17, 17, 17, 17, 18, 18, 18, - 18, 19, 18, 19, 19, 19, 20, 19, - 18, 19, 19, 18, 18, 19, 19, 19, - 18, 19, 19, 20, 19, 18, 20, 21, - 20, 20, 19, 19, 21, 20, 21, 20, - 20, 20, 19, 19, 20, 20, 21, 20, - 19, 7, 11, 13, 14, 15, 15, 15, - 16, 16, 17, 17, 17, 17, 18, 18, - 18, 18, 18, 19, 20, 19, 19, 20, - 19, 19, 19, 19, 19, 19, 19, 19, - 18, 18, 19, 20, 19, 19, 19, 20, - 19, 19, 19, 20, 19, 20, 20, 21, - 20, 20, 20, 21, 22, 20, 19, 20, - 20, 21, 20, 21, 20, 19, 8, 11, - 13, 14, 15, 16, 16, 16, 17, 17, - 17, 18, 18, 18, 18, 18, 19, 18, - 19, 19, 19, 19, 21, 19, 19, 21, - 19, 20, 20, 20, 19, 18, 18, 8, - 12, 14, 15, 16, 16, 16, 16, 17, - 17, 17, 19, 18, 18, 19, 19, 20, - 19, 18, 20, 19, 20, 20, 19, 19, - 20, 20, 21, 21, 20, 19, 19, 19, - 19, 19, 19, 20, 21, 20, 19, 19, - 8, 12, 14, 15, 16, 16, 17, 17, - 17, 18, 18, 18, 19, 19, 19, 19, - 19, 19, 20, 21, 20, 21, 19, 21, - 20, 20, 20, 20, 21, 20, 19, 20, - 19, 20, 20, 20, 19, 22, 21, 21, - 19, 9, 12, 14, 15, 16, 17, 17, - 17, 18, 18, 18, 19, 19, 19, 19, - 20, 19, 19, 19, 9, 13, 15, 16, - 17, 17, 18, 18, 18, 19, 18, 20, - 19, 20, 20, 20, 19, 9, 13, 15, - 16, 17, 17, 18, 18, 18, 20, 18, - 19, 20, 20, 20, 20, 19, 20, 19, - 9, 13, 15, 16, 17, 18, 18, 18, - 19, 19, 19, 19, 10, 14, 16, 17, - 18, 18, 19, 19, 19, 19, 19, 10, - 14, 16, 17, 18, 18, 18, 19, 19, - 10, 14, 16, 17, 18, 18, 18, 19, - 19, 20, 19, 10, 14, 16, 18, 18, - 18, 19, 20, 19, 19, 10, 14, 17, - 18, 18, 18, 10, 15, 17, 18, 19, - 19, 21, 19, 11, 15, 17, 18, 18, - 19, 19, 11, 15, 17, 18, 19, 19, - 11, 15, 17, 18, 11, 15, 18, 19, - 19, 11, 15, 18, 19, 19, 11, 16, - 18, 19, 11, 15, 18, 19, 11, 16, - 18, 12, 16, 18, 19, 12, 16, 19, - 12, 16, 19, 19, 19, 12, 16, 19, - 12, 16, 19, 19, 12, 16, 18, 12, - 16, 19, 12, 17, 19, 12, 17, 19, - 12, 17, 19, 12, 17, 19, 13, 17, - 13, 17, 13, 17, 19, 19, 13, 17, - 13, 17, 19, 13, 17, 13, 18, 19, - 13, 17, 19, 13, 18, 13, 17, 13, - 18, 13, 18, 13, 18, 13, 18, 13, - 18, 13, 18, 14, 18, 19, 14, 18, - 14, 18, 14, 18, 14, 18, 14, 19, - 14, 19, 14, 18, 14, 18, 14, 18, - 14, 19, 14, 14, 18, 14, 14, 19, - 14, 18, 14, 19, 14, 19, 14, 15, - 19, 15, 15, 15, 15, 19, 15, 19, - 15, 15, 19, 15, 15, 19, 15, 19, - 15, 19, 15, 19, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 16, - 15, 15, 15, 16, 16, 16, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 17, 16, 16, 16, 17, - 17, 16, 17, 17, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 18, - 17, 17, 17, 17, 17, 17, 17, 17, - 18, 17, 17, 18, 17, 17, 17, 17, - 18, 18, 17, 17, 17, 17, 17, 17, - 17, 18, 17, 18, 18, 17, 17, 17, - 18, 18, 18, 17, 18, 17, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 17, - 18, 18, 18, 18, 19, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 19, - 18, 18, 19, 18, 18, 18, 19, 18, - 19, 18, 18, 19, 18, 18, 19, 19, - 19, 19, 19, 18, 19, 18, 19, 18, - 19, 19, 18, 18, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 18, 19, - 19, 19, 19, 19, 18, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 20, - 19, 19, 19, 19, 21, 19, 19, 20, - 19, 20, 19, 19, 19, 19, 19, 20, - 20, 20, 19, 19, 19, 20, 19, 19, - 19, 20, 20, 19, 20, 19, 19, 21, - 20, 20, 19, 19, 19, 19, 19, 19, - 20, 19, 20, 20, 20, 20, 20, 20, - 20, 19, 19, 21, 20, 20, 19, 19, -}; - -static const uint32_t coef3_huffcodes[1072] = { - 0x001b2, 0x00069, 0x00000, 0x00004, 0x00006, 0x0000e, 0x00014, 0x00019, - 0x00016, 0x0002b, 0x00030, 0x0003d, 0x0003c, 0x0005a, 0x0005f, 0x0006d, - 0x0007e, 0x0005f, 0x0007f, 0x000b6, 0x000bc, 0x000d8, 0x000f2, 0x000fe, - 0x000bc, 0x000fc, 0x00161, 0x0016e, 0x00174, 0x00176, 0x001a2, 0x001e3, - 0x001f3, 0x00174, 0x0017a, 0x001ea, 0x002a8, 0x002c4, 0x002e6, 0x00314, - 0x00346, 0x00367, 0x003e9, 0x002e5, 0x002ee, 0x003d6, 0x00555, 0x00554, - 0x00557, 0x005c3, 0x005d6, 0x006e0, 0x0062f, 0x006e2, 0x00799, 0x00789, - 0x007fa, 0x005ce, 0x007fe, 0x005ec, 0x007cc, 0x007af, 0x00aa7, 0x00b19, - 0x00b94, 0x00b85, 0x00b9f, 0x00c48, 0x00c45, 0x00dd8, 0x00c4c, 0x00c4b, - 0x00d99, 0x00d1f, 0x00dc2, 0x00f95, 0x00fa2, 0x00bb5, 0x00b9f, 0x00f5d, - 0x00bbf, 0x00f47, 0x0154a, 0x00fd5, 0x00f45, 0x00f7f, 0x0160d, 0x01889, - 0x01757, 0x01722, 0x018b3, 0x0172d, 0x01a39, 0x01a18, 0x01bb3, 0x01b30, - 0x01e63, 0x0173c, 0x01b35, 0x01723, 0x01e80, 0x01fee, 0x01761, 0x01ffc, - 0x01f7f, 0x02c7c, 0x01fa1, 0x0177b, 0x01755, 0x0175a, 0x01fa6, 0x02eab, - 0x0310a, 0x02c69, 0x03669, 0x03127, 0x03103, 0x02e43, 0x03662, 0x03165, - 0x03124, 0x0313b, 0x03111, 0x03668, 0x0343b, 0x03c52, 0x03efc, 0x02e6c, - 0x03fda, 0x03ef8, 0x02e7b, 0x03ee2, 0x03cc5, 0x03d72, 0x058c0, 0x03df8, - 0x02ea9, 0x03e7e, 0x0556d, 0x05c82, 0x03d71, 0x03e7b, 0x03c42, 0x058d7, - 0x03f4e, 0x06200, 0x03d70, 0x05cb2, 0x05c96, 0x05cb0, 0x03f45, 0x05cb1, - 0x02e6d, 0x03110, 0x02f68, 0x05c90, 0x07ca6, 0x07c88, 0x06204, 0x062c8, - 0x078a6, 0x07986, 0x079d5, 0x0b1ad, 0x07989, 0x0b079, 0x05cdd, 0x0aad4, - 0x05de8, 0x07dcd, 0x07987, 0x05d67, 0x05d99, 0x0b91d, 0x07cf1, 0x05d9b, - 0x079d7, 0x0b07b, 0x05c85, 0x05d9a, 0x07dcc, 0x07ebf, 0x07dce, 0x07dfb, - 0x07ec0, 0x07d1a, 0x07a07, 0x05c84, 0x0c471, 0x07cf2, 0x0baef, 0x0b9d2, - 0x05deb, 0x07bd6, 0x0b845, 0x05d98, 0x0b91a, 0x0bae8, 0x0c4e0, 0x0dc31, - 0x0f93d, 0x0bbce, 0x0d1d2, 0x0f7a9, 0x0d9b9, 0x0bbcb, 0x0b900, 0x0aad7, - 0x0babd, 0x0c4e1, 0x0f46f, 0x0c588, 0x0c58b, 0x160e6, 0x0bbcf, 0x0bac3, - 0x0f945, 0x0f7a3, 0x0d1c1, 0x0fb8e, 0x0f7a4, 0x0fb8c, 0x0f40c, 0x0c473, - 0x0fd72, 0x0bbcd, 0x0fffa, 0x0f940, 0x0bbc9, 0x0f7a8, 0x1a1ed, 0x0bbc5, - 0x1f26f, 0x163fd, 0x160c7, 0x1a1f5, 0x0f947, 0x163fc, 0x154b3, 0x0fff6, - 0x163f6, 0x160e9, 0x1a1f0, 0x0bab9, 0x0baba, 0x17086, 0x0b903, 0x0fd75, - 0x0f308, 0x176f3, 0x163ff, 0x0fd7d, 0x1bb78, 0x163fb, 0x188db, 0x1a1f7, - 0x154b2, 0x172fd, 0x163f4, 0x1bb73, 0x172ff, 0x0babc, 0x0f97d, 0x1a1f3, - 0x1bb6d, 0x1ffd5, 0x1a1f4, 0x1f272, 0x17380, 0x17382, 0x1ffe7, 0x0bac8, - 0x0bbc4, 0x188d3, 0x160e0, 0x0fd7b, 0x1725f, 0x172f5, 0x1bb79, 0x1fad9, - 0x1f269, 0x188d0, 0x0bac4, 0x0bac5, 0x31185, 0x188d2, 0x188cc, 0x31187, - 0x3e7fe, 0x188d1, 0x1bb6c, 0x1f268, 0x1fad2, 0x1ffd9, 0x1a1ea, 0x1bb68, - 0x1facb, 0x3fdb2, 0x1e81a, 0x188ce, 0x172fb, 0x1a1ef, 0x1face, 0x1bb70, - 0x0bac1, 0x1bb6b, 0x172f8, 0x1bb66, 0x1ffdf, 0x1bb6a, 0x1ffd7, 0x1f266, - 0x176f8, 0x37653, 0x1fa7e, 0x31182, 0x1fac8, 0x2c7e3, 0x370ee, 0x176ec, - 0x176e9, 0x2e4bc, 0x160c5, 0x3765a, 0x3ce9c, 0x17373, 0x176e8, 0x188d4, - 0x176f1, 0x176ef, 0x37659, 0x1bb7c, 0x1ffde, 0x176f2, 0x3118b, 0x2c7d4, - 0x37651, 0x5ce9f, 0x37650, 0x31191, 0x3f4f6, 0x3f4f5, 0x7a06c, 0x1fac1, - 0x5c97b, 0x2c7e0, 0x79d3a, 0x3e7fd, 0x2c7df, 0x3f4f0, 0x7a06d, 0x376c1, - 0x79d3b, 0x00004, 0x00014, 0x00059, 0x000ab, 0x000b8, 0x00177, 0x001f5, - 0x001f2, 0x00315, 0x003fc, 0x005bd, 0x0062d, 0x006e8, 0x007dd, 0x00b04, - 0x007cd, 0x00b1e, 0x00d1e, 0x00f15, 0x00f3b, 0x00f41, 0x01548, 0x018b0, - 0x0173b, 0x01884, 0x01a1c, 0x01bb4, 0x01f25, 0x017b5, 0x0176d, 0x01ef8, - 0x02e73, 0x03107, 0x03125, 0x03105, 0x02e49, 0x03ce8, 0x03ef9, 0x03e5e, - 0x02e72, 0x03471, 0x03fd9, 0x0623f, 0x078a0, 0x06867, 0x05cb3, 0x06272, - 0x068ec, 0x06e9a, 0x079d4, 0x06e98, 0x0b1aa, 0x06e1a, 0x07985, 0x068ee, - 0x06e9b, 0x05c88, 0x0b1ac, 0x07dfa, 0x05d65, 0x07cf0, 0x07cbf, 0x0c475, - 0x160eb, 0x1bb7e, 0x0f7a6, 0x1fedd, 0x160e3, 0x0fffb, 0x0fb8d, 0x0fff9, - 0x0d1c0, 0x0c58c, 0x1a1e9, 0x0bab8, 0x0f5cf, 0x0fff5, 0x376c5, 0x1a1ec, - 0x160ed, 0x1fede, 0x1fac9, 0x1a1eb, 0x1f224, 0x176ee, 0x0fd79, 0x17080, - 0x17387, 0x1bb7a, 0x1ffe9, 0x176f7, 0x17385, 0x17781, 0x2c7d5, 0x17785, - 0x1ffe3, 0x163f5, 0x1fac2, 0x3e7f9, 0x3118d, 0x3fdb1, 0x1ffe2, 0x1f226, - 0x3118a, 0x2c7d9, 0x31190, 0x3118c, 0x3f4f3, 0x1bb7f, 0x1bb72, 0x31184, - 0xb92f4, 0x3e7fb, 0x6e1d9, 0x1faca, 0x62300, 0x3fdb8, 0x3d037, 0x3e7fc, - 0x62301, 0x3f4f2, 0x1f26a, 0x0000e, 0x00063, 0x000f8, 0x001ee, 0x00377, - 0x003f7, 0x006e3, 0x005cc, 0x00b05, 0x00dd2, 0x00fd4, 0x0172e, 0x0172a, - 0x01e23, 0x01f2d, 0x01763, 0x01769, 0x0176c, 0x02e75, 0x03104, 0x02ec1, - 0x03e58, 0x0583f, 0x03f62, 0x03f44, 0x058c5, 0x0623c, 0x05cf4, 0x07bd7, - 0x05d9d, 0x0aad2, 0x05d66, 0x0b1a9, 0x0b078, 0x07cfe, 0x0b918, 0x0c46f, - 0x0b919, 0x0b847, 0x06e1b, 0x0b84b, 0x0aad8, 0x0fd74, 0x172f4, 0x17081, - 0x0f97c, 0x1f273, 0x0f7a0, 0x0fd7c, 0x172f7, 0x0fd7a, 0x1bb77, 0x172fe, - 0x1f270, 0x0fd73, 0x1bb7b, 0x1a1bc, 0x1bb7d, 0x0bbc3, 0x172f6, 0x0baeb, - 0x0fb8f, 0x3f4f4, 0x3fdb4, 0x376c8, 0x3e7fa, 0x1ffd0, 0x62303, 0xb92f5, - 0x1f261, 0x31189, 0x3fdb5, 0x2c7db, 0x376c9, 0x1fad6, 0x1fad1, 0x00015, - 0x000f0, 0x002e0, 0x0058e, 0x005d7, 0x00c4d, 0x00fa1, 0x00bdb, 0x01756, - 0x01f70, 0x02c19, 0x0313c, 0x0370f, 0x03cc0, 0x02ea8, 0x058c6, 0x058c7, - 0x02eb7, 0x058d0, 0x07d18, 0x0aa58, 0x0b848, 0x05d9e, 0x05d6c, 0x0b84c, - 0x0c589, 0x0b901, 0x163f8, 0x0bac9, 0x0b9c5, 0x0f93c, 0x188d8, 0x0bbc7, - 0x160ec, 0x0fd6f, 0x188d9, 0x160ea, 0x0f7a7, 0x0f944, 0x0baab, 0x0dc3a, - 0x188cf, 0x176fb, 0x2c7d8, 0x2c7d7, 0x1bb75, 0x5ce9e, 0x62302, 0x370ed, - 0x176f4, 0x1ffd1, 0x370ef, 0x3f4f8, 0x376c7, 0x1ffe1, 0x376c6, 0x176ff, - 0x6e1d8, 0x176f6, 0x17087, 0x0f5cd, 0x00035, 0x001a0, 0x0058b, 0x00aac, - 0x00b9a, 0x0175f, 0x01e22, 0x01e8c, 0x01fb2, 0x0310b, 0x058d1, 0x0552e, - 0x05c27, 0x0686e, 0x07ca7, 0x0c474, 0x0dc33, 0x07bf2, 0x05de9, 0x07a35, - 0x0baaa, 0x0b9eb, 0x0fb95, 0x0b9b8, 0x17381, 0x1f262, 0x188cd, 0x17088, - 0x172fa, 0x0f7a2, 0x1fad3, 0x0bac0, 0x3765c, 0x1fedf, 0x1f225, 0x1fad4, - 0x2c7da, 0x5ce9d, 0x3e7f8, 0x1e203, 0x188d7, 0x00054, 0x002c0, 0x007a1, - 0x00f78, 0x01b36, 0x01fa3, 0x0313a, 0x03436, 0x0343a, 0x07d1d, 0x07bd8, - 0x05cdf, 0x0b846, 0x0b189, 0x0d9b8, 0x0fff8, 0x0d9be, 0x0c58a, 0x05dea, - 0x0d1d3, 0x160e4, 0x1f26b, 0x188da, 0x1e202, 0x2c7d2, 0x163fe, 0x31193, - 0x17782, 0x376c2, 0x2c7d1, 0x3fdb0, 0x3765d, 0x2c7d0, 0x1fad0, 0x1e201, - 0x188dd, 0x2c7e2, 0x37657, 0x37655, 0x376c4, 0x376c0, 0x176ea, 0x0006f, - 0x003cf, 0x00dd5, 0x01f23, 0x02c61, 0x02ed0, 0x05d54, 0x0552d, 0x07883, - 0x0b1a8, 0x0b91c, 0x0babf, 0x0b902, 0x0f7aa, 0x0f7a5, 0x1a1e8, 0x1ffd6, - 0x0babe, 0x1a1bf, 0x163f3, 0x1ffd8, 0x1fad7, 0x1f275, 0x1ffdc, 0x0007d, - 0x005bc, 0x01549, 0x02a99, 0x03def, 0x06273, 0x079d6, 0x07d1b, 0x0aad3, - 0x0d0fc, 0x2c7dd, 0x188d6, 0x0bac2, 0x2c7e1, 0x1bb76, 0x1a1bd, 0x31186, - 0x0fd78, 0x1a1be, 0x31183, 0x3fdb6, 0x3f4f1, 0x37652, 0x1fad5, 0x3f4f9, - 0x3e7ff, 0x5ce9c, 0x3765b, 0x31188, 0x17372, 0x000bd, 0x0078b, 0x01f21, - 0x03c43, 0x03ded, 0x0aad6, 0x07ec1, 0x0f942, 0x05c86, 0x17089, 0x0babb, - 0x1ffe8, 0x2c7de, 0x1f26e, 0x1fac4, 0x3f4f7, 0x37656, 0x1fa7d, 0x376c3, - 0x3fdb3, 0x3118f, 0x1fac6, 0x000f8, 0x007ed, 0x01efd, 0x03e7a, 0x05c91, - 0x0aad9, 0x0baec, 0x0dc32, 0x0f46e, 0x1e200, 0x176fa, 0x3765e, 0x3fdb7, - 0x2c7d6, 0x3fdb9, 0x37654, 0x37658, 0x3118e, 0x1ffdb, 0x000f6, 0x00c43, - 0x03106, 0x068ef, 0x0b84d, 0x0b188, 0x0bbcc, 0x1f264, 0x1bb69, 0x17386, - 0x1fac0, 0x00171, 0x00f39, 0x03e41, 0x068ed, 0x0d9bc, 0x0f7a1, 0x1bb67, - 0x1ffdd, 0x176f9, 0x001b9, 0x00f7d, 0x03f63, 0x0d0fd, 0x0b9ea, 0x188dc, - 0x1fac3, 0x1a1f2, 0x31192, 0x1ffe4, 0x001f6, 0x01754, 0x06865, 0x0f309, - 0x160e5, 0x176f5, 0x3765f, 0x1facc, 0x001e9, 0x01a1a, 0x06201, 0x0f105, - 0x176f0, 0x002df, 0x01756, 0x05d6d, 0x163fa, 0x176ed, 0x00342, 0x02e40, - 0x0d0ff, 0x17082, 0x003cd, 0x02a98, 0x0fffc, 0x2c7dc, 0x1fa7f, 0x003fe, - 0x03764, 0x0fffd, 0x176fc, 0x1fac5, 0x002f7, 0x02ed1, 0x0fb97, 0x0058a, - 0x02edc, 0x0bbc8, 0x005d4, 0x0623d, 0x160e8, 0x0062e, 0x05830, 0x163f9, - 0x006eb, 0x06205, 0x1f274, 0x007de, 0x062c9, 0x1f265, 0x005c9, 0x05cde, - 0x1ffd3, 0x005d4, 0x07988, 0x007ce, 0x0b849, 0x00b1b, 0x05c89, 0x1fac7, - 0x00b93, 0x05c83, 0x00b9e, 0x0f14f, 0x00c4a, 0x0b9c7, 0x00dd4, 0x0c470, - 0x1f271, 0x00f38, 0x0fb96, 0x176eb, 0x00fa0, 0x163f7, 0x00bb2, 0x0b91b, - 0x00bbe, 0x0f102, 0x00f44, 0x0f946, 0x1facd, 0x00f79, 0x0d9bd, 0x0154d, - 0x0bbc6, 0x00fd2, 0x160e7, 0x0172b, 0x188cb, 0x0175e, 0x0fd76, 0x0175c, - 0x1bb71, 0x0189f, 0x1a1ee, 0x01f24, 0x1a1f6, 0x01ba7, 0x0bbca, 0x01f7d, - 0x0ffff, 0x01f2e, 0x1bb65, 0x01bb5, 0x172f9, 0x01fef, 0x1f26c, 0x01f3e, - 0x0fd77, 0x01762, 0x1bb6e, 0x01ef9, 0x172fc, 0x01fa0, 0x02ab7, 0x02e4a, - 0x1f267, 0x01fb3, 0x1ffda, 0x02e42, 0x03101, 0x17780, 0x0313d, 0x03475, - 0x17784, 0x03126, 0x1facf, 0x03c51, 0x17783, 0x03e40, 0x1ffe5, 0x03663, - 0x1ffe0, 0x03e8f, 0x1f26d, 0x0343c, 0x03cc1, 0x176fd, 0x03e45, 0x02ec0, - 0x03f61, 0x03dee, 0x03fd8, 0x0583e, 0x02e45, 0x03e59, 0x03d02, 0x05ce8, - 0x05568, 0x176fe, 0x02f69, 0x1fad8, 0x058c1, 0x05c83, 0x1ffe6, 0x06271, - 0x06e1c, 0x062c7, 0x068e1, 0x0552f, 0x06864, 0x06866, 0x06e99, 0x05cbc, - 0x07ca5, 0x078a1, 0x05c82, 0x07dcf, 0x0623b, 0x0623e, 0x068e8, 0x07a36, - 0x05d9c, 0x0b077, 0x07cf3, 0x07a34, 0x07ca4, 0x07d19, 0x079d2, 0x07d1c, - 0x07bd9, 0x0b84a, 0x0fb94, 0x0aad5, 0x0dc30, 0x07bf3, 0x0baee, 0x0b07a, - 0x0c472, 0x0b91e, 0x0d9ba, 0x05d9f, 0x0d0fe, 0x0b9c6, 0x05c87, 0x0f14e, - 0x0baed, 0x0b92e, 0x0f103, 0x0b9c4, 0x0fb91, 0x0d9bb, 0x0b1ab, 0x0c58d, - 0x0fffe, 0x0f93b, 0x0f941, 0x0baea, 0x0b91f, 0x0f5cc, 0x0d9bf, 0x0f943, - 0x0f104, 0x1f260, 0x0fb92, 0x0f93f, 0x0f3a6, 0x0bac7, 0x0f7ab, 0x0bac6, - 0x17383, 0x0fd6d, 0x0bae9, 0x0fd6e, 0x1e74f, 0x188ca, 0x1f227, 0x0fb93, - 0x0fb90, 0x0fff7, 0x17085, 0x17083, 0x160e1, 0x17084, 0x0f93e, 0x160e2, - 0x160c6, 0x1a1f1, 0x1bb6f, 0x17384, 0x0fd70, 0x1f263, 0x188d5, 0x173a6, - 0x0f5ce, 0x163f2, 0x0fd71, 0x1ffd2, 0x160c4, 0x1ffd4, 0x2c7d3, 0x1bb74, -}; - -static const uint8_t coef3_huffbits[1072] = { - 9, 7, 2, 3, 4, 4, 5, 5, - 6, 6, 6, 6, 7, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 12, 11, 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, 14, 13, 14, 14, 13, 14, 13, - 13, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 15, - 14, 14, 15, 14, 14, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 14, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 16, 15, 16, 16, 16, - 16, 15, 15, 16, 16, 16, 16, 16, - 15, 16, 16, 16, 15, 16, 15, 15, - 16, 15, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 17, 16, 17, 16, 17, 17, 16, - 17, 16, 17, 16, 16, 17, 17, 17, - 16, 17, 16, 16, 17, 16, 17, 16, - 17, 17, 16, 16, 17, 17, 17, 17, - 17, 17, 17, 17, 16, 17, 17, 16, - 17, 17, 17, 17, 17, 17, 17, 17, - 16, 18, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 16, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 18, - 17, 17, 17, 17, 18, 17, 17, 18, - 19, 17, 17, 17, 18, 17, 17, 17, - 18, 18, 18, 17, 17, 17, 18, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 17, 18, 18, 18, 18, 17, - 18, 18, 18, 17, 17, 18, 18, 18, - 18, 19, 18, 18, 19, 19, 20, 18, - 19, 18, 19, 19, 18, 19, 20, 18, - 19, 4, 6, 7, 8, 9, 9, 9, - 10, 10, 10, 11, 11, 11, 11, 12, - 12, 12, 12, 12, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 16, 15, 15, 15, - 15, 16, 16, 15, 16, 16, 15, 16, - 17, 17, 17, 17, 17, 16, 16, 16, - 16, 16, 17, 17, 17, 16, 18, 17, - 17, 17, 18, 17, 17, 18, 17, 17, - 17, 17, 17, 18, 17, 18, 18, 18, - 17, 17, 18, 19, 18, 18, 17, 17, - 18, 18, 18, 18, 19, 17, 17, 18, - 20, 19, 19, 18, 19, 18, 19, 19, - 19, 19, 17, 5, 7, 9, 10, 10, - 11, 11, 12, 12, 12, 13, 13, 13, - 13, 13, 14, 14, 14, 14, 14, 15, - 14, 15, 15, 15, 15, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 15, 16, 16, 17, 17, 17, - 16, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 16, - 16, 19, 18, 18, 19, 17, 19, 20, - 17, 18, 18, 18, 18, 18, 18, 6, - 8, 10, 11, 12, 12, 12, 13, 13, - 13, 14, 14, 14, 14, 15, 15, 15, - 15, 15, 15, 16, 16, 16, 16, 16, - 16, 17, 17, 17, 16, 16, 17, 17, - 17, 17, 17, 17, 17, 16, 16, 16, - 17, 18, 18, 18, 17, 19, 19, 18, - 18, 17, 18, 19, 18, 17, 18, 18, - 19, 18, 17, 17, 6, 9, 11, 12, - 13, 13, 13, 14, 14, 14, 15, 15, - 15, 15, 15, 16, 16, 16, 16, 16, - 16, 17, 16, 17, 17, 17, 17, 17, - 17, 17, 18, 17, 18, 17, 17, 18, - 18, 19, 19, 17, 17, 7, 10, 12, - 13, 13, 14, 14, 14, 14, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 17, 17, 17, 17, 18, 17, 18, - 18, 18, 18, 18, 18, 18, 18, 17, - 17, 18, 18, 18, 18, 18, 18, 7, - 10, 12, 13, 14, 15, 15, 15, 15, - 16, 16, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 18, 17, 17, 8, - 11, 13, 14, 15, 15, 15, 15, 16, - 16, 18, 17, 17, 18, 17, 17, 18, - 17, 17, 18, 18, 19, 18, 18, 19, - 19, 19, 18, 18, 18, 8, 11, 13, - 14, 15, 16, 16, 16, 16, 17, 17, - 17, 18, 17, 18, 19, 18, 18, 18, - 18, 18, 18, 8, 12, 14, 15, 15, - 16, 16, 16, 17, 17, 18, 18, 18, - 18, 18, 18, 18, 18, 17, 9, 12, - 14, 15, 16, 16, 17, 17, 17, 17, - 18, 9, 12, 14, 15, 16, 17, 17, - 17, 18, 9, 13, 15, 16, 17, 17, - 18, 17, 18, 17, 9, 13, 15, 16, - 17, 18, 18, 18, 10, 13, 15, 16, - 18, 10, 14, 16, 17, 18, 10, 14, - 16, 17, 10, 14, 16, 18, 18, 10, - 14, 16, 18, 18, 11, 15, 16, 11, - 15, 17, 11, 15, 17, 11, 15, 17, - 11, 15, 17, 11, 15, 17, 12, 16, - 17, 12, 15, 12, 16, 12, 16, 18, - 12, 16, 12, 16, 12, 16, 12, 16, - 17, 12, 16, 18, 12, 17, 13, 16, - 13, 16, 13, 16, 18, 13, 16, 13, - 17, 13, 17, 13, 17, 13, 17, 13, - 17, 13, 17, 13, 17, 13, 17, 13, - 16, 13, 17, 13, 17, 13, 17, 14, - 17, 14, 17, 14, 17, 14, 14, 14, - 17, 14, 17, 14, 14, 18, 14, 14, - 18, 14, 18, 14, 18, 14, 17, 14, - 17, 14, 17, 14, 14, 18, 14, 15, - 15, 15, 14, 15, 15, 14, 15, 15, - 15, 18, 15, 18, 15, 15, 17, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 16, 15, 15, 15, 15, 16, - 16, 16, 16, 16, 15, 15, 15, 15, - 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, 17, 16, 16, - 16, 17, 16, 16, 16, 17, 17, 17, - 17, 17, 16, 17, 17, 17, 17, 16, - 16, 16, 17, 17, 17, 17, 16, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 18, 17, -}; - -static const uint32_t coef4_huffcodes[476] = { - 0x00f01, 0x0001e, 0x00000, 0x00004, 0x00006, 0x0000d, 0x0000a, 0x00017, - 0x0001d, 0x00017, 0x0002c, 0x00031, 0x00039, 0x0003e, 0x00039, 0x0005a, - 0x00066, 0x00070, 0x0007b, 0x00070, 0x00077, 0x000af, 0x000c9, 0x000f2, - 0x000f4, 0x000b2, 0x000e3, 0x0015b, 0x0015d, 0x00181, 0x0019d, 0x001e3, - 0x001c5, 0x002b5, 0x002db, 0x00338, 0x003c3, 0x003cc, 0x003f0, 0x002cd, - 0x003fa, 0x003a1, 0x005b4, 0x00657, 0x007ab, 0x0074d, 0x0074c, 0x00ac1, - 0x00ac5, 0x0076b, 0x00ca8, 0x00f04, 0x00f00, 0x00fe3, 0x00f3c, 0x00f10, - 0x00f39, 0x00fe6, 0x00e26, 0x00e90, 0x016c5, 0x01827, 0x01954, 0x015c5, - 0x01958, 0x01f8a, 0x01c4a, 0x02b0f, 0x02b41, 0x02b0e, 0x033c6, 0x03050, - 0x01c4f, 0x02d88, 0x0305c, 0x03c18, 0x02b4f, 0x02cc2, 0x03a47, 0x05680, - 0x0569d, 0x06442, 0x06443, 0x06446, 0x0656e, 0x06444, 0x07120, 0x0748a, - 0x0c1ba, 0x07e22, 0x07aa6, 0x07f25, 0x07aa7, 0x07e20, 0x0c11b, 0x0c118, - 0x07aa5, 0x0ad0a, 0x0f389, 0x19ebb, 0x0caad, 0x0fe42, 0x0fe40, 0x16c34, - 0x2b4e5, 0x33d65, 0x16c30, 0x1e7ae, 0x1e25c, 0x18370, 0x1e703, 0x19eba, - 0x16c37, 0x0e234, 0x16c6e, 0x00004, 0x0002a, 0x00061, 0x00075, 0x000cb, - 0x000ff, 0x00190, 0x001eb, 0x001d1, 0x002b9, 0x00307, 0x00339, 0x0033f, - 0x003fb, 0x003b4, 0x0060c, 0x00679, 0x00645, 0x0067d, 0x0078a, 0x007e3, - 0x00749, 0x00ac4, 0x00ad2, 0x00ae3, 0x00c10, 0x00c16, 0x00ad1, 0x00cf4, - 0x00fe2, 0x01586, 0x00e9d, 0x019f1, 0x01664, 0x01e26, 0x01d38, 0x02b4d, - 0x033c5, 0x01fc2, 0x01fc3, 0x01d28, 0x03c1d, 0x0598e, 0x0f094, 0x07aa4, - 0x0ad38, 0x0ac0c, 0x0c11a, 0x079ea, 0x0c881, 0x0fe44, 0x0b635, 0x0ac0d, - 0x0b61e, 0x05987, 0x07121, 0x0f382, 0x0f387, 0x0e237, 0x0fe47, 0x0f383, - 0x0f091, 0x0f385, 0x0e233, 0x182ee, 0x19eb8, 0x1663e, 0x0f093, 0x00014, - 0x00058, 0x00159, 0x00167, 0x00300, 0x003d4, 0x005b5, 0x0079d, 0x0076a, - 0x00b67, 0x00b60, 0x00f05, 0x00cf0, 0x00f17, 0x00e95, 0x01822, 0x01913, - 0x016c2, 0x0182f, 0x01959, 0x01fcb, 0x01e27, 0x01c40, 0x033c7, 0x01e7b, - 0x01c49, 0x02d89, 0x01e23, 0x01660, 0x03f12, 0x02cc6, 0x033e1, 0x05b34, - 0x0609a, 0x06569, 0x07488, 0x07e21, 0x0cf5f, 0x0712c, 0x0389d, 0x067cf, - 0x07f28, 0x1663f, 0x33d67, 0x1663d, 0x1e25d, 0x3c1ab, 0x15c44, 0x16c36, - 0x0001f, 0x000ec, 0x00323, 0x005b2, 0x0079f, 0x00ac2, 0x00f16, 0x00e9e, - 0x01956, 0x01e0f, 0x019ea, 0x01666, 0x02b89, 0x02b02, 0x02d8c, 0x03c1b, - 0x03c19, 0x032b5, 0x03f9c, 0x02ccf, 0x03897, 0x05b35, 0x0ad02, 0x07f29, - 0x06441, 0x03884, 0x07888, 0x0784e, 0x06568, 0x0c1bb, 0x05986, 0x067cc, - 0x0fe49, 0x0fe48, 0x0c1bc, 0x0fe41, 0x18371, 0x1663c, 0x0e231, 0x0711e, - 0x0ad09, 0x0f092, 0x0002d, 0x001db, 0x00781, 0x00c1a, 0x00f55, 0x01580, - 0x01ea8, 0x02d9b, 0x032af, 0x03f16, 0x03c1c, 0x07834, 0x03c45, 0x0389c, - 0x067ce, 0x06445, 0x0c1b9, 0x07889, 0x07f3a, 0x0784f, 0x07f2b, 0x0ad0b, - 0x0f090, 0x0c11d, 0x0e94e, 0x0711f, 0x0e9f1, 0x0f38e, 0x079e9, 0x0ad03, - 0x0f09b, 0x0caae, 0x0fe46, 0x2b4e6, 0x0e9f0, 0x19eb6, 0x67ac1, 0x67ac0, - 0x33d66, 0x0f388, 0x00071, 0x003a0, 0x00ca9, 0x01829, 0x01d39, 0x02b43, - 0x02cc4, 0x06554, 0x0f09a, 0x0b61f, 0x067cd, 0x0711c, 0x0b636, 0x07f2a, - 0x0b634, 0x0c11f, 0x0cf5e, 0x0b61d, 0x0f06b, 0x0caab, 0x0c1be, 0x0e94c, - 0x0f099, 0x182ed, 0x0e94f, 0x0c119, 0x0e232, 0x2b4e4, 0x0f38a, 0x19eb4, - 0x1e25f, 0x0e94d, 0x000b7, 0x00785, 0x016cc, 0x03051, 0x033c4, 0x0656f, - 0x03891, 0x0711d, 0x0caaf, 0x0f097, 0x07489, 0x0f098, 0x0c880, 0x0caaa, - 0x0f386, 0x19eb7, 0x16c6f, 0x0f384, 0x182e8, 0x182e9, 0x0e230, 0x1e700, - 0x33d62, 0x33d63, 0x33d64, 0x16c33, 0x0e216, 0x000fd, 0x00c15, 0x01665, - 0x03c4a, 0x07f3b, 0x07896, 0x0c11c, 0x0e215, 0x16c32, 0x0f38b, 0x0f38d, - 0x182ea, 0x1e701, 0x712df, 0x15c46, 0x00194, 0x00fe0, 0x03f13, 0x0748b, - 0x0f096, 0x0cf80, 0x1e25e, 0xe25bd, 0x33d61, 0x16c31, 0x001f9, 0x01912, - 0x05710, 0x0f3d0, 0x0c1bf, 0x00301, 0x01e24, 0x0ad08, 0x003cd, 0x01c41, - 0x0c1bd, 0x00563, 0x03a52, 0x0f3d1, 0x00570, 0x02cce, 0x0e217, 0x0067b, - 0x0655d, 0x0074b, 0x06447, 0x00c12, 0x074fb, 0x00f08, 0x0b61c, 0x00e22, - 0x0fe43, 0x016c7, 0x01836, 0x019f2, 0x01c43, 0x01d3f, 0x01fcf, 0x02b4c, - 0x0304c, 0x032b6, 0x03a46, 0x05607, 0x03f17, 0x02cc5, 0x0609b, 0x0655c, - 0x07e23, 0x067c1, 0x07f26, 0x07f27, 0x0f095, 0x0e9f3, 0x0cf81, 0x0c11e, - 0x0caac, 0x0f38f, 0x0e9f2, 0x074fa, 0x0e236, 0x0fe45, 0x1c428, 0x0e235, - 0x182ef, 0x19eb5, 0x0f3d6, 0x182ec, 0x16c35, 0x0f38c, 0x2b4e7, 0x15c47, - 0xe25bc, 0x1e702, 0x1c4b6, 0x0e25a, 0x3c1aa, 0x15c45, 0x1c429, 0x19eb9, - 0x1e7af, 0x182eb, 0x1e0d4, 0x3896e, -}; - -static const uint8_t coef4_huffbits[476] = { - 12, 6, 2, 3, 4, 4, 5, 5, - 5, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 8, 8, 8, 8, 8, - 8, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 11, - 10, 11, 11, 11, 11, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 13, 13, 13, 13, 13, 13, - 13, 13, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 16, 16, - 16, 15, 15, 15, 15, 15, 16, 16, - 15, 16, 16, 17, 16, 16, 16, 17, - 18, 18, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 4, 6, 7, 8, 8, - 8, 9, 9, 10, 10, 10, 10, 10, - 10, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 13, 13, 13, 14, 13, 14, 14, - 14, 13, 13, 14, 14, 16, 16, 15, - 16, 16, 16, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 16, 16, - 16, 16, 17, 17, 17, 18, 16, 5, - 8, 9, 10, 10, 10, 11, 11, 12, - 12, 12, 12, 12, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 14, 14, 13, - 14, 14, 13, 14, 14, 15, 14, 15, - 15, 15, 16, 15, 16, 16, 15, 15, - 15, 18, 18, 18, 17, 18, 17, 17, - 6, 9, 10, 11, 11, 12, 12, 13, - 13, 13, 13, 14, 14, 14, 14, 14, - 14, 14, 14, 15, 15, 15, 16, 15, - 15, 15, 15, 15, 15, 16, 16, 15, - 16, 16, 16, 16, 17, 18, 17, 16, - 16, 16, 7, 10, 11, 12, 12, 13, - 13, 14, 14, 14, 14, 15, 14, 15, - 15, 15, 16, 15, 15, 15, 15, 16, - 16, 16, 17, 16, 17, 16, 15, 16, - 16, 16, 16, 18, 17, 17, 19, 19, - 18, 16, 7, 11, 12, 13, 14, 14, - 15, 15, 16, 16, 15, 16, 16, 15, - 16, 16, 16, 16, 16, 16, 16, 17, - 16, 17, 17, 16, 17, 18, 16, 17, - 17, 17, 8, 11, 13, 14, 14, 15, - 15, 16, 16, 16, 16, 16, 16, 16, - 16, 17, 17, 16, 17, 17, 17, 17, - 18, 18, 18, 17, 17, 8, 12, 14, - 14, 15, 15, 16, 17, 17, 16, 16, - 17, 17, 20, 17, 9, 12, 14, 16, - 16, 16, 17, 21, 18, 17, 9, 13, - 15, 16, 16, 10, 13, 16, 10, 14, - 16, 11, 15, 16, 11, 15, 17, 11, - 15, 12, 15, 12, 16, 12, 16, 13, - 16, 13, 13, 13, 14, 14, 13, 14, - 14, 14, 15, 15, 14, 15, 15, 15, - 15, 15, 15, 15, 16, 17, 16, 16, - 16, 16, 17, 16, 17, 16, 18, 17, - 17, 17, 16, 17, 17, 16, 18, 17, - 21, 17, 18, 17, 18, 17, 18, 17, - 17, 17, 17, 19, -}; - -static const uint32_t coef5_huffcodes[435] = { - 0x00347, 0x0000b, 0x00001, 0x00001, 0x0000c, 0x00004, 0x00010, 0x00015, - 0x0001f, 0x0000b, 0x00023, 0x00026, 0x00029, 0x00035, 0x00037, 0x00001, - 0x00015, 0x0001a, 0x0001d, 0x0001c, 0x0001e, 0x0004e, 0x00049, 0x00051, - 0x00078, 0x00004, 0x00000, 0x00008, 0x0000d, 0x0007b, 0x00005, 0x00032, - 0x00095, 0x00091, 0x00096, 0x000a1, 0x000d9, 0x00003, 0x00019, 0x00061, - 0x00066, 0x00060, 0x00017, 0x0000e, 0x00063, 0x001a0, 0x001b7, 0x001e6, - 0x001e7, 0x001b6, 0x00018, 0x001e8, 0x00038, 0x00031, 0x00005, 0x0003d, - 0x00027, 0x001ea, 0x0001a, 0x000c5, 0x000f9, 0x000ff, 0x000db, 0x00250, - 0x000fc, 0x0025c, 0x00008, 0x00075, 0x003d7, 0x003d3, 0x001b0, 0x0007c, - 0x003ca, 0x00036, 0x00189, 0x004a6, 0x004a2, 0x004fb, 0x000c0, 0x0007f, - 0x0009a, 0x00311, 0x0006e, 0x0009b, 0x0068c, 0x006c0, 0x00484, 0x00012, - 0x000c3, 0x0094f, 0x00979, 0x009f9, 0x00d09, 0x00da6, 0x00da8, 0x00901, - 0x000c1, 0x00373, 0x00d08, 0x009fa, 0x00d8b, 0x00d85, 0x00d86, 0x000df, - 0x006e2, 0x000ce, 0x00f24, 0x009fe, 0x001f7, 0x007c1, 0x000cf, 0x009fc, - 0x009ff, 0x00d89, 0x00da9, 0x009fd, 0x001f8, 0x01a36, 0x0128c, 0x0129d, - 0x01a37, 0x00196, 0x003ea, 0x00f8b, 0x00d93, 0x01e45, 0x01e58, 0x01e4b, - 0x01e59, 0x013f1, 0x00309, 0x00265, 0x00308, 0x0243a, 0x027e1, 0x00f89, - 0x00324, 0x03cbc, 0x03c86, 0x03695, 0x0243c, 0x0243b, 0x0243e, 0x01e4a, - 0x003a5, 0x03468, 0x03428, 0x03c84, 0x027e0, 0x025e2, 0x01880, 0x00197, - 0x00325, 0x03cb7, 0x0791e, 0x007ec, 0x06c75, 0x004c8, 0x04bc7, 0x004c6, - 0x00983, 0x0481e, 0x01b53, 0x0251b, 0x01b58, 0x00984, 0x04fa8, 0x03cbb, - 0x00f8a, 0x00322, 0x0346a, 0x0243d, 0x00326, 0x03469, 0x0481f, 0x0481d, - 0x00746, 0x09032, 0x01b50, 0x01d13, 0x0d8e4, 0x0481b, 0x06c74, 0x0796b, - 0x07969, 0x00985, 0x0d8e3, 0x00986, 0x00fa2, 0x01301, 0x06c7c, 0x00987, - 0x03cb8, 0x0f4af, 0x00e88, 0x1b1c0, 0x00fce, 0x033eb, 0x03f6a, 0x03f69, - 0x00fcf, 0x0791f, 0x004c9, 0x04871, 0x00fcd, 0x00982, 0x00fcc, 0x00fa3, - 0x01d12, 0x0796c, 0x01b47, 0x00321, 0x0796a, 0x0d8e2, 0x04872, 0x04873, - 0x0000e, 0x00014, 0x0000a, 0x000a0, 0x00012, 0x0007d, 0x001a2, 0x0003b, - 0x0025f, 0x000dd, 0x0027c, 0x00343, 0x00368, 0x0036b, 0x0003e, 0x001fa, - 0x00485, 0x001b3, 0x0007f, 0x001b1, 0x0019e, 0x004ba, 0x007ad, 0x00339, - 0x00066, 0x007a4, 0x00793, 0x006c6, 0x0007e, 0x000f1, 0x00372, 0x009fb, - 0x00d83, 0x00d8a, 0x00947, 0x009f4, 0x001d0, 0x01b09, 0x01b4b, 0x007ec, - 0x003e1, 0x000ca, 0x003ec, 0x02539, 0x04fa9, 0x01b57, 0x03429, 0x03d2a, - 0x00d97, 0x003a7, 0x00dc0, 0x00d96, 0x00dc1, 0x007eb, 0x03cba, 0x00c43, - 0x00c41, 0x01b52, 0x007ef, 0x00323, 0x03cb9, 0x03c83, 0x007d0, 0x007ed, - 0x06c7f, 0x09033, 0x03f6c, 0x36383, 0x1e95d, 0x06c78, 0x00747, 0x01b51, - 0x00022, 0x00016, 0x00039, 0x00252, 0x00079, 0x00486, 0x00338, 0x00369, - 0x00d88, 0x00026, 0x00d87, 0x00f4b, 0x00d82, 0x00027, 0x001e1, 0x01a15, - 0x007c7, 0x012f0, 0x001e0, 0x006d0, 0x01a16, 0x01e44, 0x01e5f, 0x03690, - 0x00d90, 0x00c42, 0x00daf, 0x00d92, 0x00f80, 0x00cfb, 0x0342f, 0x0487f, - 0x01b46, 0x07968, 0x00d95, 0x00d91, 0x01b55, 0x03f68, 0x04bc6, 0x03cbd, - 0x00f81, 0x00320, 0x00069, 0x000fe, 0x006d5, 0x0033f, 0x000de, 0x007c6, - 0x01e40, 0x00d94, 0x00f88, 0x03c8e, 0x03694, 0x00dae, 0x00dad, 0x00267, - 0x003a6, 0x00327, 0x0487e, 0x007ee, 0x00749, 0x004c7, 0x03692, 0x01b56, - 0x00fd1, 0x07a56, 0x06c77, 0x09031, 0x00748, 0x06c7a, 0x0796d, 0x033ea, - 0x06c76, 0x00fd0, 0x36382, 0x1e417, 0x00745, 0x04faf, 0x0d8e1, 0x03f6b, - 0x1e95c, 0x04fad, 0x0009e, 0x004bd, 0x0067c, 0x01b08, 0x003eb, 0x01b45, - 0x03691, 0x0d8e5, 0x07904, 0x00981, 0x007ea, 0x019f4, 0x06c7d, 0x04fab, - 0x04fac, 0x06c7e, 0x01300, 0x06c7b, 0x0006f, 0x003f7, 0x03c85, 0x004c4, - 0x0001e, 0x006e1, 0x03693, 0x01b44, 0x00241, 0x01e46, 0x0019d, 0x00266, - 0x004bb, 0x02538, 0x007ac, 0x01b54, 0x00902, 0x04870, 0x00da7, 0x00900, - 0x00185, 0x06c79, 0x006e3, 0x003e9, 0x01e94, 0x003ed, 0x003f2, 0x0342e, - 0x0346b, 0x0251a, 0x004c5, 0x01881, 0x0481c, 0x01b59, 0x03c87, 0x04fae, - 0x007e9, 0x03f6d, 0x0f20a, 0x09030, 0x04faa, 0x0d8e6, 0x03f6f, 0x0481a, - 0x03f6e, 0x1e416, 0x0d8e7, -}; - -static const uint8_t coef5_huffbits[435] = { - 10, 4, 2, 4, 4, 5, 5, 5, - 5, 6, 6, 6, 6, 6, 6, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 8, 8, 8, 8, 7, 8, 8, - 8, 8, 8, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 10, 9, 10, 10, 10, 10, - 10, 9, 10, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 10, 10, 11, 11, - 10, 11, 11, 11, 11, 11, 12, 12, - 12, 12, 12, 12, 11, 11, 11, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 13, - 13, 13, 12, 12, 13, 13, 13, 12, - 12, 12, 12, 12, 13, 13, 13, 13, - 13, 14, 14, 14, 14, 13, 13, 13, - 13, 13, 14, 14, 14, 14, 14, 14, - 15, 14, 14, 14, 14, 14, 14, 13, - 14, 14, 14, 14, 14, 14, 15, 14, - 15, 14, 15, 15, 15, 15, 15, 15, - 16, 15, 15, 14, 15, 16, 15, 14, - 14, 15, 14, 14, 15, 14, 15, 15, - 15, 16, 15, 17, 16, 15, 15, 15, - 15, 16, 16, 16, 16, 17, 15, 16, - 14, 16, 16, 17, 16, 16, 16, 16, - 16, 15, 15, 15, 16, 16, 16, 16, - 17, 15, 15, 15, 15, 16, 15, 15, - 4, 7, 8, 8, 9, 9, 9, 10, - 10, 10, 10, 10, 10, 10, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 12, - 12, 11, 11, 11, 12, 12, 12, 12, - 12, 12, 12, 12, 13, 13, 13, 13, - 12, 13, 14, 14, 15, 15, 14, 14, - 14, 14, 14, 14, 14, 15, 14, 14, - 14, 15, 15, 15, 14, 14, 15, 15, - 15, 16, 16, 18, 17, 15, 15, 15, - 6, 9, 10, 10, 11, 11, 12, 12, - 12, 13, 12, 12, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 15, - 15, 15, 14, 14, 15, 16, 15, 14, - 14, 15, 7, 10, 11, 12, 13, 13, - 13, 14, 14, 14, 14, 14, 14, 14, - 14, 15, 15, 15, 15, 15, 14, 15, - 16, 15, 15, 16, 15, 15, 15, 16, - 15, 16, 18, 17, 15, 15, 16, 16, - 17, 15, 8, 11, 13, 13, 14, 15, - 14, 16, 15, 16, 15, 15, 15, 15, - 15, 15, 17, 15, 9, 12, 14, 15, - 10, 13, 14, 15, 10, 13, 11, 14, - 11, 14, 11, 15, 12, 15, 12, 12, - 13, 15, 13, 14, 13, 14, 14, 14, - 14, 14, 15, 15, 15, 15, 14, 15, - 15, 16, 16, 16, 15, 16, 16, 15, - 16, 17, 16, -}; - -static const uint16_t levels0[60] = { -317, 92, 62, 60, 19, 17, 10, 7, - 6, 5, 5, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 1, 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, -}; - -static const uint16_t levels1[40] = { -311, 91, 61, 28, 10, 6, 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, -}; - -static const uint16_t levels2[340] = { -181,110, 78, 63, 61, 62, 60, 61, - 33, 41, 41, 19, 17, 19, 12, 11, - 9, 11, 10, 6, 8, 7, 6, 4, - 5, 5, 4, 4, 3, 4, 3, 5, - 3, 4, 3, 3, 3, 3, 3, 3, - 2, 2, 4, 2, 3, 2, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 2, 1, 2, 2, - 2, 2, 1, 2, 1, 1, 1, 2, - 2, 1, 2, 1, 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, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, -}; - -static const uint16_t levels3[180] = { -351,122, 76, 61, 41, 42, 24, 30, - 22, 19, 11, 9, 10, 8, 5, 5, - 4, 5, 5, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 3, 2, 2, 2, - 3, 3, 2, 2, 2, 3, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 1, - 2, 2, 1, 2, 1, 2, 2, 2, - 2, 2, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, - 2, 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, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, -}; - -static const uint16_t levels4[70] = { -113, 68, 49, 42, 40, 32, 27, 15, - 10, 5, 3, 3, 3, 3, 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, -}; - -static const uint16_t levels5[40] = { -214, 72, 42, 40, 18, 4, 4, 2, - 2, 2, 2, 2, 1, 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, -}; - -static const CoefVLCTable coef_vlcs[6] = { - { - sizeof(coef0_huffbits), sizeof(levels0)/2, coef0_huffcodes, coef0_huffbits, levels0, - }, - { - sizeof(coef1_huffbits), sizeof(levels1)/2, coef1_huffcodes, coef1_huffbits, levels1, - }, - { - sizeof(coef2_huffbits), sizeof(levels2)/2, coef2_huffcodes, coef2_huffbits, levels2, - }, - { - sizeof(coef3_huffbits), sizeof(levels3)/2, coef3_huffcodes, coef3_huffbits, levels3, - }, - { - sizeof(coef4_huffbits), sizeof(levels4)/2, coef4_huffcodes, coef4_huffbits, levels4, - }, - { - sizeof(coef5_huffbits), sizeof(levels5)/2, coef5_huffcodes, coef5_huffbits, levels5, - }, -}; - -#endif /* AVCODEC_WMADATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/wmadec.c b/tizen/distrib/ffmpeg/libavcodec/wmadec.c deleted file mode 100644 index a24256d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmadec.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - * WMA compatible decoder - * Copyright (c) 2002 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * WMA compatible decoder. - * This decoder handles Microsoft Windows Media Audio data, versions 1 & 2. - * WMA v1 is identified by audio format 0x160 in Microsoft media files - * (ASF/AVI/WAV). WMA v2 is identified by audio format 0x161. - * - * To use this decoder, a calling application must supply the extra data - * bytes provided with the WMA data. These are the extra, codec-specific - * bytes at the end of a WAVEFORMATEX data structure. Transmit these bytes - * to the decoder using the extradata[_size] fields in AVCodecContext. There - * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data. - */ - -#include "avcodec.h" -#include "wma.h" - -#undef NDEBUG -#include - -#define EXPVLCBITS 8 -#define EXPMAX ((19+EXPVLCBITS-1)/EXPVLCBITS) - -#define HGAINVLCBITS 9 -#define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS) - -static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len); - -#ifdef TRACE -static void dump_shorts(WMACodecContext *s, const char *name, const short *tab, int n) -{ - int i; - - tprintf(s->avctx, "%s[%d]:\n", name, n); - for(i=0;iavctx, "%4d: ", i); - tprintf(s->avctx, " %5d.0", tab[i]); - if ((i & 7) == 7) - tprintf(s->avctx, "\n"); - } -} - -static void dump_floats(WMACodecContext *s, const char *name, int prec, const float *tab, int n) -{ - int i; - - tprintf(s->avctx, "%s[%d]:\n", name, n); - for(i=0;iavctx, "%4d: ", i); - tprintf(s->avctx, " %8.*f", prec, tab[i]); - if ((i & 7) == 7) - tprintf(s->avctx, "\n"); - } - if ((i & 7) != 0) - tprintf(s->avctx, "\n"); -} -#endif - -static int wma_decode_init(AVCodecContext * avctx) -{ - WMACodecContext *s = avctx->priv_data; - int i, flags2; - uint8_t *extradata; - - s->avctx = avctx; - - /* extract flag infos */ - flags2 = 0; - extradata = avctx->extradata; - if (avctx->codec->id == CODEC_ID_WMAV1 && avctx->extradata_size >= 4) { - flags2 = AV_RL16(extradata+2); - } else if (avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 6) { - flags2 = AV_RL16(extradata+4); - } -// for(i=0; iextradata_size; i++) -// av_log(NULL, AV_LOG_ERROR, "%02X ", extradata[i]); - - s->use_exp_vlc = flags2 & 0x0001; - s->use_bit_reservoir = flags2 & 0x0002; - s->use_variable_block_len = flags2 & 0x0004; - - if(ff_wma_init(avctx, flags2)<0) - return -1; - - /* init MDCT */ - for(i = 0; i < s->nb_block_sizes; i++) - ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1, 1.0); - - if (s->use_noise_coding) { - init_vlc(&s->hgain_vlc, HGAINVLCBITS, sizeof(ff_wma_hgain_huffbits), - ff_wma_hgain_huffbits, 1, 1, - ff_wma_hgain_huffcodes, 2, 2, 0); - } - - if (s->use_exp_vlc) { - init_vlc(&s->exp_vlc, EXPVLCBITS, sizeof(ff_aac_scalefactor_bits), //FIXME move out of context - ff_aac_scalefactor_bits, 1, 1, - ff_aac_scalefactor_code, 4, 4, 0); - } else { - wma_lsp_to_curve_init(s, s->frame_len); - } - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -/** - * compute x^-0.25 with an exponent and mantissa table. We use linear - * interpolation to reduce the mantissa table size at a small speed - * expense (linear interpolation approximately doubles the number of - * bits of precision). - */ -static inline float pow_m1_4(WMACodecContext *s, float x) -{ - union { - float f; - unsigned int v; - } u, t; - unsigned int e, m; - float a, b; - - u.f = x; - e = u.v >> 23; - m = (u.v >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1); - /* build interpolation scale: 1 <= t < 2. */ - t.v = ((u.v << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23); - a = s->lsp_pow_m_table1[m]; - b = s->lsp_pow_m_table2[m]; - return s->lsp_pow_e_table[e] * (a + b * t.f); -} - -static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len) -{ - float wdel, a, b; - int i, e, m; - - wdel = M_PI / frame_len; - for(i=0;ilsp_cos_table[i] = 2.0f * cos(wdel * i); - - /* tables for x^-0.25 computation */ - for(i=0;i<256;i++) { - e = i - 126; - s->lsp_pow_e_table[i] = pow(2.0, e * -0.25); - } - - /* NOTE: these two tables are needed to avoid two operations in - pow_m1_4 */ - b = 1.0; - for(i=(1 << LSP_POW_BITS) - 1;i>=0;i--) { - m = (1 << LSP_POW_BITS) + i; - a = (float)m * (0.5 / (1 << LSP_POW_BITS)); - a = pow(a, -0.25); - s->lsp_pow_m_table1[i] = 2 * a - b; - s->lsp_pow_m_table2[i] = b - a; - b = a; - } -#if 0 - for(i=1;i<20;i++) { - float v, r1, r2; - v = 5.0 / i; - r1 = pow_m1_4(s, v); - r2 = pow(v,-0.25); - printf("%f^-0.25=%f e=%f\n", v, r1, r2 - r1); - } -#endif -} - -/** - * NOTE: We use the same code as Vorbis here - * @todo optimize it further with SSE/3Dnow - */ -static void wma_lsp_to_curve(WMACodecContext *s, - float *out, float *val_max_ptr, - int n, float *lsp) -{ - int i, j; - float p, q, w, v, val_max; - - val_max = 0; - for(i=0;ilsp_cos_table[i]; - for(j=1;j val_max) - val_max = v; - out[i] = v; - } - *val_max_ptr = val_max; -} - -/** - * decode exponents coded with LSP coefficients (same idea as Vorbis) - */ -static void decode_exp_lsp(WMACodecContext *s, int ch) -{ - float lsp_coefs[NB_LSP_COEFS]; - int val, i; - - for(i = 0; i < NB_LSP_COEFS; i++) { - if (i == 0 || i >= 8) - val = get_bits(&s->gb, 3); - else - val = get_bits(&s->gb, 4); - lsp_coefs[i] = ff_wma_lsp_codebook[i][val]; - } - - wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch], - s->block_len, lsp_coefs); -} - -/** pow(10, i / 16.0) for i in -60..95 */ -static const float pow_tab[] = { - 1.7782794100389e-04, 2.0535250264571e-04, - 2.3713737056617e-04, 2.7384196342644e-04, - 3.1622776601684e-04, 3.6517412725484e-04, - 4.2169650342858e-04, 4.8696752516586e-04, - 5.6234132519035e-04, 6.4938163157621e-04, - 7.4989420933246e-04, 8.6596432336006e-04, - 1.0000000000000e-03, 1.1547819846895e-03, - 1.3335214321633e-03, 1.5399265260595e-03, - 1.7782794100389e-03, 2.0535250264571e-03, - 2.3713737056617e-03, 2.7384196342644e-03, - 3.1622776601684e-03, 3.6517412725484e-03, - 4.2169650342858e-03, 4.8696752516586e-03, - 5.6234132519035e-03, 6.4938163157621e-03, - 7.4989420933246e-03, 8.6596432336006e-03, - 1.0000000000000e-02, 1.1547819846895e-02, - 1.3335214321633e-02, 1.5399265260595e-02, - 1.7782794100389e-02, 2.0535250264571e-02, - 2.3713737056617e-02, 2.7384196342644e-02, - 3.1622776601684e-02, 3.6517412725484e-02, - 4.2169650342858e-02, 4.8696752516586e-02, - 5.6234132519035e-02, 6.4938163157621e-02, - 7.4989420933246e-02, 8.6596432336007e-02, - 1.0000000000000e-01, 1.1547819846895e-01, - 1.3335214321633e-01, 1.5399265260595e-01, - 1.7782794100389e-01, 2.0535250264571e-01, - 2.3713737056617e-01, 2.7384196342644e-01, - 3.1622776601684e-01, 3.6517412725484e-01, - 4.2169650342858e-01, 4.8696752516586e-01, - 5.6234132519035e-01, 6.4938163157621e-01, - 7.4989420933246e-01, 8.6596432336007e-01, - 1.0000000000000e+00, 1.1547819846895e+00, - 1.3335214321633e+00, 1.5399265260595e+00, - 1.7782794100389e+00, 2.0535250264571e+00, - 2.3713737056617e+00, 2.7384196342644e+00, - 3.1622776601684e+00, 3.6517412725484e+00, - 4.2169650342858e+00, 4.8696752516586e+00, - 5.6234132519035e+00, 6.4938163157621e+00, - 7.4989420933246e+00, 8.6596432336007e+00, - 1.0000000000000e+01, 1.1547819846895e+01, - 1.3335214321633e+01, 1.5399265260595e+01, - 1.7782794100389e+01, 2.0535250264571e+01, - 2.3713737056617e+01, 2.7384196342644e+01, - 3.1622776601684e+01, 3.6517412725484e+01, - 4.2169650342858e+01, 4.8696752516586e+01, - 5.6234132519035e+01, 6.4938163157621e+01, - 7.4989420933246e+01, 8.6596432336007e+01, - 1.0000000000000e+02, 1.1547819846895e+02, - 1.3335214321633e+02, 1.5399265260595e+02, - 1.7782794100389e+02, 2.0535250264571e+02, - 2.3713737056617e+02, 2.7384196342644e+02, - 3.1622776601684e+02, 3.6517412725484e+02, - 4.2169650342858e+02, 4.8696752516586e+02, - 5.6234132519035e+02, 6.4938163157621e+02, - 7.4989420933246e+02, 8.6596432336007e+02, - 1.0000000000000e+03, 1.1547819846895e+03, - 1.3335214321633e+03, 1.5399265260595e+03, - 1.7782794100389e+03, 2.0535250264571e+03, - 2.3713737056617e+03, 2.7384196342644e+03, - 3.1622776601684e+03, 3.6517412725484e+03, - 4.2169650342858e+03, 4.8696752516586e+03, - 5.6234132519035e+03, 6.4938163157621e+03, - 7.4989420933246e+03, 8.6596432336007e+03, - 1.0000000000000e+04, 1.1547819846895e+04, - 1.3335214321633e+04, 1.5399265260595e+04, - 1.7782794100389e+04, 2.0535250264571e+04, - 2.3713737056617e+04, 2.7384196342644e+04, - 3.1622776601684e+04, 3.6517412725484e+04, - 4.2169650342858e+04, 4.8696752516586e+04, - 5.6234132519035e+04, 6.4938163157621e+04, - 7.4989420933246e+04, 8.6596432336007e+04, - 1.0000000000000e+05, 1.1547819846895e+05, - 1.3335214321633e+05, 1.5399265260595e+05, - 1.7782794100389e+05, 2.0535250264571e+05, - 2.3713737056617e+05, 2.7384196342644e+05, - 3.1622776601684e+05, 3.6517412725484e+05, - 4.2169650342858e+05, 4.8696752516586e+05, - 5.6234132519035e+05, 6.4938163157621e+05, - 7.4989420933246e+05, 8.6596432336007e+05, -}; - -/** - * decode exponents coded with VLC codes - */ -static int decode_exp_vlc(WMACodecContext *s, int ch) -{ - int last_exp, n, code; - const uint16_t *ptr; - float v, max_scale; - uint32_t *q, *q_end, iv; - const float *ptab = pow_tab + 60; - const uint32_t *iptab = (const uint32_t*)ptab; - - ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; - q = (uint32_t *)s->exponents[ch]; - q_end = q + s->block_len; - max_scale = 0; - if (s->version == 1) { - last_exp = get_bits(&s->gb, 5) + 10; - v = ptab[last_exp]; - iv = iptab[last_exp]; - max_scale = v; - n = *ptr++; - switch (n & 3) do { - case 0: *q++ = iv; - case 3: *q++ = iv; - case 2: *q++ = iv; - case 1: *q++ = iv; - } while ((n -= 4) > 0); - }else - last_exp = 36; - - while (q < q_end) { - code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "Exponent vlc invalid\n"); - return -1; - } - /* NOTE: this offset is the same as MPEG4 AAC ! */ - last_exp += code - 60; - if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) { - av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n", - last_exp); - return -1; - } - v = ptab[last_exp]; - iv = iptab[last_exp]; - if (v > max_scale) - max_scale = v; - n = *ptr++; - switch (n & 3) do { - case 0: *q++ = iv; - case 3: *q++ = iv; - case 2: *q++ = iv; - case 1: *q++ = iv; - } while ((n -= 4) > 0); - } - s->max_exponent[ch] = max_scale; - return 0; -} - - -/** - * Apply MDCT window and add into output. - * - * We ensure that when the windows overlap their squared sum - * is always 1 (MDCT reconstruction rule). - */ -static void wma_window(WMACodecContext *s, float *out) -{ - float *in = s->output; - int block_len, bsize, n; - - /* left part */ - if (s->block_len_bits <= s->prev_block_len_bits) { - block_len = s->block_len; - bsize = s->frame_len_bits - s->block_len_bits; - - s->dsp.vector_fmul_add(out, in, s->windows[bsize], - out, block_len); - - } else { - block_len = 1 << s->prev_block_len_bits; - n = (s->block_len - block_len) / 2; - bsize = s->frame_len_bits - s->prev_block_len_bits; - - s->dsp.vector_fmul_add(out+n, in+n, s->windows[bsize], - out+n, block_len); - - memcpy(out+n+block_len, in+n+block_len, n*sizeof(float)); - } - - out += s->block_len; - in += s->block_len; - - /* right part */ - if (s->block_len_bits <= s->next_block_len_bits) { - block_len = s->block_len; - bsize = s->frame_len_bits - s->block_len_bits; - - s->dsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len); - - } else { - block_len = 1 << s->next_block_len_bits; - n = (s->block_len - block_len) / 2; - bsize = s->frame_len_bits - s->next_block_len_bits; - - memcpy(out, in, n*sizeof(float)); - - s->dsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len); - - memset(out+n+block_len, 0, n*sizeof(float)); - } -} - - -/** - * @return 0 if OK. 1 if last block of frame. return -1 if - * unrecorrable error. - */ -static int wma_decode_block(WMACodecContext *s) -{ - int n, v, a, ch, bsize; - int coef_nb_bits, total_gain; - int nb_coefs[MAX_CHANNELS]; - float mdct_norm; - -#ifdef TRACE - tprintf(s->avctx, "***decode_block: %d:%d\n", s->frame_count - 1, s->block_num); -#endif - - /* compute current block length */ - if (s->use_variable_block_len) { - n = av_log2(s->nb_block_sizes - 1) + 1; - - if (s->reset_block_lengths) { - s->reset_block_lengths = 0; - v = get_bits(&s->gb, n); - if (v >= s->nb_block_sizes){ - av_log(s->avctx, AV_LOG_ERROR, "prev_block_len_bits %d out of range\n", s->frame_len_bits - v); - return -1; - } - s->prev_block_len_bits = s->frame_len_bits - v; - v = get_bits(&s->gb, n); - if (v >= s->nb_block_sizes){ - av_log(s->avctx, AV_LOG_ERROR, "block_len_bits %d out of range\n", s->frame_len_bits - v); - return -1; - } - s->block_len_bits = s->frame_len_bits - v; - } else { - /* update block lengths */ - s->prev_block_len_bits = s->block_len_bits; - s->block_len_bits = s->next_block_len_bits; - } - v = get_bits(&s->gb, n); - if (v >= s->nb_block_sizes){ - av_log(s->avctx, AV_LOG_ERROR, "next_block_len_bits %d out of range\n", s->frame_len_bits - v); - return -1; - } - s->next_block_len_bits = s->frame_len_bits - v; - } else { - /* fixed block len */ - s->next_block_len_bits = s->frame_len_bits; - s->prev_block_len_bits = s->frame_len_bits; - s->block_len_bits = s->frame_len_bits; - } - - /* now check if the block length is coherent with the frame length */ - s->block_len = 1 << s->block_len_bits; - if ((s->block_pos + s->block_len) > s->frame_len){ - av_log(s->avctx, AV_LOG_ERROR, "frame_len overflow\n"); - return -1; - } - - if (s->nb_channels == 2) { - s->ms_stereo = get_bits1(&s->gb); - } - v = 0; - for(ch = 0; ch < s->nb_channels; ch++) { - a = get_bits1(&s->gb); - s->channel_coded[ch] = a; - v |= a; - } - - bsize = s->frame_len_bits - s->block_len_bits; - - /* if no channel coded, no need to go further */ - /* XXX: fix potential framing problems */ - if (!v) - goto next; - - /* read total gain and extract corresponding number of bits for - coef escape coding */ - total_gain = 1; - for(;;) { - a = get_bits(&s->gb, 7); - total_gain += a; - if (a != 127) - break; - } - - coef_nb_bits= ff_wma_total_gain_to_bits(total_gain); - - /* compute number of coefficients */ - n = s->coefs_end[bsize] - s->coefs_start; - for(ch = 0; ch < s->nb_channels; ch++) - nb_coefs[ch] = n; - - /* complex coding */ - if (s->use_noise_coding) { - - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - int i, n, a; - n = s->exponent_high_sizes[bsize]; - for(i=0;igb); - s->high_band_coded[ch][i] = a; - /* if noise coding, the coefficients are not transmitted */ - if (a) - nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; - } - } - } - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - int i, n, val, code; - - n = s->exponent_high_sizes[bsize]; - val = (int)0x80000000; - for(i=0;ihigh_band_coded[ch][i]) { - if (val == (int)0x80000000) { - val = get_bits(&s->gb, 7) - 19; - } else { - code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "hgain vlc invalid\n"); - return -1; - } - val += code - 18; - } - s->high_band_values[ch][i] = val; - } - } - } - } - } - - /* exponents can be reused in short blocks. */ - if ((s->block_len_bits == s->frame_len_bits) || - get_bits1(&s->gb)) { - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - if (s->use_exp_vlc) { - if (decode_exp_vlc(s, ch) < 0) - return -1; - } else { - decode_exp_lsp(s, ch); - } - s->exponents_bsize[ch] = bsize; - } - } - } - - /* parse spectral coefficients : just RLE encoding */ - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - int tindex; - WMACoef* ptr = &s->coefs1[ch][0]; - - /* special VLC tables are used for ms stereo because - there is potentially less energy there */ - tindex = (ch == 1 && s->ms_stereo); - memset(ptr, 0, s->block_len * sizeof(WMACoef)); - ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex], - s->level_table[tindex], s->run_table[tindex], - 0, ptr, 0, nb_coefs[ch], - s->block_len, s->frame_len_bits, coef_nb_bits); - } - if (s->version == 1 && s->nb_channels >= 2) { - align_get_bits(&s->gb); - } - } - - /* normalize */ - { - int n4 = s->block_len / 2; - mdct_norm = 1.0 / (float)n4; - if (s->version == 1) { - mdct_norm *= sqrt(n4); - } - } - - /* finally compute the MDCT coefficients */ - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - WMACoef *coefs1; - float *coefs, *exponents, mult, mult1, noise; - int i, j, n, n1, last_high_band, esize; - float exp_power[HIGH_BAND_MAX_SIZE]; - - coefs1 = s->coefs1[ch]; - exponents = s->exponents[ch]; - esize = s->exponents_bsize[ch]; - mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; - mult *= mdct_norm; - coefs = s->coefs[ch]; - if (s->use_noise_coding) { - mult1 = mult; - /* very low freqs : noise */ - for(i = 0;i < s->coefs_start; i++) { - *coefs++ = s->noise_table[s->noise_index] * - exponents[i<>esize] * mult1; - s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - } - - n1 = s->exponent_high_sizes[bsize]; - - /* compute power of high bands */ - exponents = s->exponents[ch] + - (s->high_band_start[bsize]<>esize); - last_high_band = 0; /* avoid warning */ - for(j=0;jexponent_high_bands[s->frame_len_bits - - s->block_len_bits][j]; - if (s->high_band_coded[ch][j]) { - float e2, v; - e2 = 0; - for(i = 0;i < n; i++) { - v = exponents[i<>esize]; - e2 += v * v; - } - exp_power[j] = e2 / n; - last_high_band = j; - tprintf(s->avctx, "%d: power=%f (%d)\n", j, exp_power[j], n); - } - exponents += n<>esize; - } - - /* main freqs and high freqs */ - exponents = s->exponents[ch] + (s->coefs_start<>esize); - for(j=-1;jhigh_band_start[bsize] - - s->coefs_start; - } else { - n = s->exponent_high_bands[s->frame_len_bits - - s->block_len_bits][j]; - } - if (j >= 0 && s->high_band_coded[ch][j]) { - /* use noise with specified power */ - mult1 = sqrt(exp_power[j] / exp_power[last_high_band]); - /* XXX: use a table */ - mult1 = mult1 * pow(10, s->high_band_values[ch][j] * 0.05); - mult1 = mult1 / (s->max_exponent[ch] * s->noise_mult); - mult1 *= mdct_norm; - for(i = 0;i < n; i++) { - noise = s->noise_table[s->noise_index]; - s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - *coefs++ = noise * - exponents[i<>esize] * mult1; - } - exponents += n<>esize; - } else { - /* coded values + small noise */ - for(i = 0;i < n; i++) { - noise = s->noise_table[s->noise_index]; - s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - *coefs++ = ((*coefs1++) + noise) * - exponents[i<>esize] * mult; - } - exponents += n<>esize; - } - } - - /* very high freqs : noise */ - n = s->block_len - s->coefs_end[bsize]; - mult1 = mult * exponents[((-1<>esize]; - for(i = 0; i < n; i++) { - *coefs++ = s->noise_table[s->noise_index] * mult1; - s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - } - } else { - /* XXX: optimize more */ - for(i = 0;i < s->coefs_start; i++) - *coefs++ = 0.0; - n = nb_coefs[ch]; - for(i = 0;i < n; i++) { - *coefs++ = coefs1[i] * exponents[i<>esize] * mult; - } - n = s->block_len - s->coefs_end[bsize]; - for(i = 0;i < n; i++) - *coefs++ = 0.0; - } - } - } - -#ifdef TRACE - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - dump_floats(s, "exponents", 3, s->exponents[ch], s->block_len); - dump_floats(s, "coefs", 1, s->coefs[ch], s->block_len); - } - } -#endif - - if (s->ms_stereo && s->channel_coded[1]) { - /* nominal case for ms stereo: we do it before mdct */ - /* no need to optimize this case because it should almost - never happen */ - if (!s->channel_coded[0]) { - tprintf(s->avctx, "rare ms-stereo case happened\n"); - memset(s->coefs[0], 0, sizeof(float) * s->block_len); - s->channel_coded[0] = 1; - } - - s->dsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len); - } - -next: - for(ch = 0; ch < s->nb_channels; ch++) { - int n4, index; - - n4 = s->block_len / 2; - if(s->channel_coded[ch]){ - ff_imdct_calc(&s->mdct_ctx[bsize], s->output, s->coefs[ch]); - }else if(!(s->ms_stereo && ch==1)) - memset(s->output, 0, sizeof(s->output)); - - /* multiply by the window and add in the frame */ - index = (s->frame_len / 2) + s->block_pos - n4; - wma_window(s, &s->frame_out[ch][index]); - } - - /* update block number */ - s->block_num++; - s->block_pos += s->block_len; - if (s->block_pos >= s->frame_len) - return 1; - else - return 0; -} - -/* decode a frame of frame_len samples */ -static int wma_decode_frame(WMACodecContext *s, int16_t *samples) -{ - int ret, i, n, ch, incr; - int16_t *ptr; - float *iptr; - -#ifdef TRACE - tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len); -#endif - - /* read each block */ - s->block_num = 0; - s->block_pos = 0; - for(;;) { - ret = wma_decode_block(s); - if (ret < 0) - return -1; - if (ret) - break; - } - - /* convert frame to integer */ - n = s->frame_len; - incr = s->nb_channels; - if (s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { - for(ch = 0; ch < s->nb_channels; ch++) { - ptr = samples + ch; - iptr = s->frame_out[ch]; - - for(i=0;iframe_out[ch][0], &s->frame_out[ch][s->frame_len], - s->frame_len * sizeof(float)); - } - } else { - float *output[MAX_CHANNELS]; - for (ch = 0; ch < MAX_CHANNELS; ch++) - output[ch] = s->frame_out[ch]; - s->dsp.float_to_int16_interleave(samples, (const float **)output, n, incr); - for(ch = 0; ch < incr; ch++) { - /* prepare for next block */ - memmove(&s->frame_out[ch][0], &s->frame_out[ch][n], n * sizeof(float)); - } - } - -#ifdef TRACE - dump_shorts(s, "samples", samples, n * s->nb_channels); -#endif - return 0; -} - -static int wma_decode_superframe(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - WMACodecContext *s = avctx->priv_data; - int nb_frames, bit_offset, i, pos, len; - uint8_t *q; - int16_t *samples; - - tprintf(avctx, "***decode_superframe:\n"); - - if(buf_size==0){ - s->last_superframe_len = 0; - return 0; - } - if (buf_size < s->block_align) - return 0; - buf_size = s->block_align; - - samples = data; - - init_get_bits(&s->gb, buf, buf_size*8); - - if (s->use_bit_reservoir) { - /* read super frame header */ - skip_bits(&s->gb, 4); /* super frame index */ - nb_frames = get_bits(&s->gb, 4) - 1; - - if((nb_frames+1) * s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ - av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); - goto fail; - } - - bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); - - if (s->last_superframe_len > 0) { - // printf("skip=%d\n", s->last_bitoffset); - /* add bit_offset bits to last frame */ - if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) > - MAX_CODED_SUPERFRAME_SIZE) - goto fail; - q = s->last_superframe + s->last_superframe_len; - len = bit_offset; - while (len > 7) { - *q++ = (get_bits)(&s->gb, 8); - len -= 8; - } - if (len > 0) { - *q++ = (get_bits)(&s->gb, len) << (8 - len); - } - - /* XXX: bit_offset bits into last frame */ - init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); - /* skip unused bits */ - if (s->last_bitoffset > 0) - skip_bits(&s->gb, s->last_bitoffset); - /* this frame is stored in the last superframe and in the - current one */ - if (wma_decode_frame(s, samples) < 0) - goto fail; - samples += s->nb_channels * s->frame_len; - } - - /* read each frame starting from bit_offset */ - pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; - init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); - len = pos & 7; - if (len > 0) - skip_bits(&s->gb, len); - - s->reset_block_lengths = 1; - for(i=0;inb_channels * s->frame_len; - } - - /* we copy the end of the frame in the last frame buffer */ - pos = get_bits_count(&s->gb) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7); - s->last_bitoffset = pos & 7; - pos >>= 3; - len = buf_size - pos; - if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0) { - av_log(s->avctx, AV_LOG_ERROR, "len %d invalid\n", len); - goto fail; - } - s->last_superframe_len = len; - memcpy(s->last_superframe, buf + pos, len); - } else { - if(s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ - av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); - goto fail; - } - /* single frame decode */ - if (wma_decode_frame(s, samples) < 0) - goto fail; - samples += s->nb_channels * s->frame_len; - } - -//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d outbytes:%d eaten:%d\n", s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len, (int8_t *)samples - (int8_t *)data, s->block_align); - - *data_size = (int8_t *)samples - (int8_t *)data; - return s->block_align; - fail: - /* when error, we reset the bit reservoir */ - s->last_superframe_len = 0; - return -1; -} - -static av_cold void flush(AVCodecContext *avctx) -{ - WMACodecContext *s = avctx->priv_data; - - s->last_bitoffset= - s->last_superframe_len= 0; -} - -AVCodec wmav1_decoder = -{ - "wmav1", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WMAV1, - sizeof(WMACodecContext), - wma_decode_init, - NULL, - ff_wma_end, - wma_decode_superframe, - .flush=flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), -}; - -AVCodec wmav2_decoder = -{ - "wmav2", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WMAV2, - sizeof(WMACodecContext), - wma_decode_init, - NULL, - ff_wma_end, - wma_decode_superframe, - .flush=flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/wmaenc.c b/tizen/distrib/ffmpeg/libavcodec/wmaenc.c deleted file mode 100644 index 7aaeb70..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmaenc.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * WMA compatible encoder - * Copyright (c) 2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "wma.h" - -#undef NDEBUG -#include - - -static int encode_init(AVCodecContext * avctx){ - WMACodecContext *s = avctx->priv_data; - int i, flags1, flags2; - uint8_t *extradata; - - s->avctx = avctx; - - if(avctx->channels > MAX_CHANNELS) - return -1; - - if(avctx->bit_rate < 24*1000) - return -1; - - /* extract flag infos */ - flags1 = 0; - flags2 = 1; - if (avctx->codec->id == CODEC_ID_WMAV1) { - extradata= av_malloc(4); - avctx->extradata_size= 4; - AV_WL16(extradata, flags1); - AV_WL16(extradata+2, flags2); - } else if (avctx->codec->id == CODEC_ID_WMAV2) { - extradata= av_mallocz(10); - avctx->extradata_size= 10; - AV_WL32(extradata, flags1); - AV_WL16(extradata+4, flags2); - }else - assert(0); - avctx->extradata= extradata; - s->use_exp_vlc = flags2 & 0x0001; - s->use_bit_reservoir = flags2 & 0x0002; - s->use_variable_block_len = flags2 & 0x0004; - - ff_wma_init(avctx, flags2); - - /* init MDCT */ - for(i = 0; i < s->nb_block_sizes; i++) - ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); - - avctx->block_align= - s->block_align= avctx->bit_rate*(int64_t)s->frame_len / (avctx->sample_rate*8); -//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", s->block_align, avctx->bit_rate, s->frame_len, avctx->sample_rate); - avctx->frame_size= s->frame_len; - - return 0; -} - - -static void apply_window_and_mdct(AVCodecContext * avctx, signed short * audio, int len) { - WMACodecContext *s = avctx->priv_data; - int window_index= s->frame_len_bits - s->block_len_bits; - int i, j, channel; - const float * win = s->windows[window_index]; - int window_len = 1 << s->block_len_bits; - float n = window_len/2; - - for (channel = 0; channel < avctx->channels; channel++) { - memcpy(s->output, s->frame_out[channel], sizeof(float)*window_len); - j = channel; - for (i = 0; i < len; i++, j += avctx->channels){ - s->output[i+window_len] = audio[j] / n * win[window_len - i - 1]; - s->frame_out[channel][i] = audio[j] / n * win[i]; - } - ff_mdct_calc(&s->mdct_ctx[window_index], s->coefs[channel], s->output); - } -} - -//FIXME use for decoding too -static void init_exp(WMACodecContext *s, int ch, const int *exp_param){ - int n; - const uint16_t *ptr; - float v, *q, max_scale, *q_end; - - ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; - q = s->exponents[ch]; - q_end = q + s->block_len; - max_scale = 0; - while (q < q_end) { - /* XXX: use a table */ - v = pow(10, *exp_param++ * (1.0 / 16.0)); - max_scale= FFMAX(max_scale, v); - n = *ptr++; - do { - *q++ = v; - } while (--n); - } - s->max_exponent[ch] = max_scale; -} - -static void encode_exp_vlc(WMACodecContext *s, int ch, const int *exp_param){ - int last_exp; - const uint16_t *ptr; - float *q, *q_end; - - ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; - q = s->exponents[ch]; - q_end = q + s->block_len; - if (s->version == 1) { - last_exp= *exp_param++; - assert(last_exp-10 >= 0 && last_exp-10 < 32); - put_bits(&s->pb, 5, last_exp - 10); - q+= *ptr++; - }else - last_exp = 36; - while (q < q_end) { - int exp = *exp_param++; - int code = exp - last_exp + 60; - assert(code >= 0 && code < 120); - put_bits(&s->pb, ff_aac_scalefactor_bits[code], ff_aac_scalefactor_code[code]); - /* XXX: use a table */ - q+= *ptr++; - last_exp= exp; - } -} - -static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], int total_gain){ - int v, bsize, ch, coef_nb_bits, parse_exponents; - float mdct_norm; - int nb_coefs[MAX_CHANNELS]; - static const int fixed_exp[25]={20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20}; - - //FIXME remove duplication relative to decoder - if (s->use_variable_block_len) { - assert(0); //FIXME not implemented - }else{ - /* fixed block len */ - s->next_block_len_bits = s->frame_len_bits; - s->prev_block_len_bits = s->frame_len_bits; - s->block_len_bits = s->frame_len_bits; - } - - s->block_len = 1 << s->block_len_bits; -// assert((s->block_pos + s->block_len) <= s->frame_len); - bsize = s->frame_len_bits - s->block_len_bits; - - //FIXME factor - v = s->coefs_end[bsize] - s->coefs_start; - for(ch = 0; ch < s->nb_channels; ch++) - nb_coefs[ch] = v; - { - int n4 = s->block_len / 2; - mdct_norm = 1.0 / (float)n4; - if (s->version == 1) { - mdct_norm *= sqrt(n4); - } - } - - if (s->nb_channels == 2) { - put_bits(&s->pb, 1, s->ms_stereo= 1); - } - - for(ch = 0; ch < s->nb_channels; ch++) { - s->channel_coded[ch] = 1; //FIXME only set channel_coded when needed, instead of always - if (s->channel_coded[ch]) { - init_exp(s, ch, fixed_exp); - } - } - - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - WMACoef *coefs1; - float *coefs, *exponents, mult; - int i, n; - - coefs1 = s->coefs1[ch]; - exponents = s->exponents[ch]; - mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; - mult *= mdct_norm; - coefs = src_coefs[ch]; - if (s->use_noise_coding && 0) { - assert(0); //FIXME not implemented - } else { - coefs += s->coefs_start; - n = nb_coefs[ch]; - for(i = 0;i < n; i++){ - double t= *coefs++ / (exponents[i] * mult); - if(t<-32768 || t>32767) - return -1; - - coefs1[i] = lrint(t); - } - } - } - } - - v = 0; - for(ch = 0; ch < s->nb_channels; ch++) { - int a = s->channel_coded[ch]; - put_bits(&s->pb, 1, a); - v |= a; - } - - if (!v) - return 1; - - for(v= total_gain-1; v>=127; v-= 127) - put_bits(&s->pb, 7, 127); - put_bits(&s->pb, 7, v); - - coef_nb_bits= ff_wma_total_gain_to_bits(total_gain); - - if (s->use_noise_coding) { - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - int i, n; - n = s->exponent_high_sizes[bsize]; - for(i=0;ipb, 1, s->high_band_coded[ch][i]= 0); - if (0) - nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; - } - } - } - } - - parse_exponents = 1; - if (s->block_len_bits != s->frame_len_bits) { - put_bits(&s->pb, 1, parse_exponents); - } - - if (parse_exponents) { - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - if (s->use_exp_vlc) { - encode_exp_vlc(s, ch, fixed_exp); - } else { - assert(0); //FIXME not implemented -// encode_exp_lsp(s, ch); - } - } - } - } else { - assert(0); //FIXME not implemented - } - - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - int run, tindex; - WMACoef *ptr, *eptr; - tindex = (ch == 1 && s->ms_stereo); - ptr = &s->coefs1[ch][0]; - eptr = ptr + nb_coefs[ch]; - - run=0; - for(;ptr < eptr; ptr++){ - if(*ptr){ - int level= *ptr; - int abs_level= FFABS(level); - int code= 0; - if(abs_level <= s->coef_vlcs[tindex]->max_level){ - if(run < s->coef_vlcs[tindex]->levels[abs_level-1]) - code= run + s->int_table[tindex][abs_level-1]; - } - - assert(code < s->coef_vlcs[tindex]->n); - put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[code], s->coef_vlcs[tindex]->huffcodes[code]); - - if(code == 0){ - if(1<avctx->flags & CODEC_FLAG_BITEXACT)) abs_level=0x71A; - - put_bits(&s->pb, coef_nb_bits, abs_level); - put_bits(&s->pb, s->frame_len_bits, run); - } - put_bits(&s->pb, 1, level < 0); //FIXME the sign is fliped somewhere - run=0; - }else{ - run++; - } - } - if(run) - put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[1], s->coef_vlcs[tindex]->huffcodes[1]); - } - if (s->version == 1 && s->nb_channels >= 2) { - align_put_bits(&s->pb); - } - } - return 0; -} - -static int encode_frame(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], uint8_t *buf, int buf_size, int total_gain){ - init_put_bits(&s->pb, buf, buf_size); - - if (s->use_bit_reservoir) { - assert(0);//FIXME not implemented - }else{ - if(encode_block(s, src_coefs, total_gain) < 0) - return INT_MAX; - } - - align_put_bits(&s->pb); - - return put_bits_count(&s->pb)/8 - s->block_align; -} - -static int encode_superframe(AVCodecContext *avctx, - unsigned char *buf, int buf_size, void *data){ - WMACodecContext *s = avctx->priv_data; - short *samples = data; - int i, total_gain; - - s->block_len_bits= s->frame_len_bits; //required by non variable block len - s->block_len = 1 << s->block_len_bits; - - apply_window_and_mdct(avctx, samples, avctx->frame_size); - - if (s->ms_stereo) { - float a, b; - int i; - - for(i = 0; i < s->block_len; i++) { - a = s->coefs[0][i]*0.5; - b = s->coefs[1][i]*0.5; - s->coefs[0][i] = a + b; - s->coefs[1][i] = a - b; - } - } - -#if 1 - total_gain= 128; - for(i=64; i; i>>=1){ - int error= encode_frame(s, s->coefs, buf, buf_size, total_gain-i); - if(error<0) - total_gain-= i; - } -#else - total_gain= 90; - best= encode_frame(s, s->coefs, buf, buf_size, total_gain); - for(i=32; i; i>>=1){ - int scoreL= encode_frame(s, s->coefs, buf, buf_size, total_gain-i); - int scoreR= encode_frame(s, s->coefs, buf, buf_size, total_gain+i); - av_log(NULL, AV_LOG_ERROR, "%d %d %d (%d)\n", scoreL, best, scoreR, total_gain); - if(scoreL < FFMIN(best, scoreR)){ - best = scoreL; - total_gain -= i; - }else if(scoreR < best){ - best = scoreR; - total_gain += i; - } - } -#endif - - encode_frame(s, s->coefs, buf, buf_size, total_gain); - assert((put_bits_count(&s->pb) & 7) == 0); - i= s->block_align - (put_bits_count(&s->pb)+7)/8; - assert(i>=0); - while(i--) - put_bits(&s->pb, 8, 'N'); - - flush_put_bits(&s->pb); - return put_bits_ptr(&s->pb) - s->pb.buf; -} - -AVCodec wmav1_encoder = -{ - "wmav1", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WMAV1, - sizeof(WMACodecContext), - encode_init, - encode_superframe, - ff_wma_end, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), -}; - -AVCodec wmav2_encoder = -{ - "wmav2", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WMAV2, - sizeof(WMACodecContext), - encode_init, - encode_superframe, - ff_wma_end, - .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/wmaprodata.h b/tizen/distrib/ffmpeg/libavcodec/wmaprodata.h deleted file mode 100644 index 5382479..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmaprodata.h +++ /dev/null @@ -1,604 +0,0 @@ -/* - * WMA 9/3/PRO compatible decoder - * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion - * Copyright (c) 2008 - 2009 Sascha Sommer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief tables for wmapro decoding - */ - -#ifndef AVCODEC_WMAPRODATA_H -#define AVCODEC_WMAPRODATA_H - -#include -#include - -/** - * @brief frequencies to divide the frequency spectrum into scale factor bands - */ -static const uint16_t critical_freq[] = { - 100, 200, 300, 400, 510, 630, 770, - 920, 1080, 1270, 1480, 1720, 2000, 2320, - 2700, 3150, 3700, 4400, 5300, 6400, 7700, - 9500, 12000, 15500, 20675, 28575, 41375, 63875, -}; - - -/** - * @name Huffman tables for DPCM-coded scale factors - * @{ - */ -#define HUFF_SCALE_SIZE 121 -#define HUFF_SCALE_MAXBITS 19 -static const uint16_t scale_huffcodes[HUFF_SCALE_SIZE] = { - 0xE639, 0xE6C2, 0xE6C1, 0xE6C0, 0xE63F, 0xE63E, 0xE63D, 0xE63C, - 0xE63B, 0xE63A, 0xE638, 0xE637, 0xE636, 0xE635, 0xE634, 0xE632, - 0xE633, 0xE620, 0x737B, 0xE610, 0xE611, 0xE612, 0xE613, 0xE614, - 0xE615, 0xE616, 0xE617, 0xE618, 0xE619, 0xE61A, 0xE61B, 0xE61C, - 0xE61D, 0xE61E, 0xE61F, 0xE6C3, 0xE621, 0xE622, 0xE623, 0xE624, - 0xE625, 0xE626, 0xE627, 0xE628, 0xE629, 0xE62A, 0xE62B, 0xE62C, - 0xE62D, 0xE62E, 0xE62F, 0xE630, 0xE631, 0x1CDF, 0x0E60, 0x0399, - 0x00E7, 0x001D, 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, 0x0006, - 0x0002, 0x0007, 0x0006, 0x000F, 0x0038, 0x0072, 0x039A, 0xE6C4, - 0xE6C5, 0xE6C6, 0xE6C7, 0xE6C8, 0xE6C9, 0xE6CA, 0xE6CB, 0xE6CC, - 0xE6CD, 0xE6CE, 0xE6CF, 0xE6D0, 0xE6D1, 0xE6D2, 0xE6D3, 0xE6D4, - 0xE6D5, 0xE6D6, 0xE6D7, 0xE6D8, 0xE6D9, 0xE6DA, 0xE6DB, 0xE6DC, - 0xE6DD, 0xE6DE, 0xE6DF, 0xE6E0, 0xE6E1, 0xE6E2, 0xE6E3, 0xE6E4, - 0xE6E5, 0xE6E6, 0xE6E7, 0xE6E8, 0xE6E9, 0xE6EA, 0xE6EB, 0xE6EC, - 0xE6ED, 0xE6EE, 0xE6EF, 0xE6F0, 0xE6F1, 0xE6F2, 0xE6F3, 0xE6F4, - 0xE6F5, -}; - -static const uint8_t scale_huffbits[HUFF_SCALE_SIZE] = { - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 18, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 16, 15, 13, - 11, 8, 5, 2, 1, 3, 5, 6, - 6, 7, 7, 7, 9, 10, 13, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, - 19, -}; -/** @} */ - - -/** - * @name Huffman, run and level tables for runlevel-coded scale factors - * @{ - */ -#define HUFF_SCALE_RL_SIZE 120 -#define HUFF_SCALE_RL_MAXBITS 21 -static const uint32_t scale_rl_huffcodes[HUFF_SCALE_RL_SIZE] = { - 0x00010C, 0x000001, 0x10FE2A, 0x000003, 0x000003, 0x000001, 0x000013, - 0x000020, 0x000029, 0x000014, 0x000016, 0x000045, 0x000049, 0x00002F, - 0x000042, 0x00008E, 0x00008F, 0x000129, 0x000009, 0x00000D, 0x0004AC, - 0x00002C, 0x000561, 0x0002E6, 0x00087C, 0x0002E2, 0x00095C, 0x000018, - 0x000001, 0x000016, 0x000044, 0x00002A, 0x000007, 0x000159, 0x000143, - 0x000128, 0x00015A, 0x00012D, 0x00002B, 0x0000A0, 0x000142, 0x00012A, - 0x0002EF, 0x0004AF, 0x00087D, 0x004AE9, 0x0043F9, 0x000067, 0x000199, - 0x002B05, 0x001583, 0x0021FE, 0x10FE2C, 0x000004, 0x00002E, 0x00010D, - 0x00000A, 0x000244, 0x000017, 0x000245, 0x000011, 0x00010E, 0x00012C, - 0x00002A, 0x00002F, 0x000121, 0x000046, 0x00087E, 0x0000BA, 0x000032, - 0x0087F0, 0x0056DC, 0x0002EC, 0x0043FA, 0x002B6F, 0x004AE8, 0x0002B7, - 0x10FE2B, 0x000001, 0x000051, 0x000010, 0x0002EE, 0x000B9C, 0x002576, - 0x000198, 0x0056DD, 0x0000CD, 0x000AC0, 0x000170, 0x004AEF, 0x00002D, - 0x0004AD, 0x0021FF, 0x0005CF, 0x002B04, 0x10FE29, 0x10FE28, 0x0002ED, - 0x002E74, 0x021FC4, 0x004AEE, 0x010FE3, 0x087F17, 0x000000, 0x000097, - 0x0002E3, 0x000ADA, 0x002575, 0x00173B, 0x0043FB, 0x002E75, 0x10FE2D, - 0x0015B6, 0x00056C, 0x000057, 0x000123, 0x000120, 0x00021E, 0x000172, - 0x0002B1, -}; - -static const uint8_t scale_rl_huffbits[HUFF_SCALE_RL_SIZE] = { - 9, 2, 21, 2, 4, 5, 5, - 6, 6, 7, 7, 7, 7, 6, - 7, 8, 8, 9, 10, 10, 11, - 12, 11, 12, 12, 12, 12, 11, - 4, 5, 7, 8, 9, 9, 9, - 9, 9, 9, 8, 8, 9, 9, - 12, 11, 12, 15, 15, 13, 15, - 14, 13, 14, 21, 5, 6, 9, - 10, 10, 11, 10, 11, 9, 9, - 6, 8, 9, 7, 12, 10, 12, - 16, 15, 12, 15, 14, 15, 10, - 21, 6, 7, 11, 12, 14, 14, - 15, 15, 14, 12, 11, 15, 12, - 11, 14, 13, 14, 21, 21, 12, - 16, 18, 15, 17, 20, 7, 8, - 12, 12, 14, 15, 15, 16, 21, - 13, 11, 7, 9, 9, 10, 11, - 10, -}; - - -static const uint8_t scale_rl_run[HUFF_SCALE_RL_SIZE] = { - 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, 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, 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, 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, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 0, 1, 0, 1, 0, 1, -}; - -static const uint8_t scale_rl_level[HUFF_SCALE_RL_SIZE] = { - 0, 0, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 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, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 8, 8, 9, 9, -}; -/** @} */ - - -/** - * @name Huffman, run and level codes for runlevel-coded coefficients - * @{ - */ -#define HUFF_COEF0_SIZE 272 -#define HUFF_COEF0_MAXBITS 21 -static const uint32_t coef0_huffcodes[HUFF_COEF0_SIZE] = { - 0x00004A, 0x00002B, 0x000000, 0x000003, 0x000006, 0x000009, 0x00000F, - 0x000010, 0x000016, 0x000011, 0x000016, 0x000028, 0x00002F, 0x000026, - 0x000029, 0x000045, 0x000055, 0x00005D, 0x000042, 0x00004E, 0x000051, - 0x00005E, 0x00008D, 0x0000A8, 0x0000AD, 0x000080, 0x000096, 0x00009F, - 0x0000AA, 0x0000BE, 0x00011C, 0x000153, 0x000158, 0x000170, 0x000104, - 0x00010D, 0x000105, 0x000103, 0x00012F, 0x000177, 0x000175, 0x000157, - 0x000174, 0x000225, 0x00023B, 0x00020D, 0x00021F, 0x000281, 0x00027B, - 0x000282, 0x0002AC, 0x0002FD, 0x00044F, 0x000478, 0x00044D, 0x0002EC, - 0x00044E, 0x000564, 0x000409, 0x00040B, 0x000501, 0x000545, 0x0004F3, - 0x000541, 0x00043B, 0x0004F1, 0x0004F4, 0x0008FD, 0x000A94, 0x000811, - 0x000B88, 0x000B91, 0x000B93, 0x0008EA, 0x000899, 0x000B8A, 0x000972, - 0x0009E5, 0x000A8F, 0x000A84, 0x000A8E, 0x000A00, 0x000830, 0x0008E8, - 0x000B95, 0x000871, 0x00083A, 0x000814, 0x000873, 0x000BFE, 0x001728, - 0x001595, 0x001712, 0x00102A, 0x001021, 0x001729, 0x00152E, 0x0013C3, - 0x001721, 0x001597, 0x00151B, 0x0010F2, 0x001403, 0x001703, 0x001503, - 0x001708, 0x0013C1, 0x00170E, 0x00170C, 0x0010E1, 0x0011EA, 0x001020, - 0x001500, 0x0017FA, 0x001704, 0x001705, 0x0017F0, 0x0017FB, 0x0021E6, - 0x002B2D, 0x0020C6, 0x002B29, 0x002E4A, 0x0023AC, 0x001519, 0x0023F3, - 0x002B2C, 0x0021C0, 0x0017FE, 0x0023D7, 0x0017F9, 0x0012E7, 0x0013C0, - 0x002261, 0x0023D3, 0x002057, 0x002056, 0x0021D2, 0x0020C7, 0x0023D2, - 0x0020EC, 0x0044C0, 0x002FE2, 0x00475B, 0x002A03, 0x002FE3, 0x0021E2, - 0x0021D0, 0x002A31, 0x002E13, 0x002E05, 0x0047E5, 0x00000E, 0x000024, - 0x000088, 0x0000B9, 0x00010C, 0x000224, 0x0002B3, 0x000283, 0x0002ED, - 0x00047B, 0x00041E, 0x00043D, 0x0004F5, 0x0005FD, 0x000A92, 0x000B96, - 0x000838, 0x000971, 0x000B83, 0x000B80, 0x000BF9, 0x0011D3, 0x0011E8, - 0x0011D7, 0x001527, 0x0011F8, 0x001073, 0x0010F0, 0x0010E4, 0x0017F8, - 0x001062, 0x001402, 0x0017E3, 0x00151A, 0x001077, 0x00152B, 0x00170D, - 0x0021D3, 0x002E41, 0x0013C2, 0x000029, 0x0000A9, 0x00025D, 0x000419, - 0x000544, 0x000B8B, 0x0009E4, 0x0011D2, 0x001526, 0x001724, 0x0012E6, - 0x00150B, 0x0017FF, 0x002E26, 0x002E4B, 0x002B28, 0x0021E3, 0x002A14, - 0x00475A, 0x002E12, 0x000057, 0x00023E, 0x000A90, 0x000BF0, 0x001072, - 0x001502, 0x0023D6, 0x0020ED, 0x002A30, 0x0044C7, 0x00008C, 0x00047F, - 0x00152A, 0x002262, 0x002E04, 0x0000A1, 0x0005F9, 0x000173, 0x000875, - 0x000171, 0x00152D, 0x0002E3, 0x0017E2, 0x0002AD, 0x0021C1, 0x000479, - 0x0021E7, 0x00041F, 0x005C4E, 0x000543, 0x005C4F, 0x000A91, 0x00898D, - 0x000B97, 0x008746, 0x000970, 0x008745, 0x000B85, 0x00A856, 0x00152F, - 0x010E8E, 0x0010E5, 0x00A857, 0x00170F, 0x021D11, 0x002A58, 0x010E8F, - 0x002E40, 0x021D13, 0x002A59, 0x043A25, 0x002A02, 0x043A21, 0x0044C1, - 0x087448, 0x0047E4, 0x043A20, 0x00542A, 0x087449, 0x00898C, -}; - -static const uint8_t coef0_huffbits[HUFF_COEF0_SIZE] = { - 8, 7, 2, 3, 3, 4, 4, - 5, 5, 6, 6, 6, 6, 7, - 7, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, - 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 13, - 12, 12, 12, 12, 12, 12, 13, - 13, 13, 13, 13, 13, 13, 12, - 12, 13, 13, 13, 13, 13, 13, - 13, 13, 14, 14, 13, 13, 14, - 13, 13, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 13, 14, - 14, 14, 14, 14, 14, 14, 15, - 14, 15, 14, 14, 14, 14, 14, - 14, 15, 14, 14, 14, 14, 14, - 14, 14, 15, 15, 15, 15, 14, - 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 4, 7, - 8, 9, 10, 10, 10, 11, 11, - 11, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 13, 14, - 15, 14, 14, 6, 9, 11, 12, - 12, 12, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 15, 15, - 15, 15, 7, 10, 12, 13, 14, - 14, 14, 15, 15, 15, 8, 11, - 13, 14, 15, 9, 12, 9, 13, - 10, 13, 10, 14, 11, 15, 11, - 15, 12, 15, 12, 15, 12, 16, - 12, 17, 13, 17, 13, 17, 13, - 18, 14, 17, 14, 19, 14, 18, - 14, 19, 14, 20, 15, 20, 15, - 21, 15, 20, 16, 21, 16, -}; - - -#define HUFF_COEF1_SIZE 244 -#define HUFF_COEF1_MAXBITS 22 -static const uint32_t coef1_huffcodes[HUFF_COEF1_SIZE] = { - 0x0001E2, 0x00007F, 0x000000, 0x000002, 0x000008, 0x00000E, 0x000019, - 0x00002F, 0x000037, 0x000060, 0x00006C, 0x000095, 0x0000C6, 0x0000F0, - 0x00012E, 0x000189, 0x0001A5, 0x0001F8, 0x000253, 0x00030A, 0x000344, - 0x00034D, 0x0003F2, 0x0004BD, 0x0005D7, 0x00062A, 0x00068B, 0x000693, - 0x000797, 0x00097D, 0x000BAB, 0x000C52, 0x000C5E, 0x000D21, 0x000D20, - 0x000F1A, 0x000FCE, 0x000FD1, 0x0012F1, 0x001759, 0x0018AC, 0x0018A7, - 0x0018BF, 0x001A2B, 0x001E52, 0x001E50, 0x001E31, 0x001FB8, 0x0025E6, - 0x0025E7, 0x002EB4, 0x002EB7, 0x003169, 0x00315B, 0x00317C, 0x00316C, - 0x0034CA, 0x00348D, 0x003F40, 0x003CA2, 0x003F76, 0x004BC3, 0x004BE5, - 0x003F73, 0x004BF8, 0x004BF9, 0x006131, 0x00628B, 0x006289, 0x0062DA, - 0x00628A, 0x0062D4, 0x006997, 0x0062B4, 0x006918, 0x00794D, 0x007E7B, - 0x007E87, 0x007EEA, 0x00794E, 0x00699D, 0x007967, 0x00699F, 0x0062DB, - 0x007E7A, 0x007EEB, 0x00BAC0, 0x0097C9, 0x00C537, 0x00C5AB, 0x00D233, - 0x00D338, 0x00BAC1, 0x00D23D, 0x012F91, 0x00D339, 0x00FDC8, 0x00D23C, - 0x00FDDC, 0x00FDC9, 0x00FDDD, 0x00D33C, 0x000003, 0x000016, 0x00003E, - 0x0000C3, 0x0001A1, 0x000347, 0x00062E, 0x000BAA, 0x000F2D, 0x001A2A, - 0x001E58, 0x00309B, 0x003CA3, 0x005D6A, 0x00629A, 0x006996, 0x00794F, - 0x007EE5, 0x00BAD7, 0x00C5AA, 0x00C5F4, 0x00FDDF, 0x00FDDE, 0x018A20, - 0x018A6D, 0x01A67B, 0x01A464, 0x025F21, 0x01F9E2, 0x01F9E3, 0x00000A, - 0x00003D, 0x000128, 0x0003C7, 0x000C24, 0x0018A3, 0x002EB1, 0x003CB2, - 0x00691F, 0x007E79, 0x000013, 0x0000BB, 0x00034E, 0x000D14, 0x0025FD, - 0x004BE7, 0x000024, 0x000188, 0x0007EF, 0x000035, 0x000308, 0x0012F2, - 0x00005C, 0x0003F6, 0x0025E0, 0x00006D, 0x000698, 0x000096, 0x000C25, - 0x0000C7, 0x000F1B, 0x0000F3, 0x0012FF, 0x000174, 0x001A66, 0x0001A0, - 0x003099, 0x0001E4, 0x00316B, 0x000252, 0x003F31, 0x00030B, 0x004BE6, - 0x000346, 0x0062FB, 0x00034F, 0x007966, 0x0003F5, 0x007E86, 0x0005D4, - 0x00C511, 0x00062C, 0x00C5F5, 0x000692, 0x00F299, 0x000795, 0x00F298, - 0x0007E9, 0x018A21, 0x00097E, 0x0175AD, 0x000C27, 0x01A67A, 0x000C57, - 0x02EB59, 0x000D22, 0x0314D9, 0x000F19, 0x03F3C2, 0x000FCD, 0x0348CB, - 0x0012F8, 0x04BE41, 0x0018A0, 0x03F3C1, 0x0018A1, 0x04BE40, 0x0018B7, - 0x0629B0, 0x001A64, 0x0D2329, 0x001E30, 0x03F3C3, 0x001F9F, 0x0BAD62, - 0x001F99, 0x0FCF00, 0x00309A, 0x0629B1, 0x002EB6, 0x175AC3, 0x00314C, - 0x069195, 0x003168, 0x0BAD63, 0x00348E, 0x175AC1, 0x003F30, 0x07E781, - 0x003F41, 0x0D2328, 0x003F42, 0x1F9E03, 0x004BC2, 0x175AC2, 0x003F74, - 0x175AC0, 0x005D61, 0x3F3C05, 0x006130, 0x3F3C04, 0x0062B5, -}; - -static const uint8_t coef1_huffbits[HUFF_COEF1_SIZE] = { - 9, 7, 2, 3, 4, 4, 5, - 6, 6, 7, 7, 8, 8, 8, - 9, 9, 9, 9, 10, 10, 10, - 10, 10, 11, 11, 11, 11, 11, - 11, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 15, 15, - 14, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, - 15, 15, 16, 16, 16, 16, 16, - 16, 16, 16, 17, 16, 16, 16, - 16, 16, 16, 16, 3, 5, 6, - 8, 9, 10, 11, 12, 12, 13, - 13, 14, 14, 15, 15, 15, 15, - 15, 16, 16, 16, 16, 16, 17, - 17, 17, 17, 18, 17, 17, 4, - 6, 9, 10, 12, 13, 14, 14, - 15, 15, 5, 8, 10, 12, 14, - 15, 6, 9, 11, 6, 10, 13, - 7, 10, 14, 7, 11, 8, 12, - 8, 12, 8, 13, 9, 13, 9, - 14, 9, 14, 10, 14, 10, 15, - 10, 15, 10, 15, 10, 15, 11, - 16, 11, 16, 11, 16, 11, 16, - 11, 17, 12, 17, 12, 17, 12, - 18, 12, 18, 12, 18, 12, 18, - 13, 19, 13, 18, 13, 19, 13, - 19, 13, 20, 13, 18, 13, 20, - 13, 20, 14, 19, 14, 21, 14, - 19, 14, 20, 14, 21, 14, 19, - 14, 20, 14, 21, 15, 21, 14, - 21, 15, 22, 15, 22, 15, -}; - - -static const uint16_t coef0_run[HUFF_COEF0_SIZE] = { - 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, 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, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, - 2, 3, 4, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, -}; - -static const float coef0_level[HUFF_COEF0_SIZE] = { - 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, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 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, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, - 5, 5, 5, 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, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, - 25, 26, 26, 27, 27, 28, -}; - - -static const uint16_t coef1_run[HUFF_COEF1_SIZE] = { - 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, 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, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, - 2, 3, 4, 5, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, - 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, -}; - -static const float coef1_level[HUFF_COEF1_SIZE] = { - 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, 2, 2, 2, 2, 2, 2, - 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, 4, 4, - 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, - 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, - 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, - 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, - 46, 47, 47, 48, 48, 49, 49, 50, 51, 52, -}; -/** @} */ - - -/** - * @name Huffman and vector lookup tables for vector-coded coefficients - * @{ - */ -#define HUFF_VEC4_SIZE 127 -#define HUFF_VEC4_MAXBITS 14 -static const uint16_t vec4_huffcodes[HUFF_VEC4_SIZE] = { - 0x0019, 0x0027, 0x00F2, 0x03BA, 0x0930, 0x1267, 0x0031, 0x0030, - 0x0097, 0x0221, 0x058B, 0x0124, 0x00EB, 0x01D4, 0x03D8, 0x0584, - 0x0364, 0x045F, 0x0F66, 0x0931, 0x24CD, 0x002F, 0x0039, 0x00E8, - 0x02C3, 0x078A, 0x0037, 0x0029, 0x0084, 0x01B1, 0x00ED, 0x0086, - 0x00F9, 0x03AB, 0x01EB, 0x08BC, 0x011E, 0x00F3, 0x0220, 0x058A, - 0x00EC, 0x008E, 0x012B, 0x01EA, 0x0119, 0x04B0, 0x04B1, 0x03B8, - 0x0691, 0x0365, 0x01ED, 0x049A, 0x0EA9, 0x0EA8, 0x08BD, 0x24CC, - 0x0026, 0x0035, 0x00DB, 0x02C4, 0x07B2, 0x0038, 0x002B, 0x007F, - 0x01B3, 0x00F4, 0x0091, 0x0116, 0x03BB, 0x0215, 0x0932, 0x002D, - 0x002A, 0x008A, 0x01DE, 0x0028, 0x0020, 0x005C, 0x0090, 0x0068, - 0x01EE, 0x00E9, 0x008D, 0x012A, 0x0087, 0x005D, 0x0118, 0x0349, - 0x01EF, 0x01E3, 0x08B9, 0x00F0, 0x00D3, 0x0214, 0x049B, 0x00DA, - 0x0089, 0x0125, 0x0217, 0x012D, 0x0690, 0x0094, 0x007D, 0x011F, - 0x007E, 0x0059, 0x0127, 0x01A5, 0x0111, 0x00F8, 0x045D, 0x03B9, - 0x0259, 0x0580, 0x02C1, 0x01DF, 0x0585, 0x0216, 0x0163, 0x01B0, - 0x03C4, 0x08B8, 0x078B, 0x0755, 0x0581, 0x0F67, 0x0000, -}; - -static const uint8_t vec4_huffbits[HUFF_VEC4_SIZE] = { - 5, 6, 8, 10, 12, 13, 6, 6, - 8, 10, 11, 9, 8, 9, 10, 11, - 10, 11, 12, 12, 14, 6, 6, 8, - 10, 11, 6, 6, 8, 9, 8, 8, - 8, 10, 9, 12, 9, 8, 10, 11, - 8, 8, 9, 9, 9, 11, 11, 10, - 11, 10, 9, 11, 12, 12, 12, 14, - 6, 6, 8, 10, 11, 6, 6, 7, - 9, 8, 8, 9, 10, 10, 12, 6, - 6, 8, 9, 6, 6, 7, 8, 7, - 9, 8, 8, 9, 8, 7, 9, 10, - 9, 9, 12, 8, 8, 10, 11, 8, - 8, 9, 10, 9, 11, 8, 7, 9, - 7, 7, 9, 9, 9, 8, 11, 10, - 10, 11, 10, 9, 11, 10, 9, 9, - 10, 12, 11, 11, 11, 12, 1, -}; - - -#define HUFF_VEC2_SIZE 137 -#define HUFF_VEC2_MAXBITS 12 -static const uint16_t vec2_huffcodes[HUFF_VEC2_SIZE] = { - 0x055, 0x01C, 0x01A, 0x02B, 0x028, 0x067, 0x08B, 0x039, - 0x170, 0x10D, 0x2A5, 0x047, 0x464, 0x697, 0x523, 0x8CB, - 0x01B, 0x00E, 0x000, 0x010, 0x012, 0x036, 0x048, 0x04C, - 0x0C2, 0x09B, 0x171, 0x03B, 0x224, 0x34A, 0x2D6, 0x019, - 0x00F, 0x002, 0x014, 0x017, 0x006, 0x05D, 0x054, 0x0C7, - 0x0B4, 0x192, 0x10E, 0x233, 0x043, 0x02C, 0x00F, 0x013, - 0x006, 0x02F, 0x02C, 0x068, 0x077, 0x0DF, 0x111, 0x1A4, - 0x16A, 0x2A4, 0x027, 0x011, 0x018, 0x02D, 0x00F, 0x04A, - 0x040, 0x097, 0x01F, 0x11B, 0x022, 0x16D, 0x066, 0x035, - 0x005, 0x02B, 0x049, 0x009, 0x075, 0x0CB, 0x0AA, 0x187, - 0x106, 0x08A, 0x047, 0x060, 0x06E, 0x01D, 0x074, 0x0C4, - 0x01E, 0x118, 0x1A7, 0x038, 0x042, 0x053, 0x076, 0x0A8, - 0x0CA, 0x082, 0x110, 0x18D, 0x12D, 0x0B9, 0x0C8, 0x0DE, - 0x01C, 0x0AB, 0x113, 0x18C, 0x10F, 0x09A, 0x0A5, 0x0B7, - 0x11A, 0x186, 0x1A6, 0x259, 0x153, 0x18A, 0x193, 0x020, - 0x10C, 0x046, 0x03A, 0x107, 0x149, 0x16C, 0x2D7, 0x225, - 0x258, 0x316, 0x696, 0x317, 0x042, 0x522, 0x290, 0x8CA, - 0x001, -}; - -static const uint8_t vec2_huffbits[HUFF_VEC2_SIZE] = { - 7, 6, 6, 6, 7, 7, 8, 9, - 9, 10, 10, 11, 11, 11, 12, 12, - 6, 4, 5, 5, 6, 6, 7, 8, - 8, 9, 9, 10, 10, 10, 11, 6, - 4, 5, 5, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 6, 5, 5, - 6, 6, 7, 7, 8, 8, 9, 9, - 10, 10, 7, 6, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10, 7, 6, - 7, 7, 7, 8, 8, 8, 9, 9, - 10, 8, 7, 7, 7, 8, 8, 8, - 9, 9, 9, 9, 8, 8, 8, 8, - 8, 9, 9, 9, 9, 8, 8, 8, - 9, 9, 9, 9, 10, 9, 9, 9, - 9, 9, 9, 10, 9, 9, 9, 10, - 10, 11, 10, 10, 10, 10, 11, 10, - 10, 10, 11, 10, 11, 12, 11, 12, - 3, -}; - - -#define HUFF_VEC1_SIZE 101 -#define HUFF_VEC1_MAXBITS 11 -static const uint16_t vec1_huffcodes[HUFF_VEC1_SIZE] = { - 0x01A, 0x003, 0x017, 0x010, 0x00C, 0x009, 0x005, 0x000, - 0x00D, 0x00A, 0x009, 0x00C, 0x00F, 0x002, 0x004, 0x007, - 0x00B, 0x00F, 0x01C, 0x006, 0x010, 0x015, 0x01C, 0x022, - 0x03B, 0x00E, 0x019, 0x023, 0x034, 0x036, 0x03A, 0x047, - 0x008, 0x00A, 0x01E, 0x031, 0x037, 0x050, 0x053, 0x06B, - 0x06F, 0x08C, 0x0E8, 0x0EA, 0x0EB, 0x016, 0x03E, 0x03F, - 0x06C, 0x089, 0x08A, 0x0A3, 0x0A4, 0x0D4, 0x0DD, 0x0EC, - 0x0EE, 0x11A, 0x1D2, 0x024, 0x025, 0x02E, 0x027, 0x0C2, - 0x0C0, 0x0DA, 0x0DB, 0x111, 0x144, 0x116, 0x14A, 0x145, - 0x1B8, 0x1AB, 0x1DA, 0x1DE, 0x1DB, 0x1DF, 0x236, 0x237, - 0x3A6, 0x3A7, 0x04D, 0x04C, 0x05E, 0x05F, 0x183, 0x182, - 0x186, 0x221, 0x187, 0x220, 0x22E, 0x22F, 0x296, 0x354, - 0x297, 0x355, 0x372, 0x373, 0x016, -}; - -static const uint8_t vec1_huffbits[HUFF_VEC1_SIZE] = { - 7, 6, 5, 5, 5, 5, 5, 5, - 4, 4, 4, 4, 4, 5, 5, 5, - 5, 5, 5, 6, 6, 6, 6, 6, - 6, 7, 7, 7, 7, 7, 7, 7, - 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, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 5, -}; - - -static const uint16_t symbol_to_vec4[HUFF_VEC4_SIZE] = { - 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, - 20, 32, 33, 34, 35, 48, 49, 50, 64, 65, - 80, 256, 257, 258, 259, 260, 272, 273, 274, 275, - 288, 289, 290, 304, 305, 320, 512, 513, 514, 515, - 528, 529, 530, 544, 545, 560, 768, 769, 770, 784, - 785, 800, 1024, 1025, 1040, 1280, 4096, 4097, 4098, 4099, - 4100, 4112, 4113, 4114, 4115, 4128, 4129, 4130, 4144, 4145, - 4160, 4352, 4353, 4354, 4355, 4368, 4369, 4370, 4384, 4385, - 4400, 4608, 4609, 4610, 4624, 4625, 4640, 4864, 4865, 4880, - 5120, 8192, 8193, 8194, 8195, 8208, 8209, 8210, 8224, 8225, - 8240, 8448, 8449, 8450, 8464, 8465, 8480, 8704, 8705, 8720, - 8960, 12288, 12289, 12290, 12304, 12305, 12320, 12544, 12545, 12560, - 12800, 16384, 16385, 16400, 16640, 20480, 0, -}; - - -static const uint8_t symbol_to_vec2[HUFF_VEC2_SIZE] = { - 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 112, 113, 114, 115, 116, 117, 118, 119, 120, 128, 129, 130, 131, 132, - 133, 134, 135, 144, 145, 146, 147, 148, 149, 150, 160, 161, 162, 163, 164, - 165, 176, 177, 178, 179, 180, 192, 193, 194, 195, 208, 209, 210, 224, 225, - 240, 0, -}; -/** @} */ - - -/** - * @brief decorrelation matrix for multichannel streams - **/ -static const float default_decorrelation_matrices[] = { - 1.000000, 0.707031, -0.707031, 0.707031, 0.707031, 0.578125, 0.707031, - 0.410156, 0.578125, -0.707031, 0.410156, 0.578125, 0.000000, -0.816406, - 0.500000, 0.652344, 0.500000, 0.269531, 0.500000, 0.269531, -0.500000, - -0.652344, 0.500000, -0.269531, -0.500000, 0.652344, 0.500000, -0.652344, - 0.500000, -0.269531, 0.445312, 0.601562, 0.511719, 0.371094, 0.195312, - 0.445312, 0.371094, -0.195312, -0.601562, -0.511719, 0.445312, 0.000000, - -0.632812, 0.000000, 0.632812, 0.445312, -0.371094, -0.195312, 0.601562, - -0.511719, 0.445312, -0.601562, 0.511719, -0.371094, 0.195312, 0.410156, - 0.558594, 0.500000, 0.410156, 0.289062, 0.148438, 0.410156, 0.410156, - 0.000000, -0.410156, -0.578125, -0.410156, 0.410156, 0.148438, -0.500000, - -0.410156, 0.289062, 0.558594, 0.410156, -0.148438, -0.500000, 0.410156, - 0.289062, -0.558594, 0.410156, -0.410156, 0.000000, 0.410156, -0.578125, - 0.410156, 0.410156, -0.558594, 0.500000, -0.410156, 0.289062, -0.148438, -}; - -/** - * @brief default decorrelation matrix offsets - */ -static const float * const default_decorrelation[] = { - NULL, - &default_decorrelation_matrices[0], - &default_decorrelation_matrices[1], - &default_decorrelation_matrices[5], - &default_decorrelation_matrices[14], - &default_decorrelation_matrices[30], - &default_decorrelation_matrices[55] -}; - -#endif /* AVCODEC_WMAPRODATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/wmaprodec.c b/tizen/distrib/ffmpeg/libavcodec/wmaprodec.c deleted file mode 100644 index 3eca101..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmaprodec.c +++ /dev/null @@ -1,1579 +0,0 @@ -/* - * Wmapro compatible decoder - * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion - * Copyright (c) 2008 - 2009 Sascha Sommer, Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief wmapro decoder implementation - * Wmapro is an MDCT based codec comparable to wma standard or AAC. - * The decoding therefore consists of the following steps: - * - bitstream decoding - * - reconstruction of per-channel data - * - rescaling and inverse quantization - * - IMDCT - * - windowing and overlapp-add - * - * The compressed wmapro bitstream is split into individual packets. - * Every such packet contains one or more wma frames. - * The compressed frames may have a variable length and frames may - * cross packet boundaries. - * Common to all wmapro frames is the number of samples that are stored in - * a frame. - * The number of samples and a few other decode flags are stored - * as extradata that has to be passed to the decoder. - * - * The wmapro frames themselves are again split into a variable number of - * subframes. Every subframe contains the data for 2^N time domain samples - * where N varies between 7 and 12. - * - * Example wmapro bitstream (in samples): - * - * || packet 0 || packet 1 || packet 2 packets - * --------------------------------------------------- - * || frame 0 || frame 1 || frame 2 || frames - * --------------------------------------------------- - * || | | || | | | || || subframes of channel 0 - * --------------------------------------------------- - * || | | || | | | || || subframes of channel 1 - * --------------------------------------------------- - * - * The frame layouts for the individual channels of a wma frame does not need - * to be the same. - * - * However, if the offsets and lengths of several subframes of a frame are the - * same, the subframes of the channels can be grouped. - * Every group may then use special coding techniques like M/S stereo coding - * to improve the compression ratio. These channel transformations do not - * need to be applied to a whole subframe. Instead, they can also work on - * individual scale factor bands (see below). - * The coefficients that carry the audio signal in the frequency domain - * are transmitted as huffman-coded vectors with 4, 2 and 1 elements. - * In addition to that, the encoder can switch to a runlevel coding scheme - * by transmitting subframe_length / 128 zero coefficients. - * - * Before the audio signal can be converted to the time domain, the - * coefficients have to be rescaled and inverse quantized. - * A subframe is therefore split into several scale factor bands that get - * scaled individually. - * Scale factors are submitted for every frame but they might be shared - * between the subframes of a channel. Scale factors are initially DPCM-coded. - * Once scale factors are shared, the differences are transmitted as runlevel - * codes. - * Every subframe length and offset combination in the frame layout shares a - * common quantization factor that can be adjusted for every channel by a - * modifier. - * After the inverse quantization, the coefficients get processed by an IMDCT. - * The resulting values are then windowed with a sine window and the first half - * of the values are added to the second half of the output from the previous - * subframe in order to reconstruct the output samples. - */ - -#include "avcodec.h" -#include "internal.h" -#include "get_bits.h" -#include "put_bits.h" -#include "wmaprodata.h" -#include "dsputil.h" -#include "wma.h" - -/** current decoder limitations */ -#define WMAPRO_MAX_CHANNELS 8 ///< max number of handled channels -#define MAX_SUBFRAMES 32 ///< max number of subframes per channel -#define MAX_BANDS 29 ///< max number of scale factor bands -#define MAX_FRAMESIZE 32768 ///< maximum compressed frame size - -#define WMAPRO_BLOCK_MAX_BITS 12 ///< log2 of max block size -#define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size -#define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) ///< possible block sizes - - -#define VLCBITS 9 -#define SCALEVLCBITS 8 -#define VEC4MAXDEPTH ((HUFF_VEC4_MAXBITS+VLCBITS-1)/VLCBITS) -#define VEC2MAXDEPTH ((HUFF_VEC2_MAXBITS+VLCBITS-1)/VLCBITS) -#define VEC1MAXDEPTH ((HUFF_VEC1_MAXBITS+VLCBITS-1)/VLCBITS) -#define SCALEMAXDEPTH ((HUFF_SCALE_MAXBITS+SCALEVLCBITS-1)/SCALEVLCBITS) -#define SCALERLMAXDEPTH ((HUFF_SCALE_RL_MAXBITS+VLCBITS-1)/VLCBITS) - -static VLC sf_vlc; ///< scale factor DPCM vlc -static VLC sf_rl_vlc; ///< scale factor run length vlc -static VLC vec4_vlc; ///< 4 coefficients per symbol -static VLC vec2_vlc; ///< 2 coefficients per symbol -static VLC vec1_vlc; ///< 1 coefficient per symbol -static VLC coef_vlc[2]; ///< coefficient run length vlc codes -static float sin64[33]; ///< sinus table for decorrelation - -/** - * @brief frame specific decoder context for a single channel - */ -typedef struct { - int16_t prev_block_len; ///< length of the previous block - uint8_t transmit_coefs; - uint8_t num_subframes; - uint16_t subframe_len[MAX_SUBFRAMES]; ///< subframe length in samples - uint16_t subframe_offset[MAX_SUBFRAMES]; ///< subframe positions in the current frame - uint8_t cur_subframe; ///< current subframe number - uint16_t decoded_samples; ///< number of already processed samples - uint8_t grouped; ///< channel is part of a group - int quant_step; ///< quantization step for the current subframe - int8_t reuse_sf; ///< share scale factors between subframes - int8_t scale_factor_step; ///< scaling step for the current subframe - int max_scale_factor; ///< maximum scale factor for the current subframe - int saved_scale_factors[2][MAX_BANDS]; ///< resampled and (previously) transmitted scale factor values - int8_t scale_factor_idx; ///< index for the transmitted scale factor values (used for resampling) - int* scale_factors; ///< pointer to the scale factor values used for decoding - uint8_t table_idx; ///< index in sf_offsets for the scale factor reference block - float* coeffs; ///< pointer to the subframe decode buffer - DECLARE_ALIGNED(16, float, out)[WMAPRO_BLOCK_MAX_SIZE + WMAPRO_BLOCK_MAX_SIZE / 2]; ///< output buffer -} WMAProChannelCtx; - -/** - * @brief channel group for channel transformations - */ -typedef struct { - uint8_t num_channels; ///< number of channels in the group - int8_t transform; ///< transform on / off - int8_t transform_band[MAX_BANDS]; ///< controls if the transform is enabled for a certain band - float decorrelation_matrix[WMAPRO_MAX_CHANNELS*WMAPRO_MAX_CHANNELS]; - float* channel_data[WMAPRO_MAX_CHANNELS]; ///< transformation coefficients -} WMAProChannelGrp; - -/** - * @brief main decoder context - */ -typedef struct WMAProDecodeCtx { - /* generic decoder variables */ - AVCodecContext* avctx; ///< codec context for av_log - DSPContext dsp; ///< accelerated DSP functions - uint8_t frame_data[MAX_FRAMESIZE + - FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data - PutBitContext pb; ///< context for filling the frame_data buffer - FFTContext mdct_ctx[WMAPRO_BLOCK_SIZES]; ///< MDCT context per block size - DECLARE_ALIGNED(16, float, tmp)[WMAPRO_BLOCK_MAX_SIZE]; ///< IMDCT output buffer - float* windows[WMAPRO_BLOCK_SIZES]; ///< windows for the different block sizes - - /* frame size dependent frame information (set during initialization) */ - uint32_t decode_flags; ///< used compression features - uint8_t len_prefix; ///< frame is prefixed with its length - uint8_t dynamic_range_compression; ///< frame contains DRC data - uint8_t bits_per_sample; ///< integer audio sample size for the unscaled IMDCT output (used to scale to [-1.0, 1.0]) - uint16_t samples_per_frame; ///< number of samples to output - uint16_t log2_frame_size; - int8_t num_channels; ///< number of channels in the stream (same as AVCodecContext.num_channels) - int8_t lfe_channel; ///< lfe channel index - uint8_t max_num_subframes; - uint8_t subframe_len_bits; ///< number of bits used for the subframe length - uint8_t max_subframe_len_bit; ///< flag indicating that the subframe is of maximum size when the first subframe length bit is 1 - uint16_t min_samples_per_subframe; - int8_t num_sfb[WMAPRO_BLOCK_SIZES]; ///< scale factor bands per block size - int16_t sfb_offsets[WMAPRO_BLOCK_SIZES][MAX_BANDS]; ///< scale factor band offsets (multiples of 4) - int8_t sf_offsets[WMAPRO_BLOCK_SIZES][WMAPRO_BLOCK_SIZES][MAX_BANDS]; ///< scale factor resample matrix - int16_t subwoofer_cutoffs[WMAPRO_BLOCK_SIZES]; ///< subwoofer cutoff values - - /* packet decode state */ - GetBitContext pgb; ///< bitstream reader context for the packet - uint8_t packet_offset; ///< frame offset in the packet - uint8_t packet_sequence_number; ///< current packet number - int num_saved_bits; ///< saved number of bits - int frame_offset; ///< frame offset in the bit reservoir - int subframe_offset; ///< subframe offset in the bit reservoir - uint8_t packet_loss; ///< set in case of bitstream error - uint8_t packet_done; ///< set when a packet is fully decoded - - /* frame decode state */ - uint32_t frame_num; ///< current frame number (not used for decoding) - GetBitContext gb; ///< bitstream reader context - int buf_bit_size; ///< buffer size in bits - float* samples; ///< current samplebuffer pointer - float* samples_end; ///< maximum samplebuffer pointer - uint8_t drc_gain; ///< gain for the DRC tool - int8_t skip_frame; ///< skip output step - int8_t parsed_all_subframes; ///< all subframes decoded? - - /* subframe/block decode state */ - int16_t subframe_len; ///< current subframe length - int8_t channels_for_cur_subframe; ///< number of channels that contain the subframe - int8_t channel_indexes_for_cur_subframe[WMAPRO_MAX_CHANNELS]; - int8_t num_bands; ///< number of scale factor bands - int16_t* cur_sfb_offsets; ///< sfb offsets for the current block - uint8_t table_idx; ///< index for the num_sfb, sfb_offsets, sf_offsets and subwoofer_cutoffs tables - int8_t esc_len; ///< length of escaped coefficients - - uint8_t num_chgroups; ///< number of channel groups - WMAProChannelGrp chgroup[WMAPRO_MAX_CHANNELS]; ///< channel group information - - WMAProChannelCtx channel[WMAPRO_MAX_CHANNELS]; ///< per channel data -} WMAProDecodeCtx; - - -/** - *@brief helper function to print the most important members of the context - *@param s context - */ -static void av_cold dump_context(WMAProDecodeCtx *s) -{ -#define PRINT(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %d\n", a, b); -#define PRINT_HEX(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %x\n", a, b); - - PRINT("ed sample bit depth", s->bits_per_sample); - PRINT_HEX("ed decode flags", s->decode_flags); - PRINT("samples per frame", s->samples_per_frame); - PRINT("log2 frame size", s->log2_frame_size); - PRINT("max num subframes", s->max_num_subframes); - PRINT("len prefix", s->len_prefix); - PRINT("num channels", s->num_channels); -} - -/** - *@brief Uninitialize the decoder and free all resources. - *@param avctx codec context - *@return 0 on success, < 0 otherwise - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - WMAProDecodeCtx *s = avctx->priv_data; - int i; - - for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) - ff_mdct_end(&s->mdct_ctx[i]); - - return 0; -} - -/** - *@brief Initialize the decoder. - *@param avctx codec context - *@return 0 on success, -1 otherwise - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - WMAProDecodeCtx *s = avctx->priv_data; - uint8_t *edata_ptr = avctx->extradata; - unsigned int channel_mask; - int i; - int log2_max_num_subframes; - int num_possible_block_sizes; - - s->avctx = avctx; - dsputil_init(&s->dsp, avctx); - init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); - - avctx->sample_fmt = SAMPLE_FMT_FLT; - - if (avctx->extradata_size >= 18) { - s->decode_flags = AV_RL16(edata_ptr+14); - channel_mask = AV_RL32(edata_ptr+2); - s->bits_per_sample = AV_RL16(edata_ptr); - /** dump the extradata */ - for (i = 0; i < avctx->extradata_size; i++) - dprintf(avctx, "[%x] ", avctx->extradata[i]); - dprintf(avctx, "\n"); - - } else { - av_log_ask_for_sample(avctx, "Unknown extradata size\n"); - return AVERROR_INVALIDDATA; - } - - /** generic init */ - s->log2_frame_size = av_log2(avctx->block_align) + 4; - - /** frame info */ - s->skip_frame = 1; /** skip first frame */ - s->packet_loss = 1; - s->len_prefix = (s->decode_flags & 0x40); - - if (!s->len_prefix) { - av_log_ask_for_sample(avctx, "no length prefix\n"); - return AVERROR_INVALIDDATA; - } - - /** get frame len */ - s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate, - 3, s->decode_flags); - - /** init previous block len */ - for (i = 0; i < avctx->channels; i++) - s->channel[i].prev_block_len = s->samples_per_frame; - - /** subframe info */ - log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3); - s->max_num_subframes = 1 << log2_max_num_subframes; - if (s->max_num_subframes == 16) - s->max_subframe_len_bit = 1; - s->subframe_len_bits = av_log2(log2_max_num_subframes) + 1; - - num_possible_block_sizes = log2_max_num_subframes + 1; - s->min_samples_per_subframe = s->samples_per_frame / s->max_num_subframes; - s->dynamic_range_compression = (s->decode_flags & 0x80); - - if (s->max_num_subframes > MAX_SUBFRAMES) { - av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %i\n", - s->max_num_subframes); - return AVERROR_INVALIDDATA; - } - - s->num_channels = avctx->channels; - - /** extract lfe channel position */ - s->lfe_channel = -1; - - if (channel_mask & 8) { - unsigned int mask; - for (mask = 1; mask < 16; mask <<= 1) { - if (channel_mask & mask) - ++s->lfe_channel; - } - } - - if (s->num_channels < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels); - return AVERROR_INVALIDDATA; - } else if (s->num_channels > WMAPRO_MAX_CHANNELS) { - av_log_ask_for_sample(avctx, "unsupported number of channels\n"); - return AVERROR_PATCHWELCOME; - } - - INIT_VLC_STATIC(&sf_vlc, SCALEVLCBITS, HUFF_SCALE_SIZE, - scale_huffbits, 1, 1, - scale_huffcodes, 2, 2, 616); - - INIT_VLC_STATIC(&sf_rl_vlc, VLCBITS, HUFF_SCALE_RL_SIZE, - scale_rl_huffbits, 1, 1, - scale_rl_huffcodes, 4, 4, 1406); - - INIT_VLC_STATIC(&coef_vlc[0], VLCBITS, HUFF_COEF0_SIZE, - coef0_huffbits, 1, 1, - coef0_huffcodes, 4, 4, 2108); - - INIT_VLC_STATIC(&coef_vlc[1], VLCBITS, HUFF_COEF1_SIZE, - coef1_huffbits, 1, 1, - coef1_huffcodes, 4, 4, 3912); - - INIT_VLC_STATIC(&vec4_vlc, VLCBITS, HUFF_VEC4_SIZE, - vec4_huffbits, 1, 1, - vec4_huffcodes, 2, 2, 604); - - INIT_VLC_STATIC(&vec2_vlc, VLCBITS, HUFF_VEC2_SIZE, - vec2_huffbits, 1, 1, - vec2_huffcodes, 2, 2, 562); - - INIT_VLC_STATIC(&vec1_vlc, VLCBITS, HUFF_VEC1_SIZE, - vec1_huffbits, 1, 1, - vec1_huffcodes, 2, 2, 562); - - /** calculate number of scale factor bands and their offsets - for every possible block size */ - for (i = 0; i < num_possible_block_sizes; i++) { - int subframe_len = s->samples_per_frame >> i; - int x; - int band = 1; - - s->sfb_offsets[i][0] = 0; - - for (x = 0; x < MAX_BANDS-1 && s->sfb_offsets[i][band - 1] < subframe_len; x++) { - int offset = (subframe_len * 2 * critical_freq[x]) - / s->avctx->sample_rate + 2; - offset &= ~3; - if (offset > s->sfb_offsets[i][band - 1]) - s->sfb_offsets[i][band++] = offset; - } - s->sfb_offsets[i][band - 1] = subframe_len; - s->num_sfb[i] = band - 1; - } - - - /** Scale factors can be shared between blocks of different size - as every block has a different scale factor band layout. - The matrix sf_offsets is needed to find the correct scale factor. - */ - - for (i = 0; i < num_possible_block_sizes; i++) { - int b; - for (b = 0; b < s->num_sfb[i]; b++) { - int x; - int offset = ((s->sfb_offsets[i][b] - + s->sfb_offsets[i][b + 1] - 1) << i) >> 1; - for (x = 0; x < num_possible_block_sizes; x++) { - int v = 0; - while (s->sfb_offsets[x][v + 1] << x < offset) - ++v; - s->sf_offsets[i][x][b] = v; - } - } - } - - /** init MDCT, FIXME: only init needed sizes */ - for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) - ff_mdct_init(&s->mdct_ctx[i], BLOCK_MIN_BITS+1+i, 1, - 1.0 / (1 << (BLOCK_MIN_BITS + i - 1)) - / (1 << (s->bits_per_sample - 1))); - - /** init MDCT windows: simple sinus window */ - for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) { - const int win_idx = WMAPRO_BLOCK_MAX_BITS - i; - ff_init_ff_sine_windows(win_idx); - s->windows[WMAPRO_BLOCK_SIZES - i - 1] = ff_sine_windows[win_idx]; - } - - /** calculate subwoofer cutoff values */ - for (i = 0; i < num_possible_block_sizes; i++) { - int block_size = s->samples_per_frame >> i; - int cutoff = (440*block_size + 3 * (s->avctx->sample_rate >> 1) - 1) - / s->avctx->sample_rate; - s->subwoofer_cutoffs[i] = av_clip(cutoff, 4, block_size); - } - - /** calculate sine values for the decorrelation matrix */ - for (i = 0; i < 33; i++) - sin64[i] = sin(i*M_PI / 64.0); - - if (avctx->debug & FF_DEBUG_BITSTREAM) - dump_context(s); - - avctx->channel_layout = channel_mask; - return 0; -} - -/** - *@brief Decode the subframe length. - *@param s context - *@param offset sample offset in the frame - *@return decoded subframe length on success, < 0 in case of an error - */ -static int decode_subframe_length(WMAProDecodeCtx *s, int offset) -{ - int frame_len_shift = 0; - int subframe_len; - - /** no need to read from the bitstream when only one length is possible */ - if (offset == s->samples_per_frame - s->min_samples_per_subframe) - return s->min_samples_per_subframe; - - /** 1 bit indicates if the subframe is of maximum length */ - if (s->max_subframe_len_bit) { - if (get_bits1(&s->gb)) - frame_len_shift = 1 + get_bits(&s->gb, s->subframe_len_bits-1); - } else - frame_len_shift = get_bits(&s->gb, s->subframe_len_bits); - - subframe_len = s->samples_per_frame >> frame_len_shift; - - /** sanity check the length */ - if (subframe_len < s->min_samples_per_subframe || - subframe_len > s->samples_per_frame) { - av_log(s->avctx, AV_LOG_ERROR, "broken frame: subframe_len %i\n", - subframe_len); - return AVERROR_INVALIDDATA; - } - return subframe_len; -} - -/** - *@brief Decode how the data in the frame is split into subframes. - * Every WMA frame contains the encoded data for a fixed number of - * samples per channel. The data for every channel might be split - * into several subframes. This function will reconstruct the list of - * subframes for every channel. - * - * If the subframes are not evenly split, the algorithm estimates the - * channels with the lowest number of total samples. - * Afterwards, for each of these channels a bit is read from the - * bitstream that indicates if the channel contains a subframe with the - * next subframe size that is going to be read from the bitstream or not. - * If a channel contains such a subframe, the subframe size gets added to - * the channel's subframe list. - * The algorithm repeats these steps until the frame is properly divided - * between the individual channels. - * - *@param s context - *@return 0 on success, < 0 in case of an error - */ -static int decode_tilehdr(WMAProDecodeCtx *s) -{ - uint16_t num_samples[WMAPRO_MAX_CHANNELS]; /** sum of samples for all currently known subframes of a channel */ - uint8_t contains_subframe[WMAPRO_MAX_CHANNELS]; /** flag indicating if a channel contains the current subframe */ - int channels_for_cur_subframe = s->num_channels; /** number of channels that contain the current subframe */ - int fixed_channel_layout = 0; /** flag indicating that all channels use the same subframe offsets and sizes */ - int min_channel_len = 0; /** smallest sum of samples (channels with this length will be processed first) */ - int c; - - /* Should never consume more than 3073 bits (256 iterations for the - * while loop when always the minimum amount of 128 samples is substracted - * from missing samples in the 8 channel case). - * 1 + BLOCK_MAX_SIZE * MAX_CHANNELS / BLOCK_MIN_SIZE * (MAX_CHANNELS + 4) - */ - - /** reset tiling information */ - for (c = 0; c < s->num_channels; c++) - s->channel[c].num_subframes = 0; - - memset(num_samples, 0, sizeof(num_samples)); - - if (s->max_num_subframes == 1 || get_bits1(&s->gb)) - fixed_channel_layout = 1; - - /** loop until the frame data is split between the subframes */ - do { - int subframe_len; - - /** check which channels contain the subframe */ - for (c = 0; c < s->num_channels; c++) { - if (num_samples[c] == min_channel_len) { - if (fixed_channel_layout || channels_for_cur_subframe == 1 || - (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) - contains_subframe[c] = 1; - else - contains_subframe[c] = get_bits1(&s->gb); - } else - contains_subframe[c] = 0; - } - - /** get subframe length, subframe_len == 0 is not allowed */ - if ((subframe_len = decode_subframe_length(s, min_channel_len)) <= 0) - return AVERROR_INVALIDDATA; - - /** add subframes to the individual channels and find new min_channel_len */ - min_channel_len += subframe_len; - for (c = 0; c < s->num_channels; c++) { - WMAProChannelCtx* chan = &s->channel[c]; - - if (contains_subframe[c]) { - if (chan->num_subframes >= MAX_SUBFRAMES) { - av_log(s->avctx, AV_LOG_ERROR, - "broken frame: num subframes > 31\n"); - return AVERROR_INVALIDDATA; - } - chan->subframe_len[chan->num_subframes] = subframe_len; - num_samples[c] += subframe_len; - ++chan->num_subframes; - if (num_samples[c] > s->samples_per_frame) { - av_log(s->avctx, AV_LOG_ERROR, "broken frame: " - "channel len > samples_per_frame\n"); - return AVERROR_INVALIDDATA; - } - } else if (num_samples[c] <= min_channel_len) { - if (num_samples[c] < min_channel_len) { - channels_for_cur_subframe = 0; - min_channel_len = num_samples[c]; - } - ++channels_for_cur_subframe; - } - } - } while (min_channel_len < s->samples_per_frame); - - for (c = 0; c < s->num_channels; c++) { - int i; - int offset = 0; - for (i = 0; i < s->channel[c].num_subframes; i++) { - dprintf(s->avctx, "frame[%i] channel[%i] subframe[%i]" - " len %i\n", s->frame_num, c, i, - s->channel[c].subframe_len[i]); - s->channel[c].subframe_offset[i] = offset; - offset += s->channel[c].subframe_len[i]; - } - } - - return 0; -} - -/** - *@brief Calculate a decorrelation matrix from the bitstream parameters. - *@param s codec context - *@param chgroup channel group for which the matrix needs to be calculated - */ -static void decode_decorrelation_matrix(WMAProDecodeCtx *s, - WMAProChannelGrp *chgroup) -{ - int i; - int offset = 0; - int8_t rotation_offset[WMAPRO_MAX_CHANNELS * WMAPRO_MAX_CHANNELS]; - memset(chgroup->decorrelation_matrix, 0, s->num_channels * - s->num_channels * sizeof(*chgroup->decorrelation_matrix)); - - for (i = 0; i < chgroup->num_channels * (chgroup->num_channels - 1) >> 1; i++) - rotation_offset[i] = get_bits(&s->gb, 6); - - for (i = 0; i < chgroup->num_channels; i++) - chgroup->decorrelation_matrix[chgroup->num_channels * i + i] = - get_bits1(&s->gb) ? 1.0 : -1.0; - - for (i = 1; i < chgroup->num_channels; i++) { - int x; - for (x = 0; x < i; x++) { - int y; - for (y = 0; y < i + 1; y++) { - float v1 = chgroup->decorrelation_matrix[x * chgroup->num_channels + y]; - float v2 = chgroup->decorrelation_matrix[i * chgroup->num_channels + y]; - int n = rotation_offset[offset + x]; - float sinv; - float cosv; - - if (n < 32) { - sinv = sin64[n]; - cosv = sin64[32 - n]; - } else { - sinv = sin64[64 - n]; - cosv = -sin64[n - 32]; - } - - chgroup->decorrelation_matrix[y + x * chgroup->num_channels] = - (v1 * sinv) - (v2 * cosv); - chgroup->decorrelation_matrix[y + i * chgroup->num_channels] = - (v1 * cosv) + (v2 * sinv); - } - } - offset += i; - } -} - -/** - *@brief Decode channel transformation parameters - *@param s codec context - *@return 0 in case of success, < 0 in case of bitstream errors - */ -static int decode_channel_transform(WMAProDecodeCtx* s) -{ - int i; - /* should never consume more than 1921 bits for the 8 channel case - * 1 + MAX_CHANNELS * (MAX_CHANNELS + 2 + 3 * MAX_CHANNELS * MAX_CHANNELS - * + MAX_CHANNELS + MAX_BANDS + 1) - */ - - /** in the one channel case channel transforms are pointless */ - s->num_chgroups = 0; - if (s->num_channels > 1) { - int remaining_channels = s->channels_for_cur_subframe; - - if (get_bits1(&s->gb)) { - av_log_ask_for_sample(s->avctx, - "unsupported channel transform bit\n"); - return AVERROR_INVALIDDATA; - } - - for (s->num_chgroups = 0; remaining_channels && - s->num_chgroups < s->channels_for_cur_subframe; s->num_chgroups++) { - WMAProChannelGrp* chgroup = &s->chgroup[s->num_chgroups]; - float** channel_data = chgroup->channel_data; - chgroup->num_channels = 0; - chgroup->transform = 0; - - /** decode channel mask */ - if (remaining_channels > 2) { - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int channel_idx = s->channel_indexes_for_cur_subframe[i]; - if (!s->channel[channel_idx].grouped - && get_bits1(&s->gb)) { - ++chgroup->num_channels; - s->channel[channel_idx].grouped = 1; - *channel_data++ = s->channel[channel_idx].coeffs; - } - } - } else { - chgroup->num_channels = remaining_channels; - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int channel_idx = s->channel_indexes_for_cur_subframe[i]; - if (!s->channel[channel_idx].grouped) - *channel_data++ = s->channel[channel_idx].coeffs; - s->channel[channel_idx].grouped = 1; - } - } - - /** decode transform type */ - if (chgroup->num_channels == 2) { - if (get_bits1(&s->gb)) { - if (get_bits1(&s->gb)) { - av_log_ask_for_sample(s->avctx, - "unsupported channel transform type\n"); - } - } else { - chgroup->transform = 1; - if (s->num_channels == 2) { - chgroup->decorrelation_matrix[0] = 1.0; - chgroup->decorrelation_matrix[1] = -1.0; - chgroup->decorrelation_matrix[2] = 1.0; - chgroup->decorrelation_matrix[3] = 1.0; - } else { - /** cos(pi/4) */ - chgroup->decorrelation_matrix[0] = 0.70703125; - chgroup->decorrelation_matrix[1] = -0.70703125; - chgroup->decorrelation_matrix[2] = 0.70703125; - chgroup->decorrelation_matrix[3] = 0.70703125; - } - } - } else if (chgroup->num_channels > 2) { - if (get_bits1(&s->gb)) { - chgroup->transform = 1; - if (get_bits1(&s->gb)) { - decode_decorrelation_matrix(s, chgroup); - } else { - /** FIXME: more than 6 coupled channels not supported */ - if (chgroup->num_channels > 6) { - av_log_ask_for_sample(s->avctx, - "coupled channels > 6\n"); - } else { - memcpy(chgroup->decorrelation_matrix, - default_decorrelation[chgroup->num_channels], - chgroup->num_channels * chgroup->num_channels * - sizeof(*chgroup->decorrelation_matrix)); - } - } - } - } - - /** decode transform on / off */ - if (chgroup->transform) { - if (!get_bits1(&s->gb)) { - int i; - /** transform can be enabled for individual bands */ - for (i = 0; i < s->num_bands; i++) { - chgroup->transform_band[i] = get_bits1(&s->gb); - } - } else { - memset(chgroup->transform_band, 1, s->num_bands); - } - } - remaining_channels -= chgroup->num_channels; - } - } - return 0; -} - -/** - *@brief Extract the coefficients from the bitstream. - *@param s codec context - *@param c current channel number - *@return 0 on success, < 0 in case of bitstream errors - */ -static int decode_coeffs(WMAProDecodeCtx *s, int c) -{ - /* Integers 0..15 as single-precision floats. The table saves a - costly int to float conversion, and storing the values as - integers allows fast sign-flipping. */ - static const int fval_tab[16] = { - 0x00000000, 0x3f800000, 0x40000000, 0x40400000, - 0x40800000, 0x40a00000, 0x40c00000, 0x40e00000, - 0x41000000, 0x41100000, 0x41200000, 0x41300000, - 0x41400000, 0x41500000, 0x41600000, 0x41700000, - }; - int vlctable; - VLC* vlc; - WMAProChannelCtx* ci = &s->channel[c]; - int rl_mode = 0; - int cur_coeff = 0; - int num_zeros = 0; - const uint16_t* run; - const float* level; - - dprintf(s->avctx, "decode coefficients for channel %i\n", c); - - vlctable = get_bits1(&s->gb); - vlc = &coef_vlc[vlctable]; - - if (vlctable) { - run = coef1_run; - level = coef1_level; - } else { - run = coef0_run; - level = coef0_level; - } - - /** decode vector coefficients (consumes up to 167 bits per iteration for - 4 vector coded large values) */ - while (!rl_mode && cur_coeff + 3 < s->subframe_len) { - int vals[4]; - int i; - unsigned int idx; - - idx = get_vlc2(&s->gb, vec4_vlc.table, VLCBITS, VEC4MAXDEPTH); - - if (idx == HUFF_VEC4_SIZE - 1) { - for (i = 0; i < 4; i += 2) { - idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH); - if (idx == HUFF_VEC2_SIZE - 1) { - int v0, v1; - v0 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); - if (v0 == HUFF_VEC1_SIZE - 1) - v0 += ff_wma_get_large_val(&s->gb); - v1 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); - if (v1 == HUFF_VEC1_SIZE - 1) - v1 += ff_wma_get_large_val(&s->gb); - ((float*)vals)[i ] = v0; - ((float*)vals)[i+1] = v1; - } else { - vals[i] = fval_tab[symbol_to_vec2[idx] >> 4 ]; - vals[i+1] = fval_tab[symbol_to_vec2[idx] & 0xF]; - } - } - } else { - vals[0] = fval_tab[ symbol_to_vec4[idx] >> 12 ]; - vals[1] = fval_tab[(symbol_to_vec4[idx] >> 8) & 0xF]; - vals[2] = fval_tab[(symbol_to_vec4[idx] >> 4) & 0xF]; - vals[3] = fval_tab[ symbol_to_vec4[idx] & 0xF]; - } - - /** decode sign */ - for (i = 0; i < 4; i++) { - if (vals[i]) { - int sign = get_bits1(&s->gb) - 1; - *(uint32_t*)&ci->coeffs[cur_coeff] = vals[i] ^ sign<<31; - num_zeros = 0; - } else { - ci->coeffs[cur_coeff] = 0; - /** switch to run level mode when subframe_len / 128 zeros - were found in a row */ - rl_mode |= (++num_zeros > s->subframe_len >> 8); - } - ++cur_coeff; - } - } - - /** decode run level coded coefficients */ - if (rl_mode) { - memset(&ci->coeffs[cur_coeff], 0, - sizeof(*ci->coeffs) * (s->subframe_len - cur_coeff)); - if (ff_wma_run_level_decode(s->avctx, &s->gb, vlc, - level, run, 1, ci->coeffs, - cur_coeff, s->subframe_len, - s->subframe_len, s->esc_len, 0)) - return AVERROR_INVALIDDATA; - } - - return 0; -} - -/** - *@brief Extract scale factors from the bitstream. - *@param s codec context - *@return 0 on success, < 0 in case of bitstream errors - */ -static int decode_scale_factors(WMAProDecodeCtx* s) -{ - int i; - - /** should never consume more than 5344 bits - * MAX_CHANNELS * (1 + MAX_BANDS * 23) - */ - - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - int* sf; - int* sf_end; - s->channel[c].scale_factors = s->channel[c].saved_scale_factors[!s->channel[c].scale_factor_idx]; - sf_end = s->channel[c].scale_factors + s->num_bands; - - /** resample scale factors for the new block size - * as the scale factors might need to be resampled several times - * before some new values are transmitted, a backup of the last - * transmitted scale factors is kept in saved_scale_factors - */ - if (s->channel[c].reuse_sf) { - const int8_t* sf_offsets = s->sf_offsets[s->table_idx][s->channel[c].table_idx]; - int b; - for (b = 0; b < s->num_bands; b++) - s->channel[c].scale_factors[b] = - s->channel[c].saved_scale_factors[s->channel[c].scale_factor_idx][*sf_offsets++]; - } - - if (!s->channel[c].cur_subframe || get_bits1(&s->gb)) { - - if (!s->channel[c].reuse_sf) { - int val; - /** decode DPCM coded scale factors */ - s->channel[c].scale_factor_step = get_bits(&s->gb, 2) + 1; - val = 45 / s->channel[c].scale_factor_step; - for (sf = s->channel[c].scale_factors; sf < sf_end; sf++) { - val += get_vlc2(&s->gb, sf_vlc.table, SCALEVLCBITS, SCALEMAXDEPTH) - 60; - *sf = val; - } - } else { - int i; - /** run level decode differences to the resampled factors */ - for (i = 0; i < s->num_bands; i++) { - int idx; - int skip; - int val; - int sign; - - idx = get_vlc2(&s->gb, sf_rl_vlc.table, VLCBITS, SCALERLMAXDEPTH); - - if (!idx) { - uint32_t code = get_bits(&s->gb, 14); - val = code >> 6; - sign = (code & 1) - 1; - skip = (code & 0x3f) >> 1; - } else if (idx == 1) { - break; - } else { - skip = scale_rl_run[idx]; - val = scale_rl_level[idx]; - sign = get_bits1(&s->gb)-1; - } - - i += skip; - if (i >= s->num_bands) { - av_log(s->avctx, AV_LOG_ERROR, - "invalid scale factor coding\n"); - return AVERROR_INVALIDDATA; - } - s->channel[c].scale_factors[i] += (val ^ sign) - sign; - } - } - /** swap buffers */ - s->channel[c].scale_factor_idx = !s->channel[c].scale_factor_idx; - s->channel[c].table_idx = s->table_idx; - s->channel[c].reuse_sf = 1; - } - - /** calculate new scale factor maximum */ - s->channel[c].max_scale_factor = s->channel[c].scale_factors[0]; - for (sf = s->channel[c].scale_factors + 1; sf < sf_end; sf++) { - s->channel[c].max_scale_factor = - FFMAX(s->channel[c].max_scale_factor, *sf); - } - - } - return 0; -} - -/** - *@brief Reconstruct the individual channel data. - *@param s codec context - */ -static void inverse_channel_transform(WMAProDecodeCtx *s) -{ - int i; - - for (i = 0; i < s->num_chgroups; i++) { - if (s->chgroup[i].transform) { - float data[WMAPRO_MAX_CHANNELS]; - const int num_channels = s->chgroup[i].num_channels; - float** ch_data = s->chgroup[i].channel_data; - float** ch_end = ch_data + num_channels; - const int8_t* tb = s->chgroup[i].transform_band; - int16_t* sfb; - - /** multichannel decorrelation */ - for (sfb = s->cur_sfb_offsets; - sfb < s->cur_sfb_offsets + s->num_bands; sfb++) { - int y; - if (*tb++ == 1) { - /** multiply values with the decorrelation_matrix */ - for (y = sfb[0]; y < FFMIN(sfb[1], s->subframe_len); y++) { - const float* mat = s->chgroup[i].decorrelation_matrix; - const float* data_end = data + num_channels; - float* data_ptr = data; - float** ch; - - for (ch = ch_data; ch < ch_end; ch++) - *data_ptr++ = (*ch)[y]; - - for (ch = ch_data; ch < ch_end; ch++) { - float sum = 0; - data_ptr = data; - while (data_ptr < data_end) - sum += *data_ptr++ * *mat++; - - (*ch)[y] = sum; - } - } - } else if (s->num_channels == 2) { - int len = FFMIN(sfb[1], s->subframe_len) - sfb[0]; - s->dsp.vector_fmul_scalar(ch_data[0] + sfb[0], - ch_data[0] + sfb[0], - 181.0 / 128, len); - s->dsp.vector_fmul_scalar(ch_data[1] + sfb[0], - ch_data[1] + sfb[0], - 181.0 / 128, len); - } - } - } - } -} - -/** - *@brief Apply sine window and reconstruct the output buffer. - *@param s codec context - */ -static void wmapro_window(WMAProDecodeCtx *s) -{ - int i; - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - float* window; - int winlen = s->channel[c].prev_block_len; - float* start = s->channel[c].coeffs - (winlen >> 1); - - if (s->subframe_len < winlen) { - start += (winlen - s->subframe_len) >> 1; - winlen = s->subframe_len; - } - - window = s->windows[av_log2(winlen) - BLOCK_MIN_BITS]; - - winlen >>= 1; - - s->dsp.vector_fmul_window(start, start, start + winlen, - window, 0, winlen); - - s->channel[c].prev_block_len = s->subframe_len; - } -} - -/** - *@brief Decode a single subframe (block). - *@param s codec context - *@return 0 on success, < 0 when decoding failed - */ -static int decode_subframe(WMAProDecodeCtx *s) -{ - int offset = s->samples_per_frame; - int subframe_len = s->samples_per_frame; - int i; - int total_samples = s->samples_per_frame * s->num_channels; - int transmit_coeffs = 0; - int cur_subwoofer_cutoff; - - s->subframe_offset = get_bits_count(&s->gb); - - /** reset channel context and find the next block offset and size - == the next block of the channel with the smallest number of - decoded samples - */ - for (i = 0; i < s->num_channels; i++) { - s->channel[i].grouped = 0; - if (offset > s->channel[i].decoded_samples) { - offset = s->channel[i].decoded_samples; - subframe_len = - s->channel[i].subframe_len[s->channel[i].cur_subframe]; - } - } - - dprintf(s->avctx, - "processing subframe with offset %i len %i\n", offset, subframe_len); - - /** get a list of all channels that contain the estimated block */ - s->channels_for_cur_subframe = 0; - for (i = 0; i < s->num_channels; i++) { - const int cur_subframe = s->channel[i].cur_subframe; - /** substract already processed samples */ - total_samples -= s->channel[i].decoded_samples; - - /** and count if there are multiple subframes that match our profile */ - if (offset == s->channel[i].decoded_samples && - subframe_len == s->channel[i].subframe_len[cur_subframe]) { - total_samples -= s->channel[i].subframe_len[cur_subframe]; - s->channel[i].decoded_samples += - s->channel[i].subframe_len[cur_subframe]; - s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i; - ++s->channels_for_cur_subframe; - } - } - - /** check if the frame will be complete after processing the - estimated block */ - if (!total_samples) - s->parsed_all_subframes = 1; - - - dprintf(s->avctx, "subframe is part of %i channels\n", - s->channels_for_cur_subframe); - - /** calculate number of scale factor bands and their offsets */ - s->table_idx = av_log2(s->samples_per_frame/subframe_len); - s->num_bands = s->num_sfb[s->table_idx]; - s->cur_sfb_offsets = s->sfb_offsets[s->table_idx]; - cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; - - /** configure the decoder for the current subframe */ - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - - s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) - + offset]; - } - - s->subframe_len = subframe_len; - s->esc_len = av_log2(s->subframe_len - 1) + 1; - - /** skip extended header if any */ - if (get_bits1(&s->gb)) { - int num_fill_bits; - if (!(num_fill_bits = get_bits(&s->gb, 2))) { - int len = get_bits(&s->gb, 4); - num_fill_bits = get_bits(&s->gb, len) + 1; - } - - if (num_fill_bits >= 0) { - if (get_bits_count(&s->gb) + num_fill_bits > s->num_saved_bits) { - av_log(s->avctx, AV_LOG_ERROR, "invalid number of fill bits\n"); - return AVERROR_INVALIDDATA; - } - - skip_bits_long(&s->gb, num_fill_bits); - } - } - - /** no idea for what the following bit is used */ - if (get_bits1(&s->gb)) { - av_log_ask_for_sample(s->avctx, "reserved bit set\n"); - return AVERROR_INVALIDDATA; - } - - - if (decode_channel_transform(s) < 0) - return AVERROR_INVALIDDATA; - - - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - if ((s->channel[c].transmit_coefs = get_bits1(&s->gb))) - transmit_coeffs = 1; - } - - if (transmit_coeffs) { - int step; - int quant_step = 90 * s->bits_per_sample >> 4; - if ((get_bits1(&s->gb))) { - /** FIXME: might change run level mode decision */ - av_log_ask_for_sample(s->avctx, "unsupported quant step coding\n"); - return AVERROR_INVALIDDATA; - } - /** decode quantization step */ - step = get_sbits(&s->gb, 6); - quant_step += step; - if (step == -32 || step == 31) { - const int sign = (step == 31) - 1; - int quant = 0; - while (get_bits_count(&s->gb) + 5 < s->num_saved_bits && - (step = get_bits(&s->gb, 5)) == 31) { - quant += 31; - } - quant_step += ((quant + step) ^ sign) - sign; - } - if (quant_step < 0) { - av_log(s->avctx, AV_LOG_DEBUG, "negative quant step\n"); - } - - /** decode quantization step modifiers for every channel */ - - if (s->channels_for_cur_subframe == 1) { - s->channel[s->channel_indexes_for_cur_subframe[0]].quant_step = quant_step; - } else { - int modifier_len = get_bits(&s->gb, 3); - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].quant_step = quant_step; - if (get_bits1(&s->gb)) { - if (modifier_len) { - s->channel[c].quant_step += get_bits(&s->gb, modifier_len) + 1; - } else - ++s->channel[c].quant_step; - } - } - } - - /** decode scale factors */ - if (decode_scale_factors(s) < 0) - return AVERROR_INVALIDDATA; - } - - dprintf(s->avctx, "BITSTREAM: subframe header length was %i\n", - get_bits_count(&s->gb) - s->subframe_offset); - - /** parse coefficients */ - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - if (s->channel[c].transmit_coefs && - get_bits_count(&s->gb) < s->num_saved_bits) { - decode_coeffs(s, c); - } else - memset(s->channel[c].coeffs, 0, - sizeof(*s->channel[c].coeffs) * subframe_len); - } - - dprintf(s->avctx, "BITSTREAM: subframe length was %i\n", - get_bits_count(&s->gb) - s->subframe_offset); - - if (transmit_coeffs) { - /** reconstruct the per channel data */ - inverse_channel_transform(s); - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - const int* sf = s->channel[c].scale_factors; - int b; - - if (c == s->lfe_channel) - memset(&s->tmp[cur_subwoofer_cutoff], 0, sizeof(*s->tmp) * - (subframe_len - cur_subwoofer_cutoff)); - - /** inverse quantization and rescaling */ - for (b = 0; b < s->num_bands; b++) { - const int end = FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len); - const int exp = s->channel[c].quant_step - - (s->channel[c].max_scale_factor - *sf++) * - s->channel[c].scale_factor_step; - const float quant = pow(10.0, exp / 20.0); - int start = s->cur_sfb_offsets[b]; - s->dsp.vector_fmul_scalar(s->tmp + start, - s->channel[c].coeffs + start, - quant, end - start); - } - - /** apply imdct (ff_imdct_half == DCTIV with reverse) */ - ff_imdct_half(&s->mdct_ctx[av_log2(subframe_len) - BLOCK_MIN_BITS], - s->channel[c].coeffs, s->tmp); - } - } - - /** window and overlapp-add */ - wmapro_window(s); - - /** handled one subframe */ - for (i = 0; i < s->channels_for_cur_subframe; i++) { - int c = s->channel_indexes_for_cur_subframe[i]; - if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) { - av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n"); - return AVERROR_INVALIDDATA; - } - ++s->channel[c].cur_subframe; - } - - return 0; -} - -/** - *@brief Decode one WMA frame. - *@param s codec context - *@return 0 if the trailer bit indicates that this is the last frame, - * 1 if there are additional frames - */ -static int decode_frame(WMAProDecodeCtx *s) -{ - GetBitContext* gb = &s->gb; - int more_frames = 0; - int len = 0; - int i; - - /** check for potential output buffer overflow */ - if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) { - /** return an error if no frame could be decoded at all */ - av_log(s->avctx, AV_LOG_ERROR, - "not enough space for the output samples\n"); - s->packet_loss = 1; - return 0; - } - - /** get frame length */ - if (s->len_prefix) - len = get_bits(gb, s->log2_frame_size); - - dprintf(s->avctx, "decoding frame with length %x\n", len); - - /** decode tile information */ - if (decode_tilehdr(s)) { - s->packet_loss = 1; - return 0; - } - - /** read postproc transform */ - if (s->num_channels > 1 && get_bits1(gb)) { - av_log_ask_for_sample(s->avctx, "Unsupported postproc transform found\n"); - s->packet_loss = 1; - return 0; - } - - /** read drc info */ - if (s->dynamic_range_compression) { - s->drc_gain = get_bits(gb, 8); - dprintf(s->avctx, "drc_gain %i\n", s->drc_gain); - } - - /** no idea what these are for, might be the number of samples - that need to be skipped at the beginning or end of a stream */ - if (get_bits1(gb)) { - int skip; - - /** usually true for the first frame */ - if (get_bits1(gb)) { - skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); - dprintf(s->avctx, "start skip: %i\n", skip); - } - - /** sometimes true for the last frame */ - if (get_bits1(gb)) { - skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); - dprintf(s->avctx, "end skip: %i\n", skip); - } - - } - - dprintf(s->avctx, "BITSTREAM: frame header length was %i\n", - get_bits_count(gb) - s->frame_offset); - - /** reset subframe states */ - s->parsed_all_subframes = 0; - for (i = 0; i < s->num_channels; i++) { - s->channel[i].decoded_samples = 0; - s->channel[i].cur_subframe = 0; - s->channel[i].reuse_sf = 0; - } - - /** decode all subframes */ - while (!s->parsed_all_subframes) { - if (decode_subframe(s) < 0) { - s->packet_loss = 1; - return 0; - } - } - - /** interleave samples and write them to the output buffer */ - for (i = 0; i < s->num_channels; i++) { - float* ptr = s->samples + i; - int incr = s->num_channels; - float* iptr = s->channel[i].out; - float* iend = iptr + s->samples_per_frame; - - // FIXME should create/use a DSP function here - while (iptr < iend) { - *ptr = *iptr++; - ptr += incr; - } - - /** reuse second half of the IMDCT output for the next frame */ - memcpy(&s->channel[i].out[0], - &s->channel[i].out[s->samples_per_frame], - s->samples_per_frame * sizeof(*s->channel[i].out) >> 1); - } - - if (s->skip_frame) { - s->skip_frame = 0; - } else - s->samples += s->num_channels * s->samples_per_frame; - - if (len != (get_bits_count(gb) - s->frame_offset) + 2) { - /** FIXME: not sure if this is always an error */ - av_log(s->avctx, AV_LOG_ERROR, "frame[%i] would have to skip %i bits\n", - s->frame_num, len - (get_bits_count(gb) - s->frame_offset) - 1); - s->packet_loss = 1; - return 0; - } - - /** skip the rest of the frame data */ - skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1); - - /** decode trailer bit */ - more_frames = get_bits1(gb); - - ++s->frame_num; - return more_frames; -} - -/** - *@brief Calculate remaining input buffer length. - *@param s codec context - *@param gb bitstream reader context - *@return remaining size in bits - */ -static int remaining_bits(WMAProDecodeCtx *s, GetBitContext *gb) -{ - return s->buf_bit_size - get_bits_count(gb); -} - -/** - *@brief Fill the bit reservoir with a (partial) frame. - *@param s codec context - *@param gb bitstream reader context - *@param len length of the partial frame - *@param append decides wether to reset the buffer or not - */ -static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, - int append) -{ - int buflen; - - /** when the frame data does not need to be concatenated, the input buffer - is resetted and additional bits from the previous frame are copyed - and skipped later so that a fast byte copy is possible */ - - if (!append) { - s->frame_offset = get_bits_count(gb) & 7; - s->num_saved_bits = s->frame_offset; - init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); - } - - buflen = (s->num_saved_bits + len + 8) >> 3; - - if (len <= 0 || buflen > MAX_FRAMESIZE) { - av_log_ask_for_sample(s->avctx, "input buffer too small\n"); - s->packet_loss = 1; - return; - } - - s->num_saved_bits += len; - if (!append) { - ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), - s->num_saved_bits); - } else { - int align = 8 - (get_bits_count(gb) & 7); - align = FFMIN(align, len); - put_bits(&s->pb, align, get_bits(gb, align)); - len -= align; - ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); - } - skip_bits_long(gb, len); - - { - PutBitContext tmp = s->pb; - flush_put_bits(&tmp); - } - - init_get_bits(&s->gb, s->frame_data, s->num_saved_bits); - skip_bits(&s->gb, s->frame_offset); -} - -/** - *@brief Decode a single WMA packet. - *@param avctx codec context - *@param data the output buffer - *@param data_size number of bytes that were written to the output buffer - *@param avpkt input packet - *@return number of bytes that were read from the input buffer - */ -static int decode_packet(AVCodecContext *avctx, - void *data, int *data_size, AVPacket* avpkt) -{ - WMAProDecodeCtx *s = avctx->priv_data; - GetBitContext* gb = &s->pgb; - const uint8_t* buf = avpkt->data; - int buf_size = avpkt->size; - int num_bits_prev_frame; - int packet_sequence_number; - - s->samples = data; - s->samples_end = (float*)((int8_t*)data + *data_size); - *data_size = 0; - - if (s->packet_done || s->packet_loss) { - s->packet_done = 0; - s->buf_bit_size = buf_size << 3; - - /** sanity check for the buffer length */ - if (buf_size < avctx->block_align) - return 0; - - buf_size = avctx->block_align; - - /** parse packet header */ - init_get_bits(gb, buf, s->buf_bit_size); - packet_sequence_number = get_bits(gb, 4); - skip_bits(gb, 2); - - /** get number of bits that need to be added to the previous frame */ - num_bits_prev_frame = get_bits(gb, s->log2_frame_size); - dprintf(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number, - num_bits_prev_frame); - - /** check for packet loss */ - if (!s->packet_loss && - ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) { - s->packet_loss = 1; - av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n", - s->packet_sequence_number, packet_sequence_number); - } - s->packet_sequence_number = packet_sequence_number; - - if (num_bits_prev_frame > 0) { - /** append the previous frame data to the remaining data from the - previous packet to create a full frame */ - save_bits(s, gb, num_bits_prev_frame, 1); - dprintf(avctx, "accumulated %x bits of frame data\n", - s->num_saved_bits - s->frame_offset); - - /** decode the cross packet frame if it is valid */ - if (!s->packet_loss) - decode_frame(s); - } else if (s->num_saved_bits - s->frame_offset) { - dprintf(avctx, "ignoring %x previously saved bits\n", - s->num_saved_bits - s->frame_offset); - } - - s->packet_loss = 0; - - } else { - int frame_size; - s->buf_bit_size = avpkt->size << 3; - init_get_bits(gb, avpkt->data, s->buf_bit_size); - skip_bits(gb, s->packet_offset); - if (remaining_bits(s, gb) > s->log2_frame_size && - (frame_size = show_bits(gb, s->log2_frame_size)) && - frame_size <= remaining_bits(s, gb)) { - save_bits(s, gb, frame_size, 0); - s->packet_done = !decode_frame(s); - } else - s->packet_done = 1; - } - - if (s->packet_done && !s->packet_loss && - remaining_bits(s, gb) > 0) { - /** save the rest of the data so that it can be decoded - with the next packet */ - save_bits(s, gb, remaining_bits(s, gb), 0); - } - - *data_size = (int8_t *)s->samples - (int8_t *)data; - s->packet_offset = get_bits_count(gb) & 7; - - return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3; -} - -/** - *@brief Clear decoder buffers (for seeking). - *@param avctx codec context - */ -static void flush(AVCodecContext *avctx) -{ - WMAProDecodeCtx *s = avctx->priv_data; - int i; - /** reset output buffer as a part of it is used during the windowing of a - new frame */ - for (i = 0; i < s->num_channels; i++) - memset(s->channel[i].out, 0, s->samples_per_frame * - sizeof(*s->channel[i].out)); - s->packet_loss = 1; -} - - -/** - *@brief wmapro decoder - */ -AVCodec wmapro_decoder = { - "wmapro", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WMAPRO, - sizeof(WMAProDecodeCtx), - decode_init, - NULL, - decode_end, - decode_packet, - .capabilities = CODEC_CAP_SUBFRAMES, - .flush= flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/wmavoice.c b/tizen/distrib/ffmpeg/libavcodec/wmavoice.c deleted file mode 100644 index 4ec17eb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmavoice.c +++ /dev/null @@ -1,2030 +0,0 @@ -/* - * Windows Media Audio Voice decoder. - * Copyright (c) 2009 Ronald S. Bultje - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Windows Media Audio Voice compatible decoder - * @author Ronald S. Bultje - */ - -#include -#include "avcodec.h" -#include "get_bits.h" -#include "put_bits.h" -#include "wmavoice_data.h" -#include "celp_math.h" -#include "celp_filters.h" -#include "acelp_vectors.h" -#include "acelp_filters.h" -#include "lsp.h" -#include "libavutil/lzo.h" -#include "avfft.h" -#include "fft.h" - -#define MAX_BLOCKS 8 ///< maximum number of blocks per frame -#define MAX_LSPS 16 ///< maximum filter order -#define MAX_LSPS_ALIGN16 16 ///< same as #MAX_LSPS; needs to be multiple - ///< of 16 for ASM input buffer alignment -#define MAX_FRAMES 3 ///< maximum number of frames per superframe -#define MAX_FRAMESIZE 160 ///< maximum number of samples per frame -#define MAX_SIGNAL_HISTORY 416 ///< maximum excitation signal history -#define MAX_SFRAMESIZE (MAX_FRAMESIZE * MAX_FRAMES) - ///< maximum number of samples per superframe -#define SFRAME_CACHE_MAXSIZE 256 ///< maximum cache size for frame data that - ///< was split over two packets -#define VLC_NBITS 6 ///< number of bits to read per VLC iteration - -/** - * Frame type VLC coding. - */ -static VLC frame_type_vlc; - -/** - * Adaptive codebook types. - */ -enum { - ACB_TYPE_NONE = 0, ///< no adaptive codebook (only hardcoded fixed) - ACB_TYPE_ASYMMETRIC = 1, ///< adaptive codebook with per-frame pitch, which - ///< we interpolate to get a per-sample pitch. - ///< Signal is generated using an asymmetric sinc - ///< window function - ///< @note see #wmavoice_ipol1_coeffs - ACB_TYPE_HAMMING = 2 ///< Per-block pitch with signal generation using - ///< a Hamming sinc window function - ///< @note see #wmavoice_ipol2_coeffs -}; - -/** - * Fixed codebook types. - */ -enum { - FCB_TYPE_SILENCE = 0, ///< comfort noise during silence - ///< generated from a hardcoded (fixed) codebook - ///< with per-frame (low) gain values - FCB_TYPE_HARDCODED = 1, ///< hardcoded (fixed) codebook with per-block - ///< gain values - FCB_TYPE_AW_PULSES = 2, ///< Pitch-adaptive window (AW) pulse signals, - ///< used in particular for low-bitrate streams - FCB_TYPE_EXC_PULSES = 3, ///< Innovation (fixed) codebook pulse sets in - ///< combinations of either single pulses or - ///< pulse pairs -}; - -/** - * Description of frame types. - */ -static const struct frame_type_desc { - uint8_t n_blocks; ///< amount of blocks per frame (each block - ///< (contains 160/#n_blocks samples) - uint8_t log_n_blocks; ///< log2(#n_blocks) - uint8_t acb_type; ///< Adaptive codebook type (ACB_TYPE_*) - uint8_t fcb_type; ///< Fixed codebook type (FCB_TYPE_*) - uint8_t dbl_pulses; ///< how many pulse vectors have pulse pairs - ///< (rather than just one single pulse) - ///< only if #fcb_type == #FCB_TYPE_EXC_PULSES - uint16_t frame_size; ///< the amount of bits that make up the block - ///< data (per frame) -} frame_descs[17] = { - { 1, 0, ACB_TYPE_NONE, FCB_TYPE_SILENCE, 0, 0 }, - { 2, 1, ACB_TYPE_NONE, FCB_TYPE_HARDCODED, 0, 28 }, - { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_AW_PULSES, 0, 46 }, - { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2, 80 }, - { 2, 1, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5, 104 }, - { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 0, 108 }, - { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 2, 132 }, - { 4, 2, ACB_TYPE_ASYMMETRIC, FCB_TYPE_EXC_PULSES, 5, 168 }, - { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 64 }, - { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 80 }, - { 2, 1, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 104 }, - { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 108 }, - { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 132 }, - { 4, 2, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 168 }, - { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 0, 176 }, - { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 2, 208 }, - { 8, 3, ACB_TYPE_HAMMING, FCB_TYPE_EXC_PULSES, 5, 256 } -}; - -/** - * WMA Voice decoding context. - */ -typedef struct { - /** - * @defgroup struct_global Global values - * Global values, specified in the stream header / extradata or used - * all over. - * @{ - */ - GetBitContext gb; ///< packet bitreader. During decoder init, - ///< it contains the extradata from the - ///< demuxer. During decoding, it contains - ///< packet data. - int8_t vbm_tree[25]; ///< converts VLC codes to frame type - - int spillover_bitsize; ///< number of bits used to specify - ///< #spillover_nbits in the packet header - ///< = ceil(log2(ctx->block_align << 3)) - int history_nsamples; ///< number of samples in history for signal - ///< prediction (through ACB) - - /* postfilter specific values */ - int do_apf; ///< whether to apply the averaged - ///< projection filter (APF) - int denoise_strength; ///< strength of denoising in Wiener filter - ///< [0-11] - int denoise_tilt_corr; ///< Whether to apply tilt correction to the - ///< Wiener filter coefficients (postfilter) - int dc_level; ///< Predicted amount of DC noise, based - ///< on which a DC removal filter is used - - int lsps; ///< number of LSPs per frame [10 or 16] - int lsp_q_mode; ///< defines quantizer defaults [0, 1] - int lsp_def_mode; ///< defines different sets of LSP defaults - ///< [0, 1] - int frame_lsp_bitsize; ///< size (in bits) of LSPs, when encoded - ///< per-frame (independent coding) - int sframe_lsp_bitsize; ///< size (in bits) of LSPs, when encoded - ///< per superframe (residual coding) - - int min_pitch_val; ///< base value for pitch parsing code - int max_pitch_val; ///< max value + 1 for pitch parsing - int pitch_nbits; ///< number of bits used to specify the - ///< pitch value in the frame header - int block_pitch_nbits; ///< number of bits used to specify the - ///< first block's pitch value - int block_pitch_range; ///< range of the block pitch - int block_delta_pitch_nbits; ///< number of bits used to specify the - ///< delta pitch between this and the last - ///< block's pitch value, used in all but - ///< first block - int block_delta_pitch_hrange; ///< 1/2 range of the delta (full range is - ///< from -this to +this-1) - uint16_t block_conv_table[4]; ///< boundaries for block pitch unit/scale - ///< conversion - - /** - * @} - * @defgroup struct_packet Packet values - * Packet values, specified in the packet header or related to a packet. - * A packet is considered to be a single unit of data provided to this - * decoder by the demuxer. - * @{ - */ - int spillover_nbits; ///< number of bits of the previous packet's - ///< last superframe preceeding this - ///< packet's first full superframe (useful - ///< for re-synchronization also) - int has_residual_lsps; ///< if set, superframes contain one set of - ///< LSPs that cover all frames, encoded as - ///< independent and residual LSPs; if not - ///< set, each frame contains its own, fully - ///< independent, LSPs - int skip_bits_next; ///< number of bits to skip at the next call - ///< to #wmavoice_decode_packet() (since - ///< they're part of the previous superframe) - - uint8_t sframe_cache[SFRAME_CACHE_MAXSIZE + FF_INPUT_BUFFER_PADDING_SIZE]; - ///< cache for superframe data split over - ///< multiple packets - int sframe_cache_size; ///< set to >0 if we have data from an - ///< (incomplete) superframe from a previous - ///< packet that spilled over in the current - ///< packet; specifies the amount of bits in - ///< #sframe_cache - PutBitContext pb; ///< bitstream writer for #sframe_cache - - /** - * @} - * @defgroup struct_frame Frame and superframe values - * Superframe and frame data - these can change from frame to frame, - * although some of them do in that case serve as a cache / history for - * the next frame or superframe. - * @{ - */ - double prev_lsps[MAX_LSPS]; ///< LSPs of the last frame of the previous - ///< superframe - int last_pitch_val; ///< pitch value of the previous frame - int last_acb_type; ///< frame type [0-2] of the previous frame - int pitch_diff_sh16; ///< ((cur_pitch_val - #last_pitch_val) - ///< << 16) / #MAX_FRAMESIZE - float silence_gain; ///< set for use in blocks if #ACB_TYPE_NONE - - int aw_idx_is_ext; ///< whether the AW index was encoded in - ///< 8 bits (instead of 6) - int aw_pulse_range; ///< the range over which #aw_pulse_set1() - ///< can apply the pulse, relative to the - ///< value in aw_first_pulse_off. The exact - ///< position of the first AW-pulse is within - ///< [pulse_off, pulse_off + this], and - ///< depends on bitstream values; [16 or 24] - int aw_n_pulses[2]; ///< number of AW-pulses in each block; note - ///< that this number can be negative (in - ///< which case it basically means "zero") - int aw_first_pulse_off[2]; ///< index of first sample to which to - ///< apply AW-pulses, or -0xff if unset - int aw_next_pulse_off_cache; ///< the position (relative to start of the - ///< second block) at which pulses should - ///< start to be positioned, serves as a - ///< cache for pitch-adaptive window pulses - ///< between blocks - - int frame_cntr; ///< current frame index [0 - 0xFFFE]; is - ///< only used for comfort noise in #pRNG() - float gain_pred_err[6]; ///< cache for gain prediction - float excitation_history[MAX_SIGNAL_HISTORY]; - ///< cache of the signal of previous - ///< superframes, used as a history for - ///< signal generation - float synth_history[MAX_LSPS]; ///< see #excitation_history - /** - * @} - * @defgroup post_filter Postfilter values - * Varibales used for postfilter implementation, mostly history for - * smoothing and so on, and context variables for FFT/iFFT. - * @{ - */ - RDFTContext rdft, irdft; ///< contexts for FFT-calculation in the - ///< postfilter (for denoise filter) - DCTContext dct, dst; ///< contexts for phase shift (in Hilbert - ///< transform, part of postfilter) - float sin[511], cos[511]; ///< 8-bit cosine/sine windows over [-pi,pi] - ///< range - float postfilter_agc; ///< gain control memory, used in - ///< #adaptive_gain_control() - float dcf_mem[2]; ///< DC filter history - float zero_exc_pf[MAX_SIGNAL_HISTORY + MAX_SFRAMESIZE]; - ///< zero filter output (i.e. excitation) - ///< by postfilter - float denoise_filter_cache[MAX_FRAMESIZE]; - int denoise_filter_cache_size; ///< samples in #denoise_filter_cache - DECLARE_ALIGNED(16, float, tilted_lpcs_pf)[0x80]; - ///< aligned buffer for LPC tilting - DECLARE_ALIGNED(16, float, denoise_coeffs_pf)[0x80]; - ///< aligned buffer for denoise coefficients - DECLARE_ALIGNED(16, float, synth_filter_out_buf)[0x80 + MAX_LSPS_ALIGN16]; - ///< aligned buffer for postfilter speech - ///< synthesis - /** - * @} - */ -} WMAVoiceContext; - -/** - * Sets up the variable bit mode (VBM) tree from container extradata. - * @param gb bit I/O context. - * The bit context (s->gb) should be loaded with byte 23-46 of the - * container extradata (i.e. the ones containing the VBM tree). - * @param vbm_tree pointer to array to which the decoded VBM tree will be - * written. - * @return 0 on success, <0 on error. - */ -static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25]) -{ - static const uint8_t bits[] = { - 2, 2, 2, 4, 4, 4, - 6, 6, 6, 8, 8, 8, - 10, 10, 10, 12, 12, 12, - 14, 14, 14, 14 - }; - static const uint16_t codes[] = { - 0x0000, 0x0001, 0x0002, // 00/01/10 - 0x000c, 0x000d, 0x000e, // 11+00/01/10 - 0x003c, 0x003d, 0x003e, // 1111+00/01/10 - 0x00fc, 0x00fd, 0x00fe, // 111111+00/01/10 - 0x03fc, 0x03fd, 0x03fe, // 11111111+00/01/10 - 0x0ffc, 0x0ffd, 0x0ffe, // 1111111111+00/01/10 - 0x3ffc, 0x3ffd, 0x3ffe, 0x3fff // 111111111111+xx - }; - int cntr[8], n, res; - - memset(vbm_tree, 0xff, sizeof(vbm_tree)); - memset(cntr, 0, sizeof(cntr)); - for (n = 0; n < 17; n++) { - res = get_bits(gb, 3); - if (cntr[res] > 3) // should be >= 3 + (res == 7)) - return -1; - vbm_tree[res * 3 + cntr[res]++] = n; - } - INIT_VLC_STATIC(&frame_type_vlc, VLC_NBITS, sizeof(bits), - bits, 1, 1, codes, 2, 2, 132); - return 0; -} - -/** - * Set up decoder with parameters from demuxer (extradata etc.). - */ -static av_cold int wmavoice_decode_init(AVCodecContext *ctx) -{ - int n, flags, pitch_range, lsp16_flag; - WMAVoiceContext *s = ctx->priv_data; - - /** - * Extradata layout: - * - byte 0-18: WMAPro-in-WMAVoice extradata (see wmaprodec.c), - * - byte 19-22: flags field (annoyingly in LE; see below for known - * values), - * - byte 23-46: variable bitmode tree (really just 17 * 3 bits, - * rest is 0). - */ - if (ctx->extradata_size != 46) { - av_log(ctx, AV_LOG_ERROR, - "Invalid extradata size %d (should be 46)\n", - ctx->extradata_size); - return -1; - } - flags = AV_RL32(ctx->extradata + 18); - s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align); - s->do_apf = flags & 0x1; - if (s->do_apf) { - ff_rdft_init(&s->rdft, 7, DFT_R2C); - ff_rdft_init(&s->irdft, 7, IDFT_C2R); - ff_dct_init(&s->dct, 6, DCT_I); - ff_dct_init(&s->dst, 6, DST_I); - - ff_sine_window_init(s->cos, 256); - memcpy(&s->sin[255], s->cos, 256 * sizeof(s->cos[0])); - for (n = 0; n < 255; n++) { - s->sin[n] = -s->sin[510 - n]; - s->cos[510 - n] = s->cos[n]; - } - } - s->denoise_strength = (flags >> 2) & 0xF; - if (s->denoise_strength >= 12) { - av_log(ctx, AV_LOG_ERROR, - "Invalid denoise filter strength %d (max=11)\n", - s->denoise_strength); - return -1; - } - s->denoise_tilt_corr = !!(flags & 0x40); - s->dc_level = (flags >> 7) & 0xF; - s->lsp_q_mode = !!(flags & 0x2000); - s->lsp_def_mode = !!(flags & 0x4000); - lsp16_flag = flags & 0x1000; - if (lsp16_flag) { - s->lsps = 16; - s->frame_lsp_bitsize = 34; - s->sframe_lsp_bitsize = 60; - } else { - s->lsps = 10; - s->frame_lsp_bitsize = 24; - s->sframe_lsp_bitsize = 48; - } - for (n = 0; n < s->lsps; n++) - s->prev_lsps[n] = M_PI * (n + 1.0) / (s->lsps + 1.0); - - init_get_bits(&s->gb, ctx->extradata + 22, (ctx->extradata_size - 22) << 3); - if (decode_vbmtree(&s->gb, s->vbm_tree) < 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid VBM tree; broken extradata?\n"); - return -1; - } - - s->min_pitch_val = ((ctx->sample_rate << 8) / 400 + 50) >> 8; - s->max_pitch_val = ((ctx->sample_rate << 8) * 37 / 2000 + 50) >> 8; - pitch_range = s->max_pitch_val - s->min_pitch_val; - s->pitch_nbits = av_ceil_log2(pitch_range); - s->last_pitch_val = 40; - s->last_acb_type = ACB_TYPE_NONE; - s->history_nsamples = s->max_pitch_val + 8; - - if (s->min_pitch_val < 1 || s->history_nsamples > MAX_SIGNAL_HISTORY) { - int min_sr = ((((1 << 8) - 50) * 400) + 0xFF) >> 8, - max_sr = ((((MAX_SIGNAL_HISTORY - 8) << 8) + 205) * 2000 / 37) >> 8; - - av_log(ctx, AV_LOG_ERROR, - "Unsupported samplerate %d (min=%d, max=%d)\n", - ctx->sample_rate, min_sr, max_sr); // 322-22097 Hz - - return -1; - } - - s->block_conv_table[0] = s->min_pitch_val; - s->block_conv_table[1] = (pitch_range * 25) >> 6; - s->block_conv_table[2] = (pitch_range * 44) >> 6; - s->block_conv_table[3] = s->max_pitch_val - 1; - s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF; - s->block_delta_pitch_nbits = 1 + av_ceil_log2(s->block_delta_pitch_hrange); - s->block_pitch_range = s->block_conv_table[2] + - s->block_conv_table[3] + 1 + - 2 * (s->block_conv_table[1] - 2 * s->min_pitch_val); - s->block_pitch_nbits = av_ceil_log2(s->block_pitch_range); - - ctx->sample_fmt = SAMPLE_FMT_FLT; - - return 0; -} - -/** - * @defgroup postfilter Postfilter functions - * Postfilter functions (gain control, wiener denoise filter, DC filter, - * kalman smoothening, plus surrounding code to wrap it) - * @{ - */ -/** - * Adaptive gain control (as used in postfilter). - * - * Identical to #ff_adaptive_gain_control() in acelp_vectors.c, except - * that the energy here is calculated using sum(abs(...)), whereas the - * other codecs (e.g. AMR-NB, SIPRO) use sqrt(dotproduct(...)). - * - * @param out output buffer for filtered samples - * @param in input buffer containing the samples as they are after the - * postfilter steps so far - * @param speech_synth input buffer containing speech synth before postfilter - * @param size input buffer size - * @param alpha exponential filter factor - * @param gain_mem pointer to filter memory (single float) - */ -static void adaptive_gain_control(float *out, const float *in, - const float *speech_synth, - int size, float alpha, float *gain_mem) -{ - int i; - float speech_energy = 0.0, postfilter_energy = 0.0, gain_scale_factor; - float mem = *gain_mem; - - for (i = 0; i < size; i++) { - speech_energy += fabsf(speech_synth[i]); - postfilter_energy += fabsf(in[i]); - } - gain_scale_factor = (1.0 - alpha) * speech_energy / postfilter_energy; - - for (i = 0; i < size; i++) { - mem = alpha * mem + gain_scale_factor; - out[i] = in[i] * mem; - } - - *gain_mem = mem; -} - -/** - * Kalman smoothing function. - * - * This function looks back pitch +/- 3 samples back into history to find - * the best fitting curve (that one giving the optimal gain of the two - * signals, i.e. the highest dot product between the two), and then - * uses that signal history to smoothen the output of the speech synthesis - * filter. - * - * @param s WMA Voice decoding context - * @param pitch pitch of the speech signal - * @param in input speech signal - * @param out output pointer for smoothened signal - * @param size input/output buffer size - * - * @returns -1 if no smoothening took place, e.g. because no optimal - * fit could be found, or 0 on success. - */ -static int kalman_smoothen(WMAVoiceContext *s, int pitch, - const float *in, float *out, int size) -{ - int n; - float optimal_gain = 0, dot; - const float *ptr = &in[-FFMAX(s->min_pitch_val, pitch - 3)], - *end = &in[-FFMIN(s->max_pitch_val, pitch + 3)], - *best_hist_ptr; - - /* find best fitting point in history */ - do { - dot = ff_dot_productf(in, ptr, size); - if (dot > optimal_gain) { - optimal_gain = dot; - best_hist_ptr = ptr; - } - } while (--ptr >= end); - - if (optimal_gain <= 0) - return -1; - dot = ff_dot_productf(best_hist_ptr, best_hist_ptr, size); - if (dot <= 0) // would be 1.0 - return -1; - - if (optimal_gain <= dot) { - dot = dot / (dot + 0.6 * optimal_gain); // 0.625-1.000 - } else - dot = 0.625; - - /* actual smoothing */ - for (n = 0; n < size; n++) - out[n] = best_hist_ptr[n] + dot * (in[n] - best_hist_ptr[n]); - - return 0; -} - -/** - * Get the tilt factor of a formant filter from its transfer function - * @see #tilt_factor() in amrnbdec.c, which does essentially the same, - * but somehow (??) it does a speech synthesis filter in the - * middle, which is missing here - * - * @param lpcs LPC coefficients - * @param n_lpcs Size of LPC buffer - * @returns the tilt factor - */ -static float tilt_factor(const float *lpcs, int n_lpcs) -{ - float rh0, rh1; - - rh0 = 1.0 + ff_dot_productf(lpcs, lpcs, n_lpcs); - rh1 = lpcs[0] + ff_dot_productf(lpcs, &lpcs[1], n_lpcs - 1); - - return rh1 / rh0; -} - -/** - * Derive denoise filter coefficients (in real domain) from the LPCs. - */ -static void calc_input_response(WMAVoiceContext *s, float *lpcs, - int fcb_type, float *coeffs, int remainder) -{ - float last_coeff, min = 15.0, max = -15.0; - float irange, angle_mul, gain_mul, range, sq; - int n, idx; - - /* Create frequency power spectrum of speech input (i.e. RDFT of LPCs) */ - ff_rdft_calc(&s->rdft, lpcs); -#define log_range(var, assign) do { \ - float tmp = log10f(assign); var = tmp; \ - max = FFMAX(max, tmp); min = FFMIN(min, tmp); \ - } while (0) - log_range(last_coeff, lpcs[1] * lpcs[1]); - for (n = 1; n < 64; n++) - log_range(lpcs[n], lpcs[n * 2] * lpcs[n * 2] + - lpcs[n * 2 + 1] * lpcs[n * 2 + 1]); - log_range(lpcs[0], lpcs[0] * lpcs[0]); -#undef log_range - range = max - min; - lpcs[64] = last_coeff; - - /* Now, use this spectrum to pick out these frequencies with higher - * (relative) power/energy (which we then take to be "not noise"), - * and set up a table (still in lpc[]) of (relative) gains per frequency. - * These frequencies will be maintained, while others ("noise") will be - * decreased in the filter output. */ - irange = 64.0 / range; // so irange*(max-value) is in the range [0, 63] - gain_mul = range * (fcb_type == FCB_TYPE_HARDCODED ? (5.0 / 13.0) : - (5.0 / 14.7)); - angle_mul = gain_mul * (8.0 * M_LN10 / M_PI); - for (n = 0; n <= 64; n++) { - float pow; - - idx = FFMAX(0, lrint((max - lpcs[n]) * irange) - 1); - pow = wmavoice_denoise_power_table[s->denoise_strength][idx]; - lpcs[n] = angle_mul * pow; - - /* 70.57 =~ 1/log10(1.0331663) */ - idx = (pow * gain_mul - 0.0295) * 70.570526123; - if (idx > 127) { // fallback if index falls outside table range - coeffs[n] = wmavoice_energy_table[127] * - powf(1.0331663, idx - 127); - } else - coeffs[n] = wmavoice_energy_table[FFMAX(0, idx)]; - } - - /* calculate the Hilbert transform of the gains, which we do (since this - * is a sinus input) by doing a phase shift (in theory, H(sin())=cos()). - * Hilbert_Transform(RDFT(x)) = Laplace_Transform(x), which calculates the - * "moment" of the LPCs in this filter. */ - ff_dct_calc(&s->dct, lpcs); - ff_dct_calc(&s->dst, lpcs); - - /* Split out the coefficient indexes into phase/magnitude pairs */ - idx = 255 + av_clip(lpcs[64], -255, 255); - coeffs[0] = coeffs[0] * s->cos[idx]; - idx = 255 + av_clip(lpcs[64] - 2 * lpcs[63], -255, 255); - last_coeff = coeffs[64] * s->cos[idx]; - for (n = 63;; n--) { - idx = 255 + av_clip(-lpcs[64] - 2 * lpcs[n - 1], -255, 255); - coeffs[n * 2 + 1] = coeffs[n] * s->sin[idx]; - coeffs[n * 2] = coeffs[n] * s->cos[idx]; - - if (!--n) break; - - idx = 255 + av_clip( lpcs[64] - 2 * lpcs[n - 1], -255, 255); - coeffs[n * 2 + 1] = coeffs[n] * s->sin[idx]; - coeffs[n * 2] = coeffs[n] * s->cos[idx]; - } - coeffs[1] = last_coeff; - - /* move into real domain */ - ff_rdft_calc(&s->irdft, coeffs); - - /* tilt correction and normalize scale */ - memset(&coeffs[remainder], 0, sizeof(coeffs[0]) * (128 - remainder)); - if (s->denoise_tilt_corr) { - float tilt_mem = 0; - - coeffs[remainder - 1] = 0; - ff_tilt_compensation(&tilt_mem, - -1.8 * tilt_factor(coeffs, remainder - 1), - coeffs, remainder); - } - sq = (1.0 / 64.0) * sqrtf(1 / ff_dot_productf(coeffs, coeffs, remainder)); - for (n = 0; n < remainder; n++) - coeffs[n] *= sq; -} - -/** - * This function applies a Wiener filter on the (noisy) speech signal as - * a means to denoise it. - * - * - take RDFT of LPCs to get the power spectrum of the noise + speech; - * - using this power spectrum, calculate (for each frequency) the Wiener - * filter gain, which depends on the frequency power and desired level - * of noise subtraction (when set too high, this leads to artifacts) - * We can do this symmetrically over the X-axis (so 0-4kHz is the inverse - * of 4-8kHz); - * - by doing a phase shift, calculate the Hilbert transform of this array - * of per-frequency filter-gains to get the filtering coefficients; - * - smoothen/normalize/de-tilt these filter coefficients as desired; - * - take RDFT of noisy sound, apply the coefficients and take its IRDFT - * to get the denoised speech signal; - * - the leftover (i.e. output of the IRDFT on denoised speech data beyond - * the frame boundary) are saved and applied to subsequent frames by an - * overlap-add method (otherwise you get clicking-artifacts). - * - * @param s WMA Voice decoding context - * @param s fcb_type Frame (codebook) type - * @param synth_pf input: the noisy speech signal, output: denoised speech - * data; should be 16-byte aligned (for ASM purposes) - * @param size size of the speech data - * @param lpcs LPCs used to synthesize this frame's speech data - */ -static void wiener_denoise(WMAVoiceContext *s, int fcb_type, - float *synth_pf, int size, - const float *lpcs) -{ - int remainder, lim, n; - - if (fcb_type != FCB_TYPE_SILENCE) { - float *tilted_lpcs = s->tilted_lpcs_pf, - *coeffs = s->denoise_coeffs_pf, tilt_mem = 0; - - tilted_lpcs[0] = 1.0; - memcpy(&tilted_lpcs[1], lpcs, sizeof(lpcs[0]) * s->lsps); - memset(&tilted_lpcs[s->lsps + 1], 0, - sizeof(tilted_lpcs[0]) * (128 - s->lsps - 1)); - ff_tilt_compensation(&tilt_mem, 0.7 * tilt_factor(lpcs, s->lsps), - tilted_lpcs, s->lsps + 2); - - /* The IRDFT output (127 samples for 7-bit filter) beyond the frame - * size is applied to the next frame. All input beyond this is zero, - * and thus all output beyond this will go towards zero, hence we can - * limit to min(size-1, 127-size) as a performance consideration. */ - remainder = FFMIN(127 - size, size - 1); - calc_input_response(s, tilted_lpcs, fcb_type, coeffs, remainder); - - /* apply coefficients (in frequency spectrum domain), i.e. complex - * number multiplication */ - memset(&synth_pf[size], 0, sizeof(synth_pf[0]) * (128 - size)); - ff_rdft_calc(&s->rdft, synth_pf); - ff_rdft_calc(&s->rdft, coeffs); - synth_pf[0] *= coeffs[0]; - synth_pf[1] *= coeffs[1]; - for (n = 1; n < 64; n++) { - float v1 = synth_pf[n * 2], v2 = synth_pf[n * 2 + 1]; - synth_pf[n * 2] = v1 * coeffs[n * 2] - v2 * coeffs[n * 2 + 1]; - synth_pf[n * 2 + 1] = v2 * coeffs[n * 2] + v1 * coeffs[n * 2 + 1]; - } - ff_rdft_calc(&s->irdft, synth_pf); - } - - /* merge filter output with the history of previous runs */ - if (s->denoise_filter_cache_size) { - lim = FFMIN(s->denoise_filter_cache_size, size); - for (n = 0; n < lim; n++) - synth_pf[n] += s->denoise_filter_cache[n]; - s->denoise_filter_cache_size -= lim; - memmove(s->denoise_filter_cache, &s->denoise_filter_cache[size], - sizeof(s->denoise_filter_cache[0]) * s->denoise_filter_cache_size); - } - - /* move remainder of filter output into a cache for future runs */ - if (fcb_type != FCB_TYPE_SILENCE) { - lim = FFMIN(remainder, s->denoise_filter_cache_size); - for (n = 0; n < lim; n++) - s->denoise_filter_cache[n] += synth_pf[size + n]; - if (lim < remainder) { - memcpy(&s->denoise_filter_cache[lim], &synth_pf[size + lim], - sizeof(s->denoise_filter_cache[0]) * (remainder - lim)); - s->denoise_filter_cache_size = remainder; - } - } -} - -/** - * Averaging projection filter, the postfilter used in WMAVoice. - * - * This uses the following steps: - * - A zero-synthesis filter (generate excitation from synth signal) - * - Kalman smoothing on excitation, based on pitch - * - Re-synthesized smoothened output - * - Iterative Wiener denoise filter - * - Adaptive gain filter - * - DC filter - * - * @param s WMAVoice decoding context - * @param synth Speech synthesis output (before postfilter) - * @param samples Output buffer for filtered samples - * @param size Buffer size of synth & samples - * @param lpcs Generated LPCs used for speech synthesis - * @param fcb_type Frame type (silence, hardcoded, AW-pulses or FCB-pulses) - * @param pitch Pitch of the input signal - */ -static void postfilter(WMAVoiceContext *s, const float *synth, - float *samples, int size, - const float *lpcs, float *zero_exc_pf, - int fcb_type, int pitch) -{ - float synth_filter_in_buf[MAX_FRAMESIZE / 2], - *synth_pf = &s->synth_filter_out_buf[MAX_LSPS_ALIGN16], - *synth_filter_in = zero_exc_pf; - - assert(size <= MAX_FRAMESIZE / 2); - - /* generate excitation from input signal */ - ff_celp_lp_zero_synthesis_filterf(zero_exc_pf, lpcs, synth, size, s->lsps); - - if (fcb_type >= FCB_TYPE_AW_PULSES && - !kalman_smoothen(s, pitch, zero_exc_pf, synth_filter_in_buf, size)) - synth_filter_in = synth_filter_in_buf; - - /* re-synthesize speech after smoothening, and keep history */ - ff_celp_lp_synthesis_filterf(synth_pf, lpcs, - synth_filter_in, size, s->lsps); - memcpy(&synth_pf[-s->lsps], &synth_pf[size - s->lsps], - sizeof(synth_pf[0]) * s->lsps); - - wiener_denoise(s, fcb_type, synth_pf, size, lpcs); - - adaptive_gain_control(samples, synth_pf, synth, size, 0.99, - &s->postfilter_agc); - - if (s->dc_level > 8) { - /* remove ultra-low frequency DC noise / highpass filter; - * coefficients are identical to those used in SIPR decoding, - * and very closely resemble those used in AMR-NB decoding. */ - ff_acelp_apply_order_2_transfer_function(samples, samples, - (const float[2]) { -1.99997, 1.0 }, - (const float[2]) { -1.9330735188, 0.93589198496 }, - 0.93980580475, s->dcf_mem, size); - } -} -/** - * @} - */ - -/** - * Dequantize LSPs - * @param lsps output pointer to the array that will hold the LSPs - * @param num number of LSPs to be dequantized - * @param values quantized values, contains n_stages values - * @param sizes range (i.e. max value) of each quantized value - * @param n_stages number of dequantization runs - * @param table dequantization table to be used - * @param mul_q LSF multiplier - * @param base_q base (lowest) LSF values - */ -static void dequant_lsps(double *lsps, int num, - const uint16_t *values, - const uint16_t *sizes, - int n_stages, const uint8_t *table, - const double *mul_q, - const double *base_q) -{ - int n, m; - - memset(lsps, 0, num * sizeof(*lsps)); - for (n = 0; n < n_stages; n++) { - const uint8_t *t_off = &table[values[n] * num]; - double base = base_q[n], mul = mul_q[n]; - - for (m = 0; m < num; m++) - lsps[m] += base + mul * t_off[m]; - - table += sizes[n] * num; - } -} - -/** - * @defgroup lsp_dequant LSP dequantization routines - * LSP dequantization routines, for 10/16LSPs and independent/residual coding. - * @note we assume enough bits are available, caller should check. - * lsp10i() consumes 24 bits; lsp10r() consumes an additional 24 bits; - * lsp16i() consumes 34 bits; lsp16r() consumes an additional 26 bits. - * @{ - */ -/** - * Parse 10 independently-coded LSPs. - */ -static void dequant_lsp10i(GetBitContext *gb, double *lsps) -{ - static const uint16_t vec_sizes[4] = { 256, 64, 32, 32 }; - static const double mul_lsf[4] = { - 5.2187144800e-3, 1.4626986422e-3, - 9.6179549166e-4, 1.1325736225e-3 - }; - static const double base_lsf[4] = { - M_PI * -2.15522e-1, M_PI * -6.1646e-2, - M_PI * -3.3486e-2, M_PI * -5.7408e-2 - }; - uint16_t v[4]; - - v[0] = get_bits(gb, 8); - v[1] = get_bits(gb, 6); - v[2] = get_bits(gb, 5); - v[3] = get_bits(gb, 5); - - dequant_lsps(lsps, 10, v, vec_sizes, 4, wmavoice_dq_lsp10i, - mul_lsf, base_lsf); -} - -/** - * Parse 10 independently-coded LSPs, and then derive the tables to - * generate LSPs for the other frames from them (residual coding). - */ -static void dequant_lsp10r(GetBitContext *gb, - double *i_lsps, const double *old, - double *a1, double *a2, int q_mode) -{ - static const uint16_t vec_sizes[3] = { 128, 64, 64 }; - static const double mul_lsf[3] = { - 2.5807601174e-3, 1.2354460219e-3, 1.1763821673e-3 - }; - static const double base_lsf[3] = { - M_PI * -1.07448e-1, M_PI * -5.2706e-2, M_PI * -5.1634e-2 - }; - const float (*ipol_tab)[2][10] = q_mode ? - wmavoice_lsp10_intercoeff_b : wmavoice_lsp10_intercoeff_a; - uint16_t interpol, v[3]; - int n; - - dequant_lsp10i(gb, i_lsps); - - interpol = get_bits(gb, 5); - v[0] = get_bits(gb, 7); - v[1] = get_bits(gb, 6); - v[2] = get_bits(gb, 6); - - for (n = 0; n < 10; n++) { - double delta = old[n] - i_lsps[n]; - a1[n] = ipol_tab[interpol][0][n] * delta + i_lsps[n]; - a1[10 + n] = ipol_tab[interpol][1][n] * delta + i_lsps[n]; - } - - dequant_lsps(a2, 20, v, vec_sizes, 3, wmavoice_dq_lsp10r, - mul_lsf, base_lsf); -} - -/** - * Parse 16 independently-coded LSPs. - */ -static void dequant_lsp16i(GetBitContext *gb, double *lsps) -{ - static const uint16_t vec_sizes[5] = { 256, 64, 128, 64, 128 }; - static const double mul_lsf[5] = { - 3.3439586280e-3, 6.9908173703e-4, - 3.3216608306e-3, 1.0334960326e-3, - 3.1899104283e-3 - }; - static const double base_lsf[5] = { - M_PI * -1.27576e-1, M_PI * -2.4292e-2, - M_PI * -1.28094e-1, M_PI * -3.2128e-2, - M_PI * -1.29816e-1 - }; - uint16_t v[5]; - - v[0] = get_bits(gb, 8); - v[1] = get_bits(gb, 6); - v[2] = get_bits(gb, 7); - v[3] = get_bits(gb, 6); - v[4] = get_bits(gb, 7); - - dequant_lsps( lsps, 5, v, vec_sizes, 2, - wmavoice_dq_lsp16i1, mul_lsf, base_lsf); - dequant_lsps(&lsps[5], 5, &v[2], &vec_sizes[2], 2, - wmavoice_dq_lsp16i2, &mul_lsf[2], &base_lsf[2]); - dequant_lsps(&lsps[10], 6, &v[4], &vec_sizes[4], 1, - wmavoice_dq_lsp16i3, &mul_lsf[4], &base_lsf[4]); -} - -/** - * Parse 16 independently-coded LSPs, and then derive the tables to - * generate LSPs for the other frames from them (residual coding). - */ -static void dequant_lsp16r(GetBitContext *gb, - double *i_lsps, const double *old, - double *a1, double *a2, int q_mode) -{ - static const uint16_t vec_sizes[3] = { 128, 128, 128 }; - static const double mul_lsf[3] = { - 1.2232979501e-3, 1.4062241527e-3, 1.6114744851e-3 - }; - static const double base_lsf[3] = { - M_PI * -5.5830e-2, M_PI * -5.2908e-2, M_PI * -5.4776e-2 - }; - const float (*ipol_tab)[2][16] = q_mode ? - wmavoice_lsp16_intercoeff_b : wmavoice_lsp16_intercoeff_a; - uint16_t interpol, v[3]; - int n; - - dequant_lsp16i(gb, i_lsps); - - interpol = get_bits(gb, 5); - v[0] = get_bits(gb, 7); - v[1] = get_bits(gb, 7); - v[2] = get_bits(gb, 7); - - for (n = 0; n < 16; n++) { - double delta = old[n] - i_lsps[n]; - a1[n] = ipol_tab[interpol][0][n] * delta + i_lsps[n]; - a1[16 + n] = ipol_tab[interpol][1][n] * delta + i_lsps[n]; - } - - dequant_lsps( a2, 10, v, vec_sizes, 1, - wmavoice_dq_lsp16r1, mul_lsf, base_lsf); - dequant_lsps(&a2[10], 10, &v[1], &vec_sizes[1], 1, - wmavoice_dq_lsp16r2, &mul_lsf[1], &base_lsf[1]); - dequant_lsps(&a2[20], 12, &v[2], &vec_sizes[2], 1, - wmavoice_dq_lsp16r3, &mul_lsf[2], &base_lsf[2]); -} - -/** - * @} - * @defgroup aw Pitch-adaptive window coding functions - * The next few functions are for pitch-adaptive window coding. - * @{ - */ -/** - * Parse the offset of the first pitch-adaptive window pulses, and - * the distribution of pulses between the two blocks in this frame. - * @param s WMA Voice decoding context private data - * @param gb bit I/O context - * @param pitch pitch for each block in this frame - */ -static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb, - const int *pitch) -{ - static const int16_t start_offset[94] = { - -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, - 13, 15, 18, 17, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 35, 37, 39, 41, 43, - 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, - 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, - 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, - 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, - 141, 143, 145, 147, 149, 151, 153, 155, 157, 159 - }; - int bits, offset; - - /* position of pulse */ - s->aw_idx_is_ext = 0; - if ((bits = get_bits(gb, 6)) >= 54) { - s->aw_idx_is_ext = 1; - bits += (bits - 54) * 3 + get_bits(gb, 2); - } - - /* for a repeated pulse at pulse_off with a pitch_lag of pitch[], count - * the distribution of the pulses in each block contained in this frame. */ - s->aw_pulse_range = FFMIN(pitch[0], pitch[1]) > 32 ? 24 : 16; - for (offset = start_offset[bits]; offset < 0; offset += pitch[0]) ; - s->aw_n_pulses[0] = (pitch[0] - 1 + MAX_FRAMESIZE / 2 - offset) / pitch[0]; - s->aw_first_pulse_off[0] = offset - s->aw_pulse_range / 2; - offset += s->aw_n_pulses[0] * pitch[0]; - s->aw_n_pulses[1] = (pitch[1] - 1 + MAX_FRAMESIZE - offset) / pitch[1]; - s->aw_first_pulse_off[1] = offset - (MAX_FRAMESIZE + s->aw_pulse_range) / 2; - - /* if continuing from a position before the block, reset position to - * start of block (when corrected for the range over which it can be - * spread in aw_pulse_set1()). */ - if (start_offset[bits] < MAX_FRAMESIZE / 2) { - while (s->aw_first_pulse_off[1] - pitch[1] + s->aw_pulse_range > 0) - s->aw_first_pulse_off[1] -= pitch[1]; - if (start_offset[bits] < 0) - while (s->aw_first_pulse_off[0] - pitch[0] + s->aw_pulse_range > 0) - s->aw_first_pulse_off[0] -= pitch[0]; - } -} - -/** - * Apply second set of pitch-adaptive window pulses. - * @param s WMA Voice decoding context private data - * @param gb bit I/O context - * @param block_idx block index in frame [0, 1] - * @param fcb structure containing fixed codebook vector info - */ -static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, AMRFixed *fcb) -{ - uint16_t use_mask[7]; // only 5 are used, rest is padding - /* in this function, idx is the index in the 80-bit (+ padding) use_mask - * bit-array. Since use_mask consists of 16-bit values, the lower 4 bits - * of idx are the position of the bit within a particular item in the - * array (0 being the most significant bit, and 15 being the least - * significant bit), and the remainder (>> 4) is the index in the - * use_mask[]-array. This is faster and uses less memory than using a - * 80-byte/80-int array. */ - int pulse_off = s->aw_first_pulse_off[block_idx], - pulse_start, n, idx, range, aidx, start_off = 0; - - /* set offset of first pulse to within this block */ - if (s->aw_n_pulses[block_idx] > 0) - while (pulse_off + s->aw_pulse_range < 1) - pulse_off += fcb->pitch_lag; - - /* find range per pulse */ - if (s->aw_n_pulses[0] > 0) { - if (block_idx == 0) { - range = 32; - } else /* block_idx = 1 */ { - range = 8; - if (s->aw_n_pulses[block_idx] > 0) - pulse_off = s->aw_next_pulse_off_cache; - } - } else - range = 16; - pulse_start = s->aw_n_pulses[block_idx] > 0 ? pulse_off - range / 2 : 0; - - /* aw_pulse_set1() already applies pulses around pulse_off (to be exactly, - * in the range of [pulse_off, pulse_off + s->aw_pulse_range], and thus - * we exclude that range from being pulsed again in this function. */ - memset( use_mask, -1, 5 * sizeof(use_mask[0])); - memset(&use_mask[5], 0, 2 * sizeof(use_mask[0])); - if (s->aw_n_pulses[block_idx] > 0) - for (idx = pulse_off; idx < MAX_FRAMESIZE / 2; idx += fcb->pitch_lag) { - int excl_range = s->aw_pulse_range; // always 16 or 24 - uint16_t *use_mask_ptr = &use_mask[idx >> 4]; - int first_sh = 16 - (idx & 15); - *use_mask_ptr++ &= 0xFFFF << first_sh; - excl_range -= first_sh; - if (excl_range >= 16) { - *use_mask_ptr++ = 0; - *use_mask_ptr &= 0xFFFF >> (excl_range - 16); - } else - *use_mask_ptr &= 0xFFFF >> excl_range; - } - - /* find the 'aidx'th offset that is not excluded */ - aidx = get_bits(gb, s->aw_n_pulses[0] > 0 ? 5 - 2 * block_idx : 4); - for (n = 0; n <= aidx; pulse_start++) { - for (idx = pulse_start; idx < 0; idx += fcb->pitch_lag) ; - if (idx >= MAX_FRAMESIZE / 2) { // find from zero - if (use_mask[0]) idx = 0x0F; - else if (use_mask[1]) idx = 0x1F; - else if (use_mask[2]) idx = 0x2F; - else if (use_mask[3]) idx = 0x3F; - else if (use_mask[4]) idx = 0x4F; - else return; - idx -= av_log2_16bit(use_mask[idx >> 4]); - } - if (use_mask[idx >> 4] & (0x8000 >> (idx & 15))) { - use_mask[idx >> 4] &= ~(0x8000 >> (idx & 15)); - n++; - start_off = idx; - } - } - - fcb->x[fcb->n] = start_off; - fcb->y[fcb->n] = get_bits1(gb) ? -1.0 : 1.0; - fcb->n++; - - /* set offset for next block, relative to start of that block */ - n = (MAX_FRAMESIZE / 2 - start_off) % fcb->pitch_lag; - s->aw_next_pulse_off_cache = n ? fcb->pitch_lag - n : 0; -} - -/** - * Apply first set of pitch-adaptive window pulses. - * @param s WMA Voice decoding context private data - * @param gb bit I/O context - * @param block_idx block index in frame [0, 1] - * @param fcb storage location for fixed codebook pulse info - */ -static void aw_pulse_set1(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, AMRFixed *fcb) -{ - int val = get_bits(gb, 12 - 2 * (s->aw_idx_is_ext && !block_idx)); - float v; - - if (s->aw_n_pulses[block_idx] > 0) { - int n, v_mask, i_mask, sh, n_pulses; - - if (s->aw_pulse_range == 24) { // 3 pulses, 1:sign + 3:index each - n_pulses = 3; - v_mask = 8; - i_mask = 7; - sh = 4; - } else { // 4 pulses, 1:sign + 2:index each - n_pulses = 4; - v_mask = 4; - i_mask = 3; - sh = 3; - } - - for (n = n_pulses - 1; n >= 0; n--, val >>= sh) { - fcb->y[fcb->n] = (val & v_mask) ? -1.0 : 1.0; - fcb->x[fcb->n] = (val & i_mask) * n_pulses + n + - s->aw_first_pulse_off[block_idx]; - while (fcb->x[fcb->n] < 0) - fcb->x[fcb->n] += fcb->pitch_lag; - if (fcb->x[fcb->n] < MAX_FRAMESIZE / 2) - fcb->n++; - } - } else { - int num2 = (val & 0x1FF) >> 1, delta, idx; - - if (num2 < 1 * 79) { delta = 1; idx = num2 + 1; } - else if (num2 < 2 * 78) { delta = 3; idx = num2 + 1 - 1 * 77; } - else if (num2 < 3 * 77) { delta = 5; idx = num2 + 1 - 2 * 76; } - else { delta = 7; idx = num2 + 1 - 3 * 75; } - v = (val & 0x200) ? -1.0 : 1.0; - - fcb->no_repeat_mask |= 3 << fcb->n; - fcb->x[fcb->n] = idx - delta; - fcb->y[fcb->n] = v; - fcb->x[fcb->n + 1] = idx; - fcb->y[fcb->n + 1] = (val & 1) ? -v : v; - fcb->n += 2; - } -} - -/** - * @} - * - * Generate a random number from frame_cntr and block_idx, which will lief - * in the range [0, 1000 - block_size] (so it can be used as an index in a - * table of size 1000 of which you want to read block_size entries). - * - * @param frame_cntr current frame number - * @param block_num current block index - * @param block_size amount of entries we want to read from a table - * that has 1000 entries - * @return a (non-)random number in the [0, 1000 - block_size] range. - */ -static int pRNG(int frame_cntr, int block_num, int block_size) -{ - /* array to simplify the calculation of z: - * y = (x % 9) * 5 + 6; - * z = (49995 * x) / y; - * Since y only has 9 values, we can remove the division by using a - * LUT and using FASTDIV-style divisions. For each of the 9 values - * of y, we can rewrite z as: - * z = x * (49995 / y) + x * ((49995 % y) / y) - * In this table, each col represents one possible value of y, the - * first number is 49995 / y, and the second is the FASTDIV variant - * of 49995 % y / y. */ - static const unsigned int div_tbl[9][2] = { - { 8332, 3 * 715827883U }, // y = 6 - { 4545, 0 * 390451573U }, // y = 11 - { 3124, 11 * 268435456U }, // y = 16 - { 2380, 15 * 204522253U }, // y = 21 - { 1922, 23 * 165191050U }, // y = 26 - { 1612, 23 * 138547333U }, // y = 31 - { 1388, 27 * 119304648U }, // y = 36 - { 1219, 16 * 104755300U }, // y = 41 - { 1086, 39 * 93368855U } // y = 46 - }; - unsigned int z, y, x = MUL16(block_num, 1877) + frame_cntr; - if (x >= 0xFFFF) x -= 0xFFFF; // max value of x is 8*1877+0xFFFE=0x13AA6, - // so this is effectively a modulo (%) - y = x - 9 * MULH(477218589, x); // x % 9 - z = (uint16_t) (x * div_tbl[y][0] + UMULH(x, div_tbl[y][1])); - // z = x * 49995 / (y * 5 + 6) - return z % (1000 - block_size); -} - -/** - * Parse hardcoded signal for a single block. - * @note see #synth_block(). - */ -static void synth_block_hardcoded(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, int size, - const struct frame_type_desc *frame_desc, - float *excitation) -{ - float gain; - int n, r_idx; - - assert(size <= MAX_FRAMESIZE); - - /* Set the offset from which we start reading wmavoice_std_codebook */ - if (frame_desc->fcb_type == FCB_TYPE_SILENCE) { - r_idx = pRNG(s->frame_cntr, block_idx, size); - gain = s->silence_gain; - } else /* FCB_TYPE_HARDCODED */ { - r_idx = get_bits(gb, 8); - gain = wmavoice_gain_universal[get_bits(gb, 6)]; - } - - /* Clear gain prediction parameters */ - memset(s->gain_pred_err, 0, sizeof(s->gain_pred_err)); - - /* Apply gain to hardcoded codebook and use that as excitation signal */ - for (n = 0; n < size; n++) - excitation[n] = wmavoice_std_codebook[r_idx + n] * gain; -} - -/** - * Parse FCB/ACB signal for a single block. - * @note see #synth_block(). - */ -static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, int size, - int block_pitch_sh2, - const struct frame_type_desc *frame_desc, - float *excitation) -{ - static const float gain_coeff[6] = { - 0.8169, -0.06545, 0.1726, 0.0185, -0.0359, 0.0458 - }; - float pulses[MAX_FRAMESIZE / 2], pred_err, acb_gain, fcb_gain; - int n, idx, gain_weight; - AMRFixed fcb; - - assert(size <= MAX_FRAMESIZE / 2); - memset(pulses, 0, sizeof(*pulses) * size); - - fcb.pitch_lag = block_pitch_sh2 >> 2; - fcb.pitch_fac = 1.0; - fcb.no_repeat_mask = 0; - fcb.n = 0; - - /* For the other frame types, this is where we apply the innovation - * (fixed) codebook pulses of the speech signal. */ - if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { - aw_pulse_set1(s, gb, block_idx, &fcb); - aw_pulse_set2(s, gb, block_idx, &fcb); - } else /* FCB_TYPE_EXC_PULSES */ { - int offset_nbits = 5 - frame_desc->log_n_blocks; - - fcb.no_repeat_mask = -1; - /* similar to ff_decode_10_pulses_35bits(), but with single pulses - * (instead of double) for a subset of pulses */ - for (n = 0; n < 5; n++) { - float sign; - int pos1, pos2; - - sign = get_bits1(gb) ? 1.0 : -1.0; - pos1 = get_bits(gb, offset_nbits); - fcb.x[fcb.n] = n + 5 * pos1; - fcb.y[fcb.n++] = sign; - if (n < frame_desc->dbl_pulses) { - pos2 = get_bits(gb, offset_nbits); - fcb.x[fcb.n] = n + 5 * pos2; - fcb.y[fcb.n++] = (pos1 < pos2) ? -sign : sign; - } - } - } - ff_set_fixed_vector(pulses, &fcb, 1.0, size); - - /* Calculate gain for adaptive & fixed codebook signal. - * see ff_amr_set_fixed_gain(). */ - idx = get_bits(gb, 7); - fcb_gain = expf(ff_dot_productf(s->gain_pred_err, gain_coeff, 6) - - 5.2409161640 + wmavoice_gain_codebook_fcb[idx]); - acb_gain = wmavoice_gain_codebook_acb[idx]; - pred_err = av_clipf(wmavoice_gain_codebook_fcb[idx], - -2.9957322736 /* log(0.05) */, - 1.6094379124 /* log(5.0) */); - - gain_weight = 8 >> frame_desc->log_n_blocks; - memmove(&s->gain_pred_err[gain_weight], s->gain_pred_err, - sizeof(*s->gain_pred_err) * (6 - gain_weight)); - for (n = 0; n < gain_weight; n++) - s->gain_pred_err[n] = pred_err; - - /* Calculation of adaptive codebook */ - if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) { - int len; - for (n = 0; n < size; n += len) { - int next_idx_sh16; - int abs_idx = block_idx * size + n; - int pitch_sh16 = (s->last_pitch_val << 16) + - s->pitch_diff_sh16 * abs_idx; - int pitch = (pitch_sh16 + 0x6FFF) >> 16; - int idx_sh16 = ((pitch << 16) - pitch_sh16) * 8 + 0x58000; - idx = idx_sh16 >> 16; - if (s->pitch_diff_sh16) { - if (s->pitch_diff_sh16 > 0) { - next_idx_sh16 = (idx_sh16) &~ 0xFFFF; - } else - next_idx_sh16 = (idx_sh16 + 0x10000) &~ 0xFFFF; - len = av_clip((idx_sh16 - next_idx_sh16) / s->pitch_diff_sh16 / 8, - 1, size - n); - } else - len = size; - - ff_acelp_interpolatef(&excitation[n], &excitation[n - pitch], - wmavoice_ipol1_coeffs, 17, - idx, 9, len); - } - } else /* ACB_TYPE_HAMMING */ { - int block_pitch = block_pitch_sh2 >> 2; - idx = block_pitch_sh2 & 3; - if (idx) { - ff_acelp_interpolatef(excitation, &excitation[-block_pitch], - wmavoice_ipol2_coeffs, 4, - idx, 8, size); - } else - av_memcpy_backptr(excitation, sizeof(float) * block_pitch, - sizeof(float) * size); - } - - /* Interpolate ACB/FCB and use as excitation signal */ - ff_weighted_vector_sumf(excitation, excitation, pulses, - acb_gain, fcb_gain, size); -} - -/** - * Parse data in a single block. - * @note we assume enough bits are available, caller should check. - * - * @param s WMA Voice decoding context private data - * @param gb bit I/O context - * @param block_idx index of the to-be-read block - * @param size amount of samples to be read in this block - * @param block_pitch_sh2 pitch for this block << 2 - * @param lsps LSPs for (the end of) this frame - * @param prev_lsps LSPs for the last frame - * @param frame_desc frame type descriptor - * @param excitation target memory for the ACB+FCB interpolated signal - * @param synth target memory for the speech synthesis filter output - * @return 0 on success, <0 on error. - */ -static void synth_block(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, int size, - int block_pitch_sh2, - const double *lsps, const double *prev_lsps, - const struct frame_type_desc *frame_desc, - float *excitation, float *synth) -{ - double i_lsps[MAX_LSPS]; - float lpcs[MAX_LSPS]; - float fac; - int n; - - if (frame_desc->acb_type == ACB_TYPE_NONE) - synth_block_hardcoded(s, gb, block_idx, size, frame_desc, excitation); - else - synth_block_fcb_acb(s, gb, block_idx, size, block_pitch_sh2, - frame_desc, excitation); - - /* convert interpolated LSPs to LPCs */ - fac = (block_idx + 0.5) / frame_desc->n_blocks; - for (n = 0; n < s->lsps; n++) // LSF -> LSP - i_lsps[n] = cos(prev_lsps[n] + fac * (lsps[n] - prev_lsps[n])); - ff_acelp_lspd2lpc(i_lsps, lpcs, s->lsps >> 1); - - /* Speech synthesis */ - ff_celp_lp_synthesis_filterf(synth, lpcs, excitation, size, s->lsps); -} - -/** - * Synthesize output samples for a single frame. - * @note we assume enough bits are available, caller should check. - * - * @param ctx WMA Voice decoder context - * @param gb bit I/O context (s->gb or one for cross-packet superframes) - * @param frame_idx Frame number within superframe [0-2] - * @param samples pointer to output sample buffer, has space for at least 160 - * samples - * @param lsps LSP array - * @param prev_lsps array of previous frame's LSPs - * @param excitation target buffer for excitation signal - * @param synth target buffer for synthesized speech data - * @return 0 on success, <0 on error. - */ -static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, - float *samples, - const double *lsps, const double *prev_lsps, - float *excitation, float *synth) -{ - WMAVoiceContext *s = ctx->priv_data; - int n, n_blocks_x2, log_n_blocks_x2, cur_pitch_val; - int pitch[MAX_BLOCKS], last_block_pitch; - - /* Parse frame type ("frame header"), see frame_descs */ - int bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)], - block_nsamples = MAX_FRAMESIZE / frame_descs[bd_idx].n_blocks; - - if (bd_idx < 0) { - av_log(ctx, AV_LOG_ERROR, - "Invalid frame type VLC code, skipping\n"); - return -1; - } - - /* Pitch calculation for ACB_TYPE_ASYMMETRIC ("pitch-per-frame") */ - if (frame_descs[bd_idx].acb_type == ACB_TYPE_ASYMMETRIC) { - /* Pitch is provided per frame, which is interpreted as the pitch of - * the last sample of the last block of this frame. We can interpolate - * the pitch of other blocks (and even pitch-per-sample) by gradually - * incrementing/decrementing prev_frame_pitch to cur_pitch_val. */ - n_blocks_x2 = frame_descs[bd_idx].n_blocks << 1; - log_n_blocks_x2 = frame_descs[bd_idx].log_n_blocks + 1; - cur_pitch_val = s->min_pitch_val + get_bits(gb, s->pitch_nbits); - cur_pitch_val = FFMIN(cur_pitch_val, s->max_pitch_val - 1); - if (s->last_acb_type == ACB_TYPE_NONE || - 20 * abs(cur_pitch_val - s->last_pitch_val) > - (cur_pitch_val + s->last_pitch_val)) - s->last_pitch_val = cur_pitch_val; - - /* pitch per block */ - for (n = 0; n < frame_descs[bd_idx].n_blocks; n++) { - int fac = n * 2 + 1; - - pitch[n] = (MUL16(fac, cur_pitch_val) + - MUL16((n_blocks_x2 - fac), s->last_pitch_val) + - frame_descs[bd_idx].n_blocks) >> log_n_blocks_x2; - } - - /* "pitch-diff-per-sample" for calculation of pitch per sample */ - s->pitch_diff_sh16 = - ((cur_pitch_val - s->last_pitch_val) << 16) / MAX_FRAMESIZE; - } - - /* Global gain (if silence) and pitch-adaptive window coordinates */ - switch (frame_descs[bd_idx].fcb_type) { - case FCB_TYPE_SILENCE: - s->silence_gain = wmavoice_gain_silence[get_bits(gb, 8)]; - break; - case FCB_TYPE_AW_PULSES: - aw_parse_coords(s, gb, pitch); - break; - } - - for (n = 0; n < frame_descs[bd_idx].n_blocks; n++) { - int bl_pitch_sh2; - - /* Pitch calculation for ACB_TYPE_HAMMING ("pitch-per-block") */ - switch (frame_descs[bd_idx].acb_type) { - case ACB_TYPE_HAMMING: { - /* Pitch is given per block. Per-block pitches are encoded as an - * absolute value for the first block, and then delta values - * relative to this value) for all subsequent blocks. The scale of - * this pitch value is semi-logaritmic compared to its use in the - * decoder, so we convert it to normal scale also. */ - int block_pitch, - t1 = (s->block_conv_table[1] - s->block_conv_table[0]) << 2, - t2 = (s->block_conv_table[2] - s->block_conv_table[1]) << 1, - t3 = s->block_conv_table[3] - s->block_conv_table[2] + 1; - - if (n == 0) { - block_pitch = get_bits(gb, s->block_pitch_nbits); - } else - block_pitch = last_block_pitch - s->block_delta_pitch_hrange + - get_bits(gb, s->block_delta_pitch_nbits); - /* Convert last_ so that any next delta is within _range */ - last_block_pitch = av_clip(block_pitch, - s->block_delta_pitch_hrange, - s->block_pitch_range - - s->block_delta_pitch_hrange); - - /* Convert semi-log-style scale back to normal scale */ - if (block_pitch < t1) { - bl_pitch_sh2 = (s->block_conv_table[0] << 2) + block_pitch; - } else { - block_pitch -= t1; - if (block_pitch < t2) { - bl_pitch_sh2 = - (s->block_conv_table[1] << 2) + (block_pitch << 1); - } else { - block_pitch -= t2; - if (block_pitch < t3) { - bl_pitch_sh2 = - (s->block_conv_table[2] + block_pitch) << 2; - } else - bl_pitch_sh2 = s->block_conv_table[3] << 2; - } - } - pitch[n] = bl_pitch_sh2 >> 2; - break; - } - - case ACB_TYPE_ASYMMETRIC: { - bl_pitch_sh2 = pitch[n] << 2; - break; - } - - default: // ACB_TYPE_NONE has no pitch - bl_pitch_sh2 = 0; - break; - } - - synth_block(s, gb, n, block_nsamples, bl_pitch_sh2, - lsps, prev_lsps, &frame_descs[bd_idx], - &excitation[n * block_nsamples], - &synth[n * block_nsamples]); - } - - /* Averaging projection filter, if applicable. Else, just copy samples - * from synthesis buffer */ - if (s->do_apf) { - double i_lsps[MAX_LSPS]; - float lpcs[MAX_LSPS]; - - for (n = 0; n < s->lsps; n++) // LSF -> LSP - i_lsps[n] = cos(0.5 * (prev_lsps[n] + lsps[n])); - ff_acelp_lspd2lpc(i_lsps, lpcs, s->lsps >> 1); - postfilter(s, synth, samples, 80, lpcs, - &s->zero_exc_pf[s->history_nsamples + MAX_FRAMESIZE * frame_idx], - frame_descs[bd_idx].fcb_type, pitch[0]); - - for (n = 0; n < s->lsps; n++) // LSF -> LSP - i_lsps[n] = cos(lsps[n]); - ff_acelp_lspd2lpc(i_lsps, lpcs, s->lsps >> 1); - postfilter(s, &synth[80], &samples[80], 80, lpcs, - &s->zero_exc_pf[s->history_nsamples + MAX_FRAMESIZE * frame_idx + 80], - frame_descs[bd_idx].fcb_type, pitch[0]); - } else - memcpy(samples, synth, 160 * sizeof(synth[0])); - - /* Cache values for next frame */ - s->frame_cntr++; - if (s->frame_cntr >= 0xFFFF) s->frame_cntr -= 0xFFFF; // i.e. modulo (%) - s->last_acb_type = frame_descs[bd_idx].acb_type; - switch (frame_descs[bd_idx].acb_type) { - case ACB_TYPE_NONE: - s->last_pitch_val = 0; - break; - case ACB_TYPE_ASYMMETRIC: - s->last_pitch_val = cur_pitch_val; - break; - case ACB_TYPE_HAMMING: - s->last_pitch_val = pitch[frame_descs[bd_idx].n_blocks - 1]; - break; - } - - return 0; -} - -/** - * Ensure minimum value for first item, maximum value for last value, - * proper spacing between each value and proper ordering. - * - * @param lsps array of LSPs - * @param num size of LSP array - * - * @note basically a double version of #ff_acelp_reorder_lsf(), might be - * useful to put in a generic location later on. Parts are also - * present in #ff_set_min_dist_lsf() + #ff_sort_nearly_sorted_floats(), - * which is in float. - */ -static void stabilize_lsps(double *lsps, int num) -{ - int n, m, l; - - /* set minimum value for first, maximum value for last and minimum - * spacing between LSF values. - * Very similar to ff_set_min_dist_lsf(), but in double. */ - lsps[0] = FFMAX(lsps[0], 0.0015 * M_PI); - for (n = 1; n < num; n++) - lsps[n] = FFMAX(lsps[n], lsps[n - 1] + 0.0125 * M_PI); - lsps[num - 1] = FFMIN(lsps[num - 1], 0.9985 * M_PI); - - /* reorder (looks like one-time / non-recursed bubblesort). - * Very similar to ff_sort_nearly_sorted_floats(), but in double. */ - for (n = 1; n < num; n++) { - if (lsps[n] < lsps[n - 1]) { - for (m = 1; m < num; m++) { - double tmp = lsps[m]; - for (l = m - 1; l >= 0; l--) { - if (lsps[l] <= tmp) break; - lsps[l + 1] = lsps[l]; - } - lsps[l + 1] = tmp; - } - break; - } - } -} - -/** - * Test if there's enough bits to read 1 superframe. - * - * @param orig_gb bit I/O context used for reading. This function - * does not modify the state of the bitreader; it - * only uses it to copy the current stream position - * @param s WMA Voice decoding context private data - * @return -1 if unsupported, 1 on not enough bits or 0 if OK. - */ -static int check_bits_for_superframe(GetBitContext *orig_gb, - WMAVoiceContext *s) -{ - GetBitContext s_gb, *gb = &s_gb; - int n, need_bits, bd_idx; - const struct frame_type_desc *frame_desc; - - /* initialize a copy */ - init_get_bits(gb, orig_gb->buffer, orig_gb->size_in_bits); - skip_bits_long(gb, get_bits_count(orig_gb)); - assert(get_bits_left(gb) == get_bits_left(orig_gb)); - - /* superframe header */ - if (get_bits_left(gb) < 14) - return 1; - if (!get_bits1(gb)) - return -1; // WMAPro-in-WMAVoice superframe - if (get_bits1(gb)) skip_bits(gb, 12); // number of samples in superframe - if (s->has_residual_lsps) { // residual LSPs (for all frames) - if (get_bits_left(gb) < s->sframe_lsp_bitsize) - return 1; - skip_bits_long(gb, s->sframe_lsp_bitsize); - } - - /* frames */ - for (n = 0; n < MAX_FRAMES; n++) { - int aw_idx_is_ext = 0; - - if (!s->has_residual_lsps) { // independent LSPs (per-frame) - if (get_bits_left(gb) < s->frame_lsp_bitsize) return 1; - skip_bits_long(gb, s->frame_lsp_bitsize); - } - bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)]; - if (bd_idx < 0) - return -1; // invalid frame type VLC code - frame_desc = &frame_descs[bd_idx]; - if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) { - if (get_bits_left(gb) < s->pitch_nbits) - return 1; - skip_bits_long(gb, s->pitch_nbits); - } - if (frame_desc->fcb_type == FCB_TYPE_SILENCE) { - skip_bits(gb, 8); - } else if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { - int tmp = get_bits(gb, 6); - if (tmp >= 0x36) { - skip_bits(gb, 2); - aw_idx_is_ext = 1; - } - } - - /* blocks */ - if (frame_desc->acb_type == ACB_TYPE_HAMMING) { - need_bits = s->block_pitch_nbits + - (frame_desc->n_blocks - 1) * s->block_delta_pitch_nbits; - } else if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { - need_bits = 2 * !aw_idx_is_ext; - } else - need_bits = 0; - need_bits += frame_desc->frame_size; - if (get_bits_left(gb) < need_bits) - return 1; - skip_bits_long(gb, need_bits); - } - - return 0; -} - -/** - * Synthesize output samples for a single superframe. If we have any data - * cached in s->sframe_cache, that will be used instead of whatever is loaded - * in s->gb. - * - * WMA Voice superframes contain 3 frames, each containing 160 audio samples, - * to give a total of 480 samples per frame. See #synth_frame() for frame - * parsing. In addition to 3 frames, superframes can also contain the LSPs - * (if these are globally specified for all frames (residually); they can - * also be specified individually per-frame. See the s->has_residual_lsps - * option), and can specify the number of samples encoded in this superframe - * (if less than 480), usually used to prevent blanks at track boundaries. - * - * @param ctx WMA Voice decoder context - * @param samples pointer to output buffer for voice samples - * @param data_size pointer containing the size of #samples on input, and the - * amount of #samples filled on output - * @return 0 on success, <0 on error or 1 if there was not enough data to - * fully parse the superframe - */ -static int synth_superframe(AVCodecContext *ctx, - float *samples, int *data_size) -{ - WMAVoiceContext *s = ctx->priv_data; - GetBitContext *gb = &s->gb, s_gb; - int n, res, n_samples = 480; - double lsps[MAX_FRAMES][MAX_LSPS]; - const double *mean_lsf = s->lsps == 16 ? - wmavoice_mean_lsf16[s->lsp_def_mode] : wmavoice_mean_lsf10[s->lsp_def_mode]; - float excitation[MAX_SIGNAL_HISTORY + MAX_SFRAMESIZE + 12]; - float synth[MAX_LSPS + MAX_SFRAMESIZE]; - - memcpy(synth, s->synth_history, - s->lsps * sizeof(*synth)); - memcpy(excitation, s->excitation_history, - s->history_nsamples * sizeof(*excitation)); - - if (s->sframe_cache_size > 0) { - gb = &s_gb; - init_get_bits(gb, s->sframe_cache, s->sframe_cache_size); - s->sframe_cache_size = 0; - } - - if ((res = check_bits_for_superframe(gb, s)) == 1) return 1; - - /* First bit is speech/music bit, it differentiates between WMAVoice - * speech samples (the actual codec) and WMAVoice music samples, which - * are really WMAPro-in-WMAVoice-superframes. I've never seen those in - * the wild yet. */ - if (!get_bits1(gb)) { - av_log_missing_feature(ctx, "WMAPro-in-WMAVoice support", 1); - return -1; - } - - /* (optional) nr. of samples in superframe; always <= 480 and >= 0 */ - if (get_bits1(gb)) { - if ((n_samples = get_bits(gb, 12)) > 480) { - av_log(ctx, AV_LOG_ERROR, - "Superframe encodes >480 samples (%d), not allowed\n", - n_samples); - return -1; - } - } - /* Parse LSPs, if global for the superframe (can also be per-frame). */ - if (s->has_residual_lsps) { - double prev_lsps[MAX_LSPS], a1[MAX_LSPS * 2], a2[MAX_LSPS * 2]; - - for (n = 0; n < s->lsps; n++) - prev_lsps[n] = s->prev_lsps[n] - mean_lsf[n]; - - if (s->lsps == 10) { - dequant_lsp10r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode); - } else /* s->lsps == 16 */ - dequant_lsp16r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode); - - for (n = 0; n < s->lsps; n++) { - lsps[0][n] = mean_lsf[n] + (a1[n] - a2[n * 2]); - lsps[1][n] = mean_lsf[n] + (a1[s->lsps + n] - a2[n * 2 + 1]); - lsps[2][n] += mean_lsf[n]; - } - for (n = 0; n < 3; n++) - stabilize_lsps(lsps[n], s->lsps); - } - - /* Parse frames, optionally preceeded by per-frame (independent) LSPs. */ - for (n = 0; n < 3; n++) { - if (!s->has_residual_lsps) { - int m; - - if (s->lsps == 10) { - dequant_lsp10i(gb, lsps[n]); - } else /* s->lsps == 16 */ - dequant_lsp16i(gb, lsps[n]); - - for (m = 0; m < s->lsps; m++) - lsps[n][m] += mean_lsf[m]; - stabilize_lsps(lsps[n], s->lsps); - } - - if ((res = synth_frame(ctx, gb, n, - &samples[n * MAX_FRAMESIZE], - lsps[n], n == 0 ? s->prev_lsps : lsps[n - 1], - &excitation[s->history_nsamples + n * MAX_FRAMESIZE], - &synth[s->lsps + n * MAX_FRAMESIZE]))) - return res; - } - - /* Statistics? FIXME - we don't check for length, a slight overrun - * will be caught by internal buffer padding, and anything else - * will be skipped, not read. */ - if (get_bits1(gb)) { - res = get_bits(gb, 4); - skip_bits(gb, 10 * (res + 1)); - } - - /* Specify nr. of output samples */ - *data_size = n_samples * sizeof(float); - - /* Update history */ - memcpy(s->prev_lsps, lsps[2], - s->lsps * sizeof(*s->prev_lsps)); - memcpy(s->synth_history, &synth[MAX_SFRAMESIZE], - s->lsps * sizeof(*synth)); - memcpy(s->excitation_history, &excitation[MAX_SFRAMESIZE], - s->history_nsamples * sizeof(*excitation)); - if (s->do_apf) - memmove(s->zero_exc_pf, &s->zero_exc_pf[MAX_SFRAMESIZE], - s->history_nsamples * sizeof(*s->zero_exc_pf)); - - return 0; -} - -/** - * Parse the packet header at the start of each packet (input data to this - * decoder). - * - * @param s WMA Voice decoding context private data - * @return 1 if not enough bits were available, or 0 on success. - */ -static int parse_packet_header(WMAVoiceContext *s) -{ - GetBitContext *gb = &s->gb; - unsigned int res; - - if (get_bits_left(gb) < 11) - return 1; - skip_bits(gb, 4); // packet sequence number - s->has_residual_lsps = get_bits1(gb); - do { - res = get_bits(gb, 6); // number of superframes per packet - // (minus first one if there is spillover) - if (get_bits_left(gb) < 6 * (res == 0x3F) + s->spillover_bitsize) - return 1; - } while (res == 0x3F); - s->spillover_nbits = get_bits(gb, s->spillover_bitsize); - - return 0; -} - -/** - * Copy (unaligned) bits from gb/data/size to pb. - * - * @param pb target buffer to copy bits into - * @param data source buffer to copy bits from - * @param size size of the source data, in bytes - * @param gb bit I/O context specifying the current position in the source. - * data. This function might use this to align the bit position to - * a whole-byte boundary before calling #ff_copy_bits() on aligned - * source data - * @param nbits the amount of bits to copy from source to target - * - * @note after calling this function, the current position in the input bit - * I/O context is undefined. - */ -static void copy_bits(PutBitContext *pb, - const uint8_t *data, int size, - GetBitContext *gb, int nbits) -{ - int rmn_bytes, rmn_bits; - - rmn_bits = rmn_bytes = get_bits_left(gb); - if (rmn_bits < nbits) - return; - rmn_bits &= 7; rmn_bytes >>= 3; - if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0) - put_bits(pb, rmn_bits, get_bits(gb, rmn_bits)); - ff_copy_bits(pb, data + size - rmn_bytes, - FFMIN(nbits - rmn_bits, rmn_bytes << 3)); -} - -/** - * Packet decoding: a packet is anything that the (ASF) demuxer contains, - * and we expect that the demuxer / application provides it to us as such - * (else you'll probably get garbage as output). Every packet has a size of - * ctx->block_align bytes, starts with a packet header (see - * #parse_packet_header()), and then a series of superframes. Superframe - * boundaries may exceed packets, i.e. superframes can split data over - * multiple (two) packets. - * - * For more information about frames, see #synth_superframe(). - */ -static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, - int *data_size, AVPacket *avpkt) -{ - WMAVoiceContext *s = ctx->priv_data; - GetBitContext *gb = &s->gb; - int size, res, pos; - - if (*data_size < 480 * sizeof(float)) { - av_log(ctx, AV_LOG_ERROR, - "Output buffer too small (%d given - %lu needed)\n", - *data_size, 480 * sizeof(float)); - return -1; - } - *data_size = 0; - - /* Packets are sometimes a multiple of ctx->block_align, with a packet - * header at each ctx->block_align bytes. However, FFmpeg's ASF demuxer - * feeds us ASF packets, which may concatenate multiple "codec" packets - * in a single "muxer" packet, so we artificially emulate that by - * capping the packet size at ctx->block_align. */ - for (size = avpkt->size; size > ctx->block_align; size -= ctx->block_align); - if (!size) - return 0; - init_get_bits(&s->gb, avpkt->data, size << 3); - - /* size == ctx->block_align is used to indicate whether we are dealing with - * a new packet or a packet of which we already read the packet header - * previously. */ - if (size == ctx->block_align) { // new packet header - if ((res = parse_packet_header(s)) < 0) - return res; - - /* If the packet header specifies a s->spillover_nbits, then we want - * to push out all data of the previous packet (+ spillover) before - * continuing to parse new superframes in the current packet. */ - if (s->spillover_nbits > 0) { - if (s->sframe_cache_size > 0) { - int cnt = get_bits_count(gb); - copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits); - flush_put_bits(&s->pb); - s->sframe_cache_size += s->spillover_nbits; - if ((res = synth_superframe(ctx, data, data_size)) == 0 && - *data_size > 0) { - cnt += s->spillover_nbits; - s->skip_bits_next = cnt & 7; - return cnt >> 3; - } else - skip_bits_long (gb, s->spillover_nbits - cnt + - get_bits_count(gb)); // resync - } else - skip_bits_long(gb, s->spillover_nbits); // resync - } - } else if (s->skip_bits_next) - skip_bits(gb, s->skip_bits_next); - - /* Try parsing superframes in current packet */ - s->sframe_cache_size = 0; - s->skip_bits_next = 0; - pos = get_bits_left(gb); - if ((res = synth_superframe(ctx, data, data_size)) < 0) { - return res; - } else if (*data_size > 0) { - int cnt = get_bits_count(gb); - s->skip_bits_next = cnt & 7; - return cnt >> 3; - } else if ((s->sframe_cache_size = pos) > 0) { - /* rewind bit reader to start of last (incomplete) superframe... */ - init_get_bits(gb, avpkt->data, size << 3); - skip_bits_long(gb, (size << 3) - pos); - assert(get_bits_left(gb) == pos); - - /* ...and cache it for spillover in next packet */ - init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE); - copy_bits(&s->pb, avpkt->data, size, gb, s->sframe_cache_size); - // FIXME bad - just copy bytes as whole and add use the - // skip_bits_next field - } - - return size; -} - -static av_cold int wmavoice_decode_end(AVCodecContext *ctx) -{ - WMAVoiceContext *s = ctx->priv_data; - - if (s->do_apf) { - ff_rdft_end(&s->rdft); - ff_rdft_end(&s->irdft); - ff_dct_end(&s->dct); - ff_dct_end(&s->dst); - } - - return 0; -} - -static av_cold void wmavoice_flush(AVCodecContext *ctx) -{ - WMAVoiceContext *s = ctx->priv_data; - int n; - - s->postfilter_agc = 0; - s->sframe_cache_size = 0; - s->skip_bits_next = 0; - for (n = 0; n < s->lsps; n++) - s->prev_lsps[n] = M_PI * (n + 1.0) / (s->lsps + 1.0); - memset(s->excitation_history, 0, - sizeof(*s->excitation_history) * MAX_SIGNAL_HISTORY); - memset(s->synth_history, 0, - sizeof(*s->synth_history) * MAX_LSPS); - memset(s->gain_pred_err, 0, - sizeof(s->gain_pred_err)); - - if (s->do_apf) { - memset(&s->synth_filter_out_buf[MAX_LSPS_ALIGN16 - s->lsps], 0, - sizeof(*s->synth_filter_out_buf) * s->lsps); - memset(s->dcf_mem, 0, - sizeof(*s->dcf_mem) * 2); - memset(s->zero_exc_pf, 0, - sizeof(*s->zero_exc_pf) * s->history_nsamples); - memset(s->denoise_filter_cache, 0, sizeof(s->denoise_filter_cache)); - } -} - -AVCodec wmavoice_decoder = { - "wmavoice", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WMAVOICE, - sizeof(WMAVoiceContext), - wmavoice_decode_init, - NULL, - wmavoice_decode_end, - wmavoice_decode_packet, - CODEC_CAP_SUBFRAMES, - .flush = wmavoice_flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/wmavoice_data.h b/tizen/distrib/ffmpeg/libavcodec/wmavoice_data.h deleted file mode 100644 index cbf65b0..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmavoice_data.h +++ /dev/null @@ -1,3259 +0,0 @@ -/* - * Windows Media Voice (WMAVoice) tables. - * Copyright (c) 2009 Ronald S. Bultje - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Windows Media Voice (WMAVoice) tables - * @author Ronald S. Bultje - */ - -#ifndef AVCODEC_WMAVOICE_DATA_H -#define AVCODEC_WMAVOICE_DATA_H - -#include - -static const uint8_t wmavoice_dq_lsp10i[0xf00] = { - 125, 109, 84, 55, 34, 51, 109, 112, 118, 132, - 122, 102, 78, 80, 132, 119, 132, 132, 125, 131, - 109, 91, 131, 131, 136, 136, 137, 137, 140, 145, - 140, 143, 117, 136, 122, 106, 109, 91, 115, 119, - 133, 117, 103, 80, 55, 117, 123, 102, 93, 80, - 139, 116, 70, 39, 95, 89, 103, 113, 112, 122, - 135, 244, 229, 215, 199, 181, 163, 150, 146, 144, - 143, 173, 171, 154, 155, 154, 151, 148, 145, 143, - 132, 138, 116, 85, 117, 94, 108, 117, 107, 116, - 132, 118, 123, 119, 88, 67, 49, 95, 84, 95, - 121, 103, 74, 70, 179, 164, 141, 126, 107, 112, - 119, 95, 103, 149, 139, 148, 144, 147, 148, 141, - 151, 133, 142, 129, 111, 131, 108, 128, 122, 108, - 121, 96, 115, 138, 116, 93, 105, 115, 115, 123, - 129, 106, 136, 180, 147, 130, 108, 141, 131, 118, - 136, 155, 176, 156, 135, 129, 140, 146, 142, 134, - 141, 130, 109, 80, 52, 38, 18, 47, 118, 134, - 155, 141, 100, 78, 72, 89, 79, 96, 92, 98, - 133, 111, 83, 91, 72, 58, 105, 115, 112, 120, - 145, 127, 135, 113, 113, 105, 105, 85, 69, 61, - 115, 96, 116, 145, 159, 170, 175, 175, 168, 155, - 140, 120, 84, 52, 80, 145, 125, 127, 116, 126, - 128, 108, 101, 198, 227, 200, 178, 159, 147, 148, - 121, 88, 46, 109, 124, 126, 126, 137, 147, 147, - 129, 107, 164, 148, 127, 117, 134, 120, 111, 116, - 120, 103, 98, 73, 66, 61, 70, 115, 116, 125, - 126, 100, 77, 188, 162, 140, 114, 128, 139, 123, - 145, 165, 164, 134, 109, 100, 108, 118, 127, 130, - 156, 182, 190, 173, 167, 165, 162, 157, 152, 147, - 150, 164, 179, 183, 173, 155, 140, 136, 134, 135, - 122, 92, 69, 140, 132, 118, 108, 128, 138, 132, - 123, 127, 148, 137, 150, 149, 139, 127, 124, 130, - 136, 138, 112, 70, 41, 37, 132, 140, 129, 125, - 130, 111, 78, 33, 51, 161, 141, 136, 120, 122, - 126, 110, 87, 106, 85, 68, 48, 81, 112, 113, - 135, 125, 98, 85, 102, 80, 100, 87, 86, 116, - 142, 133, 110, 66, 48, 152, 139, 135, 136, 123, - 128, 116, 89, 102, 128, 99, 83, 61, 105, 124, - 120, 94, 73, 83, 78, 100, 122, 124, 128, 132, - 144, 137, 116, 102, 75, 144, 136, 127, 140, 127, - 154, 144, 118, 99, 90, 90, 89, 75, 68, 83, - 123, 103, 89, 198, 180, 154, 138, 122, 136, 120, - 138, 118, 121, 136, 110, 105, 85, 111, 101, 104, - 121, 126, 139, 115, 99, 101, 107, 110, 123, 126, - 127, 115, 88, 109, 164, 134, 138, 138, 120, 121, - 130, 202, 195, 202, 199, 201, 181, 164, 159, 148, - 120, 116, 194, 199, 186, 171, 154, 142, 137, 133, - 137, 129, 112, 149, 134, 112, 149, 138, 120, 134, - 119, 102, 107, 83, 79, 114, 119, 127, 128, 128, - 144, 148, 165, 155, 161, 150, 135, 122, 116, 115, - 120, 99, 80, 120, 123, 124, 111, 89, 70, 108, - 118, 95, 66, 53, 105, 126, 125, 105, 83, 111, - 129, 197, 191, 197, 206, 213, 216, 208, 196, 169, - 133, 109, 127, 164, 134, 121, 99, 92, 82, 71, - 131, 121, 93, 91, 136, 105, 115, 140, 120, 110, - 150, 164, 139, 108, 87, 81, 93, 92, 104, 116, - 133, 114, 125, 126, 111, 136, 110, 156, 147, 133, - 113, 94, 118, 120, 115, 125, 124, 126, 127, 134, - 116, 131, 161, 158, 166, 157, 150, 150, 144, 141, - 125, 185, 169, 142, 140, 143, 139, 131, 134, 138, - 179, 188, 170, 150, 134, 140, 144, 133, 127, 127, - 150, 177, 204, 184, 192, 194, 190, 193, 177, 158, - 114, 113, 138, 116, 137, 135, 132, 131, 127, 134, - 120, 147, 163, 135, 133, 137, 136, 136, 133, 135, - 137, 120, 95, 73, 46, 48, 111, 97, 97, 123, - 139, 130, 109, 76, 52, 72, 61, 61, 125, 127, - 132, 119, 119, 90, 66, 41, 64, 156, 143, 129, - 131, 106, 58, 25, 99, 115, 122, 136, 129, 132, - 134, 123, 97, 53, 27, 114, 125, 114, 120, 123, - 122, 107, 93, 57, 47, 133, 128, 138, 141, 131, - 145, 132, 122, 110, 79, 57, 30, 73, 153, 144, - 150, 132, 85, 59, 133, 125, 130, 115, 100, 96, - 148, 127, 111, 86, 61, 38, 110, 121, 108, 99, - 157, 143, 105, 77, 116, 118, 115, 131, 122, 122, - 133, 119, 134, 108, 86, 61, 129, 165, 143, 127, - 125, 105, 89, 111, 97, 85, 113, 99, 98, 117, - 149, 131, 101, 106, 88, 95, 79, 119, 123, 120, - 125, 109, 81, 100, 201, 183, 156, 138, 115, 116, - 141, 119, 129, 105, 76, 60, 110, 99, 92, 82, - 150, 156, 129, 95, 69, 115, 115, 113, 134, 125, - 118, 97, 67, 96, 203, 197, 171, 151, 133, 125, - 143, 131, 120, 134, 105, 80, 51, 60, 139, 134, - 129, 160, 223, 219, 219, 212, 197, 173, 157, 146, - 132, 112, 164, 144, 119, 102, 92, 76, 73, 94, - 132, 112, 124, 114, 93, 92, 83, 73, 69, 99, - 129, 103, 188, 163, 142, 132, 127, 101, 82, 59, - 140, 141, 111, 74, 46, 105, 113, 99, 127, 122, - 125, 94, 63, 112, 116, 101, 81, 120, 136, 134, - 133, 190, 224, 193, 179, 158, 146, 143, 140, 136, - 152, 161, 132, 120, 112, 94, 114, 102, 92, 116, - 129, 194, 196, 202, 211, 212, 210, 190, 169, 152, - 166, 166, 145, 111, 91, 132, 133, 128, 136, 130, - 118, 94, 72, 74, 92, 86, 89, 92, 106, 123, - 126, 100, 86, 137, 117, 92, 76, 104, 106, 114, - 133, 109, 204, 192, 166, 148, 138, 128, 111, 81, - 118, 99, 79, 146, 169, 141, 123, 102, 131, 120, - 127, 105, 136, 204, 170, 154, 131, 145, 135, 119, - 117, 95, 64, 83, 141, 136, 118, 96, 99, 126, - 115, 93, 98, 102, 95, 105, 106, 114, 119, 128, - 131, 121, 98, 139, 149, 119, 109, 86, 105, 129, - 134, 119, 104, 169, 185, 155, 141, 122, 107, 127, - 136, 115, 85, 108, 87, 126, 102, 128, 136, 129, - 125, 99, 126, 158, 133, 139, 132, 113, 91, 107, - 141, 122, 128, 161, 130, 127, 105, 120, 118, 106, - 122, 140, 161, 168, 187, 184, 176, 158, 144, 140, - 127, 111, 89, 130, 132, 105, 134, 121, 100, 122, - 129, 110, 128, 115, 129, 116, 132, 118, 114, 119, - 138, 133, 132, 188, 183, 159, 161, 147, 134, 140, - 132, 113, 84, 167, 147, 132, 124, 109, 133, 121, - 132, 128, 116, 121, 98, 101, 145, 129, 128, 129, - 124, 112, 152, 158, 136, 161, 139, 165, 158, 142, - 139, 138, 110, 127, 148, 117, 126, 118, 101, 116, - 155, 168, 154, 128, 120, 152, 150, 141, 140, 135, - 127, 111, 109, 134, 104, 133, 110, 112, 132, 114, - 111, 87, 68, 89, 107, 121, 121, 126, 126, 129, - 120, 148, 169, 163, 173, 178, 185, 188, 178, 163, - 122, 97, 86, 117, 101, 138, 118, 142, 155, 139, - 125, 114, 131, 138, 153, 149, 163, 150, 143, 141, - 157, 161, 138, 152, 134, 121, 122, 109, 110, 124, - 151, 171, 196, 168, 145, 139, 147, 151, 146, 139, - 134, 169, 179, 170, 175, 178, 177, 173, 165, 154, - 120, 151, 118, 107, 125, 129, 133, 133, 136, 139, - 119, 141, 159, 151, 160, 165, 168, 169, 162, 152, - 115, 111, 119, 94, 117, 121, 127, 127, 132, 136, - 134, 153, 147, 142, 142, 147, 159, 159, 154, 147, - 110, 106, 139, 135, 143, 142, 147, 146, 147, 147, - 115, 133, 151, 133, 141, 142, 151, 152, 147, 144, - 115, 132, 144, 131, 125, 126, 128, 130, 131, 136, - 138, 118, 96, 71, 48, 26, 43, 130, 125, 125, - 134, 122, 98, 54, 28, 84, 77, 73, 109, 125, - 133, 112, 67, 48, 141, 129, 126, 113, 112, 118, - 143, 123, 89, 54, 71, 73, 75, 131, 123, 123, - 126, 109, 81, 31, 15, 94, 110, 109, 119, 128, - 132, 122, 97, 92, 73, 50, 27, 22, 104, 133, - 133, 119, 94, 48, 34, 168, 160, 154, 151, 130, - 147, 133, 90, 54, 71, 123, 106, 105, 93, 117, - 143, 132, 107, 69, 45, 78, 178, 169, 150, 139, - 138, 123, 116, 96, 69, 49, 32, 113, 103, 112, - 154, 151, 125, 79, 60, 152, 160, 154, 155, 137, - 142, 151, 124, 88, 66, 59, 94, 87, 95, 119, - 166, 154, 122, 92, 138, 132, 124, 114, 97, 97, - 122, 99, 98, 219, 191, 176, 165, 159, 153, 131, - 130, 119, 91, 51, 24, 41, 144, 156, 147, 139, - 139, 122, 81, 65, 124, 111, 104, 90, 94, 98, - 138, 120, 112, 91, 63, 65, 89, 75, 78, 106, - 126, 107, 91, 85, 69, 95, 90, 84, 108, 120, - 155, 139, 100, 78, 120, 110, 109, 91, 77, 73, - 144, 130, 135, 112, 88, 65, 62, 142, 129, 126, - 170, 154, 150, 131, 121, 116, 100, 92, 83, 86, - 131, 122, 98, 107, 102, 75, 54, 38, 117, 130, - 146, 139, 117, 107, 86, 66, 44, 30, 97, 128, - 129, 116, 100, 59, 108, 127, 119, 139, 129, 129, - 124, 106, 79, 49, 154, 190, 166, 152, 133, 123, - 141, 149, 123, 89, 61, 70, 143, 132, 125, 126, - 136, 113, 177, 166, 141, 123, 109, 108, 105, 93, - 137, 117, 147, 123, 99, 85, 109, 98, 91, 75, - 129, 121, 102, 78, 53, 90, 149, 136, 134, 135, - 144, 136, 126, 90, 114, 152, 137, 152, 138, 128, - 133, 115, 107, 129, 99, 78, 60, 129, 125, 118, - 147, 141, 119, 124, 110, 91, 79, 64, 106, 117, - 134, 111, 164, 143, 123, 113, 116, 95, 76, 56, - 147, 159, 140, 109, 83, 84, 140, 135, 127, 129, - 123, 104, 116, 99, 91, 87, 80, 110, 113, 121, - 124, 106, 174, 174, 152, 141, 132, 134, 126, 124, - 140, 190, 240, 215, 212, 189, 173, 158, 144, 137, - 123, 97, 79, 102, 110, 111, 90, 75, 126, 124, - 134, 121, 104, 145, 127, 100, 77, 65, 120, 118, - 123, 106, 87, 41, 68, 119, 106, 115, 109, 119, - 137, 232, 241, 225, 217, 202, 183, 169, 156, 145, - 161, 146, 127, 110, 97, 107, 88, 114, 108, 106, - 141, 244, 216, 192, 172, 163, 148, 143, 144, 144, - 128, 127, 109, 89, 77, 68, 124, 120, 121, 125, - 125, 94, 48, 71, 116, 113, 104, 120, 142, 137, - 133, 129, 115, 82, 68, 120, 99, 133, 134, 124, - 130, 106, 108, 160, 130, 111, 89, 129, 124, 119, - 134, 120, 149, 143, 116, 95, 87, 142, 132, 122, - 126, 114, 108, 107, 80, 141, 133, 123, 137, 124, - 117, 95, 69, 43, 62, 98, 114, 116, 112, 120, - 122, 99, 87, 164, 145, 123, 99, 95, 118, 105, - 126, 101, 102, 120, 113, 110, 92, 139, 134, 126, - 148, 194, 241, 219, 221, 215, 200, 193, 174, 151, - 127, 104, 122, 136, 113, 106, 110, 95, 78, 106, - 131, 163, 217, 199, 194, 175, 164, 155, 142, 138, - 139, 124, 88, 57, 161, 161, 145, 139, 124, 116, - 127, 110, 91, 98, 126, 104, 113, 98, 94, 94, - 145, 138, 114, 90, 75, 130, 117, 107, 99, 90, - 119, 98, 86, 101, 148, 133, 103, 83, 124, 131, - 143, 168, 169, 133, 110, 117, 139, 149, 147, 137, - 124, 106, 80, 138, 194, 163, 142, 119, 106, 130, - 136, 125, 105, 114, 87, 113, 101, 89, 108, 102, - 114, 90, 53, 46, 105, 116, 126, 122, 118, 122, - 124, 102, 92, 195, 167, 160, 144, 154, 154, 132, - 118, 97, 88, 72, 98, 120, 112, 98, 79, 117, - 114, 107, 185, 191, 191, 188, 175, 165, 153, 143, - 119, 97, 90, 89, 120, 151, 136, 113, 99, 112, - 141, 121, 144, 122, 125, 113, 133, 111, 92, 69, - 120, 98, 78, 109, 151, 145, 157, 157, 151, 143, - 130, 110, 120, 188, 159, 141, 119, 112, 109, 98, - 126, 112, 83, 110, 169, 139, 127, 105, 93, 123, - 141, 145, 117, 106, 91, 78, 123, 107, 101, 125, - 117, 95, 71, 147, 176, 153, 148, 133, 135, 127, - 124, 106, 79, 64, 115, 96, 108, 115, 106, 105, - 127, 115, 90, 98, 105, 81, 144, 135, 117, 125, - 126, 104, 98, 165, 138, 136, 112, 149, 148, 131, - 119, 144, 186, 185, 204, 202, 209, 200, 182, 161, - 123, 153, 190, 189, 199, 194, 191, 176, 157, 147, - 121, 103, 119, 98, 100, 120, 106, 97, 95, 126, - 137, 130, 102, 117, 117, 92, 126, 114, 101, 118, - 131, 219, 190, 167, 153, 151, 144, 140, 142, 143, - 114, 102, 151, 152, 132, 120, 112, 120, 127, 131, - 138, 122, 91, 143, 118, 120, 114, 104, 124, 117, - 148, 142, 117, 126, 97, 125, 108, 116, 142, 125, - 126, 106, 91, 169, 208, 178, 158, 138, 127, 135, - 133, 126, 101, 83, 147, 130, 125, 117, 114, 117, - 120, 103, 94, 149, 136, 129, 139, 118, 133, 133, - 147, 152, 126, 132, 119, 97, 132, 129, 114, 126, - 112, 107, 148, 125, 112, 114, 124, 125, 129, 135, - 139, 121, 157, 151, 131, 140, 118, 147, 136, 121, - 115, 105, 159, 167, 185, 191, 196, 190, 176, 160, - 124, 106, 104, 122, 130, 114, 152, 144, 134, 136, - 136, 152, 159, 153, 131, 114, 116, 126, 129, 129, - 124, 109, 87, 131, 107, 115, 130, 107, 144, 131, - 126, 162, 176, 175, 180, 176, 160, 141, 134, 134, - 136, 127, 108, 161, 162, 133, 141, 124, 112, 128, - 130, 115, 110, 140, 107, 155, 134, 131, 156, 137, - 122, 106, 116, 127, 118, 161, 150, 170, 167, 152, - 139, 177, 203, 176, 155, 139, 130, 128, 129, 132, - 137, 119, 125, 103, 110, 123, 107, 120, 108, 101, - 113, 107, 160, 154, 160, 166, 169, 176, 168, 156, - 115, 90, 65, 115, 115, 104, 120, 112, 109, 124, - 131, 123, 100, 109, 185, 158, 141, 132, 116, 119, - 139, 130, 119, 156, 124, 138, 127, 116, 141, 128, - 133, 118, 115, 180, 149, 151, 135, 130, 147, 129, - 117, 90, 80, 119, 124, 128, 132, 130, 128, 135, - 112, 97, 142, 161, 167, 165, 154, 142, 136, 135, - 118, 141, 193, 172, 157, 152, 148, 145, 146, 141, - 125, 147, 165, 166, 149, 133, 123, 122, 128, 131, - 128, 193, 177, 174, 182, 186, 197, 193, 191, 173, - 124, 144, 162, 133, 113, 113, 123, 128, 129, 130, - 117, 98, 121, 122, 137, 132, 110, 97, 111, 130, - 128, 176, 151, 125, 126, 134, 130, 121, 127, 130, - 122, 151, 142, 111, 106, 121, 126, 126, 130, 134, - 148, 167, 186, 153, 129, 122, 124, 128, 130, 128, - 148, 172, 206, 178, 171, 182, 169, 180, 172, 156, - 133, 164, 174, 160, 155, 163, 163, 172, 169, 158, - 132, 150, 147, 142, 152, 140, 140, 140, 134, 135, - 137, 158, 167, 172, 163, 153, 169, 158, 146, 147, - 150, 161, 162, 172, 153, 133, 140, 144, 136, 135, - 109, 84, 101, 120, 129, 134, 133, 136, 137, 143, - 112, 114, 157, 147, 141, 136, 135, 133, 135, 138, - 121, 154, 161, 150, 149, 154, 151, 144, 146, 144, - 111, 117, 125, 125, 130, 131, 135, 137, 143, 148, - 121, 141, 146, 131, 138, 126, 118, 111, 119, 130, - 120, 135, 145, 121, 140, 134, 138, 137, 131, 134, - 115, 137, 132, 137, 139, 138, 138, 139, 145, 149, - 131, 149, 147, 133, 132, 126, 131, 134, 130, 133, - 110, 98, 84, 141, 107, 169, 169, 123, 125, 126, - 118, 210, 98, 126, 132, 138, 128, 139, 156, 157, - 140, 142, 129, 95, 192, 178, 182, 186, 183, 159, - 135, 134, 144, 124, 100, 228, 203, 161, 122, 104, - 139, 159, 134, 161, 121, 126, 192, 152, 218, 180, - 132, 132, 119, 99, 96, 97, 80, 53, 134, 143, - 102, 114, 133, 114, 127, 83, 77, 126, 85, 107, - 110, 114, 194, 186, 139, 116, 147, 104, 129, 138, - 126, 133, 109, 144, 115, 45, 130, 97, 159, 155, - 157, 162, 189, 185, 168, 163, 151, 151, 142, 135, - 144, 147, 120, 74, 192, 186, 149, 118, 71, 84, - 143, 156, 133, 178, 168, 107, 119, 149, 105, 112, - 182, 184, 158, 118, 118, 148, 128, 177, 171, 152, - 139, 135, 126, 209, 171, 150, 123, 100, 190, 158, - 166, 97, 136, 123, 136, 139, 128, 138, 126, 121, - 132, 131, 128, 95, 60, 168, 127, 140, 208, 161, - 109, 102, 119, 162, 150, 137, 107, 200, 156, 136, - 136, 128, 103, 95, 74, 91, 220, 173, 152, 138, - 139, 129, 140, 136, 122, 82, 180, 115, 53, 90, - 121, 107, 99, 148, 116, 139, 100, 63, 191, 155, - 130, 129, 163, 155, 98, 175, 95, 151, 127, 107, - 124, 124, 116, 88, 71, 164, 148, 96, 57, 89, - 125, 117, 77, 63, 162, 144, 113, 109, 137, 134, - 134, 130, 149, 174, 158, 158, 130, 81, 28, 67, - 142, 139, 129, 100, 194, 134, 68, 175, 131, 103, - 136, 132, 122, 96, 119, 82, 115, 249, 215, 168, - 125, 139, 199, 96, 146, 123, 136, 179, 142, 137, - 181, 166, 106, 86, 122, 106, 123, 131, 106, 119, - 129, 189, 188, 147, 126, 110, 101, 114, 147, 136, - 132, 106, 72, 175, 148, 99, 130, 153, 125, 136, - 123, 119, 147, 170, 157, 126, 209, 188, 158, 152, - 101, 89, 142, 131, 161, 150, 148, 124, 89, 119, - 141, 137, 131, 103, 81, 85, 64, 175, 129, 121, - 137, 144, 142, 145, 119, 205, 148, 80, 165, 138, - 143, 137, 167, 165, 148, 149, 110, 234, 217, 170, - 167, 152, 75, 140, 155, 155, 175, 129, 136, 134, - 136, 152, 161, 131, 140, 121, 91, 79, 255, 209, - 132, 147, 120, 114, 177, 128, 110, 61, 89, 131, - 125, 127, 93, 87, 167, 115, 186, 162, 107, 106, - 134, 162, 151, 100, 79, 67, 151, 116, 130, 142, - 162, 153, 155, 143, 122, 85, 202, 187, 135, 125, - 158, 155, 103, 129, 74, 149, 130, 98, 129, 126, - 148, 152, 153, 133, 118, 94, 80, 70, 47, 90, - 124, 118, 143, 184, 158, 126, 70, 82, 111, 113, - 126, 135, 175, 141, 203, 166, 123, 123, 134, 133, - 113, 111, 128, 76, 128, 177, 151, 178, 134, 125, - 120, 120, 193, 106, 98, 134, 101, 86, 101, 114, - 136, 127, 134, 196, 86, 105, 145, 128, 119, 137, - 138, 126, 230, 161, 141, 128, 129, 136, 88, 83, - 103, 118, 178, 123, 89, 101, 161, 173, 165, 147, - 130, 123, 171, 158, 131, 81, 50, 177, 162, 136, - 125, 115, 82, 173, 195, 168, 130, 112, 112, 121, - 152, 148, 167, 87, 82, 161, 142, 147, 98, 89, - 168, 138, 97, 157, 132, 114, 74, 126, 161, 141, - 135, 123, 68, 137, 124, 118, 112, 92, 65, 96, - 191, 181, 161, 151, 141, 145, 129, 102, 97, 111, - 144, 128, 55, 128, 115, 155, 129, 184, 167, 147, - 131, 141, 125, 33, 127, 111, 127, 131, 125, 130, - 137, 130, 121, 195, 172, 177, 176, 149, 98, 97, - 126, 106, 168, 159, 144, 185, 156, 151, 182, 158, - 123, 93, 110, 116, 98, 99, 125, 136, 139, 148, - 79, 112, 149, 128, 147, 136, 118, 105, 166, 152, - 117, 115, 92, 128, 148, 132, 170, 143, 226, 190, - 122, 192, 165, 121, 143, 144, 174, 124, 113, 124, - 122, 135, 34, 93, 118, 111, 111, 136, 123, 116, - 99, 195, 139, 99, 114, 102, 96, 108, 111, 112, - 113, 129, 172, 137, 105, 139, 154, 86, 113, 108, - 132, 79, 63, 120, 93, 162, 90, 103, 94, 95, - 117, 127, 104, 100, 142, 129, 93, 27, 196, 153, - 113, 91, 101, 90, 84, 68, 138, 38, 118, 148, - 87, 103, 125, 109, 96, 152, 100, 56, 31, 62, - 176, 129, 124, 115, 103, 92, 100, 121, 130, 125, - 128, 71, 82, 71, 152, 85, 107, 116, 138, 133, - 103, 116, 139, 144, 72, 37, 118, 141, 109, 95, - 86, 92, 121, 167, 156, 104, 92, 91, 122, 114, - 89, 61, 172, 128, 95, 103, 84, 101, 88, 84, - 116, 125, 108, 62, 74, 108, 160, 143, 189, 164, - 91, 115, 144, 43, 116, 79, 106, 108, 74, 83, - 87, 90, 61, 71, 76, 76, 95, 130, 89, 94, - 114, 107, 101, 145, 161, 147, 143, 163, 147, 129, - 101, 73, 111, 108, 93, 104, 186, 141, 99, 89, - 112, 126, 111, 113, 152, 41, 159, 115, 131, 124, - 117, 101, 115, 130, 124, 87, 59, 177, 63, 85, - 109, 116, 103, 68, 145, 132, 29, 119, 96, 89, - 117, 90, 181, 103, 101, 111, 97, 96, 199, 171, - 113, 120, 93, 119, 101, 64, 56, 55, 63, 90, - 105, 101, 86, 45, 136, 179, 142, 102, 115, 114, - 113, 108, 121, 84, 23, 125, 76, 102, 119, 107, - 120, 104, 73, 177, 83, 114, 128, 85, 152, 126, - 137, 115, 149, 109, 163, 133, 110, 98, 54, 61, - 95, 111, 135, 103, 88, 164, 115, 187, 122, 98, - 129, 132, 95, 86, 71, 119, 146, 111, 38, 67, - 102, 100, 66, 148, 137, 103, 145, 95, 35, 85, - 44, 136, 102, 111, 108, 115, 136, 105, 120, 110, - 108, 147, 112, 169, 116, 146, 81, 120, 94, 84, - 93, 97, 90, 119, 102, 91, 48, 147, 204, 151, - 148, 160, 144, 131, 144, 175, 158, 133, 212, 163, - 172, 152, 151, 112, 148, 151, 145, 179, 160, 124, - 164, 164, 167, 161, 141, 120, 131, 141, 198, 177, - 169, 156, 146, 156, 124, 185, 164, 195, 181, 193, - 201, 147, 148, 168, 165, 159, 162, 148, 150, 148, - 146, 157, 158, 149, 164, 129, 160, 214, 174, 166, - 154, 176, 146, 141, 155, 140, 140, 169, 106, 155, - 166, 162, 134, 193, 157, 155, 146, 196, 171, 107, - 177, 174, 163, 155, 147, 203, 162, 146, 150, 83, - 157, 170, 180, 178, 159, 157, 151, 117, 115, 183, - 170, 180, 174, 150, 177, 173, 136, 181, 196, 184, - 164, 168, 165, 148, 175, 168, 209, 189, 159, 114, - 157, 158, 141, 168, 170, 139, 175, 128, 151, 39, - 128, 154, 159, 161, 148, 180, 131, 165, 159, 131, - 163, 150, 174, 178, 178, 198, 172, 138, 184, 191, - 143, 164, 161, 163, 210, 171, 155, 168, 150, 116, - 182, 170, 145, 152, 141, 139, 191, 149, 160, 202, - 145, 169, 145, 181, 148, 183, 197, 165, 146, 171, - 161, 153, 157, 170, 164, 149, 183, 167, 246, 235, - 162, 144, 170, 152, 173, 150, 113, 135, 156, 154, - 158, 148, 178, 159, 161, 114, 180, 156, 116, 163, - 164, 161, 122, 164, 164, 183, 135, 135, 144, 182, - 160, 147, 163, 152, 169, 185, 159, 177, 99, 211, - 168, 167, 215, 170, 150, 157, 154, 176, 154, 143, - 163, 117, 178, 160, 163, 165, 164, 166, 174, 136, - 159, 169, 152, 123, 199, 149, 169, 140, 159, 208, - 155, 161, 186, 122, 134, 167, 171, 145, 148, 176, - 148, 137, 114, 160, 166, 153, 162, 156, 164, 172, - 155, 148, 155, 182, 114, 150, 157, 154, 140, 159, - 166, 160, 169, 206, 182, 145, 157, 165, 147, 202, - 131, 154, 193, 162, 162, 149, 167, 157, 191, 188, - 149, 205, 147, 166, 150, 150, 159, 153, 171, 160 -}; - -static const uint8_t wmavoice_dq_lsp16i1[0x640] = { - 142, 121, 141, 112, 99, 119, 92, 122, 183, 155, - 122, 98, 75, 78, 85, 101, 108, 134, 128, 123, - 115, 90, 79, 58, 73, 127, 106, 60, 97, 107, - 141, 163, 130, 123, 136, 156, 201, 189, 204, 206, - 140, 116, 69, 60, 117, 123, 106, 124, 91, 63, - 150, 144, 110, 80, 63, 112, 80, 70, 76, 63, - 114, 86, 147, 165, 137, 125, 120, 140, 115, 101, - 101, 99, 166, 158, 158, 104, 126, 131, 134, 143, - 121, 102, 73, 36, 83, 132, 113, 76, 38, 20, - 132, 111, 78, 73, 51, 131, 108, 131, 105, 80, - 148, 138, 101, 65, 47, 115, 86, 50, 124, 129, - 116, 89, 85, 87, 64, 111, 74, 39, 115, 113, - 112, 83, 75, 122, 127, 114, 91, 106, 125, 130, - 131, 108, 79, 136, 112, 110, 147, 164, 144, 124, - 121, 236, 218, 190, 168, 106, 101, 160, 172, 191, - 113, 138, 102, 91, 109, 100, 71, 85, 112, 119, - 121, 96, 51, 64, 126, 135, 114, 76, 34, 104, - 145, 127, 90, 56, 131, 142, 131, 92, 123, 102, - 128, 105, 63, 24, 95, 115, 87, 49, 156, 174, - 123, 105, 88, 58, 55, 141, 119, 99, 75, 81, - 137, 117, 114, 80, 56, 119, 91, 106, 166, 135, - 114, 84, 38, 93, 116, 129, 103, 97, 87, 97, - 115, 184, 193, 173, 157, 117, 88, 114, 151, 121, - 126, 111, 75, 129, 133, 130, 107, 71, 115, 92, - 128, 108, 120, 100, 97, 111, 80, 119, 122, 91, - 114, 94, 149, 129, 136, 114, 88, 132, 110, 85, - 116, 99, 101, 71, 71, 110, 140, 142, 131, 110, - 122, 98, 83, 127, 100, 106, 130, 123, 114, 103, - 113, 87, 140, 116, 113, 140, 161, 171, 145, 129, - 115, 178, 158, 161, 160, 118, 195, 209, 221, 228, - 99, 83, 140, 134, 140, 127, 186, 168, 187, 187, - 107, 114, 100, 111, 111, 104, 130, 131, 116, 128, - 128, 104, 64, 18, 49, 126, 107, 69, 56, 153, - 154, 142, 110, 113, 89, 120, 93, 73, 190, 172, - 119, 96, 57, 21, 60, 126, 122, 81, 99, 117, - 159, 141, 108, 88, 120, 144, 125, 89, 44, 94, - 147, 131, 93, 81, 61, 133, 113, 85, 47, 62, - 123, 121, 87, 53, 90, 120, 94, 76, 70, 48, - 125, 103, 93, 64, 35, 140, 129, 88, 47, 30, - 127, 104, 58, 51, 103, 124, 100, 102, 76, 47, - 115, 87, 54, 46, 77, 182, 218, 174, 163, 145, - 140, 126, 89, 105, 82, 125, 119, 101, 69, 58, - 125, 107, 172, 145, 128, 138, 113, 109, 92, 90, - 117, 93, 83, 93, 132, 125, 102, 67, 148, 161, - 131, 110, 96, 99, 74, 119, 92, 54, 84, 81, - 110, 152, 120, 106, 131, 108, 74, 68, 99, 107, - 121, 97, 120, 101, 78, 132, 110, 127, 164, 134, - 111, 159, 204, 189, 178, 158, 183, 146, 144, 137, - 123, 106, 136, 108, 135, 117, 91, 163, 135, 113, - 119, 177, 134, 122, 121, 132, 109, 157, 131, 113, - 115, 87, 87, 100, 92, 120, 95, 59, 146, 139, - 129, 101, 135, 122, 101, 119, 100, 112, 88, 99, - 118, 90, 123, 125, 107, 121, 98, 73, 104, 80, - 112, 79, 86, 122, 96, 104, 81, 107, 90, 93, - 112, 150, 140, 109, 115, 113, 86, 73, 76, 112, - 130, 111, 101, 112, 84, 123, 97, 63, 134, 115, - 109, 77, 128, 141, 119, 125, 101, 108, 147, 119, - 134, 149, 150, 127, 115, 136, 244, 220, 210, 189, - 105, 138, 171, 156, 174, 117, 162, 133, 146, 141, - 115, 93, 119, 98, 122, 114, 106, 154, 145, 162, - 107, 131, 189, 165, 152, 101, 107, 129, 114, 139, - 116, 186, 186, 161, 180, 100, 89, 137, 116, 116, - 106, 130, 194, 196, 207, 110, 156, 157, 138, 149, - 102, 93, 159, 138, 120, 109, 132, 105, 122, 135, - 148, 128, 85, 76, 102, 168, 154, 141, 117, 100, - 125, 106, 62, 101, 146, 124, 102, 65, 25, 15, - 120, 94, 46, 21, 94, 149, 128, 115, 85, 92, - 119, 93, 70, 52, 30, 162, 151, 123, 91, 80, - 126, 112, 84, 47, 33, 138, 114, 73, 60, 87, - 126, 211, 174, 158, 143, 129, 106, 65, 31, 133, - 119, 95, 52, 99, 173, 123, 96, 119, 206, 178, - 127, 104, 60, 61, 67, 152, 136, 104, 63, 83, - 133, 130, 92, 64, 45, 120, 96, 53, 30, 130, - 128, 103, 74, 59, 35, 135, 114, 77, 30, 57, - 108, 130, 123, 90, 87, 143, 125, 93, 54, 60, - 133, 118, 79, 87, 95, 115, 89, 111, 88, 65, - 124, 102, 70, 40, 47, 148, 131, 123, 130, 104, - 127, 109, 87, 56, 121, 147, 123, 121, 107, 85, - 178, 237, 200, 193, 170, 139, 118, 100, 75, 110, - 133, 121, 81, 73, 68, 120, 195, 157, 141, 131, - 127, 102, 107, 88, 60, 136, 113, 100, 69, 45, - 128, 105, 93, 77, 67, 131, 116, 149, 184, 156, - 115, 85, 35, 45, 112, 128, 108, 68, 73, 111, - 118, 93, 187, 162, 139, 136, 115, 84, 57, 37, - 131, 133, 125, 98, 85, 138, 115, 92, 86, 61, - 116, 96, 70, 52, 110, 115, 109, 135, 104, 88, - 136, 159, 122, 109, 115, 122, 110, 98, 70, 95, - 112, 81, 68, 85, 90, 124, 101, 87, 56, 89, - 109, 82, 98, 100, 115, 124, 102, 76, 88, 63, - 111, 78, 42, 78, 102, 110, 71, 64, 131, 111, - 125, 104, 107, 87, 123, 129, 131, 99, 85, 68, - 147, 137, 102, 99, 75, 120, 155, 142, 109, 91, - 132, 109, 131, 141, 113, 136, 119, 94, 152, 128, - 127, 102, 79, 159, 134, 111, 78, 98, 109, 80, - 115, 86, 51, 63, 103, 116, 86, 170, 149, 123, - 135, 178, 159, 125, 114, 113, 189, 226, 203, 202, - 140, 117, 116, 94, 70, 128, 103, 94, 174, 149, - 118, 98, 83, 84, 106, 115, 157, 120, 94, 95, - 131, 112, 75, 96, 74, 121, 97, 144, 117, 95, - 120, 90, 140, 138, 110, 119, 93, 55, 92, 114, - 114, 87, 151, 125, 100, 111, 82, 83, 160, 139, - 114, 86, 56, 90, 138, 104, 109, 101, 77, 118, - 140, 142, 143, 148, 126, 121, 102, 129, 107, 111, - 113, 79, 58, 111, 91, 120, 94, 63, 115, 98, - 121, 94, 99, 97, 78, 120, 92, 68, 173, 148, - 122, 114, 109, 87, 82, 132, 229, 192, 176, 155, - 137, 116, 123, 97, 115, 132, 115, 86, 120, 95, - 135, 116, 101, 136, 108, 109, 74, 100, 125, 115, - 112, 158, 144, 124, 134, 114, 83, 73, 147, 120, - 120, 104, 150, 122, 116, 110, 104, 192, 183, 174, - 134, 112, 116, 120, 93, 121, 101, 93, 110, 90, - 121, 93, 147, 152, 122, 115, 153, 171, 161, 142, - 123, 95, 116, 114, 93, 113, 89, 96, 77, 93, - 113, 174, 180, 143, 138, 116, 86, 100, 135, 106, - 103, 121, 149, 115, 103, 121, 95, 82, 149, 121, - 117, 92, 93, 111, 114, 123, 209, 196, 193, 183, - 125, 102, 107, 130, 104, 115, 91, 113, 103, 99, - 114, 86, 68, 108, 110, 111, 159, 162, 125, 113, - 125, 235, 234, 225, 214, 99, 74, 118, 121, 127, - 104, 123, 158, 128, 127, 113, 96, 116, 136, 158, - 100, 80, 138, 155, 166, 118, 143, 115, 125, 114, - 119, 137, 133, 136, 139, 151, 188, 172, 174, 173, - 138, 161, 158, 158, 155, 121, 198, 194, 211, 202, - 100, 90, 112, 110, 122, 100, 91, 122, 128, 135, - 101, 109, 127, 101, 114, 105, 126, 160, 147, 143, - 109, 138, 142, 158, 163, 113, 174, 185, 188, 206, - 112, 154, 166, 176, 183, 101, 108, 140, 140, 143, - 106, 135, 130, 137, 126, 103, 114, 115, 128, 126, - 107, 86, 21, 115, 75, 117, 139, 97, 65, 105, - 64, 191, 101, 106, 139, 107, 98, 218, 132, 104, - 73, 136, 165, 84, 118, 150, 111, 58, 130, 107, - 99, 136, 132, 56, 52, 102, 136, 69, 78, 163, - 85, 173, 148, 138, 85, 69, 106, 128, 133, 155, - 104, 91, 149, 56, 104, 103, 101, 172, 96, 57, - 104, 97, 125, 197, 166, 107, 169, 47, 120, 103, - 150, 89, 99, 139, 162, 101, 69, 137, 158, 126, - 191, 173, 127, 79, 155, 51, 131, 112, 86, 74, - 135, 61, 114, 81, 125, 117, 112, 72, 175, 72, - 127, 123, 142, 132, 78, 116, 158, 111, 121, 143, - 108, 102, 89, 20, 194, 81, 99, 107, 65, 150, - 103, 78, 91, 69, 96, 104, 116, 116, 103, 105, - 107, 117, 110, 130, 28, 88, 103, 62, 72, 85, - 125, 126, 141, 126, 178, 121, 102, 57, 46, 124, - 97, 91, 89, 138, 95, 98, 143, 99, 169, 123, - 140, 119, 113, 82, 140, 118, 112, 91, 92, 241, - 134, 89, 95, 112, 78, 167, 140, 145, 121, 100, - 109, 205, 144, 91, 100, 113, 103, 142, 175, 95, - 117, 121, 35, 121, 127, 159, 129, 85, 64, 75, - 116, 98, 103, 127, 129, 66, 68, 110, 96, 86, - 79, 100, 156, 133, 92, 135, 96, 164, 132, 121, - 93, 163, 134, 91, 208, 104, 77, 126, 116, 58, - 136, 118, 132, 81, 61, 73, 115, 66, 129, 123, - 111, 85, 42, 178, 134, 108, 132, 159, 45, 157, - 105, 164, 100, 94, 60, 96, 57, 154, 105, 102, - 103, 114, 96, 12, 91, 119, 115, 67, 92, 64, - 94, 61, 106, 106, 165, 105, 94, 98, 68, 30, - 146, 130, 107, 173, 140, 102, 90, 163, 106, 184, - 100, 53, 68, 131, 92, 105, 111, 68, 153, 186, - 101, 82, 48, 99, 147, 122, 136, 176, 96, 96, - 104, 132, 167, 149, 136, 138, 144, 97, 120, 92 -}; - -static const uint8_t wmavoice_dq_lsp16i2[0x3c0] = { - 23, 12, 107, 119, 110, 205, 214, 212, 208, 201, - 102, 95, 69, 117, 107, 118, 123, 118, 123, 121, - 82, 58, 83, 95, 84, 139, 145, 153, 161, 169, - 102, 100, 138, 121, 101, 129, 130, 138, 150, 139, - 76, 104, 86, 112, 133, 113, 91, 63, 73, 129, - 199, 193, 182, 181, 172, 119, 101, 83, 94, 76, - 161, 157, 152, 157, 158, 110, 90, 121, 96, 79, - 124, 107, 114, 88, 73, 152, 137, 121, 107, 99, - 57, 50, 100, 81, 74, 115, 96, 72, 49, 69, - 83, 68, 40, 53, 103, 36, 131, 107, 84, 64, - 236, 245, 242, 231, 213, 95, 109, 88, 69, 110, - 228, 221, 204, 182, 170, 129, 110, 97, 118, 104, - 98, 76, 98, 75, 61, 93, 77, 113, 91, 72, - 116, 94, 106, 134, 118, 177, 188, 169, 162, 153, - 163, 149, 131, 131, 132, 177, 163, 173, 168, 158, - 113, 131, 107, 113, 100, 132, 143, 131, 134, 142, - 45, 36, 121, 113, 102, 43, 95, 84, 67, 56, - 76, 82, 68, 48, 33, 55, 58, 59, 43, 65, - 66, 85, 66, 81, 94, 102, 82, 54, 33, 94, - 113, 111, 89, 60, 34, 138, 120, 101, 101, 86, - 88, 73, 55, 114, 115, 92, 74, 93, 77, 123, - 90, 117, 99, 79, 59, 97, 75, 97, 122, 104, - 233, 237, 227, 208, 190, 209, 230, 233, 240, 241, - 195, 197, 188, 167, 147, 204, 185, 168, 162, 157, - 142, 124, 119, 123, 106, 117, 110, 81, 121, 123, - 74, 116, 124, 119, 120, 178, 168, 146, 132, 125, - 102, 104, 105, 110, 114, 104, 82, 78, 100, 86, - 120, 102, 105, 93, 143, 127, 108, 128, 106, 88, - 177, 189, 203, 207, 215, 101, 131, 119, 95, 73, - 149, 139, 135, 147, 153, 160, 167, 165, 174, 177, - 120, 109, 134, 140, 145, 131, 130, 142, 139, 161, - 143, 158, 148, 145, 145, 123, 142, 132, 116, 102, - 40, 23, 79, 82, 84, 26, 83, 141, 130, 122, - 65, 46, 43, 89, 86, 28, 75, 80, 79, 98, - 84, 65, 47, 26, 44, 49, 112, 101, 100, 94, - 88, 76, 75, 48, 82, 104, 100, 75, 45, 15, - 99, 83, 63, 34, 30, 66, 55, 94, 118, 113, - 122, 106, 91, 68, 60, 135, 122, 104, 77, 59, - 82, 102, 84, 62, 46, 92, 74, 55, 82, 71, - 145, 134, 118, 93, 75, 79, 62, 83, 65, 55, - 91, 94, 64, 70, 98, 89, 117, 110, 87, 97, - 210, 223, 225, 223, 213, 83, 103, 86, 101, 85, - 126, 106, 81, 79, 105, 216, 219, 217, 199, 179, - 86, 78, 115, 138, 135, 102, 84, 87, 59, 46, - 219, 206, 184, 167, 158, 201, 188, 165, 145, 135, - 87, 113, 142, 152, 155, 190, 170, 153, 149, 146, - 205, 208, 201, 185, 167, 84, 73, 124, 104, 96, - 76, 88, 99, 74, 80, 110, 125, 122, 99, 112, - 108, 84, 70, 130, 137, 161, 152, 136, 119, 105, - 110, 91, 101, 74, 96, 111, 101, 93, 153, 149, - 133, 124, 102, 97, 120, 101, 93, 75, 81, 64, - 111, 94, 107, 79, 58, 188, 206, 215, 221, 232, - 163, 175, 165, 150, 136, 103, 106, 123, 133, 132, - 168, 184, 191, 183, 170, 110, 117, 90, 98, 93, - 104, 87, 122, 98, 127, 129, 110, 127, 113, 125, - 134, 118, 102, 140, 132, 186, 199, 202, 198, 188, - 149, 147, 175, 185, 186, 117, 93, 99, 112, 93, - 107, 138, 138, 129, 128, 96, 129, 104, 118, 134, - 145, 136, 115, 121, 129, 138, 155, 148, 134, 120, - 170, 151, 150, 145, 138, 168, 173, 185, 194, 200, - 144, 159, 172, 168, 156, 121, 121, 138, 173, 168, - 126, 111, 140, 139, 117, 149, 133, 142, 137, 130, - 143, 139, 158, 158, 146, 119, 128, 121, 132, 145, - 122, 136, 159, 153, 141, 133, 133, 130, 129, 126, - 120, 76, 50, 149, 109, 92, 155, 118, 90, 66, - 132, 117, 87, 156, 117, 119, 102, 44, 83, 91, - 109, 73, 106, 84, 29, 55, 130, 112, 81, 241, - 75, 40, 91, 89, 67, 112, 90, 149, 81, 72, - 128, 90, 71, 28, 160, 73, 157, 123, 143, 108, - 63, 88, 70, 81, 97, 75, 111, 149, 113, 96, - 78, 104, 83, 179, 95, 105, 106, 65, 130, 66, - 51, 118, 92, 53, 68, 105, 75, 176, 151, 115, - 94, 75, 68, 95, 220, 103, 125, 105, 43, 95, - 39, 114, 65, 145, 135, 33, 142, 138, 103, 52, - 82, 85, 117, 110, 67, 102, 74, 42, 62, 118, - 144, 121, 82, 57, 102, 67, 75, 44, 129, 96, - 75, 63, 88, 48, 116, 135, 94, 85, 102, 66, - 122, 77, 105, 122, 152, 120, 56, 90, 83, 100, - 90, 128, 63, 80, 103, 126, 117, 103, 80, 193, - 42, 73, 117, 93, 91, 95, 128, 100, 128, 162, - 70, 120, 126, 73, 123, 99, 99, 91, 75, 135, - 81, 125, 111, 77, 13, 94, 78, 85, 187, 157, - 11, 143, 109, 99, 119, 53, 141, 82, 122, 68, - 132, 89, 136, 119, 88, 75, 49, 174, 119, 70, - 138, 121, 108, 78, 52, 104, 90, 96, 93, 93, - 114, 90, 78, 46, 58, 62, 114, 69, 44, 162, - 103, 58, 98, 141, 83, 137, 95, 119, 73, 111, - 81, 46, 126, 111, 123, 107, 117, 122, 121, 54, - 106, 104, 59, 110, 148, 97, 155, 97, 83, 133, - 97, 71, 57, 91, 58, 52, 79, 127, 152, 109, - 96, 92, 145, 107, 149, 102, 61, 125, 61, 170, - 56, 89, 77, 106, 38, 147, 96, 77, 105, 123, - 85, 83, 117, 63, 69, 126, 133, 93, 107, 92, - 77, 115, 95, 111, 103, 61, 87, 103, 98, 155, - 94, 111, 80, 78, 54, 117, 128, 130, 99, 109, - 106, 99, 113, 133, 115, 89, 65, 74, 112, 127 -}; - -static const uint8_t wmavoice_dq_lsp16i3[0x300] = { - 70, 100, 121, 129, 132, 132, 201, 188, 165, 145, 144, 136, - 112, 127, 116, 125, 130, 129, 124, 135, 135, 146, 129, 128, - 162, 158, 144, 151, 135, 129, 103, 86, 111, 113, 112, 122, - 90, 139, 129, 117, 126, 129, 142, 145, 167, 147, 124, 124, - 230, 209, 189, 175, 156, 141, 64, 80, 86, 108, 121, 129, - 44, 79, 115, 113, 115, 128, 133, 106, 79, 109, 125, 127, - 171, 156, 132, 109, 103, 115, 106, 70, 93, 145, 141, 128, - 148, 125, 122, 107, 110, 117, 146, 145, 128, 110, 98, 111, - 237, 212, 185, 156, 139, 133, 84, 55, 26, 77, 114, 127, - 172, 170, 171, 168, 162, 143, 82, 82, 76, 70, 104, 126, - 17, 95, 109, 111, 120, 132, 81, 74, 57, 126, 141, 131, - 110, 127, 162, 148, 129, 123, 177, 172, 155, 151, 145, 134, - 144, 123, 90, 66, 109, 130, 82, 127, 103, 123, 132, 131, - 127, 97, 97, 142, 140, 128, 159, 134, 136, 123, 113, 117, - 131, 140, 154, 169, 158, 134, 96, 109, 150, 122, 105, 120, - 120, 150, 152, 122, 119, 125, 123, 126, 124, 107, 100, 113, - 248, 233, 216, 189, 160, 142, 58, 24, 13, 77, 111, 127, - 183, 189, 182, 157, 140, 131, 96, 83, 59, 43, 73, 119, - 222, 196, 171, 146, 129, 128, 32, 13, 53, 101, 114, 127, - 119, 101, 70, 70, 110, 127, 77, 86, 161, 148, 130, 118, - 199, 183, 170, 167, 156, 141, 30, 115, 142, 133, 131, 130, - 101, 103, 181, 176, 152, 126, 66, 44, 73, 94, 111, 128, - 150, 122, 100, 101, 104, 118, 61, 110, 87, 76, 93, 125, - 190, 170, 150, 134, 135, 129, 112, 89, 63, 123, 141, 132, - 175, 154, 136, 142, 140, 132, 117, 143, 129, 128, 136, 132, - 168, 142, 112, 113, 128, 128, 155, 169, 159, 144, 139, 131, - 61, 136, 144, 124, 112, 123, 86, 81, 104, 121, 129, 130, - 160, 127, 118, 150, 151, 134, 126, 115, 121, 132, 134, 131, - 137, 148, 144, 139, 140, 134, 106, 102, 105, 90, 87, 113, - 134, 129, 128, 121, 121, 123, 153, 151, 129, 139, 142, 134, - 150, 142, 141, 148, 149, 141, 100, 121, 133, 147, 150, 134, - 163, 158, 147, 132, 141, 132, 142, 127, 141, 136, 136, 132, - 232, 218, 205, 189, 169, 146, 243, 224, 201, 171, 147, 138, - 224, 196, 169, 162, 154, 140, 51, 20, 59, 111, 121, 128, - 203, 197, 193, 177, 162, 145, 75, 40, 47, 122, 130, 129, - 102, 77, 47, 83, 121, 129, 111, 108, 84, 56, 63, 114, - 211, 181, 154, 137, 126, 125, 213, 198, 186, 162, 144, 138, - 41, 45, 90, 110, 118, 130, 83, 63, 130, 164, 153, 128, - 195, 167, 142, 123, 113, 119, 19, 42, 105, 113, 120, 132, - 50, 63, 49, 64, 112, 128, 114, 90, 132, 171, 162, 134, - 129, 128, 107, 83, 74, 110, 50, 116, 109, 120, 128, 132, - 94, 59, 73, 111, 117, 126, 197, 170, 166, 153, 138, 132, - 65, 48, 109, 133, 131, 128, 170, 163, 172, 158, 138, 130, - 66, 126, 147, 160, 151, 132, 42, 129, 117, 95, 91, 120, - 97, 165, 164, 142, 133, 125, 163, 142, 114, 88, 97, 122, - 104, 77, 142, 143, 128, 120, 136, 160, 188, 169, 149, 130, - 113, 83, 85, 102, 114, 125, 164, 169, 142, 120, 122, 124, - 98, 152, 132, 105, 92, 117, 42, 71, 125, 155, 151, 137, - 94, 105, 81, 107, 118, 126, 84, 56, 123, 117, 108, 122, - 174, 179, 166, 137, 118, 121, 130, 103, 147, 152, 134, 124, - 148, 127, 94, 117, 144, 134, 129, 106, 102, 95, 106, 118, - 147, 157, 153, 125, 103, 117, 155, 128, 113, 132, 120, 122, - 181, 151, 136, 126, 122, 122, 110, 111, 109, 108, 120, 124, - 97, 130, 103, 89, 107, 124, 179, 158, 158, 142, 131, 128, - 142, 111, 115, 122, 126, 125, 145, 145, 134, 115, 129, 128, - 130, 139, 112, 99, 121, 125, 79, 104, 119, 102, 105, 123, - 116, 121, 136, 125, 126, 127, 124, 100, 122, 119, 111, 119, - 159, 140, 139, 128, 138, 131, 105, 100, 116, 128, 135, 132, - 159, 142, 156, 147, 140, 134, 130, 150, 129, 126, 114, 120, - 138, 124, 146, 131, 109, 119, 93, 115, 125, 131, 125, 129, - 125, 121, 101, 119, 114, 120, 163, 154, 151, 153, 153, 139, - 166, 153, 150, 133, 119, 121, 159, 151, 128, 130, 122, 123, - 147, 154, 144, 133, 128, 127, 129, 131, 134, 140, 148, 138, - 138, 136, 120, 131, 135, 131, 150, 140, 137, 144, 129, 129 -}; - -static const uint8_t wmavoice_dq_lsp10r[0x1400] = { - 128, 128, 129, 129, 130, 130, 131, 130, 129, 129, - 134, 133, 127, 125, 136, 135, 135, 134, 173, 172, - 133, 139, 136, 165, 133, 176, 137, 159, 135, 152, - 147, 161, 147, 152, 149, 156, 146, 146, 140, 136, - 134, 135, 136, 140, 139, 155, 123, 133, 132, 142, - 132, 148, 143, 177, 124, 143, 123, 136, 126, 134, - 126, 125, 125, 124, 129, 128, 123, 123, 133, 133, - 116, 116, 121, 121, 121, 120, 129, 128, 131, 131, - 132, 133, 132, 129, 138, 124, 138, 124, 132, 100, - 135, 94, 149, 111, 152, 115, 150, 128, 141, 133, - 129, 129, 130, 129, 147, 145, 136, 137, 120, 122, - 120, 122, 127, 129, 104, 108, 113, 115, 124, 124, - 140, 139, 147, 145, 132, 130, 184, 177, 201, 196, - 170, 171, 160, 161, 145, 147, 137, 145, 131, 131, - 130, 130, 130, 130, 130, 130, 132, 134, 131, 132, - 131, 133, 141, 144, 142, 149, 84, 93, 103, 104, - 139, 139, 142, 140, 147, 147, 172, 165, 122, 121, - 98, 100, 101, 106, 112, 117, 122, 124, 124, 124, - 134, 133, 133, 133, 146, 142, 147, 145, 156, 156, - 143, 146, 119, 124, 129, 132, 151, 149, 136, 135, - 147, 148, 181, 180, 199, 188, 190, 173, 166, 161, - 147, 142, 153, 149, 154, 146, 150, 146, 138, 134, - 131, 135, 96, 136, 48, 138, 56, 131, 63, 124, - 85, 128, 103, 132, 117, 134, 120, 132, 125, 129, - 131, 130, 129, 128, 129, 128, 163, 168, 117, 120, - 121, 121, 136, 138, 131, 132, 135, 136, 131, 133, - 133, 133, 133, 134, 117, 118, 105, 109, 142, 151, - 144, 159, 131, 138, 121, 126, 123, 123, 121, 124, - 131, 131, 129, 129, 141, 140, 142, 134, 87, 90, - 109, 109, 130, 127, 139, 143, 133, 131, 127, 126, - 134, 135, 134, 136, 97, 98, 130, 132, 134, 137, - 115, 119, 125, 130, 107, 109, 119, 118, 126, 127, - 134, 135, 127, 132, 172, 203, 160, 196, 152, 179, - 152, 172, 148, 168, 153, 172, 145, 156, 137, 140, - 102, 116, 42, 56, 74, 61, 82, 70, 86, 78, - 101, 97, 104, 100, 115, 108, 116, 108, 123, 118, - 149, 143, 166, 129, 168, 96, 142, 95, 135, 98, - 117, 86, 116, 93, 121, 108, 119, 107, 121, 117, - 135, 135, 127, 138, 72, 132, 99, 136, 112, 147, - 120, 152, 136, 155, 138, 146, 140, 142, 134, 139, - 163, 145, 192, 130, 147, 124, 147, 125, 133, 125, - 127, 124, 128, 123, 129, 122, 130, 122, 130, 125, - 130, 137, 135, 180, 124, 133, 130, 129, 132, 133, - 124, 124, 131, 130, 132, 136, 126, 124, 127, 125, - 132, 132, 133, 133, 144, 140, 143, 142, 137, 135, - 143, 138, 152, 149, 221, 219, 158, 161, 143, 141, - 130, 129, 140, 135, 170, 145, 193, 156, 186, 152, - 167, 139, 151, 131, 142, 127, 134, 120, 131, 125, - 135, 133, 141, 125, 199, 109, 137, 126, 134, 123, - 130, 129, 132, 123, 128, 125, 122, 126, 125, 125, - 130, 128, 91, 89, 138, 135, 139, 134, 133, 129, - 132, 130, 125, 128, 136, 135, 129, 127, 126, 126, - 132, 131, 133, 131, 128, 120, 132, 126, 126, 119, - 134, 130, 131, 123, 104, 95, 140, 141, 136, 137, - 133, 133, 133, 134, 117, 98, 74, 49, 112, 111, - 123, 122, 126, 127, 131, 131, 127, 126, 128, 129, - 130, 131, 124, 127, 101, 107, 108, 109, 115, 115, - 100, 99, 130, 128, 134, 136, 125, 127, 128, 130, - 136, 137, 145, 150, 149, 164, 136, 151, 114, 111, - 124, 125, 143, 150, 162, 174, 158, 169, 136, 137, - 131, 131, 131, 131, 132, 133, 111, 110, 122, 121, - 136, 136, 134, 133, 131, 132, 127, 127, 125, 125, - 128, 129, 129, 130, 125, 127, 140, 140, 148, 149, - 133, 136, 146, 153, 110, 118, 127, 129, 128, 129, - 131, 133, 127, 131, 140, 161, 167, 224, 131, 139, - 136, 143, 135, 139, 138, 143, 149, 155, 141, 143, - 134, 132, 120, 111, 83, 83, 121, 126, 102, 107, - 112, 115, 97, 104, 120, 115, 129, 123, 122, 122, - 134, 135, 122, 131, 102, 124, 114, 119, 93, 103, - 78, 79, 67, 72, 66, 73, 78, 82, 103, 102, - 144, 135, 165, 139, 165, 129, 160, 126, 153, 127, - 161, 134, 160, 142, 160, 143, 148, 140, 138, 135, - 138, 95, 147, 54, 143, 78, 140, 112, 142, 113, - 140, 121, 135, 117, 135, 122, 136, 131, 131, 132, - 147, 159, 140, 156, 127, 81, 142, 128, 146, 127, - 144, 125, 146, 128, 149, 130, 144, 135, 133, 128, - 130, 131, 131, 131, 134, 139, 126, 134, 141, 154, - 168, 205, 153, 176, 148, 163, 147, 158, 141, 143, - 131, 135, 126, 146, 108, 157, 107, 156, 119, 146, - 100, 138, 104, 125, 119, 134, 101, 122, 113, 122, - 95, 133, 52, 140, 83, 136, 110, 133, 114, 131, - 123, 131, 133, 131, 138, 135, 132, 132, 127, 127, - 129, 128, 124, 122, 128, 126, 145, 170, 143, 172, - 141, 163, 143, 176, 138, 164, 139, 155, 135, 145, - 135, 136, 136, 127, 132, 76, 128, 76, 127, 63, - 125, 66, 123, 67, 120, 71, 124, 92, 122, 111, - 133, 133, 135, 136, 139, 140, 147, 147, 150, 144, - 156, 147, 150, 145, 154, 146, 120, 123, 123, 124, - 137, 133, 170, 141, 124, 124, 135, 134, 134, 135, - 132, 132, 129, 129, 130, 130, 136, 136, 130, 132, - 147, 159, 135, 158, 115, 146, 120, 148, 117, 136, - 115, 137, 113, 132, 133, 142, 140, 144, 132, 134, - 134, 135, 134, 137, 137, 147, 162, 178, 136, 147, - 134, 144, 123, 132, 111, 113, 113, 113, 124, 124, - 132, 131, 126, 126, 117, 114, 100, 95, 130, 125, - 157, 145, 164, 156, 163, 158, 145, 145, 133, 134, - 134, 134, 127, 126, 113, 102, 136, 130, 124, 122, - 143, 145, 127, 131, 135, 143, 133, 137, 132, 132, - 92, 94, 122, 125, 128, 129, 131, 130, 134, 135, - 132, 128, 129, 127, 132, 132, 131, 129, 127, 127, - 129, 129, 132, 131, 139, 131, 137, 132, 216, 178, - 146, 134, 147, 137, 151, 142, 148, 139, 144, 138, - 128, 127, 129, 129, 123, 131, 71, 91, 126, 128, - 130, 134, 117, 123, 125, 125, 135, 140, 129, 132, - 132, 132, 133, 134, 124, 130, 127, 133, 133, 138, - 142, 149, 135, 141, 145, 149, 154, 164, 135, 138, - 135, 135, 141, 142, 138, 137, 116, 96, 105, 86, - 127, 118, 128, 120, 124, 117, 125, 117, 125, 121, - 131, 131, 132, 134, 144, 145, 112, 112, 121, 123, - 113, 116, 121, 123, 139, 138, 128, 128, 131, 131, - 134, 132, 132, 132, 125, 128, 127, 130, 125, 131, - 120, 128, 90, 119, 68, 98, 99, 112, 115, 124, - 135, 135, 134, 134, 128, 129, 137, 137, 137, 138, - 110, 114, 129, 130, 144, 145, 123, 125, 129, 129, - 132, 133, 129, 130, 168, 187, 140, 149, 137, 144, - 129, 130, 129, 134, 133, 138, 118, 118, 122, 120, - 131, 130, 129, 128, 133, 133, 125, 125, 124, 123, - 181, 179, 129, 129, 131, 127, 139, 136, 130, 128, - 133, 133, 132, 132, 121, 120, 122, 119, 132, 129, - 129, 125, 107, 96, 136, 137, 150, 146, 135, 134, - 131, 131, 130, 130, 126, 123, 126, 123, 128, 125, - 130, 123, 134, 127, 183, 159, 143, 135, 137, 134, - 129, 129, 128, 128, 134, 133, 139, 138, 133, 132, - 129, 127, 154, 151, 150, 144, 146, 146, 141, 142, - 132, 132, 131, 131, 130, 130, 132, 133, 114, 115, - 132, 132, 122, 122, 132, 131, 115, 117, 120, 120, - 129, 129, 130, 130, 130, 129, 130, 131, 129, 131, - 130, 130, 129, 129, 133, 132, 143, 144, 91, 91, - 137, 136, 118, 107, 60, 45, 56, 49, 57, 52, - 60, 56, 71, 75, 77, 80, 92, 97, 106, 106, - 112, 131, 58, 121, 19, 65, 84, 101, 108, 122, - 121, 127, 112, 117, 106, 112, 117, 124, 126, 127, - 130, 129, 138, 133, 166, 155, 192, 179, 192, 177, - 208, 191, 204, 192, 186, 179, 163, 163, 138, 142, - 134, 134, 144, 142, 243, 236, 148, 146, 141, 137, - 145, 141, 151, 144, 147, 143, 135, 139, 134, 133, - 134, 128, 138, 88, 142, 10, 127, 76, 130, 96, - 129, 102, 128, 108, 123, 111, 127, 119, 127, 124, - 136, 136, 139, 139, 142, 140, 246, 241, 158, 167, - 143, 145, 146, 149, 143, 145, 148, 152, 133, 134, - 139, 135, 135, 136, 99, 137, 95, 133, 75, 138, - 67, 135, 73, 128, 83, 132, 96, 126, 115, 127, - 130, 132, 137, 136, 140, 135, 134, 130, 137, 131, - 159, 151, 215, 197, 181, 170, 160, 149, 150, 143, - 145, 148, 186, 207, 141, 147, 135, 137, 122, 122, - 126, 125, 128, 126, 127, 127, 134, 126, 131, 123, - 133, 133, 126, 122, 128, 122, 99, 93, 59, 60, - 82, 82, 106, 107, 119, 123, 124, 128, 128, 129, - 134, 137, 133, 139, 133, 136, 141, 132, 139, 122, - 142, 97, 130, 81, 128, 89, 129, 101, 125, 112, - 137, 140, 129, 148, 101, 159, 118, 180, 122, 178, - 120, 178, 116, 168, 118, 153, 127, 151, 126, 136, - 132, 134, 125, 126, 118, 105, 156, 124, 180, 132, - 163, 124, 148, 121, 131, 112, 127, 115, 125, 122, - 129, 131, 128, 129, 136, 134, 142, 141, 165, 158, - 203, 182, 141, 136, 132, 130, 135, 135, 130, 130, - 133, 133, 132, 132, 127, 126, 106, 105, 112, 110, - 106, 105, 80, 84, 100, 101, 122, 125, 126, 128, - 101, 109, 46, 59, 114, 112, 119, 119, 126, 121, - 129, 124, 128, 125, 125, 122, 123, 120, 125, 122, - 135, 134, 121, 134, 56, 139, 131, 145, 135, 138, - 136, 139, 126, 130, 122, 132, 126, 129, 124, 129, - 153, 169, 146, 179, 138, 139, 151, 143, 148, 138, - 153, 137, 142, 129, 144, 126, 140, 128, 133, 126, - 136, 134, 154, 149, 173, 157, 152, 144, 149, 141, - 137, 136, 127, 121, 123, 121, 121, 126, 120, 123, - 157, 143, 166, 135, 120, 122, 112, 118, 102, 118, - 111, 124, 134, 131, 141, 138, 135, 134, 126, 129, - 140, 123, 152, 76, 131, 116, 138, 136, 126, 134, - 130, 142, 126, 136, 120, 132, 126, 128, 124, 127, - 131, 138, 80, 147, 126, 138, 130, 140, 129, 134, - 133, 135, 131, 132, 126, 127, 127, 125, 125, 123, - 132, 132, 130, 132, 123, 130, 102, 102, 107, 110, - 116, 127, 132, 152, 142, 160, 143, 151, 142, 146, - 132, 132, 132, 132, 125, 126, 132, 140, 158, 199, - 135, 149, 134, 140, 135, 131, 129, 120, 127, 121, - 129, 130, 122, 123, 125, 124, 138, 138, 138, 135, - 140, 141, 101, 94, 105, 98, 121, 122, 127, 128, - 126, 127, 119, 121, 133, 156, 132, 159, 130, 148, - 137, 164, 127, 138, 130, 137, 135, 140, 126, 126, - 128, 129, 129, 129, 126, 124, 130, 128, 143, 138, - 149, 143, 185, 170, 129, 127, 138, 133, 138, 135, - 132, 134, 137, 144, 139, 183, 131, 145, 127, 128, - 128, 127, 128, 122, 129, 125, 145, 139, 135, 131, - 132, 133, 132, 130, 152, 96, 159, 85, 150, 105, - 154, 115, 143, 120, 138, 126, 134, 124, 130, 126, - 128, 127, 121, 123, 122, 123, 116, 125, 84, 87, - 133, 135, 129, 131, 123, 126, 133, 135, 131, 130, - 136, 134, 129, 119, 79, 63, 116, 116, 136, 133, - 133, 130, 140, 143, 127, 127, 124, 125, 127, 128, - 128, 126, 124, 120, 139, 128, 153, 134, 151, 134, - 174, 145, 159, 136, 165, 144, 171, 149, 143, 135, - 134, 134, 133, 133, 121, 119, 177, 162, 166, 154, - 127, 130, 132, 132, 136, 137, 142, 143, 138, 137, - 167, 151, 162, 142, 128, 136, 142, 148, 128, 143, - 145, 153, 140, 149, 132, 141, 128, 139, 127, 133, - 156, 169, 131, 129, 126, 120, 127, 125, 129, 120, - 131, 126, 126, 123, 124, 121, 122, 121, 123, 123, - 138, 140, 149, 156, 145, 152, 105, 102, 131, 126, - 151, 146, 147, 139, 144, 137, 143, 133, 135, 130, - 132, 130, 131, 129, 126, 130, 126, 129, 110, 135, - 115, 139, 108, 146, 105, 147, 121, 134, 124, 133, - 137, 137, 135, 134, 143, 142, 146, 146, 120, 121, - 139, 137, 133, 129, 149, 145, 139, 133, 130, 127, - 134, 134, 134, 134, 125, 124, 117, 119, 120, 113, - 84, 80, 122, 125, 108, 112, 97, 102, 118, 120, - 124, 123, 115, 116, 110, 111, 98, 97, 127, 124, - 129, 127, 120, 117, 114, 109, 106, 104, 116, 116, - 138, 138, 139, 141, 142, 146, 127, 125, 133, 130, - 134, 128, 134, 127, 116, 91, 105, 84, 114, 106, - 128, 128, 126, 126, 131, 137, 126, 129, 133, 139, - 134, 145, 132, 143, 150, 192, 131, 142, 138, 141, - 132, 130, 132, 130, 149, 138, 196, 152, 137, 125, - 134, 125, 139, 128, 133, 125, 141, 134, 134, 135, - 134, 135, 134, 135, 131, 130, 136, 133, 110, 106, - 142, 144, 153, 162, 131, 129, 134, 132, 131, 130, - 126, 125, 132, 130, 168, 153, 126, 124, 130, 126, - 140, 135, 140, 134, 138, 133, 145, 137, 135, 134, - 130, 130, 132, 131, 133, 132, 129, 129, 125, 128, - 128, 130, 133, 139, 143, 152, 193, 215, 152, 160, - 130, 131, 129, 131, 130, 131, 135, 136, 136, 141, - 83, 81, 121, 120, 136, 130, 150, 145, 147, 145, - 134, 133, 135, 133, 146, 142, 135, 131, 127, 128, - 134, 135, 93, 102, 126, 132, 131, 133, 127, 129, - 124, 125, 120, 122, 103, 106, 128, 129, 139, 138, - 127, 128, 134, 134, 143, 138, 139, 134, 135, 133, - 131, 130, 133, 131, 139, 134, 138, 136, 166, 156, - 119, 116, 121, 122, 126, 124, 116, 117, 123, 124, - 131, 131, 129, 129, 130, 128, 141, 138, 135, 132, - 154, 145, 137, 129, 131, 125, 146, 137, 138, 135, - 131, 131, 131, 132, 129, 130, 134, 138, 111, 116, - 113, 118, 123, 125, 122, 124, 143, 147, 138, 140, - 116, 113, 114, 112, 130, 126, 117, 115, 127, 126, - 139, 137, 141, 139, 131, 132, 143, 144, 139, 140, - 130, 130, 129, 128, 136, 134, 119, 117, 152, 143, - 155, 143, 120, 119, 142, 139, 124, 130, 126, 128, - 112, 110, 112, 109, 136, 132, 125, 118, 121, 115, - 103, 101, 109, 100, 125, 120, 121, 117, 122, 121, - 128, 128, 127, 127, 124, 124, 128, 127, 131, 129, - 142, 138, 147, 141, 115, 108, 113, 109, 122, 119, - 136, 133, 150, 139, 142, 131, 119, 111, 151, 137, - 121, 116, 146, 134, 137, 129, 121, 123, 127, 129, - 130, 130, 130, 130, 136, 137, 126, 126, 136, 136, - 133, 133, 139, 139, 142, 143, 119, 120, 134, 134, - 132, 132, 133, 133, 135, 138, 129, 131, 133, 134, - 135, 138, 126, 130, 117, 118, 131, 132, 135, 135, - 129, 129, 128, 128, 126, 129, 127, 129, 123, 125, - 115, 117, 156, 157, 127, 131, 129, 129, 128, 129, - 129, 130, 131, 131, 126, 127, 135, 134, 136, 135, - 140, 136, 117, 113, 132, 128, 104, 97, 109, 106, - 131, 131, 131, 131, 121, 123, 124, 125, 126, 127, - 127, 127, 135, 135, 128, 128, 130, 130, 141, 140, - 129, 129, 129, 129, 129, 127, 127, 125, 149, 146, - 125, 123, 134, 133, 134, 132, 152, 150, 138, 138, - 128, 128, 126, 125, 132, 133, 141, 143, 136, 136, - 126, 127, 126, 127, 129, 131, 128, 129, 135, 134, - 176, 139, 192, 135, 145, 122, 149, 117, 155, 134, - 169, 133, 157, 139, 142, 136, 151, 152, 142, 147, - 166, 174, 103, 107, 141, 134, 140, 136, 144, 135, - 147, 135, 156, 131, 153, 127, 133, 126, 130, 124, - 127, 130, 123, 124, 114, 105, 195, 193, 156, 157, - 165, 158, 126, 122, 149, 141, 174, 173, 152, 147, - 136, 139, 131, 138, 163, 169, 103, 124, 80, 102, - 153, 186, 121, 151, 134, 161, 156, 190, 141, 151, - 121, 123, 124, 127, 119, 127, 133, 134, 157, 156, - 81, 69, 136, 134, 160, 169, 118, 114, 135, 128, - 114, 116, 97, 97, 117, 122, 152, 161, 115, 121, - 106, 122, 135, 137, 111, 113, 125, 135, 141, 145, - 143, 146, 143, 150, 132, 136, 142, 150, 151, 167, - 101, 107, 155, 173, 112, 124, 105, 100, 128, 126, - 127, 130, 133, 134, 142, 121, 131, 116, 176, 145, - 161, 120, 209, 150, 196, 133, 147, 115, 149, 130, - 144, 145, 144, 145, 120, 119, 163, 160, 117, 118, - 123, 117, 154, 119, 193, 98, 149, 101, 137, 116, - 133, 135, 140, 143, 144, 156, 131, 146, 186, 201, - 140, 139, 123, 125, 158, 169, 157, 166, 142, 143, - 130, 131, 132, 132, 128, 128, 141, 142, 147, 149, - 145, 148, 137, 139, 129, 129, 107, 108, 157, 157, - 120, 121, 119, 119, 140, 132, 137, 131, 118, 113, - 143, 136, 134, 135, 164, 158, 133, 125, 127, 124, - 148, 122, 197, 130, 173, 145, 110, 139, 123, 165, - 83, 158, 90, 167, 93, 142, 136, 169, 134, 152, - 130, 126, 154, 138, 227, 150, 156, 114, 147, 114, - 142, 109, 135, 110, 166, 135, 176, 150, 152, 142, - 132, 132, 136, 136, 130, 135, 143, 152, 136, 144, - 152, 160, 177, 185, 112, 112, 165, 166, 160, 161, - 145, 145, 138, 139, 116, 118, 127, 131, 66, 80, - 132, 142, 119, 127, 101, 108, 120, 130, 126, 130, - 135, 135, 142, 139, 153, 137, 55, 30, 142, 139, - 139, 143, 135, 133, 129, 133, 109, 108, 129, 129, - 136, 135, 134, 131, 129, 132, 132, 134, 135, 149, - 79, 206, 123, 137, 135, 143, 130, 140, 131, 134, - 100, 99, 165, 164, 142, 123, 148, 133, 133, 122, - 142, 133, 138, 125, 119, 111, 129, 123, 137, 130, - 131, 132, 123, 129, 174, 185, 196, 181, 127, 111, - 156, 141, 132, 114, 129, 106, 132, 107, 126, 117, - 134, 140, 131, 136, 119, 146, 92, 246, 128, 132, - 125, 129, 132, 140, 128, 141, 126, 145, 137, 142, - 130, 130, 110, 115, 124, 139, 127, 151, 118, 152, - 98, 146, 36, 108, 126, 158, 112, 146, 112, 130, - 138, 136, 145, 138, 153, 145, 116, 125, 90, 103, - 137, 138, 189, 185, 141, 151, 86, 93, 111, 111, - 133, 171, 125, 209, 140, 132, 130, 134, 129, 101, - 142, 120, 142, 132, 135, 126, 141, 140, 140, 134, - 128, 123, 131, 123, 138, 118, 163, 133, 240, 197, - 176, 151, 126, 123, 81, 94, 109, 118, 124, 133, - 135, 133, 137, 134, 154, 135, 140, 155, 69, 190, - 119, 149, 141, 151, 142, 123, 135, 125, 129, 130, - 127, 125, 132, 127, 107, 80, 123, 103, 145, 131, - 133, 107, 140, 103, 135, 106, 170, 145, 159, 143, - 136, 137, 127, 130, 105, 119, 129, 134, 141, 151, - 116, 127, 119, 140, 75, 119, 152, 162, 149, 152, - 72, 138, 9, 143, 118, 160, 126, 134, 141, 147, - 135, 131, 129, 129, 135, 129, 136, 126, 133, 125, - 137, 135, 146, 141, 145, 139, 141, 140, 133, 130, - 213, 208, 139, 130, 139, 136, 117, 117, 126, 125, - 133, 130, 138, 131, 141, 100, 145, 93, 159, 121, - 144, 132, 117, 160, 102, 187, 99, 162, 117, 144, - 132, 132, 134, 134, 140, 141, 127, 126, 128, 131, - 116, 116, 121, 127, 119, 126, 114, 114, 99, 100, - 141, 144, 148, 159, 179, 224, 95, 131, 100, 125, - 87, 110, 112, 132, 134, 147, 111, 125, 122, 122, - 137, 140, 141, 129, 169, 12, 144, 132, 133, 144, - 141, 146, 137, 147, 136, 122, 133, 130, 131, 128, - 141, 142, 128, 139, 15, 69, 160, 159, 142, 130, - 137, 126, 159, 141, 145, 143, 128, 125, 134, 128, - 131, 130, 127, 127, 114, 104, 119, 98, 83, 68, - 139, 120, 173, 142, 199, 154, 191, 153, 158, 145, - 128, 130, 127, 127, 148, 150, 110, 99, 119, 109, - 120, 113, 163, 154, 110, 90, 138, 129, 149, 144, - 131, 134, 124, 142, 76, 217, 130, 129, 140, 138, - 133, 135, 145, 150, 136, 138, 127, 130, 130, 134, - 144, 119, 178, 70, 143, 130, 115, 136, 139, 138, - 129, 109, 136, 116, 147, 122, 126, 112, 126, 123, - 132, 139, 128, 144, 107, 156, 75, 163, 120, 164, - 151, 136, 151, 99, 160, 112, 159, 126, 143, 126, - 140, 138, 137, 135, 152, 108, 251, 85, 138, 116, - 137, 118, 141, 119, 136, 121, 150, 134, 138, 131, - 137, 137, 143, 144, 150, 153, 148, 154, 152, 151, - 117, 104, 124, 96, 93, 67, 146, 138, 149, 148, - 149, 153, 172, 193, 108, 114, 125, 128, 145, 165, - 149, 160, 121, 130, 115, 120, 110, 112, 121, 118, - 145, 146, 141, 142, 127, 127, 103, 95, 138, 143, - 114, 126, 109, 115, 143, 136, 153, 149, 144, 142, - 140, 138, 150, 144, 128, 116, 142, 136, 135, 122, - 93, 88, 164, 163, 141, 142, 171, 182, 154, 160, - 124, 125, 122, 123, 158, 155, 111, 97, 138, 130, - 157, 134, 101, 65, 129, 118, 121, 114, 124, 119, - 131, 133, 125, 129, 136, 147, 135, 152, 131, 133, - 110, 115, 118, 114, 161, 159, 233, 218, 172, 166, - 140, 107, 125, 0, 140, 103, 140, 115, 125, 113, - 132, 135, 128, 133, 138, 146, 131, 145, 127, 133, - 131, 131, 122, 122, 135, 132, 126, 124, 132, 133, - 164, 167, 121, 127, 117, 120, 167, 162, 145, 143, - 135, 134, 136, 134, 156, 146, 195, 177, 127, 139, - 108, 140, 141, 173, 141, 178, 131, 155, 129, 141, - 134, 134, 119, 114, 184, 184, 127, 126, 147, 151, - 130, 140, 146, 159, 134, 145, 131, 136, 137, 142, - 135, 137, 128, 136, 83, 108, 97, 98, 152, 119, - 207, 144, 142, 121, 144, 129, 131, 127, 130, 132, - 124, 125, 108, 107, 94, 116, 81, 114, 139, 173, - 131, 158, 145, 177, 141, 163, 136, 140, 143, 144, - 135, 141, 132, 136, 134, 142, 142, 136, 173, 50, - 143, 106, 142, 127, 134, 139, 127, 133, 125, 125, - 129, 130, 131, 133, 132, 148, 110, 138, 113, 135, - 138, 175, 108, 151, 55, 119, 51, 100, 93, 116, - 121, 121, 146, 151, 99, 120, 127, 137, 107, 122, - 125, 139, 110, 132, 135, 156, 141, 156, 148, 157, - 137, 137, 141, 140, 139, 137, 130, 128, 138, 136, - 132, 134, 115, 110, 177, 179, 81, 86, 100, 98, - 84, 83, 121, 121, 148, 157, 127, 133, 146, 156, - 127, 136, 143, 151, 135, 139, 138, 142, 136, 136, - 201, 164, 151, 129, 123, 136, 147, 148, 127, 142, - 128, 143, 101, 126, 119, 133, 114, 131, 116, 126, - 132, 133, 140, 140, 126, 125, 156, 153, 142, 129, - 140, 130, 77, 69, 134, 132, 146, 148, 135, 136, - 133, 132, 123, 116, 116, 103, 150, 135, 144, 127, - 130, 117, 136, 122, 122, 106, 48, 38, 81, 78, - 145, 146, 135, 136, 123, 122, 126, 133, 133, 138, - 145, 145, 144, 150, 160, 181, 142, 139, 150, 150, - 136, 136, 139, 139, 133, 133, 139, 135, 134, 129, - 140, 137, 153, 145, 132, 131, 151, 144, 68, 66, - 137, 137, 139, 139, 146, 146, 142, 139, 129, 128, - 131, 129, 133, 132, 135, 134, 135, 134, 201, 200, - 137, 136, 146, 143, 155, 153, 157, 158, 131, 138, - 140, 139, 143, 144, 128, 123, 216, 192, 159, 150, - 137, 138, 136, 142, 145, 148, 126, 162, 140, 170, - 186, 95, 131, 140, 143, 148, 133, 128, 130, 133, - 141, 139, 153, 150, 122, 122, 134, 144, 124, 130, - 159, 166, 133, 139, 151, 150, 138, 139, 131, 134, - 121, 121, 131, 129, 148, 180, 121, 135, 118, 131, - 124, 148, 119, 119, 129, 126, 150, 156, 155, 160, - 40, 154, 115, 157, 133, 129, 140, 133, 143, 133, - 143, 132, 144, 130, 141, 131, 134, 130, 137, 133, - 134, 136, 141, 140, 145, 137, 152, 124, 183, 91, - 118, 154, 123, 158, 136, 134, 140, 142, 138, 142, - 138, 135, 131, 131, 138, 129, 121, 128, 146, 219, - 124, 123, 125, 135, 120, 126, 127, 141, 133, 136, - 127, 124, 120, 107, 152, 125, 149, 108, 158, 144, - 196, 185, 174, 164, 151, 149, 138, 131, 140, 137, - 149, 148, 144, 145, 143, 145, 140, 143, 141, 147, - 112, 125, 113, 113, 149, 155, 143, 149, 146, 151, - 138, 138, 141, 138, 144, 129, 134, 125, 143, 140, - 153, 154, 142, 123, 162, 42, 154, 106, 153, 130, - 153, 153, 137, 137, 144, 144, 142, 140, 165, 151, - 161, 140, 144, 134, 156, 124, 167, 143, 166, 155, - 132, 132, 137, 138, 137, 132, 124, 127, 140, 144, - 134, 140, 162, 180, 127, 131, 152, 169, 145, 156, - 133, 134, 131, 133, 130, 132, 147, 149, 125, 117, - 127, 118, 159, 155, 147, 142, 122, 117, 145, 144, - 138, 137, 130, 133, 113, 149, 168, 224, 166, 201, - 129, 151, 147, 154, 136, 135, 140, 136, 152, 141, - 120, 112, 140, 127, 161, 100, 132, 115, 118, 125, - 115, 133, 115, 157, 144, 146, 114, 135, 127, 139, - 138, 141, 135, 135, 137, 136, 147, 142, 143, 144, - 139, 152, 142, 136, 147, 143, 177, 39, 125, 71, - 147, 143, 66, 88, 132, 158, 123, 126, 116, 135, - 119, 124, 128, 135, 133, 140, 137, 126, 137, 130, - 155, 38, 149, 103, 130, 135, 139, 143, 127, 137, - 135, 141, 138, 148, 131, 148, 136, 147, 132, 139, - 136, 140, 115, 129, 115, 151, 136, 160, 87, 131, - 157, 176, 150, 164, 140, 141, 135, 119, 137, 133, - 141, 140, 140, 139, 134, 134, 142, 144, 131, 132, - 131, 134, 131, 132, 116, 114, 129, 133, 205, 207, - 130, 133, 160, 170, 137, 127, 124, 112, 158, 146, - 155, 137, 134, 136, 137, 142, 177, 184, 149, 152, - 135, 134, 133, 132, 135, 129, 144, 136, 139, 134, - 161, 155, 126, 109, 215, 186, 177, 153, 160, 149, - 139, 139, 136, 140, 140, 142, 186, 71, 129, 144, - 131, 165, 142, 152, 140, 151, 141, 143, 137, 139, - 144, 138, 150, 135, 133, 126, 136, 143, 99, 152, - 139, 131, 190, 118, 122, 147, 134, 155, 136, 143, - 138, 135, 137, 132, 147, 144, 150, 144, 138, 134, - 129, 133, 130, 138, 56, 175, 129, 166, 147, 165, - 140, 138, 144, 137, 141, 133, 150, 139, 129, 135, - 40, 83, 126, 130, 110, 120, 100, 110, 126, 128, - 141, 142, 217, 175, 172, 151, 146, 153, 125, 132, - 128, 137, 141, 141, 145, 145, 140, 133, 132, 131, - 129, 144, 128, 177, 133, 195, 147, 120, 138, 131, - 161, 114, 166, 134, 162, 118, 161, 115, 155, 129, - 137, 136, 141, 129, 141, 132, 55, 168, 121, 126, - 136, 139, 120, 133, 149, 147, 132, 141, 131, 136, - 147, 150, 151, 132, 101, 31, 117, 101, 129, 132, - 122, 138, 128, 137, 140, 170, 131, 143, 131, 134, - 149, 192, 122, 158, 136, 146, 133, 166, 143, 141, - 141, 136, 141, 129, 125, 155, 140, 138, 137, 131, - 111, 112, 131, 132, 120, 127, 149, 148, 151, 141, - 156, 148, 133, 129, 127, 124, 144, 137, 142, 139, - 134, 133, 141, 138, 133, 135, 124, 96, 226, 152, - 116, 108, 128, 105, 155, 130, 153, 138, 144, 139, - 142, 141, 137, 135, 142, 143, 156, 162, 136, 89, - 188, 145, 181, 152, 138, 146, 146, 154, 145, 149, - 152, 133, 158, 133, 42, 153, 117, 144, 149, 139, - 125, 139, 134, 128, 150, 128, 143, 125, 135, 132, - 143, 141, 143, 141, 164, 173, 141, 142, 156, 155, - 154, 154, 169, 170, 77, 80, 112, 105, 135, 134, - 126, 143, 120, 172, 111, 144, 120, 154, 107, 153, - 95, 134, 104, 134, 128, 116, 163, 131, 151, 136, - 135, 133, 142, 143, 152, 204, 149, 112, 156, 128, - 150, 126, 127, 129, 139, 175, 143, 141, 138, 135, - 168, 148, 152, 105, 164, 121, 134, 122, 119, 109, - 122, 148, 136, 143, 153, 132, 158, 148, 149, 150, - 133, 131, 142, 141, 150, 149, 156, 173, 138, 155, - 129, 144, 111, 107, 130, 129, 96, 89, 106, 104, - 135, 135, 144, 146, 131, 153, 134, 154, 146, 166, - 117, 138, 163, 187, 190, 216, 149, 156, 149, 152, - 142, 142, 153, 154, 109, 145, 40, 102, 116, 126, - 137, 139, 149, 157, 108, 124, 139, 146, 142, 147, - 130, 126, 120, 111, 172, 146, 169, 136, 150, 135, - 126, 96, 159, 143, 150, 122, 162, 129, 156, 142, - 135, 142, 144, 138, 222, 109, 137, 145, 144, 142, - 141, 143, 138, 136, 124, 150, 133, 144, 137, 145, - 141, 144, 139, 144, 134, 154, 114, 136, 145, 173, - 151, 215, 110, 115, 127, 134, 145, 150, 145, 144, - 144, 142, 139, 131, 147, 132, 141, 119, 143, 106, - 165, 41, 147, 129, 129, 144, 138, 135, 138, 140, - 128, 150, 89, 163, 154, 115, 141, 127, 132, 145, - 135, 157, 143, 145, 140, 141, 127, 135, 127, 129, - 142, 147, 116, 147, 104, 162, 153, 143, 146, 130, - 144, 110, 133, 123, 130, 137, 118, 198, 126, 152, - 154, 146, 139, 127, 147, 112, 207, 151, 156, 136, - 162, 137, 108, 121, 130, 135, 125, 131, 131, 134, - 134, 134, 141, 144, 107, 143, 137, 144, 124, 136, - 115, 147, 130, 157, 119, 167, 71, 144, 97, 128, - 134, 138, 132, 133, 138, 138, 146, 146, 147, 131, - 141, 138, 185, 65, 145, 123, 139, 130, 142, 128, - 139, 136, 157, 147, 124, 119, 164, 148, 170, 154, - 133, 130, 157, 148, 140, 141, 130, 135, 134, 137, - 136, 137, 143, 144, 144, 144, 178, 186, 71, 73, - 120, 118, 127, 124, 152, 151, 155, 146, 141, 138, - 142, 143, 139, 143, 133, 134, 139, 140, 138, 135, - 146, 141, 78, 198, 129, 139, 141, 141, 134, 141, - 137, 136, 120, 120, 124, 118, 143, 148, 148, 152, - 131, 143, 129, 137, 152, 158, 157, 160, 175, 178, - 137, 139, 131, 133, 146, 152, 121, 147, 142, 143, - 129, 136, 149, 145, 197, 114, 103, 141, 124, 140, - 141, 140, 129, 129, 127, 130, 131, 124, 123, 117, - 150, 139, 120, 109, 119, 120, 163, 163, 117, 121, - 139, 139, 136, 136, 94, 74, 150, 145, 126, 127, - 147, 150, 158, 162, 84, 74, 136, 129, 140, 132, - 136, 135, 146, 145, 124, 116, 129, 120, 130, 129, - 130, 109, 122, 111, 160, 141, 135, 113, 131, 121, - 136, 135, 135, 135, 147, 147, 140, 140, 144, 145, - 139, 142, 131, 137, 145, 145, 143, 153, 48, 49, - 145, 143, 151, 147, 158, 146, 135, 124, 124, 116, - 159, 140, 131, 126, 123, 120, 103, 117, 113, 119, - 148, 146, 128, 124, 123, 126, 123, 120, 158, 141, - 148, 137, 146, 143, 125, 143, 89, 107, 116, 123, - 149, 147, 141, 139, 149, 153, 118, 121, 139, 138, - 105, 119, 168, 147, 139, 141, 143, 138, 133, 130, - 126, 126, 143, 142, 146, 144, 124, 123, 143, 145, - 149, 148, 147, 141, 151, 143, 118, 113, 175, 171 -}; - -static const uint8_t wmavoice_dq_lsp16r1[0x500] = { - 147, 145, 193, 168, 188, 156, 141, 145, 141, 139, - 148, 149, 148, 149, 153, 157, 144, 144, 152, 152, - 141, 145, 153, 143, 243, 134, 151, 133, 166, 135, - 150, 149, 135, 132, 32, 39, 110, 111, 109, 114, - 126, 127, 147, 146, 177, 169, 162, 156, 210, 187, - 141, 147, 95, 150, 127, 155, 108, 133, 139, 148, - 138, 138, 140, 140, 147, 146, 134, 130, 136, 134, - 147, 146, 142, 150, 62, 174, 126, 151, 122, 156, - 154, 156, 179, 184, 115, 107, 105, 99, 127, 124, - 146, 131, 140, 44, 132, 125, 156, 146, 153, 153, - 136, 137, 145, 144, 141, 139, 158, 152, 138, 132, - 145, 145, 147, 145, 146, 141, 144, 140, 110, 97, - 140, 141, 143, 142, 130, 123, 127, 117, 126, 120, - 147, 146, 161, 155, 169, 135, 122, 117, 166, 155, - 144, 144, 142, 142, 125, 122, 137, 128, 194, 172, - 127, 85, 148, 143, 153, 141, 147, 147, 140, 143, - 118, 140, 0, 69, 51, 60, 111, 123, 137, 135, - 146, 146, 164, 165, 207, 214, 145, 143, 149, 147, - 178, 168, 197, 170, 134, 154, 148, 159, 115, 140, - 103, 118, 13, 38, 139, 138, 135, 138, 140, 141, - 144, 144, 140, 140, 150, 150, 156, 157, 164, 171, - 143, 143, 140, 142, 118, 120, 172, 172, 160, 163, - 146, 147, 150, 151, 176, 176, 230, 237, 153, 153, - 168, 156, 173, 149, 164, 148, 162, 146, 178, 158, - 147, 145, 143, 145, 111, 126, 111, 130, 89, 118, - 153, 158, 122, 120, 142, 125, 124, 105, 148, 138, - 145, 144, 156, 151, 193, 154, 146, 147, 119, 135, - 142, 141, 145, 145, 152, 147, 142, 141, 146, 146, - 139, 138, 154, 154, 148, 150, 147, 149, 144, 145, - 134, 134, 141, 140, 135, 134, 145, 147, 160, 163, - 144, 145, 149, 146, 115, 67, 127, 119, 141, 135, - 145, 141, 130, 124, 143, 144, 151, 165, 141, 144, - 154, 152, 160, 136, 115, 82, 64, 71, 64, 65, - 143, 143, 151, 149, 240, 251, 165, 173, 173, 179, - 148, 134, 156, 55, 160, 105, 133, 91, 129, 96, - 149, 149, 145, 144, 160, 154, 171, 159, 140, 142, - 154, 163, 178, 244, 147, 140, 153, 150, 137, 121, - 145, 144, 145, 146, 138, 139, 149, 152, 189, 198, - 148, 148, 156, 158, 168, 182, 165, 182, 172, 201, - 143, 142, 99, 92, 152, 152, 143, 143, 127, 127, - 165, 148, 173, 124, 113, 122, 134, 142, 127, 142, - 124, 126, 137, 137, 131, 132, 144, 142, 141, 138, - 172, 176, 138, 111, 152, 136, 167, 154, 156, 137, - 140, 150, 78, 145, 158, 157, 161, 154, 155, 147, - 153, 164, 156, 191, 129, 109, 153, 146, 153, 141, - 138, 137, 141, 138, 115, 94, 144, 141, 155, 147, - 144, 142, 144, 137, 168, 113, 141, 134, 145, 137, - 146, 144, 150, 148, 140, 155, 103, 178, 137, 149, - 145, 147, 148, 153, 175, 201, 138, 146, 110, 108, - 143, 146, 124, 134, 124, 127, 164, 158, 127, 135, - 145, 146, 150, 150, 145, 147, 95, 80, 150, 151, - 149, 149, 162, 162, 144, 152, 170, 169, 145, 154, - 145, 149, 143, 146, 142, 145, 152, 146, 160, 98, - 141, 141, 153, 153, 140, 137, 131, 131, 145, 146, - 133, 132, 127, 124, 158, 150, 173, 164, 178, 167, - 146, 146, 154, 155, 117, 127, 143, 147, 147, 156, - 142, 143, 144, 145, 146, 152, 170, 199, 151, 165, - 146, 147, 139, 140, 147, 149, 132, 134, 147, 149, - 138, 139, 142, 143, 162, 188, 145, 149, 160, 164, - 150, 150, 139, 139, 143, 142, 146, 146, 137, 138, - 142, 142, 141, 140, 152, 153, 164, 171, 110, 112, - 139, 139, 143, 143, 138, 138, 142, 142, 143, 143, - 137, 140, 142, 142, 145, 141, 149, 141, 182, 135, - 146, 146, 150, 150, 144, 145, 150, 151, 135, 137, - 137, 145, 51, 62, 68, 54, 69, 57, 62, 41, - 137, 139, 139, 144, 135, 150, 225, 232, 208, 197, - 136, 135, 141, 143, 145, 150, 160, 169, 213, 247, - 142, 137, 72, 54, 110, 107, 105, 107, 127, 130, - 145, 143, 169, 155, 219, 174, 195, 164, 183, 157, - 155, 157, 239, 232, 169, 164, 170, 172, 156, 159, - 142, 143, 136, 144, 59, 100, 139, 142, 130, 138, - 147, 146, 150, 161, 128, 235, 143, 155, 146, 167, - 154, 149, 128, 151, 42, 149, 55, 136, 59, 127, - 128, 126, 74, 92, 143, 153, 140, 150, 166, 176, - 146, 152, 150, 145, 140, 100, 140, 105, 124, 59, - 195, 191, 146, 148, 144, 136, 136, 133, 129, 122, - 133, 148, 40, 147, 102, 140, 123, 148, 118, 136, - 143, 143, 150, 148, 184, 153, 160, 147, 166, 149, - 58, 68, 127, 135, 141, 145, 143, 147, 150, 151, - 140, 143, 137, 137, 120, 114, 71, 65, 125, 123, - 153, 148, 215, 159, 136, 135, 150, 146, 150, 150, - 148, 138, 166, 94, 150, 145, 145, 139, 147, 145, - 146, 147, 150, 139, 171, 63, 158, 142, 153, 133, - 147, 148, 143, 143, 76, 72, 155, 159, 164, 176, - 149, 149, 173, 195, 145, 165, 138, 144, 150, 167, - 180, 169, 146, 151, 146, 166, 147, 166, 149, 171, - 157, 156, 168, 166, 147, 149, 121, 122, 116, 124, - 145, 145, 147, 148, 172, 189, 168, 180, 144, 146, - 139, 145, 141, 150, 115, 172, 141, 146, 143, 148, - 145, 145, 142, 143, 145, 147, 138, 143, 58, 73, - 141, 142, 146, 145, 163, 149, 218, 161, 147, 132, - 152, 147, 146, 147, 140, 150, 141, 152, 89, 150, - 78, 134, 135, 137, 139, 142, 140, 137, 137, 130, - 144, 144, 152, 151, 145, 140, 181, 170, 191, 168, - 164, 166, 136, 148, 112, 124, 139, 144, 146, 149, - 142, 151, 113, 182, 137, 150, 143, 156, 138, 147, - 154, 156, 108, 102, 118, 119, 133, 139, 113, 111, - 145, 144, 150, 147, 175, 151, 104, 106, 116, 114, - 143, 144, 151, 157, 151, 191, 135, 113, 138, 123, - 146, 146, 155, 157, 106, 145, 132, 127, 140, 125, - 161, 165, 146, 150, 151, 154, 139, 140, 142, 143, - 144, 148, 145, 149, 147, 138, 168, 104, 146, 136, - 138, 140, 91, 108, 111, 110, 145, 140, 158, 154, - 130, 112, 122, 118, 136, 135, 119, 118, 141, 140, - 147, 146, 146, 145, 138, 138, 182, 188, 132, 132, - 144, 144, 156, 155, 168, 172, 123, 128, 144, 151, - 142, 140, 145, 145, 137, 144, 141, 152, 128, 188, - 149, 149, 160, 161, 160, 160, 166, 163, 130, 107, - 143, 143, 142, 142, 149, 149, 132, 132, 170, 174, - 148, 148, 154, 153, 118, 111, 157, 155, 114, 109, - 140, 139, 138, 137, 205, 187, 137, 133, 147, 144, - 144, 145, 147, 149, 105, 125, 108, 117, 155, 162, - 146, 146, 162, 157, 144, 122, 154, 143, 161, 139, - 141, 142, 130, 131, 144, 144, 142, 141, 144, 142, - 132, 132, 141, 141, 150, 151, 139, 141, 151, 153, - 142, 142, 154, 154, 150, 150, 148, 148, 166, 165, - 143, 142, 144, 144, 132, 132, 142, 144, 130, 128, - 142, 142, 143, 143, 153, 153, 147, 142, 129, 125, - 142, 141, 143, 142, 143, 147, 105, 122, 135, 140, - 141, 140, 140, 140, 151, 151, 156, 155, 146, 146, - 133, 134, 140, 142, 142, 145, 141, 146, 112, 133, - 142, 142, 145, 145, 137, 138, 155, 157, 149, 150, - 144, 144, 139, 138, 130, 128, 132, 131, 147, 147, - 139, 140, 142, 143, 115, 121, 141, 143, 137, 141, - 146, 146, 150, 150, 145, 144, 133, 133, 133, 135, - 143, 144, 144, 144, 166, 167, 139, 142, 139, 140, - 150, 149, 138, 138, 142, 140, 148, 147, 160, 155, - 146, 146, 147, 147, 138, 137, 143, 142, 151, 150 -}; - -static const uint8_t wmavoice_dq_lsp16r2[0x500] = { - 98, 98, 119, 121, 109, 112, 128, 135, 115, 121, - 159, 113, 113, 106, 127, 114, 101, 102, 105, 111, - 161, 162, 137, 138, 161, 159, 152, 150, 150, 148, - 128, 79, 131, 102, 142, 120, 133, 119, 130, 117, - 121, 115, 142, 133, 186, 155, 179, 144, 169, 135, - 107, 103, 106, 106, 122, 122, 111, 112, 112, 115, - 127, 123, 118, 115, 128, 125, 123, 119, 115, 109, - 124, 130, 117, 126, 121, 133, 84, 144, 99, 114, - 122, 125, 123, 131, 124, 135, 176, 200, 158, 176, - 68, 74, 86, 87, 117, 115, 119, 116, 135, 128, - 115, 116, 102, 104, 119, 123, 133, 148, 102, 109, - 71, 121, 106, 117, 107, 127, 106, 122, 100, 110, - 117, 115, 129, 128, 87, 84, 116, 116, 151, 157, - 116, 128, 110, 117, 119, 134, 100, 114, 120, 129, - 142, 141, 146, 151, 94, 91, 114, 114, 118, 118, - 114, 112, 112, 109, 115, 112, 123, 123, 147, 148, - 110, 164, 106, 152, 110, 158, 106, 151, 105, 135, - 85, 51, 71, 27, 71, 34, 74, 45, 85, 53, - 145, 134, 140, 130, 136, 134, 118, 122, 118, 126, - 117, 84, 121, 81, 106, 80, 109, 106, 121, 127, - 95, 94, 112, 110, 90, 94, 109, 107, 114, 109, - 117, 118, 118, 123, 107, 107, 86, 93, 29, 31, - 125, 112, 104, 60, 121, 111, 127, 116, 133, 130, - 118, 117, 148, 145, 122, 126, 124, 127, 90, 91, - 113, 110, 119, 118, 152, 147, 115, 112, 132, 131, - 129, 140, 98, 112, 73, 85, 109, 115, 122, 126, - 123, 122, 122, 122, 126, 125, 137, 140, 203, 210, - 164, 176, 114, 114, 125, 122, 119, 112, 125, 120, - 124, 122, 118, 115, 95, 96, 141, 144, 132, 131, - 127, 130, 132, 134, 116, 114, 122, 123, 137, 134, - 111, 111, 112, 116, 106, 118, 77, 101, 104, 115, - 111, 111, 125, 126, 118, 121, 113, 115, 113, 113, - 171, 170, 202, 199, 221, 206, 199, 184, 177, 167, - 73, 90, 61, 93, 43, 74, 51, 71, 51, 72, - 130, 130, 140, 137, 134, 132, 164, 160, 118, 111, - 123, 136, 133, 154, 130, 158, 106, 110, 110, 114, - 97, 97, 91, 94, 70, 69, 125, 123, 141, 140, - 119, 100, 116, 77, 111, 67, 105, 52, 95, 34, - 100, 122, 90, 124, 68, 120, 43, 117, 50, 112, - 130, 129, 192, 188, 123, 118, 124, 117, 121, 115, - 122, 111, 129, 111, 157, 85, 125, 109, 125, 119, - 143, 152, 119, 128, 114, 116, 129, 136, 148, 157, - 119, 117, 115, 115, 150, 148, 163, 154, 109, 102, - 120, 126, 73, 119, 106, 121, 102, 122, 96, 113, - 84, 83, 117, 115, 122, 117, 154, 143, 159, 142, - 118, 122, 114, 117, 115, 122, 114, 130, 99, 156, - 123, 120, 122, 116, 100, 81, 99, 91, 121, 112, - 139, 131, 164, 142, 132, 119, 145, 133, 157, 141, - 112, 109, 118, 116, 142, 134, 108, 110, 96, 99, - 111, 110, 113, 112, 111, 104, 98, 94, 131, 131, - 115, 114, 121, 118, 120, 115, 173, 148, 123, 117, - 121, 124, 122, 124, 140, 146, 78, 82, 96, 93, - 86, 90, 124, 125, 121, 123, 105, 106, 134, 135, - 107, 109, 132, 141, 100, 95, 113, 114, 102, 105, - 113, 130, 98, 145, 116, 115, 124, 117, 115, 105, - 120, 123, 89, 87, 109, 108, 102, 101, 117, 117, - 113, 122, 132, 138, 77, 116, 86, 99, 118, 126, - 123, 120, 117, 111, 124, 119, 129, 118, 63, 58, - 141, 135, 108, 106, 109, 111, 108, 110, 135, 138, - 117, 114, 134, 127, 139, 129, 138, 130, 126, 122, - 121, 118, 124, 121, 133, 130, 98, 85, 130, 123, - 147, 129, 118, 112, 148, 130, 136, 123, 148, 131, - 113, 112, 123, 118, 123, 115, 147, 95, 117, 110, - 118, 119, 112, 113, 112, 113, 119, 119, 120, 120, - 158, 133, 198, 145, 188, 129, 197, 137, 195, 133, - 132, 140, 140, 139, 158, 156, 223, 217, 233, 233, - 48, 56, 34, 37, 82, 84, 102, 102, 108, 110, - 120, 142, 136, 169, 146, 195, 136, 186, 140, 182, - 196, 186, 158, 155, 142, 134, 132, 125, 120, 119, - 97, 105, 72, 75, 82, 85, 81, 84, 107, 109, - 67, 121, 43, 119, 69, 124, 87, 129, 88, 128, - 53, 57, 93, 98, 91, 94, 93, 98, 104, 104, - 124, 123, 133, 133, 182, 181, 119, 121, 114, 116, - 128, 105, 134, 112, 131, 72, 119, 59, 111, 84, - 132, 142, 145, 180, 124, 132, 131, 143, 122, 134, - 88, 85, 103, 103, 136, 140, 131, 143, 114, 132, - 116, 57, 113, 57, 121, 76, 126, 80, 118, 86, - 127, 112, 127, 97, 131, 100, 149, 91, 163, 86, - 122, 119, 128, 121, 128, 116, 142, 127, 173, 139, - 162, 116, 166, 107, 149, 103, 152, 107, 141, 108, - 114, 113, 118, 116, 56, 43, 90, 90, 105, 105, - 132, 134, 110, 107, 106, 105, 82, 84, 84, 84, - 102, 106, 79, 89, 99, 99, 127, 129, 114, 118, - 139, 157, 116, 123, 116, 123, 87, 89, 110, 113, - 119, 126, 97, 97, 155, 163, 142, 153, 143, 146, - 117, 114, 66, 67, 125, 126, 127, 128, 114, 113, - 111, 114, 127, 133, 123, 132, 143, 162, 133, 148, - 105, 108, 114, 114, 110, 109, 57, 48, 109, 106, - 113, 130, 104, 131, 88, 139, 102, 169, 100, 172, - 129, 114, 150, 97, 114, 112, 117, 119, 109, 116, - 92, 107, 96, 116, 90, 125, 101, 122, 125, 140, - 125, 133, 122, 129, 136, 153, 125, 135, 131, 139, - 84, 71, 129, 123, 135, 120, 114, 103, 112, 101, - 108, 121, 115, 156, 106, 123, 116, 131, 127, 139, - 137, 147, 109, 117, 119, 126, 135, 144, 117, 119, - 120, 127, 76, 105, 111, 116, 120, 125, 141, 138, - 107, 104, 162, 155, 135, 130, 127, 123, 127, 121, - 102, 104, 84, 87, 112, 115, 97, 102, 78, 82, - 119, 118, 120, 123, 91, 105, 114, 119, 119, 126, - 130, 126, 134, 126, 158, 134, 133, 99, 116, 100, - 125, 122, 145, 143, 126, 117, 98, 96, 121, 120, - 152, 148, 131, 126, 130, 129, 126, 119, 87, 87, - 131, 131, 139, 137, 101, 102, 104, 105, 86, 83, - 92, 89, 111, 105, 121, 115, 137, 124, 96, 84, - 100, 96, 122, 119, 107, 108, 93, 96, 79, 82, - 128, 123, 108, 106, 123, 120, 150, 150, 143, 140, - 121, 120, 97, 99, 79, 80, 116, 116, 88, 90, - 128, 131, 101, 97, 140, 140, 117, 116, 116, 118, - 137, 135, 100, 91, 115, 112, 134, 121, 107, 99, - 120, 122, 122, 125, 124, 126, 136, 141, 89, 95, - 103, 119, 103, 116, 122, 139, 125, 137, 152, 170, - 121, 122, 124, 124, 98, 97, 137, 140, 96, 92, - 115, 113, 136, 136, 128, 132, 122, 124, 151, 158, - 100, 107, 121, 131, 131, 158, 119, 130, 113, 114, - 114, 109, 148, 130, 103, 95, 127, 116, 137, 120, - 103, 108, 97, 97, 133, 128, 113, 109, 136, 128, - 125, 124, 118, 118, 122, 121, 101, 99, 157, 152, - 138, 134, 124, 115, 113, 101, 123, 112, 124, 110, - 116, 113, 128, 121, 119, 110, 124, 113, 128, 67, - 114, 118, 114, 123, 109, 121, 102, 123, 56, 116, - 117, 111, 112, 99, 124, 114, 112, 79, 114, 88, - 112, 113, 115, 117, 126, 127, 130, 132, 123, 122, - 111, 104, 111, 102, 112, 102, 129, 118, 129, 115, - 123, 124, 130, 133, 114, 117, 125, 127, 112, 117, - 124, 125, 119, 120, 117, 116, 105, 104, 110, 110, - 125, 124, 118, 116, 124, 123, 124, 121, 133, 132, - 111, 111, 124, 124, 120, 119, 116, 116, 134, 130, - 114, 116, 112, 113, 109, 111, 116, 118, 95, 98 -}; - -static const uint8_t wmavoice_dq_lsp16r3[0x600] = { - 84, 82, 95, 94, 125, 131, 98, 102, 94, 93, 104, 104, - 127, 113, 87, 77, 125, 114, 109, 94, 94, 91, 106, 105, - 168, 125, 163, 120, 128, 100, 119, 99, 108, 97, 108, 106, - 86, 85, 128, 125, 79, 73, 103, 102, 123, 123, 116, 117, - 84, 76, 135, 131, 133, 133, 129, 130, 125, 123, 115, 114, - 94, 97, 79, 81, 115, 115, 94, 93, 128, 127, 126, 125, - 124, 111, 105, 114, 104, 117, 109, 110, 124, 125, 118, 117, - 107, 110, 106, 110, 93, 93, 149, 148, 118, 119, 111, 110, - 147, 157, 143, 156, 134, 136, 118, 121, 106, 107, 105, 105, - 114, 83, 114, 46, 106, 53, 110, 83, 107, 94, 105, 103, - 92, 90, 109, 106, 172, 160, 114, 110, 109, 110, 110, 109, - 90, 98, 98, 109, 102, 98, 97, 92, 100, 100, 101, 102, - 123, 117, 124, 98, 82, 80, 117, 115, 112, 110, 109, 108, - 107, 111, 100, 115, 105, 120, 104, 105, 83, 82, 95, 96, - 109, 120, 72, 71, 97, 104, 69, 74, 99, 102, 118, 117, - 137, 133, 142, 135, 105, 110, 121, 121, 125, 122, 114, 112, - 151, 186, 115, 132, 103, 111, 100, 104, 99, 101, 104, 105, - 18, 38, 56, 65, 76, 83, 85, 91, 101, 103, 108, 110, - 144, 135, 126, 121, 115, 113, 79, 80, 118, 117, 117, 117, - 117, 124, 115, 115, 126, 113, 130, 116, 112, 106, 108, 105, - 77, 76, 76, 80, 109, 109, 125, 129, 130, 133, 116, 118, - 96, 86, 109, 99, 102, 69, 84, 69, 107, 103, 114, 113, - 78, 118, 82, 114, 84, 129, 69, 112, 78, 98, 96, 103, - 89, 137, 96, 111, 105, 97, 93, 93, 101, 105, 105, 105, - 141, 123, 102, 93, 91, 79, 87, 81, 102, 99, 109, 108, - 94, 92, 124, 123, 130, 134, 100, 107, 71, 75, 92, 91, - 94, 104, 107, 83, 106, 101, 113, 114, 122, 122, 114, 114, - 118, 124, 103, 106, 95, 116, 90, 93, 107, 104, 109, 107, - 116, 118, 76, 72, 88, 88, 132, 132, 140, 141, 116, 116, - 90, 81, 111, 95, 139, 97, 123, 96, 112, 100, 110, 108, - 112, 116, 133, 140, 112, 120, 80, 85, 55, 55, 85, 84, - 125, 94, 111, 104, 116, 103, 112, 86, 93, 84, 99, 98, - 180, 179, 197, 197, 169, 163, 149, 146, 130, 124, 116, 115, - 76, 47, 36, 11, 43, 28, 66, 53, 82, 80, 102, 99, - 119, 123, 176, 201, 113, 120, 112, 111, 103, 105, 106, 110, - 145, 114, 112, 89, 120, 93, 123, 104, 131, 123, 113, 111, - 97, 109, 82, 106, 75, 104, 103, 115, 120, 124, 111, 114, - 114, 111, 113, 105, 34, 33, 63, 63, 105, 106, 122, 122, - 51, 41, 96, 92, 125, 125, 118, 118, 118, 119, 113, 113, - 111, 180, 108, 178, 107, 171, 110, 160, 105, 136, 102, 117, - 76, 79, 90, 92, 80, 88, 88, 93, 123, 124, 122, 122, - 131, 128, 123, 122, 151, 158, 108, 107, 129, 128, 119, 119, - 97, 99, 114, 120, 121, 125, 151, 157, 82, 89, 95, 96, - 128, 94, 130, 95, 149, 113, 149, 120, 127, 115, 113, 109, - 167, 171, 83, 80, 84, 79, 106, 106, 112, 110, 107, 108, - 130, 139, 81, 88, 107, 106, 112, 112, 119, 118, 114, 112, - 108, 105, 100, 98, 120, 116, 122, 117, 38, 37, 72, 73, - 118, 125, 110, 120, 114, 126, 135, 142, 139, 142, 118, 119, - 119, 119, 156, 145, 78, 75, 94, 94, 112, 110, 113, 113, - 101, 108, 98, 104, 103, 109, 117, 118, 167, 167, 132, 132, - 116, 108, 118, 111, 149, 136, 85, 74, 95, 92, 113, 112, - 74, 69, 104, 107, 96, 100, 117, 121, 103, 105, 103, 103, - 110, 106, 111, 101, 82, 72, 96, 92, 132, 130, 120, 121, - 116, 113, 138, 139, 104, 103, 131, 131, 68, 69, 92, 92, - 97, 97, 146, 151, 122, 132, 97, 95, 117, 116, 115, 116, - 139, 134, 110, 110, 124, 129, 100, 110, 86, 91, 100, 102, - 116, 136, 88, 90, 137, 139, 103, 114, 114, 117, 111, 110, - 82, 83, 104, 102, 97, 99, 97, 97, 58, 56, 84, 84, - 83, 122, 76, 105, 112, 126, 120, 134, 112, 120, 108, 110, - 114, 128, 73, 90, 72, 76, 98, 100, 95, 96, 101, 102, - 101, 108, 118, 126, 94, 102, 81, 83, 138, 140, 131, 130, - 88, 100, 112, 124, 105, 106, 122, 123, 121, 121, 114, 114, - 76, 108, 73, 83, 93, 95, 110, 111, 98, 99, 103, 103, - 105, 112, 98, 108, 114, 95, 117, 98, 120, 116, 116, 115, - 231, 238, 150, 146, 124, 126, 115, 122, 117, 121, 112, 112, - 74, 73, 72, 74, 60, 61, 62, 61, 85, 85, 101, 101, - 67, 69, 50, 51, 83, 83, 110, 110, 118, 113, 112, 111, - 199, 124, 184, 115, 176, 117, 165, 120, 138, 115, 116, 114, - 52, 116, 36, 107, 49, 99, 72, 106, 91, 107, 104, 105, - 140, 138, 141, 135, 154, 147, 166, 159, 139, 136, 116, 115, - 130, 119, 180, 157, 183, 149, 136, 121, 119, 114, 111, 110, - 104, 129, 113, 154, 111, 148, 108, 132, 105, 117, 106, 111, - 114, 35, 99, 65, 113, 94, 110, 98, 111, 107, 107, 106, - 106, 110, 128, 135, 162, 175, 143, 155, 115, 116, 109, 109, - 168, 155, 112, 109, 125, 125, 126, 122, 126, 124, 111, 112, - 128, 96, 160, 77, 151, 77, 121, 80, 114, 94, 107, 103, - 97, 104, 101, 116, 56, 79, 74, 83, 92, 95, 104, 106, - 63, 68, 76, 77, 110, 107, 96, 90, 85, 83, 97, 96, - 116, 110, 46, 42, 103, 100, 122, 120, 102, 101, 104, 104, - 106, 101, 109, 98, 96, 61, 67, 35, 72, 61, 96, 93, - 88, 80, 81, 76, 113, 110, 144, 143, 88, 89, 93, 94, - 95, 96, 100, 101, 136, 132, 166, 160, 148, 147, 115, 116, - 80, 78, 130, 129, 120, 108, 91, 85, 95, 91, 104, 102, - 151, 147, 106, 109, 110, 110, 64, 69, 68, 67, 96, 96, - 90, 166, 97, 128, 99, 120, 104, 121, 109, 118, 105, 109, - 122, 138, 110, 143, 75, 97, 83, 94, 89, 94, 102, 103, - 136, 142, 103, 110, 83, 89, 99, 101, 138, 138, 120, 122, - 168, 88, 105, 90, 109, 107, 110, 111, 106, 105, 103, 102, - 68, 72, 102, 104, 92, 102, 65, 75, 89, 94, 106, 106, - 83, 74, 93, 85, 73, 66, 106, 102, 100, 92, 99, 97, - 93, 99, 101, 96, 116, 112, 125, 120, 88, 88, 96, 96, - 44, 98, 93, 115, 104, 116, 103, 107, 112, 113, 107, 107, - 93, 83, 105, 99, 93, 84, 127, 125, 141, 143, 117, 118, - 106, 103, 126, 121, 137, 123, 123, 114, 147, 142, 127, 123, - 103, 110, 89, 91, 121, 124, 66, 71, 68, 69, 96, 97, - 114, 105, 68, 65, 69, 67, 96, 94, 131, 130, 123, 121, - 111, 104, 130, 121, 95, 95, 72, 74, 88, 88, 105, 104, - 135, 124, 110, 98, 114, 111, 159, 158, 111, 113, 104, 106, - 103, 108, 94, 107, 55, 57, 115, 118, 121, 122, 111, 111, - 97, 99, 106, 111, 119, 126, 59, 62, 111, 112, 124, 125, - 86, 93, 100, 110, 118, 145, 113, 132, 120, 125, 112, 112, - 101, 115, 78, 149, 81, 114, 111, 121, 108, 112, 107, 108, - 104, 104, 94, 96, 84, 83, 135, 132, 71, 69, 88, 86, - 100, 98, 62, 60, 81, 80, 90, 89, 63, 66, 89, 90, - 123, 116, 108, 99, 90, 86, 91, 92, 65, 65, 88, 88, - 84, 79, 115, 109, 123, 111, 99, 99, 134, 136, 121, 123, - 127, 137, 84, 88, 104, 107, 128, 130, 74, 69, 89, 89, - 118, 112, 143, 132, 141, 131, 113, 113, 99, 102, 104, 105, - 117, 115, 100, 99, 131, 126, 90, 88, 145, 144, 128, 127, - 112, 114, 131, 133, 85, 84, 118, 119, 151, 152, 117, 117, - 110, 105, 162, 140, 116, 107, 140, 134, 124, 122, 113, 113, - 107, 110, 124, 133, 98, 103, 99, 107, 109, 113, 112, 112, - 115, 105, 82, 77, 125, 122, 133, 132, 118, 120, 113, 113, - 101, 88, 84, 80, 97, 99, 91, 91, 94, 94, 101, 100, - 121, 86, 139, 108, 106, 93, 103, 99, 112, 108, 108, 107, - 113, 83, 105, 102, 125, 125, 114, 115, 110, 112, 108, 109, - 93, 112, 113, 121, 125, 131, 101, 101, 107, 109, 111, 111, - 98, 102, 117, 126, 80, 84, 107, 109, 83, 84, 96, 97, - 132, 136, 112, 118, 94, 93, 121, 118, 99, 98, 102, 103, - 122, 127, 128, 133, 118, 104, 102, 88, 100, 94, 104, 102, - 115, 116, 102, 105, 140, 142, 135, 130, 90, 88, 100, 101, - 94, 86, 112, 112, 89, 121, 92, 101, 109, 108, 110, 112, - 99, 93, 129, 114, 109, 99, 131, 119, 102, 97, 103, 103, - 103, 116, 124, 101, 115, 95, 105, 101, 94, 91, 100, 100, - 113, 90, 94, 86, 92, 92, 117, 111, 106, 103, 106, 105, - 115, 99, 110, 91, 107, 104, 81, 90, 108, 113, 112, 113, - 113, 114, 93, 101, 101, 102, 101, 126, 93, 103, 104, 105, - 117, 106, 124, 107, 104, 119, 108, 133, 104, 111, 104, 106 -}; - -static const float wmavoice_lsp10_intercoeff_a[32][2][10] = { - { { 0.5108627081, 0.0480548441, -1.5099149644, 0.6736935377, - 0.7536551058, 0.7651474178, 0.8510628343, 0.6667704582, - 0.7576012611, 0.7091397047 }, - { 0.1351471841, -0.1965375543, -1.6313457787, 0.3218626380, - 0.4132472873, 0.4663473070, 0.5805781186, 0.3962165117, - 0.4818550050, 0.4907165468 } }, - { { 0.8556320667, 0.7774704993, -0.0175759494, -0.1882298589, - 0.1892164350, 0.4850396216, 0.6270319819, 0.6327089071, - 0.6513319910, 0.6075088978 }, - { 0.4374088347, 0.3505934179, -0.0762144327, -0.2830760479, - -0.0626451969, 0.1500318050, 0.2602472305, 0.2781780064, - 0.3167395592, 0.3596626520 } }, - { { 0.1899779737, 0.0650856197, 0.1699010432, 0.9122628570, - 0.9097705483, 0.7433397174, 0.6304935217, 0.5164704025, - 0.4174703658, 0.5215242505 }, - { 0.0704856217, 0.0169009864, 0.0188394487, 0.5587704182, - 0.5194473267, 0.3539164960, 0.2426626086, 0.1721164286, - 0.1371548772, 0.2594856918 } }, - { { 0.8858859241, 0.9100474715, 0.8921859264, 0.9332397878, - 1.0225475132, 1.0555013716, 1.0983552337, 1.1290244758, - 1.0363244414, 0.9277705550 }, - { 0.4810934663, 0.5782935023, 0.6835935414, 0.7650781870, - 0.9018090069, 0.9996321201, 1.0219936669, 1.0474705994, - 0.9109474719, 0.7774704993 } }, - { { 0.4359549880, 0.2275702953, 0.0993548632, 0.1763395071, - 0.1055856347, 0.1018471718, 0.1170087159, 0.1221317947, - 0.1834010482, 0.2988780141 }, - { 0.1573702693, 0.1041317880, 0.0506856143, 0.0781702399, - 0.0058932900, -0.0026913285, -0.0031067133, 0.0070702136, - 0.0116394460, 0.0566394627 } }, - { { 0.8528628349, 0.8028782010, 0.4680088460, 0.9055474699, - 1.3742399514, 1.1093629301, 0.4122780561, 0.4003703594, - 0.6360319853, 0.6415704489 }, - { 0.4252934456, 0.3823703527, 0.1676856577, 0.5241550207, - 1.1995706558, 0.9088013172, 0.1224087179, 0.0730471611, - 0.3071857095, 0.3772472739 } }, - { { 0.5508781075, 0.2829549313, -0.0022067130, 0.1042702496, - 1.0318244398, 1.3258476257, 1.3550630212, 0.9931936562, - 0.7195243239, 0.6807550788 }, - { 0.2679318488, 0.0960317850, -0.1357529163, -0.1291759908, - 0.6451012194, 0.9968628883, 0.9510321021, 0.6608166099, - 0.3799472749, 0.3735780418 } }, - { { 0.9967244267, 1.0255244374, 0.9800398052, 0.7939474285, - 0.8288397491, 0.8390166759, 0.8660166860, 0.9247936308, - 0.9127474725, 0.8684397638 }, - { 0.7921474278, 0.9416859448, 0.8547320664, 0.5348165631, - 0.6231550574, 0.6703012288, 0.6987550855, 0.8147858977, - 0.7406397164, 0.6496012211 } }, - { { 0.1439394951, -0.3193529844, -0.2024914026, -0.1854606271, - 0.0877240896, 0.1617318094, 0.3087087870, 0.3777318895, - 0.3910242021, 0.4797780812 }, - { -0.0157067180, -0.1778452396, -0.1554836929, -0.1759760082, - -0.0607759655, -0.0161221027, 0.0393317640, 0.0758856237, - 0.1163856387, 0.1947548985 } }, - { { 1.1021629274, 0.9958244264, 0.4658626914, 0.3089164793, - 0.3740626574, 0.2962472439, 0.3170857131, 0.2420395315, - 0.2649549246, 0.2936857045 }, - { 0.4700857699, 0.1809087396, 0.0311625302, 0.0106009841, - 0.0311625302, 0.0266625285, 0.0221625268, 0.0156548321, - 0.0551163852, 0.1010164022 } }, - { { 0.2925087810, 0.3418011069, 0.7339243293, 0.7322627902, - 0.7288704813, 0.7924935818, 0.7724166512, 0.7819012702, - 0.8325782120, 0.7954705060 }, - { 0.0559471548, -0.0456144214, -0.0462374985, -0.1005144417, - -0.0511528850, -0.0455451906, -0.0044220984, 0.0451471508, - 0.1232394874, 0.2085318267 } }, - { { 0.2230702937, -0.9052532017, 1.2441552877, 1.0825706124, - 0.9088705480, 0.8797243834, 0.8648397624, 0.8091089725, - 0.7633474171, 0.7468704879 }, - { -0.2030452490, -1.4167303145, 1.3542322516, 0.8369397521, - 0.6148473620, 0.5560704172, 0.5450627208, 0.4978473186, - 0.4200319052, 0.4904396236 } }, - { { 0.6088242829, 0.5965704322, 0.6547242999, 0.8554936051, - -0.2989298999, 0.2404472232, 0.3573780358, 0.7499166429, - 0.7691628039, 0.6824858487 }, - { 0.2582395375, 0.2721549273, 0.3462318778, 0.4820626974, - -0.4780299664, -0.0712990463, 0.0200163722, 0.4246703684, - 0.4660011530, 0.4172626734 } }, - { { 1.1749937236, 1.0773090720, 1.0566782951, 1.0249013603, - 0.9947167337, 0.9626628757, 0.9562244117, 0.9072782397, - 0.7654243410, 0.6448935270 }, - { 1.1595552564, 0.9340013266, 0.3959395885, 0.3693549633, - 0.3915780485, 0.3104395568, 0.3499011099, 0.2236933708, - 0.1638087332, 0.1811856627 } }, - { { 0.9572628736, 0.9389859438, 0.6619243026, 0.6849089265, - 0.7276935577, 0.7839781940, 0.7987243533, 0.7748397291, - 0.7101089358, 0.7277627885 }, - { 0.5809935033, 0.5575934947, 0.3544703424, 0.3636780381, - 0.3736472726, 0.4486242235, 0.4684934616, 0.4481396079, - 0.3456780314, 0.4478626847 } }, - { { 0.1259394884, 1.3096476197, 1.0794552267, 1.0009475052, - 0.9061013162, 0.9216782451, 0.8954397738, 0.9160013199, - 0.8575012982, 0.7479089499 }, - { -0.3689222336, 1.5293861628, 0.7323320210, 0.4102703631, - 0.3825780451, 0.2828164697, 0.2644010782, 0.2455010712, - 0.2482010722, 0.2335241437 } }, - { { 0.5380704105, 0.1600702703, -0.0657605827, -0.2390452623, - -0.3885837793, -0.4150299430, -0.3001760542, -0.1451683044, - 0.1312010288, 0.2798395455 }, - { 0.2074933648, 0.0560163856, -0.0956682861, -0.2893068194, - -0.3889991641, -0.3918376267, -0.3550068438, -0.2649375796, - -0.0554451942, 0.1167317927 } }, - { { 0.6092396677, 0.5101011693, 0.4012011290, 0.5416011810, - 0.5715781152, 0.6476627588, 0.6988243163, 0.7306012511, - 0.7531704903, 0.6534781456 }, - { 0.2060395181, 0.1409625709, 0.1024702489, 0.1834010482, - 0.1946856678, 0.2547779977, 0.3134857118, 0.3283011019, - 0.3837549686, 0.3501780331 } }, - { { 0.4516011477, 0.5351627171, 0.8068243563, 0.7049858570, - 0.7165473998, 0.6005858183, 0.4870473146, 0.2500010729, - 0.3132087886, 0.4462703764 }, - { 0.1053087115, 0.1348702610, 0.4457857609, 0.3499703407, - 0.3537780344, 0.2628780007, 0.1665087342, 0.0200856030, - 0.0329625309, 0.1525241137 } }, - { { 0.7058166265, 0.7305320203, 1.1684860289, 1.4524707496, - 1.3212091625, 1.2613245249, 1.1712552607, 1.1154552400, - 1.0487167537, 0.9153782427 }, - { 0.2286087573, 0.2851703167, 1.2016475797, 1.5154707730, - 1.2726091444, 1.1459167898, 0.9801090360, 0.9296397865, - 0.8490551412, 0.6772243083 } }, - { { 0.6686396897, 0.5728935003, 0.4734780788, 0.6970243156, - 0.5852165818, -0.0762836635, -0.2054683268, -0.1380375326, - 0.1282933354, 0.3467164934 }, - { 0.2925087810, 0.2344933748, 0.1677548885, 0.2747856975, - 0.2097087502, -0.2795452774, -0.3761222363, -0.3183837533, - -0.0834836662, 0.1482318044 } }, - { { 0.6559704542, 0.7737320364, 0.9867551923, 0.9912551939, - 0.9508936405, 0.9114320874, 0.8336859047, 0.7905551195, - 0.7672935724, 0.7532397211 }, - { 0.1843702793, 0.2565087676, 0.7571858764, 0.7545551062, - 0.6793704629, 0.5981627405, 0.5078165531, 0.4282011390, - 0.3948318958, 0.4502165318 } }, - { { 0.4430857599, 0.6102781296, 0.8485012949, 0.8573628366, - 0.9078320861, 0.9979705811, 1.0411013663, 1.0524552166, - 1.0194321275, 0.9023628533 }, - { 0.0070009828, 0.0084548295, 0.1613856554, 0.3484472632, - 0.4385857582, 0.5895088911, 0.6367935240, 0.6736935377, - 0.7026320100, 0.5924165845 } }, - { { 1.0532859862, 1.1059706211, 1.1311013997, 1.1250783205, - 1.0425552130, 0.9993551970, 0.9673013389, 0.9386397898, - 0.8836013079, 0.8336859047 }, - { 0.9791398048, 1.1481321752, 1.1275706291, 1.0082167387, - 0.8809705377, 0.8031551242, 0.7287320197, 0.6496704519, - 0.5211088657, 0.4734088480 } }, - { { -0.0251221061, -0.0443682671, 0.1282241046, 0.3850703537, - 0.4252934456, 0.4547857642, 0.4690473080, 0.4873242378, - 0.6001012027, 0.5882627368 }, - { -0.0562759638, -0.0246374905, 0.0070009828, 0.0971394777, - 0.1232394874, 0.1278779507, 0.1302317977, 0.1462241113, - 0.2073549032, 0.2446010709 } }, - { { 1.1749244928, 1.1155937016, 0.9236167073, 0.6288319826, - 0.6515396833, 0.5391781032, 0.5398011804, 0.4997165501, - 0.4066703618, 0.3998857439 }, - { 0.9403013289, 0.7346166372, 0.1841625869, 0.1319625676, - 0.1395087242, 0.0857856274, 0.0952702463, 0.0860625505, - 0.0829471648, 0.1132010221 } }, - { { 0.9047167003, 0.9840551913, 0.9933321178, 0.9360090196, - 0.9164859354, 0.9213320911, 0.8701705337, 0.8815936148, - 0.8414397538, 0.8188012838 }, - { 0.0961010158, -0.0147374868, 0.0202240646, 0.1002548635, - 0.1407548785, 0.1837472022, 0.1858241260, 0.2064549029, - 0.2228626013, 0.2859318554 } }, - { { 0.4034165144, 0.1918472052, 2.1959402561, 0.4763165414, - 0.6577012241, 0.7036704719, 0.6626858413, 0.7650089562, - 0.7702704966, 0.6543781459 }, - { 0.0940933228, -0.1222529113, 2.3491480052, 0.1385394931, - 0.3052472472, 0.3665857315, 0.3350857198, 0.4722319245, - 0.4313857555, 0.3846549690 } }, - { { 0.8215012848, 0.8613782227, 1.0399936736, 1.4082322717, - 0.4075011313, 0.4091626704, 0.5230473280, 0.6101396680, - 0.7510243356, 0.7237474024 }, - { 0.4810934663, 0.5670088828, 0.9207782447, 1.3007860780, - 0.0453548431, 0.0858548582, 0.1803548932, 0.2790087759, - 0.3974626660, 0.4581780732 } }, - { { 1.5921784937, 1.4987169206, 1.1321398616, 0.8235089779, - 0.6888550818, 0.6621319950, 0.6192089021, 0.6533396840, - 0.7196627855, 0.6549319923 }, - { 1.5911400318, 1.4768399894, 0.9358705580, 0.4674549997, - 0.3522549570, 0.3144549429, 0.2985318601, 0.3559241891, - 0.4061857462, 0.3958703578 } }, - { { 0.7975474298, 0.8712782264, 0.8974474669, 0.3008164763, - 0.5562088788, 0.6655935347, 0.8921166956, 1.0918475389, - 0.9544936419, 0.8554936051 }, - { 0.3769703507, 0.4930703938, 0.6619243026, -0.0382759571, - 0.1766856611, 0.3015780151, 0.5952550471, 0.8903859258, - 0.7395320237, 0.6205935180 } }, - { { 0.2206472158, 2.4467634261, 1.2920629978, 1.0239321291, - 0.9014628530, 0.8552166820, 0.8219859004, 0.9005628526, - 0.7614781857, 0.7763628066 }, - { -0.2722068131, 2.8967635930, 1.3039706945, 0.7695089579, - 0.6132550538, 0.5701242685, 0.5737935007, 0.6533396840, - 0.5422934890, 0.5150857866 } }, -}; - -static const float wmavoice_lsp10_intercoeff_b[32][2][10] = { - { { 0.4881048799, -0.1998192370, -0.3872502148, 0.0109423101, - 0.0406953394, 0.1788437665, 0.1673750877, 0.3409781158, - 0.4061202109, 0.5221177042 }, - { 0.1492218077, -0.1372330189, -0.2683691680, -0.0621950924, - -0.0624572337, -0.0068177581, -0.0076041818, 0.0680235624, - 0.1055752933, 0.1199930608 } }, - { { 0.7934338748, 0.0012430847, 0.4239458144, 0.5521328747, - 0.6497149467, 0.6423749924, 0.7170197070, 0.7169541717, - 0.7778364718, 0.8397018015 }, - { 0.2768190503, -0.0491535664, -0.0325731337, 0.0261465013, - 0.0469867289, 0.0649434030, 0.0781815350, 0.1031504869, - 0.1194687784, 0.2451654971 } }, - { { 0.7212139666, 0.1658677757, 0.0101558864, 0.5636015534, - 1.3175852597, 1.1911676526, 1.1266809106, 0.8230558336, - 0.8604109585, 0.8094900250 }, - { 0.3658815324, 0.0816549063, -0.2092563212, 0.1946377754, - 1.0856558084, 0.9491457641, 0.8461242616, 0.5193652213, - 0.5975488424, 0.5293265879 } }, - { { 0.9507186115, 0.9078585207, 0.8773190677, 0.8677509129, - 0.8024122119, 0.8127667904, 0.8246286809, 0.8779088855, - 0.9454102516, 0.9863698184 }, - { 0.6883807778, 0.6900191605, 0.7059442401, 0.6552854478, - 0.5843107104, 0.5553441048, 0.5887671113, 0.6494528055, - 0.7725936472, 0.7792782485 } }, - { { 0.2399882078, 0.1938513517, 0.4441962242, 0.4475385249, - 0.3055235147, 0.1745184362, 0.1174371839, 0.0679580271, - 0.0782470703, 0.1695377529 }, - { 0.0170370936, 0.0253600776, 0.2072205544, 0.1907711923, - 0.1096384823, 0.0327000320, -0.0134368241, -0.0461389422, - -0.0372916758, -0.0243156850 } }, - { { 0.5457104146, 0.3774812818, 0.5235594809, 0.2994287312, - 0.2394639254, 0.5731041729, 0.9971176088, 1.1646913886, - 0.9028123021, 0.7777709365 }, - { 0.2288472056, 0.1181580722, 0.2074171603, 0.0355180502, - -0.0024924278, 0.2596487999, 0.7474936247, 0.9103488624, - 0.5927647650, 0.4772915542 } }, - { { 0.6541713476, 0.6412608922, 0.7625012100, 0.7826205492, - 0.4839106202, 0.3311478198, 0.4577620327, 0.8572652638, - 0.9442306161, 0.8282986581 }, - { 0.2852075696, 0.2614837885, 0.4221763611, 0.4314823747, - 0.1434547007, 0.0435788929, 0.1397191882, 0.5525916219, - 0.6752081811, 0.5487250388 } }, - { { 0.6742251515, 1.0610800683, 1.0500701368, 0.9570100009, - 0.9325653315, 0.9243078828, 0.9148707986, 0.8317720294, - 0.7696445584, 0.6784849465 }, - { 0.2283884585, 0.9739181101, 0.5336519182, 0.4974764287, - 0.3998288214, 0.3674543798, 0.2719694376, 0.2608939707, - 0.2087934017, 0.1675716937 } }, - { { 0.3736146986, -1.5457833707, 0.9216864705, 0.7959242165, - 0.7358283401, 0.7233110964, 0.7271121442, 0.6852350831, - 0.6891672015, 0.6589554250 }, - { 0.1246460676, -1.7167649865, 0.7037160397, 0.4803061783, - 0.4694928527, 0.4654951990, 0.5208069980, 0.5305717587, - 0.5288023055, 0.5278192759 } }, - { { 1.0116009116, 0.9882703424, 0.8393741250, 0.8889843524, - 0.8934407532, 0.8906227350, 0.9222107530, 0.8973073363, - 0.9257496595, 0.9306648076 }, - { 0.5097970665, -0.0106843412, 0.1419473886, 0.2804890275, - 0.3719763160, 0.3694859743, 0.4640534222, 0.5034401417, - 0.5592106879, 0.6652468145 } }, - { { 0.9718209803, 0.7615181804, 0.2172474563, 0.4920369983, - 0.4310891628, 0.5038333535, 0.4668059051, 0.5339140594, - 0.4453758597, 0.4050061107 }, - { 0.6543679535, 0.1205173433, -0.0050483048, 0.1580035388, - 0.1308719218, 0.1700620353, 0.1740596890, 0.2179683447, - 0.1967349052, 0.1703897119 } }, - { { 0.7663022578, 0.4025157690, 1.3811545074, 1.1642981768, - 1.0709758997, 0.9812580645, 1.0092416406, 0.9089070857, - 0.7776398659, 0.8189926445 }, - { 0.3471384346, 0.0602248609, 1.3968829811, 1.0841484964, - 0.8940305710, 0.7313719392, 0.7345176339, 0.5304406881, - 0.4076275229, 0.4535677731 } }, - { { 0.1300854981, 0.1323136985, 0.7564064264, 0.7335346043, - 0.7924508452, 0.6039057672, 0.6896914840, 0.3694859743, - 0.2825861573, 0.3179096878 }, - { -0.0208423138, -0.0530856848, 0.3449102342, 0.3819376826, - 0.4466865659, 0.2807511687, 0.3842969537, 0.1144880950, - 0.0617321730, 0.0767397583 } }, - { { 0.7559476793, 0.8462553322, 0.6452585459, 1.1308751702, - 1.0606868565, 0.9498666525, 0.7425129414, 0.6221901178, - 0.6574481130, 0.6976212561 }, - { 0.3420922160, 0.4310236275, 0.2800958157, 0.9317133725, - 0.8210897744, 0.6144569516, 0.3227593005, 0.2464762032, - 0.2769501209, 0.3521846533 } }, - { { 0.7609938979, 0.6943444908, 1.1490939856, 0.4350868165, - 0.6101971567, 0.6246149242, 0.7370079756, 0.6522052884, - 0.6966382265, 0.7565374970 }, - { 0.3939306438, 0.3449102342, 0.9874839187, 0.0910919905, - 0.2804234922, 0.2888775468, 0.4060546756, 0.3284608722, - 0.3483836055, 0.4819445610 } }, - { { 0.7828826904, 1.1833034158, 1.9916158915, 0.8667678833, - 0.9218830764, 0.8856420517, 0.9373494089, 0.7415299118, - 0.7450032830, 0.7074515522 }, - { 0.4685098231, 1.1713104546, 1.9853245020, 0.6206828058, - 0.6664264500, 0.6033814847, 0.6089519858, 0.3784643114, - 0.4212588668, 0.3441893458 } }, - { { 0.4671335816, 0.4177199602, 0.0804097354, -0.1836975515, - -0.1802241802, -0.0775958896, -0.0250365734, 0.0884050429, - 0.2136430144, 0.3472039700 }, - { 0.1187478900, 0.1122598946, -0.0381436348, -0.2284581661, - -0.2302276194, -0.1738672554, -0.1350048184, -0.0547896028, - 0.0000634491, 0.0545888245 } }, - { { 0.5545576811, 0.4791920781, 0.8204999566, 0.8462553322, - 0.9212277234, 0.8946203887, 0.9659883380, 0.9137566984, - 0.9225384295, 0.9207034409 }, - { 0.1176993251, -0.0429277122, -0.0330318809, 0.0566859543, - 0.0983008742, 0.1593797803, 0.1732077301, 0.2320584357, - 0.2739354968, 0.3753186166 } }, - { { 0.7157745361, 0.6367389560, -1.2036890686, 0.7107283175, - 0.6885118484, 0.7332724631, 0.7436270416, 0.7113181353, - 0.5935511887, 0.6023984551 }, - { 0.3664058149, 0.3280676603, -1.3082178831, 0.3909815550, - 0.3641776145, 0.3926854730, 0.3898674548, 0.4086760879, - 0.3127979338, 0.3949792087 } }, - { { 1.0267395675, 1.0621941686, 1.0415505469, 0.9971176088, - 0.9764739871, 0.9904330075, 0.9591071308, 0.9338760376, - 0.9026156962, 0.9073997736 }, - { 0.9855833948, 1.0548542142, 0.9787021875, 0.8573307991, - 0.8360973597, 0.8193203211, 0.7386463583, 0.7038471103, - 0.6333966553, 0.6434235573 } }, - { { 0.6235008240, 0.7635497749, 0.8094900250, 0.7227212787, - -0.0610809922, -0.1357912421, -0.2359291911, 0.0800165236, - 0.3972729445, 0.5078965425 }, - { 0.2983146310, 0.4983939230, 0.4145742655, 0.3284608722, - -0.3203386664, -0.3495018780, -0.4734291434, -0.1808139980, - 0.1211071610, 0.2001427412 } }, - { { 0.8925887942, 0.8804647624, 0.6153089106, 0.6760601401, - 0.7887153327, 1.0065546930, 1.0829033256, 1.0347348750, - 0.9800128937, 0.9125770628 }, - { 0.5955827832, 0.6195687056, 0.2924164534, 0.3553958833, - 0.5417127609, 0.8713553548, 0.9977729619, 0.8817754686, - 0.7645328045, 0.6604627371 } }, - { { 1.1581378579, 1.0359145105, 0.7731179297, 0.6839243770, - 0.6839899123, 0.6664264500, 0.6910677254, 0.6579068601, - 0.6779606640, 0.6243527830 }, - { 1.1508634388, 0.8400294781, 0.2358594835, 0.2542749047, - 0.2484422624, 0.2620736063, 0.2676441073, 0.2713796198, - 0.3068997562, 0.3223005533 } }, - { { 0.1376220584, 1.2572927773, 0.8593623936, 0.6218624413, - 0.5128116906, 0.5393534899, 0.4436064065, 0.4334484339, - 0.4494390488, 0.4002220333 }, - { -0.1159995794, 1.2433337569, 0.4805027843, 0.2632532418, - 0.1769432425, 0.1868390739, 0.1555131972, 0.1530228555, - 0.1490252018, 0.1559064090 } }, - { { 0.1817273200, -0.0085216761, 0.0739872754, 0.1808098257, - 0.2770811915, 0.3344901204, 0.4292541742, 0.5404020548, - 0.5780193210, 0.5707449019 }, - { -0.0035409927, -0.0188107193, -0.0057691932, 0.0132360458, - 0.0560961366, 0.0534747243, 0.1002013981, 0.1737320125, - 0.1706518531, 0.1637706459 } }, - { { 0.9648087025, 1.0030813217, 0.9501943290, 0.8381944895, - 0.7545059025, 0.7621735334, 0.7121700943, 0.7328792512, - 0.7534573376, 0.7414643764 }, - { 0.1872322857, -0.0081939995, 0.0663851798, 0.0963348150, - 0.0509188473, 0.0565548837, 0.0471833348, 0.0809340179, - 0.1049199402, 0.1751082540 } }, - { { 0.6792713702, 0.9521603882, 0.5296542645, 0.3657504618, - 0.3905883431, 0.3121425807, 0.2726903260, 0.3156159520, - 0.2859284580, 0.3179096878 }, - { 0.2307477295, 0.3771536052, 0.0743804872, 0.0260154307, - 0.0477731526, 0.0391880274, 0.0228042006, 0.0572757721, - 0.0337485969, 0.0492149293 } }, - { { 0.8649328947, 0.9505875409, 1.0443030298, 1.1704584956, - 1.2709241211, 1.3232212961, 1.2477901578, 1.1513877213, - 1.0346038043, 0.9695272446 }, - { 0.4620873630, 0.5685822368, 0.8975039423, 1.0476453304, - 1.2278674245, 1.2290470600, 1.1962138712, 1.0051129162, - 0.8706344664, 0.7477557659 } }, - { { 0.4188340604, 0.6011532843, 0.4726385474, 0.6389671564, - 0.6753392518, 0.7842589319, 0.6147846282, 0.6708828509, - 0.6406055391, 0.5398777723 }, - { 0.1012499630, 0.2312064767, 0.1773364544, 0.2800302804, - 0.3348177969, 0.4343003929, 0.2822584808, 0.3293128312, - 0.3024433553, 0.2401848137 } }, - { { 0.5049474537, 0.7943513691, 0.9536021650, 0.9407572448, - 0.9823721647, 0.9747045338, 1.0145500004, 0.9629737139, - 0.9526191354, 0.9283710718 }, - { 0.0566204190, 0.0973178446, 0.5812305510, 0.5687133074, - 0.6834000945, 0.6616423726, 0.7611905038, 0.6683925092, - 0.6463071108, 0.6118355393 } }, - { { 0.8969141245, 0.9359731674, 0.8756151497, 0.8419300020, - 0.8353109360, 0.6807131469, 0.3358008265, 0.3386188447, - 0.3524467945, 0.4495045841 }, - { 0.5298508704, 0.4606455863, 0.4934132397, 0.4415748119, - 0.4015327394, 0.2052544951, -0.0329663455, -0.0154684186, - 0.0418094397, 0.1631152928 } }, - { { 0.6345762908, 2.5209445655, 1.0373562872, 0.9166402519, - 0.8865595460, 0.8907538056, 0.8522190452, 0.7290782034, - 0.7385808229, 0.6345107555 }, - { 0.2641707361, 2.5696372986, 0.8539884984, 0.6532538533, - 0.6087553799, 0.5851626694, 0.5276226699, 0.4330552220, - 0.3971418738, 0.3599833548 } }, -}; - -static const float wmavoice_lsp16_intercoeff_a[32][2][16] = { - { { 0.5337238312, 0.4810695648, -0.3766536713, -0.1204767227, - -0.0898437500, -0.0070896149, 0.1134738922, 0.1337728500, - 0.3739156723, 0.3849058151, 0.4220180511, 0.5404901505, - 0.5224876404, 0.5502910614, 0.5313453674, 0.4405946732 }, - { 0.1775283813, 0.1679325104, -0.2702789307, -0.1359367371, - -0.1452455521, -0.0888595581, -0.0256662369, -0.0023736954, - 0.1074047089, 0.1431636810, 0.1357412338, 0.2045526505, - 0.2686481476, 0.3404531479, 0.3209333420, 0.1493968964 } }, - { { 0.7402400970, 0.0838251114, 0.6486282349, 0.6145095825, - 0.7331047058, 0.7183008194, 0.7436847687, 0.7627944946, - 0.7653779984, 0.7795667648, 0.8399305344, 0.8393154144, - 0.8219690323, 0.7474164963, 0.6681070328, 0.6490793228 }, - { 0.2850513458, -0.0544128418, -0.0300130844, 0.0204677582, - 0.0328931808, 0.0589332581, 0.0796422958, 0.1187639236, - 0.1320505142, 0.1539077759, 0.2189874649, 0.2865276337, - 0.2973947525, 0.2614307404, 0.2416648865, 0.2428951263 } }, - { { 0.6129922867, 0.7300701141, 0.2073822021, 0.5005893707, - 0.5713691711, 0.5374965668, 0.6293134689, 0.5639057159, - 0.7402811050, 0.6982889175, 0.4668397903, 0.6698703766, - 0.8758535385, 0.8678569794, 0.8678569794, 0.7810840607 }, - { 0.2986249924, 0.3269615173, 0.0096416473, 0.1800708771, - 0.2474060059, 0.2203407288, 0.3007984161, 0.2674179077, - 0.4424810410, 0.4046306610, 0.2063980103, 0.4230022430, - 0.6222190857, 0.6574449539, 0.6776618958, 0.6604385376 } }, - { { 0.7258052826, 0.5073966980, -0.3947381973, 0.5254812241, - 1.0561246872, 0.9706230164, 0.9727144241, 0.9185838699, - 0.8184833527, 0.9093980789, 0.8645353317, 0.7870302200, - 0.6347675323, 0.5123996735, 0.2846002579, 0.3252801895 }, - { 0.4306297302, 0.2182903290, -0.4902458191, 0.1783485413, - 0.7783365250, 0.7152252197, 0.7404451370, 0.6012639999, - 0.5421304703, 0.6619558334, 0.6316919327, 0.5596818924, - 0.3952398300, 0.3567333221, 0.1505041122, 0.1290159225 } }, - { { 0.3077287674, 0.2543363571, 0.2834520340, 0.5282287598, - 0.5350360870, 0.4943971634, 0.4521999359, 0.3086309433, - 0.2372770309, 0.0819387436, -0.1385612488, -0.0848407745, - -0.0380916595, 0.1192150116, 0.3228197098, 0.3012905121 }, - { 0.0567188263, 0.0196886063, 0.0682420731, 0.2102527618, - 0.2452325821, 0.2060699463, 0.1620273590, 0.0784120560, - 0.0418329239, -0.0508041382, -0.2193880081, -0.1644783020, - -0.1361827850, -0.0307512283, 0.1486587524, 0.2356367111 } }, - { { 0.4387903214, 0.5723943710, 0.6147556305, 0.9973602295, - 1.1645498276, 1.1898927689, 1.0326681137, 0.6939010620, - 0.6064310074, 0.4686441422, 0.4646663666, 0.4895582199, - 0.5654230118, 0.6004848480, 0.6179132462, 0.6439123154 }, - { 0.1324195862, 0.2426080704, 0.3132238388, 0.7359752655, - 0.9749288559, 0.9535636902, 0.8105278015, 0.4118890762, - 0.3013315201, 0.2006158829, 0.2331352234, 0.2535161972, - 0.3375005722, 0.4103307724, 0.4102897644, 0.4529380798 } }, - { { 0.7335557938, 0.9203472137, 0.4852113724, 0.8646993637, - 0.7304391861, 0.7503690720, 0.6289854050, 0.6900463104, - 0.6421079636, 0.5184278488, 0.4444904327, 0.2660236359, - 0.2143125534, 0.2406396866, 0.4836940765, 0.5597229004 }, - { 0.3689947128, 0.4967346191, 0.1176567078, 0.5127687454, - 0.3235168457, 0.3426265717, 0.2417469025, 0.3310623169, - 0.2629890442, 0.2130823135, 0.1329116821, 0.0468769073, - -0.0081968307, 0.0146446228, 0.2440433502, 0.3408632278 } }, - { { 0.9425325394, 0.9597969055, 0.6160678864, 0.7050962448, - 0.8063859940, 0.9063224792, 0.9890356064, 1.0038805008, - 1.0338163376, 0.9453620911, 0.9634056091, 0.8068370819, - 0.6859455109, 0.8909034729, 0.9990415573, 1.0122871399 }, - { 0.6895952225, 0.6451835632, 0.3169965744, 0.4268569946, - 0.5666122437, 0.7722673416, 0.8845882416, 0.9061584473, - 0.9550399780, 0.8118810654, 0.8601064682, 0.6129922867, - 0.5069866180, 0.7065315247, 0.7862920761, 0.7766551971 } }, - { { 0.5641517639, -0.0941905975, 0.0412998199, 0.1810550690, - 0.3459482193, 0.4213209152, 0.4401025772, 0.5397109985, - 0.5607891083, 0.6348905563, 0.6861915588, 0.7280607224, - 0.7267074585, 0.6447324753, 0.5948257446, 0.5475025177 }, - { 0.1906919479, -0.0519113541, -0.0608100891, -0.0018815994, - 0.0383062363, 0.0362558365, 0.0529870987, 0.0692672729, - 0.0953073502, 0.1327886581, 0.1390628815, 0.1904459000, - 0.2362518311, 0.2063980103, 0.2311668396, 0.2291574478 } }, - { { 0.9901428223, 0.9589767456, 0.9012374878, 0.8017930984, - 0.8929538727, 0.8512077332, 0.8790111542, 0.8832759857, - 0.8949632645, 0.9159183502, 0.9293279648, 0.9152622223, - 0.9247350693, 0.8753614426, 0.8730239868, 0.8066730499 }, - { 0.4230432510, -0.0464572906, 0.0182533264, 0.1159753799, - 0.2349395752, 0.2740612030, 0.2987070084, 0.3620643616, - 0.3923282623, 0.4694643021, 0.5202322006, 0.5356512070, - 0.5564012527, 0.5362663269, 0.4791831970, 0.5046901703 } }, - { { 0.9785375595, 0.8820457458, 0.3965110779, 0.4790191650, - 0.3907699585, 0.4195575714, 0.2938270569, 0.4091415405, - 0.3659191132, 0.4030723572, 0.4168510437, 0.5030908585, - 0.5023117065, 0.5511522293, 0.5354051590, 0.5563192368 }, - { 0.6592903137, 0.2933759689, 0.0562677383, 0.1286878586, - 0.0758285522, 0.1192560196, 0.0508956909, 0.1175336838, - 0.0684061050, 0.0988750458, 0.0923957825, 0.1819572449, - 0.1965150833, 0.2257537842, 0.3049812317, 0.2993221283 } }, - { { 0.7120265961, 0.7847747803, 0.6065950394, 0.7235908508, - 0.6740531921, 0.6535081863, 0.3734235764, 0.4788551331, - 0.4410867691, 0.6927528381, 1.0758495331, 1.1148891449, - 1.0708875656, 0.8896322250, 0.6401805878, 0.5057153702 }, - { 0.4210338593, 0.4763126373, 0.3229017258, 0.4079113007, - 0.3922462463, 0.3529195786, 0.1258993149, 0.2168960571, - 0.2207508087, 0.4605655670, 0.8759355545, 0.9526205063, - 0.8843832016, 0.7001342773, 0.4503545761, 0.3484086990 } }, - { { 0.5254402161, 0.5349540710, 0.7036199570, 0.6240234375, - 0.6464548111, 0.7537727356, 0.8311548233, 0.7334327698, - 0.3484907150, 0.1846637726, 0.0894021988, 0.3977823257, - 0.7672233582, 0.9224796295, 0.8818407059, 0.7453250885 }, - { 0.2587652206, 0.2524499893, 0.4135704041, 0.3129367828, - 0.3403711319, 0.4473199844, 0.5330266953, 0.4227561951, - 0.1080198288, -0.0044651031, -0.0727024078, 0.1583776474, - 0.5302381516, 0.7313823700, 0.6735610962, 0.5630855560 } }, - { { 0.7936325073, 0.8551034927, 0.9755849838, 0.8953323364, - 0.9345769882, 0.7202281952, 0.8388233185, 0.7941656113, - 0.7550849915, 0.7894906998, 0.8590402603, 0.7813711166, - 0.8483371735, 0.8652324677, 0.8586711884, 0.9584846497 }, - { 0.4781579971, 0.4731960297, 0.8289403915, 0.6175031662, - 0.7262973785, 0.3638277054, 0.5544328690, 0.4761896133, - 0.4388723373, 0.5021476746, 0.5630445480, 0.4562187195, - 0.5190429688, 0.5937595367, 0.6121721268, 0.6973457336 } }, - { { 1.0724458694, 1.0449705124, 0.8594503403, 0.7604160309, - 0.7837905884, 0.8136444092, 0.7623023987, 0.6098756790, - 0.6432561874, 0.6395244598, 0.6853713989, 0.7401580811, - 0.7399530411, 0.7652549744, 0.7675104141, 0.7393789291 }, - { 0.9382266998, 0.8419809341, 0.3087539673, 0.3620233536, - 0.3547649384, 0.4241094589, 0.2857894897, 0.2123851776, - 0.2355957031, 0.2794332504, 0.3219995499, 0.3898267746, - 0.3937635422, 0.4058198929, 0.4228382111, 0.4181222916 } }, - { { 1.0275421143, 1.0940570831, 1.0164289474, 0.9097671509, - 0.9400720596, 0.8976287842, 0.9175586700, 0.8900833130, - 0.9154262543, 0.9492578506, 1.0011329651, 1.0361537933, - 1.0359487534, 0.9320344925, 0.8974237442, 0.8811845779 }, - { 1.0046186447, 1.0860195160, 0.9442958832, 0.7473344803, - 0.7876043320, 0.7410602570, 0.7422084808, 0.6844692230, - 0.7256412506, 0.8455486298, 0.8969316483, 0.9362173080, - 0.9092340469, 0.8227071762, 0.7481546402, 0.7088689804 } }, - { { 0.2205047607, -0.0129537582, 0.0972347260, 0.1154832840, - 0.0951843262, 0.1532516479, 0.1288108826, 0.1749858856, - 0.1591157913, 0.2134923935, 0.2477340698, 0.2634811401, - 0.3032999039, 0.3272485733, 0.3170785904, 0.3172016144 }, - { 0.0032854080, -0.0446119308, 0.0284643173, 0.0155467987, - -0.0063104630, 0.0226001740, 0.0086984634, 0.0262088776, - 0.0173921585, 0.0360507965, 0.0366659164, 0.0215339661, - 0.0412178040, 0.1047391891, 0.1258172989, 0.0609836578 } }, - { { 0.1495609283, 0.3275766373, 0.8598194122, 0.6847562790, - 0.7550849915, 0.5662431717, 0.6930398941, 0.7526245117, - 0.7300291061, 0.7284708023, 0.6608896255, 0.5224056244, - 0.4273900986, 0.5757160187, 0.4625749588, 0.5123586655 }, - { -0.0352210999, -0.0428895950, 0.3110914230, 0.2699604034, - 0.3307752609, 0.2059469223, 0.2332172394, 0.3204412460, - 0.2846412659, 0.3354911804, 0.2448635101, 0.1514062881, - 0.1062564850, 0.2613077164, 0.2123441696, 0.3000602722 } }, - { { 0.6218910217, 0.6033554077, 0.4551525116, 0.3161764145, - 0.2864866257, 0.6195125580, 0.7577505112, 1.0062179565, - 0.8485012054, 0.6777849197, 0.7455301285, 0.3630485535, - 0.2327661514, 0.5563192368, 0.4448595047, 0.3806819916 }, - { 0.2624969482, 0.2679510117, 0.1839666367, 0.0335903168, - 0.0294075012, 0.2902593613, 0.4959144592, 0.7905979156, - 0.5748548508, 0.3753919601, 0.4855394363, 0.1089630127, - 0.0362968445, 0.3632535934, 0.2681150436, 0.2735691071 } }, - { { 0.7064495087, 0.4431781769, 0.7628355026, 0.7271585464, - 0.7812070847, 0.7806739807, 0.8909854889, 0.8958654404, - 0.9126787186, 0.9038209915, 0.9246120453, 0.9624624252, - 0.9732475281, 0.7420034409, 0.5060844421, 0.5189199448 }, - { 0.3457021713, -0.0149221420, 0.3174476624, 0.3580865860, - 0.4243965149, 0.4275541306, 0.5887155533, 0.6478490829, - 0.6320610046, 0.6627349854, 0.6868886948, 0.7396659851, - 0.7551259995, 0.5275316238, 0.3075237274, 0.3806819916 } }, - { { 0.4376831055, 0.4904603958, 0.6262788773, 0.5901098251, - 0.4176712036, 0.0221490860, -0.1612796783, -0.2236118317, - -0.1087894440, -0.0022506714, 0.1051902771, 0.3307752609, - 0.4167690277, 0.4997692108, 0.4645843506, 0.5228567123 }, - { 0.1228237152, 0.1671123505, 0.2931299210, 0.2549924850, - 0.1435737610, -0.1124801636, -0.2181987762, -0.2723293304, - -0.1573429108, -0.0837745667, -0.0325555801, 0.1024427414, - 0.1938495636, 0.2825498581, 0.2247285843, 0.2879629135 } }, - { { 0.6100807190, 0.7900238037, 0.9581155777, 0.8999662399, - 0.9277286530, 0.9720993042, 0.9966220856, 0.9630365372, - 0.9571723938, 0.8992280960, 0.8370189667, 0.7417984009, - 0.7174396515, 0.6122951508, 0.6746683121, 0.7030458450 }, - { 0.0859165192, 0.0914115906, 0.6077432632, 0.5471334457, - 0.5943746567, 0.6805324554, 0.6680250168, 0.6033554077, - 0.6302976608, 0.4874258041, 0.3647298813, 0.2770137787, - 0.2544183731, 0.2608156204, 0.3331537247, 0.4950942993 } }, - { { 0.4051227570, 1.1022176743, 0.8262338638, 0.6573219299, - 0.5948667526, 0.5426225662, 0.4987850189, 0.4370269775, - 0.4421119690, 0.3837165833, 0.3728494644, 0.3706760406, - 0.4169740677, 0.3559951782, 0.2994041443, 0.3896217346 }, - { 0.0716867447, 0.9253911972, 0.2780799866, 0.2460117340, - 0.1675224304, 0.1527595520, 0.1278266907, 0.1226596832, - 0.1165084839, 0.0982189178, 0.0952253342, 0.1113414764, - 0.1498889923, 0.0940361023, 0.0802984238, 0.1560811996 } }, - { { 0.7024717331, 0.7363853455, 0.9629545212, 0.9635286331, - 1.0819597244, 1.1529855728, 1.2984409332, 1.2693252563, - 1.2848672867, 1.2877378464, 1.2133083344, 1.0696573257, - 1.0864706039, 0.9851808548, 0.8312368393, 0.8047866821 }, - { 0.3001422882, 0.2273120880, 0.6279602051, 0.6936140060, - 0.8097076416, 0.9440498352, 1.1028738022, 1.1766471863, - 1.1199741364, 1.1608181000, 1.0665817261, 0.8872537613, - 0.9082908630, 0.7602519989, 0.6542053223, 0.7317514420 } }, - { { 0.0643463135, -0.6808919907, 0.2889881134, 0.6142225266, - 0.6356697083, 0.6825828552, 0.6259508133, 0.4945611954, - 0.5866651535, 0.6357517242, 0.5208883286, 0.4207878113, - 0.5125637054, 0.3758020401, 0.5424175262, 0.6172571182 }, - { -0.0636806488, -0.7585611343, 0.0850553513, 0.2996912003, - 0.3620643616, 0.4444084167, 0.4597454071, 0.3120756149, - 0.4016780853, 0.5026807785, 0.4111919403, 0.3183498383, - 0.3666572571, 0.1829824448, 0.3269205093, 0.4095926285 } }, - { { 0.9277286530, 0.9651279449, 0.9602069855, 0.9327726364, - 0.9208393097, 0.8868436813, 0.9011554718, 0.8569488525, - 0.9015245438, 0.8969726562, 0.9367094040, 0.9445009232, - 0.8617057800, 0.8215589523, 0.8333692551, 0.7939195633 }, - { 0.1719102859, 0.1142530441, 0.1245460510, 0.1646108627, - 0.1408672333, 0.0949792862, 0.0271930695, 0.0265779495, - -0.0064334869, -0.0109033585, 0.0152187347, 0.0252656937, - 0.0166950226, 0.0736141205, 0.1205682755, 0.1895437241 } }, - { { 0.5964250565, 0.6065130234, 0.7228116989, 0.7348270416, - 0.0718097687, 0.2369899750, 0.2456426620, 0.4961194992, - 0.6410417557, 0.6765956879, 0.6771287918, 0.7285938263, - 0.6706905365, 0.5105543137, 0.5068635941, 0.5430326462 }, - { 0.2782440186, 0.2620048523, 0.4424400330, 0.4124631882, - -0.1158838272, 0.0186223984, 0.0059919357, 0.1853609085, - 0.3568563461, 0.3791646957, 0.4100847244, 0.4654865265, - 0.4614677429, 0.3209743500, 0.3199081421, 0.3836755753 } }, - { { 0.8051557541, 0.8506336212, 0.9544658661, 0.5584516525, - 0.5874032974, 0.5727224350, 0.6177902222, 0.7659521103, - 0.9526205063, 1.0424280167, 1.0705595016, 1.0042905807, - 0.6005258560, 0.3886785507, 0.4739751816, 0.6542463303 }, - { 0.4775428772, 0.5541868210, 0.7128057480, 0.2146816254, - 0.2502765656, 0.2488822937, 0.3009214401, 0.4667987823, - 0.6929988861, 0.8599834442, 0.8784780502, 0.7463912964, - 0.3217535019, 0.1274986267, 0.2767267227, 0.5119485855 } }, - { { 0.5978193283, 0.5092830658, 1.0738401413, 0.7688636780, - 0.8214769363, 0.7682075500, 0.4970626831, 0.2783260345, - 0.2652854919, 0.3625154495, 0.5700569153, 0.5044031143, - 0.4003248215, 0.5162544250, 0.5727634430, 0.5538587570 }, - { 0.2752094269, 0.1747808456, 0.8557186127, 0.4280872345, - 0.5143680573, 0.4139804840, 0.1810960770, 0.0109539032, - 0.0317039490, 0.0842351913, 0.3129367828, 0.2614717484, - 0.1564092636, 0.2352676392, 0.3249931335, 0.3505821228 } }, - { { 0.7093610764, 0.7587757111, 1.8517618179, 1.0092525482, - 0.8078622818, 0.8792982101, 0.8210668564, 0.8600654602, - 0.6913585663, 0.6436662674, 0.6216859818, 0.6123771667, - 0.5940465927, 0.5910940170, 0.6505966187, 0.5801038742 }, - { 0.3370904922, 0.4681930542, 1.9236078262, 0.8053607941, - 0.5321245193, 0.6342344284, 0.5054693222, 0.5788326263, - 0.4400615692, 0.4086904526, 0.3924102783, 0.4220180511, - 0.3835115433, 0.4230432510, 0.5190839767, 0.3990535736 } }, - { { 0.6277141571, 1.1122236252, 1.0259838104, 0.9486427307, - 0.9184608459, 0.9059944153, 0.9080038071, 0.8282022476, - 0.8440313339, 0.7887935638, 0.7468013763, 0.6746683121, - 0.6319379807, 0.6246795654, 0.7263793945, 0.7349090576 }, - { 0.2427721024, 1.0851583481, 0.6180362701, 0.5837125778, - 0.4324750900, 0.4684801102, 0.3745307922, 0.3027257919, - 0.3646888733, 0.2409267426, 0.2158298492, 0.2052907944, - 0.2100887299, 0.2276401520, 0.3409452438, 0.4045896530 } }, - { { 0.8391513824, 0.8713426590, 1.1366233826, 1.1440868378, - 1.1443738937, 1.0877418518, 1.0516138077, 1.0099496841, - 0.9216184616, 0.8990640640, 0.9001302719, 0.8993101120, - 0.8055248260, 0.8150796890, 0.7272815704, 0.7196130753 }, - { 0.4634771347, 0.5807189941, 1.1287908554, 1.1066875458, - 1.0765056610, 0.9287538528, 0.8956193924, 0.8026132584, - 0.6725769043, 0.5856809616, 0.5527515411, 0.5183868408, - 0.4529380798, 0.5074377060, 0.4632720947, 0.5554990768 } }, -}; - -static const float wmavoice_lsp16_intercoeff_b[32][2][16] = { - { { 0.5431776047, -0.1212130189, -0.2471650839, 0.0683670044, - 0.1418520808, 0.2518971562, 0.3708084226, 0.4141484499, - 0.5712364912, 0.5852659345, 0.5670641661, 0.6401320100, - 0.6447737217, 0.6726239920, 0.4994724989, 0.5574678183 }, - { 0.2040718794, -0.1271064281, -0.2266163826, -0.0406349897, - -0.0145058036, 0.0283126831, 0.0851084590, 0.0913147926, - 0.1307432652, 0.1926501393, 0.2310355306, 0.2828245163, - 0.3171940446, 0.4424681067, 0.2960716486, 0.3510941863 } }, - { { 0.8073900938, 0.0403081179, 0.5392660499, 0.6928597689, - 0.6499369740, 0.7328097820, 0.7755761147, 0.7766191959, - 0.8820225596, 0.8423333168, 0.8898978233, 0.8488525748, - 0.8654375672, 0.6728326082, 0.6169234514, 0.6755967736 }, - { 0.3653843999, -0.0846008658, -0.0224332213, 0.1120721102, - 0.1020585299, 0.1741876006, 0.2129902244, 0.2160151601, - 0.3619422317, 0.4185815454, 0.5455245376, 0.5363975763, - 0.5429168344, 0.3505726457, 0.3296067119, 0.3620986938 } }, - { { 0.1843576431, 0.0179861784, 0.3122915626, 0.3600125313, - 0.2466817498, 0.2172668576, 0.1975526214, 0.1177569032, - 0.1196866035, 0.0849519968, 0.0962694287, 0.1591672301, - 0.2300446033, 0.3082756996, 0.4047607183, 0.3925045133 }, - { -0.0275964737, -0.0794897676, 0.1168181300, 0.1591150761, - 0.0915755630, 0.0460972190, 0.0562151074, 0.0084419847, - -0.0095511675, -0.0408957601, -0.0376100540, -0.0166962743, - 0.0656028390, 0.1226072311, 0.2293144464, 0.2142419219 } }, - { { 0.4781936407, -1.2478972673, 0.4884679914, 0.7755239606, - 0.6785174012, 0.6590117812, 0.6177057624, 0.6427918673, - 0.5402048230, 0.5512614846, 0.6424267888, 0.4229103327, - 0.5106334686, 0.5136062503, 0.4490395188, 0.4753251672 }, - { 0.2852236032, -1.3815159798, 0.1904075146, 0.4874770641, - 0.4593138695, 0.4182686210, 0.4174863100, 0.4604612589, - 0.4089330435, 0.3891666532, 0.4700576067, 0.2383370996, - 0.2801646590, 0.3398289084, 0.2766703367, 0.3374298215 } }, - { { 0.5925153494, 0.3858809471, 1.0754098296, 0.5752002001, - 0.5516265631, 0.4853909016, 0.4719351530, 0.5018194318, - 0.3037382960, 0.5154316425, 0.8809794784, 0.7755761147, - 0.5941321254, 0.3974069953, 0.5925675035, 0.6097261906 }, - { 0.3008176684, 0.0706617832, 0.8484353423, 0.2574254870, - 0.2815728188, 0.1930673718, 0.2523665428, 0.2691601515, - 0.1271967888, 0.2653007507, 0.6473292708, 0.5275835395, - 0.3928174376, 0.2405275702, 0.4008491635, 0.4556109309 } }, - { { 0.7339050174, 0.4290645123, 0.6859754324, 0.6349166036, - 0.8034263849, 0.8509387374, 0.8591269255, 1.1049811840, - 1.3928194642, 1.3423343301, 1.0849018693, 0.8943830729, - 0.8579795361, 0.6920774579, 0.5613272190, 0.4303162098 }, - { 0.4534726143, 0.0901674032, 0.3465046287, 0.3470261693, - 0.5217422843, 0.5874564052, 0.6014336944, 0.9161834717, - 1.2823571563, 1.2193550467, 0.8868207335, 0.6514494419, - 0.6249030232, 0.4453887343, 0.3665317893, 0.2242033482 } }, - { { 0.4293252826, 0.3303368688, 0.6181751490, 0.9884168506, - 0.9915460944, 0.7939864993, 0.3019129038, 0.2443348169, - 0.4543070793, 0.5617444515, 0.4895110726, 0.6600027084, - 0.6290231943, 0.5580936670, 0.5459417701, 0.4647378922 }, - { 0.1409133077, -0.0050137639, 0.2551307082, 0.6764833927, - 0.7112701535, 0.4648943543, 0.0301380754, -0.0235806108, - 0.1018499136, 0.2422486544, 0.2406318784, 0.4000146985, - 0.3713299632, 0.3259559274, 0.3820737004, 0.2888743877 } }, - { { 0.7733334899, 0.8321111202, 1.3098945022, 1.0331128836, - 1.0380675197, 0.9479974508, 0.9740223289, 0.9442945123, - 0.8926619887, 0.8719046712, 0.8640815616, 0.8404036164, - 0.8359183669, 0.7675965428, 0.6895219088, 0.7266034484 }, - { 0.3655408621, 0.4643206596, 1.2171645761, 0.8341451287, - 0.8387868404, 0.6713201404, 0.6814901829, 0.6294404268, - 0.5172048807, 0.5205948949, 0.5408828259, 0.5298783183, - 0.5781729817, 0.5000983477, 0.4727174640, 0.4326109886 } }, - { { 0.8902629018, 0.4598354101, 0.6392975450, 0.4483093619, - 0.6220867038, 0.6323089004, 0.7063676715, 0.3717993498, - 0.6718416810, 0.7876758575, 0.2807383537, 0.3118221760, - 0.6703813672, 0.7662405372, 0.7122610807, 0.7851724625 }, - { 0.6301705837, 0.1221378446, 0.3532846570, 0.1412783861, - 0.3471826315, 0.3435318470, 0.4466925859, 0.1390357614, - 0.4092981219, 0.5406742096, 0.0690450072, 0.0829179883, - 0.4625995755, 0.5700891018, 0.5542864203, 0.6545265317 } }, - { { -0.1100520492, 0.3803526163, 0.8075987101, 0.6903563738, - 0.8012359142, 0.7835035324, 0.8195941448, 0.8381088376, - 0.8033220768, 0.7511680126, 0.6393496990, 0.6096218824, - 0.6934856176, 0.6690253615, 0.6401841640, 0.5600233674 }, - { -0.1776958704, -0.0293175578, 0.1520742774, 0.1746048331, - 0.2222214937, 0.3052507639, 0.2977927327, 0.3797789216, - 0.3395681381, 0.2976884246, 0.2516885400, 0.2403711081, - 0.3567789793, 0.3302847147, 0.3368039727, 0.3310148716 } }, - { { 0.5587195158, 0.4676063657, 0.1392965317, -0.0990996957, - -0.0816280842, -0.1146416068, -0.0116894841, 0.0521992445, - 0.1626615524, 0.2923687100, 0.4029874802, 0.4528989196, - 0.4694839120, 0.5058352947, 0.5369191170, 0.5105291605 }, - { 0.2193530202, 0.1211469173, 0.0179861784, -0.2022604346, - -0.1409794092, -0.2121175528, -0.1152674556, -0.0594626069, - -0.0122110248, 0.0274260640, 0.1414870024, 0.2044369578, - 0.2167974710, 0.2615978122, 0.3348221183, 0.3707562685 } }, - { { 0.5948622823, 0.7065241337, 0.9414781928, 0.9340723157, - 0.8835350275, 0.9730835557, 0.8503650427, 0.8902629018, - 0.8746688366, 0.6910865307, 0.6404449344, 0.6976057887, - 0.5916287303, 0.6022160053, 0.7729684114, 0.6096740365 }, - { 0.1262058616, 0.1300652623, 0.6594290137, 0.6535877585, - 0.5639349222, 0.6982316375, 0.4828875065, 0.5577285886, - 0.4591052532, 0.2964367270, 0.2695252299, 0.3324751854, - 0.2860580683, 0.2902825475, 0.4623388052, 0.3369604349 } }, - { { 0.8821268678, 0.8539636731, 0.2898653150, 0.7478301525, - 0.5109463930, 0.8577187657, 0.4884679914, 0.7846509218, - 0.7684310079, 0.7032384276, 0.6691296697, 0.8593355417, - 0.9383489490, 0.9808023572, 0.6804992557, 0.6403927803 }, - { 0.5590324402, 0.4209806323, 0.0259135962, 0.4318808317, - 0.2104346752, 0.5453680754, 0.1783599257, 0.4467447400, - 0.4352708459, 0.4089330435, 0.3994410038, 0.5984609127, - 0.6872792840, 0.7321317792, 0.4408513308, 0.4542027712 } }, - { { 0.6371070743, 0.6311093569, 0.7152860165, 0.6929640770, - 0.2292101383, 0.3234525323, 0.9644259810, 0.9881039262, - 0.8722697496, 0.4370440841, 0.4051779509, 0.4944135547, - 0.5392660499, 0.5969484448, 0.4268740416, 0.4990552664 }, - { 0.4233797193, 0.3647063971, 0.4345406890, 0.4180078506, - -0.0006328225, 0.0586141944, 0.7620160580, 0.8152132034, - 0.6707985997, 0.2095480561, 0.2178405523, 0.2776612639, - 0.3142212629, 0.3808741570, 0.2676998377, 0.2804775834 } }, - { { 0.4509170651, 0.9490405321, 0.8557890654, 0.8271043301, - 0.6915559173, 0.7321839333, 0.6257896423, 0.6274064183, - 0.5238284469, 0.5194996595, 0.4116972089, 0.3382642865, - 0.3755022883, 0.4867990613, 0.5686287880, 0.5106856227 }, - { 0.0989292860, 0.6244857907, 0.4700576067, 0.3905226588, - 0.2630059719, 0.3009741306, 0.2150763869, 0.2067838907, - 0.1533781290, 0.1815934777, 0.1023714542, 0.0373874903, - 0.0897501707, 0.1849313378, 0.2852757573, 0.2625887394 } }, - { { 0.9954054952, 0.9554033279, 0.8237664700, 0.9780903459, - 0.7261862159, 0.7884581685, 0.7933084965, 0.7393290401, - 0.8783196211, 1.0409359932, 1.0217954516, 0.9159227014, - 0.8698185086, 0.7057939768, 0.7662926912, 0.7339571714 }, - { 0.7913266420, 0.6739278436, 0.5061482191, 0.7058982849, - 0.3480692506, 0.4338105321, 0.4428853393, 0.3758152127, - 0.5962182879, 0.7925261855, 0.7968549728, 0.6629754901, - 0.6325175166, 0.4598354101, 0.5310778618, 0.5518873334 } }, - { { 0.4638512731, 0.0604917407, 0.1897295117, 0.3403504491, - 0.4708399177, 0.5241413713, 0.6061275601, 0.6446694136, - 0.7313494682, 0.7208143473, 0.6268848777, 0.6081094146, - 0.4913364649, 0.3529717326, 0.4954566360, 0.5767126679 }, - { 0.1353849769, -0.0274400115, 0.0002537966, 0.0272174478, - 0.0555371046, 0.0652899146, 0.1010676026, 0.1073260903, - 0.1568724513, 0.2207611799, 0.1434167027, 0.2262373567, - 0.1177047491, 0.0162650943, 0.2529402375, 0.4087765813 } }, - { { 0.9700064659, 0.9917025566, 0.9159227014, 0.9309430718, - 0.8991290927, 0.9314124584, 0.9059612751, 0.9473194480, - 0.9604622722, 0.9377752542, 0.9197821021, 0.8869771957, - 0.8506779671, 0.8594920039, 0.8320589662, 0.8739908338 }, - { 0.2892394662, 0.0551198721, 0.0892807841, 0.1158793569, - 0.0905846357, 0.0738953352, 0.0395258069, 0.0240360498, - 0.0477139950, 0.0751470327, 0.1171310544, 0.1555164456, - 0.1384620667, 0.1818542480, 0.2104868293, 0.1288135648 } }, - { { 0.4101847410, 0.3326316476, 0.4666675925, 0.5077128410, - 0.5892296433, 0.4272912741, 0.0603352785, -0.8668596745, - -1.1103670001, -0.0900248885, 0.1626615524, 0.1487885714, - 0.4130010605, 0.5119373202, 0.5820323825, 0.5486016273 }, - { 0.0383262634, 0.1300652623, 0.2295230627, 0.2706204653, - 0.3722165823, 0.1698066592, -0.0934670568, -0.8677462935, - -1.0724509954, -0.2164463401, -0.0056917667, -0.0301520228, - 0.1299088001, 0.2579991817, 0.3482257128, 0.2469425201 } }, - { { 0.6031547785, 0.5515222549, 0.4292209744, 0.5027582049, - 0.8167778254, 1.0925685167, 0.9878953099, 0.7019345760, - 0.2509583831, 0.2475162148, 0.5660732388, 0.5145971775, - 0.4824181199, 0.5970005989, 0.5996604562, 0.5384315848 }, - { 0.3677313328, 0.2650399804, 0.1585935354, 0.2213348746, - 0.5566333532, 0.8425940871, 0.7604514360, 0.4523773789, - 0.0681062341, 0.0737388730, 0.3169854283, 0.2868403792, - 0.2661873698, 0.3635068536, 0.4300554395, 0.3743027449 } }, - { { 0.5017672777, 0.6634970307, 0.6869142056, 0.7066284418, - 0.5669598579, 0.0621085167, 0.0634645224, 0.2321307659, - 0.8322675824, 0.9855483770, 0.8296598792, 0.6140028238, - 0.5462546945, 0.6730412245, 0.6856103539, 0.5975221395 }, - { 0.2680649161, 0.3324230313, 0.3688787222, 0.3886451125, - 0.2774004936, -0.1695076823, -0.1353467703, 0.0159000158, - 0.5895425677, 0.7586781979, 0.5639870763, 0.3687744141, - 0.3401418328, 0.4477356672, 0.4782979488, 0.4034568667 } }, - { { 0.8838479519, 0.9025712609, 0.7326533198, 0.8124490380, - 0.8956347704, 1.1007045507, 1.2731780410, 1.2029786706, - 1.0839109421, 0.9664078355, 0.7356782556, 0.6942157745, - 0.6917645335, 0.6383587718, 0.6503020525, 0.5989302993 }, - { 0.5576764345, 0.4596789479, 0.3790487647, 0.5514179468, - 0.7333834767, 0.9612445831, 1.1976589561, 1.1094664335, - 0.8868207335, 0.6789346337, 0.4643206596, 0.4029353261, - 0.4384522438, 0.3871847987, 0.4326109886, 0.3691916466 } }, - { { 0.8520861268, 0.8413423896, 0.7238392830, 0.9103943706, - 0.7072542906, 0.6479029655, 0.4557673931, 0.1908247471, - -0.0569070578, -0.1013423204, 0.2517406940, 0.4854952097, - 0.5820845366, 0.5886037946, 0.6177579165, 0.6226603985 }, - { 0.6160889864, 0.4592095613, 0.4752208591, 0.6685559750, - 0.4326109886, 0.4077335000, 0.2314006090, 0.0173603296, - -0.2208272815, -0.3014574647, 0.0321199298, 0.2559130192, - 0.3603254557, 0.3466089368, 0.4072119594, 0.4776199460 } }, - { { 0.7083495259, 0.9001721740, 0.6795083284, 1.2743254304, - 1.3672639728, 1.2563322783, 0.8557369113, 0.8287732601, - 0.7942472696, 0.8006622195, 0.7034991980, 0.5479236245, - 0.6391932368, 0.6248508692, 0.5495925546, 0.4719351530 }, - { 0.4000146985, 0.6493632793, 0.4583229423, 1.1484255195, - 1.2521599531, 1.1232351065, 0.6150459051, 0.5347808003, - 0.4726653099, 0.5269576907, 0.4278128147, 0.2745841742, - 0.3868718743, 0.4183729291, 0.3474434018, 0.3150035739 } }, - { { 0.9070043564, 0.7648323774, 0.4281778932, 0.5475063920, - 0.4134704471, 0.4706834555, 0.4549329281, 0.4648422003, - 0.4572798610, 0.4823138118, 0.4666154385, 0.4841913581, - 0.4018922448, 0.4297946692, 0.4646857381, 0.6091003418 }, - { 0.4925360084, 0.2065231204, 0.0948612690, 0.1716842055, - 0.0992422104, 0.1332988143, 0.1255800128, 0.1257364750, - 0.0955392718, 0.1118634939, 0.1372103691, 0.1525958180, - 0.0902717113, 0.1591672301, 0.2335910797, 0.3767018318 } }, - { { 0.3185500503, 0.8677845001, 0.7776622772, 0.8160476685, - 0.8624126315, 0.8057211637, 0.8852561116, 0.8471314907, - 0.9145145416, 0.8945916891, 0.8638729453, 0.8531292081, - 0.7425104380, 0.6215651631, 0.6501455903, 0.6341864467 }, - { -0.0499705672, 0.0687842369, 0.3051464558, 0.3368039727, - 0.4942049384, 0.3823344707, 0.5683158636, 0.5044271350, - 0.6278236508, 0.5777035952, 0.5745221972, 0.5502184033, - 0.4244228005, 0.3163595796, 0.3525545001, 0.3582914472 } }, - { { 0.3200625181, 0.9415303469, 0.6067534089, 0.3568832874, - 0.1600538492, 0.2938811779, 0.2037589550, 0.3017564416, - 0.2572168708, 0.4796018004, 0.6938506961, 0.6847758889, - 0.7232134342, 0.6111343503, 0.5159531832, 0.4856516719 }, - { 0.0680540800, 0.6285016537, 0.2514277697, 0.0790064335, - -0.0687981844, 0.0521992445, -0.0055874586, 0.0537117124, - 0.0188206434, 0.1883213520, 0.4493002892, 0.4300554395, - 0.4750122428, 0.3658016324, 0.3119786382, 0.2818335891 } }, - { { 0.6864969730, 1.0815640092, 0.9838794470, 0.8845259547, - 0.9438772798, 0.8888025880, 0.8178730607, 0.8581881523, - 0.7128347754, 0.7120524645, 0.7345308661, 0.7945601940, - 0.7854853868, 0.8261655569, 0.6941114664, 0.6646444201 }, - { 0.2847542167, 0.9535257816, 0.6691818237, 0.5026538968, - 0.5945493579, 0.4125838280, 0.3886451125, 0.3740941286, - 0.2453778982, 0.2928902507, 0.3219922185, 0.4065861106, - 0.3838469386, 0.4289602041, 0.3910441995, 0.3821780086 } }, - { { 1.1335094571, 1.0390062928, 0.7019867301, 0.6203134656, - 0.6951545477, 0.4863818288, 0.6171320677, 0.6247465611, - 0.5907421112, 0.6711115241, 0.7322882414, 0.7042293549, - 0.5635698438, 0.6174449921, 0.6727283001, 0.6431047916 }, - { 1.0146503448, 0.7762541175, 0.2200310230, 0.2459515929, - 0.2703596950, 0.1376276016, 0.2522100806, 0.2622758150, - 0.2389107943, 0.2956544161, 0.3799875379, 0.3653843999, - 0.2561216354, 0.2842326760, 0.4034568667, 0.3700782657 } }, - { { 0.6342907548, 0.9627570510, 0.5214815140, -0.0226939917, - 0.5616401434, 0.7231091261, 0.7417802811, 0.9092991352, - 0.9739701748, 0.7804785967, 0.6771092415, 0.6352295280, - 0.4660417438, 0.5869870186, 0.6692339778, 0.5986173749 }, - { 0.3988673091, 0.6997441053, 0.2316613793, -0.2566571236, - 0.2685343027, 0.4484136701, 0.4490395188, 0.6886874437, - 0.7703085542, 0.5847443938, 0.4539941549, 0.4098196626, - 0.2579991817, 0.3376384377, 0.4754816294, 0.5095382333 } }, - { { 0.4443456531, 2.0296727419, 0.6569256186, 0.6439914107, - 0.6436263323, 0.5507399440, 0.6095175743, 0.6066491008, - 0.5347808003, 0.2529402375, 0.4443978071, 0.7000570297, - 0.8259569407, 0.5927761197, 0.5078171492, 0.4418422580 }, - { 0.2430831194, 1.9133691788, 0.3723730445, 0.3764410615, - 0.3874977231, 0.3212099075, 0.3832210898, 0.4474227428, - 0.3644977808, 0.0814055204, 0.2752621770, 0.4647378922, - 0.6619845629, 0.4304205179, 0.3143777251, 0.2705683112 } }, - { { 0.9740744829, 1.0730628967, 0.9743352532, 0.9098728299, - 0.9453375936, 0.9661470652, 0.9270836711, 0.9643738270, - 0.9989519715, 0.9627048969, 0.9348546267, 0.9865393043, - 0.9399657249, 0.9752218723, 0.8440544009, 0.8819182515 }, - { 0.9258319736, 1.0357205868, 0.8463491797, 0.8108844161, - 0.8391519189, 0.8566235304, 0.8305986524, 0.8880724311, - 0.9181653261, 0.8670021892, 0.8305986524, 0.8995984793, - 0.8300249577, 0.8711223602, 0.7195626497, 0.8138571978 } }, -}; - -static const double wmavoice_mean_lsf10[2][10] = { - { 0.2235394066, 0.4097484909, 0.7025292732, 1.1077160169, - 1.3939179044, 1.6741291716, 1.9552949226, 2.2199793918, - 2.5103400247, 2.7829212906 }, - { 0.1493683393, 0.3714357373, 0.7702730245, 1.0609411394, - 1.3270362536, 1.5806033119, 1.8398507524, 2.1116740248, - 2.3823505771, 2.6865718527 } -}; - -static const double wmavoice_mean_lsf16[2][16] = { - { 0.0999206754, 0.2345933590, 0.4621011210, 0.6772546160, - 0.8346396060, 1.0067495130, 1.1571691668, 1.3292508688, - 1.4941465650, 1.6600755584, 1.8461284908, 2.0529487333, - 2.2690810112, 2.4949894820, 2.7172752965, 2.9164840903 }, - { 0.0918298402, 0.2475621892, 0.4782937721, 0.6284774045, - 0.7861951264, 0.9303736000, 1.0940441024, 1.2521029300, - 1.4434732098, 1.6551410742, 1.8917962963, 2.0967280403, - 2.2981430375, 2.4826173497, 2.6827972461, 2.8811350800 } -}; - -static const float wmavoice_std_codebook[1000] = { - -0.185013, -0.150405, -0.707267, -0.284100, 0.882898, - -0.788627, 0.061005, 0.374431, 0.053843, -0.909826, - 0.543602, 0.219326, 0.285698, 0.154709, -0.455005, - 0.426276, -0.868852, -0.952324, -0.550001, 0.813814, - -0.352815, 0.242122, 0.820495, -0.189574, -0.449538, - 0.499132, -0.247783, 0.598159, 0.732040, -0.564406, - -0.631788, -0.452973, 0.285189, -0.339055, 0.262927, - 0.168087, -0.127682, -0.676067, -0.457481, 0.926161, - -0.585893, -0.913880, 0.145487, 0.699804, 0.240829, - 0.690482, 0.126081, 0.371977, 0.738158, 0.576080, - 0.185791, -0.614657, -0.181799, 0.006285, 0.195768, - 0.368663, -0.494583, 0.947985, -0.033178, -0.762543, - -0.616421, 0.335034, -0.215516, 0.668769, 0.995979, - -0.952588, -0.163144, -0.131704, -0.628655, 0.379374, - -0.205543, -0.214549, 0.465494, 0.939944, -0.514744, - -0.293676, 0.630426, 0.611336, -0.921699, 0.368584, - 0.187416, 0.264092, 0.753927, -0.994382, -0.729623, - -0.050304, 0.374280, -0.224205, -0.102319, -0.658897, - 0.013252, 0.281260, 0.676137, 0.797736, -0.049971, - 0.672115, 0.845148, 0.786885, -0.459588, -0.783507, - 0.166259, 0.334869, 0.001944, -0.368247, 0.274813, - 0.487200, 0.338077, -0.094761, 0.098536, 0.416378, - -0.726176, -0.714048, -0.319530, -0.972249, -0.708430, - -0.049153, -0.022553, 0.665850, 0.726642, 0.875127, - -0.993047, -0.260106, 0.156387, 0.683090, -0.462370, - -0.893584, 0.355205, -0.617222, 0.893301, 0.895617, - -0.400729, 0.059559, 0.230486, 0.601215, 0.691313, - -0.494701, 0.088415, 0.029390, 0.410539, -0.813049, - -0.554232, 0.684362, -0.527097, 0.126238, 0.712113, - -0.235528, -0.922915, -0.310440, -0.569678, 0.803727, - -0.435313, -0.562725, -0.456380, 0.721075, -0.879635, - 0.081250, 0.827491, 0.475570, 0.464029, 0.720792, - 0.371187, -0.936700, -0.219649, -0.398327, 0.664515, - -0.528336, 0.106972, -0.247070, 0.501053, -0.482490, - -0.060119, 0.946821, -0.798127, 0.412784, 0.073058, - 0.913986, -0.822744, 0.150143, -0.396453, -0.392421, - -0.046130, 0.168234, 0.044854, 0.497490, -0.110691, - 0.165219, -0.421259, -0.283200, -0.359212, -0.957231, - -0.562409, -0.988025, -0.893931, 0.217942, -0.386352, - 0.770585, 0.689606, 0.720620, -0.476485, 0.190659, - -0.761870, 0.463395, 0.137480, -0.559997, -0.123821, - -0.789461, -0.646011, 0.053435, 0.360682, -0.042464, - 0.661014, -0.685448, -0.874230, -0.294133, 0.812042, - 0.015078, 0.871086, -0.609218, 0.731878, -0.488126, - -0.566448, -0.830530, -0.476150, -0.460379, 0.387412, - 0.137497, -0.689794, 0.077018, -0.141883, -0.166280, - -0.732322, 0.096247, -0.702884, 0.405158, 0.536250, - 0.173295, 0.615696, 0.890239, -0.773270, -0.023622, - -0.152226, 0.887744, 0.290930, -0.026456, -0.406389, - 0.102972, 0.988622, -0.535303, 0.493754, 0.720500, - -0.023428, 0.927306, 0.889970, 0.500421, -0.533073, - 0.277382, -0.362081, -0.222867, -0.645599, 0.496035, - 0.610853, -0.377922, -0.407718, 0.907969, -0.972764, - -0.871468, 0.081264, 0.642933, -0.981230, 0.307994, - -0.380689, -0.133456, 0.195738, 0.910241, 0.840088, - 0.789349, 0.013213, 0.828710, -0.745954, -0.493033, - 0.549210, 0.230618, -0.565727, 0.439180, -0.268961, - -0.098800, -0.283438, 0.368958, 0.678333, 0.070963, - -0.135007, 0.289186, 0.693041, 0.457275, 0.197155, - 0.720277, 0.585807, -0.721581, 0.363210, 0.604577, - 0.586413, 0.982521, -0.528878, -0.217849, 0.892762, - -0.688791, -0.428500, -0.094025, -0.860081, -0.174454, - 0.412942, 0.689129, -0.943836, 0.847215, 0.128309, - -0.212797, -0.251585, 0.844871, -0.843839, -0.573252, - -0.084167, 0.021154, 0.715935, -0.391126, -0.521570, - -0.086910, -0.670848, -0.935763, 0.191509, 0.692361, - 0.668814, -0.222078, 0.674882, -0.860064, 0.560073, - 0.567644, -0.548855, -0.868427, -0.526382, -0.408936, - -0.042881, 0.886560, -0.719807, 0.013283, 0.733775, - 0.408502, 0.800487, -0.517810, 0.253372, 0.956648, - -0.091062, -0.830794, -0.022198, -0.375127, -0.221920, - 0.456232, 0.537963, 0.107232, 0.520469, -0.270529, - -0.200406, 0.189284, 0.507393, -0.525524, 0.329220, - 0.067466, -0.957881, 0.780365, 0.199039, -0.484262, - -0.628570, -0.843843, -0.597703, -0.348377, 0.169441, - -0.863928, -0.939875, -0.030073, -0.381738, 0.313497, - -0.073425, 0.527200, 0.482703, 0.904377, -0.847927, - -0.739217, 0.360609, 0.690035, 0.368015, -0.118921, - -0.580493, -0.832391, -0.929638, 0.926900, -0.357915, - 0.399582, -0.005634, -0.315796, 0.179947, -0.806596, - 0.393360, 0.732931, -0.415833, -0.724526, 0.957347, - -0.892887, 0.475366, 0.173583, -0.418554, -0.302536, - 0.627315, 0.782000, 0.497542, 0.139082, 0.570111, - 0.732375, -0.454643, 0.302218, -0.019505, 0.881778, - -0.057606, 0.273041, 0.414170, -0.503501, -0.079602, - -0.083941, 0.007178, -0.171925, 0.506856, 0.520953, - 0.631684, -0.099784, 0.253885, -0.784149, 0.175691, - 0.211231, -0.677036, -0.348943, -0.615186, -0.095591, - 0.348521, -0.987871, -0.313590, -0.153938, 0.151210, - -0.743479, -0.421562, 0.696567, 0.558739, 0.558933, - 0.578346, -0.498867, -0.168026, -0.007485, -0.002368, - 0.752372, 0.908575, -0.995190, -0.419553, 0.415430, - 0.525763, -0.787869, -0.684353, -0.220353, -0.572018, - 0.491337, 0.990879, -0.249054, -0.857606, -0.624307, - 0.655355, 0.490915, -0.612178, -0.658235, -0.663023, - 0.539032, -0.401714, -0.084585, 0.235599, -0.842975, - -0.525653, -0.186055, -0.341841, 0.306321, 0.806460, - 0.655791, 0.058693, 0.715035, 0.660601, 0.639140, - 0.130465, 0.186363, 0.851271, 0.446112, 0.966011, - -0.720746, -0.062551, 0.956890, 0.030200, 0.079843, - -0.667418, -0.314445, -0.429243, -0.279596, 0.027320, - -0.092266, -0.740564, 0.625606, 0.823149, 0.495035, - 0.782632, -0.702504, -0.691020, -0.559209, 0.603818, - -0.884560, -0.903419, -0.337489, 0.830475, 0.757182, - -0.698349, -0.039060, -0.056455, -0.847078, -0.592948, - -0.090444, -0.567824, 0.344501, -0.133554, 0.462375, - -0.575656, 0.199028, -0.852070, -0.004899, 0.919432, - 0.175251, 0.902835, -0.821132, -0.199143, 0.725984, - 0.673903, -0.416511, -0.976519, 0.982883, 0.024279, - 0.627298, -0.901677, 0.120861, -0.710191, 0.928798, - -0.121958, -0.408540, -0.110261, 0.821588, -0.255618, - 0.296790, -0.268856, 0.176557, -0.358709, 0.597589, - -0.361067, 0.065635, -0.203382, -0.213137, -0.939264, - -0.283951, 0.962113, 0.963571, -0.105083, -0.237030, - 0.689556, -0.431180, 0.346459, 0.713037, -0.448297, - -0.629262, 0.340335, -0.349973, 0.491599, 0.630144, - -0.421175, -0.630359, -0.778396, 0.468564, -0.808771, - -0.034014, -0.234646, -0.077627, -0.857457, 0.406645, - -0.480038, -0.218524, -0.527720, 0.316580, 0.568338, - -0.466984, -0.967371, 0.530452, -0.503413, -0.072454, - -0.706578, -0.813857, 0.496366, 0.639881, 0.899179, - -0.951931, -0.989381, 0.239514, -0.301904, 0.502218, - -0.130341, 0.276921, 0.871860, 0.091262, -0.254515, - -0.936911, -0.942752, 0.510839, -0.014539, -0.800209, - -0.082516, 0.505423, -0.018733, 0.389763, -0.177997, - -0.450395, 0.922779, -0.145368, -0.919943, -0.580634, - 0.782178, -0.626521, -0.394491, 0.278545, -0.986640, - -0.495312, 0.326614, -0.976021, 0.744203, -0.975290, - 0.526197, -0.386139, 0.301631, 0.398057, 0.705124, - -0.952884, 0.461146, 0.762372, 0.557954, -0.553393, - 0.962163, -0.524562, 0.952030, -0.056570, 0.865202, - -0.225967, 0.493035, 0.787981, 0.628665, 0.573093, - -0.792653, 0.410844, 0.946571, -0.187144, -0.310612, - 0.959931, 0.317544, -0.983998, 0.983911, 0.061747, - -0.959287, 0.510108, 0.675608, 0.342344, -0.091835, - 0.380731, 0.389460, -0.630689, 0.143103, -0.052586, - -0.184083, 0.105266, 0.422852, -0.232052, -0.951303, - 0.288054, 0.541981, 0.541732, 0.076035, 0.170646, - 0.114825, 0.283382, -0.418510, 0.061396, -0.903763, - 0.270879, 0.021327, 0.413782, 0.286881, 0.005238, - -0.524472, 0.327594, -0.484654, -0.848864, -0.330063, - 0.423511, 0.531868, -0.940603, 0.792822, -0.325029, - 0.006811, -0.391261, 0.780237, -0.570337, 0.376687, - 0.828934, 0.717717, -0.081333, 0.370666, -0.206248, - -0.910686, -0.514510, -0.922867, -0.329196, 0.546886, - -0.826629, 0.941683, -0.431786, 0.587152, 0.228564, - 0.573452, -0.937320, -0.443843, -0.911202, -0.786184, - 0.226094, 0.512309, 0.745684, 0.285491, 0.305131, - -0.579345, -0.707698, 0.913870, -0.799108, -0.278035, - 0.290556, -0.970174, -0.560318, -0.790776, 0.400492, - 0.233434, -0.701462, 0.885982, 0.310567, -0.030658, - 0.432868, 0.483938, -0.088976, -0.998918, 0.071090, - -0.860412, 0.574534, 0.133770, -0.304255, 0.663332, - 0.347586, 0.921839, 0.175641, 0.093270, 0.207330, - -0.519228, 0.513925, 0.499633, -0.605358, 0.714817, - -0.778402, 0.685198, 0.744643, -0.338720, 0.894422, - 0.145135, 0.894714, -0.807041, 0.031117, 0.205281, - 0.162301, -0.536015, -0.310781, -0.926675, -0.534932, - 0.760308, -0.787088, -0.960398, -0.105922, -0.091343, - 0.702934, -0.758336, -0.169504, -0.121425, 0.334935, - -0.962173, 0.359347, -0.151140, 0.537460, 0.753989, - -0.436323, 0.759058, 0.439187, -0.691680, -0.579662, - 0.333608, 0.453454, -0.684948, 0.526567, -0.515429, - 0.520333, -0.311132, -0.051443, -0.790448, -0.237807, - 0.413625, 0.969861, -0.024895, 0.453226, -0.136061, - 0.883762, 0.156160, 0.105603, -0.285741, -0.965264, - -0.559462, -0.247914, 0.394083, 0.289398, -0.710455, - 0.148072, 0.853074, -0.951397, -0.412742, -0.838606, - -0.531059, 0.920866, 0.614848, -0.216007, 0.447434, - -0.900580, -0.695673, -0.863698, 0.047977, -0.486121, - -0.101505, -0.538399, -0.516261, 0.873600, 0.914828, - 0.347678, 0.757362, 0.070988, -0.546718, -0.528380, - 0.105724, -0.106180, 0.223706, -0.500194, -0.816782, - 0.513251, 0.647878, -0.963708, 0.561854, -0.764864, - -0.802314, -0.969205, -0.843997, 0.812534, -0.185212, - 0.603436, 0.911954, 0.119114, 0.739738, -0.040069, - 0.632993, -0.361767, 0.421532, -0.883268, -0.488168, - 0.336360, 0.464411, -0.730806, -0.592652, 0.917693, - -0.259186, 0.513071, -0.188487, 0.964520, -0.987122, - -0.005270, 0.477771, 0.660756, 0.031023, 0.039625, - 0.895892, 0.228709, 0.070419, -0.948105, 0.041243, - 0.885207, 0.655331, -0.046803, 0.004321, 0.395069, - 0.913128, -0.362686, -0.966698, 0.334661, -0.245954, - -0.454865, -0.328980, -0.781543, -0.185671, 0.078368, - -0.863850, 0.555143, -0.408560, -0.052338, 0.519663, - -0.395683, 0.942393, -0.002565, -0.734927, -0.026585, - -0.962941, -0.839035, -0.797876, 0.107479, -0.787140, - 0.243367, -0.007314, 0.868191, -0.803435, 0.997007, - 0.263261, -0.890307, -0.365679, 0.296563, 0.444354, - 0.388367, 0.841698, -0.884626, 0.606824, -0.343973, - 0.193743, 0.742974, -0.788830, 0.785182, -0.309364, - 0.730833, -0.610500, -0.366971, -0.271732, -0.345427, - 0.606444, -0.234673, -0.184462, 0.808568, 0.872806, - 0.028398, 0.051936, -0.134508, -0.103410, 0.248500, - -0.137501, -0.840150, 0.358194, 0.496819, 0.456413, - -0.197453, -0.114814, 0.298111, -0.082078, -0.507990, - 0.954138, -0.888336, -0.765016, -0.834692, 0.896847, - -0.074380, 0.896141, -0.713654, 0.558649, -0.375591, - -0.059081, 0.165093, 0.389736, 0.756458, -0.026339, - 0.262542, -0.215144, -0.974403, -0.871966, 0.681446 -}; - -static const float wmavoice_gain_silence[256] = { - 0.0000188351, 0.0000249147, 0.0000294447, 0.0000365973, - 0.0000423193, 0.0000464916, 0.0000498295, 0.0000525713, - 0.0000550747, 0.0000574589, 0.0000596046, 0.0000615120, - 0.0000634193, 0.0000649691, 0.0000665188, 0.0000679493, - 0.0000692606, 0.0000704527, 0.0000716448, 0.0000728369, - 0.0000737906, 0.0000747442, 0.0000755787, 0.0000762939, - 0.0000770092, 0.0000778437, 0.0000785589, 0.0000792742, - 0.0000799894, 0.0000807047, 0.0000814199, 0.0000822544, - 0.0000829697, 0.0000838041, 0.0000845194, 0.0000854731, - 0.0000865459, 0.0000876188, 0.0000889301, 0.0000904799, - 0.0000923872, 0.0000950098, 0.0000988245, 0.0001032352, - 0.0001088381, 0.0001147985, 0.0001225471, 0.0001319647, - 0.0001431704, 0.0001568794, 0.0001744032, 0.0001952648, - 0.0002206564, 0.0002535582, 0.0002965927, 0.0003464222, - 0.0004109144, 0.0004891157, 0.0005909204, 0.0007261038, - 0.0008867979, 0.0010721684, 0.0012696981, 0.0015079975, - 0.0017461777, 0.0019979477, 0.0022052526, 0.0023679733, - 0.0025173426, 0.0026556253, 0.0027927160, 0.0029264688, - 0.0030447245, 0.0031807423, 0.0033060312, 0.0034313202, - 0.0035454035, 0.0036598444, 0.0037686825, 0.0038731098, - 0.0039769411, 0.0040702820, 0.0041661263, 0.0042562485, - 0.0043400526, 0.0044249296, 0.0045082569, 0.0045900345, - 0.0046693087, 0.0047430992, 0.0048171282, 0.0048881769, - 0.0049589872, 0.0050252676, 0.0050880909, 0.0051497221, - 0.0052082539, 0.0052671432, 0.0053246021, 0.0053800344, - 0.0054348707, 0.0054861307, 0.0055367947, 0.0055862665, - 0.0056355000, 0.0056805611, 0.0057252645, 0.0057705641, - 0.0058110952, 0.0058538914, 0.0058966875, 0.0059366226, - 0.0059723854, 0.0060091019, 0.0060437918, 0.0060794353, - 0.0061159134, 0.0061485767, 0.0061824322, 0.0062153339, - 0.0062497854, 0.0062820911, 0.0063197613, 0.0063550472, - 0.0063927174, 0.0064336061, 0.0064769983, 0.0065194368, - 0.0065603256, 0.0066006184, 0.0066410303, 0.0066826344, - 0.0067234039, 0.0067654848, 0.0068060160, 0.0068466663, - 0.0068866014, 0.0069231987, 0.0069609880, 0.0069983006, - 0.0070366859, 0.0070750713, 0.0071122646, 0.0071535110, - 0.0071973801, 0.0072410107, 0.0072846413, 0.0073343515, - 0.0073832273, 0.0074360371, 0.0074878931, 0.0075426102, - 0.0076007843, 0.0076560974, 0.0077134371, 0.0077683926, - 0.0078265667, 0.0078855753, 0.0079488754, 0.0080170631, - 0.0080827475, 0.0081528425, 0.0082212687, 0.0082877874, - 0.0083510876, 0.0084129572, 0.0084775686, 0.0085455179, - 0.0086110830, 0.0086781979, 0.0087503195, 0.0088242292, - 0.0089002848, 0.0089734793, 0.0090423822, 0.0091133118, - 0.0091816187, 0.0092473030, 0.0093164444, 0.0093911886, - 0.0094678402, 0.0095427036, 0.0096175671, 0.0096931458, - 0.0097666979, 0.0098397732, 0.0099166632, 0.0099946260, - 0.0100749731, 0.0101612806, 0.0102528334, 0.0103493929, - 0.0104434490, 0.0105448961, 0.0106583834, 0.0107737780, - 0.0108981133, 0.0110142231, 0.0111318827, 0.0112472773, - 0.0113576651, 0.0114786625, 0.0116028786, 0.0117331743, - 0.0118676424, 0.0120122433, 0.0121580362, 0.0123010874, - 0.0124633312, 0.0126402378, 0.0128232241, 0.0130140781, - 0.0132108927, 0.0134289265, 0.0136625767, 0.0138912201, - 0.0141364336, 0.0144006014, 0.0146615505, 0.0149335861, - 0.0152134895, 0.0155050755, 0.0158376694, 0.0162067413, - 0.0165973902, 0.0169926882, 0.0174319744, 0.0179271698, - 0.0184448957, 0.0190744400, 0.0197248459, 0.0204203129, - 0.0212460756, 0.0221523046, 0.0231562853, 0.0243031979, - 0.0256397724, 0.0271918774, 0.0289602280, 0.0310072899, - 0.0333702564, 0.0363805294, 0.0401413441, 0.0443998575, - 0.0498176813, 0.0562580824, 0.0640066862, 0.0732775927, - 0.0836604834, 0.0962959528, 0.1122496128, 0.1335854530, - 0.1608980894, 0.1990102530, 0.2616490126, 0.3926030397 -}; - -static const float wmavoice_gain_universal[64] = { - 0.0000000000, 0.0000000000, 0.0000015497, 0.0000015497, - 0.0000095367, 0.0000164509, 0.0000379086, 0.0000494719, - 0.0000799894, 0.0001058578, 0.0001349449, 0.0001627207, - 0.0001972914, 0.0002325773, 0.0002671480, 0.0003106594, - 0.0003589392, 0.0004127026, 0.0004582405, 0.0005071163, - 0.0005759001, 0.0006588697, 0.0007554293, 0.0008602142, - 0.0009772778, 0.0011068583, 0.0012603998, 0.0013889074, - 0.0015437603, 0.0016924143, 0.0018980503, 0.0021264553, - 0.0023632050, 0.0025693178, 0.0028522015, 0.0031896830, - 0.0034654140, 0.0037885904, 0.0041683912, 0.0046081543, - 0.0050576925, 0.0055632591, 0.0061818361, 0.0068151951, - 0.0073953867, 0.0081818104, 0.0091186762, 0.0102789402, - 0.0119919777, 0.0134155750, 0.0154829025, 0.0173798800, - 0.0199711323, 0.0229473114, 0.0268185139, 0.0319474936, - 0.0393068790, 0.0460114479, 0.0523469448, 0.0637906790, - 0.0845471621, 0.1105458736, 0.1499300003, 0.2219169140 -}; - -static const float wmavoice_gain_codebook_acb[128] = { - 0.05, 0.14, 0.16, 0.05, 0.17, 0.25, 0.07, 0.21, - 0.12, 0.22, 0.23, 0.13, 0.24, 0.32, 0.14, 0.29, - 0.31, 0.41, 0.43, 0.32, 0.43, 0.51, 0.34, 0.48, - 0.38, 0.47, 0.49, 0.38, 0.49, 0.57, 0.40, 0.54, - 0.49, 0.59, 0.61, 0.50, 0.61, 0.69, 0.52, 0.66, - 0.56, 0.65, 0.67, 0.56, 0.67, 0.75, 0.58, 0.72, - 0.65, 0.74, 0.76, 0.65, 0.76, 0.84, 0.67, 0.81, - 0.71, 0.80, 0.82, 0.71, 0.82, 0.90, 0.73, 0.87, - 0.81, 0.90, 0.92, 0.81, 0.93, 1.01, 0.83, 0.97, - 0.87, 0.96, 0.98, 0.87, 0.98, 1.06, 0.89, 1.03, - 0.92, 1.02, 1.04, 0.93, 1.04, 1.12, 0.95, 1.09, - 0.93, 1.02, 1.04, 0.93, 1.04, 1.12, 0.95, 1.09, - 0.94, 1.04, 1.05, 0.10, 1.06, 1.14, 0.96, 1.11, - 0.98, 1.08, 1.10, 0.99, 1.10, 1.18, 1.01, 1.15, - 1.06, 1.15, 1.17, 1.06, 1.17, 1.25, 1.08, 1.22, - 1.16, 1.25, 1.27, 1.16, 1.28, 1.36, 1.18, 1.32 -}; - -static const float wmavoice_gain_codebook_fcb[128] = { - -0.8439700703 /* log(0.430) */, -0.6143360001 /* log(0.541) */, - -0.1531511795 /* log(0.858) */, -0.0998203353 /* log(0.905) */, - 0.3213585988 /* log(1.379) */, 0.3777512695 /* log(1.459) */, - 0.7158866675 /* log(2.046) */, 1.2700414043 /* log(3.561) */, - -1.6873994539 /* log(0.185) */, -1.2173958247 /* log(0.296) */, - -0.4893903430 /* log(0.613) */, -0.4155154440 /* log(0.660) */, - 0.1257512053 /* log(1.134) */, 0.1947440768 /* log(1.215) */, - 0.5883420662 /* log(1.801) */, 1.1987592373 /* log(3.316) */, - -1.3586791941 /* log(0.257) */, -0.9996723408 /* log(0.368) */, - -0.3768776513 /* log(0.686) */, -0.3119747650 /* log(0.732) */, - 0.1881379421 /* log(1.207) */, 0.2523139286 /* log(1.287) */, - 0.6280751838 /* log(1.874) */, 1.2202397768 /* log(3.388) */, - -0.7381445465 /* log(0.478) */, -0.5310283311 /* log(0.588) */, - -0.0987159729 /* log(0.906) */, -0.0491902442 /* log(0.952) */, - 0.3555743385 /* log(1.427) */, 0.4101209196 /* log(1.507) */, - 0.7390761124 /* log(2.094) */, 1.2831536022 /* log(3.608) */, - -0.2497442331 /* log(0.779) */, -0.1165338163 /* log(0.890) */, - 0.1881379421 /* log(1.207) */, 0.2255406759 /* log(1.253) */, - 0.5469646704 /* log(1.728) */, 0.5922212620 /* log(1.808) */, - 0.8733832309 /* log(2.395) */, 1.3632815868 /* log(3.909) */, - -1.3903023825 /* log(0.249) */, -1.0216512475 /* log(0.360) */, - -0.3900840061 /* log(0.677) */, -0.3229638866 /* log(0.724) */, - 0.1806534997 /* log(1.198) */, 0.2460785226 /* log(1.279) */, - 0.6232610531 /* log(1.865) */, 1.2178757095 /* log(3.380) */, - -0.6033064766 /* log(0.547) */, -0.4185503477 /* log(0.658) */, - -0.0253178080 /* log(0.975) */, 0.0217614918 /* log(1.022) */, - 0.4027948796 /* log(1.496) */, 0.4555243080 /* log(1.577) */, - 0.7714961470 /* log(2.163) */, 1.3023691262 /* log(3.678) */, - -1.1056369036 /* log(0.331) */, -0.8164453969 /* log(0.442) */, - -0.2757535016 /* log(0.759) */, -0.2156715365 /* log(0.806) */, - 0.2468600779 /* log(1.280) */, 0.3082197237 /* log(1.361) */, - 0.6662897264 /* log(1.947) */, 1.2418464568 /* log(3.462) */, - -0.5395680926 /* log(0.583) */, -0.3652833185 /* log(0.694) */, - 0.0109399400 /* log(1.011) */, 0.0554347069 /* log(1.057) */, - 0.4265740713 /* log(1.532) */, 0.4774756441 /* log(1.612) */, - 0.7880027116 /* log(2.199) */, 1.3118401752 /* log(3.713) */, - -0.9571127264 /* log(0.384) */, -0.7031975164 /* log(0.495) */, - -0.2082549388 /* log(0.812) */, -0.1519863570 /* log(0.859) */, - 0.2874320412 /* log(1.333) */, 0.3464225675 /* log(1.414) */, - 0.6931471806 /* log(2.000) */, 1.2570395253 /* log(3.515) */, - -0.2420715612 /* log(0.785) */, -0.1098148660 /* log(0.896) */, - 0.1930966300 /* log(1.213) */, 0.2311117210 /* log(1.260) */, - 0.5504308784 /* log(1.734) */, 0.5960854677 /* log(1.815) */, - 0.8758853172 /* log(2.401) */, 1.3650707247 /* log(3.916) */, - 0.6564831962 /* log(1.928) */, 0.7124594916 /* log(2.039) */, - 0.8569652658 /* log(2.356) */, 0.8767179568 /* log(2.403) */, - 1.0567480846 /* log(2.877) */, 1.0841752409 /* log(2.957) */, - 1.2652560327 /* log(3.544) */, 1.6211688353 /* log(5.059) */, - -1.5417792640 /* log(0.214) */, -1.1239300967 /* log(0.325) */, - -0.4431669753 /* log(0.642) */, -5.2983173665 /* log(0.005) */, - 0.1510028735 /* log(1.163) */, 0.2183319943 /* log(1.244) */, - 0.6043159669 /* log(1.830) */, 1.2074666936 /* log(3.345) */, - -0.5124936809 /* log(0.599) */, -0.3424903089 /* log(0.710) */, - 0.0266419309 /* log(1.027) */, 0.0713899961 /* log(1.074) */, - 0.4369637752 /* log(1.548) */, 0.4879663296 /* log(1.629) */, - 0.7952524035 /* log(2.215) */, 1.3164082337 /* log(3.730) */, - -0.8867319296 /* log(0.412) */, -0.6481738149 /* log(0.523) */, - -0.1743533871 /* log(0.840) */, -0.1199102967 /* log(0.887) */, - 0.3089542077 /* log(1.362) */, 0.3660310389 /* log(1.442) */, - 0.7075430608 /* log(2.029) */, 1.2649738259 /* log(3.543) */, - -0.0943106795 /* log(0.910) */, 0.0207825392 /* log(1.021) */, - 0.2911759617 /* log(1.338) */, 0.3249778572 /* log(1.384) */, - 0.6200387087 /* log(1.859) */, 0.6621723763 /* log(1.939) */, - 0.9266370239 /* log(2.526) */, 1.3962446920 /* log(4.040) */ -}; - -static const float wmavoice_ipol1_coeffs[17*9] = { - 0, - 0.6308171151, 0.7613050340, 0.8632577061, 0.9280143976, - 0.9499985575, 0.9273047447, 0.8618999123, 0.7594153284, - -0.1791058179, -0.1351341452, -0.0589959878, 0.0472882274, - 0.1784339990, 0.3262237605, 0.4801855979, 0.6285545824, - 0, - -0.1921342459, -0.1786532696, -0.1341681625, -0.0575229186, - 0.0492091286, 0.1806929555, 0.3286687729, 0.4826357064, - 0.0807464118, 0.0506337392, 0.0080115446, -0.0428523305, - -0.0958572026, -0.1436148431, -0.1782128509, -0.1921164688, - 0, - 0.0960653644, 0.0803771760, 0.0500416081, 0.0072485465, - -0.0437018941, -0.0966834794, -0.1442930843, -0.1786170151, - -0.0391932014, -0.0189622506, 0.0070230183, 0.0356589290, - 0.0630142610, 0.0847979258, 0.0969368290, 0.0961942221, - 0, - -0.0515680681, -0.0389267015, -0.0185848991, 0.0074699190, - 0.0361179407, 0.0634181346, 0.0850781347, 0.0970333587, - 0.0178811825, 0.0048708571, -0.0108041526, -0.0271167825, - -0.0416534986, -0.0519338618, -0.0557823736, -0.0517020743, - 0, - 0.0267091128, 0.0177022810, 0.0046363524, -0.0110662053, - -0.0273700613, -0.0418578978, -0.0520511451, -0.0557823028, - -0.0069270437, 0.0008217385, 0.0097293532, 0.0185749526, - 0.0259542684, 0.0304777338, 0.0309953480, 0.0268154419, - 0, - -0.0125539196, -0.0068173436, 0.0009580161, 0.0098749646, - 0.0187084037, 0.0260526291, 0.0305201071, 0.0309665180, - 0.0019149571, -0.0022503408, -0.0068592466, -0.0112465904, - -0.0146595868, -0.0163685936, -0.0157934162, -0.0126258885, - 0, - 0.0050976076, 0.0018546581, -0.0023221741, -0.0069331308, - -0.0113109085, -0.0147021576, -0.0163786146, -0.0157635096, - -0.0001162733, 0.0019313511, 0.0040823850, 0.0060192454, - 0.0073876535, 0.0078486321, 0.0071403184, 0.0051400312, - 0, - -0.0017920607, -0.0000857157, 0.0019657183, 0.0041159806, - 0.0060465694, 0.0074030068, 0.0078470460, 0.0071185785, - -0.0004100171, -0.0015364708, -0.0025490071, -0.0033188616, - -0.0037196307, -0.0036417283, -0.0030119629, -0.0018155784, - 0, - 0.0006907531, -0.0004282868, -0.0015539061, -0.0025635813, - -0.0033285026, -0.0037224069, -0.0036361245, -0.0029972247, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/** - * Hamming-window sinc function (num = 32, x = [ 0, 31 ]): - * (0.54 + 0.46 * cos(2 * M_PI * x / (num - 1))) * - * sin(x * M_PI / 4) / (x * M_PI / 4) - */ -static const float wmavoice_ipol2_coeffs[32] = { - 1, 0.8563459515, 0.5888634918, 0.2648358640, - 0, -0.1360490318, -0.1434589471, -0.0758505310, - 0, 0.0410402636, 0.0412485781, 0.0200064587, - 0, -0.0081391358, -0.0068223253, -0.0029313546, - 0, 0.0025864919, 0.0053062555, 0.0055688801, - 0, -0.0104795941, -0.0187493577, -0.0160592399, - 0, 0.0212381664, 0.0331059131, 0.0251942366, - 0, -0.0273968070, -0.0392575669, -0.0276240534 -}; - -/** - * LUT for 1.071575641632 * pow(1.0331663, n - 127) - */ -static const float wmavoice_energy_table[128] = { - 0.0169982178, 0.0175619858, 0.0181444519, 0.0187462362, - 0.0193679795, 0.0200103437, 0.0206740128, 0.0213596933, - 0.0220681153, 0.0228000330, 0.0235562258, 0.0243374986, - 0.0251446834, 0.0259786395, 0.0268402549, 0.0277304468, - 0.0286501631, 0.0296003830, 0.0305821182, 0.0315964139, - 0.0326443501, 0.0337270424, 0.0348456436, 0.0360013446, - 0.0371953760, 0.0384290090, 0.0397035571, 0.0410203772, - 0.0423808713, 0.0437864880, 0.0452387238, 0.0467391249, - 0.0482892887, 0.0498908657, 0.0515455612, 0.0532551367, - 0.0550214125, 0.0568462692, 0.0587316496, 0.0606795611, - 0.0626920777, 0.0647713419, 0.0669195677, 0.0691390421, - 0.0714321284, 0.0738012678, 0.0762489827, 0.0787778794, - 0.0813906502, 0.0840900769, 0.0868790336, 0.0897604897, - 0.0927375130, 0.0958132732, 0.0989910450, 0.1022742117, - 0.1056662688, 0.1091708280, 0.1127916204, 0.1165325012, - 0.1203974531, 0.1243905911, 0.1285161668, 0.1327785725, - 0.1371823465, 0.1417321773, 0.1464329093, 0.1512895470, - 0.1563072616, 0.1614913951, 0.1668474671, 0.1723811803, - 0.1780984262, 0.1840052921, 0.1901080668, 0.1964132480, - 0.2029275487, 0.2096579046, 0.2166114816, 0.2237956830, - 0.2312181577, 0.2388868085, 0.2468098001, 0.2549955679, - 0.2634528274, 0.2721905830, 0.2812181375, 0.2905451026, - 0.3001814086, 0.3101373153, 0.3204234225, 0.3310506819, - 0.3420304081, 0.3533742912, 0.3650944090, 0.3772032397, - 0.3897136755, 0.4026390362, 0.4159930832, 0.4297900346, - 0.4440445799, 0.4587718956, 0.4739876619, 0.4897080789, - 0.5059498840, 0.5227303696, 0.5400674019, 0.5579794393, - 0.5764855528, 0.5956054456, 0.6153594745, 0.6357686714, - 0.6568547659, 0.6786402082, 0.7011481929, 0.7244026842, - 0.7484284410, 0.7732510432, 0.7988969192, 0.8253933741, - 0.8527686184, 0.8810517982, 0.9102730265, 0.9404634147, - 0.9716551065, 1.0038813113, 1.0371763400, 1.0715756416 -}; - -/** - * LUT for f(x,y) = pow((y + 6.9) / 64, 0.025 * (x + 1)). - */ -static const float wmavoice_denoise_power_table[12][64] = { - { 0.9458379339, 0.9490436287, 0.9518757236, 0.9544130754, - 0.9567118717, 0.9588135761, 0.9607496688, 0.9625446194, - 0.9642178285, 0.9657849396, 0.9672587526, 0.9686498743, - 0.9699671937, 0.9712182343, 0.9724094211, 0.9735462842, - 0.9746336187, 0.9756756090, 0.9766759291, 0.9776378218, - 0.9785641645, 0.9794575217, 0.9803201890, 0.9811542296, - 0.9819615045, 0.9827436985, 0.9835023412, 0.9842388263, - 0.9849544265, 0.9856503078, 0.9863275406, 0.9869871101, - 0.9876299254, 0.9882568267, 0.9888685922, 0.9894659445, - 0.9900495551, 0.9906200497, 0.9911780119, 0.9917239872, - 0.9922584859, 0.9927819864, 0.9932949377, 0.9937977618, - 0.9942908555, 0.9947745929, 0.9952493267, 0.9957153901, - 0.9961730980, 0.9966227482, 0.9970646231, 0.9974989903, - 0.9979261037, 0.9983462046, 0.9987595223, 0.9991662752, - 0.9995666709, 0.9999609077, 1.0003491745, 1.0007316515, - 1.0011085110, 1.0014799178, 1.0018460292, 1.0022069960 }, - { 0.8946093973, 0.9006838092, 0.9060673931, 0.9109043185, - 0.9152976055, 0.9193234737, 0.9230399260, 0.9264921443, - 0.9297160207, 0.9327405496, 0.9355894944, 0.9382825789, - 0.9408363568, 0.9432648587, 0.9455800822, 0.9477923675, - 0.9499106907, 0.9519428941, 0.9538958704, 0.9557757107, - 0.9575878241, 0.9593370368, 0.9610276730, 0.9626636222, - 0.9642483964, 0.9657851769, 0.9672768552, 0.9687260672, - 0.9701352224, 0.9715065293, 0.9728420173, 0.9741435556, - 0.9754128696, 0.9766515555, 0.9778610927, 0.9790428553, - 0.9801981216, 0.9813280829, 0.9824338513, 0.9835164667, - 0.9845769028, 0.9856160726, 0.9866348334, 0.9876339913, - 0.9886143053, 0.9895764906, 0.9905212223, 0.9914491381, - 0.9923608411, 0.9932569022, 0.9941378627, 0.9950042356, - 0.9958565084, 0.9966951442, 0.9975205834, 0.9983332454, - 0.9991335296, 0.9999218170, 1.0006984708, 1.0014638383, - 1.0022182509, 1.0029620257, 1.0036954662, 1.0044188628 }, - { 0.8461555040, 0.8547882305, 0.8624635555, 0.8693789920, - 0.8756760853, 0.8814598273, 0.8868103032, 0.8917900284, - 0.8964487626, 0.9008267754, 0.9049571273, 0.9088673021, - 0.9125804007, 0.9161160306, 0.9194909803, 0.9227197376, - 0.9258148939, 0.9287874629, 0.9316471355, 0.9344024839, - 0.9370611291, 0.9396298766, 0.9421148300, 0.9445214846, - 0.9468548060, 0.9491192967, 0.9513190517, 0.9534578074, - 0.9555389816, 0.9575657096, 0.9595408742, 0.9614671327, - 0.9633469396, 0.9651825670, 0.9669761222, 0.9687295635, - 0.9704447142, 0.9721232742, 0.9737668316, 0.9753768718, - 0.9769547868, 0.9785018824, 0.9800193854, 0.9815084500, - 0.9829701633, 0.9844055505, 0.9858155796, 0.9872011653, - 0.9885631734, 0.9899024236, 0.9912196934, 0.9925157203, - 0.9937912053, 0.9950468143, 0.9962831814, 0.9975009102, - 0.9987005760, 0.9998827277, 1.0010478892, 1.0021965608, - 1.0033292209, 1.0044463270, 1.0055483173, 1.0066356112 }, - { 0.8003259737, 0.8112313241, 0.8209581209, 0.8297466775, - 0.8377697066, 0.8451556492, 0.8520027051, 0.8583876935, - 0.8643718792, 0.8700049328, 0.8753277020, 0.8803741979, - 0.8851730502, 0.8897485937, 0.8941216918, 0.8983103719, - 0.9023303202, 0.9061952736, 0.9099173316, 0.9135072091, - 0.9169744409, 0.9203275502, 0.9235741882, 0.9267212496, - 0.9297749699, 0.9327410079, 0.9356245146, 0.9384301933, - 0.9411623497, 0.9438249364, 0.9464215906, 0.9489556668, - 0.9514302661, 0.9538482608, 0.9562123167, 0.9585249126, - 0.9607883576, 0.9630048062, 0.9651762722, 0.9673046403, - 0.9693916775, 0.9714390425, 0.9734482944, 0.9754209007, - 0.9773582446, 0.9792616307, 0.9811322918, 0.9829713934, - 0.9847800389, 0.9865592739, 0.9883100900, 0.9900334289, - 0.9917301853, 0.9934012104, 0.9950473143, 0.9966692689, - 0.9982678100, 0.9998436400, 1.0013974295, 1.0029298194, - 1.0044414224, 1.0059328250, 1.0074045889, 1.0088572520 }, - { 0.7569786654, 0.7698939195, 0.7814501054, 0.7919210783, - 0.8015042240, 0.8103467104, 0.8185613167, 0.8262364557, - 0.8334427763, 0.8402376615, 0.8466683811, 0.8527743561, - 0.8585888194, 0.8641400582, 0.8694523567, 0.8745467247, - 0.8794414652, 0.8841526254, 0.8886943552, 0.8930791981, - 0.8973183276, 0.9014217415, 0.9053984227, 0.9092564737, - 0.9130032283, 0.9166453478, 0.9201889007, 0.9236394320, - 0.9270020224, 0.9302813390, 0.9334816797, 0.9366070112, - 0.9396610028, 0.9426470554, 0.9455683275, 0.9484277579, - 0.9512280860, 0.9539718690, 0.9566614986, 0.9592992147, - 0.9618871182, 0.9644271823, 0.9669212630, 0.9693711079, - 0.9717783651, 0.9741445900, 0.9764712529, 0.9787597445, - 0.9810113822, 0.9832274148, 0.9854090274, 0.9875573457, - 0.9896734398, 0.9917583281, 0.9938129803, 0.9958383209, - 0.9978352315, 0.9998045539, 1.0017470919, 1.0036636145, - 1.0055548568, 1.0074215229, 1.0092642871, 1.0110837959 }, - { 0.7159791370, 0.7306629191, 0.7438433845, 0.7558198318, - 0.7668086064, 0.7769714272, 0.7864325139, 0.7952894548, - 0.8036203840, 0.8114888792, 0.8189474022, 0.8260397728, - 0.8328029877, 0.8392685815, 0.8454636629, 0.8514117142, - 0.8571332177, 0.8626461513, 0.8679663850, 0.8731080020, - 0.8780835596, 0.8829043049, 0.8875803529, 0.8921208349, - 0.8965340237, 0.9008274393, 0.9050079382, 0.9090817905, - 0.9130547454, 0.9169320882, 0.9207186893, 0.9244190474, - 0.9280373261, 0.9315773876, 0.9350428208, 0.9384369673, - 0.9417629433, 0.9450236603, 0.9482218422, 0.9513600421, - 0.9544406555, 0.9574659338, 0.9604379957, 0.9633588374, - 0.9662303420, 0.9690542879, 0.9718323569, 0.9745661408, - 0.9772571477, 0.9799068082, 0.9825164805, 0.9850874551, - 0.9876209597, 0.9901181627, 0.9925801775, 0.9950080658, - 0.9974028405, 0.9997654692, 1.0020968764, 1.0043979464, - 1.0066695255, 1.0089124239, 1.0111274185, 1.0133152537 }, - { 0.6772002277, 0.6934309881, 0.7080464599, 0.7213643301, - 0.7336148970, 0.7449707526, 0.7555647772, 0.7655015856, - 0.7748651015, 0.7837237382, 0.7921340426, 0.8001433220, - 0.8077915768, 0.8151129499, 0.8221368310, 0.8288887107, - 0.8353908496, 0.8416628090, 0.8477218755, 0.8535834053, - 0.8592611049, 0.8647672624, 0.8701129393, 0.8753081305, - 0.8803618988, 0.8852824894, 0.8900774261, 0.8947535945, - 0.8993173131, 0.9037743949, 0.9081302004, 0.9123896841, - 0.9165574352, 0.9206377129, 0.9246344779, 0.9285514202, - 0.9323919830, 0.9361593853, 0.9398566405, 0.9434865742, - 0.9470518396, 0.9505549317, 0.9539981992, 0.9573838564, - 0.9607139933, 0.9639905847, 0.9672154989, 0.9703905051, - 0.9735172803, 0.9765974162, 0.9796324243, 0.9826237418, - 0.9855727362, 0.9884807098, 0.9913489039, 0.9941785028, - 0.9969706369, 0.9997263861, 1.0024467831, 1.0051328157, - 1.0077854297, 1.0104055314, 1.0129939892, 1.0155516364 }, - { 0.6405216642, 0.6580962612, 0.6739722363, 0.6884795488, - 0.7018580813, 0.7142880714, 0.7259086094, 0.7368294324, - 0.7471387455, 0.7569085832, 0.7661985859, 0.7750587283, - 0.7835313288, 0.7916525600, 0.7994535998, 0.8069615243, - 0.8142000068, 0.8211898738, 0.8279495504, 0.8344954211, - 0.8408421252, 0.8470027997, 0.8529892811, 0.8588122744, - 0.8644814947, 0.8700057878, 0.8753932324, 0.8806512276, - 0.8857865684, 0.8908055105, 0.8957138271, 0.9005168576, - 0.9052195513, 0.9098265046, 0.9143419945, 0.9187700080, - 0.9231142680, 0.9273782568, 0.9315652364, 0.9356782672, - 0.9397202245, 0.9436938133, 0.9476015819, 0.9514459336, - 0.9552291382, 0.9589533414, 0.9626205741, 0.9662327603, - 0.9697917251, 0.9732992008, 0.9767568340, 0.9801661903, - 0.9835287605, 0.9868459649, 0.9901191578, 0.9933496315, - 0.9965386205, 0.9996873045, 1.0027968119, 1.0058682226, - 1.0089025710, 1.0119008485, 1.0148640056, 1.0177929548 }, - { 0.6058296875, 0.6245620637, 0.6415378101, 0.6570938835, - 0.6714759586, 0.6848691001, 0.6974164561, 0.7092312055, - 0.7204044988, 0.7310109103, 0.7411122884, 0.7507605397, - 0.7599996842, 0.7688674015, 0.7773962122, 0.7856143935, - 0.7935466990, 0.8012149303, 0.8086383963, 0.8158342858, - 0.8228179717, 0.8296032631, 0.8362026133, 0.8426272954, - 0.8488875492, 0.8549927056, 0.8609512936, 0.8667711307, - 0.8724594015, 0.8780227256, 0.8834672161, 0.8887985309, - 0.8940219180, 0.8991422543, 0.9041640810, 0.9090916337, - 0.9139288704, 0.9186794948, 0.9233469789, 0.9279345818, - 0.9324453671, 0.9368822185, 0.9412478543, 0.9455448393, - 0.9497755970, 0.9539424198, 0.9580474782, 0.9620928299, - 0.9660804271, 0.9700121244, 0.9738896845, 0.9777147851, - 0.9814890239, 0.9852139236, 0.9888909370, 0.9925214512, - 0.9961067913, 0.9996482244, 1.0031469629, 1.0066041676, - 1.0100209506, 1.0133983785, 1.0167374742, 1.0200392198 }, - { 0.5730166999, 0.5927366473, 0.6106642672, 0.6271389942, - 0.6424090212, 0.6566617910, 0.6700426292, 0.6826666808, - 0.6946268614, 0.7059993279, 0.7168473476, 0.7272241023, - 0.7371747608, 0.7467380401, 0.7559474006, 0.7648319736, - 0.7734172908, 0.7817258650, 0.7897776570, 0.7975904541, - 0.8051801811, 0.8125611560, 0.8197463039, 0.8267473349, - 0.8335748949, 0.8402386937, 0.8467476129, 0.8531098003, - 0.8593327495, 0.8654233698, 0.8713880464, 0.8772326935, - 0.8829628002, 0.8885834710, 0.8940994619, 0.8995152120, - 0.9048348715, 0.9100623268, 0.9152012229, 0.9202549833, - 0.9252268281, 0.9301197899, 0.9349367288, 0.9396803449, - 0.9443531909, 0.9489576823, 0.9534961076, 0.9579706374, - 0.9623833320, 0.9667361492, 0.9710309512, 0.9752695109, - 0.9794535174, 0.9835845813, 0.9876642399, 0.9916939614, - 0.9956751493, 0.9996091459, 1.0034972362, 1.0073406510, - 1.0111405700, 1.0148981248, 1.0186144013, 1.0222904422 }, - { 0.5419809316, 0.5625329386, 0.5812764912, 0.5985496562, - 0.6146003370, 0.6296162401, 0.6437432340, 0.6570971404, - 0.6697716039, 0.6818435182, 0.6933768712, 0.7044255353, - 0.7150353340, 0.7252456009, 0.7350903742, 0.7445993259, - 0.7537984929, 0.7627108595, 0.7713568269, 0.7797545943, - 0.7879204712, 0.7958691361, 0.8036138516, 0.8111666444, - 0.8185384580, 0.8257392814, 0.8327782597, 0.8396637886, - 0.8464035955, 0.8530048108, 0.8594740287, 0.8658173611, - 0.8720404845, 0.8781486812, 0.8841468762, 0.8900396688, - 0.8958313620, 0.9015259874, 0.9071273286, 0.9126389413, - 0.9180641715, 0.9234061727, 0.9286679198, 0.9338522236, - 0.9389617420, 0.9439989920, 0.9489663591, 0.9538661069, - 0.9587003852, 0.9634712378, 0.9681806094, 0.9728303524, - 0.9774222323, 0.9819579336, 0.9864390644, 0.9908671615, - 0.9952436943, 0.9995700689, 1.0038476318, 1.0080776733, - 1.0122614305, 1.0164000906, 1.0204947932, 1.0245466331 }, - { 0.5126261246, 0.5338683013, 0.5533029807, 0.5712636181, - 0.5879954388, 0.6036845987, 0.6184760989, 0.6324853169, - 0.6458057215, 0.6585142011, 0.6706748475, 0.6823417062, - 0.6935608163, 0.7043717519, 0.7148088052, 0.7249019070, - 0.7346773529, 0.7441583823, 0.7533656456, 0.7623175831, - 0.7710307376, 0.7795200117, 0.7877988829, 0.7958795841, - 0.8037732557, 0.8114900754, 0.8190393682, 0.8264297018, - 0.8336689680, 0.8407644543, 0.8477229049, 0.8545505751, - 0.8612532786, 0.8678364291, 0.8743050768, 0.8806639416, - 0.8869174414, 0.8930697184, 0.8991246621, 0.9050859297, - 0.9109569648, 0.9167410144, 0.9224411436, 0.9280602496, - 0.9336010737, 0.9390662129, 0.9444581300, 0.9497791628, - 0.9550315328, 0.9602173528, 0.9653386345, 0.9703972943, - 0.9753951600, 0.9803339761, 0.9852154088, 0.9900410510, - 0.9948124263, 0.9995309934, 1.0041981497, 1.0088152348, - 1.0133835335, 1.0179042791, 1.0223786564, 1.0268078035 }, -}; - -#endif /* AVCODEC_WMAVOICE_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/wmv2.c b/tizen/distrib/ffmpeg/libavcodec/wmv2.c deleted file mode 100644 index e872b44..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmv2.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2002 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "mpegvideo.h" -#include "msmpeg4data.h" -#include "simple_idct.h" -#include "wmv2.h" - - -av_cold void ff_wmv2_common_init(Wmv2Context * w){ - MpegEncContext * const s= &w->s; - - ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0], wmv2_scantableA); - ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1], wmv2_scantableB); -} - -static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int stride, int n){ - MpegEncContext * const s= &w->s; - - if (s->block_last_index[n] >= 0) { - switch(w->abt_type_table[n]){ - case 0: - s->dsp.idct_add (dst, stride, block1); - break; - case 1: - ff_simple_idct84_add(dst , stride, block1); - ff_simple_idct84_add(dst + 4*stride, stride, w->abt_block2[n]); - s->dsp.clear_block(w->abt_block2[n]); - break; - case 2: - ff_simple_idct48_add(dst , stride, block1); - ff_simple_idct48_add(dst + 4 , stride, w->abt_block2[n]); - s->dsp.clear_block(w->abt_block2[n]); - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "internal error in WMV2 abt\n"); - } - } -} - -void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block1[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr){ - Wmv2Context * const w= (Wmv2Context*)s; - - wmv2_add_block(w, block1[0], dest_y , s->linesize, 0); - wmv2_add_block(w, block1[1], dest_y + 8 , s->linesize, 1); - wmv2_add_block(w, block1[2], dest_y + 8*s->linesize, s->linesize, 2); - wmv2_add_block(w, block1[3], dest_y + 8 + 8*s->linesize, s->linesize, 3); - - if(s->flags&CODEC_FLAG_GRAY) return; - - wmv2_add_block(w, block1[4], dest_cb , s->uvlinesize, 4); - wmv2_add_block(w, block1[5], dest_cr , s->uvlinesize, 5); -} - -void ff_mspel_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h) -{ - Wmv2Context * const w= (Wmv2Context*)s; - uint8_t *ptr; - int dxy, offset, mx, my, src_x, src_y, v_edge_pos, linesize, uvlinesize; - int emu=0; - - dxy = ((motion_y & 1) << 1) | (motion_x & 1); - dxy = 2*dxy + w->hshift; - src_x = s->mb_x * 16 + (motion_x >> 1); - src_y = s->mb_y * 16 + (motion_y >> 1); - - /* WARNING: do no forget half pels */ - v_edge_pos = s->v_edge_pos; - src_x = av_clip(src_x, -16, s->width); - src_y = av_clip(src_y, -16, s->height); - - if(src_x<=-16 || src_x >= s->width) - dxy &= ~3; - if(src_y<=-16 || src_y >= s->height) - dxy &= ~4; - - linesize = s->linesize; - uvlinesize = s->uvlinesize; - ptr = ref_picture[0] + (src_y * linesize) + src_x; - - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if(src_x<1 || src_y<1 || src_x + 17 >= s->h_edge_pos - || src_y + h+1 >= v_edge_pos){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr - 1 - s->linesize, s->linesize, 19, 19, - src_x-1, src_y-1, s->h_edge_pos, s->v_edge_pos); - ptr= s->edge_emu_buffer + 1 + s->linesize; - emu=1; - } - } - - s->dsp.put_mspel_pixels_tab[dxy](dest_y , ptr , linesize); - s->dsp.put_mspel_pixels_tab[dxy](dest_y+8 , ptr+8 , linesize); - s->dsp.put_mspel_pixels_tab[dxy](dest_y +8*linesize, ptr +8*linesize, linesize); - s->dsp.put_mspel_pixels_tab[dxy](dest_y+8+8*linesize, ptr+8+8*linesize, linesize); - - if(s->flags&CODEC_FLAG_GRAY) return; - - if (s->out_format == FMT_H263) { - dxy = 0; - if ((motion_x & 3) != 0) - dxy |= 1; - if ((motion_y & 3) != 0) - dxy |= 2; - mx = motion_x >> 2; - my = motion_y >> 2; - } else { - mx = motion_x / 2; - my = motion_y / 2; - dxy = ((my & 1) << 1) | (mx & 1); - mx >>= 1; - my >>= 1; - } - - src_x = s->mb_x * 8 + mx; - src_y = s->mb_y * 8 + my; - src_x = av_clip(src_x, -8, s->width >> 1); - if (src_x == (s->width >> 1)) - dxy &= ~1; - src_y = av_clip(src_y, -8, s->height >> 1); - if (src_y == (s->height >> 1)) - dxy &= ~2; - offset = (src_y * uvlinesize) + src_x; - ptr = ref_picture[1] + offset; - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, - src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - } - pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1); - - ptr = ref_picture[2] + offset; - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, - src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - } - pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/wmv2.h b/tizen/distrib/ffmpeg/libavcodec/wmv2.h deleted file mode 100644 index c69c9f4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmv2.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2002 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_WMV2_H -#define AVCODEC_WMV2_H - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "intrax8.h" - -#define SKIP_TYPE_NONE 0 -#define SKIP_TYPE_MPEG 1 -#define SKIP_TYPE_ROW 2 -#define SKIP_TYPE_COL 3 - - -typedef struct Wmv2Context{ - MpegEncContext s; - IntraX8Context x8; - int j_type_bit; - int j_type; - int abt_flag; - int abt_type; - int abt_type_table[6]; - int per_mb_abt; - int per_block_abt; - int mspel_bit; - int cbp_table_index; - int top_left_mv_flag; - int per_mb_rl_bit; - int skip_type; - int hshift; - - ScanTable abt_scantable[2]; - DECLARE_ALIGNED(16, DCTELEM, abt_block2)[6][64]; -}Wmv2Context; - -void ff_wmv2_common_init(Wmv2Context * w); - -#endif /* AVCODEC_WMV2_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/wmv2dec.c b/tizen/distrib/ffmpeg/libavcodec/wmv2dec.c deleted file mode 100644 index a9bb80c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmv2dec.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Copyright (c) 2002 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "mpegvideo.h" -#include "h263.h" -#include "mathops.h" -#include "msmpeg4.h" -#include "msmpeg4data.h" -#include "intrax8.h" -#include "wmv2.h" - - -static void parse_mb_skip(Wmv2Context * w){ - int mb_x, mb_y; - MpegEncContext * const s= &w->s; - uint32_t * const mb_type= s->current_picture_ptr->mb_type; - - w->skip_type= get_bits(&s->gb, 2); - switch(w->skip_type){ - case SKIP_TYPE_NONE: - for(mb_y=0; mb_ymb_height; mb_y++){ - for(mb_x=0; mb_xmb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_16x16 | MB_TYPE_L0; - } - } - break; - case SKIP_TYPE_MPEG: - for(mb_y=0; mb_ymb_height; mb_y++){ - for(mb_x=0; mb_xmb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; - } - } - break; - case SKIP_TYPE_ROW: - for(mb_y=0; mb_ymb_height; mb_y++){ - if(get_bits1(&s->gb)){ - for(mb_x=0; mb_xmb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - } - }else{ - for(mb_x=0; mb_xmb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; - } - } - } - break; - case SKIP_TYPE_COL: - for(mb_x=0; mb_xmb_width; mb_x++){ - if(get_bits1(&s->gb)){ - for(mb_y=0; mb_ymb_height; mb_y++){ - mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - } - }else{ - for(mb_y=0; mb_ymb_height; mb_y++){ - mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; - } - } - } - break; - } -} - -static int decode_ext_header(Wmv2Context *w){ - MpegEncContext * const s= &w->s; - GetBitContext gb; - int fps; - int code; - - if(s->avctx->extradata_size<4) return -1; - - init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); - - fps = get_bits(&gb, 5); - s->bit_rate = get_bits(&gb, 11)*1024; - w->mspel_bit = get_bits1(&gb); - s->loop_filter = get_bits1(&gb); - w->abt_flag = get_bits1(&gb); - w->j_type_bit = get_bits1(&gb); - w->top_left_mv_flag= get_bits1(&gb); - w->per_mb_rl_bit = get_bits1(&gb); - code = get_bits(&gb, 3); - - if(code==0) return -1; - - s->slice_height = s->mb_height / code; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, tl_mv_flag:%d, mbrl_bit:%d, code:%d, loop_filter:%d, slices:%d\n", - fps, s->bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit, w->top_left_mv_flag, w->per_mb_rl_bit, code, s->loop_filter, - code); - } - return 0; -} - -int ff_wmv2_decode_picture_header(MpegEncContext * s) -{ - Wmv2Context * const w= (Wmv2Context*)s; - int code; - -#if 0 -{ -int i; -for(i=0; igb.size*8; i++) - printf("%d", get_bits1(&s->gb)); -// get_bits1(&s->gb); -printf("END\n"); -return -1; -} -#endif - if(s->picture_number==0) - decode_ext_header(w); - - s->pict_type = get_bits1(&s->gb) + 1; - if(s->pict_type == FF_I_TYPE){ - code = get_bits(&s->gb, 7); - av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code); - } - s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); - if(s->qscale <= 0) - return -1; - - return 0; -} - -int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s) -{ - Wmv2Context * const w= (Wmv2Context*)s; - - if (s->pict_type == FF_I_TYPE) { - if(w->j_type_bit) w->j_type= get_bits1(&s->gb); - else w->j_type= 0; //FIXME check - - if(!w->j_type){ - if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_chroma_table_index = decode012(&s->gb); - s->rl_table_index = decode012(&s->gb); - } - - s->dc_table_index = get_bits1(&s->gb); - } - s->inter_intra_pred= 0; - s->no_rounding = 1; - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n", - s->qscale, - s->rl_chroma_table_index, - s->rl_table_index, - s->dc_table_index, - s->per_mb_rl_table, - w->j_type); - } - }else{ - int cbp_index; - w->j_type=0; - - parse_mb_skip(w); - cbp_index= decode012(&s->gb); - if(s->qscale <= 10){ - int map[3]= {0,2,1}; - w->cbp_table_index= map[cbp_index]; - }else if(s->qscale <= 20){ - int map[3]= {1,0,2}; - w->cbp_table_index= map[cbp_index]; - }else{ - int map[3]= {2,1,0}; - w->cbp_table_index= map[cbp_index]; - } - - if(w->mspel_bit) s->mspel= get_bits1(&s->gb); - else s->mspel= 0; //FIXME check - - if(w->abt_flag){ - w->per_mb_abt= get_bits1(&s->gb)^1; - if(!w->per_mb_abt){ - w->abt_type= decode012(&s->gb); - } - } - - if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - s->dc_table_index = get_bits1(&s->gb); - s->mv_table_index = get_bits1(&s->gb); - - s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); - s->no_rounding ^= 1; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d mspel:%d per_mb_abt:%d abt_type:%d cbp:%d ii:%d\n", - s->rl_table_index, - s->rl_chroma_table_index, - s->dc_table_index, - s->mv_table_index, - s->per_mb_rl_table, - s->qscale, - s->mspel, - w->per_mb_abt, - w->abt_type, - w->cbp_table_index, - s->inter_intra_pred); - } - } - s->esc3_level_length= 0; - s->esc3_run_length= 0; - -s->picture_number++; //FIXME ? - - - if(w->j_type){ - ff_intrax8_decode_picture(&w->x8, 2*s->qscale, (s->qscale-1)|1 ); - return 1; - } - - return 0; -} - -static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){ - MpegEncContext * const s= &w->s; - int ret; - - ret= ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr); - - if(ret<0) return -1; - - if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel) - w->hshift= get_bits1(&s->gb); - else - w->hshift= 0; - -//printf("%d %d ", *mx_ptr, *my_ptr); - - return 0; -} - -static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ - MpegEncContext * const s= &w->s; - int xy, wrap, diff, type; - int16_t *A, *B, *C, *mot_val; - - wrap = s->b8_stride; - xy = s->block_index[0]; - - mot_val = s->current_picture.motion_val[0][xy]; - - A = s->current_picture.motion_val[0][xy - 1]; - B = s->current_picture.motion_val[0][xy - wrap]; - C = s->current_picture.motion_val[0][xy + 2 - wrap]; - - if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) - diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1])); - else - diff=0; - - if(diff >= 8) - type= get_bits1(&s->gb); - else - type= 2; - - if(type == 0){ - *px= A[0]; - *py= A[1]; - }else if(type == 1){ - *px= B[0]; - *py= B[1]; - }else{ - /* special case for first (slice) line */ - if (s->first_slice_line) { - *px = A[0]; - *py = A[1]; - } else { - *px = mid_pred(A[0], B[0], C[0]); - *py = mid_pred(A[1], B[1], C[1]); - } - } - - return mot_val; -} - -static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){ - MpegEncContext * const s= &w->s; - static const int sub_cbp_table[3]= {2,3,1}; - int sub_cbp; - - if(!cbp){ - s->block_last_index[n] = -1; - - return 0; - } - - if(w->per_block_abt) - w->abt_type= decode012(&s->gb); -#if 0 - if(w->per_block_abt) - printf("B%d", w->abt_type); -#endif - w->abt_type_table[n]= w->abt_type; - - if(w->abt_type){ -// const uint8_t *scantable= w->abt_scantable[w->abt_type-1].permutated; - const uint8_t *scantable= w->abt_scantable[w->abt_type-1].scantable; -// const uint8_t *scantable= w->abt_type-1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable; - - sub_cbp= sub_cbp_table[ decode012(&s->gb) ]; -// printf("S%d", sub_cbp); - - if(sub_cbp&1){ - if (ff_msmpeg4_decode_block(s, block, n, 1, scantable) < 0) - return -1; - } - - if(sub_cbp&2){ - if (ff_msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0) - return -1; - } - s->block_last_index[n] = 63; - - return 0; - }else{ - return ff_msmpeg4_decode_block(s, block, n, 1, s->inter_scantable.permutated); - } -} - - -int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) -{ - Wmv2Context * const w= (Wmv2Context*)s; - int cbp, code, i; - uint8_t *coded_val; - - if(w->j_type) return 0; - - if (s->pict_type == FF_P_TYPE) { - if(IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])){ - /* 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->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - w->hshift=0; - return 0; - } - - code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3); - if (code < 0) - return -1; - s->mb_intra = (~code & 0x40) >> 6; - - cbp = code & 0x3f; - } else { - s->mb_intra = 1; - code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - /* predict coded block pattern */ - cbp = 0; - for(i=0;i<6;i++) { - int val = ((code >> (5 - i)) & 1); - if (i < 4) { - int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); - val = val ^ pred; - *coded_val = val; - } - cbp |= val << (5 - i); - } - } - - if (!s->mb_intra) { - int mx, my; -//printf("P at %d %d\n", s->mb_x, s->mb_y); - wmv2_pred_motion(w, &mx, &my); - - if(cbp){ - s->dsp.clear_blocks(s->block[0]); - if(s->per_mb_rl_table){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - if(w->abt_flag && w->per_mb_abt){ - w->per_block_abt= get_bits1(&s->gb); - if(!w->per_block_abt) - w->abt_type= decode012(&s->gb); - }else - w->per_block_abt=0; - } - - if (wmv2_decode_motion(w, &mx, &my) < 0) - return -1; - - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - - for (i = 0; i < 6; i++) { - if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding inter block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - } else { -//if(s->pict_type==FF_P_TYPE) -// printf("%d%d ", s->inter_intra_pred, cbp); -//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); - s->ac_pred = get_bits1(&s->gb); - if(s->inter_intra_pred){ - s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); -// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); - } - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding intra block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - } - - return 0; -} - -static av_cold int wmv2_decode_init(AVCodecContext *avctx){ - Wmv2Context * const w= avctx->priv_data; - - if(avctx->idct_algo==FF_IDCT_AUTO){ - avctx->idct_algo=FF_IDCT_WMV2; - } - - if(ff_msmpeg4_decode_init(avctx) < 0) - return -1; - - ff_wmv2_common_init(w); - - ff_intrax8_common_init(&w->x8,&w->s); - - return 0; -} - -static av_cold int wmv2_decode_end(AVCodecContext *avctx) -{ - Wmv2Context *w = avctx->priv_data; - - ff_intrax8_common_end(&w->x8); - return ff_h263_decode_end(avctx); -} - -AVCodec wmv2_decoder = { - "wmv2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WMV2, - sizeof(Wmv2Context), - wmv2_decode_init, - NULL, - wmv2_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), - .pix_fmts= ff_pixfmt_list_420, -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/wmv2enc.c b/tizen/distrib/ffmpeg/libavcodec/wmv2enc.c deleted file mode 100644 index 7416f85..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wmv2enc.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2002 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "mpegvideo.h" -#include "msmpeg4.h" -#include "msmpeg4data.h" -#include "h263.h" -#include "wmv2.h" - - -static int encode_ext_header(Wmv2Context *w){ - MpegEncContext * const s= &w->s; - PutBitContext pb; - int code; - - init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size); - - put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 - put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); - - put_bits(&pb, 1, w->mspel_bit=1); - put_bits(&pb, 1, s->loop_filter); - put_bits(&pb, 1, w->abt_flag=1); - put_bits(&pb, 1, w->j_type_bit=1); - put_bits(&pb, 1, w->top_left_mv_flag=0); - put_bits(&pb, 1, w->per_mb_rl_bit=1); - put_bits(&pb, 3, code=1); - - flush_put_bits(&pb); - - s->slice_height = s->mb_height / code; - - return 0; -} - -static av_cold int wmv2_encode_init(AVCodecContext *avctx){ - Wmv2Context * const w= avctx->priv_data; - - if(MPV_encode_init(avctx) < 0) - return -1; - - ff_wmv2_common_init(w); - - avctx->extradata_size= 4; - avctx->extradata= av_mallocz(avctx->extradata_size + 10); - encode_ext_header(w); - - return 0; -} - -int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number) -{ - Wmv2Context * const w= (Wmv2Context*)s; - - put_bits(&s->pb, 1, s->pict_type - 1); - if(s->pict_type == FF_I_TYPE){ - put_bits(&s->pb, 7, 0); - } - put_bits(&s->pb, 5, s->qscale); - - s->dc_table_index = 1; - s->mv_table_index = 1; /* only if P frame */ - s->per_mb_rl_table = 0; - s->mspel= 0; - w->per_mb_abt=0; - w->abt_type=0; - w->j_type=0; - - assert(s->flipflop_rounding); - - if (s->pict_type == FF_I_TYPE) { - assert(s->no_rounding==1); - if(w->j_type_bit) put_bits(&s->pb, 1, w->j_type); - - if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); - - if(!s->per_mb_rl_table){ - ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); - ff_msmpeg4_code012(&s->pb, s->rl_table_index); - } - - put_bits(&s->pb, 1, s->dc_table_index); - - s->inter_intra_pred= 0; - }else{ - int cbp_index; - - put_bits(&s->pb, 2, SKIP_TYPE_NONE); - - ff_msmpeg4_code012(&s->pb, cbp_index=0); - if(s->qscale <= 10){ - int map[3]= {0,2,1}; - w->cbp_table_index= map[cbp_index]; - }else if(s->qscale <= 20){ - int map[3]= {1,0,2}; - w->cbp_table_index= map[cbp_index]; - }else{ - int map[3]= {2,1,0}; - w->cbp_table_index= map[cbp_index]; - } - - if(w->mspel_bit) put_bits(&s->pb, 1, s->mspel); - - if(w->abt_flag){ - put_bits(&s->pb, 1, w->per_mb_abt^1); - if(!w->per_mb_abt){ - ff_msmpeg4_code012(&s->pb, w->abt_type); - } - } - - if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); - - if(!s->per_mb_rl_table){ - ff_msmpeg4_code012(&s->pb, s->rl_table_index); - s->rl_chroma_table_index = s->rl_table_index; - } - put_bits(&s->pb, 1, s->dc_table_index); - put_bits(&s->pb, 1, s->mv_table_index); - - s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); - } - s->esc3_level_length= 0; - s->esc3_run_length= 0; - - return 0; -} - -/* Nearly identical to wmv1 but that is just because we do not use the - * useless M$ crap features. It is duplicated here in case someone wants - * to add support for these crap features. */ -void ff_wmv2_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y) -{ - Wmv2Context * const w= (Wmv2Context*)s; - int cbp, coded_cbp, i; - int pred_x, pred_y; - uint8_t *coded_block; - - ff_msmpeg4_handle_slices(s); - - if (!s->mb_intra) { - /* compute cbp */ - cbp = 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } - - put_bits(&s->pb, - wmv2_inter_table[w->cbp_table_index][cbp + 64][1], - wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); - - /* motion vector */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - ff_msmpeg4_encode_motion(s, motion_x - pred_x, - motion_y - pred_y); - } else { - /* compute cbp */ - cbp = 0; - coded_cbp = 0; - for (i = 0; i < 6; i++) { - int val, pred; - val = (s->block_last_index[i] >= 1); - cbp |= val << (5 - i); - if (i < 4) { - /* predict value for close blocks only for luma */ - pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); - *coded_block = val; - val = val ^ pred; - } - coded_cbp |= val << (5 - i); - } - - if (s->pict_type == FF_I_TYPE) { - put_bits(&s->pb, - ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); - } else { - put_bits(&s->pb, - wmv2_inter_table[w->cbp_table_index][cbp][1], - wmv2_inter_table[w->cbp_table_index][cbp][0]); - } - put_bits(&s->pb, 1, 0); /* no AC prediction yet */ - if(s->inter_intra_pred){ - s->h263_aic_dir=0; - put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); - } - } - - for (i = 0; i < 6; i++) { - ff_msmpeg4_encode_block(s, block[i], i); - } -} - -AVCodec wmv2_encoder = { - "wmv2", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WMV2, - sizeof(Wmv2Context), - wmv2_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 8"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/wnv1.c b/tizen/distrib/ffmpeg/libavcodec/wnv1.c deleted file mode 100644 index 56634d1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/wnv1.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Winnov WNV1 codec - * Copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Winnov WNV1 codec. - */ - -#include "avcodec.h" -#include "get_bits.h" -#include "libavutil/common.h" - - -typedef struct WNV1Context{ - AVCodecContext *avctx; - AVFrame pic; - - int shift; - GetBitContext gb; -} WNV1Context; - -static const uint16_t code_tab[16][2]={ -{0x1FD,9}, {0xFD,8}, {0x7D,7}, {0x3D,6}, {0x1D,5}, {0x0D,4}, {0x005,3}, -{0x000,1}, -{0x004,3}, {0x0C,4}, {0x1C,5}, {0x3C,6}, {0x7C,7}, {0xFC,8}, {0x1FC,9}, {0xFF,8} -}; - -#define CODE_VLC_BITS 9 -static VLC code_vlc; - -/* returns modified base_value */ -static inline int wnv1_get_code(WNV1Context *w, int base_value) -{ - int v = get_vlc2(&w->gb, code_vlc.table, CODE_VLC_BITS, 1); - - if(v==15) - return av_reverse[ get_bits(&w->gb, 8 - w->shift) ]; - else - return base_value + ((v - 7)<shift); -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - WNV1Context * const l = avctx->priv_data; - AVFrame * const p= (AVFrame*)&l->pic; - unsigned char *Y,*U,*V; - int i, j; - int prev_y = 0, prev_u = 0, prev_v = 0; - uint8_t *rbuf; - - rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if(!rbuf){ - av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); - return -1; - } - - 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"); - av_free(rbuf); - return -1; - } - p->key_frame = 1; - - for(i=8; igb, rbuf+8, (buf_size-8)*8); - - if (buf[2] >> 4 == 6) - l->shift = 2; - else { - l->shift = 8 - (buf[2] >> 4); - if (l->shift > 4) { - av_log(avctx, AV_LOG_ERROR, "Unknown WNV1 frame header value %i, please upload file for study\n", buf[2] >> 4); - l->shift = 4; - } - if (l->shift < 1) { - av_log(avctx, AV_LOG_ERROR, "Unknown WNV1 frame header value %i, please upload file for study\n", buf[2] >> 4); - l->shift = 1; - } - } - - Y = p->data[0]; - U = p->data[1]; - V = p->data[2]; - for (j = 0; j < avctx->height; j++) { - for (i = 0; i < avctx->width / 2; i++) { - Y[i * 2] = wnv1_get_code(l, prev_y); - prev_u = U[i] = wnv1_get_code(l, prev_u); - prev_y = Y[(i * 2) + 1] = wnv1_get_code(l, Y[i * 2]); - prev_v = V[i] = wnv1_get_code(l, prev_v); - } - Y += p->linesize[0]; - U += p->linesize[1]; - V += p->linesize[2]; - } - - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = l->pic; - av_free(rbuf); - - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx){ - WNV1Context * const l = avctx->priv_data; - static VLC_TYPE code_table[1 << CODE_VLC_BITS][2]; - - l->avctx = avctx; - avctx->pix_fmt = PIX_FMT_YUV422P; - - code_vlc.table = code_table; - code_vlc.table_allocated = 1 << CODE_VLC_BITS; - init_vlc(&code_vlc, CODE_VLC_BITS, 16, - &code_tab[0][1], 4, 2, - &code_tab[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC); - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - WNV1Context * const l = avctx->priv_data; - AVFrame *pic = &l->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - -AVCodec wnv1_decoder = { - "wnv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_WNV1, - sizeof(WNV1Context), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/ws-snd1.c b/tizen/distrib/ffmpeg/libavcodec/ws-snd1.c deleted file mode 100644 index a383673..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/ws-snd1.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Westwood SNDx codecs - * Copyright (c) 2005 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -/** - * @file - * Westwood SNDx codecs. - * - * Reference documents about VQA format and its audio codecs - * can be found here: - * http://www.multimedia.cx - */ - -static const char ws_adpcm_2bit[] = { -2, -1, 0, 1}; -static const char ws_adpcm_4bit[] = { - -9, -8, -6, -5, -4, -3, -2, -1, - 0, 1, 2, 3, 4, 5, 6, 8 }; - -#define CLIP8(a) if(a>127)a=127;if(a<-128)a=-128; - -static av_cold int ws_snd_decode_init(AVCodecContext * avctx) -{ -// WSSNDContext *c = avctx->priv_data; - - avctx->sample_fmt = SAMPLE_FMT_S16; - return 0; -} - -static int ws_snd_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; -// WSSNDContext *c = avctx->priv_data; - - int in_size, out_size; - int sample = 0; - int i; - short *samples = data; - - if (!buf_size) - return 0; - - out_size = AV_RL16(&buf[0]); - *data_size = out_size * 2; - in_size = AV_RL16(&buf[2]); - buf += 4; - - if (out_size > *data_size) { - av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); - return -1; - } - if (in_size > buf_size) { - av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n"); - return -1; - } - if (in_size == out_size) { - for (i = 0; i < out_size; i++) - *samples++ = (*buf++ - 0x80) << 8; - return buf_size; - } - - while (out_size > 0) { - int code; - uint8_t count; - code = (*buf) >> 6; - count = (*buf) & 0x3F; - buf++; - switch(code) { - case 0: /* ADPCM 2-bit */ - for (count++; count > 0; count--) { - code = *buf++; - sample += ws_adpcm_2bit[code & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; - sample += ws_adpcm_2bit[(code >> 2) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; - sample += ws_adpcm_2bit[(code >> 4) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; - sample += ws_adpcm_2bit[(code >> 6) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; - out_size -= 4; - } - break; - case 1: /* ADPCM 4-bit */ - for (count++; count > 0; count--) { - code = *buf++; - sample += ws_adpcm_4bit[code & 0xF]; - CLIP8(sample); - *samples++ = sample << 8; - sample += ws_adpcm_4bit[code >> 4]; - CLIP8(sample); - *samples++ = sample << 8; - out_size -= 2; - } - break; - case 2: /* no compression */ - if (count & 0x20) { /* big delta */ - char t; - t = count; - t <<= 3; - sample += t >> 3; - *samples++ = sample << 8; - out_size--; - } else { /* copy */ - for (count++; count > 0; count--) { - *samples++ = (*buf++ - 0x80) << 8; - out_size--; - } - sample = buf[-1] - 0x80; - } - break; - default: /* run */ - for(count++; count > 0; count--) { - *samples++ = sample << 8; - out_size--; - } - } - } - - return buf_size; -} - -AVCodec ws_snd1_decoder = { - "ws_snd1", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_WESTWOOD_SND1, - 0, - ws_snd_decode_init, - NULL, - NULL, - ws_snd_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/Makefile b/tizen/distrib/ffmpeg/libavcodec/x86/Makefile deleted file mode 100644 index f4d0c84..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o -OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp.o - -YASM-OBJS-FFT-$(HAVE_AMD3DNOW) += x86/fft_3dn.o -YASM-OBJS-FFT-$(HAVE_AMD3DNOWEXT) += x86/fft_3dn2.o -YASM-OBJS-FFT-$(HAVE_SSE) += x86/fft_sse.o -YASM-OBJS-$(CONFIG_FFT) += x86/fft_mmx.o \ - $(YASM-OBJS-FFT-yes) -YASM-OBJS-$(CONFIG_GPL) += x86/h264_deblock_sse2.o \ - x86/h264_idct_sse2.o \ - -MMX-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp_mmx.o -MMX-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_mmx.o -MMX-OBJS-$(CONFIG_GPL) += x86/idct_mmx.o -MMX-OBJS-$(CONFIG_LPC) += x86/lpc_mmx.o -MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o -MMX-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_mmx.o -MMX-OBJS-$(CONFIG_VP3_DECODER) += x86/vp3dsp_mmx.o \ - x86/vp3dsp_sse2.o -MMX-OBJS-$(CONFIG_VP5_DECODER) += x86/vp3dsp_mmx.o \ - x86/vp3dsp_sse2.o -MMX-OBJS-$(CONFIG_VP6_DECODER) += x86/vp3dsp_mmx.o \ - x86/vp3dsp_sse2.o \ - x86/vp6dsp_mmx.o \ - x86/vp6dsp_sse2.o -MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \ - $(YASM-OBJS-yes) - -MMX-OBJS-$(CONFIG_FFT) += x86/fft.o - -OBJS-$(HAVE_MMX) += x86/cpuid.o \ - x86/dnxhd_mmx.o \ - x86/dsputil_mmx.o \ - x86/fdct_mmx.o \ - x86/idct_mmx_xvid.o \ - x86/idct_sse2_xvid.o \ - x86/motion_est_mmx.o \ - x86/mpegvideo_mmx.o \ - x86/simple_idct_mmx.o \ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/cavsdsp_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/cavsdsp_mmx.c deleted file mode 100644 index 638eaf7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/cavsdsp_mmx.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * Copyright (c) 2006 Stefan Gehrer - * - * MMX-optimized DSP functions, based on H.264 optimizations by - * Michael Niedermayer and Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "dsputil_mmx.h" - -/***************************************************************************** - * - * inverse transform - * - ****************************************************************************/ - -static inline void cavs_idct8_1d(int16_t *block, uint64_t bias) -{ - __asm__ volatile( - "movq 112(%0), %%mm4 \n\t" /* mm4 = src7 */ - "movq 16(%0), %%mm5 \n\t" /* mm5 = src1 */ - "movq 80(%0), %%mm2 \n\t" /* mm2 = src5 */ - "movq 48(%0), %%mm7 \n\t" /* mm7 = src3 */ - "movq %%mm4, %%mm0 \n\t" - "movq %%mm5, %%mm3 \n\t" - "movq %%mm2, %%mm6 \n\t" - "movq %%mm7, %%mm1 \n\t" - - "paddw %%mm4, %%mm4 \n\t" /* mm4 = 2*src7 */ - "paddw %%mm3, %%mm3 \n\t" /* mm3 = 2*src1 */ - "paddw %%mm6, %%mm6 \n\t" /* mm6 = 2*src5 */ - "paddw %%mm1, %%mm1 \n\t" /* mm1 = 2*src3 */ - "paddw %%mm4, %%mm0 \n\t" /* mm0 = 3*src7 */ - "paddw %%mm3, %%mm5 \n\t" /* mm5 = 3*src1 */ - "paddw %%mm6, %%mm2 \n\t" /* mm2 = 3*src5 */ - "paddw %%mm1, %%mm7 \n\t" /* mm7 = 3*src3 */ - "psubw %%mm4, %%mm5 \n\t" /* mm5 = 3*src1 - 2*src7 = a0 */ - "paddw %%mm6, %%mm7 \n\t" /* mm7 = 3*src3 + 2*src5 = a1 */ - "psubw %%mm2, %%mm1 \n\t" /* mm1 = 2*src3 - 3*src5 = a2 */ - "paddw %%mm0, %%mm3 \n\t" /* mm3 = 2*src1 + 3*src7 = a3 */ - - "movq %%mm5, %%mm4 \n\t" - "movq %%mm7, %%mm6 \n\t" - "movq %%mm3, %%mm0 \n\t" - "movq %%mm1, %%mm2 \n\t" - SUMSUB_BA( %%mm7, %%mm5 ) /* mm7 = a0 + a1 mm5 = a0 - a1 */ - "paddw %%mm3, %%mm7 \n\t" /* mm7 = a0 + a1 + a3 */ - "paddw %%mm1, %%mm5 \n\t" /* mm5 = a0 - a1 + a2 */ - "paddw %%mm7, %%mm7 \n\t" - "paddw %%mm5, %%mm5 \n\t" - "paddw %%mm6, %%mm7 \n\t" /* mm7 = b4 */ - "paddw %%mm4, %%mm5 \n\t" /* mm5 = b5 */ - - SUMSUB_BA( %%mm1, %%mm3 ) /* mm1 = a3 + a2 mm3 = a3 - a2 */ - "psubw %%mm1, %%mm4 \n\t" /* mm4 = a0 - a2 - a3 */ - "movq %%mm4, %%mm1 \n\t" /* mm1 = a0 - a2 - a3 */ - "psubw %%mm6, %%mm3 \n\t" /* mm3 = a3 - a2 - a1 */ - "paddw %%mm1, %%mm1 \n\t" - "paddw %%mm3, %%mm3 \n\t" - "psubw %%mm2, %%mm1 \n\t" /* mm1 = b7 */ - "paddw %%mm0, %%mm3 \n\t" /* mm3 = b6 */ - - "movq 32(%0), %%mm2 \n\t" /* mm2 = src2 */ - "movq 96(%0), %%mm6 \n\t" /* mm6 = src6 */ - "movq %%mm2, %%mm4 \n\t" - "movq %%mm6, %%mm0 \n\t" - "psllw $2, %%mm4 \n\t" /* mm4 = 4*src2 */ - "psllw $2, %%mm6 \n\t" /* mm6 = 4*src6 */ - "paddw %%mm4, %%mm2 \n\t" /* mm2 = 5*src2 */ - "paddw %%mm6, %%mm0 \n\t" /* mm0 = 5*src6 */ - "paddw %%mm2, %%mm2 \n\t" - "paddw %%mm0, %%mm0 \n\t" - "psubw %%mm0, %%mm4 \n\t" /* mm4 = 4*src2 - 10*src6 = a7 */ - "paddw %%mm2, %%mm6 \n\t" /* mm6 = 4*src6 + 10*src2 = a6 */ - - "movq (%0), %%mm2 \n\t" /* mm2 = src0 */ - "movq 64(%0), %%mm0 \n\t" /* mm0 = src4 */ - SUMSUB_BA( %%mm0, %%mm2 ) /* mm0 = src0+src4 mm2 = src0-src4 */ - "psllw $3, %%mm0 \n\t" - "psllw $3, %%mm2 \n\t" - "paddw %1, %%mm0 \n\t" /* add rounding bias */ - "paddw %1, %%mm2 \n\t" /* add rounding bias */ - - SUMSUB_BA( %%mm6, %%mm0 ) /* mm6 = a4 + a6 mm0 = a4 - a6 */ - SUMSUB_BA( %%mm4, %%mm2 ) /* mm4 = a5 + a7 mm2 = a5 - a7 */ - SUMSUB_BA( %%mm7, %%mm6 ) /* mm7 = dst0 mm6 = dst7 */ - SUMSUB_BA( %%mm5, %%mm4 ) /* mm5 = dst1 mm4 = dst6 */ - SUMSUB_BA( %%mm3, %%mm2 ) /* mm3 = dst2 mm2 = dst5 */ - SUMSUB_BA( %%mm1, %%mm0 ) /* mm1 = dst3 mm0 = dst4 */ - :: "r"(block), "m"(bias) - ); -} - -static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) -{ - int i; - DECLARE_ALIGNED(8, int16_t, b2)[64]; - - for(i=0; i<2; i++){ - DECLARE_ALIGNED(8, uint64_t, tmp); - - cavs_idct8_1d(block+4*i, ff_pw_4); - - __asm__ volatile( - "psraw $3, %%mm7 \n\t" - "psraw $3, %%mm6 \n\t" - "psraw $3, %%mm5 \n\t" - "psraw $3, %%mm4 \n\t" - "psraw $3, %%mm3 \n\t" - "psraw $3, %%mm2 \n\t" - "psraw $3, %%mm1 \n\t" - "psraw $3, %%mm0 \n\t" - "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++){ - cavs_idct8_1d(b2+4*i, ff_pw_64.a); - - __asm__ volatile( - "psraw $7, %%mm7 \n\t" - "psraw $7, %%mm6 \n\t" - "psraw $7, %%mm5 \n\t" - "psraw $7, %%mm4 \n\t" - "psraw $7, %%mm3 \n\t" - "psraw $7, %%mm2 \n\t" - "psraw $7, %%mm1 \n\t" - "psraw $7, %%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); -} - -/***************************************************************************** - * - * motion compensation - * - ****************************************************************************/ - -/* vertical filter [-1 -2 96 42 -7 0] */ -#define QPEL_CAVSV1(A,B,C,D,E,F,OP,MUL2) \ - "movd (%0), "#F" \n\t"\ - "movq "#C", %%mm6 \n\t"\ - "pmullw %5, %%mm6 \n\t"\ - "movq "#D", %%mm7 \n\t"\ - "pmullw "MANGLE(MUL2)", %%mm7\n\t"\ - "psllw $3, "#E" \n\t"\ - "psubw "#E", %%mm6 \n\t"\ - "psraw $3, "#E" \n\t"\ - "paddw %%mm7, %%mm6 \n\t"\ - "paddw "#E", %%mm6 \n\t"\ - "paddw "#B", "#B" \n\t"\ - "pxor %%mm7, %%mm7 \n\t"\ - "add %2, %0 \n\t"\ - "punpcklbw %%mm7, "#F" \n\t"\ - "psubw "#B", %%mm6 \n\t"\ - "psraw $1, "#B" \n\t"\ - "psubw "#A", %%mm6 \n\t"\ - "paddw %4, %%mm6 \n\t"\ - "psraw $7, %%mm6 \n\t"\ - "packuswb %%mm6, %%mm6 \n\t"\ - OP(%%mm6, (%1), A, d) \ - "add %3, %1 \n\t" - -/* vertical filter [ 0 -1 5 5 -1 0] */ -#define QPEL_CAVSV2(A,B,C,D,E,F,OP,MUL2) \ - "movd (%0), "#F" \n\t"\ - "movq "#C", %%mm6 \n\t"\ - "paddw "#D", %%mm6 \n\t"\ - "pmullw %5, %%mm6 \n\t"\ - "add %2, %0 \n\t"\ - "punpcklbw %%mm7, "#F" \n\t"\ - "psubw "#B", %%mm6 \n\t"\ - "psubw "#E", %%mm6 \n\t"\ - "paddw %4, %%mm6 \n\t"\ - "psraw $3, %%mm6 \n\t"\ - "packuswb %%mm6, %%mm6 \n\t"\ - OP(%%mm6, (%1), A, d) \ - "add %3, %1 \n\t" - -/* vertical filter [ 0 -7 42 96 -2 -1] */ -#define QPEL_CAVSV3(A,B,C,D,E,F,OP,MUL2) \ - "movd (%0), "#F" \n\t"\ - "movq "#C", %%mm6 \n\t"\ - "pmullw "MANGLE(MUL2)", %%mm6\n\t"\ - "movq "#D", %%mm7 \n\t"\ - "pmullw %5, %%mm7 \n\t"\ - "psllw $3, "#B" \n\t"\ - "psubw "#B", %%mm6 \n\t"\ - "psraw $3, "#B" \n\t"\ - "paddw %%mm7, %%mm6 \n\t"\ - "paddw "#B", %%mm6 \n\t"\ - "paddw "#E", "#E" \n\t"\ - "pxor %%mm7, %%mm7 \n\t"\ - "add %2, %0 \n\t"\ - "punpcklbw %%mm7, "#F" \n\t"\ - "psubw "#E", %%mm6 \n\t"\ - "psraw $1, "#E" \n\t"\ - "psubw "#F", %%mm6 \n\t"\ - "paddw %4, %%mm6 \n\t"\ - "psraw $7, %%mm6 \n\t"\ - "packuswb %%mm6, %%mm6 \n\t"\ - OP(%%mm6, (%1), A, d) \ - "add %3, %1 \n\t" - - -#define QPEL_CAVSVNUM(VOP,OP,ADD,MUL1,MUL2)\ - 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"\ - VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, MUL2)\ - VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, MUL2)\ - VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, MUL2)\ - VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, MUL2)\ - VOP(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP, MUL2)\ - VOP(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP, MUL2)\ - VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, MUL2)\ - VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, MUL2)\ - \ - : "+a"(src), "+c"(dst)\ - : "S"((x86_reg)srcStride), "r"((x86_reg)dstStride), "m"(ADD), "m"(MUL1)\ - : "memory"\ - );\ - if(h==16){\ - __asm__ volatile(\ - VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, MUL2)\ - VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, MUL2)\ - VOP(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP, MUL2)\ - VOP(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP, MUL2)\ - VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, MUL2)\ - VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, MUL2)\ - VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, MUL2)\ - VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, MUL2)\ - \ - : "+a"(src), "+c"(dst)\ - : "S"((x86_reg)srcStride), "r"((x86_reg)dstStride), "m"(ADD), "m"(MUL1)\ - : "memory"\ - );\ - }\ - src += 4-(h+5)*srcStride;\ - dst += 4-h*dstStride;\ - } - -#define QPEL_CAVS(OPNAME, OP, MMX)\ -static void OPNAME ## cavs_qpel8_h_ ## 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"\ - "pmullw %%mm6, %%mm0 \n\t"\ - "pmullw %%mm6, %%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"\ - "movq %6, %%mm5 \n\t"\ - "paddw %%mm5, %%mm0 \n\t"\ - "paddw %%mm5, %%mm1 \n\t"\ - "psraw $3, %%mm0 \n\t"\ - "psraw $3, %%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"((x86_reg)srcStride), "S"((x86_reg)dstStride), "m"(ff_pw_5), "m"(ff_pw_4)\ - : "memory"\ - );\ -}\ -\ -static inline void OPNAME ## cavs_qpel8or16_v1_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - QPEL_CAVSVNUM(QPEL_CAVSV1,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ -}\ -\ -static inline void OPNAME ## cavs_qpel8or16_v2_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - QPEL_CAVSVNUM(QPEL_CAVSV2,OP,ff_pw_4,ff_pw_5,ff_pw_5) \ -}\ -\ -static inline void OPNAME ## cavs_qpel8or16_v3_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - QPEL_CAVSVNUM(QPEL_CAVSV3,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ -}\ -\ -static void OPNAME ## cavs_qpel8_v1_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 8);\ -}\ -static void OPNAME ## cavs_qpel16_v1_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 16);\ - OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ -}\ -\ -static void OPNAME ## cavs_qpel8_v2_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 8);\ -}\ -static void OPNAME ## cavs_qpel16_v2_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 16);\ - OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ -}\ -\ -static void OPNAME ## cavs_qpel8_v3_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 8);\ -}\ -static void OPNAME ## cavs_qpel16_v3_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 16);\ - OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ -}\ -\ -static void OPNAME ## cavs_qpel16_h_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - OPNAME ## cavs_qpel8_h_ ## MMX(dst , src , dstStride, srcStride);\ - OPNAME ## cavs_qpel8_h_ ## MMX(dst+8, src+8, dstStride, srcStride);\ - src += 8*srcStride;\ - dst += 8*dstStride;\ - OPNAME ## cavs_qpel8_h_ ## MMX(dst , src , dstStride, srcStride);\ - OPNAME ## cavs_qpel8_h_ ## MMX(dst+8, src+8, dstStride, srcStride);\ -}\ - -#define CAVS_MC(OPNAME, SIZE, MMX) \ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## cavs_qpel ## SIZE ## _h_ ## MMX(dst, src, stride, stride);\ -}\ -\ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## cavs_qpel ## SIZE ## _v1_ ## MMX(dst, src, stride, stride);\ -}\ -\ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## cavs_qpel ## SIZE ## _v2_ ## MMX(dst, src, stride, stride);\ -}\ -\ -static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## cavs_qpel ## SIZE ## _v3_ ## MMX(dst, src, stride, stride);\ -}\ - -#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" - -QPEL_CAVS(put_, PUT_OP, 3dnow) -QPEL_CAVS(avg_, AVG_3DNOW_OP, 3dnow) -QPEL_CAVS(put_, PUT_OP, mmx2) -QPEL_CAVS(avg_, AVG_MMX2_OP, mmx2) - -CAVS_MC(put_, 8, 3dnow) -CAVS_MC(put_, 16,3dnow) -CAVS_MC(avg_, 8, 3dnow) -CAVS_MC(avg_, 16,3dnow) -CAVS_MC(put_, 8, mmx2) -CAVS_MC(put_, 16,mmx2) -CAVS_MC(avg_, 8, mmx2) -CAVS_MC(avg_, 16,mmx2) - -void ff_cavsdsp_init_mmx2(DSPContext* c, AVCodecContext *avctx) { -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_mmx2; \ - c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_mmx2; \ - - dspfunc(put_cavs_qpel, 0, 16); - dspfunc(put_cavs_qpel, 1, 8); - dspfunc(avg_cavs_qpel, 0, 16); - dspfunc(avg_cavs_qpel, 1, 8); -#undef dspfunc - c->cavs_idct8_add = cavs_idct8_add_mmx; -} - -void ff_cavsdsp_init_3dnow(DSPContext* c, AVCodecContext *avctx) { -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_3dnow; \ - c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_3dnow; \ - - dspfunc(put_cavs_qpel, 0, 16); - dspfunc(put_cavs_qpel, 1, 8); - dspfunc(avg_cavs_qpel, 0, 16); - dspfunc(avg_cavs_qpel, 1, 8); -#undef dspfunc - c->cavs_idct8_add = cavs_idct8_add_mmx; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/cpuid.c b/tizen/distrib/ffmpeg/libavcodec/x86/cpuid.c deleted file mode 100644 index 1ed4d2e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/cpuid.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * CPU detection code, extracted from mmx.h - * (c)1997-99 by H. Dietz and R. Fisher - * Converted to C and improved by Fabrice Bellard. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" - -#undef printf - -/* 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; - -#if ARCH_X86_32 - x86_reg a, c; - __asm__ volatile ( - /* See if CPUID instruction is supported ... */ - /* ... Get copies of EFLAGS into eax and ecx */ - "pushfl\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" - "popfl\n\t" - - /* ... Get the (hopefully modified) EFLAGS */ - "pushfl\n\t" - "pop %0\n\t" - : "=a" (a), "=c" (c) - : - : "cc" - ); - - if (a == c) - return 0; /* CPUID not supported */ -#endif - - 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 |= FF_MM_MMX; - if (std_caps & (1<<25)) - rval |= FF_MM_MMX2 -#if HAVE_SSE - | FF_MM_SSE; - if (std_caps & (1<<26)) - rval |= FF_MM_SSE2; - if (ecx & 1) - rval |= FF_MM_SSE3; - if (ecx & 0x00000200 ) - rval |= FF_MM_SSSE3; - if (ecx & 0x00080000 ) - rval |= FF_MM_SSE4; - if (ecx & 0x00100000 ) - rval |= FF_MM_SSE42; -#endif - ; - } - - 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 |= FF_MM_3DNOW; - if (ext_caps & (1<<30)) - rval |= FF_MM_3DNOWEXT; - if (ext_caps & (1<<23)) - rval |= FF_MM_MMX; - if (ext_caps & (1<<22)) - rval |= FF_MM_MMX2; - } - -#if 0 - av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s%s%s%s%s\n", - (rval&FF_MM_MMX) ? "MMX ":"", - (rval&FF_MM_MMX2) ? "MMX2 ":"", - (rval&FF_MM_SSE) ? "SSE ":"", - (rval&FF_MM_SSE2) ? "SSE2 ":"", - (rval&FF_MM_SSE3) ? "SSE3 ":"", - (rval&FF_MM_SSSE3) ? "SSSE3 ":"", - (rval&FF_MM_SSE4) ? "SSE4.1 ":"", - (rval&FF_MM_SSE42) ? "SSE4.2 ":"", - (rval&FF_MM_3DNOW) ? "3DNow ":"", - (rval&FF_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/tizen/distrib/ffmpeg/libavcodec/x86/dnxhd_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/dnxhd_mmx.c deleted file mode 100644 index 59bcb39..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dnxhd_mmx.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * VC3/DNxHD SIMD functions - * Copyright (c) 2007 Baptiste Coudurier - * - * VC-3 encoder funded by the British Broadcasting Corporation - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dnxhdenc.h" - -static void get_pixels_8x4_sym_sse2(DCTELEM *block, const uint8_t *pixels, int line_size) -{ - __asm__ volatile( - "pxor %%xmm7, %%xmm7 \n\t" - "movq (%0), %%xmm0 \n\t" - "add %2, %0 \n\t" - "movq (%0), %%xmm1 \n\t" - "movq (%0, %2), %%xmm2 \n\t" - "movq (%0, %2,2), %%xmm3 \n\t" - "punpcklbw %%xmm7, %%xmm0 \n\t" - "punpcklbw %%xmm7, %%xmm1 \n\t" - "punpcklbw %%xmm7, %%xmm2 \n\t" - "punpcklbw %%xmm7, %%xmm3 \n\t" - "movdqa %%xmm0, (%1) \n\t" - "movdqa %%xmm1, 16(%1) \n\t" - "movdqa %%xmm2, 32(%1) \n\t" - "movdqa %%xmm3, 48(%1) \n\t" - "movdqa %%xmm3 , 64(%1) \n\t" - "movdqa %%xmm2 , 80(%1) \n\t" - "movdqa %%xmm1 , 96(%1) \n\t" - "movdqa %%xmm0, 112(%1) \n\t" - : "+r" (pixels) - : "r" (block), "r" ((x86_reg)line_size) - ); -} - -void ff_dnxhd_init_mmx(DNXHDEncContext *ctx) -{ - if (mm_flags & FF_MM_SSE2) { - ctx->get_pixels_8x4_sym = get_pixels_8x4_sym_sse2; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_mmx.c deleted file mode 100644 index bc2379e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_mmx.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2005 Zoltan Hidvegi , - * Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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, const uint64_t *rnd_reg) -{ - 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" - "movq %2, %%mm6\n\t" /* mm6 = rnd >> 3 */ - "punpcklwd %%mm5, %%mm5\n\t" - "punpckldq %%mm5, %%mm5\n\t" /* mm5 = B = x */ - "pxor %%mm7, %%mm7\n\t" - "psubw %%mm5, %%mm4\n\t" /* mm4 = A = 8-x */ - :: "rm"(x+y), "m"(ff_pw_8), "m"(*(rnd_reg+1))); - - for(i=0; i> 3)) >> 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" (*rnd_reg)); - 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, const uint64_t *rnd_reg) -{ - __asm__ volatile( - "pxor %%mm7, %%mm7 \n\t" - "movd %5, %%mm2 \n\t" - "movd %6, %%mm3 \n\t" - "movq "MANGLE(ff_pw_8)", %%mm4\n\t" - "movq "MANGLE(ff_pw_8)", %%mm5\n\t" - "punpcklwd %%mm2, %%mm2 \n\t" - "punpcklwd %%mm3, %%mm3 \n\t" - "punpcklwd %%mm2, %%mm2 \n\t" - "punpcklwd %%mm3, %%mm3 \n\t" - "psubw %%mm2, %%mm4 \n\t" - "psubw %%mm3, %%mm5 \n\t" - - "movd (%1), %%mm0 \n\t" - "movd 1(%1), %%mm6 \n\t" - "add %3, %1 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm6 \n\t" - "pmullw %%mm4, %%mm0 \n\t" - "pmullw %%mm2, %%mm6 \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "1: \n\t" - "movd (%1), %%mm0 \n\t" - "movd 1(%1), %%mm1 \n\t" - "add %3, %1 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "pmullw %%mm4, %%mm0 \n\t" - "pmullw %%mm2, %%mm1 \n\t" - "paddw %%mm0, %%mm1 \n\t" - "movq %%mm1, %%mm0 \n\t" - "pmullw %%mm5, %%mm6 \n\t" - "pmullw %%mm3, %%mm1 \n\t" - "paddw %4, %%mm6 \n\t" - "paddw %%mm6, %%mm1 \n\t" - "psrlw $6, %%mm1 \n\t" - "packuswb %%mm1, %%mm1 \n\t" - H264_CHROMA_OP4((%0), %%mm1, %%mm6) - "movd %%mm1, (%0) \n\t" - "add %3, %0 \n\t" - "movd (%1), %%mm6 \n\t" - "movd 1(%1), %%mm1 \n\t" - "add %3, %1 \n\t" - "punpcklbw %%mm7, %%mm6 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "pmullw %%mm4, %%mm6 \n\t" - "pmullw %%mm2, %%mm1 \n\t" - "paddw %%mm6, %%mm1 \n\t" - "movq %%mm1, %%mm6 \n\t" - "pmullw %%mm5, %%mm0 \n\t" - "pmullw %%mm3, %%mm1 \n\t" - "paddw %4, %%mm0 \n\t" - "paddw %%mm0, %%mm1 \n\t" - "psrlw $6, %%mm1 \n\t" - "packuswb %%mm1, %%mm1 \n\t" - H264_CHROMA_OP4((%0), %%mm1, %%mm0) - "movd %%mm1, (%0) \n\t" - "add %3, %0 \n\t" - "sub $2, %2 \n\t" - "jnz 1b \n\t" - : "+r"(dst), "+r"(src), "+r"(h) - : "r"((x86_reg)stride), "m"(*rnd_reg), "m"(x), "m"(y) - ); -} - -#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 tmp = ((1<<16)-1)*x + 8; - int CD= tmp*y; - int AB= (tmp<<3) - CD; - __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" - /* mm0 = src[0,1,1,2] */ - "movd %2, %%mm2\n\t" - "punpcklbw %%mm7, %%mm2\n\t" - "pshufw $0x94, %%mm2, %%mm2\n\t" - :: "r"(AB), "r"(CD), "m"(src[0])); - - - __asm__ volatile( - "1:\n\t" - "add %4, %1\n\t" - /* mm1 = A * src[0,1] + B * src[1,2] */ - "movq %%mm2, %%mm1\n\t" - "pmaddwd %%mm5, %%mm1\n\t" - /* mm0 = src[0,1,1,2] */ - "movd (%1), %%mm0\n\t" - "punpcklbw %%mm7, %%mm0\n\t" - "pshufw $0x94, %%mm0, %%mm0\n\t" - /* mm1 += C * src[0,1] + D * src[1,2] */ - "movq %%mm0, %%mm2\n\t" - "pmaddwd %%mm6, %%mm0\n\t" - "paddw %3, %%mm1\n\t" - "paddw %%mm0, %%mm1\n\t" - /* dst[0,1] = pack((mm1 + 32) >> 6) */ - "psrlw $6, %%mm1\n\t" - "packssdw %%mm7, %%mm1\n\t" - "packuswb %%mm7, %%mm1\n\t" - H264_CHROMA_OP4((%0), %%mm1, %%mm3) - "movd %%mm1, %%esi\n\t" - "movw %%si, (%0)\n\t" - "add %4, %0\n\t" - "sub $1, %2\n\t" - "jnz 1b\n\t" - : "+r" (dst), "+r"(src), "+r"(h) - : "m" (ff_pw_32), "r"((x86_reg)stride) - : "%esi"); - -} -#endif - diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_ssse3.c b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_ssse3.c deleted file mode 100644 index e29e05e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_h264_template_ssse3.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2008 Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * SSSE3 optimized version of (put|avg)_h264_chroma_mc8. - * H264_CHROMA_MC8_TMPL must be defined to the desired function name - * H264_CHROMA_MC8_MV0 must be defined to a (put|avg)_pixels8 function - * AVG_OP must be defined to empty for put and the identify for avg - */ -static void H264_CHROMA_MC8_TMPL(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y, int rnd) -{ - 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 */ - __asm__ volatile( - "movd %0, %%xmm7 \n\t" - "movq %1, %%xmm6 \n\t" - "pshuflw $0, %%xmm7, %%xmm7 \n\t" - "movlhps %%xmm6, %%xmm6 \n\t" - "movlhps %%xmm7, %%xmm7 \n\t" - :: "r"(255*(x+y)+8), "m"(*(rnd?&ff_pw_4:&ff_pw_3)) - ); - - if(x) { - __asm__ volatile( - "1: \n\t" - "movq (%1), %%xmm0 \n\t" - "movq 1(%1), %%xmm1 \n\t" - "movq (%1,%3), %%xmm2 \n\t" - "movq 1(%1,%3), %%xmm3 \n\t" - "punpcklbw %%xmm1, %%xmm0 \n\t" - "punpcklbw %%xmm3, %%xmm2 \n\t" - "pmaddubsw %%xmm7, %%xmm0 \n\t" - "pmaddubsw %%xmm7, %%xmm2 \n\t" - AVG_OP("movq (%0), %%xmm4 \n\t") - AVG_OP("movhps (%0,%3), %%xmm4 \n\t") - "paddw %%xmm6, %%xmm0 \n\t" - "paddw %%xmm6, %%xmm2 \n\t" - "psrlw $3, %%xmm0 \n\t" - "psrlw $3, %%xmm2 \n\t" - "packuswb %%xmm2, %%xmm0 \n\t" - AVG_OP("pavgb %%xmm4, %%xmm0 \n\t") - "movq %%xmm0, (%0) \n\t" - "movhps %%xmm0, (%0,%3) \n\t" - "sub $2, %2 \n\t" - "lea (%1,%3,2), %1 \n\t" - "lea (%0,%3,2), %0 \n\t" - "jg 1b \n\t" - :"+r"(dst), "+r"(src), "+r"(h) - :"r"((x86_reg)stride) - ); - } else { - __asm__ volatile( - "1: \n\t" - "movq (%1), %%xmm0 \n\t" - "movq (%1,%3), %%xmm1 \n\t" - "movdqa %%xmm1, %%xmm2 \n\t" - "movq (%1,%3,2), %%xmm3 \n\t" - "punpcklbw %%xmm1, %%xmm0 \n\t" - "punpcklbw %%xmm3, %%xmm2 \n\t" - "pmaddubsw %%xmm7, %%xmm0 \n\t" - "pmaddubsw %%xmm7, %%xmm2 \n\t" - AVG_OP("movq (%0), %%xmm4 \n\t") - AVG_OP("movhps (%0,%3), %%xmm4 \n\t") - "paddw %%xmm6, %%xmm0 \n\t" - "paddw %%xmm6, %%xmm2 \n\t" - "psrlw $3, %%xmm0 \n\t" - "psrlw $3, %%xmm2 \n\t" - "packuswb %%xmm2, %%xmm0 \n\t" - AVG_OP("pavgb %%xmm4, %%xmm0 \n\t") - "movq %%xmm0, (%0) \n\t" - "movhps %%xmm0, (%0,%3) \n\t" - "sub $2, %2 \n\t" - "lea (%1,%3,2), %1 \n\t" - "lea (%0,%3,2), %0 \n\t" - "jg 1b \n\t" - :"+r"(dst), "+r"(src), "+r"(h) - :"r"((x86_reg)stride) - ); - } - return; - } - - /* general case, bilinear */ - __asm__ volatile( - "movd %0, %%xmm7 \n\t" - "movd %1, %%xmm6 \n\t" - "movdqa %2, %%xmm5 \n\t" - "pshuflw $0, %%xmm7, %%xmm7 \n\t" - "pshuflw $0, %%xmm6, %%xmm6 \n\t" - "movlhps %%xmm7, %%xmm7 \n\t" - "movlhps %%xmm6, %%xmm6 \n\t" - :: "r"((x*255+8)*(8-y)), "r"((x*255+8)*y), "m"(*(rnd?&ff_pw_32:&ff_pw_28)) - ); - - __asm__ volatile( - "movq (%1), %%xmm0 \n\t" - "movq 1(%1), %%xmm1 \n\t" - "punpcklbw %%xmm1, %%xmm0 \n\t" - "add %3, %1 \n\t" - "1: \n\t" - "movq (%1), %%xmm1 \n\t" - "movq 1(%1), %%xmm2 \n\t" - "movq (%1,%3), %%xmm3 \n\t" - "movq 1(%1,%3), %%xmm4 \n\t" - "lea (%1,%3,2), %1 \n\t" - "punpcklbw %%xmm2, %%xmm1 \n\t" - "punpcklbw %%xmm4, %%xmm3 \n\t" - "movdqa %%xmm1, %%xmm2 \n\t" - "movdqa %%xmm3, %%xmm4 \n\t" - "pmaddubsw %%xmm7, %%xmm0 \n\t" - "pmaddubsw %%xmm6, %%xmm1 \n\t" - "pmaddubsw %%xmm7, %%xmm2 \n\t" - "pmaddubsw %%xmm6, %%xmm3 \n\t" - "paddw %%xmm5, %%xmm0 \n\t" - "paddw %%xmm5, %%xmm2 \n\t" - "paddw %%xmm0, %%xmm1 \n\t" - "paddw %%xmm2, %%xmm3 \n\t" - "movdqa %%xmm4, %%xmm0 \n\t" - "psrlw $6, %%xmm1 \n\t" - "psrlw $6, %%xmm3 \n\t" - AVG_OP("movq (%0), %%xmm2 \n\t") - AVG_OP("movhps (%0,%3), %%xmm2 \n\t") - "packuswb %%xmm3, %%xmm1 \n\t" - AVG_OP("pavgb %%xmm2, %%xmm1 \n\t") - "movq %%xmm1, (%0)\n\t" - "movhps %%xmm1, (%0,%3)\n\t" - "sub $2, %2 \n\t" - "lea (%0,%3,2), %0 \n\t" - "jg 1b \n\t" - :"+r"(dst), "+r"(src), "+r"(h) - :"r"((x86_reg)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) -{ - __asm__ volatile( - "movd %0, %%mm7 \n\t" - "movd %1, %%mm6 \n\t" - "movq %2, %%mm5 \n\t" - "pshufw $0, %%mm7, %%mm7 \n\t" - "pshufw $0, %%mm6, %%mm6 \n\t" - :: "r"((x*255+8)*(8-y)), "r"((x*255+8)*y), "m"(ff_pw_32) - ); - - __asm__ volatile( - "movd (%1), %%mm0 \n\t" - "punpcklbw 1(%1), %%mm0 \n\t" - "add %3, %1 \n\t" - "1: \n\t" - "movd (%1), %%mm1 \n\t" - "movd (%1,%3), %%mm3 \n\t" - "punpcklbw 1(%1), %%mm1 \n\t" - "punpcklbw 1(%1,%3), %%mm3 \n\t" - "lea (%1,%3,2), %1 \n\t" - "movq %%mm1, %%mm2 \n\t" - "movq %%mm3, %%mm4 \n\t" - "pmaddubsw %%mm7, %%mm0 \n\t" - "pmaddubsw %%mm6, %%mm1 \n\t" - "pmaddubsw %%mm7, %%mm2 \n\t" - "pmaddubsw %%mm6, %%mm3 \n\t" - "paddw %%mm5, %%mm0 \n\t" - "paddw %%mm5, %%mm2 \n\t" - "paddw %%mm0, %%mm1 \n\t" - "paddw %%mm2, %%mm3 \n\t" - "movq %%mm4, %%mm0 \n\t" - "psrlw $6, %%mm1 \n\t" - "psrlw $6, %%mm3 \n\t" - "packuswb %%mm1, %%mm1 \n\t" - "packuswb %%mm3, %%mm3 \n\t" - AVG_OP("pavgb (%0), %%mm1 \n\t") - AVG_OP("pavgb (%0,%3), %%mm3 \n\t") - "movd %%mm1, (%0)\n\t" - "movd %%mm3, (%0,%3)\n\t" - "sub $2, %2 \n\t" - "lea (%0,%3,2), %0 \n\t" - "jg 1b \n\t" - :"+r"(dst), "+r"(src), "+r"(h) - :"r"((x86_reg)stride) - ); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.c deleted file mode 100644 index cc2f881..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.c +++ /dev/null @@ -1,3002 +0,0 @@ -/* - * MMX optimized DSP utils - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/h264dsp.h" -#include "libavcodec/mpegvideo.h" -#include "libavcodec/simple_idct.h" -#include "dsputil_mmx.h" -#include "vp3dsp_mmx.h" -#include "vp3dsp_sse2.h" -#include "vp6dsp_mmx.h" -#include "vp6dsp_sse2.h" -#include "idct_xvid.h" - -//#undef NDEBUG -//#include - -int mm_flags; /* multimedia extension flags */ - -/* pixel operations */ -DECLARE_ALIGNED(8, const uint64_t, ff_bone) = 0x0101010101010101ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_wtwo) = 0x0002000200020002ULL; - -DECLARE_ALIGNED(16, const uint64_t, ff_pdw_80000000)[2] = -{0x8000000080000000ULL, 0x8000000080000000ULL}; - -DECLARE_ALIGNED(8, const uint64_t, ff_pw_3 ) = 0x0003000300030003ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_4 ) = 0x0004000400040004ULL; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_5 ) = {0x0005000500050005ULL, 0x0005000500050005ULL}; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_8 ) = {0x0008000800080008ULL, 0x0008000800080008ULL}; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_15 ) = 0x000F000F000F000FULL; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_16 ) = {0x0010001000100010ULL, 0x0010001000100010ULL}; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_20 ) = 0x0014001400140014ULL; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_28 ) = {0x001C001C001C001CULL, 0x001C001C001C001CULL}; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_32 ) = {0x0020002000200020ULL, 0x0020002000200020ULL}; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_42 ) = 0x002A002A002A002AULL; -DECLARE_ALIGNED(16, const xmm_reg, ff_pw_64 ) = {0x0040004000400040ULL, 0x0040004000400040ULL}; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_96 ) = 0x0060006000600060ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL; - -DECLARE_ALIGNED(8, const uint64_t, ff_pb_1 ) = 0x0101010101010101ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_3 ) = 0x0303030303030303ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_7 ) = 0x0707070707070707ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_1F ) = 0x1F1F1F1F1F1F1F1FULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_3F ) = 0x3F3F3F3F3F3F3F3FULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_81 ) = 0x8181818181818181ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_A1 ) = 0xA1A1A1A1A1A1A1A1ULL; -DECLARE_ALIGNED(8, const uint64_t, ff_pb_FC ) = 0xFCFCFCFCFCFCFCFCULL; - -DECLARE_ALIGNED(16, const double, ff_pd_1)[2] = { 1.0, 1.0 }; -DECLARE_ALIGNED(16, const double, ff_pd_2)[2] = { 2.0, 2.0 }; - -#define JUMPALIGN() __asm__ volatile (ASMALIGN(3)::) -#define MOVQ_ZERO(regd) __asm__ volatile ("pxor %%" #regd ", %%" #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"(ff_bone)) -#define MOVQ_WTWO(regd) __asm__ volatile ("movq %0, %%" #regd " \n\t" ::"m"(ff_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) -#define OP_AVG(a, b, c, e) PAVGB_MMX(a, b, c, e) - -#include "dsputil_mmx_rnd_template.c" - -#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_template.c" - -#undef DEF -#undef SET_RND -#undef PAVGBP -#undef PAVGB -#undef OP_AVG - -/***********************************/ -/* 3Dnow specific */ - -#define DEF(x) x ## _3dnow -#define PAVGB "pavgusb" -#define OP_AVG PAVGB - -#include "dsputil_mmx_avg_template.c" - -#undef DEF -#undef PAVGB -#undef OP_AVG - -/***********************************/ -/* MMX2 specific */ - -#define DEF(x) x ## _mmx2 - -/* Introduced only in MMX2 set */ -#define PAVGB "pavgb" -#define OP_AVG PAVGB - -#include "dsputil_mmx_avg_template.c" - -#undef DEF -#undef PAVGB -#undef OP_AVG - -#define put_no_rnd_pixels16_mmx put_pixels16_mmx -#define put_no_rnd_pixels8_mmx put_pixels8_mmx -#define put_pixels16_mmx2 put_pixels16_mmx -#define put_pixels8_mmx2 put_pixels8_mmx -#define put_pixels4_mmx2 put_pixels4_mmx -#define put_no_rnd_pixels16_mmx2 put_no_rnd_pixels16_mmx -#define put_no_rnd_pixels8_mmx2 put_no_rnd_pixels8_mmx -#define put_pixels16_3dnow put_pixels16_mmx -#define put_pixels8_3dnow put_pixels8_mmx -#define put_pixels4_3dnow put_pixels4_mmx -#define put_no_rnd_pixels16_3dnow put_no_rnd_pixels16_mmx -#define put_no_rnd_pixels8_3dnow put_no_rnd_pixels8_mmx - -/***********************************/ -/* standard MMX */ - -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" ((x86_reg)line_size), "r" ((x86_reg)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" ((x86_reg)line_size), "r" ((x86_reg)line_size*3), "r"(p) - :"memory"); -} - -DECLARE_ASM_CONST(8, uint8_t, ff_vector128)[8] = - { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; - -#define put_signed_pixels_clamped_mmx_half(off) \ - "movq "#off"(%2), %%mm1 \n\t"\ - "movq 16+"#off"(%2), %%mm2 \n\t"\ - "movq 32+"#off"(%2), %%mm3 \n\t"\ - "movq 48+"#off"(%2), %%mm4 \n\t"\ - "packsswb 8+"#off"(%2), %%mm1 \n\t"\ - "packsswb 24+"#off"(%2), %%mm2 \n\t"\ - "packsswb 40+"#off"(%2), %%mm3 \n\t"\ - "packsswb 56+"#off"(%2), %%mm4 \n\t"\ - "paddb %%mm0, %%mm1 \n\t"\ - "paddb %%mm0, %%mm2 \n\t"\ - "paddb %%mm0, %%mm3 \n\t"\ - "paddb %%mm0, %%mm4 \n\t"\ - "movq %%mm1, (%0) \n\t"\ - "movq %%mm2, (%0, %3) \n\t"\ - "movq %%mm3, (%0, %3, 2) \n\t"\ - "movq %%mm4, (%0, %1) \n\t" - -void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size) -{ - x86_reg line_skip = line_size; - x86_reg line_skip3; - - __asm__ volatile ( - "movq "MANGLE(ff_vector128)", %%mm0 \n\t" - "lea (%3, %3, 2), %1 \n\t" - put_signed_pixels_clamped_mmx_half(0) - "lea (%0, %3, 4), %0 \n\t" - put_signed_pixels_clamped_mmx_half(64) - :"+&r" (pixels), "=&r" (line_skip3) - :"r" (block), "r"(line_skip) - :"memory"); -} - -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" - ASMALIGN(3) - "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"((x86_reg)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" - ASMALIGN(3) - "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"((x86_reg)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" - ASMALIGN(3) - "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"((x86_reg)line_size) - : "%"REG_a, "memory" - ); -} - -static void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - __asm__ volatile( - "1: \n\t" - "movdqu (%1), %%xmm0 \n\t" - "movdqu (%1,%3), %%xmm1 \n\t" - "movdqu (%1,%3,2), %%xmm2 \n\t" - "movdqu (%1,%4), %%xmm3 \n\t" - "movdqa %%xmm0, (%2) \n\t" - "movdqa %%xmm1, (%2,%3) \n\t" - "movdqa %%xmm2, (%2,%3,2) \n\t" - "movdqa %%xmm3, (%2,%4) \n\t" - "subl $4, %0 \n\t" - "lea (%1,%3,4), %1 \n\t" - "lea (%2,%3,4), %2 \n\t" - "jnz 1b \n\t" - : "+g"(h), "+r" (pixels), "+r" (block) - : "r"((x86_reg)line_size), "r"((x86_reg)3L*line_size) - : "memory" - ); -} - -static void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - __asm__ volatile( - "1: \n\t" - "movdqu (%1), %%xmm0 \n\t" - "movdqu (%1,%3), %%xmm1 \n\t" - "movdqu (%1,%3,2), %%xmm2 \n\t" - "movdqu (%1,%4), %%xmm3 \n\t" - "pavgb (%2), %%xmm0 \n\t" - "pavgb (%2,%3), %%xmm1 \n\t" - "pavgb (%2,%3,2), %%xmm2 \n\t" - "pavgb (%2,%4), %%xmm3 \n\t" - "movdqa %%xmm0, (%2) \n\t" - "movdqa %%xmm1, (%2,%3) \n\t" - "movdqa %%xmm2, (%2,%3,2) \n\t" - "movdqa %%xmm3, (%2,%4) \n\t" - "subl $4, %0 \n\t" - "lea (%1,%3,4), %1 \n\t" - "lea (%2,%3,4), %2 \n\t" - "jnz 1b \n\t" - : "+g"(h), "+r" (pixels), "+r" (block) - : "r"((x86_reg)line_size), "r"((x86_reg)3L*line_size) - : "memory" - ); -} - -#define CLEAR_BLOCKS(name,n) \ -static void name(DCTELEM *blocks)\ -{\ - __asm__ volatile(\ - "pxor %%mm7, %%mm7 \n\t"\ - "mov %1, %%"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*n),\ - "i" (-128*n)\ - : "%"REG_a\ - );\ -} -CLEAR_BLOCKS(clear_blocks_mmx, 6) -CLEAR_BLOCKS(clear_block_mmx, 1) - -static void clear_block_sse(DCTELEM *block) -{ - __asm__ volatile( - "xorps %%xmm0, %%xmm0 \n" - "movaps %%xmm0, (%0) \n" - "movaps %%xmm0, 16(%0) \n" - "movaps %%xmm0, 32(%0) \n" - "movaps %%xmm0, 48(%0) \n" - "movaps %%xmm0, 64(%0) \n" - "movaps %%xmm0, 80(%0) \n" - "movaps %%xmm0, 96(%0) \n" - "movaps %%xmm0, 112(%0) \n" - :: "r"(block) - : "memory" - ); -} - -static void clear_blocks_sse(DCTELEM *blocks) -{\ - __asm__ volatile( - "xorps %%xmm0, %%xmm0 \n" - "mov %1, %%"REG_a" \n" - "1: \n" - "movaps %%xmm0, (%0, %%"REG_a") \n" - "movaps %%xmm0, 16(%0, %%"REG_a") \n" - "movaps %%xmm0, 32(%0, %%"REG_a") \n" - "movaps %%xmm0, 48(%0, %%"REG_a") \n" - "movaps %%xmm0, 64(%0, %%"REG_a") \n" - "movaps %%xmm0, 80(%0, %%"REG_a") \n" - "movaps %%xmm0, 96(%0, %%"REG_a") \n" - "movaps %%xmm0, 112(%0, %%"REG_a") \n" - "add $128, %%"REG_a" \n" - " js 1b \n" - : : "r" (((uint8_t *)blocks)+128*6), - "i" (-128*6) - : "%"REG_a - ); -} - -static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ - x86_reg i=0; - __asm__ volatile( - "jmp 2f \n\t" - "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" - "2: \n\t" - "cmp %3, %0 \n\t" - " js 1b \n\t" - : "+r" (i) - : "r"(src), "r"(dst), "r"((x86_reg)w-15) - ); - for(; i>(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<0) & (a ^ sign(m))) - "movq %%mm3, %1 \n\t" - "movq %%mm0, %0 \n\t" - :"+m"(mag[i]), "+m"(ang[i]) - ::"memory" - ); - } - __asm__ volatile("femms"); -} -static void vorbis_inverse_coupling_sse(float *mag, float *ang, int blocksize) -{ - int i; - - __asm__ volatile( - "movaps %0, %%xmm5 \n\t" - ::"m"(ff_pdw_80000000[0]) - ); - for(i=0; i0) & (a ^ sign(m))) - "movaps %%xmm3, %1 \n\t" - "movaps %%xmm0, %0 \n\t" - :"+m"(mag[i]), "+m"(ang[i]) - ::"memory" - ); - } -} - -#define IF1(x) x -#define IF0(x) - -#define MIX5(mono,stereo)\ - __asm__ volatile(\ - "movss 0(%2), %%xmm5 \n"\ - "movss 8(%2), %%xmm6 \n"\ - "movss 24(%2), %%xmm7 \n"\ - "shufps $0, %%xmm5, %%xmm5 \n"\ - "shufps $0, %%xmm6, %%xmm6 \n"\ - "shufps $0, %%xmm7, %%xmm7 \n"\ - "1: \n"\ - "movaps (%0,%1), %%xmm0 \n"\ - "movaps 0x400(%0,%1), %%xmm1 \n"\ - "movaps 0x800(%0,%1), %%xmm2 \n"\ - "movaps 0xc00(%0,%1), %%xmm3 \n"\ - "movaps 0x1000(%0,%1), %%xmm4 \n"\ - "mulps %%xmm5, %%xmm0 \n"\ - "mulps %%xmm6, %%xmm1 \n"\ - "mulps %%xmm5, %%xmm2 \n"\ - "mulps %%xmm7, %%xmm3 \n"\ - "mulps %%xmm7, %%xmm4 \n"\ - stereo("addps %%xmm1, %%xmm0 \n")\ - "addps %%xmm1, %%xmm2 \n"\ - "addps %%xmm3, %%xmm0 \n"\ - "addps %%xmm4, %%xmm2 \n"\ - mono("addps %%xmm2, %%xmm0 \n")\ - "movaps %%xmm0, (%0,%1) \n"\ - stereo("movaps %%xmm2, 0x400(%0,%1) \n")\ - "add $16, %0 \n"\ - "jl 1b \n"\ - :"+&r"(i)\ - :"r"(samples[0]+len), "r"(matrix)\ - :"memory"\ - ); - -#define MIX_MISC(stereo)\ - __asm__ volatile(\ - "1: \n"\ - "movaps (%3,%0), %%xmm0 \n"\ - stereo("movaps %%xmm0, %%xmm1 \n")\ - "mulps %%xmm6, %%xmm0 \n"\ - stereo("mulps %%xmm7, %%xmm1 \n")\ - "lea 1024(%3,%0), %1 \n"\ - "mov %5, %2 \n"\ - "2: \n"\ - "movaps (%1), %%xmm2 \n"\ - stereo("movaps %%xmm2, %%xmm3 \n")\ - "mulps (%4,%2), %%xmm2 \n"\ - stereo("mulps 16(%4,%2), %%xmm3 \n")\ - "addps %%xmm2, %%xmm0 \n"\ - stereo("addps %%xmm3, %%xmm1 \n")\ - "add $1024, %1 \n"\ - "add $32, %2 \n"\ - "jl 2b \n"\ - "movaps %%xmm0, (%3,%0) \n"\ - stereo("movaps %%xmm1, 1024(%3,%0) \n")\ - "add $16, %0 \n"\ - "jl 1b \n"\ - :"+&r"(i), "=&r"(j), "=&r"(k)\ - :"r"(samples[0]+len), "r"(matrix_simd+in_ch), "g"((intptr_t)-32*(in_ch-1))\ - :"memory"\ - ); - -static void ac3_downmix_sse(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len) -{ - int (*matrix_cmp)[2] = (int(*)[2])matrix; - intptr_t i,j,k; - - i = -len*sizeof(float); - if(in_ch == 5 && out_ch == 2 && !(matrix_cmp[0][1]|matrix_cmp[2][0]|matrix_cmp[3][1]|matrix_cmp[4][0]|(matrix_cmp[1][0]^matrix_cmp[1][1])|(matrix_cmp[0][0]^matrix_cmp[2][1]))) { - MIX5(IF0,IF1); - } else if(in_ch == 5 && out_ch == 1 && matrix_cmp[0][0]==matrix_cmp[2][0] && matrix_cmp[3][0]==matrix_cmp[4][0]) { - MIX5(IF1,IF0); - } else { - DECLARE_ALIGNED(16, float, matrix_simd)[in_ch][2][4]; - j = 2*in_ch*sizeof(float); - __asm__ volatile( - "1: \n" - "sub $8, %0 \n" - "movss (%2,%0), %%xmm6 \n" - "movss 4(%2,%0), %%xmm7 \n" - "shufps $0, %%xmm6, %%xmm6 \n" - "shufps $0, %%xmm7, %%xmm7 \n" - "movaps %%xmm6, (%1,%0,4) \n" - "movaps %%xmm7, 16(%1,%0,4) \n" - "jg 1b \n" - :"+&r"(j) - :"r"(matrix_simd), "r"(matrix) - :"memory" - ); - if(out_ch == 2) { - MIX_MISC(IF1); - } else { - MIX_MISC(IF0); - } - } -} - -static void vector_fmul_3dnow(float *dst, const float *src, int len){ - x86_reg i = (len-4)*4; - __asm__ volatile( - "1: \n\t" - "movq (%1,%0), %%mm0 \n\t" - "movq 8(%1,%0), %%mm1 \n\t" - "pfmul (%2,%0), %%mm0 \n\t" - "pfmul 8(%2,%0), %%mm1 \n\t" - "movq %%mm0, (%1,%0) \n\t" - "movq %%mm1, 8(%1,%0) \n\t" - "sub $16, %0 \n\t" - "jge 1b \n\t" - "femms \n\t" - :"+r"(i) - :"r"(dst), "r"(src) - :"memory" - ); -} -static void vector_fmul_sse(float *dst, const float *src, int len){ - x86_reg i = (len-8)*4; - __asm__ volatile( - "1: \n\t" - "movaps (%1,%0), %%xmm0 \n\t" - "movaps 16(%1,%0), %%xmm1 \n\t" - "mulps (%2,%0), %%xmm0 \n\t" - "mulps 16(%2,%0), %%xmm1 \n\t" - "movaps %%xmm0, (%1,%0) \n\t" - "movaps %%xmm1, 16(%1,%0) \n\t" - "sub $32, %0 \n\t" - "jge 1b \n\t" - :"+r"(i) - :"r"(dst), "r"(src) - :"memory" - ); -} - -static void vector_fmul_reverse_3dnow2(float *dst, const float *src0, const float *src1, int len){ - x86_reg i = len*4-16; - __asm__ volatile( - "1: \n\t" - "pswapd 8(%1), %%mm0 \n\t" - "pswapd (%1), %%mm1 \n\t" - "pfmul (%3,%0), %%mm0 \n\t" - "pfmul 8(%3,%0), %%mm1 \n\t" - "movq %%mm0, (%2,%0) \n\t" - "movq %%mm1, 8(%2,%0) \n\t" - "add $16, %1 \n\t" - "sub $16, %0 \n\t" - "jge 1b \n\t" - :"+r"(i), "+r"(src1) - :"r"(dst), "r"(src0) - ); - __asm__ volatile("femms"); -} -static void vector_fmul_reverse_sse(float *dst, const float *src0, const float *src1, int len){ - x86_reg i = len*4-32; - __asm__ volatile( - "1: \n\t" - "movaps 16(%1), %%xmm0 \n\t" - "movaps (%1), %%xmm1 \n\t" - "shufps $0x1b, %%xmm0, %%xmm0 \n\t" - "shufps $0x1b, %%xmm1, %%xmm1 \n\t" - "mulps (%3,%0), %%xmm0 \n\t" - "mulps 16(%3,%0), %%xmm1 \n\t" - "movaps %%xmm0, (%2,%0) \n\t" - "movaps %%xmm1, 16(%2,%0) \n\t" - "add $32, %1 \n\t" - "sub $32, %0 \n\t" - "jge 1b \n\t" - :"+r"(i), "+r"(src1) - :"r"(dst), "r"(src0) - ); -} - -static void vector_fmul_add_3dnow(float *dst, const float *src0, const float *src1, - const float *src2, int len){ - x86_reg i = (len-4)*4; - __asm__ volatile( - "1: \n\t" - "movq (%2,%0), %%mm0 \n\t" - "movq 8(%2,%0), %%mm1 \n\t" - "pfmul (%3,%0), %%mm0 \n\t" - "pfmul 8(%3,%0), %%mm1 \n\t" - "pfadd (%4,%0), %%mm0 \n\t" - "pfadd 8(%4,%0), %%mm1 \n\t" - "movq %%mm0, (%1,%0) \n\t" - "movq %%mm1, 8(%1,%0) \n\t" - "sub $16, %0 \n\t" - "jge 1b \n\t" - :"+r"(i) - :"r"(dst), "r"(src0), "r"(src1), "r"(src2) - :"memory" - ); - __asm__ volatile("femms"); -} -static void vector_fmul_add_sse(float *dst, const float *src0, const float *src1, - const float *src2, int len){ - x86_reg i = (len-8)*4; - __asm__ volatile( - "1: \n\t" - "movaps (%2,%0), %%xmm0 \n\t" - "movaps 16(%2,%0), %%xmm1 \n\t" - "mulps (%3,%0), %%xmm0 \n\t" - "mulps 16(%3,%0), %%xmm1 \n\t" - "addps (%4,%0), %%xmm0 \n\t" - "addps 16(%4,%0), %%xmm1 \n\t" - "movaps %%xmm0, (%1,%0) \n\t" - "movaps %%xmm1, 16(%1,%0) \n\t" - "sub $32, %0 \n\t" - "jge 1b \n\t" - :"+r"(i) - :"r"(dst), "r"(src0), "r"(src1), "r"(src2) - :"memory" - ); -} - -static void vector_fmul_window_3dnow2(float *dst, const float *src0, const float *src1, - const float *win, float add_bias, int len){ -#if HAVE_6REGS - if(add_bias == 0){ - x86_reg i = -len*4; - x86_reg j = len*4-8; - __asm__ volatile( - "1: \n" - "pswapd (%5,%1), %%mm1 \n" - "movq (%5,%0), %%mm0 \n" - "pswapd (%4,%1), %%mm5 \n" - "movq (%3,%0), %%mm4 \n" - "movq %%mm0, %%mm2 \n" - "movq %%mm1, %%mm3 \n" - "pfmul %%mm4, %%mm2 \n" // src0[len+i]*win[len+i] - "pfmul %%mm5, %%mm3 \n" // src1[ j]*win[len+j] - "pfmul %%mm4, %%mm1 \n" // src0[len+i]*win[len+j] - "pfmul %%mm5, %%mm0 \n" // src1[ j]*win[len+i] - "pfadd %%mm3, %%mm2 \n" - "pfsub %%mm0, %%mm1 \n" - "pswapd %%mm2, %%mm2 \n" - "movq %%mm1, (%2,%0) \n" - "movq %%mm2, (%2,%1) \n" - "sub $8, %1 \n" - "add $8, %0 \n" - "jl 1b \n" - "femms \n" - :"+r"(i), "+r"(j) - :"r"(dst+len), "r"(src0+len), "r"(src1), "r"(win+len) - ); - }else -#endif - ff_vector_fmul_window_c(dst, src0, src1, win, add_bias, len); -} - -static void vector_fmul_window_sse(float *dst, const float *src0, const float *src1, - const float *win, float add_bias, int len){ -#if HAVE_6REGS - if(add_bias == 0){ - x86_reg i = -len*4; - x86_reg j = len*4-16; - __asm__ volatile( - "1: \n" - "movaps (%5,%1), %%xmm1 \n" - "movaps (%5,%0), %%xmm0 \n" - "movaps (%4,%1), %%xmm5 \n" - "movaps (%3,%0), %%xmm4 \n" - "shufps $0x1b, %%xmm1, %%xmm1 \n" - "shufps $0x1b, %%xmm5, %%xmm5 \n" - "movaps %%xmm0, %%xmm2 \n" - "movaps %%xmm1, %%xmm3 \n" - "mulps %%xmm4, %%xmm2 \n" // src0[len+i]*win[len+i] - "mulps %%xmm5, %%xmm3 \n" // src1[ j]*win[len+j] - "mulps %%xmm4, %%xmm1 \n" // src0[len+i]*win[len+j] - "mulps %%xmm5, %%xmm0 \n" // src1[ j]*win[len+i] - "addps %%xmm3, %%xmm2 \n" - "subps %%xmm0, %%xmm1 \n" - "shufps $0x1b, %%xmm2, %%xmm2 \n" - "movaps %%xmm1, (%2,%0) \n" - "movaps %%xmm2, (%2,%1) \n" - "sub $16, %1 \n" - "add $16, %0 \n" - "jl 1b \n" - :"+r"(i), "+r"(j) - :"r"(dst+len), "r"(src0+len), "r"(src1), "r"(win+len) - ); - }else -#endif - ff_vector_fmul_window_c(dst, src0, src1, win, add_bias, len); -} - -static void int32_to_float_fmul_scalar_sse(float *dst, const int *src, float mul, int len) -{ - x86_reg i = -4*len; - __asm__ volatile( - "movss %3, %%xmm4 \n" - "shufps $0, %%xmm4, %%xmm4 \n" - "1: \n" - "cvtpi2ps (%2,%0), %%xmm0 \n" - "cvtpi2ps 8(%2,%0), %%xmm1 \n" - "cvtpi2ps 16(%2,%0), %%xmm2 \n" - "cvtpi2ps 24(%2,%0), %%xmm3 \n" - "movlhps %%xmm1, %%xmm0 \n" - "movlhps %%xmm3, %%xmm2 \n" - "mulps %%xmm4, %%xmm0 \n" - "mulps %%xmm4, %%xmm2 \n" - "movaps %%xmm0, (%1,%0) \n" - "movaps %%xmm2, 16(%1,%0) \n" - "add $32, %0 \n" - "jl 1b \n" - :"+r"(i) - :"r"(dst+len), "r"(src+len), "m"(mul) - ); -} - -static void int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len) -{ - x86_reg i = -4*len; - __asm__ volatile( - "movss %3, %%xmm4 \n" - "shufps $0, %%xmm4, %%xmm4 \n" - "1: \n" - "cvtdq2ps (%2,%0), %%xmm0 \n" - "cvtdq2ps 16(%2,%0), %%xmm1 \n" - "mulps %%xmm4, %%xmm0 \n" - "mulps %%xmm4, %%xmm1 \n" - "movaps %%xmm0, (%1,%0) \n" - "movaps %%xmm1, 16(%1,%0) \n" - "add $32, %0 \n" - "jl 1b \n" - :"+r"(i) - :"r"(dst+len), "r"(src+len), "m"(mul) - ); -} - -static void vector_clipf_sse(float *dst, const float *src, float min, float max, - int len) -{ - x86_reg i = (len-16)*4; - __asm__ volatile( - "movss %3, %%xmm4 \n" - "movss %4, %%xmm5 \n" - "shufps $0, %%xmm4, %%xmm4 \n" - "shufps $0, %%xmm5, %%xmm5 \n" - "1: \n\t" - "movaps (%2,%0), %%xmm0 \n\t" // 3/1 on intel - "movaps 16(%2,%0), %%xmm1 \n\t" - "movaps 32(%2,%0), %%xmm2 \n\t" - "movaps 48(%2,%0), %%xmm3 \n\t" - "maxps %%xmm4, %%xmm0 \n\t" - "maxps %%xmm4, %%xmm1 \n\t" - "maxps %%xmm4, %%xmm2 \n\t" - "maxps %%xmm4, %%xmm3 \n\t" - "minps %%xmm5, %%xmm0 \n\t" - "minps %%xmm5, %%xmm1 \n\t" - "minps %%xmm5, %%xmm2 \n\t" - "minps %%xmm5, %%xmm3 \n\t" - "movaps %%xmm0, (%1,%0) \n\t" - "movaps %%xmm1, 16(%1,%0) \n\t" - "movaps %%xmm2, 32(%1,%0) \n\t" - "movaps %%xmm3, 48(%1,%0) \n\t" - "sub $64, %0 \n\t" - "jge 1b \n\t" - :"+&r"(i) - :"r"(dst), "r"(src), "m"(min), "m"(max) - :"memory" - ); -} - -static void float_to_int16_3dnow(int16_t *dst, const float *src, long len){ - x86_reg reglen = len; - // not bit-exact: pf2id uses different rounding than C and SSE - __asm__ volatile( - "add %0 , %0 \n\t" - "lea (%2,%0,2) , %2 \n\t" - "add %0 , %1 \n\t" - "neg %0 \n\t" - "1: \n\t" - "pf2id (%2,%0,2) , %%mm0 \n\t" - "pf2id 8(%2,%0,2) , %%mm1 \n\t" - "pf2id 16(%2,%0,2) , %%mm2 \n\t" - "pf2id 24(%2,%0,2) , %%mm3 \n\t" - "packssdw %%mm1 , %%mm0 \n\t" - "packssdw %%mm3 , %%mm2 \n\t" - "movq %%mm0 , (%1,%0) \n\t" - "movq %%mm2 , 8(%1,%0) \n\t" - "add $16 , %0 \n\t" - " js 1b \n\t" - "femms \n\t" - :"+r"(reglen), "+r"(dst), "+r"(src) - ); -} -static void float_to_int16_sse(int16_t *dst, const float *src, long len){ - x86_reg reglen = len; - __asm__ volatile( - "add %0 , %0 \n\t" - "lea (%2,%0,2) , %2 \n\t" - "add %0 , %1 \n\t" - "neg %0 \n\t" - "1: \n\t" - "cvtps2pi (%2,%0,2) , %%mm0 \n\t" - "cvtps2pi 8(%2,%0,2) , %%mm1 \n\t" - "cvtps2pi 16(%2,%0,2) , %%mm2 \n\t" - "cvtps2pi 24(%2,%0,2) , %%mm3 \n\t" - "packssdw %%mm1 , %%mm0 \n\t" - "packssdw %%mm3 , %%mm2 \n\t" - "movq %%mm0 , (%1,%0) \n\t" - "movq %%mm2 , 8(%1,%0) \n\t" - "add $16 , %0 \n\t" - " js 1b \n\t" - "emms \n\t" - :"+r"(reglen), "+r"(dst), "+r"(src) - ); -} - -static void float_to_int16_sse2(int16_t *dst, const float *src, long len){ - x86_reg reglen = len; - __asm__ volatile( - "add %0 , %0 \n\t" - "lea (%2,%0,2) , %2 \n\t" - "add %0 , %1 \n\t" - "neg %0 \n\t" - "1: \n\t" - "cvtps2dq (%2,%0,2) , %%xmm0 \n\t" - "cvtps2dq 16(%2,%0,2) , %%xmm1 \n\t" - "packssdw %%xmm1 , %%xmm0 \n\t" - "movdqa %%xmm0 , (%1,%0) \n\t" - "add $16 , %0 \n\t" - " js 1b \n\t" - :"+r"(reglen), "+r"(dst), "+r"(src) - ); -} - -void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len); -void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len); -void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len); -int32_t ff_scalarproduct_int16_mmx2(int16_t *v1, int16_t *v2, int order, int shift); -int32_t ff_scalarproduct_int16_sse2(int16_t *v1, int16_t *v2, int order, int shift); -int32_t ff_scalarproduct_and_madd_int16_mmx2(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul); -int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul); -int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul); -void ff_add_hfyu_median_prediction_mmx2(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top); -int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src, int w, int left); -int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, int w, int left); -void ff_x264_deblock_v_luma_sse2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); -void ff_x264_deblock_h_luma_sse2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); -void ff_x264_deblock_h_luma_intra_mmxext(uint8_t *pix, int stride, int alpha, int beta); -void ff_x264_deblock_v_luma_intra_sse2(uint8_t *pix, int stride, int alpha, int beta); -void ff_x264_deblock_h_luma_intra_sse2(uint8_t *pix, int stride, int alpha, int beta); - -#if HAVE_YASM && ARCH_X86_32 -void ff_x264_deblock_v8_luma_intra_mmxext(uint8_t *pix, int stride, int alpha, int beta); -static void ff_x264_deblock_v_luma_intra_mmxext(uint8_t *pix, int stride, int alpha, int beta) -{ - ff_x264_deblock_v8_luma_intra_mmxext(pix+0, stride, alpha, beta); - ff_x264_deblock_v8_luma_intra_mmxext(pix+8, stride, alpha, beta); -} -#elif !HAVE_YASM -#define ff_float_to_int16_interleave6_sse(a,b,c) float_to_int16_interleave_misc_sse(a,b,c,6) -#define ff_float_to_int16_interleave6_3dnow(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6) -#define ff_float_to_int16_interleave6_3dn2(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6) -#endif -#define ff_float_to_int16_interleave6_sse2 ff_float_to_int16_interleave6_sse - -#define FLOAT_TO_INT16_INTERLEAVE(cpu, body) \ -/* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\ -static av_noinline void float_to_int16_interleave_misc_##cpu(int16_t *dst, const float **src, long len, int channels){\ - DECLARE_ALIGNED(16, int16_t, tmp)[len];\ - int i,j,c;\ - for(c=0; cdsp_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 & FF_MM_MMX) - av_log(avctx, AV_LOG_INFO, " mmx"); - if (mm_flags & FF_MM_MMX2) - av_log(avctx, AV_LOG_INFO, " mmx2"); - if (mm_flags & FF_MM_3DNOW) - av_log(avctx, AV_LOG_INFO, " 3dnow"); - if (mm_flags & FF_MM_SSE) - av_log(avctx, AV_LOG_INFO, " sse"); - if (mm_flags & FF_MM_SSE2) - av_log(avctx, AV_LOG_INFO, " sse2"); - av_log(avctx, AV_LOG_INFO, "\n"); -#endif - - if (mm_flags & FF_MM_MMX) { - const int idct_algo= avctx->idct_algo; - - 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; -#if CONFIG_GPL - }else if(idct_algo==FF_IDCT_LIBMPEG2MMX){ - if(mm_flags & FF_MM_MMX2){ - 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; -#endif - }else if((CONFIG_VP3_DECODER || CONFIG_VP5_DECODER || CONFIG_VP6_DECODER) && - idct_algo==FF_IDCT_VP3){ - if(mm_flags & FF_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{ - 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; - } - }else if(idct_algo==FF_IDCT_CAVS){ - c->idct_permutation_type= FF_TRANSPOSE_IDCT_PERM; - }else if(idct_algo==FF_IDCT_XVIDMMX){ - if(mm_flags & FF_MM_SSE2){ - c->idct_put= ff_idct_xvid_sse2_put; - c->idct_add= ff_idct_xvid_sse2_add; - c->idct = ff_idct_xvid_sse2; - c->idct_permutation_type= FF_SSE2_IDCT_PERM; - }else if(mm_flags & FF_MM_MMX2){ - 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; - } - } - } - - 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_block = clear_block_mmx; - c->clear_blocks = clear_blocks_mmx; - if ((mm_flags & FF_MM_SSE) && - !(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)){ - /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */ - c->clear_block = clear_block_sse; - c->clear_blocks = clear_blocks_sse; - } - -#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU) \ - c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## SIZE ## _ ## CPU; \ - c->PFX ## _pixels_tab[IDX][1] = PFX ## _pixels ## SIZE ## _x2_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][2] = PFX ## _pixels ## SIZE ## _y2_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU - - SET_HPEL_FUNCS(put, 0, 16, mmx); - SET_HPEL_FUNCS(put_no_rnd, 0, 16, mmx); - SET_HPEL_FUNCS(avg, 0, 16, mmx); - SET_HPEL_FUNCS(avg_no_rnd, 0, 16, mmx); - SET_HPEL_FUNCS(put, 1, 8, mmx); - SET_HPEL_FUNCS(put_no_rnd, 1, 8, mmx); - SET_HPEL_FUNCS(avg, 1, 8, mmx); - SET_HPEL_FUNCS(avg_no_rnd, 1, 8, mmx); - - c->gmc= gmc_mmx; - - c->add_bytes= add_bytes_mmx; - c->add_bytes_l2= add_bytes_l2_mmx; - - c->draw_edges = draw_edges_mmx; - - if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { - 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_rnd; - c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_mmx; - c->put_no_rnd_vc1_chroma_pixels_tab[0]= put_vc1_chroma_mc8_mmx_nornd; - - c->put_rv40_chroma_pixels_tab[0]= put_rv40_chroma_mc8_mmx; - c->put_rv40_chroma_pixels_tab[1]= put_rv40_chroma_mc4_mmx; - - if (CONFIG_VP6_DECODER) { - c->vp6_filter_diag4 = ff_vp6_filter_diag4_mmx; - } - - if (mm_flags & FF_MM_MMX2) { - 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; - - 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; - - if (CONFIG_VP3_DECODER) { - c->vp3_v_loop_filter= ff_vp3_v_loop_filter_mmx2; - c->vp3_h_loop_filter= ff_vp3_h_loop_filter_mmx2; - } - } - if (CONFIG_VP3_DECODER) { - c->vp3_idct_dc_add = ff_vp3_idct_dc_add_mmx2; - } - -#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## SIZE ## _mc00_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## SIZE ## _mc10_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## SIZE ## _mc20_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## SIZE ## _mc30_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## SIZE ## _mc01_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## SIZE ## _mc11_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## SIZE ## _mc21_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## SIZE ## _mc31_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## SIZE ## _mc02_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## SIZE ## _mc12_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## SIZE ## _mc22_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## SIZE ## _mc32_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## SIZE ## _mc03_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## SIZE ## _mc13_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## SIZE ## _mc23_ ## CPU; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## SIZE ## _mc33_ ## CPU - - SET_QPEL_FUNCS(put_qpel, 0, 16, mmx2); - SET_QPEL_FUNCS(put_qpel, 1, 8, mmx2); - SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmx2); - SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmx2); - SET_QPEL_FUNCS(avg_qpel, 0, 16, mmx2); - SET_QPEL_FUNCS(avg_qpel, 1, 8, mmx2); - - SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmx2); - SET_QPEL_FUNCS(put_h264_qpel, 1, 8, mmx2); - SET_QPEL_FUNCS(put_h264_qpel, 2, 4, mmx2); - SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmx2); - SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, mmx2); - SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, mmx2); - - SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, mmx2); - SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, mmx2); - SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, mmx2); - SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, mmx2); - - c->avg_rv40_chroma_pixels_tab[0]= avg_rv40_chroma_mc8_mmx2; - c->avg_rv40_chroma_pixels_tab[1]= avg_rv40_chroma_mc4_mmx2; - - c->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_vc1_chroma_mc8_mmx2_nornd; - - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_mmx2_rnd; - 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; - -#if HAVE_YASM - c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmx2; -#endif -#if HAVE_7REGS && HAVE_TEN_OPERANDS - if( mm_flags&FF_MM_3DNOW ) - c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov; -#endif - - if (CONFIG_CAVS_DECODER) - ff_cavsdsp_init_mmx2(c, avctx); - - if (CONFIG_VC1_DECODER) - ff_vc1dsp_init_mmx(c, avctx); - - c->add_png_paeth_prediction= add_png_paeth_prediction_mmx2; - } else if (mm_flags & FF_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_FUNCS(put_qpel, 0, 16, 3dnow); - SET_QPEL_FUNCS(put_qpel, 1, 8, 3dnow); - SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, 3dnow); - SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, 3dnow); - SET_QPEL_FUNCS(avg_qpel, 0, 16, 3dnow); - SET_QPEL_FUNCS(avg_qpel, 1, 8, 3dnow); - - SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 3dnow); - SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 3dnow); - SET_QPEL_FUNCS(put_h264_qpel, 2, 4, 3dnow); - SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 3dnow); - SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 3dnow); - SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, 3dnow); - - SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, 3dnow); - SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, 3dnow); - SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, 3dnow); - SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, 3dnow); - - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_3dnow_rnd; - c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_3dnow; - - c->avg_rv40_chroma_pixels_tab[0]= avg_rv40_chroma_mc8_3dnow; - c->avg_rv40_chroma_pixels_tab[1]= avg_rv40_chroma_mc4_3dnow; - - if (CONFIG_CAVS_DECODER) - ff_cavsdsp_init_3dnow(c, avctx); - } - - -#define H264_QPEL_FUNCS(x, y, CPU)\ - c->put_h264_qpel_pixels_tab[0][x+y*4] = put_h264_qpel16_mc##x##y##_##CPU;\ - c->put_h264_qpel_pixels_tab[1][x+y*4] = put_h264_qpel8_mc##x##y##_##CPU;\ - c->avg_h264_qpel_pixels_tab[0][x+y*4] = avg_h264_qpel16_mc##x##y##_##CPU;\ - c->avg_h264_qpel_pixels_tab[1][x+y*4] = avg_h264_qpel8_mc##x##y##_##CPU; - if((mm_flags & FF_MM_SSE2) && !(mm_flags & FF_MM_3DNOW)){ - // these functions are slower than mmx on AMD, but faster on Intel - c->put_pixels_tab[0][0] = put_pixels16_sse2; - c->avg_pixels_tab[0][0] = avg_pixels16_sse2; - H264_QPEL_FUNCS(0, 0, sse2); - } - if(mm_flags & FF_MM_SSE2){ - H264_QPEL_FUNCS(0, 1, sse2); - H264_QPEL_FUNCS(0, 2, sse2); - H264_QPEL_FUNCS(0, 3, sse2); - H264_QPEL_FUNCS(1, 1, sse2); - H264_QPEL_FUNCS(1, 2, sse2); - H264_QPEL_FUNCS(1, 3, sse2); - H264_QPEL_FUNCS(2, 1, sse2); - H264_QPEL_FUNCS(2, 2, sse2); - H264_QPEL_FUNCS(2, 3, sse2); - H264_QPEL_FUNCS(3, 1, sse2); - H264_QPEL_FUNCS(3, 2, sse2); - H264_QPEL_FUNCS(3, 3, sse2); - - if (CONFIG_VP6_DECODER) { - c->vp6_filter_diag4 = ff_vp6_filter_diag4_sse2; - } - } -#if HAVE_SSSE3 - if(mm_flags & FF_MM_SSSE3){ - H264_QPEL_FUNCS(1, 0, ssse3); - H264_QPEL_FUNCS(1, 1, ssse3); - H264_QPEL_FUNCS(1, 2, ssse3); - H264_QPEL_FUNCS(1, 3, ssse3); - H264_QPEL_FUNCS(2, 0, ssse3); - H264_QPEL_FUNCS(2, 1, ssse3); - H264_QPEL_FUNCS(2, 2, ssse3); - H264_QPEL_FUNCS(2, 3, ssse3); - H264_QPEL_FUNCS(3, 0, ssse3); - H264_QPEL_FUNCS(3, 1, ssse3); - H264_QPEL_FUNCS(3, 2, ssse3); - H264_QPEL_FUNCS(3, 3, ssse3); - c->put_no_rnd_vc1_chroma_pixels_tab[0]= put_vc1_chroma_mc8_ssse3_nornd; - c->avg_no_rnd_vc1_chroma_pixels_tab[0]= avg_vc1_chroma_mc8_ssse3_nornd; - c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_ssse3_rnd; - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_ssse3_rnd; - c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_ssse3; - c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_ssse3; - c->add_png_paeth_prediction= add_png_paeth_prediction_ssse3; -#if HAVE_YASM - c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3; - if (mm_flags & FF_MM_SSE4) // not really sse4, just slow on Conroe - c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4; -#endif - } -#endif - - if(mm_flags & FF_MM_3DNOW){ - c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow; - c->vector_fmul = vector_fmul_3dnow; - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->float_to_int16 = float_to_int16_3dnow; - c->float_to_int16_interleave = float_to_int16_interleave_3dnow; - } - } - if(mm_flags & FF_MM_3DNOWEXT){ - c->vector_fmul_reverse = vector_fmul_reverse_3dnow2; - c->vector_fmul_window = vector_fmul_window_3dnow2; - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->float_to_int16_interleave = float_to_int16_interleave_3dn2; - } - } - if(mm_flags & FF_MM_MMX2){ -#if HAVE_YASM - c->scalarproduct_int16 = ff_scalarproduct_int16_mmx2; - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmx2; -#endif - } - if(mm_flags & FF_MM_SSE){ - c->vorbis_inverse_coupling = vorbis_inverse_coupling_sse; - c->ac3_downmix = ac3_downmix_sse; - c->vector_fmul = vector_fmul_sse; - c->vector_fmul_reverse = vector_fmul_reverse_sse; - c->vector_fmul_add = vector_fmul_add_sse; - c->vector_fmul_window = vector_fmul_window_sse; - c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse; - c->vector_clipf = vector_clipf_sse; - c->float_to_int16 = float_to_int16_sse; - c->float_to_int16_interleave = float_to_int16_interleave_sse; -#if HAVE_YASM - c->scalarproduct_float = ff_scalarproduct_float_sse; -#endif - } - if(mm_flags & FF_MM_3DNOW) - c->vector_fmul_add = vector_fmul_add_3dnow; // faster than sse - if(mm_flags & FF_MM_SSE2){ - c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse2; - c->float_to_int16 = float_to_int16_sse2; - c->float_to_int16_interleave = float_to_int16_interleave_sse2; -#if HAVE_YASM - c->scalarproduct_int16 = ff_scalarproduct_int16_sse2; - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2; -#endif - } - if((mm_flags & FF_MM_SSSE3) && !(mm_flags & (FF_MM_SSE42|FF_MM_3DNOW)) && HAVE_YASM) // cachesplit - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3; - } - - if (CONFIG_ENCODERS) - dsputilenc_init_mmx(c, avctx); - -#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 -} - -#if CONFIG_H264DSP -void ff_h264dsp_init_x86(H264DSPContext *c) -{ - mm_flags = mm_support(); - - if (mm_flags & FF_MM_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; - - c->h264_idct_add16 = ff_h264_idct_add16_mmx; - c->h264_idct8_add4 = ff_h264_idct8_add4_mmx; - c->h264_idct_add8 = ff_h264_idct_add8_mmx; - c->h264_idct_add16intra= ff_h264_idct_add16intra_mmx; - - if (mm_flags & FF_MM_MMX2) { - c->h264_idct_dc_add= ff_h264_idct_dc_add_mmx2; - c->h264_idct8_dc_add= ff_h264_idct8_dc_add_mmx2; - c->h264_idct_add16 = ff_h264_idct_add16_mmx2; - c->h264_idct8_add4 = ff_h264_idct8_add4_mmx2; - c->h264_idct_add8 = ff_h264_idct_add8_mmx2; - c->h264_idct_add16intra= ff_h264_idct_add16intra_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->h264_loop_filter_strength= h264_loop_filter_strength_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; - } - if(mm_flags & FF_MM_SSE2){ - c->h264_idct8_add = ff_h264_idct8_add_sse2; - c->h264_idct8_add4= ff_h264_idct8_add4_sse2; - } - -#if CONFIG_GPL && HAVE_YASM - if (mm_flags & FF_MM_MMX2){ -#if ARCH_X86_32 - c->h264_v_loop_filter_luma_intra = ff_x264_deblock_v_luma_intra_mmxext; - c->h264_h_loop_filter_luma_intra = ff_x264_deblock_h_luma_intra_mmxext; -#endif - if( mm_flags&FF_MM_SSE2 ){ -#if ARCH_X86_64 || !defined(__ICC) || __ICC > 1110 - c->h264_v_loop_filter_luma = ff_x264_deblock_v_luma_sse2; - c->h264_h_loop_filter_luma = ff_x264_deblock_h_luma_sse2; - c->h264_v_loop_filter_luma_intra = ff_x264_deblock_v_luma_intra_sse2; - c->h264_h_loop_filter_luma_intra = ff_x264_deblock_h_luma_intra_sse2; -#endif - c->h264_idct_add16 = ff_h264_idct_add16_sse2; - c->h264_idct_add8 = ff_h264_idct_add8_sse2; - c->h264_idct_add16intra = ff_h264_idct_add16intra_sse2; - } - } -#endif - } -} -#endif /* CONFIG_H264DSP */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.h b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.h deleted file mode 100644 index 7d1bf7f..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * MMX optimized DSP utils - * Copyright (c) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_DSPUTIL_MMX_H -#define AVCODEC_X86_DSPUTIL_MMX_H - -#include -#include "libavcodec/dsputil.h" - -typedef struct { uint64_t a, b; } xmm_reg; - -extern const uint64_t ff_bone; -extern const uint64_t ff_wtwo; - -extern const uint64_t ff_pdw_80000000[2]; - -extern const uint64_t ff_pw_3; -extern const uint64_t ff_pw_4; -extern const xmm_reg ff_pw_5; -extern const xmm_reg ff_pw_8; -extern const uint64_t ff_pw_15; -extern const xmm_reg ff_pw_16; -extern const uint64_t ff_pw_20; -extern const xmm_reg ff_pw_28; -extern const xmm_reg ff_pw_32; -extern const uint64_t ff_pw_42; -extern const xmm_reg ff_pw_64; -extern const uint64_t ff_pw_96; -extern const uint64_t ff_pw_128; -extern const uint64_t ff_pw_255; - -extern const uint64_t ff_pb_1; -extern const uint64_t ff_pb_3; -extern const uint64_t ff_pb_7; -extern const uint64_t ff_pb_1F; -extern const uint64_t ff_pb_3F; -extern const uint64_t ff_pb_81; -extern const uint64_t ff_pb_A1; -extern const uint64_t ff_pb_FC; - -extern const double ff_pd_1[2]; -extern const double ff_pd_2[2]; - -#define LOAD4(stride,in,a,b,c,d)\ - "movq 0*"#stride"+"#in", "#a"\n\t"\ - "movq 1*"#stride"+"#in", "#b"\n\t"\ - "movq 2*"#stride"+"#in", "#c"\n\t"\ - "movq 3*"#stride"+"#in", "#d"\n\t" - -#define STORE4(stride,out,a,b,c,d)\ - "movq "#a", 0*"#stride"+"#out"\n\t"\ - "movq "#b", 1*"#stride"+"#out"\n\t"\ - "movq "#c", 2*"#stride"+"#out"\n\t"\ - "movq "#d", 3*"#stride"+"#out"\n\t" - -/* 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 SBUTTERFLY(a,b,t,n,m)\ - "mov" #m " " #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,q) /* a=aebf t=cgdh */\ - SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\ - SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\ - SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */ - -// e,f,g,h can be memory -// out: a,d,t,c -#define TRANSPOSE8x4(a,b,c,d,e,f,g,h,t)\ - "punpcklbw " #e ", " #a " \n\t" /* a0 e0 a1 e1 a2 e2 a3 e3 */\ - "punpcklbw " #f ", " #b " \n\t" /* b0 f0 b1 f1 b2 f2 b3 f3 */\ - "punpcklbw " #g ", " #c " \n\t" /* c0 g0 c1 g1 c2 g2 d3 g3 */\ - "punpcklbw " #h ", " #d " \n\t" /* d0 h0 d1 h1 d2 h2 d3 h3 */\ - SBUTTERFLY(a, b, t, bw, q) /* a= a0 b0 e0 f0 a1 b1 e1 f1 */\ - /* t= a2 b2 e2 f2 a3 b3 e3 f3 */\ - SBUTTERFLY(c, d, b, bw, q) /* c= c0 d0 g0 h0 c1 d1 g1 h1 */\ - /* b= c2 d2 g2 h2 c3 d3 g3 h3 */\ - SBUTTERFLY(a, c, d, wd, q) /* a= a0 b0 c0 d0 e0 f0 g0 h0 */\ - /* d= a1 b1 c1 d1 e1 f1 g1 h1 */\ - SBUTTERFLY(t, b, c, wd, q) /* t= a2 b2 c2 d2 e2 f2 g2 h2 */\ - /* c= a3 b3 c3 d3 e3 f3 g3 h3 */ - -#if ARCH_X86_64 -// permutes 01234567 -> 05736421 -#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\ - SBUTTERFLY(a,b,%%xmm8,wd,dqa)\ - SBUTTERFLY(c,d,b,wd,dqa)\ - SBUTTERFLY(e,f,d,wd,dqa)\ - SBUTTERFLY(g,h,f,wd,dqa)\ - SBUTTERFLY(a,c,h,dq,dqa)\ - SBUTTERFLY(%%xmm8,b,c,dq,dqa)\ - SBUTTERFLY(e,g,b,dq,dqa)\ - SBUTTERFLY(d,f,g,dq,dqa)\ - SBUTTERFLY(a,e,f,qdq,dqa)\ - SBUTTERFLY(%%xmm8,d,e,qdq,dqa)\ - SBUTTERFLY(h,b,d,qdq,dqa)\ - SBUTTERFLY(c,g,b,qdq,dqa)\ - "movdqa %%xmm8, "#g" \n\t" -#else -#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\ - "movdqa "#h", "#t" \n\t"\ - SBUTTERFLY(a,b,h,wd,dqa)\ - "movdqa "#h", 16"#t" \n\t"\ - "movdqa "#t", "#h" \n\t"\ - SBUTTERFLY(c,d,b,wd,dqa)\ - SBUTTERFLY(e,f,d,wd,dqa)\ - SBUTTERFLY(g,h,f,wd,dqa)\ - SBUTTERFLY(a,c,h,dq,dqa)\ - "movdqa "#h", "#t" \n\t"\ - "movdqa 16"#t", "#h" \n\t"\ - SBUTTERFLY(h,b,c,dq,dqa)\ - SBUTTERFLY(e,g,b,dq,dqa)\ - SBUTTERFLY(d,f,g,dq,dqa)\ - SBUTTERFLY(a,e,f,qdq,dqa)\ - SBUTTERFLY(h,d,e,qdq,dqa)\ - "movdqa "#h", 16"#t" \n\t"\ - "movdqa "#t", "#h" \n\t"\ - SBUTTERFLY(h,b,d,qdq,dqa)\ - SBUTTERFLY(c,g,b,qdq,dqa)\ - "movdqa 16"#t", "#g" \n\t" -#endif - -#define MOVQ_WONE(regd) \ - __asm__ volatile ( \ - "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ - "psrlw $15, %%" #regd ::) - -void dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx); -void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); - -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); - -void ff_cavsdsp_init_mmx2(DSPContext* c, AVCodecContext *avctx); -void ff_cavsdsp_init_3dnow(DSPContext* c, AVCodecContext *avctx); -void ff_put_cavs_qpel8_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_cavs_qpel8_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride); -void ff_put_cavs_qpel16_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_cavs_qpel16_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride); - -void ff_vc1dsp_init_mmx(DSPContext* dsp, AVCodecContext *avctx); -void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd); -void ff_avg_vc1_mspel_mc00_mmx2(uint8_t *dst, const uint8_t *src, int stride, int rnd); - -void ff_lpc_compute_autocorr_sse2(const int32_t *data, int len, int lag, - double *autoc); - -void ff_mmx_idct(DCTELEM *block); -void ff_mmxext_idct(DCTELEM *block); - -#endif /* AVCODEC_X86_DSPUTIL_MMX_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_avg_template.c b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_avg_template.c deleted file mode 100644 index 8220867..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_avg_template.c +++ /dev/null @@ -1,896 +0,0 @@ -/* - * DSP utils : average functions are compiled twice for 3dnow/mmx2 - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * MMX optimization by Nick Kurshev - * mostly rewritten by Michael Niedermayer - * and improved by Zdenek Kabelac - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* 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" ((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" ((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" ((x86_reg)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" ((x86_reg)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" ((x86_reg)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" ((x86_reg)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" ((x86_reg)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" ((x86_reg)line_size) - :"%"REG_a, "memory"); -} - -/* Note this is not correctly rounded, but this function is only - * used for B-frames so it does not 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" - ASMALIGN(3) - "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" ((x86_reg)line_size) - :"%"REG_a, "memory"); -} - -static void DEF(avg_pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - do { - __asm__ volatile( - "movd (%1), %%mm0 \n\t" - "movd (%1, %2), %%mm1 \n\t" - "movd (%1, %2, 2), %%mm2 \n\t" - "movd (%1, %3), %%mm3 \n\t" - PAVGB" (%0), %%mm0 \n\t" - PAVGB" (%0, %2), %%mm1 \n\t" - PAVGB" (%0, %2, 2), %%mm2 \n\t" - PAVGB" (%0, %3), %%mm3 \n\t" - "movd %%mm0, (%1) \n\t" - "movd %%mm1, (%1, %2) \n\t" - "movd %%mm2, (%1, %2, 2) \n\t" - "movd %%mm3, (%1, %3) \n\t" - ::"S"(pixels), "D"(block), - "r" ((x86_reg)line_size), "r"((x86_reg)3L*line_size) - :"memory"); - block += 4*line_size; - pixels += 4*line_size; - h -= 4; - } while(h > 0); -} - -//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); -} - -#define QPEL_2TAP_L3(OPNAME) \ -static void DEF(OPNAME ## 2tap_qpel16_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\ - __asm__ volatile(\ - "1: \n\t"\ - "movq (%1,%2), %%mm0 \n\t"\ - "movq 8(%1,%2), %%mm1 \n\t"\ - PAVGB" (%1,%3), %%mm0 \n\t"\ - PAVGB" 8(%1,%3), %%mm1 \n\t"\ - PAVGB" (%1), %%mm0 \n\t"\ - PAVGB" 8(%1), %%mm1 \n\t"\ - STORE_OP( (%1,%4),%%mm0)\ - STORE_OP(8(%1,%4),%%mm1)\ - "movq %%mm0, (%1,%4) \n\t"\ - "movq %%mm1, 8(%1,%4) \n\t"\ - "add %5, %1 \n\t"\ - "decl %0 \n\t"\ - "jnz 1b \n\t"\ - :"+g"(h), "+r"(src)\ - :"r"((x86_reg)off1), "r"((x86_reg)off2),\ - "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\ - :"memory"\ - );\ -}\ -static void DEF(OPNAME ## 2tap_qpel8_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\ - __asm__ volatile(\ - "1: \n\t"\ - "movq (%1,%2), %%mm0 \n\t"\ - PAVGB" (%1,%3), %%mm0 \n\t"\ - PAVGB" (%1), %%mm0 \n\t"\ - STORE_OP((%1,%4),%%mm0)\ - "movq %%mm0, (%1,%4) \n\t"\ - "add %5, %1 \n\t"\ - "decl %0 \n\t"\ - "jnz 1b \n\t"\ - :"+g"(h), "+r"(src)\ - :"r"((x86_reg)off1), "r"((x86_reg)off2),\ - "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\ - :"memory"\ - );\ -} - -#define STORE_OP(a,b) PAVGB" "#a","#b" \n\t" -QPEL_2TAP_L3(avg_) -#undef STORE_OP -#define STORE_OP(a,b) -QPEL_2TAP_L3(put_) -#undef STORE_OP -#undef QPEL_2TAP_L3 diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_qns_template.c b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_qns_template.c deleted file mode 100644 index d2dbfc5..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_qns_template.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * DSP utils : QNS functions are compiled 3 times for mmx/3dnow/ssse3 - * Copyright (c) 2004 Michael Niedermayer - * - * MMX optimization by Michael Niedermayer - * 3DNow! and SSSE3 optimization by Zuxy Meng - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define MAX_ABS (512 >> (SCALE_OFFSET>0 ? SCALE_OFFSET : 0)) - -static int DEF(try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale) -{ - x86_reg i=0; - - assert(FFABS(scale) < MAX_ABS); - scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; - - SET_RND(mm6); - __asm__ volatile( - "pxor %%mm7, %%mm7 \n\t" - "movd %4, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%1, %0), %%mm0 \n\t" - "movq 8(%1, %0), %%mm1 \n\t" - PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) - "paddw (%2, %0), %%mm0 \n\t" - "paddw 8(%2, %0), %%mm1 \n\t" - "psraw $6, %%mm0 \n\t" - "psraw $6, %%mm1 \n\t" - "pmullw (%3, %0), %%mm0 \n\t" - "pmullw 8(%3, %0), %%mm1 \n\t" - "pmaddwd %%mm0, %%mm0 \n\t" - "pmaddwd %%mm1, %%mm1 \n\t" - "paddd %%mm1, %%mm0 \n\t" - "psrld $4, %%mm0 \n\t" - "paddd %%mm0, %%mm7 \n\t" - "add $16, %0 \n\t" - "cmp $128, %0 \n\t" //FIXME optimize & bench - " jb 1b \n\t" - PHADDD(%%mm7, %%mm6) - "psrld $2, %%mm7 \n\t" - "movd %%mm7, %0 \n\t" - - : "+r" (i) - : "r"(basis), "r"(rem), "r"(weight), "g"(scale) - ); - return i; -} - -static void DEF(add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale) -{ - x86_reg i=0; - - if(FFABS(scale) < MAX_ABS){ - scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; - SET_RND(mm6); - __asm__ volatile( - "movd %3, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%1, %0), %%mm0 \n\t" - "movq 8(%1, %0), %%mm1 \n\t" - PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) - "paddw (%2, %0), %%mm0 \n\t" - "paddw 8(%2, %0), %%mm1 \n\t" - "movq %%mm0, (%2, %0) \n\t" - "movq %%mm1, 8(%2, %0) \n\t" - "add $16, %0 \n\t" - "cmp $128, %0 \n\t" // FIXME optimize & bench - " jb 1b \n\t" - - : "+r" (i) - : "r"(basis), "r"(rem), "g"(scale) - ); - }else{ - for(i=0; i<8*8; i++){ - rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); - } - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_rnd_template.c b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_rnd_template.c deleted file mode 100644 index 2fc1756..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_mmx_rnd_template.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * DSP utils mmx functions are compiled twice for rnd/no_rnd - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003-2004 Michael Niedermayer - * - * MMX optimization by Nick Kurshev - * mostly rewritten by Michael Niedermayer - * and improved by Zdenek Kabelac - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// 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" - ASMALIGN(3) - "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"((x86_reg)line_size) - :REG_a, "memory"); -} - -static void av_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" - ASMALIGN(3) - "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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" - ASMALIGN(3) - "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"((x86_reg)line_size) - :REG_a, "memory"); -} - -static void av_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" - ASMALIGN(3) - "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" -#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used - :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#else - :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) -#endif - :"S"((x86_reg)src1Stride), "D"((x86_reg)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" - ASMALIGN(3) - "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"((x86_reg)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" - ASMALIGN(3) - "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"((x86_reg)line_size) - :REG_a, "memory"); -} - -// avg_pixels -static void av_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" - OP_AVG(%%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" - OP_AVG(%%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" - OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6) - "movq %%mm2, %0 \n\t" - "movq 8%0, %%mm0 \n\t" - "movq 8%1, %%mm1 \n\t" - OP_AVG(%%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) - OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6) - "movq %%mm0, %0 \n\t" - :"+m"(*block) - :"m"(*pixels) - :"memory"); - pixels += line_size; - block += line_size; - } while (--h); -} - -static av_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) - OP_AVG(%%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) - OP_AVG(%%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) - OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6) - "movq %%mm0, 8%0 \n\t" - :"+m"(*block) - :"m"(*pixels) - :"memory"); - pixels += line_size; - block += line_size; - } while (--h); -} - -static av_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) - OP_AVG(%%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) - OP_AVG(%%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" - ASMALIGN(3) - "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" - OP_AVG(%%mm3, %%mm4, %%mm0, %%mm6) - "movq (%2, %3), %%mm3 \n\t" - OP_AVG(%%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" - OP_AVG(%%mm3, %%mm4, %%mm2, %%mm6) - "movq (%2, %3), %%mm3 \n\t" - OP_AVG(%%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"((x86_reg)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" - ASMALIGN(3) - "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" - OP_AVG(%%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" - OP_AVG(%%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"((x86_reg)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/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_yasm.asm b/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_yasm.asm deleted file mode 100644 index e2478a4..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputil_yasm.asm +++ /dev/null @@ -1,423 +0,0 @@ -;****************************************************************************** -;* MMX optimized DSP utils -;* Copyright (c) 2008 Loren Merritt -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg 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.1 of the License, or (at your option) any later version. -;* -;* FFmpeg 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 FFmpeg; if not, write to the Free Software -;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;****************************************************************************** - -%include "x86inc.asm" - -SECTION_RODATA -pb_f: times 16 db 15 -pb_zzzzzzzz77777777: times 8 db -1 -pb_7: times 8 db 7 -pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11 -pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13 - -section .text align=16 - -%macro PSWAPD_SSE 2 - pshufw %1, %2, 0x4e -%endmacro -%macro PSWAPD_3DN1 2 - movq %1, %2 - psrlq %1, 32 - punpckldq %1, %2 -%endmacro - -%macro FLOAT_TO_INT16_INTERLEAVE6 1 -; void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len) -cglobal float_to_int16_interleave6_%1, 2,7,0, dst, src, src1, src2, src3, src4, src5 -%ifdef ARCH_X86_64 - %define lend r10d - mov lend, r2d -%else - %define lend dword r2m -%endif - mov src1q, [srcq+1*gprsize] - mov src2q, [srcq+2*gprsize] - mov src3q, [srcq+3*gprsize] - mov src4q, [srcq+4*gprsize] - mov src5q, [srcq+5*gprsize] - mov srcq, [srcq] - sub src1q, srcq - sub src2q, srcq - sub src3q, srcq - sub src4q, srcq - sub src5q, srcq -.loop: - cvtps2pi mm0, [srcq] - cvtps2pi mm1, [srcq+src1q] - cvtps2pi mm2, [srcq+src2q] - cvtps2pi mm3, [srcq+src3q] - cvtps2pi mm4, [srcq+src4q] - cvtps2pi mm5, [srcq+src5q] - packssdw mm0, mm3 - packssdw mm1, mm4 - packssdw mm2, mm5 - pswapd mm3, mm0 - punpcklwd mm0, mm1 - punpckhwd mm1, mm2 - punpcklwd mm2, mm3 - pswapd mm3, mm0 - punpckldq mm0, mm2 - punpckhdq mm2, mm1 - punpckldq mm1, mm3 - movq [dstq ], mm0 - movq [dstq+16], mm2 - movq [dstq+ 8], mm1 - add srcq, 8 - add dstq, 24 - sub lend, 2 - jg .loop - emms - RET -%endmacro ; FLOAT_TO_INT16_INTERLEAVE6 - -%define pswapd PSWAPD_SSE -FLOAT_TO_INT16_INTERLEAVE6 sse -%define cvtps2pi pf2id -%define pswapd PSWAPD_3DN1 -FLOAT_TO_INT16_INTERLEAVE6 3dnow -%undef pswapd -FLOAT_TO_INT16_INTERLEAVE6 3dn2 -%undef cvtps2pi - - - -%macro SCALARPRODUCT 1 -; int scalarproduct_int16(int16_t *v1, int16_t *v2, int order, int shift) -cglobal scalarproduct_int16_%1, 3,3,4, v1, v2, order, shift - shl orderq, 1 - add v1q, orderq - add v2q, orderq - neg orderq - movd m3, shiftm - pxor m2, m2 -.loop: - movu m0, [v1q + orderq] - movu m1, [v1q + orderq + mmsize] - pmaddwd m0, [v2q + orderq] - pmaddwd m1, [v2q + orderq + mmsize] - paddd m2, m0 - paddd m2, m1 - add orderq, mmsize*2 - jl .loop -%if mmsize == 16 - movhlps m0, m2 - paddd m2, m0 - psrad m2, m3 - pshuflw m0, m2, 0x4e -%else - psrad m2, m3 - pshufw m0, m2, 0x4e -%endif - paddd m2, m0 - movd eax, m2 - RET - -; int scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul) -cglobal scalarproduct_and_madd_int16_%1, 4,4,8, v1, v2, v3, order, mul - shl orderq, 1 - movd m7, mulm -%if mmsize == 16 - pshuflw m7, m7, 0 - punpcklqdq m7, m7 -%else - pshufw m7, m7, 0 -%endif - pxor m6, m6 - add v1q, orderq - add v2q, orderq - add v3q, orderq - neg orderq -.loop: - movu m0, [v2q + orderq] - movu m1, [v2q + orderq + mmsize] - mova m4, [v1q + orderq] - mova m5, [v1q + orderq + mmsize] - movu m2, [v3q + orderq] - movu m3, [v3q + orderq + mmsize] - pmaddwd m0, m4 - pmaddwd m1, m5 - pmullw m2, m7 - pmullw m3, m7 - paddd m6, m0 - paddd m6, m1 - paddw m2, m4 - paddw m3, m5 - mova [v1q + orderq], m2 - mova [v1q + orderq + mmsize], m3 - add orderq, mmsize*2 - jl .loop -%if mmsize == 16 - movhlps m0, m6 - paddd m6, m0 - pshuflw m0, m6, 0x4e -%else - pshufw m0, m6, 0x4e -%endif - paddd m6, m0 - movd eax, m6 - RET -%endmacro - -INIT_MMX -SCALARPRODUCT mmx2 -INIT_XMM -SCALARPRODUCT sse2 - -%macro SCALARPRODUCT_LOOP 1 -align 16 -.loop%1: - sub orderq, mmsize*2 -%if %1 - mova m1, m4 - mova m4, [v2q + orderq] - mova m0, [v2q + orderq + mmsize] - palignr m1, m0, %1 - palignr m0, m4, %1 - mova m3, m5 - mova m5, [v3q + orderq] - mova m2, [v3q + orderq + mmsize] - palignr m3, m2, %1 - palignr m2, m5, %1 -%else - mova m0, [v2q + orderq] - mova m1, [v2q + orderq + mmsize] - mova m2, [v3q + orderq] - mova m3, [v3q + orderq + mmsize] -%endif - %define t0 [v1q + orderq] - %define t1 [v1q + orderq + mmsize] -%ifdef ARCH_X86_64 - mova m8, t0 - mova m9, t1 - %define t0 m8 - %define t1 m9 -%endif - pmaddwd m0, t0 - pmaddwd m1, t1 - pmullw m2, m7 - pmullw m3, m7 - paddw m2, t0 - paddw m3, t1 - paddd m6, m0 - paddd m6, m1 - mova [v1q + orderq], m2 - mova [v1q + orderq + mmsize], m3 - jg .loop%1 -%if %1 - jmp .end -%endif -%endmacro - -; int scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul) -cglobal scalarproduct_and_madd_int16_ssse3, 4,5,10, v1, v2, v3, order, mul - shl orderq, 1 - movd m7, mulm - pshuflw m7, m7, 0 - punpcklqdq m7, m7 - pxor m6, m6 - mov r4d, v2d - and r4d, 15 - and v2q, ~15 - and v3q, ~15 - mova m4, [v2q + orderq] - mova m5, [v3q + orderq] - ; linear is faster than branch tree or jump table, because the branches taken are cyclic (i.e. predictable) - cmp r4d, 0 - je .loop0 - cmp r4d, 2 - je .loop2 - cmp r4d, 4 - je .loop4 - cmp r4d, 6 - je .loop6 - cmp r4d, 8 - je .loop8 - cmp r4d, 10 - je .loop10 - cmp r4d, 12 - je .loop12 -SCALARPRODUCT_LOOP 14 -SCALARPRODUCT_LOOP 12 -SCALARPRODUCT_LOOP 10 -SCALARPRODUCT_LOOP 8 -SCALARPRODUCT_LOOP 6 -SCALARPRODUCT_LOOP 4 -SCALARPRODUCT_LOOP 2 -SCALARPRODUCT_LOOP 0 -.end: - movhlps m0, m6 - paddd m6, m0 - pshuflw m0, m6, 0x4e - paddd m6, m0 - movd eax, m6 - RET - - - -; void ff_add_hfyu_median_prediction_mmx2(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top) -cglobal add_hfyu_median_prediction_mmx2, 6,6,0, dst, top, diff, w, left, left_top - movq mm0, [topq] - movq mm2, mm0 - movd mm4, [left_topq] - psllq mm2, 8 - movq mm1, mm0 - por mm4, mm2 - movd mm3, [leftq] - psubb mm0, mm4 ; t-tl - add dstq, wq - add topq, wq - add diffq, wq - neg wq - jmp .skip -.loop: - movq mm4, [topq+wq] - movq mm0, mm4 - psllq mm4, 8 - por mm4, mm1 - movq mm1, mm0 ; t - psubb mm0, mm4 ; t-tl -.skip: - movq mm2, [diffq+wq] -%assign i 0 -%rep 8 - movq mm4, mm0 - paddb mm4, mm3 ; t-tl+l - movq mm5, mm3 - pmaxub mm3, mm1 - pminub mm5, mm1 - pminub mm3, mm4 - pmaxub mm3, mm5 ; median - paddb mm3, mm2 ; +residual -%if i==0 - movq mm7, mm3 - psllq mm7, 56 -%else - movq mm6, mm3 - psrlq mm7, 8 - psllq mm6, 56 - por mm7, mm6 -%endif -%if i<7 - psrlq mm0, 8 - psrlq mm1, 8 - psrlq mm2, 8 -%endif -%assign i i+1 -%endrep - movq [dstq+wq], mm7 - add wq, 8 - jl .loop - movzx r2d, byte [dstq-1] - mov [leftq], r2d - movzx r2d, byte [topq-1] - mov [left_topq], r2d - RET - - -%macro ADD_HFYU_LEFT_LOOP 1 ; %1 = is_aligned - add srcq, wq - add dstq, wq - neg wq -%%.loop: - mova m1, [srcq+wq] - mova m2, m1 - psllw m1, 8 - paddb m1, m2 - mova m2, m1 - pshufb m1, m3 - paddb m1, m2 - pshufb m0, m5 - mova m2, m1 - pshufb m1, m4 - paddb m1, m2 -%if mmsize == 16 - mova m2, m1 - pshufb m1, m6 - paddb m1, m2 -%endif - paddb m0, m1 -%if %1 - mova [dstq+wq], m0 -%else - movq [dstq+wq], m0 - movhps [dstq+wq+8], m0 -%endif - add wq, mmsize - jl %%.loop - mov eax, mmsize-1 - sub eax, wd - movd m1, eax - pshufb m0, m1 - movd eax, m0 - RET -%endmacro - -; int ff_add_hfyu_left_prediction(uint8_t *dst, const uint8_t *src, int w, int left) -INIT_MMX -cglobal add_hfyu_left_prediction_ssse3, 3,3,7, dst, src, w, left -.skip_prologue: - mova m5, [pb_7 GLOBAL] - mova m4, [pb_zzzz3333zzzzbbbb GLOBAL] - mova m3, [pb_zz11zz55zz99zzdd GLOBAL] - movd m0, leftm - psllq m0, 56 - ADD_HFYU_LEFT_LOOP 1 - -INIT_XMM -cglobal add_hfyu_left_prediction_sse4, 3,3,7, dst, src, w, left - mova m5, [pb_f GLOBAL] - mova m6, [pb_zzzzzzzz77777777 GLOBAL] - mova m4, [pb_zzzz3333zzzzbbbb GLOBAL] - mova m3, [pb_zz11zz55zz99zzdd GLOBAL] - movd m0, leftm - pslldq m0, 15 - test srcq, 15 - jnz add_hfyu_left_prediction_ssse3.skip_prologue - test dstq, 15 - jnz .unaligned - ADD_HFYU_LEFT_LOOP 1 -.unaligned: - ADD_HFYU_LEFT_LOOP 0 - - -; float ff_scalarproduct_float_sse(const float *v1, const float *v2, int len) -cglobal scalarproduct_float_sse, 3,3,2, v1, v2, offset - neg offsetq - shl offsetq, 2 - sub v1q, offsetq - sub v2q, offsetq - xorps xmm0, xmm0 - .loop: - movaps xmm1, [v1q+offsetq] - mulps xmm1, [v2q+offsetq] - addps xmm0, xmm1 - add offsetq, 16 - js .loop - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movss xmm1, xmm0 - shufps xmm0, xmm0, 1 - addss xmm0, xmm1 -%ifndef ARCH_X86_64 - movd r0m, xmm0 - fld dword r0m -%endif - RET diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/dsputilenc_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/dsputilenc_mmx.c deleted file mode 100644 index f491111..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/dsputilenc_mmx.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* - * MMX optimized DSP utils - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; 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 "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" -#include "libavcodec/mathops.h" -#include "dsputil_mmx.h" - - -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" - ASMALIGN(4) - "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" ((x86_reg)line_size), "r" ((x86_reg)line_size*2) - : "%"REG_a - ); -} - -static void get_pixels_sse2(DCTELEM *block, const uint8_t *pixels, int line_size) -{ - __asm__ volatile( - "pxor %%xmm7, %%xmm7 \n\t" - "movq (%0), %%xmm0 \n\t" - "movq (%0, %2), %%xmm1 \n\t" - "movq (%0, %2,2), %%xmm2 \n\t" - "movq (%0, %3), %%xmm3 \n\t" - "lea (%0,%2,4), %0 \n\t" - "punpcklbw %%xmm7, %%xmm0 \n\t" - "punpcklbw %%xmm7, %%xmm1 \n\t" - "punpcklbw %%xmm7, %%xmm2 \n\t" - "punpcklbw %%xmm7, %%xmm3 \n\t" - "movdqa %%xmm0, (%1) \n\t" - "movdqa %%xmm1, 16(%1) \n\t" - "movdqa %%xmm2, 32(%1) \n\t" - "movdqa %%xmm3, 48(%1) \n\t" - "movq (%0), %%xmm0 \n\t" - "movq (%0, %2), %%xmm1 \n\t" - "movq (%0, %2,2), %%xmm2 \n\t" - "movq (%0, %3), %%xmm3 \n\t" - "punpcklbw %%xmm7, %%xmm0 \n\t" - "punpcklbw %%xmm7, %%xmm1 \n\t" - "punpcklbw %%xmm7, %%xmm2 \n\t" - "punpcklbw %%xmm7, %%xmm3 \n\t" - "movdqa %%xmm0, 64(%1) \n\t" - "movdqa %%xmm1, 80(%1) \n\t" - "movdqa %%xmm2, 96(%1) \n\t" - "movdqa %%xmm3, 112(%1) \n\t" - : "+r" (pixels) - : "r" (block), "r" ((x86_reg)line_size), "r" ((x86_reg)line_size*3) - ); -} - -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" - ASMALIGN(4) - "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" ((x86_reg)stride) - : "%"REG_a - ); -} - -static int pix_sum16_mmx(uint8_t * pix, int line_size){ - const int h=16; - int sum; - x86_reg 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" ((x86_reg)line_size) - ); - - return sum; -} - -static int pix_norm1_mmx(uint8_t *pix, int line_size) { - int tmp; - __asm__ volatile ( - "movl $16,%%ecx\n" - "pxor %%mm0,%%mm0\n" - "pxor %%mm7,%%mm7\n" - "1:\n" - "movq (%0),%%mm2\n" /* mm2 = pix[0-7] */ - "movq 8(%0),%%mm3\n" /* mm3 = pix[8-15] */ - - "movq %%mm2,%%mm1\n" /* mm1 = mm2 = pix[0-7] */ - - "punpckhbw %%mm0,%%mm1\n" /* mm1 = [pix4-7] */ - "punpcklbw %%mm0,%%mm2\n" /* mm2 = [pix0-3] */ - - "movq %%mm3,%%mm4\n" /* mm4 = mm3 = pix[8-15] */ - "punpckhbw %%mm0,%%mm3\n" /* mm3 = [pix12-15] */ - "punpcklbw %%mm0,%%mm4\n" /* mm4 = [pix8-11] */ - - "pmaddwd %%mm1,%%mm1\n" /* mm1 = (pix0^2+pix1^2,pix2^2+pix3^2) */ - "pmaddwd %%mm2,%%mm2\n" /* mm2 = (pix4^2+pix5^2,pix6^2+pix7^2) */ - - "pmaddwd %%mm3,%%mm3\n" - "pmaddwd %%mm4,%%mm4\n" - - "paddd %%mm1,%%mm2\n" /* mm2 = (pix0^2+pix1^2+pix4^2+pix5^2, - pix2^2+pix3^2+pix6^2+pix7^2) */ - "paddd %%mm3,%%mm4\n" - "paddd %%mm2,%%mm7\n" - - "add %2, %0\n" - "paddd %%mm4,%%mm7\n" - "dec %%ecx\n" - "jnz 1b\n" - - "movq %%mm7,%%mm1\n" - "psrlq $32, %%mm7\n" /* shift hi dword to lo */ - "paddd %%mm7,%%mm1\n" - "movd %%mm1,%1\n" - : "+r" (pix), "=r"(tmp) : "r" ((x86_reg)line_size) : "%ecx" ); - return tmp; -} - -static int sse8_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - __asm__ volatile ( - "movl %4,%%ecx\n" - "shr $1,%%ecx\n" - "pxor %%mm0,%%mm0\n" /* mm0 = 0 */ - "pxor %%mm7,%%mm7\n" /* mm7 holds the sum */ - "1:\n" - "movq (%0),%%mm1\n" /* mm1 = pix1[0][0-7] */ - "movq (%1),%%mm2\n" /* mm2 = pix2[0][0-7] */ - "movq (%0,%3),%%mm3\n" /* mm3 = pix1[1][0-7] */ - "movq (%1,%3),%%mm4\n" /* mm4 = pix2[1][0-7] */ - - /* todo: mm1-mm2, mm3-mm4 */ - /* algo: subtract mm1 from mm2 with saturation and vice versa */ - /* OR the results to get absolute difference */ - "movq %%mm1,%%mm5\n" - "movq %%mm3,%%mm6\n" - "psubusb %%mm2,%%mm1\n" - "psubusb %%mm4,%%mm3\n" - "psubusb %%mm5,%%mm2\n" - "psubusb %%mm6,%%mm4\n" - - "por %%mm1,%%mm2\n" - "por %%mm3,%%mm4\n" - - /* now convert to 16-bit vectors so we can square them */ - "movq %%mm2,%%mm1\n" - "movq %%mm4,%%mm3\n" - - "punpckhbw %%mm0,%%mm2\n" - "punpckhbw %%mm0,%%mm4\n" - "punpcklbw %%mm0,%%mm1\n" /* mm1 now spread over (mm1,mm2) */ - "punpcklbw %%mm0,%%mm3\n" /* mm4 now spread over (mm3,mm4) */ - - "pmaddwd %%mm2,%%mm2\n" - "pmaddwd %%mm4,%%mm4\n" - "pmaddwd %%mm1,%%mm1\n" - "pmaddwd %%mm3,%%mm3\n" - - "lea (%0,%3,2), %0\n" /* pix1 += 2*line_size */ - "lea (%1,%3,2), %1\n" /* pix2 += 2*line_size */ - - "paddd %%mm2,%%mm1\n" - "paddd %%mm4,%%mm3\n" - "paddd %%mm1,%%mm7\n" - "paddd %%mm3,%%mm7\n" - - "decl %%ecx\n" - "jnz 1b\n" - - "movq %%mm7,%%mm1\n" - "psrlq $32, %%mm7\n" /* shift hi dword to lo */ - "paddd %%mm7,%%mm1\n" - "movd %%mm1,%2\n" - : "+r" (pix1), "+r" (pix2), "=r"(tmp) - : "r" ((x86_reg)line_size) , "m" (h) - : "%ecx"); - return tmp; -} - -static int sse16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - __asm__ volatile ( - "movl %4,%%ecx\n" - "pxor %%mm0,%%mm0\n" /* mm0 = 0 */ - "pxor %%mm7,%%mm7\n" /* mm7 holds the sum */ - "1:\n" - "movq (%0),%%mm1\n" /* mm1 = pix1[0-7] */ - "movq (%1),%%mm2\n" /* mm2 = pix2[0-7] */ - "movq 8(%0),%%mm3\n" /* mm3 = pix1[8-15] */ - "movq 8(%1),%%mm4\n" /* mm4 = pix2[8-15] */ - - /* todo: mm1-mm2, mm3-mm4 */ - /* algo: subtract mm1 from mm2 with saturation and vice versa */ - /* OR the results to get absolute difference */ - "movq %%mm1,%%mm5\n" - "movq %%mm3,%%mm6\n" - "psubusb %%mm2,%%mm1\n" - "psubusb %%mm4,%%mm3\n" - "psubusb %%mm5,%%mm2\n" - "psubusb %%mm6,%%mm4\n" - - "por %%mm1,%%mm2\n" - "por %%mm3,%%mm4\n" - - /* now convert to 16-bit vectors so we can square them */ - "movq %%mm2,%%mm1\n" - "movq %%mm4,%%mm3\n" - - "punpckhbw %%mm0,%%mm2\n" - "punpckhbw %%mm0,%%mm4\n" - "punpcklbw %%mm0,%%mm1\n" /* mm1 now spread over (mm1,mm2) */ - "punpcklbw %%mm0,%%mm3\n" /* mm4 now spread over (mm3,mm4) */ - - "pmaddwd %%mm2,%%mm2\n" - "pmaddwd %%mm4,%%mm4\n" - "pmaddwd %%mm1,%%mm1\n" - "pmaddwd %%mm3,%%mm3\n" - - "add %3,%0\n" - "add %3,%1\n" - - "paddd %%mm2,%%mm1\n" - "paddd %%mm4,%%mm3\n" - "paddd %%mm1,%%mm7\n" - "paddd %%mm3,%%mm7\n" - - "decl %%ecx\n" - "jnz 1b\n" - - "movq %%mm7,%%mm1\n" - "psrlq $32, %%mm7\n" /* shift hi dword to lo */ - "paddd %%mm7,%%mm1\n" - "movd %%mm1,%2\n" - : "+r" (pix1), "+r" (pix2), "=r"(tmp) - : "r" ((x86_reg)line_size) , "m" (h) - : "%ecx"); - return tmp; -} - -static int sse16_sse2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - __asm__ volatile ( - "shr $1,%2\n" - "pxor %%xmm0,%%xmm0\n" /* mm0 = 0 */ - "pxor %%xmm7,%%xmm7\n" /* mm7 holds the sum */ - "1:\n" - "movdqu (%0),%%xmm1\n" /* mm1 = pix1[0][0-15] */ - "movdqu (%1),%%xmm2\n" /* mm2 = pix2[0][0-15] */ - "movdqu (%0,%4),%%xmm3\n" /* mm3 = pix1[1][0-15] */ - "movdqu (%1,%4),%%xmm4\n" /* mm4 = pix2[1][0-15] */ - - /* todo: mm1-mm2, mm3-mm4 */ - /* algo: subtract mm1 from mm2 with saturation and vice versa */ - /* OR the results to get absolute difference */ - "movdqa %%xmm1,%%xmm5\n" - "movdqa %%xmm3,%%xmm6\n" - "psubusb %%xmm2,%%xmm1\n" - "psubusb %%xmm4,%%xmm3\n" - "psubusb %%xmm5,%%xmm2\n" - "psubusb %%xmm6,%%xmm4\n" - - "por %%xmm1,%%xmm2\n" - "por %%xmm3,%%xmm4\n" - - /* now convert to 16-bit vectors so we can square them */ - "movdqa %%xmm2,%%xmm1\n" - "movdqa %%xmm4,%%xmm3\n" - - "punpckhbw %%xmm0,%%xmm2\n" - "punpckhbw %%xmm0,%%xmm4\n" - "punpcklbw %%xmm0,%%xmm1\n" /* mm1 now spread over (mm1,mm2) */ - "punpcklbw %%xmm0,%%xmm3\n" /* mm4 now spread over (mm3,mm4) */ - - "pmaddwd %%xmm2,%%xmm2\n" - "pmaddwd %%xmm4,%%xmm4\n" - "pmaddwd %%xmm1,%%xmm1\n" - "pmaddwd %%xmm3,%%xmm3\n" - - "lea (%0,%4,2), %0\n" /* pix1 += 2*line_size */ - "lea (%1,%4,2), %1\n" /* pix2 += 2*line_size */ - - "paddd %%xmm2,%%xmm1\n" - "paddd %%xmm4,%%xmm3\n" - "paddd %%xmm1,%%xmm7\n" - "paddd %%xmm3,%%xmm7\n" - - "decl %2\n" - "jnz 1b\n" - - "movdqa %%xmm7,%%xmm1\n" - "psrldq $8, %%xmm7\n" /* shift hi qword to lo */ - "paddd %%xmm1,%%xmm7\n" - "movdqa %%xmm7,%%xmm1\n" - "psrldq $4, %%xmm7\n" /* shift hi dword to lo */ - "paddd %%xmm1,%%xmm7\n" - "movd %%xmm7,%3\n" - : "+r" (pix1), "+r" (pix2), "+r"(h), "=r"(tmp) - : "r" ((x86_reg)line_size)); - return tmp; -} - -static int hf_noise8_mmx(uint8_t * pix1, int line_size, int h) { - int tmp; - __asm__ volatile ( - "movl %3,%%ecx\n" - "pxor %%mm7,%%mm7\n" - "pxor %%mm6,%%mm6\n" - - "movq (%0),%%mm0\n" - "movq %%mm0, %%mm1\n" - "psllq $8, %%mm0\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm0\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq %%mm4, %%mm1\n" - "psllq $8, %%mm4\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm4\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "1:\n" - - "movq (%0),%%mm0\n" - "movq %%mm0, %%mm1\n" - "psllq $8, %%mm0\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm0\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - "psubw %%mm0, %%mm4\n" - "psubw %%mm2, %%mm5\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm4, %%mm3\n\t" - "pcmpgtw %%mm5, %%mm1\n\t" - "pxor %%mm3, %%mm4\n" - "pxor %%mm1, %%mm5\n" - "psubw %%mm3, %%mm4\n" - "psubw %%mm1, %%mm5\n" - "paddw %%mm4, %%mm5\n" - "paddw %%mm5, %%mm6\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq %%mm4, %%mm1\n" - "psllq $8, %%mm4\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm4\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "subl $2, %%ecx\n" - " jnz 1b\n" - - "movq %%mm6, %%mm0\n" - "punpcklwd %%mm7,%%mm0\n" - "punpckhwd %%mm7,%%mm6\n" - "paddd %%mm0, %%mm6\n" - - "movq %%mm6,%%mm0\n" - "psrlq $32, %%mm6\n" - "paddd %%mm6,%%mm0\n" - "movd %%mm0,%1\n" - : "+r" (pix1), "=r"(tmp) - : "r" ((x86_reg)line_size) , "g" (h-2) - : "%ecx"); - return tmp; -} - -static int hf_noise16_mmx(uint8_t * pix1, int line_size, int h) { - int tmp; - uint8_t * pix= pix1; - __asm__ volatile ( - "movl %3,%%ecx\n" - "pxor %%mm7,%%mm7\n" - "pxor %%mm6,%%mm6\n" - - "movq (%0),%%mm0\n" - "movq 1(%0),%%mm1\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq 1(%0),%%mm1\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "1:\n" - - "movq (%0),%%mm0\n" - "movq 1(%0),%%mm1\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - "psubw %%mm0, %%mm4\n" - "psubw %%mm2, %%mm5\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm4, %%mm3\n\t" - "pcmpgtw %%mm5, %%mm1\n\t" - "pxor %%mm3, %%mm4\n" - "pxor %%mm1, %%mm5\n" - "psubw %%mm3, %%mm4\n" - "psubw %%mm1, %%mm5\n" - "paddw %%mm4, %%mm5\n" - "paddw %%mm5, %%mm6\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq 1(%0),%%mm1\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "subl $2, %%ecx\n" - " jnz 1b\n" - - "movq %%mm6, %%mm0\n" - "punpcklwd %%mm7,%%mm0\n" - "punpckhwd %%mm7,%%mm6\n" - "paddd %%mm0, %%mm6\n" - - "movq %%mm6,%%mm0\n" - "psrlq $32, %%mm6\n" - "paddd %%mm6,%%mm0\n" - "movd %%mm0,%1\n" - : "+r" (pix1), "=r"(tmp) - : "r" ((x86_reg)line_size) , "g" (h-2) - : "%ecx"); - return tmp + hf_noise8_mmx(pix+8, line_size, h); -} - -static int nsse16_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - MpegEncContext *c = p; - int score1, score2; - - if(c) score1 = c->dsp.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 + FFABS(score2)*c->avctx->nsse_weight; - else return score1 + FFABS(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 + FFABS(score2)*c->avctx->nsse_weight; - else return score1 + FFABS(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" - "jmp 2f\n" - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - "2:\n" - 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" ((x86_reg)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" - "jmp 2f\n" - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - "2:\n" - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - - "subl $2, %%ecx\n" - "jnz 1b\n" - - "movd %%mm6,%1\n" - : "+r" (pix), "=r"(tmp) - : "r" ((x86_reg)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" - "psubb %%mm2, %%mm0\n" - "psubb %%mm3, %%mm1\n" - "pxor %%mm7, %%mm0\n" - "pxor %%mm7, %%mm1\n" - "jmp 2f\n" - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - "2:\n" - 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" ((x86_reg)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" - "psubb %%mm2, %%mm0\n" - "psubb %%mm3, %%mm1\n" - "pxor %%mm7, %%mm0\n" - "pxor %%mm7, %%mm1\n" - "jmp 2f\n" - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - "2:\n" - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - - "subl $2, %%ecx\n" - "jnz 1b\n" - - "movd %%mm6,%2\n" - : "+r" (pix1), "+r" (pix2), "=r"(tmp) - : "r" ((x86_reg)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){ - x86_reg 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"((x86_reg)w-15) - ); - for(; idct_algo; - if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){ - if(mm_flags & FF_MM_SSE2){ - c->fdct = ff_fdct_sse2; - }else if(mm_flags & FF_MM_MMX2){ - c->fdct = ff_fdct_mmx2; - }else{ - c->fdct = ff_fdct_mmx; - } - } - - c->get_pixels = get_pixels_mmx; - c->diff_pixels = diff_pixels_mmx; - c->pix_sum = pix_sum16_mmx; - - c->diff_bytes= diff_bytes_mmx; - c->sum_abs_dctelem= sum_abs_dctelem_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 & FF_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; - - c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx; - - - if (mm_flags & FF_MM_MMX2) { - c->sum_abs_dctelem= sum_abs_dctelem_mmx2; - c->hadamard8_diff[0]= hadamard8_diff16_mmx2; - c->hadamard8_diff[1]= hadamard8_diff_mmx2; - c->vsad[4]= vsad_intra16_mmx2; - - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->vsad[0] = vsad16_mmx2; - } - - c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_mmx2; - } - - if(mm_flags & FF_MM_SSE2){ - c->get_pixels = get_pixels_sse2; - c->sum_abs_dctelem= sum_abs_dctelem_sse2; - c->hadamard8_diff[0]= hadamard8_diff16_sse2; - c->hadamard8_diff[1]= hadamard8_diff_sse2; -#if CONFIG_LPC - c->lpc_compute_autocorr = ff_lpc_compute_autocorr_sse2; -#endif - } - -#if HAVE_SSSE3 - if(mm_flags & FF_MM_SSSE3){ - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->try_8x8basis= try_8x8basis_ssse3; - } - c->add_8x8basis= add_8x8basis_ssse3; - c->sum_abs_dctelem= sum_abs_dctelem_ssse3; - c->hadamard8_diff[0]= hadamard8_diff16_ssse3; - c->hadamard8_diff[1]= hadamard8_diff_ssse3; - } -#endif - - if(mm_flags & FF_MM_3DNOW){ - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->try_8x8basis= try_8x8basis_3dnow; - } - c->add_8x8basis= add_8x8basis_3dnow; - } - } - - dsputil_init_pix_mmx(c, avctx); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/fdct_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/fdct_mmx.c deleted file mode 100644 index 6e52285..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/fdct_mmx.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * 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 - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "libavcodec/dsputil.h" - -////////////////////////////////////////////////////////////////////// -// -// 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)) - -#define X8(x) x,x,x,x,x,x,x,x - -//concatenated table, for forward DCT transformation -DECLARE_ALIGNED(16, static const int16_t, fdct_tg_all_16)[24] = { - X8(13036), // tg * (2<<16) + 0.5 - X8(27146), // tg * (2<<16) + 0.5 - X8(-21746) // tg * (2<<16) + 0.5 -}; - -DECLARE_ALIGNED(16, static const int16_t, ocos_4_16)[8] = { - X8(23170) //cos * (2<<15) + 0.5 -}; - -DECLARE_ALIGNED(16, static const int16_t, fdct_one_corr)[8] = { X8(1) }; - -DECLARE_ALIGNED(8, static const int32_t, fdct_r_row)[2] = {RND_FRW_ROW, RND_FRW_ROW }; - -static struct -{ - DECLARE_ALIGNED(16, const int32_t, fdct_r_row_sse2)[4]; -} fdct_r_row_sse2 = -{{ - RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW -}}; -//DECLARE_ALIGNED(16, static const long, fdct_r_row_sse2)[4] = {RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW}; - -DECLARE_ALIGNED(8, static const int16_t, tab_frw_01234567)[] = { // 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, -}; - -static struct -{ - DECLARE_ALIGNED(16, const int16_t, tab_frw_01234567_sse2)[256]; -} tab_frw_01234567_sse2 = -{{ -//DECLARE_ALIGNED(16, static const int16_t, tab_frw_01234567_sse2)[] = { // 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 -}}; - -#define S(s) AV_TOSTRING(s) //AV_STRINGIFY is too long - -#define FDCT_COL(cpu, mm, mov)\ -static av_always_inline void fdct_col_##cpu(const int16_t *in, int16_t *out, int offset)\ -{\ - __asm__ volatile (\ - #mov" 16(%0), %%"#mm"0 \n\t" \ - #mov" 96(%0), %%"#mm"1 \n\t" \ - #mov" %%"#mm"0, %%"#mm"2 \n\t" \ - #mov" 32(%0), %%"#mm"3 \n\t" \ - "paddsw %%"#mm"1, %%"#mm"0 \n\t" \ - #mov" 80(%0), %%"#mm"4 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)", %%"#mm"0 \n\t" \ - #mov" (%0), %%"#mm"5 \n\t" \ - "paddsw %%"#mm"3, %%"#mm"4 \n\t" \ - "paddsw 112(%0), %%"#mm"5 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)", %%"#mm"4 \n\t" \ - #mov" %%"#mm"0, %%"#mm"6 \n\t" \ - "psubsw %%"#mm"1, %%"#mm"2 \n\t" \ - #mov" 16(%1), %%"#mm"1 \n\t" \ - "psubsw %%"#mm"4, %%"#mm"0 \n\t" \ - #mov" 48(%0), %%"#mm"7 \n\t" \ - "pmulhw %%"#mm"0, %%"#mm"1 \n\t" \ - "paddsw 64(%0), %%"#mm"7 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)", %%"#mm"5 \n\t" \ - "paddsw %%"#mm"4, %%"#mm"6 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)", %%"#mm"7 \n\t" \ - #mov" %%"#mm"5, %%"#mm"4 \n\t" \ - "psubsw %%"#mm"7, %%"#mm"5 \n\t" \ - "paddsw %%"#mm"5, %%"#mm"1 \n\t" \ - "paddsw %%"#mm"7, %%"#mm"4 \n\t" \ - "por (%2), %%"#mm"1 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)"+1, %%"#mm"2 \n\t" \ - "pmulhw 16(%1), %%"#mm"5 \n\t" \ - #mov" %%"#mm"4, %%"#mm"7 \n\t" \ - "psubsw 80(%0), %%"#mm"3 \n\t" \ - "psubsw %%"#mm"6, %%"#mm"4 \n\t" \ - #mov" %%"#mm"1, 32(%3) \n\t" \ - "paddsw %%"#mm"6, %%"#mm"7 \n\t" \ - #mov" 48(%0), %%"#mm"1 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)"+1, %%"#mm"3 \n\t" \ - "psubsw 64(%0), %%"#mm"1 \n\t" \ - #mov" %%"#mm"2, %%"#mm"6 \n\t" \ - #mov" %%"#mm"4, 64(%3) \n\t" \ - "paddsw %%"#mm"3, %%"#mm"2 \n\t" \ - "pmulhw (%4), %%"#mm"2 \n\t" \ - "psubsw %%"#mm"3, %%"#mm"6 \n\t" \ - "pmulhw (%4), %%"#mm"6 \n\t" \ - "psubsw %%"#mm"0, %%"#mm"5 \n\t" \ - "por (%2), %%"#mm"5 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)", %%"#mm"1 \n\t" \ - "por (%2), %%"#mm"2 \n\t" \ - #mov" %%"#mm"1, %%"#mm"4 \n\t" \ - #mov" (%0), %%"#mm"3 \n\t" \ - "paddsw %%"#mm"6, %%"#mm"1 \n\t" \ - "psubsw 112(%0), %%"#mm"3 \n\t" \ - "psubsw %%"#mm"6, %%"#mm"4 \n\t" \ - #mov" (%1), %%"#mm"0 \n\t" \ - "psllw $"S(SHIFT_FRW_COL)", %%"#mm"3 \n\t" \ - #mov" 32(%1), %%"#mm"6 \n\t" \ - "pmulhw %%"#mm"1, %%"#mm"0 \n\t" \ - #mov" %%"#mm"7, (%3) \n\t" \ - "pmulhw %%"#mm"4, %%"#mm"6 \n\t" \ - #mov" %%"#mm"5, 96(%3) \n\t" \ - #mov" %%"#mm"3, %%"#mm"7 \n\t" \ - #mov" 32(%1), %%"#mm"5 \n\t" \ - "psubsw %%"#mm"2, %%"#mm"7 \n\t" \ - "paddsw %%"#mm"2, %%"#mm"3 \n\t" \ - "pmulhw %%"#mm"7, %%"#mm"5 \n\t" \ - "paddsw %%"#mm"3, %%"#mm"0 \n\t" \ - "paddsw %%"#mm"4, %%"#mm"6 \n\t" \ - "pmulhw (%1), %%"#mm"3 \n\t" \ - "por (%2), %%"#mm"0 \n\t" \ - "paddsw %%"#mm"7, %%"#mm"5 \n\t" \ - "psubsw %%"#mm"6, %%"#mm"7 \n\t" \ - #mov" %%"#mm"0, 16(%3) \n\t" \ - "paddsw %%"#mm"4, %%"#mm"5 \n\t" \ - #mov" %%"#mm"7, 48(%3) \n\t" \ - "psubsw %%"#mm"1, %%"#mm"3 \n\t" \ - #mov" %%"#mm"5, 80(%3) \n\t" \ - #mov" %%"#mm"3, 112(%3) \n\t" \ - : \ - : "r" (in + offset), "r" (fdct_tg_all_16), "r" (fdct_one_corr), \ - "r" (out + offset), "r" (ocos_4_16)); \ -} - -FDCT_COL(mmx, mm, movq) -FDCT_COL(sse2, xmm, movdqa) - -static av_always_inline void fdct_row_sse2(const int16_t *in, int16_t *out) -{ - __asm__ volatile( -#define FDCT_ROW_SSE2_H1(i,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" - -#define FDCT_ROW_SSE2_H2(i,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" - -#define FDCT_ROW_SSE2(i) \ - "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" - - "movdqa (%2), %%xmm6 \n\t" - FDCT_ROW_SSE2_H1(0,0) - FDCT_ROW_SSE2(0) - FDCT_ROW_SSE2_H2(64,0) - FDCT_ROW_SSE2(64) - - FDCT_ROW_SSE2_H1(16,64) - FDCT_ROW_SSE2(16) - FDCT_ROW_SSE2_H2(112,64) - FDCT_ROW_SSE2(112) - - FDCT_ROW_SSE2_H1(32,128) - FDCT_ROW_SSE2(32) - FDCT_ROW_SSE2_H2(96,128) - FDCT_ROW_SSE2(96) - - FDCT_ROW_SSE2_H1(48,192) - FDCT_ROW_SSE2(48) - FDCT_ROW_SSE2_H2(80,192) - FDCT_ROW_SSE2(80) - : - : "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 av_always_inline void fdct_row_mmx2(const int16_t *in, int16_t *out, const int16_t *table) -{ - __asm__ volatile ( - "pshufw $0x1B, 8(%0), %%mm5 \n\t" - "movq (%0), %%mm0 \n\t" - "movq %%mm0, %%mm1 \n\t" - "paddsw %%mm5, %%mm0 \n\t" - "psubsw %%mm5, %%mm1 \n\t" - "movq %%mm0, %%mm2 \n\t" - "punpckldq %%mm1, %%mm0 \n\t" - "punpckhdq %%mm1, %%mm2 \n\t" - "movq (%1), %%mm1 \n\t" - "movq 8(%1), %%mm3 \n\t" - "movq 16(%1), %%mm4 \n\t" - "movq 24(%1), %%mm5 \n\t" - "movq 32(%1), %%mm6 \n\t" - "movq 40(%1), %%mm7 \n\t" - "pmaddwd %%mm0, %%mm1 \n\t" - "pmaddwd %%mm2, %%mm3 \n\t" - "pmaddwd %%mm0, %%mm4 \n\t" - "pmaddwd %%mm2, %%mm5 \n\t" - "pmaddwd %%mm0, %%mm6 \n\t" - "pmaddwd %%mm2, %%mm7 \n\t" - "pmaddwd 48(%1), %%mm0 \n\t" - "pmaddwd 56(%1), %%mm2 \n\t" - "paddd %%mm1, %%mm3 \n\t" - "paddd %%mm4, %%mm5 \n\t" - "paddd %%mm6, %%mm7 \n\t" - "paddd %%mm0, %%mm2 \n\t" - "movq (%2), %%mm0 \n\t" - "paddd %%mm0, %%mm3 \n\t" - "paddd %%mm0, %%mm5 \n\t" - "paddd %%mm0, %%mm7 \n\t" - "paddd %%mm0, %%mm2 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm3 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm5 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm7 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm2 \n\t" - "packssdw %%mm5, %%mm3 \n\t" - "packssdw %%mm2, %%mm7 \n\t" - "movq %%mm3, (%3) \n\t" - "movq %%mm7, 8(%3) \n\t" - : - : "r" (in), "r" (table), "r" (fdct_r_row), "r" (out)); -} - -static av_always_inline void fdct_row_mmx(const int16_t *in, int16_t *out, const int16_t *table) -{ - //FIXME reorder (I do not have an old MMX-only CPU here to benchmark ...) - __asm__ volatile( - "movd 12(%0), %%mm1 \n\t" - "punpcklwd 8(%0), %%mm1 \n\t" - "movq %%mm1, %%mm2 \n\t" - "psrlq $0x20, %%mm1 \n\t" - "movq 0(%0), %%mm0 \n\t" - "punpcklwd %%mm2, %%mm1 \n\t" - "movq %%mm0, %%mm5 \n\t" - "paddsw %%mm1, %%mm0 \n\t" - "psubsw %%mm1, %%mm5 \n\t" - "movq %%mm0, %%mm2 \n\t" - "punpckldq %%mm5, %%mm0 \n\t" - "punpckhdq %%mm5, %%mm2 \n\t" - "movq 0(%1), %%mm1 \n\t" - "movq 8(%1), %%mm3 \n\t" - "movq 16(%1), %%mm4 \n\t" - "movq 24(%1), %%mm5 \n\t" - "movq 32(%1), %%mm6 \n\t" - "movq 40(%1), %%mm7 \n\t" - "pmaddwd %%mm0, %%mm1 \n\t" - "pmaddwd %%mm2, %%mm3 \n\t" - "pmaddwd %%mm0, %%mm4 \n\t" - "pmaddwd %%mm2, %%mm5 \n\t" - "pmaddwd %%mm0, %%mm6 \n\t" - "pmaddwd %%mm2, %%mm7 \n\t" - "pmaddwd 48(%1), %%mm0 \n\t" - "pmaddwd 56(%1), %%mm2 \n\t" - "paddd %%mm1, %%mm3 \n\t" - "paddd %%mm4, %%mm5 \n\t" - "paddd %%mm6, %%mm7 \n\t" - "paddd %%mm0, %%mm2 \n\t" - "movq (%2), %%mm0 \n\t" - "paddd %%mm0, %%mm3 \n\t" - "paddd %%mm0, %%mm5 \n\t" - "paddd %%mm0, %%mm7 \n\t" - "paddd %%mm0, %%mm2 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm3 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm5 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm7 \n\t" - "psrad $"S(SHIFT_FRW_ROW)", %%mm2 \n\t" - "packssdw %%mm5, %%mm3 \n\t" - "packssdw %%mm2, %%mm7 \n\t" - "movq %%mm3, 0(%3) \n\t" - "movq %%mm7, 8(%3) \n\t" - : - : "r" (in), "r" (table), "r" (fdct_r_row), "r" (out)); -} - -void ff_fdct_mmx(int16_t *block) -{ - DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; - int16_t * block1= (int16_t*)align_tmp; - const int16_t *table= tab_frw_01234567; - int i; - - fdct_col_mmx(block, block1, 0); - fdct_col_mmx(block, block1, 4); - - for(i=8;i>0;i--) { - fdct_row_mmx(block1, block, table); - block1 += 8; - table += 32; - block += 8; - } -} - -void ff_fdct_mmx2(int16_t *block) -{ - DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; - int16_t *block1= (int16_t*)align_tmp; - const int16_t *table= tab_frw_01234567; - int i; - - fdct_col_mmx(block, block1, 0); - fdct_col_mmx(block, block1, 4); - - for(i=8;i>0;i--) { - fdct_row_mmx2(block1, block, table); - block1 += 8; - table += 32; - block += 8; - } -} - -void ff_fdct_sse2(int16_t *block) -{ - DECLARE_ALIGNED(16, int64_t, align_tmp)[16]; - int16_t * const block1= (int16_t*)align_tmp; - - fdct_col_sse2(block, block1, 0); - fdct_row_sse2(block1, block); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/fft.c b/tizen/distrib/ffmpeg/libavcodec/x86/fft.c deleted file mode 100644 index 2c46c63..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/fft.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "fft.h" - -av_cold void ff_fft_init_mmx(FFTContext *s) -{ -#if HAVE_YASM - int has_vectors = mm_support(); - if (has_vectors & FF_MM_SSE && HAVE_SSE) { - /* SSE for P3/P4/K8 */ - s->imdct_calc = ff_imdct_calc_sse; - s->imdct_half = ff_imdct_half_sse; - s->fft_permute = ff_fft_permute_sse; - s->fft_calc = ff_fft_calc_sse; - } else if (has_vectors & FF_MM_3DNOWEXT && HAVE_AMD3DNOWEXT) { - /* 3DNowEx for K7 */ - s->imdct_calc = ff_imdct_calc_3dn2; - s->imdct_half = ff_imdct_half_3dn2; - s->fft_calc = ff_fft_calc_3dn2; - } else if (has_vectors & FF_MM_3DNOW && HAVE_AMD3DNOW) { - /* 3DNow! for K6-2/3 */ - s->imdct_calc = ff_imdct_calc_3dn; - s->imdct_half = ff_imdct_half_3dn; - s->fft_calc = ff_fft_calc_3dn; - } -#endif -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/fft.h b/tizen/distrib/ffmpeg/libavcodec/x86/fft.h deleted file mode 100644 index 7ef5839..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/fft.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_FFT_H -#define AVCODEC_X86_FFT_H - -#include "libavcodec/fft.h" - -void ff_fft_permute_sse(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_imdct_calc_3dn(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_imdct_half_3dn(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_imdct_calc_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input); -void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input); - -#endif diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn.c b/tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn.c deleted file mode 100644 index 6f2e2e8..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * FFT/MDCT transform with 3DNow! optimizations - * Copyright (c) 2008 Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define EMULATE_3DNOWEXT -#include "fft_3dn2.c" diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn2.c b/tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn2.c deleted file mode 100644 index b3bec46..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/fft_3dn2.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * FFT/MDCT transform with Extended 3DNow! optimizations - * Copyright (c) 2006-2008 Zuxy MENG Jie, Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "fft.h" - -DECLARE_ALIGNED(8, static const int, m1m1)[2] = { 1<<31, 1<<31 }; - -#ifdef EMULATE_3DNOWEXT -#define PSWAPD(s,d)\ - "movq "#s","#d"\n"\ - "psrlq $32,"#d"\n"\ - "punpckldq "#s","#d"\n" -#define ff_fft_calc_3dn2 ff_fft_calc_3dn -#define ff_fft_dispatch_3dn2 ff_fft_dispatch_3dn -#define ff_fft_dispatch_interleave_3dn2 ff_fft_dispatch_interleave_3dn -#define ff_imdct_calc_3dn2 ff_imdct_calc_3dn -#define ff_imdct_half_3dn2 ff_imdct_half_3dn -#else -#define PSWAPD(s,d) "pswapd "#s","#d"\n" -#endif - -void ff_fft_dispatch_3dn2(FFTComplex *z, int nbits); -void ff_fft_dispatch_interleave_3dn2(FFTComplex *z, int nbits); - -void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z) -{ - int n = 1<nbits; - int i; - ff_fft_dispatch_interleave_3dn2(z, s->nbits); - __asm__ volatile("femms"); - if(n <= 8) - for(i=0; imdct_bits; - long n2 = n >> 1; - long n4 = n >> 2; - long n8 = n >> 3; - const uint16_t *revtab = s->revtab; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - const FFTSample *in1, *in2; - FFTComplex *z = (FFTComplex *)output; - - /* pre rotation */ - in1 = input; - in2 = input + n2 - 1; -#ifdef EMULATE_3DNOWEXT - __asm__ volatile("movd %0, %%mm7" ::"r"(1<<31)); -#endif - for(k = 0; k < n4; k++) { - // FIXME a single block is faster, but gcc 2.95 and 3.4.x on 32bit can't compile it - __asm__ volatile( - "movd %0, %%mm0 \n" - "movd %2, %%mm1 \n" - "punpckldq %1, %%mm0 \n" - "punpckldq %3, %%mm1 \n" - "movq %%mm0, %%mm2 \n" - PSWAPD( %%mm1, %%mm3 ) - "pfmul %%mm1, %%mm0 \n" - "pfmul %%mm3, %%mm2 \n" -#ifdef EMULATE_3DNOWEXT - "movq %%mm0, %%mm1 \n" - "punpckhdq %%mm2, %%mm0 \n" - "punpckldq %%mm2, %%mm1 \n" - "pxor %%mm7, %%mm0 \n" - "pfadd %%mm1, %%mm0 \n" -#else - "pfpnacc %%mm2, %%mm0 \n" -#endif - ::"m"(in2[-2*k]), "m"(in1[2*k]), - "m"(tcos[k]), "m"(tsin[k]) - ); - __asm__ volatile( - "movq %%mm0, %0 \n\t" - :"=m"(z[revtab[k]]) - ); - } - - ff_fft_dispatch_3dn2(z, s->nbits); - -#define CMUL(j,mm0,mm1)\ - "movq (%2,"#j",2), %%mm6 \n"\ - "movq 8(%2,"#j",2), "#mm0"\n"\ - "movq %%mm6, "#mm1"\n"\ - "movq "#mm0",%%mm7 \n"\ - "pfmul (%3,"#j"), %%mm6 \n"\ - "pfmul (%4,"#j"), "#mm0"\n"\ - "pfmul (%4,"#j"), "#mm1"\n"\ - "pfmul (%3,"#j"), %%mm7 \n"\ - "pfsub %%mm6, "#mm0"\n"\ - "pfadd %%mm7, "#mm1"\n" - - /* post rotation */ - j = -n2; - k = n2-8; - __asm__ volatile( - "1: \n" - CMUL(%0, %%mm0, %%mm1) - CMUL(%1, %%mm2, %%mm3) - "movd %%mm0, (%2,%0,2) \n" - "movd %%mm1,12(%2,%1,2) \n" - "movd %%mm2, (%2,%1,2) \n" - "movd %%mm3,12(%2,%0,2) \n" - "psrlq $32, %%mm0 \n" - "psrlq $32, %%mm1 \n" - "psrlq $32, %%mm2 \n" - "psrlq $32, %%mm3 \n" - "movd %%mm0, 8(%2,%0,2) \n" - "movd %%mm1, 4(%2,%1,2) \n" - "movd %%mm2, 8(%2,%1,2) \n" - "movd %%mm3, 4(%2,%0,2) \n" - "sub $8, %1 \n" - "add $8, %0 \n" - "jl 1b \n" - :"+r"(j), "+r"(k) - :"r"(z+n8), "r"(tcos+n8), "r"(tsin+n8) - :"memory" - ); - __asm__ volatile("femms"); -} - -void ff_imdct_calc_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - x86_reg j, k; - long n = 1 << s->mdct_bits; - long n4 = n >> 2; - - ff_imdct_half_3dn2(s, output+n4, input); - - j = -n; - k = n-8; - __asm__ volatile( - "movq %4, %%mm7 \n" - "1: \n" - PSWAPD((%2,%1), %%mm0) - PSWAPD((%3,%0), %%mm1) - "pxor %%mm7, %%mm0 \n" - "movq %%mm1, (%3,%1) \n" - "movq %%mm0, (%2,%0) \n" - "sub $8, %1 \n" - "add $8, %0 \n" - "jl 1b \n" - :"+r"(j), "+r"(k) - :"r"(output+n4), "r"(output+n4*3), - "m"(*m1m1) - ); - __asm__ volatile("femms"); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/fft_mmx.asm b/tizen/distrib/ffmpeg/libavcodec/x86/fft_mmx.asm deleted file mode 100644 index 9cb0ae1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/fft_mmx.asm +++ /dev/null @@ -1,480 +0,0 @@ -;****************************************************************************** -;* FFT transform with SSE/3DNow optimizations -;* Copyright (c) 2008 Loren Merritt -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg 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.1 of the License, or (at your option) any later version. -;* -;* FFmpeg 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 FFmpeg; if not, write to the Free Software -;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;****************************************************************************** - -; These functions are not individually interchangeable with the C versions. -; While C takes arrays of FFTComplex, SSE/3DNow leave intermediate results -; in blocks as conventient to the vector size. -; i.e. {4x real, 4x imaginary, 4x real, ...} (or 2x respectively) - -%include "x86inc.asm" - -SECTION_RODATA - -%define M_SQRT1_2 0.70710678118654752440 -ps_root2: times 4 dd M_SQRT1_2 -ps_root2mppm: dd -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2 -ps_m1p1: dd 1<<31, 0 - -%assign i 16 -%rep 13 -cextern ff_cos_ %+ i -%assign i i<<1 -%endrep - -%ifdef ARCH_X86_64 - %define pointer dq -%else - %define pointer dd -%endif - -%macro IF0 1+ -%endmacro -%macro IF1 1+ - %1 -%endmacro - -section .text align=16 - -%macro T2_3DN 4 ; z0, z1, mem0, mem1 - mova %1, %3 - mova %2, %1 - pfadd %1, %4 - pfsub %2, %4 -%endmacro - -%macro T4_3DN 6 ; z0, z1, z2, z3, tmp0, tmp1 - mova %5, %3 - pfsub %3, %4 - pfadd %5, %4 ; {t6,t5} - pxor %3, [ps_m1p1 GLOBAL] ; {t8,t7} - mova %6, %1 - pswapd %3, %3 - pfadd %1, %5 ; {r0,i0} - pfsub %6, %5 ; {r2,i2} - mova %4, %2 - pfadd %2, %3 ; {r1,i1} - pfsub %4, %3 ; {r3,i3} - SWAP %3, %6 -%endmacro - -; in: %1={r0,i0,r1,i1} %2={r2,i2,r3,i3} -; out: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} -%macro T4_SSE 3 - mova %3, %1 - shufps %1, %2, 0x64 ; {r0,i0,r3,i2} - shufps %3, %2, 0xce ; {r1,i1,r2,i3} - mova %2, %1 - addps %1, %3 ; {t1,t2,t6,t5} - subps %2, %3 ; {t3,t4,t8,t7} - mova %3, %1 - shufps %1, %2, 0x44 ; {t1,t2,t3,t4} - shufps %3, %2, 0xbe ; {t6,t5,t7,t8} - mova %2, %1 - addps %1, %3 ; {r0,i0,r1,i1} - subps %2, %3 ; {r2,i2,r3,i3} - mova %3, %1 - shufps %1, %2, 0x88 ; {r0,r1,r2,r3} - shufps %3, %2, 0xdd ; {i0,i1,i2,i3} - SWAP %2, %3 -%endmacro - -%macro T8_SSE 6 ; r0,i0,r1,i1,t0,t1 - mova %5, %3 - shufps %3, %4, 0x44 ; {r4,i4,r6,i6} - shufps %5, %4, 0xee ; {r5,i5,r7,i7} - mova %6, %3 - subps %3, %5 ; {r5,i5,r7,i7} - addps %6, %5 ; {t1,t2,t3,t4} - mova %5, %3 - shufps %5, %5, 0xb1 ; {i5,r5,i7,r7} - mulps %3, [ps_root2mppm GLOBAL] ; {-r5,i5,r7,-i7} - mulps %5, [ps_root2 GLOBAL] - addps %3, %5 ; {t8,t7,ta,t9} - mova %5, %6 - shufps %6, %3, 0x36 ; {t3,t2,t9,t8} - shufps %5, %3, 0x9c ; {t1,t4,t7,ta} - mova %3, %6 - addps %6, %5 ; {t1,t2,t9,ta} - subps %3, %5 ; {t6,t5,tc,tb} - mova %5, %6 - shufps %6, %3, 0xd8 ; {t1,t9,t5,tb} - shufps %5, %3, 0x8d ; {t2,ta,t6,tc} - mova %3, %1 - mova %4, %2 - addps %1, %6 ; {r0,r1,r2,r3} - addps %2, %5 ; {i0,i1,i2,i3} - subps %3, %6 ; {r4,r5,r6,r7} - subps %4, %5 ; {i4,i5,i6,i7} -%endmacro - -; scheduled for cpu-bound sizes -%macro PASS_SMALL 3 ; (to load m4-m7), wre, wim -IF%1 mova m4, Z(4) -IF%1 mova m5, Z(5) - mova m0, %2 ; wre - mova m2, m4 - mova m1, %3 ; wim - mova m3, m5 - mulps m2, m0 ; r2*wre -IF%1 mova m6, Z(6) - mulps m3, m1 ; i2*wim -IF%1 mova m7, Z(7) - mulps m4, m1 ; r2*wim - mulps m5, m0 ; i2*wre - addps m2, m3 ; r2*wre + i2*wim - mova m3, m1 - mulps m1, m6 ; r3*wim - subps m5, m4 ; i2*wre - r2*wim - mova m4, m0 - mulps m3, m7 ; i3*wim - mulps m4, m6 ; r3*wre - mulps m0, m7 ; i3*wre - subps m4, m3 ; r3*wre - i3*wim - mova m3, Z(0) - addps m0, m1 ; i3*wre + r3*wim - mova m1, m4 - addps m4, m2 ; t5 - subps m1, m2 ; t3 - subps m3, m4 ; r2 - addps m4, Z(0) ; r0 - mova m6, Z(2) - mova Z(4), m3 - mova Z(0), m4 - mova m3, m5 - subps m5, m0 ; t4 - mova m4, m6 - subps m6, m5 ; r3 - addps m5, m4 ; r1 - mova Z(6), m6 - mova Z(2), m5 - mova m2, Z(3) - addps m3, m0 ; t6 - subps m2, m1 ; i3 - mova m7, Z(1) - addps m1, Z(3) ; i1 - mova Z(7), m2 - mova Z(3), m1 - mova m4, m7 - subps m7, m3 ; i2 - addps m3, m4 ; i0 - mova Z(5), m7 - mova Z(1), m3 -%endmacro - -; scheduled to avoid store->load aliasing -%macro PASS_BIG 1 ; (!interleave) - mova m4, Z(4) ; r2 - mova m5, Z(5) ; i2 - mova m2, m4 - mova m0, [wq] ; wre - mova m3, m5 - mova m1, [wq+o1q] ; wim - mulps m2, m0 ; r2*wre - mova m6, Z(6) ; r3 - mulps m3, m1 ; i2*wim - mova m7, Z(7) ; i3 - mulps m4, m1 ; r2*wim - mulps m5, m0 ; i2*wre - addps m2, m3 ; r2*wre + i2*wim - mova m3, m1 - mulps m1, m6 ; r3*wim - subps m5, m4 ; i2*wre - r2*wim - mova m4, m0 - mulps m3, m7 ; i3*wim - mulps m4, m6 ; r3*wre - mulps m0, m7 ; i3*wre - subps m4, m3 ; r3*wre - i3*wim - mova m3, Z(0) - addps m0, m1 ; i3*wre + r3*wim - mova m1, m4 - addps m4, m2 ; t5 - subps m1, m2 ; t3 - subps m3, m4 ; r2 - addps m4, Z(0) ; r0 - mova m6, Z(2) - mova Z(4), m3 - mova Z(0), m4 - mova m3, m5 - subps m5, m0 ; t4 - mova m4, m6 - subps m6, m5 ; r3 - addps m5, m4 ; r1 -IF%1 mova Z(6), m6 -IF%1 mova Z(2), m5 - mova m2, Z(3) - addps m3, m0 ; t6 - subps m2, m1 ; i3 - mova m7, Z(1) - addps m1, Z(3) ; i1 -IF%1 mova Z(7), m2 -IF%1 mova Z(3), m1 - mova m4, m7 - subps m7, m3 ; i2 - addps m3, m4 ; i0 -IF%1 mova Z(5), m7 -IF%1 mova Z(1), m3 -%if %1==0 - mova m4, m5 ; r1 - mova m0, m6 ; r3 - unpcklps m5, m1 - unpckhps m4, m1 - unpcklps m6, m2 - unpckhps m0, m2 - mova m1, Z(0) - mova m2, Z(4) - mova Z(2), m5 - mova Z(3), m4 - mova Z(6), m6 - mova Z(7), m0 - mova m5, m1 ; r0 - mova m4, m2 ; r2 - unpcklps m1, m3 - unpckhps m5, m3 - unpcklps m2, m7 - unpckhps m4, m7 - mova Z(0), m1 - mova Z(1), m5 - mova Z(4), m2 - mova Z(5), m4 -%endif -%endmacro - -%macro PUNPCK 3 - mova %3, %1 - punpckldq %1, %2 - punpckhdq %3, %2 -%endmacro - -INIT_XMM -%define mova movaps - -%define Z(x) [r0+mmsize*x] - -align 16 -fft4_sse: - mova m0, Z(0) - mova m1, Z(1) - T4_SSE m0, m1, m2 - mova Z(0), m0 - mova Z(1), m1 - ret - -align 16 -fft8_sse: - mova m0, Z(0) - mova m1, Z(1) - T4_SSE m0, m1, m2 - mova m2, Z(2) - mova m3, Z(3) - T8_SSE m0, m1, m2, m3, m4, m5 - mova Z(0), m0 - mova Z(1), m1 - mova Z(2), m2 - mova Z(3), m3 - ret - -align 16 -fft16_sse: - mova m0, Z(0) - mova m1, Z(1) - T4_SSE m0, m1, m2 - mova m2, Z(2) - mova m3, Z(3) - T8_SSE m0, m1, m2, m3, m4, m5 - mova m4, Z(4) - mova m5, Z(5) - mova Z(0), m0 - mova Z(1), m1 - mova Z(2), m2 - mova Z(3), m3 - T4_SSE m4, m5, m6 - mova m6, Z(6) - mova m7, Z(7) - T4_SSE m6, m7, m0 - PASS_SMALL 0, [ff_cos_16 GLOBAL], [ff_cos_16+16 GLOBAL] - ret - - -INIT_MMX - -%macro FFT48_3DN 1 -align 16 -fft4%1: - T2_3DN m0, m1, Z(0), Z(1) - mova m2, Z(2) - mova m3, Z(3) - T4_3DN m0, m1, m2, m3, m4, m5 - PUNPCK m0, m1, m4 - PUNPCK m2, m3, m5 - mova Z(0), m0 - mova Z(1), m4 - mova Z(2), m2 - mova Z(3), m5 - ret - -align 16 -fft8%1: - T2_3DN m0, m1, Z(0), Z(1) - mova m2, Z(2) - mova m3, Z(3) - T4_3DN m0, m1, m2, m3, m4, m5 - mova Z(0), m0 - mova Z(2), m2 - T2_3DN m4, m5, Z(4), Z(5) - T2_3DN m6, m7, Z(6), Z(7) - pswapd m0, m5 - pswapd m2, m7 - pxor m0, [ps_m1p1 GLOBAL] - pxor m2, [ps_m1p1 GLOBAL] - pfsub m5, m0 - pfadd m7, m2 - pfmul m5, [ps_root2 GLOBAL] - pfmul m7, [ps_root2 GLOBAL] - T4_3DN m1, m3, m5, m7, m0, m2 - mova Z(5), m5 - mova Z(7), m7 - mova m0, Z(0) - mova m2, Z(2) - T4_3DN m0, m2, m4, m6, m5, m7 - PUNPCK m0, m1, m5 - PUNPCK m2, m3, m7 - mova Z(0), m0 - mova Z(1), m5 - mova Z(2), m2 - mova Z(3), m7 - PUNPCK m4, Z(5), m5 - PUNPCK m6, Z(7), m7 - mova Z(4), m4 - mova Z(5), m5 - mova Z(6), m6 - mova Z(7), m7 - ret -%endmacro - -FFT48_3DN _3dn2 - -%macro pswapd 2 -%ifidn %1, %2 - movd [r0+12], %1 - punpckhdq %1, [r0+8] -%else - movq %1, %2 - psrlq %1, 32 - punpckldq %1, %2 -%endif -%endmacro - -FFT48_3DN _3dn - - -%define Z(x) [zq + o1q*(x&6)*((x/6)^1) + o3q*(x/6) + mmsize*(x&1)] - -%macro DECL_PASS 2+ ; name, payload -align 16 -%1: -DEFINE_ARGS z, w, n, o1, o3 - lea o3q, [nq*3] - lea o1q, [nq*8] - shl o3q, 4 -.loop: - %2 - add zq, mmsize*2 - add wq, mmsize - sub nd, mmsize/8 - jg .loop - rep ret -%endmacro - -INIT_XMM -%define mova movaps -DECL_PASS pass_sse, PASS_BIG 1 -DECL_PASS pass_interleave_sse, PASS_BIG 0 - -INIT_MMX -%define mulps pfmul -%define addps pfadd -%define subps pfsub -%define unpcklps punpckldq -%define unpckhps punpckhdq -DECL_PASS pass_3dn, PASS_SMALL 1, [wq], [wq+o1q] -DECL_PASS pass_interleave_3dn, PASS_BIG 0 -%define pass_3dn2 pass_3dn -%define pass_interleave_3dn2 pass_interleave_3dn - -%ifdef PIC -%define SECTION_REL - $$ -%else -%define SECTION_REL -%endif - -%macro DECL_FFT 2-3 ; nbits, cpu, suffix -%xdefine list_of_fft fft4%2 SECTION_REL, fft8%2 SECTION_REL -%if %1==5 -%xdefine list_of_fft list_of_fft, fft16%2 SECTION_REL -%endif - -%assign n 1<<%1 -%rep 17-%1 -%assign n2 n/2 -%assign n4 n/4 -%xdefine list_of_fft list_of_fft, fft %+ n %+ %3%2 SECTION_REL - -align 16 -fft %+ n %+ %3%2: - call fft %+ n2 %+ %2 - add r0, n*4 - (n&(-2<<%1)) - call fft %+ n4 %+ %2 - add r0, n*2 - (n2&(-2<<%1)) - call fft %+ n4 %+ %2 - sub r0, n*6 + (n2&(-2<<%1)) - lea r1, [ff_cos_ %+ n GLOBAL] - mov r2d, n4/2 - jmp pass%3%2 - -%assign n n*2 -%endrep -%undef n - -align 8 -dispatch_tab%3%2: pointer list_of_fft - -section .text - -; On x86_32, this function does the register saving and restoring for all of fft. -; The others pass args in registers and don't spill anything. -cglobal fft_dispatch%3%2, 2,5,8, z, nbits - lea r2, [dispatch_tab%3%2 GLOBAL] - mov r2, [r2 + (nbitsq-2)*gprsize] -%ifdef PIC - lea r3, [$$ GLOBAL] - add r2, r3 -%endif - call r2 - RET -%endmacro ; DECL_FFT - -DECL_FFT 5, _sse -DECL_FFT 5, _sse, _interleave -DECL_FFT 4, _3dn -DECL_FFT 4, _3dn, _interleave -DECL_FFT 4, _3dn2 -DECL_FFT 4, _3dn2, _interleave - diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/fft_sse.c b/tizen/distrib/ffmpeg/libavcodec/x86/fft_sse.c deleted file mode 100644 index a4cce69..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/fft_sse.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * FFT/MDCT transform with SSE optimizations - * Copyright (c) 2008 Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "fft.h" - -DECLARE_ALIGNED(16, static const int, m1m1m1m1)[4] = - { 1 << 31, 1 << 31, 1 << 31, 1 << 31 }; - -void ff_fft_dispatch_sse(FFTComplex *z, int nbits); -void ff_fft_dispatch_interleave_sse(FFTComplex *z, int nbits); - -void ff_fft_calc_sse(FFTContext *s, FFTComplex *z) -{ - int n = 1 << s->nbits; - - ff_fft_dispatch_interleave_sse(z, s->nbits); - - if(n <= 16) { - x86_reg i = -8*n; - __asm__ volatile( - "1: \n" - "movaps (%0,%1), %%xmm0 \n" - "movaps %%xmm0, %%xmm1 \n" - "unpcklps 16(%0,%1), %%xmm0 \n" - "unpckhps 16(%0,%1), %%xmm1 \n" - "movaps %%xmm0, (%0,%1) \n" - "movaps %%xmm1, 16(%0,%1) \n" - "add $32, %0 \n" - "jl 1b \n" - :"+r"(i) - :"r"(z+n) - :"memory" - ); - } -} - -void ff_fft_permute_sse(FFTContext *s, FFTComplex *z) -{ - int n = 1 << s->nbits; - int i; - for(i=0; itmp_buf[s->revtab[i]]), - "=m"(s->tmp_buf[s->revtab[i+1]]) - :"m"(z[i]) - ); - } - memcpy(z, s->tmp_buf, n*sizeof(FFTComplex)); -} - -void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - av_unused x86_reg i, j, k, l; - long n = 1 << s->mdct_bits; - long n2 = n >> 1; - long n4 = n >> 2; - long n8 = n >> 3; - const uint16_t *revtab = s->revtab + n8; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - FFTComplex *z = (FFTComplex *)output; - - /* pre rotation */ - for(k=n8-2; k>=0; k-=2) { - __asm__ volatile( - "movaps (%2,%1,2), %%xmm0 \n" // { z[k].re, z[k].im, z[k+1].re, z[k+1].im } - "movaps -16(%2,%0,2), %%xmm1 \n" // { z[-k-2].re, z[-k-2].im, z[-k-1].re, z[-k-1].im } - "movaps %%xmm0, %%xmm2 \n" - "shufps $0x88, %%xmm1, %%xmm0 \n" // { z[k].re, z[k+1].re, z[-k-2].re, z[-k-1].re } - "shufps $0x77, %%xmm2, %%xmm1 \n" // { z[-k-1].im, z[-k-2].im, z[k+1].im, z[k].im } - "movlps (%3,%1), %%xmm4 \n" - "movlps (%4,%1), %%xmm5 \n" - "movhps -8(%3,%0), %%xmm4 \n" // { cos[k], cos[k+1], cos[-k-2], cos[-k-1] } - "movhps -8(%4,%0), %%xmm5 \n" // { sin[k], sin[k+1], sin[-k-2], sin[-k-1] } - "movaps %%xmm0, %%xmm2 \n" - "movaps %%xmm1, %%xmm3 \n" - "mulps %%xmm5, %%xmm0 \n" // re*sin - "mulps %%xmm4, %%xmm1 \n" // im*cos - "mulps %%xmm4, %%xmm2 \n" // re*cos - "mulps %%xmm5, %%xmm3 \n" // im*sin - "subps %%xmm0, %%xmm1 \n" // -> re - "addps %%xmm3, %%xmm2 \n" // -> im - "movaps %%xmm1, %%xmm0 \n" - "unpcklps %%xmm2, %%xmm1 \n" // { z[k], z[k+1] } - "unpckhps %%xmm2, %%xmm0 \n" // { z[-k-2], z[-k-1] } - ::"r"(-4*k), "r"(4*k), - "r"(input+n4), "r"(tcos+n8), "r"(tsin+n8) - ); -#if ARCH_X86_64 - // if we have enough regs, don't let gcc make the luts latency-bound - // but if not, latency is faster than spilling - __asm__("movlps %%xmm0, %0 \n" - "movhps %%xmm0, %1 \n" - "movlps %%xmm1, %2 \n" - "movhps %%xmm1, %3 \n" - :"=m"(z[revtab[-k-2]]), - "=m"(z[revtab[-k-1]]), - "=m"(z[revtab[ k ]]), - "=m"(z[revtab[ k+1]]) - ); -#else - __asm__("movlps %%xmm0, %0" :"=m"(z[revtab[-k-2]])); - __asm__("movhps %%xmm0, %0" :"=m"(z[revtab[-k-1]])); - __asm__("movlps %%xmm1, %0" :"=m"(z[revtab[ k ]])); - __asm__("movhps %%xmm1, %0" :"=m"(z[revtab[ k+1]])); -#endif - } - - ff_fft_dispatch_sse(z, s->nbits); - - /* post rotation + reinterleave + reorder */ - -#define CMUL(j,xmm0,xmm1)\ - "movaps (%2,"#j",2), %%xmm6 \n"\ - "movaps 16(%2,"#j",2), "#xmm0"\n"\ - "movaps %%xmm6, "#xmm1"\n"\ - "movaps "#xmm0",%%xmm7 \n"\ - "mulps (%3,"#j"), %%xmm6 \n"\ - "mulps (%4,"#j"), "#xmm0"\n"\ - "mulps (%4,"#j"), "#xmm1"\n"\ - "mulps (%3,"#j"), %%xmm7 \n"\ - "subps %%xmm6, "#xmm0"\n"\ - "addps %%xmm7, "#xmm1"\n" - - j = -n2; - k = n2-16; - __asm__ volatile( - "1: \n" - CMUL(%0, %%xmm0, %%xmm1) - CMUL(%1, %%xmm4, %%xmm5) - "shufps $0x1b, %%xmm1, %%xmm1 \n" - "shufps $0x1b, %%xmm5, %%xmm5 \n" - "movaps %%xmm4, %%xmm6 \n" - "unpckhps %%xmm1, %%xmm4 \n" - "unpcklps %%xmm1, %%xmm6 \n" - "movaps %%xmm0, %%xmm2 \n" - "unpcklps %%xmm5, %%xmm0 \n" - "unpckhps %%xmm5, %%xmm2 \n" - "movaps %%xmm6, (%2,%1,2) \n" - "movaps %%xmm4, 16(%2,%1,2) \n" - "movaps %%xmm0, (%2,%0,2) \n" - "movaps %%xmm2, 16(%2,%0,2) \n" - "sub $16, %1 \n" - "add $16, %0 \n" - "jl 1b \n" - :"+&r"(j), "+&r"(k) - :"r"(z+n8), "r"(tcos+n8), "r"(tsin+n8) - :"memory" - ); -} - -void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - x86_reg j, k; - long n = 1 << s->mdct_bits; - long n4 = n >> 2; - - ff_imdct_half_sse(s, output+n4, input); - - j = -n; - k = n-16; - __asm__ volatile( - "movaps %4, %%xmm7 \n" - "1: \n" - "movaps (%2,%1), %%xmm0 \n" - "movaps (%3,%0), %%xmm1 \n" - "shufps $0x1b, %%xmm0, %%xmm0 \n" - "shufps $0x1b, %%xmm1, %%xmm1 \n" - "xorps %%xmm7, %%xmm0 \n" - "movaps %%xmm1, (%3,%1) \n" - "movaps %%xmm0, (%2,%0) \n" - "sub $16, %1 \n" - "add $16, %0 \n" - "jl 1b \n" - :"+r"(j), "+r"(k) - :"r"(output+n4), "r"(output+n4*3), - "m"(*m1m1m1m1) - ); -} - diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/h264_deblock_sse2.asm b/tizen/distrib/ffmpeg/libavcodec/x86/h264_deblock_sse2.asm deleted file mode 100644 index bf45c7e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/h264_deblock_sse2.asm +++ /dev/null @@ -1,759 +0,0 @@ -;***************************************************************************** -;* MMX/SSE2-optimized H.264 deblocking code -;***************************************************************************** -;* Copyright (C) 2005-2008 x264 project -;* -;* Authors: Loren Merritt -;* -;* 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 02111, USA. -;***************************************************************************** - -%include "x86inc.asm" - -SECTION_RODATA -pb_00: times 16 db 0x00 -pb_01: times 16 db 0x01 -pb_03: times 16 db 0x03 -pb_a1: times 16 db 0xa1 - -SECTION .text - -; expands to [base],...,[base+7*stride] -%define PASS8ROWS(base, base3, stride, stride3) \ - [base], [base+stride], [base+stride*2], [base3], \ - [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4] - -; in: 8 rows of 4 bytes in %1..%8 -; out: 4 rows of 8 bytes in m0..m3 -%macro TRANSPOSE4x8_LOAD 8 - movd m0, %1 - movd m2, %2 - movd m1, %3 - movd m3, %4 - punpcklbw m0, m2 - punpcklbw m1, m3 - movq m2, m0 - punpcklwd m0, m1 - punpckhwd m2, m1 - - movd m4, %5 - movd m6, %6 - movd m5, %7 - movd m7, %8 - punpcklbw m4, m6 - punpcklbw m5, m7 - movq m6, m4 - punpcklwd m4, m5 - punpckhwd m6, m5 - - movq m1, m0 - movq m3, m2 - punpckldq m0, m4 - punpckhdq m1, m4 - punpckldq m2, m6 - punpckhdq m3, m6 -%endmacro - -; in: 4 rows of 8 bytes in m0..m3 -; out: 8 rows of 4 bytes in %1..%8 -%macro TRANSPOSE8x4_STORE 8 - movq m4, m0 - movq m5, m1 - movq m6, m2 - punpckhdq m4, m4 - punpckhdq m5, m5 - punpckhdq m6, m6 - - punpcklbw m0, m1 - punpcklbw m2, m3 - movq m1, m0 - punpcklwd m0, m2 - punpckhwd m1, m2 - movd %1, m0 - punpckhdq m0, m0 - movd %2, m0 - movd %3, m1 - punpckhdq m1, m1 - movd %4, m1 - - punpckhdq m3, m3 - punpcklbw m4, m5 - punpcklbw m6, m3 - movq m5, m4 - punpcklwd m4, m6 - punpckhwd m5, m6 - movd %5, m4 - punpckhdq m4, m4 - movd %6, m4 - movd %7, m5 - punpckhdq m5, m5 - movd %8, m5 -%endmacro - -%macro SBUTTERFLY 4 - movq %4, %2 - punpckl%1 %2, %3 - punpckh%1 %4, %3 -%endmacro - -; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8 -; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16] -%macro TRANSPOSE6x8_MEM 9 - movq m0, %1 - movq m1, %2 - movq m2, %3 - movq m3, %4 - movq m4, %5 - movq m5, %6 - movq m6, %7 - SBUTTERFLY bw, m0, m1, m7 - SBUTTERFLY bw, m2, m3, m1 - SBUTTERFLY bw, m4, m5, m3 - movq [%9+0x10], m1 - SBUTTERFLY bw, m6, %8, m5 - SBUTTERFLY wd, m0, m2, m1 - SBUTTERFLY wd, m4, m6, m2 - punpckhdq m0, m4 - movq [%9+0x00], m0 - SBUTTERFLY wd, m7, [%9+0x10], m6 - SBUTTERFLY wd, m3, m5, m4 - SBUTTERFLY dq, m7, m3, m0 - SBUTTERFLY dq, m1, m2, m5 - punpckldq m6, m4 - movq [%9+0x10], m1 - movq [%9+0x20], m5 - movq [%9+0x30], m7 - movq [%9+0x40], m0 - movq [%9+0x50], m6 -%endmacro - -; in: 8 rows of 8 in %1..%8 -; out: 8 rows of 8 in %9..%16 -%macro TRANSPOSE8x8_MEM 16 - movq m0, %1 - movq m1, %2 - movq m2, %3 - movq m3, %4 - movq m4, %5 - movq m5, %6 - movq m6, %7 - SBUTTERFLY bw, m0, m1, m7 - SBUTTERFLY bw, m2, m3, m1 - SBUTTERFLY bw, m4, m5, m3 - SBUTTERFLY bw, m6, %8, m5 - movq %9, m3 - SBUTTERFLY wd, m0, m2, m3 - SBUTTERFLY wd, m4, m6, m2 - SBUTTERFLY wd, m7, m1, m6 - movq %11, m2 - movq m2, %9 - SBUTTERFLY wd, m2, m5, m1 - SBUTTERFLY dq, m0, m4, m5 - SBUTTERFLY dq, m7, m2, m4 - movq %9, m0 - movq %10, m5 - movq %13, m7 - movq %14, m4 - SBUTTERFLY dq, m3, %11, m0 - SBUTTERFLY dq, m6, m1, m5 - movq %11, m3 - movq %12, m0 - movq %15, m6 - movq %16, m5 -%endmacro - -; out: %4 = |%1-%2|>%3 -; clobbers: %5 -%macro DIFF_GT 5 - mova %5, %2 - mova %4, %1 - psubusb %5, %1 - psubusb %4, %2 - por %4, %5 - psubusb %4, %3 -%endmacro - -; out: %4 = |%1-%2|>%3 -; clobbers: %5 -%macro DIFF_GT2 5 - mova %5, %2 - mova %4, %1 - psubusb %5, %1 - psubusb %4, %2 - psubusb %5, %3 - psubusb %4, %3 - pcmpeqb %4, %5 -%endmacro - -%macro SPLATW 1 -%ifidn m0, xmm0 - pshuflw %1, %1, 0 - punpcklqdq %1, %1 -%else - pshufw %1, %1, 0 -%endif -%endmacro - -; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1 -; out: m5=beta-1, m7=mask, %3=alpha-1 -; clobbers: m4,m6 -%macro LOAD_MASK 2-3 - movd m4, %1 - movd m5, %2 - SPLATW m4 - SPLATW m5 - packuswb m4, m4 ; 16x alpha-1 - packuswb m5, m5 ; 16x beta-1 -%if %0>2 - mova %3, m4 -%endif - DIFF_GT m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1 - DIFF_GT m0, m1, m5, m4, m6 ; |p1-p0| > beta-1 - por m7, m4 - DIFF_GT m3, m2, m5, m4, m6 ; |q1-q0| > beta-1 - por m7, m4 - pxor m6, m6 - pcmpeqb m7, m6 -%endmacro - -; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask) -; out: m1=p0' m2=q0' -; clobbers: m0,3-6 -%macro DEBLOCK_P0_Q0 0 - mova m5, m1 - pxor m5, m2 ; p0^q0 - pand m5, [pb_01 GLOBAL] ; (p0^q0)&1 - pcmpeqb m4, m4 - pxor m3, m4 - pavgb m3, m0 ; (p1 - q1 + 256)>>1 - pavgb m3, [pb_03 GLOBAL] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2 - pxor m4, m1 - pavgb m4, m2 ; (q0 - p0 + 256)>>1 - pavgb m3, m5 - paddusb m3, m4 ; d+128+33 - mova m6, [pb_a1 GLOBAL] - psubusb m6, m3 - psubusb m3, [pb_a1 GLOBAL] - pminub m6, m7 - pminub m3, m7 - psubusb m1, m6 - psubusb m2, m3 - paddusb m1, m3 - paddusb m2, m6 -%endmacro - -; in: m1=p0 m2=q0 -; %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp -; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 ) -; clobbers: q2, tmp, tc0 -%macro LUMA_Q1 6 - mova %6, m1 - pavgb %6, m2 - pavgb %2, %6 ; avg(p2,avg(p0,q0)) - pxor %6, %3 - pand %6, [pb_01 GLOBAL] ; (p2^avg(p0,q0))&1 - psubusb %2, %6 ; (p2+((p0+q0+1)>>1))>>1 - mova %6, %1 - psubusb %6, %5 - paddusb %5, %1 - pmaxub %2, %6 - pminub %2, %5 - mova %4, %2 -%endmacro - -%ifdef ARCH_X86_64 -;----------------------------------------------------------------------------- -; void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 ) -;----------------------------------------------------------------------------- -INIT_XMM -cglobal x264_deblock_v_luma_sse2, 5,5,10 - movd m8, [r4] ; tc0 - lea r4, [r1*3] - dec r2d ; alpha-1 - neg r4 - dec r3d ; beta-1 - add r4, r0 ; pix-3*stride - - mova m0, [r4+r1] ; p1 - mova m1, [r4+2*r1] ; p0 - mova m2, [r0] ; q0 - mova m3, [r0+r1] ; q1 - LOAD_MASK r2d, r3d - - punpcklbw m8, m8 - punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0] - pcmpeqb m9, m9 - pcmpeqb m9, m8 - pandn m9, m7 - pand m8, m9 - - movdqa m3, [r4] ; p2 - DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1 - pand m6, m9 - mova m7, m8 - psubb m7, m6 - pand m6, m8 - LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4 - - movdqa m4, [r0+2*r1] ; q2 - DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1 - pand m6, m9 - pand m8, m6 - psubb m7, m6 - mova m3, [r0+r1] - LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6 - - DEBLOCK_P0_Q0 - mova [r4+2*r1], m1 - mova [r0], m2 - RET - -;----------------------------------------------------------------------------- -; void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 ) -;----------------------------------------------------------------------------- -INIT_MMX -cglobal x264_deblock_h_luma_sse2, 5,7 - movsxd r10, r1d - lea r11, [r10+r10*2] - lea r6, [r0-4] - lea r5, [r0-4+r11] -%ifdef WIN64 - sub rsp, 0x98 - %define pix_tmp rsp+0x30 -%else - sub rsp, 0x68 - %define pix_tmp rsp -%endif - - ; transpose 6x16 -> tmp space - TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r10, r11), pix_tmp - lea r6, [r6+r10*8] - lea r5, [r5+r10*8] - TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r10, r11), pix_tmp+8 - - ; vertical filter - ; alpha, beta, tc0 are still in r2d, r3d, r4 - ; don't backup r6, r5, r10, r11 because x264_deblock_v_luma_sse2 doesn't use them - lea r0, [pix_tmp+0x30] - mov r1d, 0x10 -%ifdef WIN64 - mov [rsp+0x20], r4 -%endif - call x264_deblock_v_luma_sse2 - - ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter) - add r6, 2 - add r5, 2 - movq m0, [pix_tmp+0x18] - movq m1, [pix_tmp+0x28] - movq m2, [pix_tmp+0x38] - movq m3, [pix_tmp+0x48] - TRANSPOSE8x4_STORE PASS8ROWS(r6, r5, r10, r11) - - shl r10, 3 - sub r6, r10 - sub r5, r10 - shr r10, 3 - movq m0, [pix_tmp+0x10] - movq m1, [pix_tmp+0x20] - movq m2, [pix_tmp+0x30] - movq m3, [pix_tmp+0x40] - TRANSPOSE8x4_STORE PASS8ROWS(r6, r5, r10, r11) - -%ifdef WIN64 - add rsp, 0x98 -%else - add rsp, 0x68 -%endif - RET - -%else - -%macro DEBLOCK_LUMA 3 -;----------------------------------------------------------------------------- -; void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 ) -;----------------------------------------------------------------------------- -cglobal x264_deblock_%2_luma_%1, 5,5 - lea r4, [r1*3] - dec r2 ; alpha-1 - neg r4 - dec r3 ; beta-1 - add r4, r0 ; pix-3*stride - %assign pad 2*%3+12-(stack_offset&15) - SUB esp, pad - - mova m0, [r4+r1] ; p1 - mova m1, [r4+2*r1] ; p0 - mova m2, [r0] ; q0 - mova m3, [r0+r1] ; q1 - LOAD_MASK r2, r3 - - mov r3, r4mp - movd m4, [r3] ; tc0 - punpcklbw m4, m4 - punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0] - mova [esp+%3], m4 ; tc - pcmpeqb m3, m3 - pcmpgtb m4, m3 - pand m4, m7 - mova [esp], m4 ; mask - - mova m3, [r4] ; p2 - DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1 - pand m6, m4 - pand m4, [esp+%3] ; tc - mova m7, m4 - psubb m7, m6 - pand m6, m4 - LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4 - - mova m4, [r0+2*r1] ; q2 - DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1 - mova m5, [esp] ; mask - pand m6, m5 - mova m5, [esp+%3] ; tc - pand m5, m6 - psubb m7, m6 - mova m3, [r0+r1] - LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6 - - DEBLOCK_P0_Q0 - mova [r4+2*r1], m1 - mova [r0], m2 - ADD esp, pad - RET - -;----------------------------------------------------------------------------- -; void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 ) -;----------------------------------------------------------------------------- -INIT_MMX -cglobal x264_deblock_h_luma_%1, 0,5 - mov r0, r0mp - mov r3, r1m - lea r4, [r3*3] - sub r0, 4 - lea r1, [r0+r4] - %assign pad 0x78-(stack_offset&15) - SUB esp, pad -%define pix_tmp esp+12 - - ; transpose 6x16 -> tmp space - TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp - lea r0, [r0+r3*8] - lea r1, [r1+r3*8] - TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp+8 - - ; vertical filter - lea r0, [pix_tmp+0x30] - PUSH dword r4m - PUSH dword r3m - PUSH dword r2m - PUSH dword 16 - PUSH dword r0 - call x264_deblock_%2_luma_%1 -%ifidn %2, v8 - add dword [esp ], 8 ; pix_tmp+0x38 - add dword [esp+16], 2 ; tc0+2 - call x264_deblock_%2_luma_%1 -%endif - ADD esp, 20 - - ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter) - mov r0, r0mp - sub r0, 2 - lea r1, [r0+r4] - - movq m0, [pix_tmp+0x10] - movq m1, [pix_tmp+0x20] - movq m2, [pix_tmp+0x30] - movq m3, [pix_tmp+0x40] - TRANSPOSE8x4_STORE PASS8ROWS(r0, r1, r3, r4) - - lea r0, [r0+r3*8] - lea r1, [r1+r3*8] - movq m0, [pix_tmp+0x18] - movq m1, [pix_tmp+0x28] - movq m2, [pix_tmp+0x38] - movq m3, [pix_tmp+0x48] - TRANSPOSE8x4_STORE PASS8ROWS(r0, r1, r3, r4) - - ADD esp, pad - RET -%endmacro ; DEBLOCK_LUMA - -INIT_XMM -DEBLOCK_LUMA sse2, v, 16 - -%endif ; ARCH - - - -%macro LUMA_INTRA_P012 4 ; p0..p3 in memory - mova t0, p2 - mova t1, p0 - pavgb t0, p1 - pavgb t1, q0 - pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2 - mova t5, t1 - mova t2, p2 - mova t3, p0 - paddb t2, p1 - paddb t3, q0 - paddb t2, t3 - mova t3, t2 - mova t4, t2 - psrlw t2, 1 - pavgb t2, mpb_00 - pxor t2, t0 - pand t2, mpb_01 - psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4; - - mova t1, p2 - mova t2, p2 - pavgb t1, q1 - psubb t2, q1 - paddb t3, t3 - psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1 - pand t2, mpb_01 - psubb t1, t2 - pavgb t1, p1 - pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2 - psrlw t3, 2 - pavgb t3, mpb_00 - pxor t3, t1 - pand t3, mpb_01 - psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8 - - mova t3, p0 - mova t2, p0 - pxor t3, q1 - pavgb t2, q1 - pand t3, mpb_01 - psubb t2, t3 - pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4 - - pxor t1, t2 - pxor t2, p0 - pand t1, mask1p - pand t2, mask0 - pxor t1, t2 - pxor t1, p0 - mova %1, t1 ; store p0 - - mova t1, %4 ; p3 - mova t2, t1 - pavgb t1, p2 - paddb t2, p2 - pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4 - paddb t2, t2 - paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0 - psrlw t2, 2 - pavgb t2, mpb_00 - pxor t2, t1 - pand t2, mpb_01 - psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8 - - pxor t0, p1 - pxor t1, p2 - pand t0, mask1p - pand t1, mask1p - pxor t0, p1 - pxor t1, p2 - mova %2, t0 ; store p1 - mova %3, t1 ; store p2 -%endmacro - -%macro LUMA_INTRA_SWAP_PQ 0 - %define q1 m0 - %define q0 m1 - %define p0 m2 - %define p1 m3 - %define p2 q2 - %define mask1p mask1q -%endmacro - -%macro DEBLOCK_LUMA_INTRA 2 - %define p1 m0 - %define p0 m1 - %define q0 m2 - %define q1 m3 - %define t0 m4 - %define t1 m5 - %define t2 m6 - %define t3 m7 -%ifdef ARCH_X86_64 - %define p2 m8 - %define q2 m9 - %define t4 m10 - %define t5 m11 - %define mask0 m12 - %define mask1p m13 - %define mask1q [rsp-24] - %define mpb_00 m14 - %define mpb_01 m15 -%else - %define spill(x) [esp+16*x+((stack_offset+4)&15)] - %define p2 [r4+r1] - %define q2 [r0+2*r1] - %define t4 spill(0) - %define t5 spill(1) - %define mask0 spill(2) - %define mask1p spill(3) - %define mask1q spill(4) - %define mpb_00 [pb_00 GLOBAL] - %define mpb_01 [pb_01 GLOBAL] -%endif - -;----------------------------------------------------------------------------- -; void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta ) -;----------------------------------------------------------------------------- -cglobal x264_deblock_%2_luma_intra_%1, 4,6,16 -%ifndef ARCH_X86_64 - sub esp, 0x60 -%endif - lea r4, [r1*4] - lea r5, [r1*3] ; 3*stride - dec r2d ; alpha-1 - jl .end - neg r4 - dec r3d ; beta-1 - jl .end - add r4, r0 ; pix-4*stride - mova p1, [r4+2*r1] - mova p0, [r4+r5] - mova q0, [r0] - mova q1, [r0+r1] -%ifdef ARCH_X86_64 - pxor mpb_00, mpb_00 - mova mpb_01, [pb_01 GLOBAL] - LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0 - SWAP 7, 12 ; m12=mask0 - pavgb t5, mpb_00 - pavgb t5, mpb_01 ; alpha/4+1 - movdqa p2, [r4+r1] - movdqa q2, [r0+2*r1] - DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1 - DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1 - DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1 - pand t0, mask0 - pand t4, t0 - pand t2, t0 - mova mask1q, t4 - mova mask1p, t2 -%else - LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0 - mova m4, t5 - mova mask0, m7 - pavgb m4, [pb_00 GLOBAL] - pavgb m4, [pb_01 GLOBAL] ; alpha/4+1 - DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1 - pand m6, mask0 - DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1 - pand m4, m6 - mova mask1p, m4 - DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1 - pand m4, m6 - mova mask1q, m4 -%endif - LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4] - LUMA_INTRA_SWAP_PQ - LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5] -.end: -%ifndef ARCH_X86_64 - add esp, 0x60 -%endif - RET - -INIT_MMX -%ifdef ARCH_X86_64 -;----------------------------------------------------------------------------- -; void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta ) -;----------------------------------------------------------------------------- -cglobal x264_deblock_h_luma_intra_%1, 4,7 - movsxd r10, r1d - lea r11, [r10*3] - lea r6, [r0-4] - lea r5, [r0-4+r11] - sub rsp, 0x88 - %define pix_tmp rsp - - ; transpose 8x16 -> tmp space - TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30) - lea r6, [r6+r10*8] - lea r5, [r5+r10*8] - TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30) - - lea r0, [pix_tmp+0x40] - mov r1, 0x10 - call x264_deblock_v_luma_intra_%1 - - ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8) - lea r5, [r6+r11] - TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11) - shl r10, 3 - sub r6, r10 - sub r5, r10 - shr r10, 3 - TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11) - add rsp, 0x88 - RET -%else -cglobal x264_deblock_h_luma_intra_%1, 2,4 - lea r3, [r1*3] - sub r0, 4 - lea r2, [r0+r3] -%assign pad 0x8c-(stack_offset&15) - SUB rsp, pad - %define pix_tmp rsp - - ; transpose 8x16 -> tmp space - TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30) - lea r0, [r0+r1*8] - lea r2, [r2+r1*8] - TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30) - - lea r0, [pix_tmp+0x40] - PUSH dword r3m - PUSH dword r2m - PUSH dword 16 - PUSH r0 - call x264_deblock_%2_luma_intra_%1 -%ifidn %2, v8 - add dword [rsp], 8 ; pix_tmp+8 - call x264_deblock_%2_luma_intra_%1 -%endif - ADD esp, 16 - - mov r1, r1m - mov r0, r0mp - lea r3, [r1*3] - sub r0, 4 - lea r2, [r0+r3] - ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8) - TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3) - lea r0, [r0+r1*8] - lea r2, [r2+r1*8] - TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3) - ADD rsp, pad - RET -%endif ; ARCH_X86_64 -%endmacro ; DEBLOCK_LUMA_INTRA - -INIT_XMM -DEBLOCK_LUMA_INTRA sse2, v -%ifndef ARCH_X86_64 -INIT_MMX -DEBLOCK_LUMA_INTRA mmxext, v8 -%endif diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/h264_i386.h b/tizen/distrib/ffmpeg/libavcodec/x86/h264_i386.h deleted file mode 100644 index 26c163b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/h264_i386.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 / AVC / MPEG4 part10 codec. - * non-MMX i386-specific optimizations for H.264 - * @author Michael Niedermayer - */ - -#ifndef AVCODEC_X86_H264_I386_H -#define AVCODEC_X86_H264_I386_H - -#include "libavcodec/cabac.h" - -//FIXME use some macros to avoid duplicating get_cabac (cannot be done yet -//as that would make optimization work hard) -#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) -static int decode_significance_x86(CABACContext *c, int max_coeff, - uint8_t *significant_coeff_ctx_base, - int *index){ - void *end= significant_coeff_ctx_base + max_coeff - 1; - int minusstart= -(int)significant_coeff_ctx_base; - int minusindex= 4-(int)index; - int coeff_count; - __asm__ volatile( - "movl "RANGE "(%3), %%esi \n\t" - "movl "LOW "(%3), %%ebx \n\t" - - "2: \n\t" - - BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") - - "test $1, %%edx \n\t" - " jz 3f \n\t" - - BRANCHLESS_GET_CABAC("%%edx", "%3", "61(%1)", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") - - "mov %2, %%"REG_a" \n\t" - "movl %4, %%ecx \n\t" - "add %1, %%"REG_c" \n\t" - "movl %%ecx, (%%"REG_a") \n\t" - - "test $1, %%edx \n\t" - " jnz 4f \n\t" - - "add $4, %%"REG_a" \n\t" - "mov %%"REG_a", %2 \n\t" - - "3: \n\t" - "add $1, %1 \n\t" - "cmp %5, %1 \n\t" - " jb 2b \n\t" - "mov %2, %%"REG_a" \n\t" - "movl %4, %%ecx \n\t" - "add %1, %%"REG_c" \n\t" - "movl %%ecx, (%%"REG_a") \n\t" - "4: \n\t" - "add %6, %%eax \n\t" - "shr $2, %%eax \n\t" - - "movl %%esi, "RANGE "(%3) \n\t" - "movl %%ebx, "LOW "(%3) \n\t" - :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index) - :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex) - : "%"REG_c, "%ebx", "%edx", "%esi", "memory" - ); - return coeff_count; -} - -static int decode_significance_8x8_x86(CABACContext *c, - uint8_t *significant_coeff_ctx_base, - int *index, const uint8_t *sig_off){ - int minusindex= 4-(int)index; - int coeff_count; - x86_reg last=0; - __asm__ volatile( - "movl "RANGE "(%3), %%esi \n\t" - "movl "LOW "(%3), %%ebx \n\t" - - "mov %1, %%"REG_D" \n\t" - "2: \n\t" - - "mov %6, %%"REG_a" \n\t" - "movzbl (%%"REG_a", %%"REG_D"), %%edi \n\t" - "add %5, %%"REG_D" \n\t" - - BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") - - "mov %1, %%edi \n\t" - "test $1, %%edx \n\t" - " jz 3f \n\t" - - "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" - "add %5, %%"REG_D" \n\t" - - BRANCHLESS_GET_CABAC("%%edx", "%3", "15(%%"REG_D")", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") - - "mov %2, %%"REG_a" \n\t" - "mov %1, %%edi \n\t" - "movl %%edi, (%%"REG_a") \n\t" - - "test $1, %%edx \n\t" - " jnz 4f \n\t" - - "add $4, %%"REG_a" \n\t" - "mov %%"REG_a", %2 \n\t" - - "3: \n\t" - "addl $1, %%edi \n\t" - "mov %%edi, %1 \n\t" - "cmpl $63, %%edi \n\t" - " jb 2b \n\t" - "mov %2, %%"REG_a" \n\t" - "movl %%edi, (%%"REG_a") \n\t" - "4: \n\t" - "addl %4, %%eax \n\t" - "shr $2, %%eax \n\t" - - "movl %%esi, "RANGE "(%3) \n\t" - "movl %%ebx, "LOW "(%3) \n\t" - :"=&a"(coeff_count),"+m"(last), "+m"(index) - :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off) - : "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory" - ); - return coeff_count; -} -#endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE */ - /* !defined(BROKEN_RELOCATIONS) */ - -#endif /* AVCODEC_X86_H264_I386_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/h264_idct_sse2.asm b/tizen/distrib/ffmpeg/libavcodec/x86/h264_idct_sse2.asm deleted file mode 100644 index f8ee2b6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/h264_idct_sse2.asm +++ /dev/null @@ -1,54 +0,0 @@ -;***************************************************************************** -;* SSE2-optimized H.264 iDCT -;***************************************************************************** -;* Copyright (C) 2003-2008 x264 project -;* -;* Authors: Laurent Aimar -;* Loren Merritt -;* Holger Lubitz -;* Min Chen -;* -;* 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 02111, USA. -;***************************************************************************** - -%include "x86inc.asm" -%include "x86util.asm" - -SECTION_RODATA -pw_32: times 8 dw 32 - -SECTION .text - -INIT_XMM -cglobal x264_add8x4_idct_sse2, 3,3,8 - movq m0, [r1+ 0] - movq m1, [r1+ 8] - movq m2, [r1+16] - movq m3, [r1+24] - movhps m0, [r1+32] - movhps m1, [r1+40] - movhps m2, [r1+48] - movhps m3, [r1+56] - IDCT4_1D 0,1,2,3,4,5 - TRANSPOSE2x4x4W 0,1,2,3,4 - paddw m0, [pw_32 GLOBAL] - IDCT4_1D 0,1,2,3,4,5 - pxor m7, m7 - STORE_DIFF m0, m4, m7, [r0] - STORE_DIFF m1, m4, m7, [r0+r2] - lea r0, [r0+r2*2] - STORE_DIFF m2, m4, m7, [r0] - STORE_DIFF m3, m4, m7, [r0+r2] - RET diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/h264dsp_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/h264dsp_mmx.c deleted file mode 100644 index fd16a02..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/h264dsp_mmx.c +++ /dev/null @@ -1,2324 +0,0 @@ -/* - * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "dsputil_mmx.h" - -DECLARE_ALIGNED(8, static const uint64_t, ff_pb_3_1 ) = 0x0103010301030103ULL; -DECLARE_ALIGNED(8, static const uint64_t, ff_pb_7_3 ) = 0x0307030703070307ULL; - -/***********************************/ -/* IDCT */ - -#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 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" ((x86_reg)stride) - ); -} - -static inline void h264_idct8_1d(int16_t *block) -{ - __asm__ volatile( - "movq 112(%0), %%mm7 \n\t" - "movq 80(%0), %%mm0 \n\t" - "movq 48(%0), %%mm3 \n\t" - "movq 16(%0), %%mm5 \n\t" - - "movq %%mm0, %%mm4 \n\t" - "movq %%mm5, %%mm1 \n\t" - "psraw $1, %%mm4 \n\t" - "psraw $1, %%mm1 \n\t" - "paddw %%mm0, %%mm4 \n\t" - "paddw %%mm5, %%mm1 \n\t" - "paddw %%mm7, %%mm4 \n\t" - "paddw %%mm0, %%mm1 \n\t" - "psubw %%mm5, %%mm4 \n\t" - "paddw %%mm3, %%mm1 \n\t" - - "psubw %%mm3, %%mm5 \n\t" - "psubw %%mm3, %%mm0 \n\t" - "paddw %%mm7, %%mm5 \n\t" - "psubw %%mm7, %%mm0 \n\t" - "psraw $1, %%mm3 \n\t" - "psraw $1, %%mm7 \n\t" - "psubw %%mm3, %%mm5 \n\t" - "psubw %%mm7, %%mm0 \n\t" - - "movq %%mm4, %%mm3 \n\t" - "movq %%mm1, %%mm7 \n\t" - "psraw $2, %%mm1 \n\t" - "psraw $2, %%mm3 \n\t" - "paddw %%mm5, %%mm3 \n\t" - "psraw $2, %%mm5 \n\t" - "paddw %%mm0, %%mm1 \n\t" - "psraw $2, %%mm0 \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; - DECLARE_ALIGNED(8, int16_t, b2)[64]; - - block[0] += 32; - - for(i=0; i<2; i++){ - DECLARE_ALIGNED(8, 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); -} - -#define STORE_DIFF_8P( p, d, t, z )\ - "movq "#d", "#t" \n"\ - "psraw $6, "#p" \n"\ - "punpcklbw "#z", "#t" \n"\ - "paddsw "#t", "#p" \n"\ - "packuswb "#p", "#p" \n"\ - "movq "#p", "#d" \n" - -#define H264_IDCT8_1D_SSE2(a,b,c,d,e,f,g,h)\ - "movdqa "#c", "#a" \n"\ - "movdqa "#g", "#e" \n"\ - "psraw $1, "#c" \n"\ - "psraw $1, "#g" \n"\ - "psubw "#e", "#c" \n"\ - "paddw "#a", "#g" \n"\ - "movdqa "#b", "#e" \n"\ - "psraw $1, "#e" \n"\ - "paddw "#b", "#e" \n"\ - "paddw "#d", "#e" \n"\ - "paddw "#f", "#e" \n"\ - "movdqa "#f", "#a" \n"\ - "psraw $1, "#a" \n"\ - "paddw "#f", "#a" \n"\ - "paddw "#h", "#a" \n"\ - "psubw "#b", "#a" \n"\ - "psubw "#d", "#b" \n"\ - "psubw "#d", "#f" \n"\ - "paddw "#h", "#b" \n"\ - "psubw "#h", "#f" \n"\ - "psraw $1, "#d" \n"\ - "psraw $1, "#h" \n"\ - "psubw "#d", "#b" \n"\ - "psubw "#h", "#f" \n"\ - "movdqa "#e", "#d" \n"\ - "movdqa "#a", "#h" \n"\ - "psraw $2, "#d" \n"\ - "psraw $2, "#h" \n"\ - "paddw "#f", "#d" \n"\ - "paddw "#b", "#h" \n"\ - "psraw $2, "#f" \n"\ - "psraw $2, "#b" \n"\ - "psubw "#f", "#e" \n"\ - "psubw "#a", "#b" \n"\ - "movdqa 0x00(%1), "#a" \n"\ - "movdqa 0x40(%1), "#f" \n"\ - SUMSUB_BA(f, a)\ - SUMSUB_BA(g, f)\ - SUMSUB_BA(c, a)\ - SUMSUB_BA(e, g)\ - SUMSUB_BA(b, c)\ - SUMSUB_BA(h, a)\ - SUMSUB_BA(d, f) - -static void ff_h264_idct8_add_sse2(uint8_t *dst, int16_t *block, int stride) -{ - __asm__ volatile( - "movdqa 0x10(%1), %%xmm1 \n" - "movdqa 0x20(%1), %%xmm2 \n" - "movdqa 0x30(%1), %%xmm3 \n" - "movdqa 0x50(%1), %%xmm5 \n" - "movdqa 0x60(%1), %%xmm6 \n" - "movdqa 0x70(%1), %%xmm7 \n" - H264_IDCT8_1D_SSE2(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm6, %%xmm7) - TRANSPOSE8(%%xmm4, %%xmm1, %%xmm7, %%xmm3, %%xmm5, %%xmm0, %%xmm2, %%xmm6, (%1)) - "paddw %4, %%xmm4 \n" - "movdqa %%xmm4, 0x00(%1) \n" - "movdqa %%xmm2, 0x40(%1) \n" - H264_IDCT8_1D_SSE2(%%xmm4, %%xmm0, %%xmm6, %%xmm3, %%xmm2, %%xmm5, %%xmm7, %%xmm1) - "movdqa %%xmm6, 0x60(%1) \n" - "movdqa %%xmm7, 0x70(%1) \n" - "pxor %%xmm7, %%xmm7 \n" - STORE_DIFF_8P(%%xmm2, (%0), %%xmm6, %%xmm7) - STORE_DIFF_8P(%%xmm0, (%0,%2), %%xmm6, %%xmm7) - STORE_DIFF_8P(%%xmm1, (%0,%2,2), %%xmm6, %%xmm7) - STORE_DIFF_8P(%%xmm3, (%0,%3), %%xmm6, %%xmm7) - "lea (%0,%2,4), %0 \n" - STORE_DIFF_8P(%%xmm5, (%0), %%xmm6, %%xmm7) - STORE_DIFF_8P(%%xmm4, (%0,%2), %%xmm6, %%xmm7) - "movdqa 0x60(%1), %%xmm0 \n" - "movdqa 0x70(%1), %%xmm1 \n" - STORE_DIFF_8P(%%xmm0, (%0,%2,2), %%xmm6, %%xmm7) - STORE_DIFF_8P(%%xmm1, (%0,%3), %%xmm6, %%xmm7) - :"+r"(dst) - :"r"(block), "r"((x86_reg)stride), "r"((x86_reg)3L*stride), "m"(ff_pw_32) - ); -} - -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)) - ); - } -} - -//FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split -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 void ff_h264_idct_add16_mmx(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - if(nnzc[ scan8[i] ]) - ff_h264_idct_add_mmx(dst + block_offset[i], block + i*16, stride); - } -} - -static void ff_h264_idct8_add4_mmx(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i+=4){ - if(nnzc[ scan8[i] ]) - ff_h264_idct8_add_mmx(dst + block_offset[i], block + i*16, stride); - } -} - - -static void ff_h264_idct_add16_mmx2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) ff_h264_idct_dc_add_mmx2(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct_add_mmx (dst + block_offset[i], block + i*16, stride); - } - } -} - -static void ff_h264_idct_add16intra_mmx(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - if(nnzc[ scan8[i] ] || block[i*16]) - ff_h264_idct_add_mmx(dst + block_offset[i], block + i*16, stride); - } -} - -static void ff_h264_idct_add16intra_mmx2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i++){ - if(nnzc[ scan8[i] ]) ff_h264_idct_add_mmx (dst + block_offset[i], block + i*16, stride); - else if(block[i*16]) ff_h264_idct_dc_add_mmx2(dst + block_offset[i], block + i*16, stride); - } -} - -static void ff_h264_idct8_add4_mmx2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i+=4){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) ff_h264_idct8_dc_add_mmx2(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct8_add_mmx (dst + block_offset[i], block + i*16, stride); - } - } -} - -static void ff_h264_idct8_add4_sse2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i+=4){ - int nnz = nnzc[ scan8[i] ]; - if(nnz){ - if(nnz==1 && block[i*16]) ff_h264_idct8_dc_add_mmx2(dst + block_offset[i], block + i*16, stride); - else ff_h264_idct8_add_sse2 (dst + block_offset[i], block + i*16, stride); - } - } -} - -static void ff_h264_idct_add8_mmx(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=16; i<16+8; i++){ - if(nnzc[ scan8[i] ] || block[i*16]) - ff_h264_idct_add_mmx (dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - } -} - -static void ff_h264_idct_add8_mmx2(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=16; i<16+8; i++){ - if(nnzc[ scan8[i] ]) - ff_h264_idct_add_mmx (dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - else if(block[i*16]) - ff_h264_idct_dc_add_mmx2(dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - } -} - -#if CONFIG_GPL && HAVE_YASM -static void ff_h264_idct_dc_add8_mmx2(uint8_t *dst, int16_t *block, int stride) -{ - __asm__ volatile( - "movd %0, %%mm0 \n\t" // 0 0 X D - "punpcklwd %1, %%mm0 \n\t" // x X d D - "paddsw %2, %%mm0 \n\t" - "psraw $6, %%mm0 \n\t" - "punpcklwd %%mm0, %%mm0 \n\t" // d d D D - "pxor %%mm1, %%mm1 \n\t" // 0 0 0 0 - "psubw %%mm0, %%mm1 \n\t" // -d-d-D-D - "packuswb %%mm1, %%mm0 \n\t" // -d-d-D-D d d D D - "pshufw $0xFA, %%mm0, %%mm1 \n\t" // -d-d-d-d-D-D-D-D - "punpcklwd %%mm0, %%mm0 \n\t" // d d d d D D D D - ::"m"(block[ 0]), - "m"(block[16]), - "m"(ff_pw_32) - ); - __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)) - ); -} - -extern void ff_x264_add8x4_idct_sse2(uint8_t *dst, int16_t *block, int stride); - -static void ff_h264_idct_add16_sse2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i+=2) - if(nnzc[ scan8[i+0] ]|nnzc[ scan8[i+1] ]) - ff_x264_add8x4_idct_sse2 (dst + block_offset[i], block + i*16, stride); -} - -static void ff_h264_idct_add16intra_sse2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=0; i<16; i+=2){ - if(nnzc[ scan8[i+0] ]|nnzc[ scan8[i+1] ]) - ff_x264_add8x4_idct_sse2 (dst + block_offset[i], block + i*16, stride); - else if(block[i*16]|block[i*16+16]) - ff_h264_idct_dc_add8_mmx2(dst + block_offset[i], block + i*16, stride); - } -} - -static void ff_h264_idct_add8_sse2(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ - int i; - for(i=16; i<16+8; i+=2){ - if(nnzc[ scan8[i+0] ]|nnzc[ scan8[i+1] ]) - ff_x264_add8x4_idct_sse2 (dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - else if(block[i*16]|block[i*16+16]) - ff_h264_idct_dc_add8_mmx2(dest[(i&4)>>2] + block_offset[i], block + i*16, stride); - } -} -#endif - -/***********************************/ -/* 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" - -// out: o = |x-y|>a -// clobbers: t -#define DIFF_GT2_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"\ - "psubusb "#a", "#t" \n\t"\ - "psubusb "#a", "#o" \n\t"\ - "pcmpeqb "#t", "#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)\ - "movq %%mm1 , %%mm5 \n\t"\ - "pxor %%mm2 , %%mm5 \n\t" /* p0^q0*/\ - "pand "#pb_01" , %%mm5 \n\t" /* (p0^q0)&1*/\ - "pcmpeqb %%mm4 , %%mm4 \n\t"\ - "pxor %%mm4 , %%mm3 \n\t"\ - "pavgb %%mm0 , %%mm3 \n\t" /* (p1 - q1 + 256)>>1*/\ - "pavgb "MANGLE(ff_pb_3)" , %%mm3 \n\t" /*(((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2*/\ - "pxor %%mm1 , %%mm4 \n\t"\ - "pavgb %%mm2 , %%mm4 \n\t" /* (q0 - p0 + 256)>>1*/\ - "pavgb %%mm5 , %%mm3 \n\t"\ - "paddusb %%mm4 , %%mm3 \n\t" /* d+128+33*/\ - "movq "MANGLE(ff_pb_A1)" , %%mm6 \n\t"\ - "psubusb %%mm3 , %%mm6 \n\t"\ - "psubusb "MANGLE(ff_pb_A1)" , %%mm3 \n\t"\ - "pminub %%mm7 , %%mm6 \n\t"\ - "pminub %%mm7 , %%mm3 \n\t"\ - "psubusb %%mm6 , %%mm1 \n\t"\ - "psubusb %%mm3 , %%mm2 \n\t"\ - "paddusb %%mm3 , %%mm1 \n\t"\ - "paddusb %%mm6 , %%mm2 \n\t" - -// in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 mm7=(tc&mask) %8=ff_bone -// out: (q1addr) = av_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 %9, "#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) -{ - DECLARE_ALIGNED(8, uint64_t, tmp0)[2]; - - __asm__ volatile( - "movq (%2,%4), %%mm0 \n\t" //p1 - "movq (%2,%4,2), %%mm1 \n\t" //p0 - "movq (%3), %%mm2 \n\t" //q0 - "movq (%3,%4), %%mm3 \n\t" //q1 - H264_DEBLOCK_MASK(%7, %8) - - "movd %6, %%mm4 \n\t" - "punpcklbw %%mm4, %%mm4 \n\t" - "punpcklwd %%mm4, %%mm4 \n\t" - "pcmpeqb %%mm3, %%mm3 \n\t" - "movq %%mm4, %%mm6 \n\t" - "pcmpgtb %%mm3, %%mm4 \n\t" - "movq %%mm6, %1 \n\t" - "pand %%mm4, %%mm7 \n\t" - "movq %%mm7, %0 \n\t" - - /* filter p1 */ - "movq (%2), %%mm3 \n\t" //p2 - DIFF_GT2_MMX(%%mm1, %%mm3, %%mm5, %%mm6, %%mm4) // |p2-p0|>beta-1 - "pand %%mm7, %%mm6 \n\t" // mask & |p2-p0|beta-1 - "pand %0, %%mm6 \n\t" - "movq %1, %%mm5 \n\t" // can be merged with the and below but is slower then - "pand %%mm6, %%mm5 \n\t" - "psubb %%mm6, %%mm7 \n\t" - "movq (%3,%4), %%mm3 \n\t" - H264_DEBLOCK_Q1(%%mm3, %%mm4, "(%3,%4,2)", "(%3,%4)", %%mm5, %%mm6) - - /* filter p0, q0 */ - H264_DEBLOCK_P0_Q0(%9, unused) - "movq %%mm1, (%2,%4,2) \n\t" - "movq %%mm2, (%3) \n\t" - - : "=m"(tmp0[0]), "=m"(tmp0[1]) - : "r"(pix-3*stride), "r"(pix), "r"((x86_reg)stride), - "m"(*tmp0/*unused*/), "m"(*(uint32_t*)tc0), "m"(alpha1), "m"(beta1), - "m"(ff_bone) - ); -} - -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 - DECLARE_ALIGNED(8, 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"((x86_reg)stride), - "r"(*(uint32_t*)tc0), - "m"(alpha1), "m"(beta1), "m"(ff_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 - DECLARE_ALIGNED(8, 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"((x86_reg)stride), - "m"(alpha1), "m"(beta1), "m"(ff_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 - DECLARE_ALIGNED(8, 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); -} - -static void h264_loop_filter_strength_mmx2( int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], - int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field ) { - int dir; - __asm__ volatile( - "movq %0, %%mm7 \n" - "movq %1, %%mm6 \n" - ::"m"(ff_pb_1), "m"(ff_pb_3) - ); - if(field) - __asm__ volatile( - "movq %0, %%mm6 \n" - ::"m"(ff_pb_3_1) - ); - __asm__ volatile( - "movq %%mm6, %%mm5 \n" - "paddb %%mm5, %%mm5 \n" - :); - - // could do a special case for dir==0 && edges==1, but it only reduces the - // average filter time by 1.2% - for( dir=1; dir>=0; dir-- ) { - const x86_reg d_idx = dir ? -8 : -1; - const int mask_mv = dir ? mask_mv1 : mask_mv0; - DECLARE_ALIGNED(8, const uint64_t, mask_dir) = dir ? 0 : 0xffffffffffffffffULL; - int b_idx, edge; - for( b_idx=12, edge=0; edge= limit - "psubusb %%mm5, %%mm3 \n" - "packsswb %%mm3, %%mm1 \n" - "add $40, %0 \n" - "cmp $40, %0 \n" - "jl 1b \n" - "sub $80, %0 \n" - "pshufw $0x4E, %%mm1, %%mm1 \n" - "por %%mm1, %%mm0 \n" - "pshufw $0x4E, %%mm0, %%mm1 \n" - "pminub %%mm1, %%mm0 \n" - ::"r"(d_idx), - "r"(ref[0]+b_idx), - "r"(mv[0]+b_idx) - ); - } else { - __asm__ volatile( - "movd (%1), %%mm0 \n" - "psubb (%1,%0), %%mm0 \n" // ref[b] != ref[bn] - "movq (%2), %%mm1 \n" - "movq 8(%2), %%mm2 \n" - "psubw (%2,%0,4), %%mm1 \n" - "psubw 8(%2,%0,4), %%mm2 \n" - "packsswb %%mm2, %%mm1 \n" - "paddb %%mm6, %%mm1 \n" - "psubusb %%mm5, %%mm1 \n" // abs(mv[b] - mv[bn]) >= limit - "packsswb %%mm1, %%mm1 \n" - "por %%mm1, %%mm0 \n" - ::"r"(d_idx), - "r"(ref[0]+b_idx), - "r"(mv[0]+b_idx) - ); - } - } - __asm__ volatile( - "movd %0, %%mm1 \n" - "por %1, %%mm1 \n" // nnz[b] || nnz[bn] - ::"m"(nnz[b_idx]), - "m"(nnz[b_idx+d_idx]) - ); - __asm__ volatile( - "pminub %%mm7, %%mm1 \n" - "pminub %%mm7, %%mm0 \n" - "psllw $1, %%mm1 \n" - "pxor %%mm2, %%mm2 \n" - "pmaxub %%mm0, %%mm1 \n" - "punpcklbw %%mm2, %%mm1 \n" - "movq %%mm1, %0 \n" - :"=m"(*bS[dir][edge]) - ::"memory" - ); - } - edges = 4; - step = 1; - } - __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" - TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4) - "movq %%mm0, (%0) \n\t" - "movq %%mm3, 8(%0) \n\t" - "movq %%mm4, 16(%0) \n\t" - "movq %%mm2, 24(%0) \n\t" - ::"r"(bS[0]) - :"memory" - ); -} - -/***********************************/ -/* motion compensation */ - -#define QPEL_H264V_MM(A,B,C,D,E,F,OP,T,Z,d,q)\ - "mov"#q" "#C", "#T" \n\t"\ - "mov"#d" (%0), "#F" \n\t"\ - "paddw "#D", "#T" \n\t"\ - "psllw $2, "#T" \n\t"\ - "psubw "#B", "#T" \n\t"\ - "psubw "#E", "#T" \n\t"\ - "punpcklbw "#Z", "#F" \n\t"\ - "pmullw %4, "#T" \n\t"\ - "paddw %5, "#A" \n\t"\ - "add %2, %0 \n\t"\ - "paddw "#F", "#A" \n\t"\ - "paddw "#A", "#T" \n\t"\ - "psraw $5, "#T" \n\t"\ - "packuswb "#T", "#T" \n\t"\ - OP(T, (%1), A, d)\ - "add %3, %1 \n\t" - -#define QPEL_H264HV_MM(A,B,C,D,E,F,OF,T,Z,d,q)\ - "mov"#q" "#C", "#T" \n\t"\ - "mov"#d" (%0), "#F" \n\t"\ - "paddw "#D", "#T" \n\t"\ - "psllw $2, "#T" \n\t"\ - "paddw %4, "#A" \n\t"\ - "psubw "#B", "#T" \n\t"\ - "psubw "#E", "#T" \n\t"\ - "punpcklbw "#Z", "#F" \n\t"\ - "pmullw %3, "#T" \n\t"\ - "paddw "#F", "#A" \n\t"\ - "add %2, %0 \n\t"\ - "paddw "#A", "#T" \n\t"\ - "mov"#q" "#T", "#OF"(%1) \n\t" - -#define QPEL_H264V(A,B,C,D,E,F,OP) QPEL_H264V_MM(A,B,C,D,E,F,OP,%%mm6,%%mm7,d,q) -#define QPEL_H264HV(A,B,C,D,E,F,OF) QPEL_H264HV_MM(A,B,C,D,E,F,OF,%%mm6,%%mm7,d,q) -#define QPEL_H264V_XMM(A,B,C,D,E,F,OP) QPEL_H264V_MM(A,B,C,D,E,F,OP,%%xmm6,%%xmm7,q,dqa) -#define QPEL_H264HV_XMM(A,B,C,D,E,F,OF) QPEL_H264HV_MM(A,B,C,D,E,F,OF,%%xmm6,%%xmm7,q,dqa) - - -#define QPEL_H264(OPNAME, OP, MMX)\ -static av_noinline 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 "MANGLE(ff_pw_5) ", %%mm4\n\t"\ - "movq "MANGLE(ff_pw_16)", %%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), "+g"(h)\ - : "d"((x86_reg)srcStride), "S"((x86_reg)dstStride)\ - : "memory"\ - );\ -}\ -static av_noinline 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"((x86_reg)src2Stride), "S"((x86_reg)dstStride)\ - : "memory"\ - );\ - }while(--h);\ -}\ -static av_noinline 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"((x86_reg)srcStride), "D"((x86_reg)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ - : "memory"\ - );\ -}\ -static av_noinline 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"((x86_reg)srcStride), "m"(ff_pw_5), "m"(ff_pw_16)\ - : "memory"\ - );\ - tmp += 4;\ - src += 4 - 9*srcStride;\ - }\ - tmp -= 3*4;\ - __asm__ volatile(\ - "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 %%mm2, %%mm0 \n\t"/*(a-5*b+20*c)/16 */\ - "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), "+g"(h)\ - : "S"((x86_reg)dstStride)\ - : "memory"\ - );\ -}\ -\ -static av_noinline 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 "MANGLE(ff_pw_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 "MANGLE(ff_pw_16)", %%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), "+g"(h)\ - : "d"((x86_reg)srcStride), "S"((x86_reg)dstStride)\ - : "memory"\ - );\ -}\ -\ -static av_noinline 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"((x86_reg)src2Stride), "S"((x86_reg)dstStride),\ - "m"(ff_pw_16)\ - : "memory"\ - );\ - }while(--h);\ -}\ -\ -static av_noinline 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"((x86_reg)srcStride), "D"((x86_reg)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"((x86_reg)srcStride), "D"((x86_reg)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ - : "memory"\ - );\ - }\ - src += 4-(h+5)*srcStride;\ - dst += 4-h*dstStride;\ - }\ -}\ -static av_always_inline void OPNAME ## h264_qpel8or16_hv1_lowpass_ ## MMX(int16_t *tmp, uint8_t *src, int tmpStride, int srcStride, int 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"((x86_reg)srcStride), "m"(ff_pw_5), "m"(ff_pw_16)\ - : "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"((x86_reg)srcStride), "m"(ff_pw_5), "m"(ff_pw_16)\ - : "memory"\ - );\ - }\ - tmp += 4;\ - src += 4 - (size+5)*srcStride;\ - }\ -}\ -static av_always_inline void OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size){\ - int w = size>>4;\ - do{\ - int h = size;\ - __asm__ volatile(\ - "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 %%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), "+g"(h)\ - : "S"((x86_reg)dstStride)\ - : "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 av_noinline 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 av_noinline 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 av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ - put_h264_qpel8or16_hv1_lowpass_ ## MMX(tmp, src, tmpStride, srcStride, size);\ - OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ -}\ -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 av_noinline void OPNAME ## pixels4_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ -{\ - __asm__ volatile(\ - "movq (%1), %%mm0 \n\t"\ - "movq 24(%1), %%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"\ - "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"((x86_reg)src8Stride), "D"((x86_reg)dstStride)\ - :"memory");\ -}\ -static av_noinline void OPNAME ## pixels8_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ -{\ - do{\ - __asm__ volatile(\ - "movq (%1), %%mm0 \n\t"\ - "movq 8(%1), %%mm1 \n\t"\ - "movq 48(%1), %%mm2 \n\t"\ - "movq 8+48(%1), %%mm3 \n\t"\ - "psraw $5, %%mm0 \n\t"\ - "psraw $5, %%mm1 \n\t"\ - "psraw $5, %%mm2 \n\t"\ - "psraw $5, %%mm3 \n\t"\ - "packuswb %%mm1, %%mm0 \n\t"\ - "packuswb %%mm3, %%mm2 \n\t"\ - PAVGB" (%0), %%mm0 \n\t"\ - PAVGB" (%0,%3), %%mm2 \n\t"\ - OP(%%mm0, (%2), %%mm5, q)\ - OP(%%mm2, (%2,%4), %%mm5, q)\ - ::"a"(src8), "c"(src16), "d"(dst),\ - "r"((x86_reg)src8Stride), "r"((x86_reg)dstStride)\ - :"memory");\ - src8 += 2L*src8Stride;\ - src16 += 48;\ - dst += 2L*dstStride;\ - }while(h-=2);\ -}\ -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);\ -}\ - - -#if ARCH_X86_64 -#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ -static av_noinline void OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, uint8_t *src, uint8_t *src2, int dstStride, int src2Stride){\ - int h=16;\ - __asm__ volatile(\ - "pxor %%xmm15, %%xmm15 \n\t"\ - "movdqa %6, %%xmm14 \n\t"\ - "movdqa %7, %%xmm13 \n\t"\ - "1: \n\t"\ - "lddqu 6(%0), %%xmm1 \n\t"\ - "lddqu -2(%0), %%xmm7 \n\t"\ - "movdqa %%xmm1, %%xmm0 \n\t"\ - "punpckhbw %%xmm15, %%xmm1 \n\t"\ - "punpcklbw %%xmm15, %%xmm0 \n\t"\ - "punpcklbw %%xmm15, %%xmm7 \n\t"\ - "movdqa %%xmm1, %%xmm2 \n\t"\ - "movdqa %%xmm0, %%xmm6 \n\t"\ - "movdqa %%xmm1, %%xmm3 \n\t"\ - "movdqa %%xmm0, %%xmm8 \n\t"\ - "movdqa %%xmm1, %%xmm4 \n\t"\ - "movdqa %%xmm0, %%xmm9 \n\t"\ - "movdqa %%xmm0, %%xmm12 \n\t"\ - "movdqa %%xmm1, %%xmm11 \n\t"\ - "palignr $10,%%xmm0, %%xmm11\n\t"\ - "palignr $10,%%xmm7, %%xmm12\n\t"\ - "palignr $2, %%xmm0, %%xmm4 \n\t"\ - "palignr $2, %%xmm7, %%xmm9 \n\t"\ - "palignr $4, %%xmm0, %%xmm3 \n\t"\ - "palignr $4, %%xmm7, %%xmm8 \n\t"\ - "palignr $6, %%xmm0, %%xmm2 \n\t"\ - "palignr $6, %%xmm7, %%xmm6 \n\t"\ - "paddw %%xmm0 ,%%xmm11 \n\t"\ - "palignr $8, %%xmm0, %%xmm1 \n\t"\ - "palignr $8, %%xmm7, %%xmm0 \n\t"\ - "paddw %%xmm12,%%xmm7 \n\t"\ - "paddw %%xmm3, %%xmm2 \n\t"\ - "paddw %%xmm8, %%xmm6 \n\t"\ - "paddw %%xmm4, %%xmm1 \n\t"\ - "paddw %%xmm9, %%xmm0 \n\t"\ - "psllw $2, %%xmm2 \n\t"\ - "psllw $2, %%xmm6 \n\t"\ - "psubw %%xmm1, %%xmm2 \n\t"\ - "psubw %%xmm0, %%xmm6 \n\t"\ - "paddw %%xmm13,%%xmm11 \n\t"\ - "paddw %%xmm13,%%xmm7 \n\t"\ - "pmullw %%xmm14,%%xmm2 \n\t"\ - "pmullw %%xmm14,%%xmm6 \n\t"\ - "lddqu (%2), %%xmm3 \n\t"\ - "paddw %%xmm11,%%xmm2 \n\t"\ - "paddw %%xmm7, %%xmm6 \n\t"\ - "psraw $5, %%xmm2 \n\t"\ - "psraw $5, %%xmm6 \n\t"\ - "packuswb %%xmm2,%%xmm6 \n\t"\ - "pavgb %%xmm3, %%xmm6 \n\t"\ - OP(%%xmm6, (%1), %%xmm4, dqa)\ - "add %5, %0 \n\t"\ - "add %5, %1 \n\t"\ - "add %4, %2 \n\t"\ - "decl %3 \n\t"\ - "jg 1b \n\t"\ - : "+a"(src), "+c"(dst), "+d"(src2), "+g"(h)\ - : "D"((x86_reg)src2Stride), "S"((x86_reg)dstStride),\ - "m"(ff_pw_5), "m"(ff_pw_16)\ - : "memory"\ - );\ -} -#else // ARCH_X86_64 -#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ -static av_noinline 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);\ -} -#endif // ARCH_X86_64 - -#define QPEL_H264_H_XMM(OPNAME, OP, MMX)\ -static av_noinline 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 %%xmm7, %%xmm7 \n\t"\ - "movdqa %0, %%xmm6 \n\t"\ - :: "m"(ff_pw_5)\ - );\ - do{\ - __asm__ volatile(\ - "lddqu -2(%0), %%xmm1 \n\t"\ - "movdqa %%xmm1, %%xmm0 \n\t"\ - "punpckhbw %%xmm7, %%xmm1 \n\t"\ - "punpcklbw %%xmm7, %%xmm0 \n\t"\ - "movdqa %%xmm1, %%xmm2 \n\t"\ - "movdqa %%xmm1, %%xmm3 \n\t"\ - "movdqa %%xmm1, %%xmm4 \n\t"\ - "movdqa %%xmm1, %%xmm5 \n\t"\ - "palignr $2, %%xmm0, %%xmm4 \n\t"\ - "palignr $4, %%xmm0, %%xmm3 \n\t"\ - "palignr $6, %%xmm0, %%xmm2 \n\t"\ - "palignr $8, %%xmm0, %%xmm1 \n\t"\ - "palignr $10,%%xmm0, %%xmm5 \n\t"\ - "paddw %%xmm5, %%xmm0 \n\t"\ - "paddw %%xmm3, %%xmm2 \n\t"\ - "paddw %%xmm4, %%xmm1 \n\t"\ - "psllw $2, %%xmm2 \n\t"\ - "movq (%2), %%xmm3 \n\t"\ - "psubw %%xmm1, %%xmm2 \n\t"\ - "paddw %5, %%xmm0 \n\t"\ - "pmullw %%xmm6, %%xmm2 \n\t"\ - "paddw %%xmm0, %%xmm2 \n\t"\ - "psraw $5, %%xmm2 \n\t"\ - "packuswb %%xmm2, %%xmm2 \n\t"\ - "pavgb %%xmm3, %%xmm2 \n\t"\ - OP(%%xmm2, (%1), %%xmm4, q)\ - "add %4, %0 \n\t"\ - "add %4, %1 \n\t"\ - "add %3, %2 \n\t"\ - : "+a"(src), "+c"(dst), "+d"(src2)\ - : "D"((x86_reg)src2Stride), "S"((x86_reg)dstStride),\ - "m"(ff_pw_16)\ - : "memory"\ - );\ - }while(--h);\ -}\ -QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ -\ -static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - int h=8;\ - __asm__ volatile(\ - "pxor %%xmm7, %%xmm7 \n\t"\ - "movdqa "MANGLE(ff_pw_5)", %%xmm6\n\t"\ - "1: \n\t"\ - "lddqu -2(%0), %%xmm1 \n\t"\ - "movdqa %%xmm1, %%xmm0 \n\t"\ - "punpckhbw %%xmm7, %%xmm1 \n\t"\ - "punpcklbw %%xmm7, %%xmm0 \n\t"\ - "movdqa %%xmm1, %%xmm2 \n\t"\ - "movdqa %%xmm1, %%xmm3 \n\t"\ - "movdqa %%xmm1, %%xmm4 \n\t"\ - "movdqa %%xmm1, %%xmm5 \n\t"\ - "palignr $2, %%xmm0, %%xmm4 \n\t"\ - "palignr $4, %%xmm0, %%xmm3 \n\t"\ - "palignr $6, %%xmm0, %%xmm2 \n\t"\ - "palignr $8, %%xmm0, %%xmm1 \n\t"\ - "palignr $10,%%xmm0, %%xmm5 \n\t"\ - "paddw %%xmm5, %%xmm0 \n\t"\ - "paddw %%xmm3, %%xmm2 \n\t"\ - "paddw %%xmm4, %%xmm1 \n\t"\ - "psllw $2, %%xmm2 \n\t"\ - "psubw %%xmm1, %%xmm2 \n\t"\ - "paddw "MANGLE(ff_pw_16)", %%xmm0\n\t"\ - "pmullw %%xmm6, %%xmm2 \n\t"\ - "paddw %%xmm0, %%xmm2 \n\t"\ - "psraw $5, %%xmm2 \n\t"\ - "packuswb %%xmm2, %%xmm2 \n\t"\ - OP(%%xmm2, (%1), %%xmm4, q)\ - "add %3, %0 \n\t"\ - "add %4, %1 \n\t"\ - "decl %2 \n\t"\ - " jnz 1b \n\t"\ - : "+a"(src), "+c"(dst), "+g"(h)\ - : "D"((x86_reg)srcStride), "S"((x86_reg)dstStride)\ - : "memory"\ - );\ -}\ -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);\ -}\ - -#define QPEL_H264_V_XMM(OPNAME, OP, MMX)\ -static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ - src -= 2*srcStride;\ - \ - __asm__ volatile(\ - "pxor %%xmm7, %%xmm7 \n\t"\ - "movq (%0), %%xmm0 \n\t"\ - "add %2, %0 \n\t"\ - "movq (%0), %%xmm1 \n\t"\ - "add %2, %0 \n\t"\ - "movq (%0), %%xmm2 \n\t"\ - "add %2, %0 \n\t"\ - "movq (%0), %%xmm3 \n\t"\ - "add %2, %0 \n\t"\ - "movq (%0), %%xmm4 \n\t"\ - "add %2, %0 \n\t"\ - "punpcklbw %%xmm7, %%xmm0 \n\t"\ - "punpcklbw %%xmm7, %%xmm1 \n\t"\ - "punpcklbw %%xmm7, %%xmm2 \n\t"\ - "punpcklbw %%xmm7, %%xmm3 \n\t"\ - "punpcklbw %%xmm7, %%xmm4 \n\t"\ - QPEL_H264V_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, OP)\ - QPEL_H264V_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, OP)\ - QPEL_H264V_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, OP)\ - QPEL_H264V_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, OP)\ - QPEL_H264V_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, OP)\ - QPEL_H264V_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, OP)\ - QPEL_H264V_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, OP)\ - QPEL_H264V_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, OP)\ - \ - : "+a"(src), "+c"(dst)\ - : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ - : "memory"\ - );\ - if(h==16){\ - __asm__ volatile(\ - QPEL_H264V_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, OP)\ - QPEL_H264V_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, OP)\ - QPEL_H264V_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, OP)\ - QPEL_H264V_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, OP)\ - QPEL_H264V_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, OP)\ - QPEL_H264V_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, OP)\ - QPEL_H264V_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, OP)\ - QPEL_H264V_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, OP)\ - \ - : "+a"(src), "+c"(dst)\ - : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ - : "memory"\ - );\ - }\ -}\ -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 av_noinline 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 av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, uint8_t *src, int tmpStride, int srcStride, int size){ - int w = (size+8)>>3; - src -= 2*srcStride+2; - while(w--){ - __asm__ volatile( - "pxor %%xmm7, %%xmm7 \n\t" - "movq (%0), %%xmm0 \n\t" - "add %2, %0 \n\t" - "movq (%0), %%xmm1 \n\t" - "add %2, %0 \n\t" - "movq (%0), %%xmm2 \n\t" - "add %2, %0 \n\t" - "movq (%0), %%xmm3 \n\t" - "add %2, %0 \n\t" - "movq (%0), %%xmm4 \n\t" - "add %2, %0 \n\t" - "punpcklbw %%xmm7, %%xmm0 \n\t" - "punpcklbw %%xmm7, %%xmm1 \n\t" - "punpcklbw %%xmm7, %%xmm2 \n\t" - "punpcklbw %%xmm7, %%xmm3 \n\t" - "punpcklbw %%xmm7, %%xmm4 \n\t" - QPEL_H264HV_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, 0*48) - QPEL_H264HV_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, 1*48) - QPEL_H264HV_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, 2*48) - QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 3*48) - QPEL_H264HV_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, 4*48) - QPEL_H264HV_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, 5*48) - QPEL_H264HV_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, 6*48) - QPEL_H264HV_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, 7*48) - : "+a"(src) - : "c"(tmp), "S"((x86_reg)srcStride), "m"(ff_pw_5), "m"(ff_pw_16) - : "memory" - ); - if(size==16){ - __asm__ volatile( - QPEL_H264HV_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, 8*48) - QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 9*48) - QPEL_H264HV_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, 10*48) - QPEL_H264HV_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, 11*48) - QPEL_H264HV_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, 12*48) - QPEL_H264HV_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, 13*48) - QPEL_H264HV_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, 14*48) - QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 15*48) - : "+a"(src) - : "c"(tmp), "S"((x86_reg)srcStride), "m"(ff_pw_5), "m"(ff_pw_16) - : "memory" - ); - } - tmp += 8; - src += 8 - (size+5)*srcStride; - } -} - -#define QPEL_H264_HV2_XMM(OPNAME, OP, MMX)\ -static av_always_inline void OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size){\ - int h = size;\ - if(size == 16){\ - __asm__ volatile(\ - "1: \n\t"\ - "movdqa 32(%0), %%xmm4 \n\t"\ - "movdqa 16(%0), %%xmm5 \n\t"\ - "movdqa (%0), %%xmm7 \n\t"\ - "movdqa %%xmm4, %%xmm3 \n\t"\ - "movdqa %%xmm4, %%xmm2 \n\t"\ - "movdqa %%xmm4, %%xmm1 \n\t"\ - "movdqa %%xmm4, %%xmm0 \n\t"\ - "palignr $10, %%xmm5, %%xmm0 \n\t"\ - "palignr $8, %%xmm5, %%xmm1 \n\t"\ - "palignr $6, %%xmm5, %%xmm2 \n\t"\ - "palignr $4, %%xmm5, %%xmm3 \n\t"\ - "palignr $2, %%xmm5, %%xmm4 \n\t"\ - "paddw %%xmm5, %%xmm0 \n\t"\ - "paddw %%xmm4, %%xmm1 \n\t"\ - "paddw %%xmm3, %%xmm2 \n\t"\ - "movdqa %%xmm5, %%xmm6 \n\t"\ - "movdqa %%xmm5, %%xmm4 \n\t"\ - "movdqa %%xmm5, %%xmm3 \n\t"\ - "palignr $8, %%xmm7, %%xmm4 \n\t"\ - "palignr $2, %%xmm7, %%xmm6 \n\t"\ - "palignr $10, %%xmm7, %%xmm3 \n\t"\ - "paddw %%xmm6, %%xmm4 \n\t"\ - "movdqa %%xmm5, %%xmm6 \n\t"\ - "palignr $6, %%xmm7, %%xmm5 \n\t"\ - "palignr $4, %%xmm7, %%xmm6 \n\t"\ - "paddw %%xmm7, %%xmm3 \n\t"\ - "paddw %%xmm6, %%xmm5 \n\t"\ - \ - "psubw %%xmm1, %%xmm0 \n\t"\ - "psubw %%xmm4, %%xmm3 \n\t"\ - "psraw $2, %%xmm0 \n\t"\ - "psraw $2, %%xmm3 \n\t"\ - "psubw %%xmm1, %%xmm0 \n\t"\ - "psubw %%xmm4, %%xmm3 \n\t"\ - "paddw %%xmm2, %%xmm0 \n\t"\ - "paddw %%xmm5, %%xmm3 \n\t"\ - "psraw $2, %%xmm0 \n\t"\ - "psraw $2, %%xmm3 \n\t"\ - "paddw %%xmm2, %%xmm0 \n\t"\ - "paddw %%xmm5, %%xmm3 \n\t"\ - "psraw $6, %%xmm0 \n\t"\ - "psraw $6, %%xmm3 \n\t"\ - "packuswb %%xmm0, %%xmm3 \n\t"\ - OP(%%xmm3, (%1), %%xmm7, dqa)\ - "add $48, %0 \n\t"\ - "add %3, %1 \n\t"\ - "decl %2 \n\t"\ - " jnz 1b \n\t"\ - : "+a"(tmp), "+c"(dst), "+g"(h)\ - : "S"((x86_reg)dstStride)\ - : "memory"\ - );\ - }else{\ - __asm__ volatile(\ - "1: \n\t"\ - "movdqa 16(%0), %%xmm1 \n\t"\ - "movdqa (%0), %%xmm0 \n\t"\ - "movdqa %%xmm1, %%xmm2 \n\t"\ - "movdqa %%xmm1, %%xmm3 \n\t"\ - "movdqa %%xmm1, %%xmm4 \n\t"\ - "movdqa %%xmm1, %%xmm5 \n\t"\ - "palignr $10, %%xmm0, %%xmm5 \n\t"\ - "palignr $8, %%xmm0, %%xmm4 \n\t"\ - "palignr $6, %%xmm0, %%xmm3 \n\t"\ - "palignr $4, %%xmm0, %%xmm2 \n\t"\ - "palignr $2, %%xmm0, %%xmm1 \n\t"\ - "paddw %%xmm5, %%xmm0 \n\t"\ - "paddw %%xmm4, %%xmm1 \n\t"\ - "paddw %%xmm3, %%xmm2 \n\t"\ - "psubw %%xmm1, %%xmm0 \n\t"\ - "psraw $2, %%xmm0 \n\t"\ - "psubw %%xmm1, %%xmm0 \n\t"\ - "paddw %%xmm2, %%xmm0 \n\t"\ - "psraw $2, %%xmm0 \n\t"\ - "paddw %%xmm2, %%xmm0 \n\t"\ - "psraw $6, %%xmm0 \n\t"\ - "packuswb %%xmm0, %%xmm0 \n\t"\ - OP(%%xmm0, (%1), %%xmm7, q)\ - "add $48, %0 \n\t"\ - "add %3, %1 \n\t"\ - "decl %2 \n\t"\ - " jnz 1b \n\t"\ - : "+a"(tmp), "+c"(dst), "+g"(h)\ - : "S"((x86_reg)dstStride)\ - : "memory"\ - );\ - }\ -} - -#define QPEL_H264_HV_XMM(OPNAME, OP, MMX)\ -static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ - put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\ - OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ -}\ -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);\ -}\ - -#define put_pixels8_l2_sse2 put_pixels8_l2_mmx2 -#define avg_pixels8_l2_sse2 avg_pixels8_l2_mmx2 -#define put_pixels16_l2_sse2 put_pixels16_l2_mmx2 -#define avg_pixels16_l2_sse2 avg_pixels16_l2_mmx2 -#define put_pixels8_l2_ssse3 put_pixels8_l2_mmx2 -#define avg_pixels8_l2_ssse3 avg_pixels8_l2_mmx2 -#define put_pixels16_l2_ssse3 put_pixels16_l2_mmx2 -#define avg_pixels16_l2_ssse3 avg_pixels16_l2_mmx2 - -#define put_pixels8_l2_shift5_sse2 put_pixels8_l2_shift5_mmx2 -#define avg_pixels8_l2_shift5_sse2 avg_pixels8_l2_shift5_mmx2 -#define put_pixels16_l2_shift5_sse2 put_pixels16_l2_shift5_mmx2 -#define avg_pixels16_l2_shift5_sse2 avg_pixels16_l2_shift5_mmx2 -#define put_pixels8_l2_shift5_ssse3 put_pixels8_l2_shift5_mmx2 -#define avg_pixels8_l2_shift5_ssse3 avg_pixels8_l2_shift5_mmx2 -#define put_pixels16_l2_shift5_ssse3 put_pixels16_l2_shift5_mmx2 -#define avg_pixels16_l2_shift5_ssse3 avg_pixels16_l2_shift5_mmx2 - -#define put_h264_qpel8_h_lowpass_l2_sse2 put_h264_qpel8_h_lowpass_l2_mmx2 -#define avg_h264_qpel8_h_lowpass_l2_sse2 avg_h264_qpel8_h_lowpass_l2_mmx2 -#define put_h264_qpel16_h_lowpass_l2_sse2 put_h264_qpel16_h_lowpass_l2_mmx2 -#define avg_h264_qpel16_h_lowpass_l2_sse2 avg_h264_qpel16_h_lowpass_l2_mmx2 - -#define put_h264_qpel8_v_lowpass_ssse3 put_h264_qpel8_v_lowpass_sse2 -#define avg_h264_qpel8_v_lowpass_ssse3 avg_h264_qpel8_v_lowpass_sse2 -#define put_h264_qpel16_v_lowpass_ssse3 put_h264_qpel16_v_lowpass_sse2 -#define avg_h264_qpel16_v_lowpass_ssse3 avg_h264_qpel16_v_lowpass_sse2 - -#define put_h264_qpel8or16_hv2_lowpass_sse2 put_h264_qpel8or16_hv2_lowpass_mmx2 -#define avg_h264_qpel8or16_hv2_lowpass_sse2 avg_h264_qpel8or16_hv2_lowpass_mmx2 - -#define H264_MC(OPNAME, SIZE, MMX, ALIGN) \ -H264_MC_C(OPNAME, SIZE, MMX, ALIGN)\ -H264_MC_V(OPNAME, SIZE, MMX, ALIGN)\ -H264_MC_H(OPNAME, SIZE, MMX, ALIGN)\ -H264_MC_HV(OPNAME, SIZE, MMX, ALIGN)\ - -static void put_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src, int stride){ - put_pixels16_sse2(dst, src, stride, 16); -} -static void avg_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src, int stride){ - avg_pixels16_sse2(dst, src, stride, 16); -} -#define put_h264_qpel8_mc00_sse2 put_h264_qpel8_mc00_mmx2 -#define avg_h264_qpel8_mc00_sse2 avg_h264_qpel8_mc00_mmx2 - -#define H264_MC_C(OPNAME, SIZE, MMX, ALIGN) \ -static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels ## SIZE ## _ ## MMX(dst, src, stride, SIZE);\ -}\ - -#define H264_MC_H(OPNAME, SIZE, MMX, ALIGN) \ -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);\ -}\ - -#define H264_MC_V(OPNAME, SIZE, MMX, ALIGN) \ -static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src, temp, 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){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src+stride, temp, stride, stride, SIZE);\ -}\ - -#define H264_MC_HV(OPNAME, SIZE, MMX, ALIGN) \ -static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(ALIGN, uint16_t, temp)[SIZE*(SIZE<8?12:24)];\ - OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(dst, temp, src, stride, SIZE, stride);\ -}\ -\ -static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ - uint8_t * const halfHV= temp;\ - int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, 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){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ - uint8_t * const halfHV= temp;\ - int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, 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){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ - uint8_t * const halfHV= temp;\ - int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ - 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){\ - DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\ - uint8_t * const halfHV= temp;\ - int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ - assert(((int)temp & 7) == 0);\ - 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 H264_MC_4816(MMX)\ -H264_MC(put_, 4, MMX, 8)\ -H264_MC(put_, 8, MMX, 8)\ -H264_MC(put_, 16,MMX, 8)\ -H264_MC(avg_, 4, MMX, 8)\ -H264_MC(avg_, 8, MMX, 8)\ -H264_MC(avg_, 16,MMX, 8)\ - -#define H264_MC_816(QPEL, XMM)\ -QPEL(put_, 8, XMM, 16)\ -QPEL(put_, 16,XMM, 16)\ -QPEL(avg_, 8, XMM, 16)\ -QPEL(avg_, 16,XMM, 16)\ - - -#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) -QPEL_H264_V_XMM(put_, PUT_OP, sse2) -QPEL_H264_V_XMM(avg_, AVG_MMX2_OP, sse2) -QPEL_H264_HV_XMM(put_, PUT_OP, sse2) -QPEL_H264_HV_XMM(avg_, AVG_MMX2_OP, sse2) -#if HAVE_SSSE3 -QPEL_H264_H_XMM(put_, PUT_OP, ssse3) -QPEL_H264_H_XMM(avg_, AVG_MMX2_OP, ssse3) -QPEL_H264_HV2_XMM(put_, PUT_OP, ssse3) -QPEL_H264_HV2_XMM(avg_, AVG_MMX2_OP, ssse3) -QPEL_H264_HV_XMM(put_, PUT_OP, ssse3) -QPEL_H264_HV_XMM(avg_, AVG_MMX2_OP, ssse3) -#endif -#undef PAVGB - -H264_MC_4816(3dnow) -H264_MC_4816(mmx2) -H264_MC_816(H264_MC_V, sse2) -H264_MC_816(H264_MC_HV, sse2) -#if HAVE_SSSE3 -H264_MC_816(H264_MC_H, ssse3) -H264_MC_816(H264_MC_HV, ssse3) -#endif - -/* rnd interleaved with rnd div 8, use p+1 to access rnd div 8 */ -DECLARE_ALIGNED(8, static const uint64_t, h264_rnd_reg)[4] = { - 0x0020002000200020ULL, 0x0004000400040004ULL, 0x001C001C001C001CULL, 0x0003000300030003ULL -}; - -#define H264_CHROMA_OP(S,D) -#define H264_CHROMA_OP4(S,D,T) -#define H264_CHROMA_MC8_TMPL put_h264_chroma_generic_mc8_mmx -#define H264_CHROMA_MC4_TMPL put_h264_chroma_generic_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" - -static void put_h264_chroma_mc8_mmx_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - put_h264_chroma_generic_mc8_mmx(dst, src, stride, h, x, y, h264_rnd_reg); -} -static void put_vc1_chroma_mc8_mmx_nornd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - put_h264_chroma_generic_mc8_mmx(dst, src, stride, h, x, y, h264_rnd_reg+2); -} -static void put_h264_chroma_mc4_mmx(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - put_h264_chroma_generic_mc4_mmx(dst, src, stride, h, x, y, h264_rnd_reg); -} - -#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_generic_mc8_mmx2 -#define H264_CHROMA_MC4_TMPL avg_h264_chroma_generic_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" -static void avg_h264_chroma_mc8_mmx2_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc8_mmx2(dst, src, stride, h, x, y, h264_rnd_reg); -} -static void avg_vc1_chroma_mc8_mmx2_nornd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc8_mmx2(dst, src, stride, h, x, y, h264_rnd_reg+2); -} -static void avg_h264_chroma_mc4_mmx2(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc4_mmx2(dst, src, stride, h, x, y, h264_rnd_reg); -} -#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_generic_mc8_3dnow -#define H264_CHROMA_MC4_TMPL avg_h264_chroma_generic_mc4_3dnow -#define H264_CHROMA_MC8_MV0 avg_pixels8_3dnow -#include "dsputil_h264_template_mmx.c" -static void avg_h264_chroma_mc8_3dnow_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc8_3dnow(dst, src, stride, h, x, y, h264_rnd_reg); -} -static void avg_h264_chroma_mc4_3dnow(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc4_3dnow(dst, src, stride, h, x, y, h264_rnd_reg); -} -#undef H264_CHROMA_OP -#undef H264_CHROMA_OP4 -#undef H264_CHROMA_MC8_TMPL -#undef H264_CHROMA_MC4_TMPL -#undef H264_CHROMA_MC8_MV0 - -#if HAVE_SSSE3 -#define AVG_OP(X) -#undef H264_CHROMA_MC8_TMPL -#undef H264_CHROMA_MC4_TMPL -#define H264_CHROMA_MC8_TMPL put_h264_chroma_mc8_ssse3 -#define H264_CHROMA_MC4_TMPL put_h264_chroma_mc4_ssse3 -#define H264_CHROMA_MC8_MV0 put_pixels8_mmx -#include "dsputil_h264_template_ssse3.c" -static void put_h264_chroma_mc8_ssse3_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - put_h264_chroma_mc8_ssse3(dst, src, stride, h, x, y, 1); -} -static void put_vc1_chroma_mc8_ssse3_nornd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - put_h264_chroma_mc8_ssse3(dst, src, stride, h, x, y, 0); -} - -#undef AVG_OP -#undef H264_CHROMA_MC8_TMPL -#undef H264_CHROMA_MC4_TMPL -#undef H264_CHROMA_MC8_MV0 -#define AVG_OP(X) X -#define H264_CHROMA_MC8_TMPL avg_h264_chroma_mc8_ssse3 -#define H264_CHROMA_MC4_TMPL avg_h264_chroma_mc4_ssse3 -#define H264_CHROMA_MC8_MV0 avg_pixels8_mmx2 -#include "dsputil_h264_template_ssse3.c" -static void avg_h264_chroma_mc8_ssse3_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_mc8_ssse3(dst, src, stride, h, x, y, 1); -} -static void avg_vc1_chroma_mc8_ssse3_nornd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_mc8_ssse3(dst, src, stride, h, x, y, 0); -} -#undef AVG_OP -#undef H264_CHROMA_MC8_TMPL -#undef H264_CHROMA_MC4_TMPL -#undef H264_CHROMA_MC8_MV0 -#endif - -/***********************************/ -/* 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. - * See http://libmpeg2.sourceforge.net/ for updates. - * - * 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 mpeg2dec; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "libavcodec/dsputil.h" - -#include "dsputil_mmx.h" -#include "mmx.h" - -#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 * const row, const int offset, - const int16_t * const 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 * const table, - const int32_t * const 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 * const row, const 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 * const row, const int store, - const int offset, - const int16_t * const 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 * const row, const int offset, - const int16_t * const 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 * const table, - const int32_t * const 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 * const row, const 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 * const row, const int store, - const int offset, const int16_t * const 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 - it is 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 * const col, const int offset) -{ -#define T1 13036 -#define T2 27146 -#define T3 43790 -#define C4 23170 - - DECLARE_ALIGNED(8, static const short, t1_vector)[] = {T1,T1,T1,T1}; - DECLARE_ALIGNED(8, static const short, t2_vector)[] = {T2,T2,T2,T2}; - DECLARE_ALIGNED(8, static const short, t3_vector)[] = {T3,T3,T3,T3}; - DECLARE_ALIGNED(8, static const short, c4_vector)[] = {C4,C4,C4,C4}; - - /* column code adapted from Peter Gubanov */ - /* http://www.elecard.com/peter/idct.shtml */ - - movq_m2r (*t1_vector, 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_vector, 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_vector, 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_vector, 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 -} - - -DECLARE_ALIGNED(8, static const int32_t, rounder0)[] = - rounder ((1 << (COL_SHIFT - 1)) - 0.5); -DECLARE_ALIGNED(8, static const int32_t, rounder4)[] = rounder (0); -DECLARE_ALIGNED(8, static const int32_t, rounder1)[] = - rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ -DECLARE_ALIGNED(8, static const int32_t, rounder7)[] = - rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ -DECLARE_ALIGNED(8, static const int32_t, rounder2)[] = - rounder (0.60355339059); /* C2 * (C6+C2)/2 */ -DECLARE_ALIGNED(8, static const int32_t, rounder6)[] = - rounder (-0.25); /* C2 * (C6-C2)/2 */ -DECLARE_ALIGNED(8, static const int32_t, rounder3)[] = - rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ -DECLARE_ALIGNED(8, static const int32_t, rounder5)[] = - 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 * const block) \ -{ \ - DECLARE_ALIGNED(16, static const int16_t, table04)[] = \ - table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ - DECLARE_ALIGNED(16, static const int16_t, table17)[] = \ - table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ - DECLARE_ALIGNED(16, static const int16_t, table26)[] = \ - table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ - DECLARE_ALIGNED(16, static const int16_t, table35)[] = \ - 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); \ -} - -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/tizen/distrib/ffmpeg/libavcodec/x86/idct_mmx_xvid.c b/tizen/distrib/ffmpeg/libavcodec/x86/idct_mmx_xvid.c deleted file mode 100644 index 466cf75..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/idct_mmx_xvid.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * XVID MPEG-4 VIDEO CODEC - * - MMX and XMM forward discrete cosine transform - - * - * Copyright(C) 2001 Peter Ross - * - * 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 - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "libavcodec/avcodec.h" -#include "idct_xvid.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) -//----------------------------------------------------------------------------- - - -DECLARE_ALIGNED(8, static const int16_t, tg_1_16)[4*4] = { - 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 - -DECLARE_ALIGNED(8, static const int32_t, rounder_0)[2*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 -DECLARE_ALIGNED(8, static const int16_t, tab_i_04_mmx)[32*4] = { - 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 -DECLARE_ALIGNED(8, static const int16_t, tab_i_04_xmm)[32*4] = { - 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 $0x88,%%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 $0x88,%%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 $0xdd,%%mm2,%%mm2 \n\t"/* x3 x1 x3 x1*/\ - "pmaddwd %%mm2,%%mm6 \n\t"/* x3*w21+x1*w20 x3*w17+x1*w16*/\ - "pshufw $0xdd,%%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 $0xb1,%%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/tizen/distrib/ffmpeg/libavcodec/x86/idct_sse2_xvid.c b/tizen/distrib/ffmpeg/libavcodec/x86/idct_sse2_xvid.c deleted file mode 100644 index fc670e2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/idct_sse2_xvid.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * XVID MPEG-4 VIDEO CODEC - * - SSE2 inverse discrete cosine transform - - * - * Copyright(C) 2003 Pascal Massimino - * - * Conversion to gcc syntax with modifications - * by Alexander Strange - * - * Originally from dct/x86_asm/fdct_sse2_skal.asm in Xvid. - * - * This file is part of FFmpeg. - * - * Vertical pass is an implementation of the scheme: - * Loeffler C., Ligtenberg A., and Moschytz C.S.: - * Practical Fast 1D DCT Algorithm with Eleven Multiplications, - * Proc. ICASSP 1989, 988-991. - * - * Horizontal pass is a double 4x4 vector/matrix multiplication, - * (see also Intel's Application Note 922: - * http://developer.intel.com/vtune/cbts/strmsimd/922down.htm - * Copyright (C) 1999 Intel Corporation) - * - * More details at http://skal.planet-d.net/coding/dct.html - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/dsputil.h" -#include "idct_xvid.h" -#include "dsputil_mmx.h" - -/*! - * @file - * @brief SSE2 idct compatible with xvidmmx - */ - -#define X8(x) x,x,x,x,x,x,x,x - -#define ROW_SHIFT 11 -#define COL_SHIFT 6 - -DECLARE_ASM_CONST(16, int16_t, tan1)[] = {X8(13036)}; // tan( pi/16) -DECLARE_ASM_CONST(16, int16_t, tan2)[] = {X8(27146)}; // tan(2pi/16) = sqrt(2)-1 -DECLARE_ASM_CONST(16, int16_t, tan3)[] = {X8(43790)}; // tan(3pi/16)-1 -DECLARE_ASM_CONST(16, int16_t, sqrt2)[]= {X8(23170)}; // 0.5/sqrt(2) -DECLARE_ASM_CONST(8, uint8_t, m127)[] = {X8(127)}; - -DECLARE_ASM_CONST(16, int16_t, iTab1)[] = { - 0x4000, 0x539f, 0xc000, 0xac61, 0x4000, 0xdd5d, 0x4000, 0xdd5d, - 0x4000, 0x22a3, 0x4000, 0x22a3, 0xc000, 0x539f, 0x4000, 0xac61, - 0x3249, 0x11a8, 0x4b42, 0xee58, 0x11a8, 0x4b42, 0x11a8, 0xcdb7, - 0x58c5, 0x4b42, 0xa73b, 0xcdb7, 0x3249, 0xa73b, 0x4b42, 0xa73b -}; - -DECLARE_ASM_CONST(16, int16_t, iTab2)[] = { - 0x58c5, 0x73fc, 0xa73b, 0x8c04, 0x58c5, 0xcff5, 0x58c5, 0xcff5, - 0x58c5, 0x300b, 0x58c5, 0x300b, 0xa73b, 0x73fc, 0x58c5, 0x8c04, - 0x45bf, 0x187e, 0x6862, 0xe782, 0x187e, 0x6862, 0x187e, 0xba41, - 0x7b21, 0x6862, 0x84df, 0xba41, 0x45bf, 0x84df, 0x6862, 0x84df -}; - -DECLARE_ASM_CONST(16, int16_t, iTab3)[] = { - 0x539f, 0x6d41, 0xac61, 0x92bf, 0x539f, 0xd2bf, 0x539f, 0xd2bf, - 0x539f, 0x2d41, 0x539f, 0x2d41, 0xac61, 0x6d41, 0x539f, 0x92bf, - 0x41b3, 0x1712, 0x6254, 0xe8ee, 0x1712, 0x6254, 0x1712, 0xbe4d, - 0x73fc, 0x6254, 0x8c04, 0xbe4d, 0x41b3, 0x8c04, 0x6254, 0x8c04 -}; - -DECLARE_ASM_CONST(16, int16_t, iTab4)[] = { - 0x4b42, 0x6254, 0xb4be, 0x9dac, 0x4b42, 0xd746, 0x4b42, 0xd746, - 0x4b42, 0x28ba, 0x4b42, 0x28ba, 0xb4be, 0x6254, 0x4b42, 0x9dac, - 0x3b21, 0x14c3, 0x587e, 0xeb3d, 0x14c3, 0x587e, 0x14c3, 0xc4df, - 0x6862, 0x587e, 0x979e, 0xc4df, 0x3b21, 0x979e, 0x587e, 0x979e -}; - -DECLARE_ASM_CONST(16, int32_t, walkenIdctRounders)[] = { - 65536, 65536, 65536, 65536, - 3597, 3597, 3597, 3597, - 2260, 2260, 2260, 2260, - 1203, 1203, 1203, 1203, - 120, 120, 120, 120, - 512, 512, 512, 512 -}; - -// Temporary storage before the column pass -#define ROW1 "%%xmm6" -#define ROW3 "%%xmm4" -#define ROW5 "%%xmm5" -#define ROW7 "%%xmm7" - -#define CLEAR_ODD(r) "pxor "r","r" \n\t" -#define PUT_ODD(dst) "pshufhw $0x1B, %%xmm2, "dst" \n\t" - -#if ARCH_X86_64 - -# define ROW0 "%%xmm8" -# define REG0 ROW0 -# define ROW2 "%%xmm9" -# define REG2 ROW2 -# define ROW4 "%%xmm10" -# define REG4 ROW4 -# define ROW6 "%%xmm11" -# define REG6 ROW6 -# define CLEAR_EVEN(r) CLEAR_ODD(r) -# define PUT_EVEN(dst) PUT_ODD(dst) -# define XMMS "%%xmm12" -# define MOV_32_ONLY "#" -# define SREG2 REG2 -# define TAN3 "%%xmm13" -# define TAN1 "%%xmm14" - -#else - -# define ROW0 "(%0)" -# define REG0 "%%xmm4" -# define ROW2 "2*16(%0)" -# define REG2 "%%xmm4" -# define ROW4 "4*16(%0)" -# define REG4 "%%xmm6" -# define ROW6 "6*16(%0)" -# define REG6 "%%xmm6" -# define CLEAR_EVEN(r) -# define PUT_EVEN(dst) \ - "pshufhw $0x1B, %%xmm2, %%xmm2 \n\t" \ - "movdqa %%xmm2, "dst" \n\t" -# define XMMS "%%xmm2" -# define MOV_32_ONLY "movdqa " -# define SREG2 "%%xmm7" -# define TAN3 "%%xmm0" -# define TAN1 "%%xmm2" - -#endif - -#define ROUND(x) "paddd "MANGLE(x) - -#define JZ(reg, to) \ - "testl "reg","reg" \n\t" \ - "jz "to" \n\t" - -#define JNZ(reg, to) \ - "testl "reg","reg" \n\t" \ - "jnz "to" \n\t" - -#define TEST_ONE_ROW(src, reg, clear) \ - clear \ - "movq "src", %%mm1 \n\t" \ - "por 8+"src", %%mm1 \n\t" \ - "paddusb %%mm0, %%mm1 \n\t" \ - "pmovmskb %%mm1, "reg" \n\t" - -#define TEST_TWO_ROWS(row1, row2, reg1, reg2, clear1, clear2) \ - clear1 \ - clear2 \ - "movq "row1", %%mm1 \n\t" \ - "por 8+"row1", %%mm1 \n\t" \ - "movq "row2", %%mm2 \n\t" \ - "por 8+"row2", %%mm2 \n\t" \ - "paddusb %%mm0, %%mm1 \n\t" \ - "paddusb %%mm0, %%mm2 \n\t" \ - "pmovmskb %%mm1, "reg1" \n\t" \ - "pmovmskb %%mm2, "reg2" \n\t" - -///IDCT pass on rows. -#define iMTX_MULT(src, table, rounder, put) \ - "movdqa "src", %%xmm3 \n\t" \ - "movdqa %%xmm3, %%xmm0 \n\t" \ - "pshufd $0x11, %%xmm3, %%xmm1 \n\t" /* 4602 */ \ - "punpcklqdq %%xmm0, %%xmm0 \n\t" /* 0246 */ \ - "pmaddwd "table", %%xmm0 \n\t" \ - "pmaddwd 16+"table", %%xmm1 \n\t" \ - "pshufd $0xBB, %%xmm3, %%xmm2 \n\t" /* 5713 */ \ - "punpckhqdq %%xmm3, %%xmm3 \n\t" /* 1357 */ \ - "pmaddwd 32+"table", %%xmm2 \n\t" \ - "pmaddwd 48+"table", %%xmm3 \n\t" \ - "paddd %%xmm1, %%xmm0 \n\t" \ - "paddd %%xmm3, %%xmm2 \n\t" \ - rounder", %%xmm0 \n\t" \ - "movdqa %%xmm2, %%xmm3 \n\t" \ - "paddd %%xmm0, %%xmm2 \n\t" \ - "psubd %%xmm3, %%xmm0 \n\t" \ - "psrad $11, %%xmm2 \n\t" \ - "psrad $11, %%xmm0 \n\t" \ - "packssdw %%xmm0, %%xmm2 \n\t" \ - put \ - "1: \n\t" - -#define iLLM_HEAD \ - "movdqa "MANGLE(tan3)", "TAN3" \n\t" \ - "movdqa "MANGLE(tan1)", "TAN1" \n\t" \ - -///IDCT pass on columns. -#define iLLM_PASS(dct) \ - "movdqa "TAN3", %%xmm1 \n\t" \ - "movdqa "TAN1", %%xmm3 \n\t" \ - "pmulhw %%xmm4, "TAN3" \n\t" \ - "pmulhw %%xmm5, %%xmm1 \n\t" \ - "paddsw %%xmm4, "TAN3" \n\t" \ - "paddsw %%xmm5, %%xmm1 \n\t" \ - "psubsw %%xmm5, "TAN3" \n\t" \ - "paddsw %%xmm4, %%xmm1 \n\t" \ - "pmulhw %%xmm7, %%xmm3 \n\t" \ - "pmulhw %%xmm6, "TAN1" \n\t" \ - "paddsw %%xmm6, %%xmm3 \n\t" \ - "psubsw %%xmm7, "TAN1" \n\t" \ - "movdqa %%xmm3, %%xmm7 \n\t" \ - "movdqa "TAN1", %%xmm6 \n\t" \ - "psubsw %%xmm1, %%xmm3 \n\t" \ - "psubsw "TAN3", "TAN1" \n\t" \ - "paddsw %%xmm7, %%xmm1 \n\t" \ - "paddsw %%xmm6, "TAN3" \n\t" \ - "movdqa %%xmm3, %%xmm6 \n\t" \ - "psubsw "TAN3", %%xmm3 \n\t" \ - "paddsw %%xmm6, "TAN3" \n\t" \ - "movdqa "MANGLE(sqrt2)", %%xmm4 \n\t" \ - "pmulhw %%xmm4, %%xmm3 \n\t" \ - "pmulhw %%xmm4, "TAN3" \n\t" \ - "paddsw "TAN3", "TAN3" \n\t" \ - "paddsw %%xmm3, %%xmm3 \n\t" \ - "movdqa "MANGLE(tan2)", %%xmm7 \n\t" \ - MOV_32_ONLY ROW2", "REG2" \n\t" \ - MOV_32_ONLY ROW6", "REG6" \n\t" \ - "movdqa %%xmm7, %%xmm5 \n\t" \ - "pmulhw "REG6", %%xmm7 \n\t" \ - "pmulhw "REG2", %%xmm5 \n\t" \ - "paddsw "REG2", %%xmm7 \n\t" \ - "psubsw "REG6", %%xmm5 \n\t" \ - MOV_32_ONLY ROW0", "REG0" \n\t" \ - MOV_32_ONLY ROW4", "REG4" \n\t" \ - MOV_32_ONLY" "TAN1", (%0) \n\t" \ - "movdqa "REG0", "XMMS" \n\t" \ - "psubsw "REG4", "REG0" \n\t" \ - "paddsw "XMMS", "REG4" \n\t" \ - "movdqa "REG4", "XMMS" \n\t" \ - "psubsw %%xmm7, "REG4" \n\t" \ - "paddsw "XMMS", %%xmm7 \n\t" \ - "movdqa "REG0", "XMMS" \n\t" \ - "psubsw %%xmm5, "REG0" \n\t" \ - "paddsw "XMMS", %%xmm5 \n\t" \ - "movdqa %%xmm5, "XMMS" \n\t" \ - "psubsw "TAN3", %%xmm5 \n\t" \ - "paddsw "XMMS", "TAN3" \n\t" \ - "movdqa "REG0", "XMMS" \n\t" \ - "psubsw %%xmm3, "REG0" \n\t" \ - "paddsw "XMMS", %%xmm3 \n\t" \ - MOV_32_ONLY" (%0), "TAN1" \n\t" \ - "psraw $6, %%xmm5 \n\t" \ - "psraw $6, "REG0" \n\t" \ - "psraw $6, "TAN3" \n\t" \ - "psraw $6, %%xmm3 \n\t" \ - "movdqa "TAN3", 1*16("dct") \n\t" \ - "movdqa %%xmm3, 2*16("dct") \n\t" \ - "movdqa "REG0", 5*16("dct") \n\t" \ - "movdqa %%xmm5, 6*16("dct") \n\t" \ - "movdqa %%xmm7, %%xmm0 \n\t" \ - "movdqa "REG4", %%xmm4 \n\t" \ - "psubsw %%xmm1, %%xmm7 \n\t" \ - "psubsw "TAN1", "REG4" \n\t" \ - "paddsw %%xmm0, %%xmm1 \n\t" \ - "paddsw %%xmm4, "TAN1" \n\t" \ - "psraw $6, %%xmm1 \n\t" \ - "psraw $6, %%xmm7 \n\t" \ - "psraw $6, "TAN1" \n\t" \ - "psraw $6, "REG4" \n\t" \ - "movdqa %%xmm1, ("dct") \n\t" \ - "movdqa "TAN1", 3*16("dct") \n\t" \ - "movdqa "REG4", 4*16("dct") \n\t" \ - "movdqa %%xmm7, 7*16("dct") \n\t" - -///IDCT pass on columns, assuming rows 4-7 are zero. -#define iLLM_PASS_SPARSE(dct) \ - "pmulhw %%xmm4, "TAN3" \n\t" \ - "paddsw %%xmm4, "TAN3" \n\t" \ - "movdqa %%xmm6, %%xmm3 \n\t" \ - "pmulhw %%xmm6, "TAN1" \n\t" \ - "movdqa %%xmm4, %%xmm1 \n\t" \ - "psubsw %%xmm1, %%xmm3 \n\t" \ - "paddsw %%xmm6, %%xmm1 \n\t" \ - "movdqa "TAN1", %%xmm6 \n\t" \ - "psubsw "TAN3", "TAN1" \n\t" \ - "paddsw %%xmm6, "TAN3" \n\t" \ - "movdqa %%xmm3, %%xmm6 \n\t" \ - "psubsw "TAN3", %%xmm3 \n\t" \ - "paddsw %%xmm6, "TAN3" \n\t" \ - "movdqa "MANGLE(sqrt2)", %%xmm4 \n\t" \ - "pmulhw %%xmm4, %%xmm3 \n\t" \ - "pmulhw %%xmm4, "TAN3" \n\t" \ - "paddsw "TAN3", "TAN3" \n\t" \ - "paddsw %%xmm3, %%xmm3 \n\t" \ - "movdqa "MANGLE(tan2)", %%xmm5 \n\t" \ - MOV_32_ONLY ROW2", "SREG2" \n\t" \ - "pmulhw "SREG2", %%xmm5 \n\t" \ - MOV_32_ONLY ROW0", "REG0" \n\t" \ - "movdqa "REG0", %%xmm6 \n\t" \ - "psubsw "SREG2", %%xmm6 \n\t" \ - "paddsw "REG0", "SREG2" \n\t" \ - MOV_32_ONLY" "TAN1", (%0) \n\t" \ - "movdqa "REG0", "XMMS" \n\t" \ - "psubsw %%xmm5, "REG0" \n\t" \ - "paddsw "XMMS", %%xmm5 \n\t" \ - "movdqa %%xmm5, "XMMS" \n\t" \ - "psubsw "TAN3", %%xmm5 \n\t" \ - "paddsw "XMMS", "TAN3" \n\t" \ - "movdqa "REG0", "XMMS" \n\t" \ - "psubsw %%xmm3, "REG0" \n\t" \ - "paddsw "XMMS", %%xmm3 \n\t" \ - MOV_32_ONLY" (%0), "TAN1" \n\t" \ - "psraw $6, %%xmm5 \n\t" \ - "psraw $6, "REG0" \n\t" \ - "psraw $6, "TAN3" \n\t" \ - "psraw $6, %%xmm3 \n\t" \ - "movdqa "TAN3", 1*16("dct") \n\t" \ - "movdqa %%xmm3, 2*16("dct") \n\t" \ - "movdqa "REG0", 5*16("dct") \n\t" \ - "movdqa %%xmm5, 6*16("dct") \n\t" \ - "movdqa "SREG2", %%xmm0 \n\t" \ - "movdqa %%xmm6, %%xmm4 \n\t" \ - "psubsw %%xmm1, "SREG2" \n\t" \ - "psubsw "TAN1", %%xmm6 \n\t" \ - "paddsw %%xmm0, %%xmm1 \n\t" \ - "paddsw %%xmm4, "TAN1" \n\t" \ - "psraw $6, %%xmm1 \n\t" \ - "psraw $6, "SREG2" \n\t" \ - "psraw $6, "TAN1" \n\t" \ - "psraw $6, %%xmm6 \n\t" \ - "movdqa %%xmm1, ("dct") \n\t" \ - "movdqa "TAN1", 3*16("dct") \n\t" \ - "movdqa %%xmm6, 4*16("dct") \n\t" \ - "movdqa "SREG2", 7*16("dct") \n\t" - -inline void ff_idct_xvid_sse2(short *block) -{ - __asm__ volatile( - "movq "MANGLE(m127)", %%mm0 \n\t" - iMTX_MULT("(%0)", MANGLE(iTab1), ROUND(walkenIdctRounders), PUT_EVEN(ROW0)) - iMTX_MULT("1*16(%0)", MANGLE(iTab2), ROUND(walkenIdctRounders+1*16), PUT_ODD(ROW1)) - iMTX_MULT("2*16(%0)", MANGLE(iTab3), ROUND(walkenIdctRounders+2*16), PUT_EVEN(ROW2)) - - TEST_TWO_ROWS("3*16(%0)", "4*16(%0)", "%%eax", "%%ecx", CLEAR_ODD(ROW3), CLEAR_EVEN(ROW4)) - JZ("%%eax", "1f") - iMTX_MULT("3*16(%0)", MANGLE(iTab4), ROUND(walkenIdctRounders+3*16), PUT_ODD(ROW3)) - - TEST_TWO_ROWS("5*16(%0)", "6*16(%0)", "%%eax", "%%edx", CLEAR_ODD(ROW5), CLEAR_EVEN(ROW6)) - TEST_ONE_ROW("7*16(%0)", "%%esi", CLEAR_ODD(ROW7)) - iLLM_HEAD - ASMALIGN(4) - JNZ("%%ecx", "2f") - JNZ("%%eax", "3f") - JNZ("%%edx", "4f") - JNZ("%%esi", "5f") - iLLM_PASS_SPARSE("%0") - "jmp 6f \n\t" - "2: \n\t" - iMTX_MULT("4*16(%0)", MANGLE(iTab1), "#", PUT_EVEN(ROW4)) - "3: \n\t" - iMTX_MULT("5*16(%0)", MANGLE(iTab4), ROUND(walkenIdctRounders+4*16), PUT_ODD(ROW5)) - JZ("%%edx", "1f") - "4: \n\t" - iMTX_MULT("6*16(%0)", MANGLE(iTab3), ROUND(walkenIdctRounders+5*16), PUT_EVEN(ROW6)) - JZ("%%esi", "1f") - "5: \n\t" - iMTX_MULT("7*16(%0)", MANGLE(iTab2), ROUND(walkenIdctRounders+5*16), PUT_ODD(ROW7)) -#if !ARCH_X86_64 - iLLM_HEAD -#endif - iLLM_PASS("%0") - "6: \n\t" - : "+r"(block) - : - : "%eax", "%ecx", "%edx", "%esi", "memory"); -} - -void ff_idct_xvid_sse2_put(uint8_t *dest, int line_size, short *block) -{ - ff_idct_xvid_sse2(block); - put_pixels_clamped_mmx(block, dest, line_size); -} - -void ff_idct_xvid_sse2_add(uint8_t *dest, int line_size, short *block) -{ - ff_idct_xvid_sse2(block); - add_pixels_clamped_mmx(block, dest, line_size); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/idct_xvid.h b/tizen/distrib/ffmpeg/libavcodec/x86/idct_xvid.h deleted file mode 100644 index 5fdc20d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/idct_xvid.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * XVID MPEG-4 VIDEO CODEC - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/*! - * @file - * header for Xvid IDCT functions - */ - -#ifndef AVCODEC_X86_IDCT_XVID_H -#define AVCODEC_X86_IDCT_XVID_H - -#include - -void ff_idct_xvid_mmx(short *block); -void ff_idct_xvid_mmx2(short *block); -void ff_idct_xvid_sse2(short *block); -void ff_idct_xvid_sse2_put(uint8_t *dest, int line_size, short *block); -void ff_idct_xvid_sse2_add(uint8_t *dest, int line_size, short *block); - -#endif /* AVCODEC_X86_IDCT_XVID_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/lpc_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/lpc_mmx.c deleted file mode 100644 index 2ef5fa6..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/lpc_mmx.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * MMX optimized LPC DSP utils - * Copyright (c) 2007 Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "dsputil_mmx.h" - -static void apply_welch_window_sse2(const int32_t *data, int len, double *w_data) -{ - double c = 2.0 / (len-1.0); - int n2 = len>>1; - x86_reg i = -n2*sizeof(int32_t); - x86_reg j = n2*sizeof(int32_t); - __asm__ volatile( - "movsd %0, %%xmm7 \n\t" - "movapd "MANGLE(ff_pd_1)", %%xmm6 \n\t" - "movapd "MANGLE(ff_pd_2)", %%xmm5 \n\t" - "movlhps %%xmm7, %%xmm7 \n\t" - "subpd %%xmm5, %%xmm7 \n\t" - "addsd %%xmm6, %%xmm7 \n\t" - ::"m"(c) - ); -#define WELCH(MOVPD, offset)\ - __asm__ volatile(\ - "1: \n\t"\ - "movapd %%xmm7, %%xmm1 \n\t"\ - "mulpd %%xmm1, %%xmm1 \n\t"\ - "movapd %%xmm6, %%xmm0 \n\t"\ - "subpd %%xmm1, %%xmm0 \n\t"\ - "pshufd $0x4e, %%xmm0, %%xmm1 \n\t"\ - "cvtpi2pd (%3,%0), %%xmm2 \n\t"\ - "cvtpi2pd "#offset"*4(%3,%1), %%xmm3 \n\t"\ - "mulpd %%xmm0, %%xmm2 \n\t"\ - "mulpd %%xmm1, %%xmm3 \n\t"\ - "movapd %%xmm2, (%2,%0,2) \n\t"\ - MOVPD" %%xmm3, "#offset"*8(%2,%1,2) \n\t"\ - "subpd %%xmm5, %%xmm7 \n\t"\ - "sub $8, %1 \n\t"\ - "add $8, %0 \n\t"\ - "jl 1b \n\t"\ - :"+&r"(i), "+&r"(j)\ - :"r"(w_data+n2), "r"(data+n2)\ - ); - if(len&1) - WELCH("movupd", -1) - else - WELCH("movapd", -2) -#undef WELCH -} - -void ff_lpc_compute_autocorr_sse2(const int32_t *data, int len, int lag, - double *autoc) -{ - double tmp[len + lag + 2]; - double *data1 = tmp + lag; - int j; - - if((x86_reg)data1 & 15) - data1++; - - apply_welch_window_sse2(data, len, data1); - - for(j=0; j et al - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_MATHOPS_H -#define AVCODEC_X86_MATHOPS_H - -#include "config.h" -#include "libavutil/common.h" - -#if ARCH_X86_32 -#define MULL(ra, rb, shift) \ - ({ int rt, dummy; __asm__ (\ - "imull %3 \n\t"\ - "shrdl %4, %%edx, %%eax \n\t"\ - : "=a"(rt), "=d"(dummy)\ - : "a" ((int)(ra)), "rm" ((int)(rb)), "i"(shift));\ - rt; }) - -#define MULH(ra, rb) \ - ({ int rt, dummy;\ - __asm__ ("imull %3\n\t" : "=d"(rt), "=a"(dummy): "a" ((int)(ra)), "rm" ((int)(rb)));\ - rt; }) - -#define MUL64(ra, rb) \ - ({ int64_t rt;\ - __asm__ ("imull %2\n\t" : "=A"(rt) : "a" ((int)(ra)), "g" ((int)(rb)));\ - rt; }) -#endif - -#if HAVE_CMOV -/* median of 3 */ -#define mid_pred mid_pred -static inline av_const int mid_pred(int a, int b, int c) -{ - int i=b; - __asm__ volatile( - "cmp %2, %1 \n\t" - "cmovg %1, %0 \n\t" - "cmovg %2, %1 \n\t" - "cmp %3, %1 \n\t" - "cmovl %3, %1 \n\t" - "cmp %1, %0 \n\t" - "cmovg %1, %0 \n\t" - :"+&r"(i), "+&r"(a) - :"r"(b), "r"(c) - ); - return i; -} -#endif - -#if HAVE_CMOV -#define COPY3_IF_LT(x, y, a, b, c, d)\ -__asm__ volatile(\ - "cmpl %0, %3 \n\t"\ - "cmovl %3, %0 \n\t"\ - "cmovl %4, %1 \n\t"\ - "cmovl %5, %2 \n\t"\ - : "+&r" (x), "+&r" (a), "+r" (c)\ - : "r" (y), "r" (b), "r" (d)\ -); -#endif - -// avoid +32 for shift optimization (gcc should do that ...) -#define NEG_SSR32 NEG_SSR32 -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; -} - -#define NEG_USR32 NEG_USR32 -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; -} - -#endif /* AVCODEC_X86_MATHOPS_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/mlpdsp.c b/tizen/distrib/ffmpeg/libavcodec/x86/mlpdsp.c deleted file mode 100644 index 486a927..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/mlpdsp.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * MLP DSP functions x86-optimized - * Copyright (c) 2009 Ramiro Polla - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mlp.h" - -#if HAVE_7REGS && HAVE_TEN_OPERANDS - -extern void ff_mlp_firorder_8; -extern void ff_mlp_firorder_7; -extern void ff_mlp_firorder_6; -extern void ff_mlp_firorder_5; -extern void ff_mlp_firorder_4; -extern void ff_mlp_firorder_3; -extern void ff_mlp_firorder_2; -extern void ff_mlp_firorder_1; -extern void ff_mlp_firorder_0; - -extern void ff_mlp_iirorder_4; -extern void ff_mlp_iirorder_3; -extern void ff_mlp_iirorder_2; -extern void ff_mlp_iirorder_1; -extern void ff_mlp_iirorder_0; - -static const void *firtable[9] = { &ff_mlp_firorder_0, &ff_mlp_firorder_1, - &ff_mlp_firorder_2, &ff_mlp_firorder_3, - &ff_mlp_firorder_4, &ff_mlp_firorder_5, - &ff_mlp_firorder_6, &ff_mlp_firorder_7, - &ff_mlp_firorder_8 }; -static const void *iirtable[5] = { &ff_mlp_iirorder_0, &ff_mlp_iirorder_1, - &ff_mlp_iirorder_2, &ff_mlp_iirorder_3, - &ff_mlp_iirorder_4 }; - -#if ARCH_X86_64 - -#define MLPMUL(label, offset, offs, offc) \ - LABEL_MANGLE(label)": \n\t" \ - "movslq "offset"+"offs"(%0), %%rax\n\t" \ - "movslq "offset"+"offc"(%1), %%rdx\n\t" \ - "imul %%rdx, %%rax\n\t" \ - "add %%rax, %%rsi\n\t" - -#define FIRMULREG(label, offset, firc)\ - LABEL_MANGLE(label)": \n\t" \ - "movslq "#offset"(%0), %%rax\n\t" \ - "imul %"#firc", %%rax\n\t" \ - "add %%rax, %%rsi\n\t" - -#define CLEAR_ACCUM \ - "xor %%rsi, %%rsi\n\t" - -#define SHIFT_ACCUM \ - "shr %%cl, %%rsi\n\t" - -#define ACCUM "%%rdx" -#define RESULT "%%rsi" -#define RESULT32 "%%esi" - -#else /* if ARCH_X86_32 */ - -#define MLPMUL(label, offset, offs, offc) \ - LABEL_MANGLE(label)": \n\t" \ - "mov "offset"+"offs"(%0), %%eax\n\t" \ - "imull "offset"+"offc"(%1) \n\t" \ - "add %%eax , %%esi\n\t" \ - "adc %%edx , %%ecx\n\t" - -#define FIRMULREG(label, offset, firc) \ - MLPMUL(label, #offset, "0", "0") - -#define CLEAR_ACCUM \ - "xor %%esi, %%esi\n\t" \ - "xor %%ecx, %%ecx\n\t" - -#define SHIFT_ACCUM \ - "mov %%ecx, %%edx\n\t" \ - "mov %%esi, %%eax\n\t" \ - "movzbl %7 , %%ecx\n\t" \ - "shrd %%cl, %%edx, %%eax\n\t" \ - -#define ACCUM "%%edx" -#define RESULT "%%eax" -#define RESULT32 "%%eax" - -#endif /* !ARCH_X86_64 */ - -#define BINC AV_STRINGIFY(4* MAX_CHANNELS) -#define IOFFS AV_STRINGIFY(4*(MAX_FIR_ORDER + MAX_BLOCKSIZE)) -#define IOFFC AV_STRINGIFY(4* MAX_FIR_ORDER) - -#define FIRMUL(label, offset) MLPMUL(label, #offset, "0", "0") -#define IIRMUL(label, offset) MLPMUL(label, #offset, IOFFS, IOFFC) - -static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, - int firorder, int iirorder, - unsigned int filter_shift, int32_t mask, - int blocksize, int32_t *sample_buffer) -{ - const void *firjump = firtable[firorder]; - const void *iirjump = iirtable[iirorder]; - - blocksize = -blocksize; - - __asm__ volatile( - "1: \n\t" - CLEAR_ACCUM - "jmp *%5 \n\t" - FIRMUL (ff_mlp_firorder_8, 0x1c ) - FIRMUL (ff_mlp_firorder_7, 0x18 ) - FIRMUL (ff_mlp_firorder_6, 0x14 ) - FIRMUL (ff_mlp_firorder_5, 0x10 ) - FIRMUL (ff_mlp_firorder_4, 0x0c ) - FIRMULREG(ff_mlp_firorder_3, 0x08,10) - FIRMULREG(ff_mlp_firorder_2, 0x04, 9) - FIRMULREG(ff_mlp_firorder_1, 0x00, 8) - LABEL_MANGLE(ff_mlp_firorder_0)":\n\t" - "jmp *%6 \n\t" - IIRMUL (ff_mlp_iirorder_4, 0x0c ) - IIRMUL (ff_mlp_iirorder_3, 0x08 ) - IIRMUL (ff_mlp_iirorder_2, 0x04 ) - IIRMUL (ff_mlp_iirorder_1, 0x00 ) - LABEL_MANGLE(ff_mlp_iirorder_0)":\n\t" - SHIFT_ACCUM - "mov "RESULT" ,"ACCUM" \n\t" - "add (%2) ,"RESULT" \n\t" - "and %4 ,"RESULT" \n\t" - "sub $4 , %0 \n\t" - "mov "RESULT32", (%0) \n\t" - "mov "RESULT32", (%2) \n\t" - "add $"BINC" , %2 \n\t" - "sub "ACCUM" ,"RESULT" \n\t" - "mov "RESULT32","IOFFS"(%0) \n\t" - "incl %3 \n\t" - "js 1b \n\t" - : /* 0*/"+r"(state), - /* 1*/"+r"(coeff), - /* 2*/"+r"(sample_buffer), -#if ARCH_X86_64 - /* 3*/"+r"(blocksize) - : /* 4*/"r"((x86_reg)mask), /* 5*/"r"(firjump), - /* 6*/"r"(iirjump) , /* 7*/"c"(filter_shift) - , /* 8*/"r"((int64_t)coeff[0]) - , /* 9*/"r"((int64_t)coeff[1]) - , /*10*/"r"((int64_t)coeff[2]) - : "rax", "rdx", "rsi" -#else /* ARCH_X86_32 */ - /* 3*/"+m"(blocksize) - : /* 4*/"m"( mask), /* 5*/"m"(firjump), - /* 6*/"m"(iirjump) , /* 7*/"m"(filter_shift) - : "eax", "edx", "esi", "ecx" -#endif /* !ARCH_X86_64 */ - ); -} - -#endif /* HAVE_7REGS && HAVE_TEN_OPERANDS */ - -void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx) -{ -#if HAVE_7REGS && HAVE_TEN_OPERANDS - c->mlp_filter_channel = mlp_filter_channel_x86; -#endif -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/mmx.h b/tizen/distrib/ffmpeg/libavcodec/x86/mmx.h deleted file mode 100644 index d7a76bb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/mmx.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * mmx.h - * Copyright (C) 1997-2001 H. Dietz and R. Fisher - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVCODEC_X86_MMX_H -#define AVCODEC_X86_MMX_H - -#warning Everything in this header is deprecated, use plain __asm__()! New code using this header will be rejected. - - -#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 */ \ - : "m" (mem), "i" (imm)) -#define mmx_r2ri(op,regs,regd,imm) \ - __asm__ volatile (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "i" (imm) ) - -#define mmx_fetch(mem,hint) \ - __asm__ volatile ("prefetch" #hint " %0" \ - : /* nothing */ \ - : "m" (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_X86_MMX_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/motion_est_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/motion_est_mmx.c deleted file mode 100644 index 0272410..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/motion_est_mmx.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * MMX optimized motion estimation - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002-2004 Michael Niedermayer - * - * mostly by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "dsputil_mmx.h" - -DECLARE_ASM_CONST(8, uint64_t, round_tab)[3]={ -0x0000000000000000ULL, -0x0001000100010001ULL, -0x0002000200020002ULL, -}; - -DECLARE_ASM_CONST(8, uint64_t, bone)= 0x0101010101010101LL; - -static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - x86_reg len= -(stride*h); - __asm__ volatile( - ASMALIGN(4) - "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" ((x86_reg)stride) - ); -} - -static inline void sad8_1_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - __asm__ volatile( - ASMALIGN(4) - "1: \n\t" - "movq (%1), %%mm0 \n\t" - "movq (%1, %3), %%mm1 \n\t" - "psadbw (%2), %%mm0 \n\t" - "psadbw (%2, %3), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - "paddw %%mm1, %%mm6 \n\t" - "lea (%1,%3,2), %1 \n\t" - "lea (%2,%3,2), %2 \n\t" - "sub $2, %0 \n\t" - " jg 1b \n\t" - : "+r" (h), "+r" (blk1), "+r" (blk2) - : "r" ((x86_reg)stride) - ); -} - -static int sad16_sse2(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h) -{ - int ret; - __asm__ volatile( - "pxor %%xmm6, %%xmm6 \n\t" - ASMALIGN(4) - "1: \n\t" - "movdqu (%1), %%xmm0 \n\t" - "movdqu (%1, %3), %%xmm1 \n\t" - "psadbw (%2), %%xmm0 \n\t" - "psadbw (%2, %3), %%xmm1 \n\t" - "paddw %%xmm0, %%xmm6 \n\t" - "paddw %%xmm1, %%xmm6 \n\t" - "lea (%1,%3,2), %1 \n\t" - "lea (%2,%3,2), %2 \n\t" - "sub $2, %0 \n\t" - " jg 1b \n\t" - : "+r" (h), "+r" (blk1), "+r" (blk2) - : "r" ((x86_reg)stride) - ); - __asm__ volatile( - "movhlps %%xmm6, %%xmm0 \n\t" - "paddw %%xmm0, %%xmm6 \n\t" - "movd %%xmm6, %0 \n\t" - : "=r"(ret) - ); - return ret; -} - -static inline void sad8_x2a_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - __asm__ volatile( - ASMALIGN(4) - "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" - "psadbw (%2), %%mm0 \n\t" - "psadbw (%2, %3), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - "paddw %%mm1, %%mm6 \n\t" - "lea (%1,%3,2), %1 \n\t" - "lea (%2,%3,2), %2 \n\t" - "sub $2, %0 \n\t" - " jg 1b \n\t" - : "+r" (h), "+r" (blk1), "+r" (blk2) - : "r" ((x86_reg)stride) - ); -} - -static inline void sad8_y2a_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - __asm__ volatile( - "movq (%1), %%mm0 \n\t" - "add %3, %1 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%1), %%mm1 \n\t" - "movq (%1, %3), %%mm2 \n\t" - "pavgb %%mm1, %%mm0 \n\t" - "pavgb %%mm2, %%mm1 \n\t" - "psadbw (%2), %%mm0 \n\t" - "psadbw (%2, %3), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - "paddw %%mm1, %%mm6 \n\t" - "movq %%mm2, %%mm0 \n\t" - "lea (%1,%3,2), %1 \n\t" - "lea (%2,%3,2), %2 \n\t" - "sub $2, %0 \n\t" - " jg 1b \n\t" - : "+r" (h), "+r" (blk1), "+r" (blk2) - : "r" ((x86_reg)stride) - ); -} - -static inline void sad8_4_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - __asm__ volatile( - "movq "MANGLE(bone)", %%mm5 \n\t" - "movq (%1), %%mm0 \n\t" - "pavgb 1(%1), %%mm0 \n\t" - "add %3, %1 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%1), %%mm1 \n\t" - "movq (%1,%3), %%mm2 \n\t" - "pavgb 1(%1), %%mm1 \n\t" - "pavgb 1(%1,%3), %%mm2 \n\t" - "psubusb %%mm5, %%mm1 \n\t" - "pavgb %%mm1, %%mm0 \n\t" - "pavgb %%mm2, %%mm1 \n\t" - "psadbw (%2), %%mm0 \n\t" - "psadbw (%2,%3), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - "paddw %%mm1, %%mm6 \n\t" - "movq %%mm2, %%mm0 \n\t" - "lea (%1,%3,2), %1 \n\t" - "lea (%2,%3,2), %2 \n\t" - "sub $2, %0 \n\t" - " jg 1b \n\t" - : "+r" (h), "+r" (blk1), "+r" (blk2) - : "r" ((x86_reg)stride) - ); -} - -static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h) -{ - x86_reg len= -(stride*h); - __asm__ volatile( - ASMALIGN(4) - "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" ((x86_reg)stride) - ); -} - -static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - x86_reg len= -(stride*h); - __asm__ volatile( - "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" - "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" - ASMALIGN(4) - "1: \n\t" - "movq (%2, %%"REG_a"), %%mm2 \n\t" - "movq 1(%2, %%"REG_a"), %%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 %%mm5, %%mm3 \n\t" - "movq 16+"MANGLE(round_tab)", %%mm5 \n\t" - "paddw %%mm2, %%mm0 \n\t" - "paddw %%mm3, %%mm1 \n\t" - "paddw %%mm5, %%mm0 \n\t" - "paddw %%mm5, %%mm1 \n\t" - "movq (%3, %%"REG_a"), %%mm4 \n\t" - "movq (%3, %%"REG_a"), %%mm5 \n\t" - "psrlw $2, %%mm0 \n\t" - "psrlw $2, %%mm1 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "psubusb %%mm0, %%mm4 \n\t" - "psubusb %%mm5, %%mm0 \n\t" - "por %%mm4, %%mm0 \n\t" - "movq %%mm0, %%mm4 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpckhbw %%mm7, %%mm4 \n\t" - "paddw %%mm0, %%mm6 \n\t" - "paddw %%mm4, %%mm6 \n\t" - "movq %%mm2, %%mm0 \n\t" - "movq %%mm3, %%mm1 \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" ((x86_reg)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; -} - -static inline void sad8_x2a_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - sad8_2_mmx(blk1, blk1+1, blk2, stride, h); -} -static inline void sad8_y2a_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ - sad8_2_mmx(blk1, blk1+stride, blk2, stride, h); -} - - -#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_x2a_ ## suf(blk1, 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_y2a_ ## suf(blk1, 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"\ - ::);\ -\ - 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_x2a_ ## suf(blk1 , blk2 , stride, h);\ - sad8_x2a_ ## suf(blk1+8, 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_y2a_ ## suf(blk1 , blk2 , stride, h);\ - sad8_y2a_ ## suf(blk1+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"\ - ::);\ -\ - 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 & FF_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 & FF_MM_MMX2) { - 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; - } - } - if ((mm_flags & FF_MM_SSE2) && !(mm_flags & FF_MM_3DNOW) && avctx->codec_id != CODEC_ID_SNOW) { - c->sad[0]= sad16_sse2; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx.c deleted file mode 100644 index 5deb68d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * The simplest mpeg encoder (well, it was the simplest!) - * Copyright (c) 2000,2001 Fabrice Bellard - * - * Optimized for ia32 CPUs by Nick Kurshev - * h263, mpeg1, mpeg2 dequantizer & draw_edges by Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" -#include "libavcodec/mpegvideo.h" -#include "dsputil_mmx.h" - -extern uint16_t inv_zigzag_direct16[64]; - - -static void dct_unquantize_h263_intra_mmx(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - x86_reg 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" - ASMALIGN(4) - "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), "rm"(qmul), "rm" (qadd), "r" (2*(-nCoeffs)) - : "memory" - ); - block[0]= level; -} - - -static void dct_unquantize_h263_inter_mmx(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - x86_reg 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" - ASMALIGN(4) - "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), "rm"(qmul), "rm" (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 greater than 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) -{ - x86_reg 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" - ASMALIGN(4) - "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), "rm" (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) -{ - x86_reg 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" - ASMALIGN(4) - "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), "rm" (qscale), "g" (-2*nCoeffs) - : "%"REG_a, "memory" - ); -} - -static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - x86_reg 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" - ASMALIGN(4) - "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), "rm" (qscale), "g" (-2*nCoeffs) - : "%"REG_a, "memory" - ); - block[0]= block0; - //Note, we do not do mismatch control for intra as errors cannot accumulate -} - -static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s, - DCTELEM *block, int n, int qscale) -{ - x86_reg 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" - ASMALIGN(4) - "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), "rm" (qscale), "r" (-2*nCoeffs) - : "%"REG_a, "memory" - ); -} - -static void denoise_dct_mmx(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 %%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) - ); -} - -#if HAVE_SSSE3 -#define HAVE_SSSE3_BAK -#endif -#undef HAVE_SSSE3 -#define HAVE_SSSE3 0 - -#undef HAVE_SSE2 -#undef HAVE_MMX2 -#define HAVE_SSE2 0 -#define HAVE_MMX2 0 -#define RENAME(a) a ## _MMX -#define RENAMEl(a) a ## _mmx -#include "mpegvideo_mmx_template.c" - -#undef HAVE_MMX2 -#define HAVE_MMX2 1 -#undef RENAME -#undef RENAMEl -#define RENAME(a) a ## _MMX2 -#define RENAMEl(a) a ## _mmx2 -#include "mpegvideo_mmx_template.c" - -#undef HAVE_SSE2 -#define HAVE_SSE2 1 -#undef RENAME -#undef RENAMEl -#define RENAME(a) a ## _SSE2 -#define RENAMEl(a) a ## _sse2 -#include "mpegvideo_mmx_template.c" - -#ifdef HAVE_SSSE3_BAK -#undef HAVE_SSSE3 -#define HAVE_SSSE3 1 -#undef RENAME -#undef RENAMEl -#define RENAME(a) a ## _SSSE3 -#define RENAMEl(a) a ## _sse2 -#include "mpegvideo_mmx_template.c" -#endif - -void MPV_common_init_mmx(MpegEncContext *s) -{ - if (mm_flags & FF_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; - if(!(s->flags & CODEC_FLAG_BITEXACT)) - s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx; - s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx; - - if (mm_flags & FF_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 HAVE_SSSE3 - if(mm_flags & FF_MM_SSSE3){ - s->dct_quantize= dct_quantize_SSSE3; - } else -#endif - if(mm_flags & FF_MM_SSE2){ - s->dct_quantize= dct_quantize_SSE2; - } else if(mm_flags & FF_MM_MMX2){ - s->dct_quantize= dct_quantize_MMX2; - } else { - s->dct_quantize= dct_quantize_MMX; - } - } - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx_template.c b/tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx_template.c deleted file mode 100644 index 0d92792..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/mpegvideo_mmx_template.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * MPEG video MMX templates - * - * Copyright (c) 2002 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#undef MMREG_WIDTH -#undef MM -#undef MOVQ -#undef SPREADW -#undef PMAXW -#undef PMAX -#undef SAVE_SIGN -#undef RESTORE_SIGN - -#if HAVE_SSE2 -#define MMREG_WIDTH "16" -#define MM "%%xmm" -#define MOVQ "movdqa" -#define SPREADW(a) \ - "pshuflw $0, "a", "a" \n\t"\ - "punpcklwd "a", "a" \n\t" -#define PMAXW(a,b) "pmaxsw "a", "b" \n\t" -#define PMAX(a,b) \ - "movhlps "a", "b" \n\t"\ - PMAXW(b, a)\ - "pshuflw $0x0E, "a", "b" \n\t"\ - PMAXW(b, a)\ - "pshuflw $0x01, "a", "b" \n\t"\ - PMAXW(b, a) -#else -#define MMREG_WIDTH "8" -#define MM "%%mm" -#define MOVQ "movq" -#if 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 -#endif - -#if HAVE_SSSE3 -#define SAVE_SIGN(a,b) \ - "movdqa "b", "a" \n\t"\ - "pabsw "b", "b" \n\t" -#define RESTORE_SIGN(a,b) \ - "psignw "a", "b" \n\t" -#else -#define SAVE_SIGN(a,b) \ - "pxor "a", "a" \n\t"\ - "pcmpgtw "b", "a" \n\t" /* block[i] <= 0 ? 0xFF : 0x00 */\ - "pxor "a", "b" \n\t"\ - "psubw "a", "b" \n\t" /* ABS(block[i]) */ -#define RESTORE_SIGN(a,b) \ - "pxor "a", "b" \n\t"\ - "psubw "a", "b" \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) -#endif - -static int RENAME(dct_quantize)(MpegEncContext *s, - DCTELEM *block, int n, - int qscale, int *overflow) -{ - x86_reg last_non_zero_p1; - int level=0, q; //=0 is because gcc says uninitialized ... - const uint16_t *qmat, *bias; - DECLARE_ALIGNED(16, int16_t, temp_block)[64]; - - assert((7&(int)(&temp_block[0])) == 0); //did gcc align it correctly? - - //s->fdct (block); - RENAMEl(ff_fdct) (block); //cannot 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" (ff_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", "MM"3 \n\t" // last_non_zero_p1 - SPREADW(MM"3") - "pxor "MM"7, "MM"7 \n\t" // 0 - "pxor "MM"4, "MM"4 \n\t" // 0 - MOVQ" (%2), "MM"5 \n\t" // qmat[0] - "pxor "MM"6, "MM"6 \n\t" - "psubw (%3), "MM"6 \n\t" // -bias[0] - "mov $-128, %%"REG_a" \n\t" - ASMALIGN(4) - "1: \n\t" - MOVQ" (%1, %%"REG_a"), "MM"0 \n\t" // block[i] - SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) - "psubusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] - "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16 - "por "MM"0, "MM"4 \n\t" - RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) - MOVQ" "MM"0, (%5, %%"REG_a") \n\t" - "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 - MOVQ" (%4, %%"REG_a"), "MM"1 \n\t" - MOVQ" "MM"7, (%1, %%"REG_a") \n\t" // 0 - "pandn "MM"1, "MM"0 \n\t" - PMAXW(MM"0", MM"3") - "add $"MMREG_WIDTH", %%"REG_a" \n\t" - " js 1b \n\t" - PMAX(MM"3", MM"0") - "movd "MM"3, %%"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) - ); - }else{ // FMT_H263 - __asm__ volatile( - "movd %%"REG_a", "MM"3 \n\t" // last_non_zero_p1 - SPREADW(MM"3") - "pxor "MM"7, "MM"7 \n\t" // 0 - "pxor "MM"4, "MM"4 \n\t" // 0 - "mov $-128, %%"REG_a" \n\t" - ASMALIGN(4) - "1: \n\t" - MOVQ" (%1, %%"REG_a"), "MM"0 \n\t" // block[i] - SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) - MOVQ" (%3, %%"REG_a"), "MM"6 \n\t" // bias[0] - "paddusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] - MOVQ" (%2, %%"REG_a"), "MM"5 \n\t" // qmat[i] - "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16 - "por "MM"0, "MM"4 \n\t" - RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) - MOVQ" "MM"0, (%5, %%"REG_a") \n\t" - "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 - MOVQ" (%4, %%"REG_a"), "MM"1 \n\t" - MOVQ" "MM"7, (%1, %%"REG_a") \n\t" // 0 - "pandn "MM"1, "MM"0 \n\t" - PMAXW(MM"0", MM"3") - "add $"MMREG_WIDTH", %%"REG_a" \n\t" - " js 1b \n\t" - PMAX(MM"3", MM"0") - "movd "MM"3, %%"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) - ); - } - __asm__ volatile( - "movd %1, "MM"1 \n\t" // max_qcoeff - SPREADW(MM"1") - "psubusw "MM"1, "MM"4 \n\t" - "packuswb "MM"4, "MM"4 \n\t" -#if HAVE_SSE2 - "packuswb "MM"4, "MM"4 \n\t" -#endif - "movd "MM"4, %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>1][x&(~1)]); -} -static void put_rv40_chroma_mc4_mmx(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - put_h264_chroma_generic_mc4_mmx(dst, src, stride, h, x, y, &rv40_bias_reg[y>>1][x&(~1)]); -} -static void avg_rv40_chroma_mc8_mmx2(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc8_mmx2(dst, src, stride, h, x, y, &rv40_bias_reg[y>>1][x&(~1)]); -} -static void avg_rv40_chroma_mc4_mmx2(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc4_mmx2(dst, src, stride, h, x, y, &rv40_bias_reg[y>>1][x&(~1)]); -} -static void avg_rv40_chroma_mc8_3dnow(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc8_3dnow(dst, src, stride, h, x, y, &rv40_bias_reg[y>>1][x&(~1)]); -} -static void avg_rv40_chroma_mc4_3dnow(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) -{ - avg_h264_chroma_generic_mc4_3dnow(dst, src, stride, h, x, y, &rv40_bias_reg[y>>1][x&(~1)]); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/simple_idct_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/simple_idct_mmx.c deleted file mode 100644 index 5ea4c84..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/simple_idct_mmx.c +++ /dev/null @@ -1,1296 +0,0 @@ -/* - * Simple IDCT MMX - * - * Copyright (c) 2001, 2002 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "libavcodec/dsputil.h" -#include "libavcodec/simple_idct.h" -#include "dsputil_mmx.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 - -DECLARE_ASM_CONST(8, uint64_t, wm1010)= 0xFFFF0000FFFF0000ULL; -DECLARE_ASM_CONST(8, uint64_t, d40000)= 0x0000000000040000ULL; - -DECLARE_ALIGNED(8, static const int16_t, 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) -{ - DECLARE_ALIGNED(8, int64_t, 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, 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 %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "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, shift) -COL_IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -COL_IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -COL_IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -COL_IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 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, 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 %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "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, shift) -IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - "jmp 9f \n\t" - - "#" ASMALIGN(4) \ - "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, 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 */\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "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, shift) -IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - "jmp 9f \n\t" - - "#" ASMALIGN(4) \ - "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, 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 */\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "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, shift) -IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - "jmp 9f \n\t" - - "#" ASMALIGN(4) \ - "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, 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 */\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "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, shift) -IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - "jmp 9f \n\t" - - "#" ASMALIGN(4) \ - "3: \n\t" -#undef IDCT -#define IDCT(src0, src4, src1, src5, dst, 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 */\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "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, shift) -IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - "jmp 9f \n\t" - - "#" ASMALIGN(4) \ - "5: \n\t" -#undef IDCT -#define IDCT(src0, src4, src1, src5, dst, 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 */\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "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 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 */\ - "paddd %%mm1, %%mm7 \n\t" /* A0 a0 */\ - "paddd %%mm1, %%mm1 \n\t" /* 2C0 2c0 */\ - "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, shift) -IDCT( 0(%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -//IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -//IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - "jmp 9f \n\t" - - - "#" ASMALIGN(4) \ - "1: \n\t" -#undef IDCT -#define IDCT(src0, src4, src1, src5, dst, 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 */\ - "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ - "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ - "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, shift) -IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20) - "jmp 9f \n\t" - - - "#" ASMALIGN(4) - "7: \n\t" -#undef IDCT -#define IDCT(src0, src4, src1, src5, dst, 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 */\ - "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 */\ - "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, shift) -IDCT( 0(%1), 64(%1), 32(%1), 96(%1), 0(%0), 20) -//IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0), 20) -IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0), 20) -//IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 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/tizen/distrib/ffmpeg/libavcodec/x86/snowdsp_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/snowdsp_mmx.c deleted file mode 100644 index 263f0bb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/snowdsp_mmx.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * MMX and SSE2 optimized snow DSP utils - * Copyright (c) 2005-2006 Robert Edele - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/snow.h" -#include "libavcodec/dwt.h" -#include "dsputil_mmx.h" - -static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, int width){ - const int w2= (width+1)>>1; - DECLARE_ALIGNED(16, IDWTELEM, temp)[width>>1]; - const int w_l= (width>>1); - const int w_r= w2 - 1; - int i; - - { // Lift 0 - IDWTELEM * const ref = b + w2 - 1; - IDWTELEM 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" - "pcmpeqd %%xmm3, %%xmm3 \n\t" - "psllw $1, %%xmm3 \n\t" - "paddw %%xmm7, %%xmm3 \n\t" - "psllw $13, %%xmm3 \n\t" - ::); - for(; i>W_DS); - } - - { // Lift 1 - IDWTELEM * const dst = b+w2; - - i = 0; - for(; (((x86_reg)&dst[i]) & 0x1F) && i> W_BS); - } - - { // Lift 3 - IDWTELEM * const src = b+w2; - - i = 0; - for(; (((x86_reg)&temp[i]) & 0x1F) && i>W_AS); - } - for(; i>1]; - b[i] = b[i>>1]; - } - for (i-=62; i>=0; i-=64){ - __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" - "punpcklwd (%2), %%xmm0 \n\t" - "punpcklwd 16(%2), %%xmm2 \n\t" - "punpcklwd 32(%2), %%xmm4 \n\t" - "punpcklwd 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" - "punpckhwd (%2), %%xmm1 \n\t" - "punpckhwd 16(%2), %%xmm3 \n\t" - "punpckhwd 32(%2), %%xmm5 \n\t" - "punpckhwd 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" - ); - } - } -} - -static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, int width){ - const int w2= (width+1)>>1; - IDWTELEM temp[width >> 1]; - const int w_l= (width>>1); - const int w_r= w2 - 1; - int i; - - { // Lift 0 - IDWTELEM * const ref = b + w2 - 1; - - i = 1; - b[0] = b[0] - ((W_DM * 2 * ref[1]+W_DO)>>W_DS); - __asm__ volatile( - "pcmpeqw %%mm7, %%mm7 \n\t" - "pcmpeqw %%mm3, %%mm3 \n\t" - "psllw $1, %%mm3 \n\t" - "paddw %%mm7, %%mm3 \n\t" - "psllw $13, %%mm3 \n\t" - ::); - for(; i> W_BS); - __asm__ volatile( - "psllw $15, %%mm7 \n\t" - "pcmpeqw %%mm6, %%mm6 \n\t" - "psrlw $13, %%mm6 \n\t" - "paddw %%mm7, %%mm6 \n\t" - ::); - for(; i>1]; - b[i] = b[i>>1]; - } - for (i-=30; i>=0; i-=32){ - __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" - "punpcklwd (%2), %%mm0 \n\t" - "punpcklwd 8(%2), %%mm2 \n\t" - "punpcklwd 16(%2), %%mm4 \n\t" - "punpcklwd 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" - "punpckhwd (%2), %%mm1 \n\t" - "punpckhwd 8(%2), %%mm3 \n\t" - "punpckhwd 16(%2), %%mm5 \n\t" - "punpckhwd 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" - ); - } - } -} - -#if HAVE_7REGS -#define snow_vertical_compose_sse2_load_add(op,r,t0,t1,t2,t3)\ - ""op" ("r",%%"REG_d"), %%"t0" \n\t"\ - ""op" 16("r",%%"REG_d"), %%"t1" \n\t"\ - ""op" 32("r",%%"REG_d"), %%"t2" \n\t"\ - ""op" 48("r",%%"REG_d"), %%"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("paddw",r,t0,t1,t2,t3) - -#define snow_vertical_compose_r2r_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ - "psubw %%"s0", %%"t0" \n\t"\ - "psubw %%"s1", %%"t1" \n\t"\ - "psubw %%"s2", %%"t2" \n\t"\ - "psubw %%"s3", %%"t3" \n\t" - -#define snow_vertical_compose_sse2_store(w,s0,s1,s2,s3)\ - "movdqa %%"s0", ("w",%%"REG_d") \n\t"\ - "movdqa %%"s1", 16("w",%%"REG_d") \n\t"\ - "movdqa %%"s2", 32("w",%%"REG_d") \n\t"\ - "movdqa %%"s3", 48("w",%%"REG_d") \n\t" - -#define snow_vertical_compose_sra(n,t0,t1,t2,t3)\ - "psraw $"n", %%"t0" \n\t"\ - "psraw $"n", %%"t1" \n\t"\ - "psraw $"n", %%"t2" \n\t"\ - "psraw $"n", %%"t3" \n\t" - -#define snow_vertical_compose_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ - "paddw %%"s0", %%"t0" \n\t"\ - "paddw %%"s1", %%"t1" \n\t"\ - "paddw %%"s2", %%"t2" \n\t"\ - "paddw %%"s3", %%"t3" \n\t" - -#define snow_vertical_compose_r2r_pmulhw(s0,s1,s2,s3,t0,t1,t2,t3)\ - "pmulhw %%"s0", %%"t0" \n\t"\ - "pmulhw %%"s1", %%"t1" \n\t"\ - "pmulhw %%"s2", %%"t2" \n\t"\ - "pmulhw %%"s3", %%"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" - -static void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ - x86_reg i = width; - - while(i & 0x1F) - { - 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; - } - i+=i; - - __asm__ volatile ( - "jmp 2f \n\t" - "1: \n\t" - snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add("%6","xmm0","xmm2","xmm4","xmm6") - - - "pcmpeqw %%xmm0, %%xmm0 \n\t" - "pcmpeqw %%xmm2, %%xmm2 \n\t" - "paddw %%xmm2, %%xmm2 \n\t" - "paddw %%xmm0, %%xmm2 \n\t" - "psllw $13, %%xmm2 \n\t" - snow_vertical_compose_r2r_add("xmm0","xmm0","xmm0","xmm0","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_r2r_pmulhw("xmm2","xmm2","xmm2","xmm2","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_add("%5","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_store("%5","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add("%3","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_r2r_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_store("%4","xmm0","xmm2","xmm4","xmm6") - - "pcmpeqw %%xmm7, %%xmm7 \n\t" - "pcmpeqw %%xmm5, %%xmm5 \n\t" - "psllw $15, %%xmm7 \n\t" - "psrlw $13, %%xmm5 \n\t" - "paddw %%xmm7, %%xmm5 \n\t" - snow_vertical_compose_r2r_add("xmm5","xmm5","xmm5","xmm5","xmm0","xmm2","xmm4","xmm6") - "movq (%2,%%"REG_d"), %%xmm1 \n\t" - "movq 8(%2,%%"REG_d"), %%xmm3 \n\t" - "paddw %%xmm7, %%xmm1 \n\t" - "paddw %%xmm7, %%xmm3 \n\t" - "pavgw %%xmm1, %%xmm0 \n\t" - "pavgw %%xmm3, %%xmm2 \n\t" - "movq 16(%2,%%"REG_d"), %%xmm1 \n\t" - "movq 24(%2,%%"REG_d"), %%xmm3 \n\t" - "paddw %%xmm7, %%xmm1 \n\t" - "paddw %%xmm7, %%xmm3 \n\t" - "pavgw %%xmm1, %%xmm4 \n\t" - "pavgw %%xmm3, %%xmm6 \n\t" - snow_vertical_compose_r2r_sub("xmm7","xmm7","xmm7","xmm7","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") - - snow_vertical_compose_sra("2","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_store("%3","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add("%1","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add("%2","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_store("%2","xmm0","xmm2","xmm4","xmm6") - - "2: \n\t" - "sub $64, %%"REG_d" \n\t" - "jge 1b \n\t" - :"+d"(i) - :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); -} - -#define snow_vertical_compose_mmx_load_add(op,r,t0,t1,t2,t3)\ - ""op" ("r",%%"REG_d"), %%"t0" \n\t"\ - ""op" 8("r",%%"REG_d"), %%"t1" \n\t"\ - ""op" 16("r",%%"REG_d"), %%"t2" \n\t"\ - ""op" 24("r",%%"REG_d"), %%"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("paddw",r,t0,t1,t2,t3) - -#define snow_vertical_compose_mmx_store(w,s0,s1,s2,s3)\ - "movq %%"s0", ("w",%%"REG_d") \n\t"\ - "movq %%"s1", 8("w",%%"REG_d") \n\t"\ - "movq %%"s2", 16("w",%%"REG_d") \n\t"\ - "movq %%"s3", 24("w",%%"REG_d") \n\t" - -#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" - - -static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ - x86_reg i = width; - while(i & 15) - { - 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; - } - i+=i; - __asm__ volatile( - "jmp 2f \n\t" - "1: \n\t" - - snow_vertical_compose_mmx_load("%4","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_add("%6","mm1","mm3","mm5","mm7") - "pcmpeqw %%mm0, %%mm0 \n\t" - "pcmpeqw %%mm2, %%mm2 \n\t" - "paddw %%mm2, %%mm2 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "psllw $13, %%mm2 \n\t" - snow_vertical_compose_r2r_add("mm0","mm0","mm0","mm0","mm1","mm3","mm5","mm7") - snow_vertical_compose_r2r_pmulhw("mm2","mm2","mm2","mm2","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_add("%5","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_store("%5","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_load("%4","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add("%3","mm1","mm3","mm5","mm7") - snow_vertical_compose_r2r_sub("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_store("%4","mm0","mm2","mm4","mm6") - "pcmpeqw %%mm7, %%mm7 \n\t" - "pcmpeqw %%mm5, %%mm5 \n\t" - "psllw $15, %%mm7 \n\t" - "psrlw $13, %%mm5 \n\t" - "paddw %%mm7, %%mm5 \n\t" - snow_vertical_compose_r2r_add("mm5","mm5","mm5","mm5","mm0","mm2","mm4","mm6") - "movq (%2,%%"REG_d"), %%mm1 \n\t" - "movq 8(%2,%%"REG_d"), %%mm3 \n\t" - "paddw %%mm7, %%mm1 \n\t" - "paddw %%mm7, %%mm3 \n\t" - "pavgw %%mm1, %%mm0 \n\t" - "pavgw %%mm3, %%mm2 \n\t" - "movq 16(%2,%%"REG_d"), %%mm1 \n\t" - "movq 24(%2,%%"REG_d"), %%mm3 \n\t" - "paddw %%mm7, %%mm1 \n\t" - "paddw %%mm7, %%mm3 \n\t" - "pavgw %%mm1, %%mm4 \n\t" - "pavgw %%mm3, %%mm6 \n\t" - snow_vertical_compose_r2r_sub("mm7","mm7","mm7","mm7","mm0","mm2","mm4","mm6") - snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") - - snow_vertical_compose_sra("2","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_store("%3","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add("%1","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") - snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") - snow_vertical_compose_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add("%2","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_store("%2","mm0","mm2","mm4","mm6") - - "2: \n\t" - "sub $32, %%"REG_d" \n\t" - "jge 1b \n\t" - :"+d"(i) - :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); -} -#endif //HAVE_7REGS - -#define snow_inner_add_yblock_sse2_header \ - IDWTELEM * * dst_array = sb->line + src_y;\ - x86_reg tmp;\ - __asm__ volatile(\ - "mov %7, %%"REG_c" \n\t"\ - "mov %6, %2 \n\t"\ - "mov %4, %%"REG_S" \n\t"\ - "pxor %%xmm7, %%xmm7 \n\t" /* 0 */\ - "pcmpeqd %%xmm3, %%xmm3 \n\t"\ - "psllw $15, %%xmm3 \n\t"\ - "psrlw $12, %%xmm3 \n\t" /* FRAC_BITS >> 1 */\ - "1: \n\t"\ - "mov %1, %%"REG_D" \n\t"\ - "mov (%%"REG_D"), %%"REG_D" \n\t"\ - "add %3, %%"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),"=&r"(tmp)\ - :\ - "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\ - "%"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, %2 \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 %2 \n\t"\ - snow_inner_add_yblock_sse2_end_common2 - -static void inner_add_yblock_bw_8_obmc_16_bh_even_sse2(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, - int src_x, int src_y, x86_reg 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 %3, %%"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(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, - int src_x, int src_y, x86_reg 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" - "psrlw $4, %%xmm1 \n\t" - "psrlw $4, %%xmm5 \n\t" - "paddw (%%"REG_D"), %%xmm1 \n\t" - "paddw 16(%%"REG_D"), %%xmm5 \n\t" - "paddw %%xmm3, %%xmm1 \n\t" - "paddw %%xmm3, %%xmm5 \n\t" - "psraw $4, %%xmm1 \n\t" /* FRAC_BITS. */ - "psraw $4, %%xmm5 \n\t" /* FRAC_BITS. */ - "packuswb %%xmm5, %%xmm1 \n\t" - - "movdqu %%xmm1, (%%"REG_d") \n\t" - -snow_inner_add_yblock_sse2_end_16 -} - -#define snow_inner_add_yblock_mmx_header \ - IDWTELEM * * dst_array = sb->line + src_y;\ - x86_reg tmp;\ - __asm__ volatile(\ - "mov %7, %%"REG_c" \n\t"\ - "mov %6, %2 \n\t"\ - "mov %4, %%"REG_S" \n\t"\ - "pxor %%mm7, %%mm7 \n\t" /* 0 */\ - "pcmpeqd %%mm3, %%mm3 \n\t"\ - "psllw $15, %%mm3 \n\t"\ - "psrlw $12, %%mm3 \n\t" /* FRAC_BITS >> 1 */\ - "1: \n\t"\ - "mov %1, %%"REG_D" \n\t"\ - "mov (%%"REG_D"), %%"REG_D" \n\t"\ - "add %3, %%"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"\ - "psrlw $4, %%mm1 \n\t"\ - "psrlw $4, %%mm5 \n\t"\ - "paddw "read_offset"(%%"REG_D"), %%mm1 \n\t"\ - "paddw "read_offset"+8(%%"REG_D"), %%mm5 \n\t"\ - "paddw %%mm3, %%mm1 \n\t"\ - "paddw %%mm3, %%mm5 \n\t"\ - "psraw $4, %%mm1 \n\t"\ - "psraw $4, %%mm5 \n\t"\ - "packuswb %%mm5, %%mm1 \n\t"\ - "movq %%mm1, "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 %2 \n\t"\ - "jnz 1b \n\t"\ - :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\ - :\ - "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\ - "%"REG_c"","%"REG_S"","%"REG_D"","%"REG_d""); - -static void inner_add_yblock_bw_8_obmc_16_mmx(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, - int src_x, int src_y, x86_reg 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(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, - int src_x, int src_y, x86_reg 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("16", "8") -snow_inner_add_yblock_mmx_end("32") -} - -static void ff_snow_inner_add_yblock_sse2(const 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); -} - -static void ff_snow_inner_add_yblock_mmx(const 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); -} - -void ff_dwt_init_x86(DWTContext *c) -{ - mm_flags = mm_support(); - - if (mm_flags & FF_MM_MMX) { - if(mm_flags & FF_MM_SSE2 & 0){ - c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2; -#if HAVE_7REGS - c->vertical_compose97i = ff_snow_vertical_compose97i_sse2; -#endif - c->inner_add_yblock = ff_snow_inner_add_yblock_sse2; - } - else{ - if(mm_flags & FF_MM_MMX2){ - c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx; -#if HAVE_7REGS - c->vertical_compose97i = ff_snow_vertical_compose97i_mmx; -#endif - } - c->inner_add_yblock = ff_snow_inner_add_yblock_mmx; - } - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vc1dsp_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/vc1dsp_mmx.c deleted file mode 100644 index e0b1f5b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vc1dsp_mmx.c +++ /dev/null @@ -1,741 +0,0 @@ -/* - * VC-1 and WMV3 - DSP functions MMX-optimized - * Copyright (c) 2007 Christophe GISQUET - * - * 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 AUTHORS OR 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. - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "dsputil_mmx.h" - -#define OP_PUT(S,D) -#define OP_AVG(S,D) "pavgb " #S ", " #D " \n\t" - -/** Add rounder from mm7 to mm3 and pack result at destination */ -#define NORMALIZE_MMX(SHIFT) \ - "paddw %%mm7, %%mm3 \n\t" /* +bias-r */ \ - "paddw %%mm7, %%mm4 \n\t" /* +bias-r */ \ - "psraw "SHIFT", %%mm3 \n\t" \ - "psraw "SHIFT", %%mm4 \n\t" - -#define TRANSFER_DO_PACK(OP) \ - "packuswb %%mm4, %%mm3 \n\t" \ - OP((%2), %%mm3) \ - "movq %%mm3, (%2) \n\t" - -#define TRANSFER_DONT_PACK(OP) \ - OP(0(%2), %%mm3) \ - OP(8(%2), %%mm4) \ - "movq %%mm3, 0(%2) \n\t" \ - "movq %%mm4, 8(%2) \n\t" - -/** @see MSPEL_FILTER13_CORE for use as UNPACK macro */ -#define DO_UNPACK(reg) "punpcklbw %%mm0, " reg "\n\t" -#define DONT_UNPACK(reg) - -/** Compute the rounder 32-r or 8-r and unpacks it to mm7 */ -#define LOAD_ROUNDER_MMX(ROUND) \ - "movd "ROUND", %%mm7 \n\t" \ - "punpcklwd %%mm7, %%mm7 \n\t" \ - "punpckldq %%mm7, %%mm7 \n\t" - -#define SHIFT2_LINE(OFF, R0,R1,R2,R3) \ - "paddw %%mm"#R2", %%mm"#R1" \n\t" \ - "movd (%0,%3), %%mm"#R0" \n\t" \ - "pmullw %%mm6, %%mm"#R1" \n\t" \ - "punpcklbw %%mm0, %%mm"#R0" \n\t" \ - "movd (%0,%2), %%mm"#R3" \n\t" \ - "psubw %%mm"#R0", %%mm"#R1" \n\t" \ - "punpcklbw %%mm0, %%mm"#R3" \n\t" \ - "paddw %%mm7, %%mm"#R1" \n\t" \ - "psubw %%mm"#R3", %%mm"#R1" \n\t" \ - "psraw %4, %%mm"#R1" \n\t" \ - "movq %%mm"#R1", "#OFF"(%1) \n\t" \ - "add %2, %0 \n\t" - -DECLARE_ALIGNED(16, const uint64_t, ff_pw_9) = 0x0009000900090009ULL; - -/** Sacrifying mm6 allows to pipeline loads from src */ -static void vc1_put_ver_16b_shift2_mmx(int16_t *dst, - const uint8_t *src, x86_reg stride, - int rnd, int64_t shift) -{ - __asm__ volatile( - "mov $3, %%"REG_c" \n\t" - LOAD_ROUNDER_MMX("%5") - "movq "MANGLE(ff_pw_9)", %%mm6 \n\t" - "1: \n\t" - "movd (%0), %%mm2 \n\t" - "add %2, %0 \n\t" - "movd (%0), %%mm3 \n\t" - "punpcklbw %%mm0, %%mm2 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" - SHIFT2_LINE( 0, 1, 2, 3, 4) - SHIFT2_LINE( 24, 2, 3, 4, 1) - SHIFT2_LINE( 48, 3, 4, 1, 2) - SHIFT2_LINE( 72, 4, 1, 2, 3) - SHIFT2_LINE( 96, 1, 2, 3, 4) - SHIFT2_LINE(120, 2, 3, 4, 1) - SHIFT2_LINE(144, 3, 4, 1, 2) - SHIFT2_LINE(168, 4, 1, 2, 3) - "sub %6, %0 \n\t" - "add $8, %1 \n\t" - "dec %%"REG_c" \n\t" - "jnz 1b \n\t" - : "+r"(src), "+r"(dst) - : "r"(stride), "r"(-2*stride), - "m"(shift), "m"(rnd), "r"(9*stride-4) - : "%"REG_c, "memory" - ); -} - -/** - * Data is already unpacked, so some operations can directly be made from - * memory. - */ -#define VC1_HOR_16b_SHIFT2(OP, OPNAME)\ -static void OPNAME ## vc1_hor_16b_shift2_mmx(uint8_t *dst, x86_reg stride,\ - const int16_t *src, int rnd)\ -{\ - int h = 8;\ -\ - src -= 1;\ - rnd -= (-1+9+9-1)*1024; /* Add -1024 bias */\ - __asm__ volatile(\ - LOAD_ROUNDER_MMX("%4")\ - "movq "MANGLE(ff_pw_128)", %%mm6\n\t"\ - "movq "MANGLE(ff_pw_9)", %%mm5 \n\t"\ - "1: \n\t"\ - "movq 2*0+0(%1), %%mm1 \n\t"\ - "movq 2*0+8(%1), %%mm2 \n\t"\ - "movq 2*1+0(%1), %%mm3 \n\t"\ - "movq 2*1+8(%1), %%mm4 \n\t"\ - "paddw 2*3+0(%1), %%mm1 \n\t"\ - "paddw 2*3+8(%1), %%mm2 \n\t"\ - "paddw 2*2+0(%1), %%mm3 \n\t"\ - "paddw 2*2+8(%1), %%mm4 \n\t"\ - "pmullw %%mm5, %%mm3 \n\t"\ - "pmullw %%mm5, %%mm4 \n\t"\ - "psubw %%mm1, %%mm3 \n\t"\ - "psubw %%mm2, %%mm4 \n\t"\ - NORMALIZE_MMX("$7")\ - /* Remove bias */\ - "paddw %%mm6, %%mm3 \n\t"\ - "paddw %%mm6, %%mm4 \n\t"\ - TRANSFER_DO_PACK(OP)\ - "add $24, %1 \n\t"\ - "add %3, %2 \n\t"\ - "decl %0 \n\t"\ - "jnz 1b \n\t"\ - : "+r"(h), "+r" (src), "+r" (dst)\ - : "r"(stride), "m"(rnd)\ - : "memory"\ - );\ -} - -VC1_HOR_16b_SHIFT2(OP_PUT, put_) -VC1_HOR_16b_SHIFT2(OP_AVG, avg_) - - -/** - * Purely vertical or horizontal 1/2 shift interpolation. - * Sacrify mm6 for *9 factor. - */ -#define VC1_SHIFT2(OP, OPNAME)\ -static void OPNAME ## vc1_shift2_mmx(uint8_t *dst, const uint8_t *src,\ - x86_reg stride, int rnd, x86_reg offset)\ -{\ - rnd = 8-rnd;\ - __asm__ volatile(\ - "mov $8, %%"REG_c" \n\t"\ - LOAD_ROUNDER_MMX("%5")\ - "movq "MANGLE(ff_pw_9)", %%mm6\n\t"\ - "1: \n\t"\ - "movd 0(%0 ), %%mm3 \n\t"\ - "movd 4(%0 ), %%mm4 \n\t"\ - "movd 0(%0,%2), %%mm1 \n\t"\ - "movd 4(%0,%2), %%mm2 \n\t"\ - "add %2, %0 \n\t"\ - "punpcklbw %%mm0, %%mm3 \n\t"\ - "punpcklbw %%mm0, %%mm4 \n\t"\ - "punpcklbw %%mm0, %%mm1 \n\t"\ - "punpcklbw %%mm0, %%mm2 \n\t"\ - "paddw %%mm1, %%mm3 \n\t"\ - "paddw %%mm2, %%mm4 \n\t"\ - "movd 0(%0,%3), %%mm1 \n\t"\ - "movd 4(%0,%3), %%mm2 \n\t"\ - "pmullw %%mm6, %%mm3 \n\t" /* 0,9,9,0*/\ - "pmullw %%mm6, %%mm4 \n\t" /* 0,9,9,0*/\ - "punpcklbw %%mm0, %%mm1 \n\t"\ - "punpcklbw %%mm0, %%mm2 \n\t"\ - "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,0*/\ - "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,0*/\ - "movd 0(%0,%2), %%mm1 \n\t"\ - "movd 4(%0,%2), %%mm2 \n\t"\ - "punpcklbw %%mm0, %%mm1 \n\t"\ - "punpcklbw %%mm0, %%mm2 \n\t"\ - "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,-1*/\ - "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,-1*/\ - NORMALIZE_MMX("$4")\ - "packuswb %%mm4, %%mm3 \n\t"\ - OP((%1), %%mm3)\ - "movq %%mm3, (%1) \n\t"\ - "add %6, %0 \n\t"\ - "add %4, %1 \n\t"\ - "dec %%"REG_c" \n\t"\ - "jnz 1b \n\t"\ - : "+r"(src), "+r"(dst)\ - : "r"(offset), "r"(-2*offset), "g"(stride), "m"(rnd),\ - "g"(stride-offset)\ - : "%"REG_c, "memory"\ - );\ -} - -VC1_SHIFT2(OP_PUT, put_) -VC1_SHIFT2(OP_AVG, avg_) - -/** - * Filter coefficients made global to allow access by all 1 or 3 quarter shift - * interpolation functions. - */ -DECLARE_ASM_CONST(16, uint64_t, ff_pw_53) = 0x0035003500350035ULL; -DECLARE_ASM_CONST(16, uint64_t, ff_pw_18) = 0x0012001200120012ULL; - -/** - * Core of the 1/4 and 3/4 shift bicubic interpolation. - * - * @param UNPACK Macro unpacking arguments from 8 to 16bits (can be empty). - * @param MOVQ "movd 1" or "movq 2", if data read is already unpacked. - * @param A1 Address of 1st tap (beware of unpacked/packed). - * @param A2 Address of 2nd tap - * @param A3 Address of 3rd tap - * @param A4 Address of 4th tap - */ -#define MSPEL_FILTER13_CORE(UNPACK, MOVQ, A1, A2, A3, A4) \ - MOVQ "*0+"A1", %%mm1 \n\t" \ - MOVQ "*4+"A1", %%mm2 \n\t" \ - UNPACK("%%mm1") \ - UNPACK("%%mm2") \ - "pmullw "MANGLE(ff_pw_3)", %%mm1\n\t" \ - "pmullw "MANGLE(ff_pw_3)", %%mm2\n\t" \ - MOVQ "*0+"A2", %%mm3 \n\t" \ - MOVQ "*4+"A2", %%mm4 \n\t" \ - UNPACK("%%mm3") \ - UNPACK("%%mm4") \ - "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ - "pmullw %%mm6, %%mm4 \n\t" /* *18 */ \ - "psubw %%mm1, %%mm3 \n\t" /* 18,-3 */ \ - "psubw %%mm2, %%mm4 \n\t" /* 18,-3 */ \ - MOVQ "*0+"A4", %%mm1 \n\t" \ - MOVQ "*4+"A4", %%mm2 \n\t" \ - UNPACK("%%mm1") \ - UNPACK("%%mm2") \ - "psllw $2, %%mm1 \n\t" /* 4* */ \ - "psllw $2, %%mm2 \n\t" /* 4* */ \ - "psubw %%mm1, %%mm3 \n\t" /* -4,18,-3 */ \ - "psubw %%mm2, %%mm4 \n\t" /* -4,18,-3 */ \ - MOVQ "*0+"A3", %%mm1 \n\t" \ - MOVQ "*4+"A3", %%mm2 \n\t" \ - UNPACK("%%mm1") \ - UNPACK("%%mm2") \ - "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ - "pmullw %%mm5, %%mm2 \n\t" /* *53 */ \ - "paddw %%mm1, %%mm3 \n\t" /* 4,53,18,-3 */ \ - "paddw %%mm2, %%mm4 \n\t" /* 4,53,18,-3 */ - -/** - * Macro to build the vertical 16bits version of vc1_put_shift[13]. - * Here, offset=src_stride. Parameters passed A1 to A4 must use - * %3 (src_stride) and %4 (3*src_stride). - * - * @param NAME Either 1 or 3 - * @see MSPEL_FILTER13_CORE for information on A1->A4 - */ -#define MSPEL_FILTER13_VER_16B(NAME, A1, A2, A3, A4) \ -static void \ -vc1_put_ver_16b_ ## NAME ## _mmx(int16_t *dst, const uint8_t *src, \ - x86_reg src_stride, \ - int rnd, int64_t shift) \ -{ \ - int h = 8; \ - src -= src_stride; \ - __asm__ volatile( \ - LOAD_ROUNDER_MMX("%5") \ - "movq "MANGLE(ff_pw_53)", %%mm5\n\t" \ - "movq "MANGLE(ff_pw_18)", %%mm6\n\t" \ - ASMALIGN(3) \ - "1: \n\t" \ - MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ - NORMALIZE_MMX("%6") \ - TRANSFER_DONT_PACK(OP_PUT) \ - /* Last 3 (in fact 4) bytes on the line */ \ - "movd 8+"A1", %%mm1 \n\t" \ - DO_UNPACK("%%mm1") \ - "movq %%mm1, %%mm3 \n\t" \ - "paddw %%mm1, %%mm1 \n\t" \ - "paddw %%mm3, %%mm1 \n\t" /* 3* */ \ - "movd 8+"A2", %%mm3 \n\t" \ - DO_UNPACK("%%mm3") \ - "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ - "psubw %%mm1, %%mm3 \n\t" /*18,-3 */ \ - "movd 8+"A3", %%mm1 \n\t" \ - DO_UNPACK("%%mm1") \ - "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ - "paddw %%mm1, %%mm3 \n\t" /*53,18,-3 */ \ - "movd 8+"A4", %%mm1 \n\t" \ - DO_UNPACK("%%mm1") \ - "psllw $2, %%mm1 \n\t" /* 4* */ \ - "psubw %%mm1, %%mm3 \n\t" \ - "paddw %%mm7, %%mm3 \n\t" \ - "psraw %6, %%mm3 \n\t" \ - "movq %%mm3, 16(%2) \n\t" \ - "add %3, %1 \n\t" \ - "add $24, %2 \n\t" \ - "decl %0 \n\t" \ - "jnz 1b \n\t" \ - : "+r"(h), "+r" (src), "+r" (dst) \ - : "r"(src_stride), "r"(3*src_stride), \ - "m"(rnd), "m"(shift) \ - : "memory" \ - ); \ -} - -/** - * Macro to build the horizontal 16bits version of vc1_put_shift[13]. - * Here, offset=16bits, so parameters passed A1 to A4 should be simple. - * - * @param NAME Either 1 or 3 - * @see MSPEL_FILTER13_CORE for information on A1->A4 - */ -#define MSPEL_FILTER13_HOR_16B(NAME, A1, A2, A3, A4, OP, OPNAME) \ -static void \ -OPNAME ## vc1_hor_16b_ ## NAME ## _mmx(uint8_t *dst, x86_reg stride, \ - const int16_t *src, int rnd) \ -{ \ - int h = 8; \ - src -= 1; \ - rnd -= (-4+58+13-3)*256; /* Add -256 bias */ \ - __asm__ volatile( \ - LOAD_ROUNDER_MMX("%4") \ - "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ - "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ - ASMALIGN(3) \ - "1: \n\t" \ - MSPEL_FILTER13_CORE(DONT_UNPACK, "movq 2", A1, A2, A3, A4) \ - NORMALIZE_MMX("$7") \ - /* Remove bias */ \ - "paddw "MANGLE(ff_pw_128)", %%mm3 \n\t" \ - "paddw "MANGLE(ff_pw_128)", %%mm4 \n\t" \ - TRANSFER_DO_PACK(OP) \ - "add $24, %1 \n\t" \ - "add %3, %2 \n\t" \ - "decl %0 \n\t" \ - "jnz 1b \n\t" \ - : "+r"(h), "+r" (src), "+r" (dst) \ - : "r"(stride), "m"(rnd) \ - : "memory" \ - ); \ -} - -/** - * Macro to build the 8bits, any direction, version of vc1_put_shift[13]. - * Here, offset=src_stride. Parameters passed A1 to A4 must use - * %3 (offset) and %4 (3*offset). - * - * @param NAME Either 1 or 3 - * @see MSPEL_FILTER13_CORE for information on A1->A4 - */ -#define MSPEL_FILTER13_8B(NAME, A1, A2, A3, A4, OP, OPNAME) \ -static void \ -OPNAME ## vc1_## NAME ## _mmx(uint8_t *dst, const uint8_t *src, \ - x86_reg stride, int rnd, x86_reg offset) \ -{ \ - int h = 8; \ - src -= offset; \ - rnd = 32-rnd; \ - __asm__ volatile ( \ - LOAD_ROUNDER_MMX("%6") \ - "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ - "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ - ASMALIGN(3) \ - "1: \n\t" \ - MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ - NORMALIZE_MMX("$6") \ - TRANSFER_DO_PACK(OP) \ - "add %5, %1 \n\t" \ - "add %5, %2 \n\t" \ - "decl %0 \n\t" \ - "jnz 1b \n\t" \ - : "+r"(h), "+r" (src), "+r" (dst) \ - : "r"(offset), "r"(3*offset), "g"(stride), "m"(rnd) \ - : "memory" \ - ); \ -} - -/** 1/4 shift bicubic interpolation */ -MSPEL_FILTER13_8B (shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )", OP_PUT, put_) -MSPEL_FILTER13_8B (shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )", OP_AVG, avg_) -MSPEL_FILTER13_VER_16B(shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )") -MSPEL_FILTER13_HOR_16B(shift1, "2*3(%1)", "2*2(%1)", "2*1(%1)", "2*0(%1)", OP_PUT, put_) -MSPEL_FILTER13_HOR_16B(shift1, "2*3(%1)", "2*2(%1)", "2*1(%1)", "2*0(%1)", OP_AVG, avg_) - -/** 3/4 shift bicubic interpolation */ -MSPEL_FILTER13_8B (shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )", OP_PUT, put_) -MSPEL_FILTER13_8B (shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )", OP_AVG, avg_) -MSPEL_FILTER13_VER_16B(shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )") -MSPEL_FILTER13_HOR_16B(shift3, "2*0(%1)", "2*1(%1)", "2*2(%1)", "2*3(%1)", OP_PUT, put_) -MSPEL_FILTER13_HOR_16B(shift3, "2*0(%1)", "2*1(%1)", "2*2(%1)", "2*3(%1)", OP_AVG, avg_) - -typedef void (*vc1_mspel_mc_filter_ver_16bits)(int16_t *dst, const uint8_t *src, x86_reg src_stride, int rnd, int64_t shift); -typedef void (*vc1_mspel_mc_filter_hor_16bits)(uint8_t *dst, x86_reg dst_stride, const int16_t *src, int rnd); -typedef void (*vc1_mspel_mc_filter_8bits)(uint8_t *dst, const uint8_t *src, x86_reg stride, int rnd, x86_reg offset); - -/** - * Interpolates fractional pel values by applying proper vertical then - * horizontal filter. - * - * @param dst Destination buffer for interpolated pels. - * @param src Source buffer. - * @param stride Stride for both src and dst buffers. - * @param hmode Horizontal filter (expressed in quarter pixels shift). - * @param hmode Vertical filter. - * @param rnd Rounding bias. - */ -#define VC1_MSPEL_MC(OP)\ -static void OP ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride,\ - int hmode, int vmode, int rnd)\ -{\ - static const vc1_mspel_mc_filter_ver_16bits vc1_put_shift_ver_16bits[] =\ - { NULL, vc1_put_ver_16b_shift1_mmx, vc1_put_ver_16b_shift2_mmx, vc1_put_ver_16b_shift3_mmx };\ - static const vc1_mspel_mc_filter_hor_16bits vc1_put_shift_hor_16bits[] =\ - { NULL, OP ## vc1_hor_16b_shift1_mmx, OP ## vc1_hor_16b_shift2_mmx, OP ## vc1_hor_16b_shift3_mmx };\ - static const vc1_mspel_mc_filter_8bits vc1_put_shift_8bits[] =\ - { NULL, OP ## vc1_shift1_mmx, OP ## vc1_shift2_mmx, OP ## vc1_shift3_mmx };\ -\ - __asm__ volatile(\ - "pxor %%mm0, %%mm0 \n\t"\ - ::: "memory"\ - );\ -\ - if (vmode) { /* Vertical filter to apply */\ - if (hmode) { /* Horizontal filter to apply, output to tmp */\ - static const int shift_value[] = { 0, 5, 1, 5 };\ - int shift = (shift_value[hmode]+shift_value[vmode])>>1;\ - int r;\ - DECLARE_ALIGNED(16, int16_t, tmp)[12*8];\ -\ - r = (1<<(shift-1)) + rnd-1;\ - vc1_put_shift_ver_16bits[vmode](tmp, src-1, stride, r, shift);\ -\ - vc1_put_shift_hor_16bits[hmode](dst, stride, tmp+1, 64-rnd);\ - return;\ - }\ - else { /* No horizontal filter, output 8 lines to dst */\ - vc1_put_shift_8bits[vmode](dst, src, stride, 1-rnd, stride);\ - return;\ - }\ - }\ -\ - /* Horizontal mode with no vertical mode */\ - vc1_put_shift_8bits[hmode](dst, src, stride, rnd, 1);\ -} - -VC1_MSPEL_MC(put_) -VC1_MSPEL_MC(avg_) - -/** Macro to ease bicubic filter interpolation functions declarations */ -#define DECLARE_FUNCTION(a, b) \ -static void put_vc1_mspel_mc ## a ## b ## _mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \ - put_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ -}\ -static void avg_vc1_mspel_mc ## a ## b ## _mmx2(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \ - avg_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ -} - -DECLARE_FUNCTION(0, 1) -DECLARE_FUNCTION(0, 2) -DECLARE_FUNCTION(0, 3) - -DECLARE_FUNCTION(1, 0) -DECLARE_FUNCTION(1, 1) -DECLARE_FUNCTION(1, 2) -DECLARE_FUNCTION(1, 3) - -DECLARE_FUNCTION(2, 0) -DECLARE_FUNCTION(2, 1) -DECLARE_FUNCTION(2, 2) -DECLARE_FUNCTION(2, 3) - -DECLARE_FUNCTION(3, 0) -DECLARE_FUNCTION(3, 1) -DECLARE_FUNCTION(3, 2) -DECLARE_FUNCTION(3, 3) - -static void vc1_inv_trans_4x4_dc_mmx2(uint8_t *dest, int linesize, DCTELEM *block) -{ - int dc = block[0]; - dc = (17 * dc + 4) >> 3; - dc = (17 * dc + 64) >> 7; - __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*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) - ); -} - -static void vc1_inv_trans_4x8_dc_mmx2(uint8_t *dest, int linesize, DCTELEM *block) -{ - int dc = block[0]; - dc = (17 * dc + 4) >> 3; - dc = (12 * dc + 64) >> 7; - __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*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) - ); - dest += 4*linesize; - __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*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) - ); -} - -static void vc1_inv_trans_8x4_dc_mmx2(uint8_t *dest, int linesize, DCTELEM *block) -{ - int dc = block[0]; - dc = ( 3 * dc + 1) >> 1; - dc = (17 * dc + 64) >> 7; - __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( - "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"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) - ); -} - -static void vc1_inv_trans_8x8_dc_mmx2(uint8_t *dest, int linesize, DCTELEM *block) -{ - int dc = block[0]; - dc = (3 * dc + 1) >> 1; - dc = (3 * dc + 16) >> 5; - __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( - "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"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) - ); - dest += 4*linesize; - __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"(*(uint32_t*)(dest+0*linesize)), - "+m"(*(uint32_t*)(dest+1*linesize)), - "+m"(*(uint32_t*)(dest+2*linesize)), - "+m"(*(uint32_t*)(dest+3*linesize)) - ); -} - -void ff_vc1dsp_init_mmx(DSPContext* dsp, AVCodecContext *avctx) { - mm_flags = mm_support(); - - dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_mmx; - dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx; - dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_mmx; - dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_mmx; - - dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_mmx; - dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_mmx; - dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_mmx; - dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_mmx; - - dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_mmx; - dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_mmx; - dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_mmx; - dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_mmx; - - dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_mmx; - dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_mmx; - dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_mmx; - dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_mmx; - - if (mm_flags & FF_MM_MMX2){ - dsp->avg_vc1_mspel_pixels_tab[ 0] = ff_avg_vc1_mspel_mc00_mmx2; - dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_mmx2; - dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_mmx2; - dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_mmx2; - - dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_mmx2; - dsp->avg_vc1_mspel_pixels_tab[ 5] = avg_vc1_mspel_mc11_mmx2; - dsp->avg_vc1_mspel_pixels_tab[ 9] = avg_vc1_mspel_mc12_mmx2; - dsp->avg_vc1_mspel_pixels_tab[13] = avg_vc1_mspel_mc13_mmx2; - - dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_mmx2; - dsp->avg_vc1_mspel_pixels_tab[ 6] = avg_vc1_mspel_mc21_mmx2; - dsp->avg_vc1_mspel_pixels_tab[10] = avg_vc1_mspel_mc22_mmx2; - dsp->avg_vc1_mspel_pixels_tab[14] = avg_vc1_mspel_mc23_mmx2; - - dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_mmx2; - dsp->avg_vc1_mspel_pixels_tab[ 7] = avg_vc1_mspel_mc31_mmx2; - dsp->avg_vc1_mspel_pixels_tab[11] = avg_vc1_mspel_mc32_mmx2; - dsp->avg_vc1_mspel_pixels_tab[15] = avg_vc1_mspel_mc33_mmx2; - - dsp->vc1_inv_trans_8x8_dc = vc1_inv_trans_8x8_dc_mmx2; - dsp->vc1_inv_trans_4x8_dc = vc1_inv_trans_4x8_dc_mmx2; - dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_mmx2; - dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_mmx2; - } -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.c deleted file mode 100644 index 44a8477..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (C) 2004 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MMX-optimized functions cribbed from the original VP3 source code. - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "dsputil_mmx.h" -#include "vp3dsp_mmx.h" - -extern const uint16_t ff_vp3_idct_data[]; - -// this is off by one or two for some cases when filter_limit is greater than 63 -// in: p0 in mm6, p1 in mm4, p2 in mm2, p3 in mm1 -// out: p1 in mm4, p2 in mm3 -#define VP3_LOOP_FILTER(flim) \ - "movq %%mm6, %%mm7 \n\t" \ - "pand "MANGLE(ff_pb_7 )", %%mm6 \n\t" /* p0&7 */ \ - "psrlw $3, %%mm7 \n\t" \ - "pand "MANGLE(ff_pb_1F)", %%mm7 \n\t" /* p0>>3 */ \ - "movq %%mm2, %%mm3 \n\t" /* mm3 = p2 */ \ - "pxor %%mm4, %%mm2 \n\t" \ - "pand "MANGLE(ff_pb_1 )", %%mm2 \n\t" /* (p2^p1)&1 */ \ - "movq %%mm2, %%mm5 \n\t" \ - "paddb %%mm2, %%mm2 \n\t" \ - "paddb %%mm5, %%mm2 \n\t" /* 3*(p2^p1)&1 */ \ - "paddb %%mm6, %%mm2 \n\t" /* extra bits lost in shifts */ \ - "pcmpeqb %%mm0, %%mm0 \n\t" \ - "pxor %%mm0, %%mm1 \n\t" /* 255 - p3 */ \ - "pavgb %%mm2, %%mm1 \n\t" /* (256 - p3 + extrabits) >> 1 */ \ - "pxor %%mm4, %%mm0 \n\t" /* 255 - p1 */ \ - "pavgb %%mm3, %%mm0 \n\t" /* (256 + p2-p1) >> 1 */ \ - "paddb "MANGLE(ff_pb_3 )", %%mm1 \n\t" \ - "pavgb %%mm0, %%mm1 \n\t" /* 128+2+( p2-p1 - p3) >> 2 */ \ - "pavgb %%mm0, %%mm1 \n\t" /* 128+1+(3*(p2-p1) - p3) >> 3 */ \ - "paddusb %%mm1, %%mm7 \n\t" /* d+128+1 */ \ - "movq "MANGLE(ff_pb_81)", %%mm6 \n\t" \ - "psubusb %%mm7, %%mm6 \n\t" \ - "psubusb "MANGLE(ff_pb_81)", %%mm7 \n\t" \ -\ - "movq "#flim", %%mm5 \n\t" \ - "pminub %%mm5, %%mm6 \n\t" \ - "pminub %%mm5, %%mm7 \n\t" \ - "movq %%mm6, %%mm0 \n\t" \ - "movq %%mm7, %%mm1 \n\t" \ - "paddb %%mm6, %%mm6 \n\t" \ - "paddb %%mm7, %%mm7 \n\t" \ - "pminub %%mm5, %%mm6 \n\t" \ - "pminub %%mm5, %%mm7 \n\t" \ - "psubb %%mm0, %%mm6 \n\t" \ - "psubb %%mm1, %%mm7 \n\t" \ - "paddusb %%mm7, %%mm4 \n\t" \ - "psubusb %%mm6, %%mm4 \n\t" \ - "psubusb %%mm7, %%mm3 \n\t" \ - "paddusb %%mm6, %%mm3 \n\t" - -#define STORE_4_WORDS(dst0, dst1, dst2, dst3, mm) \ - "movd "#mm", %0 \n\t" \ - "movw %w0, -1"#dst0" \n\t" \ - "psrlq $32, "#mm" \n\t" \ - "shr $16, %0 \n\t" \ - "movw %w0, -1"#dst1" \n\t" \ - "movd "#mm", %0 \n\t" \ - "movw %w0, -1"#dst2" \n\t" \ - "shr $16, %0 \n\t" \ - "movw %w0, -1"#dst3" \n\t" - -void ff_vp3_v_loop_filter_mmx2(uint8_t *src, int stride, int *bounding_values) -{ - __asm__ volatile( - "movq %0, %%mm6 \n\t" - "movq %1, %%mm4 \n\t" - "movq %2, %%mm2 \n\t" - "movq %3, %%mm1 \n\t" - - VP3_LOOP_FILTER(%4) - - "movq %%mm4, %1 \n\t" - "movq %%mm3, %2 \n\t" - - : "+m" (*(uint64_t*)(src - 2*stride)), - "+m" (*(uint64_t*)(src - 1*stride)), - "+m" (*(uint64_t*)(src + 0*stride)), - "+m" (*(uint64_t*)(src + 1*stride)) - : "m"(*(uint64_t*)(bounding_values+129)) - ); -} - -void ff_vp3_h_loop_filter_mmx2(uint8_t *src, int stride, int *bounding_values) -{ - x86_reg tmp; - - __asm__ volatile( - "movd -2(%1), %%mm6 \n\t" - "movd -2(%1,%3), %%mm0 \n\t" - "movd -2(%1,%3,2), %%mm1 \n\t" - "movd -2(%1,%4), %%mm4 \n\t" - - TRANSPOSE8x4(%%mm6, %%mm0, %%mm1, %%mm4, -2(%2), -2(%2,%3), -2(%2,%3,2), -2(%2,%4), %%mm2) - VP3_LOOP_FILTER(%5) - SBUTTERFLY(%%mm4, %%mm3, %%mm5, bw, q) - - STORE_4_WORDS((%1), (%1,%3), (%1,%3,2), (%1,%4), %%mm4) - STORE_4_WORDS((%2), (%2,%3), (%2,%3,2), (%2,%4), %%mm5) - - : "=&r"(tmp) - : "r"(src), "r"(src+4*stride), "r"((x86_reg)stride), "r"((x86_reg)3*stride), - "m"(*(uint64_t*)(bounding_values+129)) - : "memory" - ); -} - -/* from original comments: The Macro does IDct on 4 1-D Dcts */ -#define BeginIDCT() \ - "movq "I(3)", %%mm2 \n\t" \ - "movq "C(3)", %%mm6 \n\t" \ - "movq %%mm2, %%mm4 \n\t" \ - "movq "J(5)", %%mm7 \n\t" \ - "pmulhw %%mm6, %%mm4 \n\t" /* r4 = c3*i3 - i3 */ \ - "movq "C(5)", %%mm1 \n\t" \ - "pmulhw %%mm7, %%mm6 \n\t" /* r6 = c3*i5 - i5 */ \ - "movq %%mm1, %%mm5 \n\t" \ - "pmulhw %%mm2, %%mm1 \n\t" /* r1 = c5*i3 - i3 */ \ - "movq "I(1)", %%mm3 \n\t" \ - "pmulhw %%mm7, %%mm5 \n\t" /* r5 = c5*i5 - i5 */ \ - "movq "C(1)", %%mm0 \n\t" \ - "paddw %%mm2, %%mm4 \n\t" /* r4 = c3*i3 */ \ - "paddw %%mm7, %%mm6 \n\t" /* r6 = c3*i5 */ \ - "paddw %%mm1, %%mm2 \n\t" /* r2 = c5*i3 */ \ - "movq "J(7)", %%mm1 \n\t" \ - "paddw %%mm5, %%mm7 \n\t" /* r7 = c5*i5 */ \ - "movq %%mm0, %%mm5 \n\t" /* r5 = c1 */ \ - "pmulhw %%mm3, %%mm0 \n\t" /* r0 = c1*i1 - i1 */ \ - "paddsw %%mm7, %%mm4 \n\t" /* r4 = C = c3*i3 + c5*i5 */ \ - "pmulhw %%mm1, %%mm5 \n\t" /* r5 = c1*i7 - i7 */ \ - "movq "C(7)", %%mm7 \n\t" \ - "psubsw %%mm2, %%mm6 \n\t" /* r6 = D = c3*i5 - c5*i3 */ \ - "paddw %%mm3, %%mm0 \n\t" /* r0 = c1*i1 */ \ - "pmulhw %%mm7, %%mm3 \n\t" /* r3 = c7*i1 */ \ - "movq "I(2)", %%mm2 \n\t" \ - "pmulhw %%mm1, %%mm7 \n\t" /* r7 = c7*i7 */ \ - "paddw %%mm1, %%mm5 \n\t" /* r5 = c1*i7 */ \ - "movq %%mm2, %%mm1 \n\t" /* r1 = i2 */ \ - "pmulhw "C(2)", %%mm2 \n\t" /* r2 = c2*i2 - i2 */ \ - "psubsw %%mm5, %%mm3 \n\t" /* r3 = B = c7*i1 - c1*i7 */ \ - "movq "J(6)", %%mm5 \n\t" \ - "paddsw %%mm7, %%mm0 \n\t" /* r0 = A = c1*i1 + c7*i7 */ \ - "movq %%mm5, %%mm7 \n\t" /* r7 = i6 */ \ - "psubsw %%mm4, %%mm0 \n\t" /* r0 = A - C */ \ - "pmulhw "C(2)", %%mm5 \n\t" /* r5 = c2*i6 - i6 */ \ - "paddw %%mm1, %%mm2 \n\t" /* r2 = c2*i2 */ \ - "pmulhw "C(6)", %%mm1 \n\t" /* r1 = c6*i2 */ \ - "paddsw %%mm4, %%mm4 \n\t" /* r4 = C + C */ \ - "paddsw %%mm0, %%mm4 \n\t" /* r4 = C. = A + C */ \ - "psubsw %%mm6, %%mm3 \n\t" /* r3 = B - D */ \ - "paddw %%mm7, %%mm5 \n\t" /* r5 = c2*i6 */ \ - "paddsw %%mm6, %%mm6 \n\t" /* r6 = D + D */ \ - "pmulhw "C(6)", %%mm7 \n\t" /* r7 = c6*i6 */ \ - "paddsw %%mm3, %%mm6 \n\t" /* r6 = D. = B + D */ \ - "movq %%mm4, "I(1)"\n\t" /* save C. at I(1) */ \ - "psubsw %%mm5, %%mm1 \n\t" /* r1 = H = c6*i2 - c2*i6 */ \ - "movq "C(4)", %%mm4 \n\t" \ - "movq %%mm3, %%mm5 \n\t" /* r5 = B - D */ \ - "pmulhw %%mm4, %%mm3 \n\t" /* r3 = (c4 - 1) * (B - D) */ \ - "paddsw %%mm2, %%mm7 \n\t" /* r3 = (c4 - 1) * (B - D) */ \ - "movq %%mm6, "I(2)"\n\t" /* save D. at I(2) */ \ - "movq %%mm0, %%mm2 \n\t" /* r2 = A - C */ \ - "movq "I(0)", %%mm6 \n\t" \ - "pmulhw %%mm4, %%mm0 \n\t" /* r0 = (c4 - 1) * (A - C) */ \ - "paddw %%mm3, %%mm5 \n\t" /* r5 = B. = c4 * (B - D) */ \ - "movq "J(4)", %%mm3 \n\t" \ - "psubsw %%mm1, %%mm5 \n\t" /* r5 = B.. = B. - H */ \ - "paddw %%mm0, %%mm2 \n\t" /* r0 = A. = c4 * (A - C) */ \ - "psubsw %%mm3, %%mm6 \n\t" /* r6 = i0 - i4 */ \ - "movq %%mm6, %%mm0 \n\t" \ - "pmulhw %%mm4, %%mm6 \n\t" /* r6 = (c4 - 1) * (i0 - i4) */ \ - "paddsw %%mm3, %%mm3 \n\t" /* r3 = i4 + i4 */ \ - "paddsw %%mm1, %%mm1 \n\t" /* r1 = H + H */ \ - "paddsw %%mm0, %%mm3 \n\t" /* r3 = i0 + i4 */ \ - "paddsw %%mm5, %%mm1 \n\t" /* r1 = H. = B + H */ \ - "pmulhw %%mm3, %%mm4 \n\t" /* r4 = (c4 - 1) * (i0 + i4) */ \ - "paddsw %%mm0, %%mm6 \n\t" /* r6 = F = c4 * (i0 - i4) */ \ - "psubsw %%mm2, %%mm6 \n\t" /* r6 = F. = F - A. */ \ - "paddsw %%mm2, %%mm2 \n\t" /* r2 = A. + A. */ \ - "movq "I(1)", %%mm0 \n\t" /* r0 = C. */ \ - "paddsw %%mm6, %%mm2 \n\t" /* r2 = A.. = F + A. */ \ - "paddw %%mm3, %%mm4 \n\t" /* r4 = E = c4 * (i0 + i4) */ \ - "psubsw %%mm1, %%mm2 \n\t" /* r2 = R2 = A.. - H. */ - -/* RowIDCT gets ready to transpose */ -#define RowIDCT() \ - BeginIDCT() \ - "movq "I(2)", %%mm3 \n\t" /* r3 = D. */ \ - "psubsw %%mm7, %%mm4 \n\t" /* r4 = E. = E - G */ \ - "paddsw %%mm1, %%mm1 \n\t" /* r1 = H. + H. */ \ - "paddsw %%mm7, %%mm7 \n\t" /* r7 = G + G */ \ - "paddsw %%mm2, %%mm1 \n\t" /* r1 = R1 = A.. + H. */ \ - "paddsw %%mm4, %%mm7 \n\t" /* r1 = R1 = A.. + H. */ \ - "psubsw %%mm3, %%mm4 \n\t" /* r4 = R4 = E. - D. */ \ - "paddsw %%mm3, %%mm3 \n\t" \ - "psubsw %%mm5, %%mm6 \n\t" /* r6 = R6 = F. - B.. */ \ - "paddsw %%mm5, %%mm5 \n\t" \ - "paddsw %%mm4, %%mm3 \n\t" /* r3 = R3 = E. + D. */ \ - "paddsw %%mm6, %%mm5 \n\t" /* r5 = R5 = F. + B.. */ \ - "psubsw %%mm0, %%mm7 \n\t" /* r7 = R7 = G. - C. */ \ - "paddsw %%mm0, %%mm0 \n\t" \ - "movq %%mm1, "I(1)"\n\t" /* save R1 */ \ - "paddsw %%mm7, %%mm0 \n\t" /* r0 = R0 = G. + C. */ - -/* Column IDCT normalizes and stores final results */ -#define ColumnIDCT() \ - BeginIDCT() \ - "paddsw "OC_8", %%mm2 \n\t" /* adjust R2 (and R1) for shift */ \ - "paddsw %%mm1, %%mm1 \n\t" /* r1 = H. + H. */ \ - "paddsw %%mm2, %%mm1 \n\t" /* r1 = R1 = A.. + H. */ \ - "psraw $4, %%mm2 \n\t" /* r2 = NR2 */ \ - "psubsw %%mm7, %%mm4 \n\t" /* r4 = E. = E - G */ \ - "psraw $4, %%mm1 \n\t" /* r1 = NR1 */ \ - "movq "I(2)", %%mm3 \n\t" /* r3 = D. */ \ - "paddsw %%mm7, %%mm7 \n\t" /* r7 = G + G */ \ - "movq %%mm2, "I(2)"\n\t" /* store NR2 at I2 */ \ - "paddsw %%mm4, %%mm7 \n\t" /* r7 = G. = E + G */ \ - "movq %%mm1, "I(1)"\n\t" /* store NR1 at I1 */ \ - "psubsw %%mm3, %%mm4 \n\t" /* r4 = R4 = E. - D. */ \ - "paddsw "OC_8", %%mm4 \n\t" /* adjust R4 (and R3) for shift */ \ - "paddsw %%mm3, %%mm3 \n\t" /* r3 = D. + D. */ \ - "paddsw %%mm4, %%mm3 \n\t" /* r3 = R3 = E. + D. */ \ - "psraw $4, %%mm4 \n\t" /* r4 = NR4 */ \ - "psubsw %%mm5, %%mm6 \n\t" /* r6 = R6 = F. - B.. */ \ - "psraw $4, %%mm3 \n\t" /* r3 = NR3 */ \ - "paddsw "OC_8", %%mm6 \n\t" /* adjust R6 (and R5) for shift */ \ - "paddsw %%mm5, %%mm5 \n\t" /* r5 = B.. + B.. */ \ - "paddsw %%mm6, %%mm5 \n\t" /* r5 = R5 = F. + B.. */ \ - "psraw $4, %%mm6 \n\t" /* r6 = NR6 */ \ - "movq %%mm4, "J(4)"\n\t" /* store NR4 at J4 */ \ - "psraw $4, %%mm5 \n\t" /* r5 = NR5 */ \ - "movq %%mm3, "I(3)"\n\t" /* store NR3 at I3 */ \ - "psubsw %%mm0, %%mm7 \n\t" /* r7 = R7 = G. - C. */ \ - "paddsw "OC_8", %%mm7 \n\t" /* adjust R7 (and R0) for shift */ \ - "paddsw %%mm0, %%mm0 \n\t" /* r0 = C. + C. */ \ - "paddsw %%mm7, %%mm0 \n\t" /* r0 = R0 = G. + C. */ \ - "psraw $4, %%mm7 \n\t" /* r7 = NR7 */ \ - "movq %%mm6, "J(6)"\n\t" /* store NR6 at J6 */ \ - "psraw $4, %%mm0 \n\t" /* r0 = NR0 */ \ - "movq %%mm5, "J(5)"\n\t" /* store NR5 at J5 */ \ - "movq %%mm7, "J(7)"\n\t" /* store NR7 at J7 */ \ - "movq %%mm0, "I(0)"\n\t" /* 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 %%mm4, %%mm1 \n\t" /* r1 = e3 e2 e1 e0 */ \ - "punpcklwd %%mm5, %%mm4 \n\t" /* r4 = f1 e1 f0 e0 */ \ - "movq %%mm0, "I(0)"\n\t" /* save a3 a2 a1 a0 */ \ - "punpckhwd %%mm5, %%mm1 \n\t" /* r1 = f3 e3 f2 e2 */ \ - "movq %%mm6, %%mm0 \n\t" /* r0 = g3 g2 g1 g0 */ \ - "punpcklwd %%mm7, %%mm6 \n\t" /* r6 = h1 g1 h0 g0 */ \ - "movq %%mm4, %%mm5 \n\t" /* r5 = f1 e1 f0 e0 */ \ - "punpckldq %%mm6, %%mm4 \n\t" /* r4 = h0 g0 f0 e0 = R4 */ \ - "punpckhdq %%mm6, %%mm5 \n\t" /* r5 = h1 g1 f1 e1 = R5 */ \ - "movq %%mm1, %%mm6 \n\t" /* r6 = f3 e3 f2 e2 */ \ - "movq %%mm4, "J(4)"\n\t" \ - "punpckhwd %%mm7, %%mm0 \n\t" /* r0 = h3 g3 h2 g2 */ \ - "movq %%mm5, "J(5)"\n\t" \ - "punpckhdq %%mm0, %%mm6 \n\t" /* r6 = h3 g3 f3 e3 = R7 */ \ - "movq "I(0)", %%mm4 \n\t" /* r4 = a3 a2 a1 a0 */ \ - "punpckldq %%mm0, %%mm1 \n\t" /* r1 = h2 g2 f2 e2 = R6 */ \ - "movq "I(1)", %%mm5 \n\t" /* r5 = b3 b2 b1 b0 */ \ - "movq %%mm4, %%mm0 \n\t" /* r0 = a3 a2 a1 a0 */ \ - "movq %%mm6, "J(7)"\n\t" \ - "punpcklwd %%mm5, %%mm0 \n\t" /* r0 = b1 a1 b0 a0 */ \ - "movq %%mm1, "J(6)"\n\t" \ - "punpckhwd %%mm5, %%mm4 \n\t" /* r4 = b3 a3 b2 a2 */ \ - "movq %%mm2, %%mm5 \n\t" /* r5 = c3 c2 c1 c0 */ \ - "punpcklwd %%mm3, %%mm2 \n\t" /* r2 = d1 c1 d0 c0 */ \ - "movq %%mm0, %%mm1 \n\t" /* r1 = b1 a1 b0 a0 */ \ - "punpckldq %%mm2, %%mm0 \n\t" /* r0 = d0 c0 b0 a0 = R0 */ \ - "punpckhdq %%mm2, %%mm1 \n\t" /* r1 = d1 c1 b1 a1 = R1 */ \ - "movq %%mm4, %%mm2 \n\t" /* r2 = b3 a3 b2 a2 */ \ - "movq %%mm0, "I(0)"\n\t" \ - "punpckhwd %%mm3, %%mm5 \n\t" /* r5 = d3 c3 d2 c2 */ \ - "movq %%mm1, "I(1)"\n\t" \ - "punpckhdq %%mm5, %%mm4 \n\t" /* r4 = d3 c3 b3 a3 = R3 */ \ - "punpckldq %%mm5, %%mm2 \n\t" /* r2 = d2 c2 b2 a2 = R2 */ \ - "movq %%mm4, "I(3)"\n\t" \ - "movq %%mm2, "I(2)"\n\t" - -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) AV_STRINGIFY(16*(x-1))"(%1)" -#define OC_8 "%2" - - /* at this point, function has completed dequantization + dezigzag + - * partial transposition; now do the idct itself */ -#define I(x) AV_STRINGIFY(16* x )"(%0)" -#define J(x) AV_STRINGIFY(16*(x-4) + 8)"(%0)" - - __asm__ volatile ( - RowIDCT() - Transpose() - -#undef I -#undef J -#define I(x) AV_STRINGIFY(16* x + 64)"(%0)" -#define J(x) AV_STRINGIFY(16*(x-4) + 72)"(%0)" - - RowIDCT() - Transpose() - -#undef I -#undef J -#define I(x) AV_STRINGIFY(16*x)"(%0)" -#define J(x) AV_STRINGIFY(16*x)"(%0)" - - ColumnIDCT() - -#undef I -#undef J -#define I(x) AV_STRINGIFY(16*x + 8)"(%0)" -#define J(x) AV_STRINGIFY(16*x + 8)"(%0)" - - ColumnIDCT() - :: "r"(output_data), "r"(ff_vp3_idct_data), "m"(ff_pw_8) - ); -#undef I -#undef J - -} - -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); -} - -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); -} - -void ff_vp3_idct_dc_add_mmx2(uint8_t *dest, int linesize, const DCTELEM *block) -{ - int dc = block[0]; - dc = (46341*dc)>>16; - dc = (46341*dc + (8<<16))>>20; - - __asm__ volatile( - "movd %3, %%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" - -#define DC_ADD \ - "movq (%0), %%mm2 \n\t" \ - "movq (%0,%1), %%mm3 \n\t" \ - "paddusb %%mm0, %%mm2 \n\t" \ - "movq (%0,%1,2), %%mm4 \n\t" \ - "paddusb %%mm0, %%mm3 \n\t" \ - "movq (%0,%2), %%mm5 \n\t" \ - "paddusb %%mm0, %%mm4 \n\t" \ - "paddusb %%mm0, %%mm5 \n\t" \ - "psubusb %%mm1, %%mm2 \n\t" \ - "psubusb %%mm1, %%mm3 \n\t" \ - "movq %%mm2, (%0) \n\t" \ - "psubusb %%mm1, %%mm4 \n\t" \ - "movq %%mm3, (%0,%1) \n\t" \ - "psubusb %%mm1, %%mm5 \n\t" \ - "movq %%mm4, (%0,%1,2) \n\t" \ - "movq %%mm5, (%0,%2) \n\t" - - DC_ADD - "lea (%0,%1,4), %0 \n\t" - DC_ADD - - : "+r"(dest) - : "r"((x86_reg)linesize), "r"((x86_reg)3*linesize), "r"(dc) - ); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.h b/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.h deleted file mode 100644 index e0ebf0b..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_mmx.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * vp3dsp MMX function declarations - * Copyright (c) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_VP3DSP_MMX_H -#define AVCODEC_X86_VP3DSP_MMX_H - -#include -#include "libavcodec/dsputil.h" - -void ff_vp3_idct_mmx(int16_t *data); -void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block); -void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block); -void ff_vp3_idct_dc_add_mmx2(uint8_t *dest, int line_size, const DCTELEM *block); - -void ff_vp3_v_loop_filter_mmx2(uint8_t *src, int stride, int *bounding_values); -void ff_vp3_h_loop_filter_mmx2(uint8_t *src, int stride, int *bounding_values); - -#endif /* AVCODEC_X86_VP3DSP_MMX_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.c b/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.c deleted file mode 100644 index e0ebd42..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2004 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * SSE2-optimized functions cribbed from the original VP3 source code. - */ - -#include "libavcodec/dsputil.h" -#include "dsputil_mmx.h" -#include "vp3dsp_sse2.h" - -DECLARE_ALIGNED(16, const uint16_t, ff_vp3_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 VP3_1D_IDCT_SSE2(ADD, SHIFT) \ - "movdqa "I(3)", %%xmm2 \n\t" /* xmm2 = i3 */ \ - "movdqa "C(3)", %%xmm6 \n\t" /* xmm6 = c3 */ \ - "movdqa %%xmm2, %%xmm4 \n\t" /* xmm4 = i3 */ \ - "movdqa "I(5)", %%xmm7 \n\t" /* xmm7 = i5 */ \ - "pmulhw %%xmm6, %%xmm4 \n\t" /* xmm4 = c3 * i3 - i3 */ \ - "movdqa "C(5)", %%xmm1 \n\t" /* xmm1 = c5 */ \ - "pmulhw %%xmm7, %%xmm6 \n\t" /* xmm6 = c3 * i5 - i5 */ \ - "movdqa %%xmm1, %%xmm5 \n\t" /* xmm5 = c5 */ \ - "pmulhw %%xmm2, %%xmm1 \n\t" /* xmm1 = c5 * i3 - i3 */ \ - "movdqa "I(1)", %%xmm3 \n\t" /* xmm3 = i1 */ \ - "pmulhw %%xmm7, %%xmm5 \n\t" /* xmm5 = c5 * i5 - i5 */ \ - "movdqa "C(1)", %%xmm0 \n\t" /* xmm0 = c1 */ \ - "paddw %%xmm2, %%xmm4 \n\t" /* xmm4 = c3 * i3 */ \ - "paddw %%xmm7, %%xmm6 \n\t" /* xmm6 = c3 * i5 */ \ - "paddw %%xmm1, %%xmm2 \n\t" /* xmm2 = c5 * i3 */ \ - "movdqa "I(7)", %%xmm1 \n\t" /* xmm1 = i7 */ \ - "paddw %%xmm5, %%xmm7 \n\t" /* xmm7 = c5 * i5 */ \ - "movdqa %%xmm0, %%xmm5 \n\t" /* xmm5 = c1 */ \ - "pmulhw %%xmm3, %%xmm0 \n\t" /* xmm0 = c1 * i1 - i1 */ \ - "paddsw %%xmm7, %%xmm4 \n\t" /* xmm4 = c3 * i3 + c5 * i5 = C */ \ - "pmulhw %%xmm1, %%xmm5 \n\t" /* xmm5 = c1 * i7 - i7 */ \ - "movdqa "C(7)", %%xmm7 \n\t" /* xmm7 = c7 */ \ - "psubsw %%xmm2, %%xmm6 \n\t" /* xmm6 = c3 * i5 - c5 * i3 = D */ \ - "paddw %%xmm3, %%xmm0 \n\t" /* xmm0 = c1 * i1 */ \ - "pmulhw %%xmm7, %%xmm3 \n\t" /* xmm3 = c7 * i1 */ \ - "movdqa "I(2)", %%xmm2 \n\t" /* xmm2 = i2 */ \ - "pmulhw %%xmm1, %%xmm7 \n\t" /* xmm7 = c7 * i7 */ \ - "paddw %%xmm1, %%xmm5 \n\t" /* xmm5 = c1 * i7 */ \ - "movdqa %%xmm2, %%xmm1 \n\t" /* xmm1 = i2 */ \ - "pmulhw "C(2)", %%xmm2 \n\t" /* xmm2 = i2 * c2 -i2 */ \ - "psubsw %%xmm5, %%xmm3 \n\t" /* xmm3 = c7 * i1 - c1 * i7 = B */ \ - "movdqa "I(6)", %%xmm5 \n\t" /* xmm5 = i6 */ \ - "paddsw %%xmm7, %%xmm0 \n\t" /* xmm0 = c1 * i1 + c7 * i7 = A */ \ - "movdqa %%xmm5, %%xmm7 \n\t" /* xmm7 = i6 */ \ - "psubsw %%xmm4, %%xmm0 \n\t" /* xmm0 = A - C */ \ - "pmulhw "C(2)", %%xmm5 \n\t" /* xmm5 = c2 * i6 - i6 */ \ - "paddw %%xmm1, %%xmm2 \n\t" /* xmm2 = i2 * c2 */ \ - "pmulhw "C(6)", %%xmm1 \n\t" /* xmm1 = c6 * i2 */ \ - "paddsw %%xmm4, %%xmm4 \n\t" /* xmm4 = C + C */ \ - "paddsw %%xmm0, %%xmm4 \n\t" /* xmm4 = A + C = C. */ \ - "psubsw %%xmm6, %%xmm3 \n\t" /* xmm3 = B - D */ \ - "paddw %%xmm7, %%xmm5 \n\t" /* xmm5 = c2 * i6 */ \ - "paddsw %%xmm6, %%xmm6 \n\t" /* xmm6 = D + D */ \ - "pmulhw "C(6)", %%xmm7 \n\t" /* xmm7 = c6 * i6 */ \ - "paddsw %%xmm3, %%xmm6 \n\t" /* xmm6 = B + D = D. */ \ - "movdqa %%xmm4, "I(1)" \n\t" /* Save C. at I(1) */ \ - "psubsw %%xmm5, %%xmm1 \n\t" /* xmm1 = c6 * i2 - c2 * i6 = H */ \ - "movdqa "C(4)", %%xmm4 \n\t" /* xmm4 = c4 */ \ - "movdqa %%xmm3, %%xmm5 \n\t" /* xmm5 = B - D */ \ - "pmulhw %%xmm4, %%xmm3 \n\t" /* xmm3 = ( c4 -1 ) * ( B - D ) */ \ - "paddsw %%xmm2, %%xmm7 \n\t" /* xmm7 = c2 * i2 + c6 * i6 = G */ \ - "movdqa %%xmm6, "I(2)" \n\t" /* Save D. at I(2) */ \ - "movdqa %%xmm0, %%xmm2 \n\t" /* xmm2 = A - C */ \ - "movdqa "I(0)", %%xmm6 \n\t" /* xmm6 = i0 */ \ - "pmulhw %%xmm4, %%xmm0 \n\t" /* xmm0 = ( c4 - 1 ) * ( A - C ) = A. */ \ - "paddw %%xmm3, %%xmm5 \n\t" /* xmm5 = c4 * ( B - D ) = B. */ \ - "movdqa "I(4)", %%xmm3 \n\t" /* xmm3 = i4 */ \ - "psubsw %%xmm1, %%xmm5 \n\t" /* xmm5 = B. - H = B.. */ \ - "paddw %%xmm0, %%xmm2 \n\t" /* xmm2 = c4 * ( A - C) = A. */ \ - "psubsw %%xmm3, %%xmm6 \n\t" /* xmm6 = i0 - i4 */ \ - "movdqa %%xmm6, %%xmm0 \n\t" /* xmm0 = i0 - i4 */ \ - "pmulhw %%xmm4, %%xmm6 \n\t" /* xmm6 = (c4 - 1) * (i0 - i4) = F */ \ - "paddsw %%xmm3, %%xmm3 \n\t" /* xmm3 = i4 + i4 */ \ - "paddsw %%xmm1, %%xmm1 \n\t" /* xmm1 = H + H */ \ - "paddsw %%xmm0, %%xmm3 \n\t" /* xmm3 = i0 + i4 */ \ - "paddsw %%xmm5, %%xmm1 \n\t" /* xmm1 = B. + H = H. */ \ - "pmulhw %%xmm3, %%xmm4 \n\t" /* xmm4 = ( c4 - 1 ) * ( i0 + i4 ) */ \ - "paddw %%xmm0, %%xmm6 \n\t" /* xmm6 = c4 * ( i0 - i4 ) */ \ - "psubsw %%xmm2, %%xmm6 \n\t" /* xmm6 = F - A. = F. */ \ - "paddsw %%xmm2, %%xmm2 \n\t" /* xmm2 = A. + A. */ \ - "movdqa "I(1)", %%xmm0 \n\t" /* Load C. from I(1) */ \ - "paddsw %%xmm6, %%xmm2 \n\t" /* xmm2 = F + A. = A.. */ \ - "paddw %%xmm3, %%xmm4 \n\t" /* xmm4 = c4 * ( i0 + i4 ) = 3 */ \ - "psubsw %%xmm1, %%xmm2 \n\t" /* xmm2 = A.. - H. = R2 */ \ - ADD(%%xmm2) /* Adjust R2 and R1 before shifting */ \ - "paddsw %%xmm1, %%xmm1 \n\t" /* xmm1 = H. + H. */ \ - "paddsw %%xmm2, %%xmm1 \n\t" /* xmm1 = A.. + H. = R1 */ \ - SHIFT(%%xmm2) /* xmm2 = op2 */ \ - "psubsw %%xmm7, %%xmm4 \n\t" /* xmm4 = E - G = E. */ \ - SHIFT(%%xmm1) /* xmm1 = op1 */ \ - "movdqa "I(2)", %%xmm3 \n\t" /* Load D. from I(2) */ \ - "paddsw %%xmm7, %%xmm7 \n\t" /* xmm7 = G + G */ \ - "paddsw %%xmm4, %%xmm7 \n\t" /* xmm7 = E + G = G. */ \ - "psubsw %%xmm3, %%xmm4 \n\t" /* xmm4 = E. - D. = R4 */ \ - ADD(%%xmm4) /* Adjust R4 and R3 before shifting */ \ - "paddsw %%xmm3, %%xmm3 \n\t" /* xmm3 = D. + D. */ \ - "paddsw %%xmm4, %%xmm3 \n\t" /* xmm3 = E. + D. = R3 */ \ - SHIFT(%%xmm4) /* xmm4 = op4 */ \ - "psubsw %%xmm5, %%xmm6 \n\t" /* xmm6 = F. - B..= R6 */ \ - SHIFT(%%xmm3) /* xmm3 = op3 */ \ - ADD(%%xmm6) /* Adjust R6 and R5 before shifting */ \ - "paddsw %%xmm5, %%xmm5 \n\t" /* xmm5 = B.. + B.. */ \ - "paddsw %%xmm6, %%xmm5 \n\t" /* xmm5 = F. + B.. = R5 */ \ - SHIFT(%%xmm6) /* xmm6 = op6 */ \ - SHIFT(%%xmm5) /* xmm5 = op5 */ \ - "psubsw %%xmm0, %%xmm7 \n\t" /* xmm7 = G. - C. = R7 */ \ - ADD(%%xmm7) /* Adjust R7 and R0 before shifting */ \ - "paddsw %%xmm0, %%xmm0 \n\t" /* xmm0 = C. + C. */ \ - "paddsw %%xmm7, %%xmm0 \n\t" /* xmm0 = G. + C. */ \ - SHIFT(%%xmm7) /* xmm7 = op7 */ \ - SHIFT(%%xmm0) /* xmm0 = op0 */ - -#define PUT_BLOCK(r0, r1, r2, r3, r4, r5, r6, r7) \ - "movdqa " #r0 ", " O(0) "\n\t" \ - "movdqa " #r1 ", " O(1) "\n\t" \ - "movdqa " #r2 ", " O(2) "\n\t" \ - "movdqa " #r3 ", " O(3) "\n\t" \ - "movdqa " #r4 ", " O(4) "\n\t" \ - "movdqa " #r5 ", " O(5) "\n\t" \ - "movdqa " #r6 ", " O(6) "\n\t" \ - "movdqa " #r7 ", " O(7) "\n\t" - -#define NOP(xmm) -#define SHIFT4(xmm) "psraw $4, "#xmm"\n\t" -#define ADD8(xmm) "paddsw %2, "#xmm"\n\t" - -void ff_vp3_idct_sse2(int16_t *input_data) -{ -#define I(x) AV_STRINGIFY(16*x)"(%0)" -#define O(x) I(x) -#define C(x) AV_STRINGIFY(16*(x-1))"(%1)" - - __asm__ volatile ( - VP3_1D_IDCT_SSE2(NOP, NOP) - - TRANSPOSE8(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm6, %%xmm7, (%0)) - PUT_BLOCK(%%xmm0, %%xmm5, %%xmm7, %%xmm3, %%xmm6, %%xmm4, %%xmm2, %%xmm1) - - VP3_1D_IDCT_SSE2(ADD8, SHIFT4) - PUT_BLOCK(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm6, %%xmm7) - :: "r"(input_data), "r"(ff_vp3_idct_data), "m"(ff_pw_8) - ); -} - -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); -} - -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); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.h b/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.h deleted file mode 100644 index 9094620..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp3dsp_sse2.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * vp3dsp SSE2 function declarations - * Copyright (c) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_VP3DSP_SSE2_H -#define AVCODEC_X86_VP3DSP_SSE2_H - -#include "libavcodec/dsputil.h" - -void ff_vp3_idct_sse2(int16_t *input_data); -void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block); -void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block); - -#endif /* AVCODEC_X86_VP3DSP_SSE2_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.c b/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.c deleted file mode 100644 index 905b3a7..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.c +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file - * MMX-optimized functions for the VP6 decoder - * - * Copyright (C) 2009 Sebastien Lucas - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "dsputil_mmx.h" -#include "vp6dsp_mmx.h" - - -#define DIAG4_MMX(in1,in2,in3,in4) \ - "movq "#in1"(%0), %%mm0 \n\t" \ - "movq "#in2"(%0), %%mm1 \n\t" \ - "movq %%mm0, %%mm3 \n\t" \ - "movq %%mm1, %%mm4 \n\t" \ - "punpcklbw %%mm7, %%mm0 \n\t" \ - "punpcklbw %%mm7, %%mm1 \n\t" \ - "punpckhbw %%mm7, %%mm3 \n\t" \ - "punpckhbw %%mm7, %%mm4 \n\t" \ - "pmullw 0(%2), %%mm0 \n\t" /* src[x-8 ] * biweight [0] */ \ - "pmullw 8(%2), %%mm1 \n\t" /* src[x ] * biweight [1] */ \ - "pmullw 0(%2), %%mm3 \n\t" /* src[x-8 ] * biweight [0] */ \ - "pmullw 8(%2), %%mm4 \n\t" /* src[x ] * biweight [1] */ \ - "paddw %%mm1, %%mm0 \n\t" \ - "paddw %%mm4, %%mm3 \n\t" \ - "movq "#in3"(%0), %%mm1 \n\t" \ - "movq "#in4"(%0), %%mm2 \n\t" \ - "movq %%mm1, %%mm4 \n\t" \ - "movq %%mm2, %%mm5 \n\t" \ - "punpcklbw %%mm7, %%mm1 \n\t" \ - "punpcklbw %%mm7, %%mm2 \n\t" \ - "punpckhbw %%mm7, %%mm4 \n\t" \ - "punpckhbw %%mm7, %%mm5 \n\t" \ - "pmullw 16(%2), %%mm1 \n\t" /* src[x+8 ] * biweight [2] */ \ - "pmullw 24(%2), %%mm2 \n\t" /* src[x+16] * biweight [3] */ \ - "pmullw 16(%2), %%mm4 \n\t" /* src[x+8 ] * biweight [2] */ \ - "pmullw 24(%2), %%mm5 \n\t" /* src[x+16] * biweight [3] */ \ - "paddw %%mm2, %%mm1 \n\t" \ - "paddw %%mm5, %%mm4 \n\t" \ - "paddsw %%mm1, %%mm0 \n\t" \ - "paddsw %%mm4, %%mm3 \n\t" \ - "paddsw %%mm6, %%mm0 \n\t" /* Add 64 */ \ - "paddsw %%mm6, %%mm3 \n\t" /* Add 64 */ \ - "psraw $7, %%mm0 \n\t" \ - "psraw $7, %%mm3 \n\t" \ - "packuswb %%mm3, %%mm0 \n\t" \ - "movq %%mm0, (%1) \n\t" - -void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights, const int16_t *v_weights) -{ - uint8_t tmp[8*11], *t = tmp; - int16_t weights[4*4]; - int i; - src -= stride; - - for (i=0; i<4*4; i++) - weights[i] = h_weights[i>>2]; - - __asm__ volatile( - "pxor %%mm7, %%mm7 \n\t" - "movq "MANGLE(ff_pw_64)", %%mm6 \n\t" - "1: \n\t" - DIAG4_MMX(-1,0,1,2) - "add $8, %1 \n\t" - "add %3, %0 \n\t" - "decl %4 \n\t" - "jnz 1b \n\t" - : "+r"(src), "+r"(t) - : "r"(weights), "r"((x86_reg)stride), "r"(11) - : "memory"); - - t = tmp + 8; - for (i=0; i<4*4; i++) - weights[i] = v_weights[i>>2]; - - __asm__ volatile( - "pxor %%mm7, %%mm7 \n\t" - "movq "MANGLE(ff_pw_64)", %%mm6 \n\t" - "1: \n\t" - DIAG4_MMX(-8,0,8,16) - "add $8, %0 \n\t" - "add %3, %1 \n\t" - "decl %4 \n\t" - "jnz 1b \n\t" - : "+r"(t), "+r"(dst) - : "r"(weights), "r"((x86_reg)stride), "r"(8) - : "memory"); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.h b/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.h deleted file mode 100644 index 743bc43..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_mmx.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * vp6dsp MMX function declarations - * Copyright (c) 2009 Sebastien Lucas - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_VP6DSP_MMX_H -#define AVCODEC_X86_VP6DSP_MMX_H - -#include - -void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights,const int16_t *v_weights); - -#endif /* AVCODEC_X86_VP6DSP_MMX_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.c b/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.c deleted file mode 100644 index bfd733a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.c +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file - * SSE2-optimized functions for the VP6 decoder - * - * Copyright (C) 2009 Zuxy Meng - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "dsputil_mmx.h" -#include "vp6dsp_sse2.h" - -#define DIAG4_SSE2(in1,in2,in3,in4) \ - "movq "#in1"(%0), %%xmm0 \n\t" \ - "movq "#in2"(%0), %%xmm1 \n\t" \ - "punpcklbw %%xmm7, %%xmm0 \n\t" \ - "punpcklbw %%xmm7, %%xmm1 \n\t" \ - "pmullw %%xmm4, %%xmm0 \n\t" /* src[x-8 ] * biweight [0] */ \ - "pmullw %%xmm5, %%xmm1 \n\t" /* src[x ] * biweight [1] */ \ - "paddw %%xmm1, %%xmm0 \n\t" \ - "movq "#in3"(%0), %%xmm1 \n\t" \ - "movq "#in4"(%0), %%xmm2 \n\t" \ - "punpcklbw %%xmm7, %%xmm1 \n\t" \ - "punpcklbw %%xmm7, %%xmm2 \n\t" \ - "pmullw %%xmm6, %%xmm1 \n\t" /* src[x+8 ] * biweight [2] */ \ - "pmullw %%xmm3, %%xmm2 \n\t" /* src[x+16] * biweight [3] */ \ - "paddw %%xmm2, %%xmm1 \n\t" \ - "paddsw %%xmm1, %%xmm0 \n\t" \ - "paddsw "MANGLE(ff_pw_64)", %%xmm0 \n\t" /* Add 64 */ \ - "psraw $7, %%xmm0 \n\t" \ - "packuswb %%xmm0, %%xmm0 \n\t" \ - "movq %%xmm0, (%1) \n\t" \ - -void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights,const int16_t *v_weights) -{ - uint8_t tmp[8*11], *t = tmp; - src -= stride; - - __asm__ volatile( - "pxor %%xmm7, %%xmm7 \n\t" - "movq %4, %%xmm3 \n\t" - "pshuflw $0, %%xmm3, %%xmm4 \n\t" - "punpcklqdq %%xmm4, %%xmm4 \n\t" - "pshuflw $85, %%xmm3, %%xmm5 \n\t" - "punpcklqdq %%xmm5, %%xmm5 \n\t" - "pshuflw $170, %%xmm3, %%xmm6 \n\t" - "punpcklqdq %%xmm6, %%xmm6 \n\t" - "pshuflw $255, %%xmm3, %%xmm3 \n\t" - "punpcklqdq %%xmm3, %%xmm3 \n\t" - "1: \n\t" - DIAG4_SSE2(-1,0,1,2) - "add $8, %1 \n\t" - "add %2, %0 \n\t" - "decl %3 \n\t" - "jnz 1b \n\t" - : "+r"(src), "+r"(t) - : "g"((x86_reg)stride), "r"(11), "m"(*(const int64_t*)h_weights) - : "memory"); - - t = tmp + 8; - - __asm__ volatile( - "movq %4, %%xmm3 \n\t" - "pshuflw $0, %%xmm3, %%xmm4 \n\t" - "punpcklqdq %%xmm4, %%xmm4 \n\t" - "pshuflw $85, %%xmm3, %%xmm5 \n\t" - "punpcklqdq %%xmm5, %%xmm5 \n\t" - "pshuflw $170, %%xmm3, %%xmm6 \n\t" - "punpcklqdq %%xmm6, %%xmm6 \n\t" - "pshuflw $255, %%xmm3, %%xmm3 \n\t" - "punpcklqdq %%xmm3, %%xmm3 \n\t" - "1: \n\t" - DIAG4_SSE2(-8,0,8,16) - "add $8, %0 \n\t" - "add %2, %1 \n\t" - "decl %3 \n\t" - "jnz 1b \n\t" - : "+r"(t), "+r"(dst) - : "g"((x86_reg)stride), "r"(8), "m"(*(const int64_t*)v_weights) - : "memory"); -} diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.h b/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.h deleted file mode 100644 index a30089a..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/vp6dsp_sse2.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * vp6dsp SSE2 function declarations - * Copyright (c) 2009 Zuxy Meng - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_X86_VP6DSP_SSE2_H -#define AVCODEC_X86_VP6DSP_SSE2_H - -#include - -void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, int stride, - const int16_t *h_weights,const int16_t *v_weights); - -#endif /* AVCODEC_X86_VP6DSP_SSE2_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/x86inc.asm b/tizen/distrib/ffmpeg/libavcodec/x86/x86inc.asm deleted file mode 100644 index c29ef3e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/x86inc.asm +++ /dev/null @@ -1,625 +0,0 @@ -;***************************************************************************** -;* x86inc.asm -;***************************************************************************** -;* Copyright (C) 2005-2008 Loren Merritt -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg 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.1 of the License, or (at your option) any later version. -;* -;* FFmpeg 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 FFmpeg; if not, write to the Free Software -;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;***************************************************************************** - -%ifdef ARCH_X86_64 - %ifidn __OUTPUT_FORMAT__,win32 - %define WIN64 - %else - %define UNIX64 - %endif -%endif - -; FIXME: All of the 64bit asm functions that take a stride as an argument -; via register, assume that the high dword of that register is filled with 0. -; This is true in practice (since we never do any 64bit arithmetic on strides, -; and x264's strides are all positive), but is not guaranteed by the ABI. - -; Name of the .rodata section. -; Kludge: Something on OS X fails to align .rodata even given an align attribute, -; so use a different read-only section. -%macro SECTION_RODATA 0-1 16 - %ifidn __OUTPUT_FORMAT__,macho64 - SECTION .text align=%1 - %elifidn __OUTPUT_FORMAT__,macho - SECTION .text align=%1 - fakegot: - %else - SECTION .rodata align=%1 - %endif -%endmacro - -; PIC support macros. -; x86_64 can't fit 64bit address literals in most instruction types, -; so shared objects (under the assumption that they might be anywhere -; in memory) must use an address mode that does fit. -; So all accesses to global variables must use this macro, e.g. -; mov eax, [foo GLOBAL] -; instead of -; mov eax, [foo] -; -; x86_32 doesn't require PIC. -; Some distros prefer shared objects to be PIC, but nothing breaks if -; the code contains a few textrels, so we'll skip that complexity. - -%ifdef WIN64 - %define PIC -%elifndef ARCH_X86_64 - %undef PIC -%endif -%ifdef PIC - %define GLOBAL wrt rip -%else - %define GLOBAL -%endif - -; Macros to eliminate most code duplication between x86_32 and x86_64: -; Currently this works only for leaf functions which load all their arguments -; into registers at the start, and make no other use of the stack. Luckily that -; covers most of x264's asm. - -; PROLOGUE: -; %1 = number of arguments. loads them from stack if needed. -; %2 = number of registers used. pushes callee-saved regs if needed. -; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed. -; %4 = list of names to define to registers -; PROLOGUE can also be invoked by adding the same options to cglobal - -; e.g. -; cglobal foo, 2,3,0, dst, src, tmp -; declares a function (foo), taking two args (dst and src) and one local variable (tmp) - -; TODO Some functions can use some args directly from the stack. If they're the -; last args then you can just not declare them, but if they're in the middle -; we need more flexible macro. - -; RET: -; Pops anything that was pushed by PROLOGUE - -; REP_RET: -; Same, but if it doesn't pop anything it becomes a 2-byte ret, for athlons -; which are slow when a normal ret follows a branch. - -; registers: -; rN and rNq are the native-size register holding function argument N -; rNd, rNw, rNb are dword, word, and byte size -; rNm is the original location of arg N (a register or on the stack), dword -; rNmp is native size - -%macro DECLARE_REG 6 - %define r%1q %2 - %define r%1d %3 - %define r%1w %4 - %define r%1b %5 - %define r%1m %6 - %ifid %6 ; i.e. it's a register - %define r%1mp %2 - %elifdef ARCH_X86_64 ; memory - %define r%1mp qword %6 - %else - %define r%1mp dword %6 - %endif - %define r%1 %2 -%endmacro - -%macro DECLARE_REG_SIZE 2 - %define r%1q r%1 - %define e%1q r%1 - %define r%1d e%1 - %define e%1d e%1 - %define r%1w %1 - %define e%1w %1 - %define r%1b %2 - %define e%1b %2 -%ifndef ARCH_X86_64 - %define r%1 e%1 -%endif -%endmacro - -DECLARE_REG_SIZE ax, al -DECLARE_REG_SIZE bx, bl -DECLARE_REG_SIZE cx, cl -DECLARE_REG_SIZE dx, dl -DECLARE_REG_SIZE si, sil -DECLARE_REG_SIZE di, dil -DECLARE_REG_SIZE bp, bpl - -; t# defines for when per-arch register allocation is more complex than just function arguments - -%macro DECLARE_REG_TMP 1-* - %assign %%i 0 - %rep %0 - CAT_XDEFINE t, %%i, r%1 - %assign %%i %%i+1 - %rotate 1 - %endrep -%endmacro - -%macro DECLARE_REG_TMP_SIZE 0-* - %rep %0 - %define t%1q t%1 %+ q - %define t%1d t%1 %+ d - %define t%1w t%1 %+ w - %define t%1b t%1 %+ b - %rotate 1 - %endrep -%endmacro - -DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7 - -%ifdef ARCH_X86_64 - %define gprsize 8 -%else - %define gprsize 4 -%endif - -%macro PUSH 1 - push %1 - %assign stack_offset stack_offset+gprsize -%endmacro - -%macro POP 1 - pop %1 - %assign stack_offset stack_offset-gprsize -%endmacro - -%macro SUB 2 - sub %1, %2 - %ifidn %1, rsp - %assign stack_offset stack_offset+(%2) - %endif -%endmacro - -%macro ADD 2 - add %1, %2 - %ifidn %1, rsp - %assign stack_offset stack_offset-(%2) - %endif -%endmacro - -%macro movifnidn 2 - %ifnidn %1, %2 - mov %1, %2 - %endif -%endmacro - -%macro movsxdifnidn 2 - %ifnidn %1, %2 - movsxd %1, %2 - %endif -%endmacro - -%macro ASSERT 1 - %if (%1) == 0 - %error assert failed - %endif -%endmacro - -%macro DEFINE_ARGS 0-* - %ifdef n_arg_names - %assign %%i 0 - %rep n_arg_names - CAT_UNDEF arg_name %+ %%i, q - CAT_UNDEF arg_name %+ %%i, d - CAT_UNDEF arg_name %+ %%i, w - CAT_UNDEF arg_name %+ %%i, b - CAT_UNDEF arg_name %+ %%i, m - CAT_UNDEF arg_name, %%i - %assign %%i %%i+1 - %endrep - %endif - - %assign %%i 0 - %rep %0 - %xdefine %1q r %+ %%i %+ q - %xdefine %1d r %+ %%i %+ d - %xdefine %1w r %+ %%i %+ w - %xdefine %1b r %+ %%i %+ b - %xdefine %1m r %+ %%i %+ m - CAT_XDEFINE arg_name, %%i, %1 - %assign %%i %%i+1 - %rotate 1 - %endrep - %assign n_arg_names %%i -%endmacro - -%ifdef WIN64 ; Windows x64 ;================================================= - -DECLARE_REG 0, rcx, ecx, cx, cl, ecx -DECLARE_REG 1, rdx, edx, dx, dl, edx -DECLARE_REG 2, r8, r8d, r8w, r8b, r8d -DECLARE_REG 3, r9, r9d, r9w, r9b, r9d -DECLARE_REG 4, rdi, edi, di, dil, [rsp + stack_offset + 40] -DECLARE_REG 5, rsi, esi, si, sil, [rsp + stack_offset + 48] -DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 56] -%define r7m [rsp + stack_offset + 64] -%define r8m [rsp + stack_offset + 72] - -%macro LOAD_IF_USED 2 ; reg_id, number_of_args - %if %1 < %2 - mov r%1, [rsp + stack_offset + 8 + %1*8] - %endif -%endmacro - -%macro PROLOGUE 2-4+ ; #args, #regs, #xmm_regs, arg_names... - ASSERT %2 >= %1 - %assign regs_used %2 - ASSERT regs_used <= 7 - %if %0 > 2 - %assign xmm_regs_used %3 - %else - %assign xmm_regs_used 0 - %endif - ASSERT xmm_regs_used <= 16 - %if regs_used > 4 - push r4 - push r5 - %assign stack_offset stack_offset+16 - %endif - %if xmm_regs_used > 6 - sub rsp, (xmm_regs_used-6)*16+16 - %assign stack_offset stack_offset+(xmm_regs_used-6)*16+16 - %assign %%i xmm_regs_used - %rep (xmm_regs_used-6) - %assign %%i %%i-1 - movdqa [rsp + (%%i-6)*16+8], xmm %+ %%i - %endrep - %endif - LOAD_IF_USED 4, %1 - LOAD_IF_USED 5, %1 - LOAD_IF_USED 6, %1 - DEFINE_ARGS %4 -%endmacro - -%macro RESTORE_XMM_INTERNAL 1 - %if xmm_regs_used > 6 - %assign %%i xmm_regs_used - %rep (xmm_regs_used-6) - %assign %%i %%i-1 - movdqa xmm %+ %%i, [%1 + (%%i-6)*16+8] - %endrep - add %1, (xmm_regs_used-6)*16+16 - %endif -%endmacro - -%macro RESTORE_XMM 1 - RESTORE_XMM_INTERNAL %1 - %assign stack_offset stack_offset-(xmm_regs_used-6)*16+16 - %assign xmm_regs_used 0 -%endmacro - -%macro RET 0 - RESTORE_XMM_INTERNAL rsp - %if regs_used > 4 - pop r5 - pop r4 - %endif - ret -%endmacro - -%macro REP_RET 0 - %if regs_used > 4 || xmm_regs_used > 6 - RET - %else - rep ret - %endif -%endmacro - -%elifdef ARCH_X86_64 ; *nix x64 ;============================================= - -DECLARE_REG 0, rdi, edi, di, dil, edi -DECLARE_REG 1, rsi, esi, si, sil, esi -DECLARE_REG 2, rdx, edx, dx, dl, edx -DECLARE_REG 3, rcx, ecx, cx, cl, ecx -DECLARE_REG 4, r8, r8d, r8w, r8b, r8d -DECLARE_REG 5, r9, r9d, r9w, r9b, r9d -DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 8] -%define r7m [rsp + stack_offset + 16] -%define r8m [rsp + stack_offset + 24] - -%macro LOAD_IF_USED 2 ; reg_id, number_of_args - %if %1 < %2 - mov r%1, [rsp - 40 + %1*8] - %endif -%endmacro - -%macro PROLOGUE 2-4+ ; #args, #regs, #xmm_regs, arg_names... - ASSERT %2 >= %1 - ASSERT %2 <= 7 - LOAD_IF_USED 6, %1 - DEFINE_ARGS %4 -%endmacro - -%macro RET 0 - ret -%endmacro - -%macro REP_RET 0 - rep ret -%endmacro - -%else ; X86_32 ;============================================================== - -DECLARE_REG 0, eax, eax, ax, al, [esp + stack_offset + 4] -DECLARE_REG 1, ecx, ecx, cx, cl, [esp + stack_offset + 8] -DECLARE_REG 2, edx, edx, dx, dl, [esp + stack_offset + 12] -DECLARE_REG 3, ebx, ebx, bx, bl, [esp + stack_offset + 16] -DECLARE_REG 4, esi, esi, si, null, [esp + stack_offset + 20] -DECLARE_REG 5, edi, edi, di, null, [esp + stack_offset + 24] -DECLARE_REG 6, ebp, ebp, bp, null, [esp + stack_offset + 28] -%define r7m [esp + stack_offset + 32] -%define r8m [esp + stack_offset + 36] -%define rsp esp - -%macro PUSH_IF_USED 1 ; reg_id - %if %1 < regs_used - push r%1 - %assign stack_offset stack_offset+4 - %endif -%endmacro - -%macro POP_IF_USED 1 ; reg_id - %if %1 < regs_used - pop r%1 - %endif -%endmacro - -%macro LOAD_IF_USED 2 ; reg_id, number_of_args - %if %1 < %2 - mov r%1, [esp + stack_offset + 4 + %1*4] - %endif -%endmacro - -%macro PROLOGUE 2-4+ ; #args, #regs, arg_names... - ASSERT %2 >= %1 - %assign regs_used %2 - ASSERT regs_used <= 7 - PUSH_IF_USED 3 - PUSH_IF_USED 4 - PUSH_IF_USED 5 - PUSH_IF_USED 6 - LOAD_IF_USED 0, %1 - LOAD_IF_USED 1, %1 - LOAD_IF_USED 2, %1 - LOAD_IF_USED 3, %1 - LOAD_IF_USED 4, %1 - LOAD_IF_USED 5, %1 - LOAD_IF_USED 6, %1 - DEFINE_ARGS %4 -%endmacro - -%macro RET 0 - POP_IF_USED 6 - POP_IF_USED 5 - POP_IF_USED 4 - POP_IF_USED 3 - ret -%endmacro - -%macro REP_RET 0 - %if regs_used > 3 - RET - %else - rep ret - %endif -%endmacro - -%endif ;====================================================================== - - - -;============================================================================= -; arch-independent part -;============================================================================= - -%assign function_align 16 - -; Symbol prefix for C linkage -%macro cglobal 1-2+ - %xdefine %1 ff_%1 - %ifdef PREFIX - %xdefine %1 _ %+ %1 - %endif - %xdefine %1.skip_prologue %1 %+ .skip_prologue - %ifidn __OUTPUT_FORMAT__,elf - global %1:function hidden - %else - global %1 - %endif - align function_align - %1: - RESET_MM_PERMUTATION ; not really needed, but makes disassembly somewhat nicer - %assign stack_offset 0 - %if %0 > 1 - PROLOGUE %2 - %endif -%endmacro - -%macro cextern 1 - %ifdef PREFIX - %xdefine %1 _%1 - %endif - extern %1 -%endmacro - -; This is needed for ELF, otherwise the GNU linker assumes the stack is -; executable by default. -%ifidn __OUTPUT_FORMAT__,elf -SECTION .note.GNU-stack noalloc noexec nowrite progbits -%endif - -%assign FENC_STRIDE 16 -%assign FDEC_STRIDE 32 - -; merge mmx and sse* - -%macro CAT_XDEFINE 3 - %xdefine %1%2 %3 -%endmacro - -%macro CAT_UNDEF 2 - %undef %1%2 -%endmacro - -%macro INIT_MMX 0 - %define RESET_MM_PERMUTATION INIT_MMX - %define mmsize 8 - %define num_mmregs 8 - %define mova movq - %define movu movq - %define movh movd - %define movnt movntq - %assign %%i 0 - %rep 8 - CAT_XDEFINE m, %%i, mm %+ %%i - CAT_XDEFINE nmm, %%i, %%i - %assign %%i %%i+1 - %endrep - %rep 8 - CAT_UNDEF m, %%i - CAT_UNDEF nmm, %%i - %assign %%i %%i+1 - %endrep -%endmacro - -%macro INIT_XMM 0 - %define RESET_MM_PERMUTATION INIT_XMM - %define mmsize 16 - %define num_mmregs 8 - %ifdef ARCH_X86_64 - %define num_mmregs 16 - %endif - %define mova movdqa - %define movu movdqu - %define movh movq - %define movnt movntdq - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE m, %%i, xmm %+ %%i - CAT_XDEFINE nxmm, %%i, %%i - %assign %%i %%i+1 - %endrep -%endmacro - -INIT_MMX - -; I often want to use macros that permute their arguments. e.g. there's no -; efficient way to implement butterfly or transpose or dct without swapping some -; arguments. -; -; I would like to not have to manually keep track of the permutations: -; If I insert a permutation in the middle of a function, it should automatically -; change everything that follows. For more complex macros I may also have multiple -; implementations, e.g. the SSE2 and SSSE3 versions may have different permutations. -; -; Hence these macros. Insert a PERMUTE or some SWAPs at the end of a macro that -; permutes its arguments. It's equivalent to exchanging the contents of the -; registers, except that this way you exchange the register names instead, so it -; doesn't cost any cycles. - -%macro PERMUTE 2-* ; takes a list of pairs to swap -%rep %0/2 - %xdefine tmp%2 m%2 - %xdefine ntmp%2 nm%2 - %rotate 2 -%endrep -%rep %0/2 - %xdefine m%1 tmp%2 - %xdefine nm%1 ntmp%2 - %undef tmp%2 - %undef ntmp%2 - %rotate 2 -%endrep -%endmacro - -%macro SWAP 2-* ; swaps a single chain (sometimes more concise than pairs) -%rep %0-1 -%ifdef m%1 - %xdefine tmp m%1 - %xdefine m%1 m%2 - %xdefine m%2 tmp - CAT_XDEFINE n, m%1, %1 - CAT_XDEFINE n, m%2, %2 -%else - ; If we were called as "SWAP m0,m1" rather than "SWAP 0,1" infer the original numbers here. - ; Be careful using this mode in nested macros though, as in some cases there may be - ; other copies of m# that have already been dereferenced and don't get updated correctly. - %xdefine %%n1 n %+ %1 - %xdefine %%n2 n %+ %2 - %xdefine tmp m %+ %%n1 - CAT_XDEFINE m, %%n1, m %+ %%n2 - CAT_XDEFINE m, %%n2, tmp - CAT_XDEFINE n, m %+ %%n1, %%n1 - CAT_XDEFINE n, m %+ %%n2, %%n2 -%endif - %undef tmp - %rotate 1 -%endrep -%endmacro - -%macro SAVE_MM_PERMUTATION 1 - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE %1_m, %%i, m %+ %%i - %assign %%i %%i+1 - %endrep -%endmacro - -%macro LOAD_MM_PERMUTATION 1 - %assign %%i 0 - %rep num_mmregs - CAT_XDEFINE m, %%i, %1_m %+ %%i - CAT_XDEFINE n, m %+ %%i, %%i - %assign %%i %%i+1 - %endrep -%endmacro - -%macro call 1 - call %1 - %ifdef %1_m0 - LOAD_MM_PERMUTATION %1 - %endif -%endmacro - -;Substitutions that reduce instruction size but are functionally equivalent -%macro add 2 - %ifnum %2 - %if %2==128 - sub %1, -128 - %else - add %1, %2 - %endif - %else - add %1, %2 - %endif -%endmacro - -%macro sub 2 - %ifnum %2 - %if %2==128 - add %1, -128 - %else - sub %1, %2 - %endif - %else - sub %1, %2 - %endif -%endmacro diff --git a/tizen/distrib/ffmpeg/libavcodec/x86/x86util.asm b/tizen/distrib/ffmpeg/libavcodec/x86/x86util.asm deleted file mode 100644 index f3e0e2d..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/x86/x86util.asm +++ /dev/null @@ -1,515 +0,0 @@ -;***************************************************************************** -;* x86util.asm -;***************************************************************************** -;* Copyright (C) 2008 Loren Merritt -;* -;* 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 02111, USA. -;***************************************************************************** - -%macro SBUTTERFLY 4 - mova m%4, m%2 - punpckl%1 m%2, m%3 - punpckh%1 m%4, m%3 - SWAP %3, %4 -%endmacro - -%macro TRANSPOSE4x4W 5 - SBUTTERFLY wd, %1, %2, %5 - SBUTTERFLY wd, %3, %4, %5 - SBUTTERFLY dq, %1, %3, %5 - SBUTTERFLY dq, %2, %4, %5 - SWAP %2, %3 -%endmacro - -%macro TRANSPOSE2x4x4W 5 - SBUTTERFLY wd, %1, %2, %5 - SBUTTERFLY wd, %3, %4, %5 - SBUTTERFLY dq, %1, %3, %5 - SBUTTERFLY dq, %2, %4, %5 - SBUTTERFLY qdq, %1, %2, %5 - SBUTTERFLY qdq, %3, %4, %5 -%endmacro - -%macro TRANSPOSE4x4D 5 - SBUTTERFLY dq, %1, %2, %5 - SBUTTERFLY dq, %3, %4, %5 - SBUTTERFLY qdq, %1, %3, %5 - SBUTTERFLY qdq, %2, %4, %5 - SWAP %2, %3 -%endmacro - -%macro TRANSPOSE8x8W 9-11 -%ifdef ARCH_X86_64 - SBUTTERFLY wd, %1, %2, %9 - SBUTTERFLY wd, %3, %4, %9 - SBUTTERFLY wd, %5, %6, %9 - SBUTTERFLY wd, %7, %8, %9 - SBUTTERFLY dq, %1, %3, %9 - SBUTTERFLY dq, %2, %4, %9 - SBUTTERFLY dq, %5, %7, %9 - SBUTTERFLY dq, %6, %8, %9 - SBUTTERFLY qdq, %1, %5, %9 - SBUTTERFLY qdq, %2, %6, %9 - SBUTTERFLY qdq, %3, %7, %9 - SBUTTERFLY qdq, %4, %8, %9 - SWAP %2, %5 - SWAP %4, %7 -%else -; in: m0..m7, unless %11 in which case m6 is in %9 -; out: m0..m7, unless %11 in which case m4 is in %10 -; spills into %9 and %10 -%if %0<11 - movdqa %9, m%7 -%endif - SBUTTERFLY wd, %1, %2, %7 - movdqa %10, m%2 - movdqa m%7, %9 - SBUTTERFLY wd, %3, %4, %2 - SBUTTERFLY wd, %5, %6, %2 - SBUTTERFLY wd, %7, %8, %2 - SBUTTERFLY dq, %1, %3, %2 - movdqa %9, m%3 - movdqa m%2, %10 - SBUTTERFLY dq, %2, %4, %3 - SBUTTERFLY dq, %5, %7, %3 - SBUTTERFLY dq, %6, %8, %3 - SBUTTERFLY qdq, %1, %5, %3 - SBUTTERFLY qdq, %2, %6, %3 - movdqa %10, m%2 - movdqa m%3, %9 - SBUTTERFLY qdq, %3, %7, %2 - SBUTTERFLY qdq, %4, %8, %2 - SWAP %2, %5 - SWAP %4, %7 -%if %0<11 - movdqa m%5, %10 -%endif -%endif -%endmacro - -%macro ABS1_MMX 2 ; a, tmp - pxor %2, %2 - psubw %2, %1 - pmaxsw %1, %2 -%endmacro - -%macro ABS2_MMX 4 ; a, b, tmp0, tmp1 - pxor %3, %3 - pxor %4, %4 - psubw %3, %1 - psubw %4, %2 - pmaxsw %1, %3 - pmaxsw %2, %4 -%endmacro - -%macro ABS1_SSSE3 2 - pabsw %1, %1 -%endmacro - -%macro ABS2_SSSE3 4 - pabsw %1, %1 - pabsw %2, %2 -%endmacro - -%define ABS1 ABS1_MMX -%define ABS2 ABS2_MMX - -%macro ABS4 6 - ABS2 %1, %2, %5, %6 - ABS2 %3, %4, %5, %6 -%endmacro - -%macro SPLATB_MMX 3 - movd %1, [%2-3] ;to avoid crossing a cacheline - punpcklbw %1, %1 -%if mmsize==16 - pshuflw %1, %1, 0xff - punpcklqdq %1, %1 -%else - pshufw %1, %1, 0xff -%endif -%endmacro - -%macro SPLATB_SSSE3 3 - movd %1, [%2-3] - pshufb %1, %3 -%endmacro - -%macro PALIGNR_MMX 4 - %ifnidn %4, %2 - mova %4, %2 - %endif - %if mmsize == 8 - psllq %1, (8-%3)*8 - psrlq %4, %3*8 - %else - pslldq %1, 16-%3 - psrldq %4, %3 - %endif - por %1, %4 -%endmacro - -%macro PALIGNR_SSSE3 4 - palignr %1, %2, %3 -%endmacro - -%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from -%ifnum %5 - mova m%1, m%5 - mova m%3, m%5 -%else - mova m%1, %5 - mova m%3, m%1 -%endif - pand m%1, m%2 ; dst .. y6 .. y4 - pand m%3, m%4 ; src .. y6 .. y4 - psrlw m%2, 8 ; dst .. y7 .. y5 - psrlw m%4, 8 ; src .. y7 .. y5 -%endmacro - -%macro SUMSUB_BA 2-3 -%if %0==2 - paddw %1, %2 - paddw %2, %2 - psubw %2, %1 -%else - mova %3, %1 - paddw %1, %2 - psubw %2, %3 -%endif -%endmacro - -%macro SUMSUB_BADC 4-5 -%if %0==5 - SUMSUB_BA %1, %2, %5 - SUMSUB_BA %3, %4, %5 -%else - paddw %1, %2 - paddw %3, %4 - paddw %2, %2 - paddw %4, %4 - psubw %2, %1 - psubw %4, %3 -%endif -%endmacro - -%macro HADAMARD4_V 4+ - SUMSUB_BADC %1, %2, %3, %4 - SUMSUB_BADC %1, %3, %2, %4 -%endmacro - -%macro HADAMARD8_V 8+ - SUMSUB_BADC %1, %2, %3, %4 - SUMSUB_BADC %5, %6, %7, %8 - SUMSUB_BADC %1, %3, %2, %4 - SUMSUB_BADC %5, %7, %6, %8 - SUMSUB_BADC %1, %5, %2, %6 - SUMSUB_BADC %3, %7, %4, %8 -%endmacro - -%macro TRANS_SSE2 5-6 -; TRANSPOSE2x2 -; %1: transpose width (d/q) - use SBUTTERFLY qdq for dq -; %2: ord/unord (for compat with sse4, unused) -; %3/%4: source regs -; %5/%6: tmp regs -%ifidn %1, d -%define mask [mask_10 GLOBAL] -%define shift 16 -%elifidn %1, q -%define mask [mask_1100 GLOBAL] -%define shift 32 -%endif -%if %0==6 ; less dependency if we have two tmp - mova m%5, mask ; ff00 - mova m%6, m%4 ; x5x4 - psll%1 m%4, shift ; x4.. - pand m%6, m%5 ; x5.. - pandn m%5, m%3 ; ..x0 - psrl%1 m%3, shift ; ..x1 - por m%4, m%5 ; x4x0 - por m%3, m%6 ; x5x1 -%else ; more dependency, one insn less. sometimes faster, sometimes not - mova m%5, m%4 ; x5x4 - psll%1 m%4, shift ; x4.. - pxor m%4, m%3 ; (x4^x1)x0 - pand m%4, mask ; (x4^x1).. - pxor m%3, m%4 ; x4x0 - psrl%1 m%4, shift ; ..(x1^x4) - pxor m%5, m%4 ; x5x1 - SWAP %4, %3, %5 -%endif -%endmacro - -%macro TRANS_SSE4 5-6 ; see above -%ifidn %1, d - mova m%5, m%3 -%ifidn %2, ord - psrl%1 m%3, 16 -%endif - pblendw m%3, m%4, 10101010b - psll%1 m%4, 16 -%ifidn %2, ord - pblendw m%4, m%5, 01010101b -%else - psrl%1 m%5, 16 - por m%4, m%5 -%endif -%elifidn %1, q - mova m%5, m%3 - shufps m%3, m%4, 10001000b - shufps m%5, m%4, 11011101b - SWAP %4, %5 -%endif -%endmacro - -%macro HADAMARD 5-6 -; %1=distance in words (0 for vertical pass, 1/2/4 for horizontal passes) -; %2=sumsub/max/amax (sum and diff / maximum / maximum of absolutes) -; %3/%4: regs -; %5(%6): tmpregs -%if %1!=0 ; have to reorder stuff for horizontal op - %ifidn %2, sumsub - %define ORDER ord - ; sumsub needs order because a-b != b-a unless a=b - %else - %define ORDER unord - ; if we just max, order doesn't matter (allows pblendw+or in sse4) - %endif - %if %1==1 - TRANS d, ORDER, %3, %4, %5, %6 - %elif %1==2 - %if mmsize==8 - SBUTTERFLY dq, %3, %4, %5 - %else - TRANS q, ORDER, %3, %4, %5, %6 - %endif - %elif %1==4 - SBUTTERFLY qdq, %3, %4, %5 - %endif -%endif -%ifidn %2, sumsub - SUMSUB_BA m%3, m%4, m%5 -%else - %ifidn %2, amax - %if %0==6 - ABS2 m%3, m%4, m%5, m%6 - %else - ABS1 m%3, m%5 - ABS1 m%4, m%5 - %endif - %endif - pmaxsw m%3, m%4 -%endif -%endmacro - - -%macro HADAMARD2_2D 6-7 sumsub - HADAMARD 0, sumsub, %1, %2, %5 - HADAMARD 0, sumsub, %3, %4, %5 - SBUTTERFLY %6, %1, %2, %5 -%ifnum %7 - HADAMARD 0, amax, %1, %2, %5, %7 -%else - HADAMARD 0, %7, %1, %2, %5 -%endif - SBUTTERFLY %6, %3, %4, %5 -%ifnum %7 - HADAMARD 0, amax, %3, %4, %5, %7 -%else - HADAMARD 0, %7, %3, %4, %5 -%endif -%endmacro - -%macro HADAMARD4_2D 5-6 sumsub - HADAMARD2_2D %1, %2, %3, %4, %5, wd - HADAMARD2_2D %1, %3, %2, %4, %5, dq, %6 - SWAP %2, %3 -%endmacro - -%macro HADAMARD4_2D_SSE 5-6 sumsub - HADAMARD 0, sumsub, %1, %2, %5 ; 1st V row 0 + 1 - HADAMARD 0, sumsub, %3, %4, %5 ; 1st V row 2 + 3 - SBUTTERFLY wd, %1, %2, %5 ; %1: m0 1+0 %2: m1 1+0 - SBUTTERFLY wd, %3, %4, %5 ; %3: m0 3+2 %4: m1 3+2 - HADAMARD2_2D %1, %3, %2, %4, %5, dq - SBUTTERFLY qdq, %1, %2, %5 - HADAMARD 0, %6, %1, %2, %5 ; 2nd H m1/m0 row 0+1 - SBUTTERFLY qdq, %3, %4, %5 - HADAMARD 0, %6, %3, %4, %5 ; 2nd H m1/m0 row 2+3 -%endmacro - -%macro HADAMARD8_2D 9-10 sumsub - HADAMARD2_2D %1, %2, %3, %4, %9, wd - HADAMARD2_2D %5, %6, %7, %8, %9, wd - HADAMARD2_2D %1, %3, %2, %4, %9, dq - HADAMARD2_2D %5, %7, %6, %8, %9, dq - HADAMARD2_2D %1, %5, %3, %7, %9, qdq, %10 - HADAMARD2_2D %2, %6, %4, %8, %9, qdq, %10 -%ifnidn %10, amax - SWAP %2, %5 - SWAP %4, %7 -%endif -%endmacro - -%macro SUMSUB2_AB 3 - mova %3, %1 - paddw %1, %1 - paddw %1, %2 - psubw %3, %2 - psubw %3, %2 -%endmacro - -%macro SUMSUB2_BA 3 - mova m%3, m%1 - paddw m%1, m%2 - paddw m%1, m%2 - psubw m%2, m%3 - psubw m%2, m%3 -%endmacro - -%macro SUMSUBD2_AB 4 - mova %4, %1 - mova %3, %2 - psraw %2, 1 - psraw %1, 1 - paddw %2, %4 - psubw %1, %3 -%endmacro - -%macro DCT4_1D 5 -%ifnum %5 - SUMSUB_BADC m%4, m%1, m%3, m%2; m%5 - SUMSUB_BA m%3, m%4, m%5 - SUMSUB2_AB m%1, m%2, m%5 - SWAP %1, %3, %4, %5, %2 -%else - SUMSUB_BADC m%4, m%1, m%3, m%2 - SUMSUB_BA m%3, m%4 - mova [%5], m%2 - SUMSUB2_AB m%1, [%5], m%2 - SWAP %1, %3, %4, %2 -%endif -%endmacro - -%macro IDCT4_1D 5-6 -%ifnum %5 - SUMSUBD2_AB m%2, m%4, m%6, m%5 - SUMSUB_BA m%3, m%1, m%6 - SUMSUB_BADC m%4, m%3, m%2, m%1, m%6 -%else - SUMSUBD2_AB m%2, m%4, [%5], [%5+16] - SUMSUB_BA m%3, m%1 - SUMSUB_BADC m%4, m%3, m%2, m%1 -%endif - SWAP %1, %4, %3 -%endmacro - -%macro LOAD_DIFF 5 -%ifidn %3, none - movh %1, %4 - movh %2, %5 - punpcklbw %1, %2 - punpcklbw %2, %2 - psubw %1, %2 -%else - movh %1, %4 - punpcklbw %1, %3 - movh %2, %5 - punpcklbw %2, %3 - psubw %1, %2 -%endif -%endmacro - -%macro LOAD_DIFF8x4_SSE2 8 - LOAD_DIFF m%1, m%5, m%6, [%7+%1*FENC_STRIDE], [%8+%1*FDEC_STRIDE] - LOAD_DIFF m%2, m%5, m%6, [%7+%2*FENC_STRIDE], [%8+%2*FDEC_STRIDE] - LOAD_DIFF m%3, m%5, m%6, [%7+%3*FENC_STRIDE], [%8+%3*FDEC_STRIDE] - LOAD_DIFF m%4, m%5, m%6, [%7+%4*FENC_STRIDE], [%8+%4*FDEC_STRIDE] -%endmacro - -%macro LOAD_DIFF8x4_SSSE3 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr - movh m%2, [%8+%1*FDEC_STRIDE] - movh m%1, [%7+%1*FENC_STRIDE] - punpcklbw m%1, m%2 - movh m%3, [%8+%2*FDEC_STRIDE] - movh m%2, [%7+%2*FENC_STRIDE] - punpcklbw m%2, m%3 - movh m%4, [%8+%3*FDEC_STRIDE] - movh m%3, [%7+%3*FENC_STRIDE] - punpcklbw m%3, m%4 - movh m%5, [%8+%4*FDEC_STRIDE] - movh m%4, [%7+%4*FENC_STRIDE] - punpcklbw m%4, m%5 - pmaddubsw m%1, m%6 - pmaddubsw m%2, m%6 - pmaddubsw m%3, m%6 - pmaddubsw m%4, m%6 -%endmacro - -%macro STORE_DCT 6 - movq [%5+%6+ 0], m%1 - movq [%5+%6+ 8], m%2 - movq [%5+%6+16], m%3 - movq [%5+%6+24], m%4 - movhps [%5+%6+32], m%1 - movhps [%5+%6+40], m%2 - movhps [%5+%6+48], m%3 - movhps [%5+%6+56], m%4 -%endmacro - -%macro STORE_IDCT 4 - movhps [r0-4*FDEC_STRIDE], %1 - movh [r0-3*FDEC_STRIDE], %1 - movhps [r0-2*FDEC_STRIDE], %2 - movh [r0-1*FDEC_STRIDE], %2 - movhps [r0+0*FDEC_STRIDE], %3 - movh [r0+1*FDEC_STRIDE], %3 - movhps [r0+2*FDEC_STRIDE], %4 - movh [r0+3*FDEC_STRIDE], %4 -%endmacro - -%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment? - LOAD_DIFF m%1, m%5, m%7, [%8], [%9] - LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3] - LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3] - LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5] -%if %10 - lea %8, [%8+4*r1] - lea %9, [%9+4*r3] -%endif -%endmacro - -%macro DIFFx2 6-7 - movh %3, %5 - punpcklbw %3, %4 - psraw %1, 6 - paddsw %1, %3 - movh %3, %6 - punpcklbw %3, %4 - psraw %2, 6 - paddsw %2, %3 - packuswb %2, %1 -%endmacro - -%macro STORE_DIFF 4 - movh %2, %4 - punpcklbw %2, %3 - psraw %1, 6 - paddsw %1, %2 - packuswb %1, %1 - movh %4, %1 -%endmacro - diff --git a/tizen/distrib/ffmpeg/libavcodec/xan.c b/tizen/distrib/ffmpeg/libavcodec/xan.c deleted file mode 100644 index 3f6aa8c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xan.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Wing Commander/Xan Video Decoder - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Xan video decoder for Wing Commander III computer game - * by Mario Brito (mbrito@student.dei.uc.pt) - * and Mike Melanson (melanson@pcisys.net) - * - * The xan_wc3 decoder outputs PAL8 data. - */ - -#include -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" -#include "bytestream.h" -#define ALT_BITSTREAM_READER_LE -#include "get_bits.h" -// for av_memcpy_backptr -#include "libavutil/lzo.h" - -typedef struct XanContext { - - AVCodecContext *avctx; - AVFrame last_frame; - AVFrame current_frame; - - const unsigned char *buf; - int size; - - /* scratch space */ - unsigned char *buffer1; - int buffer1_size; - unsigned char *buffer2; - int buffer2_size; - - int frame_size; - -} XanContext; - -static av_cold int xan_decode_init(AVCodecContext *avctx) -{ - XanContext *s = avctx->priv_data; - - s->avctx = avctx; - s->frame_size = 0; - - if ((avctx->codec->id == CODEC_ID_XAN_WC3) && - (s->avctx->palctrl == NULL)) { - av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n"); - return -1; - } - - avctx->pix_fmt = PIX_FMT_PAL8; - - s->buffer1_size = avctx->width * avctx->height; - s->buffer1 = av_malloc(s->buffer1_size); - if (!s->buffer1) - return -1; - s->buffer2_size = avctx->width * avctx->height; - s->buffer2 = av_malloc(s->buffer2_size + 130); - if (!s->buffer2) { - av_freep(&s->buffer1); - return -1; - } - - return 0; -} - -static int xan_huffman_decode(unsigned char *dest, const unsigned char *src, - int dest_len) -{ - unsigned char byte = *src++; - unsigned char ival = byte + 0x16; - const unsigned char * ptr = src + byte*2; - unsigned char val = ival; - unsigned char *dest_end = dest + dest_len; - GetBitContext gb; - - init_get_bits(&gb, ptr, 0); // FIXME: no src size available - - while ( val != 0x16 ) { - val = src[val - 0x17 + get_bits1(&gb) * byte]; - - if ( val < 0x16 ) { - if (dest >= dest_end) - return 0; - *dest++ = val; - val = ival; - } - } - - return 0; -} - -/** - * unpack simple compression - * - * @param dest destination buffer of dest_len, must be padded with at least 130 bytes - */ -static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len) -{ - unsigned char opcode; - int size; - unsigned char *dest_end = dest + dest_len; - - while (dest < dest_end) { - opcode = *src++; - - if (opcode < 0xe0) { - int size2, back; - if ( (opcode & 0x80) == 0 ) { - - size = opcode & 3; - - back = ((opcode & 0x60) << 3) + *src++ + 1; - size2 = ((opcode & 0x1c) >> 2) + 3; - - } else if ( (opcode & 0x40) == 0 ) { - - size = *src >> 6; - - back = (bytestream_get_be16(&src) & 0x3fff) + 1; - size2 = (opcode & 0x3f) + 4; - - } else { - - size = opcode & 3; - - back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1; - size2 = ((opcode & 0x0c) << 6) + *src++ + 5; - if (size + size2 > dest_end - dest) - return; - } - memcpy(dest, src, size); dest += size; src += size; - av_memcpy_backptr(dest, back, size2); - dest += size2; - } else { - int finish = opcode >= 0xfc; - size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4; - - memcpy(dest, src, size); dest += size; src += size; - if (finish) - return; - } - } -} - -static inline void xan_wc3_output_pixel_run(XanContext *s, - const unsigned char *pixel_buffer, int x, int y, int pixel_count) -{ - int stride; - int line_inc; - int index; - int current_x; - int width = s->avctx->width; - unsigned char *palette_plane; - - palette_plane = s->current_frame.data[0]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width; - index = y * stride + x; - current_x = x; - while(pixel_count && (index < s->frame_size)) { - int count = FFMIN(pixel_count, width - current_x); - memcpy(palette_plane + index, pixel_buffer, count); - pixel_count -= count; - index += count; - pixel_buffer += count; - current_x += count; - - if (current_x >= width) { - index += line_inc; - current_x = 0; - } - } -} - -static inline void xan_wc3_copy_pixel_run(XanContext *s, - int x, int y, int pixel_count, int motion_x, int motion_y) -{ - int stride; - int line_inc; - int curframe_index, prevframe_index; - int curframe_x, prevframe_x; - int width = s->avctx->width; - unsigned char *palette_plane, *prev_palette_plane; - - palette_plane = s->current_frame.data[0]; - prev_palette_plane = s->last_frame.data[0]; - stride = s->current_frame.linesize[0]; - line_inc = stride - width; - curframe_index = y * stride + x; - curframe_x = x; - prevframe_index = (y + motion_y) * stride + x + motion_x; - prevframe_x = x + motion_x; - while(pixel_count && (curframe_index < s->frame_size)) { - int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x); - - memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count); - pixel_count -= count; - curframe_index += count; - prevframe_index += count; - curframe_x += count; - prevframe_x += count; - - if (curframe_x >= width) { - curframe_index += line_inc; - curframe_x = 0; - } - - if (prevframe_x >= width) { - prevframe_index += line_inc; - prevframe_x = 0; - } - } -} - -static void xan_wc3_decode_frame(XanContext *s) { - - int width = s->avctx->width; - int height = s->avctx->height; - int total_pixels = width * height; - unsigned char opcode; - unsigned char flag = 0; - int size = 0; - int motion_x, motion_y; - int x, y; - - unsigned char *opcode_buffer = s->buffer1; - int opcode_buffer_size = s->buffer1_size; - const unsigned char *imagedata_buffer = s->buffer2; - - /* pointers to segments inside the compressed chunk */ - const unsigned char *huffman_segment; - const unsigned char *size_segment; - const unsigned char *vector_segment; - const unsigned char *imagedata_segment; - - huffman_segment = s->buf + AV_RL16(&s->buf[0]); - size_segment = s->buf + AV_RL16(&s->buf[2]); - vector_segment = s->buf + AV_RL16(&s->buf[4]); - imagedata_segment = s->buf + AV_RL16(&s->buf[6]); - - xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size); - - if (imagedata_segment[0] == 2) - xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); - else - imagedata_buffer = &imagedata_segment[1]; - - /* use the decoded data segments to build the frame */ - x = y = 0; - while (total_pixels) { - - opcode = *opcode_buffer++; - size = 0; - - switch (opcode) { - - case 0: - flag ^= 1; - continue; - - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - size = opcode; - break; - - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - size += (opcode - 10); - break; - - case 9: - case 19: - size = *size_segment++; - break; - - case 10: - case 20: - size = AV_RB16(&size_segment[0]); - size_segment += 2; - break; - - case 11: - case 21: - size = AV_RB24(size_segment); - size_segment += 3; - break; - } - - if (opcode < 12) { - flag ^= 1; - if (flag) { - /* run of (size) pixels is unchanged from last frame */ - xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); - } else { - /* output a run of pixels from imagedata_buffer */ - xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size); - imagedata_buffer += size; - } - } else { - /* run-based motion compensation from last frame */ - motion_x = sign_extend(*vector_segment >> 4, 4); - motion_y = sign_extend(*vector_segment & 0xF, 4); - vector_segment++; - - /* copy a run of pixels from the previous frame */ - xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y); - - flag = 0; - } - - /* coordinate accounting */ - total_pixels -= size; - y += (x + size) / width; - x = (x + size) % width; - } -} - -static void xan_wc4_decode_frame(XanContext *s) { -} - -static int xan_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - XanContext *s = avctx->priv_data; - AVPaletteControl *palette_control = avctx->palctrl; - - if (avctx->get_buffer(avctx, &s->current_frame)) { - av_log(s->avctx, AV_LOG_ERROR, " Xan Video: get_buffer() failed\n"); - return -1; - } - s->current_frame.reference = 3; - - if (!s->frame_size) - s->frame_size = s->current_frame.linesize[0] * s->avctx->height; - - palette_control->palette_changed = 0; - memcpy(s->current_frame.data[1], palette_control->palette, - AVPALETTE_SIZE); - s->current_frame.palette_has_changed = 1; - - s->buf = buf; - s->size = buf_size; - - if (avctx->codec->id == CODEC_ID_XAN_WC3) - xan_wc3_decode_frame(s); - else if (avctx->codec->id == CODEC_ID_XAN_WC4) - xan_wc4_decode_frame(s); - - /* release the last frame if it is allocated */ - if (s->last_frame.data[0]) - avctx->release_buffer(avctx, &s->last_frame); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->current_frame; - - /* shuffle frames */ - FFSWAP(AVFrame, s->current_frame, s->last_frame); - - /* always report that the buffer was completely consumed */ - return buf_size; -} - -static av_cold int xan_decode_end(AVCodecContext *avctx) -{ - XanContext *s = avctx->priv_data; - - /* release the frames */ - if (s->last_frame.data[0]) - avctx->release_buffer(avctx, &s->last_frame); - if (s->current_frame.data[0]) - avctx->release_buffer(avctx, &s->current_frame); - - av_freep(&s->buffer1); - av_freep(&s->buffer2); - - return 0; -} - -AVCodec xan_wc3_decoder = { - "xan_wc3", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_XAN_WC3, - sizeof(XanContext), - xan_decode_init, - NULL, - xan_decode_end, - xan_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), -}; - -/* -AVCodec xan_wc4_decoder = { - "xan_wc4", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_XAN_WC4, - sizeof(XanContext), - xan_decode_init, - NULL, - xan_decode_end, - xan_decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"), -}; -*/ diff --git a/tizen/distrib/ffmpeg/libavcodec/xiph.c b/tizen/distrib/ffmpeg/libavcodec/xiph.c deleted file mode 100644 index 2f4f25c..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xiph.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2007 FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "xiph.h" - -int ff_split_xiph_headers(uint8_t *extradata, int extradata_size, - int first_header_size, uint8_t *header_start[3], - int header_len[3]) -{ - int i; - - if (extradata_size >= 6 && AV_RB16(extradata) == first_header_size) { - int overall_len = 6; - for (i=0; i<3; i++) { - header_len[i] = AV_RB16(extradata); - extradata += 2; - header_start[i] = extradata; - extradata += header_len[i]; - if (overall_len > extradata_size - header_len[i]) - return -1; - overall_len += header_len[i]; - } - } else if (extradata_size >= 3 && extradata_size < INT_MAX - 0x1ff && extradata[0] == 2) { - int overall_len = 3; - extradata++; - for (i=0; i<2; i++, extradata++) { - header_len[i] = 0; - for (; overall_len < extradata_size && *extradata==0xff; extradata++) { - header_len[i] += 0xff; - overall_len += 0xff + 1; - } - header_len[i] += *extradata; - overall_len += *extradata; - if (overall_len > extradata_size) - return -1; - } - header_len[2] = extradata_size - overall_len; - header_start[0] = extradata; - header_start[1] = header_start[0] + header_len[0]; - header_start[2] = header_start[1] + header_len[1]; - } else { - return -1; - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavcodec/xiph.h b/tizen/distrib/ffmpeg/libavcodec/xiph.h deleted file mode 100644 index 60f4a95..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xiph.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2007 FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_XIPH_H -#define AVCODEC_XIPH_H - -#include "libavutil/common.h" - -/** - * Splits a single extradata buffer into the three headers that most - * Xiph codecs use. (e.g. Theora and Vorbis) - * Works both with Matroska's packing and lavc's packing. - * - * @param[in] extradata The single chunk that combines all three headers - * @param[in] extradata_size The size of the extradata buffer - * @param[in] first_header_size The size of the first header, used to - * differentiate between the Matroska packing and lavc packing. - * @param[out] header_start Pointers to the start of the three separate headers. - * @param[out] header_len The sizes of each of the three headers. - * @return On error a negative value is returned, on success zero. - */ -int ff_split_xiph_headers(uint8_t *extradata, int extradata_size, - int first_header_size, uint8_t *header_start[3], - int header_len[3]); - -#endif /* AVCODEC_XIPH_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/xl.c b/tizen/distrib/ffmpeg/libavcodec/xl.c deleted file mode 100644 index f7d025e..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xl.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Miro VideoXL codec - * Copyright (c) 2004 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Miro VideoXL codec. - */ - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -typedef struct VideoXLContext{ - AVCodecContext *avctx; - AVFrame pic; -} VideoXLContext; - -static const int xl_table[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 12, 15, 20, 25, 34, 46, - 64, 82, 94, 103, 108, 113, 116, 119, - 120, 121, 122, 123, 124, 125, 126, 127}; - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - VideoXLContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; - uint8_t *Y, *U, *V; - int i, j; - int stride; - uint32_t val; - int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0; - - 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= FF_I_TYPE; - p->key_frame= 1; - - Y = a->pic.data[0]; - U = a->pic.data[1]; - V = a->pic.data[2]; - - stride = avctx->width - 4; - for (i = 0; i < avctx->height; i++) { - /* lines are stored in reversed order */ - buf += stride; - - for (j = 0; j < avctx->width; j += 4) { - /* value is stored in LE dword with word swapped */ - val = AV_RL32(buf); - buf -= 4; - val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16); - - if(!j) - y0 = (val & 0x1F) << 2; - else - y0 = y3 + xl_table[val & 0x1F]; - val >>= 5; - y1 = y0 + xl_table[val & 0x1F]; - val >>= 5; - y2 = y1 + xl_table[val & 0x1F]; - val >>= 6; /* align to word */ - y3 = y2 + xl_table[val & 0x1F]; - val >>= 5; - if(!j) - c0 = (val & 0x1F) << 2; - else - c0 += xl_table[val & 0x1F]; - val >>= 5; - if(!j) - c1 = (val & 0x1F) << 2; - else - c1 += xl_table[val & 0x1F]; - - Y[j + 0] = y0 << 1; - Y[j + 1] = y1 << 1; - Y[j + 2] = y2 << 1; - Y[j + 3] = y3 << 1; - - U[j >> 2] = c0 << 1; - V[j >> 2] = c1 << 1; - } - - buf += avctx->width + 4; - Y += a->pic.linesize[0]; - U += a->pic.linesize[1]; - V += a->pic.linesize[2]; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = a->pic; - - return buf_size; -} - -static av_cold int decode_init(AVCodecContext *avctx){ -// VideoXLContext * const a = avctx->priv_data; - - avctx->pix_fmt= PIX_FMT_YUV411P; - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - VideoXLContext * const a = avctx->priv_data; - AVFrame *pic = &a->pic; - - if (pic->data[0]) - avctx->release_buffer(avctx, pic); - - return 0; -} - -AVCodec xl_decoder = { - "xl", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_VIXL, - sizeof(VideoXLContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Miro VideoXL"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/xsubdec.c b/tizen/distrib/ffmpeg/libavcodec/xsubdec.c deleted file mode 100644 index 0055ebb..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xsubdec.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * XSUB subtitle decoder - * Copyright (c) 2007 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avcodec.h" -#include "get_bits.h" -#include "bytestream.h" - -static av_cold int decode_init(AVCodecContext *avctx) { - avctx->pix_fmt = PIX_FMT_PAL8; - return 0; -} - -static const uint8_t tc_offsets[9] = { 0, 1, 3, 4, 6, 7, 9, 10, 11 }; -static const uint8_t tc_muls[9] = { 10, 6, 10, 6, 10, 10, 10, 10, 1 }; - -static int64_t parse_timecode(const uint8_t *buf, int64_t packet_time) { - int i; - int64_t ms = 0; - if (buf[2] != ':' || buf[5] != ':' || buf[8] != '.') - return AV_NOPTS_VALUE; - for (i = 0; i < sizeof(tc_offsets); i++) { - uint8_t c = buf[tc_offsets[i]] - '0'; - if (c > 9) return AV_NOPTS_VALUE; - ms = (ms + c) * tc_muls[i]; - } - return ms - packet_time; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AVSubtitle *sub = data; - const uint8_t *buf_end = buf + buf_size; - uint8_t *bitmap; - int w, h, x, y, rlelen, i; - int64_t packet_time = 0; - GetBitContext gb; - - memset(sub, 0, sizeof(*sub)); - - // check that at least header fits - if (buf_size < 27 + 7 * 2 + 4 * 3) { - av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); - return -1; - } - - // read start and end time - if (buf[0] != '[' || buf[13] != '-' || buf[26] != ']') { - av_log(avctx, AV_LOG_ERROR, "invalid time code\n"); - return -1; - } - if (avpkt->pts != AV_NOPTS_VALUE) - packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000}); - sub->start_display_time = parse_timecode(buf + 1, packet_time); - sub->end_display_time = parse_timecode(buf + 14, packet_time); - buf += 27; - - // read header - w = bytestream_get_le16(&buf); - h = bytestream_get_le16(&buf); - if (avcodec_check_dimensions(avctx, w, h) < 0) - return -1; - x = bytestream_get_le16(&buf); - y = bytestream_get_le16(&buf); - // skip bottom right position, it gives no new information - bytestream_get_le16(&buf); - bytestream_get_le16(&buf); - rlelen = bytestream_get_le16(&buf); - - // allocate sub and set values - sub->rects = av_mallocz(sizeof(*sub->rects)); - sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); - sub->num_rects = 1; - sub->rects[0]->x = x; sub->rects[0]->y = y; - sub->rects[0]->w = w; sub->rects[0]->h = h; - sub->rects[0]->type = SUBTITLE_BITMAP; - sub->rects[0]->pict.linesize[0] = w; - sub->rects[0]->pict.data[0] = av_malloc(w * h); - sub->rects[0]->nb_colors = 4; - sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); - - // read palette - for (i = 0; i < sub->rects[0]->nb_colors; i++) - ((uint32_t*)sub->rects[0]->pict.data[1])[i] = bytestream_get_be24(&buf); - // make all except background (first entry) non-transparent - for (i = 1; i < sub->rects[0]->nb_colors; i++) - ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= 0xff000000; - - // process RLE-compressed data - rlelen = FFMIN(rlelen, buf_end - buf); - init_get_bits(&gb, buf, rlelen * 8); - bitmap = sub->rects[0]->pict.data[0]; - for (y = 0; y < h; y++) { - // interlaced: do odd lines - if (y == (h + 1) / 2) bitmap = sub->rects[0]->pict.data[0] + w; - for (x = 0; x < w; ) { - int log2 = ff_log2_tab[show_bits(&gb, 8)]; - int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); - int color = get_bits(&gb, 2); - run = FFMIN(run, w - x); - // run length 0 means till end of row - if (!run) run = w - x; - memset(bitmap, color, run); - bitmap += run; - x += run; - } - // interlaced, skip every second line - bitmap += w; - align_get_bits(&gb); - } - *data_size = 1; - return buf_size; -} - -AVCodec xsub_decoder = { - "xsub", - AVMEDIA_TYPE_SUBTITLE, - CODEC_ID_XSUB, - 0, - decode_init, - NULL, - NULL, - decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("XSUB"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/xsubenc.c b/tizen/distrib/ffmpeg/libavcodec/xsubenc.c deleted file mode 100644 index 903cbd2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xsubenc.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * DivX (XSUB) subtitle encoder - * Copyright (c) 2005 DivX, Inc. - * Copyright (c) 2009 Bjorn Axelsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avcodec.h" -#include "bytestream.h" -#include "put_bits.h" - -/** - * Number of pixels to pad left and right. - * - * The official encoder pads the subtitles with two pixels on either side, - * but until we find out why, we won't do it (we will pad to have width - * divisible by 2 though). - */ -#define PADDING 0 -#define PADDING_COLOR 0 - -/** - * Encodes a single color run. At most 16 bits will be used. - * \param len length of the run, values > 255 mean "until end of line", may not be < 0. - * \param color color to encode, only the lowest two bits are used and all others must be 0. - */ -static void put_xsub_rle(PutBitContext *pb, int len, int color) -{ - if (len <= 255) - put_bits(pb, 2 + ((ff_log2_tab[len] >> 1) << 2), len); - else - put_bits(pb, 14, 0); - put_bits(pb, 2, color); -} - -/** - * Encodes a 4-color bitmap with XSUB rle. - * - * The encoded bitmap may be wider than the source bitmap due to padding. - */ -static int xsub_encode_rle(PutBitContext *pb, const uint8_t *bitmap, - int linesize, int w, int h) -{ - int x0, x1, y, len, color = PADDING_COLOR; - - for (y = 0; y < h; y++) { - x0 = 0; - while (x0 < w) { - // Make sure we have enough room for at least one run and padding - if (pb->size_in_bits - put_bits_count(pb) < 7*8) - return -1; - - x1 = x0; - color = bitmap[x1++] & 3; - while (x1 < w && (bitmap[x1] & 3) == color) - x1++; - len = x1 - x0; - if (PADDING && x0 == 0) { - if (color == PADDING_COLOR) { - len += PADDING; - x0 -= PADDING; - } else - put_xsub_rle(pb, PADDING, PADDING_COLOR); - } - - // Run can't be longer than 255, unless it is the rest of a row - if (x1 == w && color == PADDING_COLOR) { - len += PADDING + (w&1); - } else - len = FFMIN(len, 255); - put_xsub_rle(pb, len, color); - - x0 += len; - } - if (color != PADDING_COLOR && (PADDING + (w&1))) - put_xsub_rle(pb, PADDING + (w&1), PADDING_COLOR); - - align_put_bits(pb); - - bitmap += linesize; - } - - return 0; -} - -static int make_tc(uint64_t ms, int *tc) -{ - static const int tc_divs[3] = { 1000, 60, 60 }; - int i; - for (i=0; i<3; i++) { - tc[i] = ms % tc_divs[i]; - ms /= tc_divs[i]; - } - tc[3] = ms; - return ms > 99; -} - -static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, - int bufsize, void *data) -{ - AVSubtitle *h = data; - uint64_t startTime = h->pts / 1000; // FIXME: need better solution... - uint64_t endTime = startTime + h->end_display_time - h->start_display_time; - int start_tc[4], end_tc[4]; - uint8_t *hdr = buf + 27; // Point behind the timestamp - uint8_t *rlelenptr; - uint16_t width, height; - int i; - PutBitContext pb; - - if (bufsize < 27 + 7*2 + 4*3) { - av_log(avctx, AV_LOG_ERROR, "Buffer too small for XSUB header.\n"); - return -1; - } - - // TODO: support multiple rects - if (h->num_rects > 1) - av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_rects); - - // TODO: render text-based subtitles into bitmaps - if (!h->rects[0]->pict.data[0] || !h->rects[0]->pict.data[1]) { - av_log(avctx, AV_LOG_WARNING, "No subtitle bitmap available.\n"); - return -1; - } - - // TODO: color reduction, similar to dvdsub encoder - if (h->rects[0]->nb_colors > 4) - av_log(avctx, AV_LOG_WARNING, "No more than 4 subtitle colors supported (%d found.)\n", h->rects[0]->nb_colors); - - // TODO: Palette swapping if color zero is not transparent - if (((uint32_t *)h->rects[0]->pict.data[1])[0] & 0xff) - av_log(avctx, AV_LOG_WARNING, "Color index 0 is not transparent. Transparency will be messed up.\n"); - - if (make_tc(startTime, start_tc) || make_tc(endTime, end_tc)) { - av_log(avctx, AV_LOG_WARNING, "Time code >= 100 hours.\n"); - return -1; - } - - snprintf(buf, 28, - "[%02d:%02d:%02d.%03d-%02d:%02d:%02d.%03d]", - start_tc[3], start_tc[2], start_tc[1], start_tc[0], - end_tc[3], end_tc[2], end_tc[1], end_tc[0]); - - // Width and height must probably be multiples of 2. - // 2 pixels required on either side of subtitle. - // Possibly due to limitations of hardware renderers. - // TODO: check if the bitmap is already padded - width = FFALIGN(h->rects[0]->w, 2) + PADDING * 2; - height = FFALIGN(h->rects[0]->h, 2); - - bytestream_put_le16(&hdr, width); - bytestream_put_le16(&hdr, height); - bytestream_put_le16(&hdr, h->rects[0]->x); - bytestream_put_le16(&hdr, h->rects[0]->y); - bytestream_put_le16(&hdr, h->rects[0]->x + width); - bytestream_put_le16(&hdr, h->rects[0]->y + height); - - rlelenptr = hdr; // Will store length of first field here later. - hdr+=2; - - // Palette - for (i=0; i<4; i++) - bytestream_put_be24(&hdr, ((uint32_t *)h->rects[0]->pict.data[1])[i]); - - // Bitmap - // RLE buffer. Reserve 2 bytes for possible padding after the last row. - init_put_bits(&pb, hdr, bufsize - (hdr - buf) - 2); - if (xsub_encode_rle(&pb, h->rects[0]->pict.data[0], - h->rects[0]->pict.linesize[0]*2, - h->rects[0]->w, (h->rects[0]->h + 1) >> 1)) - return -1; - bytestream_put_le16(&rlelenptr, put_bits_count(&pb) >> 3); // Length of first field - - if (xsub_encode_rle(&pb, h->rects[0]->pict.data[0] + h->rects[0]->pict.linesize[0], - h->rects[0]->pict.linesize[0]*2, - h->rects[0]->w, h->rects[0]->h >> 1)) - return -1; - - // Enforce total height to be be multiple of 2 - if (h->rects[0]->h & 1) { - put_xsub_rle(&pb, h->rects[0]->w, PADDING_COLOR); - align_put_bits(&pb); - } - - flush_put_bits(&pb); - - return hdr - buf + put_bits_count(&pb)/8; -} - -static av_cold int xsub_encoder_init(AVCodecContext *avctx) -{ - if (!avctx->codec_tag) - avctx->codec_tag = MKTAG('D','X','S','B'); - - return 0; -} - -AVCodec xsub_encoder = { - "xsub", - AVMEDIA_TYPE_SUBTITLE, - CODEC_ID_XSUB, - 0, - xsub_encoder_init, - xsub_encode, - NULL, - .long_name = NULL_IF_CONFIG_SMALL("DivX subtitles (XSUB)"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/xvmc.h b/tizen/distrib/ffmpeg/libavcodec/xvmc.h deleted file mode 100644 index 01f84b2..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xvmc.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2003 Ivan Kalvachev - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_XVMC_H -#define AVCODEC_XVMC_H - -#include - -#include "avcodec.h" - -#if LIBAVCODEC_VERSION_MAJOR < 53 -#define AV_XVMC_STATE_DISPLAY_PENDING 1 /** the surface should be shown, the video driver manipulates this */ -#define AV_XVMC_STATE_PREDICTION 2 /** the surface is needed for prediction, the codec manipulates this */ -#define AV_XVMC_STATE_OSD_SOURCE 4 /** the surface is needed for subpicture rendering */ -#endif -#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct - the number is 1337 speak for the letters IDCT MCo (motion compensation) */ - -struct xvmc_pix_fmt { - /** The field contains the special constant value AV_XVMC_ID. - It is used as a test that the application correctly uses the API, - and that there is no corruption caused by pixel routines. - - application - set during initialization - - libavcodec - unchanged - */ - int xvmc_id; - - /** Pointer to the block array allocated by XvMCCreateBlocks(). - The array has to be freed by XvMCDestroyBlocks(). - Each group of 64 values represents one data block of differential - pixel information (in MoCo mode) or coefficients for IDCT. - - application - set the pointer during initialization - - libavcodec - fills coefficients/pixel data into the array - */ - short* data_blocks; - - /** Pointer to the macroblock description array allocated by - XvMCCreateMacroBlocks() and freed by XvMCDestroyMacroBlocks(). - - application - set the pointer during initialization - - libavcodec - fills description data into the array - */ - XvMCMacroBlock* mv_blocks; - - /** Number of macroblock descriptions that can be stored in the mv_blocks - array. - - application - set during initialization - - libavcodec - unchanged - */ - int allocated_mv_blocks; - - /** Number of blocks that can be stored at once in the data_blocks array. - - application - set during initialization - - libavcodec - unchanged - */ - int allocated_data_blocks; - - /** Indicates that the hardware would interpret data_blocks as IDCT - coefficients and perform IDCT on them. - - application - set during initialization - - libavcodec - unchanged - */ - int idct; - - /** In MoCo mode it indicates that intra macroblocks are assumed to be in - unsigned format; same as the XVMC_INTRA_UNSIGNED flag. - - application - set during initialization - - libavcodec - unchanged - */ - int unsigned_intra; - - /** Pointer to the surface allocated by XvMCCreateSurface(). - It has to be freed by XvMCDestroySurface() on application exit. - It identifies the frame and its state on the video hardware. - - application - set during initialization - - libavcodec - unchanged - */ - XvMCSurface* p_surface; - -/** Set by the decoder before calling ff_draw_horiz_band(), - needed by the XvMCRenderSurface function. */ -//@{ - /** Pointer to the surface used as past reference - - application - unchanged - - libavcodec - set - */ - XvMCSurface* p_past_surface; - - /** Pointer to the surface used as future reference - - application - unchanged - - libavcodec - set - */ - XvMCSurface* p_future_surface; - - /** top/bottom field or frame - - application - unchanged - - libavcodec - set - */ - unsigned int picture_structure; - - /** XVMC_SECOND_FIELD - 1st or 2nd field in the sequence - - application - unchanged - - libavcodec - set - */ - unsigned int flags; -//}@ - - /** Number of macroblock descriptions in the mv_blocks array - that have already been passed to the hardware. - - application - zeroes it on get_buffer(). - A successful ff_draw_horiz_band() may increment it - with filled_mb_block_num or zero both. - - libavcodec - unchanged - */ - int start_mv_blocks_num; - - /** Number of new macroblock descriptions in the mv_blocks array (after - start_mv_blocks_num) that are filled by libavcodec and have to be - passed to the hardware. - - application - zeroes it on get_buffer() or after successful - ff_draw_horiz_band(). - - libavcodec - increment with one of each stored MB - */ - int filled_mv_blocks_num; - - /** Number of the the next free data block; one data block consists of - 64 short values in the data_blocks array. - All blocks before this one have already been claimed by placing their - position into the corresponding block description structure field, - that are part of the mv_blocks array. - - application - zeroes it on get_buffer(). - A successful ff_draw_horiz_band() may zero it together - with start_mb_blocks_num. - - libavcodec - each decoded macroblock increases it by the number - of coded blocks it contains. - */ - int next_free_data_block_num; - -/** extensions may be placed here */ -#if LIBAVCODEC_VERSION_MAJOR < 53 -//@{ - /** State flags used to work around limitations in the MPlayer video system. - 0 - Surface is not used. - 1 - Surface is still held in application to be displayed or is - still visible. - 2 - Surface is still held in libavcodec buffer for prediction. - */ - int state; - - /** pointer to the surface where the subpicture is rendered */ - void* p_osd_target_surface_render; -//}@ -#endif -}; - -#endif /* AVCODEC_XVMC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/xvmc_internal.h b/tizen/distrib/ffmpeg/libavcodec/xvmc_internal.h deleted file mode 100644 index 9bb8909..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/xvmc_internal.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * XVideo Motion Compensation internal functions - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_INTERNAL_XVMC_H -#define AVCODEC_INTERNAL_XVMC_H - -#include "avcodec.h" -#include "mpegvideo.h" - -void ff_xvmc_init_block(MpegEncContext *s); -void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp); -int ff_xvmc_field_start(MpegEncContext*s, AVCodecContext *avctx); -void ff_xvmc_field_end(MpegEncContext *s); -void ff_xvmc_decode_mb(MpegEncContext *s); - -#endif /* AVCODEC_INTERNAL_XVMC_H */ diff --git a/tizen/distrib/ffmpeg/libavcodec/yop.c b/tizen/distrib/ffmpeg/libavcodec/yop.c deleted file mode 100644 index 1eb76b1..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/yop.c +++ /dev/null @@ -1,260 +0,0 @@ -/** - * @file - * Psygnosis YOP decoder - * - * Copyright (C) 2010 Mohamed Naufal Basheer - * derived from the code by - * Copyright (C) 2009 Thomas P. Higdon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" - -#include "avcodec.h" -#include "get_bits.h" - -typedef struct YopDecContext { - AVFrame frame; - AVCodecContext *avctx; - - int num_pal_colors; - int first_color[2]; - int frame_data_length; - int row_pos; - - uint8_t *low_nibble; - uint8_t *srcptr; - uint8_t *dstptr; - uint8_t *dstbuf; -} YopDecContext; - -// These tables are taken directly from: -// http://wiki.multimedia.cx/index.php?title=Psygnosis_YOP - -/** - * Lookup table for painting macroblocks. Bytes 0-2 of each entry contain - * the macroblock positions to be painted (taken as (0, B0, B1, B2)). - * Byte 3 contains the number of bytes consumed on the input, - * equal to max(bytes 0-2) + 1. - */ -static const uint8_t paint_lut[15][4] = - {{1, 2, 3, 4}, {1, 2, 0, 3}, - {1, 2, 1, 3}, {1, 2, 2, 3}, - {1, 0, 2, 3}, {1, 0, 0, 2}, - {1, 0, 1, 2}, {1, 1, 2, 3}, - {0, 1, 2, 3}, {0, 1, 0, 2}, - {1, 1, 0, 2}, {0, 1, 1, 2}, - {0, 0, 1, 2}, {0, 0, 0, 1}, - {1, 1, 1, 2}, - }; - -/** - * Lookup table for copying macroblocks. Each entry contains the respective - * x and y pixel offset for the copy source. - */ -static const int8_t motion_vector[16][2] = - {{-4, -4}, {-2, -4}, - { 0, -4}, { 2, -4}, - {-4, -2}, {-4, 0}, - {-3, -3}, {-1, -3}, - { 1, -3}, { 3, -3}, - {-3, -1}, {-2, -2}, - { 0, -2}, { 2, -2}, - { 4, -2}, {-2, 0}, - }; - -static av_cold int yop_decode_init(AVCodecContext *avctx) -{ - YopDecContext *s = avctx->priv_data; - s->avctx = avctx; - - if (avctx->width & 1 || avctx->height & 1 || - avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { - av_log(avctx, AV_LOG_ERROR, "YOP has invalid dimensions\n"); - return -1; - } - - avctx->pix_fmt = PIX_FMT_PAL8; - - s->num_pal_colors = avctx->extradata[0]; - s->first_color[0] = avctx->extradata[1]; - s->first_color[1] = avctx->extradata[2]; - - if (s->num_pal_colors + s->first_color[0] > 256 || - s->num_pal_colors + s->first_color[1] > 256) { - av_log(avctx, AV_LOG_ERROR, - "YOP: palette parameters invalid, header probably corrupt\n"); - return AVERROR_INVALIDDATA; - } - - return 0; -} - -static av_cold int yop_decode_close(AVCodecContext *avctx) -{ - YopDecContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - return 0; -} - -/** - * Paints a macroblock using the pattern in paint_lut. - * @param s codec context - * @param tag the tag that was in the nibble - */ -static void yop_paint_block(YopDecContext *s, int tag) -{ - s->dstptr[0] = s->srcptr[0]; - s->dstptr[1] = s->srcptr[paint_lut[tag][0]]; - s->dstptr[s->frame.linesize[0]] = s->srcptr[paint_lut[tag][1]]; - s->dstptr[s->frame.linesize[0] + 1] = s->srcptr[paint_lut[tag][2]]; - - // The number of src bytes consumed is in the last part of the lut entry. - s->srcptr += paint_lut[tag][3]; -} - -/** - * Copies a previously painted macroblock to the current_block. - * @param copy_tag the tag that was in the nibble - */ -static int yop_copy_previous_block(YopDecContext *s, int copy_tag) -{ - uint8_t *bufptr; - - // Calculate position for the copy source - bufptr = s->dstptr + motion_vector[copy_tag][0] + - s->frame.linesize[0] * motion_vector[copy_tag][1]; - if (bufptr < s->dstbuf) { - av_log(s->avctx, AV_LOG_ERROR, - "YOP: cannot decode, file probably corrupt\n"); - return AVERROR_INVALIDDATA; - } - - s->dstptr[0] = bufptr[0]; - s->dstptr[1] = bufptr[1]; - s->dstptr[s->frame.linesize[0]] = bufptr[s->frame.linesize[0]]; - s->dstptr[s->frame.linesize[0] + 1] = bufptr[s->frame.linesize[0] + 1]; - - return 0; -} - -/** - * Returns the next nibble in sequence, consuming a new byte on the input - * only if necessary. - */ -static uint8_t yop_get_next_nibble(YopDecContext *s) -{ - int ret; - - if (s->low_nibble) { - ret = *s->low_nibble & 0xf; - s->low_nibble = NULL; - }else { - s->low_nibble = s->srcptr++; - ret = *s->low_nibble >> 4; - } - return ret; -} - -/** - * Takes s->dstptr to the next macroblock in sequence. - */ -static void yop_next_macroblock(YopDecContext *s) -{ - // If we are advancing to the next row of macroblocks - if (s->row_pos == s->frame.linesize[0] - 2) { - s->dstptr += s->frame.linesize[0]; - s->row_pos = 0; - }else { - s->row_pos += 2; - } - s->dstptr += 2; -} - -static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - YopDecContext *s = avctx->priv_data; - int tag, firstcolor, is_odd_frame; - int ret, i; - uint32_t *palette; - - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - ret = avctx->get_buffer(avctx, &s->frame); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return ret; - } - - s->frame.linesize[0] = avctx->width; - - s->dstbuf = s->frame.data[0]; - s->dstptr = s->frame.data[0]; - s->srcptr = avpkt->data + 4; - s->row_pos = 0; - s->low_nibble = NULL; - - is_odd_frame = avpkt->data[0]; - firstcolor = s->first_color[is_odd_frame]; - palette = (uint32_t *)s->frame.data[1]; - - for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3) - palette[i + firstcolor] = (s->srcptr[0] << 18) | - (s->srcptr[1] << 10) | - (s->srcptr[2] << 2); - - s->frame.palette_has_changed = 1; - - while (s->dstptr - s->dstbuf < - avctx->width * avctx->height && - s->srcptr - avpkt->data < avpkt->size) { - - tag = yop_get_next_nibble(s); - - if (tag != 0xf) { - yop_paint_block(s, tag); - }else { - tag = yop_get_next_nibble(s); - ret = yop_copy_previous_block(s, tag); - if (ret < 0) { - avctx->release_buffer(avctx, &s->frame); - return ret; - } - } - yop_next_macroblock(s); - } - - *data_size = sizeof(AVFrame); - *(AVFrame *) data = s->frame; - return avpkt->size; -} - -AVCodec yop_decoder = { - "yop", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_YOP, - sizeof(YopDecContext), - yop_decode_init, - NULL, - yop_decode_close, - yop_decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"), -}; diff --git a/tizen/distrib/ffmpeg/libavcodec/zmbv.c b/tizen/distrib/ffmpeg/libavcodec/zmbv.c deleted file mode 100644 index 8af8c84..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/zmbv.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Zip Motion Blocks Video (ZMBV) decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Zip Motion Blocks Video decoder - */ - -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#include - -#define ZMBV_KEYFRAME 1 -#define ZMBV_DELTAPAL 2 - -enum ZmbvFormat { - ZMBV_FMT_NONE = 0, - ZMBV_FMT_1BPP = 1, - ZMBV_FMT_2BPP = 2, - ZMBV_FMT_4BPP = 3, - ZMBV_FMT_8BPP = 4, - ZMBV_FMT_15BPP = 5, - ZMBV_FMT_16BPP = 6, - ZMBV_FMT_24BPP = 7, - ZMBV_FMT_32BPP = 8 -}; - -/* - * Decoder context - */ -typedef struct ZmbvContext { - AVCodecContext *avctx; - AVFrame pic; - - int bpp; - unsigned int decomp_size; - uint8_t* decomp_buf; - uint8_t pal[768]; - uint8_t *prev, *cur; - int width, height; - int fmt; - int comp; - int flags; - int bw, bh, bx, by; - int decomp_len; - z_stream zstream; - int (*decode_intra)(struct ZmbvContext *c); - int (*decode_xor)(struct ZmbvContext *c); -} ZmbvContext; - -/** - * Decode XOR'ed frame - 8bpp version - */ - -static int zmbv_decode_xor_8(ZmbvContext *c) -{ - uint8_t *src = c->decomp_buf; - uint8_t *output, *prev; - int8_t *mvec; - int x, y; - int d, dx, dy, bw2, bh2; - int block; - int i, j; - int mx, my; - - output = c->cur; - prev = c->prev; - - if(c->flags & ZMBV_DELTAPAL){ - for(i = 0; i < 768; i++) - c->pal[i] ^= *src++; - } - - mvec = (int8_t*)src; - src += ((c->bx * c->by * 2 + 3) & ~3); - - block = 0; - for(y = 0; y < c->height; y += c->bh) { - bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); - for(x = 0; x < c->width; x += c->bw) { - uint8_t *out, *tprev; - - d = mvec[block] & 1; - dx = mvec[block] >> 1; - dy = mvec[block + 1] >> 1; - block += 2; - - bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); - - /* copy block - motion vectors out of bounds are used to zero blocks */ - out = output + x; - tprev = prev + x + dx + dy * c->width; - mx = x + dx; - my = y + dy; - for(j = 0; j < bh2; j++){ - if((my + j < 0) || (my + j >= c->height)) { - memset(out, 0, bw2); - } else { - for(i = 0; i < bw2; i++){ - if((mx + i < 0) || (mx + i >= c->width)) - out[i] = 0; - else - out[i] = tprev[i]; - } - } - out += c->width; - tprev += c->width; - } - - if(d) { /* apply XOR'ed difference */ - out = output + x; - for(j = 0; j < bh2; j++){ - for(i = 0; i < bw2; i++) - out[i] ^= *src++; - out += c->width; - } - } - } - output += c->width * c->bh; - prev += c->width * c->bh; - } - if(src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len); - return 0; -} - -/** - * Decode XOR'ed frame - 15bpp and 16bpp version - */ - -static int zmbv_decode_xor_16(ZmbvContext *c) -{ - uint8_t *src = c->decomp_buf; - uint16_t *output, *prev; - int8_t *mvec; - int x, y; - int d, dx, dy, bw2, bh2; - int block; - int i, j; - int mx, my; - - output = (uint16_t*)c->cur; - prev = (uint16_t*)c->prev; - - mvec = (int8_t*)src; - src += ((c->bx * c->by * 2 + 3) & ~3); - - block = 0; - for(y = 0; y < c->height; y += c->bh) { - bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); - for(x = 0; x < c->width; x += c->bw) { - uint16_t *out, *tprev; - - d = mvec[block] & 1; - dx = mvec[block] >> 1; - dy = mvec[block + 1] >> 1; - block += 2; - - bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); - - /* copy block - motion vectors out of bounds are used to zero blocks */ - out = output + x; - tprev = prev + x + dx + dy * c->width; - mx = x + dx; - my = y + dy; - for(j = 0; j < bh2; j++){ - if((my + j < 0) || (my + j >= c->height)) { - memset(out, 0, bw2 * 2); - } else { - for(i = 0; i < bw2; i++){ - if((mx + i < 0) || (mx + i >= c->width)) - out[i] = 0; - else - out[i] = tprev[i]; - } - } - out += c->width; - tprev += c->width; - } - - if(d) { /* apply XOR'ed difference */ - out = output + x; - for(j = 0; j < bh2; j++){ - for(i = 0; i < bw2; i++) { - out[i] ^= *((uint16_t*)src); - src += 2; - } - out += c->width; - } - } - } - output += c->width * c->bh; - prev += c->width * c->bh; - } - if(src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len); - return 0; -} - -#ifdef ZMBV_ENABLE_24BPP -/** - * Decode XOR'ed frame - 24bpp version - */ - -static int zmbv_decode_xor_24(ZmbvContext *c) -{ - uint8_t *src = c->decomp_buf; - uint8_t *output, *prev; - int8_t *mvec; - int x, y; - int d, dx, dy, bw2, bh2; - int block; - int i, j; - int mx, my; - int stride; - - output = c->cur; - prev = c->prev; - - stride = c->width * 3; - mvec = (int8_t*)src; - src += ((c->bx * c->by * 2 + 3) & ~3); - - block = 0; - for(y = 0; y < c->height; y += c->bh) { - bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); - for(x = 0; x < c->width; x += c->bw) { - uint8_t *out, *tprev; - - d = mvec[block] & 1; - dx = mvec[block] >> 1; - dy = mvec[block + 1] >> 1; - block += 2; - - bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); - - /* copy block - motion vectors out of bounds are used to zero blocks */ - out = output + x * 3; - tprev = prev + (x + dx) * 3 + dy * stride; - mx = x + dx; - my = y + dy; - for(j = 0; j < bh2; j++){ - if((my + j < 0) || (my + j >= c->height)) { - memset(out, 0, bw2 * 3); - } else { - for(i = 0; i < bw2; i++){ - if((mx + i < 0) || (mx + i >= c->width)) { - out[i * 3 + 0] = 0; - out[i * 3 + 1] = 0; - out[i * 3 + 2] = 0; - } else { - out[i * 3 + 0] = tprev[i * 3 + 0]; - out[i * 3 + 1] = tprev[i * 3 + 1]; - out[i * 3 + 2] = tprev[i * 3 + 2]; - } - } - } - out += stride; - tprev += stride; - } - - if(d) { /* apply XOR'ed difference */ - out = output + x * 3; - for(j = 0; j < bh2; j++){ - for(i = 0; i < bw2; i++) { - out[i * 3 + 0] ^= *src++; - out[i * 3 + 1] ^= *src++; - out[i * 3 + 2] ^= *src++; - } - out += stride; - } - } - } - output += stride * c->bh; - prev += stride * c->bh; - } - if(src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); - return 0; -} -#endif //ZMBV_ENABLE_24BPP - -/** - * Decode XOR'ed frame - 32bpp version - */ - -static int zmbv_decode_xor_32(ZmbvContext *c) -{ - uint8_t *src = c->decomp_buf; - uint32_t *output, *prev; - int8_t *mvec; - int x, y; - int d, dx, dy, bw2, bh2; - int block; - int i, j; - int mx, my; - - output = (uint32_t*)c->cur; - prev = (uint32_t*)c->prev; - - mvec = (int8_t*)src; - src += ((c->bx * c->by * 2 + 3) & ~3); - - block = 0; - for(y = 0; y < c->height; y += c->bh) { - bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); - for(x = 0; x < c->width; x += c->bw) { - uint32_t *out, *tprev; - - d = mvec[block] & 1; - dx = mvec[block] >> 1; - dy = mvec[block + 1] >> 1; - block += 2; - - bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); - - /* copy block - motion vectors out of bounds are used to zero blocks */ - out = output + x; - tprev = prev + x + dx + dy * c->width; - mx = x + dx; - my = y + dy; - for(j = 0; j < bh2; j++){ - if((my + j < 0) || (my + j >= c->height)) { - memset(out, 0, bw2 * 4); - } else { - for(i = 0; i < bw2; i++){ - if((mx + i < 0) || (mx + i >= c->width)) - out[i] = 0; - else - out[i] = tprev[i]; - } - } - out += c->width; - tprev += c->width; - } - - if(d) { /* apply XOR'ed difference */ - out = output + x; - for(j = 0; j < bh2; j++){ - for(i = 0; i < bw2; i++) { - out[i] ^= *((uint32_t*)src); - src += 4; - } - out += c->width; - } - } - } - output += c->width * c->bh; - prev += c->width * c->bh; - } - if(src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len); - return 0; -} - -/** - * Decode intraframe - */ -static int zmbv_decode_intra(ZmbvContext *c) -{ - uint8_t *src = c->decomp_buf; - - /* make the palette available on the way out */ - if (c->fmt == ZMBV_FMT_8BPP) { - memcpy(c->pal, src, 768); - src += 768; - } - - memcpy(c->cur, src, c->width * c->height * (c->bpp / 8)); - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - ZmbvContext * const c = avctx->priv_data; - uint8_t *outptr; - int zret = Z_OK; // Zlib return code - int len = buf_size; - int hi_ver, lo_ver; - - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 1; - 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 - - /* parse header */ - c->flags = buf[0]; - buf++; len--; - if(c->flags & ZMBV_KEYFRAME) { - hi_ver = buf[0]; - lo_ver = buf[1]; - c->comp = buf[2]; - c->fmt = buf[3]; - c->bw = buf[4]; - c->bh = buf[5]; - - buf += 6; - len -= 6; - av_log(avctx, AV_LOG_DEBUG, "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh); - if(hi_ver != 0 || lo_ver != 1) { - av_log(avctx, AV_LOG_ERROR, "Unsupported version %i.%i\n", hi_ver, lo_ver); - return -1; - } - if(c->bw == 0 || c->bh == 0) { - av_log(avctx, AV_LOG_ERROR, "Unsupported block size %ix%i\n", c->bw, c->bh); - return -1; - } - if(c->comp != 0 && c->comp != 1) { - av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n", c->comp); - return -1; - } - - switch(c->fmt) { - case ZMBV_FMT_8BPP: - c->bpp = 8; - c->decode_intra = zmbv_decode_intra; - c->decode_xor = zmbv_decode_xor_8; - break; - case ZMBV_FMT_15BPP: - case ZMBV_FMT_16BPP: - c->bpp = 16; - c->decode_intra = zmbv_decode_intra; - c->decode_xor = zmbv_decode_xor_16; - break; -#ifdef ZMBV_ENABLE_24BPP - case ZMBV_FMT_24BPP: - c->bpp = 24; - c->decode_intra = zmbv_decode_intra; - c->decode_xor = zmbv_decode_xor_24; - break; -#endif //ZMBV_ENABLE_24BPP - case ZMBV_FMT_32BPP: - c->bpp = 32; - c->decode_intra = zmbv_decode_intra; - c->decode_xor = zmbv_decode_xor_32; - break; - default: - c->decode_intra = NULL; - c->decode_xor = NULL; - av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt); - return -1; - } - - zret = inflateReset(&c->zstream); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); - return -1; - } - - c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8)); - c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8)); - c->bx = (c->width + c->bw - 1) / c->bw; - c->by = (c->height+ c->bh - 1) / c->bh; - } - - if(c->decode_intra == NULL) { - av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n"); - return -1; - } - - if(c->comp == 0) { //Uncompressed data - memcpy(c->decomp_buf, buf, len); - c->decomp_size = 1; - } else { // ZLIB-compressed data - c->zstream.total_in = c->zstream.total_out = 0; - c->zstream.next_in = buf; - c->zstream.avail_in = len; - c->zstream.next_out = c->decomp_buf; - c->zstream.avail_out = c->decomp_size; - inflate(&c->zstream, Z_FINISH); - c->decomp_len = c->zstream.total_out; - } - if(c->flags & ZMBV_KEYFRAME) { - c->pic.key_frame = 1; - c->pic.pict_type = FF_I_TYPE; - c->decode_intra(c); - } else { - c->pic.key_frame = 0; - c->pic.pict_type = FF_P_TYPE; - if(c->decomp_len) - c->decode_xor(c); - } - - /* update frames */ - { - uint8_t *out, *src; - int i, j; - - out = c->pic.data[0]; - src = c->cur; - switch(c->fmt) { - case ZMBV_FMT_8BPP: - for(j = 0; j < c->height; j++) { - for(i = 0; i < c->width; i++) { - out[i * 3 + 0] = c->pal[(*src) * 3 + 0]; - out[i * 3 + 1] = c->pal[(*src) * 3 + 1]; - out[i * 3 + 2] = c->pal[(*src) * 3 + 2]; - src++; - } - out += c->pic.linesize[0]; - } - break; - case ZMBV_FMT_15BPP: - for(j = 0; j < c->height; j++) { - for(i = 0; i < c->width; i++) { - uint16_t tmp = AV_RL16(src); - src += 2; - out[i * 3 + 0] = (tmp & 0x7C00) >> 7; - out[i * 3 + 1] = (tmp & 0x03E0) >> 2; - out[i * 3 + 2] = (tmp & 0x001F) << 3; - } - out += c->pic.linesize[0]; - } - break; - case ZMBV_FMT_16BPP: - for(j = 0; j < c->height; j++) { - for(i = 0; i < c->width; i++) { - uint16_t tmp = AV_RL16(src); - src += 2; - out[i * 3 + 0] = (tmp & 0xF800) >> 8; - out[i * 3 + 1] = (tmp & 0x07E0) >> 3; - out[i * 3 + 2] = (tmp & 0x001F) << 3; - } - out += c->pic.linesize[0]; - } - break; -#ifdef ZMBV_ENABLE_24BPP - case ZMBV_FMT_24BPP: - for(j = 0; j < c->height; j++) { - memcpy(out, src, c->width * 3); - src += c->width * 3; - out += c->pic.linesize[0]; - } - break; -#endif //ZMBV_ENABLE_24BPP - case ZMBV_FMT_32BPP: - for(j = 0; j < c->height; j++) { - for(i = 0; i < c->width; i++) { - uint32_t tmp = AV_RL32(src); - src += 4; - AV_WB24(out+(i*3), tmp); - } - out += c->pic.linesize[0]; - } - break; - default: - av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt); - } - memcpy(c->prev, c->cur, c->width * c->height * (c->bpp / 8)); - } - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - - - -/* - * - * Init zmbv decoder - * - */ -static av_cold int decode_init(AVCodecContext *avctx) -{ - ZmbvContext * const c = avctx->priv_data; - int zret; // Zlib return code - - c->avctx = avctx; - - c->width = avctx->width; - c->height = avctx->height; - - c->bpp = avctx->bits_per_coded_sample; - - // Needed if zlib unused or init aborted before inflateInit - memset(&(c->zstream), 0, sizeof(z_stream)); - - avctx->pix_fmt = PIX_FMT_RGB24; - c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64); - - /* Allocate decompression buffer */ - if (c->decomp_size) { - if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; - } - } - - 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; - } - - return 0; -} - - - -/* - * - * Uninit zmbv decoder - * - */ -static av_cold int decode_end(AVCodecContext *avctx) -{ - ZmbvContext * const c = avctx->priv_data; - - av_freep(&c->decomp_buf); - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - inflateEnd(&(c->zstream)); - av_freep(&c->cur); - av_freep(&c->prev); - - return 0; -} - -AVCodec zmbv_decoder = { - "zmbv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ZMBV, - sizeof(ZmbvContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), -}; - diff --git a/tizen/distrib/ffmpeg/libavcodec/zmbvenc.c b/tizen/distrib/ffmpeg/libavcodec/zmbvenc.c deleted file mode 100644 index 95f2906..0000000 --- a/tizen/distrib/ffmpeg/libavcodec/zmbvenc.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Zip Motion Blocks Video (ZMBV) encoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Zip Motion Blocks Video encoder - */ - -#include -#include - -#include "libavutil/intreadwrite.h" -#include "avcodec.h" - -#include - -#define ZMBV_KEYFRAME 1 -#define ZMBV_DELTAPAL 2 - -#define ZMBV_BLOCK 16 - -/** - * Encoder context - */ -typedef struct ZmbvEncContext { - AVCodecContext *avctx; - AVFrame pic; - - int range; - uint8_t *comp_buf, *work_buf; - uint8_t pal[768]; - uint32_t pal2[256]; //for quick comparisons - uint8_t *prev; - int pstride; - int comp_size; - int keyint, curfrm; - z_stream zstream; -} ZmbvEncContext; - -static int score_tab[256]; - -/** Block comparing function - * XXX should be optimized and moved to DSPContext - * TODO handle out of edge ME - */ -static inline int block_cmp(uint8_t *src, int stride, uint8_t *src2, int stride2, - int bw, int bh, int *xored) -{ - int sum = 0; - int i, j; - uint8_t histogram[256] = {0}; - - *xored = 0; - for(j = 0; j < bh; j++){ - for(i = 0; i < bw; i++){ - int t = src[i] ^ src2[i]; - histogram[t]++; - *xored |= t; - } - src += stride; - src2 += stride2; - } - - for(i = 1; i < 256; i++) - sum += score_tab[histogram[i]]; - - return sum; -} - -/** Motion estimation function - * TODO make better ME decisions - */ -static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, - int pstride, int x, int y, int *mx, int *my, int *xored) -{ - int dx, dy, tx, ty, tv, bv, bw, bh; - - *mx = *my = 0; - bw = FFMIN(ZMBV_BLOCK, c->avctx->width - x); - bh = FFMIN(ZMBV_BLOCK, c->avctx->height - y); - bv = block_cmp(src, sstride, prev, pstride, bw, bh, xored); - if(!bv) return 0; - for(ty = FFMAX(y - c->range, 0); ty < FFMIN(y + c->range, c->avctx->height - bh); ty++){ - for(tx = FFMAX(x - c->range, 0); tx < FFMIN(x + c->range, c->avctx->width - bw); tx++){ - if(tx == x && ty == y) continue; // we already tested this block - dx = tx - x; - dy = ty - y; - tv = block_cmp(src, sstride, prev + dx + dy*pstride, pstride, bw, bh, xored); - if(tv < bv){ - bv = tv; - *mx = dx; - *my = dy; - if(!bv) return 0; - } - } - } - return bv; -} - -static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) -{ - ZmbvEncContext * const c = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p = &c->pic; - uint8_t *src, *prev; - uint32_t *palptr; - int len = 0; - int keyframe, chpal; - int fl; - int work_size = 0; - int bw, bh; - int i, j; - - keyframe = !c->curfrm; - c->curfrm++; - if(c->curfrm == c->keyint) - c->curfrm = 0; - *p = *pict; - p->pict_type= keyframe ? FF_I_TYPE : FF_P_TYPE; - p->key_frame= keyframe; - chpal = !keyframe && memcmp(p->data[1], c->pal2, 1024); - - fl = (keyframe ? ZMBV_KEYFRAME : 0) | (chpal ? ZMBV_DELTAPAL : 0); - *buf++ = fl; len++; - if(keyframe){ - deflateReset(&c->zstream); - *buf++ = 0; len++; // hi ver - *buf++ = 1; len++; // lo ver - *buf++ = 1; len++; // comp - *buf++ = 4; len++; // format - 8bpp - *buf++ = ZMBV_BLOCK; len++; // block width - *buf++ = ZMBV_BLOCK; len++; // block height - } - palptr = (uint32_t*)p->data[1]; - src = p->data[0]; - prev = c->prev; - if(chpal){ - uint8_t tpal[3]; - for(i = 0; i < 256; i++){ - AV_WB24(tpal, palptr[i]); - c->work_buf[work_size++] = tpal[0] ^ c->pal[i * 3 + 0]; - c->work_buf[work_size++] = tpal[1] ^ c->pal[i * 3 + 1]; - c->work_buf[work_size++] = tpal[2] ^ c->pal[i * 3 + 2]; - c->pal[i * 3 + 0] = tpal[0]; - c->pal[i * 3 + 1] = tpal[1]; - c->pal[i * 3 + 2] = tpal[2]; - } - memcpy(c->pal2, p->data[1], 1024); - } - if(keyframe){ - for(i = 0; i < 256; i++){ - AV_WB24(c->pal+(i*3), palptr[i]); - } - memcpy(c->work_buf, c->pal, 768); - memcpy(c->pal2, p->data[1], 1024); - work_size = 768; - for(i = 0; i < avctx->height; i++){ - memcpy(c->work_buf + work_size, src, avctx->width); - src += p->linesize[0]; - work_size += avctx->width; - } - }else{ - int x, y, bh2, bw2, xored; - uint8_t *tsrc, *tprev; - uint8_t *mv; - int mx, my, bv; - - bw = (avctx->width + ZMBV_BLOCK - 1) / ZMBV_BLOCK; - bh = (avctx->height + ZMBV_BLOCK - 1) / ZMBV_BLOCK; - mv = c->work_buf + work_size; - memset(c->work_buf + work_size, 0, (bw * bh * 2 + 3) & ~3); - work_size += (bw * bh * 2 + 3) & ~3; - /* for now just XOR'ing */ - for(y = 0; y < avctx->height; y += ZMBV_BLOCK) { - bh2 = FFMIN(avctx->height - y, ZMBV_BLOCK); - for(x = 0; x < avctx->width; x += ZMBV_BLOCK, mv += 2) { - bw2 = FFMIN(avctx->width - x, ZMBV_BLOCK); - - tsrc = src + x; - tprev = prev + x; - - bv = zmbv_me(c, tsrc, p->linesize[0], tprev, c->pstride, x, y, &mx, &my, &xored); - mv[0] = (mx << 1) | !!xored; - mv[1] = my << 1; - tprev += mx + my * c->pstride; - if(xored){ - for(j = 0; j < bh2; j++){ - for(i = 0; i < bw2; i++) - c->work_buf[work_size++] = tsrc[i] ^ tprev[i]; - tsrc += p->linesize[0]; - tprev += c->pstride; - } - } - } - src += p->linesize[0] * ZMBV_BLOCK; - prev += c->pstride * ZMBV_BLOCK; - } - } - /* save the previous frame */ - src = p->data[0]; - prev = c->prev; - for(i = 0; i < avctx->height; i++){ - memcpy(prev, src, avctx->width); - prev += c->pstride; - src += p->linesize[0]; - } - - c->zstream.next_in = c->work_buf; - c->zstream.avail_in = work_size; - c->zstream.total_in = 0; - - c->zstream.next_out = c->comp_buf; - c->zstream.avail_out = c->comp_size; - c->zstream.total_out = 0; - if(deflate(&c->zstream, Z_SYNC_FLUSH) != Z_OK){ - av_log(avctx, AV_LOG_ERROR, "Error compressing data\n"); - return -1; - } - - memcpy(buf, c->comp_buf, c->zstream.total_out); - return len + c->zstream.total_out; -} - - -/** - * Init zmbv encoder - */ -static av_cold int encode_init(AVCodecContext *avctx) -{ - ZmbvEncContext * const c = avctx->priv_data; - int zret; // Zlib return code - int i; - int lvl = 9; - - for(i=1; i<256; i++) - score_tab[i]= -i * log(i/(double)(ZMBV_BLOCK*ZMBV_BLOCK)) * (256/M_LN2); - - c->avctx = avctx; - - c->curfrm = 0; - c->keyint = avctx->keyint_min; - c->range = 8; - if(avctx->me_range > 0) - c->range = FFMIN(avctx->me_range, 127); - - if(avctx->compression_level >= 0) - lvl = avctx->compression_level; - if(lvl < 0 || lvl > 9){ - av_log(avctx, AV_LOG_ERROR, "Compression level should be 0-9, not %i\n", lvl); - return -1; - } - - // Needed if zlib unused or init aborted before deflateInit - memset(&(c->zstream), 0, sizeof(z_stream)); - c->comp_size = avctx->width * avctx->height + 1024 + - ((avctx->width + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * ((avctx->height + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * 2 + 4; - if ((c->work_buf = av_malloc(c->comp_size)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate work buffer.\n"); - return -1; - } - /* Conservative upper bound taken from zlib v1.2.1 source via lcl.c */ - c->comp_size = c->comp_size + ((c->comp_size + 7) >> 3) + - ((c->comp_size + 63) >> 6) + 11; - - /* Allocate compression buffer */ - if ((c->comp_buf = av_malloc(c->comp_size)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); - return -1; - } - c->pstride = FFALIGN(avctx->width, 16); - if ((c->prev = av_malloc(c->pstride * avctx->height)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate picture.\n"); - return -1; - } - - c->zstream.zalloc = Z_NULL; - c->zstream.zfree = Z_NULL; - c->zstream.opaque = Z_NULL; - zret = deflateInit(&(c->zstream), lvl); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); - return -1; - } - - avctx->coded_frame = (AVFrame*)&c->pic; - - return 0; -} - - - -/** - * Uninit zmbv encoder - */ -static av_cold int encode_end(AVCodecContext *avctx) -{ - ZmbvEncContext * const c = avctx->priv_data; - - av_freep(&c->comp_buf); - av_freep(&c->work_buf); - - deflateEnd(&(c->zstream)); - av_freep(&c->prev); - - return 0; -} - -AVCodec zmbv_encoder = { - "zmbv", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_ZMBV, - sizeof(ZmbvEncContext), - encode_init, - encode_frame, - encode_end, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_PAL8, PIX_FMT_NONE}, - .long_name = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"), -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/Makefile b/tizen/distrib/ffmpeg/libavdevice/Makefile deleted file mode 100644 index a0c3858..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = avdevice -FFLIBS = avformat avcodec avutil - -HEADERS = avdevice.h - -OBJS = alldevices.o avdevice.o - -# input/output devices -OBJS-$(CONFIG_ALSA_INDEV) += alsa-audio-common.o \ - alsa-audio-dec.o -OBJS-$(CONFIG_ALSA_OUTDEV) += alsa-audio-common.o \ - alsa-audio-enc.o -OBJS-$(CONFIG_BKTR_INDEV) += bktr.o -OBJS-$(CONFIG_DV1394_INDEV) += dv1394.o -OBJS-$(CONFIG_JACK_INDEV) += jack_audio.o -OBJS-$(CONFIG_OSS_INDEV) += oss_audio.o -OBJS-$(CONFIG_OSS_OUTDEV) += oss_audio.o -OBJS-$(CONFIG_V4L2_INDEV) += v4l2.o -OBJS-$(CONFIG_V4L_INDEV) += v4l.o -OBJS-$(CONFIG_VFWCAP_INDEV) += vfwcap.o -OBJS-$(CONFIG_X11_GRAB_DEVICE_INDEV) += x11grab.o - -# external libraries -OBJS-$(CONFIG_LIBDC1394_INDEV) += libdc1394.o - -OBJS-$(CONFIG_AUDIO_BEOS_INDEV) += beosaudio.o -OBJS-$(CONFIG_AUDIO_BEOS_OUTDEV) += beosaudio.o - -SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H) += alsa-audio.h - -include $(SUBDIR)../subdir.mak diff --git a/tizen/distrib/ffmpeg/libavdevice/alldevices.c b/tizen/distrib/ffmpeg/libavdevice/alldevices.c deleted file mode 100644 index e7a9a5e..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/alldevices.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Register all the grabbing devices. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "libavformat/avformat.h" -#include "avdevice.h" - -#define REGISTER_OUTDEV(X,x) { \ - extern AVOutputFormat x##_muxer; \ - if(CONFIG_##X##_OUTDEV) av_register_output_format(&x##_muxer); } -#define REGISTER_INDEV(X,x) { \ - extern AVInputFormat x##_demuxer; \ - if(CONFIG_##X##_INDEV) av_register_input_format(&x##_demuxer); } -#define REGISTER_INOUTDEV(X,x) REGISTER_OUTDEV(X,x); REGISTER_INDEV(X,x) - -void avdevice_register_all(void) -{ - static int initialized; - - if (initialized) - return; - initialized = 1; - - /* devices */ - REGISTER_INOUTDEV (ALSA, alsa); - REGISTER_INOUTDEV (AUDIO_BEOS, audio_beos); - REGISTER_INDEV (BKTR, bktr); - REGISTER_INDEV (DV1394, dv1394); - REGISTER_INDEV (JACK, jack); - REGISTER_INOUTDEV (OSS, oss); - REGISTER_INDEV (V4L2, v4l2); - REGISTER_INDEV (V4L, v4l); - REGISTER_INDEV (VFWCAP, vfwcap); - REGISTER_INDEV (X11_GRAB_DEVICE, x11_grab_device); - - /* external libraries */ - REGISTER_INDEV (LIBDC1394, libdc1394); -} diff --git a/tizen/distrib/ffmpeg/libavdevice/alsa-audio-common.c b/tizen/distrib/ffmpeg/libavdevice/alsa-audio-common.c deleted file mode 100644 index 38cb0de..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/alsa-audio-common.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * ALSA input and output - * Copyright (c) 2007 Luca Abeni ( lucabe72 email it ) - * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * ALSA input and output: common code - * @author Luca Abeni ( lucabe72 email it ) - * @author Benoit Fouet ( benoit fouet free fr ) - * @author Nicolas George ( nicolas george normalesup org ) - */ - -#include -#include "libavformat/avformat.h" - -#include "alsa-audio.h" - -static av_cold snd_pcm_format_t codec_id_to_pcm_format(int codec_id) -{ - switch(codec_id) { - case CODEC_ID_PCM_S16LE: return SND_PCM_FORMAT_S16_LE; - case CODEC_ID_PCM_S16BE: return SND_PCM_FORMAT_S16_BE; - case CODEC_ID_PCM_S8: return SND_PCM_FORMAT_S8; - default: return SND_PCM_FORMAT_UNKNOWN; - } -} - -av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode, - unsigned int *sample_rate, - int channels, enum CodecID *codec_id) -{ - AlsaData *s = ctx->priv_data; - const char *audio_device; - int res, flags = 0; - snd_pcm_format_t format; - snd_pcm_t *h; - snd_pcm_hw_params_t *hw_params; - snd_pcm_uframes_t buffer_size, period_size; - - if (ctx->filename[0] == 0) audio_device = "default"; - else audio_device = ctx->filename; - - if (*codec_id == CODEC_ID_NONE) - *codec_id = DEFAULT_CODEC_ID; - format = codec_id_to_pcm_format(*codec_id); - if (format == SND_PCM_FORMAT_UNKNOWN) { - av_log(ctx, AV_LOG_ERROR, "sample format 0x%04x is not supported\n", *codec_id); - return AVERROR(ENOSYS); - } - s->frame_size = av_get_bits_per_sample(*codec_id) / 8 * channels; - - if (ctx->flags & AVFMT_FLAG_NONBLOCK) { - flags = SND_PCM_NONBLOCK; - } - res = snd_pcm_open(&h, audio_device, mode, flags); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot open audio device %s (%s)\n", - audio_device, snd_strerror(res)); - return AVERROR(EIO); - } - - res = snd_pcm_hw_params_malloc(&hw_params); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot allocate hardware parameter structure (%s)\n", - snd_strerror(res)); - goto fail1; - } - - res = snd_pcm_hw_params_any(h, hw_params); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot initialize hardware parameter structure (%s)\n", - snd_strerror(res)); - goto fail; - } - - res = snd_pcm_hw_params_set_access(h, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot set access type (%s)\n", - snd_strerror(res)); - goto fail; - } - - res = snd_pcm_hw_params_set_format(h, hw_params, format); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot set sample format 0x%04x %d (%s)\n", - *codec_id, format, snd_strerror(res)); - goto fail; - } - - res = snd_pcm_hw_params_set_rate_near(h, hw_params, sample_rate, 0); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot set sample rate (%s)\n", - snd_strerror(res)); - goto fail; - } - - res = snd_pcm_hw_params_set_channels(h, hw_params, channels); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot set channel count to %d (%s)\n", - channels, snd_strerror(res)); - goto fail; - } - - snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size); - /* TODO: maybe use ctx->max_picture_buffer somehow */ - res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot set ALSA buffer size (%s)\n", - snd_strerror(res)); - goto fail; - } - - snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL); - res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size, NULL); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot set ALSA period size (%s)\n", - snd_strerror(res)); - goto fail; - } - s->period_size = period_size; - - res = snd_pcm_hw_params(h, hw_params); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "cannot set parameters (%s)\n", - snd_strerror(res)); - goto fail; - } - - snd_pcm_hw_params_free(hw_params); - - s->h = h; - return 0; - -fail: - snd_pcm_hw_params_free(hw_params); -fail1: - snd_pcm_close(h); - return AVERROR(EIO); -} - -av_cold int ff_alsa_close(AVFormatContext *s1) -{ - AlsaData *s = s1->priv_data; - - snd_pcm_close(s->h); - return 0; -} - -int ff_alsa_xrun_recover(AVFormatContext *s1, int err) -{ - AlsaData *s = s1->priv_data; - snd_pcm_t *handle = s->h; - - av_log(s1, AV_LOG_WARNING, "ALSA buffer xrun.\n"); - if (err == -EPIPE) { - err = snd_pcm_prepare(handle); - if (err < 0) { - av_log(s1, AV_LOG_ERROR, "cannot recover from underrun (snd_pcm_prepare failed: %s)\n", snd_strerror(err)); - - return AVERROR(EIO); - } - } else if (err == -ESTRPIPE) { - av_log(s1, AV_LOG_ERROR, "-ESTRPIPE... Unsupported!\n"); - - return -1; - } - return err; -} diff --git a/tizen/distrib/ffmpeg/libavdevice/alsa-audio-dec.c b/tizen/distrib/ffmpeg/libavdevice/alsa-audio-dec.c deleted file mode 100644 index f1dd29b..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/alsa-audio-dec.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * ALSA input and output - * Copyright (c) 2007 Luca Abeni ( lucabe72 email it ) - * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * ALSA input and output: input - * @author Luca Abeni ( lucabe72 email it ) - * @author Benoit Fouet ( benoit fouet free fr ) - * @author Nicolas George ( nicolas george normalesup org ) - * - * This avdevice decoder allows to capture audio from an ALSA (Advanced - * Linux Sound Architecture) device. - * - * The filename parameter is the name of an ALSA PCM device capable of - * capture, for example "default" or "plughw:1"; see the ALSA documentation - * for naming conventions. The empty string is equivalent to "default". - * - * The capture period is set to the lower value available for the device, - * which gives a low latency suitable for real-time capture. - * - * The PTS are an Unix time in microsecond. - * - * Due to a bug in the ALSA library - * (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4308), this - * decoder does not work with certain ALSA plugins, especially the dsnoop - * plugin. - */ - -#include -#include "libavformat/avformat.h" - -#include "alsa-audio.h" - -static av_cold int audio_read_header(AVFormatContext *s1, - AVFormatParameters *ap) -{ - AlsaData *s = s1->priv_data; - AVStream *st; - int ret; - unsigned int sample_rate; - enum CodecID codec_id; - snd_pcm_sw_params_t *sw_params; - - if (ap->sample_rate <= 0) { - av_log(s1, AV_LOG_ERROR, "Bad sample rate %d\n", ap->sample_rate); - - return AVERROR(EIO); - } - - if (ap->channels <= 0) { - av_log(s1, AV_LOG_ERROR, "Bad channels number %d\n", ap->channels); - - return AVERROR(EIO); - } - - st = av_new_stream(s1, 0); - if (!st) { - av_log(s1, AV_LOG_ERROR, "Cannot add stream\n"); - - return AVERROR(ENOMEM); - } - sample_rate = ap->sample_rate; - codec_id = s1->audio_codec_id; - - ret = ff_alsa_open(s1, SND_PCM_STREAM_CAPTURE, &sample_rate, ap->channels, - &codec_id); - if (ret < 0) { - return AVERROR(EIO); - } - - if (snd_pcm_type(s->h) != SND_PCM_TYPE_HW) - av_log(s1, AV_LOG_WARNING, - "capture with some ALSA plugins, especially dsnoop, " - "may hang.\n"); - - ret = snd_pcm_sw_params_malloc(&sw_params); - if (ret < 0) { - av_log(s1, AV_LOG_ERROR, "cannot allocate software parameters structure (%s)\n", - snd_strerror(ret)); - goto fail; - } - - snd_pcm_sw_params_current(s->h, sw_params); - snd_pcm_sw_params_set_tstamp_mode(s->h, sw_params, SND_PCM_TSTAMP_ENABLE); - - ret = snd_pcm_sw_params(s->h, sw_params); - snd_pcm_sw_params_free(sw_params); - if (ret < 0) { - av_log(s1, AV_LOG_ERROR, "cannot install ALSA software parameters (%s)\n", - snd_strerror(ret)); - goto fail; - } - - /* take real parameters */ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = codec_id; - st->codec->sample_rate = sample_rate; - st->codec->channels = ap->channels; - av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - - return 0; - -fail: - snd_pcm_close(s->h); - return AVERROR(EIO); -} - -static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AlsaData *s = s1->priv_data; - AVStream *st = s1->streams[0]; - int res; - snd_htimestamp_t timestamp; - snd_pcm_uframes_t ts_delay; - - if (av_new_packet(pkt, s->period_size) < 0) { - return AVERROR(EIO); - } - - while ((res = snd_pcm_readi(s->h, pkt->data, pkt->size / s->frame_size)) < 0) { - if (res == -EAGAIN) { - av_free_packet(pkt); - - return AVERROR(EAGAIN); - } - if (ff_alsa_xrun_recover(s1, res) < 0) { - av_log(s1, AV_LOG_ERROR, "ALSA read error: %s\n", - snd_strerror(res)); - av_free_packet(pkt); - - return AVERROR(EIO); - } - } - - snd_pcm_htimestamp(s->h, &ts_delay, ×tamp); - ts_delay += res; - pkt->pts = timestamp.tv_sec * 1000000LL - + (timestamp.tv_nsec * st->codec->sample_rate - - ts_delay * 1000000000LL + st->codec->sample_rate * 500LL) - / (st->codec->sample_rate * 1000LL); - - pkt->size = res * s->frame_size; - - return 0; -} - -AVInputFormat alsa_demuxer = { - "alsa", - NULL_IF_CONFIG_SMALL("ALSA audio input"), - sizeof(AlsaData), - NULL, - audio_read_header, - audio_read_packet, - ff_alsa_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/alsa-audio-enc.c b/tizen/distrib/ffmpeg/libavdevice/alsa-audio-enc.c deleted file mode 100644 index 7c07bf7..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/alsa-audio-enc.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ALSA input and output - * Copyright (c) 2007 Luca Abeni ( lucabe72 email it ) - * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * ALSA input and output: output - * @author Luca Abeni ( lucabe72 email it ) - * @author Benoit Fouet ( benoit fouet free fr ) - * - * This avdevice encoder allows to play audio to an ALSA (Advanced Linux - * Sound Architecture) device. - * - * The filename parameter is the name of an ALSA PCM device capable of - * capture, for example "default" or "plughw:1"; see the ALSA documentation - * for naming conventions. The empty string is equivalent to "default". - * - * The playback period is set to the lower value available for the device, - * which gives a low latency suitable for real-time playback. - */ - -#include -#include "libavformat/avformat.h" - -#include "alsa-audio.h" - -static av_cold int audio_write_header(AVFormatContext *s1) -{ - AlsaData *s = s1->priv_data; - AVStream *st; - unsigned int sample_rate; - enum CodecID codec_id; - int res; - - st = s1->streams[0]; - sample_rate = st->codec->sample_rate; - codec_id = st->codec->codec_id; - res = ff_alsa_open(s1, SND_PCM_STREAM_PLAYBACK, &sample_rate, - st->codec->channels, &codec_id); - if (sample_rate != st->codec->sample_rate) { - av_log(s1, AV_LOG_ERROR, - "sample rate %d not available, nearest is %d\n", - st->codec->sample_rate, sample_rate); - goto fail; - } - - return res; - -fail: - snd_pcm_close(s->h); - return AVERROR(EIO); -} - -static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AlsaData *s = s1->priv_data; - int res; - int size = pkt->size; - uint8_t *buf = pkt->data; - - while((res = snd_pcm_writei(s->h, buf, size / s->frame_size)) < 0) { - if (res == -EAGAIN) { - - return AVERROR(EAGAIN); - } - - if (ff_alsa_xrun_recover(s1, res) < 0) { - av_log(s1, AV_LOG_ERROR, "ALSA write error: %s\n", - snd_strerror(res)); - - return AVERROR(EIO); - } - } - - return 0; -} - -AVOutputFormat alsa_muxer = { - "alsa", - NULL_IF_CONFIG_SMALL("ALSA audio output"), - "", - "", - sizeof(AlsaData), - DEFAULT_CODEC_ID, - CODEC_ID_NONE, - audio_write_header, - audio_write_packet, - ff_alsa_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/alsa-audio.h b/tizen/distrib/ffmpeg/libavdevice/alsa-audio.h deleted file mode 100644 index 9a8a089..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/alsa-audio.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * ALSA input and output - * Copyright (c) 2007 Luca Abeni ( lucabe72 email it ) - * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr ) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * ALSA input and output: definitions and structures - * @author Luca Abeni ( lucabe72 email it ) - * @author Benoit Fouet ( benoit fouet free fr ) - */ - -#ifndef AVDEVICE_ALSA_AUDIO_H -#define AVDEVICE_ALSA_AUDIO_H - -#include -#include "config.h" -#include "libavformat/avformat.h" - -/* XXX: we make the assumption that the soundcard accepts this format */ -/* XXX: find better solution with "preinit" method, needed also in - other formats */ -#if HAVE_BIGENDIAN -#define DEFAULT_CODEC_ID CODEC_ID_PCM_S16BE -#else -#define DEFAULT_CODEC_ID CODEC_ID_PCM_S16LE -#endif - -typedef struct { - snd_pcm_t *h; - int frame_size; ///< preferred size for reads and writes - int period_size; ///< bytes per sample * channels -} AlsaData; - -/** - * Opens an ALSA PCM. - * - * @param s media file handle - * @param mode either SND_PCM_STREAM_CAPTURE or SND_PCM_STREAM_PLAYBACK - * @param sample_rate in: requested sample rate; - * out: actually selected sample rate - * @param channels number of channels - * @param codec_id in: requested CodecID or CODEC_ID_NONE; - * out: actually selected CodecID, changed only if - * CODEC_ID_NONE was requested - * - * @return 0 if OK, AVERROR_xxx on error - */ -int ff_alsa_open(AVFormatContext *s, snd_pcm_stream_t mode, - unsigned int *sample_rate, - int channels, enum CodecID *codec_id); - -/** - * Closes the ALSA PCM. - * - * @param s1 media file handle - * - * @return 0 - */ -int ff_alsa_close(AVFormatContext *s1); - -/** - * Tries to recover from ALSA buffer underrun. - * - * @param s1 media file handle - * @param err error code reported by the previous ALSA call - * - * @return 0 if OK, AVERROR_xxx on error - */ -int ff_alsa_xrun_recover(AVFormatContext *s1, int err); - -#endif /* AVDEVICE_ALSA_AUDIO_H */ diff --git a/tizen/distrib/ffmpeg/libavdevice/avdevice.c b/tizen/distrib/ffmpeg/libavdevice/avdevice.c deleted file mode 100644 index 3d67b4b..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/avdevice.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avdevice.h" - -unsigned avdevice_version(void) -{ - return LIBAVDEVICE_VERSION_INT; -} - -const char * avdevice_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char * avdevice_license(void) -{ -#define LICENSE_PREFIX "libavdevice license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} diff --git a/tizen/distrib/ffmpeg/libavdevice/avdevice.h b/tizen/distrib/ffmpeg/libavdevice/avdevice.h deleted file mode 100644 index dcd835c..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/avdevice.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVDEVICE_AVDEVICE_H -#define AVDEVICE_AVDEVICE_H - -#include "libavutil/avutil.h" - -#define LIBAVDEVICE_VERSION_MAJOR 52 -#define LIBAVDEVICE_VERSION_MINOR 2 -#define LIBAVDEVICE_VERSION_MICRO 0 - -#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ - LIBAVDEVICE_VERSION_MINOR, \ - LIBAVDEVICE_VERSION_MICRO) -#define LIBAVDEVICE_VERSION AV_VERSION(LIBAVDEVICE_VERSION_MAJOR, \ - LIBAVDEVICE_VERSION_MINOR, \ - LIBAVDEVICE_VERSION_MICRO) -#define LIBAVDEVICE_BUILD LIBAVDEVICE_VERSION_INT - -/** - * Returns the LIBAVDEVICE_VERSION_INT constant. - */ -unsigned avdevice_version(void); - -/** - * Returns the libavdevice build-time configuration. - */ -const char *avdevice_configuration(void); - -/** - * Returns the libavdevice license. - */ -const char *avdevice_license(void); - -/** - * Initialize libavdevice and register all the input and output devices. - * @warning This function is not thread safe. - */ -void avdevice_register_all(void); - -#endif /* AVDEVICE_AVDEVICE_H */ - diff --git a/tizen/distrib/ffmpeg/libavdevice/beosaudio.cpp b/tizen/distrib/ffmpeg/libavdevice/beosaudio.cpp deleted file mode 100644 index 9f32571..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/beosaudio.cpp +++ /dev/null @@ -1,467 +0,0 @@ -/* - * BeOS audio play interface - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -extern "C" { -#include "libavformat/avformat.h" -} - -#if HAVE_BSOUNDRECORDER -#include -using namespace BPrivate::Media::Experimental; -#endif - -/* enable performance checks */ -//#define PERF_CHECK - -/* enable Media Kit latency checks */ -//#define LATENCY_CHECK - -#define AUDIO_BLOCK_SIZE 4096 -#define AUDIO_BLOCK_COUNT 8 - -#define AUDIO_BUFFER_SIZE (AUDIO_BLOCK_SIZE*AUDIO_BLOCK_COUNT) - -typedef struct { - int fd; // UNUSED - int sample_rate; - int channels; - int frame_size; /* in bytes ! */ - CodecID codec_id; - uint8_t buffer[AUDIO_BUFFER_SIZE]; - int buffer_ptr; - /* ring buffer */ - sem_id input_sem; - int input_index; - sem_id output_sem; - int output_index; - BSoundPlayer *player; -#if HAVE_BSOUNDRECORDER - BSoundRecorder *recorder; -#endif - int has_quit; /* signal callbacks not to wait */ - volatile bigtime_t starve_time; -} AudioData; - -static thread_id main_thid; -static thread_id bapp_thid; -static int own_BApp_created = 0; -static int refcount = 0; - -/* create the BApplication and Run() it */ -static int32 bapp_thread(void *arg) -{ - new BApplication("application/x-vnd.ffmpeg"); - own_BApp_created = 1; - be_app->Run(); - /* kill the process group */ -// kill(0, SIGINT); -// kill(main_thid, SIGHUP); - return B_OK; -} - -/* create the BApplication only if needed */ -static void create_bapp_if_needed(void) -{ - if (refcount++ == 0) { - /* needed by libmedia */ - if (be_app == NULL) { - bapp_thid = spawn_thread(bapp_thread, "ffmpeg BApplication", B_NORMAL_PRIORITY, NULL); - resume_thread(bapp_thid); - while (!own_BApp_created) - snooze(50000); - } - } -} - -static void destroy_bapp_if_needed(void) -{ - if (--refcount == 0 && own_BApp_created) { - be_app->Lock(); - be_app->Quit(); - be_app = NULL; - } -} - -/* called back by BSoundPlayer */ -static void audioplay_callback(void *cookie, void *buffer, size_t bufferSize, const media_raw_audio_format &format) -{ - AudioData *s; - size_t len, amount; - unsigned char *buf = (unsigned char *)buffer; - - s = (AudioData *)cookie; - if (s->has_quit) - return; - while (bufferSize > 0) { -#ifdef PERF_CHECK - bigtime_t t; - t = system_time(); -#endif - len = MIN(AUDIO_BLOCK_SIZE, bufferSize); - if (acquire_sem_etc(s->output_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) { - s->has_quit = 1; - s->player->SetHasData(false); - return; - } - amount = MIN(len, (AUDIO_BUFFER_SIZE - s->output_index)); - memcpy(buf, &s->buffer[s->output_index], amount); - s->output_index += amount; - if (s->output_index >= AUDIO_BUFFER_SIZE) { - s->output_index %= AUDIO_BUFFER_SIZE; - memcpy(buf + amount, &s->buffer[s->output_index], len - amount); - s->output_index += len-amount; - s->output_index %= AUDIO_BUFFER_SIZE; - } - release_sem_etc(s->input_sem, len, 0); -#ifdef PERF_CHECK - t = system_time() - t; - s->starve_time = MAX(s->starve_time, t); -#endif - buf += len; - bufferSize -= len; - } -} - -#if HAVE_BSOUNDRECORDER -/* called back by BSoundRecorder */ -static void audiorecord_callback(void *cookie, bigtime_t timestamp, void *buffer, size_t bufferSize, const media_multi_audio_format &format) -{ - AudioData *s; - size_t len, amount; - unsigned char *buf = (unsigned char *)buffer; - - s = (AudioData *)cookie; - if (s->has_quit) - return; - - while (bufferSize > 0) { - len = MIN(bufferSize, AUDIO_BLOCK_SIZE); - //printf("acquire_sem(input, %d)\n", len); - if (acquire_sem_etc(s->input_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) { - s->has_quit = 1; - return; - } - amount = MIN(len, (AUDIO_BUFFER_SIZE - s->input_index)); - memcpy(&s->buffer[s->input_index], buf, amount); - s->input_index += amount; - if (s->input_index >= AUDIO_BUFFER_SIZE) { - s->input_index %= AUDIO_BUFFER_SIZE; - memcpy(&s->buffer[s->input_index], buf + amount, len - amount); - s->input_index += len - amount; - } - release_sem_etc(s->output_sem, len, 0); - //printf("release_sem(output, %d)\n", len); - buf += len; - bufferSize -= len; - } -} -#endif - -static int audio_open(AudioData *s, int is_output, const char *audio_device) -{ - int p[2]; - int ret; - media_raw_audio_format format; - media_multi_audio_format iformat; - -#if !HAVE_BSOUNDRECORDER - if (!is_output) - return AVERROR(EIO); /* not for now */ -#endif - s->input_sem = create_sem(AUDIO_BUFFER_SIZE, "ffmpeg_ringbuffer_input"); - if (s->input_sem < B_OK) - return AVERROR(EIO); - s->output_sem = create_sem(0, "ffmpeg_ringbuffer_output"); - if (s->output_sem < B_OK) { - delete_sem(s->input_sem); - return AVERROR(EIO); - } - s->input_index = 0; - s->output_index = 0; - create_bapp_if_needed(); - s->frame_size = AUDIO_BLOCK_SIZE; - /* bump up the priority (avoid realtime though) */ - set_thread_priority(find_thread(NULL), B_DISPLAY_PRIORITY+1); -#if HAVE_BSOUNDRECORDER - if (!is_output) { - bool wait_for_input = false; - if (audio_device && !strcmp(audio_device, "wait:")) - wait_for_input = true; - s->recorder = new BSoundRecorder(&iformat, wait_for_input, "ffmpeg input", audiorecord_callback); - if (wait_for_input && (s->recorder->InitCheck() == B_OK)) { - s->recorder->WaitForIncomingConnection(&iformat); - } - if (s->recorder->InitCheck() != B_OK || iformat.format != media_raw_audio_format::B_AUDIO_SHORT) { - delete s->recorder; - s->recorder = NULL; - if (s->input_sem) - delete_sem(s->input_sem); - if (s->output_sem) - delete_sem(s->output_sem); - return AVERROR(EIO); - } - s->codec_id = (iformat.byte_order == B_MEDIA_LITTLE_ENDIAN)?CODEC_ID_PCM_S16LE:CODEC_ID_PCM_S16BE; - s->channels = iformat.channel_count; - s->sample_rate = (int)iformat.frame_rate; - s->frame_size = iformat.buffer_size; - s->recorder->SetCookie(s); - s->recorder->SetVolume(1.0); - s->recorder->Start(); - return 0; - } -#endif - format = media_raw_audio_format::wildcard; - format.format = media_raw_audio_format::B_AUDIO_SHORT; - format.byte_order = B_HOST_IS_LENDIAN ? B_MEDIA_LITTLE_ENDIAN : B_MEDIA_BIG_ENDIAN; - format.channel_count = s->channels; - format.buffer_size = s->frame_size; - format.frame_rate = s->sample_rate; - s->player = new BSoundPlayer(&format, "ffmpeg output", audioplay_callback); - if (s->player->InitCheck() != B_OK) { - delete s->player; - s->player = NULL; - if (s->input_sem) - delete_sem(s->input_sem); - if (s->output_sem) - delete_sem(s->output_sem); - return AVERROR(EIO); - } - s->player->SetCookie(s); - s->player->SetVolume(1.0); - s->player->Start(); - s->player->SetHasData(true); - return 0; -} - -static int audio_close(AudioData *s) -{ - if (s->input_sem) - delete_sem(s->input_sem); - if (s->output_sem) - delete_sem(s->output_sem); - s->has_quit = 1; - if (s->player) { - s->player->Stop(); - } - if (s->player) - delete s->player; -#if HAVE_BSOUNDRECORDER - if (s->recorder) - delete s->recorder; -#endif - destroy_bapp_if_needed(); - return 0; -} - -/* sound output support */ -static int audio_write_header(AVFormatContext *s1) -{ - AudioData *s = (AudioData *)s1->priv_data; - AVStream *st; - int ret; - - st = s1->streams[0]; - s->sample_rate = st->codec->sample_rate; - s->channels = st->codec->channels; - ret = audio_open(s, 1, NULL); - if (ret < 0) - return AVERROR(EIO); - return 0; -} - -static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AudioData *s = (AudioData *)s1->priv_data; - int len, ret; - const uint8_t *buf = pkt->data; - int size = pkt->size; -#ifdef LATENCY_CHECK -bigtime_t lat1, lat2; -lat1 = s->player->Latency(); -#endif -#ifdef PERF_CHECK - bigtime_t t = s->starve_time; - s->starve_time = 0; - printf("starve_time: %lld \n", t); -#endif - while (size > 0) { - int amount; - len = MIN(size, AUDIO_BLOCK_SIZE); - if (acquire_sem_etc(s->input_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) - return AVERROR(EIO); - amount = MIN(len, (AUDIO_BUFFER_SIZE - s->input_index)); - memcpy(&s->buffer[s->input_index], buf, amount); - s->input_index += amount; - if (s->input_index >= AUDIO_BUFFER_SIZE) { - s->input_index %= AUDIO_BUFFER_SIZE; - memcpy(&s->buffer[s->input_index], buf + amount, len - amount); - s->input_index += len - amount; - } - release_sem_etc(s->output_sem, len, 0); - buf += len; - size -= len; - } -#ifdef LATENCY_CHECK -lat2 = s->player->Latency(); -printf("#### BSoundPlayer::Latency(): before= %lld, after= %lld\n", lat1, lat2); -#endif - return 0; -} - -static int audio_write_trailer(AVFormatContext *s1) -{ - AudioData *s = (AudioData *)s1->priv_data; - - audio_close(s); - return 0; -} - -/* grab support */ - -static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - AudioData *s = (AudioData *)s1->priv_data; - AVStream *st; - int ret; - - if (!ap || ap->sample_rate <= 0 || ap->channels <= 0) - return -1; - - st = av_new_stream(s1, 0); - if (!st) { - return AVERROR(ENOMEM); - } - s->sample_rate = ap->sample_rate; - s->channels = ap->channels; - - ret = audio_open(s, 0, s1->filename); - if (ret < 0) { - av_free(st); - return AVERROR(EIO); - } - /* take real parameters */ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->codec_id; - st->codec->sample_rate = s->sample_rate; - st->codec->channels = s->channels; - return 0; - av_set_pts_info(st, 48, 1, 1000000); /* 48 bits pts in us */ -} - -static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AudioData *s = (AudioData *)s1->priv_data; - int size; - size_t len, amount; - unsigned char *buf; - status_t err; - - if (av_new_packet(pkt, s->frame_size) < 0) - return AVERROR(EIO); - buf = (unsigned char *)pkt->data; - size = pkt->size; - while (size > 0) { - len = MIN(AUDIO_BLOCK_SIZE, size); - //printf("acquire_sem(output, %d)\n", len); - while ((err=acquire_sem_etc(s->output_sem, len, B_CAN_INTERRUPT, 0LL)) == B_INTERRUPTED); - if (err < B_OK) { - av_free_packet(pkt); - return AVERROR(EIO); - } - amount = MIN(len, (AUDIO_BUFFER_SIZE - s->output_index)); - memcpy(buf, &s->buffer[s->output_index], amount); - s->output_index += amount; - if (s->output_index >= AUDIO_BUFFER_SIZE) { - s->output_index %= AUDIO_BUFFER_SIZE; - memcpy(buf + amount, &s->buffer[s->output_index], len - amount); - s->output_index += len-amount; - s->output_index %= AUDIO_BUFFER_SIZE; - } - release_sem_etc(s->input_sem, len, 0); - //printf("release_sem(input, %d)\n", len); - buf += len; - size -= len; - } - //XXX: add pts info - return 0; -} - -static int audio_read_close(AVFormatContext *s1) -{ - AudioData *s = (AudioData *)s1->priv_data; - - audio_close(s); - return 0; -} - -static AVInputFormat audio_beos_demuxer = { - "audio_beos", - NULL_IF_CONFIG_SMALL("audio grab and output"), - sizeof(AudioData), - NULL, - audio_read_header, - audio_read_packet, - audio_read_close, - NULL, - NULL, - AVFMT_NOFILE, -}; - -AVOutputFormat audio_beos_muxer = { - "audio_beos", - NULL_IF_CONFIG_SMALL("audio grab and output"), - "", - "", - sizeof(AudioData), -#if HAVE_BIGENDIAN - CODEC_ID_PCM_S16BE, -#else - CODEC_ID_PCM_S16LE, -#endif - CODEC_ID_NONE, - audio_write_header, - audio_write_packet, - audio_write_trailer, - AVFMT_NOFILE, -}; - -extern "C" { - -int audio_init(void) -{ - main_thid = find_thread(NULL); - av_register_input_format(&audio_beos_demuxer); - av_register_output_format(&audio_beos_muxer); - return 0; -} - -} // "C" - diff --git a/tizen/distrib/ffmpeg/libavdevice/bktr.c b/tizen/distrib/ffmpeg/libavdevice/bktr.c deleted file mode 100644 index afb94b6..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/bktr.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * *BSD video grab interface - * Copyright (c) 2002 Steve O'Hara-Smith - * based on - * Linux video grab interface - * Copyright (c) 2000,2001 Gerard Lantau - * and - * simple_grab.c Copyright (c) 1999 Roger Hardiman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _BSD_SOURCE 1 -#define _NETBSD_SOURCE - -#include "libavformat/avformat.h" -#if HAVE_DEV_BKTR_IOCTL_METEOR_H && HAVE_DEV_BKTR_IOCTL_BT848_H -# include -# include -#elif HAVE_MACHINE_IOCTL_METEOR_H && HAVE_MACHINE_IOCTL_BT848_H -# include -# include -#elif HAVE_DEV_VIDEO_METEOR_IOCTL_METEOR_H && HAVE_DEV_VIDEO_BKTR_IOCTL_BT848_H -# include -# include -#elif HAVE_DEV_IC_BT8XX_H -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct { - int video_fd; - int tuner_fd; - int width, height; - int frame_rate; - int frame_rate_base; - uint64_t per_frame; -} VideoData; - - -#define PAL 1 -#define PALBDGHI 1 -#define NTSC 2 -#define NTSCM 2 -#define SECAM 3 -#define PALN 4 -#define PALM 5 -#define NTSCJ 6 - -/* PAL is 768 x 576. NTSC is 640 x 480 */ -#define PAL_HEIGHT 576 -#define SECAM_HEIGHT 576 -#define NTSC_HEIGHT 480 - -#ifndef VIDEO_FORMAT -#define VIDEO_FORMAT NTSC -#endif - -static int bktr_dev[] = { METEOR_DEV0, METEOR_DEV1, METEOR_DEV2, - METEOR_DEV3, METEOR_DEV_SVIDEO }; - -uint8_t *video_buf; -size_t video_buf_size; -uint64_t last_frame_time; -volatile sig_atomic_t nsignals; - - -static void catchsignal(int signal) -{ - nsignals++; - return; -} - -static av_cold int bktr_init(const char *video_device, int width, int height, - int format, int *video_fd, int *tuner_fd, int idev, double frequency) -{ - struct meteor_geomet geo; - int h_max; - long ioctl_frequency; - char *arg; - int c; - struct sigaction act, old; - - if (idev < 0 || idev > 4) - { - arg = getenv ("BKTR_DEV"); - if (arg) - idev = atoi (arg); - if (idev < 0 || idev > 4) - idev = 1; - } - - if (format < 1 || format > 6) - { - arg = getenv ("BKTR_FORMAT"); - if (arg) - format = atoi (arg); - if (format < 1 || format > 6) - format = VIDEO_FORMAT; - } - - if (frequency <= 0) - { - arg = getenv ("BKTR_FREQUENCY"); - if (arg) - frequency = atof (arg); - if (frequency <= 0) - frequency = 0.0; - } - - memset(&act, 0, sizeof(act)); - sigemptyset(&act.sa_mask); - act.sa_handler = catchsignal; - sigaction(SIGUSR1, &act, &old); - - *tuner_fd = open("/dev/tuner0", O_RDONLY); - if (*tuner_fd < 0) - av_log(NULL, AV_LOG_ERROR, "Warning. Tuner not opened, continuing: %s\n", strerror(errno)); - - *video_fd = open(video_device, O_RDONLY); - if (*video_fd < 0) { - av_log(NULL, AV_LOG_ERROR, "%s: %s\n", video_device, strerror(errno)); - return -1; - } - - geo.rows = height; - geo.columns = width; - geo.frames = 1; - geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12; - - switch (format) { - case PAL: h_max = PAL_HEIGHT; c = BT848_IFORM_F_PALBDGHI; break; - case PALN: h_max = PAL_HEIGHT; c = BT848_IFORM_F_PALN; break; - case PALM: h_max = PAL_HEIGHT; c = BT848_IFORM_F_PALM; break; - case SECAM: h_max = SECAM_HEIGHT; c = BT848_IFORM_F_SECAM; break; - case NTSC: h_max = NTSC_HEIGHT; c = BT848_IFORM_F_NTSCM; break; - case NTSCJ: h_max = NTSC_HEIGHT; c = BT848_IFORM_F_NTSCJ; break; - default: h_max = PAL_HEIGHT; c = BT848_IFORM_F_PALBDGHI; break; - } - - if (height <= h_max / 2) - geo.oformat |= METEOR_GEO_EVEN_ONLY; - - if (ioctl(*video_fd, METEORSETGEO, &geo) < 0) { - av_log(NULL, AV_LOG_ERROR, "METEORSETGEO: %s\n", strerror(errno)); - return -1; - } - - if (ioctl(*video_fd, BT848SFMT, &c) < 0) { - av_log(NULL, AV_LOG_ERROR, "BT848SFMT: %s\n", strerror(errno)); - return -1; - } - - c = bktr_dev[idev]; - if (ioctl(*video_fd, METEORSINPUT, &c) < 0) { - av_log(NULL, AV_LOG_ERROR, "METEORSINPUT: %s\n", strerror(errno)); - return -1; - } - - video_buf_size = width * height * 12 / 8; - - video_buf = (uint8_t *)mmap((caddr_t)0, video_buf_size, - PROT_READ, MAP_SHARED, *video_fd, (off_t)0); - if (video_buf == MAP_FAILED) { - av_log(NULL, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); - return -1; - } - - if (frequency != 0.0) { - ioctl_frequency = (unsigned long)(frequency*16); - if (ioctl(*tuner_fd, TVTUNER_SETFREQ, &ioctl_frequency) < 0) - av_log(NULL, AV_LOG_ERROR, "TVTUNER_SETFREQ: %s\n", strerror(errno)); - } - - c = AUDIO_UNMUTE; - if (ioctl(*tuner_fd, BT848_SAUDIO, &c) < 0) - av_log(NULL, AV_LOG_ERROR, "TVTUNER_SAUDIO: %s\n", strerror(errno)); - - c = METEOR_CAP_CONTINOUS; - ioctl(*video_fd, METEORCAPTUR, &c); - - c = SIGUSR1; - ioctl(*video_fd, METEORSSIGNAL, &c); - - return 0; -} - -static void bktr_getframe(uint64_t per_frame) -{ - uint64_t curtime; - - curtime = av_gettime(); - if (!last_frame_time - || ((last_frame_time + per_frame) > curtime)) { - if (!usleep(last_frame_time + per_frame + per_frame / 8 - curtime)) { - if (!nsignals) - av_log(NULL, AV_LOG_INFO, - "SLEPT NO signals - %d microseconds late\n", - (int)(av_gettime() - last_frame_time - per_frame)); - } - } - nsignals = 0; - last_frame_time = curtime; -} - - -/* note: we support only one picture read at a time */ -static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - VideoData *s = s1->priv_data; - - if (av_new_packet(pkt, video_buf_size) < 0) - return AVERROR(EIO); - - bktr_getframe(s->per_frame); - - pkt->pts = av_gettime(); - memcpy(pkt->data, video_buf, video_buf_size); - - return video_buf_size; -} - -static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - VideoData *s = s1->priv_data; - AVStream *st; - int width, height; - int frame_rate; - int frame_rate_base; - int format = -1; - - if (ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) - return -1; - - width = ap->width; - height = ap->height; - frame_rate = ap->time_base.den; - frame_rate_base = ap->time_base.num; - - st = av_new_stream(s1, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in use */ - - s->width = width; - s->height = height; - s->frame_rate = frame_rate; - s->frame_rate_base = frame_rate_base; - s->per_frame = ((uint64_t)1000000 * s->frame_rate_base) / s->frame_rate; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->pix_fmt = PIX_FMT_YUV420P; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->width = width; - st->codec->height = height; - st->codec->time_base.den = frame_rate; - st->codec->time_base.num = frame_rate_base; - - if (ap->standard) { - if (!strcasecmp(ap->standard, "pal")) - format = PAL; - else if (!strcasecmp(ap->standard, "secam")) - format = SECAM; - else if (!strcasecmp(ap->standard, "ntsc")) - format = NTSC; - } - - if (bktr_init(s1->filename, width, height, format, - &(s->video_fd), &(s->tuner_fd), -1, 0.0) < 0) - return AVERROR(EIO); - - nsignals = 0; - last_frame_time = 0; - - return 0; -} - -static int grab_read_close(AVFormatContext *s1) -{ - VideoData *s = s1->priv_data; - int c; - - c = METEOR_CAP_STOP_CONT; - ioctl(s->video_fd, METEORCAPTUR, &c); - close(s->video_fd); - - c = AUDIO_MUTE; - ioctl(s->tuner_fd, BT848_SAUDIO, &c); - close(s->tuner_fd); - - munmap((caddr_t)video_buf, video_buf_size); - - return 0; -} - -AVInputFormat bktr_demuxer = { - "bktr", - NULL_IF_CONFIG_SMALL("video grab"), - sizeof(VideoData), - NULL, - grab_read_header, - grab_read_packet, - grab_read_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/dv1394.c b/tizen/distrib/ffmpeg/libavdevice/dv1394.c deleted file mode 100644 index a55fa97..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/dv1394.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Linux DV1394 interface - * Copyright (c) 2003 Max Krasnyansky - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libavformat/avformat.h" - -#undef DV1394_DEBUG - -#include "libavformat/dv.h" -#include "dv1394.h" - -struct dv1394_data { - int fd; - int channel; - int format; - - uint8_t *ring; /* Ring buffer */ - int index; /* Current frame index */ - int avail; /* Number of frames available for reading */ - int done; /* Number of completed frames */ - - DVDemuxContext* dv_demux; /* Generic DV muxing/demuxing context */ -}; - -/* - * The trick here is to kludge around well known problem with kernel Ooopsing - * when you try to capture PAL on a device node configure for NTSC. That's - * why we have to configure the device node for PAL, and then read only NTSC - * amount of data. - */ -static int dv1394_reset(struct dv1394_data *dv) -{ - struct dv1394_init init; - - init.channel = dv->channel; - init.api_version = DV1394_API_VERSION; - init.n_frames = DV1394_RING_FRAMES; - init.format = DV1394_PAL; - - if (ioctl(dv->fd, DV1394_INIT, &init) < 0) - return -1; - - dv->avail = dv->done = 0; - return 0; -} - -static int dv1394_start(struct dv1394_data *dv) -{ - /* Tell DV1394 driver to enable receiver */ - if (ioctl(dv->fd, DV1394_START_RECEIVE, 0) < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to start receiver: %s\n", strerror(errno)); - return -1; - } - return 0; -} - -static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap) -{ - struct dv1394_data *dv = context->priv_data; - - dv->dv_demux = dv_init_demux(context); - if (!dv->dv_demux) - goto failed; - - if (ap->standard && !strcasecmp(ap->standard, "pal")) - dv->format = DV1394_PAL; - else - dv->format = DV1394_NTSC; - - if (ap->channel) - dv->channel = ap->channel; - else - dv->channel = DV1394_DEFAULT_CHANNEL; - - /* Open and initialize DV1394 device */ - dv->fd = open(context->filename, O_RDONLY); - if (dv->fd < 0) { - av_log(context, AV_LOG_ERROR, "Failed to open DV interface: %s\n", strerror(errno)); - goto failed; - } - - if (dv1394_reset(dv) < 0) { - av_log(context, AV_LOG_ERROR, "Failed to initialize DV interface: %s\n", strerror(errno)); - goto failed; - } - - dv->ring = mmap(NULL, DV1394_PAL_FRAME_SIZE * DV1394_RING_FRAMES, - PROT_READ, MAP_PRIVATE, dv->fd, 0); - if (dv->ring == MAP_FAILED) { - av_log(context, AV_LOG_ERROR, "Failed to mmap DV ring buffer: %s\n", strerror(errno)); - goto failed; - } - - if (dv1394_start(dv) < 0) - goto failed; - - return 0; - -failed: - close(dv->fd); - return AVERROR(EIO); -} - -static int dv1394_read_packet(AVFormatContext *context, AVPacket *pkt) -{ - struct dv1394_data *dv = context->priv_data; - int size; - - size = dv_get_packet(dv->dv_demux, pkt); - if (size > 0) - return size; - - if (!dv->avail) { - struct dv1394_status s; - struct pollfd p; - - if (dv->done) { - /* Request more frames */ - if (ioctl(dv->fd, DV1394_RECEIVE_FRAMES, dv->done) < 0) { - /* This usually means that ring buffer overflowed. - * We have to reset :(. - */ - - av_log(context, AV_LOG_ERROR, "DV1394: Ring buffer overflow. Reseting ..\n"); - - dv1394_reset(dv); - dv1394_start(dv); - } - dv->done = 0; - } - - /* Wait until more frames are available */ -restart_poll: - p.fd = dv->fd; - p.events = POLLIN | POLLERR | POLLHUP; - if (poll(&p, 1, -1) < 0) { - if (errno == EAGAIN || errno == EINTR) - goto restart_poll; - av_log(context, AV_LOG_ERROR, "Poll failed: %s\n", strerror(errno)); - return AVERROR(EIO); - } - - if (ioctl(dv->fd, DV1394_GET_STATUS, &s) < 0) { - av_log(context, AV_LOG_ERROR, "Failed to get status: %s\n", strerror(errno)); - return AVERROR(EIO); - } -#ifdef DV1394_DEBUG - av_log(context, AV_LOG_DEBUG, "DV1394: status\n" - "\tactive_frame\t%d\n" - "\tfirst_clear_frame\t%d\n" - "\tn_clear_frames\t%d\n" - "\tdropped_frames\t%d\n", - s.active_frame, s.first_clear_frame, - s.n_clear_frames, s.dropped_frames); -#endif - - dv->avail = s.n_clear_frames; - dv->index = s.first_clear_frame; - dv->done = 0; - - if (s.dropped_frames) { - av_log(context, AV_LOG_ERROR, "DV1394: Frame drop detected (%d). Reseting ..\n", - s.dropped_frames); - - dv1394_reset(dv); - dv1394_start(dv); - } - } - -#ifdef DV1394_DEBUG - av_log(context, AV_LOG_DEBUG, "index %d, avail %d, done %d\n", dv->index, dv->avail, - dv->done); -#endif - - size = dv_produce_packet(dv->dv_demux, pkt, - dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE), - DV1394_PAL_FRAME_SIZE); - dv->index = (dv->index + 1) % DV1394_RING_FRAMES; - dv->done++; dv->avail--; - - return size; -} - -static int dv1394_close(AVFormatContext * context) -{ - struct dv1394_data *dv = context->priv_data; - - /* Shutdown DV1394 receiver */ - if (ioctl(dv->fd, DV1394_SHUTDOWN, 0) < 0) - av_log(context, AV_LOG_ERROR, "Failed to shutdown DV1394: %s\n", strerror(errno)); - - /* Unmap ring buffer */ - if (munmap(dv->ring, DV1394_NTSC_FRAME_SIZE * DV1394_RING_FRAMES) < 0) - av_log(context, AV_LOG_ERROR, "Failed to munmap DV1394 ring buffer: %s\n", strerror(errno)); - - close(dv->fd); - av_free(dv->dv_demux); - - return 0; -} - -AVInputFormat dv1394_demuxer = { - .name = "dv1394", - .long_name = NULL_IF_CONFIG_SMALL("DV1394 A/V grab"), - .priv_data_size = sizeof(struct dv1394_data), - .read_header = dv1394_read_header, - .read_packet = dv1394_read_packet, - .read_close = dv1394_close, - .flags = AVFMT_NOFILE -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/dv1394.h b/tizen/distrib/ffmpeg/libavdevice/dv1394.h deleted file mode 100644 index 00706f7..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/dv1394.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * DV input/output over IEEE 1394 on OHCI chips - * Copyright (C)2001 Daniel Maas - * receive, proc_fs by Dan Dennedy - * - * based on: - * video1394.h - driver for OHCI 1394 boards - * Copyright (C)1999,2000 Sebastien Rougeaux - * Peter Schlaile - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVDEVICE_DV1394_H -#define AVDEVICE_DV1394_H - -#define DV1394_DEFAULT_CHANNEL 63 -#define DV1394_DEFAULT_CARD 0 -#define DV1394_RING_FRAMES 20 - -#define DV1394_WIDTH 720 -#define DV1394_NTSC_HEIGHT 480 -#define DV1394_PAL_HEIGHT 576 - -/* This is the public user-space interface. Try not to break it. */ - -#define DV1394_API_VERSION 0x20011127 - -/* ******************** - ** ** - ** DV1394 API ** - ** ** - ******************** - - There are two methods of operating the DV1394 DV output device. - - 1) - - The simplest is an interface based on write(): simply write - full DV frames of data to the device, and they will be transmitted - as quickly as possible. The FD may be set for non-blocking I/O, - in which case you can use select() or poll() to wait for output - buffer space. - - To set the DV output parameters (e.g. whether you want NTSC or PAL - video), use the DV1394_INIT ioctl, passing in the parameters you - want in a struct dv1394_init. - - Example 1: - To play a raw .DV file: cat foo.DV > /dev/dv1394 - (cat will use write() internally) - - Example 2: - static struct dv1394_init init = { - 0x63, (broadcast channel) - 4, (four-frame ringbuffer) - DV1394_NTSC, (send NTSC video) - 0, 0 (default empty packet rate) - } - - ioctl(fd, DV1394_INIT, &init); - - while(1) { - read(
, buf, DV1394_NTSC_FRAME_SIZE ); - write( , buf, DV1394_NTSC_FRAME_SIZE ); - } - - 2) - - For more control over buffering, and to avoid unnecessary copies - of the DV data, you can use the more sophisticated the mmap() interface. - First, call the DV1394_INIT ioctl to specify your parameters, - including the number of frames in the ringbuffer. Then, calling mmap() - on the dv1394 device will give you direct access to the ringbuffer - from which the DV card reads your frame data. - - The ringbuffer is simply one large, contiguous region of memory - containing two or more frames of packed DV data. Each frame of DV data - is 120000 bytes (NTSC) or 144000 bytes (PAL). - - Fill one or more frames in the ringbuffer, then use the DV1394_SUBMIT_FRAMES - ioctl to begin I/O. You can use either the DV1394_WAIT_FRAMES ioctl - or select()/poll() to wait until the frames are transmitted. Next, you'll - need to call the DV1394_GET_STATUS ioctl to determine which ringbuffer - frames are clear (ready to be filled with new DV data). Finally, use - DV1394_SUBMIT_FRAMES again to send the new data to the DV output. - - - Example: here is what a four-frame ringbuffer might look like - during DV transmission: - - - frame 0 frame 1 frame 2 frame 3 - - *--------------------------------------* - | CLEAR | DV data | DV data | CLEAR | - *--------------------------------------* - - - transmission goes in this direction --->>> - - - The DV hardware is currently transmitting the data in frame 1. - Once frame 1 is finished, it will automatically transmit frame 2. - (if frame 2 finishes before frame 3 is submitted, the device - will continue to transmit frame 2, and will increase the dropped_frames - counter each time it repeats the transmission). - - - If you called DV1394_GET_STATUS at this instant, you would - receive the following values: - - n_frames = 4 - active_frame = 1 - first_clear_frame = 3 - n_clear_frames = 2 - - At this point, you should write new DV data into frame 3 and optionally - frame 0. Then call DV1394_SUBMIT_FRAMES to inform the device that - it may transmit the new frames. - - ERROR HANDLING - - An error (buffer underflow/overflow or a break in the DV stream due - to a 1394 bus reset) can be detected by checking the dropped_frames - field of struct dv1394_status (obtained through the - DV1394_GET_STATUS ioctl). - - The best way to recover from such an error is to re-initialize - dv1394, either by using the DV1394_INIT ioctl call, or closing the - file descriptor and opening it again. (note that you must unmap all - ringbuffer mappings when closing the file descriptor, or else - dv1394 will still be considered 'in use'). - - MAIN LOOP - - For maximum efficiency and robustness against bus errors, you are - advised to model the main loop of your application after the - following pseudo-code example: - - (checks of system call return values omitted for brevity; always - check return values in your code!) - - while( frames left ) { - - struct pollfd *pfd = ...; - - pfd->fd = dv1394_fd; - pfd->revents = 0; - pfd->events = POLLOUT | POLLIN; (OUT for transmit, IN for receive) - - (add other sources of I/O here) - - poll(pfd, 1, -1); (or select(); add a timeout if you want) - - if(pfd->revents) { - struct dv1394_status status; - - ioctl(dv1394_fd, DV1394_GET_STATUS, &status); - - if(status.dropped_frames > 0) { - reset_dv1394(); - } else { - for(int i = 0; i < status.n_clear_frames; i++) { - copy_DV_frame(); - } - } - } - } - - where copy_DV_frame() reads or writes on the dv1394 file descriptor - (read/write mode) or copies data to/from the mmap ringbuffer and - then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new - frames are availble (mmap mode). - - reset_dv1394() is called in the event of a buffer - underflow/overflow or a halt in the DV stream (e.g. due to a 1394 - bus reset). To guarantee recovery from the error, this function - should close the dv1394 file descriptor (and munmap() all - ringbuffer mappings, if you are using them), then re-open the - dv1394 device (and re-map the ringbuffer). - -*/ - - -/* maximum number of frames in the ringbuffer */ -#define DV1394_MAX_FRAMES 32 - -/* number of *full* isochronous packets per DV frame */ -#define DV1394_NTSC_PACKETS_PER_FRAME 250 -#define DV1394_PAL_PACKETS_PER_FRAME 300 - -/* size of one frame's worth of DV data, in bytes */ -#define DV1394_NTSC_FRAME_SIZE (480 * DV1394_NTSC_PACKETS_PER_FRAME) -#define DV1394_PAL_FRAME_SIZE (480 * DV1394_PAL_PACKETS_PER_FRAME) - - -/* ioctl() commands */ - -enum { - /* I don't like using 0 as a valid ioctl() */ - DV1394_INVALID = 0, - - - /* get the driver ready to transmit video. - pass a struct dv1394_init* as the parameter (see below), - or NULL to get default parameters */ - DV1394_INIT, - - - /* stop transmitting video and free the ringbuffer */ - DV1394_SHUTDOWN, - - - /* submit N new frames to be transmitted, where - the index of the first new frame is first_clear_buffer, - and the index of the last new frame is - (first_clear_buffer + N) % n_frames */ - DV1394_SUBMIT_FRAMES, - - - /* block until N buffers are clear (pass N as the parameter) - Because we re-transmit the last frame on underrun, there - will at most be n_frames - 1 clear frames at any time */ - DV1394_WAIT_FRAMES, - - /* capture new frames that have been received, where - the index of the first new frame is first_clear_buffer, - and the index of the last new frame is - (first_clear_buffer + N) % n_frames */ - DV1394_RECEIVE_FRAMES, - - - DV1394_START_RECEIVE, - - - /* pass a struct dv1394_status* as the parameter (see below) */ - DV1394_GET_STATUS, -}; - - - -enum pal_or_ntsc { - DV1394_NTSC = 0, - DV1394_PAL -}; - - - - -/* this is the argument to DV1394_INIT */ -struct dv1394_init { - /* DV1394_API_VERSION */ - unsigned int api_version; - - /* isochronous transmission channel to use */ - unsigned int channel; - - /* number of frames in the ringbuffer. Must be at least 2 - and at most DV1394_MAX_FRAMES. */ - unsigned int n_frames; - - /* send/receive PAL or NTSC video format */ - enum pal_or_ntsc format; - - /* the following are used only for transmission */ - - /* set these to zero unless you want a - non-default empty packet rate (see below) */ - unsigned long cip_n; - unsigned long cip_d; - - /* set this to zero unless you want a - non-default SYT cycle offset (default = 3 cycles) */ - unsigned int syt_offset; -}; - -/* NOTE: you may only allocate the DV frame ringbuffer once each time - you open the dv1394 device. DV1394_INIT will fail if you call it a - second time with different 'n_frames' or 'format' arguments (which - would imply a different size for the ringbuffer). If you need a - different buffer size, simply close and re-open the device, then - initialize it with your new settings. */ - -/* Q: What are cip_n and cip_d? */ - -/* - A: DV video streams do not utilize 100% of the potential bandwidth offered - by IEEE 1394 (FireWire). To achieve the correct rate of data transmission, - DV devices must periodically insert empty packets into the 1394 data stream. - Typically there is one empty packet per 14-16 data-carrying packets. - - Some DV devices will accept a wide range of empty packet rates, while others - require a precise rate. If the dv1394 driver produces empty packets at - a rate that your device does not accept, you may see ugly patterns on the - DV output, or even no output at all. - - The default empty packet insertion rate seems to work for many people; if - your DV output is stable, you can simply ignore this discussion. However, - we have exposed the empty packet rate as a parameter to support devices that - do not work with the default rate. - - The decision to insert an empty packet is made with a numerator/denominator - algorithm. Empty packets are produced at an average rate of CIP_N / CIP_D. - You can alter the empty packet rate by passing non-zero values for cip_n - and cip_d to the INIT ioctl. - - */ - - - -struct dv1394_status { - /* this embedded init struct returns the current dv1394 - parameters in use */ - struct dv1394_init init; - - /* the ringbuffer frame that is currently being - displayed. (-1 if the device is not transmitting anything) */ - int active_frame; - - /* index of the first buffer (ahead of active_frame) that - is ready to be filled with data */ - unsigned int first_clear_frame; - - /* how many buffers, including first_clear_buffer, are - ready to be filled with data */ - unsigned int n_clear_frames; - - /* how many times the DV stream has underflowed, overflowed, - or otherwise encountered an error, since the previous call - to DV1394_GET_STATUS */ - unsigned int dropped_frames; - - /* N.B. The dropped_frames counter is only a lower bound on the actual - number of dropped frames, with the special case that if dropped_frames - is zero, then it is guaranteed that NO frames have been dropped - since the last call to DV1394_GET_STATUS. - */ -}; - - -#endif /* AVDEVICE_DV1394_H */ diff --git a/tizen/distrib/ffmpeg/libavdevice/jack_audio.c b/tizen/distrib/ffmpeg/libavdevice/jack_audio.c deleted file mode 100644 index b41bbdf..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/jack_audio.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * JACK Audio Connection Kit input device - * Copyright (c) 2009 Samalyse - * Author: Olivier Guilyardi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include -#include - -#include "libavutil/log.h" -#include "libavutil/fifo.h" -#include "libavcodec/avcodec.h" -#include "libavformat/avformat.h" -#include "libavformat/timefilter.h" - -/** - * Size of the internal FIFO buffers as a number of audio packets - */ -#define FIFO_PACKETS_NUM 16 - -typedef struct { - jack_client_t * client; - int activated; - sem_t packet_count; - jack_nframes_t sample_rate; - jack_nframes_t buffer_size; - jack_port_t ** ports; - int nports; - TimeFilter * timefilter; - AVFifoBuffer * new_pkts; - AVFifoBuffer * filled_pkts; - int pkt_xrun; - int jack_xrun; -} JackData; - -static int process_callback(jack_nframes_t nframes, void *arg) -{ - /* Warning: this function runs in realtime. One mustn't allocate memory here - * or do any other thing that could block. */ - - int i, j; - JackData *self = arg; - float * buffer; - jack_nframes_t latency, cycle_delay; - AVPacket pkt; - float *pkt_data; - double cycle_time; - - if (!self->client) - return 0; - - /* The approximate delay since the hardware interrupt as a number of frames */ - cycle_delay = jack_frames_since_cycle_start(self->client); - - /* Retrieve filtered cycle time */ - cycle_time = ff_timefilter_update(self->timefilter, - av_gettime() / 1000000.0 - (double) cycle_delay / self->sample_rate, - self->buffer_size); - - /* Check if an empty packet is available, and if there's enough space to send it back once filled */ - if ((av_fifo_size(self->new_pkts) < sizeof(pkt)) || (av_fifo_space(self->filled_pkts) < sizeof(pkt))) { - self->pkt_xrun = 1; - return 0; - } - - /* Retrieve empty (but allocated) packet */ - av_fifo_generic_read(self->new_pkts, &pkt, sizeof(pkt), NULL); - - pkt_data = (float *) pkt.data; - latency = 0; - - /* Copy and interleave audio data from the JACK buffer into the packet */ - for (i = 0; i < self->nports; i++) { - latency += jack_port_get_total_latency(self->client, self->ports[i]); - buffer = jack_port_get_buffer(self->ports[i], self->buffer_size); - for (j = 0; j < self->buffer_size; j++) - pkt_data[j * self->nports + i] = buffer[j]; - } - - /* Timestamp the packet with the cycle start time minus the average latency */ - pkt.pts = (cycle_time - (double) latency / (self->nports * self->sample_rate)) * 1000000.0; - - /* Send the now filled packet back, and increase packet counter */ - av_fifo_generic_write(self->filled_pkts, &pkt, sizeof(pkt), NULL); - sem_post(&self->packet_count); - - return 0; -} - -static void shutdown_callback(void *arg) -{ - JackData *self = arg; - self->client = NULL; -} - -static int xrun_callback(void *arg) -{ - JackData *self = arg; - self->jack_xrun = 1; - ff_timefilter_reset(self->timefilter); - return 0; -} - -static int supply_new_packets(JackData *self, AVFormatContext *context) -{ - AVPacket pkt; - int test, pkt_size = self->buffer_size * self->nports * sizeof(float); - - /* Supply the process callback with new empty packets, by filling the new - * packets FIFO buffer with as many packets as possible. process_callback() - * can't do this by itself, because it can't allocate memory in realtime. */ - while (av_fifo_space(self->new_pkts) >= sizeof(pkt)) { - if ((test = av_new_packet(&pkt, pkt_size)) < 0) { - av_log(context, AV_LOG_ERROR, "Could not create packet of size %d\n", pkt_size); - return test; - } - av_fifo_generic_write(self->new_pkts, &pkt, sizeof(pkt), NULL); - } - return 0; -} - -static int start_jack(AVFormatContext *context, AVFormatParameters *params) -{ - JackData *self = context->priv_data; - jack_status_t status; - int i, test; - double o, period; - - /* Register as a JACK client, using the context filename as client name. */ - self->client = jack_client_open(context->filename, JackNullOption, &status); - if (!self->client) { - av_log(context, AV_LOG_ERROR, "Unable to register as a JACK client\n"); - return AVERROR(EIO); - } - - sem_init(&self->packet_count, 0, 0); - - self->sample_rate = jack_get_sample_rate(self->client); - self->nports = params->channels; - self->ports = av_malloc(self->nports * sizeof(*self->ports)); - self->buffer_size = jack_get_buffer_size(self->client); - - /* Register JACK ports */ - for (i = 0; i < self->nports; i++) { - char str[16]; - snprintf(str, sizeof(str), "input_%d", i + 1); - self->ports[i] = jack_port_register(self->client, str, - JACK_DEFAULT_AUDIO_TYPE, - JackPortIsInput, 0); - if (!self->ports[i]) { - av_log(context, AV_LOG_ERROR, "Unable to register port %s:%s\n", - context->filename, str); - jack_client_close(self->client); - return AVERROR(EIO); - } - } - - /* Register JACK callbacks */ - jack_set_process_callback(self->client, process_callback, self); - jack_on_shutdown(self->client, shutdown_callback, self); - jack_set_xrun_callback(self->client, xrun_callback, self); - - /* Create time filter */ - period = (double) self->buffer_size / self->sample_rate; - o = 2 * M_PI * 1.5 * period; /// bandwidth: 1.5Hz - self->timefilter = ff_timefilter_new (1.0 / self->sample_rate, sqrt(2 * o), o * o); - - /* Create FIFO buffers */ - self->filled_pkts = av_fifo_alloc(FIFO_PACKETS_NUM * sizeof(AVPacket)); - /* New packets FIFO with one extra packet for safety against underruns */ - self->new_pkts = av_fifo_alloc((FIFO_PACKETS_NUM + 1) * sizeof(AVPacket)); - if ((test = supply_new_packets(self, context))) { - jack_client_close(self->client); - return test; - } - - return 0; - -} - -static void free_pkt_fifo(AVFifoBuffer *fifo) -{ - AVPacket pkt; - while (av_fifo_size(fifo)) { - av_fifo_generic_read(fifo, &pkt, sizeof(pkt), NULL); - av_free_packet(&pkt); - } - av_fifo_free(fifo); -} - -static void stop_jack(JackData *self) -{ - if (self->client) { - if (self->activated) - jack_deactivate(self->client); - jack_client_close(self->client); - } - sem_destroy(&self->packet_count); - free_pkt_fifo(self->new_pkts); - free_pkt_fifo(self->filled_pkts); - av_freep(&self->ports); - ff_timefilter_destroy(self->timefilter); -} - -static int audio_read_header(AVFormatContext *context, AVFormatParameters *params) -{ - JackData *self = context->priv_data; - AVStream *stream; - int test; - - if (params->sample_rate <= 0 || params->channels <= 0) - return -1; - - if ((test = start_jack(context, params))) - return test; - - stream = av_new_stream(context, 0); - if (!stream) { - stop_jack(self); - return AVERROR(ENOMEM); - } - - stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; -#if HAVE_BIGENDIAN - stream->codec->codec_id = CODEC_ID_PCM_F32BE; -#else - stream->codec->codec_id = CODEC_ID_PCM_F32LE; -#endif - stream->codec->sample_rate = self->sample_rate; - stream->codec->channels = self->nports; - - av_set_pts_info(stream, 64, 1, 1000000); /* 64 bits pts in us */ - return 0; -} - -static int audio_read_packet(AVFormatContext *context, AVPacket *pkt) -{ - JackData *self = context->priv_data; - struct timespec timeout = {0, 0}; - int test; - - /* Activate the JACK client on first packet read. Activating the JACK client - * means that process_callback() starts to get called at regular interval. - * If we activate it in audio_read_header(), we're actually reading audio data - * from the device before instructed to, and that may result in an overrun. */ - if (!self->activated) { - if (!jack_activate(self->client)) { - self->activated = 1; - av_log(context, AV_LOG_INFO, - "JACK client registered and activated (rate=%dHz, buffer_size=%d frames)\n", - self->sample_rate, self->buffer_size); - } else { - av_log(context, AV_LOG_ERROR, "Unable to activate JACK client\n"); - return AVERROR(EIO); - } - } - - /* Wait for a packet comming back from process_callback(), if one isn't available yet */ - timeout.tv_sec = av_gettime() / 1000000 + 2; - if (sem_timedwait(&self->packet_count, &timeout)) { - if (errno == ETIMEDOUT) { - av_log(context, AV_LOG_ERROR, - "Input error: timed out when waiting for JACK process callback output\n"); - } else { - av_log(context, AV_LOG_ERROR, "Error while waiting for audio packet: %s\n", - strerror(errno)); - } - if (!self->client) - av_log(context, AV_LOG_ERROR, "Input error: JACK server is gone\n"); - - return AVERROR(EIO); - } - - if (self->pkt_xrun) { - av_log(context, AV_LOG_WARNING, "Audio packet xrun\n"); - self->pkt_xrun = 0; - } - - if (self->jack_xrun) { - av_log(context, AV_LOG_WARNING, "JACK xrun\n"); - self->jack_xrun = 0; - } - - /* Retrieve the packet filled with audio data by process_callback() */ - av_fifo_generic_read(self->filled_pkts, pkt, sizeof(*pkt), NULL); - - if ((test = supply_new_packets(self, context))) - return test; - - return 0; -} - -static int audio_read_close(AVFormatContext *context) -{ - JackData *self = context->priv_data; - stop_jack(self); - return 0; -} - -AVInputFormat jack_demuxer = { - "jack", - NULL_IF_CONFIG_SMALL("JACK Audio Connection Kit"), - sizeof(JackData), - NULL, - audio_read_header, - audio_read_packet, - audio_read_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/libavdevice.v b/tizen/distrib/ffmpeg/libavdevice/libavdevice.v deleted file mode 100644 index 663af85..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/libavdevice.v +++ /dev/null @@ -1,4 +0,0 @@ -LIBAVDEVICE_$MAJOR { - global: avdevice_*; - local: *; -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/libdc1394.c b/tizen/distrib/ffmpeg/libavdevice/libdc1394.c deleted file mode 100644 index 1f35135..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/libdc1394.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * IIDC1394 grab interface (uses libdc1394 and libraw1394) - * Copyright (c) 2004 Roman Shaposhnik - * Copyright (c) 2008 Alessandro Sappia - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "libavformat/avformat.h" - -#if HAVE_LIBDC1394_2 -#include -#elif HAVE_LIBDC1394_1 -#include -#include - -#define DC1394_VIDEO_MODE_320x240_YUV422 MODE_320x240_YUV422 -#define DC1394_VIDEO_MODE_640x480_YUV411 MODE_640x480_YUV411 -#define DC1394_VIDEO_MODE_640x480_YUV422 MODE_640x480_YUV422 -#define DC1394_FRAMERATE_1_875 FRAMERATE_1_875 -#define DC1394_FRAMERATE_3_75 FRAMERATE_3_75 -#define DC1394_FRAMERATE_7_5 FRAMERATE_7_5 -#define DC1394_FRAMERATE_15 FRAMERATE_15 -#define DC1394_FRAMERATE_30 FRAMERATE_30 -#define DC1394_FRAMERATE_60 FRAMERATE_60 -#define DC1394_FRAMERATE_120 FRAMERATE_120 -#define DC1394_FRAMERATE_240 FRAMERATE_240 -#endif - -#undef free - -typedef struct dc1394_data { -#if HAVE_LIBDC1394_1 - raw1394handle_t handle; - dc1394_cameracapture camera; -#elif HAVE_LIBDC1394_2 - dc1394_t *d; - dc1394camera_t *camera; - dc1394video_frame_t *frame; -#endif - int current_frame; - int fps; - - AVPacket packet; -} dc1394_data; - -struct dc1394_frame_format { - int width; - int height; - enum PixelFormat pix_fmt; - int frame_size_id; -} dc1394_frame_formats[] = { - { 320, 240, PIX_FMT_UYVY422, DC1394_VIDEO_MODE_320x240_YUV422 }, - { 640, 480, PIX_FMT_UYYVYY411, DC1394_VIDEO_MODE_640x480_YUV411 }, - { 640, 480, PIX_FMT_UYVY422, DC1394_VIDEO_MODE_640x480_YUV422 }, - { 0, 0, 0, 0 } /* gotta be the last one */ -}; - -struct dc1394_frame_rate { - int frame_rate; - int frame_rate_id; -} dc1394_frame_rates[] = { - { 1875, DC1394_FRAMERATE_1_875 }, - { 3750, DC1394_FRAMERATE_3_75 }, - { 7500, DC1394_FRAMERATE_7_5 }, - { 15000, DC1394_FRAMERATE_15 }, - { 30000, DC1394_FRAMERATE_30 }, - { 60000, DC1394_FRAMERATE_60 }, - {120000, DC1394_FRAMERATE_120 }, - {240000, DC1394_FRAMERATE_240 }, - { 0, 0 } /* gotta be the last one */ -}; - -static inline int dc1394_read_common(AVFormatContext *c, AVFormatParameters *ap, - struct dc1394_frame_format **select_fmt, struct dc1394_frame_rate **select_fps) -{ - dc1394_data* dc1394 = c->priv_data; - AVStream* vst; - struct dc1394_frame_format *fmt; - struct dc1394_frame_rate *fps; - enum PixelFormat pix_fmt = ap->pix_fmt == PIX_FMT_NONE ? PIX_FMT_UYVY422 : ap->pix_fmt; /* defaults */ - int width = !ap->width ? 320 : ap->width; - int height = !ap->height ? 240 : ap->height; - int frame_rate = !ap->time_base.num ? 30000 : av_rescale(1000, ap->time_base.den, ap->time_base.num); - - for (fmt = dc1394_frame_formats; fmt->width; fmt++) - if (fmt->pix_fmt == pix_fmt && fmt->width == width && fmt->height == height) - break; - - for (fps = dc1394_frame_rates; fps->frame_rate; fps++) - if (fps->frame_rate == frame_rate) - break; - - if (!fps->frame_rate || !fmt->width) { - av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%d:1000fps\n", avcodec_get_pix_fmt_name(pix_fmt), - width, height, frame_rate); - goto out; - } - - /* create a video stream */ - vst = av_new_stream(c, 0); - if (!vst) - goto out; - av_set_pts_info(vst, 64, 1, 1000); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_RAWVIDEO; - vst->codec->time_base.den = fps->frame_rate; - vst->codec->time_base.num = 1000; - vst->codec->width = fmt->width; - vst->codec->height = fmt->height; - vst->codec->pix_fmt = fmt->pix_fmt; - - /* packet init */ - av_init_packet(&dc1394->packet); - dc1394->packet.size = avpicture_get_size(fmt->pix_fmt, fmt->width, fmt->height); - dc1394->packet.stream_index = vst->index; - dc1394->packet.flags |= AV_PKT_FLAG_KEY; - - dc1394->current_frame = 0; - dc1394->fps = fps->frame_rate; - - vst->codec->bit_rate = av_rescale(dc1394->packet.size * 8, fps->frame_rate, 1000); - *select_fps = fps; - *select_fmt = fmt; - return 0; -out: - return -1; -} - -#if HAVE_LIBDC1394_1 -static int dc1394_v1_read_header(AVFormatContext *c, AVFormatParameters * ap) -{ - dc1394_data* dc1394 = c->priv_data; - AVStream* vst; - nodeid_t* camera_nodes; - int res; - struct dc1394_frame_format *fmt = NULL; - struct dc1394_frame_rate *fps = NULL; - - if (dc1394_read_common(c,ap,&fmt,&fps) != 0) - return -1; - - /* Now let us prep the hardware. */ - dc1394->handle = dc1394_create_handle(0); /* FIXME: gotta have ap->port */ - if (!dc1394->handle) { - av_log(c, AV_LOG_ERROR, "Can't acquire dc1394 handle on port %d\n", 0 /* ap->port */); - goto out; - } - camera_nodes = dc1394_get_camera_nodes(dc1394->handle, &res, 1); - if (!camera_nodes || camera_nodes[ap->channel] == DC1394_NO_CAMERA) { - av_log(c, AV_LOG_ERROR, "There's no IIDC camera on the channel %d\n", ap->channel); - goto out_handle; - } - res = dc1394_dma_setup_capture(dc1394->handle, camera_nodes[ap->channel], - 0, - FORMAT_VGA_NONCOMPRESSED, - fmt->frame_size_id, - SPEED_400, - fps->frame_rate_id, 8, 1, - c->filename, - &dc1394->camera); - dc1394_free_camera_nodes(camera_nodes); - if (res != DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Can't prepare camera for the DMA capture\n"); - goto out_handle; - } - - res = dc1394_start_iso_transmission(dc1394->handle, dc1394->camera.node); - if (res != DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Can't start isochronous transmission\n"); - goto out_handle_dma; - } - - return 0; - -out_handle_dma: - dc1394_dma_unlisten(dc1394->handle, &dc1394->camera); - dc1394_dma_release_camera(dc1394->handle, &dc1394->camera); -out_handle: - dc1394_destroy_handle(dc1394->handle); -out: - return -1; -} - -static int dc1394_v1_read_packet(AVFormatContext *c, AVPacket *pkt) -{ - struct dc1394_data *dc1394 = c->priv_data; - int res; - - /* discard stale frame */ - if (dc1394->current_frame++) { - if (dc1394_dma_done_with_buffer(&dc1394->camera) != DC1394_SUCCESS) - av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame); - } - - res = dc1394_dma_single_capture(&dc1394->camera); - - if (res == DC1394_SUCCESS) { - dc1394->packet.data = (uint8_t *)(dc1394->camera.capture_buffer); - dc1394->packet.pts = (dc1394->current_frame * 1000000) / dc1394->fps; - res = dc1394->packet.size; - } else { - av_log(c, AV_LOG_ERROR, "DMA capture failed\n"); - dc1394->packet.data = NULL; - res = -1; - } - - *pkt = dc1394->packet; - return res; -} - -static int dc1394_v1_close(AVFormatContext * context) -{ - struct dc1394_data *dc1394 = context->priv_data; - - dc1394_stop_iso_transmission(dc1394->handle, dc1394->camera.node); - dc1394_dma_unlisten(dc1394->handle, &dc1394->camera); - dc1394_dma_release_camera(dc1394->handle, &dc1394->camera); - dc1394_destroy_handle(dc1394->handle); - - return 0; -} - -#elif HAVE_LIBDC1394_2 -static int dc1394_v2_read_header(AVFormatContext *c, AVFormatParameters * ap) -{ - dc1394_data* dc1394 = c->priv_data; - dc1394camera_list_t *list; - int res, i; - struct dc1394_frame_format *fmt = NULL; - struct dc1394_frame_rate *fps = NULL; - - if (dc1394_read_common(c,ap,&fmt,&fps) != 0) - return -1; - - /* Now let us prep the hardware. */ - dc1394->d = dc1394_new(); - dc1394_camera_enumerate (dc1394->d, &list); - if ( !list || list->num == 0) { - av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera\n\n"); - goto out; - } - - /* FIXME: To select a specific camera I need to search in list its guid */ - dc1394->camera = dc1394_camera_new (dc1394->d, list->ids[0].guid); - if (list->num > 1) { - av_log(c, AV_LOG_INFO, "Working with the first camera found\n"); - } - - /* Freeing list of cameras */ - dc1394_camera_free_list (list); - - /* Select MAX Speed possible from the cam */ - if (dc1394->camera->bmode_capable>0) { - dc1394_video_set_operation_mode(dc1394->camera, DC1394_OPERATION_MODE_1394B); - i = DC1394_ISO_SPEED_800; - } else { - i = DC1394_ISO_SPEED_400; - } - - for (res = DC1394_FAILURE; i >= DC1394_ISO_SPEED_MIN && res != DC1394_SUCCESS; i--) { - res=dc1394_video_set_iso_speed(dc1394->camera, i); - } - if (res != DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Couldn't set ISO Speed\n"); - goto out_camera; - } - - if (dc1394_video_set_mode(dc1394->camera, fmt->frame_size_id) != DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Couldn't set video format\n"); - goto out_camera; - } - - if (dc1394_video_set_framerate(dc1394->camera,fps->frame_rate_id) != DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Couldn't set framerate %d \n",fps->frame_rate); - goto out_camera; - } - if (dc1394_capture_setup(dc1394->camera, 10, DC1394_CAPTURE_FLAGS_DEFAULT)!=DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Cannot setup camera \n"); - goto out_camera; - } - - if (dc1394_video_set_transmission(dc1394->camera, DC1394_ON) !=DC1394_SUCCESS) { - av_log(c, AV_LOG_ERROR, "Cannot start capture\n"); - goto out_camera; - } - return 0; - -out_camera: - dc1394_capture_stop(dc1394->camera); - dc1394_video_set_transmission(dc1394->camera, DC1394_OFF); - dc1394_camera_free (dc1394->camera); -out: - dc1394_free(dc1394->d); - return -1; -} - -static int dc1394_v2_read_packet(AVFormatContext *c, AVPacket *pkt) -{ - struct dc1394_data *dc1394 = c->priv_data; - int res; - - /* discard stale frame */ - if (dc1394->current_frame++) { - if (dc1394_capture_enqueue(dc1394->camera, dc1394->frame) != DC1394_SUCCESS) - av_log(c, AV_LOG_ERROR, "failed to release %d frame\n", dc1394->current_frame); - } - - res = dc1394_capture_dequeue(dc1394->camera, DC1394_CAPTURE_POLICY_WAIT, &dc1394->frame); - if (res == DC1394_SUCCESS) { - dc1394->packet.data = (uint8_t *)(dc1394->frame->image); - dc1394->packet.pts = (dc1394->current_frame * 1000000) / (dc1394->fps); - res = dc1394->frame->image_bytes; - } else { - av_log(c, AV_LOG_ERROR, "DMA capture failed\n"); - dc1394->packet.data = NULL; - res = -1; - } - - *pkt = dc1394->packet; - return res; -} - -static int dc1394_v2_close(AVFormatContext * context) -{ - struct dc1394_data *dc1394 = context->priv_data; - - dc1394_video_set_transmission(dc1394->camera, DC1394_OFF); - dc1394_capture_stop(dc1394->camera); - dc1394_camera_free(dc1394->camera); - dc1394_free(dc1394->d); - - return 0; -} - -AVInputFormat libdc1394_demuxer = { - .name = "libdc1394", - .long_name = NULL_IF_CONFIG_SMALL("dc1394 v.2 A/V grab"), - .priv_data_size = sizeof(struct dc1394_data), - .read_header = dc1394_v2_read_header, - .read_packet = dc1394_v2_read_packet, - .read_close = dc1394_v2_close, - .flags = AVFMT_NOFILE -}; - -#endif -#if HAVE_LIBDC1394_1 -AVInputFormat libdc1394_demuxer = { - .name = "libdc1394", - .long_name = NULL_IF_CONFIG_SMALL("dc1394 v.1 A/V grab"), - .priv_data_size = sizeof(struct dc1394_data), - .read_header = dc1394_v1_read_header, - .read_packet = dc1394_v1_read_packet, - .read_close = dc1394_v1_close, - .flags = AVFMT_NOFILE -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavdevice/oss_audio.c b/tizen/distrib/ffmpeg/libavdevice/oss_audio.c deleted file mode 100644 index d382c03..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/oss_audio.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Linux audio play and grab interface - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include -#include -#include -#include -#include -#if HAVE_SOUNDCARD_H -#include -#else -#include -#endif -#include -#include -#include -#include -#include - -#include "libavutil/log.h" -#include "libavcodec/avcodec.h" -#include "libavformat/avformat.h" - -#define AUDIO_BLOCK_SIZE 4096 - -typedef struct { - int fd; - int sample_rate; - int channels; - int frame_size; /* in bytes ! */ - enum CodecID codec_id; - unsigned int flip_left : 1; - uint8_t buffer[AUDIO_BLOCK_SIZE]; - int buffer_ptr; -} AudioData; - -static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device) -{ - AudioData *s = s1->priv_data; - int audio_fd; - int tmp, err; - char *flip = getenv("AUDIO_FLIP_LEFT"); - - if (is_output) - audio_fd = open(audio_device, O_WRONLY); - else - audio_fd = open(audio_device, O_RDONLY); - if (audio_fd < 0) { - av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno)); - return AVERROR(EIO); - } - - if (flip && *flip == '1') { - s->flip_left = 1; - } - - /* non blocking mode */ - if (!is_output) - fcntl(audio_fd, F_SETFL, O_NONBLOCK); - - s->frame_size = AUDIO_BLOCK_SIZE; -#if 0 - tmp = (NB_FRAGMENTS << 16) | FRAGMENT_BITS; - err = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp); - if (err < 0) { - perror("SNDCTL_DSP_SETFRAGMENT"); - } -#endif - - /* select format : favour native format */ - err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp); - -#if HAVE_BIGENDIAN - if (tmp & AFMT_S16_BE) { - tmp = AFMT_S16_BE; - } else if (tmp & AFMT_S16_LE) { - tmp = AFMT_S16_LE; - } else { - tmp = 0; - } -#else - if (tmp & AFMT_S16_LE) { - tmp = AFMT_S16_LE; - } else if (tmp & AFMT_S16_BE) { - tmp = AFMT_S16_BE; - } else { - tmp = 0; - } -#endif - - switch(tmp) { - case AFMT_S16_LE: - s->codec_id = CODEC_ID_PCM_S16LE; - break; - case AFMT_S16_BE: - s->codec_id = CODEC_ID_PCM_S16BE; - break; - default: - av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n"); - close(audio_fd); - return AVERROR(EIO); - } - err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp); - if (err < 0) { - av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno)); - goto fail; - } - - tmp = (s->channels == 2); - err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); - if (err < 0) { - av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno)); - goto fail; - } - - tmp = s->sample_rate; - err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp); - if (err < 0) { - av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno)); - goto fail; - } - s->sample_rate = tmp; /* store real sample rate */ - s->fd = audio_fd; - - return 0; - fail: - close(audio_fd); - return AVERROR(EIO); -} - -static int audio_close(AudioData *s) -{ - close(s->fd); - return 0; -} - -/* sound output support */ -static int audio_write_header(AVFormatContext *s1) -{ - AudioData *s = s1->priv_data; - AVStream *st; - int ret; - - st = s1->streams[0]; - s->sample_rate = st->codec->sample_rate; - s->channels = st->codec->channels; - ret = audio_open(s1, 1, s1->filename); - if (ret < 0) { - return AVERROR(EIO); - } else { - return 0; - } -} - -static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AudioData *s = s1->priv_data; - int len, ret; - int size= pkt->size; - uint8_t *buf= pkt->data; - - while (size > 0) { - len = AUDIO_BLOCK_SIZE - s->buffer_ptr; - if (len > size) - len = size; - memcpy(s->buffer + s->buffer_ptr, buf, len); - s->buffer_ptr += len; - if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) { - for(;;) { - ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE); - if (ret > 0) - break; - if (ret < 0 && (errno != EAGAIN && errno != EINTR)) - return AVERROR(EIO); - } - s->buffer_ptr = 0; - } - buf += len; - size -= len; - } - return 0; -} - -static int audio_write_trailer(AVFormatContext *s1) -{ - AudioData *s = s1->priv_data; - - audio_close(s); - return 0; -} - -/* grab support */ - -static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - AudioData *s = s1->priv_data; - AVStream *st; - int ret; - - if (ap->sample_rate <= 0 || ap->channels <= 0) - return -1; - - st = av_new_stream(s1, 0); - if (!st) { - return AVERROR(ENOMEM); - } - s->sample_rate = ap->sample_rate; - s->channels = ap->channels; - - ret = audio_open(s1, 0, s1->filename); - if (ret < 0) { - return AVERROR(EIO); - } - - /* take real parameters */ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->codec_id; - st->codec->sample_rate = s->sample_rate; - st->codec->channels = s->channels; - - av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - return 0; -} - -static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AudioData *s = s1->priv_data; - int ret, bdelay; - int64_t cur_time; - struct audio_buf_info abufi; - - if ((ret=av_new_packet(pkt, s->frame_size)) < 0) - return ret; - - ret = read(s->fd, pkt->data, pkt->size); - if (ret <= 0){ - av_free_packet(pkt); - pkt->size = 0; - if (ret<0) return AVERROR(errno); - else return AVERROR_EOF; - } - pkt->size = ret; - - /* compute pts of the start of the packet */ - cur_time = av_gettime(); - bdelay = ret; - if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) { - bdelay += abufi.bytes; - } - /* subtract time represented by the number of bytes in the audio fifo */ - cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels); - - /* convert to wanted units */ - pkt->pts = cur_time; - - if (s->flip_left && s->channels == 2) { - int i; - short *p = (short *) pkt->data; - - for (i = 0; i < ret; i += 4) { - *p = ~*p; - p += 2; - } - } - return 0; -} - -static int audio_read_close(AVFormatContext *s1) -{ - AudioData *s = s1->priv_data; - - audio_close(s); - return 0; -} - -#if CONFIG_OSS_INDEV -AVInputFormat oss_demuxer = { - "oss", - NULL_IF_CONFIG_SMALL("Open Sound System capture"), - sizeof(AudioData), - NULL, - audio_read_header, - audio_read_packet, - audio_read_close, - .flags = AVFMT_NOFILE, -}; -#endif - -#if CONFIG_OSS_OUTDEV -AVOutputFormat oss_muxer = { - "oss", - NULL_IF_CONFIG_SMALL("Open Sound System playback"), - "", - "", - sizeof(AudioData), - /* XXX: we make the assumption that the soundcard accepts this format */ - /* XXX: find better solution with "preinit" method, needed also in - other formats */ -#if HAVE_BIGENDIAN - CODEC_ID_PCM_S16BE, -#else - CODEC_ID_PCM_S16LE, -#endif - CODEC_ID_NONE, - audio_write_header, - audio_write_packet, - audio_write_trailer, - .flags = AVFMT_NOFILE, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavdevice/v4l.c b/tizen/distrib/ffmpeg/libavdevice/v4l.c deleted file mode 100644 index d0ef7d5..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/v4l.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Linux video grab interface - * Copyright (c) 2000,2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#undef __STRICT_ANSI__ //workaround due to broken kernel headers -#include "config.h" -#include "libavutil/rational.h" -#include "libavformat/avformat.h" -#include "libavcodec/dsputil.h" -#include -#include -#include -#include -#include -#define _LINUX_TIME_H 1 -#include -#include -#include - -typedef struct { - int fd; - int frame_format; /* see VIDEO_PALETTE_xxx */ - int use_mmap; - AVRational time_base; - int64_t time_frame; - int frame_size; - struct video_capability video_cap; - struct video_audio audio_saved; - struct video_window video_win; - uint8_t *video_buf; - struct video_mbuf gb_buffers; - struct video_mmap gb_buf; - int gb_frame; -} VideoData; - -static const struct { - int palette; - int depth; - enum PixelFormat pix_fmt; -} video_formats [] = { - {.palette = VIDEO_PALETTE_YUV420P, .depth = 12, .pix_fmt = PIX_FMT_YUV420P }, - {.palette = VIDEO_PALETTE_YUV422, .depth = 16, .pix_fmt = PIX_FMT_YUYV422 }, - {.palette = VIDEO_PALETTE_UYVY, .depth = 16, .pix_fmt = PIX_FMT_UYVY422 }, - {.palette = VIDEO_PALETTE_YUYV, .depth = 16, .pix_fmt = PIX_FMT_YUYV422 }, - /* NOTE: v4l uses BGR24, not RGB24 */ - {.palette = VIDEO_PALETTE_RGB24, .depth = 24, .pix_fmt = PIX_FMT_BGR24 }, - {.palette = VIDEO_PALETTE_RGB565, .depth = 16, .pix_fmt = PIX_FMT_BGR565 }, - {.palette = VIDEO_PALETTE_GREY, .depth = 8, .pix_fmt = PIX_FMT_GRAY8 }, -}; - - -static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - VideoData *s = s1->priv_data; - AVStream *st; - int video_fd; - int desired_palette, desired_depth; - struct video_tuner tuner; - struct video_audio audio; - struct video_picture pict; - int j; - int vformat_num = FF_ARRAY_ELEMS(video_formats); - - if (ap->time_base.den <= 0) { - av_log(s1, AV_LOG_ERROR, "Wrong time base (%d)\n", ap->time_base.den); - return -1; - } - s->time_base = ap->time_base; - - s->video_win.width = ap->width; - s->video_win.height = ap->height; - - st = av_new_stream(s1, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - - video_fd = open(s1->filename, O_RDWR); - if (video_fd < 0) { - av_log(s1, AV_LOG_ERROR, "%s: %s\n", s1->filename, strerror(errno)); - goto fail; - } - - if (ioctl(video_fd, VIDIOCGCAP, &s->video_cap) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCGCAP: %s\n", strerror(errno)); - goto fail; - } - - if (!(s->video_cap.type & VID_TYPE_CAPTURE)) { - av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not handle capture\n"); - goto fail; - } - - /* no values set, autodetect them */ - if (s->video_win.width <= 0 || s->video_win.height <= 0) { - if (ioctl(video_fd, VIDIOCGWIN, &s->video_win, sizeof(s->video_win)) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCGWIN: %s\n", strerror(errno)); - goto fail; - } - } - - if(avcodec_check_dimensions(s1, s->video_win.width, s->video_win.height) < 0) - return -1; - - desired_palette = -1; - desired_depth = -1; - for (j = 0; j < vformat_num; j++) { - if (ap->pix_fmt == video_formats[j].pix_fmt) { - desired_palette = video_formats[j].palette; - desired_depth = video_formats[j].depth; - break; - } - } - - /* set tv standard */ - if (ap->standard && !ioctl(video_fd, VIDIOCGTUNER, &tuner)) { - if (!strcasecmp(ap->standard, "pal")) - tuner.mode = VIDEO_MODE_PAL; - else if (!strcasecmp(ap->standard, "secam")) - tuner.mode = VIDEO_MODE_SECAM; - else - tuner.mode = VIDEO_MODE_NTSC; - ioctl(video_fd, VIDIOCSTUNER, &tuner); - } - - /* unmute audio */ - audio.audio = 0; - ioctl(video_fd, VIDIOCGAUDIO, &audio); - memcpy(&s->audio_saved, &audio, sizeof(audio)); - audio.flags &= ~VIDEO_AUDIO_MUTE; - ioctl(video_fd, VIDIOCSAUDIO, &audio); - - ioctl(video_fd, VIDIOCGPICT, &pict); -#if 0 - printf("v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n", - pict.colour, - pict.hue, - pict.brightness, - pict.contrast, - pict.whiteness); -#endif - /* try to choose a suitable video format */ - pict.palette = desired_palette; - pict.depth= desired_depth; - if (desired_palette == -1 || ioctl(video_fd, VIDIOCSPICT, &pict) < 0) { - for (j = 0; j < vformat_num; j++) { - pict.palette = video_formats[j].palette; - pict.depth = video_formats[j].depth; - if (-1 != ioctl(video_fd, VIDIOCSPICT, &pict)) - break; - } - if (j >= vformat_num) - goto fail1; - } - - if (ioctl(video_fd, VIDIOCGMBUF, &s->gb_buffers) < 0) { - /* try to use read based access */ - int val; - - s->video_win.x = 0; - s->video_win.y = 0; - s->video_win.chromakey = -1; - s->video_win.flags = 0; - - if (ioctl(video_fd, VIDIOCSWIN, s->video_win) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCSWIN: %s\n", strerror(errno)); - goto fail; - } - - s->frame_format = pict.palette; - - val = 1; - if (ioctl(video_fd, VIDIOCCAPTURE, &val) < 0) { - av_log(s1, AV_LOG_ERROR, "VIDIOCCAPTURE: %s\n", strerror(errno)); - goto fail; - } - - s->time_frame = av_gettime() * s->time_base.den / s->time_base.num; - s->use_mmap = 0; - } else { - s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_SHARED, video_fd, 0); - if ((unsigned char*)-1 == s->video_buf) { - s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_PRIVATE, video_fd, 0); - if ((unsigned char*)-1 == s->video_buf) { - av_log(s1, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); - goto fail; - } - } - s->gb_frame = 0; - s->time_frame = av_gettime() * s->time_base.den / s->time_base.num; - - /* start to grab the first frame */ - s->gb_buf.frame = s->gb_frame % s->gb_buffers.frames; - s->gb_buf.height = s->video_win.height; - s->gb_buf.width = s->video_win.width; - s->gb_buf.format = pict.palette; - - if (ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) { - if (errno != EAGAIN) { - fail1: - av_log(s1, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno)); - } else { - av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not receive any video signal\n"); - } - goto fail; - } - for (j = 1; j < s->gb_buffers.frames; j++) { - s->gb_buf.frame = j; - ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf); - } - s->frame_format = s->gb_buf.format; - s->use_mmap = 1; - } - - for (j = 0; j < vformat_num; j++) { - if (s->frame_format == video_formats[j].palette) { - s->frame_size = s->video_win.width * s->video_win.height * video_formats[j].depth / 8; - st->codec->pix_fmt = video_formats[j].pix_fmt; - break; - } - } - - if (j >= vformat_num) - goto fail; - - s->fd = video_fd; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->width = s->video_win.width; - st->codec->height = s->video_win.height; - st->codec->time_base = s->time_base; - st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; - - return 0; - fail: - if (video_fd >= 0) - close(video_fd); - return AVERROR(EIO); -} - -static int v4l_mm_read_picture(VideoData *s, uint8_t *buf) -{ - uint8_t *ptr; - - while (ioctl(s->fd, VIDIOCSYNC, &s->gb_frame) < 0 && - (errno == EAGAIN || errno == EINTR)); - - ptr = s->video_buf + s->gb_buffers.offsets[s->gb_frame]; - memcpy(buf, ptr, s->frame_size); - - /* Setup to capture the next frame */ - s->gb_buf.frame = s->gb_frame; - if (ioctl(s->fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) { - if (errno == EAGAIN) - av_log(NULL, AV_LOG_ERROR, "Cannot Sync\n"); - else - av_log(NULL, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno)); - return AVERROR(EIO); - } - - /* This is now the grabbing frame */ - s->gb_frame = (s->gb_frame + 1) % s->gb_buffers.frames; - - return s->frame_size; -} - -static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - VideoData *s = s1->priv_data; - int64_t curtime, delay; - struct timespec ts; - - /* Calculate the time of the next frame */ - s->time_frame += INT64_C(1000000); - - /* wait based on the frame rate */ - for(;;) { - curtime = av_gettime(); - delay = s->time_frame * s->time_base.num / s->time_base.den - curtime; - if (delay <= 0) { - if (delay < INT64_C(-1000000) * s->time_base.num / s->time_base.den) { - /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */ - s->time_frame += INT64_C(1000000); - } - break; - } - ts.tv_sec = delay / 1000000; - ts.tv_nsec = (delay % 1000000) * 1000; - nanosleep(&ts, NULL); - } - - if (av_new_packet(pkt, s->frame_size) < 0) - return AVERROR(EIO); - - pkt->pts = curtime; - - /* read one frame */ - if (s->use_mmap) { - return v4l_mm_read_picture(s, pkt->data); - } else { - if (read(s->fd, pkt->data, pkt->size) != pkt->size) - return AVERROR(EIO); - return s->frame_size; - } -} - -static int grab_read_close(AVFormatContext *s1) -{ - VideoData *s = s1->priv_data; - - if (s->use_mmap) - munmap(s->video_buf, s->gb_buffers.size); - - /* mute audio. we must force it because the BTTV driver does not - return its state correctly */ - s->audio_saved.flags |= VIDEO_AUDIO_MUTE; - ioctl(s->fd, VIDIOCSAUDIO, &s->audio_saved); - - close(s->fd); - return 0; -} - -AVInputFormat v4l_demuxer = { - "video4linux", - NULL_IF_CONFIG_SMALL("Video4Linux device grab"), - sizeof(VideoData), - NULL, - grab_read_header, - grab_read_packet, - grab_read_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/v4l2.c b/tizen/distrib/ffmpeg/libavdevice/v4l2.c deleted file mode 100644 index ce88903..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/v4l2.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Video4Linux2 grab interface - * Copyright (c) 2000,2001 Fabrice Bellard - * Copyright (c) 2006 Luca Abeni - * - * Part of this file is based on the V4L2 video capture example - * (http://v4l2spec.bytesex.org/v4l2spec/capture.c) - * - * Thanks to Michael Niedermayer for providing the mapping between - * V4L2_PIX_FMT_* and PIX_FMT_* - * - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#undef __STRICT_ANSI__ //workaround due to broken kernel headers -#include "config.h" -#include "libavformat/avformat.h" -#include -#include -#include -#include -#include -#if HAVE_SYS_VIDEOIO_H -#include -#else -#include -#include -#endif -#include -#include - -static const int desired_video_buffers = 256; - -enum io_method { - io_read, - io_mmap, - io_userptr -}; - -struct video_data { - int fd; - int frame_format; /* V4L2_PIX_FMT_* */ - enum io_method io_method; - int width, height; - int frame_size; - int top_field_first; - - int buffers; - void **buf_start; - unsigned int *buf_len; -}; - -struct buff_data { - int index; - int fd; -}; - -struct fmt_map { - enum PixelFormat ff_fmt; - enum CodecID codec_id; - uint32_t v4l2_fmt; -}; - -static struct fmt_map fmt_conversion_table[] = { - { - .ff_fmt = PIX_FMT_YUV420P, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_YUV420, - }, - { - .ff_fmt = PIX_FMT_YUV422P, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_YUV422P, - }, - { - .ff_fmt = PIX_FMT_YUYV422, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_YUYV, - }, - { - .ff_fmt = PIX_FMT_UYVY422, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_UYVY, - }, - { - .ff_fmt = PIX_FMT_YUV411P, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_YUV411P, - }, - { - .ff_fmt = PIX_FMT_YUV410P, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_YUV410, - }, - { - .ff_fmt = PIX_FMT_RGB555, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_RGB555, - }, - { - .ff_fmt = PIX_FMT_RGB565, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_RGB565, - }, - { - .ff_fmt = PIX_FMT_BGR24, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_BGR24, - }, - { - .ff_fmt = PIX_FMT_RGB24, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_RGB24, - }, - { - .ff_fmt = PIX_FMT_BGRA, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_BGR32, - }, - { - .ff_fmt = PIX_FMT_GRAY8, - .codec_id = CODEC_ID_RAWVIDEO, - .v4l2_fmt = V4L2_PIX_FMT_GREY, - }, - { - .ff_fmt = PIX_FMT_NONE, - .codec_id = CODEC_ID_MJPEG, - .v4l2_fmt = V4L2_PIX_FMT_MJPEG, - }, - { - .ff_fmt = PIX_FMT_NONE, - .codec_id = CODEC_ID_MJPEG, - .v4l2_fmt = V4L2_PIX_FMT_JPEG, - }, -}; - -static int device_open(AVFormatContext *ctx, uint32_t *capabilities) -{ - struct v4l2_capability cap; - int fd; - int res, err; - int flags = O_RDWR; - - if (ctx->flags & AVFMT_FLAG_NONBLOCK) { - flags |= O_NONBLOCK; - } - fd = open(ctx->filename, flags, 0); - if (fd < 0) { - av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n", - ctx->filename, strerror(errno)); - - return AVERROR(errno); - } - - res = ioctl(fd, VIDIOC_QUERYCAP, &cap); - // ENOIOCTLCMD definition only availble on __KERNEL__ - if (res < 0 && ((err = errno) == 515)) { - av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n"); - close(fd); - - return AVERROR(515); - } - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", - strerror(errno)); - close(fd); - - return AVERROR(err); - } - if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { - av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n"); - close(fd); - - return AVERROR(ENODEV); - } - *capabilities = cap.capabilities; - - return fd; -} - -static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pix_fmt) -{ - struct video_data *s = ctx->priv_data; - int fd = s->fd; - struct v4l2_format fmt; - int res; - - memset(&fmt, 0, sizeof(struct v4l2_format)); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = *width; - fmt.fmt.pix.height = *height; - fmt.fmt.pix.pixelformat = pix_fmt; - fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; - res = ioctl(fd, VIDIOC_S_FMT, &fmt); - if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) { - av_log(ctx, AV_LOG_INFO, "The V4L2 driver changed the video from %dx%d to %dx%d\n", *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height); - *width = fmt.fmt.pix.width; - *height = fmt.fmt.pix.height; - } - - if (pix_fmt != fmt.fmt.pix.pixelformat) { - av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver changed the pixel format from 0x%08X to 0x%08X\n", pix_fmt, fmt.fmt.pix.pixelformat); - res = -1; - } - - return res; -} - -static int first_field(int fd) -{ - int res; - v4l2_std_id std; - - res = ioctl(fd, VIDIOC_G_STD, &std); - if (res < 0) { - return 0; - } - if (std & V4L2_STD_NTSC) { - return 0; - } - - return 1; -} - -static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt, enum CodecID codec_id) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { - if ((codec_id == CODEC_ID_NONE || - fmt_conversion_table[i].codec_id == codec_id) && - (pix_fmt == PIX_FMT_NONE || - fmt_conversion_table[i].ff_fmt == pix_fmt)) { - return fmt_conversion_table[i].v4l2_fmt; - } - } - - return 0; -} - -static enum PixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum CodecID codec_id) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { - if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt && - fmt_conversion_table[i].codec_id == codec_id) { - return fmt_conversion_table[i].ff_fmt; - } - } - - return PIX_FMT_NONE; -} - -static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { - if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) { - return fmt_conversion_table[i].codec_id; - } - } - - return CODEC_ID_NONE; -} - -static int mmap_init(AVFormatContext *ctx) -{ - struct video_data *s = ctx->priv_data; - struct v4l2_requestbuffers req; - int i, res; - - memset(&req, 0, sizeof(struct v4l2_requestbuffers)); - req.count = desired_video_buffers; - req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - req.memory = V4L2_MEMORY_MMAP; - res = ioctl (s->fd, VIDIOC_REQBUFS, &req); - if (res < 0) { - if (errno == EINVAL) { - av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n"); - } else { - av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n"); - } - - return AVERROR(errno); - } - - if (req.count < 2) { - av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n"); - - return AVERROR(ENOMEM); - } - s->buffers = req.count; - s->buf_start = av_malloc(sizeof(void *) * s->buffers); - if (s->buf_start == NULL) { - av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n"); - - return AVERROR(ENOMEM); - } - s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers); - if (s->buf_len == NULL) { - av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n"); - av_free(s->buf_start); - - return AVERROR(ENOMEM); - } - - for (i = 0; i < req.count; i++) { - struct v4l2_buffer buf; - - memset(&buf, 0, sizeof(struct v4l2_buffer)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; - res = ioctl (s->fd, VIDIOC_QUERYBUF, &buf); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n"); - - return AVERROR(errno); - } - - s->buf_len[i] = buf.length; - if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) { - av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size); - - return -1; - } - s->buf_start[i] = mmap (NULL, buf.length, - PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset); - if (s->buf_start[i] == MAP_FAILED) { - av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); - - return AVERROR(errno); - } - } - - return 0; -} - -static int read_init(AVFormatContext *ctx) -{ - return -1; -} - -static void mmap_release_buffer(AVPacket *pkt) -{ - struct v4l2_buffer buf; - int res, fd; - struct buff_data *buf_descriptor = pkt->priv; - - if (pkt->data == NULL) { - return; - } - - memset(&buf, 0, sizeof(struct v4l2_buffer)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = buf_descriptor->index; - fd = buf_descriptor->fd; - av_free(buf_descriptor); - - res = ioctl (fd, VIDIOC_QBUF, &buf); - if (res < 0) { - av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); - } - pkt->data = NULL; - pkt->size = 0; -} - -static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) -{ - struct video_data *s = ctx->priv_data; - struct v4l2_buffer buf; - struct buff_data *buf_descriptor; - int res; - - memset(&buf, 0, sizeof(struct v4l2_buffer)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - - /* FIXME: Some special treatment might be needed in case of loss of signal... */ - while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR)); - if (res < 0) { - if (errno == EAGAIN) { - pkt->size = 0; - - return AVERROR(EAGAIN); - } - av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno)); - - return AVERROR(errno); - } - assert (buf.index < s->buffers); - if (s->frame_size > 0 && buf.bytesused != s->frame_size) { - av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size); - - return AVERROR_INVALIDDATA; - } - - /* Image is at s->buff_start[buf.index] */ - pkt->data= s->buf_start[buf.index]; - pkt->size = buf.bytesused; - pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec; - pkt->destruct = mmap_release_buffer; - buf_descriptor = av_malloc(sizeof(struct buff_data)); - if (buf_descriptor == NULL) { - /* Something went wrong... Since av_malloc() failed, we cannot even - * allocate a buffer for memcopying into it - */ - av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n"); - res = ioctl (s->fd, VIDIOC_QBUF, &buf); - - return AVERROR(ENOMEM); - } - buf_descriptor->fd = s->fd; - buf_descriptor->index = buf.index; - pkt->priv = buf_descriptor; - - return s->buf_len[buf.index]; -} - -static int read_frame(AVFormatContext *ctx, AVPacket *pkt) -{ - return -1; -} - -static int mmap_start(AVFormatContext *ctx) -{ - struct video_data *s = ctx->priv_data; - enum v4l2_buf_type type; - int i, res; - - for (i = 0; i < s->buffers; i++) { - struct v4l2_buffer buf; - - memset(&buf, 0, sizeof(struct v4l2_buffer)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; - - res = ioctl (s->fd, VIDIOC_QBUF, &buf); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno)); - - return AVERROR(errno); - } - } - - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - res = ioctl (s->fd, VIDIOC_STREAMON, &type); - if (res < 0) { - av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno)); - - return AVERROR(errno); - } - - return 0; -} - -static void mmap_close(struct video_data *s) -{ - enum v4l2_buf_type type; - int i; - - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - /* We do not check for the result, because we could - * not do anything about it anyway... - */ - ioctl(s->fd, VIDIOC_STREAMOFF, &type); - for (i = 0; i < s->buffers; i++) { - munmap(s->buf_start[i], s->buf_len[i]); - } - av_free(s->buf_start); - av_free(s->buf_len); -} - -static int v4l2_set_parameters( AVFormatContext *s1, AVFormatParameters *ap ) -{ - struct video_data *s = s1->priv_data; - struct v4l2_input input; - struct v4l2_standard standard; - int i; - - if(ap->channel>=0) { - /* set tv video input */ - memset (&input, 0, sizeof (input)); - input.index = ap->channel; - if(ioctl (s->fd, VIDIOC_ENUMINPUT, &input) < 0) { - av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n"); - return AVERROR(EIO); - } - - av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n", - ap->channel, input.name); - if(ioctl (s->fd, VIDIOC_S_INPUT, &input.index) < 0 ) { - av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set input(%d) failed\n", - ap->channel); - return AVERROR(EIO); - } - } - - if(ap->standard) { - av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n", - ap->standard ); - /* set tv standard */ - memset (&standard, 0, sizeof (standard)); - for(i=0;;i++) { - standard.index = i; - if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) { - av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n", - ap->standard); - return AVERROR(EIO); - } - - if(!strcasecmp(standard.name, ap->standard)) { - break; - } - } - - av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n", - ap->standard, (uint64_t)standard.id); - if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) { - av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n", - ap->standard); - return AVERROR(EIO); - } - } - - return 0; -} - -static uint32_t device_try_init(AVFormatContext *s1, - const AVFormatParameters *ap, - int *width, - int *height, - enum CodecID *codec_id) -{ - uint32_t desired_format = fmt_ff2v4l(ap->pix_fmt, s1->video_codec_id); - - if (desired_format == 0 || - device_init(s1, width, height, desired_format) < 0) { - int i; - - desired_format = 0; - for (i = 0; ivideo_codec_id == CODEC_ID_NONE || - fmt_conversion_table[i].codec_id == s1->video_codec_id) { - desired_format = fmt_conversion_table[i].v4l2_fmt; - if (device_init(s1, width, height, desired_format) >= 0) { - break; - } - desired_format = 0; - } - } - } - if (desired_format != 0) { - *codec_id = fmt_v4l2codec(desired_format); - assert(*codec_id != CODEC_ID_NONE); - } - - return desired_format; -} - -static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - struct video_data *s = s1->priv_data; - AVStream *st; - int res; - uint32_t desired_format, capabilities; - enum CodecID codec_id; - - st = av_new_stream(s1, 0); - if (!st) { - return AVERROR(ENOMEM); - } - av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - - s->width = ap->width; - s->height = ap->height; - - capabilities = 0; - s->fd = device_open(s1, &capabilities); - if (s->fd < 0) { - return AVERROR(EIO); - } - av_log(s1, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n", s->fd, capabilities); - - if (!s->width && !s->height) { - struct v4l2_format fmt; - - av_log(s1, AV_LOG_VERBOSE, "Querying the device for the current frame size\n"); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) { - av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", strerror(errno)); - return AVERROR(errno); - } - s->width = fmt.fmt.pix.width; - s->height = fmt.fmt.pix.height; - av_log(s1, AV_LOG_VERBOSE, "Setting frame size to %dx%d\n", s->width, s->height); - } - - desired_format = device_try_init(s1, ap, &s->width, &s->height, &codec_id); - if (desired_format == 0) { - av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for " - "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, ap->pix_fmt); - close(s->fd); - - return AVERROR(EIO); - } - if (avcodec_check_dimensions(s1, s->width, s->height) < 0) - return AVERROR(EINVAL); - s->frame_format = desired_format; - - if( v4l2_set_parameters( s1, ap ) < 0 ) - return AVERROR(EIO); - - st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id); - s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height); - if (capabilities & V4L2_CAP_STREAMING) { - s->io_method = io_mmap; - res = mmap_init(s1); - if (res == 0) { - res = mmap_start(s1); - } - } else { - s->io_method = io_read; - res = read_init(s1); - } - if (res < 0) { - close(s->fd); - - return AVERROR(EIO); - } - s->top_field_first = first_field(s->fd); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = codec_id; - st->codec->width = s->width; - st->codec->height = s->height; - st->codec->time_base.den = ap->time_base.den; - st->codec->time_base.num = ap->time_base.num; - st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; - - return 0; -} - -static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - struct video_data *s = s1->priv_data; - int res; - - if (s->io_method == io_mmap) { - av_init_packet(pkt); - res = mmap_read_frame(s1, pkt); - } else if (s->io_method == io_read) { - if (av_new_packet(pkt, s->frame_size) < 0) - return AVERROR(EIO); - - res = read_frame(s1, pkt); - } else { - return AVERROR(EIO); - } - if (res < 0) { - return res; - } - - if (s1->streams[0]->codec->coded_frame) { - s1->streams[0]->codec->coded_frame->interlaced_frame = 1; - s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first; - } - - return pkt->size; -} - -static int v4l2_read_close(AVFormatContext *s1) -{ - struct video_data *s = s1->priv_data; - - if (s->io_method == io_mmap) { - mmap_close(s); - } - - close(s->fd); - return 0; -} - -AVInputFormat v4l2_demuxer = { - "video4linux2", - NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"), - sizeof(struct video_data), - NULL, - v4l2_read_header, - v4l2_read_packet, - v4l2_read_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/vfwcap.c b/tizen/distrib/ffmpeg/libavdevice/vfwcap.c deleted file mode 100644 index 13aaad9..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/vfwcap.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * VFW capture interface - * Copyright (c) 2006-2008 Ramiro Polla - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavformat/avformat.h" -#include -#include - -//#define DEBUG_VFW - -/* Defines for VFW missing from MinGW. - * Remove this when MinGW incorporates them. */ -#define HWND_MESSAGE ((HWND)-3) - -#define BI_RGB 0 - -/* End of missing MinGW defines */ - -struct vfw_ctx { - HWND hwnd; - HANDLE mutex; - HANDLE event; - AVPacketList *pktl; - unsigned int curbufsize; - unsigned int frame_num; -}; - -static enum PixelFormat vfw_pixfmt(DWORD biCompression, WORD biBitCount) -{ - switch(biCompression) { - case MKTAG('U', 'Y', 'V', 'Y'): - return PIX_FMT_UYVY422; - case MKTAG('Y', 'U', 'Y', '2'): - return PIX_FMT_YUYV422; - case MKTAG('I', '4', '2', '0'): - return PIX_FMT_YUV420P; - case BI_RGB: - switch(biBitCount) { /* 1-8 are untested */ - case 1: - return PIX_FMT_MONOWHITE; - case 4: - return PIX_FMT_RGB4; - case 8: - return PIX_FMT_RGB8; - case 16: - return PIX_FMT_RGB555; - case 24: - return PIX_FMT_BGR24; - case 32: - return PIX_FMT_RGB32; - } - } - return PIX_FMT_NONE; -} - -static enum CodecID vfw_codecid(DWORD biCompression) -{ - switch(biCompression) { - case MKTAG('d', 'v', 's', 'd'): - return CODEC_ID_DVVIDEO; - case MKTAG('M', 'J', 'P', 'G'): - case MKTAG('m', 'j', 'p', 'g'): - return CODEC_ID_MJPEG; - } - return CODEC_ID_NONE; -} - -#define dstruct(pctx, sname, var, type) \ - av_log(pctx, AV_LOG_DEBUG, #var":\t%"type"\n", sname->var) - -static void dump_captureparms(AVFormatContext *s, CAPTUREPARMS *cparms) -{ - av_log(s, AV_LOG_DEBUG, "CAPTUREPARMS\n"); - dstruct(s, cparms, dwRequestMicroSecPerFrame, "lu"); - dstruct(s, cparms, fMakeUserHitOKToCapture, "d"); - dstruct(s, cparms, wPercentDropForError, "u"); - dstruct(s, cparms, fYield, "d"); - dstruct(s, cparms, dwIndexSize, "lu"); - dstruct(s, cparms, wChunkGranularity, "u"); - dstruct(s, cparms, fUsingDOSMemory, "d"); - dstruct(s, cparms, wNumVideoRequested, "u"); - dstruct(s, cparms, fCaptureAudio, "d"); - dstruct(s, cparms, wNumAudioRequested, "u"); - dstruct(s, cparms, vKeyAbort, "u"); - dstruct(s, cparms, fAbortLeftMouse, "d"); - dstruct(s, cparms, fAbortRightMouse, "d"); - dstruct(s, cparms, fLimitEnabled, "d"); - dstruct(s, cparms, wTimeLimit, "u"); - dstruct(s, cparms, fMCIControl, "d"); - dstruct(s, cparms, fStepMCIDevice, "d"); - dstruct(s, cparms, dwMCIStartTime, "lu"); - dstruct(s, cparms, dwMCIStopTime, "lu"); - dstruct(s, cparms, fStepCaptureAt2x, "d"); - dstruct(s, cparms, wStepCaptureAverageFrames, "u"); - dstruct(s, cparms, dwAudioBufferSize, "lu"); - dstruct(s, cparms, fDisableWriteCache, "d"); - dstruct(s, cparms, AVStreamMaster, "u"); -} - -static void dump_videohdr(AVFormatContext *s, VIDEOHDR *vhdr) -{ -#ifdef DEBUG_VFW - av_log(s, AV_LOG_DEBUG, "VIDEOHDR\n"); - dstruct(s, vhdr, lpData, "p"); - dstruct(s, vhdr, dwBufferLength, "lu"); - dstruct(s, vhdr, dwBytesUsed, "lu"); - dstruct(s, vhdr, dwTimeCaptured, "lu"); - dstruct(s, vhdr, dwUser, "lu"); - dstruct(s, vhdr, dwFlags, "lu"); - dstruct(s, vhdr, dwReserved[0], "lu"); - dstruct(s, vhdr, dwReserved[1], "lu"); - dstruct(s, vhdr, dwReserved[2], "lu"); - dstruct(s, vhdr, dwReserved[3], "lu"); -#endif -} - -static void dump_bih(AVFormatContext *s, BITMAPINFOHEADER *bih) -{ - av_log(s, AV_LOG_DEBUG, "BITMAPINFOHEADER\n"); - dstruct(s, bih, biSize, "lu"); - dstruct(s, bih, biWidth, "ld"); - dstruct(s, bih, biHeight, "ld"); - dstruct(s, bih, biPlanes, "d"); - dstruct(s, bih, biBitCount, "d"); - dstruct(s, bih, biCompression, "lu"); - av_log(s, AV_LOG_DEBUG, " biCompression:\t\"%.4s\"\n", - (char*) &bih->biCompression); - dstruct(s, bih, biSizeImage, "lu"); - dstruct(s, bih, biXPelsPerMeter, "lu"); - dstruct(s, bih, biYPelsPerMeter, "lu"); - dstruct(s, bih, biClrUsed, "lu"); - dstruct(s, bih, biClrImportant, "lu"); -} - -static int shall_we_drop(AVFormatContext *s) -{ - struct vfw_ctx *ctx = s->priv_data; - const uint8_t dropscore[] = {62, 75, 87, 100}; - const int ndropscores = FF_ARRAY_ELEMS(dropscore); - unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer; - - if(dropscore[++ctx->frame_num%ndropscores] <= buffer_fullness) { - av_log(s, AV_LOG_ERROR, - "real-time buffer %d%% full! frame dropped!\n", buffer_fullness); - return 1; - } - - return 0; -} - -static LRESULT CALLBACK videostream_cb(HWND hwnd, LPVIDEOHDR vdhdr) -{ - AVFormatContext *s; - struct vfw_ctx *ctx; - AVPacketList **ppktl, *pktl_next; - - s = (AVFormatContext *) GetWindowLongPtr(hwnd, GWLP_USERDATA); - ctx = s->priv_data; - - dump_videohdr(s, vdhdr); - - if(shall_we_drop(s)) - return FALSE; - - WaitForSingleObject(ctx->mutex, INFINITE); - - pktl_next = av_mallocz(sizeof(AVPacketList)); - if(!pktl_next) - goto fail; - - if(av_new_packet(&pktl_next->pkt, vdhdr->dwBytesUsed) < 0) { - av_free(pktl_next); - goto fail; - } - - pktl_next->pkt.pts = vdhdr->dwTimeCaptured; - memcpy(pktl_next->pkt.data, vdhdr->lpData, vdhdr->dwBytesUsed); - - for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next); - *ppktl = pktl_next; - - ctx->curbufsize += vdhdr->dwBytesUsed; - - SetEvent(ctx->event); - ReleaseMutex(ctx->mutex); - - return TRUE; -fail: - ReleaseMutex(ctx->mutex); - return FALSE; -} - -static int vfw_read_close(AVFormatContext *s) -{ - struct vfw_ctx *ctx = s->priv_data; - AVPacketList *pktl; - - if(ctx->hwnd) { - SendMessage(ctx->hwnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0); - SendMessage(ctx->hwnd, WM_CAP_DRIVER_DISCONNECT, 0, 0); - DestroyWindow(ctx->hwnd); - } - if(ctx->mutex) - CloseHandle(ctx->mutex); - if(ctx->event) - CloseHandle(ctx->event); - - pktl = ctx->pktl; - while (pktl) { - AVPacketList *next = pktl->next; - av_destruct_packet(&pktl->pkt); - av_free(pktl); - pktl = next; - } - - return 0; -} - -static int vfw_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - struct vfw_ctx *ctx = s->priv_data; - AVCodecContext *codec; - AVStream *st; - int devnum; - int bisize; - BITMAPINFO *bi; - CAPTUREPARMS cparms; - DWORD biCompression; - WORD biBitCount; - int width; - int height; - int ret; - - if(!ap->time_base.den) { - av_log(s, AV_LOG_ERROR, "A time base must be specified.\n"); - return AVERROR(EIO); - } - - ctx->hwnd = capCreateCaptureWindow(NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0); - if(!ctx->hwnd) { - av_log(s, AV_LOG_ERROR, "Could not create capture window.\n"); - return AVERROR(EIO); - } - - /* If atoi fails, devnum==0 and the default device is used */ - devnum = atoi(s->filename); - - ret = SendMessage(ctx->hwnd, WM_CAP_DRIVER_CONNECT, devnum, 0); - if(!ret) { - av_log(s, AV_LOG_ERROR, "Could not connect to device.\n"); - DestroyWindow(ctx->hwnd); - return AVERROR(ENODEV); - } - - SendMessage(ctx->hwnd, WM_CAP_SET_OVERLAY, 0, 0); - SendMessage(ctx->hwnd, WM_CAP_SET_PREVIEW, 0, 0); - - ret = SendMessage(ctx->hwnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, - (LPARAM) videostream_cb); - if(!ret) { - av_log(s, AV_LOG_ERROR, "Could not set video stream callback.\n"); - goto fail_io; - } - - SetWindowLongPtr(ctx->hwnd, GWLP_USERDATA, (LONG_PTR) s); - - st = av_new_stream(s, 0); - if(!st) { - vfw_read_close(s); - return AVERROR(ENOMEM); - } - - /* Set video format */ - bisize = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, 0, 0); - if(!bisize) - goto fail_io; - bi = av_malloc(bisize); - if(!bi) { - vfw_read_close(s); - return AVERROR(ENOMEM); - } - ret = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, bisize, (LPARAM) bi); - if(!ret) - goto fail_bi; - - dump_bih(s, &bi->bmiHeader); - - width = ap->width ? ap->width : bi->bmiHeader.biWidth ; - height = ap->height ? ap->height : bi->bmiHeader.biHeight; - bi->bmiHeader.biWidth = width ; - bi->bmiHeader.biHeight = height; - - if (0) { - /* For testing yet unsupported compressions - * Copy these values from user-supplied verbose information */ - bi->bmiHeader.biWidth = 320; - bi->bmiHeader.biHeight = 240; - bi->bmiHeader.biPlanes = 1; - bi->bmiHeader.biBitCount = 12; - bi->bmiHeader.biCompression = MKTAG('I','4','2','0'); - bi->bmiHeader.biSizeImage = 115200; - dump_bih(s, &bi->bmiHeader); - } - - ret = SendMessage(ctx->hwnd, WM_CAP_SET_VIDEOFORMAT, bisize, (LPARAM) bi); - if(!ret) { - av_log(s, AV_LOG_ERROR, "Could not set Video Format.\n"); - goto fail_bi; - } - - biCompression = bi->bmiHeader.biCompression; - biBitCount = bi->bmiHeader.biBitCount; - - av_free(bi); - - /* Set sequence setup */ - ret = SendMessage(ctx->hwnd, WM_CAP_GET_SEQUENCE_SETUP, sizeof(cparms), - (LPARAM) &cparms); - if(!ret) - goto fail_io; - - dump_captureparms(s, &cparms); - - cparms.fYield = 1; // Spawn a background thread - cparms.dwRequestMicroSecPerFrame = - (ap->time_base.num*1000000) / ap->time_base.den; - cparms.fAbortLeftMouse = 0; - cparms.fAbortRightMouse = 0; - cparms.fCaptureAudio = 0; - cparms.vKeyAbort = 0; - - ret = SendMessage(ctx->hwnd, WM_CAP_SET_SEQUENCE_SETUP, sizeof(cparms), - (LPARAM) &cparms); - if(!ret) - goto fail_io; - - codec = st->codec; - codec->time_base = ap->time_base; - codec->codec_type = AVMEDIA_TYPE_VIDEO; - codec->width = width; - codec->height = height; - codec->pix_fmt = vfw_pixfmt(biCompression, biBitCount); - if(codec->pix_fmt == PIX_FMT_NONE) { - codec->codec_id = vfw_codecid(biCompression); - if(codec->codec_id == CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "Unknown compression type. " - "Please report verbose (-v 9) debug information.\n"); - vfw_read_close(s); - return AVERROR_PATCHWELCOME; - } - codec->bits_per_coded_sample = biBitCount; - } else { - codec->codec_id = CODEC_ID_RAWVIDEO; - if(biCompression == BI_RGB) { - codec->bits_per_coded_sample = biBitCount; - codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE); - if (codec->extradata) { - codec->extradata_size = 9; - memcpy(codec->extradata, "BottomUp", 9); - } - } - } - - av_set_pts_info(st, 32, 1, 1000); - - ctx->mutex = CreateMutex(NULL, 0, NULL); - if(!ctx->mutex) { - av_log(s, AV_LOG_ERROR, "Could not create Mutex.\n" ); - goto fail_io; - } - ctx->event = CreateEvent(NULL, 1, 0, NULL); - if(!ctx->event) { - av_log(s, AV_LOG_ERROR, "Could not create Event.\n" ); - goto fail_io; - } - - ret = SendMessage(ctx->hwnd, WM_CAP_SEQUENCE_NOFILE, 0, 0); - if(!ret) { - av_log(s, AV_LOG_ERROR, "Could not start capture sequence.\n" ); - goto fail_io; - } - - return 0; - -fail_bi: - av_free(bi); - -fail_io: - vfw_read_close(s); - return AVERROR(EIO); -} - -static int vfw_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - struct vfw_ctx *ctx = s->priv_data; - AVPacketList *pktl = NULL; - - while(!pktl) { - WaitForSingleObject(ctx->mutex, INFINITE); - pktl = ctx->pktl; - if(ctx->pktl) { - *pkt = ctx->pktl->pkt; - ctx->pktl = ctx->pktl->next; - av_free(pktl); - } - ResetEvent(ctx->event); - ReleaseMutex(ctx->mutex); - if(!pktl) { - if(s->flags & AVFMT_FLAG_NONBLOCK) { - return AVERROR(EAGAIN); - } else { - WaitForSingleObject(ctx->event, INFINITE); - } - } - } - - ctx->curbufsize -= pkt->size; - - return pkt->size; -} - -AVInputFormat vfwcap_demuxer = { - "vfwcap", - NULL_IF_CONFIG_SMALL("VFW video capture"), - sizeof(struct vfw_ctx), - NULL, - vfw_read_header, - vfw_read_packet, - vfw_read_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavdevice/x11grab.c b/tizen/distrib/ffmpeg/libavdevice/x11grab.c deleted file mode 100644 index ab0a94c..0000000 --- a/tizen/distrib/ffmpeg/libavdevice/x11grab.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * X11 video grab interface - * - * This file is part of FFmpeg. - * - * FFmpeg integration: - * Copyright (C) 2006 Clemens Fruhwirth - * Edouard Gomez - * - * This file contains code from grab.c: - * Copyright (c) 2000-2001 Fabrice Bellard - * - * This file contains code from the xvidcap project: - * Copyright (C) 1997-1998 Rasca, Berlin - * 2003-2004 Karl H. Beckers, Frankfurt - * - * FFmpeg 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. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * X11 frame device demuxer by Clemens Fruhwirth - * and Edouard Gomez . - */ - -#define _XOPEN_SOURCE 600 - -#include "config.h" -#include "libavformat/avformat.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * X11 Device Demuxer context - */ -struct x11_grab -{ - int frame_size; /**< Size in bytes of a grabbed frame */ - AVRational time_base; /**< Time base */ - int64_t time_frame; /**< Current time */ - - int height; /**< Height of the grab frame */ - int width; /**< Width of the grab frame */ - int x_off; /**< Horizontal top-left corner coordinate */ - int y_off; /**< Vertical top-left corner coordinate */ - - Display *dpy; /**< X11 display from which x11grab grabs frames */ - XImage *image; /**< X11 image holding the grab */ - int use_shm; /**< !0 when using XShm extension */ - XShmSegmentInfo shminfo; /**< When using XShm, keeps track of XShm infos */ - int nomouse; -}; - -/** - * Initializes the x11 grab device demuxer (public device demuxer API). - * - * @param s1 Context from avformat core - * @param ap Parameters from avformat core - * @return

- */ -static int -x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - struct x11_grab *x11grab = s1->priv_data; - Display *dpy; - AVStream *st = NULL; - enum PixelFormat input_pixfmt; - XImage *image; - int x_off = 0; - int y_off = 0; - int use_shm; - char *param, *offset; - - param = av_strdup(s1->filename); - offset = strchr(param, '+'); - if (offset) { - sscanf(offset, "%d,%d", &x_off, &y_off); - x11grab->nomouse= strstr(offset, "nomouse"); - *offset= 0; - } - - av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", s1->filename, param, x_off, y_off, ap->width, ap->height); - - dpy = XOpenDisplay(param); - if(!dpy) { - av_log(s1, AV_LOG_ERROR, "Could not open X display.\n"); - return AVERROR(EIO); - } - - if (ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) { - av_log(s1, AV_LOG_ERROR, "AVParameters don't have video size and/or rate. Use -s and -r.\n"); - return AVERROR(EIO); - } - - st = av_new_stream(s1, 0); - if (!st) { - return AVERROR(ENOMEM); - } - av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - - use_shm = XShmQueryExtension(dpy); - av_log(s1, AV_LOG_INFO, "shared memory extension %s found\n", use_shm ? "" : "not"); - - if(use_shm) { - int scr = XDefaultScreen(dpy); - image = XShmCreateImage(dpy, - DefaultVisual(dpy, scr), - DefaultDepth(dpy, scr), - ZPixmap, - NULL, - &x11grab->shminfo, - ap->width, ap->height); - x11grab->shminfo.shmid = shmget(IPC_PRIVATE, - image->bytes_per_line * image->height, - IPC_CREAT|0777); - if (x11grab->shminfo.shmid == -1) { - av_log(s1, AV_LOG_ERROR, "Fatal: Can't get shared memory!\n"); - return AVERROR(ENOMEM); - } - x11grab->shminfo.shmaddr = image->data = shmat(x11grab->shminfo.shmid, 0, 0); - x11grab->shminfo.readOnly = False; - - if (!XShmAttach(dpy, &x11grab->shminfo)) { - av_log(s1, AV_LOG_ERROR, "Fatal: Failed to attach shared memory!\n"); - /* needs some better error subroutine :) */ - return AVERROR(EIO); - } - } else { - image = XGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)), - x_off,y_off, - ap->width,ap->height, - AllPlanes, ZPixmap); - } - - switch (image->bits_per_pixel) { - case 8: - av_log (s1, AV_LOG_DEBUG, "8 bit palette\n"); - input_pixfmt = PIX_FMT_PAL8; - break; - case 16: - if ( image->red_mask == 0xf800 && - image->green_mask == 0x07e0 && - image->blue_mask == 0x001f ) { - av_log (s1, AV_LOG_DEBUG, "16 bit RGB565\n"); - input_pixfmt = PIX_FMT_RGB565; - } else if (image->red_mask == 0x7c00 && - image->green_mask == 0x03e0 && - image->blue_mask == 0x001f ) { - av_log(s1, AV_LOG_DEBUG, "16 bit RGB555\n"); - input_pixfmt = PIX_FMT_RGB555; - } else { - av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel); - av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask); - return AVERROR(EIO); - } - break; - case 24: - if ( image->red_mask == 0xff0000 && - image->green_mask == 0x00ff00 && - image->blue_mask == 0x0000ff ) { - input_pixfmt = PIX_FMT_BGR24; - } else if ( image->red_mask == 0x0000ff && - image->green_mask == 0x00ff00 && - image->blue_mask == 0xff0000 ) { - input_pixfmt = PIX_FMT_RGB24; - } else { - av_log(s1, AV_LOG_ERROR,"rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel); - av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask); - return AVERROR(EIO); - } - break; - case 32: -#if 0 - GetColorInfo (image, &c_info); - if ( c_info.alpha_mask == 0xff000000 && image->green_mask == 0x0000ff00) { - /* byte order is relevant here, not endianness - * endianness is handled by avcodec, but atm no such thing - * as having ABGR, instead of ARGB in a word. Since we - * need this for Solaris/SPARC, but need to do the conversion - * for every frame we do it outside of this loop, cf. below - * this matches both ARGB32 and ABGR32 */ - input_pixfmt = PIX_FMT_ARGB32; - } else { - av_log(s1, AV_LOG_ERROR,"image depth %i not supported ... aborting\n", image->bits_per_pixel); - return AVERROR(EIO); - } -#endif - input_pixfmt = PIX_FMT_RGB32; - break; - default: - av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel); - return -1; - } - - x11grab->frame_size = ap->width * ap->height * image->bits_per_pixel/8; - x11grab->dpy = dpy; - x11grab->width = ap->width; - x11grab->height = ap->height; - x11grab->time_base = ap->time_base; - x11grab->time_frame = av_gettime() / av_q2d(ap->time_base); - x11grab->x_off = x_off; - x11grab->y_off = y_off; - x11grab->image = image; - x11grab->use_shm = use_shm; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->width = ap->width; - st->codec->height = ap->height; - st->codec->pix_fmt = input_pixfmt; - st->codec->time_base = ap->time_base; - st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(ap->time_base) * 8; - - return 0; -} - -/** - * Paints a mouse pointer in an X11 image. - * - * @param image image to paint the mouse pointer to - * @param s context used to retrieve original grabbing rectangle - * coordinates - * @param x Mouse pointer coordinate - * @param y Mouse pointer coordinate - */ -static void -paint_mouse_pointer(XImage *image, struct x11_grab *s) -{ - int x_off = s->x_off; - int y_off = s->y_off; - int width = s->width; - int height = s->height; - Display *dpy = s->dpy; - XFixesCursorImage *xcim; - int x, y; - int line, column; - int to_line, to_column; - int image_addr, xcim_addr; - - xcim = XFixesGetCursorImage(dpy);; - - x = xcim->x - xcim->xhot; - y = xcim->y - xcim->yhot; - - to_line = FFMIN((y + xcim->height), (height + y_off)); - to_column = FFMIN((x + xcim->width), (width + x_off)); - - for (line = FFMAX(y, y_off); line < to_line; line++) { - for (column = FFMAX(x, x_off); column < to_column; column++) { - xcim_addr = (line - y) * xcim->width + column - x; - - if ((unsigned char)(xcim->pixels[xcim_addr] >> 24) != 0) { // skip fully transparent pixel - image_addr = ((line - y_off) * width + column - x_off) * 4; - - image->data[image_addr] = (unsigned char)(xcim->pixels[xcim_addr] >> 0); - image->data[image_addr+1] = (unsigned char)(xcim->pixels[xcim_addr] >> 8); - image->data[image_addr+2] = (unsigned char)(xcim->pixels[xcim_addr] >> 16); - } - } - } - - XFree(xcim); - xcim = NULL; -} - - -/** - * Reads new data in the image structure. - * - * @param dpy X11 display to grab from - * @param d - * @param image Image where the grab will be put - * @param x Top-Left grabbing rectangle horizontal coordinate - * @param y Top-Left grabbing rectangle vertical coordinate - * @return 0 if error, !0 if successful - */ -static int -xget_zpixmap(Display *dpy, Drawable d, XImage *image, int x, int y) -{ - xGetImageReply rep; - xGetImageReq *req; - long nbytes; - - if (!image) { - return 0; - } - - LockDisplay(dpy); - GetReq(GetImage, req); - - /* First set up the standard stuff in the request */ - req->drawable = d; - req->x = x; - req->y = y; - req->width = image->width; - req->height = image->height; - req->planeMask = (unsigned int)AllPlanes; - req->format = ZPixmap; - - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.length) { - UnlockDisplay(dpy); - SyncHandle(); - return 0; - } - - nbytes = (long)rep.length << 2; - _XReadPad(dpy, image->data, nbytes); - - UnlockDisplay(dpy); - SyncHandle(); - return 1; -} - -/** - * Grabs a frame from x11 (public device demuxer API). - * - * @param s1 Context from avformat core - * @param pkt Packet holding the brabbed frame - * @return frame size in bytes - */ -static int -x11grab_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - struct x11_grab *s = s1->priv_data; - Display *dpy = s->dpy; - XImage *image = s->image; - int x_off = s->x_off; - int y_off = s->y_off; - - int64_t curtime, delay; - struct timespec ts; - - /* Calculate the time of the next frame */ - s->time_frame += INT64_C(1000000); - - /* wait based on the frame rate */ - for(;;) { - curtime = av_gettime(); - delay = s->time_frame * av_q2d(s->time_base) - curtime; - if (delay <= 0) { - if (delay < INT64_C(-1000000) * av_q2d(s->time_base)) { - s->time_frame += INT64_C(1000000); - } - break; - } - ts.tv_sec = delay / 1000000; - ts.tv_nsec = (delay % 1000000) * 1000; - nanosleep(&ts, NULL); - } - - if (av_new_packet(pkt, s->frame_size) < 0) { - return AVERROR(EIO); - } - - pkt->pts = curtime; - - if(s->use_shm) { - if (!XShmGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off, AllPlanes)) { - av_log (s1, AV_LOG_INFO, "XShmGetImage() failed\n"); - } - } else { - if (!xget_zpixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), image, x_off, y_off)) { - av_log (s1, AV_LOG_INFO, "XGetZPixmap() failed\n"); - } - } - - if(!s->nomouse){ - paint_mouse_pointer(image, s); - } - - - /* XXX: avoid memcpy */ - memcpy(pkt->data, image->data, s->frame_size); - return s->frame_size; -} - -/** - * Closes x11 frame grabber (public device demuxer API). - * - * @param s1 Context from avformat core - * @return 0 success, !0 failure - */ -static int -x11grab_read_close(AVFormatContext *s1) -{ - struct x11_grab *x11grab = s1->priv_data; - - /* Detach cleanly from shared mem */ - if (x11grab->use_shm) { - XShmDetach(x11grab->dpy, &x11grab->shminfo); - shmdt(x11grab->shminfo.shmaddr); - shmctl(x11grab->shminfo.shmid, IPC_RMID, NULL); - } - - /* Destroy X11 image */ - if (x11grab->image) { - XDestroyImage(x11grab->image); - x11grab->image = NULL; - } - - /* Free X11 display */ - XCloseDisplay(x11grab->dpy); - return 0; -} - -/** x11 grabber device demuxer declaration */ -AVInputFormat x11_grab_device_demuxer = -{ - "x11grab", - NULL_IF_CONFIG_SMALL("X11grab"), - sizeof(struct x11_grab), - NULL, - x11grab_read_header, - x11grab_read_packet, - x11grab_read_close, - .flags = AVFMT_NOFILE, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/Makefile b/tizen/distrib/ffmpeg/libavfilter/Makefile deleted file mode 100644 index 84f7a9c..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = avfilter -FFLIBS = avcodec avutil swscale -FFLIBS-$(CONFIG_AVFILTER_LAVF) += avformat - -HEADERS = avfilter.h - -OBJS = allfilters.o \ - avfilter.o \ - avfiltergraph.o \ - defaults.o \ - formats.o \ - graphparser.o \ - parseutils.o \ - -OBJS-$(CONFIG_ASPECT_FILTER) += vf_aspect.o -OBJS-$(CONFIG_CROP_FILTER) += vf_crop.o -OBJS-$(CONFIG_FORMAT_FILTER) += vf_format.o -OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o -OBJS-$(CONFIG_NULL_FILTER) += vf_null.o -OBJS-$(CONFIG_PIXELASPECT_FILTER) += vf_aspect.o -OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o -OBJS-$(CONFIG_SLICIFY_FILTER) += vf_slicify.o -OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o -OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o - -OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_nullsrc.o - -OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o - -include $(SUBDIR)../subdir.mak diff --git a/tizen/distrib/ffmpeg/libavfilter/allfilters.c b/tizen/distrib/ffmpeg/libavfilter/allfilters.c deleted file mode 100644 index 75d42cc..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/allfilters.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * filter registration - * copyright (c) 2008 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avfilter.h" - - -#define REGISTER_FILTER(X,x,y) { \ - extern AVFilter avfilter_##y##_##x ; \ - if(CONFIG_##X##_FILTER ) avfilter_register(&avfilter_##y##_##x ); } - -void avfilter_register_all(void) -{ - static int initialized; - - if (initialized) - return; - initialized = 1; - - REGISTER_FILTER (ASPECT, aspect, vf); - REGISTER_FILTER (CROP, crop, vf); - REGISTER_FILTER (FORMAT, format, vf); - REGISTER_FILTER (NOFORMAT, noformat, vf); - REGISTER_FILTER (NULL, null, vf); - REGISTER_FILTER (PIXELASPECT, pixelaspect, vf); - REGISTER_FILTER (SCALE, scale, vf); - REGISTER_FILTER (SLICIFY, slicify, vf); - REGISTER_FILTER (UNSHARP, unsharp, vf); - REGISTER_FILTER (VFLIP, vflip, vf); - - REGISTER_FILTER (NULLSRC, nullsrc, vsrc); - - REGISTER_FILTER (NULLSINK, nullsink, vsink); -} diff --git a/tizen/distrib/ffmpeg/libavfilter/avfilter.c b/tizen/distrib/ffmpeg/libavfilter/avfilter.c deleted file mode 100644 index 3ed59d7..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/avfilter.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * filter layer - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* #define DEBUG */ - -#include "libavcodec/imgconvert.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" - -unsigned avfilter_version(void) { - return LIBAVFILTER_VERSION_INT; -} - -const char *avfilter_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *avfilter_license(void) -{ -#define LICENSE_PREFIX "libavfilter license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} - -/** helper macros to get the in/out pad on the dst/src filter */ -#define link_dpad(link) link->dst-> input_pads[link->dstpad] -#define link_spad(link) link->src->output_pads[link->srcpad] - -AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask) -{ - AVFilterPicRef *ret = av_malloc(sizeof(AVFilterPicRef)); - *ret = *ref; - ret->perms &= pmask; - ret->pic->refcount ++; - return ret; -} - -void avfilter_unref_pic(AVFilterPicRef *ref) -{ - if(!(--ref->pic->refcount)) - ref->pic->free(ref->pic); - av_free(ref); -} - -void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, - AVFilterPad **pads, AVFilterLink ***links, - AVFilterPad *newpad) -{ - unsigned i; - - idx = FFMIN(idx, *count); - - *pads = av_realloc(*pads, sizeof(AVFilterPad) * (*count + 1)); - *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1)); - memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad) * (*count-idx)); - memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx)); - memcpy(*pads+idx, newpad, sizeof(AVFilterPad)); - (*links)[idx] = NULL; - - (*count) ++; - for(i = idx+1; i < *count; i ++) - if(*links[i]) - (*(unsigned *)((uint8_t *) *links[i] + padidx_off)) ++; -} - -int avfilter_link(AVFilterContext *src, unsigned srcpad, - AVFilterContext *dst, unsigned dstpad) -{ - AVFilterLink *link; - - if(src->output_count <= srcpad || dst->input_count <= dstpad || - src->outputs[srcpad] || dst->inputs[dstpad]) - return -1; - - src->outputs[srcpad] = - dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink)); - - link->src = src; - link->dst = dst; - link->srcpad = srcpad; - link->dstpad = dstpad; - link->format = PIX_FMT_NONE; - - return 0; -} - -int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, - unsigned in, unsigned out) -{ - av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s' " - "between the filter '%s' and the filter '%s'\n", - filt->name, link->src->name, link->dst->name); - - link->dst->inputs[link->dstpad] = NULL; - if(avfilter_link(filt, out, link->dst, link->dstpad)) { - /* failed to link output filter to new filter */ - link->dst->inputs[link->dstpad] = link; - return -1; - } - - /* re-hookup the link to the new destination filter we inserted */ - link->dst = filt; - link->dstpad = in; - filt->inputs[in] = link; - - /* if any information on supported colorspaces already exists on the - * link, we need to preserve that */ - if(link->out_formats) - avfilter_formats_changeref(&link->out_formats, - &filt->outputs[out]->out_formats); - - return 0; -} - -int avfilter_config_links(AVFilterContext *filter) -{ - int (*config_link)(AVFilterLink *); - unsigned i; - - for(i = 0; i < filter->input_count; i ++) { - AVFilterLink *link = filter->inputs[i]; - - if(!link) continue; - - switch(link->init_state) { - case AVLINK_INIT: - continue; - case AVLINK_STARTINIT: - av_log(filter, AV_LOG_INFO, "circular filter chain detected\n"); - return 0; - case AVLINK_UNINIT: - link->init_state = AVLINK_STARTINIT; - - if(avfilter_config_links(link->src)) - return -1; - - if(!(config_link = link_spad(link).config_props)) - config_link = avfilter_default_config_output_link; - if(config_link(link)) - return -1; - - if((config_link = link_dpad(link).config_props)) - if(config_link(link)) - return -1; - - link->init_state = AVLINK_INIT; - } - } - - return 0; -} - -static void dprintf_picref(void *ctx, AVFilterPicRef *picref, int end) -{ - dprintf(ctx, - "picref[%p data[%p, %p, %p, %p] linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64" a:%d/%d s:%dx%d]%s", - picref, - picref->data [0], picref->data [1], picref->data [2], picref->data [3], - picref->linesize[0], picref->linesize[1], picref->linesize[2], picref->linesize[3], - picref->pts, picref->pos, - picref->pixel_aspect.num, picref->pixel_aspect.den, picref->w, picref->h, - end ? "\n" : ""); -} - -static void dprintf_link(void *ctx, AVFilterLink *link, int end) -{ - dprintf(ctx, - "link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s", - link, link->w, link->h, - av_pix_fmt_descriptors[link->format].name, - link->src ? link->src->filter->name : "", - link->dst ? link->dst->filter->name : "", - end ? "\n" : ""); -} - -#define DPRINTF_START(ctx, func) dprintf(NULL, "%-16s: ", #func) - -AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h) -{ - AVFilterPicRef *ret = NULL; - - DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d w:%d h:%d\n", perms, w, h); - - if(link_dpad(link).get_video_buffer) - ret = link_dpad(link).get_video_buffer(link, perms, w, h); - - if(!ret) - ret = avfilter_default_get_video_buffer(link, perms, w, h); - - DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " returning "); dprintf_picref(NULL, ret, 1); - - return ret; -} - -int avfilter_request_frame(AVFilterLink *link) -{ - DPRINTF_START(NULL, request_frame); dprintf_link(NULL, link, 1); - - if(link_spad(link).request_frame) - return link_spad(link).request_frame(link); - else if(link->src->inputs[0]) - return avfilter_request_frame(link->src->inputs[0]); - else return -1; -} - -int avfilter_poll_frame(AVFilterLink *link) -{ - int i, min=INT_MAX; - - if(link_spad(link).poll_frame) - return link_spad(link).poll_frame(link); - - for (i=0; isrc->input_count; i++) { - int val; - if(!link->src->inputs[i]) - return -1; - val = avfilter_poll_frame(link->src->inputs[i]); - min = FFMIN(min, val); - } - - return min; -} - -/* XXX: should we do the duplicating of the picture ref here, instead of - * forcing the source filter to do it? */ -void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - void (*start_frame)(AVFilterLink *, AVFilterPicRef *); - AVFilterPad *dst = &link_dpad(link); - - DPRINTF_START(NULL, start_frame); dprintf_link(NULL, link, 0); dprintf(NULL, " "); dprintf_picref(NULL, picref, 1); - - if(!(start_frame = dst->start_frame)) - start_frame = avfilter_default_start_frame; - - /* prepare to copy the picture if it has insufficient permissions */ - if((dst->min_perms & picref->perms) != dst->min_perms || - dst->rej_perms & picref->perms) { - /* - av_log(link->dst, AV_LOG_INFO, - "frame copy needed (have perms %x, need %x, reject %x)\n", - picref->perms, - link_dpad(link).min_perms, link_dpad(link).rej_perms); - */ - - link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms, link->w, link->h); - link->srcpic = picref; - link->cur_pic->pts = link->srcpic->pts; - link->cur_pic->pos = link->srcpic->pos; - link->cur_pic->pixel_aspect = link->srcpic->pixel_aspect; - } - else - link->cur_pic = picref; - - start_frame(link, link->cur_pic); -} - -void avfilter_end_frame(AVFilterLink *link) -{ - void (*end_frame)(AVFilterLink *); - - if(!(end_frame = link_dpad(link).end_frame)) - end_frame = avfilter_default_end_frame; - - end_frame(link); - - /* unreference the source picture if we're feeding the destination filter - * a copied version dues to permission issues */ - if(link->srcpic) { - avfilter_unref_pic(link->srcpic); - link->srcpic = NULL; - } - -} - -void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - uint8_t *src[4], *dst[4]; - int i, j, vsub; - void (*draw_slice)(AVFilterLink *, int, int, int); - - DPRINTF_START(NULL, draw_slice); dprintf_link(NULL, link, 0); dprintf(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir); - - /* copy the slice if needed for permission reasons */ - if(link->srcpic) { - vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; - - for(i = 0; i < 4; i ++) { - if(link->srcpic->data[i]) { - src[i] = link->srcpic-> data[i] + - (y >> (i==0 ? 0 : vsub)) * link->srcpic-> linesize[i]; - dst[i] = link->cur_pic->data[i] + - (y >> (i==0 ? 0 : vsub)) * link->cur_pic->linesize[i]; - } else - src[i] = dst[i] = NULL; - } - - for(i = 0; i < 4; i ++) { - int planew = - ff_get_plane_bytewidth(link->format, link->cur_pic->w, i); - - if(!src[i]) continue; - - for(j = 0; j < h >> (i==0 ? 0 : vsub); j ++) { - memcpy(dst[i], src[i], planew); - src[i] += link->srcpic ->linesize[i]; - dst[i] += link->cur_pic->linesize[i]; - } - } - } - - if(!(draw_slice = link_dpad(link).draw_slice)) - draw_slice = avfilter_default_draw_slice; - draw_slice(link, y, h, slice_dir); -} - -#define MAX_REGISTERED_AVFILTERS_NB 64 - -static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1]; - -static int next_registered_avfilter_idx = 0; - -AVFilter *avfilter_get_by_name(const char *name) -{ - int i; - - for (i = 0; registered_avfilters[i]; i++) - if (!strcmp(registered_avfilters[i]->name, name)) - return registered_avfilters[i]; - - return NULL; -} - -int avfilter_register(AVFilter *filter) -{ - if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB) - return -1; - - registered_avfilters[next_registered_avfilter_idx++] = filter; - return 0; -} - -AVFilter **av_filter_next(AVFilter **filter) -{ - return filter ? ++filter : ®istered_avfilters[0]; -} - -void avfilter_uninit(void) -{ - memset(registered_avfilters, 0, sizeof(registered_avfilters)); - next_registered_avfilter_idx = 0; -} - -static int pad_count(const AVFilterPad *pads) -{ - int count; - - for(count = 0; pads->name; count ++) pads ++; - return count; -} - -static const char *filter_name(void *p) -{ - AVFilterContext *filter = p; - return filter->filter->name; -} - -static const AVClass avfilter_class = { - "AVFilter", - filter_name, - NULL, - LIBAVUTIL_VERSION_INT, -}; - -AVFilterContext *avfilter_open(AVFilter *filter, const char *inst_name) -{ - AVFilterContext *ret; - - if (!filter) - return 0; - - ret = av_mallocz(sizeof(AVFilterContext)); - - ret->av_class = &avfilter_class; - ret->filter = filter; - ret->name = inst_name ? av_strdup(inst_name) : NULL; - ret->priv = av_mallocz(filter->priv_size); - - ret->input_count = pad_count(filter->inputs); - if (ret->input_count) { - ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->input_count); - memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count); - ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->input_count); - } - - ret->output_count = pad_count(filter->outputs); - if (ret->output_count) { - ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->output_count); - memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count); - ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->output_count); - } - - return ret; -} - -void avfilter_destroy(AVFilterContext *filter) -{ - int i; - - if(filter->filter->uninit) - filter->filter->uninit(filter); - - for(i = 0; i < filter->input_count; i ++) { - if(filter->inputs[i]) - filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL; - av_freep(&filter->inputs[i]); - } - for(i = 0; i < filter->output_count; i ++) { - if(filter->outputs[i]) - filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL; - av_freep(&filter->outputs[i]); - } - - av_freep(&filter->name); - av_freep(&filter->input_pads); - av_freep(&filter->output_pads); - av_freep(&filter->inputs); - av_freep(&filter->outputs); - av_freep(&filter->priv); - av_free(filter); -} - -int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque) -{ - int ret=0; - - if(filter->filter->init) - ret = filter->filter->init(filter, args, opaque); - return ret; -} - diff --git a/tizen/distrib/ffmpeg/libavfilter/avfilter.h b/tizen/distrib/ffmpeg/libavfilter/avfilter.h deleted file mode 100644 index 214b8d4..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/avfilter.h +++ /dev/null @@ -1,703 +0,0 @@ -/* - * filter layer - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_AVFILTER_H -#define AVFILTER_AVFILTER_H - -#include "libavutil/avutil.h" - -#define LIBAVFILTER_VERSION_MAJOR 1 -#define LIBAVFILTER_VERSION_MINOR 19 -#define LIBAVFILTER_VERSION_MICRO 0 - -#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ - LIBAVFILTER_VERSION_MINOR, \ - LIBAVFILTER_VERSION_MICRO) -#define LIBAVFILTER_VERSION AV_VERSION(LIBAVFILTER_VERSION_MAJOR, \ - LIBAVFILTER_VERSION_MINOR, \ - LIBAVFILTER_VERSION_MICRO) -#define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT - -#include -#include "libavcodec/avcodec.h" - -/** - * Returns the LIBAVFILTER_VERSION_INT constant. - */ -unsigned avfilter_version(void); - -/** - * Returns the libavfilter build-time configuration. - */ -const char *avfilter_configuration(void); - -/** - * Returns the libavfilter license. - */ -const char *avfilter_license(void); - - -typedef struct AVFilterContext AVFilterContext; -typedef struct AVFilterLink AVFilterLink; -typedef struct AVFilterPad AVFilterPad; - -/* TODO: look for other flags which may be useful in this structure (interlace - * flags, etc) - */ -/** - * A reference-counted picture data type used by the filter system. Filters - * should not store pointers to this structure directly, but instead use the - * AVFilterPicRef structure below. - */ -typedef struct AVFilterPic -{ - uint8_t *data[4]; ///< picture data for each plane - int linesize[4]; ///< number of bytes per line - enum PixelFormat format; ///< colorspace - - unsigned refcount; ///< number of references to this image - - /** private data to be used by a custom free function */ - void *priv; - /** - * A pointer to the function to deallocate this image if the default - * function is not sufficient. This could, for example, add the memory - * back into a memory pool to be reused later without the overhead of - * reallocating it from scratch. - */ - void (*free)(struct AVFilterPic *pic); - - int w, h; ///< width and height of the allocated buffer -} AVFilterPic; - -/** - * A reference to an AVFilterPic. Since filters can manipulate the origin of - * a picture to, for example, crop image without any memcpy, the picture origin - * and dimensions are per-reference properties. Linesize is also useful for - * image flipping, frame to field filters, etc, and so is also per-reference. - * - * TODO: add anything necessary for frame reordering - */ -typedef struct AVFilterPicRef -{ - AVFilterPic *pic; ///< the picture that this is a reference to - uint8_t *data[4]; ///< picture data for each plane - int linesize[4]; ///< number of bytes per line - int w; ///< image width - int h; ///< image height - - int64_t pts; ///< presentation timestamp in units of 1/AV_TIME_BASE - int64_t pos; ///< byte position in stream, -1 if unknown - - AVRational pixel_aspect; ///< pixel aspect ratio - - int perms; ///< permissions -#define AV_PERM_READ 0x01 ///< can read from the buffer -#define AV_PERM_WRITE 0x02 ///< can write to the buffer -#define AV_PERM_PRESERVE 0x04 ///< nobody else can overwrite the buffer -#define AV_PERM_REUSE 0x08 ///< can output the buffer multiple times, with the same contents each time -#define AV_PERM_REUSE2 0x10 ///< can output the buffer multiple times, modified each time -} AVFilterPicRef; - -/** - * Adds a new reference to a picture. - * @param ref an existing reference to the picture - * @param pmask a bitmask containing the allowable permissions in the new - * reference - * @return a new reference to the picture with the same properties as the - * old, excluding any permissions denied by pmask - */ -AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask); - -/** - * Removes a reference to a picture. If this is the last reference to the - * picture, the picture itself is also automatically freed. - * @param ref reference to the picture - */ -void avfilter_unref_pic(AVFilterPicRef *ref); - -/** - * A list of supported formats for one end of a filter link. This is used - * during the format negotiation process to try to pick the best format to - * use to minimize the number of necessary conversions. Each filter gives a - * list of the formats supported by each input and output pad. The list - * given for each pad need not be distinct - they may be references to the - * same list of formats, as is often the case when a filter supports multiple - * formats, but will always output the same format as it is given in input. - * - * In this way, a list of possible input formats and a list of possible - * output formats are associated with each link. When a set of formats is - * negotiated over a link, the input and output lists are merged to form a - * new list containing only the common elements of each list. In the case - * that there were no common elements, a format conversion is necessary. - * Otherwise, the lists are merged, and all other links which reference - * either of the format lists involved in the merge are also affected. - * - * For example, consider the filter chain: - * filter (a) --> (b) filter (b) --> (c) filter - * - * where the letters in parenthesis indicate a list of formats supported on - * the input or output of the link. Suppose the lists are as follows: - * (a) = {A, B} - * (b) = {A, B, C} - * (c) = {B, C} - * - * First, the first link's lists are merged, yielding: - * filter (a) --> (a) filter (a) --> (c) filter - * - * Notice that format list (b) now refers to the same list as filter list (a). - * Next, the lists for the second link are merged, yielding: - * filter (a) --> (a) filter (a) --> (a) filter - * - * where (a) = {B}. - * - * Unfortunately, when the format lists at the two ends of a link are merged, - * we must ensure that all links which reference either pre-merge format list - * get updated as well. Therefore, we have the format list structure store a - * pointer to each of the pointers to itself. - */ -typedef struct AVFilterFormats AVFilterFormats; -struct AVFilterFormats -{ - unsigned format_count; ///< number of formats - enum PixelFormat *formats; ///< list of pixel formats - - unsigned refcount; ///< number of references to this list - AVFilterFormats ***refs; ///< references to this list -}; - -/** - * Creates a list of supported formats. This is intended for use in - * AVFilter->query_formats(). - * @param pix_fmt list of pixel formats, terminated by PIX_FMT_NONE - * @return the format list, with no existing references - */ -AVFilterFormats *avfilter_make_format_list(const enum PixelFormat *pix_fmts); - -/** - * Adds pix_fmt to the list of pixel formats contained in *avff. - * If *avff is NULL the function allocates the filter formats struct - * and puts its pointer in *avff. - * - * @return a non negative value in case of success, or a negative - * value corresponding to an AVERROR code in case of error - */ -int avfilter_add_colorspace(AVFilterFormats **avff, enum PixelFormat pix_fmt); - -/** - * Returns a list of all colorspaces supported by FFmpeg. - */ -AVFilterFormats *avfilter_all_colorspaces(void); - -/** - * Returns a format list which contains the intersection of the formats of - * a and b. Also, all the references of a, all the references of b, and - * a and b themselves will be deallocated. - * - * If a and b do not share any common formats, neither is modified, and NULL - * is returned. - */ -AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b); - -/** - * Adds *ref as a new reference to formats. - * That is the pointers will point like in the ascii art below: - * ________ - * |formats |<--------. - * | ____ | ____|___________________ - * | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| - * | |____| | | |____| - * |________| |________________________ - */ -void avfilter_formats_ref(AVFilterFormats *formats, AVFilterFormats **ref); - -/** - * If *ref is non-NULL, removes *ref as a reference to the format list - * it currently points to, deallocates that list if this was the last - * reference, and sets *ref to NULL. - * - * Before After - * ________ ________ NULL - * |formats |<--------. |formats | ^ - * | ____ | ____|________________ | ____ | ____|________________ - * | |refs| | | __|_ | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| | |* | | | |*ref| - * | |____| | | |____| | |____| | | |____| - * |________| |_____________________ |________| |_____________________ - */ -void avfilter_formats_unref(AVFilterFormats **ref); - -/** - * - * Before After - * ________ ________ - * |formats |<---------. |formats |<---------. - * | ____ | ___|___ | ____ | ___|___ - * | |refs| | | | | | |refs| | | | | NULL - * | |* *--------->|*oldref| | |* *--------->|*newref| ^ - * | |* * | | |_______| | |* * | | |_______| ___|___ - * | |____| | | |____| | | | | - * |________| |________| |*oldref| - * |_______| - */ -void avfilter_formats_changeref(AVFilterFormats **oldref, - AVFilterFormats **newref); - -/** - * A filter pad used for either input or output. - */ -struct AVFilterPad -{ - /** - * Pad name. The name is unique among inputs and among outputs, but an - * input may have the same name as an output. This may be NULL if this - * pad has no need to ever be referenced by name. - */ - const char *name; - - /** - * AVFilterPad type. Only video supported now, hopefully someone will - * add audio in the future. - */ - enum AVMediaType type; - - /** - * Minimum required permissions on incoming buffers. Any buffer with - * insufficient permissions will be automatically copied by the filter - * system to a new buffer which provides the needed access permissions. - * - * Input pads only. - */ - int min_perms; - - /** - * Permissions which are not accepted on incoming buffers. Any buffer - * which has any of these permissions set will be automatically copied - * by the filter system to a new buffer which does not have those - * permissions. This can be used to easily disallow buffers with - * AV_PERM_REUSE. - * - * Input pads only. - */ - int rej_perms; - - /** - * Callback called before passing the first slice of a new frame. If - * NULL, the filter layer will default to storing a reference to the - * picture inside the link structure. - * - * Input video pads only. - */ - void (*start_frame)(AVFilterLink *link, AVFilterPicRef *picref); - - /** - * Callback function to get a buffer. If NULL, the filter system will - * use avfilter_default_get_video_buffer(). - * - * Input video pads only. - */ - AVFilterPicRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h); - - /** - * Callback called after the slices of a frame are completely sent. If - * NULL, the filter layer will default to releasing the reference stored - * in the link structure during start_frame(). - * - * Input video pads only. - */ - void (*end_frame)(AVFilterLink *link); - - /** - * Slice drawing callback. This is where a filter receives video data - * and should do its processing. - * - * Input video pads only. - */ - void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); - - /** - * Frame poll callback. This returns the number of immediately available - * frames. It should return a positive value if the next request_frame() - * is guaranteed to return one frame (with no delay). - * - * Defaults to just calling the source poll_frame() method. - * - * Output video pads only. - */ - int (*poll_frame)(AVFilterLink *link); - - /** - * Frame request callback. A call to this should result in at least one - * frame being output over the given link. This should return zero on - * success, and another value on error. - * - * Output video pads only. - */ - int (*request_frame)(AVFilterLink *link); - - /** - * Link configuration callback. - * - * For output pads, this should set the link properties such as - * width/height. This should NOT set the format property - that is - * negotiated between filters by the filter system using the - * query_formats() callback before this function is called. - * - * For input pads, this should check the properties of the link, and update - * the filter's internal state as necessary. - * - * For both input and output filters, this should return zero on success, - * and another value on error. - */ - int (*config_props)(AVFilterLink *link); -}; - -/** default handler for start_frame() for video inputs */ -void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref); -/** default handler for draw_slice() for video inputs */ -void avfilter_default_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); -/** default handler for end_frame() for video inputs */ -void avfilter_default_end_frame(AVFilterLink *link); -/** default handler for config_props() for video outputs */ -int avfilter_default_config_output_link(AVFilterLink *link); -/** default handler for config_props() for video inputs */ -int avfilter_default_config_input_link (AVFilterLink *link); -/** default handler for get_video_buffer() for video inputs */ -AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, - int perms, int w, int h); -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); -/** Default handler for query_formats() */ -int avfilter_default_query_formats(AVFilterContext *ctx); - -/** start_frame() handler for filters which simply pass video along */ -void avfilter_null_start_frame(AVFilterLink *link, AVFilterPicRef *picref); - -/** draw_slice() handler for filters which simply pass video along */ -void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); - -/** end_frame() handler for filters which simply pass video along */ -void avfilter_null_end_frame(AVFilterLink *link); - -/** get_video_buffer() handler for filters which simply pass video along */ -AVFilterPicRef *avfilter_null_get_video_buffer(AVFilterLink *link, - int perms, int w, int h); - -/** - * Filter definition. This defines the pads a filter contains, and all the - * callback functions used to interact with the filter. - */ -typedef struct AVFilter -{ - const char *name; ///< filter name - - int priv_size; ///< size of private data to allocate for the filter - - /** - * Filter initialization function. Args contains the user-supplied - * parameters. FIXME: maybe an AVOption-based system would be better? - * opaque is data provided by the code requesting creation of the filter, - * and is used to pass data to the filter. - */ - int (*init)(AVFilterContext *ctx, const char *args, void *opaque); - - /** - * Filter uninitialization function. Should deallocate any memory held - * by the filter, release any picture references, etc. This does not need - * to deallocate the AVFilterContext->priv memory itself. - */ - void (*uninit)(AVFilterContext *ctx); - - /** - * Queries formats supported by the filter and its pads, and sets the - * in_formats for links connected to its output pads, and out_formats - * for links connected to its input pads. - * - * @return zero on success, a negative value corresponding to an - * AVERROR code otherwise - */ - int (*query_formats)(AVFilterContext *); - - const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none - const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none - - /** - * A description for the filter. You should use the - * NULL_IF_CONFIG_SMALL() macro to define it. - */ - const char *description; -} AVFilter; - -/** An instance of a filter */ -struct AVFilterContext -{ - const AVClass *av_class; ///< needed for av_log() - - AVFilter *filter; ///< the AVFilter of which this is an instance - - char *name; ///< name of this filter instance - - unsigned input_count; ///< number of input pads - AVFilterPad *input_pads; ///< array of input pads - AVFilterLink **inputs; ///< array of pointers to input links - - unsigned output_count; ///< number of output pads - AVFilterPad *output_pads; ///< array of output pads - AVFilterLink **outputs; ///< array of pointers to output links - - void *priv; ///< private data for use by the filter -}; - -/** - * A link between two filters. This contains pointers to the source and - * destination filters between which this link exists, and the indexes of - * the pads involved. In addition, this link also contains the parameters - * which have been negotiated and agreed upon between the filter, such as - * image dimensions, format, etc. - */ -struct AVFilterLink -{ - AVFilterContext *src; ///< source filter - unsigned int srcpad; ///< index of the output pad on the source filter - - AVFilterContext *dst; ///< dest filter - unsigned int dstpad; ///< index of the input pad on the dest filter - - /** stage of the initialization of the link properties (dimensions, etc) */ - enum { - AVLINK_UNINIT = 0, ///< not started - AVLINK_STARTINIT, ///< started, but incomplete - AVLINK_INIT ///< complete - } init_state; - - int w; ///< agreed upon image width - int h; ///< agreed upon image height - enum PixelFormat format; ///< agreed upon image colorspace - - /** - * Lists of formats supported by the input and output filters respectively. - * These lists are used for negotiating the format to actually be used, - * which will be loaded into the format member, above, when chosen. - */ - AVFilterFormats *in_formats; - AVFilterFormats *out_formats; - - /** - * The picture reference currently being sent across the link by the source - * filter. This is used internally by the filter system to allow - * automatic copying of pictures which do not have sufficient permissions - * for the destination. This should not be accessed directly by the - * filters. - */ - AVFilterPicRef *srcpic; - - AVFilterPicRef *cur_pic; - AVFilterPicRef *outpic; -}; - -/** - * Links two filters together. - * @param src the source filter - * @param srcpad index of the output pad on the source filter - * @param dst the destination filter - * @param dstpad index of the input pad on the destination filter - * @return zero on success - */ -int avfilter_link(AVFilterContext *src, unsigned srcpad, - AVFilterContext *dst, unsigned dstpad); - -/** - * Negotiates the colorspace, dimensions, etc of all inputs to a filter. - * @param filter the filter to negotiate the properties for its inputs - * @return zero on successful negotiation - */ -int avfilter_config_links(AVFilterContext *filter); - -/** - * Requests a picture buffer with a specific set of permissions. - * @param link the output link to the filter from which the picture will - * be requested - * @param perms the required access permissions - * @param w the minimum width of the buffer to allocate - * @param h the minimum height of the buffer to allocate - * @return A reference to the picture. This must be unreferenced with - * avfilter_unref_pic when you are finished with it. - */ -AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, - int w, int h); - -/** - * Requests an input frame from the filter at the other end of the link. - * @param link the input link - * @return zero on success - */ -int avfilter_request_frame(AVFilterLink *link); - -/** - * Polls a frame from the filter chain. - * @param link the input link - * @return the number of immediately available frames, a negative - * number in case of error - */ -int avfilter_poll_frame(AVFilterLink *link); - -/** - * Notifies the next filter of the start of a frame. - * @param link the output link the frame will be sent over - * @param picref A reference to the frame about to be sent. The data for this - * frame need only be valid once draw_slice() is called for that - * portion. The receiving filter will free this reference when - * it no longer needs it. - */ -void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref); - -/** - * Notifies the next filter that the current frame has finished. - * @param link the output link the frame was sent over - */ -void avfilter_end_frame(AVFilterLink *link); - -/** - * Sends a slice to the next filter. - * - * Slices have to be provided in sequential order, either in - * top-bottom or bottom-top order. If slices are provided in - * non-sequential order the behavior of the function is undefined. - * - * @param link the output link over which the frame is being sent - * @param y offset in pixels from the top of the image for this slice - * @param h height of this slice in pixels - * @param slice_dir the assumed direction for sending slices, - * from the top slice to the bottom slice if the value is 1, - * from the bottom slice to the top slice if the value is -1, - * for other values the behavior of the function is undefined. - */ -void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); - -/** Initializes the filter system. Registers all builtin filters. */ -void avfilter_register_all(void); - -/** Uninitializes the filter system. Unregisters all filters. */ -void avfilter_uninit(void); - -/** - * Registers a filter. This is only needed if you plan to use - * avfilter_get_by_name later to lookup the AVFilter structure by name. A - * filter can still by instantiated with avfilter_open even if it is not - * registered. - * @param filter the filter to register - * @return 0 if the registration was succesfull, a negative value - * otherwise - */ -int avfilter_register(AVFilter *filter); - -/** - * Gets a filter definition matching the given name. - * @param name the filter name to find - * @return the filter definition, if any matching one is registered. - * NULL if none found. - */ -AVFilter *avfilter_get_by_name(const char *name); - -/** - * If filter is NULL, returns a pointer to the first registered filter pointer, - * if filter is non-NULL, returns the next pointer after filter. - * If the returned pointer points to NULL, the last registered filter - * was already reached. - */ -AVFilter **av_filter_next(AVFilter **filter); - -/** - * Creates a filter instance. - * @param filter the filter to create an instance of - * @param inst_name Name to give to the new instance. Can be NULL for none. - * @return Pointer to the new instance on success. NULL on failure. - */ -AVFilterContext *avfilter_open(AVFilter *filter, const char *inst_name); - -/** - * Initializes a filter. - * @param filter the filter to initialize - * @param args A string of parameters to use when initializing the filter. - * The format and meaning of this string varies by filter. - * @param opaque Any extra non-string data needed by the filter. The meaning - * of this parameter varies by filter. - * @return zero on success - */ -int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque); - -/** - * Destroys a filter. - * @param filter the filter to destroy - */ -void avfilter_destroy(AVFilterContext *filter); - -/** - * Inserts a filter in the middle of an existing link. - * @param link the link into which the filter should be inserted - * @param filt the filter to be inserted - * @param in the input pad on the filter to connect - * @param out the output pad on the filter to connect - * @return zero on success - */ -int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, - unsigned in, unsigned out); - -/** - * Inserts a new pad. - * @param idx Insertion point. Pad is inserted at the end if this point - * is beyond the end of the list of pads. - * @param count Pointer to the number of pads in the list - * @param padidx_off Offset within an AVFilterLink structure to the element - * to increment when inserting a new pad causes link - * numbering to change - * @param pads Pointer to the pointer to the beginning of the list of pads - * @param links Pointer to the pointer to the beginning of the list of links - * @param newpad The new pad to add. A copy is made when adding. - */ -void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, - AVFilterPad **pads, AVFilterLink ***links, - AVFilterPad *newpad); - -/** Inserts a new input pad for the filter. */ -static inline void avfilter_insert_inpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - avfilter_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad), - &f->input_pads, &f->inputs, p); -} - -/** Inserts a new output pad for the filter. */ -static inline void avfilter_insert_outpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - avfilter_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), - &f->output_pads, &f->outputs, p); -} - -#endif /* AVFILTER_AVFILTER_H */ diff --git a/tizen/distrib/ffmpeg/libavfilter/avfiltergraph.c b/tizen/distrib/ffmpeg/libavfilter/avfiltergraph.c deleted file mode 100644 index 9ad6536..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/avfiltergraph.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * filter graphs - * copyright (c) 2008 Vitor Sessak - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "avfilter.h" -#include "avfiltergraph.h" - -void avfilter_graph_destroy(AVFilterGraph *graph) -{ - for(; graph->filter_count > 0; graph->filter_count --) - avfilter_destroy(graph->filters[graph->filter_count - 1]); - av_freep(&graph->scale_sws_opts); - av_freep(&graph->filters); -} - -int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter) -{ - AVFilterContext **filters = av_realloc(graph->filters, - sizeof(AVFilterContext*) * (graph->filter_count+1)); - if (!filters) - return AVERROR(ENOMEM); - - graph->filters = filters; - graph->filters[graph->filter_count++] = filter; - - return 0; -} - -int avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx) -{ - AVFilterContext *filt; - int i, j; - - for (i=0; i < graph->filter_count; i++) { - filt = graph->filters[i]; - - for (j = 0; j < filt->input_count; j++) { - if (!filt->inputs[j] || !filt->inputs[j]->src) { - av_log(log_ctx, AV_LOG_ERROR, - "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n", - filt->input_pads[j].name, filt->name, filt->filter->name); - return -1; - } - } - - for (j = 0; j < filt->output_count; j++) { - if (!filt->outputs[j] || !filt->outputs[j]->dst) { - av_log(log_ctx, AV_LOG_ERROR, - "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n", - filt->output_pads[j].name, filt->name, filt->filter->name); - return -1; - } - } - } - - return 0; -} - -int avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx) -{ - AVFilterContext *filt; - int i, ret; - - for (i=0; i < graph->filter_count; i++) { - filt = graph->filters[i]; - - if (!filt->output_count) { - if ((ret = avfilter_config_links(filt))) - return ret; - } - } - - return 0; -} - -AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name) -{ - int i; - - for(i = 0; i < graph->filter_count; i ++) - if(graph->filters[i]->name && !strcmp(name, graph->filters[i]->name)) - return graph->filters[i]; - - return NULL; -} - -static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) -{ - int i, j; - int scaler_count = 0; - char inst_name[30]; - - /* ask all the sub-filters for their supported colorspaces */ - for(i = 0; i < graph->filter_count; i ++) { - if(graph->filters[i]->filter->query_formats) - graph->filters[i]->filter->query_formats(graph->filters[i]); - else - avfilter_default_query_formats(graph->filters[i]); - } - - /* go through and merge as many format lists as possible */ - for(i = 0; i < graph->filter_count; i ++) { - AVFilterContext *filter = graph->filters[i]; - - for(j = 0; j < filter->input_count; j ++) { - AVFilterLink *link = filter->inputs[j]; - if(link && link->in_formats != link->out_formats) { - if(!avfilter_merge_formats(link->in_formats, - link->out_formats)) { - AVFilterContext *scale; - char scale_args[256]; - /* couldn't merge format lists. auto-insert scale filter */ - snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d", - scaler_count++); - scale = - avfilter_open(avfilter_get_by_name("scale"),inst_name); - - snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts); - if(!scale || scale->filter->init(scale, scale_args, NULL) || - avfilter_insert_filter(link, scale, 0, 0)) { - avfilter_destroy(scale); - return -1; - } - - if (avfilter_graph_add_filter(graph, scale) < 0) - return -1; - - scale->filter->query_formats(scale); - if (((link = scale-> inputs[0]) && - !avfilter_merge_formats(link->in_formats, link->out_formats)) || - ((link = scale->outputs[0]) && - !avfilter_merge_formats(link->in_formats, link->out_formats))) { - av_log(log_ctx, AV_LOG_ERROR, - "Impossible to convert between the formats supported by the filter " - "'%s' and the filter '%s'\n", link->src->name, link->dst->name); - return -1; - } - } - } - } - } - - return 0; -} - -static void pick_format(AVFilterLink *link) -{ - if(!link || !link->in_formats) - return; - - link->in_formats->format_count = 1; - link->format = link->in_formats->formats[0]; - - avfilter_formats_unref(&link->in_formats); - avfilter_formats_unref(&link->out_formats); -} - -static void pick_formats(AVFilterGraph *graph) -{ - int i, j; - - for(i = 0; i < graph->filter_count; i ++) { - AVFilterContext *filter = graph->filters[i]; - - for(j = 0; j < filter->input_count; j ++) - pick_format(filter->inputs[j]); - for(j = 0; j < filter->output_count; j ++) - pick_format(filter->outputs[j]); - } -} - -int avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) -{ - /* find supported formats from sub-filters, and merge along links */ - if(query_formats(graph, log_ctx)) - return -1; - - /* Once everything is merged, it's possible that we'll still have - * multiple valid colorspace choices. We pick the first one. */ - pick_formats(graph); - - return 0; -} - diff --git a/tizen/distrib/ffmpeg/libavfilter/avfiltergraph.h b/tizen/distrib/ffmpeg/libavfilter/avfiltergraph.h deleted file mode 100644 index 1640795..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/avfiltergraph.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Filter graphs - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_AVFILTERGRAPH_H -#define AVFILTER_AVFILTERGRAPH_H - -#include "avfilter.h" - -typedef struct AVFilterGraph { - unsigned filter_count; - AVFilterContext **filters; - - char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters -} AVFilterGraph; - -/** - * Gets a filter instance with name name from graph. - * - * @return the pointer to the found filter instance or NULL if it - * cannot be found. - */ -AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name); - -/** - * Adds an existing filter instance to a filter graph. - * - * @param graph the filter graph - * @param filter the filter to be added - */ -int avfilter_graph_add_filter(AVFilterGraph *graphctx, AVFilterContext *filter); - -/** - * Checks for the validity of graph. - * - * A graph is considered valid if all its input and output pads are - * connected. - * - * @return 0 in case of success, a negative value otherwise - */ -int avfilter_graph_check_validity(AVFilterGraph *graphctx, AVClass *log_ctx); - -/** - * Configures all the links of graphctx. - * - * @return 0 in case of success, a negative value otherwise - */ -int avfilter_graph_config_links(AVFilterGraph *graphctx, AVClass *log_ctx); - -/** - * Configures the formats of all the links in the graph. - */ -int avfilter_graph_config_formats(AVFilterGraph *graphctx, AVClass *log_ctx); - -/** - * Frees a graph and destroys its links. - */ -void avfilter_graph_destroy(AVFilterGraph *graph); - -#endif /* AVFILTER_AVFILTERGRAPH_H */ diff --git a/tizen/distrib/ffmpeg/libavfilter/defaults.c b/tizen/distrib/ffmpeg/libavfilter/defaults.c deleted file mode 100644 index afa0f66..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/defaults.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Filter layer - default implementations - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/imgconvert.h" -#include "avfilter.h" - -/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */ -static void avfilter_default_free_video_buffer(AVFilterPic *pic) -{ - av_free(pic->data[0]); - av_free(pic); -} - -/* TODO: set the buffer's priv member to a context structure for the whole - * filter chain. This will allow for a buffer pool instead of the constant - * alloc & free cycle currently implemented. */ -AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h) -{ - AVFilterPic *pic = av_mallocz(sizeof(AVFilterPic)); - AVFilterPicRef *ref = av_mallocz(sizeof(AVFilterPicRef)); - int i, tempsize; - char *buf; - - ref->pic = pic; - ref->w = pic->w = w; - ref->h = pic->h = h; - - /* make sure the buffer gets read permission or it's useless for output */ - ref->perms = perms | AV_PERM_READ; - - pic->refcount = 1; - pic->format = link->format; - pic->free = avfilter_default_free_video_buffer; - ff_fill_linesize((AVPicture *)pic, pic->format, ref->w); - - for (i=0; i<4;i++) - pic->linesize[i] = FFALIGN(pic->linesize[i], 16); - - tempsize = ff_fill_pointer((AVPicture *)pic, NULL, pic->format, ref->h); - buf = av_malloc(tempsize); - ff_fill_pointer((AVPicture *)pic, buf, pic->format, ref->h); - - memcpy(ref->data, pic->data, sizeof(pic->data)); - memcpy(ref->linesize, pic->linesize, sizeof(pic->linesize)); - - return ref; -} - -void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - AVFilterLink *out = NULL; - - if(link->dst->output_count) - out = link->dst->outputs[0]; - - if(out) { - out->outpic = avfilter_get_video_buffer(out, AV_PERM_WRITE, out->w, out->h); - out->outpic->pts = picref->pts; - out->outpic->pos = picref->pos; - out->outpic->pixel_aspect = picref->pixel_aspect; - avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0)); - } -} - -void avfilter_default_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - AVFilterLink *out = NULL; - - if(link->dst->output_count) - out = link->dst->outputs[0]; - - if(out) - avfilter_draw_slice(out, y, h, slice_dir); -} - -void avfilter_default_end_frame(AVFilterLink *link) -{ - AVFilterLink *out = NULL; - - if(link->dst->output_count) - out = link->dst->outputs[0]; - - avfilter_unref_pic(link->cur_pic); - link->cur_pic = NULL; - - if(out) { - if(out->outpic) { - avfilter_unref_pic(out->outpic); - out->outpic = NULL; - } - avfilter_end_frame(out); - } -} - -/** - * default config_link() implementation for output video links to simplify - * the implementation of one input one output video filters */ -int avfilter_default_config_output_link(AVFilterLink *link) -{ - if(link->src->input_count && link->src->inputs[0]) { - link->w = link->src->inputs[0]->w; - link->h = link->src->inputs[0]->h; - } else { - /* XXX: any non-simple filter which would cause this branch to be taken - * really should implement its own config_props() for this link. */ - return -1; - } - - return 0; -} - -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - * - * FIXME: this will need changed for filters with a mix of pad types - * (video + audio, etc) - */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) -{ - int count = 0, i; - - for(i = 0; i < ctx->input_count; i ++) { - if(ctx->inputs[i]) { - avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats); - count ++; - } - } - for(i = 0; i < ctx->output_count; i ++) { - if(ctx->outputs[i]) { - avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats); - count ++; - } - } - - if(!count) { - av_free(formats->formats); - av_free(formats->refs); - av_free(formats); - } -} - -int avfilter_default_query_formats(AVFilterContext *ctx) -{ - avfilter_set_common_formats(ctx, avfilter_all_colorspaces()); - return 0; -} - -void avfilter_null_start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - avfilter_start_frame(link->dst->outputs[0], picref); -} - -void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir); -} - -void avfilter_null_end_frame(AVFilterLink *link) -{ - avfilter_end_frame(link->dst->outputs[0]); -} - -AVFilterPicRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h) -{ - return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); -} - diff --git a/tizen/distrib/ffmpeg/libavfilter/formats.c b/tizen/distrib/ffmpeg/libavfilter/formats.c deleted file mode 100644 index 2a9bdb0..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/formats.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Filter layer - format negotiation - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/pixdesc.h" -#include "avfilter.h" - -/** - * Add all refs from a to ret and destroy a. - */ -static void merge_ref(AVFilterFormats *ret, AVFilterFormats *a) -{ - int i; - - for(i = 0; i < a->refcount; i ++) { - ret->refs[ret->refcount] = a->refs[i]; - *ret->refs[ret->refcount++] = ret; - } - - av_free(a->refs); - av_free(a->formats); - av_free(a); -} - -AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b) -{ - AVFilterFormats *ret; - unsigned i, j, k = 0; - - ret = av_mallocz(sizeof(AVFilterFormats)); - - /* merge list of formats */ - ret->formats = av_malloc(sizeof(*ret->formats) * FFMIN(a->format_count, - b->format_count)); - for(i = 0; i < a->format_count; i ++) - for(j = 0; j < b->format_count; j ++) - if(a->formats[i] == b->formats[j]) - ret->formats[k++] = a->formats[i]; - - ret->format_count = k; - /* check that there was at least one common format */ - if(!ret->format_count) { - av_free(ret->formats); - av_free(ret); - return NULL; - } - - ret->refs = av_malloc(sizeof(AVFilterFormats**)*(a->refcount+b->refcount)); - - merge_ref(ret, a); - merge_ref(ret, b); - - return ret; -} - -AVFilterFormats *avfilter_make_format_list(const enum PixelFormat *pix_fmts) -{ - AVFilterFormats *formats; - int count; - - for (count = 0; pix_fmts[count] != PIX_FMT_NONE; count++) - ; - - formats = av_mallocz(sizeof(AVFilterFormats)); - formats->formats = av_malloc(sizeof(*formats->formats) * count); - formats->format_count = count; - memcpy(formats->formats, pix_fmts, sizeof(*formats->formats) * count); - - return formats; -} - -int avfilter_add_colorspace(AVFilterFormats **avff, enum PixelFormat pix_fmt) -{ - enum PixelFormat *pix_fmts; - - if (!(*avff) && !(*avff = av_mallocz(sizeof(AVFilterFormats)))) - return AVERROR(ENOMEM); - - pix_fmts = av_realloc((*avff)->formats, - sizeof((*avff)->formats) * ((*avff)->format_count+1)); - if (!pix_fmts) - return AVERROR(ENOMEM); - - (*avff)->formats = pix_fmts; - (*avff)->formats[(*avff)->format_count++] = pix_fmt; - return 0; -} - -AVFilterFormats *avfilter_all_colorspaces(void) -{ - AVFilterFormats *ret = NULL; - enum PixelFormat pix_fmt; - - for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) - if (!(av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL)) - avfilter_add_colorspace(&ret, pix_fmt); - - return ret; -} - -void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) -{ - *ref = f; - f->refs = av_realloc(f->refs, sizeof(AVFilterFormats**) * ++f->refcount); - f->refs[f->refcount-1] = ref; -} - -static int find_ref_index(AVFilterFormats **ref) -{ - int i; - for(i = 0; i < (*ref)->refcount; i ++) - if((*ref)->refs[i] == ref) - return i; - return -1; -} - -void avfilter_formats_unref(AVFilterFormats **ref) -{ - int idx; - - if (!*ref) - return; - - idx = find_ref_index(ref); - - if(idx >= 0) - memmove((*ref)->refs + idx, (*ref)->refs + idx+1, - sizeof(AVFilterFormats**) * ((*ref)->refcount-idx-1)); - - if(!--(*ref)->refcount) { - av_free((*ref)->formats); - av_free((*ref)->refs); - av_free(*ref); - } - *ref = NULL; -} - -void avfilter_formats_changeref(AVFilterFormats **oldref, - AVFilterFormats **newref) -{ - int idx = find_ref_index(oldref); - - if(idx >= 0) { - (*oldref)->refs[idx] = newref; - *newref = *oldref; - *oldref = NULL; - } -} - diff --git a/tizen/distrib/ffmpeg/libavfilter/graphparser.c b/tizen/distrib/ffmpeg/libavfilter/graphparser.c deleted file mode 100644 index c4a3bdf..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/graphparser.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * filter graph parser - * copyright (c) 2008 Vitor Sessak - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "graphparser.h" -#include "avfilter.h" -#include "avfiltergraph.h" -#include "parseutils.h" - -#define WHITESPACES " \n\t" - -static int link_filter(AVFilterContext *src, int srcpad, - AVFilterContext *dst, int dstpad, - AVClass *log_ctx) -{ - if(avfilter_link(src, srcpad, dst, dstpad)) { - av_log(log_ctx, AV_LOG_ERROR, - "cannot create the link %s:%d -> %s:%d\n", - src->filter->name, srcpad, dst->filter->name, dstpad); - return -1; - } - - return 0; -} - -/** - * Parse "[linkname]" - * @param name a pointer (that need to be free'd after use) to the name between - * parenthesis - */ -static char *parse_link_name(const char **buf, AVClass *log_ctx) -{ - const char *start = *buf; - char *name; - (*buf)++; - - name = av_get_token(buf, "]"); - - if(!name[0]) { - av_log(log_ctx, AV_LOG_ERROR, - "Bad (empty?) label found in the following: \"%s\".\n", start); - goto fail; - } - - if(*(*buf)++ != ']') { - av_log(log_ctx, AV_LOG_ERROR, - "Mismatched '[' found in the following: \"%s\".\n", start); - fail: - av_freep(&name); - } - - return name; -} - -static AVFilterContext *create_filter(AVFilterGraph *ctx, int index, - const char *filt_name, const char *args, - AVClass *log_ctx) -{ - AVFilterContext *filt_ctx; - - AVFilter *filt; - char inst_name[30]; - - snprintf(inst_name, sizeof(inst_name), "Parsed filter %d", index); - - filt = avfilter_get_by_name(filt_name); - - if(!filt) { - av_log(log_ctx, AV_LOG_ERROR, - "no such filter: '%s'\n", filt_name); - return NULL; - } - - filt_ctx = avfilter_open(filt, inst_name); - if(!filt_ctx) { - av_log(log_ctx, AV_LOG_ERROR, - "error creating filter '%s'\n", filt_name); - return NULL; - } - - if(avfilter_graph_add_filter(ctx, filt_ctx) < 0) { - avfilter_destroy(filt_ctx); - return NULL; - } - - if(avfilter_init_filter(filt_ctx, args, NULL)) { - av_log(log_ctx, AV_LOG_ERROR, - "error initializing filter '%s' with args '%s'\n", filt_name, args); - return NULL; - } - - return filt_ctx; -} - -/** - * Parse "filter=params" - */ -static AVFilterContext *parse_filter(const char **buf, AVFilterGraph *graph, - int index, AVClass *log_ctx) -{ - char *opts = NULL; - char *name = av_get_token(buf, "=,;[\n"); - AVFilterContext *ret; - - if(**buf == '=') { - (*buf)++; - opts = av_get_token(buf, "[],;\n"); - } - - ret = create_filter(graph, index, name, opts, log_ctx); - av_free(name); - av_free(opts); - return ret; -} - -static void free_inout(AVFilterInOut *head) -{ - while(head) { - AVFilterInOut *next = head->next; - av_free(head->name); - av_free(head); - head = next; - } -} - -static AVFilterInOut *extract_inout(const char *label, AVFilterInOut **links) -{ - AVFilterInOut *ret; - - while(*links && strcmp((*links)->name, label)) - links = &((*links)->next); - - ret = *links; - - if(ret) - *links = ret->next; - - return ret; -} - -static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element) -{ - element->next = *inouts; - *inouts = element; -} - -static int link_filter_inouts(AVFilterContext *filter, - AVFilterInOut **curr_inputs, - AVFilterInOut **open_inputs, AVClass *log_ctx) -{ - int pad = filter->input_count; - - while(pad--) { - AVFilterInOut *p = *curr_inputs; - if(!p) { - av_log(log_ctx, AV_LOG_ERROR, - "Not enough inputs specified for the \"%s\" filter.\n", - filter->filter->name); - return -1; - } - - *curr_inputs = (*curr_inputs)->next; - - if(p->filter) { - if(link_filter(p->filter, p->pad_idx, filter, pad, log_ctx)) - return -1; - av_free(p->name); - av_free(p); - } else { - p->filter = filter; - p->pad_idx = pad; - insert_inout(open_inputs, p); - } - } - - if(*curr_inputs) { - av_log(log_ctx, AV_LOG_ERROR, - "Too many inputs specified for the \"%s\" filter.\n", - filter->filter->name); - return -1; - } - - pad = filter->output_count; - while(pad--) { - AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut)); - currlinkn->filter = filter; - currlinkn->pad_idx = pad; - insert_inout(curr_inputs, currlinkn); - } - - return 0; -} - -static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, - AVFilterInOut **open_outputs, AVClass *log_ctx) -{ - int pad = 0; - - while(**buf == '[') { - char *name = parse_link_name(buf, log_ctx); - AVFilterInOut *match; - - if(!name) - return -1; - - /* First check if the label is not in the open_outputs list */ - match = extract_inout(name, open_outputs); - - if(match) { - av_free(name); - } else { - /* Not in the list, so add it as an input */ - match = av_mallocz(sizeof(AVFilterInOut)); - match->name = name; - match->pad_idx = pad; - } - - insert_inout(curr_inputs, match); - - *buf += strspn(*buf, WHITESPACES); - pad++; - } - - return pad; -} - -static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, - AVFilterInOut **open_inputs, - AVFilterInOut **open_outputs, AVClass *log_ctx) -{ - int pad = 0; - - while(**buf == '[') { - char *name = parse_link_name(buf, log_ctx); - AVFilterInOut *match; - - AVFilterInOut *input = *curr_inputs; - *curr_inputs = (*curr_inputs)->next; - - if(!name) - return -1; - - /* First check if the label is not in the open_inputs list */ - match = extract_inout(name, open_inputs); - - if(match) { - if(link_filter(input->filter, input->pad_idx, - match->filter, match->pad_idx, log_ctx) < 0) - return -1; - av_free(match->name); - av_free(name); - av_free(match); - av_free(input); - } else { - /* Not in the list, so add the first input as a open_output */ - input->name = name; - insert_inout(open_outputs, input); - } - *buf += strspn(*buf, WHITESPACES); - pad++; - } - - return pad; -} - -int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, - AVFilterInOut *open_inputs, - AVFilterInOut *open_outputs, AVClass *log_ctx) -{ - int index = 0; - char chr = 0; - - AVFilterInOut *curr_inputs = NULL; - - do { - AVFilterContext *filter; - filters += strspn(filters, WHITESPACES); - - if(parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx) < 0) - goto fail; - - filter = parse_filter(&filters, graph, index, log_ctx); - - if(!filter) - goto fail; - - if(filter->input_count == 1 && !curr_inputs && !index) { - /* First input can be omitted if it is "[in]" */ - const char *tmp = "[in]"; - if(parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx) < 0) - goto fail; - } - - if(link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx) < 0) - goto fail; - - if(parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs, - log_ctx) < 0) - goto fail; - - filters += strspn(filters, WHITESPACES); - chr = *filters++; - - if(chr == ';' && curr_inputs) { - av_log(log_ctx, AV_LOG_ERROR, - "Could not find a output to link when parsing \"%s\"\n", - filters - 1); - goto fail; - } - index++; - } while(chr == ',' || chr == ';'); - - if (chr) { - av_log(log_ctx, AV_LOG_ERROR, - "Unable to parse graph description substring: \"%s\"\n", - filters - 1); - goto fail; - } - - if(open_inputs && !strcmp(open_inputs->name, "out") && curr_inputs) { - /* Last output can be omitted if it is "[out]" */ - const char *tmp = "[out]"; - if(parse_outputs(&tmp, &curr_inputs, &open_inputs, - &open_outputs, log_ctx) < 0) - goto fail; - } - - return 0; - - fail: - avfilter_graph_destroy(graph); - free_inout(open_inputs); - free_inout(open_outputs); - free_inout(curr_inputs); - return -1; -} diff --git a/tizen/distrib/ffmpeg/libavfilter/graphparser.h b/tizen/distrib/ffmpeg/libavfilter/graphparser.h deleted file mode 100644 index e69f295..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/graphparser.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Filter graph parser - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_GRAPHPARSER_H -#define AVFILTER_GRAPHPARSER_H - -#include "avfilter.h" -#include "avfiltergraph.h" - -/** - * A linked-list of the inputs/outputs of the filter chain. - */ -typedef struct AVFilterInOut { - char *name; - AVFilterContext *filter; - int pad_idx; - - struct AVFilterInOut *next; -} AVFilterInOut; - -/** - * Adds a graph described by a string to a graph. - * - * @param graph the filter graph where to link the parsed graph context - * @param filters string to be parsed - * @param inputs linked list to the inputs of the graph - * @param outputs linked list to the outputs of the graph - * @return zero on success, -1 on error - */ -int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, - AVFilterInOut *inputs, AVFilterInOut *outputs, - AVClass *log_ctx); - -#endif /* AVFILTER_GRAPHPARSER_H */ diff --git a/tizen/distrib/ffmpeg/libavfilter/libavfilter.v b/tizen/distrib/ffmpeg/libavfilter/libavfilter.v deleted file mode 100644 index 83e8887..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/libavfilter.v +++ /dev/null @@ -1,4 +0,0 @@ -LIBAVFILTER_$MAJOR { - global: avfilter_*; av_*; - local: *; -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/parseutils.c b/tizen/distrib/ffmpeg/libavfilter/parseutils.c deleted file mode 100644 index 222ac73..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/parseutils.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * copyright (c) 2009 Stefano Sabatini - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * parsing utils - */ - -#include -#include "libavutil/avutil.h" -#include "libavutil/random_seed.h" -#include "parseutils.h" - -#define WHITESPACES " \n\t" - -char *av_get_token(const char **buf, const char *term) -{ - char *out = av_malloc(strlen(*buf) + 1); - char *ret= out, *end= out; - const char *p = *buf; - p += strspn(p, WHITESPACES); - - while(*p && !strspn(p, term)) { - char c = *p++; - if(c == '\\' && *p){ - *out++ = *p++; - end= out; - }else if(c == '\''){ - while(*p && *p != '\'') - *out++ = *p++; - if(*p){ - p++; - end= out; - } - }else{ - *out++ = c; - } - } - - do{ - *out-- = 0; - }while(out >= end && strspn(out, WHITESPACES)); - - *buf = p; - - return ret; -} - -typedef struct { - const char *name; ///< a string representing the name of the color - uint8_t rgba_color[4]; ///< RGBA values for the color -} ColorEntry; - -static ColorEntry color_table[] = { - { "AliceBlue", { 0xF0, 0xF8, 0xFF } }, - { "AntiqueWhite", { 0xFA, 0xEB, 0xD7 } }, - { "Aqua", { 0x00, 0xFF, 0xFF } }, - { "Aquamarine", { 0x7F, 0xFF, 0xD4 } }, - { "Azure", { 0xF0, 0xFF, 0xFF } }, - { "Beige", { 0xF5, 0xF5, 0xDC } }, - { "Bisque", { 0xFF, 0xE4, 0xC4 } }, - { "Black", { 0x00, 0x00, 0x00 } }, - { "BlanchedAlmond", { 0xFF, 0xEB, 0xCD } }, - { "Blue", { 0x00, 0x00, 0xFF } }, - { "BlueViolet", { 0x8A, 0x2B, 0xE2 } }, - { "Brown", { 0xA5, 0x2A, 0x2A } }, - { "BurlyWood", { 0xDE, 0xB8, 0x87 } }, - { "CadetBlue", { 0x5F, 0x9E, 0xA0 } }, - { "Chartreuse", { 0x7F, 0xFF, 0x00 } }, - { "Chocolate", { 0xD2, 0x69, 0x1E } }, - { "Coral", { 0xFF, 0x7F, 0x50 } }, - { "CornflowerBlue", { 0x64, 0x95, 0xED } }, - { "Cornsilk", { 0xFF, 0xF8, 0xDC } }, - { "Crimson", { 0xDC, 0x14, 0x3C } }, - { "Cyan", { 0x00, 0xFF, 0xFF } }, - { "DarkBlue", { 0x00, 0x00, 0x8B } }, - { "DarkCyan", { 0x00, 0x8B, 0x8B } }, - { "DarkGoldenRod", { 0xB8, 0x86, 0x0B } }, - { "DarkGray", { 0xA9, 0xA9, 0xA9 } }, - { "DarkGreen", { 0x00, 0x64, 0x00 } }, - { "DarkKhaki", { 0xBD, 0xB7, 0x6B } }, - { "DarkMagenta", { 0x8B, 0x00, 0x8B } }, - { "DarkOliveGreen", { 0x55, 0x6B, 0x2F } }, - { "Darkorange", { 0xFF, 0x8C, 0x00 } }, - { "DarkOrchid", { 0x99, 0x32, 0xCC } }, - { "DarkRed", { 0x8B, 0x00, 0x00 } }, - { "DarkSalmon", { 0xE9, 0x96, 0x7A } }, - { "DarkSeaGreen", { 0x8F, 0xBC, 0x8F } }, - { "DarkSlateBlue", { 0x48, 0x3D, 0x8B } }, - { "DarkSlateGray", { 0x2F, 0x4F, 0x4F } }, - { "DarkTurquoise", { 0x00, 0xCE, 0xD1 } }, - { "DarkViolet", { 0x94, 0x00, 0xD3 } }, - { "DeepPink", { 0xFF, 0x14, 0x93 } }, - { "DeepSkyBlue", { 0x00, 0xBF, 0xFF } }, - { "DimGray", { 0x69, 0x69, 0x69 } }, - { "DodgerBlue", { 0x1E, 0x90, 0xFF } }, - { "FireBrick", { 0xB2, 0x22, 0x22 } }, - { "FloralWhite", { 0xFF, 0xFA, 0xF0 } }, - { "ForestGreen", { 0x22, 0x8B, 0x22 } }, - { "Fuchsia", { 0xFF, 0x00, 0xFF } }, - { "Gainsboro", { 0xDC, 0xDC, 0xDC } }, - { "GhostWhite", { 0xF8, 0xF8, 0xFF } }, - { "Gold", { 0xFF, 0xD7, 0x00 } }, - { "GoldenRod", { 0xDA, 0xA5, 0x20 } }, - { "Gray", { 0x80, 0x80, 0x80 } }, - { "Green", { 0x00, 0x80, 0x00 } }, - { "GreenYellow", { 0xAD, 0xFF, 0x2F } }, - { "HoneyDew", { 0xF0, 0xFF, 0xF0 } }, - { "HotPink", { 0xFF, 0x69, 0xB4 } }, - { "IndianRed", { 0xCD, 0x5C, 0x5C } }, - { "Indigo", { 0x4B, 0x00, 0x82 } }, - { "Ivory", { 0xFF, 0xFF, 0xF0 } }, - { "Khaki", { 0xF0, 0xE6, 0x8C } }, - { "Lavender", { 0xE6, 0xE6, 0xFA } }, - { "LavenderBlush", { 0xFF, 0xF0, 0xF5 } }, - { "LawnGreen", { 0x7C, 0xFC, 0x00 } }, - { "LemonChiffon", { 0xFF, 0xFA, 0xCD } }, - { "LightBlue", { 0xAD, 0xD8, 0xE6 } }, - { "LightCoral", { 0xF0, 0x80, 0x80 } }, - { "LightCyan", { 0xE0, 0xFF, 0xFF } }, - { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } }, - { "LightGrey", { 0xD3, 0xD3, 0xD3 } }, - { "LightGreen", { 0x90, 0xEE, 0x90 } }, - { "LightPink", { 0xFF, 0xB6, 0xC1 } }, - { "LightSalmon", { 0xFF, 0xA0, 0x7A } }, - { "LightSeaGreen", { 0x20, 0xB2, 0xAA } }, - { "LightSkyBlue", { 0x87, 0xCE, 0xFA } }, - { "LightSlateGray", { 0x77, 0x88, 0x99 } }, - { "LightSteelBlue", { 0xB0, 0xC4, 0xDE } }, - { "LightYellow", { 0xFF, 0xFF, 0xE0 } }, - { "Lime", { 0x00, 0xFF, 0x00 } }, - { "LimeGreen", { 0x32, 0xCD, 0x32 } }, - { "Linen", { 0xFA, 0xF0, 0xE6 } }, - { "Magenta", { 0xFF, 0x00, 0xFF } }, - { "Maroon", { 0x80, 0x00, 0x00 } }, - { "MediumAquaMarine", { 0x66, 0xCD, 0xAA } }, - { "MediumBlue", { 0x00, 0x00, 0xCD } }, - { "MediumOrchid", { 0xBA, 0x55, 0xD3 } }, - { "MediumPurple", { 0x93, 0x70, 0xD8 } }, - { "MediumSeaGreen", { 0x3C, 0xB3, 0x71 } }, - { "MediumSlateBlue", { 0x7B, 0x68, 0xEE } }, - { "MediumSpringGreen", { 0x00, 0xFA, 0x9A } }, - { "MediumTurquoise", { 0x48, 0xD1, 0xCC } }, - { "MediumVioletRed", { 0xC7, 0x15, 0x85 } }, - { "MidnightBlue", { 0x19, 0x19, 0x70 } }, - { "MintCream", { 0xF5, 0xFF, 0xFA } }, - { "MistyRose", { 0xFF, 0xE4, 0xE1 } }, - { "Moccasin", { 0xFF, 0xE4, 0xB5 } }, - { "NavajoWhite", { 0xFF, 0xDE, 0xAD } }, - { "Navy", { 0x00, 0x00, 0x80 } }, - { "OldLace", { 0xFD, 0xF5, 0xE6 } }, - { "Olive", { 0x80, 0x80, 0x00 } }, - { "OliveDrab", { 0x6B, 0x8E, 0x23 } }, - { "Orange", { 0xFF, 0xA5, 0x00 } }, - { "OrangeRed", { 0xFF, 0x45, 0x00 } }, - { "Orchid", { 0xDA, 0x70, 0xD6 } }, - { "PaleGoldenRod", { 0xEE, 0xE8, 0xAA } }, - { "PaleGreen", { 0x98, 0xFB, 0x98 } }, - { "PaleTurquoise", { 0xAF, 0xEE, 0xEE } }, - { "PaleVioletRed", { 0xD8, 0x70, 0x93 } }, - { "PapayaWhip", { 0xFF, 0xEF, 0xD5 } }, - { "PeachPuff", { 0xFF, 0xDA, 0xB9 } }, - { "Peru", { 0xCD, 0x85, 0x3F } }, - { "Pink", { 0xFF, 0xC0, 0xCB } }, - { "Plum", { 0xDD, 0xA0, 0xDD } }, - { "PowderBlue", { 0xB0, 0xE0, 0xE6 } }, - { "Purple", { 0x80, 0x00, 0x80 } }, - { "Red", { 0xFF, 0x00, 0x00 } }, - { "RosyBrown", { 0xBC, 0x8F, 0x8F } }, - { "RoyalBlue", { 0x41, 0x69, 0xE1 } }, - { "SaddleBrown", { 0x8B, 0x45, 0x13 } }, - { "Salmon", { 0xFA, 0x80, 0x72 } }, - { "SandyBrown", { 0xF4, 0xA4, 0x60 } }, - { "SeaGreen", { 0x2E, 0x8B, 0x57 } }, - { "SeaShell", { 0xFF, 0xF5, 0xEE } }, - { "Sienna", { 0xA0, 0x52, 0x2D } }, - { "Silver", { 0xC0, 0xC0, 0xC0 } }, - { "SkyBlue", { 0x87, 0xCE, 0xEB } }, - { "SlateBlue", { 0x6A, 0x5A, 0xCD } }, - { "SlateGray", { 0x70, 0x80, 0x90 } }, - { "Snow", { 0xFF, 0xFA, 0xFA } }, - { "SpringGreen", { 0x00, 0xFF, 0x7F } }, - { "SteelBlue", { 0x46, 0x82, 0xB4 } }, - { "Tan", { 0xD2, 0xB4, 0x8C } }, - { "Teal", { 0x00, 0x80, 0x80 } }, - { "Thistle", { 0xD8, 0xBF, 0xD8 } }, - { "Tomato", { 0xFF, 0x63, 0x47 } }, - { "Turquoise", { 0x40, 0xE0, 0xD0 } }, - { "Violet", { 0xEE, 0x82, 0xEE } }, - { "Wheat", { 0xF5, 0xDE, 0xB3 } }, - { "White", { 0xFF, 0xFF, 0xFF } }, - { "WhiteSmoke", { 0xF5, 0xF5, 0xF5 } }, - { "Yellow", { 0xFF, 0xFF, 0x00 } }, - { "YellowGreen", { 0x9A, 0xCD, 0x32 } }, -}; - -static int color_table_compare(const void *lhs, const void *rhs) -{ - return strcasecmp(lhs, ((const ColorEntry *)rhs)->name); -} - -int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx) -{ - if (!strcasecmp(color_string, "random") || !strcasecmp(color_string, "bikeshed")) { - int rgba = ff_random_get_seed(); - rgba_color[0] = rgba >> 24; - rgba_color[1] = rgba >> 16; - rgba_color[2] = rgba >> 8; - rgba_color[3] = rgba; - } else - if (!strncmp(color_string, "0x", 2)) { - char *tail; - int len = strlen(color_string); - unsigned int rgba = strtoul(color_string, &tail, 16); - - if (*tail || (len != 8 && len != 10)) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string); - return -1; - } - if (len == 10) { - rgba_color[3] = rgba; - rgba >>= 8; - } - rgba_color[0] = rgba >> 16; - rgba_color[1] = rgba >> 8; - rgba_color[2] = rgba; - } else { - const ColorEntry *entry = bsearch(color_string, - color_table, - FF_ARRAY_ELEMS(color_table), - sizeof(ColorEntry), - color_table_compare); - if (!entry) { - av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string); - return -1; - } - memcpy(rgba_color, entry->rgba_color, 4); - } - - return 0; -} - -/** - * Stores the value in the field in ctx that is named like key. - * ctx must be an AVClass context, storing is done using AVOptions. - * - * @param buf the string to parse, buf will be updated to point at the - * separator just after the parsed key/value pair - * @param key_val_sep a 0-terminated list of characters used to - * separate key from value - * @param pairs_sep a 0-terminated list of characters used to separate - * two pairs from each other - * @return 0 if the key/value pair has been successfully parsed and - * set, or a negative value corresponding to an AVERROR code in case - * of error: - * AVERROR(EINVAL) if the key/value pair cannot be parsed, - * the error code issued by av_set_string3() if the key/value pair - * cannot be set - */ -static int parse_key_value_pair(void *ctx, const char **buf, - const char *key_val_sep, const char *pairs_sep) -{ - char *key = av_get_token(buf, key_val_sep); - char *val; - int ret; - - if (*key && strspn(*buf, key_val_sep)) { - (*buf)++; - val = av_get_token(buf, pairs_sep); - } else { - av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); - av_free(key); - return AVERROR(EINVAL); - } - - av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key); - - ret = av_set_string3(ctx, key, val, 1, NULL); - if (ret == AVERROR(ENOENT)) - av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); - - av_free(key); - av_free(val); - return ret; -} - -int av_set_options_string(void *ctx, const char *opts, - const char *key_val_sep, const char *pairs_sep) -{ - int ret, count = 0; - - while (*opts) { - if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) - return ret; - count++; - - if (*opts) - opts++; - } - - return count; -} - -#ifdef TEST - -#undef printf - -typedef struct TestContext -{ - const AVClass *class; - int num; - int toggle; - char *string; - int flags; - AVRational rational; -} TestContext; - -#define OFFSET(x) offsetof(TestContext, x) - -#define TEST_FLAG_COOL 01 -#define TEST_FLAG_LAME 02 -#define TEST_FLAG_MU 04 - -static const AVOption test_options[]= { -{"num", "set num", OFFSET(num), FF_OPT_TYPE_INT, 0, 0, 100 }, -{"toggle", "set toggle", OFFSET(toggle), FF_OPT_TYPE_INT, 0, 0, 1 }, -{"rational", "set rational", OFFSET(rational), FF_OPT_TYPE_RATIONAL, 0, 0, 10 }, -{"string", "set string", OFFSET(string), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, -{"flags", "set flags", OFFSET(flags), FF_OPT_TYPE_FLAGS, 0, 0, INT_MAX, 0, "flags" }, -{"cool", "set cool flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_COOL, INT_MIN, INT_MAX, 0, "flags" }, -{"lame", "set lame flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_LAME, INT_MIN, INT_MAX, 0, "flags" }, -{"mu", "set mu flag ", 0, FF_OPT_TYPE_CONST, TEST_FLAG_MU, INT_MIN, INT_MAX, 0, "flags" }, -{NULL}, -}; - -static const char *test_get_name(void *ctx) -{ - return "test"; -} - -static const AVClass test_class = { - "TestContext", - test_get_name, - test_options -}; - -int main(void) -{ - int i; - - const char *strings[] = { - "''", - "", - ":", - "\\", - "'", - " '' :", - " '' '' :", - "foo '' :", - "'foo'", - "foo ", - "foo\\", - "foo': blah:blah", - "foo\\: blah:blah", - "foo\'", - "'foo : ' :blahblah", - "\\ :blah", - " foo", - " foo ", - " foo \\ ", - "foo ':blah", - " foo bar : blahblah", - "\\f\\o\\o", - "'foo : \\ \\ ' : blahblah", - "'\\fo\\o:': blahblah", - "\\'fo\\o\\:': foo ' :blahblah" - }; - - for (i=0; i < FF_ARRAY_ELEMS(strings); i++) { - const char *p= strings[i]; - printf("|%s|", p); - printf(" -> |%s|", av_get_token(&p, ":")); - printf(" + |%s|\n", p); - } - - printf("\nTesting av_parse_color()\n"); - { - uint8_t rgba[4]; - const char *color_names[] = { - "bikeshed", - "RaNdOm", - "foo", - "red", - "Red ", - "RED", - "Violet", - "Yellow", - "Red", - "0x000000", - "0x0000000", - "0xff000000", - "0x3e34ff", - "0x3e34ffaa", - "0xffXXee", - "0xfoobar", - "0xffffeeeeeeee", - }; - - av_log_set_level(AV_LOG_DEBUG); - - for (int i = 0; i < FF_ARRAY_ELEMS(color_names); i++) { - if (av_parse_color(rgba, color_names[i], NULL) >= 0) - printf("%s -> R(%d) G(%d) B(%d) A(%d)\n", color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]); - } - } - - printf("\nTesting av_set_options_string()\n"); - { - TestContext test_ctx; - const char *options[] = { - "", - ":", - "=", - "foo=:", - ":=foo", - "=foo", - "foo=", - "foo", - "foo=val", - "foo==val", - "toggle=:", - "string=:", - "toggle=1 : foo", - "toggle=100", - "toggle==1", - "flags=+mu-lame : num=42: toggle=0", - "num=42 : string=blahblah", - "rational=0 : rational=1/2 : rational=1/-1", - "rational=-1/0", - }; - - test_ctx.class = &test_class; - av_opt_set_defaults2(&test_ctx, 0, 0); - test_ctx.string = av_strdup("default"); - - av_log_set_level(AV_LOG_DEBUG); - - for (i=0; i < FF_ARRAY_ELEMS(options); i++) { - av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); - if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0) - av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); - printf("\n"); - } - } - - return 0; -} - -#endif diff --git a/tizen/distrib/ffmpeg/libavfilter/parseutils.h b/tizen/distrib/ffmpeg/libavfilter/parseutils.h deleted file mode 100644 index b5b494e..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/parseutils.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * copyright (c) 2009 Stefano Sabatini - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * parsing utils - */ - -#ifndef AVFILTER_PARSEUTILS_H -#define AVFILTER_PARSEUTILS_H - -#include "libavcodec/opt.h" - -/** - * Unescapes the given string until a non escaped terminating char, - * and returns the token corresponding to the unescaped string. - * - * The normal \ and ' escaping is supported. Leading and trailing - * whitespaces are removed. - * - * @param term a 0-terminated list of terminating chars - * @param buf the buffer to parse, buf will be updated to point to the - * terminating char - * @return the malloced unescaped string, which must be av_freed by - * the user - */ -char *av_get_token(const char **buf, const char *term); - -/** - * Puts the RGBA values that correspond to color_string in rgba_color. - * - * @param color_string a string specifying a color. It can be the name of - * a color (case insensitive match) or a 0xRRGGBB[AA] sequence. - * The string "random" will result in a random color. - * @return >= 0 in case of success, a negative value in case of - * failure (for example if color_string cannot be parsed). - */ -int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx); - -/** - * Parses the key/value pairs list in opts. For each key/value pair - * found, stores the value in the field in ctx that is named like the - * key. ctx must be an AVClass context, storing is done using - * AVOptions. - * - * @param key_val_sep a 0-terminated list of characters used to - * separate key from value - * @param pairs_sep a 0-terminated list of characters used to separate - * two pairs from each other - * @return the number of successfully set key/value pairs, or a negative - * value corresponding to an AVERROR code in case of error: - * AVERROR(EINVAL) if opts cannot be parsed, - * the error code issued by av_set_string3() if a key/value pair - * cannot be set - */ -int av_set_options_string(void *ctx, const char *opts, - const char *key_val_sep, const char *pairs_sep); - -#endif /* AVFILTER_PARSEUTILS_H */ diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_aspect.c b/tizen/distrib/ffmpeg/libavfilter/vf_aspect.c deleted file mode 100644 index 2627722..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_aspect.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Aspect ratio modification video filter - * Copyright (c) 2010 Bobby Bingham - - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * aspect ratio modification video filter - */ - -#include "avfilter.h" - -typedef struct { - AVRational aspect; -} AspectContext; - -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) -{ - AspectContext *aspect = ctx->priv; - double ratio; - int64_t gcd; - - if(args) { - if(sscanf(args, "%d:%d", &aspect->aspect.num, &aspect->aspect.den) < 2) { - if(sscanf(args, "%lf", &ratio) < 1) - return -1; - aspect->aspect = av_d2q(ratio, 100); - } else { - gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den)); - if(gcd) { - aspect->aspect.num /= gcd; - aspect->aspect.den /= gcd; - } - } - } - - if(aspect->aspect.den == 0) - aspect->aspect = (AVRational) {0, 1}; - - return 0; -} - -static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - AspectContext *aspect = link->dst->priv; - - picref->pixel_aspect = aspect->aspect; - avfilter_start_frame(link->dst->outputs[0], picref); -} - -#if CONFIG_ASPECT_FILTER -/* for aspect filter, convert from frame aspect ratio to pixel aspect ratio */ -static int frameaspect_config_props(AVFilterLink *inlink) -{ - AspectContext *aspect = inlink->dst->priv; - - av_reduce(&aspect->aspect.num, &aspect->aspect.den, - aspect->aspect.num * inlink->h, - aspect->aspect.den * inlink->w, 100); - - return 0; -} - -AVFilter avfilter_vf_aspect = { - .name = "aspect", - .description = NULL_IF_CONFIG_SMALL("Set the frame aspect ratio."), - - .init = init, - - .priv_size = sizeof(AspectContext), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = frameaspect_config_props, - .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = start_frame, - .end_frame = avfilter_null_end_frame }, - { .name = NULL}}, - - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, -}; -#endif /* CONFIG_ASPECT_FILTER */ - -#if CONFIG_PIXELASPECT_FILTER -AVFilter avfilter_vf_pixelaspect = { - .name = "pixelaspect", - .description = NULL_IF_CONFIG_SMALL("Set the pixel aspect ratio."), - - .init = init, - - .priv_size = sizeof(AspectContext), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = start_frame, - .end_frame = avfilter_null_end_frame }, - { .name = NULL}}, - - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, -}; -#endif /* CONFIG_PIXELASPECT_FILTER */ - diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_crop.c b/tizen/distrib/ffmpeg/libavfilter/vf_crop.c deleted file mode 100644 index 204adcf..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_crop.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video crop filter - */ - -#include "avfilter.h" -#include "libavutil/pixdesc.h" - -typedef struct { - int x; ///< x offset of the non-cropped area with respect to the input area - int y; ///< y offset of the non-cropped area with respect to the input area - int w; ///< width of the cropped area - int h; ///< height of the cropped area - - int bpp; ///< bits per pixel - int hsub, vsub; ///< chroma subsampling -} CropContext; - -static int query_formats(AVFilterContext *ctx) -{ - static const enum PixelFormat pix_fmts[] = { - PIX_FMT_RGB48BE, PIX_FMT_RGB48LE, - PIX_FMT_ARGB, PIX_FMT_RGBA, - PIX_FMT_ABGR, PIX_FMT_BGRA, - PIX_FMT_RGB24, PIX_FMT_BGR24, - PIX_FMT_RGB565BE, PIX_FMT_RGB565LE, - PIX_FMT_RGB555BE, PIX_FMT_RGB555LE, - PIX_FMT_BGR565BE, PIX_FMT_BGR565LE, - PIX_FMT_BGR555BE, PIX_FMT_BGR555LE, - PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE, - PIX_FMT_YUV420P16LE, PIX_FMT_YUV420P16BE, - PIX_FMT_YUV422P16LE, PIX_FMT_YUV422P16BE, - PIX_FMT_YUV444P16LE, PIX_FMT_YUV444P16BE, - PIX_FMT_YUV444P, PIX_FMT_YUV422P, - PIX_FMT_YUV420P, PIX_FMT_YUV411P, - PIX_FMT_YUV410P, PIX_FMT_YUV440P, - PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, - PIX_FMT_YUVJ420P, PIX_FMT_YUVJ440P, - PIX_FMT_YUVA420P, - PIX_FMT_RGB8, PIX_FMT_BGR8, - PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, - PIX_FMT_PAL8, PIX_FMT_GRAY8, - PIX_FMT_NONE - }; - - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); - - return 0; -} - -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) -{ - CropContext *crop = ctx->priv; - - if (args) - sscanf(args, "%d:%d:%d:%d", &crop->x, &crop->y, &crop->w, &crop->h); - - return 0; -} - -static int config_input(AVFilterLink *link) -{ - AVFilterContext *ctx = link->dst; - CropContext *crop = ctx->priv; - - switch (link->format) { - case PIX_FMT_RGB48BE: - case PIX_FMT_RGB48LE: - crop->bpp = 48; - break; - case PIX_FMT_ARGB: - case PIX_FMT_RGBA: - case PIX_FMT_ABGR: - case PIX_FMT_BGRA: - crop->bpp = 32; - break; - case PIX_FMT_RGB24: - case PIX_FMT_BGR24: - crop->bpp = 24; - break; - case PIX_FMT_RGB565BE: - case PIX_FMT_RGB565LE: - case PIX_FMT_RGB555BE: - case PIX_FMT_RGB555LE: - case PIX_FMT_BGR565BE: - case PIX_FMT_BGR565LE: - case PIX_FMT_BGR555BE: - case PIX_FMT_BGR555LE: - case PIX_FMT_GRAY16BE: - case PIX_FMT_GRAY16LE: - case PIX_FMT_YUV420P16LE: - case PIX_FMT_YUV420P16BE: - case PIX_FMT_YUV422P16LE: - case PIX_FMT_YUV422P16BE: - case PIX_FMT_YUV444P16LE: - case PIX_FMT_YUV444P16BE: - crop->bpp = 16; - break; - default: - crop->bpp = 8; - } - - avcodec_get_chroma_sub_sample(link->format, &crop->hsub, &crop->vsub); - - if (crop->w == 0) - crop->w = link->w - crop->x; - if (crop->h == 0) - crop->h = link->h - crop->y; - - crop->x &= ~((1 << crop->hsub) - 1); - crop->y &= ~((1 << crop->vsub) - 1); - - av_log(link->dst, AV_LOG_INFO, "x:%d y:%d w:%d h:%d\n", - crop->x, crop->y, crop->w, crop->h); - - if (crop->x < 0 || crop->y < 0 || - crop->w <= 0 || crop->h <= 0 || - (unsigned)crop->x + (unsigned)crop->w > link->w || - (unsigned)crop->y + (unsigned)crop->h > link->h) { - av_log(ctx, AV_LOG_ERROR, - "Output area %d:%d:%d:%d not within the input area 0:0:%d:%d or zero-sized\n", - crop->x, crop->y, crop->w, crop->h, link->w, link->h); - return -1; - } - - return 0; -} - -static int config_output(AVFilterLink *link) -{ - CropContext *crop = link->src->priv; - - link->w = crop->w; - link->h = crop->h; - - return 0; -} - -static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - CropContext *crop = link->dst->priv; - AVFilterPicRef *ref2 = avfilter_ref_pic(picref, ~0); - int i; - - ref2->w = crop->w; - ref2->h = crop->h; - - ref2->data[0] += crop->y * ref2->linesize[0]; - ref2->data[0] += (crop->x * crop->bpp) >> 3; - - if (!(av_pix_fmt_descriptors[link->format].flags & PIX_FMT_PAL)) { - for (i = 1; i < 3; i ++) { - if (ref2->data[i]) { - ref2->data[i] += (crop->y >> crop->vsub) * ref2->linesize[i]; - ref2->data[i] += ((crop->x * crop->bpp) >> 3) >> crop->hsub; - } - } - } - - /* alpha plane */ - if (ref2->data[3]) { - ref2->data[3] += crop->y * ref2->linesize[3]; - ref2->data[3] += (crop->x * crop->bpp) >> 3; - } - - avfilter_start_frame(link->dst->outputs[0], ref2); -} - -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - AVFilterContext *ctx = link->dst; - CropContext *crop = ctx->priv; - - if (y >= crop->y + crop->h || y + h <= crop->y) - return; - - if (y < crop->y) { - h -= crop->y - y; - y = crop->y; - } - if (y + h > crop->y + crop->h) - h = crop->y + crop->h - y; - - avfilter_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir); -} - -AVFilter avfilter_vf_crop = { - .name = "crop", - .description = NULL_IF_CONFIG_SMALL("Crop the input video to x:y:width:height."), - - .priv_size = sizeof(CropContext), - - .query_formats = query_formats, - .init = init, - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .start_frame = start_frame, - .draw_slice = draw_slice, - .get_video_buffer = avfilter_null_get_video_buffer, - .config_props = config_input, }, - { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, }, - { .name = NULL}}, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_format.c b/tizen/distrib/ffmpeg/libavfilter/vf_format.c deleted file mode 100644 index 36b7d33..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_format.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * format and noformat video filters - */ - -#include "libavutil/pixdesc.h" -#include "avfilter.h" - -typedef struct { - /** - * List of flags telling if a given image format has been listed - * as argument to the filter. - */ - int listed_pix_fmt_flags[PIX_FMT_NB]; -} FormatContext; - -#define PIX_FMT_NAME_MAXSIZE 32 - -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) -{ - FormatContext *format = ctx->priv; - const char *cur, *sep; - char pix_fmt_name[PIX_FMT_NAME_MAXSIZE]; - int pix_fmt_name_len; - enum PixelFormat pix_fmt; - - /* parse the list of formats */ - for (cur = args; cur; cur = sep ? sep+1 : NULL) { - if (!(sep = strchr(cur, ':'))) - pix_fmt_name_len = strlen(cur); - else - pix_fmt_name_len = sep - cur; - if (pix_fmt_name_len >= PIX_FMT_NAME_MAXSIZE) { - av_log(ctx, AV_LOG_ERROR, "Format name too long\n"); - return -1; - } - - memcpy(pix_fmt_name, cur, pix_fmt_name_len); - pix_fmt_name[pix_fmt_name_len] = 0; - pix_fmt = av_get_pix_fmt(pix_fmt_name); - - if (pix_fmt == PIX_FMT_NONE) { - av_log(ctx, AV_LOG_ERROR, "Unknown pixel format: %s\n", pix_fmt_name); - return -1; - } - - format->listed_pix_fmt_flags[pix_fmt] = 1; - } - - return 0; -} - -static AVFilterFormats *make_format_list(FormatContext *format, int flag) -{ - AVFilterFormats *formats; - enum PixelFormat pix_fmt; - - formats = av_mallocz(sizeof(AVFilterFormats)); - formats->formats = av_malloc(sizeof(enum PixelFormat) * PIX_FMT_NB); - - for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) - if (format->listed_pix_fmt_flags[pix_fmt] == flag) - formats->formats[formats->format_count++] = pix_fmt; - - return formats; -} - -#if CONFIG_FORMAT_FILTER -static int query_formats_format(AVFilterContext *ctx) -{ - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1)); - return 0; -} - -AVFilter avfilter_vf_format = { - .name = "format", - .description = "Convert the input video to one of the specified pixel formats.", - - .init = init, - - .query_formats = query_formats_format, - - .priv_size = sizeof(FormatContext), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer= avfilter_null_get_video_buffer, - .start_frame = avfilter_null_start_frame, - .draw_slice = avfilter_null_draw_slice, - .end_frame = avfilter_null_end_frame, }, - { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO }, - { .name = NULL}}, -}; -#endif /* CONFIG_FORMAT_FILTER */ - -#if CONFIG_NOFORMAT_FILTER -static int query_formats_noformat(AVFilterContext *ctx) -{ - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0)); - return 0; -} - -AVFilter avfilter_vf_noformat = { - .name = "noformat", - .description = "Force libavfilter not to use any of the specified pixel formats for the input to the next filter.", - - .init = init, - - .query_formats = query_formats_noformat, - - .priv_size = sizeof(FormatContext), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer= avfilter_null_get_video_buffer, - .start_frame = avfilter_null_start_frame, - .draw_slice = avfilter_null_draw_slice, - .end_frame = avfilter_null_end_frame, }, - { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO }, - { .name = NULL}}, -}; -#endif /* CONFIG_NOFORMAT_FILTER */ - diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_null.c b/tizen/distrib/ffmpeg/libavfilter/vf_null.c deleted file mode 100644 index 989cd86..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_null.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * null video filter - */ - -#include "avfilter.h" - -AVFilter avfilter_vf_null = { - .name = "null", - .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."), - - .priv_size = 0, - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = avfilter_null_start_frame, - .end_frame = avfilter_null_end_frame }, - { .name = NULL}}, - - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_scale.c b/tizen/distrib/ffmpeg/libavfilter/vf_scale.c deleted file mode 100644 index a6b50ac..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_scale.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * scale video filter - */ - -#include "avfilter.h" -#include "libavutil/pixdesc.h" -#include "libswscale/swscale.h" - -typedef struct { - struct SwsContext *sws; ///< software scaler context - - /** - * New dimensions. Special values are: - * 0 = original width/height - * -1 = keep original aspect - */ - int w, h; - - int hsub, vsub; ///< chroma subsampling - int slice_y; ///< top of current output slice - int input_is_pal; ///< set to 1 if the input format is paletted -} ScaleContext; - -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) -{ - ScaleContext *scale = ctx->priv; - - if (args) - sscanf(args, "%d:%d", &scale->w, &scale->h); - - /* sanity check params */ - if (scale->w < -1 || scale->h < -1) { - av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n"); - return -1; - } - if (scale->w == -1 && scale->h == -1) - scale->w = scale->h = 0; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ScaleContext *scale = ctx->priv; - sws_freeContext(scale->sws); - scale->sws = NULL; -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats; - enum PixelFormat pix_fmt; - int ret; - - if (ctx->inputs[0]) { - formats = NULL; - for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) - if ( sws_isSupportedInput(pix_fmt) - && (ret = avfilter_add_colorspace(&formats, pix_fmt)) < 0) { - avfilter_formats_unref(&formats); - return ret; - } - avfilter_formats_ref(formats, &ctx->inputs[0]->out_formats); - } - if (ctx->outputs[0]) { - formats = NULL; - for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) - if ( sws_isSupportedOutput(pix_fmt) - && (ret = avfilter_add_colorspace(&formats, pix_fmt)) < 0) { - avfilter_formats_unref(&formats); - return ret; - } - avfilter_formats_ref(formats, &ctx->outputs[0]->in_formats); - } - - return 0; -} - -static int config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = outlink->src->inputs[0]; - ScaleContext *scale = ctx->priv; - int64_t w, h; - - if (!(w = scale->w)) - w = inlink->w; - if (!(h = scale->h)) - h = inlink->h; - if (w == -1) - w = av_rescale(h, inlink->w, inlink->h); - if (h == -1) - h = av_rescale(w, inlink->h, inlink->w); - - if (w > INT_MAX || h > INT_MAX || - (h * inlink->w) > INT_MAX || - (w * inlink->h) > INT_MAX) - av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); - - outlink->w = w; - outlink->h = h; - - /* TODO: make algorithm configurable */ - scale->sws = sws_getContext(inlink ->w, inlink ->h, inlink ->format, - outlink->w, outlink->h, outlink->format, - SWS_BILINEAR, NULL, NULL, NULL); - - av_log(ctx, AV_LOG_INFO, "w:%d h:%d fmt:%s\n", - outlink->w, outlink->h, av_pix_fmt_descriptors[outlink->format].name); - - scale->input_is_pal = av_pix_fmt_descriptors[inlink->format].flags & PIX_FMT_PAL; - - return !scale->sws; -} - -static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - ScaleContext *scale = link->dst->priv; - AVFilterLink *outlink = link->dst->outputs[0]; - AVFilterPicRef *outpicref; - - scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w; - scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; - - outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); - outpicref->pts = picref->pts; - outpicref->pos = picref->pos; - outlink->outpic = outpicref; - - av_reduce(&outpicref->pixel_aspect.num, &outpicref->pixel_aspect.den, - (int64_t)picref->pixel_aspect.num * outlink->h * link->w, - (int64_t)picref->pixel_aspect.den * outlink->w * link->h, - INT_MAX); - - scale->slice_y = 0; - avfilter_start_frame(outlink, avfilter_ref_pic(outpicref, ~0)); -} - -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - ScaleContext *scale = link->dst->priv; - int out_h; - AVFilterPicRef *cur_pic = link->cur_pic; - uint8_t *data[4]; - - if (scale->slice_y == 0 && slice_dir == -1) - scale->slice_y = link->dst->outputs[0]->h; - - data[0] = cur_pic->data[0] + y * cur_pic->linesize[0]; - data[1] = scale->input_is_pal ? - cur_pic->data[1] : - cur_pic->data[1] + (y>>scale->vsub) * cur_pic->linesize[1]; - data[2] = cur_pic->data[2] + (y>>scale->vsub) * cur_pic->linesize[2]; - data[3] = cur_pic->data[3] + y * cur_pic->linesize[3]; - - out_h = sws_scale(scale->sws, data, cur_pic->linesize, y, h, - link->dst->outputs[0]->outpic->data, - link->dst->outputs[0]->outpic->linesize); - - if (slice_dir == -1) - scale->slice_y -= out_h; - avfilter_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir); - if (slice_dir == 1) - scale->slice_y += out_h; -} - -AVFilter avfilter_vf_scale = { - .name = "scale", - .description = "Scale the input video to width:height size and/or convert the image format.", - - .init = init, - .uninit = uninit, - - .query_formats = query_formats, - - .priv_size = sizeof(ScaleContext), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .start_frame = start_frame, - .draw_slice = draw_slice, - .min_perms = AV_PERM_READ, }, - { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, }, - { .name = NULL}}, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_slicify.c b/tizen/distrib/ffmpeg/libavfilter/vf_slicify.c deleted file mode 100644 index 35e05da..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_slicify.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video slicing filter - */ - -#include "avfilter.h" -#include "libavutil/pixdesc.h" - -typedef struct { - int h; ///< output slice height - int vshift; ///< vertical chroma subsampling shift - uint32_t lcg_state; ///< LCG state used to compute random slice height - int use_random_h; ///< enable the use of random slice height values -} SliceContext; - -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) -{ - SliceContext *slice = ctx->priv; - - slice->h = 16; - if (args) { - if (!strcmp(args, "random")) { - slice->use_random_h = 1; - } else { - sscanf(args, "%d", &slice->h); - } - } - return 0; -} - -static int config_props(AVFilterLink *link) -{ - SliceContext *slice = link->dst->priv; - - slice->vshift = av_pix_fmt_descriptors[link->format].log2_chroma_h; - - return 0; -} - -static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - SliceContext *slice = link->dst->priv; - - if (slice->use_random_h) { - slice->lcg_state = slice->lcg_state * 1664525 + 1013904223; - slice->h = 8 + (uint64_t)slice->lcg_state * 25 / UINT32_MAX; - } - - /* ensure that slices play nice with chroma subsampling, and enforce - * a reasonable minimum size for the slices */ - slice->h = FFMAX(8, slice->h & (-1 << slice->vshift)); - - av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h); - - avfilter_start_frame(link->dst->outputs[0], picref); -} - -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - SliceContext *slice = link->dst->priv; - int y2; - - if (slice_dir == 1) { - for (y2 = y; y2 + slice->h <= y + h; y2 += slice->h) - avfilter_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir); - - if (y2 < y + h) - avfilter_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir); - } else if (slice_dir == -1) { - for (y2 = y + h; y2 - slice->h >= y; y2 -= slice->h) - avfilter_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir); - - if (y2 > y) - avfilter_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir); - } -} - -AVFilter avfilter_vf_slicify = { - .name = "slicify", - .description = "Pass the images of input video on to next video filter as multiple slices.", - - .init = init, - - .priv_size = sizeof(SliceContext), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = start_frame, - .draw_slice = draw_slice, - .config_props = config_props, - .end_frame = avfilter_null_end_frame, }, - { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_unsharp.c b/tizen/distrib/ffmpeg/libavfilter/vf_unsharp.c deleted file mode 100644 index 78a6d7c..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_unsharp.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Ported to FFmpeg from MPlayer libmpcodecs/unsharp.c - * Original copyright (C) 2002 Remi Guyomarch - * Port copyright (C) 2010 Daniel G. Taylor - * Relicensed to the LGPL with permission from Remi Guyomarch. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * blur / sharpen filter - * - * This code is based on: - * - * An Efficient algorithm for Gaussian blur using finite-state machines - * Frederick M. Waltz and John W. V. Miller - * - * SPIE Conf. on Machine Vision Systems for Inspection and Metrology VII - * Originally published Boston, Nov 98 - * - * http://www.engin.umd.umich.edu/~jwvm/ece581/21_GBlur.pdf - */ - -#include "avfilter.h" -#include "libavutil/common.h" -#include "libavutil/mem.h" -#include "libavutil/pixdesc.h" - -#define MIN_SIZE 3 -#define MAX_SIZE 13 - -#define CHROMA_WIDTH(link) -((-link->w) >> av_pix_fmt_descriptors[link->format].log2_chroma_w) -#define CHROMA_HEIGHT(link) -((-link->h) >> av_pix_fmt_descriptors[link->format].log2_chroma_h) - -typedef struct FilterParam { - int msize_x; ///< matrix width - int msize_y; ///< matrix height - int amount; ///< effect amount - int steps_x; ///< horizontal step count - int steps_y; ///< vertical step count - int scalebits; ///< bits to shift pixel - int32_t halfscale; ///< amount to add to pixel - uint32_t *sc[(MAX_SIZE * MAX_SIZE) - 1]; ///< finite state machine storage -} FilterParam; - -typedef struct { - FilterParam luma; ///< luma parameters (width, height, amount) - FilterParam chroma; ///< chroma parameters (width, height, amount) -} UnsharpContext; - -static void unsharpen(uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, FilterParam *fp) -{ - uint32_t **sc = fp->sc; - uint32_t sr[(MAX_SIZE * MAX_SIZE) - 1], tmp1, tmp2; - - int32_t res; - int x, y, z; - - if (!fp->amount) { - if (dst_stride == src_stride) - memcpy(dst, src, src_stride * height); - else - for (y = 0; y < height; y++, dst += dst_stride, src += src_stride) - memcpy(dst, src, width); - return; - } - - for (y = 0; y < 2 * fp->steps_y; y++) - memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * fp->steps_x)); - - for (y =- fp->steps_y; y < height + fp->steps_y; y++) { - memset(sr, 0, sizeof(sr[0]) * (2 * fp->steps_x - 1)); - for (x =- fp->steps_x; x < width + fp->steps_x; x++) { - tmp1 = x <= 0 ? src[0] : x >= width ? src[width-1] : src[x]; - for (z = 0; z < fp->steps_x * 2; z += 2) { - tmp2 = sr[z + 0] + tmp1; sr[z + 0] = tmp1; - tmp1 = sr[z + 1] + tmp2; sr[z + 1] = tmp2; - } - for (z = 0; z < fp->steps_y * 2; z += 2) { - tmp2 = sc[z + 0][x + fp->steps_x] + tmp1; sc[z + 0][x + fp->steps_x] = tmp1; - tmp1 = sc[z + 1][x + fp->steps_x] + tmp2; sc[z + 1][x + fp->steps_x] = tmp2; - } - if (x >= fp->steps_x && y >= fp->steps_y) { - uint8_t* srx = src - fp->steps_y * src_stride + x - fp->steps_x; - uint8_t* dsx = dst - fp->steps_y * dst_stride + x - fp->steps_x; - - res = (int32_t)*srx + ((((int32_t) * srx - (int32_t)((tmp1 + fp->halfscale) >> fp->scalebits)) * fp->amount) >> 16); - *dsx = av_clip_uint8(res); - } - } - if (y >= 0) { - dst += dst_stride; - src += src_stride; - } - } -} - -static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double amount) -{ - fp->msize_x = msize_x; - fp->msize_y = msize_y; - fp->amount = amount * 65536.0; - - fp->steps_x = msize_x / 2; - fp->steps_y = msize_y / 2; - fp->scalebits = (fp->steps_x + fp->steps_y) * 2; - fp->halfscale = 1 << (fp->scalebits - 1); -} - -static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) -{ - UnsharpContext *unsharp = ctx->priv; - int lmsize_x = 5, cmsize_x = 0; - int lmsize_y = 5, cmsize_y = 0; - double lamount = 1.0f, camount = 0.0f; - - if (args) - sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount, - &cmsize_x, &cmsize_y, &camount); - - set_filter_param(&unsharp->luma, lmsize_x, lmsize_y, lamount); - set_filter_param(&unsharp->chroma, cmsize_x, cmsize_y, camount); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - enum PixelFormat pix_fmts[] = { - PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_YUV410P, - PIX_FMT_YUV411P, PIX_FMT_YUV440P, PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, - PIX_FMT_YUVJ444P, PIX_FMT_YUVJ440P, PIX_FMT_NONE - }; - - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); - - return 0; -} - -static void init_filter_param(AVFilterContext *ctx, FilterParam *fp, const char *effect_type, int width) -{ - int z; - const char *effect; - - effect = fp->amount == 0 ? "none" : fp->amount < 0 ? "blur" : "sharpen"; - - av_log(ctx, AV_LOG_INFO, "effect:%s type:%s msize_x:%d msize_y:%d amount:%0.2f\n", - effect, effect_type, fp->msize_x, fp->msize_y, fp->amount / 65535.0); - - for (z = 0; z < 2 * fp->steps_y; z++) - fp->sc[z] = av_malloc(sizeof(*(fp->sc[z])) * (width + 2 * fp->steps_x)); -} - -static int config_props(AVFilterLink *link) -{ - UnsharpContext *unsharp = link->dst->priv; - - init_filter_param(link->dst, &unsharp->luma, "luma", link->w); - init_filter_param(link->dst, &unsharp->chroma, "chroma", CHROMA_WIDTH(link)); - - return 0; -} - -static void free_filter_param(FilterParam *fp) -{ - int z; - - for (z = 0; z < 2 * fp->steps_y; z++) - av_free(fp->sc[z]); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - UnsharpContext *unsharp = ctx->priv; - - free_filter_param(&unsharp->luma); - free_filter_param(&unsharp->chroma); -} - -static void end_frame(AVFilterLink *link) -{ - UnsharpContext *unsharp = link->dst->priv; - AVFilterPicRef *in = link->cur_pic; - AVFilterPicRef *out = link->dst->outputs[0]->outpic; - - unsharpen(out->data[0], in->data[0], out->linesize[0], in->linesize[0], link->w, link->h, &unsharp->luma); - unsharpen(out->data[1], in->data[1], out->linesize[1], in->linesize[1], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), &unsharp->chroma); - unsharpen(out->data[2], in->data[2], out->linesize[2], in->linesize[2], CHROMA_WIDTH(link), CHROMA_HEIGHT(link), &unsharp->chroma); - - avfilter_unref_pic(in); - avfilter_draw_slice(link->dst->outputs[0], 0, link->h, 1); - avfilter_end_frame(link->dst->outputs[0]); - avfilter_unref_pic(out); -} - -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ -} - -AVFilter avfilter_vf_unsharp = { - .name = "unsharp", - .description = NULL_IF_CONFIG_SMALL("Sharpen or blur the input video."), - - .priv_size = sizeof(UnsharpContext), - - .init = init, - .uninit = uninit, - .query_formats = query_formats, - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .draw_slice = draw_slice, - .end_frame = end_frame, - .config_props = config_props, - .min_perms = AV_PERM_READ, }, - { .name = NULL}}, - - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/vf_vflip.c b/tizen/distrib/ffmpeg/libavfilter/vf_vflip.c deleted file mode 100644 index 0dfcb35..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vf_vflip.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video vertical flip filter - */ - -#include "libavutil/pixdesc.h" -#include "avfilter.h" - -typedef struct { - int vsub; ///< vertical chroma subsampling -} FlipContext; - -static int config_input(AVFilterLink *link) -{ - FlipContext *flip = link->dst->priv; - - flip->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; - - return 0; -} - -static AVFilterPicRef *get_video_buffer(AVFilterLink *link, int perms, - int w, int h) -{ - FlipContext *flip = link->dst->priv; - int i; - - AVFilterPicRef *picref = avfilter_get_video_buffer(link->dst->outputs[0], - perms, w, h); - - for (i = 0; i < 4; i ++) { - int vsub = i == 1 || i == 2 ? flip->vsub : 0; - - if (picref->data[i]) { - picref->data[i] += ((h >> vsub)-1) * picref->linesize[i]; - picref->linesize[i] = -picref->linesize[i]; - } - } - - return picref; -} - -static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ - FlipContext *flip = link->dst->priv; - int i; - - for (i = 0; i < 4; i ++) { - int vsub = i == 1 || i == 2 ? flip->vsub : 0; - - if (picref->data[i]) { - picref->data[i] += ((link->h >> vsub)-1) * picref->linesize[i]; - picref->linesize[i] = -picref->linesize[i]; - } - } - - avfilter_start_frame(link->dst->outputs[0], picref); -} - -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) -{ - AVFilterContext *ctx = link->dst; - - avfilter_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir); -} - -AVFilter avfilter_vf_vflip = { - .name = "vflip", - .description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."), - - .priv_size = sizeof(FlipContext), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = get_video_buffer, - .start_frame = start_frame, - .draw_slice = draw_slice, - .end_frame = avfilter_null_end_frame, - .config_props = config_input, }, - { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, }, - { .name = NULL}}, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/vsink_nullsink.c b/tizen/distrib/ffmpeg/libavfilter/vsink_nullsink.c deleted file mode 100644 index d11912f..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vsink_nullsink.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avfilter.h" - -static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) -{ -} - -static void end_frame(AVFilterLink *link) -{ -} - -AVFilter avfilter_vsink_nullsink = { - .name = "nullsink", - .description = "Do absolutely nothing with the input video.", - - .priv_size = 0, - - .inputs = (AVFilterPad[]) { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .start_frame = start_frame, - .end_frame = end_frame, - }, - { .name = NULL}, - }, - .outputs = (AVFilterPad[]) {{ .name = NULL }}, -}; diff --git a/tizen/distrib/ffmpeg/libavfilter/vsrc_nullsrc.c b/tizen/distrib/ffmpeg/libavfilter/vsrc_nullsrc.c deleted file mode 100644 index 4356199..0000000 --- a/tizen/distrib/ffmpeg/libavfilter/vsrc_nullsrc.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * null video source - */ - -#include "avfilter.h" - -typedef struct { - int w, h; -} NullContext; - -static int init(AVFilterContext *ctx, const char *args, void *opaque) -{ - NullContext *priv = ctx->priv; - - priv->w = 352; - priv->h = 288; - - if (args) - sscanf(args, "%d:%d", &priv->w, &priv->h); - - if (priv->w <= 0 || priv->h <= 0) { - av_log(ctx, AV_LOG_ERROR, "Non-positive size values are not acceptable.\n"); - return -1; - } - - return 0; -} - -static int config_props(AVFilterLink *outlink) -{ - NullContext *priv = outlink->src->priv; - - outlink->w = priv->w; - outlink->h = priv->h; - - av_log(outlink->src, AV_LOG_INFO, "w:%d h:%d\n", priv->w, priv->h); - - return 0; -} - -static int request_frame(AVFilterLink *link) -{ - return -1; -} - -AVFilter avfilter_vsrc_nullsrc = { - .name = "nullsrc", - .description = "Null video source, never return images.", - - .init = init, - .priv_size = sizeof(NullContext), - - .inputs = (AVFilterPad[]) {{ .name = NULL}}, - - .outputs = (AVFilterPad[]) { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, - .request_frame = request_frame, - }, - { .name = NULL} - }, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/4xm.c b/tizen/distrib/ffmpeg/libavformat/4xm.c deleted file mode 100644 index a697f8d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/4xm.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * 4X Technologies .4xm File Demuxer (no muxer) - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 4X Technologies file demuxer - * by Mike Melanson (melanson@pcisys.net) - * for more information on the .4xm file format, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define RIFF_TAG MKTAG('R', 'I', 'F', 'F') -#define FOURXMV_TAG MKTAG('4', 'X', 'M', 'V') -#define LIST_TAG MKTAG('L', 'I', 'S', 'T') -#define HEAD_TAG MKTAG('H', 'E', 'A', 'D') -#define TRK__TAG MKTAG('T', 'R', 'K', '_') -#define MOVI_TAG MKTAG('M', 'O', 'V', 'I') -#define VTRK_TAG MKTAG('V', 'T', 'R', 'K') -#define STRK_TAG MKTAG('S', 'T', 'R', 'K') -#define std__TAG MKTAG('s', 't', 'd', '_') -#define name_TAG MKTAG('n', 'a', 'm', 'e') -#define vtrk_TAG MKTAG('v', 't', 'r', 'k') -#define strk_TAG MKTAG('s', 't', 'r', 'k') -#define ifrm_TAG MKTAG('i', 'f', 'r', 'm') -#define pfrm_TAG MKTAG('p', 'f', 'r', 'm') -#define cfrm_TAG MKTAG('c', 'f', 'r', 'm') -#define ifr2_TAG MKTAG('i', 'f', 'r', '2') -#define pfr2_TAG MKTAG('p', 'f', 'r', '2') -#define cfr2_TAG MKTAG('c', 'f', 'r', '2') -#define snd__TAG MKTAG('s', 'n', 'd', '_') - -#define vtrk_SIZE 0x44 -#define strk_SIZE 0x28 - -#define GET_LIST_HEADER() \ - fourcc_tag = get_le32(pb); \ - size = get_le32(pb); \ - if (fourcc_tag != LIST_TAG) \ - return AVERROR_INVALIDDATA; \ - fourcc_tag = get_le32(pb); - -typedef struct AudioTrack { - int sample_rate; - int bits; - int channels; - int stream_index; - int adpcm; - int64_t audio_pts; -} AudioTrack; - -typedef struct FourxmDemuxContext { - int width; - int height; - int video_stream_index; - int track_count; - AudioTrack *tracks; - - int64_t video_pts; - float fps; -} FourxmDemuxContext; - -static int fourxm_probe(AVProbeData *p) -{ - if ((AV_RL32(&p->buf[0]) != RIFF_TAG) || - (AV_RL32(&p->buf[8]) != FOURXMV_TAG)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int fourxm_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - unsigned int fourcc_tag; - unsigned int size; - int header_size; - FourxmDemuxContext *fourxm = s->priv_data; - unsigned char *header; - int i, ret; - AVStream *st; - - fourxm->track_count = 0; - fourxm->tracks = NULL; - fourxm->fps = 1.0; - - /* skip the first 3 32-bit numbers */ - url_fseek(pb, 12, SEEK_CUR); - - /* check for LIST-HEAD */ - GET_LIST_HEADER(); - header_size = size - 4; - if (fourcc_tag != HEAD_TAG || header_size < 0) - return AVERROR_INVALIDDATA; - - /* allocate space for the header and load the whole thing */ - header = av_malloc(header_size); - if (!header) - return AVERROR(ENOMEM); - if (get_buffer(pb, header, header_size) != header_size){ - av_free(header); - return AVERROR(EIO); - } - - /* take the lazy approach and search for any and all vtrk and strk chunks */ - for (i = 0; i < header_size - 8; i++) { - fourcc_tag = AV_RL32(&header[i]); - size = AV_RL32(&header[i + 4]); - - if (fourcc_tag == std__TAG) { - fourxm->fps = av_int2flt(AV_RL32(&header[i + 12])); - } else if (fourcc_tag == vtrk_TAG) { - /* check that there is enough data */ - if (size != vtrk_SIZE) { - ret= AVERROR_INVALIDDATA; - goto fail; - } - fourxm->width = AV_RL32(&header[i + 36]); - fourxm->height = AV_RL32(&header[i + 40]); - - /* allocate a new AVStream */ - st = av_new_stream(s, 0); - if (!st){ - ret= AVERROR(ENOMEM); - goto fail; - } - av_set_pts_info(st, 60, 1, fourxm->fps); - - fourxm->video_stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_4XM; - st->codec->extradata_size = 4; - st->codec->extradata = av_malloc(4); - AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16])); - st->codec->width = fourxm->width; - st->codec->height = fourxm->height; - - i += 8 + size; - } else if (fourcc_tag == strk_TAG) { - int current_track; - /* check that there is enough data */ - if (size != strk_SIZE) { - ret= AVERROR_INVALIDDATA; - goto fail; - } - current_track = AV_RL32(&header[i + 8]); - if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){ - av_log(s, AV_LOG_ERROR, "current_track too large\n"); - ret= -1; - goto fail; - } - if (current_track + 1 > fourxm->track_count) { - fourxm->track_count = current_track + 1; - fourxm->tracks = av_realloc(fourxm->tracks, - fourxm->track_count * sizeof(AudioTrack)); - if (!fourxm->tracks) { - ret= AVERROR(ENOMEM); - goto fail; - } - } - fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]); - fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]); - fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]); - fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]); - fourxm->tracks[current_track].audio_pts = 0; - i += 8 + size; - - /* allocate a new AVStream */ - st = av_new_stream(s, current_track); - if (!st){ - ret= AVERROR(ENOMEM); - goto fail; - } - - av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate); - - fourxm->tracks[current_track].stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; - st->codec->channels = fourxm->tracks[current_track].channels; - st->codec->sample_rate = fourxm->tracks[current_track].sample_rate; - st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - if (fourxm->tracks[current_track].adpcm){ - st->codec->codec_id = CODEC_ID_ADPCM_4XM; - }else if (st->codec->bits_per_coded_sample == 8){ - st->codec->codec_id = CODEC_ID_PCM_U8; - }else - st->codec->codec_id = CODEC_ID_PCM_S16LE; - } - } - - /* skip over the LIST-MOVI chunk (which is where the stream should be */ - GET_LIST_HEADER(); - if (fourcc_tag != MOVI_TAG){ - ret= AVERROR_INVALIDDATA; - goto fail; - } - - av_free(header); - /* initialize context members */ - fourxm->video_pts = -1; /* first frame will push to 0 */ - - return 0; -fail: - av_freep(&fourxm->tracks); - av_free(header); - return ret; -} - -static int fourxm_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - FourxmDemuxContext *fourxm = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned int fourcc_tag; - unsigned int size, out_size; - int ret = 0; - unsigned int track_number; - int packet_read = 0; - unsigned char header[8]; - int audio_frame_count; - - while (!packet_read) { - - if ((ret = get_buffer(s->pb, header, 8)) < 0) - return ret; - fourcc_tag = AV_RL32(&header[0]); - size = AV_RL32(&header[4]); - if (url_feof(pb)) - return AVERROR(EIO); - switch (fourcc_tag) { - - case LIST_TAG: - /* this is a good time to bump the video pts */ - fourxm->video_pts ++; - - /* skip the LIST-* tag and move on to the next fourcc */ - get_le32(pb); - break; - - case ifrm_TAG: - case pfrm_TAG: - case cfrm_TAG: - case ifr2_TAG: - case pfr2_TAG: - case cfr2_TAG: - /* allocate 8 more bytes than 'size' to account for fourcc - * and size */ - if (size + 8 < size || av_new_packet(pkt, size + 8)) - return AVERROR(EIO); - pkt->stream_index = fourxm->video_stream_index; - pkt->pts = fourxm->video_pts; - pkt->pos = url_ftell(s->pb); - memcpy(pkt->data, header, 8); - ret = get_buffer(s->pb, &pkt->data[8], size); - - if (ret < 0){ - av_free_packet(pkt); - }else - packet_read = 1; - break; - - case snd__TAG: - track_number = get_le32(pb); - out_size= get_le32(pb); - size-=8; - - if (track_number < fourxm->track_count) { - ret= av_get_packet(s->pb, pkt, size); - if(ret<0) - return AVERROR(EIO); - pkt->stream_index = - fourxm->tracks[track_number].stream_index; - pkt->pts = fourxm->tracks[track_number].audio_pts; - packet_read = 1; - - /* pts accounting */ - audio_frame_count = size; - if (fourxm->tracks[track_number].adpcm) - audio_frame_count -= - 2 * (fourxm->tracks[track_number].channels); - audio_frame_count /= - fourxm->tracks[track_number].channels; - if (fourxm->tracks[track_number].adpcm){ - audio_frame_count *= 2; - }else - audio_frame_count /= - (fourxm->tracks[track_number].bits / 8); - fourxm->tracks[track_number].audio_pts += audio_frame_count; - - } else { - url_fseek(pb, size, SEEK_CUR); - } - break; - - default: - url_fseek(pb, size, SEEK_CUR); - break; - } - } - return ret; -} - -static int fourxm_read_close(AVFormatContext *s) -{ - FourxmDemuxContext *fourxm = s->priv_data; - - av_freep(&fourxm->tracks); - - return 0; -} - -AVInputFormat fourxm_demuxer = { - "4xm", - NULL_IF_CONFIG_SMALL("4X Technologies format"), - sizeof(FourxmDemuxContext), - fourxm_probe, - fourxm_read_header, - fourxm_read_packet, - fourxm_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/Makefile b/tizen/distrib/ffmpeg/libavformat/Makefile deleted file mode 100644 index 7a2d00f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/Makefile +++ /dev/null @@ -1,299 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = avformat -FFLIBS = avcodec avutil - -HEADERS = avformat.h avio.h - -OBJS = allformats.o \ - cutils.o \ - metadata.o \ - metadata_compat.o \ - options.o \ - os_support.o \ - sdp.o \ - seek.o \ - utils.o \ - -# muxers/demuxers -OBJS-$(CONFIG_AAC_DEMUXER) += raw.o id3v1.o id3v2.o -OBJS-$(CONFIG_AC3_DEMUXER) += raw.o -OBJS-$(CONFIG_AC3_MUXER) += raw.o -OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o -OBJS-$(CONFIG_AEA_DEMUXER) += aea.o raw.o -OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o raw.o -OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o riff.o -OBJS-$(CONFIG_AMR_DEMUXER) += amr.o -OBJS-$(CONFIG_AMR_MUXER) += amr.o -OBJS-$(CONFIG_ANM_DEMUXER) += anm.o -OBJS-$(CONFIG_APC_DEMUXER) += apc.o -OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o -OBJS-$(CONFIG_ASF_DEMUXER) += asfdec.o asf.o asfcrypt.o \ - riff.o avlanguage.o -OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o riff.o -OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o -OBJS-$(CONFIG_ASS_MUXER) += assenc.o -OBJS-$(CONFIG_AU_DEMUXER) += au.o raw.o -OBJS-$(CONFIG_AU_MUXER) += au.o -OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o avi.o -OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o avi.o -OBJS-$(CONFIG_AVISYNTH) += avisynth.o -OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o -OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o -OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o -OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o -OBJS-$(CONFIG_BINK_DEMUXER) += bink.o -OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o -OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o riff.o isom.o -OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += raw.o -OBJS-$(CONFIG_CDG_DEMUXER) += cdg.o -OBJS-$(CONFIG_CRC_MUXER) += crcenc.o -OBJS-$(CONFIG_DAUD_DEMUXER) += daud.o -OBJS-$(CONFIG_DAUD_MUXER) += daud.o -OBJS-$(CONFIG_DIRAC_DEMUXER) += raw.o -OBJS-$(CONFIG_DIRAC_MUXER) += raw.o -OBJS-$(CONFIG_DNXHD_DEMUXER) += raw.o -OBJS-$(CONFIG_DNXHD_MUXER) += raw.o -OBJS-$(CONFIG_DSICIN_DEMUXER) += dsicin.o -OBJS-$(CONFIG_DTS_DEMUXER) += raw.o id3v2.o -OBJS-$(CONFIG_DTS_MUXER) += raw.o -OBJS-$(CONFIG_DV_DEMUXER) += dv.o -OBJS-$(CONFIG_DV_MUXER) += dvenc.o -OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o riff.o -OBJS-$(CONFIG_EA_CDATA_DEMUXER) += eacdata.o -OBJS-$(CONFIG_EA_DEMUXER) += electronicarts.o -OBJS-$(CONFIG_EAC3_DEMUXER) += raw.o id3v2.o -OBJS-$(CONFIG_EAC3_MUXER) += raw.o -OBJS-$(CONFIG_FFM_DEMUXER) += ffmdec.o -OBJS-$(CONFIG_FFM_MUXER) += ffmenc.o -OBJS-$(CONFIG_FILMSTRIP_DEMUXER) += filmstripdec.o -OBJS-$(CONFIG_FILMSTRIP_MUXER) += filmstripenc.o -OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o raw.o id3v1.o \ - id3v2.o oggparsevorbis.o \ - vorbiscomment.o -OBJS-$(CONFIG_FLAC_MUXER) += flacenc.o flacenc_header.o \ - vorbiscomment.o -OBJS-$(CONFIG_FLIC_DEMUXER) += flic.o -OBJS-$(CONFIG_FLV_DEMUXER) += flvdec.o -OBJS-$(CONFIG_FLV_MUXER) += flvenc.o avc.o -OBJS-$(CONFIG_FOURXM_DEMUXER) += 4xm.o -OBJS-$(CONFIG_FRAMECRC_MUXER) += framecrcenc.o -OBJS-$(CONFIG_GIF_MUXER) += gif.o -OBJS-$(CONFIG_GSM_DEMUXER) += raw.o id3v2.o -OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o -OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o audiointerleave.o -OBJS-$(CONFIG_H261_DEMUXER) += raw.o -OBJS-$(CONFIG_H261_MUXER) += raw.o -OBJS-$(CONFIG_H263_DEMUXER) += raw.o -OBJS-$(CONFIG_H263_MUXER) += raw.o -OBJS-$(CONFIG_H264_DEMUXER) += raw.o -OBJS-$(CONFIG_H264_MUXER) += raw.o -OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o -OBJS-$(CONFIG_IFF_DEMUXER) += iff.o -OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2.o -OBJS-$(CONFIG_IMAGE2_MUXER) += img2.o -OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER) += img2.o -OBJS-$(CONFIG_IMAGE2PIPE_MUXER) += img2.o -OBJS-$(CONFIG_INGENIENT_DEMUXER) += raw.o -OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o -OBJS-$(CONFIG_ISS_DEMUXER) += iss.o -OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o -OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o -OBJS-$(CONFIG_M4V_DEMUXER) += raw.o -OBJS-$(CONFIG_M4V_MUXER) += raw.o -OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ - riff.o isom.o rmdec.o rm.o -OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ - riff.o isom.o avc.o \ - flacenc_header.o -OBJS-$(CONFIG_MJPEG_DEMUXER) += raw.o -OBJS-$(CONFIG_MJPEG_MUXER) += raw.o -OBJS-$(CONFIG_MLP_DEMUXER) += raw.o id3v2.o -OBJS-$(CONFIG_MLP_MUXER) += raw.o -OBJS-$(CONFIG_MM_DEMUXER) += mm.o -OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o raw.o -OBJS-$(CONFIG_MMF_MUXER) += mmf.o riff.o -OBJS-$(CONFIG_MOV_DEMUXER) += mov.o riff.o isom.o -OBJS-$(CONFIG_MOV_MUXER) += movenc.o riff.o isom.o avc.o movenchint.o -OBJS-$(CONFIG_MP2_MUXER) += mp3.o id3v1.o -OBJS-$(CONFIG_MP3_DEMUXER) += mp3.o id3v1.o id3v2.o -OBJS-$(CONFIG_MP3_MUXER) += mp3.o id3v1.o id3v2.o -OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o id3v1.o id3v2.o apetag.o -OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o -OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG1VCD_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG2DVD_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG2VOB_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG2SVCD_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG1VIDEO_MUXER) += raw.o -OBJS-$(CONFIG_MPEG2VIDEO_MUXER) += raw.o -OBJS-$(CONFIG_MPEGPS_DEMUXER) += mpeg.o -OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpegts.o -OBJS-$(CONFIG_MPEGTS_MUXER) += mpegtsenc.o adtsenc.o -OBJS-$(CONFIG_MPEGVIDEO_DEMUXER) += raw.o -OBJS-$(CONFIG_MPJPEG_MUXER) += mpjpeg.o -OBJS-$(CONFIG_MSNWC_TCP_DEMUXER) += msnwc_tcp.o -OBJS-$(CONFIG_MTV_DEMUXER) += mtv.o -OBJS-$(CONFIG_MVI_DEMUXER) += mvi.o -OBJS-$(CONFIG_MXF_DEMUXER) += mxfdec.o mxf.o -OBJS-$(CONFIG_MXF_MUXER) += mxfenc.o mxf.o audiointerleave.o -OBJS-$(CONFIG_NC_DEMUXER) += ncdec.o -OBJS-$(CONFIG_NSV_DEMUXER) += nsvdec.o -OBJS-$(CONFIG_NULL_MUXER) += raw.o -OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o riff.o -OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o riff.o -OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o riff.o -OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ - oggparsedirac.o \ - oggparseflac.o \ - oggparseogm.o \ - oggparseskeleton.o \ - oggparsespeex.o \ - oggparsetheora.o \ - oggparsevorbis.o \ - riff.o \ - vorbiscomment.o -OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \ - vorbiscomment.o -OBJS-$(CONFIG_OMA_DEMUXER) += oma.o raw.o -OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_ALAW_MUXER) += raw.o -OBJS-$(CONFIG_PCM_F32BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_F32BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_F32LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_F32LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_F64BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_F64BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_F64LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_F64LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_MULAW_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_MULAW_MUXER) += raw.o -OBJS-$(CONFIG_PCM_S16BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_S16BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_S16LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_S16LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_S24BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_S24BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_S24LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_S24LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_S32BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_S32BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_S32LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_S32LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_S8_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_S8_MUXER) += raw.o -OBJS-$(CONFIG_PCM_U16BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_U16BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_U16LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_U16LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_U24BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_U24BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_U24LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_U24LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_U32BE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_U32BE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_U32LE_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_U32LE_MUXER) += raw.o -OBJS-$(CONFIG_PCM_U8_DEMUXER) += raw.o -OBJS-$(CONFIG_PCM_U8_MUXER) += raw.o -OBJS-$(CONFIG_PVA_DEMUXER) += pva.o -OBJS-$(CONFIG_QCP_DEMUXER) += qcp.o -OBJS-$(CONFIG_R3D_DEMUXER) += r3d.o -OBJS-$(CONFIG_RAWVIDEO_DEMUXER) += raw.o -OBJS-$(CONFIG_RAWVIDEO_MUXER) += raw.o -OBJS-$(CONFIG_RL2_DEMUXER) += rl2.o -OBJS-$(CONFIG_RM_DEMUXER) += rmdec.o rm.o -OBJS-$(CONFIG_RM_MUXER) += rmenc.o rm.o -OBJS-$(CONFIG_ROQ_DEMUXER) += idroq.o -OBJS-$(CONFIG_ROQ_MUXER) += raw.o -OBJS-$(CONFIG_RPL_DEMUXER) += rpl.o -OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ - rtpenc_aac.o \ - rtpenc_amr.o \ - rtpenc_h263.o \ - rtpenc_mpv.o \ - rtpenc.o \ - rtpenc_h264.o \ - avc.o -OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o httpauth.o -OBJS-$(CONFIG_RTSP_MUXER) += rtsp.o rtspenc.o httpauth.o -OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o \ - rdt.o \ - rtp.o \ - rtpdec.o \ - rtpdec_amr.o \ - rtpdec_asf.o \ - rtpdec_h263.o \ - rtpdec_h264.o \ - rtpdec_xiph.o -OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o -OBJS-$(CONFIG_SHORTEN_DEMUXER) += raw.o id3v2.o -OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o -OBJS-$(CONFIG_SMACKER_DEMUXER) += smacker.o -OBJS-$(CONFIG_SOL_DEMUXER) += sol.o raw.o -OBJS-$(CONFIG_SOX_DEMUXER) += soxdec.o raw.o -OBJS-$(CONFIG_SOX_MUXER) += soxenc.o -OBJS-$(CONFIG_SPDIF_MUXER) += spdif.o -OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o -OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o -OBJS-$(CONFIG_SWF_MUXER) += swfenc.o -OBJS-$(CONFIG_THP_DEMUXER) += thp.o -OBJS-$(CONFIG_TIERTEXSEQ_DEMUXER) += tiertexseq.o -OBJS-$(CONFIG_TMV_DEMUXER) += tmv.o -OBJS-$(CONFIG_TRUEHD_DEMUXER) += raw.o id3v2.o -OBJS-$(CONFIG_TRUEHD_MUXER) += raw.o -OBJS-$(CONFIG_TTA_DEMUXER) += tta.o id3v1.o id3v2.o -OBJS-$(CONFIG_TXD_DEMUXER) += txd.o -OBJS-$(CONFIG_VC1_DEMUXER) += raw.o -OBJS-$(CONFIG_VC1T_DEMUXER) += vc1test.o -OBJS-$(CONFIG_VC1T_MUXER) += vc1testenc.o -OBJS-$(CONFIG_VMD_DEMUXER) += sierravmd.o -OBJS-$(CONFIG_VOC_DEMUXER) += vocdec.o voc.o -OBJS-$(CONFIG_VOC_MUXER) += vocenc.o voc.o -OBJS-$(CONFIG_VQF_DEMUXER) += vqf.o -OBJS-$(CONFIG_W64_DEMUXER) += wav.o riff.o raw.o -OBJS-$(CONFIG_WAV_DEMUXER) += wav.o riff.o raw.o -OBJS-$(CONFIG_WAV_MUXER) += wav.o riff.o -OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o -OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \ - riff.o isom.o avc.o \ - flacenc_header.o -OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood.o -OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood.o -OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o id3v1.o -OBJS-$(CONFIG_XA_DEMUXER) += xa.o -OBJS-$(CONFIG_YOP_DEMUXER) += yop.o -OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o -OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o - -# external libraries -OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o riff.o -OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o riff.o - -# protocols I/O -OBJS+= avio.o aviobuf.o - -OBJS-$(CONFIG_FILE_PROTOCOL) += file.o -OBJS-$(CONFIG_GOPHER_PROTOCOL) += gopher.o -OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o -OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o - -# external or internal rtmp -RTMP-OBJS-$(CONFIG_LIBRTMP) = librtmp.o -RTMP-OBJS-$(!CONFIG_LIBRTMP) = rtmpproto.o rtmppkt.o -OBJS-$(CONFIG_RTMP_PROTOCOL) += $(RTMP-OBJS-yes) - -OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o -OBJS-$(CONFIG_TCP_PROTOCOL) += tcp.o -OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o -OBJS-$(CONFIG_CONCAT_PROTOCOL) += concat.o - -# libavdevice dependencies -OBJS-$(CONFIG_JACK_INDEV) += timefilter.o - -EXAMPLES = output -TESTPROGS = timefilter - -include $(SUBDIR)../subdir.mak - -$(SUBDIR)output-example$(EXESUF): ELIBS = -lswscale diff --git a/tizen/distrib/ffmpeg/libavformat/adts.h b/tizen/distrib/ffmpeg/libavformat/adts.h deleted file mode 100644 index 1da57be..0000000 --- a/tizen/distrib/ffmpeg/libavformat/adts.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ADTS muxer. - * Copyright (c) 2006 Baptiste Coudurier - * Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_ADTS_H -#define AVFORMAT_ADTS_H - -#include "avformat.h" -#include "libavcodec/mpeg4audio.h" - -#define ADTS_HEADER_SIZE 7 - -typedef struct { - int write_adts; - int objecttype; - int sample_rate_index; - int channel_conf; - int pce_size; - uint8_t pce_data[MAX_PCE_SIZE]; -} ADTSContext; - -int ff_adts_write_frame_header(ADTSContext *ctx, uint8_t *buf, - int size, int pce_size); -int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, - uint8_t *buf, int size); - -#endif /* AVFORMAT_ADTS_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/adtsenc.c b/tizen/distrib/ffmpeg/libavformat/adtsenc.c deleted file mode 100644 index ecc8dc4..0000000 --- a/tizen/distrib/ffmpeg/libavformat/adtsenc.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * ADTS muxer. - * Copyright (c) 2006 Baptiste Coudurier - * Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/get_bits.h" -#include "libavcodec/put_bits.h" -#include "libavcodec/avcodec.h" -#include "avformat.h" -#include "adts.h" - -int ff_adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf, int size) -{ - GetBitContext gb; - PutBitContext pb; - - init_get_bits(&gb, buf, size * 8); - adts->objecttype = get_bits(&gb, 5) - 1; - adts->sample_rate_index = get_bits(&gb, 4); - adts->channel_conf = get_bits(&gb, 4); - - if (adts->objecttype > 3U) { - av_log(s, AV_LOG_ERROR, "MPEG-4 AOT %d is not allowed in ADTS\n", adts->objecttype+1); - return -1; - } - if (adts->sample_rate_index == 15) { - av_log(s, AV_LOG_ERROR, "Escape sample rate index illegal in ADTS\n"); - return -1; - } - if (get_bits(&gb, 1)) { - av_log(s, AV_LOG_ERROR, "960/120 MDCT window is not allowed in ADTS\n"); - return -1; - } - if (get_bits(&gb, 1)) { - av_log(s, AV_LOG_ERROR, "Scalable configurations are not allowed in ADTS\n"); - return -1; - } - if (get_bits(&gb, 1)) { - av_log_missing_feature(s, "Signaled SBR or PS", 0); - return -1; - } - if (!adts->channel_conf) { - init_put_bits(&pb, adts->pce_data, MAX_PCE_SIZE); - - put_bits(&pb, 3, 5); //ID_PCE - adts->pce_size = (ff_copy_pce_data(&pb, &gb) + 3) / 8; - flush_put_bits(&pb); - } - - adts->write_adts = 1; - - return 0; -} - -static int adts_write_header(AVFormatContext *s) -{ - ADTSContext *adts = s->priv_data; - AVCodecContext *avc = s->streams[0]->codec; - - if(avc->extradata_size > 0 && - ff_adts_decode_extradata(s, adts, avc->extradata, avc->extradata_size) < 0) - return -1; - - return 0; -} - -int ff_adts_write_frame_header(ADTSContext *ctx, - uint8_t *buf, int size, int pce_size) -{ - PutBitContext pb; - - init_put_bits(&pb, buf, ADTS_HEADER_SIZE); - - /* adts_fixed_header */ - put_bits(&pb, 12, 0xfff); /* syncword */ - put_bits(&pb, 1, 0); /* ID */ - put_bits(&pb, 2, 0); /* layer */ - put_bits(&pb, 1, 1); /* protection_absent */ - put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */ - put_bits(&pb, 4, ctx->sample_rate_index); - put_bits(&pb, 1, 0); /* private_bit */ - put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */ - put_bits(&pb, 1, 0); /* original_copy */ - put_bits(&pb, 1, 0); /* home */ - - /* adts_variable_header */ - put_bits(&pb, 1, 0); /* copyright_identification_bit */ - put_bits(&pb, 1, 0); /* copyright_identification_start */ - put_bits(&pb, 13, ADTS_HEADER_SIZE + size + pce_size); /* aac_frame_length */ - put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */ - put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */ - - flush_put_bits(&pb); - - return 0; -} - -static int adts_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ADTSContext *adts = s->priv_data; - ByteIOContext *pb = s->pb; - uint8_t buf[ADTS_HEADER_SIZE]; - - if (!pkt->size) - return 0; - if(adts->write_adts) { - ff_adts_write_frame_header(adts, buf, pkt->size, adts->pce_size); - put_buffer(pb, buf, ADTS_HEADER_SIZE); - if(adts->pce_size) { - put_buffer(pb, adts->pce_data, adts->pce_size); - adts->pce_size = 0; - } - } - put_buffer(pb, pkt->data, pkt->size); - put_flush_packet(pb); - - return 0; -} - -AVOutputFormat adts_muxer = { - "adts", - NULL_IF_CONFIG_SMALL("ADTS AAC"), - "audio/aac", - "aac,adts", - sizeof(ADTSContext), - CODEC_ID_AAC, - CODEC_ID_NONE, - adts_write_header, - adts_write_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/aea.c b/tizen/distrib/ffmpeg/libavformat/aea.c deleted file mode 100644 index 518995c..0000000 --- a/tizen/distrib/ffmpeg/libavformat/aea.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * MD STUDIO audio demuxer - * - * Copyright (c) 2009 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "raw.h" -#include "libavutil/intreadwrite.h" - -#define AT1_SU_SIZE 212 - -static int aea_read_probe(AVProbeData *p) -{ - if (p->buf_size <= 2048+212) - return 0; - - /* Magic is '00 08 00 00' in Little Endian*/ - if (AV_RL32(p->buf)==0x800) { - int bsm_s, bsm_e, inb_s, inb_e, ch; - ch = p->buf[264]; - bsm_s = p->buf[2048]; - inb_s = p->buf[2048+1]; - inb_e = p->buf[2048+210]; - bsm_e = p->buf[2048+211]; - - if (ch != 1 && ch != 2) - return 0; - - /* Check so that the redundant bsm bytes and info bytes are valid - * the block size mode bytes have to be the same - * the info bytes have to be the same - */ - if (bsm_s == bsm_e && inb_s == inb_e) - return AVPROBE_SCORE_MAX / 4 + 1; - } - return 0; -} - -static int aea_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - /* Parse the amount of channels and skip to pos 2048(0x800) */ - url_fskip(s->pb, 264); - st->codec->channels = get_byte(s->pb); - url_fskip(s->pb, 1783); - - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ATRAC1; - st->codec->sample_rate = 44100; - st->codec->bit_rate = 292000; - - if (st->codec->channels != 1 && st->codec->channels != 2) { - av_log(s,AV_LOG_ERROR,"Channels %d not supported!\n",st->codec->channels); - return -1; - } - - st->codec->channel_layout = (st->codec->channels == 1) ? CH_LAYOUT_MONO : CH_LAYOUT_STEREO; - - st->codec->block_align = AT1_SU_SIZE * st->codec->channels; - return 0; -} - -static int aea_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); - - pkt->stream_index = 0; - if (ret <= 0) - return AVERROR(EIO); - - return ret; -} - -AVInputFormat aea_demuxer = { - "aea", - NULL_IF_CONFIG_SMALL("MD STUDIO audio"), - 0, - aea_read_probe, - aea_read_header, - aea_read_packet, - 0, - pcm_read_seek, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "aea", -}; - diff --git a/tizen/distrib/ffmpeg/libavformat/aiff.h b/tizen/distrib/ffmpeg/libavformat/aiff.h deleted file mode 100644 index 047f81d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/aiff.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * AIFF/AIFF-C muxer/demuxer common header - * Copyright (c) 2006 Patrick Guimond - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * common header for AIFF muxer and demuxer - */ - -#ifndef AVFORMAT_AIFF_H -#define AVFORMAT_AIFF_H - -#include "avformat.h" -#include "riff.h" - -static const AVCodecTag ff_codec_aiff_tags[] = { - { CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_S8, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') }, - { CODEC_ID_PCM_F32BE, MKTAG('f','l','3','2') }, - { CODEC_ID_PCM_F64BE, MKTAG('f','l','6','4') }, - { CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, - { CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, - { CODEC_ID_MACE3, MKTAG('M','A','C','3') }, - { CODEC_ID_MACE6, MKTAG('M','A','C','6') }, - { CODEC_ID_GSM, MKTAG('G','S','M',' ') }, - { CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') }, - { CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, - { CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, - { CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, - { CODEC_ID_QCELP, MKTAG('Q','c','l','p') }, - { CODEC_ID_NONE, 0 }, -}; - -#endif /* AVFORMAT_AIFF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/aiffdec.c b/tizen/distrib/ffmpeg/libavformat/aiffdec.c deleted file mode 100644 index f72af00..0000000 --- a/tizen/distrib/ffmpeg/libavformat/aiffdec.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * AIFF/AIFF-C demuxer - * Copyright (c) 2006 Patrick Guimond - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intfloat_readwrite.h" -#include "avformat.h" -#include "raw.h" -#include "aiff.h" - -#define AIFF 0 -#define AIFF_C_VERSION1 0xA2805140 - -typedef struct { - int64_t data_end; -} AIFFInputContext; - -static enum CodecID aiff_codec_get_id(int bps) -{ - if (bps <= 8) - return CODEC_ID_PCM_S8; - if (bps <= 16) - return CODEC_ID_PCM_S16BE; - if (bps <= 24) - return CODEC_ID_PCM_S24BE; - if (bps <= 32) - return CODEC_ID_PCM_S32BE; - - /* bigger than 32 isn't allowed */ - return CODEC_ID_NONE; -} - -/* returns the size of the found tag */ -static int get_tag(ByteIOContext *pb, uint32_t * tag) -{ - int size; - - if (url_feof(pb)) - return AVERROR(EIO); - - *tag = get_le32(pb); - size = get_be32(pb); - - if (size < 0) - size = 0x7fffffff; - - return size; -} - -/* Metadata string read */ -static void get_meta(AVFormatContext *s, const char *key, int size) -{ - uint8_t *str = av_malloc(size+1); - int res; - - if (!str) { - url_fskip(s->pb, size); - return; - } - - res = get_buffer(s->pb, str, size); - if (res < 0) - return; - - str[res] = 0; - av_metadata_set2(&s->metadata, key, str, AV_METADATA_DONT_STRDUP_VAL); -} - -/* Returns the number of sound data frames or negative on error */ -static unsigned int get_aiff_header(ByteIOContext *pb, AVCodecContext *codec, - int size, unsigned version) -{ - AVExtFloat ext; - double sample_rate; - unsigned int num_frames; - - if (size & 1) - size++; - codec->codec_type = AVMEDIA_TYPE_AUDIO; - codec->channels = get_be16(pb); - num_frames = get_be32(pb); - codec->bits_per_coded_sample = get_be16(pb); - - get_buffer(pb, (uint8_t*)&ext, sizeof(ext));/* Sample rate is in */ - sample_rate = av_ext2dbl(ext); /* 80 bits BE IEEE extended float */ - codec->sample_rate = sample_rate; - size -= 18; - - /* Got an AIFF-C? */ - if (version == AIFF_C_VERSION1) { - codec->codec_tag = get_le32(pb); - codec->codec_id = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag); - - switch (codec->codec_id) { - case CODEC_ID_PCM_S16BE: - codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample); - codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id); - break; - case CODEC_ID_ADPCM_IMA_QT: - codec->block_align = 34*codec->channels; - codec->frame_size = 64; - break; - case CODEC_ID_MACE3: - codec->block_align = 2*codec->channels; - codec->frame_size = 6; - break; - case CODEC_ID_MACE6: - codec->block_align = 1*codec->channels; - codec->frame_size = 6; - break; - case CODEC_ID_GSM: - codec->block_align = 33; - codec->frame_size = 160; - break; - case CODEC_ID_QCELP: - codec->block_align = 35; - codec->frame_size= 160; - break; - default: - break; - } - size -= 4; - } else { - /* Need the codec type */ - codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample); - codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id); - } - - /* Block align needs to be computed in all cases, as the definition - * is specific to applications -> here we use the WAVE format definition */ - if (!codec->block_align) - codec->block_align = (codec->bits_per_coded_sample * codec->channels) >> 3; - - codec->bit_rate = (codec->frame_size ? codec->sample_rate/codec->frame_size : - codec->sample_rate) * (codec->block_align << 3); - - /* Chunk is over */ - if (size) - url_fseek(pb, size, SEEK_CUR); - - return num_frames; -} - -static int aiff_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf[0] == 'F' && p->buf[1] == 'O' && - p->buf[2] == 'R' && p->buf[3] == 'M' && - p->buf[8] == 'A' && p->buf[9] == 'I' && - p->buf[10] == 'F' && (p->buf[11] == 'F' || p->buf[11] == 'C')) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* aiff input */ -static int aiff_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - int size, filesize; - int64_t offset = 0; - uint32_t tag; - unsigned version = AIFF_C_VERSION1; - ByteIOContext *pb = s->pb; - AVStream * st; - AIFFInputContext *aiff = s->priv_data; - - /* check FORM header */ - filesize = get_tag(pb, &tag); - if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M')) - return AVERROR_INVALIDDATA; - - /* AIFF data type */ - tag = get_le32(pb); - if (tag == MKTAG('A', 'I', 'F', 'F')) /* Got an AIFF file */ - version = AIFF; - else if (tag != MKTAG('A', 'I', 'F', 'C')) /* An AIFF-C file then */ - return AVERROR_INVALIDDATA; - - filesize -= 4; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - while (filesize > 0) { - /* parse different chunks */ - size = get_tag(pb, &tag); - if (size < 0) - return size; - - filesize -= size + 8; - - switch (tag) { - case MKTAG('C', 'O', 'M', 'M'): /* Common chunk */ - /* Then for the complete header info */ - st->nb_frames = get_aiff_header(pb, st->codec, size, version); - if (st->nb_frames < 0) - return st->nb_frames; - if (offset > 0) // COMM is after SSND - goto got_sound; - break; - case MKTAG('F', 'V', 'E', 'R'): /* Version chunk */ - version = get_be32(pb); - break; - case MKTAG('N', 'A', 'M', 'E'): /* Sample name chunk */ - get_meta(s, "title" , size); - break; - case MKTAG('A', 'U', 'T', 'H'): /* Author chunk */ - get_meta(s, "author" , size); - break; - case MKTAG('(', 'c', ')', ' '): /* Copyright chunk */ - get_meta(s, "copyright", size); - break; - case MKTAG('A', 'N', 'N', 'O'): /* Annotation chunk */ - get_meta(s, "comment" , size); - break; - case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ - aiff->data_end = url_ftell(pb) + size; - offset = get_be32(pb); /* Offset of sound data */ - get_be32(pb); /* BlockSize... don't care */ - offset += url_ftell(pb); /* Compute absolute data offset */ - if (st->codec->block_align) /* Assume COMM already parsed */ - goto got_sound; - if (url_is_streamed(pb)) { - av_log(s, AV_LOG_ERROR, "file is not seekable\n"); - return -1; - } - url_fskip(pb, size - 8); - break; - case MKTAG('w', 'a', 'v', 'e'): - if ((uint64_t)size > (1<<30)) - return -1; - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = size; - get_buffer(pb, st->codec->extradata, size); - break; - default: /* Jump */ - if (size & 1) /* Always even aligned */ - size++; - url_fskip (pb, size); - } - } - - if (!st->codec->block_align) { - av_log(s, AV_LOG_ERROR, "could not find COMM tag\n"); - return -1; - } - -got_sound: - /* Now positioned, get the sound data start and end */ - if (st->nb_frames) - s->file_size = st->nb_frames * st->codec->block_align; - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - st->start_time = 0; - st->duration = st->codec->frame_size ? - st->nb_frames * st->codec->frame_size : st->nb_frames; - - /* Position the stream at the first block */ - url_fseek(pb, offset, SEEK_SET); - - return 0; -} - -#define MAX_SIZE 4096 - -static int aiff_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AVStream *st = s->streams[0]; - AIFFInputContext *aiff = s->priv_data; - int64_t max_size; - int res, size; - - /* calculate size of remaining data */ - max_size = aiff->data_end - url_ftell(s->pb); - if (max_size <= 0) - return AVERROR_EOF; - - /* Now for that packet */ - if (st->codec->block_align >= 33) // GSM, QCLP, IMA4 - size = st->codec->block_align; - else - size = (MAX_SIZE / st->codec->block_align) * st->codec->block_align; - size = FFMIN(max_size, size); - res = av_get_packet(s->pb, pkt, size); - if (res < 0) - return res; - - /* Only one stream in an AIFF file */ - pkt->stream_index = 0; - return 0; -} - -AVInputFormat aiff_demuxer = { - "aiff", - NULL_IF_CONFIG_SMALL("Audio IFF"), - sizeof(AIFFInputContext), - aiff_probe, - aiff_read_header, - aiff_read_packet, - NULL, - pcm_read_seek, - .codec_tag= (const AVCodecTag* const []){ff_codec_aiff_tags, 0}, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/aiffenc.c b/tizen/distrib/ffmpeg/libavformat/aiffenc.c deleted file mode 100644 index e3c6a0b..0000000 --- a/tizen/distrib/ffmpeg/libavformat/aiffenc.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * AIFF/AIFF-C muxer - * Copyright (c) 2006 Patrick Guimond - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "aiff.h" - -typedef struct { - int64_t form; - int64_t frames; - int64_t ssnd; -} AIFFOutputContext; - -static int aiff_write_header(AVFormatContext *s) -{ - AIFFOutputContext *aiff = s->priv_data; - ByteIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - AVExtFloat sample_rate; - int aifc = 0; - - /* First verify if format is ok */ - if (!enc->codec_tag) - return -1; - if (enc->codec_tag != MKTAG('N','O','N','E')) - aifc = 1; - - /* FORM AIFF header */ - put_tag(pb, "FORM"); - aiff->form = url_ftell(pb); - put_be32(pb, 0); /* file length */ - put_tag(pb, aifc ? "AIFC" : "AIFF"); - - if (aifc) { // compressed audio - enc->bits_per_coded_sample = 16; - if (!enc->block_align) { - av_log(s, AV_LOG_ERROR, "block align not set\n"); - return -1; - } - /* Version chunk */ - put_tag(pb, "FVER"); - put_be32(pb, 4); - put_be32(pb, 0xA2805140); - } - - /* Common chunk */ - put_tag(pb, "COMM"); - put_be32(pb, aifc ? 24 : 18); /* size */ - put_be16(pb, enc->channels); /* Number of channels */ - - aiff->frames = url_ftell(pb); - put_be32(pb, 0); /* Number of frames */ - - if (!enc->bits_per_coded_sample) - enc->bits_per_coded_sample = av_get_bits_per_sample(enc->codec_id); - if (!enc->bits_per_coded_sample) { - av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n"); - return -1; - } - if (!enc->block_align) - enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3; - - put_be16(pb, enc->bits_per_coded_sample); /* Sample size */ - - sample_rate = av_dbl2ext((double)enc->sample_rate); - put_buffer(pb, (uint8_t*)&sample_rate, sizeof(sample_rate)); - - if (aifc) { - put_le32(pb, enc->codec_tag); - put_be16(pb, 0); - } - - /* Sound data chunk */ - put_tag(pb, "SSND"); - aiff->ssnd = url_ftell(pb); /* Sound chunk size */ - put_be32(pb, 0); /* Sound samples data size */ - put_be32(pb, 0); /* Data offset */ - put_be32(pb, 0); /* Block-size (block align) */ - - av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate); - - /* Data is starting here */ - put_flush_packet(pb); - - return 0; -} - -static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - put_buffer(pb, pkt->data, pkt->size); - return 0; -} - -static int aiff_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - AIFFOutputContext *aiff = s->priv_data; - AVCodecContext *enc = s->streams[0]->codec; - - /* Chunks sizes must be even */ - int64_t file_size, end_size; - end_size = file_size = url_ftell(pb); - if (file_size & 1) { - put_byte(pb, 0); - end_size++; - } - - if (!url_is_streamed(s->pb)) { - /* File length */ - url_fseek(pb, aiff->form, SEEK_SET); - put_be32(pb, file_size - aiff->form - 4); - - /* Number of sample frames */ - url_fseek(pb, aiff->frames, SEEK_SET); - put_be32(pb, (file_size-aiff->ssnd-12)/enc->block_align); - - /* Sound Data chunk size */ - url_fseek(pb, aiff->ssnd, SEEK_SET); - put_be32(pb, file_size - aiff->ssnd - 4); - - /* return to the end */ - url_fseek(pb, end_size, SEEK_SET); - - put_flush_packet(pb); - } - - return 0; -} - -AVOutputFormat aiff_muxer = { - "aiff", - NULL_IF_CONFIG_SMALL("Audio IFF"), - "audio/aiff", - "aif,aiff,afc,aifc", - sizeof(AIFFOutputContext), - CODEC_ID_PCM_S16BE, - CODEC_ID_NONE, - aiff_write_header, - aiff_write_packet, - aiff_write_trailer, - .codec_tag= (const AVCodecTag* const []){ff_codec_aiff_tags, 0}, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/allformats.c b/tizen/distrib/ffmpeg/libavformat/allformats.c deleted file mode 100644 index 27a9555..0000000 --- a/tizen/distrib/ffmpeg/libavformat/allformats.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Register all the formats and protocols - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "rtp.h" -#include "rdt.h" - -#define REGISTER_MUXER(X,x) { \ - extern AVOutputFormat x##_muxer; \ - if(CONFIG_##X##_MUXER) av_register_output_format(&x##_muxer); } - -#define REGISTER_DEMUXER(X,x) { \ - extern AVInputFormat x##_demuxer; \ - if(CONFIG_##X##_DEMUXER) av_register_input_format(&x##_demuxer); } - -#define REGISTER_MUXDEMUX(X,x) REGISTER_MUXER(X,x); REGISTER_DEMUXER(X,x) - -#define REGISTER_PROTOCOL(X,x) { \ - extern URLProtocol x##_protocol; \ - if(CONFIG_##X##_PROTOCOL) av_register_protocol(&x##_protocol); } - -void av_register_all(void) -{ - static int initialized; - - if (initialized) - return; - initialized = 1; - - avcodec_register_all(); - - /* (de)muxers */ - REGISTER_DEMUXER (AAC, aac); - REGISTER_MUXDEMUX (AC3, ac3); - REGISTER_MUXER (ADTS, adts); - REGISTER_DEMUXER (AEA, aea); - REGISTER_MUXDEMUX (AIFF, aiff); - REGISTER_MUXDEMUX (AMR, amr); - REGISTER_DEMUXER (ANM, anm); - REGISTER_DEMUXER (APC, apc); - REGISTER_DEMUXER (APE, ape); - REGISTER_MUXDEMUX (ASF, asf); - REGISTER_MUXDEMUX (ASS, ass); - REGISTER_MUXER (ASF_STREAM, asf_stream); - REGISTER_MUXDEMUX (AU, au); - REGISTER_MUXDEMUX (AVI, avi); - REGISTER_DEMUXER (AVISYNTH, avisynth); - REGISTER_MUXER (AVM2, avm2); - REGISTER_DEMUXER (AVS, avs); - REGISTER_DEMUXER (BETHSOFTVID, bethsoftvid); - REGISTER_DEMUXER (BFI, bfi); - REGISTER_DEMUXER (BINK, bink); - REGISTER_DEMUXER (C93, c93); - REGISTER_DEMUXER (CAF, caf); - REGISTER_DEMUXER (CAVSVIDEO, cavsvideo); - REGISTER_DEMUXER (CDG, cdg); - REGISTER_MUXER (CRC, crc); - REGISTER_MUXDEMUX (DAUD, daud); - REGISTER_MUXDEMUX (DIRAC, dirac); - REGISTER_MUXDEMUX (DNXHD, dnxhd); - REGISTER_DEMUXER (DSICIN, dsicin); - REGISTER_MUXDEMUX (DTS, dts); - REGISTER_MUXDEMUX (DV, dv); - REGISTER_DEMUXER (DXA, dxa); - REGISTER_DEMUXER (EA, ea); - REGISTER_DEMUXER (EA_CDATA, ea_cdata); - REGISTER_MUXDEMUX (EAC3, eac3); - REGISTER_MUXDEMUX (FFM, ffm); - REGISTER_MUXDEMUX (FILMSTRIP, filmstrip); - REGISTER_MUXDEMUX (FLAC, flac); - REGISTER_DEMUXER (FLIC, flic); - REGISTER_MUXDEMUX (FLV, flv); - REGISTER_DEMUXER (FOURXM, fourxm); - REGISTER_MUXER (FRAMECRC, framecrc); - REGISTER_MUXER (GIF, gif); - REGISTER_DEMUXER (GSM, gsm); - REGISTER_MUXDEMUX (GXF, gxf); - REGISTER_MUXDEMUX (H261, h261); - REGISTER_MUXDEMUX (H263, h263); - REGISTER_MUXDEMUX (H264, h264); - REGISTER_DEMUXER (IDCIN, idcin); - REGISTER_DEMUXER (IFF, iff); - REGISTER_MUXDEMUX (IMAGE2, image2); - REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe); - REGISTER_DEMUXER (INGENIENT, ingenient); - REGISTER_DEMUXER (IPMOVIE, ipmovie); - REGISTER_MUXER (IPOD, ipod); - REGISTER_DEMUXER (ISS, iss); - REGISTER_DEMUXER (IV8, iv8); - REGISTER_DEMUXER (LMLM4, lmlm4); - REGISTER_MUXDEMUX (M4V, m4v); - REGISTER_MUXDEMUX (MATROSKA, matroska); - REGISTER_MUXER (MATROSKA_AUDIO, matroska_audio); - REGISTER_MUXDEMUX (MJPEG, mjpeg); - REGISTER_MUXDEMUX (MLP, mlp); - REGISTER_DEMUXER (MM, mm); - REGISTER_MUXDEMUX (MMF, mmf); - REGISTER_MUXDEMUX (MOV, mov); - REGISTER_MUXER (MP2, mp2); - REGISTER_MUXDEMUX (MP3, mp3); - REGISTER_MUXER (MP4, mp4); - REGISTER_DEMUXER (MPC, mpc); - REGISTER_DEMUXER (MPC8, mpc8); - REGISTER_MUXER (MPEG1SYSTEM, mpeg1system); - REGISTER_MUXER (MPEG1VCD, mpeg1vcd); - REGISTER_MUXER (MPEG1VIDEO, mpeg1video); - REGISTER_MUXER (MPEG2DVD, mpeg2dvd); - REGISTER_MUXER (MPEG2SVCD, mpeg2svcd); - REGISTER_MUXER (MPEG2VIDEO, mpeg2video); - REGISTER_MUXER (MPEG2VOB, mpeg2vob); - REGISTER_DEMUXER (MPEGPS, mpegps); - REGISTER_MUXDEMUX (MPEGTS, mpegts); - REGISTER_DEMUXER (MPEGTSRAW, mpegtsraw); - REGISTER_DEMUXER (MPEGVIDEO, mpegvideo); - REGISTER_MUXER (MPJPEG, mpjpeg); - REGISTER_DEMUXER (MSNWC_TCP, msnwc_tcp); - REGISTER_DEMUXER (MTV, mtv); - REGISTER_DEMUXER (MVI, mvi); - REGISTER_MUXDEMUX (MXF, mxf); - REGISTER_MUXER (MXF_D10, mxf_d10); - REGISTER_DEMUXER (NC, nc); - REGISTER_DEMUXER (NSV, nsv); - REGISTER_MUXER (NULL, null); - REGISTER_MUXDEMUX (NUT, nut); - REGISTER_DEMUXER (NUV, nuv); - REGISTER_MUXDEMUX (OGG, ogg); - REGISTER_DEMUXER (OMA, oma); - REGISTER_MUXDEMUX (PCM_ALAW, pcm_alaw); - REGISTER_MUXDEMUX (PCM_MULAW, pcm_mulaw); - REGISTER_MUXDEMUX (PCM_F64BE, pcm_f64be); - REGISTER_MUXDEMUX (PCM_F64LE, pcm_f64le); - REGISTER_MUXDEMUX (PCM_F32BE, pcm_f32be); - REGISTER_MUXDEMUX (PCM_F32LE, pcm_f32le); - REGISTER_MUXDEMUX (PCM_S32BE, pcm_s32be); - REGISTER_MUXDEMUX (PCM_S32LE, pcm_s32le); - REGISTER_MUXDEMUX (PCM_S24BE, pcm_s24be); - REGISTER_MUXDEMUX (PCM_S24LE, pcm_s24le); - REGISTER_MUXDEMUX (PCM_S16BE, pcm_s16be); - REGISTER_MUXDEMUX (PCM_S16LE, pcm_s16le); - REGISTER_MUXDEMUX (PCM_S8, pcm_s8); - REGISTER_MUXDEMUX (PCM_U32BE, pcm_u32be); - REGISTER_MUXDEMUX (PCM_U32LE, pcm_u32le); - REGISTER_MUXDEMUX (PCM_U24BE, pcm_u24be); - REGISTER_MUXDEMUX (PCM_U24LE, pcm_u24le); - REGISTER_MUXDEMUX (PCM_U16BE, pcm_u16be); - REGISTER_MUXDEMUX (PCM_U16LE, pcm_u16le); - REGISTER_MUXDEMUX (PCM_U8, pcm_u8); - REGISTER_MUXER (PSP, psp); - REGISTER_DEMUXER (PVA, pva); - REGISTER_DEMUXER (QCP, qcp); - REGISTER_DEMUXER (R3D, r3d); - REGISTER_MUXDEMUX (RAWVIDEO, rawvideo); - REGISTER_DEMUXER (RL2, rl2); - REGISTER_MUXDEMUX (RM, rm); - REGISTER_MUXDEMUX (ROQ, roq); - REGISTER_DEMUXER (RPL, rpl); - REGISTER_MUXER (RTP, rtp); - REGISTER_MUXDEMUX (RTSP, rtsp); - REGISTER_DEMUXER (SDP, sdp); -#if CONFIG_SDP_DEMUXER - av_register_rtp_dynamic_payload_handlers(); - av_register_rdt_dynamic_payload_handlers(); -#endif - REGISTER_DEMUXER (SEGAFILM, segafilm); - REGISTER_DEMUXER (SHORTEN, shorten); - REGISTER_DEMUXER (SIFF, siff); - REGISTER_DEMUXER (SMACKER, smacker); - REGISTER_DEMUXER (SOL, sol); - REGISTER_MUXDEMUX (SOX, sox); - REGISTER_MUXER (SPDIF, spdif); - REGISTER_DEMUXER (STR, str); - REGISTER_MUXDEMUX (SWF, swf); - REGISTER_MUXER (TG2, tg2); - REGISTER_MUXER (TGP, tgp); - REGISTER_DEMUXER (THP, thp); - REGISTER_DEMUXER (TIERTEXSEQ, tiertexseq); - REGISTER_DEMUXER (TMV, tmv); - REGISTER_MUXDEMUX (TRUEHD, truehd); - REGISTER_DEMUXER (TTA, tta); - REGISTER_DEMUXER (TXD, txd); - REGISTER_DEMUXER (VC1, vc1); - REGISTER_MUXDEMUX (VC1T, vc1t); - REGISTER_DEMUXER (VMD, vmd); - REGISTER_MUXDEMUX (VOC, voc); - REGISTER_DEMUXER (VQF, vqf); - REGISTER_DEMUXER (W64, w64); - REGISTER_MUXDEMUX (WAV, wav); - REGISTER_DEMUXER (WC3, wc3); - REGISTER_MUXER (WEBM, webm); - REGISTER_DEMUXER (WSAUD, wsaud); - REGISTER_DEMUXER (WSVQA, wsvqa); - REGISTER_DEMUXER (WV, wv); - REGISTER_DEMUXER (XA, xa); - REGISTER_DEMUXER (YOP, yop); - REGISTER_MUXDEMUX (YUV4MPEGPIPE, yuv4mpegpipe); - - /* external libraries */ - REGISTER_MUXDEMUX (LIBNUT, libnut); - - /* protocols */ - REGISTER_PROTOCOL (FILE, file); - REGISTER_PROTOCOL (GOPHER, gopher); - REGISTER_PROTOCOL (HTTP, http); - REGISTER_PROTOCOL (PIPE, pipe); - REGISTER_PROTOCOL (RTMP, rtmp); -#if CONFIG_LIBRTMP - REGISTER_PROTOCOL (RTMP, rtmpt); - REGISTER_PROTOCOL (RTMP, rtmpe); - REGISTER_PROTOCOL (RTMP, rtmpte); - REGISTER_PROTOCOL (RTMP, rtmps); -#endif - REGISTER_PROTOCOL (RTP, rtp); - REGISTER_PROTOCOL (TCP, tcp); - REGISTER_PROTOCOL (UDP, udp); - REGISTER_PROTOCOL (CONCAT, concat); -} diff --git a/tizen/distrib/ffmpeg/libavformat/amr.c b/tizen/distrib/ffmpeg/libavformat/amr.c deleted file mode 100644 index d16b4c0..0000000 --- a/tizen/distrib/ffmpeg/libavformat/amr.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * amr file format - * Copyright (c) 2001 ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* -Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.txt?number=3267 - -Only mono files are supported. - -*/ -#include "avformat.h" - -static const char AMR_header [] = "#!AMR\n"; -static const char AMRWB_header [] = "#!AMR-WB\n"; - -#if CONFIG_AMR_MUXER -static int amr_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - - s->priv_data = NULL; - - if (enc->codec_id == CODEC_ID_AMR_NB) - { - put_tag(pb, AMR_header); /* magic number */ - } - else if(enc->codec_id == CODEC_ID_AMR_WB) - { - put_tag(pb, AMRWB_header); /* magic number */ - } - else - { - return -1; - } - put_flush_packet(pb); - return 0; -} - -static int amr_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - put_buffer(s->pb, pkt->data, pkt->size); - put_flush_packet(s->pb); - return 0; -} -#endif /* CONFIG_AMR_MUXER */ - -static int amr_probe(AVProbeData *p) -{ - //Only check for "#!AMR" which could be amr-wb, amr-nb. - //This will also trigger multichannel files: "#!AMR_MC1.0\n" and - //"#!AMR-WB_MC1.0\n" (not supported) - - if(memcmp(p->buf,AMR_header,5)==0) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* amr input */ -static int amr_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - AVStream *st; - uint8_t header[9]; - - get_buffer(pb, header, 6); - - st = av_new_stream(s, 0); - if (!st) - { - return AVERROR(ENOMEM); - } - if(memcmp(header,AMR_header,6)!=0) - { - get_buffer(pb, header+6, 3); - if(memcmp(header,AMRWB_header,9)!=0) - { - return -1; - } - - st->codec->codec_tag = MKTAG('s', 'a', 'w', 'b'); - st->codec->codec_id = CODEC_ID_AMR_WB; - st->codec->sample_rate = 16000; - } - else - { - st->codec->codec_tag = MKTAG('s', 'a', 'm', 'r'); - st->codec->codec_id = CODEC_ID_AMR_NB; - st->codec->sample_rate = 8000; - } - st->codec->channels = 1; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -static int amr_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AVCodecContext *enc = s->streams[0]->codec; - int read, size = 0, toc, mode; - - if (url_feof(s->pb)) - { - return AVERROR(EIO); - } - -//FIXME this is wrong, this should rather be in a AVParset - toc=get_byte(s->pb); - mode = (toc >> 3) & 0x0F; - - if (enc->codec_id == CODEC_ID_AMR_NB) - { - static const uint8_t packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; - - size=packed_size[mode]+1; - } - else if(enc->codec_id == CODEC_ID_AMR_WB) - { - static uint8_t packed_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1}; - - size=packed_size[mode]; - } - else - { - assert(0); - } - - if ( (size==0) || av_new_packet(pkt, size)) - { - return AVERROR(EIO); - } - - pkt->stream_index = 0; - pkt->pos= url_ftell(s->pb); - pkt->data[0]=toc; - pkt->duration= enc->codec_id == CODEC_ID_AMR_NB ? 160 : 320; - read = get_buffer(s->pb, pkt->data+1, size-1); - - if (read != size-1) - { - av_free_packet(pkt); - return AVERROR(EIO); - } - - return 0; -} - -#if CONFIG_AMR_DEMUXER -AVInputFormat amr_demuxer = { - "amr", - NULL_IF_CONFIG_SMALL("3GPP AMR file format"), - 0, /*priv_data_size*/ - amr_probe, - amr_read_header, - amr_read_packet, - NULL, -}; -#endif - -#if CONFIG_AMR_MUXER -AVOutputFormat amr_muxer = { - "amr", - NULL_IF_CONFIG_SMALL("3GPP AMR file format"), - "audio/amr", - "amr", - 0, - CODEC_ID_AMR_NB, - CODEC_ID_NONE, - amr_write_header, - amr_write_packet, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/anm.c b/tizen/distrib/ffmpeg/libavformat/anm.c deleted file mode 100644 index ba77e18..0000000 --- a/tizen/distrib/ffmpeg/libavformat/anm.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Deluxe Paint Animation demuxer - * Copyright (c) 2009 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Deluxe Paint Animation demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -typedef struct { - int base_record; - unsigned int nb_records; - int size; -} Page; - -typedef struct { - unsigned int nb_pages; /** total pages in file */ - unsigned int nb_records; /** total records in file */ - int page_table_offset; -#define MAX_PAGES 256 /** Deluxe Paint hardcoded value */ - Page pt[MAX_PAGES]; /** page table */ - int page; /** current page (or AVERROR_xxx code) */ - int record; /** current record (with in page) */ -} AnmDemuxContext; - -#define LPF_TAG MKTAG('L','P','F',' ') -#define ANIM_TAG MKTAG('A','N','I','M') - -static int probe(AVProbeData *p) -{ - /* verify tags and video dimensions */ - if (AV_RL32(&p->buf[0]) == LPF_TAG && - AV_RL32(&p->buf[16]) == ANIM_TAG && - AV_RL16(&p->buf[20]) && AV_RL16(&p->buf[22])) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** - * @return page containing the requested record or AVERROR_XXX - */ -static int find_record(const AnmDemuxContext *anm, int record) -{ - int i; - - if (record >= anm->nb_records) - return AVERROR_EOF; - - for (i = 0; i < MAX_PAGES; i++) { - const Page *p = &anm->pt[i]; - if (p->nb_records > 0 && record >= p->base_record && record < p->base_record + p->nb_records) - return i; - } - - return AVERROR_INVALIDDATA; -} - -static int read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AnmDemuxContext *anm = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - int i, ret; - - url_fskip(pb, 4); /* magic number */ - if (get_le16(pb) != MAX_PAGES) { - av_log_ask_for_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES) "\n"); - return AVERROR_INVALIDDATA; - } - - anm->nb_pages = get_le16(pb); - anm->nb_records = get_le32(pb); - url_fskip(pb, 2); /* max records per page */ - anm->page_table_offset = get_le16(pb); - if (get_le32(pb) != ANIM_TAG) - return AVERROR_INVALIDDATA; - - /* video stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_ANM; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = get_le16(pb); - st->codec->height = get_le16(pb); - if (get_byte(pb) != 0) - goto invalid; - url_fskip(pb, 1); /* frame rate multiplier info */ - - /* ignore last delta record (used for looping) */ - if (get_byte(pb)) /* has_last_delta */ - anm->nb_records = FFMAX(anm->nb_records - 1, 0); - - url_fskip(pb, 1); /* last_delta_valid */ - - if (get_byte(pb) != 0) - goto invalid; - - if (get_byte(pb) != 1) - goto invalid; - - url_fskip(pb, 1); /* other recs per frame */ - - if (get_byte(pb) != 1) - goto invalid; - - url_fskip(pb, 32); /* record_types */ - st->nb_frames = get_le32(pb); - av_set_pts_info(st, 64, 1, get_le16(pb)); - url_fskip(pb, 58); - - /* color cycling and palette data */ - st->codec->extradata_size = 16*8 + 4*256; - st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - ret = AVERROR(ENOMEM); - goto close_and_return; - } - ret = get_buffer(pb, st->codec->extradata, st->codec->extradata_size); - if (ret < 0) - goto close_and_return; - - /* read page table */ - ret = url_fseek(pb, anm->page_table_offset, SEEK_SET); - if (ret < 0) - goto close_and_return; - - for (i = 0; i < MAX_PAGES; i++) { - Page *p = &anm->pt[i]; - p->base_record = get_le16(pb); - p->nb_records = get_le16(pb); - p->size = get_le16(pb); - } - - /* find page of first frame */ - anm->page = find_record(anm, 0); - if (anm->page < 0) { - ret = anm->page; - goto close_and_return; - } - - anm->record = -1; - return 0; - -invalid: - av_log_ask_for_sample(s, NULL); - ret = AVERROR_INVALIDDATA; - -close_and_return: - av_close_input_stream(s); - return ret; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AnmDemuxContext *anm = s->priv_data; - ByteIOContext *pb = s->pb; - Page *p; - int tmp, record_size; - - if (url_feof(s->pb)) - return AVERROR(EIO); - - if (anm->page < 0) - return anm->page; - -repeat: - p = &anm->pt[anm->page]; - - /* parse page header */ - if (anm->record < 0) { - url_fseek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16), SEEK_SET); - url_fskip(pb, 8 + 2*p->nb_records); - anm->record = 0; - } - - /* if we have fetched all records in this page, then find the - next page and repeat */ - if (anm->record >= p->nb_records) { - anm->page = find_record(anm, p->base_record + p->nb_records); - if (anm->page < 0) - return anm->page; - anm->record = -1; - goto repeat; - } - - /* fetch record size */ - tmp = url_ftell(pb); - url_fseek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16) + - 8 + anm->record * 2, SEEK_SET); - record_size = get_le16(pb); - url_fseek(pb, tmp, SEEK_SET); - - /* fetch record */ - pkt->size = av_get_packet(s->pb, pkt, record_size); - if (pkt->size < 0) - return pkt->size; - if (p->base_record + anm->record == 0) - pkt->flags |= AV_PKT_FLAG_KEY; - - anm->record++; - return 0; -} - -AVInputFormat anm_demuxer = { - "anm", - NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"), - sizeof(AnmDemuxContext), - probe, - read_header, - read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/apc.c b/tizen/distrib/ffmpeg/libavformat/apc.c deleted file mode 100644 index 9b4a8ad..0000000 --- a/tizen/distrib/ffmpeg/libavformat/apc.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * CRYO APC audio format demuxer - * Copyright (c) 2007 Anssi Hannula - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avformat.h" - -static int apc_probe(AVProbeData *p) -{ - if (!strncmp(p->buf, "CRYO_APC", 8)) - return AVPROBE_SCORE_MAX; - - return 0; -} - -static int apc_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - AVStream *st; - - get_le32(pb); /* CRYO */ - get_le32(pb); /* _APC */ - get_le32(pb); /* 1.20 */ - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; - - get_le32(pb); /* number of samples */ - st->codec->sample_rate = get_le32(pb); - - st->codec->extradata_size = 2 * 4; - st->codec->extradata = av_malloc(st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - - /* initial predictor values for adpcm decoder */ - get_buffer(pb, st->codec->extradata, 2 * 4); - - st->codec->channels = 1; - if (get_le32(pb)) - st->codec->channels = 2; - - st->codec->bits_per_coded_sample = 4; - st->codec->bit_rate = st->codec->bits_per_coded_sample * st->codec->channels - * st->codec->sample_rate; - st->codec->block_align = 1; - - return 0; -} - -#define MAX_READ_SIZE 4096 - -static int apc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - if (av_get_packet(s->pb, pkt, MAX_READ_SIZE) <= 0) - return AVERROR(EIO); - pkt->stream_index = 0; - return 0; -} - -AVInputFormat apc_demuxer = { - "apc", - NULL_IF_CONFIG_SMALL("CRYO APC format"), - 0, - apc_probe, - apc_read_header, - apc_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/ape.c b/tizen/distrib/ffmpeg/libavformat/ape.c deleted file mode 100644 index 91acf72..0000000 --- a/tizen/distrib/ffmpeg/libavformat/ape.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Monkey's Audio APE demuxer - * Copyright (c) 2007 Benjamin Zores - * based upon libdemac from Dave Chapman. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "apetag.h" - -#define ENABLE_DEBUG 0 - -/* The earliest and latest file formats supported by this library */ -#define APE_MIN_VERSION 3950 -#define APE_MAX_VERSION 3990 - -#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE] -#define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE] -#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE] -#define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE] -#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level -#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored) - -#define MAC_SUBFRAME_SIZE 4608 - -#define APE_EXTRADATA_SIZE 6 - -typedef struct { - int64_t pos; - int nblocks; - int size; - int skip; - int64_t pts; -} APEFrame; - -typedef struct { - /* Derived fields */ - uint32_t junklength; - uint32_t firstframe; - uint32_t totalsamples; - int currentframe; - APEFrame *frames; - - /* Info from Descriptor Block */ - char magic[4]; - int16_t fileversion; - int16_t padding1; - uint32_t descriptorlength; - uint32_t headerlength; - uint32_t seektablelength; - uint32_t wavheaderlength; - uint32_t audiodatalength; - uint32_t audiodatalength_high; - uint32_t wavtaillength; - uint8_t md5[16]; - - /* Info from Header Block */ - uint16_t compressiontype; - uint16_t formatflags; - uint32_t blocksperframe; - uint32_t finalframeblocks; - uint32_t totalframes; - uint16_t bps; - uint16_t channels; - uint32_t samplerate; - - /* Seektable */ - uint32_t *seektable; -} APEContext; - -static int ape_probe(AVProbeData * p) -{ - if (p->buf[0] == 'M' && p->buf[1] == 'A' && p->buf[2] == 'C' && p->buf[3] == ' ') - return AVPROBE_SCORE_MAX; - - return 0; -} - -static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) -{ -#if ENABLE_DEBUG - int i; - - av_log(s, AV_LOG_DEBUG, "Descriptor Block:\n\n"); - av_log(s, AV_LOG_DEBUG, "magic = \"%c%c%c%c\"\n", ape_ctx->magic[0], ape_ctx->magic[1], ape_ctx->magic[2], ape_ctx->magic[3]); - av_log(s, AV_LOG_DEBUG, "fileversion = %d\n", ape_ctx->fileversion); - av_log(s, AV_LOG_DEBUG, "descriptorlength = %d\n", ape_ctx->descriptorlength); - av_log(s, AV_LOG_DEBUG, "headerlength = %d\n", ape_ctx->headerlength); - av_log(s, AV_LOG_DEBUG, "seektablelength = %d\n", ape_ctx->seektablelength); - av_log(s, AV_LOG_DEBUG, "wavheaderlength = %d\n", ape_ctx->wavheaderlength); - av_log(s, AV_LOG_DEBUG, "audiodatalength = %d\n", ape_ctx->audiodatalength); - av_log(s, AV_LOG_DEBUG, "audiodatalength_high = %d\n", ape_ctx->audiodatalength_high); - av_log(s, AV_LOG_DEBUG, "wavtaillength = %d\n", ape_ctx->wavtaillength); - av_log(s, AV_LOG_DEBUG, "md5 = "); - for (i = 0; i < 16; i++) - av_log(s, AV_LOG_DEBUG, "%02x", ape_ctx->md5[i]); - av_log(s, AV_LOG_DEBUG, "\n"); - - av_log(s, AV_LOG_DEBUG, "\nHeader Block:\n\n"); - - av_log(s, AV_LOG_DEBUG, "compressiontype = %d\n", ape_ctx->compressiontype); - av_log(s, AV_LOG_DEBUG, "formatflags = %d\n", ape_ctx->formatflags); - av_log(s, AV_LOG_DEBUG, "blocksperframe = %d\n", ape_ctx->blocksperframe); - av_log(s, AV_LOG_DEBUG, "finalframeblocks = %d\n", ape_ctx->finalframeblocks); - av_log(s, AV_LOG_DEBUG, "totalframes = %d\n", ape_ctx->totalframes); - av_log(s, AV_LOG_DEBUG, "bps = %d\n", ape_ctx->bps); - av_log(s, AV_LOG_DEBUG, "channels = %d\n", ape_ctx->channels); - av_log(s, AV_LOG_DEBUG, "samplerate = %d\n", ape_ctx->samplerate); - - av_log(s, AV_LOG_DEBUG, "\nSeektable\n\n"); - if ((ape_ctx->seektablelength / sizeof(uint32_t)) != ape_ctx->totalframes) { - av_log(s, AV_LOG_DEBUG, "No seektable\n"); - } else { - for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) { - if (i < ape_ctx->totalframes - 1) { - av_log(s, AV_LOG_DEBUG, "%8d %d (%d bytes)\n", i, ape_ctx->seektable[i], ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]); - } else { - av_log(s, AV_LOG_DEBUG, "%8d %d\n", i, ape_ctx->seektable[i]); - } - } - } - - av_log(s, AV_LOG_DEBUG, "\nFrames\n\n"); - for (i = 0; i < ape_ctx->totalframes; i++) - av_log(s, AV_LOG_DEBUG, "%8d %8lld %8d (%d samples)\n", i, ape_ctx->frames[i].pos, ape_ctx->frames[i].size, ape_ctx->frames[i].nblocks); - - av_log(s, AV_LOG_DEBUG, "\nCalculated information:\n\n"); - av_log(s, AV_LOG_DEBUG, "junklength = %d\n", ape_ctx->junklength); - av_log(s, AV_LOG_DEBUG, "firstframe = %d\n", ape_ctx->firstframe); - av_log(s, AV_LOG_DEBUG, "totalsamples = %d\n", ape_ctx->totalsamples); -#endif -} - -static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) -{ - ByteIOContext *pb = s->pb; - APEContext *ape = s->priv_data; - AVStream *st; - uint32_t tag; - int i; - int total_blocks; - int64_t pts; - - /* TODO: Skip any leading junk such as id3v2 tags */ - ape->junklength = 0; - - tag = get_le32(pb); - if (tag != MKTAG('M', 'A', 'C', ' ')) - return -1; - - ape->fileversion = get_le16(pb); - - if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) { - av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10); - return -1; - } - - if (ape->fileversion >= 3980) { - ape->padding1 = get_le16(pb); - ape->descriptorlength = get_le32(pb); - ape->headerlength = get_le32(pb); - ape->seektablelength = get_le32(pb); - ape->wavheaderlength = get_le32(pb); - ape->audiodatalength = get_le32(pb); - ape->audiodatalength_high = get_le32(pb); - ape->wavtaillength = get_le32(pb); - get_buffer(pb, ape->md5, 16); - - /* Skip any unknown bytes at the end of the descriptor. - This is for future compatibility */ - if (ape->descriptorlength > 52) - url_fseek(pb, ape->descriptorlength - 52, SEEK_CUR); - - /* Read header data */ - ape->compressiontype = get_le16(pb); - ape->formatflags = get_le16(pb); - ape->blocksperframe = get_le32(pb); - ape->finalframeblocks = get_le32(pb); - ape->totalframes = get_le32(pb); - ape->bps = get_le16(pb); - ape->channels = get_le16(pb); - ape->samplerate = get_le32(pb); - } else { - ape->descriptorlength = 0; - ape->headerlength = 32; - - ape->compressiontype = get_le16(pb); - ape->formatflags = get_le16(pb); - ape->channels = get_le16(pb); - ape->samplerate = get_le32(pb); - ape->wavheaderlength = get_le32(pb); - ape->wavtaillength = get_le32(pb); - ape->totalframes = get_le32(pb); - ape->finalframeblocks = get_le32(pb); - - if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) { - url_fseek(pb, 4, SEEK_CUR); /* Skip the peak level */ - ape->headerlength += 4; - } - - if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) { - ape->seektablelength = get_le32(pb); - ape->headerlength += 4; - ape->seektablelength *= sizeof(int32_t); - } else - ape->seektablelength = ape->totalframes * sizeof(int32_t); - - if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT) - ape->bps = 8; - else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT) - ape->bps = 24; - else - ape->bps = 16; - - if (ape->fileversion >= 3950) - ape->blocksperframe = 73728 * 4; - else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800 && ape->compressiontype >= 4000)) - ape->blocksperframe = 73728; - else - ape->blocksperframe = 9216; - - /* Skip any stored wav header */ - if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) - url_fskip(pb, ape->wavheaderlength); - } - - if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){ - av_log(s, AV_LOG_ERROR, "Too many frames: %d\n", ape->totalframes); - return -1; - } - ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame)); - if(!ape->frames) - return AVERROR(ENOMEM); - ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength; - ape->currentframe = 0; - - - ape->totalsamples = ape->finalframeblocks; - if (ape->totalframes > 1) - ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); - - if (ape->seektablelength > 0) { - ape->seektable = av_malloc(ape->seektablelength); - for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) - ape->seektable[i] = get_le32(pb); - } - - ape->frames[0].pos = ape->firstframe; - ape->frames[0].nblocks = ape->blocksperframe; - ape->frames[0].skip = 0; - for (i = 1; i < ape->totalframes; i++) { - ape->frames[i].pos = ape->seektable[i]; //ape->frames[i-1].pos + ape->blocksperframe; - ape->frames[i].nblocks = ape->blocksperframe; - ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; - ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; - } - ape->frames[ape->totalframes - 1].size = ape->finalframeblocks * 4; - ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; - - for (i = 0; i < ape->totalframes; i++) { - if(ape->frames[i].skip){ - ape->frames[i].pos -= ape->frames[i].skip; - ape->frames[i].size += ape->frames[i].skip; - } - ape->frames[i].size = (ape->frames[i].size + 3) & ~3; - } - - - ape_dumpinfo(s, ape); - - /* try to read APE tags */ - if (!url_is_streamed(pb)) { - ff_ape_parse_tag(s); - url_fseek(pb, 0, SEEK_SET); - } - - av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype); - - /* now we are ready: build format streams */ - st = av_new_stream(s, 0); - if (!st) - return -1; - - total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_APE; - st->codec->codec_tag = MKTAG('A', 'P', 'E', ' '); - st->codec->channels = ape->channels; - st->codec->sample_rate = ape->samplerate; - st->codec->bits_per_coded_sample = ape->bps; - st->codec->frame_size = MAC_SUBFRAME_SIZE; - - st->nb_frames = ape->totalframes; - st->start_time = 0; - st->duration = total_blocks / MAC_SUBFRAME_SIZE; - av_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate); - - st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE); - st->codec->extradata_size = APE_EXTRADATA_SIZE; - AV_WL16(st->codec->extradata + 0, ape->fileversion); - AV_WL16(st->codec->extradata + 2, ape->compressiontype); - AV_WL16(st->codec->extradata + 4, ape->formatflags); - - pts = 0; - for (i = 0; i < ape->totalframes; i++) { - ape->frames[i].pts = pts; - av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME); - pts += ape->blocksperframe / MAC_SUBFRAME_SIZE; - } - - return 0; -} - -static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) -{ - int ret; - int nblocks; - APEContext *ape = s->priv_data; - uint32_t extra_size = 8; - - if (url_feof(s->pb)) - return AVERROR(EIO); - if (ape->currentframe > ape->totalframes) - return AVERROR(EIO); - - url_fseek (s->pb, ape->frames[ape->currentframe].pos, SEEK_SET); - - /* Calculate how many blocks there are in this frame */ - if (ape->currentframe == (ape->totalframes - 1)) - nblocks = ape->finalframeblocks; - else - nblocks = ape->blocksperframe; - - if (av_new_packet(pkt, ape->frames[ape->currentframe].size + extra_size) < 0) - return AVERROR(ENOMEM); - - AV_WL32(pkt->data , nblocks); - AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip); - ret = get_buffer(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size); - - pkt->pts = ape->frames[ape->currentframe].pts; - pkt->stream_index = 0; - - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret + extra_size; - - ape->currentframe++; - - return 0; -} - -static int ape_read_close(AVFormatContext * s) -{ - APEContext *ape = s->priv_data; - - av_freep(&ape->frames); - av_freep(&ape->seektable); - return 0; -} - -static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - APEContext *ape = s->priv_data; - int index = av_index_search_timestamp(st, timestamp, flags); - - if (index < 0) - return -1; - - ape->currentframe = index; - return 0; -} - -AVInputFormat ape_demuxer = { - "ape", - NULL_IF_CONFIG_SMALL("Monkey's Audio"), - sizeof(APEContext), - ape_probe, - ape_read_header, - ape_read_packet, - ape_read_close, - ape_read_seek, - .extensions = "ape,apl,mac" -}; diff --git a/tizen/distrib/ffmpeg/libavformat/apetag.c b/tizen/distrib/ffmpeg/libavformat/apetag.c deleted file mode 100644 index d30c132..0000000 --- a/tizen/distrib/ffmpeg/libavformat/apetag.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * APE tag handling - * Copyright (c) 2007 Benjamin Zores - * based upon libdemac from Dave Chapman. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "apetag.h" - -#define ENABLE_DEBUG 0 - -#define APE_TAG_VERSION 2000 -#define APE_TAG_FOOTER_BYTES 32 -#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31) -#define APE_TAG_FLAG_IS_HEADER (1 << 29) - -static int ape_tag_read_field(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - uint8_t key[1024], *value; - uint32_t size, flags; - int i, c; - - size = get_le32(pb); /* field size */ - flags = get_le32(pb); /* field flags */ - for (i = 0; i < sizeof(key) - 1; i++) { - c = get_byte(pb); - if (c < 0x20 || c > 0x7E) - break; - else - key[i] = c; - } - key[i] = 0; - if (c != 0) { - av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key); - return -1; - } - if (size >= UINT_MAX) - return -1; - value = av_malloc(size+1); - if (!value) - return AVERROR(ENOMEM); - get_buffer(pb, value, size); - value[size] = 0; - av_metadata_set2(&s->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL); - return 0; -} - -void ff_ape_parse_tag(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - int file_size = url_fsize(pb); - uint32_t val, fields, tag_bytes; - uint8_t buf[8]; - int i; - - if (file_size < APE_TAG_FOOTER_BYTES) - return; - - url_fseek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET); - - get_buffer(pb, buf, 8); /* APETAGEX */ - if (strncmp(buf, "APETAGEX", 8)) { - return; - } - - val = get_le32(pb); /* APE tag version */ - if (val > APE_TAG_VERSION) { - av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION); - return; - } - - tag_bytes = get_le32(pb); /* tag size */ - if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) { - av_log(s, AV_LOG_ERROR, "Tag size is way too big\n"); - return; - } - - fields = get_le32(pb); /* number of fields */ - if (fields > 65536) { - av_log(s, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields); - return; - } - - val = get_le32(pb); /* flags */ - if (val & APE_TAG_FLAG_IS_HEADER) { - av_log(s, AV_LOG_ERROR, "APE Tag is a header\n"); - return; - } - - url_fseek(pb, file_size - tag_bytes, SEEK_SET); - - for (i=0; i - * based upon libdemac from Dave Chapman. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_APETAG_H -#define AVFORMAT_APETAG_H - -#include "avformat.h" - -/** - * Read and parse an APE tag - */ -void ff_ape_parse_tag(AVFormatContext *s); - -#endif /* AVFORMAT_ID3V2_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/asf.c b/tizen/distrib/ffmpeg/libavformat/asf.c deleted file mode 100644 index e25ac03..0000000 --- a/tizen/distrib/ffmpeg/libavformat/asf.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "asf.h" - - -const ff_asf_guid ff_asf_header = { - 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C -}; - -const ff_asf_guid ff_asf_file_header = { - 0xA1, 0xDC, 0xAB, 0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_stream_header = { - 0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_ext_stream_header = { - 0xCB, 0xA5, 0xE6, 0x14, 0x72, 0xC6, 0x32, 0x43, 0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A -}; - -const ff_asf_guid ff_asf_audio_stream = { - 0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B -}; - -const ff_asf_guid ff_asf_audio_conceal_none = { - // 0x40, 0xa4, 0xf1, 0x49, 0x4ece, 0x11d0, 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 - // New value lifted from avifile - 0x00, 0x57, 0xfb, 0x20, 0x55, 0x5B, 0xCF, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b -}; - -const ff_asf_guid ff_asf_audio_conceal_spread = { - 0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20 -}; - -const ff_asf_guid ff_asf_video_stream = { - 0xC0, 0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B -}; - -const ff_asf_guid ff_asf_video_conceal_none = { - 0x00, 0x57, 0xFB, 0x20, 0x55, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B -}; - -const ff_asf_guid ff_asf_command_stream = { - 0xC0, 0xCF, 0xDA, 0x59, 0xE6, 0x59, 0xD0, 0x11, 0xA3, 0xAC, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 -}; - -const ff_asf_guid ff_asf_comment_header = { - 0x33, 0x26, 0xb2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c -}; - -const ff_asf_guid ff_asf_codec_comment_header = { - 0x40, 0x52, 0xD1, 0x86, 0x1D, 0x31, 0xD0, 0x11, 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 -}; -const ff_asf_guid ff_asf_codec_comment1_header = { - 0x41, 0x52, 0xd1, 0x86, 0x1D, 0x31, 0xD0, 0x11, 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 -}; - -const ff_asf_guid ff_asf_data_header = { - 0x36, 0x26, 0xb2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c -}; - -const ff_asf_guid ff_asf_head1_guid = { - 0xb5, 0x03, 0xbf, 0x5f, 0x2E, 0xA9, 0xCF, 0x11, 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_head2_guid = { - 0x11, 0xd2, 0xd3, 0xab, 0xBA, 0xA9, 0xCF, 0x11, 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_extended_content_header = { - 0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50 -}; - -const ff_asf_guid ff_asf_simple_index_header = { - 0x90, 0x08, 0x00, 0x33, 0xB1, 0xE5, 0xCF, 0x11, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB -}; - -const ff_asf_guid ff_asf_ext_stream_embed_stream_header = { - 0xe2, 0x65, 0xfb, 0x3a, 0xEF, 0x47, 0xF2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43 -}; - -const ff_asf_guid ff_asf_ext_stream_audio_stream = { - 0x9d, 0x8c, 0x17, 0x31, 0xE1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03 -}; - -const ff_asf_guid ff_asf_metadata_header = { - 0xea, 0xcb, 0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca -}; - -const ff_asf_guid ff_asf_marker_header = { - 0x01, 0xCD, 0x87, 0xF4, 0x51, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 -}; - -/* I am not a number !!! This GUID is the one found on the PC used to - generate the stream */ -const ff_asf_guid ff_asf_my_guid = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -const ff_asf_guid ff_asf_language_guid = { - 0xa9, 0x46, 0x43, 0x7c, 0xe0, 0xef, 0xfc, 0x4b, 0xb2, 0x29, 0x39, 0x3e, 0xde, 0x41, 0x5c, 0x85 -}; - -const ff_asf_guid ff_asf_content_encryption = { - 0xfb, 0xb3, 0x11, 0x22, 0x23, 0xbd, 0xd2, 0x11, 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e -}; - -const ff_asf_guid ff_asf_ext_content_encryption = { - 0x14, 0xe6, 0x8a, 0x29, 0x22, 0x26, 0x17, 0x4c, 0xb9, 0x35, 0xda, 0xe0, 0x7e, 0xe9, 0x28, 0x9c -}; - -const ff_asf_guid ff_asf_digital_signature = { - 0xfc, 0xb3, 0x11, 0x22, 0x23, 0xbd, 0xd2, 0x11, 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e -}; - -/* List of official tags at http://msdn.microsoft.com/en-us/library/dd743066(VS.85).aspx */ -const AVMetadataConv ff_asf_metadata_conv[] = { - { "WM/AlbumArtist" , "album_artist"}, - { "WM/AlbumTitle" , "album" }, - { "Author" , "artist" }, - { "Description" , "comment" }, - { "WM/Composer" , "composer" }, - { "WM/EncodedBy" , "encoded_by" }, - { "WM/EncodingSettings", "encoder" }, - { "WM/Genre" , "genre" }, - { "WM/Language" , "language" }, - { "WM/OriginalFilename", "filename" }, - { "WM/PartOfSet" , "disc" }, - { "WM/Publisher" , "publisher" }, - { "WM/Tool" , "encoder" }, - { "WM/TrackNumber" , "track" }, - { "WM/Track" , "track" }, -// { "Year" , "date" }, TODO: conversion year<->date - { 0 } -}; - -int ff_put_str16_nolen(ByteIOContext *s, const char *tag) -{ - const uint8_t *q = tag; - int ret = 0; - - while (*q) { - uint32_t ch; - uint16_t tmp; - - GET_UTF8(ch, *q++, break;) - PUT_UTF16(ch, tmp, put_le16(s, tmp);ret += 2;) - } - put_le16(s, 0); - ret += 2; - return ret; -} diff --git a/tizen/distrib/ffmpeg/libavformat/asf.h b/tizen/distrib/ffmpeg/libavformat/asf.h deleted file mode 100644 index 85e54cc..0000000 --- a/tizen/distrib/ffmpeg/libavformat/asf.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_ASF_H -#define AVFORMAT_ASF_H - -#include -#include "avformat.h" -#include "metadata.h" - -#define PACKET_SIZE 3200 - -typedef struct { - int num; - unsigned char seq; - /* use for reading */ - AVPacket pkt; - int frag_offset; - int timestamp; - int64_t duration; - - int ds_span; /* descrambling */ - int ds_packet_size; - int ds_chunk_size; - - int64_t packet_pos; - - uint16_t stream_language_index; - -} ASFStream; - -typedef uint8_t ff_asf_guid[16]; - -typedef struct { - ff_asf_guid guid; ///< generated by client computer - uint64_t file_size; /**< in bytes - * invalid if broadcasting */ - uint64_t create_time; /**< time of creation, in 100-nanosecond units since 1.1.1601 - * invalid if broadcasting */ - uint64_t play_time; /**< play time, in 100-nanosecond units - * invalid if broadcasting */ - uint64_t send_time; /**< time to send file, in 100-nanosecond units - * invalid if broadcasting (could be ignored) */ - uint32_t preroll; /**< timestamp of the first packet, in milliseconds - * if nonzero - subtract from time */ - uint32_t ignore; ///< preroll is 64bit - but let's just ignore it - uint32_t flags; /**< 0x01 - broadcast - * 0x02 - seekable - * rest is reserved should be 0 */ - uint32_t min_pktsize; /**< size of a data packet - * invalid if broadcasting */ - uint32_t max_pktsize; /**< shall be the same as for min_pktsize - * invalid if broadcasting */ - uint32_t max_bitrate; /**< bandwidth of stream in bps - * should be the sum of bitrates of the - * individual media streams */ -} ASFMainHeader; - - -typedef struct { - uint32_t packet_number; - uint16_t packet_count; -} ASFIndex; - - -typedef struct { - uint32_t seqno; - int is_streamed; - int asfid2avid[128]; ///< conversion table from asf ID 2 AVStream ID - ASFStream streams[128]; ///< it's max number and it's not that big - uint32_t stream_bitrates[128]; ///< max number of streams, bitrate for each (for streaming) - char stream_languages[128][6]; ///< max number of streams, language for each (RFC1766, e.g. en-US) - /* non streamed additonnal info */ - uint64_t nb_packets; ///< how many packets are there in the file, invalid if broadcasting - int64_t duration; ///< in 100ns units - /* packet filling */ - unsigned char multi_payloads_present; - int packet_size_left; - int packet_timestamp_start; - int packet_timestamp_end; - unsigned int packet_nb_payloads; - int packet_nb_frames; - uint8_t packet_buf[PACKET_SIZE]; - ByteIOContext pb; - /* only for reading */ - uint64_t data_offset; ///< beginning of the first data packet - uint64_t data_object_offset; ///< data object offset (excl. GUID & size) - uint64_t data_object_size; ///< size of the data object - int index_read; - - ASFMainHeader hdr; - - int packet_flags; - int packet_property; - int packet_timestamp; - int packet_segsizetype; - int packet_segments; - int packet_seq; - int packet_replic_size; - int packet_key_frame; - int packet_padsize; - unsigned int packet_frag_offset; - unsigned int packet_frag_size; - int64_t packet_frag_timestamp; - int packet_multi_size; - int packet_obj_size; - int packet_time_delta; - int packet_time_start; - int64_t packet_pos; - - int stream_index; - - - int64_t last_indexed_pts; - ASFIndex* index_ptr; - uint32_t nb_index_count; - uint32_t nb_index_memory_alloc; - uint16_t maximum_packet; - - ASFStream* asf_st; ///< currently decoded stream -} ASFContext; - -extern const ff_asf_guid ff_asf_header; -extern const ff_asf_guid ff_asf_file_header; -extern const ff_asf_guid ff_asf_stream_header; -extern const ff_asf_guid ff_asf_ext_stream_header; -extern const ff_asf_guid ff_asf_audio_stream; -extern const ff_asf_guid ff_asf_audio_conceal_none; -extern const ff_asf_guid ff_asf_audio_conceal_spread; -extern const ff_asf_guid ff_asf_video_stream; -extern const ff_asf_guid ff_asf_video_conceal_none; -extern const ff_asf_guid ff_asf_command_stream; -extern const ff_asf_guid ff_asf_comment_header; -extern const ff_asf_guid ff_asf_codec_comment_header; -extern const ff_asf_guid ff_asf_codec_comment1_header; -extern const ff_asf_guid ff_asf_data_header; -extern const ff_asf_guid ff_asf_head1_guid; -extern const ff_asf_guid ff_asf_head2_guid; -extern const ff_asf_guid ff_asf_extended_content_header; -extern const ff_asf_guid ff_asf_simple_index_header; -extern const ff_asf_guid ff_asf_ext_stream_embed_stream_header; -extern const ff_asf_guid ff_asf_ext_stream_audio_stream; -extern const ff_asf_guid ff_asf_metadata_header; -extern const ff_asf_guid ff_asf_marker_header; -extern const ff_asf_guid ff_asf_my_guid; -extern const ff_asf_guid ff_asf_language_guid; -extern const ff_asf_guid ff_asf_content_encryption; -extern const ff_asf_guid ff_asf_ext_content_encryption; -extern const ff_asf_guid ff_asf_digital_signature; - -extern const AVMetadataConv ff_asf_metadata_conv[]; - -#define ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT 0x80 //1000 0000 - - -// ASF data packet structure -// ========================= -// -// -// ----------------------------------- -// | Error Correction Data | Optional -// ----------------------------------- -// | Payload Parsing Information (PPI) | -// ----------------------------------- -// | Payload Data | -// ----------------------------------- -// | Padding Data | -// ----------------------------------- - - -// PPI_FLAG - Payload parsing information flags -#define ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT 1 - -#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE 0x02 //0000 0010 -#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD 0x04 //0000 0100 -#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD 0x06 //0000 0110 -#define ASF_PPI_MASK_SEQUENCE_FIELD_SIZE 0x06 //0000 0110 - -#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE 0x08 //0000 1000 -#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD 0x10 //0001 0000 -#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD 0x18 //0001 1000 -#define ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE 0x18 //0001 1000 - -#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE 0x20 //0010 0000 -#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD 0x40 //0100 0000 -#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD 0x60 //0110 0000 -#define ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE 0x60 //0110 0000 - -// PL_FLAG - Payload flags -#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE 0x01 //0000 0001 -#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD 0x02 //0000 0010 -#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD 0x03 //0000 0011 -#define ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE 0x03 //0000 0011 - -#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_BYTE 0x04 //0000 0100 -#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_WORD 0x08 //0000 1000 -#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD 0x0c //0000 1100 -#define ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE 0x0c //0000 1100 - -#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE 0x10 //0001 0000 -#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD 0x20 //0010 0000 -#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD 0x30 //0011 0000 -#define ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE 0x30 //0011 0000 - -#define ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE 0x40 //0100 0000 -#define ASF_PL_MASK_STREAM_NUMBER_LENGTH_FIELD_SIZE 0xc0 //1100 0000 - -#define ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE 0x40 //0100 0000 -#define ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD 0x80 //1000 0000 -#define ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE 0xc0 //1100 0000 - -#define ASF_PL_FLAG_KEY_FRAME 0x80 //1000 0000 - -extern AVInputFormat asf_demuxer; -int ff_put_str16_nolen(ByteIOContext *s, const char *tag); - -#endif /* AVFORMAT_ASF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/asfcrypt.c b/tizen/distrib/ffmpeg/libavformat/asfcrypt.c deleted file mode 100644 index 09e9af6..0000000 --- a/tizen/distrib/ffmpeg/libavformat/asfcrypt.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * ASF decryption - * Copyright (c) 2007 Reimar Doeffinger - * This is a rewrite of code contained in freeme/freeme2 - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/bswap.h" -#include "libavutil/des.h" -#include "libavutil/rc4.h" -#include "asfcrypt.h" - -/** - * \brief find multiplicative inverse modulo 2 ^ 32 - * \param v number to invert, must be odd! - * \return number so that result * v = 1 (mod 2^32) - */ -static uint32_t inverse(uint32_t v) { - // v ^ 3 gives the inverse (mod 16), could also be implemented - // as table etc. (only lowest 4 bits matter!) - uint32_t inverse = v * v * v; - // uses a fixpoint-iteration that doubles the number - // of correct lowest bits each time - inverse *= 2 - v * inverse; - inverse *= 2 - v * inverse; - inverse *= 2 - v * inverse; - return inverse; -} - -/** - * \brief read keys from keybuf into keys - * \param keybuf buffer containing the keys - * \param keys output key array containing the keys for encryption in - * native endianness - */ -static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12]) { - int i; - for (i = 0; i < 12; i++) - keys[i] = AV_RL32(keybuf + (i << 2)) | 1; -} - -/** - * \brief invert the keys so that encryption become decryption keys and - * the other way round. - * \param keys key array of ints to invert - */ -static void multiswap_invert_keys(uint32_t keys[12]) { - int i; - for (i = 0; i < 5; i++) - keys[i] = inverse(keys[i]); - for (i = 6; i < 11; i++) - keys[i] = inverse(keys[i]); -} - -static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v) { - int i; - v *= keys[0]; - for (i = 1; i < 5; i++) { - v = (v >> 16) | (v << 16); - v *= keys[i]; - } - v += keys[5]; - return v; -} - -static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v) { - int i; - v -= keys[5]; - for (i = 4; i > 0; i--) { - v *= keys[i]; - v = (v >> 16) | (v << 16); - } - v *= keys[0]; - return v; -} - -/** - * \brief "MultiSwap" encryption - * \param keys 32 bit numbers in machine endianness, - * 0-4 and 6-10 must be inverted from decryption - * \param key another key, this one must be the same for the decryption - * \param data data to encrypt - * \return encrypted data - */ -static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t data) { - uint32_t a = data; - uint32_t b = data >> 32; - uint32_t c; - uint32_t tmp; - a += key; - tmp = multiswap_step(keys , a); - b += tmp; - c = (key >> 32) + tmp; - tmp = multiswap_step(keys + 6, b); - c += tmp; - return ((uint64_t)c << 32) | tmp; -} - -/** - * \brief "MultiSwap" decryption - * \param keys 32 bit numbers in machine endianness, - * 0-4 and 6-10 must be inverted from encryption - * \param key another key, this one must be the same as for the encryption - * \param data data to decrypt - * \return decrypted data - */ -static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t data) { - uint32_t a; - uint32_t b; - uint32_t c = data >> 32; - uint32_t tmp = data; - c -= tmp; - b = multiswap_inv_step(keys + 6, tmp); - tmp = c - (key >> 32); - b -= tmp; - a = multiswap_inv_step(keys , tmp); - a -= key; - return ((uint64_t)b << 32) | a; -} - -void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len) { - struct AVDES des; - struct AVRC4 rc4; - int num_qwords = len >> 3; - uint64_t *qwords = (uint64_t *)data; - uint64_t rc4buff[8]; - uint64_t packetkey; - uint32_t ms_keys[12]; - uint64_t ms_state; - int i; - if (len < 16) { - for (i = 0; i < len; i++) - data[i] ^= key[i]; - return; - } - - memset(rc4buff, 0, sizeof(rc4buff)); - av_rc4_init(&rc4, key, 12 * 8, 1); - av_rc4_crypt(&rc4, (uint8_t *)rc4buff, NULL, sizeof(rc4buff), NULL, 1); - multiswap_init((uint8_t *)rc4buff, ms_keys); - - packetkey = qwords[num_qwords - 1]; - packetkey ^= rc4buff[7]; - av_des_init(&des, key + 12, 64, 1); - av_des_crypt(&des, (uint8_t *)&packetkey, (uint8_t *)&packetkey, 1, NULL, 1); - packetkey ^= rc4buff[6]; - - av_rc4_init(&rc4, (uint8_t *)&packetkey, 64, 1); - av_rc4_crypt(&rc4, data, data, len, NULL, 1); - - ms_state = 0; - for (i = 0; i < num_qwords - 1; i++, qwords++) - ms_state = multiswap_enc(ms_keys, ms_state, AV_RL64(qwords)); - multiswap_invert_keys(ms_keys); - packetkey = (packetkey << 32) | (packetkey >> 32); - packetkey = le2me_64(packetkey); - packetkey = multiswap_dec(ms_keys, ms_state, packetkey); - AV_WL64(qwords, packetkey); -} diff --git a/tizen/distrib/ffmpeg/libavformat/asfcrypt.h b/tizen/distrib/ffmpeg/libavformat/asfcrypt.h deleted file mode 100644 index 8b80d63..0000000 --- a/tizen/distrib/ffmpeg/libavformat/asfcrypt.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ASF decryption - * Copyright (c) 2007 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_ASFCRYPT_H -#define AVFORMAT_ASFCRYPT_H - -#include - -void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len); - -#endif /* AVFORMAT_ASFCRYPT_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/asfdec.c b/tizen/distrib/ffmpeg/libavformat/asfdec.c deleted file mode 100644 index 8aea8c7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/asfdec.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* - * ASF compatible demuxer - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//#define DEBUG - -#include "libavutil/common.h" -#include "libavutil/avstring.h" -#include "libavcodec/mpegaudio.h" -#include "avformat.h" -#include "riff.h" -#include "asf.h" -#include "asfcrypt.h" -#include "avlanguage.h" - -void ff_mms_set_stream_selection(URLContext *h, AVFormatContext *format); - -#undef NDEBUG -#include - -#define FRAME_HEADER_SIZE 17 -// Fix Me! FRAME_HEADER_SIZE may be different. - -static const ff_asf_guid index_guid = { - 0x90, 0x08, 0x00, 0x33, 0xb1, 0xe5, 0xcf, 0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb -}; - -static const ff_asf_guid stream_bitrate_guid = { /* (http://get.to/sdp) */ - 0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2 -}; -/**********************************/ -/* decoding */ - -static int guidcmp(const void *g1, const void *g2) -{ - return memcmp(g1, g2, sizeof(ff_asf_guid)); -} - -#ifdef DEBUG -#define PRINT_IF_GUID(g,cmp) \ -if (!guidcmp(g, &cmp)) \ - dprintf(NULL, "(GUID: %s) ", #cmp) - -static void print_guid(const ff_asf_guid *g) -{ - int i; - PRINT_IF_GUID(g, ff_asf_header); - else PRINT_IF_GUID(g, ff_asf_file_header); - else PRINT_IF_GUID(g, ff_asf_stream_header); - else PRINT_IF_GUID(g, ff_asf_audio_stream); - else PRINT_IF_GUID(g, ff_asf_audio_conceal_none); - else PRINT_IF_GUID(g, ff_asf_video_stream); - else PRINT_IF_GUID(g, ff_asf_video_conceal_none); - else PRINT_IF_GUID(g, ff_asf_command_stream); - else PRINT_IF_GUID(g, ff_asf_comment_header); - else PRINT_IF_GUID(g, ff_asf_codec_comment_header); - else PRINT_IF_GUID(g, ff_asf_codec_comment1_header); - else PRINT_IF_GUID(g, ff_asf_data_header); - else PRINT_IF_GUID(g, index_guid); - else PRINT_IF_GUID(g, ff_asf_head1_guid); - else PRINT_IF_GUID(g, ff_asf_head2_guid); - else PRINT_IF_GUID(g, ff_asf_my_guid); - else PRINT_IF_GUID(g, ff_asf_ext_stream_header); - else PRINT_IF_GUID(g, ff_asf_extended_content_header); - else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); - else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); - else PRINT_IF_GUID(g, ff_asf_metadata_header); - else PRINT_IF_GUID(g, ff_asf_marker_header); - else PRINT_IF_GUID(g, stream_bitrate_guid); - else PRINT_IF_GUID(g, ff_asf_language_guid); - else - dprintf(NULL, "(GUID: unknown) "); - for(i=0;i<16;i++) - dprintf(NULL, " 0x%02x,", (*g)[i]); - dprintf(NULL, "}\n"); -} -#undef PRINT_IF_GUID -#else -#define print_guid(g) -#endif - -static void get_guid(ByteIOContext *s, ff_asf_guid *g) -{ - assert(sizeof(*g) == 16); - get_buffer(s, *g, sizeof(*g)); -} - -#if 0 -static void get_str16(ByteIOContext *pb, char *buf, int buf_size) -{ - int len, c; - char *q; - - len = get_le16(pb); - q = buf; - while (len > 0) { - c = get_le16(pb); - if ((q - buf) < buf_size - 1) - *q++ = c; - len--; - } - *q = '\0'; -} -#endif - -static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size) -{ - char* q = buf; - while (len > 1) { - uint8_t tmp; - uint32_t ch; - - GET_UTF16(ch, (len -= 2) >= 0 ? get_le16(pb) : 0, break;) - PUT_UTF8(ch, tmp, if (q - buf < buf_size - 1) *q++ = tmp;) - } - if (len > 0) - url_fskip(pb, len); - *q = '\0'; -} - -static int asf_probe(AVProbeData *pd) -{ - /* check file header */ - if (!guidcmp(pd->buf, &ff_asf_header)) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int get_value(ByteIOContext *pb, int type){ - switch(type){ - case 2: return get_le32(pb); - case 3: return get_le32(pb); - case 4: return get_le64(pb); - case 5: return get_le16(pb); - default:return INT_MIN; - } -} - -static void get_tag(AVFormatContext *s, const char *key, int type, int len) -{ - char *value; - - if ((unsigned)len >= (UINT_MAX - 1)/2) - return; - - value = av_malloc(2*len+1); - if (!value) - return; - - if (type == 0) { // UTF16-LE - get_str16_nolen(s->pb, len, value, 2*len + 1); - } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD - uint64_t num = get_value(s->pb, type); - snprintf(value, len, "%"PRIu64, num); - } else { - url_fskip(s->pb, len); - av_freep(&value); - av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type, key); - return; - } - av_metadata_set2(&s->metadata, key, value, 0); - av_freep(&value); -} - -static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ASFContext *asf = s->priv_data; - ff_asf_guid g; - ByteIOContext *pb = s->pb; - AVStream *st; - ASFStream *asf_st; - int size, i; - int64_t gsize; - AVRational dar[128]; - uint32_t bitrate[128]; - - memset(dar, 0, sizeof(dar)); - memset(bitrate, 0, sizeof(bitrate)); - - get_guid(pb, &g); - if (guidcmp(&g, &ff_asf_header)) - return -1; - get_le64(pb); - get_le32(pb); - get_byte(pb); - get_byte(pb); - memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); - for(;;) { - uint64_t gpos= url_ftell(pb); - get_guid(pb, &g); - gsize = get_le64(pb); - dprintf(s, "%08"PRIx64": ", gpos); - print_guid(&g); - dprintf(s, " size=0x%"PRIx64"\n", gsize); - if (!guidcmp(&g, &ff_asf_data_header)) { - asf->data_object_offset = url_ftell(pb); - // if not streaming, gsize is not unlimited (how?), and there is enough space in the file.. - if (!(asf->hdr.flags & 0x01) && gsize >= 100) { - asf->data_object_size = gsize - 24; - } else { - asf->data_object_size = (uint64_t)-1; - } - break; - } - if (gsize < 24) - return -1; - if (!guidcmp(&g, &ff_asf_file_header)) { - get_guid(pb, &asf->hdr.guid); - asf->hdr.file_size = get_le64(pb); - asf->hdr.create_time = get_le64(pb); - asf->nb_packets = get_le64(pb); - asf->hdr.play_time = get_le64(pb); - asf->hdr.send_time = get_le64(pb); - asf->hdr.preroll = get_le32(pb); - asf->hdr.ignore = get_le32(pb); - asf->hdr.flags = get_le32(pb); - asf->hdr.min_pktsize = get_le32(pb); - asf->hdr.max_pktsize = get_le32(pb); - asf->hdr.max_bitrate = get_le32(pb); - s->packet_size = asf->hdr.max_pktsize; - } else if (!guidcmp(&g, &ff_asf_stream_header)) { - enum AVMediaType type; - int type_specific_size, sizeX; - uint64_t total_size; - unsigned int tag1; - int64_t pos1, pos2, start_time; - int test_for_ext_stream_audio, is_dvr_ms_audio=0; - - pos1 = url_ftell(pb); - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ - asf_st = av_mallocz(sizeof(ASFStream)); - if (!asf_st) - return AVERROR(ENOMEM); - st->priv_data = asf_st; - start_time = asf->hdr.preroll; - - asf_st->stream_language_index = 128; // invalid stream index means no language info - - if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming... - st->duration = asf->hdr.play_time / - (10000000 / 1000) - start_time; - } - get_guid(pb, &g); - - test_for_ext_stream_audio = 0; - if (!guidcmp(&g, &ff_asf_audio_stream)) { - type = AVMEDIA_TYPE_AUDIO; - } else if (!guidcmp(&g, &ff_asf_video_stream)) { - type = AVMEDIA_TYPE_VIDEO; - } else if (!guidcmp(&g, &ff_asf_command_stream)) { - type = AVMEDIA_TYPE_DATA; - } else if (!guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) { - test_for_ext_stream_audio = 1; - type = AVMEDIA_TYPE_UNKNOWN; - } else { - return -1; - } - get_guid(pb, &g); - total_size = get_le64(pb); - type_specific_size = get_le32(pb); - get_le32(pb); - st->id = get_le16(pb) & 0x7f; /* stream id */ - // mapping of asf ID to AV stream ID; - asf->asfid2avid[st->id] = s->nb_streams - 1; - - get_le32(pb); - - if (test_for_ext_stream_audio) { - get_guid(pb, &g); - if (!guidcmp(&g, &ff_asf_ext_stream_audio_stream)) { - type = AVMEDIA_TYPE_AUDIO; - is_dvr_ms_audio=1; - get_guid(pb, &g); - get_le32(pb); - get_le32(pb); - get_le32(pb); - get_guid(pb, &g); - get_le32(pb); - } - } - - st->codec->codec_type = type; - if (type == AVMEDIA_TYPE_AUDIO) { - ff_get_wav_header(pb, st->codec, type_specific_size); - if (is_dvr_ms_audio) { - // codec_id and codec_tag are unreliable in dvr_ms - // files. Set them later by probing stream. - st->codec->codec_id = CODEC_ID_PROBE; - st->codec->codec_tag = 0; - } - if (st->codec->codec_id == CODEC_ID_AAC) { - st->need_parsing = AVSTREAM_PARSE_NONE; - } else { - st->need_parsing = AVSTREAM_PARSE_FULL; - } - /* We have to init the frame size at some point .... */ - pos2 = url_ftell(pb); - if (gsize >= (pos2 + 8 - pos1 + 24)) { - asf_st->ds_span = get_byte(pb); - asf_st->ds_packet_size = get_le16(pb); - asf_st->ds_chunk_size = get_le16(pb); - get_le16(pb); //ds_data_size - get_byte(pb); //ds_silence_data - } - //printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n", - // asf_st->ds_packet_size, asf_st->ds_chunk_size, - // asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data); - if (asf_st->ds_span > 1) { - if (!asf_st->ds_chunk_size - || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1) - || asf_st->ds_packet_size % asf_st->ds_chunk_size) - asf_st->ds_span = 0; // disable descrambling - } - switch (st->codec->codec_id) { - case CODEC_ID_MP3: - st->codec->frame_size = MPA_FRAME_SIZE; - break; - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - st->codec->frame_size = 1; - break; - default: - /* This is probably wrong, but it prevents a crash later */ - st->codec->frame_size = 1; - break; - } - } else if (type == AVMEDIA_TYPE_VIDEO) { - get_le32(pb); - get_le32(pb); - get_byte(pb); - size = get_le16(pb); /* size */ - sizeX= get_le32(pb); /* size */ - st->codec->width = get_le32(pb); - st->codec->height = get_le32(pb); - /* not available for asf */ - get_le16(pb); /* panes */ - st->codec->bits_per_coded_sample = get_le16(pb); /* depth */ - tag1 = get_le32(pb); - url_fskip(pb, 20); -// av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX); - size= sizeX; - if (size > 40) { - st->codec->extradata_size = size - 40; - st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - get_buffer(pb, st->codec->extradata, st->codec->extradata_size); - } - - /* Extract palette from extradata if bpp <= 8 */ - /* This code assumes that extradata contains only palette */ - /* This is true for all paletted codecs implemented in ffmpeg */ - if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { - st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); -#if HAVE_BIGENDIAN - for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) - st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]); -#else - memcpy(st->codec->palctrl->palette, st->codec->extradata, - FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); -#endif - st->codec->palctrl->palette_changed = 1; - } - - st->codec->codec_tag = tag1; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); - if(tag1 == MKTAG('D', 'V', 'R', ' ')) - st->need_parsing = AVSTREAM_PARSE_FULL; - } - pos2 = url_ftell(pb); - url_fskip(pb, gsize - (pos2 - pos1 + 24)); - } else if (!guidcmp(&g, &ff_asf_comment_header)) { - int len1, len2, len3, len4, len5; - - len1 = get_le16(pb); - len2 = get_le16(pb); - len3 = get_le16(pb); - len4 = get_le16(pb); - len5 = get_le16(pb); - get_tag(s, "title" , 0, len1); - get_tag(s, "author" , 0, len2); - get_tag(s, "copyright", 0, len3); - get_tag(s, "comment" , 0, len4); - url_fskip(pb, len5); - } else if (!guidcmp(&g, &stream_bitrate_guid)) { - int stream_count = get_le16(pb); - int j; - -// av_log(s, AV_LOG_ERROR, "stream bitrate properties\n"); -// av_log(s, AV_LOG_ERROR, "streams %d\n", streams); - for(j = 0; j < stream_count; j++) { - int flags, bitrate, stream_id; - - flags= get_le16(pb); - bitrate= get_le32(pb); - stream_id= (flags & 0x7f); -// av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate); - asf->stream_bitrates[stream_id]= bitrate; - } - } else if (!guidcmp(&g, &ff_asf_language_guid)) { - int j; - int stream_count = get_le16(pb); - for(j = 0; j < stream_count; j++) { - char lang[6]; - unsigned int lang_len = get_byte(pb); - get_str16_nolen(pb, lang_len, lang, sizeof(lang)); - if (j < 128) - av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages)); - } - } else if (!guidcmp(&g, &ff_asf_extended_content_header)) { - int desc_count, i; - - desc_count = get_le16(pb); - for(i=0;i\n", i, stream_num, name_len, value_type, value_len, name); - value_num= get_le16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere - url_fskip(pb, value_len - 2); - - if(stream_num<128){ - if (!strcmp(name, "AspectRatioX")) dar[stream_num].num= value_num; - else if(!strcmp(name, "AspectRatioY")) dar[stream_num].den= value_num; - } - } - } else if (!guidcmp(&g, &ff_asf_ext_stream_header)) { - int ext_len, payload_ext_ct, stream_ct; - uint32_t ext_d, leak_rate, stream_num; - unsigned int stream_languageid_index; - - get_le64(pb); // starttime - get_le64(pb); // endtime - leak_rate = get_le32(pb); // leak-datarate - get_le32(pb); // bucket-datasize - get_le32(pb); // init-bucket-fullness - get_le32(pb); // alt-leak-datarate - get_le32(pb); // alt-bucket-datasize - get_le32(pb); // alt-init-bucket-fullness - get_le32(pb); // max-object-size - get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved) - stream_num = get_le16(pb); // stream-num - - stream_languageid_index = get_le16(pb); // stream-language-id-index - if (stream_num < 128) - asf->streams[stream_num].stream_language_index = stream_languageid_index; - - get_le64(pb); // avg frametime in 100ns units - stream_ct = get_le16(pb); //stream-name-count - payload_ext_ct = get_le16(pb); //payload-extension-system-count - - if (stream_num < 128) - bitrate[stream_num] = leak_rate; - - for (i=0; i 0) { - v1 = get_byte(pb); - if ((q - tag) < sizeof(tag) - 1) - *q++ = v1; - len--; - } - *q = '\0'; - } -#endif - } else if (url_feof(pb)) { - return -1; - } else { - if (!s->keylen) { - if (!guidcmp(&g, &ff_asf_content_encryption)) { - av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n"); - } else if (!guidcmp(&g, &ff_asf_ext_content_encryption)) { - av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n"); - } else if (!guidcmp(&g, &ff_asf_digital_signature)) { - av_log(s, AV_LOG_WARNING, "Digital signature detected, decoding will likely fail!\n"); - } - } - } - if(url_ftell(pb) != gpos + gsize) - av_log(s, AV_LOG_DEBUG, "gpos mismatch our pos=%"PRIu64", end=%"PRIu64"\n", url_ftell(pb)-gpos, gsize); - url_fseek(pb, gpos + gsize, SEEK_SET); - } - get_guid(pb, &g); - get_le64(pb); - get_byte(pb); - get_byte(pb); - if (url_feof(pb)) - return -1; - asf->data_offset = url_ftell(pb); - asf->packet_size_left = 0; - - - for(i=0; i<128; i++){ - int stream_num= asf->asfid2avid[i]; - if(stream_num>=0){ - AVStream *st = s->streams[stream_num]; - if (!st->codec->bit_rate) - st->codec->bit_rate = bitrate[i]; - if (dar[i].num > 0 && dar[i].den > 0) - av_reduce(&st->sample_aspect_ratio.num, - &st->sample_aspect_ratio.den, - dar[i].num, dar[i].den, INT_MAX); -//av_log(s, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); - - // copy and convert language codes to the frontend - if (asf->streams[i].stream_language_index < 128) { - const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index]; - if (rfc1766 && strlen(rfc1766) > 1) { - const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any - const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL); - if (iso6392) - av_metadata_set2(&st->metadata, "language", iso6392, 0); - } - } - } - } - - return 0; -} - -#define DO_2BITS(bits, var, defval) \ - switch (bits & 3) \ - { \ - case 3: var = get_le32(pb); rsize += 4; break; \ - case 2: var = get_le16(pb); rsize += 2; break; \ - case 1: var = get_byte(pb); rsize++; break; \ - default: var = defval; break; \ - } - -/** - * Load a single ASF packet into the demuxer. - * @param s demux context - * @param pb context to read data from - * @return 0 on success, <0 on error - */ -static int ff_asf_get_packet(AVFormatContext *s, ByteIOContext *pb) -{ - ASFContext *asf = s->priv_data; - uint32_t packet_length, padsize; - int rsize = 8; - int c, d, e, off; - - // if we do not know packet size, allow skipping up to 32 kB - off= 32768; - if (s->packet_size > 0) - off= (url_ftell(pb) - s->data_offset) % s->packet_size + 3; - - c=d=e=-1; - while(off-- > 0){ - c=d; d=e; - e= get_byte(pb); - if(c == 0x82 && !d && !e) - break; - } - - if (c != 0x82) { - /** - * This code allows handling of -EAGAIN at packet boundaries (i.e. - * if the packet sync code above triggers -EAGAIN). This does not - * imply complete -EAGAIN handling support at random positions in - * the stream. - */ - if (url_ferror(pb) == AVERROR(EAGAIN)) - return AVERROR(EAGAIN); - if (!url_feof(pb)) - av_log(s, AV_LOG_ERROR, "ff asf bad header %x at:%"PRId64"\n", c, url_ftell(pb)); - } - if ((c & 0x8f) == 0x82) { - if (d || e) { - if (!url_feof(pb)) - av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n"); - return -1; - } - c= get_byte(pb); - d= get_byte(pb); - rsize+=3; - }else{ - url_fseek(pb, -1, SEEK_CUR); //FIXME - } - - asf->packet_flags = c; - asf->packet_property = d; - - DO_2BITS(asf->packet_flags >> 5, packet_length, s->packet_size); - DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored - DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length - - //the following checks prevent overflows and infinite loops - if(!packet_length || packet_length >= (1U<<29)){ - av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, url_ftell(pb)); - return -1; - } - if(padsize >= packet_length){ - av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, url_ftell(pb)); - return -1; - } - - asf->packet_timestamp = get_le32(pb); - get_le16(pb); /* duration */ - // rsize has at least 11 bytes which have to be present - - if (asf->packet_flags & 0x01) { - asf->packet_segsizetype = get_byte(pb); rsize++; - asf->packet_segments = asf->packet_segsizetype & 0x3f; - } else { - asf->packet_segments = 1; - asf->packet_segsizetype = 0x80; - } - asf->packet_size_left = packet_length - padsize - rsize; - if (packet_length < asf->hdr.min_pktsize) - padsize += asf->hdr.min_pktsize - packet_length; - asf->packet_padsize = padsize; - dprintf(s, "packet: size=%d padsize=%d left=%d\n", s->packet_size, asf->packet_padsize, asf->packet_size_left); - return 0; -} - -/** - * - * @return <0 if error - */ -static int asf_read_frame_header(AVFormatContext *s, ByteIOContext *pb){ - ASFContext *asf = s->priv_data; - int rsize = 1; - int num = get_byte(pb); - int64_t ts0, ts1; - - asf->packet_segments--; - asf->packet_key_frame = num >> 7; - asf->stream_index = asf->asfid2avid[num & 0x7f]; - // sequence should be ignored! - DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0); - DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0); - DO_2BITS(asf->packet_property, asf->packet_replic_size, 0); -//printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size); - if (asf->packet_replic_size >= 8) { - asf->packet_obj_size = get_le32(pb); - if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){ - av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n"); - return -1; - } - asf->packet_frag_timestamp = get_le32(pb); // timestamp - if(asf->packet_replic_size >= 8+38+4){ -// for(i=0; ipacket_replic_size-8; i++) -// av_log(s, AV_LOG_DEBUG, "%02X ",get_byte(pb)); -// av_log(s, AV_LOG_DEBUG, "\n"); - url_fskip(pb, 10); - ts0= get_le64(pb); - ts1= get_le64(pb); - url_fskip(pb, 12); - get_le32(pb); - url_fskip(pb, asf->packet_replic_size - 8 - 38 - 4); - if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000; - else asf->packet_frag_timestamp= AV_NOPTS_VALUE; - }else - url_fskip(pb, asf->packet_replic_size - 8); - rsize += asf->packet_replic_size; // FIXME - check validity - } else if (asf->packet_replic_size==1){ - // multipacket - frag_offset is beginning timestamp - asf->packet_time_start = asf->packet_frag_offset; - asf->packet_frag_offset = 0; - asf->packet_frag_timestamp = asf->packet_timestamp; - - asf->packet_time_delta = get_byte(pb); - rsize++; - }else if(asf->packet_replic_size!=0){ - av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size); - return -1; - } - if (asf->packet_flags & 0x01) { - DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal - if(asf->packet_frag_size > asf->packet_size_left - rsize){ - av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid\n"); - return -1; - } - //printf("Fragsize %d\n", asf->packet_frag_size); - } else { - asf->packet_frag_size = asf->packet_size_left - rsize; - //printf("Using rest %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize); - } - if (asf->packet_replic_size == 1) { - asf->packet_multi_size = asf->packet_frag_size; - if (asf->packet_multi_size > asf->packet_size_left) - return -1; - } - asf->packet_size_left -= rsize; - //printf("___objsize____ %d %d rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize); - - return 0; -} - -/** - * Parse data from individual ASF packets (which were previously loaded - * with asf_get_packet()). - * @param s demux context - * @param pb context to read data from - * @param pkt pointer to store packet data into - * @return 0 if data was stored in pkt, <0 on error or 1 if more ASF - * packets need to be loaded (through asf_get_packet()) - */ -static int ff_asf_parse_packet(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt) -{ - ASFContext *asf = s->priv_data; - ASFStream *asf_st = 0; - for (;;) { - if(url_feof(pb)) - return AVERROR_EOF; - if (asf->packet_size_left < FRAME_HEADER_SIZE - || asf->packet_segments < 1) { - //asf->packet_size_left <= asf->packet_padsize) { - int ret = asf->packet_size_left + asf->packet_padsize; - //printf("PacketLeftSize:%d Pad:%d Pos:%"PRId64"\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb)); - assert(ret>=0); - /* fail safe */ - url_fskip(pb, ret); - - asf->packet_pos= url_ftell(pb); - if (asf->data_object_size != (uint64_t)-1 && - (asf->packet_pos - asf->data_object_offset >= asf->data_object_size)) - return AVERROR_EOF; /* Do not exceed the size of the data object */ - return 1; - } - if (asf->packet_time_start == 0) { - if(asf_read_frame_header(s, pb) < 0){ - asf->packet_segments= 0; - continue; - } - if (asf->stream_index < 0 - || s->streams[asf->stream_index]->discard >= AVDISCARD_ALL - || (!asf->packet_key_frame && s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY) - ) { - asf->packet_time_start = 0; - /* unhandled packet (should not happen) */ - url_fskip(pb, asf->packet_frag_size); - asf->packet_size_left -= asf->packet_frag_size; - if(asf->stream_index < 0) - av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size); - continue; - } - asf->asf_st = s->streams[asf->stream_index]->priv_data; - } - asf_st = asf->asf_st; - - if (asf->packet_replic_size == 1) { - // frag_offset is here used as the beginning timestamp - asf->packet_frag_timestamp = asf->packet_time_start; - asf->packet_time_start += asf->packet_time_delta; - asf->packet_obj_size = asf->packet_frag_size = get_byte(pb); - asf->packet_size_left--; - asf->packet_multi_size--; - if (asf->packet_multi_size < asf->packet_obj_size) - { - asf->packet_time_start = 0; - url_fskip(pb, asf->packet_multi_size); - asf->packet_size_left -= asf->packet_multi_size; - continue; - } - asf->packet_multi_size -= asf->packet_obj_size; - //printf("COMPRESS size %d %d %d ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size); - } - if( /*asf->packet_frag_size == asf->packet_obj_size*/ - asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size - && asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size){ - av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n", - asf_st->frag_offset, asf->packet_frag_size, - asf->packet_obj_size, asf_st->pkt.size); - asf->packet_obj_size= asf_st->pkt.size; - } - - if ( asf_st->pkt.size != asf->packet_obj_size - || asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) { //FIXME is this condition sufficient? - if(asf_st->pkt.data){ - av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, new %d\n", asf_st->pkt.size, asf->packet_obj_size); - asf_st->frag_offset = 0; - av_free_packet(&asf_st->pkt); - } - /* new packet */ - av_new_packet(&asf_st->pkt, asf->packet_obj_size); - asf_st->seq = asf->packet_seq; - asf_st->pkt.dts = asf->packet_frag_timestamp; - asf_st->pkt.stream_index = asf->stream_index; - asf_st->pkt.pos = - asf_st->packet_pos= asf->packet_pos; -//printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n", -//asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & AV_PKT_FLAG_KEY, -//s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO, asf->packet_obj_size); - if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO) - asf->packet_key_frame = 1; - if (asf->packet_key_frame) - asf_st->pkt.flags |= AV_PKT_FLAG_KEY; - } - - /* read data */ - //printf("READ PACKET s:%d os:%d o:%d,%d l:%d DATA:%p\n", - // s->packet_size, asf_st->pkt.size, asf->packet_frag_offset, - // asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data); - asf->packet_size_left -= asf->packet_frag_size; - if (asf->packet_size_left < 0) - continue; - - if( asf->packet_frag_offset >= asf_st->pkt.size - || asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset){ - av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n", - asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size); - continue; - } - - get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset, - asf->packet_frag_size); - if (s->key && s->keylen == 20) - ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset, - asf->packet_frag_size); - asf_st->frag_offset += asf->packet_frag_size; - /* test if whole packet is read */ - if (asf_st->frag_offset == asf_st->pkt.size) { - //workaround for macroshit radio DVR-MS files - if( s->streams[asf->stream_index]->codec->codec_id == CODEC_ID_MPEG2VIDEO - && asf_st->pkt.size > 100){ - int i; - for(i=0; ipkt.size && !asf_st->pkt.data[i]; i++); - if(i == asf_st->pkt.size){ - av_log(s, AV_LOG_DEBUG, "discarding ms fart\n"); - asf_st->frag_offset = 0; - av_free_packet(&asf_st->pkt); - continue; - } - } - - /* return packet */ - if (asf_st->ds_span > 1) { - if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span){ - av_log(s, AV_LOG_ERROR, "pkt.size != ds_packet_size * ds_span (%d %d %d)\n", asf_st->pkt.size, asf_st->ds_packet_size, asf_st->ds_span); - }else{ - /* packet descrambling */ - uint8_t *newdata = av_malloc(asf_st->pkt.size); - if (newdata) { - int offset = 0; - while (offset < asf_st->pkt.size) { - int off = offset / asf_st->ds_chunk_size; - int row = off / asf_st->ds_span; - int col = off % asf_st->ds_span; - int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size; - //printf("off:%d row:%d col:%d idx:%d\n", off, row, col, idx); - - assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size); - assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size); - memcpy(newdata + offset, - asf_st->pkt.data + idx * asf_st->ds_chunk_size, - asf_st->ds_chunk_size); - offset += asf_st->ds_chunk_size; - } - av_free(asf_st->pkt.data); - asf_st->pkt.data = newdata; - } - } - } - asf_st->frag_offset = 0; - *pkt= asf_st->pkt; - //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size); - asf_st->pkt.size = 0; - asf_st->pkt.data = 0; - break; // packet completed - } - } - return 0; -} - -static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ASFContext *asf = s->priv_data; - - for (;;) { - int ret; - - /* parse cached packets, if any */ - if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0) - return ret; - if ((ret = ff_asf_get_packet(s, s->pb)) < 0) - assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1); - asf->packet_time_start = 0; - } - - return 0; -} - -// Added to support seeking after packets have been read -// If information is not reset, read_packet fails due to -// leftover information from previous reads -static void asf_reset_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - ASFStream *asf_st; - int i; - - asf->packet_nb_frames = 0; - asf->packet_size_left = 0; - asf->packet_segments = 0; - asf->packet_flags = 0; - asf->packet_property = 0; - asf->packet_timestamp = 0; - asf->packet_segsizetype = 0; - asf->packet_segments = 0; - asf->packet_seq = 0; - asf->packet_replic_size = 0; - asf->packet_key_frame = 0; - asf->packet_padsize = 0; - asf->packet_frag_offset = 0; - asf->packet_frag_size = 0; - asf->packet_frag_timestamp = 0; - asf->packet_multi_size = 0; - asf->packet_obj_size = 0; - asf->packet_time_delta = 0; - asf->packet_time_start = 0; - - for(i=0; inb_streams; i++){ - asf_st= s->streams[i]->priv_data; - av_free_packet(&asf_st->pkt); - asf_st->frag_offset=0; - asf_st->seq=0; - } - asf->asf_st= NULL; -} - -static int asf_read_close(AVFormatContext *s) -{ - int i; - - asf_reset_header(s); - for(i=0;inb_streams;i++) { - AVStream *st = s->streams[i]; - av_free(st->codec->palctrl); - } - return 0; -} - -static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit) -{ - AVPacket pkt1, *pkt = &pkt1; - ASFStream *asf_st; - int64_t pts; - int64_t pos= *ppos; - int i; - int64_t start_pos[s->nb_streams]; - - for(i=0; inb_streams; i++){ - start_pos[i]= pos; - } - - if (s->packet_size > 0) - pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset; - *ppos= pos; - url_fseek(s->pb, pos, SEEK_SET); - -//printf("asf_read_pts\n"); - asf_reset_header(s); - for(;;){ - if (av_read_frame(s, pkt) < 0){ - av_log(s, AV_LOG_INFO, "asf_read_pts failed\n"); - return AV_NOPTS_VALUE; - } - - pts= pkt->pts; - - av_free_packet(pkt); - if(pkt->flags&AV_PKT_FLAG_KEY){ - i= pkt->stream_index; - - asf_st= s->streams[i]->priv_data; - -// assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0); - pos= asf_st->packet_pos; - - av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME); - start_pos[i]= asf_st->packet_pos + 1; - - if(pkt->stream_index == stream_index) - break; - } - } - - *ppos= pos; -//printf("found keyframe at %"PRId64" stream %d stamp:%"PRId64"\n", *ppos, stream_index, pts); - - return pts; -} - -static void asf_build_simple_index(AVFormatContext *s, int stream_index) -{ - ff_asf_guid g; - ASFContext *asf = s->priv_data; - int64_t current_pos= url_ftell(s->pb); - int i; - - url_fseek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET); - get_guid(s->pb, &g); - if (!guidcmp(&g, &index_guid)) { - int64_t itime, last_pos=-1; - int pct, ict; - int64_t av_unused gsize= get_le64(s->pb); - get_guid(s->pb, &g); - itime=get_le64(s->pb); - pct=get_le32(s->pb); - ict=get_le32(s->pb); - av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict); - - for (i=0;ipb); - int pktct =get_le16(s->pb); - int64_t pos = s->data_offset + s->packet_size*(int64_t)pktnum; - int64_t index_pts= av_rescale(itime, i, 10000); - - if(pos != last_pos){ - av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d\n", pktnum, pktct); - av_add_index_entry(s->streams[stream_index], pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME); - last_pos=pos; - } - } - asf->index_read= 1; - } - url_fseek(s->pb, current_pos, SEEK_SET); -} - -static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags) -{ - ASFContext *asf = s->priv_data; - AVStream *st = s->streams[stream_index]; - int64_t pos; - int index; - - if (s->packet_size <= 0) - return -1; - - /* Try using the protocol's read_seek if available */ - if(s->pb) { - int ret = av_url_read_fseek(s->pb, stream_index, pts, flags); - if(ret >= 0) - asf_reset_header(s); - if (ret != AVERROR(ENOSYS)) - return ret; - } - - if (!asf->index_read) - asf_build_simple_index(s, stream_index); - - if(!(asf->index_read && st->index_entries)){ - if(av_seek_frame_binary(s, stream_index, pts, flags)<0) - return -1; - }else{ - index= av_index_search_timestamp(st, pts, flags); - if(index<0) - return -1; - - /* find the position */ - pos = st->index_entries[index].pos; - - // various attempts to find key frame have failed so far - // asf_reset_header(s); - // url_fseek(s->pb, pos, SEEK_SET); - // key_pos = pos; - // for(i=0;i<16;i++){ - // pos = url_ftell(s->pb); - // if (av_read_frame(s, &pkt) < 0){ - // av_log(s, AV_LOG_INFO, "seek failed\n"); - // return -1; - // } - // asf_st = s->streams[stream_index]->priv_data; - // pos += st->parser->frame_offset; - // - // if (pkt.size > b) { - // b = pkt.size; - // key_pos = pos; - // } - // - // av_free_packet(&pkt); - // } - - /* do the seek */ - av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos); - url_fseek(s->pb, pos, SEEK_SET); - } - asf_reset_header(s); - return 0; -} - -AVInputFormat asf_demuxer = { - "asf", - NULL_IF_CONFIG_SMALL("ASF format"), - sizeof(ASFContext), - asf_probe, - asf_read_header, - asf_read_packet, - asf_read_close, - asf_read_seek, - asf_read_pts, - .metadata_conv = ff_asf_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/asfenc.c b/tizen/distrib/ffmpeg/libavformat/asfenc.c deleted file mode 100644 index 9f8d69a..0000000 --- a/tizen/distrib/ffmpeg/libavformat/asfenc.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * ASF muxer - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "metadata.h" -#include "riff.h" -#include "asf.h" - -#undef NDEBUG -#include - - -#define ASF_INDEXED_INTERVAL 10000000 -#define ASF_INDEX_BLOCK 600 - -#define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2 -#define ASF_PACKET_ERROR_CORRECTION_FLAGS (\ - ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT | \ - ASF_PACKET_ERROR_CORRECTION_DATA_SIZE\ - ) - -#if (ASF_PACKET_ERROR_CORRECTION_FLAGS != 0) -# define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 1 -#else -# define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 0 -#endif - -#define ASF_PPI_PROPERTY_FLAGS (\ - ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE | \ - ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD | \ - ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE | \ - ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE \ - ) - -#define ASF_PPI_LENGTH_TYPE_FLAGS 0 - -#define ASF_PAYLOAD_FLAGS ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD - -#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) -# define ASF_PPI_SEQUENCE_FIELD_SIZE 1 -#endif -#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) -# define ASF_PPI_SEQUENCE_FIELD_SIZE 2 -#endif -#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) -# define ASF_PPI_SEQUENCE_FIELD_SIZE 4 -#endif -#ifndef ASF_PPI_SEQUENCE_FIELD_SIZE -# define ASF_PPI_SEQUENCE_FIELD_SIZE 0 -#endif - - -#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 2 -#endif -#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 4 -#endif -#ifndef ASF_PPI_PACKET_LENGTH_FIELD_SIZE -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 0 -#endif - -#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 2 -#endif -#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 4 -#endif -#ifndef ASF_PPI_PADDING_LENGTH_FIELD_SIZE -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 2 -#endif -#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 4 -#endif -#ifndef ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 2 -#endif -#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 4 -#endif -#ifndef ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 2 -#endif -#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 4 -#endif -#ifndef ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 2 -#endif -#ifndef ASF_PAYLOAD_LENGTH_FIELD_SIZE -# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 0 -#endif - -#define PACKET_HEADER_MIN_SIZE (\ - ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE + \ - ASF_PACKET_ERROR_CORRECTION_DATA_SIZE + \ - 1 + /*Length Type Flags*/ \ - 1 + /*Property Flags*/ \ - ASF_PPI_PACKET_LENGTH_FIELD_SIZE + \ - ASF_PPI_SEQUENCE_FIELD_SIZE + \ - ASF_PPI_PADDING_LENGTH_FIELD_SIZE + \ - 4 + /*Send Time Field*/ \ - 2 /*Duration Field*/ \ - ) - - -// Replicated Data shall be at least 8 bytes long. -#define ASF_PAYLOAD_REPLICATED_DATA_LENGTH 0x08 - -#define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD (\ - 1 + /*Stream Number*/ \ - ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \ - ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH \ - ) - -#define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS (\ - 1 + /*Stream Number*/ \ - ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \ - ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH + \ - ASF_PAYLOAD_LENGTH_FIELD_SIZE \ - ) - -#define SINGLE_PAYLOAD_DATA_LENGTH (\ - PACKET_SIZE - \ - PACKET_HEADER_MIN_SIZE - \ - PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD \ - ) - -#define MULTI_PAYLOAD_CONSTANT (\ - PACKET_SIZE - \ - PACKET_HEADER_MIN_SIZE - \ - 1 - /*Payload Flags*/ \ - 2*PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS \ - ) - -static const AVCodecTag codec_asf_bmp_tags[] = { - { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') }, - { CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') }, - { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') }, - { CODEC_ID_NONE, 0 }, -}; - -#define PREROLL_TIME 3100 - -static void put_guid(ByteIOContext *s, const ff_asf_guid *g) -{ - assert(sizeof(*g) == 16); - put_buffer(s, *g, sizeof(*g)); -} - -static void put_str16(ByteIOContext *s, const char *tag) -{ - int len; - uint8_t *pb; - ByteIOContext *dyn_buf; - if (url_open_dyn_buf(&dyn_buf) < 0) - return; - - ff_put_str16_nolen(dyn_buf, tag); - len = url_close_dyn_buf(dyn_buf, &pb); - put_le16(s, len); - put_buffer(s, pb, len); - av_freep(&pb); -} - -static int64_t put_header(ByteIOContext *pb, const ff_asf_guid *g) -{ - int64_t pos; - - pos = url_ftell(pb); - put_guid(pb, g); - put_le64(pb, 24); - return pos; -} - -/* update header size */ -static void end_header(ByteIOContext *pb, int64_t pos) -{ - int64_t pos1; - - pos1 = url_ftell(pb); - url_fseek(pb, pos + 16, SEEK_SET); - put_le64(pb, pos1 - pos); - url_fseek(pb, pos1, SEEK_SET); -} - -/* write an asf chunk (only used in streaming case) */ -static void put_chunk(AVFormatContext *s, int type, int payload_length, int flags) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = s->pb; - int length; - - length = payload_length + 8; - put_le16(pb, type); - put_le16(pb, length); //size - put_le32(pb, asf->seqno);//sequence number - put_le16(pb, flags); /* unknown bytes */ - put_le16(pb, length); //size_confirm - asf->seqno++; -} - -/* convert from unix to windows time */ -static int64_t unix_to_file_time(int ti) -{ - int64_t t; - - t = ti * INT64_C(10000000); - t += INT64_C(116444736000000000); - return t; -} - -/* write the header (used two times if non streamed) */ -static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data_chunk_size) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = s->pb; - AVMetadataTag *tags[5]; - int header_size, n, extra_size, extra_size2, wav_extra_size, file_time; - int has_title; - int metadata_count; - AVCodecContext *enc; - int64_t header_offset, cur_pos, hpos; - int bit_rate; - int64_t duration; - - tags[0] = av_metadata_get(s->metadata, "title" , NULL, 0); - tags[1] = av_metadata_get(s->metadata, "author" , NULL, 0); - tags[2] = av_metadata_get(s->metadata, "copyright", NULL, 0); - tags[3] = av_metadata_get(s->metadata, "comment" , NULL, 0); - tags[4] = av_metadata_get(s->metadata, "rating" , NULL, 0); - - duration = asf->duration + PREROLL_TIME * 10000; - has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4]; - metadata_count = s->metadata ? s->metadata->count : 0; - - bit_rate = 0; - for(n=0;nnb_streams;n++) { - enc = s->streams[n]->codec; - - av_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */ - - bit_rate += enc->bit_rate; - } - - if (asf->is_streamed) { - put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */ - } - - put_guid(pb, &ff_asf_header); - put_le64(pb, -1); /* header length, will be patched after */ - put_le32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */ - put_byte(pb, 1); /* ??? */ - put_byte(pb, 2); /* ??? */ - - /* file header */ - header_offset = url_ftell(pb); - hpos = put_header(pb, &ff_asf_file_header); - put_guid(pb, &ff_asf_my_guid); - put_le64(pb, file_size); - file_time = 0; - put_le64(pb, unix_to_file_time(file_time)); - put_le64(pb, asf->nb_packets); /* number of packets */ - put_le64(pb, duration); /* end time stamp (in 100ns units) */ - put_le64(pb, asf->duration); /* duration (in 100ns units) */ - put_le64(pb, PREROLL_TIME); /* start time stamp */ - put_le32(pb, (asf->is_streamed || url_is_streamed(pb)) ? 3 : 2); /* ??? */ - put_le32(pb, s->packet_size); /* packet size */ - put_le32(pb, s->packet_size); /* packet size */ - put_le32(pb, bit_rate); /* Nominal data rate in bps */ - end_header(pb, hpos); - - /* unknown headers */ - hpos = put_header(pb, &ff_asf_head1_guid); - put_guid(pb, &ff_asf_head2_guid); - put_le32(pb, 6); - put_le16(pb, 0); - end_header(pb, hpos); - - /* title and other infos */ - if (has_title) { - int len; - uint8_t *buf; - ByteIOContext *dyn_buf; - - if (url_open_dyn_buf(&dyn_buf) < 0) - return AVERROR(ENOMEM); - - hpos = put_header(pb, &ff_asf_comment_header); - - for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) { - len = tags[n] ? ff_put_str16_nolen(dyn_buf, tags[n]->value) : 0; - put_le16(pb, len); - } - len = url_close_dyn_buf(dyn_buf, &buf); - put_buffer(pb, buf, len); - av_freep(&buf); - end_header(pb, hpos); - } - if (metadata_count) { - AVMetadataTag *tag = NULL; - hpos = put_header(pb, &ff_asf_extended_content_header); - put_le16(pb, metadata_count); - while ((tag = av_metadata_get(s->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) { - put_str16(pb, tag->key); - put_le16(pb, 0); - put_str16(pb, tag->value); - } - end_header(pb, hpos); - } - - /* stream headers */ - for(n=0;nnb_streams;n++) { - int64_t es_pos; - // ASFStream *stream = &asf->streams[n]; - - enc = s->streams[n]->codec; - asf->streams[n].num = n + 1; - asf->streams[n].seq = 0; - - - switch(enc->codec_type) { - case AVMEDIA_TYPE_AUDIO: - wav_extra_size = 0; - extra_size = 18 + wav_extra_size; - extra_size2 = 8; - break; - default: - case AVMEDIA_TYPE_VIDEO: - wav_extra_size = enc->extradata_size; - extra_size = 0x33 + wav_extra_size; - extra_size2 = 0; - break; - } - - hpos = put_header(pb, &ff_asf_stream_header); - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - put_guid(pb, &ff_asf_audio_stream); - put_guid(pb, &ff_asf_audio_conceal_spread); - } else { - put_guid(pb, &ff_asf_video_stream); - put_guid(pb, &ff_asf_video_conceal_none); - } - put_le64(pb, 0); /* ??? */ - es_pos = url_ftell(pb); - put_le32(pb, extra_size); /* wav header len */ - put_le32(pb, extra_size2); /* additional data len */ - put_le16(pb, n + 1); /* stream number */ - put_le32(pb, 0); /* ??? */ - - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - /* WAVEFORMATEX header */ - int wavsize = ff_put_wav_header(pb, enc); - if ((enc->codec_id != CODEC_ID_MP3) && (enc->codec_id != CODEC_ID_MP2) && (enc->codec_id != CODEC_ID_ADPCM_IMA_WAV) && (enc->extradata_size==0)) { - wavsize += 2; - put_le16(pb, 0); - } - - if (wavsize < 0) - return -1; - if (wavsize != extra_size) { - cur_pos = url_ftell(pb); - url_fseek(pb, es_pos, SEEK_SET); - put_le32(pb, wavsize); /* wav header len */ - url_fseek(pb, cur_pos, SEEK_SET); - } - /* ERROR Correction */ - put_byte(pb, 0x01); - if(enc->codec_id == CODEC_ID_ADPCM_G726 || !enc->block_align){ - put_le16(pb, 0x0190); - put_le16(pb, 0x0190); - }else{ - put_le16(pb, enc->block_align); - put_le16(pb, enc->block_align); - } - put_le16(pb, 0x01); - put_byte(pb, 0x00); - } else { - put_le32(pb, enc->width); - put_le32(pb, enc->height); - put_byte(pb, 2); /* ??? */ - put_le16(pb, 40 + enc->extradata_size); /* size */ - - /* BITMAPINFOHEADER header */ - ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1); - } - end_header(pb, hpos); - } - - /* media comments */ - - hpos = put_header(pb, &ff_asf_codec_comment_header); - put_guid(pb, &ff_asf_codec_comment1_header); - put_le32(pb, s->nb_streams); - for(n=0;nnb_streams;n++) { - AVCodec *p; - const char *desc; - int len; - uint8_t *buf; - ByteIOContext *dyn_buf; - - enc = s->streams[n]->codec; - p = avcodec_find_encoder(enc->codec_id); - - if(enc->codec_type == AVMEDIA_TYPE_AUDIO) - put_le16(pb, 2); - else if(enc->codec_type == AVMEDIA_TYPE_VIDEO) - put_le16(pb, 1); - else - put_le16(pb, -1); - - if(enc->codec_id == CODEC_ID_WMAV2) - desc = "Windows Media Audio V8"; - else - desc = p ? p->name : enc->codec_name; - - if ( url_open_dyn_buf(&dyn_buf) < 0) - return AVERROR(ENOMEM); - - ff_put_str16_nolen(dyn_buf, desc); - len = url_close_dyn_buf(dyn_buf, &buf); - put_le16(pb, len / 2); // "number of characters" = length in bytes / 2 - - put_buffer(pb, buf, len); - av_freep(&buf); - - put_le16(pb, 0); /* no parameters */ - - - /* id */ - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - put_le16(pb, 2); - put_le16(pb, enc->codec_tag); - } else { - put_le16(pb, 4); - put_le32(pb, enc->codec_tag); - } - if(!enc->codec_tag) - return -1; - } - end_header(pb, hpos); - - /* patch the header size fields */ - - cur_pos = url_ftell(pb); - header_size = cur_pos - header_offset; - if (asf->is_streamed) { - header_size += 8 + 30 + 50; - - url_fseek(pb, header_offset - 10 - 30, SEEK_SET); - put_le16(pb, header_size); - url_fseek(pb, header_offset - 2 - 30, SEEK_SET); - put_le16(pb, header_size); - - header_size -= 8 + 30 + 50; - } - header_size += 24 + 6; - url_fseek(pb, header_offset - 14, SEEK_SET); - put_le64(pb, header_size); - url_fseek(pb, cur_pos, SEEK_SET); - - /* movie chunk, followed by packets of packet_size */ - asf->data_offset = cur_pos; - put_guid(pb, &ff_asf_data_header); - put_le64(pb, data_chunk_size); - put_guid(pb, &ff_asf_my_guid); - put_le64(pb, asf->nb_packets); /* nb packets */ - put_byte(pb, 1); /* ??? */ - put_byte(pb, 1); /* ??? */ - return 0; -} - -static int asf_write_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - - s->packet_size = PACKET_SIZE; - asf->nb_packets = 0; - - asf->last_indexed_pts = 0; - asf->index_ptr = av_malloc( sizeof(ASFIndex) * ASF_INDEX_BLOCK ); - asf->nb_index_memory_alloc = ASF_INDEX_BLOCK; - asf->nb_index_count = 0; - asf->maximum_packet = 0; - - /* the data-chunk-size has to be 50, which is data_size - asf->data_offset - * at the moment this function is done. It is needed to use asf as - * streamable format. */ - if (asf_write_header1(s, 0, 50) < 0) { - //av_free(asf); - return -1; - } - - put_flush_packet(s->pb); - - asf->packet_nb_payloads = 0; - asf->packet_timestamp_start = -1; - asf->packet_timestamp_end = -1; - init_put_byte(&asf->pb, asf->packet_buf, s->packet_size, 1, - NULL, NULL, NULL, NULL); - - return 0; -} - -static int asf_write_stream_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - - asf->is_streamed = 1; - - return asf_write_header(s); -} - -static int put_payload_parsing_info( - AVFormatContext *s, - unsigned int sendtime, - unsigned int duration, - int nb_payloads, - int padsize - ) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = s->pb; - int ppi_size, i; - int64_t start= url_ftell(pb); - - int iLengthTypeFlags = ASF_PPI_LENGTH_TYPE_FLAGS; - - padsize -= PACKET_HEADER_MIN_SIZE; - if(asf->multi_payloads_present) - padsize--; - assert(padsize>=0); - - put_byte(pb, ASF_PACKET_ERROR_CORRECTION_FLAGS); - for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++){ - put_byte(pb, 0x0); - } - - if (asf->multi_payloads_present) - iLengthTypeFlags |= ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT; - - if (padsize > 0) { - if (padsize < 256) - iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE; - else - iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD; - } - put_byte(pb, iLengthTypeFlags); - - put_byte(pb, ASF_PPI_PROPERTY_FLAGS); - - if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD) - put_le16(pb, padsize - 2); - if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE) - put_byte(pb, padsize - 1); - - put_le32(pb, sendtime); - put_le16(pb, duration); - if (asf->multi_payloads_present) - put_byte(pb, nb_payloads | ASF_PAYLOAD_FLAGS); - - ppi_size = url_ftell(pb) - start; - - return ppi_size; -} - -static void flush_packet(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - int packet_hdr_size, packet_filled_size; - - assert(asf->packet_timestamp_end >= asf->packet_timestamp_start); - - if (asf->is_streamed) { - put_chunk(s, 0x4424, s->packet_size, 0); - } - - packet_hdr_size = put_payload_parsing_info( - s, - asf->packet_timestamp_start, - asf->packet_timestamp_end - asf->packet_timestamp_start, - asf->packet_nb_payloads, - asf->packet_size_left - ); - - packet_filled_size = PACKET_SIZE - asf->packet_size_left; - assert(packet_hdr_size <= asf->packet_size_left); - memset(asf->packet_buf + packet_filled_size, 0, asf->packet_size_left); - - put_buffer(s->pb, asf->packet_buf, s->packet_size - packet_hdr_size); - - put_flush_packet(s->pb); - asf->nb_packets++; - asf->packet_nb_payloads = 0; - asf->packet_timestamp_start = -1; - asf->packet_timestamp_end = -1; - init_put_byte(&asf->pb, asf->packet_buf, s->packet_size, 1, - NULL, NULL, NULL, NULL); -} - -static void put_payload_header( - AVFormatContext *s, - ASFStream *stream, - int presentation_time, - int m_obj_size, - int m_obj_offset, - int payload_len, - int flags - ) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = &asf->pb; - int val; - - val = stream->num; - if (flags & AV_PKT_FLAG_KEY) - val |= ASF_PL_FLAG_KEY_FRAME; - put_byte(pb, val); - - put_byte(pb, stream->seq); //Media object number - put_le32(pb, m_obj_offset); //Offset Into Media Object - - // Replicated Data shall be at least 8 bytes long. - // The first 4 bytes of data shall contain the - // Size of the Media Object that the payload belongs to. - // The next 4 bytes of data shall contain the - // Presentation Time for the media object that the payload belongs to. - put_byte(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH); - - put_le32(pb, m_obj_size); //Replicated Data - Media Object Size - put_le32(pb, presentation_time);//Replicated Data - Presentation Time - - if (asf->multi_payloads_present){ - put_le16(pb, payload_len); //payload length - } -} - -static void put_frame( - AVFormatContext *s, - ASFStream *stream, - AVStream *avst, - int timestamp, - const uint8_t *buf, - int m_obj_size, - int flags - ) -{ - ASFContext *asf = s->priv_data; - int m_obj_offset, payload_len, frag_len1; - - m_obj_offset = 0; - while (m_obj_offset < m_obj_size) { - payload_len = m_obj_size - m_obj_offset; - if (asf->packet_timestamp_start == -1) { - asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT); - - asf->packet_size_left = PACKET_SIZE; - if (asf->multi_payloads_present){ - frag_len1 = MULTI_PAYLOAD_CONSTANT - 1; - } - else { - frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH; - } - asf->packet_timestamp_start = timestamp; - } - else { - // multi payloads - frag_len1 = asf->packet_size_left - PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS - PACKET_HEADER_MIN_SIZE - 1; - - if(frag_len1 < payload_len && avst->codec->codec_type == AVMEDIA_TYPE_AUDIO){ - flush_packet(s); - continue; - } - } - if (frag_len1 > 0) { - if (payload_len > frag_len1) - payload_len = frag_len1; - else if (payload_len == (frag_len1 - 1)) - payload_len = frag_len1 - 2; //additional byte need to put padding length - - put_payload_header(s, stream, timestamp+PREROLL_TIME, m_obj_size, m_obj_offset, payload_len, flags); - put_buffer(&asf->pb, buf, payload_len); - - if (asf->multi_payloads_present) - asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS); - else - asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD); - asf->packet_timestamp_end = timestamp; - - asf->packet_nb_payloads++; - } else { - payload_len = 0; - } - m_obj_offset += payload_len; - buf += payload_len; - - if (!asf->multi_payloads_present) - flush_packet(s); - else if (asf->packet_size_left <= (PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS + PACKET_HEADER_MIN_SIZE + 1)) - flush_packet(s); - } - stream->seq++; -} - -static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ASFContext *asf = s->priv_data; - ASFStream *stream; - int64_t duration; - AVCodecContext *codec; - int64_t packet_st,pts; - int start_sec,i; - int flags= pkt->flags; - - codec = s->streams[pkt->stream_index]->codec; - stream = &asf->streams[pkt->stream_index]; - - if(codec->codec_type == AVMEDIA_TYPE_AUDIO) - flags &= ~AV_PKT_FLAG_KEY; - - pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts; - assert(pts != AV_NOPTS_VALUE); - duration = pts * 10000; - asf->duration= FFMAX(asf->duration, duration + pkt->duration * 10000); - - packet_st = asf->nb_packets; - put_frame(s, stream, s->streams[pkt->stream_index], pkt->dts, pkt->data, pkt->size, flags); - - /* check index */ - if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) { - start_sec = (int)(duration / INT64_C(10000000)); - if (start_sec != (int)(asf->last_indexed_pts / INT64_C(10000000))) { - for(i=asf->nb_index_count;i=asf->nb_index_memory_alloc) { - asf->nb_index_memory_alloc += ASF_INDEX_BLOCK; - asf->index_ptr = (ASFIndex*)av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc ); - } - // store - asf->index_ptr[i].packet_number = (uint32_t)packet_st; - asf->index_ptr[i].packet_count = (uint16_t)(asf->nb_packets-packet_st); - asf->maximum_packet = FFMAX(asf->maximum_packet, (uint16_t)(asf->nb_packets-packet_st)); - } - asf->nb_index_count = start_sec; - asf->last_indexed_pts = duration; - } - } - return 0; -} - -// -static int asf_write_index(AVFormatContext *s, ASFIndex *index, uint16_t max, uint32_t count) -{ - ByteIOContext *pb = s->pb; - int i; - - put_guid(pb, &ff_asf_simple_index_header); - put_le64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2)*count); - put_guid(pb, &ff_asf_my_guid); - put_le64(pb, ASF_INDEXED_INTERVAL); - put_le32(pb, max); - put_le32(pb, count); - for(i=0; ipriv_data; - int64_t file_size,data_size; - - /* flush the current packet */ - if (asf->pb.buf_ptr > asf->pb.buffer) - flush_packet(s); - - /* write index */ - data_size = url_ftell(s->pb); - if ((!asf->is_streamed) && (asf->nb_index_count != 0)) { - asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->nb_index_count); - } - put_flush_packet(s->pb); - - if (asf->is_streamed || url_is_streamed(s->pb)) { - put_chunk(s, 0x4524, 0, 0); /* end of stream */ - } else { - /* rewrite an updated header */ - file_size = url_ftell(s->pb); - url_fseek(s->pb, 0, SEEK_SET); - asf_write_header1(s, file_size, data_size - asf->data_offset); - } - - put_flush_packet(s->pb); - av_free(asf->index_ptr); - return 0; -} - -#if CONFIG_ASF_MUXER -AVOutputFormat asf_muxer = { - "asf", - NULL_IF_CONFIG_SMALL("ASF format"), - "video/x-ms-asf", - "asf,wmv,wma", - sizeof(ASFContext), -#if CONFIG_LIBMP3LAME - CODEC_ID_MP3, -#else - CODEC_ID_MP2, -#endif - CODEC_ID_MSMPEG4V3, - asf_write_header, - asf_write_packet, - asf_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, - .metadata_conv = ff_asf_metadata_conv, -}; -#endif - -#if CONFIG_ASF_STREAM_MUXER -AVOutputFormat asf_stream_muxer = { - "asf_stream", - NULL_IF_CONFIG_SMALL("ASF format"), - "video/x-ms-asf", - "asf,wmv,wma", - sizeof(ASFContext), -#if CONFIG_LIBMP3LAME - CODEC_ID_MP3, -#else - CODEC_ID_MP2, -#endif - CODEC_ID_MSMPEG4V3, - asf_write_stream_header, - asf_write_packet, - asf_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, - .metadata_conv = ff_asf_metadata_conv, -}; -#endif //CONFIG_ASF_STREAM_MUXER diff --git a/tizen/distrib/ffmpeg/libavformat/assdec.c b/tizen/distrib/ffmpeg/libavformat/assdec.c deleted file mode 100644 index 5f8e0b9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/assdec.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * SSA/ASS demuxer - * Copyright (c) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" - -#define MAX_LINESIZE 2000 - -typedef struct ASSContext{ - uint8_t *event_buffer; - uint8_t **event; - unsigned int event_count; - unsigned int event_index; -}ASSContext; - -static void get_line(ByteIOContext *s, char *buf, int maxlen) -{ - int i = 0; - char c; - - do{ - c = get_byte(s); - if (i < maxlen-1) - buf[i++] = c; - }while(c != '\n' && c); - - buf[i] = 0; -} - -static int probe(AVProbeData *p) -{ - const char *header= "[Script Info]"; - - if( !memcmp(p->buf , header, strlen(header)) - || !memcmp(p->buf+3, header, strlen(header))) - return AVPROBE_SCORE_MAX; - - return 0; -} - -static int read_close(AVFormatContext *s) -{ - ASSContext *ass = s->priv_data; - - av_freep(&ass->event_buffer); - av_freep(&ass->event); - - return 0; -} - -static int64_t get_pts(const uint8_t *p) -{ - int hour, min, sec, hsec; - - if(sscanf(p, "%*[^,],%d:%d:%d%*c%d", &hour, &min, &sec, &hsec) != 4) - return AV_NOPTS_VALUE; - -// av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d [%s]\n", i, hour, min, sec, hsec, p); - - min+= 60*hour; - sec+= 60*min; - - return sec*100+hsec; -} - -static int event_cmp(uint8_t **a, uint8_t **b) -{ - return get_pts(*a) - get_pts(*b); -} - -static int read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - int i, header_remaining; - ASSContext *ass = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - int allocated[2]={0}; - uint8_t *p, **dst[2]={0}; - int pos[2]={0}; - - st = av_new_stream(s, 0); - if (!st) - return -1; - av_set_pts_info(st, 64, 1, 100); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id= CODEC_ID_SSA; - - header_remaining= INT_MAX; - dst[0] = &st->codec->extradata; - dst[1] = &ass->event_buffer; - while(!url_feof(pb)){ - uint8_t line[MAX_LINESIZE]; - - get_line(pb, line, sizeof(line)); - - if(!memcmp(line, "[Events]", 8)) - header_remaining= 2; - else if(line[0]=='[') - header_remaining= INT_MAX; - - i= header_remaining==0; - - if(i && get_pts(line) == AV_NOPTS_VALUE) - continue; - - p = av_fast_realloc(*(dst[i]), &allocated[i], pos[i]+MAX_LINESIZE); - if(!p) - goto fail; - *(dst[i])= p; - memcpy(p + pos[i], line, strlen(line)+1); - pos[i] += strlen(line); - if(i) ass->event_count++; - else header_remaining--; - } - st->codec->extradata_size= pos[0]; - - if(ass->event_count >= UINT_MAX / sizeof(*ass->event)) - goto fail; - - ass->event= av_malloc(ass->event_count * sizeof(*ass->event)); - p= ass->event_buffer; - for(i=0; ievent_count; i++){ - ass->event[i]= p; - while(*p && *p != '\n') - p++; - p++; - } - - qsort(ass->event, ass->event_count, sizeof(*ass->event), (void*)event_cmp); - - return 0; - -fail: - read_close(s); - - return -1; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ASSContext *ass = s->priv_data; - uint8_t *p, *end; - - if(ass->event_index >= ass->event_count) - return AVERROR(EIO); - - p= ass->event[ ass->event_index ]; - - end= strchr(p, '\n'); - av_new_packet(pkt, end ? end-p+1 : strlen(p)); - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pos= p - ass->event_buffer + s->streams[0]->codec->extradata_size; - pkt->pts= pkt->dts= get_pts(p); - memcpy(pkt->data, p, pkt->size); - - ass->event_index++; - - return 0; -} - -AVInputFormat ass_demuxer = { - "ass", - NULL_IF_CONFIG_SMALL("SSA/ASS format"), - sizeof(ASSContext), - probe, - read_header, - read_packet, - read_close, -// read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/assenc.c b/tizen/distrib/ffmpeg/libavformat/assenc.c deleted file mode 100644 index d1b93e8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/assenc.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * SSA/ASS muxer - * Copyright (c) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" - -typedef struct ASSContext{ - unsigned int extra_index; -}ASSContext; - -static int write_header(AVFormatContext *s) -{ - ASSContext *ass = s->priv_data; - AVCodecContext *avctx= s->streams[0]->codec; - uint8_t *last= NULL; - - if(s->nb_streams != 1 || avctx->codec_id != CODEC_ID_SSA){ - av_log(s, AV_LOG_ERROR, "Exactly one ASS/SSA stream is needed.\n"); - return -1; - } - - while(ass->extra_index < avctx->extradata_size){ - uint8_t *p = avctx->extradata + ass->extra_index; - uint8_t *end= strchr(p, '\n'); - if(!end) end= avctx->extradata + avctx->extradata_size; - else end++; - - put_buffer(s->pb, p, end-p); - ass->extra_index += end-p; - - if(last && !memcmp(last, "[Events]", 8)) - break; - last=p; - } - - put_flush_packet(s->pb); - - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - put_buffer(s->pb, pkt->data, pkt->size); - - put_flush_packet(s->pb); - - return 0; -} - -static int write_trailer(AVFormatContext *s) -{ - ASSContext *ass = s->priv_data; - AVCodecContext *avctx= s->streams[0]->codec; - - put_buffer(s->pb, avctx->extradata + ass->extra_index, - avctx->extradata_size - ass->extra_index); - - put_flush_packet(s->pb); - - return 0; -} - -AVOutputFormat ass_muxer = { - "ass", - NULL_IF_CONFIG_SMALL("SSA/ASS format"), - NULL, - "ass,ssa", - sizeof(ASSContext), - CODEC_ID_NONE, - CODEC_ID_NONE, - write_header, - write_packet, - write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_NOTIMESTAMPS -}; diff --git a/tizen/distrib/ffmpeg/libavformat/au.c b/tizen/distrib/ffmpeg/libavformat/au.c deleted file mode 100644 index f8f718d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/au.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * AU muxer and demuxer - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * First version by Francois Revol revol@free.fr - * - * Reference documents: - * http://www.opengroup.org/public/pubs/external/auformat.html - * http://www.goice.co.jp/member/mo/formats/au.html - */ - -#include "avformat.h" -#include "raw.h" -#include "riff.h" - -/* if we don't know the size in advance */ -#define AU_UNKNOWN_SIZE ((uint32_t)(~0)) - -/* The ffmpeg codecs we support, and the IDs they have in the file */ -static const AVCodecTag codec_au_tags[] = { - { CODEC_ID_PCM_MULAW, 1 }, - { CODEC_ID_PCM_S8, 2 }, - { CODEC_ID_PCM_S16BE, 3 }, - { CODEC_ID_PCM_S24BE, 4 }, - { CODEC_ID_PCM_S32BE, 5 }, - { CODEC_ID_PCM_F32BE, 6 }, - { CODEC_ID_PCM_F64BE, 7 }, - { CODEC_ID_PCM_ALAW, 27 }, - { CODEC_ID_NONE, 0 }, -}; - -#if CONFIG_AU_MUXER -/* AUDIO_FILE header */ -static int put_au_header(ByteIOContext *pb, AVCodecContext *enc) -{ - if(!enc->codec_tag) - return -1; - put_tag(pb, ".snd"); /* magic number */ - put_be32(pb, 24); /* header size */ - put_be32(pb, AU_UNKNOWN_SIZE); /* data size */ - put_be32(pb, (uint32_t)enc->codec_tag); /* codec ID */ - put_be32(pb, enc->sample_rate); - put_be32(pb, (uint32_t)enc->channels); - return 0; -} - -static int au_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - - s->priv_data = NULL; - - /* format header */ - if (put_au_header(pb, s->streams[0]->codec) < 0) { - return -1; - } - - put_flush_packet(pb); - - return 0; -} - -static int au_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - put_buffer(pb, pkt->data, pkt->size); - return 0; -} - -static int au_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - int64_t file_size; - - if (!url_is_streamed(s->pb)) { - - /* update file size */ - file_size = url_ftell(pb); - url_fseek(pb, 8, SEEK_SET); - put_be32(pb, (uint32_t)(file_size - 24)); - url_fseek(pb, file_size, SEEK_SET); - - put_flush_packet(pb); - } - - return 0; -} -#endif /* CONFIG_AU_MUXER */ - -static int au_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf[0] == '.' && p->buf[1] == 's' && - p->buf[2] == 'n' && p->buf[3] == 'd') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* au input */ -static int au_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - int size; - unsigned int tag; - ByteIOContext *pb = s->pb; - unsigned int id, channels, rate; - enum CodecID codec; - AVStream *st; - - /* check ".snd" header */ - tag = get_le32(pb); - if (tag != MKTAG('.', 's', 'n', 'd')) - return -1; - size = get_be32(pb); /* header size */ - get_be32(pb); /* data size */ - - id = get_be32(pb); - rate = get_be32(pb); - channels = get_be32(pb); - - codec = ff_codec_get_id(codec_au_tags, id); - - if (size >= 24) { - /* skip unused data */ - url_fseek(pb, size - 24, SEEK_CUR); - } - - /* now we are ready: build format streams */ - st = av_new_stream(s, 0); - if (!st) - return -1; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = id; - st->codec->codec_id = codec; - st->codec->channels = channels; - st->codec->sample_rate = rate; - av_set_pts_info(st, 64, 1, rate); - return 0; -} - -#define BLOCK_SIZE 1024 - -static int au_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret; - - ret= av_get_packet(s->pb, pkt, BLOCK_SIZE * - s->streams[0]->codec->channels * - av_get_bits_per_sample(s->streams[0]->codec->codec_id) >> 3); - if (ret < 0) - return ret; - pkt->stream_index = 0; - - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - return 0; -} - -#if CONFIG_AU_DEMUXER -AVInputFormat au_demuxer = { - "au", - NULL_IF_CONFIG_SMALL("SUN AU format"), - 0, - au_probe, - au_read_header, - au_read_packet, - NULL, - pcm_read_seek, - .codec_tag= (const AVCodecTag* const []){codec_au_tags, 0}, -}; -#endif - -#if CONFIG_AU_MUXER -AVOutputFormat au_muxer = { - "au", - NULL_IF_CONFIG_SMALL("SUN AU format"), - "audio/basic", - "au", - 0, - CODEC_ID_PCM_S16BE, - CODEC_ID_NONE, - au_write_header, - au_write_packet, - au_write_trailer, - .codec_tag= (const AVCodecTag* const []){codec_au_tags, 0}, -}; -#endif //CONFIG_AU_MUXER diff --git a/tizen/distrib/ffmpeg/libavformat/audiointerleave.c b/tizen/distrib/ffmpeg/libavformat/audiointerleave.c deleted file mode 100644 index 3c235c0..0000000 --- a/tizen/distrib/ffmpeg/libavformat/audiointerleave.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Audio Interleaving functions - * - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/fifo.h" -#include "avformat.h" -#include "audiointerleave.h" -#include "internal.h" - -void ff_audio_interleave_close(AVFormatContext *s) -{ - int i; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - AudioInterleaveContext *aic = st->priv_data; - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - av_fifo_free(aic->fifo); - } -} - -int ff_audio_interleave_init(AVFormatContext *s, - const int *samples_per_frame, - AVRational time_base) -{ - int i; - - if (!samples_per_frame) - return -1; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - AudioInterleaveContext *aic = st->priv_data; - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - aic->sample_size = (st->codec->channels * - av_get_bits_per_sample(st->codec->codec_id)) / 8; - if (!aic->sample_size) { - av_log(s, AV_LOG_ERROR, "could not compute sample size\n"); - return -1; - } - aic->samples_per_frame = samples_per_frame; - aic->samples = aic->samples_per_frame; - aic->time_base = time_base; - - aic->fifo_size = 100* *aic->samples; - aic->fifo= av_fifo_alloc(100 * *aic->samples); - } - } - - return 0; -} - -static int ff_interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt, - int stream_index, int flush) -{ - AVStream *st = s->streams[stream_index]; - AudioInterleaveContext *aic = st->priv_data; - - int size = FFMIN(av_fifo_size(aic->fifo), *aic->samples * aic->sample_size); - if (!size || (!flush && size == av_fifo_size(aic->fifo))) - return 0; - - av_new_packet(pkt, size); - av_fifo_generic_read(aic->fifo, pkt->data, size, NULL); - - pkt->dts = pkt->pts = aic->dts; - pkt->duration = av_rescale_q(*aic->samples, st->time_base, aic->time_base); - pkt->stream_index = stream_index; - aic->dts += pkt->duration; - - aic->samples++; - if (!*aic->samples) - aic->samples = aic->samples_per_frame; - - return size; -} - -int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush, - int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int), - int (*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *)) -{ - int i; - - if (pkt) { - AVStream *st = s->streams[pkt->stream_index]; - AudioInterleaveContext *aic = st->priv_data; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - unsigned new_size = av_fifo_size(aic->fifo) + pkt->size; - if (new_size > aic->fifo_size) { - if (av_fifo_realloc2(aic->fifo, new_size) < 0) - return -1; - aic->fifo_size = new_size; - } - av_fifo_generic_write(aic->fifo, pkt->data, pkt->size, NULL); - } else { - // rewrite pts and dts to be decoded time line position - pkt->pts = pkt->dts = aic->dts; - aic->dts += pkt->duration; - ff_interleave_add_packet(s, pkt, compare_ts); - } - pkt = NULL; - } - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - AVPacket new_pkt; - while (ff_interleave_new_audio_packet(s, &new_pkt, i, flush)) - ff_interleave_add_packet(s, &new_pkt, compare_ts); - } - } - - return get_packet(s, out, pkt, flush); -} diff --git a/tizen/distrib/ffmpeg/libavformat/audiointerleave.h b/tizen/distrib/ffmpeg/libavformat/audiointerleave.h deleted file mode 100644 index c948c36..0000000 --- a/tizen/distrib/ffmpeg/libavformat/audiointerleave.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * audio interleaving prototypes and declarations - * - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_AUDIOINTERLEAVE_H -#define AVFORMAT_AUDIOINTERLEAVE_H - -#include "libavutil/fifo.h" -#include "avformat.h" - -typedef struct { - AVFifoBuffer *fifo; - unsigned fifo_size; ///< size of currently allocated FIFO - uint64_t dts; ///< current dts - int sample_size; ///< size of one sample all channels included - const int *samples_per_frame; ///< must be 0-terminated - const int *samples; ///< current samples per frame, pointer to samples_per_frame - AVRational time_base; ///< time base of output audio packets -} AudioInterleaveContext; - -int ff_audio_interleave_init(AVFormatContext *s, const int *samples_per_frame, AVRational time_base); -void ff_audio_interleave_close(AVFormatContext *s); - -int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt); -/** - * Rechunk audio PCM packets per AudioInterleaveContext->samples_per_frame - * and interleave them correctly. - * The first element of AVStream->priv_data must be AudioInterleaveContext - * when using this function. - * - * @param get_packet function will output a packet when streams are correctly interleaved. - * @param compare_ts function will compare AVPackets and decide interleaving order. - */ -int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush, - int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int), - int (*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *)); - -#endif /* AVFORMAT_AUDIOINTERLEAVE_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/avc.c b/tizen/distrib/ffmpeg/libavformat/avc.c deleted file mode 100644 index 7c99196..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avc.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * AVC helper functions for muxers - * Copyright (c) 2006 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "avio.h" -#include "avc.h" - -static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) -{ - const uint8_t *a = p + 4 - ((intptr_t)p & 3); - - for (end -= 3; p < a && p < end; p++) { - if (p[0] == 0 && p[1] == 0 && p[2] == 1) - return p; - } - - for (end -= 3; p < end; p += 4) { - uint32_t x = *(const uint32_t*)p; -// if ((x - 0x01000100) & (~x) & 0x80008000) // little endian -// if ((x - 0x00010001) & (~x) & 0x00800080) // big endian - if ((x - 0x01010101) & (~x) & 0x80808080) { // generic - if (p[1] == 0) { - if (p[0] == 0 && p[2] == 1) - return p; - if (p[2] == 0 && p[3] == 1) - return p+1; - } - if (p[3] == 0) { - if (p[2] == 0 && p[4] == 1) - return p+2; - if (p[4] == 0 && p[5] == 1) - return p+3; - } - } - } - - for (end += 3; p < end; p++) { - if (p[0] == 0 && p[1] == 0 && p[2] == 1) - return p; - } - - return end + 3; -} - -const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){ - const uint8_t *out= ff_avc_find_startcode_internal(p, end); - if(p 6) { - /* check for h264 start code */ - if (AV_RB32(data) == 0x00000001 || - AV_RB24(data) == 0x000001) { - uint8_t *buf=NULL, *end, *start; - uint32_t sps_size=0, pps_size=0; - uint8_t *sps=0, *pps=0; - - int ret = ff_avc_parse_nal_units_buf(data, &buf, &len); - if (ret < 0) - return ret; - start = buf; - end = buf + len; - - /* look for sps and pps */ - while (buf < end) { - unsigned int size; - uint8_t nal_type; - size = AV_RB32(buf); - nal_type = buf[4] & 0x1f; - if (nal_type == 7) { /* SPS */ - sps = buf + 4; - sps_size = size; - } else if (nal_type == 8) { /* PPS */ - pps = buf + 4; - pps_size = size; - } - buf += size + 4; - } - assert(sps); - assert(pps); - - put_byte(pb, 1); /* version */ - put_byte(pb, sps[1]); /* profile */ - put_byte(pb, sps[2]); /* profile compat */ - put_byte(pb, sps[3]); /* level */ - put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ - put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ - - put_be16(pb, sps_size); - put_buffer(pb, sps, sps_size); - put_byte(pb, 1); /* number of pps */ - put_be16(pb, pps_size); - put_buffer(pb, pps, pps_size); - av_free(start); - } else { - put_buffer(pb, data, len); - } - } - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavformat/avc.h b/tizen/distrib/ffmpeg/libavformat/avc.h deleted file mode 100644 index 2deb77d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avc.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * AVC helper functions for muxers - * Copyright (c) 2008 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_AVC_H -#define AVFORMAT_AVC_H - -#include -#include "avio.h" - -int ff_avc_parse_nal_units(ByteIOContext *s, const uint8_t *buf, int size); -int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size); -int ff_isom_write_avcc(ByteIOContext *pb, const uint8_t *data, int len); -const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end); - -#endif /* AVFORMAT_AVC_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/avformat.h b/tizen/distrib/ffmpeg/libavformat/avformat.h deleted file mode 100644 index 0e93376..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avformat.h +++ /dev/null @@ -1,1355 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_AVFORMAT_H -#define AVFORMAT_AVFORMAT_H - -#define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 64 -#define LIBAVFORMAT_VERSION_MICRO 2 - -#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ - LIBAVFORMAT_VERSION_MINOR, \ - LIBAVFORMAT_VERSION_MICRO) -#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \ - LIBAVFORMAT_VERSION_MINOR, \ - LIBAVFORMAT_VERSION_MICRO) -#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT - -#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) - -/** - * I return the LIBAVFORMAT_VERSION_INT constant. You got - * a fucking problem with that, douchebag? - */ -unsigned avformat_version(void); - -/** - * Returns the libavformat build-time configuration. - */ -const char *avformat_configuration(void); - -/** - * Returns the libavformat license. - */ -const char *avformat_license(void); - -#include -#include /* FILE */ -#include "libavcodec/avcodec.h" - -#include "avio.h" - -struct AVFormatContext; - - -/* - * Public Metadata API. - * The metadata API allows libavformat to export metadata tags to a client - * application using a sequence of key/value pairs. Like all strings in FFmpeg, - * metadata must be stored as UTF-8 encoded Unicode. Note that metadata - * exported by demuxers isn't checked to be valid UTF-8 in most cases. - * Important concepts to keep in mind: - * 1. Keys are unique; there can never be 2 tags with the same key. This is - * also meant semantically, i.e., a demuxer should not knowingly produce - * several keys that are literally different but semantically identical. - * E.g., key=Author5, key=Author6. In this example, all authors must be - * placed in the same tag. - * 2. Metadata is flat, not hierarchical; there are no subtags. If you - * want to store, e.g., the email address of the child of producer Alice - * and actor Bob, that could have key=alice_and_bobs_childs_email_address. - * 3. Several modifiers can be applied to the tag name. This is done by - * appending a dash character ('-') and the modifier name in the order - * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng. - * a) language -- a tag whose value is localized for a particular language - * is appended with the ISO 639-2/B 3-letter language code. - * For example: Author-ger=Michael, Author-eng=Mike - * The original/default language is in the unqualified "Author" tag. - * A demuxer should set a default if it sets any translated tag. - * b) sorting -- a modified version of a tag that should be used for - * sorting will have '-sort' appended. E.g. artist="The Beatles", - * artist-sort="Beatles, The". - * - * 4. Tag names are normally exported exactly as stored in the container to - * allow lossless remuxing to the same format. For container-independent - * handling of metadata, av_metadata_conv() can convert it to ffmpeg generic - * format. Follows a list of generic tag names: - * - * album -- name of the set this work belongs to - * album_artist -- main creator of the set/album, if different from artist. - * e.g. "Various Artists" for compilation albums. - * artist -- main creator of the work - * comment -- any additional description of the file. - * composer -- who composed the work, if different from artist. - * copyright -- name of copyright holder. - * date -- date when the work was created, preferably in ISO 8601. - * disc -- number of a subset, e.g. disc in a multi-disc collection. - * encoder -- name/settings of the software/hardware that produced the file. - * encoded_by -- person/group who created the file. - * filename -- original name of the file. - * genre -- . - * language -- main language in which the work is performed, preferably - * in ISO 639-2 format. - * performer -- artist who performed the work, if different from artist. - * E.g for "Also sprach Zarathustra", artist would be "Richard - * Strauss" and performer "London Philharmonic Orchestra". - * publisher -- name of the label/publisher. - * title -- name of the work. - * track -- number of this work in the set, can be in form current/total. - */ - -#define AV_METADATA_MATCH_CASE 1 -#define AV_METADATA_IGNORE_SUFFIX 2 -#define AV_METADATA_DONT_STRDUP_KEY 4 -#define AV_METADATA_DONT_STRDUP_VAL 8 -#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags. - -typedef struct { - char *key; - char *value; -}AVMetadataTag; - -typedef struct AVMetadata AVMetadata; -typedef struct AVMetadataConv AVMetadataConv; - -/** - * Gets a metadata element with matching key. - * @param prev Set to the previous matching element to find the next. - * If set to NULL the first matching element is returned. - * @param flags Allows case as well as suffix-insensitive comparisons. - * @return Found tag or NULL, changing key or value leads to undefined behavior. - */ -AVMetadataTag * -av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags); - -#if LIBAVFORMAT_VERSION_MAJOR == 52 -/** - * Sets the given tag in m, overwriting an existing tag. - * @param key tag key to add to m (will be av_strduped) - * @param value tag value to add to m (will be av_strduped) - * @return >= 0 on success otherwise an error code <0 - * @deprecated Use av_metadata_set2() instead. - */ -attribute_deprecated int av_metadata_set(AVMetadata **pm, const char *key, const char *value); -#endif - -/** - * Sets the given tag in m, overwriting an existing tag. - * @param key tag key to add to m (will be av_strduped depending on flags) - * @param value tag value to add to m (will be av_strduped depending on flags) - * @return >= 0 on success otherwise an error code <0 - */ -int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags); - -/** - * Converts all the metadata sets from ctx according to the source and - * destination conversion tables. If one of the tables is NULL, then - * tags are converted to/from ffmpeg generic tag names. - * @param d_conv destination tags format conversion table - * @param s_conv source tags format conversion table - */ -void av_metadata_conv(struct AVFormatContext *ctx,const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv); - -/** - * Frees all the memory allocated for an AVMetadata struct. - */ -void av_metadata_free(AVMetadata **m); - - -/* packet functions */ - - -/** - * Allocates and reads the payload of a packet and initializes its - * fields with default values. - * - * @param pkt packet - * @param size desired payload size - * @return >0 (read size) if OK, AVERROR_xxx otherwise - */ -int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size); - - -/*************************************************/ -/* fractional numbers for exact pts handling */ - -/** - * The exact value of the fractional number is: 'val + num / den'. - * num is assumed to be 0 <= num < den. - */ -typedef struct AVFrac { - int64_t val, num, den; -} AVFrac; - -/*************************************************/ -/* input/output formats */ - -struct AVCodecTag; - -/** This structure contains the data a format has to probe a file. */ -typedef struct AVProbeData { - const char *filename; - unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */ - int buf_size; /**< Size of buf except extra allocated bytes */ -} AVProbeData; - -#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection -#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer - -typedef struct AVFormatParameters { - AVRational time_base; - int sample_rate; - int channels; - int width; - int height; - enum PixelFormat pix_fmt; - int channel; /**< Used to select DV channel. */ - const char *standard; /**< TV standard, NTSC, PAL, SECAM */ - unsigned int mpeg2ts_raw:1; /**< Force raw MPEG-2 transport stream output, if possible. */ - unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport - stream packet (only meaningful if - mpeg2ts_raw is TRUE). */ - unsigned int initial_pause:1; /**< Do not begin to play the stream - immediately (RTSP only). */ - unsigned int prealloced_context:1; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - enum CodecID video_codec_id; - enum CodecID audio_codec_id; -#endif -} AVFormatParameters; - -//! Demuxer will use url_fopen, no opened file should be provided by the caller. -#define AVFMT_NOFILE 0x0001 -#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ -#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ -#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for - raw picture data. */ -#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ -#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ -#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ -#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. */ -#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */ -#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */ - -typedef struct AVOutputFormat { - const char *name; - /** - * Descriptive name for the format, meant to be more human-readable - * than name. You should use the NULL_IF_CONFIG_SMALL() macro - * to define it. - */ - const char *long_name; - const char *mime_type; - const char *extensions; /**< comma-separated filename extensions */ - /** size of private data so that it can be allocated in the wrapper */ - int priv_data_size; - /* output support */ - enum CodecID audio_codec; /**< default audio codec */ - enum CodecID video_codec; /**< default video codec */ - int (*write_header)(struct AVFormatContext *); - int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); - int (*write_trailer)(struct AVFormatContext *); - /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */ - int flags; - /** Currently only used to set pixel format if not YUV420P. */ - int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *); - int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, - AVPacket *in, int flush); - - /** - * List of supported codec_id-codec_tag pairs, ordered by "better - * choice first". The arrays are all terminated by CODEC_ID_NONE. - */ - const struct AVCodecTag * const *codec_tag; - - enum CodecID subtitle_codec; /**< default subtitle codec */ - - const AVMetadataConv *metadata_conv; - - /* private fields */ - struct AVOutputFormat *next; -} AVOutputFormat; - -typedef struct AVInputFormat { - const char *name; - /** - * Descriptive name for the format, meant to be more human-readable - * than name. You should use the NULL_IF_CONFIG_SMALL() macro - * to define it. - */ - const char *long_name; - /** Size of private data so that it can be allocated in the wrapper. */ - int priv_data_size; - /** - * Tell if a given file has a chance of being parsed as this format. - * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes - * big so you do not have to check for that unless you need more. - */ - int (*read_probe)(AVProbeData *); - /** Read the format header and initialize the AVFormatContext - structure. Return 0 if OK. 'ap' if non-NULL contains - additional parameters. Only used in raw format right - now. 'av_new_stream' should be called to create new streams. */ - int (*read_header)(struct AVFormatContext *, - AVFormatParameters *ap); - /** Read one packet and put it in 'pkt'. pts and flags are also - set. 'av_new_stream' can be called only if the flag - AVFMTCTX_NOHEADER is used. - @return 0 on success, < 0 on error. - When returning an error, pkt must not have been allocated - or must be freed before returning */ - int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); - /** Close the stream. The AVFormatContext and AVStreams are not - freed by this function */ - int (*read_close)(struct AVFormatContext *); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 - /** - * Seek to a given timestamp relative to the frames in - * stream component stream_index. - * @param stream_index Must not be -1. - * @param flags Selects which direction should be preferred if no exact - * match is available. - * @return >= 0 on success (but not necessarily the new offset) - */ - int (*read_seek)(struct AVFormatContext *, - int stream_index, int64_t timestamp, int flags); -#endif - /** - * Gets the next timestamp in stream[stream_index].time_base units. - * @return the timestamp or AV_NOPTS_VALUE if an error occurred - */ - int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit); - /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */ - int flags; - /** If extensions are defined, then no probe is done. You should - usually not use extension format guessing because it is not - reliable enough */ - const char *extensions; - /** General purpose read-only value that the format can use. */ - int value; - - /** Starts/resumes playing - only meaningful if using a network-based format - (RTSP). */ - int (*read_play)(struct AVFormatContext *); - - /** Pauses playing - only meaningful if using a network-based format - (RTSP). */ - int (*read_pause)(struct AVFormatContext *); - - const struct AVCodecTag * const *codec_tag; - - /** - * Seeks to timestamp ts. - * Seeking will be done so that the point from which all active streams - * can be presented successfully will be closest to ts and within min/max_ts. - * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. - */ - int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); - - const AVMetadataConv *metadata_conv; - - /* private fields */ - struct AVInputFormat *next; -} AVInputFormat; - -enum AVStreamParseType { - AVSTREAM_PARSE_NONE, - AVSTREAM_PARSE_FULL, /**< full parsing and repack */ - AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ - AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ -}; - -typedef struct AVIndexEntry { - int64_t pos; - int64_t timestamp; -#define AVINDEX_KEYFRAME 0x0001 - int flags:2; - int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment). - int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ -} AVIndexEntry; - -#define AV_DISPOSITION_DEFAULT 0x0001 -#define AV_DISPOSITION_DUB 0x0002 -#define AV_DISPOSITION_ORIGINAL 0x0004 -#define AV_DISPOSITION_COMMENT 0x0008 -#define AV_DISPOSITION_LYRICS 0x0010 -#define AV_DISPOSITION_KARAOKE 0x0020 - -/** - * Stream structure. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVStream) must not be used outside libav*. - */ -typedef struct AVStream { - int index; /**< stream index in AVFormatContext */ - int id; /**< format-specific stream ID */ - AVCodecContext *codec; /**< codec context */ - /** - * Real base framerate of the stream. - * This is the lowest framerate with which all timestamps can be - * represented accurately (it is the least common multiple of all - * framerates in the stream). Note, this value is just a guess! - * For example, if the time base is 1/90000 and all frames have either - * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. - */ - AVRational r_frame_rate; - void *priv_data; - - /* internal data used in av_find_stream_info() */ - int64_t first_dts; - /** encoding: pts generation when outputting stream */ - struct AVFrac pts; - - /** - * This is the fundamental unit of time (in seconds) in terms - * of which frame timestamps are represented. For fixed-fps content, - * time base should be 1/framerate and timestamp increments should be 1. - */ - AVRational time_base; - int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ - /* ffmpeg.c private use */ - int stream_copy; /**< If set, just copy stream. */ - enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed. - //FIXME move stuff to a flags field? - /** Quality, as it has been removed from AVCodecContext and put in AVVideoFrame. - * MN: dunno if that is the right place for it */ - float quality; - /** - * Decoding: pts of the first frame of the stream, in stream time base. - * Only set this if you are absolutely 100% sure that the value you set - * it to really is the pts of the first frame. - * This may be undefined (AV_NOPTS_VALUE). - * @note The ASF header does NOT contain a correct start_time the ASF - * demuxer must NOT set this. - */ - int64_t start_time; - /** - * Decoding: duration of the stream, in stream time base. - * If a source file does not specify a duration, but does specify - * a bitrate, this value will be estimated from bitrate and file size. - */ - int64_t duration; - -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char language[4]; /** ISO 639-2/B 3-letter language code (empty string if undefined) */ -#endif - - /* av_read_frame() support */ - enum AVStreamParseType need_parsing; - struct AVCodecParserContext *parser; - - int64_t cur_dts; - int last_IP_duration; - int64_t last_IP_pts; - /* av_seek_frame() support */ - AVIndexEntry *index_entries; /**< Only used if the format does not - support seeking natively. */ - int nb_index_entries; - unsigned int index_entries_allocated_size; - - int64_t nb_frames; ///< number of frames in this stream if known or 0 - -#if LIBAVFORMAT_VERSION_INT < (53<<16) - int64_t unused[4+1]; - - char *filename; /**< source filename of the stream */ -#endif - - int disposition; /**< AV_DISPOSITION_* bit field */ - - AVProbeData probe_data; -#define MAX_REORDER_DELAY 16 - int64_t pts_buffer[MAX_REORDER_DELAY+1]; - - /** - * sample aspect ratio (0 if unknown) - * - encoding: Set by user. - * - decoding: Set by libavformat. - */ - AVRational sample_aspect_ratio; - - AVMetadata *metadata; - - /* av_read_frame() support */ - const uint8_t *cur_ptr; - int cur_len; - AVPacket cur_pkt; - - // Timestamp generation support: - /** - * Timestamp corresponding to the last dts sync point. - * - * Initialized when AVCodecParserContext.dts_sync_point >= 0 and - * a DTS is received from the underlying container. Otherwise set to - * AV_NOPTS_VALUE by default. - */ - int64_t reference_dts; - - /** - * Number of packets to buffer for codec probing - * NOT PART OF PUBLIC API - */ -#define MAX_PROBE_PACKETS 2500 - int probe_packets; - - /** - * last packet in packet_buffer for this stream when muxing. - * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav* - */ - struct AVPacketList *last_in_packet_buffer; - - /** - * Average framerate - */ - AVRational avg_frame_rate; - - /** - * Number of frames that have been demuxed during av_find_stream_info() - */ - int codec_info_nb_frames; -} AVStream; - -#define AV_PROGRAM_RUNNING 1 - -/** - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVProgram) must not be used outside libav*. - */ -typedef struct AVProgram { - int id; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char *provider_name; ///< network name for DVB streams - char *name; ///< service name for DVB streams -#endif - int flags; - enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller - unsigned int *stream_index; - unsigned int nb_stream_indexes; - AVMetadata *metadata; -} AVProgram; - -#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present - (streams are added dynamically) */ - -typedef struct AVChapter { - int id; ///< unique ID to identify the chapter - AVRational time_base; ///< time base in which the start/end timestamps are specified - int64_t start, end; ///< chapter start/end time in time_base units -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char *title; ///< chapter title -#endif - AVMetadata *metadata; -} AVChapter; - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -#define MAX_STREAMS 20 -#else -#define MAX_STREAMS 100 -#endif - -/** - * Format I/O context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVFormatContext) must not be used outside libav*. - */ -typedef struct AVFormatContext { - const AVClass *av_class; /**< Set by avformat_alloc_context. */ - /* Can only be iformat or oformat, not both at the same time. */ - struct AVInputFormat *iformat; - struct AVOutputFormat *oformat; - void *priv_data; - ByteIOContext *pb; - unsigned int nb_streams; - AVStream *streams[MAX_STREAMS]; - char filename[1024]; /**< input or output filename */ - /* stream info */ - int64_t timestamp; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - char title[512]; - char author[512]; - char copyright[512]; - char comment[512]; - char album[512]; - int year; /**< ID3 year, 0 if none */ - int track; /**< track number, 0 if none */ - char genre[32]; /**< ID3 genre */ -#endif - - int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ - /* private data for pts handling (do not modify directly). */ - /** This buffer is only needed when packets were already buffered but - not decoded, for example to get the codec parameters in MPEG - streams. */ - struct AVPacketList *packet_buffer; - - /** Decoding: position of the first frame of the component, in - AV_TIME_BASE fractional seconds. NEVER set this value directly: - It is deduced from the AVStream values. */ - int64_t start_time; - /** Decoding: duration of the stream, in AV_TIME_BASE fractional - seconds. Only set this value if you know none of the individual stream - durations and also dont set any of them. This is deduced from the - AVStream values if not set. */ - int64_t duration; - /** decoding: total file size, 0 if unknown */ - int64_t file_size; - /** Decoding: total stream bitrate in bit/s, 0 if not - available. Never set it directly if the file_size and the - duration are known as FFmpeg can compute it automatically. */ - int bit_rate; - - /* av_read_frame() support */ - AVStream *cur_st; -#if LIBAVFORMAT_VERSION_INT < (53<<16) - const uint8_t *cur_ptr_deprecated; - int cur_len_deprecated; - AVPacket cur_pkt_deprecated; -#endif - - /* av_seek_frame() support */ - int64_t data_offset; /** offset of the first packet */ - int index_built; - - int mux_rate; - unsigned int packet_size; - int preload; - int max_delay; - -#define AVFMT_NOOUTPUTLOOP -1 -#define AVFMT_INFINITEOUTPUTLOOP 0 - /** number of times to loop output in formats that support it */ - int loop_output; - - int flags; -#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames. -#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. -#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. -#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS -#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container -#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled -#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Add RTP hinting to the output file - - int loop_input; - /** decoding: size of data to probe; encoding: unused. */ - unsigned int probesize; - - /** - * Maximum time (in AV_TIME_BASE units) during which the input should - * be analyzed in av_find_stream_info(). - */ - int max_analyze_duration; - - const uint8_t *key; - int keylen; - - unsigned int nb_programs; - AVProgram **programs; - - /** - * Forced video codec_id. - * Demuxing: Set by user. - */ - enum CodecID video_codec_id; - /** - * Forced audio codec_id. - * Demuxing: Set by user. - */ - enum CodecID audio_codec_id; - /** - * Forced subtitle codec_id. - * Demuxing: Set by user. - */ - enum CodecID subtitle_codec_id; - - /** - * Maximum amount of memory in bytes to use for the index of each stream. - * If the index exceeds this size, entries will be discarded as - * needed to maintain a smaller size. This can lead to slower or less - * accurate seeking (depends on demuxer). - * Demuxers for which a full in-memory index is mandatory will ignore - * this. - * muxing : unused - * demuxing: set by user - */ - unsigned int max_index_size; - - /** - * Maximum amount of memory in bytes to use for buffering frames - * obtained from realtime capture devices. - */ - unsigned int max_picture_buffer; - - unsigned int nb_chapters; - AVChapter **chapters; - - /** - * Flags to enable debugging. - */ - int debug; -#define FF_FDEBUG_TS 0x0001 - - /** - * Raw packets from the demuxer, prior to parsing and decoding. - * This buffer is used for buffering packets until the codec can - * be identified, as parsing cannot be done without knowing the - * codec. - */ - struct AVPacketList *raw_packet_buffer; - struct AVPacketList *raw_packet_buffer_end; - - struct AVPacketList *packet_buffer_end; - - AVMetadata *metadata; - - /** - * Remaining size available for raw_packet_buffer, in bytes. - * NOT PART OF PUBLIC API - */ -#define RAW_PACKET_BUFFER_SIZE 2500000 - int raw_packet_buffer_remaining_size; - - /** - * Start time of the stream in real world time, in microseconds - * since the unix epoch (00:00 1st January 1970). That is, pts=0 - * in the stream was captured at this real world time. - * - encoding: Set by user. - * - decoding: Unused. - */ - int64_t start_time_realtime; -} AVFormatContext; - -typedef struct AVPacketList { - AVPacket pkt; - struct AVPacketList *next; -} AVPacketList; - -#if LIBAVFORMAT_VERSION_INT < (53<<16) -extern AVInputFormat *first_iformat; -extern AVOutputFormat *first_oformat; -#endif - -/** - * If f is NULL, returns the first registered input format, - * if f is non-NULL, returns the next registered input format after f - * or NULL if f is the last one. - */ -AVInputFormat *av_iformat_next(AVInputFormat *f); - -/** - * If f is NULL, returns the first registered output format, - * if f is non-NULL, returns the next registered output format after f - * or NULL if f is the last one. - */ -AVOutputFormat *av_oformat_next(AVOutputFormat *f); - -enum CodecID av_guess_image2_codec(const char *filename); - -/* XXX: Use automatic init with either ELF sections or C file parser */ -/* modules. */ - -/* utils.c */ -void av_register_input_format(AVInputFormat *format); -void av_register_output_format(AVOutputFormat *format); -#if LIBAVFORMAT_VERSION_MAJOR < 53 -attribute_deprecated AVOutputFormat *guess_stream_format(const char *short_name, - const char *filename, - const char *mime_type); - -/** - * @deprecated Use av_guess_format() instead. - */ -attribute_deprecated AVOutputFormat *guess_format(const char *short_name, - const char *filename, - const char *mime_type); -#endif - -/** - * Returns the output format in the list of registered output formats - * which best matches the provided parameters, or returns NULL if - * there is no match. - * - * @param short_name if non-NULL checks if short_name matches with the - * names of the registered formats - * @param filename if non-NULL checks if filename terminates with the - * extensions of the registered formats - * @param mime_type if non-NULL checks if mime_type matches with the - * MIME type of the registered formats - */ -AVOutputFormat *av_guess_format(const char *short_name, - const char *filename, - const char *mime_type); - -/** - * Guesses the codec ID based upon muxer and filename. - */ -enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, - const char *filename, const char *mime_type, - enum AVMediaType type); - -/** - * Sends a nice hexadecimal dump of a buffer to the specified file stream. - * - * @param f The file stream pointer where the dump should be sent to. - * @param buf buffer - * @param size buffer size - * - * @see av_hex_dump_log, av_pkt_dump, av_pkt_dump_log - */ -void av_hex_dump(FILE *f, uint8_t *buf, int size); - -/** - * Sends a nice hexadecimal dump of a buffer to the log. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param buf buffer - * @param size buffer size - * - * @see av_hex_dump, av_pkt_dump, av_pkt_dump_log - */ -void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size); - -/** - * Sends a nice dump of a packet to the specified file stream. - * - * @param f The file stream pointer where the dump should be sent to. - * @param pkt packet to dump - * @param dump_payload True if the payload must be displayed, too. - */ -void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); - -/** - * Sends a nice dump of a packet to the log. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param pkt packet to dump - * @param dump_payload True if the payload must be displayed, too. - */ -void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload); - -/** - * Initializes libavformat and registers all the muxers, demuxers and - * protocols. If you do not call this function, then you can select - * exactly which formats you want to support. - * - * @see av_register_input_format() - * @see av_register_output_format() - * @see av_register_protocol() - */ -void av_register_all(void); - -/** codec tag <-> codec id */ -enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); -unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id); - -/* media file input */ - -/** - * Finds AVInputFormat based on the short name of the input format. - */ -AVInputFormat *av_find_input_format(const char *short_name); - -/** - * Guesses the file format. - * - * @param is_opened Whether the file is already opened; determines whether - * demuxers with or without AVFMT_NOFILE are probed. - */ -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); - -/** - * Guesses the file format. - * - * @param is_opened Whether the file is already opened; determines whether - * demuxers with or without AVFMT_NOFILE are probed. - * @param score_max A probe score larger that this is required to accept a - * detection, the variable is set to the actual detection - * score afterwards. - * If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended - * to retry with a larger probe buffer. - */ -AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max); - -/** - * Allocates all the structures needed to read an input stream. - * This does not open the needed codecs for decoding the stream[s]. - */ -int av_open_input_stream(AVFormatContext **ic_ptr, - ByteIOContext *pb, const char *filename, - AVInputFormat *fmt, AVFormatParameters *ap); - -/** - * Opens a media file as input. The codecs are not opened. Only the file - * header (if present) is read. - * - * @param ic_ptr The opened media file handle is put here. - * @param filename filename to open - * @param fmt If non-NULL, force the file format to use. - * @param buf_size optional buffer size (zero if default is OK) - * @param ap Additional parameters needed when opening the file - * (NULL if default). - * @return 0 if OK, AVERROR_xxx otherwise - */ -int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, - AVInputFormat *fmt, - int buf_size, - AVFormatParameters *ap); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** - * @deprecated Use avformat_alloc_context() instead. - */ -attribute_deprecated AVFormatContext *av_alloc_format_context(void); -#endif - -/** - * Allocates an AVFormatContext. - * Can be freed with av_free() but do not forget to free everything you - * explicitly allocated as well! - */ -AVFormatContext *avformat_alloc_context(void); - -/** - * Reads packets of a media file to get stream information. This - * is useful for file formats with no headers such as MPEG. This - * function also computes the real framerate in case of MPEG-2 repeat - * frame mode. - * The logical file position is not changed by this function; - * examined packets may be buffered for later processing. - * - * @param ic media file handle - * @return >=0 if OK, AVERROR_xxx on error - * @todo Let the user decide somehow what information is needed so that - * we do not waste time getting stuff the user does not need. - */ -int av_find_stream_info(AVFormatContext *ic); - -/** - * Reads a transport packet from a media file. - * - * This function is obsolete and should never be used. - * Use av_read_frame() instead. - * - * @param s media file handle - * @param pkt is filled - * @return 0 if OK, AVERROR_xxx on error - */ -int av_read_packet(AVFormatContext *s, AVPacket *pkt); - -/** - * Returns the next frame of a stream. - * - * The returned packet is valid - * until the next av_read_frame() or until av_close_input_file() and - * must be freed with av_free_packet. For video, the packet contains - * exactly one frame. For audio, it contains an integer number of - * frames if each frame has a known fixed size (e.g. PCM or ADPCM - * data). If the audio frames have a variable size (e.g. MPEG audio), - * then it contains one frame. - * - * pkt->pts, pkt->dts and pkt->duration are always set to correct - * values in AVStream.time_base units (and guessed if the format cannot - * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format - * has B-frames, so it is better to rely on pkt->dts if you do not - * decompress the payload. - * - * @return 0 if OK, < 0 on error or end of file - */ -int av_read_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Seeks to the keyframe at timestamp. - * 'timestamp' in 'stream_index'. - * @param stream_index If stream_index is (-1), a default - * stream is selected, and timestamp is automatically converted - * from AV_TIME_BASE units to the stream specific time_base. - * @param timestamp Timestamp in AVStream.time_base units - * or, if no stream is specified, in AV_TIME_BASE units. - * @param flags flags which select direction and seeking mode - * @return >= 0 on success - */ -int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, - int flags); - -/** - * Seeks to timestamp ts. - * Seeking will be done so that the point from which all active streams - * can be presented successfully will be closest to ts and within min/max_ts. - * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. - * - * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and - * are the file position (this may not be supported by all demuxers). - * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames - * in the stream with stream_index (this may not be supported by all demuxers). - * Otherwise all timestamps are in units of the stream selected by stream_index - * or if stream_index is -1, in AV_TIME_BASE units. - * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as - * keyframes (this may not be supported by all demuxers). - * - * @param stream_index index of the stream which is used as time base reference - * @param min_ts smallest acceptable timestamp - * @param ts target timestamp - * @param max_ts largest acceptable timestamp - * @param flags flags - * @return >=0 on success, error code otherwise - * - * @NOTE This is part of the new seek API which is still under construction. - * Thus do not use this yet. It may change at any time, do not expect - * ABI compatibility yet! - */ -int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); - -/** - * Starts playing a network-based stream (e.g. RTSP stream) at the - * current position. - */ -int av_read_play(AVFormatContext *s); - -/** - * Pauses a network-based stream (e.g. RTSP stream). - * - * Use av_read_play() to resume it. - */ -int av_read_pause(AVFormatContext *s); - -/** - * Frees a AVFormatContext allocated by av_open_input_stream. - * @param s context to free - */ -void av_close_input_stream(AVFormatContext *s); - -/** - * Closes a media file (but not its codecs). - * - * @param s media file handle - */ -void av_close_input_file(AVFormatContext *s); - -/** - * Adds a new stream to a media file. - * - * Can only be called in the read_header() function. If the flag - * AVFMTCTX_NOHEADER is in the format context, then new streams - * can be added in read_packet too. - * - * @param s media file handle - * @param id file-format-dependent stream ID - */ -AVStream *av_new_stream(AVFormatContext *s, int id); -AVProgram *av_new_program(AVFormatContext *s, int id); - -/** - * Adds a new chapter. - * This function is NOT part of the public API - * and should ONLY be used by demuxers. - * - * @param s media file handle - * @param id unique ID for this chapter - * @param start chapter start time in time_base units - * @param end chapter end time in time_base units - * @param title chapter title - * - * @return AVChapter or NULL on error - */ -AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, - int64_t start, int64_t end, const char *title); - -/** - * Sets the pts for a given stream. - * - * @param s stream - * @param pts_wrap_bits number of bits effectively used by the pts - * (used for wrap control, 33 is the value for MPEG) - * @param pts_num numerator to convert to seconds (MPEG: 1) - * @param pts_den denominator to convert to seconds (MPEG: 90000) - */ -void av_set_pts_info(AVStream *s, int pts_wrap_bits, - unsigned int pts_num, unsigned int pts_den); - -#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward -#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes -#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes -#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number - -int av_find_default_stream_index(AVFormatContext *s); - -/** - * Gets the index for a specific timestamp. - * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond - * to the timestamp which is <= the requested one, if backward - * is 0, then it will be >= - * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise - * @return < 0 if no such timestamp could be found - */ -int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); - -/** - * Ensures the index uses less memory than the maximum specified in - * AVFormatContext.max_index_size by discarding entries if it grows - * too large. - * This function is not part of the public API and should only be called - * by demuxers. - */ -void ff_reduce_index(AVFormatContext *s, int stream_index); - -/** - * Adds an index entry into a sorted list. Updates the entry if the list - * already contains it. - * - * @param timestamp timestamp in the time base of the given stream - */ -int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, - int size, int distance, int flags); - -/** - * Does a binary search using av_index_search_timestamp() and - * AVCodec.read_timestamp(). - * This is not supposed to be called directly by a user application, - * but by demuxers. - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ -int av_seek_frame_binary(AVFormatContext *s, int stream_index, - int64_t target_ts, int flags); - -/** - * Updates cur_dts of all streams based on the given timestamp and AVStream. - * - * Stream ref_st unchanged, others set cur_dts in their native time base. - * Only needed for timestamp wrapping or if (dts not set and pts!=dts). - * @param timestamp new dts expressed in time_base of param ref_st - * @param ref_st reference stream giving time_base of param timestamp - */ -void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); - -/** - * Does a binary search using read_timestamp(). - * This is not supposed to be called directly by a user application, - * but by demuxers. - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ -int64_t av_gen_search(AVFormatContext *s, int stream_index, - int64_t target_ts, int64_t pos_min, - int64_t pos_max, int64_t pos_limit, - int64_t ts_min, int64_t ts_max, - int flags, int64_t *ts_ret, - int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); - -/** media file output */ -int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); - -/** - * Allocates the stream private data and writes the stream header to an - * output media file. - * - * @param s media file handle - * @return 0 if OK, AVERROR_xxx on error - */ -int av_write_header(AVFormatContext *s); - -/** - * Writes a packet to an output media file. - * - * The packet shall contain one audio or video frame. - * The packet must be correctly interleaved according to the container - * specification, if not then av_interleaved_write_frame must be used. - * - * @param s media file handle - * @param pkt The packet, which contains the stream_index, buf/buf_size, - dts/pts, ... - * @return < 0 on error, = 0 if OK, 1 if end of stream wanted - */ -int av_write_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Writes a packet to an output media file ensuring correct interleaving. - * - * The packet must contain one audio or video frame. - * If the packets are already correctly interleaved, the application should - * call av_write_frame() instead as it is slightly faster. It is also important - * to keep in mind that completely non-interleaved input will need huge amounts - * of memory to interleave with this, so it is preferable to interleave at the - * demuxer level. - * - * @param s media file handle - * @param pkt The packet, which contains the stream_index, buf/buf_size, - dts/pts, ... - * @return < 0 on error, = 0 if OK, 1 if end of stream wanted - */ -int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Interleaves a packet per dts in an output media file. - * - * Packets with pkt->destruct == av_destruct_packet will be freed inside this - * function, so they cannot be used after it. Note that calling av_free_packet() - * on them is still safe. - * - * @param s media file handle - * @param out the interleaved packet will be output here - * @param in the input packet - * @param flush 1 if no further packets are available as input and all - * remaining packets should be output - * @return 1 if a packet was output, 0 if no packet could be output, - * < 0 if an error occurred - */ -int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, - AVPacket *pkt, int flush); - -/** - * Writes the stream trailer to an output media file and frees the - * file private data. - * - * May only be called after a successful call to av_write_header. - * - * @param s media file handle - * @return 0 if OK, AVERROR_xxx on error - */ -int av_write_trailer(AVFormatContext *s); - -void dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** - * Parses width and height out of string str. - * @deprecated Use av_parse_video_frame_size instead. - */ -attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr, - const char *str); - -/** - * Converts framerate from a string to a fraction. - * @deprecated Use av_parse_video_frame_rate instead. - */ -attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base, - const char *arg); -#endif - -/** - * Parses datestr and returns a corresponding number of microseconds. - * @param datestr String representing a date or a duration. - * - If a date the syntax is: - * @code - * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} - * @endcode - * Time is local time unless Z is appended, in which case it is - * interpreted as UTC. - * If the year-month-day part is not specified it takes the current - * year-month-day. - * Returns the number of microseconds since 1st of January, 1970 up to - * the time of the parsed date or INT64_MIN if datestr cannot be - * successfully parsed. - * - If a duration the syntax is: - * @code - * [-]HH[:MM[:SS[.m...]]] - * [-]S+[.m...] - * @endcode - * Returns the number of microseconds contained in a time interval - * with the specified duration or INT64_MIN if datestr cannot be - * successfully parsed. - * @param duration Flag which tells how to interpret datestr, if - * not zero datestr is interpreted as a duration, otherwise as a - * date. - */ -int64_t parse_date(const char *datestr, int duration); - -/** Gets the current time in microseconds. */ -int64_t av_gettime(void); - -/* ffm-specific for ffserver */ -#define FFM_PACKET_SIZE 4096 -int64_t ffm_read_write_index(int fd); -int ffm_write_write_index(int fd, int64_t pos); -void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size); - -/** - * Attempts to find a specific tag in a URL. - * - * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. - * Return 1 if found. - */ -int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); - -/** - * Returns in 'buf' the path with '%d' replaced by a number. - * - * Also handles the '%0nd' format where 'n' is the total number - * of digits and '%%'. - * - * @param buf destination buffer - * @param buf_size destination buffer size - * @param path numbered sequence string - * @param number frame number - * @return 0 if OK, -1 on format error - */ -int av_get_frame_filename(char *buf, int buf_size, - const char *path, int number); - -/** - * Checks whether filename actually is a numbered sequence generator. - * - * @param filename possible numbered sequence string - * @return 1 if a valid numbered sequence string, 0 otherwise - */ -int av_filename_number_test(const char *filename); - -/** - * Generates an SDP for an RTP session. - * - * @param ac array of AVFormatContexts describing the RTP streams. If the - * array is composed by only one context, such context can contain - * multiple AVStreams (one AVStream per RTP stream). Otherwise, - * all the contexts in the array (an AVCodecContext per RTP stream) - * must contain only one AVStream. - * @param n_files number of AVCodecContexts contained in ac - * @param buff buffer where the SDP will be stored (must be allocated by - * the caller) - * @param size the size of the buffer - * @return 0 if OK, AVERROR_xxx on error - */ -int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size); - -/** - * Returns a positive value if the given filename has one of the given - * extensions, 0 otherwise. - * - * @param extensions a comma-separated list of filename extensions - */ -int av_match_ext(const char *filename, const char *extensions); - -#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/avi.c b/tizen/distrib/ffmpeg/libavformat/avi.c deleted file mode 100644 index 705ad03..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avi.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * AVI common data - * Copyright (c) 2010 Anton Khirnov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avi.h" - -const AVMetadataConv ff_avi_metadata_conv[] = { - { "IART", "artist" }, - { "ICMT", "comment" }, - { "ICOP", "copyright" }, - { "ICRD", "date" }, - { "IGNR", "genre" }, - { "ILNG", "language" }, - { "INAM", "title" }, - { "IPRD", "album" }, - { "IPRT", "track" }, - { "ISFT", "encoder" }, - { "ITCH", "encoded_by"}, - { "strn", "title" }, - { 0 }, -}; - -const char ff_avi_tags[][5] = { - "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI", - "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD", - "IPRT", "ISBJ", "ISFT", "ISHP", "ISRC", "ISRF", "ITCH", - {0} -}; diff --git a/tizen/distrib/ffmpeg/libavformat/avi.h b/tizen/distrib/ffmpeg/libavformat/avi.h deleted file mode 100644 index f345c14..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avi.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_AVI_H -#define AVFORMAT_AVI_H - -#include "metadata.h" - -#define AVIF_HASINDEX 0x00000010 // Index at end of file? -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 - -#define AVI_MAX_RIFF_SIZE 0x40000000LL -#define AVI_MASTER_INDEX_SIZE 256 - -/* index flags */ -#define AVIIF_INDEX 0x10 - -extern const AVMetadataConv ff_avi_metadata_conv[]; - -/** - * A list of AVI info tags. - */ -extern const char ff_avi_tags[][5]; - -#endif /* AVFORMAT_AVI_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/avidec.c b/tizen/distrib/ffmpeg/libavformat/avidec.c deleted file mode 100644 index 485c4eb..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avidec.c +++ /dev/null @@ -1,1198 +0,0 @@ -/* - * AVI demuxer - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//#define DEBUG -//#define DEBUG_SEEK - -#include "libavutil/intreadwrite.h" -#include "libavutil/bswap.h" -#include "avformat.h" -#include "avi.h" -#include "dv.h" -#include "riff.h" - -#undef NDEBUG -#include - -typedef struct AVIStream { - int64_t frame_offset; /* current frame (video) or byte (audio) counter - (used to compute the pts) */ - int remaining; - int packet_size; - - int scale; - int rate; - int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */ - - int64_t cum_len; /* temporary storage (used during seek) */ - - int prefix; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b' - int prefix_count; - uint32_t pal[256]; - int has_pal; -} AVIStream; - -typedef struct { - int64_t riff_end; - int64_t movi_end; - int64_t fsize; - int64_t movi_list; - int64_t last_pkt_pos; - int index_loaded; - int is_odml; - int non_interleaved; - int stream_index; - DVDemuxContext* dv_demux; -} AVIContext; - -static const char avi_headers[][8] = { - { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' }, - { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' }, - { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19}, - { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' }, - { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' }, - { 0 } -}; - -static int avi_load_index(AVFormatContext *s); -static int guess_ni_flag(AVFormatContext *s); - -#ifdef DEBUG -static void print_tag(const char *str, unsigned int tag, int size) -{ - dprintf(NULL, "%s: tag=%c%c%c%c size=0x%x\n", - str, tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - size); -} -#endif - -static int get_riff(AVFormatContext *s, ByteIOContext *pb) -{ - AVIContext *avi = s->priv_data; - char header[8]; - int i; - - /* check RIFF header */ - get_buffer(pb, header, 4); - avi->riff_end = get_le32(pb); /* RIFF chunk size */ - avi->riff_end += url_ftell(pb); /* RIFF chunk end */ - get_buffer(pb, header+4, 4); - - for(i=0; avi_headers[i][0]; i++) - if(!memcmp(header, avi_headers[i], 8)) - break; - if(!avi_headers[i][0]) - return -1; - - if(header[7] == 0x19) - av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n"); - - return 0; -} - -static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - int longs_pre_entry= get_le16(pb); - int index_sub_type = get_byte(pb); - int index_type = get_byte(pb); - int entries_in_use = get_le32(pb); - int chunk_id = get_le32(pb); - int64_t base = get_le64(pb); - int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0'); - AVStream *st; - AVIStream *ast; - int i; - int64_t last_pos= -1; - int64_t filesize= url_fsize(s->pb); - -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n", - longs_pre_entry,index_type, entries_in_use, chunk_id, base); -#endif - - if(stream_id >= s->nb_streams || stream_id < 0) - return -1; - st= s->streams[stream_id]; - ast = st->priv_data; - - if(index_sub_type) - return -1; - - get_le32(pb); - - if(index_type && longs_pre_entry != 2) - return -1; - if(index_type>1) - return -1; - - if(filesize > 0 && base >= filesize){ - av_log(s, AV_LOG_ERROR, "ODML index invalid\n"); - if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF) - base &= 0xFFFFFFFF; - else - return -1; - } - - for(i=0; i= 0; - len &= 0x7FFFFFFF; - -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len); -#endif - if(url_feof(pb)) - return -1; - - if(last_pos == pos || pos == base - 8) - avi->non_interleaved= 1; - if(last_pos != pos && (len || !ast->sample_size)) - av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0); - - if(ast->sample_size) - ast->cum_len += len; - else - ast->cum_len ++; - last_pos= pos; - }else{ - int64_t offset, pos; - int duration; - offset = get_le64(pb); - get_le32(pb); /* size */ - duration = get_le32(pb); - - if(url_feof(pb)) - return -1; - - pos = url_ftell(pb); - - url_fseek(pb, offset+8, SEEK_SET); - read_braindead_odml_indx(s, frame_num); - frame_num += duration; - - url_fseek(pb, pos, SEEK_SET); - } - } - avi->index_loaded=1; - return 0; -} - -static void clean_index(AVFormatContext *s){ - int i; - int64_t j; - - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - AVIStream *ast = st->priv_data; - int n= st->nb_index_entries; - int max= ast->sample_size; - int64_t pos, size, ts; - - if(n != 1 || ast->sample_size==0) - continue; - - while(max < 1024) max+=max; - - pos= st->index_entries[0].pos; - size= st->index_entries[0].size; - ts= st->index_entries[0].timestamp; - - for(j=0; jpb; - char key[5] = {0}, *value; - - size += (size & 1); - - if (size == UINT_MAX) - return -1; - value = av_malloc(size+1); - if (!value) - return -1; - get_buffer(pb, value, size); - value[size]=0; - - AV_WL32(key, tag); - - if(st) - return av_metadata_set2(&st->metadata, key, value, - AV_METADATA_DONT_STRDUP_VAL); - else - return av_metadata_set2(&s->metadata, key, value, - AV_METADATA_DONT_STRDUP_VAL); -} - -static void avi_read_info(AVFormatContext *s, uint64_t end) -{ - while (url_ftell(s->pb) < end) { - uint32_t tag = get_le32(s->pb); - uint32_t size = get_le32(s->pb); - avi_read_tag(s, NULL, tag, size); - } -} - -static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned int tag, tag1, handler; - int codec_type, stream_index, frame_period, bit_rate; - unsigned int size; - int i; - AVStream *st; - AVIStream *ast = NULL; - int avih_width=0, avih_height=0; - int amv_file_format=0; - uint64_t list_end = 0; - - avi->stream_index= -1; - - if (get_riff(s, pb) < 0) - return -1; - - avi->fsize = url_fsize(pb); - if(avi->fsize<=0) - avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end; - - /* first list tag */ - stream_index = -1; - codec_type = -1; - frame_period = 0; - for(;;) { - if (url_feof(pb)) - goto fail; - tag = get_le32(pb); - size = get_le32(pb); -#ifdef DEBUG - print_tag("tag", tag, size); -#endif - - switch(tag) { - case MKTAG('L', 'I', 'S', 'T'): - list_end = url_ftell(pb) + size; - /* Ignored, except at start of video packets. */ - tag1 = get_le32(pb); -#ifdef DEBUG - print_tag("list", tag1, 0); -#endif - if (tag1 == MKTAG('m', 'o', 'v', 'i')) { - avi->movi_list = url_ftell(pb) - 4; - if(size) avi->movi_end = avi->movi_list + size + (size & 1); - else avi->movi_end = url_fsize(pb); - dprintf(NULL, "movi end=%"PRIx64"\n", avi->movi_end); - goto end_of_header; - } - else if (tag1 == MKTAG('I', 'N', 'F', 'O')) - avi_read_info(s, list_end); - - break; - case MKTAG('d', 'm', 'l', 'h'): - avi->is_odml = 1; - url_fskip(pb, size + (size & 1)); - break; - case MKTAG('a', 'm', 'v', 'h'): - amv_file_format=1; - case MKTAG('a', 'v', 'i', 'h'): - /* AVI header */ - /* using frame_period is bad idea */ - frame_period = get_le32(pb); - bit_rate = get_le32(pb) * 8; - get_le32(pb); - avi->non_interleaved |= get_le32(pb) & AVIF_MUSTUSEINDEX; - - url_fskip(pb, 2 * 4); - get_le32(pb); - get_le32(pb); - avih_width=get_le32(pb); - avih_height=get_le32(pb); - - url_fskip(pb, size - 10 * 4); - break; - case MKTAG('s', 't', 'r', 'h'): - /* stream header */ - - tag1 = get_le32(pb); - handler = get_le32(pb); /* codec tag */ - - if(tag1 == MKTAG('p', 'a', 'd', 's')){ - url_fskip(pb, size - 8); - break; - }else{ - stream_index++; - st = av_new_stream(s, stream_index); - if (!st) - goto fail; - - ast = av_mallocz(sizeof(AVIStream)); - if (!ast) - goto fail; - st->priv_data = ast; - } - if(amv_file_format) - tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s'); - -#ifdef DEBUG - print_tag("strh", tag1, -1); -#endif - if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){ - int64_t dv_dur; - - /* - * After some consideration -- I don't think we - * have to support anything but DV in type1 AVIs. - */ - if (s->nb_streams != 1) - goto fail; - - if (handler != MKTAG('d', 'v', 's', 'd') && - handler != MKTAG('d', 'v', 'h', 'd') && - handler != MKTAG('d', 'v', 's', 'l')) - goto fail; - - ast = s->streams[0]->priv_data; - av_freep(&s->streams[0]->codec->extradata); - av_freep(&s->streams[0]); - s->nb_streams = 0; - if (CONFIG_DV_DEMUXER) { - avi->dv_demux = dv_init_demux(s); - if (!avi->dv_demux) - goto fail; - } - s->streams[0]->priv_data = ast; - url_fskip(pb, 3 * 4); - ast->scale = get_le32(pb); - ast->rate = get_le32(pb); - url_fskip(pb, 4); /* start time */ - - dv_dur = get_le32(pb); - if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) { - dv_dur *= AV_TIME_BASE; - s->duration = av_rescale(dv_dur, ast->scale, ast->rate); - } - /* - * else, leave duration alone; timing estimation in utils.c - * will make a guess based on bitrate. - */ - - stream_index = s->nb_streams - 1; - url_fskip(pb, size - 9*4); - break; - } - - assert(stream_index < s->nb_streams); - st->codec->stream_codec_tag= handler; - - get_le32(pb); /* flags */ - get_le16(pb); /* priority */ - get_le16(pb); /* language */ - get_le32(pb); /* initial frame */ - ast->scale = get_le32(pb); - ast->rate = get_le32(pb); - if(!(ast->scale && ast->rate)){ - av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate); - if(frame_period){ - ast->rate = 1000000; - ast->scale = frame_period; - }else{ - ast->rate = 25; - ast->scale = 1; - } - } - av_set_pts_info(st, 64, ast->scale, ast->rate); - - ast->cum_len=get_le32(pb); /* start */ - st->nb_frames = get_le32(pb); - - st->start_time = 0; - get_le32(pb); /* buffer size */ - get_le32(pb); /* quality */ - ast->sample_size = get_le32(pb); /* sample ssize */ - ast->cum_len *= FFMAX(1, ast->sample_size); -// av_log(s, AV_LOG_DEBUG, "%d %d %d %d\n", ast->rate, ast->scale, ast->start, ast->sample_size); - - switch(tag1) { - case MKTAG('v', 'i', 'd', 's'): - codec_type = AVMEDIA_TYPE_VIDEO; - - ast->sample_size = 0; - break; - case MKTAG('a', 'u', 'd', 's'): - codec_type = AVMEDIA_TYPE_AUDIO; - break; - case MKTAG('t', 'x', 't', 's'): - //FIXME - codec_type = AVMEDIA_TYPE_DATA; //AVMEDIA_TYPE_SUB ? FIXME - break; - case MKTAG('d', 'a', 't', 's'): - codec_type = AVMEDIA_TYPE_DATA; - break; - default: - av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1); - goto fail; - } - if(ast->sample_size == 0) - st->duration = st->nb_frames; - ast->frame_offset= ast->cum_len; - url_fskip(pb, size - 12 * 4); - break; - case MKTAG('s', 't', 'r', 'f'): - /* stream header */ - if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) { - url_fskip(pb, size); - } else { - uint64_t cur_pos = url_ftell(pb); - if (cur_pos < list_end) - size = FFMIN(size, list_end - cur_pos); - st = s->streams[stream_index]; - switch(codec_type) { - case AVMEDIA_TYPE_VIDEO: - if(amv_file_format){ - st->codec->width=avih_width; - st->codec->height=avih_height; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_AMV; - url_fskip(pb, size); - break; - } - get_le32(pb); /* size */ - st->codec->width = get_le32(pb); - st->codec->height = (int32_t)get_le32(pb); - get_le16(pb); /* panes */ - st->codec->bits_per_coded_sample= get_le16(pb); /* depth */ - tag1 = get_le32(pb); - get_le32(pb); /* ImageSize */ - get_le32(pb); /* XPelsPerMeter */ - get_le32(pb); /* YPelsPerMeter */ - get_le32(pb); /* ClrUsed */ - get_le32(pb); /* ClrImportant */ - - if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) { - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_tag = tag1; - st->codec->codec_id = CODEC_ID_XSUB; - break; - } - - if(size > 10*4 && size<(1<<30)){ - st->codec->extradata_size= size - 10*4; - st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - st->codec->extradata_size= 0; - return AVERROR(ENOMEM); - } - get_buffer(pb, st->codec->extradata, st->codec->extradata_size); - } - - if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly - get_byte(pb); - - /* Extract palette from extradata if bpp <= 8. */ - /* This code assumes that extradata contains only palette. */ - /* This is true for all paletted codecs implemented in FFmpeg. */ - if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { - st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl)); -#if HAVE_BIGENDIAN - for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++) - st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]); -#else - memcpy(st->codec->palctrl->palette, st->codec->extradata, - FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); -#endif - st->codec->palctrl->palette_changed = 1; - } - -#ifdef DEBUG - print_tag("video", tag1, 0); -#endif - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = tag1; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); - st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts. - // Support "Resolution 1:1" for Avid AVI Codec - if(tag1 == MKTAG('A', 'V', 'R', 'n') && - st->codec->extradata_size >= 31 && - !memcmp(&st->codec->extradata[28], "1:1", 3)) - st->codec->codec_id = CODEC_ID_RAWVIDEO; - - if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){ - st->codec->extradata_size+= 9; - st->codec->extradata= av_realloc(st->codec->extradata, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if(st->codec->extradata) - memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9); - } - st->codec->height= FFABS(st->codec->height); - -// url_fskip(pb, size - 5 * 4); - break; - case AVMEDIA_TYPE_AUDIO: - ff_get_wav_header(pb, st->codec, size); - if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){ - av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align); - ast->sample_size= st->codec->block_align; - } - if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ - url_fskip(pb, 1); - /* Force parsing as several audio frames can be in - * one packet and timestamps refer to packet start. */ - st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; - /* ADTS header is in extradata, AAC without header must be - * stored as exact frames. Parser not needed and it will - * fail. */ - if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size) - st->need_parsing = AVSTREAM_PARSE_NONE; - /* AVI files with Xan DPCM audio (wrongly) declare PCM - * audio in the header but have Axan as stream_code_tag. */ - if (st->codec->stream_codec_tag == AV_RL32("Axan")){ - st->codec->codec_id = CODEC_ID_XAN_DPCM; - st->codec->codec_tag = 0; - } - if (amv_file_format) - st->codec->codec_id = CODEC_ID_ADPCM_IMA_AMV; - break; - default: - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id= CODEC_ID_NONE; - st->codec->codec_tag= 0; - url_fskip(pb, size); - break; - } - } - break; - case MKTAG('i', 'n', 'd', 'x'): - i= url_ftell(pb); - if(!url_is_streamed(pb) && !(s->flags & AVFMT_FLAG_IGNIDX)){ - read_braindead_odml_indx(s, 0); - } - url_fseek(pb, i+size, SEEK_SET); - break; - case MKTAG('v', 'p', 'r', 'p'): - if(stream_index < (unsigned)s->nb_streams && size > 9*4){ - AVRational active, active_aspect; - - st = s->streams[stream_index]; - get_le32(pb); - get_le32(pb); - get_le32(pb); - get_le32(pb); - get_le32(pb); - - active_aspect.den= get_le16(pb); - active_aspect.num= get_le16(pb); - active.num = get_le32(pb); - active.den = get_le32(pb); - get_le32(pb); //nbFieldsPerFrame - - if(active_aspect.num && active_aspect.den && active.num && active.den){ - st->sample_aspect_ratio= av_div_q(active_aspect, active); -//av_log(s, AV_LOG_ERROR, "vprp %d/%d %d/%d\n", active_aspect.num, active_aspect.den, active.num, active.den); - } - size -= 9*4; - } - url_fseek(pb, size, SEEK_CUR); - break; - case MKTAG('s', 't', 'r', 'n'): - if(s->nb_streams){ - avi_read_tag(s, s->streams[s->nb_streams-1], tag, size); - break; - } - default: - if(size > 1000000){ - av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, " - "I will ignore it and try to continue anyway.\n"); - avi->movi_list = url_ftell(pb) - 4; - avi->movi_end = url_fsize(pb); - goto end_of_header; - } - /* skip tag */ - size += (size & 1); - url_fskip(pb, size); - break; - } - } - end_of_header: - /* check stream number */ - if (stream_index != s->nb_streams - 1) { - fail: - return -1; - } - - if(!avi->index_loaded && !url_is_streamed(pb)) - avi_load_index(s); - avi->index_loaded = 1; - avi->non_interleaved |= guess_ni_flag(s); - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - if(st->nb_index_entries) - break; - } - if(i==s->nb_streams && avi->non_interleaved) { - av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n"); - avi->non_interleaved=0; - } - - if(avi->non_interleaved) { - av_log(s, AV_LOG_INFO, "non-interleaved AVI\n"); - clean_index(s); - } - - return 0; -} - -static int get_stream_idx(int *d){ - if( d[0] >= '0' && d[0] <= '9' - && d[1] >= '0' && d[1] <= '9'){ - return (d[0] - '0') * 10 + (d[1] - '0'); - }else{ - return 100; //invalid stream ID - } -} - -static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - int n, d[8]; - unsigned int size; - int64_t i, sync; - void* dstr; - - if (CONFIG_DV_DEMUXER && avi->dv_demux) { - int size = dv_get_packet(avi->dv_demux, pkt); - if (size >= 0) - return size; - } - - if(avi->non_interleaved){ - int best_stream_index = 0; - AVStream *best_st= NULL; - AVIStream *best_ast; - int64_t best_ts= INT64_MAX; - int i; - - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - AVIStream *ast = st->priv_data; - int64_t ts= ast->frame_offset; - int64_t last_ts; - - if(!st->nb_index_entries) - continue; - - last_ts = st->index_entries[st->nb_index_entries - 1].timestamp; - if(!ast->remaining && ts > last_ts) - continue; - - ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE}); - -// av_log(s, AV_LOG_DEBUG, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset); - if(ts < best_ts){ - best_ts= ts; - best_st= st; - best_stream_index= i; - } - } - if(!best_st) - return -1; - - best_ast = best_st->priv_data; - best_ts = av_rescale_q(best_ts, (AVRational){FFMAX(1, best_ast->sample_size), AV_TIME_BASE}, best_st->time_base); - if(best_ast->remaining) - i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); - else{ - i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY); - if(i>=0) - best_ast->frame_offset= best_st->index_entries[i].timestamp; - } - -// av_log(s, AV_LOG_DEBUG, "%d\n", i); - if(i>=0){ - int64_t pos= best_st->index_entries[i].pos; - pos += best_ast->packet_size - best_ast->remaining; - url_fseek(s->pb, pos + 8, SEEK_SET); -// av_log(s, AV_LOG_DEBUG, "pos=%"PRId64"\n", pos); - - assert(best_ast->remaining <= best_ast->packet_size); - - avi->stream_index= best_stream_index; - if(!best_ast->remaining) - best_ast->packet_size= - best_ast->remaining= best_st->index_entries[i].size; - } - } - -resync: - if(avi->stream_index >= 0){ - AVStream *st= s->streams[ avi->stream_index ]; - AVIStream *ast= st->priv_data; - int size, err; - - if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM - size= INT_MAX; - else if(ast->sample_size < 32) - // arbitrary multiplier to avoid tiny packets for raw PCM data - size= 1024*ast->sample_size; - else - size= ast->sample_size; - - if(size > ast->remaining) - size= ast->remaining; - avi->last_pkt_pos= url_ftell(pb); - err= av_get_packet(pb, pkt, size); - if(err<0) - return err; - - if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){ - void *ptr= av_realloc(pkt->data, pkt->size + 4*256 + FF_INPUT_BUFFER_PADDING_SIZE); - if(ptr){ - ast->has_pal=0; - pkt->size += 4*256; - pkt->data= ptr; - memcpy(pkt->data + pkt->size - 4*256, ast->pal, 4*256); - }else - av_log(s, AV_LOG_ERROR, "Failed to append palette\n"); - } - - if (CONFIG_DV_DEMUXER && avi->dv_demux) { - dstr = pkt->destruct; - size = dv_produce_packet(avi->dv_demux, pkt, - pkt->data, pkt->size); - pkt->destruct = dstr; - pkt->flags |= AV_PKT_FLAG_KEY; - } else { - /* XXX: How to handle B-frames in AVI? */ - pkt->dts = ast->frame_offset; -// pkt->dts += ast->start; - if(ast->sample_size) - pkt->dts /= ast->sample_size; -//av_log(s, AV_LOG_DEBUG, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n", pkt->dts, ast->frame_offset, ast->scale, ast->rate, ast->sample_size, AV_TIME_BASE, avi->stream_index, size); - pkt->stream_index = avi->stream_index; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - AVIndexEntry *e; - int index; - assert(st->index_entries); - - index= av_index_search_timestamp(st, ast->frame_offset, 0); - e= &st->index_entries[index]; - - if(index >= 0 && e->timestamp == ast->frame_offset){ - if (e->flags & AVINDEX_KEYFRAME) - pkt->flags |= AV_PKT_FLAG_KEY; - } - } else { - pkt->flags |= AV_PKT_FLAG_KEY; - } - if(ast->sample_size) - ast->frame_offset += pkt->size; - else - ast->frame_offset++; - } - ast->remaining -= size; - if(!ast->remaining){ - avi->stream_index= -1; - ast->packet_size= 0; - } - - return size; - } - - memset(d, -1, sizeof(int)*8); - for(i=sync=url_ftell(pb); !url_feof(pb); i++) { - int j; - - for(j=0; j<7; j++) - d[j]= d[j+1]; - d[7]= get_byte(pb); - - size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24); - - n= get_stream_idx(d+2); -//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n); - if(i + (uint64_t)size > avi->fsize || d[0]<0) - continue; - - //parse ix## - if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) - //parse JUNK - ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') - ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){ - url_fskip(pb, size); -//av_log(s, AV_LOG_DEBUG, "SKIP\n"); - goto resync; - } - - //parse stray LIST - if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){ - url_fskip(pb, 4); - goto resync; - } - - n= get_stream_idx(d); - - if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams) - continue; - - //detect ##ix chunk and skip - if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){ - url_fskip(pb, size); - goto resync; - } - - //parse ##dc/##wb - if(n < s->nb_streams){ - AVStream *st; - AVIStream *ast; - st = s->streams[n]; - ast = st->priv_data; - - if(s->nb_streams>=2){ - AVStream *st1 = s->streams[1]; - AVIStream *ast1= st1->priv_data; - //workaround for broken small-file-bug402.avi - if( d[2] == 'w' && d[3] == 'b' - && n==0 - && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO - && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO - && ast->prefix == 'd'*256+'c' - && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count) - ){ - n=1; - st = st1; - ast = ast1; - av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n"); - } - } - - - if( (st->discard >= AVDISCARD_DEFAULT && size==0) - /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering - || st->discard >= AVDISCARD_ALL){ - if(ast->sample_size) ast->frame_offset += size; - else ast->frame_offset++; - url_fskip(pb, size); - goto resync; - } - - if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) { - int k = get_byte(pb); - int last = (k + get_byte(pb) - 1) & 0xFF; - - get_le16(pb); //flags - - for (; k <= last; k++) - ast->pal[k] = get_be32(pb)>>8;// b + (g << 8) + (r << 16); - ast->has_pal= 1; - goto resync; - } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) || - d[2]*256+d[3] == ast->prefix /*|| - (d[2] == 'd' && d[3] == 'c') || - (d[2] == 'w' && d[3] == 'b')*/) { - -//av_log(s, AV_LOG_DEBUG, "OK\n"); - if(d[2]*256+d[3] == ast->prefix) - ast->prefix_count++; - else{ - ast->prefix= d[2]*256+d[3]; - ast->prefix_count= 0; - } - - avi->stream_index= n; - ast->packet_size= size + 8; - ast->remaining= size; - - if(size || !ast->sample_size){ - uint64_t pos= url_ftell(pb) - 8; - if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){ - av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME); - } - } - goto resync; - } - } - } - - return AVERROR_EOF; -} - -/* XXX: We make the implicit supposition that the positions are sorted - for each stream. */ -static int avi_read_idx1(AVFormatContext *s, int size) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - int nb_index_entries, i; - AVStream *st; - AVIStream *ast; - unsigned int index, tag, flags, pos, len; - unsigned last_pos= -1; - - nb_index_entries = size / 16; - if (nb_index_entries <= 0) - return -1; - - /* Read the entries and sort them in each stream component. */ - for(i = 0; i < nb_index_entries; i++) { - tag = get_le32(pb); - flags = get_le32(pb); - pos = get_le32(pb); - len = get_le32(pb); -#if defined(DEBUG_SEEK) - av_log(s, AV_LOG_DEBUG, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", - i, tag, flags, pos, len); -#endif - if(i==0 && pos > avi->movi_list) - avi->movi_list= 0; //FIXME better check - pos += avi->movi_list; - - index = ((tag & 0xff) - '0') * 10; - index += ((tag >> 8) & 0xff) - '0'; - if (index >= s->nb_streams) - continue; - st = s->streams[index]; - ast = st->priv_data; - -#if defined(DEBUG_SEEK) - av_log(s, AV_LOG_DEBUG, "%d cum_len=%"PRId64"\n", len, ast->cum_len); -#endif - if(url_feof(pb)) - return -1; - - if(last_pos == pos) - avi->non_interleaved= 1; - else if(len || !ast->sample_size) - av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0); - if(ast->sample_size) - ast->cum_len += len; - else - ast->cum_len ++; - last_pos= pos; - } - return 0; -} - -static int guess_ni_flag(AVFormatContext *s){ - int i; - int64_t last_start=0; - int64_t first_end= INT64_MAX; - int64_t oldpos= url_ftell(s->pb); - - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - int n= st->nb_index_entries; - unsigned int size; - - if(n <= 0) - continue; - - if(n >= 2){ - int64_t pos= st->index_entries[0].pos; - url_fseek(s->pb, pos + 4, SEEK_SET); - size= get_le32(s->pb); - if(pos + size > st->index_entries[1].pos) - last_start= INT64_MAX; - } - - if(st->index_entries[0].pos > last_start) - last_start= st->index_entries[0].pos; - if(st->index_entries[n-1].pos < first_end) - first_end= st->index_entries[n-1].pos; - } - url_fseek(s->pb, oldpos, SEEK_SET); - return last_start > first_end; -} - -static int avi_load_index(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - uint32_t tag, size; - int64_t pos= url_ftell(pb); - int ret = -1; - - if (url_fseek(pb, avi->movi_end, SEEK_SET) < 0) - goto the_end; // maybe truncated file -#ifdef DEBUG_SEEK - printf("movi_end=0x%"PRIx64"\n", avi->movi_end); -#endif - for(;;) { - if (url_feof(pb)) - break; - tag = get_le32(pb); - size = get_le32(pb); -#ifdef DEBUG_SEEK - printf("tag=%c%c%c%c size=0x%x\n", - tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - size); -#endif - switch(tag) { - case MKTAG('i', 'd', 'x', '1'): - if (avi_read_idx1(s, size) < 0) - goto skip; - ret = 0; - goto the_end; - break; - default: - skip: - size += (size & 1); - if (url_fseek(pb, size, SEEK_CUR) < 0) - goto the_end; // something is wrong here - break; - } - } - the_end: - url_fseek(pb, pos, SEEK_SET); - return ret; -} - -static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVIContext *avi = s->priv_data; - AVStream *st; - int i, index; - int64_t pos; - AVIStream *ast; - - if (!avi->index_loaded) { - /* we only load the index on demand */ - avi_load_index(s); - avi->index_loaded = 1; - } - assert(stream_index>= 0); - - st = s->streams[stream_index]; - ast= st->priv_data; - index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags); - if(index<0) - return -1; - - /* find the position */ - pos = st->index_entries[index].pos; - timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); - -// av_log(s, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp); - - if (CONFIG_DV_DEMUXER && avi->dv_demux) { - /* One and only one real stream for DV in AVI, and it has video */ - /* offsets. Calling with other stream indexes should have failed */ - /* the av_index_search_timestamp call above. */ - assert(stream_index == 0); - - /* Feed the DV video stream version of the timestamp to the */ - /* DV demux so it can synthesize correct timestamps. */ - dv_offset_reset(avi->dv_demux, timestamp); - - url_fseek(s->pb, pos, SEEK_SET); - avi->stream_index= -1; - return 0; - } - - for(i = 0; i < s->nb_streams; i++) { - AVStream *st2 = s->streams[i]; - AVIStream *ast2 = st2->priv_data; - - ast2->packet_size= - ast2->remaining= 0; - - if (st2->nb_index_entries <= 0) - continue; - -// assert(st2->codec->block_align); - assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale); - index = av_index_search_timestamp( - st2, - av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1), - flags | AVSEEK_FLAG_BACKWARD); - if(index<0) - index=0; - - if(!avi->non_interleaved){ - while(index>0 && st2->index_entries[index].pos > pos) - index--; - while(index+1 < st2->nb_index_entries && st2->index_entries[index].pos < pos) - index++; - } - -// av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp); - /* extract the current frame number */ - ast2->frame_offset = st2->index_entries[index].timestamp; - } - - /* do the seek */ - url_fseek(s->pb, pos, SEEK_SET); - avi->stream_index= -1; - return 0; -} - -static int avi_read_close(AVFormatContext *s) -{ - int i; - AVIContext *avi = s->priv_data; - - for(i=0;inb_streams;i++) { - AVStream *st = s->streams[i]; - av_free(st->codec->palctrl); - } - - if (avi->dv_demux) - av_free(avi->dv_demux); - - return 0; -} - -static int avi_probe(AVProbeData *p) -{ - int i; - - /* check file header */ - for(i=0; avi_headers[i][0]; i++) - if(!memcmp(p->buf , avi_headers[i] , 4) && - !memcmp(p->buf+8, avi_headers[i]+4, 4)) - return AVPROBE_SCORE_MAX; - - return 0; -} - -AVInputFormat avi_demuxer = { - "avi", - NULL_IF_CONFIG_SMALL("AVI format"), - sizeof(AVIContext), - avi_probe, - avi_read_header, - avi_read_packet, - avi_read_close, - avi_read_seek, - .metadata_conv = ff_avi_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/avienc.c b/tizen/distrib/ffmpeg/libavformat/avienc.c deleted file mode 100644 index b4a31ec..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avienc.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - * AVI muxer - * Copyright (c) 2000 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "avi.h" -#include "riff.h" -#include "libavutil/intreadwrite.h" - -/* - * TODO: - * - fill all fields if non streamed (nb_frames for example) - */ - -typedef struct AVIIentry { - unsigned int flags, pos, len; -} AVIIentry; - -#define AVI_INDEX_CLUSTER_SIZE 16384 - -typedef struct AVIIndex { - int64_t indx_start; - int entry; - int ents_allocated; - AVIIentry** cluster; -} AVIIndex; - -typedef struct { - int64_t riff_start, movi_list, odml_list; - int64_t frames_hdr_all; - int riff_id; -} AVIContext; - -typedef struct { - int64_t frames_hdr_strm; - int audio_strm_length; - int packet_count; - int entry; - - AVIIndex indexes; -} AVIStream ; - -static inline AVIIentry* avi_get_ientry(AVIIndex* idx, int ent_id) -{ - int cl = ent_id / AVI_INDEX_CLUSTER_SIZE; - int id = ent_id % AVI_INDEX_CLUSTER_SIZE; - return &idx->cluster[cl][id]; -} - -static int64_t avi_start_new_riff(AVFormatContext *s, ByteIOContext *pb, - const char* riff_tag, const char* list_tag) -{ - AVIContext *avi= s->priv_data; - int64_t loff; - int i; - - avi->riff_id++; - for (i=0; inb_streams; i++){ - AVIStream *avist= s->streams[i]->priv_data; - avist->indexes.entry = 0; - } - - avi->riff_start = ff_start_tag(pb, "RIFF"); - put_tag(pb, riff_tag); - loff = ff_start_tag(pb, "LIST"); - put_tag(pb, list_tag); - return loff; -} - -static char* avi_stream2fourcc(char* tag, int index, enum AVMediaType type) -{ - tag[0] = '0'; - tag[1] = '0' + index; - if (type == AVMEDIA_TYPE_VIDEO) { - tag[2] = 'd'; - tag[3] = 'c'; - } else if (type == AVMEDIA_TYPE_SUBTITLE) { - // note: this is not an official code - tag[2] = 's'; - tag[3] = 'b'; - } else { - tag[2] = 'w'; - tag[3] = 'b'; - } - tag[4] = '\0'; - return tag; -} - -static void avi_write_info_tag(ByteIOContext *pb, const char *tag, const char *str) -{ - int len = strlen(str); - if (len > 0) { - len++; - put_tag(pb, tag); - put_le32(pb, len); - put_strz(pb, str); - if (len & 1) - put_byte(pb, 0); - } -} - -static int avi_write_counters(AVFormatContext* s, int riff_id) -{ - ByteIOContext *pb = s->pb; - AVIContext *avi = s->priv_data; - int n, au_byterate, au_ssize, au_scale, nb_frames = 0; - int64_t file_size; - AVCodecContext* stream; - - file_size = url_ftell(pb); - for(n = 0; n < s->nb_streams; n++) { - AVIStream *avist= s->streams[n]->priv_data; - - assert(avist->frames_hdr_strm); - stream = s->streams[n]->codec; - url_fseek(pb, avist->frames_hdr_strm, SEEK_SET); - ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); - if(au_ssize == 0) { - put_le32(pb, avist->packet_count); - } else { - put_le32(pb, avist->audio_strm_length / au_ssize); - } - if(stream->codec_type == AVMEDIA_TYPE_VIDEO) - nb_frames = FFMAX(nb_frames, avist->packet_count); - } - if(riff_id == 1) { - assert(avi->frames_hdr_all); - url_fseek(pb, avi->frames_hdr_all, SEEK_SET); - put_le32(pb, nb_frames); - } - url_fseek(pb, file_size, SEEK_SET); - - return 0; -} - -static int avi_write_header(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; - AVCodecContext *stream, *video_enc; - int64_t list1, list2, strh, strf; - AVMetadataTag *t = NULL; - - for(n=0;nnb_streams;n++) { - s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); - if(!s->streams[n]->priv_data) - return AVERROR(ENOMEM); - } - - /* header list */ - avi->riff_id = 0; - list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl"); - - /* avi header */ - put_tag(pb, "avih"); - put_le32(pb, 14 * 4); - bitrate = 0; - - video_enc = NULL; - for(n=0;nnb_streams;n++) { - stream = s->streams[n]->codec; - bitrate += stream->bit_rate; - if (stream->codec_type == AVMEDIA_TYPE_VIDEO) - video_enc = stream; - } - - nb_frames = 0; - - if(video_enc){ - put_le32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); - } else { - put_le32(pb, 0); - } - put_le32(pb, bitrate / 8); /* XXX: not quite exact */ - put_le32(pb, 0); /* padding */ - if (url_is_streamed(pb)) - put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ - else - put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ - avi->frames_hdr_all = url_ftell(pb); /* remember this offset to fill later */ - put_le32(pb, nb_frames); /* nb frames, filled later */ - put_le32(pb, 0); /* initial frame */ - put_le32(pb, s->nb_streams); /* nb streams */ - put_le32(pb, 1024 * 1024); /* suggested buffer size */ - if(video_enc){ - put_le32(pb, video_enc->width); - put_le32(pb, video_enc->height); - } else { - put_le32(pb, 0); - put_le32(pb, 0); - } - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - - /* stream list */ - for(i=0;istreams[i]->priv_data; - list2 = ff_start_tag(pb, "LIST"); - put_tag(pb, "strl"); - - stream = s->streams[i]->codec; - - /* stream generic header */ - strh = ff_start_tag(pb, "strh"); - switch(stream->codec_type) { - case AVMEDIA_TYPE_SUBTITLE: - // XSUB subtitles behave like video tracks, other subtitles - // are not (yet) supported. - if (stream->codec_id != CODEC_ID_XSUB) break; - case AVMEDIA_TYPE_VIDEO: put_tag(pb, "vids"); break; - case AVMEDIA_TYPE_AUDIO: put_tag(pb, "auds"); break; -// case AVMEDIA_TYPE_TEXT : put_tag(pb, "txts"); break; - case AVMEDIA_TYPE_DATA : put_tag(pb, "dats"); break; - } - if(stream->codec_type == AVMEDIA_TYPE_VIDEO || - stream->codec_id == CODEC_ID_XSUB) - put_le32(pb, stream->codec_tag); - else - put_le32(pb, 1); - put_le32(pb, 0); /* flags */ - put_le16(pb, 0); /* priority */ - put_le16(pb, 0); /* language */ - put_le32(pb, 0); /* initial frame */ - - ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); - - put_le32(pb, au_scale); /* scale */ - put_le32(pb, au_byterate); /* rate */ - av_set_pts_info(s->streams[i], 64, au_scale, au_byterate); - - put_le32(pb, 0); /* start */ - avist->frames_hdr_strm = url_ftell(pb); /* remember this offset to fill later */ - if (url_is_streamed(pb)) - put_le32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ - else - put_le32(pb, 0); /* length, XXX: filled later */ - - /* suggested buffer size */ //FIXME set at the end to largest chunk - if(stream->codec_type == AVMEDIA_TYPE_VIDEO) - put_le32(pb, 1024 * 1024); - else if(stream->codec_type == AVMEDIA_TYPE_AUDIO) - put_le32(pb, 12 * 1024); - else - put_le32(pb, 0); - put_le32(pb, -1); /* quality */ - put_le32(pb, au_ssize); /* sample size */ - put_le32(pb, 0); - put_le16(pb, stream->width); - put_le16(pb, stream->height); - ff_end_tag(pb, strh); - - if(stream->codec_type != AVMEDIA_TYPE_DATA){ - strf = ff_start_tag(pb, "strf"); - switch(stream->codec_type) { - case AVMEDIA_TYPE_SUBTITLE: - // XSUB subtitles behave like video tracks, other subtitles - // are not (yet) supported. - if (stream->codec_id != CODEC_ID_XSUB) break; - case AVMEDIA_TYPE_VIDEO: - ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0); - break; - case AVMEDIA_TYPE_AUDIO: - if (ff_put_wav_header(pb, stream) < 0) { - return -1; - } - break; - default: - return -1; - } - ff_end_tag(pb, strf); - if ((t = av_metadata_get(s->streams[i]->metadata, "strn", NULL, 0))) { - avi_write_info_tag(s->pb, t->key, t->value); - t = NULL; - } - //FIXME a limitation of metadata conversion system - else if ((t = av_metadata_get(s->streams[i]->metadata, "INAM", NULL, 0))) { - avi_write_info_tag(s->pb, "strn", t->value); - t = NULL; - } - } - - if (!url_is_streamed(pb)) { - unsigned char tag[5]; - int j; - - /* Starting to lay out AVI OpenDML master index. - * We want to make it JUNK entry for now, since we'd - * like to get away without making AVI an OpenDML one - * for compatibility reasons. - */ - avist->indexes.entry = avist->indexes.ents_allocated = 0; - avist->indexes.indx_start = ff_start_tag(pb, "JUNK"); - put_le16(pb, 4); /* wLongsPerEntry */ - put_byte(pb, 0); /* bIndexSubType (0 == frame index) */ - put_byte(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ - put_le32(pb, 0); /* nEntriesInUse (will fill out later on) */ - put_tag(pb, avi_stream2fourcc(&tag[0], i, stream->codec_type)); - /* dwChunkId */ - put_le64(pb, 0); /* dwReserved[3] - put_le32(pb, 0); Must be 0. */ - for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++) - put_le64(pb, 0); - ff_end_tag(pb, avist->indexes.indx_start); - } - - if( stream->codec_type == AVMEDIA_TYPE_VIDEO - && s->streams[i]->sample_aspect_ratio.num>0 - && s->streams[i]->sample_aspect_ratio.den>0){ - int vprp= ff_start_tag(pb, "vprp"); - AVRational dar = av_mul_q(s->streams[i]->sample_aspect_ratio, - (AVRational){stream->width, stream->height}); - int num, den; - av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); - - put_le32(pb, 0); //video format = unknown - put_le32(pb, 0); //video standard= unknown - put_le32(pb, lrintf(1.0/av_q2d(stream->time_base))); - put_le32(pb, stream->width ); - put_le32(pb, stream->height); - put_le16(pb, den); - put_le16(pb, num); - put_le32(pb, stream->width ); - put_le32(pb, stream->height); - put_le32(pb, 1); //progressive FIXME - - put_le32(pb, stream->height); - put_le32(pb, stream->width ); - put_le32(pb, stream->height); - put_le32(pb, stream->width ); - put_le32(pb, 0); - put_le32(pb, 0); - - put_le32(pb, 0); - put_le32(pb, 0); - ff_end_tag(pb, vprp); - } - - ff_end_tag(pb, list2); - } - - if (!url_is_streamed(pb)) { - /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ - avi->odml_list = ff_start_tag(pb, "JUNK"); - put_tag(pb, "odml"); - put_tag(pb, "dmlh"); - put_le32(pb, 248); - for (i = 0; i < 248; i+= 4) - put_le32(pb, 0); - ff_end_tag(pb, avi->odml_list); - } - - ff_end_tag(pb, list1); - - list2 = ff_start_tag(pb, "LIST"); - put_tag(pb, "INFO"); - for (i = 0; *ff_avi_tags[i]; i++) { - if ((t = av_metadata_get(s->metadata, ff_avi_tags[i], NULL, AV_METADATA_MATCH_CASE))) - avi_write_info_tag(s->pb, t->key, t->value); - } - ff_end_tag(pb, list2); - - /* some padding for easier tag editing */ - list2 = ff_start_tag(pb, "JUNK"); - for (i = 0; i < 1016; i += 4) - put_le32(pb, 0); - ff_end_tag(pb, list2); - - avi->movi_list = ff_start_tag(pb, "LIST"); - put_tag(pb, "movi"); - - put_flush_packet(pb); - - return 0; -} - -static int avi_write_ix(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - AVIContext *avi = s->priv_data; - char tag[5]; - char ix_tag[] = "ix00"; - int i, j; - - assert(!url_is_streamed(pb)); - - if (avi->riff_id > AVI_MASTER_INDEX_SIZE) - return -1; - - for (i=0;inb_streams;i++) { - AVIStream *avist= s->streams[i]->priv_data; - int64_t ix, pos; - - avi_stream2fourcc(&tag[0], i, s->streams[i]->codec->codec_type); - ix_tag[3] = '0' + i; - - /* Writing AVI OpenDML leaf index chunk */ - ix = url_ftell(pb); - put_tag(pb, &ix_tag[0]); /* ix?? */ - put_le32(pb, avist->indexes.entry * 8 + 24); - /* chunk size */ - put_le16(pb, 2); /* wLongsPerEntry */ - put_byte(pb, 0); /* bIndexSubType (0 == frame index) */ - put_byte(pb, 1); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */ - put_le32(pb, avist->indexes.entry); - /* nEntriesInUse */ - put_tag(pb, &tag[0]); /* dwChunkId */ - put_le64(pb, avi->movi_list);/* qwBaseOffset */ - put_le32(pb, 0); /* dwReserved_3 (must be 0) */ - - for (j=0; jindexes.entry; j++) { - AVIIentry* ie = avi_get_ientry(&avist->indexes, j); - put_le32(pb, ie->pos + 8); - put_le32(pb, ((uint32_t)ie->len & ~0x80000000) | - (ie->flags & 0x10 ? 0 : 0x80000000)); - } - put_flush_packet(pb); - pos = url_ftell(pb); - - /* Updating one entry in the AVI OpenDML master index */ - url_fseek(pb, avist->indexes.indx_start - 8, SEEK_SET); - put_tag(pb, "indx"); /* enabling this entry */ - url_fskip(pb, 8); - put_le32(pb, avi->riff_id); /* nEntriesInUse */ - url_fskip(pb, 16*avi->riff_id); - put_le64(pb, ix); /* qwOffset */ - put_le32(pb, pos - ix); /* dwSize */ - put_le32(pb, avist->indexes.entry); /* dwDuration */ - - url_fseek(pb, pos, SEEK_SET); - } - return 0; -} - -static int avi_write_idx1(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - AVIContext *avi = s->priv_data; - int64_t idx_chunk; - int i; - char tag[5]; - - if (!url_is_streamed(pb)) { - AVIStream *avist; - AVIIentry* ie = 0, *tie; - int empty, stream_id = -1; - - idx_chunk = ff_start_tag(pb, "idx1"); - for(i=0; inb_streams; i++){ - avist= s->streams[i]->priv_data; - avist->entry=0; - } - - do { - empty = 1; - for (i=0; inb_streams; i++) { - avist= s->streams[i]->priv_data; - if (avist->indexes.entry <= avist->entry) - continue; - - tie = avi_get_ientry(&avist->indexes, avist->entry); - if (empty || tie->pos < ie->pos) { - ie = tie; - stream_id = i; - } - empty = 0; - } - if (!empty) { - avist= s->streams[stream_id]->priv_data; - avi_stream2fourcc(&tag[0], stream_id, - s->streams[stream_id]->codec->codec_type); - put_tag(pb, &tag[0]); - put_le32(pb, ie->flags); - put_le32(pb, ie->pos); - put_le32(pb, ie->len); - avist->entry++; - } - } while (!empty); - ff_end_tag(pb, idx_chunk); - - avi_write_counters(s, avi->riff_id); - } - return 0; -} - -static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned char tag[5]; - unsigned int flags=0; - const int stream_index= pkt->stream_index; - AVIStream *avist= s->streams[stream_index]->priv_data; - AVCodecContext *enc= s->streams[stream_index]->codec; - int size= pkt->size; - -// av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %d\n", pkt->dts, avi->packet_count[stream_index], stream_index); - while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count){ - AVPacket empty_packet; - - av_init_packet(&empty_packet); - empty_packet.size= 0; - empty_packet.data= NULL; - empty_packet.stream_index= stream_index; - avi_write_packet(s, &empty_packet); -// av_log(s, AV_LOG_DEBUG, "dup %"PRId64" %d\n", pkt->dts, avi->packet_count[stream_index]); - } - avist->packet_count++; - - // Make sure to put an OpenDML chunk when the file size exceeds the limits - if (!url_is_streamed(pb) && - (url_ftell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) { - - avi_write_ix(s); - ff_end_tag(pb, avi->movi_list); - - if (avi->riff_id == 1) - avi_write_idx1(s); - - ff_end_tag(pb, avi->riff_start); - avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi"); - } - - avi_stream2fourcc(&tag[0], stream_index, enc->codec_type); - if(pkt->flags&AV_PKT_FLAG_KEY) - flags = 0x10; - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - avist->audio_strm_length += size; - } - - if (!url_is_streamed(s->pb)) { - AVIIndex* idx = &avist->indexes; - int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE; - int id = idx->entry % AVI_INDEX_CLUSTER_SIZE; - if (idx->ents_allocated <= idx->entry) { - idx->cluster = av_realloc(idx->cluster, (cl+1)*sizeof(void*)); - if (!idx->cluster) - return -1; - idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry)); - if (!idx->cluster[cl]) - return -1; - idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE; - } - - idx->cluster[cl][id].flags = flags; - idx->cluster[cl][id].pos = url_ftell(pb) - avi->movi_list; - idx->cluster[cl][id].len = size; - idx->entry++; - } - - put_buffer(pb, tag, 4); - put_le32(pb, size); - put_buffer(pb, pkt->data, size); - if (size & 1) - put_byte(pb, 0); - - put_flush_packet(pb); - return 0; -} - -static int avi_write_trailer(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = s->pb; - int res = 0; - int i, j, n, nb_frames; - int64_t file_size; - - if (!url_is_streamed(pb)){ - if (avi->riff_id == 1) { - ff_end_tag(pb, avi->movi_list); - res = avi_write_idx1(s); - ff_end_tag(pb, avi->riff_start); - } else { - avi_write_ix(s); - ff_end_tag(pb, avi->movi_list); - ff_end_tag(pb, avi->riff_start); - - file_size = url_ftell(pb); - url_fseek(pb, avi->odml_list - 8, SEEK_SET); - put_tag(pb, "LIST"); /* Making this AVI OpenDML one */ - url_fskip(pb, 16); - - for (n=nb_frames=0;nnb_streams;n++) { - AVCodecContext *stream = s->streams[n]->codec; - AVIStream *avist= s->streams[n]->priv_data; - - if (stream->codec_type == AVMEDIA_TYPE_VIDEO) { - if (nb_frames < avist->packet_count) - nb_frames = avist->packet_count; - } else { - if (stream->codec_id == CODEC_ID_MP2 || stream->codec_id == CODEC_ID_MP3) { - nb_frames += avist->packet_count; - } - } - } - put_le32(pb, nb_frames); - url_fseek(pb, file_size, SEEK_SET); - - avi_write_counters(s, avi->riff_id); - } - } - put_flush_packet(pb); - - for (i=0; inb_streams; i++) { - AVIStream *avist= s->streams[i]->priv_data; - for (j=0; jindexes.ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++) - av_free(avist->indexes.cluster[j]); - av_freep(&avist->indexes.cluster); - avist->indexes.ents_allocated = avist->indexes.entry = 0; - } - - return res; -} - -AVOutputFormat avi_muxer = { - "avi", - NULL_IF_CONFIG_SMALL("AVI format"), - "video/x-msvideo", - "avi", - sizeof(AVIContext), - CODEC_ID_MP2, - CODEC_ID_MPEG4, - avi_write_header, - avi_write_packet, - avi_write_trailer, - .codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, - .flags= AVFMT_VARIABLE_FPS, - .metadata_conv = ff_avi_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/avio.c b/tizen/distrib/ffmpeg/libavformat/avio.c deleted file mode 100644 index 48399d0..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avio.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Unbuffered io for ffmpeg system - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* needed for usleep() */ -#define _XOPEN_SOURCE 600 -#include -#include "libavutil/avstring.h" -#include "libavcodec/opt.h" -#include "os_support.h" -#include "avformat.h" -#if CONFIG_NETWORK -#include "network.h" -#endif - -#if LIBAVFORMAT_VERSION_MAJOR >= 53 -/** @name Logging context. */ -/*@{*/ -static const char *urlcontext_to_name(void *ptr) -{ - URLContext *h = (URLContext *)ptr; - if(h->prot) return h->prot->name; - else return "NULL"; -} -static const AVOption options[] = {{NULL}}; -static const AVClass urlcontext_class = - { "URLContext", urlcontext_to_name, options, LIBAVUTIL_VERSION_INT }; -/*@}*/ -#endif - -static int default_interrupt_cb(void); - -URLProtocol *first_protocol = NULL; -URLInterruptCB *url_interrupt_cb = default_interrupt_cb; - -URLProtocol *av_protocol_next(URLProtocol *p) -{ - if(p) return p->next; - else return first_protocol; -} - -int av_register_protocol(URLProtocol *protocol) -{ - URLProtocol **p; - p = &first_protocol; - while (*p != NULL) p = &(*p)->next; - *p = protocol; - protocol->next = NULL; - return 0; -} - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -int register_protocol(URLProtocol *protocol) -{ - return av_register_protocol(protocol); -} -#endif - -int url_open_protocol (URLContext **puc, struct URLProtocol *up, - const char *filename, int flags) -{ - URLContext *uc; - int err; - -#if CONFIG_NETWORK - if (!ff_network_init()) - return AVERROR(EIO); -#endif - uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1); - if (!uc) { - err = AVERROR(ENOMEM); - goto fail; - } -#if LIBAVFORMAT_VERSION_MAJOR >= 53 - uc->av_class = &urlcontext_class; -#endif - uc->filename = (char *) &uc[1]; - strcpy(uc->filename, filename); - uc->prot = up; - uc->flags = flags; - uc->is_streamed = 0; /* default = not streamed */ - uc->max_packet_size = 0; /* default: stream file */ - err = up->url_open(uc, filename, flags); - if (err < 0) { - av_free(uc); - goto fail; - } - - //We must be careful here as url_seek() could be slow, for example for http - if( (flags & (URL_WRONLY | URL_RDWR)) - || !strcmp(up->name, "file")) - if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0) - uc->is_streamed= 1; - *puc = uc; - return 0; - fail: - *puc = NULL; -#if CONFIG_NETWORK - ff_network_close(); -#endif - return err; -} - -int url_open(URLContext **puc, const char *filename, int flags) -{ - URLProtocol *up; - const char *p; - char proto_str[128], *q; - - p = filename; - q = proto_str; - while (*p != '\0' && *p != ':') { - /* protocols can only contain alphabetic chars */ - if (!isalpha(*p)) - goto file_proto; - if ((q - proto_str) < sizeof(proto_str) - 1) - *q++ = *p; - p++; - } - /* if the protocol has length 1, we consider it is a dos drive */ - if (*p == '\0' || is_dos_path(filename)) { - file_proto: - strcpy(proto_str, "file"); - } else { - *q = '\0'; - } - - up = first_protocol; - while (up != NULL) { - if (!strcmp(proto_str, up->name)) - return url_open_protocol (puc, up, filename, flags); - up = up->next; - } - *puc = NULL; - return AVERROR(ENOENT); -} - -int url_read(URLContext *h, unsigned char *buf, int size) -{ - int ret; - if (h->flags & URL_WRONLY) - return AVERROR(EIO); - ret = h->prot->url_read(h, buf, size); - return ret; -} - -int url_read_complete(URLContext *h, unsigned char *buf, int size) -{ - int ret, len; - int fast_retries = 5; - - len = 0; - while (len < size) { - ret = url_read(h, buf+len, size-len); - if (ret == AVERROR(EAGAIN)) { - ret = 0; - if (fast_retries) - fast_retries--; - else - usleep(1000); - } else if (ret < 1) - return ret < 0 ? ret : len; - if (ret) - fast_retries = FFMAX(fast_retries, 2); - len += ret; - } - return len; -} - -int url_write(URLContext *h, unsigned char *buf, int size) -{ - int ret; - if (!(h->flags & (URL_WRONLY | URL_RDWR))) - return AVERROR(EIO); - /* avoid sending too big packets */ - if (h->max_packet_size && size > h->max_packet_size) - return AVERROR(EIO); - ret = h->prot->url_write(h, buf, size); - return ret; -} - -int64_t url_seek(URLContext *h, int64_t pos, int whence) -{ - int64_t ret; - - if (!h->prot->url_seek) - return AVERROR(ENOSYS); - ret = h->prot->url_seek(h, pos, whence & ~AVSEEK_FORCE); - return ret; -} - -int url_close(URLContext *h) -{ - int ret = 0; - if (!h) return 0; /* can happen when url_open fails */ - - if (h->prot->url_close) - ret = h->prot->url_close(h); -#if CONFIG_NETWORK - ff_network_close(); -#endif - av_free(h); - return ret; -} - -int url_exist(const char *filename) -{ - URLContext *h; - if (url_open(&h, filename, URL_RDONLY) < 0) - return 0; - url_close(h); - return 1; -} - -int64_t url_filesize(URLContext *h) -{ - int64_t pos, size; - - size= url_seek(h, 0, AVSEEK_SIZE); - if(size<0){ - pos = url_seek(h, 0, SEEK_CUR); - if ((size = url_seek(h, -1, SEEK_END)) < 0) - return size; - size++; - url_seek(h, pos, SEEK_SET); - } - return size; -} - -int url_get_file_handle(URLContext *h) -{ - if (!h->prot->url_get_file_handle) - return -1; - return h->prot->url_get_file_handle(h); -} - -int url_get_max_packet_size(URLContext *h) -{ - return h->max_packet_size; -} - -void url_get_filename(URLContext *h, char *buf, int buf_size) -{ - av_strlcpy(buf, h->filename, buf_size); -} - - -static int default_interrupt_cb(void) -{ - return 0; -} - -void url_set_interrupt_cb(URLInterruptCB *interrupt_cb) -{ - if (!interrupt_cb) - interrupt_cb = default_interrupt_cb; - url_interrupt_cb = interrupt_cb; -} - -int av_url_read_pause(URLContext *h, int pause) -{ - if (!h->prot->url_read_pause) - return AVERROR(ENOSYS); - return h->prot->url_read_pause(h, pause); -} - -int64_t av_url_read_seek(URLContext *h, - int stream_index, int64_t timestamp, int flags) -{ - if (!h->prot->url_read_seek) - return AVERROR(ENOSYS); - return h->prot->url_read_seek(h, stream_index, timestamp, flags); -} diff --git a/tizen/distrib/ffmpeg/libavformat/avio.h b/tizen/distrib/ffmpeg/libavformat/avio.h deleted file mode 100644 index 9ffe935..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avio.h +++ /dev/null @@ -1,525 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVFORMAT_AVIO_H -#define AVFORMAT_AVIO_H - -/** - * @file - * unbuffered I/O operations - * - * @warning This file has to be considered an internal but installed - * header, so it should not be directly included in your projects. - */ - -#include - -#include "libavutil/common.h" - -/* unbuffered I/O */ - -/** - * URL Context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(URLContext) must not be used outside libav*. - */ -typedef struct URLContext { -#if LIBAVFORMAT_VERSION_MAJOR >= 53 - const AVClass *av_class; ///< information for av_log(). Set by url_open(). -#endif - struct URLProtocol *prot; - int flags; - int is_streamed; /**< true if streamed (no seek possible), default = false */ - int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ - void *priv_data; - char *filename; /**< specified URL */ -} URLContext; - -typedef struct URLPollEntry { - URLContext *handle; - int events; - int revents; -} URLPollEntry; - -#define URL_RDONLY 0 -#define URL_WRONLY 1 -#define URL_RDWR 2 - -typedef int URLInterruptCB(void); - -/** - * Creates an URLContext for accessing to the resource indicated by - * url, and opens it using the URLProtocol up. - * - * @param puc pointer to the location where, in case of success, the - * function puts the pointer to the created URLContext - * @param flags flags which control how the resource indicated by url - * is to be opened - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_open_protocol (URLContext **puc, struct URLProtocol *up, - const char *url, int flags); - -/** - * Creates an URLContext for accessing to the resource indicated by - * url, and opens it. - * - * @param puc pointer to the location where, in case of success, the - * function puts the pointer to the created URLContext - * @param flags flags which control how the resource indicated by url - * is to be opened - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_open(URLContext **h, const char *url, int flags); - -/** - * Reads up to size bytes from the resource accessed by h, and stores - * the read bytes in buf. - * - * @return The number of bytes actually read, or a negative value - * corresponding to an AVERROR code in case of error. A value of zero - * indicates that it is not possible to read more from the accessed - * resource (except if the value of the size argument is also zero). - */ -int url_read(URLContext *h, unsigned char *buf, int size); - -/** - * Read as many bytes as possible (up to size), calling the - * read function multiple times if necessary. - * Will also retry if the read function returns AVERROR(EAGAIN). - * This makes special short-read handling in applications - * unnecessary, if the return value is < size then it is - * certain there was either an error or the end of file was reached. - */ -int url_read_complete(URLContext *h, unsigned char *buf, int size); -int url_write(URLContext *h, unsigned char *buf, int size); - -/** - * Changes the position that will be used by the next read/write - * operation on the resource accessed by h. - * - * @param pos specifies the new position to set - * @param whence specifies how pos should be interpreted, it must be - * one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the - * current position), SEEK_END (seek from the end), or AVSEEK_SIZE - * (return the filesize of the requested resource, pos is ignored). - * @return a negative value corresponding to an AVERROR code in case - * of failure, or the resulting file position, measured in bytes from - * the beginning of the file. You can use this feature together with - * SEEK_CUR to read the current file position. - */ -int64_t url_seek(URLContext *h, int64_t pos, int whence); - -/** - * Closes the resource accessed by the URLContext h, and frees the - * memory used by it. - * - * @return a negative value if an error condition occurred, 0 - * otherwise - */ -int url_close(URLContext *h); - -/** - * Returns a non-zero value if the resource indicated by url - * exists, 0 otherwise. - */ -int url_exist(const char *url); - -int64_t url_filesize(URLContext *h); - -/** - * Return the file descriptor associated with this URL. For RTP, this - * will return only the RTP file descriptor, not the RTCP file descriptor. - * To get both, use rtp_get_file_handles(). - * - * @return the file descriptor associated with this URL, or <0 on error. - */ -int url_get_file_handle(URLContext *h); - -/** - * Return the maximum packet size associated to packetized file - * handle. If the file is not packetized (stream like HTTP or file on - * disk), then 0 is returned. - * - * @param h file handle - * @return maximum packet size in bytes - */ -int url_get_max_packet_size(URLContext *h); -void url_get_filename(URLContext *h, char *buf, int buf_size); - -/** - * The callback is called in blocking functions to test regulary if - * asynchronous interruption is needed. AVERROR(EINTR) is returned - * in this case by the interrupted function. 'NULL' means no interrupt - * callback is given. - */ -void url_set_interrupt_cb(URLInterruptCB *interrupt_cb); - -/* not implemented */ -int url_poll(URLPollEntry *poll_table, int n, int timeout); - -/** - * Pause and resume playing - only meaningful if using a network streaming - * protocol (e.g. MMS). - * @param pause 1 for pause, 0 for resume - */ -int av_url_read_pause(URLContext *h, int pause); - -/** - * Seek to a given timestamp relative to some component stream. - * Only meaningful if using a network streaming protocol (e.g. MMS.). - * @param stream_index The stream index that the timestamp is relative to. - * If stream_index is (-1) the timestamp should be in AV_TIME_BASE - * units from the beginning of the presentation. - * If a stream_index >= 0 is used and the protocol does not support - * seeking based on component streams, the call will fail with ENOTSUP. - * @param timestamp timestamp in AVStream.time_base units - * or if there is no stream specified then in AV_TIME_BASE units. - * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE - * and AVSEEK_FLAG_ANY. The protocol may silently ignore - * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will - * fail with ENOTSUP if used and not supported. - * @return >= 0 on success - * @see AVInputFormat::read_seek - */ -int64_t av_url_read_seek(URLContext *h, int stream_index, - int64_t timestamp, int flags); - -/** - * Passing this as the "whence" parameter to a seek function causes it to - * return the filesize without seeking anywhere. Supporting this is optional. - * If it is not supported then the seek function will return <0. - */ -#define AVSEEK_SIZE 0x10000 - -/** - * Oring this flag as into the "whence" parameter to a seek function causes it to - * seek by any means (like reopening and linear reading) or other normally unreasonble - * means that can be extreemly slow. - * This may be ignored by the seek code. - */ -#define AVSEEK_FORCE 0x20000 - -typedef struct URLProtocol { - const char *name; - int (*url_open)(URLContext *h, const char *url, int flags); - int (*url_read)(URLContext *h, unsigned char *buf, int size); - int (*url_write)(URLContext *h, unsigned char *buf, int size); - int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); - int (*url_close)(URLContext *h); - struct URLProtocol *next; - int (*url_read_pause)(URLContext *h, int pause); - int64_t (*url_read_seek)(URLContext *h, int stream_index, - int64_t timestamp, int flags); - int (*url_get_file_handle)(URLContext *h); -} URLProtocol; - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -extern URLProtocol *first_protocol; -#endif - -extern URLInterruptCB *url_interrupt_cb; - -/** - * If protocol is NULL, returns the first registered protocol, - * if protocol is non-NULL, returns the next registered protocol after protocol, - * or NULL if protocol is the last one. - */ -URLProtocol *av_protocol_next(URLProtocol *p); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** - * @deprecated Use av_register_protocol() instead. - */ -attribute_deprecated int register_protocol(URLProtocol *protocol); -#endif - -/** - * Registers the URLProtocol protocol. - */ -int av_register_protocol(URLProtocol *protocol); - -/** - * Bytestream IO Context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(ByteIOContext) must not be used outside libav*. - */ -typedef struct { - unsigned char *buffer; - int buffer_size; - unsigned char *buf_ptr, *buf_end; - void *opaque; - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); - int64_t (*seek)(void *opaque, int64_t offset, int whence); - int64_t pos; /**< position in the file of the current buffer */ - int must_flush; /**< true if the next seek should flush */ - int eof_reached; /**< true if eof reached */ - int write_flag; /**< true if open for writing */ - int is_streamed; - int max_packet_size; - unsigned long checksum; - unsigned char *checksum_ptr; - unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); - int error; ///< contains the error code or 0 if no error happened - int (*read_pause)(void *opaque, int pause); - int64_t (*read_seek)(void *opaque, int stream_index, - int64_t timestamp, int flags); -} ByteIOContext; - -int init_put_byte(ByteIOContext *s, - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)); -ByteIOContext *av_alloc_put_byte( - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)); - -void put_byte(ByteIOContext *s, int b); -void put_buffer(ByteIOContext *s, const unsigned char *buf, int size); -void put_le64(ByteIOContext *s, uint64_t val); -void put_be64(ByteIOContext *s, uint64_t val); -void put_le32(ByteIOContext *s, unsigned int val); -void put_be32(ByteIOContext *s, unsigned int val); -void put_le24(ByteIOContext *s, unsigned int val); -void put_be24(ByteIOContext *s, unsigned int val); -void put_le16(ByteIOContext *s, unsigned int val); -void put_be16(ByteIOContext *s, unsigned int val); -void put_tag(ByteIOContext *s, const char *tag); - -void put_strz(ByteIOContext *s, const char *buf); - -/** - * fseek() equivalent for ByteIOContext. - * @return new position or AVERROR. - */ -int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence); - -/** - * Skip given number of bytes forward. - * @param offset number of bytes - */ -void url_fskip(ByteIOContext *s, int64_t offset); - -/** - * ftell() equivalent for ByteIOContext. - * @return position or AVERROR. - */ -int64_t url_ftell(ByteIOContext *s); - -/** - * Gets the filesize. - * @return filesize or AVERROR - */ -int64_t url_fsize(ByteIOContext *s); - -/** - * feof() equivalent for ByteIOContext. - * @return non zero if and only if end of file - */ -int url_feof(ByteIOContext *s); - -int url_ferror(ByteIOContext *s); - -int av_url_read_fpause(ByteIOContext *h, int pause); -int64_t av_url_read_fseek(ByteIOContext *h, int stream_index, - int64_t timestamp, int flags); - -#define URL_EOF (-1) -/** @note return URL_EOF (-1) if EOF */ -int url_fgetc(ByteIOContext *s); - -/** @warning currently size is limited */ -#ifdef __GNUC__ -int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); -#else -int url_fprintf(ByteIOContext *s, const char *fmt, ...); -#endif - -/** @note unlike fgets, the EOL character is not returned and a whole - line is parsed. return NULL if first char read was EOF */ -char *url_fgets(ByteIOContext *s, char *buf, int buf_size); - -void put_flush_packet(ByteIOContext *s); - - -/** - * Reads size bytes from ByteIOContext into buf. - * @return number of bytes read or AVERROR - */ -int get_buffer(ByteIOContext *s, unsigned char *buf, int size); - -/** - * Reads size bytes from ByteIOContext into buf. - * This reads at most 1 packet. If that is not enough fewer bytes will be - * returned. - * @return number of bytes read or AVERROR - */ -int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size); - -/** @note return 0 if EOF, so you cannot use it if EOF handling is - necessary */ -int get_byte(ByteIOContext *s); -unsigned int get_le24(ByteIOContext *s); -unsigned int get_le32(ByteIOContext *s); -uint64_t get_le64(ByteIOContext *s); -unsigned int get_le16(ByteIOContext *s); - -char *get_strz(ByteIOContext *s, char *buf, int maxlen); -unsigned int get_be16(ByteIOContext *s); -unsigned int get_be24(ByteIOContext *s); -unsigned int get_be32(ByteIOContext *s); -uint64_t get_be64(ByteIOContext *s); - -uint64_t ff_get_v(ByteIOContext *bc); - -static inline int url_is_streamed(ByteIOContext *s) -{ - return s->is_streamed; -} - -/** - * Creates and initializes a ByteIOContext for accessing the - * resource referenced by the URLContext h. - * @note When the URLContext h has been opened in read+write mode, the - * ByteIOContext can be used only for writing. - * - * @param s Used to return the pointer to the created ByteIOContext. - * In case of failure the pointed to value is set to NULL. - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_fdopen(ByteIOContext **s, URLContext *h); - -/** @warning must be called before any I/O */ -int url_setbufsize(ByteIOContext *s, int buf_size); -#if LIBAVFORMAT_VERSION_MAJOR < 53 -/** Reset the buffer for reading or writing. - * @note Will drop any data currently in the buffer without transmitting it. - * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY - * to set up the buffer for writing. */ -int url_resetbuf(ByteIOContext *s, int flags); -#endif - -/** - * Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file. - * Used after probing to avoid seeking. - * Joins buf and s->buffer, taking any overlap into consideration. - * @note s->buffer must overlap with buf or they can't be joined and the function fails - * @note This function is NOT part of the public API - * - * @param s The read-only ByteIOContext to rewind - * @param buf The probe buffer containing the first buf_size bytes of the file - * @param buf_size The size of buf - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size); - -/** - * Creates and initializes a ByteIOContext for accessing the - * resource indicated by url. - * @note When the resource indicated by url has been opened in - * read+write mode, the ByteIOContext can be used only for writing. - * - * @param s Used to return the pointer to the created ByteIOContext. - * In case of failure the pointed to value is set to NULL. - * @param flags flags which control how the resource indicated by url - * is to be opened - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int url_fopen(ByteIOContext **s, const char *url, int flags); - -int url_fclose(ByteIOContext *s); -URLContext *url_fileno(ByteIOContext *s); - -/** - * Return the maximum packet size associated to packetized buffered file - * handle. If the file is not packetized (stream like http or file on - * disk), then 0 is returned. - * - * @param s buffered file handle - * @return maximum packet size in bytes - */ -int url_fget_max_packet_size(ByteIOContext *s); - -int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags); - -/** return the written or read size */ -int url_close_buf(ByteIOContext *s); - -/** - * Open a write only memory stream. - * - * @param s new IO context - * @return zero if no error. - */ -int url_open_dyn_buf(ByteIOContext **s); - -/** - * Open a write only packetized memory stream with a maximum packet - * size of 'max_packet_size'. The stream is stored in a memory buffer - * with a big endian 4 byte header giving the packet size in bytes. - * - * @param s new IO context - * @param max_packet_size maximum packet size (must be > 0) - * @return zero if no error. - */ -int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size); - -/** - * Return the written size and a pointer to the buffer. The buffer - * must be freed with av_free(). - * @param s IO context - * @param pbuffer pointer to a byte buffer - * @return the length of the byte buffer - */ -int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer); - -unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, - unsigned int len); -unsigned long get_checksum(ByteIOContext *s); -void init_checksum(ByteIOContext *s, - unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), - unsigned long checksum); - -/* udp.c */ -int udp_set_remote_url(URLContext *h, const char *uri); -int udp_get_local_port(URLContext *h); -#if (LIBAVFORMAT_VERSION_MAJOR <= 52) -int udp_get_file_handle(URLContext *h); -#endif - -#endif /* AVFORMAT_AVIO_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/aviobuf.c b/tizen/distrib/ffmpeg/libavformat/aviobuf.c deleted file mode 100644 index 8684903..0000000 --- a/tizen/distrib/ffmpeg/libavformat/aviobuf.c +++ /dev/null @@ -1,906 +0,0 @@ -/* - * Buffered I/O for ffmpeg system - * Copyright (c) 2000,2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/crc.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "avio.h" -#include - -#define IO_BUFFER_SIZE 32768 - -static void fill_buffer(ByteIOContext *s); -#if LIBAVFORMAT_VERSION_MAJOR >= 53 -static int url_resetbuf(ByteIOContext *s, int flags); -#endif - -int init_put_byte(ByteIOContext *s, - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)) -{ - s->buffer = buffer; - s->buffer_size = buffer_size; - s->buf_ptr = buffer; - s->opaque = opaque; - url_resetbuf(s, write_flag ? URL_WRONLY : URL_RDONLY); - s->write_packet = write_packet; - s->read_packet = read_packet; - s->seek = seek; - s->pos = 0; - s->must_flush = 0; - s->eof_reached = 0; - s->error = 0; - s->is_streamed = 0; - s->max_packet_size = 0; - s->update_checksum= NULL; - if(!read_packet && !write_flag){ - s->pos = buffer_size; - s->buf_end = s->buffer + buffer_size; - } - s->read_pause = NULL; - s->read_seek = NULL; - return 0; -} - -ByteIOContext *av_alloc_put_byte( - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)) -{ - ByteIOContext *s = av_mallocz(sizeof(ByteIOContext)); - init_put_byte(s, buffer, buffer_size, write_flag, opaque, - read_packet, write_packet, seek); - return s; -} - -static void flush_buffer(ByteIOContext *s) -{ - if (s->buf_ptr > s->buffer) { - if (s->write_packet && !s->error){ - int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer); - if(ret < 0){ - s->error = ret; - } - } - if(s->update_checksum){ - s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); - s->checksum_ptr= s->buffer; - } - s->pos += s->buf_ptr - s->buffer; - } - s->buf_ptr = s->buffer; -} - -void put_byte(ByteIOContext *s, int b) -{ - *(s->buf_ptr)++ = b; - if (s->buf_ptr >= s->buf_end) - flush_buffer(s); -} - -void put_buffer(ByteIOContext *s, const unsigned char *buf, int size) -{ - while (size > 0) { - int len = FFMIN(s->buf_end - s->buf_ptr, size); - memcpy(s->buf_ptr, buf, len); - s->buf_ptr += len; - - if (s->buf_ptr >= s->buf_end) - flush_buffer(s); - - buf += len; - size -= len; - } -} - -void put_flush_packet(ByteIOContext *s) -{ - flush_buffer(s); - s->must_flush = 0; -} - -int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence) -{ - int64_t offset1; - int64_t pos; - int force = whence & AVSEEK_FORCE; - whence &= ~AVSEEK_FORCE; - - if(!s) - return AVERROR(EINVAL); - - pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer)); - - if (whence != SEEK_CUR && whence != SEEK_SET) - return AVERROR(EINVAL); - - if (whence == SEEK_CUR) { - offset1 = pos + (s->buf_ptr - s->buffer); - if (offset == 0) - return offset1; - offset += offset1; - } - offset1 = offset - pos; - if (!s->must_flush && - offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { - /* can do the seek inside the buffer */ - s->buf_ptr = s->buffer + offset1; - } else if(s->is_streamed && !s->write_flag && offset1 >= 0 && - (whence != SEEK_END || force)) { - while(s->pos < offset && !s->eof_reached) - fill_buffer(s); - if (s->eof_reached) - return AVERROR_EOF; - s->buf_ptr = s->buf_end + offset - s->pos; - } else { - int64_t res; - -#if CONFIG_MUXERS || CONFIG_NETWORK - if (s->write_flag) { - flush_buffer(s); - s->must_flush = 1; - } -#endif /* CONFIG_MUXERS || CONFIG_NETWORK */ - if (!s->seek) - return AVERROR(EPIPE); - if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0) - return res; - if (!s->write_flag) - s->buf_end = s->buffer; - s->buf_ptr = s->buffer; - s->pos = offset; - } - s->eof_reached = 0; - return offset; -} - -void url_fskip(ByteIOContext *s, int64_t offset) -{ - url_fseek(s, offset, SEEK_CUR); -} - -int64_t url_ftell(ByteIOContext *s) -{ - return url_fseek(s, 0, SEEK_CUR); -} - -int64_t url_fsize(ByteIOContext *s) -{ - int64_t size; - - if(!s) - return AVERROR(EINVAL); - - if (!s->seek) - return AVERROR(ENOSYS); - size = s->seek(s->opaque, 0, AVSEEK_SIZE); - if(size<0){ - if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0) - return size; - size++; - s->seek(s->opaque, s->pos, SEEK_SET); - } - return size; -} - -int url_feof(ByteIOContext *s) -{ - if(!s) - return 0; - return s->eof_reached; -} - -int url_ferror(ByteIOContext *s) -{ - if(!s) - return 0; - return s->error; -} - -void put_le32(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val); - put_byte(s, val >> 8); - put_byte(s, val >> 16); - put_byte(s, val >> 24); -} - -void put_be32(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val >> 24); - put_byte(s, val >> 16); - put_byte(s, val >> 8); - put_byte(s, val); -} - -void put_strz(ByteIOContext *s, const char *str) -{ - if (str) - put_buffer(s, (const unsigned char *) str, strlen(str) + 1); - else - put_byte(s, 0); -} - -void put_le64(ByteIOContext *s, uint64_t val) -{ - put_le32(s, (uint32_t)(val & 0xffffffff)); - put_le32(s, (uint32_t)(val >> 32)); -} - -void put_be64(ByteIOContext *s, uint64_t val) -{ - put_be32(s, (uint32_t)(val >> 32)); - put_be32(s, (uint32_t)(val & 0xffffffff)); -} - -void put_le16(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val); - put_byte(s, val >> 8); -} - -void put_be16(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val >> 8); - put_byte(s, val); -} - -void put_le24(ByteIOContext *s, unsigned int val) -{ - put_le16(s, val & 0xffff); - put_byte(s, val >> 16); -} - -void put_be24(ByteIOContext *s, unsigned int val) -{ - put_be16(s, val >> 8); - put_byte(s, val); -} - -void put_tag(ByteIOContext *s, const char *tag) -{ - while (*tag) { - put_byte(s, *tag++); - } -} - -/* Input stream */ - -static void fill_buffer(ByteIOContext *s) -{ - uint8_t *dst= !s->max_packet_size && s->buf_end - s->buffer < s->buffer_size ? s->buf_ptr : s->buffer; - int len= s->buffer_size - (dst - s->buffer); - int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE; - - assert(s->buf_ptr == s->buf_end); - - /* no need to do anything if EOF already reached */ - if (s->eof_reached) - return; - - if(s->update_checksum && dst == s->buffer){ - if(s->buf_end > s->checksum_ptr) - s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_end - s->checksum_ptr); - s->checksum_ptr= s->buffer; - } - - /* make buffer smaller in case it ended up large after probing */ - if (s->buffer_size > max_buffer_size) { - url_setbufsize(s, max_buffer_size); - - s->checksum_ptr = dst = s->buffer; - len = s->buffer_size; - } - - if(s->read_packet) - len = s->read_packet(s->opaque, dst, len); - else - len = 0; - if (len <= 0) { - /* do not modify buffer if EOF reached so that a seek back can - be done without rereading data */ - s->eof_reached = 1; - if(len<0) - s->error= len; - } else { - s->pos += len; - s->buf_ptr = dst; - s->buf_end = dst + len; - } -} - -unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, - unsigned int len) -{ - return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len); -} - -unsigned long get_checksum(ByteIOContext *s) -{ - s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); - s->update_checksum= NULL; - return s->checksum; -} - -void init_checksum(ByteIOContext *s, - unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), - unsigned long checksum) -{ - s->update_checksum= update_checksum; - if(s->update_checksum){ - s->checksum= checksum; - s->checksum_ptr= s->buf_ptr; - } -} - -/* XXX: put an inline version */ -int get_byte(ByteIOContext *s) -{ - if (s->buf_ptr < s->buf_end) { - return *s->buf_ptr++; - } else { - fill_buffer(s); - if (s->buf_ptr < s->buf_end) - return *s->buf_ptr++; - else - return 0; - } -} - -int url_fgetc(ByteIOContext *s) -{ - if (s->buf_ptr < s->buf_end) { - return *s->buf_ptr++; - } else { - fill_buffer(s); - if (s->buf_ptr < s->buf_end) - return *s->buf_ptr++; - else - return URL_EOF; - } -} - -int get_buffer(ByteIOContext *s, unsigned char *buf, int size) -{ - int len, size1; - - size1 = size; - while (size > 0) { - len = s->buf_end - s->buf_ptr; - if (len > size) - len = size; - if (len == 0) { - if(size > s->buffer_size && !s->update_checksum){ - if(s->read_packet) - len = s->read_packet(s->opaque, buf, size); - if (len <= 0) { - /* do not modify buffer if EOF reached so that a seek back can - be done without rereading data */ - s->eof_reached = 1; - if(len<0) - s->error= len; - break; - } else { - s->pos += len; - size -= len; - buf += len; - s->buf_ptr = s->buffer; - s->buf_end = s->buffer/* + len*/; - } - }else{ - fill_buffer(s); - len = s->buf_end - s->buf_ptr; - if (len == 0) - break; - } - } else { - memcpy(buf, s->buf_ptr, len); - buf += len; - s->buf_ptr += len; - size -= len; - } - } - if (size1 == size) { - if (url_ferror(s)) return url_ferror(s); - if (url_feof(s)) return AVERROR_EOF; - } - return size1 - size; -} - -int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size) -{ - int len; - - if(size<0) - return -1; - - len = s->buf_end - s->buf_ptr; - if (len == 0) { - fill_buffer(s); - len = s->buf_end - s->buf_ptr; - } - if (len > size) - len = size; - memcpy(buf, s->buf_ptr, len); - s->buf_ptr += len; - if (!len) { - if (url_ferror(s)) return url_ferror(s); - if (url_feof(s)) return AVERROR_EOF; - } - return len; -} - -unsigned int get_le16(ByteIOContext *s) -{ - unsigned int val; - val = get_byte(s); - val |= get_byte(s) << 8; - return val; -} - -unsigned int get_le24(ByteIOContext *s) -{ - unsigned int val; - val = get_le16(s); - val |= get_byte(s) << 16; - return val; -} - -unsigned int get_le32(ByteIOContext *s) -{ - unsigned int val; - val = get_le16(s); - val |= get_le16(s) << 16; - return val; -} - -uint64_t get_le64(ByteIOContext *s) -{ - uint64_t val; - val = (uint64_t)get_le32(s); - val |= (uint64_t)get_le32(s) << 32; - return val; -} - -unsigned int get_be16(ByteIOContext *s) -{ - unsigned int val; - val = get_byte(s) << 8; - val |= get_byte(s); - return val; -} - -unsigned int get_be24(ByteIOContext *s) -{ - unsigned int val; - val = get_be16(s) << 8; - val |= get_byte(s); - return val; -} -unsigned int get_be32(ByteIOContext *s) -{ - unsigned int val; - val = get_be16(s) << 16; - val |= get_be16(s); - return val; -} - -char *get_strz(ByteIOContext *s, char *buf, int maxlen) -{ - int i = 0; - char c; - - while ((c = get_byte(s))) { - if (i < maxlen-1) - buf[i++] = c; - } - - buf[i] = 0; /* Ensure null terminated, but may be truncated */ - - return buf; -} - -uint64_t get_be64(ByteIOContext *s) -{ - uint64_t val; - val = (uint64_t)get_be32(s) << 32; - val |= (uint64_t)get_be32(s); - return val; -} - -uint64_t ff_get_v(ByteIOContext *bc){ - uint64_t val = 0; - int tmp; - - do{ - tmp = get_byte(bc); - val= (val<<7) + (tmp&127); - }while(tmp&128); - return val; -} - -int url_fdopen(ByteIOContext **s, URLContext *h) -{ - uint8_t *buffer; - int buffer_size, max_packet_size; - - max_packet_size = url_get_max_packet_size(h); - if (max_packet_size) { - buffer_size = max_packet_size; /* no need to bufferize more than one packet */ - } else { - buffer_size = IO_BUFFER_SIZE; - } - buffer = av_malloc(buffer_size); - if (!buffer) - return AVERROR(ENOMEM); - - *s = av_mallocz(sizeof(ByteIOContext)); - if(!*s) { - av_free(buffer); - return AVERROR(ENOMEM); - } - - if (init_put_byte(*s, buffer, buffer_size, - (h->flags & URL_WRONLY || h->flags & URL_RDWR), h, - url_read, url_write, url_seek) < 0) { - av_free(buffer); - av_freep(s); - return AVERROR(EIO); - } - (*s)->is_streamed = h->is_streamed; - (*s)->max_packet_size = max_packet_size; - if(h->prot) { - (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; - (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; - } - return 0; -} - -int url_setbufsize(ByteIOContext *s, int buf_size) -{ - uint8_t *buffer; - buffer = av_malloc(buf_size); - if (!buffer) - return AVERROR(ENOMEM); - - av_free(s->buffer); - s->buffer = buffer; - s->buffer_size = buf_size; - s->buf_ptr = buffer; - url_resetbuf(s, s->write_flag ? URL_WRONLY : URL_RDONLY); - return 0; -} - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -int url_resetbuf(ByteIOContext *s, int flags) -#else -static int url_resetbuf(ByteIOContext *s, int flags) -#endif -{ -#if LIBAVFORMAT_VERSION_MAJOR < 53 - URLContext *h = s->opaque; - if ((flags & URL_RDWR) || (h && h->flags != flags && !h->flags & URL_RDWR)) - return AVERROR(EINVAL); -#else - assert(flags == URL_WRONLY || flags == URL_RDONLY); -#endif - - if (flags & URL_WRONLY) { - s->buf_end = s->buffer + s->buffer_size; - s->write_flag = 1; - } else { - s->buf_end = s->buffer; - s->write_flag = 0; - } - return 0; -} - -int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size) -{ - int64_t buffer_start; - int buffer_size; - int overlap, new_size; - - if (s->write_flag) - return AVERROR(EINVAL); - - buffer_size = s->buf_end - s->buffer; - - /* the buffers must touch or overlap */ - if ((buffer_start = s->pos - buffer_size) > buf_size) - return AVERROR(EINVAL); - - overlap = buf_size - buffer_start; - new_size = buf_size + buffer_size - overlap; - - if (new_size > buf_size) { - if (!(buf = av_realloc(buf, new_size))) - return AVERROR(ENOMEM); - - memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap); - buf_size = new_size; - } - - av_free(s->buffer); - s->buf_ptr = s->buffer = buf; - s->pos = s->buffer_size = buf_size; - s->buf_end = s->buf_ptr + buf_size; - s->eof_reached = 0; - s->must_flush = 0; - - return 0; -} - -int url_fopen(ByteIOContext **s, const char *filename, int flags) -{ - URLContext *h; - int err; - - err = url_open(&h, filename, flags); - if (err < 0) - return err; - err = url_fdopen(s, h); - if (err < 0) { - url_close(h); - return err; - } - return 0; -} - -int url_fclose(ByteIOContext *s) -{ - URLContext *h = s->opaque; - - av_free(s->buffer); - av_free(s); - return url_close(h); -} - -URLContext *url_fileno(ByteIOContext *s) -{ - return s->opaque; -} - -#if CONFIG_MUXERS -int url_fprintf(ByteIOContext *s, const char *fmt, ...) -{ - va_list ap; - char buf[4096]; - int ret; - - va_start(ap, fmt); - ret = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - put_buffer(s, buf, strlen(buf)); - return ret; -} -#endif //CONFIG_MUXERS - -char *url_fgets(ByteIOContext *s, char *buf, int buf_size) -{ - int c; - char *q; - - c = url_fgetc(s); - if (c == EOF) - return NULL; - q = buf; - for(;;) { - if (c == EOF || c == '\n') - break; - if ((q - buf) < buf_size - 1) - *q++ = c; - c = url_fgetc(s); - } - if (buf_size > 0) - *q = '\0'; - return buf; -} - -int url_fget_max_packet_size(ByteIOContext *s) -{ - return s->max_packet_size; -} - -int av_url_read_fpause(ByteIOContext *s, int pause) -{ - if (!s->read_pause) - return AVERROR(ENOSYS); - return s->read_pause(s->opaque, pause); -} - -int64_t av_url_read_fseek(ByteIOContext *s, int stream_index, - int64_t timestamp, int flags) -{ - URLContext *h = s->opaque; - int64_t ret; - if (!s->read_seek) - return AVERROR(ENOSYS); - ret = s->read_seek(h, stream_index, timestamp, flags); - if(ret >= 0) { - int64_t pos; - s->buf_ptr = s->buf_end; // Flush buffer - pos = s->seek(h, 0, SEEK_CUR); - if (pos >= 0) - s->pos = pos; - else if (pos != AVERROR(ENOSYS)) - ret = pos; - } - return ret; -} - -/* url_open_dyn_buf and url_close_dyn_buf are used in rtp.c to send a response - * back to the server even if CONFIG_MUXERS is false. */ -#if CONFIG_MUXERS || CONFIG_NETWORK -/* buffer handling */ -int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags) -{ - int ret; - *s = av_mallocz(sizeof(ByteIOContext)); - if(!*s) - return AVERROR(ENOMEM); - ret = init_put_byte(*s, buf, buf_size, - (flags & URL_WRONLY || flags & URL_RDWR), - NULL, NULL, NULL, NULL); - if(ret != 0) - av_freep(s); - return ret; -} - -int url_close_buf(ByteIOContext *s) -{ - put_flush_packet(s); - return s->buf_ptr - s->buffer; -} - -/* output in a dynamic buffer */ - -typedef struct DynBuffer { - int pos, size, allocated_size; - uint8_t *buffer; - int io_buffer_size; - uint8_t io_buffer[1]; -} DynBuffer; - -static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) -{ - DynBuffer *d = opaque; - unsigned new_size, new_allocated_size; - - /* reallocate buffer if needed */ - new_size = d->pos + buf_size; - new_allocated_size = d->allocated_size; - if(new_size < d->pos || new_size > INT_MAX/2) - return -1; - while (new_size > new_allocated_size) { - if (!new_allocated_size) - new_allocated_size = new_size; - else - new_allocated_size += new_allocated_size / 2 + 1; - } - - if (new_allocated_size > d->allocated_size) { - d->buffer = av_realloc(d->buffer, new_allocated_size); - if(d->buffer == NULL) - return AVERROR(ENOMEM); - d->allocated_size = new_allocated_size; - } - memcpy(d->buffer + d->pos, buf, buf_size); - d->pos = new_size; - if (d->pos > d->size) - d->size = d->pos; - return buf_size; -} - -static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size) -{ - unsigned char buf1[4]; - int ret; - - /* packetized write: output the header */ - AV_WB32(buf1, buf_size); - ret= dyn_buf_write(opaque, buf1, 4); - if(ret < 0) - return ret; - - /* then the data */ - return dyn_buf_write(opaque, buf, buf_size); -} - -static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) -{ - DynBuffer *d = opaque; - - if (whence == SEEK_CUR) - offset += d->pos; - else if (whence == SEEK_END) - offset += d->size; - if (offset < 0 || offset > 0x7fffffffLL) - return -1; - d->pos = offset; - return 0; -} - -static int url_open_dyn_buf_internal(ByteIOContext **s, int max_packet_size) -{ - DynBuffer *d; - int ret; - unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; - - if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size) - return -1; - d = av_mallocz(sizeof(DynBuffer) + io_buffer_size); - if (!d) - return AVERROR(ENOMEM); - *s = av_mallocz(sizeof(ByteIOContext)); - if(!*s) { - av_free(d); - return AVERROR(ENOMEM); - } - d->io_buffer_size = io_buffer_size; - ret = init_put_byte(*s, d->io_buffer, io_buffer_size, - 1, d, NULL, - max_packet_size ? dyn_packet_buf_write : dyn_buf_write, - max_packet_size ? NULL : dyn_buf_seek); - if (ret == 0) { - (*s)->max_packet_size = max_packet_size; - } else { - av_free(d); - av_freep(s); - } - return ret; -} - -int url_open_dyn_buf(ByteIOContext **s) -{ - return url_open_dyn_buf_internal(s, 0); -} - -int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size) -{ - if (max_packet_size <= 0) - return -1; - return url_open_dyn_buf_internal(s, max_packet_size); -} - -int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer) -{ - DynBuffer *d = s->opaque; - int size; - - put_flush_packet(s); - - *pbuffer = d->buffer; - size = d->size; - av_free(d); - av_free(s); - return size; -} -#endif /* CONFIG_MUXERS || CONFIG_NETWORK */ diff --git a/tizen/distrib/ffmpeg/libavformat/avisynth.c b/tizen/distrib/ffmpeg/libavformat/avisynth.c deleted file mode 100644 index e2a8a3c..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avisynth.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * AVISynth support for ffmpeg system - * Copyright (c) 2006 DivX, Inc. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "riff.h" - -#include -#include - -typedef struct { - PAVISTREAM handle; - AVISTREAMINFO info; - DWORD read; - LONG chunck_size; - LONG chunck_samples; -} AVISynthStream; - -typedef struct { - PAVIFILE file; - AVISynthStream *streams; - int nb_streams; - int next_stream; -} AVISynthContext; - -static int avisynth_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - AVISynthContext *avs = s->priv_data; - HRESULT res; - AVIFILEINFO info; - DWORD id; - AVStream *st; - AVISynthStream *stream; - - AVIFileInit(); - - res = AVIFileOpen(&avs->file, s->filename, OF_READ|OF_SHARE_DENY_WRITE, NULL); - if (res != S_OK) - { - av_log(s, AV_LOG_ERROR, "AVIFileOpen failed with error %ld", res); - AVIFileExit(); - return -1; - } - - res = AVIFileInfo(avs->file, &info, sizeof(info)); - if (res != S_OK) - { - av_log(s, AV_LOG_ERROR, "AVIFileInfo failed with error %ld", res); - AVIFileExit(); - return -1; - } - - avs->streams = av_mallocz(info.dwStreams * sizeof(AVISynthStream)); - - for (id=0; idstreams[id]; - stream->read = 0; - if (AVIFileGetStream(avs->file, &stream->handle, 0, id) == S_OK) - { - if (AVIStreamInfo(stream->handle, &stream->info, sizeof(stream->info)) == S_OK) - { - if (stream->info.fccType == streamtypeAUDIO) - { - WAVEFORMATEX wvfmt; - LONG struct_size = sizeof(WAVEFORMATEX); - if (AVIStreamReadFormat(stream->handle, 0, &wvfmt, &struct_size) != S_OK) - continue; - - st = av_new_stream(s, id); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - st->codec->block_align = wvfmt.nBlockAlign; - st->codec->channels = wvfmt.nChannels; - st->codec->sample_rate = wvfmt.nSamplesPerSec; - st->codec->bit_rate = wvfmt.nAvgBytesPerSec * 8; - st->codec->bits_per_coded_sample = wvfmt.wBitsPerSample; - - stream->chunck_samples = wvfmt.nSamplesPerSec * (uint64_t)info.dwScale / (uint64_t)info.dwRate; - stream->chunck_size = stream->chunck_samples * wvfmt.nChannels * wvfmt.wBitsPerSample / 8; - - st->codec->codec_tag = wvfmt.wFormatTag; - st->codec->codec_id = ff_wav_codec_get_id(wvfmt.wFormatTag, st->codec->bits_per_coded_sample); - } - else if (stream->info.fccType == streamtypeVIDEO) - { - BITMAPINFO imgfmt; - LONG struct_size = sizeof(BITMAPINFO); - - stream->chunck_size = stream->info.dwSampleSize; - stream->chunck_samples = 1; - - if (AVIStreamReadFormat(stream->handle, 0, &imgfmt, &struct_size) != S_OK) - continue; - - st = av_new_stream(s, id); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->r_frame_rate.num = stream->info.dwRate; - st->r_frame_rate.den = stream->info.dwScale; - - st->codec->width = imgfmt.bmiHeader.biWidth; - st->codec->height = imgfmt.bmiHeader.biHeight; - - st->codec->bits_per_coded_sample = imgfmt.bmiHeader.biBitCount; - st->codec->bit_rate = (uint64_t)stream->info.dwSampleSize * (uint64_t)stream->info.dwRate * 8 / (uint64_t)stream->info.dwScale; - st->codec->codec_tag = imgfmt.bmiHeader.biCompression; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, imgfmt.bmiHeader.biCompression); - - st->duration = stream->info.dwLength; - } - else - { - AVIStreamRelease(stream->handle); - continue; - } - - avs->nb_streams++; - - st->codec->stream_codec_tag = stream->info.fccHandler; - - av_set_pts_info(st, 64, info.dwScale, info.dwRate); - st->start_time = stream->info.dwStart; - } - } - } - - return 0; -} - -static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVISynthContext *avs = s->priv_data; - HRESULT res; - AVISynthStream *stream; - int stream_id = avs->next_stream; - LONG read_size; - - // handle interleaving manually... - stream = &avs->streams[stream_id]; - - if (stream->read >= stream->info.dwLength) - return AVERROR(EIO); - - if (av_new_packet(pkt, stream->chunck_size)) - return AVERROR(EIO); - pkt->stream_index = stream_id; - pkt->pts = avs->streams[stream_id].read / avs->streams[stream_id].chunck_samples; - - res = AVIStreamRead(stream->handle, stream->read, stream->chunck_samples, pkt->data, stream->chunck_size, &read_size, NULL); - - pkt->pts = stream->read; - pkt->size = read_size; - - stream->read += stream->chunck_samples; - - // prepare for the next stream to read - do { - avs->next_stream = (avs->next_stream+1) % avs->nb_streams; - } while (avs->next_stream != stream_id && s->streams[avs->next_stream]->discard >= AVDISCARD_ALL); - - return (res == S_OK) ? pkt->size : -1; -} - -static int avisynth_read_close(AVFormatContext *s) -{ - AVISynthContext *avs = s->priv_data; - int i; - - for (i=0;inb_streams;i++) - { - AVIStreamRelease(avs->streams[i].handle); - } - - av_free(avs->streams); - AVIFileRelease(avs->file); - AVIFileExit(); - return 0; -} - -static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags) -{ - AVISynthContext *avs = s->priv_data; - int stream_id; - - for (stream_id = 0; stream_id < avs->nb_streams; stream_id++) - { - avs->streams[stream_id].read = pts * avs->streams[stream_id].chunck_samples; - } - - return 0; -} - -AVInputFormat avisynth_demuxer = { - "avs", - NULL_IF_CONFIG_SMALL("AVISynth"), - sizeof(AVISynthContext), - NULL, - avisynth_read_header, - avisynth_read_packet, - avisynth_read_close, - avisynth_read_seek, - NULL, - 0, - "avs", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/avlanguage.c b/tizen/distrib/ffmpeg/libavformat/avlanguage.c deleted file mode 100644 index 525bf07..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avlanguage.c +++ /dev/null @@ -1,764 +0,0 @@ -/* - * Cyril Comparon, Larbi Joubala, Resonate-MP4 2009 - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avlanguage.h" -#include "libavutil/avstring.h" -#include -#include -#include - -typedef struct LangEntry { - const char str[4]; - uint16_t next_equivalent; -} LangEntry; - -static const uint16_t lang_table_counts[] = { 484, 20, 184 }; -static const uint16_t lang_table_offsets[] = { 0, 484, 504 }; - -static const LangEntry lang_table[] = { - /*----- AV_LANG_ISO639_2_BIBL entries (484) -----*/ - /*0000*/ { "aar", 504 }, - /*0001*/ { "abk", 505 }, - /*0002*/ { "ace", 2 }, - /*0003*/ { "ach", 3 }, - /*0004*/ { "ada", 4 }, - /*0005*/ { "ady", 5 }, - /*0006*/ { "afa", 6 }, - /*0007*/ { "afh", 7 }, - /*0008*/ { "afr", 507 }, - /*0009*/ { "ain", 9 }, - /*0010*/ { "aka", 508 }, - /*0011*/ { "akk", 11 }, - /*0012*/ { "alb", 502 }, - /*0013*/ { "ale", 13 }, - /*0014*/ { "alg", 14 }, - /*0015*/ { "alt", 15 }, - /*0016*/ { "amh", 509 }, - /*0017*/ { "ang", 17 }, - /*0018*/ { "anp", 18 }, - /*0019*/ { "apa", 19 }, - /*0020*/ { "ara", 511 }, - /*0021*/ { "arc", 21 }, - /*0022*/ { "arg", 510 }, - /*0023*/ { "arm", 492 }, - /*0024*/ { "arn", 24 }, - /*0025*/ { "arp", 25 }, - /*0026*/ { "art", 26 }, - /*0027*/ { "arw", 27 }, - /*0028*/ { "asm", 512 }, - /*0029*/ { "ast", 29 }, - /*0030*/ { "ath", 30 }, - /*0031*/ { "aus", 31 }, - /*0032*/ { "ava", 513 }, - /*0033*/ { "ave", 506 }, - /*0034*/ { "awa", 34 }, - /*0035*/ { "aym", 514 }, - /*0036*/ { "aze", 515 }, - /*0037*/ { "bad", 37 }, - /*0038*/ { "bai", 38 }, - /*0039*/ { "bak", 516 }, - /*0040*/ { "bal", 40 }, - /*0041*/ { "bam", 521 }, - /*0042*/ { "ban", 42 }, - /*0043*/ { "baq", 489 }, - /*0044*/ { "bas", 44 }, - /*0045*/ { "bat", 45 }, - /*0046*/ { "bej", 46 }, - /*0047*/ { "bel", 517 }, - /*0048*/ { "bem", 48 }, - /*0049*/ { "ben", 522 }, - /*0050*/ { "ber", 50 }, - /*0051*/ { "bho", 51 }, - /*0052*/ { "bih", 519 }, - /*0053*/ { "bik", 53 }, - /*0054*/ { "bin", 54 }, - /*0055*/ { "bis", 520 }, - /*0056*/ { "bla", 56 }, - /*0057*/ { "bnt", 57 }, - /*0058*/ { "bos", 525 }, - /*0059*/ { "bra", 59 }, - /*0060*/ { "bre", 524 }, - /*0061*/ { "btk", 61 }, - /*0062*/ { "bua", 62 }, - /*0063*/ { "bug", 63 }, - /*0064*/ { "bul", 518 }, - /*0065*/ { "bur", 498 }, - /*0066*/ { "byn", 66 }, - /*0067*/ { "cad", 67 }, - /*0068*/ { "cai", 68 }, - /*0069*/ { "car", 69 }, - /*0070*/ { "cat", 526 }, - /*0071*/ { "cau", 71 }, - /*0072*/ { "ceb", 72 }, - /*0073*/ { "cel", 73 }, - /*0074*/ { "cha", 528 }, - /*0075*/ { "chb", 75 }, - /*0076*/ { "che", 527 }, - /*0077*/ { "chg", 77 }, - /*0078*/ { "chi", 503 }, - /*0079*/ { "chk", 79 }, - /*0080*/ { "chm", 80 }, - /*0081*/ { "chn", 81 }, - /*0082*/ { "cho", 82 }, - /*0083*/ { "chp", 83 }, - /*0084*/ { "chr", 84 }, - /*0085*/ { "chu", 532 }, - /*0086*/ { "chv", 533 }, - /*0087*/ { "chy", 87 }, - /*0088*/ { "cmc", 88 }, - /*0089*/ { "cop", 89 }, - /*0090*/ { "cor", 593 }, - /*0091*/ { "cos", 529 }, - /*0092*/ { "cpe", 92 }, - /*0093*/ { "cpf", 93 }, - /*0094*/ { "cpp", 94 }, - /*0095*/ { "cre", 530 }, - /*0096*/ { "crh", 96 }, - /*0097*/ { "crp", 97 }, - /*0098*/ { "csb", 98 }, - /*0099*/ { "cus", 99 }, - /*0100*/ { "cze", 485 }, - /*0101*/ { "dak", 101 }, - /*0102*/ { "dan", 535 }, - /*0103*/ { "dar", 103 }, - /*0104*/ { "day", 104 }, - /*0105*/ { "del", 105 }, - /*0106*/ { "den", 106 }, - /*0107*/ { "dgr", 107 }, - /*0108*/ { "din", 108 }, - /*0109*/ { "div", 537 }, - /*0110*/ { "doi", 110 }, - /*0111*/ { "dra", 111 }, - /*0112*/ { "dsb", 112 }, - /*0113*/ { "dua", 113 }, - /*0114*/ { "dum", 114 }, - /*0115*/ { "dut", 499 }, - /*0116*/ { "dyu", 116 }, - /*0117*/ { "dzo", 538 }, - /*0118*/ { "efi", 118 }, - /*0119*/ { "egy", 119 }, - /*0120*/ { "eka", 120 }, - /*0121*/ { "elx", 121 }, - /*0122*/ { "eng", 541 }, - /*0123*/ { "enm", 123 }, - /*0124*/ { "epo", 542 }, - /*0125*/ { "est", 544 }, - /*0126*/ { "ewe", 539 }, - /*0127*/ { "ewo", 127 }, - /*0128*/ { "fan", 128 }, - /*0129*/ { "fao", 550 }, - /*0130*/ { "fat", 130 }, - /*0131*/ { "fij", 549 }, - /*0132*/ { "fil", 132 }, - /*0133*/ { "fin", 548 }, - /*0134*/ { "fiu", 134 }, - /*0135*/ { "fon", 135 }, - /*0136*/ { "fre", 491 }, - /*0137*/ { "frm", 137 }, - /*0138*/ { "fro", 138 }, - /*0139*/ { "frr", 139 }, - /*0140*/ { "frs", 140 }, - /*0141*/ { "fry", 552 }, - /*0142*/ { "ful", 547 }, - /*0143*/ { "fur", 143 }, - /*0144*/ { "gaa", 144 }, - /*0145*/ { "gay", 145 }, - /*0146*/ { "gba", 146 }, - /*0147*/ { "gem", 147 }, - /*0148*/ { "geo", 494 }, - /*0149*/ { "ger", 487 }, - /*0150*/ { "gez", 150 }, - /*0151*/ { "gil", 151 }, - /*0152*/ { "gla", 554 }, - /*0153*/ { "gle", 553 }, - /*0154*/ { "glg", 555 }, - /*0155*/ { "glv", 558 }, - /*0156*/ { "gmh", 156 }, - /*0157*/ { "goh", 157 }, - /*0158*/ { "gon", 158 }, - /*0159*/ { "gor", 159 }, - /*0160*/ { "got", 160 }, - /*0161*/ { "grb", 161 }, - /*0162*/ { "grc", 162 }, - /*0163*/ { "gre", 488 }, - /*0164*/ { "grn", 556 }, - /*0165*/ { "gsw", 165 }, - /*0166*/ { "guj", 557 }, - /*0167*/ { "gwi", 167 }, - /*0168*/ { "hai", 168 }, - /*0169*/ { "hat", 564 }, - /*0170*/ { "hau", 559 }, - /*0171*/ { "haw", 171 }, - /*0172*/ { "heb", 560 }, - /*0173*/ { "her", 567 }, - /*0174*/ { "hil", 174 }, - /*0175*/ { "him", 175 }, - /*0176*/ { "hin", 561 }, - /*0177*/ { "hit", 177 }, - /*0178*/ { "hmn", 178 }, - /*0179*/ { "hmo", 562 }, - /*0180*/ { "hrv", 563 }, - /*0181*/ { "hsb", 181 }, - /*0182*/ { "hun", 565 }, - /*0183*/ { "hup", 183 }, - /*0184*/ { "iba", 184 }, - /*0185*/ { "ibo", 571 }, - /*0186*/ { "ice", 493 }, - /*0187*/ { "ido", 574 }, - /*0188*/ { "iii", 572 }, - /*0189*/ { "ijo", 189 }, - /*0190*/ { "iku", 577 }, - /*0191*/ { "ile", 570 }, - /*0192*/ { "ilo", 192 }, - /*0193*/ { "ina", 568 }, - /*0194*/ { "inc", 194 }, - /*0195*/ { "ind", 569 }, - /*0196*/ { "ine", 196 }, - /*0197*/ { "inh", 197 }, - /*0198*/ { "ipk", 573 }, - /*0199*/ { "ira", 199 }, - /*0200*/ { "iro", 200 }, - /*0201*/ { "ita", 576 }, - /*0202*/ { "jav", 579 }, - /*0203*/ { "jbo", 203 }, - /*0204*/ { "jpn", 578 }, - /*0205*/ { "jpr", 205 }, - /*0206*/ { "jrb", 206 }, - /*0207*/ { "kaa", 207 }, - /*0208*/ { "kab", 208 }, - /*0209*/ { "kac", 209 }, - /*0210*/ { "kal", 585 }, - /*0211*/ { "kam", 211 }, - /*0212*/ { "kan", 587 }, - /*0213*/ { "kar", 213 }, - /*0214*/ { "kas", 590 }, - /*0215*/ { "kau", 589 }, - /*0216*/ { "kaw", 216 }, - /*0217*/ { "kaz", 584 }, - /*0218*/ { "kbd", 218 }, - /*0219*/ { "kha", 219 }, - /*0220*/ { "khi", 220 }, - /*0221*/ { "khm", 586 }, - /*0222*/ { "kho", 222 }, - /*0223*/ { "kik", 582 }, - /*0224*/ { "kin", 640 }, - /*0225*/ { "kir", 594 }, - /*0226*/ { "kmb", 226 }, - /*0227*/ { "kok", 227 }, - /*0228*/ { "kom", 592 }, - /*0229*/ { "kon", 581 }, - /*0230*/ { "kor", 588 }, - /*0231*/ { "kos", 231 }, - /*0232*/ { "kpe", 232 }, - /*0233*/ { "krc", 233 }, - /*0234*/ { "krl", 234 }, - /*0235*/ { "kro", 235 }, - /*0236*/ { "kru", 236 }, - /*0237*/ { "kua", 583 }, - /*0238*/ { "kum", 238 }, - /*0239*/ { "kur", 591 }, - /*0240*/ { "kut", 240 }, - /*0241*/ { "lad", 241 }, - /*0242*/ { "lah", 242 }, - /*0243*/ { "lam", 243 }, - /*0244*/ { "lao", 600 }, - /*0245*/ { "lat", 595 }, - /*0246*/ { "lav", 603 }, - /*0247*/ { "lez", 247 }, - /*0248*/ { "lim", 598 }, - /*0249*/ { "lin", 599 }, - /*0250*/ { "lit", 601 }, - /*0251*/ { "lol", 251 }, - /*0252*/ { "loz", 252 }, - /*0253*/ { "ltz", 596 }, - /*0254*/ { "lua", 254 }, - /*0255*/ { "lub", 602 }, - /*0256*/ { "lug", 597 }, - /*0257*/ { "lui", 257 }, - /*0258*/ { "lun", 258 }, - /*0259*/ { "luo", 259 }, - /*0260*/ { "lus", 260 }, - /*0261*/ { "mac", 495 }, - /*0262*/ { "mad", 262 }, - /*0263*/ { "mag", 263 }, - /*0264*/ { "mah", 605 }, - /*0265*/ { "mai", 265 }, - /*0266*/ { "mak", 266 }, - /*0267*/ { "mal", 608 }, - /*0268*/ { "man", 268 }, - /*0269*/ { "mao", 496 }, - /*0270*/ { "map", 270 }, - /*0271*/ { "mar", 610 }, - /*0272*/ { "mas", 272 }, - /*0273*/ { "may", 497 }, - /*0274*/ { "mdf", 274 }, - /*0275*/ { "mdr", 275 }, - /*0276*/ { "men", 276 }, - /*0277*/ { "mga", 277 }, - /*0278*/ { "mic", 278 }, - /*0279*/ { "min", 279 }, - /*0280*/ { "mis", 280 }, - /*0281*/ { "mkh", 281 }, - /*0282*/ { "mlg", 604 }, - /*0283*/ { "mlt", 612 }, - /*0284*/ { "mnc", 284 }, - /*0285*/ { "mni", 285 }, - /*0286*/ { "mno", 286 }, - /*0287*/ { "moh", 287 }, - /*0288*/ { "mon", 609 }, - /*0289*/ { "mos", 289 }, - /*0290*/ { "mul", 290 }, - /*0291*/ { "mun", 291 }, - /*0292*/ { "mus", 292 }, - /*0293*/ { "mwl", 293 }, - /*0294*/ { "mwr", 294 }, - /*0295*/ { "myn", 295 }, - /*0296*/ { "myv", 296 }, - /*0297*/ { "nah", 297 }, - /*0298*/ { "nai", 298 }, - /*0299*/ { "nap", 299 }, - /*0300*/ { "nau", 614 }, - /*0301*/ { "nav", 623 }, - /*0302*/ { "nbl", 622 }, - /*0303*/ { "nde", 616 }, - /*0304*/ { "ndo", 618 }, - /*0305*/ { "nds", 305 }, - /*0306*/ { "nep", 617 }, - /*0307*/ { "new", 307 }, - /*0308*/ { "nia", 308 }, - /*0309*/ { "nic", 309 }, - /*0310*/ { "niu", 310 }, - /*0311*/ { "nno", 620 }, - /*0312*/ { "nob", 615 }, - /*0313*/ { "nog", 313 }, - /*0314*/ { "non", 314 }, - /*0315*/ { "nor", 621 }, - /*0316*/ { "nqo", 316 }, - /*0317*/ { "nso", 317 }, - /*0318*/ { "nub", 318 }, - /*0319*/ { "nwc", 319 }, - /*0320*/ { "nya", 624 }, - /*0321*/ { "nym", 321 }, - /*0322*/ { "nyn", 322 }, - /*0323*/ { "nyo", 323 }, - /*0324*/ { "nzi", 324 }, - /*0325*/ { "oci", 625 }, - /*0326*/ { "oji", 626 }, - /*0327*/ { "ori", 628 }, - /*0328*/ { "orm", 627 }, - /*0329*/ { "osa", 329 }, - /*0330*/ { "oss", 629 }, - /*0331*/ { "ota", 331 }, - /*0332*/ { "oto", 332 }, - /*0333*/ { "paa", 333 }, - /*0334*/ { "pag", 334 }, - /*0335*/ { "pal", 335 }, - /*0336*/ { "pam", 336 }, - /*0337*/ { "pan", 630 }, - /*0338*/ { "pap", 338 }, - /*0339*/ { "pau", 339 }, - /*0340*/ { "peo", 340 }, - /*0341*/ { "per", 490 }, - /*0342*/ { "phi", 342 }, - /*0343*/ { "phn", 343 }, - /*0344*/ { "pli", 631 }, - /*0345*/ { "pol", 632 }, - /*0346*/ { "pon", 346 }, - /*0347*/ { "por", 634 }, - /*0348*/ { "pra", 348 }, - /*0349*/ { "pro", 349 }, - /*0350*/ { "pus", 633 }, - /*0351*/ { "que", 635 }, - /*0352*/ { "raj", 352 }, - /*0353*/ { "rap", 353 }, - /*0354*/ { "rar", 354 }, - /*0355*/ { "roa", 355 }, - /*0356*/ { "roh", 636 }, - /*0357*/ { "rom", 357 }, - /*0358*/ { "rum", 500 }, - /*0359*/ { "run", 637 }, - /*0360*/ { "rup", 360 }, - /*0361*/ { "rus", 639 }, - /*0362*/ { "sad", 362 }, - /*0363*/ { "sag", 645 }, - /*0364*/ { "sah", 364 }, - /*0365*/ { "sai", 365 }, - /*0366*/ { "sal", 366 }, - /*0367*/ { "sam", 367 }, - /*0368*/ { "san", 641 }, - /*0369*/ { "sas", 369 }, - /*0370*/ { "sat", 370 }, - /*0371*/ { "scn", 371 }, - /*0372*/ { "sco", 372 }, - /*0373*/ { "sel", 373 }, - /*0374*/ { "sem", 374 }, - /*0375*/ { "sga", 375 }, - /*0376*/ { "sgn", 376 }, - /*0377*/ { "shn", 377 }, - /*0378*/ { "sid", 378 }, - /*0379*/ { "sin", 646 }, - /*0380*/ { "sio", 380 }, - /*0381*/ { "sit", 381 }, - /*0382*/ { "sla", 382 }, - /*0383*/ { "slo", 501 }, - /*0384*/ { "slv", 648 }, - /*0385*/ { "sma", 385 }, - /*0386*/ { "sme", 644 }, - /*0387*/ { "smi", 387 }, - /*0388*/ { "smj", 388 }, - /*0389*/ { "smn", 389 }, - /*0390*/ { "smo", 649 }, - /*0391*/ { "sms", 391 }, - /*0392*/ { "sna", 650 }, - /*0393*/ { "snd", 643 }, - /*0394*/ { "snk", 394 }, - /*0395*/ { "sog", 395 }, - /*0396*/ { "som", 651 }, - /*0397*/ { "son", 397 }, - /*0398*/ { "sot", 655 }, - /*0399*/ { "spa", 543 }, - /*0400*/ { "srd", 642 }, - /*0401*/ { "srn", 401 }, - /*0402*/ { "srp", 653 }, - /*0403*/ { "srr", 403 }, - /*0404*/ { "ssa", 404 }, - /*0405*/ { "ssw", 654 }, - /*0406*/ { "suk", 406 }, - /*0407*/ { "sun", 656 }, - /*0408*/ { "sus", 408 }, - /*0409*/ { "sux", 409 }, - /*0410*/ { "swa", 658 }, - /*0411*/ { "swe", 657 }, - /*0412*/ { "syc", 412 }, - /*0413*/ { "syr", 413 }, - /*0414*/ { "tah", 672 }, - /*0415*/ { "tai", 415 }, - /*0416*/ { "tam", 659 }, - /*0417*/ { "tat", 670 }, - /*0418*/ { "tel", 660 }, - /*0419*/ { "tem", 419 }, - /*0420*/ { "ter", 420 }, - /*0421*/ { "tet", 421 }, - /*0422*/ { "tgk", 661 }, - /*0423*/ { "tgl", 665 }, - /*0424*/ { "tha", 662 }, - /*0425*/ { "tib", 484 }, - /*0426*/ { "tig", 426 }, - /*0427*/ { "tir", 663 }, - /*0428*/ { "tiv", 428 }, - /*0429*/ { "tkl", 429 }, - /*0430*/ { "tlh", 430 }, - /*0431*/ { "tli", 431 }, - /*0432*/ { "tmh", 432 }, - /*0433*/ { "tog", 433 }, - /*0434*/ { "ton", 667 }, - /*0435*/ { "tpi", 435 }, - /*0436*/ { "tsi", 436 }, - /*0437*/ { "tsn", 666 }, - /*0438*/ { "tso", 669 }, - /*0439*/ { "tuk", 664 }, - /*0440*/ { "tum", 440 }, - /*0441*/ { "tup", 441 }, - /*0442*/ { "tur", 668 }, - /*0443*/ { "tut", 443 }, - /*0444*/ { "tvl", 444 }, - /*0445*/ { "twi", 671 }, - /*0446*/ { "tyv", 446 }, - /*0447*/ { "udm", 447 }, - /*0448*/ { "uga", 448 }, - /*0449*/ { "uig", 673 }, - /*0450*/ { "ukr", 674 }, - /*0451*/ { "umb", 451 }, - /*0452*/ { "und", 452 }, - /*0453*/ { "urd", 675 }, - /*0454*/ { "uzb", 676 }, - /*0455*/ { "vai", 455 }, - /*0456*/ { "ven", 677 }, - /*0457*/ { "vie", 678 }, - /*0458*/ { "vol", 679 }, - /*0459*/ { "vot", 459 }, - /*0460*/ { "wak", 460 }, - /*0461*/ { "wal", 461 }, - /*0462*/ { "war", 462 }, - /*0463*/ { "was", 463 }, - /*0464*/ { "wel", 486 }, - /*0465*/ { "wen", 465 }, - /*0466*/ { "wln", 680 }, - /*0467*/ { "wol", 681 }, - /*0468*/ { "xal", 468 }, - /*0469*/ { "xho", 682 }, - /*0470*/ { "yao", 470 }, - /*0471*/ { "yap", 471 }, - /*0472*/ { "yid", 683 }, - /*0473*/ { "yor", 684 }, - /*0474*/ { "ypk", 474 }, - /*0475*/ { "zap", 475 }, - /*0476*/ { "zbl", 476 }, - /*0477*/ { "zen", 477 }, - /*0478*/ { "zha", 685 }, - /*0479*/ { "znd", 479 }, - /*0480*/ { "zul", 687 }, - /*0481*/ { "zun", 481 }, - /*0482*/ { "zxx", 482 }, - /*0483*/ { "zza", 483 }, - /*----- AV_LANG_ISO639_2_TERM entries (20) -----*/ - /*0484*/ { "bod", 523 }, - /*0485*/ { "ces", 531 }, - /*0486*/ { "cym", 534 }, - /*0487*/ { "deu", 536 }, - /*0488*/ { "ell", 540 }, - /*0489*/ { "eus", 545 }, - /*0490*/ { "fas", 546 }, - /*0491*/ { "fra", 551 }, - /*0492*/ { "hye", 566 }, - /*0493*/ { "isl", 575 }, - /*0494*/ { "kat", 580 }, - /*0495*/ { "mkd", 607 }, - /*0496*/ { "mri", 606 }, - /*0497*/ { "msa", 611 }, - /*0498*/ { "mya", 613 }, - /*0499*/ { "nld", 619 }, - /*0500*/ { "ron", 638 }, - /*0501*/ { "slk", 647 }, - /*0502*/ { "sqi", 652 }, - /*0503*/ { "zho", 686 }, - /*----- AV_LANG_ISO639_1 entries (184) -----*/ - /*0504*/ { "aa" , 0 }, - /*0505*/ { "ab" , 1 }, - /*0506*/ { "ae" , 33 }, - /*0507*/ { "af" , 8 }, - /*0508*/ { "ak" , 10 }, - /*0509*/ { "am" , 16 }, - /*0510*/ { "an" , 22 }, - /*0511*/ { "ar" , 20 }, - /*0512*/ { "as" , 28 }, - /*0513*/ { "av" , 32 }, - /*0514*/ { "ay" , 35 }, - /*0515*/ { "az" , 36 }, - /*0516*/ { "ba" , 39 }, - /*0517*/ { "be" , 47 }, - /*0518*/ { "bg" , 64 }, - /*0519*/ { "bh" , 52 }, - /*0520*/ { "bi" , 55 }, - /*0521*/ { "bm" , 41 }, - /*0522*/ { "bn" , 49 }, - /*0523*/ { "bo" , 425 }, - /*0524*/ { "br" , 60 }, - /*0525*/ { "bs" , 58 }, - /*0526*/ { "ca" , 70 }, - /*0527*/ { "ce" , 76 }, - /*0528*/ { "ch" , 74 }, - /*0529*/ { "co" , 91 }, - /*0530*/ { "cr" , 95 }, - /*0531*/ { "cs" , 100 }, - /*0532*/ { "cu" , 85 }, - /*0533*/ { "cv" , 86 }, - /*0534*/ { "cy" , 464 }, - /*0535*/ { "da" , 102 }, - /*0536*/ { "de" , 149 }, - /*0537*/ { "dv" , 109 }, - /*0538*/ { "dz" , 117 }, - /*0539*/ { "ee" , 126 }, - /*0540*/ { "el" , 163 }, - /*0541*/ { "en" , 122 }, - /*0542*/ { "eo" , 124 }, - /*0543*/ { "es" , 399 }, - /*0544*/ { "et" , 125 }, - /*0545*/ { "eu" , 43 }, - /*0546*/ { "fa" , 341 }, - /*0547*/ { "ff" , 142 }, - /*0548*/ { "fi" , 133 }, - /*0549*/ { "fj" , 131 }, - /*0550*/ { "fo" , 129 }, - /*0551*/ { "fr" , 136 }, - /*0552*/ { "fy" , 141 }, - /*0553*/ { "ga" , 153 }, - /*0554*/ { "gd" , 152 }, - /*0555*/ { "gl" , 154 }, - /*0556*/ { "gn" , 164 }, - /*0557*/ { "gu" , 166 }, - /*0558*/ { "gv" , 155 }, - /*0559*/ { "ha" , 170 }, - /*0560*/ { "he" , 172 }, - /*0561*/ { "hi" , 176 }, - /*0562*/ { "ho" , 179 }, - /*0563*/ { "hr" , 180 }, - /*0564*/ { "ht" , 169 }, - /*0565*/ { "hu" , 182 }, - /*0566*/ { "hy" , 23 }, - /*0567*/ { "hz" , 173 }, - /*0568*/ { "ia" , 193 }, - /*0569*/ { "id" , 195 }, - /*0570*/ { "ie" , 191 }, - /*0571*/ { "ig" , 185 }, - /*0572*/ { "ii" , 188 }, - /*0573*/ { "ik" , 198 }, - /*0574*/ { "io" , 187 }, - /*0575*/ { "is" , 186 }, - /*0576*/ { "it" , 201 }, - /*0577*/ { "iu" , 190 }, - /*0578*/ { "ja" , 204 }, - /*0579*/ { "jv" , 202 }, - /*0580*/ { "ka" , 148 }, - /*0581*/ { "kg" , 229 }, - /*0582*/ { "ki" , 223 }, - /*0583*/ { "kj" , 237 }, - /*0584*/ { "kk" , 217 }, - /*0585*/ { "kl" , 210 }, - /*0586*/ { "km" , 221 }, - /*0587*/ { "kn" , 212 }, - /*0588*/ { "ko" , 230 }, - /*0589*/ { "kr" , 215 }, - /*0590*/ { "ks" , 214 }, - /*0591*/ { "ku" , 239 }, - /*0592*/ { "kv" , 228 }, - /*0593*/ { "kw" , 90 }, - /*0594*/ { "ky" , 225 }, - /*0595*/ { "la" , 245 }, - /*0596*/ { "lb" , 253 }, - /*0597*/ { "lg" , 256 }, - /*0598*/ { "li" , 248 }, - /*0599*/ { "ln" , 249 }, - /*0600*/ { "lo" , 244 }, - /*0601*/ { "lt" , 250 }, - /*0602*/ { "lu" , 255 }, - /*0603*/ { "lv" , 246 }, - /*0604*/ { "mg" , 282 }, - /*0605*/ { "mh" , 264 }, - /*0606*/ { "mi" , 269 }, - /*0607*/ { "mk" , 261 }, - /*0608*/ { "ml" , 267 }, - /*0609*/ { "mn" , 288 }, - /*0610*/ { "mr" , 271 }, - /*0611*/ { "ms" , 273 }, - /*0612*/ { "mt" , 283 }, - /*0613*/ { "my" , 65 }, - /*0614*/ { "na" , 300 }, - /*0615*/ { "nb" , 312 }, - /*0616*/ { "nd" , 303 }, - /*0617*/ { "ne" , 306 }, - /*0618*/ { "ng" , 304 }, - /*0619*/ { "nl" , 115 }, - /*0620*/ { "nn" , 311 }, - /*0621*/ { "no" , 315 }, - /*0622*/ { "nr" , 302 }, - /*0623*/ { "nv" , 301 }, - /*0624*/ { "ny" , 320 }, - /*0625*/ { "oc" , 325 }, - /*0626*/ { "oj" , 326 }, - /*0627*/ { "om" , 328 }, - /*0628*/ { "or" , 327 }, - /*0629*/ { "os" , 330 }, - /*0630*/ { "pa" , 337 }, - /*0631*/ { "pi" , 344 }, - /*0632*/ { "pl" , 345 }, - /*0633*/ { "ps" , 350 }, - /*0634*/ { "pt" , 347 }, - /*0635*/ { "qu" , 351 }, - /*0636*/ { "rm" , 356 }, - /*0637*/ { "rn" , 359 }, - /*0638*/ { "ro" , 358 }, - /*0639*/ { "ru" , 361 }, - /*0640*/ { "rw" , 224 }, - /*0641*/ { "sa" , 368 }, - /*0642*/ { "sc" , 400 }, - /*0643*/ { "sd" , 393 }, - /*0644*/ { "se" , 386 }, - /*0645*/ { "sg" , 363 }, - /*0646*/ { "si" , 379 }, - /*0647*/ { "sk" , 383 }, - /*0648*/ { "sl" , 384 }, - /*0649*/ { "sm" , 390 }, - /*0650*/ { "sn" , 392 }, - /*0651*/ { "so" , 396 }, - /*0652*/ { "sq" , 12 }, - /*0653*/ { "sr" , 402 }, - /*0654*/ { "ss" , 405 }, - /*0655*/ { "st" , 398 }, - /*0656*/ { "su" , 407 }, - /*0657*/ { "sv" , 411 }, - /*0658*/ { "sw" , 410 }, - /*0659*/ { "ta" , 416 }, - /*0660*/ { "te" , 418 }, - /*0661*/ { "tg" , 422 }, - /*0662*/ { "th" , 424 }, - /*0663*/ { "ti" , 427 }, - /*0664*/ { "tk" , 439 }, - /*0665*/ { "tl" , 423 }, - /*0666*/ { "tn" , 437 }, - /*0667*/ { "to" , 434 }, - /*0668*/ { "tr" , 442 }, - /*0669*/ { "ts" , 438 }, - /*0670*/ { "tt" , 417 }, - /*0671*/ { "tw" , 445 }, - /*0672*/ { "ty" , 414 }, - /*0673*/ { "ug" , 449 }, - /*0674*/ { "uk" , 450 }, - /*0675*/ { "ur" , 453 }, - /*0676*/ { "uz" , 454 }, - /*0677*/ { "ve" , 456 }, - /*0678*/ { "vi" , 457 }, - /*0679*/ { "vo" , 458 }, - /*0680*/ { "wa" , 466 }, - /*0681*/ { "wo" , 467 }, - /*0682*/ { "xh" , 469 }, - /*0683*/ { "yi" , 472 }, - /*0684*/ { "yo" , 473 }, - /*0685*/ { "za" , 478 }, - /*0686*/ { "zh" , 78 }, - /*0687*/ { "zu" , 480 }, - { "", 0 } -}; - -static int lang_table_compare(const void *lhs, const void *rhs) -{ - return strcmp(lhs, ((const LangEntry *)rhs)->str); -} - -const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace) -{ - int i; - const LangEntry *entry = NULL; - const int NB_CODESPACES = sizeof(lang_table_counts)/sizeof(*lang_table_counts); - - if (target_codespace >= NB_CODESPACES) - return NULL; - - for (i=0; !entry && i= lang_table + lang_table_offsets[target_codespace] && - entry < lang_table + lang_table_offsets[target_codespace] + lang_table_counts[target_codespace]) - return entry->str; - else - entry = lang_table + entry->next_equivalent; - - if (target_codespace == AV_LANG_ISO639_2_TERM) - return av_convert_lang_to(lang, AV_LANG_ISO639_2_BIBL); - - return NULL; -} diff --git a/tizen/distrib/ffmpeg/libavformat/avlanguage.h b/tizen/distrib/ffmpeg/libavformat/avlanguage.h deleted file mode 100644 index eac0031..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avlanguage.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cyril Comparon, Larbi Joubala, Resonate-MP4 2009 - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_AVLANGUAGE_H -#define AVFORMAT_AVLANGUAGE_H - -/** - * Known language codespaces - */ -enum AVLangCodespace { - AV_LANG_ISO639_2_BIBL, /** 3-char bibliographic language codes as per ISO-IEC 639-2 */ - AV_LANG_ISO639_2_TERM, /** 3-char terminologic language codes as per ISO-IEC 639-2 */ - AV_LANG_ISO639_1 /** 2-char code of language as per ISO/IEC 639-1 */ -}; - -/** - * Converts a language code to a target codespace. The source codespace is guessed. - * Returns NULL if the provided lang is null or invalid. - */ -const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace); - -#endif /* AVFORMAT_AVLANGUAGE_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/avs.c b/tizen/distrib/ffmpeg/libavformat/avs.c deleted file mode 100644 index caf3a89..0000000 --- a/tizen/distrib/ffmpeg/libavformat/avs.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * AVS demuxer. - * Copyright (c) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "voc.h" - - -typedef struct avs_format { - VocDecContext voc; - AVStream *st_video; - AVStream *st_audio; - int width; - int height; - int bits_per_sample; - int fps; - int nb_frames; - int remaining_frame_size; - int remaining_audio_size; -} AvsFormat; - -typedef enum avs_block_type { - AVS_NONE = 0x00, - AVS_VIDEO = 0x01, - AVS_AUDIO = 0x02, - AVS_PALETTE = 0x03, - AVS_GAME_DATA = 0x04, -} AvsBlockType; - -static int avs_probe(AVProbeData * p) -{ - const uint8_t *d; - - d = p->buf; - if (d[0] == 'w' && d[1] == 'W' && d[2] == 0x10 && d[3] == 0) - return 50; - - return 0; -} - -static int avs_read_header(AVFormatContext * s, AVFormatParameters * ap) -{ - AvsFormat *avs = s->priv_data; - - s->ctx_flags |= AVFMTCTX_NOHEADER; - - url_fskip(s->pb, 4); - avs->width = get_le16(s->pb); - avs->height = get_le16(s->pb); - avs->bits_per_sample = get_le16(s->pb); - avs->fps = get_le16(s->pb); - avs->nb_frames = get_le32(s->pb); - avs->remaining_frame_size = 0; - avs->remaining_audio_size = 0; - - avs->st_video = avs->st_audio = NULL; - - if (avs->width != 318 || avs->height != 198) - av_log(s, AV_LOG_ERROR, "This avs pretend to be %dx%d " - "when the avs format is supposed to be 318x198 only.\n", - avs->width, avs->height); - - return 0; -} - -static int -avs_read_video_packet(AVFormatContext * s, AVPacket * pkt, - AvsBlockType type, int sub_type, int size, - uint8_t * palette, int palette_size) -{ - AvsFormat *avs = s->priv_data; - int ret; - - ret = av_new_packet(pkt, size + palette_size); - if (ret < 0) - return ret; - - if (palette_size) { - pkt->data[0] = 0x00; - pkt->data[1] = 0x03; - pkt->data[2] = palette_size & 0xFF; - pkt->data[3] = (palette_size >> 8) & 0xFF; - memcpy(pkt->data + 4, palette, palette_size - 4); - } - - pkt->data[palette_size + 0] = sub_type; - pkt->data[palette_size + 1] = type; - pkt->data[palette_size + 2] = size & 0xFF; - pkt->data[palette_size + 3] = (size >> 8) & 0xFF; - ret = get_buffer(s->pb, pkt->data + palette_size + 4, size - 4) + 4; - if (ret < size) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - pkt->size = ret + palette_size; - pkt->stream_index = avs->st_video->index; - if (sub_type == 0) - pkt->flags |= AV_PKT_FLAG_KEY; - - return 0; -} - -static int avs_read_audio_packet(AVFormatContext * s, AVPacket * pkt) -{ - AvsFormat *avs = s->priv_data; - int ret, size; - - size = url_ftell(s->pb); - ret = voc_get_packet(s, pkt, avs->st_audio, avs->remaining_audio_size); - size = url_ftell(s->pb) - size; - avs->remaining_audio_size -= size; - - if (ret == AVERROR(EIO)) - return 0; /* this indicate EOS */ - if (ret < 0) - return ret; - - pkt->stream_index = avs->st_audio->index; - pkt->flags |= AV_PKT_FLAG_KEY; - - return size; -} - -static int avs_read_packet(AVFormatContext * s, AVPacket * pkt) -{ - AvsFormat *avs = s->priv_data; - int sub_type = 0, size = 0; - AvsBlockType type = AVS_NONE; - int palette_size = 0; - uint8_t palette[4 + 3 * 256]; - int ret; - - if (avs->remaining_audio_size > 0) - if (avs_read_audio_packet(s, pkt) > 0) - return 0; - - while (1) { - if (avs->remaining_frame_size <= 0) { - if (!get_le16(s->pb)) /* found EOF */ - return AVERROR(EIO); - avs->remaining_frame_size = get_le16(s->pb) - 4; - } - - while (avs->remaining_frame_size > 0) { - sub_type = get_byte(s->pb); - type = get_byte(s->pb); - size = get_le16(s->pb); - avs->remaining_frame_size -= size; - - switch (type) { - case AVS_PALETTE: - ret = get_buffer(s->pb, palette, size - 4); - if (ret < size - 4) - return AVERROR(EIO); - palette_size = size; - break; - - case AVS_VIDEO: - if (!avs->st_video) { - avs->st_video = av_new_stream(s, AVS_VIDEO); - if (avs->st_video == NULL) - return AVERROR(ENOMEM); - avs->st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO; - avs->st_video->codec->codec_id = CODEC_ID_AVS; - avs->st_video->codec->width = avs->width; - avs->st_video->codec->height = avs->height; - avs->st_video->codec->bits_per_coded_sample=avs->bits_per_sample; - avs->st_video->nb_frames = avs->nb_frames; - avs->st_video->codec->time_base = (AVRational) { - 1, avs->fps}; - } - return avs_read_video_packet(s, pkt, type, sub_type, size, - palette, palette_size); - - case AVS_AUDIO: - if (!avs->st_audio) { - avs->st_audio = av_new_stream(s, AVS_AUDIO); - if (avs->st_audio == NULL) - return AVERROR(ENOMEM); - avs->st_audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } - avs->remaining_audio_size = size - 4; - size = avs_read_audio_packet(s, pkt); - if (size != 0) - return size; - break; - - default: - url_fskip(s->pb, size - 4); - } - } - } -} - -static int avs_read_close(AVFormatContext * s) -{ - return 0; -} - -AVInputFormat avs_demuxer = { - "avs", - NULL_IF_CONFIG_SMALL("AVS format"), - sizeof(AvsFormat), - avs_probe, - avs_read_header, - avs_read_packet, - avs_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/bethsoftvid.c b/tizen/distrib/ffmpeg/libavformat/bethsoftvid.c deleted file mode 100644 index 4f9d1c1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/bethsoftvid.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Bethsoft VID format Demuxer - * Copyright (c) 2007 Nicholas Tung - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Bethesda Softworks VID (.vid) file demuxer - * @author Nicholas Tung [ntung (at. ntung com] (2007-03) - * @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID - * @sa http://www.svatopluk.com/andux/docs/dfvid.html - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "libavcodec/bethsoftvideo.h" - -typedef struct BVID_DemuxContext -{ - int nframes; - /** delay value between frames, added to individual frame delay. - * custom units, which will be added to other custom units (~=16ms according - * to free, unofficial documentation) */ - int bethsoft_global_delay; - - /** video presentation time stamp. - * delay = 16 milliseconds * (global_delay + per_frame_delay) */ - int video_pts; - - int is_finished; - -} BVID_DemuxContext; - -static int vid_probe(AVProbeData *p) -{ - // little endian VID tag, file starts with "VID\0" - if (AV_RL32(p->buf) != MKTAG('V', 'I', 'D', 0)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int vid_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - BVID_DemuxContext *vid = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *stream; - - /* load main header. Contents: - * bytes: 'V' 'I' 'D' - * int16s: always_512, nframes, width, height, delay, always_14 - */ - url_fseek(pb, 5, SEEK_CUR); - vid->nframes = get_le16(pb); - - stream = av_new_stream(s, 0); - if (!stream) - return AVERROR(ENOMEM); - av_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps - stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - stream->codec->codec_id = CODEC_ID_BETHSOFTVID; - stream->codec->width = get_le16(pb); - stream->codec->height = get_le16(pb); - stream->codec->pix_fmt = PIX_FMT_PAL8; - vid->bethsoft_global_delay = get_le16(pb); - get_le16(pb); - - // done with video codec, set up audio codec - stream = av_new_stream(s, 0); - if (!stream) - return AVERROR(ENOMEM); - stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; - stream->codec->codec_id = CODEC_ID_PCM_U8; - stream->codec->channels = 1; - stream->codec->sample_rate = 11025; - stream->codec->bits_per_coded_sample = 8; - stream->codec->bit_rate = stream->codec->channels * stream->codec->sample_rate * stream->codec->bits_per_coded_sample; - - return 0; -} - -#define BUFFER_PADDING_SIZE 1000 -static int read_frame(BVID_DemuxContext *vid, ByteIOContext *pb, AVPacket *pkt, - uint8_t block_type, AVFormatContext *s, int npixels) -{ - uint8_t * vidbuf_start = NULL; - int vidbuf_nbytes = 0; - int code; - int bytes_copied = 0; - int position; - unsigned int vidbuf_capacity; - - vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); - if(!vidbuf_start) - return AVERROR(ENOMEM); - - // save the file position for the packet, include block type - position = url_ftell(pb) - 1; - - vidbuf_start[vidbuf_nbytes++] = block_type; - - // get the video delay (next int16), and set the presentation time - vid->video_pts += vid->bethsoft_global_delay + get_le16(pb); - - // set the y offset if it exists (decoder header data should be in data section) - if(block_type == VIDEO_YOFF_P_FRAME){ - if(get_buffer(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) - goto fail; - vidbuf_nbytes += 2; - } - - do{ - vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); - if(!vidbuf_start) - return AVERROR(ENOMEM); - - code = get_byte(pb); - vidbuf_start[vidbuf_nbytes++] = code; - - if(code >= 0x80){ // rle sequence - if(block_type == VIDEO_I_FRAME) - vidbuf_start[vidbuf_nbytes++] = get_byte(pb); - } else if(code){ // plain sequence - if(get_buffer(pb, &vidbuf_start[vidbuf_nbytes], code) != code) - goto fail; - vidbuf_nbytes += code; - } - bytes_copied += code & 0x7F; - if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied - // may contain a 0 byte even if read all pixels - if(get_byte(pb)) - url_fseek(pb, -1, SEEK_CUR); - break; - } - if(bytes_copied > npixels) - goto fail; - } while(code); - - // copy data into packet - if(av_new_packet(pkt, vidbuf_nbytes) < 0) - goto fail; - memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); - av_free(vidbuf_start); - - pkt->pos = position; - pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream - pkt->pts = vid->video_pts; - - vid->nframes--; // used to check if all the frames were read - return vidbuf_nbytes; -fail: - av_free(vidbuf_start); - return -1; -} - -static int vid_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - BVID_DemuxContext *vid = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned char block_type; - int audio_length; - int ret_value; - - if(vid->is_finished || url_feof(pb)) - return AVERROR(EIO); - - block_type = get_byte(pb); - switch(block_type){ - case PALETTE_BLOCK: - url_fseek(pb, -1, SEEK_CUR); // include block type - ret_value = av_get_packet(pb, pkt, 3 * 256 + 1); - if(ret_value != 3 * 256 + 1){ - av_free_packet(pkt); - return AVERROR(EIO); - } - pkt->stream_index = 0; - return ret_value; - - case FIRST_AUDIO_BLOCK: - get_le16(pb); - // soundblaster DAC used for sample rate, as on specification page (link above) - s->streams[1]->codec->sample_rate = 1000000 / (256 - get_byte(pb)); - s->streams[1]->codec->bit_rate = s->streams[1]->codec->channels * s->streams[1]->codec->sample_rate * s->streams[1]->codec->bits_per_coded_sample; - case AUDIO_BLOCK: - audio_length = get_le16(pb); - ret_value = av_get_packet(pb, pkt, audio_length); - pkt->stream_index = 1; - return ret_value != audio_length ? AVERROR(EIO) : ret_value; - - case VIDEO_P_FRAME: - case VIDEO_YOFF_P_FRAME: - case VIDEO_I_FRAME: - return read_frame(vid, pb, pkt, block_type, s, - s->streams[0]->codec->width * s->streams[0]->codec->height); - - case EOF_BLOCK: - if(vid->nframes != 0) - av_log(s, AV_LOG_VERBOSE, "reached terminating character but not all frames read.\n"); - vid->is_finished = 1; - return AVERROR(EIO); - default: - av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n", - block_type, block_type, block_type); return -1; - } - - return 0; -} - -AVInputFormat bethsoftvid_demuxer = { - "bethsoftvid", - NULL_IF_CONFIG_SMALL("Bethesda Softworks VID format"), - sizeof(BVID_DemuxContext), - vid_probe, - vid_read_header, - vid_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/bfi.c b/tizen/distrib/ffmpeg/libavformat/bfi.c deleted file mode 100644 index 94014a4..0000000 --- a/tizen/distrib/ffmpeg/libavformat/bfi.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Brute Force & Ignorance (BFI) demuxer - * Copyright (c) 2008 Sisir Koppaka - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Brute Force & Ignorance (.bfi) file demuxer - * @author Sisir Koppaka ( sisir.koppaka at gmail dot com ) - * @sa http://wiki.multimedia.cx/index.php?title=BFI - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -typedef struct BFIContext { - int nframes; - int audio_frame; - int video_frame; - int video_size; - int avflag; -} BFIContext; - -static int bfi_probe(AVProbeData * p) -{ - /* Check file header */ - if (AV_RL32(p->buf) == MKTAG('B', 'F', '&', 'I')) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int bfi_read_header(AVFormatContext * s, AVFormatParameters * ap) -{ - BFIContext *bfi = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *vstream; - AVStream *astream; - int fps, chunk_header; - - /* Initialize the video codec... */ - vstream = av_new_stream(s, 0); - if (!vstream) - return AVERROR(ENOMEM); - - /* Initialize the audio codec... */ - astream = av_new_stream(s, 0); - if (!astream) - return AVERROR(ENOMEM); - - /* Set the total number of frames. */ - url_fskip(pb, 8); - chunk_header = get_le32(pb); - bfi->nframes = get_le32(pb); - get_le32(pb); - get_le32(pb); - get_le32(pb); - fps = get_le32(pb); - url_fskip(pb, 12); - vstream->codec->width = get_le32(pb); - vstream->codec->height = get_le32(pb); - - /*Load the palette to extradata */ - url_fskip(pb, 8); - vstream->codec->extradata = av_malloc(768); - vstream->codec->extradata_size = 768; - get_buffer(pb, vstream->codec->extradata, - vstream->codec->extradata_size); - - astream->codec->sample_rate = get_le32(pb); - - /* Set up the video codec... */ - av_set_pts_info(vstream, 32, 1, fps); - vstream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vstream->codec->codec_id = CODEC_ID_BFI; - vstream->codec->pix_fmt = PIX_FMT_PAL8; - - /* Set up the audio codec now... */ - astream->codec->codec_type = AVMEDIA_TYPE_AUDIO; - astream->codec->codec_id = CODEC_ID_PCM_U8; - astream->codec->channels = 1; - astream->codec->bits_per_coded_sample = 8; - astream->codec->bit_rate = - astream->codec->sample_rate * astream->codec->bits_per_coded_sample; - url_fseek(pb, chunk_header - 3, SEEK_SET); - av_set_pts_info(astream, 64, 1, astream->codec->sample_rate); - return 0; -} - - -static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) -{ - BFIContext *bfi = s->priv_data; - ByteIOContext *pb = s->pb; - int ret, audio_offset, video_offset, chunk_size, audio_size = 0; - if (bfi->nframes == 0 || url_feof(pb)) { - return AVERROR(EIO); - } - - /* If all previous chunks were completely read, then find a new one... */ - if (!bfi->avflag) { - uint32_t state = 0; - while(state != MKTAG('S','A','V','I')){ - if (url_feof(pb)) - return AVERROR(EIO); - state = 256*state + get_byte(pb); - } - /* Now that the chunk's location is confirmed, we proceed... */ - chunk_size = get_le32(pb); - get_le32(pb); - audio_offset = get_le32(pb); - get_le32(pb); - video_offset = get_le32(pb); - audio_size = video_offset - audio_offset; - bfi->video_size = chunk_size - video_offset; - - //Tossing an audio packet at the audio decoder. - ret = av_get_packet(pb, pkt, audio_size); - if (ret < 0) - return ret; - - pkt->pts = bfi->audio_frame; - bfi->audio_frame += ret; - } - - else { - - //Tossing a video packet at the video decoder. - ret = av_get_packet(pb, pkt, bfi->video_size); - if (ret < 0) - return ret; - - pkt->pts = bfi->video_frame; - bfi->video_frame += ret / bfi->video_size; - - /* One less frame to read. A cursory decrement. */ - bfi->nframes--; - } - - bfi->avflag = !bfi->avflag; - pkt->stream_index = bfi->avflag; - return ret; -} - -AVInputFormat bfi_demuxer = { - "bfi", - NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"), - sizeof(BFIContext), - bfi_probe, - bfi_read_header, - bfi_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/bink.c b/tizen/distrib/ffmpeg/libavformat/bink.c deleted file mode 100644 index afa629f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/bink.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Bink demuxer - * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org) - * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Bink demuxer - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Bink_Container - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -enum BinkAudFlags { - BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output - BINK_AUD_STEREO = 0x2000, - BINK_AUD_USEDCT = 0x1000, -}; - -#define BINK_EXTRADATA_SIZE 1 -#define BINK_MAX_AUDIO_TRACKS 256 -#define BINK_MAX_WIDTH 7680 -#define BINK_MAX_HEIGHT 4800 - -typedef struct { - uint32_t file_size; - - uint32_t num_audio_tracks; - int current_track; ///< audio track to return in next packet - int64_t video_pts; - int64_t audio_pts[BINK_MAX_AUDIO_TRACKS]; - - uint32_t remain_packet_size; -} BinkDemuxContext; - -static int probe(AVProbeData *p) -{ - const uint8_t *b = p->buf; - - if ( b[0] == 'B' && b[1] == 'I' && b[2] == 'K' && - (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i') && - AV_RL32(b+8) > 0 && // num_frames - AV_RL32(b+20) > 0 && AV_RL32(b+20) <= BINK_MAX_WIDTH && - AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT && - AV_RL32(b+28) > 0 && AV_RL32(b+32) > 0) // fps num,den - return AVPROBE_SCORE_MAX; - return 0; -} - -static int read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - BinkDemuxContext *bink = s->priv_data; - ByteIOContext *pb = s->pb; - uint32_t fps_num, fps_den; - AVStream *vst, *ast; - unsigned int i; - uint32_t pos, next_pos; - uint16_t flags; - int keyframe; - - vst = av_new_stream(s, 0); - if (!vst) - return AVERROR(ENOMEM); - - vst->codec->codec_tag = get_le32(pb); - - bink->file_size = get_le32(pb) + 8; - vst->duration = get_le32(pb); - - if (vst->duration > 1000000) { - av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); - return AVERROR(EIO); - } - - if (get_le32(pb) > bink->file_size) { - av_log(s, AV_LOG_ERROR, - "invalid header: largest frame size greater than file size\n"); - return AVERROR(EIO); - } - - url_fskip(pb, 4); - - vst->codec->width = get_le32(pb); - vst->codec->height = get_le32(pb); - - fps_num = get_le32(pb); - fps_den = get_le32(pb); - if (fps_num == 0 || fps_den == 0) { - av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den); - return AVERROR(EIO); - } - av_set_pts_info(vst, 64, fps_den, fps_num); - - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_BINKVIDEO; - vst->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); - vst->codec->extradata_size = 4; - get_buffer(pb, vst->codec->extradata, 4); - - bink->num_audio_tracks = get_le32(pb); - - if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { - av_log(s, AV_LOG_ERROR, - "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n", - bink->num_audio_tracks); - return AVERROR(EIO); - } - - if (bink->num_audio_tracks) { - url_fskip(pb, 4 * bink->num_audio_tracks); - - for (i = 0; i < bink->num_audio_tracks; i++) { - ast = av_new_stream(s, 1); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_tag = 0; - ast->codec->sample_rate = get_le16(pb); - av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - flags = get_le16(pb); - ast->codec->codec_id = flags & BINK_AUD_USEDCT ? - CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT; - ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1; - } - - url_fskip(pb, 4 * bink->num_audio_tracks); - } - - /* frame index table */ - next_pos = get_le32(pb); - for (i = 0; i < vst->duration; i++) { - pos = next_pos; - if (i == vst->duration - 1) { - next_pos = bink->file_size; - keyframe = 0; - } else { - next_pos = get_le32(pb); - keyframe = pos & 1; - } - pos &= ~1; - next_pos &= ~1; - - if (next_pos <= pos) { - av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); - return AVERROR(EIO); - } - av_add_index_entry(vst, pos, i, next_pos - pos, 0, - keyframe ? AVINDEX_KEYFRAME : 0); - } - - url_fskip(pb, 4); - - bink->current_track = -1; - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - BinkDemuxContext *bink = s->priv_data; - ByteIOContext *pb = s->pb; - int ret; - - if (bink->current_track < 0) { - int index_entry; - AVStream *st = s->streams[0]; // stream 0 is video stream with index - - if (bink->video_pts >= st->duration) - return AVERROR(EIO); - - index_entry = av_index_search_timestamp(st, bink->video_pts, - AVSEEK_FLAG_ANY); - if (index_entry < 0) { - av_log(s, AV_LOG_ERROR, - "could not find index entry for frame %"PRId64"\n", - bink->video_pts); - return AVERROR(EIO); - } - - bink->remain_packet_size = st->index_entries[index_entry].size; - bink->current_track = 0; - } - - while (bink->current_track < bink->num_audio_tracks) { - uint32_t audio_size = get_le32(pb); - if (audio_size > bink->remain_packet_size - 4) { - av_log(s, AV_LOG_ERROR, - "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n", - bink->video_pts, audio_size, bink->remain_packet_size); - return AVERROR(EIO); - } - bink->remain_packet_size -= 4 + audio_size; - bink->current_track++; - if (audio_size >= 4) { - /* get one audio packet per track */ - if ((ret = av_get_packet(pb, pkt, audio_size)) < 0) - return ret; - pkt->stream_index = bink->current_track; - pkt->pts = bink->audio_pts[bink->current_track - 1]; - - /* Each audio packet reports the number of decompressed samples - (in bytes). We use this value to calcuate the audio PTS */ - if (pkt->size >= 4) - bink->audio_pts[bink->current_track -1] += - AV_RL32(pkt->data) / (2 * s->streams[bink->current_track]->codec->channels); - return 0; - } else { - url_fseek(pb, audio_size, SEEK_CUR); - } - } - - /* get video packet */ - if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size)) < 0) - return ret; - pkt->stream_index = 0; - pkt->pts = bink->video_pts++; - pkt->flags |= AV_PKT_FLAG_KEY; - - /* -1 instructs the next call to read_packet() to read the next frame */ - bink->current_track = -1; - - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - BinkDemuxContext *bink = s->priv_data; - AVStream *vst = s->streams[0]; - - if (url_is_streamed(s->pb)) - return -1; - - /* seek to the first frame */ - url_fseek(s->pb, vst->index_entries[0].pos, SEEK_SET); - bink->video_pts = 0; - memset(bink->audio_pts, 0, sizeof(bink->audio_pts)); - bink->current_track = -1; - return 0; -} - -AVInputFormat bink_demuxer = { - "bink", - NULL_IF_CONFIG_SMALL("Bink"), - sizeof(BinkDemuxContext), - probe, - read_header, - read_packet, - NULL, - read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/c93.c b/tizen/distrib/ffmpeg/libavformat/c93.c deleted file mode 100644 index 033b36b..0000000 --- a/tizen/distrib/ffmpeg/libavformat/c93.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Interplay C93 demuxer - * Copyright (c) 2007 Anssi Hannula - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "voc.h" -#include "libavutil/intreadwrite.h" - -typedef struct { - uint16_t index; - uint8_t length; - uint8_t frames; -} C93BlockRecord; - -typedef struct { - VocDecContext voc; - - C93BlockRecord block_records[512]; - int current_block; - - uint32_t frame_offsets[32]; - int current_frame; - int next_pkt_is_audio; - - AVStream *audio; -} C93DemuxContext; - -static int probe(AVProbeData *p) -{ - int i; - int index = 1; - if (p->buf_size < 16) - return 0; - for (i = 0; i < 16; i += 4) { - if (AV_RL16(p->buf + i) != index || !p->buf[i + 2] || !p->buf[i + 3]) - return 0; - index += p->buf[i + 2]; - } - return AVPROBE_SCORE_MAX; -} - -static int read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *video; - ByteIOContext *pb = s->pb; - C93DemuxContext *c93 = s->priv_data; - int i; - int framecount = 0; - - for (i = 0; i < 512; i++) { - c93->block_records[i].index = get_le16(pb); - c93->block_records[i].length = get_byte(pb); - c93->block_records[i].frames = get_byte(pb); - if (c93->block_records[i].frames > 32) { - av_log(s, AV_LOG_ERROR, "too many frames in block\n"); - return AVERROR_INVALIDDATA; - } - framecount += c93->block_records[i].frames; - } - - /* Audio streams are added if audio packets are found */ - s->ctx_flags |= AVFMTCTX_NOHEADER; - - video = av_new_stream(s, 0); - if (!video) - return AVERROR(ENOMEM); - - video->codec->codec_type = AVMEDIA_TYPE_VIDEO; - video->codec->codec_id = CODEC_ID_C93; - video->codec->width = 320; - video->codec->height = 192; - /* 4:3 320x200 with 8 empty lines */ - video->sample_aspect_ratio = (AVRational) { 5, 6 }; - video->time_base = (AVRational) { 2, 25 }; - video->nb_frames = framecount; - video->duration = framecount; - video->start_time = 0; - - c93->current_block = 0; - c93->current_frame = 0; - c93->next_pkt_is_audio = 0; - return 0; -} - -#define C93_HAS_PALETTE 0x01 -#define C93_FIRST_FRAME 0x02 - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - C93DemuxContext *c93 = s->priv_data; - C93BlockRecord *br = &c93->block_records[c93->current_block]; - int datasize; - int ret, i; - - if (c93->next_pkt_is_audio) { - c93->current_frame++; - c93->next_pkt_is_audio = 0; - datasize = get_le16(pb); - if (datasize > 42) { - if (!c93->audio) { - c93->audio = av_new_stream(s, 1); - if (!c93->audio) - return AVERROR(ENOMEM); - c93->audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } - url_fskip(pb, 26); /* VOC header */ - ret = voc_get_packet(s, pkt, c93->audio, datasize - 26); - if (ret > 0) { - pkt->stream_index = 1; - pkt->flags |= AV_PKT_FLAG_KEY; - return ret; - } - } - } - if (c93->current_frame >= br->frames) { - if (c93->current_block >= 511 || !br[1].length) - return AVERROR(EIO); - br++; - c93->current_block++; - c93->current_frame = 0; - } - - if (c93->current_frame == 0) { - url_fseek(pb, br->index * 2048, SEEK_SET); - for (i = 0; i < 32; i++) { - c93->frame_offsets[i] = get_le32(pb); - } - } - - url_fseek(pb,br->index * 2048 + - c93->frame_offsets[c93->current_frame], SEEK_SET); - datasize = get_le16(pb); /* video frame size */ - - ret = av_new_packet(pkt, datasize + 768 + 1); - if (ret < 0) - return ret; - pkt->data[0] = 0; - pkt->size = datasize + 1; - - ret = get_buffer(pb, pkt->data + 1, datasize); - if (ret < datasize) { - ret = AVERROR(EIO); - goto fail; - } - - datasize = get_le16(pb); /* palette size */ - if (datasize) { - if (datasize != 768) { - av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize); - ret = AVERROR_INVALIDDATA; - goto fail; - } - pkt->data[0] |= C93_HAS_PALETTE; - ret = get_buffer(pb, pkt->data + pkt->size, datasize); - if (ret < datasize) { - ret = AVERROR(EIO); - goto fail; - } - pkt->size += 768; - } - pkt->stream_index = 0; - c93->next_pkt_is_audio = 1; - - /* only the first frame is guaranteed to not reference previous frames */ - if (c93->current_block == 0 && c93->current_frame == 0) { - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->data[0] |= C93_FIRST_FRAME; - } - return 0; - - fail: - av_free_packet(pkt); - return ret; -} - -AVInputFormat c93_demuxer = { - "c93", - NULL_IF_CONFIG_SMALL("Interplay C93"), - sizeof(C93DemuxContext), - probe, - read_header, - read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/caf.c b/tizen/distrib/ffmpeg/libavformat/caf.c deleted file mode 100644 index a814ab0..0000000 --- a/tizen/distrib/ffmpeg/libavformat/caf.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * CAF common code - * Copyright (c) 2007 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * CAF common code - */ - -#include "avformat.h" -#include "riff.h" -#include "caf.h" - -/** - * Known codec tags for CAF - */ -const AVCodecTag ff_codec_caf_tags[] = { - { CODEC_ID_AAC, MKBETAG('a','a','c',' ') }, - { CODEC_ID_AC3, MKBETAG('a','c','-','3') }, - { CODEC_ID_ALAC, MKBETAG('a','l','a','c') }, - /* FIXME: use DV demuxer, as done in MOV */ - /*{ CODEC_ID_DVAUDIO, MKBETAG('v','d','v','a') },*/ - /*{ CODEC_ID_DVAUDIO, MKBETAG('d','v','c','a') },*/ - { CODEC_ID_ADPCM_IMA_QT, MKBETAG('i','m','a','4') }, - { CODEC_ID_MACE3, MKBETAG('M','A','C','3') }, - { CODEC_ID_MACE6, MKBETAG('M','A','C','6') }, - { CODEC_ID_MP3, MKBETAG('.','m','p','3') }, - { CODEC_ID_MP2, MKBETAG('.','m','p','2') }, - { CODEC_ID_MP1, MKBETAG('.','m','p','1') }, - { CODEC_ID_PCM_ALAW, MKBETAG('a','l','a','w') }, - { CODEC_ID_PCM_MULAW, MKBETAG('u','l','a','w') }, - { CODEC_ID_QCELP, MKBETAG('Q','c','l','p') }, - { CODEC_ID_QDM2, MKBETAG('Q','D','M','2') }, - { CODEC_ID_QDM2, MKBETAG('Q','D','M','C') }, - /* currently unsupported codecs */ - /*{ AC-3 over S/PDIF MKBETAG('c','a','c','3') },*/ - /*{ MPEG4CELP MKBETAG('c','e','l','p') },*/ - /*{ MPEG4HVXC MKBETAG('h','v','x','c') },*/ - /*{ MPEG4TwinVQ MKBETAG('t','w','v','q') },*/ - { CODEC_ID_NONE, 0 }, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/caf.h b/tizen/distrib/ffmpeg/libavformat/caf.h deleted file mode 100644 index e1f93a6..0000000 --- a/tizen/distrib/ffmpeg/libavformat/caf.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * CAF common code - * Copyright (c) 2007 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * CAF common code - */ - -#ifndef AVFORMAT_CAF_H -#define AVFORMAT_CAF_H - -#include "riff.h" - -extern const AVCodecTag ff_codec_caf_tags[]; - -#endif /* AVFORMAT_CAF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/cafdec.c b/tizen/distrib/ffmpeg/libavformat/cafdec.c deleted file mode 100644 index c020579..0000000 --- a/tizen/distrib/ffmpeg/libavformat/cafdec.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Core Audio Format demuxer - * Copyright (c) 2007 Justin Ruggles - * Copyright (c) 2009 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Core Audio Format demuxer - */ - -#include "avformat.h" -#include "riff.h" -#include "isom.h" -#include "libavutil/intreadwrite.h" -#include "caf.h" - -typedef struct { - int bytes_per_packet; ///< bytes in a packet, or 0 if variable - int frames_per_packet; ///< frames in a packet, or 0 if variable - int64_t num_bytes; ///< total number of bytes in stream - - int64_t packet_cnt; ///< packet counter - int64_t frame_cnt; ///< frame counter - - int64_t data_start; ///< data start position, in bytes - int64_t data_size; ///< raw data size, in bytes -} CaffContext; - -static int probe(AVProbeData *p) -{ - if (AV_RB32(p->buf) == MKBETAG('c','a','f','f') && AV_RB16(&p->buf[4]) == 1) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** Read audio description chunk */ -static int read_desc_chunk(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - CaffContext *caf = s->priv_data; - AVStream *st; - int flags; - - /* new audio stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - /* parse format description */ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->sample_rate = av_int2dbl(get_be64(pb)); - st->codec->codec_tag = get_be32(pb); - flags = get_be32(pb); - caf->bytes_per_packet = get_be32(pb); - st->codec->block_align = caf->bytes_per_packet; - caf->frames_per_packet = get_be32(pb); - st->codec->channels = get_be32(pb); - st->codec->bits_per_coded_sample = get_be32(pb); - - /* calculate bit rate for constant size packets */ - if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) { - st->codec->bit_rate = (uint64_t)st->codec->sample_rate * (uint64_t)caf->bytes_per_packet * 8 - / (uint64_t)caf->frames_per_packet; - } else { - st->codec->bit_rate = 0; - } - - /* determine codec */ - if (st->codec->codec_tag == MKBETAG('l','p','c','m')) - st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, (flags ^ 0x2) | 0x4); - else - st->codec->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codec->codec_tag); - return 0; -} - -/** Read magic cookie chunk */ -static int read_kuki_chunk(AVFormatContext *s, int64_t size) -{ - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - - if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) - return -1; - - if (st->codec->codec_id == CODEC_ID_AAC) { - /* The magic cookie format for AAC is an mp4 esds atom. - The lavc AAC decoder requires the data from the codec specific - description as extradata input. */ - int strt, skip; - MOVAtom atom; - - strt = url_ftell(pb); - ff_mov_read_esds(s, pb, atom); - skip = size - (url_ftell(pb) - strt); - if (skip < 0 || !st->codec->extradata || - st->codec->codec_id != CODEC_ID_AAC) { - av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n"); - return AVERROR_INVALIDDATA; - } - url_fskip(pb, skip); - } else { - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - get_buffer(pb, st->codec->extradata, size); - st->codec->extradata_size = size; - } - - return 0; -} - -/** Read packet table chunk */ -static int read_pakt_chunk(AVFormatContext *s, int64_t size) -{ - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - CaffContext *caf = s->priv_data; - int64_t pos = 0, ccount; - int num_packets, i; - - ccount = url_ftell(pb); - - num_packets = get_be64(pb); - if (num_packets < 0 || INT32_MAX / sizeof(AVIndexEntry) < num_packets) - return AVERROR_INVALIDDATA; - - st->nb_frames = get_be64(pb); /* valid frames */ - st->nb_frames += get_be32(pb); /* priming frames */ - st->nb_frames += get_be32(pb); /* remainder frames */ - - st->duration = 0; - for (i = 0; i < num_packets; i++) { - av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); - pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); - st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); - } - - if (url_ftell(pb) - ccount != size) { - av_log(s, AV_LOG_ERROR, "error reading packet table\n"); - return -1; - } - - caf->num_bytes = pos; - return 0; -} - -/** Read information chunk */ -static void read_info_chunk(AVFormatContext *s, int64_t size) -{ - ByteIOContext *pb = s->pb; - unsigned int i; - unsigned int nb_entries = get_be32(pb); - for (i = 0; i < nb_entries; i++) { - char key[32]; - char value[1024]; - get_strz(pb, key, sizeof(key)); - get_strz(pb, value, sizeof(value)); - av_metadata_set2(&s->metadata, key, value, 0); - } -} - -static int read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - CaffContext *caf = s->priv_data; - AVStream *st; - uint32_t tag = 0; - int found_data, ret; - int64_t size; - - url_fskip(pb, 8); /* magic, version, file flags */ - - /* audio description chunk */ - if (get_be32(pb) != MKBETAG('d','e','s','c')) { - av_log(s, AV_LOG_ERROR, "desc chunk not present\n"); - return AVERROR_INVALIDDATA; - } - size = get_be64(pb); - if (size != 32) - return AVERROR_INVALIDDATA; - - ret = read_desc_chunk(s); - if (ret) - return ret; - st = s->streams[0]; - - /* parse each chunk */ - found_data = 0; - while (!url_feof(pb)) { - - /* stop at data chunk if seeking is not supported or - data chunk size is unknown */ - if (found_data && (caf->data_size < 0 || url_is_streamed(pb))) - break; - - tag = get_be32(pb); - size = get_be64(pb); - if (url_feof(pb)) - break; - - switch (tag) { - case MKBETAG('d','a','t','a'): - url_fskip(pb, 4); /* edit count */ - caf->data_start = url_ftell(pb); - caf->data_size = size < 0 ? -1 : size - 4; - if (caf->data_size > 0 && !url_is_streamed(pb)) - url_fskip(pb, caf->data_size); - found_data = 1; - break; - - /* magic cookie chunk */ - case MKBETAG('k','u','k','i'): - if (read_kuki_chunk(s, size)) - return AVERROR_INVALIDDATA; - break; - - /* packet table chunk */ - case MKBETAG('p','a','k','t'): - if (read_pakt_chunk(s, size)) - return AVERROR_INVALIDDATA; - break; - - case MKBETAG('i','n','f','o'): - read_info_chunk(s, size); - break; - - default: -#define _(x) ((x) >= ' ' ? (x) : ' ') - av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c)\n", - tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF)); -#undef _ - case MKBETAG('f','r','e','e'): - if (size < 0) - return AVERROR_INVALIDDATA; - url_fskip(pb, size); - break; - } - } - - if (!found_data) - return AVERROR_INVALIDDATA; - - if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) { - if (caf->data_size > 0) - st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet; - } else if (st->nb_index_entries) { - st->codec->bit_rate = st->codec->sample_rate * caf->data_size * 8 / - st->duration; - } else { - av_log(s, AV_LOG_ERROR, "Missing packet table. It is required when " - "block size or frame size are variable.\n"); - return AVERROR_INVALIDDATA; - } - s->file_size = url_fsize(pb); - s->file_size = FFMAX(0, s->file_size); - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - st->start_time = 0; - - /* position the stream at the start of data */ - if (caf->data_size >= 0) - url_fseek(pb, caf->data_start, SEEK_SET); - - return 0; -} - -#define CAF_MAX_PKT_SIZE 4096 - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - CaffContext *caf = s->priv_data; - int res, pkt_size = 0, pkt_frames = 0; - int64_t left = CAF_MAX_PKT_SIZE; - - if (url_feof(pb)) - return AVERROR(EIO); - - /* don't read past end of data chunk */ - if (caf->data_size > 0) { - left = (caf->data_start + caf->data_size) - url_ftell(pb); - if (left <= 0) - return AVERROR(EIO); - } - - pkt_frames = caf->frames_per_packet; - pkt_size = caf->bytes_per_packet; - - if (pkt_size > 0 && pkt_frames == 1) { - pkt_size = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size; - pkt_size = FFMIN(pkt_size, left); - pkt_frames = pkt_size / caf->bytes_per_packet; - } else if (st->nb_index_entries) { - if (caf->packet_cnt < st->nb_index_entries - 1) { - pkt_size = st->index_entries[caf->packet_cnt + 1].pos - st->index_entries[caf->packet_cnt].pos; - pkt_frames = st->index_entries[caf->packet_cnt + 1].timestamp - st->index_entries[caf->packet_cnt].timestamp; - } else if (caf->packet_cnt == st->nb_index_entries - 1) { - pkt_size = caf->num_bytes - st->index_entries[caf->packet_cnt].pos; - pkt_frames = st->duration - st->index_entries[caf->packet_cnt].timestamp; - } else { - return AVERROR(EIO); - } - } - - if (pkt_size == 0 || pkt_frames == 0 || pkt_size > left) - return AVERROR(EIO); - - res = av_get_packet(pb, pkt, pkt_size); - if (res < 0) - return res; - - pkt->size = res; - pkt->stream_index = 0; - pkt->dts = pkt->pts = caf->frame_cnt; - - caf->packet_cnt++; - caf->frame_cnt += pkt_frames; - - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - AVStream *st = s->streams[0]; - CaffContext *caf = s->priv_data; - int64_t pos; - - timestamp = FFMAX(timestamp, 0); - - if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) { - /* calculate new byte position based on target frame position */ - pos = caf->bytes_per_packet * timestamp / caf->frames_per_packet; - if (caf->data_size > 0) - pos = FFMIN(pos, caf->data_size); - caf->packet_cnt = pos / caf->bytes_per_packet; - caf->frame_cnt = caf->frames_per_packet * caf->packet_cnt; - } else if (st->nb_index_entries) { - caf->packet_cnt = av_index_search_timestamp(st, timestamp, flags); - caf->frame_cnt = st->index_entries[caf->packet_cnt].timestamp; - pos = st->index_entries[caf->packet_cnt].pos; - } else { - return -1; - } - - url_fseek(s->pb, pos + caf->data_start, SEEK_SET); - return 0; -} - -AVInputFormat caf_demuxer = { - "caf", - NULL_IF_CONFIG_SMALL("Apple Core Audio Format"), - sizeof(CaffContext), - probe, - read_header, - read_packet, - NULL, - read_seek, - .codec_tag = (const AVCodecTag*[]){ff_codec_caf_tags, 0}, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/cdg.c b/tizen/distrib/ffmpeg/libavformat/cdg.c deleted file mode 100644 index 2f4fb27..0000000 --- a/tizen/distrib/ffmpeg/libavformat/cdg.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * CD Graphics Demuxer - * Copyright (c) 2009 Michael Tison - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" - -#define CDG_PACKET_SIZE 24 - -static int read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - AVStream *vst; - int ret; - - vst = av_new_stream(s, 0); - if (!vst) - return AVERROR(ENOMEM); - - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_CDGRAPHICS; - - /// 75 sectors/sec * 4 packets/sector = 300 packets/sec - av_set_pts_info(vst, 32, 1, 300); - - ret = url_fsize(s->pb); - if (ret > 0) - vst->duration = (ret * vst->time_base.den) / (CDG_PACKET_SIZE * 300); - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret; - - ret = av_get_packet(s->pb, pkt, CDG_PACKET_SIZE); - - pkt->stream_index = 0; - return ret; -} - -AVInputFormat cdg_demuxer = { - "cdg", - NULL_IF_CONFIG_SMALL("CD Graphics Format"), - 0, - NULL, - read_header, - read_packet, - .extensions = "cdg" -}; diff --git a/tizen/distrib/ffmpeg/libavformat/concat.c b/tizen/distrib/ffmpeg/libavformat/concat.c deleted file mode 100644 index 3a19d0a..0000000 --- a/tizen/distrib/ffmpeg/libavformat/concat.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Concat URL protocol - * Copyright (c) 2006 Steve Lhomme - * Copyright (c) 2007 Wolfram Gloger - * Copyright (c) 2010 Michele Orrù - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "libavutil/avstring.h" -#include "libavutil/mem.h" - -#define AV_CAT_SEPARATOR "|" - -struct concat_nodes { - URLContext *uc; ///< node's URLContext - int64_t size; ///< url filesize -}; - -struct concat_data { - struct concat_nodes *nodes; ///< list of nodes to concat - size_t length; ///< number of cat'ed nodes - size_t current; ///< index of currently read node -}; - -static av_cold int concat_close(URLContext *h) -{ - int err = 0; - size_t i; - struct concat_data *data = h->priv_data; - struct concat_nodes *nodes = data->nodes; - - for (i = 0; i != data->length; i++) - err |= url_close(nodes[i].uc); - - av_freep(&data->nodes); - av_freep(&h->priv_data); - - return err < 0 ? -1 : 0; -} - -static av_cold int concat_open(URLContext *h, const char *uri, int flags) -{ - char *node_uri = NULL, *tmp_uri; - int err = 0; - int64_t size; - size_t len, i; - URLContext *uc; - struct concat_data *data; - struct concat_nodes *nodes; - - av_strstart(uri, "concat:", &uri); - - /* creating data */ - if (!(data = av_mallocz(sizeof(*data)))) - return AVERROR(ENOMEM); - h->priv_data = data; - - for (i = 0, len = 1; uri[i]; i++) - if (uri[i] == *AV_CAT_SEPARATOR) - /* integer overflow */ - if (++len == UINT_MAX / sizeof(*nodes)) { - av_freep(&h->priv_data); - return AVERROR(ENAMETOOLONG); - } - - if (!(nodes = av_malloc(sizeof(*nodes) * len))) { - av_freep(&h->priv_data); - return AVERROR(ENOMEM); - } else - data->nodes = nodes; - - /* handle input */ - if (!*uri) - err = AVERROR(ENOENT); - for (i = 0; *uri; i++) { - /* parsing uri */ - len = strcspn(uri, AV_CAT_SEPARATOR); - if (!(tmp_uri = av_realloc(node_uri, len+1))) { - err = AVERROR(ENOMEM); - break; - } else - node_uri = tmp_uri; - av_strlcpy(node_uri, uri, len+1); - uri += len + strspn(uri+len, AV_CAT_SEPARATOR); - - /* creating URLContext */ - if ((err = url_open(&uc, node_uri, flags)) < 0) - break; - - /* creating size */ - if ((size = url_filesize(uc)) < 0) { - url_close(uc); - err = AVERROR(ENOSYS); - break; - } - - /* assembling */ - nodes[i].uc = uc; - nodes[i].size = size; - } - av_free(node_uri); - data->length = i; - - if (err < 0) - concat_close(h); - else if (!(nodes = av_realloc(nodes, data->length * sizeof(*nodes)))) { - concat_close(h); - err = AVERROR(ENOMEM); - } else - data->nodes = nodes; - return err; -} - -static int concat_read(URLContext *h, unsigned char *buf, int size) -{ - int result, total = 0; - struct concat_data *data = h->priv_data; - struct concat_nodes *nodes = data->nodes; - size_t i = data->current; - - while (size > 0) { - result = url_read(nodes[i].uc, buf, size); - if (result < 0) - return total ? total : result; - if (!result) - if (i + 1 == data->length || - url_seek(nodes[++i].uc, 0, SEEK_SET) < 0) - break; - total += result; - buf += result; - size -= result; - } - data->current = i; - return total; -} - -static int64_t concat_seek(URLContext *h, int64_t pos, int whence) -{ - int64_t result; - struct concat_data *data = h->priv_data; - struct concat_nodes *nodes = data->nodes; - size_t i; - - switch (whence) { - case SEEK_END: - for (i = data->length - 1; - i && pos < -nodes[i].size; - i--) - pos += nodes[i].size; - break; - case SEEK_CUR: - /* get the absolute position */ - for (i = 0; i != data->current; i++) - pos += nodes[i].size; - pos += url_seek(nodes[i].uc, 0, SEEK_CUR); - whence = SEEK_SET; - /* fall through with the absolute position */ - case SEEK_SET: - for (i = 0; i != data->length - 1 && pos >= nodes[i].size; i++) - pos -= nodes[i].size; - break; - default: - return AVERROR(EINVAL); - } - - result = url_seek(nodes[i].uc, pos, whence); - if (result >= 0) { - data->current = i; - while (i) - result += nodes[--i].size; - } - return result; -} - -URLProtocol concat_protocol = { - "concat", - concat_open, - concat_read, - NULL, - concat_seek, - concat_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/crcenc.c b/tizen/distrib/ffmpeg/libavformat/crcenc.c deleted file mode 100644 index b343464..0000000 --- a/tizen/distrib/ffmpeg/libavformat/crcenc.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * CRC encoder (for codec/format testing) - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/adler32.h" -#include "avformat.h" - -typedef struct CRCState { - uint32_t crcval; -} CRCState; - -static int crc_write_header(struct AVFormatContext *s) -{ - CRCState *crc = s->priv_data; - - /* init CRC */ - crc->crcval = 1; - - return 0; -} - -static int crc_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - CRCState *crc = s->priv_data; - crc->crcval = av_adler32_update(crc->crcval, pkt->data, pkt->size); - return 0; -} - -static int crc_write_trailer(struct AVFormatContext *s) -{ - CRCState *crc = s->priv_data; - char buf[64]; - - snprintf(buf, sizeof(buf), "CRC=0x%08x\n", crc->crcval); - put_buffer(s->pb, buf, strlen(buf)); - put_flush_packet(s->pb); - return 0; -} - -AVOutputFormat crc_muxer = { - "crc", - NULL_IF_CONFIG_SMALL("CRC testing format"), - NULL, - "", - sizeof(CRCState), - CODEC_ID_PCM_S16LE, - CODEC_ID_RAWVIDEO, - crc_write_header, - crc_write_packet, - crc_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/cutils.c b/tizen/distrib/ffmpeg/libavformat/cutils.c deleted file mode 100644 index ad5cb05..0000000 --- a/tizen/distrib/ffmpeg/libavformat/cutils.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Various simple utilities for ffmpeg system - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "internal.h" - -/* add one element to a dynamic array */ -void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem) -{ - int nb, nb_alloc; - intptr_t *tab; - - nb = *nb_ptr; - tab = *tab_ptr; - if ((nb & (nb - 1)) == 0) { - if (nb == 0) - nb_alloc = 1; - else - nb_alloc = nb * 2; - tab = av_realloc(tab, nb_alloc * sizeof(intptr_t)); - *tab_ptr = tab; - } - tab[nb++] = elem; - *nb_ptr = nb; -} - -/* multiple definition between FFMPEG and QEMU */ -time_t _mktimegm(struct tm *tm) -{ - time_t t; - - int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday; - - if (m < 3) { - m += 12; - y--; - } - - t = 86400 * - (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469); - - t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; - - return t; -} - -#define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0)) -#define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400) - -/* This is our own gmtime_r. It differs from its POSIX counterpart in a - couple of places, though. */ -struct tm *brktimegm(time_t secs, struct tm *tm) -{ - int days, y, ny, m; - int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - - days = secs / 86400; - secs %= 86400; - tm->tm_hour = secs / 3600; - tm->tm_min = (secs % 3600) / 60; - tm->tm_sec = secs % 60; - - /* oh well, may be someone some day will invent a formula for this stuff */ - y = 1970; /* start "guessing" */ - while (days > 365) { - ny = (y + days/366); - days -= (ny - y) * 365 + LEAPS_COUNT(ny - 1) - LEAPS_COUNT(y - 1); - y = ny; - } - if (days==365 && !ISLEAP(y)) { days=0; y++; } - md[1] = ISLEAP(y)?29:28; - for (m=0; days >= md[m]; m++) - days -= md[m]; - - tm->tm_year = y; /* unlike gmtime_r we store complete year here */ - tm->tm_mon = m+1; /* unlike gmtime_r tm_mon is from 1 to 12 */ - tm->tm_mday = days+1; - - return tm; -} - -/* get a positive number between n_min and n_max, for a maximum length - of len_max. Return -1 if error. */ -static int date_get_num(const char **pp, - int n_min, int n_max, int len_max) -{ - int i, val, c; - const char *p; - - p = *pp; - val = 0; - for(i = 0; i < len_max; i++) { - c = *p; - if (!isdigit(c)) - break; - val = (val * 10) + c - '0'; - p++; - } - /* no number read ? */ - if (p == *pp) - return -1; - if (val < n_min || val > n_max) - return -1; - *pp = p; - return val; -} - -/* small strptime for ffmpeg */ -const char *small_strptime(const char *p, const char *fmt, - struct tm *dt) -{ - int c, val; - - for(;;) { - c = *fmt++; - if (c == '\0') { - return p; - } else if (c == '%') { - c = *fmt++; - switch(c) { - case 'H': - val = date_get_num(&p, 0, 23, 2); - if (val == -1) - return NULL; - dt->tm_hour = val; - break; - case 'M': - val = date_get_num(&p, 0, 59, 2); - if (val == -1) - return NULL; - dt->tm_min = val; - break; - case 'S': - val = date_get_num(&p, 0, 59, 2); - if (val == -1) - return NULL; - dt->tm_sec = val; - break; - case 'Y': - val = date_get_num(&p, 0, 9999, 4); - if (val == -1) - return NULL; - dt->tm_year = val - 1900; - break; - case 'm': - val = date_get_num(&p, 1, 12, 2); - if (val == -1) - return NULL; - dt->tm_mon = val - 1; - break; - case 'd': - val = date_get_num(&p, 1, 31, 2); - if (val == -1) - return NULL; - dt->tm_mday = val; - break; - case '%': - goto match; - default: - return NULL; - } - } else { - match: - if (c != *p) - return NULL; - p++; - } - } - return p; -} - diff --git a/tizen/distrib/ffmpeg/libavformat/daud.c b/tizen/distrib/ffmpeg/libavformat/daud.c deleted file mode 100644 index 9b0e008..0000000 --- a/tizen/distrib/ffmpeg/libavformat/daud.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * D-Cinema audio demuxer - * Copyright (c) 2005 Reimar Döffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" - -static int daud_header(AVFormatContext *s, AVFormatParameters *ap) { - AVStream *st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_S24DAUD; - st->codec->codec_tag = MKTAG('d', 'a', 'u', 'd'); - st->codec->channels = 6; - st->codec->sample_rate = 96000; - st->codec->bit_rate = 3 * 6 * 96000 * 8; - st->codec->block_align = 3 * 6; - st->codec->bits_per_coded_sample = 24; - return 0; -} - -static int daud_packet(AVFormatContext *s, AVPacket *pkt) { - ByteIOContext *pb = s->pb; - int ret, size; - if (url_feof(pb)) - return AVERROR(EIO); - size = get_be16(pb); - get_be16(pb); // unknown - ret = av_get_packet(pb, pkt, size); - pkt->stream_index = 0; - return ret; -} - -static int daud_write_header(struct AVFormatContext *s) -{ - AVCodecContext *codec = s->streams[0]->codec; - if (codec->channels!=6 || codec->sample_rate!=96000) - return -1; - return 0; -} - -static int daud_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - put_be16(s->pb, pkt->size); - put_be16(s->pb, 0x8010); // unknown - put_buffer(s->pb, pkt->data, pkt->size); - put_flush_packet(s->pb); - return 0; -} - -#if CONFIG_DAUD_DEMUXER -AVInputFormat daud_demuxer = { - "daud", - NULL_IF_CONFIG_SMALL("D-Cinema audio format"), - 0, - NULL, - daud_header, - daud_packet, - NULL, - NULL, - .extensions = "302", -}; -#endif - -#if CONFIG_DAUD_MUXER -AVOutputFormat daud_muxer = -{ - "daud", - NULL_IF_CONFIG_SMALL("D-Cinema audio format"), - NULL, - "302", - 0, - CODEC_ID_PCM_S24DAUD, - CODEC_ID_NONE, - daud_write_header, - daud_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/dsicin.c b/tizen/distrib/ffmpeg/libavformat/dsicin.c deleted file mode 100644 index af5e2d9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/dsicin.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Delphine Software International CIN File Demuxer - * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Delphine Software International CIN file demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - - -typedef struct CinFileHeader { - int video_frame_size; - int video_frame_width; - int video_frame_height; - int audio_frequency; - int audio_bits; - int audio_stereo; - int audio_frame_size; -} CinFileHeader; - -typedef struct CinFrameHeader { - int audio_frame_type; - int video_frame_type; - int pal_colors_count; - int audio_frame_size; - int video_frame_size; -} CinFrameHeader; - -typedef struct CinDemuxContext { - int audio_stream_index; - int video_stream_index; - CinFileHeader file_header; - int64_t audio_stream_pts; - int64_t video_stream_pts; - CinFrameHeader frame_header; - int audio_buffer_size; -} CinDemuxContext; - - -static int cin_probe(AVProbeData *p) -{ - /* header starts with this special marker */ - if (AV_RL32(&p->buf[0]) != 0x55AA0000) - return 0; - - /* for accuracy, check some header field values */ - if (AV_RL32(&p->buf[12]) != 22050 || p->buf[16] != 16 || p->buf[17] != 0) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int cin_read_file_header(CinDemuxContext *cin, ByteIOContext *pb) { - CinFileHeader *hdr = &cin->file_header; - - if (get_le32(pb) != 0x55AA0000) - return AVERROR_INVALIDDATA; - - hdr->video_frame_size = get_le32(pb); - hdr->video_frame_width = get_le16(pb); - hdr->video_frame_height = get_le16(pb); - hdr->audio_frequency = get_le32(pb); - hdr->audio_bits = get_byte(pb); - hdr->audio_stereo = get_byte(pb); - hdr->audio_frame_size = get_le16(pb); - - if (hdr->audio_frequency != 22050 || hdr->audio_bits != 16 || hdr->audio_stereo != 0) - return AVERROR_INVALIDDATA; - - return 0; -} - -static int cin_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - int rc; - CinDemuxContext *cin = s->priv_data; - CinFileHeader *hdr = &cin->file_header; - ByteIOContext *pb = s->pb; - AVStream *st; - - rc = cin_read_file_header(cin, pb); - if (rc) - return rc; - - cin->video_stream_pts = 0; - cin->audio_stream_pts = 0; - cin->audio_buffer_size = 0; - - /* initialize the video decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 32, 1, 12); - cin->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DSICINVIDEO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = hdr->video_frame_width; - st->codec->height = hdr->video_frame_height; - - /* initialize the audio decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 32, 1, 22050); - cin->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_DSICINAUDIO; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = 1; - st->codec->sample_rate = 22050; - st->codec->bits_per_coded_sample = 16; - st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - - return 0; -} - -static int cin_read_frame_header(CinDemuxContext *cin, ByteIOContext *pb) { - CinFrameHeader *hdr = &cin->frame_header; - - hdr->video_frame_type = get_byte(pb); - hdr->audio_frame_type = get_byte(pb); - hdr->pal_colors_count = get_le16(pb); - hdr->video_frame_size = get_le32(pb); - hdr->audio_frame_size = get_le32(pb); - - if (url_feof(pb) || url_ferror(pb)) - return AVERROR(EIO); - - if (get_le32(pb) != 0xAA55AA55) - return AVERROR_INVALIDDATA; - - return 0; -} - -static int cin_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - CinDemuxContext *cin = s->priv_data; - ByteIOContext *pb = s->pb; - CinFrameHeader *hdr = &cin->frame_header; - int rc, palette_type, pkt_size; - int ret; - - if (cin->audio_buffer_size == 0) { - rc = cin_read_frame_header(cin, pb); - if (rc) - return rc; - - if ((int16_t)hdr->pal_colors_count < 0) { - hdr->pal_colors_count = -(int16_t)hdr->pal_colors_count; - palette_type = 1; - } else { - palette_type = 0; - } - - /* palette and video packet */ - pkt_size = (palette_type + 3) * hdr->pal_colors_count + hdr->video_frame_size; - - ret = av_new_packet(pkt, 4 + pkt_size); - if (ret < 0) - return ret; - - pkt->stream_index = cin->video_stream_index; - pkt->pts = cin->video_stream_pts++; - - pkt->data[0] = palette_type; - pkt->data[1] = hdr->pal_colors_count & 0xFF; - pkt->data[2] = hdr->pal_colors_count >> 8; - pkt->data[3] = hdr->video_frame_type; - - ret = get_buffer(pb, &pkt->data[4], pkt_size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - if (ret < pkt_size) - av_shrink_packet(pkt, 4 + ret); - - /* sound buffer will be processed on next read_packet() call */ - cin->audio_buffer_size = hdr->audio_frame_size; - return 0; - } - - /* audio packet */ - ret = av_get_packet(pb, pkt, cin->audio_buffer_size); - if (ret < 0) - return ret; - - pkt->stream_index = cin->audio_stream_index; - pkt->pts = cin->audio_stream_pts; - cin->audio_stream_pts += cin->audio_buffer_size * 2 / cin->file_header.audio_frame_size; - cin->audio_buffer_size = 0; - return 0; -} - -AVInputFormat dsicin_demuxer = { - "dsicin", - NULL_IF_CONFIG_SMALL("Delphine Software International CIN format"), - sizeof(CinDemuxContext), - cin_probe, - cin_read_header, - cin_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/dv.c b/tizen/distrib/ffmpeg/libavformat/dv.c deleted file mode 100644 index b6f9c6a..0000000 --- a/tizen/distrib/ffmpeg/libavformat/dv.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * General DV muxer/demuxer - * Copyright (c) 2003 Roman Shaposhnik - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * Raw DV format - * Copyright (c) 2002 Fabrice Bellard - * - * 50 Mbps (DVCPRO50) and 100 Mbps (DVCPRO HD) support - * Copyright (c) 2006 Daniel Maas - * Funded by BBC Research & Development - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include "avformat.h" -#include "libavcodec/dvdata.h" -#include "libavutil/intreadwrite.h" -#include "dv.h" - -struct DVDemuxContext { - const DVprofile* sys; /* Current DV profile. E.g.: 525/60, 625/50 */ - AVFormatContext* fctx; - AVStream* vst; - AVStream* ast[4]; - AVPacket audio_pkt[4]; - uint8_t audio_buf[4][8192]; - int ach; - int frames; - uint64_t abytes; -}; - -static inline uint16_t dv_audio_12to16(uint16_t sample) -{ - uint16_t shift, result; - - sample = (sample < 0x800) ? sample : sample | 0xf000; - shift = (sample & 0xf00) >> 8; - - if (shift < 0x2 || shift > 0xd) { - result = sample; - } else if (shift < 0x8) { - shift--; - result = (sample - (256 * shift)) << shift; - } else { - shift = 0xe - shift; - result = ((sample + ((256 * shift) + 1)) << shift) - 1; - } - - return result; -} - -/* - * This is the dumbest implementation of all -- it simply looks at - * a fixed offset and if pack isn't there -- fails. We might want - * to have a fallback mechanism for complete search of missing packs. - */ -static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t) -{ - int offs; - - switch (t) { - case dv_audio_source: - offs = (80*6 + 80*16*3 + 3); - break; - case dv_audio_control: - offs = (80*6 + 80*16*4 + 3); - break; - case dv_video_control: - offs = (80*5 + 48 + 5); - break; - default: - return NULL; - } - - return frame[offs] == t ? &frame[offs] : NULL; -} - -/* - * There's a couple of assumptions being made here: - * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples. - * We can pass them upwards when ffmpeg will be ready to deal with them. - * 2. We don't do software emphasis. - * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples - * are converted into 16bit linear ones. - */ -static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], - const DVprofile *sys) -{ - int size, chan, i, j, d, of, smpls, freq, quant, half_ch; - uint16_t lc, rc; - const uint8_t* as_pack; - uint8_t *pcm, ipcm; - - as_pack = dv_extract_pack(frame, dv_audio_source); - if (!as_pack) /* No audio ? */ - return 0; - - smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */ - freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */ - quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ - - if (quant > 1) - return -1; /* unsupported quantization */ - - size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ - half_ch = sys->difseg_size / 2; - - /* We work with 720p frames split in half, thus even frames have - * channels 0,1 and odd 2,3. */ - ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0; - pcm = ppcm[ipcm++]; - - /* for each DIF channel */ - for (chan = 0; chan < sys->n_difchan; chan++) { - /* for each DIF segment */ - for (i = 0; i < sys->difseg_size; i++) { - frame += 6 * 80; /* skip DIF segment header */ - if (quant == 1 && i == half_ch) { - /* next stereo channel (12bit mode only) */ - pcm = ppcm[ipcm++]; - if (!pcm) - break; - } - - /* for each AV sequence */ - for (j = 0; j < 9; j++) { - for (d = 8; d < 80; d += 2) { - if (quant == 0) { /* 16bit quantization */ - of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride; - if (of*2 >= size) - continue; - - pcm[of*2] = frame[d+1]; // FIXME: maybe we have to admit - pcm[of*2+1] = frame[d]; // that DV is a big-endian PCM - if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00) - pcm[of*2+1] = 0; - } else { /* 12bit quantization */ - lc = ((uint16_t)frame[d] << 4) | - ((uint16_t)frame[d+2] >> 4); - rc = ((uint16_t)frame[d+1] << 4) | - ((uint16_t)frame[d+2] & 0x0f); - lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc)); - rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc)); - - of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride; - if (of*2 >= size) - continue; - - pcm[of*2] = lc & 0xff; // FIXME: maybe we have to admit - pcm[of*2+1] = lc >> 8; // that DV is a big-endian PCM - of = sys->audio_shuffle[i%half_ch+half_ch][j] + - (d - 8) / 3 * sys->audio_stride; - pcm[of*2] = rc & 0xff; // FIXME: maybe we have to admit - pcm[of*2+1] = rc >> 8; // that DV is a big-endian PCM - ++d; - } - } - - frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ - } - } - - /* next stereo channel (50Mbps and 100Mbps only) */ - pcm = ppcm[ipcm++]; - if (!pcm) - break; - } - - return size; -} - -static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame) -{ - const uint8_t* as_pack; - int freq, stype, smpls, quant, i, ach; - - as_pack = dv_extract_pack(frame, dv_audio_source); - if (!as_pack || !c->sys) { /* No audio ? */ - c->ach = 0; - return 0; - } - - smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */ - freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */ - stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */ - quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ - - /* note: ach counts PAIRS of channels (i.e. stereo channels) */ - ach = ((int[4]){ 1, 0, 2, 4})[stype]; - if (ach == 1 && quant && freq == 2) - ach = 2; - - /* Dynamic handling of the audio streams in DV */ - for (i = 0; i < ach; i++) { - if (!c->ast[i]) { - c->ast[i] = av_new_stream(c->fctx, 0); - if (!c->ast[i]) - break; - av_set_pts_info(c->ast[i], 64, 1, 30000); - c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO; - c->ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE; - - av_init_packet(&c->audio_pkt[i]); - c->audio_pkt[i].size = 0; - c->audio_pkt[i].data = c->audio_buf[i]; - c->audio_pkt[i].stream_index = c->ast[i]->index; - c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY; - } - c->ast[i]->codec->sample_rate = dv_audio_frequency[freq]; - c->ast[i]->codec->channels = 2; - c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16; - c->ast[i]->start_time = 0; - } - c->ach = i; - - return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */; -} - -static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame) -{ - const uint8_t* vsc_pack; - AVCodecContext* avctx; - int apt, is16_9; - int size = 0; - - if (c->sys) { - avctx = c->vst->codec; - - av_set_pts_info(c->vst, 64, c->sys->time_base.num, - c->sys->time_base.den); - avctx->time_base= c->sys->time_base; - if (!avctx->width){ - avctx->width = c->sys->width; - avctx->height = c->sys->height; - } - avctx->pix_fmt = c->sys->pix_fmt; - - /* finding out SAR is a little bit messy */ - vsc_pack = dv_extract_pack(frame, dv_video_control); - apt = frame[4] & 0x07; - is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || - (!apt && (vsc_pack[2] & 0x07) == 0x07))); - c->vst->sample_aspect_ratio = c->sys->sar[is16_9]; - avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1}, - c->sys->time_base); - size = c->sys->frame_size; - } - return size; -} - -/* - * The following 3 functions constitute our interface to the world - */ - -DVDemuxContext* dv_init_demux(AVFormatContext *s) -{ - DVDemuxContext *c; - - c = av_mallocz(sizeof(DVDemuxContext)); - if (!c) - return NULL; - - c->vst = av_new_stream(s, 0); - if (!c->vst) { - av_free(c); - return NULL; - } - - c->sys = NULL; - c->fctx = s; - memset(c->ast, 0, sizeof(c->ast)); - c->ach = 0; - c->frames = 0; - c->abytes = 0; - - c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - c->vst->codec->codec_id = CODEC_ID_DVVIDEO; - c->vst->codec->bit_rate = 25000000; - c->vst->start_time = 0; - - return c; -} - -int dv_get_packet(DVDemuxContext *c, AVPacket *pkt) -{ - int size = -1; - int i; - - for (i = 0; i < c->ach; i++) { - if (c->ast[i] && c->audio_pkt[i].size) { - *pkt = c->audio_pkt[i]; - c->audio_pkt[i].size = 0; - size = pkt->size; - break; - } - } - - return size; -} - -int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, - uint8_t* buf, int buf_size) -{ - int size, i; - uint8_t *ppcm[4] = {0}; - - if (buf_size < DV_PROFILE_BYTES || - !(c->sys = ff_dv_frame_profile(c->sys, buf, buf_size)) || - buf_size < c->sys->frame_size) { - return -1; /* Broken frame, or not enough data */ - } - - /* Queueing audio packet */ - /* FIXME: in case of no audio/bad audio we have to do something */ - size = dv_extract_audio_info(c, buf); - for (i = 0; i < c->ach; i++) { - c->audio_pkt[i].size = size; - c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate; - ppcm[i] = c->audio_buf[i]; - } - dv_extract_audio(buf, ppcm, c->sys); - - /* We work with 720p frames split in half, thus even frames have - * channels 0,1 and odd 2,3. */ - if (c->sys->height == 720) { - if (buf[1] & 0x0C) { - c->audio_pkt[2].size = c->audio_pkt[3].size = 0; - } else { - c->audio_pkt[0].size = c->audio_pkt[1].size = 0; - c->abytes += size; - } - } else { - c->abytes += size; - } - - /* Now it's time to return video packet */ - size = dv_extract_video_info(c, buf); - av_init_packet(pkt); - pkt->data = buf; - pkt->size = size; - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->stream_index = c->vst->id; - pkt->pts = c->frames; - - c->frames++; - - return size; -} - -static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c, - int64_t timestamp, int flags) -{ - // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk) - const DVprofile* sys = ff_dv_codec_profile(c->vst->codec); - int64_t offset; - int64_t size = url_fsize(s->pb); - int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size; - - offset = sys->frame_size * timestamp; - - if (size >= 0 && offset > max_offset) offset = max_offset; - else if (offset < 0) offset = 0; - - return offset; -} - -void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset) -{ - c->frames= frame_offset; - if (c->ach) - c->abytes= av_rescale_q(c->frames, c->sys->time_base, - (AVRational){8, c->ast[0]->codec->bit_rate}); - c->audio_pkt[0].size = c->audio_pkt[1].size = 0; - c->audio_pkt[2].size = c->audio_pkt[3].size = 0; -} - -/************************************************************ - * Implementation of the easiest DV storage of all -- raw DV. - ************************************************************/ - -typedef struct RawDVContext { - DVDemuxContext* dv_demux; - uint8_t buf[DV_MAX_FRAME_SIZE]; -} RawDVContext; - -static int dv_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - unsigned state, marker_pos = 0; - RawDVContext *c = s->priv_data; - - c->dv_demux = dv_init_demux(s); - if (!c->dv_demux) - return -1; - - state = get_be32(s->pb); - while ((state & 0xffffff7f) != 0x1f07003f) { - if (url_feof(s->pb)) { - av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n"); - return -1; - } - if (state == 0x003f0700 || state == 0xff3f0700) - marker_pos = url_ftell(s->pb); - if (state == 0xff3f0701 && url_ftell(s->pb) - marker_pos == 80) { - url_fseek(s->pb, -163, SEEK_CUR); - state = get_be32(s->pb); - break; - } - state = (state << 8) | get_byte(s->pb); - } - AV_WB32(c->buf, state); - - if (get_buffer(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 || - url_fseek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0) - return AVERROR(EIO); - - c->dv_demux->sys = ff_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES); - if (!c->dv_demux->sys) { - av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n"); - return -1; - } - - s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1}, - c->dv_demux->sys->time_base); - - return 0; -} - - -static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size; - RawDVContext *c = s->priv_data; - - size = dv_get_packet(c->dv_demux, pkt); - - if (size < 0) { - if (!c->dv_demux->sys) - return AVERROR(EIO); - size = c->dv_demux->sys->frame_size; - if (get_buffer(s->pb, c->buf, size) <= 0) - return AVERROR(EIO); - - size = dv_produce_packet(c->dv_demux, pkt, c->buf, size); - } - - return size; -} - -static int dv_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - RawDVContext *r = s->priv_data; - DVDemuxContext *c = r->dv_demux; - int64_t offset = dv_frame_offset(s, c, timestamp, flags); - - dv_offset_reset(c, offset / c->sys->frame_size); - - offset = url_fseek(s->pb, offset, SEEK_SET); - return (offset < 0) ? offset : 0; -} - -static int dv_read_close(AVFormatContext *s) -{ - RawDVContext *c = s->priv_data; - av_free(c->dv_demux); - return 0; -} - -static int dv_probe(AVProbeData *p) -{ - unsigned state, marker_pos = 0; - int i; - int matches = 0; - int secondary_matches = 0; - - if (p->buf_size < 5) - return 0; - - state = AV_RB32(p->buf); - for (i = 4; i < p->buf_size; i++) { - if ((state & 0xffffff7f) == 0x1f07003f) - matches++; - // any section header, also with seq/chan num != 0, - // should appear around every 12000 bytes, at least 10 per frame - if ((state & 0xff07ff7f) == 0x1f07003f) - secondary_matches++; - if (state == 0x003f0700 || state == 0xff3f0700) - marker_pos = i; - if (state == 0xff3f0701 && i - marker_pos == 80) - matches++; - state = (state << 8) | p->buf[i]; - } - - if (matches && p->buf_size / matches < 1024*1024) { - if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000)) - return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match - return AVPROBE_SCORE_MAX/4; - } - return 0; -} - -#if CONFIG_DV_DEMUXER -AVInputFormat dv_demuxer = { - "dv", - NULL_IF_CONFIG_SMALL("DV video format"), - sizeof(RawDVContext), - dv_probe, - dv_read_header, - dv_read_packet, - dv_read_close, - dv_read_seek, - .extensions = "dv,dif", -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/dv.h b/tizen/distrib/ffmpeg/libavformat/dv.h deleted file mode 100644 index ae16bef..0000000 --- a/tizen/distrib/ffmpeg/libavformat/dv.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * General DV muxer/demuxer - * Copyright (c) 2003 Roman Shaposhnik - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * Raw DV format - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_DV_H -#define AVFORMAT_DV_H - -#include "avformat.h" - -typedef struct DVDemuxContext DVDemuxContext; -DVDemuxContext* dv_init_demux(AVFormatContext* s); -int dv_get_packet(DVDemuxContext*, AVPacket *); -int dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int); -void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset); - -typedef struct DVMuxContext DVMuxContext; -DVMuxContext* dv_init_mux(AVFormatContext* s); -int dv_assemble_frame(DVMuxContext *c, AVStream*, uint8_t*, int, uint8_t**); -void dv_delete_mux(DVMuxContext*); - -#endif /* AVFORMAT_DV_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/dvenc.c b/tizen/distrib/ffmpeg/libavformat/dvenc.c deleted file mode 100644 index 0176ac9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/dvenc.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * General DV muxer/demuxer - * Copyright (c) 2003 Roman Shaposhnik - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * Raw DV format - * Copyright (c) 2002 Fabrice Bellard - * - * 50 Mbps (DVCPRO50) support - * Copyright (c) 2006 Daniel Maas - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include - -#include "avformat.h" -#include "internal.h" -#include "libavcodec/dvdata.h" -#include "dv.h" -#include "libavutil/fifo.h" - -struct DVMuxContext { - const DVprofile* sys; /* current DV profile, e.g.: 525/60, 625/50 */ - int n_ast; /* number of stereo audio streams (up to 2) */ - AVStream *ast[2]; /* stereo audio streams */ - AVFifoBuffer *audio_data[2]; /* FIFO for storing excessive amounts of PCM */ - int frames; /* current frame number */ - time_t start_time; /* recording start time */ - int has_audio; /* frame under contruction has audio */ - int has_video; /* frame under contruction has video */ - uint8_t frame_buf[DV_MAX_FRAME_SIZE]; /* frame under contruction */ -}; - -static const int dv_aaux_packs_dist[12][9] = { - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, -}; - -static int dv_audio_frame_size(const DVprofile* sys, int frame) -{ - return sys->audio_samples_dist[frame % (sizeof(sys->audio_samples_dist) / - sizeof(sys->audio_samples_dist[0]))]; -} - -static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t* buf, ...) -{ - struct tm tc; - time_t ct; - int ltc_frame; - va_list ap; - - buf[0] = (uint8_t)pack_id; - switch (pack_id) { - case dv_timecode: - ct = (time_t)av_rescale_rnd(c->frames, c->sys->time_base.num, - c->sys->time_base.den, AV_ROUND_DOWN); - brktimegm(ct, &tc); - /* - * LTC drop-frame frame counter drops two frames (0 and 1) every - * minute, unless it is exactly divisible by 10 - */ - ltc_frame = (c->frames + 2 * ct / 60 - 2 * ct / 600) % c->sys->ltc_divisor; - buf[1] = (0 << 7) | /* color frame: 0 - unsync; 1 - sync mode */ - (1 << 6) | /* drop frame timecode: 0 - nondrop; 1 - drop */ - ((ltc_frame / 10) << 4) | /* tens of frames */ - (ltc_frame % 10); /* units of frames */ - buf[2] = (1 << 7) | /* biphase mark polarity correction: 0 - even; 1 - odd */ - ((tc.tm_sec / 10) << 4) | /* tens of seconds */ - (tc.tm_sec % 10); /* units of seconds */ - buf[3] = (1 << 7) | /* binary group flag BGF0 */ - ((tc.tm_min / 10) << 4) | /* tens of minutes */ - (tc.tm_min % 10); /* units of minutes */ - buf[4] = (1 << 7) | /* binary group flag BGF2 */ - (1 << 6) | /* binary group flag BGF1 */ - ((tc.tm_hour / 10) << 4) | /* tens of hours */ - (tc.tm_hour % 10); /* units of hours */ - break; - case dv_audio_source: /* AAUX source pack */ - va_start(ap, buf); - buf[1] = (1 << 7) | /* locked mode -- SMPTE only supports locked mode */ - (1 << 6) | /* reserved -- always 1 */ - (dv_audio_frame_size(c->sys, c->frames) - - c->sys->audio_min_samples[0]); - /* # of samples */ - buf[2] = (0 << 7) | /* multi-stereo */ - (0 << 5) | /* #of audio channels per block: 0 -- 1 channel */ - (0 << 4) | /* pair bit: 0 -- one pair of channels */ - !!va_arg(ap, int); /* audio mode */ - buf[3] = (1 << 7) | /* res */ - (1 << 6) | /* multi-language flag */ - (c->sys->dsf << 5) | /* system: 60fields/50fields */ - (c->sys->n_difchan & 2); /* definition: 0 -- 25Mbps, 2 -- 50Mbps */ - buf[4] = (1 << 7) | /* emphasis: 1 -- off */ - (0 << 6) | /* emphasis time constant: 0 -- reserved */ - (0 << 3) | /* frequency: 0 -- 48kHz, 1 -- 44,1kHz, 2 -- 32kHz */ - 0; /* quantization: 0 -- 16bit linear, 1 -- 12bit nonlinear */ - va_end(ap); - break; - case dv_audio_control: - buf[1] = (0 << 6) | /* copy protection: 0 -- unrestricted */ - (1 << 4) | /* input source: 1 -- digital input */ - (3 << 2) | /* compression: 3 -- no information */ - 0; /* misc. info/SMPTE emphasis off */ - buf[2] = (1 << 7) | /* recording start point: 1 -- no */ - (1 << 6) | /* recording end point: 1 -- no */ - (1 << 3) | /* recording mode: 1 -- original */ - 7; - buf[3] = (1 << 7) | /* direction: 1 -- forward */ - (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0x20 : /* speed */ - c->sys->ltc_divisor * 4); - buf[4] = (1 << 7) | /* reserved -- always 1 */ - 0x7f; /* genre category */ - break; - case dv_audio_recdate: - case dv_video_recdate: /* VAUX recording date */ - ct = c->start_time + av_rescale_rnd(c->frames, c->sys->time_base.num, - c->sys->time_base.den, AV_ROUND_DOWN); - brktimegm(ct, &tc); - buf[1] = 0xff; /* ds, tm, tens of time zone, units of time zone */ - /* 0xff is very likely to be "unknown" */ - buf[2] = (3 << 6) | /* reserved -- always 1 */ - ((tc.tm_mday / 10) << 4) | /* Tens of day */ - (tc.tm_mday % 10); /* Units of day */ - buf[3] = /* we set high 4 bits to 0, shouldn't we set them to week? */ - ((tc.tm_mon / 10) << 4) | /* Tens of month */ - (tc.tm_mon % 10); /* Units of month */ - buf[4] = (((tc.tm_year % 100) / 10) << 4) | /* Tens of year */ - (tc.tm_year % 10); /* Units of year */ - break; - case dv_audio_rectime: /* AAUX recording time */ - case dv_video_rectime: /* VAUX recording time */ - ct = c->start_time + av_rescale_rnd(c->frames, c->sys->time_base.num, - c->sys->time_base.den, AV_ROUND_DOWN); - brktimegm(ct, &tc); - buf[1] = (3 << 6) | /* reserved -- always 1 */ - 0x3f; /* tens of frame, units of frame: 0x3f - "unknown" ? */ - buf[2] = (1 << 7) | /* reserved -- always 1 */ - ((tc.tm_sec / 10) << 4) | /* Tens of seconds */ - (tc.tm_sec % 10); /* Units of seconds */ - buf[3] = (1 << 7) | /* reserved -- always 1 */ - ((tc.tm_min / 10) << 4) | /* Tens of minutes */ - (tc.tm_min % 10); /* Units of minutes */ - buf[4] = (3 << 6) | /* reserved -- always 1 */ - ((tc.tm_hour / 10) << 4) | /* Tens of hours */ - (tc.tm_hour % 10); /* Units of hours */ - break; - default: - buf[1] = buf[2] = buf[3] = buf[4] = 0xff; - } - return 5; -} - -static void dv_inject_audio(DVMuxContext *c, int channel, uint8_t* frame_ptr) -{ - int i, j, d, of, size; - size = 4 * dv_audio_frame_size(c->sys, c->frames); - frame_ptr += channel * c->sys->difseg_size * 150 * 80; - for (i = 0; i < c->sys->difseg_size; i++) { - frame_ptr += 6 * 80; /* skip DIF segment header */ - for (j = 0; j < 9; j++) { - dv_write_pack(dv_aaux_packs_dist[i][j], c, &frame_ptr[3], i >= c->sys->difseg_size/2); - for (d = 8; d < 80; d+=2) { - of = c->sys->audio_shuffle[i][j] + (d - 8)/2 * c->sys->audio_stride; - if (of*2 >= size) - continue; - - frame_ptr[d] = av_fifo_peek(c->audio_data[channel], of*2+1); // FIXME: maybe we have to admit - frame_ptr[d+1] = av_fifo_peek(c->audio_data[channel], of*2); // that DV is a big-endian PCM - } - frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ - } - } -} - -static void dv_inject_metadata(DVMuxContext *c, uint8_t* frame) -{ - int j, k; - uint8_t* buf; - - for (buf = frame; buf < frame + c->sys->frame_size; buf += 150 * 80) { - /* DV subcode: 2nd and 3d DIFs */ - for (j = 80; j < 80 * 3; j += 80) { - for (k = 6; k < 6 * 8; k += 8) - dv_write_pack(dv_timecode, c, &buf[j+k]); - - if (((long)(buf-frame)/(c->sys->frame_size/(c->sys->difseg_size*c->sys->n_difchan))%c->sys->difseg_size) > 5) { /* FIXME: is this really needed ? */ - dv_write_pack(dv_video_recdate, c, &buf[j+14]); - dv_write_pack(dv_video_rectime, c, &buf[j+22]); - dv_write_pack(dv_video_recdate, c, &buf[j+38]); - dv_write_pack(dv_video_rectime, c, &buf[j+46]); - } - } - - /* DV VAUX: 4th, 5th and 6th 3DIFs */ - for (j = 80*3 + 3; j < 80*6; j += 80) { - dv_write_pack(dv_video_recdate, c, &buf[j+5*2]); - dv_write_pack(dv_video_rectime, c, &buf[j+5*3]); - dv_write_pack(dv_video_recdate, c, &buf[j+5*11]); - dv_write_pack(dv_video_rectime, c, &buf[j+5*12]); - } - } -} - -/* - * The following 3 functions constitute our interface to the world - */ - -int dv_assemble_frame(DVMuxContext *c, AVStream* st, - uint8_t* data, int data_size, uint8_t** frame) -{ - int i, reqasize; - - *frame = &c->frame_buf[0]; - reqasize = 4 * dv_audio_frame_size(c->sys, c->frames); - - switch (st->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - /* FIXME: we have to have more sensible approach than this one */ - if (c->has_video) - av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient audio data or severe sync problem.\n", c->frames); - - memcpy(*frame, data, c->sys->frame_size); - c->has_video = 1; - break; - case AVMEDIA_TYPE_AUDIO: - for (i = 0; i < c->n_ast && st != c->ast[i]; i++); - - /* FIXME: we have to have more sensible approach than this one */ - if (av_fifo_size(c->audio_data[i]) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) - av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames); - av_fifo_generic_write(c->audio_data[i], data, data_size, NULL); - - /* Let us see if we've got enough audio for one DV frame. */ - c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i); - - break; - default: - break; - } - - /* Let us see if we have enough data to construct one DV frame. */ - if (c->has_video == 1 && c->has_audio + 1 == 1 << c->n_ast) { - dv_inject_metadata(c, *frame); - c->has_audio = 0; - for (i=0; i < c->n_ast; i++) { - dv_inject_audio(c, i, *frame); - av_fifo_drain(c->audio_data[i], reqasize); - c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i); - } - - c->has_video = 0; - - c->frames++; - - return c->sys->frame_size; - } - - return 0; -} - -DVMuxContext* dv_init_mux(AVFormatContext* s) -{ - DVMuxContext *c = s->priv_data; - AVStream *vst = NULL; - int i; - - /* we support at most 1 video and 2 audio streams */ - if (s->nb_streams > 3) - return NULL; - - c->n_ast = 0; - c->ast[0] = c->ast[1] = NULL; - - /* We have to sort out where audio and where video stream is */ - for (i=0; inb_streams; i++) { - switch (s->streams[i]->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if (vst) return NULL; - vst = s->streams[i]; - break; - case AVMEDIA_TYPE_AUDIO: - if (c->n_ast > 1) return NULL; - c->ast[c->n_ast++] = s->streams[i]; - break; - default: - goto bail_out; - } - } - - /* Some checks -- DV format is very picky about its incoming streams */ - if (!vst || vst->codec->codec_id != CODEC_ID_DVVIDEO) - goto bail_out; - for (i=0; in_ast; i++) { - if (c->ast[i] && (c->ast[i]->codec->codec_id != CODEC_ID_PCM_S16LE || - c->ast[i]->codec->sample_rate != 48000 || - c->ast[i]->codec->channels != 2)) - goto bail_out; - } - c->sys = ff_dv_codec_profile(vst->codec); - if (!c->sys) - goto bail_out; - - if ((c->n_ast > 1) && (c->sys->n_difchan < 2)) { - /* only 1 stereo pair is allowed in 25Mbps mode */ - goto bail_out; - } - - /* Ok, everything seems to be in working order */ - c->frames = 0; - c->has_audio = 0; - c->has_video = 0; - c->start_time = (time_t)s->timestamp; - - for (i=0; i < c->n_ast; i++) { - if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*AVCODEC_MAX_AUDIO_FRAME_SIZE))) { - while (i > 0) { - i--; - av_fifo_free(c->audio_data[i]); - } - goto bail_out; - } - } - - return c; - -bail_out: - return NULL; -} - -void dv_delete_mux(DVMuxContext *c) -{ - int i; - for (i=0; i < c->n_ast; i++) - av_fifo_free(c->audio_data[i]); -} - -#if CONFIG_DV_MUXER -static int dv_write_header(AVFormatContext *s) -{ - if (!dv_init_mux(s)) { - av_log(s, AV_LOG_ERROR, "Can't initialize DV format!\n" - "Make sure that you supply exactly two streams:\n" - " video: 25fps or 29.97fps, audio: 2ch/48kHz/PCM\n" - " (50Mbps allows an optional second audio stream)\n"); - return -1; - } - return 0; -} - -static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - uint8_t* frame; - int fsize; - - fsize = dv_assemble_frame(s->priv_data, s->streams[pkt->stream_index], - pkt->data, pkt->size, &frame); - if (fsize > 0) { - put_buffer(s->pb, frame, fsize); - put_flush_packet(s->pb); - } - return 0; -} - -/* - * We might end up with some extra A/V data without matching counterpart. - * E.g. video data without enough audio to write the complete frame. - * Currently we simply drop the last frame. I don't know whether this - * is the best strategy of all - */ -static int dv_write_trailer(struct AVFormatContext *s) -{ - dv_delete_mux(s->priv_data); - return 0; -} - -AVOutputFormat dv_muxer = { - "dv", - NULL_IF_CONFIG_SMALL("DV video format"), - NULL, - "dv", - sizeof(DVMuxContext), - CODEC_ID_PCM_S16LE, - CODEC_ID_DVVIDEO, - dv_write_header, - dv_write_packet, - dv_write_trailer, -}; -#endif /* CONFIG_DV_MUXER */ diff --git a/tizen/distrib/ffmpeg/libavformat/dxa.c b/tizen/distrib/ffmpeg/libavformat/dxa.c deleted file mode 100644 index c00c917..0000000 --- a/tizen/distrib/ffmpeg/libavformat/dxa.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * DXA demuxer - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "riff.h" - -#define DXA_EXTRA_SIZE 9 - -typedef struct{ - int frames; - int has_sound; - int bpc; - uint32_t bytes_left; - int64_t wavpos, vidpos; - int readvid; -}DXAContext; - -static int dxa_probe(AVProbeData *p) -{ - int w, h; - if (p->buf_size < 15) - return 0; - w = AV_RB16(p->buf + 11); - h = AV_RB16(p->buf + 13); - /* check file header */ - if (p->buf[0] == 'D' && p->buf[1] == 'E' && - p->buf[2] == 'X' && p->buf[3] == 'A' && - w && w <= 2048 && h && h <= 2048) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int dxa_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - DXAContext *c = s->priv_data; - AVStream *st, *ast; - uint32_t tag; - int32_t fps; - int w, h; - int num, den; - int flags; - - tag = get_le32(pb); - if (tag != MKTAG('D', 'E', 'X', 'A')) - return -1; - flags = get_byte(pb); - c->frames = get_be16(pb); - if(!c->frames){ - av_log(s, AV_LOG_ERROR, "File contains no frames ???\n"); - return -1; - } - - fps = get_be32(pb); - if(fps > 0){ - den = 1000; - num = fps; - }else if (fps < 0){ - den = 100000; - num = -fps; - }else{ - den = 10; - num = 1; - } - w = get_be16(pb); - h = get_be16(pb); - c->has_sound = 0; - - st = av_new_stream(s, 0); - if (!st) - return -1; - - // Parse WAV data header - if(get_le32(pb) == MKTAG('W', 'A', 'V', 'E')){ - uint32_t size, fsize; - c->has_sound = 1; - size = get_be32(pb); - c->vidpos = url_ftell(pb) + size; - url_fskip(pb, 16); - fsize = get_le32(pb); - - ast = av_new_stream(s, 0); - if (!ast) - return -1; - ff_get_wav_header(pb, ast->codec, fsize); - // find 'data' chunk - while(url_ftell(pb) < c->vidpos && !url_feof(pb)){ - tag = get_le32(pb); - fsize = get_le32(pb); - if(tag == MKTAG('d', 'a', 't', 'a')) break; - url_fskip(pb, fsize); - } - c->bpc = (fsize + c->frames - 1) / c->frames; - if(ast->codec->block_align) - c->bpc = ((c->bpc + ast->codec->block_align - 1) / ast->codec->block_align) * ast->codec->block_align; - c->bytes_left = fsize; - c->wavpos = url_ftell(pb); - url_fseek(pb, c->vidpos, SEEK_SET); - } - - /* now we are ready: build format streams */ - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DXA; - st->codec->width = w; - st->codec->height = h; - av_reduce(&den, &num, den, num, (1UL<<31)-1); - av_set_pts_info(st, 33, num, den); - /* flags & 0x80 means that image is interlaced, - * flags & 0x40 means that image has double height - * either way set true height - */ - if(flags & 0xC0){ - st->codec->height >>= 1; - } - c->readvid = !c->has_sound; - c->vidpos = url_ftell(pb); - s->start_time = 0; - s->duration = (int64_t)c->frames * AV_TIME_BASE * num / den; - av_log(s, AV_LOG_DEBUG, "%d frame(s)\n",c->frames); - - return 0; -} - -static int dxa_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - DXAContext *c = s->priv_data; - int ret; - uint32_t size; - uint8_t buf[DXA_EXTRA_SIZE], pal[768+4]; - int pal_size = 0; - - if(!c->readvid && c->has_sound && c->bytes_left){ - c->readvid = 1; - url_fseek(s->pb, c->wavpos, SEEK_SET); - size = FFMIN(c->bytes_left, c->bpc); - ret = av_get_packet(s->pb, pkt, size); - pkt->stream_index = 1; - if(ret != size) - return AVERROR(EIO); - c->bytes_left -= size; - c->wavpos = url_ftell(s->pb); - return 0; - } - url_fseek(s->pb, c->vidpos, SEEK_SET); - while(!url_feof(s->pb) && c->frames){ - get_buffer(s->pb, buf, 4); - switch(AV_RL32(buf)){ - case MKTAG('N', 'U', 'L', 'L'): - if(av_new_packet(pkt, 4 + pal_size) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 0; - if(pal_size) memcpy(pkt->data, pal, pal_size); - memcpy(pkt->data + pal_size, buf, 4); - c->frames--; - c->vidpos = url_ftell(s->pb); - c->readvid = 0; - return 0; - case MKTAG('C', 'M', 'A', 'P'): - pal_size = 768+4; - memcpy(pal, buf, 4); - get_buffer(s->pb, pal + 4, 768); - break; - case MKTAG('F', 'R', 'A', 'M'): - get_buffer(s->pb, buf + 4, DXA_EXTRA_SIZE - 4); - size = AV_RB32(buf + 5); - if(size > 0xFFFFFF){ - av_log(s, AV_LOG_ERROR, "Frame size is too big: %d\n", size); - return -1; - } - if(av_new_packet(pkt, size + DXA_EXTRA_SIZE + pal_size) < 0) - return AVERROR(ENOMEM); - memcpy(pkt->data + pal_size, buf, DXA_EXTRA_SIZE); - ret = get_buffer(s->pb, pkt->data + DXA_EXTRA_SIZE + pal_size, size); - if(ret != size){ - av_free_packet(pkt); - return AVERROR(EIO); - } - if(pal_size) memcpy(pkt->data, pal, pal_size); - pkt->stream_index = 0; - c->frames--; - c->vidpos = url_ftell(s->pb); - c->readvid = 0; - return 0; - default: - av_log(s, AV_LOG_ERROR, "Unknown tag %c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]); - return -1; - } - } - return AVERROR(EIO); -} - -AVInputFormat dxa_demuxer = { - "dxa", - NULL_IF_CONFIG_SMALL("DXA"), - sizeof(DXAContext), - dxa_probe, - dxa_read_header, - dxa_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/eacdata.c b/tizen/distrib/ffmpeg/libavformat/eacdata.c deleted file mode 100644 index 32c3343..0000000 --- a/tizen/distrib/ffmpeg/libavformat/eacdata.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Electronic Arts .cdata file Demuxer - * Copyright (c) 2007 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts cdata Format Demuxer - * by Peter Ross (pross@xvid.org) - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=EA_Command_And_Conquer_3_Audio_Codec - */ - -#include "avformat.h" - -typedef struct { - unsigned int channels; - unsigned int audio_pts; -} CdataDemuxContext; - -static int cdata_probe(AVProbeData *p) -{ - const uint8_t *b = p->buf; - - if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C)) - return AVPROBE_SCORE_MAX/8; - return 0; -} - -static int cdata_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - CdataDemuxContext *cdata = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned int sample_rate, header; - AVStream *st; - - header = get_be16(pb); - switch (header) { - case 0x0400: cdata->channels = 1; break; - case 0x0404: cdata->channels = 2; break; - case 0x040C: cdata->channels = 4; break; - default: - av_log(s, AV_LOG_INFO, "unknown header 0x%04x\n", header); - return -1; - }; - - sample_rate = get_be16(pb); - url_fskip(pb, 12); - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->codec_id = CODEC_ID_ADPCM_EA_XAS; - st->codec->channels = cdata->channels; - st->codec->sample_rate = sample_rate; - av_set_pts_info(st, 64, 1, sample_rate); - - cdata->audio_pts = 0; - return 0; -} - -static int cdata_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - CdataDemuxContext *cdata = s->priv_data; - int packet_size = 76*cdata->channels; - - int ret = av_get_packet(s->pb, pkt, packet_size); - if (ret < 0) - return ret; - pkt->pts = cdata->audio_pts++; - return 0; -} - -AVInputFormat ea_cdata_demuxer = { - "ea_cdata", - NULL_IF_CONFIG_SMALL("Electronic Arts cdata"), - sizeof(CdataDemuxContext), - cdata_probe, - cdata_read_header, - cdata_read_packet, - .extensions = "cdata", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/electronicarts.c b/tizen/distrib/ffmpeg/libavformat/electronicarts.c deleted file mode 100644 index 86d7f91..0000000 --- a/tizen/distrib/ffmpeg/libavformat/electronicarts.c +++ /dev/null @@ -1,567 +0,0 @@ -/* Electronic Arts Multimedia File Demuxer - * Copyright (c) 2004 The ffmpeg Project - * Copyright (c) 2006-2008 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Electronic Arts Multimedia file demuxer (WVE/UV2/etc.) - * by Robin Kay (komadori at gekkou.co.uk) - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define SCHl_TAG MKTAG('S', 'C', 'H', 'l') -#define SEAD_TAG MKTAG('S', 'E', 'A', 'D') /* Sxxx header */ -#define SNDC_TAG MKTAG('S', 'N', 'D', 'C') /* Sxxx data */ -#define SEND_TAG MKTAG('S', 'E', 'N', 'D') /* Sxxx end */ -#define SHEN_TAG MKTAG('S', 'H', 'E', 'N') /* SxEN header */ -#define SDEN_TAG MKTAG('S', 'D', 'E', 'N') /* SxEN data */ -#define SEEN_TAG MKTAG('S', 'E', 'E', 'N') /* SxEN end */ -#define ISNh_TAG MKTAG('1', 'S', 'N', 'h') /* 1SNx header */ -#define EACS_TAG MKTAG('E', 'A', 'C', 'S') -#define ISNd_TAG MKTAG('1', 'S', 'N', 'd') /* 1SNx data */ -#define ISNe_TAG MKTAG('1', 'S', 'N', 'e') /* 1SNx end */ -#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0) -#define GSTR_TAG MKTAG('G', 'S', 'T', 'R') -#define SCDl_TAG MKTAG('S', 'C', 'D', 'l') -#define SCEl_TAG MKTAG('S', 'C', 'E', 'l') -#define kVGT_TAG MKTAG('k', 'V', 'G', 'T') /* TGV i-frame */ -#define fVGT_TAG MKTAG('f', 'V', 'G', 'T') /* TGV p-frame */ -#define mTCD_TAG MKTAG('m', 'T', 'C', 'D') /* MDEC */ -#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */ -#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD p-frame */ -#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */ -#define MPCh_TAG MKTAG('M', 'P', 'C', 'h') /* MPEG2 */ -#define TGQs_TAG MKTAG('T', 'G', 'Q', 's') /* TGQ i-frame (appears in .TGQ files) */ -#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T') /* TGQ i-frame (appears in .UV files) */ -#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T') /* TQI/UV2 i-frame (.UV2/.WVE) */ -#define MVhd_TAG MKTAG('M', 'V', 'h', 'd') -#define MV0K_TAG MKTAG('M', 'V', '0', 'K') -#define MV0F_TAG MKTAG('M', 'V', '0', 'F') -#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */ -#define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV i-frame */ - -typedef struct EaDemuxContext { - int big_endian; - - enum CodecID video_codec; - AVRational time_base; - int width, height; - int video_stream_index; - - enum CodecID audio_codec; - int audio_stream_index; - int audio_frame_counter; - - int bytes; - int sample_rate; - int num_channels; - int num_samples; -} EaDemuxContext; - -static uint32_t read_arbitary(ByteIOContext *pb) { - uint8_t size, byte; - int i; - uint32_t word; - - size = get_byte(pb); - - word = 0; - for (i = 0; i < size; i++) { - byte = get_byte(pb); - word <<= 8; - word |= byte; - } - - return word; -} - -/* - * Process PT/GSTR sound header - * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx - */ -static int process_audio_header_elements(AVFormatContext *s) -{ - int inHeader = 1; - EaDemuxContext *ea = s->priv_data; - ByteIOContext *pb = s->pb; - int compression_type = -1, revision = -1, revision2 = -1; - - ea->bytes = 2; - ea->sample_rate = -1; - ea->num_channels = 1; - - while (inHeader) { - int inSubheader; - uint8_t byte; - byte = get_byte(pb); - - switch (byte) { - case 0xFD: - av_log (s, AV_LOG_DEBUG, "entered audio subheader\n"); - inSubheader = 1; - while (inSubheader) { - uint8_t subbyte; - subbyte = get_byte(pb); - - switch (subbyte) { - case 0x80: - revision = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "revision (element 0x80) set to 0x%08x\n", revision); - break; - case 0x82: - ea->num_channels = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels); - break; - case 0x83: - compression_type = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "compression_type (element 0x83) set to 0x%08x\n", compression_type); - break; - case 0x84: - ea->sample_rate = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "sample_rate (element 0x84) set to %i\n", ea->sample_rate); - break; - case 0x85: - ea->num_samples = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples); - break; - case 0x8A: - av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); - av_log (s, AV_LOG_DEBUG, "exited audio subheader\n"); - inSubheader = 0; - break; - case 0xA0: - revision2 = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "revision2 (element 0xA0) set to 0x%08x\n", revision2); - break; - case 0xFF: - av_log (s, AV_LOG_DEBUG, "end of header block reached (within audio subheader)\n"); - inSubheader = 0; - inHeader = 0; - break; - default: - av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); - break; - } - } - break; - case 0xFF: - av_log (s, AV_LOG_DEBUG, "end of header block reached\n"); - inHeader = 0; - break; - default: - av_log (s, AV_LOG_DEBUG, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb)); - break; - } - } - - switch (compression_type) { - case 0: ea->audio_codec = CODEC_ID_PCM_S16LE; break; - case 7: ea->audio_codec = CODEC_ID_ADPCM_EA; break; - case -1: - switch (revision) { - case 1: ea->audio_codec = CODEC_ID_ADPCM_EA_R1; break; - case 2: ea->audio_codec = CODEC_ID_ADPCM_EA_R2; break; - case 3: ea->audio_codec = CODEC_ID_ADPCM_EA_R3; break; - case -1: break; - default: - av_log(s, AV_LOG_ERROR, "unsupported stream type; revision=%i\n", revision); - return 0; - } - switch (revision2) { - case 8: ea->audio_codec = CODEC_ID_PCM_S16LE_PLANAR; break; - case 10: ea->audio_codec = CODEC_ID_ADPCM_EA_R2; break; - case 16: ea->audio_codec = CODEC_ID_MP3; break; - case -1: break; - default: - ea->audio_codec = CODEC_ID_NONE; - av_log(s, AV_LOG_ERROR, "unsupported stream type; revision2=%i\n", revision2); - return 0; - } - break; - default: - av_log(s, AV_LOG_ERROR, "unsupported stream type; compression_type=%i\n", compression_type); - return 0; - } - - if (ea->sample_rate == -1) - ea->sample_rate = revision==3 ? 48000 : 22050; - - return 1; -} - -/* - * Process EACS sound header - * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx - */ -static int process_audio_header_eacs(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - ByteIOContext *pb = s->pb; - int compression_type; - - ea->sample_rate = ea->big_endian ? get_be32(pb) : get_le32(pb); - ea->bytes = get_byte(pb); /* 1=8-bit, 2=16-bit */ - ea->num_channels = get_byte(pb); - compression_type = get_byte(pb); - url_fskip(pb, 13); - - switch (compression_type) { - case 0: - switch (ea->bytes) { - case 1: ea->audio_codec = CODEC_ID_PCM_S8; break; - case 2: ea->audio_codec = CODEC_ID_PCM_S16LE; break; - } - break; - case 1: ea->audio_codec = CODEC_ID_PCM_MULAW; ea->bytes = 1; break; - case 2: ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_EACS; break; - default: - av_log (s, AV_LOG_ERROR, "unsupported stream type; audio compression_type=%i\n", compression_type); - } - - return 1; -} - -/* - * Process SEAD sound header - * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx - */ -static int process_audio_header_sead(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - ByteIOContext *pb = s->pb; - - ea->sample_rate = get_le32(pb); - ea->bytes = get_le32(pb); /* 1=8-bit, 2=16-bit */ - ea->num_channels = get_le32(pb); - ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_SEAD; - - return 1; -} - -static int process_video_header_mdec(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - ByteIOContext *pb = s->pb; - url_fskip(pb, 4); - ea->width = get_le16(pb); - ea->height = get_le16(pb); - ea->time_base = (AVRational){1,15}; - ea->video_codec = CODEC_ID_MDEC; - return 1; -} - -static int process_video_header_vp6(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - ByteIOContext *pb = s->pb; - - url_fskip(pb, 16); - ea->time_base.den = get_le32(pb); - ea->time_base.num = get_le32(pb); - ea->video_codec = CODEC_ID_VP6; - - return 1; -} - -/* - * Process EA file header - * Returns 1 if the EA file is valid and successfully opened, 0 otherwise - */ -static int process_ea_header(AVFormatContext *s) { - uint32_t blockid, size = 0; - EaDemuxContext *ea = s->priv_data; - ByteIOContext *pb = s->pb; - int i; - - for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) { - unsigned int startpos = url_ftell(pb); - int err = 0; - - blockid = get_le32(pb); - size = get_le32(pb); - if (i == 0) - ea->big_endian = size > 0x000FFFFF; - if (ea->big_endian) - size = bswap_32(size); - - switch (blockid) { - case ISNh_TAG: - if (get_le32(pb) != EACS_TAG) { - av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n"); - return 0; - } - err = process_audio_header_eacs(s); - break; - - case SCHl_TAG : - case SHEN_TAG : - blockid = get_le32(pb); - if (blockid == GSTR_TAG) { - url_fskip(pb, 4); - } else if ((blockid & 0xFFFF)!=PT00_TAG) { - av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n"); - return 0; - } - err = process_audio_header_elements(s); - break; - - case SEAD_TAG: - err = process_audio_header_sead(s); - break; - - case MVIh_TAG : - ea->video_codec = CODEC_ID_CMV; - ea->time_base = (AVRational){0,0}; - break; - - case kVGT_TAG: - ea->video_codec = CODEC_ID_TGV; - ea->time_base = (AVRational){0,0}; - break; - - case mTCD_TAG : - err = process_video_header_mdec(s); - break; - - case MPCh_TAG: - ea->video_codec = CODEC_ID_MPEG2VIDEO; - break; - - case pQGT_TAG: - case TGQs_TAG: - ea->video_codec = CODEC_ID_TGQ; - break; - - case pIQT_TAG: - ea->video_codec = CODEC_ID_TQI; - break; - - case MADk_TAG : - ea->video_codec = CODEC_ID_MAD; - break; - - case MVhd_TAG : - err = process_video_header_vp6(s); - break; - } - - if (err < 0) { - av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err); - return err; - } - - url_fseek(pb, startpos + size, SEEK_SET); - } - - url_fseek(pb, 0, SEEK_SET); - - return 1; -} - - -static int ea_probe(AVProbeData *p) -{ - switch (AV_RL32(&p->buf[0])) { - case ISNh_TAG: - case SCHl_TAG: - case SEAD_TAG: - case SHEN_TAG: - case kVGT_TAG: - case MADk_TAG: - case MPCh_TAG: - case MVhd_TAG: - case MVIh_TAG: - break; - default: - return 0; - } - if (AV_RL32(&p->buf[4]) > 0xfffff && AV_RB32(&p->buf[4]) > 0xfffff) - return 0; - return AVPROBE_SCORE_MAX; -} - -static int ea_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - EaDemuxContext *ea = s->priv_data; - AVStream *st; - - if (!process_ea_header(s)) - return AVERROR(EIO); - - if (ea->video_codec) { - /* initialize the video decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - ea->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = ea->video_codec; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->time_base = ea->time_base; - st->codec->width = ea->width; - st->codec->height = ea->height; - } - - if (ea->audio_codec) { - /* initialize the audio decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, ea->sample_rate); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ea->audio_codec; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = ea->num_channels; - st->codec->sample_rate = ea->sample_rate; - st->codec->bits_per_coded_sample = ea->bytes * 8; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample / 4; - st->codec->block_align = st->codec->channels*st->codec->bits_per_coded_sample; - ea->audio_stream_index = st->index; - ea->audio_frame_counter = 0; - } - - return 1; -} - -static int ea_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - EaDemuxContext *ea = s->priv_data; - ByteIOContext *pb = s->pb; - int ret = 0; - int packet_read = 0; - unsigned int chunk_type, chunk_size; - int key = 0; - int av_uninit(num_samples); - - while (!packet_read) { - chunk_type = get_le32(pb); - chunk_size = (ea->big_endian ? get_be32(pb) : get_le32(pb)) - 8; - - switch (chunk_type) { - /* audio data */ - case ISNh_TAG: - /* header chunk also contains data; skip over the header portion*/ - url_fskip(pb, 32); - chunk_size -= 32; - case ISNd_TAG: - case SCDl_TAG: - case SNDC_TAG: - case SDEN_TAG: - if (!ea->audio_codec) { - url_fskip(pb, chunk_size); - break; - } else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR || - ea->audio_codec == CODEC_ID_MP3) { - num_samples = get_le32(pb); - url_fskip(pb, 8); - chunk_size -= 12; - } - ret = av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; - pkt->stream_index = ea->audio_stream_index; - pkt->pts = 90000; - pkt->pts *= ea->audio_frame_counter; - pkt->pts /= ea->sample_rate; - - switch (ea->audio_codec) { - case CODEC_ID_ADPCM_EA: - /* 2 samples/byte, 1 or 2 samples per frame depending - * on stereo; chunk also has 12-byte header */ - ea->audio_frame_counter += ((chunk_size - 12) * 2) / - ea->num_channels; - break; - case CODEC_ID_PCM_S16LE_PLANAR: - case CODEC_ID_MP3: - ea->audio_frame_counter += num_samples; - break; - default: - ea->audio_frame_counter += chunk_size / - (ea->bytes * ea->num_channels); - } - - packet_read = 1; - break; - - /* ending tag */ - case 0: - case ISNe_TAG: - case SCEl_TAG: - case SEND_TAG: - case SEEN_TAG: - ret = AVERROR(EIO); - packet_read = 1; - break; - - case MVIh_TAG: - case kVGT_TAG: - case pQGT_TAG: - case TGQs_TAG: - case MADk_TAG: - key = AV_PKT_FLAG_KEY; - case MVIf_TAG: - case fVGT_TAG: - case MADm_TAG: - case MADe_TAG: - url_fseek(pb, -8, SEEK_CUR); // include chunk preamble - chunk_size += 8; - goto get_video_packet; - - case mTCD_TAG: - url_fseek(pb, 8, SEEK_CUR); // skip ea dct header - chunk_size -= 8; - goto get_video_packet; - - case MV0K_TAG: - case MPCh_TAG: - case pIQT_TAG: - key = AV_PKT_FLAG_KEY; - case MV0F_TAG: -get_video_packet: - ret = av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; - pkt->stream_index = ea->video_stream_index; - pkt->flags |= key; - packet_read = 1; - break; - - default: - url_fseek(pb, chunk_size, SEEK_CUR); - break; - } - } - - return ret; -} - -AVInputFormat ea_demuxer = { - "ea", - NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia Format"), - sizeof(EaDemuxContext), - ea_probe, - ea_read_header, - ea_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/ffm.h b/tizen/distrib/ffmpeg/libavformat/ffm.h deleted file mode 100644 index 05d6eb1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/ffm.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * FFM (ffserver live feed) common header - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_FFM_H -#define AVFORMAT_FFM_H - -#include -#include "avformat.h" -#include "avio.h" - -/* The FFM file is made of blocks of fixed size */ -#define FFM_HEADER_SIZE 14 -#define PACKET_ID 0x666d - -/* each packet contains frames (which can span several packets */ -#define FRAME_HEADER_SIZE 16 -#define FLAG_KEY_FRAME 0x01 -#define FLAG_DTS 0x02 - -enum { - READ_HEADER, - READ_DATA, -}; - -typedef struct FFMContext { - /* only reading mode */ - int64_t write_index, file_size; - int read_state; - uint8_t header[FRAME_HEADER_SIZE+4]; - - /* read and write */ - int first_packet; /* true if first packet, needed to set the discontinuity tag */ - int packet_size; - int frame_offset; - int64_t dts; - uint8_t *packet_ptr, *packet_end; - uint8_t packet[FFM_PACKET_SIZE]; -} FFMContext; - -#endif /* AVFORMAT_FFM_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/ffmdec.c b/tizen/distrib/ffmpeg/libavformat/ffmdec.c deleted file mode 100644 index b2a4bc2..0000000 --- a/tizen/distrib/ffmpeg/libavformat/ffmdec.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * FFM (ffserver live feed) demuxer - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "ffm.h" -#if CONFIG_FFSERVER -#include - -int64_t ffm_read_write_index(int fd) -{ - uint8_t buf[8]; - - lseek(fd, 8, SEEK_SET); - if (read(fd, buf, 8) != 8) - return AVERROR(EIO); - return AV_RB64(buf); -} - -int ffm_write_write_index(int fd, int64_t pos) -{ - uint8_t buf[8]; - int i; - - for(i=0;i<8;i++) - buf[i] = (pos >> (56 - i * 8)) & 0xff; - lseek(fd, 8, SEEK_SET); - if (write(fd, buf, 8) != 8) - return AVERROR(EIO); - return 8; -} - -void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size) -{ - FFMContext *ffm = s->priv_data; - ffm->write_index = pos; - ffm->file_size = file_size; -} -#endif // CONFIG_FFSERVER - -static int ffm_is_avail_data(AVFormatContext *s, int size) -{ - FFMContext *ffm = s->priv_data; - int64_t pos, avail_size; - int len; - - len = ffm->packet_end - ffm->packet_ptr; - if (size <= len) - return 1; - pos = url_ftell(s->pb); - if (!ffm->write_index) { - if (pos == ffm->file_size) - return AVERROR_EOF; - avail_size = ffm->file_size - pos; - } else { - if (pos == ffm->write_index) { - /* exactly at the end of stream */ - return AVERROR(EAGAIN); - } else if (pos < ffm->write_index) { - avail_size = ffm->write_index - pos; - } else { - avail_size = (ffm->file_size - pos) + (ffm->write_index - FFM_PACKET_SIZE); - } - } - avail_size = (avail_size / ffm->packet_size) * (ffm->packet_size - FFM_HEADER_SIZE) + len; - if (size <= avail_size) - return 1; - else - return AVERROR(EAGAIN); -} - -static int ffm_resync(AVFormatContext *s, int state) -{ - av_log(s, AV_LOG_ERROR, "resyncing\n"); - while (state != PACKET_ID) { - if (url_feof(s->pb)) { - av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n"); - return -1; - } - state = (state << 8) | get_byte(s->pb); - } - return 0; -} - -/* first is true if we read the frame header */ -static int ffm_read_data(AVFormatContext *s, - uint8_t *buf, int size, int header) -{ - FFMContext *ffm = s->priv_data; - ByteIOContext *pb = s->pb; - int len, fill_size, size1, frame_offset, id; - - size1 = size; - while (size > 0) { - redo: - len = ffm->packet_end - ffm->packet_ptr; - if (len < 0) - return -1; - if (len > size) - len = size; - if (len == 0) { - if (url_ftell(pb) == ffm->file_size) - url_fseek(pb, ffm->packet_size, SEEK_SET); - retry_read: - id = get_be16(pb); /* PACKET_ID */ - if (id != PACKET_ID) - if (ffm_resync(s, id) < 0) - return -1; - fill_size = get_be16(pb); - ffm->dts = get_be64(pb); - frame_offset = get_be16(pb); - get_buffer(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE); - ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); - if (ffm->packet_end < ffm->packet || frame_offset < 0) - return -1; - /* if first packet or resynchronization packet, we must - handle it specifically */ - if (ffm->first_packet || (frame_offset & 0x8000)) { - if (!frame_offset) { - /* This packet has no frame headers in it */ - if (url_ftell(pb) >= ffm->packet_size * 3) { - url_fseek(pb, -ffm->packet_size * 2, SEEK_CUR); - goto retry_read; - } - /* This is bad, we cannot find a valid frame header */ - return 0; - } - ffm->first_packet = 0; - if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) - return -1; - ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE; - if (!header) - break; - } else { - ffm->packet_ptr = ffm->packet; - } - goto redo; - } - memcpy(buf, ffm->packet_ptr, len); - buf += len; - ffm->packet_ptr += len; - size -= len; - header = 0; - } - return size1 - size; -} - -//#define DEBUG_SEEK - -/* ensure that acutal seeking happens between FFM_PACKET_SIZE - and file_size - FFM_PACKET_SIZE */ -static void ffm_seek1(AVFormatContext *s, int64_t pos1) -{ - FFMContext *ffm = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos; - - pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE); - pos = FFMAX(pos, FFM_PACKET_SIZE); -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos); -#endif - url_fseek(pb, pos, SEEK_SET); -} - -static int64_t get_dts(AVFormatContext *s, int64_t pos) -{ - ByteIOContext *pb = s->pb; - int64_t dts; - - ffm_seek1(s, pos); - url_fskip(pb, 4); - dts = get_be64(pb); -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "dts=%0.6f\n", dts / 1000000.0); -#endif - return dts; -} - -static void adjust_write_index(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pts; - //int64_t orig_write_index = ffm->write_index; - int64_t pos_min, pos_max; - int64_t pts_start; - int64_t ptr = url_ftell(pb); - - - pos_min = 0; - pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE; - - pts_start = get_dts(s, pos_min); - - pts = get_dts(s, pos_max); - - if (pts - 100000 > pts_start) - goto end; - - ffm->write_index = FFM_PACKET_SIZE; - - pts_start = get_dts(s, pos_min); - - pts = get_dts(s, pos_max); - - if (pts - 100000 <= pts_start) { - while (1) { - int64_t newpos; - int64_t newpts; - - newpos = ((pos_max + pos_min) / (2 * FFM_PACKET_SIZE)) * FFM_PACKET_SIZE; - - if (newpos == pos_min) - break; - - newpts = get_dts(s, newpos); - - if (newpts - 100000 <= pts) { - pos_max = newpos; - pts = newpts; - } else { - pos_min = newpos; - } - } - ffm->write_index += pos_max; - } - - //printf("Adjusted write index from %"PRId64" to %"PRId64": pts=%0.6f\n", orig_write_index, ffm->write_index, pts / 1000000.); - //printf("pts range %0.6f - %0.6f\n", get_dts(s, 0) / 1000000. , get_dts(s, ffm->file_size - 2 * FFM_PACKET_SIZE) / 1000000. ); - - end: - url_fseek(pb, ptr, SEEK_SET); -} - - -static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - FFMContext *ffm = s->priv_data; - AVStream *st; - ByteIOContext *pb = s->pb; - AVCodecContext *codec; - int i, nb_streams; - uint32_t tag; - - /* header */ - tag = get_le32(pb); - if (tag != MKTAG('F', 'F', 'M', '1')) - goto fail; - ffm->packet_size = get_be32(pb); - if (ffm->packet_size != FFM_PACKET_SIZE) - goto fail; - ffm->write_index = get_be64(pb); - /* get also filesize */ - if (!url_is_streamed(pb)) { - ffm->file_size = url_fsize(pb); - if (ffm->write_index) - adjust_write_index(s); - } else { - ffm->file_size = (UINT64_C(1) << 63) - 1; - } - - nb_streams = get_be32(pb); - get_be32(pb); /* total bitrate */ - /* read each stream */ - for(i=0;icodec; - /* generic info */ - codec->codec_id = get_be32(pb); - codec->codec_type = get_byte(pb); /* codec_type */ - codec->bit_rate = get_be32(pb); - st->quality = get_be32(pb); - codec->flags = get_be32(pb); - codec->flags2 = get_be32(pb); - codec->debug = get_be32(pb); - /* specific info */ - switch(codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - codec->time_base.num = get_be32(pb); - codec->time_base.den = get_be32(pb); - codec->width = get_be16(pb); - codec->height = get_be16(pb); - codec->gop_size = get_be16(pb); - codec->pix_fmt = get_be32(pb); - codec->qmin = get_byte(pb); - codec->qmax = get_byte(pb); - codec->max_qdiff = get_byte(pb); - codec->qcompress = get_be16(pb) / 10000.0; - codec->qblur = get_be16(pb) / 10000.0; - codec->bit_rate_tolerance = get_be32(pb); - codec->rc_eq = av_strdup(get_strz(pb, rc_eq_buf, sizeof(rc_eq_buf))); - codec->rc_max_rate = get_be32(pb); - codec->rc_min_rate = get_be32(pb); - codec->rc_buffer_size = get_be32(pb); - codec->i_quant_factor = av_int2dbl(get_be64(pb)); - codec->b_quant_factor = av_int2dbl(get_be64(pb)); - codec->i_quant_offset = av_int2dbl(get_be64(pb)); - codec->b_quant_offset = av_int2dbl(get_be64(pb)); - codec->dct_algo = get_be32(pb); - codec->strict_std_compliance = get_be32(pb); - codec->max_b_frames = get_be32(pb); - codec->luma_elim_threshold = get_be32(pb); - codec->chroma_elim_threshold = get_be32(pb); - codec->mpeg_quant = get_be32(pb); - codec->intra_dc_precision = get_be32(pb); - codec->me_method = get_be32(pb); - codec->mb_decision = get_be32(pb); - codec->nsse_weight = get_be32(pb); - codec->frame_skip_cmp = get_be32(pb); - codec->rc_buffer_aggressivity = av_int2dbl(get_be64(pb)); - codec->codec_tag = get_be32(pb); - codec->thread_count = get_byte(pb); - codec->coder_type = get_be32(pb); - codec->me_cmp = get_be32(pb); - codec->partitions = get_be32(pb); - codec->me_subpel_quality = get_be32(pb); - codec->me_range = get_be32(pb); - codec->keyint_min = get_be32(pb); - codec->scenechange_threshold = get_be32(pb); - codec->b_frame_strategy = get_be32(pb); - codec->qcompress = av_int2dbl(get_be64(pb)); - codec->qblur = av_int2dbl(get_be64(pb)); - codec->max_qdiff = get_be32(pb); - codec->refs = get_be32(pb); - codec->directpred = get_be32(pb); - break; - case AVMEDIA_TYPE_AUDIO: - codec->sample_rate = get_be32(pb); - codec->channels = get_le16(pb); - codec->frame_size = get_le16(pb); - codec->sample_fmt = (int16_t) get_le16(pb); - break; - default: - goto fail; - } - if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { - codec->extradata_size = get_be32(pb); - codec->extradata = av_malloc(codec->extradata_size); - if (!codec->extradata) - return AVERROR(ENOMEM); - get_buffer(pb, codec->extradata, codec->extradata_size); - } - } - - /* get until end of block reached */ - while ((url_ftell(pb) % ffm->packet_size) != 0) - get_byte(pb); - - /* init packet demux */ - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet; - ffm->frame_offset = 0; - ffm->dts = 0; - ffm->read_state = READ_HEADER; - ffm->first_packet = 1; - return 0; - fail: - for(i=0;inb_streams;i++) { - st = s->streams[i]; - if (st) { - av_free(st); - } - } - return -1; -} - -/* return < 0 if eof */ -static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size; - FFMContext *ffm = s->priv_data; - int duration, ret; - - switch(ffm->read_state) { - case READ_HEADER: - if ((ret = ffm_is_avail_data(s, FRAME_HEADER_SIZE+4)) < 0) - return ret; - - dprintf(s, "pos=%08"PRIx64" spos=%"PRIx64", write_index=%"PRIx64" size=%"PRIx64"\n", - url_ftell(s->pb), s->pb->pos, ffm->write_index, ffm->file_size); - if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) != - FRAME_HEADER_SIZE) - return -1; - if (ffm->header[1] & FLAG_DTS) - if (ffm_read_data(s, ffm->header+16, 4, 1) != 4) - return -1; -#if 0 - av_hexdump_log(s, AV_LOG_DEBUG, ffm->header, FRAME_HEADER_SIZE); -#endif - ffm->read_state = READ_DATA; - /* fall thru */ - case READ_DATA: - size = AV_RB24(ffm->header + 2); - if ((ret = ffm_is_avail_data(s, size)) < 0) - return ret; - - duration = AV_RB24(ffm->header + 5); - - av_new_packet(pkt, size); - pkt->stream_index = ffm->header[0]; - if ((unsigned)pkt->stream_index >= s->nb_streams) { - av_log(s, AV_LOG_ERROR, "invalid stream index %d\n", pkt->stream_index); - av_free_packet(pkt); - ffm->read_state = READ_HEADER; - return -1; - } - pkt->pos = url_ftell(s->pb); - if (ffm->header[1] & FLAG_KEY_FRAME) - pkt->flags |= AV_PKT_FLAG_KEY; - - ffm->read_state = READ_HEADER; - if (ffm_read_data(s, pkt->data, size, 0) != size) { - /* bad case: desynchronized packet. we cancel all the packet loading */ - av_free_packet(pkt); - return -1; - } - pkt->pts = AV_RB64(ffm->header+8); - if (ffm->header[1] & FLAG_DTS) - pkt->dts = pkt->pts - AV_RB32(ffm->header+16); - else - pkt->dts = pkt->pts; - pkt->duration = duration; - break; - } - return 0; -} - -/* seek to a given time in the file. The file read pointer is - positioned at or before pts. XXX: the following code is quite - approximative */ -static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, int flags) -{ - FFMContext *ffm = s->priv_data; - int64_t pos_min, pos_max, pos; - int64_t pts_min, pts_max, pts; - double pos1; - -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0); -#endif - /* find the position using linear interpolation (better than - dichotomy in typical cases) */ - pos_min = FFM_PACKET_SIZE; - pos_max = ffm->file_size - FFM_PACKET_SIZE; - while (pos_min <= pos_max) { - pts_min = get_dts(s, pos_min); - pts_max = get_dts(s, pos_max); - /* linear interpolation */ - pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) / - (double)(pts_max - pts_min); - pos = (((int64_t)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE; - if (pos <= pos_min) - pos = pos_min; - else if (pos >= pos_max) - pos = pos_max; - pts = get_dts(s, pos); - /* check if we are lucky */ - if (pts == wanted_pts) { - goto found; - } else if (pts > wanted_pts) { - pos_max = pos - FFM_PACKET_SIZE; - } else { - pos_min = pos + FFM_PACKET_SIZE; - } - } - pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; - - found: - ffm_seek1(s, pos); - - /* reset read state */ - ffm->read_state = READ_HEADER; - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet; - ffm->first_packet = 1; - - return 0; -} - -static int ffm_probe(AVProbeData *p) -{ - if ( - p->buf[0] == 'F' && p->buf[1] == 'F' && p->buf[2] == 'M' && - p->buf[3] == '1') - return AVPROBE_SCORE_MAX + 1; - return 0; -} - -static int ffm_close(AVFormatContext *s) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) - av_freep(&s->streams[i]->codec->rc_eq); - - return 0; -} - -AVInputFormat ffm_demuxer = { - "ffm", - NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"), - sizeof(FFMContext), - ffm_probe, - ffm_read_header, - ffm_read_packet, - ffm_close, - ffm_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/ffmenc.c b/tizen/distrib/ffmpeg/libavformat/ffmenc.c deleted file mode 100644 index c5c59db..0000000 --- a/tizen/distrib/ffmpeg/libavformat/ffmenc.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * FFM (ffserver live feed) muxer - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "ffm.h" - -static void flush_packet(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - int fill_size, h; - ByteIOContext *pb = s->pb; - - fill_size = ffm->packet_end - ffm->packet_ptr; - memset(ffm->packet_ptr, 0, fill_size); - - if (url_ftell(pb) % ffm->packet_size) - av_abort(); - - /* put header */ - put_be16(pb, PACKET_ID); - put_be16(pb, fill_size); - put_be64(pb, ffm->dts); - h = ffm->frame_offset; - if (ffm->first_packet) - h |= 0x8000; - put_be16(pb, h); - put_buffer(pb, ffm->packet, ffm->packet_end - ffm->packet); - put_flush_packet(pb); - - /* prepare next packet */ - ffm->frame_offset = 0; /* no key frame */ - ffm->packet_ptr = ffm->packet; - ffm->first_packet = 0; -} - -/* 'first' is true if first data of a frame */ -static void ffm_write_data(AVFormatContext *s, - const uint8_t *buf, int size, - int64_t dts, int header) -{ - FFMContext *ffm = s->priv_data; - int len; - - if (header && ffm->frame_offset == 0) { - ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE; - ffm->dts = dts; - } - - /* write as many packets as needed */ - while (size > 0) { - len = ffm->packet_end - ffm->packet_ptr; - if (len > size) - len = size; - memcpy(ffm->packet_ptr, buf, len); - - ffm->packet_ptr += len; - buf += len; - size -= len; - if (ffm->packet_ptr >= ffm->packet_end) - flush_packet(s); - } -} - -static int ffm_write_header(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - AVStream *st; - ByteIOContext *pb = s->pb; - AVCodecContext *codec; - int bit_rate, i; - - ffm->packet_size = FFM_PACKET_SIZE; - - /* header */ - put_le32(pb, MKTAG('F', 'F', 'M', '1')); - put_be32(pb, ffm->packet_size); - put_be64(pb, 0); /* current write position */ - - put_be32(pb, s->nb_streams); - bit_rate = 0; - for(i=0;inb_streams;i++) { - st = s->streams[i]; - bit_rate += st->codec->bit_rate; - } - put_be32(pb, bit_rate); - - /* list of streams */ - for(i=0;inb_streams;i++) { - st = s->streams[i]; - av_set_pts_info(st, 64, 1, 1000000); - - codec = st->codec; - /* generic info */ - put_be32(pb, codec->codec_id); - put_byte(pb, codec->codec_type); - put_be32(pb, codec->bit_rate); - put_be32(pb, st->quality); - put_be32(pb, codec->flags); - put_be32(pb, codec->flags2); - put_be32(pb, codec->debug); - /* specific info */ - switch(codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - put_be32(pb, codec->time_base.num); - put_be32(pb, codec->time_base.den); - put_be16(pb, codec->width); - put_be16(pb, codec->height); - put_be16(pb, codec->gop_size); - put_be32(pb, codec->pix_fmt); - put_byte(pb, codec->qmin); - put_byte(pb, codec->qmax); - put_byte(pb, codec->max_qdiff); - put_be16(pb, (int) (codec->qcompress * 10000.0)); - put_be16(pb, (int) (codec->qblur * 10000.0)); - put_be32(pb, codec->bit_rate_tolerance); - put_strz(pb, codec->rc_eq ? codec->rc_eq : "tex^qComp"); - put_be32(pb, codec->rc_max_rate); - put_be32(pb, codec->rc_min_rate); - put_be32(pb, codec->rc_buffer_size); - put_be64(pb, av_dbl2int(codec->i_quant_factor)); - put_be64(pb, av_dbl2int(codec->b_quant_factor)); - put_be64(pb, av_dbl2int(codec->i_quant_offset)); - put_be64(pb, av_dbl2int(codec->b_quant_offset)); - put_be32(pb, codec->dct_algo); - put_be32(pb, codec->strict_std_compliance); - put_be32(pb, codec->max_b_frames); - put_be32(pb, codec->luma_elim_threshold); - put_be32(pb, codec->chroma_elim_threshold); - put_be32(pb, codec->mpeg_quant); - put_be32(pb, codec->intra_dc_precision); - put_be32(pb, codec->me_method); - put_be32(pb, codec->mb_decision); - put_be32(pb, codec->nsse_weight); - put_be32(pb, codec->frame_skip_cmp); - put_be64(pb, av_dbl2int(codec->rc_buffer_aggressivity)); - put_be32(pb, codec->codec_tag); - put_byte(pb, codec->thread_count); - put_be32(pb, codec->coder_type); - put_be32(pb, codec->me_cmp); - put_be32(pb, codec->partitions); - put_be32(pb, codec->me_subpel_quality); - put_be32(pb, codec->me_range); - put_be32(pb, codec->keyint_min); - put_be32(pb, codec->scenechange_threshold); - put_be32(pb, codec->b_frame_strategy); - put_be64(pb, av_dbl2int(codec->qcompress)); - put_be64(pb, av_dbl2int(codec->qblur)); - put_be32(pb, codec->max_qdiff); - put_be32(pb, codec->refs); - put_be32(pb, codec->directpred); - break; - case AVMEDIA_TYPE_AUDIO: - put_be32(pb, codec->sample_rate); - put_le16(pb, codec->channels); - put_le16(pb, codec->frame_size); - put_le16(pb, codec->sample_fmt); - break; - default: - return -1; - } - if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { - put_be32(pb, codec->extradata_size); - put_buffer(pb, codec->extradata, codec->extradata_size); - } - } - - /* flush until end of block reached */ - while ((url_ftell(pb) % ffm->packet_size) != 0) - put_byte(pb, 0); - - put_flush_packet(pb); - - /* init packet mux */ - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; - assert(ffm->packet_end >= ffm->packet); - ffm->frame_offset = 0; - ffm->dts = 0; - ffm->first_packet = 1; - - return 0; -} - -static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - int64_t dts; - uint8_t header[FRAME_HEADER_SIZE+4]; - int header_size = FRAME_HEADER_SIZE; - - dts = s->timestamp + pkt->dts; - /* packet size & key_frame */ - header[0] = pkt->stream_index; - header[1] = 0; - if (pkt->flags & AV_PKT_FLAG_KEY) - header[1] |= FLAG_KEY_FRAME; - AV_WB24(header+2, pkt->size); - AV_WB24(header+5, pkt->duration); - AV_WB64(header+8, s->timestamp + pkt->pts); - if (pkt->pts != pkt->dts) { - header[1] |= FLAG_DTS; - AV_WB32(header+16, pkt->pts - pkt->dts); - header_size += 4; - } - ffm_write_data(s, header, header_size, dts, 1); - ffm_write_data(s, pkt->data, pkt->size, dts, 0); - - return 0; -} - -static int ffm_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - FFMContext *ffm = s->priv_data; - - /* flush packets */ - if (ffm->packet_ptr > ffm->packet) - flush_packet(s); - - put_flush_packet(pb); - - return 0; -} - -AVOutputFormat ffm_muxer = { - "ffm", - NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"), - "", - "ffm", - sizeof(FFMContext), - /* not really used */ - CODEC_ID_MP2, - CODEC_ID_MPEG1VIDEO, - ffm_write_header, - ffm_write_packet, - ffm_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/file.c b/tizen/distrib/ffmpeg/libavformat/file.c deleted file mode 100644 index 8873d5f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/file.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Buffered file io for ffmpeg system - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avstring.h" -#include "avformat.h" -#include -#if HAVE_SETMODE -#include -#endif -#include -#include -#include -#include -#include "os_support.h" - - -/* standard file protocol */ - -static int file_open(URLContext *h, const char *filename, int flags) -{ - int access; - int fd; - - av_strstart(filename, "file:", &filename); - - if (flags & URL_RDWR) { - access = O_CREAT | O_TRUNC | O_RDWR; - } else if (flags & URL_WRONLY) { - access = O_CREAT | O_TRUNC | O_WRONLY; - } else { - access = O_RDONLY; - } -#ifdef O_BINARY - access |= O_BINARY; -#endif - fd = open(filename, access, 0666); - if (fd == -1) - return AVERROR(errno); - h->priv_data = (void *) (intptr_t) fd; - return 0; -} - -static int file_read(URLContext *h, unsigned char *buf, int size) -{ - int fd = (intptr_t) h->priv_data; - return read(fd, buf, size); -} - -static int file_write(URLContext *h, unsigned char *buf, int size) -{ - int fd = (intptr_t) h->priv_data; - return write(fd, buf, size); -} - -/* XXX: use llseek */ -static int64_t file_seek(URLContext *h, int64_t pos, int whence) -{ - int fd = (intptr_t) h->priv_data; - if (whence == AVSEEK_SIZE) { - struct stat st; - int ret = fstat(fd, &st); - return ret < 0 ? AVERROR(errno) : st.st_size; - } - return lseek(fd, pos, whence); -} - -static int file_close(URLContext *h) -{ - int fd = (intptr_t) h->priv_data; - return close(fd); -} - -static int file_get_handle(URLContext *h) -{ - return (intptr_t) h->priv_data; -} - -URLProtocol file_protocol = { - "file", - file_open, - file_read, - file_write, - file_seek, - file_close, - .url_get_file_handle = file_get_handle, -}; - -/* pipe protocol */ - -static int pipe_open(URLContext *h, const char *filename, int flags) -{ - int fd; - char *final; - av_strstart(filename, "pipe:", &filename); - - fd = strtol(filename, &final, 10); - if((filename == final) || *final ) {/* No digits found, or something like 10ab */ - if (flags & URL_WRONLY) { - fd = 1; - } else { - fd = 0; - } - } -#if HAVE_SETMODE - setmode(fd, O_BINARY); -#endif - h->priv_data = (void *) (intptr_t) fd; - h->is_streamed = 1; - return 0; -} - -URLProtocol pipe_protocol = { - "pipe", - pipe_open, - file_read, - file_write, - .url_get_file_handle = file_get_handle, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/filmstripdec.c b/tizen/distrib/ffmpeg/libavformat/filmstripdec.c deleted file mode 100644 index 0442fc3..0000000 --- a/tizen/distrib/ffmpeg/libavformat/filmstripdec.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Adobe Filmstrip demuxer - * Copyright (c) 2010 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Adobe Filmstrip demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define RAND_TAG MKBETAG('R','a','n','d') - -typedef struct { - int leading; -} FilmstripDemuxContext; - -static int read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - FilmstripDemuxContext *film = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - - if (url_is_streamed(s->pb)) - return AVERROR(EIO); - - url_fseek(pb, url_fsize(pb) - 36, SEEK_SET); - if (get_be32(pb) != RAND_TAG) { - av_log(s, AV_LOG_ERROR, "magic number not found"); - return AVERROR_INVALIDDATA; - } - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->nb_frames = get_be32(pb); - if (get_be16(pb) != 0) { - av_log_ask_for_sample(s, "unsupported packing method\n"); - return AVERROR_INVALIDDATA; - } - - url_fskip(pb, 2); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->pix_fmt = PIX_FMT_RGBA; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = get_be16(pb); - st->codec->height = get_be16(pb); - film->leading = get_be16(pb); - av_set_pts_info(st, 64, 1, get_be16(pb)); - - url_fseek(pb, 0, SEEK_SET); - - return 0; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - FilmstripDemuxContext *film = s->priv_data; - AVStream *st = s->streams[0]; - - if (url_feof(s->pb)) - return AVERROR(EIO); - pkt->dts = url_ftell(s->pb) / (st->codec->width * (st->codec->height + film->leading) * 4); - pkt->size = av_get_packet(s->pb, pkt, st->codec->width * st->codec->height * 4); - url_fskip(s->pb, st->codec->width * film->leading * 4); - if (pkt->size < 0) - return pkt->size; - pkt->flags |= AV_PKT_FLAG_KEY; - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - url_fseek(s->pb, FFMAX(timestamp, 0) * st->codec->width * st->codec->height * 4, SEEK_SET); - return 0; -} - -AVInputFormat filmstrip_demuxer = { - "filmstrip", - NULL_IF_CONFIG_SMALL("Adobe Filmstrip"), - sizeof(FilmstripDemuxContext), - NULL, - read_header, - read_packet, - NULL, - read_seek, - .extensions = "flm", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/filmstripenc.c b/tizen/distrib/ffmpeg/libavformat/filmstripenc.c deleted file mode 100644 index 4e10c28..0000000 --- a/tizen/distrib/ffmpeg/libavformat/filmstripenc.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Adobe Filmstrip muxer - * Copyright (c) 2010 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Adobe Filmstrip muxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define RAND_TAG MKBETAG('R','a','n','d') - -typedef struct { - int nb_frames; -} FilmstripMuxContext; - -static int write_header(AVFormatContext *s) -{ - if (s->streams[0]->codec->pix_fmt != PIX_FMT_RGBA) { - av_log(s, AV_LOG_ERROR, "only PIX_FMT_RGBA is supported\n"); - return AVERROR_INVALIDDATA; - } - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - FilmstripMuxContext *film = s->priv_data; - put_buffer(s->pb, pkt->data, pkt->size); - film->nb_frames++; - return 0; -} - -static int write_trailer(AVFormatContext *s) -{ - FilmstripMuxContext *film = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - int i; - - put_be32(pb, RAND_TAG); - put_be32(pb, film->nb_frames); - put_be16(pb, 0); // packing method - put_be16(pb, 0); // reserved - put_be16(pb, st->codec->width); - put_be16(pb, st->codec->height); - put_be16(pb, 0); // leading - put_be16(pb, 1/av_q2d(st->codec->time_base)); - for (i = 0; i < 16; i++) - put_byte(pb, 0x00); // reserved - put_flush_packet(pb); - return 0; -} - -AVOutputFormat filmstrip_muxer = { - "filmstrip", - NULL_IF_CONFIG_SMALL("Adobe Filmstrip"), - NULL, - "flm", - sizeof(FilmstripMuxContext), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - write_header, - write_packet, - write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/flacdec.c b/tizen/distrib/ffmpeg/libavformat/flacdec.c deleted file mode 100644 index 2ceef96..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flacdec.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Raw FLAC demuxer - * Copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/flac.h" -#include "avformat.h" -#include "raw.h" -#include "id3v2.h" -#include "oggdec.h" -#include "vorbiscomment.h" - -static int flac_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - uint8_t buf[ID3v2_HEADER_SIZE]; - int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0; - uint8_t header[4]; - uint8_t *buffer=NULL; - AVStream *st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_FLAC; - st->need_parsing = AVSTREAM_PARSE_FULL; - /* the parameters will be extracted from the compressed bitstream */ - - /* skip ID3v2 header if found */ - ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); - if (ret == ID3v2_HEADER_SIZE && ff_id3v2_match(buf)) { - int len = ff_id3v2_tag_len(buf); - url_fseek(s->pb, len - ID3v2_HEADER_SIZE, SEEK_CUR); - } else { - url_fseek(s->pb, 0, SEEK_SET); - } - - /* if fLaC marker is not found, assume there is no header */ - if (get_le32(s->pb) != MKTAG('f','L','a','C')) { - url_fseek(s->pb, -4, SEEK_CUR); - return 0; - } - - /* process metadata blocks */ - while (!url_feof(s->pb) && !metadata_last) { - get_buffer(s->pb, header, 4); - ff_flac_parse_block_header(header, &metadata_last, &metadata_type, - &metadata_size); - switch (metadata_type) { - /* allocate and read metadata block for supported types */ - case FLAC_METADATA_TYPE_STREAMINFO: - case FLAC_METADATA_TYPE_VORBIS_COMMENT: - buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!buffer) { - return AVERROR(ENOMEM); - } - if (get_buffer(s->pb, buffer, metadata_size) != metadata_size) { - av_freep(&buffer); - return AVERROR(EIO); - } - break; - /* skip metadata block for unsupported types */ - default: - ret = url_fseek(s->pb, metadata_size, SEEK_CUR); - if (ret < 0) - return ret; - } - - if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) { - FLACStreaminfo si; - /* STREAMINFO can only occur once */ - if (found_streaminfo) { - av_freep(&buffer); - return AVERROR_INVALIDDATA; - } - if (metadata_size != FLAC_STREAMINFO_SIZE) { - av_freep(&buffer); - return AVERROR_INVALIDDATA; - } - found_streaminfo = 1; - st->codec->extradata = buffer; - st->codec->extradata_size = metadata_size; - buffer = NULL; - - /* get codec params from STREAMINFO header */ - ff_flac_parse_streaminfo(st->codec, &si, st->codec->extradata); - - /* set time base and duration */ - if (si.samplerate > 0) { - av_set_pts_info(st, 64, 1, si.samplerate); - if (si.samples > 0) - st->duration = si.samples; - } - } else { - /* STREAMINFO must be the first block */ - if (!found_streaminfo) { - av_freep(&buffer); - return AVERROR_INVALIDDATA; - } - /* process supported blocks other than STREAMINFO */ - if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { - if (ff_vorbis_comment(s, &s->metadata, buffer, metadata_size)) { - av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n"); - } - } - av_freep(&buffer); - } - } - - return 0; -} - -static int flac_probe(AVProbeData *p) -{ - uint8_t *bufptr = p->buf; - uint8_t *end = p->buf + p->buf_size; - - if(ff_id3v2_match(bufptr)) - bufptr += ff_id3v2_tag_len(bufptr); - - if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0; - else return AVPROBE_SCORE_MAX/2; -} - -AVInputFormat flac_demuxer = { - "flac", - NULL_IF_CONFIG_SMALL("raw FLAC"), - 0, - flac_probe, - flac_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "flac", - .value = CODEC_ID_FLAC, - .metadata_conv = ff_vorbiscomment_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/flacenc.c b/tizen/distrib/ffmpeg/libavformat/flacenc.c deleted file mode 100644 index 91a080f3..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flacenc.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * raw FLAC muxer - * Copyright (c) 2006-2009 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/flac.h" -#include "avformat.h" -#include "flacenc.h" -#include "metadata.h" -#include "vorbiscomment.h" -#include "libavcodec/bytestream.h" - - -static int flac_write_block_padding(ByteIOContext *pb, unsigned int n_padding_bytes, - int last_block) -{ - put_byte(pb, last_block ? 0x81 : 0x01); - put_be24(pb, n_padding_bytes); - while (n_padding_bytes > 0) { - put_byte(pb, 0); - n_padding_bytes--; - } - return 0; -} - -static int flac_write_block_comment(ByteIOContext *pb, AVMetadata *m, - int last_block, int bitexact) -{ - const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; - unsigned int len, count; - uint8_t *p, *p0; - - len = ff_vorbiscomment_length(m, vendor, &count); - p0 = av_malloc(len+4); - if (!p0) - return AVERROR(ENOMEM); - p = p0; - - bytestream_put_byte(&p, last_block ? 0x84 : 0x04); - bytestream_put_be24(&p, len); - ff_vorbiscomment_write(&p, m, vendor, count); - - put_buffer(pb, p0, len+4); - av_freep(&p0); - p = NULL; - - return 0; -} - -static int flac_write_header(struct AVFormatContext *s) -{ - int ret; - AVCodecContext *codec = s->streams[0]->codec; - - ret = ff_flac_write_header(s->pb, codec, 0); - if (ret) - return ret; - - ret = flac_write_block_comment(s->pb, s->metadata, 0, - codec->flags & CODEC_FLAG_BITEXACT); - if (ret) - return ret; - - /* The command line flac encoder defaults to placing a seekpoint - * every 10s. So one might add padding to allow that later - * but there seems to be no simple way to get the duration here. - * So let's try the flac default of 8192 bytes */ - flac_write_block_padding(s->pb, 8192, 1); - - return ret; -} - -static int flac_write_trailer(struct AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - uint8_t *streaminfo; - enum FLACExtradataFormat format; - int64_t file_size; - - if (!ff_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo)) - return -1; - - if (!url_is_streamed(pb)) { - /* rewrite the STREAMINFO header block data */ - file_size = url_ftell(pb); - url_fseek(pb, 8, SEEK_SET); - put_buffer(pb, streaminfo, FLAC_STREAMINFO_SIZE); - url_fseek(pb, file_size, SEEK_SET); - put_flush_packet(pb); - } else { - av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n"); - } - return 0; -} - -static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - put_buffer(s->pb, pkt->data, pkt->size); - put_flush_packet(s->pb); - return 0; -} - -AVOutputFormat flac_muxer = { - "flac", - NULL_IF_CONFIG_SMALL("raw FLAC"), - "audio/x-flac", - "flac", - 0, - CODEC_ID_FLAC, - CODEC_ID_NONE, - flac_write_header, - flac_write_packet, - flac_write_trailer, - .flags= AVFMT_NOTIMESTAMPS, - .metadata_conv = ff_vorbiscomment_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/flacenc.h b/tizen/distrib/ffmpeg/libavformat/flacenc.h deleted file mode 100644 index 8ad1c26..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flacenc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * raw FLAC muxer - * Copyright (C) 2009 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_FLACENC_H -#define AVFORMAT_FLACENC_H - -#include "libavcodec/flac.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" - -int ff_flac_write_header(ByteIOContext *pb, AVCodecContext *codec, - int last_block); - -#endif /* AVFORMAT_FLACENC_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/flacenc_header.c b/tizen/distrib/ffmpeg/libavformat/flacenc_header.c deleted file mode 100644 index 92a129a..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flacenc_header.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * raw FLAC muxer - * Copyright (C) 2009 Justin Ruggles - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/flac.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "flacenc.h" - -int ff_flac_write_header(ByteIOContext *pb, AVCodecContext *codec, - int last_block) -{ - uint8_t header[8] = { - 0x66, 0x4C, 0x61, 0x43, 0x00, 0x00, 0x00, 0x22 - }; - uint8_t *streaminfo; - enum FLACExtradataFormat format; - - header[4] = last_block ? 0x80 : 0x00; - if (!ff_flac_is_extradata_valid(codec, &format, &streaminfo)) - return -1; - - /* write "fLaC" stream marker and first metadata block header if needed */ - if (format == FLAC_EXTRADATA_FORMAT_STREAMINFO) { - put_buffer(pb, header, 8); - } - - /* write STREAMINFO or full header */ - put_buffer(pb, codec->extradata, codec->extradata_size); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavformat/flic.c b/tizen/distrib/ffmpeg/libavformat/flic.c deleted file mode 100644 index 27145db..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flic.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * FLI/FLC Animation File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * FLI/FLC file demuxer - * 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 demuxer handles standard 0xAF11- and 0xAF12-type FLIs. It also handles - * special FLIs from the PC games "Magic Carpet" and "X-COM: Terror from the Deep". - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define FLIC_FILE_MAGIC_1 0xAF11 -#define FLIC_FILE_MAGIC_2 0xAF12 -#define FLIC_FILE_MAGIC_3 0xAF44 /* Flic Type for Extended FLX Format which - originated in Dave's Targa Animator (DTA) */ -#define FLIC_CHUNK_MAGIC_1 0xF1FA -#define FLIC_CHUNK_MAGIC_2 0xF5FA -#define FLIC_MC_SPEED 5 /* speed for Magic Carpet game FLIs */ -#define FLIC_DEFAULT_SPEED 5 /* for FLIs that have 0 speed */ -#define FLIC_TFTD_CHUNK_AUDIO 0xAAAA /* Audio chunk. Used in Terror from the Deep. - Has 10 B extra header not accounted for in the chunk header */ -#define FLIC_TFTD_SAMPLE_RATE 22050 - -#define FLIC_HEADER_SIZE 128 -#define FLIC_PREAMBLE_SIZE 6 - -typedef struct FlicDemuxContext { - int video_stream_index; - int audio_stream_index; - int frame_number; -} FlicDemuxContext; - -static int flic_probe(AVProbeData *p) -{ - int magic_number; - - if(p->buf_size < FLIC_HEADER_SIZE) - return 0; - - magic_number = AV_RL16(&p->buf[4]); - if ((magic_number != FLIC_FILE_MAGIC_1) && - (magic_number != FLIC_FILE_MAGIC_2) && - (magic_number != FLIC_FILE_MAGIC_3)) - return 0; - - if(AV_RL16(&p->buf[0x10]) != FLIC_CHUNK_MAGIC_1){ - if(AV_RL32(&p->buf[0x10]) > 2000) - return 0; - } - - if( AV_RL16(&p->buf[0x08]) > 4096 - || AV_RL16(&p->buf[0x0A]) > 4096) - return 0; - - - return AVPROBE_SCORE_MAX; -} - -static int flic_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - FlicDemuxContext *flic = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned char header[FLIC_HEADER_SIZE]; - AVStream *st, *ast; - int speed; - int magic_number; - unsigned char preamble[FLIC_PREAMBLE_SIZE]; - - flic->frame_number = 0; - - /* load the whole header and pull out the width and height */ - if (get_buffer(pb, header, FLIC_HEADER_SIZE) != FLIC_HEADER_SIZE) - return AVERROR(EIO); - - magic_number = AV_RL16(&header[4]); - speed = AV_RL32(&header[0x10]); - if (speed == 0) - speed = FLIC_DEFAULT_SPEED; - - /* initialize the decoder streams */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - flic->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_FLIC; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = AV_RL16(&header[0x08]); - st->codec->height = AV_RL16(&header[0x0A]); - - if (!st->codec->width || !st->codec->height) { - /* Ugly hack needed for the following sample: */ - /* http://samples.mplayerhq.hu/fli-flc/fli-bugs/specular.flc */ - av_log(s, AV_LOG_WARNING, - "File with no specified width/height. Trying 640x480.\n"); - st->codec->width = 640; - st->codec->height = 480; - } - - /* send over the whole 128-byte FLIC header */ - st->codec->extradata_size = FLIC_HEADER_SIZE; - st->codec->extradata = av_malloc(FLIC_HEADER_SIZE); - memcpy(st->codec->extradata, header, FLIC_HEADER_SIZE); - - /* peek at the preamble to detect TFTD videos - they seem to always start with an audio chunk */ - if (get_buffer(pb, preamble, FLIC_PREAMBLE_SIZE) != FLIC_PREAMBLE_SIZE) { - av_log(s, AV_LOG_ERROR, "Failed to peek at preamble\n"); - return AVERROR(EIO); - } - - url_fseek(pb, -FLIC_PREAMBLE_SIZE, SEEK_CUR); - - /* Time to figure out the framerate: - * If the first preamble's magic number is 0xAAAA then this file is from - * X-COM: Terror from the Deep. If on the other hand there is a FLIC chunk - * magic number at offset 0x10 assume this file is from Magic Carpet instead. - * If neither of the above is true then this is a normal FLIC file. - */ - if (AV_RL16(&preamble[4]) == FLIC_TFTD_CHUNK_AUDIO) { - /* TFTD videos have an extra 22050 Hz 8-bit mono audio stream */ - ast = av_new_stream(s, 1); - if (!ast) - return AVERROR(ENOMEM); - - flic->audio_stream_index = ast->index; - - /* all audio frames are the same size, so use the size of the first chunk for block_align */ - ast->codec->block_align = AV_RL32(&preamble[0]); - ast->codec->codec_type = CODEC_TYPE_AUDIO; - ast->codec->codec_id = CODEC_ID_PCM_U8; - ast->codec->codec_tag = 0; - ast->codec->sample_rate = FLIC_TFTD_SAMPLE_RATE; - ast->codec->channels = 1; - ast->codec->sample_fmt = SAMPLE_FMT_U8; - ast->codec->bit_rate = st->codec->sample_rate * 8; - ast->codec->bits_per_coded_sample = 8; - ast->codec->channel_layout = CH_LAYOUT_MONO; - ast->codec->extradata_size = 0; - - /* Since the header information is incorrect we have to figure out the - * framerate using block_align and the fact that the audio is 22050 Hz. - * We usually have two cases: 2205 -> 10 fps and 1470 -> 15 fps */ - av_set_pts_info(st, 64, ast->codec->block_align, FLIC_TFTD_SAMPLE_RATE); - av_set_pts_info(ast, 64, 1, FLIC_TFTD_SAMPLE_RATE); - } else if (AV_RL16(&header[0x10]) == FLIC_CHUNK_MAGIC_1) { - av_set_pts_info(st, 64, FLIC_MC_SPEED, 70); - - /* rewind the stream since the first chunk is at offset 12 */ - url_fseek(pb, 12, SEEK_SET); - - /* send over abbreviated FLIC header chunk */ - av_free(st->codec->extradata); - st->codec->extradata_size = 12; - st->codec->extradata = av_malloc(12); - memcpy(st->codec->extradata, header, 12); - - } else if (magic_number == FLIC_FILE_MAGIC_1) { - av_set_pts_info(st, 64, speed, 70); - } else if ((magic_number == FLIC_FILE_MAGIC_2) || - (magic_number == FLIC_FILE_MAGIC_3)) { - av_set_pts_info(st, 64, speed, 1000); - } else { - av_log(s, AV_LOG_INFO, "Invalid or unsupported magic chunk in file\n"); - return AVERROR_INVALIDDATA; - } - - return 0; -} - -static int flic_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - FlicDemuxContext *flic = s->priv_data; - ByteIOContext *pb = s->pb; - int packet_read = 0; - unsigned int size; - int magic; - int ret = 0; - unsigned char preamble[FLIC_PREAMBLE_SIZE]; - - while (!packet_read) { - - if ((ret = get_buffer(pb, preamble, FLIC_PREAMBLE_SIZE)) != - FLIC_PREAMBLE_SIZE) { - ret = AVERROR(EIO); - break; - } - - size = AV_RL32(&preamble[0]); - magic = AV_RL16(&preamble[4]); - - if (((magic == FLIC_CHUNK_MAGIC_1) || (magic == FLIC_CHUNK_MAGIC_2)) && size > FLIC_PREAMBLE_SIZE) { - if (av_new_packet(pkt, size)) { - ret = AVERROR(EIO); - break; - } - pkt->stream_index = flic->video_stream_index; - pkt->pts = flic->frame_number++; - pkt->pos = url_ftell(pb); - memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE); - ret = get_buffer(pb, pkt->data + FLIC_PREAMBLE_SIZE, - size - FLIC_PREAMBLE_SIZE); - if (ret != size - FLIC_PREAMBLE_SIZE) { - av_free_packet(pkt); - ret = AVERROR(EIO); - } - packet_read = 1; - } else if (magic == FLIC_TFTD_CHUNK_AUDIO) { - if (av_new_packet(pkt, size)) { - ret = AVERROR(EIO); - break; - } - - /* skip useless 10B sub-header (yes, it's not accounted for in the chunk header) */ - url_fseek(pb, 10, SEEK_CUR); - - pkt->stream_index = flic->audio_stream_index; - pkt->pos = url_ftell(pb); - ret = get_buffer(pb, pkt->data, size); - - if (ret != size) { - av_free_packet(pkt); - ret = AVERROR(EIO); - } - - packet_read = 1; - } else { - /* not interested in this chunk */ - url_fseek(pb, size - 6, SEEK_CUR); - } - } - - return ret; -} - -AVInputFormat flic_demuxer = { - "flic", - NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation format"), - sizeof(FlicDemuxContext), - flic_probe, - flic_read_header, - flic_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/flv.h b/tizen/distrib/ffmpeg/libavformat/flv.h deleted file mode 100644 index 55266a1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flv.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file - * FLV common header - * - * Copyright (c) 2006 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_FLV_H -#define AVFORMAT_FLV_H - -/* offsets for packed values */ -#define FLV_AUDIO_SAMPLESSIZE_OFFSET 1 -#define FLV_AUDIO_SAMPLERATE_OFFSET 2 -#define FLV_AUDIO_CODECID_OFFSET 4 - -#define FLV_VIDEO_FRAMETYPE_OFFSET 4 - -/* bitmasks to isolate specific values */ -#define FLV_AUDIO_CHANNEL_MASK 0x01 -#define FLV_AUDIO_SAMPLESIZE_MASK 0x02 -#define FLV_AUDIO_SAMPLERATE_MASK 0x0c -#define FLV_AUDIO_CODECID_MASK 0xf0 - -#define FLV_VIDEO_CODECID_MASK 0x0f -#define FLV_VIDEO_FRAMETYPE_MASK 0xf0 - -#define AMF_END_OF_OBJECT 0x09 - -enum { - FLV_HEADER_FLAG_HASVIDEO = 1, - FLV_HEADER_FLAG_HASAUDIO = 4, -}; - -enum { - FLV_TAG_TYPE_AUDIO = 0x08, - FLV_TAG_TYPE_VIDEO = 0x09, - FLV_TAG_TYPE_META = 0x12, -}; - -enum { - FLV_MONO = 0, - FLV_STEREO = 1, -}; - -enum { - FLV_SAMPLESSIZE_8BIT = 0, - FLV_SAMPLESSIZE_16BIT = 1 << FLV_AUDIO_SAMPLESSIZE_OFFSET, -}; - -enum { - FLV_SAMPLERATE_SPECIAL = 0, /**< signifies 5512Hz and 8000Hz in the case of NELLYMOSER */ - FLV_SAMPLERATE_11025HZ = 1 << FLV_AUDIO_SAMPLERATE_OFFSET, - FLV_SAMPLERATE_22050HZ = 2 << FLV_AUDIO_SAMPLERATE_OFFSET, - FLV_SAMPLERATE_44100HZ = 3 << FLV_AUDIO_SAMPLERATE_OFFSET, -}; - -enum { - FLV_CODECID_PCM = 0, - FLV_CODECID_ADPCM = 1 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_MP3 = 2 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_PCM_LE = 3 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_NELLYMOSER_8KHZ_MONO = 5 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_NELLYMOSER = 6 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_AAC = 10<< FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_SPEEX = 11<< FLV_AUDIO_CODECID_OFFSET, -}; - -enum { - FLV_CODECID_H263 = 2, - FLV_CODECID_SCREEN = 3, - FLV_CODECID_VP6 = 4, - FLV_CODECID_VP6A = 5, - FLV_CODECID_SCREEN2 = 6, - FLV_CODECID_H264 = 7, -}; - -enum { - FLV_FRAME_KEY = 1 << FLV_VIDEO_FRAMETYPE_OFFSET, - FLV_FRAME_INTER = 2 << FLV_VIDEO_FRAMETYPE_OFFSET, - FLV_FRAME_DISP_INTER = 3 << FLV_VIDEO_FRAMETYPE_OFFSET, -}; - -typedef enum { - AMF_DATA_TYPE_NUMBER = 0x00, - AMF_DATA_TYPE_BOOL = 0x01, - AMF_DATA_TYPE_STRING = 0x02, - AMF_DATA_TYPE_OBJECT = 0x03, - AMF_DATA_TYPE_NULL = 0x05, - AMF_DATA_TYPE_UNDEFINED = 0x06, - AMF_DATA_TYPE_REFERENCE = 0x07, - AMF_DATA_TYPE_MIXEDARRAY = 0x08, - AMF_DATA_TYPE_OBJECT_END = 0x09, - AMF_DATA_TYPE_ARRAY = 0x0a, - AMF_DATA_TYPE_DATE = 0x0b, - AMF_DATA_TYPE_LONG_STRING = 0x0c, - AMF_DATA_TYPE_UNSUPPORTED = 0x0d, -} AMFDataType; - -#endif /* AVFORMAT_FLV_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/flvdec.c b/tizen/distrib/ffmpeg/libavformat/flvdec.c deleted file mode 100644 index fcdf214..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flvdec.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * FLV demuxer - * Copyright (c) 2003 The FFmpeg Project - * - * This demuxer will generate a 1 byte extradata for VP6F content. - * It is composed of: - * - upper 4bits: difference between encoded width and visible width - * - lower 4bits: difference between encoded height and visible height - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avstring.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/mpeg4audio.h" -#include "avformat.h" -#include "flv.h" - -typedef struct { - int wrong_dts; ///< wrong dts due to negative cts -} FLVContext; - -static int flv_probe(AVProbeData *p) -{ - const uint8_t *d; - - d = p->buf; - if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0 && AV_RB32(d+5)>8) { - return AVPROBE_SCORE_MAX; - } - return 0; -} - -static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, int flv_codecid) { - AVCodecContext *acodec = astream->codec; - switch(flv_codecid) { - //no distinction between S16 and S8 PCM codec flags - case FLV_CODECID_PCM: - acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 : -#if HAVE_BIGENDIAN - CODEC_ID_PCM_S16BE; -#else - CODEC_ID_PCM_S16LE; -#endif - break; - case FLV_CODECID_PCM_LE: - acodec->codec_id = acodec->bits_per_coded_sample == 8 ? CODEC_ID_PCM_U8 : CODEC_ID_PCM_S16LE; break; - case FLV_CODECID_AAC : acodec->codec_id = CODEC_ID_AAC; break; - case FLV_CODECID_ADPCM: acodec->codec_id = CODEC_ID_ADPCM_SWF; break; - case FLV_CODECID_SPEEX: - acodec->codec_id = CODEC_ID_SPEEX; - acodec->sample_rate = 16000; - break; - case FLV_CODECID_MP3 : acodec->codec_id = CODEC_ID_MP3 ; astream->need_parsing = AVSTREAM_PARSE_FULL; break; - case FLV_CODECID_NELLYMOSER_8KHZ_MONO: - acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate - case FLV_CODECID_NELLYMOSER: - acodec->codec_id = CODEC_ID_NELLYMOSER; - break; - default: - av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET); - acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET; - } -} - -static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) { - AVCodecContext *vcodec = vstream->codec; - switch(flv_codecid) { - case FLV_CODECID_H263 : vcodec->codec_id = CODEC_ID_FLV1 ; break; - case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break; - case FLV_CODECID_SCREEN2: vcodec->codec_id = CODEC_ID_FLASHSV2; break; - case FLV_CODECID_VP6 : vcodec->codec_id = CODEC_ID_VP6F ; - case FLV_CODECID_VP6A : - if(flv_codecid == FLV_CODECID_VP6A) - vcodec->codec_id = CODEC_ID_VP6A; - if(vcodec->extradata_size != 1) { - vcodec->extradata_size = 1; - vcodec->extradata = av_malloc(1); - } - vcodec->extradata[0] = get_byte(s->pb); - return 1; // 1 byte body size adjustment for flv_read_packet() - case FLV_CODECID_H264: - vcodec->codec_id = CODEC_ID_H264; - return 3; // not 4, reading packet type will consume one byte - default: - av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); - vcodec->codec_tag = flv_codecid; - } - - return 0; -} - -static int amf_get_string(ByteIOContext *ioc, char *buffer, int buffsize) { - int length = get_be16(ioc); - if(length >= buffsize) { - url_fskip(ioc, length); - return -1; - } - - get_buffer(ioc, buffer, length); - - buffer[length] = '\0'; - - return length; -} - -static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) { - AVCodecContext *acodec, *vcodec; - ByteIOContext *ioc; - AMFDataType amf_type; - char str_val[256]; - double num_val; - - num_val = 0; - ioc = s->pb; - - amf_type = get_byte(ioc); - - switch(amf_type) { - case AMF_DATA_TYPE_NUMBER: - num_val = av_int2dbl(get_be64(ioc)); break; - case AMF_DATA_TYPE_BOOL: - num_val = get_byte(ioc); break; - case AMF_DATA_TYPE_STRING: - if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0) - return -1; - break; - case AMF_DATA_TYPE_OBJECT: { - unsigned int keylen; - - while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) { - url_fskip(ioc, keylen); //skip key string - if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) - return -1; //if we couldn't skip, bomb out. - } - if(get_byte(ioc) != AMF_END_OF_OBJECT) - return -1; - } - break; - case AMF_DATA_TYPE_NULL: - case AMF_DATA_TYPE_UNDEFINED: - case AMF_DATA_TYPE_UNSUPPORTED: - break; //these take up no additional space - case AMF_DATA_TYPE_MIXEDARRAY: - url_fskip(ioc, 4); //skip 32-bit max array index - while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { - //this is the only case in which we would want a nested parse to not skip over the object - if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) - return -1; - } - if(get_byte(ioc) != AMF_END_OF_OBJECT) - return -1; - break; - case AMF_DATA_TYPE_ARRAY: { - unsigned int arraylen, i; - - arraylen = get_be32(ioc); - for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) { - if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) - return -1; //if we couldn't skip, bomb out. - } - } - break; - case AMF_DATA_TYPE_DATE: - url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16) - break; - default: //unsupported type, we couldn't skip - return -1; - } - - if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL - acodec = astream ? astream->codec : NULL; - vcodec = vstream ? vstream->codec : NULL; - - if(amf_type == AMF_DATA_TYPE_BOOL) { - av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val)); - av_metadata_set2(&s->metadata, key, str_val, 0); - } else if(amf_type == AMF_DATA_TYPE_NUMBER) { - snprintf(str_val, sizeof(str_val), "%.f", num_val); - av_metadata_set2(&s->metadata, key, str_val, 0); - if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE; - else if(!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0)) - vcodec->bit_rate = num_val * 1024.0; - else if(!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0)) - acodec->bit_rate = num_val * 1024.0; - } else if (amf_type == AMF_DATA_TYPE_STRING) - av_metadata_set2(&s->metadata, key, str_val, 0); - } - - return 0; -} - -static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { - AMFDataType type; - AVStream *stream, *astream, *vstream; - ByteIOContext *ioc; - int i; - char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. - - astream = NULL; - vstream = NULL; - ioc = s->pb; - - //first object needs to be "onMetaData" string - type = get_byte(ioc); - if(type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0 || strcmp(buffer, "onMetaData")) - return -1; - - //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. - for(i = 0; i < s->nb_streams; i++) { - stream = s->streams[i]; - if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream; - else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream; - } - - //parse the second object (we want a mixed array) - if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) - return -1; - - return 0; -} - -static AVStream *create_stream(AVFormatContext *s, int is_audio){ - AVStream *st = av_new_stream(s, is_audio); - if (!st) - return NULL; - st->codec->codec_type = is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO; - av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ - return st; -} - -static int flv_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - int offset, flags; - - url_fskip(s->pb, 4); - flags = get_byte(s->pb); - /* old flvtool cleared this field */ - /* FIXME: better fix needed */ - if (!flags) { - flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO; - av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n"); - } - - if((flags & (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) - != (FLV_HEADER_FLAG_HASVIDEO|FLV_HEADER_FLAG_HASAUDIO)) - s->ctx_flags |= AVFMTCTX_NOHEADER; - - if(flags & FLV_HEADER_FLAG_HASVIDEO){ - if(!create_stream(s, 0)) - return AVERROR(ENOMEM); - } - if(flags & FLV_HEADER_FLAG_HASAUDIO){ - if(!create_stream(s, 1)) - return AVERROR(ENOMEM); - } - - offset = get_be32(s->pb); - url_fseek(s->pb, offset, SEEK_SET); - url_fskip(s->pb, 4); - - s->start_time = 0; - - return 0; -} - -static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) -{ - av_free(st->codec->extradata); - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = size; - get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size); - return 0; -} - -static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - FLVContext *flv = s->priv_data; - int ret, i, type, size, flags, is_audio; - int64_t next, pos; - int64_t dts, pts = AV_NOPTS_VALUE; - AVStream *st = NULL; - - for(;;url_fskip(s->pb, 4)){ /* pkt size is repeated at end. skip it */ - pos = url_ftell(s->pb); - type = get_byte(s->pb); - size = get_be24(s->pb); - dts = get_be24(s->pb); - dts |= get_byte(s->pb) << 24; -// av_log(s, AV_LOG_DEBUG, "type:%d, size:%d, dts:%d\n", type, size, dts); - if (url_feof(s->pb)) - return AVERROR_EOF; - url_fskip(s->pb, 3); /* stream id, always 0 */ - flags = 0; - - if(size == 0) - continue; - - next= size + url_ftell(s->pb); - - if (type == FLV_TAG_TYPE_AUDIO) { - is_audio=1; - flags = get_byte(s->pb); - size--; - } else if (type == FLV_TAG_TYPE_VIDEO) { - is_audio=0; - flags = get_byte(s->pb); - size--; - if ((flags & 0xf0) == 0x50) /* video info / command frame */ - goto skip; - } else { - if (type == FLV_TAG_TYPE_META && size > 13+1+4) - flv_read_metabody(s, next); - else /* skip packet */ - av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); - skip: - url_fseek(s->pb, next, SEEK_SET); - continue; - } - - /* skip empty data packets */ - if (!size) - continue; - - /* now find stream */ - for(i=0;inb_streams;i++) { - st = s->streams[i]; - if (st->id == is_audio) - break; - } - if(i == s->nb_streams){ - av_log(s, AV_LOG_ERROR, "invalid stream\n"); - st= create_stream(s, is_audio); - s->ctx_flags &= ~AVFMTCTX_NOHEADER; - } -// av_log(s, AV_LOG_DEBUG, "%d %X %d \n", is_audio, flags, st->discard); - if( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || is_audio)) - ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio)) - || st->discard >= AVDISCARD_ALL - ){ - url_fseek(s->pb, next, SEEK_SET); - continue; - } - if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) - av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); - break; - } - - // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps - if(!url_is_streamed(s->pb) && (!s->duration || s->duration==AV_NOPTS_VALUE)){ - int size; - const int64_t pos= url_ftell(s->pb); - const int64_t fsize= url_fsize(s->pb); - url_fseek(s->pb, fsize-4, SEEK_SET); - size= get_be32(s->pb); - url_fseek(s->pb, fsize-3-size, SEEK_SET); - if(size == get_be24(s->pb) + 11){ - uint32_t ts = get_be24(s->pb); - ts |= get_byte(s->pb) << 24; - s->duration = ts * (int64_t)AV_TIME_BASE / 1000; - } - url_fseek(s->pb, pos, SEEK_SET); - } - - if(is_audio){ - if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) { - st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1; - st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3); - st->codec->bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8; - } - if(!st->codec->codec_id){ - flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK); - } - }else{ - size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK); - } - - if (st->codec->codec_id == CODEC_ID_AAC || - st->codec->codec_id == CODEC_ID_H264) { - int type = get_byte(s->pb); - size--; - if (st->codec->codec_id == CODEC_ID_H264) { - int32_t cts = (get_be24(s->pb)+0xff800000)^0xff800000; // sign extension - pts = dts + cts; - if (cts < 0) { // dts are wrong - flv->wrong_dts = 1; - av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n"); - } - if (flv->wrong_dts) - dts = AV_NOPTS_VALUE; - } - if (type == 0) { - if ((ret = flv_get_extradata(s, st, size)) < 0) - return ret; - if (st->codec->codec_id == CODEC_ID_AAC) { - MPEG4AudioConfig cfg; - ff_mpeg4audio_get_config(&cfg, st->codec->extradata, - st->codec->extradata_size); - st->codec->channels = cfg.channels; - st->codec->sample_rate = cfg.sample_rate; - dprintf(s, "mp4a config channels %d sample rate %d\n", - st->codec->channels, st->codec->sample_rate); - } - - ret = AVERROR(EAGAIN); - goto leave; - } - } - - /* skip empty data packets */ - if (!size) { - ret = AVERROR(EAGAIN); - goto leave; - } - - ret= av_get_packet(s->pb, pkt, size); - if (ret < 0) { - return AVERROR(EIO); - } - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - pkt->dts = dts; - pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts; - pkt->stream_index = st->index; - - if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)) - pkt->flags |= AV_PKT_FLAG_KEY; - -leave: - url_fskip(s->pb, 4); - return ret; -} - -static int flv_read_seek(AVFormatContext *s, int stream_index, - int64_t ts, int flags) -{ - return av_url_read_fseek(s->pb, stream_index, ts, flags); -} - -#if 0 /* don't know enough to implement this */ -static int flv_read_seek2(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - int ret = AVERROR(ENOSYS); - - if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD; - - if (url_is_streamed(s->pb)) { - if (stream_index < 0) { - stream_index = av_find_default_stream_index(s); - if (stream_index < 0) - return -1; - - /* timestamp for default must be expressed in AV_TIME_BASE units */ - ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE, - flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); - } - ret = av_url_read_fseek(s->pb, stream_index, ts, flags); - } - - if (ret == AVERROR(ENOSYS)) - ret = av_seek_frame(s, stream_index, ts, flags); - return ret; -} -#endif - -AVInputFormat flv_demuxer = { - "flv", - NULL_IF_CONFIG_SMALL("FLV format"), - sizeof(FLVContext), - flv_probe, - flv_read_header, - flv_read_packet, - .read_seek = flv_read_seek, -#if 0 - .read_seek2 = flv_read_seek2, -#endif - .extensions = "flv", - .value = CODEC_ID_FLV1, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/flvenc.c b/tizen/distrib/ffmpeg/libavformat/flvenc.c deleted file mode 100644 index c351117..0000000 --- a/tizen/distrib/ffmpeg/libavformat/flvenc.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * FLV muxer - * Copyright (c) 2003 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "flv.h" -#include "riff.h" -#include "avc.h" - -#undef NDEBUG -#include - -static const AVCodecTag flv_video_codec_ids[] = { - {CODEC_ID_FLV1, FLV_CODECID_H263 }, - {CODEC_ID_FLASHSV, FLV_CODECID_SCREEN}, - {CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2}, - {CODEC_ID_VP6F, FLV_CODECID_VP6 }, - {CODEC_ID_VP6, FLV_CODECID_VP6 }, - {CODEC_ID_H264, FLV_CODECID_H264 }, - {CODEC_ID_NONE, 0} -}; - -static const AVCodecTag flv_audio_codec_ids[] = { - {CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_PCM_U8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_SPEEX, FLV_CODECID_SPEEX >> FLV_AUDIO_CODECID_OFFSET}, - {CODEC_ID_NONE, 0} -}; - -typedef struct FLVContext { - int reserved; - int64_t duration_offset; - int64_t filesize_offset; - int64_t duration; - int delay; ///< first dts delay for AVC -} FLVContext; - -static int get_audio_flags(AVCodecContext *enc){ - int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT : FLV_SAMPLESSIZE_8BIT; - - if (enc->codec_id == CODEC_ID_AAC) // specs force these parameters - return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO; - else if (enc->codec_id == CODEC_ID_SPEEX) { - if (enc->sample_rate != 16000) { - av_log(enc, AV_LOG_ERROR, "flv only supports wideband (16kHz) Speex audio\n"); - return -1; - } - if (enc->channels != 1) { - av_log(enc, AV_LOG_ERROR, "flv only supports mono Speex audio\n"); - return -1; - } - if (enc->frame_size / 320 > 8) { - av_log(enc, AV_LOG_WARNING, "Warning: Speex stream has more than " - "8 frames per packet. Adobe Flash " - "Player cannot handle this!\n"); - } - return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT; - } else { - switch (enc->sample_rate) { - case 44100: - flags |= FLV_SAMPLERATE_44100HZ; - break; - case 22050: - flags |= FLV_SAMPLERATE_22050HZ; - break; - case 11025: - flags |= FLV_SAMPLERATE_11025HZ; - break; - case 8000: //nellymoser only - case 5512: //not mp3 - if(enc->codec_id != CODEC_ID_MP3){ - flags |= FLV_SAMPLERATE_SPECIAL; - break; - } - default: - av_log(enc, AV_LOG_ERROR, "flv does not support that sample rate, choose from (44100, 22050, 11025).\n"); - return -1; - } - } - - if (enc->channels > 1) { - flags |= FLV_STEREO; - } - - switch(enc->codec_id){ - case CODEC_ID_MP3: - flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT; - break; - case CODEC_ID_PCM_U8: - flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_8BIT; - break; - case CODEC_ID_PCM_S16BE: - flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_16BIT; - break; - case CODEC_ID_PCM_S16LE: - flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT; - break; - case CODEC_ID_ADPCM_SWF: - flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT; - break; - case CODEC_ID_NELLYMOSER: - if (enc->sample_rate == 8000) { - flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT; - } else { - flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT; - } - break; - case 0: - flags |= enc->codec_tag<<4; - break; - default: - av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n"); - return -1; - } - - return flags; -} - -static void put_amf_string(ByteIOContext *pb, const char *str) -{ - size_t len = strlen(str); - put_be16(pb, len); - put_buffer(pb, str, len); -} - -static void put_amf_double(ByteIOContext *pb, double d) -{ - put_byte(pb, AMF_DATA_TYPE_NUMBER); - put_be64(pb, av_dbl2int(d)); -} - -static void put_amf_bool(ByteIOContext *pb, int b) { - put_byte(pb, AMF_DATA_TYPE_BOOL); - put_byte(pb, !!b); -} - -static int flv_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - FLVContext *flv = s->priv_data; - AVCodecContext *audio_enc = NULL, *video_enc = NULL; - int i; - double framerate = 0.0; - int metadata_size_pos, data_size; - - for(i=0; inb_streams; i++){ - AVCodecContext *enc = s->streams[i]->codec; - if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { - if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) { - framerate = av_q2d(s->streams[i]->r_frame_rate); - } else { - framerate = 1/av_q2d(s->streams[i]->codec->time_base); - } - video_enc = enc; - if(enc->codec_tag == 0) { - av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n"); - return -1; - } - } else { - audio_enc = enc; - if(get_audio_flags(enc)<0) - return -1; - } - av_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ - } - put_tag(pb,"FLV"); - put_byte(pb,1); - put_byte(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc - + FLV_HEADER_FLAG_HASVIDEO * !!video_enc); - put_be32(pb,9); - put_be32(pb,0); - - for(i=0; inb_streams; i++){ - if(s->streams[i]->codec->codec_tag == 5){ - put_byte(pb,8); // message type - put_be24(pb,0); // include flags - put_be24(pb,0); // time stamp - put_be32(pb,0); // reserved - put_be32(pb,11); // size - flv->reserved=5; - } - } - - /* write meta_tag */ - put_byte(pb, 18); // tag type META - metadata_size_pos= url_ftell(pb); - put_be24(pb, 0); // size of data part (sum of all parts below) - put_be24(pb, 0); // time stamp - put_be32(pb, 0); // reserved - - /* now data of data_size size */ - - /* first event name as a string */ - put_byte(pb, AMF_DATA_TYPE_STRING); - put_amf_string(pb, "onMetaData"); // 12 bytes - - /* mixed array (hash) with size and string/type/data tuples */ - put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY); - put_be32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and file size - - put_amf_string(pb, "duration"); - flv->duration_offset= url_ftell(pb); - put_amf_double(pb, s->duration / AV_TIME_BASE); // fill in the guessed duration, it'll be corrected later if incorrect - - if(video_enc){ - put_amf_string(pb, "width"); - put_amf_double(pb, video_enc->width); - - put_amf_string(pb, "height"); - put_amf_double(pb, video_enc->height); - - put_amf_string(pb, "videodatarate"); - put_amf_double(pb, video_enc->bit_rate / 1024.0); - - put_amf_string(pb, "framerate"); - put_amf_double(pb, framerate); - - put_amf_string(pb, "videocodecid"); - put_amf_double(pb, video_enc->codec_tag); - } - - if(audio_enc){ - put_amf_string(pb, "audiodatarate"); - put_amf_double(pb, audio_enc->bit_rate / 1024.0); - - put_amf_string(pb, "audiosamplerate"); - put_amf_double(pb, audio_enc->sample_rate); - - put_amf_string(pb, "audiosamplesize"); - put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_U8 ? 8 : 16); - - put_amf_string(pb, "stereo"); - put_amf_bool(pb, audio_enc->channels == 2); - - put_amf_string(pb, "audiocodecid"); - put_amf_double(pb, audio_enc->codec_tag); - } - - put_amf_string(pb, "filesize"); - flv->filesize_offset= url_ftell(pb); - put_amf_double(pb, 0); // delayed write - - put_amf_string(pb, ""); - put_byte(pb, AMF_END_OF_OBJECT); - - /* write total size of tag */ - data_size= url_ftell(pb) - metadata_size_pos - 10; - url_fseek(pb, metadata_size_pos, SEEK_SET); - put_be24(pb, data_size); - url_fseek(pb, data_size + 10 - 3, SEEK_CUR); - put_be32(pb, data_size + 11); - - for (i = 0; i < s->nb_streams; i++) { - AVCodecContext *enc = s->streams[i]->codec; - if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) { - int64_t pos; - put_byte(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? - FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); - put_be24(pb, 0); // size patched later - put_be24(pb, 0); // ts - put_byte(pb, 0); // ts ext - put_be24(pb, 0); // streamid - pos = url_ftell(pb); - if (enc->codec_id == CODEC_ID_AAC) { - put_byte(pb, get_audio_flags(enc)); - put_byte(pb, 0); // AAC sequence header - put_buffer(pb, enc->extradata, enc->extradata_size); - } else { - put_byte(pb, enc->codec_tag | FLV_FRAME_KEY); // flags - put_byte(pb, 0); // AVC sequence header - put_be24(pb, 0); // composition time - ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); - } - data_size = url_ftell(pb) - pos; - url_fseek(pb, -data_size - 10, SEEK_CUR); - put_be24(pb, data_size); - url_fseek(pb, data_size + 10 - 3, SEEK_CUR); - put_be32(pb, data_size + 11); // previous tag size - } - } - - return 0; -} - -static int flv_write_trailer(AVFormatContext *s) -{ - int64_t file_size; - - ByteIOContext *pb = s->pb; - FLVContext *flv = s->priv_data; - - file_size = url_ftell(pb); - - /* update informations */ - url_fseek(pb, flv->duration_offset, SEEK_SET); - put_amf_double(pb, flv->duration / (double)1000); - url_fseek(pb, flv->filesize_offset, SEEK_SET); - put_amf_double(pb, file_size); - - url_fseek(pb, file_size, SEEK_SET); - return 0; -} - -static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[pkt->stream_index]->codec; - FLVContext *flv = s->priv_data; - unsigned ts; - int size= pkt->size; - uint8_t *data= NULL; - int flags, flags_size; - -// av_log(s, AV_LOG_DEBUG, "type:%d pts: %"PRId64" size:%d\n", enc->codec_type, timestamp, size); - - if(enc->codec_id == CODEC_ID_VP6 || enc->codec_id == CODEC_ID_VP6F || - enc->codec_id == CODEC_ID_AAC) - flags_size= 2; - else if(enc->codec_id == CODEC_ID_H264) - flags_size= 5; - else - flags_size= 1; - - if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { - put_byte(pb, FLV_TAG_TYPE_VIDEO); - - flags = enc->codec_tag; - if(flags == 0) { - av_log(enc, AV_LOG_ERROR, "video codec %X not compatible with flv\n",enc->codec_id); - return -1; - } - - flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER; - } else { - assert(enc->codec_type == AVMEDIA_TYPE_AUDIO); - flags = get_audio_flags(enc); - - assert(size); - - put_byte(pb, FLV_TAG_TYPE_AUDIO); - } - - if (enc->codec_id == CODEC_ID_H264) { - /* check if extradata looks like mp4 formated */ - if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) { - if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0) - return -1; - } - if (!flv->delay && pkt->dts < 0) - flv->delay = -pkt->dts; - } - - ts = pkt->dts + flv->delay; // add delay to force positive dts - put_be24(pb,size + flags_size); - put_be24(pb,ts); - put_byte(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_ - put_be24(pb,flv->reserved); - put_byte(pb,flags); - if (enc->codec_id == CODEC_ID_VP6) - put_byte(pb,0); - if (enc->codec_id == CODEC_ID_VP6F) - put_byte(pb, enc->extradata_size ? enc->extradata[0] : 0); - else if (enc->codec_id == CODEC_ID_AAC) - put_byte(pb,1); // AAC raw - else if (enc->codec_id == CODEC_ID_H264) { - put_byte(pb,1); // AVC NALU - put_be24(pb,pkt->pts - pkt->dts); - } - - put_buffer(pb, data ? data : pkt->data, size); - - put_be32(pb,size+flags_size+11); // previous tag size - flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + pkt->duration); - - put_flush_packet(pb); - - av_free(data); - - return 0; -} - -AVOutputFormat flv_muxer = { - "flv", - NULL_IF_CONFIG_SMALL("FLV format"), - "video/x-flv", - "flv", - sizeof(FLVContext), -#if CONFIG_LIBMP3LAME - CODEC_ID_MP3, -#else // CONFIG_LIBMP3LAME - CODEC_ID_ADPCM_SWF, -#endif // CONFIG_LIBMP3LAME - CODEC_ID_FLV1, - flv_write_header, - flv_write_packet, - flv_write_trailer, - .codec_tag= (const AVCodecTag* const []){flv_video_codec_ids, flv_audio_codec_ids, 0}, - .flags= AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/framecrcenc.c b/tizen/distrib/ffmpeg/libavformat/framecrcenc.c deleted file mode 100644 index f59a0c8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/framecrcenc.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * frame CRC encoder (for codec/format testing) - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/adler32.h" -#include "avformat.h" - -static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - uint32_t crc = av_adler32_update(0, pkt->data, pkt->size); - char buf[256]; - - snprintf(buf, sizeof(buf), "%d, %"PRId64", %d, 0x%08x\n", pkt->stream_index, pkt->dts, pkt->size, crc); - put_buffer(s->pb, buf, strlen(buf)); - put_flush_packet(s->pb); - return 0; -} - -AVOutputFormat framecrc_muxer = { - "framecrc", - NULL_IF_CONFIG_SMALL("framecrc testing format"), - NULL, - "", - 0, - CODEC_ID_PCM_S16LE, - CODEC_ID_RAWVIDEO, - NULL, - framecrc_write_packet, - NULL, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/gif.c b/tizen/distrib/ffmpeg/libavformat/gif.c deleted file mode 100644 index 4741915..0000000 --- a/tizen/distrib/ffmpeg/libavformat/gif.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Animated GIF muxer - * Copyright (c) 2000 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * First version by Francois Revol revol@free.fr - * - * Features and limitations: - * - currently no compression is performed, - * in fact the size of the data is 9/8 the size of the image in 8bpp - * - uses only a global standard palette - * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS). - * - * Reference documents: - * http://www.goice.co.jp/member/mo/formats/gif.html - * http://astronomy.swin.edu.au/pbourke/dataformats/gif/ - * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt - * - * this url claims to have an LZW algorithm not covered by Unisys patent: - * http://www.msg.net/utility/whirlgif/gifencod.html - * could help reduce the size of the files _a lot_... - * some sites mentions an RLE type compression also. - */ - -#include "avformat.h" - -/* The GIF format uses reversed order for bitstreams... */ -/* at least they don't use PDP_ENDIAN :) */ -#define BITSTREAM_WRITER_LE - -#include "libavcodec/put_bits.h" - -/* bitstream minipacket size */ -#define GIF_CHUNKS 100 - -/* slows down the decoding (and some browsers don't like it) */ -/* update on the 'some browsers don't like it issue from above: this was probably due to missing 'Data Sub-block Terminator' (byte 19) in the app_header */ -#define GIF_ADD_APP_HEADER // required to enable looping of animated gif - -typedef struct { - unsigned char r; - unsigned char g; - unsigned char b; -} rgb_triplet; - -/* we use the standard 216 color palette */ - -/* this script was used to create the palette: - * for r in 00 33 66 99 cc ff; do for g in 00 33 66 99 cc ff; do echo -n " "; for b in 00 33 66 99 cc ff; do - * echo -n "{ 0x$r, 0x$g, 0x$b }, "; done; echo ""; done; done - */ - -static const rgb_triplet gif_clut[216] = { - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x33 }, { 0x00, 0x00, 0x66 }, { 0x00, 0x00, 0x99 }, { 0x00, 0x00, 0xcc }, { 0x00, 0x00, 0xff }, - { 0x00, 0x33, 0x00 }, { 0x00, 0x33, 0x33 }, { 0x00, 0x33, 0x66 }, { 0x00, 0x33, 0x99 }, { 0x00, 0x33, 0xcc }, { 0x00, 0x33, 0xff }, - { 0x00, 0x66, 0x00 }, { 0x00, 0x66, 0x33 }, { 0x00, 0x66, 0x66 }, { 0x00, 0x66, 0x99 }, { 0x00, 0x66, 0xcc }, { 0x00, 0x66, 0xff }, - { 0x00, 0x99, 0x00 }, { 0x00, 0x99, 0x33 }, { 0x00, 0x99, 0x66 }, { 0x00, 0x99, 0x99 }, { 0x00, 0x99, 0xcc }, { 0x00, 0x99, 0xff }, - { 0x00, 0xcc, 0x00 }, { 0x00, 0xcc, 0x33 }, { 0x00, 0xcc, 0x66 }, { 0x00, 0xcc, 0x99 }, { 0x00, 0xcc, 0xcc }, { 0x00, 0xcc, 0xff }, - { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0x33 }, { 0x00, 0xff, 0x66 }, { 0x00, 0xff, 0x99 }, { 0x00, 0xff, 0xcc }, { 0x00, 0xff, 0xff }, - { 0x33, 0x00, 0x00 }, { 0x33, 0x00, 0x33 }, { 0x33, 0x00, 0x66 }, { 0x33, 0x00, 0x99 }, { 0x33, 0x00, 0xcc }, { 0x33, 0x00, 0xff }, - { 0x33, 0x33, 0x00 }, { 0x33, 0x33, 0x33 }, { 0x33, 0x33, 0x66 }, { 0x33, 0x33, 0x99 }, { 0x33, 0x33, 0xcc }, { 0x33, 0x33, 0xff }, - { 0x33, 0x66, 0x00 }, { 0x33, 0x66, 0x33 }, { 0x33, 0x66, 0x66 }, { 0x33, 0x66, 0x99 }, { 0x33, 0x66, 0xcc }, { 0x33, 0x66, 0xff }, - { 0x33, 0x99, 0x00 }, { 0x33, 0x99, 0x33 }, { 0x33, 0x99, 0x66 }, { 0x33, 0x99, 0x99 }, { 0x33, 0x99, 0xcc }, { 0x33, 0x99, 0xff }, - { 0x33, 0xcc, 0x00 }, { 0x33, 0xcc, 0x33 }, { 0x33, 0xcc, 0x66 }, { 0x33, 0xcc, 0x99 }, { 0x33, 0xcc, 0xcc }, { 0x33, 0xcc, 0xff }, - { 0x33, 0xff, 0x00 }, { 0x33, 0xff, 0x33 }, { 0x33, 0xff, 0x66 }, { 0x33, 0xff, 0x99 }, { 0x33, 0xff, 0xcc }, { 0x33, 0xff, 0xff }, - { 0x66, 0x00, 0x00 }, { 0x66, 0x00, 0x33 }, { 0x66, 0x00, 0x66 }, { 0x66, 0x00, 0x99 }, { 0x66, 0x00, 0xcc }, { 0x66, 0x00, 0xff }, - { 0x66, 0x33, 0x00 }, { 0x66, 0x33, 0x33 }, { 0x66, 0x33, 0x66 }, { 0x66, 0x33, 0x99 }, { 0x66, 0x33, 0xcc }, { 0x66, 0x33, 0xff }, - { 0x66, 0x66, 0x00 }, { 0x66, 0x66, 0x33 }, { 0x66, 0x66, 0x66 }, { 0x66, 0x66, 0x99 }, { 0x66, 0x66, 0xcc }, { 0x66, 0x66, 0xff }, - { 0x66, 0x99, 0x00 }, { 0x66, 0x99, 0x33 }, { 0x66, 0x99, 0x66 }, { 0x66, 0x99, 0x99 }, { 0x66, 0x99, 0xcc }, { 0x66, 0x99, 0xff }, - { 0x66, 0xcc, 0x00 }, { 0x66, 0xcc, 0x33 }, { 0x66, 0xcc, 0x66 }, { 0x66, 0xcc, 0x99 }, { 0x66, 0xcc, 0xcc }, { 0x66, 0xcc, 0xff }, - { 0x66, 0xff, 0x00 }, { 0x66, 0xff, 0x33 }, { 0x66, 0xff, 0x66 }, { 0x66, 0xff, 0x99 }, { 0x66, 0xff, 0xcc }, { 0x66, 0xff, 0xff }, - { 0x99, 0x00, 0x00 }, { 0x99, 0x00, 0x33 }, { 0x99, 0x00, 0x66 }, { 0x99, 0x00, 0x99 }, { 0x99, 0x00, 0xcc }, { 0x99, 0x00, 0xff }, - { 0x99, 0x33, 0x00 }, { 0x99, 0x33, 0x33 }, { 0x99, 0x33, 0x66 }, { 0x99, 0x33, 0x99 }, { 0x99, 0x33, 0xcc }, { 0x99, 0x33, 0xff }, - { 0x99, 0x66, 0x00 }, { 0x99, 0x66, 0x33 }, { 0x99, 0x66, 0x66 }, { 0x99, 0x66, 0x99 }, { 0x99, 0x66, 0xcc }, { 0x99, 0x66, 0xff }, - { 0x99, 0x99, 0x00 }, { 0x99, 0x99, 0x33 }, { 0x99, 0x99, 0x66 }, { 0x99, 0x99, 0x99 }, { 0x99, 0x99, 0xcc }, { 0x99, 0x99, 0xff }, - { 0x99, 0xcc, 0x00 }, { 0x99, 0xcc, 0x33 }, { 0x99, 0xcc, 0x66 }, { 0x99, 0xcc, 0x99 }, { 0x99, 0xcc, 0xcc }, { 0x99, 0xcc, 0xff }, - { 0x99, 0xff, 0x00 }, { 0x99, 0xff, 0x33 }, { 0x99, 0xff, 0x66 }, { 0x99, 0xff, 0x99 }, { 0x99, 0xff, 0xcc }, { 0x99, 0xff, 0xff }, - { 0xcc, 0x00, 0x00 }, { 0xcc, 0x00, 0x33 }, { 0xcc, 0x00, 0x66 }, { 0xcc, 0x00, 0x99 }, { 0xcc, 0x00, 0xcc }, { 0xcc, 0x00, 0xff }, - { 0xcc, 0x33, 0x00 }, { 0xcc, 0x33, 0x33 }, { 0xcc, 0x33, 0x66 }, { 0xcc, 0x33, 0x99 }, { 0xcc, 0x33, 0xcc }, { 0xcc, 0x33, 0xff }, - { 0xcc, 0x66, 0x00 }, { 0xcc, 0x66, 0x33 }, { 0xcc, 0x66, 0x66 }, { 0xcc, 0x66, 0x99 }, { 0xcc, 0x66, 0xcc }, { 0xcc, 0x66, 0xff }, - { 0xcc, 0x99, 0x00 }, { 0xcc, 0x99, 0x33 }, { 0xcc, 0x99, 0x66 }, { 0xcc, 0x99, 0x99 }, { 0xcc, 0x99, 0xcc }, { 0xcc, 0x99, 0xff }, - { 0xcc, 0xcc, 0x00 }, { 0xcc, 0xcc, 0x33 }, { 0xcc, 0xcc, 0x66 }, { 0xcc, 0xcc, 0x99 }, { 0xcc, 0xcc, 0xcc }, { 0xcc, 0xcc, 0xff }, - { 0xcc, 0xff, 0x00 }, { 0xcc, 0xff, 0x33 }, { 0xcc, 0xff, 0x66 }, { 0xcc, 0xff, 0x99 }, { 0xcc, 0xff, 0xcc }, { 0xcc, 0xff, 0xff }, - { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0x33 }, { 0xff, 0x00, 0x66 }, { 0xff, 0x00, 0x99 }, { 0xff, 0x00, 0xcc }, { 0xff, 0x00, 0xff }, - { 0xff, 0x33, 0x00 }, { 0xff, 0x33, 0x33 }, { 0xff, 0x33, 0x66 }, { 0xff, 0x33, 0x99 }, { 0xff, 0x33, 0xcc }, { 0xff, 0x33, 0xff }, - { 0xff, 0x66, 0x00 }, { 0xff, 0x66, 0x33 }, { 0xff, 0x66, 0x66 }, { 0xff, 0x66, 0x99 }, { 0xff, 0x66, 0xcc }, { 0xff, 0x66, 0xff }, - { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff }, - { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff }, - { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff }, -}; - -/* GIF header */ -static int gif_image_write_header(ByteIOContext *pb, - int width, int height, int loop_count, - uint32_t *palette) -{ - int i; - unsigned int v; - - put_tag(pb, "GIF"); - put_tag(pb, "89a"); - put_le16(pb, width); - put_le16(pb, height); - - put_byte(pb, 0xf7); /* flags: global clut, 256 entries */ - put_byte(pb, 0x1f); /* background color index */ - put_byte(pb, 0); /* aspect ratio */ - - /* the global palette */ - if (!palette) { - put_buffer(pb, (const unsigned char *)gif_clut, 216*3); - for(i=0;i<((256-216)*3);i++) - put_byte(pb, 0); - } else { - for(i=0;i<256;i++) { - v = palette[i]; - put_byte(pb, (v >> 16) & 0xff); - put_byte(pb, (v >> 8) & 0xff); - put_byte(pb, (v) & 0xff); - } - } - - /* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated gif - see http://members.aol.com/royalef/gifabout.htm#net-extension - - byte 1 : 33 (hex 0x21) GIF Extension code - byte 2 : 255 (hex 0xFF) Application Extension Label - byte 3 : 11 (hex (0x0B) Length of Application Block - (eleven bytes of data to follow) - bytes 4 to 11 : "NETSCAPE" - bytes 12 to 14 : "2.0" - byte 15 : 3 (hex 0x03) Length of Data Sub-Block - (three bytes of data to follow) - byte 16 : 1 (hex 0x01) - bytes 17 to 18 : 0 to 65535, an unsigned integer in - lo-hi byte format. This indicate the - number of iterations the loop should - be executed. - bytes 19 : 0 (hex 0x00) a Data Sub-block Terminator - */ - - /* application extension header */ -#ifdef GIF_ADD_APP_HEADER - if (loop_count >= 0 && loop_count <= 65535) { - put_byte(pb, 0x21); - put_byte(pb, 0xff); - put_byte(pb, 0x0b); - put_tag(pb, "NETSCAPE2.0"); // bytes 4 to 14 - put_byte(pb, 0x03); // byte 15 - put_byte(pb, 0x01); // byte 16 - put_le16(pb, (uint16_t)loop_count); - put_byte(pb, 0x00); // byte 19 - } -#endif - return 0; -} - -/* 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 int gif_image_write_image(ByteIOContext *pb, - int x1, int y1, int width, int height, - const uint8_t *buf, int linesize, int pix_fmt) -{ - PutBitContext p; - uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */ - int i, left, w, v; - const uint8_t *ptr; - /* image block */ - - put_byte(pb, 0x2c); - put_le16(pb, x1); - put_le16(pb, y1); - put_le16(pb, width); - put_le16(pb, height); - put_byte(pb, 0x00); /* flags */ - /* no local clut */ - - put_byte(pb, 0x08); - - left= width * height; - - init_put_bits(&p, buffer, 130); - -/* - * the thing here is the bitstream is written as little packets, with a size byte before - * but it's still the same bitstream between packets (no flush !) - */ - ptr = buf; - w = width; - while(left>0) { - - put_bits(&p, 9, 0x0100); /* clear code */ - - for(i=(left 0) { - put_byte(pb, put_bits_ptr(&p) - p.buf); /* byte count of the packet */ - put_buffer(pb, p.buf, put_bits_ptr(&p) - p.buf); /* the actual buffer */ - p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */ - } - left-=GIF_CHUNKS; - } - put_byte(pb, 0x00); /* end of image block */ - - return 0; -} - -typedef struct { - int64_t time, file_time; - uint8_t buffer[100]; /* data chunks */ -} GIFContext; - -static int gif_write_header(AVFormatContext *s) -{ - GIFContext *gif = s->priv_data; - ByteIOContext *pb = s->pb; - AVCodecContext *enc, *video_enc; - int i, width, height, loop_count /*, rate*/; - -/* XXX: do we reject audio streams or just ignore them ? - if(s->nb_streams > 1) - return -1; -*/ - gif->time = 0; - gif->file_time = 0; - - video_enc = NULL; - for(i=0;inb_streams;i++) { - enc = s->streams[i]->codec; - if (enc->codec_type != AVMEDIA_TYPE_AUDIO) - video_enc = enc; - } - - if (!video_enc) { - av_free(gif); - return -1; - } else { - width = video_enc->width; - height = video_enc->height; - loop_count = s->loop_output; -// rate = video_enc->time_base.den; - } - - if (video_enc->pix_fmt != PIX_FMT_RGB24) { - av_log(s, AV_LOG_ERROR, "ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24.\n"); - return AVERROR(EIO); - } - - gif_image_write_header(pb, width, height, loop_count, NULL); - - put_flush_packet(s->pb); - return 0; -} - -static int gif_write_video(AVFormatContext *s, - AVCodecContext *enc, const uint8_t *buf, int size) -{ - ByteIOContext *pb = s->pb; - GIFContext *gif = s->priv_data; - int jiffies; - int64_t delay; - - /* graphic control extension block */ - put_byte(pb, 0x21); - put_byte(pb, 0xf9); - put_byte(pb, 0x04); /* block size */ - put_byte(pb, 0x04); /* flags */ - - /* 1 jiffy is 1/70 s */ - /* the delay_time field indicates the number of jiffies - 1 */ - delay = gif->file_time - gif->time; - - /* XXX: should use delay, in order to be more accurate */ - /* instead of using the same rounded value each time */ - /* XXX: don't even remember if I really use it for now */ - jiffies = (70*enc->time_base.num/enc->time_base.den) - 1; - - put_le16(pb, jiffies); - - put_byte(pb, 0x1f); /* transparent color index */ - put_byte(pb, 0x00); - - gif_image_write_image(pb, 0, 0, enc->width, enc->height, - buf, enc->width * 3, PIX_FMT_RGB24); - - put_flush_packet(s->pb); - return 0; -} - -static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) - return 0; /* just ignore audio */ - else - return gif_write_video(s, codec, pkt->data, pkt->size); -} - -static int gif_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - - put_byte(pb, 0x3b); - put_flush_packet(s->pb); - return 0; -} - -AVOutputFormat gif_muxer = { - "gif", - NULL_IF_CONFIG_SMALL("GIF Animation"), - "image/gif", - "gif", - sizeof(GIFContext), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - gif_write_header, - gif_write_packet, - gif_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/gopher.c b/tizen/distrib/ffmpeg/libavformat/gopher.c deleted file mode 100644 index f5bb4a3..0000000 --- a/tizen/distrib/ffmpeg/libavformat/gopher.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Gopher protocol - * - * Copyright (c) 2009 Toshimitsu Kimura - * - * based on libavformat/http.c, Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avstring.h" -#include "avformat.h" -#include "internal.h" -#include "network.h" - -typedef struct { - URLContext *hd; -} GopherContext; - -static int gopher_write(URLContext *h, uint8_t *buf, int size) -{ - GopherContext *s = h->priv_data; - return url_write(s->hd, buf, size); -} - -static int gopher_connect(URLContext *h, const char *path) -{ - char buffer[1024]; - - if (!*path) return AVERROR(EINVAL); - switch (*++path) { - case '5': - case '9': - path = strchr(path, '/'); - if (!path) return AVERROR(EINVAL); - break; - default: - av_log(NULL, AV_LOG_WARNING, - "Gopher protocol type '%c' not supported yet!\n", - *path); - return AVERROR(EINVAL); - } - - /* send gopher sector */ - snprintf(buffer, sizeof(buffer), "%s\r\n", path); - - if (gopher_write(h, buffer, strlen(buffer)) < 0) - return AVERROR(EIO); - - return 0; -} - -static int gopher_close(URLContext *h) -{ - GopherContext *s = h->priv_data; - if (s->hd) { - url_close(s->hd); - s->hd = NULL; - } - av_freep(&h->priv_data); - return 0; -} - -static int gopher_open(URLContext *h, const char *uri, int flags) -{ - GopherContext *s; - char hostname[1024], auth[1024], path[1024], buf[1024]; - int port, err; - - h->is_streamed = 1; - - s = av_malloc(sizeof(GopherContext)); - if (!s) { - return AVERROR(ENOMEM); - } - h->priv_data = s; - - /* needed in any case to build the host string */ - ff_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - path, sizeof(path), uri); - - if (port < 0) - port = 70; - - ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); - - s->hd = NULL; - err = url_open(&s->hd, buf, URL_RDWR); - if (err < 0) - goto fail; - - if ((err = gopher_connect(h, path)) < 0) - goto fail; - return 0; - fail: - gopher_close(h); - return err; -} - -static int gopher_read(URLContext *h, uint8_t *buf, int size) -{ - GopherContext *s = h->priv_data; - int len = url_read(s->hd, buf, size); - return len; -} - - -URLProtocol gopher_protocol = { - "gopher", - gopher_open, - gopher_read, - gopher_write, - NULL, /*seek*/ - gopher_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/gxf.c b/tizen/distrib/ffmpeg/libavformat/gxf.c deleted file mode 100644 index ea8a2ff..0000000 --- a/tizen/distrib/ffmpeg/libavformat/gxf.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * GXF demuxer. - * Copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/common.h" -#include "avformat.h" -#include "gxf.h" - -struct gxf_stream_info { - int64_t first_field; - int64_t last_field; - AVRational frames_per_second; - int32_t fields_per_frame; -}; - -/** - * \brief parses a packet header, extracting type and length - * \param pb ByteIOContext to read header from - * \param type detected packet type is stored here - * \param length detected packet length, excluding header is stored here - * \return 0 if header not found or contains invalid data, 1 otherwise - */ -static int parse_packet_header(ByteIOContext *pb, GXFPktType *type, int *length) { - if (get_be32(pb)) - return 0; - if (get_byte(pb) != 1) - return 0; - *type = get_byte(pb); - *length = get_be32(pb); - if ((*length >> 24) || *length < 16) - return 0; - *length -= 16; - if (get_be32(pb)) - return 0; - if (get_byte(pb) != 0xe1) - return 0; - if (get_byte(pb) != 0xe2) - return 0; - return 1; -} - -/** - * \brief check if file starts with a PKT_MAP header - */ -static int gxf_probe(AVProbeData *p) { - static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet - static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2}; - if (!memcmp(p->buf, startcode, sizeof(startcode)) && - !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode))) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** - * \brief gets the stream index for the track with the specified id, creates new - * stream if not found - * \param stream id of stream to find / add - * \param format stream format identifier - */ -static int get_sindex(AVFormatContext *s, int id, int format) { - int i; - AVStream *st = NULL; - for (i = 0; i < s->nb_streams; i++) { - if (s->streams[i]->id == id) - return i; - } - st = av_new_stream(s, id); - if (!st) - return AVERROR(ENOMEM); - switch (format) { - case 3: - case 4: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MJPEG; - break; - case 13: - case 15: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DVVIDEO; - break; - case 14: - case 16: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DVVIDEO; - break; - case 11: - case 12: - case 20: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG2VIDEO; - st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. - break; - case 22: - case 23: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG1VIDEO; - st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. - break; - case 9: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_S24LE; - st->codec->channels = 1; - st->codec->sample_rate = 48000; - st->codec->bit_rate = 3 * 1 * 48000 * 8; - st->codec->block_align = 3 * 1; - st->codec->bits_per_coded_sample = 24; - break; - case 10: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_S16LE; - st->codec->channels = 1; - st->codec->sample_rate = 48000; - st->codec->bit_rate = 2 * 1 * 48000 * 8; - st->codec->block_align = 2 * 1; - st->codec->bits_per_coded_sample = 16; - break; - case 17: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_AC3; - st->codec->channels = 2; - st->codec->sample_rate = 48000; - break; - // timecode tracks: - case 7: - case 8: - case 24: - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = CODEC_ID_NONE; - break; - default: - st->codec->codec_type = AVMEDIA_TYPE_UNKNOWN; - st->codec->codec_id = CODEC_ID_NONE; - break; - } - return s->nb_streams - 1; -} - -/** - * \brief filters out interesting tags from material information. - * \param len length of tag section, will be adjusted to contain remaining bytes - * \param si struct to store collected information into - */ -static void gxf_material_tags(ByteIOContext *pb, int *len, struct gxf_stream_info *si) { - si->first_field = AV_NOPTS_VALUE; - si->last_field = AV_NOPTS_VALUE; - while (*len >= 2) { - GXFMatTag tag = get_byte(pb); - int tlen = get_byte(pb); - *len -= 2; - if (tlen > *len) - return; - *len -= tlen; - if (tlen == 4) { - uint32_t value = get_be32(pb); - if (tag == MAT_FIRST_FIELD) - si->first_field = value; - else if (tag == MAT_LAST_FIELD) - si->last_field = value; - } else - url_fskip(pb, tlen); - } -} - -/** - * \brief convert fps tag value to AVRational fps - * \param fps fps value from tag - * \return fps as AVRational, or 0 / 0 if unknown - */ -static AVRational fps_tag2avr(int32_t fps) { - extern const AVRational ff_frame_rate_tab[]; - if (fps < 1 || fps > 9) fps = 9; - return ff_frame_rate_tab[9 - fps]; // values have opposite order -} - -/** - * \brief convert UMF attributes flags to AVRational fps - * \param fps fps value from flags - * \return fps as AVRational, or 0 / 0 if unknown - */ -static AVRational fps_umf2avr(uint32_t flags) { - static const AVRational map[] = {{50, 1}, {60000, 1001}, {24, 1}, - {25, 1}, {30000, 1001}}; - int idx = av_log2((flags & 0x7c0) >> 6); - return map[idx]; -} - -/** - * \brief filters out interesting tags from track information. - * \param len length of tag section, will be adjusted to contain remaining bytes - * \param si struct to store collected information into - */ -static void gxf_track_tags(ByteIOContext *pb, int *len, struct gxf_stream_info *si) { - si->frames_per_second = (AVRational){0, 0}; - si->fields_per_frame = 0; - while (*len >= 2) { - GXFTrackTag tag = get_byte(pb); - int tlen = get_byte(pb); - *len -= 2; - if (tlen > *len) - return; - *len -= tlen; - if (tlen == 4) { - uint32_t value = get_be32(pb); - if (tag == TRACK_FPS) - si->frames_per_second = fps_tag2avr(value); - else if (tag == TRACK_FPF && (value == 1 || value == 2)) - si->fields_per_frame = value; - } else - url_fskip(pb, tlen); - } -} - -/** - * \brief read index from FLT packet into stream 0 av_index - */ -static void gxf_read_index(AVFormatContext *s, int pkt_len) { - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - uint32_t fields_per_map = get_le32(pb); - uint32_t map_cnt = get_le32(pb); - int i; - pkt_len -= 8; - if (map_cnt > 1000) { - av_log(s, AV_LOG_ERROR, "too many index entries %u (%x)\n", map_cnt, map_cnt); - map_cnt = 1000; - } - if (pkt_len < 4 * map_cnt) { - av_log(s, AV_LOG_ERROR, "invalid index length\n"); - url_fskip(pb, pkt_len); - return; - } - pkt_len -= 4 * map_cnt; - av_add_index_entry(st, 0, 0, 0, 0, 0); - for (i = 0; i < map_cnt; i++) - av_add_index_entry(st, (uint64_t)get_le32(pb) * 1024, - i * (uint64_t)fields_per_map + 1, 0, 0, 0); - url_fskip(pb, pkt_len); -} - -static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { - ByteIOContext *pb = s->pb; - GXFPktType pkt_type; - int map_len; - int len; - AVRational main_timebase = {0, 0}; - struct gxf_stream_info si; - int i; - if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) { - av_log(s, AV_LOG_ERROR, "map packet not found\n"); - return 0; - } - map_len -= 2; - if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) { - av_log(s, AV_LOG_ERROR, "unknown version or invalid map preamble\n"); - return 0; - } - map_len -= 2; - len = get_be16(pb); // length of material data section - if (len > map_len) { - av_log(s, AV_LOG_ERROR, "material data longer than map data\n"); - return 0; - } - map_len -= len; - gxf_material_tags(pb, &len, &si); - url_fskip(pb, len); - map_len -= 2; - len = get_be16(pb); // length of track description - if (len > map_len) { - av_log(s, AV_LOG_ERROR, "track description longer than map data\n"); - return 0; - } - map_len -= len; - while (len > 0) { - int track_type, track_id, track_len; - AVStream *st; - int idx; - len -= 4; - track_type = get_byte(pb); - track_id = get_byte(pb); - track_len = get_be16(pb); - len -= track_len; - gxf_track_tags(pb, &track_len, &si); - url_fskip(pb, track_len); - if (!(track_type & 0x80)) { - av_log(s, AV_LOG_ERROR, "invalid track type %x\n", track_type); - continue; - } - track_type &= 0x7f; - if ((track_id & 0xc0) != 0xc0) { - av_log(s, AV_LOG_ERROR, "invalid track id %x\n", track_id); - continue; - } - track_id &= 0x3f; - idx = get_sindex(s, track_id, track_type); - if (idx < 0) continue; - st = s->streams[idx]; - if (!main_timebase.num || !main_timebase.den) { - main_timebase.num = si.frames_per_second.den; - main_timebase.den = si.frames_per_second.num * 2; - } - st->start_time = si.first_field; - if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE) - st->duration = si.last_field - si.first_field; - } - if (len < 0) - av_log(s, AV_LOG_ERROR, "invalid track description length specified\n"); - if (map_len) - url_fskip(pb, map_len); - if (!parse_packet_header(pb, &pkt_type, &len)) { - av_log(s, AV_LOG_ERROR, "sync lost in header\n"); - return -1; - } - if (pkt_type == PKT_FLT) { - gxf_read_index(s, len); - if (!parse_packet_header(pb, &pkt_type, &len)) { - av_log(s, AV_LOG_ERROR, "sync lost in header\n"); - return -1; - } - } - if (pkt_type == PKT_UMF) { - if (len >= 0x39) { - AVRational fps; - len -= 0x39; - url_fskip(pb, 5); // preamble - url_fskip(pb, 0x30); // payload description - fps = fps_umf2avr(get_le32(pb)); - if (!main_timebase.num || !main_timebase.den) { - // this may not always be correct, but simply the best we can get - main_timebase.num = fps.den; - main_timebase.den = fps.num * 2; - } - } else - av_log(s, AV_LOG_INFO, "UMF packet too short\n"); - } else - av_log(s, AV_LOG_INFO, "UMF packet missing\n"); - url_fskip(pb, len); - // set a fallback value, 60000/1001 is specified for audio-only files - // so use that regardless of why we do not know the video frame rate. - if (!main_timebase.num || !main_timebase.den) - main_timebase = (AVRational){1001, 60000}; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - av_set_pts_info(st, 32, main_timebase.num, main_timebase.den); - } - return 0; -} - -#define READ_ONE() \ - { \ - if (!max_interval-- || url_feof(pb)) \ - goto out; \ - tmp = tmp << 8 | get_byte(pb); \ - } - -/** - * \brief resync the stream on the next media packet with specified properties - * \param max_interval how many bytes to search for matching packet at most - * \param track track id the media packet must belong to, -1 for any - * \param timestamp minimum timestamp (== field number) the packet must have, -1 for any - * \return timestamp of packet found - */ -static int64_t gxf_resync_media(AVFormatContext *s, uint64_t max_interval, int track, int timestamp) { - uint32_t tmp; - uint64_t last_pos; - uint64_t last_found_pos = 0; - int cur_track; - int64_t cur_timestamp = AV_NOPTS_VALUE; - int len; - ByteIOContext *pb = s->pb; - GXFPktType type; - tmp = get_be32(pb); -start: - while (tmp) - READ_ONE(); - READ_ONE(); - if (tmp != 1) - goto start; - last_pos = url_ftell(pb); - url_fseek(pb, -5, SEEK_CUR); - if (!parse_packet_header(pb, &type, &len) || type != PKT_MEDIA) { - url_fseek(pb, last_pos, SEEK_SET); - goto start; - } - get_byte(pb); - cur_track = get_byte(pb); - cur_timestamp = get_be32(pb); - last_found_pos = url_ftell(pb) - 16 - 6; - if ((track >= 0 && track != cur_track) || (timestamp >= 0 && timestamp > cur_timestamp)) { - url_fseek(pb, last_pos, SEEK_SET); - goto start; - } -out: - if (last_found_pos) - url_fseek(pb, last_found_pos, SEEK_SET); - return cur_timestamp; -} - -static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { - ByteIOContext *pb = s->pb; - GXFPktType pkt_type; - int pkt_len; - while (!url_feof(pb)) { - AVStream *st; - int track_type, track_id, ret; - int field_nr, field_info, skip = 0; - int stream_index; - if (!parse_packet_header(pb, &pkt_type, &pkt_len)) { - if (!url_feof(pb)) - av_log(s, AV_LOG_ERROR, "sync lost\n"); - return -1; - } - if (pkt_type == PKT_FLT) { - gxf_read_index(s, pkt_len); - continue; - } - if (pkt_type != PKT_MEDIA) { - url_fskip(pb, pkt_len); - continue; - } - if (pkt_len < 16) { - av_log(s, AV_LOG_ERROR, "invalid media packet length\n"); - continue; - } - pkt_len -= 16; - track_type = get_byte(pb); - track_id = get_byte(pb); - stream_index = get_sindex(s, track_id, track_type); - if (stream_index < 0) - return stream_index; - st = s->streams[stream_index]; - field_nr = get_be32(pb); - field_info = get_be32(pb); - get_be32(pb); // "timeline" field number - get_byte(pb); // flags - get_byte(pb); // reserved - if (st->codec->codec_id == CODEC_ID_PCM_S24LE || - st->codec->codec_id == CODEC_ID_PCM_S16LE) { - int first = field_info >> 16; - int last = field_info & 0xffff; // last is exclusive - int bps = av_get_bits_per_sample(st->codec->codec_id)>>3; - if (first <= last && last*bps <= pkt_len) { - url_fskip(pb, first*bps); - skip = pkt_len - last*bps; - pkt_len = (last-first)*bps; - } else - av_log(s, AV_LOG_ERROR, "invalid first and last sample values\n"); - } - ret = av_get_packet(pb, pkt, pkt_len); - if (skip) - url_fskip(pb, skip); - pkt->stream_index = stream_index; - pkt->dts = field_nr; - return ret; - } - return AVERROR(EIO); -} - -static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - uint64_t pos; - uint64_t maxlen = 100 * 1024 * 1024; - AVStream *st = s->streams[0]; - int64_t start_time = s->streams[stream_index]->start_time; - int64_t found; - int idx; - if (timestamp < start_time) timestamp = start_time; - idx = av_index_search_timestamp(st, timestamp - start_time, - AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); - if (idx < 0) - return -1; - pos = st->index_entries[idx].pos; - if (idx < st->nb_index_entries - 2) - maxlen = st->index_entries[idx + 2].pos - pos; - maxlen = FFMAX(maxlen, 200 * 1024); - url_fseek(s->pb, pos, SEEK_SET); - found = gxf_resync_media(s, maxlen, -1, timestamp); - if (FFABS(found - timestamp) > 4) - return -1; - return 0; -} - -static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit) { - ByteIOContext *pb = s->pb; - int64_t res; - url_fseek(pb, *pos, SEEK_SET); - res = gxf_resync_media(s, pos_limit - *pos, -1, -1); - *pos = url_ftell(pb); - return res; -} - -AVInputFormat gxf_demuxer = { - "gxf", - NULL_IF_CONFIG_SMALL("GXF format"), - 0, - gxf_probe, - gxf_header, - gxf_packet, - NULL, - gxf_seek, - gxf_read_timestamp, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/gxf.h b/tizen/distrib/ffmpeg/libavformat/gxf.h deleted file mode 100644 index dcdcdef..0000000 --- a/tizen/distrib/ffmpeg/libavformat/gxf.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * GXF demuxer - * copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_GXF_H -#define AVFORMAT_GXF_H - -typedef enum { - PKT_MAP = 0xbc, - PKT_MEDIA = 0xbf, - PKT_EOS = 0xfb, - PKT_FLT = 0xfc, - PKT_UMF = 0xfd, -} GXFPktType; - -typedef enum { - MAT_NAME = 0x40, - MAT_FIRST_FIELD = 0x41, - MAT_LAST_FIELD = 0x42, - MAT_MARK_IN = 0x43, - MAT_MARK_OUT = 0x44, - MAT_SIZE = 0x45, -} GXFMatTag; - -typedef enum { - TRACK_NAME = 0x4c, - TRACK_AUX = 0x4d, - TRACK_VER = 0x4e, - TRACK_MPG_AUX = 0x4f, - TRACK_FPS = 0x50, - TRACK_LINES = 0x51, - TRACK_FPF = 0x52, -} GXFTrackTag; - -#endif /* AVFORMAT_GXF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/gxfenc.c b/tizen/distrib/ffmpeg/libavformat/gxfenc.c deleted file mode 100644 index a6f4b72..0000000 --- a/tizen/distrib/ffmpeg/libavformat/gxfenc.c +++ /dev/null @@ -1,938 +0,0 @@ -/* - * GXF muxer. - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "gxf.h" -#include "riff.h" -#include "audiointerleave.h" - -#define GXF_AUDIO_PACKET_SIZE 65536 - -typedef struct GXFStreamContext { - AudioInterleaveContext aic; - uint32_t track_type; - uint32_t sample_size; - uint32_t sample_rate; - uint16_t media_type; - uint16_t media_info; - int frame_rate_index; - int lines_index; - int fields; - int iframes; - int pframes; - int bframes; - int p_per_gop; - int b_per_i_or_p; ///< number of B frames per I frame or P frame - int first_gop_closed; - unsigned order; ///< interleaving order -} GXFStreamContext; - -typedef struct GXFContext { - uint32_t nb_fields; - uint16_t audio_tracks; - uint16_t mpeg_tracks; - int64_t creation_time; - uint32_t umf_start_offset; - uint32_t umf_track_offset; - uint32_t umf_media_offset; - uint32_t umf_length; - uint16_t umf_track_size; - uint16_t umf_media_size; - AVRational time_base; - int flags; - GXFStreamContext timecode_track; - unsigned *flt_entries; ///< offsets of packets /1024, starts after 2nd video field - unsigned flt_entries_nb; - uint64_t *map_offsets; ///< offset of map packets - unsigned map_offsets_nb; - unsigned packet_count; -} GXFContext; - -static const struct { - int height, index; -} gxf_lines_tab[] = { - { 480, 1 }, /* NTSC */ - { 512, 1 }, /* NTSC + VBI */ - { 576, 2 }, /* PAL */ - { 608, 2 }, /* PAL + VBI */ - { 1080, 4 }, - { 720, 6 }, -}; - -static const AVCodecTag gxf_media_types[] = { - { CODEC_ID_MJPEG , 3 }, /* NTSC */ - { CODEC_ID_MJPEG , 4 }, /* PAL */ - { CODEC_ID_PCM_S24LE , 9 }, - { CODEC_ID_PCM_S16LE , 10 }, - { CODEC_ID_MPEG2VIDEO, 11 }, /* NTSC */ - { CODEC_ID_MPEG2VIDEO, 12 }, /* PAL */ - { CODEC_ID_DVVIDEO , 13 }, /* NTSC */ - { CODEC_ID_DVVIDEO , 14 }, /* PAL */ - { CODEC_ID_DVVIDEO , 15 }, /* 50M NTSC */ - { CODEC_ID_DVVIDEO , 16 }, /* 50M PAL */ - { CODEC_ID_AC3 , 17 }, - //{ CODEC_ID_NONE, , 18 }, /* Non compressed 24 bit audio */ - { CODEC_ID_MPEG2VIDEO, 20 }, /* MPEG HD */ - { CODEC_ID_MPEG1VIDEO, 22 }, /* NTSC */ - { CODEC_ID_MPEG1VIDEO, 23 }, /* PAL */ - { CODEC_ID_NONE, 0 }, -}; - -#define SERVER_PATH "EXT:/PDR/default/" -#define ES_NAME_PATTERN "EXT:/PDR/default/ES." - -static int gxf_find_lines_index(AVStream *st) -{ - GXFStreamContext *sc = st->priv_data; - int i; - - for (i = 0; i < 6; ++i) { - if (st->codec->height == gxf_lines_tab[i].height) { - sc->lines_index = gxf_lines_tab[i].index; - return 0; - } - } - return -1; -} - -static void gxf_write_padding(ByteIOContext *pb, int64_t to_pad) -{ - for (; to_pad > 0; to_pad--) { - put_byte(pb, 0); - } -} - -static int64_t updatePacketSize(ByteIOContext *pb, int64_t pos) -{ - int64_t curpos; - int size; - - size = url_ftell(pb) - pos; - if (size % 4) { - gxf_write_padding(pb, 4 - size % 4); - size = url_ftell(pb) - pos; - } - curpos = url_ftell(pb); - url_fseek(pb, pos + 6, SEEK_SET); - put_be32(pb, size); - url_fseek(pb, curpos, SEEK_SET); - return curpos - pos; -} - -static int64_t updateSize(ByteIOContext *pb, int64_t pos) -{ - int64_t curpos; - - curpos = url_ftell(pb); - url_fseek(pb, pos, SEEK_SET); - put_be16(pb, curpos - pos - 2); - url_fseek(pb, curpos, SEEK_SET); - return curpos - pos; -} - -static void gxf_write_packet_header(ByteIOContext *pb, GXFPktType type) -{ - put_be32(pb, 0); /* packet leader for synchro */ - put_byte(pb, 1); - put_byte(pb, type); /* map packet */ - put_be32(pb, 0); /* size */ - put_be32(pb, 0); /* reserved */ - put_byte(pb, 0xE1); /* trailer 1 */ - put_byte(pb, 0xE2); /* trailer 2 */ -} - -static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, AVStream *st) -{ - GXFStreamContext *sc = st->priv_data; - char buffer[1024]; - int size, starting_line; - - if (sc->iframes) { - sc->p_per_gop = sc->pframes / sc->iframes; - if (sc->pframes % sc->iframes) - sc->p_per_gop++; - if (sc->pframes) { - sc->b_per_i_or_p = sc->bframes / sc->pframes; - if (sc->bframes % sc->pframes) - sc->b_per_i_or_p++; - } - if (sc->p_per_gop > 9) - sc->p_per_gop = 9; /* ensure value won't take more than one char */ - if (sc->b_per_i_or_p > 9) - sc->b_per_i_or_p = 9; /* ensure value won't take more than one char */ - } - if (st->codec->height == 512 || st->codec->height == 608) - starting_line = 7; // VBI - else if (st->codec->height == 480) - starting_line = 20; - else - starting_line = 23; // default PAL - - size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n" - "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n", - (float)st->codec->bit_rate, sc->p_per_gop, sc->b_per_i_or_p, - st->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, sc->first_gop_closed == 1, - starting_line, st->codec->height / 16); - put_byte(pb, TRACK_MPG_AUX); - put_byte(pb, size + 1); - put_buffer(pb, (uint8_t *)buffer, size + 1); - return size + 3; -} - -static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *sc) -{ - put_byte(pb, 0); /* fields */ - put_byte(pb, 0); /* seconds */ - put_byte(pb, 0); /* minutes */ - put_byte(pb, 0); /* flags + hours */ - /* reserved */ - put_be32(pb, 0); - return 8; -} - -static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index) -{ - ByteIOContext *pb = s->pb; - int64_t pos; - int mpeg = sc->track_type == 4 || sc->track_type == 9; - - /* track description section */ - put_byte(pb, sc->media_type + 0x80); - put_byte(pb, index + 0xC0); - - pos = url_ftell(pb); - put_be16(pb, 0); /* size */ - - /* media file name */ - put_byte(pb, TRACK_NAME); - put_byte(pb, strlen(ES_NAME_PATTERN) + 3); - put_tag(pb, ES_NAME_PATTERN); - put_be16(pb, sc->media_info); - put_byte(pb, 0); - - if (!mpeg) { - /* auxiliary information */ - put_byte(pb, TRACK_AUX); - put_byte(pb, 8); - if (sc->track_type == 3) - gxf_write_timecode_auxiliary(pb, sc); - else - put_le64(pb, 0); - } - - /* file system version */ - put_byte(pb, TRACK_VER); - put_byte(pb, 4); - put_be32(pb, 0); - - if (mpeg) - gxf_write_mpeg_auxiliary(pb, s->streams[index]); - - /* frame rate */ - put_byte(pb, TRACK_FPS); - put_byte(pb, 4); - put_be32(pb, sc->frame_rate_index); - - /* lines per frame */ - put_byte(pb, TRACK_LINES); - put_byte(pb, 4); - put_be32(pb, sc->lines_index); - - /* fields per frame */ - put_byte(pb, TRACK_FPF); - put_byte(pb, 4); - put_be32(pb, sc->fields); - - return updateSize(pb, pos); -} - -static int gxf_write_material_data_section(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos; - const char *filename = strrchr(s->filename, '/'); - - pos = url_ftell(pb); - put_be16(pb, 0); /* size */ - - /* name */ - if (filename) - filename++; - else - filename = s->filename; - put_byte(pb, MAT_NAME); - put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1); - put_tag(pb, SERVER_PATH); - put_tag(pb, filename); - put_byte(pb, 0); - - /* first field */ - put_byte(pb, MAT_FIRST_FIELD); - put_byte(pb, 4); - put_be32(pb, 0); - - /* last field */ - put_byte(pb, MAT_LAST_FIELD); - put_byte(pb, 4); - put_be32(pb, gxf->nb_fields); - - /* reserved */ - put_byte(pb, MAT_MARK_IN); - put_byte(pb, 4); - put_be32(pb, 0); - - put_byte(pb, MAT_MARK_OUT); - put_byte(pb, 4); - put_be32(pb, gxf->nb_fields); - - /* estimated size */ - put_byte(pb, MAT_SIZE); - put_byte(pb, 4); - put_be32(pb, url_fsize(pb) / 1024); - - return updateSize(pb, pos); -} - -static int gxf_write_track_description_section(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos; - int i; - - pos = url_ftell(pb); - put_be16(pb, 0); /* size */ - for (i = 0; i < s->nb_streams; ++i) - gxf_write_track_description(s, s->streams[i]->priv_data, i); - - gxf_write_track_description(s, &gxf->timecode_track, s->nb_streams); - - return updateSize(pb, pos); -} - -static int gxf_write_map_packet(AVFormatContext *s, int rewrite) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos = url_ftell(pb); - - if (!rewrite) { - if (!(gxf->map_offsets_nb % 30)) { - gxf->map_offsets = av_realloc(gxf->map_offsets, - (gxf->map_offsets_nb+30)*sizeof(*gxf->map_offsets)); - if (!gxf->map_offsets) { - av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n"); - return -1; - } - } - gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here - } - - gxf_write_packet_header(pb, PKT_MAP); - - /* preamble */ - put_byte(pb, 0xE0); /* version */ - put_byte(pb, 0xFF); /* reserved */ - - gxf_write_material_data_section(s); - gxf_write_track_description_section(s); - - return updatePacketSize(pb, pos); -} - -static int gxf_write_flt_packet(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos = url_ftell(pb); - int fields_per_flt = (gxf->nb_fields+1) / 1000 + 1; - int flt_entries = gxf->nb_fields / fields_per_flt - 1; - int i = 0; - - gxf_write_packet_header(pb, PKT_FLT); - - put_le32(pb, fields_per_flt); /* number of fields */ - put_le32(pb, flt_entries); /* number of active flt entries */ - - if (gxf->flt_entries) { - for (i = 0; i < flt_entries; i++) - put_le32(pb, gxf->flt_entries[(i*fields_per_flt)>>1]); - } - - for (; i < 1000; i++) - put_le32(pb, 0); - - return updatePacketSize(pb, pos); -} - -static int gxf_write_umf_material_description(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int timecode_base = gxf->time_base.den == 60000 ? 60 : 50; - - // XXX drop frame - uint32_t timecode = - gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours - gxf->nb_fields / (timecode_base * 60) % 60 << 16 | // minutes - gxf->nb_fields / timecode_base % 60 << 8 | // seconds - gxf->nb_fields % timecode_base; // fields - - put_le32(pb, gxf->flags); - put_le32(pb, gxf->nb_fields); /* length of the longest track */ - put_le32(pb, gxf->nb_fields); /* length of the shortest track */ - put_le32(pb, 0); /* mark in */ - put_le32(pb, gxf->nb_fields); /* mark out */ - put_le32(pb, 0); /* timecode mark in */ - put_le32(pb, timecode); /* timecode mark out */ - put_le64(pb, s->timestamp); /* modification time */ - put_le64(pb, s->timestamp); /* creation time */ - put_le16(pb, 0); /* reserved */ - put_le16(pb, 0); /* reserved */ - put_le16(pb, gxf->audio_tracks); - put_le16(pb, 1); /* timecode track count */ - put_le16(pb, 0); /* reserved */ - put_le16(pb, gxf->mpeg_tracks); - return 48; -} - -static int gxf_write_umf_payload(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - - put_le32(pb, gxf->umf_length); /* total length of the umf data */ - put_le32(pb, 3); /* version */ - put_le32(pb, s->nb_streams+1); - put_le32(pb, gxf->umf_track_offset); /* umf track section offset */ - put_le32(pb, gxf->umf_track_size); - put_le32(pb, s->nb_streams+1); - put_le32(pb, gxf->umf_media_offset); - put_le32(pb, gxf->umf_media_size); - put_le32(pb, gxf->umf_length); /* user data offset */ - put_le32(pb, 0); /* user data size */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - return 48; -} - -static int gxf_write_umf_track_description(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - GXFContext *gxf = s->priv_data; - int64_t pos = url_ftell(pb); - int i; - - gxf->umf_track_offset = pos - gxf->umf_start_offset; - for (i = 0; i < s->nb_streams; ++i) { - GXFStreamContext *sc = s->streams[i]->priv_data; - put_le16(pb, sc->media_info); - put_le16(pb, 1); - } - - put_le16(pb, gxf->timecode_track.media_info); - put_le16(pb, 1); - - return url_ftell(pb) - pos; -} - -static int gxf_write_umf_media_mpeg(ByteIOContext *pb, AVStream *st) -{ - GXFStreamContext *sc = st->priv_data; - - if (st->codec->pix_fmt == PIX_FMT_YUV422P) - put_le32(pb, 2); - else - put_le32(pb, 1); /* default to 420 */ - put_le32(pb, sc->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */ - put_le32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */ - put_le32(pb, 1); /* I picture per GOP */ - put_le32(pb, sc->p_per_gop); - put_le32(pb, sc->b_per_i_or_p); - if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) - put_le32(pb, 2); - else if (st->codec->codec_id == CODEC_ID_MPEG1VIDEO) - put_le32(pb, 1); - else - put_le32(pb, 0); - put_le32(pb, 0); /* reserved */ - return 32; -} - -static int gxf_write_umf_media_timecode(ByteIOContext *pb, GXFStreamContext *sc) -{ - put_le32(pb, 1); /* non drop frame */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - return 32; -} - -static int gxf_write_umf_media_dv(ByteIOContext *pb, GXFStreamContext *sc) -{ - int i; - - for (i = 0; i < 8; i++) { - put_be32(pb, 0); - } - return 32; -} - -static int gxf_write_umf_media_audio(ByteIOContext *pb, GXFStreamContext *sc) -{ - put_le64(pb, av_dbl2int(1)); /* sound level to begin to */ - put_le64(pb, av_dbl2int(1)); /* sound level to begin to */ - put_le32(pb, 0); /* number of fields over which to ramp up sound level */ - put_le32(pb, 0); /* number of fields over which to ramp down sound level */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - return 32; -} - -#if 0 -static int gxf_write_umf_media_mjpeg(ByteIOContext *pb, GXFStreamContext *sc) -{ - put_be64(pb, 0); /* FIXME FLOAT max chroma quant level */ - put_be64(pb, 0); /* FIXME FLOAT max luma quant level */ - put_be64(pb, 0); /* FIXME FLOAT min chroma quant level */ - put_be64(pb, 0); /* FIXME FLOAT min luma quant level */ - return 32; -} -#endif - -static int gxf_write_umf_media_description(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos; - int i, j; - - pos = url_ftell(pb); - gxf->umf_media_offset = pos - gxf->umf_start_offset; - for (i = 0; i <= s->nb_streams; ++i) { - GXFStreamContext *sc; - int64_t startpos, curpos; - - if (i == s->nb_streams) - sc = &gxf->timecode_track; - else - sc = s->streams[i]->priv_data; - - startpos = url_ftell(pb); - put_le16(pb, 0); /* length */ - put_le16(pb, sc->media_info); - put_le16(pb, 0); /* reserved */ - put_le16(pb, 0); /* reserved */ - put_le32(pb, gxf->nb_fields); - put_le32(pb, 0); /* attributes rw, ro */ - put_le32(pb, 0); /* mark in */ - put_le32(pb, gxf->nb_fields); /* mark out */ - put_buffer(pb, ES_NAME_PATTERN, sizeof(ES_NAME_PATTERN)); - put_be16(pb, sc->media_info); - for (j = sizeof(ES_NAME_PATTERN)+2; j < 88; j++) - put_byte(pb, 0); - put_le32(pb, sc->track_type); - put_le32(pb, sc->sample_rate); - put_le32(pb, sc->sample_size); - put_le32(pb, 0); /* reserved */ - - if (sc == &gxf->timecode_track) - gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */ - else { - AVStream *st = s->streams[i]; - switch (st->codec->codec_id) { - case CODEC_ID_MPEG2VIDEO: - gxf_write_umf_media_mpeg(pb, st); - break; - case CODEC_ID_PCM_S16LE: - gxf_write_umf_media_audio(pb, sc); - break; - case CODEC_ID_DVVIDEO: - gxf_write_umf_media_dv(pb, sc); - break; - } - } - - curpos = url_ftell(pb); - url_fseek(pb, startpos, SEEK_SET); - put_le16(pb, curpos - startpos); - url_fseek(pb, curpos, SEEK_SET); - } - return url_ftell(pb) - pos; -} - -static int gxf_write_umf_packet(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos = url_ftell(pb); - - gxf_write_packet_header(pb, PKT_UMF); - - /* preamble */ - put_byte(pb, 3); /* first and last (only) packet */ - put_be32(pb, gxf->umf_length); /* data length */ - - gxf->umf_start_offset = url_ftell(pb); - gxf_write_umf_payload(s); - gxf_write_umf_material_description(s); - gxf->umf_track_size = gxf_write_umf_track_description(s); - gxf->umf_media_size = gxf_write_umf_media_description(s); - gxf->umf_length = url_ftell(pb) - gxf->umf_start_offset; - return updatePacketSize(pb, pos); -} - -static const int GXF_samples_per_frame[] = { 32768, 0 }; - -static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc) -{ - if (!vsc) - return; - - sc->media_type = vsc->sample_rate == 60 ? 7 : 8; - sc->sample_rate = vsc->sample_rate; - sc->media_info = ('T'<<8) | '0'; - sc->track_type = 3; - sc->frame_rate_index = vsc->frame_rate_index; - sc->lines_index = vsc->lines_index; - sc->sample_size = 16; - sc->fields = vsc->fields; -} - -static int gxf_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - GXFContext *gxf = s->priv_data; - GXFStreamContext *vsc = NULL; - uint8_t tracks[255] = {0}; - int i, media_info = 0; - - if (url_is_streamed(pb)) { - av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome"); - return -1; - } - - gxf->flags |= 0x00080000; /* material is simple clip */ - for (i = 0; i < s->nb_streams; ++i) { - AVStream *st = s->streams[i]; - GXFStreamContext *sc = av_mallocz(sizeof(*sc)); - if (!sc) - return AVERROR(ENOMEM); - st->priv_data = sc; - - sc->media_type = ff_codec_get_tag(gxf_media_types, st->codec->codec_id); - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (st->codec->codec_id != CODEC_ID_PCM_S16LE) { - av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n"); - return -1; - } - if (st->codec->sample_rate != 48000) { - av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n"); - return -1; - } - if (st->codec->channels != 1) { - av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n"); - return -1; - } - sc->track_type = 2; - sc->sample_rate = st->codec->sample_rate; - av_set_pts_info(st, 64, 1, sc->sample_rate); - sc->sample_size = 16; - sc->frame_rate_index = -2; - sc->lines_index = -2; - sc->fields = -2; - gxf->audio_tracks++; - gxf->flags |= 0x04000000; /* audio is 16 bit pcm */ - media_info = 'A'; - } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (i != 0) { - av_log(s, AV_LOG_ERROR, "video stream must be the first track\n"); - return -1; - } - /* FIXME check from time_base ? */ - if (st->codec->height == 480 || st->codec->height == 512) { /* NTSC or NTSC+VBI */ - sc->frame_rate_index = 5; - sc->sample_rate = 60; - gxf->flags |= 0x00000080; - gxf->time_base = (AVRational){ 1001, 60000 }; - } else { /* assume PAL */ - sc->frame_rate_index = 6; - sc->media_type++; - sc->sample_rate = 50; - gxf->flags |= 0x00000040; - gxf->time_base = (AVRational){ 1, 50 }; - } - av_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den); - if (gxf_find_lines_index(st) < 0) - sc->lines_index = -1; - sc->sample_size = st->codec->bit_rate; - sc->fields = 2; /* interlaced */ - - vsc = sc; - - switch (st->codec->codec_id) { - case CODEC_ID_MJPEG: - sc->track_type = 1; - gxf->flags |= 0x00004000; - media_info = 'J'; - break; - case CODEC_ID_MPEG1VIDEO: - sc->track_type = 9; - gxf->mpeg_tracks++; - media_info = 'L'; - break; - case CODEC_ID_MPEG2VIDEO: - sc->first_gop_closed = -1; - sc->track_type = 4; - gxf->mpeg_tracks++; - gxf->flags |= 0x00008000; - media_info = 'M'; - break; - case CODEC_ID_DVVIDEO: - if (st->codec->pix_fmt == PIX_FMT_YUV422P) { - sc->media_type += 2; - sc->track_type = 6; - gxf->flags |= 0x00002000; - media_info = 'E'; - } else { - sc->track_type = 5; - gxf->flags |= 0x00001000; - media_info = 'D'; - } - break; - default: - av_log(s, AV_LOG_ERROR, "video codec not supported\n"); - return -1; - } - } - /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */ - sc->media_info = media_info<<8 | ('0'+tracks[media_info]++); - sc->order = s->nb_streams - st->index; - } - - if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0) - return -1; - - gxf_init_timecode_track(&gxf->timecode_track, vsc); - gxf->flags |= 0x200000; // time code track is non-drop frame - - gxf_write_map_packet(s, 0); - gxf_write_flt_packet(s); - gxf_write_umf_packet(s); - - gxf->packet_count = 3; - - put_flush_packet(pb); - return 0; -} - -static int gxf_write_eos_packet(ByteIOContext *pb) -{ - int64_t pos = url_ftell(pb); - - gxf_write_packet_header(pb, PKT_EOS); - return updatePacketSize(pb, pos); -} - -static int gxf_write_trailer(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t end; - int i; - - ff_audio_interleave_close(s); - - gxf_write_eos_packet(pb); - end = url_ftell(pb); - url_fseek(pb, 0, SEEK_SET); - /* overwrite map, flt and umf packets with new values */ - gxf_write_map_packet(s, 1); - gxf_write_flt_packet(s); - gxf_write_umf_packet(s); - put_flush_packet(pb); - /* update duration in all map packets */ - for (i = 1; i < gxf->map_offsets_nb; i++) { - url_fseek(pb, gxf->map_offsets[i], SEEK_SET); - gxf_write_map_packet(s, 1); - put_flush_packet(pb); - } - - url_fseek(pb, end, SEEK_SET); - - av_freep(&gxf->flt_entries); - av_freep(&gxf->map_offsets); - - return 0; -} - -static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size) -{ - uint32_t c=-1; - int i; - for(i=0; ifirst_gop_closed == -1) /* GOP start code */ - sc->first_gop_closed= (buf[i+4]>>6)&1; - } - return (buf[i+1]>>3)&7; -} - -static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[pkt->stream_index]; - GXFStreamContext *sc = st->priv_data; - unsigned field_nb; - /* If the video is frame-encoded, the frame numbers shall be represented by - * even field numbers. - * see SMPTE360M-2004 6.4.2.1.3 Media field number */ - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - field_nb = gxf->nb_fields; - } else { - field_nb = av_rescale_rnd(pkt->dts, gxf->time_base.den, - (int64_t)48000*gxf->time_base.num, AV_ROUND_UP); - } - - put_byte(pb, sc->media_type); - put_byte(pb, st->index); - put_be32(pb, field_nb); - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - put_be16(pb, 0); - put_be16(pb, size / 2); - } else if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) { - int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size); - if (frame_type == FF_I_TYPE) { - put_byte(pb, 0x0d); - sc->iframes++; - } else if (frame_type == FF_B_TYPE) { - put_byte(pb, 0x0f); - sc->bframes++; - } else { - put_byte(pb, 0x0e); - sc->pframes++; - } - put_be24(pb, size); - } else if (st->codec->codec_id == CODEC_ID_DVVIDEO) { - put_byte(pb, size / 4096); - put_be24(pb, 0); - } else - put_be32(pb, size); - put_be32(pb, field_nb); - put_byte(pb, 1); /* flags */ - put_byte(pb, 0); /* reserved */ - return 16; -} - -static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - GXFContext *gxf = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[pkt->stream_index]; - int64_t pos = url_ftell(pb); - int padding = 0; - - gxf_write_packet_header(pb, PKT_MEDIA); - if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */ - padding = 4 - pkt->size % 4; - else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - padding = GXF_AUDIO_PACKET_SIZE - pkt->size; - gxf_write_media_preamble(s, pkt, pkt->size + padding); - put_buffer(pb, pkt->data, pkt->size); - gxf_write_padding(pb, padding); - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (!(gxf->flt_entries_nb % 500)) { - gxf->flt_entries = av_realloc(gxf->flt_entries, - (gxf->flt_entries_nb+500)*sizeof(*gxf->flt_entries)); - if (!gxf->flt_entries) { - av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n"); - return -1; - } - } - gxf->flt_entries[gxf->flt_entries_nb++] = url_ftell(pb) / 1024; - gxf->nb_fields += 2; // count fields - } - - updatePacketSize(pb, pos); - - gxf->packet_count++; - if (gxf->packet_count == 100) { - gxf_write_map_packet(s, 0); - gxf->packet_count = 0; - } - - put_flush_packet(pb); - - return 0; -} - -static int gxf_compare_field_nb(AVFormatContext *s, AVPacket *next, AVPacket *cur) -{ - GXFContext *gxf = s->priv_data; - AVPacket *pkt[2] = { cur, next }; - int i, field_nb[2]; - GXFStreamContext *sc[2]; - - for (i = 0; i < 2; i++) { - AVStream *st = s->streams[pkt[i]->stream_index]; - sc[i] = st->priv_data; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - field_nb[i] = av_rescale_rnd(pkt[i]->dts, gxf->time_base.den, - (int64_t)48000*gxf->time_base.num, AV_ROUND_UP); - field_nb[i] &= ~1; // compare against even field number because audio must be before video - } else - field_nb[i] = pkt[i]->dts; // dts are field based - } - - return field_nb[1] > field_nb[0] || - (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order); -} - -static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) -{ - if (pkt && s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO) - pkt->duration = 2; // enforce 2 fields - return ff_audio_rechunk_interleave(s, out, pkt, flush, - av_interleave_packet_per_dts, gxf_compare_field_nb); -} - -AVOutputFormat gxf_muxer = { - "gxf", - NULL_IF_CONFIG_SMALL("GXF format"), - NULL, - "gxf", - sizeof(GXFContext), - CODEC_ID_PCM_S16LE, - CODEC_ID_MPEG2VIDEO, - gxf_write_header, - gxf_write_packet, - gxf_write_trailer, - 0, - NULL, - gxf_interleave_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/http.c b/tizen/distrib/ffmpeg/libavformat/http.c deleted file mode 100644 index e697578..0000000 --- a/tizen/distrib/ffmpeg/libavformat/http.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * HTTP protocol for ffmpeg client - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avstring.h" -#include "avformat.h" -#include -#include -#include "internal.h" -#include "network.h" -#include "os_support.h" -#include "httpauth.h" - -/* XXX: POST protocol is not completely implemented because ffmpeg uses - only a subset of it. */ - -/* used for protocol handling */ -#define BUFFER_SIZE 1024 -#define URL_SIZE 4096 -#define MAX_REDIRECTS 8 - -typedef struct { - URLContext *hd; - unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end; - int line_count; - int http_code; - int64_t chunksize; /**< Used if "Transfer-Encoding: chunked" otherwise -1. */ - int64_t off, filesize; - char location[URL_SIZE]; - HTTPAuthState auth_state; -} HTTPContext; - -static int http_connect(URLContext *h, const char *path, const char *hoststr, - const char *auth, int *new_location); -static int http_write(URLContext *h, uint8_t *buf, int size); - - -/* return non zero if error */ -static int http_open_cnx(URLContext *h) -{ - const char *path, *proxy_path; - char hostname[1024], hoststr[1024]; - char auth[1024]; - char path1[1024]; - char buf[1024]; - int port, use_proxy, err, location_changed = 0, redirects = 0; - HTTPAuthType cur_auth_type; - HTTPContext *s = h->priv_data; - URLContext *hd = NULL; - - proxy_path = getenv("http_proxy"); - use_proxy = (proxy_path != NULL) && !getenv("no_proxy") && - av_strstart(proxy_path, "http://", NULL); - - /* fill the dest addr */ - redo: - /* needed in any case to build the host string */ - ff_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - path1, sizeof(path1), s->location); - ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); - - if (use_proxy) { - ff_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - NULL, 0, proxy_path); - path = s->location; - } else { - if (path1[0] == '\0') - path = "/"; - else - path = path1; - } - if (port < 0) - port = 80; - - ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); - err = url_open(&hd, buf, URL_RDWR); - if (err < 0) - goto fail; - - s->hd = hd; - cur_auth_type = s->auth_state.auth_type; - if (http_connect(h, path, hoststr, auth, &location_changed) < 0) - goto fail; - if (s->http_code == 401) { - if (cur_auth_type == HTTP_AUTH_NONE && s->auth_state.auth_type != HTTP_AUTH_NONE) { - url_close(hd); - goto redo; - } else - goto fail; - } - if ((s->http_code == 302 || s->http_code == 303) && location_changed == 1) { - /* url moved, get next */ - url_close(hd); - if (redirects++ >= MAX_REDIRECTS) - return AVERROR(EIO); - location_changed = 0; - goto redo; - } - return 0; - fail: - if (hd) - url_close(hd); - return AVERROR(EIO); -} - -static int http_open(URLContext *h, const char *uri, int flags) -{ - HTTPContext *s; - int ret; - - h->is_streamed = 1; - - s = av_malloc(sizeof(HTTPContext)); - if (!s) { - return AVERROR(ENOMEM); - } - h->priv_data = s; - s->filesize = -1; - s->chunksize = -1; - s->off = 0; - memset(&s->auth_state, 0, sizeof(s->auth_state)); - av_strlcpy(s->location, uri, URL_SIZE); - - ret = http_open_cnx(h); - if (ret != 0) - av_free (s); - return ret; -} -static int http_getc(HTTPContext *s) -{ - int len; - if (s->buf_ptr >= s->buf_end) { - len = url_read(s->hd, s->buffer, BUFFER_SIZE); - if (len < 0) { - return AVERROR(EIO); - } else if (len == 0) { - return -1; - } else { - s->buf_ptr = s->buffer; - s->buf_end = s->buffer + len; - } - } - return *s->buf_ptr++; -} - -static int http_get_line(HTTPContext *s, char *line, int line_size) -{ - int ch; - char *q; - - q = line; - for(;;) { - ch = http_getc(s); - if (ch < 0) - return AVERROR(EIO); - if (ch == '\n') { - /* process line */ - if (q > line && q[-1] == '\r') - q--; - *q = '\0'; - - return 0; - } else { - if ((q - line) < line_size - 1) - *q++ = ch; - } - } -} - -static int process_line(URLContext *h, char *line, int line_count, - int *new_location) -{ - HTTPContext *s = h->priv_data; - char *tag, *p; - - /* end of header */ - if (line[0] == '\0') - return 0; - - p = line; - if (line_count == 0) { - while (!isspace(*p) && *p != '\0') - p++; - while (isspace(*p)) - p++; - s->http_code = strtol(p, NULL, 10); - - dprintf(NULL, "http_code=%d\n", s->http_code); - - /* error codes are 4xx and 5xx, but regard 401 as a success, so we - * don't abort until all headers have been parsed. */ - if (s->http_code >= 400 && s->http_code < 600 && s->http_code != 401) - return -1; - } else { - while (*p != '\0' && *p != ':') - p++; - if (*p != ':') - return 1; - - *p = '\0'; - tag = line; - p++; - while (isspace(*p)) - p++; - if (!strcmp(tag, "Location")) { - strcpy(s->location, p); - *new_location = 1; - } else if (!strcmp (tag, "Content-Length") && s->filesize == -1) { - s->filesize = atoll(p); - } else if (!strcmp (tag, "Content-Range")) { - /* "bytes $from-$to/$document_size" */ - const char *slash; - if (!strncmp (p, "bytes ", 6)) { - p += 6; - s->off = atoll(p); - if ((slash = strchr(p, '/')) && strlen(slash) > 0) - s->filesize = atoll(slash+1); - } - h->is_streamed = 0; /* we _can_ in fact seek */ - } else if (!strcmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) { - s->filesize = -1; - s->chunksize = 0; - } else if (!strcmp (tag, "WWW-Authenticate")) { - ff_http_auth_handle_header(&s->auth_state, tag, p); - } else if (!strcmp (tag, "Authentication-Info")) { - ff_http_auth_handle_header(&s->auth_state, tag, p); - } - } - return 1; -} - -static int http_connect(URLContext *h, const char *path, const char *hoststr, - const char *auth, int *new_location) -{ - HTTPContext *s = h->priv_data; - int post, err; - char line[1024]; - char *authstr = NULL; - int64_t off = s->off; - - - /* send http header */ - post = h->flags & URL_WRONLY; - authstr = ff_http_auth_create_response(&s->auth_state, auth, path, - post ? "POST" : "GET"); - snprintf(s->buffer, sizeof(s->buffer), - "%s %s HTTP/1.1\r\n" - "User-Agent: %s\r\n" - "Accept: */*\r\n" - "Range: bytes=%"PRId64"-\r\n" - "Host: %s\r\n" - "%s" - "Connection: close\r\n" - "%s" - "\r\n", - post ? "POST" : "GET", - path, - LIBAVFORMAT_IDENT, - s->off, - hoststr, - authstr ? authstr : "", - post ? "Transfer-Encoding: chunked\r\n" : ""); - - av_freep(&authstr); - if (http_write(h, s->buffer, strlen(s->buffer)) < 0) - return AVERROR(EIO); - - /* init input buffer */ - s->buf_ptr = s->buffer; - s->buf_end = s->buffer; - s->line_count = 0; - s->off = 0; - s->filesize = -1; - if (post) { - /* always use chunked encoding for upload data */ - s->chunksize = 0; - return 0; - } - - /* wait for header */ - for(;;) { - if (http_get_line(s, line, sizeof(line)) < 0) - return AVERROR(EIO); - - dprintf(NULL, "header='%s'\n", line); - - err = process_line(h, line, s->line_count, new_location); - if (err < 0) - return err; - if (err == 0) - break; - s->line_count++; - } - - return (off == s->off) ? 0 : -1; -} - - -static int http_read(URLContext *h, uint8_t *buf, int size) -{ - HTTPContext *s = h->priv_data; - int len; - - if (s->chunksize >= 0) { - if (!s->chunksize) { - char line[32]; - - for(;;) { - do { - if (http_get_line(s, line, sizeof(line)) < 0) - return AVERROR(EIO); - } while (!*line); /* skip CR LF from last chunk */ - - s->chunksize = strtoll(line, NULL, 16); - - dprintf(NULL, "Chunked encoding data size: %"PRId64"'\n", s->chunksize); - - if (!s->chunksize) - return 0; - break; - } - } - size = FFMIN(size, s->chunksize); - } - /* read bytes from input buffer first */ - len = s->buf_end - s->buf_ptr; - if (len > 0) { - if (len > size) - len = size; - memcpy(buf, s->buf_ptr, len); - s->buf_ptr += len; - } else { - len = url_read(s->hd, buf, size); - } - if (len > 0) { - s->off += len; - if (s->chunksize > 0) - s->chunksize -= len; - } - return len; -} - -/* used only when posting data */ -static int http_write(URLContext *h, uint8_t *buf, int size) -{ - char temp[11]; /* 32-bit hex + CRLF + nul */ - int ret; - char crlf[] = "\r\n"; - HTTPContext *s = h->priv_data; - - if (s->chunksize == -1) { - /* headers are sent without any special encoding */ - return url_write(s->hd, buf, size); - } - - /* silently ignore zero-size data since chunk encoding that would - * signal EOF */ - if (size > 0) { - /* upload data using chunked encoding */ - snprintf(temp, sizeof(temp), "%x\r\n", size); - - if ((ret = url_write(s->hd, temp, strlen(temp))) < 0 || - (ret = url_write(s->hd, buf, size)) < 0 || - (ret = url_write(s->hd, crlf, sizeof(crlf) - 1)) < 0) - return ret; - } - return size; -} - -static int http_close(URLContext *h) -{ - int ret = 0; - char footer[] = "0\r\n\r\n"; - HTTPContext *s = h->priv_data; - - /* signal end of chunked encoding if used */ - if ((h->flags & URL_WRONLY) && s->chunksize != -1) { - ret = url_write(s->hd, footer, sizeof(footer) - 1); - ret = ret > 0 ? 0 : ret; - } - - url_close(s->hd); - av_free(s); - return ret; -} - -static int64_t http_seek(URLContext *h, int64_t off, int whence) -{ - HTTPContext *s = h->priv_data; - URLContext *old_hd = s->hd; - int64_t old_off = s->off; - uint8_t old_buf[BUFFER_SIZE]; - int old_buf_size; - - if (whence == AVSEEK_SIZE) - return s->filesize; - else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed) - return -1; - - /* we save the old context in case the seek fails */ - old_buf_size = s->buf_end - s->buf_ptr; - memcpy(old_buf, s->buf_ptr, old_buf_size); - s->hd = NULL; - if (whence == SEEK_CUR) - off += s->off; - else if (whence == SEEK_END) - off += s->filesize; - s->off = off; - - /* if it fails, continue on old connection */ - if (http_open_cnx(h) < 0) { - memcpy(s->buffer, old_buf, old_buf_size); - s->buf_ptr = s->buffer; - s->buf_end = s->buffer + old_buf_size; - s->hd = old_hd; - s->off = old_off; - return -1; - } - url_close(old_hd); - return off; -} - -static int -http_get_file_handle(URLContext *h) -{ - HTTPContext *s = h->priv_data; - return url_get_file_handle(s->hd); -} - -URLProtocol http_protocol = { - "http", - http_open, - http_read, - http_write, - http_seek, - http_close, - .url_get_file_handle = http_get_file_handle, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/httpauth.c b/tizen/distrib/ffmpeg/libavformat/httpauth.c deleted file mode 100644 index cef2756..0000000 --- a/tizen/distrib/ffmpeg/libavformat/httpauth.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * HTTP authentication - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "httpauth.h" -#include "libavutil/base64.h" -#include "libavutil/avstring.h" -#include "internal.h" -#include "libavutil/random_seed.h" -#include "libavutil/md5.h" -#include "avformat.h" -#include - -static void parse_key_value(const char *params, - void (*callback_get_buf)(HTTPAuthState *state, - const char *key, int key_len, - char **dest, int *dest_len), HTTPAuthState *state) -{ - const char *ptr = params; - - /* Parse key=value pairs. */ - for (;;) { - const char *key; - char *dest = NULL, *dest_end; - int key_len, dest_len = 0; - - /* Skip whitespace and potential commas. */ - while (*ptr && (isspace(*ptr) || *ptr == ',')) - ptr++; - if (!*ptr) - break; - - key = ptr; - - if (!(ptr = strchr(key, '='))) - break; - ptr++; - key_len = ptr - key; - - callback_get_buf(state, key, key_len, &dest, &dest_len); - dest_end = dest + dest_len - 1; - - if (*ptr == '\"') { - ptr++; - while (*ptr && *ptr != '\"') { - if (*ptr == '\\') { - if (!ptr[1]) - break; - if (dest && dest < dest_end) - *dest++ = ptr[1]; - ptr += 2; - } else { - if (dest && dest < dest_end) - *dest++ = *ptr; - ptr++; - } - } - if (*ptr == '\"') - ptr++; - } else { - for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++) - if (dest && dest < dest_end) - *dest++ = *ptr; - } - if (dest) - *dest = 0; - } -} - -static void handle_basic_params(HTTPAuthState *state, const char *key, - int key_len, char **dest, int *dest_len) -{ - if (!strncmp(key, "realm=", key_len)) { - *dest = state->realm; - *dest_len = sizeof(state->realm); - } -} - -static void handle_digest_params(HTTPAuthState *state, const char *key, - int key_len, char **dest, int *dest_len) -{ - DigestParams *digest = &state->digest_params; - - if (!strncmp(key, "realm=", key_len)) { - *dest = state->realm; - *dest_len = sizeof(state->realm); - } else if (!strncmp(key, "nonce=", key_len)) { - *dest = digest->nonce; - *dest_len = sizeof(digest->nonce); - } else if (!strncmp(key, "opaque=", key_len)) { - *dest = digest->opaque; - *dest_len = sizeof(digest->opaque); - } else if (!strncmp(key, "algorithm=", key_len)) { - *dest = digest->algorithm; - *dest_len = sizeof(digest->algorithm); - } else if (!strncmp(key, "qop=", key_len)) { - *dest = digest->qop; - *dest_len = sizeof(digest->qop); - } -} - -static void handle_digest_update(HTTPAuthState *state, const char *key, - int key_len, char **dest, int *dest_len) -{ - DigestParams *digest = &state->digest_params; - - if (!strncmp(key, "nextnonce=", key_len)) { - *dest = digest->nonce; - *dest_len = sizeof(digest->nonce); - } -} - -static void choose_qop(char *qop, int size) -{ - char *ptr = strstr(qop, "auth"); - char *end = ptr + strlen("auth"); - - if (ptr && (!*end || isspace(*end) || *end == ',') && - (ptr == qop || isspace(ptr[-1]) || ptr[-1] == ',')) { - av_strlcpy(qop, "auth", size); - } else { - qop[0] = 0; - } -} - -void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, - const char *value) -{ - if (!strcmp(key, "WWW-Authenticate")) { - const char *p; - if (av_stristart(value, "Basic ", &p) && - state->auth_type <= HTTP_AUTH_BASIC) { - state->auth_type = HTTP_AUTH_BASIC; - state->realm[0] = 0; - parse_key_value(p, handle_basic_params, state); - } else if (av_stristart(value, "Digest ", &p) && - state->auth_type <= HTTP_AUTH_DIGEST) { - state->auth_type = HTTP_AUTH_DIGEST; - memset(&state->digest_params, 0, sizeof(DigestParams)); - state->realm[0] = 0; - parse_key_value(p, handle_digest_params, state); - choose_qop(state->digest_params.qop, - sizeof(state->digest_params.qop)); - } - } else if (!strcmp(key, "Authentication-Info")) { - parse_key_value(value, handle_digest_update, state); - } -} - - -static void update_md5_strings(struct AVMD5 *md5ctx, ...) -{ - va_list vl; - - va_start(vl, md5ctx); - while (1) { - const char* str = va_arg(vl, const char*); - if (!str) - break; - av_md5_update(md5ctx, str, strlen(str)); - } - va_end(vl); -} - -/* Generate a digest reply, according to RFC 2617. */ -static char *make_digest_auth(HTTPAuthState *state, const char *username, - const char *password, const char *uri, - const char *method) -{ - DigestParams *digest = &state->digest_params; - int len; - uint32_t cnonce_buf[2]; - char cnonce[17]; - char nc[9]; - int i; - char A1hash[33], A2hash[33], response[33]; - struct AVMD5 *md5ctx; - uint8_t hash[16]; - char *authstr; - - digest->nc++; - snprintf(nc, sizeof(nc), "%08x", digest->nc); - - /* Generate a client nonce. */ - for (i = 0; i < 2; i++) - cnonce_buf[i] = ff_random_get_seed(); - ff_data_to_hex(cnonce, (const uint8_t*) cnonce_buf, sizeof(cnonce_buf), 1); - cnonce[2*sizeof(cnonce_buf)] = 0; - - md5ctx = av_malloc(av_md5_size); - if (!md5ctx) - return NULL; - - av_md5_init(md5ctx); - update_md5_strings(md5ctx, username, ":", state->realm, ":", password, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(A1hash, hash, 16, 1); - A1hash[32] = 0; - - if (!strcmp(digest->algorithm, "") || !strcmp(digest->algorithm, "MD5")) { - } else if (!strcmp(digest->algorithm, "MD5-sess")) { - av_md5_init(md5ctx); - update_md5_strings(md5ctx, A1hash, ":", digest->nonce, ":", cnonce, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(A1hash, hash, 16, 1); - A1hash[32] = 0; - } else { - /* Unsupported algorithm */ - av_free(md5ctx); - return NULL; - } - - av_md5_init(md5ctx); - update_md5_strings(md5ctx, method, ":", uri, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(A2hash, hash, 16, 1); - A2hash[32] = 0; - - av_md5_init(md5ctx); - update_md5_strings(md5ctx, A1hash, ":", digest->nonce, NULL); - if (!strcmp(digest->qop, "auth") || !strcmp(digest->qop, "auth-int")) { - update_md5_strings(md5ctx, ":", nc, ":", cnonce, ":", digest->qop, NULL); - } - update_md5_strings(md5ctx, ":", A2hash, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(response, hash, 16, 1); - response[32] = 0; - - av_free(md5ctx); - - if (!strcmp(digest->qop, "") || !strcmp(digest->qop, "auth")) { - } else if (!strcmp(digest->qop, "auth-int")) { - /* qop=auth-int not supported */ - return NULL; - } else { - /* Unsupported qop value. */ - return NULL; - } - - len = strlen(username) + strlen(state->realm) + strlen(digest->nonce) + - strlen(uri) + strlen(response) + strlen(digest->algorithm) + - strlen(digest->opaque) + strlen(digest->qop) + strlen(cnonce) + - strlen(nc) + 150; - - authstr = av_malloc(len); - if (!authstr) - return NULL; - snprintf(authstr, len, "Authorization: Digest "); - - /* TODO: Escape the quoted strings properly. */ - av_strlcatf(authstr, len, "username=\"%s\"", username); - av_strlcatf(authstr, len, ",realm=\"%s\"", state->realm); - av_strlcatf(authstr, len, ",nonce=\"%s\"", digest->nonce); - av_strlcatf(authstr, len, ",uri=\"%s\"", uri); - av_strlcatf(authstr, len, ",response=\"%s\"", response); - if (digest->algorithm[0]) - av_strlcatf(authstr, len, ",algorithm=%s", digest->algorithm); - if (digest->opaque[0]) - av_strlcatf(authstr, len, ",opaque=\"%s\"", digest->opaque); - if (digest->qop[0]) { - av_strlcatf(authstr, len, ",qop=\"%s\"", digest->qop); - av_strlcatf(authstr, len, ",cnonce=\"%s\"", cnonce); - av_strlcatf(authstr, len, ",nc=%s", nc); - } - - av_strlcatf(authstr, len, "\r\n"); - - return authstr; -} - -char *ff_http_auth_create_response(HTTPAuthState *state, const char *auth, - const char *path, const char *method) -{ - char *authstr = NULL; - - if (!auth || !strchr(auth, ':')) - return NULL; - - if (state->auth_type == HTTP_AUTH_BASIC) { - int auth_b64_len = (strlen(auth) + 2) / 3 * 4 + 1; - int len = auth_b64_len + 30; - char *ptr; - authstr = av_malloc(len); - if (!authstr) - return NULL; - snprintf(authstr, len, "Authorization: Basic "); - ptr = authstr + strlen(authstr); - av_base64_encode(ptr, auth_b64_len, auth, strlen(auth)); - av_strlcat(ptr, "\r\n", len); - } else if (state->auth_type == HTTP_AUTH_DIGEST) { - char *username = av_strdup(auth), *password; - - if (!username) - return NULL; - - if ((password = strchr(username, ':'))) { - *password++ = 0; - authstr = make_digest_auth(state, username, password, path, method); - } - av_free(username); - } - return authstr; -} - diff --git a/tizen/distrib/ffmpeg/libavformat/httpauth.h b/tizen/distrib/ffmpeg/libavformat/httpauth.h deleted file mode 100644 index ebab3fc..0000000 --- a/tizen/distrib/ffmpeg/libavformat/httpauth.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * HTTP authentication - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_HTTPAUTH_H -#define AVFORMAT_HTTPAUTH_H - -/** - * Authentication types, ordered from weakest to strongest. - */ -typedef enum HTTPAuthType { - HTTP_AUTH_NONE = 0, /**< No authentication specified */ - HTTP_AUTH_BASIC, /**< HTTP 1.0 Basic auth from RFC 1945 - * (also in RFC 2617) */ - HTTP_AUTH_DIGEST, /**< HTTP 1.1 Digest auth from RFC 2617 */ -} HTTPAuthType; - -typedef struct { - char nonce[300]; /**< Server specified nonce */ - char algorithm[10]; /**< Server specified digest algorithm */ - char qop[30]; /**< Quality of protection, containing the one - * that we've chosen to use, from the - * alternatives that the server offered. */ - char opaque[300]; /**< A server-specified string that should be - * included in authentication responses, not - * included in the actual digest calculation. */ - int nc; /**< Nonce count, the number of earlier replies - * where this particular nonce has been used. */ -} DigestParams; - -/** - * HTTP Authentication state structure. Must be zero-initialized - * before used with the functions below. - */ -typedef struct { - /** - * The currently chosen auth type. - */ - HTTPAuthType auth_type; - /** - * Authentication realm - */ - char realm[200]; - /** - * The parameters specifiec to digest authentication. - */ - DigestParams digest_params; -} HTTPAuthState; - -void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, - const char *value); -char *ff_http_auth_create_response(HTTPAuthState *state, const char *auth, - const char *path, const char *method); - -#endif /* AVFORMAT_HTTPAUTH_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/id3v1.c b/tizen/distrib/ffmpeg/libavformat/id3v1.c deleted file mode 100644 index c72fca4..0000000 --- a/tizen/distrib/ffmpeg/libavformat/id3v1.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * ID3v1 header parser - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "id3v1.h" -#include "libavcodec/avcodec.h" -#include "libavutil/avstring.h" - -const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1] = { - [0] = "Blues", - [1] = "Classic Rock", - [2] = "Country", - [3] = "Dance", - [4] = "Disco", - [5] = "Funk", - [6] = "Grunge", - [7] = "Hip-Hop", - [8] = "Jazz", - [9] = "Metal", - [10] = "New Age", - [11] = "Oldies", - [12] = "Other", - [13] = "Pop", - [14] = "R&B", - [15] = "Rap", - [16] = "Reggae", - [17] = "Rock", - [18] = "Techno", - [19] = "Industrial", - [20] = "Alternative", - [21] = "Ska", - [22] = "Death Metal", - [23] = "Pranks", - [24] = "Soundtrack", - [25] = "Euro-Techno", - [26] = "Ambient", - [27] = "Trip-Hop", - [28] = "Vocal", - [29] = "Jazz+Funk", - [30] = "Fusion", - [31] = "Trance", - [32] = "Classical", - [33] = "Instrumental", - [34] = "Acid", - [35] = "House", - [36] = "Game", - [37] = "Sound Clip", - [38] = "Gospel", - [39] = "Noise", - [40] = "AlternRock", - [41] = "Bass", - [42] = "Soul", - [43] = "Punk", - [44] = "Space", - [45] = "Meditative", - [46] = "Instrumental Pop", - [47] = "Instrumental Rock", - [48] = "Ethnic", - [49] = "Gothic", - [50] = "Darkwave", - [51] = "Techno-Industrial", - [52] = "Electronic", - [53] = "Pop-Folk", - [54] = "Eurodance", - [55] = "Dream", - [56] = "Southern Rock", - [57] = "Comedy", - [58] = "Cult", - [59] = "Gangsta", - [60] = "Top 40", - [61] = "Christian Rap", - [62] = "Pop/Funk", - [63] = "Jungle", - [64] = "Native American", - [65] = "Cabaret", - [66] = "New Wave", - [67] = "Psychadelic", - [68] = "Rave", - [69] = "Showtunes", - [70] = "Trailer", - [71] = "Lo-Fi", - [72] = "Tribal", - [73] = "Acid Punk", - [74] = "Acid Jazz", - [75] = "Polka", - [76] = "Retro", - [77] = "Musical", - [78] = "Rock & Roll", - [79] = "Hard Rock", - [80] = "Folk", - [81] = "Folk-Rock", - [82] = "National Folk", - [83] = "Swing", - [84] = "Fast Fusion", - [85] = "Bebob", - [86] = "Latin", - [87] = "Revival", - [88] = "Celtic", - [89] = "Bluegrass", - [90] = "Avantgarde", - [91] = "Gothic Rock", - [92] = "Progressive Rock", - [93] = "Psychedelic Rock", - [94] = "Symphonic Rock", - [95] = "Slow Rock", - [96] = "Big Band", - [97] = "Chorus", - [98] = "Easy Listening", - [99] = "Acoustic", - [100] = "Humour", - [101] = "Speech", - [102] = "Chanson", - [103] = "Opera", - [104] = "Chamber Music", - [105] = "Sonata", - [106] = "Symphony", - [107] = "Booty Bass", - [108] = "Primus", - [109] = "Porn Groove", - [110] = "Satire", - [111] = "Slow Jam", - [112] = "Club", - [113] = "Tango", - [114] = "Samba", - [115] = "Folklore", - [116] = "Ballad", - [117] = "Power Ballad", - [118] = "Rhythmic Soul", - [119] = "Freestyle", - [120] = "Duet", - [121] = "Punk Rock", - [122] = "Drum Solo", - [123] = "A capella", - [124] = "Euro-House", - [125] = "Dance Hall", - [126] = "Goa", - [127] = "Drum & Bass", - [128] = "Club-House", - [129] = "Hardcore", - [130] = "Terror", - [131] = "Indie", - [132] = "BritPop", - [133] = "Negerpunk", - [134] = "Polsk Punk", - [135] = "Beat", - [136] = "Christian Gangsta", - [137] = "Heavy Metal", - [138] = "Black Metal", - [139] = "Crossover", - [140] = "Contemporary Christian", - [141] = "Christian Rock", - [142] = "Merengue", - [143] = "Salsa", - [144] = "Thrash Metal", - [145] = "Anime", - [146] = "JPop", - [147] = "SynthPop", -}; - -static void get_string(AVFormatContext *s, const char *key, - const uint8_t *buf, int buf_size) -{ - int i, c; - char *q, str[512]; - - q = str; - for(i = 0; i < buf_size; i++) { - c = buf[i]; - if (c == '\0') - break; - if ((q - str) >= sizeof(str) - 1) - break; - *q++ = c; - } - *q = '\0'; - - if (*str) - av_metadata_set2(&s->metadata, key, str, 0); -} - -/** - * Parse an ID3v1 tag - * - * @param buf ID3v1_TAG_SIZE long buffer containing the tag - */ -static int parse_tag(AVFormatContext *s, const uint8_t *buf) -{ - int genre; - - if (!(buf[0] == 'T' && - buf[1] == 'A' && - buf[2] == 'G')) - return -1; - get_string(s, "title", buf + 3, 30); - get_string(s, "artist", buf + 33, 30); - get_string(s, "album", buf + 63, 30); - get_string(s, "date", buf + 93, 4); - get_string(s, "comment", buf + 97, 30); - if (buf[125] == 0 && buf[126] != 0) - av_metadata_set2(&s->metadata, "track", av_d2str(buf[126]), AV_METADATA_DONT_STRDUP_VAL); - genre = buf[127]; - if (genre <= ID3v1_GENRE_MAX) - av_metadata_set2(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0); - return 0; -} - -void ff_id3v1_read(AVFormatContext *s) -{ - int ret, filesize; - uint8_t buf[ID3v1_TAG_SIZE]; - - if (!url_is_streamed(s->pb)) { - /* XXX: change that */ - filesize = url_fsize(s->pb); - if (filesize > 128) { - url_fseek(s->pb, filesize - 128, SEEK_SET); - ret = get_buffer(s->pb, buf, ID3v1_TAG_SIZE); - if (ret == ID3v1_TAG_SIZE) { - parse_tag(s, buf); - } - url_fseek(s->pb, 0, SEEK_SET); - } - } -} diff --git a/tizen/distrib/ffmpeg/libavformat/id3v1.h b/tizen/distrib/ffmpeg/libavformat/id3v1.h deleted file mode 100644 index 8eb58be..0000000 --- a/tizen/distrib/ffmpeg/libavformat/id3v1.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * ID3v1 header parser - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_ID3V1_H -#define AVFORMAT_ID3V1_H - -#include "avformat.h" - -#define ID3v1_TAG_SIZE 128 - -#define ID3v1_GENRE_MAX 147 - -/** - * ID3v1 genres - */ -extern const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1]; - -/** - * Read an ID3v1 tag - */ -void ff_id3v1_read(AVFormatContext *s); - -#endif /* AVFORMAT_ID3V1_H */ - diff --git a/tizen/distrib/ffmpeg/libavformat/id3v2.c b/tizen/distrib/ffmpeg/libavformat/id3v2.c deleted file mode 100644 index 6fa11db..0000000 --- a/tizen/distrib/ffmpeg/libavformat/id3v2.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * ID3v2 header parser - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "id3v2.h" -#include "id3v1.h" -#include "libavutil/avstring.h" - -int ff_id3v2_match(const uint8_t *buf) -{ - return buf[0] == 'I' && - buf[1] == 'D' && - buf[2] == '3' && - buf[3] != 0xff && - buf[4] != 0xff && - (buf[6] & 0x80) == 0 && - (buf[7] & 0x80) == 0 && - (buf[8] & 0x80) == 0 && - (buf[9] & 0x80) == 0; -} - -int ff_id3v2_tag_len(const uint8_t * buf) -{ - int len = ((buf[6] & 0x7f) << 21) + - ((buf[7] & 0x7f) << 14) + - ((buf[8] & 0x7f) << 7) + - (buf[9] & 0x7f) + - ID3v2_HEADER_SIZE; - if (buf[5] & 0x10) - len += ID3v2_HEADER_SIZE; - return len; -} - -void ff_id3v2_read(AVFormatContext *s) -{ - int len, ret; - uint8_t buf[ID3v2_HEADER_SIZE]; - - ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); - if (ret != ID3v2_HEADER_SIZE) - return; - if (ff_id3v2_match(buf)) { - /* parse ID3v2 header */ - len = ((buf[6] & 0x7f) << 21) | - ((buf[7] & 0x7f) << 14) | - ((buf[8] & 0x7f) << 7) | - (buf[9] & 0x7f); - ff_id3v2_parse(s, len, buf[3], buf[5]); - } else { - url_fseek(s->pb, 0, SEEK_SET); - } -} - -static unsigned int get_size(ByteIOContext *s, int len) -{ - int v = 0; - while (len--) - v = (v << 7) + (get_byte(s) & 0x7F); - return v; -} - -static void read_ttag(AVFormatContext *s, int taglen, const char *key) -{ - char *q, dst[512]; - const char *val = NULL; - int len, dstlen = sizeof(dst) - 1; - unsigned genre; - unsigned int (*get)(ByteIOContext*) = get_be16; - - dst[0] = 0; - if (taglen < 1) - return; - - taglen--; /* account for encoding type byte */ - - switch (get_byte(s->pb)) { /* encoding type */ - - case 0: /* ISO-8859-1 (0 - 255 maps directly into unicode) */ - q = dst; - while (taglen-- && q - dst < dstlen - 7) { - uint8_t tmp; - PUT_UTF8(get_byte(s->pb), tmp, *q++ = tmp;) - } - *q = 0; - break; - - case 1: /* UTF-16 with BOM */ - taglen -= 2; - switch (get_be16(s->pb)) { - case 0xfffe: - get = get_le16; - case 0xfeff: - break; - default: - av_log(s, AV_LOG_ERROR, "Incorrect BOM value in tag %s.\n", key); - return; - } - // fall-through - - case 2: /* UTF-16BE without BOM */ - q = dst; - while (taglen > 1 && q - dst < dstlen - 7) { - uint32_t ch; - uint8_t tmp; - - GET_UTF16(ch, ((taglen -= 2) >= 0 ? get(s->pb) : 0), break;) - PUT_UTF8(ch, tmp, *q++ = tmp;) - } - *q = 0; - break; - - case 3: /* UTF-8 */ - len = FFMIN(taglen, dstlen); - get_buffer(s->pb, dst, len); - dst[len] = 0; - break; - default: - av_log(s, AV_LOG_WARNING, "Unknown encoding in tag %s\n.", key); - } - - if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) - && (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) - && genre <= ID3v1_GENRE_MAX) - val = ff_id3v1_genre_str[genre]; - else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { - /* dst now contains two 0-terminated strings */ - dst[dstlen] = 0; - len = strlen(dst); - key = dst; - val = dst + FFMIN(len + 1, dstlen); - } - else if (*dst) - val = dst; - - if (val) - av_metadata_set2(&s->metadata, key, val, 0); -} - -void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags) -{ - int isv34, tlen; - char tag[5]; - int64_t next; - int taghdrlen; - const char *reason; - - switch (version) { - case 2: - if (flags & 0x40) { - reason = "compression"; - goto error; - } - isv34 = 0; - taghdrlen = 6; - break; - - case 3: - case 4: - isv34 = 1; - taghdrlen = 10; - break; - - default: - reason = "version"; - goto error; - } - - if (flags & 0x80) { - reason = "unsynchronization"; - goto error; - } - - if (isv34 && flags & 0x40) /* Extended header present, just skip over it */ - url_fskip(s->pb, get_size(s->pb, 4)); - - while (len >= taghdrlen) { - if (isv34) { - get_buffer(s->pb, tag, 4); - tag[4] = 0; - if(version==3){ - tlen = get_be32(s->pb); - }else - tlen = get_size(s->pb, 4); - get_be16(s->pb); /* flags */ - } else { - get_buffer(s->pb, tag, 3); - tag[3] = 0; - tlen = get_be24(s->pb); - } - len -= taghdrlen + tlen; - - if (len < 0) - break; - - next = url_ftell(s->pb) + tlen; - - if (tag[0] == 'T') - read_ttag(s, tlen, tag); - else if (!tag[0]) { - if (tag[1]) - av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding"); - url_fskip(s->pb, len); - break; - } - /* Skip to end of tag */ - url_fseek(s->pb, next, SEEK_SET); - } - - if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */ - url_fskip(s->pb, 10); - return; - - error: - av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason); - url_fskip(s->pb, len); -} - -const AVMetadataConv ff_id3v2_metadata_conv[] = { - { "TALB", "album"}, - { "TAL", "album"}, - { "TCOM", "composer"}, - { "TCON", "genre"}, - { "TCO", "genre"}, - { "TCOP", "copyright"}, - { "TDRL", "date"}, - { "TDRC", "date"}, - { "TENC", "encoded_by"}, - { "TEN", "encoded_by"}, - { "TIT2", "title"}, - { "TT2", "title"}, - { "TLAN", "language"}, - { "TPE1", "artist"}, - { "TP1", "artist"}, - { "TPE2", "album_artist"}, - { "TP2", "album_artist"}, - { "TPE3", "performer"}, - { "TP3", "performer"}, - { "TPOS", "disc"}, - { "TPUB", "publisher"}, - { "TRCK", "track"}, - { "TRK", "track"}, - { "TSOA", "album-sort"}, - { "TSOP", "artist-sort"}, - { "TSOT", "title-sort"}, - { "TSSE", "encoder"}, - { 0 } -}; - -const char ff_id3v2_tags[][4] = { - "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDEN", "TDLY", "TDOR", "TDRC", - "TDRL", "TDTG", "TENC", "TEXT", "TFLT", "TIPL", "TIT1", "TIT2", "TIT3", - "TKEY", "TLAN", "TLEN", "TMCL", "TMED", "TMOO", "TOAL", "TOFN", "TOLY", - "TOPE", "TOWN", "TPE1", "TPE2", "TPE3", "TPE4", "TPOS", "TPRO", "TPUB", - "TRCK", "TRSN", "TRSO", "TSOA", "TSOP", "TSOT", "TSRC", "TSSE", "TSST", - { 0 }, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/id3v2.h b/tizen/distrib/ffmpeg/libavformat/id3v2.h deleted file mode 100644 index 70030d2..0000000 --- a/tizen/distrib/ffmpeg/libavformat/id3v2.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * ID3v2 header parser - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_ID3V2_H -#define AVFORMAT_ID3V2_H - -#include -#include "avformat.h" -#include "metadata.h" - -#define ID3v2_HEADER_SIZE 10 - -/** - * Detects ID3v2 Header. - * @buf must be ID3v2_HEADER_SIZE byte long - */ -int ff_id3v2_match(const uint8_t *buf); - -/** - * Gets the length of an ID3v2 tag. - * @buf must be ID3v2_HEADER_SIZE bytes long and point to the start of an - * already detected ID3v2 tag - */ -int ff_id3v2_tag_len(const uint8_t *buf); - -/** - * ID3v2 parser - * Handles ID3v2.2, 2.3 and 2.4. - */ -void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags); - -/** - * Read an ID3v2 tag - */ -void ff_id3v2_read(AVFormatContext *s); - -extern const AVMetadataConv ff_id3v2_metadata_conv[]; - -/** - * A list of ID3v2.4 text information frames. - * http://www.id3.org/id3v2.4.0-frames - */ -extern const char ff_id3v2_tags[][4]; - -#endif /* AVFORMAT_ID3V2_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/idcin.c b/tizen/distrib/ffmpeg/libavformat/idcin.c deleted file mode 100644 index cd4ebf8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/idcin.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * id Quake II CIN File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * id Quake II CIN file demuxer by Mike Melanson (melanson@pcisys.net) - * For more information about the id CIN format, visit: - * http://www.csse.monash.edu.au/~timf/ - * - * CIN is a somewhat quirky and ill-defined format. Here are some notes - * for anyone trying to understand the technical details of this format: - * - * The format has no definite file signature. This is problematic for a - * general-purpose media player that wants to automatically detect file - * types. However, a CIN file does start with 5 32-bit numbers that - * specify audio and video parameters. This demuxer gets around the lack - * of file signature by performing sanity checks on those parameters. - * Probabalistically, this is a reasonable solution since the number of - * valid combinations of the 5 parameters is a very small subset of the - * total 160-bit number space. - * - * Refer to the function idcin_probe() for the precise A/V parameters - * that this demuxer allows. - * - * Next, each audio and video frame has a duration of 1/14 sec. If the - * audio sample rate is a multiple of the common frequency 22050 Hz it will - * divide evenly by 14. However, if the sample rate is 11025 Hz: - * 11025 (samples/sec) / 14 (frames/sec) = 787.5 (samples/frame) - * The way the CIN stores audio in this case is by storing 787 sample - * frames in the first audio frame and 788 sample frames in the second - * audio frame. Therefore, the total number of bytes in an audio frame - * is given as: - * audio frame #0: 787 * (bytes/sample) * (# channels) bytes in frame - * audio frame #1: 788 * (bytes/sample) * (# channels) bytes in frame - * audio frame #2: 787 * (bytes/sample) * (# channels) bytes in frame - * audio frame #3: 788 * (bytes/sample) * (# channels) bytes in frame - * - * Finally, not all id CIN creation tools agree on the resolution of the - * color palette, apparently. Some creation tools specify red, green, and - * blue palette components in terms of 6-bit VGA color DAC values which - * range from 0..63. Other tools specify the RGB components as full 8-bit - * values that range from 0..255. Since there are no markers in the file to - * differentiate between the two variants, this demuxer uses the following - * heuristic: - * - load the 768 palette bytes from disk - * - assume that they will need to be shifted left by 2 bits to - * transform them from 6-bit values to 8-bit values - * - scan through all 768 palette bytes - * - if any bytes exceed 63, do not shift the bytes at all before - * transmitting them to the video decoder - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define HUFFMAN_TABLE_SIZE (64 * 1024) -#define IDCIN_FPS 14 - -typedef struct IdcinDemuxContext { - int video_stream_index; - int audio_stream_index; - int audio_chunk_size1; - int audio_chunk_size2; - - /* demux state variables */ - int current_audio_chunk; - int next_chunk_is_video; - int audio_present; - - int64_t pts; - - AVPaletteControl palctrl; -} IdcinDemuxContext; - -static int idcin_probe(AVProbeData *p) -{ - unsigned int number; - - /* - * This is what you could call a "probabilistic" file check: id CIN - * files don't have a definite file signature. In lieu of such a marker, - * perform sanity checks on the 5 32-bit header fields: - * width, height: greater than 0, less than or equal to 1024 - * audio sample rate: greater than or equal to 8000, less than or - * equal to 48000, or 0 for no audio - * audio sample width (bytes/sample): 0 for no audio, or 1 or 2 - * audio channels: 0 for no audio, or 1 or 2 - */ - - /* check we have enough data to do all checks, otherwise the - 0-padding may cause a wrong recognition */ - if (p->buf_size < 20) - return 0; - - /* check the video width */ - number = AV_RL32(&p->buf[0]); - if ((number == 0) || (number > 1024)) - return 0; - - /* check the video height */ - number = AV_RL32(&p->buf[4]); - if ((number == 0) || (number > 1024)) - return 0; - - /* check the audio sample rate */ - number = AV_RL32(&p->buf[8]); - if ((number != 0) && ((number < 8000) | (number > 48000))) - return 0; - - /* check the audio bytes/sample */ - number = AV_RL32(&p->buf[12]); - if (number > 2) - return 0; - - /* check the audio channels */ - number = AV_RL32(&p->buf[16]); - if (number > 2) - return 0; - - /* return half certainly since this check is a bit sketchy */ - return AVPROBE_SCORE_MAX / 2; -} - -static int idcin_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - IdcinDemuxContext *idcin = s->priv_data; - AVStream *st; - unsigned int width, height; - unsigned int sample_rate, bytes_per_sample, channels; - - /* get the 5 header parameters */ - width = get_le32(pb); - height = get_le32(pb); - sample_rate = get_le32(pb); - bytes_per_sample = get_le32(pb); - channels = get_le32(pb); - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, IDCIN_FPS); - idcin->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_IDCIN; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = width; - st->codec->height = height; - - /* load up the Huffman tables into extradata */ - st->codec->extradata_size = HUFFMAN_TABLE_SIZE; - st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE); - if (get_buffer(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != - HUFFMAN_TABLE_SIZE) - return AVERROR(EIO); - /* save a reference in order to transport the palette */ - st->codec->palctrl = &idcin->palctrl; - - /* if sample rate is 0, assume no audio */ - if (sample_rate) { - idcin->audio_present = 1; - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, IDCIN_FPS); - idcin->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 1; - st->codec->channels = channels; - st->codec->sample_rate = sample_rate; - st->codec->bits_per_coded_sample = bytes_per_sample * 8; - st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels; - st->codec->block_align = bytes_per_sample * channels; - if (bytes_per_sample == 1) - st->codec->codec_id = CODEC_ID_PCM_U8; - else - st->codec->codec_id = CODEC_ID_PCM_S16LE; - - if (sample_rate % 14 != 0) { - idcin->audio_chunk_size1 = (sample_rate / 14) * - bytes_per_sample * channels; - idcin->audio_chunk_size2 = (sample_rate / 14 + 1) * - bytes_per_sample * channels; - } else { - idcin->audio_chunk_size1 = idcin->audio_chunk_size2 = - (sample_rate / 14) * bytes_per_sample * channels; - } - idcin->current_audio_chunk = 0; - } else - idcin->audio_present = 1; - - idcin->next_chunk_is_video = 1; - idcin->pts = 0; - - return 0; -} - -static int idcin_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret; - unsigned int command; - unsigned int chunk_size; - IdcinDemuxContext *idcin = s->priv_data; - ByteIOContext *pb = s->pb; - int i; - int palette_scale; - unsigned char r, g, b; - unsigned char palette_buffer[768]; - - if (url_feof(s->pb)) - return AVERROR(EIO); - - if (idcin->next_chunk_is_video) { - command = get_le32(pb); - if (command == 2) { - return AVERROR(EIO); - } else if (command == 1) { - /* trigger a palette change */ - idcin->palctrl.palette_changed = 1; - if (get_buffer(pb, palette_buffer, 768) != 768) - return AVERROR(EIO); - /* scale the palette as necessary */ - palette_scale = 2; - for (i = 0; i < 768; i++) - if (palette_buffer[i] > 63) { - palette_scale = 0; - break; - } - - for (i = 0; i < 256; i++) { - r = palette_buffer[i * 3 ] << palette_scale; - g = palette_buffer[i * 3 + 1] << palette_scale; - b = palette_buffer[i * 3 + 2] << palette_scale; - idcin->palctrl.palette[i] = (r << 16) | (g << 8) | (b); - } - } - - chunk_size = get_le32(pb); - /* skip the number of decoded bytes (always equal to width * height) */ - url_fseek(pb, 4, SEEK_CUR); - chunk_size -= 4; - ret= av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; - pkt->stream_index = idcin->video_stream_index; - pkt->pts = idcin->pts; - } else { - /* send out the audio chunk */ - if (idcin->current_audio_chunk) - chunk_size = idcin->audio_chunk_size2; - else - chunk_size = idcin->audio_chunk_size1; - ret= av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; - pkt->stream_index = idcin->audio_stream_index; - pkt->pts = idcin->pts; - - idcin->current_audio_chunk ^= 1; - idcin->pts++; - } - - if (idcin->audio_present) - idcin->next_chunk_is_video ^= 1; - - return ret; -} - -AVInputFormat idcin_demuxer = { - "idcin", - NULL_IF_CONFIG_SMALL("id Cinematic format"), - sizeof(IdcinDemuxContext), - idcin_probe, - idcin_read_header, - idcin_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/idroq.c b/tizen/distrib/ffmpeg/libavformat/idroq.c deleted file mode 100644 index 6b036d9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/idroq.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * id RoQ (.roq) File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * id RoQ format file demuxer - * by Mike Melanson (melanson@pcisys.net) - * for more information on the .roq file format, visit: - * http://www.csse.monash.edu.au/~timf/ - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define RoQ_MAGIC_NUMBER 0x1084 -#define RoQ_CHUNK_PREAMBLE_SIZE 8 -#define RoQ_AUDIO_SAMPLE_RATE 22050 -#define RoQ_CHUNKS_TO_SCAN 30 - -#define RoQ_INFO 0x1001 -#define RoQ_QUAD_CODEBOOK 0x1002 -#define RoQ_QUAD_VQ 0x1011 -#define RoQ_SOUND_MONO 0x1020 -#define RoQ_SOUND_STEREO 0x1021 - -typedef struct RoqDemuxContext { - - int width; - int height; - int audio_channels; - - int video_stream_index; - int audio_stream_index; - - int64_t video_pts; - unsigned int audio_frame_count; - -} RoqDemuxContext; - -static int roq_probe(AVProbeData *p) -{ - if ((AV_RL16(&p->buf[0]) != RoQ_MAGIC_NUMBER) || - (AV_RL32(&p->buf[2]) != 0xFFFFFFFF)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int roq_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - RoqDemuxContext *roq = s->priv_data; - ByteIOContext *pb = s->pb; - int framerate; - AVStream *st; - unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; - - /* get the main header */ - if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - framerate = AV_RL16(&preamble[6]); - - /* init private context parameters */ - roq->width = roq->height = roq->audio_channels = roq->video_pts = - roq->audio_frame_count = 0; - roq->audio_stream_index = -1; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 63, 1, framerate); - roq->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_ROQ; - st->codec->codec_tag = 0; /* no fourcc */ - - return 0; -} - -static int roq_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - RoqDemuxContext *roq = s->priv_data; - ByteIOContext *pb = s->pb; - int ret = 0; - unsigned int chunk_size; - unsigned int chunk_type; - unsigned int codebook_size; - unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; - int packet_read = 0; - int64_t codebook_offset; - - while (!packet_read) { - - if (url_feof(s->pb)) - return AVERROR(EIO); - - /* get the next chunk preamble */ - if ((ret = get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE)) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - - chunk_type = AV_RL16(&preamble[0]); - chunk_size = AV_RL32(&preamble[2]); - if(chunk_size > INT_MAX) - return AVERROR_INVALIDDATA; - - switch (chunk_type) { - - case RoQ_INFO: - if (!roq->width || !roq->height) { - AVStream *st = s->streams[roq->video_stream_index]; - if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - st->codec->width = roq->width = AV_RL16(preamble); - st->codec->height = roq->height = AV_RL16(preamble + 2); - break; - } - /* don't care about this chunk anymore */ - url_fseek(pb, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_CUR); - break; - - case RoQ_QUAD_CODEBOOK: - /* packet needs to contain both this codebook and next VQ chunk */ - codebook_offset = url_ftell(pb) - RoQ_CHUNK_PREAMBLE_SIZE; - codebook_size = chunk_size; - url_fseek(pb, codebook_size, SEEK_CUR); - if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - chunk_size = AV_RL32(&preamble[2]) + RoQ_CHUNK_PREAMBLE_SIZE * 2 + - codebook_size; - - /* rewind */ - url_fseek(pb, codebook_offset, SEEK_SET); - - /* load up the packet */ - ret= av_get_packet(pb, pkt, chunk_size); - if (ret != chunk_size) - return AVERROR(EIO); - pkt->stream_index = roq->video_stream_index; - pkt->pts = roq->video_pts++; - - packet_read = 1; - break; - - case RoQ_SOUND_MONO: - case RoQ_SOUND_STEREO: - if (roq->audio_stream_index == -1) { - AVStream *st = av_new_stream(s, 1); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE); - roq->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ROQ_DPCM; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = roq->audio_channels = chunk_type == RoQ_SOUND_STEREO ? 2 : 1; - st->codec->sample_rate = RoQ_AUDIO_SAMPLE_RATE; - st->codec->bits_per_coded_sample = 16; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - } - case RoQ_QUAD_VQ: - /* load up the packet */ - if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE)) - return AVERROR(EIO); - /* copy over preamble */ - memcpy(pkt->data, preamble, RoQ_CHUNK_PREAMBLE_SIZE); - - if (chunk_type == RoQ_QUAD_VQ) { - pkt->stream_index = roq->video_stream_index; - pkt->pts = roq->video_pts++; - } else { - pkt->stream_index = roq->audio_stream_index; - pkt->pts = roq->audio_frame_count; - roq->audio_frame_count += (chunk_size / roq->audio_channels); - } - - pkt->pos= url_ftell(pb); - ret = get_buffer(pb, pkt->data + RoQ_CHUNK_PREAMBLE_SIZE, - chunk_size); - if (ret != chunk_size) - ret = AVERROR(EIO); - - packet_read = 1; - break; - - default: - av_log(s, AV_LOG_ERROR, " unknown RoQ chunk (%04X)\n", chunk_type); - return AVERROR_INVALIDDATA; - break; - } - } - - return ret; -} - -AVInputFormat roq_demuxer = { - "RoQ", - NULL_IF_CONFIG_SMALL("id RoQ format"), - sizeof(RoqDemuxContext), - roq_probe, - roq_read_header, - roq_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/iff.c b/tizen/distrib/ffmpeg/libavformat/iff.c deleted file mode 100644 index db74b8d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/iff.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * IFF (.iff) file demuxer - * Copyright (c) 2008 Jaikrishnan Menon - * Copyright (c) 2010 Peter Ross - * Copyright (c) 2010 Sebastian Vater - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * IFF file demuxer - * by Jaikrishnan Menon - * for more information on the .iff file format, visit: - * http://wiki.multimedia.cx/index.php?title=IFF - */ - -#include "libavutil/intreadwrite.h" -#include "libavcodec/iff.h" -#include "avformat.h" - -#define ID_8SVX MKTAG('8','S','V','X') -#define ID_VHDR MKTAG('V','H','D','R') -#define ID_ATAK MKTAG('A','T','A','K') -#define ID_RLSE MKTAG('R','L','S','E') -#define ID_CHAN MKTAG('C','H','A','N') -#define ID_PBM MKTAG('P','B','M',' ') -#define ID_ILBM MKTAG('I','L','B','M') -#define ID_BMHD MKTAG('B','M','H','D') -#define ID_CMAP MKTAG('C','M','A','P') - -#define ID_FORM MKTAG('F','O','R','M') -#define ID_ANNO MKTAG('A','N','N','O') -#define ID_AUTH MKTAG('A','U','T','H') -#define ID_CHRS MKTAG('C','H','R','S') -#define ID_COPYRIGHT MKTAG('(','c',')',' ') -#define ID_CSET MKTAG('C','S','E','T') -#define ID_FVER MKTAG('F','V','E','R') -#define ID_NAME MKTAG('N','A','M','E') -#define ID_TEXT MKTAG('T','E','X','T') -#define ID_BODY MKTAG('B','O','D','Y') -#define ID_ANNO MKTAG('A','N','N','O') - -#define LEFT 2 -#define RIGHT 4 -#define STEREO 6 - -#define PACKET_SIZE 1024 - -typedef enum { - COMP_NONE, - COMP_FIB, - COMP_EXP -} svx8_compression_type; - -typedef enum { - BITMAP_RAW, - BITMAP_BYTERUN1 -} bitmap_compression_type; - -typedef struct { - uint64_t body_pos; - uint32_t body_size; - uint32_t sent_bytes; - uint32_t audio_frame_count; -} IffDemuxContext; - - -static void interleave_stereo(const uint8_t *src, uint8_t *dest, int size) -{ - uint8_t *end = dest + size; - size = size>>1; - - while(dest < end) { - *dest++ = *src; - *dest++ = *(src+size); - src++; - } -} - -static int iff_probe(AVProbeData *p) -{ - const uint8_t *d = p->buf; - - if ( AV_RL32(d) == ID_FORM && - (AV_RL32(d+8) == ID_8SVX || AV_RL32(d+8) == ID_PBM || AV_RL32(d+8) == ID_ILBM) ) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int iff_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - IffDemuxContext *iff = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - uint32_t chunk_id, data_size; - int compression = -1; - char *buf; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->channels = 1; - url_fskip(pb, 8); - // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content - st->codec->codec_tag = get_le32(pb); - - while(!url_feof(pb)) { - uint64_t orig_pos; - chunk_id = get_le32(pb); - data_size = get_be32(pb); - orig_pos = url_ftell(pb); - - switch(chunk_id) { - case ID_VHDR: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - if (data_size < 14) - return AVERROR_INVALIDDATA; - url_fskip(pb, 12); - st->codec->sample_rate = get_be16(pb); - if (data_size >= 16) { - url_fskip(pb, 1); - compression = get_byte(pb); - } - break; - - case ID_BODY: - iff->body_pos = url_ftell(pb); - iff->body_size = data_size; - break; - - case ID_CHAN: - if (data_size < 4) - return AVERROR_INVALIDDATA; - st->codec->channels = (get_be32(pb) < 6) ? 1 : 2; - break; - - case ID_CMAP: - st->codec->extradata_size = data_size; - st->codec->extradata = av_malloc(data_size); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - if (get_buffer(pb, st->codec->extradata, data_size) < 0) - return AVERROR(EIO); - break; - - case ID_BMHD: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - if (data_size <= 8) - return AVERROR_INVALIDDATA; - st->codec->width = get_be16(pb); - st->codec->height = get_be16(pb); - url_fskip(pb, 4); // x, y offset - st->codec->bits_per_coded_sample = get_byte(pb); - if (data_size >= 11) { - url_fskip(pb, 1); // masking - compression = get_byte(pb); - } - if (data_size >= 16) { - url_fskip(pb, 3); // paddding, transparent - st->sample_aspect_ratio.num = get_byte(pb); - st->sample_aspect_ratio.den = get_byte(pb); - } - break; - - case ID_ANNO: - buf = av_malloc(data_size + 1); - if (!buf) - break; - get_buffer(pb, buf, data_size); - buf[data_size] = 0; - av_metadata_set2(&s->metadata, "comment", buf, AV_METADATA_DONT_STRDUP_VAL); - break; - } - - url_fskip(pb, data_size - (url_ftell(pb) - orig_pos) + (data_size & 1)); - } - - url_fseek(pb, iff->body_pos, SEEK_SET); - - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - av_set_pts_info(st, 32, 1, st->codec->sample_rate); - - switch(compression) { - case COMP_NONE: - st->codec->codec_id = CODEC_ID_PCM_S8; - break; - case COMP_FIB: - st->codec->codec_id = CODEC_ID_8SVX_FIB; - break; - case COMP_EXP: - st->codec->codec_id = CODEC_ID_8SVX_EXP; - break; - default: - av_log(s, AV_LOG_ERROR, "iff: unknown compression method\n"); - return -1; - } - - st->codec->bits_per_coded_sample = 8; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - break; - - case AVMEDIA_TYPE_VIDEO: - switch (compression) { - case BITMAP_RAW: - if (st->codec->codec_tag == ID_ILBM) { - st->codec->codec_id = CODEC_ID_IFF_ILBM; - } else { - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->pix_fmt = PIX_FMT_PAL8; - st->codec->codec_tag = 0; - } - break; - case BITMAP_BYTERUN1: - st->codec->codec_id = CODEC_ID_IFF_BYTERUN1; - break; - default: - av_log(s, AV_LOG_ERROR, "unknown compression method\n"); - return AVERROR_INVALIDDATA; - } - break; - default: - return -1; - } - - return 0; -} - -static int iff_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - IffDemuxContext *iff = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - int ret; - - if(iff->sent_bytes >= iff->body_size) - return AVERROR(EIO); - - if(s->streams[0]->codec->channels == 2) { - uint8_t sample_buffer[PACKET_SIZE]; - - ret = get_buffer(pb, sample_buffer, PACKET_SIZE); - if(av_new_packet(pkt, PACKET_SIZE) < 0) { - av_log(s, AV_LOG_ERROR, "iff: cannot allocate packet \n"); - return AVERROR(ENOMEM); - } - interleave_stereo(sample_buffer, pkt->data, PACKET_SIZE); - } else if (s->streams[0]->codec->codec_id == CODEC_ID_RAWVIDEO) { - if(av_new_packet(pkt, iff->body_size + AVPALETTE_SIZE) < 0) { - return AVERROR(ENOMEM); - } - - ret = ff_cmap_read_palette(st->codec, (uint32_t*)(pkt->data + iff->body_size)); - if (ret < 0) - return ret; - av_freep(&st->codec->extradata); - st->codec->extradata_size = 0; - - ret = get_buffer(pb, pkt->data, iff->body_size); - } else if (s->streams[0]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = av_get_packet(pb, pkt, iff->body_size); - } else { - ret = av_get_packet(pb, pkt, PACKET_SIZE); - } - - if(iff->sent_bytes == 0) - pkt->flags |= AV_PKT_FLAG_KEY; - - if(s->streams[0]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - iff->sent_bytes += PACKET_SIZE; - } else { - iff->sent_bytes = iff->body_size; - } - pkt->stream_index = 0; - if(s->streams[0]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - pkt->pts = iff->audio_frame_count; - iff->audio_frame_count += ret / s->streams[0]->codec->channels; - } - return ret; -} - -AVInputFormat iff_demuxer = { - "IFF", - NULL_IF_CONFIG_SMALL("IFF format"), - sizeof(IffDemuxContext), - iff_probe, - iff_read_header, - iff_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/img2.c b/tizen/distrib/ffmpeg/libavformat/img2.c deleted file mode 100644 index 85bee97..0000000 --- a/tizen/distrib/ffmpeg/libavformat/img2.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Image format - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/avstring.h" -#include "avformat.h" -#include - -typedef struct { - int img_first; - int img_last; - int img_number; - int img_count; - int is_pipe; - char path[1024]; -} VideoData; - -typedef struct { - enum CodecID id; - const char *str; -} IdStrMap; - -static const IdStrMap img_tags[] = { - { CODEC_ID_MJPEG , "jpeg"}, - { CODEC_ID_MJPEG , "jpg"}, - { CODEC_ID_LJPEG , "ljpg"}, - { CODEC_ID_PNG , "png"}, - { CODEC_ID_PNG , "mng"}, - { CODEC_ID_PPM , "ppm"}, - { CODEC_ID_PPM , "pnm"}, - { CODEC_ID_PGM , "pgm"}, - { CODEC_ID_PGMYUV , "pgmyuv"}, - { CODEC_ID_PBM , "pbm"}, - { CODEC_ID_PAM , "pam"}, - { CODEC_ID_MPEG1VIDEO, "mpg1-img"}, - { CODEC_ID_MPEG2VIDEO, "mpg2-img"}, - { CODEC_ID_MPEG4 , "mpg4-img"}, - { CODEC_ID_FFV1 , "ffv1-img"}, - { CODEC_ID_RAWVIDEO , "y"}, - { CODEC_ID_BMP , "bmp"}, - { CODEC_ID_GIF , "gif"}, - { CODEC_ID_TARGA , "tga"}, - { CODEC_ID_TIFF , "tiff"}, - { CODEC_ID_TIFF , "tif"}, - { CODEC_ID_SGI , "sgi"}, - { CODEC_ID_PTX , "ptx"}, - { CODEC_ID_PCX , "pcx"}, - { CODEC_ID_SUNRAST , "sun"}, - { CODEC_ID_SUNRAST , "ras"}, - { CODEC_ID_SUNRAST , "rs"}, - { CODEC_ID_SUNRAST , "im1"}, - { CODEC_ID_SUNRAST , "im8"}, - { CODEC_ID_SUNRAST , "im24"}, - { CODEC_ID_SUNRAST , "sunras"}, - { CODEC_ID_JPEG2000 , "jp2"}, - { CODEC_ID_DPX , "dpx"}, - { CODEC_ID_NONE , NULL} -}; - -static const int sizes[][2] = { - { 640, 480 }, - { 720, 480 }, - { 720, 576 }, - { 352, 288 }, - { 352, 240 }, - { 160, 128 }, - { 512, 384 }, - { 640, 352 }, - { 640, 240 }, -}; - -static int infer_size(int *width_ptr, int *height_ptr, int size) -{ - int i; - - for(i=0;iid) { - if (!strcasecmp(str, tags->str)) - return tags->id; - - tags++; - } - return CODEC_ID_NONE; -} - -/* return -1 if no image found */ -static int find_image_range(int *pfirst_index, int *plast_index, - const char *path) -{ - char buf[1024]; - int range, last_index, range1, first_index; - - /* find the first image */ - for(first_index = 0; first_index < 5; first_index++) { - if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){ - *pfirst_index = - *plast_index = 1; - if(url_exist(buf)) - return 0; - return -1; - } - if (url_exist(buf)) - break; - } - if (first_index == 5) - goto fail; - - /* find the last image */ - last_index = first_index; - for(;;) { - range = 0; - for(;;) { - if (!range) - range1 = 1; - else - range1 = 2 * range; - if (av_get_frame_filename(buf, sizeof(buf), path, - last_index + range1) < 0) - goto fail; - if (!url_exist(buf)) - break; - range = range1; - /* just in case... */ - if (range >= (1 << 30)) - goto fail; - } - /* we are sure than image last_index + range exists */ - if (!range) - break; - last_index += range; - } - *pfirst_index = first_index; - *plast_index = last_index; - return 0; - fail: - return -1; -} - - -static int image_probe(AVProbeData *p) -{ - if (p->filename && av_str2id(img_tags, p->filename)) { - if (av_filename_number_test(p->filename)) - return AVPROBE_SCORE_MAX; - else - return AVPROBE_SCORE_MAX/2; - } - return 0; -} - -enum CodecID av_guess_image2_codec(const char *filename){ - return av_str2id(img_tags, filename); -} - -static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - VideoData *s = s1->priv_data; - int first_index, last_index; - AVStream *st; - - s1->ctx_flags |= AVFMTCTX_NOHEADER; - - st = av_new_stream(s1, 0); - if (!st) { - return AVERROR(ENOMEM); - } - - av_strlcpy(s->path, s1->filename, sizeof(s->path)); - s->img_number = 0; - s->img_count = 0; - - /* find format */ - if (s1->iformat->flags & AVFMT_NOFILE) - s->is_pipe = 0; - else{ - s->is_pipe = 1; - st->need_parsing = AVSTREAM_PARSE_FULL; - } - - if (!ap->time_base.num) { - av_set_pts_info(st, 60, 1, 25); - } else { - av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den); - } - - if(ap->width && ap->height){ - st->codec->width = ap->width; - st->codec->height= ap->height; - } - - if (!s->is_pipe) { - if (find_image_range(&first_index, &last_index, s->path) < 0) - return AVERROR(ENOENT); - s->img_first = first_index; - s->img_last = last_index; - s->img_number = first_index; - /* compute duration */ - st->start_time = 0; - st->duration = last_index - first_index + 1; - } - - if(s1->video_codec_id){ - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = s1->video_codec_id; - }else if(s1->audio_codec_id){ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s1->audio_codec_id; - }else{ - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = av_str2id(img_tags, s->path); - } - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ap->pix_fmt != PIX_FMT_NONE) - st->codec->pix_fmt = ap->pix_fmt; - - return 0; -} - -static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - VideoData *s = s1->priv_data; - char filename[1024]; - int i; - int size[3]={0}, ret[3]={0}; - ByteIOContext *f[3]; - AVCodecContext *codec= s1->streams[0]->codec; - - if (!s->is_pipe) { - /* loop over input */ - if (s1->loop_input && s->img_number > s->img_last) { - s->img_number = s->img_first; - } - if (s->img_number > s->img_last) - return AVERROR_EOF; - if (av_get_frame_filename(filename, sizeof(filename), - s->path, s->img_number)<0 && s->img_number > 1) - return AVERROR(EIO); - for(i=0; i<3; i++){ - if (url_fopen(&f[i], filename, URL_RDONLY) < 0) { - if(i==1) - break; - av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",filename); - return AVERROR(EIO); - } - size[i]= url_fsize(f[i]); - - if(codec->codec_id != CODEC_ID_RAWVIDEO) - break; - filename[ strlen(filename) - 1 ]= 'U' + i; - } - - if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width) - infer_size(&codec->width, &codec->height, size[0]); - } else { - f[0] = s1->pb; - if (url_feof(f[0])) - return AVERROR(EIO); - size[0]= 4096; - } - - av_new_packet(pkt, size[0] + size[1] + size[2]); - pkt->stream_index = 0; - pkt->flags |= AV_PKT_FLAG_KEY; - - pkt->size= 0; - for(i=0; i<3; i++){ - if(size[i]){ - ret[i]= get_buffer(f[i], pkt->data + pkt->size, size[i]); - if (!s->is_pipe) - url_fclose(f[i]); - if(ret[i]>0) - pkt->size += ret[i]; - } - } - - if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) { - av_free_packet(pkt); - return AVERROR(EIO); /* signal EOF */ - } else { - s->img_count++; - s->img_number++; - return 0; - } -} - -#if CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER -/******************************************************/ -/* image output */ - -static int img_write_header(AVFormatContext *s) -{ - VideoData *img = s->priv_data; - - img->img_number = 1; - av_strlcpy(img->path, s->filename, sizeof(img->path)); - - /* find format */ - if (s->oformat->flags & AVFMT_NOFILE) - img->is_pipe = 0; - else - img->is_pipe = 1; - - return 0; -} - -static int img_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - VideoData *img = s->priv_data; - ByteIOContext *pb[3]; - char filename[1024]; - AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec; - int i; - - if (!img->is_pipe) { - if (av_get_frame_filename(filename, sizeof(filename), - img->path, img->img_number) < 0 && img->img_number>1) { - av_log(s, AV_LOG_ERROR, "Could not get frame filename from pattern\n"); - return AVERROR(EIO); - } - for(i=0; i<3; i++){ - if (url_fopen(&pb[i], filename, URL_WRONLY) < 0) { - av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename); - return AVERROR(EIO); - } - - if(codec->codec_id != CODEC_ID_RAWVIDEO) - break; - filename[ strlen(filename) - 1 ]= 'U' + i; - } - } else { - pb[0] = s->pb; - } - - if(codec->codec_id == CODEC_ID_RAWVIDEO){ - int ysize = codec->width * codec->height; - put_buffer(pb[0], pkt->data , ysize); - put_buffer(pb[1], pkt->data + ysize, (pkt->size - ysize)/2); - put_buffer(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2); - put_flush_packet(pb[1]); - put_flush_packet(pb[2]); - url_fclose(pb[1]); - url_fclose(pb[2]); - }else{ - if(av_str2id(img_tags, s->filename) == CODEC_ID_JPEG2000){ - AVStream *st = s->streams[0]; - if(st->codec->extradata_size > 8 && - AV_RL32(st->codec->extradata+4) == MKTAG('j','p','2','h')){ - if(pkt->size < 8 || AV_RL32(pkt->data+4) != MKTAG('j','p','2','c')) - goto error; - put_be32(pb[0], 12); - put_tag (pb[0], "jP "); - put_be32(pb[0], 0x0D0A870A); // signature - put_be32(pb[0], 20); - put_tag (pb[0], "ftyp"); - put_tag (pb[0], "jp2 "); - put_be32(pb[0], 0); - put_tag (pb[0], "jp2 "); - put_buffer(pb[0], st->codec->extradata, st->codec->extradata_size); - }else if(pkt->size < 8 || - (!st->codec->extradata_size && - AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature - error: - av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream\n"); - return -1; - } - } - put_buffer(pb[0], pkt->data, pkt->size); - } - put_flush_packet(pb[0]); - if (!img->is_pipe) { - url_fclose(pb[0]); - } - - img->img_number++; - return 0; -} - -#endif /* CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER */ - -/* input */ -#if CONFIG_IMAGE2_DEMUXER -AVInputFormat image2_demuxer = { - "image2", - NULL_IF_CONFIG_SMALL("image2 sequence"), - sizeof(VideoData), - image_probe, - img_read_header, - img_read_packet, - NULL, - NULL, - NULL, - AVFMT_NOFILE, -}; -#endif -#if CONFIG_IMAGE2PIPE_DEMUXER -AVInputFormat image2pipe_demuxer = { - "image2pipe", - NULL_IF_CONFIG_SMALL("piped image2 sequence"), - sizeof(VideoData), - NULL, /* no probe */ - img_read_header, - img_read_packet, -}; -#endif - -/* output */ -#if CONFIG_IMAGE2_MUXER -AVOutputFormat image2_muxer = { - "image2", - NULL_IF_CONFIG_SMALL("image2 sequence"), - "", - "bmp,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,ppm,sgi,tif,tiff,jp2", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_MJPEG, - img_write_header, - img_write_packet, - NULL, - .flags= AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS | AVFMT_NOFILE -}; -#endif -#if CONFIG_IMAGE2PIPE_MUXER -AVOutputFormat image2pipe_muxer = { - "image2pipe", - NULL_IF_CONFIG_SMALL("piped image2 sequence"), - "", - "", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_MJPEG, - img_write_header, - img_write_packet, - .flags= AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/internal.h b/tizen/distrib/ffmpeg/libavformat/internal.h deleted file mode 100644 index b586a62..0000000 --- a/tizen/distrib/ffmpeg/libavformat/internal.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_INTERNAL_H -#define AVFORMAT_INTERNAL_H - -#include -#include "avformat.h" - -void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem); - -#ifdef __GNUC__ -#define dynarray_add(tab, nb_ptr, elem)\ -do {\ - __typeof__(tab) _tab = (tab);\ - __typeof__(elem) _elem = (elem);\ - (void)sizeof(**_tab == _elem); /* check that types are compatible */\ - ff_dynarray_add((intptr_t **)_tab, nb_ptr, (intptr_t)_elem);\ -} while(0) -#else -#define dynarray_add(tab, nb_ptr, elem)\ -do {\ - ff_dynarray_add((intptr_t **)(tab), nb_ptr, (intptr_t)(elem));\ -} while(0) -#endif - -time_t _mktimegm(struct tm *tm); -struct tm *brktimegm(time_t secs, struct tm *tm); -const char *small_strptime(const char *p, const char *fmt, - struct tm *dt); - -char *ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase); - -void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx); - -/** - * Add packet to AVFormatContext->packet_buffer list, determining its - * interleaved position using compare() function argument. - */ -void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, - int (*compare)(AVFormatContext *, AVPacket *, AVPacket *)); - -void ff_read_frame_flush(AVFormatContext *s); - -#define NTP_OFFSET 2208988800ULL -#define NTP_OFFSET_US (NTP_OFFSET * 1000000ULL) - -/** Gets the current time since NTP epoch in microseconds. */ -uint64_t ff_ntp_time(void); - -/** - * Probes a bytestream to determine the input format. Each time a probe returns - * with a score that is too low, the probe buffer size is increased and another - * attempt is made. When the maximum probe size is reached, the input format - * with the highest score is returned. - * - * @param pb the bytestream to probe, it may be closed and opened again - * @param fmt the input format is put here - * @param filename the filename of the stream - * @param logctx the log context - * @param offset the offset within the bytestream to probe from - * @param max_probe_size the maximum probe buffer size (zero for default) - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code otherwise - */ -int ff_probe_input_buffer(ByteIOContext **pb, AVInputFormat **fmt, - const char *filename, void *logctx, - unsigned int offset, unsigned int max_probe_size); - -/** - * Splits a URL string into components. To reassemble components back into - * a URL, use ff_url_join instead of using snprintf directly. - * - * The pointers to buffers for storing individual components may be null, - * in order to ignore that component. Buffers for components not found are - * set to empty strings. If the port isn't found, it is set to a negative - * value. - * - * @see ff_url_join - * - * @param proto the buffer for the protocol - * @param proto_size the size of the proto buffer - * @param authorization the buffer for the authorization - * @param authorization_size the size of the authorization buffer - * @param hostname the buffer for the host name - * @param hostname_size the size of the hostname buffer - * @param port_ptr a pointer to store the port number in - * @param path the buffer for the path - * @param path_size the size of the path buffer - * @param url the URL to split - */ -void ff_url_split(char *proto, int proto_size, - char *authorization, int authorization_size, - char *hostname, int hostname_size, - int *port_ptr, - char *path, int path_size, - const char *url); - -/** - * Assembles a URL string from components. This is the reverse operation - * of ff_url_split. - * - * Note, this requires networking to be initialized, so the caller must - * ensure ff_network_init has been called. - * - * @see ff_url_split - * - * @param str the buffer to fill with the url - * @param size the size of the str buffer - * @param proto the protocol identifier, if null, the separator - * after the identifier is left out, too - * @param authorization an optional authorization string, may be null - * @param hostname the host name string - * @param port the port number, left out from the string if negative - * @param fmt a generic format string for everything to add after the - * host/port, may be null - * @return the number of characters written to the destination buffer - */ -int ff_url_join(char *str, int size, const char *proto, - const char *authorization, const char *hostname, - int port, const char *fmt, ...); - -/** - * Appends the media-specific SDP fragment for the media stream c - * to the buffer buff. - * - * Note, the buffer needs to be initialized, since it is appended to - * existing content. - * - * @param buff the buffer to append the SDP fragment to - * @param size the size of the buff buffer - * @param c the AVCodecContext of the media to describe - * @param dest_addr the destination address of the media stream, may be NULL - * @param port the destination port of the media stream, 0 if unknown - * @param ttl the time to live of the stream, 0 if not multicast - */ -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, - const char *dest_addr, int port, int ttl); - -#endif /* AVFORMAT_INTERNAL_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/ipmovie.c b/tizen/distrib/ffmpeg/libavformat/ipmovie.c deleted file mode 100644 index 372a926..0000000 --- a/tizen/distrib/ffmpeg/libavformat/ipmovie.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Interplay MVE File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Interplay MVE file demuxer - * by Mike Melanson (melanson@pcisys.net) - * For more information regarding the Interplay MVE file format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * The aforementioned site also contains a command line utility for parsing - * IP MVE files so that you can get a good idea of the typical structure of - * such files. This demuxer is not the best example to use if you are trying - * to write your own as it uses a rather roundabout approach for splitting - * up and sending out the chunks. - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -/* debugging support: #define DEBUG_IPMOVIE as non-zero to see extremely - * verbose information about the demux process */ -#define DEBUG_IPMOVIE 0 - -#if DEBUG_IPMOVIE -#undef printf -#define debug_ipmovie printf -#else -static inline void debug_ipmovie(const char *format, ...) { } -#endif - -#define CHUNK_PREAMBLE_SIZE 4 -#define OPCODE_PREAMBLE_SIZE 4 - -#define CHUNK_INIT_AUDIO 0x0000 -#define CHUNK_AUDIO_ONLY 0x0001 -#define CHUNK_INIT_VIDEO 0x0002 -#define CHUNK_VIDEO 0x0003 -#define CHUNK_SHUTDOWN 0x0004 -#define CHUNK_END 0x0005 -/* these last types are used internally */ -#define CHUNK_DONE 0xFFFC -#define CHUNK_NOMEM 0xFFFD -#define CHUNK_EOF 0xFFFE -#define CHUNK_BAD 0xFFFF - -#define OPCODE_END_OF_STREAM 0x00 -#define OPCODE_END_OF_CHUNK 0x01 -#define OPCODE_CREATE_TIMER 0x02 -#define OPCODE_INIT_AUDIO_BUFFERS 0x03 -#define OPCODE_START_STOP_AUDIO 0x04 -#define OPCODE_INIT_VIDEO_BUFFERS 0x05 -#define OPCODE_UNKNOWN_06 0x06 -#define OPCODE_SEND_BUFFER 0x07 -#define OPCODE_AUDIO_FRAME 0x08 -#define OPCODE_SILENCE_FRAME 0x09 -#define OPCODE_INIT_VIDEO_MODE 0x0A -#define OPCODE_CREATE_GRADIENT 0x0B -#define OPCODE_SET_PALETTE 0x0C -#define OPCODE_SET_PALETTE_COMPRESSED 0x0D -#define OPCODE_UNKNOWN_0E 0x0E -#define OPCODE_SET_DECODING_MAP 0x0F -#define OPCODE_UNKNOWN_10 0x10 -#define OPCODE_VIDEO_DATA 0x11 -#define OPCODE_UNKNOWN_12 0x12 -#define OPCODE_UNKNOWN_13 0x13 -#define OPCODE_UNKNOWN_14 0x14 -#define OPCODE_UNKNOWN_15 0x15 - -#define PALETTE_COUNT 256 - -typedef struct IPMVEContext { - - unsigned char *buf; - int buf_size; - - uint64_t frame_pts_inc; - - unsigned int video_bpp; - unsigned int video_width; - unsigned int video_height; - int64_t video_pts; - - unsigned int audio_bits; - unsigned int audio_channels; - unsigned int audio_sample_rate; - enum CodecID audio_type; - unsigned int audio_frame_count; - - int video_stream_index; - int audio_stream_index; - - int64_t audio_chunk_offset; - int audio_chunk_size; - int64_t video_chunk_offset; - int video_chunk_size; - int64_t decode_map_chunk_offset; - int decode_map_chunk_size; - - int64_t next_chunk_offset; - - AVPaletteControl palette_control; - -} IPMVEContext; - -static int load_ipmovie_packet(IPMVEContext *s, ByteIOContext *pb, - AVPacket *pkt) { - - int chunk_type; - - if (s->audio_chunk_offset) { - - /* adjust for PCM audio by skipping chunk header */ - if (s->audio_type != CODEC_ID_INTERPLAY_DPCM) { - s->audio_chunk_offset += 6; - s->audio_chunk_size -= 6; - } - - url_fseek(pb, s->audio_chunk_offset, SEEK_SET); - s->audio_chunk_offset = 0; - - if (s->audio_chunk_size != av_get_packet(pb, pkt, s->audio_chunk_size)) - return CHUNK_EOF; - - pkt->stream_index = s->audio_stream_index; - pkt->pts = s->audio_frame_count; - - /* audio frame maintenance */ - if (s->audio_type != CODEC_ID_INTERPLAY_DPCM) - s->audio_frame_count += - (s->audio_chunk_size / s->audio_channels / (s->audio_bits / 8)); - else - s->audio_frame_count += - (s->audio_chunk_size - 6) / s->audio_channels; - - debug_ipmovie("sending audio frame with pts %"PRId64" (%d audio frames)\n", - pkt->pts, s->audio_frame_count); - - chunk_type = CHUNK_VIDEO; - - } else if (s->decode_map_chunk_offset) { - - /* send both the decode map and the video data together */ - - if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size)) - return CHUNK_NOMEM; - - pkt->pos= s->decode_map_chunk_offset; - url_fseek(pb, s->decode_map_chunk_offset, SEEK_SET); - s->decode_map_chunk_offset = 0; - - if (get_buffer(pb, pkt->data, s->decode_map_chunk_size) != - s->decode_map_chunk_size) { - av_free_packet(pkt); - return CHUNK_EOF; - } - - url_fseek(pb, s->video_chunk_offset, SEEK_SET); - s->video_chunk_offset = 0; - - if (get_buffer(pb, pkt->data + s->decode_map_chunk_size, - s->video_chunk_size) != s->video_chunk_size) { - av_free_packet(pkt); - return CHUNK_EOF; - } - - pkt->stream_index = s->video_stream_index; - pkt->pts = s->video_pts; - - debug_ipmovie("sending video frame with pts %"PRId64"\n", - pkt->pts); - - s->video_pts += s->frame_pts_inc; - - chunk_type = CHUNK_VIDEO; - - } else { - - url_fseek(pb, s->next_chunk_offset, SEEK_SET); - chunk_type = CHUNK_DONE; - - } - - return chunk_type; -} - -/* This function loads and processes a single chunk in an IP movie file. - * It returns the type of chunk that was processed. */ -static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb, - AVPacket *pkt) -{ - unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; - int chunk_type; - int chunk_size; - unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE]; - unsigned char opcode_type; - unsigned char opcode_version; - int opcode_size; - unsigned char scratch[1024]; - int i, j; - int first_color, last_color; - int audio_flags; - unsigned char r, g, b; - - /* see if there are any pending packets */ - chunk_type = load_ipmovie_packet(s, pb, pkt); - if (chunk_type != CHUNK_DONE) - return chunk_type; - - /* read the next chunk, wherever the file happens to be pointing */ - if (url_feof(pb)) - return CHUNK_EOF; - if (get_buffer(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) != - CHUNK_PREAMBLE_SIZE) - return CHUNK_BAD; - chunk_size = AV_RL16(&chunk_preamble[0]); - chunk_type = AV_RL16(&chunk_preamble[2]); - - debug_ipmovie("chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size); - - switch (chunk_type) { - - case CHUNK_INIT_AUDIO: - debug_ipmovie("initialize audio\n"); - break; - - case CHUNK_AUDIO_ONLY: - debug_ipmovie("audio only\n"); - break; - - case CHUNK_INIT_VIDEO: - debug_ipmovie("initialize video\n"); - break; - - case CHUNK_VIDEO: - debug_ipmovie("video (and audio)\n"); - break; - - case CHUNK_SHUTDOWN: - debug_ipmovie("shutdown\n"); - break; - - case CHUNK_END: - debug_ipmovie("end\n"); - break; - - default: - debug_ipmovie("invalid chunk\n"); - chunk_type = CHUNK_BAD; - break; - - } - - while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) { - - /* read the next chunk, wherever the file happens to be pointing */ - if (url_feof(pb)) { - chunk_type = CHUNK_EOF; - break; - } - if (get_buffer(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) != - CHUNK_PREAMBLE_SIZE) { - chunk_type = CHUNK_BAD; - break; - } - - opcode_size = AV_RL16(&opcode_preamble[0]); - opcode_type = opcode_preamble[2]; - opcode_version = opcode_preamble[3]; - - chunk_size -= OPCODE_PREAMBLE_SIZE; - chunk_size -= opcode_size; - if (chunk_size < 0) { - debug_ipmovie("chunk_size countdown just went negative\n"); - chunk_type = CHUNK_BAD; - break; - } - - debug_ipmovie(" opcode type %02X, version %d, 0x%04X bytes: ", - opcode_type, opcode_version, opcode_size); - switch (opcode_type) { - - case OPCODE_END_OF_STREAM: - debug_ipmovie("end of stream\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_END_OF_CHUNK: - debug_ipmovie("end of chunk\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_CREATE_TIMER: - debug_ipmovie("create timer\n"); - if ((opcode_version > 0) || (opcode_size > 6)) { - debug_ipmovie("bad create_timer opcode\n"); - chunk_type = CHUNK_BAD; - break; - } - if (get_buffer(pb, scratch, opcode_size) != - opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - s->frame_pts_inc = ((uint64_t)AV_RL32(&scratch[0])) * AV_RL16(&scratch[4]); - debug_ipmovie(" %.2f frames/second (timer div = %d, subdiv = %d)\n", - 1000000.0/s->frame_pts_inc, AV_RL32(&scratch[0]), AV_RL16(&scratch[4])); - break; - - case OPCODE_INIT_AUDIO_BUFFERS: - debug_ipmovie("initialize audio buffers\n"); - if ((opcode_version > 1) || (opcode_size > 10)) { - debug_ipmovie("bad init_audio_buffers opcode\n"); - chunk_type = CHUNK_BAD; - break; - } - if (get_buffer(pb, scratch, opcode_size) != - opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - s->audio_sample_rate = AV_RL16(&scratch[4]); - audio_flags = AV_RL16(&scratch[2]); - /* bit 0 of the flags: 0 = mono, 1 = stereo */ - s->audio_channels = (audio_flags & 1) + 1; - /* bit 1 of the flags: 0 = 8 bit, 1 = 16 bit */ - s->audio_bits = (((audio_flags >> 1) & 1) + 1) * 8; - /* bit 2 indicates compressed audio in version 1 opcode */ - if ((opcode_version == 1) && (audio_flags & 0x4)) - s->audio_type = CODEC_ID_INTERPLAY_DPCM; - else if (s->audio_bits == 16) - s->audio_type = CODEC_ID_PCM_S16LE; - else - s->audio_type = CODEC_ID_PCM_U8; - debug_ipmovie("audio: %d bits, %d Hz, %s, %s format\n", - s->audio_bits, - s->audio_sample_rate, - (s->audio_channels == 2) ? "stereo" : "mono", - (s->audio_type == CODEC_ID_INTERPLAY_DPCM) ? - "Interplay audio" : "PCM"); - break; - - case OPCODE_START_STOP_AUDIO: - debug_ipmovie("start/stop audio\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_INIT_VIDEO_BUFFERS: - debug_ipmovie("initialize video buffers\n"); - if ((opcode_version > 2) || (opcode_size > 8)) { - debug_ipmovie("bad init_video_buffers opcode\n"); - chunk_type = CHUNK_BAD; - break; - } - if (get_buffer(pb, scratch, opcode_size) != - opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - s->video_width = AV_RL16(&scratch[0]) * 8; - s->video_height = AV_RL16(&scratch[2]) * 8; - if (opcode_version < 2 || !AV_RL16(&scratch[6])) { - s->video_bpp = 8; - } else { - s->video_bpp = 16; - } - debug_ipmovie("video resolution: %d x %d\n", - s->video_width, s->video_height); - break; - - case OPCODE_UNKNOWN_06: - case OPCODE_UNKNOWN_0E: - case OPCODE_UNKNOWN_10: - case OPCODE_UNKNOWN_12: - case OPCODE_UNKNOWN_13: - case OPCODE_UNKNOWN_14: - case OPCODE_UNKNOWN_15: - debug_ipmovie("unknown (but documented) opcode %02X\n", opcode_type); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_SEND_BUFFER: - debug_ipmovie("send buffer\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_AUDIO_FRAME: - debug_ipmovie("audio frame\n"); - - /* log position and move on for now */ - s->audio_chunk_offset = url_ftell(pb); - s->audio_chunk_size = opcode_size; - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_SILENCE_FRAME: - debug_ipmovie("silence frame\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_INIT_VIDEO_MODE: - debug_ipmovie("initialize video mode\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_CREATE_GRADIENT: - debug_ipmovie("create gradient\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_SET_PALETTE: - debug_ipmovie("set palette\n"); - /* check for the logical maximum palette size - * (3 * 256 + 4 bytes) */ - if (opcode_size > 0x304) { - debug_ipmovie("demux_ipmovie: set_palette opcode too large\n"); - chunk_type = CHUNK_BAD; - break; - } - if (get_buffer(pb, scratch, opcode_size) != opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - - /* load the palette into internal data structure */ - first_color = AV_RL16(&scratch[0]); - last_color = first_color + AV_RL16(&scratch[2]) - 1; - /* sanity check (since they are 16 bit values) */ - if ((first_color > 0xFF) || (last_color > 0xFF)) { - debug_ipmovie("demux_ipmovie: set_palette indexes out of range (%d -> %d)\n", - first_color, last_color); - chunk_type = CHUNK_BAD; - break; - } - j = 4; /* offset of first palette data */ - for (i = first_color; i <= last_color; i++) { - /* the palette is stored as a 6-bit VGA palette, thus each - * component is shifted up to a 8-bit range */ - r = scratch[j++] * 4; - g = scratch[j++] * 4; - b = scratch[j++] * 4; - s->palette_control.palette[i] = (r << 16) | (g << 8) | (b); - } - /* indicate a palette change */ - s->palette_control.palette_changed = 1; - break; - - case OPCODE_SET_PALETTE_COMPRESSED: - debug_ipmovie("set palette compressed\n"); - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_SET_DECODING_MAP: - debug_ipmovie("set decoding map\n"); - - /* log position and move on for now */ - s->decode_map_chunk_offset = url_ftell(pb); - s->decode_map_chunk_size = opcode_size; - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - case OPCODE_VIDEO_DATA: - debug_ipmovie("set video data\n"); - - /* log position and move on for now */ - s->video_chunk_offset = url_ftell(pb); - s->video_chunk_size = opcode_size; - url_fseek(pb, opcode_size, SEEK_CUR); - break; - - default: - debug_ipmovie("*** unknown opcode type\n"); - chunk_type = CHUNK_BAD; - break; - - } - } - - /* make a note of where the stream is sitting */ - s->next_chunk_offset = url_ftell(pb); - - /* dispatch the first of any pending packets */ - if ((chunk_type == CHUNK_VIDEO) || (chunk_type == CHUNK_AUDIO_ONLY)) - chunk_type = load_ipmovie_packet(s, pb, pkt); - - return chunk_type; -} - -static const char signature[] = "Interplay MVE File\x1A\0\x1A"; - -static int ipmovie_probe(AVProbeData *p) -{ - uint8_t *b = p->buf; - uint8_t *b_end = p->buf + p->buf_size - sizeof(signature); - do { - if (memcmp(b++, signature, sizeof(signature)) == 0) - return AVPROBE_SCORE_MAX; - } while (b < b_end); - - return 0; -} - -static int ipmovie_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - IPMVEContext *ipmovie = s->priv_data; - ByteIOContext *pb = s->pb; - AVPacket pkt; - AVStream *st; - unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; - int chunk_type; - uint8_t signature_buffer[sizeof(signature)]; - - get_buffer(pb, signature_buffer, sizeof(signature_buffer)); - while (memcmp(signature_buffer, signature, sizeof(signature))) { - memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1); - signature_buffer[sizeof(signature_buffer) - 1] = get_byte(pb); - if (url_feof(pb)) - return AVERROR_EOF; - } - /* initialize private context members */ - ipmovie->video_pts = ipmovie->audio_frame_count = 0; - ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset = - ipmovie->decode_map_chunk_offset = 0; - - /* on the first read, this will position the stream at the first chunk */ - ipmovie->next_chunk_offset = url_ftell(pb) + 4; - - /* process the first chunk which should be CHUNK_INIT_VIDEO */ - if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO) - return AVERROR_INVALIDDATA; - - /* peek ahead to the next chunk-- if it is an init audio chunk, process - * it; if it is the first video chunk, this is a silent file */ - if (get_buffer(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) != - CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - chunk_type = AV_RL16(&chunk_preamble[2]); - url_fseek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR); - - if (chunk_type == CHUNK_VIDEO) - ipmovie->audio_type = CODEC_ID_NONE; /* no audio */ - else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) - return AVERROR_INVALIDDATA; - - /* initialize the stream decoders */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 63, 1, 1000000); - ipmovie->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_INTERPLAY_VIDEO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = ipmovie->video_width; - st->codec->height = ipmovie->video_height; - st->codec->bits_per_coded_sample = ipmovie->video_bpp; - - /* palette considerations */ - st->codec->palctrl = &ipmovie->palette_control; - - if (ipmovie->audio_type) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate); - ipmovie->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ipmovie->audio_type; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = ipmovie->audio_channels; - st->codec->sample_rate = ipmovie->audio_sample_rate; - st->codec->bits_per_coded_sample = ipmovie->audio_bits; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - if (st->codec->codec_id == CODEC_ID_INTERPLAY_DPCM) - st->codec->bit_rate /= 2; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - } - - return 0; -} - -static int ipmovie_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - IPMVEContext *ipmovie = s->priv_data; - ByteIOContext *pb = s->pb; - int ret; - - ret = process_ipmovie_chunk(ipmovie, pb, pkt); - if (ret == CHUNK_BAD) - ret = AVERROR_INVALIDDATA; - else if (ret == CHUNK_EOF) - ret = AVERROR(EIO); - else if (ret == CHUNK_NOMEM) - ret = AVERROR(ENOMEM); - else if (ret == CHUNK_VIDEO) - ret = 0; - else - ret = -1; - - return ret; -} - -AVInputFormat ipmovie_demuxer = { - "ipmovie", - NULL_IF_CONFIG_SMALL("Interplay MVE format"), - sizeof(IPMVEContext), - ipmovie_probe, - ipmovie_read_header, - ipmovie_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/isom.c b/tizen/distrib/ffmpeg/libavformat/isom.c deleted file mode 100644 index a6e67e2..0000000 --- a/tizen/distrib/ffmpeg/libavformat/isom.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * ISO Media common code - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002 Francois Revol - * Copyright (c) 2006 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "riff.h" -#include "isom.h" - -/* http://www.mp4ra.org */ -/* ordered by muxing preference */ -const AVCodecTag ff_mp4_obj_type[] = { - { CODEC_ID_MOV_TEXT , 0x08 }, - { CODEC_ID_MPEG4 , 0x20 }, - { CODEC_ID_H264 , 0x21 }, - { CODEC_ID_AAC , 0x40 }, - { CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */ - { CODEC_ID_MPEG2VIDEO, 0x61 }, /* MPEG2 Main */ - { CODEC_ID_MPEG2VIDEO, 0x60 }, /* MPEG2 Simple */ - { CODEC_ID_MPEG2VIDEO, 0x62 }, /* MPEG2 SNR */ - { CODEC_ID_MPEG2VIDEO, 0x63 }, /* MPEG2 Spatial */ - { CODEC_ID_MPEG2VIDEO, 0x64 }, /* MPEG2 High */ - { CODEC_ID_MPEG2VIDEO, 0x65 }, /* MPEG2 422 */ - { CODEC_ID_AAC , 0x66 }, /* MPEG2 AAC Main */ - { CODEC_ID_AAC , 0x67 }, /* MPEG2 AAC Low */ - { CODEC_ID_AAC , 0x68 }, /* MPEG2 AAC SSR */ - { CODEC_ID_MP3 , 0x69 }, /* 13818-3 */ - { CODEC_ID_MP2 , 0x69 }, /* 11172-3 */ - { CODEC_ID_MPEG1VIDEO, 0x6A }, /* 11172-2 */ - { CODEC_ID_MP3 , 0x6B }, /* 11172-3 */ - { CODEC_ID_MJPEG , 0x6C }, /* 10918-1 */ - { CODEC_ID_PNG , 0x6D }, - { CODEC_ID_JPEG2000 , 0x6E }, /* 15444-1 */ - { CODEC_ID_VC1 , 0xA3 }, - { CODEC_ID_DIRAC , 0xA4 }, - { CODEC_ID_AC3 , 0xA5 }, - { CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */ - { CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */ - { CODEC_ID_QCELP , 0xE1 }, - { CODEC_ID_NONE , 0 }, -}; - -const AVCodecTag codec_movvideo_tags[] = { -/* { CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */ - - { CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') }, /* Uncompressed RGB */ - { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') }, /* Uncompressed YUV422 */ - { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') }, /* YUV with alpha-channel (AVID Uncompressed) */ - { CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* UNCOMPRESSED 8BIT 4:2:2 */ - { CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') }, /* same as 2vuy but byte swapped */ - - { CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, /* UNCOMPRESSED 10BIT RGB */ - { CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, /* UNCOMPRESSED 10BIT 4:2:2 */ - - { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */ - { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */ - { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */ -/* { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */ - { CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') }, /* Motion JPEG OpenDML */ - { CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */ - - { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */ - { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */ - { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/ - { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */ - - { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, - { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */ - { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, - { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */ - - { CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H263 */ - { CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H263 ?? works */ - - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL produced by FCP */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL produced by FCP */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC produced by FCP */ - { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, /* AVID DV */ - { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') }, /* AVID DV100 */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'q') }, /* DVCPRO HD 720p50 */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'p') }, /* DVCPRO HD 720p60 */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '2') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '4') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') }, /* DVCPRO HD 50i produced by FCP */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') }, /* DVCPRO HD 60i produced by FCP */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '3') }, /* DVCPRO HD 30p produced by FCP */ - - { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */ - { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */ - { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */ - { CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */ - { CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */ - { CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */ - { CODEC_ID_MSRLE, MKTAG('W', 'R', 'L', 'E') }, - { CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */ - - { CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') }, - - { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */ - - { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */ - { CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, - { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG2 HDV 720p30 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 HDV 1080i60 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG2 HDV 1080i50 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG2 HDV 720p25 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG2 HDV 1080p24 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG2 HDV 1080p25 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG2 HDV 1080p30 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */ - { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */ - { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG2 IMX NTSC 525/60 40mb/s produced by FCP */ - { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') }, /* MPEG2 IMX PAL 625/50 40mb/s produced by FCP */ - { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG2 IMX NTSC 525/60 30mb/s produced by FCP */ - { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG2 IMX PAL 625/50 30mb/s produced by FCP */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') }, /* XDCAM HD422 720p60 CBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'a') }, /* XDCAM HD422 720p50 CBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'b') }, /* XDCAM HD422 1080i60 CBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'c') }, /* XDCAM HD422 1080i50 CBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'd') }, /* XDCAM HD422 1080p24 CBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'e') }, /* XDCAM HD422 1080p25 CBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'f') }, /* XDCAM HD422 1080p30 CBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '1') }, /* XDCAM EX 720p30 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '2') }, /* XDCAM HD 1080i60 */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '3') }, /* XDCAM HD 1080i50 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '4') }, /* XDCAM EX 720p24 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '5') }, /* XDCAM EX 720p25 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '6') }, /* XDCAM HD 1080p24 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '7') }, /* XDCAM HD 1080p25 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '8') }, /* XDCAM HD 1080p30 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '9') }, /* XDCAM EX 720p60 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'a') }, /* XDCAM EX 720p50 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'b') }, /* XDCAM EX 1080i60 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'c') }, /* XDCAM EX 1080i50 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */ - { CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */ - { CODEC_ID_MPEG2VIDEO, MKTAG('m', '2', 'v', '1') }, - - { CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */ - - { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, /* Truevision Targa */ - { CODEC_ID_TIFF, MKTAG('t', 'i', 'f', 'f') }, /* TIFF embedded in MOV */ - { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, /* embedded gif files as frames (usually one "click to play movie" frame) */ - { CODEC_ID_PNG, MKTAG('p', 'n', 'g', ' ') }, - - { CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') }, /* SMPTE RP 2025 */ - { CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') }, - - { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, - { CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */ - { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') }, /* AVID 1:1x */ - { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') }, - { CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') }, /* SGI */ - { CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') }, /* DPX */ - - { CODEC_ID_NONE, 0 }, -}; - -const AVCodecTag codec_movaudio_tags[] = { - { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') }, - { CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') }, - { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') }, - { CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') }, - { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */ - { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /* */ - { CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') }, - { CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') }, - { CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') }, - { CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') }, - { CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') }, - { CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') }, - { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */ - { CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') }, /* uncompressed */ - { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /* */ - { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /* */ - - { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */ - - { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */ - { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */ - - { CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') }, /* MPEG layer 1 */ - { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') }, /* MPEG layer 2 */ - - { CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */ - { CODEC_ID_MP3, 0x6D730055 }, /* MPEG layer 3 */ - -/* { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */ - - { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */ - { CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */ - { CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */ - - { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */ - { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ - - { CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') }, - { CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */ - - { CODEC_ID_QCELP, MKTAG('Q','c','l','p') }, - { CODEC_ID_QCELP, MKTAG('Q','c','l','q') }, - { CODEC_ID_QCELP, MKTAG('s','q','c','p') }, /* ISO Media fourcc */ - - { CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */ - - { CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') }, - { CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') }, - - { CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') }, - - { CODEC_ID_NONE, 0 }, -}; - -const AVCodecTag ff_codec_movsubtitle_tags[] = { - { CODEC_ID_MOV_TEXT, MKTAG('t', 'e', 'x', 't') }, - { CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') }, - { CODEC_ID_NONE, 0 }, -}; - -/* map numeric codes from mdhd atom to ISO 639 */ -/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */ -/* http://developer.apple.com/documentation/mac/Text/Text-368.html */ -/* deprecated by putting the code as 3*5bit ascii */ -static const char mov_mdhd_language_map[][4] = { - /* 0-9 */ - "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor", - "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/, - "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "", - "fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk", - "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze", - /*?*/ - "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus", - "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj", - "pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao", - /* roman? arabic? */ - "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa", - /*==rundi?*/ - "", "run", "", "mlg", "epo", "", "", "", "", "", - /* 100 */ - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "wel", "baq", - "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav" -}; - -int ff_mov_iso639_to_lang(const char lang[4], int mp4) -{ - int i, code = 0; - - /* old way, only for QT? */ - for (i = 0; lang[0] && !mp4 && i < FF_ARRAY_ELEMS(mov_mdhd_language_map); i++) { - if (!strcmp(lang, mov_mdhd_language_map[i])) - return i; - } - /* XXX:can we do that in mov too? */ - if (!mp4) - return -1; - /* handle undefined as such */ - if (lang[0] == '\0') - lang = "und"; - /* 5bit ascii */ - for (i = 0; i < 3; i++) { - uint8_t c = lang[i]; - c -= 0x60; - if (c > 0x1f) - return -1; - code <<= 5; - code |= c; - } - return code; -} - -int ff_mov_lang_to_iso639(unsigned code, char to[4]) -{ - int i; - memset(to, 0, 4); - /* is it the mangled iso code? */ - /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */ - if (code > 138) { - for (i = 2; i >= 0; i--) { - to[i] = 0x60 + (code & 0x1f); - code >>= 5; - } - return 1; - } - /* old fashion apple lang code */ - if (code >= FF_ARRAY_ELEMS(mov_mdhd_language_map)) - return 0; - if (!mov_mdhd_language_map[code][0]) - return 0; - memcpy(to, mov_mdhd_language_map[code], 4); - return 1; -} diff --git a/tizen/distrib/ffmpeg/libavformat/isom.h b/tizen/distrib/ffmpeg/libavformat/isom.h deleted file mode 100644 index 92997a7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/isom.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * ISO Media common code - * copyright (c) 2001 Fabrice Bellard - * copyright (c) 2002 Francois Revol - * copyright (c) 2006 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_ISOM_H -#define AVFORMAT_ISOM_H - -#include "avio.h" -#include "riff.h" -#include "dv.h" - -/* isom.c */ -extern const AVCodecTag ff_mp4_obj_type[]; -extern const AVCodecTag codec_movvideo_tags[]; -extern const AVCodecTag codec_movaudio_tags[]; -extern const AVCodecTag ff_codec_movsubtitle_tags[]; - -int ff_mov_iso639_to_lang(const char lang[4], int mp4); -int ff_mov_lang_to_iso639(unsigned code, char to[4]); - -/* the QuickTime file format is quite convoluted... - * it has lots of index tables, each indexing something in another one... - * Here we just use what is needed to read the chunks - */ - -typedef struct { - int count; - int duration; -} MOVStts; - -typedef struct { - int first; - int count; - int id; -} MOVStsc; - -typedef struct { - uint32_t type; - char *path; - char *dir; - char volume[28]; - char filename[64]; - int16_t nlvl_to, nlvl_from; -} MOVDref; - -typedef struct { - uint32_t type; - int64_t size; /* total size (excluding the size and type fields) */ -} MOVAtom; - -struct MOVParseTableEntry; - -typedef struct { - unsigned track_id; - uint64_t base_data_offset; - uint64_t moof_offset; - unsigned stsd_id; - unsigned duration; - unsigned size; - unsigned flags; -} MOVFragment; - -typedef struct { - unsigned track_id; - unsigned stsd_id; - unsigned duration; - unsigned size; - unsigned flags; -} MOVTrackExt; - -typedef struct MOVStreamContext { - ByteIOContext *pb; - int ffindex; ///< AVStream index - int next_chunk; - unsigned int chunk_count; - int64_t *chunk_offsets; - unsigned int stts_count; - MOVStts *stts_data; - unsigned int ctts_count; - MOVStts *ctts_data; - unsigned int stsc_count; - MOVStsc *stsc_data; - unsigned int stps_count; - unsigned *stps_data; ///< partial sync sample for mpeg-2 open gop - int ctts_index; - int ctts_sample; - unsigned int sample_size; - unsigned int sample_count; - int *sample_sizes; - unsigned int keyframe_count; - int *keyframes; - int time_scale; - int time_offset; ///< time offset of the first edit list entry - int current_sample; - unsigned int bytes_per_frame; - unsigned int samples_per_frame; - int dv_audio_container; - int pseudo_stream_id; ///< -1 means demux all ids - int16_t audio_cid; ///< stsd audio compression id - unsigned drefs_count; - MOVDref *drefs; - int dref_id; - int wrong_dts; ///< dts are wrong due to huge ctts offset (iMovie files) - int width; ///< tkhd width - int height; ///< tkhd height - int dts_shift; ///< dts shift when ctts is negative -} MOVStreamContext; - -typedef struct MOVContext { - AVFormatContext *fc; - int time_scale; - int64_t duration; ///< duration of the longest track - int found_moov; ///< 'moov' atom has been found - int found_mdat; ///< 'mdat' atom has been found - DVDemuxContext *dv_demux; - AVFormatContext *dv_fctx; - int isom; ///< 1 if file is ISO Media (mp4/3gp) - MOVFragment fragment; ///< current fragment in moof atom - MOVTrackExt *trex_data; - unsigned trex_count; - int itunes_metadata; ///< metadata are itunes style - int chapter_track; -} MOVContext; - -int ff_mp4_read_descr_len(ByteIOContext *pb); -int ff_mov_read_esds(AVFormatContext *fc, ByteIOContext *pb, MOVAtom atom); -enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags); - -#endif /* AVFORMAT_ISOM_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/iss.c b/tizen/distrib/ffmpeg/libavformat/iss.c deleted file mode 100644 index 156af97..0000000 --- a/tizen/distrib/ffmpeg/libavformat/iss.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * ISS (.iss) file demuxer - * Copyright (c) 2008 Jaikrishnan Menon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Funcom ISS file demuxer - * @author Jaikrishnan Menon - * for more information on the .iss file format, visit: - * http://wiki.multimedia.cx/index.php?title=FunCom_ISS - */ - -#include "avformat.h" -#include "libavutil/avstring.h" - -#define ISS_SIG "IMA_ADPCM_Sound" -#define ISS_SIG_LEN 15 -#define MAX_TOKEN_SIZE 20 - -typedef struct { - int packet_size; - int sample_start_pos; -} IssDemuxContext; - -static void get_token(ByteIOContext *s, char *buf, int maxlen) -{ - int i = 0; - char c; - - while ((c = get_byte(s))) { - if(c == ' ') - break; - if (i < maxlen-1) - buf[i++] = c; - } - - if(!c) - get_byte(s); - - buf[i] = 0; /* Ensure null terminated, but may be truncated */ -} - -static int iss_probe(AVProbeData *p) -{ - if (strncmp(p->buf, ISS_SIG, ISS_SIG_LEN)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static av_cold int iss_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - IssDemuxContext *iss = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - char token[MAX_TOKEN_SIZE]; - int stereo, rate_divisor; - - get_token(pb, token, sizeof(token)); //"IMA_ADPCM_Sound" - get_token(pb, token, sizeof(token)); //packet size - sscanf(token, "%d", &iss->packet_size); - get_token(pb, token, sizeof(token)); //File ID - get_token(pb, token, sizeof(token)); //out size - get_token(pb, token, sizeof(token)); //stereo - sscanf(token, "%d", &stereo); - get_token(pb, token, sizeof(token)); //Unknown1 - get_token(pb, token, sizeof(token)); //RateDivisor - sscanf(token, "%d", &rate_divisor); - get_token(pb, token, sizeof(token)); //Unknown2 - get_token(pb, token, sizeof(token)); //Version ID - get_token(pb, token, sizeof(token)); //Size - - iss->sample_start_pos = url_ftell(pb); - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ADPCM_IMA_ISS; - st->codec->channels = stereo ? 2 : 1; - st->codec->sample_rate = 44100; - if(rate_divisor > 0) - st->codec->sample_rate /= rate_divisor; - st->codec->bits_per_coded_sample = 4; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate - * st->codec->bits_per_coded_sample; - st->codec->block_align = iss->packet_size; - av_set_pts_info(st, 32, 1, st->codec->sample_rate); - - return 0; -} - -static int iss_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - IssDemuxContext *iss = s->priv_data; - int ret = av_get_packet(s->pb, pkt, iss->packet_size); - - if(ret != iss->packet_size) - return AVERROR(EIO); - - pkt->stream_index = 0; - pkt->pts = url_ftell(s->pb) - iss->sample_start_pos; - if(s->streams[0]->codec->channels > 0) - pkt->pts /= s->streams[0]->codec->channels*2; - return 0; -} - -AVInputFormat iss_demuxer = { - "ISS", - NULL_IF_CONFIG_SMALL("Funcom ISS format"), - sizeof(IssDemuxContext), - iss_probe, - iss_read_header, - iss_read_packet, -}; - diff --git a/tizen/distrib/ffmpeg/libavformat/iv8.c b/tizen/distrib/ffmpeg/libavformat/iv8.c deleted file mode 100644 index 00ddcd4..0000000 --- a/tizen/distrib/ffmpeg/libavformat/iv8.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2009 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" - - -static int probe(AVProbeData *p) -{ - // the single file i have starts with that, i dont know if others do too - if( p->buf[0] == 1 - && p->buf[1] == 1 - && p->buf[2] == 3 - && p->buf[3] == 0xB8 - && p->buf[4] == 0x80 - && p->buf[5] == 0x60 - ) - return AVPROBE_SCORE_MAX-2; - - return 0; -} - -static int read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - AVStream *st; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG4; - st->need_parsing = AVSTREAM_PARSE_FULL; - av_set_pts_info(st, 64, 1, 90000); - - return 0; - -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size, pts, type; -retry: - type= get_be16(s->pb); // 257 or 258 - size= get_be16(s->pb); - - get_be16(s->pb); //some flags, 0x80 indicates end of frame - get_be16(s->pb); //packet number - pts=get_be32(s->pb); - get_be32(s->pb); //6A 13 E3 88 - - size -= 12; - if(size<1) - return -1; - - if(type==258){ - url_fskip(s->pb, size); - goto retry; - } - - ret= av_get_packet(s->pb, pkt, size); - - pkt->pts= pts; - pkt->pos-=16; - - pkt->stream_index = 0; - - return ret; -} - -AVInputFormat iv8_demuxer = { - "iv8", - NULL_IF_CONFIG_SMALL("A format generated by IndigoVision 8000 video server"), - 0, - probe, - read_header, - read_packet, - .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_MPEG4, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/libavformat.v b/tizen/distrib/ffmpeg/libavformat/libavformat.v deleted file mode 100644 index da2311e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/libavformat.v +++ /dev/null @@ -1,3 +0,0 @@ -LIBAVFORMAT_$MAJOR { - global: *; -}; diff --git a/tizen/distrib/ffmpeg/libavformat/libnut.c b/tizen/distrib/ffmpeg/libavformat/libnut.c deleted file mode 100644 index 4543df7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/libnut.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * NUT (de)muxing via libnut - * copyright (c) 2006 Oded Shimon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * NUT demuxing and muxing via libnut. - * @author Oded Shimon - */ - -#include "avformat.h" -#include "riff.h" -#include - -#define ID_STRING "nut/multimedia container" -#define ID_LENGTH (strlen(ID_STRING) + 1) - -typedef struct { - nut_context_tt * nut; - nut_stream_header_tt * s; -} NUTContext; - -static const AVCodecTag nut_tags[] = { - { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, - { CODEC_ID_MP3, MKTAG('m', 'p', '3', ' ') }, - { CODEC_ID_VORBIS, MKTAG('v', 'r', 'b', 's') }, - { 0, 0 }, -}; - -#if CONFIG_LIBNUT_MUXER -static int av_write(void * h, size_t len, const uint8_t * buf) { - ByteIOContext * bc = h; - put_buffer(bc, buf, len); - //put_flush_packet(bc); - return len; -} - -static int nut_write_header(AVFormatContext * avf) { - NUTContext * priv = avf->priv_data; - ByteIOContext * bc = avf->pb; - nut_muxer_opts_tt mopts = { - .output = { - .priv = bc, - .write = av_write, - }, - .alloc = { av_malloc, av_realloc, av_free }, - .write_index = 1, - .realtime_stream = 0, - .max_distance = 32768, - .fti = NULL, - }; - nut_stream_header_tt * s; - int i; - - priv->s = s = av_mallocz((avf->nb_streams + 1) * sizeof*s); - - for (i = 0; i < avf->nb_streams; i++) { - AVCodecContext * codec = avf->streams[i]->codec; - int j; - int fourcc = 0; - int num, denom, ssize; - - s[i].type = codec->codec_type == AVMEDIA_TYPE_VIDEO ? NUT_VIDEO_CLASS : NUT_AUDIO_CLASS; - - if (codec->codec_tag) fourcc = codec->codec_tag; - else fourcc = ff_codec_get_tag(nut_tags, codec->codec_id); - - if (!fourcc) { - if (codec->codec_type == AVMEDIA_TYPE_VIDEO) fourcc = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id); - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) fourcc = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id); - } - - s[i].fourcc_len = 4; - s[i].fourcc = av_malloc(s[i].fourcc_len); - for (j = 0; j < s[i].fourcc_len; j++) s[i].fourcc[j] = (fourcc >> (j*8)) & 0xFF; - - ff_parse_specific_params(codec, &num, &ssize, &denom); - av_set_pts_info(avf->streams[i], 60, denom, num); - - s[i].time_base.num = denom; - s[i].time_base.den = num; - - s[i].fixed_fps = 0; - s[i].decode_delay = codec->has_b_frames; - s[i].codec_specific_len = codec->extradata_size; - s[i].codec_specific = codec->extradata; - - if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { - s[i].width = codec->width; - s[i].height = codec->height; - s[i].sample_width = 0; - s[i].sample_height = 0; - s[i].colorspace_type = 0; - } else { - s[i].samplerate_num = codec->sample_rate; - s[i].samplerate_denom = 1; - s[i].channel_count = codec->channels; - } - } - - s[avf->nb_streams].type = -1; - priv->nut = nut_muxer_init(&mopts, s, NULL); - - return 0; -} - -static int nut_write_packet(AVFormatContext * avf, AVPacket * pkt) { - NUTContext * priv = avf->priv_data; - nut_packet_tt p; - - p.len = pkt->size; - p.stream = pkt->stream_index; - p.pts = pkt->pts; - p.flags = pkt->flags & AV_PKT_FLAG_KEY ? NUT_FLAG_KEY : 0; - p.next_pts = 0; - - nut_write_frame_reorder(priv->nut, &p, pkt->data); - - return 0; -} - -static int nut_write_trailer(AVFormatContext * avf) { - ByteIOContext * bc = avf->pb; - NUTContext * priv = avf->priv_data; - int i; - - nut_muxer_uninit_reorder(priv->nut); - put_flush_packet(bc); - - for(i = 0; priv->s[i].type != -1; i++ ) av_freep(&priv->s[i].fourcc); - av_freep(&priv->s); - - return 0; -} - -AVOutputFormat libnut_muxer = { - "libnut", - "nut format", - "video/x-nut", - "nut", - sizeof(NUTContext), - CODEC_ID_VORBIS, - CODEC_ID_MPEG4, - nut_write_header, - nut_write_packet, - nut_write_trailer, - .flags = AVFMT_GLOBALHEADER, -}; -#endif /* CONFIG_LIBNUT_MUXER */ - -static int nut_probe(AVProbeData *p) { - if (!memcmp(p->buf, ID_STRING, ID_LENGTH)) return AVPROBE_SCORE_MAX; - - return 0; -} - -static size_t av_read(void * h, size_t len, uint8_t * buf) { - ByteIOContext * bc = h; - return get_buffer(bc, buf, len); -} - -static off_t av_seek(void * h, long long pos, int whence) { - ByteIOContext * bc = h; - if (whence == SEEK_END) { - pos = url_fsize(bc) + pos; - whence = SEEK_SET; - } - return url_fseek(bc, pos, whence); -} - -static int nut_read_header(AVFormatContext * avf, AVFormatParameters * ap) { - NUTContext * priv = avf->priv_data; - ByteIOContext * bc = avf->pb; - nut_demuxer_opts_tt dopts = { - .input = { - .priv = bc, - .seek = av_seek, - .read = av_read, - .eof = NULL, - .file_pos = 0, - }, - .alloc = { av_malloc, av_realloc, av_free }, - .read_index = 1, - .cache_syncpoints = 1, - }; - nut_context_tt * nut = priv->nut = nut_demuxer_init(&dopts); - nut_stream_header_tt * s; - int ret, i; - - if ((ret = nut_read_headers(nut, &s, NULL))) { - av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret)); - nut_demuxer_uninit(nut); - return -1; - } - - priv->s = s; - - for (i = 0; s[i].type != -1 && i < 2; i++) { - AVStream * st = av_new_stream(avf, i); - int j; - - for (j = 0; j < s[i].fourcc_len && j < 8; j++) st->codec->codec_tag |= s[i].fourcc[j]<<(j*8); - - st->codec->has_b_frames = s[i].decode_delay; - - st->codec->extradata_size = s[i].codec_specific_len; - if (st->codec->extradata_size) { - st->codec->extradata = av_mallocz(st->codec->extradata_size); - memcpy(st->codec->extradata, s[i].codec_specific, st->codec->extradata_size); - } - - av_set_pts_info(avf->streams[i], 60, s[i].time_base.num, s[i].time_base.den); - st->start_time = 0; - st->duration = s[i].max_pts; - - st->codec->codec_id = ff_codec_get_id(nut_tags, st->codec->codec_tag); - - switch(s[i].type) { - case NUT_AUDIO_CLASS: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, st->codec->codec_tag); - - st->codec->channels = s[i].channel_count; - st->codec->sample_rate = s[i].samplerate_num / s[i].samplerate_denom; - break; - case NUT_VIDEO_CLASS: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codec->codec_tag); - - st->codec->width = s[i].width; - st->codec->height = s[i].height; - st->sample_aspect_ratio.num = s[i].sample_width; - st->sample_aspect_ratio.den = s[i].sample_height; - break; - } - if (st->codec->codec_id == CODEC_ID_NONE) av_log(avf, AV_LOG_ERROR, "Unknown codec?!\n"); - } - - return 0; -} - -static int nut_read_packet(AVFormatContext * avf, AVPacket * pkt) { - NUTContext * priv = avf->priv_data; - nut_packet_tt pd; - int ret; - - ret = nut_read_next_packet(priv->nut, &pd); - - if (ret || av_new_packet(pkt, pd.len) < 0) { - if (ret != NUT_ERR_EOF) - av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret)); - return -1; - } - - if (pd.flags & NUT_FLAG_KEY) pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pts = pd.pts; - pkt->stream_index = pd.stream; - pkt->pos = url_ftell(avf->pb); - - ret = nut_read_frame(priv->nut, &pd.len, pkt->data); - - return ret; -} - -static int nut_read_seek(AVFormatContext * avf, int stream_index, int64_t target_ts, int flags) { - NUTContext * priv = avf->priv_data; - int active_streams[] = { stream_index, -1 }; - double time_pos = target_ts * priv->s[stream_index].time_base.num / (double)priv->s[stream_index].time_base.den; - - if (nut_seek(priv->nut, time_pos, 2*!(flags & AVSEEK_FLAG_BACKWARD), active_streams)) return -1; - - return 0; -} - -static int nut_read_close(AVFormatContext *s) { - NUTContext * priv = s->priv_data; - - nut_demuxer_uninit(priv->nut); - - return 0; -} - -AVInputFormat libnut_demuxer = { - "libnut", - NULL_IF_CONFIG_SMALL("NUT format"), - sizeof(NUTContext), - nut_probe, - nut_read_header, - nut_read_packet, - nut_read_close, - nut_read_seek, - .extensions = "nut", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/librtmp.c b/tizen/distrib/ffmpeg/libavformat/librtmp.c deleted file mode 100644 index d765102..0000000 --- a/tizen/distrib/ffmpeg/libavformat/librtmp.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * RTMP network protocol - * Copyright (c) 2010 Howard Chu - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RTMP protocol based on http://rtmpdump.mplayerhq.hu/ librtmp - */ - -#include "avformat.h" - -#include -#include - -static void rtmp_log(int level, const char *fmt, va_list args) -{ - switch (level) { - default: - case RTMP_LOGCRIT: level = AV_LOG_FATAL; break; - case RTMP_LOGERROR: level = AV_LOG_ERROR; break; - case RTMP_LOGWARNING: level = AV_LOG_WARNING; break; - case RTMP_LOGINFO: level = AV_LOG_INFO; break; - case RTMP_LOGDEBUG: level = AV_LOG_VERBOSE; break; - case RTMP_LOGDEBUG2: level = AV_LOG_DEBUG; break; - } - - av_vlog(NULL, level, fmt, args); - av_log(NULL, level, "\n"); -} - -static int rtmp_close(URLContext *s) -{ - RTMP *r = s->priv_data; - - RTMP_Close(r); - av_free(r); - return 0; -} - -/** - * Opens RTMP connection and verifies that the stream can be played. - * - * URL syntax: rtmp://server[:port][/app][/playpath][ keyword=value]... - * where 'app' is first one or two directories in the path - * (e.g. /ondemand/, /flash/live/, etc.) - * and 'playpath' is a file name (the rest of the path, - * may be prefixed with "mp4:") - * - * Additional RTMP library options may be appended as - * space-separated key-value pairs. - */ -static int rtmp_open(URLContext *s, const char *uri, int flags) -{ - RTMP *r; - int rc; - - r = av_mallocz(sizeof(RTMP)); - if (!r) - return AVERROR(ENOMEM); - - switch (av_log_get_level()) { - default: - case AV_LOG_FATAL: rc = RTMP_LOGCRIT; break; - case AV_LOG_ERROR: rc = RTMP_LOGERROR; break; - case AV_LOG_WARNING: rc = RTMP_LOGWARNING; break; - case AV_LOG_INFO: rc = RTMP_LOGINFO; break; - case AV_LOG_VERBOSE: rc = RTMP_LOGDEBUG; break; - case AV_LOG_DEBUG: rc = RTMP_LOGDEBUG2; break; - } - RTMP_LogSetLevel(rc); - RTMP_LogSetCallback(rtmp_log); - - RTMP_Init(r); - if (!RTMP_SetupURL(r, s->filename)) { - rc = -1; - goto fail; - } - - if (flags & URL_WRONLY) - r->Link.protocol |= RTMP_FEATURE_WRITE; - - if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) { - rc = -1; - goto fail; - } - - s->priv_data = r; - s->is_streamed = 1; - return 0; -fail: - av_free(r); - return rc; -} - -static int rtmp_write(URLContext *s, uint8_t *buf, int size) -{ - RTMP *r = s->priv_data; - - return RTMP_Write(r, buf, size); -} - -static int rtmp_read(URLContext *s, uint8_t *buf, int size) -{ - RTMP *r = s->priv_data; - - return RTMP_Read(r, buf, size); -} - -static int rtmp_read_pause(URLContext *s, int pause) -{ - RTMP *r = s->priv_data; - - if (pause) - r->m_pauseStamp = - r->m_channelTimestamp[r->m_mediaChannel]; - if (!RTMP_SendPause(r, pause, r->m_pauseStamp)) - return -1; - return 0; -} - -static int64_t rtmp_read_seek(URLContext *s, int stream_index, - int64_t timestamp, int flags) -{ - RTMP *r = s->priv_data; - - if (flags & AVSEEK_FLAG_BYTE) - return AVERROR(ENOSYS); - - /* seeks are in milliseconds */ - if (stream_index < 0) - timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE, - flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); - - if (!RTMP_SendSeek(r, timestamp)) - return -1; - return timestamp; -} - -static int rtmp_get_file_handle(URLContext *s) -{ - RTMP *r = s->priv_data; - - return r->m_sb.sb_socket; -} - -URLProtocol rtmp_protocol = { - "rtmp", - rtmp_open, - rtmp_read, - rtmp_write, - NULL, /* seek */ - rtmp_close, - NULL, /* next */ - rtmp_read_pause, - rtmp_read_seek, - rtmp_get_file_handle -}; - -URLProtocol rtmpt_protocol = { - "rtmpt", - rtmp_open, - rtmp_read, - rtmp_write, - NULL, /* seek */ - rtmp_close, - NULL, /* next */ - rtmp_read_pause, - rtmp_read_seek, - rtmp_get_file_handle -}; - -URLProtocol rtmpe_protocol = { - "rtmpe", - rtmp_open, - rtmp_read, - rtmp_write, - NULL, /* seek */ - rtmp_close, - NULL, /* next */ - rtmp_read_pause, - rtmp_read_seek, - rtmp_get_file_handle -}; - -URLProtocol rtmpte_protocol = { - "rtmpte", - rtmp_open, - rtmp_read, - rtmp_write, - NULL, /* seek */ - rtmp_close, - NULL, /* next */ - rtmp_read_pause, - rtmp_read_seek, - rtmp_get_file_handle -}; - -URLProtocol rtmps_protocol = { - "rtmps", - rtmp_open, - rtmp_read, - rtmp_write, - NULL, /* seek */ - rtmp_close, - NULL, /* next */ - rtmp_read_pause, - rtmp_read_seek, - rtmp_get_file_handle -}; diff --git a/tizen/distrib/ffmpeg/libavformat/lmlm4.c b/tizen/distrib/ffmpeg/libavformat/lmlm4.c deleted file mode 100644 index c1397fb..0000000 --- a/tizen/distrib/ffmpeg/libavformat/lmlm4.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Linux Media Labs MPEG-4 demuxer - * Copyright (c) 2008 Ivo van Poorten - * - * Due to a lack of sample files, only files with one channel are supported. - * u-law and ADPCM audio are unsupported for the same reason. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define LMLM4_I_FRAME 0x00 -#define LMLM4_P_FRAME 0x01 -#define LMLM4_B_FRAME 0x02 -#define LMLM4_INVALID 0x03 -#define LMLM4_MPEG1L2 0x04 - -#define LMLM4_MAX_PACKET_SIZE 1024 * 1024 - -static int lmlm4_probe(AVProbeData * pd) { - unsigned char *buf = pd->buf; - unsigned int frame_type, packet_size; - - frame_type = AV_RB16(buf+2); - packet_size = AV_RB32(buf+4); - - if (!AV_RB16(buf) && frame_type <= LMLM4_MPEG1L2 && packet_size && - frame_type != LMLM4_INVALID && packet_size <= LMLM4_MAX_PACKET_SIZE) { - - if (frame_type == LMLM4_MPEG1L2) { - if ((AV_RB16(buf+8) & 0xfffe) != 0xfffc) - return 0; - /* I could calculate the audio framesize and compare with - * packet_size-8, but that seems overkill */ - return AVPROBE_SCORE_MAX / 3; - } else if (AV_RB24(buf+8) == 0x000001) { /* PES Signal */ - return AVPROBE_SCORE_MAX / 5; - } - } - - return 0; -} - -static int lmlm4_read_header(AVFormatContext *s, AVFormatParameters *ap) { - AVStream *st; - - if (!(st = av_new_stream(s, 0))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG4; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - av_set_pts_info(st, 64, 1001, 30000); - - if (!(st = av_new_stream(s, 1))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_MP2; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt) { - ByteIOContext *pb = s->pb; - int ret; - unsigned int frame_type, packet_size, padding, frame_size; - - get_be16(pb); /* channel number */ - frame_type = get_be16(pb); - packet_size = get_be32(pb); - padding = -packet_size & 511; - frame_size = packet_size - 8; - - if (frame_type > LMLM4_MPEG1L2 || frame_type == LMLM4_INVALID) { - av_log(s, AV_LOG_ERROR, "invalid or unsupported frame_type\n"); - return AVERROR(EIO); - } - if (packet_size > LMLM4_MAX_PACKET_SIZE) { - av_log(s, AV_LOG_ERROR, "packet size exceeds maximum\n"); - return AVERROR(EIO); - } - - if ((ret = av_get_packet(pb, pkt, frame_size)) <= 0) - return AVERROR(EIO); - - url_fskip(pb, padding); - - switch (frame_type) { - case LMLM4_I_FRAME: - pkt->flags = AV_PKT_FLAG_KEY; - case LMLM4_P_FRAME: - case LMLM4_B_FRAME: - pkt->stream_index = 0; - break; - case LMLM4_MPEG1L2: - pkt->stream_index = 1; - break; - } - - return ret; -} - -AVInputFormat lmlm4_demuxer = { - "lmlm4", - NULL_IF_CONFIG_SMALL("lmlm4 raw format"), - 0, - lmlm4_probe, - lmlm4_read_header, - lmlm4_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/matroska.c b/tizen/distrib/ffmpeg/libavformat/matroska.c deleted file mode 100644 index dac4735..0000000 --- a/tizen/distrib/ffmpeg/libavformat/matroska.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Matroska common data - * Copyright (c) 2003-2004 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "matroska.h" - -const CodecTags ff_mkv_codec_tags[]={ - {"A_AAC" , CODEC_ID_AAC}, - {"A_AC3" , CODEC_ID_AC3}, - {"A_DTS" , CODEC_ID_DTS}, - {"A_EAC3" , CODEC_ID_EAC3}, - {"A_FLAC" , CODEC_ID_FLAC}, - {"A_MLP" , CODEC_ID_MLP}, - {"A_MPEG/L2" , CODEC_ID_MP2}, - {"A_MPEG/L1" , CODEC_ID_MP2}, - {"A_MPEG/L3" , CODEC_ID_MP3}, - {"A_PCM/FLOAT/IEEE" , CODEC_ID_PCM_F32LE}, - {"A_PCM/FLOAT/IEEE" , CODEC_ID_PCM_F64LE}, - {"A_PCM/INT/BIG" , CODEC_ID_PCM_S16BE}, - {"A_PCM/INT/BIG" , CODEC_ID_PCM_S24BE}, - {"A_PCM/INT/BIG" , CODEC_ID_PCM_S32BE}, - {"A_PCM/INT/LIT" , CODEC_ID_PCM_S16LE}, - {"A_PCM/INT/LIT" , CODEC_ID_PCM_S24LE}, - {"A_PCM/INT/LIT" , CODEC_ID_PCM_S32LE}, - {"A_PCM/INT/LIT" , CODEC_ID_PCM_U8}, - {"A_QUICKTIME/QDM2" , CODEC_ID_QDM2}, - {"A_REAL/14_4" , CODEC_ID_RA_144}, - {"A_REAL/28_8" , CODEC_ID_RA_288}, - {"A_REAL/ATRC" , CODEC_ID_ATRAC3}, - {"A_REAL/COOK" , CODEC_ID_COOK}, - {"A_REAL/SIPR" , CODEC_ID_SIPR}, - {"A_TRUEHD" , CODEC_ID_TRUEHD}, - {"A_TTA1" , CODEC_ID_TTA}, - {"A_VORBIS" , CODEC_ID_VORBIS}, - {"A_WAVPACK4" , CODEC_ID_WAVPACK}, - - {"S_TEXT/UTF8" , CODEC_ID_TEXT}, - {"S_TEXT/ASCII" , CODEC_ID_TEXT}, - {"S_TEXT/ASS" , CODEC_ID_SSA}, - {"S_TEXT/SSA" , CODEC_ID_SSA}, - {"S_ASS" , CODEC_ID_SSA}, - {"S_SSA" , CODEC_ID_SSA}, - {"S_VOBSUB" , CODEC_ID_DVD_SUBTITLE}, - {"S_HDMV/PGS" , CODEC_ID_HDMV_PGS_SUBTITLE}, - - {"V_DIRAC" , CODEC_ID_DIRAC}, - {"V_MJPEG" , CODEC_ID_MJPEG}, - {"V_MPEG1" , CODEC_ID_MPEG1VIDEO}, - {"V_MPEG2" , CODEC_ID_MPEG2VIDEO}, - {"V_MPEG4/ISO/ASP" , CODEC_ID_MPEG4}, - {"V_MPEG4/ISO/AP" , CODEC_ID_MPEG4}, - {"V_MPEG4/ISO/SP" , CODEC_ID_MPEG4}, - {"V_MPEG4/ISO/AVC" , CODEC_ID_H264}, - {"V_MPEG4/MS/V3" , CODEC_ID_MSMPEG4V3}, - {"V_REAL/RV10" , CODEC_ID_RV10}, - {"V_REAL/RV20" , CODEC_ID_RV20}, - {"V_REAL/RV30" , CODEC_ID_RV30}, - {"V_REAL/RV40" , CODEC_ID_RV40}, - {"V_SNOW" , CODEC_ID_SNOW}, - {"V_THEORA" , CODEC_ID_THEORA}, - {"V_UNCOMPRESSED" , CODEC_ID_RAWVIDEO}, - {"V_VP8" , CODEC_ID_VP8}, - - {"" , CODEC_ID_NONE} -}; - -const CodecMime ff_mkv_mime_tags[] = { - {"text/plain" , CODEC_ID_TEXT}, - {"image/gif" , CODEC_ID_GIF}, - {"image/jpeg" , CODEC_ID_MJPEG}, - {"image/png" , CODEC_ID_PNG}, - {"image/tiff" , CODEC_ID_TIFF}, - {"application/x-truetype-font", CODEC_ID_TTF}, - {"application/x-font" , CODEC_ID_TTF}, - - {"" , CODEC_ID_NONE} -}; - -const AVMetadataConv ff_mkv_metadata_conv[] = { - { "LEAD_PERFORMER", "performer" }, - { "PART_NUMBER" , "track" }, - { 0 } -}; diff --git a/tizen/distrib/ffmpeg/libavformat/matroska.h b/tizen/distrib/ffmpeg/libavformat/matroska.h deleted file mode 100644 index 40ab3a7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/matroska.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Matroska constants - * Copyright (c) 2003-2004 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_MATROSKA_H -#define AVFORMAT_MATROSKA_H - -#include "libavcodec/avcodec.h" -#include "metadata.h" - -/* EBML version supported */ -#define EBML_VERSION 1 - -/* top-level master-IDs */ -#define EBML_ID_HEADER 0x1A45DFA3 - -/* IDs in the HEADER master */ -#define EBML_ID_EBMLVERSION 0x4286 -#define EBML_ID_EBMLREADVERSION 0x42F7 -#define EBML_ID_EBMLMAXIDLENGTH 0x42F2 -#define EBML_ID_EBMLMAXSIZELENGTH 0x42F3 -#define EBML_ID_DOCTYPE 0x4282 -#define EBML_ID_DOCTYPEVERSION 0x4287 -#define EBML_ID_DOCTYPEREADVERSION 0x4285 - -/* general EBML types */ -#define EBML_ID_VOID 0xEC -#define EBML_ID_CRC32 0xBF - -/* - * Matroska element IDs, max. 32 bits - */ - -/* toplevel segment */ -#define MATROSKA_ID_SEGMENT 0x18538067 - -/* Matroska top-level master IDs */ -#define MATROSKA_ID_INFO 0x1549A966 -#define MATROSKA_ID_TRACKS 0x1654AE6B -#define MATROSKA_ID_CUES 0x1C53BB6B -#define MATROSKA_ID_TAGS 0x1254C367 -#define MATROSKA_ID_SEEKHEAD 0x114D9B74 -#define MATROSKA_ID_ATTACHMENTS 0x1941A469 -#define MATROSKA_ID_CLUSTER 0x1F43B675 -#define MATROSKA_ID_CHAPTERS 0x1043A770 - -/* IDs in the info master */ -#define MATROSKA_ID_TIMECODESCALE 0x2AD7B1 -#define MATROSKA_ID_DURATION 0x4489 -#define MATROSKA_ID_TITLE 0x7BA9 -#define MATROSKA_ID_WRITINGAPP 0x5741 -#define MATROSKA_ID_MUXINGAPP 0x4D80 -#define MATROSKA_ID_DATEUTC 0x4461 -#define MATROSKA_ID_SEGMENTUID 0x73A4 - -/* ID in the tracks master */ -#define MATROSKA_ID_TRACKENTRY 0xAE - -/* IDs in the trackentry master */ -#define MATROSKA_ID_TRACKNUMBER 0xD7 -#define MATROSKA_ID_TRACKUID 0x73C5 -#define MATROSKA_ID_TRACKTYPE 0x83 -#define MATROSKA_ID_TRACKAUDIO 0xE1 -#define MATROSKA_ID_TRACKVIDEO 0xE0 -#define MATROSKA_ID_CODECID 0x86 -#define MATROSKA_ID_CODECPRIVATE 0x63A2 -#define MATROSKA_ID_CODECNAME 0x258688 -#define MATROSKA_ID_CODECINFOURL 0x3B4040 -#define MATROSKA_ID_CODECDOWNLOADURL 0x26B240 -#define MATROSKA_ID_CODECDECODEALL 0xAA -#define MATROSKA_ID_TRACKNAME 0x536E -#define MATROSKA_ID_TRACKLANGUAGE 0x22B59C -#define MATROSKA_ID_TRACKFLAGENABLED 0xB9 -#define MATROSKA_ID_TRACKFLAGDEFAULT 0x88 -#define MATROSKA_ID_TRACKFLAGFORCED 0x55AA -#define MATROSKA_ID_TRACKFLAGLACING 0x9C -#define MATROSKA_ID_TRACKMINCACHE 0x6DE7 -#define MATROSKA_ID_TRACKMAXCACHE 0x6DF8 -#define MATROSKA_ID_TRACKDEFAULTDURATION 0x23E383 -#define MATROSKA_ID_TRACKCONTENTENCODINGS 0x6D80 -#define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 -#define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F -#define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE - -/* IDs in the trackvideo master */ -#define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 -#define MATROSKA_ID_VIDEODISPLAYWIDTH 0x54B0 -#define MATROSKA_ID_VIDEODISPLAYHEIGHT 0x54BA -#define MATROSKA_ID_VIDEOPIXELWIDTH 0xB0 -#define MATROSKA_ID_VIDEOPIXELHEIGHT 0xBA -#define MATROSKA_ID_VIDEOPIXELCROPB 0x54AA -#define MATROSKA_ID_VIDEOPIXELCROPT 0x54BB -#define MATROSKA_ID_VIDEOPIXELCROPL 0x54CC -#define MATROSKA_ID_VIDEOPIXELCROPR 0x54DD -#define MATROSKA_ID_VIDEODISPLAYUNIT 0x54B2 -#define MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A -#define MATROSKA_ID_VIDEOSTEREOMODE 0x53B9 -#define MATROSKA_ID_VIDEOASPECTRATIO 0x54B3 -#define MATROSKA_ID_VIDEOCOLORSPACE 0x2EB524 - -/* IDs in the trackaudio master */ -#define MATROSKA_ID_AUDIOSAMPLINGFREQ 0xB5 -#define MATROSKA_ID_AUDIOOUTSAMPLINGFREQ 0x78B5 - -#define MATROSKA_ID_AUDIOBITDEPTH 0x6264 -#define MATROSKA_ID_AUDIOCHANNELS 0x9F - -/* IDs in the content encoding master */ -#define MATROSKA_ID_ENCODINGORDER 0x5031 -#define MATROSKA_ID_ENCODINGSCOPE 0x5032 -#define MATROSKA_ID_ENCODINGTYPE 0x5033 -#define MATROSKA_ID_ENCODINGCOMPRESSION 0x5034 -#define MATROSKA_ID_ENCODINGCOMPALGO 0x4254 -#define MATROSKA_ID_ENCODINGCOMPSETTINGS 0x4255 - -/* ID in the cues master */ -#define MATROSKA_ID_POINTENTRY 0xBB - -/* IDs in the pointentry master */ -#define MATROSKA_ID_CUETIME 0xB3 -#define MATROSKA_ID_CUETRACKPOSITION 0xB7 - -/* IDs in the cuetrackposition master */ -#define MATROSKA_ID_CUETRACK 0xF7 -#define MATROSKA_ID_CUECLUSTERPOSITION 0xF1 -#define MATROSKA_ID_CUEBLOCKNUMBER 0x5378 - -/* IDs in the tags master */ -#define MATROSKA_ID_TAG 0x7373 -#define MATROSKA_ID_SIMPLETAG 0x67C8 -#define MATROSKA_ID_TAGNAME 0x45A3 -#define MATROSKA_ID_TAGSTRING 0x4487 -#define MATROSKA_ID_TAGLANG 0x447A -#define MATROSKA_ID_TAGDEFAULT 0x44B4 -#define MATROSKA_ID_TAGTARGETS 0x63C0 -#define MATROSKA_ID_TAGTARGETS_TYPE 0x63CA -#define MATROSKA_ID_TAGTARGETS_TYPEVALUE 0x68CA -#define MATROSKA_ID_TAGTARGETS_TRACKUID 0x63C5 -#define MATROSKA_ID_TAGTARGETS_CHAPTERUID 0x63C4 -#define MATROSKA_ID_TAGTARGETS_ATTACHUID 0x63C6 - -/* IDs in the seekhead master */ -#define MATROSKA_ID_SEEKENTRY 0x4DBB - -/* IDs in the seekpoint master */ -#define MATROSKA_ID_SEEKID 0x53AB -#define MATROSKA_ID_SEEKPOSITION 0x53AC - -/* IDs in the cluster master */ -#define MATROSKA_ID_CLUSTERTIMECODE 0xE7 -#define MATROSKA_ID_CLUSTERPOSITION 0xA7 -#define MATROSKA_ID_CLUSTERPREVSIZE 0xAB -#define MATROSKA_ID_BLOCKGROUP 0xA0 -#define MATROSKA_ID_SIMPLEBLOCK 0xA3 - -/* IDs in the blockgroup master */ -#define MATROSKA_ID_BLOCK 0xA1 -#define MATROSKA_ID_BLOCKDURATION 0x9B -#define MATROSKA_ID_BLOCKREFERENCE 0xFB - -/* IDs in the attachments master */ -#define MATROSKA_ID_ATTACHEDFILE 0x61A7 -#define MATROSKA_ID_FILEDESC 0x467E -#define MATROSKA_ID_FILENAME 0x466E -#define MATROSKA_ID_FILEMIMETYPE 0x4660 -#define MATROSKA_ID_FILEDATA 0x465C -#define MATROSKA_ID_FILEUID 0x46AE - -/* IDs in the chapters master */ -#define MATROSKA_ID_EDITIONENTRY 0x45B9 -#define MATROSKA_ID_CHAPTERATOM 0xB6 -#define MATROSKA_ID_CHAPTERTIMESTART 0x91 -#define MATROSKA_ID_CHAPTERTIMEEND 0x92 -#define MATROSKA_ID_CHAPTERDISPLAY 0x80 -#define MATROSKA_ID_CHAPSTRING 0x85 -#define MATROSKA_ID_CHAPLANG 0x437C -#define MATROSKA_ID_EDITIONUID 0x45BC -#define MATROSKA_ID_EDITIONFLAGHIDDEN 0x45BD -#define MATROSKA_ID_EDITIONFLAGDEFAULT 0x45DB -#define MATROSKA_ID_EDITIONFLAGORDERED 0x45DD -#define MATROSKA_ID_CHAPTERUID 0x73C4 -#define MATROSKA_ID_CHAPTERFLAGHIDDEN 0x98 -#define MATROSKA_ID_CHAPTERFLAGENABLED 0x4598 -#define MATROSKA_ID_CHAPTERPHYSEQUIV 0x63C3 - -typedef enum { - MATROSKA_TRACK_TYPE_NONE = 0x0, - MATROSKA_TRACK_TYPE_VIDEO = 0x1, - MATROSKA_TRACK_TYPE_AUDIO = 0x2, - MATROSKA_TRACK_TYPE_COMPLEX = 0x3, - MATROSKA_TRACK_TYPE_LOGO = 0x10, - MATROSKA_TRACK_TYPE_SUBTITLE = 0x11, - MATROSKA_TRACK_TYPE_CONTROL = 0x20, -} MatroskaTrackType; - -typedef enum { - MATROSKA_TRACK_ENCODING_COMP_ZLIB = 0, - MATROSKA_TRACK_ENCODING_COMP_BZLIB = 1, - MATROSKA_TRACK_ENCODING_COMP_LZO = 2, - MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP = 3, -} MatroskaTrackEncodingCompAlgo; - -/* - * Matroska Codec IDs, strings - */ - -typedef struct CodecTags{ - char str[20]; - enum CodecID id; -}CodecTags; - -typedef struct CodecMime{ - char str[32]; - enum CodecID id; -}CodecMime; - -/* max. depth in the EBML tree structure */ -#define EBML_MAX_DEPTH 16 - -extern const CodecTags ff_mkv_codec_tags[]; -extern const CodecMime ff_mkv_mime_tags[]; -extern const AVMetadataConv ff_mkv_metadata_conv[]; - -#endif /* AVFORMAT_MATROSKA_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/matroskadec.c b/tizen/distrib/ffmpeg/libavformat/matroskadec.c deleted file mode 100644 index e254a31..0000000 --- a/tizen/distrib/ffmpeg/libavformat/matroskadec.c +++ /dev/null @@ -1,1891 +0,0 @@ -/* - * Matroska file demuxer - * Copyright (c) 2003-2008 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Matroska file demuxer - * by Ronald Bultje - * with a little help from Moritz Bunkus - * totally reworked by Aurelien Jacobs - * Specs available on the Matroska project page: http://www.matroska.org/. - */ - -#include -#include "avformat.h" -#include "internal.h" -/* For ff_codec_get_id(). */ -#include "riff.h" -#include "isom.h" -#include "rm.h" -#include "matroska.h" -#include "libavcodec/mpeg4audio.h" -#include "libavutil/intfloat_readwrite.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/avstring.h" -#include "libavutil/lzo.h" -#if CONFIG_ZLIB -#include -#endif -#if CONFIG_BZLIB -#include -#endif - -typedef enum { - EBML_NONE, - EBML_UINT, - EBML_FLOAT, - EBML_STR, - EBML_UTF8, - EBML_BIN, - EBML_NEST, - EBML_PASS, - EBML_STOP, -} EbmlType; - -typedef const struct EbmlSyntax { - uint32_t id; - EbmlType type; - int list_elem_size; - int data_offset; - union { - uint64_t u; - double f; - const char *s; - const struct EbmlSyntax *n; - } def; -} EbmlSyntax; - -typedef struct { - int nb_elem; - void *elem; -} EbmlList; - -typedef struct { - int size; - uint8_t *data; - int64_t pos; -} EbmlBin; - -typedef struct { - uint64_t version; - uint64_t max_size; - uint64_t id_length; - char *doctype; - uint64_t doctype_version; -} Ebml; - -typedef struct { - uint64_t algo; - EbmlBin settings; -} MatroskaTrackCompression; - -typedef struct { - uint64_t scope; - uint64_t type; - MatroskaTrackCompression compression; -} MatroskaTrackEncoding; - -typedef struct { - double frame_rate; - uint64_t display_width; - uint64_t display_height; - uint64_t pixel_width; - uint64_t pixel_height; - uint64_t fourcc; -} MatroskaTrackVideo; - -typedef struct { - double samplerate; - double out_samplerate; - uint64_t bitdepth; - uint64_t channels; - - /* real audio header (extracted from extradata) */ - int coded_framesize; - int sub_packet_h; - int frame_size; - int sub_packet_size; - int sub_packet_cnt; - int pkt_cnt; - uint8_t *buf; -} MatroskaTrackAudio; - -typedef struct { - uint64_t num; - uint64_t uid; - uint64_t type; - char *name; - char *codec_id; - EbmlBin codec_priv; - char *language; - double time_scale; - uint64_t default_duration; - uint64_t flag_default; - MatroskaTrackVideo video; - MatroskaTrackAudio audio; - EbmlList encodings; - - AVStream *stream; - int64_t end_timecode; - int ms_compat; -} MatroskaTrack; - -typedef struct { - uint64_t uid; - char *filename; - char *mime; - EbmlBin bin; - - AVStream *stream; -} MatroskaAttachement; - -typedef struct { - uint64_t start; - uint64_t end; - uint64_t uid; - char *title; - - AVChapter *chapter; -} MatroskaChapter; - -typedef struct { - uint64_t track; - uint64_t pos; -} MatroskaIndexPos; - -typedef struct { - uint64_t time; - EbmlList pos; -} MatroskaIndex; - -typedef struct { - char *name; - char *string; - char *lang; - uint64_t def; - EbmlList sub; -} MatroskaTag; - -typedef struct { - char *type; - uint64_t typevalue; - uint64_t trackuid; - uint64_t chapteruid; - uint64_t attachuid; -} MatroskaTagTarget; - -typedef struct { - MatroskaTagTarget target; - EbmlList tag; -} MatroskaTags; - -typedef struct { - uint64_t id; - uint64_t pos; -} MatroskaSeekhead; - -typedef struct { - uint64_t start; - uint64_t length; -} MatroskaLevel; - -typedef struct { - AVFormatContext *ctx; - - /* EBML stuff */ - int num_levels; - MatroskaLevel levels[EBML_MAX_DEPTH]; - int level_up; - - uint64_t time_scale; - double duration; - char *title; - EbmlList tracks; - EbmlList attachments; - EbmlList chapters; - EbmlList index; - EbmlList tags; - EbmlList seekhead; - - /* byte position of the segment inside the stream */ - int64_t segment_start; - - /* the packet queue */ - AVPacket **packets; - int num_packets; - AVPacket *prev_pkt; - - int done; - int has_cluster_id; - - /* What to skip before effectively reading a packet. */ - int skip_to_keyframe; - uint64_t skip_to_timecode; -} MatroskaDemuxContext; - -typedef struct { - uint64_t duration; - int64_t reference; - uint64_t non_simple; - EbmlBin bin; -} MatroskaBlock; - -typedef struct { - uint64_t timecode; - EbmlList blocks; -} MatroskaCluster; - -static EbmlSyntax ebml_header[] = { - { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u=EBML_VERSION} }, - { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.u=8} }, - { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml,id_length), {.u=4} }, - { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml,doctype), {.s="(none)"} }, - { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml,doctype_version), {.u=1} }, - { EBML_ID_EBMLVERSION, EBML_NONE }, - { EBML_ID_DOCTYPEVERSION, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax ebml_syntax[] = { - { EBML_ID_HEADER, EBML_NEST, 0, 0, {.n=ebml_header} }, - { 0 } -}; - -static EbmlSyntax matroska_info[] = { - { MATROSKA_ID_TIMECODESCALE, EBML_UINT, 0, offsetof(MatroskaDemuxContext,time_scale), {.u=1000000} }, - { MATROSKA_ID_DURATION, EBML_FLOAT, 0, offsetof(MatroskaDemuxContext,duration) }, - { MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext,title) }, - { MATROSKA_ID_WRITINGAPP, EBML_NONE }, - { MATROSKA_ID_MUXINGAPP, EBML_NONE }, - { MATROSKA_ID_DATEUTC, EBML_NONE }, - { MATROSKA_ID_SEGMENTUID, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_track_video[] = { - { MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT,0, offsetof(MatroskaTrackVideo,frame_rate) }, - { MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_width) }, - { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_height) }, - { MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_width) }, - { MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) }, - { MATROSKA_ID_VIDEOCOLORSPACE, EBML_UINT, 0, offsetof(MatroskaTrackVideo,fourcc) }, - { MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE }, - { MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE }, - { MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE }, - { MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE }, - { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE }, - { MATROSKA_ID_VIDEOFLAGINTERLACED,EBML_NONE }, - { MATROSKA_ID_VIDEOSTEREOMODE, EBML_NONE }, - { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_track_audio[] = { - { MATROSKA_ID_AUDIOSAMPLINGFREQ, EBML_FLOAT,0, offsetof(MatroskaTrackAudio,samplerate), {.f=8000.0} }, - { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ,EBML_FLOAT,0,offsetof(MatroskaTrackAudio,out_samplerate) }, - { MATROSKA_ID_AUDIOBITDEPTH, EBML_UINT, 0, offsetof(MatroskaTrackAudio,bitdepth) }, - { MATROSKA_ID_AUDIOCHANNELS, EBML_UINT, 0, offsetof(MatroskaTrackAudio,channels), {.u=1} }, - { 0 } -}; - -static EbmlSyntax matroska_track_encoding_compression[] = { - { MATROSKA_ID_ENCODINGCOMPALGO, EBML_UINT, 0, offsetof(MatroskaTrackCompression,algo), {.u=0} }, - { MATROSKA_ID_ENCODINGCOMPSETTINGS,EBML_BIN, 0, offsetof(MatroskaTrackCompression,settings) }, - { 0 } -}; - -static EbmlSyntax matroska_track_encoding[] = { - { MATROSKA_ID_ENCODINGSCOPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,scope), {.u=1} }, - { MATROSKA_ID_ENCODINGTYPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,type), {.u=0} }, - { MATROSKA_ID_ENCODINGCOMPRESSION,EBML_NEST, 0, offsetof(MatroskaTrackEncoding,compression), {.n=matroska_track_encoding_compression} }, - { MATROSKA_ID_ENCODINGORDER, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_track_encodings[] = { - { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack,encodings), {.n=matroska_track_encoding} }, - { 0 } -}; - -static EbmlSyntax matroska_track[] = { - { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, offsetof(MatroskaTrack,num) }, - { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, offsetof(MatroskaTrack,name) }, - { MATROSKA_ID_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTrack,uid) }, - { MATROSKA_ID_TRACKTYPE, EBML_UINT, 0, offsetof(MatroskaTrack,type) }, - { MATROSKA_ID_CODECID, EBML_STR, 0, offsetof(MatroskaTrack,codec_id) }, - { MATROSKA_ID_CODECPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrack,codec_priv) }, - { MATROSKA_ID_TRACKLANGUAGE, EBML_UTF8, 0, offsetof(MatroskaTrack,language), {.s="eng"} }, - { MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, offsetof(MatroskaTrack,default_duration) }, - { MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT,0, offsetof(MatroskaTrack,time_scale), {.f=1.0} }, - { MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTrack,flag_default), {.u=1} }, - { MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} }, - { MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} }, - { MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} }, - { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, - { MATROSKA_ID_TRACKFLAGFORCED, EBML_NONE }, - { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, - { MATROSKA_ID_CODECNAME, EBML_NONE }, - { MATROSKA_ID_CODECDECODEALL, EBML_NONE }, - { MATROSKA_ID_CODECINFOURL, EBML_NONE }, - { MATROSKA_ID_CODECDOWNLOADURL, EBML_NONE }, - { MATROSKA_ID_TRACKMINCACHE, EBML_NONE }, - { MATROSKA_ID_TRACKMAXCACHE, EBML_NONE }, - { MATROSKA_ID_TRACKMAXBLKADDID, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_tracks[] = { - { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext,tracks), {.n=matroska_track} }, - { 0 } -}; - -static EbmlSyntax matroska_attachment[] = { - { MATROSKA_ID_FILEUID, EBML_UINT, 0, offsetof(MatroskaAttachement,uid) }, - { MATROSKA_ID_FILENAME, EBML_UTF8, 0, offsetof(MatroskaAttachement,filename) }, - { MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, offsetof(MatroskaAttachement,mime) }, - { MATROSKA_ID_FILEDATA, EBML_BIN, 0, offsetof(MatroskaAttachement,bin) }, - { MATROSKA_ID_FILEDESC, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_attachments[] = { - { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachement), offsetof(MatroskaDemuxContext,attachments), {.n=matroska_attachment} }, - { 0 } -}; - -static EbmlSyntax matroska_chapter_display[] = { - { MATROSKA_ID_CHAPSTRING, EBML_UTF8, 0, offsetof(MatroskaChapter,title) }, - { MATROSKA_ID_CHAPLANG, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_chapter_entry[] = { - { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, offsetof(MatroskaChapter,start), {.u=AV_NOPTS_VALUE} }, - { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, offsetof(MatroskaChapter,end), {.u=AV_NOPTS_VALUE} }, - { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaChapter,uid) }, - { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, {.n=matroska_chapter_display} }, - { MATROSKA_ID_CHAPTERFLAGHIDDEN, EBML_NONE }, - { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE }, - { MATROSKA_ID_CHAPTERPHYSEQUIV, EBML_NONE }, - { MATROSKA_ID_CHAPTERATOM, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_chapter[] = { - { MATROSKA_ID_CHAPTERATOM, EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext,chapters), {.n=matroska_chapter_entry} }, - { MATROSKA_ID_EDITIONUID, EBML_NONE }, - { MATROSKA_ID_EDITIONFLAGHIDDEN, EBML_NONE }, - { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE }, - { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_chapters[] = { - { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, {.n=matroska_chapter} }, - { 0 } -}; - -static EbmlSyntax matroska_index_pos[] = { - { MATROSKA_ID_CUETRACK, EBML_UINT, 0, offsetof(MatroskaIndexPos,track) }, - { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos,pos) }, - { MATROSKA_ID_CUEBLOCKNUMBER, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_index_entry[] = { - { MATROSKA_ID_CUETIME, EBML_UINT, 0, offsetof(MatroskaIndex,time) }, - { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex,pos), {.n=matroska_index_pos} }, - { 0 } -}; - -static EbmlSyntax matroska_index[] = { - { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext,index), {.n=matroska_index_entry} }, - { 0 } -}; - -static EbmlSyntax matroska_simpletag[] = { - { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag,name) }, - { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag,string) }, - { MATROSKA_ID_TAGLANG, EBML_STR, 0, offsetof(MatroskaTag,lang), {.s="und"} }, - { MATROSKA_ID_TAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTag,def) }, - { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag,sub), {.n=matroska_simpletag} }, - { 0 } -}; - -static EbmlSyntax matroska_tagtargets[] = { - { MATROSKA_ID_TAGTARGETS_TYPE, EBML_STR, 0, offsetof(MatroskaTagTarget,type) }, - { MATROSKA_ID_TAGTARGETS_TYPEVALUE, EBML_UINT, 0, offsetof(MatroskaTagTarget,typevalue), {.u=50} }, - { MATROSKA_ID_TAGTARGETS_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTagTarget,trackuid) }, - { MATROSKA_ID_TAGTARGETS_CHAPTERUID,EBML_UINT, 0, offsetof(MatroskaTagTarget,chapteruid) }, - { MATROSKA_ID_TAGTARGETS_ATTACHUID, EBML_UINT, 0, offsetof(MatroskaTagTarget,attachuid) }, - { 0 } -}; - -static EbmlSyntax matroska_tag[] = { - { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTags,tag), {.n=matroska_simpletag} }, - { MATROSKA_ID_TAGTARGETS, EBML_NEST, 0, offsetof(MatroskaTags,target), {.n=matroska_tagtargets} }, - { 0 } -}; - -static EbmlSyntax matroska_tags[] = { - { MATROSKA_ID_TAG, EBML_NEST, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext,tags), {.n=matroska_tag} }, - { 0 } -}; - -static EbmlSyntax matroska_seekhead_entry[] = { - { MATROSKA_ID_SEEKID, EBML_UINT, 0, offsetof(MatroskaSeekhead,id) }, - { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead,pos), {.u=-1} }, - { 0 } -}; - -static EbmlSyntax matroska_seekhead[] = { - { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext,seekhead), {.n=matroska_seekhead_entry} }, - { 0 } -}; - -static EbmlSyntax matroska_segment[] = { - { MATROSKA_ID_INFO, EBML_NEST, 0, 0, {.n=matroska_info } }, - { MATROSKA_ID_TRACKS, EBML_NEST, 0, 0, {.n=matroska_tracks } }, - { MATROSKA_ID_ATTACHMENTS, EBML_NEST, 0, 0, {.n=matroska_attachments} }, - { MATROSKA_ID_CHAPTERS, EBML_NEST, 0, 0, {.n=matroska_chapters } }, - { MATROSKA_ID_CUES, EBML_NEST, 0, 0, {.n=matroska_index } }, - { MATROSKA_ID_TAGS, EBML_NEST, 0, 0, {.n=matroska_tags } }, - { MATROSKA_ID_SEEKHEAD, EBML_NEST, 0, 0, {.n=matroska_seekhead } }, - { MATROSKA_ID_CLUSTER, EBML_STOP, 0, offsetof(MatroskaDemuxContext,has_cluster_id) }, - { 0 } -}; - -static EbmlSyntax matroska_segments[] = { - { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, {.n=matroska_segment } }, - { 0 } -}; - -static EbmlSyntax matroska_blockgroup[] = { - { MATROSKA_ID_BLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, - { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, - { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration), {.u=AV_NOPTS_VALUE} }, - { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) }, - { 1, EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} }, - { 0 } -}; - -static EbmlSyntax matroska_cluster[] = { - { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) }, - { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, - { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, - { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE }, - { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_clusters[] = { - { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} }, - { MATROSKA_ID_INFO, EBML_NONE }, - { MATROSKA_ID_CUES, EBML_NONE }, - { MATROSKA_ID_TAGS, EBML_NONE }, - { MATROSKA_ID_SEEKHEAD, EBML_NONE }, - { 0 } -}; - -static const char *matroska_doctypes[] = { "matroska", "webm" }; - -/* - * Return: Whether we reached the end of a level in the hierarchy or not. - */ -static int ebml_level_end(MatroskaDemuxContext *matroska) -{ - ByteIOContext *pb = matroska->ctx->pb; - int64_t pos = url_ftell(pb); - - if (matroska->num_levels > 0) { - MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1]; - if (pos - level->start >= level->length) { - matroska->num_levels--; - return 1; - } - } - return 0; -} - -/* - * Read: an "EBML number", which is defined as a variable-length - * array of bytes. The first byte indicates the length by giving a - * number of 0-bits followed by a one. The position of the first - * "one" bit inside the first byte indicates the length of this - * number. - * Returns: number of bytes read, < 0 on error - */ -static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb, - int max_size, uint64_t *number) -{ - int len_mask = 0x80, read = 1, n = 1; - int64_t total = 0; - - /* The first byte tells us the length in bytes - get_byte() can normally - * return 0, but since that's not a valid first ebmlID byte, we can - * use it safely here to catch EOS. */ - if (!(total = get_byte(pb))) { - /* we might encounter EOS here */ - if (!url_feof(pb)) { - int64_t pos = url_ftell(pb); - av_log(matroska->ctx, AV_LOG_ERROR, - "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", - pos, pos); - } - return AVERROR(EIO); /* EOS or actual I/O error */ - } - - /* get the length of the EBML number */ - while (read <= max_size && !(total & len_mask)) { - read++; - len_mask >>= 1; - } - if (read > max_size) { - int64_t pos = url_ftell(pb) - 1; - av_log(matroska->ctx, AV_LOG_ERROR, - "Invalid EBML number size tag 0x%02x at pos %"PRIu64" (0x%"PRIx64")\n", - (uint8_t) total, pos, pos); - return AVERROR_INVALIDDATA; - } - - /* read out length */ - total &= ~len_mask; - while (n++ < read) - total = (total << 8) | get_byte(pb); - - *number = total; - - return read; -} - -/* - * Read the next element as an unsigned int. - * 0 is success, < 0 is failure. - */ -static int ebml_read_uint(ByteIOContext *pb, int size, uint64_t *num) -{ - int n = 0; - - if (size < 1 || size > 8) - return AVERROR_INVALIDDATA; - - /* big-endian ordering; build up number */ - *num = 0; - while (n++ < size) - *num = (*num << 8) | get_byte(pb); - - return 0; -} - -/* - * Read the next element as a float. - * 0 is success, < 0 is failure. - */ -static int ebml_read_float(ByteIOContext *pb, int size, double *num) -{ - if (size == 4) { - *num= av_int2flt(get_be32(pb)); - } else if(size==8){ - *num= av_int2dbl(get_be64(pb)); - } else - return AVERROR_INVALIDDATA; - - return 0; -} - -/* - * Read the next element as an ASCII string. - * 0 is success, < 0 is failure. - */ -static int ebml_read_ascii(ByteIOContext *pb, int size, char **str) -{ - av_free(*str); - /* EBML strings are usually not 0-terminated, so we allocate one - * byte more, read the string and NULL-terminate it ourselves. */ - if (!(*str = av_malloc(size + 1))) - return AVERROR(ENOMEM); - if (get_buffer(pb, (uint8_t *) *str, size) != size) { - av_free(*str); - return AVERROR(EIO); - } - (*str)[size] = '\0'; - - return 0; -} - -/* - * Read the next element as binary data. - * 0 is success, < 0 is failure. - */ -static int ebml_read_binary(ByteIOContext *pb, int length, EbmlBin *bin) -{ - av_free(bin->data); - if (!(bin->data = av_malloc(length))) - return AVERROR(ENOMEM); - - bin->size = length; - bin->pos = url_ftell(pb); - if (get_buffer(pb, bin->data, length) != length) - return AVERROR(EIO); - - return 0; -} - -/* - * Read the next element, but only the header. The contents - * are supposed to be sub-elements which can be read separately. - * 0 is success, < 0 is failure. - */ -static int ebml_read_master(MatroskaDemuxContext *matroska, int length) -{ - ByteIOContext *pb = matroska->ctx->pb; - MatroskaLevel *level; - - if (matroska->num_levels >= EBML_MAX_DEPTH) { - av_log(matroska->ctx, AV_LOG_ERROR, - "File moves beyond max. allowed depth (%d)\n", EBML_MAX_DEPTH); - return AVERROR(ENOSYS); - } - - level = &matroska->levels[matroska->num_levels++]; - level->start = url_ftell(pb); - level->length = length; - - return 0; -} - -/* - * Read signed/unsigned "EBML" numbers. - * Return: number of bytes processed, < 0 on error - */ -static int matroska_ebmlnum_uint(MatroskaDemuxContext *matroska, - uint8_t *data, uint32_t size, uint64_t *num) -{ - ByteIOContext pb; - init_put_byte(&pb, data, size, 0, NULL, NULL, NULL, NULL); - return ebml_read_num(matroska, &pb, 8, num); -} - -/* - * Same as above, but signed. - */ -static int matroska_ebmlnum_sint(MatroskaDemuxContext *matroska, - uint8_t *data, uint32_t size, int64_t *num) -{ - uint64_t unum; - int res; - - /* read as unsigned number first */ - if ((res = matroska_ebmlnum_uint(matroska, data, size, &unum)) < 0) - return res; - - /* make signed (weird way) */ - *num = unum - ((1LL << (7*res - 1)) - 1); - - return res; -} - -static int ebml_parse_elem(MatroskaDemuxContext *matroska, - EbmlSyntax *syntax, void *data); - -static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, - uint32_t id, void *data) -{ - int i; - for (i=0; syntax[i].id; i++) - if (id == syntax[i].id) - break; - if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32) - av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id); - return ebml_parse_elem(matroska, &syntax[i], data); -} - -static int ebml_parse(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, - void *data) -{ - uint64_t id; - int res = ebml_read_num(matroska, matroska->ctx->pb, 4, &id); - id |= 1 << 7*res; - return res < 0 ? res : ebml_parse_id(matroska, syntax, id, data); -} - -static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, - void *data) -{ - int i, res = 0; - - for (i=0; syntax[i].id; i++) - switch (syntax[i].type) { - case EBML_UINT: - *(uint64_t *)((char *)data+syntax[i].data_offset) = syntax[i].def.u; - break; - case EBML_FLOAT: - *(double *)((char *)data+syntax[i].data_offset) = syntax[i].def.f; - break; - case EBML_STR: - case EBML_UTF8: - *(char **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s); - break; - } - - while (!res && !ebml_level_end(matroska)) - res = ebml_parse(matroska, syntax, data); - - return res; -} - -static int ebml_parse_elem(MatroskaDemuxContext *matroska, - EbmlSyntax *syntax, void *data) -{ - ByteIOContext *pb = matroska->ctx->pb; - uint32_t id = syntax->id; - uint64_t length; - int res; - - data = (char *)data + syntax->data_offset; - if (syntax->list_elem_size) { - EbmlList *list = data; - list->elem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size); - data = (char*)list->elem + list->nb_elem*syntax->list_elem_size; - memset(data, 0, syntax->list_elem_size); - list->nb_elem++; - } - - if (syntax->type != EBML_PASS && syntax->type != EBML_STOP) - if ((res = ebml_read_num(matroska, pb, 8, &length)) < 0) - return res; - - switch (syntax->type) { - case EBML_UINT: res = ebml_read_uint (pb, length, data); break; - case EBML_FLOAT: res = ebml_read_float (pb, length, data); break; - case EBML_STR: - case EBML_UTF8: res = ebml_read_ascii (pb, length, data); break; - case EBML_BIN: res = ebml_read_binary(pb, length, data); break; - case EBML_NEST: if ((res=ebml_read_master(matroska, length)) < 0) - return res; - if (id == MATROSKA_ID_SEGMENT) - matroska->segment_start = url_ftell(matroska->ctx->pb); - return ebml_parse_nest(matroska, syntax->def.n, data); - case EBML_PASS: return ebml_parse_id(matroska, syntax->def.n, id, data); - case EBML_STOP: *(int *)data = 1; return 1; - default: return url_fseek(pb,length,SEEK_CUR)<0 ? AVERROR(EIO) : 0; - } - if (res == AVERROR_INVALIDDATA) - av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n"); - else if (res == AVERROR(EIO)) - av_log(matroska->ctx, AV_LOG_ERROR, "Read error\n"); - return res; -} - -static void ebml_free(EbmlSyntax *syntax, void *data) -{ - int i, j; - for (i=0; syntax[i].id; i++) { - void *data_off = (char *)data + syntax[i].data_offset; - switch (syntax[i].type) { - case EBML_STR: - case EBML_UTF8: av_freep(data_off); break; - case EBML_BIN: av_freep(&((EbmlBin *)data_off)->data); break; - case EBML_NEST: - if (syntax[i].list_elem_size) { - EbmlList *list = data_off; - char *ptr = list->elem; - for (j=0; jnb_elem; j++, ptr+=syntax[i].list_elem_size) - ebml_free(syntax[i].def.n, ptr); - av_free(list->elem); - } else - ebml_free(syntax[i].def.n, data_off); - default: break; - } - } -} - - -/* - * Autodetecting... - */ -static int matroska_probe(AVProbeData *p) -{ - uint64_t total = 0; - int len_mask = 0x80, size = 1, n = 1, i; - - /* EBML header? */ - if (AV_RB32(p->buf) != EBML_ID_HEADER) - return 0; - - /* length of header */ - total = p->buf[4]; - while (size <= 8 && !(total & len_mask)) { - size++; - len_mask >>= 1; - } - if (size > 8) - return 0; - total &= (len_mask - 1); - while (n < size) - total = (total << 8) | p->buf[4 + n++]; - - /* Does the probe data contain the whole header? */ - if (p->buf_size < 4 + size + total) - return 0; - - /* The header should contain a known document type. For now, - * we don't parse the whole header but simply check for the - * availability of that array of characters inside the header. - * Not fully fool-proof, but good enough. */ - for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) { - int probelen = strlen(matroska_doctypes[i]); - for (n = 4+size; n <= 4+size+total-probelen; n++) - if (!memcmp(p->buf+n, matroska_doctypes[i], probelen)) - return AVPROBE_SCORE_MAX; - } - - // probably valid EBML header but no recognized doctype - return AVPROBE_SCORE_MAX/2; -} - -static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska, - int num) -{ - MatroskaTrack *tracks = matroska->tracks.elem; - int i; - - for (i=0; i < matroska->tracks.nb_elem; i++) - if (tracks[i].num == num) - return &tracks[i]; - - av_log(matroska->ctx, AV_LOG_ERROR, "Invalid track number %d\n", num); - return NULL; -} - -static int matroska_decode_buffer(uint8_t** buf, int* buf_size, - MatroskaTrack *track) -{ - MatroskaTrackEncoding *encodings = track->encodings.elem; - uint8_t* data = *buf; - int isize = *buf_size; - uint8_t* pkt_data = NULL; - int pkt_size = isize; - int result = 0; - int olen; - - switch (encodings[0].compression.algo) { - case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: - return encodings[0].compression.settings.size; - case MATROSKA_TRACK_ENCODING_COMP_LZO: - do { - olen = pkt_size *= 3; - pkt_data = av_realloc(pkt_data, pkt_size+AV_LZO_OUTPUT_PADDING); - result = av_lzo1x_decode(pkt_data, &olen, data, &isize); - } while (result==AV_LZO_OUTPUT_FULL && pkt_size<10000000); - if (result) - goto failed; - pkt_size -= olen; - break; -#if CONFIG_ZLIB - case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { - z_stream zstream = {0}; - if (inflateInit(&zstream) != Z_OK) - return -1; - zstream.next_in = data; - zstream.avail_in = isize; - do { - pkt_size *= 3; - pkt_data = av_realloc(pkt_data, pkt_size); - zstream.avail_out = pkt_size - zstream.total_out; - zstream.next_out = pkt_data + zstream.total_out; - result = inflate(&zstream, Z_NO_FLUSH); - } while (result==Z_OK && pkt_size<10000000); - pkt_size = zstream.total_out; - inflateEnd(&zstream); - if (result != Z_STREAM_END) - goto failed; - break; - } -#endif -#if CONFIG_BZLIB - case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { - bz_stream bzstream = {0}; - if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) - return -1; - bzstream.next_in = data; - bzstream.avail_in = isize; - do { - pkt_size *= 3; - pkt_data = av_realloc(pkt_data, pkt_size); - bzstream.avail_out = pkt_size - bzstream.total_out_lo32; - bzstream.next_out = pkt_data + bzstream.total_out_lo32; - result = BZ2_bzDecompress(&bzstream); - } while (result==BZ_OK && pkt_size<10000000); - pkt_size = bzstream.total_out_lo32; - BZ2_bzDecompressEnd(&bzstream); - if (result != BZ_STREAM_END) - goto failed; - break; - } -#endif - default: - return -1; - } - - *buf = pkt_data; - *buf_size = pkt_size; - return 0; - failed: - av_free(pkt_data); - return -1; -} - -static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska, - AVPacket *pkt, uint64_t display_duration) -{ - char *line, *layer, *ptr = pkt->data, *end = ptr+pkt->size; - for (; *ptr!=',' && ptrpts + display_duration; - int sc = matroska->time_scale * pkt->pts / 10000000; - int ec = matroska->time_scale * end_pts / 10000000; - int sh, sm, ss, eh, em, es, len; - sh = sc/360000; sc -= 360000*sh; - sm = sc/ 6000; sc -= 6000*sm; - ss = sc/ 100; sc -= 100*ss; - eh = ec/360000; ec -= 360000*eh; - em = ec/ 6000; ec -= 6000*em; - es = ec/ 100; ec -= 100*es; - *ptr++ = '\0'; - len = 50 + end-ptr + FF_INPUT_BUFFER_PADDING_SIZE; - if (!(line = av_malloc(len))) - return; - snprintf(line,len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n", - layer, sh, sm, ss, sc, eh, em, es, ec, ptr); - av_free(pkt->data); - pkt->data = line; - pkt->size = strlen(line); - } -} - -static void matroska_merge_packets(AVPacket *out, AVPacket *in) -{ - out->data = av_realloc(out->data, out->size+in->size); - memcpy(out->data+out->size, in->data, in->size); - out->size += in->size; - av_destruct_packet(in); - av_free(in); -} - -static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, - AVMetadata **metadata, char *prefix) -{ - MatroskaTag *tags = list->elem; - char key[1024]; - int i; - - for (i=0; i < list->nb_elem; i++) { - const char *lang = strcmp(tags[i].lang, "und") ? tags[i].lang : NULL; - if (prefix) snprintf(key, sizeof(key), "%s/%s", prefix, tags[i].name); - else av_strlcpy(key, tags[i].name, sizeof(key)); - if (tags[i].def || !lang) { - av_metadata_set2(metadata, key, tags[i].string, 0); - if (tags[i].sub.nb_elem) - matroska_convert_tag(s, &tags[i].sub, metadata, key); - } - if (lang) { - av_strlcat(key, "-", sizeof(key)); - av_strlcat(key, lang, sizeof(key)); - av_metadata_set2(metadata, key, tags[i].string, 0); - if (tags[i].sub.nb_elem) - matroska_convert_tag(s, &tags[i].sub, metadata, key); - } - } -} - -static void matroska_convert_tags(AVFormatContext *s) -{ - MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTags *tags = matroska->tags.elem; - int i, j; - - for (i=0; i < matroska->tags.nb_elem; i++) { - if (tags[i].target.attachuid) { - MatroskaAttachement *attachment = matroska->attachments.elem; - for (j=0; jattachments.nb_elem; j++) - if (attachment[j].uid == tags[i].target.attachuid) - matroska_convert_tag(s, &tags[i].tag, - &attachment[j].stream->metadata, NULL); - } else if (tags[i].target.chapteruid) { - MatroskaChapter *chapter = matroska->chapters.elem; - for (j=0; jchapters.nb_elem; j++) - if (chapter[j].uid == tags[i].target.chapteruid) - matroska_convert_tag(s, &tags[i].tag, - &chapter[j].chapter->metadata, NULL); - } else if (tags[i].target.trackuid) { - MatroskaTrack *track = matroska->tracks.elem; - for (j=0; jtracks.nb_elem; j++) - if (track[j].uid == tags[i].target.trackuid) - matroska_convert_tag(s, &tags[i].tag, - &track[j].stream->metadata, NULL); - } else { - matroska_convert_tag(s, &tags[i].tag, &s->metadata, - tags[i].target.type); - } - } -} - -static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) -{ - EbmlList *seekhead_list = &matroska->seekhead; - MatroskaSeekhead *seekhead = seekhead_list->elem; - uint32_t level_up = matroska->level_up; - int64_t before_pos = url_ftell(matroska->ctx->pb); - MatroskaLevel level; - int i; - - for (i=0; inb_elem; i++) { - int64_t offset = seekhead[i].pos + matroska->segment_start; - - if (seekhead[i].pos <= before_pos - || seekhead[i].id == MATROSKA_ID_SEEKHEAD - || seekhead[i].id == MATROSKA_ID_CLUSTER) - continue; - - /* seek */ - if (url_fseek(matroska->ctx->pb, offset, SEEK_SET) != offset) - continue; - - /* We don't want to lose our seekhead level, so we add - * a dummy. This is a crude hack. */ - if (matroska->num_levels == EBML_MAX_DEPTH) { - av_log(matroska->ctx, AV_LOG_INFO, - "Max EBML element depth (%d) reached, " - "cannot parse further.\n", EBML_MAX_DEPTH); - break; - } - - level.start = 0; - level.length = (uint64_t)-1; - matroska->levels[matroska->num_levels] = level; - matroska->num_levels++; - - ebml_parse(matroska, matroska_segment, matroska); - - /* remove dummy level */ - while (matroska->num_levels) { - uint64_t length = matroska->levels[--matroska->num_levels].length; - if (length == (uint64_t)-1) - break; - } - } - - /* seek back */ - url_fseek(matroska->ctx->pb, before_pos, SEEK_SET); - matroska->level_up = level_up; -} - -static int matroska_aac_profile(char *codec_id) -{ - static const char * const aac_profiles[] = { "MAIN", "LC", "SSR" }; - int profile; - - for (profile=0; profilepriv_data; - EbmlList *attachements_list = &matroska->attachments; - MatroskaAttachement *attachements; - EbmlList *chapters_list = &matroska->chapters; - MatroskaChapter *chapters; - MatroskaTrack *tracks; - EbmlList *index_list; - MatroskaIndex *index; - int index_scale = 1; - uint64_t max_start = 0; - Ebml ebml = { 0 }; - AVStream *st; - int i, j; - - matroska->ctx = s; - - /* First read the EBML header. */ - if (ebml_parse(matroska, ebml_syntax, &ebml) - || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t) - || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) { - av_log(matroska->ctx, AV_LOG_ERROR, - "EBML header using unsupported features\n" - "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", - ebml.version, ebml.doctype, ebml.doctype_version); - ebml_free(ebml_syntax, &ebml); - return AVERROR_PATCHWELCOME; - } - for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) - if (!strcmp(ebml.doctype, matroska_doctypes[i])) - break; - if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) { - av_log(s, AV_LOG_WARNING, "Unknown EBML doctype '%s'\n", ebml.doctype); - } - av_metadata_set2(&s->metadata, "doctype", ebml.doctype, 0); - ebml_free(ebml_syntax, &ebml); - - /* The next thing is a segment. */ - if (ebml_parse(matroska, matroska_segments, matroska) < 0) - return -1; - matroska_execute_seekhead(matroska); - - if (matroska->duration) - matroska->ctx->duration = matroska->duration * matroska->time_scale - * 1000 / AV_TIME_BASE; - av_metadata_set2(&s->metadata, "title", matroska->title, 0); - - tracks = matroska->tracks.elem; - for (i=0; i < matroska->tracks.nb_elem; i++) { - MatroskaTrack *track = &tracks[i]; - enum CodecID codec_id = CODEC_ID_NONE; - EbmlList *encodings_list = &tracks->encodings; - MatroskaTrackEncoding *encodings = encodings_list->elem; - uint8_t *extradata = NULL; - int extradata_size = 0; - int extradata_offset = 0; - ByteIOContext b; - - /* Apply some sanity checks. */ - if (track->type != MATROSKA_TRACK_TYPE_VIDEO && - track->type != MATROSKA_TRACK_TYPE_AUDIO && - track->type != MATROSKA_TRACK_TYPE_SUBTITLE) { - av_log(matroska->ctx, AV_LOG_INFO, - "Unknown or unsupported track type %"PRIu64"\n", - track->type); - continue; - } - if (track->codec_id == NULL) - continue; - - if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { - if (!track->default_duration) - track->default_duration = 1000000000/track->video.frame_rate; - if (!track->video.display_width) - track->video.display_width = track->video.pixel_width; - if (!track->video.display_height) - track->video.display_height = track->video.pixel_height; - } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { - if (!track->audio.out_samplerate) - track->audio.out_samplerate = track->audio.samplerate; - } - if (encodings_list->nb_elem > 1) { - av_log(matroska->ctx, AV_LOG_ERROR, - "Multiple combined encodings no supported"); - } else if (encodings_list->nb_elem == 1) { - if (encodings[0].type || - (encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && -#if CONFIG_ZLIB - encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB && -#endif -#if CONFIG_BZLIB - encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_BZLIB && -#endif - encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO)) { - encodings[0].scope = 0; - av_log(matroska->ctx, AV_LOG_ERROR, - "Unsupported encoding type"); - } else if (track->codec_priv.size && encodings[0].scope&2) { - uint8_t *codec_priv = track->codec_priv.data; - int offset = matroska_decode_buffer(&track->codec_priv.data, - &track->codec_priv.size, - track); - if (offset < 0) { - track->codec_priv.data = NULL; - track->codec_priv.size = 0; - av_log(matroska->ctx, AV_LOG_ERROR, - "Failed to decode codec private data\n"); - } else if (offset > 0) { - track->codec_priv.data = av_malloc(track->codec_priv.size + offset); - memcpy(track->codec_priv.data, - encodings[0].compression.settings.data, offset); - memcpy(track->codec_priv.data+offset, codec_priv, - track->codec_priv.size); - track->codec_priv.size += offset; - } - if (codec_priv != track->codec_priv.data) - av_free(codec_priv); - } - } - - for(j=0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++){ - if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id, - strlen(ff_mkv_codec_tags[j].str))){ - codec_id= ff_mkv_codec_tags[j].id; - break; - } - } - - st = track->stream = av_new_stream(s, 0); - if (st == NULL) - return AVERROR(ENOMEM); - - if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC") - && track->codec_priv.size >= 40 - && track->codec_priv.data != NULL) { - track->ms_compat = 1; - track->video.fourcc = AV_RL32(track->codec_priv.data + 16); - codec_id = ff_codec_get_id(ff_codec_bmp_tags, track->video.fourcc); - extradata_offset = 40; - } else if (!strcmp(track->codec_id, "A_MS/ACM") - && track->codec_priv.size >= 14 - && track->codec_priv.data != NULL) { - init_put_byte(&b, track->codec_priv.data, track->codec_priv.size, - URL_RDONLY, NULL, NULL, NULL, NULL); - ff_get_wav_header(&b, st->codec, track->codec_priv.size); - codec_id = st->codec->codec_id; - extradata_offset = FFMIN(track->codec_priv.size, 18); - } else if (!strcmp(track->codec_id, "V_QUICKTIME") - && (track->codec_priv.size >= 86) - && (track->codec_priv.data != NULL)) { - track->video.fourcc = AV_RL32(track->codec_priv.data); - codec_id=ff_codec_get_id(codec_movvideo_tags, track->video.fourcc); - } else if (codec_id == CODEC_ID_PCM_S16BE) { - switch (track->audio.bitdepth) { - case 8: codec_id = CODEC_ID_PCM_U8; break; - case 24: codec_id = CODEC_ID_PCM_S24BE; break; - case 32: codec_id = CODEC_ID_PCM_S32BE; break; - } - } else if (codec_id == CODEC_ID_PCM_S16LE) { - switch (track->audio.bitdepth) { - case 8: codec_id = CODEC_ID_PCM_U8; break; - case 24: codec_id = CODEC_ID_PCM_S24LE; break; - case 32: codec_id = CODEC_ID_PCM_S32LE; break; - } - } else if (codec_id==CODEC_ID_PCM_F32LE && track->audio.bitdepth==64) { - codec_id = CODEC_ID_PCM_F64LE; - } else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) { - int profile = matroska_aac_profile(track->codec_id); - int sri = matroska_aac_sri(track->audio.samplerate); - extradata = av_malloc(5); - if (extradata == NULL) - return AVERROR(ENOMEM); - extradata[0] = (profile << 3) | ((sri&0x0E) >> 1); - extradata[1] = ((sri&0x01) << 7) | (track->audio.channels<<3); - if (strstr(track->codec_id, "SBR")) { - sri = matroska_aac_sri(track->audio.out_samplerate); - extradata[2] = 0x56; - extradata[3] = 0xE5; - extradata[4] = 0x80 | (sri<<3); - extradata_size = 5; - } else - extradata_size = 2; - } else if (codec_id == CODEC_ID_TTA) { - extradata_size = 30; - extradata = av_mallocz(extradata_size); - if (extradata == NULL) - return AVERROR(ENOMEM); - init_put_byte(&b, extradata, extradata_size, 1, - NULL, NULL, NULL, NULL); - put_buffer(&b, "TTA1", 4); - put_le16(&b, 1); - put_le16(&b, track->audio.channels); - put_le16(&b, track->audio.bitdepth); - put_le32(&b, track->audio.out_samplerate); - put_le32(&b, matroska->ctx->duration * track->audio.out_samplerate); - } else if (codec_id == CODEC_ID_RV10 || codec_id == CODEC_ID_RV20 || - codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) { - extradata_offset = 26; - } else if (codec_id == CODEC_ID_RA_144) { - track->audio.out_samplerate = 8000; - track->audio.channels = 1; - } else if (codec_id == CODEC_ID_RA_288 || codec_id == CODEC_ID_COOK || - codec_id == CODEC_ID_ATRAC3 || codec_id == CODEC_ID_SIPR) { - int flavor; - init_put_byte(&b, track->codec_priv.data,track->codec_priv.size, - 0, NULL, NULL, NULL, NULL); - url_fskip(&b, 22); - flavor = get_be16(&b); - track->audio.coded_framesize = get_be32(&b); - url_fskip(&b, 12); - track->audio.sub_packet_h = get_be16(&b); - track->audio.frame_size = get_be16(&b); - track->audio.sub_packet_size = get_be16(&b); - track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h); - if (codec_id == CODEC_ID_RA_288) { - st->codec->block_align = track->audio.coded_framesize; - track->codec_priv.size = 0; - } else { - if (codec_id == CODEC_ID_SIPR && flavor < 4) { - const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 }; - track->audio.sub_packet_size = ff_sipr_subpk_size[flavor]; - st->codec->bit_rate = sipr_bit_rate[flavor]; - } - st->codec->block_align = track->audio.sub_packet_size; - extradata_offset = 78; - } - } - track->codec_priv.size -= extradata_offset; - - if (codec_id == CODEC_ID_NONE) - av_log(matroska->ctx, AV_LOG_INFO, - "Unknown/unsupported CodecID %s.\n", track->codec_id); - - if (track->time_scale < 0.01) - track->time_scale = 1.0; - av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */ - - st->codec->codec_id = codec_id; - st->start_time = 0; - if (strcmp(track->language, "und")) - av_metadata_set2(&st->metadata, "language", track->language, 0); - av_metadata_set2(&st->metadata, "title", track->name, 0); - - if (track->flag_default) - st->disposition |= AV_DISPOSITION_DEFAULT; - - if (track->default_duration) - av_reduce(&st->codec->time_base.num, &st->codec->time_base.den, - track->default_duration, 1000000000, 30000); - - if (!st->codec->extradata) { - if(extradata){ - st->codec->extradata = extradata; - st->codec->extradata_size = extradata_size; - } else if(track->codec_priv.data && track->codec_priv.size > 0){ - st->codec->extradata = av_mallocz(track->codec_priv.size + - FF_INPUT_BUFFER_PADDING_SIZE); - if(st->codec->extradata == NULL) - return AVERROR(ENOMEM); - st->codec->extradata_size = track->codec_priv.size; - memcpy(st->codec->extradata, - track->codec_priv.data + extradata_offset, - track->codec_priv.size); - } - } - - if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = track->video.fourcc; - st->codec->width = track->video.pixel_width; - st->codec->height = track->video.pixel_height; - av_reduce(&st->sample_aspect_ratio.num, - &st->sample_aspect_ratio.den, - st->codec->height * track->video.display_width, - st->codec-> width * track->video.display_height, - 255); - if (st->codec->codec_id != CODEC_ID_H264) - st->need_parsing = AVSTREAM_PARSE_HEADERS; - if (track->default_duration) - st->avg_frame_rate = av_d2q(1000000000.0/track->default_duration, INT_MAX); - } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->sample_rate = track->audio.out_samplerate; - st->codec->channels = track->audio.channels; - if (st->codec->codec_id != CODEC_ID_AAC) - st->need_parsing = AVSTREAM_PARSE_HEADERS; - } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) { - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - } - } - - attachements = attachements_list->elem; - for (j=0; jnb_elem; j++) { - if (!(attachements[j].filename && attachements[j].mime && - attachements[j].bin.data && attachements[j].bin.size > 0)) { - av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n"); - } else { - AVStream *st = av_new_stream(s, 0); - if (st == NULL) - break; - av_metadata_set2(&st->metadata, "filename",attachements[j].filename, 0); - st->codec->codec_id = CODEC_ID_NONE; - st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; - st->codec->extradata = av_malloc(attachements[j].bin.size); - if(st->codec->extradata == NULL) - break; - st->codec->extradata_size = attachements[j].bin.size; - memcpy(st->codec->extradata, attachements[j].bin.data, attachements[j].bin.size); - - for (i=0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++) { - if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime, - strlen(ff_mkv_mime_tags[i].str))) { - st->codec->codec_id = ff_mkv_mime_tags[i].id; - break; - } - } - attachements[j].stream = st; - } - } - - chapters = chapters_list->elem; - for (i=0; inb_elem; i++) - if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid - && (max_start==0 || chapters[i].start > max_start)) { - chapters[i].chapter = - ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000}, - chapters[i].start, chapters[i].end, - chapters[i].title); - av_metadata_set2(&chapters[i].chapter->metadata, - "title", chapters[i].title, 0); - max_start = chapters[i].start; - } - - index_list = &matroska->index; - index = index_list->elem; - if (index_list->nb_elem - && index[0].time > 100000000000000/matroska->time_scale) { - av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n"); - index_scale = matroska->time_scale; - } - for (i=0; inb_elem; i++) { - EbmlList *pos_list = &index[i].pos; - MatroskaIndexPos *pos = pos_list->elem; - for (j=0; jnb_elem; j++) { - MatroskaTrack *track = matroska_find_track_by_num(matroska, - pos[j].track); - if (track && track->stream) - av_add_index_entry(track->stream, - pos[j].pos + matroska->segment_start, - index[i].time/index_scale, 0, 0, - AVINDEX_KEYFRAME); - } - } - - matroska_convert_tags(s); - - return 0; -} - -/* - * Put one packet in an application-supplied AVPacket struct. - * Returns 0 on success or -1 on failure. - */ -static int matroska_deliver_packet(MatroskaDemuxContext *matroska, - AVPacket *pkt) -{ - if (matroska->num_packets > 0) { - memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); - av_free(matroska->packets[0]); - if (matroska->num_packets > 1) { - memmove(&matroska->packets[0], &matroska->packets[1], - (matroska->num_packets - 1) * sizeof(AVPacket *)); - matroska->packets = - av_realloc(matroska->packets, (matroska->num_packets - 1) * - sizeof(AVPacket *)); - } else { - av_freep(&matroska->packets); - } - matroska->num_packets--; - return 0; - } - - return -1; -} - -/* - * Free all packets in our internal queue. - */ -static void matroska_clear_queue(MatroskaDemuxContext *matroska) -{ - if (matroska->packets) { - int n; - for (n = 0; n < matroska->num_packets; n++) { - av_free_packet(matroska->packets[n]); - av_free(matroska->packets[n]); - } - av_freep(&matroska->packets); - matroska->num_packets = 0; - } -} - -static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, - int size, int64_t pos, uint64_t cluster_time, - uint64_t duration, int is_keyframe, - int64_t cluster_pos) -{ - uint64_t timecode = AV_NOPTS_VALUE; - MatroskaTrack *track; - int res = 0; - AVStream *st; - AVPacket *pkt; - int16_t block_time; - uint32_t *lace_size = NULL; - int n, flags, laces = 0; - uint64_t num; - - if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) { - av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n"); - return res; - } - data += n; - size -= n; - - track = matroska_find_track_by_num(matroska, num); - if (size <= 3 || !track || !track->stream) { - av_log(matroska->ctx, AV_LOG_INFO, - "Invalid stream %"PRIu64" or size %u\n", num, size); - return res; - } - st = track->stream; - if (st->discard >= AVDISCARD_ALL) - return res; - if (duration == AV_NOPTS_VALUE) - duration = track->default_duration / matroska->time_scale; - - block_time = AV_RB16(data); - data += 2; - flags = *data++; - size -= 3; - if (is_keyframe == -1) - is_keyframe = flags & 0x80 ? AV_PKT_FLAG_KEY : 0; - - if (cluster_time != (uint64_t)-1 - && (block_time >= 0 || cluster_time >= -block_time)) { - timecode = cluster_time + block_time; - if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE - && timecode < track->end_timecode) - is_keyframe = 0; /* overlapping subtitles are not key frame */ - if (is_keyframe) - av_add_index_entry(st, cluster_pos, timecode, 0,0,AVINDEX_KEYFRAME); - track->end_timecode = FFMAX(track->end_timecode, timecode+duration); - } - - if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) { - if (!is_keyframe || timecode < matroska->skip_to_timecode) - return res; - matroska->skip_to_keyframe = 0; - } - - switch ((flags & 0x06) >> 1) { - case 0x0: /* no lacing */ - laces = 1; - lace_size = av_mallocz(sizeof(int)); - lace_size[0] = size; - break; - - case 0x1: /* Xiph lacing */ - case 0x2: /* fixed-size lacing */ - case 0x3: /* EBML lacing */ - assert(size>0); // size <=3 is checked before size-=3 above - laces = (*data) + 1; - data += 1; - size -= 1; - lace_size = av_mallocz(laces * sizeof(int)); - - switch ((flags & 0x06) >> 1) { - case 0x1: /* Xiph lacing */ { - uint8_t temp; - uint32_t total = 0; - for (n = 0; res == 0 && n < laces - 1; n++) { - while (1) { - if (size == 0) { - res = -1; - break; - } - temp = *data; - lace_size[n] += temp; - data += 1; - size -= 1; - if (temp != 0xff) - break; - } - total += lace_size[n]; - } - lace_size[n] = size - total; - break; - } - - case 0x2: /* fixed-size lacing */ - for (n = 0; n < laces; n++) - lace_size[n] = size / laces; - break; - - case 0x3: /* EBML lacing */ { - uint32_t total; - n = matroska_ebmlnum_uint(matroska, data, size, &num); - if (n < 0) { - av_log(matroska->ctx, AV_LOG_INFO, - "EBML block data error\n"); - break; - } - data += n; - size -= n; - total = lace_size[0] = num; - for (n = 1; res == 0 && n < laces - 1; n++) { - int64_t snum; - int r; - r = matroska_ebmlnum_sint(matroska, data, size, &snum); - if (r < 0) { - av_log(matroska->ctx, AV_LOG_INFO, - "EBML block data error\n"); - break; - } - data += r; - size -= r; - lace_size[n] = lace_size[n - 1] + snum; - total += lace_size[n]; - } - lace_size[n] = size - total; - break; - } - } - break; - } - - if (res == 0) { - for (n = 0; n < laces; n++) { - if ((st->codec->codec_id == CODEC_ID_RA_288 || - st->codec->codec_id == CODEC_ID_COOK || - st->codec->codec_id == CODEC_ID_SIPR || - st->codec->codec_id == CODEC_ID_ATRAC3) && - st->codec->block_align && track->audio.sub_packet_size) { - int a = st->codec->block_align; - int sps = track->audio.sub_packet_size; - int cfs = track->audio.coded_framesize; - int h = track->audio.sub_packet_h; - int y = track->audio.sub_packet_cnt; - int w = track->audio.frame_size; - int x; - - if (!track->audio.pkt_cnt) { - if (st->codec->codec_id == CODEC_ID_RA_288) - for (x=0; xaudio.buf+x*2*w+y*cfs, - data+x*cfs, cfs); - else if (st->codec->codec_id == CODEC_ID_SIPR) - memcpy(track->audio.buf + y*w, data, w); - else - for (x=0; xaudio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); - - if (++track->audio.sub_packet_cnt >= h) { - if (st->codec->codec_id == CODEC_ID_SIPR) - ff_rm_reorder_sipr_data(track->audio.buf, h, w); - track->audio.sub_packet_cnt = 0; - track->audio.pkt_cnt = h*w / a; - } - } - while (track->audio.pkt_cnt) { - pkt = av_mallocz(sizeof(AVPacket)); - av_new_packet(pkt, a); - memcpy(pkt->data, track->audio.buf - + a * (h*w / a - track->audio.pkt_cnt--), a); - pkt->pos = pos; - pkt->stream_index = st->index; - dynarray_add(&matroska->packets,&matroska->num_packets,pkt); - } - } else { - MatroskaTrackEncoding *encodings = track->encodings.elem; - int offset = 0, pkt_size = lace_size[n]; - uint8_t *pkt_data = data; - - if (lace_size[n] > size) { - av_log(matroska->ctx, AV_LOG_ERROR, "Invalid packet size\n"); - break; - } - - if (encodings && encodings->scope & 1) { - offset = matroska_decode_buffer(&pkt_data,&pkt_size, track); - if (offset < 0) - continue; - } - - pkt = av_mallocz(sizeof(AVPacket)); - /* XXX: prevent data copy... */ - if (av_new_packet(pkt, pkt_size+offset) < 0) { - av_free(pkt); - res = AVERROR(ENOMEM); - break; - } - if (offset) - memcpy (pkt->data, encodings->compression.settings.data, offset); - memcpy (pkt->data+offset, pkt_data, pkt_size); - - if (pkt_data != data) - av_free(pkt_data); - - if (n == 0) - pkt->flags = is_keyframe; - pkt->stream_index = st->index; - - if (track->ms_compat) - pkt->dts = timecode; - else - pkt->pts = timecode; - pkt->pos = pos; - if (st->codec->codec_id == CODEC_ID_TEXT) - pkt->convergence_duration = duration; - else if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE) - pkt->duration = duration; - - if (st->codec->codec_id == CODEC_ID_SSA) - matroska_fix_ass_packet(matroska, pkt, duration); - - if (matroska->prev_pkt && - timecode != AV_NOPTS_VALUE && - matroska->prev_pkt->pts == timecode && - matroska->prev_pkt->stream_index == st->index) - matroska_merge_packets(matroska->prev_pkt, pkt); - else { - dynarray_add(&matroska->packets,&matroska->num_packets,pkt); - matroska->prev_pkt = pkt; - } - } - - if (timecode != AV_NOPTS_VALUE) - timecode = duration ? timecode + duration : AV_NOPTS_VALUE; - data += lace_size[n]; - size -= lace_size[n]; - } - } - - av_free(lace_size); - return res; -} - -static int matroska_parse_cluster(MatroskaDemuxContext *matroska) -{ - MatroskaCluster cluster = { 0 }; - EbmlList *blocks_list; - MatroskaBlock *blocks; - int i, res; - int64_t pos = url_ftell(matroska->ctx->pb); - matroska->prev_pkt = NULL; - if (matroska->has_cluster_id){ - /* For the first cluster we parse, its ID was already read as - part of matroska_read_header(), so don't read it again */ - res = ebml_parse_id(matroska, matroska_clusters, - MATROSKA_ID_CLUSTER, &cluster); - pos -= 4; /* sizeof the ID which was already read */ - matroska->has_cluster_id = 0; - } else - res = ebml_parse(matroska, matroska_clusters, &cluster); - blocks_list = &cluster.blocks; - blocks = blocks_list->elem; - for (i=0; inb_elem; i++) - if (blocks[i].bin.size > 0) { - int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1; - res=matroska_parse_block(matroska, - blocks[i].bin.data, blocks[i].bin.size, - blocks[i].bin.pos, cluster.timecode, - blocks[i].duration, is_keyframe, - pos); - } - ebml_free(matroska_cluster, &cluster); - if (res < 0) matroska->done = 1; - return res; -} - -static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MatroskaDemuxContext *matroska = s->priv_data; - - while (matroska_deliver_packet(matroska, pkt)) { - if (matroska->done) - return AVERROR_EOF; - matroska_parse_cluster(matroska); - } - - return 0; -} - -static int matroska_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTrack *tracks = matroska->tracks.elem; - AVStream *st = s->streams[stream_index]; - int i, index, index_sub, index_min; - - if (!st->nb_index_entries) - return 0; - timestamp = FFMAX(timestamp, st->index_entries[0].timestamp); - - if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { - url_fseek(s->pb, st->index_entries[st->nb_index_entries-1].pos, SEEK_SET); - while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { - matroska_clear_queue(matroska); - if (matroska_parse_cluster(matroska) < 0) - break; - } - } - - matroska_clear_queue(matroska); - if (index < 0) - return 0; - - index_min = index; - for (i=0; i < matroska->tracks.nb_elem; i++) { - tracks[i].end_timecode = 0; - if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE - && !tracks[i].stream->discard != AVDISCARD_ALL) { - index_sub = av_index_search_timestamp(tracks[i].stream, st->index_entries[index].timestamp, AVSEEK_FLAG_BACKWARD); - if (index_sub >= 0 - && st->index_entries[index_sub].pos < st->index_entries[index_min].pos - && st->index_entries[index].timestamp - st->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale) - index_min = index_sub; - } - } - - url_fseek(s->pb, st->index_entries[index_min].pos, SEEK_SET); - matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY); - matroska->skip_to_timecode = st->index_entries[index].timestamp; - matroska->done = 0; - av_update_cur_dts(s, st, st->index_entries[index].timestamp); - return 0; -} - -static int matroska_read_close(AVFormatContext *s) -{ - MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTrack *tracks = matroska->tracks.elem; - int n; - - matroska_clear_queue(matroska); - - for (n=0; n < matroska->tracks.nb_elem; n++) - if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) - av_free(tracks[n].audio.buf); - ebml_free(matroska_segment, matroska); - - return 0; -} - -AVInputFormat matroska_demuxer = { - "matroska", - NULL_IF_CONFIG_SMALL("Matroska file format"), - sizeof(MatroskaDemuxContext), - matroska_probe, - matroska_read_header, - matroska_read_packet, - matroska_read_close, - matroska_read_seek, - .metadata_conv = ff_mkv_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/matroskaenc.c b/tizen/distrib/ffmpeg/libavformat/matroskaenc.c deleted file mode 100644 index c004bd6..0000000 --- a/tizen/distrib/ffmpeg/libavformat/matroskaenc.c +++ /dev/null @@ -1,1042 +0,0 @@ -/* - * Matroska muxer - * Copyright (c) 2007 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "riff.h" -#include "isom.h" -#include "matroska.h" -#include "avc.h" -#include "flacenc.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/md5.h" -#include "libavcodec/xiph.h" -#include "libavcodec/mpeg4audio.h" - -typedef struct ebml_master { - int64_t pos; ///< absolute offset in the file where the master's elements start - int sizebytes; ///< how many bytes were reserved for the size -} ebml_master; - -typedef struct mkv_seekhead_entry { - unsigned int elementid; - uint64_t segmentpos; -} mkv_seekhead_entry; - -typedef struct mkv_seekhead { - int64_t filepos; - int64_t segment_offset; ///< the file offset to the beginning of the segment - int reserved_size; ///< -1 if appending to file - int max_entries; - mkv_seekhead_entry *entries; - int num_entries; -} mkv_seekhead; - -typedef struct { - uint64_t pts; - int tracknum; - int64_t cluster_pos; ///< file offset of the cluster containing the block -} mkv_cuepoint; - -typedef struct { - int64_t segment_offset; - mkv_cuepoint *entries; - int num_entries; -} mkv_cues; - -typedef struct { - int write_dts; -} mkv_track; - -#define MODE_MATROSKAv2 0x01 -#define MODE_WEBM 0x02 - -typedef struct MatroskaMuxContext { - int mode; - ByteIOContext *dyn_bc; - ebml_master segment; - int64_t segment_offset; - int64_t segment_uid; - ebml_master cluster; - int64_t cluster_pos; ///< file offset of the current cluster - int64_t cluster_pts; - int64_t duration_offset; - int64_t duration; - mkv_seekhead *main_seekhead; - mkv_seekhead *cluster_seekhead; - mkv_cues *cues; - mkv_track *tracks; - - struct AVMD5 *md5_ctx; -} MatroskaMuxContext; - - -/** 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit - * offset, 4 bytes for target EBML ID */ -#define MAX_SEEKENTRY_SIZE 21 - -/** per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2 - * 8-byte uint max */ -#define MAX_CUETRACKPOS_SIZE 22 - -/** per-cuepoint - 2 1-byte EBML IDs, 2 1-byte EBML sizes, 8-byte uint max */ -#define MAX_CUEPOINT_SIZE(num_tracks) 12 + MAX_CUETRACKPOS_SIZE*num_tracks - - -static int ebml_id_size(unsigned int id) -{ - return (av_log2(id+1)-1)/7+1; -} - -static void put_ebml_id(ByteIOContext *pb, unsigned int id) -{ - int i = ebml_id_size(id); - while (i--) - put_byte(pb, id >> (i*8)); -} - -/** - * Write an EBML size meaning "unknown size". - * - * @param bytes The number of bytes the size should occupy (maximum: 8). - */ -static void put_ebml_size_unknown(ByteIOContext *pb, int bytes) -{ - assert(bytes <= 8); - put_byte(pb, 0x1ff >> bytes); - while (--bytes) - put_byte(pb, 0xff); -} - -/** - * Calculate how many bytes are needed to represent a given number in EBML. - */ -static int ebml_num_size(uint64_t num) -{ - int bytes = 1; - while ((num+1) >> bytes*7) bytes++; - return bytes; -} - -/** - * Write a number in EBML variable length format. - * - * @param bytes The number of bytes that need to be used to write the number. - * If zero, any number of bytes can be used. - */ -static void put_ebml_num(ByteIOContext *pb, uint64_t num, int bytes) -{ - int i, needed_bytes = ebml_num_size(num); - - // sizes larger than this are currently undefined in EBML - assert(num < (1ULL<<56)-1); - - if (bytes == 0) - // don't care how many bytes are used, so use the min - bytes = needed_bytes; - // the bytes needed to write the given size would exceed the bytes - // that we need to use, so write unknown size. This shouldn't happen. - assert(bytes >= needed_bytes); - - num |= 1ULL << bytes*7; - for (i = bytes - 1; i >= 0; i--) - put_byte(pb, num >> i*8); -} - -static void put_ebml_uint(ByteIOContext *pb, unsigned int elementid, uint64_t val) -{ - int i, bytes = 1; - uint64_t tmp = val; - while (tmp>>=8) bytes++; - - put_ebml_id(pb, elementid); - put_ebml_num(pb, bytes, 0); - for (i = bytes - 1; i >= 0; i--) - put_byte(pb, val >> i*8); -} - -static void put_ebml_float(ByteIOContext *pb, unsigned int elementid, double val) -{ - put_ebml_id(pb, elementid); - put_ebml_num(pb, 8, 0); - put_be64(pb, av_dbl2int(val)); -} - -static void put_ebml_binary(ByteIOContext *pb, unsigned int elementid, - const uint8_t *buf, int size) -{ - put_ebml_id(pb, elementid); - put_ebml_num(pb, size, 0); - put_buffer(pb, buf, size); -} - -static void put_ebml_string(ByteIOContext *pb, unsigned int elementid, const char *str) -{ - put_ebml_binary(pb, elementid, str, strlen(str)); -} - -/** - * Writes a void element of a given size. Useful for reserving space in - * the file to be written to later. - * - * @param size The number of bytes to reserve, which must be at least 2. - */ -static void put_ebml_void(ByteIOContext *pb, uint64_t size) -{ - int64_t currentpos = url_ftell(pb); - - assert(size >= 2); - - put_ebml_id(pb, EBML_ID_VOID); - // we need to subtract the length needed to store the size from the - // size we need to reserve so 2 cases, we use 8 bytes to store the - // size if possible, 1 byte otherwise - if (size < 10) - put_ebml_num(pb, size-1, 0); - else - put_ebml_num(pb, size-9, 8); - while(url_ftell(pb) < currentpos + size) - put_byte(pb, 0); -} - -static ebml_master start_ebml_master(ByteIOContext *pb, unsigned int elementid, uint64_t expectedsize) -{ - int bytes = expectedsize ? ebml_num_size(expectedsize) : 8; - put_ebml_id(pb, elementid); - put_ebml_size_unknown(pb, bytes); - return (ebml_master){ url_ftell(pb), bytes }; -} - -static void end_ebml_master(ByteIOContext *pb, ebml_master master) -{ - int64_t pos = url_ftell(pb); - - if (url_fseek(pb, master.pos - master.sizebytes, SEEK_SET) < 0) - return; - put_ebml_num(pb, pos - master.pos, master.sizebytes); - url_fseek(pb, pos, SEEK_SET); -} - -static void put_xiph_size(ByteIOContext *pb, int size) -{ - int i; - for (i = 0; i < size / 255; i++) - put_byte(pb, 255); - put_byte(pb, size % 255); -} - -/** - * Initialize a mkv_seekhead element to be ready to index level 1 Matroska - * elements. If a maximum number of elements is specified, enough space - * will be reserved at the current file location to write a seek head of - * that size. - * - * @param segment_offset The absolute offset to the position in the file - * where the segment begins. - * @param numelements The maximum number of elements that will be indexed - * by this seek head, 0 if unlimited. - */ -static mkv_seekhead * mkv_start_seekhead(ByteIOContext *pb, int64_t segment_offset, int numelements) -{ - mkv_seekhead *new_seekhead = av_mallocz(sizeof(mkv_seekhead)); - if (new_seekhead == NULL) - return NULL; - - new_seekhead->segment_offset = segment_offset; - - if (numelements > 0) { - new_seekhead->filepos = url_ftell(pb); - // 21 bytes max for a seek entry, 10 bytes max for the SeekHead ID - // and size, and 3 bytes to guarantee that an EBML void element - // will fit afterwards - new_seekhead->reserved_size = numelements * MAX_SEEKENTRY_SIZE + 13; - new_seekhead->max_entries = numelements; - put_ebml_void(pb, new_seekhead->reserved_size); - } - return new_seekhead; -} - -static int mkv_add_seekhead_entry(mkv_seekhead *seekhead, unsigned int elementid, uint64_t filepos) -{ - mkv_seekhead_entry *entries = seekhead->entries; - - // don't store more elements than we reserved space for - if (seekhead->max_entries > 0 && seekhead->max_entries <= seekhead->num_entries) - return -1; - - entries = av_realloc(entries, (seekhead->num_entries + 1) * sizeof(mkv_seekhead_entry)); - if (entries == NULL) - return AVERROR(ENOMEM); - - entries[seekhead->num_entries ].elementid = elementid; - entries[seekhead->num_entries++].segmentpos = filepos - seekhead->segment_offset; - - seekhead->entries = entries; - return 0; -} - -/** - * Write the seek head to the file and free it. If a maximum number of - * elements was specified to mkv_start_seekhead(), the seek head will - * be written at the location reserved for it. Otherwise, it is written - * at the current location in the file. - * - * @return The file offset where the seekhead was written, - * -1 if an error occurred. - */ -static int64_t mkv_write_seekhead(ByteIOContext *pb, mkv_seekhead *seekhead) -{ - ebml_master metaseek, seekentry; - int64_t currentpos; - int i; - - currentpos = url_ftell(pb); - - if (seekhead->reserved_size > 0) - if (url_fseek(pb, seekhead->filepos, SEEK_SET) < 0) - return -1; - - metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_size); - for (i = 0; i < seekhead->num_entries; i++) { - mkv_seekhead_entry *entry = &seekhead->entries[i]; - - seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_SIZE); - - put_ebml_id(pb, MATROSKA_ID_SEEKID); - put_ebml_num(pb, ebml_id_size(entry->elementid), 0); - put_ebml_id(pb, entry->elementid); - - put_ebml_uint(pb, MATROSKA_ID_SEEKPOSITION, entry->segmentpos); - end_ebml_master(pb, seekentry); - } - end_ebml_master(pb, metaseek); - - if (seekhead->reserved_size > 0) { - uint64_t remaining = seekhead->filepos + seekhead->reserved_size - url_ftell(pb); - put_ebml_void(pb, remaining); - url_fseek(pb, currentpos, SEEK_SET); - - currentpos = seekhead->filepos; - } - av_free(seekhead->entries); - av_free(seekhead); - - return currentpos; -} - -static mkv_cues * mkv_start_cues(int64_t segment_offset) -{ - mkv_cues *cues = av_mallocz(sizeof(mkv_cues)); - if (cues == NULL) - return NULL; - - cues->segment_offset = segment_offset; - return cues; -} - -static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos) -{ - mkv_cuepoint *entries = cues->entries; - - entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint)); - if (entries == NULL) - return AVERROR(ENOMEM); - - if (ts < 0) - return 0; - - entries[cues->num_entries ].pts = ts; - entries[cues->num_entries ].tracknum = stream + 1; - entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset; - - cues->entries = entries; - return 0; -} - -static int64_t mkv_write_cues(ByteIOContext *pb, mkv_cues *cues, int num_tracks) -{ - ebml_master cues_element; - int64_t currentpos; - int i, j; - - currentpos = url_ftell(pb); - cues_element = start_ebml_master(pb, MATROSKA_ID_CUES, 0); - - for (i = 0; i < cues->num_entries; i++) { - ebml_master cuepoint, track_positions; - mkv_cuepoint *entry = &cues->entries[i]; - uint64_t pts = entry->pts; - - cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(num_tracks)); - put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts); - - // put all the entries from different tracks that have the exact same - // timestamp into the same CuePoint - for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { - track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE); - put_ebml_uint(pb, MATROSKA_ID_CUETRACK , entry[j].tracknum ); - put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos); - end_ebml_master(pb, track_positions); - } - i += j - 1; - end_ebml_master(pb, cuepoint); - } - end_ebml_master(pb, cues_element); - - av_free(cues->entries); - av_free(cues); - return currentpos; -} - -static int put_xiph_codecpriv(AVFormatContext *s, ByteIOContext *pb, AVCodecContext *codec) -{ - uint8_t *header_start[3]; - int header_len[3]; - int first_header_size; - int j; - - if (codec->codec_id == CODEC_ID_VORBIS) - first_header_size = 30; - else - first_header_size = 42; - - if (ff_split_xiph_headers(codec->extradata, codec->extradata_size, - first_header_size, header_start, header_len) < 0) { - av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n"); - return -1; - } - - put_byte(pb, 2); // number packets - 1 - for (j = 0; j < 2; j++) { - put_xiph_size(pb, header_len[j]); - } - for (j = 0; j < 3; j++) - put_buffer(pb, header_start[j], header_len[j]); - - return 0; -} - -static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int *sample_rate, int *output_sample_rate) -{ - int sri; - - if (codec->extradata_size < 2) { - av_log(s, AV_LOG_WARNING, "No AAC extradata, unable to determine samplerate.\n"); - return; - } - - sri = ((codec->extradata[0] << 1) & 0xE) | (codec->extradata[1] >> 7); - if (sri > 12) { - av_log(s, AV_LOG_WARNING, "AAC samplerate index out of bounds\n"); - return; - } - *sample_rate = ff_mpeg4audio_sample_rates[sri]; - - // if sbr, get output sample rate as well - if (codec->extradata_size == 5) { - sri = (codec->extradata[4] >> 3) & 0xF; - if (sri > 12) { - av_log(s, AV_LOG_WARNING, "AAC output samplerate index out of bounds\n"); - return; - } - *output_sample_rate = ff_mpeg4audio_sample_rates[sri]; - } -} - -static int mkv_write_codecprivate(AVFormatContext *s, ByteIOContext *pb, AVCodecContext *codec, int native_id, int qt_id) -{ - ByteIOContext *dyn_cp; - uint8_t *codecpriv; - int ret, codecpriv_size; - - ret = url_open_dyn_buf(&dyn_cp); - if(ret < 0) - return ret; - - if (native_id) { - if (codec->codec_id == CODEC_ID_VORBIS || codec->codec_id == CODEC_ID_THEORA) - ret = put_xiph_codecpriv(s, dyn_cp, codec); - else if (codec->codec_id == CODEC_ID_FLAC) - ret = ff_flac_write_header(dyn_cp, codec, 1); - else if (codec->codec_id == CODEC_ID_H264) - ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size); - else if (codec->extradata_size) - put_buffer(dyn_cp, codec->extradata, codec->extradata_size); - } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (qt_id) { - if (!codec->codec_tag) - codec->codec_tag = ff_codec_get_tag(codec_movvideo_tags, codec->codec_id); - if (codec->extradata_size) - put_buffer(dyn_cp, codec->extradata, codec->extradata_size); - } else { - if (!codec->codec_tag) - codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id); - if (!codec->codec_tag) { - av_log(s, AV_LOG_ERROR, "No bmp codec ID found.\n"); - ret = -1; - } - - ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0); - } - - } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { - unsigned int tag; - tag = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id); - if (!tag) { - av_log(s, AV_LOG_ERROR, "No wav codec ID found.\n"); - ret = -1; - } - if (!codec->codec_tag) - codec->codec_tag = tag; - - ff_put_wav_header(dyn_cp, codec); - } - - codecpriv_size = url_close_dyn_buf(dyn_cp, &codecpriv); - if (codecpriv_size) - put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv, codecpriv_size); - av_free(codecpriv); - return ret; -} - -static int mkv_write_tracks(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - ByteIOContext *pb = s->pb; - ebml_master tracks; - int i, j, ret; - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TRACKS, url_ftell(pb)); - if (ret < 0) return ret; - - tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS, 0); - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - AVCodecContext *codec = st->codec; - ebml_master subinfo, track; - int native_id = 0; - int qt_id = 0; - int bit_depth = av_get_bits_per_sample(codec->codec_id); - int sample_rate = codec->sample_rate; - int output_sample_rate = 0; - AVMetadataTag *tag; - - if (!bit_depth) - bit_depth = av_get_bits_per_sample_format(codec->sample_fmt); - - if (codec->codec_id == CODEC_ID_AAC) - get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate); - - track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0); - put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1); - put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1); - put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet) - - if ((tag = av_metadata_get(st->metadata, "title", NULL, 0))) - put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value); - tag = av_metadata_get(st->metadata, "language", NULL, 0); - put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und"); - - if (st->disposition) - put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT)); - - // look for a codec ID string specific to mkv to use, - // if none are found, use AVI codes - for (j = 0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++) { - if (ff_mkv_codec_tags[j].id == codec->codec_id) { - put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str); - native_id = 1; - break; - } - } - - if (mkv->mode == MODE_WEBM && !(codec->codec_id == CODEC_ID_VP8 || - codec->codec_id == CODEC_ID_VORBIS)) { - av_log(s, AV_LOG_ERROR, - "Only VP8 video and Vorbis audio are supported for WebM.\n"); - return AVERROR(EINVAL); - } - - switch (codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO); - put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, av_q2d(codec->time_base)*1E9); - - if (!native_id && - ff_codec_get_tag(codec_movvideo_tags, codec->codec_id) && - (!ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id) - || codec->codec_id == CODEC_ID_SVQ1 - || codec->codec_id == CODEC_ID_SVQ3 - || codec->codec_id == CODEC_ID_CINEPAK)) - qt_id = 1; - - if (qt_id) - put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME"); - else if (!native_id) { - // if there is no mkv-specific codec ID, use VFW mode - put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC"); - mkv->tracks[i].write_dts = 1; - } - - subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0); - // XXX: interlace flag? - put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width); - put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height); - if (st->sample_aspect_ratio.num) { - int d_width = codec->width*av_q2d(st->sample_aspect_ratio); - put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width); - put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height); - } - end_ebml_master(pb, subinfo); - break; - - case AVMEDIA_TYPE_AUDIO: - put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO); - - if (!native_id) - // no mkv-specific ID, use ACM mode - put_ebml_string(pb, MATROSKA_ID_CODECID, "A_MS/ACM"); - - subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO, 0); - put_ebml_uint (pb, MATROSKA_ID_AUDIOCHANNELS , codec->channels); - put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate); - if (output_sample_rate) - put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate); - if (bit_depth) - put_ebml_uint(pb, MATROSKA_ID_AUDIOBITDEPTH, bit_depth); - end_ebml_master(pb, subinfo); - break; - - case AVMEDIA_TYPE_SUBTITLE: - put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_SUBTITLE); - break; - default: - av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska."); - break; - } - ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id); - if (ret < 0) return ret; - - end_ebml_master(pb, track); - - // ms precision is the de-facto standard timescale for mkv files - av_set_pts_info(st, 64, 1, 1000); - } - end_ebml_master(pb, tracks); - return 0; -} - -static int mkv_write_chapters(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - ByteIOContext *pb = s->pb; - ebml_master chapters, editionentry; - AVRational scale = {1, 1E9}; - int i, ret; - - if (!s->nb_chapters) - return 0; - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CHAPTERS, url_ftell(pb)); - if (ret < 0) return ret; - - chapters = start_ebml_master(pb, MATROSKA_ID_CHAPTERS , 0); - editionentry = start_ebml_master(pb, MATROSKA_ID_EDITIONENTRY, 0); - put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGDEFAULT, 1); - put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGHIDDEN , 0); - for (i = 0; i < s->nb_chapters; i++) { - ebml_master chapteratom, chapterdisplay; - AVChapter *c = s->chapters[i]; - AVMetadataTag *t = NULL; - - chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMESTART, - av_rescale_q(c->start, c->time_base, scale)); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMEEND, - av_rescale_q(c->end, c->time_base, scale)); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGHIDDEN , 0); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGENABLED, 1); - if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) { - chapterdisplay = start_ebml_master(pb, MATROSKA_ID_CHAPTERDISPLAY, 0); - put_ebml_string(pb, MATROSKA_ID_CHAPSTRING, t->value); - put_ebml_string(pb, MATROSKA_ID_CHAPLANG , "und"); - end_ebml_master(pb, chapterdisplay); - } - end_ebml_master(pb, chapteratom); - } - end_ebml_master(pb, editionentry); - end_ebml_master(pb, chapters); - return 0; -} - -static int mkv_write_header(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - ByteIOContext *pb = s->pb; - ebml_master ebml_header, segment_info; - AVMetadataTag *tag; - int ret; - - if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM; - else mkv->mode = MODE_MATROSKAv2; - - mkv->md5_ctx = av_mallocz(av_md5_size); - av_md5_init(mkv->md5_ctx); - mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks)); - - ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0); - put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); - put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); - put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); - put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); - put_ebml_string (pb, EBML_ID_DOCTYPE , s->oformat->name); - put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2); - put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); - end_ebml_master(pb, ebml_header); - - mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT, 0); - mkv->segment_offset = url_ftell(pb); - - // we write 2 seek heads - one at the end of the file to point to each - // cluster, and one at the beginning to point to all other level one - // elements (including the seek head at the end of the file), which - // isn't more than 10 elements if we only write one of each other - // currently defined level 1 element - mkv->main_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 10); - mkv->cluster_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 0); - if (mkv->main_seekhead == NULL || mkv->cluster_seekhead == NULL) - return AVERROR(ENOMEM); - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_INFO, url_ftell(pb)); - if (ret < 0) return ret; - - segment_info = start_ebml_master(pb, MATROSKA_ID_INFO, 0); - put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000); - if ((tag = av_metadata_get(s->metadata, "title", NULL, 0))) - put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value); - if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { - put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); - put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); - - // reserve space to write the segment UID later - mkv->segment_uid = url_ftell(pb); - put_ebml_void(pb, 19); - } - - // reserve space for the duration - mkv->duration = 0; - mkv->duration_offset = url_ftell(pb); - put_ebml_void(pb, 11); // assumes double-precision float to be written - end_ebml_master(pb, segment_info); - - ret = mkv_write_tracks(s); - if (ret < 0) return ret; - - if (mkv->mode != MODE_WEBM) { - ret = mkv_write_chapters(s); - if (ret < 0) return ret; - } - - if (url_is_streamed(s->pb)) - mkv_write_seekhead(pb, mkv->main_seekhead); - - mkv->cues = mkv_start_cues(mkv->segment_offset); - if (mkv->cues == NULL) - return AVERROR(ENOMEM); - - put_flush_packet(pb); - return 0; -} - -static int mkv_blockgroup_size(int pkt_size) -{ - int size = pkt_size + 4; - size += ebml_num_size(size); - size += 2; // EBML ID for block and block duration - size += 8; // max size of block duration - size += ebml_num_size(size); - size += 1; // blockgroup EBML ID - return size; -} - -static int ass_get_duration(const uint8_t *p) -{ - int sh, sm, ss, sc, eh, em, es, ec; - uint64_t start, end; - - if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d", - &sh, &sm, &ss, &sc, &eh, &em, &es, &ec) != 8) - return 0; - start = 3600000*sh + 60000*sm + 1000*ss + 10*sc; - end = 3600000*eh + 60000*em + 1000*es + 10*ec; - return end - start; -} - -static int mkv_write_ass_blocks(AVFormatContext *s, ByteIOContext *pb, AVPacket *pkt) -{ - MatroskaMuxContext *mkv = s->priv_data; - int i, layer = 0, max_duration = 0, size, line_size, data_size = pkt->size; - uint8_t *start, *end, *data = pkt->data; - ebml_master blockgroup; - char buffer[2048]; - - while (data_size) { - int duration = ass_get_duration(data); - max_duration = FFMAX(duration, max_duration); - end = memchr(data, '\n', data_size); - size = line_size = end ? end-data+1 : data_size; - size -= end ? (end[-1]=='\r')+1 : 0; - start = data; - for (i=0; i<3; i++, start++) - if (!(start = memchr(start, ',', size-(start-data)))) - return max_duration; - size -= start - data; - sscanf(data, "Dialogue: %d,", &layer); - i = snprintf(buffer, sizeof(buffer), "%"PRId64",%d,", - s->streams[pkt->stream_index]->nb_frames++, layer); - size = FFMIN(i+size, sizeof(buffer)); - memcpy(buffer+i, start, size-i); - - av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " - "pts %" PRId64 ", duration %d\n", - url_ftell(pb), size, pkt->pts, duration); - blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size)); - put_ebml_id(pb, MATROSKA_ID_BLOCK); - put_ebml_num(pb, size+4, 0); - put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 - put_be16(pb, pkt->pts - mkv->cluster_pts); - put_byte(pb, 0); - put_buffer(pb, buffer, size); - put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); - end_ebml_master(pb, blockgroup); - - data += line_size; - data_size -= line_size; - } - - return max_duration; -} - -static void mkv_write_block(AVFormatContext *s, ByteIOContext *pb, - unsigned int blockid, AVPacket *pkt, int flags) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - uint8_t *data = NULL; - int size = pkt->size; - int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; - - av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " - "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", - url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags); - if (codec->codec_id == CODEC_ID_H264 && codec->extradata_size > 0 && - (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) - ff_avc_parse_nal_units_buf(pkt->data, &data, &size); - else - data = pkt->data; - put_ebml_id(pb, blockid); - put_ebml_num(pb, size+4, 0); - put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 - put_be16(pb, ts - mkv->cluster_pts); - put_byte(pb, flags); - put_buffer(pb, data, size); - if (data != pkt->data) - av_free(data); -} - -static void mkv_flush_dynbuf(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - int bufsize; - uint8_t *dyn_buf; - - if (!mkv->dyn_bc) - return; - - bufsize = url_close_dyn_buf(mkv->dyn_bc, &dyn_buf); - put_buffer(s->pb, dyn_buf, bufsize); - av_free(dyn_buf); - mkv->dyn_bc = NULL; -} - -static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - MatroskaMuxContext *mkv = s->priv_data; - ByteIOContext *pb = s->pb; - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY); - int duration = pkt->duration; - int ret; - int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; - - if (ts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n"); - return AVERROR(EINVAL); - } - - if (url_is_streamed(s->pb)) { - if (!mkv->dyn_bc) - url_open_dyn_buf(&mkv->dyn_bc); - pb = mkv->dyn_bc; - } - - if (!mkv->cluster_pos) { - ret = mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)); - if (ret < 0) return ret; - - mkv->cluster_pos = url_ftell(s->pb); - mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0); - put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts)); - mkv->cluster_pts = FFMAX(0, ts); - av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); - } - - if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) { - mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); - } else if (codec->codec_id == CODEC_ID_SSA) { - duration = mkv_write_ass_blocks(s, pb, pkt); - } else { - ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size)); - duration = pkt->convergence_duration; - mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 0); - put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); - end_ebml_master(pb, blockgroup); - } - - if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe) { - ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos); - if (ret < 0) return ret; - } - - // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming - if ((url_is_streamed(s->pb) && (url_ftell(pb) > 32*1024 || ts > mkv->cluster_pts + 1000)) - || url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || ts > mkv->cluster_pts + 5000) { - av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64 - " bytes, pts %" PRIu64 "\n", url_ftell(pb), ts); - end_ebml_master(pb, mkv->cluster); - mkv->cluster_pos = 0; - if (mkv->dyn_bc) - mkv_flush_dynbuf(s); - } - - mkv->duration = FFMAX(mkv->duration, ts + duration); - return 0; -} - -static int mkv_write_trailer(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t currentpos, second_seekhead, cuespos; - int ret; - - if (mkv->dyn_bc) { - end_ebml_master(mkv->dyn_bc, mkv->cluster); - mkv_flush_dynbuf(s); - } else if (mkv->cluster_pos) { - end_ebml_master(pb, mkv->cluster); - } - - if (!url_is_streamed(pb)) { - cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams); - second_seekhead = mkv_write_seekhead(pb, mkv->cluster_seekhead); - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES , cuespos); - if (ret < 0) return ret; - if (second_seekhead >= 0) { - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_SEEKHEAD, second_seekhead); - if (ret < 0) return ret; - } - mkv_write_seekhead(pb, mkv->main_seekhead); - - // update the duration - av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration); - currentpos = url_ftell(pb); - url_fseek(pb, mkv->duration_offset, SEEK_SET); - put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration); - - // write the md5sum of some frames as the segment UID - if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { - uint8_t segment_uid[16]; - av_md5_final(mkv->md5_ctx, segment_uid); - url_fseek(pb, mkv->segment_uid, SEEK_SET); - put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); - } - url_fseek(pb, currentpos, SEEK_SET); - } - - end_ebml_master(pb, mkv->segment); - av_free(mkv->md5_ctx); - av_free(mkv->tracks); - put_flush_packet(pb); - return 0; -} - -#if CONFIG_MATROSKA_MUXER -AVOutputFormat matroska_muxer = { - "matroska", - NULL_IF_CONFIG_SMALL("Matroska file format"), - "video/x-matroska", - "mkv", - sizeof(MatroskaMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG4, - mkv_write_header, - mkv_write_packet, - mkv_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, - .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, - .subtitle_codec = CODEC_ID_TEXT, -}; -#endif - -#if CONFIG_WEBM_MUXER -AVOutputFormat webm_muxer = { - "webm", - NULL_IF_CONFIG_SMALL("WebM file format"), - "video/webm", - "webm", - sizeof(MatroskaMuxContext), - CODEC_ID_VORBIS, - CODEC_ID_VP8, - mkv_write_header, - mkv_write_packet, - mkv_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, -}; -#endif - -#if CONFIG_MATROSKA_AUDIO_MUXER -AVOutputFormat matroska_audio_muxer = { - "matroska", - NULL_IF_CONFIG_SMALL("Matroska file format"), - "audio/x-matroska", - "mka", - sizeof(MatroskaMuxContext), - CODEC_ID_MP2, - CODEC_ID_NONE, - mkv_write_header, - mkv_write_packet, - mkv_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/metadata.c b/tizen/distrib/ffmpeg/libavformat/metadata.c deleted file mode 100644 index ff7ffe9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/metadata.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * copyright (c) 2009 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avformat.h" -#include "metadata.h" - -AVMetadataTag * -av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags) -{ - unsigned int i, j; - - if(!m) - return NULL; - - if(prev) i= prev - m->elems + 1; - else i= 0; - - for(; icount; i++){ - const char *s= m->elems[i].key; - if(flags & AV_METADATA_MATCH_CASE) for(j=0; s[j] == key[j] && key[j]; j++); - else for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++); - if(key[j]) - continue; - if(s[j] && !(flags & AV_METADATA_IGNORE_SUFFIX)) - continue; - return &m->elems[i]; - } - return NULL; -} - -int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags) -{ - AVMetadata *m= *pm; - AVMetadataTag *tag= av_metadata_get(m, key, NULL, AV_METADATA_MATCH_CASE); - - if(!m) - m=*pm= av_mallocz(sizeof(*m)); - - if(tag){ - if (flags & AV_METADATA_DONT_OVERWRITE) - return 0; - av_free(tag->value); - av_free(tag->key); - *tag= m->elems[--m->count]; - }else{ - AVMetadataTag *tmp= av_realloc(m->elems, (m->count+1) * sizeof(*m->elems)); - if(tmp){ - m->elems= tmp; - }else - return AVERROR(ENOMEM); - } - if(value){ - if(flags & AV_METADATA_DONT_STRDUP_KEY){ - m->elems[m->count].key = key; - }else - m->elems[m->count].key = av_strdup(key ); - if(flags & AV_METADATA_DONT_STRDUP_VAL){ - m->elems[m->count].value= value; - }else - m->elems[m->count].value= av_strdup(value); - m->count++; - } - if(!m->count) { - av_free(m->elems); - av_freep(pm); - } - - return 0; -} - -#if LIBAVFORMAT_VERSION_MAJOR == 52 -int av_metadata_set(AVMetadata **pm, const char *key, const char *value) -{ - return av_metadata_set2(pm, key, value, 0); -} -#endif - -void av_metadata_free(AVMetadata **pm) -{ - AVMetadata *m= *pm; - - if(m){ - while(m->count--){ - av_free(m->elems[m->count].key); - av_free(m->elems[m->count].value); - } - av_free(m->elems); - } - av_freep(pm); -} - -void metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv) -{ - /* TODO: use binary search to look up the two conversion tables - if the tables are getting big enough that it would matter speed wise */ - const AVMetadataConv *sc, *dc; - AVMetadataTag *mtag = NULL; - AVMetadata *dst = NULL; - const char *key; - - while((mtag=av_metadata_get(*pm, "", mtag, AV_METADATA_IGNORE_SUFFIX))) { - key = mtag->key; - if (s_conv != d_conv) { - if (s_conv) - for (sc=s_conv; sc->native; sc++) - if (!strcasecmp(key, sc->native)) { - key = sc->generic; - break; - } - if (d_conv) - for (dc=d_conv; dc->native; dc++) - if (!strcasecmp(key, dc->generic)) { - key = dc->native; - break; - } - } - av_metadata_set2(&dst, key, mtag->value, 0); - } - av_metadata_free(pm); - *pm = dst; -} - -void av_metadata_conv(AVFormatContext *ctx, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv) -{ - int i; - metadata_conv(&ctx->metadata, d_conv, s_conv); - for (i=0; inb_streams ; i++) - metadata_conv(&ctx->streams [i]->metadata, d_conv, s_conv); - for (i=0; inb_chapters; i++) - metadata_conv(&ctx->chapters[i]->metadata, d_conv, s_conv); - for (i=0; inb_programs; i++) - metadata_conv(&ctx->programs[i]->metadata, d_conv, s_conv); -} diff --git a/tizen/distrib/ffmpeg/libavformat/metadata.h b/tizen/distrib/ffmpeg/libavformat/metadata.h deleted file mode 100644 index fe7130e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/metadata.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * copyright (c) 2009 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_METADATA_H -#define AVFORMAT_METADATA_H - -/** - * @file - * internal metadata API header - * see avformat.h or the public API! - */ - - -#include "avformat.h" - -struct AVMetadata{ - int count; - AVMetadataTag *elems; -}; - -struct AVMetadataConv{ - const char *native; - const char *generic; -}; - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -void ff_metadata_demux_compat(AVFormatContext *s); -void ff_metadata_mux_compat(AVFormatContext *s); -#endif - -void metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv); - -#endif /* AVFORMAT_METADATA_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/metadata_compat.c b/tizen/distrib/ffmpeg/libavformat/metadata_compat.c deleted file mode 100644 index ac99c05..0000000 --- a/tizen/distrib/ffmpeg/libavformat/metadata_compat.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2009 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avformat.h" -#include "metadata.h" -#include "libavutil/avstring.h" - -#if LIBAVFORMAT_VERSION_MAJOR < 53 - -#define SIZE_OFFSET(x) sizeof(((AVFormatContext*)0)->x),offsetof(AVFormatContext,x) - -static const struct { - const char name[16]; - int size; - int offset; -} compat_tab[] = { - { "title", SIZE_OFFSET(title) }, - { "author", SIZE_OFFSET(author) }, - { "copyright", SIZE_OFFSET(copyright) }, - { "comment", SIZE_OFFSET(comment) }, - { "album", SIZE_OFFSET(album) }, - { "year", SIZE_OFFSET(year) }, - { "track", SIZE_OFFSET(track) }, - { "genre", SIZE_OFFSET(genre) }, - - { "artist", SIZE_OFFSET(author) }, - { "creator", SIZE_OFFSET(author) }, - { "written_by", SIZE_OFFSET(author) }, - { "lead_performer", SIZE_OFFSET(author) }, - { "composer", SIZE_OFFSET(author) }, - { "performer", SIZE_OFFSET(author) }, - { "description", SIZE_OFFSET(comment) }, - { "albumtitle", SIZE_OFFSET(album) }, - { "date", SIZE_OFFSET(year) }, - { "date_written", SIZE_OFFSET(year) }, - { "date_released", SIZE_OFFSET(year) }, - { "tracknumber", SIZE_OFFSET(track) }, - { "part_number", SIZE_OFFSET(track) }, -}; - -void ff_metadata_demux_compat(AVFormatContext *ctx) -{ - AVMetadata *m; - int i, j; - - if ((m = ctx->metadata)) - for (j=0; jcount; j++) - for (i=0; ielems[j].key, compat_tab[i].name)) { - int *ptr = (int *)((char *)ctx+compat_tab[i].offset); - if (*ptr) continue; - if (compat_tab[i].size > sizeof(int)) - av_strlcpy((char *)ptr, m->elems[j].value, compat_tab[i].size); - else - *ptr = atoi(m->elems[j].value); - } - - for (i=0; inb_chapters; i++) - if ((m = ctx->chapters[i]->metadata)) - for (j=0; jcount; j++) - if (!strcasecmp(m->elems[j].key, "title")) { - av_free(ctx->chapters[i]->title); - ctx->chapters[i]->title = av_strdup(m->elems[j].value); - } - - for (i=0; inb_programs; i++) - if ((m = ctx->programs[i]->metadata)) - for (j=0; jcount; j++) { - if (!strcasecmp(m->elems[j].key, "name")) { - av_free(ctx->programs[i]->name); - ctx->programs[i]->name = av_strdup(m->elems[j].value); - } - if (!strcasecmp(m->elems[j].key, "provider_name")) { - av_free(ctx->programs[i]->provider_name); - ctx->programs[i]->provider_name = av_strdup(m->elems[j].value); - } - } - - for (i=0; inb_streams; i++) - if ((m = ctx->streams[i]->metadata)) - for (j=0; jcount; j++) { - if (!strcasecmp(m->elems[j].key, "language")) - av_strlcpy(ctx->streams[i]->language, m->elems[j].value, 4); - if (!strcasecmp(m->elems[j].key, "filename")) { - av_free(ctx->streams[i]->filename); - ctx->streams[i]->filename= av_strdup(m->elems[j].value); - } - } -} - - -#define FILL_METADATA(s, key, value) { \ - if (value && *value && !av_metadata_get(s->metadata, #key, NULL, 0)) \ - av_metadata_set2(&s->metadata, #key, value, 0); \ - } -#define FILL_METADATA_STR(s, key) FILL_METADATA(s, key, s->key) -#define FILL_METADATA_INT(s, key) { \ - char number[10]; \ - snprintf(number, sizeof(number), "%d", s->key); \ - if(s->key) FILL_METADATA(s, key, number) } - -void ff_metadata_mux_compat(AVFormatContext *ctx) -{ - int i; - - if (ctx->metadata && ctx->metadata->count > 0) - return; - - FILL_METADATA_STR(ctx, title); - FILL_METADATA_STR(ctx, author); - FILL_METADATA_STR(ctx, copyright); - FILL_METADATA_STR(ctx, comment); - FILL_METADATA_STR(ctx, album); - FILL_METADATA_INT(ctx, year); - FILL_METADATA_INT(ctx, track); - FILL_METADATA_STR(ctx, genre); - for (i=0; inb_chapters; i++) - FILL_METADATA_STR(ctx->chapters[i], title); - for (i=0; inb_programs; i++) { - FILL_METADATA_STR(ctx->programs[i], name); - FILL_METADATA_STR(ctx->programs[i], provider_name); - } - for (i=0; inb_streams; i++) { - FILL_METADATA_STR(ctx->streams[i], language); - FILL_METADATA_STR(ctx->streams[i], filename); - } -} - -#endif /* LIBAVFORMAT_VERSION_MAJOR < 53 */ diff --git a/tizen/distrib/ffmpeg/libavformat/mm.c b/tizen/distrib/ffmpeg/libavformat/mm.c deleted file mode 100644 index cb0917a..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mm.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * American Laser Games MM Format Demuxer - * Copyright (c) 2006 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * American Laser Games MM Format Demuxer - * by Peter Ross (pross@xvid.org) - * - * The MM format was used by IBM-PC ports of ALG's "arcade shooter" games, - * including Mad Dog McCree and Crime Patrol. - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=American_Laser_Games_MM - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define MM_PREAMBLE_SIZE 6 - -#define MM_TYPE_HEADER 0x0 -#define MM_TYPE_INTER 0x5 -#define MM_TYPE_INTRA 0x8 -#define MM_TYPE_INTRA_HH 0xc -#define MM_TYPE_INTER_HH 0xd -#define MM_TYPE_INTRA_HHV 0xe -#define MM_TYPE_INTER_HHV 0xf -#define MM_TYPE_AUDIO 0x15 -#define MM_TYPE_PALETTE 0x31 - -#define MM_HEADER_LEN_V 0x16 /* video only */ -#define MM_HEADER_LEN_AV 0x18 /* video + audio */ - -#define MM_PALETTE_COUNT 128 -#define MM_PALETTE_SIZE (MM_PALETTE_COUNT*3) - -typedef struct { - unsigned int audio_pts, video_pts; -} MmDemuxContext; - -static int probe(AVProbeData *p) -{ - int len, type, fps, w, h; - if (p->buf_size < MM_HEADER_LEN_AV + MM_PREAMBLE_SIZE) - return 0; - /* the first chunk is always the header */ - if (AV_RL16(&p->buf[0]) != MM_TYPE_HEADER) - return 0; - len = AV_RL32(&p->buf[2]); - if (len != MM_HEADER_LEN_V && len != MM_HEADER_LEN_AV) - return 0; - fps = AV_RL16(&p->buf[8]); - w = AV_RL16(&p->buf[12]); - h = AV_RL16(&p->buf[14]); - if (!fps || fps > 60 || !w || w > 2048 || !h || h > 2048) - return 0; - type = AV_RL16(&p->buf[len]); - if (!type || type > 0x31) - return 0; - - /* only return half certainty since this check is a bit sketchy */ - return AVPROBE_SCORE_MAX / 2; -} - -static int read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - MmDemuxContext *mm = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - - unsigned int type, length; - unsigned int frame_rate, width, height; - - type = get_le16(pb); - length = get_le32(pb); - - if (type != MM_TYPE_HEADER) - return AVERROR_INVALIDDATA; - - /* read header */ - get_le16(pb); /* total number of chunks */ - frame_rate = get_le16(pb); - get_le16(pb); /* ibm-pc video bios mode */ - width = get_le16(pb); - height = get_le16(pb); - url_fseek(pb, length - 10, SEEK_CUR); /* unknown data */ - - /* video stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MMVIDEO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = width; - st->codec->height = height; - av_set_pts_info(st, 64, 1, frame_rate); - - /* audio stream */ - if (length == MM_HEADER_LEN_AV) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->codec_id = CODEC_ID_PCM_U8; - st->codec->channels = 1; - st->codec->sample_rate = 8000; - av_set_pts_info(st, 64, 1, 8000); /* 8000 hz */ - } - - mm->audio_pts = 0; - mm->video_pts = 0; - return 0; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MmDemuxContext *mm = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned char preamble[MM_PREAMBLE_SIZE]; - unsigned int type, length; - - while(1) { - - if (get_buffer(pb, preamble, MM_PREAMBLE_SIZE) != MM_PREAMBLE_SIZE) { - return AVERROR(EIO); - } - - type = AV_RL16(&preamble[0]); - length = AV_RL16(&preamble[2]); - - switch(type) { - case MM_TYPE_PALETTE : - case MM_TYPE_INTER : - case MM_TYPE_INTRA : - case MM_TYPE_INTRA_HH : - case MM_TYPE_INTER_HH : - case MM_TYPE_INTRA_HHV : - case MM_TYPE_INTER_HHV : - /* output preamble + data */ - if (av_new_packet(pkt, length + MM_PREAMBLE_SIZE)) - return AVERROR(ENOMEM); - memcpy(pkt->data, preamble, MM_PREAMBLE_SIZE); - if (get_buffer(pb, pkt->data + MM_PREAMBLE_SIZE, length) != length) - return AVERROR(EIO); - pkt->size = length + MM_PREAMBLE_SIZE; - pkt->stream_index = 0; - pkt->pts = mm->video_pts; - if (type!=MM_TYPE_PALETTE) - mm->video_pts++; - return 0; - - case MM_TYPE_AUDIO : - if (av_get_packet(s->pb, pkt, length)<0) - return AVERROR(ENOMEM); - pkt->size = length; - pkt->stream_index = 1; - pkt->pts = mm->audio_pts++; - return 0; - - default : - av_log(s, AV_LOG_INFO, "unknown chunk type 0x%x\n", type); - url_fseek(pb, length, SEEK_CUR); - } - } - - return 0; -} - -AVInputFormat mm_demuxer = { - "mm", - NULL_IF_CONFIG_SMALL("American Laser Games MM format"), - sizeof(MmDemuxContext), - probe, - read_header, - read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mmf.c b/tizen/distrib/ffmpeg/libavformat/mmf.c deleted file mode 100644 index 540407f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mmf.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Yamaha SMAF format - * Copyright (c) 2005 Vidar Madsen - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "raw.h" -#include "riff.h" - -typedef struct { - int64_t atrpos, atsqpos, awapos; - int64_t data_size; -} MMFContext; - -static const int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 }; - -static int mmf_rate(int code) -{ - if((code < 0) || (code > 4)) - return -1; - return mmf_rates[code]; -} - -#if CONFIG_MMF_MUXER -static int mmf_rate_code(int rate) -{ - int i; - for(i = 0; i < 5; i++) - if(mmf_rates[i] == rate) - return i; - return -1; -} - -/* Copy of end_tag() from avienc.c, but for big-endian chunk size */ -static void end_tag_be(ByteIOContext *pb, int64_t start) -{ - int64_t pos; - - pos = url_ftell(pb); - url_fseek(pb, start - 4, SEEK_SET); - put_be32(pb, (uint32_t)(pos - start)); - url_fseek(pb, pos, SEEK_SET); -} - -static int mmf_write_header(AVFormatContext *s) -{ - MMFContext *mmf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos; - int rate; - - rate = mmf_rate_code(s->streams[0]->codec->sample_rate); - if(rate < 0) { - av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d\n", s->streams[0]->codec->sample_rate); - return -1; - } - - put_tag(pb, "MMMD"); - put_be32(pb, 0); - pos = ff_start_tag(pb, "CNTI"); - put_byte(pb, 0); /* class */ - put_byte(pb, 0); /* type */ - put_byte(pb, 0); /* code type */ - put_byte(pb, 0); /* status */ - put_byte(pb, 0); /* counts */ - put_tag(pb, "VN:libavcodec,"); /* metadata ("ST:songtitle,VN:version,...") */ - end_tag_be(pb, pos); - - put_buffer(pb, "ATR\x00", 4); - put_be32(pb, 0); - mmf->atrpos = url_ftell(pb); - put_byte(pb, 0); /* format type */ - put_byte(pb, 0); /* sequence type */ - put_byte(pb, (0 << 7) | (1 << 4) | rate); /* (channel << 7) | (format << 4) | rate */ - put_byte(pb, 0); /* wave base bit */ - put_byte(pb, 2); /* time base d */ - put_byte(pb, 2); /* time base g */ - - put_tag(pb, "Atsq"); - put_be32(pb, 16); - mmf->atsqpos = url_ftell(pb); - /* Will be filled on close */ - put_buffer(pb, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16); - - mmf->awapos = ff_start_tag(pb, "Awa\x01"); - - av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate); - - put_flush_packet(pb); - - return 0; -} - -static int mmf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - put_buffer(pb, pkt->data, pkt->size); - return 0; -} - -/* Write a variable-length symbol */ -static void put_varlength(ByteIOContext *pb, int val) -{ - if(val < 128) - put_byte(pb, val); - else { - val -= 128; - put_byte(pb, 0x80 | val >> 7); - put_byte(pb, 0x7f & val); - } -} - -static int mmf_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - MMFContext *mmf = s->priv_data; - int64_t pos, size; - int gatetime; - - if (!url_is_streamed(s->pb)) { - /* Fill in length fields */ - end_tag_be(pb, mmf->awapos); - end_tag_be(pb, mmf->atrpos); - end_tag_be(pb, 8); - - pos = url_ftell(pb); - size = pos - mmf->awapos; - - /* Fill Atsq chunk */ - url_fseek(pb, mmf->atsqpos, SEEK_SET); - - /* "play wav" */ - put_byte(pb, 0); /* start time */ - put_byte(pb, 1); /* (channel << 6) | wavenum */ - gatetime = size * 500 / s->streams[0]->codec->sample_rate; - put_varlength(pb, gatetime); /* duration */ - - /* "nop" */ - put_varlength(pb, gatetime); /* start time */ - put_buffer(pb, "\xff\x00", 2); /* nop */ - - /* "end of sequence" */ - put_buffer(pb, "\x00\x00\x00\x00", 4); - - url_fseek(pb, pos, SEEK_SET); - - put_flush_packet(pb); - } - return 0; -} -#endif /* CONFIG_MMF_MUXER */ - -static int mmf_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf[0] == 'M' && p->buf[1] == 'M' && - p->buf[2] == 'M' && p->buf[3] == 'D' && - p->buf[8] == 'C' && p->buf[9] == 'N' && - p->buf[10] == 'T' && p->buf[11] == 'I') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* mmf input */ -static int mmf_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - MMFContext *mmf = s->priv_data; - unsigned int tag; - ByteIOContext *pb = s->pb; - AVStream *st; - int64_t file_size, size; - int rate, params; - - tag = get_le32(pb); - if (tag != MKTAG('M', 'M', 'M', 'D')) - return -1; - file_size = get_be32(pb); - - /* Skip some unused chunks that may or may not be present */ - for(;; url_fseek(pb, size, SEEK_CUR)) { - tag = get_le32(pb); - size = get_be32(pb); - if(tag == MKTAG('C','N','T','I')) continue; - if(tag == MKTAG('O','P','D','A')) continue; - break; - } - - /* Tag = "ATRx", where "x" = track number */ - if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) { - av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n"); - return -1; - } - if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) { - av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag); - return -1; - } - - get_byte(pb); /* format type */ - get_byte(pb); /* sequence type */ - params = get_byte(pb); /* (channel << 7) | (format << 4) | rate */ - rate = mmf_rate(params & 0x0f); - if(rate < 0) { - av_log(s, AV_LOG_ERROR, "Invalid sample rate\n"); - return -1; - } - get_byte(pb); /* wave base bit */ - get_byte(pb); /* time base d */ - get_byte(pb); /* time base g */ - - /* Skip some unused chunks that may or may not be present */ - for(;; url_fseek(pb, size, SEEK_CUR)) { - tag = get_le32(pb); - size = get_be32(pb); - if(tag == MKTAG('A','t','s','q')) continue; - if(tag == MKTAG('A','s','p','I')) continue; - break; - } - - /* Make sure it's followed by an Awa chunk, aka wave data */ - if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) { - av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag); - return -1; - } - mmf->data_size = size; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ADPCM_YAMAHA; - st->codec->sample_rate = rate; - st->codec->channels = 1; - st->codec->bits_per_coded_sample = 4; - st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample; - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -#define MAX_SIZE 4096 - -static int mmf_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MMFContext *mmf = s->priv_data; - AVStream *st; - int ret, size; - - if (url_feof(s->pb)) - return AVERROR(EIO); - st = s->streams[0]; - - size = MAX_SIZE; - if(size > mmf->data_size) - size = mmf->data_size; - - if(!size) - return AVERROR(EIO); - - if (av_new_packet(pkt, size)) - return AVERROR(EIO); - pkt->stream_index = 0; - - ret = get_buffer(s->pb, pkt->data, pkt->size); - if (ret < 0) - av_free_packet(pkt); - - mmf->data_size -= ret; - - pkt->size = ret; - return ret; -} - -#if CONFIG_MMF_DEMUXER -AVInputFormat mmf_demuxer = { - "mmf", - NULL_IF_CONFIG_SMALL("Yamaha SMAF"), - sizeof(MMFContext), - mmf_probe, - mmf_read_header, - mmf_read_packet, - NULL, - pcm_read_seek, -}; -#endif -#if CONFIG_MMF_MUXER -AVOutputFormat mmf_muxer = { - "mmf", - NULL_IF_CONFIG_SMALL("Yamaha SMAF"), - "application/vnd.smaf", - "mmf", - sizeof(MMFContext), - CODEC_ID_ADPCM_YAMAHA, - CODEC_ID_NONE, - mmf_write_header, - mmf_write_packet, - mmf_write_trailer, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/mov.c b/tizen/distrib/ffmpeg/libavformat/mov.c deleted file mode 100644 index 2edd27e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mov.c +++ /dev/null @@ -1,2595 +0,0 @@ -/* - * MOV demuxer - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -//#define DEBUG -//#define DEBUG_METADATA -//#define MOV_EXPORT_ALL_METADATA - -#include "libavutil/intreadwrite.h" -#include "libavutil/avstring.h" -#include "avformat.h" -#include "riff.h" -#include "isom.h" -#include "libavcodec/mpeg4audio.h" -#include "libavcodec/mpegaudiodata.h" -#include "libavcodec/get_bits.h" - -#if CONFIG_ZLIB -#include -#endif - -/* - * First version by Francois Revol revol@free.fr - * Seek function by Gael Chardon gael.dev@4now.net - * - * Features and limitations: - * - reads most of the QT files I have (at least the structure), - * Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html - * - the code is quite ugly... maybe I won't do it recursive next time :-) - * - * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/ - * when coding this :) (it's a writer anyway) - * - * Reference documents: - * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt - * Apple: - * http://developer.apple.com/documentation/QuickTime/QTFF/ - * http://developer.apple.com/documentation/QuickTime/QTFF/qtff.pdf - * QuickTime is a trademark of Apple (AFAIK :)) - */ - -#include "qtpalette.h" - - -#undef NDEBUG -#include - -/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */ - -/* those functions parse an atom */ -/* return code: - 0: continue to parse next atom - <0: error occurred, exit -*/ -/* links atom IDs to parse functions */ -typedef struct MOVParseTableEntry { - uint32_t type; - int (*parse)(MOVContext *ctx, ByteIOContext *pb, MOVAtom atom); -} MOVParseTableEntry; - -static const MOVParseTableEntry mov_default_parse_table[]; - -static int mov_metadata_trkn(MOVContext *c, ByteIOContext *pb, unsigned len) -{ - char buf[16]; - - get_be16(pb); // unknown - snprintf(buf, sizeof(buf), "%d", get_be16(pb)); - av_metadata_set2(&c->fc->metadata, "track", buf, 0); - - get_be16(pb); // total tracks - - return 0; -} - -static const uint32_t mac_to_unicode[128] = { - 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, - 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, - 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3, - 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC, - 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF, - 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8, - 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211, - 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8, - 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB, - 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153, - 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA, - 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02, - 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1, - 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4, - 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC, - 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7, -}; - -static int mov_read_mac_string(MOVContext *c, ByteIOContext *pb, int len, - char *dst, int dstlen) -{ - char *p = dst; - char *end = dst+dstlen-1; - int i; - - for (i = 0; i < len; i++) { - uint8_t t, c = get_byte(pb); - if (c < 0x80 && p < end) - *p++ = c; - else - PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;); - } - *p = 0; - return p - dst; -} - -static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ -#ifdef MOV_EXPORT_ALL_METADATA - char tmp_key[5]; -#endif - char str[1024], key2[16], language[4] = {0}; - const char *key = NULL; - uint16_t str_size, langcode = 0; - uint32_t data_type = 0; - int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL; - - switch (atom.type) { - case MKTAG(0xa9,'n','a','m'): key = "title"; break; - case MKTAG(0xa9,'a','u','t'): - case MKTAG(0xa9,'A','R','T'): key = "artist"; break; - case MKTAG(0xa9,'w','r','t'): key = "composer"; break; - case MKTAG( 'c','p','r','t'): - case MKTAG(0xa9,'c','p','y'): key = "copyright"; break; - case MKTAG(0xa9,'c','m','t'): - case MKTAG(0xa9,'i','n','f'): key = "comment"; break; - case MKTAG(0xa9,'a','l','b'): key = "album"; break; - case MKTAG(0xa9,'d','a','y'): key = "date"; break; - case MKTAG(0xa9,'g','e','n'): key = "genre"; break; - case MKTAG(0xa9,'t','o','o'): - case MKTAG(0xa9,'e','n','c'): key = "encoder"; break; - case MKTAG( 'd','e','s','c'): key = "description";break; - case MKTAG( 'l','d','e','s'): key = "synopsis"; break; - case MKTAG( 't','v','s','h'): key = "show"; break; - case MKTAG( 't','v','e','n'): key = "episode_id";break; - case MKTAG( 't','v','n','n'): key = "network"; break; - case MKTAG( 't','r','k','n'): key = "track"; - parse = mov_metadata_trkn; break; - } - - if (c->itunes_metadata && atom.size > 8) { - int data_size = get_be32(pb); - int tag = get_le32(pb); - if (tag == MKTAG('d','a','t','a')) { - data_type = get_be32(pb); // type - get_be32(pb); // unknown - str_size = data_size - 16; - atom.size -= 16; - } else return 0; - } else if (atom.size > 4 && key && !c->itunes_metadata) { - str_size = get_be16(pb); // string length - langcode = get_be16(pb); - ff_mov_lang_to_iso639(langcode, language); - atom.size -= 4; - } else - str_size = atom.size; - -#ifdef MOV_EXPORT_ALL_METADATA - if (!key) { - snprintf(tmp_key, 5, "%.4s", (char*)&atom.type); - key = tmp_key; - } -#endif - - if (!key) - return 0; - if (atom.size < 0) - return -1; - - str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); - - if (parse) - parse(c, pb, str_size); - else { - if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded - mov_read_mac_string(c, pb, str_size, str, sizeof(str)); - } else { - get_buffer(pb, str, str_size); - str[str_size] = 0; - } - av_metadata_set2(&c->fc->metadata, key, str, 0); - if (*language && strcmp(language, "und")) { - snprintf(key2, sizeof(key2), "%s-%s", key, language); - av_metadata_set2(&c->fc->metadata, key2, str, 0); - } - } -#ifdef DEBUG_METADATA - av_log(c->fc, AV_LOG_DEBUG, "lang \"%3s\" ", language); - av_log(c->fc, AV_LOG_DEBUG, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %lld\n", - key, str, (char*)&atom.type, str_size, atom.size); -#endif - - return 0; -} - -static int mov_read_chpl(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - int64_t start; - int i, nb_chapters, str_len; - char str[256+1]; - - if ((atom.size -= 5) < 0) - return 0; - - get_be32(pb); // version + flags - get_be32(pb); // ??? - nb_chapters = get_byte(pb); - - for (i = 0; i < nb_chapters; i++) { - if (atom.size < 9) - return 0; - - start = get_be64(pb); - str_len = get_byte(pb); - - if ((atom.size -= 9+str_len) < 0) - return 0; - - get_buffer(pb, str, str_len); - str[str_len] = 0; - ff_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str); - } - return 0; -} - -static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - int64_t total_size = 0; - MOVAtom a; - int i; - - if (atom.size < 0) - atom.size = INT64_MAX; - while (total_size + 8 < atom.size && !url_feof(pb)) { - int (*parse)(MOVContext*, ByteIOContext*, MOVAtom) = NULL; - a.size = atom.size; - a.type=0; - if(atom.size >= 8) { - a.size = get_be32(pb); - a.type = get_le32(pb); - } - total_size += 8; - dprintf(c->fc, "type: %08x %.4s sz: %"PRIx64" %"PRIx64" %"PRIx64"\n", - a.type, (char*)&a.type, a.size, atom.size, total_size); - if (a.size == 1) { /* 64 bit extended size */ - a.size = get_be64(pb) - 8; - total_size += 8; - } - if (a.size == 0) { - a.size = atom.size - total_size; - if (a.size <= 8) - break; - } - a.size -= 8; - if(a.size < 0) - break; - a.size = FFMIN(a.size, atom.size - total_size); - - for (i = 0; mov_default_parse_table[i].type; i++) - if (mov_default_parse_table[i].type == a.type) { - parse = mov_default_parse_table[i].parse; - break; - } - - // container is user data - if (!parse && (atom.type == MKTAG('u','d','t','a') || - atom.type == MKTAG('i','l','s','t'))) - parse = mov_read_udta_string; - - if (!parse) { /* skip leaf atoms data */ - url_fskip(pb, a.size); - } else { - int64_t start_pos = url_ftell(pb); - int64_t left; - int err = parse(c, pb, a); - if (err < 0) - return err; - if (c->found_moov && c->found_mdat && - (url_is_streamed(pb) || start_pos + a.size == url_fsize(pb))) - return 0; - left = a.size - url_ftell(pb) + start_pos; - if (left > 0) /* skip garbage at atom end */ - url_fskip(pb, left); - } - - total_size += a.size; - } - - if (total_size < atom.size && atom.size < 0x7ffff) - url_fskip(pb, atom.size - total_size); - - return 0; -} - -static int mov_read_dref(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - int entries, i, j; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_be32(pb); // version + flags - entries = get_be32(pb); - if (entries >= UINT_MAX / sizeof(*sc->drefs)) - return -1; - sc->drefs = av_mallocz(entries * sizeof(*sc->drefs)); - if (!sc->drefs) - return AVERROR(ENOMEM); - sc->drefs_count = entries; - - for (i = 0; i < sc->drefs_count; i++) { - MOVDref *dref = &sc->drefs[i]; - uint32_t size = get_be32(pb); - int64_t next = url_ftell(pb) + size - 4; - - dref->type = get_le32(pb); - get_be32(pb); // version + flags - dprintf(c->fc, "type %.4s size %d\n", (char*)&dref->type, size); - - if (dref->type == MKTAG('a','l','i','s') && size > 150) { - /* macintosh alias record */ - uint16_t volume_len, len; - int16_t type; - - url_fskip(pb, 10); - - volume_len = get_byte(pb); - volume_len = FFMIN(volume_len, 27); - get_buffer(pb, dref->volume, 27); - dref->volume[volume_len] = 0; - av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len); - - url_fskip(pb, 12); - - len = get_byte(pb); - len = FFMIN(len, 63); - get_buffer(pb, dref->filename, 63); - dref->filename[len] = 0; - av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len); - - url_fskip(pb, 16); - - /* read next level up_from_alias/down_to_target */ - dref->nlvl_from = get_be16(pb); - dref->nlvl_to = get_be16(pb); - av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n", - dref->nlvl_from, dref->nlvl_to); - - url_fskip(pb, 16); - - for (type = 0; type != -1 && url_ftell(pb) < next; ) { - type = get_be16(pb); - len = get_be16(pb); - av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len); - if (len&1) - len += 1; - if (type == 2) { // absolute path - av_free(dref->path); - dref->path = av_mallocz(len+1); - if (!dref->path) - return AVERROR(ENOMEM); - get_buffer(pb, dref->path, len); - if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) { - len -= volume_len; - memmove(dref->path, dref->path+volume_len, len); - dref->path[len] = 0; - } - for (j = 0; j < len; j++) - if (dref->path[j] == ':') - dref->path[j] = '/'; - av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path); - } else if (type == 0) { // directory name - av_free(dref->dir); - dref->dir = av_malloc(len+1); - if (!dref->dir) - return AVERROR(ENOMEM); - get_buffer(pb, dref->dir, len); - dref->dir[len] = 0; - for (j = 0; j < len; j++) - if (dref->dir[j] == ':') - dref->dir[j] = '/'; - av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir); - } else - url_fskip(pb, len); - } - } - url_fseek(pb, next, SEEK_SET); - } - return 0; -} - -static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - uint32_t type; - uint32_t ctype; - - if (c->fc->nb_streams < 1) // meta before first trak - return 0; - - st = c->fc->streams[c->fc->nb_streams-1]; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - - /* component type */ - ctype = get_le32(pb); - type = get_le32(pb); /* component subtype */ - - dprintf(c->fc, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype); - dprintf(c->fc, "stype= %.4s\n", (char*)&type); - - if (type == MKTAG('v','i','d','e')) - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - else if(type == MKTAG('s','o','u','n')) - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - else if(type == MKTAG('m','1','a',' ')) - st->codec->codec_id = CODEC_ID_MP2; - else if(type == MKTAG('s','u','b','p')) - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - - get_be32(pb); /* component manufacture */ - get_be32(pb); /* component flags */ - get_be32(pb); /* component flags mask */ - - return 0; -} - -int ff_mp4_read_descr_len(ByteIOContext *pb) -{ - int len = 0; - int count = 4; - while (count--) { - int c = get_byte(pb); - len = (len << 7) | (c & 0x7f); - if (!(c & 0x80)) - break; - } - return len; -} - -static int mp4_read_descr(AVFormatContext *fc, ByteIOContext *pb, int *tag) -{ - int len; - *tag = get_byte(pb); - len = ff_mp4_read_descr_len(pb); - dprintf(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len); - return len; -} - -#define MP4ESDescrTag 0x03 -#define MP4DecConfigDescrTag 0x04 -#define MP4DecSpecificDescrTag 0x05 - -static const AVCodecTag mp4_audio_types[] = { - { CODEC_ID_MP3ON4, AOT_PS }, /* old mp3on4 draft */ - { CODEC_ID_MP3ON4, AOT_L1 }, /* layer 1 */ - { CODEC_ID_MP3ON4, AOT_L2 }, /* layer 2 */ - { CODEC_ID_MP3ON4, AOT_L3 }, /* layer 3 */ - { CODEC_ID_MP4ALS, AOT_ALS }, /* MPEG-4 ALS */ - { CODEC_ID_NONE, AOT_NULL }, -}; - -int ff_mov_read_esds(AVFormatContext *fc, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - int tag, len; - - if (fc->nb_streams < 1) - return 0; - st = fc->streams[fc->nb_streams-1]; - - get_be32(pb); /* version + flags */ - len = mp4_read_descr(fc, pb, &tag); - if (tag == MP4ESDescrTag) { - get_be16(pb); /* ID */ - get_byte(pb); /* priority */ - } else - get_be16(pb); /* ID */ - - len = mp4_read_descr(fc, pb, &tag); - if (tag == MP4DecConfigDescrTag) { - int object_type_id = get_byte(pb); - get_byte(pb); /* stream type */ - get_be24(pb); /* buffer size db */ - get_be32(pb); /* max bitrate */ - get_be32(pb); /* avg bitrate */ - - st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id); - dprintf(fc, "esds object type id 0x%02x\n", object_type_id); - len = mp4_read_descr(fc, pb, &tag); - if (tag == MP4DecSpecificDescrTag) { - dprintf(fc, "Specific MPEG4 header len=%d\n", len); - if((uint64_t)len > (1<<30)) - return -1; - st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - get_buffer(pb, st->codec->extradata, len); - st->codec->extradata_size = len; - if (st->codec->codec_id == CODEC_ID_AAC) { - MPEG4AudioConfig cfg; - ff_mpeg4audio_get_config(&cfg, st->codec->extradata, - st->codec->extradata_size); - st->codec->channels = cfg.channels; - if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 - st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index]; - else - st->codec->sample_rate = cfg.sample_rate; // ext sample rate ? - dprintf(fc, "mp4a config channels %d obj %d ext obj %d " - "sample rate %d ext sample rate %d\n", st->codec->channels, - cfg.object_type, cfg.ext_object_type, - cfg.sample_rate, cfg.ext_sample_rate); - if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types, - cfg.object_type))) - st->codec->codec_id = CODEC_ID_AAC; - } - } - } - return 0; -} - -static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - return ff_mov_read_esds(c->fc, pb, atom); -} - -static int mov_read_pasp(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - const int num = get_be32(pb); - const int den = get_be32(pb); - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if (den != 0) { - if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default - (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) - av_log(c->fc, AV_LOG_WARNING, - "sample aspect ratio already set to %d:%d, overriding by 'pasp' atom\n", - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); - st->sample_aspect_ratio.num = num; - st->sample_aspect_ratio.den = den; - } - return 0; -} - -/* this atom contains actual media data */ -static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - if(atom.size == 0) /* wrong one (MP4) */ - return 0; - c->found_mdat=1; - return 0; /* now go for moov */ -} - -/* read major brand, minor version and compatible brands and store them as metadata */ -static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - uint32_t minor_ver; - int comp_brand_size; - char minor_ver_str[11]; /* 32 bit integer -> 10 digits + null */ - char* comp_brands_str; - uint8_t type[5] = {0}; - - get_buffer(pb, type, 4); - if (strcmp(type, "qt ")) - c->isom = 1; - av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type); - av_metadata_set2(&c->fc->metadata, "major_brand", type, 0); - minor_ver = get_be32(pb); /* minor version */ - snprintf(minor_ver_str, sizeof(minor_ver_str), "%d", minor_ver); - av_metadata_set2(&c->fc->metadata, "minor_version", minor_ver_str, 0); - - comp_brand_size = atom.size - 8; - if (comp_brand_size < 0) - return -1; - comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */ - if (!comp_brands_str) - return AVERROR(ENOMEM); - get_buffer(pb, comp_brands_str, comp_brand_size); - comp_brands_str[comp_brand_size] = 0; - av_metadata_set2(&c->fc->metadata, "compatible_brands", comp_brands_str, 0); - av_freep(&comp_brands_str); - - return 0; -} - -/* this atom should contain all header atoms */ -static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - if (mov_read_default(c, pb, atom) < 0) - return -1; - /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */ - /* so we don't parse the whole file if over a network */ - c->found_moov=1; - return 0; /* now go for mdat */ -} - -static int mov_read_moof(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - c->fragment.moof_offset = url_ftell(pb) - 8; - dprintf(c->fc, "moof offset %llx\n", c->fragment.moof_offset); - return mov_read_default(c, pb, atom); -} - -static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - int version; - char language[4] = {0}; - unsigned lang; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - version = get_byte(pb); - if (version > 1) - return -1; /* unsupported */ - - get_be24(pb); /* flags */ - if (version == 1) { - get_be64(pb); - get_be64(pb); - } else { - get_be32(pb); /* creation time */ - get_be32(pb); /* modification time */ - } - - sc->time_scale = get_be32(pb); - st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */ - - lang = get_be16(pb); /* language */ - if (ff_mov_lang_to_iso639(lang, language)) - av_metadata_set2(&st->metadata, "language", language, 0); - get_be16(pb); /* quality */ - - return 0; -} - -static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - int version = get_byte(pb); /* version */ - get_be24(pb); /* flags */ - - if (version == 1) { - get_be64(pb); - get_be64(pb); - } else { - get_be32(pb); /* creation time */ - get_be32(pb); /* modification time */ - } - c->time_scale = get_be32(pb); /* time scale */ - - dprintf(c->fc, "time scale = %i\n", c->time_scale); - - c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */ - get_be32(pb); /* preferred scale */ - - get_be16(pb); /* preferred volume */ - - url_fskip(pb, 10); /* reserved */ - - url_fskip(pb, 36); /* display matrix */ - - get_be32(pb); /* preview time */ - get_be32(pb); /* preview duration */ - get_be32(pb); /* poster time */ - get_be32(pb); /* selection time */ - get_be32(pb); /* selection duration */ - get_be32(pb); /* current time */ - get_be32(pb); /* next track ID */ - - return 0; -} - -static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if((uint64_t)atom.size > (1<<30)) - return -1; - - // currently SVQ3 decoder expect full STSD header - so let's fake it - // this should be fixed and just SMI header should be passed - av_free(st->codec->extradata); - st->codec->extradata = av_mallocz(atom.size + 0x5a + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = 0x5a + atom.size; - memcpy(st->codec->extradata, "SVQ3", 4); // fake - get_buffer(pb, st->codec->extradata + 0x5a, atom.size); - dprintf(c->fc, "Reading SMI %"PRId64" %s\n", atom.size, st->codec->extradata + 0x5a); - return 0; -} - -static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - int little_endian; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - little_endian = get_be16(pb); - dprintf(c->fc, "enda %d\n", little_endian); - if (little_endian == 1) { - switch (st->codec->codec_id) { - case CODEC_ID_PCM_S24BE: - st->codec->codec_id = CODEC_ID_PCM_S24LE; - break; - case CODEC_ID_PCM_S32BE: - st->codec->codec_id = CODEC_ID_PCM_S32LE; - break; - case CODEC_ID_PCM_F32BE: - st->codec->codec_id = CODEC_ID_PCM_F32LE; - break; - case CODEC_ID_PCM_F64BE: - st->codec->codec_id = CODEC_ID_PCM_F64LE; - break; - default: - break; - } - } - return 0; -} - -/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */ -static int mov_read_extradata(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - uint64_t size; - uint8_t *buf; - - if (c->fc->nb_streams < 1) // will happen with jp2 files - return 0; - st= c->fc->streams[c->fc->nb_streams-1]; - size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE; - if(size > INT_MAX || (uint64_t)atom.size > INT_MAX) - return -1; - buf= av_realloc(st->codec->extradata, size); - if(!buf) - return -1; - st->codec->extradata= buf; - buf+= st->codec->extradata_size; - st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE; - AV_WB32( buf , atom.size + 8); - AV_WL32( buf + 4, atom.type); - get_buffer(pb, buf + 8, atom.size); - return 0; -} - -static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if((uint64_t)atom.size > (1<<30)) - return -1; - - if (st->codec->codec_id == CODEC_ID_QDM2) { - // pass all frma atom to codec, needed at least for QDM2 - av_free(st->codec->extradata); - st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = atom.size; - get_buffer(pb, st->codec->extradata, atom.size); - } else if (atom.size > 8) { /* to read frma, esds atoms */ - if (mov_read_default(c, pb, atom) < 0) - return -1; - } else - url_fskip(pb, atom.size); - return 0; -} - -/** - * This function reads atom content and puts data in extradata without tag - * nor size unlike mov_read_extradata. - */ -static int mov_read_glbl(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if((uint64_t)atom.size > (1<<30)) - return -1; - - av_free(st->codec->extradata); - st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = atom.size; - get_buffer(pb, st->codec->extradata, atom.size); - return 0; -} - -/** - * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself, - * but can have extradata appended at the end after the 40 bytes belonging - * to the struct. - */ -static int mov_read_strf(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - if (atom.size <= 40) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if((uint64_t)atom.size > (1<<30)) - return -1; - - av_free(st->codec->extradata); - st->codec->extradata = av_mallocz(atom.size - 40 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = atom.size - 40; - url_fskip(pb, 40); - get_buffer(pb, st->codec->extradata, atom.size - 40); - return 0; -} - -static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - - entries = get_be32(pb); - - if(entries >= UINT_MAX/sizeof(int64_t)) - return -1; - - sc->chunk_offsets = av_malloc(entries * sizeof(int64_t)); - if (!sc->chunk_offsets) - return AVERROR(ENOMEM); - sc->chunk_count = entries; - - if (atom.type == MKTAG('s','t','c','o')) - for(i=0; ichunk_offsets[i] = get_be32(pb); - else if (atom.type == MKTAG('c','o','6','4')) - for(i=0; ichunk_offsets[i] = get_be64(pb); - else - return -1; - - return 0; -} - -/** - * Compute codec id for 'lpcm' tag. - * See CoreAudioTypes and AudioStreamBasicDescription at Apple. - */ -enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags) -{ - if (flags & 1) { // floating point - if (flags & 2) { // big endian - if (bps == 32) return CODEC_ID_PCM_F32BE; - else if (bps == 64) return CODEC_ID_PCM_F64BE; - } else { - if (bps == 32) return CODEC_ID_PCM_F32LE; - else if (bps == 64) return CODEC_ID_PCM_F64LE; - } - } else { - if (flags & 2) { - if (bps == 8) - // signed integer - if (flags & 4) return CODEC_ID_PCM_S8; - else return CODEC_ID_PCM_U8; - else if (bps == 16) return CODEC_ID_PCM_S16BE; - else if (bps == 24) return CODEC_ID_PCM_S24BE; - else if (bps == 32) return CODEC_ID_PCM_S32BE; - } else { - if (bps == 8) - if (flags & 4) return CODEC_ID_PCM_S8; - else return CODEC_ID_PCM_U8; - else if (bps == 16) return CODEC_ID_PCM_S16LE; - else if (bps == 24) return CODEC_ID_PCM_S24LE; - else if (bps == 32) return CODEC_ID_PCM_S32LE; - } - } - return CODEC_ID_NONE; -} - -static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - int j, entries, pseudo_stream_id; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - - entries = get_be32(pb); - - for(pseudo_stream_id=0; pseudo_stream_id= 16) { - get_be32(pb); /* reserved */ - get_be16(pb); /* reserved */ - dref_id = get_be16(pb); - } - - if (st->codec->codec_tag && - st->codec->codec_tag != format && - (c->fc->video_codec_id ? ff_codec_get_id(codec_movvideo_tags, format) != c->fc->video_codec_id - : st->codec->codec_tag != MKTAG('j','p','e','g')) - ){ - /* Multiple fourcc, we skip JPEG. This is not correct, we should - * export it as a separate AVStream but this needs a few changes - * in the MOV demuxer, patch welcome. */ - av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n"); - url_fskip(pb, size - (url_ftell(pb) - start_pos)); - continue; - } - sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id; - sc->dref_id= dref_id; - - st->codec->codec_tag = format; - id = ff_codec_get_id(codec_movaudio_tags, format); - if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8))) - id = ff_codec_get_id(ff_codec_wav_tags, bswap_32(format)&0xFFFF); - - if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) { - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO && /* do not overwrite codec type */ - format && format != MKTAG('m','p','4','s')) { /* skip old asf mpeg4 tag */ - id = ff_codec_get_id(codec_movvideo_tags, format); - if (id <= 0) - id = ff_codec_get_id(ff_codec_bmp_tags, format); - if (id > 0) - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - else if(st->codec->codec_type == AVMEDIA_TYPE_DATA){ - id = ff_codec_get_id(ff_codec_movsubtitle_tags, format); - if(id > 0) - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - } - } - - dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size, - (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, - (format >> 24) & 0xff, st->codec->codec_type); - - if(st->codec->codec_type==AVMEDIA_TYPE_VIDEO) { - unsigned int color_depth, len; - int color_greyscale; - - st->codec->codec_id = id; - get_be16(pb); /* version */ - get_be16(pb); /* revision level */ - get_be32(pb); /* vendor */ - get_be32(pb); /* temporal quality */ - get_be32(pb); /* spatial quality */ - - st->codec->width = get_be16(pb); /* width */ - st->codec->height = get_be16(pb); /* height */ - - get_be32(pb); /* horiz resolution */ - get_be32(pb); /* vert resolution */ - get_be32(pb); /* data size, always 0 */ - get_be16(pb); /* frames per samples */ - - len = get_byte(pb); /* codec name, pascal string */ - if (len > 31) - len = 31; - mov_read_mac_string(c, pb, len, st->codec->codec_name, 32); - if (len < 31) - url_fskip(pb, 31 - len); - /* codec_tag YV12 triggers an UV swap in rawdec.c */ - if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) - st->codec->codec_tag=MKTAG('I', '4', '2', '0'); - - st->codec->bits_per_coded_sample = get_be16(pb); /* depth */ - st->codec->color_table_id = get_be16(pb); /* colortable id */ - dprintf(c->fc, "depth %d, ctab id %d\n", - st->codec->bits_per_coded_sample, st->codec->color_table_id); - /* figure out the palette situation */ - color_depth = st->codec->bits_per_coded_sample & 0x1F; - color_greyscale = st->codec->bits_per_coded_sample & 0x20; - - /* if the depth is 2, 4, or 8 bpp, file is palettized */ - if ((color_depth == 2) || (color_depth == 4) || - (color_depth == 8)) { - /* for palette traversal */ - unsigned int color_start, color_count, color_end; - unsigned char r, g, b; - - st->codec->palctrl = av_malloc(sizeof(*st->codec->palctrl)); - if (color_greyscale) { - int color_index, color_dec; - /* compute the greyscale palette */ - st->codec->bits_per_coded_sample = color_depth; - color_count = 1 << color_depth; - color_index = 255; - color_dec = 256 / (color_count - 1); - for (j = 0; j < color_count; j++) { - r = g = b = color_index; - st->codec->palctrl->palette[j] = - (r << 16) | (g << 8) | (b); - color_index -= color_dec; - if (color_index < 0) - color_index = 0; - } - } else if (st->codec->color_table_id) { - const uint8_t *color_table; - /* if flag bit 3 is set, use the default palette */ - color_count = 1 << color_depth; - if (color_depth == 2) - color_table = ff_qt_default_palette_4; - else if (color_depth == 4) - color_table = ff_qt_default_palette_16; - else - color_table = ff_qt_default_palette_256; - - for (j = 0; j < color_count; j++) { - r = color_table[j * 3 + 0]; - g = color_table[j * 3 + 1]; - b = color_table[j * 3 + 2]; - st->codec->palctrl->palette[j] = - (r << 16) | (g << 8) | (b); - } - } else { - /* load the palette from the file */ - color_start = get_be32(pb); - color_count = get_be16(pb); - color_end = get_be16(pb); - if ((color_start <= 255) && - (color_end <= 255)) { - for (j = color_start; j <= color_end; j++) { - /* each R, G, or B component is 16 bits; - * only use the top 8 bits; skip alpha bytes - * up front */ - get_byte(pb); - get_byte(pb); - r = get_byte(pb); - get_byte(pb); - g = get_byte(pb); - get_byte(pb); - b = get_byte(pb); - get_byte(pb); - st->codec->palctrl->palette[j] = - (r << 16) | (g << 8) | (b); - } - } - } - st->codec->palctrl->palette_changed = 1; - } - } else if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO) { - int bits_per_sample, flags; - uint16_t version = get_be16(pb); - - st->codec->codec_id = id; - get_be16(pb); /* revision level */ - get_be32(pb); /* vendor */ - - st->codec->channels = get_be16(pb); /* channel count */ - dprintf(c->fc, "audio channels %d\n", st->codec->channels); - st->codec->bits_per_coded_sample = get_be16(pb); /* sample size */ - - sc->audio_cid = get_be16(pb); - get_be16(pb); /* packet size = 0 */ - - st->codec->sample_rate = ((get_be32(pb) >> 16)); - - //Read QT version 1 fields. In version 0 these do not exist. - dprintf(c->fc, "version =%d, isom =%d\n",version,c->isom); - if(!c->isom) { - if(version==1) { - sc->samples_per_frame = get_be32(pb); - get_be32(pb); /* bytes per packet */ - sc->bytes_per_frame = get_be32(pb); - get_be32(pb); /* bytes per sample */ - } else if(version==2) { - get_be32(pb); /* sizeof struct only */ - st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */ - st->codec->channels = get_be32(pb); - get_be32(pb); /* always 0x7F000000 */ - st->codec->bits_per_coded_sample = get_be32(pb); /* bits per channel if sound is uncompressed */ - flags = get_be32(pb); /* lpcm format specific flag */ - sc->bytes_per_frame = get_be32(pb); /* bytes per audio packet if constant */ - sc->samples_per_frame = get_be32(pb); /* lpcm frames per audio packet if constant */ - if (format == MKTAG('l','p','c','m')) - st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags); - } - } - - switch (st->codec->codec_id) { - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_U8: - if (st->codec->bits_per_coded_sample == 16) - st->codec->codec_id = CODEC_ID_PCM_S16BE; - break; - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - if (st->codec->bits_per_coded_sample == 8) - st->codec->codec_id = CODEC_ID_PCM_S8; - else if (st->codec->bits_per_coded_sample == 24) - st->codec->codec_id = - st->codec->codec_id == CODEC_ID_PCM_S16BE ? - CODEC_ID_PCM_S24BE : CODEC_ID_PCM_S24LE; - break; - /* set values for old format before stsd version 1 appeared */ - case CODEC_ID_MACE3: - sc->samples_per_frame = 6; - sc->bytes_per_frame = 2*st->codec->channels; - break; - case CODEC_ID_MACE6: - sc->samples_per_frame = 6; - sc->bytes_per_frame = 1*st->codec->channels; - break; - case CODEC_ID_ADPCM_IMA_QT: - sc->samples_per_frame = 64; - sc->bytes_per_frame = 34*st->codec->channels; - break; - case CODEC_ID_GSM: - sc->samples_per_frame = 160; - sc->bytes_per_frame = 33; - break; - default: - break; - } - - bits_per_sample = av_get_bits_per_sample(st->codec->codec_id); - if (bits_per_sample) { - st->codec->bits_per_coded_sample = bits_per_sample; - sc->sample_size = (bits_per_sample >> 3) * st->codec->channels; - } - } else if(st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){ - // ttxt stsd contains display flags, justification, background - // color, fonts, and default styles, so fake an atom to read it - MOVAtom fake_atom = { .size = size - (url_ftell(pb) - start_pos) }; - if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom - mov_read_glbl(c, pb, fake_atom); - st->codec->codec_id= id; - st->codec->width = sc->width; - st->codec->height = sc->height; - } else { - /* other codec type, just skip (rtp, mp4s, tmcd ...) */ - url_fskip(pb, size - (url_ftell(pb) - start_pos)); - } - /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */ - a.size = size - (url_ftell(pb) - start_pos); - if (a.size > 8) { - if (mov_read_default(c, pb, a) < 0) - return -1; - } else if (a.size > 0) - url_fskip(pb, a.size); - } - - if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) - st->codec->sample_rate= sc->time_scale; - - /* special codec parameters handling */ - switch (st->codec->codec_id) { -#if CONFIG_DV_DEMUXER - case CODEC_ID_DVAUDIO: - c->dv_fctx = avformat_alloc_context(); - c->dv_demux = dv_init_demux(c->dv_fctx); - if (!c->dv_demux) { - av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n"); - return -1; - } - sc->dv_audio_container = 1; - st->codec->codec_id = CODEC_ID_PCM_S16LE; - break; -#endif - /* no ifdef since parameters are always those */ - case CODEC_ID_QCELP: - // force sample rate for qcelp when not stored in mov - if (st->codec->codec_tag != MKTAG('Q','c','l','p')) - st->codec->sample_rate = 8000; - st->codec->frame_size= 160; - st->codec->channels= 1; /* really needed */ - break; - case CODEC_ID_AMR_NB: - case CODEC_ID_AMR_WB: - st->codec->frame_size= sc->samples_per_frame; - st->codec->channels= 1; /* really needed */ - /* force sample rate for amr, stsd in 3gp does not store sample rate */ - if (st->codec->codec_id == CODEC_ID_AMR_NB) - st->codec->sample_rate = 8000; - else if (st->codec->codec_id == CODEC_ID_AMR_WB) - st->codec->sample_rate = 16000; - break; - case CODEC_ID_MP2: - case CODEC_ID_MP3: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; /* force type after stsd for m1a hdlr */ - st->need_parsing = AVSTREAM_PARSE_FULL; - break; - case CODEC_ID_GSM: - case CODEC_ID_ADPCM_MS: - case CODEC_ID_ADPCM_IMA_WAV: - st->codec->block_align = sc->bytes_per_frame; - break; - case CODEC_ID_ALAC: - if (st->codec->extradata_size == 36) { - st->codec->frame_size = AV_RB32(st->codec->extradata+12); - st->codec->channels = AV_RB8 (st->codec->extradata+21); - } - break; - default: - break; - } - - return 0; -} - -static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - - entries = get_be32(pb); - - dprintf(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); - - if(entries >= UINT_MAX / sizeof(*sc->stsc_data)) - return -1; - sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data)); - if (!sc->stsc_data) - return AVERROR(ENOMEM); - sc->stsc_count = entries; - - for(i=0; istsc_data[i].first = get_be32(pb); - sc->stsc_data[i].count = get_be32(pb); - sc->stsc_data[i].id = get_be32(pb); - } - return 0; -} - -static int mov_read_stps(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_be32(pb); // version + flags - - entries = get_be32(pb); - if (entries >= UINT_MAX / sizeof(*sc->stps_data)) - return -1; - sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data)); - if (!sc->stps_data) - return AVERROR(ENOMEM); - sc->stps_count = entries; - - for (i = 0; i < entries; i++) { - sc->stps_data[i] = get_be32(pb); - //dprintf(c->fc, "stps %d\n", sc->stps_data[i]); - } - - return 0; -} - -static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - - entries = get_be32(pb); - - dprintf(c->fc, "keyframe_count = %d\n", entries); - - if(entries >= UINT_MAX / sizeof(int)) - return -1; - sc->keyframes = av_malloc(entries * sizeof(int)); - if (!sc->keyframes) - return AVERROR(ENOMEM); - sc->keyframe_count = entries; - - for(i=0; ikeyframes[i] = get_be32(pb); - //dprintf(c->fc, "keyframes[]=%d\n", sc->keyframes[i]); - } - return 0; -} - -static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries, sample_size, field_size, num_bytes; - GetBitContext gb; - unsigned char* buf; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - - if (atom.type == MKTAG('s','t','s','z')) { - sample_size = get_be32(pb); - if (!sc->sample_size) /* do not overwrite value computed in stsd */ - sc->sample_size = sample_size; - field_size = 32; - } else { - sample_size = 0; - get_be24(pb); /* reserved */ - field_size = get_byte(pb); - } - entries = get_be32(pb); - - dprintf(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, entries); - - sc->sample_count = entries; - if (sample_size) - return 0; - - if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) { - av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size); - return -1; - } - - if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size) - return -1; - sc->sample_sizes = av_malloc(entries * sizeof(int)); - if (!sc->sample_sizes) - return AVERROR(ENOMEM); - - num_bytes = (entries*field_size+4)>>3; - - buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE); - if (!buf) { - av_freep(&sc->sample_sizes); - return AVERROR(ENOMEM); - } - - if (get_buffer(pb, buf, num_bytes) < num_bytes) { - av_freep(&sc->sample_sizes); - av_free(buf); - return -1; - } - - init_get_bits(&gb, buf, 8*num_bytes); - - for(i=0; isample_sizes[i] = get_bits_long(&gb, field_size); - - av_free(buf); - return 0; -} - -static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - int64_t duration=0; - int64_t total_sample_count=0; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - entries = get_be32(pb); - - dprintf(c->fc, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries); - - if(entries >= UINT_MAX / sizeof(*sc->stts_data)) - return -1; - sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data)); - if (!sc->stts_data) - return AVERROR(ENOMEM); - sc->stts_count = entries; - - for(i=0; istts_data[i].count= sample_count; - sc->stts_data[i].duration= sample_duration; - - dprintf(c->fc, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration); - - duration+=(int64_t)sample_duration*sample_count; - total_sample_count+=sample_count; - } - - st->nb_frames= total_sample_count; - if(duration) - st->duration= duration; - return 0; -} - -static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - entries = get_be32(pb); - - dprintf(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries); - - if(entries >= UINT_MAX / sizeof(*sc->ctts_data)) - return -1; - sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data)); - if (!sc->ctts_data) - return AVERROR(ENOMEM); - sc->ctts_count = entries; - - for(i=0; ictts_data[i].count = count; - sc->ctts_data[i].duration= duration; - if (duration < 0) - sc->dts_shift = FFMAX(sc->dts_shift, -duration); - } - - dprintf(c->fc, "dts shift %d\n", sc->dts_shift); - - return 0; -} - -static void mov_build_index(MOVContext *mov, AVStream *st) -{ - MOVStreamContext *sc = st->priv_data; - int64_t current_offset; - int64_t current_dts = 0; - unsigned int stts_index = 0; - unsigned int stsc_index = 0; - unsigned int stss_index = 0; - unsigned int stps_index = 0; - unsigned int i, j; - uint64_t stream_size = 0; - - /* adjust first dts according to edit list */ - if (sc->time_offset) { - int rescaled = sc->time_offset < 0 ? av_rescale(sc->time_offset, sc->time_scale, mov->time_scale) : sc->time_offset; - current_dts = -rescaled; - if (sc->ctts_data && sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) { - /* more than 16 frames delay, dts are likely wrong - this happens with files created by iMovie */ - sc->wrong_dts = 1; - st->codec->has_b_frames = 1; - } - } - - /* only use old uncompressed audio chunk demuxing when stts specifies it */ - if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - sc->stts_count == 1 && sc->stts_data[0].duration == 1)) { - unsigned int current_sample = 0; - unsigned int stts_sample = 0; - unsigned int sample_size; - unsigned int distance = 0; - int key_off = sc->keyframes && sc->keyframes[0] == 1; - - current_dts -= sc->dts_shift; - - if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries)) - return; - st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries)); - if (!st->index_entries) - return; - st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_entries); - - for (i = 0; i < sc->chunk_count; i++) { - current_offset = sc->chunk_offsets[i]; - if (stsc_index + 1 < sc->stsc_count && - i + 1 == sc->stsc_data[stsc_index + 1].first) - stsc_index++; - for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { - int keyframe = 0; - if (current_sample >= sc->sample_count) { - av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); - return; - } - - if (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]) { - keyframe = 1; - if (stss_index + 1 < sc->keyframe_count) - stss_index++; - } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) { - keyframe = 1; - if (stps_index + 1 < sc->stps_count) - stps_index++; - } - if (keyframe) - distance = 0; - sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample]; - if(sc->pseudo_stream_id == -1 || - sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { - AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]; - e->pos = current_offset; - e->timestamp = current_dts; - e->size = sample_size; - e->min_distance = distance; - e->flags = keyframe ? AVINDEX_KEYFRAME : 0; - dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " - "size %d, distance %d, keyframe %d\n", st->index, current_sample, - current_offset, current_dts, sample_size, distance, keyframe); - } - - current_offset += sample_size; - stream_size += sample_size; - current_dts += sc->stts_data[stts_index].duration; - distance++; - stts_sample++; - current_sample++; - if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) { - stts_sample = 0; - stts_index++; - } - } - } - if (st->duration > 0) - st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; - } else { - unsigned chunk_samples, total = 0; - - // compute total chunk count - for (i = 0; i < sc->stsc_count; i++) { - unsigned count, chunk_count; - - chunk_samples = sc->stsc_data[i].count; - if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) { - av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); - return; - } - - if (sc->samples_per_frame >= 160) { // gsm - count = chunk_samples / sc->samples_per_frame; - } else if (sc->samples_per_frame > 1) { - unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame; - count = (chunk_samples+samples-1) / samples; - } else { - count = (chunk_samples+1023) / 1024; - } - - if (i < sc->stsc_count - 1) - chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first; - else - chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1); - total += chunk_count * count; - } - - dprintf(mov->fc, "chunk count %d\n", total); - if (total >= UINT_MAX / sizeof(*st->index_entries)) - return; - st->index_entries = av_malloc(total*sizeof(*st->index_entries)); - if (!st->index_entries) - return; - st->index_entries_allocated_size = total*sizeof(*st->index_entries); - - // populate index - for (i = 0; i < sc->chunk_count; i++) { - current_offset = sc->chunk_offsets[i]; - if (stsc_index + 1 < sc->stsc_count && - i + 1 == sc->stsc_data[stsc_index + 1].first) - stsc_index++; - chunk_samples = sc->stsc_data[stsc_index].count; - - while (chunk_samples > 0) { - AVIndexEntry *e; - unsigned size, samples; - - if (sc->samples_per_frame >= 160) { // gsm - samples = sc->samples_per_frame; - size = sc->bytes_per_frame; - } else { - if (sc->samples_per_frame > 1) { - samples = FFMIN((1024 / sc->samples_per_frame)* - sc->samples_per_frame, chunk_samples); - size = (samples / sc->samples_per_frame) * sc->bytes_per_frame; - } else { - samples = FFMIN(1024, chunk_samples); - size = samples * sc->sample_size; - } - } - - if (st->nb_index_entries >= total) { - av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total); - return; - } - e = &st->index_entries[st->nb_index_entries++]; - e->pos = current_offset; - e->timestamp = current_dts; - e->size = size; - e->min_distance = 0; - e->flags = AVINDEX_KEYFRAME; - dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", " - "size %d, duration %d\n", st->index, i, current_offset, current_dts, - size, samples); - - current_offset += size; - current_dts += samples; - chunk_samples -= samples; - } - } - } -} - -static int mov_open_dref(ByteIOContext **pb, char *src, MOVDref *ref) -{ - /* try relative path, we do not try the absolute because it can leak information about our - system to an attacker */ - if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { - char filename[1024]; - char *src_path; - int i, l; - - /* find a source dir */ - src_path = strrchr(src, '/'); - if (src_path) - src_path++; - else - src_path = src; - - /* find a next level down to target */ - for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--) - if (ref->path[l] == '/') { - if (i == ref->nlvl_to - 1) - break; - else - i++; - } - - /* compose filename if next level down to target was found */ - if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) { - memcpy(filename, src, src_path - src); - filename[src_path - src] = 0; - - for (i = 1; i < ref->nlvl_from; i++) - av_strlcat(filename, "../", 1024); - - av_strlcat(filename, ref->path + l + 1, 1024); - - if (!url_fopen(pb, filename, URL_RDONLY)) - return 0; - } - } - - return AVERROR(ENOENT); -}; - -static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - int ret; - - st = av_new_stream(c->fc, c->fc->nb_streams); - if (!st) return AVERROR(ENOMEM); - sc = av_mallocz(sizeof(MOVStreamContext)); - if (!sc) return AVERROR(ENOMEM); - - st->priv_data = sc; - st->codec->codec_type = AVMEDIA_TYPE_DATA; - sc->ffindex = st->index; - - if ((ret = mov_read_default(c, pb, atom)) < 0) - return ret; - - /* sanity checks */ - if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count || - (!sc->sample_size && !sc->sample_count))) { - av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n", - st->index); - return 0; - } - - if (!sc->time_scale) { - av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", st->index); - sc->time_scale = c->time_scale; - if (!sc->time_scale) - sc->time_scale = 1; - } - - av_set_pts_info(st, 64, 1, sc->time_scale); - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - !st->codec->frame_size && sc->stts_count == 1) { - st->codec->frame_size = av_rescale(sc->stts_data[0].duration, - st->codec->sample_rate, sc->time_scale); - dprintf(c->fc, "frame size %d\n", st->codec->frame_size); - } - - mov_build_index(c, st); - - if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { - MOVDref *dref = &sc->drefs[sc->dref_id - 1]; - if (mov_open_dref(&sc->pb, c->fc->filename, dref) < 0) - av_log(c->fc, AV_LOG_ERROR, - "stream %d, error opening alias: path='%s', dir='%s', " - "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", - st->index, dref->path, dref->dir, dref->filename, - dref->volume, dref->nlvl_from, dref->nlvl_to); - } else - sc->pb = c->fc->pb; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (st->codec->width != sc->width || st->codec->height != sc->height) { - AVRational r = av_d2q(((double)st->codec->height * sc->width) / - ((double)st->codec->width * sc->height), INT_MAX); - if (st->sample_aspect_ratio.num) - st->sample_aspect_ratio = av_mul_q(st->sample_aspect_ratio, r); - else - st->sample_aspect_ratio = r; - } - - av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - sc->time_scale*st->nb_frames, st->duration, INT_MAX); - } - - switch (st->codec->codec_id) { -#if CONFIG_H261_DECODER - case CODEC_ID_H261: -#endif -#if CONFIG_H263_DECODER - case CODEC_ID_H263: -#endif -#if CONFIG_H264_DECODER - case CODEC_ID_H264: -#endif -#if CONFIG_MPEG4_DECODER - case CODEC_ID_MPEG4: -#endif - st->codec->width = 0; /* let decoder init width/height */ - st->codec->height= 0; - break; - } - - /* Do not need those anymore. */ - av_freep(&sc->chunk_offsets); - av_freep(&sc->stsc_data); - av_freep(&sc->sample_sizes); - av_freep(&sc->keyframes); - av_freep(&sc->stts_data); - av_freep(&sc->stps_data); - - return 0; -} - -static int mov_read_ilst(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - int ret; - c->itunes_metadata = 1; - ret = mov_read_default(c, pb, atom); - c->itunes_metadata = 0; - return ret; -} - -static int mov_read_meta(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - while (atom.size > 8) { - uint32_t tag = get_le32(pb); - atom.size -= 4; - if (tag == MKTAG('h','d','l','r')) { - url_fseek(pb, -8, SEEK_CUR); - atom.size += 8; - return mov_read_default(c, pb, atom); - } - } - return 0; -} - -static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - int i; - int width; - int height; - int64_t disp_transform[2]; - int display_matrix[3][2]; - AVStream *st; - MOVStreamContext *sc; - int version; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - version = get_byte(pb); - get_be24(pb); /* flags */ - /* - MOV_TRACK_ENABLED 0x0001 - MOV_TRACK_IN_MOVIE 0x0002 - MOV_TRACK_IN_PREVIEW 0x0004 - MOV_TRACK_IN_POSTER 0x0008 - */ - - if (version == 1) { - get_be64(pb); - get_be64(pb); - } else { - get_be32(pb); /* creation time */ - get_be32(pb); /* modification time */ - } - st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/ - get_be32(pb); /* reserved */ - - /* highlevel (considering edits) duration in movie timebase */ - (version == 1) ? get_be64(pb) : get_be32(pb); - get_be32(pb); /* reserved */ - get_be32(pb); /* reserved */ - - get_be16(pb); /* layer */ - get_be16(pb); /* alternate group */ - get_be16(pb); /* volume */ - get_be16(pb); /* reserved */ - - //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2) - // they're kept in fixed point format through all calculations - // ignore u,v,z b/c we don't need the scale factor to calc aspect ratio - for (i = 0; i < 3; i++) { - display_matrix[i][0] = get_be32(pb); // 16.16 fixed point - display_matrix[i][1] = get_be32(pb); // 16.16 fixed point - get_be32(pb); // 2.30 fixed point (not used) - } - - width = get_be32(pb); // 16.16 fixed point track width - height = get_be32(pb); // 16.16 fixed point track height - sc->width = width >> 16; - sc->height = height >> 16; - - // transform the display width/height according to the matrix - // skip this if the display matrix is the default identity matrix - // or if it is rotating the picture, ex iPhone 3GS - // to keep the same scale, use [width height 1<<16] - if (width && height && - ((display_matrix[0][0] != 65536 || - display_matrix[1][1] != 65536) && - !display_matrix[0][1] && - !display_matrix[1][0] && - !display_matrix[2][0] && !display_matrix[2][1])) { - for (i = 0; i < 2; i++) - disp_transform[i] = - (int64_t) width * display_matrix[0][i] + - (int64_t) height * display_matrix[1][i] + - ((int64_t) display_matrix[2][i] << 16); - - //sample aspect ratio is new width/height divided by old width/height - st->sample_aspect_ratio = av_d2q( - ((double) disp_transform[0] * height) / - ((double) disp_transform[1] * width), INT_MAX); - } - return 0; -} - -static int mov_read_tfhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - MOVFragment *frag = &c->fragment; - MOVTrackExt *trex = NULL; - int flags, track_id, i; - - get_byte(pb); /* version */ - flags = get_be24(pb); - - track_id = get_be32(pb); - if (!track_id) - return -1; - frag->track_id = track_id; - for (i = 0; i < c->trex_count; i++) - if (c->trex_data[i].track_id == frag->track_id) { - trex = &c->trex_data[i]; - break; - } - if (!trex) { - av_log(c->fc, AV_LOG_ERROR, "could not find corresponding trex\n"); - return -1; - } - - if (flags & 0x01) frag->base_data_offset = get_be64(pb); - else frag->base_data_offset = frag->moof_offset; - if (flags & 0x02) frag->stsd_id = get_be32(pb); - else frag->stsd_id = trex->stsd_id; - - frag->duration = flags & 0x08 ? get_be32(pb) : trex->duration; - frag->size = flags & 0x10 ? get_be32(pb) : trex->size; - frag->flags = flags & 0x20 ? get_be32(pb) : trex->flags; - dprintf(c->fc, "frag flags 0x%x\n", frag->flags); - return 0; -} - -static int mov_read_chap(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - c->chapter_track = get_be32(pb); - return 0; -} - -static int mov_read_trex(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - MOVTrackExt *trex; - - if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data)) - return -1; - trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data)); - if (!trex) - return AVERROR(ENOMEM); - c->trex_data = trex; - trex = &c->trex_data[c->trex_count++]; - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - trex->track_id = get_be32(pb); - trex->stsd_id = get_be32(pb); - trex->duration = get_be32(pb); - trex->size = get_be32(pb); - trex->flags = get_be32(pb); - return 0; -} - -static int mov_read_trun(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - MOVFragment *frag = &c->fragment; - AVStream *st = NULL; - MOVStreamContext *sc; - uint64_t offset; - int64_t dts; - int data_offset = 0; - unsigned entries, first_sample_flags = frag->flags; - int flags, distance, i; - - for (i = 0; i < c->fc->nb_streams; i++) { - if (c->fc->streams[i]->id == frag->track_id) { - st = c->fc->streams[i]; - break; - } - } - if (!st) { - av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id); - return -1; - } - sc = st->priv_data; - if (sc->pseudo_stream_id+1 != frag->stsd_id) - return 0; - get_byte(pb); /* version */ - flags = get_be24(pb); - entries = get_be32(pb); - dprintf(c->fc, "flags 0x%x entries %d\n", flags, entries); - if (flags & 0x001) data_offset = get_be32(pb); - if (flags & 0x004) first_sample_flags = get_be32(pb); - if (flags & 0x800) { - MOVStts *ctts_data; - if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data)) - return -1; - ctts_data = av_realloc(sc->ctts_data, - (entries+sc->ctts_count)*sizeof(*sc->ctts_data)); - if (!ctts_data) - return AVERROR(ENOMEM); - sc->ctts_data = ctts_data; - } - dts = st->duration; - offset = frag->base_data_offset + data_offset; - distance = 0; - dprintf(c->fc, "first sample flags 0x%x\n", first_sample_flags); - for (i = 0; i < entries; i++) { - unsigned sample_size = frag->size; - int sample_flags = i ? frag->flags : first_sample_flags; - unsigned sample_duration = frag->duration; - int keyframe; - - if (flags & 0x100) sample_duration = get_be32(pb); - if (flags & 0x200) sample_size = get_be32(pb); - if (flags & 0x400) sample_flags = get_be32(pb); - if (flags & 0x800) { - sc->ctts_data[sc->ctts_count].count = 1; - sc->ctts_data[sc->ctts_count].duration = get_be32(pb); - sc->ctts_count++; - } - if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO || - (flags & 0x004 && !i && !sample_flags) || sample_flags & 0x2000000)) - distance = 0; - av_add_index_entry(st, offset, dts, sample_size, distance, - keyframe ? AVINDEX_KEYFRAME : 0); - dprintf(c->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " - "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i, - offset, dts, sample_size, distance, keyframe); - distance++; - dts += sample_duration; - offset += sample_size; - } - frag->moof_offset = offset; - st->duration = dts; - return 0; -} - -/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */ -/* like the files created with Adobe Premiere 5.0, for samples see */ -/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */ -static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - int err; - - if (atom.size < 8) - return 0; /* continue */ - if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */ - url_fskip(pb, atom.size - 4); - return 0; - } - atom.type = get_le32(pb); - atom.size -= 8; - if (atom.type != MKTAG('m','d','a','t')) { - url_fskip(pb, atom.size); - return 0; - } - err = mov_read_mdat(c, pb, atom); - return err; -} - -static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ -#if CONFIG_ZLIB - ByteIOContext ctx; - uint8_t *cmov_data; - uint8_t *moov_data; /* uncompressed data */ - long cmov_len, moov_len; - int ret = -1; - - get_be32(pb); /* dcom atom */ - if (get_le32(pb) != MKTAG('d','c','o','m')) - return -1; - if (get_le32(pb) != MKTAG('z','l','i','b')) { - av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !"); - return -1; - } - get_be32(pb); /* cmvd atom */ - if (get_le32(pb) != MKTAG('c','m','v','d')) - return -1; - moov_len = get_be32(pb); /* uncompressed size */ - cmov_len = atom.size - 6 * 4; - - cmov_data = av_malloc(cmov_len); - if (!cmov_data) - return AVERROR(ENOMEM); - moov_data = av_malloc(moov_len); - if (!moov_data) { - av_free(cmov_data); - return AVERROR(ENOMEM); - } - get_buffer(pb, cmov_data, cmov_len); - if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK) - goto free_and_return; - if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0) - goto free_and_return; - atom.type = MKTAG('m','o','o','v'); - atom.size = moov_len; -#ifdef DEBUG -// { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); } -#endif - ret = mov_read_default(c, &ctx, atom); -free_and_return: - av_free(moov_data); - av_free(cmov_data); - return ret; -#else - av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n"); - return -1; -#endif -} - -/* edit list atom */ -static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOVAtom atom) -{ - MOVStreamContext *sc; - int i, edit_count; - - if (c->fc->nb_streams < 1) - return 0; - sc = c->fc->streams[c->fc->nb_streams-1]->priv_data; - - get_byte(pb); /* version */ - get_be24(pb); /* flags */ - edit_count = get_be32(pb); /* entries */ - - if((uint64_t)edit_count*12+8 > atom.size) - return -1; - - for(i=0; i= -1) { - sc->time_offset = time != -1 ? time : -duration; - } - } - - if(edit_count > 1) - av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, " - "a/v desync might occur, patch welcome\n"); - - dprintf(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count); - return 0; -} - -static const MOVParseTableEntry mov_default_parse_table[] = { -{ MKTAG('a','v','s','s'), mov_read_extradata }, -{ MKTAG('c','h','p','l'), mov_read_chpl }, -{ MKTAG('c','o','6','4'), mov_read_stco }, -{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */ -{ MKTAG('d','i','n','f'), mov_read_default }, -{ MKTAG('d','r','e','f'), mov_read_dref }, -{ MKTAG('e','d','t','s'), mov_read_default }, -{ MKTAG('e','l','s','t'), mov_read_elst }, -{ MKTAG('e','n','d','a'), mov_read_enda }, -{ MKTAG('f','i','e','l'), mov_read_extradata }, -{ MKTAG('f','t','y','p'), mov_read_ftyp }, -{ MKTAG('g','l','b','l'), mov_read_glbl }, -{ MKTAG('h','d','l','r'), mov_read_hdlr }, -{ MKTAG('i','l','s','t'), mov_read_ilst }, -{ MKTAG('j','p','2','h'), mov_read_extradata }, -{ MKTAG('m','d','a','t'), mov_read_mdat }, -{ MKTAG('m','d','h','d'), mov_read_mdhd }, -{ MKTAG('m','d','i','a'), mov_read_default }, -{ MKTAG('m','e','t','a'), mov_read_meta }, -{ MKTAG('m','i','n','f'), mov_read_default }, -{ MKTAG('m','o','o','f'), mov_read_moof }, -{ MKTAG('m','o','o','v'), mov_read_moov }, -{ MKTAG('m','v','e','x'), mov_read_default }, -{ MKTAG('m','v','h','d'), mov_read_mvhd }, -{ MKTAG('S','M','I',' '), mov_read_smi }, /* Sorenson extension ??? */ -{ MKTAG('a','l','a','c'), mov_read_extradata }, /* alac specific atom */ -{ MKTAG('a','v','c','C'), mov_read_glbl }, -{ MKTAG('p','a','s','p'), mov_read_pasp }, -{ MKTAG('s','t','b','l'), mov_read_default }, -{ MKTAG('s','t','c','o'), mov_read_stco }, -{ MKTAG('s','t','p','s'), mov_read_stps }, -{ MKTAG('s','t','r','f'), mov_read_strf }, -{ MKTAG('s','t','s','c'), mov_read_stsc }, -{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */ -{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */ -{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */ -{ MKTAG('s','t','t','s'), mov_read_stts }, -{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */ -{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */ -{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */ -{ MKTAG('t','r','a','k'), mov_read_trak }, -{ MKTAG('t','r','a','f'), mov_read_default }, -{ MKTAG('t','r','e','f'), mov_read_default }, -{ MKTAG('c','h','a','p'), mov_read_chap }, -{ MKTAG('t','r','e','x'), mov_read_trex }, -{ MKTAG('t','r','u','n'), mov_read_trun }, -{ MKTAG('u','d','t','a'), mov_read_default }, -{ MKTAG('w','a','v','e'), mov_read_wave }, -{ MKTAG('e','s','d','s'), mov_read_esds }, -{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */ -{ MKTAG('c','m','o','v'), mov_read_cmov }, -{ 0, NULL } -}; - -static int mov_probe(AVProbeData *p) -{ - unsigned int offset; - uint32_t tag; - int score = 0; - - /* check file header */ - offset = 0; - for(;;) { - /* ignore invalid offset */ - if ((offset + 8) > (unsigned int)p->buf_size) - return score; - tag = AV_RL32(p->buf + offset + 4); - switch(tag) { - /* check for obvious tags */ - case MKTAG('j','P',' ',' '): /* jpeg 2000 signature */ - case MKTAG('m','o','o','v'): - case MKTAG('m','d','a','t'): - case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */ - case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */ - case MKTAG('f','t','y','p'): - return AVPROBE_SCORE_MAX; - /* those are more common words, so rate then a bit less */ - case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */ - case MKTAG('w','i','d','e'): - case MKTAG('f','r','e','e'): - case MKTAG('j','u','n','k'): - case MKTAG('p','i','c','t'): - return AVPROBE_SCORE_MAX - 5; - case MKTAG(0x82,0x82,0x7f,0x7d): - case MKTAG('s','k','i','p'): - case MKTAG('u','u','i','d'): - case MKTAG('p','r','f','l'): - offset = AV_RB32(p->buf+offset) + offset; - /* if we only find those cause probedata is too small at least rate them */ - score = AVPROBE_SCORE_MAX - 50; - break; - default: - /* unrecognized tag */ - return score; - } - } - return score; -} - -// must be done after parsing all trak because there's no order requirement -static void mov_read_chapters(AVFormatContext *s) -{ - MOVContext *mov = s->priv_data; - AVStream *st = NULL; - MOVStreamContext *sc; - int64_t cur_pos; - uint8_t *title = NULL; - int i, len, i8, i16; - - for (i = 0; i < s->nb_streams; i++) - if (s->streams[i]->id == mov->chapter_track) { - st = s->streams[i]; - break; - } - if (!st) { - av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n"); - return; - } - - st->discard = AVDISCARD_ALL; - sc = st->priv_data; - cur_pos = url_ftell(sc->pb); - - for (i = 0; i < st->nb_index_entries; i++) { - AVIndexEntry *sample = &st->index_entries[i]; - int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration; - - if (url_fseek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { - av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i); - goto finish; - } - - title = av_malloc(sample->size+2); - get_buffer(sc->pb, title, sample->size); - - // the first two bytes are the length of the title - len = AV_RB16(title); - if (len > sample->size-2) - continue; - - // The samples could theoretically be in any encoding if there's an encd - // atom following, but in practice are only utf-8 or utf-16, distinguished - // instead by the presence of a BOM - if (AV_RB16(title+2) == 0xfeff) { - uint8_t *utf8 = av_malloc(2*len+3); - - i8 = i16 = 0; - while (i16 < len) { - uint32_t ch; - uint8_t tmp; - GET_UTF16(ch, i16 < len ? AV_RB16(title + (i16+=2)) : 0, break;) - PUT_UTF8(ch, tmp, if (i8 < 2*len) utf8[2+i8++] = tmp;) - } - utf8[2+i8] = 0; - av_freep(&title); - title = utf8; - } - - ff_new_chapter(s, i, st->time_base, sample->timestamp, end, title+2); - av_freep(&title); - } -finish: - av_free(title); - url_fseek(sc->pb, cur_pos, SEEK_SET); -} - -static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - MOVContext *mov = s->priv_data; - ByteIOContext *pb = s->pb; - int err; - MOVAtom atom = { 0 }; - - mov->fc = s; - /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */ - if(!url_is_streamed(pb)) - atom.size = url_fsize(pb); - else - atom.size = INT64_MAX; - - /* check MOV header */ - if ((err = mov_read_default(mov, pb, atom)) < 0) { - av_log(s, AV_LOG_ERROR, "error reading header: %d\n", err); - return err; - } - if (!mov->found_moov) { - av_log(s, AV_LOG_ERROR, "moov atom not found\n"); - return -1; - } - dprintf(mov->fc, "on_parse_exit_offset=%lld\n", url_ftell(pb)); - - if (!url_is_streamed(pb) && mov->chapter_track > 0) - mov_read_chapters(s); - - return 0; -} - -static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) -{ - AVIndexEntry *sample = NULL; - int64_t best_dts = INT64_MAX; - int i; - for (i = 0; i < s->nb_streams; i++) { - AVStream *avst = s->streams[i]; - MOVStreamContext *msc = avst->priv_data; - if (msc->pb && msc->current_sample < avst->nb_index_entries) { - AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample]; - int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); - dprintf(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); - if (!sample || (url_is_streamed(s->pb) && current_sample->pos < sample->pos) || - (!url_is_streamed(s->pb) && - ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && - ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || - (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) { - sample = current_sample; - best_dts = dts; - *st = avst; - } - } - } - return sample; -} - -static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MOVContext *mov = s->priv_data; - MOVStreamContext *sc; - AVIndexEntry *sample; - AVStream *st = NULL; - int ret; - retry: - sample = mov_find_next_sample(s, &st); - if (!sample) { - mov->found_mdat = 0; - if (!url_is_streamed(s->pb) || - mov_read_default(mov, s->pb, (MOVAtom){ 0, INT64_MAX }) < 0 || - url_feof(s->pb)) - return AVERROR_EOF; - dprintf(s, "read fragments, offset 0x%llx\n", url_ftell(s->pb)); - goto retry; - } - sc = st->priv_data; - /* must be done just before reading, to avoid infinite loop on sample */ - sc->current_sample++; - - if (st->discard != AVDISCARD_ALL) { - if (url_fseek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { - av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n", - sc->ffindex, sample->pos); - return -1; - } - ret = av_get_packet(sc->pb, pkt, sample->size); - if (ret < 0) - return ret; -#if CONFIG_DV_DEMUXER - if (mov->dv_demux && sc->dv_audio_container) { - dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size); - av_free(pkt->data); - pkt->size = 0; - ret = dv_get_packet(mov->dv_demux, pkt); - if (ret < 0) - return ret; - } -#endif - } - - pkt->stream_index = sc->ffindex; - pkt->dts = sample->timestamp; - if (sc->ctts_data) { - pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration; - /* update ctts context */ - sc->ctts_sample++; - if (sc->ctts_index < sc->ctts_count && - sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) { - sc->ctts_index++; - sc->ctts_sample = 0; - } - if (sc->wrong_dts) - pkt->dts = AV_NOPTS_VALUE; - } else { - int64_t next_dts = (sc->current_sample < st->nb_index_entries) ? - st->index_entries[sc->current_sample].timestamp : st->duration; - pkt->duration = next_dts - pkt->dts; - pkt->pts = pkt->dts; - } - if (st->discard == AVDISCARD_ALL) - goto retry; - pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0; - pkt->pos = sample->pos; - dprintf(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\n", - pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration); - return 0; -} - -static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags) -{ - MOVStreamContext *sc = st->priv_data; - int sample, time_sample; - int i; - - sample = av_index_search_timestamp(st, timestamp, flags); - dprintf(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample); - if (sample < 0) /* not sure what to do */ - return -1; - sc->current_sample = sample; - dprintf(s, "stream %d, found sample %d\n", st->index, sc->current_sample); - /* adjust ctts index */ - if (sc->ctts_data) { - time_sample = 0; - for (i = 0; i < sc->ctts_count; i++) { - int next = time_sample + sc->ctts_data[i].count; - if (next > sc->current_sample) { - sc->ctts_index = i; - sc->ctts_sample = sc->current_sample - time_sample; - break; - } - time_sample = next; - } - } - return sample; -} - -static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) -{ - AVStream *st; - int64_t seek_timestamp, timestamp; - int sample; - int i; - - if (stream_index >= s->nb_streams) - return -1; - if (sample_time < 0) - sample_time = 0; - - st = s->streams[stream_index]; - sample = mov_seek_stream(s, st, sample_time, flags); - if (sample < 0) - return -1; - - /* adjust seek timestamp to found sample timestamp */ - seek_timestamp = st->index_entries[sample].timestamp; - - for (i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - if (stream_index == i) - continue; - - timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base); - mov_seek_stream(s, st, timestamp, flags); - } - return 0; -} - -static int mov_read_close(AVFormatContext *s) -{ - MOVContext *mov = s->priv_data; - int i, j; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MOVStreamContext *sc = st->priv_data; - - av_freep(&sc->ctts_data); - for (j = 0; j < sc->drefs_count; j++) { - av_freep(&sc->drefs[j].path); - av_freep(&sc->drefs[j].dir); - } - av_freep(&sc->drefs); - if (sc->pb && sc->pb != s->pb) - url_fclose(sc->pb); - - av_freep(&st->codec->palctrl); - } - - if (mov->dv_demux) { - for(i = 0; i < mov->dv_fctx->nb_streams; i++) { - av_freep(&mov->dv_fctx->streams[i]->codec); - av_freep(&mov->dv_fctx->streams[i]); - } - av_freep(&mov->dv_fctx); - av_freep(&mov->dv_demux); - } - - av_freep(&mov->trex_data); - - return 0; -} - -AVInputFormat mov_demuxer = { - "mov,mp4,m4a,3gp,3g2,mj2", - NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"), - sizeof(MOVContext), - mov_probe, - mov_read_header, - mov_read_packet, - mov_read_close, - mov_read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/movenc.c b/tizen/distrib/ffmpeg/libavformat/movenc.c deleted file mode 100644 index 00f6990..0000000 --- a/tizen/distrib/ffmpeg/libavformat/movenc.c +++ /dev/null @@ -1,2278 +0,0 @@ -/* - * MOV, 3GP, MP4 muxer - * Copyright (c) 2003 Thomas Raivio - * Copyright (c) 2004 Gildas Bazin - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "movenc.h" -#include "avformat.h" -#include "riff.h" -#include "avio.h" -#include "isom.h" -#include "avc.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/put_bits.h" -#include "internal.h" -#include "libavutil/avstring.h" - -#undef NDEBUG -#include - -//FIXME support 64 bit variant with wide placeholders -static int64_t updateSize(ByteIOContext *pb, int64_t pos) -{ - int64_t curpos = url_ftell(pb); - url_fseek(pb, pos, SEEK_SET); - put_be32(pb, curpos - pos); /* rewrite size */ - url_fseek(pb, curpos, SEEK_SET); - - return curpos - pos; -} - -/* Chunk offset atom */ -static int mov_write_stco_tag(ByteIOContext *pb, MOVTrack *track) -{ - int i; - int mode64 = 0; // use 32 bit size variant if possible - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - if (pos > UINT32_MAX) { - mode64 = 1; - put_tag(pb, "co64"); - } else - put_tag(pb, "stco"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, track->entry); /* entry count */ - for (i=0; ientry; i++) { - if(mode64 == 1) - put_be64(pb, track->cluster[i].pos); - else - put_be32(pb, track->cluster[i].pos); - } - return updateSize(pb, pos); -} - -/* Sample size atom */ -static int mov_write_stsz_tag(ByteIOContext *pb, MOVTrack *track) -{ - int equalChunks = 1; - int i, j, entries = 0, tst = -1, oldtst = -1; - - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "stsz"); - put_be32(pb, 0); /* version & flags */ - - for (i=0; ientry; i++) { - tst = track->cluster[i].size/track->cluster[i].entries; - if(oldtst != -1 && tst != oldtst) { - equalChunks = 0; - } - oldtst = tst; - entries += track->cluster[i].entries; - } - if (equalChunks) { - int sSize = track->cluster[0].size/track->cluster[0].entries; - put_be32(pb, sSize); // sample size - put_be32(pb, entries); // sample count - } - else { - put_be32(pb, 0); // sample size - put_be32(pb, entries); // sample count - for (i=0; ientry; i++) { - for (j=0; jcluster[i].entries; j++) { - put_be32(pb, track->cluster[i].size / - track->cluster[i].entries); - } - } - } - return updateSize(pb, pos); -} - -/* Sample to chunk atom */ -static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack *track) -{ - int index = 0, oldval = -1, i; - int64_t entryPos, curpos; - - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "stsc"); - put_be32(pb, 0); // version & flags - entryPos = url_ftell(pb); - put_be32(pb, track->entry); // entry count - for (i=0; ientry; i++) { - if(oldval != track->cluster[i].samplesInChunk) - { - put_be32(pb, i+1); // first chunk - put_be32(pb, track->cluster[i].samplesInChunk); // samples per chunk - put_be32(pb, 0x1); // sample description index - oldval = track->cluster[i].samplesInChunk; - index++; - } - } - curpos = url_ftell(pb); - url_fseek(pb, entryPos, SEEK_SET); - put_be32(pb, index); // rewrite size - url_fseek(pb, curpos, SEEK_SET); - - return updateSize(pb, pos); -} - -/* Sync sample atom */ -static int mov_write_stss_tag(ByteIOContext *pb, MOVTrack *track, uint32_t flag) -{ - int64_t curpos, entryPos; - int i, index = 0; - int64_t pos = url_ftell(pb); - put_be32(pb, 0); // size - put_tag(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps"); - put_be32(pb, 0); // version & flags - entryPos = url_ftell(pb); - put_be32(pb, track->entry); // entry count - for (i=0; ientry; i++) { - if (track->cluster[i].flags & flag) { - put_be32(pb, i+1); - index++; - } - } - curpos = url_ftell(pb); - url_fseek(pb, entryPos, SEEK_SET); - put_be32(pb, index); // rewrite size - url_fseek(pb, curpos, SEEK_SET); - return updateSize(pb, pos); -} - -static int mov_write_amr_tag(ByteIOContext *pb, MOVTrack *track) -{ - put_be32(pb, 0x11); /* size */ - if (track->mode == MODE_MOV) put_tag(pb, "samr"); - else put_tag(pb, "damr"); - put_tag(pb, "FFMP"); - put_byte(pb, 0); /* decoder version */ - - put_be16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */ - put_byte(pb, 0x00); /* Mode change period (no restriction) */ - put_byte(pb, 0x01); /* Frames per sample */ - return 0x11; -} - -static int mov_write_ac3_tag(ByteIOContext *pb, MOVTrack *track) -{ - GetBitContext gbc; - PutBitContext pbc; - uint8_t buf[3]; - int fscod, bsid, bsmod, acmod, lfeon, frmsizecod; - - if (track->vosLen < 7) - return -1; - - put_be32(pb, 11); - put_tag(pb, "dac3"); - - init_get_bits(&gbc, track->vosData+4, track->vosLen-4); - fscod = get_bits(&gbc, 2); - frmsizecod = get_bits(&gbc, 6); - bsid = get_bits(&gbc, 5); - bsmod = get_bits(&gbc, 3); - acmod = get_bits(&gbc, 3); - if (acmod == 2) { - skip_bits(&gbc, 2); // dsurmod - } else { - if ((acmod & 1) && acmod != 1) - skip_bits(&gbc, 2); // cmixlev - if (acmod & 4) - skip_bits(&gbc, 2); // surmixlev - } - lfeon = get_bits1(&gbc); - - init_put_bits(&pbc, buf, sizeof(buf)); - put_bits(&pbc, 2, fscod); - put_bits(&pbc, 5, bsid); - put_bits(&pbc, 3, bsmod); - put_bits(&pbc, 3, acmod); - put_bits(&pbc, 1, lfeon); - put_bits(&pbc, 5, frmsizecod>>1); // bit_rate_code - put_bits(&pbc, 5, 0); // reserved - - flush_put_bits(&pbc); - put_buffer(pb, buf, sizeof(buf)); - - return 11; -} - -/** - * This function writes extradata "as is". - * Extradata must be formated like a valid atom (with size and tag) - */ -static int mov_write_extradata_tag(ByteIOContext *pb, MOVTrack *track) -{ - put_buffer(pb, track->enc->extradata, track->enc->extradata_size); - return track->enc->extradata_size; -} - -static int mov_write_enda_tag(ByteIOContext *pb) -{ - put_be32(pb, 10); - put_tag(pb, "enda"); - put_be16(pb, 1); /* little endian */ - return 10; -} - -static unsigned int descrLength(unsigned int len) -{ - int i; - for(i=1; len>>(7*i); i++); - return len + 1 + i; -} - -static void putDescr(ByteIOContext *pb, int tag, unsigned int size) -{ - int i= descrLength(size) - size - 2; - put_byte(pb, tag); - for(; i>0; i--) - put_byte(pb, (size>>(7*i)) | 0x80); - put_byte(pb, size & 0x7F); -} - -static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack *track) // Basic -{ - int64_t pos = url_ftell(pb); - int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0; - - put_be32(pb, 0); // size - put_tag(pb, "esds"); - put_be32(pb, 0); // Version - - // ES descriptor - putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) + - descrLength(1)); - put_be16(pb, track->trackID); - put_byte(pb, 0x00); // flags (= no flags) - - // DecoderConfig descriptor - putDescr(pb, 0x04, 13 + decoderSpecificInfoLen); - - // Object type indication - if ((track->enc->codec_id == CODEC_ID_MP2 || - track->enc->codec_id == CODEC_ID_MP3) && - track->enc->sample_rate > 24000) - put_byte(pb, 0x6B); // 11172-3 - else - put_byte(pb, ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id)); - - // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio) - // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved) - if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - put_byte(pb, 0x15); // flags (= Audiostream) - else - put_byte(pb, 0x11); // flags (= Visualstream) - - put_byte(pb, track->enc->rc_buffer_size>>(3+16)); // Buffersize DB (24 bits) - put_be16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB - - put_be32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate)); // maxbitrate (FIXME should be max rate in any 1 sec window) - if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0) - put_be32(pb, 0); // vbr - else - put_be32(pb, track->enc->rc_max_rate); // avg bitrate - - if (track->vosLen) { - // DecoderSpecific info descriptor - putDescr(pb, 0x05, track->vosLen); - put_buffer(pb, track->vosData, track->vosLen); - } - - // SL descriptor - putDescr(pb, 0x06, 1); - put_byte(pb, 0x02); - return updateSize(pb, pos); -} - -static int mov_pcm_le_gt16(enum CodecID codec_id) -{ - return codec_id == CODEC_ID_PCM_S24LE || - codec_id == CODEC_ID_PCM_S32LE || - codec_id == CODEC_ID_PCM_F32LE || - codec_id == CODEC_ID_PCM_F64LE; -} - -static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - - put_be32(pb, 0); /* size */ - put_tag(pb, "wave"); - - put_be32(pb, 12); /* size */ - put_tag(pb, "frma"); - put_le32(pb, track->tag); - - if (track->enc->codec_id == CODEC_ID_AAC) { - /* useless atom needed by mplayer, ipod, not needed by quicktime */ - put_be32(pb, 12); /* size */ - put_tag(pb, "mp4a"); - put_be32(pb, 0); - mov_write_esds_tag(pb, track); - } else if (mov_pcm_le_gt16(track->enc->codec_id)) { - mov_write_enda_tag(pb); - } else if (track->enc->codec_id == CODEC_ID_AMR_NB) { - mov_write_amr_tag(pb, track); - } else if (track->enc->codec_id == CODEC_ID_AC3) { - mov_write_ac3_tag(pb, track); - } else if (track->enc->codec_id == CODEC_ID_ALAC) { - mov_write_extradata_tag(pb, track); - } - - put_be32(pb, 8); /* size */ - put_be32(pb, 0); /* null tag */ - - return updateSize(pb, pos); -} - -static int mov_write_glbl_tag(ByteIOContext *pb, MOVTrack *track) -{ - put_be32(pb, track->vosLen+8); - put_tag(pb, "glbl"); - put_buffer(pb, track->vosData, track->vosLen); - return 8+track->vosLen; -} - -/** - * Compute flags for 'lpcm' tag. - * See CoreAudioTypes and AudioStreamBasicDescription at Apple. - */ -static int mov_get_lpcm_flags(enum CodecID codec_id) -{ - switch (codec_id) { - case CODEC_ID_PCM_F32BE: - case CODEC_ID_PCM_F64BE: - return 11; - case CODEC_ID_PCM_F32LE: - case CODEC_ID_PCM_F64LE: - return 9; - case CODEC_ID_PCM_U8: - return 10; - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_S24BE: - case CODEC_ID_PCM_S32BE: - return 14; - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S24LE: - case CODEC_ID_PCM_S32LE: - return 12; - default: - return 0; - } -} - -static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - int version = 0; - uint32_t tag = track->tag; - - if (track->mode == MODE_MOV) { - if (track->timescale > UINT16_MAX) { - if (mov_get_lpcm_flags(track->enc->codec_id)) - tag = AV_RL32("lpcm"); - version = 2; - } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id)) { - version = 1; - } - } - - put_be32(pb, 0); /* size */ - put_le32(pb, tag); // store it byteswapped - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 0); /* Reserved */ - put_be16(pb, 1); /* Data-reference index, XXX == 1 */ - - /* SoundDescription */ - put_be16(pb, version); /* Version */ - put_be16(pb, 0); /* Revision level */ - put_be32(pb, 0); /* Reserved */ - - if (version == 2) { - put_be16(pb, 3); - put_be16(pb, 16); - put_be16(pb, 0xfffe); - put_be16(pb, 0); - put_be32(pb, 0x00010000); - put_be32(pb, 72); - put_be64(pb, av_dbl2int(track->timescale)); - put_be32(pb, track->enc->channels); - put_be32(pb, 0x7F000000); - put_be32(pb, av_get_bits_per_sample(track->enc->codec_id)); - put_be32(pb, mov_get_lpcm_flags(track->enc->codec_id)); - put_be32(pb, track->sampleSize); - put_be32(pb, track->enc->frame_size); - } else { - if (track->mode == MODE_MOV) { - put_be16(pb, track->enc->channels); - if (track->enc->codec_id == CODEC_ID_PCM_U8 || - track->enc->codec_id == CODEC_ID_PCM_S8) - put_be16(pb, 8); /* bits per sample */ - else - put_be16(pb, 16); - put_be16(pb, track->audio_vbr ? -2 : 0); /* compression ID */ - } else { /* reserved for mp4/3gp */ - put_be16(pb, 2); - put_be16(pb, 16); - put_be16(pb, 0); - } - - put_be16(pb, 0); /* packet size (= 0) */ - put_be16(pb, track->timescale); /* Time scale */ - put_be16(pb, 0); /* Reserved */ - } - - if(version == 1) { /* SoundDescription V1 extended info */ - put_be32(pb, track->enc->frame_size); /* Samples per packet */ - put_be32(pb, track->sampleSize / track->enc->channels); /* Bytes per packet */ - put_be32(pb, track->sampleSize); /* Bytes per frame */ - put_be32(pb, 2); /* Bytes per sample */ - } - - if(track->mode == MODE_MOV && - (track->enc->codec_id == CODEC_ID_AAC || - track->enc->codec_id == CODEC_ID_AC3 || - track->enc->codec_id == CODEC_ID_AMR_NB || - track->enc->codec_id == CODEC_ID_ALAC || - mov_pcm_le_gt16(track->enc->codec_id))) - mov_write_wave_tag(pb, track); - else if(track->tag == MKTAG('m','p','4','a')) - mov_write_esds_tag(pb, track); - else if(track->enc->codec_id == CODEC_ID_AMR_NB) - mov_write_amr_tag(pb, track); - else if(track->enc->codec_id == CODEC_ID_AC3) - mov_write_ac3_tag(pb, track); - else if(track->enc->codec_id == CODEC_ID_ALAC) - mov_write_extradata_tag(pb, track); - else if(track->vosLen > 0) - mov_write_glbl_tag(pb, track); - - return updateSize(pb, pos); -} - -static int mov_write_d263_tag(ByteIOContext *pb) -{ - put_be32(pb, 0xf); /* size */ - put_tag(pb, "d263"); - put_tag(pb, "FFMP"); - put_byte(pb, 0); /* decoder version */ - /* FIXME use AVCodecContext level/profile, when encoder will set values */ - put_byte(pb, 0xa); /* level */ - put_byte(pb, 0); /* profile */ - return 0xf; -} - -/* TODO: No idea about these values */ -static int mov_write_svq3_tag(ByteIOContext *pb) -{ - put_be32(pb, 0x15); - put_tag(pb, "SMI "); - put_tag(pb, "SEQH"); - put_be32(pb, 0x5); - put_be32(pb, 0xe2c0211d); - put_be32(pb, 0xc0000000); - put_byte(pb, 0); - return 0x15; -} - -static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - - put_be32(pb, 0); - put_tag(pb, "avcC"); - ff_isom_write_avcc(pb, track->vosData, track->vosLen); - return updateSize(pb, pos); -} - -/* also used by all avid codecs (dv, imx, meridien) and their variants */ -static int mov_write_avid_tag(ByteIOContext *pb, MOVTrack *track) -{ - int i; - put_be32(pb, 24); /* size */ - put_tag(pb, "ACLR"); - put_tag(pb, "ACLR"); - put_tag(pb, "0001"); - put_be32(pb, 1); /* yuv 1 / rgb 2 ? */ - put_be32(pb, 0); /* unknown */ - - put_be32(pb, 24); /* size */ - put_tag(pb, "APRG"); - put_tag(pb, "APRG"); - put_tag(pb, "0001"); - put_be32(pb, 1); /* unknown */ - put_be32(pb, 0); /* unknown */ - - put_be32(pb, 120); /* size */ - put_tag(pb, "ARES"); - put_tag(pb, "ARES"); - put_tag(pb, "0001"); - put_be32(pb, AV_RB32(track->vosData + 0x28)); /* dnxhd cid, some id ? */ - put_be32(pb, track->enc->width); - /* values below are based on samples created with quicktime and avid codecs */ - if (track->vosData[5] & 2) { // interlaced - put_be32(pb, track->enc->height/2); - put_be32(pb, 2); /* unknown */ - put_be32(pb, 0); /* unknown */ - put_be32(pb, 4); /* unknown */ - } else { - put_be32(pb, track->enc->height); - put_be32(pb, 1); /* unknown */ - put_be32(pb, 0); /* unknown */ - if (track->enc->height == 1080) - put_be32(pb, 5); /* unknown */ - else - put_be32(pb, 6); /* unknown */ - } - /* padding */ - for (i = 0; i < 10; i++) - put_be64(pb, 0); - - /* extra padding for stsd needed */ - put_be32(pb, 0); - return 0; -} - -static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - - if (!ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id)) - return 0; - - if (track->enc->codec_id == CODEC_ID_H264) tag = MKTAG('a','v','c','1'); - else if (track->enc->codec_id == CODEC_ID_AC3) tag = MKTAG('a','c','-','3'); - else if (track->enc->codec_id == CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c'); - else if (track->enc->codec_id == CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g'); - else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v'); - else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a'); - - return tag; -} - -static const AVCodecTag codec_ipod_tags[] = { - { CODEC_ID_H264, MKTAG('a','v','c','1') }, - { CODEC_ID_MPEG4, MKTAG('m','p','4','v') }, - { CODEC_ID_AAC, MKTAG('m','p','4','a') }, - { CODEC_ID_ALAC, MKTAG('a','l','a','c') }, - { CODEC_ID_AC3, MKTAG('a','c','-','3') }, - { CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') }, - { CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') }, - { CODEC_ID_NONE, 0 }, -}; - -static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - - // keep original tag for subs, ipod supports both formats - if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE && - (tag == MKTAG('t','x','3','g') || - tag == MKTAG('t','e','x','t')))) - tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id); - - if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v")) - av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v " - "Quicktime/Ipod might not play the file\n"); - - return tag; -} - -static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag; - - if (track->enc->height == 480) /* NTSC */ - if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n'); - else tag = MKTAG('d','v','c',' '); - else if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p'); - else if (track->enc->pix_fmt == PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p'); - else tag = MKTAG('d','v','p','p'); - - return tag; -} - -static const struct { - enum PixelFormat pix_fmt; - uint32_t tag; - unsigned bps; -} mov_pix_fmt_tags[] = { - { PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 }, - { PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 }, - { PIX_FMT_BGR555, MKTAG('r','a','w',' '), 16 }, - { PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 }, - { PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 }, - { PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 }, - { PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 }, - { PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 }, - { PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 }, - { PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 }, - { PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 }, -}; - -static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) { - if (track->enc->pix_fmt == mov_pix_fmt_tags[i].pix_fmt) { - tag = mov_pix_fmt_tags[i].tag; - track->enc->bits_per_coded_sample = mov_pix_fmt_tags[i].bps; - break; - } - } - - return tag; -} - -static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - - if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL && - (tag == MKTAG('d','v','c','p') || - track->enc->codec_id == CODEC_ID_RAWVIDEO || - av_get_bits_per_sample(track->enc->codec_id)))) { // pcm audio - if (track->enc->codec_id == CODEC_ID_DVVIDEO) - tag = mov_get_dv_codec_tag(s, track); - else if (track->enc->codec_id == CODEC_ID_RAWVIDEO) - tag = mov_get_rawvideo_codec_tag(s, track); - else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { - tag = ff_codec_get_tag(codec_movvideo_tags, track->enc->codec_id); - if (!tag) { // if no mac fcc found, try with Microsoft tags - tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id); - if (tag) - av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, " - "the file may be unplayable!\n"); - } - } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) { - tag = ff_codec_get_tag(codec_movaudio_tags, track->enc->codec_id); - if (!tag) { // if no mac fcc found, try with Microsoft tags - int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id); - if (ms_tag) { - tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff)); - av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, " - "the file may be unplayable!\n"); - } - } - } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) - tag = ff_codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id); - } - - return tag; -} - -static const AVCodecTag codec_3gp_tags[] = { - { CODEC_ID_H263, MKTAG('s','2','6','3') }, - { CODEC_ID_H264, MKTAG('a','v','c','1') }, - { CODEC_ID_MPEG4, MKTAG('m','p','4','v') }, - { CODEC_ID_AAC, MKTAG('m','p','4','a') }, - { CODEC_ID_AMR_NB, MKTAG('s','a','m','r') }, - { CODEC_ID_AMR_WB, MKTAG('s','a','w','b') }, - { CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') }, - { CODEC_ID_NONE, 0 }, -}; - -static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - - if (track->mode == MODE_MP4 || track->mode == MODE_PSP) - tag = mp4_get_codec_tag(s, track); - else if (track->mode == MODE_IPOD) - tag = ipod_get_codec_tag(s, track); - else if (track->mode & MODE_3GP) - tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id); - else - tag = mov_get_codec_tag(s, track); - - return tag; -} - -/** Write uuid atom. - * Needed to make file play in iPods running newest firmware - * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1 - */ -static int mov_write_uuid_tag_ipod(ByteIOContext *pb) -{ - put_be32(pb, 28); - put_tag(pb, "uuid"); - put_be32(pb, 0x6b6840f2); - put_be32(pb, 0x5f244fc5); - put_be32(pb, 0xba39a51b); - put_be32(pb, 0xcf0323f3); - put_be32(pb, 0x0); - return 28; -} - -static int mov_write_subtitle_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_le32(pb, track->tag); // store it byteswapped - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 0); /* Reserved */ - put_be16(pb, 1); /* Data-reference index */ - - if (track->enc->extradata_size) - put_buffer(pb, track->enc->extradata, track->enc->extradata_size); - - return updateSize(pb, pos); -} - -static int mov_write_video_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - char compressor_name[32]; - - put_be32(pb, 0); /* size */ - put_le32(pb, track->tag); // store it byteswapped - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 0); /* Reserved */ - put_be16(pb, 1); /* Data-reference index */ - - put_be16(pb, 0); /* Codec stream version */ - put_be16(pb, 0); /* Codec stream revision (=0) */ - if (track->mode == MODE_MOV) { - put_tag(pb, "FFMP"); /* Vendor */ - if(track->enc->codec_id == CODEC_ID_RAWVIDEO) { - put_be32(pb, 0); /* Temporal Quality */ - put_be32(pb, 0x400); /* Spatial Quality = lossless*/ - } else { - put_be32(pb, 0x200); /* Temporal Quality = normal */ - put_be32(pb, 0x200); /* Spatial Quality = normal */ - } - } else { - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - put_be32(pb, 0); /* Reserved */ - } - put_be16(pb, track->enc->width); /* Video width */ - put_be16(pb, track->height); /* Video height */ - put_be32(pb, 0x00480000); /* Horizontal resolution 72dpi */ - put_be32(pb, 0x00480000); /* Vertical resolution 72dpi */ - put_be32(pb, 0); /* Data size (= 0) */ - put_be16(pb, 1); /* Frame count (= 1) */ - - memset(compressor_name,0,32); - /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */ - if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name) - strncpy(compressor_name,track->enc->codec->name,31); - put_byte(pb, strlen(compressor_name)); - put_buffer(pb, compressor_name, 31); - - if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample) - put_be16(pb, track->enc->bits_per_coded_sample); - else - put_be16(pb, 0x18); /* Reserved */ - put_be16(pb, 0xffff); /* Reserved */ - if(track->tag == MKTAG('m','p','4','v')) - mov_write_esds_tag(pb, track); - else if(track->enc->codec_id == CODEC_ID_H263) - mov_write_d263_tag(pb); - else if(track->enc->codec_id == CODEC_ID_SVQ3) - mov_write_svq3_tag(pb); - else if(track->enc->codec_id == CODEC_ID_DNXHD) - mov_write_avid_tag(pb, track); - else if(track->enc->codec_id == CODEC_ID_H264) { - mov_write_avcc_tag(pb, track); - if(track->mode == MODE_IPOD) - mov_write_uuid_tag_ipod(pb); - } else if(track->vosLen > 0) - mov_write_glbl_tag(pb, track); - - return updateSize(pb, pos); -} - -static int mov_write_rtp_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "rtp "); - put_be32(pb, 0); /* Reserved */ - put_be16(pb, 0); /* Reserved */ - put_be16(pb, 1); /* Data-reference index */ - - put_be16(pb, 1); /* Hint track version */ - put_be16(pb, 1); /* Highest compatible version */ - put_be32(pb, track->max_packet_size); /* Max packet size */ - - put_be32(pb, 12); /* size */ - put_tag(pb, "tims"); - put_be32(pb, track->timescale); - - return updateSize(pb, pos); -} - -static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "stsd"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, 1); /* entry count */ - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) - mov_write_video_tag(pb, track); - else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - mov_write_audio_tag(pb, track); - else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) - mov_write_subtitle_tag(pb, track); - else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) - mov_write_rtp_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_ctts_tag(ByteIOContext *pb, MOVTrack *track) -{ - MOVStts *ctts_entries; - uint32_t entries = 0; - uint32_t atom_size; - int i; - - ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */ - ctts_entries[0].count = 1; - ctts_entries[0].duration = track->cluster[0].cts; - for (i=1; ientry; i++) { - if (track->cluster[i].cts == ctts_entries[entries].duration) { - ctts_entries[entries].count++; /* compress */ - } else { - entries++; - ctts_entries[entries].duration = track->cluster[i].cts; - ctts_entries[entries].count = 1; - } - } - entries++; /* last one */ - atom_size = 16 + (entries * 8); - put_be32(pb, atom_size); /* size */ - put_tag(pb, "ctts"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, entries); /* entry count */ - for (i=0; ienc->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) { - stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */ - stts_entries[0].count = track->sampleCount; - stts_entries[0].duration = 1; - entries = 1; - } else { - stts_entries = av_malloc(track->entry * sizeof(*stts_entries)); /* worst case */ - for (i=0; ientry; i++) { - int64_t duration = i + 1 == track->entry ? - track->trackDuration - track->cluster[i].dts + track->cluster[0].dts : /* readjusting */ - track->cluster[i+1].dts - track->cluster[i].dts; - if (i && duration == stts_entries[entries].duration) { - stts_entries[entries].count++; /* compress */ - } else { - entries++; - stts_entries[entries].duration = duration; - stts_entries[entries].count = 1; - } - } - entries++; /* last one */ - } - atom_size = 16 + (entries * 8); - put_be32(pb, atom_size); /* size */ - put_tag(pb, "stts"); - put_be32(pb, 0); /* version & flags */ - put_be32(pb, entries); /* entry count */ - for (i=0; ienc->codec_type == AVMEDIA_TYPE_VIDEO || - track->enc->codec_tag == MKTAG('r','t','p',' ')) && - track->hasKeyframes && track->hasKeyframes < track->entry) - mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE); - if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS) - mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE); - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && - track->flags & MOV_TRACK_CTTS) - mov_write_ctts_tag(pb, track); - mov_write_stsc_tag(pb, track); - mov_write_stsz_tag(pb, track); - mov_write_stco_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_dinf_tag(ByteIOContext *pb) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "dinf"); - mov_write_dref_tag(pb); - return updateSize(pb, pos); -} - -static int mov_write_nmhd_tag(ByteIOContext *pb) -{ - put_be32(pb, 12); - put_tag(pb, "nmhd"); - put_be32(pb, 0); - return 12; -} - -static int mov_write_gmhd_tag(ByteIOContext *pb) -{ - put_be32(pb, 0x20); /* size */ - put_tag(pb, "gmhd"); - put_be32(pb, 0x18); /* gmin size */ - put_tag(pb, "gmin"); /* generic media info */ - put_be32(pb, 0); /* version & flags */ - put_be16(pb, 0x40); /* graphics mode = */ - put_be16(pb, 0x8000); /* opColor (r?) */ - put_be16(pb, 0x8000); /* opColor (g?) */ - put_be16(pb, 0x8000); /* opColor (b?) */ - put_be16(pb, 0); /* balance */ - put_be16(pb, 0); /* reserved */ - return 0x20; -} - -static int mov_write_smhd_tag(ByteIOContext *pb) -{ - put_be32(pb, 16); /* size */ - put_tag(pb, "smhd"); - put_be32(pb, 0); /* version & flags */ - put_be16(pb, 0); /* reserved (balance, normally = 0) */ - put_be16(pb, 0); /* reserved */ - return 16; -} - -static int mov_write_vmhd_tag(ByteIOContext *pb) -{ - put_be32(pb, 0x14); /* size (always 0x14) */ - put_tag(pb, "vmhd"); - put_be32(pb, 0x01); /* version & flags */ - put_be64(pb, 0); /* reserved (graphics mode = copy) */ - return 0x14; -} - -static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack *track) -{ - const char *hdlr, *descr = NULL, *hdlr_type = NULL; - int64_t pos = url_ftell(pb); - - if (!track) { /* no media --> data handler */ - hdlr = "dhlr"; - hdlr_type = "url "; - descr = "DataHandler"; - } else { - hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0"; - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { - hdlr_type = "vide"; - descr = "VideoHandler"; - } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) { - hdlr_type = "soun"; - descr = "SoundHandler"; - } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) { - if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl"; - else hdlr_type = "text"; - descr = "SubtitleHandler"; - } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) { - hdlr_type = "hint"; - descr = "HintHandler"; - } - } - - put_be32(pb, 0); /* size */ - put_tag(pb, "hdlr"); - put_be32(pb, 0); /* Version & flags */ - put_buffer(pb, hdlr, 4); /* handler */ - put_tag(pb, hdlr_type); /* handler type */ - put_be32(pb ,0); /* reserved */ - put_be32(pb ,0); /* reserved */ - put_be32(pb ,0); /* reserved */ - if (!track || track->mode == MODE_MOV) - put_byte(pb, strlen(descr)); /* pascal string */ - put_buffer(pb, descr, strlen(descr)); /* handler description */ - if (track && track->mode != MODE_MOV) - put_byte(pb, 0); /* c string */ - return updateSize(pb, pos); -} - -static int mov_write_hmhd_tag(ByteIOContext *pb) -{ - /* This atom must be present, but leaving the values at zero - * seems harmless. */ - put_be32(pb, 28); /* size */ - put_tag(pb, "hmhd"); - put_be32(pb, 0); /* version, flags */ - put_be16(pb, 0); /* maxPDUsize */ - put_be16(pb, 0); /* avgPDUsize */ - put_be32(pb, 0); /* maxbitrate */ - put_be32(pb, 0); /* avgbitrate */ - put_be32(pb, 0); /* reserved */ - return 28; -} - -static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "minf"); - if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO) - mov_write_vmhd_tag(pb); - else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - mov_write_smhd_tag(pb); - else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) { - if (track->tag == MKTAG('t','e','x','t')) mov_write_gmhd_tag(pb); - else mov_write_nmhd_tag(pb); - } else if (track->tag == MKTAG('r','t','p',' ')) { - mov_write_hmhd_tag(pb); - } - if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */ - mov_write_hdlr_tag(pb, NULL); - mov_write_dinf_tag(pb); - mov_write_stbl_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack *track) -{ - int version = track->trackDuration < INT32_MAX ? 0 : 1; - - (version == 1) ? put_be32(pb, 44) : put_be32(pb, 32); /* size */ - put_tag(pb, "mdhd"); - put_byte(pb, version); - put_be24(pb, 0); /* flags */ - if (version == 1) { - put_be64(pb, track->time); - put_be64(pb, track->time); - } else { - put_be32(pb, track->time); /* creation time */ - put_be32(pb, track->time); /* modification time */ - } - put_be32(pb, track->timescale); /* time scale (sample rate for audio) */ - (version == 1) ? put_be64(pb, track->trackDuration) : put_be32(pb, track->trackDuration); /* duration */ - put_be16(pb, track->language); /* language */ - put_be16(pb, 0); /* reserved (quality) */ - - if(version!=0 && track->mode == MODE_MOV){ - av_log(NULL, AV_LOG_ERROR, - "FATAL error, file duration too long for timebase, this file will not be\n" - "playable with quicktime. Choose a different timebase or a different\n" - "container format\n"); - } - - return 32; -} - -static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack *track) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "mdia"); - mov_write_mdhd_tag(pb, track); - mov_write_hdlr_tag(pb, track); - mov_write_minf_tag(pb, track); - return updateSize(pb, pos); -} - -static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st) -{ - int64_t duration = av_rescale_rnd(track->trackDuration, MOV_TIMESCALE, - track->timescale, AV_ROUND_UP); - int version = duration < INT32_MAX ? 0 : 1; - - (version == 1) ? put_be32(pb, 104) : put_be32(pb, 92); /* size */ - put_tag(pb, "tkhd"); - put_byte(pb, version); - put_be24(pb, 0xf); /* flags (track enabled) */ - if (version == 1) { - put_be64(pb, track->time); - put_be64(pb, track->time); - } else { - put_be32(pb, track->time); /* creation time */ - put_be32(pb, track->time); /* modification time */ - } - put_be32(pb, track->trackID); /* track-id */ - put_be32(pb, 0); /* reserved */ - (version == 1) ? put_be64(pb, duration) : put_be32(pb, duration); - - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */ - /* Volume, only for audio */ - if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - put_be16(pb, 0x0100); - else - put_be16(pb, 0); - put_be16(pb, 0); /* reserved */ - - /* Matrix structure */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x40000000); /* reserved */ - - /* Track width and height, for visual only */ - if(st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO || - track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) { - double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio); - if(!sample_aspect_ratio || track->height != track->enc->height) - sample_aspect_ratio = 1; - put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000); - put_be32(pb, track->height*0x10000); - } - else { - put_be32(pb, 0); - put_be32(pb, 0); - } - return 0x5c; -} - -// This box seems important for the psp playback ... without it the movie seems to hang -static int mov_write_edts_tag(ByteIOContext *pb, MOVTrack *track) -{ - put_be32(pb, 0x24); /* size */ - put_tag(pb, "edts"); - put_be32(pb, 0x1c); /* size */ - put_tag(pb, "elst"); - put_be32(pb, 0x0); - put_be32(pb, 0x1); - - /* duration ... doesn't seem to effect psp */ - put_be32(pb, av_rescale_rnd(track->trackDuration, MOV_TIMESCALE, - track->timescale, AV_ROUND_UP)); - - put_be32(pb, track->cluster[0].cts); /* first pts is cts since dts is 0 */ - put_be32(pb, 0x00010000); - return 0x24; -} - -static int mov_write_tref_tag(ByteIOContext *pb, MOVTrack *track) -{ - put_be32(pb, 20); // size - put_tag(pb, "tref"); - put_be32(pb, 12); // size (subatom) - put_le32(pb, track->tref_tag); - put_be32(pb, track->tref_id); - return 20; -} - -// goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it) -static int mov_write_uuid_tag_psp(ByteIOContext *pb, MOVTrack *mov) -{ - put_be32(pb, 0x34); /* size ... reports as 28 in mp4box! */ - put_tag(pb, "uuid"); - put_tag(pb, "USMT"); - put_be32(pb, 0x21d24fce); - put_be32(pb, 0xbb88695c); - put_be32(pb, 0xfac9c740); - put_be32(pb, 0x1c); // another size here! - put_tag(pb, "MTDT"); - put_be32(pb, 0x00010012); - put_be32(pb, 0x0a); - put_be32(pb, 0x55c40000); - put_be32(pb, 0x1); - put_be32(pb, 0x0); - return 0x34; -} - -static int mov_write_udta_sdp(ByteIOContext *pb, AVCodecContext *ctx, int index) -{ - char buf[1000] = ""; - int len; - - ff_sdp_write_media(buf, sizeof(buf), ctx, NULL, 0, 0); - av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", index); - len = strlen(buf); - - put_be32(pb, len + 24); - put_tag (pb, "udta"); - put_be32(pb, len + 16); - put_tag (pb, "hnti"); - put_be32(pb, len + 8); - put_tag (pb, "sdp "); - put_buffer(pb, buf, len); - return len + 24; -} - -static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "trak"); - mov_write_tkhd_tag(pb, track, st); - if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS) - mov_write_edts_tag(pb, track); // PSP Movies require edts box - if (track->tref_tag) - mov_write_tref_tag(pb, track); - mov_write_mdia_tag(pb, track); - if (track->mode == MODE_PSP) - mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box - if (track->tag == MKTAG('r','t','p',' ')) - mov_write_udta_sdp(pb, track->rtp_ctx->streams[0]->codec, track->trackID); - return updateSize(pb, pos); -} - -#if 0 -/* TODO: Not sorted out, but not necessary either */ -static int mov_write_iods_tag(ByteIOContext *pb, MOVMuxContext *mov) -{ - put_be32(pb, 0x15); /* size */ - put_tag(pb, "iods"); - put_be32(pb, 0); /* version & flags */ - put_be16(pb, 0x1007); - put_byte(pb, 0); - put_be16(pb, 0x4fff); - put_be16(pb, 0xfffe); - put_be16(pb, 0x01ff); - return 0x15; -} -#endif - -static int mov_write_mvhd_tag(ByteIOContext *pb, MOVMuxContext *mov) -{ - int maxTrackID = 1, i; - int64_t maxTrackLenTemp, maxTrackLen = 0; - int version; - - for (i=0; inb_streams; i++) { - if(mov->tracks[i].entry > 0) { - maxTrackLenTemp = av_rescale_rnd(mov->tracks[i].trackDuration, - MOV_TIMESCALE, - mov->tracks[i].timescale, - AV_ROUND_UP); - if(maxTrackLen < maxTrackLenTemp) - maxTrackLen = maxTrackLenTemp; - if(maxTrackID < mov->tracks[i].trackID) - maxTrackID = mov->tracks[i].trackID; - } - } - - version = maxTrackLen < UINT32_MAX ? 0 : 1; - (version == 1) ? put_be32(pb, 120) : put_be32(pb, 108); /* size */ - put_tag(pb, "mvhd"); - put_byte(pb, version); - put_be24(pb, 0); /* flags */ - if (version == 1) { - put_be64(pb, mov->time); - put_be64(pb, mov->time); - } else { - put_be32(pb, mov->time); /* creation time */ - put_be32(pb, mov->time); /* modification time */ - } - put_be32(pb, MOV_TIMESCALE); - (version == 1) ? put_be64(pb, maxTrackLen) : put_be32(pb, maxTrackLen); /* duration of longest track */ - - put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */ - put_be16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */ - put_be16(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - - /* Matrix structure */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x00010000); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x0); /* reserved */ - put_be32(pb, 0x40000000); /* reserved */ - - put_be32(pb, 0); /* reserved (preview time) */ - put_be32(pb, 0); /* reserved (preview duration) */ - put_be32(pb, 0); /* reserved (poster time) */ - put_be32(pb, 0); /* reserved (selection time) */ - put_be32(pb, 0); /* reserved (selection duration) */ - put_be32(pb, 0); /* reserved (current time) */ - put_be32(pb, maxTrackID+1); /* Next track id */ - return 0x6c; -} - -static int mov_write_itunes_hdlr_tag(ByteIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - put_be32(pb, 33); /* size */ - put_tag(pb, "hdlr"); - put_be32(pb, 0); - put_be32(pb, 0); - put_tag(pb, "mdir"); - put_tag(pb, "appl"); - put_be32(pb, 0); - put_be32(pb, 0); - put_byte(pb, 0); - return 33; -} - -/* helper function to write a data tag with the specified string as data */ -static int mov_write_string_data_tag(ByteIOContext *pb, const char *data, int lang, int long_style) -{ - if(long_style){ - int size = 16 + strlen(data); - put_be32(pb, size); /* size */ - put_tag(pb, "data"); - put_be32(pb, 1); - put_be32(pb, 0); - put_buffer(pb, data, strlen(data)); - return size; - }else{ - if (!lang) - lang = ff_mov_iso639_to_lang("und", 1); - put_be16(pb, strlen(data)); /* string length */ - put_be16(pb, lang); - put_buffer(pb, data, strlen(data)); - return strlen(data) + 4; - } -} - -static int mov_write_string_tag(ByteIOContext *pb, const char *name, const char *value, int lang, int long_style){ - int size = 0; - if (value && value[0]) { - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, name); - mov_write_string_data_tag(pb, value, lang, long_style); - size= updateSize(pb, pos); - } - return size; -} - -static int mov_write_string_metadata(AVFormatContext *s, ByteIOContext *pb, - const char *name, const char *tag, - int long_style) -{ - int l, lang = 0, len, len2; - AVMetadataTag *t, *t2 = NULL; - char tag2[16]; - - if (!(t = av_metadata_get(s->metadata, tag, NULL, 0))) - return 0; - - len = strlen(t->key); - snprintf(tag2, sizeof(tag2), "%s-", tag); - while ((t2 = av_metadata_get(s->metadata, tag2, t2, AV_METADATA_IGNORE_SUFFIX))) { - len2 = strlen(t2->key); - if (len2 == len+4 && !strcmp(t->value, t2->value) - && (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) { - lang = l; - break; - } - } - return mov_write_string_tag(pb, name, t->value, lang, long_style); -} - -/* iTunes track number */ -static int mov_write_trkn_tag(ByteIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - AVMetadataTag *t = av_metadata_get(s->metadata, "track", NULL, 0); - int size = 0, track = t ? atoi(t->value) : 0; - if (track) { - put_be32(pb, 32); /* size */ - put_tag(pb, "trkn"); - put_be32(pb, 24); /* size */ - put_tag(pb, "data"); - put_be32(pb, 0); // 8 bytes empty - put_be32(pb, 0); - put_be16(pb, 0); // empty - put_be16(pb, track); // track number - put_be16(pb, 0); // total track number - put_be16(pb, 0); // empty - size = 32; - } - return size; -} - -/* iTunes meta data list */ -static int mov_write_ilst_tag(ByteIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "ilst"); - mov_write_string_metadata(s, pb, "\251nam", "title" , 1); - mov_write_string_metadata(s, pb, "\251ART", "artist" , 1); - mov_write_string_metadata(s, pb, "aART", "album_artist", 1); - mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1); - mov_write_string_metadata(s, pb, "\251alb", "album" , 1); - mov_write_string_metadata(s, pb, "\251day", "date" , 1); - mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1); - mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1); - mov_write_string_metadata(s, pb, "\251gen", "genre" , 1); - mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1); - mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1); - mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1); - mov_write_string_metadata(s, pb, "desc", "description",1); - mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1); - mov_write_string_metadata(s, pb, "tvsh", "show" , 1); - mov_write_string_metadata(s, pb, "tven", "episode_id",1); - mov_write_string_metadata(s, pb, "tvnn", "network" , 1); - mov_write_trkn_tag(pb, mov, s); - return updateSize(pb, pos); -} - -/* iTunes meta data tag */ -static int mov_write_meta_tag(ByteIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - int size = 0; - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size */ - put_tag(pb, "meta"); - put_be32(pb, 0); - mov_write_itunes_hdlr_tag(pb, mov, s); - mov_write_ilst_tag(pb, mov, s); - size = updateSize(pb, pos); - return size; -} - -static int utf8len(const uint8_t *b) -{ - int len=0; - int val; - while(*b){ - GET_UTF8(val, *b++, return -1;) - len++; - } - return len; -} - -static int ascii_to_wc(ByteIOContext *pb, const uint8_t *b) -{ - int val; - while(*b){ - GET_UTF8(val, *b++, return -1;) - put_be16(pb, val); - } - put_be16(pb, 0x00); - return 0; -} - -static uint16_t language_code(const char *str) -{ - return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F); -} - -static int mov_write_3gp_udta_tag(ByteIOContext *pb, AVFormatContext *s, - const char *tag, const char *str) -{ - int64_t pos = url_ftell(pb); - AVMetadataTag *t = av_metadata_get(s->metadata, str, NULL, 0); - if (!t || !utf8len(t->value)) - return 0; - put_be32(pb, 0); /* size */ - put_tag (pb, tag); /* type */ - put_be32(pb, 0); /* version + flags */ - if (!strcmp(tag, "yrrc")) - put_be16(pb, atoi(t->value)); - else { - put_be16(pb, language_code("eng")); /* language */ - put_buffer(pb, t->value, strlen(t->value)+1); /* UTF8 string value */ - if (!strcmp(tag, "albm") && - (t = av_metadata_get(s->metadata, "date", NULL, 0))) - put_byte(pb, atoi(t->value)); - } - return updateSize(pb, pos); -} - -static int mov_write_chpl_tag(ByteIOContext *pb, AVFormatContext *s) -{ - int64_t pos = url_ftell(pb); - int i, nb_chapters = FFMIN(s->nb_chapters, 255); - - put_be32(pb, 0); // size - put_tag (pb, "chpl"); - put_be32(pb, 0x01000000); // version + flags - put_be32(pb, 0); // unknown - put_byte(pb, nb_chapters); - - for (i = 0; i < nb_chapters; i++) { - AVChapter *c = s->chapters[i]; - AVMetadataTag *t; - put_be64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000})); - - if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) { - int len = FFMIN(strlen(t->value), 255); - put_byte(pb, len); - put_buffer(pb, t->value, len); - } else - put_byte(pb, 0); - } - return updateSize(pb, pos); -} - -static int mov_write_udta_tag(ByteIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - ByteIOContext *pb_buf; - int i, ret, size; - uint8_t *buf; - - for (i = 0; i < s->nb_streams; i++) - if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) { - return 0; - } - - ret = url_open_dyn_buf(&pb_buf); - if(ret < 0) - return ret; - - if (mov->mode & MODE_3GP) { - mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist"); - mov_write_3gp_udta_tag(pb_buf, s, "titl", "title"); - mov_write_3gp_udta_tag(pb_buf, s, "auth", "author"); - mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre"); - mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment"); - mov_write_3gp_udta_tag(pb_buf, s, "albm", "album"); - mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright"); - mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date"); - } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4 - mov_write_string_metadata(s, pb_buf, "\251nam", "title" , 0); - mov_write_string_metadata(s, pb_buf, "\251aut", "author" , 0); - mov_write_string_metadata(s, pb_buf, "\251alb", "album" , 0); - mov_write_string_metadata(s, pb_buf, "\251day", "date" , 0); - mov_write_string_tag(pb_buf, "\251enc", LIBAVFORMAT_IDENT, 0, 0); - mov_write_string_metadata(s, pb_buf, "\251des", "comment" , 0); - mov_write_string_metadata(s, pb_buf, "\251gen", "genre" , 0); - mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright" , 0); - } else { - /* iTunes meta data */ - mov_write_meta_tag(pb_buf, mov, s); - } - - if (s->nb_chapters) - mov_write_chpl_tag(pb_buf, s); - - if ((size = url_close_dyn_buf(pb_buf, &buf)) > 0) { - put_be32(pb, size+8); - put_tag(pb, "udta"); - put_buffer(pb, buf, size); - av_free(buf); - } - - return 0; -} - -static void mov_write_psp_udta_tag(ByteIOContext *pb, - const char *str, const char *lang, int type) -{ - int len = utf8len(str)+1; - if(len<=0) - return; - put_be16(pb, len*2+10); /* size */ - put_be32(pb, type); /* type */ - put_be16(pb, language_code(lang)); /* language */ - put_be16(pb, 0x01); /* ? */ - ascii_to_wc(pb, str); -} - -static int mov_write_uuidusmt_tag(ByteIOContext *pb, AVFormatContext *s) -{ - AVMetadataTag *title = av_metadata_get(s->metadata, "title", NULL, 0); - int64_t pos, pos2; - - if (title) { - pos = url_ftell(pb); - put_be32(pb, 0); /* size placeholder*/ - put_tag(pb, "uuid"); - put_tag(pb, "USMT"); - put_be32(pb, 0x21d24fce); /* 96 bit UUID */ - put_be32(pb, 0xbb88695c); - put_be32(pb, 0xfac9c740); - - pos2 = url_ftell(pb); - put_be32(pb, 0); /* size placeholder*/ - put_tag(pb, "MTDT"); - put_be16(pb, 4); - - // ? - put_be16(pb, 0x0C); /* size */ - put_be32(pb, 0x0B); /* type */ - put_be16(pb, language_code("und")); /* language */ - put_be16(pb, 0x0); /* ? */ - put_be16(pb, 0x021C); /* data */ - - mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04); - mov_write_psp_udta_tag(pb, title->value, "eng", 0x01); -// snprintf(dt,32,"%04d/%02d/%02d %02d:%02d:%02d",t_st->tm_year+1900,t_st->tm_mon+1,t_st->tm_mday,t_st->tm_hour,t_st->tm_min,t_st->tm_sec); - mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03); - - updateSize(pb, pos2); - return updateSize(pb, pos); - } - - return 0; -} - -static int mov_write_moov_tag(ByteIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - int i; - int64_t pos = url_ftell(pb); - put_be32(pb, 0); /* size placeholder*/ - put_tag(pb, "moov"); - - for (i=0; inb_streams; i++) { - if(mov->tracks[i].entry <= 0) continue; - - mov->tracks[i].time = mov->time; - mov->tracks[i].trackID = i+1; - } - - if (mov->chapter_track) - for (i=0; inb_streams; i++) { - mov->tracks[i].tref_tag = MKTAG('c','h','a','p'); - mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].trackID; - } - for (i = 0; i < mov->nb_streams; i++) { - if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) { - mov->tracks[i].tref_tag = MKTAG('h','i','n','t'); - mov->tracks[i].tref_id = - mov->tracks[mov->tracks[i].src_track].trackID; - } - } - - mov_write_mvhd_tag(pb, mov); - //mov_write_iods_tag(pb, mov); - for (i=0; inb_streams; i++) { - if(mov->tracks[i].entry > 0) { - mov_write_trak_tag(pb, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL); - } - } - - if (mov->mode == MODE_PSP) - mov_write_uuidusmt_tag(pb, s); - else - mov_write_udta_tag(pb, mov, s); - - return updateSize(pb, pos); -} - -static int mov_write_mdat_tag(ByteIOContext *pb, MOVMuxContext *mov) -{ - put_be32(pb, 8); // placeholder for extended size field (64 bit) - put_tag(pb, mov->mode == MODE_MOV ? "wide" : "free"); - - mov->mdat_pos = url_ftell(pb); - put_be32(pb, 0); /* size placeholder*/ - put_tag(pb, "mdat"); - return 0; -} - -/* TODO: This needs to be more general */ -static int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s) -{ - MOVMuxContext *mov = s->priv_data; - int64_t pos = url_ftell(pb); - int has_h264 = 0, has_video = 0; - int minor = 0x200; - int i; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - has_video = 1; - if (st->codec->codec_id == CODEC_ID_H264) - has_h264 = 1; - } - - put_be32(pb, 0); /* size */ - put_tag(pb, "ftyp"); - - if (mov->mode == MODE_3GP) { - put_tag(pb, has_h264 ? "3gp6" : "3gp4"); - minor = has_h264 ? 0x100 : 0x200; - } else if (mov->mode & MODE_3G2) { - put_tag(pb, has_h264 ? "3g2b" : "3g2a"); - minor = has_h264 ? 0x20000 : 0x10000; - }else if (mov->mode == MODE_PSP) - put_tag(pb, "MSNV"); - else if (mov->mode == MODE_MP4) - put_tag(pb, "isom"); - else if (mov->mode == MODE_IPOD) - put_tag(pb, has_video ? "M4V ":"M4A "); - else - put_tag(pb, "qt "); - - put_be32(pb, minor); - - if(mov->mode == MODE_MOV) - put_tag(pb, "qt "); - else{ - put_tag(pb, "isom"); - put_tag(pb, "iso2"); - if(has_h264) - put_tag(pb, "avc1"); - } - - if (mov->mode == MODE_3GP) - put_tag(pb, has_h264 ? "3gp6":"3gp4"); - else if (mov->mode & MODE_3G2) - put_tag(pb, has_h264 ? "3g2b":"3g2a"); - else if (mov->mode == MODE_PSP) - put_tag(pb, "MSNV"); - else if (mov->mode == MODE_MP4) - put_tag(pb, "mp41"); - return updateSize(pb, pos); -} - -static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s) -{ - AVCodecContext *VideoCodec = s->streams[0]->codec; - AVCodecContext *AudioCodec = s->streams[1]->codec; - int AudioRate = AudioCodec->sample_rate; - int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num); - int audio_kbitrate= AudioCodec->bit_rate / 1000; - int video_kbitrate= FFMIN(VideoCodec->bit_rate / 1000, 800 - audio_kbitrate); - - put_be32(pb, 0x94); /* size */ - put_tag(pb, "uuid"); - put_tag(pb, "PROF"); - - put_be32(pb, 0x21d24fce); /* 96 bit UUID */ - put_be32(pb, 0xbb88695c); - put_be32(pb, 0xfac9c740); - - put_be32(pb, 0x0); /* ? */ - put_be32(pb, 0x3); /* 3 sections ? */ - - put_be32(pb, 0x14); /* size */ - put_tag(pb, "FPRF"); - put_be32(pb, 0x0); /* ? */ - put_be32(pb, 0x0); /* ? */ - put_be32(pb, 0x0); /* ? */ - - put_be32(pb, 0x2c); /* size */ - put_tag(pb, "APRF"); /* audio */ - put_be32(pb, 0x0); - put_be32(pb, 0x2); /* TrackID */ - put_tag(pb, "mp4a"); - put_be32(pb, 0x20f); - put_be32(pb, 0x0); - put_be32(pb, audio_kbitrate); - put_be32(pb, audio_kbitrate); - put_be32(pb, AudioRate); - put_be32(pb, AudioCodec->channels); - - put_be32(pb, 0x34); /* size */ - put_tag(pb, "VPRF"); /* video */ - put_be32(pb, 0x0); - put_be32(pb, 0x1); /* TrackID */ - if (VideoCodec->codec_id == CODEC_ID_H264) { - put_tag(pb, "avc1"); - put_be16(pb, 0x014D); - put_be16(pb, 0x0015); - } else { - put_tag(pb, "mp4v"); - put_be16(pb, 0x0000); - put_be16(pb, 0x0103); - } - put_be32(pb, 0x0); - put_be32(pb, video_kbitrate); - put_be32(pb, video_kbitrate); - put_be32(pb, FrameRate); - put_be32(pb, FrameRate); - put_be16(pb, VideoCodec->width); - put_be16(pb, VideoCodec->height); - put_be32(pb, 0x010001); /* ? */ -} - -static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags) -{ - uint32_t c = -1; - int i, closed_gop = 0; - - for (i = 0; i < pkt->size - 4; i++) { - c = (c<<8) + pkt->data[i]; - if (c == 0x1b8) { // gop - closed_gop = pkt->data[i+4]>>6 & 0x01; - } else if (c == 0x100) { // pic - int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6); - if (!temp_ref || closed_gop) // I picture is not reordered - *flags = MOV_SYNC_SAMPLE; - else - *flags = MOV_PARTIAL_SYNC_SAMPLE; - break; - } - } - return 0; -} - -int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - MOVMuxContext *mov = s->priv_data; - ByteIOContext *pb = s->pb; - MOVTrack *trk = &mov->tracks[pkt->stream_index]; - AVCodecContext *enc = trk->enc; - unsigned int samplesInChunk = 0; - int size= pkt->size; - - if (url_is_streamed(s->pb)) return 0; /* Can't handle that */ - if (!size) return 0; /* Discard 0 sized packets */ - - if (enc->codec_id == CODEC_ID_AMR_NB) { - /* We must find out how many AMR blocks there are in one packet */ - static uint16_t packed_size[16] = - {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0}; - int len = 0; - - while (len < size && samplesInChunk < 100) { - len += packed_size[(pkt->data[len] >> 3) & 0x0F]; - samplesInChunk++; - } - if(samplesInChunk > 1){ - av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n"); - return -1; - } - } else if (trk->sampleSize) - samplesInChunk = size/trk->sampleSize; - else - samplesInChunk = 1; - - /* copy extradata if it exists */ - if (trk->vosLen == 0 && enc->extradata_size > 0) { - trk->vosLen = enc->extradata_size; - trk->vosData = av_malloc(trk->vosLen); - memcpy(trk->vosData, enc->extradata, trk->vosLen); - } - - if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) { - /* from x264 or from bytestream h264 */ - /* nal reformating needed */ - size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size); - } else { - put_buffer(pb, pkt->data, size); - } - - if ((enc->codec_id == CODEC_ID_DNXHD || - enc->codec_id == CODEC_ID_AC3) && !trk->vosLen) { - /* copy frame to create needed atoms */ - trk->vosLen = size; - trk->vosData = av_malloc(size); - if (!trk->vosData) - return AVERROR(ENOMEM); - memcpy(trk->vosData, pkt->data, size); - } - - if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) { - trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster)); - if (!trk->cluster) - return -1; - } - - trk->cluster[trk->entry].pos = url_ftell(pb) - size; - trk->cluster[trk->entry].samplesInChunk = samplesInChunk; - trk->cluster[trk->entry].size = size; - trk->cluster[trk->entry].entries = samplesInChunk; - trk->cluster[trk->entry].dts = pkt->dts; - trk->trackDuration = pkt->dts - trk->cluster[0].dts + pkt->duration; - - if (pkt->pts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_WARNING, "pts has no value\n"); - pkt->pts = pkt->dts; - } - if (pkt->dts != pkt->pts) - trk->flags |= MOV_TRACK_CTTS; - trk->cluster[trk->entry].cts = pkt->pts - pkt->dts; - trk->cluster[trk->entry].flags = 0; - if (pkt->flags & AV_PKT_FLAG_KEY) { - if (mov->mode == MODE_MOV && enc->codec_id == CODEC_ID_MPEG2VIDEO) { - mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags); - if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE) - trk->flags |= MOV_TRACK_STPS; - } else { - trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE; - } - if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE) - trk->hasKeyframes++; - } - trk->entry++; - trk->sampleCount += samplesInChunk; - mov->mdat_size += size; - - put_flush_packet(pb); - - if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) - ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry); - return 0; -} - -// QuickTime chapters involve an additional text track with the chapter names -// as samples, and a tref pointing from the other tracks to the chapter one. -static void mov_create_chapter_track(AVFormatContext *s, int tracknum) -{ - MOVMuxContext *mov = s->priv_data; - MOVTrack *track = &mov->tracks[tracknum]; - AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY }; - int i, len; - - track->mode = mov->mode; - track->tag = MKTAG('t','e','x','t'); - track->timescale = MOV_TIMESCALE; - track->enc = avcodec_alloc_context(); - track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE; - - for (i = 0; i < s->nb_chapters; i++) { - AVChapter *c = s->chapters[i]; - AVMetadataTag *t; - - int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE}); - pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE}); - pkt.duration = end - pkt.dts; - - if ((t = av_metadata_get(c->metadata, "title", NULL, 0))) { - len = strlen(t->value); - pkt.size = len+2; - pkt.data = av_malloc(pkt.size); - AV_WB16(pkt.data, len); - memcpy(pkt.data+2, t->value, len); - ff_mov_write_packet(s, &pkt); - av_freep(&pkt.data); - } - } -} - -static int mov_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - MOVMuxContext *mov = s->priv_data; - int i, hint_track = 0; - - if (url_is_streamed(s->pb)) { - av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n"); - return -1; - } - - /* Default mode == MP4 */ - mov->mode = MODE_MP4; - - if (s->oformat != NULL) { - if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP; - else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2; - else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV; - else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP; - else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD; - - mov_write_ftyp_tag(pb,s); - if (mov->mode == MODE_PSP) { - if (s->nb_streams != 2) { - av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n"); - return -1; - } - mov_write_uuidprof_tag(pb,s); - } - } - - mov->nb_streams = s->nb_streams; - if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters) - mov->chapter_track = mov->nb_streams++; - - if (s->flags & AVFMT_FLAG_RTP_HINT) { - /* Add hint tracks for each audio and video stream */ - hint_track = mov->nb_streams; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || - st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - mov->nb_streams++; - } - } - } - - mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks)); - if (!mov->tracks) - return AVERROR(ENOMEM); - - for(i=0; inb_streams; i++){ - AVStream *st= s->streams[i]; - MOVTrack *track= &mov->tracks[i]; - AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL,0); - - track->enc = st->codec; - track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV); - if (track->language < 0) - track->language = 0; - track->mode = mov->mode; - track->tag = mov_find_codec_tag(s, track); - if (!track->tag) { - av_log(s, AV_LOG_ERROR, "track %d: could not find tag, " - "codec not currently supported in container\n", i); - goto error; - } - /* If hinting of this track is enabled by a later hint track, - * this is updated. */ - track->hint_track = -1; - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') || - track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') || - track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) { - if (st->codec->width != 720 || (st->codec->height != 608 && st->codec->height != 512)) { - av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n"); - goto error; - } - track->height = track->tag>>24 == 'n' ? 486 : 576; - } - track->timescale = st->codec->time_base.den; - if (track->mode == MODE_MOV && track->timescale > 100000) - av_log(s, AV_LOG_WARNING, - "WARNING codec timebase is very high. If duration is too long,\n" - "file may not be playable by quicktime. Specify a shorter timebase\n" - "or choose different container.\n"); - }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){ - track->timescale = st->codec->sample_rate; - if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) { - av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i); - goto error; - }else if(st->codec->frame_size > 1){ /* assume compressed audio */ - track->audio_vbr = 1; - }else{ - st->codec->frame_size = 1; - track->sampleSize = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels; - } - if (track->mode != MODE_MOV) { - if (track->timescale > UINT16_MAX) { - av_log(s, AV_LOG_ERROR, "track %d: output format does not support " - "sample rate %dhz\n", i, track->timescale); - goto error; - } - if (track->enc->codec_id == CODEC_ID_MP3 && track->timescale < 16000) { - av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n", - i, track->enc->sample_rate); - goto error; - } - } - }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){ - track->timescale = st->codec->time_base.den; - } - if (!track->height) - track->height = st->codec->height; - - av_set_pts_info(st, 64, 1, track->timescale); - } - - mov_write_mdat_tag(pb, mov); - mov->time = s->timestamp + 0x7C25B080; //1970 based -> 1904 based - - if (mov->chapter_track) - mov_create_chapter_track(s, mov->chapter_track); - - if (s->flags & AVFMT_FLAG_RTP_HINT) { - /* Initialize the hint tracks for each audio and video stream */ - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || - st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - ff_mov_init_hinting(s, hint_track, i); - hint_track++; - } - } - } - - put_flush_packet(pb); - - return 0; - error: - av_freep(&mov->tracks); - return -1; -} - -static int mov_write_trailer(AVFormatContext *s) -{ - MOVMuxContext *mov = s->priv_data; - ByteIOContext *pb = s->pb; - int res = 0; - int i; - - int64_t moov_pos = url_ftell(pb); - - /* Write size of mdat tag */ - if (mov->mdat_size+8 <= UINT32_MAX) { - url_fseek(pb, mov->mdat_pos, SEEK_SET); - put_be32(pb, mov->mdat_size+8); - } else { - /* overwrite 'wide' placeholder atom */ - url_fseek(pb, mov->mdat_pos - 8, SEEK_SET); - put_be32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */ - put_tag(pb, "mdat"); - put_be64(pb, mov->mdat_size+16); - } - url_fseek(pb, moov_pos, SEEK_SET); - - mov_write_moov_tag(pb, mov, s); - - if (mov->chapter_track) - av_freep(&mov->tracks[mov->chapter_track].enc); - - for (i=0; inb_streams; i++) { - if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) - ff_mov_close_hinting(&mov->tracks[i]); - av_freep(&mov->tracks[i].cluster); - - if(mov->tracks[i].vosLen) av_free(mov->tracks[i].vosData); - - } - - put_flush_packet(pb); - - av_freep(&mov->tracks); - - return res; -} - -#if CONFIG_MOV_MUXER -AVOutputFormat mov_muxer = { - "mov", - NULL_IF_CONFIG_SMALL("MOV format"), - NULL, - "mov", - sizeof(MOVMuxContext), - CODEC_ID_AAC, - CODEC_ID_MPEG4, - mov_write_header, - ff_mov_write_packet, - mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, - .codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0}, -}; -#endif -#if CONFIG_TGP_MUXER -AVOutputFormat tgp_muxer = { - "3gp", - NULL_IF_CONFIG_SMALL("3GP format"), - NULL, - "3gp", - sizeof(MOVMuxContext), - CODEC_ID_AMR_NB, - CODEC_ID_H263, - mov_write_header, - ff_mov_write_packet, - mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0}, -}; -#endif -#if CONFIG_MP4_MUXER -AVOutputFormat mp4_muxer = { - "mp4", - NULL_IF_CONFIG_SMALL("MP4 format"), - "application/mp4", - "mp4", - sizeof(MOVMuxContext), - CODEC_ID_AAC, - CODEC_ID_MPEG4, - mov_write_header, - ff_mov_write_packet, - mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, - .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0}, -}; -#endif -#if CONFIG_PSP_MUXER -AVOutputFormat psp_muxer = { - "psp", - NULL_IF_CONFIG_SMALL("PSP MP4 format"), - NULL, - "mp4,psp", - sizeof(MOVMuxContext), - CODEC_ID_AAC, - CODEC_ID_MPEG4, - mov_write_header, - ff_mov_write_packet, - mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0}, -}; -#endif -#if CONFIG_TG2_MUXER -AVOutputFormat tg2_muxer = { - "3g2", - NULL_IF_CONFIG_SMALL("3GP2 format"), - NULL, - "3g2", - sizeof(MOVMuxContext), - CODEC_ID_AMR_NB, - CODEC_ID_H263, - mov_write_header, - ff_mov_write_packet, - mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0}, -}; -#endif -#if CONFIG_IPOD_MUXER -AVOutputFormat ipod_muxer = { - "ipod", - NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"), - "application/mp4", - "m4v,m4a", - sizeof(MOVMuxContext), - CODEC_ID_AAC, - CODEC_ID_H264, - mov_write_header, - ff_mov_write_packet, - mov_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0}, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/movenc.h b/tizen/distrib/ffmpeg/libavformat/movenc.h deleted file mode 100644 index 182c5ed..0000000 --- a/tizen/distrib/ffmpeg/libavformat/movenc.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * MOV, 3GP, MP4 muxer - * Copyright (c) 2003 Thomas Raivio - * Copyright (c) 2004 Gildas Bazin - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_MOVENC_H -#define AVFORMAT_MOVENC_H - -#include "avformat.h" - -#define MOV_INDEX_CLUSTER_SIZE 16384 -#define MOV_TIMESCALE 1000 - -#define RTP_MAX_PACKET_SIZE 1450 - -#define MODE_MP4 0x01 -#define MODE_MOV 0x02 -#define MODE_3GP 0x04 -#define MODE_PSP 0x08 // example working PSP command line: -// ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4 -#define MODE_3G2 0x10 -#define MODE_IPOD 0x20 - -typedef struct MOVIentry { - unsigned int size; - uint64_t pos; - unsigned int samplesInChunk; - unsigned int entries; - int cts; - int64_t dts; -#define MOV_SYNC_SAMPLE 0x0001 -#define MOV_PARTIAL_SYNC_SAMPLE 0x0002 - uint32_t flags; -} MOVIentry; - -typedef struct HintSample { - uint8_t *data; - int size; - int sample_number; - int offset; - int own_data; -} HintSample; - -typedef struct { - int size; - int len; - HintSample *samples; -} HintSampleQueue; - -typedef struct MOVIndex { - int mode; - int entry; - unsigned timescale; - uint64_t time; - int64_t trackDuration; - long sampleCount; - long sampleSize; - int hasKeyframes; -#define MOV_TRACK_CTTS 0x0001 -#define MOV_TRACK_STPS 0x0002 - uint32_t flags; - int language; - int trackID; - int tag; ///< stsd fourcc - AVCodecContext *enc; - - int vosLen; - uint8_t *vosData; - MOVIentry *cluster; - int audio_vbr; - int height; ///< active picture (w/o VBI) height for D-10/IMX - uint32_t tref_tag; - int tref_id; ///< trackID of the referenced track - - int hint_track; ///< the track that hints this track, -1 if no hint track is set - int src_track; ///< the track that this hint track describes - AVFormatContext *rtp_ctx; ///< the format context for the hinting rtp muxer - uint32_t prev_rtp_ts; - int64_t cur_rtp_ts_unwrapped; - uint32_t max_packet_size; - - HintSampleQueue sample_queue; -} MOVTrack; - -typedef struct MOVMuxContext { - int mode; - int64_t time; - int nb_streams; - int chapter_track; ///< qt chapter track number - int64_t mdat_pos; - uint64_t mdat_size; - MOVTrack *tracks; -} MOVMuxContext; - -int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt); - -int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index); -int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, - int track_index, int sample); -void ff_mov_close_hinting(MOVTrack *track); - -#endif /* AVFORMAT_MOVENC_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/movenchint.c b/tizen/distrib/ffmpeg/libavformat/movenchint.c deleted file mode 100644 index d90ac67..0000000 --- a/tizen/distrib/ffmpeg/libavformat/movenchint.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * MOV, 3GP, MP4 muxer RTP hinting - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "movenc.h" -#include "libavutil/intreadwrite.h" - -int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index) -{ - MOVMuxContext *mov = s->priv_data; - MOVTrack *track = &mov->tracks[index]; - MOVTrack *src_track = &mov->tracks[src_index]; - AVStream *src_st = s->streams[src_index]; - int ret = AVERROR(ENOMEM); - AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); - - track->tag = MKTAG('r','t','p',' '); - track->src_track = src_index; - - if (!rtp_format) { - ret = AVERROR(ENOENT); - goto fail; - } - - track->enc = avcodec_alloc_context(); - if (!track->enc) - goto fail; - track->enc->codec_type = AVMEDIA_TYPE_DATA; - track->enc->codec_tag = track->tag; - - track->rtp_ctx = avformat_alloc_context(); - if (!track->rtp_ctx) - goto fail; - track->rtp_ctx->oformat = rtp_format; - if (!av_new_stream(track->rtp_ctx, 0)) - goto fail; - - /* Copy stream parameters */ - track->rtp_ctx->streams[0]->sample_aspect_ratio = - src_st->sample_aspect_ratio; - - /* Remove the allocated codec context, link to the original one - * instead, to give the rtp muxer access to codec parameters. */ - av_free(track->rtp_ctx->streams[0]->codec); - track->rtp_ctx->streams[0]->codec = src_st->codec; - - if ((ret = url_open_dyn_packet_buf(&track->rtp_ctx->pb, - RTP_MAX_PACKET_SIZE)) < 0) - goto fail; - ret = av_write_header(track->rtp_ctx); - if (ret) - goto fail; - - /* Copy the RTP AVStream timebase back to the hint AVStream */ - track->timescale = track->rtp_ctx->streams[0]->time_base.den; - - /* Mark the hinted track that packets written to it should be - * sent to this track for hinting. */ - src_track->hint_track = index; - return 0; -fail: - av_log(s, AV_LOG_WARNING, - "Unable to initialize hinting of stream %d\n", src_index); - if (track->rtp_ctx && track->rtp_ctx->pb) { - uint8_t *buf; - url_close_dyn_buf(track->rtp_ctx->pb, &buf); - av_free(buf); - } - if (track->rtp_ctx && track->rtp_ctx->streams[0]) { - av_metadata_free(&track->rtp_ctx->streams[0]->metadata); - av_free(track->rtp_ctx->streams[0]); - } - if (track->rtp_ctx) { - av_metadata_free(&track->rtp_ctx->metadata); - av_free(track->rtp_ctx->priv_data); - av_freep(&track->rtp_ctx); - } - av_freep(&track->enc); - /* Set a default timescale, to avoid crashes in dump_format */ - track->timescale = 90000; - return ret; -} - -/** - * Remove the first sample from the sample queue. - */ -static void sample_queue_pop(HintSampleQueue *queue) -{ - if (queue->len <= 0) - return; - if (queue->samples[0].own_data) - av_free(queue->samples[0].data); - queue->len--; - memmove(queue->samples, queue->samples + 1, sizeof(HintSample)*queue->len); -} - -/** - * Empty the sample queue, releasing all memory. - */ -static void sample_queue_free(HintSampleQueue *queue) -{ - int i; - for (i = 0; i < queue->len; i++) - if (queue->samples[i].own_data) - av_free(queue->samples[i].data); - av_freep(&queue->samples); - queue->len = 0; - queue->size = 0; -} - -/** - * Add a reference to the sample data to the sample queue. The data is - * not copied. sample_queue_retain should be called before pkt->data - * is reused/freed. - */ -static void sample_queue_push(HintSampleQueue *queue, AVPacket *pkt, int sample) -{ - /* No need to keep track of smaller samples, since describing them - * with immediates is more efficient. */ - if (pkt->size <= 14) - return; - if (!queue->samples || queue->len >= queue->size) { - HintSample* samples; - queue->size += 10; - samples = av_realloc(queue->samples, sizeof(HintSample)*queue->size); - if (!samples) - return; - queue->samples = samples; - } - queue->samples[queue->len].data = pkt->data; - queue->samples[queue->len].size = pkt->size; - queue->samples[queue->len].sample_number = sample; - queue->samples[queue->len].offset = 0; - queue->samples[queue->len].own_data = 0; - queue->len++; -} - -/** - * Make local copies of all referenced sample data in the queue. - */ -static void sample_queue_retain(HintSampleQueue *queue) -{ - int i; - for (i = 0; i < queue->len; ) { - HintSample *sample = &queue->samples[i]; - if (!sample->own_data) { - uint8_t* ptr = av_malloc(sample->size); - if (!ptr) { - /* Unable to allocate memory for this one, remove it */ - memmove(queue->samples + i, queue->samples + i + 1, - sizeof(HintSample)*(queue->len - i - 1)); - queue->len--; - continue; - } - memcpy(ptr, sample->data, sample->size); - sample->data = ptr; - sample->own_data = 1; - } - i++; - } -} - -/** - * Find matches of needle[n_pos ->] within haystack. If a sufficiently - * large match is found, matching bytes before n_pos are included - * in the match, too (within the limits of the arrays). - * - * @param haystack buffer that may contain parts of needle - * @param h_len length of the haystack buffer - * @param needle buffer containing source data that have been used to - * construct haystack - * @param n_pos start position in needle used for looking for matches - * @param n_len length of the needle buffer - * @param match_h_offset_ptr offset of the first matching byte within haystack - * @param match_n_offset_ptr offset of the first matching byte within needle - * @param match_len_ptr length of the matched segment - * @return 0 if a match was found, < 0 if no match was found - */ -static int match_segments(const uint8_t *haystack, int h_len, - const uint8_t *needle, int n_pos, int n_len, - int *match_h_offset_ptr, int *match_n_offset_ptr, - int *match_len_ptr) -{ - int h_pos; - for (h_pos = 0; h_pos < h_len; h_pos++) { - int match_len = 0; - int match_h_pos, match_n_pos; - - /* Check how many bytes match at needle[n_pos] and haystack[h_pos] */ - while (h_pos + match_len < h_len && n_pos + match_len < n_len && - needle[n_pos + match_len] == haystack[h_pos + match_len]) - match_len++; - if (match_len <= 8) - continue; - - /* If a sufficiently large match was found, try to expand - * the matched segment backwards. */ - match_h_pos = h_pos; - match_n_pos = n_pos; - while (match_n_pos > 0 && match_h_pos > 0 && - needle[match_n_pos - 1] == haystack[match_h_pos - 1]) { - match_n_pos--; - match_h_pos--; - match_len++; - } - if (match_len <= 14) - continue; - *match_h_offset_ptr = match_h_pos; - *match_n_offset_ptr = match_n_pos; - *match_len_ptr = match_len; - return 0; - } - return -1; -} - -/** - * Look for segments in samples in the sample queue matching the data - * in ptr. Samples not matching are removed from the queue. If a match - * is found, the next time it will look for matches starting from the - * end of the previous matched segment. - * - * @param data data to find matches for in the sample queue - * @param len length of the data buffer - * @param queue samples used for looking for matching segments - * @param pos the offset in data of the matched segment - * @param match_sample the number of the sample that contained the match - * @param match_offset the offset of the matched segment within the sample - * @param match_len the length of the matched segment - * @return 0 if a match was found, < 0 if no match was found - */ -static int find_sample_match(const uint8_t *data, int len, - HintSampleQueue *queue, int *pos, - int *match_sample, int *match_offset, - int *match_len) -{ - while (queue->len > 0) { - HintSample *sample = &queue->samples[0]; - /* If looking for matches in a new sample, skip the first 5 bytes, - * since they often may be modified/removed in the output packet. */ - if (sample->offset == 0 && sample->size > 5) - sample->offset = 5; - - if (match_segments(data, len, sample->data, sample->offset, - sample->size, pos, match_offset, match_len) == 0) { - *match_sample = sample->sample_number; - /* Next time, look for matches at this offset, with a little - * margin to this match. */ - sample->offset = *match_offset + *match_len + 5; - if (sample->offset + 10 >= sample->size) - sample_queue_pop(queue); /* Not enough useful data left */ - return 0; - } - - if (sample->offset < 10 && sample->size > 20) { - /* No match found from the start of the sample, - * try from the middle of the sample instead. */ - sample->offset = sample->size/2; - } else { - /* No match for this sample, remove it */ - sample_queue_pop(queue); - } - } - return -1; -} - -static void output_immediate(const uint8_t *data, int size, - ByteIOContext *out, int *entries) -{ - while (size > 0) { - int len = size; - if (len > 14) - len = 14; - put_byte(out, 1); /* immediate constructor */ - put_byte(out, len); /* amount of valid data */ - put_buffer(out, data, len); - data += len; - size -= len; - - for (; len < 14; len++) - put_byte(out, 0); - - (*entries)++; - } -} - -static void output_match(ByteIOContext *out, int match_sample, - int match_offset, int match_len, int *entries) -{ - put_byte(out, 2); /* sample constructor */ - put_byte(out, 0); /* track reference */ - put_be16(out, match_len); - put_be32(out, match_sample); - put_be32(out, match_offset); - put_be16(out, 1); /* bytes per block */ - put_be16(out, 1); /* samples per block */ - (*entries)++; -} - -static void describe_payload(const uint8_t *data, int size, - ByteIOContext *out, int *entries, - HintSampleQueue *queue) -{ - /* Describe the payload using different constructors */ - while (size > 0) { - int match_sample, match_offset, match_len, pos; - if (find_sample_match(data, size, queue, &pos, &match_sample, - &match_offset, &match_len) < 0) - break; - output_immediate(data, pos, out, entries); - data += pos; - size -= pos; - output_match(out, match_sample, match_offset, match_len, entries); - data += match_len; - size -= match_len; - } - output_immediate(data, size, out, entries); -} - -/** - * Write an RTP hint (that may contain one or more RTP packets) - * for the packets in data. data contains one or more packets with a - * BE32 size header. - * - * @param out buffer where the hints are written - * @param data buffer containing RTP packets - * @param size the size of the data buffer - * @param trk the MOVTrack for the hint track - * @param pts pointer where the timestamp for the written RTP hint is stored - * @return the number of RTP packets in the written hint - */ -static int write_hint_packets(ByteIOContext *out, const uint8_t *data, - int size, MOVTrack *trk, int64_t *pts) -{ - int64_t curpos; - int64_t count_pos, entries_pos; - int count = 0, entries; - - count_pos = url_ftell(out); - /* RTPsample header */ - put_be16(out, 0); /* packet count */ - put_be16(out, 0); /* reserved */ - - while (size > 4) { - uint32_t packet_len = AV_RB32(data); - uint16_t seq; - uint32_t ts; - - data += 4; - size -= 4; - if (packet_len > size || packet_len <= 12) - break; - if (data[1] >= 200 && data[1] <= 204) { - /* RTCP packet, just skip */ - data += packet_len; - size -= packet_len; - continue; - } - - if (packet_len > trk->max_packet_size) - trk->max_packet_size = packet_len; - - seq = AV_RB16(&data[2]); - ts = AV_RB32(&data[4]); - - if (trk->prev_rtp_ts == 0) - trk->prev_rtp_ts = ts; - /* Unwrap the 32-bit RTP timestamp that wraps around often - * into a not (as often) wrapping 64-bit timestamp. */ - trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts); - trk->prev_rtp_ts = ts; - if (*pts == AV_NOPTS_VALUE) - *pts = trk->cur_rtp_ts_unwrapped; - - count++; - /* RTPpacket header */ - put_be32(out, 0); /* relative_time */ - put_buffer(out, data, 2); /* RTP header */ - put_be16(out, seq); /* RTPsequenceseed */ - put_be16(out, 0); /* reserved + flags */ - entries_pos = url_ftell(out); - put_be16(out, 0); /* entry count */ - - data += 12; - size -= 12; - packet_len -= 12; - - entries = 0; - /* Write one or more constructors describing the payload data */ - describe_payload(data, packet_len, out, &entries, &trk->sample_queue); - data += packet_len; - size -= packet_len; - - curpos = url_ftell(out); - url_fseek(out, entries_pos, SEEK_SET); - put_be16(out, entries); - url_fseek(out, curpos, SEEK_SET); - } - - curpos = url_ftell(out); - url_fseek(out, count_pos, SEEK_SET); - put_be16(out, count); - url_fseek(out, curpos, SEEK_SET); - return count; -} - -int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, - int track_index, int sample) -{ - MOVMuxContext *mov = s->priv_data; - MOVTrack *trk = &mov->tracks[track_index]; - AVFormatContext *rtp_ctx = trk->rtp_ctx; - uint8_t *buf = NULL; - int size; - ByteIOContext *hintbuf = NULL; - AVPacket hint_pkt; - AVPacket local_pkt; - int ret = 0, count; - - if (!rtp_ctx) - return AVERROR(ENOENT); - if (!rtp_ctx->pb) - return AVERROR(ENOMEM); - - sample_queue_push(&trk->sample_queue, pkt, sample); - - /* Feed the packet to the RTP muxer */ - local_pkt = *pkt; - local_pkt.stream_index = 0; - local_pkt.pts = av_rescale_q(pkt->pts, - s->streams[pkt->stream_index]->time_base, - rtp_ctx->streams[0]->time_base); - local_pkt.dts = av_rescale_q(pkt->dts, - s->streams[pkt->stream_index]->time_base, - rtp_ctx->streams[0]->time_base); - av_write_frame(rtp_ctx, &local_pkt); - - /* Fetch the output from the RTP muxer, open a new output buffer - * for next time. */ - size = url_close_dyn_buf(rtp_ctx->pb, &buf); - if ((ret = url_open_dyn_packet_buf(&rtp_ctx->pb, - RTP_MAX_PACKET_SIZE)) < 0) - goto done; - - if (size <= 0) - goto done; - - /* Open a buffer for writing the hint */ - if ((ret = url_open_dyn_buf(&hintbuf)) < 0) - goto done; - av_init_packet(&hint_pkt); - count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt.dts); - av_freep(&buf); - - /* Write the hint data into the hint track */ - hint_pkt.size = size = url_close_dyn_buf(hintbuf, &buf); - hint_pkt.data = buf; - hint_pkt.pts = hint_pkt.dts; - hint_pkt.stream_index = track_index; - if (pkt->flags & AV_PKT_FLAG_KEY) - hint_pkt.flags |= AV_PKT_FLAG_KEY; - if (count > 0) - ff_mov_write_packet(s, &hint_pkt); -done: - av_free(buf); - sample_queue_retain(&trk->sample_queue); - return ret; -} - -void ff_mov_close_hinting(MOVTrack *track) { - AVFormatContext* rtp_ctx = track->rtp_ctx; - uint8_t *ptr; - - av_freep(&track->enc); - sample_queue_free(&track->sample_queue); - if (!rtp_ctx) - return; - if (rtp_ctx->pb) { - av_write_trailer(rtp_ctx); - url_close_dyn_buf(rtp_ctx->pb, &ptr); - av_free(ptr); - } - av_metadata_free(&rtp_ctx->streams[0]->metadata); - av_metadata_free(&rtp_ctx->metadata); - av_free(rtp_ctx->streams[0]); - av_freep(&rtp_ctx); -} - diff --git a/tizen/distrib/ffmpeg/libavformat/mp3.c b/tizen/distrib/ffmpeg/libavformat/mp3.c deleted file mode 100644 index dcb59e8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mp3.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * MP3 muxer and demuxer - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "libavutil/avstring.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "id3v2.h" -#include "id3v1.h" - -#if CONFIG_MP3_DEMUXER - -#include "libavcodec/mpegaudio.h" -#include "libavcodec/mpegaudiodecheader.h" - -/* mp3 read */ - -static int mp3_read_probe(AVProbeData *p) -{ - int max_frames, first_frames = 0; - int fsize, frames, sample_rate; - uint32_t header; - uint8_t *buf, *buf0, *buf2, *end; - AVCodecContext avctx; - - buf0 = p->buf; - if(ff_id3v2_match(buf0)) { - buf0 += ff_id3v2_tag_len(buf0); - } - end = p->buf + p->buf_size - sizeof(uint32_t); - while(buf0 < end && !*buf0) - buf0++; - - max_frames = 0; - buf = buf0; - - for(; buf < end; buf= buf2+1) { - buf2 = buf; - - for(frames = 0; buf2 < end; frames++) { - header = AV_RB32(buf2); - fsize = ff_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate); - if(fsize < 0) - break; - buf2 += fsize; - } - max_frames = FFMAX(max_frames, frames); - if(buf == buf0) - first_frames= frames; - } - // keep this in sync with ac3 probe, both need to avoid - // issues with MPEG-files! - if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1; - else if(max_frames>500)return AVPROBE_SCORE_MAX/2; - else if(max_frames>=4) return AVPROBE_SCORE_MAX/4; - else if(buf0!=p->buf) return AVPROBE_SCORE_MAX/4-1; - else if(max_frames>=1) return 1; - else return 0; -//mpegps_mp3_unrecognized_format.mpg has max_frames=3 -} - -/** - * Try to find Xing/Info/VBRI tags and compute duration from info therein - */ -static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) -{ - uint32_t v, spf; - int frames = -1; /* Total number of frames in file */ - const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; - MPADecodeHeader c; - int vbrtag_size = 0; - - v = get_be32(s->pb); - if(ff_mpa_check_header(v) < 0) - return -1; - - if (ff_mpegaudio_decode_header(&c, v) == 0) - vbrtag_size = c.frame_size; - if(c.layer != 3) - return -1; - - /* Check for Xing / Info tag */ - url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR); - v = get_be32(s->pb); - if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { - v = get_be32(s->pb); - if(v & 0x1) - frames = get_be32(s->pb); - } - - /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ - url_fseek(s->pb, base + 4 + 32, SEEK_SET); - v = get_be32(s->pb); - if(v == MKBETAG('V', 'B', 'R', 'I')) { - /* Check tag version */ - if(get_be16(s->pb) == 1) { - /* skip delay, quality and total bytes */ - url_fseek(s->pb, 8, SEEK_CUR); - frames = get_be32(s->pb); - } - } - - if(frames < 0) - return -1; - - /* Skip the vbr tag frame */ - url_fseek(s->pb, base + vbrtag_size, SEEK_SET); - - spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ - st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, - st->time_base); - return 0; -} - -static int mp3_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st; - int64_t off; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_MP3; - st->need_parsing = AVSTREAM_PARSE_FULL; - st->start_time = 0; - - // lcm of all mp3 sample rates - av_set_pts_info(st, 64, 1, 14112000); - - ff_id3v2_read(s); - off = url_ftell(s->pb); - - if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) - ff_id3v1_read(s); - - if (mp3_parse_vbr_tags(s, st, off) < 0) - url_fseek(s->pb, off, SEEK_SET); - - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -#define MP3_PACKET_SIZE 1024 - -static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size; - // AVStream *st = s->streams[0]; - - size= MP3_PACKET_SIZE; - - ret= av_get_packet(s->pb, pkt, size); - - pkt->stream_index = 0; - if (ret <= 0) { - return AVERROR(EIO); - } - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - return ret; -} - -AVInputFormat mp3_demuxer = { - "mp3", - NULL_IF_CONFIG_SMALL("MPEG audio layer 2/3"), - 0, - mp3_read_probe, - mp3_read_header, - mp3_read_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "mp2,mp3,m2a", /* XXX: use probe */ - .metadata_conv = ff_id3v2_metadata_conv, -}; -#endif - -#if CONFIG_MP2_MUXER || CONFIG_MP3_MUXER -static int id3v1_set_string(AVFormatContext *s, const char *key, - uint8_t *buf, int buf_size) -{ - AVMetadataTag *tag; - if ((tag = av_metadata_get(s->metadata, key, NULL, 0))) - strncpy(buf, tag->value, buf_size); - return !!tag; -} - -static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf) -{ - AVMetadataTag *tag; - int i, count = 0; - - memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */ - buf[0] = 'T'; - buf[1] = 'A'; - buf[2] = 'G'; - count += id3v1_set_string(s, "title", buf + 3, 30); - count += id3v1_set_string(s, "author", buf + 33, 30); - count += id3v1_set_string(s, "album", buf + 63, 30); - count += id3v1_set_string(s, "date", buf + 93, 4); - count += id3v1_set_string(s, "comment", buf + 97, 30); - if ((tag = av_metadata_get(s->metadata, "track", NULL, 0))) { - buf[125] = 0; - buf[126] = atoi(tag->value); - count++; - } - buf[127] = 0xFF; /* default to unknown genre */ - if ((tag = av_metadata_get(s->metadata, "genre", NULL, 0))) { - for(i = 0; i <= ID3v1_GENRE_MAX; i++) { - if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) { - buf[127] = i; - count++; - break; - } - } - } - return count; -} - -/* simple formats */ - -static void id3v2_put_size(AVFormatContext *s, int size) -{ - put_byte(s->pb, size >> 21 & 0x7f); - put_byte(s->pb, size >> 14 & 0x7f); - put_byte(s->pb, size >> 7 & 0x7f); - put_byte(s->pb, size & 0x7f); -} - -static void id3v2_put_ttag(AVFormatContext *s, const char *buf, int len, - uint32_t tag) -{ - put_be32(s->pb, tag); - id3v2_put_size(s, len + 1); - put_be16(s->pb, 0); - put_byte(s->pb, 3); /* UTF-8 */ - put_buffer(s->pb, buf, len); -} - - -static int mp3_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - put_buffer(s->pb, pkt->data, pkt->size); - put_flush_packet(s->pb); - return 0; -} - -static int mp3_write_trailer(struct AVFormatContext *s) -{ - uint8_t buf[ID3v1_TAG_SIZE]; - - /* write the id3v1 tag */ - if (id3v1_create_tag(s, buf) > 0) { - put_buffer(s->pb, buf, ID3v1_TAG_SIZE); - put_flush_packet(s->pb); - } - return 0; -} -#endif /* CONFIG_MP2_MUXER || CONFIG_MP3_MUXER */ - -#if CONFIG_MP2_MUXER -AVOutputFormat mp2_muxer = { - "mp2", - NULL_IF_CONFIG_SMALL("MPEG audio layer 2"), - "audio/x-mpeg", - "mp2,m2a", - 0, - CODEC_ID_MP2, - CODEC_ID_NONE, - NULL, - mp3_write_packet, - mp3_write_trailer, -}; -#endif - -#if CONFIG_MP3_MUXER -/** - * Write an ID3v2.4 header at beginning of stream - */ - -static int mp3_write_header(struct AVFormatContext *s) -{ - AVMetadataTag *t = NULL; - int totlen = 0; - int64_t size_pos, cur_pos; - - put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */ - put_byte(s->pb, 0); - put_byte(s->pb, 0); /* flags */ - - /* reserve space for size */ - size_pos = url_ftell(s->pb); - put_be32(s->pb, 0); - - while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) { - uint32_t tag = 0; - - if (t->key[0] == 'T' && strlen(t->key) == 4) { - int i; - for (i = 0; *ff_id3v2_tags[i]; i++) - if (AV_RB32(t->key) == AV_RB32(ff_id3v2_tags[i])) { - int len = strlen(t->value); - tag = AV_RB32(t->key); - totlen += len + ID3v2_HEADER_SIZE + 2; - id3v2_put_ttag(s, t->value, len + 1, tag); - break; - } - } - - if (!tag) { /* unknown tag, write as TXXX frame */ - int len = strlen(t->key), len1 = strlen(t->value); - char *buf = av_malloc(len + len1 + 2); - if (!buf) - return AVERROR(ENOMEM); - tag = MKBETAG('T', 'X', 'X', 'X'); - strcpy(buf, t->key); - strcpy(buf + len + 1, t->value); - id3v2_put_ttag(s, buf, len + len1 + 2, tag); - totlen += len + len1 + ID3v2_HEADER_SIZE + 3; - av_free(buf); - } - } - - cur_pos = url_ftell(s->pb); - url_fseek(s->pb, size_pos, SEEK_SET); - id3v2_put_size(s, totlen); - url_fseek(s->pb, cur_pos, SEEK_SET); - - return 0; -} - -AVOutputFormat mp3_muxer = { - "mp3", - NULL_IF_CONFIG_SMALL("MPEG audio layer 3"), - "audio/x-mpeg", - "mp3", - 0, - CODEC_ID_MP3, - CODEC_ID_NONE, - mp3_write_header, - mp3_write_packet, - mp3_write_trailer, - AVFMT_NOTIMESTAMPS, - .metadata_conv = ff_id3v2_metadata_conv, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/mpc.c b/tizen/distrib/ffmpeg/libavformat/mpc.c deleted file mode 100644 index 4dda65d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpc.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Musepack demuxer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "id3v2.h" -#include "apetag.h" - -#define MPC_FRAMESIZE 1152 -#define DELAY_FRAMES 32 - -static const int mpc_rate[4] = { 44100, 48000, 37800, 32000 }; -typedef struct { - int64_t pos; - int size, skip; -}MPCFrame; - -typedef struct { - int ver; - uint32_t curframe, lastframe; - uint32_t fcount; - MPCFrame *frames; - int curbits; - int frames_noted; -} MPCContext; - -static int mpc_probe(AVProbeData *p) -{ - const uint8_t *d = p->buf; - if (ff_id3v2_match(d)) { - d += ff_id3v2_tag_len(d); - } - if (d+3 < p->buf+p->buf_size) - if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7)) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - MPCContext *c = s->priv_data; - AVStream *st; - int t, ret; - int64_t pos = url_ftell(s->pb); - - t = get_le24(s->pb); - if(t != MKTAG('M', 'P', '+', 0)){ - uint8_t buf[ID3v2_HEADER_SIZE]; - if (url_fseek(s->pb, pos, SEEK_SET) < 0) - return -1; - ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE); - if (ret != ID3v2_HEADER_SIZE || !ff_id3v2_match(buf)) { - av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); - return -1; - } - /* skip ID3 tags and try again */ - t = ff_id3v2_tag_len(buf) - ID3v2_HEADER_SIZE; - av_log(s, AV_LOG_DEBUG, "Skipping %d(%X) bytes of ID3 data\n", t, t); - url_fskip(s->pb, t); - if(get_le24(s->pb) != MKTAG('M', 'P', '+', 0)){ - av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); - return -1; - } - /* read ID3 tags */ - if (url_fseek(s->pb, pos, SEEK_SET) < 0) - return -1; - ff_id3v2_read(s); - get_le24(s->pb); - } - c->ver = get_byte(s->pb); - if(c->ver != 0x07 && c->ver != 0x17){ - av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); - return -1; - } - c->fcount = get_le32(s->pb); - if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){ - av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); - return -1; - } - c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); - c->curframe = 0; - c->lastframe = -1; - c->curbits = 8; - c->frames_noted = 0; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_MUSEPACK7; - st->codec->channels = 2; - st->codec->bits_per_coded_sample = 16; - - st->codec->extradata_size = 16; - st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); - get_buffer(s->pb, st->codec->extradata, 16); - st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; - av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); - /* scan for seekpoints */ - st->start_time = 0; - st->duration = c->fcount; - - /* try to read APE tags */ - if (!url_is_streamed(s->pb)) { - int64_t pos = url_ftell(s->pb); - ff_ape_parse_tag(s); - url_fseek(s->pb, pos, SEEK_SET); - } - - return 0; -} - -static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MPCContext *c = s->priv_data; - int ret, size, size2, curbits, cur = c->curframe; - int64_t tmp, pos; - - if (c->curframe >= c->fcount) - return -1; - - if(c->curframe != c->lastframe + 1){ - url_fseek(s->pb, c->frames[c->curframe].pos, SEEK_SET); - c->curbits = c->frames[c->curframe].skip; - } - c->lastframe = c->curframe; - c->curframe++; - curbits = c->curbits; - pos = url_ftell(s->pb); - tmp = get_le32(s->pb); - if(curbits <= 12){ - size2 = (tmp >> (12 - curbits)) & 0xFFFFF; - }else{ - tmp = (tmp << 32) | get_le32(s->pb); - size2 = (tmp >> (44 - curbits)) & 0xFFFFF; - } - curbits += 20; - url_fseek(s->pb, pos, SEEK_SET); - - size = ((size2 + curbits + 31) & ~31) >> 3; - if(cur == c->frames_noted){ - c->frames[cur].pos = pos; - c->frames[cur].size = size; - c->frames[cur].skip = curbits - 20; - av_add_index_entry(s->streams[0], cur, cur, size, 0, AVINDEX_KEYFRAME); - c->frames_noted++; - } - c->curbits = (curbits + size2) & 0x1F; - - if (av_new_packet(pkt, size) < 0) - return AVERROR(EIO); - - pkt->data[0] = curbits; - pkt->data[1] = (c->curframe > c->fcount); - pkt->data[2] = 0; - pkt->data[3] = 0; - - pkt->stream_index = 0; - pkt->pts = cur; - ret = get_buffer(s->pb, pkt->data + 4, size); - if(c->curbits) - url_fseek(s->pb, -4, SEEK_CUR); - if(ret < size){ - av_free_packet(pkt); - return AVERROR(EIO); - } - pkt->size = ret + 4; - - return 0; -} - -static int mpc_read_close(AVFormatContext *s) -{ - MPCContext *c = s->priv_data; - - av_freep(&c->frames); - return 0; -} - -/** - * Seek to the given position - * If position is unknown but is within the limits of file - * then packets are skipped unless desired position is reached - * - * Also this function makes use of the fact that timestamp == frameno - */ -static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - MPCContext *c = s->priv_data; - AVPacket pkt1, *pkt = &pkt1; - int ret; - int index = av_index_search_timestamp(st, timestamp - DELAY_FRAMES, flags); - uint32_t lastframe; - - /* if found, seek there */ - if (index >= 0){ - c->curframe = st->index_entries[index].pos; - return 0; - } - /* if timestamp is out of bounds, return error */ - if(timestamp < 0 || timestamp >= c->fcount) - return -1; - timestamp -= DELAY_FRAMES; - /* seek to the furthest known position and read packets until - we reach desired position */ - lastframe = c->curframe; - if(c->frames_noted) c->curframe = c->frames_noted - 1; - while(c->curframe < timestamp){ - ret = av_read_frame(s, pkt); - if (ret < 0){ - c->curframe = lastframe; - return -1; - } - av_free_packet(pkt); - } - return 0; -} - - -AVInputFormat mpc_demuxer = { - "mpc", - NULL_IF_CONFIG_SMALL("Musepack"), - sizeof(MPCContext), - mpc_probe, - mpc_read_header, - mpc_read_packet, - mpc_read_close, - mpc_read_seek, - .extensions = "mpc", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mpc8.c b/tizen/distrib/ffmpeg/libavformat/mpc8.c deleted file mode 100644 index 92e996c..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpc8.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Musepack SV8 demuxer - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/get_bits.h" -#include "libavcodec/unary.h" -#include "avformat.h" - -/// Two-byte MPC tag -#define MKMPCTAG(a, b) (a | (b << 8)) - -#define TAG_MPCK MKTAG('M','P','C','K') - -/// Reserved MPC tags -enum MPCPacketTags{ - TAG_STREAMHDR = MKMPCTAG('S','H'), - TAG_STREAMEND = MKMPCTAG('S','E'), - - TAG_AUDIOPACKET = MKMPCTAG('A','P'), - - TAG_SEEKTBLOFF = MKMPCTAG('S','O'), - TAG_SEEKTABLE = MKMPCTAG('S','T'), - - TAG_REPLAYGAIN = MKMPCTAG('R','G'), - TAG_ENCINFO = MKMPCTAG('E','I'), -}; - -static const int mpc8_rate[8] = { 44100, 48000, 37800, 32000, -1, -1, -1, -1 }; - -typedef struct { - int ver; - int frame; - int64_t header_pos; - int64_t samples; -} MPCContext; - -static inline int64_t bs_get_v(uint8_t **bs) -{ - int64_t v = 0; - int br = 0; - int c; - - do { - c = **bs; (*bs)++; - v <<= 7; - v |= c & 0x7F; - br++; - if (br > 10) - return -1; - } while (c & 0x80); - - return v - br; -} - -static int mpc8_probe(AVProbeData *p) -{ - uint8_t *bs = p->buf + 4; - uint8_t *bs_end = bs + p->buf_size; - int64_t size; - - if (p->buf_size < 16) - return 0; - if (AV_RL32(p->buf) != TAG_MPCK) - return 0; - while (bs < bs_end + 3) { - int header_found = (bs[0] == 'S' && bs[1] == 'H'); - if (bs[0] < 'A' || bs[0] > 'Z' || bs[1] < 'A' || bs[1] > 'Z') - return 0; - bs += 2; - size = bs_get_v(&bs); - if (size < 2) - return 0; - if (bs + size - 2 >= bs_end) - return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet - if (header_found) { - if (size < 11 || size > 28) - return 0; - if (!AV_RL32(bs)) //zero CRC is invalid - return 0; - return AVPROBE_SCORE_MAX; - } else { - bs += size - 2; - } - } - return 0; -} - -static inline int64_t gb_get_v(GetBitContext *gb) -{ - int64_t v = 0; - int bits = 0; - while(get_bits1(gb) && bits < 64-7){ - v <<= 7; - v |= get_bits(gb, 7); - bits += 7; - } - v <<= 7; - v |= get_bits(gb, 7); - - return v; -} - -static void mpc8_get_chunk_header(ByteIOContext *pb, int *tag, int64_t *size) -{ - int64_t pos; - pos = url_ftell(pb); - *tag = get_le16(pb); - *size = ff_get_v(pb); - *size -= url_ftell(pb) - pos; -} - -static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) -{ - MPCContext *c = s->priv_data; - int tag; - int64_t size, pos, ppos[2]; - uint8_t *buf; - int i, t, seekd; - GetBitContext gb; - - url_fseek(s->pb, off, SEEK_SET); - mpc8_get_chunk_header(s->pb, &tag, &size); - if(tag != TAG_SEEKTABLE){ - av_log(s, AV_LOG_ERROR, "No seek table at given position\n"); - return; - } - if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE))) - return; - get_buffer(s->pb, buf, size); - init_get_bits(&gb, buf, size * 8); - size = gb_get_v(&gb); - if(size > UINT_MAX/4 || size > c->samples/1152){ - av_log(s, AV_LOG_ERROR, "Seek table is too big\n"); - return; - } - seekd = get_bits(&gb, 4); - for(i = 0; i < 2; i++){ - pos = gb_get_v(&gb) + c->header_pos; - ppos[1 - i] = pos; - av_add_index_entry(s->streams[0], pos, i, 0, 0, AVINDEX_KEYFRAME); - } - for(; i < size; i++){ - t = get_unary(&gb, 1, 33) << 12; - t += get_bits(&gb, 12); - if(t & 1) - t = -(t & ~1); - pos = (t >> 1) + ppos[0]*2 - ppos[1]; - av_add_index_entry(s->streams[0], pos, i << seekd, 0, 0, AVINDEX_KEYFRAME); - ppos[1] = ppos[0]; - ppos[0] = pos; - } - av_free(buf); -} - -static void mpc8_handle_chunk(AVFormatContext *s, int tag, int64_t chunk_pos, int64_t size) -{ - ByteIOContext *pb = s->pb; - int64_t pos, off; - - switch(tag){ - case TAG_SEEKTBLOFF: - pos = url_ftell(pb) + size; - off = ff_get_v(pb); - mpc8_parse_seektable(s, chunk_pos + off); - url_fseek(pb, pos, SEEK_SET); - break; - default: - url_fskip(pb, size); - } -} - -static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - MPCContext *c = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - int tag = 0; - int64_t size, pos; - - c->header_pos = url_ftell(pb); - if(get_le32(pb) != TAG_MPCK){ - av_log(s, AV_LOG_ERROR, "Not a Musepack8 file\n"); - return -1; - } - - while(!url_feof(pb)){ - pos = url_ftell(pb); - mpc8_get_chunk_header(pb, &tag, &size); - if(tag == TAG_STREAMHDR) - break; - mpc8_handle_chunk(s, tag, pos, size); - } - if(tag != TAG_STREAMHDR){ - av_log(s, AV_LOG_ERROR, "Stream header not found\n"); - return -1; - } - pos = url_ftell(pb); - url_fskip(pb, 4); //CRC - c->ver = get_byte(pb); - if(c->ver != 8){ - av_log(s, AV_LOG_ERROR, "Unknown stream version %d\n", c->ver); - return -1; - } - c->samples = ff_get_v(pb); - ff_get_v(pb); //silence samples at the beginning - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_MUSEPACK8; - st->codec->bits_per_coded_sample = 16; - - st->codec->extradata_size = 2; - st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - get_buffer(pb, st->codec->extradata, st->codec->extradata_size); - - st->codec->channels = (st->codec->extradata[1] >> 4) + 1; - st->codec->sample_rate = mpc8_rate[st->codec->extradata[0] >> 5]; - av_set_pts_info(st, 32, 1152 << (st->codec->extradata[1]&3)*2, st->codec->sample_rate); - st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2); - size -= url_ftell(pb) - pos; - - return 0; -} - -static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MPCContext *c = s->priv_data; - int tag; - int64_t pos, size; - - while(!url_feof(s->pb)){ - pos = url_ftell(s->pb); - mpc8_get_chunk_header(s->pb, &tag, &size); - if (size < 0) - return -1; - if(tag == TAG_AUDIOPACKET){ - if(av_get_packet(s->pb, pkt, size) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 0; - pkt->pts = c->frame; - return 0; - } - if(tag == TAG_STREAMEND) - return AVERROR(EIO); - mpc8_handle_chunk(s, tag, pos, size); - } - return 0; -} - -static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - MPCContext *c = s->priv_data; - int index = av_index_search_timestamp(st, timestamp, flags); - - if(index < 0) return -1; - url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET); - c->frame = st->index_entries[index].timestamp; - return 0; -} - - -AVInputFormat mpc8_demuxer = { - "mpc8", - NULL_IF_CONFIG_SMALL("Musepack SV8"), - sizeof(MPCContext), - mpc8_probe, - mpc8_read_header, - mpc8_read_packet, - NULL, - mpc8_read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mpeg.c b/tizen/distrib/ffmpeg/libavformat/mpeg.c deleted file mode 100644 index 4224a04..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpeg.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * MPEG1/2 demuxer - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "mpeg.h" - -//#define DEBUG_SEEK - -#undef NDEBUG -#include - -/*********************************************/ -/* demux code */ - -#define MAX_SYNC_SIZE 100000 - -static int check_pes(uint8_t *p, uint8_t *end){ - int pes1; - int pes2= (p[3] & 0xC0) == 0x80 - && (p[4] & 0xC0) != 0x40 - &&((p[4] & 0xC0) == 0x00 || (p[4]&0xC0)>>2 == (p[6]&0xF0)); - - for(p+=3; pbuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - int pes= check_pes(p->buf+i, p->buf+p->buf_size); - - if(code == SYSTEM_HEADER_START_CODE) sys++; - else if(code == PRIVATE_STREAM_1) priv1++; - else if(code == PACK_START_CODE) pspack++; - else if((code & 0xf0) == VIDEO_ID && pes) vid++; - else if((code & 0xe0) == AUDIO_ID && pes) audio++; - - else if((code & 0xf0) == VIDEO_ID && !pes) invalid++; - else if((code & 0xe0) == AUDIO_ID && !pes) invalid++; - } - } - - if(vid+audio > invalid) /* invalid VDR files nd short PES streams */ - score= AVPROBE_SCORE_MAX/4; - -//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d %d len:%d\n", sys, priv1, pspack,vid, audio, invalid, p->buf_size); - if(sys>invalid && sys*9 <= pspack*10) - return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg - if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9) - return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg - if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */ - return (audio > 12 || vid > 3) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; - - //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1 - //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6 - return score; -} - - -typedef struct MpegDemuxContext { - int32_t header_state; - unsigned char psm_es_type[256]; - int sofdec; -} MpegDemuxContext; - -static int mpegps_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - MpegDemuxContext *m = s->priv_data; - const char *sofdec = "Sofdec"; - int v, i = 0; - - m->header_state = 0xff; - s->ctx_flags |= AVFMTCTX_NOHEADER; - - m->sofdec = -1; - do { - v = get_byte(s->pb); - m->header_state = m->header_state << 8 | v; - m->sofdec++; - } while (v == sofdec[i] && i++ < 6); - - m->sofdec = (m->sofdec == 6) ? 1 : 0; - - /* no need to do more */ - return 0; -} - -static int64_t get_pts(ByteIOContext *pb, int c) -{ - uint8_t buf[5]; - - buf[0] = c<0 ? get_byte(pb) : c; - get_buffer(pb, buf+1, 4); - - return ff_parse_pes_pts(buf); -} - -static int find_next_start_code(ByteIOContext *pb, int *size_ptr, - int32_t *header_state) -{ - unsigned int state, v; - int val, n; - - state = *header_state; - n = *size_ptr; - while (n > 0) { - if (url_feof(pb)) - break; - v = get_byte(pb); - n--; - if (state == 0x000001) { - state = ((state << 8) | v) & 0xffffff; - val = state; - goto found; - } - state = ((state << 8) | v) & 0xffffff; - } - val = -1; - found: - *header_state = state; - *size_ptr = n; - return val; -} - -#if 0 /* unused, remove? */ -/* XXX: optimize */ -static int find_prev_start_code(ByteIOContext *pb, int *size_ptr) -{ - int64_t pos, pos_start; - int max_size, start_code; - - max_size = *size_ptr; - pos_start = url_ftell(pb); - - /* in order to go faster, we fill the buffer */ - pos = pos_start - 16386; - if (pos < 0) - pos = 0; - url_fseek(pb, pos, SEEK_SET); - get_byte(pb); - - pos = pos_start; - for(;;) { - pos--; - if (pos < 0 || (pos_start - pos) >= max_size) { - start_code = -1; - goto the_end; - } - url_fseek(pb, pos, SEEK_SET); - start_code = get_be32(pb); - if ((start_code & 0xffffff00) == 0x100) - break; - } - the_end: - *size_ptr = pos_start - pos; - return start_code; -} -#endif - -/** - * Extracts stream types from a program stream map - * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35 - * - * @return number of bytes occupied by PSM in the bitstream - */ -static long mpegps_psm_parse(MpegDemuxContext *m, ByteIOContext *pb) -{ - int psm_length, ps_info_length, es_map_length; - - psm_length = get_be16(pb); - get_byte(pb); - get_byte(pb); - ps_info_length = get_be16(pb); - - /* skip program_stream_info */ - url_fskip(pb, ps_info_length); - es_map_length = get_be16(pb); - - /* at least one es available? */ - while (es_map_length >= 4){ - unsigned char type = get_byte(pb); - unsigned char es_id = get_byte(pb); - uint16_t es_info_length = get_be16(pb); - /* remember mapping from stream id to stream type */ - m->psm_es_type[es_id] = type; - /* skip program_stream_info */ - url_fskip(pb, es_info_length); - es_map_length -= 4 + es_info_length; - } - get_be32(pb); /* crc32 */ - return 2 + psm_length; -} - -/* read the next PES header. Return its position in ppos - (if not NULL), and its start code, pts and dts. - */ -static int mpegps_read_pes_header(AVFormatContext *s, - int64_t *ppos, int *pstart_code, - int64_t *ppts, int64_t *pdts) -{ - MpegDemuxContext *m = s->priv_data; - int len, size, startcode, c, flags, header_len; - int pes_ext, ext2_len, id_ext, skip; - int64_t pts, dts; - int64_t last_sync= url_ftell(s->pb); - - error_redo: - url_fseek(s->pb, last_sync, SEEK_SET); - redo: - /* next start code (should be immediately after) */ - m->header_state = 0xff; - size = MAX_SYNC_SIZE; - startcode = find_next_start_code(s->pb, &size, &m->header_state); - last_sync = url_ftell(s->pb); - //printf("startcode=%x pos=0x%"PRIx64"\n", startcode, url_ftell(s->pb)); - if (startcode < 0){ - if(url_feof(s->pb)) - return AVERROR_EOF; - //FIXME we should remember header_state - return AVERROR(EAGAIN); - } - - if (startcode == PACK_START_CODE) - goto redo; - if (startcode == SYSTEM_HEADER_START_CODE) - goto redo; - if (startcode == PADDING_STREAM) { - url_fskip(s->pb, get_be16(s->pb)); - goto redo; - } - if (startcode == PRIVATE_STREAM_2) { - len = get_be16(s->pb); - if (!m->sofdec) { - while (len-- >= 6) { - if (get_byte(s->pb) == 'S') { - uint8_t buf[5]; - get_buffer(s->pb, buf, sizeof(buf)); - m->sofdec = !memcmp(buf, "ofdec", 5); - len -= sizeof(buf); - break; - } - } - m->sofdec -= !m->sofdec; - } - url_fskip(s->pb, len); - goto redo; - } - if (startcode == PROGRAM_STREAM_MAP) { - mpegps_psm_parse(m, s->pb); - goto redo; - } - - /* find matching stream */ - if (!((startcode >= 0x1c0 && startcode <= 0x1df) || - (startcode >= 0x1e0 && startcode <= 0x1ef) || - (startcode == 0x1bd) || (startcode == 0x1fd))) - goto redo; - if (ppos) { - *ppos = url_ftell(s->pb) - 4; - } - len = get_be16(s->pb); - pts = - dts = AV_NOPTS_VALUE; - /* stuffing */ - for(;;) { - if (len < 1) - goto error_redo; - c = get_byte(s->pb); - len--; - /* XXX: for mpeg1, should test only bit 7 */ - if (c != 0xff) - break; - } - if ((c & 0xc0) == 0x40) { - /* buffer scale & size */ - get_byte(s->pb); - c = get_byte(s->pb); - len -= 2; - } - if ((c & 0xe0) == 0x20) { - dts = pts = get_pts(s->pb, c); - len -= 4; - if (c & 0x10){ - dts = get_pts(s->pb, -1); - len -= 5; - } - } else if ((c & 0xc0) == 0x80) { - /* mpeg 2 PES */ -#if 0 /* some streams have this field set for no apparent reason */ - if ((c & 0x30) != 0) { - /* Encrypted multiplex not handled */ - goto redo; - } -#endif - flags = get_byte(s->pb); - header_len = get_byte(s->pb); - len -= 2; - if (header_len > len) - goto error_redo; - len -= header_len; - if (flags & 0x80) { - dts = pts = get_pts(s->pb, -1); - header_len -= 5; - if (flags & 0x40) { - dts = get_pts(s->pb, -1); - header_len -= 5; - } - } - if (flags & 0x3f && header_len == 0){ - flags &= 0xC0; - av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n"); - } - if (flags & 0x01) { /* PES extension */ - pes_ext = get_byte(s->pb); - header_len--; - /* Skip PES private data, program packet sequence counter and P-STD buffer */ - skip = (pes_ext >> 4) & 0xb; - skip += skip & 0x9; - if (pes_ext & 0x40 || skip > header_len){ - av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext); - pes_ext=skip=0; - } - url_fskip(s->pb, skip); - header_len -= skip; - - if (pes_ext & 0x01) { /* PES extension 2 */ - ext2_len = get_byte(s->pb); - header_len--; - if ((ext2_len & 0x7f) > 0) { - id_ext = get_byte(s->pb); - if ((id_ext & 0x80) == 0) - startcode = ((startcode & 0xff) << 8) | id_ext; - header_len--; - } - } - } - if(header_len < 0) - goto error_redo; - url_fskip(s->pb, header_len); - } - else if( c!= 0xf ) - goto redo; - - if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) { - startcode = get_byte(s->pb); - len--; - if (startcode >= 0x80 && startcode <= 0xcf) { - /* audio: skip header */ - get_byte(s->pb); - get_byte(s->pb); - get_byte(s->pb); - len -= 3; - if (startcode >= 0xb0 && startcode <= 0xbf) { - /* MLP/TrueHD audio has a 4-byte header */ - get_byte(s->pb); - len--; - } - } - } - if(len<0) - goto error_redo; - if(dts != AV_NOPTS_VALUE && ppos){ - int i; - for(i=0; inb_streams; i++){ - if(startcode == s->streams[i]->id && - !url_is_streamed(s->pb) /* index useless on streams anyway */) { - ff_reduce_index(s, i); - av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); - } - } - } - - *pstart_code = startcode; - *ppts = pts; - *pdts = dts; - return len; -} - -static int mpegps_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegDemuxContext *m = s->priv_data; - AVStream *st; - int len, startcode, i, es_type; - enum CodecID codec_id = CODEC_ID_NONE; - enum AVMediaType type; - int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work - uint8_t av_uninit(dvdaudio_substream_type); - - redo: - len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts); - if (len < 0) - return len; - - if(startcode == 0x1bd) { - dvdaudio_substream_type = get_byte(s->pb); - url_fskip(s->pb, 3); - len -= 4; - } - - /* now find stream */ - for(i=0;inb_streams;i++) { - st = s->streams[i]; - if (st->id == startcode) - goto found; - } - - es_type = m->psm_es_type[startcode & 0xff]; - if(es_type > 0 && es_type != STREAM_TYPE_PRIVATE_DATA){ - if(es_type == STREAM_TYPE_VIDEO_MPEG1){ - codec_id = CODEC_ID_MPEG2VIDEO; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){ - codec_id = CODEC_ID_MPEG2VIDEO; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 || - es_type == STREAM_TYPE_AUDIO_MPEG2){ - codec_id = CODEC_ID_MP3; - type = AVMEDIA_TYPE_AUDIO; - } else if(es_type == STREAM_TYPE_AUDIO_AAC){ - codec_id = CODEC_ID_AAC; - type = AVMEDIA_TYPE_AUDIO; - } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){ - codec_id = CODEC_ID_MPEG4; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_VIDEO_H264){ - codec_id = CODEC_ID_H264; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_AUDIO_AC3){ - codec_id = CODEC_ID_AC3; - type = AVMEDIA_TYPE_AUDIO; - } else { - goto skip; - } - } else if (startcode >= 0x1e0 && startcode <= 0x1ef) { - static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 }; - unsigned char buf[8]; - get_buffer(s->pb, buf, 8); - url_fseek(s->pb, -8, SEEK_CUR); - if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) - codec_id = CODEC_ID_CAVS; - else - codec_id = CODEC_ID_PROBE; - type = AVMEDIA_TYPE_VIDEO; - } else if (startcode >= 0x1c0 && startcode <= 0x1df) { - type = AVMEDIA_TYPE_AUDIO; - codec_id = m->sofdec > 0 ? CODEC_ID_ADPCM_ADX : CODEC_ID_MP2; - } else if (startcode >= 0x80 && startcode <= 0x87) { - type = AVMEDIA_TYPE_AUDIO; - codec_id = CODEC_ID_AC3; - } else if ( ( startcode >= 0x88 && startcode <= 0x8f) - ||( startcode >= 0x98 && startcode <= 0x9f)) { - /* 0x90 - 0x97 is reserved for SDDS in DVD specs */ - type = AVMEDIA_TYPE_AUDIO; - codec_id = CODEC_ID_DTS; - } else if (startcode >= 0xa0 && startcode <= 0xaf) { - type = AVMEDIA_TYPE_AUDIO; - /* 16 bit form will be handled as CODEC_ID_PCM_S16BE */ - codec_id = CODEC_ID_PCM_DVD; - } else if (startcode >= 0xb0 && startcode <= 0xbf) { - type = AVMEDIA_TYPE_AUDIO; - codec_id = CODEC_ID_TRUEHD; - } else if (startcode >= 0xc0 && startcode <= 0xcf) { - /* Used for both AC-3 and E-AC-3 in EVOB files */ - type = AVMEDIA_TYPE_AUDIO; - codec_id = CODEC_ID_AC3; - } else if (startcode >= 0x20 && startcode <= 0x3f) { - type = AVMEDIA_TYPE_SUBTITLE; - codec_id = CODEC_ID_DVD_SUBTITLE; - } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) { - type = AVMEDIA_TYPE_VIDEO; - codec_id = CODEC_ID_VC1; - } else if (startcode == 0x1bd) { - // check dvd audio substream type - type = AVMEDIA_TYPE_AUDIO; - switch(dvdaudio_substream_type & 0xe0) { - case 0xa0: codec_id = CODEC_ID_PCM_DVD; - break; - case 0x80: if((dvdaudio_substream_type & 0xf8) == 0x88) - codec_id = CODEC_ID_DTS; - else codec_id = CODEC_ID_AC3; - break; - default: av_log(s, AV_LOG_ERROR, "Unknown 0x1bd sub-stream\n"); - goto skip; - } - } else { - skip: - /* skip packet */ - url_fskip(s->pb, len); - goto redo; - } - /* no stream found: add a new stream */ - st = av_new_stream(s, startcode); - if (!st) - goto skip; - st->codec->codec_type = type; - st->codec->codec_id = codec_id; - if (codec_id != CODEC_ID_PCM_S16BE) - st->need_parsing = AVSTREAM_PARSE_FULL; - found: - if(st->discard >= AVDISCARD_ALL) - goto skip; - if ((startcode >= 0xa0 && startcode <= 0xaf) || - (startcode == 0x1bd && ((dvdaudio_substream_type & 0xe0) == 0xa0))) { - int b1, freq; - - /* for LPCM, we just skip the header and consider it is raw - audio data */ - if (len <= 3) - goto skip; - get_byte(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ - b1 = get_byte(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ - get_byte(s->pb); /* dynamic range control (0x80 = off) */ - len -= 3; - freq = (b1 >> 4) & 3; - st->codec->sample_rate = lpcm_freq_tab[freq]; - st->codec->channels = 1 + (b1 & 7); - st->codec->bits_per_coded_sample = 16 + ((b1 >> 6) & 3) * 4; - st->codec->bit_rate = st->codec->channels * - st->codec->sample_rate * - st->codec->bits_per_coded_sample; - if (st->codec->bits_per_coded_sample == 16) - st->codec->codec_id = CODEC_ID_PCM_S16BE; - else if (st->codec->bits_per_coded_sample == 28) - return AVERROR(EINVAL); - } - av_new_packet(pkt, len); - get_buffer(s->pb, pkt->data, pkt->size); - pkt->pts = pts; - pkt->dts = dts; - pkt->pos = dummy_pos; - pkt->stream_index = st->index; -#if 0 - av_log(s, AV_LOG_DEBUG, "%d: pts=%0.3f dts=%0.3f size=%d\n", - pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, pkt->size); -#endif - - return 0; -} - -static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - int len, startcode; - int64_t pos, pts, dts; - - pos = *ppos; -#ifdef DEBUG_SEEK - printf("read_dts: pos=0x%"PRIx64" next=%d -> ", pos, find_next); -#endif - if (url_fseek(s->pb, pos, SEEK_SET) < 0) - return AV_NOPTS_VALUE; - - for(;;) { - len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); - if (len < 0) { -#ifdef DEBUG_SEEK - printf("none (ret=%d)\n", len); -#endif - return AV_NOPTS_VALUE; - } - if (startcode == s->streams[stream_index]->id && - dts != AV_NOPTS_VALUE) { - break; - } - url_fskip(s->pb, len); - } -#ifdef DEBUG_SEEK - printf("pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", pos, dts, dts / 90000.0); -#endif - *ppos = pos; - return dts; -} - -AVInputFormat mpegps_demuxer = { - "mpeg", - NULL_IF_CONFIG_SMALL("MPEG-PS format"), - sizeof(MpegDemuxContext), - mpegps_probe, - mpegps_read_header, - mpegps_read_packet, - NULL, - NULL, //mpegps_read_seek, - mpegps_read_dts, - .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mpeg.h b/tizen/distrib/ffmpeg/libavformat/mpeg.h deleted file mode 100644 index d09b2e8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpeg.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * MPEG1/2 muxer and demuxer common defines - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_MPEG_H -#define AVFORMAT_MPEG_H - -#include -#include "libavutil/intreadwrite.h" - -#define PACK_START_CODE ((unsigned int)0x000001ba) -#define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) -#define SEQUENCE_END_CODE ((unsigned int)0x000001b7) -#define PACKET_START_CODE_MASK ((unsigned int)0xffffff00) -#define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100) -#define ISO_11172_END_CODE ((unsigned int)0x000001b9) - -/* mpeg2 */ -#define PROGRAM_STREAM_MAP 0x1bc -#define PRIVATE_STREAM_1 0x1bd -#define PADDING_STREAM 0x1be -#define PRIVATE_STREAM_2 0x1bf - -#define AUDIO_ID 0xc0 -#define VIDEO_ID 0xe0 -#define AC3_ID 0x80 -#define DTS_ID 0x8a -#define LPCM_ID 0xa0 -#define SUB_ID 0x20 - -#define STREAM_TYPE_VIDEO_MPEG1 0x01 -#define STREAM_TYPE_VIDEO_MPEG2 0x02 -#define STREAM_TYPE_AUDIO_MPEG1 0x03 -#define STREAM_TYPE_AUDIO_MPEG2 0x04 -#define STREAM_TYPE_PRIVATE_SECTION 0x05 -#define STREAM_TYPE_PRIVATE_DATA 0x06 -#define STREAM_TYPE_AUDIO_AAC 0x0f -#define STREAM_TYPE_VIDEO_MPEG4 0x10 -#define STREAM_TYPE_VIDEO_H264 0x1b - -#define STREAM_TYPE_AUDIO_AC3 0x81 -#define STREAM_TYPE_AUDIO_DTS 0x8a - -static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; - -/** - * Parse MPEG-PES five-byte timestamp - */ -static inline int64_t ff_parse_pes_pts(uint8_t *buf) { - return (int64_t)(*buf & 0x0e) << 29 | - (AV_RB16(buf+1) >> 1) << 15 | - AV_RB16(buf+3) >> 1; -} - -#endif /* AVFORMAT_MPEG_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/mpegenc.c b/tizen/distrib/ffmpeg/libavformat/mpegenc.c deleted file mode 100644 index b37a774..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpegenc.c +++ /dev/null @@ -1,1302 +0,0 @@ -/* - * MPEG1/2 muxer - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/fifo.h" -#include "libavcodec/put_bits.h" -#include "avformat.h" -#include "mpeg.h" - -#define MAX_PAYLOAD_SIZE 4096 -//#define DEBUG_SEEK - -#undef NDEBUG -#include - -typedef struct PacketDesc { - int64_t pts; - int64_t dts; - int size; - int unwritten_size; - int flags; - struct PacketDesc *next; -} PacketDesc; - -typedef struct { - AVFifoBuffer *fifo; - uint8_t id; - int max_buffer_size; /* in bytes */ - int buffer_index; - PacketDesc *predecode_packet; - PacketDesc *premux_packet; - PacketDesc **next_packet; - int packet_number; - uint8_t lpcm_header[3]; - int lpcm_align; - int bytes_to_iframe; - int align_iframe; - int64_t vobu_start_pts; -} StreamInfo; - -typedef struct { - int packet_size; /* required packet size */ - int packet_number; - int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ - int system_header_freq; - int system_header_size; - int mux_rate; /* bitrate in units of 50 bytes/s */ - /* stream info */ - int audio_bound; - int video_bound; - int is_mpeg2; - int is_vcd; - int is_svcd; - int is_dvd; - int64_t last_scr; /* current system clock */ - - double vcd_padding_bitrate; //FIXME floats - int64_t vcd_padding_bytes_written; - -} MpegMuxContext; - -extern AVOutputFormat mpeg1vcd_muxer; -extern AVOutputFormat mpeg2dvd_muxer; -extern AVOutputFormat mpeg2svcd_muxer; -extern AVOutputFormat mpeg2vob_muxer; - -static int put_pack_header(AVFormatContext *ctx, - uint8_t *buf, int64_t timestamp) -{ - MpegMuxContext *s = ctx->priv_data; - PutBitContext pb; - - init_put_bits(&pb, buf, 128); - - put_bits32(&pb, PACK_START_CODE); - if (s->is_mpeg2) { - put_bits(&pb, 2, 0x1); - } else { - put_bits(&pb, 4, 0x2); - } - put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); - put_bits(&pb, 1, 1); - put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); - put_bits(&pb, 1, 1); - put_bits(&pb, 15, (uint32_t)((timestamp ) & 0x7fff)); - put_bits(&pb, 1, 1); - if (s->is_mpeg2) { - /* clock extension */ - put_bits(&pb, 9, 0); - } - put_bits(&pb, 1, 1); - put_bits(&pb, 22, s->mux_rate); - put_bits(&pb, 1, 1); - if (s->is_mpeg2) { - put_bits(&pb, 1, 1); - put_bits(&pb, 5, 0x1f); /* reserved */ - put_bits(&pb, 3, 0); /* stuffing length */ - } - flush_put_bits(&pb); - return put_bits_ptr(&pb) - pb.buf; -} - -static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_stream_id) -{ - MpegMuxContext *s = ctx->priv_data; - int size, i, private_stream_coded, id; - PutBitContext pb; - - init_put_bits(&pb, buf, 128); - - put_bits32(&pb, SYSTEM_HEADER_START_CODE); - put_bits(&pb, 16, 0); - put_bits(&pb, 1, 1); - - put_bits(&pb, 22, s->mux_rate); /* maximum bit rate of the multiplexed stream */ - put_bits(&pb, 1, 1); /* marker */ - if (s->is_vcd && only_for_stream_id==VIDEO_ID) { - /* This header applies only to the video stream (see VCD standard p. IV-7)*/ - put_bits(&pb, 6, 0); - } else - put_bits(&pb, 6, s->audio_bound); - - if (s->is_vcd) { - /* see VCD standard, p. IV-7*/ - put_bits(&pb, 1, 0); - put_bits(&pb, 1, 1); - } else { - put_bits(&pb, 1, 0); /* variable bitrate*/ - put_bits(&pb, 1, 0); /* non constrainted bit stream */ - } - - if (s->is_vcd || s->is_dvd) { - /* see VCD standard p IV-7 */ - put_bits(&pb, 1, 1); /* audio locked */ - put_bits(&pb, 1, 1); /* video locked */ - } else { - put_bits(&pb, 1, 0); /* audio locked */ - put_bits(&pb, 1, 0); /* video locked */ - } - - put_bits(&pb, 1, 1); /* marker */ - - if (s->is_vcd && (only_for_stream_id & 0xe0) == AUDIO_ID) { - /* This header applies only to the audio stream (see VCD standard p. IV-7)*/ - put_bits(&pb, 5, 0); - } else - put_bits(&pb, 5, s->video_bound); - - if (s->is_dvd) { - put_bits(&pb, 1, 0); /* packet_rate_restriction_flag */ - put_bits(&pb, 7, 0x7f); /* reserved byte */ - } else - put_bits(&pb, 8, 0xff); /* reserved byte */ - - /* DVD-Video Stream_bound entries - id (0xB9) video, maximum P-STD for stream 0xE0. (P-STD_buffer_bound_scale = 1) - id (0xB8) audio, maximum P-STD for any MPEG audio (0xC0 to 0xC7) streams. If there are none set to 4096 (32x128). (P-STD_buffer_bound_scale = 0) - id (0xBD) private stream 1 (audio other than MPEG and subpictures). (P-STD_buffer_bound_scale = 1) - id (0xBF) private stream 2, NAV packs, set to 2x1024. */ - if (s->is_dvd) { - - int P_STD_max_video = 0; - int P_STD_max_mpeg_audio = 0; - int P_STD_max_mpeg_PS1 = 0; - - for(i=0;inb_streams;i++) { - StreamInfo *stream = ctx->streams[i]->priv_data; - - id = stream->id; - if (id == 0xbd && stream->max_buffer_size > P_STD_max_mpeg_PS1) { - P_STD_max_mpeg_PS1 = stream->max_buffer_size; - } else if (id >= 0xc0 && id <= 0xc7 && stream->max_buffer_size > P_STD_max_mpeg_audio) { - P_STD_max_mpeg_audio = stream->max_buffer_size; - } else if (id == 0xe0 && stream->max_buffer_size > P_STD_max_video) { - P_STD_max_video = stream->max_buffer_size; - } - } - - /* video */ - put_bits(&pb, 8, 0xb9); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 1); - put_bits(&pb, 13, P_STD_max_video / 1024); - - /* audio */ - if (P_STD_max_mpeg_audio == 0) - P_STD_max_mpeg_audio = 4096; - put_bits(&pb, 8, 0xb8); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 0); - put_bits(&pb, 13, P_STD_max_mpeg_audio / 128); - - /* private stream 1 */ - put_bits(&pb, 8, 0xbd); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 0); - put_bits(&pb, 13, P_STD_max_mpeg_PS1 / 128); - - /* private stream 2 */ - put_bits(&pb, 8, 0xbf); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 1); - put_bits(&pb, 13, 2); - } - else { - /* audio stream info */ - private_stream_coded = 0; - for(i=0;inb_streams;i++) { - StreamInfo *stream = ctx->streams[i]->priv_data; - - - /* For VCDs, only include the stream info for the stream - that the pack which contains this system belongs to. - (see VCD standard p. IV-7) */ - if ( !s->is_vcd || stream->id==only_for_stream_id - || only_for_stream_id==0) { - - id = stream->id; - if (id < 0xc0) { - /* special case for private streams (AC-3 uses that) */ - if (private_stream_coded) - continue; - private_stream_coded = 1; - id = 0xbd; - } - put_bits(&pb, 8, id); /* stream ID */ - put_bits(&pb, 2, 3); - if (id < 0xe0) { - /* audio */ - put_bits(&pb, 1, 0); - put_bits(&pb, 13, stream->max_buffer_size / 128); - } else { - /* video */ - put_bits(&pb, 1, 1); - put_bits(&pb, 13, stream->max_buffer_size / 1024); - } - } - } - } - - flush_put_bits(&pb); - size = put_bits_ptr(&pb) - pb.buf; - /* patch packet size */ - buf[4] = (size - 6) >> 8; - buf[5] = (size - 6) & 0xff; - - return size; -} - -static int get_system_header_size(AVFormatContext *ctx) -{ - int buf_index, i, private_stream_coded; - StreamInfo *stream; - MpegMuxContext *s = ctx->priv_data; - - if (s->is_dvd) - return 18; // DVD-Video system headers are 18 bytes fixed length. - - buf_index = 12; - private_stream_coded = 0; - for(i=0;inb_streams;i++) { - stream = ctx->streams[i]->priv_data; - if (stream->id < 0xc0) { - if (private_stream_coded) - continue; - private_stream_coded = 1; - } - buf_index += 3; - } - return buf_index; -} - -static int mpeg_mux_init(AVFormatContext *ctx) -{ - MpegMuxContext *s = ctx->priv_data; - int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j; - AVStream *st; - StreamInfo *stream; - int audio_bitrate; - int video_bitrate; - - s->packet_number = 0; - s->is_vcd = (CONFIG_MPEG1VCD_MUXER && ctx->oformat == &mpeg1vcd_muxer); - s->is_svcd = (CONFIG_MPEG2SVCD_MUXER && ctx->oformat == &mpeg2svcd_muxer); - s->is_mpeg2 = ((CONFIG_MPEG2VOB_MUXER && ctx->oformat == &mpeg2vob_muxer) || - (CONFIG_MPEG2DVD_MUXER && ctx->oformat == &mpeg2dvd_muxer) || - (CONFIG_MPEG2SVCD_MUXER && ctx->oformat == &mpeg2svcd_muxer)); - s->is_dvd = (CONFIG_MPEG2DVD_MUXER && ctx->oformat == &mpeg2dvd_muxer); - - if(ctx->packet_size) { - if (ctx->packet_size < 20 || ctx->packet_size > (1 << 23) + 10) { - av_log(ctx, AV_LOG_ERROR, "Invalid packet size %d\n", - ctx->packet_size); - goto fail; - } - s->packet_size = ctx->packet_size; - } else - s->packet_size = 2048; - - s->vcd_padding_bytes_written = 0; - s->vcd_padding_bitrate=0; - - s->audio_bound = 0; - s->video_bound = 0; - mpa_id = AUDIO_ID; - ac3_id = AC3_ID; - dts_id = DTS_ID; - mpv_id = VIDEO_ID; - mps_id = SUB_ID; - lpcm_id = LPCM_ID; - for(i=0;inb_streams;i++) { - st = ctx->streams[i]; - stream = av_mallocz(sizeof(StreamInfo)); - if (!stream) - goto fail; - st->priv_data = stream; - - av_set_pts_info(st, 64, 1, 90000); - - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if (st->codec->codec_id == CODEC_ID_AC3) { - stream->id = ac3_id++; - } else if (st->codec->codec_id == CODEC_ID_DTS) { - stream->id = dts_id++; - } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) { - stream->id = lpcm_id++; - for(j = 0; j < 4; j++) { - if (lpcm_freq_tab[j] == st->codec->sample_rate) - break; - } - if (j == 4) - goto fail; - if (st->codec->channels > 8) - return -1; - stream->lpcm_header[0] = 0x0c; - stream->lpcm_header[1] = (st->codec->channels - 1) | (j << 4); - stream->lpcm_header[2] = 0x80; - stream->lpcm_align = st->codec->channels * 2; - } else { - stream->id = mpa_id++; - } - - /* This value HAS to be used for VCD (see VCD standard, p. IV-7). - Right now it is also used for everything else.*/ - stream->max_buffer_size = 4 * 1024; - s->audio_bound++; - break; - case AVMEDIA_TYPE_VIDEO: - stream->id = mpv_id++; - if (st->codec->rc_buffer_size) - stream->max_buffer_size = 6*1024 + st->codec->rc_buffer_size/8; - else - stream->max_buffer_size = 230*1024; //FIXME this is probably too small as default -#if 0 - /* see VCD standard, p. IV-7*/ - stream->max_buffer_size = 46 * 1024; - else - /* This value HAS to be used for SVCD (see SVCD standard, p. 26 V.2.3.2). - Right now it is also used for everything else.*/ - stream->max_buffer_size = 230 * 1024; -#endif - s->video_bound++; - break; - case AVMEDIA_TYPE_SUBTITLE: - stream->id = mps_id++; - stream->max_buffer_size = 16 * 1024; - break; - default: - return -1; - } - stream->fifo= av_fifo_alloc(16); - if (!stream->fifo) - goto fail; - } - bitrate = 0; - audio_bitrate = 0; - video_bitrate = 0; - for(i=0;inb_streams;i++) { - int codec_rate; - st = ctx->streams[i]; - stream = (StreamInfo*) st->priv_data; - - if(st->codec->rc_max_rate || stream->id==VIDEO_ID) - codec_rate= st->codec->rc_max_rate; - else - codec_rate= st->codec->bit_rate; - - if(!codec_rate) - codec_rate= (1<<21)*8*50/ctx->nb_streams; - - bitrate += codec_rate; - - if ((stream->id & 0xe0) == AUDIO_ID) - audio_bitrate += codec_rate; - else if (stream->id==VIDEO_ID) - video_bitrate += codec_rate; - } - - if(ctx->mux_rate){ - s->mux_rate= (ctx->mux_rate + (8 * 50) - 1) / (8 * 50); - } else { - /* we increase slightly the bitrate to take into account the - headers. XXX: compute it exactly */ - bitrate += bitrate*5/100; - bitrate += 10000; - s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); - } - - if (s->is_vcd) { - double overhead_rate; - - /* The VCD standard mandates that the mux_rate field is 3528 - (see standard p. IV-6). - The value is actually "wrong", i.e. if you calculate - it using the normal formula and the 75 sectors per second transfer - rate you get a different value because the real pack size is 2324, - not 2352. But the standard explicitly specifies that the mux_rate - field in the header must have this value.*/ -// s->mux_rate=2352 * 75 / 50; /* = 3528*/ - - /* The VCD standard states that the muxed stream must be - exactly 75 packs / second (the data rate of a single speed cdrom). - Since the video bitrate (probably 1150000 bits/sec) will be below - the theoretical maximum we have to add some padding packets - to make up for the lower data rate. - (cf. VCD standard p. IV-6 )*/ - - /* Add the header overhead to the data rate. - 2279 data bytes per audio pack, 2294 data bytes per video pack*/ - overhead_rate = ((audio_bitrate / 8.0) / 2279) * (2324 - 2279); - overhead_rate += ((video_bitrate / 8.0) / 2294) * (2324 - 2294); - overhead_rate *= 8; - - /* Add padding so that the full bitrate is 2324*75 bytes/sec */ - s->vcd_padding_bitrate = 2324 * 75 * 8 - (bitrate + overhead_rate); - } - - if (s->is_vcd || s->is_mpeg2) - /* every packet */ - s->pack_header_freq = 1; - else - /* every 2 seconds */ - s->pack_header_freq = 2 * bitrate / s->packet_size / 8; - - /* the above seems to make pack_header_freq zero sometimes */ - if (s->pack_header_freq == 0) - s->pack_header_freq = 1; - - if (s->is_mpeg2) - /* every 200 packets. Need to look at the spec. */ - s->system_header_freq = s->pack_header_freq * 40; - else if (s->is_vcd) - /* the standard mandates that there are only two system headers - in the whole file: one in the first packet of each stream. - (see standard p. IV-7 and IV-8) */ - s->system_header_freq = 0x7fffffff; - else - s->system_header_freq = s->pack_header_freq * 5; - - for(i=0;inb_streams;i++) { - stream = ctx->streams[i]->priv_data; - stream->packet_number = 0; - } - s->system_header_size = get_system_header_size(ctx); - s->last_scr = 0; - return 0; - fail: - for(i=0;inb_streams;i++) { - av_free(ctx->streams[i]->priv_data); - } - return AVERROR(ENOMEM); -} - -static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp) -{ - put_byte(pb, - (id << 4) | - (((timestamp >> 30) & 0x07) << 1) | - 1); - put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); - put_be16(pb, (uint16_t)((((timestamp ) & 0x7fff) << 1) | 1)); -} - - -/* return the number of padding bytes that should be inserted into - the multiplexed stream.*/ -static int get_vcd_padding_size(AVFormatContext *ctx, int64_t pts) -{ - MpegMuxContext *s = ctx->priv_data; - int pad_bytes = 0; - - if (s->vcd_padding_bitrate > 0 && pts!=AV_NOPTS_VALUE) - { - int64_t full_pad_bytes; - - full_pad_bytes = (int64_t)((s->vcd_padding_bitrate * (pts / 90000.0)) / 8.0); //FIXME this is wrong - pad_bytes = (int) (full_pad_bytes - s->vcd_padding_bytes_written); - - if (pad_bytes<0) - /* might happen if we have already padded to a later timestamp. This - can occur if another stream has already advanced further.*/ - pad_bytes=0; - } - - return pad_bytes; -} - - -#if 0 /* unused, remove? */ -/* return the exact available payload size for the next packet for - stream 'stream_index'. 'pts' and 'dts' are only used to know if - timestamps are needed in the packet header. */ -static int get_packet_payload_size(AVFormatContext *ctx, int stream_index, - int64_t pts, int64_t dts) -{ - MpegMuxContext *s = ctx->priv_data; - int buf_index; - StreamInfo *stream; - - stream = ctx->streams[stream_index]->priv_data; - - buf_index = 0; - if (((s->packet_number % s->pack_header_freq) == 0)) { - /* pack header size */ - if (s->is_mpeg2) - buf_index += 14; - else - buf_index += 12; - - if (s->is_vcd) { - /* there is exactly one system header for each stream in a VCD MPEG, - One in the very first video packet and one in the very first - audio packet (see VCD standard p. IV-7 and IV-8).*/ - - if (stream->packet_number==0) - /* The system headers refer only to the stream they occur in, - so they have a constant size.*/ - buf_index += 15; - - } else { - if ((s->packet_number % s->system_header_freq) == 0) - buf_index += s->system_header_size; - } - } - - if ((s->is_vcd && stream->packet_number==0) - || (s->is_svcd && s->packet_number==0)) - /* the first pack of each stream contains only the pack header, - the system header and some padding (see VCD standard p. IV-6) - Add the padding size, so that the actual payload becomes 0.*/ - buf_index += s->packet_size - buf_index; - else { - /* packet header size */ - buf_index += 6; - if (s->is_mpeg2) { - buf_index += 3; - if (stream->packet_number==0) - buf_index += 3; /* PES extension */ - buf_index += 1; /* obligatory stuffing byte */ - } - if (pts != AV_NOPTS_VALUE) { - if (dts != pts) - buf_index += 5 + 5; - else - buf_index += 5; - - } else { - if (!s->is_mpeg2) - buf_index++; - } - - if (stream->id < 0xc0) { - /* AC-3/LPCM private data header */ - buf_index += 4; - if (stream->id >= 0xa0) { - int n; - buf_index += 3; - /* NOTE: we round the payload size to an integer number of - LPCM samples */ - n = (s->packet_size - buf_index) % stream->lpcm_align; - if (n) - buf_index += (stream->lpcm_align - n); - } - } - - if (s->is_vcd && (stream->id & 0xe0) == AUDIO_ID) - /* The VCD standard demands that 20 zero bytes follow - each audio packet (see standard p. IV-8).*/ - buf_index+=20; - } - return s->packet_size - buf_index; -} -#endif - -/* Write an MPEG padding packet header. */ -static void put_padding_packet(AVFormatContext *ctx, ByteIOContext *pb,int packet_bytes) -{ - MpegMuxContext *s = ctx->priv_data; - int i; - - put_be32(pb, PADDING_STREAM); - put_be16(pb, packet_bytes - 6); - if (!s->is_mpeg2) { - put_byte(pb, 0x0f); - packet_bytes -= 7; - } else - packet_bytes -= 6; - - for(i=0;ipremux_packet; - - while(len>0){ - if(pkt_desc->size == pkt_desc->unwritten_size) - nb_frames++; - len -= pkt_desc->unwritten_size; - pkt_desc= pkt_desc->next; - } - - return nb_frames; -} - -/* flush the packet on stream stream_index */ -static int flush_packet(AVFormatContext *ctx, int stream_index, - int64_t pts, int64_t dts, int64_t scr, int trailer_size) -{ - MpegMuxContext *s = ctx->priv_data; - StreamInfo *stream = ctx->streams[stream_index]->priv_data; - uint8_t *buf_ptr; - int size, payload_size, startcode, id, stuffing_size, i, header_len; - int packet_size; - uint8_t buffer[128]; - int zero_trail_bytes = 0; - int pad_packet_bytes = 0; - int pes_flags; - int general_pack = 0; /*"general" pack without data specific to one stream?*/ - int nb_frames; - - id = stream->id; - -#if 0 - printf("packet ID=%2x PTS=%0.3f\n", - id, pts / 90000.0); -#endif - - buf_ptr = buffer; - - if ((s->packet_number % s->pack_header_freq) == 0 || s->last_scr != scr) { - /* output pack and systems header if needed */ - size = put_pack_header(ctx, buf_ptr, scr); - buf_ptr += size; - s->last_scr= scr; - - if (s->is_vcd) { - /* there is exactly one system header for each stream in a VCD MPEG, - One in the very first video packet and one in the very first - audio packet (see VCD standard p. IV-7 and IV-8).*/ - - if (stream->packet_number==0) { - size = put_system_header(ctx, buf_ptr, id); - buf_ptr += size; - } - } else if (s->is_dvd) { - if (stream->align_iframe || s->packet_number == 0){ - int PES_bytes_to_fill = s->packet_size - size - 10; - - if (pts != AV_NOPTS_VALUE) { - if (dts != pts) - PES_bytes_to_fill -= 5 + 5; - else - PES_bytes_to_fill -= 5; - } - - if (stream->bytes_to_iframe == 0 || s->packet_number == 0) { - size = put_system_header(ctx, buf_ptr, 0); - buf_ptr += size; - size = buf_ptr - buffer; - put_buffer(ctx->pb, buffer, size); - - put_be32(ctx->pb, PRIVATE_STREAM_2); - put_be16(ctx->pb, 0x03d4); // length - put_byte(ctx->pb, 0x00); // substream ID, 00=PCI - for (i = 0; i < 979; i++) - put_byte(ctx->pb, 0x00); - - put_be32(ctx->pb, PRIVATE_STREAM_2); - put_be16(ctx->pb, 0x03fa); // length - put_byte(ctx->pb, 0x01); // substream ID, 01=DSI - for (i = 0; i < 1017; i++) - put_byte(ctx->pb, 0x00); - - memset(buffer, 0, 128); - buf_ptr = buffer; - s->packet_number++; - stream->align_iframe = 0; - scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet - size = put_pack_header(ctx, buf_ptr, scr); - s->last_scr= scr; - buf_ptr += size; - /* GOP Start */ - } else if (stream->bytes_to_iframe < PES_bytes_to_fill) { - pad_packet_bytes = PES_bytes_to_fill - stream->bytes_to_iframe; - } - } - } else { - if ((s->packet_number % s->system_header_freq) == 0) { - size = put_system_header(ctx, buf_ptr, 0); - buf_ptr += size; - } - } - } - size = buf_ptr - buffer; - put_buffer(ctx->pb, buffer, size); - - packet_size = s->packet_size - size; - - if (s->is_vcd && (id & 0xe0) == AUDIO_ID) - /* The VCD standard demands that 20 zero bytes follow - each audio pack (see standard p. IV-8).*/ - zero_trail_bytes += 20; - - if ((s->is_vcd && stream->packet_number==0) - || (s->is_svcd && s->packet_number==0)) { - /* for VCD the first pack of each stream contains only the pack header, - the system header and lots of padding (see VCD standard p. IV-6). - In the case of an audio pack, 20 zero bytes are also added at - the end.*/ - /* For SVCD we fill the very first pack to increase compatibility with - some DVD players. Not mandated by the standard.*/ - if (s->is_svcd) - general_pack = 1; /* the system header refers to both streams and no stream data*/ - pad_packet_bytes = packet_size - zero_trail_bytes; - } - - packet_size -= pad_packet_bytes + zero_trail_bytes; - - if (packet_size > 0) { - - /* packet header size */ - packet_size -= 6; - - /* packet header */ - if (s->is_mpeg2) { - header_len = 3; - if (stream->packet_number==0) - header_len += 3; /* PES extension */ - header_len += 1; /* obligatory stuffing byte */ - } else { - header_len = 0; - } - if (pts != AV_NOPTS_VALUE) { - if (dts != pts) - header_len += 5 + 5; - else - header_len += 5; - } else { - if (!s->is_mpeg2) - header_len++; - } - - payload_size = packet_size - header_len; - if (id < 0xc0) { - startcode = PRIVATE_STREAM_1; - payload_size -= 1; - if (id >= 0x40) { - payload_size -= 3; - if (id >= 0xa0) - payload_size -= 3; - } - } else { - startcode = 0x100 + id; - } - - stuffing_size = payload_size - av_fifo_size(stream->fifo); - - // first byte does not fit -> reset pts/dts + stuffing - if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){ - int timestamp_len=0; - if(dts != pts) - timestamp_len += 5; - if(pts != AV_NOPTS_VALUE) - timestamp_len += s->is_mpeg2 ? 5 : 4; - pts=dts= AV_NOPTS_VALUE; - header_len -= timestamp_len; - if (s->is_dvd && stream->align_iframe) { - pad_packet_bytes += timestamp_len; - packet_size -= timestamp_len; - } else { - payload_size += timestamp_len; - } - stuffing_size += timestamp_len; - if(payload_size > trailer_size) - stuffing_size += payload_size - trailer_size; - } - - if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) { // can't use padding, so use stuffing - packet_size += pad_packet_bytes; - payload_size += pad_packet_bytes; // undo the previous adjustment - if (stuffing_size < 0) { - stuffing_size = pad_packet_bytes; - } else { - stuffing_size += pad_packet_bytes; - } - pad_packet_bytes = 0; - } - - if (stuffing_size < 0) - stuffing_size = 0; - if (stuffing_size > 16) { /*<=16 for MPEG-1, <=32 for MPEG-2*/ - pad_packet_bytes += stuffing_size; - packet_size -= stuffing_size; - payload_size -= stuffing_size; - stuffing_size = 0; - } - - nb_frames= get_nb_frames(ctx, stream, payload_size - stuffing_size); - - put_be32(ctx->pb, startcode); - - put_be16(ctx->pb, packet_size); - - if (!s->is_mpeg2) - for(i=0;ipb, 0xff); - - if (s->is_mpeg2) { - put_byte(ctx->pb, 0x80); /* mpeg2 id */ - - pes_flags=0; - - if (pts != AV_NOPTS_VALUE) { - pes_flags |= 0x80; - if (dts != pts) - pes_flags |= 0x40; - } - - /* Both the MPEG-2 and the SVCD standards demand that the - P-STD_buffer_size field be included in the first packet of - every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2 - and MPEG-2 standard 2.7.7) */ - if (stream->packet_number == 0) - pes_flags |= 0x01; - - put_byte(ctx->pb, pes_flags); /* flags */ - put_byte(ctx->pb, header_len - 3 + stuffing_size); - - if (pes_flags & 0x80) /*write pts*/ - put_timestamp(ctx->pb, (pes_flags & 0x40) ? 0x03 : 0x02, pts); - if (pes_flags & 0x40) /*write dts*/ - put_timestamp(ctx->pb, 0x01, dts); - - if (pes_flags & 0x01) { /*write pes extension*/ - put_byte(ctx->pb, 0x10); /* flags */ - - /* P-STD buffer info */ - if ((id & 0xe0) == AUDIO_ID) - put_be16(ctx->pb, 0x4000 | stream->max_buffer_size/ 128); - else - put_be16(ctx->pb, 0x6000 | stream->max_buffer_size/1024); - } - - } else { - if (pts != AV_NOPTS_VALUE) { - if (dts != pts) { - put_timestamp(ctx->pb, 0x03, pts); - put_timestamp(ctx->pb, 0x01, dts); - } else { - put_timestamp(ctx->pb, 0x02, pts); - } - } else { - put_byte(ctx->pb, 0x0f); - } - } - - if (s->is_mpeg2) { - /* special stuffing byte that is always written - to prevent accidental generation of start codes. */ - put_byte(ctx->pb, 0xff); - - for(i=0;ipb, 0xff); - } - - if (startcode == PRIVATE_STREAM_1) { - put_byte(ctx->pb, id); - if (id >= 0xa0) { - /* LPCM (XXX: check nb_frames) */ - put_byte(ctx->pb, 7); - put_be16(ctx->pb, 4); /* skip 3 header bytes */ - put_byte(ctx->pb, stream->lpcm_header[0]); - put_byte(ctx->pb, stream->lpcm_header[1]); - put_byte(ctx->pb, stream->lpcm_header[2]); - } else if (id >= 0x40) { - /* AC-3 */ - put_byte(ctx->pb, nb_frames); - put_be16(ctx->pb, trailer_size+1); - } - } - - /* output data */ - assert(payload_size - stuffing_size <= av_fifo_size(stream->fifo)); - av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, &put_buffer); - stream->bytes_to_iframe -= payload_size - stuffing_size; - }else{ - payload_size= - stuffing_size= 0; - } - - if (pad_packet_bytes > 0) - put_padding_packet(ctx,ctx->pb, pad_packet_bytes); - - for(i=0;ipb, 0x00); - - put_flush_packet(ctx->pb); - - s->packet_number++; - - /* only increase the stream packet number if this pack actually contains - something that is specific to this stream! I.e. a dedicated header - or some data.*/ - if (!general_pack) - stream->packet_number++; - - return payload_size - stuffing_size; -} - -static void put_vcd_padding_sector(AVFormatContext *ctx) -{ - /* There are two ways to do this padding: writing a sector/pack - of 0 values, or writing an MPEG padding pack. Both seem to - work with most decoders, BUT the VCD standard only allows a 0-sector - (see standard p. IV-4, IV-5). - So a 0-sector it is...*/ - - MpegMuxContext *s = ctx->priv_data; - int i; - - for(i=0;ipacket_size;i++) - put_byte(ctx->pb, 0); - - s->vcd_padding_bytes_written += s->packet_size; - - put_flush_packet(ctx->pb); - - /* increasing the packet number is correct. The SCR of the following packs - is calculated from the packet_number and it has to include the padding - sector (it represents the sector index, not the MPEG pack index) - (see VCD standard p. IV-6)*/ - s->packet_number++; -} - -#if 0 /* unused, remove? */ -static int64_t get_vcd_scr(AVFormatContext *ctx,int stream_index,int64_t pts) -{ - MpegMuxContext *s = ctx->priv_data; - int64_t scr; - - /* Since the data delivery rate is constant, SCR is computed - using the formula C + i * 1200 where C is the start constant - and i is the pack index. - It is recommended that SCR 0 is at the beginning of the VCD front - margin (a sequence of empty Form 2 sectors on the CD). - It is recommended that the front margin is 30 sectors long, so - we use C = 30*1200 = 36000 - (Note that even if the front margin is not 30 sectors the file - will still be correct according to the standard. It just won't have - the "recommended" value).*/ - scr = 36000 + s->packet_number * 1200; - - return scr; -} -#endif - -static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){ -// MpegMuxContext *s = ctx->priv_data; - int i; - - for(i=0; inb_streams; i++){ - AVStream *st = ctx->streams[i]; - StreamInfo *stream = st->priv_data; - PacketDesc *pkt_desc; - - while((pkt_desc= stream->predecode_packet) - && scr > pkt_desc->dts){ //FIXME > vs >= - if(stream->buffer_index < pkt_desc->size || - stream->predecode_packet == stream->premux_packet){ - av_log(ctx, AV_LOG_ERROR, - "buffer underflow i=%d bufi=%d size=%d\n", - i, stream->buffer_index, pkt_desc->size); - break; - } - stream->buffer_index -= pkt_desc->size; - - stream->predecode_packet= pkt_desc->next; - av_freep(&pkt_desc); - } - } - - return 0; -} - -static int output_packet(AVFormatContext *ctx, int flush){ - MpegMuxContext *s = ctx->priv_data; - AVStream *st; - StreamInfo *stream; - int i, avail_space=0, es_size, trailer_size; - int best_i= -1; - int best_score= INT_MIN; - int ignore_constraints=0; - int64_t scr= s->last_scr; - PacketDesc *timestamp_packet; - const int64_t max_delay= av_rescale(ctx->max_delay, 90000, AV_TIME_BASE); - -retry: - for(i=0; inb_streams; i++){ - AVStream *st = ctx->streams[i]; - StreamInfo *stream = st->priv_data; - const int avail_data= av_fifo_size(stream->fifo); - const int space= stream->max_buffer_size - stream->buffer_index; - int rel_space= 1024*space / stream->max_buffer_size; - PacketDesc *next_pkt= stream->premux_packet; - - /* for subtitle, a single PES packet must be generated, - so we flush after every single subtitle packet */ - if(s->packet_size > avail_data && !flush - && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) - return 0; - if(avail_data==0) - continue; - assert(avail_data>0); - - if(space < s->packet_size && !ignore_constraints) - continue; - - if(next_pkt && next_pkt->dts - scr > max_delay) - continue; - - if(rel_space > best_score){ - best_score= rel_space; - best_i = i; - avail_space= space; - } - } - - if(best_i < 0){ - int64_t best_dts= INT64_MAX; - - for(i=0; inb_streams; i++){ - AVStream *st = ctx->streams[i]; - StreamInfo *stream = st->priv_data; - PacketDesc *pkt_desc= stream->predecode_packet; - if(pkt_desc && pkt_desc->dts < best_dts) - best_dts= pkt_desc->dts; - } - -#if 0 - av_log(ctx, AV_LOG_DEBUG, "bumping scr, scr:%f, dts:%f\n", - scr/90000.0, best_dts/90000.0); -#endif - if(best_dts == INT64_MAX) - return 0; - - if(scr >= best_dts+1 && !ignore_constraints){ - av_log(ctx, AV_LOG_ERROR, "packet too large, ignoring buffer limits to mux it\n"); - ignore_constraints= 1; - } - scr= FFMAX(best_dts+1, scr); - if(remove_decoded_packets(ctx, scr) < 0) - return -1; - goto retry; - } - - assert(best_i >= 0); - - st = ctx->streams[best_i]; - stream = st->priv_data; - - assert(av_fifo_size(stream->fifo) > 0); - - assert(avail_space >= s->packet_size || ignore_constraints); - - timestamp_packet= stream->premux_packet; - if(timestamp_packet->unwritten_size == timestamp_packet->size){ - trailer_size= 0; - }else{ - trailer_size= timestamp_packet->unwritten_size; - timestamp_packet= timestamp_packet->next; - } - - if(timestamp_packet){ -//av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f scr:%f stream:%d\n", timestamp_packet->dts/90000.0, timestamp_packet->pts/90000.0, scr/90000.0, best_i); - es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size); - }else{ - assert(av_fifo_size(stream->fifo) == trailer_size); - es_size= flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr, trailer_size); - } - - if (s->is_vcd) { - /* Write one or more padding sectors, if necessary, to reach - the constant overall bitrate.*/ - int vcd_pad_bytes; - - while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->premux_packet->pts) ) >= s->packet_size){ //FIXME pts cannot be correct here - put_vcd_padding_sector(ctx); - s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet - } - } - - stream->buffer_index += es_size; - s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet - - while(stream->premux_packet && stream->premux_packet->unwritten_size <= es_size){ - es_size -= stream->premux_packet->unwritten_size; - stream->premux_packet= stream->premux_packet->next; - } - if(es_size) - stream->premux_packet->unwritten_size -= es_size; - - if(remove_decoded_packets(ctx, s->last_scr) < 0) - return -1; - - return 1; -} - -static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) -{ - MpegMuxContext *s = ctx->priv_data; - int stream_index= pkt->stream_index; - int size= pkt->size; - uint8_t *buf= pkt->data; - AVStream *st = ctx->streams[stream_index]; - StreamInfo *stream = st->priv_data; - int64_t pts, dts; - PacketDesc *pkt_desc; - const int preload= av_rescale(ctx->preload, 90000, AV_TIME_BASE); - const int is_iframe = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY); - - pts= pkt->pts; - dts= pkt->dts; - - if(pts != AV_NOPTS_VALUE) pts += preload; - if(dts != AV_NOPTS_VALUE) dts += preload; - -//av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", dts/90000.0, pts/90000.0, pkt->flags, pkt->stream_index, pts != AV_NOPTS_VALUE); - if (!stream->premux_packet) - stream->next_packet = &stream->premux_packet; - *stream->next_packet= - pkt_desc= av_mallocz(sizeof(PacketDesc)); - pkt_desc->pts= pts; - pkt_desc->dts= dts; - pkt_desc->unwritten_size= - pkt_desc->size= size; - if(!stream->predecode_packet) - stream->predecode_packet= pkt_desc; - stream->next_packet= &pkt_desc->next; - - if (av_fifo_realloc2(stream->fifo, av_fifo_size(stream->fifo) + size) < 0) - return -1; - - if (s->is_dvd){ - if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder) - stream->bytes_to_iframe = av_fifo_size(stream->fifo); - stream->align_iframe = 1; - stream->vobu_start_pts = pts; - } - } - - av_fifo_generic_write(stream->fifo, buf, size, NULL); - - for(;;){ - int ret= output_packet(ctx, 0); - if(ret<=0) - return ret; - } -} - -static int mpeg_mux_end(AVFormatContext *ctx) -{ -// MpegMuxContext *s = ctx->priv_data; - StreamInfo *stream; - int i; - - for(;;){ - int ret= output_packet(ctx, 1); - if(ret<0) - return ret; - else if(ret==0) - break; - } - - /* End header according to MPEG1 systems standard. We do not write - it as it is usually not needed by decoders and because it - complicates MPEG stream concatenation. */ - //put_be32(ctx->pb, ISO_11172_END_CODE); - //put_flush_packet(ctx->pb); - - for(i=0;inb_streams;i++) { - stream = ctx->streams[i]->priv_data; - - assert(av_fifo_size(stream->fifo) == 0); - av_fifo_free(stream->fifo); - } - return 0; -} - -#if CONFIG_MPEG1SYSTEM_MUXER -AVOutputFormat mpeg1system_muxer = { - "mpeg", - NULL_IF_CONFIG_SMALL("MPEG-1 System format"), - "video/mpeg", - "mpg,mpeg", - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG1VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; -#endif -#if CONFIG_MPEG1VCD_MUXER -AVOutputFormat mpeg1vcd_muxer = { - "vcd", - NULL_IF_CONFIG_SMALL("MPEG-1 System format (VCD)"), - "video/mpeg", - NULL, - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG1VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; -#endif -#if CONFIG_MPEG2VOB_MUXER -AVOutputFormat mpeg2vob_muxer = { - "vob", - NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"), - "video/mpeg", - "vob", - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG2VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; -#endif - -/* Same as mpeg2vob_mux except that the pack size is 2324 */ -#if CONFIG_MPEG2SVCD_MUXER -AVOutputFormat mpeg2svcd_muxer = { - "svcd", - NULL_IF_CONFIG_SMALL("MPEG-2 PS format (VOB)"), - "video/mpeg", - "vob", - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG2VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; -#endif - -/* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */ -#if CONFIG_MPEG2DVD_MUXER -AVOutputFormat mpeg2dvd_muxer = { - "dvd", - NULL_IF_CONFIG_SMALL("MPEG-2 PS format (DVD VOB)"), - "video/mpeg", - "dvd", - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG2VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/mpegts.c b/tizen/distrib/ffmpeg/libavformat/mpegts.c deleted file mode 100644 index 5960338..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpegts.c +++ /dev/null @@ -1,1785 +0,0 @@ -/* - * MPEG2 transport stream (aka DVB) demuxer - * Copyright (c) 2002-2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//#define DEBUG -//#define DEBUG_SEEK -//#define USE_SYNCPOINT_SEARCH - -#include "libavutil/crc.h" -#include "libavutil/intreadwrite.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "mpegts.h" -#include "internal.h" -#include "seek.h" - -/* 1.0 second at 24Mbit/s */ -#define MAX_SCAN_PACKETS 32000 - -/* maximum size in which we look for synchronisation if - synchronisation is lost */ -#define MAX_RESYNC_SIZE 65536 - -#define MAX_PES_PAYLOAD 200*1024 - -enum MpegTSFilterType { - MPEGTS_PES, - MPEGTS_SECTION, -}; - -typedef struct MpegTSFilter MpegTSFilter; - -typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos); - -typedef struct MpegTSPESFilter { - PESCallback *pes_cb; - void *opaque; -} MpegTSPESFilter; - -typedef void SectionCallback(MpegTSFilter *f, const uint8_t *buf, int len); - -typedef void SetServiceCallback(void *opaque, int ret); - -typedef struct MpegTSSectionFilter { - int section_index; - int section_h_size; - uint8_t *section_buf; - unsigned int check_crc:1; - unsigned int end_of_section_reached:1; - SectionCallback *section_cb; - void *opaque; -} MpegTSSectionFilter; - -struct MpegTSFilter { - int pid; - int last_cc; /* last cc code (-1 if first packet) */ - enum MpegTSFilterType type; - union { - MpegTSPESFilter pes_filter; - MpegTSSectionFilter section_filter; - } u; -}; - -#define MAX_PIDS_PER_PROGRAM 64 -struct Program { - unsigned int id; //program id/service id - unsigned int nb_pids; - unsigned int pids[MAX_PIDS_PER_PROGRAM]; -}; - -struct MpegTSContext { - /* user data */ - AVFormatContext *stream; - /** raw packet size, including FEC if present */ - int raw_packet_size; - - int pos47; - - /** if true, all pids are analyzed to find streams */ - int auto_guess; - - /** compute exact PCR for each transport stream packet */ - int mpeg2ts_compute_pcr; - - int64_t cur_pcr; /**< used to estimate the exact PCR */ - int pcr_incr; /**< used to estimate the exact PCR */ - - /* data needed to handle file based ts */ - /** stop parsing loop */ - int stop_parse; - /** packet containing Audio/Video data */ - AVPacket *pkt; - /** to detect seek */ - int64_t last_pos; - - /******************************************/ - /* private mpegts data */ - /* scan context */ - /** structure to keep track of Program->pids mapping */ - unsigned int nb_prg; - struct Program *prg; - - - /** filters for various streams specified by PMT + for the PAT and PMT */ - MpegTSFilter *pids[NB_PID_MAX]; -}; - -/* TS stream handling */ - -enum MpegTSState { - MPEGTS_HEADER = 0, - MPEGTS_PESHEADER, - MPEGTS_PESHEADER_FILL, - MPEGTS_PAYLOAD, - MPEGTS_SKIP, -}; - -/* enough for PES header + length */ -#define PES_START_SIZE 6 -#define PES_HEADER_SIZE 9 -#define MAX_PES_HEADER_SIZE (9 + 255) - -typedef struct PESContext { - int pid; - int pcr_pid; /**< if -1 then all packets containing PCR are considered */ - int stream_type; - MpegTSContext *ts; - AVFormatContext *stream; - AVStream *st; - AVStream *sub_st; /**< stream for the embedded AC3 stream in HDMV TrueHD */ - enum MpegTSState state; - /* used to get the format */ - int data_index; - int total_size; - int pes_header_size; - int extended_stream_id; - int64_t pts, dts; - int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ - uint8_t header[MAX_PES_HEADER_SIZE]; - uint8_t *buffer; -} PESContext; - -extern AVInputFormat mpegts_demuxer; - -static void clear_program(MpegTSContext *ts, unsigned int programid) -{ - int i; - - for(i=0; inb_prg; i++) - if(ts->prg[i].id == programid) - ts->prg[i].nb_pids = 0; -} - -static void clear_programs(MpegTSContext *ts) -{ - av_freep(&ts->prg); - ts->nb_prg=0; -} - -static void add_pat_entry(MpegTSContext *ts, unsigned int programid) -{ - struct Program *p; - void *tmp = av_realloc(ts->prg, (ts->nb_prg+1)*sizeof(struct Program)); - if(!tmp) - return; - ts->prg = tmp; - p = &ts->prg[ts->nb_prg]; - p->id = programid; - p->nb_pids = 0; - ts->nb_prg++; -} - -static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned int pid) -{ - int i; - struct Program *p = NULL; - for(i=0; inb_prg; i++) { - if(ts->prg[i].id == programid) { - p = &ts->prg[i]; - break; - } - } - if(!p) - return; - - if(p->nb_pids >= MAX_PIDS_PER_PROGRAM) - return; - p->pids[p->nb_pids++] = pid; -} - -/** - * \brief discard_pid() decides if the pid is to be discarded according - * to caller's programs selection - * \param ts : - TS context - * \param pid : - pid - * \return 1 if the pid is only comprised in programs that have .discard=AVDISCARD_ALL - * 0 otherwise - */ -static int discard_pid(MpegTSContext *ts, unsigned int pid) -{ - int i, j, k; - int used = 0, discarded = 0; - struct Program *p; - for(i=0; inb_prg; i++) { - p = &ts->prg[i]; - for(j=0; jnb_pids; j++) { - if(p->pids[j] != pid) - continue; - //is program with id p->id set to be discarded? - for(k=0; kstream->nb_programs; k++) { - if(ts->stream->programs[k]->id == p->id) { - if(ts->stream->programs[k]->discard == AVDISCARD_ALL) - discarded++; - else - used++; - } - } - } - } - - return !used && discarded; -} - -/** - * Assembles PES packets out of TS packets, and then calls the "section_cb" - * function when they are complete. - */ -static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1, - const uint8_t *buf, int buf_size, int is_start) -{ - MpegTSSectionFilter *tss = &tss1->u.section_filter; - int len; - - if (is_start) { - memcpy(tss->section_buf, buf, buf_size); - tss->section_index = buf_size; - tss->section_h_size = -1; - tss->end_of_section_reached = 0; - } else { - if (tss->end_of_section_reached) - return; - len = 4096 - tss->section_index; - if (buf_size < len) - len = buf_size; - memcpy(tss->section_buf + tss->section_index, buf, len); - tss->section_index += len; - } - - /* compute section length if possible */ - if (tss->section_h_size == -1 && tss->section_index >= 3) { - len = (AV_RB16(tss->section_buf + 1) & 0xfff) + 3; - if (len > 4096) - return; - tss->section_h_size = len; - } - - if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) { - tss->end_of_section_reached = 1; - if (!tss->check_crc || - av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, - tss->section_buf, tss->section_h_size) == 0) - tss->section_cb(tss1, tss->section_buf, tss->section_h_size); - } -} - -static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid, - SectionCallback *section_cb, void *opaque, - int check_crc) - -{ - MpegTSFilter *filter; - MpegTSSectionFilter *sec; - - dprintf(ts->stream, "Filter: pid=0x%x\n", pid); - - if (pid >= NB_PID_MAX || ts->pids[pid]) - return NULL; - filter = av_mallocz(sizeof(MpegTSFilter)); - if (!filter) - return NULL; - ts->pids[pid] = filter; - filter->type = MPEGTS_SECTION; - filter->pid = pid; - filter->last_cc = -1; - sec = &filter->u.section_filter; - sec->section_cb = section_cb; - sec->opaque = opaque; - sec->section_buf = av_malloc(MAX_SECTION_SIZE); - sec->check_crc = check_crc; - if (!sec->section_buf) { - av_free(filter); - return NULL; - } - return filter; -} - -static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid, - PESCallback *pes_cb, - void *opaque) -{ - MpegTSFilter *filter; - MpegTSPESFilter *pes; - - if (pid >= NB_PID_MAX || ts->pids[pid]) - return NULL; - filter = av_mallocz(sizeof(MpegTSFilter)); - if (!filter) - return NULL; - ts->pids[pid] = filter; - filter->type = MPEGTS_PES; - filter->pid = pid; - filter->last_cc = -1; - pes = &filter->u.pes_filter; - pes->pes_cb = pes_cb; - pes->opaque = opaque; - return filter; -} - -static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) -{ - int pid; - - pid = filter->pid; - if (filter->type == MPEGTS_SECTION) - av_freep(&filter->u.section_filter.section_buf); - else if (filter->type == MPEGTS_PES) { - PESContext *pes = filter->u.pes_filter.opaque; - av_freep(&pes->buffer); - /* referenced private data will be freed later in - * av_close_input_stream */ - if (!((PESContext *)filter->u.pes_filter.opaque)->st) { - av_freep(&filter->u.pes_filter.opaque); - } - } - - av_free(filter); - ts->pids[pid] = NULL; -} - -static int analyze(const uint8_t *buf, int size, int packet_size, int *index){ - int stat[TS_MAX_PACKET_SIZE]; - int i; - int x=0; - int best_score=0; - - memset(stat, 0, packet_size*sizeof(int)); - - for(x=i=0; i best_score){ - best_score= stat[x]; - if(index) *index= x; - } - } - - x++; - if(x == packet_size) x= 0; - } - - return best_score; -} - -/* autodetect fec presence. Must have at least 1024 bytes */ -static int get_packet_size(const uint8_t *buf, int size) -{ - int score, fec_score, dvhs_score; - - if (size < (TS_FEC_PACKET_SIZE * 5 + 1)) - return -1; - - score = analyze(buf, size, TS_PACKET_SIZE, NULL); - dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, NULL); - fec_score= analyze(buf, size, TS_FEC_PACKET_SIZE, NULL); -// av_log(NULL, AV_LOG_DEBUG, "score: %d, dvhs_score: %d, fec_score: %d \n", score, dvhs_score, fec_score); - - if (score > fec_score && score > dvhs_score) return TS_PACKET_SIZE; - else if(dvhs_score > score && dvhs_score > fec_score) return TS_DVHS_PACKET_SIZE; - else if(score < fec_score && dvhs_score < fec_score) return TS_FEC_PACKET_SIZE; - else return -1; -} - -typedef struct SectionHeader { - uint8_t tid; - uint16_t id; - uint8_t version; - uint8_t sec_num; - uint8_t last_sec_num; -} SectionHeader; - -static inline int get8(const uint8_t **pp, const uint8_t *p_end) -{ - const uint8_t *p; - int c; - - p = *pp; - if (p >= p_end) - return -1; - c = *p++; - *pp = p; - return c; -} - -static inline int get16(const uint8_t **pp, const uint8_t *p_end) -{ - const uint8_t *p; - int c; - - p = *pp; - if ((p + 1) >= p_end) - return -1; - c = AV_RB16(p); - p += 2; - *pp = p; - return c; -} - -/* read and allocate a DVB string preceeded by its length */ -static char *getstr8(const uint8_t **pp, const uint8_t *p_end) -{ - int len; - const uint8_t *p; - char *str; - - p = *pp; - len = get8(&p, p_end); - if (len < 0) - return NULL; - if ((p + len) > p_end) - return NULL; - str = av_malloc(len + 1); - if (!str) - return NULL; - memcpy(str, p, len); - str[len] = '\0'; - p += len; - *pp = p; - return str; -} - -static int parse_section_header(SectionHeader *h, - const uint8_t **pp, const uint8_t *p_end) -{ - int val; - - val = get8(pp, p_end); - if (val < 0) - return -1; - h->tid = val; - *pp += 2; - val = get16(pp, p_end); - if (val < 0) - return -1; - h->id = val; - val = get8(pp, p_end); - if (val < 0) - return -1; - h->version = (val >> 1) & 0x1f; - val = get8(pp, p_end); - if (val < 0) - return -1; - h->sec_num = val; - val = get8(pp, p_end); - if (val < 0) - return -1; - h->last_sec_num = val; - return 0; -} - -typedef struct { - uint32_t stream_type; - enum AVMediaType codec_type; - enum CodecID codec_id; -} StreamType; - -static const StreamType ISO_types[] = { - { 0x01, AVMEDIA_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO }, - { 0x02, AVMEDIA_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO }, - { 0x03, AVMEDIA_TYPE_AUDIO, CODEC_ID_MP3 }, - { 0x04, AVMEDIA_TYPE_AUDIO, CODEC_ID_MP3 }, - { 0x0f, AVMEDIA_TYPE_AUDIO, CODEC_ID_AAC }, - { 0x10, AVMEDIA_TYPE_VIDEO, CODEC_ID_MPEG4 }, - //{ 0x11, AVMEDIA_TYPE_AUDIO, CODEC_ID_AAC }, /* LATM syntax */ - { 0x1b, AVMEDIA_TYPE_VIDEO, CODEC_ID_H264 }, - { 0xd1, AVMEDIA_TYPE_VIDEO, CODEC_ID_DIRAC }, - { 0xea, AVMEDIA_TYPE_VIDEO, CODEC_ID_VC1 }, - { 0 }, -}; - -static const StreamType HDMV_types[] = { - { 0x80, AVMEDIA_TYPE_AUDIO, CODEC_ID_PCM_BLURAY }, - { 0x81, AVMEDIA_TYPE_AUDIO, CODEC_ID_AC3 }, - { 0x82, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS }, - { 0x83, AVMEDIA_TYPE_AUDIO, CODEC_ID_TRUEHD }, - { 0x84, AVMEDIA_TYPE_AUDIO, CODEC_ID_EAC3 }, - { 0x90, AVMEDIA_TYPE_SUBTITLE, CODEC_ID_HDMV_PGS_SUBTITLE }, - { 0 }, -}; - -/* ATSC ? */ -static const StreamType MISC_types[] = { - { 0x81, AVMEDIA_TYPE_AUDIO, CODEC_ID_AC3 }, - { 0x8a, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS }, - { 0 }, -}; - -static const StreamType REGD_types[] = { - { MKTAG('d','r','a','c'), AVMEDIA_TYPE_VIDEO, CODEC_ID_DIRAC }, - { MKTAG('A','C','-','3'), AVMEDIA_TYPE_AUDIO, CODEC_ID_AC3 }, - { 0 }, -}; - -/* descriptor present */ -static const StreamType DESC_types[] = { - { 0x6a, AVMEDIA_TYPE_AUDIO, CODEC_ID_AC3 }, /* AC-3 descriptor */ - { 0x7a, AVMEDIA_TYPE_AUDIO, CODEC_ID_EAC3 }, /* E-AC-3 descriptor */ - { 0x7b, AVMEDIA_TYPE_AUDIO, CODEC_ID_DTS }, - { 0x56, AVMEDIA_TYPE_SUBTITLE, CODEC_ID_DVB_TELETEXT }, - { 0x59, AVMEDIA_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE }, /* subtitling descriptor */ - { 0 }, -}; - -static void mpegts_find_stream_type(AVStream *st, - uint32_t stream_type, const StreamType *types) -{ - for (; types->stream_type; types++) { - if (stream_type == types->stream_type) { - st->codec->codec_type = types->codec_type; - st->codec->codec_id = types->codec_id; - return; - } - } -} - -static int mpegts_set_stream_info(AVStream *st, PESContext *pes, - uint32_t stream_type, uint32_t prog_reg_desc) -{ - av_set_pts_info(st, 33, 1, 90000); - st->priv_data = pes; - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = CODEC_ID_NONE; - st->need_parsing = AVSTREAM_PARSE_FULL; - pes->st = st; - pes->stream_type = stream_type; - - av_log(pes->stream, AV_LOG_DEBUG, - "stream=%d stream_type=%x pid=%x prog_reg_desc=%.4s\n", - st->index, pes->stream_type, pes->pid, (char*)&prog_reg_desc); - - st->codec->codec_tag = pes->stream_type; - - mpegts_find_stream_type(st, pes->stream_type, ISO_types); - if (prog_reg_desc == AV_RL32("HDMV") && - st->codec->codec_id == CODEC_ID_NONE) { - mpegts_find_stream_type(st, pes->stream_type, HDMV_types); - if (pes->stream_type == 0x83) { - // HDMV TrueHD streams also contain an AC3 coded version of the - // audio track - add a second stream for this - AVStream *sub_st; - // priv_data cannot be shared between streams - PESContext *sub_pes = av_malloc(sizeof(*sub_pes)); - if (!sub_pes) - return AVERROR(ENOMEM); - memcpy(sub_pes, pes, sizeof(*sub_pes)); - - sub_st = av_new_stream(pes->stream, pes->pid); - if (!sub_st) { - av_free(sub_pes); - return AVERROR(ENOMEM); - } - - av_set_pts_info(sub_st, 33, 1, 90000); - sub_st->priv_data = sub_pes; - sub_st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - sub_st->codec->codec_id = CODEC_ID_AC3; - sub_st->need_parsing = AVSTREAM_PARSE_FULL; - sub_pes->sub_st = pes->sub_st = sub_st; - } - } - if (pes->stream_type == 0x11) - av_log(pes->stream, AV_LOG_WARNING, - "AAC LATM not currently supported, patch welcome\n"); - if (st->codec->codec_id == CODEC_ID_NONE) - mpegts_find_stream_type(st, pes->stream_type, MISC_types); - - return 0; -} - -static int64_t get_pts(const uint8_t *p) -{ - int64_t pts = (int64_t)((p[0] >> 1) & 0x07) << 30; - pts |= (AV_RB16(p + 1) >> 1) << 15; - pts |= AV_RB16(p + 3) >> 1; - return pts; -} - -static void new_pes_packet(PESContext *pes, AVPacket *pkt) -{ - av_init_packet(pkt); - - pkt->destruct = av_destruct_packet; - pkt->data = pes->buffer; - pkt->size = pes->data_index; - memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - // Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID - if (pes->sub_st && pes->stream_type == 0x83 && pes->extended_stream_id == 0x76) - pkt->stream_index = pes->sub_st->index; - else - pkt->stream_index = pes->st->index; - pkt->pts = pes->pts; - pkt->dts = pes->dts; - /* store position of first TS packet of this PES packet */ - pkt->pos = pes->ts_packet_pos; - - /* reset pts values */ - pes->pts = AV_NOPTS_VALUE; - pes->dts = AV_NOPTS_VALUE; - pes->buffer = NULL; - pes->data_index = 0; -} - -/* return non zero if a packet could be constructed */ -static int mpegts_push_data(MpegTSFilter *filter, - const uint8_t *buf, int buf_size, int is_start, - int64_t pos) -{ - PESContext *pes = filter->u.pes_filter.opaque; - MpegTSContext *ts = pes->ts; - const uint8_t *p; - int len, code; - - if(!ts->pkt) - return 0; - - if (is_start) { - if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { - new_pes_packet(pes, ts->pkt); - ts->stop_parse = 1; - } - pes->state = MPEGTS_HEADER; - pes->data_index = 0; - pes->ts_packet_pos = pos; - } - p = buf; - while (buf_size > 0) { - switch(pes->state) { - case MPEGTS_HEADER: - len = PES_START_SIZE - pes->data_index; - if (len > buf_size) - len = buf_size; - memcpy(pes->header + pes->data_index, p, len); - pes->data_index += len; - p += len; - buf_size -= len; - if (pes->data_index == PES_START_SIZE) { - /* we got all the PES or section header. We can now - decide */ -#if 0 - av_hex_dump_log(pes->stream, AV_LOG_DEBUG, pes->header, pes->data_index); -#endif - if (pes->header[0] == 0x00 && pes->header[1] == 0x00 && - pes->header[2] == 0x01) { - /* it must be an mpeg2 PES stream */ - code = pes->header[3] | 0x100; - dprintf(pes->stream, "pid=%x pes_code=%#x\n", pes->pid, code); - - if ((!pes->st && pes->stream->nb_streams == MAX_STREAMS) || - (pes->st && pes->st->discard == AVDISCARD_ALL) || - code == 0x1be) /* padding_stream */ - goto skip; - - /* stream not present in PMT */ - if (!pes->st) { - pes->st = av_new_stream(ts->stream, pes->pid); - if (!pes->st) - return AVERROR(ENOMEM); - mpegts_set_stream_info(pes->st, pes, 0, 0); - } - - pes->total_size = AV_RB16(pes->header + 4); - /* NOTE: a zero total size means the PES size is - unbounded */ - if (!pes->total_size) - pes->total_size = MAX_PES_PAYLOAD; - - /* allocate pes buffer */ - pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); - if (!pes->buffer) - return AVERROR(ENOMEM); - - if (code != 0x1bc && code != 0x1bf && /* program_stream_map, private_stream_2 */ - code != 0x1f0 && code != 0x1f1 && /* ECM, EMM */ - code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */ - code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */ - pes->state = MPEGTS_PESHEADER; - if (pes->st->codec->codec_id == CODEC_ID_NONE) { - dprintf(pes->stream, "pid=%x stream_type=%x probing\n", - pes->pid, pes->stream_type); - pes->st->codec->codec_id = CODEC_ID_PROBE; - } - } else { - pes->state = MPEGTS_PAYLOAD; - pes->data_index = 0; - } - } else { - /* otherwise, it should be a table */ - /* skip packet */ - skip: - pes->state = MPEGTS_SKIP; - continue; - } - } - break; - /**********************************************/ - /* PES packing parsing */ - case MPEGTS_PESHEADER: - len = PES_HEADER_SIZE - pes->data_index; - if (len < 0) - return -1; - if (len > buf_size) - len = buf_size; - memcpy(pes->header + pes->data_index, p, len); - pes->data_index += len; - p += len; - buf_size -= len; - if (pes->data_index == PES_HEADER_SIZE) { - pes->pes_header_size = pes->header[8] + 9; - pes->state = MPEGTS_PESHEADER_FILL; - } - break; - case MPEGTS_PESHEADER_FILL: - len = pes->pes_header_size - pes->data_index; - if (len < 0) - return -1; - if (len > buf_size) - len = buf_size; - memcpy(pes->header + pes->data_index, p, len); - pes->data_index += len; - p += len; - buf_size -= len; - if (pes->data_index == pes->pes_header_size) { - const uint8_t *r; - unsigned int flags, pes_ext, skip; - - flags = pes->header[7]; - r = pes->header + 9; - pes->pts = AV_NOPTS_VALUE; - pes->dts = AV_NOPTS_VALUE; - if ((flags & 0xc0) == 0x80) { - pes->dts = pes->pts = get_pts(r); - r += 5; - } else if ((flags & 0xc0) == 0xc0) { - pes->pts = get_pts(r); - r += 5; - pes->dts = get_pts(r); - r += 5; - } - pes->extended_stream_id = -1; - if (flags & 0x01) { /* PES extension */ - pes_ext = *r++; - /* Skip PES private data, program packet sequence counter and P-STD buffer */ - skip = (pes_ext >> 4) & 0xb; - skip += skip & 0x9; - r += skip; - if ((pes_ext & 0x41) == 0x01 && - (r + 2) <= (pes->header + pes->pes_header_size)) { - /* PES extension 2 */ - if ((r[0] & 0x7f) > 0 && (r[1] & 0x80) == 0) - pes->extended_stream_id = r[1]; - } - } - - /* we got the full header. We parse it and get the payload */ - pes->state = MPEGTS_PAYLOAD; - pes->data_index = 0; - } - break; - case MPEGTS_PAYLOAD: - if (buf_size > 0 && pes->buffer) { - if (pes->data_index+buf_size > pes->total_size) { - new_pes_packet(pes, ts->pkt); - pes->total_size = MAX_PES_PAYLOAD; - pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); - if (!pes->buffer) - return AVERROR(ENOMEM); - ts->stop_parse = 1; - } - memcpy(pes->buffer+pes->data_index, p, buf_size); - pes->data_index += buf_size; - } - buf_size = 0; - /* emit complete packets with known packet size - * decreases demuxer delay for infrequent packets like subtitles from - * a couple of seconds to milliseconds for properly muxed files. - * total_size is the number of bytes following pes_packet_length - * in the pes header, i.e. not counting the first 6 bytes */ - if (pes->total_size < MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index == pes->total_size + 6) { - ts->stop_parse = 1; - new_pes_packet(pes, ts->pkt); - } - break; - case MPEGTS_SKIP: - buf_size = 0; - break; - } - } - - return 0; -} - -static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid) -{ - MpegTSFilter *tss; - PESContext *pes; - - /* if no pid found, then add a pid context */ - pes = av_mallocz(sizeof(PESContext)); - if (!pes) - return 0; - pes->ts = ts; - pes->stream = ts->stream; - pes->pid = pid; - pes->pcr_pid = pcr_pid; - pes->state = MPEGTS_SKIP; - pes->pts = AV_NOPTS_VALUE; - pes->dts = AV_NOPTS_VALUE; - tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes); - if (!tss) { - av_free(pes); - return 0; - } - return pes; -} - -static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h1, *h = &h1; - PESContext *pes; - AVStream *st; - const uint8_t *p, *p_end, *desc_list_end, *desc_end; - int program_info_length, pcr_pid, pid, stream_type; - int desc_list_len, desc_len, desc_tag; - int comp_page, anc_page; - char language[4]; - uint32_t prog_reg_desc = 0; /* registration descriptor */ - -#ifdef DEBUG - dprintf(ts->stream, "PMT: len %i\n", section_len); - av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); -#endif - - p_end = section + section_len - 4; - p = section; - if (parse_section_header(h, &p, p_end) < 0) - return; - - dprintf(ts->stream, "sid=0x%x sec_num=%d/%d\n", - h->id, h->sec_num, h->last_sec_num); - - if (h->tid != PMT_TID) - return; - - clear_program(ts, h->id); - pcr_pid = get16(&p, p_end) & 0x1fff; - if (pcr_pid < 0) - return; - add_pid_to_pmt(ts, h->id, pcr_pid); - - dprintf(ts->stream, "pcr_pid=0x%x\n", pcr_pid); - - program_info_length = get16(&p, p_end) & 0xfff; - if (program_info_length < 0) - return; - while(program_info_length >= 2) { - uint8_t tag, len; - tag = get8(&p, p_end); - len = get8(&p, p_end); - if(len > program_info_length - 2) - //something else is broken, exit the program_descriptors_loop - break; - program_info_length -= len + 2; - if(tag == 0x05 && len >= 4) { // registration descriptor - prog_reg_desc = bytestream_get_le32(&p); - len -= 4; - } - p += len; - } - p += program_info_length; - if (p >= p_end) - return; - - // stop parsing after pmt, we found header - if (!ts->stream->nb_streams) - ts->stop_parse = 1; - - for(;;) { - st = 0; - stream_type = get8(&p, p_end); - if (stream_type < 0) - break; - pid = get16(&p, p_end) & 0x1fff; - if (pid < 0) - break; - - /* now create ffmpeg stream */ - if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) { - pes = ts->pids[pid]->u.pes_filter.opaque; - st = pes->st; - } else { - if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably - pes = add_pes_stream(ts, pid, pcr_pid); - if (pes) - st = av_new_stream(pes->stream, pes->pid); - } - - if (!st) - return; - - if (!pes->stream_type) - mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc); - - add_pid_to_pmt(ts, h->id, pid); - - ff_program_add_stream_index(ts->stream, h->id, st->index); - - desc_list_len = get16(&p, p_end) & 0xfff; - if (desc_list_len < 0) - break; - desc_list_end = p + desc_list_len; - if (desc_list_end > p_end) - break; - for(;;) { - desc_tag = get8(&p, desc_list_end); - if (desc_tag < 0) - break; - desc_len = get8(&p, desc_list_end); - if (desc_len < 0) - break; - desc_end = p + desc_len; - if (desc_end > desc_list_end) - break; - - dprintf(ts->stream, "tag: 0x%02x len=%d\n", - desc_tag, desc_len); - - if (st->codec->codec_id == CODEC_ID_NONE && - stream_type == STREAM_TYPE_PRIVATE_DATA) - mpegts_find_stream_type(st, desc_tag, DESC_types); - - switch(desc_tag) { - case 0x56: /* DVB teletext descriptor */ - language[0] = get8(&p, desc_end); - language[1] = get8(&p, desc_end); - language[2] = get8(&p, desc_end); - language[3] = 0; - av_metadata_set2(&st->metadata, "language", language, 0); - break; - case 0x59: /* subtitling descriptor */ - language[0] = get8(&p, desc_end); - language[1] = get8(&p, desc_end); - language[2] = get8(&p, desc_end); - language[3] = 0; - get8(&p, desc_end); - comp_page = get16(&p, desc_end); - anc_page = get16(&p, desc_end); - st->codec->sub_id = (anc_page << 16) | comp_page; - av_metadata_set2(&st->metadata, "language", language, 0); - break; - case 0x0a: /* ISO 639 language descriptor */ - language[0] = get8(&p, desc_end); - language[1] = get8(&p, desc_end); - language[2] = get8(&p, desc_end); - language[3] = 0; - av_metadata_set2(&st->metadata, "language", language, 0); - break; - case 0x05: /* registration descriptor */ - st->codec->codec_tag = bytestream_get_le32(&p); - dprintf(ts->stream, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag); - if (st->codec->codec_id == CODEC_ID_NONE && - stream_type == STREAM_TYPE_PRIVATE_DATA) - mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types); - break; - default: - break; - } - p = desc_end; - - if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) { - ff_program_add_stream_index(ts->stream, h->id, pes->sub_st->index); - pes->sub_st->codec->codec_tag = st->codec->codec_tag; - } - } - p = desc_list_end; - } - /* all parameters are there */ - mpegts_close_filter(ts, filter); -} - -static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h1, *h = &h1; - const uint8_t *p, *p_end; - int sid, pmt_pid; - -#ifdef DEBUG - dprintf(ts->stream, "PAT:\n"); - av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); -#endif - p_end = section + section_len - 4; - p = section; - if (parse_section_header(h, &p, p_end) < 0) - return; - if (h->tid != PAT_TID) - return; - - clear_programs(ts); - for(;;) { - sid = get16(&p, p_end); - if (sid < 0) - break; - pmt_pid = get16(&p, p_end) & 0x1fff; - if (pmt_pid < 0) - break; - - dprintf(ts->stream, "sid=0x%x pid=0x%x\n", sid, pmt_pid); - - if (sid == 0x0000) { - /* NIT info */ - } else { - av_new_program(ts->stream, sid); - mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); - add_pat_entry(ts, sid); - add_pid_to_pmt(ts, sid, 0); //add pat pid to program - add_pid_to_pmt(ts, sid, pmt_pid); - } - } -} - -static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h1, *h = &h1; - const uint8_t *p, *p_end, *desc_list_end, *desc_end; - int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type; - char *name, *provider_name; - -#ifdef DEBUG - dprintf(ts->stream, "SDT:\n"); - av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); -#endif - - p_end = section + section_len - 4; - p = section; - if (parse_section_header(h, &p, p_end) < 0) - return; - if (h->tid != SDT_TID) - return; - onid = get16(&p, p_end); - if (onid < 0) - return; - val = get8(&p, p_end); - if (val < 0) - return; - for(;;) { - sid = get16(&p, p_end); - if (sid < 0) - break; - val = get8(&p, p_end); - if (val < 0) - break; - desc_list_len = get16(&p, p_end) & 0xfff; - if (desc_list_len < 0) - break; - desc_list_end = p + desc_list_len; - if (desc_list_end > p_end) - break; - for(;;) { - desc_tag = get8(&p, desc_list_end); - if (desc_tag < 0) - break; - desc_len = get8(&p, desc_list_end); - desc_end = p + desc_len; - if (desc_end > desc_list_end) - break; - - dprintf(ts->stream, "tag: 0x%02x len=%d\n", - desc_tag, desc_len); - - switch(desc_tag) { - case 0x48: - service_type = get8(&p, p_end); - if (service_type < 0) - break; - provider_name = getstr8(&p, p_end); - if (!provider_name) - break; - name = getstr8(&p, p_end); - if (name) { - AVProgram *program = av_new_program(ts->stream, sid); - if(program) { - av_metadata_set2(&program->metadata, "name", name, 0); - av_metadata_set2(&program->metadata, "provider_name", provider_name, 0); - } - } - av_free(name); - av_free(provider_name); - break; - default: - break; - } - p = desc_end; - } - p = desc_list_end; - } -} - -/* handle one TS packet */ -static int handle_packet(MpegTSContext *ts, const uint8_t *packet) -{ - AVFormatContext *s = ts->stream; - MpegTSFilter *tss; - int len, pid, cc, cc_ok, afc, is_start; - const uint8_t *p, *p_end; - int64_t pos; - - pid = AV_RB16(packet + 1) & 0x1fff; - if(pid && discard_pid(ts, pid)) - return 0; - is_start = packet[1] & 0x40; - tss = ts->pids[pid]; - if (ts->auto_guess && tss == NULL && is_start) { - add_pes_stream(ts, pid, -1); - tss = ts->pids[pid]; - } - if (!tss) - return 0; - - /* continuity check (currently not used) */ - cc = (packet[3] & 0xf); - cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc)); - tss->last_cc = cc; - - /* skip adaptation field */ - afc = (packet[3] >> 4) & 3; - p = packet + 4; - if (afc == 0) /* reserved value */ - return 0; - if (afc == 2) /* adaptation field only */ - return 0; - if (afc == 3) { - /* skip adapation field */ - p += p[0] + 1; - } - /* if past the end of packet, ignore */ - p_end = packet + TS_PACKET_SIZE; - if (p >= p_end) - return 0; - - pos = url_ftell(ts->stream->pb); - ts->pos47= pos % ts->raw_packet_size; - - if (tss->type == MPEGTS_SECTION) { - if (is_start) { - /* pointer field present */ - len = *p++; - if (p + len > p_end) - return 0; - if (len && cc_ok) { - /* write remaining section bytes */ - write_section_data(s, tss, - p, len, 0); - /* check whether filter has been closed */ - if (!ts->pids[pid]) - return 0; - } - p += len; - if (p < p_end) { - write_section_data(s, tss, - p, p_end - p, 1); - } - } else { - if (cc_ok) { - write_section_data(s, tss, - p, p_end - p, 0); - } - } - } else { - int ret; - // Note: The position here points actually behind the current packet. - if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, - pos - ts->raw_packet_size)) < 0) - return ret; - } - - return 0; -} - -/* XXX: try to find a better synchro over several packets (use - get_packet_size() ?) */ -static int mpegts_resync(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - int c, i; - - for(i = 0;i < MAX_RESYNC_SIZE; i++) { - c = url_fgetc(pb); - if (c < 0) - return -1; - if (c == 0x47) { - url_fseek(pb, -1, SEEK_CUR); - return 0; - } - } - av_log(s, AV_LOG_ERROR, "max resync size reached, could not find sync byte\n"); - /* no sync found */ - return -1; -} - -/* return -1 if error or EOF. Return 0 if OK. */ -static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size) -{ - ByteIOContext *pb = s->pb; - int skip, len; - - for(;;) { - len = get_buffer(pb, buf, TS_PACKET_SIZE); - if (len != TS_PACKET_SIZE) - return AVERROR(EIO); - /* check paquet sync byte */ - if (buf[0] != 0x47) { - /* find a new packet start */ - url_fseek(pb, -TS_PACKET_SIZE, SEEK_CUR); - if (mpegts_resync(s) < 0) - return AVERROR(EAGAIN); - else - continue; - } else { - skip = raw_packet_size - TS_PACKET_SIZE; - if (skip > 0) - url_fskip(pb, skip); - break; - } - } - return 0; -} - -static int handle_packets(MpegTSContext *ts, int nb_packets) -{ - AVFormatContext *s = ts->stream; - uint8_t packet[TS_PACKET_SIZE]; - int packet_num, ret; - - ts->stop_parse = 0; - packet_num = 0; - for(;;) { - if (ts->stop_parse>0) - break; - packet_num++; - if (nb_packets != 0 && packet_num >= nb_packets) - break; - ret = read_packet(s, packet, ts->raw_packet_size); - if (ret != 0) - return ret; - ret = handle_packet(ts, packet); - if (ret != 0) - return ret; - } - return 0; -} - -static int mpegts_probe(AVProbeData *p) -{ -#if 1 - const int size= p->buf_size; - int score, fec_score, dvhs_score; - int check_count= size / TS_FEC_PACKET_SIZE; -#define CHECK_COUNT 10 - - if (check_count < CHECK_COUNT) - return -1; - - score = analyze(p->buf, TS_PACKET_SIZE *check_count, TS_PACKET_SIZE , NULL)*CHECK_COUNT/check_count; - dvhs_score= analyze(p->buf, TS_DVHS_PACKET_SIZE*check_count, TS_DVHS_PACKET_SIZE, NULL)*CHECK_COUNT/check_count; - fec_score = analyze(p->buf, TS_FEC_PACKET_SIZE *check_count, TS_FEC_PACKET_SIZE , NULL)*CHECK_COUNT/check_count; -// av_log(NULL, AV_LOG_DEBUG, "score: %d, dvhs_score: %d, fec_score: %d \n", score, dvhs_score, fec_score); - -// we need a clear definition for the returned score otherwise things will become messy sooner or later - if (score > fec_score && score > dvhs_score && score > 6) return AVPROBE_SCORE_MAX + score - CHECK_COUNT; - else if(dvhs_score > score && dvhs_score > fec_score && dvhs_score > 6) return AVPROBE_SCORE_MAX + dvhs_score - CHECK_COUNT; - else if( fec_score > 6) return AVPROBE_SCORE_MAX + fec_score - CHECK_COUNT; - else return -1; -#else - /* only use the extension for safer guess */ - if (av_match_ext(p->filename, "ts")) - return AVPROBE_SCORE_MAX; - else - return 0; -#endif -} - -/* return the 90kHz PCR and the extension for the 27MHz PCR. return - (-1) if not available */ -static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, - const uint8_t *packet) -{ - int afc, len, flags; - const uint8_t *p; - unsigned int v; - - afc = (packet[3] >> 4) & 3; - if (afc <= 1) - return -1; - p = packet + 4; - len = p[0]; - p++; - if (len == 0) - return -1; - flags = *p++; - len--; - if (!(flags & 0x10)) - return -1; - if (len < 6) - return -1; - v = AV_RB32(p); - *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7); - *ppcr_low = ((p[4] & 1) << 8) | p[5]; - return 0; -} - -static int mpegts_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - MpegTSContext *ts = s->priv_data; - ByteIOContext *pb = s->pb; - uint8_t buf[5*1024]; - int len; - int64_t pos; - - if (ap) { - ts->mpeg2ts_compute_pcr = ap->mpeg2ts_compute_pcr; - if(ap->mpeg2ts_raw){ - av_log(s, AV_LOG_ERROR, "use mpegtsraw_demuxer!\n"); - return -1; - } - } - - /* read the first 1024 bytes to get packet size */ - pos = url_ftell(pb); - len = get_buffer(pb, buf, sizeof(buf)); - if (len != sizeof(buf)) - goto fail; - ts->raw_packet_size = get_packet_size(buf, sizeof(buf)); - if (ts->raw_packet_size <= 0) - goto fail; - ts->stream = s; - ts->auto_guess = 0; - - if (s->iformat == &mpegts_demuxer) { - /* normal demux */ - - /* first do a scaning to get all the services */ - url_fseek(pb, pos, SEEK_SET); - - mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); - - mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); - - handle_packets(ts, s->probesize / ts->raw_packet_size); - /* if could not find service, enable auto_guess */ - - ts->auto_guess = 1; - - dprintf(ts->stream, "tuning done\n"); - - s->ctx_flags |= AVFMTCTX_NOHEADER; - } else { - AVStream *st; - int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l; - int64_t pcrs[2], pcr_h; - int packet_count[2]; - uint8_t packet[TS_PACKET_SIZE]; - - /* only read packets */ - - st = av_new_stream(s, 0); - if (!st) - goto fail; - av_set_pts_info(st, 60, 1, 27000000); - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = CODEC_ID_MPEG2TS; - - /* we iterate until we find two PCRs to estimate the bitrate */ - pcr_pid = -1; - nb_pcrs = 0; - nb_packets = 0; - for(;;) { - ret = read_packet(s, packet, ts->raw_packet_size); - if (ret < 0) - return -1; - pid = AV_RB16(packet + 1) & 0x1fff; - if ((pcr_pid == -1 || pcr_pid == pid) && - parse_pcr(&pcr_h, &pcr_l, packet) == 0) { - pcr_pid = pid; - packet_count[nb_pcrs] = nb_packets; - pcrs[nb_pcrs] = pcr_h * 300 + pcr_l; - nb_pcrs++; - if (nb_pcrs >= 2) - break; - } - nb_packets++; - } - - /* NOTE1: the bitrate is computed without the FEC */ - /* NOTE2: it is only the bitrate of the start of the stream */ - ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]); - ts->cur_pcr = pcrs[0] - ts->pcr_incr * packet_count[0]; - s->bit_rate = (TS_PACKET_SIZE * 8) * 27e6 / ts->pcr_incr; - st->codec->bit_rate = s->bit_rate; - st->start_time = ts->cur_pcr; -#if 0 - av_log(ts->stream, AV_LOG_DEBUG, "start=%0.3f pcr=%0.3f incr=%d\n", - st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr); -#endif - } - - url_fseek(pb, pos, SEEK_SET); - return 0; - fail: - return -1; -} - -#define MAX_PACKET_READAHEAD ((128 * 1024) / 188) - -static int mpegts_raw_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegTSContext *ts = s->priv_data; - int ret, i; - int64_t pcr_h, next_pcr_h, pos; - int pcr_l, next_pcr_l; - uint8_t pcr_buf[12]; - - if (av_new_packet(pkt, TS_PACKET_SIZE) < 0) - return AVERROR(ENOMEM); - pkt->pos= url_ftell(s->pb); - ret = read_packet(s, pkt->data, ts->raw_packet_size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - if (ts->mpeg2ts_compute_pcr) { - /* compute exact PCR for each packet */ - if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) { - /* we read the next PCR (XXX: optimize it by using a bigger buffer */ - pos = url_ftell(s->pb); - for(i = 0; i < MAX_PACKET_READAHEAD; i++) { - url_fseek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET); - get_buffer(s->pb, pcr_buf, 12); - if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) { - /* XXX: not precise enough */ - ts->pcr_incr = ((next_pcr_h - pcr_h) * 300 + (next_pcr_l - pcr_l)) / - (i + 1); - break; - } - } - url_fseek(s->pb, pos, SEEK_SET); - /* no next PCR found: we use previous increment */ - ts->cur_pcr = pcr_h * 300 + pcr_l; - } - pkt->pts = ts->cur_pcr; - pkt->duration = ts->pcr_incr; - ts->cur_pcr += ts->pcr_incr; - } - pkt->stream_index = 0; - return 0; -} - -static int mpegts_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegTSContext *ts = s->priv_data; - int ret, i; - - if (url_ftell(s->pb) != ts->last_pos) { - /* seek detected, flush pes buffer */ - for (i = 0; i < NB_PID_MAX; i++) { - if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) { - PESContext *pes = ts->pids[i]->u.pes_filter.opaque; - av_freep(&pes->buffer); - pes->data_index = 0; - pes->state = MPEGTS_SKIP; /* skip until pes header */ - } - } - } - - ts->pkt = pkt; - ret = handle_packets(ts, 0); - if (ret < 0) { - /* flush pes data left */ - for (i = 0; i < NB_PID_MAX; i++) { - if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) { - PESContext *pes = ts->pids[i]->u.pes_filter.opaque; - if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { - new_pes_packet(pes, pkt); - pes->state = MPEGTS_SKIP; - ret = 0; - break; - } - } - } - } - - ts->last_pos = url_ftell(s->pb); - - return ret; -} - -static int mpegts_read_close(AVFormatContext *s) -{ - MpegTSContext *ts = s->priv_data; - int i; - - clear_programs(ts); - - for(i=0;ipids[i]) mpegts_close_filter(ts, ts->pids[i]); - - return 0; -} - -static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - MpegTSContext *ts = s->priv_data; - int64_t pos, timestamp; - uint8_t buf[TS_PACKET_SIZE]; - int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid; - const int find_next= 1; - pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47; - if (find_next) { - for(;;) { - url_fseek(s->pb, pos, SEEK_SET); - if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) - return AV_NOPTS_VALUE; - if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && - parse_pcr(×tamp, &pcr_l, buf) == 0) { - break; - } - pos += ts->raw_packet_size; - } - } else { - for(;;) { - pos -= ts->raw_packet_size; - if (pos < 0) - return AV_NOPTS_VALUE; - url_fseek(s->pb, pos, SEEK_SET); - if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) - return AV_NOPTS_VALUE; - if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && - parse_pcr(×tamp, &pcr_l, buf) == 0) { - break; - } - } - } - *ppos = pos; - - return timestamp; -} - -#ifdef USE_SYNCPOINT_SEARCH - -static int read_seek2(AVFormatContext *s, - int stream_index, - int64_t min_ts, - int64_t target_ts, - int64_t max_ts, - int flags) -{ - int64_t pos; - - int64_t ts_ret, ts_adj; - int stream_index_gen_search; - AVStream *st; - AVParserState *backup; - - backup = ff_store_parser_state(s); - - // detect direction of seeking for search purposes - flags |= (target_ts - min_ts > (uint64_t)(max_ts - target_ts)) ? - AVSEEK_FLAG_BACKWARD : 0; - - if (flags & AVSEEK_FLAG_BYTE) { - // use position directly, we will search starting from it - pos = target_ts; - } else { - // search for some position with good timestamp match - if (stream_index < 0) { - stream_index_gen_search = av_find_default_stream_index(s); - if (stream_index_gen_search < 0) { - ff_restore_parser_state(s, backup); - return -1; - } - - st = s->streams[stream_index_gen_search]; - // timestamp for default must be expressed in AV_TIME_BASE units - ts_adj = av_rescale(target_ts, - st->time_base.den, - AV_TIME_BASE * (int64_t)st->time_base.num); - } else { - ts_adj = target_ts; - stream_index_gen_search = stream_index; - } - pos = av_gen_search(s, stream_index_gen_search, ts_adj, - 0, INT64_MAX, -1, - AV_NOPTS_VALUE, - AV_NOPTS_VALUE, - flags, &ts_ret, mpegts_get_pcr); - if (pos < 0) { - ff_restore_parser_state(s, backup); - return -1; - } - } - - // search for actual matching keyframe/starting position for all streams - if (ff_gen_syncpoint_search(s, stream_index, pos, - min_ts, target_ts, max_ts, - flags) < 0) { - ff_restore_parser_state(s, backup); - return -1; - } - - ff_free_parser_state(s, backup); - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags) -{ - int ret; - if (flags & AVSEEK_FLAG_BACKWARD) { - flags &= ~AVSEEK_FLAG_BACKWARD; - ret = read_seek2(s, stream_index, INT64_MIN, target_ts, target_ts, flags); - if (ret < 0) - // for compatibility reasons, seek to the best-fitting timestamp - ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags); - } else { - ret = read_seek2(s, stream_index, target_ts, target_ts, INT64_MAX, flags); - if (ret < 0) - // for compatibility reasons, seek to the best-fitting timestamp - ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags); - } - return ret; -} - -#else - -static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){ - MpegTSContext *ts = s->priv_data; - uint8_t buf[TS_PACKET_SIZE]; - int64_t pos; - - if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0) - return -1; - - pos= url_ftell(s->pb); - - for(;;) { - url_fseek(s->pb, pos, SEEK_SET); - if (get_buffer(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) - return -1; -// pid = AV_RB16(buf + 1) & 0x1fff; - if(buf[1] & 0x40) break; - pos += ts->raw_packet_size; - } - url_fseek(s->pb, pos, SEEK_SET); - - return 0; -} - -#endif - -/**************************************************************/ -/* parsing functions - called from other demuxers such as RTP */ - -MpegTSContext *ff_mpegts_parse_open(AVFormatContext *s) -{ - MpegTSContext *ts; - - ts = av_mallocz(sizeof(MpegTSContext)); - if (!ts) - return NULL; - /* no stream case, currently used by RTP */ - ts->raw_packet_size = TS_PACKET_SIZE; - ts->stream = s; - ts->auto_guess = 1; - return ts; -} - -/* return the consumed length if a packet was output, or -1 if no - packet is output */ -int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, - const uint8_t *buf, int len) -{ - int len1; - - len1 = len; - ts->pkt = pkt; - ts->stop_parse = 0; - for(;;) { - if (ts->stop_parse>0) - break; - if (len < TS_PACKET_SIZE) - return -1; - if (buf[0] != 0x47) { - buf++; - len--; - } else { - handle_packet(ts, buf); - buf += TS_PACKET_SIZE; - len -= TS_PACKET_SIZE; - } - } - return len1 - len; -} - -void ff_mpegts_parse_close(MpegTSContext *ts) -{ - int i; - - for(i=0;ipids[i]); - av_free(ts); -} - -AVInputFormat mpegts_demuxer = { - "mpegts", - NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"), - sizeof(MpegTSContext), - mpegts_probe, - mpegts_read_header, - mpegts_read_packet, - mpegts_read_close, - read_seek, - mpegts_get_pcr, - .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT, -#ifdef USE_SYNCPOINT_SEARCH - .read_seek2 = read_seek2, -#endif -}; - -AVInputFormat mpegtsraw_demuxer = { - "mpegtsraw", - NULL_IF_CONFIG_SMALL("MPEG-2 raw transport stream format"), - sizeof(MpegTSContext), - NULL, - mpegts_read_header, - mpegts_raw_read_packet, - mpegts_read_close, - read_seek, - mpegts_get_pcr, - .flags = AVFMT_SHOW_IDS|AVFMT_TS_DISCONT, -#ifdef USE_SYNCPOINT_SEARCH - .read_seek2 = read_seek2, -#endif -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mpegts.h b/tizen/distrib/ffmpeg/libavformat/mpegts.h deleted file mode 100644 index 6be9b73..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpegts.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * MPEG2 transport stream defines - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_MPEGTS_H -#define AVFORMAT_MPEGTS_H - -#include "avformat.h" - -#define TS_FEC_PACKET_SIZE 204 -#define TS_DVHS_PACKET_SIZE 192 -#define TS_PACKET_SIZE 188 -#define TS_MAX_PACKET_SIZE 204 - -#define NB_PID_MAX 8192 -#define MAX_SECTION_SIZE 4096 - -/* pids */ -#define PAT_PID 0x0000 -#define SDT_PID 0x0011 - -/* table ids */ -#define PAT_TID 0x00 -#define PMT_TID 0x02 -#define SDT_TID 0x42 - -#define STREAM_TYPE_VIDEO_MPEG1 0x01 -#define STREAM_TYPE_VIDEO_MPEG2 0x02 -#define STREAM_TYPE_AUDIO_MPEG1 0x03 -#define STREAM_TYPE_AUDIO_MPEG2 0x04 -#define STREAM_TYPE_PRIVATE_SECTION 0x05 -#define STREAM_TYPE_PRIVATE_DATA 0x06 -#define STREAM_TYPE_AUDIO_AAC 0x0f -#define STREAM_TYPE_VIDEO_MPEG4 0x10 -#define STREAM_TYPE_VIDEO_H264 0x1b -#define STREAM_TYPE_VIDEO_VC1 0xea -#define STREAM_TYPE_VIDEO_DIRAC 0xd1 - -#define STREAM_TYPE_AUDIO_AC3 0x81 -#define STREAM_TYPE_AUDIO_DTS 0x8a - -typedef struct MpegTSContext MpegTSContext; - -MpegTSContext *ff_mpegts_parse_open(AVFormatContext *s); -int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, - const uint8_t *buf, int len); -void ff_mpegts_parse_close(MpegTSContext *ts); - -#endif /* AVFORMAT_MPEGTS_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/mpegtsenc.c b/tizen/distrib/ffmpeg/libavformat/mpegtsenc.c deleted file mode 100644 index 3fc6dc1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpegtsenc.c +++ /dev/null @@ -1,920 +0,0 @@ -/* - * MPEG2 transport stream (aka DVB) muxer - * Copyright (c) 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/bswap.h" -#include "libavutil/crc.h" -#include "libavcodec/mpegvideo.h" -#include "avformat.h" -#include "internal.h" -#include "mpegts.h" -#include "adts.h" - -/* write DVB SI sections */ - -/*********************************************/ -/* mpegts section writer */ - -typedef struct MpegTSSection { - int pid; - int cc; - void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet); - void *opaque; -} MpegTSSection; - -typedef struct MpegTSService { - MpegTSSection pmt; /* MPEG2 pmt table context */ - int sid; /* service ID */ - char *name; - char *provider_name; - int pcr_pid; - int pcr_packet_count; - int pcr_packet_period; -} MpegTSService; - -typedef struct MpegTSWrite { - MpegTSSection pat; /* MPEG2 pat table */ - MpegTSSection sdt; /* MPEG2 sdt table context */ - MpegTSService **services; - int sdt_packet_count; - int sdt_packet_period; - int pat_packet_count; - int pat_packet_period; - int nb_services; - int onid; - int tsid; - uint64_t cur_pcr; - int mux_rate; ///< set to 1 when VBR -} MpegTSWrite; - -/* NOTE: 4 bytes must be left at the end for the crc32 */ -static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) -{ - MpegTSWrite *ts = ((AVFormatContext*)s->opaque)->priv_data; - unsigned int crc; - unsigned char packet[TS_PACKET_SIZE]; - const unsigned char *buf_ptr; - unsigned char *q; - int first, b, len1, left; - - crc = bswap_32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, buf, len - 4)); - buf[len - 4] = (crc >> 24) & 0xff; - buf[len - 3] = (crc >> 16) & 0xff; - buf[len - 2] = (crc >> 8) & 0xff; - buf[len - 1] = (crc) & 0xff; - - /* send each packet */ - buf_ptr = buf; - while (len > 0) { - first = (buf == buf_ptr); - q = packet; - *q++ = 0x47; - b = (s->pid >> 8); - if (first) - b |= 0x40; - *q++ = b; - *q++ = s->pid; - s->cc = (s->cc + 1) & 0xf; - *q++ = 0x10 | s->cc; - if (first) - *q++ = 0; /* 0 offset */ - len1 = TS_PACKET_SIZE - (q - packet); - if (len1 > len) - len1 = len; - memcpy(q, buf_ptr, len1); - q += len1; - /* add known padding data */ - left = TS_PACKET_SIZE - (q - packet); - if (left > 0) - memset(q, 0xff, left); - - s->write_packet(s, packet); - - buf_ptr += len1; - len -= len1; - - ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate; - } -} - -static inline void put16(uint8_t **q_ptr, int val) -{ - uint8_t *q; - q = *q_ptr; - *q++ = val >> 8; - *q++ = val; - *q_ptr = q; -} - -static int mpegts_write_section1(MpegTSSection *s, int tid, int id, - int version, int sec_num, int last_sec_num, - uint8_t *buf, int len) -{ - uint8_t section[1024], *q; - unsigned int tot_len; - - tot_len = 3 + 5 + len + 4; - /* check if not too big */ - if (tot_len > 1024) - return -1; - - q = section; - *q++ = tid; - put16(&q, 0xb000 | (len + 5 + 4)); /* 5 byte header + 4 byte CRC */ - put16(&q, id); - *q++ = 0xc1 | (version << 1); /* current_next_indicator = 1 */ - *q++ = sec_num; - *q++ = last_sec_num; - memcpy(q, buf, len); - - mpegts_write_section(s, section, tot_len); - return 0; -} - -/*********************************************/ -/* mpegts writer */ - -#define DEFAULT_PMT_START_PID 0x1000 -#define DEFAULT_START_PID 0x0100 -#define DEFAULT_PROVIDER_NAME "FFmpeg" -#define DEFAULT_SERVICE_NAME "Service01" - -/* default network id, transport stream and service identifiers */ -#define DEFAULT_ONID 0x0001 -#define DEFAULT_TSID 0x0001 -#define DEFAULT_SID 0x0001 - -/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */ -#define DEFAULT_PES_HEADER_FREQ 16 -#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170) - -/* we retransmit the SI info at this rate */ -#define SDT_RETRANS_TIME 500 -#define PAT_RETRANS_TIME 100 -#define PCR_RETRANS_TIME 20 - -typedef struct MpegTSWriteStream { - struct MpegTSService *service; - int pid; /* stream associated pid */ - int cc; - int payload_index; - int first_pts_check; ///< first pts check needed - int64_t payload_pts; - int64_t payload_dts; - uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; - ADTSContext *adts; -} MpegTSWriteStream; - -static void mpegts_write_pat(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSService *service; - uint8_t data[1012], *q; - int i; - - q = data; - for(i = 0; i < ts->nb_services; i++) { - service = ts->services[i]; - put16(&q, service->sid); - put16(&q, 0xe000 | service->pmt.pid); - } - mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, 0, 0, 0, - data, q - data); -} - -static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) -{ - // MpegTSWrite *ts = s->priv_data; - uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr; - int val, stream_type, i; - - q = data; - put16(&q, 0xe000 | service->pcr_pid); - - program_info_length_ptr = q; - q += 2; /* patched after */ - - /* put program info here */ - - val = 0xf000 | (q - program_info_length_ptr - 2); - program_info_length_ptr[0] = val >> 8; - program_info_length_ptr[1] = val; - - for(i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MpegTSWriteStream *ts_st = st->priv_data; - AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL,0); - switch(st->codec->codec_id) { - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - stream_type = STREAM_TYPE_VIDEO_MPEG2; - break; - case CODEC_ID_MPEG4: - stream_type = STREAM_TYPE_VIDEO_MPEG4; - break; - case CODEC_ID_H264: - stream_type = STREAM_TYPE_VIDEO_H264; - break; - case CODEC_ID_DIRAC: - stream_type = STREAM_TYPE_VIDEO_DIRAC; - break; - case CODEC_ID_MP2: - case CODEC_ID_MP3: - stream_type = STREAM_TYPE_AUDIO_MPEG1; - break; - case CODEC_ID_AAC: - stream_type = STREAM_TYPE_AUDIO_AAC; - break; - case CODEC_ID_AC3: - stream_type = STREAM_TYPE_AUDIO_AC3; - break; - default: - stream_type = STREAM_TYPE_PRIVATE_DATA; - break; - } - *q++ = stream_type; - put16(&q, 0xe000 | ts_st->pid); - desc_length_ptr = q; - q += 2; /* patched after */ - - /* write optional descriptors here */ - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if (lang && strlen(lang->value) == 3) { - *q++ = 0x0a; /* ISO 639 language descriptor */ - *q++ = 4; - *q++ = lang->value[0]; - *q++ = lang->value[1]; - *q++ = lang->value[2]; - *q++ = 0; /* undefined type */ - } - break; - case AVMEDIA_TYPE_SUBTITLE: - { - const char *language; - language = lang && strlen(lang->value)==3 ? lang->value : "eng"; - *q++ = 0x59; - *q++ = 8; - *q++ = language[0]; - *q++ = language[1]; - *q++ = language[2]; - *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */ - put16(&q, 1); /* page id */ - put16(&q, 1); /* ancillary page id */ - } - break; - case AVMEDIA_TYPE_VIDEO: - if (stream_type == STREAM_TYPE_VIDEO_DIRAC) { - *q++ = 0x05; /*MPEG-2 registration descriptor*/ - *q++ = 4; - *q++ = 'd'; - *q++ = 'r'; - *q++ = 'a'; - *q++ = 'c'; - } - break; - } - - val = 0xf000 | (q - desc_length_ptr - 2); - desc_length_ptr[0] = val >> 8; - desc_length_ptr[1] = val; - } - mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0, - data, q - data); -} - -/* NOTE: str == NULL is accepted for an empty string */ -static void putstr8(uint8_t **q_ptr, const char *str) -{ - uint8_t *q; - int len; - - q = *q_ptr; - if (!str) - len = 0; - else - len = strlen(str); - *q++ = len; - memcpy(q, str, len); - q += len; - *q_ptr = q; -} - -static void mpegts_write_sdt(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSService *service; - uint8_t data[1012], *q, *desc_list_len_ptr, *desc_len_ptr; - int i, running_status, free_ca_mode, val; - - q = data; - put16(&q, ts->onid); - *q++ = 0xff; - for(i = 0; i < ts->nb_services; i++) { - service = ts->services[i]; - put16(&q, service->sid); - *q++ = 0xfc | 0x00; /* currently no EIT info */ - desc_list_len_ptr = q; - q += 2; - running_status = 4; /* running */ - free_ca_mode = 0; - - /* write only one descriptor for the service name and provider */ - *q++ = 0x48; - desc_len_ptr = q; - q++; - *q++ = 0x01; /* digital television service */ - putstr8(&q, service->provider_name); - putstr8(&q, service->name); - desc_len_ptr[0] = q - desc_len_ptr - 1; - - /* fill descriptor length */ - val = (running_status << 13) | (free_ca_mode << 12) | - (q - desc_list_len_ptr - 2); - desc_list_len_ptr[0] = val >> 8; - desc_list_len_ptr[1] = val; - } - mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, 0, 0, 0, - data, q - data); -} - -static MpegTSService *mpegts_add_service(MpegTSWrite *ts, - int sid, - const char *provider_name, - const char *name) -{ - MpegTSService *service; - - service = av_mallocz(sizeof(MpegTSService)); - if (!service) - return NULL; - service->pmt.pid = DEFAULT_PMT_START_PID + ts->nb_services - 1; - service->sid = sid; - service->provider_name = av_strdup(provider_name); - service->name = av_strdup(name); - service->pcr_pid = 0x1fff; - dynarray_add(&ts->services, &ts->nb_services, service); - return service; -} - -static void section_write_packet(MpegTSSection *s, const uint8_t *packet) -{ - AVFormatContext *ctx = s->opaque; - put_buffer(ctx->pb, packet, TS_PACKET_SIZE); -} - -static int mpegts_write_header(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st; - MpegTSService *service; - AVStream *st, *pcr_st = NULL; - AVMetadataTag *title; - int i; - const char *service_name; - - ts->tsid = DEFAULT_TSID; - ts->onid = DEFAULT_ONID; - /* allocate a single DVB service */ - title = av_metadata_get(s->metadata, "title", NULL, 0); - service_name = title ? title->value : DEFAULT_SERVICE_NAME; - service = mpegts_add_service(ts, DEFAULT_SID, - DEFAULT_PROVIDER_NAME, service_name); - service->pmt.write_packet = section_write_packet; - service->pmt.opaque = s; - service->pmt.cc = 15; - - ts->pat.pid = PAT_PID; - ts->pat.cc = 15; // Initialize at 15 so that it wraps and be equal to 0 for the first packet we write - ts->pat.write_packet = section_write_packet; - ts->pat.opaque = s; - - ts->sdt.pid = SDT_PID; - ts->sdt.cc = 15; - ts->sdt.write_packet = section_write_packet; - ts->sdt.opaque = s; - - /* assign pids to each stream */ - for(i = 0;i < s->nb_streams; i++) { - st = s->streams[i]; - ts_st = av_mallocz(sizeof(MpegTSWriteStream)); - if (!ts_st) - goto fail; - st->priv_data = ts_st; - ts_st->service = service; - ts_st->pid = DEFAULT_START_PID + i; - ts_st->payload_pts = AV_NOPTS_VALUE; - ts_st->payload_dts = AV_NOPTS_VALUE; - ts_st->first_pts_check = 1; - ts_st->cc = 15; - /* update PCR pid by using the first video stream */ - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - service->pcr_pid == 0x1fff) { - service->pcr_pid = ts_st->pid; - pcr_st = st; - } - if (st->codec->codec_id == CODEC_ID_AAC && - st->codec->extradata_size > 0) { - ts_st->adts = av_mallocz(sizeof(*ts_st->adts)); - if (!ts_st->adts) - return AVERROR(ENOMEM); - if (ff_adts_decode_extradata(s, ts_st->adts, st->codec->extradata, - st->codec->extradata_size) < 0) - return -1; - } - } - - /* if no video stream, use the first stream as PCR */ - if (service->pcr_pid == 0x1fff && s->nb_streams > 0) { - pcr_st = s->streams[0]; - ts_st = pcr_st->priv_data; - service->pcr_pid = ts_st->pid; - } - - ts->mux_rate = s->mux_rate ? s->mux_rate : 1; - - if (ts->mux_rate > 1) { - service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) / - (TS_PACKET_SIZE * 8 * 1000); - ts->sdt_packet_period = (ts->mux_rate * SDT_RETRANS_TIME) / - (TS_PACKET_SIZE * 8 * 1000); - ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) / - (TS_PACKET_SIZE * 8 * 1000); - - ts->cur_pcr = av_rescale(s->max_delay, 90000, AV_TIME_BASE); - } else { - /* Arbitrary values, PAT/PMT could be written on key frames */ - ts->sdt_packet_period = 200; - ts->pat_packet_period = 40; - if (pcr_st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (!pcr_st->codec->frame_size) { - av_log(s, AV_LOG_WARNING, "frame size not set\n"); - service->pcr_packet_period = - pcr_st->codec->sample_rate/(10*512); - } else { - service->pcr_packet_period = - pcr_st->codec->sample_rate/(10*pcr_st->codec->frame_size); - } - } else { - // max delta PCR 0.1s - service->pcr_packet_period = - pcr_st->codec->time_base.den/(10*pcr_st->codec->time_base.num); - } - } - - // output a PCR as soon as possible - service->pcr_packet_count = service->pcr_packet_period; - ts->pat_packet_count = ts->pat_packet_period-1; - ts->sdt_packet_count = ts->sdt_packet_period-1; - - av_log(s, AV_LOG_INFO, - "muxrate %d bps, pcr every %d pkts, " - "sdt every %d, pat/pmt every %d pkts\n", - ts->mux_rate, service->pcr_packet_period, - ts->sdt_packet_period, ts->pat_packet_period); - - - put_flush_packet(s->pb); - - return 0; - - fail: - for(i = 0;i < s->nb_streams; i++) { - st = s->streams[i]; - av_free(st->priv_data); - } - return -1; -} - -/* send SDT, PAT and PMT tables regulary */ -static void retransmit_si_info(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - int i; - - if (++ts->sdt_packet_count == ts->sdt_packet_period) { - ts->sdt_packet_count = 0; - mpegts_write_sdt(s); - } - if (++ts->pat_packet_count == ts->pat_packet_period) { - ts->pat_packet_count = 0; - mpegts_write_pat(s); - for(i = 0; i < ts->nb_services; i++) { - mpegts_write_pmt(s, ts->services[i]); - } - } -} - -/* Write a single null transport stream packet */ -static void mpegts_insert_null_packet(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - uint8_t *q; - uint8_t buf[TS_PACKET_SIZE]; - - q = buf; - *q++ = 0x47; - *q++ = 0x00 | 0x1f; - *q++ = 0xff; - *q++ = 0x10; - memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf)); - put_buffer(s->pb, buf, TS_PACKET_SIZE); - ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate; -} - -/* Write a single transport stream packet with a PCR and no payload */ -static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st = st->priv_data; - uint8_t *q; - uint64_t pcr = ts->cur_pcr; - uint8_t buf[TS_PACKET_SIZE]; - - q = buf; - *q++ = 0x47; - *q++ = ts_st->pid >> 8; - *q++ = ts_st->pid; - *q++ = 0x20 | ts_st->cc; /* Adaptation only */ - /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */ - *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */ - *q++ = 0x10; /* Adaptation flags: PCR present */ - - /* PCR coded into 6 bytes */ - *q++ = pcr >> 25; - *q++ = pcr >> 17; - *q++ = pcr >> 9; - *q++ = pcr >> 1; - *q++ = (pcr & 1) << 7; - *q++ = 0; - - /* stuffing bytes */ - memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); - put_buffer(s->pb, buf, TS_PACKET_SIZE); - ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate; -} - -static void write_pts(uint8_t *q, int fourbits, int64_t pts) -{ - int val; - - val = fourbits << 4 | (((pts >> 30) & 0x07) << 1) | 1; - *q++ = val; - val = (((pts >> 15) & 0x7fff) << 1) | 1; - *q++ = val >> 8; - *q++ = val; - val = (((pts) & 0x7fff) << 1) | 1; - *q++ = val >> 8; - *q++ = val; -} - -/* Add a pes header to the front of payload, and segment into an integer number of - * ts packets. The final ts packet is padded using an over-sized adaptation header - * to exactly fill the last ts packet. - * NOTE: 'payload' contains a complete PES payload. - */ -static void mpegts_write_pes(AVFormatContext *s, AVStream *st, - const uint8_t *payload, int payload_size, - int64_t pts, int64_t dts) -{ - MpegTSWriteStream *ts_st = st->priv_data; - MpegTSWrite *ts = s->priv_data; - uint8_t buf[TS_PACKET_SIZE]; - uint8_t *q; - int val, is_start, len, header_len, write_pcr, private_code, flags; - int afc_len, stuffing_len; - int64_t pcr = -1; /* avoid warning */ - int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); - - is_start = 1; - while (payload_size > 0) { - retransmit_si_info(s); - - write_pcr = 0; - if (ts_st->pid == ts_st->service->pcr_pid) { - if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames - ts_st->service->pcr_packet_count++; - if (ts_st->service->pcr_packet_count >= - ts_st->service->pcr_packet_period) { - ts_st->service->pcr_packet_count = 0; - write_pcr = 1; - } - } - - if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && - (dts - (int64_t)ts->cur_pcr) > delay) { - /* pcr insert gets priority over null packet insert */ - if (write_pcr) - mpegts_insert_pcr_only(s, st); - else - mpegts_insert_null_packet(s); - continue; /* recalculate write_pcr and possibly retransmit si_info */ - } - - /* prepare packet header */ - q = buf; - *q++ = 0x47; - val = (ts_st->pid >> 8); - if (is_start) - val |= 0x40; - *q++ = val; - *q++ = ts_st->pid; - ts_st->cc = (ts_st->cc + 1) & 0xf; - *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0); - if (write_pcr) { - // add 11, pcr references the last byte of program clock reference base - if (ts->mux_rate > 1) - pcr = ts->cur_pcr + (4+7)*8*90000LL / ts->mux_rate; - else - pcr = dts - delay; - if (dts != AV_NOPTS_VALUE && dts < pcr) - av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); - *q++ = 7; /* AFC length */ - *q++ = 0x10; /* flags: PCR present */ - *q++ = pcr >> 25; - *q++ = pcr >> 17; - *q++ = pcr >> 9; - *q++ = pcr >> 1; - *q++ = (pcr & 1) << 7; - *q++ = 0; - } - if (is_start) { - int pes_extension = 0; - /* write PES header */ - *q++ = 0x00; - *q++ = 0x00; - *q++ = 0x01; - private_code = 0; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (st->codec->codec_id == CODEC_ID_DIRAC) { - *q++ = 0xfd; - } else - *q++ = 0xe0; - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - (st->codec->codec_id == CODEC_ID_MP2 || - st->codec->codec_id == CODEC_ID_MP3)) { - *q++ = 0xc0; - } else { - *q++ = 0xbd; - if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { - private_code = 0x20; - } - } - header_len = 0; - flags = 0; - if (pts != AV_NOPTS_VALUE) { - header_len += 5; - flags |= 0x80; - } - if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { - header_len += 5; - flags |= 0x40; - } - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - st->codec->codec_id == CODEC_ID_DIRAC) { - /* set PES_extension_flag */ - pes_extension = 1; - flags |= 0x01; - - /* - * One byte for PES2 extension flag + - * one byte for extension length + - * one byte for extension id - */ - header_len += 3; - } - len = payload_size + header_len + 3; - if (private_code != 0) - len++; - if (len > 0xffff) - len = 0; - *q++ = len >> 8; - *q++ = len; - val = 0x80; - /* data alignment indicator is required for subtitle data */ - if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) - val |= 0x04; - *q++ = val; - *q++ = flags; - *q++ = header_len; - if (pts != AV_NOPTS_VALUE) { - write_pts(q, flags >> 6, pts); - q += 5; - } - if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { - write_pts(q, 1, dts); - q += 5; - } - if (pes_extension && st->codec->codec_id == CODEC_ID_DIRAC) { - flags = 0x01; /* set PES_extension_flag_2 */ - *q++ = flags; - *q++ = 0x80 | 0x01; /* marker bit + extension length */ - /* - * Set the stream id extension flag bit to 0 and - * write the extended stream id - */ - *q++ = 0x00 | 0x60; - } - if (private_code != 0) - *q++ = private_code; - is_start = 0; - } - /* header size */ - header_len = q - buf; - /* data len */ - len = TS_PACKET_SIZE - header_len; - if (len > payload_size) - len = payload_size; - stuffing_len = TS_PACKET_SIZE - header_len - len; - if (stuffing_len > 0) { - /* add stuffing with AFC */ - if (buf[3] & 0x20) { - /* stuffing already present: increase its size */ - afc_len = buf[4] + 1; - memmove(buf + 4 + afc_len + stuffing_len, - buf + 4 + afc_len, - header_len - (4 + afc_len)); - buf[4] += stuffing_len; - memset(buf + 4 + afc_len, 0xff, stuffing_len); - } else { - /* add stuffing */ - memmove(buf + 4 + stuffing_len, buf + 4, header_len - 4); - buf[3] |= 0x20; - buf[4] = stuffing_len - 1; - if (stuffing_len >= 2) { - buf[5] = 0x00; - memset(buf + 6, 0xff, stuffing_len - 2); - } - } - } - memcpy(buf + TS_PACKET_SIZE - len, payload, len); - payload += len; - payload_size -= len; - put_buffer(s->pb, buf, TS_PACKET_SIZE); - ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate; - } - put_flush_packet(s->pb); -} - -static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVStream *st = s->streams[pkt->stream_index]; - int size = pkt->size; - uint8_t *buf= pkt->data; - uint8_t *data= NULL; - MpegTSWriteStream *ts_st = st->priv_data; - const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2; - int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE; - - if (pkt->pts != AV_NOPTS_VALUE) - pts = pkt->pts + delay; - if (pkt->dts != AV_NOPTS_VALUE) - dts = pkt->dts + delay; - - if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_ERROR, "first pts value must set\n"); - return -1; - } - ts_st->first_pts_check = 0; - - if (st->codec->codec_id == CODEC_ID_H264) { - const uint8_t *p = buf, *buf_end = p+size; - uint32_t state = -1; - - if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) { - av_log(s, AV_LOG_ERROR, "h264 bitstream malformated, " - "no startcode found, use -vbsf h264_mp4toannexb\n"); - return -1; - } - - do { - p = ff_find_start_code(p, buf_end, &state); - //av_log(s, AV_LOG_INFO, "nal %d\n", state & 0x1f); - } while (p < buf_end && (state & 0x1f) != 9 && - (state & 0x1f) != 5 && (state & 0x1f) != 1); - - if ((state & 0x1f) != 9) { // AUD NAL - data = av_malloc(pkt->size+6); - if (!data) - return -1; - memcpy(data+6, pkt->data, pkt->size); - AV_WB32(data, 0x00000001); - data[4] = 0x09; - data[5] = 0xe0; // any slice type - buf = data; - size = pkt->size+6; - } - } else if (st->codec->codec_id == CODEC_ID_AAC) { - if (pkt->size < 2) - return -1; - if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) { - ADTSContext *adts = ts_st->adts; - int new_size; - if (!adts) { - av_log(s, AV_LOG_ERROR, "aac bitstream not in adts format " - "and extradata missing\n"); - return -1; - } - new_size = ADTS_HEADER_SIZE+adts->pce_size+pkt->size; - if ((unsigned)new_size >= INT_MAX) - return -1; - data = av_malloc(new_size); - if (!data) - return AVERROR(ENOMEM); - ff_adts_write_frame_header(adts, data, pkt->size, adts->pce_size); - if (adts->pce_size) { - memcpy(data+ADTS_HEADER_SIZE, adts->pce_data, adts->pce_size); - adts->pce_size = 0; - } - memcpy(data+ADTS_HEADER_SIZE+adts->pce_size, pkt->data, pkt->size); - buf = data; - size = new_size; - } - } - - if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) { - // for video and subtitle, write a single pes packet - mpegts_write_pes(s, st, buf, size, pts, dts); - av_free(data); - return 0; - } - - if (ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) { - mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, - ts_st->payload_pts, ts_st->payload_dts); - ts_st->payload_index = 0; - } - - if (!ts_st->payload_index) { - ts_st->payload_pts = pts; - ts_st->payload_dts = dts; - } - - memcpy(ts_st->payload + ts_st->payload_index, buf, size); - ts_st->payload_index += size; - - av_free(data); - - return 0; -} - -static int mpegts_write_end(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st; - MpegTSService *service; - AVStream *st; - int i; - - /* flush current packets */ - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - ts_st = st->priv_data; - if (ts_st->payload_index > 0) { - mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, - ts_st->payload_pts, ts_st->payload_dts); - } - av_freep(&ts_st->adts); - } - put_flush_packet(s->pb); - - for(i = 0; i < ts->nb_services; i++) { - service = ts->services[i]; - av_freep(&service->provider_name); - av_freep(&service->name); - av_free(service); - } - av_free(ts->services); - - return 0; -} - -AVOutputFormat mpegts_muxer = { - "mpegts", - NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"), - "video/x-mpegts", - "ts,m2t", - sizeof(MpegTSWrite), - CODEC_ID_MP2, - CODEC_ID_MPEG2VIDEO, - mpegts_write_header, - mpegts_write_packet, - mpegts_write_end, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mpjpeg.c b/tizen/distrib/ffmpeg/libavformat/mpjpeg.c deleted file mode 100644 index 8973877..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mpjpeg.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Multipart JPEG format - * Copyright (c) 2000, 2001, 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" - -/* Multipart JPEG */ - -#define BOUNDARY_TAG "ffserver" - -static int mpjpeg_write_header(AVFormatContext *s) -{ - uint8_t buf1[256]; - - snprintf(buf1, sizeof(buf1), "--%s\n", BOUNDARY_TAG); - put_buffer(s->pb, buf1, strlen(buf1)); - put_flush_packet(s->pb); - return 0; -} - -static int mpjpeg_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - uint8_t buf1[256]; - - snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\n\n"); - put_buffer(s->pb, buf1, strlen(buf1)); - put_buffer(s->pb, pkt->data, pkt->size); - - snprintf(buf1, sizeof(buf1), "\n--%s\n", BOUNDARY_TAG); - put_buffer(s->pb, buf1, strlen(buf1)); - put_flush_packet(s->pb); - return 0; -} - -static int mpjpeg_write_trailer(AVFormatContext *s) -{ - return 0; -} - -AVOutputFormat mpjpeg_muxer = { - "mpjpeg", - NULL_IF_CONFIG_SMALL("MIME multipart JPEG format"), - "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG, - "mjpg", - 0, - CODEC_ID_NONE, - CODEC_ID_MJPEG, - mpjpeg_write_header, - mpjpeg_write_packet, - mpjpeg_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/msnwc_tcp.c b/tizen/distrib/ffmpeg/libavformat/msnwc_tcp.c deleted file mode 100644 index e548871..0000000 --- a/tizen/distrib/ffmpeg/libavformat/msnwc_tcp.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2008 Ramiro Polla - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/bytestream.h" -#include "avformat.h" - -#define HEADER_SIZE 24 - -/* - * Header structure: - * uint16_t ss; // struct size - * uint16_t width; // frame width - * uint16_t height; // frame height - * uint16_t ff; // keyframe + some other info(???) - * uint32_t size; // size of data - * uint32_t fourcc; // ML20 - * uint32_t u3; // ? - * uint32_t ts; // time - */ - -static int msnwc_tcp_probe(AVProbeData *p) -{ - int i; - - for(i = 0 ; i + HEADER_SIZE <= p->buf_size ; i++) { - uint16_t width, height; - uint32_t fourcc; - const uint8_t *bytestream = p->buf+i; - - if(bytestream_get_le16(&bytestream) != HEADER_SIZE) - continue; - width = bytestream_get_le16(&bytestream); - height = bytestream_get_le16(&bytestream); - if(!(width==320 && height==240) && !(width==160 && height==120)) - continue; - bytestream += 2; // keyframe - bytestream += 4; // size - fourcc = bytestream_get_le32(&bytestream); - if(fourcc != MKTAG('M', 'L', '2', '0')) - continue; - - if(i) { - if(i < 14) /* starts with SwitchBoard connection info */ - return AVPROBE_SCORE_MAX / 2; - else /* starts in the middle of stream */ - return AVPROBE_SCORE_MAX / 3; - } else { - return AVPROBE_SCORE_MAX; - } - } - - return -1; -} - -static int msnwc_tcp_read_header(AVFormatContext *ctx, AVFormatParameters *ap) -{ - ByteIOContext *pb = ctx->pb; - AVCodecContext *codec; - AVStream *st; - - st = av_new_stream(ctx, 0); - if(!st) - return AVERROR(ENOMEM); - - codec = st->codec; - codec->codec_type = AVMEDIA_TYPE_VIDEO; - codec->codec_id = CODEC_ID_MIMIC; - codec->codec_tag = MKTAG('M', 'L', '2', '0'); - - av_set_pts_info(st, 32, 1, 1000); - - /* Some files start with "connected\r\n\r\n". - * So skip until we find the first byte of struct size */ - while(get_byte(pb) != HEADER_SIZE && !url_feof(pb)); - - if(url_feof(pb)) { - av_log(ctx, AV_LOG_ERROR, "Could not find valid start."); - return -1; - } - - return 0; -} - -static int msnwc_tcp_read_packet(AVFormatContext *ctx, AVPacket *pkt) -{ - ByteIOContext *pb = ctx->pb; - uint16_t keyframe; - uint32_t size, timestamp; - - url_fskip(pb, 1); /* one byte has been read ahead */ - url_fskip(pb, 2); - url_fskip(pb, 2); - keyframe = get_le16(pb); - size = get_le32(pb); - url_fskip(pb, 4); - url_fskip(pb, 4); - timestamp = get_le32(pb); - - if(!size || av_get_packet(pb, pkt, size) != size) - return -1; - - url_fskip(pb, 1); /* Read ahead one byte of struct size like read_header */ - - pkt->pts = timestamp; - pkt->dts = timestamp; - pkt->stream_index = 0; - - /* Some aMsn generated videos (or was it Mercury Messenger?) don't set - * this bit and rely on the codec to get keyframe information */ - if(keyframe&1) - pkt->flags |= AV_PKT_FLAG_KEY; - - return HEADER_SIZE + size; -} - -AVInputFormat msnwc_tcp_demuxer = { - "msnwctcp", - NULL_IF_CONFIG_SMALL("MSN TCP Webcam stream"), - 0, - msnwc_tcp_probe, - msnwc_tcp_read_header, - msnwc_tcp_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mtv.c b/tizen/distrib/ffmpeg/libavformat/mtv.c deleted file mode 100644 index 4eae1a1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mtv.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * mtv demuxer - * Copyright (c) 2006 Reynaldo H. Verdejo Pinochet - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * MTV demuxer. - */ - -#include "libavutil/bswap.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define MTV_ASUBCHUNK_DATA_SIZE 500 -#define MTV_HEADER_SIZE 512 -#define MTV_AUDIO_PADDING_SIZE 12 -#define AUDIO_SAMPLING_RATE 44100 -#define VIDEO_SID 0 -#define AUDIO_SID 1 - -typedef struct MTVDemuxContext { - - unsigned int file_size; ///< filesize, not always right - unsigned int segments; ///< number of 512 byte segments - unsigned int audio_identifier; ///< 'MP3' on all files I have seen - unsigned int audio_br; ///< bitrate of audio channel (mp3) - unsigned int img_colorfmt; ///< frame colorfmt rgb 565/555 - unsigned int img_bpp; ///< frame bits per pixel - unsigned int img_width; // - unsigned int img_height; // - unsigned int img_segment_size; ///< size of image segment - unsigned int video_fps; // - unsigned int full_segment_size; - -} MTVDemuxContext; - -static int mtv_probe(AVProbeData *p) -{ - /* Magic is 'AMV' */ - if(*(p->buf) != 'A' || *(p->buf+1) != 'M' || *(p->buf+2) != 'V') - return 0; - - /* Check for nonzero in bpp and (width|height) header fields */ - if(!(p->buf[51] && AV_RL16(&p->buf[52]) | AV_RL16(&p->buf[54]))) - return 0; - - /* If width or height are 0 then imagesize header field should not */ - if(!AV_RL16(&p->buf[52]) || !AV_RL16(&p->buf[54])) - { - if(!!AV_RL16(&p->buf[56])) - return AVPROBE_SCORE_MAX/2; - else - return 0; - } - - if(p->buf[51] != 16) - return AVPROBE_SCORE_MAX/4; // But we are going to assume 16bpp anyway .. - - return AVPROBE_SCORE_MAX; -} - -static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - MTVDemuxContext *mtv = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - unsigned int audio_subsegments; - - url_fskip(pb, 3); - mtv->file_size = get_le32(pb); - mtv->segments = get_le32(pb); - url_fskip(pb, 32); - mtv->audio_identifier = get_le24(pb); - mtv->audio_br = get_le16(pb); - mtv->img_colorfmt = get_le24(pb); - mtv->img_bpp = get_byte(pb); - mtv->img_width = get_le16(pb); - mtv->img_height = get_le16(pb); - mtv->img_segment_size = get_le16(pb); - - /* Calculate width and height if missing from header */ - - if(!mtv->img_width) - mtv->img_width=mtv->img_segment_size / (mtv->img_bpp>>3) - / mtv->img_height; - - if(!mtv->img_height) - mtv->img_height=mtv->img_segment_size / (mtv->img_bpp>>3) - / mtv->img_width; - - url_fskip(pb, 4); - audio_subsegments = get_le16(pb); - mtv->full_segment_size = - audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + - mtv->img_segment_size; - mtv->video_fps = (mtv->audio_br / 4) / audio_subsegments; - - // FIXME Add sanity check here - - // all systems go! init decoders - - // video - raw rgb565 - - st = av_new_stream(s, VIDEO_SID); - if(!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 64, 1, mtv->video_fps); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->pix_fmt = PIX_FMT_RGB565; - st->codec->width = mtv->img_width; - st->codec->height = mtv->img_height; - st->codec->sample_rate = mtv->video_fps; - st->codec->extradata = av_strdup("BottomUp"); - st->codec->extradata_size = 9; - - // audio - mp3 - - st = av_new_stream(s, AUDIO_SID); - if(!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_MP3; - st->codec->bit_rate = mtv->audio_br; - st->need_parsing = AVSTREAM_PARSE_FULL; - - // Jump over header - - if(url_fseek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE) - return AVERROR(EIO); - - return 0; - -} - -static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MTVDemuxContext *mtv = s->priv_data; - ByteIOContext *pb = s->pb; - int ret; -#if !HAVE_BIGENDIAN - int i; -#endif - - if((url_ftell(pb) - s->data_offset + mtv->img_segment_size) % mtv->full_segment_size) - { - url_fskip(pb, MTV_AUDIO_PADDING_SIZE); - - ret = av_get_packet(pb, pkt, MTV_ASUBCHUNK_DATA_SIZE); - if(ret < 0) - return ret; - - pkt->pos -= MTV_AUDIO_PADDING_SIZE; - pkt->stream_index = AUDIO_SID; - - }else - { - ret = av_get_packet(pb, pkt, mtv->img_segment_size); - if(ret < 0) - return ret; - -#if !HAVE_BIGENDIAN - - /* pkt->data is GGGRRRR BBBBBGGG - * and we need RRRRRGGG GGGBBBBB - * for PIX_FMT_RGB565 so here we - * just swap bytes as they come - */ - - for(i=0;iimg_segment_size/2;i++) - *((uint16_t *)pkt->data+i) = bswap_16(*((uint16_t *)pkt->data+i)); -#endif - pkt->stream_index = VIDEO_SID; - } - - return ret; -} - -AVInputFormat mtv_demuxer = { - "MTV", - NULL_IF_CONFIG_SMALL("MTV format"), - sizeof(MTVDemuxContext), - mtv_probe, - mtv_read_header, - mtv_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mvi.c b/tizen/distrib/ffmpeg/libavformat/mvi.c deleted file mode 100644 index 506976d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mvi.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Motion Pixels MVI Demuxer - * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" - -#define MVI_FRAC_BITS 10 - -#define MVI_AUDIO_STREAM_INDEX 0 -#define MVI_VIDEO_STREAM_INDEX 1 - -typedef struct MviDemuxContext { - unsigned int (*get_int)(ByteIOContext *); - uint32_t audio_data_size; - uint64_t audio_size_counter; - uint64_t audio_frame_size; - int audio_size_left; - int video_frame_size; -} MviDemuxContext; - -static int read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - MviDemuxContext *mvi = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *ast, *vst; - unsigned int version, frames_count, msecs_per_frame, player_version; - - ast = av_new_stream(s, 0); - if (!ast) - return AVERROR(ENOMEM); - - vst = av_new_stream(s, 0); - if (!vst) - return AVERROR(ENOMEM); - - vst->codec->extradata_size = 2; - vst->codec->extradata = av_mallocz(2 + FF_INPUT_BUFFER_PADDING_SIZE); - - version = get_byte(pb); - vst->codec->extradata[0] = get_byte(pb); - vst->codec->extradata[1] = get_byte(pb); - frames_count = get_le32(pb); - msecs_per_frame = get_le32(pb); - vst->codec->width = get_le16(pb); - vst->codec->height = get_le16(pb); - get_byte(pb); - ast->codec->sample_rate = get_le16(pb); - mvi->audio_data_size = get_le32(pb); - get_byte(pb); - player_version = get_le32(pb); - get_le16(pb); - get_byte(pb); - - if (frames_count == 0 || mvi->audio_data_size == 0) - return AVERROR_INVALIDDATA; - - if (version != 7 || player_version > 213) { - av_log(s, AV_LOG_ERROR, "unhandled version (%d,%d)\n", version, player_version); - return AVERROR_INVALIDDATA; - } - - av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = CODEC_ID_PCM_U8; - ast->codec->channels = 1; - ast->codec->bits_per_coded_sample = 8; - ast->codec->bit_rate = ast->codec->sample_rate * 8; - - av_set_pts_info(vst, 64, msecs_per_frame, 1000000); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_MOTIONPIXELS; - - mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? get_le16 : get_le24; - - mvi->audio_frame_size = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count; - mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size; - mvi->audio_size_left = mvi->audio_data_size; - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, count; - MviDemuxContext *mvi = s->priv_data; - ByteIOContext *pb = s->pb; - - if (mvi->video_frame_size == 0) { - mvi->video_frame_size = (mvi->get_int)(pb); - if (mvi->audio_size_left == 0) - return AVERROR(EIO); - count = (mvi->audio_size_counter + mvi->audio_frame_size + 512) >> MVI_FRAC_BITS; - if (count > mvi->audio_size_left) - count = mvi->audio_size_left; - if ((ret = av_get_packet(pb, pkt, count)) < 0) - return ret; - pkt->stream_index = MVI_AUDIO_STREAM_INDEX; - mvi->audio_size_left -= count; - mvi->audio_size_counter += mvi->audio_frame_size - (count << MVI_FRAC_BITS); - } else { - if ((ret = av_get_packet(pb, pkt, mvi->video_frame_size)) < 0) - return ret; - pkt->stream_index = MVI_VIDEO_STREAM_INDEX; - mvi->video_frame_size = 0; - } - return 0; -} - -AVInputFormat mvi_demuxer = { - "mvi", - NULL_IF_CONFIG_SMALL("Motion Pixels MVI format"), - sizeof(MviDemuxContext), - NULL, - read_header, - read_packet, - .extensions = "mvi" -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mxf.c b/tizen/distrib/ffmpeg/libavformat/mxf.c deleted file mode 100644 index 452ee6d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mxf.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * MXF - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mxf.h" - -/** - * SMPTE RP224 http://www.smpte-ra.org/mdd/index.html - */ -const MXFCodecUL ff_mxf_data_definition_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_VIDEO }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_AUDIO }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVMEDIA_TYPE_DATA }, -}; - -const MXFCodecUL ff_mxf_codec_uls[] = { - /* PictureEssenceCoding */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* MP@ML Long GoP */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, 14, CODEC_ID_MPEG2VIDEO }, /* D-10 50Mbps PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* MP@HL Long GoP */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* 422P@HL I-Frame */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, 14, CODEC_ID_MPEG4 }, /* XDCAM proxy_pal030926.mxf */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13, CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_RAWVIDEO }, /* Uncompressed */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x03,0x02,0x00,0x00 }, 14, CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */ - /* SoundEssenceCompression */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE }, /* Uncompressed */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16BE }, /* From Omneon MXF file */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 }, 15, CODEC_ID_PCM_ALAW }, /* XDCAM Proxy C0023S01.mxf */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15, CODEC_ID_AC3 }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15, CODEC_ID_MP2 }, /* MP2 or MP3 */ - //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 }, 15, CODEC_ID_DOLBY_E }, /* Dolby-E */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE }, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mxf.h b/tizen/distrib/ffmpeg/libavformat/mxf.h deleted file mode 100644 index 99553a5..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mxf.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * MXF - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVFORMAT_MXF_H -#define AVFORMAT_MXF_H - -#include "libavcodec/avcodec.h" -#include - -typedef uint8_t UID[16]; - -enum MXFMetadataSetType { - AnyType, - MaterialPackage, - SourcePackage, - SourceClip, - TimecodeComponent, - Sequence, - MultipleDescriptor, - Descriptor, - Track, - CryptoContext, - Preface, - Identification, - ContentStorage, - SubDescriptor, - IndexTableSegment, - EssenceContainerData, - TypeBottom,// add metadata type before this -}; - -typedef struct { - UID key; - int64_t offset; - uint64_t length; -} KLVPacket; - -typedef struct { - UID uid; - unsigned matching_len; - int id; -} MXFCodecUL; - -extern const MXFCodecUL ff_mxf_data_definition_uls[]; -extern const MXFCodecUL ff_mxf_codec_uls[]; - -#ifdef DEBUG -#define PRINT_KEY(pc, s, x) dprintf(pc, "%s %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", s, \ - (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5], (x)[6], (x)[7], (x)[8], (x)[9], (x)[10], (x)[11], (x)[12], (x)[13], (x)[14], (x)[15]) -#else -#define PRINT_KEY(pc, s, x) -#endif - -#endif /* AVFORMAT_MXF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/mxfdec.c b/tizen/distrib/ffmpeg/libavformat/mxfdec.c deleted file mode 100644 index 168fd8d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mxfdec.c +++ /dev/null @@ -1,1014 +0,0 @@ -/* - * MXF demuxer. - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * References - * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value - * SMPTE 377M MXF File Format Specifications - * SMPTE 378M Operational Pattern 1a - * SMPTE 379M MXF Generic Container - * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container - * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container - * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container - * - * Principle - * Search for Track numbers which will identify essence element KLV packets. - * Search for SourcePackage which define tracks which contains Track numbers. - * Material Package contains tracks with reference to SourcePackage tracks. - * Search for Descriptors (Picture, Sound) which contains codec info and parameters. - * Assign Descriptors to correct Tracks. - * - * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext. - * Metadata parsing resolves Strong References to objects. - * - * Simple demuxer, only OP1A supported and some files might not work at all. - * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1 - */ - -//#define DEBUG - -#include "libavutil/aes.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "mxf.h" - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID source_container_ul; -} MXFCryptoContext; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID source_package_uid; - UID data_definition_ul; - int64_t duration; - int64_t start_position; - int source_track_id; -} MXFStructuralComponent; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID data_definition_ul; - UID *structural_components_refs; - int structural_components_count; - int64_t duration; -} MXFSequence; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - MXFSequence *sequence; /* mandatory, and only one */ - UID sequence_ref; - int track_id; - uint8_t track_number[4]; - AVRational edit_rate; -} MXFTrack; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID essence_container_ul; - UID essence_codec_ul; - AVRational sample_rate; - AVRational aspect_ratio; - int width; - int height; - int channels; - int bits_per_sample; - UID *sub_descriptors_refs; - int sub_descriptors_count; - int linked_track_id; - uint8_t *extradata; - int extradata_size; -} MXFDescriptor; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; -} MXFIndexTableSegment; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID package_uid; - UID *tracks_refs; - int tracks_count; - MXFDescriptor *descriptor; /* only one */ - UID descriptor_ref; -} MXFPackage; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; -} MXFMetadataSet; - -typedef struct { - UID *packages_refs; - int packages_count; - MXFMetadataSet **metadata_sets; - int metadata_sets_count; - AVFormatContext *fc; - struct AVAES *aesc; - uint8_t *local_tags; - int local_tags_count; -} MXFContext; - -enum MXFWrappingScheme { - Frame, - Clip, -}; - -typedef struct { - const UID key; - int (*read)(); - int ctx_size; - enum MXFMetadataSetType type; -} MXFMetadataReadTableEntry; - -/* partial keys to match */ -static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 }; -static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 }; -static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; -/* complete keys to match */ -static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 }; -static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; -static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; -static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 }; - -#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) - -static int64_t klv_decode_ber_length(ByteIOContext *pb) -{ - uint64_t size = get_byte(pb); - if (size & 0x80) { /* long form */ - int bytes_num = size & 0x7f; - /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */ - if (bytes_num > 8) - return -1; - size = 0; - while (bytes_num--) - size = size << 8 | get_byte(pb); - } - return size; -} - -static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size) -{ - int i, b; - for (i = 0; i < size && !url_feof(pb); i++) { - b = get_byte(pb); - if (b == key[0]) - i = 0; - else if (b != key[i]) - i = -1; - } - return i == size; -} - -static int klv_read_packet(KLVPacket *klv, ByteIOContext *pb) -{ - if (!mxf_read_sync(pb, mxf_klv_key, 4)) - return -1; - klv->offset = url_ftell(pb) - 4; - memcpy(klv->key, mxf_klv_key, 4); - get_buffer(pb, klv->key + 4, 12); - klv->length = klv_decode_ber_length(pb); - return klv->length == -1 ? -1 : 0; -} - -static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) { - MXFTrack *track = s->streams[i]->priv_data; - /* SMPTE 379M 7.3 */ - if (!memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number))) - return i; - } - /* return 0 if only one stream, for OP Atom files with 0 as track number */ - return s->nb_streams == 1 ? 0 : -1; -} - -/* XXX: use AVBitStreamFilter */ -static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length) -{ - const uint8_t *buf_ptr, *end_ptr; - uint8_t *data_ptr; - int i; - - if (length > 61444) /* worst case PAL 1920 samples 8 channels */ - return -1; - av_new_packet(pkt, length); - get_buffer(pb, pkt->data, length); - data_ptr = pkt->data; - end_ptr = pkt->data + length; - buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */ - for (; buf_ptr < end_ptr; ) { - for (i = 0; i < st->codec->channels; i++) { - uint32_t sample = bytestream_get_le32(&buf_ptr); - if (st->codec->bits_per_coded_sample == 24) - bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff); - else - bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff); - } - buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M - } - pkt->size = data_ptr - pkt->data; - return 0; -} - -static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv) -{ - static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b}; - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t end = url_ftell(pb) + klv->length; - uint64_t size; - uint64_t orig_size; - uint64_t plaintext_size; - uint8_t ivec[16]; - uint8_t tmpbuf[16]; - int index; - - if (!mxf->aesc && s->key && s->keylen == 16) { - mxf->aesc = av_malloc(av_aes_size); - if (!mxf->aesc) - return -1; - av_aes_init(mxf->aesc, s->key, 128, 1); - } - // crypto context - url_fskip(pb, klv_decode_ber_length(pb)); - // plaintext offset - klv_decode_ber_length(pb); - plaintext_size = get_be64(pb); - // source klv key - klv_decode_ber_length(pb); - get_buffer(pb, klv->key, 16); - if (!IS_KLV_KEY(klv, mxf_essence_element_key)) - return -1; - index = mxf_get_stream_index(s, klv); - if (index < 0) - return -1; - // source size - klv_decode_ber_length(pb); - orig_size = get_be64(pb); - if (orig_size < plaintext_size) - return -1; - // enc. code - size = klv_decode_ber_length(pb); - if (size < 32 || size - 32 < orig_size) - return -1; - get_buffer(pb, ivec, 16); - get_buffer(pb, tmpbuf, 16); - if (mxf->aesc) - av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1); - if (memcmp(tmpbuf, checkv, 16)) - av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n"); - size -= 32; - av_get_packet(pb, pkt, size); - size -= plaintext_size; - if (mxf->aesc) - av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size], - &pkt->data[plaintext_size], size >> 4, ivec, 1); - pkt->size = orig_size; - pkt->stream_index = index; - url_fskip(pb, end - url_ftell(pb)); - return 0; -} - -static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - KLVPacket klv; - - while (!url_feof(s->pb)) { - if (klv_read_packet(&klv, s->pb) < 0) - return -1; - PRINT_KEY(s, "read packet", klv.key); - dprintf(s, "size %lld offset %#llx\n", klv.length, klv.offset); - if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) { - int res = mxf_decrypt_triplet(s, pkt, &klv); - if (res < 0) { - av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n"); - return -1; - } - return 0; - } - if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) { - int index = mxf_get_stream_index(s, &klv); - if (index < 0) { - av_log(s, AV_LOG_ERROR, "error getting stream index %d\n", AV_RB32(klv.key+12)); - goto skip; - } - if (s->streams[index]->discard == AVDISCARD_ALL) - goto skip; - /* check for 8 channels AES3 element */ - if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) { - if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) { - av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n"); - return -1; - } - } else - av_get_packet(s->pb, pkt, klv.length); - pkt->stream_index = index; - pkt->pos = klv.offset; - return 0; - } else - skip: - url_fskip(s->pb, klv.length); - } - return AVERROR_EOF; -} - -static int mxf_read_primer_pack(MXFContext *mxf) -{ - ByteIOContext *pb = mxf->fc->pb; - int item_num = get_be32(pb); - int item_len = get_be32(pb); - - if (item_len != 18) { - av_log(mxf->fc, AV_LOG_ERROR, "unsupported primer pack item length\n"); - return -1; - } - if (item_num > UINT_MAX / item_len) - return -1; - mxf->local_tags_count = item_num; - mxf->local_tags = av_malloc(item_num*item_len); - if (!mxf->local_tags) - return -1; - get_buffer(pb, mxf->local_tags, item_num*item_len); - return 0; -} - -static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) -{ - if (mxf->metadata_sets_count+1 >= UINT_MAX / sizeof(*mxf->metadata_sets)) - return AVERROR(ENOMEM); - mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets)); - if (!mxf->metadata_sets) - return -1; - mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set; - mxf->metadata_sets_count++; - return 0; -} - -static int mxf_read_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag, int size, UID uid) -{ - if (size != 16) - return -1; - if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul)) - get_buffer(pb, cryptocontext->source_container_ul, 16); - return 0; -} - -static int mxf_read_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag) -{ - switch (tag) { - case 0x1901: - mxf->packages_count = get_be32(pb); - if (mxf->packages_count >= UINT_MAX / sizeof(UID)) - return -1; - mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID)); - if (!mxf->packages_refs) - return -1; - url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ - get_buffer(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID)); - break; - } - return 0; -} - -static int mxf_read_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag) -{ - switch(tag) { - case 0x0202: - source_clip->duration = get_be64(pb); - break; - case 0x1201: - source_clip->start_position = get_be64(pb); - break; - case 0x1101: - /* UMID, only get last 16 bytes */ - url_fskip(pb, 16); - get_buffer(pb, source_clip->source_package_uid, 16); - break; - case 0x1102: - source_clip->source_track_id = get_be32(pb); - break; - } - return 0; -} - -static int mxf_read_material_package(MXFPackage *package, ByteIOContext *pb, int tag) -{ - switch(tag) { - case 0x4403: - package->tracks_count = get_be32(pb); - if (package->tracks_count >= UINT_MAX / sizeof(UID)) - return -1; - package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID)); - if (!package->tracks_refs) - return -1; - url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ - get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID)); - break; - } - return 0; -} - -static int mxf_read_track(MXFTrack *track, ByteIOContext *pb, int tag) -{ - switch(tag) { - case 0x4801: - track->track_id = get_be32(pb); - break; - case 0x4804: - get_buffer(pb, track->track_number, 4); - break; - case 0x4B01: - track->edit_rate.den = get_be32(pb); - track->edit_rate.num = get_be32(pb); - break; - case 0x4803: - get_buffer(pb, track->sequence_ref, 16); - break; - } - return 0; -} - -static int mxf_read_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag) -{ - switch(tag) { - case 0x0202: - sequence->duration = get_be64(pb); - break; - case 0x0201: - get_buffer(pb, sequence->data_definition_ul, 16); - break; - case 0x1001: - sequence->structural_components_count = get_be32(pb); - if (sequence->structural_components_count >= UINT_MAX / sizeof(UID)) - return -1; - sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID)); - if (!sequence->structural_components_refs) - return -1; - url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ - get_buffer(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID)); - break; - } - return 0; -} - -static int mxf_read_source_package(MXFPackage *package, ByteIOContext *pb, int tag) -{ - switch(tag) { - case 0x4403: - package->tracks_count = get_be32(pb); - if (package->tracks_count >= UINT_MAX / sizeof(UID)) - return -1; - package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID)); - if (!package->tracks_refs) - return -1; - url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ - get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID)); - break; - case 0x4401: - /* UMID, only get last 16 bytes */ - url_fskip(pb, 16); - get_buffer(pb, package->package_uid, 16); - break; - case 0x4701: - get_buffer(pb, package->descriptor_ref, 16); - break; - } - return 0; -} - -static int mxf_read_index_table_segment(MXFIndexTableSegment *segment, ByteIOContext *pb, int tag) -{ - switch(tag) { - case 0x3F05: dprintf(NULL, "EditUnitByteCount %d\n", get_be32(pb)); break; - case 0x3F06: dprintf(NULL, "IndexSID %d\n", get_be32(pb)); break; - case 0x3F07: dprintf(NULL, "BodySID %d\n", get_be32(pb)); break; - case 0x3F0B: dprintf(NULL, "IndexEditRate %d/%d\n", get_be32(pb), get_be32(pb)); break; - case 0x3F0C: dprintf(NULL, "IndexStartPosition %lld\n", get_be64(pb)); break; - case 0x3F0D: dprintf(NULL, "IndexDuration %lld\n", get_be64(pb)); break; - } - return 0; -} - -static void mxf_read_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor) -{ - int code; - - do { - code = get_byte(pb); - dprintf(NULL, "pixel layout: code %#x\n", code); - switch (code) { - case 0x52: /* R */ - descriptor->bits_per_sample += get_byte(pb); - break; - case 0x47: /* G */ - descriptor->bits_per_sample += get_byte(pb); - break; - case 0x42: /* B */ - descriptor->bits_per_sample += get_byte(pb); - break; - default: - get_byte(pb); - } - } while (code != 0); /* SMPTE 377M E.2.46 */ -} - -static int mxf_read_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size, UID uid) -{ - switch(tag) { - case 0x3F01: - descriptor->sub_descriptors_count = get_be32(pb); - if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID)) - return -1; - descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID)); - if (!descriptor->sub_descriptors_refs) - return -1; - url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ - get_buffer(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID)); - break; - case 0x3004: - get_buffer(pb, descriptor->essence_container_ul, 16); - break; - case 0x3006: - descriptor->linked_track_id = get_be32(pb); - break; - case 0x3201: /* PictureEssenceCoding */ - get_buffer(pb, descriptor->essence_codec_ul, 16); - break; - case 0x3203: - descriptor->width = get_be32(pb); - break; - case 0x3202: - descriptor->height = get_be32(pb); - break; - case 0x320E: - descriptor->aspect_ratio.num = get_be32(pb); - descriptor->aspect_ratio.den = get_be32(pb); - break; - case 0x3D03: - descriptor->sample_rate.num = get_be32(pb); - descriptor->sample_rate.den = get_be32(pb); - break; - case 0x3D06: /* SoundEssenceCompression */ - get_buffer(pb, descriptor->essence_codec_ul, 16); - break; - case 0x3D07: - descriptor->channels = get_be32(pb); - break; - case 0x3D01: - descriptor->bits_per_sample = get_be32(pb); - break; - case 0x3401: - mxf_read_pixel_layout(pb, descriptor); - break; - default: - /* Private uid used by SONY C0023S01.mxf */ - if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) { - descriptor->extradata = av_malloc(size); - if (!descriptor->extradata) - return -1; - descriptor->extradata_size = size; - get_buffer(pb, descriptor->extradata, size); - } - break; - } - return 0; -} - -/* - * Match an uid independently of the version byte and up to len common bytes - * Returns: boolean - */ -static int mxf_match_uid(const UID key, const UID uid, int len) -{ - int i; - for (i = 0; i < len; i++) { - if (i != 7 && key[i] != uid[i]) - return 0; - } - return 1; -} - -static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid) -{ - while (uls->uid[0]) { - if(mxf_match_uid(uls->uid, *uid, uls->matching_len)) - break; - uls++; - } - return uls; -} - -static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type) -{ - int i; - - if (!strong_ref) - return NULL; - for (i = 0; i < mxf->metadata_sets_count; i++) { - if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) && - (type == AnyType || mxf->metadata_sets[i]->type == type)) { - return mxf->metadata_sets[i]; - } - } - return NULL; -} - -static const MXFCodecUL mxf_essence_container_uls[] = { - // video essence container uls - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, CODEC_ID_MPEG2VIDEO }, /* MPEG-ES Frame wrapped */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, CODEC_ID_DVVIDEO }, /* DV 625 25mbps */ - // sound essence container uls - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, CODEC_ID_PCM_S16LE }, /* BWF Frame wrapped */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14, CODEC_ID_MP2 }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, CODEC_ID_PCM_S16LE }, /* D-10 Mapping 50Mbps PAL Extended Template */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE }, -}; - -static int mxf_parse_structural_metadata(MXFContext *mxf) -{ - MXFPackage *material_package = NULL; - MXFPackage *temp_package = NULL; - int i, j, k; - - dprintf(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count); - /* TODO: handle multiple material packages (OP3x) */ - for (i = 0; i < mxf->packages_count; i++) { - material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage); - if (material_package) break; - } - if (!material_package) { - av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n"); - return -1; - } - - for (i = 0; i < material_package->tracks_count; i++) { - MXFPackage *source_package = NULL; - MXFTrack *material_track = NULL; - MXFTrack *source_track = NULL; - MXFTrack *temp_track = NULL; - MXFDescriptor *descriptor = NULL; - MXFStructuralComponent *component = NULL; - UID *essence_container_ul = NULL; - const MXFCodecUL *codec_ul = NULL; - const MXFCodecUL *container_ul = NULL; - AVStream *st; - - if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n"); - continue; - } - - if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n"); - continue; - } - - /* TODO: handle multiple source clips */ - for (j = 0; j < material_track->sequence->structural_components_count; j++) { - /* TODO: handle timecode component */ - component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip); - if (!component) - continue; - - for (k = 0; k < mxf->packages_count; k++) { - temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage); - if (!temp_package) - continue; - if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) { - source_package = temp_package; - break; - } - } - if (!source_package) { - av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id); - break; - } - for (k = 0; k < source_package->tracks_count; k++) { - if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n"); - return -1; - } - if (temp_track->track_id == component->source_track_id) { - source_track = temp_track; - break; - } - } - if (!source_track) { - av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id); - break; - } - } - if (!source_track) - continue; - - st = av_new_stream(mxf->fc, source_track->track_id); - if (!st) { - av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n"); - return -1; - } - st->priv_data = source_track; - st->duration = component->duration; - if (st->duration == -1) - st->duration = AV_NOPTS_VALUE; - st->start_time = component->start_position; - av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den); - - if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n"); - return -1; - } - - PRINT_KEY(mxf->fc, "data definition ul", source_track->sequence->data_definition_ul); - codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul); - st->codec->codec_type = codec_ul->id; - - source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType); - if (source_package->descriptor) { - if (source_package->descriptor->type == MultipleDescriptor) { - for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) { - MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor); - - if (!sub_descriptor) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n"); - continue; - } - if (sub_descriptor->linked_track_id == source_track->track_id) { - descriptor = sub_descriptor; - break; - } - } - } else if (source_package->descriptor->type == Descriptor) - descriptor = source_package->descriptor; - } - if (!descriptor) { - av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index); - continue; - } - PRINT_KEY(mxf->fc, "essence codec ul", descriptor->essence_codec_ul); - PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul); - essence_container_ul = &descriptor->essence_container_ul; - /* HACK: replacing the original key with mxf_encrypted_essence_container - * is not allowed according to s429-6, try to find correct information anyway */ - if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) { - av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n"); - for (k = 0; k < mxf->metadata_sets_count; k++) { - MXFMetadataSet *metadata = mxf->metadata_sets[k]; - if (metadata->type == CryptoContext) { - essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul; - break; - } - } - } - /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */ - codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul); - st->codec->codec_id = codec_ul->id; - if (descriptor->extradata) { - st->codec->extradata = descriptor->extradata; - st->codec->extradata_size = descriptor->extradata_size; - } - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - container_ul = mxf_get_codec_ul(mxf_essence_container_uls, essence_container_ul); - if (st->codec->codec_id == CODEC_ID_NONE) - st->codec->codec_id = container_ul->id; - st->codec->width = descriptor->width; - st->codec->height = descriptor->height; - st->codec->bits_per_coded_sample = descriptor->bits_per_sample; /* Uncompressed */ - st->need_parsing = AVSTREAM_PARSE_HEADERS; - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - container_ul = mxf_get_codec_ul(mxf_essence_container_uls, essence_container_ul); - if (st->codec->codec_id == CODEC_ID_NONE) - st->codec->codec_id = container_ul->id; - st->codec->channels = descriptor->channels; - st->codec->bits_per_coded_sample = descriptor->bits_per_sample; - st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den; - /* TODO: implement CODEC_ID_RAWAUDIO */ - if (st->codec->codec_id == CODEC_ID_PCM_S16LE) { - if (descriptor->bits_per_sample == 24) - st->codec->codec_id = CODEC_ID_PCM_S24LE; - else if (descriptor->bits_per_sample == 32) - st->codec->codec_id = CODEC_ID_PCM_S32LE; - } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) { - if (descriptor->bits_per_sample == 24) - st->codec->codec_id = CODEC_ID_PCM_S24BE; - else if (descriptor->bits_per_sample == 32) - st->codec->codec_id = CODEC_ID_PCM_S32BE; - } else if (st->codec->codec_id == CODEC_ID_MP2) { - st->need_parsing = AVSTREAM_PARSE_FULL; - } - } - if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) { - av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n"); - st->need_parsing = AVSTREAM_PARSE_FULL; - } - } - return 0; -} - -static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Generic Sound */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG 2 Video */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }, mxf_read_index_table_segment, sizeof(MXFIndexTableSegment), IndexTableSegment }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType }, -}; - -static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type) -{ - ByteIOContext *pb = mxf->fc->pb; - MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf; - uint64_t klv_end = url_ftell(pb) + klv->length; - - if (!ctx) - return -1; - while (url_ftell(pb) + 4 < klv_end) { - int tag = get_be16(pb); - int size = get_be16(pb); /* KLV specified by 0x53 */ - uint64_t next = url_ftell(pb) + size; - UID uid = {0}; - - dprintf(mxf->fc, "local tag %#04x size %d\n", tag, size); - if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */ - av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x with 0 size\n", tag); - continue; - } - if (tag > 0x7FFF) { /* dynamic tag */ - int i; - for (i = 0; i < mxf->local_tags_count; i++) { - int local_tag = AV_RB16(mxf->local_tags+i*18); - if (local_tag == tag) { - memcpy(uid, mxf->local_tags+i*18+2, 16); - dprintf(mxf->fc, "local tag %#04x\n", local_tag); - PRINT_KEY(mxf->fc, "uid", uid); - } - } - } - if (ctx_size && tag == 0x3C0A) - get_buffer(pb, ctx->uid, 16); - else if (read_child(ctx, pb, tag, size, uid) < 0) - return -1; - - url_fseek(pb, next, SEEK_SET); - } - if (ctx_size) ctx->type = type; - return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0; -} - -static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - MXFContext *mxf = s->priv_data; - KLVPacket klv; - - if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) { - av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n"); - return -1; - } - url_fseek(s->pb, -14, SEEK_CUR); - mxf->fc = s; - while (!url_feof(s->pb)) { - const MXFMetadataReadTableEntry *metadata; - - if (klv_read_packet(&klv, s->pb) < 0) - return -1; - PRINT_KEY(s, "read header", klv.key); - dprintf(s, "size %lld offset %#llx\n", klv.length, klv.offset); - if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) || - IS_KLV_KEY(klv.key, mxf_essence_element_key)) { - /* FIXME avoid seek */ - url_fseek(s->pb, klv.offset, SEEK_SET); - break; - } - - for (metadata = mxf_metadata_read_table; metadata->read; metadata++) { - if (IS_KLV_KEY(klv.key, metadata->key)) { - int (*read)() = klv.key[5] == 0x53 ? mxf_read_local_tags : metadata->read; - if (read(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) { - av_log(s, AV_LOG_ERROR, "error reading header metadata\n"); - return -1; - } - break; - } - } - if (!metadata->read) - url_fskip(s->pb, klv.length); - } - return mxf_parse_structural_metadata(mxf); -} - -static int mxf_read_close(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - int i; - - av_freep(&mxf->packages_refs); - - for (i = 0; i < s->nb_streams; i++) - s->streams[i]->priv_data = NULL; - - for (i = 0; i < mxf->metadata_sets_count; i++) { - switch (mxf->metadata_sets[i]->type) { - case MultipleDescriptor: - av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs); - break; - case Sequence: - av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs); - break; - case SourcePackage: - case MaterialPackage: - av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs); - break; - default: - break; - } - av_freep(&mxf->metadata_sets[i]); - } - av_freep(&mxf->metadata_sets); - av_freep(&mxf->aesc); - av_freep(&mxf->local_tags); - return 0; -} - -static int mxf_probe(AVProbeData *p) { - uint8_t *bufp = p->buf; - uint8_t *end = p->buf + p->buf_size; - - if (p->buf_size < sizeof(mxf_header_partition_pack_key)) - return 0; - - /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */ - end -= sizeof(mxf_header_partition_pack_key); - for (; bufp < end; bufp++) { - if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key)) - return AVPROBE_SCORE_MAX; - } - return 0; -} - -/* rudimentary byte seek */ -/* XXX: use MXF Index */ -static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) -{ - AVStream *st = s->streams[stream_index]; - int64_t seconds; - - if (!s->bit_rate) - return -1; - if (sample_time < 0) - sample_time = 0; - seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den); - url_fseek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET); - av_update_cur_dts(s, st, sample_time); - return 0; -} - -AVInputFormat mxf_demuxer = { - "mxf", - NULL_IF_CONFIG_SMALL("Material eXchange Format"), - sizeof(MXFContext), - mxf_probe, - mxf_read_header, - mxf_read_packet, - mxf_read_close, - mxf_read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/mxfenc.c b/tizen/distrib/ffmpeg/libavformat/mxfenc.c deleted file mode 100644 index ab38118..0000000 --- a/tizen/distrib/ffmpeg/libavformat/mxfenc.c +++ /dev/null @@ -1,1908 +0,0 @@ -/* - * MXF muxer - * Copyright (c) 2008 GUCAS, Zhentan Feng - * Copyright (c) 2008 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * References - * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value - * SMPTE 377M MXF File Format Specifications - * SMPTE 379M MXF Generic Container - * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container - * SMPTE RP210: SMPTE Metadata Dictionary - * SMPTE RP224: Registry of SMPTE Universal Labels - */ - -//#define DEBUG - -#include -#include - -#include "libavutil/random_seed.h" -#include "libavcodec/bytestream.h" -#include "audiointerleave.h" -#include "avformat.h" -#include "mxf.h" - -static const int NTSC_samples_per_frame[] = { 1602, 1601, 1602, 1601, 1602, 0 }; -static const int PAL_samples_per_frame[] = { 1920, 0 }; - -AVOutputFormat mxf_d10_muxer; - -#define EDIT_UNITS_PER_BODY 250 -#define KAG_SIZE 512 - -typedef struct { - int local_tag; - UID uid; -} MXFLocalTagPair; - -typedef struct { - uint8_t flags; - uint64_t offset; - unsigned slice_offset; ///< offset of audio slice -} MXFIndexEntry; - -typedef struct { - AudioInterleaveContext aic; - UID track_essence_element_key; - int index; ///< index in mxf_essence_container_uls table - const UID *codec_ul; - int order; ///< interleaving order if dts are equal - int interlaced; ///< wether picture is interlaced - int temporal_reordering; - AVRational aspect_ratio; ///< display aspect ratio - int closed_gop; ///< gop is closed, used in mpeg-2 frame parsing -} MXFStreamContext; - -typedef struct { - UID container_ul; - UID element_ul; - UID codec_ul; - void (*write_desc)(); -} MXFContainerEssenceEntry; - -static const struct { - enum CodecID id; - int index; -} mxf_essence_mappings[] = { - { CODEC_ID_MPEG2VIDEO, 0 }, - { CODEC_ID_PCM_S24LE, 1 }, - { CODEC_ID_PCM_S16LE, 1 }, - { CODEC_ID_NONE } -}; - -static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st); - -static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 }, - mxf_write_mpegvideo_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x03,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_aes3_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_wav_desc }, - // D-10 625/50 PAL 50mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 525/60 NTSC 50mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 625/50 PAL 40mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 525/60 NTSC 40mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 625/50 PAL 30mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 525/60 NTSC 30mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - NULL }, -}; - -typedef struct MXFContext { - int64_t footer_partition_offset; - int essence_container_count; - AVRational time_base; - int header_written; - MXFIndexEntry *index_entries; - unsigned edit_units_count; - uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8) - uint8_t slice_count; ///< index slice count minus 1 (1 if no audio, 0 otherwise) - int last_indexed_edit_unit; - uint64_t *body_partition_offset; - unsigned body_partitions_count; - int last_key_index; ///< index of last key frame - uint64_t duration; - AVStream *timecode_track; - int timecode_base; ///< rounded time code base (25 or 30) - int timecode_start; ///< frame number computed from mpeg-2 gop header timecode - int timecode_drop_frame; ///< time code use drop frame method frop mpeg-2 essence gop header - int edit_unit_byte_count; ///< fixed edit unit byte count - uint64_t body_offset; - uint32_t instance_number; - uint8_t umid[16]; ///< unique material identifier -} MXFContext; - -static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; -static const uint8_t umid_ul[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 }; - -/** - * complete key for operation pattern, partitions, and primer pack - */ -static const uint8_t op1a_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 }; -static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete -static const uint8_t primer_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }; -static const uint8_t index_table_segment_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }; -static const uint8_t random_index_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 }; -static const uint8_t header_open_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; // OpenIncomplete -static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete -static const uint8_t klv_fill_key[] = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 }; -static const uint8_t body_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }; // ClosedComplete - -/** - * partial key for header metadata - */ -static const uint8_t header_metadata_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 }; -static const uint8_t multiple_desc_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 }; - -/** - * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html - */ -static const MXFLocalTagPair mxf_local_tag_batch[] = { - // preface set - { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */ - { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */ - { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */ - { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */ - { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */ - { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */ - { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */ - { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */ - // Identification - { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */ - { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */ - { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */ - { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */ - { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */ - { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */ - // Content Storage - { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */ - { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */ - // Essence Container Data - { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */ - { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */ - // Package - { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */ - { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */ - { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */ - { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */ - { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */ - // Track - { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */ - { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Track Number */ - { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */ - { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */ - { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */ - // Sequence - { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */ - { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */ - { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */ - // Source Clip - { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */ - { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */ - { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */ - // Timecode Component - { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */ - { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */ - { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */ - // File Descriptor - { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */ - { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */ - { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */ - { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */ - // Generic Picture Essence Descriptor - { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Frame Layout */ - { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */ - { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */ - { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */ - { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */ - { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */ - { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */ - { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */ - // CDCI Picture Essence Descriptor - { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */ - { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */ - // Generic Sound Essence Descriptor - { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */ - { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */ - { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */ - { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */ - { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */ - // Index Table Segment - { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, /* Index Edit Rate */ - { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Index Start Position */ - { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, /* Index Duration */ - { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, /* Edit Unit Byte Count */ - { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, /* IndexSID */ - { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, /* Slice Count */ - { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, /* Delta Entry Array */ - { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */ - // MPEG video Descriptor - { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */ - { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */ - // Wave Audio Essence Descriptor - { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */ - { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */ -}; - -static void mxf_write_uuid(ByteIOContext *pb, enum MXFMetadataSetType type, int value) -{ - put_buffer(pb, uuid_base, 12); - put_be16(pb, type); - put_be16(pb, value); -} - -static void mxf_write_umid(AVFormatContext *s, int type) -{ - MXFContext *mxf = s->priv_data; - put_buffer(s->pb, umid_ul, 13); - put_be24(s->pb, mxf->instance_number); - put_buffer(s->pb, mxf->umid, 15); - put_byte(s->pb, type); -} - -static void mxf_write_refs_count(ByteIOContext *pb, int ref_count) -{ - put_be32(pb, ref_count); - put_be32(pb, 16); -} - -static int klv_ber_length(uint64_t len) -{ - if (len < 128) - return 1; - else - return (av_log2(len) >> 3) + 2; -} - -static int klv_encode_ber_length(ByteIOContext *pb, uint64_t len) -{ - // Determine the best BER size - int size; - if (len < 128) { - //short form - put_byte(pb, len); - return 1; - } - - size = (av_log2(len) >> 3) + 1; - - // long form - put_byte(pb, 0x80 + size); - while(size) { - size--; - put_byte(pb, len >> 8 * size & 0xff); - } - return 0; -} - -static void klv_encode_ber4_length(ByteIOContext *pb, int len) -{ - put_byte(pb, 0x80 + 3); - put_be24(pb, len); -} - -/* - * Get essence container ul index - */ -static int mxf_get_essence_container_ul_index(enum CodecID id) -{ - int i; - for (i = 0; mxf_essence_mappings[i].id; i++) - if (mxf_essence_mappings[i].id == id) - return mxf_essence_mappings[i].index; - return -1; -} - -static void mxf_write_primer_pack(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - int local_tag_number, i = 0; - - local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch); - - put_buffer(pb, primer_pack_key, 16); - klv_encode_ber_length(pb, local_tag_number * 18 + 8); - - put_be32(pb, local_tag_number); // local_tag num - put_be32(pb, 18); // item size, always 18 according to the specs - - for (i = 0; i < local_tag_number; i++) { - put_be16(pb, mxf_local_tag_batch[i].local_tag); - put_buffer(pb, mxf_local_tag_batch[i].uid, 16); - } -} - -static void mxf_write_local_tag(ByteIOContext *pb, int size, int tag) -{ - put_be16(pb, tag); - put_be16(pb, size); -} - -static void mxf_write_metadata_key(ByteIOContext *pb, unsigned int value) -{ - put_buffer(pb, header_metadata_key, 13); - put_be24(pb, value); -} - -static void mxf_free(AVFormatContext *s) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - av_freep(&st->priv_data); - } -} - -static const MXFCodecUL *mxf_get_data_definition_ul(int type) -{ - const MXFCodecUL *uls = ff_mxf_data_definition_uls; - while (uls->uid[0]) { - if (type == uls->id) - break; - uls++; - } - return uls; -} - -static void mxf_write_essence_container_refs(AVFormatContext *s) -{ - MXFContext *c = s->priv_data; - ByteIOContext *pb = s->pb; - int i; - - mxf_write_refs_count(pb, c->essence_container_count); - av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count); - for (i = 0; i < c->essence_container_count; i++) { - MXFStreamContext *sc = s->streams[i]->priv_data; - put_buffer(pb, mxf_essence_container_uls[sc->index].container_ul, 16); - } -} - -static void mxf_write_preface(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x012f00); - PRINT_KEY(s, "preface key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 130 + 16 * mxf->essence_container_count); - - // write preface set uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, Preface, 0); - PRINT_KEY(s, "preface uid", pb->buf_ptr - 16); - - // last modified date - mxf_write_local_tag(pb, 8, 0x3B02); - put_be64(pb, mxf->timestamp); - - // write version - mxf_write_local_tag(pb, 2, 0x3B05); - put_be16(pb, 258); // v1.2 - - // write identification_refs - mxf_write_local_tag(pb, 16 + 8, 0x3B06); - mxf_write_refs_count(pb, 1); - mxf_write_uuid(pb, Identification, 0); - - // write content_storage_refs - mxf_write_local_tag(pb, 16, 0x3B03); - mxf_write_uuid(pb, ContentStorage, 0); - - // operational pattern - mxf_write_local_tag(pb, 16, 0x3B09); - put_buffer(pb, op1a_ul, 16); - - // write essence_container_refs - mxf_write_local_tag(pb, 8 + 16 * mxf->essence_container_count, 0x3B0A); - mxf_write_essence_container_refs(s); - - // write dm_scheme_refs - mxf_write_local_tag(pb, 8, 0x3B0B); - put_be64(pb, 0); -} - -/* - * Write a local tag containing an ascii string as utf-16 - */ -static void mxf_write_local_tag_utf16(ByteIOContext *pb, int tag, const char *value) -{ - int i, size = strlen(value); - mxf_write_local_tag(pb, size*2, tag); - for (i = 0; i < size; i++) - put_be16(pb, value[i]); -} - -static void mxf_write_identification(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - const char *company = "FFmpeg"; - const char *product = "OP1a Muxer"; - const char *version; - int length; - - mxf_write_metadata_key(pb, 0x013000); - PRINT_KEY(s, "identification key", pb->buf_ptr - 16); - - version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ? - "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION); - length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16 - klv_encode_ber_length(pb, length); - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, Identification, 0); - PRINT_KEY(s, "identification uid", pb->buf_ptr - 16); - - // write generation uid - mxf_write_local_tag(pb, 16, 0x3C09); - mxf_write_uuid(pb, Identification, 1); - - mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name - mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name - mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String - - // write product uid - mxf_write_local_tag(pb, 16, 0x3C05); - mxf_write_uuid(pb, Identification, 2); - - // modification date - mxf_write_local_tag(pb, 8, 0x3C06); - put_be64(pb, mxf->timestamp); -} - -static void mxf_write_content_storage(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x011800); - PRINT_KEY(s, "content storage key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 92); - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, ContentStorage, 0); - PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16); - - // write package reference - mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901); - mxf_write_refs_count(pb, 2); - mxf_write_uuid(pb, MaterialPackage, 0); - mxf_write_uuid(pb, SourcePackage, 0); - - // write essence container data - mxf_write_local_tag(pb, 8 + 16, 0x1902); - mxf_write_refs_count(pb, 1); - mxf_write_uuid(pb, EssenceContainerData, 0); -} - -static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - MXFStreamContext *sc = st->priv_data; - - mxf_write_metadata_key(pb, 0x013b00); - PRINT_KEY(s, "track key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 80); - - // write track uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, st->index); - PRINT_KEY(s, "track uid", pb->buf_ptr - 16); - - // write track id - mxf_write_local_tag(pb, 4, 0x4801); - put_be32(pb, st->index+2); - - // write track number - mxf_write_local_tag(pb, 4, 0x4804); - if (type == MaterialPackage) - put_be32(pb, 0); // track number of material package is 0 - else - put_buffer(pb, sc->track_essence_element_key + 12, 4); - - mxf_write_local_tag(pb, 8, 0x4B01); - put_be32(pb, mxf->time_base.den); - put_be32(pb, mxf->time_base.num); - - // write origin - mxf_write_local_tag(pb, 8, 0x4B02); - put_be64(pb, 0); - - // write sequence refs - mxf_write_local_tag(pb, 16, 0x4803); - mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); -} - -static const uint8_t smpte_12m_timecode_track_data_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x01,0x01,0x00,0x00,0x00 }; - -static void mxf_write_common_fields(AVFormatContext *s, AVStream *st) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - - // find data define uls - mxf_write_local_tag(pb, 16, 0x0201); - if (st == mxf->timecode_track) - put_buffer(pb, smpte_12m_timecode_track_data_ul, 16); - else { - const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type); - put_buffer(pb, data_def_ul->uid, 16); - } - - // write duration - mxf_write_local_tag(pb, 8, 0x0202); - put_be64(pb, mxf->duration); -} - -static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - enum MXFMetadataSetType component; - - mxf_write_metadata_key(pb, 0x010f00); - PRINT_KEY(s, "sequence key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 80); - - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); - - PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16); - mxf_write_common_fields(s, st); - - // write structural component - mxf_write_local_tag(pb, 16 + 8, 0x1001); - mxf_write_refs_count(pb, 1); - if (st == mxf->timecode_track) - component = TimecodeComponent; - else - component = SourceClip; - if (type == SourcePackage) - component += TypeBottom; - mxf_write_uuid(pb, component, st->index); -} - -static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x011400); - klv_encode_ber_length(pb, 75); - - // UID - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? TimecodeComponent : - TimecodeComponent + TypeBottom, st->index); - - mxf_write_common_fields(s, st); - - // Start Time Code - mxf_write_local_tag(pb, 8, 0x1501); - put_be64(pb, mxf->timecode_start); - - // Rounded Time Code Base - mxf_write_local_tag(pb, 2, 0x1502); - put_be16(pb, mxf->timecode_base); - - // Drop Frame - mxf_write_local_tag(pb, 1, 0x1503); - put_byte(pb, mxf->timecode_drop_frame); -} - -static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - ByteIOContext *pb = s->pb; - int i; - - mxf_write_metadata_key(pb, 0x011100); - PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 108); - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index); - - PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16); - mxf_write_common_fields(s, st); - - // write start_position - mxf_write_local_tag(pb, 8, 0x1201); - put_be64(pb, 0); - - // write source package uid, end of the reference - mxf_write_local_tag(pb, 32, 0x1101); - if (type == SourcePackage) { - for (i = 0; i < 4; i++) - put_be64(pb, 0); - } else - mxf_write_umid(s, 1); - - // write source track id - mxf_write_local_tag(pb, 4, 0x1102); - if (type == SourcePackage) - put_be32(pb, 0); - else - put_be32(pb, st->index+2); -} - -static void mxf_write_multi_descriptor(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - const uint8_t *ul; - int i; - - mxf_write_metadata_key(pb, 0x014400); - PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 64 + 16 * s->nb_streams); - - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, MultipleDescriptor, 0); - PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16); - - // write sample rate - mxf_write_local_tag(pb, 8, 0x3001); - put_be32(pb, mxf->time_base.den); - put_be32(pb, mxf->time_base.num); - - // write essence container ul - mxf_write_local_tag(pb, 16, 0x3004); - if (mxf->essence_container_count > 1) - ul = multiple_desc_ul; - else { - MXFStreamContext *sc = s->streams[0]->priv_data; - ul = mxf_essence_container_uls[sc->index].container_ul; - } - put_buffer(pb, ul, 16); - - // write sub descriptor refs - mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01); - mxf_write_refs_count(pb, s->nb_streams); - for (i = 0; i < s->nb_streams; i++) - mxf_write_uuid(pb, SubDescriptor, i); -} - -static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - MXFContext *mxf = s->priv_data; - MXFStreamContext *sc = st->priv_data; - ByteIOContext *pb = s->pb; - - put_buffer(pb, key, 16); - klv_encode_ber4_length(pb, size+20+8+12+20); - - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, SubDescriptor, st->index); - - mxf_write_local_tag(pb, 4, 0x3006); - put_be32(pb, st->index+2); - - mxf_write_local_tag(pb, 8, 0x3001); - put_be32(pb, mxf->time_base.den); - put_be32(pb, mxf->time_base.num); - - mxf_write_local_tag(pb, 16, 0x3004); - put_buffer(pb, mxf_essence_container_uls[sc->index].container_ul, 16); -} - -static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }; -static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }; -static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }; -static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }; -static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }; - -static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - MXFStreamContext *sc = st->priv_data; - ByteIOContext *pb = s->pb; - int stored_height = (st->codec->height+15)/16*16; - int display_height; - int f1, f2; - - mxf_write_generic_desc(s, st, key, size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20); - - mxf_write_local_tag(pb, 4, 0x3203); - put_be32(pb, st->codec->width); - - mxf_write_local_tag(pb, 4, 0x3202); - put_be32(pb, stored_height>>sc->interlaced); - - mxf_write_local_tag(pb, 4, 0x3209); - put_be32(pb, st->codec->width); - - if (st->codec->height == 608) // PAL + VBI - display_height = 576; - else if (st->codec->height == 512) // NTSC + VBI - display_height = 486; - else - display_height = st->codec->height; - - mxf_write_local_tag(pb, 4, 0x3208); - put_be32(pb, display_height>>sc->interlaced); - - // component depth - mxf_write_local_tag(pb, 4, 0x3301); - put_be32(pb, 8); - - // horizontal subsampling - mxf_write_local_tag(pb, 4, 0x3302); - put_be32(pb, 2); - - // frame layout - mxf_write_local_tag(pb, 1, 0x320C); - put_byte(pb, sc->interlaced); - - // video line map - switch (st->codec->height) { - case 576: f1 = 23; f2 = 336; break; - case 608: f1 = 7; f2 = 320; break; - case 480: f1 = 20; f2 = 283; break; - case 512: f1 = 7; f2 = 270; break; - case 720: f1 = 26; f2 = 0; break; // progressive - case 1080: f1 = 21; f2 = 584; break; - default: f1 = 0; f2 = 0; break; - } - - if (!sc->interlaced) { - f2 = 0; - f1 *= 2; - } - - mxf_write_local_tag(pb, 12+sc->interlaced*4, 0x320D); - put_be32(pb, sc->interlaced ? 2 : 1); - put_be32(pb, 4); - put_be32(pb, f1); - if (sc->interlaced) - put_be32(pb, f2); - - mxf_write_local_tag(pb, 8, 0x320E); - put_be32(pb, sc->aspect_ratio.num); - put_be32(pb, sc->aspect_ratio.den); - - mxf_write_local_tag(pb, 16, 0x3201); - put_buffer(pb, *sc->codec_ul, 16); -} - -static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0); -} - -static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) -{ - ByteIOContext *pb = s->pb; - int profile_and_level = (st->codec->profile<<4) | st->codec->level; - - mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5); - - // bit rate - mxf_write_local_tag(pb, 4, 0x8000); - put_be32(pb, st->codec->bit_rate); - - // profile and level - mxf_write_local_tag(pb, 1, 0x8007); - if (!st->codec->profile) - profile_and_level |= 0x80; // escape bit - put_byte(pb, profile_and_level); -} - -static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - ByteIOContext *pb = s->pb; - - mxf_write_generic_desc(s, st, key, size+5+12+8+8); - - // audio locked - mxf_write_local_tag(pb, 1, 0x3D02); - put_byte(pb, 1); - - // write audio sampling rate - mxf_write_local_tag(pb, 8, 0x3D03); - put_be32(pb, st->codec->sample_rate); - put_be32(pb, 1); - - mxf_write_local_tag(pb, 4, 0x3D07); - put_be32(pb, st->codec->channels); - - mxf_write_local_tag(pb, 4, 0x3D01); - put_be32(pb, av_get_bits_per_sample(st->codec->codec_id)); -} - -static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - ByteIOContext *pb = s->pb; - - mxf_write_generic_sound_common(s, st, key, size+6+8); - - mxf_write_local_tag(pb, 2, 0x3D0A); - put_be16(pb, st->codec->block_align); - - // avg bytes per sec - mxf_write_local_tag(pb, 4, 0x3D09); - put_be32(pb, st->codec->block_align*st->codec->sample_rate); -} - -static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0); -} - -static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0); -} - -static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0); -} - -static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - int i, track_count = s->nb_streams+1; - - if (type == MaterialPackage) { - mxf_write_metadata_key(pb, 0x013600); - PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 92 + 16*track_count); - } else { - mxf_write_metadata_key(pb, 0x013700); - PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 112 + 16*track_count); // 20 bytes length for descriptor reference - } - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type, 0); - av_log(s,AV_LOG_DEBUG, "package type:%d\n", type); - PRINT_KEY(s, "package uid", pb->buf_ptr - 16); - - // write package umid - mxf_write_local_tag(pb, 32, 0x4401); - mxf_write_umid(s, type == SourcePackage); - PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16); - - // package creation date - mxf_write_local_tag(pb, 8, 0x4405); - put_be64(pb, mxf->timestamp); - - // package modified date - mxf_write_local_tag(pb, 8, 0x4404); - put_be64(pb, mxf->timestamp); - - // write track refs - mxf_write_local_tag(pb, track_count*16 + 8, 0x4403); - mxf_write_refs_count(pb, track_count); - mxf_write_uuid(pb, type == MaterialPackage ? Track : - Track + TypeBottom, -1); // timecode track - for (i = 0; i < s->nb_streams; i++) - mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i); - - // write multiple descriptor reference - if (type == SourcePackage) { - mxf_write_local_tag(pb, 16, 0x4701); - if (s->nb_streams > 1) { - mxf_write_uuid(pb, MultipleDescriptor, 0); - mxf_write_multi_descriptor(s); - } else - mxf_write_uuid(pb, SubDescriptor, 0); - } - - // write timecode track - mxf_write_track(s, mxf->timecode_track, type); - mxf_write_sequence(s, mxf->timecode_track, type); - mxf_write_timecode_component(s, mxf->timecode_track, type); - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - mxf_write_track(s, st, type); - mxf_write_sequence(s, st, type); - mxf_write_structural_component(s, st, type); - - if (type == SourcePackage) { - MXFStreamContext *sc = st->priv_data; - mxf_essence_container_uls[sc->index].write_desc(s, st); - } - } -} - -static int mxf_write_essence_container_data(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x012300); - klv_encode_ber_length(pb, 72); - - mxf_write_local_tag(pb, 16, 0x3C0A); // Instance UID - mxf_write_uuid(pb, EssenceContainerData, 0); - - mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID - mxf_write_umid(s, 1); - - mxf_write_local_tag(pb, 4, 0x3F07); // BodySID - put_be32(pb, 1); - - mxf_write_local_tag(pb, 4, 0x3F06); // IndexSID - put_be32(pb, 2); - - return 0; -} - -static int mxf_write_header_metadata_sets(AVFormatContext *s) -{ - mxf_write_preface(s); - mxf_write_identification(s); - mxf_write_content_storage(s); - mxf_write_package(s, MaterialPackage); - mxf_write_package(s, SourcePackage); - mxf_write_essence_container_data(s); - return 0; -} - -static unsigned klv_fill_size(uint64_t size) -{ - unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1)); - if (pad < 20) // smallest fill item possible - return pad + KAG_SIZE; - else - return pad & (KAG_SIZE-1); -} - -static void mxf_write_index_table_segment(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - int i, j; - int temporal_reordering = 0; - int key_index = mxf->last_key_index; - - av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count); - - if (!mxf->edit_units_count && !mxf->edit_unit_byte_count) - return; - - put_buffer(pb, index_table_segment_key, 16); - - if (mxf->edit_unit_byte_count) { - klv_encode_ber_length(pb, 80); - } else { - klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1)*6 + - 12+mxf->edit_units_count*(11+mxf->slice_count*4)); - } - - // instance id - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, IndexTableSegment, 0); - - // index edit rate - mxf_write_local_tag(pb, 8, 0x3F0B); - put_be32(pb, mxf->time_base.den); - put_be32(pb, mxf->time_base.num); - - // index start position - mxf_write_local_tag(pb, 8, 0x3F0C); - put_be64(pb, mxf->last_indexed_edit_unit); - - // index duration - mxf_write_local_tag(pb, 8, 0x3F0D); - if (mxf->edit_unit_byte_count) - put_be64(pb, 0); // index table covers whole container - else - put_be64(pb, mxf->edit_units_count); - - // edit unit byte count - mxf_write_local_tag(pb, 4, 0x3F05); - put_be32(pb, mxf->edit_unit_byte_count); - - // index sid - mxf_write_local_tag(pb, 4, 0x3F06); - put_be32(pb, 2); - - // body sid - mxf_write_local_tag(pb, 4, 0x3F07); - put_be32(pb, 1); - - if (!mxf->edit_unit_byte_count) { - // real slice count - 1 - mxf_write_local_tag(pb, 1, 0x3F08); - put_byte(pb, mxf->slice_count); - - // delta entry array - mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09); - put_be32(pb, s->nb_streams+1); // num of entries - put_be32(pb, 6); // size of one entry - // write system item delta entry - put_byte(pb, 0); - put_byte(pb, 0); // slice entry - put_be32(pb, 0); // element delta - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MXFStreamContext *sc = st->priv_data; - put_byte(pb, sc->temporal_reordering); - if (sc->temporal_reordering) - temporal_reordering = 1; - if (i == 0) { // video track - put_byte(pb, 0); // slice number - put_be32(pb, KAG_SIZE); // system item size including klv fill - } else { // audio track - unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size; - audio_frame_size += klv_fill_size(audio_frame_size); - put_byte(pb, 1); - put_be32(pb, (i-1)*audio_frame_size); // element delta - } - } - - mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A); - put_be32(pb, mxf->edit_units_count); // num of entries - put_be32(pb, 11+mxf->slice_count*4); // size of one entry - for (i = 0; i < mxf->edit_units_count; i++) { - int temporal_offset = 0; - if (temporal_reordering) { - for (j = i+1; j < mxf->edit_units_count; j++) { - temporal_offset++; - if (mxf->index_entries[j].flags & 0x10) { // backward prediction - // next is not b, so is reordered - if (!(mxf->index_entries[i+1].flags & 0x10)) { - if ((mxf->index_entries[i].flags & 0x11) == 0) // I frame - temporal_offset = 0; - else - temporal_offset = -temporal_offset; - } - break; - } - } - } - put_byte(pb, temporal_offset); - - if (!(mxf->index_entries[i].flags & 0x33)) { // I frame - if (mxf->index_entries[i].flags & 0x40 && // seq header - (!temporal_reordering || !temporal_offset)) - mxf->index_entries[i].flags |= 0x80; // random access - mxf->last_key_index = key_index; - key_index = i; - } - if ((mxf->index_entries[i].flags & 0x30) == 0x30) { // back and forward prediction - put_byte(pb, mxf->last_key_index - i); - } else { - put_byte(pb, key_index - i); // key frame offset - if ((mxf->index_entries[i].flags & 0x20) == 0x20) // only forward - mxf->last_key_index = key_index; - } - put_byte(pb, mxf->index_entries[i].flags); - // stream offset - put_be64(pb, mxf->index_entries[i].offset); - if (s->nb_streams > 1) - put_be32(pb, mxf->index_entries[i].slice_offset); - } - - mxf->last_key_index = key_index - mxf->edit_units_count; - mxf->last_indexed_edit_unit += mxf->edit_units_count; - mxf->edit_units_count = 0; - } -} - -static void mxf_write_klv_fill(AVFormatContext *s) -{ - unsigned pad = klv_fill_size(url_ftell(s->pb)); - if (pad) { - put_buffer(s->pb, klv_fill_key, 16); - pad -= 16 + 4; - klv_encode_ber4_length(s->pb, pad); - for (; pad; pad--) - put_byte(s->pb, 0); - assert(!(url_ftell(s->pb) & (KAG_SIZE-1))); - } -} - -static void mxf_write_partition(AVFormatContext *s, int bodysid, - int indexsid, - const uint8_t *key, int write_metadata) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t header_byte_count_offset; - unsigned index_byte_count = 0; - uint64_t partition_offset = url_ftell(pb); - - if (!mxf->edit_unit_byte_count && mxf->edit_units_count) - index_byte_count = 85 + 12+(s->nb_streams+1)*6 + - 12+mxf->edit_units_count*(11+mxf->slice_count*4); - else if (mxf->edit_unit_byte_count && indexsid) - index_byte_count = 80; - - if (index_byte_count) { - // add encoded ber length - index_byte_count += 16 + klv_ber_length(index_byte_count); - index_byte_count += klv_fill_size(index_byte_count); - } - - if (!memcmp(key, body_partition_key, 16)) { - mxf->body_partition_offset = - av_realloc(mxf->body_partition_offset, - (mxf->body_partitions_count+1)* - sizeof(*mxf->body_partition_offset)); - mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset; - } - - // write klv - put_buffer(pb, key, 16); - klv_encode_ber_length(pb, 88 + 16 * mxf->essence_container_count); - - // write partition value - put_be16(pb, 1); // majorVersion - put_be16(pb, 2); // minorVersion - put_be32(pb, KAG_SIZE); // KAGSize - - put_be64(pb, partition_offset); // ThisPartition - - if (!memcmp(key, body_partition_key, 16) && mxf->body_partitions_count > 1) - put_be64(pb, mxf->body_partition_offset[mxf->body_partitions_count-2]); // PreviousPartition - else if (!memcmp(key, footer_partition_key, 16) && mxf->body_partitions_count) - put_be64(pb, mxf->body_partition_offset[mxf->body_partitions_count-1]); // PreviousPartition - else - put_be64(pb, 0); - - put_be64(pb, mxf->footer_partition_offset); // footerPartition - - // set offset - header_byte_count_offset = url_ftell(pb); - put_be64(pb, 0); // headerByteCount, update later - - // indexTable - put_be64(pb, index_byte_count); // indexByteCount - put_be32(pb, index_byte_count ? indexsid : 0); // indexSID - - // BodyOffset - if (bodysid && mxf->edit_units_count && mxf->body_partitions_count) { - put_be64(pb, mxf->body_offset); - } else - put_be64(pb, 0); - - put_be32(pb, bodysid); // bodySID - - // operational pattern - put_buffer(pb, op1a_ul, 16); - - // essence container - mxf_write_essence_container_refs(s); - - if (write_metadata) { - // mark the start of the headermetadata and calculate metadata size - int64_t pos, start; - unsigned header_byte_count; - - mxf_write_klv_fill(s); - start = url_ftell(s->pb); - mxf_write_primer_pack(s); - mxf_write_header_metadata_sets(s); - pos = url_ftell(s->pb); - header_byte_count = pos - start + klv_fill_size(pos); - - // update header_byte_count - url_fseek(pb, header_byte_count_offset, SEEK_SET); - put_be64(pb, header_byte_count); - url_fseek(pb, pos, SEEK_SET); - } - - put_flush_packet(pb); -} - -static const UID mxf_mpeg2_codec_uls[] = { - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, // MP-ML I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, // MP-ML Long GOP - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, // 422P-ML I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, // 422P-ML Long GOP - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 }, // MP-HL I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, // MP-HL Long GOP - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, // 422P-HL I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, // 422P-HL Long GOP -}; - -static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx) -{ - int long_gop = avctx->gop_size > 1 || avctx->has_b_frames; - - if (avctx->profile == 4) { // Main - if (avctx->level == 8) // Main - return &mxf_mpeg2_codec_uls[0+long_gop]; - else if (avctx->level == 4) // High - return &mxf_mpeg2_codec_uls[4+long_gop]; - } else if (avctx->profile == 0) { // 422 - if (avctx->level == 5) // Main - return &mxf_mpeg2_codec_uls[2+long_gop]; - else if (avctx->level == 2) // High - return &mxf_mpeg2_codec_uls[6+long_gop]; - } - return NULL; -} - -static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt, int *flags) -{ - MXFStreamContext *sc = st->priv_data; - MXFContext *mxf = s->priv_data; - uint32_t c = -1; - int i; - - *flags = 0; - - for(i = 0; i < pkt->size - 4; i++) { - c = (c<<8) + pkt->data[i]; - if (c == 0x1b5) { - if ((pkt->data[i+1] & 0xf0) == 0x10) { // seq ext - st->codec->profile = pkt->data[i+1] & 0x07; - st->codec->level = pkt->data[i+2] >> 4; - } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) { // pict coding ext - sc->interlaced = !(pkt->data[i+5] & 0x80); // progressive frame - break; - } - } else if (c == 0x1b8) { // gop - if (pkt->data[i+4]>>6 & 0x01) { // closed - sc->closed_gop = 1; - if (*flags & 0x40) // sequence header present - *flags |= 0x80; // random access - } - if (!mxf->header_written) { - unsigned hours = (pkt->data[i+1]>>2) & 0x1f; - unsigned minutes = ((pkt->data[i+1] & 0x03) << 4) | (pkt->data[i+2]>>4); - unsigned seconds = ((pkt->data[i+2] & 0x07) << 3) | (pkt->data[i+3]>>5); - unsigned frames = ((pkt->data[i+3] & 0x1f) << 1) | (pkt->data[i+4]>>7); - mxf->timecode_drop_frame = !!(pkt->data[i+1] & 0x80); - mxf->timecode_start = (hours*3600 + minutes*60 + seconds) * - mxf->timecode_base + frames; - if (mxf->timecode_drop_frame) { - unsigned tminutes = 60 * hours + minutes; - mxf->timecode_start -= 2 * (tminutes - tminutes / 10); - } - av_log(s, AV_LOG_DEBUG, "frame %d %d:%d:%d%c%d\n", mxf->timecode_start, - hours, minutes, seconds, mxf->timecode_drop_frame ? ';':':', frames); - } - } else if (c == 0x1b3) { // seq - *flags |= 0x40; - switch ((pkt->data[i+4]>>4) & 0xf) { - case 2: sc->aspect_ratio = (AVRational){ 4, 3}; break; - case 3: sc->aspect_ratio = (AVRational){ 16, 9}; break; - case 4: sc->aspect_ratio = (AVRational){221,100}; break; - default: - av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den, - st->codec->width, st->codec->height, 1024*1024); - } - } else if (c == 0x100) { // pic - int pict_type = (pkt->data[i+2]>>3) & 0x07; - if (pict_type == 2) { // P frame - *flags |= 0x22; - sc->closed_gop = 0; // reset closed gop, don't matter anymore - } else if (pict_type == 3) { // B frame - if (sc->closed_gop) - *flags |= 0x13; // only backward prediction - else - *flags |= 0x33; - sc->temporal_reordering = -1; - } else if (!pict_type) { - av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n"); - return 0; - } - } - } - if (s->oformat != &mxf_d10_muxer) - sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec); - return !!sc->codec_ul; -} - -static uint64_t mxf_parse_timestamp(time_t timestamp) -{ - struct tm *time = gmtime(×tamp); - return (uint64_t)(time->tm_year+1900) << 48 | - (uint64_t)(time->tm_mon+1) << 40 | - (uint64_t) time->tm_mday << 32 | - time->tm_hour << 24 | - time->tm_min << 16 | - time->tm_sec << 8; -} - -static void mxf_gen_umid(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - uint32_t seed = ff_random_get_seed(); - uint64_t umid = seed + 0x5294713400000000LL; - - AV_WB64(mxf->umid , umid); - AV_WB64(mxf->umid+8, umid>>8); - - mxf->instance_number = seed; -} - -static int mxf_write_header(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - int i; - uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0}; - const int *samples_per_frame = NULL; - - if (!s->nb_streams) - return -1; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MXFStreamContext *sc = av_mallocz(sizeof(*sc)); - if (!sc) - return AVERROR(ENOMEM); - st->priv_data = sc; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (i != 0) { - av_log(s, AV_LOG_ERROR, "video stream must be first track\n"); - return -1; - } - if (fabs(av_q2d(st->codec->time_base) - 1/25.0) < 0.0001) { - samples_per_frame = PAL_samples_per_frame; - mxf->time_base = (AVRational){ 1, 25 }; - mxf->timecode_base = 25; - } else if (fabs(av_q2d(st->codec->time_base) - 1001/30000.0) < 0.0001) { - samples_per_frame = NTSC_samples_per_frame; - mxf->time_base = (AVRational){ 1001, 30000 }; - mxf->timecode_base = 30; - } else { - av_log(s, AV_LOG_ERROR, "unsupported video frame rate\n"); - return -1; - } - av_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den); - if (s->oformat == &mxf_d10_muxer) { - if (st->codec->bit_rate == 50000000) - if (mxf->time_base.den == 25) sc->index = 3; - else sc->index = 5; - else if (st->codec->bit_rate == 40000000) - if (mxf->time_base.den == 25) sc->index = 7; - else sc->index = 9; - else if (st->codec->bit_rate == 30000000) - if (mxf->time_base.den == 25) sc->index = 11; - else sc->index = 13; - else { - av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n"); - return -1; - } - - mxf->edit_unit_byte_count = KAG_SIZE; // system element - mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate * - mxf->time_base.num / (8*mxf->time_base.den); - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - mxf->edit_unit_byte_count += 16 + 4 + 4 + samples_per_frame[0]*8*4; - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - } - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (st->codec->sample_rate != 48000) { - av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n"); - return -1; - } - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - if (s->oformat == &mxf_d10_muxer) { - if (st->index != 1) { - av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n"); - return -1; - } - if (st->codec->codec_id != CODEC_ID_PCM_S16LE && - st->codec->codec_id != CODEC_ID_PCM_S24LE) { - av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n"); - } - sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1; - } else - mxf->slice_count = 1; - } - - if (!sc->index) { - sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id); - if (sc->index == -1) { - av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, " - "codec not currently supported in container\n", i); - return -1; - } - } - - sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; - - memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15); - sc->track_essence_element_key[15] = present[sc->index]; - PRINT_KEY(s, "track essence element key", sc->track_essence_element_key); - - if (!present[sc->index]) - mxf->essence_container_count++; - present[sc->index]++; - } - - if (s->oformat == &mxf_d10_muxer) { - mxf->essence_container_count = 1; - } - - if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) - mxf_gen_umid(s); - - for (i = 0; i < s->nb_streams; i++) { - MXFStreamContext *sc = s->streams[i]->priv_data; - // update element count - sc->track_essence_element_key[13] = present[sc->index]; - sc->order = AV_RB32(sc->track_essence_element_key+12); - } - - if (s->timestamp) - mxf->timestamp = mxf_parse_timestamp(s->timestamp); - mxf->duration = -1; - - mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track)); - if (!mxf->timecode_track) - return AVERROR(ENOMEM); - mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext)); - if (!mxf->timecode_track->priv_data) - return AVERROR(ENOMEM); - mxf->timecode_track->index = -1; - - if (!samples_per_frame) - samples_per_frame = PAL_samples_per_frame; - - if (ff_audio_interleave_init(s, samples_per_frame, mxf->time_base) < 0) - return -1; - - return 0; -} - -static const uint8_t system_metadata_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 }; -static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x43,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x02,0x01 }; - -static uint32_t ff_framenum_to_12m_time_code(unsigned frame, int drop, int fps) -{ - return (0 << 31) | // color frame flag - (0 << 30) | // drop frame flag - ( ((frame % fps) / 10) << 28) | // tens of frames - ( ((frame % fps) % 10) << 24) | // units of frames - (0 << 23) | // field phase (NTSC), b0 (PAL) - ((((frame / fps) % 60) / 10) << 20) | // tens of seconds - ((((frame / fps) % 60) % 10) << 16) | // units of seconds - (0 << 15) | // b0 (NTSC), b2 (PAL) - ((((frame / (fps * 60)) % 60) / 10) << 12) | // tens of minutes - ((((frame / (fps * 60)) % 60) % 10) << 8) | // units of minutes - (0 << 7) | // b1 - (0 << 6) | // b2 (NSC), field phase (PAL) - ((((frame / (fps * 3600) % 24)) / 10) << 4) | // tens of hours - ( (frame / (fps * 3600) % 24)) % 10; // units of hours -} - -static void mxf_write_system_item(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned frame; - uint32_t time_code; - - frame = mxf->timecode_start + mxf->last_indexed_edit_unit + mxf->edit_units_count; - - // write system metadata pack - put_buffer(pb, system_metadata_pack_key, 16); - klv_encode_ber4_length(pb, 57); - put_byte(pb, 0x5c); // UL, user date/time stamp, picture and sound item present - put_byte(pb, 0x04); // content package rate - put_byte(pb, 0x00); // content package type - put_be16(pb, 0x00); // channel handle - put_be16(pb, frame); // continuity count - if (mxf->essence_container_count > 1) - put_buffer(pb, multiple_desc_ul, 16); - else { - MXFStreamContext *sc = s->streams[0]->priv_data; - put_buffer(pb, mxf_essence_container_uls[sc->index].container_ul, 16); - } - put_byte(pb, 0); - put_be64(pb, 0); - put_be64(pb, 0); // creation date/time stamp - - put_byte(pb, 0x81); // SMPTE 12M time code - time_code = ff_framenum_to_12m_time_code(frame, mxf->timecode_drop_frame, mxf->timecode_base); - put_be32(pb, time_code); - put_be32(pb, 0); // binary group data - put_be64(pb, 0); - - // write system metadata package set - put_buffer(pb, system_metadata_package_set_key, 16); - klv_encode_ber4_length(pb, 35); - put_byte(pb, 0x83); // UMID - put_be16(pb, 0x20); - mxf_write_umid(s, 1); -} - -static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num / - (8*mxf->time_base.den); // frame size - int pad; - - packet_size += 16 + 4; - packet_size += klv_fill_size(packet_size); - - klv_encode_ber4_length(pb, pkt->size); - put_buffer(pb, pkt->data, pkt->size); - - // ensure CBR muxing by padding to correct video frame size - pad = packet_size - pkt->size - 16 - 4; - if (pad > 20) { - put_buffer(s->pb, klv_fill_key, 16); - pad -= 16 + 4; - klv_encode_ber4_length(s->pb, pad); - for (; pad; pad--) - put_byte(s->pb, 0); - assert(!(url_ftell(s->pb) & (KAG_SIZE-1))); - } else { - av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n"); - for (; pad > 0; pad--) - put_byte(s->pb, 0); - } -} - -static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - int frame_size = pkt->size / st->codec->block_align; - uint8_t *samples = pkt->data; - uint8_t *end = pkt->data + pkt->size; - int i; - - klv_encode_ber4_length(pb, 4 + frame_size*4*8); - - put_byte(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1)); - put_le16(pb, frame_size); - put_byte(pb, (1<codec->channels)-1); - - while (samples < end) { - for (i = 0; i < st->codec->channels; i++) { - uint32_t sample; - if (st->codec->codec_id == CODEC_ID_PCM_S24LE) { - sample = AV_RL24(samples)<< 4; - samples += 3; - } else { - sample = AV_RL16(samples)<<12; - samples += 2; - } - put_le32(pb, sample | i); - } - for (; i < 8; i++) - put_le32(pb, i); - } -} - -static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st = s->streams[pkt->stream_index]; - MXFStreamContext *sc = st->priv_data; - int flags = 0; - - if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) { - mxf->index_entries = av_realloc(mxf->index_entries, - (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries)); - if (!mxf->index_entries) { - av_log(s, AV_LOG_ERROR, "could not allocate index entries\n"); - return -1; - } - } - - if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) { - if (!mxf_parse_mpeg2_frame(s, st, pkt, &flags)) { - av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n"); - return -1; - } - } - - if (!mxf->header_written) { - if (mxf->edit_unit_byte_count) { - mxf_write_partition(s, 1, 2, header_open_partition_key, 1); - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } else { - mxf_write_partition(s, 0, 0, header_open_partition_key, 1); - } - mxf->header_written = 1; - } - - if (st->index == 0) { - if (!mxf->edit_unit_byte_count && - (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) && - !(flags & 0x33)) { // I frame, Gop start - mxf_write_klv_fill(s); - mxf_write_partition(s, 1, 2, body_partition_key, 0); - - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } - - mxf_write_klv_fill(s); - mxf_write_system_item(s); - - if (!mxf->edit_unit_byte_count) { - mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset; - mxf->index_entries[mxf->edit_units_count].flags = flags; - mxf->body_offset += KAG_SIZE; // size of system element - } - mxf->edit_units_count++; - } else if (!mxf->edit_unit_byte_count && st->index == 1) { - mxf->index_entries[mxf->edit_units_count-1].slice_offset = - mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset; - } - - mxf_write_klv_fill(s); - put_buffer(pb, sc->track_essence_element_key, 16); // write key - if (s->oformat == &mxf_d10_muxer) { - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - mxf_write_d10_video_packet(s, st, pkt); - else - mxf_write_d10_audio_packet(s, st, pkt); - } else { - klv_encode_ber4_length(pb, pkt->size); // write length - put_buffer(pb, pkt->data, pkt->size); - mxf->body_offset += 16+4+pkt->size + klv_fill_size(16+4+pkt->size); - } - - put_flush_packet(pb); - - return 0; -} - -static void mxf_write_random_index_pack(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - uint64_t pos = url_ftell(pb); - int i; - - put_buffer(pb, random_index_pack_key, 16); - klv_encode_ber_length(pb, 28 + 12*mxf->body_partitions_count); - - if (mxf->edit_unit_byte_count) - put_be32(pb, 1); // BodySID of header partition - else - put_be32(pb, 0); - put_be64(pb, 0); // offset of header partition - - for (i = 0; i < mxf->body_partitions_count; i++) { - put_be32(pb, 1); // BodySID - put_be64(pb, mxf->body_partition_offset[i]); - } - - put_be32(pb, 0); // BodySID of footer partition - put_be64(pb, mxf->footer_partition_offset); - - put_be32(pb, url_ftell(pb) - pos + 4); -} - -static int mxf_write_footer(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - ByteIOContext *pb = s->pb; - - mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count; - - mxf_write_klv_fill(s); - mxf->footer_partition_offset = url_ftell(pb); - if (mxf->edit_unit_byte_count) { // no need to repeat index - mxf_write_partition(s, 0, 0, footer_partition_key, 0); - } else { - mxf_write_partition(s, 0, 2, footer_partition_key, 0); - - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } - - mxf_write_klv_fill(s); - mxf_write_random_index_pack(s); - - if (!url_is_streamed(s->pb)) { - url_fseek(pb, 0, SEEK_SET); - if (mxf->edit_unit_byte_count) { - mxf_write_partition(s, 1, 2, header_closed_partition_key, 1); - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } else { - mxf_write_partition(s, 0, 0, header_closed_partition_key, 1); - } - } - - put_flush_packet(pb); - - ff_audio_interleave_close(s); - - av_freep(&mxf->index_entries); - av_freep(&mxf->body_partition_offset); - av_freep(&mxf->timecode_track->priv_data); - av_freep(&mxf->timecode_track); - - mxf_free(s); - - return 0; -} - -static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) -{ - int i, stream_count = 0; - - for (i = 0; i < s->nb_streams; i++) - stream_count += !!s->streams[i]->last_in_packet_buffer; - - if (stream_count && (s->nb_streams == stream_count || flush)) { - AVPacketList *pktl = s->packet_buffer; - if (s->nb_streams != stream_count) { - AVPacketList *last = NULL; - // find last packet in edit unit - while (pktl) { - if (!stream_count || pktl->pkt.stream_index == 0) - break; - last = pktl; - pktl = pktl->next; - stream_count--; - } - // purge packet queue - while (pktl) { - AVPacketList *next = pktl->next; - - if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl) - s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL; - av_free_packet(&pktl->pkt); - av_freep(&pktl); - pktl = next; - } - if (last) - last->next = NULL; - else { - s->packet_buffer = NULL; - s->packet_buffer_end= NULL; - goto out; - } - pktl = s->packet_buffer; - } - - *out = pktl->pkt; - //av_log(s, AV_LOG_DEBUG, "out st:%d dts:%lld\n", (*out).stream_index, (*out).dts); - s->packet_buffer = pktl->next; - if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl) - s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL; - if(!s->packet_buffer) - s->packet_buffer_end= NULL; - av_freep(&pktl); - return 1; - } else { - out: - av_init_packet(out); - return 0; - } -} - -static int mxf_compare_timestamps(AVFormatContext *s, AVPacket *next, AVPacket *pkt) -{ - MXFStreamContext *sc = s->streams[pkt ->stream_index]->priv_data; - MXFStreamContext *sc2 = s->streams[next->stream_index]->priv_data; - - return next->dts > pkt->dts || - (next->dts == pkt->dts && sc->order < sc2->order); -} - -static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) -{ - return ff_audio_rechunk_interleave(s, out, pkt, flush, - mxf_interleave_get_packet, mxf_compare_timestamps); -} - -AVOutputFormat mxf_muxer = { - "mxf", - NULL_IF_CONFIG_SMALL("Material eXchange Format"), - "application/mxf", - "mxf", - sizeof(MXFContext), - CODEC_ID_PCM_S16LE, - CODEC_ID_MPEG2VIDEO, - mxf_write_header, - mxf_write_packet, - mxf_write_footer, - AVFMT_NOTIMESTAMPS, - NULL, - mxf_interleave, -}; - -AVOutputFormat mxf_d10_muxer = { - "mxf_d10", - NULL_IF_CONFIG_SMALL("Material eXchange Format, D-10 Mapping"), - "application/mxf", - NULL, - sizeof(MXFContext), - CODEC_ID_PCM_S16LE, - CODEC_ID_MPEG2VIDEO, - mxf_write_header, - mxf_write_packet, - mxf_write_footer, - AVFMT_NOTIMESTAMPS, - NULL, - mxf_interleave, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/ncdec.c b/tizen/distrib/ffmpeg/libavformat/ncdec.c deleted file mode 100644 index 6d99a04..0000000 --- a/tizen/distrib/ffmpeg/libavformat/ncdec.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * NC camera feed demuxer - * Copyright (c) 2009 Nicolas Martin (martinic at iro dot umontreal dot ca) - * Edouard Auvinet - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define NC_VIDEO_FLAG 0x1A5 - -static int nc_probe(AVProbeData *probe_packet) -{ - int size; - - if (AV_RB32(probe_packet->buf) != NC_VIDEO_FLAG) - return 0; - - size = AV_RL16(probe_packet->buf + 5); - - if (size + 20 > probe_packet->buf_size) - return AVPROBE_SCORE_MAX/4; - - if (AV_RB32(probe_packet->buf+16+size) == NC_VIDEO_FLAG) - return AVPROBE_SCORE_MAX; - - return 0; -} - -static int nc_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - AVStream *st = av_new_stream(s, 0); - - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG4; - st->need_parsing = AVSTREAM_PARSE_FULL; - - av_set_pts_info(st, 64, 1, 100); - - return 0; -} - -static int nc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size; - int ret; - - uint32_t state=-1; - while (state != NC_VIDEO_FLAG) { - if (url_feof(s->pb)) - return AVERROR(EIO); - state = (state<<8) + get_byte(s->pb); - } - - get_byte(s->pb); - size = get_le16(s->pb); - url_fskip(s->pb, 9); - - if (size == 0) { - av_log(s, AV_LOG_DEBUG, "Next packet size is zero\n"); - return AVERROR(EAGAIN); - } - - ret = av_get_packet(s->pb, pkt, size); - if (ret != size) { - if (ret > 0) av_free_packet(pkt); - return AVERROR(EIO); - } - - pkt->stream_index = 0; - return size; -} - -AVInputFormat nc_demuxer = { - "nc", - NULL_IF_CONFIG_SMALL("NC camera feed format"), - 0, - nc_probe, - nc_read_header, - nc_read_packet, - .extensions = "v", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/network.h b/tizen/distrib/ffmpeg/libavformat/network.h deleted file mode 100644 index 0fbcbbb..0000000 --- a/tizen/distrib/ffmpeg/libavformat/network.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2007 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_NETWORK_H -#define AVFORMAT_NETWORK_H - -#include "config.h" - -#if HAVE_WINSOCK2_H -#include -#include - -#define ff_neterrno() (-WSAGetLastError()) -#define FF_NETERROR(err) (-WSA##err) -#define WSAEAGAIN WSAEWOULDBLOCK -#else -#include -#include -#include -#include - -#define ff_neterrno() AVERROR(errno) -#define FF_NETERROR(err) AVERROR(err) -#endif - -#if HAVE_ARPA_INET_H -#include -#endif - -int ff_socket_nonblock(int socket, int enable); - -static inline int ff_network_init(void) -{ -#if HAVE_WINSOCK2_H - WSADATA wsaData; - if (WSAStartup(MAKEWORD(1,1), &wsaData)) - return 0; -#endif - return 1; -} - -static inline void ff_network_close(void) -{ -#if HAVE_WINSOCK2_H - WSACleanup(); -#endif -} - -int ff_inet_aton (const char * str, struct in_addr * add); - -#if !HAVE_STRUCT_SOCKADDR_STORAGE -struct sockaddr_storage { -#if HAVE_STRUCT_SOCKADDR_SA_LEN - uint8_t ss_len; - uint8_t ss_family; -#else - uint16_t ss_family; -#endif - char ss_pad1[6]; - int64_t ss_align; - char ss_pad2[112]; -}; -#endif - -#if !HAVE_STRUCT_ADDRINFO -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - int ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct addrinfo *ai_next; -}; -#endif - -/* getaddrinfo constants */ -#ifndef EAI_FAIL -#define EAI_FAIL 4 -#endif - -#ifndef EAI_FAMILY -#define EAI_FAMILY 5 -#endif - -#ifndef EAI_NONAME -#define EAI_NONAME 8 -#endif - -#ifndef AI_PASSIVE -#define AI_PASSIVE 1 -#endif - -#ifndef AI_CANONNAME -#define AI_CANONNAME 2 -#endif - -#ifndef AI_NUMERICHOST -#define AI_NUMERICHOST 4 -#endif - -#ifndef NI_NOFQDN -#define NI_NOFQDN 1 -#endif - -#ifndef NI_NUMERICHOST -#define NI_NUMERICHOST 2 -#endif - -#ifndef NI_NAMERQD -#define NI_NAMERQD 4 -#endif - -#ifndef NI_NUMERICSERV -#define NI_NUMERICSERV 8 -#endif - -#ifndef NI_DGRAM -#define NI_DGRAM 16 -#endif - -#if !HAVE_GETADDRINFO -int ff_getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, struct addrinfo **res); -void ff_freeaddrinfo(struct addrinfo *res); -int ff_getnameinfo(const struct sockaddr *sa, int salen, - char *host, int hostlen, - char *serv, int servlen, int flags); -const char *ff_gai_strerror(int ecode); -#define getaddrinfo ff_getaddrinfo -#define freeaddrinfo ff_freeaddrinfo -#define getnameinfo ff_getnameinfo -#define gai_strerror ff_gai_strerror -#endif - -#endif /* AVFORMAT_NETWORK_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/nsvdec.c b/tizen/distrib/ffmpeg/libavformat/nsvdec.c deleted file mode 100644 index 44e5097..0000000 --- a/tizen/distrib/ffmpeg/libavformat/nsvdec.c +++ /dev/null @@ -1,786 +0,0 @@ -/* - * NSV demuxer - * Copyright (c) 2004 The FFmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "riff.h" - -//#define DEBUG -//#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!! -//#define DEBUG_SEEK -#define CHECK_SUBSEQUENT_NSVS -//#define DISABLE_AUDIO - -/* max bytes to crawl for trying to resync - * stupid streaming servers don't start at chunk boundaries... - */ -#define NSV_MAX_RESYNC (500*1024) -#define NSV_MAX_RESYNC_TRIES 300 - -/* - * First version by Francois Revol - revol@free.fr - * References: - * (1) http://www.multimedia.cx/nsv-format.txt - * seems someone came to the same conclusions as me, and updated it: - * (2) http://www.stud.ktu.lt/~vitslav/nsv/nsv-format.txt - * http://www.stud.ktu.lt/~vitslav/nsv/ - * official docs - * (3) http://ultravox.aol.com/NSVFormat.rtf - * Sample files: - * (S1) http://www.nullsoft.com/nsv/samples/ - * http://www.nullsoft.com/nsv/samples/faster.nsv - * http://streamripper.sourceforge.net/openbb/read.php?TID=492&page=4 - */ - -/* - * notes on the header (Francois Revol): - * - * It is followed by strings, then a table, but nothing tells - * where the table begins according to (1). After checking faster.nsv, - * I believe NVSf[16-19] gives the size of the strings data - * (that is the offset of the data table after the header). - * After checking all samples from (S1) all confirms this. - * - * Then, about NSVf[12-15], faster.nsf has 179700. When veiwing it in VLC, - * I noticed there was about 1 NVSs chunk/s, so I ran - * strings faster.nsv | grep NSVs | wc -l - * which gave me 180. That leads me to think that NSVf[12-15] might be the - * file length in milliseconds. - * Let's try that: - * for f in *.nsv; do HTIME="$(od -t x4 "$f" | head -1 | sed 's/.* //')"; echo "'$f' $((0x$HTIME))s = $((0x$HTIME/1000/60)):$((0x$HTIME/1000%60))"; done - * except for nstrailer (which doesn't have an NSVf header), it repports correct time. - * - * nsvtrailer.nsv (S1) does not have any NSVf header, only NSVs chunks, - * so the header seems to not be mandatory. (for streaming). - * - * index slice duration check (excepts nsvtrailer.nsv): - * for f in [^n]*.nsv; do DUR="$(ffmpeg -i "$f" 2>/dev/null | grep 'NSVf duration' | cut -d ' ' -f 4)"; IC="$(ffmpeg -i "$f" 2>/dev/null | grep 'INDEX ENTRIES' | cut -d ' ' -f 2)"; echo "duration $DUR, slite time $(($DUR/$IC))"; done - */ - -/* - * TODO: - * - handle timestamps !!! - * - use index - * - mime-type in probe() - * - seek - */ - -#ifdef DEBUG -#define PRINT(_v) printf _v -#else -#define PRINT(_v) -#endif - -#if 0 -struct NSVf_header { - uint32_t chunk_tag; /* 'NSVf' */ - uint32_t chunk_size; - uint32_t file_size; /* max 4GB ??? no one learns anything it seems :^) */ - uint32_t file_length; //unknown1; /* what about MSB of file_size ? */ - uint32_t info_strings_size; /* size of the info strings */ //unknown2; - uint32_t table_entries; - uint32_t table_entries_used; /* the left ones should be -1 */ -}; - -struct NSVs_header { - uint32_t chunk_tag; /* 'NSVs' */ - uint32_t v4cc; /* or 'NONE' */ - uint32_t a4cc; /* or 'NONE' */ - uint16_t vwidth; /* assert(vwidth%16==0) */ - uint16_t vheight; /* assert(vheight%16==0) */ - uint8_t framerate; /* value = (framerate&0x80)?frtable[frameratex0x7f]:framerate */ - uint16_t unknown; -}; - -struct nsv_avchunk_header { - uint8_t vchunk_size_lsb; - uint16_t vchunk_size_msb; /* value = (vchunk_size_msb << 4) | (vchunk_size_lsb >> 4) */ - uint16_t achunk_size; -}; - -struct nsv_pcm_header { - uint8_t bits_per_sample; - uint8_t channel_count; - uint16_t sample_rate; -}; -#endif - -/* variation from avi.h */ -/*typedef struct CodecTag { - int id; - unsigned int tag; -} CodecTag;*/ - -/* tags */ - -#define T_NSVF MKTAG('N', 'S', 'V', 'f') /* file header */ -#define T_NSVS MKTAG('N', 'S', 'V', 's') /* chunk header */ -#define T_TOC2 MKTAG('T', 'O', 'C', '2') /* extra index marker */ -#define T_NONE MKTAG('N', 'O', 'N', 'E') /* null a/v 4CC */ -#define T_SUBT MKTAG('S', 'U', 'B', 'T') /* subtitle aux data */ -#define T_ASYN MKTAG('A', 'S', 'Y', 'N') /* async a/v aux marker */ -#define T_KEYF MKTAG('K', 'E', 'Y', 'F') /* video keyframe aux marker (addition) */ - -#define TB_NSVF MKBETAG('N', 'S', 'V', 'f') -#define TB_NSVS MKBETAG('N', 'S', 'V', 's') - -/* hardcoded stream indexes */ -#define NSV_ST_VIDEO 0 -#define NSV_ST_AUDIO 1 -#define NSV_ST_SUBT 2 - -enum NSVStatus { - NSV_UNSYNC, - NSV_FOUND_NSVF, - NSV_HAS_READ_NSVF, - NSV_FOUND_NSVS, - NSV_HAS_READ_NSVS, - NSV_FOUND_BEEF, - NSV_GOT_VIDEO, - NSV_GOT_AUDIO, -}; - -typedef struct NSVStream { - int frame_offset; /* current frame (video) or byte (audio) counter - (used to compute the pts) */ - int scale; - int rate; - int sample_size; /* audio only data */ - int start; - - int new_frame_offset; /* temporary storage (used during seek) */ - int cum_len; /* temporary storage (used during seek) */ -} NSVStream; - -typedef struct { - int base_offset; - int NSVf_end; - uint32_t *nsvs_file_offset; - int index_entries; - enum NSVStatus state; - AVPacket ahead[2]; /* [v, a] if .data is !NULL there is something */ - /* cached */ - int64_t duration; - uint32_t vtag, atag; - uint16_t vwidth, vheight; - int16_t avsync; - AVRational framerate; - uint32_t *nsvs_timestamps; - //DVDemuxContext* dv_demux; -} NSVContext; - -static const AVCodecTag nsv_codec_video_tags[] = { - { CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') }, - { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') }, - { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, - { CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') }, - { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') }, - { CODEC_ID_VP6, MKTAG('V', 'P', '6', ' ') }, - { CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') }, - { CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') }, - { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, -/* - { CODEC_ID_VP4, MKTAG('V', 'P', '4', ' ') }, - { CODEC_ID_VP4, MKTAG('V', 'P', '4', '0') }, -*/ - { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, /* cf sample xvid decoder from nsv_codec_sdk.zip */ - { CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', '3') }, - { CODEC_ID_NONE, 0 }, -}; - -static const AVCodecTag nsv_codec_audio_tags[] = { - { CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') }, - { CODEC_ID_AAC, MKTAG('A', 'A', 'C', ' ') }, - { CODEC_ID_AAC, MKTAG('A', 'A', 'C', 'P') }, - { CODEC_ID_SPEEX, MKTAG('S', 'P', 'X', ' ') }, - { CODEC_ID_PCM_U16LE, MKTAG('P', 'C', 'M', ' ') }, - { CODEC_ID_NONE, 0 }, -}; - -//static int nsv_load_index(AVFormatContext *s); -static int nsv_read_chunk(AVFormatContext *s, int fill_header); - -#ifdef DEBUG -static void print_tag(const char *str, unsigned int tag, int size) -{ - printf("%s: tag=%c%c%c%c\n", - str, tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff); -} -#endif - -/* try to find something we recognize, and set the state accordingly */ -static int nsv_resync(AVFormatContext *s) -{ - NSVContext *nsv = s->priv_data; - ByteIOContext *pb = s->pb; - uint32_t v = 0; - int i; - - PRINT(("%s(), offset = %"PRId64", state = %d\n", __FUNCTION__, url_ftell(pb), nsv->state)); - - //nsv->state = NSV_UNSYNC; - - for (i = 0; i < NSV_MAX_RESYNC; i++) { - if (url_feof(pb)) { - PRINT(("NSV EOF\n")); - nsv->state = NSV_UNSYNC; - return -1; - } - v <<= 8; - v |= get_byte(pb); -/* - if (i < 8) { - PRINT(("NSV resync: [%d] = %02x\n", i, v & 0x0FF)); - } -*/ - - if ((v & 0x0000ffff) == 0xefbe) { /* BEEF */ - PRINT(("NSV resynced on BEEF after %d bytes\n", i+1)); - nsv->state = NSV_FOUND_BEEF; - return 0; - } - /* we read as big endian, thus the MK*BE* */ - if (v == TB_NSVF) { /* NSVf */ - PRINT(("NSV resynced on NSVf after %d bytes\n", i+1)); - nsv->state = NSV_FOUND_NSVF; - return 0; - } - if (v == MKBETAG('N', 'S', 'V', 's')) { /* NSVs */ - PRINT(("NSV resynced on NSVs after %d bytes\n", i+1)); - nsv->state = NSV_FOUND_NSVS; - return 0; - } - - } - PRINT(("NSV sync lost\n")); - return -1; -} - -static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) -{ - NSVContext *nsv = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned int file_size, size; - int64_t duration; - int strings_size; - int table_entries; - int table_entries_used; - - PRINT(("%s()\n", __FUNCTION__)); - - nsv->state = NSV_UNSYNC; /* in case we fail */ - - size = get_le32(pb); - if (size < 28) - return -1; - nsv->NSVf_end = size; - - //s->file_size = (uint32_t)get_le32(pb); - file_size = (uint32_t)get_le32(pb); - PRINT(("NSV NSVf chunk_size %u\n", size)); - PRINT(("NSV NSVf file_size %u\n", file_size)); - - nsv->duration = duration = get_le32(pb); /* in ms */ - PRINT(("NSV NSVf duration %"PRId64" ms\n", duration)); - // XXX: store it in AVStreams - - strings_size = get_le32(pb); - table_entries = get_le32(pb); - table_entries_used = get_le32(pb); - PRINT(("NSV NSVf info-strings size: %d, table entries: %d, bis %d\n", - strings_size, table_entries, table_entries_used)); - if (url_feof(pb)) - return -1; - - PRINT(("NSV got header; filepos %"PRId64"\n", url_ftell(pb))); - - if (strings_size > 0) { - char *strings; /* last byte will be '\0' to play safe with str*() */ - char *p, *endp; - char *token, *value; - char quote; - - p = strings = av_mallocz(strings_size + 1); - endp = strings + strings_size; - get_buffer(pb, strings, strings_size); - while (p < endp) { - while (*p == ' ') - p++; /* strip out spaces */ - if (p >= endp-2) - break; - token = p; - p = strchr(p, '='); - if (!p || p >= endp-2) - break; - *p++ = '\0'; - quote = *p++; - value = p; - p = strchr(p, quote); - if (!p || p >= endp) - break; - *p++ = '\0'; - PRINT(("NSV NSVf INFO: %s='%s'\n", token, value)); - av_metadata_set2(&s->metadata, token, value, 0); - } - av_free(strings); - } - if (url_feof(pb)) - return -1; - - PRINT(("NSV got infos; filepos %"PRId64"\n", url_ftell(pb))); - - if (table_entries_used > 0) { - int i; - nsv->index_entries = table_entries_used; - if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t)) - return -1; - nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t)); - - for(i=0;insvs_file_offset[i] = get_le32(pb) + size; - - if(table_entries > table_entries_used && - get_le32(pb) == MKTAG('T','O','C','2')) { - nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t)); - for(i=0;insvs_timestamps[i] = get_le32(pb); - } - } - } - - PRINT(("NSV got index; filepos %"PRId64"\n", url_ftell(pb))); - -#ifdef DEBUG_DUMP_INDEX -#define V(v) ((v<0x20 || v > 127)?'.':v) - /* dump index */ - PRINT(("NSV %d INDEX ENTRIES:\n", table_entries)); - PRINT(("NSV [dataoffset][fileoffset]\n", table_entries)); - for (i = 0; i < table_entries; i++) { - unsigned char b[8]; - url_fseek(pb, size + nsv->nsvs_file_offset[i], SEEK_SET); - get_buffer(pb, b, 8); - PRINT(("NSV [0x%08lx][0x%08lx]: %02x %02x %02x %02x %02x %02x %02x %02x" - "%c%c%c%c%c%c%c%c\n", - nsv->nsvs_file_offset[i], size + nsv->nsvs_file_offset[i], - b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], - V(b[0]), V(b[1]), V(b[2]), V(b[3]), V(b[4]), V(b[5]), V(b[6]), V(b[7]) )); - } - //url_fseek(pb, size, SEEK_SET); /* go back to end of header */ -#undef V -#endif - - url_fseek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */ - - if (url_feof(pb)) - return -1; - nsv->state = NSV_HAS_READ_NSVF; - return 0; -} - -static int nsv_parse_NSVs_header(AVFormatContext *s, AVFormatParameters *ap) -{ - NSVContext *nsv = s->priv_data; - ByteIOContext *pb = s->pb; - uint32_t vtag, atag; - uint16_t vwidth, vheight; - AVRational framerate; - int i; - AVStream *st; - NSVStream *nst; - PRINT(("%s()\n", __FUNCTION__)); - - vtag = get_le32(pb); - atag = get_le32(pb); - vwidth = get_le16(pb); - vheight = get_le16(pb); - i = get_byte(pb); - - PRINT(("NSV NSVs framerate code %2x\n", i)); - if(i&0x80) { /* odd way of giving native framerates from docs */ - int t=(i & 0x7F)>>2; - if(t<16) framerate = (AVRational){1, t+1}; - else framerate = (AVRational){t-15, 1}; - - if(i&1){ - framerate.num *= 1000; - framerate.den *= 1001; - } - - if((i&3)==3) framerate.num *= 24; - else if((i&3)==2) framerate.num *= 25; - else framerate.num *= 30; - } - else - framerate= (AVRational){i, 1}; - - nsv->avsync = get_le16(pb); - nsv->framerate = framerate; -#ifdef DEBUG - print_tag("NSV NSVs vtag", vtag, 0); - print_tag("NSV NSVs atag", atag, 0); - PRINT(("NSV NSVs vsize %dx%d\n", vwidth, vheight)); -#endif - - /* XXX change to ap != NULL ? */ - if (s->nb_streams == 0) { /* streams not yet published, let's do that */ - nsv->vtag = vtag; - nsv->atag = atag; - nsv->vwidth = vwidth; - nsv->vheight = vwidth; - if (vtag != T_NONE) { - int i; - st = av_new_stream(s, NSV_ST_VIDEO); - if (!st) - goto fail; - - nst = av_mallocz(sizeof(NSVStream)); - if (!nst) - goto fail; - st->priv_data = nst; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = vtag; - st->codec->codec_id = ff_codec_get_id(nsv_codec_video_tags, vtag); - st->codec->width = vwidth; - st->codec->height = vheight; - st->codec->bits_per_coded_sample = 24; /* depth XXX */ - - av_set_pts_info(st, 64, framerate.den, framerate.num); - st->start_time = 0; - st->duration = av_rescale(nsv->duration, framerate.num, 1000*framerate.den); - - for(i=0;iindex_entries;i++) { - if(nsv->nsvs_timestamps) { - av_add_index_entry(st, nsv->nsvs_file_offset[i], nsv->nsvs_timestamps[i], - 0, 0, AVINDEX_KEYFRAME); - } else { - int64_t ts = av_rescale(i*nsv->duration/nsv->index_entries, framerate.num, 1000*framerate.den); - av_add_index_entry(st, nsv->nsvs_file_offset[i], ts, 0, 0, AVINDEX_KEYFRAME); - } - } - } - if (atag != T_NONE) { -#ifndef DISABLE_AUDIO - st = av_new_stream(s, NSV_ST_AUDIO); - if (!st) - goto fail; - - nst = av_mallocz(sizeof(NSVStream)); - if (!nst) - goto fail; - st->priv_data = nst; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = atag; - st->codec->codec_id = ff_codec_get_id(nsv_codec_audio_tags, atag); - - st->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */ - - /* set timebase to common denominator of ms and framerate */ - av_set_pts_info(st, 64, 1, framerate.num*1000); - st->start_time = 0; - st->duration = (int64_t)nsv->duration * framerate.num; -#endif - } -#ifdef CHECK_SUBSEQUENT_NSVS - } else { - if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) { - PRINT(("NSV NSVs header values differ from the first one!!!\n")); - //return -1; - } -#endif /* CHECK_SUBSEQUENT_NSVS */ - } - - nsv->state = NSV_HAS_READ_NSVS; - return 0; -fail: - /* XXX */ - nsv->state = NSV_UNSYNC; - return -1; -} - -static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - NSVContext *nsv = s->priv_data; - int i, err; - - PRINT(("%s()\n", __FUNCTION__)); - PRINT(("filename '%s'\n", s->filename)); - - nsv->state = NSV_UNSYNC; - nsv->ahead[0].data = nsv->ahead[1].data = NULL; - - for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) { - if (nsv_resync(s) < 0) - return -1; - if (nsv->state == NSV_FOUND_NSVF) - err = nsv_parse_NSVf_header(s, ap); - /* we need the first NSVs also... */ - if (nsv->state == NSV_FOUND_NSVS) { - err = nsv_parse_NSVs_header(s, ap); - break; /* we just want the first one */ - } - } - if (s->nb_streams < 1) /* no luck so far */ - return -1; - /* now read the first chunk, so we can attempt to decode more info */ - err = nsv_read_chunk(s, 1); - - PRINT(("parsed header\n")); - return 0; -} - -static int nsv_read_chunk(AVFormatContext *s, int fill_header) -{ - NSVContext *nsv = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st[2] = {NULL, NULL}; - NSVStream *nst; - AVPacket *pkt; - int i, err = 0; - uint8_t auxcount; /* number of aux metadata, also 4 bits of vsize */ - uint32_t vsize; - uint16_t asize; - uint16_t auxsize; - uint32_t auxtag; - - PRINT(("%s(%d)\n", __FUNCTION__, fill_header)); - - if (nsv->ahead[0].data || nsv->ahead[1].data) - return 0; //-1; /* hey! eat what you've in your plate first! */ - -null_chunk_retry: - if (url_feof(pb)) - return -1; - - for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++) - err = nsv_resync(s); - if (err < 0) - return err; - if (nsv->state == NSV_FOUND_NSVS) - err = nsv_parse_NSVs_header(s, NULL); - if (err < 0) - return err; - if (nsv->state != NSV_HAS_READ_NSVS && nsv->state != NSV_FOUND_BEEF) - return -1; - - auxcount = get_byte(pb); - vsize = get_le16(pb); - asize = get_le16(pb); - vsize = (vsize << 4) | (auxcount >> 4); - auxcount &= 0x0f; - PRINT(("NSV CHUNK %d aux, %u bytes video, %d bytes audio\n", auxcount, vsize, asize)); - /* skip aux stuff */ - for (i = 0; i < auxcount; i++) { - auxsize = get_le16(pb); - auxtag = get_le32(pb); - PRINT(("NSV aux data: '%c%c%c%c', %d bytes\n", - (auxtag & 0x0ff), - ((auxtag >> 8) & 0x0ff), - ((auxtag >> 16) & 0x0ff), - ((auxtag >> 24) & 0x0ff), - auxsize)); - url_fskip(pb, auxsize); - vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming braindead */ - } - - if (url_feof(pb)) - return -1; - if (!vsize && !asize) { - nsv->state = NSV_UNSYNC; - goto null_chunk_retry; - } - - /* map back streams to v,a */ - if (s->streams[0]) - st[s->streams[0]->id] = s->streams[0]; - if (s->streams[1]) - st[s->streams[1]->id] = s->streams[1]; - - if (vsize/* && st[NSV_ST_VIDEO]*/) { - nst = st[NSV_ST_VIDEO]->priv_data; - pkt = &nsv->ahead[NSV_ST_VIDEO]; - av_get_packet(pb, pkt, vsize); - pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO; - pkt->dts = nst->frame_offset; - pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */ -/* - for (i = 0; i < MIN(8, vsize); i++) - PRINT(("NSV video: [%d] = %02x\n", i, pkt->data[i])); -*/ - } - if(st[NSV_ST_VIDEO]) - ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++; - - if (asize/*st[NSV_ST_AUDIO]*/) { - nst = st[NSV_ST_AUDIO]->priv_data; - pkt = &nsv->ahead[NSV_ST_AUDIO]; - /* read raw audio specific header on the first audio chunk... */ - /* on ALL audio chunks ?? seems so! */ - if (asize && st[NSV_ST_AUDIO]->codec->codec_tag == MKTAG('P', 'C', 'M', ' ')/* && fill_header*/) { - uint8_t bps; - uint8_t channels; - uint16_t samplerate; - bps = get_byte(pb); - channels = get_byte(pb); - samplerate = get_le16(pb); - asize-=4; - PRINT(("NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate)); - if (fill_header) { - st[NSV_ST_AUDIO]->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */ - if (bps != 16) { - PRINT(("NSV AUDIO bit/sample != 16 (%d)!!!\n", bps)); - } - bps /= channels; // ??? - if (bps == 8) - st[NSV_ST_AUDIO]->codec->codec_id = CODEC_ID_PCM_U8; - samplerate /= 4;/* UGH ??? XXX */ - channels = 1; - st[NSV_ST_AUDIO]->codec->channels = channels; - st[NSV_ST_AUDIO]->codec->sample_rate = samplerate; - PRINT(("NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate)); - } - } - av_get_packet(pb, pkt, asize); - pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO; - pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */ - if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) { - /* on a nsvs frame we have new information on a/v sync */ - pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1); - pkt->dts *= (int64_t)1000 * nsv->framerate.den; - pkt->dts += (int64_t)nsv->avsync * nsv->framerate.num; - PRINT(("NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts)); - } - nst->frame_offset++; - } - - nsv->state = NSV_UNSYNC; - return 0; -} - - -static int nsv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - NSVContext *nsv = s->priv_data; - int i, err = 0; - - PRINT(("%s()\n", __FUNCTION__)); - - /* in case we don't already have something to eat ... */ - if (nsv->ahead[0].data == NULL && nsv->ahead[1].data == NULL) - err = nsv_read_chunk(s, 0); - if (err < 0) - return err; - - /* now pick one of the plates */ - for (i = 0; i < 2; i++) { - if (nsv->ahead[i].data) { - PRINT(("%s: using cached packet[%d]\n", __FUNCTION__, i)); - /* avoid the cost of new_packet + memcpy(->data) */ - memcpy(pkt, &nsv->ahead[i], sizeof(AVPacket)); - nsv->ahead[i].data = NULL; /* we ate that one */ - return pkt->size; - } - } - - /* this restaurant is not approvisionned :^] */ - return -1; -} - -static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - NSVContext *nsv = s->priv_data; - AVStream *st = s->streams[stream_index]; - NSVStream *nst = st->priv_data; - int index; - - index = av_index_search_timestamp(st, timestamp, flags); - if(index < 0) - return -1; - - url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET); - nst->frame_offset = st->index_entries[index].timestamp; - nsv->state = NSV_UNSYNC; - return 0; -} - -static int nsv_read_close(AVFormatContext *s) -{ -/* int i; */ - NSVContext *nsv = s->priv_data; - - av_freep(&nsv->nsvs_file_offset); - av_freep(&nsv->nsvs_timestamps); - if (nsv->ahead[0].data) - av_free_packet(&nsv->ahead[0]); - if (nsv->ahead[1].data) - av_free_packet(&nsv->ahead[1]); - -#if 0 - - for(i=0;inb_streams;i++) { - AVStream *st = s->streams[i]; - NSVStream *ast = st->priv_data; - if(ast){ - av_free(ast->index_entries); - av_free(ast); - } - av_free(st->codec->palctrl); - } - -#endif - return 0; -} - -static int nsv_probe(AVProbeData *p) -{ - int i; -// PRINT(("nsv_probe(), buf_size %d\n", p->buf_size)); - /* check file header */ - /* streamed files might not have any header */ - if (p->buf[0] == 'N' && p->buf[1] == 'S' && - p->buf[2] == 'V' && (p->buf[3] == 'f' || p->buf[3] == 's')) - return AVPROBE_SCORE_MAX; - /* XXX: do streamed files always start at chunk boundary ?? */ - /* or do we need to search NSVs in the byte stream ? */ - /* seems the servers don't bother starting clean chunks... */ - /* sometimes even the first header is at 9KB or something :^) */ - for (i = 1; i < p->buf_size - 3; i++) { - if (p->buf[i+0] == 'N' && p->buf[i+1] == 'S' && - p->buf[i+2] == 'V' && p->buf[i+3] == 's') - return AVPROBE_SCORE_MAX-20; - } - /* so we'll have more luck on extension... */ - if (av_match_ext(p->filename, "nsv")) - return AVPROBE_SCORE_MAX/2; - /* FIXME: add mime-type check */ - return 0; -} - -AVInputFormat nsv_demuxer = { - "nsv", - NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"), - sizeof(NSVContext), - nsv_probe, - nsv_read_header, - nsv_read_packet, - nsv_read_close, - nsv_read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/nut.c b/tizen/distrib/ffmpeg/libavformat/nut.c deleted file mode 100644 index 9a6a41b..0000000 --- a/tizen/distrib/ffmpeg/libavformat/nut.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nut - * Copyright (c) 2004-2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/tree.h" -#include "nut.h" - -const AVCodecTag ff_nut_subtitle_tags[] = { - { CODEC_ID_TEXT , MKTAG('U', 'T', 'F', '8') }, - { CODEC_ID_SSA , MKTAG('S', 'S', 'A', 0 ) }, - { CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') }, - { CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') }, - { CODEC_ID_NONE , 0 } -}; - -void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val){ - int i; - for(i=0; iavf->nb_streams; i++){ - nut->stream[i].last_pts= av_rescale_rnd( - val, - time_base.num * (int64_t)nut->stream[i].time_base->den, - time_base.den * (int64_t)nut->stream[i].time_base->num, - AV_ROUND_DOWN); - } -} - -int64_t ff_lsb2full(StreamContext *stream, int64_t lsb){ - int64_t mask = (1<msb_pts_shift)-1; - int64_t delta= stream->last_pts - mask/2; - return ((lsb - delta)&mask) + delta; -} - -int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b){ - return ((a->pos - b->pos) >> 32) - ((b->pos - a->pos) >> 32); -} - -int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b){ - return ((a->ts - b->ts) >> 32) - ((b->ts - a->ts) >> 32); -} - -void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){ - Syncpoint *sp= av_mallocz(sizeof(Syncpoint)); - struct AVTreeNode *node= av_mallocz(av_tree_node_size); - - sp->pos= pos; - sp->back_ptr= back_ptr; - sp->ts= ts; - av_tree_insert(&nut->syncpoints, sp, (void *) ff_nut_sp_pos_cmp, &node); - if(node){ - av_free(sp); - av_free(node); - } -} - -static int enu_free(void *opaque, void *elem) -{ - av_free(elem); - return 0; -} - -void ff_nut_free_sp(NUTContext *nut) -{ - av_tree_enumerate(nut->syncpoints, NULL, NULL, enu_free); - av_tree_destroy(nut->syncpoints); -} - -const Dispositions ff_nut_dispositions[] = { - {"default" , AV_DISPOSITION_DEFAULT}, - {"dub" , AV_DISPOSITION_DUB}, - {"original" , AV_DISPOSITION_ORIGINAL}, - {"comment" , AV_DISPOSITION_COMMENT}, - {"lyrics" , AV_DISPOSITION_LYRICS}, - {"karaoke" , AV_DISPOSITION_KARAOKE}, - {"" , 0} -}; - -const AVMetadataConv ff_nut_metadata_conv[] = { - { "Author", "artist" }, - { "X-CreationTime", "date" }, - { "CreationTime", "date" }, - { "SourceFilename", "filename" }, - { "X-Language", "language" }, - { "X-Disposition", "disposition" }, - { "X-Replaces", "replaces" }, - { "X-Depends", "depends" }, - { "X-Uses", "uses" }, - { "X-UsesFont", "usesfont" }, - { 0 }, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/nut.h b/tizen/distrib/ffmpeg/libavformat/nut.h deleted file mode 100644 index ce052df..0000000 --- a/tizen/distrib/ffmpeg/libavformat/nut.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * "NUT" Container Format (de)muxer - * Copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_NUT_H -#define AVFORMAT_NUT_H - -//#include -//#include "libavutil/adler32.h" -//#include "libavcodec/mpegaudio.h" -#include "avformat.h" -#include "riff.h" -#include "metadata.h" - -#define MAIN_STARTCODE (0x7A561F5F04ADULL + (((uint64_t)('N'<<8) + 'M')<<48)) -#define STREAM_STARTCODE (0x11405BF2F9DBULL + (((uint64_t)('N'<<8) + 'S')<<48)) -#define SYNCPOINT_STARTCODE (0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48)) -#define INDEX_STARTCODE (0xDD672F23E64EULL + (((uint64_t)('N'<<8) + 'X')<<48)) -#define INFO_STARTCODE (0xAB68B596BA78ULL + (((uint64_t)('N'<<8) + 'I')<<48)) - -#define ID_STRING "nut/multimedia container\0" - -#define MAX_DISTANCE (1024*32-1) - -typedef enum{ - FLAG_KEY = 1, /// -#include "libavutil/avstring.h" -#include "libavutil/bswap.h" -#include "libavutil/tree.h" -#include "nut.h" - -#undef NDEBUG -#include - -static int get_str(ByteIOContext *bc, char *string, unsigned int maxlen){ - unsigned int len= ff_get_v(bc); - - if(len && maxlen) - get_buffer(bc, string, FFMIN(len, maxlen)); - while(len > maxlen){ - get_byte(bc); - len--; - } - - if(maxlen) - string[FFMIN(len, maxlen-1)]= 0; - - if(maxlen == len) - return -1; - else - return 0; -} - -static int64_t get_s(ByteIOContext *bc){ - int64_t v = ff_get_v(bc) + 1; - - if (v&1) return -(v>>1); - else return (v>>1); -} - -static uint64_t get_fourcc(ByteIOContext *bc){ - unsigned int len= ff_get_v(bc); - - if (len==2) return get_le16(bc); - else if(len==4) return get_le32(bc); - else return -1; -} - -#ifdef TRACE -static inline uint64_t get_v_trace(ByteIOContext *bc, char *file, char *func, int line){ - uint64_t v= ff_get_v(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - return v; -} - -static inline int64_t get_s_trace(ByteIOContext *bc, char *file, char *func, int line){ - int64_t v= get_s(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - return v; -} - -static inline uint64_t get_vb_trace(ByteIOContext *bc, char *file, char *func, int line){ - uint64_t v= get_vb(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_vb %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - return v; -} -#define ff_get_v(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_vb(bc) get_vb_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif - -static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int calculate_checksum, uint64_t startcode) -{ - int64_t size; -// start= url_ftell(bc) - 8; - - startcode= be2me_64(startcode); - startcode= ff_crc04C11DB7_update(0, &startcode, 8); - - init_checksum(bc, ff_crc04C11DB7_update, startcode); - size= ff_get_v(bc); - if(size > 4096) - get_be32(bc); - if(get_checksum(bc) && size > 4096) - return -1; - - init_checksum(bc, calculate_checksum ? ff_crc04C11DB7_update : NULL, 0); - - return size; -} - -static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){ - uint64_t state=0; - - if(pos >= 0) - url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream is not seekable, but that should not matter, as in this case we simply start where we currently are - - while(!url_feof(bc)){ - state= (state<<8) | get_byte(bc); - if((state>>56) != 'N') - continue; - switch(state){ - case MAIN_STARTCODE: - case STREAM_STARTCODE: - case SYNCPOINT_STARTCODE: - case INFO_STARTCODE: - case INDEX_STARTCODE: - return state; - } - } - - return 0; -} - -/** - * Find the given startcode. - * @param code the startcode - * @param pos the start position of the search, or -1 if the current position - * @return the position of the startcode or -1 if not found - */ -static int64_t find_startcode(ByteIOContext *bc, uint64_t code, int64_t pos){ - for(;;){ - uint64_t startcode= find_any_startcode(bc, pos); - if(startcode == code) - return url_ftell(bc) - 8; - else if(startcode == 0) - return -1; - pos=-1; - } -} - -static int nut_probe(AVProbeData *p){ - int i; - uint64_t code= 0; - - for (i = 0; i < p->buf_size; i++) { - code = (code << 8) | p->buf[i]; - if (code == MAIN_STARTCODE) - return AVPROBE_SCORE_MAX; - } - return 0; -} - -#define GET_V(dst, check) \ - tmp= ff_get_v(bc);\ - if(!(check)){\ - av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp);\ - return -1;\ - }\ - dst= tmp; - -static int skip_reserved(ByteIOContext *bc, int64_t pos){ - pos -= url_ftell(bc); - if(pos<0){ - url_fseek(bc, pos, SEEK_CUR); - return -1; - }else{ - while(pos--) - get_byte(bc); - return 0; - } -} - -static int decode_main_header(NUTContext *nut){ - AVFormatContext *s= nut->avf; - ByteIOContext *bc = s->pb; - uint64_t tmp, end; - unsigned int stream_count; - int i, j, tmp_stream, tmp_mul, tmp_pts, tmp_size, count, tmp_res, tmp_head_idx; - int64_t tmp_match; - - end= get_packetheader(nut, bc, 1, MAIN_STARTCODE); - end += url_ftell(bc); - - GET_V(tmp , tmp >=2 && tmp <= 3) - GET_V(stream_count , tmp > 0 && tmp <=MAX_STREAMS) - - nut->max_distance = ff_get_v(bc); - if(nut->max_distance > 65536){ - av_log(s, AV_LOG_DEBUG, "max_distance %d\n", nut->max_distance); - nut->max_distance= 65536; - } - - GET_V(nut->time_base_count, tmp>0 && tmptime_base= av_malloc(nut->time_base_count * sizeof(AVRational)); - - for(i=0; itime_base_count; i++){ - GET_V(nut->time_base[i].num, tmp>0 && tmp<(1ULL<<31)) - GET_V(nut->time_base[i].den, tmp>0 && tmp<(1ULL<<31)) - if(av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1){ - av_log(s, AV_LOG_ERROR, "time base invalid\n"); - return -1; - } - } - tmp_pts=0; - tmp_mul=1; - tmp_stream=0; - tmp_match= 1-(1LL<<62); - tmp_head_idx= 0; - for(i=0; i<256;){ - int tmp_flags = ff_get_v(bc); - int tmp_fields= ff_get_v(bc); - if(tmp_fields>0) tmp_pts = get_s(bc); - if(tmp_fields>1) tmp_mul = ff_get_v(bc); - if(tmp_fields>2) tmp_stream= ff_get_v(bc); - if(tmp_fields>3) tmp_size = ff_get_v(bc); - else tmp_size = 0; - if(tmp_fields>4) tmp_res = ff_get_v(bc); - else tmp_res = 0; - if(tmp_fields>5) count = ff_get_v(bc); - else count = tmp_mul - tmp_size; - if(tmp_fields>6) tmp_match = get_s(bc); - if(tmp_fields>7) tmp_head_idx= ff_get_v(bc); - - while(tmp_fields-- > 8) - ff_get_v(bc); - - if(count == 0 || i+count > 256){ - av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i); - return -1; - } - if(tmp_stream >= stream_count){ - av_log(s, AV_LOG_ERROR, "illegal stream number\n"); - return -1; - } - - for(j=0; jframe_code[i].flags= FLAG_INVALID; - j--; - continue; - } - nut->frame_code[i].flags = tmp_flags ; - nut->frame_code[i].pts_delta = tmp_pts ; - nut->frame_code[i].stream_id = tmp_stream; - nut->frame_code[i].size_mul = tmp_mul ; - nut->frame_code[i].size_lsb = tmp_size+j; - nut->frame_code[i].reserved_count = tmp_res ; - nut->frame_code[i].header_idx = tmp_head_idx; - } - } - assert(nut->frame_code['N'].flags == FLAG_INVALID); - - if(end > url_ftell(bc) + 4){ - int rem= 1024; - GET_V(nut->header_count, tmp<128U) - nut->header_count++; - for(i=1; iheader_count; i++){ - GET_V(nut->header_len[i], tmp>0 && tmp<256); - rem -= nut->header_len[i]; - if(rem < 0){ - av_log(s, AV_LOG_ERROR, "invalid elision header\n"); - return -1; - } - nut->header[i]= av_malloc(nut->header_len[i]); - get_buffer(bc, nut->header[i], nut->header_len[i]); - } - assert(nut->header_len[0]==0); - } - - if(skip_reserved(bc, end) || get_checksum(bc)){ - av_log(s, AV_LOG_ERROR, "main header checksum mismatch\n"); - return -1; - } - - nut->stream = av_mallocz(sizeof(StreamContext)*stream_count); - for(i=0; iavf; - ByteIOContext *bc = s->pb; - StreamContext *stc; - int class, stream_id; - uint64_t tmp, end; - AVStream *st; - - end= get_packetheader(nut, bc, 1, STREAM_STARTCODE); - end += url_ftell(bc); - - GET_V(stream_id, tmp < s->nb_streams && !nut->stream[tmp].time_base); - stc= &nut->stream[stream_id]; - - st = s->streams[stream_id]; - if (!st) - return AVERROR(ENOMEM); - - class = ff_get_v(bc); - tmp = get_fourcc(bc); - st->codec->codec_tag= tmp; - switch(class) - { - case 0: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tmp); - break; - case 1: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, tmp); - break; - case 2: - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = ff_codec_get_id(ff_nut_subtitle_tags, tmp); - break; - case 3: - st->codec->codec_type = AVMEDIA_TYPE_DATA; - break; - default: - av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class); - return -1; - } - if(class<3 && st->codec->codec_id == CODEC_ID_NONE) - av_log(s, AV_LOG_ERROR, "Unknown codec tag '0x%04x' for stream number %d\n", - (unsigned int)tmp, stream_id); - - GET_V(stc->time_base_id , tmp < nut->time_base_count); - GET_V(stc->msb_pts_shift , tmp < 16); - stc->max_pts_distance= ff_get_v(bc); - GET_V(stc->decode_delay , tmp < 1000); //sanity limit, raise this if Moore's law is true - st->codec->has_b_frames= stc->decode_delay; - ff_get_v(bc); //stream flags - - GET_V(st->codec->extradata_size, tmp < (1<<30)); - if(st->codec->extradata_size){ - st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - get_buffer(bc, st->codec->extradata, st->codec->extradata_size); - } - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - GET_V(st->codec->width , tmp > 0) - GET_V(st->codec->height, tmp > 0) - st->sample_aspect_ratio.num= ff_get_v(bc); - st->sample_aspect_ratio.den= ff_get_v(bc); - if((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)){ - av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n", st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); - return -1; - } - ff_get_v(bc); /* csp type */ - }else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO){ - GET_V(st->codec->sample_rate , tmp > 0) - ff_get_v(bc); // samplerate_den - GET_V(st->codec->channels, tmp > 0) - } - if(skip_reserved(bc, end) || get_checksum(bc)){ - av_log(s, AV_LOG_ERROR, "stream header %d checksum mismatch\n", stream_id); - return -1; - } - stc->time_base= &nut->time_base[stc->time_base_id]; - av_set_pts_info(s->streams[stream_id], 63, stc->time_base->num, stc->time_base->den); - return 0; -} - -static void set_disposition_bits(AVFormatContext* avf, char* value, int stream_id){ - int flag = 0, i; - for (i=0; ff_nut_dispositions[i].flag; ++i) { - if (!strcmp(ff_nut_dispositions[i].str, value)) - flag = ff_nut_dispositions[i].flag; - } - if (!flag) - av_log(avf, AV_LOG_INFO, "unknown disposition type '%s'\n", value); - for (i = 0; i < avf->nb_streams; ++i) - if (stream_id == i || stream_id == -1) - avf->streams[i]->disposition |= flag; -} - -static int decode_info_header(NUTContext *nut){ - AVFormatContext *s= nut->avf; - ByteIOContext *bc = s->pb; - uint64_t tmp, chapter_start, chapter_len; - unsigned int stream_id_plus1, count; - int chapter_id, i; - int64_t value, end; - char name[256], str_value[1024], type_str[256]; - const char *type; - AVChapter *chapter= NULL; - AVStream *st= NULL; - - end= get_packetheader(nut, bc, 1, INFO_STARTCODE); - end += url_ftell(bc); - - GET_V(stream_id_plus1, tmp <= s->nb_streams) - chapter_id = get_s(bc); - chapter_start= ff_get_v(bc); - chapter_len = ff_get_v(bc); - count = ff_get_v(bc); - - if(chapter_id && !stream_id_plus1){ - int64_t start= chapter_start / nut->time_base_count; - chapter= ff_new_chapter(s, chapter_id, - nut->time_base[chapter_start % nut->time_base_count], - start, start + chapter_len, NULL); - } else if(stream_id_plus1) - st= s->streams[stream_id_plus1 - 1]; - - for(i=0; i s->nb_streams) { - av_log(s, AV_LOG_ERROR, "invalid stream id for info packet\n"); - continue; - } - - if(!strcmp(type, "UTF-8")){ - AVMetadata **metadata = NULL; - if(chapter_id==0 && !strcmp(name, "Disposition")) - set_disposition_bits(s, str_value, stream_id_plus1 - 1); - else if(chapter) metadata= &chapter->metadata; - else if(stream_id_plus1) metadata= &st->metadata; - else metadata= &s->metadata; - if(metadata && strcasecmp(name,"Uses") - && strcasecmp(name,"Depends") && strcasecmp(name,"Replaces")) - av_metadata_set2(metadata, name, str_value, 0); - } - } - - if(skip_reserved(bc, end) || get_checksum(bc)){ - av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n"); - return -1; - } - return 0; -} - -static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr){ - AVFormatContext *s= nut->avf; - ByteIOContext *bc = s->pb; - int64_t end, tmp; - - nut->last_syncpoint_pos= url_ftell(bc)-8; - - end= get_packetheader(nut, bc, 1, SYNCPOINT_STARTCODE); - end += url_ftell(bc); - - tmp= ff_get_v(bc); - *back_ptr= nut->last_syncpoint_pos - 16*ff_get_v(bc); - if(*back_ptr < 0) - return -1; - - ff_nut_reset_ts(nut, nut->time_base[tmp % nut->time_base_count], tmp / nut->time_base_count); - - if(skip_reserved(bc, end) || get_checksum(bc)){ - av_log(s, AV_LOG_ERROR, "sync point checksum mismatch\n"); - return -1; - } - - *ts= tmp / s->nb_streams * av_q2d(nut->time_base[tmp % s->nb_streams])*AV_TIME_BASE; - ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts); - - return 0; -} - -static int find_and_decode_index(NUTContext *nut){ - AVFormatContext *s= nut->avf; - ByteIOContext *bc = s->pb; - uint64_t tmp, end; - int i, j, syncpoint_count; - int64_t filesize= url_fsize(bc); - int64_t *syncpoints; - int8_t *has_keyframe; - int ret= -1; - - url_fseek(bc, filesize-12, SEEK_SET); - url_fseek(bc, filesize-get_be64(bc), SEEK_SET); - if(get_be64(bc) != INDEX_STARTCODE){ - av_log(s, AV_LOG_ERROR, "no index at the end\n"); - return -1; - } - - end= get_packetheader(nut, bc, 1, INDEX_STARTCODE); - end += url_ftell(bc); - - ff_get_v(bc); //max_pts - GET_V(syncpoint_count, tmp < INT_MAX/8 && tmp > 0) - syncpoints= av_malloc(sizeof(int64_t)*syncpoint_count); - has_keyframe= av_malloc(sizeof(int8_t)*(syncpoint_count+1)); - for(i=0; inb_streams; i++){ - int64_t last_pts= -1; - for(j=0; j>=1; - if(type){ - int flag= x&1; - x>>=1; - if(n+x >= syncpoint_count + 1){ - av_log(s, AV_LOG_ERROR, "index overflow A\n"); - goto fail; - } - while(x--) - has_keyframe[n++]= flag; - has_keyframe[n++]= !flag; - }else{ - while(x != 1){ - if(n>=syncpoint_count + 1){ - av_log(s, AV_LOG_ERROR, "index overflow B\n"); - goto fail; - } - has_keyframe[n++]= x&1; - x>>=1; - } - } - if(has_keyframe[0]){ - av_log(s, AV_LOG_ERROR, "keyframe before first syncpoint in index\n"); - goto fail; - } - assert(n<=syncpoint_count+1); - for(; jstreams[i], - 16*syncpoints[j-1], - last_pts + A, - 0, - 0, - AVINDEX_KEYFRAME); - last_pts += A + B; - } - } - } - } - - if(skip_reserved(bc, end) || get_checksum(bc)){ - av_log(s, AV_LOG_ERROR, "index checksum mismatch\n"); - goto fail; - } - ret= 0; -fail: - av_free(syncpoints); - av_free(has_keyframe); - return ret; -} - -static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - NUTContext *nut = s->priv_data; - ByteIOContext *bc = s->pb; - int64_t pos; - int initialized_stream_count; - - nut->avf= s; - - /* main header */ - pos=0; - do{ - pos= find_startcode(bc, MAIN_STARTCODE, pos)+1; - if (pos<0+1){ - av_log(s, AV_LOG_ERROR, "No main startcode found.\n"); - return -1; - } - }while(decode_main_header(nut) < 0); - - /* stream headers */ - pos=0; - for(initialized_stream_count=0; initialized_stream_count < s->nb_streams;){ - pos= find_startcode(bc, STREAM_STARTCODE, pos)+1; - if (pos<0+1){ - av_log(s, AV_LOG_ERROR, "Not all stream headers found.\n"); - return -1; - } - if(decode_stream_header(nut) >= 0) - initialized_stream_count++; - } - - /* info headers */ - pos=0; - for(;;){ - uint64_t startcode= find_any_startcode(bc, pos); - pos= url_ftell(bc); - - if(startcode==0){ - av_log(s, AV_LOG_ERROR, "EOF before video frames\n"); - return -1; - }else if(startcode == SYNCPOINT_STARTCODE){ - nut->next_startcode= startcode; - break; - }else if(startcode != INFO_STARTCODE){ - continue; - } - - decode_info_header(nut); - } - - s->data_offset= pos-8; - - if(!url_is_streamed(bc)){ - int64_t orig_pos= url_ftell(bc); - find_and_decode_index(nut); - url_fseek(bc, orig_pos, SEEK_SET); - } - assert(nut->next_startcode == SYNCPOINT_STARTCODE); - - return 0; -} - -static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id, uint8_t *header_idx, int frame_code){ - AVFormatContext *s= nut->avf; - ByteIOContext *bc = s->pb; - StreamContext *stc; - int size, flags, size_mul, pts_delta, i, reserved_count; - uint64_t tmp; - - if(url_ftell(bc) > nut->last_syncpoint_pos + nut->max_distance){ - av_log(s, AV_LOG_ERROR, "Last frame must have been damaged %"PRId64" > %"PRId64" + %d\n", url_ftell(bc), nut->last_syncpoint_pos, nut->max_distance); - return -1; - } - - flags = nut->frame_code[frame_code].flags; - size_mul = nut->frame_code[frame_code].size_mul; - size = nut->frame_code[frame_code].size_lsb; - *stream_id = nut->frame_code[frame_code].stream_id; - pts_delta = nut->frame_code[frame_code].pts_delta; - reserved_count = nut->frame_code[frame_code].reserved_count; - *header_idx = nut->frame_code[frame_code].header_idx; - - if(flags & FLAG_INVALID) - return -1; - if(flags & FLAG_CODED) - flags ^= ff_get_v(bc); - if(flags & FLAG_STREAM_ID){ - GET_V(*stream_id, tmp < s->nb_streams) - } - stc= &nut->stream[*stream_id]; - if(flags&FLAG_CODED_PTS){ - int coded_pts= ff_get_v(bc); -//FIXME check last_pts validity? - if(coded_pts < (1<msb_pts_shift)){ - *pts=ff_lsb2full(stc, coded_pts); - }else - *pts=coded_pts - (1<msb_pts_shift); - }else - *pts= stc->last_pts + pts_delta; - if(flags&FLAG_SIZE_MSB){ - size += size_mul*ff_get_v(bc); - } - if(flags&FLAG_MATCH_TIME) - get_s(bc); - if(flags&FLAG_HEADER_IDX) - *header_idx= ff_get_v(bc); - if(flags&FLAG_RESERVED) - reserved_count= ff_get_v(bc); - for(i=0; i= (unsigned)nut->header_count){ - av_log(s, AV_LOG_ERROR, "header_idx invalid\n"); - return -1; - } - if(size > 4096) - *header_idx=0; - size -= nut->header_len[*header_idx]; - - if(flags&FLAG_CHECKSUM){ - get_be32(bc); //FIXME check this - }else if(size > 2*nut->max_distance || FFABS(stc->last_pts - *pts) > stc->max_pts_distance){ - av_log(s, AV_LOG_ERROR, "frame size > 2max_distance and no checksum\n"); - return -1; - } - - stc->last_pts= *pts; - stc->last_flags= flags; - - return size; -} - -static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code){ - AVFormatContext *s= nut->avf; - ByteIOContext *bc = s->pb; - int size, stream_id, discard; - int64_t pts, last_IP_pts; - StreamContext *stc; - uint8_t header_idx; - - size= decode_frame_header(nut, &pts, &stream_id, &header_idx, frame_code); - if(size < 0) - return -1; - - stc= &nut->stream[stream_id]; - - if (stc->last_flags & FLAG_KEY) - stc->skip_until_key_frame=0; - - discard= s->streams[ stream_id ]->discard; - last_IP_pts= s->streams[ stream_id ]->last_IP_pts; - if( (discard >= AVDISCARD_NONKEY && !(stc->last_flags & FLAG_KEY)) - ||(discard >= AVDISCARD_BIDIR && last_IP_pts != AV_NOPTS_VALUE && last_IP_pts > pts) - || discard >= AVDISCARD_ALL - || stc->skip_until_key_frame){ - url_fskip(bc, size); - return 1; - } - - av_new_packet(pkt, size + nut->header_len[header_idx]); - memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]); - pkt->pos= url_ftell(bc); //FIXME - get_buffer(bc, pkt->data + nut->header_len[header_idx], size); - - pkt->stream_index = stream_id; - if (stc->last_flags & FLAG_KEY) - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pts = pts; - - return 0; -} - -static int nut_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - NUTContext *nut = s->priv_data; - ByteIOContext *bc = s->pb; - int i, frame_code=0, ret, skip; - int64_t ts, back_ptr; - - for(;;){ - int64_t pos= url_ftell(bc); - uint64_t tmp= nut->next_startcode; - nut->next_startcode=0; - - if(tmp){ - pos-=8; - }else{ - frame_code = get_byte(bc); - if(url_feof(bc)) - return -1; - if(frame_code == 'N'){ - tmp= frame_code; - for(i=1; i<8; i++) - tmp = (tmp<<8) + get_byte(bc); - } - } - switch(tmp){ - case MAIN_STARTCODE: - case STREAM_STARTCODE: - case INDEX_STARTCODE: - skip= get_packetheader(nut, bc, 0, tmp); - url_fseek(bc, skip, SEEK_CUR); - break; - case INFO_STARTCODE: - if(decode_info_header(nut)<0) - goto resync; - break; - case SYNCPOINT_STARTCODE: - if(decode_syncpoint(nut, &ts, &back_ptr)<0) - goto resync; - frame_code = get_byte(bc); - case 0: - ret= decode_frame(nut, pkt, frame_code); - if(ret==0) - return 0; - else if(ret==1) //ok but discard packet - break; - default: -resync: -av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", pos); - tmp= find_any_startcode(bc, nut->last_syncpoint_pos+1); - if(tmp==0) - return -1; -av_log(s, AV_LOG_DEBUG, "sync\n"); - nut->next_startcode= tmp; - } - } -} - -static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit){ - NUTContext *nut = s->priv_data; - ByteIOContext *bc = s->pb; - int64_t pos, pts, back_ptr; -av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%"PRId64",%"PRId64")\n", stream_index, *pos_arg, pos_limit); - - pos= *pos_arg; - do{ - pos= find_startcode(bc, SYNCPOINT_STARTCODE, pos)+1; - if(pos < 1){ - assert(nut->next_startcode == 0); - av_log(s, AV_LOG_ERROR, "read_timestamp failed.\n"); - return AV_NOPTS_VALUE; - } - }while(decode_syncpoint(nut, &pts, &back_ptr) < 0); - *pos_arg = pos-1; - assert(nut->last_syncpoint_pos == *pos_arg); - - av_log(s, AV_LOG_DEBUG, "return %"PRId64" %"PRId64"\n", pts,back_ptr ); - if (stream_index == -1) return pts; - else if(stream_index == -2) return back_ptr; - -assert(0); -} - -static int read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags){ - NUTContext *nut = s->priv_data; - AVStream *st= s->streams[stream_index]; - Syncpoint dummy={.ts= pts*av_q2d(st->time_base)*AV_TIME_BASE}; - Syncpoint nopts_sp= {.ts= AV_NOPTS_VALUE, .back_ptr= AV_NOPTS_VALUE}; - Syncpoint *sp, *next_node[2]= {&nopts_sp, &nopts_sp}; - int64_t pos, pos2, ts; - int i; - - if(st->index_entries){ - int index= av_index_search_timestamp(st, pts, flags); - if(index<0) - return -1; - - pos2= st->index_entries[index].pos; - ts = st->index_entries[index].timestamp; - }else{ - av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pts_cmp, - (void **) next_node); - av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n", next_node[0]->pos, next_node[1]->pos, - next_node[0]->ts , next_node[1]->ts); - pos= av_gen_search(s, -1, dummy.ts, next_node[0]->pos, next_node[1]->pos, next_node[1]->pos, - next_node[0]->ts , next_node[1]->ts, AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp); - - if(!(flags & AVSEEK_FLAG_BACKWARD)){ - dummy.pos= pos+16; - next_node[1]= &nopts_sp; - av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, - (void **) next_node); - pos2= av_gen_search(s, -2, dummy.pos, next_node[0]->pos , next_node[1]->pos, next_node[1]->pos, - next_node[0]->back_ptr, next_node[1]->back_ptr, flags, &ts, nut_read_timestamp); - if(pos2>=0) - pos= pos2; - //FIXME dir but I think it does not matter - } - dummy.pos= pos; - sp= av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, - NULL); - - assert(sp); - pos2= sp->back_ptr - 15; - } - av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos2); - pos= find_startcode(s->pb, SYNCPOINT_STARTCODE, pos2); - url_fseek(s->pb, pos, SEEK_SET); - av_log(NULL, AV_LOG_DEBUG, "SP: %"PRId64"\n", pos); - if(pos2 > pos || pos2 + 15 < pos){ - av_log(NULL, AV_LOG_ERROR, "no syncpoint at backptr pos\n"); - } - for(i=0; inb_streams; i++) - nut->stream[i].skip_until_key_frame=1; - - return 0; -} - -static int nut_read_close(AVFormatContext *s) -{ - NUTContext *nut = s->priv_data; - int i; - - av_freep(&nut->time_base); - av_freep(&nut->stream); - ff_nut_free_sp(nut); - for(i = 1; i < nut->header_count; i++) - av_freep(&nut->header[i]); - - return 0; -} - -#if CONFIG_NUT_DEMUXER -AVInputFormat nut_demuxer = { - "nut", - NULL_IF_CONFIG_SMALL("NUT format"), - sizeof(NUTContext), - nut_probe, - nut_read_header, - nut_read_packet, - nut_read_close, - read_seek, - .extensions = "nut", - .metadata_conv = ff_nut_metadata_conv, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/nutenc.c b/tizen/distrib/ffmpeg/libavformat/nutenc.c deleted file mode 100644 index dfda3ca..0000000 --- a/tizen/distrib/ffmpeg/libavformat/nutenc.c +++ /dev/null @@ -1,828 +0,0 @@ -/* - * nut muxer - * Copyright (c) 2004-2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/tree.h" -#include "libavcodec/mpegaudiodata.h" -#include "nut.h" - -static int find_expected_header(AVCodecContext *c, int size, int key_frame, uint8_t out[64]){ - int sample_rate= c->sample_rate; - - if(size>4096) - return 0; - - AV_WB24(out, 1); - - if(c->codec_id == CODEC_ID_MPEG4){ - if(key_frame){ - return 3; - }else{ - out[3]= 0xB6; - return 4; - } - }else if(c->codec_id == CODEC_ID_MPEG1VIDEO || c->codec_id == CODEC_ID_MPEG2VIDEO){ - return 3; - }else if(c->codec_id == CODEC_ID_H264){ - return 3; - }else if(c->codec_id == CODEC_ID_MP3 || c->codec_id == CODEC_ID_MP2){ - int lsf, mpeg25, sample_rate_index, bitrate_index, frame_size; - int layer= c->codec_id == CODEC_ID_MP3 ? 3 : 2; - unsigned int header= 0xFFF00000; - - lsf = sample_rate < (24000+32000)/2; - mpeg25 = sample_rate < (12000+16000)/2; - sample_rate <<= lsf + mpeg25; - if (sample_rate < (32000 + 44100)/2) sample_rate_index=2; - else if(sample_rate < (44100 + 48000)/2) sample_rate_index=0; - else sample_rate_index=1; - - sample_rate= ff_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); - - for(bitrate_index=2; bitrate_index<30; bitrate_index++){ - frame_size = ff_mpa_bitrate_tab[lsf][layer-1][bitrate_index>>1]; - frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); - - if(frame_size == size) - break; - } - - header |= (!lsf)<<19; - header |= (4-layer)<<17; - header |= 1<<16; //no crc - AV_WB32(out, header); - if(size <= 0) - return 2; //we guess there is no crc, if there is one the user clearly does not care about overhead - if(bitrate_index == 30) - return -1; //something is wrong ... - - header |= (bitrate_index>>1)<<12; - header |= sample_rate_index<<10; - header |= (bitrate_index&1)<<9; - - return 2; //FIXME actually put the needed ones in build_elision_headers() - return 3; //we guess that the private bit is not set -//FIXME the above assumptions should be checked, if these turn out false too often something should be done - } - return 0; -} - -static int find_header_idx(AVFormatContext *s, AVCodecContext *c, int size, int frame_type){ - NUTContext *nut = s->priv_data; - uint8_t out[64]; - int i; - int len= find_expected_header(c, size, frame_type, out); - -//av_log(NULL, AV_LOG_ERROR, "expected_h len=%d size=%d codec_id=%d\n", len, size, c->codec_id); - - for(i=1; iheader_count; i++){ - if( len == nut->header_len[i] - && !memcmp(out, nut->header[i], len)){ -// av_log(NULL, AV_LOG_ERROR, "found %d\n", i); - return i; - } - } -// av_log(NULL, AV_LOG_ERROR, "nothing found\n"); - return 0; -} - -static void build_elision_headers(AVFormatContext *s){ - NUTContext *nut = s->priv_data; - int i; - //FIXME this is lame - //FIXME write a 2pass mode to find the maximal headers - static const uint8_t headers[][5]={ - {3, 0x00, 0x00, 0x01}, - {4, 0x00, 0x00, 0x01, 0xB6}, - {2, 0xFF, 0xFA}, //mp3+crc - {2, 0xFF, 0xFB}, //mp3 - {2, 0xFF, 0xFC}, //mp2+crc - {2, 0xFF, 0xFD}, //mp2 - }; - - nut->header_count= 7; - for(i=1; iheader_count; i++){ - nut->header_len[i]= headers[i-1][0]; - nut->header [i]= &headers[i-1][1]; - } -} - -static void build_frame_code(AVFormatContext *s){ - NUTContext *nut = s->priv_data; - int key_frame, index, pred, stream_id; - int start=1; - int end= 254; - int keyframe_0_esc= s->nb_streams > 2; - int pred_table[10]; - FrameCode *ft; - - ft= &nut->frame_code[start]; - ft->flags= FLAG_CODED; - ft->size_mul=1; - ft->pts_delta=1; - start++; - - if(keyframe_0_esc){ - /* keyframe = 0 escape */ - FrameCode *ft= &nut->frame_code[start]; - ft->flags= FLAG_STREAM_ID | FLAG_SIZE_MSB | FLAG_CODED_PTS; - ft->size_mul=1; - start++; - } - - for(stream_id= 0; stream_idnb_streams; stream_id++){ - int start2= start + (end-start)*stream_id / s->nb_streams; - int end2 = start + (end-start)*(stream_id+1) / s->nb_streams; - AVCodecContext *codec = s->streams[stream_id]->codec; - int is_audio= codec->codec_type == AVMEDIA_TYPE_AUDIO; - int intra_only= /*codec->intra_only || */is_audio; - int pred_count; - - for(key_frame=0; key_frame<2; key_frame++){ - if(intra_only && keyframe_0_esc && key_frame==0) - continue; - - { - FrameCode *ft= &nut->frame_code[start2]; - ft->flags= FLAG_KEY*key_frame; - ft->flags|= FLAG_SIZE_MSB | FLAG_CODED_PTS; - ft->stream_id= stream_id; - ft->size_mul=1; - if(is_audio) - ft->header_idx= find_header_idx(s, codec, -1, key_frame); - start2++; - } - } - - key_frame= intra_only; -#if 1 - if(is_audio){ - int frame_bytes= codec->frame_size*(int64_t)codec->bit_rate / (8*codec->sample_rate); - int pts; - for(pts=0; pts<2; pts++){ - for(pred=0; pred<2; pred++){ - FrameCode *ft= &nut->frame_code[start2]; - ft->flags= FLAG_KEY*key_frame; - ft->stream_id= stream_id; - ft->size_mul=frame_bytes + 2; - ft->size_lsb=frame_bytes + pred; - ft->pts_delta=pts; - ft->header_idx= find_header_idx(s, codec, frame_bytes + pred, key_frame); - start2++; - } - } - }else{ - FrameCode *ft= &nut->frame_code[start2]; - ft->flags= FLAG_KEY | FLAG_SIZE_MSB; - ft->stream_id= stream_id; - ft->size_mul=1; - ft->pts_delta=1; - start2++; - } -#endif - - if(codec->has_b_frames){ - pred_count=5; - pred_table[0]=-2; - pred_table[1]=-1; - pred_table[2]=1; - pred_table[3]=3; - pred_table[4]=4; - }else if(codec->codec_id == CODEC_ID_VORBIS){ - pred_count=3; - pred_table[0]=2; - pred_table[1]=9; - pred_table[2]=16; - }else{ - pred_count=1; - pred_table[0]=1; - } - - for(pred=0; predframe_code[index]; - ft->flags= FLAG_KEY*key_frame; - ft->flags|= FLAG_SIZE_MSB; - ft->stream_id= stream_id; -//FIXME use single byte size and pred from last - ft->size_mul= end3-start3; - ft->size_lsb= index - start3; - ft->pts_delta= pred_table[pred]; - if(is_audio) - ft->header_idx= find_header_idx(s, codec, -1, key_frame); - } - } - } - memmove(&nut->frame_code['N'+1], &nut->frame_code['N'], sizeof(FrameCode)*(255-'N')); - nut->frame_code[ 0].flags= - nut->frame_code[255].flags= - nut->frame_code['N'].flags= FLAG_INVALID; -} - -/** - * Gets the length in bytes which is needed to store val as v. - */ -static int get_length(uint64_t val){ - int i=1; - - while(val>>=7) - i++; - - return i; -} - -static void put_v(ByteIOContext *bc, uint64_t val){ - int i= get_length(val); - - while(--i>0) - put_byte(bc, 128 | (val>>(7*i))); - - put_byte(bc, val&127); -} - -static void put_tt(NUTContext *nut, StreamContext *nus, ByteIOContext *bc, uint64_t val){ - val *= nut->time_base_count; - val += nus->time_base - nut->time_base; - put_v(bc, val); -} - -/** - * Stores a string as vb. - */ -static void put_str(ByteIOContext *bc, const char *string){ - int len= strlen(string); - - put_v(bc, len); - put_buffer(bc, string, len); -} - -static void put_s(ByteIOContext *bc, int64_t val){ - put_v(bc, 2*FFABS(val) - (val>0)); -} - -#ifdef TRACE -static inline void put_v_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){ - av_log(NULL, AV_LOG_DEBUG, "put_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - - put_v(bc, v); -} - -static inline void put_s_trace(ByteIOContext *bc, int64_t v, char *file, char *func, int line){ - av_log(NULL, AV_LOG_DEBUG, "put_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - - put_s(bc, v); -} -#define put_v(bc, v) put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif - -//FIXME remove calculate_checksum -static void put_packet(NUTContext *nut, ByteIOContext *bc, ByteIOContext *dyn_bc, int calculate_checksum, uint64_t startcode){ - uint8_t *dyn_buf=NULL; - int dyn_size= url_close_dyn_buf(dyn_bc, &dyn_buf); - int forw_ptr= dyn_size + 4*calculate_checksum; - - if(forw_ptr > 4096) - init_checksum(bc, ff_crc04C11DB7_update, 0); - put_be64(bc, startcode); - put_v(bc, forw_ptr); - if(forw_ptr > 4096) - put_le32(bc, get_checksum(bc)); - - if(calculate_checksum) - init_checksum(bc, ff_crc04C11DB7_update, 0); - put_buffer(bc, dyn_buf, dyn_size); - if(calculate_checksum) - put_le32(bc, get_checksum(bc)); - - av_free(dyn_buf); -} - -static void write_mainheader(NUTContext *nut, ByteIOContext *bc){ - int i, j, tmp_pts, tmp_flags, tmp_stream, tmp_mul, tmp_size, tmp_fields, tmp_head_idx; - int64_t tmp_match; - - put_v(bc, 3); /* version */ - put_v(bc, nut->avf->nb_streams); - put_v(bc, nut->max_distance); - put_v(bc, nut->time_base_count); - - for(i=0; itime_base_count; i++){ - put_v(bc, nut->time_base[i].num); - put_v(bc, nut->time_base[i].den); - } - - tmp_pts=0; - tmp_mul=1; - tmp_stream=0; - tmp_match= 1-(1LL<<62); - tmp_head_idx= 0; - for(i=0; i<256;){ - tmp_fields=0; - tmp_size=0; -// tmp_res=0; - if(tmp_pts != nut->frame_code[i].pts_delta) tmp_fields=1; - if(tmp_mul != nut->frame_code[i].size_mul ) tmp_fields=2; - if(tmp_stream != nut->frame_code[i].stream_id) tmp_fields=3; - if(tmp_size != nut->frame_code[i].size_lsb ) tmp_fields=4; -// if(tmp_res != nut->frame_code[i].res ) tmp_fields=5; - if(tmp_head_idx!=nut->frame_code[i].header_idx)tmp_fields=8; - - tmp_pts = nut->frame_code[i].pts_delta; - tmp_flags = nut->frame_code[i].flags; - tmp_stream= nut->frame_code[i].stream_id; - tmp_mul = nut->frame_code[i].size_mul; - tmp_size = nut->frame_code[i].size_lsb; -// tmp_res = nut->frame_code[i].res; - tmp_head_idx= nut->frame_code[i].header_idx; - - for(j=0; i<256; j++,i++){ - if(i == 'N'){ - j--; - continue; - } - if(nut->frame_code[i].pts_delta != tmp_pts ) break; - if(nut->frame_code[i].flags != tmp_flags ) break; - if(nut->frame_code[i].stream_id != tmp_stream) break; - if(nut->frame_code[i].size_mul != tmp_mul ) break; - if(nut->frame_code[i].size_lsb != tmp_size+j) break; -// if(nut->frame_code[i].res != tmp_res ) break; - if(nut->frame_code[i].header_idx!= tmp_head_idx) break; - } - if(j != tmp_mul - tmp_size) tmp_fields=6; - - put_v(bc, tmp_flags); - put_v(bc, tmp_fields); - if(tmp_fields>0) put_s(bc, tmp_pts); - if(tmp_fields>1) put_v(bc, tmp_mul); - if(tmp_fields>2) put_v(bc, tmp_stream); - if(tmp_fields>3) put_v(bc, tmp_size); - if(tmp_fields>4) put_v(bc, 0 /*tmp_res*/); - if(tmp_fields>5) put_v(bc, j); - if(tmp_fields>6) put_v(bc, tmp_match); - if(tmp_fields>7) put_v(bc, tmp_head_idx); - } - put_v(bc, nut->header_count-1); - for(i=1; iheader_count; i++){ - put_v(bc, nut->header_len[i]); - put_buffer(bc, nut->header[i], nut->header_len[i]); - } -} - -static int write_streamheader(NUTContext *nut, ByteIOContext *bc, AVStream *st, int i){ - AVCodecContext *codec = st->codec; - put_v(bc, i); - switch(codec->codec_type){ - case AVMEDIA_TYPE_VIDEO: put_v(bc, 0); break; - case AVMEDIA_TYPE_AUDIO: put_v(bc, 1); break; - case AVMEDIA_TYPE_SUBTITLE: put_v(bc, 2); break; - default : put_v(bc, 3); break; - } - put_v(bc, 4); - if (codec->codec_tag){ - put_le32(bc, codec->codec_tag); - }else - return -1; - - put_v(bc, nut->stream[i].time_base - nut->time_base); - put_v(bc, nut->stream[i].msb_pts_shift); - put_v(bc, nut->stream[i].max_pts_distance); - put_v(bc, codec->has_b_frames); - put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */ - - put_v(bc, codec->extradata_size); - put_buffer(bc, codec->extradata, codec->extradata_size); - - switch(codec->codec_type){ - case AVMEDIA_TYPE_AUDIO: - put_v(bc, codec->sample_rate); - put_v(bc, 1); - put_v(bc, codec->channels); - break; - case AVMEDIA_TYPE_VIDEO: - put_v(bc, codec->width); - put_v(bc, codec->height); - - if(st->sample_aspect_ratio.num<=0 || st->sample_aspect_ratio.den<=0){ - put_v(bc, 0); - put_v(bc, 0); - }else{ - put_v(bc, st->sample_aspect_ratio.num); - put_v(bc, st->sample_aspect_ratio.den); - } - put_v(bc, 0); /* csp type -- unknown */ - break; - default: - break; - } - return 0; -} - -static int add_info(ByteIOContext *bc, const char *type, const char *value){ - put_str(bc, type); - put_s(bc, -1); - put_str(bc, value); - return 1; -} - -static int write_globalinfo(NUTContext *nut, ByteIOContext *bc){ - AVFormatContext *s= nut->avf; - AVMetadataTag *t = NULL; - ByteIOContext *dyn_bc; - uint8_t *dyn_buf=NULL; - int count=0, dyn_size; - int ret = url_open_dyn_buf(&dyn_bc); - if(ret < 0) - return ret; - - while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) - count += add_info(dyn_bc, t->key, t->value); - - put_v(bc, 0); //stream_if_plus1 - put_v(bc, 0); //chapter_id - put_v(bc, 0); //timestamp_start - put_v(bc, 0); //length - - put_v(bc, count); - - dyn_size= url_close_dyn_buf(dyn_bc, &dyn_buf); - put_buffer(bc, dyn_buf, dyn_size); - av_free(dyn_buf); - return 0; -} - -static int write_streaminfo(NUTContext *nut, ByteIOContext *bc, int stream_id){ - AVFormatContext *s= nut->avf; - AVStream* st = s->streams[stream_id]; - ByteIOContext *dyn_bc; - uint8_t *dyn_buf=NULL; - int count=0, dyn_size, i; - int ret = url_open_dyn_buf(&dyn_bc); - if(ret < 0) - return ret; - - for (i=0; ff_nut_dispositions[i].flag; ++i) { - if (st->disposition & ff_nut_dispositions[i].flag) - count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str); - } - dyn_size = url_close_dyn_buf(dyn_bc, &dyn_buf); - - if (count) { - put_v(bc, stream_id + 1); //stream_id_plus1 - put_v(bc, 0); //chapter_id - put_v(bc, 0); //timestamp_start - put_v(bc, 0); //length - - put_v(bc, count); - - put_buffer(bc, dyn_buf, dyn_size); - } - - av_free(dyn_buf); - return count; -} - -static int write_headers(NUTContext *nut, ByteIOContext *bc){ - ByteIOContext *dyn_bc; - int i, ret; - - ret = url_open_dyn_buf(&dyn_bc); - if(ret < 0) - return ret; - write_mainheader(nut, dyn_bc); - put_packet(nut, bc, dyn_bc, 1, MAIN_STARTCODE); - - for (i=0; i < nut->avf->nb_streams; i++){ - ret = url_open_dyn_buf(&dyn_bc); - if(ret < 0) - return ret; - write_streamheader(nut, dyn_bc, nut->avf->streams[i], i); - put_packet(nut, bc, dyn_bc, 1, STREAM_STARTCODE); - } - - ret = url_open_dyn_buf(&dyn_bc); - if(ret < 0) - return ret; - write_globalinfo(nut, dyn_bc); - put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE); - - for (i = 0; i < nut->avf->nb_streams; i++) { - ret = url_open_dyn_buf(&dyn_bc); - if(ret < 0) - return ret; - ret = write_streaminfo(nut, dyn_bc, i); - if (ret < 0) - return ret; - if (ret > 0) - put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE); - else { - uint8_t* buf; - url_close_dyn_buf(dyn_bc, &buf); - av_free(buf); - } - } - - nut->last_syncpoint_pos= INT_MIN; - nut->header_count++; - return 0; -} - -static int write_header(AVFormatContext *s){ - NUTContext *nut = s->priv_data; - ByteIOContext *bc = s->pb; - int i, j; - - nut->avf= s; - - nut->stream = av_mallocz(sizeof(StreamContext)*s->nb_streams); - nut->time_base= av_mallocz(sizeof(AVRational )*s->nb_streams); - - for(i=0; inb_streams; i++){ - AVStream *st= s->streams[i]; - int ssize; - AVRational time_base; - ff_parse_specific_params(st->codec, &time_base.den, &ssize, &time_base.num); - - av_set_pts_info(st, 64, time_base.num, time_base.den); - - for(j=0; jtime_base_count; j++){ - if(!memcmp(&time_base, &nut->time_base[j], sizeof(AVRational))){ - break; - } - } - nut->time_base[j]= time_base; - nut->stream[i].time_base= &nut->time_base[j]; - if(j==nut->time_base_count) - nut->time_base_count++; - - if(av_q2d(time_base) >= 0.001) - nut->stream[i].msb_pts_shift = 7; - else - nut->stream[i].msb_pts_shift = 14; - nut->stream[i].max_pts_distance= FFMAX(1/av_q2d(time_base), 1); - } - - nut->max_distance = MAX_DISTANCE; - build_elision_headers(s); - build_frame_code(s); - assert(nut->frame_code['N'].flags == FLAG_INVALID); - - put_buffer(bc, ID_STRING, strlen(ID_STRING)); - put_byte(bc, 0); - - write_headers(nut, bc); - - put_flush_packet(bc); - - //FIXME index - - return 0; -} - -static int get_needed_flags(NUTContext *nut, StreamContext *nus, FrameCode *fc, AVPacket *pkt){ - int flags= 0; - - if(pkt->flags & AV_PKT_FLAG_KEY ) flags |= FLAG_KEY; - if(pkt->stream_index != fc->stream_id ) flags |= FLAG_STREAM_ID; - if(pkt->size / fc->size_mul ) flags |= FLAG_SIZE_MSB; - if(pkt->pts - nus->last_pts != fc->pts_delta) flags |= FLAG_CODED_PTS; - if(pkt->size > 2*nut->max_distance ) flags |= FLAG_CHECKSUM; - if(FFABS(pkt->pts - nus->last_pts) - > nus->max_pts_distance) flags |= FLAG_CHECKSUM; - if( pkt->size < nut->header_len[fc->header_idx] - || (pkt->size > 4096 && fc->header_idx) - || memcmp(pkt->data, nut->header[fc->header_idx], nut->header_len[fc->header_idx])) - flags |= FLAG_HEADER_IDX; - - return flags | (fc->flags & FLAG_CODED); -} - -static int find_best_header_idx(NUTContext *nut, AVPacket *pkt){ - int i; - int best_i = 0; - int best_len= 0; - - if(pkt->size > 4096) - return 0; - - for(i=1; iheader_count; i++){ - if( pkt->size >= nut->header_len[i] - && nut->header_len[i] > best_len - && !memcmp(pkt->data, nut->header[i], nut->header_len[i])){ - best_i= i; - best_len= nut->header_len[i]; - } - } - return best_i; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt){ - NUTContext *nut = s->priv_data; - StreamContext *nus= &nut->stream[pkt->stream_index]; - ByteIOContext *bc = s->pb, *dyn_bc; - FrameCode *fc; - int64_t coded_pts; - int best_length, frame_code, flags, needed_flags, i, header_idx, best_header_idx; - int key_frame = !!(pkt->flags & AV_PKT_FLAG_KEY); - int store_sp=0; - int ret; - - if(pkt->pts < 0) - return -1; - - if(1LL<<(20+3*nut->header_count) <= url_ftell(bc)) - write_headers(nut, bc); - - if(key_frame && !(nus->last_flags & FLAG_KEY)) - store_sp= 1; - - if(pkt->size + 30/*FIXME check*/ + url_ftell(bc) >= nut->last_syncpoint_pos + nut->max_distance) - store_sp= 1; - -//FIXME: Ensure store_sp is 1 in the first place. - - if(store_sp){ - Syncpoint *sp, dummy= {.pos= INT64_MAX}; - - ff_nut_reset_ts(nut, *nus->time_base, pkt->dts); - for(i=0; inb_streams; i++){ - AVStream *st= s->streams[i]; - int64_t dts_tb = av_rescale_rnd(pkt->dts, - nus->time_base->num * (int64_t)nut->stream[i].time_base->den, - nus->time_base->den * (int64_t)nut->stream[i].time_base->num, - AV_ROUND_DOWN); - int index= av_index_search_timestamp(st, dts_tb, AVSEEK_FLAG_BACKWARD); - if(index>=0) dummy.pos= FFMIN(dummy.pos, st->index_entries[index].pos); - } - if(dummy.pos == INT64_MAX) - dummy.pos= 0; - sp= av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, - NULL); - - nut->last_syncpoint_pos= url_ftell(bc); - ret = url_open_dyn_buf(&dyn_bc); - if(ret < 0) - return ret; - put_tt(nut, nus, dyn_bc, pkt->dts); - put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos)>>4 : 0); - put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE); - - ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0/*unused*/, pkt->dts); - } - assert(nus->last_pts != AV_NOPTS_VALUE); - - coded_pts = pkt->pts & ((1<msb_pts_shift)-1); - if(ff_lsb2full(nus, coded_pts) != pkt->pts) - coded_pts= pkt->pts + (1<msb_pts_shift); - - best_header_idx= find_best_header_idx(nut, pkt); - - best_length=INT_MAX; - frame_code= -1; - for(i=0; i<256; i++){ - int length= 0; - FrameCode *fc= &nut->frame_code[i]; - int flags= fc->flags; - - if(flags & FLAG_INVALID) - continue; - needed_flags= get_needed_flags(nut, nus, fc, pkt); - - if(flags & FLAG_CODED){ - length++; - flags = needed_flags; - } - - if((flags & needed_flags) != needed_flags) - continue; - - if((flags ^ needed_flags) & FLAG_KEY) - continue; - - if(flags & FLAG_STREAM_ID) - length+= get_length(pkt->stream_index); - - if(pkt->size % fc->size_mul != fc->size_lsb) - continue; - if(flags & FLAG_SIZE_MSB) - length += get_length(pkt->size / fc->size_mul); - - if(flags & FLAG_CHECKSUM) - length+=4; - - if(flags & FLAG_CODED_PTS) - length += get_length(coded_pts); - - if( (flags & FLAG_CODED) - && nut->header_len[best_header_idx] > nut->header_len[fc->header_idx]+1){ - flags |= FLAG_HEADER_IDX; - } - - if(flags & FLAG_HEADER_IDX){ - length += 1 - nut->header_len[best_header_idx]; - }else{ - length -= nut->header_len[fc->header_idx]; - } - - length*=4; - length+= !(flags & FLAG_CODED_PTS); - length+= !(flags & FLAG_CHECKSUM); - - if(length < best_length){ - best_length= length; - frame_code=i; - } - } - assert(frame_code != -1); - fc= &nut->frame_code[frame_code]; - flags= fc->flags; - needed_flags= get_needed_flags(nut, nus, fc, pkt); - header_idx= fc->header_idx; - - init_checksum(bc, ff_crc04C11DB7_update, 0); - put_byte(bc, frame_code); - if(flags & FLAG_CODED){ - put_v(bc, (flags^needed_flags) & ~(FLAG_CODED)); - flags = needed_flags; - } - if(flags & FLAG_STREAM_ID) put_v(bc, pkt->stream_index); - if(flags & FLAG_CODED_PTS) put_v(bc, coded_pts); - if(flags & FLAG_SIZE_MSB) put_v(bc, pkt->size / fc->size_mul); - if(flags & FLAG_HEADER_IDX) put_v(bc, header_idx= best_header_idx); - - if(flags & FLAG_CHECKSUM) put_le32(bc, get_checksum(bc)); - else get_checksum(bc); - - put_buffer(bc, pkt->data + nut->header_len[header_idx], pkt->size - nut->header_len[header_idx]); - nus->last_flags= flags; - nus->last_pts= pkt->pts; - - //FIXME just store one per syncpoint - if(flags & FLAG_KEY) - av_add_index_entry( - s->streams[pkt->stream_index], - nut->last_syncpoint_pos, - pkt->pts, - 0, - 0, - AVINDEX_KEYFRAME); - - return 0; -} - -static int write_trailer(AVFormatContext *s){ - NUTContext *nut= s->priv_data; - ByteIOContext *bc= s->pb; - - while(nut->header_count<3) - write_headers(nut, bc); - put_flush_packet(bc); - ff_nut_free_sp(nut); - av_freep(&nut->stream); - av_freep(&nut->time_base); - - return 0; -} - -AVOutputFormat nut_muxer = { - "nut", - NULL_IF_CONFIG_SMALL("NUT format"), - "video/x-nut", - "nut", - sizeof(NUTContext), -#if CONFIG_LIBVORBIS - CODEC_ID_VORBIS, -#elif CONFIG_LIBMP3LAME - CODEC_ID_MP3, -#else - CODEC_ID_MP2, -#endif - CODEC_ID_MPEG4, - write_header, - write_packet, - write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, - .codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0}, - .metadata_conv = ff_nut_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/nuv.c b/tizen/distrib/ffmpeg/libavformat/nuv.c deleted file mode 100644 index f0eacd5..0000000 --- a/tizen/distrib/ffmpeg/libavformat/nuv.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * NuppelVideo demuxer. - * Copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "riff.h" - -typedef struct { - int v_id; - int a_id; - int rtjpg_video; -} NUVContext; - -typedef enum { - NUV_VIDEO = 'V', - NUV_EXTRADATA = 'D', - NUV_AUDIO = 'A', - NUV_SEEKP = 'R', - NUV_MYTHEXT = 'X' -} nuv_frametype; - -static int nuv_probe(AVProbeData *p) { - if (!memcmp(p->buf, "NuppelVideo", 12)) - return AVPROBE_SCORE_MAX; - if (!memcmp(p->buf, "MythTVVideo", 12)) - return AVPROBE_SCORE_MAX; - return 0; -} - -//! little macro to sanitize packet size -#define PKTSIZE(s) (s & 0xffffff) - -/** - * \brief read until we found all data needed for decoding - * \param vst video stream of which to change parameters - * \param ast video stream of which to change parameters - * \param myth set if this is a MythTVVideo format file - * \return 1 if all required codec data was found - */ -static int get_codec_data(ByteIOContext *pb, AVStream *vst, - AVStream *ast, int myth) { - nuv_frametype frametype; - if (!vst && !myth) - return 1; // no codec data needed - while (!url_feof(pb)) { - int size, subtype; - frametype = get_byte(pb); - switch (frametype) { - case NUV_EXTRADATA: - subtype = get_byte(pb); - url_fskip(pb, 6); - size = PKTSIZE(get_le32(pb)); - if (vst && subtype == 'R') { - vst->codec->extradata_size = size; - vst->codec->extradata = av_malloc(size); - get_buffer(pb, vst->codec->extradata, size); - size = 0; - if (!myth) - return 1; - } - break; - case NUV_MYTHEXT: - url_fskip(pb, 7); - size = PKTSIZE(get_le32(pb)); - if (size != 128 * 4) - break; - get_le32(pb); // version - if (vst) { - vst->codec->codec_tag = get_le32(pb); - vst->codec->codec_id = - ff_codec_get_id(ff_codec_bmp_tags, vst->codec->codec_tag); - if (vst->codec->codec_tag == MKTAG('R', 'J', 'P', 'G')) - vst->codec->codec_id = CODEC_ID_NUV; - } else - url_fskip(pb, 4); - - if (ast) { - ast->codec->codec_tag = get_le32(pb); - ast->codec->sample_rate = get_le32(pb); - ast->codec->bits_per_coded_sample = get_le32(pb); - ast->codec->channels = get_le32(pb); - ast->codec->codec_id = - ff_wav_codec_get_id(ast->codec->codec_tag, - ast->codec->bits_per_coded_sample); - ast->need_parsing = AVSTREAM_PARSE_FULL; - } else - url_fskip(pb, 4 * 4); - - size -= 6 * 4; - url_fskip(pb, size); - return 1; - case NUV_SEEKP: - size = 11; - break; - default: - url_fskip(pb, 7); - size = PKTSIZE(get_le32(pb)); - break; - } - url_fskip(pb, size); - } - return 0; -} - -static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) { - NUVContext *ctx = s->priv_data; - ByteIOContext *pb = s->pb; - char id_string[12]; - double aspect, fps; - int is_mythtv, width, height, v_packs, a_packs; - int stream_nr = 0; - AVStream *vst = NULL, *ast = NULL; - get_buffer(pb, id_string, 12); - is_mythtv = !memcmp(id_string, "MythTVVideo", 12); - url_fskip(pb, 5); // version string - url_fskip(pb, 3); // padding - width = get_le32(pb); - height = get_le32(pb); - get_le32(pb); // unused, "desiredwidth" - get_le32(pb); // unused, "desiredheight" - get_byte(pb); // 'P' == progressive, 'I' == interlaced - url_fskip(pb, 3); // padding - aspect = av_int2dbl(get_le64(pb)); - if (aspect > 0.9999 && aspect < 1.0001) - aspect = 4.0 / 3.0; - fps = av_int2dbl(get_le64(pb)); - - // number of packets per stream type, -1 means unknown, e.g. streaming - v_packs = get_le32(pb); - a_packs = get_le32(pb); - get_le32(pb); // text - - get_le32(pb); // keyframe distance (?) - - if (v_packs) { - ctx->v_id = stream_nr++; - vst = av_new_stream(s, ctx->v_id); - if (!vst) - return AVERROR(ENOMEM); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_NUV; - vst->codec->width = width; - vst->codec->height = height; - vst->codec->bits_per_coded_sample = 10; - vst->sample_aspect_ratio = av_d2q(aspect * height / width, 10000); - vst->r_frame_rate = av_d2q(fps, 60000); - av_set_pts_info(vst, 32, 1, 1000); - } else - ctx->v_id = -1; - - if (a_packs) { - ctx->a_id = stream_nr++; - ast = av_new_stream(s, ctx->a_id); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = CODEC_ID_PCM_S16LE; - ast->codec->channels = 2; - ast->codec->sample_rate = 44100; - ast->codec->bit_rate = 2 * 2 * 44100 * 8; - ast->codec->block_align = 2 * 2; - ast->codec->bits_per_coded_sample = 16; - av_set_pts_info(ast, 32, 1, 1000); - } else - ctx->a_id = -1; - - get_codec_data(pb, vst, ast, is_mythtv); - ctx->rtjpg_video = vst && vst->codec->codec_id == CODEC_ID_NUV; - return 0; -} - -#define HDRSIZE 12 - -static int nuv_packet(AVFormatContext *s, AVPacket *pkt) { - NUVContext *ctx = s->priv_data; - ByteIOContext *pb = s->pb; - uint8_t hdr[HDRSIZE]; - nuv_frametype frametype; - int ret, size; - while (!url_feof(pb)) { - int copyhdrsize = ctx->rtjpg_video ? HDRSIZE : 0; - uint64_t pos = url_ftell(pb); - ret = get_buffer(pb, hdr, HDRSIZE); - if (ret < HDRSIZE) - return ret < 0 ? ret : AVERROR(EIO); - frametype = hdr[0]; - size = PKTSIZE(AV_RL32(&hdr[8])); - switch (frametype) { - case NUV_EXTRADATA: - if (!ctx->rtjpg_video) { - url_fskip(pb, size); - break; - } - case NUV_VIDEO: - if (ctx->v_id < 0) { - av_log(s, AV_LOG_ERROR, "Video packet in file without video stream!\n"); - url_fskip(pb, size); - break; - } - ret = av_new_packet(pkt, copyhdrsize + size); - if (ret < 0) - return ret; - // HACK: we have no idea if it is a keyframe, - // but if we mark none seeking will not work at all. - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pos = pos; - pkt->pts = AV_RL32(&hdr[4]); - pkt->stream_index = ctx->v_id; - memcpy(pkt->data, hdr, copyhdrsize); - ret = get_buffer(pb, pkt->data + copyhdrsize, size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - if (ret < size) - av_shrink_packet(pkt, copyhdrsize + ret); - return 0; - case NUV_AUDIO: - if (ctx->a_id < 0) { - av_log(s, AV_LOG_ERROR, "Audio packet in file without audio stream!\n"); - url_fskip(pb, size); - break; - } - ret = av_get_packet(pb, pkt, size); - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pos = pos; - pkt->pts = AV_RL32(&hdr[4]); - pkt->stream_index = ctx->a_id; - if (ret < 0) return ret; - return 0; - case NUV_SEEKP: - // contains no data, size value is invalid - break; - default: - url_fskip(pb, size); - break; - } - } - return AVERROR(EIO); -} - -AVInputFormat nuv_demuxer = { - "nuv", - NULL_IF_CONFIG_SMALL("NuppelVideo format"), - sizeof(NUVContext), - nuv_probe, - nuv_header, - nuv_packet, - NULL, - NULL, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggdec.c b/tizen/distrib/ffmpeg/libavformat/oggdec.c deleted file mode 100644 index 3161e68..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggdec.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Ogg bitstream support - * Luca Barbato - * Based on tcvp implementation - * - */ - -/** - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - 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 AUTHORS OR 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. -**/ - - -#include -#include "oggdec.h" -#include "avformat.h" -#include "vorbiscomment.h" - -#define MAX_PAGE_SIZE 65307 -#define DECODER_BUFFER_SIZE MAX_PAGE_SIZE - -static const struct ogg_codec * const ogg_codecs[] = { - &ff_skeleton_codec, - &ff_dirac_codec, - &ff_speex_codec, - &ff_vorbis_codec, - &ff_theora_codec, - &ff_flac_codec, - &ff_old_dirac_codec, - &ff_old_flac_codec, - &ff_ogm_video_codec, - &ff_ogm_audio_codec, - &ff_ogm_text_codec, - &ff_ogm_old_codec, - NULL -}; - -//FIXME We could avoid some structure duplication -static int -ogg_save (AVFormatContext * s) -{ - struct ogg *ogg = s->priv_data; - struct ogg_state *ost = - av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams)); - int i; - ost->pos = url_ftell (s->pb); - ost->curidx = ogg->curidx; - ost->next = ogg->state; - ost->nstreams = ogg->nstreams; - memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams)); - - for (i = 0; i < ogg->nstreams; i++){ - struct ogg_stream *os = ogg->streams + i; - os->buf = av_malloc (os->bufsize); - memset (os->buf, 0, os->bufsize); - memcpy (os->buf, ost->streams[i].buf, os->bufpos); - } - - ogg->state = ost; - - return 0; -} - -static int -ogg_restore (AVFormatContext * s, int discard) -{ - struct ogg *ogg = s->priv_data; - ByteIOContext *bc = s->pb; - struct ogg_state *ost = ogg->state; - int i; - - if (!ost) - return 0; - - ogg->state = ost->next; - - if (!discard){ - for (i = 0; i < ogg->nstreams; i++) - av_free (ogg->streams[i].buf); - - url_fseek (bc, ost->pos, SEEK_SET); - ogg->curidx = ost->curidx; - ogg->nstreams = ost->nstreams; - memcpy(ogg->streams, ost->streams, - ost->nstreams * sizeof(*ogg->streams)); - } - - av_free (ost); - - return 0; -} - -static int -ogg_reset (struct ogg * ogg) -{ - int i; - - for (i = 0; i < ogg->nstreams; i++){ - struct ogg_stream *os = ogg->streams + i; - os->bufpos = 0; - os->pstart = 0; - os->psize = 0; - os->granule = -1; - os->lastpts = AV_NOPTS_VALUE; - os->lastdts = AV_NOPTS_VALUE; - os->sync_pos = -1; - os->page_pos = 0; - os->nsegs = 0; - os->segp = 0; - os->incomplete = 0; - } - - ogg->curidx = -1; - - return 0; -} - -static const struct ogg_codec * -ogg_find_codec (uint8_t * buf, int size) -{ - int i; - - for (i = 0; ogg_codecs[i]; i++) - if (size >= ogg_codecs[i]->magicsize && - !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize)) - return ogg_codecs[i]; - - return NULL; -} - -static int -ogg_new_stream (AVFormatContext * s, uint32_t serial) -{ - - struct ogg *ogg = s->priv_data; - int idx = ogg->nstreams++; - AVStream *st; - struct ogg_stream *os; - - ogg->streams = av_realloc (ogg->streams, - ogg->nstreams * sizeof (*ogg->streams)); - memset (ogg->streams + idx, 0, sizeof (*ogg->streams)); - os = ogg->streams + idx; - os->serial = serial; - os->bufsize = DECODER_BUFFER_SIZE; - os->buf = av_malloc(os->bufsize); - os->header = -1; - - st = av_new_stream (s, idx); - if (!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 64, 1, 1000000); - - return idx; -} - -static int -ogg_new_buf(struct ogg *ogg, int idx) -{ - struct ogg_stream *os = ogg->streams + idx; - uint8_t *nb = av_malloc(os->bufsize); - int size = os->bufpos - os->pstart; - if(os->buf){ - memcpy(nb, os->buf + os->pstart, size); - av_free(os->buf); - } - os->buf = nb; - os->bufpos = size; - os->pstart = 0; - - return 0; -} - -static int -ogg_read_page (AVFormatContext * s, int *str) -{ - ByteIOContext *bc = s->pb; - struct ogg *ogg = s->priv_data; - struct ogg_stream *os; - int i = 0; - int flags, nsegs; - uint64_t gp; - uint32_t serial; - uint32_t seq; - uint32_t crc; - int size, idx; - uint8_t sync[4]; - int sp = 0; - - if (get_buffer (bc, sync, 4) < 4) - return -1; - - do{ - int c; - - if (sync[sp & 3] == 'O' && - sync[(sp + 1) & 3] == 'g' && - sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S') - break; - - c = url_fgetc (bc); - if (c < 0) - return -1; - sync[sp++ & 3] = c; - }while (i++ < MAX_PAGE_SIZE); - - if (i >= MAX_PAGE_SIZE){ - av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n"); - return -1; - } - - if (url_fgetc (bc) != 0) /* version */ - return -1; - - flags = url_fgetc (bc); - gp = get_le64 (bc); - serial = get_le32 (bc); - seq = get_le32 (bc); - crc = get_le32 (bc); - nsegs = url_fgetc (bc); - - idx = ogg_find_stream (ogg, serial); - if (idx < 0){ - idx = ogg_new_stream (s, serial); - if (idx < 0) - return -1; - } - - os = ogg->streams + idx; - os->page_pos = url_ftell(bc) - 27; - - if(os->psize > 0) - ogg_new_buf(ogg, idx); - - if (get_buffer (bc, os->segments, nsegs) < nsegs) - return -1; - - os->nsegs = nsegs; - os->segp = 0; - - size = 0; - for (i = 0; i < nsegs; i++) - size += os->segments[i]; - - if (flags & OGG_FLAG_CONT || os->incomplete){ - if (!os->psize){ - while (os->segp < os->nsegs){ - int seg = os->segments[os->segp++]; - os->pstart += seg; - if (seg < 255) - break; - } - os->sync_pos = os->page_pos; - } - }else{ - os->psize = 0; - os->sync_pos = os->page_pos; - } - - if (os->bufsize - os->bufpos < size){ - uint8_t *nb = av_malloc (os->bufsize *= 2); - memcpy (nb, os->buf, os->bufpos); - av_free (os->buf); - os->buf = nb; - } - - if (get_buffer (bc, os->buf + os->bufpos, size) < size) - return -1; - - os->bufpos += size; - os->granule = gp; - os->flags = flags; - - if (str) - *str = idx; - - return 0; -} - -static int -ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize, int64_t *fpos) -{ - struct ogg *ogg = s->priv_data; - int idx, i; - struct ogg_stream *os; - int complete = 0; - int segp = 0, psize = 0; - -#if 0 - av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx); -#endif - - do{ - idx = ogg->curidx; - - while (idx < 0){ - if (ogg_read_page (s, &idx) < 0) - return -1; - } - - os = ogg->streams + idx; - -#if 0 - av_log (s, AV_LOG_DEBUG, - "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n", - idx, os->pstart, os->psize, os->segp, os->nsegs); -#endif - - if (!os->codec){ - if (os->header < 0){ - os->codec = ogg_find_codec (os->buf, os->bufpos); - if (!os->codec){ - os->header = 0; - return 0; - } - }else{ - return 0; - } - } - - segp = os->segp; - psize = os->psize; - - while (os->segp < os->nsegs){ - int ss = os->segments[os->segp++]; - os->psize += ss; - if (ss < 255){ - complete = 1; - break; - } - } - - if (!complete && os->segp == os->nsegs){ - ogg->curidx = -1; - os->incomplete = 1; - } - }while (!complete); - -#if 0 - av_log (s, AV_LOG_DEBUG, - "ogg_packet: idx %i, frame size %i, start %i\n", - idx, os->psize, os->pstart); -#endif - - if (os->granule == -1) - av_log(s, AV_LOG_WARNING, "Page at %lld is missing granule\n", os->page_pos); - - ogg->curidx = idx; - os->incomplete = 0; - - if (os->header) { - os->header = os->codec->header (s, idx); - if (!os->header){ - os->segp = segp; - os->psize = psize; - if (!ogg->headers) - s->data_offset = os->sync_pos; - ogg->headers = 1; - }else{ - os->pstart += os->psize; - os->psize = 0; - } - } else { - os->pflags = 0; - os->pduration = 0; - if (os->codec && os->codec->packet) - os->codec->packet (s, idx); - if (str) - *str = idx; - if (dstart) - *dstart = os->pstart; - if (dsize) - *dsize = os->psize; - if (fpos) - *fpos = os->sync_pos; - os->pstart += os->psize; - os->psize = 0; - os->sync_pos = os->page_pos; - } - - // determine whether there are more complete packets in this page - // if not, the page's granule will apply to this packet - os->page_end = 1; - for (i = os->segp; i < os->nsegs; i++) - if (os->segments[i] < 255) { - os->page_end = 0; - break; - } - - if (os->segp == os->nsegs) - ogg->curidx = -1; - - return 0; -} - -static int -ogg_get_headers (AVFormatContext * s) -{ - struct ogg *ogg = s->priv_data; - - do{ - if (ogg_packet (s, NULL, NULL, NULL, NULL) < 0) - return -1; - }while (!ogg->headers); - -#if 0 - av_log (s, AV_LOG_DEBUG, "found headers\n"); -#endif - - return 0; -} - -static int -ogg_get_length (AVFormatContext * s) -{ - struct ogg *ogg = s->priv_data; - int i; - int64_t size, end; - - if(url_is_streamed(s->pb)) - return 0; - -// already set - if (s->duration != AV_NOPTS_VALUE) - return 0; - - size = url_fsize(s->pb); - if(size < 0) - return 0; - end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0; - - ogg_save (s); - url_fseek (s->pb, end, SEEK_SET); - - while (!ogg_read_page (s, &i)){ - if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 && - ogg->streams[i].codec) { - s->streams[i]->duration = - ogg_gptopts (s, i, ogg->streams[i].granule, NULL); - if (s->streams[i]->start_time != AV_NOPTS_VALUE) - s->streams[i]->duration -= s->streams[i]->start_time; - } - } - - ogg_restore (s, 0); - - return 0; -} - - -static int -ogg_read_header (AVFormatContext * s, AVFormatParameters * ap) -{ - struct ogg *ogg = s->priv_data; - int i; - ogg->curidx = -1; - //linear headers seek from start - if (ogg_get_headers (s) < 0){ - return -1; - } - - for (i = 0; i < ogg->nstreams; i++) - if (ogg->streams[i].header < 0) - ogg->streams[i].codec = NULL; - - //linear granulepos seek from end - ogg_get_length (s); - - //fill the extradata in the per codec callbacks - return 0; -} - -static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - int64_t pts = AV_NOPTS_VALUE; - - if (dts) - *dts = AV_NOPTS_VALUE; - - if (os->lastpts != AV_NOPTS_VALUE) { - pts = os->lastpts; - os->lastpts = AV_NOPTS_VALUE; - } - if (os->lastdts != AV_NOPTS_VALUE) { - if (dts) - *dts = os->lastdts; - os->lastdts = AV_NOPTS_VALUE; - } - if (os->page_end) { - if (os->granule != -1LL) { - if (os->codec && os->codec->granule_is_start) - pts = ogg_gptopts(s, idx, os->granule, dts); - else - os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts); - os->granule = -1LL; - } - } - return pts; -} - -static int -ogg_read_packet (AVFormatContext * s, AVPacket * pkt) -{ - struct ogg *ogg; - struct ogg_stream *os; - int idx = -1; - int pstart, psize; - int64_t fpos, pts, dts; - - //Get an ogg packet -retry: - do{ - if (ogg_packet (s, &idx, &pstart, &psize, &fpos) < 0) - return AVERROR(EIO); - }while (idx < 0 || !s->streams[idx]); - - ogg = s->priv_data; - os = ogg->streams + idx; - - // pflags might not be set until after this - pts = ogg_calc_pts(s, idx, &dts); - - if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY)) - goto retry; - os->keyframe_seek = 0; - - //Alloc a pkt - if (av_new_packet (pkt, psize) < 0) - return AVERROR(EIO); - pkt->stream_index = idx; - memcpy (pkt->data, os->buf + pstart, psize); - - pkt->pts = pts; - pkt->dts = dts; - pkt->flags = os->pflags; - pkt->duration = os->pduration; - pkt->pos = fpos; - - return psize; -} - - -static int -ogg_read_close (AVFormatContext * s) -{ - struct ogg *ogg = s->priv_data; - int i; - - for (i = 0; i < ogg->nstreams; i++){ - av_free (ogg->streams[i].buf); - av_free (ogg->streams[i].private); - } - av_free (ogg->streams); - return 0; -} - - -static int64_t -ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg, - int64_t pos_limit) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + stream_index; - ByteIOContext *bc = s->pb; - int64_t pts = AV_NOPTS_VALUE; - int i; - url_fseek(bc, *pos_arg, SEEK_SET); - ogg_reset(ogg); - - while (url_ftell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) { - if (i == stream_index) { - pts = ogg_calc_pts(s, i, NULL); - if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY)) - pts = AV_NOPTS_VALUE; - } - if (pts != AV_NOPTS_VALUE) - break; - } - ogg_reset(ogg); - return pts; -} - -static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + stream_index; - int ret; - - // Try seeking to a keyframe first. If this fails (very possible), - // av_seek_frame will fall back to ignoring keyframes - if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO - && !(flags & AVSEEK_FLAG_ANY)) - os->keyframe_seek = 1; - - ret = av_seek_frame_binary(s, stream_index, timestamp, flags); - if (ret < 0) - os->keyframe_seek = 0; - return ret; -} - -static int ogg_probe(AVProbeData *p) -{ - if (p->buf[0] == 'O' && p->buf[1] == 'g' && - p->buf[2] == 'g' && p->buf[3] == 'S' && - p->buf[4] == 0x0 && p->buf[5] <= 0x7 ) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -AVInputFormat ogg_demuxer = { - "ogg", - NULL_IF_CONFIG_SMALL("Ogg"), - sizeof (struct ogg), - ogg_probe, - ogg_read_header, - ogg_read_packet, - ogg_read_close, - ogg_read_seek, - ogg_read_timestamp, - .extensions = "ogg", - .metadata_conv = ff_vorbiscomment_metadata_conv, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggdec.h b/tizen/distrib/ffmpeg/libavformat/oggdec.h deleted file mode 100644 index 7d66cd5..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggdec.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - 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 AUTHORS OR 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. -**/ - -#ifndef AVFORMAT_OGGDEC_H -#define AVFORMAT_OGGDEC_H - -#include "avformat.h" -#include "metadata.h" - -struct ogg_codec { - const int8_t *magic; - uint8_t magicsize; - const int8_t *name; - /** - * Attempt to process a packet as a header - * @return 1 if the packet was a valid header, - * 0 if the packet was not a header (was a data packet) - * -1 if an error occurred or for unsupported stream - */ - int (*header)(AVFormatContext *, int); - int (*packet)(AVFormatContext *, int); - /** - * Translate a granule into a timestamp. - * Will set dts if non-null and known. - * @return pts - */ - uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts); - /** - * 1 if granule is the start time of the associated packet. - * 0 if granule is the end time of the associated packet. - */ - int granule_is_start; -}; - -struct ogg_stream { - uint8_t *buf; - unsigned int bufsize; - unsigned int bufpos; - unsigned int pstart; - unsigned int psize; - unsigned int pflags; - unsigned int pduration; - uint32_t serial; - uint64_t granule; - int64_t lastpts; - int64_t lastdts; - int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet - int64_t page_pos; ///< file offset of the current page - int flags; - const struct ogg_codec *codec; - int header; - int nsegs, segp; - uint8_t segments[255]; - int incomplete; ///< whether we're expecting a continuation in the next page - int page_end; ///< current packet is the last one completed in the page - int keyframe_seek; - void *private; -}; - -struct ogg_state { - uint64_t pos; - int curidx; - struct ogg_state *next; - int nstreams; - struct ogg_stream streams[1]; -}; - -struct ogg { - struct ogg_stream *streams; - int nstreams; - int headers; - int curidx; - struct ogg_state *state; -}; - -#define OGG_FLAG_CONT 1 -#define OGG_FLAG_BOS 2 -#define OGG_FLAG_EOS 4 - -extern const struct ogg_codec ff_dirac_codec; -extern const struct ogg_codec ff_flac_codec; -extern const struct ogg_codec ff_ogm_audio_codec; -extern const struct ogg_codec ff_ogm_old_codec; -extern const struct ogg_codec ff_ogm_text_codec; -extern const struct ogg_codec ff_ogm_video_codec; -extern const struct ogg_codec ff_old_dirac_codec; -extern const struct ogg_codec ff_old_flac_codec; -extern const struct ogg_codec ff_skeleton_codec; -extern const struct ogg_codec ff_speex_codec; -extern const struct ogg_codec ff_theora_codec; -extern const struct ogg_codec ff_vorbis_codec; - -int ff_vorbis_comment(AVFormatContext *ms, AVMetadata **m, const uint8_t *buf, int size); - -static inline int -ogg_find_stream (struct ogg * ogg, int serial) -{ - int i; - - for (i = 0; i < ogg->nstreams; i++) - if (ogg->streams[i].serial == serial) - return i; - - return -1; -} - -static inline uint64_t -ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + i; - uint64_t pts = AV_NOPTS_VALUE; - - if(os->codec && os->codec->gptopts){ - pts = os->codec->gptopts(s, i, gp, dts); - } else { - pts = gp; - if (dts) - *dts = pts; - } - - return pts; -} - -#endif /* AVFORMAT_OGGDEC_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/oggenc.c b/tizen/distrib/ffmpeg/libavformat/oggenc.c deleted file mode 100644 index 70264a4..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggenc.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Ogg muxer - * Copyright (c) 2007 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/crc.h" -#include "libavcodec/xiph.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/flac.h" -#include "avformat.h" -#include "internal.h" -#include "vorbiscomment.h" - -#define MAX_PAGE_SIZE 65025 - -typedef struct { - int64_t granule; - int stream_index; - uint8_t flags; - uint8_t segments_count; - uint8_t segments[255]; - uint8_t data[MAX_PAGE_SIZE]; - uint16_t size; -} OGGPage; - -typedef struct { - int64_t duration; - unsigned page_counter; - uint8_t *header[3]; - int header_len[3]; - /** for theora granule */ - int kfgshift; - int64_t last_kf_pts; - int vrev; - int eos; - unsigned page_count; ///< number of page buffered - OGGPage page; ///< current page -} OGGStreamContext; - -typedef struct OGGPageList { - OGGPage page; - struct OGGPageList *next; -} OGGPageList; - -typedef struct { - OGGPageList *page_list; -} OGGContext; - -static void ogg_update_checksum(AVFormatContext *s, int64_t crc_offset) -{ - int64_t pos = url_ftell(s->pb); - uint32_t checksum = get_checksum(s->pb); - url_fseek(s->pb, crc_offset, SEEK_SET); - put_be32(s->pb, checksum); - url_fseek(s->pb, pos, SEEK_SET); -} - -static void ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags) -{ - OGGStreamContext *oggstream = s->streams[page->stream_index]->priv_data; - int64_t crc_offset; - - init_checksum(s->pb, ff_crc04C11DB7_update, 0); - put_tag(s->pb, "OggS"); - put_byte(s->pb, 0); - put_byte(s->pb, page->flags | extra_flags); - put_le64(s->pb, page->granule); - put_le32(s->pb, page->stream_index); - put_le32(s->pb, oggstream->page_counter++); - crc_offset = url_ftell(s->pb); - put_le32(s->pb, 0); // crc - put_byte(s->pb, page->segments_count); - put_buffer(s->pb, page->segments, page->segments_count); - put_buffer(s->pb, page->data, page->size); - - ogg_update_checksum(s, crc_offset); - put_flush_packet(s->pb); - oggstream->page_count--; -} - -static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, OGGPage *page) -{ - if (oggstream->kfgshift) - return (page->granule>>oggstream->kfgshift) + - (page->granule & ((1<kfgshift)-1)); - else - return page->granule; -} - -static int ogg_compare_granule(AVFormatContext *s, OGGPage *next, OGGPage *page) -{ - AVStream *st2 = s->streams[next->stream_index]; - AVStream *st = s->streams[page->stream_index]; - int64_t next_granule, cur_granule; - - if (next->granule == -1 || page->granule == -1) - return 0; - - next_granule = av_rescale_q(ogg_granule_to_timestamp(st2->priv_data, next), - st2->time_base, AV_TIME_BASE_Q); - cur_granule = av_rescale_q(ogg_granule_to_timestamp(st->priv_data, page), - st ->time_base, AV_TIME_BASE_Q); - return next_granule > cur_granule; -} - -static int ogg_reset_cur_page(OGGStreamContext *oggstream) -{ - oggstream->page.granule = -1; - oggstream->page.flags = 0; - oggstream->page.segments_count = 0; - oggstream->page.size = 0; - return 0; -} - -static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream) -{ - OGGContext *ogg = s->priv_data; - OGGPageList **p = &ogg->page_list; - OGGPageList *l = av_mallocz(sizeof(*l)); - - if (!l) - return AVERROR(ENOMEM); - l->page = oggstream->page; - - oggstream->page_count++; - ogg_reset_cur_page(oggstream); - - while (*p) { - if (ogg_compare_granule(s, &(*p)->page, &l->page)) - break; - p = &(*p)->next; - } - l->next = *p; - *p = l; - - return 0; -} - -static int ogg_buffer_data(AVFormatContext *s, AVStream *st, - uint8_t *data, unsigned size, int64_t granule) -{ - OGGStreamContext *oggstream = st->priv_data; - int total_segments = size / 255 + 1; - uint8_t *p = data; - int i, segments, len; - - for (i = 0; i < total_segments; ) { - OGGPage *page = &oggstream->page; - - segments = FFMIN(total_segments - i, 255 - page->segments_count); - - if (i && !page->segments_count) - page->flags |= 1; // continued packet - - memset(page->segments+page->segments_count, 255, segments - 1); - page->segments_count += segments - 1; - - len = FFMIN(size, segments*255); - page->segments[page->segments_count++] = len - (segments-1)*255; - memcpy(page->data+page->size, p, len); - p += len; - size -= len; - i += segments; - page->size += len; - - if (i == total_segments) - page->granule = granule; - - if (page->segments_count == 255) { - ogg_buffer_page(s, oggstream); - } - } - return 0; -} - -static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact, - int *header_len, AVMetadata *m) -{ - const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; - int size; - uint8_t *p, *p0; - unsigned int count; - - size = offset + ff_vorbiscomment_length(m, vendor, &count); - p = av_mallocz(size); - if (!p) - return NULL; - p0 = p; - - p += offset; - ff_vorbiscomment_write(&p, m, vendor, count); - - *header_len = size; - return p0; -} - -static int ogg_build_flac_headers(AVCodecContext *avctx, - OGGStreamContext *oggstream, int bitexact, - AVMetadata *m) -{ - enum FLACExtradataFormat format; - uint8_t *streaminfo; - uint8_t *p; - - if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo)) - return -1; - - // first packet: STREAMINFO - oggstream->header_len[0] = 51; - oggstream->header[0] = av_mallocz(51); // per ogg flac specs - p = oggstream->header[0]; - if (!p) - return AVERROR(ENOMEM); - bytestream_put_byte(&p, 0x7F); - bytestream_put_buffer(&p, "FLAC", 4); - bytestream_put_byte(&p, 1); // major version - bytestream_put_byte(&p, 0); // minor version - bytestream_put_be16(&p, 1); // headers packets without this one - bytestream_put_buffer(&p, "fLaC", 4); - bytestream_put_byte(&p, 0x00); // streaminfo - bytestream_put_be24(&p, 34); - bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE); - - // second packet: VorbisComment - p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[1] = p; - bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment - bytestream_put_be24(&p, oggstream->header_len[1] - 4); - - return 0; -} - -#define SPEEX_HEADER_SIZE 80 - -static int ogg_build_speex_headers(AVCodecContext *avctx, - OGGStreamContext *oggstream, int bitexact, - AVMetadata *m) -{ - uint8_t *p; - - if (avctx->extradata_size < SPEEX_HEADER_SIZE) - return -1; - - // first packet: Speex header - p = av_mallocz(SPEEX_HEADER_SIZE); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[0] = p; - oggstream->header_len[0] = SPEEX_HEADER_SIZE; - bytestream_put_buffer(&p, avctx->extradata, SPEEX_HEADER_SIZE); - AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0 - - // second packet: VorbisComment - p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[1] = p; - - return 0; -} - -static int ogg_write_header(AVFormatContext *s) -{ - OGGStreamContext *oggstream; - int i, j; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den); - if (st->codec->codec_id != CODEC_ID_VORBIS && - st->codec->codec_id != CODEC_ID_THEORA && - st->codec->codec_id != CODEC_ID_SPEEX && - st->codec->codec_id != CODEC_ID_FLAC) { - av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i); - return -1; - } - - if (!st->codec->extradata || !st->codec->extradata_size) { - av_log(s, AV_LOG_ERROR, "No extradata present\n"); - return -1; - } - oggstream = av_mallocz(sizeof(*oggstream)); - oggstream->page.stream_index = i; - st->priv_data = oggstream; - if (st->codec->codec_id == CODEC_ID_FLAC) { - int err = ogg_build_flac_headers(st->codec, oggstream, - st->codec->flags & CODEC_FLAG_BITEXACT, - s->metadata); - if (err) { - av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n"); - av_freep(&st->priv_data); - return err; - } - } else if (st->codec->codec_id == CODEC_ID_SPEEX) { - int err = ogg_build_speex_headers(st->codec, oggstream, - st->codec->flags & CODEC_FLAG_BITEXACT, - s->metadata); - if (err) { - av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n"); - av_freep(&st->priv_data); - return err; - } - } else { - if (ff_split_xiph_headers(st->codec->extradata, st->codec->extradata_size, - st->codec->codec_id == CODEC_ID_VORBIS ? 30 : 42, - oggstream->header, oggstream->header_len) < 0) { - av_log(s, AV_LOG_ERROR, "Extradata corrupted\n"); - av_freep(&st->priv_data); - return -1; - } - if (st->codec->codec_id == CODEC_ID_THEORA) { - /** KFGSHIFT is the width of the less significant section of the granule position - The less significant section is the frame count since the last keyframe */ - oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5); - oggstream->vrev = oggstream->header[0][9]; - av_log(s, AV_LOG_DEBUG, "theora kfgshift %d, vrev %d\n", - oggstream->kfgshift, oggstream->vrev); - } - } - } - - for (j = 0; j < s->nb_streams; j++) { - OGGStreamContext *oggstream = s->streams[j]->priv_data; - ogg_buffer_data(s, s->streams[j], oggstream->header[0], - oggstream->header_len[0], 0); - oggstream->page.flags |= 2; // bos - ogg_buffer_page(s, oggstream); - } - for (j = 0; j < s->nb_streams; j++) { - AVStream *st = s->streams[j]; - OGGStreamContext *oggstream = st->priv_data; - for (i = 1; i < 3; i++) { - if (oggstream && oggstream->header_len[i]) - ogg_buffer_data(s, st, oggstream->header[i], - oggstream->header_len[i], 0); - } - ogg_buffer_page(s, oggstream); - } - return 0; -} - -static void ogg_write_pages(AVFormatContext *s, int flush) -{ - OGGContext *ogg = s->priv_data; - OGGPageList *next, *p; - - if (!ogg->page_list) - return; - - for (p = ogg->page_list; p; ) { - OGGStreamContext *oggstream = - s->streams[p->page.stream_index]->priv_data; - if (oggstream->page_count < 2 && !flush) - break; - ogg_write_page(s, &p->page, - flush && oggstream->page_count == 1 ? 4 : 0); // eos - next = p->next; - av_freep(&p); - p = next; - } - ogg->page_list = p; -} - -static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVStream *st = s->streams[pkt->stream_index]; - OGGStreamContext *oggstream = st->priv_data; - int ret; - int64_t granule; - - if (st->codec->codec_id == CODEC_ID_THEORA) { - int64_t pts = oggstream->vrev < 1 ? pkt->pts : pkt->pts + pkt->duration; - int pframe_count; - if (pkt->flags & AV_PKT_FLAG_KEY) - oggstream->last_kf_pts = pts; - pframe_count = pts - oggstream->last_kf_pts; - // prevent frame count from overflow if key frame flag is not set - if (pframe_count >= (1<kfgshift)) { - oggstream->last_kf_pts += pframe_count; - pframe_count = 0; - } - granule = (oggstream->last_kf_pts<kfgshift) | pframe_count; - } else - granule = pkt->pts + pkt->duration; - oggstream->duration = granule; - - ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule); - if (ret < 0) - return ret; - - ogg_write_pages(s, 0); - - return 0; -} - -static int ogg_write_trailer(AVFormatContext *s) -{ - int i; - - /* flush current page */ - for (i = 0; i < s->nb_streams; i++) - ogg_buffer_page(s, s->streams[i]->priv_data); - - ogg_write_pages(s, 1); - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - OGGStreamContext *oggstream = st->priv_data; - if (st->codec->codec_id == CODEC_ID_FLAC || - st->codec->codec_id == CODEC_ID_SPEEX) { - av_free(oggstream->header[0]); - av_free(oggstream->header[1]); - } - av_freep(&st->priv_data); - } - return 0; -} - -AVOutputFormat ogg_muxer = { - "ogg", - NULL_IF_CONFIG_SMALL("Ogg"), - "application/ogg", - "ogg,ogv,spx", - sizeof(OGGContext), - CODEC_ID_FLAC, - CODEC_ID_THEORA, - ogg_write_header, - ogg_write_packet, - ogg_write_trailer, - .metadata_conv = ff_vorbiscomment_metadata_conv, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggparsedirac.c b/tizen/distrib/ffmpeg/libavformat/oggparsedirac.c deleted file mode 100644 index a7f0401..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggparsedirac.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2008 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/get_bits.h" -#include "libavcodec/dirac.h" -#include "avformat.h" -#include "oggdec.h" - -static int dirac_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - dirac_source_params source; - GetBitContext gb; - - // already parsed the header - if (st->codec->codec_id == CODEC_ID_DIRAC) - return 0; - - init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8); - if (ff_dirac_parse_sequence_header(st->codec, &gb, &source) < 0) - return -1; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DIRAC; - // dirac in ogg always stores timestamps as though the video were interlaced - st->time_base = (AVRational){st->codec->time_base.num, 2*st->codec->time_base.den}; - return 1; -} - -// various undocument things: granule is signed (only for dirac!) -static uint64_t dirac_gptopts(AVFormatContext *s, int idx, uint64_t granule, - int64_t *dts_out) -{ - int64_t gp = granule; - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - - unsigned dist = ((gp >> 14) & 0xff00) | (gp & 0xff); - int64_t dts = (gp >> 31); - int64_t pts = dts + ((gp >> 9) & 0x1fff); - - if (!dist) - os->pflags |= AV_PKT_FLAG_KEY; - - if (dts_out) - *dts_out = dts; - - return pts; -} - -static int old_dirac_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *buf = os->buf + os->pstart; - - if (buf[0] != 'K') - return 0; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DIRAC; - st->time_base.den = AV_RB32(buf+8); - st->time_base.num = AV_RB32(buf+12); - return 1; -} - -static uint64_t old_dirac_gptopts(AVFormatContext *s, int idx, uint64_t gp, - int64_t *dts) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - uint64_t iframe = gp >> 30; - uint64_t pframe = gp & 0x3fffffff; - - if (!pframe) - os->pflags |= AV_PKT_FLAG_KEY; - - return iframe + pframe; -} - -const struct ogg_codec ff_dirac_codec = { - .magic = "BBCD\0", - .magicsize = 5, - .header = dirac_header, - .gptopts = dirac_gptopts, - .granule_is_start = 1, -}; - -const struct ogg_codec ff_old_dirac_codec = { - .magic = "KW-DIRAC", - .magicsize = 8, - .header = old_dirac_header, - .gptopts = old_dirac_gptopts, - .granule_is_start = 1, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggparseflac.c b/tizen/distrib/ffmpeg/libavformat/oggparseflac.c deleted file mode 100644 index e5034af..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggparseflac.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2005 Matthieu CASTET - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "libavcodec/get_bits.h" -#include "libavcodec/flac.h" -#include "avformat.h" -#include "oggdec.h" - -#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F - -static int -flac_header (AVFormatContext * s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - GetBitContext gb; - FLACStreaminfo si; - int mdt; - - if (os->buf[os->pstart] == 0xff) - return 0; - - init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - skip_bits1(&gb); /* metadata_last */ - mdt = get_bits(&gb, 7); - - if (mdt == OGG_FLAC_METADATA_TYPE_STREAMINFO) { - uint8_t *streaminfo_start = os->buf + os->pstart + 5 + 4 + 4 + 4; - skip_bits_long(&gb, 4*8); /* "FLAC" */ - if(get_bits(&gb, 8) != 1) /* unsupported major version */ - return -1; - skip_bits_long(&gb, 8 + 16); /* minor version + header count */ - skip_bits_long(&gb, 4*8); /* "fLaC" */ - - /* METADATA_BLOCK_HEADER */ - if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE) - return -1; - - ff_flac_parse_streaminfo(st->codec, &si, streaminfo_start); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_FLAC; - - st->codec->extradata = - av_malloc(FLAC_STREAMINFO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(st->codec->extradata, streaminfo_start, FLAC_STREAMINFO_SIZE); - st->codec->extradata_size = FLAC_STREAMINFO_SIZE; - - st->time_base.num = 1; - st->time_base.den = st->codec->sample_rate; - } else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) { - ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 4, os->psize - 4); - } - - return 1; -} - -static int -old_flac_header (AVFormatContext * s, int idx) -{ - AVStream *st = s->streams[idx]; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_FLAC; - - return 0; -} - -const struct ogg_codec ff_flac_codec = { - .magic = "\177FLAC", - .magicsize = 5, - .header = flac_header -}; - -const struct ogg_codec ff_old_flac_codec = { - .magic = "fLaC", - .magicsize = 4, - .header = old_flac_header -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggparseogm.c b/tizen/distrib/ffmpeg/libavformat/oggparseogm.c deleted file mode 100644 index e1d046f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggparseogm.c +++ /dev/null @@ -1,188 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - 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 AUTHORS OR 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. -**/ - -#include -#include "libavutil/intreadwrite.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "oggdec.h" -#include "riff.h" - -static int -ogm_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - const uint8_t *p = os->buf + os->pstart; - uint64_t time_unit; - uint64_t spu; - uint32_t default_len; - - if(!(*p & 1)) - return 0; - - if(*p == 1) { - p++; - - if(*p == 'v'){ - int tag; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - p += 8; - tag = bytestream_get_le32(&p); - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag); - st->codec->codec_tag = tag; - } else if (*p == 't') { - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = CODEC_ID_TEXT; - p += 12; - } else { - uint8_t acid[5]; - int cid; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - p += 8; - bytestream_get_buffer(&p, acid, 4); - acid[4] = 0; - cid = strtol(acid, NULL, 16); - st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid); - st->need_parsing = AVSTREAM_PARSE_FULL; - } - - p += 4; /* useless size field */ - - time_unit = bytestream_get_le64(&p); - spu = bytestream_get_le64(&p); - default_len = bytestream_get_le32(&p); - - p += 8; /* buffersize + bits_per_sample */ - - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - st->codec->width = bytestream_get_le32(&p); - st->codec->height = bytestream_get_le32(&p); - st->codec->time_base.den = spu * 10000000; - st->codec->time_base.num = time_unit; - st->time_base = st->codec->time_base; - } else { - st->codec->channels = bytestream_get_le16(&p); - p += 2; /* block_align */ - st->codec->bit_rate = bytestream_get_le32(&p) * 8; - st->codec->sample_rate = spu * 10000000 / time_unit; - st->time_base.num = 1; - st->time_base.den = st->codec->sample_rate; - } - } else if (*p == 3) { - if (os->psize > 8) - ff_vorbis_comment(s, &st->metadata, p+7, os->psize-8); - } - - return 1; -} - -static int -ogm_dshow_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *p = os->buf + os->pstart; - uint32_t t; - - if(!(*p & 1)) - return 0; - if(*p != 1) - return 1; - - t = AV_RL32(p + 96); - - if(t == 0x05589f80){ - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(p + 68)); - st->codec->time_base.den = 10000000; - st->codec->time_base.num = AV_RL64(p + 164); - st->codec->width = AV_RL32(p + 176); - st->codec->height = AV_RL32(p + 180); - } else if(t == 0x05589f81){ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, AV_RL16(p + 124)); - st->codec->channels = AV_RL16(p + 126); - st->codec->sample_rate = AV_RL32(p + 128); - st->codec->bit_rate = AV_RL32(p + 132) * 8; - } - - return 1; -} - -static int -ogm_packet(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - uint8_t *p = os->buf + os->pstart; - int lb; - - if(*p & 8) - os->pflags |= AV_PKT_FLAG_KEY; - - lb = ((*p & 2) << 1) | ((*p >> 6) & 3); - os->pstart += lb + 1; - os->psize -= lb + 1; - - while (lb--) - os->pduration += p[lb+1] << (lb*8); - - return 0; -} - -const struct ogg_codec ff_ogm_video_codec = { - .magic = "\001video", - .magicsize = 6, - .header = ogm_header, - .packet = ogm_packet, - .granule_is_start = 1, -}; - -const struct ogg_codec ff_ogm_audio_codec = { - .magic = "\001audio", - .magicsize = 6, - .header = ogm_header, - .packet = ogm_packet, - .granule_is_start = 1, -}; - -const struct ogg_codec ff_ogm_text_codec = { - .magic = "\001text", - .magicsize = 5, - .header = ogm_header, - .packet = ogm_packet, - .granule_is_start = 1, -}; - -const struct ogg_codec ff_ogm_old_codec = { - .magic = "\001Direct Show Samples embedded in Ogg", - .magicsize = 35, - .header = ogm_dshow_header, - .packet = ogm_packet, - .granule_is_start = 1, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggparseskeleton.c b/tizen/distrib/ffmpeg/libavformat/oggparseskeleton.c deleted file mode 100644 index ad0dded..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggparseskeleton.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2010 David Conrad - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "oggdec.h" - -static int skeleton_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *buf = os->buf + os->pstart; - int version_major, version_minor; - int64_t start_num, start_den, start_granule; - int target_idx, start_time; - - strcpy(st->codec->codec_name, "skeleton"); - st->codec->codec_type = AVMEDIA_TYPE_DATA; - - if (os->psize < 8) - return -1; - - if (!strncmp(buf, "fishead", 8)) { - if (os->psize < 64) - return -1; - - version_major = AV_RL16(buf+8); - version_minor = AV_RL16(buf+10); - - if (version_major != 3) { - av_log(s, AV_LOG_WARNING, "Unknown skeleton version %d.%d\n", - version_major, version_minor); - return -1; - } - - // This is the overall start time. We use it for the start time of - // of the skeleton stream since if left unset lavf assumes 0, - // which we don't want since skeleton is timeless - // FIXME: the real meaning of this field is "start playback at - // this time which can be in the middle of a packet - start_num = AV_RL64(buf+12); - start_den = AV_RL64(buf+20); - - if (start_den) { - av_reduce(&start_time, &st->time_base.den, start_num, start_den, INT_MAX); - st->time_base.num = 1; - os->lastpts = - st->start_time = start_time; - } - } else if (!strncmp(buf, "fisbone", 8)) { - if (os->psize < 52) - return -1; - - target_idx = ogg_find_stream(ogg, AV_RL32(buf+12)); - start_granule = AV_RL64(buf+36); - if (target_idx >= 0 && start_granule != -1) { - ogg->streams[target_idx].lastpts = - s->streams[target_idx]->start_time = ogg_gptopts(s, target_idx, start_granule, NULL); - } - } - - return 1; -} - -const struct ogg_codec ff_skeleton_codec = { - .magic = "fishead", - .magicsize = 8, - .header = skeleton_header, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggparsespeex.c b/tizen/distrib/ffmpeg/libavformat/oggparsespeex.c deleted file mode 100644 index 936b37e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggparsespeex.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright (C) 2008 Reimar Döffinger - - 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 AUTHORS OR 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. -**/ - -#include -#include "libavutil/bswap.h" -#include "libavutil/avstring.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "oggdec.h" - -struct speex_params { - int final_packet_duration; - int seq; -}; - -static int speex_header(AVFormatContext *s, int idx) { - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct speex_params *spxp = os->private; - AVStream *st = s->streams[idx]; - uint8_t *p = os->buf + os->pstart; - - if (!spxp) { - spxp = av_mallocz(sizeof(*spxp)); - os->private = spxp; - } - - if (spxp->seq > 1) - return 0; - - if (spxp->seq == 0) { - int frames_per_packet; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_SPEEX; - - st->codec->sample_rate = AV_RL32(p + 36); - st->codec->channels = AV_RL32(p + 48); - - /* We treat the whole Speex packet as a single frame everywhere Speex - is handled in FFmpeg. This avoids the complexities of splitting - and joining individual Speex frames, which are not always - byte-aligned. */ - st->codec->frame_size = AV_RL32(p + 56); - frames_per_packet = AV_RL32(p + 64); - if (frames_per_packet) - st->codec->frame_size *= frames_per_packet; - - st->codec->extradata_size = os->psize; - st->codec->extradata = av_malloc(st->codec->extradata_size - + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(st->codec->extradata, p, st->codec->extradata_size); - - st->time_base.num = 1; - st->time_base.den = st->codec->sample_rate; - } else - ff_vorbis_comment(s, &st->metadata, p, os->psize); - - spxp->seq++; - return 1; -} - -static int ogg_page_packets(struct ogg_stream *os) -{ - int i; - int packets = 0; - for (i = 0; i < os->nsegs; i++) - if (os->segments[i] < 255) - packets++; - return packets; -} - -static int speex_packet(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct speex_params *spxp = os->private; - int packet_size = s->streams[idx]->codec->frame_size; - - if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE && - os->granule > 0) { - /* first packet of final page. we have to calculate the final packet - duration here because it is the only place we know the next-to-last - granule position. */ - spxp->final_packet_duration = os->granule - os->lastpts - - packet_size * (ogg_page_packets(os) - 1); - } - - if (!os->lastpts && os->granule > 0) - /* first packet */ - os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1); - else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs && - spxp->final_packet_duration) - /* final packet */ - os->pduration = spxp->final_packet_duration; - else - os->pduration = packet_size; - - return 0; -} - -const struct ogg_codec ff_speex_codec = { - .magic = "Speex ", - .magicsize = 8, - .header = speex_header, - .packet = speex_packet -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggparsetheora.c b/tizen/distrib/ffmpeg/libavformat/oggparsetheora.c deleted file mode 100644 index 2299f55..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggparsetheora.c +++ /dev/null @@ -1,152 +0,0 @@ -/** - Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi - - 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 AUTHORS OR 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. -**/ - -#include -#include "libavutil/bswap.h" -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "oggdec.h" - -struct theora_params { - int gpshift; - int gpmask; - unsigned version; -}; - -static int -theora_header (AVFormatContext * s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - struct theora_params *thp = os->private; - int cds = st->codec->extradata_size + os->psize + 2; - uint8_t *cdp; - - if(!(os->buf[os->pstart] & 0x80)) - return 0; - - if(!thp){ - thp = av_mallocz(sizeof(*thp)); - os->private = thp; - } - - if (os->buf[os->pstart] == 0x80) { - GetBitContext gb; - int width, height; - - init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - - skip_bits_long(&gb, 7*8); /* 0x80"theora" */ - - thp->version = get_bits_long(&gb, 24); - if (thp->version < 0x030100) - { - av_log(s, AV_LOG_ERROR, - "Too old or unsupported Theora (%x)\n", thp->version); - return -1; - } - - width = get_bits(&gb, 16) << 4; - height = get_bits(&gb, 16) << 4; - avcodec_set_dimensions(st->codec, width, height); - - if (thp->version >= 0x030400) - skip_bits(&gb, 100); - - if (thp->version >= 0x030200) { - width = get_bits_long(&gb, 24); - height = get_bits_long(&gb, 24); - if ( width <= st->codec->width && width > st->codec->width-16 - && height <= st->codec->height && height > st->codec->height-16) - avcodec_set_dimensions(st->codec, width, height); - - skip_bits(&gb, 16); - } - st->codec->time_base.den = get_bits_long(&gb, 32); - st->codec->time_base.num = get_bits_long(&gb, 32); - if (!(st->codec->time_base.num > 0 && st->codec->time_base.den > 0)) { - av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n"); - st->codec->time_base.num = 1; - st->codec->time_base.den = 25; - } - st->time_base = st->codec->time_base; - - st->sample_aspect_ratio.num = get_bits_long(&gb, 24); - st->sample_aspect_ratio.den = get_bits_long(&gb, 24); - - if (thp->version >= 0x030200) - skip_bits_long(&gb, 38); - if (thp->version >= 0x304000) - skip_bits(&gb, 2); - - thp->gpshift = get_bits(&gb, 5); - thp->gpmask = (1 << thp->gpshift) - 1; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_THEORA; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - - } else if (os->buf[os->pstart] == 0x83) { - ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8); - } - - st->codec->extradata = av_realloc (st->codec->extradata, - cds + FF_INPUT_BUFFER_PADDING_SIZE); - cdp = st->codec->extradata + st->codec->extradata_size; - *cdp++ = os->psize >> 8; - *cdp++ = os->psize & 0xff; - memcpy (cdp, os->buf + os->pstart, os->psize); - st->codec->extradata_size = cds; - - return 1; -} - -static uint64_t -theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts) -{ - struct ogg *ogg = ctx->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct theora_params *thp = os->private; - uint64_t iframe = gp >> thp->gpshift; - uint64_t pframe = gp & thp->gpmask; - - if (thp->version < 0x030201) - iframe++; - - if(!pframe) - os->pflags |= AV_PKT_FLAG_KEY; - - if (dts) - *dts = iframe + pframe; - - return iframe + pframe; -} - -const struct ogg_codec ff_theora_codec = { - .magic = "\200theora", - .magicsize = 7, - .header = theora_header, - .gptopts = theora_gptopts -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oggparsevorbis.c b/tizen/distrib/ffmpeg/libavformat/oggparsevorbis.c deleted file mode 100644 index 886ef52..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oggparsevorbis.c +++ /dev/null @@ -1,260 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - 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 AUTHORS OR 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. -**/ - -#include -#include "libavutil/avstring.h" -#include "libavutil/bswap.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "oggdec.h" - -static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val) -{ - int i, cnum, h, m, s, ms, keylen = strlen(key); - AVChapter *chapter = NULL; - - if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1) - return 0; - - if (keylen == 9) { - if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4) - return 0; - - ff_new_chapter(as, cnum, (AVRational){1,1000}, - ms + 1000*(s + 60*(m + 60*h)), - AV_NOPTS_VALUE, NULL); - av_free(val); - } else if (!strcmp(key+9, "NAME")) { - for(i = 0; i < as->nb_chapters; i++) - if (as->chapters[i]->id == cnum) { - chapter = as->chapters[i]; - break; - } - if (!chapter) - return 0; - - av_metadata_set2(&chapter->metadata, "title", val, - AV_METADATA_DONT_STRDUP_VAL); - } else - return 0; - - av_free(key); - return 1; -} - -int -ff_vorbis_comment(AVFormatContext * as, AVMetadata **m, const uint8_t *buf, int size) -{ - const uint8_t *p = buf; - const uint8_t *end = buf + size; - unsigned n, j; - int s; - - if (size < 8) /* must have vendor_length and user_comment_list_length */ - return -1; - - s = bytestream_get_le32(&p); - - if (end - p - 4 < s || s < 0) - return -1; - - p += s; - - n = bytestream_get_le32(&p); - - while (end - p >= 4 && n > 0) { - const char *t, *v; - int tl, vl; - - s = bytestream_get_le32(&p); - - if (end - p < s || s < 0) - break; - - t = p; - p += s; - n--; - - v = memchr(t, '=', s); - if (!v) - continue; - - tl = v - t; - vl = s - tl - 1; - v++; - - if (tl && vl) { - char *tt, *ct; - - tt = av_malloc(tl + 1); - ct = av_malloc(vl + 1); - if (!tt || !ct) { - av_freep(&tt); - av_freep(&ct); - av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n"); - continue; - } - - for (j = 0; j < tl; j++) - tt[j] = toupper(t[j]); - tt[tl] = 0; - - memcpy(ct, v, vl); - ct[vl] = 0; - - if (!ogm_chapter(as, tt, ct)) - av_metadata_set2(m, tt, ct, - AV_METADATA_DONT_STRDUP_KEY | - AV_METADATA_DONT_STRDUP_VAL); - } - } - - if (p != end) - av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p); - if (n > 0) - av_log(as, AV_LOG_INFO, - "truncated comment header, %i comments not found\n", n); - - return 0; -} - - -/** Parse the vorbis header - * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec - * [vorbis_version] = read 32 bits as unsigned integer | Not used - * [audio_channels] = read 8 bit integer as unsigned | Used - * [audio_sample_rate] = read 32 bits as unsigned integer | Used - * [bitrate_maximum] = read 32 bits as signed integer | Not used yet - * [bitrate_nominal] = read 32 bits as signed integer | Not used yet - * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate - * [blocksize_0] = read 4 bits as unsigned integer | Not Used - * [blocksize_1] = read 4 bits as unsigned integer | Not Used - * [framing_flag] = read one bit | Not Used - * */ - -struct oggvorbis_private { - unsigned int len[3]; - unsigned char *packet[3]; -}; - - -static unsigned int -fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv, - uint8_t **buf) -{ - int i,offset, len; - unsigned char *ptr; - - len = priv->len[0] + priv->len[1] + priv->len[2]; - ptr = *buf = av_mallocz(len + len/255 + 64); - - ptr[0] = 2; - offset = 1; - offset += av_xiphlacing(&ptr[offset], priv->len[0]); - offset += av_xiphlacing(&ptr[offset], priv->len[1]); - for (i = 0; i < 3; i++) { - memcpy(&ptr[offset], priv->packet[i], priv->len[i]); - offset += priv->len[i]; - av_freep(&priv->packet[i]); - } - *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE); - return offset; -} - - -static int -vorbis_header (AVFormatContext * s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - struct oggvorbis_private *priv; - int pkt_type = os->buf[os->pstart]; - - if (!(pkt_type & 1)) - return 0; - - if (!os->private) { - os->private = av_mallocz(sizeof(struct oggvorbis_private)); - if (!os->private) - return 0; - } - - if (os->psize < 1 || pkt_type > 5) - return -1; - - priv = os->private; - priv->len[pkt_type >> 1] = os->psize; - priv->packet[pkt_type >> 1] = av_mallocz(os->psize); - memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize); - if (os->buf[os->pstart] == 1) { - const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */ - unsigned blocksize, bs0, bs1; - - if (os->psize != 30) - return -1; - - if (bytestream_get_le32(&p) != 0) /* vorbis_version */ - return -1; - - st->codec->channels = bytestream_get_byte(&p); - st->codec->sample_rate = bytestream_get_le32(&p); - p += 4; // skip maximum bitrate - st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate - p += 4; // skip minimum bitrate - - blocksize = bytestream_get_byte(&p); - bs0 = blocksize & 15; - bs1 = blocksize >> 4; - - if (bs0 > bs1) - return -1; - if (bs0 < 6 || bs1 > 13) - return -1; - - if (bytestream_get_byte(&p) != 1) /* framing_flag */ - return -1; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_VORBIS; - - st->time_base.num = 1; - st->time_base.den = st->codec->sample_rate; - } else if (os->buf[os->pstart] == 3) { - if (os->psize > 8) - ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8); - } else { - st->codec->extradata_size = - fixup_vorbis_headers(s, priv, &st->codec->extradata); - } - - return 1; -} - -const struct ogg_codec ff_vorbis_codec = { - .magic = "\001vorbis", - .magicsize = 7, - .header = vorbis_header -}; diff --git a/tizen/distrib/ffmpeg/libavformat/oma.c b/tizen/distrib/ffmpeg/libavformat/oma.c deleted file mode 100644 index c12365e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/oma.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Sony OpenMG (OMA) demuxer - * - * Copyright (c) 2008 Maxim Poliakovski - * 2008 Benjamin Larsson - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * This is a demuxer for Sony OpenMG Music files - * - * Known file extensions: ".oma", "aa3" - * The format of such files consists of three parts: - * - "ea3" header carrying overall info and metadata. - * - "EA3" header is a Sony-specific header containing information about - * the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA), - * codec specific info (packet size, sample rate, channels and so on) - * and DRM related info (file encryption, content id). - * - Sound data organized in packets follow the EA3 header - * (can be encrypted using the Sony DRM!). - * - * LIMITATIONS: This version supports only plain (unencrypted) OMA files. - * If any DRM-protected (encrypted) file is encountered you will get the - * corresponding error message. Try to remove the encryption using any - * Sony software (for example SonicStage). - * CODEC SUPPORT: Only ATRAC3 codec is currently supported! - */ - -#include "avformat.h" -#include "libavutil/intreadwrite.h" -#include "raw.h" -#include "riff.h" - -#define EA3_HEADER_SIZE 96 - -enum { - OMA_CODECID_ATRAC3 = 0, - OMA_CODECID_ATRAC3P = 1, - OMA_CODECID_MP3 = 3, - OMA_CODECID_LPCM = 4, - OMA_CODECID_WMA = 5, -}; - -static const AVCodecTag codec_oma_tags[] = { - { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, - { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, - { CODEC_ID_MP3, OMA_CODECID_MP3 }, -}; - -static int oma_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - static const uint16_t srate_tab[6] = {320,441,480,882,960,0}; - int ret, ea3_taglen, EA3_pos, framesize, jsflag, samplerate; - uint32_t codec_params; - int16_t eid; - uint8_t buf[EA3_HEADER_SIZE]; - uint8_t *edata; - AVStream *st; - - ret = get_buffer(s->pb, buf, 10); - if (ret != 10) - return -1; - - if(!memcmp(buf, "ea3", 3)) { - ea3_taglen = ((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f); - - EA3_pos = ea3_taglen + 10; - if (buf[5] & 0x10) - EA3_pos += 10; - - url_fseek(s->pb, EA3_pos, SEEK_SET); - ret = get_buffer(s->pb, buf, EA3_HEADER_SIZE); - if (ret != EA3_HEADER_SIZE) - return -1; - } else { - ret = get_buffer(s->pb, buf + 10, EA3_HEADER_SIZE - 10); - EA3_pos = 0; - } - - if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) { - av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n"); - return -1; - } - - eid = AV_RB16(&buf[6]); - if (eid != -1 && eid != -128) { - av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid); - return -1; - } - - codec_params = AV_RB24(&buf[33]); - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->start_time = 0; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = buf[32]; - st->codec->codec_id = ff_codec_get_id(codec_oma_tags, st->codec->codec_tag); - - switch (buf[32]) { - case OMA_CODECID_ATRAC3: - samplerate = srate_tab[(codec_params >> 13) & 7]*100; - if (samplerate != 44100) - av_log(s, AV_LOG_ERROR, "Unsupported sample rate, send sample file to developers: %d\n", samplerate); - - framesize = (codec_params & 0x3FF) * 8; - jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */ - st->codec->channels = 2; - st->codec->sample_rate = samplerate; - st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; - - /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */ - st->codec->extradata_size = 14; - edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!edata) - return AVERROR(ENOMEM); - - st->codec->extradata = edata; - AV_WL16(&edata[0], 1); // always 1 - AV_WL32(&edata[2], samplerate); // samples rate - AV_WL16(&edata[6], jsflag); // coding mode - AV_WL16(&edata[8], jsflag); // coding mode - AV_WL16(&edata[10], 1); // always 1 - // AV_WL16(&edata[12], 0); // always 0 - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - break; - case OMA_CODECID_ATRAC3P: - st->codec->channels = (codec_params >> 10) & 7; - framesize = ((codec_params & 0x3FF) * 8) + 8; - st->codec->sample_rate = srate_tab[(codec_params >> 13) & 7]*100; - st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n"); - break; - case OMA_CODECID_MP3: - st->need_parsing = AVSTREAM_PARSE_FULL; - framesize = 1024; - break; - default: - av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]); - return -1; - break; - } - - st->codec->block_align = framesize; - url_fseek(s->pb, EA3_pos + EA3_HEADER_SIZE, SEEK_SET); - - return 0; -} - - -static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); - - pkt->stream_index = 0; - if (ret <= 0) - return AVERROR(EIO); - - return ret; -} - -static int oma_read_probe(AVProbeData *p) -{ - if (!memcmp(p->buf, ((const uint8_t[]){'e', 'a', '3', 3, 0}), 5) || - (!memcmp(p->buf, "EA3", 3) && - !p->buf[4] && p->buf[5] == EA3_HEADER_SIZE)) - return AVPROBE_SCORE_MAX; - else - return 0; -} - - -AVInputFormat oma_demuxer = { - "oma", - NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), - 0, - oma_read_probe, - oma_read_header, - oma_read_packet, - 0, - pcm_read_seek, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "oma,aa3", - .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0}, -}; - diff --git a/tizen/distrib/ffmpeg/libavformat/options.c b/tizen/distrib/ffmpeg/libavformat/options.c deleted file mode 100644 index 0c1ac2d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/options.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "libavcodec/opt.h" - -/** - * @file - * Options definition for AVFormatContext. - */ - -static const char* format_to_name(void* ptr) -{ - AVFormatContext* fc = (AVFormatContext*) ptr; - if(fc->iformat) return fc->iformat->name; - else if(fc->oformat) return fc->oformat->name; - else return "NULL"; -} - -#define OFFSET(x) offsetof(AVFormatContext,x) -#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C -//these names are too long to be readable -#define E AV_OPT_FLAG_ENCODING_PARAM -#define D AV_OPT_FLAG_DECODING_PARAM - -static const AVOption options[]={ -{"probesize", "set probing size", OFFSET(probesize), FF_OPT_TYPE_INT, 5000000, 32, INT_MAX, D}, -{"muxrate", "set mux rate", OFFSET(mux_rate), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E}, -{"packetsize", "set packet size", OFFSET(packet_size), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E}, -{"fflags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, INT_MIN, INT_MAX, D|E, "fflags"}, -{"ignidx", "ignore index", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_IGNIDX, INT_MIN, INT_MAX, D, "fflags"}, -{"genpts", "generate pts", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_GENPTS, INT_MIN, INT_MAX, D, "fflags"}, -{"nofillin", "do not fill in missing values that can be exactly calculated", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_NOFILLIN, INT_MIN, INT_MAX, D, "fflags"}, -{"noparse", "disable AVParsers, this needs nofillin too", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_NOPARSE, INT_MIN, INT_MAX, D, "fflags"}, -{"igndts", "ingore dts", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_IGNDTS, INT_MIN, INT_MAX, D, "fflags"}, -{"rtphint", "add rtp hinting", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_RTP_HINT, INT_MIN, INT_MAX, E, "fflags"}, -#if LIBAVFORMAT_VERSION_INT < (53<<16) -{"track", " set the track number", OFFSET(track), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E}, -{"year", "set the year", OFFSET(year), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, E}, -#endif -{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, 5*AV_TIME_BASE, 0, INT_MAX, D}, -{"cryptokey", "decryption key", OFFSET(key), FF_OPT_TYPE_BINARY, 0, 0, 0, D}, -{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), FF_OPT_TYPE_INT, 1<<20, 0, INT_MAX, D}, -{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), FF_OPT_TYPE_INT, 3041280, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */ -{"fdebug", "print specific debug info", OFFSET(debug), FF_OPT_TYPE_FLAGS, DEFAULT, 0, INT_MAX, E|D, "fdebug"}, -{"ts", NULL, 0, FF_OPT_TYPE_CONST, FF_FDEBUG_TS, INT_MIN, INT_MAX, E|D, "fdebug"}, -{NULL}, -}; - -#undef E -#undef D -#undef DEFAULT - -static const AVClass av_format_context_class = { "AVFormatContext", format_to_name, options, LIBAVUTIL_VERSION_INT }; - -static void avformat_get_context_defaults(AVFormatContext *s) -{ - memset(s, 0, sizeof(AVFormatContext)); - - s->av_class = &av_format_context_class; - - av_opt_set_defaults(s); -} - -AVFormatContext *avformat_alloc_context(void) -{ - AVFormatContext *ic; - ic = av_malloc(sizeof(AVFormatContext)); - if (!ic) return ic; - avformat_get_context_defaults(ic); - ic->av_class = &av_format_context_class; - return ic; -} - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -AVFormatContext *av_alloc_format_context(void) -{ - return avformat_alloc_context(); -} -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/os_support.c b/tizen/distrib/ffmpeg/libavformat/os_support.c deleted file mode 100644 index 2786303..0000000 --- a/tizen/distrib/ffmpeg/libavformat/os_support.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Various utilities for ffmpeg system - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * copyright (c) 2002 Francois Revol - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* needed by inet_aton() */ -#define _SVID_SOURCE -#define _DARWIN_C_SOURCE - -#include "config.h" -#include "avformat.h" -#include -#include -#include -#include "os_support.h" - -#if CONFIG_NETWORK -#if !HAVE_POLL_H -#if HAVE_WINSOCK2_H -#include -#elif HAVE_SYS_SELECT_H -#include -#endif -#endif - -#include "network.h" - -#if !HAVE_INET_ATON -#include -#include - -int ff_inet_aton (const char * str, struct in_addr * add) -{ - unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0; - - if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4) - return 0; - - if (!add1 || (add1|add2|add3|add4) > 255) return 0; - - add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4); - - return 1; -} -#else -int ff_inet_aton (const char * str, struct in_addr * add) -{ - return inet_aton(str, add); -} -#endif /* !HAVE_INET_ATON */ - -#if !HAVE_GETADDRINFO -int ff_getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, struct addrinfo **res) -{ - struct hostent *h = NULL; - struct addrinfo *ai; - struct sockaddr_in *sin; - -#if HAVE_WINSOCK2_H - int (WSAAPI *win_getaddrinfo)(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res); - HMODULE ws2mod = GetModuleHandle("ws2_32.dll"); - win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo"); - if (win_getaddrinfo) - return win_getaddrinfo(node, service, hints, res); -#endif - - *res = NULL; - sin = av_mallocz(sizeof(struct sockaddr_in)); - if (!sin) - return EAI_FAIL; - sin->sin_family = AF_INET; - - if (node) { - if (!ff_inet_aton(node, &sin->sin_addr)) { - if (hints && (hints->ai_flags & AI_NUMERICHOST)) { - av_free(sin); - return EAI_FAIL; - } - h = gethostbyname(node); - if (!h) { - av_free(sin); - return EAI_FAIL; - } - memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr)); - } - } else { - if (hints && (hints->ai_flags & AI_PASSIVE)) { - sin->sin_addr.s_addr = INADDR_ANY; - } else - sin->sin_addr.s_addr = INADDR_LOOPBACK; - } - - /* Note: getaddrinfo allows service to be a string, which - * should be looked up using getservbyname. */ - if (service) - sin->sin_port = htons(atoi(service)); - - ai = av_mallocz(sizeof(struct addrinfo)); - if (!ai) { - av_free(sin); - return EAI_FAIL; - } - - *res = ai; - ai->ai_family = AF_INET; - ai->ai_socktype = hints ? hints->ai_socktype : 0; - switch (ai->ai_socktype) { - case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break; - case SOCK_DGRAM: ai->ai_protocol = IPPROTO_UDP; break; - default: ai->ai_protocol = 0; break; - } - - ai->ai_addr = (struct sockaddr *)sin; - ai->ai_addrlen = sizeof(struct sockaddr_in); - if (hints && (hints->ai_flags & AI_CANONNAME)) - ai->ai_canonname = h ? av_strdup(h->h_name) : NULL; - - ai->ai_next = NULL; - return 0; -} - -void ff_freeaddrinfo(struct addrinfo *res) -{ -#if HAVE_WINSOCK2_H - void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res); - HMODULE ws2mod = GetModuleHandle("ws2_32.dll"); - win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res)) - GetProcAddress(ws2mod, "freeaddrinfo"); - if (win_freeaddrinfo) { - win_freeaddrinfo(res); - return; - } -#endif - - av_free(res->ai_canonname); - av_free(res->ai_addr); - av_free(res); -} - -int ff_getnameinfo(const struct sockaddr *sa, int salen, - char *host, int hostlen, - char *serv, int servlen, int flags) -{ - const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; - -#if HAVE_WINSOCK2_H - int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen, - char *host, DWORD hostlen, - char *serv, DWORD servlen, int flags); - HMODULE ws2mod = GetModuleHandle("ws2_32.dll"); - win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo"); - if (win_getnameinfo) - return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); -#endif - - if (sa->sa_family != AF_INET) - return EAI_FAMILY; - if (!host && !serv) - return EAI_NONAME; - - if (host && hostlen > 0) { - struct hostent *ent = NULL; - uint32_t a; - if (!(flags & NI_NUMERICHOST)) - ent = gethostbyaddr((const char *)&sin->sin_addr, - sizeof(sin->sin_addr), AF_INET); - - if (ent) { - snprintf(host, hostlen, "%s", ent->h_name); - } else if (flags & NI_NAMERQD) { - return EAI_NONAME; - } else { - a = ntohl(sin->sin_addr.s_addr); - snprintf(host, hostlen, "%d.%d.%d.%d", - ((a >> 24) & 0xff), ((a >> 16) & 0xff), - ((a >> 8) & 0xff), ( a & 0xff)); - } - } - - if (serv && servlen > 0) { - struct servent *ent = NULL; - if (!(flags & NI_NUMERICSERV)) - ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp"); - - if (ent) { - snprintf(serv, servlen, "%s", ent->s_name); - } else - snprintf(serv, servlen, "%d", ntohs(sin->sin_port)); - } - - return 0; -} - -const char *ff_gai_strerror(int ecode) -{ - switch(ecode) { - case EAI_FAIL : return "A non-recoverable error occurred"; - case EAI_FAMILY : return "The address family was not recognized or the address length was invalid for the specified family"; - case EAI_NONAME : return "The name does not resolve for the supplied parameters"; - } - - return "Unknown error"; -} -#endif - -int ff_socket_nonblock(int socket, int enable) -{ -#if HAVE_WINSOCK2_H - return ioctlsocket(socket, FIONBIO, &enable); -#else - if (enable) - return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK); - else - return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK); -#endif -} -#endif /* CONFIG_NETWORK */ - -#if CONFIG_FFSERVER -#if !HAVE_POLL_H -int poll(struct pollfd *fds, nfds_t numfds, int timeout) -{ - fd_set read_set; - fd_set write_set; - fd_set exception_set; - nfds_t i; - int n; - int rc; - -#if HAVE_WINSOCK2_H - if (numfds >= FD_SETSIZE) { - errno = EINVAL; - return -1; - } -#endif - - FD_ZERO(&read_set); - FD_ZERO(&write_set); - FD_ZERO(&exception_set); - - n = -1; - for(i = 0; i < numfds; i++) { - if (fds[i].fd < 0) - continue; -#if !HAVE_WINSOCK2_H - if (fds[i].fd >= FD_SETSIZE) { - errno = EINVAL; - return -1; - } -#endif - - if (fds[i].events & POLLIN) FD_SET(fds[i].fd, &read_set); - if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set); - if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set); - - if (fds[i].fd > n) - n = fds[i].fd; - }; - - if (n == -1) - /* Hey!? Nothing to poll, in fact!!! */ - return 0; - - if (timeout < 0) - rc = select(n+1, &read_set, &write_set, &exception_set, NULL); - else { - struct timeval tv; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = 1000 * (timeout % 1000); - rc = select(n+1, &read_set, &write_set, &exception_set, &tv); - }; - - if (rc < 0) - return rc; - - for(i = 0; i < (nfds_t) n; i++) { - fds[i].revents = 0; - - if (FD_ISSET(fds[i].fd, &read_set)) fds[i].revents |= POLLIN; - if (FD_ISSET(fds[i].fd, &write_set)) fds[i].revents |= POLLOUT; - if (FD_ISSET(fds[i].fd, &exception_set)) fds[i].revents |= POLLERR; - }; - - return rc; -} -#endif /* HAVE_POLL_H */ -#endif /* CONFIG_FFSERVER */ - diff --git a/tizen/distrib/ffmpeg/libavformat/os_support.h b/tizen/distrib/ffmpeg/libavformat/os_support.h deleted file mode 100644 index e90f2c2..0000000 --- a/tizen/distrib/ffmpeg/libavformat/os_support.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * various utilities for ffmpeg system - * copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_OS_SUPPORT_H -#define AVFORMAT_OS_SUPPORT_H - -/** - * @file - * miscellaneous OS support macros and functions. - */ - -#include "config.h" - -#if defined(__MINGW32__) && !defined(__MINGW32CE__) -# include -# define lseek(f,p,w) _lseeki64((f), (p), (w)) -#endif /* defined(__MINGW32__) && !defined(__MINGW32CE__) */ - -static inline int is_dos_path(const char *path) -{ -#if HAVE_DOS_PATHS - if (path[0] && path[1] == ':') - return 1; -#endif - return 0; -} - -#ifdef __BEOS__ -# include -# include - /* not net_server ? */ -# include - /* R5 didn't have usleep, fake it. Haiku and Zeta has it now. */ -# if B_BEOS_VERSION <= B_BEOS_VERSION_5 -# include - /* doesn't set errno but that's enough */ -# define usleep(t) snooze((bigtime_t)(t)) -# endif -# ifndef SA_RESTART -# warning SA_RESTART not implemented; ffserver might misbehave. -# define SA_RESTART 0 -# endif -#endif - -#if CONFIG_NETWORK -#if !HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - -/* most of the time closing a socket is just closing an fd */ -#if !HAVE_CLOSESOCKET -#define closesocket close -#endif - -#if CONFIG_FFSERVER -#if !HAVE_POLL_H -typedef unsigned long nfds_t; - -struct pollfd { - int fd; - short events; /* events to look for */ - short revents; /* events that occurred */ -}; - -/* events & revents */ -#define POLLIN 0x0001 /* any readable data available */ -#define POLLOUT 0x0002 /* file descriptor is writeable */ -#define POLLRDNORM POLLIN -#define POLLWRNORM POLLOUT -#define POLLRDBAND 0x0008 /* priority readable data */ -#define POLLWRBAND 0x0010 /* priority data can be written */ -#define POLLPRI 0x0020 /* high priority readable data */ - -/* revents only */ -#define POLLERR 0x0004 /* errors pending */ -#define POLLHUP 0x0080 /* disconnected */ -#define POLLNVAL 0x1000 /* invalid file descriptor */ - - -int poll(struct pollfd *fds, nfds_t numfds, int timeout); -#endif /* HAVE_POLL_H */ -#endif /* CONFIG_FFSERVER */ -#endif /* CONFIG_NETWORK */ - -#endif /* AVFORMAT_OS_SUPPORT_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/output-example.c b/tizen/distrib/ffmpeg/libavformat/output-example.c deleted file mode 100644 index dd61cfe..0000000 --- a/tizen/distrib/ffmpeg/libavformat/output-example.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Libavformat API example: Output a media file in any supported - * libavformat format. The default codecs are used. - * - * Copyright (c) 2003 Fabrice Bellard - * - * 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 AUTHORS OR 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. - */ -#include -#include -#include -#include - -#include "libavformat/avformat.h" -#include "libswscale/swscale.h" - -#undef exit - -/* 5 seconds stream duration */ -#define STREAM_DURATION 5.0 -#define STREAM_FRAME_RATE 25 /* 25 images/s */ -#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE)) -#define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */ - -static int sws_flags = SWS_BICUBIC; - -/**************************************************************/ -/* audio output */ - -float t, tincr, tincr2; -int16_t *samples; -uint8_t *audio_outbuf; -int audio_outbuf_size; -int audio_input_frame_size; - -/* - * add an audio output stream - */ -static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id) -{ - AVCodecContext *c; - AVStream *st; - - st = av_new_stream(oc, 1); - if (!st) { - fprintf(stderr, "Could not alloc stream\n"); - exit(1); - } - - c = st->codec; - c->codec_id = codec_id; - c->codec_type = AVMEDIA_TYPE_AUDIO; - - /* put sample parameters */ - c->bit_rate = 64000; - c->sample_rate = 44100; - c->channels = 2; - - // some formats want stream headers to be separate - if(oc->oformat->flags & AVFMT_GLOBALHEADER) - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - - return st; -} - -static void open_audio(AVFormatContext *oc, AVStream *st) -{ - AVCodecContext *c; - AVCodec *codec; - - c = st->codec; - - /* find the audio encoder */ - codec = avcodec_find_encoder(c->codec_id); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - /* open it */ - if (avcodec_open(c, codec) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - /* init signal generator */ - t = 0; - tincr = 2 * M_PI * 110.0 / c->sample_rate; - /* increment frequency by 110 Hz per second */ - tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate; - - audio_outbuf_size = 10000; - audio_outbuf = av_malloc(audio_outbuf_size); - - /* ugly hack for PCM codecs (will be removed ASAP with new PCM - support to compute the input frame size in samples */ - if (c->frame_size <= 1) { - audio_input_frame_size = audio_outbuf_size / c->channels; - switch(st->codec->codec_id) { - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - audio_input_frame_size >>= 1; - break; - default: - break; - } - } else { - audio_input_frame_size = c->frame_size; - } - samples = av_malloc(audio_input_frame_size * 2 * c->channels); -} - -/* prepare a 16 bit dummy audio frame of 'frame_size' samples and - 'nb_channels' channels */ -static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels) -{ - int j, i, v; - int16_t *q; - - q = samples; - for(j=0;jcodec; - - get_audio_frame(samples, audio_input_frame_size, c->channels); - - pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples); - - if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base); - pkt.flags |= AV_PKT_FLAG_KEY; - pkt.stream_index= st->index; - pkt.data= audio_outbuf; - - /* write the compressed frame in the media file */ - if (av_interleaved_write_frame(oc, &pkt) != 0) { - fprintf(stderr, "Error while writing audio frame\n"); - exit(1); - } -} - -static void close_audio(AVFormatContext *oc, AVStream *st) -{ - avcodec_close(st->codec); - - av_free(samples); - av_free(audio_outbuf); -} - -/**************************************************************/ -/* video output */ - -AVFrame *picture, *tmp_picture; -uint8_t *video_outbuf; -int frame_count, video_outbuf_size; - -/* add a video output stream */ -static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id) -{ - AVCodecContext *c; - AVStream *st; - - st = av_new_stream(oc, 0); - if (!st) { - fprintf(stderr, "Could not alloc stream\n"); - exit(1); - } - - c = st->codec; - c->codec_id = codec_id; - c->codec_type = AVMEDIA_TYPE_VIDEO; - - /* put sample parameters */ - c->bit_rate = 400000; - /* resolution must be a multiple of two */ - c->width = 352; - c->height = 288; - /* time base: 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. */ - c->time_base.den = STREAM_FRAME_RATE; - c->time_base.num = 1; - c->gop_size = 12; /* emit one intra frame every twelve frames at most */ - c->pix_fmt = STREAM_PIX_FMT; - if (c->codec_id == CODEC_ID_MPEG2VIDEO) { - /* just for testing, we also add B frames */ - c->max_b_frames = 2; - } - if (c->codec_id == CODEC_ID_MPEG1VIDEO){ - /* Needed to avoid using macroblocks in which some coeffs overflow. - This does not happen with normal video, it just happens here as - the motion of the chroma plane does not match the luma plane. */ - c->mb_decision=2; - } - // some formats want stream headers to be separate - if(oc->oformat->flags & AVFMT_GLOBALHEADER) - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - - return st; -} - -static AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height) -{ - AVFrame *picture; - uint8_t *picture_buf; - int size; - - picture = avcodec_alloc_frame(); - if (!picture) - return NULL; - size = avpicture_get_size(pix_fmt, width, height); - picture_buf = av_malloc(size); - if (!picture_buf) { - av_free(picture); - return NULL; - } - avpicture_fill((AVPicture *)picture, picture_buf, - pix_fmt, width, height); - return picture; -} - -static void open_video(AVFormatContext *oc, AVStream *st) -{ - AVCodec *codec; - AVCodecContext *c; - - c = st->codec; - - /* find the video encoder */ - codec = avcodec_find_encoder(c->codec_id); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - /* open the codec */ - if (avcodec_open(c, codec) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - video_outbuf = NULL; - if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { - /* allocate output buffer */ - /* XXX: API change will be done */ - /* buffers passed into lav* can be allocated any way you prefer, - as long as they're aligned enough for the architecture, and - they're freed appropriately (such as using av_free for buffers - allocated with av_malloc) */ - video_outbuf_size = 200000; - video_outbuf = av_malloc(video_outbuf_size); - } - - /* allocate the encoded raw picture */ - picture = alloc_picture(c->pix_fmt, c->width, c->height); - if (!picture) { - fprintf(stderr, "Could not allocate picture\n"); - exit(1); - } - - /* if the output format is not YUV420P, then a temporary YUV420P - picture is needed too. It is then converted to the required - output format */ - tmp_picture = NULL; - if (c->pix_fmt != PIX_FMT_YUV420P) { - tmp_picture = alloc_picture(PIX_FMT_YUV420P, c->width, c->height); - if (!tmp_picture) { - fprintf(stderr, "Could not allocate temporary picture\n"); - exit(1); - } - } -} - -/* prepare a dummy image */ -static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height) -{ - int x, y, i; - - i = frame_index; - - /* Y */ - for(y=0;ydata[0][y * pict->linesize[0] + x] = x + y + i * 3; - } - } - - /* Cb and Cr */ - for(y=0;ydata[1][y * pict->linesize[1] + x] = 128 + y + i * 2; - pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5; - } - } -} - -static void write_video_frame(AVFormatContext *oc, AVStream *st) -{ - int out_size, ret; - AVCodecContext *c; - static struct SwsContext *img_convert_ctx; - - c = st->codec; - - if (frame_count >= STREAM_NB_FRAMES) { - /* no more frame to compress. The codec has a latency of a few - frames if using B frames, so we get the last frames by - passing the same picture again */ - } else { - if (c->pix_fmt != PIX_FMT_YUV420P) { - /* as we only generate a YUV420P picture, we must convert it - to the codec pixel format if needed */ - if (img_convert_ctx == NULL) { - img_convert_ctx = sws_getContext(c->width, c->height, - PIX_FMT_YUV420P, - c->width, c->height, - c->pix_fmt, - sws_flags, NULL, NULL, NULL); - if (img_convert_ctx == NULL) { - fprintf(stderr, "Cannot initialize the conversion context\n"); - exit(1); - } - } - fill_yuv_image(tmp_picture, frame_count, c->width, c->height); - sws_scale(img_convert_ctx, tmp_picture->data, tmp_picture->linesize, - 0, c->height, picture->data, picture->linesize); - } else { - fill_yuv_image(picture, frame_count, c->width, c->height); - } - } - - - if (oc->oformat->flags & AVFMT_RAWPICTURE) { - /* raw video case. The API will change slightly in the near - futur for that */ - AVPacket pkt; - av_init_packet(&pkt); - - pkt.flags |= AV_PKT_FLAG_KEY; - pkt.stream_index= st->index; - pkt.data= (uint8_t *)picture; - pkt.size= sizeof(AVPicture); - - ret = av_interleaved_write_frame(oc, &pkt); - } else { - /* encode the image */ - out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture); - /* if zero size, it means the image was buffered */ - if (out_size > 0) { - AVPacket pkt; - av_init_packet(&pkt); - - if (c->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base); - if(c->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - pkt.stream_index= st->index; - pkt.data= video_outbuf; - pkt.size= out_size; - - /* write the compressed frame in the media file */ - ret = av_interleaved_write_frame(oc, &pkt); - } else { - ret = 0; - } - } - if (ret != 0) { - fprintf(stderr, "Error while writing video frame\n"); - exit(1); - } - frame_count++; -} - -static void close_video(AVFormatContext *oc, AVStream *st) -{ - avcodec_close(st->codec); - av_free(picture->data[0]); - av_free(picture); - if (tmp_picture) { - av_free(tmp_picture->data[0]); - av_free(tmp_picture); - } - av_free(video_outbuf); -} - -/**************************************************************/ -/* media file output */ - -int main(int argc, char **argv) -{ - const char *filename; - AVOutputFormat *fmt; - AVFormatContext *oc; - AVStream *audio_st, *video_st; - double audio_pts, video_pts; - int i; - - /* initialize libavcodec, and register all codecs and formats */ - av_register_all(); - - if (argc != 2) { - printf("usage: %s output_file\n" - "API example program to output a media file with libavformat.\n" - "The output format is automatically guessed according to the file extension.\n" - "Raw images can also be output by using '%%d' in the filename\n" - "\n", argv[0]); - exit(1); - } - - filename = argv[1]; - - /* auto detect the output format from the name. default is - mpeg. */ - fmt = av_guess_format(NULL, filename, NULL); - if (!fmt) { - printf("Could not deduce output format from file extension: using MPEG.\n"); - fmt = av_guess_format("mpeg", NULL, NULL); - } - if (!fmt) { - fprintf(stderr, "Could not find suitable output format\n"); - exit(1); - } - - /* allocate the output media context */ - oc = avformat_alloc_context(); - if (!oc) { - fprintf(stderr, "Memory error\n"); - exit(1); - } - oc->oformat = fmt; - snprintf(oc->filename, sizeof(oc->filename), "%s", filename); - - /* add the audio and video streams using the default format codecs - and initialize the codecs */ - video_st = NULL; - audio_st = NULL; - if (fmt->video_codec != CODEC_ID_NONE) { - video_st = add_video_stream(oc, fmt->video_codec); - } - if (fmt->audio_codec != CODEC_ID_NONE) { - audio_st = add_audio_stream(oc, fmt->audio_codec); - } - - /* set the output parameters (must be done even if no - parameters). */ - if (av_set_parameters(oc, NULL) < 0) { - fprintf(stderr, "Invalid output format parameters\n"); - exit(1); - } - - dump_format(oc, 0, filename, 1); - - /* now that all the parameters are set, we can open the audio and - video codecs and allocate the necessary encode buffers */ - if (video_st) - open_video(oc, video_st); - if (audio_st) - open_audio(oc, audio_st); - - /* open the output file, if needed */ - if (!(fmt->flags & AVFMT_NOFILE)) { - if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) { - fprintf(stderr, "Could not open '%s'\n", filename); - exit(1); - } - } - - /* write the stream header, if any */ - av_write_header(oc); - - for(;;) { - /* compute current audio and video time */ - if (audio_st) - audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den; - else - audio_pts = 0.0; - - if (video_st) - video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den; - else - video_pts = 0.0; - - if ((!audio_st || audio_pts >= STREAM_DURATION) && - (!video_st || video_pts >= STREAM_DURATION)) - break; - - /* write interleaved audio and video frames */ - if (!video_st || (video_st && audio_st && audio_pts < video_pts)) { - write_audio_frame(oc, audio_st); - } else { - write_video_frame(oc, video_st); - } - } - - /* write the trailer, if any. the trailer must be written - * before you close the CodecContexts open when you wrote the - * header; otherwise write_trailer may try to use memory that - * was freed on av_codec_close() */ - av_write_trailer(oc); - - /* close each codec */ - if (video_st) - close_video(oc, video_st); - if (audio_st) - close_audio(oc, audio_st); - - /* free the streams */ - for(i = 0; i < oc->nb_streams; i++) { - av_freep(&oc->streams[i]->codec); - av_freep(&oc->streams[i]); - } - - if (!(fmt->flags & AVFMT_NOFILE)) { - /* close the output file */ - url_fclose(oc->pb); - } - - /* free the stream */ - av_free(oc); - - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavformat/psxstr.c b/tizen/distrib/ffmpeg/libavformat/psxstr.c deleted file mode 100644 index 347c26e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/psxstr.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Sony Playstation (PSX) STR File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * PSX STR file demuxer - * by Mike Melanson (melanson@pcisys.net) - * This module handles streams that have been ripped from Sony Playstation - * CD games. This demuxer can handle either raw STR files (which are just - * concatenations of raw compact disc sectors) or STR files with 0x2C-byte - * RIFF headers, followed by CD sectors. - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define RIFF_TAG MKTAG('R', 'I', 'F', 'F') -#define CDXA_TAG MKTAG('C', 'D', 'X', 'A') - -#define RAW_CD_SECTOR_SIZE 2352 -#define RAW_CD_SECTOR_DATA_SIZE 2304 -#define VIDEO_DATA_CHUNK_SIZE 0x7E0 -#define VIDEO_DATA_HEADER_SIZE 0x38 -#define RIFF_HEADER_SIZE 0x2C - -#define CDXA_TYPE_MASK 0x0E -#define CDXA_TYPE_DATA 0x08 -#define CDXA_TYPE_AUDIO 0x04 -#define CDXA_TYPE_VIDEO 0x02 - -#define STR_MAGIC (0x80010160) - -typedef struct StrChannel { - /* video parameters */ - int video_stream_index; - AVPacket tmp_pkt; - - /* audio parameters */ - int audio_stream_index; -} StrChannel; - -typedef struct StrDemuxContext { - - /* a STR file can contain up to 32 channels of data */ - StrChannel channels[32]; -} StrDemuxContext; - -static const char sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00}; - -static int str_probe(AVProbeData *p) -{ - uint8_t *sector= p->buf; - - if (p->buf_size < RAW_CD_SECTOR_SIZE) - return 0; - - if ((AV_RL32(&p->buf[0]) == RIFF_TAG) && - (AV_RL32(&p->buf[8]) == CDXA_TAG)) { - - /* RIFF header seen; skip 0x2C bytes */ - sector += RIFF_HEADER_SIZE; - } - - /* look for CD sync header (00, 0xFF x 10, 00) */ - if (memcmp(sector,sync_header,sizeof(sync_header))) - return 0; - - if(sector[0x11] >= 32) - return 0; - if( (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_VIDEO - && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_AUDIO - && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_DATA) - return 0; - - /* MPEG files (like those ripped from VCDs) can also look like this; - * only return half certainty */ - return 50; -} - -static int str_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - StrDemuxContext *str = s->priv_data; - unsigned char sector[RAW_CD_SECTOR_SIZE]; - int start; - int i; - - /* skip over any RIFF header */ - if (get_buffer(pb, sector, RIFF_HEADER_SIZE) != RIFF_HEADER_SIZE) - return AVERROR(EIO); - if (AV_RL32(§or[0]) == RIFF_TAG) - start = RIFF_HEADER_SIZE; - else - start = 0; - - url_fseek(pb, start, SEEK_SET); - - for(i=0; i<32; i++){ - str->channels[i].video_stream_index= - str->channels[i].audio_stream_index= -1; - } - - s->ctx_flags |= AVFMTCTX_NOHEADER; - - return 0; -} - -static int str_read_packet(AVFormatContext *s, - AVPacket *ret_pkt) -{ - ByteIOContext *pb = s->pb; - StrDemuxContext *str = s->priv_data; - unsigned char sector[RAW_CD_SECTOR_SIZE]; - int channel; - AVPacket *pkt; - AVStream *st; - - while (1) { - - if (get_buffer(pb, sector, RAW_CD_SECTOR_SIZE) != RAW_CD_SECTOR_SIZE) - return AVERROR(EIO); - - channel = sector[0x11]; - if (channel >= 32) - return AVERROR_INVALIDDATA; - - switch (sector[0x12] & CDXA_TYPE_MASK) { - - case CDXA_TYPE_DATA: - case CDXA_TYPE_VIDEO: - { - - int current_sector = AV_RL16(§or[0x1C]); - int sector_count = AV_RL16(§or[0x1E]); - int frame_size = AV_RL32(§or[0x24]); - - if(!( frame_size>=0 - && current_sector < sector_count - && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){ - av_log(s, AV_LOG_ERROR, "Invalid parameters %d %d %d\n", current_sector, sector_count, frame_size); - break; - } - - if(str->channels[channel].video_stream_index < 0){ - /* allocate a new AVStream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 64, 1, 15); - - str->channels[channel].video_stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MDEC; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = AV_RL16(§or[0x28]); - st->codec->height = AV_RL16(§or[0x2A]); - } - - /* if this is the first sector of the frame, allocate a pkt */ - pkt = &str->channels[channel].tmp_pkt; - - if(pkt->size != sector_count*VIDEO_DATA_CHUNK_SIZE){ - if(pkt->data) - av_log(s, AV_LOG_ERROR, "missmatching sector_count\n"); - av_free_packet(pkt); - if (av_new_packet(pkt, sector_count*VIDEO_DATA_CHUNK_SIZE)) - return AVERROR(EIO); - - pkt->pos= url_ftell(pb) - RAW_CD_SECTOR_SIZE; - pkt->stream_index = - str->channels[channel].video_stream_index; - } - - memcpy(pkt->data + current_sector*VIDEO_DATA_CHUNK_SIZE, - sector + VIDEO_DATA_HEADER_SIZE, - VIDEO_DATA_CHUNK_SIZE); - - if (current_sector == sector_count-1) { - pkt->size= frame_size; - *ret_pkt = *pkt; - pkt->data= NULL; - pkt->size= -1; - return 0; - } - - } - break; - - case CDXA_TYPE_AUDIO: - if(str->channels[channel].audio_stream_index < 0){ - int fmt = sector[0x13]; - /* allocate a new AVStream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - str->channels[channel].audio_stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ADPCM_XA; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->channels = (fmt&1)?2:1; - st->codec->sample_rate = (fmt&4)?18900:37800; - // st->codec->bit_rate = 0; //FIXME; - st->codec->block_align = 128; - - av_set_pts_info(st, 64, 128, st->codec->sample_rate); - } - pkt = ret_pkt; - if (av_new_packet(pkt, 2304)) - return AVERROR(EIO); - memcpy(pkt->data,sector+24,2304); - - pkt->stream_index = - str->channels[channel].audio_stream_index; - return 0; - break; - default: - av_log(s, AV_LOG_WARNING, "Unknown sector type %02X\n", sector[0x12]); - /* drop the sector and move on */ - break; - } - - if (url_feof(pb)) - return AVERROR(EIO); - } -} - -static int str_read_close(AVFormatContext *s) -{ - StrDemuxContext *str = s->priv_data; - int i; - for(i=0; i<32; i++){ - if(str->channels[i].tmp_pkt.data) - av_free_packet(&str->channels[i].tmp_pkt); - } - - return 0; -} - -AVInputFormat str_demuxer = { - "psxstr", - NULL_IF_CONFIG_SMALL("Sony Playstation STR format"), - sizeof(StrDemuxContext), - str_probe, - str_read_header, - str_read_packet, - str_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/pva.c b/tizen/distrib/ffmpeg/libavformat/pva.c deleted file mode 100644 index abbc6f1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/pva.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * TechnoTrend PVA (.pva) demuxer - * Copyright (c) 2007, 2008 Ivo van Poorten - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "mpeg.h" - -#define PVA_MAX_PAYLOAD_LENGTH 0x17f8 -#define PVA_VIDEO_PAYLOAD 0x01 -#define PVA_AUDIO_PAYLOAD 0x02 -#define PVA_MAGIC (('A' << 8) + 'V') - -typedef struct { - int continue_pes; -} PVAContext; - -static int pva_probe(AVProbeData * pd) { - unsigned char *buf = pd->buf; - - if (AV_RB16(buf) == PVA_MAGIC && buf[2] && buf[2] < 3 && buf[4] == 0x55) - return AVPROBE_SCORE_MAX / 2; - - return 0; -} - -static int pva_read_header(AVFormatContext *s, AVFormatParameters *ap) { - AVStream *st; - - if (!(st = av_new_stream(s, 0))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG2VIDEO; - st->need_parsing = AVSTREAM_PARSE_FULL; - av_set_pts_info(st, 32, 1, 90000); - av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME); - - if (!(st = av_new_stream(s, 1))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_MP2; - st->need_parsing = AVSTREAM_PARSE_FULL; - av_set_pts_info(st, 33, 1, 90000); - av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME); - - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -#define pva_log if (read_packet) av_log - -static int read_part_of_packet(AVFormatContext *s, int64_t *pts, - int *len, int *strid, int read_packet) { - ByteIOContext *pb = s->pb; - PVAContext *pvactx = s->priv_data; - int syncword, streamid, reserved, flags, length, pts_flag; - int64_t pva_pts = AV_NOPTS_VALUE, startpos; - -recover: - startpos = url_ftell(pb); - - syncword = get_be16(pb); - streamid = get_byte(pb); - get_byte(pb); /* counter not used */ - reserved = get_byte(pb); - flags = get_byte(pb); - length = get_be16(pb); - - pts_flag = flags & 0x10; - - if (syncword != PVA_MAGIC) { - pva_log(s, AV_LOG_ERROR, "invalid syncword\n"); - return AVERROR(EIO); - } - if (streamid != PVA_VIDEO_PAYLOAD && streamid != PVA_AUDIO_PAYLOAD) { - pva_log(s, AV_LOG_ERROR, "invalid streamid\n"); - return AVERROR(EIO); - } - if (reserved != 0x55) { - pva_log(s, AV_LOG_WARNING, "expected reserved byte to be 0x55\n"); - } - if (length > PVA_MAX_PAYLOAD_LENGTH) { - pva_log(s, AV_LOG_ERROR, "invalid payload length %u\n", length); - return AVERROR(EIO); - } - - if (streamid == PVA_VIDEO_PAYLOAD && pts_flag) { - pva_pts = get_be32(pb); - length -= 4; - } else if (streamid == PVA_AUDIO_PAYLOAD) { - /* PVA Audio Packets either start with a signaled PES packet or - * are a continuation of the previous PES packet. New PES packets - * always start at the beginning of a PVA Packet, never somewhere in - * the middle. */ - if (!pvactx->continue_pes) { - int pes_signal, pes_header_data_length, pes_packet_length, - pes_flags; - unsigned char pes_header_data[256]; - - pes_signal = get_be24(pb); - get_byte(pb); - pes_packet_length = get_be16(pb); - pes_flags = get_be16(pb); - pes_header_data_length = get_byte(pb); - - if (pes_signal != 1) { - pva_log(s, AV_LOG_WARNING, "expected signaled PES packet, " - "trying to recover\n"); - url_fskip(pb, length - 9); - if (!read_packet) - return AVERROR(EIO); - goto recover; - } - - get_buffer(pb, pes_header_data, pes_header_data_length); - length -= 9 + pes_header_data_length; - - pes_packet_length -= 3 + pes_header_data_length; - - pvactx->continue_pes = pes_packet_length; - - if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0) == 0x20) - pva_pts = ff_parse_pes_pts(pes_header_data); - } - - pvactx->continue_pes -= length; - - if (pvactx->continue_pes < 0) { - pva_log(s, AV_LOG_WARNING, "audio data corruption\n"); - pvactx->continue_pes = 0; - } - } - - if (pva_pts != AV_NOPTS_VALUE) - av_add_index_entry(s->streams[streamid-1], startpos, pva_pts, 0, 0, AVINDEX_KEYFRAME); - - *pts = pva_pts; - *len = length; - *strid = streamid; - return 0; -} - -static int pva_read_packet(AVFormatContext *s, AVPacket *pkt) { - ByteIOContext *pb = s->pb; - int64_t pva_pts; - int ret, length, streamid; - - if (read_part_of_packet(s, &pva_pts, &length, &streamid, 1) < 0 || - (ret = av_get_packet(pb, pkt, length)) <= 0) - return AVERROR(EIO); - - pkt->stream_index = streamid - 1; - pkt->pts = pva_pts; - - return ret; -} - -static int64_t pva_read_timestamp(struct AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit) { - ByteIOContext *pb = s->pb; - PVAContext *pvactx = s->priv_data; - int length, streamid; - int64_t res = AV_NOPTS_VALUE; - - pos_limit = FFMIN(*pos+PVA_MAX_PAYLOAD_LENGTH*8, (uint64_t)*pos+pos_limit); - - while (*pos < pos_limit) { - res = AV_NOPTS_VALUE; - url_fseek(pb, *pos, SEEK_SET); - - pvactx->continue_pes = 0; - if (read_part_of_packet(s, &res, &length, &streamid, 0)) { - (*pos)++; - continue; - } - if (streamid - 1 != stream_index || res == AV_NOPTS_VALUE) { - *pos = url_ftell(pb) + length; - continue; - } - break; - } - - pvactx->continue_pes = 0; - return res; -} - -AVInputFormat pva_demuxer = { - "pva", - NULL_IF_CONFIG_SMALL("TechnoTrend PVA file and stream format"), - sizeof(PVAContext), - pva_probe, - pva_read_header, - pva_read_packet, - .read_timestamp = pva_read_timestamp -}; diff --git a/tizen/distrib/ffmpeg/libavformat/qcp.c b/tizen/distrib/ffmpeg/libavformat/qcp.c deleted file mode 100644 index 676e9c7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/qcp.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * QCP format (.qcp) demuxer - * Copyright (c) 2009 Kenan Gillet - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QCP format (.qcp) demuxer - * @author Kenan Gillet - * @sa RFC 3625: "The QCP File Format and Media Types for Speech Data" - * http://tools.ietf.org/html/rfc3625 - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -typedef struct { - uint32_t data_size; ///< size of data chunk - -#define QCP_MAX_MODE 4 - int16_t rates_per_mode[QCP_MAX_MODE+1]; ///< contains the packet size corresponding - ///< to each mode, -1 if no size. -} QCPContext; - -/** - * Last 15 out of 16 bytes of QCELP-13K GUID, as stored in the file; - * the first byte of the GUID can be either 0x41 or 0x42. - */ -static const uint8_t guid_qcelp_13k_part[15] = { - 0x6d, 0x7f, 0x5e, 0x15, 0xb1, 0xd0, 0x11, 0xba, - 0x91, 0x00, 0x80, 0x5f, 0xb4, 0xb9, 0x7e -}; - -/** - * EVRC GUID as stored in the file - */ -static const uint8_t guid_evrc[16] = { - 0x8d, 0xd4, 0x89, 0xe6, 0x76, 0x90, 0xb5, 0x46, - 0x91, 0xef, 0x73, 0x6a, 0x51, 0x00, 0xce, 0xb4 -}; - -/** - * SMV GUID as stored in the file - */ -static const uint8_t guid_smv[16] = { - 0x75, 0x2b, 0x7c, 0x8d, 0x97, 0xa7, 0x49, 0xed, - 0x98, 0x5e, 0xd5, 0x3c, 0x8c, 0xc7, 0x5f, 0x84 -}; - -/** - * @param guid contains at least 16 bytes - * @return 1 if the guid is a qcelp_13k guid, 0 otherwise - */ -static int is_qcelp_13k_guid(const uint8_t *guid) { - return (guid[0] == 0x41 || guid[0] == 0x42) - && !memcmp(guid+1, guid_qcelp_13k_part, sizeof(guid_qcelp_13k_part)); -} - -static int qcp_probe(AVProbeData *pd) -{ - if (AV_RL32(pd->buf ) == AV_RL32("RIFF") && - AV_RL64(pd->buf+8) == AV_RL64("QLCMfmt ")) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - QCPContext *c = s->priv_data; - AVStream *st = av_new_stream(s, 0); - uint8_t buf[16]; - int i, nb_rates; - - if (!st) - return AVERROR(ENOMEM); - - get_be32(pb); // "RIFF" - s->file_size = get_le32(pb) + 8; - url_fskip(pb, 8 + 4 + 1 + 1); // "QLCMfmt " + chunk-size + major-version + minor-version - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->channels = 1; - get_buffer(pb, buf, 16); - if (is_qcelp_13k_guid(buf)) { - st->codec->codec_id = CODEC_ID_QCELP; - } else if (!memcmp(buf, guid_evrc, 16)) { - av_log(s, AV_LOG_ERROR, "EVRC codec is not supported.\n"); - return AVERROR_PATCHWELCOME; - } else if (!memcmp(buf, guid_smv, 16)) { - av_log(s, AV_LOG_ERROR, "SMV codec is not supported.\n"); - return AVERROR_PATCHWELCOME; - } else { - av_log(s, AV_LOG_ERROR, "Unknown codec GUID.\n"); - return AVERROR_INVALIDDATA; - } - url_fskip(pb, 2 + 80); // codec-version + codec-name - st->codec->bit_rate = get_le16(pb); - - s->packet_size = get_le16(pb); - url_fskip(pb, 2); // block-size - st->codec->sample_rate = get_le16(pb); - url_fskip(pb, 2); // sample-size - - memset(c->rates_per_mode, -1, sizeof(c->rates_per_mode)); - nb_rates = get_le32(pb); - nb_rates = FFMIN(nb_rates, 8); - for (i=0; i QCP_MAX_MODE) { - av_log(s, AV_LOG_WARNING, "Unknown entry %d=>%d in rate-map-table.\n ", mode, size); - } else - c->rates_per_mode[mode] = size; - } - url_fskip(pb, 16 - 2*nb_rates + 20); // empty entries of rate-map-table + reserved - - return 0; -} - -static int qcp_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - QCPContext *c = s->priv_data; - unsigned int chunk_size, tag; - - while(!url_feof(pb)) { - if (c->data_size) { - int pkt_size, ret, mode = get_byte(pb); - - if (s->packet_size) { - pkt_size = s->packet_size - 1; - } else if (mode > QCP_MAX_MODE || (pkt_size = c->rates_per_mode[mode]) < 0) { - c->data_size--; - continue; - } - - if (c->data_size <= pkt_size) { - av_log(s, AV_LOG_WARNING, "Data chunk is too small.\n"); - pkt_size = c->data_size - 1; - } - - if ((ret = av_get_packet(pb, pkt, pkt_size)) >= 0) { - if (pkt_size != ret) - av_log(s, AV_LOG_ERROR, "Packet size is too small.\n"); - - c->data_size -= pkt_size + 1; - } - return ret; - } - - if (url_ftell(pb) & 1 && get_byte(pb)) - av_log(s, AV_LOG_WARNING, "Padding should be 0.\n"); - - tag = get_le32(pb); - chunk_size = get_le32(pb); - switch (tag) { - case MKTAG('v', 'r', 'a', 't'): - if (get_le32(pb)) // var-rate-flag - s->packet_size = 0; - url_fskip(pb, 4); // size-in-packets - break; - case MKTAG('d', 'a', 't', 'a'): - c->data_size = chunk_size; - break; - - default: - url_fskip(pb, chunk_size); - } - } - return AVERROR_EOF; -} - -AVInputFormat qcp_demuxer = { - .name = "qcp", - .long_name = NULL_IF_CONFIG_SMALL("QCP format"), - .priv_data_size = sizeof(QCPContext), - .read_probe = qcp_probe, - .read_header = qcp_read_header, - .read_packet = qcp_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/qtpalette.h b/tizen/distrib/ffmpeg/libavformat/qtpalette.h deleted file mode 100644 index 7d6802f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/qtpalette.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Default Palettes for Quicktime Files - * Automatically generated from a utility derived from XAnim: - * http://xanim.va.pubnix.com/home.html - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_QTPALETTE_H -#define AVFORMAT_QTPALETTE_H - -#include - -static const uint8_t ff_qt_default_palette_4[4 * 3] = { - 0x93, 0x65, 0x5E, - 0xFF, 0xFF, 0xFF, - 0xDF, 0xD0, 0xAB, - 0x00, 0x00, 0x00 -}; - -static const uint8_t ff_qt_default_palette_16[16 * 3] = { - 0xFF, 0xFB, 0xFF, - 0xEF, 0xD9, 0xBB, - 0xE8, 0xC9, 0xB1, - 0x93, 0x65, 0x5E, - 0xFC, 0xDE, 0xE8, - 0x9D, 0x88, 0x91, - 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, - 0x47, 0x48, 0x37, - 0x7A, 0x5E, 0x55, - 0xDF, 0xD0, 0xAB, - 0xFF, 0xFB, 0xF9, - 0xE8, 0xCA, 0xC5, - 0x8A, 0x7C, 0x77, - 0x00, 0x00, 0x00 -}; - -static const uint8_t ff_qt_default_palette_256[256 * 3] = { - /* 0, 0x00 */ 0xFF, 0xFF, 0xFF, - /* 1, 0x01 */ 0xFF, 0xFF, 0xCC, - /* 2, 0x02 */ 0xFF, 0xFF, 0x99, - /* 3, 0x03 */ 0xFF, 0xFF, 0x66, - /* 4, 0x04 */ 0xFF, 0xFF, 0x33, - /* 5, 0x05 */ 0xFF, 0xFF, 0x00, - /* 6, 0x06 */ 0xFF, 0xCC, 0xFF, - /* 7, 0x07 */ 0xFF, 0xCC, 0xCC, - /* 8, 0x08 */ 0xFF, 0xCC, 0x99, - /* 9, 0x09 */ 0xFF, 0xCC, 0x66, - /* 10, 0x0A */ 0xFF, 0xCC, 0x33, - /* 11, 0x0B */ 0xFF, 0xCC, 0x00, - /* 12, 0x0C */ 0xFF, 0x99, 0xFF, - /* 13, 0x0D */ 0xFF, 0x99, 0xCC, - /* 14, 0x0E */ 0xFF, 0x99, 0x99, - /* 15, 0x0F */ 0xFF, 0x99, 0x66, - /* 16, 0x10 */ 0xFF, 0x99, 0x33, - /* 17, 0x11 */ 0xFF, 0x99, 0x00, - /* 18, 0x12 */ 0xFF, 0x66, 0xFF, - /* 19, 0x13 */ 0xFF, 0x66, 0xCC, - /* 20, 0x14 */ 0xFF, 0x66, 0x99, - /* 21, 0x15 */ 0xFF, 0x66, 0x66, - /* 22, 0x16 */ 0xFF, 0x66, 0x33, - /* 23, 0x17 */ 0xFF, 0x66, 0x00, - /* 24, 0x18 */ 0xFF, 0x33, 0xFF, - /* 25, 0x19 */ 0xFF, 0x33, 0xCC, - /* 26, 0x1A */ 0xFF, 0x33, 0x99, - /* 27, 0x1B */ 0xFF, 0x33, 0x66, - /* 28, 0x1C */ 0xFF, 0x33, 0x33, - /* 29, 0x1D */ 0xFF, 0x33, 0x00, - /* 30, 0x1E */ 0xFF, 0x00, 0xFF, - /* 31, 0x1F */ 0xFF, 0x00, 0xCC, - /* 32, 0x20 */ 0xFF, 0x00, 0x99, - /* 33, 0x21 */ 0xFF, 0x00, 0x66, - /* 34, 0x22 */ 0xFF, 0x00, 0x33, - /* 35, 0x23 */ 0xFF, 0x00, 0x00, - /* 36, 0x24 */ 0xCC, 0xFF, 0xFF, - /* 37, 0x25 */ 0xCC, 0xFF, 0xCC, - /* 38, 0x26 */ 0xCC, 0xFF, 0x99, - /* 39, 0x27 */ 0xCC, 0xFF, 0x66, - /* 40, 0x28 */ 0xCC, 0xFF, 0x33, - /* 41, 0x29 */ 0xCC, 0xFF, 0x00, - /* 42, 0x2A */ 0xCC, 0xCC, 0xFF, - /* 43, 0x2B */ 0xCC, 0xCC, 0xCC, - /* 44, 0x2C */ 0xCC, 0xCC, 0x99, - /* 45, 0x2D */ 0xCC, 0xCC, 0x66, - /* 46, 0x2E */ 0xCC, 0xCC, 0x33, - /* 47, 0x2F */ 0xCC, 0xCC, 0x00, - /* 48, 0x30 */ 0xCC, 0x99, 0xFF, - /* 49, 0x31 */ 0xCC, 0x99, 0xCC, - /* 50, 0x32 */ 0xCC, 0x99, 0x99, - /* 51, 0x33 */ 0xCC, 0x99, 0x66, - /* 52, 0x34 */ 0xCC, 0x99, 0x33, - /* 53, 0x35 */ 0xCC, 0x99, 0x00, - /* 54, 0x36 */ 0xCC, 0x66, 0xFF, - /* 55, 0x37 */ 0xCC, 0x66, 0xCC, - /* 56, 0x38 */ 0xCC, 0x66, 0x99, - /* 57, 0x39 */ 0xCC, 0x66, 0x66, - /* 58, 0x3A */ 0xCC, 0x66, 0x33, - /* 59, 0x3B */ 0xCC, 0x66, 0x00, - /* 60, 0x3C */ 0xCC, 0x33, 0xFF, - /* 61, 0x3D */ 0xCC, 0x33, 0xCC, - /* 62, 0x3E */ 0xCC, 0x33, 0x99, - /* 63, 0x3F */ 0xCC, 0x33, 0x66, - /* 64, 0x40 */ 0xCC, 0x33, 0x33, - /* 65, 0x41 */ 0xCC, 0x33, 0x00, - /* 66, 0x42 */ 0xCC, 0x00, 0xFF, - /* 67, 0x43 */ 0xCC, 0x00, 0xCC, - /* 68, 0x44 */ 0xCC, 0x00, 0x99, - /* 69, 0x45 */ 0xCC, 0x00, 0x66, - /* 70, 0x46 */ 0xCC, 0x00, 0x33, - /* 71, 0x47 */ 0xCC, 0x00, 0x00, - /* 72, 0x48 */ 0x99, 0xFF, 0xFF, - /* 73, 0x49 */ 0x99, 0xFF, 0xCC, - /* 74, 0x4A */ 0x99, 0xFF, 0x99, - /* 75, 0x4B */ 0x99, 0xFF, 0x66, - /* 76, 0x4C */ 0x99, 0xFF, 0x33, - /* 77, 0x4D */ 0x99, 0xFF, 0x00, - /* 78, 0x4E */ 0x99, 0xCC, 0xFF, - /* 79, 0x4F */ 0x99, 0xCC, 0xCC, - /* 80, 0x50 */ 0x99, 0xCC, 0x99, - /* 81, 0x51 */ 0x99, 0xCC, 0x66, - /* 82, 0x52 */ 0x99, 0xCC, 0x33, - /* 83, 0x53 */ 0x99, 0xCC, 0x00, - /* 84, 0x54 */ 0x99, 0x99, 0xFF, - /* 85, 0x55 */ 0x99, 0x99, 0xCC, - /* 86, 0x56 */ 0x99, 0x99, 0x99, - /* 87, 0x57 */ 0x99, 0x99, 0x66, - /* 88, 0x58 */ 0x99, 0x99, 0x33, - /* 89, 0x59 */ 0x99, 0x99, 0x00, - /* 90, 0x5A */ 0x99, 0x66, 0xFF, - /* 91, 0x5B */ 0x99, 0x66, 0xCC, - /* 92, 0x5C */ 0x99, 0x66, 0x99, - /* 93, 0x5D */ 0x99, 0x66, 0x66, - /* 94, 0x5E */ 0x99, 0x66, 0x33, - /* 95, 0x5F */ 0x99, 0x66, 0x00, - /* 96, 0x60 */ 0x99, 0x33, 0xFF, - /* 97, 0x61 */ 0x99, 0x33, 0xCC, - /* 98, 0x62 */ 0x99, 0x33, 0x99, - /* 99, 0x63 */ 0x99, 0x33, 0x66, - /* 100, 0x64 */ 0x99, 0x33, 0x33, - /* 101, 0x65 */ 0x99, 0x33, 0x00, - /* 102, 0x66 */ 0x99, 0x00, 0xFF, - /* 103, 0x67 */ 0x99, 0x00, 0xCC, - /* 104, 0x68 */ 0x99, 0x00, 0x99, - /* 105, 0x69 */ 0x99, 0x00, 0x66, - /* 106, 0x6A */ 0x99, 0x00, 0x33, - /* 107, 0x6B */ 0x99, 0x00, 0x00, - /* 108, 0x6C */ 0x66, 0xFF, 0xFF, - /* 109, 0x6D */ 0x66, 0xFF, 0xCC, - /* 110, 0x6E */ 0x66, 0xFF, 0x99, - /* 111, 0x6F */ 0x66, 0xFF, 0x66, - /* 112, 0x70 */ 0x66, 0xFF, 0x33, - /* 113, 0x71 */ 0x66, 0xFF, 0x00, - /* 114, 0x72 */ 0x66, 0xCC, 0xFF, - /* 115, 0x73 */ 0x66, 0xCC, 0xCC, - /* 116, 0x74 */ 0x66, 0xCC, 0x99, - /* 117, 0x75 */ 0x66, 0xCC, 0x66, - /* 118, 0x76 */ 0x66, 0xCC, 0x33, - /* 119, 0x77 */ 0x66, 0xCC, 0x00, - /* 120, 0x78 */ 0x66, 0x99, 0xFF, - /* 121, 0x79 */ 0x66, 0x99, 0xCC, - /* 122, 0x7A */ 0x66, 0x99, 0x99, - /* 123, 0x7B */ 0x66, 0x99, 0x66, - /* 124, 0x7C */ 0x66, 0x99, 0x33, - /* 125, 0x7D */ 0x66, 0x99, 0x00, - /* 126, 0x7E */ 0x66, 0x66, 0xFF, - /* 127, 0x7F */ 0x66, 0x66, 0xCC, - /* 128, 0x80 */ 0x66, 0x66, 0x99, - /* 129, 0x81 */ 0x66, 0x66, 0x66, - /* 130, 0x82 */ 0x66, 0x66, 0x33, - /* 131, 0x83 */ 0x66, 0x66, 0x00, - /* 132, 0x84 */ 0x66, 0x33, 0xFF, - /* 133, 0x85 */ 0x66, 0x33, 0xCC, - /* 134, 0x86 */ 0x66, 0x33, 0x99, - /* 135, 0x87 */ 0x66, 0x33, 0x66, - /* 136, 0x88 */ 0x66, 0x33, 0x33, - /* 137, 0x89 */ 0x66, 0x33, 0x00, - /* 138, 0x8A */ 0x66, 0x00, 0xFF, - /* 139, 0x8B */ 0x66, 0x00, 0xCC, - /* 140, 0x8C */ 0x66, 0x00, 0x99, - /* 141, 0x8D */ 0x66, 0x00, 0x66, - /* 142, 0x8E */ 0x66, 0x00, 0x33, - /* 143, 0x8F */ 0x66, 0x00, 0x00, - /* 144, 0x90 */ 0x33, 0xFF, 0xFF, - /* 145, 0x91 */ 0x33, 0xFF, 0xCC, - /* 146, 0x92 */ 0x33, 0xFF, 0x99, - /* 147, 0x93 */ 0x33, 0xFF, 0x66, - /* 148, 0x94 */ 0x33, 0xFF, 0x33, - /* 149, 0x95 */ 0x33, 0xFF, 0x00, - /* 150, 0x96 */ 0x33, 0xCC, 0xFF, - /* 151, 0x97 */ 0x33, 0xCC, 0xCC, - /* 152, 0x98 */ 0x33, 0xCC, 0x99, - /* 153, 0x99 */ 0x33, 0xCC, 0x66, - /* 154, 0x9A */ 0x33, 0xCC, 0x33, - /* 155, 0x9B */ 0x33, 0xCC, 0x00, - /* 156, 0x9C */ 0x33, 0x99, 0xFF, - /* 157, 0x9D */ 0x33, 0x99, 0xCC, - /* 158, 0x9E */ 0x33, 0x99, 0x99, - /* 159, 0x9F */ 0x33, 0x99, 0x66, - /* 160, 0xA0 */ 0x33, 0x99, 0x33, - /* 161, 0xA1 */ 0x33, 0x99, 0x00, - /* 162, 0xA2 */ 0x33, 0x66, 0xFF, - /* 163, 0xA3 */ 0x33, 0x66, 0xCC, - /* 164, 0xA4 */ 0x33, 0x66, 0x99, - /* 165, 0xA5 */ 0x33, 0x66, 0x66, - /* 166, 0xA6 */ 0x33, 0x66, 0x33, - /* 167, 0xA7 */ 0x33, 0x66, 0x00, - /* 168, 0xA8 */ 0x33, 0x33, 0xFF, - /* 169, 0xA9 */ 0x33, 0x33, 0xCC, - /* 170, 0xAA */ 0x33, 0x33, 0x99, - /* 171, 0xAB */ 0x33, 0x33, 0x66, - /* 172, 0xAC */ 0x33, 0x33, 0x33, - /* 173, 0xAD */ 0x33, 0x33, 0x00, - /* 174, 0xAE */ 0x33, 0x00, 0xFF, - /* 175, 0xAF */ 0x33, 0x00, 0xCC, - /* 176, 0xB0 */ 0x33, 0x00, 0x99, - /* 177, 0xB1 */ 0x33, 0x00, 0x66, - /* 178, 0xB2 */ 0x33, 0x00, 0x33, - /* 179, 0xB3 */ 0x33, 0x00, 0x00, - /* 180, 0xB4 */ 0x00, 0xFF, 0xFF, - /* 181, 0xB5 */ 0x00, 0xFF, 0xCC, - /* 182, 0xB6 */ 0x00, 0xFF, 0x99, - /* 183, 0xB7 */ 0x00, 0xFF, 0x66, - /* 184, 0xB8 */ 0x00, 0xFF, 0x33, - /* 185, 0xB9 */ 0x00, 0xFF, 0x00, - /* 186, 0xBA */ 0x00, 0xCC, 0xFF, - /* 187, 0xBB */ 0x00, 0xCC, 0xCC, - /* 188, 0xBC */ 0x00, 0xCC, 0x99, - /* 189, 0xBD */ 0x00, 0xCC, 0x66, - /* 190, 0xBE */ 0x00, 0xCC, 0x33, - /* 191, 0xBF */ 0x00, 0xCC, 0x00, - /* 192, 0xC0 */ 0x00, 0x99, 0xFF, - /* 193, 0xC1 */ 0x00, 0x99, 0xCC, - /* 194, 0xC2 */ 0x00, 0x99, 0x99, - /* 195, 0xC3 */ 0x00, 0x99, 0x66, - /* 196, 0xC4 */ 0x00, 0x99, 0x33, - /* 197, 0xC5 */ 0x00, 0x99, 0x00, - /* 198, 0xC6 */ 0x00, 0x66, 0xFF, - /* 199, 0xC7 */ 0x00, 0x66, 0xCC, - /* 200, 0xC8 */ 0x00, 0x66, 0x99, - /* 201, 0xC9 */ 0x00, 0x66, 0x66, - /* 202, 0xCA */ 0x00, 0x66, 0x33, - /* 203, 0xCB */ 0x00, 0x66, 0x00, - /* 204, 0xCC */ 0x00, 0x33, 0xFF, - /* 205, 0xCD */ 0x00, 0x33, 0xCC, - /* 206, 0xCE */ 0x00, 0x33, 0x99, - /* 207, 0xCF */ 0x00, 0x33, 0x66, - /* 208, 0xD0 */ 0x00, 0x33, 0x33, - /* 209, 0xD1 */ 0x00, 0x33, 0x00, - /* 210, 0xD2 */ 0x00, 0x00, 0xFF, - /* 211, 0xD3 */ 0x00, 0x00, 0xCC, - /* 212, 0xD4 */ 0x00, 0x00, 0x99, - /* 213, 0xD5 */ 0x00, 0x00, 0x66, - /* 214, 0xD6 */ 0x00, 0x00, 0x33, - /* 215, 0xD7 */ 0xEE, 0x00, 0x00, - /* 216, 0xD8 */ 0xDD, 0x00, 0x00, - /* 217, 0xD9 */ 0xBB, 0x00, 0x00, - /* 218, 0xDA */ 0xAA, 0x00, 0x00, - /* 219, 0xDB */ 0x88, 0x00, 0x00, - /* 220, 0xDC */ 0x77, 0x00, 0x00, - /* 221, 0xDD */ 0x55, 0x00, 0x00, - /* 222, 0xDE */ 0x44, 0x00, 0x00, - /* 223, 0xDF */ 0x22, 0x00, 0x00, - /* 224, 0xE0 */ 0x11, 0x00, 0x00, - /* 225, 0xE1 */ 0x00, 0xEE, 0x00, - /* 226, 0xE2 */ 0x00, 0xDD, 0x00, - /* 227, 0xE3 */ 0x00, 0xBB, 0x00, - /* 228, 0xE4 */ 0x00, 0xAA, 0x00, - /* 229, 0xE5 */ 0x00, 0x88, 0x00, - /* 230, 0xE6 */ 0x00, 0x77, 0x00, - /* 231, 0xE7 */ 0x00, 0x55, 0x00, - /* 232, 0xE8 */ 0x00, 0x44, 0x00, - /* 233, 0xE9 */ 0x00, 0x22, 0x00, - /* 234, 0xEA */ 0x00, 0x11, 0x00, - /* 235, 0xEB */ 0x00, 0x00, 0xEE, - /* 236, 0xEC */ 0x00, 0x00, 0xDD, - /* 237, 0xED */ 0x00, 0x00, 0xBB, - /* 238, 0xEE */ 0x00, 0x00, 0xAA, - /* 239, 0xEF */ 0x00, 0x00, 0x88, - /* 240, 0xF0 */ 0x00, 0x00, 0x77, - /* 241, 0xF1 */ 0x00, 0x00, 0x55, - /* 242, 0xF2 */ 0x00, 0x00, 0x44, - /* 243, 0xF3 */ 0x00, 0x00, 0x22, - /* 244, 0xF4 */ 0x00, 0x00, 0x11, - /* 245, 0xF5 */ 0xEE, 0xEE, 0xEE, - /* 246, 0xF6 */ 0xDD, 0xDD, 0xDD, - /* 247, 0xF7 */ 0xBB, 0xBB, 0xBB, - /* 248, 0xF8 */ 0xAA, 0xAA, 0xAA, - /* 249, 0xF9 */ 0x88, 0x88, 0x88, - /* 250, 0xFA */ 0x77, 0x77, 0x77, - /* 251, 0xFB */ 0x55, 0x55, 0x55, - /* 252, 0xFC */ 0x44, 0x44, 0x44, - /* 253, 0xFD */ 0x22, 0x22, 0x22, - /* 254, 0xFE */ 0x11, 0x11, 0x11, - /* 255, 0xFF */ 0x00, 0x00, 0x00 -}; - -#endif /* AVFORMAT_QTPALETTE_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/r3d.c b/tizen/distrib/ffmpeg/libavformat/r3d.c deleted file mode 100644 index 556a32b..0000000 --- a/tizen/distrib/ffmpeg/libavformat/r3d.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * R3D REDCODE demuxer - * Copyright (c) 2008 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//#define DEBUG - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -typedef struct { - unsigned video_offsets_count; - unsigned *video_offsets; - unsigned rdvo_offset; -} R3DContext; - -typedef struct { - unsigned size; - uint32_t tag; - uint64_t offset; -} Atom; - -static int read_atom(AVFormatContext *s, Atom *atom) -{ - atom->offset = url_ftell(s->pb); - atom->size = get_be32(s->pb); - if (atom->size < 8) - return -1; - atom->tag = get_le32(s->pb); - dprintf(s, "atom %d %.4s offset %#llx\n", - atom->size, (char*)&atom->tag, atom->offset); - return atom->size; -} - -static int r3d_read_red1(AVFormatContext *s) -{ - AVStream *st = av_new_stream(s, 0); - char filename[258]; - int tmp, tmp2; - - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_JPEG2000; - - tmp = get_byte(s->pb); // major version - tmp2 = get_byte(s->pb); // minor version - dprintf(s, "version %d.%d\n", tmp, tmp2); - - tmp = get_be16(s->pb); // unknown - dprintf(s, "unknown1 %d\n", tmp); - - tmp = get_be32(s->pb); - av_set_pts_info(st, 32, 1, tmp); - - tmp = get_be32(s->pb); // filenum - dprintf(s, "filenum %d\n", tmp); - - url_fskip(s->pb, 32); // unknown - - st->codec->width = get_be32(s->pb); - st->codec->height = get_be32(s->pb); - - tmp = get_be16(s->pb); // unknown - dprintf(s, "unknown2 %d\n", tmp); - - st->codec->time_base.den = get_be16(s->pb); - st->codec->time_base.num = get_be16(s->pb); - - tmp = get_byte(s->pb); // audio channels - dprintf(s, "audio channels %d\n", tmp); - if (tmp > 0) { - AVStream *ast = av_new_stream(s, 1); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = CODEC_ID_PCM_S32BE; - ast->codec->channels = tmp; - av_set_pts_info(ast, 32, 1, st->time_base.den); - } - - get_buffer(s->pb, filename, 257); - filename[sizeof(filename)-1] = 0; - av_metadata_set2(&st->metadata, "filename", filename, 0); - - dprintf(s, "filename %s\n", filename); - dprintf(s, "resolution %dx%d\n", st->codec->width, st->codec->height); - dprintf(s, "timescale %d\n", st->time_base.den); - dprintf(s, "frame rate %d/%d\n", - st->codec->time_base.num, st->codec->time_base.den); - - return 0; -} - -static int r3d_read_rdvo(AVFormatContext *s, Atom *atom) -{ - R3DContext *r3d = s->priv_data; - AVStream *st = s->streams[0]; - int i; - - r3d->video_offsets_count = (atom->size - 8) / 4; - r3d->video_offsets = av_malloc(atom->size); - if (!r3d->video_offsets) - return AVERROR(ENOMEM); - - for (i = 0; i < r3d->video_offsets_count; i++) { - r3d->video_offsets[i] = get_be32(s->pb); - if (!r3d->video_offsets[i]) { - r3d->video_offsets_count = i; - break; - } - dprintf(s, "video offset %d: %#x\n", i, r3d->video_offsets[i]); - } - - if (st->codec->time_base.den) - st->duration = (uint64_t)r3d->video_offsets_count* - st->time_base.den*st->codec->time_base.num/st->codec->time_base.den; - dprintf(s, "duration %lld\n", st->duration); - - return 0; -} - -static void r3d_read_reos(AVFormatContext *s) -{ - R3DContext *r3d = s->priv_data; - int tmp; - - r3d->rdvo_offset = get_be32(s->pb); - get_be32(s->pb); // rdvs offset - get_be32(s->pb); // rdao offset - get_be32(s->pb); // rdas offset - - tmp = get_be32(s->pb); - dprintf(s, "num video chunks %d\n", tmp); - - tmp = get_be32(s->pb); - dprintf(s, "num audio chunks %d\n", tmp); - - url_fskip(s->pb, 6*4); -} - -static int r3d_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - R3DContext *r3d = s->priv_data; - Atom atom; - int ret; - - if (read_atom(s, &atom) < 0) { - av_log(s, AV_LOG_ERROR, "error reading atom\n"); - return -1; - } - if (atom.tag == MKTAG('R','E','D','1')) { - if ((ret = r3d_read_red1(s)) < 0) { - av_log(s, AV_LOG_ERROR, "error parsing 'red1' atom\n"); - return ret; - } - } else { - av_log(s, AV_LOG_ERROR, "could not find 'red1' atom\n"); - return -1; - } - - s->data_offset = url_ftell(s->pb); - dprintf(s, "data offset %#llx\n", s->data_offset); - if (url_is_streamed(s->pb)) - return 0; - // find REOB/REOF/REOS to load index - url_fseek(s->pb, url_fsize(s->pb)-48-8, SEEK_SET); - if (read_atom(s, &atom) < 0) - av_log(s, AV_LOG_ERROR, "error reading end atom\n"); - - if (atom.tag != MKTAG('R','E','O','B') && - atom.tag != MKTAG('R','E','O','F') && - atom.tag != MKTAG('R','E','O','S')) - goto out; - - r3d_read_reos(s); - - if (r3d->rdvo_offset) { - url_fseek(s->pb, r3d->rdvo_offset, SEEK_SET); - if (read_atom(s, &atom) < 0) - av_log(s, AV_LOG_ERROR, "error reading 'rdvo' atom\n"); - if (atom.tag == MKTAG('R','D','V','O')) { - if (r3d_read_rdvo(s, &atom) < 0) - av_log(s, AV_LOG_ERROR, "error parsing 'rdvo' atom\n"); - } - } - - out: - url_fseek(s->pb, s->data_offset, SEEK_SET); - return 0; -} - -static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom) -{ - AVStream *st = s->streams[0]; - int tmp, tmp2; - uint64_t pos = url_ftell(s->pb); - unsigned dts; - int ret; - - dts = get_be32(s->pb); - - tmp = get_be32(s->pb); - dprintf(s, "frame num %d\n", tmp); - - tmp = get_byte(s->pb); // major version - tmp2 = get_byte(s->pb); // minor version - dprintf(s, "version %d.%d\n", tmp, tmp2); - - tmp = get_be16(s->pb); // unknown - dprintf(s, "unknown %d\n", tmp); - - if (tmp > 4) { - tmp = get_be16(s->pb); // unknown - dprintf(s, "unknown %d\n", tmp); - - tmp = get_be16(s->pb); // unknown - dprintf(s, "unknown %d\n", tmp); - - tmp = get_be32(s->pb); - dprintf(s, "width %d\n", tmp); - tmp = get_be32(s->pb); - dprintf(s, "height %d\n", tmp); - - tmp = get_be32(s->pb); - dprintf(s, "metadata len %d\n", tmp); - } - tmp = atom->size - 8 - (url_ftell(s->pb) - pos); - if (tmp < 0) - return -1; - ret = av_get_packet(s->pb, pkt, tmp); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "error reading video packet\n"); - return -1; - } - - pkt->stream_index = 0; - pkt->dts = dts; - if (st->codec->time_base.den) - pkt->duration = (uint64_t)st->time_base.den* - st->codec->time_base.num/st->codec->time_base.den; - dprintf(s, "pkt dts %lld duration %d\n", pkt->dts, pkt->duration); - - return 0; -} - -static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) -{ - AVStream *st = s->streams[1]; - int tmp, tmp2, samples, size; - uint64_t pos = url_ftell(s->pb); - unsigned dts; - int ret; - - dts = get_be32(s->pb); - - st->codec->sample_rate = get_be32(s->pb); - - samples = get_be32(s->pb); - - tmp = get_be32(s->pb); - dprintf(s, "packet num %d\n", tmp); - - tmp = get_be16(s->pb); // unkown - dprintf(s, "unknown %d\n", tmp); - - tmp = get_byte(s->pb); // major version - tmp2 = get_byte(s->pb); // minor version - dprintf(s, "version %d.%d\n", tmp, tmp2); - - tmp = get_be32(s->pb); // unknown - dprintf(s, "unknown %d\n", tmp); - - size = atom->size - 8 - (url_ftell(s->pb) - pos); - if (size < 0) - return -1; - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "error reading audio packet\n"); - return ret; - } - - pkt->stream_index = 1; - pkt->dts = dts; - pkt->duration = av_rescale(samples, st->time_base.den, st->codec->sample_rate); - dprintf(s, "pkt dts %lld duration %d samples %d sample rate %d\n", - pkt->dts, pkt->duration, samples, st->codec->sample_rate); - - return 0; -} - -static int r3d_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - Atom atom; - int err = 0; - - while (!err) { - if (read_atom(s, &atom) < 0) { - err = -1; - break; - } - switch (atom.tag) { - case MKTAG('R','E','D','V'): - if (s->streams[0]->discard == AVDISCARD_ALL) - goto skip; - if (!(err = r3d_read_redv(s, pkt, &atom))) - return 0; - break; - case MKTAG('R','E','D','A'): - if (s->nb_streams < 2) - return -1; - if (s->streams[1]->discard == AVDISCARD_ALL) - goto skip; - if (!(err = r3d_read_reda(s, pkt, &atom))) - return 0; - break; - default: - skip: - url_fskip(s->pb, atom.size-8); - } - } - return err; -} - -static int r3d_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf + 4) == MKTAG('R','E','D','1')) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int r3d_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) -{ - AVStream *st = s->streams[0]; // video stream - R3DContext *r3d = s->priv_data; - int frame_num; - - if (!st->codec->time_base.num || !st->time_base.den) - return -1; - - frame_num = sample_time*st->codec->time_base.den/ - ((int64_t)st->codec->time_base.num*st->time_base.den); - dprintf(s, "seek frame num %d timestamp %lld\n", frame_num, sample_time); - - if (frame_num < r3d->video_offsets_count) { - url_fseek(s->pb, r3d->video_offsets_count, SEEK_SET); - } else { - av_log(s, AV_LOG_ERROR, "could not seek to frame %d\n", frame_num); - return -1; - } - - return 0; -} - -static int r3d_close(AVFormatContext *s) -{ - R3DContext *r3d = s->priv_data; - - av_freep(&r3d->video_offsets); - - return 0; -} - -AVInputFormat r3d_demuxer = { - "r3d", - NULL_IF_CONFIG_SMALL("REDCODE R3D format"), - sizeof(R3DContext), - r3d_probe, - r3d_read_header, - r3d_read_packet, - r3d_close, - r3d_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/raw.c b/tizen/distrib/ffmpeg/libavformat/raw.c deleted file mode 100644 index 7837de8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/raw.c +++ /dev/null @@ -1,1363 +0,0 @@ -/* - * RAW muxer and demuxer - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2005 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/crc.h" -#include "libavcodec/ac3_parser.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "raw.h" -#include "id3v2.h" -#include "id3v1.h" - -/* simple formats */ - -#if CONFIG_ROQ_MUXER -static int roq_write_header(struct AVFormatContext *s) -{ - static const uint8_t header[] = { - 0x84, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x00 - }; - - put_buffer(s->pb, header, 8); - put_flush_packet(s->pb); - - return 0; -} -#endif - -#if CONFIG_NULL_MUXER -static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - return 0; -} -#endif - -#if CONFIG_MUXERS -static int raw_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - put_buffer(s->pb, pkt->data, pkt->size); - put_flush_packet(s->pb); - return 0; -} -#endif - -#if CONFIG_DEMUXERS -/* raw input */ -static int raw_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - AVStream *st; - enum CodecID id; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - id = s->iformat->value; - if (id == CODEC_ID_RAWVIDEO) { - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - } else { - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } - st->codec->codec_id = id; - - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - st->codec->sample_rate = ap->sample_rate; - if(ap->channels) st->codec->channels = ap->channels; - else st->codec->channels = 1; - st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); - assert(st->codec->bits_per_coded_sample > 0); - st->codec->block_align = st->codec->bits_per_coded_sample*st->codec->channels/8; - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - break; - case AVMEDIA_TYPE_VIDEO: - if(ap->time_base.num) - av_set_pts_info(st, 64, ap->time_base.num, ap->time_base.den); - else - av_set_pts_info(st, 64, 1, 25); - st->codec->width = ap->width; - st->codec->height = ap->height; - st->codec->pix_fmt = ap->pix_fmt; - if(st->codec->pix_fmt == PIX_FMT_NONE) - st->codec->pix_fmt= PIX_FMT_YUV420P; - break; - default: - return -1; - } - return 0; -} - -#define RAW_PACKET_SIZE 1024 -#define RAW_SAMPLES 1024 - -static int raw_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size, bps; - // AVStream *st = s->streams[0]; - - size= RAW_SAMPLES*s->streams[0]->codec->block_align; - - ret= av_get_packet(s->pb, pkt, size); - - pkt->stream_index = 0; - if (ret < 0) - return ret; - - bps= av_get_bits_per_sample(s->streams[0]->codec->codec_id); - assert(bps); // if false there IS a bug elsewhere (NOT in this function) - pkt->dts= - pkt->pts= pkt->pos*8 / (bps * s->streams[0]->codec->channels); - - return ret; -} - -int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size; - - size = RAW_PACKET_SIZE; - - if (av_new_packet(pkt, size) < 0) - return AVERROR(ENOMEM); - - pkt->pos= url_ftell(s->pb); - pkt->stream_index = 0; - ret = get_partial_buffer(s->pb, pkt->data, size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - pkt->size = ret; - return ret; -} -#endif - -#if CONFIG_RAWVIDEO_DEMUXER -static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int packet_size, ret, width, height; - AVStream *st = s->streams[0]; - - width = st->codec->width; - height = st->codec->height; - - packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); - if (packet_size < 0) - return -1; - - ret= av_get_packet(s->pb, pkt, packet_size); - pkt->pts= - pkt->dts= pkt->pos / packet_size; - - pkt->stream_index = 0; - if (ret < 0) - return ret; - return 0; -} -#endif - -#if CONFIG_INGENIENT_DEMUXER -// http://www.artificis.hu/files/texts/ingenient.txt -static int ingenient_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size, w, h, unk1, unk2; - - if (get_le32(s->pb) != MKTAG('M', 'J', 'P', 'G')) - return AVERROR(EIO); // FIXME - - size = get_le32(s->pb); - - w = get_le16(s->pb); - h = get_le16(s->pb); - - url_fskip(s->pb, 8); // zero + size (padded?) - url_fskip(s->pb, 2); - unk1 = get_le16(s->pb); - unk2 = get_le16(s->pb); - url_fskip(s->pb, 22); // ASCII timestamp - - av_log(s, AV_LOG_DEBUG, "Ingenient packet: size=%d, width=%d, height=%d, unk1=%d unk2=%d\n", - size, w, h, unk1, unk2); - - if (av_new_packet(pkt, size) < 0) - return AVERROR(ENOMEM); - - pkt->pos = url_ftell(s->pb); - pkt->stream_index = 0; - ret = get_buffer(s->pb, pkt->data, size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - pkt->size = ret; - return ret; -} -#endif - -#if CONFIG_DEMUXERS -int pcm_read_seek(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags) -{ - AVStream *st; - int block_align, byte_rate; - int64_t pos, ret; - - st = s->streams[0]; - - block_align = st->codec->block_align ? st->codec->block_align : - (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3; - byte_rate = st->codec->bit_rate ? st->codec->bit_rate >> 3 : - block_align * st->codec->sample_rate; - - if (block_align <= 0 || byte_rate <= 0) - return -1; - if (timestamp < 0) timestamp = 0; - - /* compute the position by aligning it to block_align */ - pos = av_rescale_rnd(timestamp * byte_rate, - st->time_base.num, - st->time_base.den * (int64_t)block_align, - (flags & AVSEEK_FLAG_BACKWARD) ? AV_ROUND_DOWN : AV_ROUND_UP); - pos *= block_align; - - /* recompute exact position */ - st->cur_dts = av_rescale(pos, st->time_base.den, byte_rate * (int64_t)st->time_base.num); - if ((ret = url_fseek(s->pb, pos + s->data_offset, SEEK_SET)) < 0) - return ret; - return 0; -} - -static int audio_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->value; - st->need_parsing = AVSTREAM_PARSE_FULL; - /* the parameters will be extracted from the compressed bitstream */ - - return 0; -} - -/* MPEG-1/H.263 input */ -static int video_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = s->iformat->value; - st->need_parsing = AVSTREAM_PARSE_FULL; - - /* for MJPEG, specify frame rate */ - /* for MPEG-4 specify it, too (most MPEG-4 streams do not have the fixed_vop_rate set ...)*/ - if (ap->time_base.num) { - st->codec->time_base= ap->time_base; - } else if ( st->codec->codec_id == CODEC_ID_MJPEG || - st->codec->codec_id == CODEC_ID_MPEG4 || - st->codec->codec_id == CODEC_ID_DIRAC || - st->codec->codec_id == CODEC_ID_DNXHD || - st->codec->codec_id == CODEC_ID_H264) { - st->codec->time_base= (AVRational){1,25}; - } - av_set_pts_info(st, 64, 1, 1200000); - - return 0; -} -#endif - -#if CONFIG_MPEGVIDEO_DEMUXER -#define SEQ_START_CODE 0x000001b3 -#define GOP_START_CODE 0x000001b8 -#define PICTURE_START_CODE 0x00000100 -#define SLICE_START_CODE 0x00000101 -#define PACK_START_CODE 0x000001ba -#define VIDEO_ID 0x000001e0 -#define AUDIO_ID 0x000001c0 - -static int mpegvideo_probe(AVProbeData *p) -{ - uint32_t code= -1; - int pic=0, seq=0, slice=0, pspack=0, pes=0; - int i; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - switch(code){ - case SEQ_START_CODE: seq++; break; - case PICTURE_START_CODE: pic++; break; - case SLICE_START_CODE: slice++; break; - case PACK_START_CODE: pspack++; break; - } - if ((code & 0x1f0) == VIDEO_ID) pes++; - else if((code & 0x1e0) == AUDIO_ID) pes++; - } - } - if(seq && seq*9<=pic*10 && pic*9<=slice*10 && !pspack && !pes) - return pic>1 ? AVPROBE_SCORE_MAX/2+1 : AVPROBE_SCORE_MAX/4; // +1 for .mpg - return 0; -} -#endif - -#if CONFIG_CAVSVIDEO_DEMUXER -#define CAVS_SEQ_START_CODE 0x000001b0 -#define CAVS_PIC_I_START_CODE 0x000001b3 -#define CAVS_UNDEF_START_CODE 0x000001b4 -#define CAVS_PIC_PB_START_CODE 0x000001b6 -#define CAVS_VIDEO_EDIT_CODE 0x000001b7 -#define CAVS_PROFILE_JIZHUN 0x20 - -static int cavsvideo_probe(AVProbeData *p) -{ - uint32_t code= -1; - int pic=0, seq=0, slice_pos = 0; - int i; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - if(code < CAVS_SEQ_START_CODE) { - /* slices have to be consecutive */ - if(code < slice_pos) - return 0; - slice_pos = code; - } else { - slice_pos = 0; - } - if (code == CAVS_SEQ_START_CODE) { - seq++; - /* check for the only currently supported profile */ - if(p->buf[i+1] != CAVS_PROFILE_JIZHUN) - return 0; - } else if ((code == CAVS_PIC_I_START_CODE) || - (code == CAVS_PIC_PB_START_CODE)) { - pic++; - } else if ((code == CAVS_UNDEF_START_CODE) || - (code > CAVS_VIDEO_EDIT_CODE)) { - return 0; - } - } - } - if(seq && seq*9<=pic*10) - return AVPROBE_SCORE_MAX/2; - return 0; -} -#endif - -#if CONFIG_M4V_DEMUXER -#define VISUAL_OBJECT_START_CODE 0x000001b5 -#define VOP_START_CODE 0x000001b6 - -static int mpeg4video_probe(AVProbeData *probe_packet) -{ - uint32_t temp_buffer= -1; - int VO=0, VOL=0, VOP = 0, VISO = 0, res=0; - int i; - - for(i=0; ibuf_size; i++){ - temp_buffer = (temp_buffer<<8) + probe_packet->buf[i]; - if ((temp_buffer & 0xffffff00) != 0x100) - continue; - - if (temp_buffer == VOP_START_CODE) VOP++; - else if (temp_buffer == VISUAL_OBJECT_START_CODE) VISO++; - else if (temp_buffer < 0x120) VO++; - else if (temp_buffer < 0x130) VOL++; - else if ( !(0x1AF < temp_buffer && temp_buffer < 0x1B7) - && !(0x1B9 < temp_buffer && temp_buffer < 0x1C4)) res++; - } - - if ( VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0) - return AVPROBE_SCORE_MAX/2; - return 0; -} -#endif - -#if CONFIG_H264_DEMUXER -static int h264_probe(AVProbeData *p) -{ - uint32_t code= -1; - int sps=0, pps=0, idr=0, res=0, sli=0; - int i; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - int ref_idc= (code>>5)&3; - int type = code & 0x1F; - static const int8_t ref_zero[32]={ - 2, 0, 0, 0, 0,-1, 1,-1, - -1, 1, 1, 1, 1,-1, 2, 2, - 2, 2, 2, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2 - }; - - if(code & 0x80) //forbidden bit - return 0; - - if(ref_zero[type] == 1 && ref_idc) - return 0; - if(ref_zero[type] ==-1 && !ref_idc) - return 0; - if(ref_zero[type] == 2) - res++; - - switch(type){ - case 1: sli++; break; - case 5: idr++; break; - case 7: - if(p->buf[i+2]&0x0F) - return 0; - sps++; - break; - case 8: pps++; break; - } - } - } - if(sps && pps && (idr||sli>3) && res<(sps+pps+idr)) - return AVPROBE_SCORE_MAX/2+1; // +1 for .mpg - return 0; -} -#endif - -#if CONFIG_H263_DEMUXER -static int h263_probe(AVProbeData *p) -{ - uint64_t code= -1; - int i; - int valid_psc=0; - int invalid_psc=0; - int res_change=0; - int src_fmt, last_src_fmt=-1; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xfffffc0000) == 0x800000) { - src_fmt= (code>>2)&3; - if( src_fmt != last_src_fmt - && last_src_fmt>0 && last_src_fmt<6 - && src_fmt<6) - res_change++; - - if((code&0x300)==0x200 && src_fmt){ - valid_psc++; - }else - invalid_psc++; - last_src_fmt= src_fmt; - } - } -//av_log(NULL, AV_LOG_ERROR, "h263_probe: psc:%d invalid:%d res_change:%d\n", valid_psc, invalid_psc, res_change); -//h263_probe: psc:3 invalid:0 res_change:0 (1588/recent_ffmpeg_parses_mpg_incorrectly.mpg) - if(valid_psc > 2*invalid_psc + 2*res_change + 3){ - return 50; - }else if(valid_psc > 2*invalid_psc) - return 25; - return 0; -} -#endif - -#if CONFIG_H261_DEMUXER -static int h261_probe(AVProbeData *p) -{ - uint32_t code= -1; - int i; - int valid_psc=0; - int invalid_psc=0; - int next_gn=0; - int src_fmt=0; - GetBitContext gb; - - init_get_bits(&gb, p->buf, p->buf_size*8); - - for(i=0; ibuf_size*8; i++){ - if ((code & 0x01ff0000) || !(code & 0xff00)) { - code = (code<<8) + get_bits(&gb, 8); - i += 7; - } else - code = (code<<1) + get_bits1(&gb); - if ((code & 0xffff0000) == 0x10000) { - int gn= (code>>12)&0xf; - if(!gn) - src_fmt= code&8; - if(gn != next_gn) invalid_psc++; - else valid_psc++; - - if(src_fmt){ // CIF - next_gn= (gn+1 )%13; - }else{ //QCIF - next_gn= (gn+1+!!gn)% 7; - } - } - } - if(valid_psc > 2*invalid_psc + 6){ - return 50; - }else if(valid_psc > 2*invalid_psc + 2) - return 25; - return 0; -} -#endif - -#if CONFIG_DTS_DEMUXER -#define DCA_MARKER_14B_BE 0x1FFFE800 -#define DCA_MARKER_14B_LE 0xFF1F00E8 -#define DCA_MARKER_RAW_BE 0x7FFE8001 -#define DCA_MARKER_RAW_LE 0xFE7F0180 -static int dts_probe(AVProbeData *p) -{ - const uint8_t *buf, *bufp; - uint32_t state = -1; - int markers[3] = {0}; - int sum, max; - - buf = p->buf; - - for(; buf < (p->buf+p->buf_size)-2; buf+=2) { - bufp = buf; - state = (state << 16) | bytestream_get_be16(&bufp); - - /* regular bitstream */ - if (state == DCA_MARKER_RAW_BE || state == DCA_MARKER_RAW_LE) - markers[0]++; - - /* 14 bits big-endian bitstream */ - if (state == DCA_MARKER_14B_BE) - if ((bytestream_get_be16(&bufp) & 0xFFF0) == 0x07F0) - markers[1]++; - - /* 14 bits little-endian bitstream */ - if (state == DCA_MARKER_14B_LE) - if ((bytestream_get_be16(&bufp) & 0xF0FF) == 0xF007) - markers[2]++; - } - sum = markers[0] + markers[1] + markers[2]; - max = markers[1] > markers[0]; - max = markers[2] > markers[max] ? 2 : max; - if (markers[max] > 3 && p->buf_size / markers[max] < 32*1024 && - markers[max] * 4 > sum * 3) - return AVPROBE_SCORE_MAX/2+1; - - return 0; -} -#endif - -#if CONFIG_DIRAC_DEMUXER -static int dirac_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == MKTAG('B', 'B', 'C', 'D')) - return AVPROBE_SCORE_MAX; - else - return 0; -} -#endif - -#if CONFIG_DNXHD_DEMUXER -static int dnxhd_probe(AVProbeData *p) -{ - static const uint8_t header[] = {0x00,0x00,0x02,0x80,0x01}; - int w, h, compression_id; - if (p->buf_size < 0x2c) - return 0; - if (memcmp(p->buf, header, 5)) - return 0; - h = AV_RB16(p->buf + 0x18); - w = AV_RB16(p->buf + 0x1a); - if (!w || !h) - return 0; - compression_id = AV_RB32(p->buf + 0x28); - if (compression_id < 1237 || compression_id > 1253) - return 0; - return AVPROBE_SCORE_MAX; -} -#endif - -#if CONFIG_AC3_DEMUXER || CONFIG_EAC3_DEMUXER -static int ac3_eac3_probe(AVProbeData *p, enum CodecID expected_codec_id) -{ - int max_frames, first_frames = 0, frames; - uint8_t *buf, *buf2, *end; - AC3HeaderInfo hdr; - GetBitContext gbc; - enum CodecID codec_id = CODEC_ID_AC3; - - max_frames = 0; - buf = p->buf; - end = buf + p->buf_size; - - for(; buf < end; buf++) { - buf2 = buf; - - for(frames = 0; buf2 < end; frames++) { - init_get_bits(&gbc, buf2, 54); - if(ff_ac3_parse_header(&gbc, &hdr) < 0) - break; - if(buf2 + hdr.frame_size > end || - av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, hdr.frame_size - 2)) - break; - if (hdr.bitstream_id > 10) - codec_id = CODEC_ID_EAC3; - buf2 += hdr.frame_size; - } - max_frames = FFMAX(max_frames, frames); - if(buf == p->buf) - first_frames = frames; - } - if(codec_id != expected_codec_id) return 0; - // keep this in sync with mp3 probe, both need to avoid - // issues with MPEG-files! - if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1; - else if(max_frames>500)return AVPROBE_SCORE_MAX/2; - else if(max_frames>=4) return AVPROBE_SCORE_MAX/4; - else if(max_frames>=1) return 1; - else return 0; -} -#endif - -#if CONFIG_AC3_DEMUXER -static int ac3_probe(AVProbeData *p) -{ - return ac3_eac3_probe(p, CODEC_ID_AC3); -} -#endif - -#if CONFIG_EAC3_DEMUXER -static int eac3_probe(AVProbeData *p) -{ - return ac3_eac3_probe(p, CODEC_ID_EAC3); -} -#endif - -#if CONFIG_AAC_DEMUXER -static int adts_aac_probe(AVProbeData *p) -{ - int max_frames = 0, first_frames = 0; - int fsize, frames; - uint8_t *buf0 = p->buf; - uint8_t *buf2; - uint8_t *buf; - uint8_t *end = buf0 + p->buf_size - 7; - - if (ff_id3v2_match(buf0)) { - buf0 += ff_id3v2_tag_len(buf0); - } - buf = buf0; - - for(; buf < end; buf= buf2+1) { - buf2 = buf; - - for(frames = 0; buf2 < end; frames++) { - uint32_t header = AV_RB16(buf2); - if((header&0xFFF6) != 0xFFF0) - break; - fsize = (AV_RB32(buf2+3)>>13) & 0x8FFF; - if(fsize < 7) - break; - buf2 += fsize; - } - max_frames = FFMAX(max_frames, frames); - if(buf == buf0) - first_frames= frames; - } - if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1; - else if(max_frames>500)return AVPROBE_SCORE_MAX/2; - else if(max_frames>=3) return AVPROBE_SCORE_MAX/4; - else if(max_frames>=1) return 1; - else return 0; -} - -static int adts_aac_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->value; - st->need_parsing = AVSTREAM_PARSE_FULL; - - ff_id3v1_read(s); - ff_id3v2_read(s); - - return 0; -} - -#endif - -/* Note: Do not forget to add new entries to the Makefile as well. */ - -#if CONFIG_AAC_DEMUXER -AVInputFormat aac_demuxer = { - "aac", - NULL_IF_CONFIG_SMALL("raw ADTS AAC"), - 0, - adts_aac_probe, - adts_aac_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "aac", - .value = CODEC_ID_AAC, -}; -#endif - -#if CONFIG_AC3_DEMUXER -AVInputFormat ac3_demuxer = { - "ac3", - NULL_IF_CONFIG_SMALL("raw AC-3"), - 0, - ac3_probe, - audio_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "ac3", - .value = CODEC_ID_AC3, -}; -#endif - -#if CONFIG_AC3_MUXER -AVOutputFormat ac3_muxer = { - "ac3", - NULL_IF_CONFIG_SMALL("raw AC-3"), - "audio/x-ac3", - "ac3", - 0, - CODEC_ID_AC3, - CODEC_ID_NONE, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_DIRAC_DEMUXER -AVInputFormat dirac_demuxer = { - "dirac", - NULL_IF_CONFIG_SMALL("raw Dirac"), - 0, - dirac_probe, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_DIRAC, -}; -#endif - -#if CONFIG_DIRAC_MUXER -AVOutputFormat dirac_muxer = { - "dirac", - NULL_IF_CONFIG_SMALL("raw Dirac"), - NULL, - "drc", - 0, - CODEC_ID_NONE, - CODEC_ID_DIRAC, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_DNXHD_DEMUXER -AVInputFormat dnxhd_demuxer = { - "dnxhd", - NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"), - 0, - dnxhd_probe, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_DNXHD, -}; -#endif - -#if CONFIG_DNXHD_MUXER -AVOutputFormat dnxhd_muxer = { - "dnxhd", - NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"), - NULL, - "dnxhd", - 0, - CODEC_ID_NONE, - CODEC_ID_DNXHD, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_DTS_DEMUXER -AVInputFormat dts_demuxer = { - "dts", - NULL_IF_CONFIG_SMALL("raw DTS"), - 0, - dts_probe, - audio_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "dts", - .value = CODEC_ID_DTS, -}; -#endif - -#if CONFIG_DTS_MUXER -AVOutputFormat dts_muxer = { - "dts", - NULL_IF_CONFIG_SMALL("raw DTS"), - "audio/x-dca", - "dts", - 0, - CODEC_ID_DTS, - CODEC_ID_NONE, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_EAC3_DEMUXER -AVInputFormat eac3_demuxer = { - "eac3", - NULL_IF_CONFIG_SMALL("raw E-AC-3"), - 0, - eac3_probe, - audio_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "eac3", - .value = CODEC_ID_EAC3, -}; -#endif - -#if CONFIG_EAC3_MUXER -AVOutputFormat eac3_muxer = { - "eac3", - NULL_IF_CONFIG_SMALL("raw E-AC-3"), - "audio/x-eac3", - "eac3", - 0, - CODEC_ID_EAC3, - CODEC_ID_NONE, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_GSM_DEMUXER -AVInputFormat gsm_demuxer = { - "gsm", - NULL_IF_CONFIG_SMALL("raw GSM"), - 0, - NULL, - audio_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "gsm", - .value = CODEC_ID_GSM, -}; -#endif - -#if CONFIG_H261_DEMUXER -AVInputFormat h261_demuxer = { - "h261", - NULL_IF_CONFIG_SMALL("raw H.261"), - 0, - h261_probe, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "h261", - .value = CODEC_ID_H261, -}; -#endif - -#if CONFIG_H261_MUXER -AVOutputFormat h261_muxer = { - "h261", - NULL_IF_CONFIG_SMALL("raw H.261"), - "video/x-h261", - "h261", - 0, - CODEC_ID_NONE, - CODEC_ID_H261, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_H263_DEMUXER -AVInputFormat h263_demuxer = { - "h263", - NULL_IF_CONFIG_SMALL("raw H.263"), - 0, - h263_probe, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, -// .extensions = "h263", //FIXME remove after writing mpeg4_probe - .value = CODEC_ID_H263, -}; -#endif - -#if CONFIG_H263_MUXER -AVOutputFormat h263_muxer = { - "h263", - NULL_IF_CONFIG_SMALL("raw H.263"), - "video/x-h263", - "h263", - 0, - CODEC_ID_NONE, - CODEC_ID_H263, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_H264_DEMUXER -AVInputFormat h264_demuxer = { - "h264", - NULL_IF_CONFIG_SMALL("raw H.264 video format"), - 0, - h264_probe, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "h26l,h264,264", //FIXME remove after writing mpeg4_probe - .value = CODEC_ID_H264, -}; -#endif - -#if CONFIG_H264_MUXER -AVOutputFormat h264_muxer = { - "h264", - NULL_IF_CONFIG_SMALL("raw H.264 video format"), - NULL, - "h264", - 0, - CODEC_ID_NONE, - CODEC_ID_H264, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_INGENIENT_DEMUXER -AVInputFormat ingenient_demuxer = { - "ingenient", - NULL_IF_CONFIG_SMALL("raw Ingenient MJPEG"), - 0, - NULL, - video_read_header, - ingenient_read_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "cgi", // FIXME - .value = CODEC_ID_MJPEG, -}; -#endif - -#if CONFIG_M4V_DEMUXER -AVInputFormat m4v_demuxer = { - "m4v", - NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"), - 0, - mpeg4video_probe, /** probing for MPEG-4 data */ - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "m4v", - .value = CODEC_ID_MPEG4, -}; -#endif - -#if CONFIG_M4V_MUXER -AVOutputFormat m4v_muxer = { - "m4v", - NULL_IF_CONFIG_SMALL("raw MPEG-4 video format"), - NULL, - "m4v", - 0, - CODEC_ID_NONE, - CODEC_ID_MPEG4, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MJPEG_DEMUXER -AVInputFormat mjpeg_demuxer = { - "mjpeg", - NULL_IF_CONFIG_SMALL("raw MJPEG video"), - 0, - NULL, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "mjpg,mjpeg", - .value = CODEC_ID_MJPEG, -}; -#endif - -#if CONFIG_MJPEG_MUXER -AVOutputFormat mjpeg_muxer = { - "mjpeg", - NULL_IF_CONFIG_SMALL("raw MJPEG video"), - "video/x-mjpeg", - "mjpg,mjpeg", - 0, - CODEC_ID_NONE, - CODEC_ID_MJPEG, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MLP_DEMUXER -AVInputFormat mlp_demuxer = { - "mlp", - NULL_IF_CONFIG_SMALL("raw MLP"), - 0, - NULL, - audio_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "mlp", - .value = CODEC_ID_MLP, -}; -#endif - -#if CONFIG_MLP_MUXER -AVOutputFormat mlp_muxer = { - "mlp", - NULL_IF_CONFIG_SMALL("raw MLP"), - NULL, - "mlp", - 0, - CODEC_ID_MLP, - CODEC_ID_NONE, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_TRUEHD_DEMUXER -AVInputFormat truehd_demuxer = { - "truehd", - NULL_IF_CONFIG_SMALL("raw TrueHD"), - 0, - NULL, - audio_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "thd", - .value = CODEC_ID_TRUEHD, -}; -#endif - -#if CONFIG_TRUEHD_MUXER -AVOutputFormat truehd_muxer = { - "truehd", - NULL_IF_CONFIG_SMALL("raw TrueHD"), - NULL, - "thd", - 0, - CODEC_ID_TRUEHD, - CODEC_ID_NONE, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MPEG1VIDEO_MUXER -AVOutputFormat mpeg1video_muxer = { - "mpeg1video", - NULL_IF_CONFIG_SMALL("raw MPEG-1 video"), - "video/x-mpeg", - "mpg,mpeg,m1v", - 0, - CODEC_ID_NONE, - CODEC_ID_MPEG1VIDEO, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MPEG2VIDEO_MUXER -AVOutputFormat mpeg2video_muxer = { - "mpeg2video", - NULL_IF_CONFIG_SMALL("raw MPEG-2 video"), - NULL, - "m2v", - 0, - CODEC_ID_NONE, - CODEC_ID_MPEG2VIDEO, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MPEGVIDEO_DEMUXER -AVInputFormat mpegvideo_demuxer = { - "mpegvideo", - NULL_IF_CONFIG_SMALL("raw MPEG video"), - 0, - mpegvideo_probe, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_MPEG1VIDEO, -}; -#endif - -#if CONFIG_CAVSVIDEO_DEMUXER -AVInputFormat cavsvideo_demuxer = { - "cavsvideo", - NULL_IF_CONFIG_SMALL("raw Chinese AVS video"), - 0, - cavsvideo_probe, - video_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .value = CODEC_ID_CAVS, -}; -#endif - -#if CONFIG_NULL_MUXER -AVOutputFormat null_muxer = { - "null", - NULL_IF_CONFIG_SMALL("raw null video format"), - NULL, - NULL, - 0, -#if HAVE_BIGENDIAN - CODEC_ID_PCM_S16BE, -#else - CODEC_ID_PCM_S16LE, -#endif - CODEC_ID_RAWVIDEO, - NULL, - null_write_packet, - .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE | AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_RAWVIDEO_DEMUXER -AVInputFormat rawvideo_demuxer = { - "rawvideo", - NULL_IF_CONFIG_SMALL("raw video format"), - 0, - NULL, - raw_read_header, - rawvideo_read_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "yuv,cif,qcif,rgb", - .value = CODEC_ID_RAWVIDEO, -}; -#endif - -#if CONFIG_RAWVIDEO_MUXER -AVOutputFormat rawvideo_muxer = { - "rawvideo", - NULL_IF_CONFIG_SMALL("raw video format"), - NULL, - "yuv,rgb", - 0, - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - NULL, - raw_write_packet, - .flags= AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_ROQ_MUXER -AVOutputFormat roq_muxer = -{ - "RoQ", - NULL_IF_CONFIG_SMALL("raw id RoQ format"), - NULL, - "roq", - 0, - CODEC_ID_ROQ_DPCM, - CODEC_ID_ROQ, - roq_write_header, - raw_write_packet, -}; -#endif - -#if CONFIG_SHORTEN_DEMUXER -AVInputFormat shorten_demuxer = { - "shn", - NULL_IF_CONFIG_SMALL("raw Shorten"), - 0, - NULL, - audio_read_header, - ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "shn", - .value = CODEC_ID_SHORTEN, -}; -#endif - -#if CONFIG_VC1_DEMUXER -AVInputFormat vc1_demuxer = { - "vc1", - NULL_IF_CONFIG_SMALL("raw VC-1"), - 0, - NULL /* vc1_probe */, - video_read_header, - ff_raw_read_partial_packet, - .extensions = "vc1", - .value = CODEC_ID_VC1, -}; -#endif - -/* PCM formats */ - -#define PCMINPUTDEF(name, long_name, ext, codec) \ -AVInputFormat pcm_ ## name ## _demuxer = {\ - #name,\ - NULL_IF_CONFIG_SMALL(long_name),\ - 0,\ - NULL,\ - raw_read_header,\ - raw_read_packet,\ - NULL,\ - pcm_read_seek,\ - .flags= AVFMT_GENERIC_INDEX,\ - .extensions = ext,\ - .value = codec,\ -}; - -#define PCMOUTPUTDEF(name, long_name, ext, codec) \ -AVOutputFormat pcm_ ## name ## _muxer = {\ - #name,\ - NULL_IF_CONFIG_SMALL(long_name),\ - NULL,\ - ext,\ - 0,\ - codec,\ - CODEC_ID_NONE,\ - NULL,\ - raw_write_packet,\ - .flags= AVFMT_NOTIMESTAMPS,\ -}; - - -#if !CONFIG_MUXERS && CONFIG_DEMUXERS -#define PCMDEF(name, long_name, ext, codec) \ - PCMINPUTDEF(name, long_name, ext, codec) -#elif CONFIG_MUXERS && !CONFIG_DEMUXERS -#define PCMDEF(name, long_name, ext, codec) \ - PCMOUTPUTDEF(name, long_name, ext, codec) -#elif CONFIG_MUXERS && CONFIG_DEMUXERS -#define PCMDEF(name, long_name, ext, codec) \ - PCMINPUTDEF(name, long_name, ext, codec)\ - PCMOUTPUTDEF(name, long_name, ext, codec) -#else -#define PCMDEF(name, long_name, ext, codec) -#endif - -#if HAVE_BIGENDIAN -#define BE_DEF(s) s -#define LE_DEF(s) NULL -#else -#define BE_DEF(s) NULL -#define LE_DEF(s) s -#endif - -PCMDEF(f64be, "PCM 64 bit floating-point big-endian format", - NULL, CODEC_ID_PCM_F64BE) - -PCMDEF(f64le, "PCM 64 bit floating-point little-endian format", - NULL, CODEC_ID_PCM_F64LE) - -PCMDEF(f32be, "PCM 32 bit floating-point big-endian format", - NULL, CODEC_ID_PCM_F32BE) - -PCMDEF(f32le, "PCM 32 bit floating-point little-endian format", - NULL, CODEC_ID_PCM_F32LE) - -PCMDEF(s32be, "PCM signed 32 bit big-endian format", - NULL, CODEC_ID_PCM_S32BE) - -PCMDEF(s32le, "PCM signed 32 bit little-endian format", - NULL, CODEC_ID_PCM_S32LE) - -PCMDEF(s24be, "PCM signed 24 bit big-endian format", - NULL, CODEC_ID_PCM_S24BE) - -PCMDEF(s24le, "PCM signed 24 bit little-endian format", - NULL, CODEC_ID_PCM_S24LE) - -PCMDEF(s16be, "PCM signed 16 bit big-endian format", - BE_DEF("sw"), CODEC_ID_PCM_S16BE) - -PCMDEF(s16le, "PCM signed 16 bit little-endian format", - LE_DEF("sw"), CODEC_ID_PCM_S16LE) - -PCMDEF(s8, "PCM signed 8 bit format", - "sb", CODEC_ID_PCM_S8) - -PCMDEF(u32be, "PCM unsigned 32 bit big-endian format", - NULL, CODEC_ID_PCM_U32BE) - -PCMDEF(u32le, "PCM unsigned 32 bit little-endian format", - NULL, CODEC_ID_PCM_U32LE) - -PCMDEF(u24be, "PCM unsigned 24 bit big-endian format", - NULL, CODEC_ID_PCM_U24BE) - -PCMDEF(u24le, "PCM unsigned 24 bit little-endian format", - NULL, CODEC_ID_PCM_U24LE) - -PCMDEF(u16be, "PCM unsigned 16 bit big-endian format", - BE_DEF("uw"), CODEC_ID_PCM_U16BE) - -PCMDEF(u16le, "PCM unsigned 16 bit little-endian format", - LE_DEF("uw"), CODEC_ID_PCM_U16LE) - -PCMDEF(u8, "PCM unsigned 8 bit format", - "ub", CODEC_ID_PCM_U8) - -PCMDEF(alaw, "PCM A-law format", - "al", CODEC_ID_PCM_ALAW) - -PCMDEF(mulaw, "PCM mu-law format", - "ul", CODEC_ID_PCM_MULAW) diff --git a/tizen/distrib/ffmpeg/libavformat/raw.h b/tizen/distrib/ffmpeg/libavformat/raw.h deleted file mode 100644 index 497c8be..0000000 --- a/tizen/distrib/ffmpeg/libavformat/raw.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * RAW muxer and demuxer - * Copyright (C) 2007 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RAW_H -#define AVFORMAT_RAW_H - -#include "avformat.h" - -int pcm_read_seek(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags); - -int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt); - -#endif /* AVFORMAT_RAW_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rdt.c b/tizen/distrib/ffmpeg/libavformat/rdt.c deleted file mode 100644 index 7dda3f3..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rdt.c +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Realmedia RTSP protocol (RDT) support. - * Copyright (c) 2007 Ronald S. Bultje - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Realmedia RTSP protocol (RDT) support - * @author Ronald S. Bultje - */ - -#include "avformat.h" -#include "libavutil/avstring.h" -#include "rtpdec.h" -#include "rdt.h" -#include "libavutil/base64.h" -#include "libavutil/md5.h" -#include "rm.h" -#include "internal.h" -#include "libavcodec/get_bits.h" - -struct RDTDemuxContext { - AVFormatContext *ic; /**< the containing (RTSP) demux context */ - /** Each RDT stream-set (represented by one RTSPStream) can contain - * multiple streams (of the same content, but with possibly different - * codecs/bitrates). Each such stream is represented by one AVStream - * in the AVFormatContext, and this variable points to the offset in - * that array such that the first is the first stream of this set. */ - AVStream **streams; - int n_streams; /**< streams with identifical content in this set */ - void *dynamic_protocol_context; - DynamicPayloadPacketHandlerProc parse_packet; - uint32_t prev_timestamp; - int prev_set_id, prev_stream_id; -}; - -RDTDemuxContext * -ff_rdt_parse_open(AVFormatContext *ic, int first_stream_of_set_idx, - void *priv_data, RTPDynamicProtocolHandler *handler) -{ - RDTDemuxContext *s = av_mallocz(sizeof(RDTDemuxContext)); - if (!s) - return NULL; - - s->ic = ic; - s->streams = &ic->streams[first_stream_of_set_idx]; - do { - s->n_streams++; - } while (first_stream_of_set_idx + s->n_streams < ic->nb_streams && - s->streams[s->n_streams]->priv_data == s->streams[0]->priv_data); - s->prev_set_id = -1; - s->prev_stream_id = -1; - s->prev_timestamp = -1; - s->parse_packet = handler ? handler->parse_packet : NULL; - s->dynamic_protocol_context = priv_data; - - return s; -} - -void -ff_rdt_parse_close(RDTDemuxContext *s) -{ - int i; - - for (i = 1; i < s->n_streams; i++) - s->streams[i]->priv_data = NULL; - - av_free(s); -} - -struct PayloadContext { - AVFormatContext *rmctx; - RMStream *rmst[MAX_STREAMS]; - uint8_t *mlti_data; - unsigned int mlti_data_size; - char buffer[RTP_MAX_PACKET_LENGTH + FF_INPUT_BUFFER_PADDING_SIZE]; - int audio_pkt_cnt; /**< remaining audio packets in rmdec */ -}; - -void -ff_rdt_calc_response_and_checksum(char response[41], char chksum[9], - const char *challenge) -{ - int ch_len = strlen (challenge), i; - unsigned char zres[16], - buf[64] = { 0xa1, 0xe9, 0x14, 0x9d, 0x0e, 0x6b, 0x3b, 0x59 }; -#define XOR_TABLE_SIZE 37 - const unsigned char xor_table[XOR_TABLE_SIZE] = { - 0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53, - 0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70, - 0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09, - 0x63, 0x11, 0x03, 0x71, 0x08, 0x08, 0x70, 0x02, - 0x10, 0x57, 0x05, 0x18, 0x54 }; - - /* some (length) checks */ - if (ch_len == 40) /* what a hack... */ - ch_len = 32; - else if (ch_len > 56) - ch_len = 56; - memcpy(buf + 8, challenge, ch_len); - - /* xor challenge bytewise with xor_table */ - for (i = 0; i < XOR_TABLE_SIZE; i++) - buf[8 + i] ^= xor_table[i]; - - av_md5_sum(zres, buf, 64); - ff_data_to_hex(response, zres, 16, 1); - - /* add tail */ - strcpy (response + 32, "01d0a8e3"); - - /* calculate checksum */ - for (i = 0; i < 8; i++) - chksum[i] = response[i * 4]; - chksum[8] = 0; -} - -static int -rdt_load_mdpr (PayloadContext *rdt, AVStream *st, int rule_nr) -{ - ByteIOContext pb; - int size; - uint32_t tag; - - /** - * Layout of the MLTI chunk: - * 4:MLTI - * 2: - * Then for each stream ([number_of_streams] times): - * 2: - * 2: - * Then for each mdpr chunk ([number_of_mdpr_chunks] times): - * 4: - * [size]: - * we skip MDPR chunks until we reach the one of the stream - * we're interested in, and forward that ([size]+[data]) to - * the RM demuxer to parse the stream-specific header data. - */ - if (!rdt->mlti_data) - return -1; - init_put_byte(&pb, rdt->mlti_data, rdt->mlti_data_size, 0, - NULL, NULL, NULL, NULL); - tag = get_le32(&pb); - if (tag == MKTAG('M', 'L', 'T', 'I')) { - int num, chunk_nr; - - /* read index of MDPR chunk numbers */ - num = get_be16(&pb); - if (rule_nr < 0 || rule_nr >= num) - return -1; - url_fskip(&pb, rule_nr * 2); - chunk_nr = get_be16(&pb); - url_fskip(&pb, (num - 1 - rule_nr) * 2); - - /* read MDPR chunks */ - num = get_be16(&pb); - if (chunk_nr >= num) - return -1; - while (chunk_nr--) - url_fskip(&pb, get_be32(&pb)); - size = get_be32(&pb); - } else { - size = rdt->mlti_data_size; - url_fseek(&pb, 0, SEEK_SET); - } - if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size) < 0) - return -1; - - return 0; -} - -/** - * Actual data handling. - */ - -int -ff_rdt_parse_header(const uint8_t *buf, int len, - int *pset_id, int *pseq_no, int *pstream_id, - int *pis_keyframe, uint32_t *ptimestamp) -{ - GetBitContext gb; - int consumed = 0, set_id, seq_no, stream_id, is_keyframe, - len_included, need_reliable; - uint32_t timestamp; - - /* skip status packets */ - while (len >= 5 && buf[1] == 0xFF /* status packet */) { - int pkt_len; - - if (!(buf[0] & 0x80)) - return -1; /* not followed by a data packet */ - - pkt_len = AV_RB16(buf+3); - buf += pkt_len; - len -= pkt_len; - consumed += pkt_len; - } - if (len < 16) - return -1; - /** - * Layout of the header (in bits): - * 1: len_included - * Flag indicating whether this header includes a length field; - * this can be used to concatenate multiple RDT packets in a - * single UDP/TCP data frame and is used to precede RDT data - * by stream status packets - * 1: need_reliable - * Flag indicating whether this header includes a "reliable - * sequence number"; these are apparently sequence numbers of - * data packets alone. For data packets, this flag is always - * set, according to the Real documentation [1] - * 5: set_id - * ID of a set of streams of identical content, possibly with - * different codecs or bitrates - * 1: is_reliable - * Flag set for certain streams deemed less tolerable for packet - * loss - * 16: seq_no - * Packet sequence number; if >=0xFF00, this is a non-data packet - * containing stream status info, the second byte indicates the - * type of status packet (see wireshark docs / source code [2]) - * if (len_included) { - * 16: packet_len - * } else { - * packet_len = remainder of UDP/TCP frame - * } - * 1: is_back_to_back - * Back-to-Back flag; used for timing, set for one in every 10 - * packets, according to the Real documentation [1] - * 1: is_slow_data - * Slow-data flag; currently unused, according to Real docs [1] - * 5: stream_id - * ID of the stream within this particular set of streams - * 1: is_no_keyframe - * Non-keyframe flag (unset if packet belongs to a keyframe) - * 32: timestamp (PTS) - * if (set_id == 0x1F) { - * 16: set_id (extended set-of-streams ID; see set_id) - * } - * if (need_reliable) { - * 16: reliable_seq_no - * Reliable sequence number (see need_reliable) - * } - * if (stream_id == 0x3F) { - * 16: stream_id (extended stream ID; see stream_id) - * } - * [1] https://protocol.helixcommunity.org/files/2005/devdocs/RDT_Feature_Level_20.txt - * [2] http://www.wireshark.org/docs/dfref/r/rdt.html and - * http://anonsvn.wireshark.org/viewvc/trunk/epan/dissectors/packet-rdt.c - */ - init_get_bits(&gb, buf, len << 3); - len_included = get_bits1(&gb); - need_reliable = get_bits1(&gb); - set_id = get_bits(&gb, 5); - skip_bits(&gb, 1); - seq_no = get_bits(&gb, 16); - if (len_included) - skip_bits(&gb, 16); - skip_bits(&gb, 2); - stream_id = get_bits(&gb, 5); - is_keyframe = !get_bits1(&gb); - timestamp = get_bits_long(&gb, 32); - if (set_id == 0x1f) - set_id = get_bits(&gb, 16); - if (need_reliable) - skip_bits(&gb, 16); - if (stream_id == 0x1f) - stream_id = get_bits(&gb, 16); - - if (pset_id) *pset_id = set_id; - if (pseq_no) *pseq_no = seq_no; - if (pstream_id) *pstream_id = stream_id; - if (pis_keyframe) *pis_keyframe = is_keyframe; - if (ptimestamp) *ptimestamp = timestamp; - - return consumed + (get_bits_count(&gb) >> 3); -} - -/**< return 0 on packet, no more left, 1 on packet, 1 on partial packet... */ -static int -rdt_parse_packet (AVFormatContext *ctx, PayloadContext *rdt, AVStream *st, - AVPacket *pkt, uint32_t *timestamp, - const uint8_t *buf, int len, int flags) -{ - int seq = 1, res; - ByteIOContext pb; - - if (rdt->audio_pkt_cnt == 0) { - int pos; - - init_put_byte(&pb, buf, len, 0, NULL, NULL, NULL, NULL); - flags = (flags & RTP_FLAG_KEY) ? 2 : 0; - res = ff_rm_parse_packet (rdt->rmctx, &pb, st, rdt->rmst[st->index], len, pkt, - &seq, flags, *timestamp); - pos = url_ftell(&pb); - if (res < 0) - return res; - if (res > 0) { - if (st->codec->codec_id == CODEC_ID_AAC) { - memcpy (rdt->buffer, buf + pos, len - pos); - rdt->rmctx->pb = av_alloc_put_byte (rdt->buffer, len - pos, 0, - NULL, NULL, NULL, NULL); - } - goto get_cache; - } - } else { -get_cache: - rdt->audio_pkt_cnt = - ff_rm_retrieve_cache (rdt->rmctx, rdt->rmctx->pb, - st, rdt->rmst[st->index], pkt); - if (rdt->audio_pkt_cnt == 0 && - st->codec->codec_id == CODEC_ID_AAC) - av_freep(&rdt->rmctx->pb); - } - pkt->stream_index = st->index; - pkt->pts = *timestamp; - - return rdt->audio_pkt_cnt > 0; -} - -int -ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt, - const uint8_t *buf, int len) -{ - int seq_no, flags = 0, stream_id, set_id, is_keyframe; - uint32_t timestamp; - int rv= 0; - - if (!s->parse_packet) - return -1; - - if (!buf && s->prev_stream_id != -1) { - /* return the next packets, if any */ - timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned.... - rv= s->parse_packet(s->ic, s->dynamic_protocol_context, - s->streams[s->prev_stream_id], - pkt, ×tamp, NULL, 0, flags); - return rv; - } - - if (len < 12) - return -1; - rv = ff_rdt_parse_header(buf, len, &set_id, &seq_no, &stream_id, &is_keyframe, ×tamp); - if (rv < 0) - return rv; - if (is_keyframe && - (set_id != s->prev_set_id || timestamp != s->prev_timestamp || - stream_id != s->prev_stream_id)) { - flags |= RTP_FLAG_KEY; - s->prev_set_id = set_id; - s->prev_timestamp = timestamp; - } - s->prev_stream_id = stream_id; - buf += rv; - len -= rv; - - if (s->prev_stream_id >= s->n_streams) { - s->prev_stream_id = -1; - return -1; - } - - rv = s->parse_packet(s->ic, s->dynamic_protocol_context, - s->streams[s->prev_stream_id], - pkt, ×tamp, buf, len, flags); - - return rv; -} - -void -ff_rdt_subscribe_rule (char *cmd, int size, - int stream_nr, int rule_nr) -{ - av_strlcatf(cmd, size, "stream=%d;rule=%d,stream=%d;rule=%d", - stream_nr, rule_nr * 2, stream_nr, rule_nr * 2 + 1); -} - -static unsigned char * -rdt_parse_b64buf (unsigned int *target_len, const char *p) -{ - unsigned char *target; - int len = strlen(p); - if (*p == '\"') { - p++; - len -= 2; /* skip embracing " at start/end */ - } - *target_len = len * 3 / 4; - target = av_mallocz(*target_len + FF_INPUT_BUFFER_PADDING_SIZE); - av_base64_decode(target, p, *target_len); - return target; -} - -static int -rdt_parse_sdp_line (AVFormatContext *s, int st_index, - PayloadContext *rdt, const char *line) -{ - AVStream *stream = s->streams[st_index]; - const char *p = line; - - if (av_strstart(p, "OpaqueData:buffer;", &p)) { - rdt->mlti_data = rdt_parse_b64buf(&rdt->mlti_data_size, p); - } else if (av_strstart(p, "StartTime:integer;", &p)) - stream->first_dts = atoi(p); - else if (av_strstart(p, "ASMRuleBook:string;", &p)) { - int n, first = -1; - - for (n = 0; n < s->nb_streams; n++) - if (s->streams[n]->priv_data == stream->priv_data) { - if (first == -1) first = n; - rdt->rmst[s->streams[n]->index] = ff_rm_alloc_rmstream(); - rdt_load_mdpr(rdt, s->streams[n], (n - first) * 2); - - if (s->streams[n]->codec->codec_id == CODEC_ID_AAC) - s->streams[n]->codec->frame_size = 1; // FIXME - } - } - - return 0; -} - -static void -real_parse_asm_rule(AVStream *st, const char *p, const char *end) -{ - do { - /* can be either averagebandwidth= or AverageBandwidth= */ - if (sscanf(p, " %*1[Aa]verage%*1[Bb]andwidth=%d", &st->codec->bit_rate) == 1) - break; - if (!(p = strchr(p, ',')) || p > end) - p = end; - p++; - } while (p < end); -} - -static AVStream * -add_dstream(AVFormatContext *s, AVStream *orig_st) -{ - AVStream *st; - - if (!(st = av_new_stream(s, 0))) - return NULL; - st->codec->codec_type = orig_st->codec->codec_type; - st->priv_data = orig_st->priv_data; - st->first_dts = orig_st->first_dts; - - return st; -} - -static void -real_parse_asm_rulebook(AVFormatContext *s, AVStream *orig_st, - const char *p) -{ - const char *end; - int n_rules, odd = 0; - AVStream *st; - - /** - * The ASMRuleBook contains a list of comma-separated strings per rule, - * and each rule is separated by a ;. The last one also has a ; at the - * end so we can use it as delimiter. - * Every rule occurs twice, once for when the RTSP packet header marker - * is set and once for if it isn't. We only read the first because we - * don't care much (that's what the "odd" variable is for). - * Each rule contains a set of one or more statements, optionally - * preceeded by a single condition. If there's a condition, the rule - * starts with a '#'. Multiple conditions are merged between brackets, - * so there are never multiple conditions spread out over separate - * statements. Generally, these conditions are bitrate limits (min/max) - * for multi-bitrate streams. - */ - if (*p == '\"') p++; - for (n_rules = 0; s->nb_streams < MAX_STREAMS;) { - if (!(end = strchr(p, ';'))) - break; - if (!odd && end != p) { - if (n_rules > 0) - st = add_dstream(s, orig_st); - else - st = orig_st; - real_parse_asm_rule(st, p, end); - n_rules++; - } - p = end + 1; - odd ^= 1; - } -} - -void -ff_real_parse_sdp_a_line (AVFormatContext *s, int stream_index, - const char *line) -{ - const char *p = line; - - if (av_strstart(p, "ASMRuleBook:string;", &p)) - real_parse_asm_rulebook(s, s->streams[stream_index], p); -} - -static PayloadContext * -rdt_new_context (void) -{ - PayloadContext *rdt = av_mallocz(sizeof(PayloadContext)); - - av_open_input_stream(&rdt->rmctx, NULL, "", &rdt_demuxer, NULL); - - return rdt; -} - -static void -rdt_free_context (PayloadContext *rdt) -{ - int i; - - for (i = 0; i < MAX_STREAMS; i++) - if (rdt->rmst[i]) { - ff_rm_free_rmstream(rdt->rmst[i]); - av_freep(&rdt->rmst[i]); - } - if (rdt->rmctx) - av_close_input_stream(rdt->rmctx); - av_freep(&rdt->mlti_data); - av_free(rdt); -} - -#define RDT_HANDLER(n, s, t) \ -static RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \ - .enc_name = s, \ - .codec_type = t, \ - .codec_id = CODEC_ID_NONE, \ - .parse_sdp_a_line = rdt_parse_sdp_line, \ - .open = rdt_new_context, \ - .close = rdt_free_context, \ - .parse_packet = rdt_parse_packet \ -}; - -RDT_HANDLER(live_video, "x-pn-multirate-realvideo-live", AVMEDIA_TYPE_VIDEO); -RDT_HANDLER(live_audio, "x-pn-multirate-realaudio-live", AVMEDIA_TYPE_AUDIO); -RDT_HANDLER(video, "x-pn-realvideo", AVMEDIA_TYPE_VIDEO); -RDT_HANDLER(audio, "x-pn-realaudio", AVMEDIA_TYPE_AUDIO); - -void av_register_rdt_dynamic_payload_handlers(void) -{ - ff_register_dynamic_payload_handler(&ff_rdt_video_handler); - ff_register_dynamic_payload_handler(&ff_rdt_audio_handler); - ff_register_dynamic_payload_handler(&ff_rdt_live_video_handler); - ff_register_dynamic_payload_handler(&ff_rdt_live_audio_handler); -} diff --git a/tizen/distrib/ffmpeg/libavformat/rdt.h b/tizen/distrib/ffmpeg/libavformat/rdt.h deleted file mode 100644 index 1592c2f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rdt.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Realmedia RTSP (RDT) definitions - * Copyright (c) 2007 Ronald S. Bultje - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RDT_H -#define AVFORMAT_RDT_H - -#include -#include "avformat.h" -#include "rtpdec.h" - -typedef struct RDTDemuxContext RDTDemuxContext; - -/** - * Allocate and init the RDT parsing context. - * @param ic the containing RTSP demuxer context - * @param first_stream_of_set_idx index to the first AVStream in the RTSP - * demuxer context's ic->streams array that is part of this - * particular stream's set of streams (with identical content) - * @param priv_data private data of the payload data handler context - * @param handler pointer to the parse_packet() payload parsing function - * @return a newly allocated RDTDemuxContext. Free with ff_rdt_parse_close(). - */ -RDTDemuxContext *ff_rdt_parse_open(AVFormatContext *ic, - int first_stream_of_set_idx, - void *priv_data, - RTPDynamicProtocolHandler *handler); -void ff_rdt_parse_close(RDTDemuxContext *s); - -/** - * Calculate the response (RealChallenge2 in the RTSP header) to the - * challenge (RealChallenge1 in the RTSP header from the Real/Helix - * server), which is used as some sort of client validation. - * - * @param response pointer to response buffer, it should be at least 41 bytes - * (40 data + 1 zero) bytes long. - * @param chksum pointer to buffer containing a checksum of the response, - * it should be at least 9 (8 data + 1 zero) bytes long. - * @param challenge pointer to the RealChallenge1 value provided by the - * server. - */ -void ff_rdt_calc_response_and_checksum(char response[41], char chksum[9], - const char *challenge); - -/** - * Register RDT-related dynamic payload handlers with our cache. - */ -void av_register_rdt_dynamic_payload_handlers(void); - -/** - * Add subscription information to Subscribe parameter string. - * - * @param cmd string to write the subscription information into. - * @param size size of cmd. - * @param stream_nr stream number. - * @param rule_nr rule number to conform to. - */ -void ff_rdt_subscribe_rule(char *cmd, int size, - int stream_nr, int rule_nr); - -/** - * Parse RDT-style packet header. - * - * @param buf input buffer - * @param len length of input buffer - * @param set_id will be set to the set ID this packet belongs to - * @param seq_no will be set to the sequence number of the packet - * @param stream_id will be set to the stream ID this packet belongs to - * @param is_keyframe will be whether this packet belongs to a keyframe - * @param timestamp will be set to the timestamp of the packet - * @return the amount of bytes consumed, or <0 on error - */ -int ff_rdt_parse_header(const uint8_t *buf, int len, - int *set_id, int *seq_no, int *stream_id, - int *is_keyframe, uint32_t *timestamp); - -/** - * Parse RDT-style packet data (header + media data). - * Usage similar to rtp_parse_packet(). - */ -int ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt, - const uint8_t *buf, int len); - -/** - * Parse a server-related SDP line. - * - * @param s the RTSP AVFormatContext - * @param stream_index the index of the first stream in the set represented - * by the SDP m= line (in s->streams) - * @param buf the SDP line - */ -void ff_real_parse_sdp_a_line(AVFormatContext *s, int stream_index, - const char *buf); - -#endif /* AVFORMAT_RDT_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/riff.c b/tizen/distrib/ffmpeg/libavformat/riff.c deleted file mode 100644 index 04b7108..0000000 --- a/tizen/distrib/ffmpeg/libavformat/riff.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * RIFF codec tags - * Copyright (c) 2000 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/avcodec.h" -#include "avformat.h" -#include "riff.h" -#include "libavcodec/bytestream.h" - -/* Note: when encoding, the first matching tag is used, so order is - important if multiple tags possible for a given codec. */ -const AVCodecTag ff_codec_bmp_tags[] = { - { CODEC_ID_H264, MKTAG('H', '2', '6', '4') }, - { CODEC_ID_H264, MKTAG('h', '2', '6', '4') }, - { CODEC_ID_H264, MKTAG('X', '2', '6', '4') }, - { CODEC_ID_H264, MKTAG('x', '2', '6', '4') }, - { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, - { CODEC_ID_H264, MKTAG('V', 'S', 'S', 'H') }, - { CODEC_ID_H263, MKTAG('H', '2', '6', '3') }, - { CODEC_ID_H263, MKTAG('X', '2', '6', '3') }, - { CODEC_ID_H263, MKTAG('T', '2', '6', '3') }, - { CODEC_ID_H263, MKTAG('L', '2', '6', '3') }, - { CODEC_ID_H263, MKTAG('V', 'X', '1', 'K') }, - { CODEC_ID_H263, MKTAG('Z', 'y', 'G', 'o') }, - { CODEC_ID_H263P, MKTAG('H', '2', '6', '3') }, - { CODEC_ID_H263I, MKTAG('I', '2', '6', '3') }, /* intel h263 */ - { CODEC_ID_H261, MKTAG('H', '2', '6', '1') }, - { CODEC_ID_H263P, MKTAG('U', '2', '6', '3') }, - { CODEC_ID_H263P, MKTAG('v', 'i', 'v', '1') }, - { CODEC_ID_MPEG4, MKTAG('F', 'M', 'P', '4') }, - { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, - { CODEC_ID_MPEG4, MKTAG('D', 'X', '5', '0') }, - { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, - { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') }, - { CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') }, - { CODEC_ID_MPEG4, MKTAG( 4 , 0 , 0 , 0 ) }, /* some broken avi use this */ - { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', '1') }, - { CODEC_ID_MPEG4, MKTAG('B', 'L', 'Z', '0') }, - { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, - { CODEC_ID_MPEG4, MKTAG('U', 'M', 'P', '4') }, - { CODEC_ID_MPEG4, MKTAG('W', 'V', '1', 'F') }, - { CODEC_ID_MPEG4, MKTAG('S', 'E', 'D', 'G') }, - { CODEC_ID_MPEG4, MKTAG('R', 'M', 'P', '4') }, - { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, - { CODEC_ID_MPEG4, MKTAG('F', 'F', 'D', 'S') }, - { CODEC_ID_MPEG4, MKTAG('F', 'V', 'F', 'W') }, - { CODEC_ID_MPEG4, MKTAG('D', 'C', 'O', 'D') }, - { CODEC_ID_MPEG4, MKTAG('M', 'V', 'X', 'M') }, - { CODEC_ID_MPEG4, MKTAG('P', 'M', '4', 'V') }, - { CODEC_ID_MPEG4, MKTAG('S', 'M', 'P', '4') }, - { CODEC_ID_MPEG4, MKTAG('D', 'X', 'G', 'M') }, - { CODEC_ID_MPEG4, MKTAG('V', 'I', 'D', 'M') }, - { CODEC_ID_MPEG4, MKTAG('M', '4', 'T', '3') }, - { CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'X') }, - { CODEC_ID_MPEG4, MKTAG('H', 'D', 'X', '4') }, /* flipped video */ - { CODEC_ID_MPEG4, MKTAG('D', 'M', 'K', '2') }, - { CODEC_ID_MPEG4, MKTAG('D', 'I', 'G', 'I') }, - { CODEC_ID_MPEG4, MKTAG('I', 'N', 'M', 'C') }, - { CODEC_ID_MPEG4, MKTAG('E', 'P', 'H', 'V') }, /* Ephv MPEG-4 */ - { CODEC_ID_MPEG4, MKTAG('E', 'M', '4', 'A') }, - { CODEC_ID_MPEG4, MKTAG('M', '4', 'C', 'C') }, /* Divio MPEG-4 */ - { CODEC_ID_MPEG4, MKTAG('S', 'N', '4', '0') }, - { CODEC_ID_MPEG4, MKTAG('V', 'S', 'P', 'X') }, - { CODEC_ID_MPEG4, MKTAG('U', 'L', 'D', 'X') }, - { CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'V') }, - { CODEC_ID_MPEG4, MKTAG('S', 'I', 'P', 'P') }, /* Samsung SHR-6040 */ - { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3') }, /* default signature when using MSMPEG4 */ - { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') }, - { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', 'G', '3') }, - { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '5') }, - { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '6') }, - { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '4') }, - { CODEC_ID_MSMPEG4V3, MKTAG('D', 'V', 'X', '3') }, - { CODEC_ID_MSMPEG4V3, MKTAG('A', 'P', '4', '1') }, - { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '1') }, - { CODEC_ID_MSMPEG4V3, MKTAG('C', 'O', 'L', '0') }, - { CODEC_ID_MSMPEG4V2, MKTAG('M', 'P', '4', '2') }, - { CODEC_ID_MSMPEG4V2, MKTAG('D', 'I', 'V', '2') }, - { CODEC_ID_MSMPEG4V1, MKTAG('M', 'P', 'G', '4') }, - { CODEC_ID_MSMPEG4V1, MKTAG('M', 'P', '4', '1') }, - { CODEC_ID_WMV1, MKTAG('W', 'M', 'V', '1') }, - { CODEC_ID_WMV2, MKTAG('W', 'M', 'V', '2') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'd') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'd') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'l') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '2', '5') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', '0') }, - { CODEC_ID_DVVIDEO, MKTAG('c', 'd', 'v', 'c') }, /* Canopus DV */ - { CODEC_ID_DVVIDEO, MKTAG('C', 'D', 'V', 'H') }, /* Canopus DV */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 's') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') }, - { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '1') }, - { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '2') }, - { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', 'g', '2') }, - { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'P', 'E', 'G') }, - { CODEC_ID_MPEG1VIDEO, MKTAG('P', 'I', 'M', '1') }, - { CODEC_ID_MPEG2VIDEO, MKTAG('P', 'I', 'M', '2') }, - { CODEC_ID_MPEG1VIDEO, MKTAG('V', 'C', 'R', '2') }, - { CODEC_ID_MPEG1VIDEO, MKTAG( 1 , 0 , 0 , 16) }, - { CODEC_ID_MPEG2VIDEO, MKTAG( 2 , 0 , 0 , 16) }, - { CODEC_ID_MPEG4, MKTAG( 4 , 0 , 0 , 16) }, - { CODEC_ID_MPEG2VIDEO, MKTAG('D', 'V', 'R', ' ') }, - { CODEC_ID_MPEG2VIDEO, MKTAG('M', 'M', 'E', 'S') }, - { CODEC_ID_MPEG2VIDEO, MKTAG('L', 'M', 'P', '2') }, /* Lead MPEG2 in avi */ - { CODEC_ID_MPEG2VIDEO, MKTAG('s', 'l', 'i', 'f') }, - { CODEC_ID_MPEG2VIDEO, MKTAG('E', 'M', '2', 'V') }, - { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') }, - { CODEC_ID_MJPEG, MKTAG('L', 'J', 'P', 'G') }, - { CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') }, - { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, - { CODEC_ID_LJPEG, MKTAG('L', 'J', 'P', 'G') }, - { CODEC_ID_MJPEG, MKTAG('J', 'P', 'G', 'L') }, /* Pegasus lossless JPEG */ - { CODEC_ID_JPEGLS, MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - encoder */ - { CODEC_ID_MJPEG, MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */ - { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, - { CODEC_ID_MJPEG, MKTAG('I', 'J', 'P', 'G') }, - { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, - { CODEC_ID_MJPEG, MKTAG('A', 'C', 'D', 'V') }, - { CODEC_ID_MJPEG, MKTAG('Q', 'I', 'V', 'G') }, - { CODEC_ID_MJPEG, MKTAG('S', 'L', 'M', 'J') }, /* SL M-JPEG */ - { CODEC_ID_MJPEG, MKTAG('C', 'J', 'P', 'G') }, /* Creative Webcam JPEG */ - { CODEC_ID_MJPEG, MKTAG('I', 'J', 'L', 'V') }, /* Intel JPEG Library Video Codec */ - { CODEC_ID_MJPEG, MKTAG('M', 'V', 'J', 'P') }, /* Midvid JPEG Video Codec */ - { CODEC_ID_MJPEG, MKTAG('A', 'V', 'I', '1') }, - { CODEC_ID_MJPEG, MKTAG('A', 'V', 'I', '2') }, - { CODEC_ID_MJPEG, MKTAG('M', 'T', 'S', 'J') }, - { CODEC_ID_MJPEG, MKTAG('Z', 'J', 'P', 'G') }, /* Paradigm Matrix M-JPEG Codec */ - { CODEC_ID_HUFFYUV, MKTAG('H', 'F', 'Y', 'U') }, - { CODEC_ID_FFVHUFF, MKTAG('F', 'F', 'V', 'H') }, - { CODEC_ID_CYUV, MKTAG('C', 'Y', 'U', 'V') }, - { CODEC_ID_RAWVIDEO, MKTAG( 0 , 0 , 0 , 0 ) }, - { CODEC_ID_RAWVIDEO, MKTAG( 3 , 0 , 0 , 0 ) }, - { CODEC_ID_RAWVIDEO, MKTAG('I', '4', '2', '0') }, - { CODEC_ID_RAWVIDEO, MKTAG('Y', 'U', 'Y', '2') }, - { CODEC_ID_RAWVIDEO, MKTAG('Y', '4', '2', '2') }, - { CODEC_ID_RAWVIDEO, MKTAG('V', '4', '2', '2') }, - { CODEC_ID_RAWVIDEO, MKTAG('Y', 'U', 'N', 'V') }, - { CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'N', 'V') }, - { CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'N', 'Y') }, - { CODEC_ID_RAWVIDEO, MKTAG('u', 'y', 'v', '1') }, - { CODEC_ID_RAWVIDEO, MKTAG('2', 'V', 'u', '1') }, - { CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, - { CODEC_ID_RAWVIDEO, MKTAG('P', '4', '2', '2') }, - { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', '1', '2') }, - { CODEC_ID_RAWVIDEO, MKTAG('U', 'Y', 'V', 'Y') }, - { CODEC_ID_RAWVIDEO, MKTAG('V', 'Y', 'U', 'Y') }, - { CODEC_ID_RAWVIDEO, MKTAG('I', 'Y', 'U', 'V') }, - { CODEC_ID_RAWVIDEO, MKTAG('Y', '8', '0', '0') }, - { CODEC_ID_RAWVIDEO, MKTAG('H', 'D', 'Y', 'C') }, - { CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', 'U', '9') }, - { CODEC_ID_RAWVIDEO, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */ - { CODEC_ID_FRWU, MKTAG('F', 'R', 'W', 'U') }, - { CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, - { CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, - { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '1') }, - { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '2') }, - { CODEC_ID_INDEO4, MKTAG('I', 'V', '4', '1') }, - { CODEC_ID_INDEO5, MKTAG('I', 'V', '5', '0') }, - { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, - { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') }, - { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') }, - { CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') }, - { CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') }, - { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, - { CODEC_ID_VP6F, MKTAG('V', 'P', '6', 'F') }, - { CODEC_ID_VP6F, MKTAG('F', 'L', 'V', '4') }, - { CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') }, - { CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') }, - { CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') }, - { CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') }, - { CODEC_ID_XAN_WC4, MKTAG('X', 'x', 'a', 'n') }, - { CODEC_ID_MIMIC, MKTAG('L', 'M', '2', '0') }, - { CODEC_ID_MSRLE, MKTAG('m', 'r', 'l', 'e') }, - { CODEC_ID_MSRLE, MKTAG( 1 , 0 , 0 , 0 ) }, - { CODEC_ID_MSRLE, MKTAG( 2 , 0 , 0 , 0 ) }, - { CODEC_ID_MSVIDEO1, MKTAG('M', 'S', 'V', 'C') }, - { CODEC_ID_MSVIDEO1, MKTAG('m', 's', 'v', 'c') }, - { CODEC_ID_MSVIDEO1, MKTAG('C', 'R', 'A', 'M') }, - { CODEC_ID_MSVIDEO1, MKTAG('c', 'r', 'a', 'm') }, - { CODEC_ID_MSVIDEO1, MKTAG('W', 'H', 'A', 'M') }, - { CODEC_ID_MSVIDEO1, MKTAG('w', 'h', 'a', 'm') }, - { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, - { CODEC_ID_TRUEMOTION1, MKTAG('D', 'U', 'C', 'K') }, - { CODEC_ID_TRUEMOTION1, MKTAG('P', 'V', 'E', 'Z') }, - { CODEC_ID_MSZH, MKTAG('M', 'S', 'Z', 'H') }, - { CODEC_ID_ZLIB, MKTAG('Z', 'L', 'I', 'B') }, - { CODEC_ID_SNOW, MKTAG('S', 'N', 'O', 'W') }, - { CODEC_ID_4XM, MKTAG('4', 'X', 'M', 'V') }, - { CODEC_ID_FLV1, MKTAG('F', 'L', 'V', '1') }, - { CODEC_ID_FLASHSV, MKTAG('F', 'S', 'V', '1') }, - { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, - { CODEC_ID_TSCC, MKTAG('t', 's', 'c', 'c') }, - { CODEC_ID_ULTI, MKTAG('U', 'L', 'T', 'I') }, - { CODEC_ID_VIXL, MKTAG('V', 'I', 'X', 'L') }, - { CODEC_ID_QPEG, MKTAG('Q', 'P', 'E', 'G') }, - { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '0') }, - { CODEC_ID_QPEG, MKTAG('Q', '1', '.', '1') }, - { CODEC_ID_WMV3, MKTAG('W', 'M', 'V', '3') }, - { CODEC_ID_VC1, MKTAG('W', 'V', 'C', '1') }, - { CODEC_ID_VC1, MKTAG('W', 'M', 'V', 'A') }, - { CODEC_ID_LOCO, MKTAG('L', 'O', 'C', 'O') }, - { CODEC_ID_WNV1, MKTAG('W', 'N', 'V', '1') }, - { CODEC_ID_AASC, MKTAG('A', 'A', 'S', 'C') }, - { CODEC_ID_INDEO2, MKTAG('R', 'T', '2', '1') }, - { CODEC_ID_FRAPS, MKTAG('F', 'P', 'S', '1') }, - { CODEC_ID_THEORA, MKTAG('t', 'h', 'e', 'o') }, - { CODEC_ID_TRUEMOTION2, MKTAG('T', 'M', '2', '0') }, - { CODEC_ID_CSCD, MKTAG('C', 'S', 'C', 'D') }, - { CODEC_ID_ZMBV, MKTAG('Z', 'M', 'B', 'V') }, - { CODEC_ID_KMVC, MKTAG('K', 'M', 'V', 'C') }, - { CODEC_ID_CAVS, MKTAG('C', 'A', 'V', 'S') }, - { CODEC_ID_JPEG2000, MKTAG('M', 'J', '2', 'C') }, - { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') }, - { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, - { CODEC_ID_PNG, MKTAG('M', 'P', 'N', 'G') }, - { CODEC_ID_PNG, MKTAG('P', 'N', 'G', '1') }, - { CODEC_ID_CLJR, MKTAG('c', 'l', 'j', 'r') }, - { CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, - { CODEC_ID_RPZA, MKTAG('a', 'z', 'p', 'r') }, - { CODEC_ID_RPZA, MKTAG('R', 'P', 'Z', 'A') }, - { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, - { CODEC_ID_SP5X, MKTAG('S', 'P', '5', '4') }, - { CODEC_ID_AURA, MKTAG('A', 'U', 'R', 'A') }, - { CODEC_ID_AURA2, MKTAG('A', 'U', 'R', '2') }, - { CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') }, - { CODEC_ID_KGV1, MKTAG('K', 'G', 'V', '1') }, - { CODEC_ID_NONE, 0 } -}; - -const AVCodecTag ff_codec_wav_tags[] = { - { CODEC_ID_PCM_S16LE, 0x0001 }, - { CODEC_ID_PCM_U8, 0x0001 }, /* must come after s16le in this list */ - { CODEC_ID_PCM_S24LE, 0x0001 }, - { CODEC_ID_PCM_S32LE, 0x0001 }, - { CODEC_ID_ADPCM_MS, 0x0002 }, - { CODEC_ID_PCM_F32LE, 0x0003 }, - { CODEC_ID_PCM_F64LE, 0x0003 }, /* must come after f32le in this list */ - { CODEC_ID_PCM_ALAW, 0x0006 }, - { CODEC_ID_PCM_MULAW, 0x0007 }, - { CODEC_ID_WMAVOICE, 0x000A }, - { CODEC_ID_ADPCM_IMA_WAV, 0x0011 }, - { CODEC_ID_PCM_ZORK, 0x0011 }, /* must come after adpcm_ima_wav in this list */ - { CODEC_ID_ADPCM_YAMAHA, 0x0020 }, - { CODEC_ID_TRUESPEECH, 0x0022 }, - { CODEC_ID_GSM_MS, 0x0031 }, - { CODEC_ID_ADPCM_G726, 0x0045 }, - { CODEC_ID_MP2, 0x0050 }, - { CODEC_ID_MP3, 0x0055 }, - { CODEC_ID_AMR_NB, 0x0057 }, - { CODEC_ID_AMR_WB, 0x0058 }, - { CODEC_ID_ADPCM_IMA_DK4, 0x0061 }, /* rogue format number */ - { CODEC_ID_ADPCM_IMA_DK3, 0x0062 }, /* rogue format number */ - { CODEC_ID_ADPCM_IMA_WAV, 0x0069 }, - { CODEC_ID_VOXWARE, 0x0075 }, - { CODEC_ID_AAC, 0x00ff }, - { CODEC_ID_SIPR, 0x0130 }, - { CODEC_ID_WMAV1, 0x0160 }, - { CODEC_ID_WMAV2, 0x0161 }, - { CODEC_ID_WMAPRO, 0x0162 }, - { CODEC_ID_WMALOSSLESS, 0x0163 }, - { CODEC_ID_ADPCM_CT, 0x0200 }, - { CODEC_ID_ATRAC3, 0x0270 }, - { CODEC_ID_IMC, 0x0401 }, - { CODEC_ID_GSM_MS, 0x1500 }, - { CODEC_ID_TRUESPEECH, 0x1501 }, - { CODEC_ID_AC3, 0x2000 }, - { CODEC_ID_DTS, 0x2001 }, - { CODEC_ID_SONIC, 0x2048 }, - { CODEC_ID_SONIC_LS, 0x2048 }, - { CODEC_ID_PCM_MULAW, 0x6c75 }, - { CODEC_ID_AAC, 0x706d }, - { CODEC_ID_AAC, 0x4143 }, - { CODEC_ID_FLAC, 0xF1AC }, - { CODEC_ID_ADPCM_SWF, ('S'<<8)+'F' }, - { CODEC_ID_VORBIS, ('V'<<8)+'o' }, //HACK/FIXME, does vorbis in WAV/AVI have an (in)official id? - - /* FIXME: All of the IDs below are not 16 bit and thus illegal. */ - // for NuppelVideo (nuv.c) - { CODEC_ID_PCM_S16LE, MKTAG('R', 'A', 'W', 'A') }, - { CODEC_ID_MP3, MKTAG('L', 'A', 'M', 'E') }, - { CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') }, - { CODEC_ID_NONE, 0 }, -}; - -#if CONFIG_MUXERS -int64_t ff_start_tag(ByteIOContext *pb, const char *tag) -{ - put_tag(pb, tag); - put_le32(pb, 0); - return url_ftell(pb); -} - -void ff_end_tag(ByteIOContext *pb, int64_t start) -{ - int64_t pos; - - pos = url_ftell(pb); - url_fseek(pb, start - 4, SEEK_SET); - put_le32(pb, (uint32_t)(pos - start)); - url_fseek(pb, pos, SEEK_SET); -} - -/* WAVEFORMATEX header */ -/* returns the size or -1 on error */ -int ff_put_wav_header(ByteIOContext *pb, AVCodecContext *enc) -{ - int bps, blkalign, bytespersec; - int hdrsize = 18; - int waveformatextensible; - uint8_t temp[256]; - uint8_t *riff_extradata= temp; - uint8_t *riff_extradata_start= temp; - - if(!enc->codec_tag || enc->codec_tag > 0xffff) - return -1; - waveformatextensible = (enc->channels > 2 && enc->channel_layout) - || enc->sample_rate > 48000 - || av_get_bits_per_sample(enc->codec_id) > 16; - - if (waveformatextensible) { - put_le16(pb, 0xfffe); - } else { - put_le16(pb, enc->codec_tag); - } - put_le16(pb, enc->channels); - put_le32(pb, enc->sample_rate); - if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) { - bps = 0; - } else if (enc->codec_id == CODEC_ID_ADPCM_G726) { - bps = 4; - } else { - if (!(bps = av_get_bits_per_sample(enc->codec_id))) - bps = 16; // default to 16 - } - if(bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample){ - av_log(enc, AV_LOG_WARNING, "requested bits_per_coded_sample (%d) and actually stored (%d) differ\n", enc->bits_per_coded_sample, bps); - } - - if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_AC3) { - blkalign = enc->frame_size; //this is wrong, but it seems many demuxers do not work if this is set correctly - //blkalign = 144 * enc->bit_rate/enc->sample_rate; - } else if (enc->codec_id == CODEC_ID_ADPCM_G726) { // - blkalign = 1; - } else if (enc->block_align != 0) { /* specified by the codec */ - blkalign = enc->block_align; - } else - blkalign = enc->channels*bps >> 3; - if (enc->codec_id == CODEC_ID_PCM_U8 || - enc->codec_id == CODEC_ID_PCM_S24LE || - enc->codec_id == CODEC_ID_PCM_S32LE || - enc->codec_id == CODEC_ID_PCM_F32LE || - enc->codec_id == CODEC_ID_PCM_F64LE || - enc->codec_id == CODEC_ID_PCM_S16LE) { - bytespersec = enc->sample_rate * blkalign; - } else { - bytespersec = enc->bit_rate / 8; - } - put_le32(pb, bytespersec); /* bytes per second */ - put_le16(pb, blkalign); /* block align */ - put_le16(pb, bps); /* bits per sample */ - if (enc->codec_id == CODEC_ID_MP3) { - hdrsize += 12; - bytestream_put_le16(&riff_extradata, 1); /* wID */ - bytestream_put_le32(&riff_extradata, 2); /* fdwFlags */ - bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */ - bytestream_put_le16(&riff_extradata, 1); /* nFramesPerBlock */ - bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */ - } else if (enc->codec_id == CODEC_ID_MP2) { - hdrsize += 22; - bytestream_put_le16(&riff_extradata, 2); /* fwHeadLayer */ - bytestream_put_le32(&riff_extradata, enc->bit_rate); /* dwHeadBitrate */ - bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8); /* fwHeadMode */ - bytestream_put_le16(&riff_extradata, 0); /* fwHeadModeExt */ - bytestream_put_le16(&riff_extradata, 1); /* wHeadEmphasis */ - bytestream_put_le16(&riff_extradata, 16); /* fwHeadFlags */ - bytestream_put_le32(&riff_extradata, 0); /* dwPTSLow */ - bytestream_put_le32(&riff_extradata, 0); /* dwPTSHigh */ - } else if (enc->codec_id == CODEC_ID_GSM_MS || enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { - hdrsize += 2; - bytestream_put_le16(&riff_extradata, enc->frame_size); /* wSamplesPerBlock */ - } else if(enc->extradata_size){ - riff_extradata_start= enc->extradata; - riff_extradata= enc->extradata + enc->extradata_size; - hdrsize += enc->extradata_size; - } else if (!waveformatextensible){ - hdrsize -= 2; - } - if(waveformatextensible) { /* write WAVEFORMATEXTENSIBLE extensions */ - hdrsize += 22; - put_le16(pb, riff_extradata - riff_extradata_start + 22); /* 22 is WAVEFORMATEXTENSIBLE size */ - put_le16(pb, enc->bits_per_coded_sample); /* ValidBitsPerSample || SamplesPerBlock || Reserved */ - put_le32(pb, enc->channel_layout); /* dwChannelMask */ - put_le32(pb, enc->codec_tag); /* GUID + next 3 */ - put_le32(pb, 0x00100000); - put_le32(pb, 0xAA000080); - put_le32(pb, 0x719B3800); - } else if(riff_extradata - riff_extradata_start) { - put_le16(pb, riff_extradata - riff_extradata_start); - } - put_buffer(pb, riff_extradata_start, riff_extradata - riff_extradata_start); - if(hdrsize&1){ - hdrsize++; - put_byte(pb, 0); - } - - return hdrsize; -} - -/* BITMAPINFOHEADER header */ -void ff_put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf) -{ - put_le32(pb, 40 + enc->extradata_size); /* size */ - put_le32(pb, enc->width); - //We always store RGB TopDown - put_le32(pb, enc->codec_tag ? enc->height : -enc->height); - put_le16(pb, 1); /* planes */ - - put_le16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24); /* depth */ - /* compression type */ - put_le32(pb, enc->codec_tag); - put_le32(pb, enc->width * enc->height * 3); - put_le32(pb, 0); - put_le32(pb, 0); - put_le32(pb, 0); - put_le32(pb, 0); - - put_buffer(pb, enc->extradata, enc->extradata_size); - - if (!for_asf && enc->extradata_size & 1) - put_byte(pb, 0); -} -#endif //CONFIG_MUXERS - -#if CONFIG_DEMUXERS -/* We could be given one of the three possible structures here: - * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure - * is an expansion of the previous one with the fields added - * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and - * WAVEFORMATEX adds 'WORD cbSize' and basically makes itself - * an openended structure. - */ -void ff_get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size) -{ - int id; - - id = get_le16(pb); - codec->codec_type = AVMEDIA_TYPE_AUDIO; - codec->codec_tag = id; - codec->channels = get_le16(pb); - codec->sample_rate = get_le32(pb); - codec->bit_rate = get_le32(pb) * 8; - codec->block_align = get_le16(pb); - if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */ - codec->bits_per_coded_sample = 8; - }else - codec->bits_per_coded_sample = get_le16(pb); - if (size >= 18) { /* We're obviously dealing with WAVEFORMATEX */ - int cbSize = get_le16(pb); /* cbSize */ - size -= 18; - cbSize = FFMIN(size, cbSize); - if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */ - codec->bits_per_coded_sample = get_le16(pb); - codec->channel_layout = get_le32(pb); /* dwChannelMask */ - id = get_le32(pb); /* 4 first bytes of GUID */ - url_fskip(pb, 12); /* skip end of GUID */ - cbSize -= 22; - size -= 22; - } - codec->extradata_size = cbSize; - if (cbSize > 0) { - codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - get_buffer(pb, codec->extradata, codec->extradata_size); - size -= cbSize; - } - - /* It is possible for the chunk to contain garbage at the end */ - if (size > 0) - url_fskip(pb, size); - } - codec->codec_id = ff_wav_codec_get_id(id, codec->bits_per_coded_sample); -} - - -enum CodecID ff_wav_codec_get_id(unsigned int tag, int bps) -{ - enum CodecID id; - id = ff_codec_get_id(ff_codec_wav_tags, tag); - if (id <= 0) - return id; - /* handle specific u8 codec */ - if (id == CODEC_ID_PCM_S16LE && bps == 8) - id = CODEC_ID_PCM_U8; - if (id == CODEC_ID_PCM_S16LE && bps == 24) - id = CODEC_ID_PCM_S24LE; - if (id == CODEC_ID_PCM_S16LE && bps == 32) - id = CODEC_ID_PCM_S32LE; - if (id == CODEC_ID_PCM_F32LE && bps == 64) - id = CODEC_ID_PCM_F64LE; - if (id == CODEC_ID_ADPCM_IMA_WAV && bps == 8) - id = CODEC_ID_PCM_ZORK; - return id; -} -#endif // CONFIG_DEMUXERS - -void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale) -{ - int gcd; - - *au_ssize= stream->block_align; - if(stream->frame_size && stream->sample_rate){ - *au_scale=stream->frame_size; - *au_rate= stream->sample_rate; - }else if(stream->codec_type == AVMEDIA_TYPE_VIDEO || - stream->codec_type == AVMEDIA_TYPE_SUBTITLE){ - *au_scale= stream->time_base.num; - *au_rate = stream->time_base.den; - }else{ - *au_scale= stream->block_align ? stream->block_align*8 : 8; - *au_rate = stream->bit_rate ? stream->bit_rate : 8*stream->sample_rate; - } - gcd= av_gcd(*au_scale, *au_rate); - *au_scale /= gcd; - *au_rate /= gcd; -} diff --git a/tizen/distrib/ffmpeg/libavformat/riff.h b/tizen/distrib/ffmpeg/libavformat/riff.h deleted file mode 100644 index 2696a0b..0000000 --- a/tizen/distrib/ffmpeg/libavformat/riff.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * RIFF codec tags - * copyright (c) 2000 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * internal header for RIFF based (de)muxers - * do NOT include this in end user applications - */ - -#ifndef AVFORMAT_RIFF_H -#define AVFORMAT_RIFF_H - -#include "libavcodec/avcodec.h" -#include "avio.h" - -int64_t ff_start_tag(ByteIOContext *pb, const char *tag); -void ff_end_tag(ByteIOContext *pb, int64_t start); - -typedef struct AVCodecTag { - enum CodecID id; - unsigned int tag; -} AVCodecTag; - -void ff_put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf); -int ff_put_wav_header(ByteIOContext *pb, AVCodecContext *enc); -enum CodecID ff_wav_codec_get_id(unsigned int tag, int bps); -void ff_get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size); - -extern const AVCodecTag ff_codec_bmp_tags[]; -extern const AVCodecTag ff_codec_wav_tags[]; - -unsigned int ff_codec_get_tag(const AVCodecTag *tags, int id); -enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag); -void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale); - -#endif /* AVFORMAT_RIFF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rl2.c b/tizen/distrib/ffmpeg/libavformat/rl2.c deleted file mode 100644 index 1b7edce..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rl2.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * RL2 Format Demuxer - * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * RL2 file demuxer - * @file - * @author Sascha Sommer (saschasommer@freenet.de) - * For more information regarding the RL2 file format, visit: - * http://wiki.multimedia.cx/index.php?title=RL2 - * - * extradata: - * 2 byte le initial drawing offset within 320x200 viewport - * 4 byte le number of used colors - * 256 * 3 bytes rgb palette - * optional background_frame - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette - -#define FORM_TAG MKBETAG('F', 'O', 'R', 'M') -#define RLV2_TAG MKBETAG('R', 'L', 'V', '2') -#define RLV3_TAG MKBETAG('R', 'L', 'V', '3') - -typedef struct Rl2DemuxContext { - unsigned int index_pos[2]; ///< indexes in the sample tables -} Rl2DemuxContext; - - -/** - * check if the file is in rl2 format - * @param p probe buffer - * @return 0 when the probe buffer does not contain rl2 data, > 0 otherwise - */ -static int rl2_probe(AVProbeData *p) -{ - - if(AV_RB32(&p->buf[0]) != FORM_TAG) - return 0; - - if(AV_RB32(&p->buf[8]) != RLV2_TAG && - AV_RB32(&p->buf[8]) != RLV3_TAG) - return 0; - - return AVPROBE_SCORE_MAX; -} - -/** - * read rl2 header data and setup the avstreams - * @param s demuxer context - * @param ap format parameters - * @return 0 on success, AVERROR otherwise - */ -static av_cold int rl2_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - AVStream *st; - unsigned int frame_count; - unsigned int audio_frame_counter = 0; - unsigned int video_frame_counter = 0; - unsigned int back_size; - int data_size; - unsigned short encoding_method; - unsigned short sound_rate; - unsigned short rate; - unsigned short channels; - unsigned short def_sound_size; - unsigned int signature; - unsigned int pts_den = 11025; /* video only case */ - unsigned int pts_num = 1103; - unsigned int* chunk_offset = NULL; - int* chunk_size = NULL; - int* audio_size = NULL; - int i; - int ret = 0; - - url_fskip(pb,4); /* skip FORM tag */ - back_size = get_le32(pb); /** get size of the background frame */ - signature = get_be32(pb); - data_size = get_be32(pb); - frame_count = get_le32(pb); - - /* disallow back_sizes and frame_counts that may lead to overflows later */ - if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t)) - return AVERROR_INVALIDDATA; - - encoding_method = get_le16(pb); - sound_rate = get_le16(pb); - rate = get_le16(pb); - channels = get_le16(pb); - def_sound_size = get_le16(pb); - - /** setup video stream */ - st = av_new_stream(s, 0); - if(!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RL2; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = 320; - st->codec->height = 200; - - /** allocate and fill extradata */ - st->codec->extradata_size = EXTRADATA1_SIZE; - - if(signature == RLV3_TAG && back_size > 0) - st->codec->extradata_size += back_size; - - st->codec->extradata = av_mallocz(st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if(!st->codec->extradata) - return AVERROR(ENOMEM); - - if(get_buffer(pb,st->codec->extradata,st->codec->extradata_size) != - st->codec->extradata_size) - return AVERROR(EIO); - - /** setup audio stream if present */ - if(sound_rate){ - pts_num = def_sound_size; - pts_den = rate; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_U8; - st->codec->codec_tag = 1; - st->codec->channels = channels; - st->codec->bits_per_coded_sample = 8; - st->codec->sample_rate = rate; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * - st->codec->bits_per_coded_sample / 8; - av_set_pts_info(st,32,1,rate); - } - - av_set_pts_info(s->streams[0], 32, pts_num, pts_den); - - chunk_size = av_malloc(frame_count * sizeof(uint32_t)); - audio_size = av_malloc(frame_count * sizeof(uint32_t)); - chunk_offset = av_malloc(frame_count * sizeof(uint32_t)); - - if(!chunk_size || !audio_size || !chunk_offset){ - av_free(chunk_size); - av_free(audio_size); - av_free(chunk_offset); - return AVERROR(ENOMEM); - } - - /** read offset and size tables */ - for(i=0; i < frame_count;i++) - chunk_size[i] = get_le32(pb); - for(i=0; i < frame_count;i++) - chunk_offset[i] = get_le32(pb); - for(i=0; i < frame_count;i++) - audio_size[i] = get_le32(pb) & 0xFFFF; - - /** build the sample index */ - for(i=0;i chunk_size[i]){ - ret = AVERROR_INVALIDDATA; - break; - } - - if(sound_rate && audio_size[i]){ - av_add_index_entry(s->streams[1], chunk_offset[i], - audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME); - audio_frame_counter += audio_size[i] / channels; - } - av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i], - video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME); - ++video_frame_counter; - } - - - av_free(chunk_size); - av_free(audio_size); - av_free(chunk_offset); - - return ret; -} - -/** - * read a single audio or video packet - * @param s demuxer context - * @param pkt the packet to be filled - * @return 0 on success, AVERROR otherwise - */ -static int rl2_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - Rl2DemuxContext *rl2 = s->priv_data; - ByteIOContext *pb = s->pb; - AVIndexEntry *sample = NULL; - int i; - int ret = 0; - int stream_id = -1; - int64_t pos = INT64_MAX; - - /** check if there is a valid video or audio entry that can be used */ - for(i=0; inb_streams; i++){ - if(rl2->index_pos[i] < s->streams[i]->nb_index_entries - && s->streams[i]->index_entries[ rl2->index_pos[i] ].pos < pos){ - sample = &s->streams[i]->index_entries[ rl2->index_pos[i] ]; - pos= sample->pos; - stream_id= i; - } - } - - if(stream_id == -1) - return AVERROR(EIO); - - ++rl2->index_pos[stream_id]; - - /** position the stream (will probably be there anyway) */ - url_fseek(pb, sample->pos, SEEK_SET); - - /** fill the packet */ - ret = av_get_packet(pb, pkt, sample->size); - if(ret != sample->size){ - av_free_packet(pkt); - return AVERROR(EIO); - } - - pkt->stream_index = stream_id; - pkt->pts = sample->timestamp; - - return ret; -} - -/** - * seek to a new timestamp - * @param s demuxer context - * @param stream_index index of the stream that should be seeked - * @param timestamp wanted timestamp - * @param flags direction and seeking mode - * @return 0 on success, -1 otherwise - */ -static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - Rl2DemuxContext *rl2 = s->priv_data; - int i; - int index = av_index_search_timestamp(st, timestamp, flags); - if(index < 0) - return -1; - - rl2->index_pos[stream_index] = index; - timestamp = st->index_entries[index].timestamp; - - for(i=0; i < s->nb_streams; i++){ - AVStream *st2 = s->streams[i]; - index = av_index_search_timestamp(st2, - av_rescale_q(timestamp, st->time_base, st2->time_base), - flags | AVSEEK_FLAG_BACKWARD); - - if(index < 0) - index = 0; - - rl2->index_pos[i] = index; - } - - return 0; -} - -AVInputFormat rl2_demuxer = { - "rl2", - NULL_IF_CONFIG_SMALL("RL2 format"), - sizeof(Rl2DemuxContext), - rl2_probe, - rl2_read_header, - rl2_read_packet, - NULL, - rl2_read_seek, -}; - diff --git a/tizen/distrib/ffmpeg/libavformat/rm.c b/tizen/distrib/ffmpeg/libavformat/rm.c deleted file mode 100644 index 29a6e40..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rm.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * "Real" compatible muxer and demuxer common code. - * Copyright (c) 2009 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "rm.h" - -const char * const ff_rm_metadata[4] = { - "title", - "author", - "copyright", - "comment" -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rm.h b/tizen/distrib/ffmpeg/libavformat/rm.h deleted file mode 100644 index 4e63114..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rm.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * "Real" compatible muxer and demuxer. - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RM_H -#define AVFORMAT_RM_H - -#include "avformat.h" - -extern const char * const ff_rm_metadata[4]; -extern const unsigned char ff_sipr_subpk_size[4]; - -typedef struct RMStream RMStream; - -RMStream *ff_rm_alloc_rmstream (void); -void ff_rm_free_rmstream (RMStream *rms); - -/*< input format for Realmedia-style RTSP streams */ -extern AVInputFormat rdt_demuxer; - -/** - * Read the MDPR chunk, which contains stream-specific codec initialization - * parameters. - * - * @param s context containing RMContext and ByteIOContext for stream reading - * @param pb context to read the data from - * @param st the stream that the MDPR chunk belongs to and where to store the - * parameters read from the chunk into - * @param rst real-specific stream information - * @param codec_data_size size of the MDPR chunk - * @return 0 on success, errno codes on error - */ -int ff_rm_read_mdpr_codecdata (AVFormatContext *s, ByteIOContext *pb, - AVStream *st, RMStream *rst, - int codec_data_size); - -/** - * Parse one rm-stream packet from the input bytestream. - * - * @param s context containing RMContext and ByteIOContext for stream reading - * @param pb context to read the data from - * @param st stream to which the packet to be read belongs - * @param rst Real-specific stream information - * @param len packet length to read from the input - * @param pkt packet location to store the parsed packet data - * @param seq pointer to an integer containing the sequence number, may be - * updated - * @param flags the packet flags - * @param ts timestamp of the current packet - * @return <0 on error, 0 if a packet was placed in the pkt pointer. A - * value >0 means that no data was placed in pkt, but that cached - * data is available by calling ff_rm_retrieve_cache(). - */ -int ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, - AVStream *st, RMStream *rst, int len, - AVPacket *pkt, int *seq, int flags, int64_t ts); - -/** - * Retrieve one cached packet from the rm-context. The real container can - * store several packets (as interpreted by the codec) in a single container - * packet, which means the demuxer holds some back when the first container - * packet is parsed and returned. The result is that rm->audio_pkt_cnt is - * a positive number, the amount of cached packets. Using this function, each - * of those packets can be retrieved sequentially. - * - * @param s context containing RMContext and ByteIOContext for stream reading - * @param pb context to read the data from - * @param st stream that this packet belongs to - * @param rst Real-specific stream information - * @param pkt location to store the packet data - * @return the number of samples left for subsequent calls to this same - * function, or 0 if all samples have been retrieved. - */ -int ff_rm_retrieve_cache (AVFormatContext *s, ByteIOContext *pb, - AVStream *st, RMStream *rst, AVPacket *pkt); - -/** - * Perform 4-bit block reordering for SIPR data. - * - * @param buf SIPR data - */ -void ff_rm_reorder_sipr_data(uint8_t *buf, int sub_packet_h, int framesize); - -#endif /* AVFORMAT_RM_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rmdec.c b/tizen/distrib/ffmpeg/libavformat/rmdec.c deleted file mode 100644 index f4603bf..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rmdec.c +++ /dev/null @@ -1,977 +0,0 @@ -/* - * "Real" compatible demuxer. - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avstring.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "riff.h" -#include "rm.h" - -struct RMStream { - AVPacket pkt; ///< place to store merged video frame / reordered audio data - int videobufsize; ///< current assembled frame size - int videobufpos; ///< position for the next slice in the video buffer - int curpic_num; ///< picture number of current frame - int cur_slice, slices; - int64_t pktpos; ///< first slice position in file - /// Audio descrambling matrix parameters - int64_t audiotimestamp; ///< Audio packet timestamp - int sub_packet_cnt; // Subpacket counter, used while reading - int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container - int audio_framesize; /// Audio frame size from container - int sub_packet_lengths[16]; /// Length of each subpacket -}; - -typedef struct { - int nb_packets; - int old_format; - int current_stream; - int remaining_len; - int audio_stream_num; ///< Stream number for audio packets - int audio_pkt_cnt; ///< Output packet counter -} RMDemuxContext; - -static const AVCodecTag rm_codec_tags[] = { - { CODEC_ID_RV10, MKTAG('R','V','1','0') }, - { CODEC_ID_RV20, MKTAG('R','V','2','0') }, - { CODEC_ID_RV20, MKTAG('R','V','T','R') }, - { CODEC_ID_RV30, MKTAG('R','V','3','0') }, - { CODEC_ID_RV40, MKTAG('R','V','4','0') }, - { CODEC_ID_AC3, MKTAG('d','n','e','t') }, - { CODEC_ID_RA_144, MKTAG('l','p','c','J') }, - { CODEC_ID_RA_288, MKTAG('2','8','_','8') }, - { CODEC_ID_COOK, MKTAG('c','o','o','k') }, - { CODEC_ID_ATRAC3, MKTAG('a','t','r','c') }, - { CODEC_ID_SIPR, MKTAG('s','i','p','r') }, - { CODEC_ID_AAC, MKTAG('r','a','a','c') }, - { CODEC_ID_AAC, MKTAG('r','a','c','p') }, - { CODEC_ID_NONE }, -}; - -static const unsigned char sipr_swaps[38][2] = { - { 0, 63 }, { 1, 22 }, { 2, 44 }, { 3, 90 }, - { 5, 81 }, { 7, 31 }, { 8, 86 }, { 9, 58 }, - { 10, 36 }, { 12, 68 }, { 13, 39 }, { 14, 73 }, - { 15, 53 }, { 16, 69 }, { 17, 57 }, { 19, 88 }, - { 20, 34 }, { 21, 71 }, { 24, 46 }, { 25, 94 }, - { 26, 54 }, { 28, 75 }, { 29, 50 }, { 32, 70 }, - { 33, 92 }, { 35, 74 }, { 38, 85 }, { 40, 56 }, - { 42, 87 }, { 43, 65 }, { 45, 59 }, { 48, 79 }, - { 49, 93 }, { 51, 89 }, { 55, 95 }, { 61, 76 }, - { 67, 83 }, { 77, 80 } -}; - -const unsigned char ff_sipr_subpk_size[4] = { 29, 19, 37, 20 }; - -static inline void get_strl(ByteIOContext *pb, char *buf, int buf_size, int len) -{ - int i; - char *q, r; - - q = buf; - for(i=0;i 0) *q = '\0'; -} - -static void get_str8(ByteIOContext *pb, char *buf, int buf_size) -{ - get_strl(pb, buf, buf_size, get_byte(pb)); -} - -static int rm_read_extradata(ByteIOContext *pb, AVCodecContext *avctx, unsigned size) -{ - if (size >= 1<<24) - return -1; - avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!avctx->extradata) - return AVERROR(ENOMEM); - avctx->extradata_size = get_buffer(pb, avctx->extradata, size); - memset(avctx->extradata + avctx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - if (avctx->extradata_size != size) - return AVERROR(EIO); - return 0; -} - -static void rm_read_metadata(AVFormatContext *s, int wide) -{ - char buf[1024]; - int i; - for (i=0; ipb) : get_byte(s->pb); - get_strl(s->pb, buf, sizeof(buf), len); - av_metadata_set2(&s->metadata, ff_rm_metadata[i], buf, 0); - } -} - -RMStream *ff_rm_alloc_rmstream (void) -{ - RMStream *rms = av_mallocz(sizeof(RMStream)); - rms->curpic_num = -1; - return rms; -} - -void ff_rm_free_rmstream (RMStream *rms) -{ - av_free_packet(&rms->pkt); -} - -static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, - AVStream *st, RMStream *ast, int read_all) -{ - char buf[256]; - uint32_t version; - int ret; - - /* ra type header */ - version = get_be16(pb); /* version */ - if (version == 3) { - int header_size = get_be16(pb); - int64_t startpos = url_ftell(pb); - url_fskip(pb, 14); - rm_read_metadata(s, 0); - if ((startpos + header_size) >= url_ftell(pb) + 2) { - // fourcc (should always be "lpcJ") - get_byte(pb); - get_str8(pb, buf, sizeof(buf)); - } - // Skip extra header crap (this should never happen) - if ((startpos + header_size) > url_ftell(pb)) - url_fskip(pb, header_size + startpos - url_ftell(pb)); - st->codec->sample_rate = 8000; - st->codec->channels = 1; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_RA_144; - } else { - int flavor, sub_packet_h, coded_framesize, sub_packet_size; - int codecdata_length; - /* old version (4) */ - url_fskip(pb, 2); /* unused */ - get_be32(pb); /* .ra4 */ - get_be32(pb); /* data size */ - get_be16(pb); /* version2 */ - get_be32(pb); /* header size */ - flavor= get_be16(pb); /* add codec info / flavor */ - ast->coded_framesize = coded_framesize = get_be32(pb); /* coded frame size */ - get_be32(pb); /* ??? */ - get_be32(pb); /* ??? */ - get_be32(pb); /* ??? */ - ast->sub_packet_h = sub_packet_h = get_be16(pb); /* 1 */ - st->codec->block_align= get_be16(pb); /* frame size */ - ast->sub_packet_size = sub_packet_size = get_be16(pb); /* sub packet size */ - get_be16(pb); /* ??? */ - if (version == 5) { - get_be16(pb); get_be16(pb); get_be16(pb); - } - st->codec->sample_rate = get_be16(pb); - get_be32(pb); - st->codec->channels = get_be16(pb); - if (version == 5) { - get_be32(pb); - get_buffer(pb, buf, 4); - buf[4] = 0; - } else { - get_str8(pb, buf, sizeof(buf)); /* desc */ - get_str8(pb, buf, sizeof(buf)); /* desc */ - } - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = AV_RL32(buf); - st->codec->codec_id = ff_codec_get_id(rm_codec_tags, st->codec->codec_tag); - switch (st->codec->codec_id) { - case CODEC_ID_AC3: - st->need_parsing = AVSTREAM_PARSE_FULL; - break; - case CODEC_ID_RA_288: - st->codec->extradata_size= 0; - ast->audio_framesize = st->codec->block_align; - st->codec->block_align = coded_framesize; - - if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ - av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n"); - return -1; - } - - av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); - break; - case CODEC_ID_COOK: - case CODEC_ID_ATRAC3: - case CODEC_ID_SIPR: - get_be16(pb); get_byte(pb); - if (version == 5) - get_byte(pb); - codecdata_length = get_be32(pb); - if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ - av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); - return -1; - } - - if (!strcmp(buf, "cook")) st->codec->codec_id = CODEC_ID_COOK; - else if (!strcmp(buf, "sipr")) st->codec->codec_id = CODEC_ID_SIPR; - else st->codec->codec_id = CODEC_ID_ATRAC3; - - ast->audio_framesize = st->codec->block_align; - if (st->codec->codec_id == CODEC_ID_SIPR) { - if (flavor > 3) { - av_log(s, AV_LOG_ERROR, "bad SIPR file flavor %d\n", - flavor); - return -1; - } - st->codec->block_align = ff_sipr_subpk_size[flavor]; - } else { - if(sub_packet_size <= 0){ - av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); - return -1; - } - st->codec->block_align = ast->sub_packet_size; - } - if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) - return ret; - - if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ - av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); - return -1; - } - - av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); - break; - case CODEC_ID_AAC: - get_be16(pb); get_byte(pb); - if (version == 5) - get_byte(pb); - st->codec->codec_id = CODEC_ID_AAC; - codecdata_length = get_be32(pb); - if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ - av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); - return -1; - } - if (codecdata_length >= 1) { - get_byte(pb); - if ((ret = rm_read_extradata(pb, st->codec, codecdata_length - 1)) < 0) - return ret; - } - break; - default: - av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name)); - } - if (read_all) { - get_byte(pb); - get_byte(pb); - get_byte(pb); - rm_read_metadata(s, 0); - } - } - return 0; -} - -int -ff_rm_read_mdpr_codecdata (AVFormatContext *s, ByteIOContext *pb, - AVStream *st, RMStream *rst, int codec_data_size) -{ - unsigned int v; - int size; - int64_t codec_pos; - int ret; - - av_set_pts_info(st, 64, 1, 1000); - codec_pos = url_ftell(pb); - v = get_be32(pb); - if (v == MKTAG(0xfd, 'a', 'r', '.')) { - /* ra type header */ - if (rm_read_audio_stream_info(s, pb, st, rst, 0)) - return -1; - } else { - int fps, fps2; - if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) { - fail1: - av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n"); - goto skip; - } - st->codec->codec_tag = get_le32(pb); - st->codec->codec_id = ff_codec_get_id(rm_codec_tags, st->codec->codec_tag); -// av_log(s, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0')); - if (st->codec->codec_id == CODEC_ID_NONE) - goto fail1; - st->codec->width = get_be16(pb); - st->codec->height = get_be16(pb); - st->codec->time_base.num= 1; - fps= get_be16(pb); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - get_be32(pb); - fps2= get_be16(pb); - get_be16(pb); - - if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (url_ftell(pb) - codec_pos))) < 0) - return ret; - -// av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2); - st->codec->time_base.den = fps * st->codec->time_base.num; - //XXX: do we really need that? - switch(st->codec->extradata[4]>>4){ - case 1: st->codec->codec_id = CODEC_ID_RV10; break; - case 2: st->codec->codec_id = CODEC_ID_RV20; break; - case 3: st->codec->codec_id = CODEC_ID_RV30; break; - case 4: st->codec->codec_id = CODEC_ID_RV40; break; - default: - av_log(st->codec, AV_LOG_ERROR, "extra:%02X %02X %02X %02X %02X\n", st->codec->extradata[0], st->codec->extradata[1], st->codec->extradata[2], st->codec->extradata[3], st->codec->extradata[4]); - goto fail1; - } - } - -skip: - /* skip codec info */ - size = url_ftell(pb) - codec_pos; - url_fskip(pb, codec_data_size - size); - - return 0; -} - -/** this function assumes that the demuxer has already seeked to the start - * of the INDX chunk, and will bail out if not. */ -static int rm_read_index(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - unsigned int size, n_pkts, str_id, next_off, n, pos, pts; - AVStream *st; - - do { - if (get_le32(pb) != MKTAG('I','N','D','X')) - return -1; - size = get_be32(pb); - if (size < 20) - return -1; - url_fskip(pb, 2); - n_pkts = get_be32(pb); - str_id = get_be16(pb); - next_off = get_be32(pb); - for (n = 0; n < s->nb_streams; n++) - if (s->streams[n]->id == str_id) { - st = s->streams[n]; - break; - } - if (n == s->nb_streams) - goto skip; - - for (n = 0; n < n_pkts; n++) { - url_fskip(pb, 2); - pts = get_be32(pb); - pos = get_be32(pb); - url_fskip(pb, 4); /* packet no. */ - - av_add_index_entry(st, pos, pts, 0, 0, AVINDEX_KEYFRAME); - } - -skip: - if (next_off && url_ftell(pb) != next_off && - url_fseek(pb, next_off, SEEK_SET) < 0) - return -1; - } while (next_off); - - return 0; -} - -static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) -{ - RMDemuxContext *rm = s->priv_data; - AVStream *st; - - rm->old_format = 1; - st = av_new_stream(s, 0); - if (!st) - return -1; - st->priv_data = ff_rm_alloc_rmstream(); - return rm_read_audio_stream_info(s, s->pb, st, st->priv_data, 1); -} - -static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - RMDemuxContext *rm = s->priv_data; - AVStream *st; - ByteIOContext *pb = s->pb; - unsigned int tag; - int tag_size; - unsigned int start_time, duration; - unsigned int data_off = 0, indx_off = 0; - char buf[128]; - int flags = 0; - - tag = get_le32(pb); - if (tag == MKTAG('.', 'r', 'a', 0xfd)) { - /* very old .ra format */ - return rm_read_header_old(s, ap); - } else if (tag != MKTAG('.', 'R', 'M', 'F')) { - return AVERROR(EIO); - } - - get_be32(pb); /* header size */ - get_be16(pb); - get_be32(pb); - get_be32(pb); /* number of headers */ - - for(;;) { - if (url_feof(pb)) - return -1; - tag = get_le32(pb); - tag_size = get_be32(pb); - get_be16(pb); -#if 0 - printf("tag=%c%c%c%c (%08x) size=%d\n", - (tag) & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - tag, - tag_size); -#endif - if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A')) - return -1; - switch(tag) { - case MKTAG('P', 'R', 'O', 'P'): - /* file header */ - get_be32(pb); /* max bit rate */ - get_be32(pb); /* avg bit rate */ - get_be32(pb); /* max packet size */ - get_be32(pb); /* avg packet size */ - get_be32(pb); /* nb packets */ - get_be32(pb); /* duration */ - get_be32(pb); /* preroll */ - indx_off = get_be32(pb); /* index offset */ - data_off = get_be32(pb); /* data offset */ - get_be16(pb); /* nb streams */ - flags = get_be16(pb); /* flags */ - break; - case MKTAG('C', 'O', 'N', 'T'): - rm_read_metadata(s, 1); - break; - case MKTAG('M', 'D', 'P', 'R'): - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->id = get_be16(pb); - get_be32(pb); /* max bit rate */ - st->codec->bit_rate = get_be32(pb); /* bit rate */ - get_be32(pb); /* max packet size */ - get_be32(pb); /* avg packet size */ - start_time = get_be32(pb); /* start time */ - get_be32(pb); /* preroll */ - duration = get_be32(pb); /* duration */ - st->start_time = start_time; - st->duration = duration; - get_str8(pb, buf, sizeof(buf)); /* desc */ - get_str8(pb, buf, sizeof(buf)); /* mimetype */ - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->priv_data = ff_rm_alloc_rmstream(); - if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, - get_be32(pb)) < 0) - return -1; - break; - case MKTAG('D', 'A', 'T', 'A'): - goto header_end; - default: - /* unknown tag: skip it */ - url_fskip(pb, tag_size - 10); - break; - } - } - header_end: - rm->nb_packets = get_be32(pb); /* number of packets */ - if (!rm->nb_packets && (flags & 4)) - rm->nb_packets = 3600 * 25; - get_be32(pb); /* next data header */ - - if (!data_off) - data_off = url_ftell(pb) - 18; - if (indx_off && url_fseek(pb, indx_off, SEEK_SET) >= 0) { - rm_read_index(s); - url_fseek(pb, data_off + 18, SEEK_SET); - } - - return 0; -} - -static int get_num(ByteIOContext *pb, int *len) -{ - int n, n1; - - n = get_be16(pb); - (*len)-=2; - n &= 0x7FFF; - if (n >= 0x4000) { - return n - 0x4000; - } else { - n1 = get_be16(pb); - (*len)-=2; - return (n << 16) | n1; - } -} - -/* multiple of 20 bytes for ra144 (ugly) */ -#define RAW_PACKET_SIZE 1000 - -static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){ - RMDemuxContext *rm = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - uint32_t state=0xFFFFFFFF; - - while(!url_feof(pb)){ - int len, num, i; - *pos= url_ftell(pb) - 3; - if(rm->remaining_len > 0){ - num= rm->current_stream; - len= rm->remaining_len; - *timestamp = AV_NOPTS_VALUE; - *flags= 0; - }else{ - state= (state<<8) + get_byte(pb); - - if(state == MKBETAG('I', 'N', 'D', 'X')){ - int n_pkts, expected_len; - len = get_be32(pb); - url_fskip(pb, 2); - n_pkts = get_be32(pb); - expected_len = 20 + n_pkts * 14; - if (len == 20) - /* some files don't add index entries to chunk size... */ - len = expected_len; - else if (len != expected_len) - av_log(s, AV_LOG_WARNING, - "Index size %d (%d pkts) is wrong, should be %d.\n", - len, n_pkts, expected_len); - len -= 14; // we already read part of the index header - if(len<0) - continue; - goto skip; - } else if (state == MKBETAG('D','A','T','A')) { - av_log(s, AV_LOG_WARNING, - "DATA tag in middle of chunk, file may be broken.\n"); - } - - if(state > (unsigned)0xFFFF || state <= 12) - continue; - len=state - 12; - state= 0xFFFFFFFF; - - num = get_be16(pb); - *timestamp = get_be32(pb); - get_byte(pb); /* reserved */ - *flags = get_byte(pb); /* flags */ - } - for(i=0;inb_streams;i++) { - st = s->streams[i]; - if (num == st->id) - break; - } - if (i == s->nb_streams) { -skip: - /* skip packet if unknown number */ - url_fskip(pb, len); - rm->remaining_len = 0; - continue; - } - *stream_index= i; - - return len; - } - return -1; -} - -static int rm_assemble_video_frame(AVFormatContext *s, ByteIOContext *pb, - RMDemuxContext *rm, RMStream *vst, - AVPacket *pkt, int len, int *pseq) -{ - int hdr, seq, pic_num, len2, pos; - int type; - - hdr = get_byte(pb); len--; - type = hdr >> 6; - - if(type != 3){ // not frame as a part of packet - seq = get_byte(pb); len--; - } - if(type != 1){ // not whole frame - len2 = get_num(pb, &len); - pos = get_num(pb, &len); - pic_num = get_byte(pb); len--; - } - if(len<0) - return -1; - rm->remaining_len = len; - if(type&1){ // frame, not slice - if(type == 3) // frame as a part of packet - len= len2; - if(rm->remaining_len < len) - return -1; - rm->remaining_len -= len; - if(av_new_packet(pkt, len + 9) < 0) - return AVERROR(EIO); - pkt->data[0] = 0; - AV_WL32(pkt->data + 1, 1); - AV_WL32(pkt->data + 5, 0); - get_buffer(pb, pkt->data + 9, len); - return 0; - } - //now we have to deal with single slice - - *pseq = seq; - if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ - vst->slices = ((hdr & 0x3F) << 1) + 1; - vst->videobufsize = len2 + 8*vst->slices + 1; - av_free_packet(&vst->pkt); //FIXME this should be output. - if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) - return AVERROR(ENOMEM); - vst->videobufpos = 8*vst->slices + 1; - vst->cur_slice = 0; - vst->curpic_num = pic_num; - vst->pktpos = url_ftell(pb); - } - if(type == 2) - len = FFMIN(len, pos); - - if(++vst->cur_slice > vst->slices) - return 1; - AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); - AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); - if(vst->videobufpos + len > vst->videobufsize) - return 1; - if (get_buffer(pb, vst->pkt.data + vst->videobufpos, len) != len) - return AVERROR(EIO); - vst->videobufpos += len; - rm->remaining_len-= len; - - if(type == 2 || (vst->videobufpos) == vst->videobufsize){ - vst->pkt.data[0] = vst->cur_slice-1; - *pkt= vst->pkt; - vst->pkt.data= NULL; - vst->pkt.size= 0; - if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin - memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, - vst->videobufpos - 1 - 8*vst->slices); - pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); - pkt->pts = AV_NOPTS_VALUE; - pkt->pos = vst->pktpos; - vst->slices = 0; - return 0; - } - - return 1; -} - -static inline void -rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt) -{ - uint8_t *ptr; - int j; - - if (st->codec->codec_id == CODEC_ID_AC3) { - ptr = pkt->data; - for (j=0;jsize;j+=2) { - FFSWAP(int, ptr[0], ptr[1]); - ptr += 2; - } - } -} - -/** - * Perform 4-bit block reordering for SIPR data. - * @todo This can be optimized, e.g. use memcpy() if data blocks are aligned - */ -void ff_rm_reorder_sipr_data(uint8_t *buf, int sub_packet_h, int framesize) -{ - int n, bs = sub_packet_h * framesize * 2 / 96; // nibbles per subpacket - - for (n = 0; n < 38; n++) { - int j; - int i = bs * sipr_swaps[n][0]; - int o = bs * sipr_swaps[n][1]; - - /* swap 4bit-nibbles of block 'i' with 'o' */ - for (j = 0; j < bs; j++, i++, o++) { - int x = (buf[i >> 1] >> (4 * (i & 1))) & 0xF, - y = (buf[o >> 1] >> (4 * (o & 1))) & 0xF; - - buf[o >> 1] = (x << (4 * (o & 1))) | - (buf[o >> 1] & (0xF << (4 * !(o & 1)))); - buf[i >> 1] = (y << (4 * (i & 1))) | - (buf[i >> 1] & (0xF << (4 * !(i & 1)))); - } - } -} - -int -ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, - AVStream *st, RMStream *ast, int len, AVPacket *pkt, - int *seq, int flags, int64_t timestamp) -{ - RMDemuxContext *rm = s->priv_data; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - rm->current_stream= st->id; - if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq)) - return -1; //got partial frame - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if ((st->codec->codec_id == CODEC_ID_RA_288) || - (st->codec->codec_id == CODEC_ID_COOK) || - (st->codec->codec_id == CODEC_ID_ATRAC3) || - (st->codec->codec_id == CODEC_ID_SIPR)) { - int x; - int sps = ast->sub_packet_size; - int cfs = ast->coded_framesize; - int h = ast->sub_packet_h; - int y = ast->sub_packet_cnt; - int w = ast->audio_framesize; - - if (flags & 2) - y = ast->sub_packet_cnt = 0; - if (!y) - ast->audiotimestamp = timestamp; - - switch(st->codec->codec_id) { - case CODEC_ID_RA_288: - for (x = 0; x < h/2; x++) - get_buffer(pb, ast->pkt.data+x*2*w+y*cfs, cfs); - break; - case CODEC_ID_ATRAC3: - case CODEC_ID_COOK: - for (x = 0; x < w/sps; x++) - get_buffer(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); - break; - case CODEC_ID_SIPR: - get_buffer(pb, ast->pkt.data + y * w, w); - break; - } - - if (++(ast->sub_packet_cnt) < h) - return -1; - if (st->codec->codec_id == CODEC_ID_SIPR) - ff_rm_reorder_sipr_data(ast->pkt.data, h, w); - - ast->sub_packet_cnt = 0; - rm->audio_stream_num = st->index; - rm->audio_pkt_cnt = h * w / st->codec->block_align; - } else if (st->codec->codec_id == CODEC_ID_AAC) { - int x; - rm->audio_stream_num = st->index; - ast->sub_packet_cnt = (get_be16(pb) & 0xf0) >> 4; - if (ast->sub_packet_cnt) { - for (x = 0; x < ast->sub_packet_cnt; x++) - ast->sub_packet_lengths[x] = get_be16(pb); - rm->audio_pkt_cnt = ast->sub_packet_cnt; - ast->audiotimestamp = timestamp; - } else - return -1; - } else { - av_get_packet(pb, pkt, len); - rm_ac3_swap_bytes(st, pkt); - } - } else - av_get_packet(pb, pkt, len); - - pkt->stream_index = st->index; - -#if 0 - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if(st->codec->codec_id == CODEC_ID_RV20){ - int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1); - av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq); - - seq |= (timestamp&~0x3FFF); - if(seq - timestamp > 0x2000) seq -= 0x4000; - if(seq - timestamp < -0x2000) seq += 0x4000; - } - } -#endif - - pkt->pts= timestamp; - if (flags & 2) - pkt->flags |= AV_PKT_FLAG_KEY; - - return st->codec->codec_type == AVMEDIA_TYPE_AUDIO ? rm->audio_pkt_cnt : 0; -} - -int -ff_rm_retrieve_cache (AVFormatContext *s, ByteIOContext *pb, - AVStream *st, RMStream *ast, AVPacket *pkt) -{ - RMDemuxContext *rm = s->priv_data; - - assert (rm->audio_pkt_cnt > 0); - - if (st->codec->codec_id == CODEC_ID_AAC) - av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]); - else { - av_new_packet(pkt, st->codec->block_align); - memcpy(pkt->data, ast->pkt.data + st->codec->block_align * //FIXME avoid this - (ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt), - st->codec->block_align); - } - rm->audio_pkt_cnt--; - if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) { - ast->audiotimestamp = AV_NOPTS_VALUE; - pkt->flags = AV_PKT_FLAG_KEY; - } else - pkt->flags = 0; - pkt->stream_index = st->index; - - return rm->audio_pkt_cnt; -} - -static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - RMDemuxContext *rm = s->priv_data; - AVStream *st; - int i, len, res, seq = 1; - int64_t timestamp, pos; - int flags; - - for (;;) { - if (rm->audio_pkt_cnt) { - // If there are queued audio packet return them first - st = s->streams[rm->audio_stream_num]; - ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt); - flags = 0; - } else { - if (rm->old_format) { - RMStream *ast; - - st = s->streams[0]; - ast = st->priv_data; - timestamp = AV_NOPTS_VALUE; - len = !ast->audio_framesize ? RAW_PACKET_SIZE : - ast->coded_framesize * ast->sub_packet_h / 2; - flags = (seq++ == 1) ? 2 : 0; - pos = url_ftell(s->pb); - } else { - len=sync(s, ×tamp, &flags, &i, &pos); - if (len > 0) - st = s->streams[i]; - } - - if(len<0 || url_feof(s->pb)) - return AVERROR(EIO); - - res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt, - &seq, flags, timestamp); - if((flags&2) && (seq&0x7F) == 1) - av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME); - if (res) - continue; - } - - if( (st->discard >= AVDISCARD_NONKEY && !(flags&2)) - || st->discard >= AVDISCARD_ALL){ - av_free_packet(pkt); - } else - break; - } - - return 0; -} - -static int rm_read_close(AVFormatContext *s) -{ - int i; - - for (i=0;inb_streams;i++) - ff_rm_free_rmstream(s->streams[i]->priv_data); - - return 0; -} - -static int rm_probe(AVProbeData *p) -{ - /* check file header */ - if ((p->buf[0] == '.' && p->buf[1] == 'R' && - p->buf[2] == 'M' && p->buf[3] == 'F' && - p->buf[4] == 0 && p->buf[5] == 0) || - (p->buf[0] == '.' && p->buf[1] == 'r' && - p->buf[2] == 'a' && p->buf[3] == 0xfd)) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int64_t rm_read_dts(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - RMDemuxContext *rm = s->priv_data; - int64_t pos, dts; - int stream_index2, flags, len, h; - - pos = *ppos; - - if(rm->old_format) - return AV_NOPTS_VALUE; - - url_fseek(s->pb, pos, SEEK_SET); - rm->remaining_len=0; - for(;;){ - int seq=1; - AVStream *st; - - len=sync(s, &dts, &flags, &stream_index2, &pos); - if(len<0) - return AV_NOPTS_VALUE; - - st = s->streams[stream_index2]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - h= get_byte(s->pb); len--; - if(!(h & 0x40)){ - seq = get_byte(s->pb); len--; - } - } - - if((flags&2) && (seq&0x7F) == 1){ -// av_log(s, AV_LOG_DEBUG, "%d %d-%d %"PRId64" %d\n", flags, stream_index2, stream_index, dts, seq); - av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME); - if(stream_index2 == stream_index) - break; - } - - url_fskip(s->pb, len); - } - *ppos = pos; - return dts; -} - -AVInputFormat rm_demuxer = { - "rm", - NULL_IF_CONFIG_SMALL("RealMedia format"), - sizeof(RMDemuxContext), - rm_probe, - rm_read_header, - rm_read_packet, - rm_read_close, - NULL, - rm_read_dts, -}; - -AVInputFormat rdt_demuxer = { - "rdt", - NULL_IF_CONFIG_SMALL("RDT demuxer"), - sizeof(RMDemuxContext), - NULL, - NULL, - NULL, - rm_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rmenc.c b/tizen/distrib/ffmpeg/libavformat/rmenc.c deleted file mode 100644 index 03db3ce..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rmenc.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * "Real" compatible muxer. - * Copyright (c) 2000, 2001 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "rm.h" - -typedef struct { - int nb_packets; - int packet_total_size; - int packet_max_size; - /* codec related output */ - int bit_rate; - float frame_rate; - int nb_frames; /* current frame number */ - int total_frames; /* total number of frames */ - int num; - AVCodecContext *enc; -} StreamInfo; - -typedef struct { - StreamInfo streams[2]; - StreamInfo *audio_stream, *video_stream; - int data_pos; /* position of the data after the header */ -} RMMuxContext; - -/* in ms */ -#define BUFFER_DURATION 0 - - -static void put_str(ByteIOContext *s, const char *tag) -{ - put_be16(s,strlen(tag)); - while (*tag) { - put_byte(s, *tag++); - } -} - -static void put_str8(ByteIOContext *s, const char *tag) -{ - put_byte(s, strlen(tag)); - while (*tag) { - put_byte(s, *tag++); - } -} - -static void rv10_write_header(AVFormatContext *ctx, - int data_size, int index_pos) -{ - RMMuxContext *rm = ctx->priv_data; - ByteIOContext *s = ctx->pb; - StreamInfo *stream; - unsigned char *data_offset_ptr, *start_ptr; - const char *desc, *mimetype; - int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i; - int bit_rate, v, duration, flags, data_pos; - AVMetadataTag *tag; - - start_ptr = s->buf_ptr; - - put_tag(s, ".RMF"); - put_be32(s,18); /* header size */ - put_be16(s,0); - put_be32(s,0); - put_be32(s,4 + ctx->nb_streams); /* num headers */ - - put_tag(s,"PROP"); - put_be32(s, 50); - put_be16(s, 0); - packet_max_size = 0; - packet_total_size = 0; - nb_packets = 0; - bit_rate = 0; - duration = 0; - for(i=0;inb_streams;i++) { - StreamInfo *stream = &rm->streams[i]; - bit_rate += stream->bit_rate; - if (stream->packet_max_size > packet_max_size) - packet_max_size = stream->packet_max_size; - nb_packets += stream->nb_packets; - packet_total_size += stream->packet_total_size; - /* select maximum duration */ - v = (int) (1000.0 * (float)stream->total_frames / stream->frame_rate); - if (v > duration) - duration = v; - } - put_be32(s, bit_rate); /* max bit rate */ - put_be32(s, bit_rate); /* avg bit rate */ - put_be32(s, packet_max_size); /* max packet size */ - if (nb_packets > 0) - packet_avg_size = packet_total_size / nb_packets; - else - packet_avg_size = 0; - put_be32(s, packet_avg_size); /* avg packet size */ - put_be32(s, nb_packets); /* num packets */ - put_be32(s, duration); /* duration */ - put_be32(s, BUFFER_DURATION); /* preroll */ - put_be32(s, index_pos); /* index offset */ - /* computation of data the data offset */ - data_offset_ptr = s->buf_ptr; - put_be32(s, 0); /* data offset : will be patched after */ - put_be16(s, ctx->nb_streams); /* num streams */ - flags = 1 | 2; /* save allowed & perfect play */ - if (url_is_streamed(s)) - flags |= 4; /* live broadcast */ - put_be16(s, flags); - - /* comments */ - - put_tag(s,"CONT"); - size = 4 * 2 + 10; - for(i=0; imetadata, ff_rm_metadata[i], NULL, 0); - if(tag) size += strlen(tag->value); - } - put_be32(s,size); - put_be16(s,0); - for(i=0; imetadata, ff_rm_metadata[i], NULL, 0); - put_str(s, tag ? tag->value : ""); - } - - for(i=0;inb_streams;i++) { - int codec_data_size; - - stream = &rm->streams[i]; - - if (stream->enc->codec_type == AVMEDIA_TYPE_AUDIO) { - desc = "The Audio Stream"; - mimetype = "audio/x-pn-realaudio"; - codec_data_size = 73; - } else { - desc = "The Video Stream"; - mimetype = "video/x-pn-realvideo"; - codec_data_size = 34; - } - - put_tag(s,"MDPR"); - size = 10 + 9 * 4 + strlen(desc) + strlen(mimetype) + codec_data_size; - put_be32(s, size); - put_be16(s, 0); - - put_be16(s, i); /* stream number */ - put_be32(s, stream->bit_rate); /* max bit rate */ - put_be32(s, stream->bit_rate); /* avg bit rate */ - put_be32(s, stream->packet_max_size); /* max packet size */ - if (stream->nb_packets > 0) - packet_avg_size = stream->packet_total_size / - stream->nb_packets; - else - packet_avg_size = 0; - put_be32(s, packet_avg_size); /* avg packet size */ - put_be32(s, 0); /* start time */ - put_be32(s, BUFFER_DURATION); /* preroll */ - /* duration */ - if (url_is_streamed(s) || !stream->total_frames) - put_be32(s, (int)(3600 * 1000)); - else - put_be32(s, (int)(stream->total_frames * 1000 / stream->frame_rate)); - put_str8(s, desc); - put_str8(s, mimetype); - put_be32(s, codec_data_size); - - if (stream->enc->codec_type == AVMEDIA_TYPE_AUDIO) { - int coded_frame_size, fscode, sample_rate; - sample_rate = stream->enc->sample_rate; - coded_frame_size = (stream->enc->bit_rate * - stream->enc->frame_size) / (8 * sample_rate); - /* audio codec info */ - put_tag(s, ".ra"); - put_byte(s, 0xfd); - put_be32(s, 0x00040000); /* version */ - put_tag(s, ".ra4"); - put_be32(s, 0x01b53530); /* stream length */ - put_be16(s, 4); /* unknown */ - put_be32(s, 0x39); /* header size */ - - switch(sample_rate) { - case 48000: - case 24000: - case 12000: - fscode = 1; - break; - default: - case 44100: - case 22050: - case 11025: - fscode = 2; - break; - case 32000: - case 16000: - case 8000: - fscode = 3; - } - put_be16(s, fscode); /* codec additional info, for AC-3, seems - to be a frequency code */ - /* special hack to compensate rounding errors... */ - if (coded_frame_size == 557) - coded_frame_size--; - put_be32(s, coded_frame_size); /* frame length */ - put_be32(s, 0x51540); /* unknown */ - put_be32(s, 0x249f0); /* unknown */ - put_be32(s, 0x249f0); /* unknown */ - put_be16(s, 0x01); - /* frame length : seems to be very important */ - put_be16(s, coded_frame_size); - put_be32(s, 0); /* unknown */ - put_be16(s, stream->enc->sample_rate); /* sample rate */ - put_be32(s, 0x10); /* unknown */ - put_be16(s, stream->enc->channels); - put_str8(s, "Int0"); /* codec name */ - put_str8(s, "dnet"); /* codec name */ - put_be16(s, 0); /* title length */ - put_be16(s, 0); /* author length */ - put_be16(s, 0); /* copyright length */ - put_byte(s, 0); /* end of header */ - } else { - /* video codec info */ - put_be32(s,34); /* size */ - if(stream->enc->codec_id == CODEC_ID_RV10) - put_tag(s,"VIDORV10"); - else - put_tag(s,"VIDORV20"); - put_be16(s, stream->enc->width); - put_be16(s, stream->enc->height); - put_be16(s, (int) stream->frame_rate); /* frames per seconds ? */ - put_be32(s,0); /* unknown meaning */ - put_be16(s, (int) stream->frame_rate); /* unknown meaning */ - put_be32(s,0); /* unknown meaning */ - put_be16(s, 8); /* unknown meaning */ - /* Seems to be the codec version: only use basic H263. The next - versions seems to add a diffential DC coding as in - MPEG... nothing new under the sun */ - if(stream->enc->codec_id == CODEC_ID_RV10) - put_be32(s,0x10000000); - else - put_be32(s,0x20103001); - //put_be32(s,0x10003000); - } - } - - /* patch data offset field */ - data_pos = s->buf_ptr - start_ptr; - rm->data_pos = data_pos; - data_offset_ptr[0] = data_pos >> 24; - data_offset_ptr[1] = data_pos >> 16; - data_offset_ptr[2] = data_pos >> 8; - data_offset_ptr[3] = data_pos; - - /* data stream */ - put_tag(s,"DATA"); - put_be32(s,data_size + 10 + 8); - put_be16(s,0); - - put_be32(s, nb_packets); /* number of packets */ - put_be32(s,0); /* next data header */ -} - -static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream, - int length, int key_frame) -{ - int timestamp; - ByteIOContext *s = ctx->pb; - - stream->nb_packets++; - stream->packet_total_size += length; - if (length > stream->packet_max_size) - stream->packet_max_size = length; - - put_be16(s,0); /* version */ - put_be16(s,length + 12); - put_be16(s, stream->num); /* stream number */ - timestamp = (1000 * (float)stream->nb_frames) / stream->frame_rate; - put_be32(s, timestamp); /* timestamp */ - put_byte(s, 0); /* reserved */ - put_byte(s, key_frame ? 2 : 0); /* flags */ -} - -static int rm_write_header(AVFormatContext *s) -{ - RMMuxContext *rm = s->priv_data; - StreamInfo *stream; - int n; - AVCodecContext *codec; - - for(n=0;nnb_streams;n++) { - s->streams[n]->id = n; - codec = s->streams[n]->codec; - stream = &rm->streams[n]; - memset(stream, 0, sizeof(StreamInfo)); - stream->num = n; - stream->bit_rate = codec->bit_rate; - stream->enc = codec; - - switch(codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - rm->audio_stream = stream; - stream->frame_rate = (float)codec->sample_rate / (float)codec->frame_size; - /* XXX: dummy values */ - stream->packet_max_size = 1024; - stream->nb_packets = 0; - stream->total_frames = stream->nb_packets; - break; - case AVMEDIA_TYPE_VIDEO: - rm->video_stream = stream; - stream->frame_rate = (float)codec->time_base.den / (float)codec->time_base.num; - /* XXX: dummy values */ - stream->packet_max_size = 4096; - stream->nb_packets = 0; - stream->total_frames = stream->nb_packets; - break; - default: - return -1; - } - } - - rv10_write_header(s, 0, 0); - put_flush_packet(s->pb); - return 0; -} - -static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int flags) -{ - uint8_t *buf1; - RMMuxContext *rm = s->priv_data; - ByteIOContext *pb = s->pb; - StreamInfo *stream = rm->audio_stream; - int i; - - /* XXX: suppress this malloc */ - buf1= (uint8_t*) av_malloc( size * sizeof(uint8_t) ); - - write_packet_header(s, stream, size, !!(flags & AV_PKT_FLAG_KEY)); - - /* for AC-3, the words seem to be reversed */ - for(i=0;inb_frames++; - av_free(buf1); - return 0; -} - -static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int flags) -{ - RMMuxContext *rm = s->priv_data; - ByteIOContext *pb = s->pb; - StreamInfo *stream = rm->video_stream; - int key_frame = !!(flags & AV_PKT_FLAG_KEY); - - /* XXX: this is incorrect: should be a parameter */ - - /* Well, I spent some time finding the meaning of these bits. I am - not sure I understood everything, but it works !! */ -#if 1 - write_packet_header(s, stream, size + 7 + (size >= 0x4000)*4, key_frame); - /* bit 7: '1' if final packet of a frame converted in several packets */ - put_byte(pb, 0x81); - /* bit 7: '1' if I frame. bits 6..0 : sequence number in current - frame starting from 1 */ - if (key_frame) { - put_byte(pb, 0x81); - } else { - put_byte(pb, 0x01); - } - if(size >= 0x4000){ - put_be32(pb, size); /* total frame size */ - put_be32(pb, size); /* offset from the start or the end */ - }else{ - put_be16(pb, 0x4000 | size); /* total frame size */ - put_be16(pb, 0x4000 | size); /* offset from the start or the end */ - } -#else - /* full frame */ - write_packet_header(s, size + 6); - put_byte(pb, 0xc0); - put_be16(pb, 0x4000 + size); /* total frame size */ - put_be16(pb, 0x4000 + packet_number * 126); /* position in stream */ -#endif - put_byte(pb, stream->nb_frames & 0xff); - - put_buffer(pb, buf, size); - put_flush_packet(pb); - - stream->nb_frames++; - return 0; -} - -static int rm_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - if (s->streams[pkt->stream_index]->codec->codec_type == - AVMEDIA_TYPE_AUDIO) - return rm_write_audio(s, pkt->data, pkt->size, pkt->flags); - else - return rm_write_video(s, pkt->data, pkt->size, pkt->flags); -} - -static int rm_write_trailer(AVFormatContext *s) -{ - RMMuxContext *rm = s->priv_data; - int data_size, index_pos, i; - ByteIOContext *pb = s->pb; - - if (!url_is_streamed(s->pb)) { - /* end of file: finish to write header */ - index_pos = url_fseek(pb, 0, SEEK_CUR); - data_size = index_pos - rm->data_pos; - - /* FIXME: write index */ - - /* undocumented end header */ - put_be32(pb, 0); - put_be32(pb, 0); - - url_fseek(pb, 0, SEEK_SET); - for(i=0;inb_streams;i++) - rm->streams[i].total_frames = rm->streams[i].nb_frames; - rv10_write_header(s, data_size, 0); - } else { - /* undocumented end header */ - put_be32(pb, 0); - put_be32(pb, 0); - } - put_flush_packet(pb); - return 0; -} - - -AVOutputFormat rm_muxer = { - "rm", - NULL_IF_CONFIG_SMALL("RealMedia format"), - "application/vnd.rn-realmedia", - "rm,ra", - sizeof(RMMuxContext), - CODEC_ID_AC3, - CODEC_ID_RV10, - rm_write_header, - rm_write_packet, - rm_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rpl.c b/tizen/distrib/ffmpeg/libavformat/rpl.c deleted file mode 100644 index f0fba3e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rpl.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * ARMovie/RPL demuxer - * Copyright (c) 2007 Christian Ohm, 2008 Eli Friedman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avstring.h" -#include "avformat.h" -#include - -#define RPL_SIGNATURE "ARMovie\x0A" -#define RPL_SIGNATURE_SIZE 8 - -/** 256 is arbitrary, but should be big enough for any reasonable file. */ -#define RPL_LINE_LENGTH 256 - -static int rpl_probe(AVProbeData *p) -{ - if (memcmp(p->buf, RPL_SIGNATURE, RPL_SIGNATURE_SIZE)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -typedef struct RPLContext { - // RPL header data - int32_t frames_per_chunk; - - // Stream position data - uint32_t chunk_number; - uint32_t chunk_part; - uint32_t frame_in_part; -} RPLContext; - -static int read_line(ByteIOContext * pb, char* line, int bufsize) -{ - int i; - for (i = 0; i < bufsize - 1; i++) { - int b = get_byte(pb); - if (b == 0) - break; - if (b == '\n') { - line[i] = '\0'; - return 0; - } - line[i] = b; - } - line[i] = '\0'; - return -1; -} - -static int32_t read_int(const char* line, const char** endptr, int* error) -{ - unsigned long result = 0; - for (; *line>='0' && *line<='9'; line++) { - if (result > (0x7FFFFFFF - 9) / 10) - *error = -1; - result = 10 * result + *line - '0'; - } - *endptr = line; - return result; -} - -static int32_t read_line_and_int(ByteIOContext * pb, int* error) -{ - char line[RPL_LINE_LENGTH]; - const char *endptr; - *error |= read_line(pb, line, sizeof(line)); - return read_int(line, &endptr, error); -} - -/** Parsing for fps, which can be a fraction. Unfortunately, - * the spec for the header leaves out a lot of details, - * so this is mostly guessing. - */ -static AVRational read_fps(const char* line, int* error) -{ - int64_t num, den = 1; - AVRational result; - num = read_int(line, &line, error); - if (*line == '.') - line++; - for (; *line>='0' && *line<='9'; line++) { - // Truncate any numerator too large to fit into an int64_t - if (num > (INT64_MAX - 9) / 10 || den > INT64_MAX / 10) - break; - num = 10 * num + *line - '0'; - den *= 10; - } - if (!num) - *error = -1; - av_reduce(&result.num, &result.den, num, den, 0x7FFFFFFF); - return result; -} - -static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - RPLContext *rpl = s->priv_data; - AVStream *vst = NULL, *ast = NULL; - int total_audio_size; - int error = 0; - - uint32_t i; - - int32_t audio_format, chunk_catalog_offset, number_of_chunks; - AVRational fps; - - char line[RPL_LINE_LENGTH]; - - // The header for RPL/ARMovie files is 21 lines of text - // containing the various header fields. The fields are always - // in the same order, and other text besides the first - // number usually isn't important. - // (The spec says that there exists some significance - // for the text in a few cases; samples needed.) - error |= read_line(pb, line, sizeof(line)); // ARMovie - error |= read_line(pb, line, sizeof(line)); // movie name - av_metadata_set2(&s->metadata, "title" , line, 0); - error |= read_line(pb, line, sizeof(line)); // date/copyright - av_metadata_set2(&s->metadata, "copyright", line, 0); - error |= read_line(pb, line, sizeof(line)); // author and other - av_metadata_set2(&s->metadata, "author" , line, 0); - - // video headers - vst = av_new_stream(s, 0); - if (!vst) - return AVERROR(ENOMEM); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_tag = read_line_and_int(pb, &error); // video format - vst->codec->width = read_line_and_int(pb, &error); // video width - vst->codec->height = read_line_and_int(pb, &error); // video height - vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // video bits per sample - error |= read_line(pb, line, sizeof(line)); // video frames per second - fps = read_fps(line, &error); - av_set_pts_info(vst, 32, fps.den, fps.num); - - // Figure out the video codec - switch (vst->codec->codec_tag) { -#if 0 - case 122: - vst->codec->codec_id = CODEC_ID_ESCAPE122; - break; -#endif - case 124: - vst->codec->codec_id = CODEC_ID_ESCAPE124; - // The header is wrong here, at least sometimes - vst->codec->bits_per_coded_sample = 16; - break; -#if 0 - case 130: - vst->codec->codec_id = CODEC_ID_ESCAPE130; - break; -#endif - default: - av_log(s, AV_LOG_WARNING, - "RPL video format %i not supported yet!\n", - vst->codec->codec_tag); - vst->codec->codec_id = CODEC_ID_NONE; - } - - // Audio headers - - // ARMovie supports multiple audio tracks; I don't have any - // samples, though. This code will ignore additional tracks. - audio_format = read_line_and_int(pb, &error); // audio format ID - if (audio_format) { - ast = av_new_stream(s, 0); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_tag = audio_format; - ast->codec->sample_rate = read_line_and_int(pb, &error); // audio bitrate - ast->codec->channels = read_line_and_int(pb, &error); // number of audio channels - ast->codec->bits_per_coded_sample = read_line_and_int(pb, &error); // audio bits per sample - // At least one sample uses 0 for ADPCM, which is really 4 bits - // per sample. - if (ast->codec->bits_per_coded_sample == 0) - ast->codec->bits_per_coded_sample = 4; - - ast->codec->bit_rate = ast->codec->sample_rate * - ast->codec->bits_per_coded_sample * - ast->codec->channels; - - ast->codec->codec_id = CODEC_ID_NONE; - switch (audio_format) { - case 1: - if (ast->codec->bits_per_coded_sample == 16) { - // 16-bit audio is always signed - ast->codec->codec_id = CODEC_ID_PCM_S16LE; - break; - } - // There are some other formats listed as legal per the spec; - // samples needed. - break; - case 101: - if (ast->codec->bits_per_coded_sample == 8) { - // The samples with this kind of audio that I have - // are all unsigned. - ast->codec->codec_id = CODEC_ID_PCM_U8; - break; - } else if (ast->codec->bits_per_coded_sample == 4) { - ast->codec->codec_id = CODEC_ID_ADPCM_IMA_EA_SEAD; - break; - } - break; - } - if (ast->codec->codec_id == CODEC_ID_NONE) { - av_log(s, AV_LOG_WARNING, - "RPL audio format %i not supported yet!\n", - audio_format); - } - av_set_pts_info(ast, 32, 1, ast->codec->bit_rate); - } else { - for (i = 0; i < 3; i++) - error |= read_line(pb, line, sizeof(line)); - } - - rpl->frames_per_chunk = read_line_and_int(pb, &error); // video frames per chunk - if (rpl->frames_per_chunk > 1 && vst->codec->codec_tag != 124) - av_log(s, AV_LOG_WARNING, - "Don't know how to split frames for video format %i. " - "Video stream will be broken!\n", vst->codec->codec_tag); - - number_of_chunks = read_line_and_int(pb, &error); // number of chunks in the file - // The number in the header is actually the index of the last chunk. - number_of_chunks++; - - error |= read_line(pb, line, sizeof(line)); // "even" chunk size in bytes - error |= read_line(pb, line, sizeof(line)); // "odd" chunk size in bytes - chunk_catalog_offset = // offset of the "chunk catalog" - read_line_and_int(pb, &error); // (file index) - error |= read_line(pb, line, sizeof(line)); // offset to "helpful" sprite - error |= read_line(pb, line, sizeof(line)); // size of "helpful" sprite - error |= read_line(pb, line, sizeof(line)); // offset to key frame list - - // Read the index - url_fseek(pb, chunk_catalog_offset, SEEK_SET); - total_audio_size = 0; - for (i = 0; i < number_of_chunks; i++) { - int64_t offset, video_size, audio_size; - error |= read_line(pb, line, sizeof(line)); - if (3 != sscanf(line, "%"PRId64" , %"PRId64" ; %"PRId64, - &offset, &video_size, &audio_size)) - error = -1; - av_add_index_entry(vst, offset, i * rpl->frames_per_chunk, - video_size, rpl->frames_per_chunk, 0); - if (ast) - av_add_index_entry(ast, offset + video_size, total_audio_size, - audio_size, audio_size * 8, 0); - total_audio_size += audio_size * 8; - } - - if (error) return AVERROR(EIO); - - return 0; -} - -static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - RPLContext *rpl = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream* stream; - AVIndexEntry* index_entry; - uint32_t ret; - - if (rpl->chunk_part == s->nb_streams) { - rpl->chunk_number++; - rpl->chunk_part = 0; - } - - stream = s->streams[rpl->chunk_part]; - - if (rpl->chunk_number >= stream->nb_index_entries) - return -1; - - index_entry = &stream->index_entries[rpl->chunk_number]; - - if (rpl->frame_in_part == 0) - if (url_fseek(pb, index_entry->pos, SEEK_SET) < 0) - return AVERROR(EIO); - - if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && - stream->codec->codec_tag == 124) { - // We have to split Escape 124 frames because there are - // multiple frames per chunk in Escape 124 samples. - uint32_t frame_size, frame_flags; - - frame_flags = get_le32(pb); - frame_size = get_le32(pb); - if (url_fseek(pb, -8, SEEK_CUR) < 0) - return AVERROR(EIO); - - ret = av_get_packet(pb, pkt, frame_size); - if (ret != frame_size) { - av_free_packet(pkt); - return AVERROR(EIO); - } - pkt->duration = 1; - pkt->pts = index_entry->timestamp + rpl->frame_in_part; - pkt->stream_index = rpl->chunk_part; - - rpl->frame_in_part++; - if (rpl->frame_in_part == rpl->frames_per_chunk) { - rpl->frame_in_part = 0; - rpl->chunk_part++; - } - } else { - ret = av_get_packet(pb, pkt, index_entry->size); - if (ret != index_entry->size) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - // frames_per_chunk should always be one here; the header - // parsing will warn if it isn't. - pkt->duration = rpl->frames_per_chunk; - } else { - // All the audio codecs supported in this container - // (at least so far) are constant-bitrate. - pkt->duration = ret * 8; - } - pkt->pts = index_entry->timestamp; - pkt->stream_index = rpl->chunk_part; - rpl->chunk_part++; - } - - // None of the Escape formats have keyframes, and the ADPCM - // format used doesn't have keyframes. - if (rpl->chunk_number == 0 && rpl->frame_in_part == 0) - pkt->flags |= AV_PKT_FLAG_KEY; - - return ret; -} - -AVInputFormat rpl_demuxer = { - "rpl", - NULL_IF_CONFIG_SMALL("RPL/ARMovie format"), - sizeof(RPLContext), - rpl_probe, - rpl_read_header, - rpl_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rtmp.h b/tizen/distrib/ffmpeg/libavformat/rtmp.h deleted file mode 100644 index b0436c0..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtmp.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * RTMP definitions - * Copyright (c) 2009 Kostya Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTMP_H -#define AVFORMAT_RTMP_H - -#include "avformat.h" - -#define RTMP_DEFAULT_PORT 1935 - -#define RTMP_HANDSHAKE_PACKET_SIZE 1536 - -/** - * emulated Flash client version - 9.0.124.2 on Linux - * @{ - */ -#define RTMP_CLIENT_PLATFORM "LNX" -#define RTMP_CLIENT_VER1 9 -#define RTMP_CLIENT_VER2 0 -#define RTMP_CLIENT_VER3 124 -#define RTMP_CLIENT_VER4 2 -/** @} */ //version defines - -#endif /* AVFORMAT_RTMP_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtmppkt.c b/tizen/distrib/ffmpeg/libavformat/rtmppkt.c deleted file mode 100644 index 58c3abe..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtmppkt.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * RTMP input format - * Copyright (c) 2009 Kostya Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/bytestream.h" -#include "libavutil/avstring.h" -#include "avformat.h" - -#include "rtmppkt.h" -#include "flv.h" - -void ff_amf_write_bool(uint8_t **dst, int val) -{ - bytestream_put_byte(dst, AMF_DATA_TYPE_BOOL); - bytestream_put_byte(dst, val); -} - -void ff_amf_write_number(uint8_t **dst, double val) -{ - bytestream_put_byte(dst, AMF_DATA_TYPE_NUMBER); - bytestream_put_be64(dst, av_dbl2int(val)); -} - -void ff_amf_write_string(uint8_t **dst, const char *str) -{ - bytestream_put_byte(dst, AMF_DATA_TYPE_STRING); - bytestream_put_be16(dst, strlen(str)); - bytestream_put_buffer(dst, str, strlen(str)); -} - -void ff_amf_write_null(uint8_t **dst) -{ - bytestream_put_byte(dst, AMF_DATA_TYPE_NULL); -} - -void ff_amf_write_object_start(uint8_t **dst) -{ - bytestream_put_byte(dst, AMF_DATA_TYPE_OBJECT); -} - -void ff_amf_write_field_name(uint8_t **dst, const char *str) -{ - bytestream_put_be16(dst, strlen(str)); - bytestream_put_buffer(dst, str, strlen(str)); -} - -void ff_amf_write_object_end(uint8_t **dst) -{ - /* first two bytes are field name length = 0, - * AMF object should end with it and end marker - */ - bytestream_put_be24(dst, AMF_DATA_TYPE_OBJECT_END); -} - -int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p, - int chunk_size, RTMPPacket *prev_pkt) -{ - uint8_t hdr, t, buf[16]; - int channel_id, timestamp, data_size, offset = 0; - uint32_t extra = 0; - enum RTMPPacketType type; - int size = 0; - - if (url_read(h, &hdr, 1) != 1) - return AVERROR(EIO); - size++; - channel_id = hdr & 0x3F; - - if (channel_id < 2) { //special case for channel number >= 64 - buf[1] = 0; - if (url_read_complete(h, buf, channel_id + 1) != channel_id + 1) - return AVERROR(EIO); - size += channel_id + 1; - channel_id = AV_RL16(buf) + 64; - } - data_size = prev_pkt[channel_id].data_size; - type = prev_pkt[channel_id].type; - extra = prev_pkt[channel_id].extra; - - hdr >>= 6; - if (hdr == RTMP_PS_ONEBYTE) { - timestamp = prev_pkt[channel_id].ts_delta; - } else { - if (url_read_complete(h, buf, 3) != 3) - return AVERROR(EIO); - size += 3; - timestamp = AV_RB24(buf); - if (hdr != RTMP_PS_FOURBYTES) { - if (url_read_complete(h, buf, 3) != 3) - return AVERROR(EIO); - size += 3; - data_size = AV_RB24(buf); - if (url_read_complete(h, buf, 1) != 1) - return AVERROR(EIO); - size++; - type = buf[0]; - if (hdr == RTMP_PS_TWELVEBYTES) { - if (url_read_complete(h, buf, 4) != 4) - return AVERROR(EIO); - size += 4; - extra = AV_RL32(buf); - } - } - if (timestamp == 0xFFFFFF) { - if (url_read_complete(h, buf, 4) != 4) - return AVERROR(EIO); - timestamp = AV_RB32(buf); - } - } - if (hdr != RTMP_PS_TWELVEBYTES) - timestamp += prev_pkt[channel_id].timestamp; - - if (ff_rtmp_packet_create(p, channel_id, type, timestamp, data_size)) - return -1; - p->extra = extra; - // save history - prev_pkt[channel_id].channel_id = channel_id; - prev_pkt[channel_id].type = type; - prev_pkt[channel_id].data_size = data_size; - prev_pkt[channel_id].ts_delta = timestamp - prev_pkt[channel_id].timestamp; - prev_pkt[channel_id].timestamp = timestamp; - prev_pkt[channel_id].extra = extra; - while (data_size > 0) { - int toread = FFMIN(data_size, chunk_size); - if (url_read_complete(h, p->data + offset, toread) != toread) { - ff_rtmp_packet_destroy(p); - return AVERROR(EIO); - } - data_size -= chunk_size; - offset += chunk_size; - size += chunk_size; - if (data_size > 0) { - url_read_complete(h, &t, 1); //marker - size++; - if (t != (0xC0 + channel_id)) - return -1; - } - } - return size; -} - -int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, - int chunk_size, RTMPPacket *prev_pkt) -{ - uint8_t pkt_hdr[16], *p = pkt_hdr; - int mode = RTMP_PS_TWELVEBYTES; - int off = 0; - int size = 0; - - pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp; - - //if channel_id = 0, this is first presentation of prev_pkt, send full hdr. - if (prev_pkt[pkt->channel_id].channel_id && - pkt->extra == prev_pkt[pkt->channel_id].extra) { - if (pkt->type == prev_pkt[pkt->channel_id].type && - pkt->data_size == prev_pkt[pkt->channel_id].data_size) { - mode = RTMP_PS_FOURBYTES; - if (pkt->ts_delta == prev_pkt[pkt->channel_id].ts_delta) - mode = RTMP_PS_ONEBYTE; - } else { - mode = RTMP_PS_EIGHTBYTES; - } - } - - if (pkt->channel_id < 64) { - bytestream_put_byte(&p, pkt->channel_id | (mode << 6)); - } else if (pkt->channel_id < 64 + 256) { - bytestream_put_byte(&p, 0 | (mode << 6)); - bytestream_put_byte(&p, pkt->channel_id - 64); - } else { - bytestream_put_byte(&p, 1 | (mode << 6)); - bytestream_put_le16(&p, pkt->channel_id - 64); - } - if (mode != RTMP_PS_ONEBYTE) { - uint32_t timestamp = pkt->timestamp; - if (mode != RTMP_PS_TWELVEBYTES) - timestamp = pkt->ts_delta; - bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp); - if (mode != RTMP_PS_FOURBYTES) { - bytestream_put_be24(&p, pkt->data_size); - bytestream_put_byte(&p, pkt->type); - if (mode == RTMP_PS_TWELVEBYTES) - bytestream_put_le32(&p, pkt->extra); - } - if (timestamp >= 0xFFFFFF) - bytestream_put_be32(&p, timestamp); - } - // save history - prev_pkt[pkt->channel_id].channel_id = pkt->channel_id; - prev_pkt[pkt->channel_id].type = pkt->type; - prev_pkt[pkt->channel_id].data_size = pkt->data_size; - prev_pkt[pkt->channel_id].timestamp = pkt->timestamp; - if (mode != RTMP_PS_TWELVEBYTES) { - prev_pkt[pkt->channel_id].ts_delta = pkt->ts_delta; - } else { - prev_pkt[pkt->channel_id].ts_delta = pkt->timestamp; - } - prev_pkt[pkt->channel_id].extra = pkt->extra; - - url_write(h, pkt_hdr, p-pkt_hdr); - size = p - pkt_hdr + pkt->data_size; - while (off < pkt->data_size) { - int towrite = FFMIN(chunk_size, pkt->data_size - off); - url_write(h, pkt->data + off, towrite); - off += towrite; - if (off < pkt->data_size) { - uint8_t marker = 0xC0 | pkt->channel_id; - url_write(h, &marker, 1); - size++; - } - } - return size; -} - -int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, - int timestamp, int size) -{ - pkt->data = av_malloc(size); - if (!pkt->data) - return AVERROR(ENOMEM); - pkt->data_size = size; - pkt->channel_id = channel_id; - pkt->type = type; - pkt->timestamp = timestamp; - pkt->extra = 0; - pkt->ts_delta = 0; - - return 0; -} - -void ff_rtmp_packet_destroy(RTMPPacket *pkt) -{ - if (!pkt) - return; - av_freep(&pkt->data); - pkt->data_size = 0; -} - -int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) -{ - const uint8_t *base = data; - - if (data >= data_end) - return -1; - switch (*data++) { - case AMF_DATA_TYPE_NUMBER: return 9; - case AMF_DATA_TYPE_BOOL: return 2; - case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data); - case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data); - case AMF_DATA_TYPE_NULL: return 1; - case AMF_DATA_TYPE_ARRAY: - data += 4; - case AMF_DATA_TYPE_OBJECT: - for (;;) { - int size = bytestream_get_be16(&data); - int t; - if (!size) { - data++; - break; - } - if (data + size >= data_end || data + size < data) - return -1; - data += size; - t = ff_amf_tag_size(data, data_end); - if (t < 0 || data + t >= data_end) - return -1; - data += t; - } - return data - base; - case AMF_DATA_TYPE_OBJECT_END: return 1; - default: return -1; - } -} - -int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, - const uint8_t *name, uint8_t *dst, int dst_size) -{ - int namelen = strlen(name); - int len; - - while (*data != AMF_DATA_TYPE_OBJECT && data < data_end) { - len = ff_amf_tag_size(data, data_end); - if (len < 0) - len = data_end - data; - data += len; - } - if (data_end - data < 3) - return -1; - data++; - for (;;) { - int size = bytestream_get_be16(&data); - if (!size) - break; - if (data + size >= data_end || data + size < data) - return -1; - data += size; - if (size == namelen && !memcmp(data-size, name, namelen)) { - switch (*data++) { - case AMF_DATA_TYPE_NUMBER: - snprintf(dst, dst_size, "%g", av_int2dbl(AV_RB64(data))); - break; - case AMF_DATA_TYPE_BOOL: - snprintf(dst, dst_size, "%s", *data ? "true" : "false"); - break; - case AMF_DATA_TYPE_STRING: - len = bytestream_get_be16(&data); - av_strlcpy(dst, data, FFMIN(len+1, dst_size)); - break; - default: - return -1; - } - return 0; - } - len = ff_amf_tag_size(data, data_end); - if (len < 0 || data + len >= data_end || data + len < data) - return -1; - data += len; - } - return -1; -} - -static const char* rtmp_packet_type(int type) -{ - switch (type) { - case RTMP_PT_CHUNK_SIZE: return "chunk size"; - case RTMP_PT_BYTES_READ: return "bytes read"; - case RTMP_PT_PING: return "ping"; - case RTMP_PT_SERVER_BW: return "server bandwidth"; - case RTMP_PT_CLIENT_BW: return "client bandwidth"; - case RTMP_PT_AUDIO: return "audio packet"; - case RTMP_PT_VIDEO: return "video packet"; - case RTMP_PT_FLEX_STREAM: return "Flex shared stream"; - case RTMP_PT_FLEX_OBJECT: return "Flex shared object"; - case RTMP_PT_FLEX_MESSAGE: return "Flex shared message"; - case RTMP_PT_NOTIFY: return "notification"; - case RTMP_PT_SHARED_OBJ: return "shared object"; - case RTMP_PT_INVOKE: return "invoke"; - case RTMP_PT_METADATA: return "metadata"; - default: return "unknown"; - } -} - -static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end) -{ - int size; - char buf[1024]; - - if (data >= data_end) - return; - switch (*data++) { - case AMF_DATA_TYPE_NUMBER: - av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2dbl(AV_RB64(data))); - return; - case AMF_DATA_TYPE_BOOL: - av_log(ctx, AV_LOG_DEBUG, " bool %d\n", *data); - return; - case AMF_DATA_TYPE_STRING: - case AMF_DATA_TYPE_LONG_STRING: - if (data[-1] == AMF_DATA_TYPE_STRING) { - size = bytestream_get_be16(&data); - } else { - size = bytestream_get_be32(&data); - } - size = FFMIN(size, 1023); - memcpy(buf, data, size); - buf[size] = 0; - av_log(ctx, AV_LOG_DEBUG, " string '%s'\n", buf); - return; - case AMF_DATA_TYPE_NULL: - av_log(ctx, AV_LOG_DEBUG, " NULL\n"); - return; - case AMF_DATA_TYPE_ARRAY: - data += 4; - case AMF_DATA_TYPE_OBJECT: - av_log(ctx, AV_LOG_DEBUG, " {\n"); - for (;;) { - int size = bytestream_get_be16(&data); - int t; - memcpy(buf, data, size); - buf[size] = 0; - if (!size) { - av_log(ctx, AV_LOG_DEBUG, " }\n"); - data++; - break; - } - if (data + size >= data_end || data + size < data) - return; - data += size; - av_log(ctx, AV_LOG_DEBUG, " %s: ", buf); - ff_amf_tag_contents(ctx, data, data_end); - t = ff_amf_tag_size(data, data_end); - if (t < 0 || data + t >= data_end) - return; - data += t; - } - return; - case AMF_DATA_TYPE_OBJECT_END: - av_log(ctx, AV_LOG_DEBUG, " }\n"); - return; - default: - return; - } -} - -void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p) -{ - av_log(ctx, AV_LOG_DEBUG, "RTMP packet type '%s'(%d) for channel %d, timestamp %d, extra field %d size %d\n", - rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->data_size); - if (p->type == RTMP_PT_INVOKE || p->type == RTMP_PT_NOTIFY) { - uint8_t *src = p->data, *src_end = p->data + p->data_size; - while (src < src_end) { - int sz; - ff_amf_tag_contents(ctx, src, src_end); - sz = ff_amf_tag_size(src, src_end); - if (sz < 0) - break; - src += sz; - } - } else if (p->type == RTMP_PT_SERVER_BW){ - av_log(ctx, AV_LOG_DEBUG, "Server BW = %d\n", AV_RB32(p->data)); - } else if (p->type == RTMP_PT_CLIENT_BW){ - av_log(ctx, AV_LOG_DEBUG, "Client BW = %d\n", AV_RB32(p->data)); - } else if (p->type != RTMP_PT_AUDIO && p->type != RTMP_PT_VIDEO && p->type != RTMP_PT_METADATA) { - int i; - for (i = 0; i < p->data_size; i++) - av_log(ctx, AV_LOG_DEBUG, " %02X", p->data[i]); - av_log(ctx, AV_LOG_DEBUG, "\n"); - } -} diff --git a/tizen/distrib/ffmpeg/libavformat/rtmppkt.h b/tizen/distrib/ffmpeg/libavformat/rtmppkt.h deleted file mode 100644 index 23d4ebc..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtmppkt.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * RTMP packet utilities - * Copyright (c) 2009 Kostya Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTMPPKT_H -#define AVFORMAT_RTMPPKT_H - -#include "avformat.h" - -/** maximum possible number of different RTMP channels */ -#define RTMP_CHANNELS 65599 - -/** - * channels used to for RTMP packets with different purposes (i.e. data, network - * control, remote procedure calls, etc.) - */ -enum RTMPChannel { - RTMP_NETWORK_CHANNEL = 2, ///< channel for network-related messages (bandwidth report, ping, etc) - RTMP_SYSTEM_CHANNEL, ///< channel for sending server control messages - RTMP_SOURCE_CHANNEL, ///< channel for sending a/v to server - RTMP_VIDEO_CHANNEL = 8, ///< channel for video data - RTMP_AUDIO_CHANNEL, ///< channel for audio data -}; - -/** - * known RTMP packet types - */ -typedef enum RTMPPacketType { - RTMP_PT_CHUNK_SIZE = 1, ///< chunk size change - RTMP_PT_BYTES_READ = 3, ///< number of bytes read - RTMP_PT_PING, ///< ping - RTMP_PT_SERVER_BW, ///< server bandwidth - RTMP_PT_CLIENT_BW, ///< client bandwidth - RTMP_PT_AUDIO = 8, ///< audio packet - RTMP_PT_VIDEO, ///< video packet - RTMP_PT_FLEX_STREAM = 15, ///< Flex shared stream - RTMP_PT_FLEX_OBJECT, ///< Flex shared object - RTMP_PT_FLEX_MESSAGE, ///< Flex shared message - RTMP_PT_NOTIFY, ///< some notification - RTMP_PT_SHARED_OBJ, ///< shared object - RTMP_PT_INVOKE, ///< invoke some stream action - RTMP_PT_METADATA = 22, ///< FLV metadata -} RTMPPacketType; - -/** - * possible RTMP packet header sizes - */ -enum RTMPPacketSize { - RTMP_PS_TWELVEBYTES = 0, ///< packet has 12-byte header - RTMP_PS_EIGHTBYTES, ///< packet has 8-byte header - RTMP_PS_FOURBYTES, ///< packet has 4-byte header - RTMP_PS_ONEBYTE ///< packet is really a next chunk of a packet -}; - -/** - * structure for holding RTMP packets - */ -typedef struct RTMPPacket { - int channel_id; ///< RTMP channel ID (nothing to do with audio/video channels though) - RTMPPacketType type; ///< packet payload type - uint32_t timestamp; ///< packet full timestamp - uint32_t ts_delta; ///< timestamp increment to the previous one in milliseconds (latter only for media packets) - uint32_t extra; ///< probably an additional channel ID used during streaming data - uint8_t *data; ///< packet payload - int data_size; ///< packet payload size -} RTMPPacket; - -/** - * Creates new RTMP packet with given attributes. - * - * @param pkt packet - * @param channel_id packet channel ID - * @param type packet type - * @param timestamp packet timestamp - * @param size packet size - * @return zero on success, negative value otherwise - */ -int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, - int timestamp, int size); - -/** - * Frees RTMP packet. - * - * @param pkt packet - */ -void ff_rtmp_packet_destroy(RTMPPacket *pkt); - -/** - * Reads RTMP packet sent by the server. - * - * @param h reader context - * @param p packet - * @param chunk_size current chunk size - * @param prev_pkt previously read packet headers for all channels - * (may be needed for restoring incomplete packet header) - * @return number of bytes read on success, negative value otherwise - */ -int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p, - int chunk_size, RTMPPacket *prev_pkt); - -/** - * Sends RTMP packet to the server. - * - * @param h reader context - * @param p packet to send - * @param chunk_size current chunk size - * @param prev_pkt previously sent packet headers for all channels - * (may be used for packet header compressing) - * @return number of bytes written on success, negative value otherwise - */ -int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p, - int chunk_size, RTMPPacket *prev_pkt); - -/** - * Prints information and contents of RTMP packet. - * - * @param h output context - * @param p packet to dump - */ -void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p); - -/** - * @defgroup amffuncs functions used to work with AMF format (which is also used in .flv) - * @see amf_* funcs in libavformat/flvdec.c - * @{ - */ - -/** - * Calculates number of bytes taken by first AMF entry in data. - * - * @param data input data - * @param data_end input buffer end - * @return number of bytes used by first AMF entry - */ -int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end); - -/** - * Retrieves value of given AMF object field in string form. - * - * @param data AMF object data - * @param data_end input buffer end - * @param name name of field to retrieve - * @param dst buffer for storing result - * @param dst_size output buffer size - * @return 0 if search and retrieval succeeded, negative value otherwise - */ -int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, - const uint8_t *name, uint8_t *dst, int dst_size); - -/** - * Writes boolean value in AMF format to buffer. - * - * @param dst pointer to the input buffer (will be modified) - * @param val value to write - */ -void ff_amf_write_bool(uint8_t **dst, int val); - -/** - * Writes number in AMF format to buffer. - * - * @param dst pointer to the input buffer (will be modified) - * @param num value to write - */ -void ff_amf_write_number(uint8_t **dst, double num); - -/** - * Writes string in AMF format to buffer. - * - * @param dst pointer to the input buffer (will be modified) - * @param str string to write - */ -void ff_amf_write_string(uint8_t **dst, const char *str); - -/** - * Writes AMF NULL value to buffer. - * - * @param dst pointer to the input buffer (will be modified) - */ -void ff_amf_write_null(uint8_t **dst); - -/** - * Writes marker for AMF object to buffer. - * - * @param dst pointer to the input buffer (will be modified) - */ -void ff_amf_write_object_start(uint8_t **dst); - -/** - * Writes string used as field name in AMF object to buffer. - * - * @param dst pointer to the input buffer (will be modified) - * @param str string to write - */ -void ff_amf_write_field_name(uint8_t **dst, const char *str); - -/** - * Writes marker for end of AMF object to buffer. - * - * @param dst pointer to the input buffer (will be modified) - */ -void ff_amf_write_object_end(uint8_t **dst); - -/** @} */ // AMF funcs - -#endif /* AVFORMAT_RTMPPKT_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtmpproto.c b/tizen/distrib/ffmpeg/libavformat/rtmpproto.c deleted file mode 100644 index 4edbffa..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtmpproto.c +++ /dev/null @@ -1,998 +0,0 @@ -/* - * RTMP network protocol - * Copyright (c) 2009 Kostya Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RTMP protocol - */ - -#include "libavcodec/bytestream.h" -#include "libavutil/avstring.h" -#include "libavutil/lfg.h" -#include "libavutil/sha.h" -#include "avformat.h" -#include "internal.h" - -#include "network.h" - -#include "flv.h" -#include "rtmp.h" -#include "rtmppkt.h" - -/* we can't use av_log() with URLContext yet... */ -#if LIBAVFORMAT_VERSION_MAJOR < 53 -#define LOG_CONTEXT NULL -#else -#define LOG_CONTEXT s -#endif - -//#define DEBUG - -/** RTMP protocol handler state */ -typedef enum { - STATE_START, ///< client has not done anything yet - STATE_HANDSHAKED, ///< client has performed handshake - STATE_RELEASING, ///< client releasing stream before publish it (for output) - STATE_FCPUBLISH, ///< client FCPublishing stream (for output) - STATE_CONNECTING, ///< client connected to server successfully - STATE_READY, ///< client has sent all needed commands and waits for server reply - STATE_PLAYING, ///< client has started receiving multimedia data from server - STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output) - STATE_STOPPED, ///< the broadcast has been stopped -} ClientState; - -/** protocol handler context */ -typedef struct RTMPContext { - URLContext* stream; ///< TCP stream used in interactions with RTMP server - RTMPPacket prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets - int chunk_size; ///< size of the chunks RTMP packets are divided into - int is_input; ///< input/output flag - char playpath[256]; ///< path to filename to play (with possible "mp4:" prefix) - char app[128]; ///< application - ClientState state; ///< current state - int main_channel_id; ///< an additional channel ID which is used for some invocations - uint8_t* flv_data; ///< buffer with data for demuxer - int flv_size; ///< current buffer size - int flv_off; ///< number of bytes read from current buffer - RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output) - uint32_t client_report_size; ///< number of bytes after which client should report to server - uint32_t bytes_read; ///< number of bytes read from server - uint32_t last_bytes_read; ///< number of bytes read last reported to server -} RTMPContext; - -#define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing -/** Client key used for digest signing */ -static const uint8_t rtmp_player_key[] = { - 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ', - 'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1', - - 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02, - 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8, - 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE -}; - -#define SERVER_KEY_OPEN_PART_LEN 36 ///< length of partial key used for first server digest signing -/** Key used for RTMP server digest signing */ -static const uint8_t rtmp_server_key[] = { - 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ', - 'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ', - 'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1', - - 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02, - 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8, - 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE -}; - -/** - * Generates 'connect' call and sends it to the server. - */ -static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto, - const char *host, int port) -{ - RTMPPacket pkt; - uint8_t ver[64], *p; - char tcurl[512]; - - ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096); - p = pkt.data; - - ff_url_join(tcurl, sizeof(tcurl), proto, NULL, host, port, "/%s", rt->app); - ff_amf_write_string(&p, "connect"); - ff_amf_write_number(&p, 1.0); - ff_amf_write_object_start(&p); - ff_amf_write_field_name(&p, "app"); - ff_amf_write_string(&p, rt->app); - - if (rt->is_input) { - snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, - RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4); - } else { - snprintf(ver, sizeof(ver), "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT); - ff_amf_write_field_name(&p, "type"); - ff_amf_write_string(&p, "nonprivate"); - } - ff_amf_write_field_name(&p, "flashVer"); - ff_amf_write_string(&p, ver); - ff_amf_write_field_name(&p, "tcUrl"); - ff_amf_write_string(&p, tcurl); - if (rt->is_input) { - ff_amf_write_field_name(&p, "fpad"); - ff_amf_write_bool(&p, 0); - ff_amf_write_field_name(&p, "capabilities"); - ff_amf_write_number(&p, 15.0); - ff_amf_write_field_name(&p, "audioCodecs"); - ff_amf_write_number(&p, 1639.0); - ff_amf_write_field_name(&p, "videoCodecs"); - ff_amf_write_number(&p, 252.0); - ff_amf_write_field_name(&p, "videoFunction"); - ff_amf_write_number(&p, 1.0); - } - ff_amf_write_object_end(&p); - - pkt.data_size = p - pkt.data; - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates 'releaseStream' call and sends it to the server. It should make - * the server release some channel for media streams. - */ -static void gen_release_stream(URLContext *s, RTMPContext *rt) -{ - RTMPPacket pkt; - uint8_t *p; - - ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, - 29 + strlen(rt->playpath)); - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Releasing stream...\n"); - p = pkt.data; - ff_amf_write_string(&p, "releaseStream"); - ff_amf_write_number(&p, 2.0); - ff_amf_write_null(&p); - ff_amf_write_string(&p, rt->playpath); - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates 'FCPublish' call and sends it to the server. It should make - * the server preapare for receiving media streams. - */ -static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt) -{ - RTMPPacket pkt; - uint8_t *p; - - ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, - 25 + strlen(rt->playpath)); - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "FCPublish stream...\n"); - p = pkt.data; - ff_amf_write_string(&p, "FCPublish"); - ff_amf_write_number(&p, 3.0); - ff_amf_write_null(&p); - ff_amf_write_string(&p, rt->playpath); - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates 'FCUnpublish' call and sends it to the server. It should make - * the server destroy stream. - */ -static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt) -{ - RTMPPacket pkt; - uint8_t *p; - - ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, - 27 + strlen(rt->playpath)); - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "UnPublishing stream...\n"); - p = pkt.data; - ff_amf_write_string(&p, "FCUnpublish"); - ff_amf_write_number(&p, 5.0); - ff_amf_write_null(&p); - ff_amf_write_string(&p, rt->playpath); - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates 'createStream' call and sends it to the server. It should make - * the server allocate some channel for media streams. - */ -static void gen_create_stream(URLContext *s, RTMPContext *rt) -{ - RTMPPacket pkt; - uint8_t *p; - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Creating stream...\n"); - ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 25); - - p = pkt.data; - ff_amf_write_string(&p, "createStream"); - ff_amf_write_number(&p, rt->is_input ? 3.0 : 4.0); - ff_amf_write_null(&p); - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - - -/** - * Generates 'deleteStream' call and sends it to the server. It should make - * the server remove some channel for media streams. - */ -static void gen_delete_stream(URLContext *s, RTMPContext *rt) -{ - RTMPPacket pkt; - uint8_t *p; - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Deleting stream...\n"); - ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 34); - - p = pkt.data; - ff_amf_write_string(&p, "deleteStream"); - ff_amf_write_number(&p, 0.0); - ff_amf_write_null(&p); - ff_amf_write_number(&p, rt->main_channel_id); - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates 'play' call and sends it to the server, then pings the server - * to start actual playing. - */ -static void gen_play(URLContext *s, RTMPContext *rt) -{ - RTMPPacket pkt; - uint8_t *p; - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath); - ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0, - 20 + strlen(rt->playpath)); - pkt.extra = rt->main_channel_id; - - p = pkt.data; - ff_amf_write_string(&p, "play"); - ff_amf_write_number(&p, 0.0); - ff_amf_write_null(&p); - ff_amf_write_string(&p, rt->playpath); - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); - - // set client buffer time disguised in ping packet - ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, 1, 10); - - p = pkt.data; - bytestream_put_be16(&p, 3); - bytestream_put_be32(&p, 1); - bytestream_put_be32(&p, 256); //TODO: what is a good value here? - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates 'publish' call and sends it to the server. - */ -static void gen_publish(URLContext *s, RTMPContext *rt) -{ - RTMPPacket pkt; - uint8_t *p; - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath); - ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE, 0, - 30 + strlen(rt->playpath)); - pkt.extra = rt->main_channel_id; - - p = pkt.data; - ff_amf_write_string(&p, "publish"); - ff_amf_write_number(&p, 0.0); - ff_amf_write_null(&p); - ff_amf_write_string(&p, rt->playpath); - ff_amf_write_string(&p, "live"); - - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates ping reply and sends it to the server. - */ -static void gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt) -{ - RTMPPacket pkt; - uint8_t *p; - - ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, ppkt->timestamp + 1, 6); - p = pkt.data; - bytestream_put_be16(&p, 7); - bytestream_put_be32(&p, AV_RB32(ppkt->data+2)); - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -/** - * Generates report on bytes read so far and sends it to the server. - */ -static void gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts) -{ - RTMPPacket pkt; - uint8_t *p; - - ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ, ts, 4); - p = pkt.data; - bytestream_put_be32(&p, rt->bytes_read); - ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); -} - -//TODO: Move HMAC code somewhere. Eventually. -#define HMAC_IPAD_VAL 0x36 -#define HMAC_OPAD_VAL 0x5C - -/** - * Calculates HMAC-SHA2 digest for RTMP handshake packets. - * - * @param src input buffer - * @param len input buffer length (should be 1536) - * @param gap offset in buffer where 32 bytes should not be taken into account - * when calculating digest (since it will be used to store that digest) - * @param key digest key - * @param keylen digest key length - * @param dst buffer where calculated digest will be stored (32 bytes) - */ -static void rtmp_calc_digest(const uint8_t *src, int len, int gap, - const uint8_t *key, int keylen, uint8_t *dst) -{ - struct AVSHA *sha; - uint8_t hmac_buf[64+32] = {0}; - int i; - - sha = av_mallocz(av_sha_size); - - if (keylen < 64) { - memcpy(hmac_buf, key, keylen); - } else { - av_sha_init(sha, 256); - av_sha_update(sha,key, keylen); - av_sha_final(sha, hmac_buf); - } - for (i = 0; i < 64; i++) - hmac_buf[i] ^= HMAC_IPAD_VAL; - - av_sha_init(sha, 256); - av_sha_update(sha, hmac_buf, 64); - if (gap <= 0) { - av_sha_update(sha, src, len); - } else { //skip 32 bytes used for storing digest - av_sha_update(sha, src, gap); - av_sha_update(sha, src + gap + 32, len - gap - 32); - } - av_sha_final(sha, hmac_buf + 64); - - for (i = 0; i < 64; i++) - hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad - av_sha_init(sha, 256); - av_sha_update(sha, hmac_buf, 64+32); - av_sha_final(sha, dst); - - av_free(sha); -} - -/** - * Puts HMAC-SHA2 digest of packet data (except for the bytes where this digest - * will be stored) into that packet. - * - * @param buf handshake data (1536 bytes) - * @return offset to the digest inside input data - */ -static int rtmp_handshake_imprint_with_digest(uint8_t *buf) -{ - int i, digest_pos = 0; - - for (i = 8; i < 12; i++) - digest_pos += buf[i]; - digest_pos = (digest_pos % 728) + 12; - - rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos, - rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN, - buf + digest_pos); - return digest_pos; -} - -/** - * Verifies that the received server response has the expected digest value. - * - * @param buf handshake data received from the server (1536 bytes) - * @param off position to search digest offset from - * @return 0 if digest is valid, digest position otherwise - */ -static int rtmp_validate_digest(uint8_t *buf, int off) -{ - int i, digest_pos = 0; - uint8_t digest[32]; - - for (i = 0; i < 4; i++) - digest_pos += buf[i + off]; - digest_pos = (digest_pos % 728) + off + 4; - - rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos, - rtmp_server_key, SERVER_KEY_OPEN_PART_LEN, - digest); - if (!memcmp(digest, buf + digest_pos, 32)) - return digest_pos; - return 0; -} - -/** - * Performs handshake with the server by means of exchanging pseudorandom data - * signed with HMAC-SHA2 digest. - * - * @return 0 if handshake succeeds, negative value otherwise - */ -static int rtmp_handshake(URLContext *s, RTMPContext *rt) -{ - AVLFG rnd; - uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = { - 3, // unencrypted data - 0, 0, 0, 0, // client uptime - RTMP_CLIENT_VER1, - RTMP_CLIENT_VER2, - RTMP_CLIENT_VER3, - RTMP_CLIENT_VER4, - }; - uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE]; - uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1]; - int i; - int server_pos, client_pos; - uint8_t digest[32]; - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Handshaking...\n"); - - av_lfg_init(&rnd, 0xDEADC0DE); - // generate handshake packet - 1536 bytes of pseudorandom data - for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++) - tosend[i] = av_lfg_get(&rnd) >> 24; - client_pos = rtmp_handshake_imprint_with_digest(tosend + 1); - - url_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE + 1); - i = url_read_complete(rt->stream, serverdata, RTMP_HANDSHAKE_PACKET_SIZE + 1); - if (i != RTMP_HANDSHAKE_PACKET_SIZE + 1) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); - return -1; - } - i = url_read_complete(rt->stream, clientdata, RTMP_HANDSHAKE_PACKET_SIZE); - if (i != RTMP_HANDSHAKE_PACKET_SIZE) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot read RTMP handshake response\n"); - return -1; - } - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n", - serverdata[5], serverdata[6], serverdata[7], serverdata[8]); - - if (rt->is_input && serverdata[5] >= 3) { - server_pos = rtmp_validate_digest(serverdata + 1, 772); - if (!server_pos) { - server_pos = rtmp_validate_digest(serverdata + 1, 8); - if (!server_pos) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server response validating failed\n"); - return -1; - } - } - - rtmp_calc_digest(tosend + 1 + client_pos, 32, 0, - rtmp_server_key, sizeof(rtmp_server_key), - digest); - rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE-32, 0, - digest, 32, - digest); - if (memcmp(digest, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Signature mismatch\n"); - return -1; - } - - for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++) - tosend[i] = av_lfg_get(&rnd) >> 24; - rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0, - rtmp_player_key, sizeof(rtmp_player_key), - digest); - rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0, - digest, 32, - tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32); - - // write reply back to the server - url_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE); - } else { - url_write(rt->stream, serverdata+1, RTMP_HANDSHAKE_PACKET_SIZE); - } - - return 0; -} - -/** - * Parses received packet and may perform some action depending on - * the packet contents. - * @return 0 for no errors, negative values for serious errors which prevent - * further communications, positive values for uncritical errors - */ -static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) -{ - int i, t; - const uint8_t *data_end = pkt->data + pkt->data_size; - -#ifdef DEBUG - ff_rtmp_packet_dump(LOG_CONTEXT, pkt); -#endif - - switch (pkt->type) { - case RTMP_PT_CHUNK_SIZE: - if (pkt->data_size != 4) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, - "Chunk size change packet is not 4 bytes long (%d)\n", pkt->data_size); - return -1; - } - if (!rt->is_input) - ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size, rt->prev_pkt[1]); - rt->chunk_size = AV_RB32(pkt->data); - if (rt->chunk_size <= 0) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size); - return -1; - } - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_size); - break; - case RTMP_PT_PING: - t = AV_RB16(pkt->data); - if (t == 6) - gen_pong(s, rt, pkt); - break; - case RTMP_PT_CLIENT_BW: - if (pkt->data_size < 4) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, - "Client bandwidth report packet is less than 4 bytes long (%d)\n", - pkt->data_size); - return -1; - } - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data)); - rt->client_report_size = AV_RB32(pkt->data) >> 1; - break; - case RTMP_PT_INVOKE: - //TODO: check for the messages sent for wrong state? - if (!memcmp(pkt->data, "\002\000\006_error", 9)) { - uint8_t tmpstr[256]; - - if (!ff_amf_get_field_value(pkt->data + 9, data_end, - "description", tmpstr, sizeof(tmpstr))) - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr); - return -1; - } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) { - switch (rt->state) { - case STATE_HANDSHAKED: - if (!rt->is_input) { - gen_release_stream(s, rt); - gen_fcpublish_stream(s, rt); - rt->state = STATE_RELEASING; - } else { - rt->state = STATE_CONNECTING; - } - gen_create_stream(s, rt); - break; - case STATE_FCPUBLISH: - rt->state = STATE_CONNECTING; - break; - case STATE_RELEASING: - rt->state = STATE_FCPUBLISH; - /* hack for Wowza Media Server, it does not send result for - * releaseStream and FCPublish calls */ - if (!pkt->data[10]) { - int pkt_id = (int) av_int2dbl(AV_RB64(pkt->data + 11)); - if (pkt_id == 4) - rt->state = STATE_CONNECTING; - } - if (rt->state != STATE_CONNECTING) - break; - case STATE_CONNECTING: - //extract a number from the result - if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) { - av_log(LOG_CONTEXT, AV_LOG_WARNING, "Unexpected reply on connect()\n"); - } else { - rt->main_channel_id = (int) av_int2dbl(AV_RB64(pkt->data + 21)); - } - if (rt->is_input) { - gen_play(s, rt); - } else { - gen_publish(s, rt); - } - rt->state = STATE_READY; - break; - } - } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) { - const uint8_t* ptr = pkt->data + 11; - uint8_t tmpstr[256]; - - for (i = 0; i < 2; i++) { - t = ff_amf_tag_size(ptr, data_end); - if (t < 0) - return 1; - ptr += t; - } - t = ff_amf_get_field_value(ptr, data_end, - "level", tmpstr, sizeof(tmpstr)); - if (!t && !strcmp(tmpstr, "error")) { - if (!ff_amf_get_field_value(ptr, data_end, - "description", tmpstr, sizeof(tmpstr))) - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Server error: %s\n",tmpstr); - return -1; - } - t = ff_amf_get_field_value(ptr, data_end, - "code", tmpstr, sizeof(tmpstr)); - if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING; - if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED; - if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED; - if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING; - } - break; - } - return 0; -} - -/** - * Interacts with the server by receiving and sending RTMP packets until - * there is some significant data (media data or expected status notification). - * - * @param s reading context - * @param for_header non-zero value tells function to work until it - * gets notification from the server that playing has been started, - * otherwise function will work until some media data is received (or - * an error happens) - * @return 0 for successful operation, negative value in case of error - */ -static int get_packet(URLContext *s, int for_header) -{ - RTMPContext *rt = s->priv_data; - int ret; - uint8_t *p; - const uint8_t *next; - uint32_t data_size; - uint32_t ts, cts, pts=0; - - if (rt->state == STATE_STOPPED) - return AVERROR_EOF; - - for (;;) { - RTMPPacket rpkt; - if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt, - rt->chunk_size, rt->prev_pkt[0])) <= 0) { - if (ret == 0) { - return AVERROR(EAGAIN); - } else { - return AVERROR(EIO); - } - } - rt->bytes_read += ret; - if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) { - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Sending bytes read report\n"); - gen_bytes_read(s, rt, rpkt.timestamp + 1); - rt->last_bytes_read = rt->bytes_read; - } - - ret = rtmp_parse_result(s, rt, &rpkt); - if (ret < 0) {//serious error in current packet - ff_rtmp_packet_destroy(&rpkt); - return -1; - } - if (rt->state == STATE_STOPPED) { - ff_rtmp_packet_destroy(&rpkt); - return AVERROR_EOF; - } - if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) { - ff_rtmp_packet_destroy(&rpkt); - return 0; - } - if (!rpkt.data_size || !rt->is_input) { - ff_rtmp_packet_destroy(&rpkt); - continue; - } - if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO || - (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) { - ts = rpkt.timestamp; - - // generate packet header and put data into buffer for FLV demuxer - rt->flv_off = 0; - rt->flv_size = rpkt.data_size + 15; - rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size); - bytestream_put_byte(&p, rpkt.type); - bytestream_put_be24(&p, rpkt.data_size); - bytestream_put_be24(&p, ts); - bytestream_put_byte(&p, ts >> 24); - bytestream_put_be24(&p, 0); - bytestream_put_buffer(&p, rpkt.data, rpkt.data_size); - bytestream_put_be32(&p, 0); - ff_rtmp_packet_destroy(&rpkt); - return 0; - } else if (rpkt.type == RTMP_PT_METADATA) { - // we got raw FLV data, make it available for FLV demuxer - rt->flv_off = 0; - rt->flv_size = rpkt.data_size; - rt->flv_data = av_realloc(rt->flv_data, rt->flv_size); - /* rewrite timestamps */ - next = rpkt.data; - ts = rpkt.timestamp; - while (next - rpkt.data < rpkt.data_size - 11) { - next++; - data_size = bytestream_get_be24(&next); - p=next; - cts = bytestream_get_be24(&next); - cts |= bytestream_get_byte(&next); - if (pts==0) - pts=cts; - ts += cts - pts; - pts = cts; - bytestream_put_be24(&p, ts); - bytestream_put_byte(&p, ts >> 24); - next += data_size + 3 + 4; - } - memcpy(rt->flv_data, rpkt.data, rpkt.data_size); - ff_rtmp_packet_destroy(&rpkt); - return 0; - } - ff_rtmp_packet_destroy(&rpkt); - } - return 0; -} - -static int rtmp_close(URLContext *h) -{ - RTMPContext *rt = h->priv_data; - - if (!rt->is_input) { - rt->flv_data = NULL; - if (rt->out_pkt.data_size) - ff_rtmp_packet_destroy(&rt->out_pkt); - if (rt->state > STATE_FCPUBLISH) - gen_fcunpublish_stream(h, rt); - } - if (rt->state > STATE_HANDSHAKED) - gen_delete_stream(h, rt); - - av_freep(&rt->flv_data); - url_close(rt->stream); - av_free(rt); - return 0; -} - -/** - * Opens RTMP connection and verifies that the stream can be played. - * - * URL syntax: rtmp://server[:port][/app][/playpath] - * where 'app' is first one or two directories in the path - * (e.g. /ondemand/, /flash/live/, etc.) - * and 'playpath' is a file name (the rest of the path, - * may be prefixed with "mp4:") - */ -static int rtmp_open(URLContext *s, const char *uri, int flags) -{ - RTMPContext *rt; - char proto[8], hostname[256], path[1024], *fname; - uint8_t buf[2048]; - int port; - int ret; - - rt = av_mallocz(sizeof(RTMPContext)); - if (!rt) - return AVERROR(ENOMEM); - s->priv_data = rt; - rt->is_input = !(flags & URL_WRONLY); - - ff_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, - path, sizeof(path), s->filename); - - if (port < 0) - port = RTMP_DEFAULT_PORT; - ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); - - if (url_open(&rt->stream, buf, URL_RDWR) < 0) { - av_log(LOG_CONTEXT, AV_LOG_ERROR, "Cannot open connection %s\n", buf); - goto fail; - } - - rt->state = STATE_START; - if (rtmp_handshake(s, rt)) - return -1; - - rt->chunk_size = 128; - rt->state = STATE_HANDSHAKED; - //extract "app" part from path - if (!strncmp(path, "/ondemand/", 10)) { - fname = path + 10; - memcpy(rt->app, "ondemand", 9); - } else { - char *p = strchr(path + 1, '/'); - if (!p) { - fname = path + 1; - rt->app[0] = '\0'; - } else { - char *c = strchr(p + 1, ':'); - fname = strchr(p + 1, '/'); - if (!fname || c < fname) { - fname = p + 1; - av_strlcpy(rt->app, path + 1, p - path); - } else { - fname++; - av_strlcpy(rt->app, path + 1, fname - path - 1); - } - } - } - if (!strchr(fname, ':') && - (!strcmp(fname + strlen(fname) - 4, ".f4v") || - !strcmp(fname + strlen(fname) - 4, ".mp4"))) { - memcpy(rt->playpath, "mp4:", 5); - } else { - rt->playpath[0] = 0; - } - strncat(rt->playpath, fname, sizeof(rt->playpath) - 5); - - rt->client_report_size = 1048576; - rt->bytes_read = 0; - rt->last_bytes_read = 0; - - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", - proto, path, rt->app, rt->playpath); - gen_connect(s, rt, proto, hostname, port); - - do { - ret = get_packet(s, 1); - } while (ret == EAGAIN); - if (ret < 0) - goto fail; - - if (rt->is_input) { - // generate FLV header for demuxer - rt->flv_size = 13; - rt->flv_data = av_realloc(rt->flv_data, rt->flv_size); - rt->flv_off = 0; - memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size); - } else { - rt->flv_size = 0; - rt->flv_data = NULL; - rt->flv_off = 0; - } - - s->max_packet_size = url_get_max_packet_size(rt->stream); - s->is_streamed = 1; - return 0; - -fail: - rtmp_close(s); - return AVERROR(EIO); -} - -static int rtmp_read(URLContext *s, uint8_t *buf, int size) -{ - RTMPContext *rt = s->priv_data; - int orig_size = size; - int ret; - - while (size > 0) { - int data_left = rt->flv_size - rt->flv_off; - - if (data_left >= size) { - memcpy(buf, rt->flv_data + rt->flv_off, size); - rt->flv_off += size; - return orig_size; - } - if (data_left > 0) { - memcpy(buf, rt->flv_data + rt->flv_off, data_left); - buf += data_left; - size -= data_left; - rt->flv_off = rt->flv_size; - } - if ((ret = get_packet(s, 0)) < 0) - return ret; - } - return orig_size; -} - -static int rtmp_write(URLContext *h, uint8_t *buf, int size) -{ - RTMPContext *rt = h->priv_data; - int size_temp = size; - int pktsize, pkttype; - uint32_t ts; - const uint8_t *buf_temp = buf; - - if (size < 11) { - av_log(LOG_CONTEXT, AV_LOG_DEBUG, "FLV packet too small %d\n", size); - return 0; - } - - do { - if (!rt->flv_off) { - //skip flv header - if (buf_temp[0] == 'F' && buf_temp[1] == 'L' && buf_temp[2] == 'V') { - buf_temp += 9 + 4; - size_temp -= 9 + 4; - } - - pkttype = bytestream_get_byte(&buf_temp); - pktsize = bytestream_get_be24(&buf_temp); - ts = bytestream_get_be24(&buf_temp); - ts |= bytestream_get_byte(&buf_temp) << 24; - bytestream_get_be24(&buf_temp); - size_temp -= 11; - rt->flv_size = pktsize; - - //force 12bytes header - if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) || - pkttype == RTMP_PT_NOTIFY) { - if (pkttype == RTMP_PT_NOTIFY) - pktsize += 16; - rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0; - } - - //this can be a big packet, it's better to send it right here - ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL, pkttype, ts, pktsize); - rt->out_pkt.extra = rt->main_channel_id; - rt->flv_data = rt->out_pkt.data; - - if (pkttype == RTMP_PT_NOTIFY) - ff_amf_write_string(&rt->flv_data, "@setDataFrame"); - } - - if (rt->flv_size - rt->flv_off > size_temp) { - bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp); - rt->flv_off += size_temp; - } else { - bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off); - rt->flv_off += rt->flv_size - rt->flv_off; - } - - if (rt->flv_off == rt->flv_size) { - bytestream_get_be32(&buf_temp); - - ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&rt->out_pkt); - rt->flv_size = 0; - rt->flv_off = 0; - } - } while (buf_temp - buf < size_temp); - return size; -} - -URLProtocol rtmp_protocol = { - "rtmp", - rtmp_open, - rtmp_read, - rtmp_write, - NULL, /* seek */ - rtmp_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rtp.c b/tizen/distrib/ffmpeg/libavformat/rtp.c deleted file mode 100644 index a8dcfd7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtp.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * RTP input/output format - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" - -#include "rtp.h" - -//#define DEBUG - -/* from http://www.iana.org/assignments/rtp-parameters last updated 05 January 2005 */ -/* payload types >= 96 are dynamic; - * payload types between 72 and 76 are reserved for RTCP conflict avoidance; - * all the other payload types not present in the table are unassigned or - * reserved - */ -static const struct -{ - int pt; - const char enc_name[6]; - enum AVMediaType codec_type; - enum CodecID codec_id; - int clock_rate; - int audio_channels; -} AVRtpPayloadTypes[]= -{ - {0, "PCMU", AVMEDIA_TYPE_AUDIO, CODEC_ID_PCM_MULAW, 8000, 1}, - {3, "GSM", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {4, "G723", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {5, "DVI4", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {6, "DVI4", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 16000, 1}, - {7, "LPC", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {8, "PCMA", AVMEDIA_TYPE_AUDIO, CODEC_ID_PCM_ALAW, 8000, 1}, - {9, "G722", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {10, "L16", AVMEDIA_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 2}, - {11, "L16", AVMEDIA_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 1}, - {12, "QCELP", AVMEDIA_TYPE_AUDIO, CODEC_ID_QCELP, 8000, 1}, - {13, "CN", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {14, "MPA", AVMEDIA_TYPE_AUDIO, CODEC_ID_MP2, -1, -1}, - {14, "MPA", AVMEDIA_TYPE_AUDIO, CODEC_ID_MP3, -1, -1}, - {15, "G728", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {16, "DVI4", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 11025, 1}, - {17, "DVI4", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 22050, 1}, - {18, "G729", AVMEDIA_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1}, - {25, "CelB", AVMEDIA_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1}, - {26, "JPEG", AVMEDIA_TYPE_VIDEO, CODEC_ID_MJPEG, 90000, -1}, - {28, "nv", AVMEDIA_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1}, - {31, "H261", AVMEDIA_TYPE_VIDEO, CODEC_ID_H261, 90000, -1}, - {32, "MPV", AVMEDIA_TYPE_VIDEO, CODEC_ID_MPEG1VIDEO, 90000, -1}, - {32, "MPV", AVMEDIA_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO, 90000, -1}, - {33, "MP2T", AVMEDIA_TYPE_DATA, CODEC_ID_MPEG2TS, 90000, -1}, - {34, "H263", AVMEDIA_TYPE_VIDEO, CODEC_ID_H263, 90000, -1}, - {-1, "", AVMEDIA_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1} -}; - -int ff_rtp_get_codec_info(AVCodecContext *codec, int payload_type) -{ - int i = 0; - - for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++) - if (AVRtpPayloadTypes[i].pt == payload_type) { - if (AVRtpPayloadTypes[i].codec_id != CODEC_ID_NONE) { - codec->codec_type = AVRtpPayloadTypes[i].codec_type; - codec->codec_id = AVRtpPayloadTypes[i].codec_id; - if (AVRtpPayloadTypes[i].audio_channels > 0) - codec->channels = AVRtpPayloadTypes[i].audio_channels; - if (AVRtpPayloadTypes[i].clock_rate > 0) - codec->sample_rate = AVRtpPayloadTypes[i].clock_rate; - return 0; - } - } - return -1; -} - -int ff_rtp_get_payload_type(AVCodecContext *codec) -{ - int i, payload_type; - - /* compute the payload type */ - for (payload_type = -1, i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i) - if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) { - if (codec->codec_id == CODEC_ID_H263) - continue; - if (codec->codec_id == CODEC_ID_PCM_S16BE) - if (codec->channels != AVRtpPayloadTypes[i].audio_channels) - continue; - payload_type = AVRtpPayloadTypes[i].pt; - } - return payload_type; -} - -const char *ff_rtp_enc_name(int payload_type) -{ - int i; - - for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++) - if (AVRtpPayloadTypes[i].pt == payload_type) { - return AVRtpPayloadTypes[i].enc_name; - } - - return ""; -} - -enum CodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type) -{ - int i; - - for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++) - if (!strcmp(buf, AVRtpPayloadTypes[i].enc_name) && (codec_type == AVRtpPayloadTypes[i].codec_type)){ - return AVRtpPayloadTypes[i].codec_id; - } - - return CODEC_ID_NONE; -} diff --git a/tizen/distrib/ffmpeg/libavformat/rtp.h b/tizen/distrib/ffmpeg/libavformat/rtp.h deleted file mode 100644 index 7834f9d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtp.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * RTP definitions - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVFORMAT_RTP_H -#define AVFORMAT_RTP_H - -#include "libavcodec/avcodec.h" - -/** - * Return the payload type for a given codec. - * - * @param codec The context of the codec - * @return In case of unknown payload type or dynamic payload type, a - * negative value is returned; otherwise, the payload type (the 'PT' field - * in the RTP header) is returned. - */ -int ff_rtp_get_payload_type(AVCodecContext *codec); - -/** - * Initialize a codec context based on the payload type. - * - * Fill the codec_type and codec_id fields of a codec context with - * information depending on the payload type; for audio codecs, the - * channels and sample_rate fields are also filled. - * - * @param codec The context of the codec - * @param payload_type The payload type (the 'PT' field in the RTP header) - * @return In case of unknown payload type or dynamic payload type, a - * negative value is returned; otherwise, 0 is returned - */ -int ff_rtp_get_codec_info(AVCodecContext *codec, int payload_type); - -/** - * Return the encoding name (as defined in - * http://www.iana.org/assignments/rtp-parameters) for a given payload type. - * - * @param payload_type The payload type (the 'PT' field in the RTP header) - * @return In case of unknown payload type or dynamic payload type, a pointer - * to an empty string is returned; otherwise, a pointer to a string containing - * the encoding name is returned - */ -const char *ff_rtp_enc_name(int payload_type); - -/** - * Return the codec id for the given encoding name and codec type. - * - * @param buf A pointer to the string containing the encoding name - * @param codec_type The codec type - * @return In case of unknown encoding name, CODEC_ID_NONE is returned; - * otherwise, the codec id is returned - */ -enum CodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type); - -#define RTP_PT_PRIVATE 96 -#define RTP_VERSION 2 -#define RTP_MAX_SDES 256 /**< maximum text length for SDES */ - -/* RTCP paquets use 0.5 % of the bandwidth */ -#define RTCP_TX_RATIO_NUM 5 -#define RTCP_TX_RATIO_DEN 1000 - -#endif /* AVFORMAT_RTP_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec.c b/tizen/distrib/ffmpeg/libavformat/rtpdec.c deleted file mode 100644 index 0d2df59..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * RTP input format - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* needed for gethostname() */ -#define _XOPEN_SOURCE 600 - -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "mpegts.h" - -#include -#include "network.h" - -#include "rtpdec.h" -#include "rtpdec_amr.h" -#include "rtpdec_asf.h" -#include "rtpdec_h263.h" -#include "rtpdec_h264.h" -#include "rtpdec_xiph.h" - -//#define DEBUG - -/* TODO: - add RTCP statistics reporting (should be optional). - - - add support for h263/mpeg4 packetized output : IDEA: send a - buffer to 'rtp_write_packet' contains all the packets for ONE - frame. Each packet should have a four byte header containing - the length in big endian format (same trick as - 'url_open_dyn_packet_buf') -*/ - -/* statistics functions */ -RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL; - -static RTPDynamicProtocolHandler mp4v_es_handler= {"MP4V-ES", AVMEDIA_TYPE_VIDEO, CODEC_ID_MPEG4}; -static RTPDynamicProtocolHandler mpeg4_generic_handler= {"mpeg4-generic", AVMEDIA_TYPE_AUDIO, CODEC_ID_AAC}; - -void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler) -{ - handler->next= RTPFirstDynamicPayloadHandler; - RTPFirstDynamicPayloadHandler= handler; -} - -void av_register_rtp_dynamic_payload_handlers(void) -{ - ff_register_dynamic_payload_handler(&mp4v_es_handler); - ff_register_dynamic_payload_handler(&mpeg4_generic_handler); - ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler); - ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler); - ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler); - ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler); - ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler); - ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler); - ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler); - - ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler); - ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler); -} - -static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len) -{ - if (buf[1] != 200) - return -1; - s->last_rtcp_ntp_time = AV_RB64(buf + 8); - if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) - s->first_rtcp_ntp_time = s->last_rtcp_ntp_time; - s->last_rtcp_timestamp = AV_RB32(buf + 16); - return 0; -} - -#define RTP_SEQ_MOD (1<<16) - -/** -* called on parse open packet -*/ -static void rtp_init_statistics(RTPStatistics *s, uint16_t base_sequence) // called on parse open packet. -{ - memset(s, 0, sizeof(RTPStatistics)); - s->max_seq= base_sequence; - s->probation= 1; -} - -/** -* called whenever there is a large jump in sequence numbers, or when they get out of probation... -*/ -static void rtp_init_sequence(RTPStatistics *s, uint16_t seq) -{ - s->max_seq= seq; - s->cycles= 0; - s->base_seq= seq -1; - s->bad_seq= RTP_SEQ_MOD + 1; - s->received= 0; - s->expected_prior= 0; - s->received_prior= 0; - s->jitter= 0; - s->transit= 0; -} - -/** -* returns 1 if we should handle this packet. -*/ -static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq) -{ - uint16_t udelta= seq - s->max_seq; - const int MAX_DROPOUT= 3000; - const int MAX_MISORDER = 100; - const int MIN_SEQUENTIAL = 2; - - /* source not valid until MIN_SEQUENTIAL packets with sequence seq. numbers have been received */ - if(s->probation) - { - if(seq==s->max_seq + 1) { - s->probation--; - s->max_seq= seq; - if(s->probation==0) { - rtp_init_sequence(s, seq); - s->received++; - return 1; - } - } else { - s->probation= MIN_SEQUENTIAL - 1; - s->max_seq = seq; - } - } else if (udelta < MAX_DROPOUT) { - // in order, with permissible gap - if(seq < s->max_seq) { - //sequence number wrapped; count antother 64k cycles - s->cycles += RTP_SEQ_MOD; - } - s->max_seq= seq; - } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) { - // sequence made a large jump... - if(seq==s->bad_seq) { - // two sequential packets-- assume that the other side restarted without telling us; just resync. - rtp_init_sequence(s, seq); - } else { - s->bad_seq= (seq + 1) & (RTP_SEQ_MOD-1); - return 0; - } - } else { - // duplicate or reordered packet... - } - s->received++; - return 1; -} - -#if 0 -/** -* This function is currently unused; without a valid local ntp time, I don't see how we could calculate the -* difference between the arrival and sent timestamp. As a result, the jitter and transit statistics values -* never change. I left this in in case someone else can see a way. (rdm) -*/ -static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp, uint32_t arrival_timestamp) -{ - uint32_t transit= arrival_timestamp - sent_timestamp; - int d; - s->transit= transit; - d= FFABS(transit - s->transit); - s->jitter += d - ((s->jitter + 8)>>4); -} -#endif - -int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) -{ - ByteIOContext *pb; - uint8_t *buf; - int len; - int rtcp_bytes; - RTPStatistics *stats= &s->statistics; - uint32_t lost; - uint32_t extended_max; - uint32_t expected_interval; - uint32_t received_interval; - uint32_t lost_interval; - uint32_t expected; - uint32_t fraction; - uint64_t ntp_time= s->last_rtcp_ntp_time; // TODO: Get local ntp time? - - if (!s->rtp_ctx || (count < 1)) - return -1; - - /* TODO: I think this is way too often; RFC 1889 has algorithm for this */ - /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */ - s->octet_count += count; - rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / - RTCP_TX_RATIO_DEN; - rtcp_bytes /= 50; // mmu_man: that's enough for me... VLC sends much less btw !? - if (rtcp_bytes < 28) - return -1; - s->last_octet_count = s->octet_count; - - if (url_open_dyn_buf(&pb) < 0) - return -1; - - // Receiver Report - put_byte(pb, (RTP_VERSION << 6) + 1); /* 1 report block */ - put_byte(pb, 201); - put_be16(pb, 7); /* length in words - 1 */ - put_be32(pb, s->ssrc); // our own SSRC - put_be32(pb, s->ssrc); // XXX: should be the server's here! - // some placeholders we should really fill... - // RFC 1889/p64 - extended_max= stats->cycles + stats->max_seq; - expected= extended_max - stats->base_seq + 1; - lost= expected - stats->received; - lost= FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits... - expected_interval= expected - stats->expected_prior; - stats->expected_prior= expected; - received_interval= stats->received - stats->received_prior; - stats->received_prior= stats->received; - lost_interval= expected_interval - received_interval; - if (expected_interval==0 || lost_interval<=0) fraction= 0; - else fraction = (lost_interval<<8)/expected_interval; - - fraction= (fraction<<24) | lost; - - put_be32(pb, fraction); /* 8 bits of fraction, 24 bits of total packets lost */ - put_be32(pb, extended_max); /* max sequence received */ - put_be32(pb, stats->jitter>>4); /* jitter */ - - if(s->last_rtcp_ntp_time==AV_NOPTS_VALUE) - { - put_be32(pb, 0); /* last SR timestamp */ - put_be32(pb, 0); /* delay since last SR */ - } else { - uint32_t middle_32_bits= s->last_rtcp_ntp_time>>16; // this is valid, right? do we need to handle 64 bit values special? - uint32_t delay_since_last= ntp_time - s->last_rtcp_ntp_time; - - put_be32(pb, middle_32_bits); /* last SR timestamp */ - put_be32(pb, delay_since_last); /* delay since last SR */ - } - - // CNAME - put_byte(pb, (RTP_VERSION << 6) + 1); /* 1 report block */ - put_byte(pb, 202); - len = strlen(s->hostname); - put_be16(pb, (6 + len + 3) / 4); /* length in words - 1 */ - put_be32(pb, s->ssrc); - put_byte(pb, 0x01); - put_byte(pb, len); - put_buffer(pb, s->hostname, len); - // padding - for (len = (6 + len) % 4; len % 4; len++) { - put_byte(pb, 0); - } - - put_flush_packet(pb); - len = url_close_dyn_buf(pb, &buf); - if ((len > 0) && buf) { - int result; - dprintf(s->ic, "sending %d bytes of RR\n", len); - result= url_write(s->rtp_ctx, buf, len); - dprintf(s->ic, "result from url_write: %d\n", result); - av_free(buf); - } - return 0; -} - -void rtp_send_punch_packets(URLContext* rtp_handle) -{ - ByteIOContext *pb; - uint8_t *buf; - int len; - - /* Send a small RTP packet */ - if (url_open_dyn_buf(&pb) < 0) - return; - - put_byte(pb, (RTP_VERSION << 6)); - put_byte(pb, 0); /* Payload type */ - put_be16(pb, 0); /* Seq */ - put_be32(pb, 0); /* Timestamp */ - put_be32(pb, 0); /* SSRC */ - - put_flush_packet(pb); - len = url_close_dyn_buf(pb, &buf); - if ((len > 0) && buf) - url_write(rtp_handle, buf, len); - av_free(buf); - - /* Send a minimal RTCP RR */ - if (url_open_dyn_buf(&pb) < 0) - return; - - put_byte(pb, (RTP_VERSION << 6)); - put_byte(pb, 201); /* receiver report */ - put_be16(pb, 1); /* length in words - 1 */ - put_be32(pb, 0); /* our own SSRC */ - - put_flush_packet(pb); - len = url_close_dyn_buf(pb, &buf); - if ((len > 0) && buf) - url_write(rtp_handle, buf, len); - av_free(buf); -} - - -/** - * open a new RTP parse context for stream 'st'. 'st' can be NULL for - * MPEG2TS streams to indicate that they should be demuxed inside the - * rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned) - * TODO: change this to not take rtp_payload data, and use the new dynamic payload system. - */ -RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, RTPPayloadData *rtp_payload_data) -{ - RTPDemuxContext *s; - - s = av_mallocz(sizeof(RTPDemuxContext)); - if (!s) - return NULL; - s->payload_type = payload_type; - s->last_rtcp_ntp_time = AV_NOPTS_VALUE; - s->first_rtcp_ntp_time = AV_NOPTS_VALUE; - s->ic = s1; - s->st = st; - s->rtp_payload_data = rtp_payload_data; - rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp? - if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) { - s->ts = ff_mpegts_parse_open(s->ic); - if (s->ts == NULL) { - av_free(s); - return NULL; - } - } else { - av_set_pts_info(st, 32, 1, 90000); - switch(st->codec->codec_id) { - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - case CODEC_ID_MP2: - case CODEC_ID_MP3: - case CODEC_ID_MPEG4: - case CODEC_ID_H263: - case CODEC_ID_H264: - st->need_parsing = AVSTREAM_PARSE_FULL; - break; - default: - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - av_set_pts_info(st, 32, 1, st->codec->sample_rate); - } - break; - } - } - // needed to send back RTCP RR in RTSP sessions - s->rtp_ctx = rtpc; - gethostname(s->hostname, sizeof(s->hostname)); - return s; -} - -void -rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx, - RTPDynamicProtocolHandler *handler) -{ - s->dynamic_protocol_context = ctx; - s->parse_packet = handler->parse_packet; -} - -static int rtp_parse_mp4_au(RTPDemuxContext *s, const uint8_t *buf) -{ - int au_headers_length, au_header_size, i; - GetBitContext getbitcontext; - RTPPayloadData *infos; - - infos = s->rtp_payload_data; - - if (infos == NULL) - return -1; - - /* decode the first 2 bytes where the AUHeader sections are stored - length in bits */ - au_headers_length = AV_RB16(buf); - - if (au_headers_length > RTP_MAX_PACKET_LENGTH) - return -1; - - infos->au_headers_length_bytes = (au_headers_length + 7) / 8; - - /* skip AU headers length section (2 bytes) */ - buf += 2; - - init_get_bits(&getbitcontext, buf, infos->au_headers_length_bytes * 8); - - /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */ - au_header_size = infos->sizelength + infos->indexlength; - if (au_header_size <= 0 || (au_headers_length % au_header_size != 0)) - return -1; - - infos->nb_au_headers = au_headers_length / au_header_size; - if (!infos->au_headers || infos->au_headers_allocated < infos->nb_au_headers) { - av_free(infos->au_headers); - infos->au_headers = av_malloc(sizeof(struct AUHeaders) * infos->nb_au_headers); - infos->au_headers_allocated = infos->nb_au_headers; - } - - /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving) - In my test, the FAAD decoder does not behave correctly when sending each AU one by one - but does when sending the whole as one big packet... */ - infos->au_headers[0].size = 0; - infos->au_headers[0].index = 0; - for (i = 0; i < infos->nb_au_headers; ++i) { - infos->au_headers[0].size += get_bits_long(&getbitcontext, infos->sizelength); - infos->au_headers[0].index = get_bits_long(&getbitcontext, infos->indexlength); - } - - infos->nb_au_headers = 1; - - return 0; -} - -/** - * This was the second switch in rtp_parse packet. Normalizes time, if required, sets stream_index, etc. - */ -static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp) -{ - if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { - int64_t addend; - int delta_timestamp; - - /* compute pts from timestamp with received ntp_time */ - delta_timestamp = timestamp - s->last_rtcp_timestamp; - /* convert to the PTS timebase */ - addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time, s->st->time_base.den, (uint64_t)s->st->time_base.num << 32); - pkt->pts = s->range_start_offset + addend + delta_timestamp; - } -} - -/** - * Parse an RTP or RTCP packet directly sent as a buffer. - * @param s RTP parse context. - * @param pkt returned packet - * @param buf input buffer or NULL to read the next packets - * @param len buffer len - * @return 0 if a packet is returned, 1 if a packet is returned and more can follow - * (use buf as NULL to read the next). -1 if no packet (error or no more packet). - */ -int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, - const uint8_t *buf, int len) -{ - unsigned int ssrc, h; - int payload_type, seq, ret, flags = 0; - AVStream *st; - uint32_t timestamp; - int rv= 0; - - if (!buf) { - /* return the next packets, if any */ - if(s->st && s->parse_packet) { - timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned.... - rv= s->parse_packet(s->ic, s->dynamic_protocol_context, - s->st, pkt, ×tamp, NULL, 0, flags); - finalize_packet(s, pkt, timestamp); - return rv; - } else { - // TODO: Move to a dynamic packet handler (like above) - if (s->read_buf_index >= s->read_buf_size) - return -1; - ret = ff_mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index, - s->read_buf_size - s->read_buf_index); - if (ret < 0) - return -1; - s->read_buf_index += ret; - if (s->read_buf_index < s->read_buf_size) - return 1; - else - return 0; - } - } - - if (len < 12) - return -1; - - if ((buf[0] & 0xc0) != (RTP_VERSION << 6)) - return -1; - if (buf[1] >= 200 && buf[1] <= 204) { - rtcp_parse_packet(s, buf, len); - return -1; - } - payload_type = buf[1] & 0x7f; - if (buf[1] & 0x80) - flags |= RTP_FLAG_MARKER; - seq = AV_RB16(buf + 2); - timestamp = AV_RB32(buf + 4); - ssrc = AV_RB32(buf + 8); - /* store the ssrc in the RTPDemuxContext */ - s->ssrc = ssrc; - - /* NOTE: we can handle only one payload type */ - if (s->payload_type != payload_type) - return -1; - - st = s->st; - // only do something with this if all the rtp checks pass... - if(!rtp_valid_packet_in_sequence(&s->statistics, seq)) - { - av_log(st?st->codec:NULL, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n", - payload_type, seq, ((s->seq + 1) & 0xffff)); - return -1; - } - - s->seq = seq; - len -= 12; - buf += 12; - - if (!st) { - /* specific MPEG2TS demux support */ - ret = ff_mpegts_parse_packet(s->ts, pkt, buf, len); - if (ret < 0) - return -1; - if (ret < len) { - s->read_buf_size = len - ret; - memcpy(s->buf, buf + ret, s->read_buf_size); - s->read_buf_index = 0; - return 1; - } - return 0; - } else if (s->parse_packet) { - rv = s->parse_packet(s->ic, s->dynamic_protocol_context, - s->st, pkt, ×tamp, buf, len, flags); - } else { - // at this point, the RTP header has been stripped; This is ASSUMING that there is only 1 CSRC, which in't wise. - switch(st->codec->codec_id) { - case CODEC_ID_MP2: - case CODEC_ID_MP3: - /* better than nothing: skip mpeg audio RTP header */ - if (len <= 4) - return -1; - h = AV_RB32(buf); - len -= 4; - buf += 4; - av_new_packet(pkt, len); - memcpy(pkt->data, buf, len); - break; - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - /* better than nothing: skip mpeg video RTP header */ - if (len <= 4) - return -1; - h = AV_RB32(buf); - buf += 4; - len -= 4; - if (h & (1 << 26)) { - /* mpeg2 */ - if (len <= 4) - return -1; - buf += 4; - len -= 4; - } - av_new_packet(pkt, len); - memcpy(pkt->data, buf, len); - break; - // moved from below, verbatim. this is because this section handles packets, and the lower switch handles - // timestamps. - // TODO: Put this into a dynamic packet handler... - case CODEC_ID_AAC: - if (rtp_parse_mp4_au(s, buf)) - return -1; - { - RTPPayloadData *infos = s->rtp_payload_data; - if (infos == NULL) - return -1; - buf += infos->au_headers_length_bytes + 2; - len -= infos->au_headers_length_bytes + 2; - - /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define - one au_header */ - av_new_packet(pkt, infos->au_headers[0].size); - memcpy(pkt->data, buf, infos->au_headers[0].size); - buf += infos->au_headers[0].size; - len -= infos->au_headers[0].size; - } - s->read_buf_size = len; - rv= 0; - break; - default: - av_new_packet(pkt, len); - memcpy(pkt->data, buf, len); - break; - } - - pkt->stream_index = st->index; - } - - // now perform timestamp things.... - finalize_packet(s, pkt, timestamp); - - return rv; -} - -void rtp_parse_close(RTPDemuxContext *s) -{ - // TODO: fold this into the protocol specific data fields. - av_free(s->rtp_payload_data->mode); - av_free(s->rtp_payload_data->au_headers); - if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) { - ff_mpegts_parse_close(s->ts); - } - av_free(s); -} diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec.h b/tizen/distrib/ffmpeg/libavformat/rtpdec.h deleted file mode 100644 index 477ab72..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * RTP demuxer definitions - * Copyright (c) 2002 Fabrice Bellard - * Copyright (c) 2006 Ryan Martell - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVFORMAT_RTPDEC_H -#define AVFORMAT_RTPDEC_H - -#include "libavcodec/avcodec.h" -#include "avformat.h" -#include "rtp.h" - -/** Structure listing useful vars to parse RTP packet payload*/ -typedef struct rtp_payload_data -{ - int sizelength; - int indexlength; - int indexdeltalength; - int profile_level_id; - int streamtype; - int objecttype; - char *mode; - - /** mpeg 4 AU headers */ - struct AUHeaders { - int size; - int index; - int cts_flag; - int cts; - int dts_flag; - int dts; - int rap_flag; - int streamstate; - } *au_headers; - int au_headers_allocated; - int nb_au_headers; - int au_headers_length_bytes; - int cur_au_index; -} RTPPayloadData; - -typedef struct PayloadContext PayloadContext; -typedef struct RTPDynamicProtocolHandler_s RTPDynamicProtocolHandler; - -#define RTP_MIN_PACKET_LENGTH 12 -#define RTP_MAX_PACKET_LENGTH 1500 /* XXX: suppress this define */ - -typedef struct RTPDemuxContext RTPDemuxContext; -RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, RTPPayloadData *rtp_payload_data); -void rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx, - RTPDynamicProtocolHandler *handler); -int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, - const uint8_t *buf, int len); -void rtp_parse_close(RTPDemuxContext *s); -#if (LIBAVFORMAT_VERSION_MAJOR <= 53) -int rtp_get_local_port(URLContext *h); -#endif -int rtp_get_local_rtp_port(URLContext *h); -int rtp_get_local_rtcp_port(URLContext *h); - -int rtp_set_remote_url(URLContext *h, const char *uri); -#if (LIBAVFORMAT_VERSION_MAJOR <= 52) -void rtp_get_file_handles(URLContext *h, int *prtp_fd, int *prtcp_fd); -#endif - -/** - * Send a dummy packet on both port pairs to set up the connection - * state in potential NAT routers, so that we're able to receive - * packets. - * - * Note, this only works if the NAT router doesn't remap ports. This - * isn't a standardized procedure, but it works in many cases in practice. - * - * The same routine is used with RDT too, even if RDT doesn't use normal - * RTP packets otherwise. - */ -void rtp_send_punch_packets(URLContext* rtp_handle); - -/** - * some rtp servers assume client is dead if they don't hear from them... - * so we send a Receiver Report to the provided ByteIO context - * (we don't have access to the rtcp handle from here) - */ -int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count); - -// these statistics are used for rtcp receiver reports... -typedef struct { - uint16_t max_seq; ///< highest sequence number seen - uint32_t cycles; ///< shifted count of sequence number cycles - uint32_t base_seq; ///< base sequence number - uint32_t bad_seq; ///< last bad sequence number + 1 - int probation; ///< sequence packets till source is valid - int received; ///< packets received - int expected_prior; ///< packets expected in last interval - int received_prior; ///< packets received in last interval - uint32_t transit; ///< relative transit time for previous packet - uint32_t jitter; ///< estimated jitter. -} RTPStatistics; - -#define RTP_FLAG_KEY 0x1 ///< RTP packet contains a keyframe -#define RTP_FLAG_MARKER 0x2 ///< RTP marker bit was set for this packet -/** - * Packet parsing for "private" payloads in the RTP specs. - * - * @param ctx RTSP demuxer context - * @param s stream context - * @param st stream that this packet belongs to - * @param pkt packet in which to write the parsed data - * @param timestamp pointer in which to write the timestamp of this RTP packet - * @param buf pointer to raw RTP packet data - * @param len length of buf - * @param flags flags from the RTP packet header (RTP_FLAG_*) - */ -typedef int (*DynamicPayloadPacketHandlerProc) (AVFormatContext *ctx, - PayloadContext *s, - AVStream *st, - AVPacket * pkt, - uint32_t *timestamp, - const uint8_t * buf, - int len, int flags); - -struct RTPDynamicProtocolHandler_s { - // fields from AVRtpDynamicPayloadType_s - const char enc_name[50]; /* XXX: still why 50 ? ;-) */ - enum AVMediaType codec_type; - enum CodecID codec_id; - - // may be null - int (*parse_sdp_a_line) (AVFormatContext *s, - int st_index, - PayloadContext *priv_data, - const char *line); ///< Parse the a= line from the sdp field - PayloadContext *(*open) (void); ///< allocate any data needed by the rtp parsing for this dynamic data. - void (*close)(PayloadContext *protocol_data); ///< free any data needed by the rtp parsing for this dynamic data. - DynamicPayloadPacketHandlerProc parse_packet; ///< parse handler for this dynamic packet. - - struct RTPDynamicProtocolHandler_s *next; -}; - -// moved out of rtp.c, because the h264 decoder needs to know about this structure.. -struct RTPDemuxContext { - AVFormatContext *ic; - AVStream *st; - int payload_type; - uint32_t ssrc; - uint16_t seq; - uint32_t timestamp; - uint32_t base_timestamp; - uint32_t cur_timestamp; - int64_t range_start_offset; - int max_payload_size; - struct MpegTSContext *ts; /* only used for MP2T payloads */ - int read_buf_index; - int read_buf_size; - /* used to send back RTCP RR */ - URLContext *rtp_ctx; - char hostname[256]; - - RTPStatistics statistics; ///< Statistics for this stream (used by RTCP receiver reports) - - /* rtcp sender statistics receive */ - int64_t last_rtcp_ntp_time; // TODO: move into statistics - int64_t first_rtcp_ntp_time; // TODO: move into statistics - uint32_t last_rtcp_timestamp; // TODO: move into statistics - - /* rtcp sender statistics */ - unsigned int packet_count; // TODO: move into statistics (outgoing) - unsigned int octet_count; // TODO: move into statistics (outgoing) - unsigned int last_octet_count; // TODO: move into statistics (outgoing) - int first_packet; - /* buffer for output */ - uint8_t buf[RTP_MAX_PACKET_LENGTH]; - uint8_t *buf_ptr; - - /* special infos for au headers parsing */ - RTPPayloadData *rtp_payload_data; // TODO: Move into dynamic payload handlers - - /* dynamic payload stuff */ - DynamicPayloadPacketHandlerProc parse_packet; ///< This is also copied from the dynamic protocol handler structure - PayloadContext *dynamic_protocol_context; ///< This is a copy from the values setup from the sdp parsing, in rtsp.c don't free me. - int max_frames_per_packet; -}; - -extern RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler; -void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler); - -int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size); ///< from rtsp.c, but used by rtp dynamic protocol handlers. - -void av_register_rtp_dynamic_payload_handlers(void); - -#endif /* AVFORMAT_RTPDEC_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_amr.c b/tizen/distrib/ffmpeg/libavformat/rtpdec_amr.c deleted file mode 100644 index a7b36c7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_amr.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * RTP AMR Depacketizer, RFC 3267 - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "rtpdec_amr.h" -#include "libavutil/avstring.h" - -static const uint8_t frame_sizes_nb[16] = { - 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 -}; -static const uint8_t frame_sizes_wb[16] = { - 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, 5, 0, 0, 0, 0, 0 -}; - -static int amr_handle_packet(AVFormatContext *ctx, - PayloadContext *data, - AVStream *st, - AVPacket * pkt, - uint32_t * timestamp, - const uint8_t * buf, - int len, int flags) -{ - const uint8_t *frame_sizes = NULL; - int frames; - int i; - const uint8_t *speech_data; - uint8_t *ptr; - - if (st->codec->codec_id == CODEC_ID_AMR_NB) { - frame_sizes = frame_sizes_nb; - } else if (st->codec->codec_id == CODEC_ID_AMR_WB) { - frame_sizes = frame_sizes_wb; - } else { - av_log(ctx, AV_LOG_ERROR, "Bad codec ID\n"); - return AVERROR_INVALIDDATA; - } - - if (st->codec->channels != 1) { - av_log(ctx, AV_LOG_ERROR, "Only mono AMR is supported\n"); - return AVERROR_INVALIDDATA; - } - - /* The AMR RTP packet consists of one header byte, followed - * by one TOC byte for each AMR frame in the packet, followed - * by the speech data for all the AMR frames. - * - * The header byte contains only a codec mode request, for - * requesting what kind of AMR data the sender wants to - * receive. Not used at the moment. - */ - - /* Count the number of frames in the packet. The highest bit - * is set in a TOC byte if there are more frames following. - */ - for (frames = 1; frames < len && (buf[frames] & 0x80); frames++) ; - - if (1 + frames >= len) { - /* We hit the end of the packet while counting frames. */ - av_log(ctx, AV_LOG_ERROR, "No speech data found\n"); - return AVERROR_INVALIDDATA; - } - - speech_data = buf + 1 + frames; - - /* Everything except the codec mode request byte should be output. */ - if (av_new_packet(pkt, len - 1)) { - av_log(ctx, AV_LOG_ERROR, "Out of memory\n"); - return AVERROR(ENOMEM); - } - pkt->stream_index = st->index; - ptr = pkt->data; - - for (i = 0; i < frames; i++) { - uint8_t toc = buf[1 + i]; - int frame_size = frame_sizes[(toc >> 3) & 0x0f]; - - if (speech_data + frame_size > buf + len) { - /* Too little speech data */ - av_log(ctx, AV_LOG_WARNING, "Too little speech data in the RTP packet\n"); - /* Set the unwritten part of the packet to zero. */ - memset(ptr, 0, pkt->data + pkt->size - ptr); - pkt->size = ptr - pkt->data; - return 0; - } - - /* Extract the AMR frame mode from the TOC byte */ - *ptr++ = toc & 0x7C; - - /* Copy the speech data */ - memcpy(ptr, speech_data, frame_size); - speech_data += frame_size; - ptr += frame_size; - } - - if (speech_data < buf + len) { - av_log(ctx, AV_LOG_WARNING, "Too much speech data in the RTP packet?\n"); - /* Set the unwritten part of the packet to zero. */ - memset(ptr, 0, pkt->data + pkt->size - ptr); - pkt->size = ptr - pkt->data; - } - - return 0; -} - -static int amr_parse_sdp_line(AVFormatContext *s, int st_index, - PayloadContext *data, const char *line) -{ - const char *p; - char attr[25], value[25]; - - /* Parse an fmtp line this one: - * a=fmtp:97 octet-align=1; interleaving=0 - * That is, a normal fmtp: line followed by semicolon & space - * separated key/value pairs. - */ - if (av_strstart(line, "fmtp:", &p)) { - int octet_align = 0; - int crc = 0; - int interleaving = 0; - int channels = 1; - - while (*p && *p == ' ') p++; /* strip spaces */ - while (*p && *p != ' ') p++; /* eat protocol identifier */ - while (*p && *p == ' ') p++; /* strip trailing spaces */ - - while (ff_rtsp_next_attr_and_value(&p, attr, sizeof(attr), value, sizeof(value))) { - /* Some AMR SDP configurations contain "octet-align", without - * the trailing =1. Therefore, if the value is empty, - * interpret it as "1". - */ - if (!strcmp(value, "")) { - av_log(s, AV_LOG_WARNING, "AMR fmtp attribute %s had " - "nonstandard empty value\n", attr); - strcpy(value, "1"); - } - if (!strcmp(attr, "octet-align")) - octet_align = atoi(value); - else if (!strcmp(attr, "crc")) - crc = atoi(value); - else if (!strcmp(attr, "interleaving")) - interleaving = atoi(value); - else if (!strcmp(attr, "channels")) - channels = atoi(value); - } - if (!octet_align || crc || interleaving || channels != 1) { - av_log(s, AV_LOG_ERROR, "Unsupported RTP/AMR configuration!\n"); - return -1; - } - } - return 0; -} - -RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler = { - .enc_name = "AMR", - .codec_type = AVMEDIA_TYPE_AUDIO, - .codec_id = CODEC_ID_AMR_NB, - .parse_sdp_a_line = amr_parse_sdp_line, - .parse_packet = amr_handle_packet, -}; - -RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler = { - .enc_name = "AMR-WB", - .codec_type = AVMEDIA_TYPE_AUDIO, - .codec_id = CODEC_ID_AMR_WB, - .parse_sdp_a_line = amr_parse_sdp_line, - .parse_packet = amr_handle_packet, -}; - diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_amr.h b/tizen/distrib/ffmpeg/libavformat/rtpdec_amr.h deleted file mode 100644 index 3cd9dd1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_amr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * RTP AMR Depacketizer, RFC 3267 - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTPDEC_AMR_H -#define AVFORMAT_RTPDEC_AMR_H - -#include "rtpdec.h" - -extern RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler; -extern RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler; - -#endif /* AVFORMAT_RTPDEC_AMR_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_asf.c b/tizen/distrib/ffmpeg/libavformat/rtpdec_asf.c deleted file mode 100644 index 7ca15f0..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_asf.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Microsoft RTP/ASF support. - * Copyright (c) 2008 Ronald S. Bultje - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Microsoft RTP/ASF support - * @author Ronald S. Bultje - */ - -#include -#include -#include -#include "rtp.h" -#include "rtpdec_asf.h" -#include "rtsp.h" -#include "asf.h" - -/** - * From MSDN 2.2.1.4, we learn that ASF data packets over RTP should not - * contain any padding. Unfortunately, the header min/max_pktsize are not - * updated (thus making min_pktsize invalid). Here, we "fix" these faulty - * min_pktsize values in the ASF file header. - * @return 0 on success, <0 on failure (currently -1). - */ -static int rtp_asf_fix_header(uint8_t *buf, int len) -{ - uint8_t *p = buf, *end = buf + len; - - if (len < sizeof(ff_asf_guid) * 2 + 22 || - memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) { - return -1; - } - p += sizeof(ff_asf_guid) + 14; - do { - uint64_t chunksize = AV_RL64(p + sizeof(ff_asf_guid)); - if (memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) { - if (chunksize > end - p) - return -1; - p += chunksize; - continue; - } - - /* skip most of the file header, to min_pktsize */ - p += 6 * 8 + 3 * 4 + sizeof(ff_asf_guid) * 2; - if (p + 8 <= end && AV_RL32(p) == AV_RL32(p + 4)) { - /* and set that to zero */ - AV_WL32(p, 0); - return 0; - } - break; - } while (end - p >= sizeof(ff_asf_guid) + 8); - - return -1; -} - -/** - * The following code is basically a buffered ByteIOContext, - * with the added benefit of returning -EAGAIN (instead of 0) - * on packet boundaries, such that the ASF demuxer can return - * safely and resume business at the next packet. - */ -static int packetizer_read(void *opaque, uint8_t *buf, int buf_size) -{ - return AVERROR(EAGAIN); -} - -static void init_packetizer(ByteIOContext *pb, uint8_t *buf, int len) -{ - init_put_byte(pb, buf, len, 0, NULL, packetizer_read, NULL, NULL); - - /* this "fills" the buffer with its current content */ - pb->pos = len; - pb->buf_end = buf + len; -} - -void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) -{ - if (av_strstart(p, "pgmpu:data:application/vnd.ms.wms-hdr.asfv1;base64,", &p)) { - ByteIOContext pb; - RTSPState *rt = s->priv_data; - int len = strlen(p) * 6 / 8; - char *buf = av_mallocz(len); - av_base64_decode(buf, p, len); - - if (rtp_asf_fix_header(buf, len) < 0) - av_log(s, AV_LOG_ERROR, - "Failed to fix invalid RTSP-MS/ASF min_pktsize\n"); - init_packetizer(&pb, buf, len); - if (rt->asf_ctx) { - av_close_input_stream(rt->asf_ctx); - rt->asf_ctx = NULL; - } - av_open_input_stream(&rt->asf_ctx, &pb, "", &asf_demuxer, NULL); - rt->asf_pb_pos = url_ftell(&pb); - av_free(buf); - rt->asf_ctx->pb = NULL; - } -} - -static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index, - PayloadContext *asf, const char *line) -{ - if (av_strstart(line, "stream:", &line)) { - RTSPState *rt = s->priv_data; - - s->streams[stream_index]->id = strtol(line, NULL, 10); - - if (rt->asf_ctx) { - int i; - - for (i = 0; i < rt->asf_ctx->nb_streams; i++) { - if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) { - *s->streams[stream_index]->codec = - *rt->asf_ctx->streams[i]->codec; - rt->asf_ctx->streams[i]->codec->extradata_size = 0; - rt->asf_ctx->streams[i]->codec->extradata = NULL; - av_set_pts_info(s->streams[stream_index], 32, 1, 1000); - } - } - } - } - - return 0; -} - -struct PayloadContext { - ByteIOContext *pktbuf, pb; - char *buf; -}; - -/** - * @return 0 when a packet was written into /p pkt, and no more data is left; - * 1 when a packet was written into /p pkt, and more packets might be left; - * <0 when not enough data was provided to return a full packet, or on error. - */ -static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf, - AVStream *st, AVPacket *pkt, - uint32_t *timestamp, - const uint8_t *buf, int len, int flags) -{ - ByteIOContext *pb = &asf->pb; - int res, mflags, len_off; - RTSPState *rt = s->priv_data; - - if (!rt->asf_ctx) - return -1; - - if (len > 0) { - int off, out_len; - - if (len < 4) - return -1; - - init_put_byte(pb, buf, len, 0, NULL, NULL, NULL, NULL); - mflags = get_byte(pb); - if (mflags & 0x80) - flags |= RTP_FLAG_KEY; - len_off = get_be24(pb); - if (mflags & 0x20) /**< relative timestamp */ - url_fskip(pb, 4); - if (mflags & 0x10) /**< has duration */ - url_fskip(pb, 4); - if (mflags & 0x8) /**< has location ID */ - url_fskip(pb, 4); - off = url_ftell(pb); - - av_freep(&asf->buf); - if (!(mflags & 0x40)) { - /** - * If 0x40 is not set, the len_off field specifies an offset of this - * packet's payload data in the complete (reassembled) ASF packet. - * This is used to spread one ASF packet over multiple RTP packets. - */ - if (asf->pktbuf && len_off != url_ftell(asf->pktbuf)) { - uint8_t *p; - url_close_dyn_buf(asf->pktbuf, &p); - asf->pktbuf = NULL; - av_free(p); - } - if (!len_off && !asf->pktbuf && - (res = url_open_dyn_buf(&asf->pktbuf)) < 0) - return res; - if (!asf->pktbuf) - return AVERROR(EIO); - - put_buffer(asf->pktbuf, buf + off, len - off); - if (!(flags & RTP_FLAG_MARKER)) - return -1; - out_len = url_close_dyn_buf(asf->pktbuf, &asf->buf); - asf->pktbuf = NULL; - } else { - /** - * If 0x40 is set, the len_off field specifies the length of the - * next ASF packet that can be read from this payload data alone. - * This is commonly the same as the payload size, but could be - * less in case of packet splitting (i.e. multiple ASF packets in - * one RTP packet). - */ - if (len_off != len) { - av_log_missing_feature(s, - "RTSP-MS packet splitting", 1); - return -1; - } - asf->buf = av_malloc(len - off); - out_len = len - off; - memcpy(asf->buf, buf + off, len - off); - } - - init_packetizer(pb, asf->buf, out_len); - pb->pos += rt->asf_pb_pos; - pb->eof_reached = 0; - rt->asf_ctx->pb = pb; - } - - for (;;) { - int i; - - res = av_read_packet(rt->asf_ctx, pkt); - rt->asf_pb_pos = url_ftell(pb); - if (res != 0) - break; - for (i = 0; i < s->nb_streams; i++) { - if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) { - pkt->stream_index = i; - return 1; // FIXME: return 0 if last packet - } - } - av_free_packet(pkt); - } - - return res == 1 ? -1 : res; -} - -static PayloadContext *asfrtp_new_context(void) -{ - return av_mallocz(sizeof(PayloadContext)); -} - -static void asfrtp_free_context(PayloadContext *asf) -{ - if (asf->pktbuf) { - uint8_t *p = NULL; - url_close_dyn_buf(asf->pktbuf, &p); - asf->pktbuf = NULL; - av_free(p); - } - av_freep(&asf->buf); - av_free(asf); -} - -#define RTP_ASF_HANDLER(n, s, t) \ -RTPDynamicProtocolHandler ff_ms_rtp_ ## n ## _handler = { \ - .enc_name = s, \ - .codec_type = t, \ - .codec_id = CODEC_ID_NONE, \ - .parse_sdp_a_line = asfrtp_parse_sdp_line, \ - .open = asfrtp_new_context, \ - .close = asfrtp_free_context, \ - .parse_packet = asfrtp_parse_packet, \ -}; - -RTP_ASF_HANDLER(asf_pfv, "x-asf-pf", AVMEDIA_TYPE_VIDEO); -RTP_ASF_HANDLER(asf_pfa, "x-asf-pf", AVMEDIA_TYPE_AUDIO); diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_asf.h b/tizen/distrib/ffmpeg/libavformat/rtpdec_asf.h deleted file mode 100644 index 5d60a14..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_asf.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Microsoft RTP/ASF support. - * Copyright (c) 2008 Ronald S. Bultje - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTPDEC_ASF_H -#define AVFORMAT_RTPDEC_ASF_H - -#include "avformat.h" -#include "rtpdec.h" - -/** - * Parse a Windows Media Server-specific SDP line - * - * @param s RTSP demux context - * @param line the SDP line to be parsed - */ -void ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p); - -/** - * Handlers for the x-asf-pf payloads (the payload ID for RTP/ASF). - * Defined and implemented in rtp_asf.c, registered in rtpdec.c. - */ -extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler, - ff_ms_rtp_asf_pfa_handler; - -#endif /* AVFORMAT_RTPDEC_ASF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_h263.c b/tizen/distrib/ffmpeg/libavformat/rtpdec_h263.c deleted file mode 100644 index 19de6ec..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_h263.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * RTP H.263 Depacketizer, RFC 4629 - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "rtpdec_h263.h" -#include "libavutil/intreadwrite.h" - -static int h263_handle_packet(AVFormatContext *ctx, - PayloadContext *data, - AVStream *st, - AVPacket * pkt, - uint32_t * timestamp, - const uint8_t * buf, - int len, int flags) -{ - uint8_t *ptr; - uint16_t header; - int startcode, vrc, picture_header; - - if (len < 2) { - av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet\n"); - return AVERROR_INVALIDDATA; - } - - /* Decode the 16 bit H.263+ payload header, as described in section - * 5.1 of RFC 4629. The fields of this header are: - * - 5 reserved bits, should be ignored. - * - One bit (P, startcode), indicating a picture start, picture segment - * start or video sequence end. If set, two zero bytes should be - * prepended to the payload. - * - One bit (V, vrc), indicating the presence of an 8 bit Video - * Redundancy Coding field after this 16 bit header. - * - 6 bits (PLEN, picture_header), the length (in bytes) of an extra - * picture header, following the VRC field. - * - 3 bits (PEBIT), the number of bits to ignore of the last byte - * of the extra picture header. (Not used at the moment.) - */ - header = AV_RB16(buf); - startcode = (header & 0x0400) >> 9; - vrc = header & 0x0200; - picture_header = (header & 0x01f8) >> 3; - buf += 2; - len -= 2; - - if (vrc) { - /* Skip VRC header if present, not used at the moment. */ - buf += 1; - len -= 1; - } - if (picture_header) { - /* Skip extra picture header if present, not used at the moment. */ - buf += picture_header; - len -= picture_header; - } - - if (len < 0) { - av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet\n"); - return AVERROR_INVALIDDATA; - } - - if (av_new_packet(pkt, len + startcode)) { - av_log(ctx, AV_LOG_ERROR, "Out of memory\n"); - return AVERROR(ENOMEM); - } - pkt->stream_index = st->index; - ptr = pkt->data; - - if (startcode) { - *ptr++ = 0; - *ptr++ = 0; - } - memcpy(ptr, buf, len); - - return 0; -} - -RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = { - .enc_name = "H263-1998", - .codec_type = AVMEDIA_TYPE_VIDEO, - .codec_id = CODEC_ID_H263, - .parse_packet = h263_handle_packet, -}; - -RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = { - .enc_name = "H263-2000", - .codec_type = AVMEDIA_TYPE_VIDEO, - .codec_id = CODEC_ID_H263, - .parse_packet = h263_handle_packet, -}; - diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_h263.h b/tizen/distrib/ffmpeg/libavformat/rtpdec_h263.h deleted file mode 100644 index 5b51128..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_h263.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * RTP H.263 Depacketizer, RFC 4629 - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTPDEC_H263_H -#define AVFORMAT_RTPDEC_H263_H - -#include "rtpdec.h" - -extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler; -extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler; - -#endif /* AVFORMAT_RTPDEC_H263_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_h264.c b/tizen/distrib/ffmpeg/libavformat/rtpdec_h264.c deleted file mode 100644 index d690173..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_h264.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * RTP H264 Protocol (RFC3984) - * Copyright (c) 2006 Ryan Martell - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file - * @brief H.264 / RTP Code (RFC3984) - * @author Ryan Martell - * - * @note Notes: - * Notes: - * This currently supports packetization mode: - * Single Nal Unit Mode (0), or - * Non-Interleaved Mode (1). It currently does not support - * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, FU-B packet types) - * - * @note TODO: - * 1) RTCP sender reports for udp streams are required.. - * - */ - -#include "libavutil/base64.h" -#include "libavutil/avstring.h" -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "mpegts.h" - -#include -#include "network.h" -#include - -#include "rtpdec.h" -#include "rtpdec_h264.h" - -/** - RTP/H264 specific private data. -*/ -struct PayloadContext { - unsigned long cookie; ///< sanity check, to make sure we get the pointer we're expecting. - - //sdp setup parameters - uint8_t profile_idc; ///< from the sdp setup parameters. - uint8_t profile_iop; ///< from the sdp setup parameters. - uint8_t level_idc; ///< from the sdp setup parameters. - int packetization_mode; ///< from the sdp setup parameters. -#ifdef DEBUG - int packet_types_received[32]; -#endif -}; - -#define MAGIC_COOKIE (0xdeadbeef) ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed. -#define DEAD_COOKIE (0xdeaddead) ///< Cookie for the extradata; once it is freed. - -/* ---------------- private code */ -static void sdp_parse_fmtp_config_h264(AVStream * stream, - PayloadContext * h264_data, - char *attr, char *value) -{ - AVCodecContext *codec = stream->codec; - assert(codec->codec_id == CODEC_ID_H264); - assert(h264_data != NULL); - - if (!strcmp(attr, "packetization-mode")) { - av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value)); - h264_data->packetization_mode = atoi(value); - /* - Packetization Mode: - 0 or not present: Single NAL mode (Only nals from 1-23 are allowed) - 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed. - 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed. - */ - if (h264_data->packetization_mode > 1) - av_log(codec, AV_LOG_ERROR, - "Interleaved RTP mode is not supported yet."); - } else if (!strcmp(attr, "profile-level-id")) { - if (strlen(value) == 6) { - char buffer[3]; - // 6 characters=3 bytes, in hex. - uint8_t profile_idc; - uint8_t profile_iop; - uint8_t level_idc; - - buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0'; - profile_idc = strtol(buffer, NULL, 16); - buffer[0] = value[2]; buffer[1] = value[3]; - profile_iop = strtol(buffer, NULL, 16); - buffer[0] = value[4]; buffer[1] = value[5]; - level_idc = strtol(buffer, NULL, 16); - - // set the parameters... - av_log(codec, AV_LOG_DEBUG, - "RTP Profile IDC: %x Profile IOP: %x Level: %x\n", - profile_idc, profile_iop, level_idc); - h264_data->profile_idc = profile_idc; - h264_data->profile_iop = profile_iop; - h264_data->level_idc = level_idc; - } - } else if (!strcmp(attr, "sprop-parameter-sets")) { - uint8_t start_sequence[]= { 0, 0, 1 }; - codec->extradata_size= 0; - codec->extradata= NULL; - - while (*value) { - char base64packet[1024]; - uint8_t decoded_packet[1024]; - uint32_t packet_size; - char *dst = base64packet; - - while (*value && *value != ',' - && (dst - base64packet) < sizeof(base64packet) - 1) { - *dst++ = *value++; - } - *dst++ = '\0'; - - if (*value == ',') - value++; - - packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet)); - if (packet_size) { - uint8_t *dest = av_malloc(packet_size + sizeof(start_sequence) + - codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if(dest) - { - if(codec->extradata_size) - { - // av_realloc? - memcpy(dest, codec->extradata, codec->extradata_size); - av_free(codec->extradata); - } - - memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence)); - memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size); - memset(dest+codec->extradata_size+sizeof(start_sequence)+ - packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - codec->extradata= dest; - codec->extradata_size+= sizeof(start_sequence)+packet_size; - } else { - av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!"); - } - } - } - av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size); - } -} - -// return 0 on packet, no more left, 1 on packet, 1 on partial packet... -static int h264_handle_packet(AVFormatContext *ctx, - PayloadContext *data, - AVStream *st, - AVPacket * pkt, - uint32_t * timestamp, - const uint8_t * buf, - int len, int flags) -{ - uint8_t nal = buf[0]; - uint8_t type = (nal & 0x1f); - int result= 0; - uint8_t start_sequence[]= {0, 0, 1}; - -#ifdef DEBUG - assert(data); - assert(data->cookie == MAGIC_COOKIE); -#endif - assert(buf); - - if (type >= 1 && type <= 23) - type = 1; // simplify the case. (these are all the nal types used internally by the h264 codec) - switch (type) { - case 0: // undefined; - result= -1; - break; - - case 1: - av_new_packet(pkt, len+sizeof(start_sequence)); - memcpy(pkt->data, start_sequence, sizeof(start_sequence)); - memcpy(pkt->data+sizeof(start_sequence), buf, len); -#ifdef DEBUG - data->packet_types_received[nal & 0x1f]++; -#endif - break; - - case 24: // STAP-A (one packet, multiple nals) - // consume the STAP-A NAL - buf++; - len--; - // first we are going to figure out the total size.... - { - int pass= 0; - int total_length= 0; - uint8_t *dst= NULL; - - for(pass= 0; pass<2; pass++) { - const uint8_t *src= buf; - int src_len= len; - - do { - uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?) - - // consume the length of the aggregate... - src += 2; - src_len -= 2; - - if (nal_size <= src_len) { - if(pass==0) { - // counting... - total_length+= sizeof(start_sequence)+nal_size; - } else { - // copying - assert(dst); - memcpy(dst, start_sequence, sizeof(start_sequence)); - dst+= sizeof(start_sequence); - memcpy(dst, src, nal_size); -#ifdef DEBUG - data->packet_types_received[*src & 0x1f]++; -#endif - dst+= nal_size; - } - } else { - av_log(ctx, AV_LOG_ERROR, - "nal size exceeds length: %d %d\n", nal_size, src_len); - } - - // eat what we handled... - src += nal_size; - src_len -= nal_size; - - if (src_len < 0) - av_log(ctx, AV_LOG_ERROR, - "Consumed more bytes than we got! (%d)\n", src_len); - } while (src_len > 2); // because there could be rtp padding.. - - if(pass==0) { - // now we know the total size of the packet (with the start sequences added) - av_new_packet(pkt, total_length); - dst= pkt->data; - } else { - assert(dst-pkt->data==total_length); - } - } - } - break; - - case 25: // STAP-B - case 26: // MTAP-16 - case 27: // MTAP-24 - case 29: // FU-B - av_log(ctx, AV_LOG_ERROR, - "Unhandled type (%d) (See RFC for implementation details\n", - type); - result= -1; - break; - - case 28: // FU-A (fragmented nal) - buf++; - len--; // skip the fu_indicator - { - // these are the same as above, we just redo them here for clarity... - uint8_t fu_indicator = nal; - uint8_t fu_header = *buf; // read the fu_header. - uint8_t start_bit = fu_header >> 7; -// uint8_t end_bit = (fu_header & 0x40) >> 6; - uint8_t nal_type = (fu_header & 0x1f); - uint8_t reconstructed_nal; - - // reconstruct this packet's true nal; only the data follows.. - reconstructed_nal = fu_indicator & (0xe0); // the original nal forbidden bit and NRI are stored in this packet's nal; - reconstructed_nal |= nal_type; - - // skip the fu_header... - buf++; - len--; - -#ifdef DEBUG - if (start_bit) - data->packet_types_received[nal_type]++; -#endif - if(start_bit) { - // copy in the start sequence, and the reconstructed nal.... - av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len); - memcpy(pkt->data, start_sequence, sizeof(start_sequence)); - pkt->data[sizeof(start_sequence)]= reconstructed_nal; - memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len); - } else { - av_new_packet(pkt, len); - memcpy(pkt->data, buf, len); - } - } - break; - - case 30: // undefined - case 31: // undefined - default: - av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type); - result= -1; - break; - } - - pkt->stream_index = st->index; - - return result; -} - -/* ---------------- public code */ -static PayloadContext *h264_new_context(void) -{ - PayloadContext *data = - av_mallocz(sizeof(PayloadContext) + - FF_INPUT_BUFFER_PADDING_SIZE); - - if (data) { - data->cookie = MAGIC_COOKIE; - } - - return data; -} - -static void h264_free_context(PayloadContext *data) -{ -#ifdef DEBUG - int ii; - - for (ii = 0; ii < 32; ii++) { - if (data->packet_types_received[ii]) - av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n", - data->packet_types_received[ii], ii); - } -#endif - - assert(data); - assert(data->cookie == MAGIC_COOKIE); - - // avoid stale pointers (assert) - data->cookie = DEAD_COOKIE; - - // and clear out this... - av_free(data); -} - -static int parse_h264_sdp_line(AVFormatContext *s, int st_index, - PayloadContext *h264_data, const char *line) -{ - AVStream *stream = s->streams[st_index]; - AVCodecContext *codec = stream->codec; - const char *p = line; - - assert(h264_data->cookie == MAGIC_COOKIE); - - if (av_strstart(p, "framesize:", &p)) { - char buf1[50]; - char *dst = buf1; - - // remove the protocol identifier.. - while (*p && *p == ' ') p++; // strip spaces. - while (*p && *p != ' ') p++; // eat protocol identifier - while (*p && *p == ' ') p++; // strip trailing spaces. - while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) { - *dst++ = *p++; - } - *dst = '\0'; - - // a='framesize:96 320-240' - // set our parameters.. - codec->width = atoi(buf1); - codec->height = atoi(p + 1); // skip the - - codec->pix_fmt = PIX_FMT_YUV420P; - } else if (av_strstart(p, "fmtp:", &p)) { - char attr[256]; - char value[4096]; - - // remove the protocol identifier.. - while (*p && *p == ' ') p++; // strip spaces. - while (*p && *p != ' ') p++; // eat protocol identifier - while (*p && *p == ' ') p++; // strip trailing spaces. - - /* loop on each attribute */ - while (ff_rtsp_next_attr_and_value - (&p, attr, sizeof(attr), value, sizeof(value))) { - /* grab the codec extra_data from the config parameter of the fmtp line */ - sdp_parse_fmtp_config_h264(stream, h264_data, attr, value); - } - } else if (av_strstart(p, "cliprect:", &p)) { - // could use this if we wanted. - } - - av_set_pts_info(stream, 33, 1, 90000); // 33 should be right, because the pts is 64 bit? (done elsewhere; this is a one time thing) - - return 0; // keep processing it the normal way... -} - -/** -This is the structure for expanding on the dynamic rtp protocols (makes everything static. yay!) -*/ -RTPDynamicProtocolHandler ff_h264_dynamic_handler = { - .enc_name = "H264", - .codec_type = AVMEDIA_TYPE_VIDEO, - .codec_id = CODEC_ID_H264, - .parse_sdp_a_line = parse_h264_sdp_line, - .open = h264_new_context, - .close = h264_free_context, - .parse_packet = h264_handle_packet -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_h264.h b/tizen/distrib/ffmpeg/libavformat/rtpdec_h264.h deleted file mode 100644 index b4d54de..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_h264.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * RTP H264 Protocol (RFC3984) - * Copyright (c) 2006 Ryan Martell - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTPDEC_H264_H -#define AVFORMAT_RTPDEC_H264_H - -#include "rtpdec.h" - -extern RTPDynamicProtocolHandler ff_h264_dynamic_handler; - -#endif /* AVFORMAT_RTPDEC_H264_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.c b/tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.c deleted file mode 100644 index 9a1f33d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Xiph RTP Protocols - * Copyright (c) 2009 Colin McQuillian - * Copyright (c) 2010 Josh Allmann - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Xiph / RTP Code - * @author Colin McQuillan - * @author Josh Allmann - */ - -#include "libavutil/avstring.h" -#include "libavutil/base64.h" -#include "libavcodec/bytestream.h" - -#include - -#include "rtpdec.h" -#include "rtpdec_xiph.h" - -/** - * RTP/Xiph specific private data. - */ -struct PayloadContext { - unsigned ident; ///< 24-bit stream configuration identifier - uint32_t timestamp; - ByteIOContext* fragment; ///< buffer for split payloads -}; - -static PayloadContext *xiph_new_context(void) -{ - return av_mallocz(sizeof(PayloadContext)); -} - -static inline void free_fragment_if_needed(PayloadContext * data) -{ - if (data->fragment) { - uint8_t* p; - url_close_dyn_buf(data->fragment, &p); - av_free(p); - data->fragment = NULL; - } -} - -static void xiph_free_context(PayloadContext * data) -{ - free_fragment_if_needed(data); - av_free(data); -} - -static int xiph_handle_packet(AVFormatContext * ctx, - PayloadContext * data, - AVStream * st, - AVPacket * pkt, - uint32_t * timestamp, - const uint8_t * buf, int len, int flags) -{ - - int ident, fragmented, tdt, num_pkts, pkt_len; - - if (len < 6) { - av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len); - return AVERROR_INVALIDDATA; - } - - // read xiph rtp headers - ident = AV_RB24(buf); - fragmented = buf[3] >> 6; - tdt = (buf[3] >> 4) & 3; - num_pkts = buf[3] & 7; - pkt_len = AV_RB16(buf + 4); - - if (pkt_len > len - 6) { - av_log(ctx, AV_LOG_ERROR, - "Invalid packet length %d in %d byte packet\n", pkt_len, - len); - return AVERROR_INVALIDDATA; - } - - if (ident != data->ident) { - av_log(ctx, AV_LOG_ERROR, - "Unimplemented Xiph SDP configuration change detected\n"); - return AVERROR_PATCHWELCOME; - } - - if (tdt) { - av_log(ctx, AV_LOG_ERROR, - "Unimplemented RTP Xiph packet settings (%d,%d,%d)\n", - fragmented, tdt, num_pkts); - return AVERROR_PATCHWELCOME; - } - - buf += 6; // move past header bits - len -= 6; - - if (fragmented == 0) { - // whole frame(s) - int i, data_len, write_len; - buf -= 2; - len += 2; - - // fast first pass to calculate total length - for (i = 0, data_len = 0; (i < num_pkts) && (len >= 2); i++) { - int off = data_len + (i << 1); - pkt_len = AV_RB16(buf + off); - data_len += pkt_len; - len -= pkt_len + 2; - } - - if (len < 0 || i < num_pkts) { - av_log(ctx, AV_LOG_ERROR, - "Bad packet: %d bytes left at frame %d of %d\n", - len, i, num_pkts); - return AVERROR_INVALIDDATA; - } - - if (av_new_packet(pkt, data_len)) { - av_log(ctx, AV_LOG_ERROR, "Out of memory.\n"); - return AVERROR(ENOMEM); - } - pkt->stream_index = st->index; - - // concatenate frames - for (i = 0, write_len = 0; write_len < data_len; i++) { - pkt_len = AV_RB16(buf); - buf += 2; - memcpy(pkt->data + write_len, buf, pkt_len); - write_len += pkt_len; - buf += pkt_len; - } - assert(write_len == data_len); - - return 0; - - } else if (fragmented == 1) { - // start of xiph data fragment - int res; - - // end packet has been lost somewhere, so drop buffered data - free_fragment_if_needed(data); - - if((res = url_open_dyn_buf(&data->fragment)) < 0) - return res; - - put_buffer(data->fragment, buf, pkt_len); - data->timestamp = *timestamp; - - } else { - assert(fragmented < 4); - if (data->timestamp != *timestamp) { - // skip if fragmented timestamp is incorrect; - // a start packet has been lost somewhere - free_fragment_if_needed(data); - av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match!\n"); - return AVERROR_INVALIDDATA; - } - - // copy data to fragment buffer - put_buffer(data->fragment, buf, pkt_len); - - if (fragmented == 3) { - // end of xiph data packet - uint8_t* xiph_data; - int frame_size = url_close_dyn_buf(data->fragment, &xiph_data); - - if (frame_size < 0) { - av_log(ctx, AV_LOG_ERROR, - "Error occurred when getting fragment buffer."); - return frame_size; - } - - if (av_new_packet(pkt, frame_size)) { - av_log(ctx, AV_LOG_ERROR, "Out of memory.\n"); - return AVERROR(ENOMEM); - } - - memcpy(pkt->data, xiph_data, frame_size); - pkt->stream_index = st->index; - - av_free(xiph_data); - data->fragment = NULL; - - return 0; - } - } - - return AVERROR(EAGAIN); -} - -/** - * Length encoding described in RFC5215 section 3.1.1. - */ -static int get_base128(const uint8_t ** buf, const uint8_t * buf_end) -{ - int n = 0; - for (; *buf < buf_end; ++*buf) { - n <<= 7; - n += **buf & 0x7f; - if (!(**buf & 0x80)) { - ++*buf; - return n; - } - } - return 0; -} - -/** - * Based off parse_packed_headers in Vorbis RTP - */ -static unsigned int -parse_packed_headers(const uint8_t * packed_headers, - const uint8_t * packed_headers_end, - AVCodecContext * codec, PayloadContext * xiph_data) -{ - - unsigned num_packed, num_headers, length, length1, length2, extradata_alloc; - uint8_t *ptr; - - if (packed_headers_end - packed_headers < 9) { - av_log(codec, AV_LOG_ERROR, - "Invalid %d byte packed header.", - packed_headers_end - packed_headers); - return AVERROR_INVALIDDATA; - } - - num_packed = bytestream_get_be32(&packed_headers); - xiph_data->ident = bytestream_get_be24(&packed_headers); - length = bytestream_get_be16(&packed_headers); - num_headers = get_base128(&packed_headers, packed_headers_end); - length1 = get_base128(&packed_headers, packed_headers_end); - length2 = get_base128(&packed_headers, packed_headers_end); - - if (num_packed != 1 || num_headers > 3) { - av_log(codec, AV_LOG_ERROR, - "Unimplemented number of headers: %d packed headers, %d headers\n", - num_packed, num_headers); - return AVERROR_PATCHWELCOME; - } - - if (packed_headers_end - packed_headers != length || - length1 > length || length2 > length - length1) { - av_log(codec, AV_LOG_ERROR, - "Bad packed header lengths (%d,%d,%d,%d)\n", length1, - length2, packed_headers_end - packed_headers, length); - return AVERROR_INVALIDDATA; - } - - /* allocate extra space: - * -- length/255 +2 for xiphlacing - * -- one for the '2' marker - * -- FF_INPUT_BUFFER_PADDING_SIZE required */ - extradata_alloc = length + length/255 + 3 + FF_INPUT_BUFFER_PADDING_SIZE; - - ptr = codec->extradata = av_malloc(extradata_alloc); - if (!ptr) { - av_log(codec, AV_LOG_ERROR, "Out of memory\n"); - return AVERROR(ENOMEM); - } - *ptr++ = 2; - ptr += av_xiphlacing(ptr, length1); - ptr += av_xiphlacing(ptr, length2); - memcpy(ptr, packed_headers, length); - ptr += length; - codec->extradata_size = ptr - codec->extradata; - // clear out remaining parts of the buffer - memset(ptr, 0, extradata_alloc - codec->extradata_size); - - return 0; -} - -static int xiph_parse_fmtp_pair(AVCodecContext * codec, - PayloadContext *xiph_data, - char *attr, char *value) -{ - int result = 0; - - if (!strcmp(attr, "sampling")) { - return AVERROR_PATCHWELCOME; - } else if (!strcmp(attr, "width")) { - /* This is an integer between 1 and 1048561 - * and MUST be in multiples of 16. */ - codec->width = atoi(value); - return 0; - } else if (!strcmp(attr, "height")) { - /* This is an integer between 1 and 1048561 - * and MUST be in multiples of 16. */ - codec->height = atoi(value); - return 0; - } else if (!strcmp(attr, "delivery-method")) { - /* Possible values are: inline, in_band, out_band/specific_name. */ - return AVERROR_PATCHWELCOME; - } else if (!strcmp(attr, "configuration-uri")) { - /* NOTE: configuration-uri is supported only under 2 conditions: - *--after the delivery-method tag - * --with a delivery-method value of out_band */ - return AVERROR_PATCHWELCOME; - } else if (!strcmp(attr, "configuration")) { - /* NOTE: configuration is supported only AFTER the delivery-method tag - * The configuration value is a base64 encoded packed header */ - uint8_t *decoded_packet = NULL; - int packet_size; - size_t decoded_alloc = strlen(value) / 4 * 3 + 4; - - if (decoded_alloc <= INT_MAX) { - decoded_packet = av_malloc(decoded_alloc); - if (decoded_packet) { - packet_size = - av_base64_decode(decoded_packet, value, decoded_alloc); - - result = parse_packed_headers - (decoded_packet, decoded_packet + packet_size, codec, - xiph_data); - } else { - av_log(codec, AV_LOG_ERROR, - "Out of memory while decoding SDP configuration.\n"); - result = AVERROR(ENOMEM); - } - } else { - av_log(codec, AV_LOG_ERROR, "Packet too large\n"); - result = AVERROR_INVALIDDATA; - } - av_free(decoded_packet); - } - return result; -} - -static int xiph_parse_sdp_line(AVFormatContext *s, int st_index, - PayloadContext *data, const char *line) -{ - const char *p; - char *value; - char attr[25]; - int value_size = strlen(line), attr_size = sizeof(attr), res = 0; - AVCodecContext* codec = s->streams[st_index]->codec; - - assert(data); - - if (!(value = av_malloc(value_size))) { - av_log(codec, AV_LOG_ERROR, "Out of memory\n"); - return AVERROR(ENOMEM); - } - - if (av_strstart(line, "fmtp:", &p)) { - // remove protocol identifier - while (*p && *p == ' ') p++; // strip spaces - while (*p && *p != ' ') p++; // eat protocol identifier - while (*p && *p == ' ') p++; // strip trailing spaces - - while (ff_rtsp_next_attr_and_value(&p, - attr, attr_size, - value, value_size)) { - res = xiph_parse_fmtp_pair(codec, data, attr, value); - if (res < 0 && res != AVERROR_PATCHWELCOME) - return res; - } - } - - av_free(value); - return 0; -} - -RTPDynamicProtocolHandler ff_theora_dynamic_handler = { - .enc_name = "theora", - .codec_type = AVMEDIA_TYPE_VIDEO, - .codec_id = CODEC_ID_THEORA, - .parse_sdp_a_line = xiph_parse_sdp_line, - .open = xiph_new_context, - .close = xiph_free_context, - .parse_packet = xiph_handle_packet -}; - -RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = { - .enc_name = "vorbis", - .codec_type = AVMEDIA_TYPE_AUDIO, - .codec_id = CODEC_ID_VORBIS, - .parse_sdp_a_line = xiph_parse_sdp_line, - .open = xiph_new_context, - .close = xiph_free_context, - .parse_packet = xiph_handle_packet -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.h b/tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.h deleted file mode 100644 index 50aa77f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpdec_xiph.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Xiph RTP Protocols - * Based off RFC 5215 (Vorbis RTP) and the Theora RTP draft. - * Copyright (c) 2009 Colin McQuillian - * Copyright (c) 2010 Josh Allmann - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTPDEC_XIPH_H -#define AVFORMAT_RTPDEC_XIPH_H - -#include "libavcodec/avcodec.h" -#include "rtpdec.h" - -/** - * Theora RTP callbacks. - */ -extern RTPDynamicProtocolHandler ff_theora_dynamic_handler; - -/** - * Vorbis RTP callbacks. - */ -extern RTPDynamicProtocolHandler ff_vorbis_dynamic_handler; - -#endif /* AVFORMAT_RTPDEC_XIPH_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpenc.c b/tizen/distrib/ffmpeg/libavformat/rtpenc.c deleted file mode 100644 index 5df101e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpenc.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * RTP output format - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "mpegts.h" -#include "internal.h" -#include "libavutil/random_seed.h" - -#include - -#include "rtpenc.h" - -//#define DEBUG - -#define RTCP_SR_SIZE 28 - -static int is_supported(enum CodecID id) -{ - switch(id) { - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_H264: - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - case CODEC_ID_MPEG4: - case CODEC_ID_AAC: - case CODEC_ID_MP2: - case CODEC_ID_MP3: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U8: - case CODEC_ID_MPEG2TS: - case CODEC_ID_AMR_NB: - case CODEC_ID_AMR_WB: - return 1; - default: - return 0; - } -} - -static int rtp_write_header(AVFormatContext *s1) -{ - RTPMuxContext *s = s1->priv_data; - int max_packet_size, n; - AVStream *st; - - if (s1->nb_streams != 1) - return -1; - st = s1->streams[0]; - if (!is_supported(st->codec->codec_id)) { - av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codec->codec_id); - - return -1; - } - - s->payload_type = ff_rtp_get_payload_type(st->codec); - if (s->payload_type < 0) - s->payload_type = RTP_PT_PRIVATE + (st->codec->codec_type == AVMEDIA_TYPE_AUDIO); - - s->base_timestamp = ff_random_get_seed(); - s->timestamp = s->base_timestamp; - s->cur_timestamp = 0; - s->ssrc = ff_random_get_seed(); - s->first_packet = 1; - s->first_rtcp_ntp_time = ff_ntp_time(); - if (s1->start_time_realtime) - /* Round the NTP time to whole milliseconds. */ - s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 + - NTP_OFFSET_US; - - max_packet_size = url_fget_max_packet_size(s1->pb); - if (max_packet_size <= 12) - return AVERROR(EIO); - s->buf = av_malloc(max_packet_size); - if (s->buf == NULL) { - return AVERROR(ENOMEM); - } - s->max_payload_size = max_packet_size - 12; - - s->max_frames_per_packet = 0; - if (s1->max_delay) { - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (st->codec->frame_size == 0) { - av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n"); - } else { - s->max_frames_per_packet = av_rescale_rnd(s1->max_delay, st->codec->sample_rate, AV_TIME_BASE * st->codec->frame_size, AV_ROUND_DOWN); - } - } - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - /* FIXME: We should round down here... */ - s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base); - } - } - - av_set_pts_info(st, 32, 1, 90000); - switch(st->codec->codec_id) { - case CODEC_ID_MP2: - case CODEC_ID_MP3: - s->buf_ptr = s->buf + 4; - break; - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - break; - case CODEC_ID_MPEG2TS: - n = s->max_payload_size / TS_PACKET_SIZE; - if (n < 1) - n = 1; - s->max_payload_size = n * TS_PACKET_SIZE; - s->buf_ptr = s->buf; - break; - case CODEC_ID_AMR_NB: - case CODEC_ID_AMR_WB: - if (!s->max_frames_per_packet) - s->max_frames_per_packet = 12; - if (st->codec->codec_id == CODEC_ID_AMR_NB) - n = 31; - else - n = 61; - /* max_header_toc_size + the largest AMR payload must fit */ - if (1 + s->max_frames_per_packet + n > s->max_payload_size) { - av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n"); - return -1; - } - if (st->codec->channels != 1) { - av_log(s1, AV_LOG_ERROR, "Only mono is supported\n"); - return -1; - } - case CODEC_ID_AAC: - s->num_frames = 0; - default: - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - av_set_pts_info(st, 32, 1, st->codec->sample_rate); - } - s->buf_ptr = s->buf; - break; - } - - return 0; -} - -/* send an rtcp sender report packet */ -static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time) -{ - RTPMuxContext *s = s1->priv_data; - uint32_t rtp_ts; - - dprintf(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp); - - s->last_rtcp_ntp_time = ntp_time; - rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000}, - s1->streams[0]->time_base) + s->base_timestamp; - put_byte(s1->pb, (RTP_VERSION << 6)); - put_byte(s1->pb, 200); - put_be16(s1->pb, 6); /* length in words - 1 */ - put_be32(s1->pb, s->ssrc); - put_be32(s1->pb, ntp_time / 1000000); - put_be32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000); - put_be32(s1->pb, rtp_ts); - put_be32(s1->pb, s->packet_count); - put_be32(s1->pb, s->octet_count); - put_flush_packet(s1->pb); -} - -/* send an rtp packet. sequence number is incremented, but the caller - must update the timestamp itself */ -void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m) -{ - RTPMuxContext *s = s1->priv_data; - - dprintf(s1, "rtp_send_data size=%d\n", len); - - /* build the RTP header */ - put_byte(s1->pb, (RTP_VERSION << 6)); - put_byte(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7)); - put_be16(s1->pb, s->seq); - put_be32(s1->pb, s->timestamp); - put_be32(s1->pb, s->ssrc); - - put_buffer(s1->pb, buf1, len); - put_flush_packet(s1->pb); - - s->seq++; - s->octet_count += len; - s->packet_count++; -} - -/* send an integer number of samples and compute time stamp and fill - the rtp send buffer before sending. */ -static void rtp_send_samples(AVFormatContext *s1, - const uint8_t *buf1, int size, int sample_size) -{ - RTPMuxContext *s = s1->priv_data; - int len, max_packet_size, n; - - max_packet_size = (s->max_payload_size / sample_size) * sample_size; - /* not needed, but who nows */ - if ((size % sample_size) != 0) - av_abort(); - n = 0; - while (size > 0) { - s->buf_ptr = s->buf; - len = FFMIN(max_packet_size, size); - - /* copy data */ - memcpy(s->buf_ptr, buf1, len); - s->buf_ptr += len; - buf1 += len; - size -= len; - s->timestamp = s->cur_timestamp + n / sample_size; - ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0); - n += (s->buf_ptr - s->buf); - } -} - -static void rtp_send_mpegaudio(AVFormatContext *s1, - const uint8_t *buf1, int size) -{ - RTPMuxContext *s = s1->priv_data; - int len, count, max_packet_size; - - max_packet_size = s->max_payload_size; - - /* test if we must flush because not enough space */ - len = (s->buf_ptr - s->buf); - if ((len + size) > max_packet_size) { - if (len > 4) { - ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0); - s->buf_ptr = s->buf + 4; - } - } - if (s->buf_ptr == s->buf + 4) { - s->timestamp = s->cur_timestamp; - } - - /* add the packet */ - if (size > max_packet_size) { - /* big packet: fragment */ - count = 0; - while (size > 0) { - len = max_packet_size - 4; - if (len > size) - len = size; - /* build fragmented packet */ - s->buf[0] = 0; - s->buf[1] = 0; - s->buf[2] = count >> 8; - s->buf[3] = count; - memcpy(s->buf + 4, buf1, len); - ff_rtp_send_data(s1, s->buf, len + 4, 0); - size -= len; - buf1 += len; - count += len; - } - } else { - if (s->buf_ptr == s->buf + 4) { - /* no fragmentation possible */ - s->buf[0] = 0; - s->buf[1] = 0; - s->buf[2] = 0; - s->buf[3] = 0; - } - memcpy(s->buf_ptr, buf1, size); - s->buf_ptr += size; - } -} - -static void rtp_send_raw(AVFormatContext *s1, - const uint8_t *buf1, int size) -{ - RTPMuxContext *s = s1->priv_data; - int len, max_packet_size; - - max_packet_size = s->max_payload_size; - - while (size > 0) { - len = max_packet_size; - if (len > size) - len = size; - - s->timestamp = s->cur_timestamp; - ff_rtp_send_data(s1, buf1, len, (len == size)); - - buf1 += len; - size -= len; - } -} - -/* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */ -static void rtp_send_mpegts_raw(AVFormatContext *s1, - const uint8_t *buf1, int size) -{ - RTPMuxContext *s = s1->priv_data; - int len, out_len; - - while (size >= TS_PACKET_SIZE) { - len = s->max_payload_size - (s->buf_ptr - s->buf); - if (len > size) - len = size; - memcpy(s->buf_ptr, buf1, len); - buf1 += len; - size -= len; - s->buf_ptr += len; - - out_len = s->buf_ptr - s->buf; - if (out_len >= s->max_payload_size) { - ff_rtp_send_data(s1, s->buf, out_len, 0); - s->buf_ptr = s->buf; - } - } -} - -static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) -{ - RTPMuxContext *s = s1->priv_data; - AVStream *st = s1->streams[0]; - int rtcp_bytes; - int size= pkt->size; - - dprintf(s1, "%d: write len=%d\n", pkt->stream_index, size); - - rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / - RTCP_TX_RATIO_DEN; - if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) && - (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) { - rtcp_send_sr(s1, ff_ntp_time()); - s->last_octet_count = s->octet_count; - s->first_packet = 0; - } - s->cur_timestamp = s->base_timestamp + pkt->pts; - - switch(st->codec->codec_id) { - case CODEC_ID_PCM_MULAW: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_S8: - rtp_send_samples(s1, pkt->data, size, 1 * st->codec->channels); - break; - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_S16LE: - rtp_send_samples(s1, pkt->data, size, 2 * st->codec->channels); - break; - case CODEC_ID_MP2: - case CODEC_ID_MP3: - rtp_send_mpegaudio(s1, pkt->data, size); - break; - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - ff_rtp_send_mpegvideo(s1, pkt->data, size); - break; - case CODEC_ID_AAC: - ff_rtp_send_aac(s1, pkt->data, size); - break; - case CODEC_ID_AMR_NB: - case CODEC_ID_AMR_WB: - ff_rtp_send_amr(s1, pkt->data, size); - break; - case CODEC_ID_MPEG2TS: - rtp_send_mpegts_raw(s1, pkt->data, size); - break; - case CODEC_ID_H264: - ff_rtp_send_h264(s1, pkt->data, size); - break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - ff_rtp_send_h263(s1, pkt->data, size); - break; - default: - /* better than nothing : send the codec raw data */ - rtp_send_raw(s1, pkt->data, size); - break; - } - return 0; -} - -static int rtp_write_trailer(AVFormatContext *s1) -{ - RTPMuxContext *s = s1->priv_data; - - av_freep(&s->buf); - - return 0; -} - -AVOutputFormat rtp_muxer = { - "rtp", - NULL_IF_CONFIG_SMALL("RTP output format"), - NULL, - NULL, - sizeof(RTPMuxContext), - CODEC_ID_PCM_MULAW, - CODEC_ID_NONE, - rtp_write_header, - rtp_write_packet, - rtp_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rtpenc.h b/tizen/distrib/ffmpeg/libavformat/rtpenc.h deleted file mode 100644 index 5710160..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpenc.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * RTP muxer definitions - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVFORMAT_RTPENC_H -#define AVFORMAT_RTPENC_H - -#include "avformat.h" -#include "rtp.h" - -struct RTPMuxContext { - AVFormatContext *ic; - AVStream *st; - int payload_type; - uint32_t ssrc; - uint16_t seq; - uint32_t timestamp; - uint32_t base_timestamp; - uint32_t cur_timestamp; - int max_payload_size; - int num_frames; - - /* rtcp sender statistics receive */ - int64_t last_rtcp_ntp_time; // TODO: move into statistics - int64_t first_rtcp_ntp_time; // TODO: move into statistics - - /* rtcp sender statistics */ - unsigned int packet_count; // TODO: move into statistics (outgoing) - unsigned int octet_count; // TODO: move into statistics (outgoing) - unsigned int last_octet_count; // TODO: move into statistics (outgoing) - int first_packet; - /* buffer for output */ - uint8_t *buf; - uint8_t *buf_ptr; - - int max_frames_per_packet; -}; - -typedef struct RTPMuxContext RTPMuxContext; - -void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m); - -void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size); -void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size); -void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size); -void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size); -void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size); - -#endif /* AVFORMAT_RTPENC_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtpenc_aac.c b/tizen/distrib/ffmpeg/libavformat/rtpenc_aac.c deleted file mode 100644 index e19b286..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpenc_aac.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * copyright (c) 2007 Luca Abeni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "rtpenc.h" - - -void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size) -{ - RTPMuxContext *s = s1->priv_data; - int len, max_packet_size; - uint8_t *p; - const int max_frames_per_packet = s->max_frames_per_packet ? s->max_frames_per_packet : 5; - const int max_au_headers_size = 2 + 2 * max_frames_per_packet; - - /* skip ADTS header, if present */ - if ((s1->streams[0]->codec->extradata_size) == 0) { - size -= 7; - buff += 7; - } - max_packet_size = s->max_payload_size - max_au_headers_size; - - /* test if the packet must be sent */ - len = (s->buf_ptr - s->buf); - if ((s->num_frames == max_frames_per_packet) || (len && (len + size) > s->max_payload_size)) { - int au_size = s->num_frames * 2; - - p = s->buf + max_au_headers_size - au_size - 2; - if (p != s->buf) { - memmove(p + 2, s->buf + 2, au_size); - } - /* Write the AU header size */ - p[0] = ((au_size * 8) & 0xFF) >> 8; - p[1] = (au_size * 8) & 0xFF; - - ff_rtp_send_data(s1, p, s->buf_ptr - p, 1); - - s->num_frames = 0; - } - if (s->num_frames == 0) { - s->buf_ptr = s->buf + max_au_headers_size; - s->timestamp = s->cur_timestamp; - } - - if (size <= max_packet_size) { - p = s->buf + s->num_frames++ * 2 + 2; - *p++ = size >> 5; - *p = (size & 0x1F) << 3; - memcpy(s->buf_ptr, buff, size); - s->buf_ptr += size; - } else { - int au_size = size; - - max_packet_size = s->max_payload_size - 4; - p = s->buf; - p[0] = 0; - p[1] = 16; - while (size > 0) { - len = FFMIN(size, max_packet_size); - p[2] = au_size >> 5; - p[3] = (au_size & 0x1F) << 3; - memcpy(p + 4, buff, len); - ff_rtp_send_data(s1, p, len + 4, len == size); - size -= len; - buff += len; - } - } -} diff --git a/tizen/distrib/ffmpeg/libavformat/rtpenc_amr.c b/tizen/distrib/ffmpeg/libavformat/rtpenc_amr.c deleted file mode 100644 index 367789f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpenc_amr.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * RTP packetization for AMR audio - * Copyright (c) 2007 Luca Abeni - * Copyright (c) 2009 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "rtpenc.h" - -/** - * Packetize AMR frames into RTP packets according to RFC 3267, - * in octet-aligned mode. - */ -void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size) -{ - RTPMuxContext *s = s1->priv_data; - int max_header_toc_size = 1 + s->max_frames_per_packet; - uint8_t *p; - int len; - - /* Test if the packet must be sent. */ - len = s->buf_ptr - s->buf; - if (s->num_frames == s->max_frames_per_packet || (len && len + size - 1 > s->max_payload_size)) { - int header_size = s->num_frames + 1; - p = s->buf + max_header_toc_size - header_size; - if (p != s->buf) - memmove(p, s->buf, header_size); - - ff_rtp_send_data(s1, p, s->buf_ptr - p, 1); - - s->num_frames = 0; - } - - if (!s->num_frames) { - s->buf[0] = 0xf0; - s->buf_ptr = s->buf + max_header_toc_size; - s->timestamp = s->cur_timestamp; - } else { - /* Mark the previous TOC entry as having more entries following. */ - s->buf[1 + s->num_frames - 1] |= 0x80; - } - - /* Copy the frame type and quality bits. */ - s->buf[1 + s->num_frames++] = buff[0] & 0x7C; - buff++; - size--; - memcpy(s->buf_ptr, buff, size); - s->buf_ptr += size; -} - diff --git a/tizen/distrib/ffmpeg/libavformat/rtpenc_h263.c b/tizen/distrib/ffmpeg/libavformat/rtpenc_h263.c deleted file mode 100644 index 84403a1..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpenc_h263.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * RTP packetization for H.263 video - * Copyright (c) 2009 Luca Abeni - * Copyright (c) 2009 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "rtpenc.h" - -static const uint8_t *find_resync_marker_reverse(const uint8_t *restrict start, - const uint8_t *restrict end) -{ - const uint8_t *p = end - 1; - start += 1; /* Make sure we never return the original start. */ - for (; p > start; p -= 2) { - if (!*p) { - if (!p[ 1] && p[2]) return p; - else if (!p[-1] && p[1]) return p - 1; - } - } - return end; -} - -/** - * Packetize H.263 frames into RTP packets according to RFC 4629 - */ -void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size) -{ - RTPMuxContext *s = s1->priv_data; - int len, max_packet_size; - uint8_t *q; - - max_packet_size = s->max_payload_size; - - while (size > 0) { - q = s->buf; - if (size >= 2 && (buf1[0] == 0) && (buf1[1] == 0)) { - *q++ = 0x04; - buf1 += 2; - size -= 2; - } else { - *q++ = 0; - } - *q++ = 0; - - len = FFMIN(max_packet_size - 2, size); - - /* Look for a better place to split the frame into packets. */ - if (len < size) { - const uint8_t *end = find_resync_marker_reverse(buf1, buf1 + len); - len = end - buf1; - } - - memcpy(q, buf1, len); - q += len; - - /* 90 KHz time stamp */ - s->timestamp = s->cur_timestamp; - ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size)); - - buf1 += len; - size -= len; - } -} diff --git a/tizen/distrib/ffmpeg/libavformat/rtpenc_h264.c b/tizen/distrib/ffmpeg/libavformat/rtpenc_h264.c deleted file mode 100644 index 697def6..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpenc_h264.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * RTP packetization for H.264 (RFC3984) - * Copyright (c) 2008 Luca Abeni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief H.264 packetization - * @author Luca Abeni - */ - -#include "avformat.h" -#include "avc.h" -#include "rtpenc.h" - -static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last) -{ - RTPMuxContext *s = s1->priv_data; - - av_log(s1, AV_LOG_DEBUG, "Sending NAL %x of len %d M=%d\n", buf[0] & 0x1F, size, last); - if (size <= s->max_payload_size) { - ff_rtp_send_data(s1, buf, size, last); - } else { - uint8_t type = buf[0] & 0x1F; - uint8_t nri = buf[0] & 0x60; - - av_log(s1, AV_LOG_DEBUG, "NAL size %d > %d\n", size, s->max_payload_size); - s->buf[0] = 28; /* FU Indicator; Type = 28 ---> FU-A */ - s->buf[0] |= nri; - s->buf[1] = type; - s->buf[1] |= 1 << 7; - buf += 1; - size -= 1; - while (size + 2 > s->max_payload_size) { - memcpy(&s->buf[2], buf, s->max_payload_size - 2); - ff_rtp_send_data(s1, s->buf, s->max_payload_size, 0); - buf += s->max_payload_size - 2; - size -= s->max_payload_size - 2; - s->buf[1] &= ~(1 << 7); - } - s->buf[1] |= 1 << 6; - memcpy(&s->buf[2], buf, size); - ff_rtp_send_data(s1, s->buf, size + 2, last); - } -} - -void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size) -{ - const uint8_t *r; - RTPMuxContext *s = s1->priv_data; - - s->timestamp = s->cur_timestamp; - r = ff_avc_find_startcode(buf1, buf1 + size); - while (r < buf1 + size) { - const uint8_t *r1; - - while(!*(r++)); - r1 = ff_avc_find_startcode(r, buf1 + size); - nal_send(s1, r, r1 - r, (r1 == buf1 + size)); - r = r1; - } -} diff --git a/tizen/distrib/ffmpeg/libavformat/rtpenc_mpv.c b/tizen/distrib/ffmpeg/libavformat/rtpenc_mpv.c deleted file mode 100644 index b23c8f8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpenc_mpv.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * RTP packetization for MPEG video - * Copyright (c) 2002 Fabrice Bellard - * Copyright (c) 2007 Luca Abeni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/mpegvideo.h" -#include "avformat.h" -#include "rtpenc.h" - -/* NOTE: a single frame must be passed with sequence header if - needed. XXX: use slices. */ -void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size) -{ - RTPMuxContext *s = s1->priv_data; - int len, h, max_packet_size; - uint8_t *q; - const uint8_t *end = buf1 + size; - int begin_of_slice, end_of_slice, frame_type, temporal_reference; - - max_packet_size = s->max_payload_size; - begin_of_slice = 1; - end_of_slice = 0; - frame_type = 0; - temporal_reference = 0; - - while (size > 0) { - int begin_of_sequence; - - begin_of_sequence = 0; - len = max_packet_size - 4; - - if (len >= size) { - len = size; - end_of_slice = 1; - } else { - const uint8_t *r, *r1; - int start_code; - - r1 = buf1; - while (1) { - start_code = -1; - r = ff_find_start_code(r1, end, &start_code); - if((start_code & 0xFFFFFF00) == 0x100) { - /* New start code found */ - if (start_code == 0x100) { - frame_type = (r[1] & 0x38) >> 3; - temporal_reference = (int)r[0] << 2 | r[1] >> 6; - } - if (start_code == 0x1B8) { - begin_of_sequence = 1; - } - - if (r - buf1 - 4 <= len) { - /* The current slice fits in the packet */ - if (begin_of_slice == 0) { - /* no slice at the beginning of the packet... */ - end_of_slice = 1; - len = r - buf1 - 4; - break; - } - r1 = r; - } else { - if ((r1 - buf1 > 4) && (r - r1 < max_packet_size)) { - len = r1 - buf1 - 4; - end_of_slice = 1; - } - break; - } - } else { - break; - } - } - } - - h = 0; - h |= temporal_reference << 16; - h |= begin_of_sequence << 13; - h |= begin_of_slice << 12; - h |= end_of_slice << 11; - h |= frame_type << 8; - - q = s->buf; - *q++ = h >> 24; - *q++ = h >> 16; - *q++ = h >> 8; - *q++ = h; - - memcpy(q, buf1, len); - q += len; - - /* 90kHz time stamp */ - s->timestamp = s->cur_timestamp; - ff_rtp_send_data(s1, s->buf, q - s->buf, (len == size)); - - buf1 += len; - size -= len; - begin_of_slice = end_of_slice; - end_of_slice = 0; - } -} - - diff --git a/tizen/distrib/ffmpeg/libavformat/rtpproto.c b/tizen/distrib/ffmpeg/libavformat/rtpproto.c deleted file mode 100644 index 754908c..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtpproto.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * RTP network protocol - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * RTP protocol - */ - -#include "libavutil/avstring.h" -#include "avformat.h" -#include "rtpdec.h" - -#include -#include -#include "internal.h" -#include "network.h" -#include "os_support.h" -#include -#if HAVE_SYS_SELECT_H -#include -#endif -#include - -#define RTP_TX_BUF_SIZE (64 * 1024) -#define RTP_RX_BUF_SIZE (128 * 1024) - -typedef struct RTPContext { - URLContext *rtp_hd, *rtcp_hd; - int rtp_fd, rtcp_fd; -} RTPContext; - -/** - * If no filename is given to av_open_input_file because you want to - * get the local port first, then you must call this function to set - * the remote server address. - * - * @param s1 media file context - * @param uri of the remote server - * @return zero if no error. - */ - -int rtp_set_remote_url(URLContext *h, const char *uri) -{ - RTPContext *s = h->priv_data; - char hostname[256]; - int port; - - char buf[1024]; - char path[1024]; - - ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, - path, sizeof(path), uri); - - ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port, "%s", path); - udp_set_remote_url(s->rtp_hd, buf); - - ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port + 1, "%s", path); - udp_set_remote_url(s->rtcp_hd, buf); - return 0; -} - - -/** - * add option to url of the form: - * "http://host:port/path?option1=val1&option2=val2... - */ - -static void url_add_option(char *buf, int buf_size, const char *fmt, ...) -{ - char buf1[1024]; - va_list ap; - - va_start(ap, fmt); - if (strchr(buf, '?')) - av_strlcat(buf, "&", buf_size); - else - av_strlcat(buf, "?", buf_size); - vsnprintf(buf1, sizeof(buf1), fmt, ap); - av_strlcat(buf, buf1, buf_size); - va_end(ap); -} - -static void build_udp_url(char *buf, int buf_size, - const char *hostname, int port, - int local_port, int ttl, - int max_packet_size) -{ - ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL); - if (local_port >= 0) - url_add_option(buf, buf_size, "localport=%d", local_port); - if (ttl >= 0) - url_add_option(buf, buf_size, "ttl=%d", ttl); - if (max_packet_size >=0) - url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size); -} - -/** - * url syntax: rtp://host:port[?option=val...] - * option: 'ttl=n' : set the ttl value (for multicast only) - * 'rtcpport=n' : set the remote rtcp port to n - * 'localrtpport=n' : set the local rtp port to n - * 'localrtcpport=n' : set the local rtcp port to n - * 'pkt_size=n' : set max packet size - * deprecated option: - * 'localport=n' : set the local port to n - * - * if rtcpport isn't set the rtcp port will be the rtp port + 1 - * if local rtp port isn't set any available port will be used for the local - * rtp and rtcp ports - * if the local rtcp port is not set it will be the local rtp port + 1 - */ - -static int rtp_open(URLContext *h, const char *uri, int flags) -{ - RTPContext *s; - int rtp_port, rtcp_port, - is_output, ttl, - local_rtp_port, local_rtcp_port, max_packet_size; - char hostname[256]; - char buf[1024]; - char path[1024]; - const char *p; - - is_output = (flags & URL_WRONLY); - - s = av_mallocz(sizeof(RTPContext)); - if (!s) - return AVERROR(ENOMEM); - h->priv_data = s; - - ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port, - path, sizeof(path), uri); - /* extract parameters */ - ttl = -1; - rtcp_port = rtp_port+1; - local_rtp_port = -1; - local_rtcp_port = -1; - max_packet_size = -1; - - p = strchr(uri, '?'); - if (p) { - if (find_info_tag(buf, sizeof(buf), "ttl", p)) { - ttl = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "rtcpport", p)) { - rtcp_port = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "localport", p)) { - local_rtp_port = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "localrtpport", p)) { - local_rtp_port = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "localrtcpport", p)) { - local_rtcp_port = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) { - max_packet_size = strtol(buf, NULL, 10); - } - } - - build_udp_url(buf, sizeof(buf), - hostname, rtp_port, local_rtp_port, ttl, max_packet_size); - if (url_open(&s->rtp_hd, buf, flags) < 0) - goto fail; - if (local_rtp_port>=0 && local_rtcp_port<0) - local_rtcp_port = udp_get_local_port(s->rtp_hd) + 1; - - build_udp_url(buf, sizeof(buf), - hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size); - if (url_open(&s->rtcp_hd, buf, flags) < 0) - goto fail; - - /* just to ease handle access. XXX: need to suppress direct handle - access */ - s->rtp_fd = url_get_file_handle(s->rtp_hd); - s->rtcp_fd = url_get_file_handle(s->rtcp_hd); - - h->max_packet_size = url_get_max_packet_size(s->rtp_hd); - h->is_streamed = 1; - return 0; - - fail: - if (s->rtp_hd) - url_close(s->rtp_hd); - if (s->rtcp_hd) - url_close(s->rtcp_hd); - av_free(s); - return AVERROR(EIO); -} - -static int rtp_read(URLContext *h, uint8_t *buf, int size) -{ - RTPContext *s = h->priv_data; - struct sockaddr_in from; - socklen_t from_len; - int len, fd_max, n; - fd_set rfds; - struct timeval tv; -#if 0 - for(;;) { - from_len = sizeof(from); - len = recvfrom (s->rtp_fd, buf, size, 0, - (struct sockaddr *)&from, &from_len); - if (len < 0) { - if (ff_neterrno() == FF_NETERROR(EAGAIN) || - ff_neterrno() == FF_NETERROR(EINTR)) - continue; - return AVERROR(EIO); - } - break; - } -#else - for(;;) { - if (url_interrupt_cb()) - return AVERROR(EINTR); - /* build fdset to listen to RTP and RTCP packets */ - FD_ZERO(&rfds); - fd_max = s->rtp_fd; - FD_SET(s->rtp_fd, &rfds); - if (s->rtcp_fd > fd_max) - fd_max = s->rtcp_fd; - FD_SET(s->rtcp_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - n = select(fd_max + 1, &rfds, NULL, NULL, &tv); - if (n > 0) { - /* first try RTCP */ - if (FD_ISSET(s->rtcp_fd, &rfds)) { - from_len = sizeof(from); - len = recvfrom (s->rtcp_fd, buf, size, 0, - (struct sockaddr *)&from, &from_len); - if (len < 0) { - if (ff_neterrno() == FF_NETERROR(EAGAIN) || - ff_neterrno() == FF_NETERROR(EINTR)) - continue; - return AVERROR(EIO); - } - break; - } - /* then RTP */ - if (FD_ISSET(s->rtp_fd, &rfds)) { - from_len = sizeof(from); - len = recvfrom (s->rtp_fd, buf, size, 0, - (struct sockaddr *)&from, &from_len); - if (len < 0) { - if (ff_neterrno() == FF_NETERROR(EAGAIN) || - ff_neterrno() == FF_NETERROR(EINTR)) - continue; - return AVERROR(EIO); - } - break; - } - } else if (n < 0) { - if (ff_neterrno() == FF_NETERROR(EINTR)) - continue; - return AVERROR(EIO); - } - } -#endif - return len; -} - -static int rtp_write(URLContext *h, uint8_t *buf, int size) -{ - RTPContext *s = h->priv_data; - int ret; - URLContext *hd; - - if (buf[1] >= 200 && buf[1] <= 204) { - /* RTCP payload type */ - hd = s->rtcp_hd; - } else { - /* RTP payload type */ - hd = s->rtp_hd; - } - - ret = url_write(hd, buf, size); -#if 0 - { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 10 * 1000000; - nanosleep(&ts, NULL); - } -#endif - return ret; -} - -static int rtp_close(URLContext *h) -{ - RTPContext *s = h->priv_data; - - url_close(s->rtp_hd); - url_close(s->rtcp_hd); - av_free(s); - return 0; -} - -/** - * Return the local rtp port used by the RTP connection - * @param s1 media file context - * @return the local port number - */ - -int rtp_get_local_rtp_port(URLContext *h) -{ - RTPContext *s = h->priv_data; - return udp_get_local_port(s->rtp_hd); -} - -/** - * Return the local rtp port used by the RTP connection - * @param s1 media file context - * @return the local port number - */ - -int rtp_get_local_port(URLContext *h) -{ - RTPContext *s = h->priv_data; - return udp_get_local_port(s->rtp_hd); -} - -/** - * Return the local rtcp port used by the RTP connection - * @param s1 media file context - * @return the local port number - */ - -int rtp_get_local_rtcp_port(URLContext *h) -{ - RTPContext *s = h->priv_data; - return udp_get_local_port(s->rtcp_hd); -} - -#if (LIBAVFORMAT_VERSION_MAJOR <= 52) -/** - * Return the rtp and rtcp file handles for select() usage to wait for - * several RTP streams at the same time. - * @param h media file context - */ - -void rtp_get_file_handles(URLContext *h, int *prtp_fd, int *prtcp_fd) -{ - RTPContext *s = h->priv_data; - - *prtp_fd = s->rtp_fd; - *prtcp_fd = s->rtcp_fd; -} -#endif - -static int rtp_get_file_handle(URLContext *h) -{ - RTPContext *s = h->priv_data; - return s->rtp_fd; -} - -URLProtocol rtp_protocol = { - "rtp", - rtp_open, - rtp_read, - rtp_write, - NULL, /* seek */ - rtp_close, - .url_get_file_handle = rtp_get_file_handle, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rtsp.c b/tizen/distrib/ffmpeg/libavformat/rtsp.c deleted file mode 100644 index 6dbd796..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtsp.c +++ /dev/null @@ -1,2091 +0,0 @@ -/* - * RTSP/SDP client - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/base64.h" -#include "libavutil/avstring.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#include -#if HAVE_SYS_SELECT_H -#include -#endif -#include -#include "internal.h" -#include "network.h" -#include "os_support.h" -#include "rtsp.h" - -#include "rtpdec.h" -#include "rdt.h" -#include "rtpdec_asf.h" - -//#define DEBUG -//#define DEBUG_RTP_TCP - -#if LIBAVFORMAT_VERSION_INT < (53 << 16) -int rtsp_default_protocols = (1 << RTSP_LOWER_TRANSPORT_UDP); -#endif - -/* Timeout values for socket select, in ms, - * and read_packet(), in seconds */ -#define SELECT_TIMEOUT_MS 100 -#define READ_PACKET_TIMEOUT_S 10 -#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / SELECT_TIMEOUT_MS - -#define SPACE_CHARS " \t\r\n" -/* we use memchr() instead of strchr() here because strchr() will return - * the terminating '\0' of SPACE_CHARS instead of NULL if c is '\0'. */ -#define redir_isspace(c) memchr(SPACE_CHARS, c, 4) -static void skip_spaces(const char **pp) -{ - const char *p; - p = *pp; - while (redir_isspace(*p)) - p++; - *pp = p; -} - -static void get_word_until_chars(char *buf, int buf_size, - const char *sep, const char **pp) -{ - const char *p; - char *q; - - p = *pp; - skip_spaces(&p); - q = buf; - while (!strchr(sep, *p) && *p != '\0') { - if ((q - buf) < buf_size - 1) - *q++ = *p; - p++; - } - if (buf_size > 0) - *q = '\0'; - *pp = p; -} - -static void get_word_sep(char *buf, int buf_size, const char *sep, - const char **pp) -{ - if (**pp == '/') (*pp)++; - get_word_until_chars(buf, buf_size, sep, pp); -} - -static void get_word(char *buf, int buf_size, const char **pp) -{ - get_word_until_chars(buf, buf_size, SPACE_CHARS, pp); -} - -/* parse the rtpmap description: /[/] */ -static int sdp_parse_rtpmap(AVFormatContext *s, - AVCodecContext *codec, RTSPStream *rtsp_st, - int payload_type, const char *p) -{ - char buf[256]; - int i; - AVCodec *c; - const char *c_name; - - /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and - * see if we can handle this kind of payload. - * The space should normally not be there but some Real streams or - * particular servers ("RealServer Version 6.1.3.970", see issue 1658) - * have a trailing space. */ - get_word_sep(buf, sizeof(buf), "/ ", &p); - if (payload_type >= RTP_PT_PRIVATE) { - RTPDynamicProtocolHandler *handler; - for (handler = RTPFirstDynamicPayloadHandler; - handler; handler = handler->next) { - if (!strcasecmp(buf, handler->enc_name) && - codec->codec_type == handler->codec_type) { - codec->codec_id = handler->codec_id; - rtsp_st->dynamic_handler = handler; - if (handler->open) - rtsp_st->dynamic_protocol_context = handler->open(); - break; - } - } - } else { - /* We are in a standard case - * (from http://www.iana.org/assignments/rtp-parameters). */ - /* search into AVRtpPayloadTypes[] */ - codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type); - } - - c = avcodec_find_decoder(codec->codec_id); - if (c && c->name) - c_name = c->name; - else - c_name = "(null)"; - - get_word_sep(buf, sizeof(buf), "/", &p); - i = atoi(buf); - switch (codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name); - codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE; - codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS; - if (i > 0) { - codec->sample_rate = i; - get_word_sep(buf, sizeof(buf), "/", &p); - i = atoi(buf); - if (i > 0) - codec->channels = i; - // TODO: there is a bug here; if it is a mono stream, and - // less than 22000Hz, faad upconverts to stereo and twice - // the frequency. No problem, but the sample rate is being - // set here by the sdp line. Patch on its way. (rdm) - } - av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n", - codec->sample_rate); - av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n", - codec->channels); - break; - case AVMEDIA_TYPE_VIDEO: - av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name); - break; - default: - break; - } - return 0; -} - -/* return the length and optionally the data */ -static int hex_to_data(uint8_t *data, const char *p) -{ - int c, len, v; - - len = 0; - v = 1; - for (;;) { - skip_spaces(&p); - if (*p == '\0') - break; - c = toupper((unsigned char) *p++); - if (c >= '0' && c <= '9') - c = c - '0'; - else if (c >= 'A' && c <= 'F') - c = c - 'A' + 10; - else - break; - v = (v << 4) | c; - if (v & 0x100) { - if (data) - data[len] = v; - len++; - v = 1; - } - } - return len; -} - -static void sdp_parse_fmtp_config(AVCodecContext * codec, void *ctx, - char *attr, char *value) -{ - switch (codec->codec_id) { - case CODEC_ID_MPEG4: - case CODEC_ID_AAC: - if (!strcmp(attr, "config")) { - /* decode the hexa encoded parameter */ - int len = hex_to_data(NULL, value); - if (codec->extradata) - av_free(codec->extradata); - codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); - if (!codec->extradata) - return; - codec->extradata_size = len; - hex_to_data(codec->extradata, value); - } - break; - default: - break; - } - return; -} - -typedef struct { - const char *str; - uint16_t type; - uint32_t offset; -} AttrNameMap; - -/* All known fmtp parameters and the corresponding RTPAttrTypeEnum */ -#define ATTR_NAME_TYPE_INT 0 -#define ATTR_NAME_TYPE_STR 1 -static const AttrNameMap attr_names[]= -{ - { "SizeLength", ATTR_NAME_TYPE_INT, - offsetof(RTPPayloadData, sizelength) }, - { "IndexLength", ATTR_NAME_TYPE_INT, - offsetof(RTPPayloadData, indexlength) }, - { "IndexDeltaLength", ATTR_NAME_TYPE_INT, - offsetof(RTPPayloadData, indexdeltalength) }, - { "profile-level-id", ATTR_NAME_TYPE_INT, - offsetof(RTPPayloadData, profile_level_id) }, - { "StreamType", ATTR_NAME_TYPE_INT, - offsetof(RTPPayloadData, streamtype) }, - { "mode", ATTR_NAME_TYPE_STR, - offsetof(RTPPayloadData, mode) }, - { NULL, -1, -1 }, -}; - -/* parse the attribute line from the fmtp a line of an sdp response. This - * is broken out as a function because it is used in rtp_h264.c, which is - * forthcoming. */ -int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, - char *value, int value_size) -{ - skip_spaces(p); - if (**p) { - get_word_sep(attr, attr_size, "=", p); - if (**p == '=') - (*p)++; - get_word_sep(value, value_size, ";", p); - if (**p == ';') - (*p)++; - return 1; - } - return 0; -} - -/* parse a SDP line and save stream attributes */ -static void sdp_parse_fmtp(AVStream *st, const char *p) -{ - char attr[256]; - /* Vorbis setup headers can be up to 12KB and are sent base64 - * encoded, giving a 12KB * (4/3) = 16KB FMTP line. */ - char value[16384]; - int i; - RTSPStream *rtsp_st = st->priv_data; - AVCodecContext *codec = st->codec; - RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data; - - /* loop on each attribute */ - while (ff_rtsp_next_attr_and_value(&p, attr, sizeof(attr), - value, sizeof(value))) { - /* grab the codec extra_data from the config parameter of the fmtp - * line */ - sdp_parse_fmtp_config(codec, rtsp_st->dynamic_protocol_context, - attr, value); - /* Looking for a known attribute */ - for (i = 0; attr_names[i].str; ++i) { - if (!strcasecmp(attr, attr_names[i].str)) { - if (attr_names[i].type == ATTR_NAME_TYPE_INT) { - *(int *)((char *)rtp_payload_data + - attr_names[i].offset) = atoi(value); - } else if (attr_names[i].type == ATTR_NAME_TYPE_STR) - *(char **)((char *)rtp_payload_data + - attr_names[i].offset) = av_strdup(value); - } - } - } -} - -/** Parse a string p in the form of Range:npt=xx-xx, and determine the start - * and end time. - * Used for seeking in the rtp stream. - */ -static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end) -{ - char buf[256]; - - skip_spaces(&p); - if (!av_stristart(p, "npt=", &p)) - return; - - *start = AV_NOPTS_VALUE; - *end = AV_NOPTS_VALUE; - - get_word_sep(buf, sizeof(buf), "-", &p); - *start = parse_date(buf, 1); - if (*p == '-') { - p++; - get_word_sep(buf, sizeof(buf), "-", &p); - *end = parse_date(buf, 1); - } -// av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start); -// av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end); -} - -typedef struct SDPParseState { - /* SDP only */ - struct in_addr default_ip; - int default_ttl; - int skip_media; ///< set if an unknown m= line occurs -} SDPParseState; - -static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, - int letter, const char *buf) -{ - RTSPState *rt = s->priv_data; - char buf1[64], st_type[64]; - const char *p; - enum AVMediaType codec_type; - int payload_type, i; - AVStream *st; - RTSPStream *rtsp_st; - struct in_addr sdp_ip; - int ttl; - - dprintf(s, "sdp: %c='%s'\n", letter, buf); - - p = buf; - if (s1->skip_media && letter != 'm') - return; - switch (letter) { - case 'c': - get_word(buf1, sizeof(buf1), &p); - if (strcmp(buf1, "IN") != 0) - return; - get_word(buf1, sizeof(buf1), &p); - if (strcmp(buf1, "IP4") != 0) - return; - get_word_sep(buf1, sizeof(buf1), "/", &p); - if (ff_inet_aton(buf1, &sdp_ip) == 0) - return; - ttl = 16; - if (*p == '/') { - p++; - get_word_sep(buf1, sizeof(buf1), "/", &p); - ttl = atoi(buf1); - } - if (s->nb_streams == 0) { - s1->default_ip = sdp_ip; - s1->default_ttl = ttl; - } else { - st = s->streams[s->nb_streams - 1]; - rtsp_st = st->priv_data; - rtsp_st->sdp_ip = sdp_ip; - rtsp_st->sdp_ttl = ttl; - } - break; - case 's': - av_metadata_set2(&s->metadata, "title", p, 0); - break; - case 'i': - if (s->nb_streams == 0) { - av_metadata_set2(&s->metadata, "comment", p, 0); - break; - } - break; - case 'm': - /* new stream */ - s1->skip_media = 0; - get_word(st_type, sizeof(st_type), &p); - if (!strcmp(st_type, "audio")) { - codec_type = AVMEDIA_TYPE_AUDIO; - } else if (!strcmp(st_type, "video")) { - codec_type = AVMEDIA_TYPE_VIDEO; - } else if (!strcmp(st_type, "application")) { - codec_type = AVMEDIA_TYPE_DATA; - } else { - s1->skip_media = 1; - return; - } - rtsp_st = av_mallocz(sizeof(RTSPStream)); - if (!rtsp_st) - return; - rtsp_st->stream_index = -1; - dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); - - rtsp_st->sdp_ip = s1->default_ip; - rtsp_st->sdp_ttl = s1->default_ttl; - - get_word(buf1, sizeof(buf1), &p); /* port */ - rtsp_st->sdp_port = atoi(buf1); - - get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */ - - /* XXX: handle list of formats */ - get_word(buf1, sizeof(buf1), &p); /* format list */ - rtsp_st->sdp_payload_type = atoi(buf1); - - if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) { - /* no corresponding stream */ - } else { - st = av_new_stream(s, 0); - if (!st) - return; - st->priv_data = rtsp_st; - rtsp_st->stream_index = st->index; - st->codec->codec_type = codec_type; - if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) { - /* if standard payload type, we can find the codec right now */ - ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type); - } - } - /* put a default control url */ - av_strlcpy(rtsp_st->control_url, rt->control_uri, - sizeof(rtsp_st->control_url)); - break; - case 'a': - if (av_strstart(p, "control:", &p)) { - if (s->nb_streams == 0) { - if (!strncmp(p, "rtsp://", 7)) - av_strlcpy(rt->control_uri, p, - sizeof(rt->control_uri)); - } else { - char proto[32]; - /* get the control url */ - st = s->streams[s->nb_streams - 1]; - rtsp_st = st->priv_data; - - /* XXX: may need to add full url resolution */ - ff_url_split(proto, sizeof(proto), NULL, 0, NULL, 0, - NULL, NULL, 0, p); - if (proto[0] == '\0') { - /* relative control URL */ - if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/') - av_strlcat(rtsp_st->control_url, "/", - sizeof(rtsp_st->control_url)); - av_strlcat(rtsp_st->control_url, p, - sizeof(rtsp_st->control_url)); - } else - av_strlcpy(rtsp_st->control_url, p, - sizeof(rtsp_st->control_url)); - } - } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) { - /* NOTE: rtpmap is only supported AFTER the 'm=' tag */ - get_word(buf1, sizeof(buf1), &p); - payload_type = atoi(buf1); - st = s->streams[s->nb_streams - 1]; - rtsp_st = st->priv_data; - sdp_parse_rtpmap(s, st->codec, rtsp_st, payload_type, p); - } else if (av_strstart(p, "fmtp:", &p)) { - /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */ - get_word(buf1, sizeof(buf1), &p); - payload_type = atoi(buf1); - for (i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st->sdp_payload_type == payload_type) { - if (!(rtsp_st->dynamic_handler && - rtsp_st->dynamic_handler->parse_sdp_a_line && - rtsp_st->dynamic_handler->parse_sdp_a_line(s, - i, rtsp_st->dynamic_protocol_context, buf))) - sdp_parse_fmtp(st, p); - } - } - } else if (av_strstart(p, "framesize:", &p)) { - // let dynamic protocol handlers have a stab at the line. - get_word(buf1, sizeof(buf1), &p); - payload_type = atoi(buf1); - for (i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st->sdp_payload_type == payload_type && - rtsp_st->dynamic_handler && - rtsp_st->dynamic_handler->parse_sdp_a_line) - rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, - rtsp_st->dynamic_protocol_context, buf); - } - } else if (av_strstart(p, "range:", &p)) { - int64_t start, end; - - // this is so that seeking on a streamed file can work. - rtsp_parse_range_npt(p, &start, &end); - s->start_time = start; - /* AV_NOPTS_VALUE means live broadcast (and can't seek) */ - s->duration = (end == AV_NOPTS_VALUE) ? - AV_NOPTS_VALUE : end - start; - } else if (av_strstart(p, "IsRealDataType:integer;",&p)) { - if (atoi(p) == 1) - rt->transport = RTSP_TRANSPORT_RDT; - } else { - if (rt->server_type == RTSP_SERVER_WMS) - ff_wms_parse_sdp_a_line(s, p); - if (s->nb_streams > 0) { - if (rt->server_type == RTSP_SERVER_REAL) - ff_real_parse_sdp_a_line(s, s->nb_streams - 1, p); - - rtsp_st = s->streams[s->nb_streams - 1]->priv_data; - if (rtsp_st->dynamic_handler && - rtsp_st->dynamic_handler->parse_sdp_a_line) - rtsp_st->dynamic_handler->parse_sdp_a_line(s, - s->nb_streams - 1, - rtsp_st->dynamic_protocol_context, buf); - } - } - break; - } -} - -static int sdp_parse(AVFormatContext *s, const char *content) -{ - const char *p; - int letter; - /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, - * contain long SDP lines containing complete ASF Headers (several - * kB) or arrays of MDPR (RM stream descriptor) headers plus - * "rulebooks" describing their properties. Therefore, the SDP line - * buffer is large. - * - * The Vorbis FMTP line can be up to 16KB - see sdp_parse_fmtp. */ - char buf[16384], *q; - SDPParseState sdp_parse_state, *s1 = &sdp_parse_state; - - memset(s1, 0, sizeof(SDPParseState)); - p = content; - for (;;) { - skip_spaces(&p); - letter = *p; - if (letter == '\0') - break; - p++; - if (*p != '=') - goto next_line; - p++; - /* get the content */ - q = buf; - while (*p != '\n' && *p != '\r' && *p != '\0') { - if ((q - buf) < sizeof(buf) - 1) - *q++ = *p; - p++; - } - *q = '\0'; - sdp_parse_line(s, s1, letter, buf); - next_line: - while (*p != '\n' && *p != '\0') - p++; - if (*p == '\n') - p++; - } - return 0; -} - -/* close and free RTSP streams */ -void ff_rtsp_close_streams(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - int i; - RTSPStream *rtsp_st; - - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rtsp_st = rt->rtsp_streams[i]; - if (rtsp_st) { - if (rtsp_st->transport_priv) { - if (s->oformat) { - AVFormatContext *rtpctx = rtsp_st->transport_priv; - av_write_trailer(rtpctx); - if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { - uint8_t *ptr; - url_close_dyn_buf(rtpctx->pb, &ptr); - av_free(ptr); - } else { - url_fclose(rtpctx->pb); - } - av_metadata_free(&rtpctx->streams[0]->metadata); - av_metadata_free(&rtpctx->metadata); - av_free(rtpctx->streams[0]); - av_free(rtpctx); - } else if (rt->transport == RTSP_TRANSPORT_RDT) - ff_rdt_parse_close(rtsp_st->transport_priv); - else - rtp_parse_close(rtsp_st->transport_priv); - } - if (rtsp_st->rtp_handle) - url_close(rtsp_st->rtp_handle); - if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) - rtsp_st->dynamic_handler->close( - rtsp_st->dynamic_protocol_context); - } - } - av_free(rt->rtsp_streams); - if (rt->asf_ctx) { - av_close_input_stream (rt->asf_ctx); - rt->asf_ctx = NULL; - } -} - -static void *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st, - URLContext *handle) -{ - RTSPState *rt = s->priv_data; - AVFormatContext *rtpctx; - int ret; - AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); - - if (!rtp_format) - return NULL; - - /* Allocate an AVFormatContext for each output stream */ - rtpctx = avformat_alloc_context(); - if (!rtpctx) - return NULL; - - rtpctx->oformat = rtp_format; - if (!av_new_stream(rtpctx, 0)) { - av_free(rtpctx); - return NULL; - } - /* Copy the max delay setting; the rtp muxer reads this. */ - rtpctx->max_delay = s->max_delay; - /* Copy other stream parameters. */ - rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; - - /* Set the synchronized start time. */ - rtpctx->start_time_realtime = rt->start_time; - - /* Remove the local codec, link to the original codec - * context instead, to give the rtp muxer access to - * codec parameters. */ - av_free(rtpctx->streams[0]->codec); - rtpctx->streams[0]->codec = st->codec; - - if (handle) { - url_fdopen(&rtpctx->pb, handle); - } else - url_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE); - ret = av_write_header(rtpctx); - - if (ret) { - if (handle) { - url_fclose(rtpctx->pb); - } else { - uint8_t *ptr; - url_close_dyn_buf(rtpctx->pb, &ptr); - av_free(ptr); - } - av_free(rtpctx->streams[0]); - av_free(rtpctx); - return NULL; - } - - /* Copy the RTP AVStream timebase back to the original AVStream */ - st->time_base = rtpctx->streams[0]->time_base; - return rtpctx; -} - -static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) -{ - RTSPState *rt = s->priv_data; - AVStream *st = NULL; - - /* open the RTP context */ - if (rtsp_st->stream_index >= 0) - st = s->streams[rtsp_st->stream_index]; - if (!st) - s->ctx_flags |= AVFMTCTX_NOHEADER; - - if (s->oformat) { - rtsp_st->transport_priv = rtsp_rtp_mux_open(s, st, rtsp_st->rtp_handle); - /* Ownership of rtp_handle is passed to the rtp mux context */ - rtsp_st->rtp_handle = NULL; - } else if (rt->transport == RTSP_TRANSPORT_RDT) - rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index, - rtsp_st->dynamic_protocol_context, - rtsp_st->dynamic_handler); - else - rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle, - rtsp_st->sdp_payload_type, - &rtsp_st->rtp_payload_data); - - if (!rtsp_st->transport_priv) { - return AVERROR(ENOMEM); - } else if (rt->transport != RTSP_TRANSPORT_RDT) { - if (rtsp_st->dynamic_handler) { - rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv, - rtsp_st->dynamic_protocol_context, - rtsp_st->dynamic_handler); - } - } - - return 0; -} - -#if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER -static int rtsp_probe(AVProbeData *p) -{ - if (av_strstart(p->filename, "rtsp:", NULL)) - return AVPROBE_SCORE_MAX; - return 0; -} - -static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp) -{ - const char *p; - int v; - - p = *pp; - skip_spaces(&p); - v = strtol(p, (char **)&p, 10); - if (*p == '-') { - p++; - *min_ptr = v; - v = strtol(p, (char **)&p, 10); - *max_ptr = v; - } else { - *min_ptr = v; - *max_ptr = v; - } - *pp = p; -} - -/* XXX: only one transport specification is parsed */ -static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p) -{ - char transport_protocol[16]; - char profile[16]; - char lower_transport[16]; - char parameter[16]; - RTSPTransportField *th; - char buf[256]; - - reply->nb_transports = 0; - - for (;;) { - skip_spaces(&p); - if (*p == '\0') - break; - - th = &reply->transports[reply->nb_transports]; - - get_word_sep(transport_protocol, sizeof(transport_protocol), - "/", &p); - if (!strcasecmp (transport_protocol, "rtp")) { - get_word_sep(profile, sizeof(profile), "/;,", &p); - lower_transport[0] = '\0'; - /* rtp/avp/ */ - if (*p == '/') { - get_word_sep(lower_transport, sizeof(lower_transport), - ";,", &p); - } - th->transport = RTSP_TRANSPORT_RTP; - } else if (!strcasecmp (transport_protocol, "x-pn-tng") || - !strcasecmp (transport_protocol, "x-real-rdt")) { - /* x-pn-tng/ */ - get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p); - profile[0] = '\0'; - th->transport = RTSP_TRANSPORT_RDT; - } - if (!strcasecmp(lower_transport, "TCP")) - th->lower_transport = RTSP_LOWER_TRANSPORT_TCP; - else - th->lower_transport = RTSP_LOWER_TRANSPORT_UDP; - - if (*p == ';') - p++; - /* get each parameter */ - while (*p != '\0' && *p != ',') { - get_word_sep(parameter, sizeof(parameter), "=;,", &p); - if (!strcmp(parameter, "port")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->port_min, &th->port_max, &p); - } - } else if (!strcmp(parameter, "client_port")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->client_port_min, - &th->client_port_max, &p); - } - } else if (!strcmp(parameter, "server_port")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->server_port_min, - &th->server_port_max, &p); - } - } else if (!strcmp(parameter, "interleaved")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->interleaved_min, - &th->interleaved_max, &p); - } - } else if (!strcmp(parameter, "multicast")) { - if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP) - th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST; - } else if (!strcmp(parameter, "ttl")) { - if (*p == '=') { - p++; - th->ttl = strtol(p, (char **)&p, 10); - } - } else if (!strcmp(parameter, "destination")) { - struct in_addr ipaddr; - - if (*p == '=') { - p++; - get_word_sep(buf, sizeof(buf), ";,", &p); - if (ff_inet_aton(buf, &ipaddr)) - th->destination = ntohl(ipaddr.s_addr); - } - } - while (*p != ';' && *p != '\0' && *p != ',') - p++; - if (*p == ';') - p++; - } - if (*p == ',') - p++; - - reply->nb_transports++; - } -} - -void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf, - HTTPAuthState *auth_state) -{ - const char *p; - - /* NOTE: we do case independent match for broken servers */ - p = buf; - if (av_stristart(p, "Session:", &p)) { - int t; - get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p); - if (av_stristart(p, ";timeout=", &p) && - (t = strtol(p, NULL, 10)) > 0) { - reply->timeout = t; - } - } else if (av_stristart(p, "Content-Length:", &p)) { - reply->content_length = strtol(p, NULL, 10); - } else if (av_stristart(p, "Transport:", &p)) { - rtsp_parse_transport(reply, p); - } else if (av_stristart(p, "CSeq:", &p)) { - reply->seq = strtol(p, NULL, 10); - } else if (av_stristart(p, "Range:", &p)) { - rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end); - } else if (av_stristart(p, "RealChallenge1:", &p)) { - skip_spaces(&p); - av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge)); - } else if (av_stristart(p, "Server:", &p)) { - skip_spaces(&p); - av_strlcpy(reply->server, p, sizeof(reply->server)); - } else if (av_stristart(p, "Notice:", &p) || - av_stristart(p, "X-Notice:", &p)) { - reply->notice = strtol(p, NULL, 10); - } else if (av_stristart(p, "Location:", &p)) { - skip_spaces(&p); - av_strlcpy(reply->location, p , sizeof(reply->location)); - } else if (av_stristart(p, "WWW-Authenticate:", &p) && auth_state) { - skip_spaces(&p); - ff_http_auth_handle_header(auth_state, "WWW-Authenticate", p); - } else if (av_stristart(p, "Authentication-Info:", &p) && auth_state) { - skip_spaces(&p); - ff_http_auth_handle_header(auth_state, "Authentication-Info", p); - } -} - -/* skip a RTP/TCP interleaved packet */ -void ff_rtsp_skip_packet(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - int ret, len, len1; - uint8_t buf[1024]; - - ret = url_read_complete(rt->rtsp_hd, buf, 3); - if (ret != 3) - return; - len = AV_RB16(buf + 1); - - dprintf(s, "skipping RTP packet len=%d\n", len); - - /* skip payload */ - while (len > 0) { - len1 = len; - if (len1 > sizeof(buf)) - len1 = sizeof(buf); - ret = url_read_complete(rt->rtsp_hd, buf, len1); - if (ret != len1) - return; - len -= len1; - } -} - -int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, - unsigned char **content_ptr, - int return_on_interleaved_data) -{ - RTSPState *rt = s->priv_data; - char buf[4096], buf1[1024], *q; - unsigned char ch; - const char *p; - int ret, content_length, line_count = 0; - unsigned char *content = NULL; - - memset(reply, 0, sizeof(*reply)); - - /* parse reply (XXX: use buffers) */ - rt->last_reply[0] = '\0'; - for (;;) { - q = buf; - for (;;) { - ret = url_read_complete(rt->rtsp_hd, &ch, 1); -#ifdef DEBUG_RTP_TCP - dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch); -#endif - if (ret != 1) - return -1; - if (ch == '\n') - break; - if (ch == '$') { - /* XXX: only parse it if first char on line ? */ - if (return_on_interleaved_data) { - return 1; - } else - ff_rtsp_skip_packet(s); - } else if (ch != '\r') { - if ((q - buf) < sizeof(buf) - 1) - *q++ = ch; - } - } - *q = '\0'; - - dprintf(s, "line='%s'\n", buf); - - /* test if last line */ - if (buf[0] == '\0') - break; - p = buf; - if (line_count == 0) { - /* get reply code */ - get_word(buf1, sizeof(buf1), &p); - get_word(buf1, sizeof(buf1), &p); - reply->status_code = atoi(buf1); - } else { - ff_rtsp_parse_line(reply, p, &rt->auth_state); - av_strlcat(rt->last_reply, p, sizeof(rt->last_reply)); - av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply)); - } - line_count++; - } - - if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0') - av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id)); - - content_length = reply->content_length; - if (content_length > 0) { - /* leave some room for a trailing '\0' (useful for simple parsing) */ - content = av_malloc(content_length + 1); - (void)url_read_complete(rt->rtsp_hd, content, content_length); - content[content_length] = '\0'; - } - if (content_ptr) - *content_ptr = content; - else - av_free(content); - - if (rt->seq != reply->seq) { - av_log(s, AV_LOG_WARNING, "CSeq %d expected, %d received.\n", - rt->seq, reply->seq); - } - - /* EOS */ - if (reply->notice == 2101 /* End-of-Stream Reached */ || - reply->notice == 2104 /* Start-of-Stream Reached */ || - reply->notice == 2306 /* Continuous Feed Terminated */) { - rt->state = RTSP_STATE_IDLE; - } else if (reply->notice >= 4400 && reply->notice < 5500) { - return AVERROR(EIO); /* data or server error */ - } else if (reply->notice == 2401 /* Ticket Expired */ || - (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ ) - return AVERROR(EPERM); - - return 0; -} - -void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, - const char *method, const char *url, - const char *headers, - const unsigned char *send_content, - int send_content_length) -{ - RTSPState *rt = s->priv_data; - char buf[4096]; - - rt->seq++; - snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url); - if (headers) - av_strlcat(buf, headers, sizeof(buf)); - av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq); - if (rt->session_id[0] != '\0' && (!headers || - !strstr(headers, "\nIf-Match:"))) { - av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id); - } - if (rt->auth[0]) { - char *str = ff_http_auth_create_response(&rt->auth_state, - rt->auth, url, method); - if (str) - av_strlcat(buf, str, sizeof(buf)); - av_free(str); - } - if (send_content_length > 0 && send_content) - av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length); - av_strlcat(buf, "\r\n", sizeof(buf)); - - dprintf(s, "Sending:\n%s--\n", buf); - - url_write(rt->rtsp_hd, buf, strlen(buf)); - if (send_content_length > 0 && send_content) - url_write(rt->rtsp_hd, send_content, send_content_length); - rt->last_cmd_time = av_gettime(); -} - -void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, - const char *url, const char *headers) -{ - ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0); -} - -void ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url, - const char *headers, RTSPMessageHeader *reply, - unsigned char **content_ptr) -{ - ff_rtsp_send_cmd_with_content(s, method, url, headers, reply, - content_ptr, NULL, 0); -} - -void ff_rtsp_send_cmd_with_content(AVFormatContext *s, - const char *method, const char *url, - const char *header, - RTSPMessageHeader *reply, - unsigned char **content_ptr, - const unsigned char *send_content, - int send_content_length) -{ - RTSPState *rt = s->priv_data; - HTTPAuthType cur_auth_type; - -retry: - cur_auth_type = rt->auth_state.auth_type; - ff_rtsp_send_cmd_with_content_async(s, method, url, header, - send_content, send_content_length); - - ff_rtsp_read_reply(s, reply, content_ptr, 0); - - if (reply->status_code == 401 && cur_auth_type == HTTP_AUTH_NONE && - rt->auth_state.auth_type != HTTP_AUTH_NONE) - goto retry; -} - -/** - * @return 0 on success, <0 on error, 1 if protocol is unavailable. - */ -static int make_setup_request(AVFormatContext *s, const char *host, int port, - int lower_transport, const char *real_challenge) -{ - RTSPState *rt = s->priv_data; - int rtx, j, i, err, interleave = 0; - RTSPStream *rtsp_st; - RTSPMessageHeader reply1, *reply = &reply1; - char cmd[2048]; - const char *trans_pref; - - if (rt->transport == RTSP_TRANSPORT_RDT) - trans_pref = "x-pn-tng"; - else - trans_pref = "RTP/AVP"; - - /* default timeout: 1 minute */ - rt->timeout = 60; - - /* for each stream, make the setup request */ - /* XXX: we assume the same server is used for the control of each - * RTSP stream */ - - for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) { - char transport[2048]; - - /** - * WMS serves all UDP data over a single connection, the RTX, which - * isn't necessarily the first in the SDP but has to be the first - * to be set up, else the second/third SETUP will fail with a 461. - */ - if (lower_transport == RTSP_LOWER_TRANSPORT_UDP && - rt->server_type == RTSP_SERVER_WMS) { - if (i == 0) { - /* rtx first */ - for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) { - int len = strlen(rt->rtsp_streams[rtx]->control_url); - if (len >= 4 && - !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4, - "/rtx")) - break; - } - if (rtx == rt->nb_rtsp_streams) - return -1; /* no RTX found */ - rtsp_st = rt->rtsp_streams[rtx]; - } else - rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1]; - } else - rtsp_st = rt->rtsp_streams[i]; - - /* RTP/UDP */ - if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) { - char buf[256]; - - if (rt->server_type == RTSP_SERVER_WMS && i > 1) { - port = reply->transports[0].client_port_min; - goto have_port; - } - - /* first try in specified port range */ - if (RTSP_RTP_PORT_MIN != 0) { - while (j <= RTSP_RTP_PORT_MAX) { - ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1, - "?localport=%d", j); - /* we will use two ports per rtp stream (rtp and rtcp) */ - j += 2; - if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) - goto rtp_opened; - } - } - -#if 0 - /* then try on any port */ - if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } -#endif - - rtp_opened: - port = rtp_get_local_port(rtsp_st->rtp_handle); - have_port: - snprintf(transport, sizeof(transport) - 1, - "%s/UDP;", trans_pref); - if (rt->server_type != RTSP_SERVER_REAL) - av_strlcat(transport, "unicast;", sizeof(transport)); - av_strlcatf(transport, sizeof(transport), - "client_port=%d", port); - if (rt->transport == RTSP_TRANSPORT_RTP && - !(rt->server_type == RTSP_SERVER_WMS && i > 0)) - av_strlcatf(transport, sizeof(transport), "-%d", port + 1); - } - - /* RTP/TCP */ - else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) { - /** For WMS streams, the application streams are only used for - * UDP. When trying to set it up for TCP streams, the server - * will return an error. Therefore, we skip those streams. */ - if (rt->server_type == RTSP_SERVER_WMS && - s->streams[rtsp_st->stream_index]->codec->codec_type == - AVMEDIA_TYPE_DATA) - continue; - snprintf(transport, sizeof(transport) - 1, - "%s/TCP;", trans_pref); - if (rt->server_type == RTSP_SERVER_WMS) - av_strlcat(transport, "unicast;", sizeof(transport)); - av_strlcatf(transport, sizeof(transport), - "interleaved=%d-%d", - interleave, interleave + 1); - interleave += 2; - } - - else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) { - snprintf(transport, sizeof(transport) - 1, - "%s/UDP;multicast", trans_pref); - } - if (s->oformat) { - av_strlcat(transport, ";mode=receive", sizeof(transport)); - } else if (rt->server_type == RTSP_SERVER_REAL || - rt->server_type == RTSP_SERVER_WMS) - av_strlcat(transport, ";mode=play", sizeof(transport)); - snprintf(cmd, sizeof(cmd), - "Transport: %s\r\n", - transport); - if (i == 0 && rt->server_type == RTSP_SERVER_REAL) { - char real_res[41], real_csum[9]; - ff_rdt_calc_response_and_checksum(real_res, real_csum, - real_challenge); - av_strlcatf(cmd, sizeof(cmd), - "If-Match: %s\r\n" - "RealChallenge2: %s, sd=%s\r\n", - rt->session_id, real_res, real_csum); - } - ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL); - if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) { - err = 1; - goto fail; - } else if (reply->status_code != RTSP_STATUS_OK || - reply->nb_transports != 1) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - /* XXX: same protocol for all streams is required */ - if (i > 0) { - if (reply->transports[0].lower_transport != rt->lower_transport || - reply->transports[0].transport != rt->transport) { - err = AVERROR_INVALIDDATA; - goto fail; - } - } else { - rt->lower_transport = reply->transports[0].lower_transport; - rt->transport = reply->transports[0].transport; - } - - /* close RTP connection if not choosen */ - if (reply->transports[0].lower_transport != RTSP_LOWER_TRANSPORT_UDP && - (lower_transport == RTSP_LOWER_TRANSPORT_UDP)) { - url_close(rtsp_st->rtp_handle); - rtsp_st->rtp_handle = NULL; - } - - switch(reply->transports[0].lower_transport) { - case RTSP_LOWER_TRANSPORT_TCP: - rtsp_st->interleaved_min = reply->transports[0].interleaved_min; - rtsp_st->interleaved_max = reply->transports[0].interleaved_max; - break; - - case RTSP_LOWER_TRANSPORT_UDP: { - char url[1024]; - - /* XXX: also use address if specified */ - ff_url_join(url, sizeof(url), "rtp", NULL, host, - reply->transports[0].server_port_min, NULL); - if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && - rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - /* Try to initialize the connection state in a - * potential NAT router by sending dummy packets. - * RTP/RTCP dummy packets are used for RDT, too. - */ - if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat) - rtp_send_punch_packets(rtsp_st->rtp_handle); - break; - } - case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: { - char url[1024]; - struct in_addr in; - int port, ttl; - - if (reply->transports[0].destination) { - in.s_addr = htonl(reply->transports[0].destination); - port = reply->transports[0].port_min; - ttl = reply->transports[0].ttl; - } else { - in = rtsp_st->sdp_ip; - port = rtsp_st->sdp_port; - ttl = rtsp_st->sdp_ttl; - } - ff_url_join(url, sizeof(url), "rtp", NULL, inet_ntoa(in), - port, "?ttl=%d", ttl); - if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - break; - } - } - - if ((err = rtsp_open_transport_ctx(s, rtsp_st))) - goto fail; - } - - if (reply->timeout > 0) - rt->timeout = reply->timeout; - - if (rt->server_type == RTSP_SERVER_REAL) - rt->need_subscription = 1; - - return 0; - -fail: - for (i = 0; i < rt->nb_rtsp_streams; i++) { - if (rt->rtsp_streams[i]->rtp_handle) { - url_close(rt->rtsp_streams[i]->rtp_handle); - rt->rtsp_streams[i]->rtp_handle = NULL; - } - } - return err; -} - -static int rtsp_read_play(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - RTSPMessageHeader reply1, *reply = &reply1; - int i; - char cmd[1024]; - - av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state); - - if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { - if (rt->state == RTSP_STATE_PAUSED) { - cmd[0] = 0; - } else { - snprintf(cmd, sizeof(cmd), - "Range: npt=%0.3f-\r\n", - (double)rt->seek_timestamp / AV_TIME_BASE); - } - ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) { - return -1; - } - if (reply->range_start != AV_NOPTS_VALUE && - rt->transport == RTSP_TRANSPORT_RTP) { - for (i = 0; i < rt->nb_rtsp_streams; i++) { - RTSPStream *rtsp_st = rt->rtsp_streams[i]; - RTPDemuxContext *rtpctx = rtsp_st->transport_priv; - AVStream *st = NULL; - if (!rtpctx) - continue; - if (rtsp_st->stream_index >= 0) - st = s->streams[rtsp_st->stream_index]; - rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE; - rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE; - if (st) - rtpctx->range_start_offset = av_rescale_q(reply->range_start, - AV_TIME_BASE_Q, - st->time_base); - } - } - } - rt->state = RTSP_STATE_STREAMING; - return 0; -} - -static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply) -{ - RTSPState *rt = s->priv_data; - char cmd[1024]; - unsigned char *content = NULL; - int ret; - - /* describe the stream */ - snprintf(cmd, sizeof(cmd), - "Accept: application/sdp\r\n"); - if (rt->server_type == RTSP_SERVER_REAL) { - /** - * The Require: attribute is needed for proper streaming from - * Realmedia servers. - */ - av_strlcat(cmd, - "Require: com.real.retain-entity-for-setup\r\n", - sizeof(cmd)); - } - ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content); - if (!content) - return AVERROR_INVALIDDATA; - if (reply->status_code != RTSP_STATUS_OK) { - av_freep(&content); - return AVERROR_INVALIDDATA; - } - - /* now we got the SDP description, we parse it */ - ret = sdp_parse(s, (const char *)content); - av_freep(&content); - if (ret < 0) - return AVERROR_INVALIDDATA; - - return 0; -} - -static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) -{ - RTSPState *rt = s->priv_data; - RTSPMessageHeader reply1, *reply = &reply1; - int i; - char *sdp; - AVFormatContext sdp_ctx, *ctx_array[1]; - - rt->start_time = av_gettime(); - - /* Announce the stream */ - sdp = av_mallocz(8192); - if (sdp == NULL) - return AVERROR(ENOMEM); - /* We create the SDP based on the RTSP AVFormatContext where we - * aren't allowed to change the filename field. (We create the SDP - * based on the RTSP context since the contexts for the RTP streams - * don't exist yet.) In order to specify a custom URL with the actual - * peer IP instead of the originally specified hostname, we create - * a temporary copy of the AVFormatContext, where the custom URL is set. - * - * FIXME: Create the SDP without copying the AVFormatContext. - * This either requires setting up the RTP stream AVFormatContexts - * already here (complicating things immensely) or getting a more - * flexible SDP creation interface. - */ - sdp_ctx = *s; - ff_url_join(sdp_ctx.filename, sizeof(sdp_ctx.filename), - "rtsp", NULL, addr, -1, NULL); - ctx_array[0] = &sdp_ctx; - if (avf_sdp_create(ctx_array, 1, sdp, 8192)) { - av_free(sdp); - return AVERROR_INVALIDDATA; - } - av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp); - ff_rtsp_send_cmd_with_content(s, "ANNOUNCE", rt->control_uri, - "Content-Type: application/sdp\r\n", - reply, NULL, sdp, strlen(sdp)); - av_free(sdp); - if (reply->status_code != RTSP_STATUS_OK) - return AVERROR_INVALIDDATA; - - /* Set up the RTSPStreams for each AVStream */ - for (i = 0; i < s->nb_streams; i++) { - RTSPStream *rtsp_st; - AVStream *st = s->streams[i]; - - rtsp_st = av_mallocz(sizeof(RTSPStream)); - if (!rtsp_st) - return AVERROR(ENOMEM); - dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); - - st->priv_data = rtsp_st; - rtsp_st->stream_index = i; - - av_strlcpy(rtsp_st->control_url, rt->control_uri, sizeof(rtsp_st->control_url)); - /* Note, this must match the relative uri set in the sdp content */ - av_strlcatf(rtsp_st->control_url, sizeof(rtsp_st->control_url), - "/streamid=%d", i); - } - - return 0; -} - -int ff_rtsp_connect(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128]; - char *option_list, *option, *filename; - URLContext *rtsp_hd; - int port, err, tcp_fd; - RTSPMessageHeader reply1 = {}, *reply = &reply1; - int lower_transport_mask = 0; - char real_challenge[64]; - struct sockaddr_storage peer; - socklen_t peer_len = sizeof(peer); - - if (!ff_network_init()) - return AVERROR(EIO); -redirect: - /* extract hostname and port */ - ff_url_split(NULL, 0, auth, sizeof(auth), - host, sizeof(host), &port, path, sizeof(path), s->filename); - if (*auth) { - av_strlcpy(rt->auth, auth, sizeof(rt->auth)); - } - if (port < 0) - port = RTSP_DEFAULT_PORT; - - /* search for options */ - option_list = strrchr(path, '?'); - if (option_list) { - /* Strip out the RTSP specific options, write out the rest of - * the options back into the same string. */ - filename = option_list; - while (option_list) { - /* move the option pointer */ - option = ++option_list; - option_list = strchr(option_list, '&'); - if (option_list) - *option_list = 0; - - /* handle the options */ - if (!strcmp(option, "udp")) { - lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_UDP); - } else if (!strcmp(option, "multicast")) { - lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST); - } else if (!strcmp(option, "tcp")) { - lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP); - } else { - /* Write options back into the buffer, using memmove instead - * of strcpy since the strings may overlap. */ - int len = strlen(option); - memmove(++filename, option, len); - filename += len; - if (option_list) *filename = '&'; - } - } - *filename = 0; - } - - if (!lower_transport_mask) - lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1; - - if (s->oformat) { - /* Only UDP or TCP - UDP multicast isn't supported. */ - lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) | - (1 << RTSP_LOWER_TRANSPORT_TCP); - if (!lower_transport_mask) { - av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, " - "only UDP and TCP are supported for output.\n"); - err = AVERROR(EINVAL); - goto fail; - } - } - - /* Construct the URI used in request; this is similar to s->filename, - * but with authentication credentials removed and RTSP specific options - * stripped out. */ - ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, - host, port, "%s", path); - - /* open the tcp connexion */ - ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL); - if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) { - err = AVERROR(EIO); - goto fail; - } - rt->rtsp_hd = rtsp_hd; - rt->seq = 0; - - tcp_fd = url_get_file_handle(rtsp_hd); - if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) { - getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host), - NULL, 0, NI_NUMERICHOST); - } - - /* request options supported by the server; this also detects server - * type */ - for (rt->server_type = RTSP_SERVER_RTP;;) { - cmd[0] = 0; - if (rt->server_type == RTSP_SERVER_REAL) - av_strlcat(cmd, - /** - * The following entries are required for proper - * streaming from a Realmedia server. They are - * interdependent in some way although we currently - * don't quite understand how. Values were copied - * from mplayer SVN r23589. - * @param CompanyID is a 16-byte ID in base64 - * @param ClientChallenge is a 16-byte ID in hex - */ - "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n" - "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n" - "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n" - "GUID: 00000000-0000-0000-0000-000000000000\r\n", - sizeof(cmd)); - ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - /* detect server type if not standard-compliant RTP */ - if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) { - rt->server_type = RTSP_SERVER_REAL; - continue; - } else if (!strncasecmp(reply->server, "WMServer/", 9)) { - rt->server_type = RTSP_SERVER_WMS; - } else if (rt->server_type == RTSP_SERVER_REAL) - strcpy(real_challenge, reply->real_challenge); - break; - } - - if (s->iformat) - err = rtsp_setup_input_streams(s, reply); - else - err = rtsp_setup_output_streams(s, host); - if (err) - goto fail; - - do { - int lower_transport = ff_log2_tab[lower_transport_mask & - ~(lower_transport_mask - 1)]; - - err = make_setup_request(s, host, port, lower_transport, - rt->server_type == RTSP_SERVER_REAL ? - real_challenge : NULL); - if (err < 0) - goto fail; - lower_transport_mask &= ~(1 << lower_transport); - if (lower_transport_mask == 0 && err == 1) { - err = FF_NETERROR(EPROTONOSUPPORT); - goto fail; - } - } while (err); - - rt->state = RTSP_STATE_IDLE; - rt->seek_timestamp = 0; /* default is to start stream at position zero */ - return 0; - fail: - ff_rtsp_close_streams(s); - url_close(rt->rtsp_hd); - if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) { - av_strlcpy(s->filename, reply->location, sizeof(s->filename)); - av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n", - reply->status_code, - s->filename); - goto redirect; - } - ff_network_close(); - return err; -} -#endif - -#if CONFIG_RTSP_DEMUXER -static int rtsp_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - RTSPState *rt = s->priv_data; - int ret; - - ret = ff_rtsp_connect(s); - if (ret) - return ret; - - if (ap->initial_pause) { - /* do not start immediately */ - } else { - if (rtsp_read_play(s) < 0) { - ff_rtsp_close_streams(s); - url_close(rt->rtsp_hd); - return AVERROR_INVALIDDATA; - } - } - - return 0; -} - -static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, - uint8_t *buf, int buf_size) -{ - RTSPState *rt = s->priv_data; - RTSPStream *rtsp_st; - fd_set rfds; - int fd, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0; - struct timeval tv; - - for (;;) { - if (url_interrupt_cb()) - return AVERROR(EINTR); - FD_ZERO(&rfds); - if (rt->rtsp_hd) { - tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd); - FD_SET(tcp_fd, &rfds); - } else { - fd_max = 0; - tcp_fd = -1; - } - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rtsp_st = rt->rtsp_streams[i]; - if (rtsp_st->rtp_handle) { - /* currently, we cannot probe RTCP handle because of - * blocking restrictions */ - fd = url_get_file_handle(rtsp_st->rtp_handle); - if (fd > fd_max) - fd_max = fd; - FD_SET(fd, &rfds); - } - } - tv.tv_sec = 0; - tv.tv_usec = SELECT_TIMEOUT_MS * 1000; - n = select(fd_max + 1, &rfds, NULL, NULL, &tv); - if (n > 0) { - timeout_cnt = 0; - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rtsp_st = rt->rtsp_streams[i]; - if (rtsp_st->rtp_handle) { - fd = url_get_file_handle(rtsp_st->rtp_handle); - if (FD_ISSET(fd, &rfds)) { - ret = url_read(rtsp_st->rtp_handle, buf, buf_size); - if (ret > 0) { - *prtsp_st = rtsp_st; - return ret; - } - } - } - } -#if CONFIG_RTSP_DEMUXER - if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) { - RTSPMessageHeader reply; - - ret = ff_rtsp_read_reply(s, &reply, NULL, 0); - if (ret < 0) - return ret; - /* XXX: parse message */ - if (rt->state != RTSP_STATE_STREAMING) - return 0; - } -#endif - } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) { - return FF_NETERROR(ETIMEDOUT); - } else if (n < 0 && errno != EINTR) - return AVERROR(errno); - } -} - -static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, - uint8_t *buf, int buf_size) -{ - RTSPState *rt = s->priv_data; - int id, len, i, ret; - RTSPStream *rtsp_st; - -#ifdef DEBUG_RTP_TCP - dprintf(s, "tcp_read_packet:\n"); -#endif -redo: - for (;;) { - RTSPMessageHeader reply; - - ret = ff_rtsp_read_reply(s, &reply, NULL, 1); - if (ret == -1) - return -1; - if (ret == 1) /* received '$' */ - break; - /* XXX: parse message */ - if (rt->state != RTSP_STATE_STREAMING) - return 0; - } - ret = url_read_complete(rt->rtsp_hd, buf, 3); - if (ret != 3) - return -1; - id = buf[0]; - len = AV_RB16(buf + 1); -#ifdef DEBUG_RTP_TCP - dprintf(s, "id=%d len=%d\n", id, len); -#endif - if (len > buf_size || len < 12) - goto redo; - /* get the data */ - ret = url_read_complete(rt->rtsp_hd, buf, len); - if (ret != len) - return -1; - if (rt->transport == RTSP_TRANSPORT_RDT && - ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0) - return -1; - - /* find the matching stream */ - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rtsp_st = rt->rtsp_streams[i]; - if (id >= rtsp_st->interleaved_min && - id <= rtsp_st->interleaved_max) - goto found; - } - goto redo; -found: - *prtsp_st = rtsp_st; - return len; -} - -static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) -{ - RTSPState *rt = s->priv_data; - int ret, len; - uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; - RTSPStream *rtsp_st; - - /* get next frames from the same RTP packet */ - if (rt->cur_transport_priv) { - if (rt->transport == RTSP_TRANSPORT_RDT) { - ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); - } else - ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); - if (ret == 0) { - rt->cur_transport_priv = NULL; - return 0; - } else if (ret == 1) { - return 0; - } else - rt->cur_transport_priv = NULL; - } - - /* read next RTP packet */ - redo: - switch(rt->lower_transport) { - default: -#if CONFIG_RTSP_DEMUXER - case RTSP_LOWER_TRANSPORT_TCP: - len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf)); - break; -#endif - case RTSP_LOWER_TRANSPORT_UDP: - case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: - len = udp_read_packet(s, &rtsp_st, buf, sizeof(buf)); - if (len >=0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) - rtp_check_and_send_back_rr(rtsp_st->transport_priv, len); - break; - } - if (len < 0) - return len; - if (len == 0) - return AVERROR_EOF; - if (rt->transport == RTSP_TRANSPORT_RDT) { - ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len); - } else { - ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, buf, len); - if (ret < 0) { - /* Either bad packet, or a RTCP packet. Check if the - * first_rtcp_ntp_time field was initialized. */ - RTPDemuxContext *rtpctx = rtsp_st->transport_priv; - if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) { - /* first_rtcp_ntp_time has been initialized for this stream, - * copy the same value to all other uninitialized streams, - * in order to map their timestamp origin to the same ntp time - * as this one. */ - int i; - for (i = 0; i < rt->nb_rtsp_streams; i++) { - RTPDemuxContext *rtpctx2 = rtsp_st->transport_priv; - if (rtpctx2 && - rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) - rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time; - } - } - } - } - if (ret < 0) - goto redo; - if (ret == 1) - /* more packets may follow, so we save the RTP context */ - rt->cur_transport_priv = rtsp_st->transport_priv; - - return ret; -} - -static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - RTSPState *rt = s->priv_data; - int ret; - RTSPMessageHeader reply1, *reply = &reply1; - char cmd[1024]; - - if (rt->server_type == RTSP_SERVER_REAL) { - int i; - enum AVDiscard cache[MAX_STREAMS]; - - for (i = 0; i < s->nb_streams; i++) - cache[i] = s->streams[i]->discard; - - if (!rt->need_subscription) { - if (memcmp (cache, rt->real_setup_cache, - sizeof(enum AVDiscard) * s->nb_streams)) { - snprintf(cmd, sizeof(cmd), - "Unsubscribe: %s\r\n", - rt->last_subscription); - ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, - cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) - return AVERROR_INVALIDDATA; - rt->need_subscription = 1; - } - } - - if (rt->need_subscription) { - int r, rule_nr, first = 1; - - memcpy(rt->real_setup_cache, cache, - sizeof(enum AVDiscard) * s->nb_streams); - rt->last_subscription[0] = 0; - - snprintf(cmd, sizeof(cmd), - "Subscribe: "); - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rule_nr = 0; - for (r = 0; r < s->nb_streams; r++) { - if (s->streams[r]->priv_data == rt->rtsp_streams[i]) { - if (s->streams[r]->discard != AVDISCARD_ALL) { - if (!first) - av_strlcat(rt->last_subscription, ",", - sizeof(rt->last_subscription)); - ff_rdt_subscribe_rule( - rt->last_subscription, - sizeof(rt->last_subscription), i, rule_nr); - first = 0; - } - rule_nr++; - } - } - } - av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); - ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, - cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) - return AVERROR_INVALIDDATA; - rt->need_subscription = 0; - - if (rt->state == RTSP_STATE_STREAMING) - rtsp_read_play (s); - } - } - - ret = rtsp_fetch_packet(s, pkt); - if (ret < 0) - return ret; - - /* send dummy request to keep TCP connection alive */ - if ((rt->server_type == RTSP_SERVER_WMS || - rt->server_type == RTSP_SERVER_REAL) && - (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { - if (rt->server_type == RTSP_SERVER_WMS) { - ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL); - } else { - ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL); - } - } - - return 0; -} - -/* pause the stream */ -static int rtsp_read_pause(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - RTSPMessageHeader reply1, *reply = &reply1; - - if (rt->state != RTSP_STATE_STREAMING) - return 0; - else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { - ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) { - return -1; - } - } - rt->state = RTSP_STATE_PAUSED; - return 0; -} - -static int rtsp_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - RTSPState *rt = s->priv_data; - - rt->seek_timestamp = av_rescale_q(timestamp, - s->streams[stream_index]->time_base, - AV_TIME_BASE_Q); - switch(rt->state) { - default: - case RTSP_STATE_IDLE: - break; - case RTSP_STATE_STREAMING: - if (rtsp_read_pause(s) != 0) - return -1; - rt->state = RTSP_STATE_SEEKING; - if (rtsp_read_play(s) != 0) - return -1; - break; - case RTSP_STATE_PAUSED: - rt->state = RTSP_STATE_IDLE; - break; - } - return 0; -} - -static int rtsp_read_close(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - -#if 0 - /* NOTE: it is valid to flush the buffer here */ - if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { - url_fclose(&rt->rtsp_gb); - } -#endif - ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); - - ff_rtsp_close_streams(s); - url_close(rt->rtsp_hd); - ff_network_close(); - return 0; -} - -AVInputFormat rtsp_demuxer = { - "rtsp", - NULL_IF_CONFIG_SMALL("RTSP input format"), - sizeof(RTSPState), - rtsp_probe, - rtsp_read_header, - rtsp_read_packet, - rtsp_read_close, - rtsp_read_seek, - .flags = AVFMT_NOFILE, - .read_play = rtsp_read_play, - .read_pause = rtsp_read_pause, -}; -#endif - -static int sdp_probe(AVProbeData *p1) -{ - const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; - - /* we look for a line beginning "c=IN IP4" */ - while (p < p_end && *p != '\0') { - if (p + sizeof("c=IN IP4") - 1 < p_end && - av_strstart(p, "c=IN IP4", NULL)) - return AVPROBE_SCORE_MAX / 2; - - while (p < p_end - 1 && *p != '\n') p++; - if (++p >= p_end) - break; - if (*p == '\r') - p++; - } - return 0; -} - -#define SDP_MAX_SIZE 8192 - -static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - RTSPState *rt = s->priv_data; - RTSPStream *rtsp_st; - int size, i, err; - char *content; - char url[1024]; - - if (!ff_network_init()) - return AVERROR(EIO); - - /* read the whole sdp file */ - /* XXX: better loading */ - content = av_malloc(SDP_MAX_SIZE); - size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1); - if (size <= 0) { - av_free(content); - return AVERROR_INVALIDDATA; - } - content[size] ='\0'; - - sdp_parse(s, content); - av_free(content); - - /* open each RTP stream */ - for (i = 0; i < rt->nb_rtsp_streams; i++) { - rtsp_st = rt->rtsp_streams[i]; - - ff_url_join(url, sizeof(url), "rtp", NULL, - inet_ntoa(rtsp_st->sdp_ip), rtsp_st->sdp_port, - "?localport=%d&ttl=%d", rtsp_st->sdp_port, - rtsp_st->sdp_ttl); - if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - if ((err = rtsp_open_transport_ctx(s, rtsp_st))) - goto fail; - } - return 0; -fail: - ff_rtsp_close_streams(s); - ff_network_close(); - return err; -} - -static int sdp_read_close(AVFormatContext *s) -{ - ff_rtsp_close_streams(s); - ff_network_close(); - return 0; -} - -AVInputFormat sdp_demuxer = { - "sdp", - NULL_IF_CONFIG_SMALL("SDP"), - sizeof(RTSPState), - sdp_probe, - sdp_read_header, - rtsp_fetch_packet, - sdp_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/rtsp.h b/tizen/distrib/ffmpeg/libavformat/rtsp.h deleted file mode 100644 index 357d3bf..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtsp.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - * RTSP definitions - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVFORMAT_RTSP_H -#define AVFORMAT_RTSP_H - -#include -#include "avformat.h" -#include "rtspcodes.h" -#include "rtpdec.h" -#include "network.h" -#include "httpauth.h" - -/** - * Network layer over which RTP/etc packet data will be transported. - */ -enum RTSPLowerTransport { - RTSP_LOWER_TRANSPORT_UDP = 0, /**< UDP/unicast */ - RTSP_LOWER_TRANSPORT_TCP = 1, /**< TCP; interleaved in RTSP */ - RTSP_LOWER_TRANSPORT_UDP_MULTICAST = 2, /**< UDP/multicast */ - RTSP_LOWER_TRANSPORT_NB -}; - -/** - * Packet profile of the data that we will be receiving. Real servers - * commonly send RDT (although they can sometimes send RTP as well), - * whereas most others will send RTP. - */ -enum RTSPTransport { - RTSP_TRANSPORT_RTP, /**< Standards-compliant RTP */ - RTSP_TRANSPORT_RDT, /**< Realmedia Data Transport */ - RTSP_TRANSPORT_NB -}; - -#define RTSP_DEFAULT_PORT 554 -#define RTSP_MAX_TRANSPORTS 8 -#define RTSP_TCP_MAX_PACKET_SIZE 1472 -#define RTSP_DEFAULT_NB_AUDIO_CHANNELS 2 -#define RTSP_DEFAULT_AUDIO_SAMPLERATE 44100 -#define RTSP_RTP_PORT_MIN 5000 -#define RTSP_RTP_PORT_MAX 10000 - -/** - * This describes a single item in the "Transport:" line of one stream as - * negotiated by the SETUP RTSP command. Multiple transports are comma- - * separated ("Transport: x-read-rdt/tcp;interleaved=0-1,rtp/avp/udp; - * client_port=1000-1001;server_port=1800-1801") and described in separate - * RTSPTransportFields. - */ -typedef struct RTSPTransportField { - /** interleave ids, if TCP transport; each TCP/RTSP data packet starts - * with a '$', stream length and stream ID. If the stream ID is within - * the range of this interleaved_min-max, then the packet belongs to - * this stream. */ - int interleaved_min, interleaved_max; - - /** UDP multicast port range; the ports to which we should connect to - * receive multicast UDP data. */ - int port_min, port_max; - - /** UDP client ports; these should be the local ports of the UDP RTP - * (and RTCP) sockets over which we receive RTP/RTCP data. */ - int client_port_min, client_port_max; - - /** UDP unicast server port range; the ports to which we should connect - * to receive unicast UDP RTP/RTCP data. */ - int server_port_min, server_port_max; - - /** time-to-live value (required for multicast); the amount of HOPs that - * packets will be allowed to make before being discarded. */ - int ttl; - - uint32_t destination; /**< destination IP address */ - - /** data/packet transport protocol; e.g. RTP or RDT */ - enum RTSPTransport transport; - - /** network layer transport protocol; e.g. TCP or UDP uni-/multicast */ - enum RTSPLowerTransport lower_transport; -} RTSPTransportField; - -/** - * This describes the server response to each RTSP command. - */ -typedef struct RTSPMessageHeader { - /** length of the data following this header */ - int content_length; - - enum RTSPStatusCode status_code; /**< response code from server */ - - /** number of items in the 'transports' variable below */ - int nb_transports; - - /** Time range of the streams that the server will stream. In - * AV_TIME_BASE unit, AV_NOPTS_VALUE if not used */ - int64_t range_start, range_end; - - /** describes the complete "Transport:" line of the server in response - * to a SETUP RTSP command by the client */ - RTSPTransportField transports[RTSP_MAX_TRANSPORTS]; - - int seq; /**< sequence number */ - - /** the "Session:" field. This value is initially set by the server and - * should be re-transmitted by the client in every RTSP command. */ - char session_id[512]; - - /** the "Location:" field. This value is used to handle redirection. - */ - char location[4096]; - - /** the "RealChallenge1:" field from the server */ - char real_challenge[64]; - - /** the "Server: field, which can be used to identify some special-case - * servers that are not 100% standards-compliant. We use this to identify - * Windows Media Server, which has a value "WMServer/v.e.r.sion", where - * version is a sequence of digits (e.g. 9.0.0.3372). Helix/Real servers - * use something like "Helix [..] Server Version v.e.r.sion (platform) - * (RealServer compatible)" or "RealServer Version v.e.r.sion (platform)", - * where platform is the output of $uname -msr | sed 's/ /-/g'. */ - char server[64]; - - /** The "timeout" comes as part of the server response to the "SETUP" - * command, in the "Session: [;timeout=]" line. It is the - * time, in seconds, that the server will go without traffic over the - * RTSP/TCP connection before it closes the connection. To prevent - * this, sent dummy requests (e.g. OPTIONS) with intervals smaller - * than this value. */ - int timeout; - - /** The "Notice" or "X-Notice" field value. See - * http://tools.ietf.org/html/draft-stiemerling-rtsp-announce-00 - * for a complete list of supported values. */ - int notice; -} RTSPMessageHeader; - -/** - * Client state, i.e. whether we are currently receiving data (PLAYING) or - * setup-but-not-receiving (PAUSED). State can be changed in applications - * by calling av_read_play/pause(). - */ -enum RTSPClientState { - RTSP_STATE_IDLE, /**< not initialized */ - RTSP_STATE_STREAMING, /**< initialized and sending/receiving data */ - RTSP_STATE_PAUSED, /**< initialized, but not receiving data */ - RTSP_STATE_SEEKING, /**< initialized, requesting a seek */ -}; - -/** - * Identifies particular servers that require special handling, such as - * standards-incompliant "Transport:" lines in the SETUP request. - */ -enum RTSPServerType { - RTSP_SERVER_RTP, /**< Standards-compliant RTP-server */ - RTSP_SERVER_REAL, /**< Realmedia-style server */ - RTSP_SERVER_WMS, /**< Windows Media server */ - RTSP_SERVER_NB -}; - -/** - * Private data for the RTSP demuxer. - * - * @todo Use ByteIOContext instead of URLContext - */ -typedef struct RTSPState { - URLContext *rtsp_hd; /* RTSP TCP connexion handle */ - - /** number of items in the 'rtsp_streams' variable */ - int nb_rtsp_streams; - - struct RTSPStream **rtsp_streams; /**< streams in this session */ - - /** indicator of whether we are currently receiving data from the - * server. Basically this isn't more than a simple cache of the - * last PLAY/PAUSE command sent to the server, to make sure we don't - * send 2x the same unexpectedly or commands in the wrong state. */ - enum RTSPClientState state; - - /** the seek value requested when calling av_seek_frame(). This value - * is subsequently used as part of the "Range" parameter when emitting - * the RTSP PLAY command. If we are currently playing, this command is - * called instantly. If we are currently paused, this command is called - * whenever we resume playback. Either way, the value is only used once, - * see rtsp_read_play() and rtsp_read_seek(). */ - int64_t seek_timestamp; - - /* XXX: currently we use unbuffered input */ - // ByteIOContext rtsp_gb; - - int seq; /**< RTSP command sequence number */ - - /** copy of RTSPMessageHeader->session_id, i.e. the server-provided session - * identifier that the client should re-transmit in each RTSP command */ - char session_id[512]; - - /** copy of RTSPMessageHeader->timeout, i.e. the time (in seconds) that - * the server will go without traffic on the RTSP/TCP line before it - * closes the connection. */ - int timeout; - - /** timestamp of the last RTSP command that we sent to the RTSP server. - * This is used to calculate when to send dummy commands to keep the - * connection alive, in conjunction with timeout. */ - int64_t last_cmd_time; - - /** the negotiated data/packet transport protocol; e.g. RTP or RDT */ - enum RTSPTransport transport; - - /** the negotiated network layer transport protocol; e.g. TCP or UDP - * uni-/multicast */ - enum RTSPLowerTransport lower_transport; - - /** brand of server that we're talking to; e.g. WMS, REAL or other. - * Detected based on the value of RTSPMessageHeader->server or the presence - * of RTSPMessageHeader->real_challenge */ - enum RTSPServerType server_type; - - /** plaintext authorization line (username:password) */ - char auth[128]; - - /** authentication state */ - HTTPAuthState auth_state; - - /** The last reply of the server to a RTSP command */ - char last_reply[2048]; /* XXX: allocate ? */ - - /** RTSPStream->transport_priv of the last stream that we read a - * packet from */ - void *cur_transport_priv; - - /** The following are used for Real stream selection */ - //@{ - /** whether we need to send a "SET_PARAMETER Subscribe:" command */ - int need_subscription; - - /** stream setup during the last frame read. This is used to detect if - * we need to subscribe or unsubscribe to any new streams. */ - enum AVDiscard real_setup_cache[MAX_STREAMS]; - - /** the last value of the "SET_PARAMETER Subscribe:" RTSP command. - * this is used to send the same "Unsubscribe:" if stream setup changed, - * before sending a new "Subscribe:" command. */ - char last_subscription[1024]; - //@} - - /** The following are used for RTP/ASF streams */ - //@{ - /** ASF demuxer context for the embedded ASF stream from WMS servers */ - AVFormatContext *asf_ctx; - - /** cache for position of the asf demuxer, since we load a new - * data packet in the bytecontext for each incoming RTSP packet. */ - uint64_t asf_pb_pos; - //@} - - /** some MS RTSP streams contain a URL in the SDP that we need to use - * for all subsequent RTSP requests, rather than the input URI; in - * other cases, this is a copy of AVFormatContext->filename. */ - char control_uri[1024]; - - /** The synchronized start time of the output streams. */ - int64_t start_time; -} RTSPState; - -/** - * Describes a single stream, as identified by a single m= line block in the - * SDP content. In the case of RDT, one RTSPStream can represent multiple - * AVStreams. In this case, each AVStream in this set has similar content - * (but different codec/bitrate). - */ -typedef struct RTSPStream { - URLContext *rtp_handle; /**< RTP stream handle (if UDP) */ - void *transport_priv; /**< RTP/RDT parse context if input, RTP AVFormatContext if output */ - - /** corresponding stream index, if any. -1 if none (MPEG2TS case) */ - int stream_index; - - /** interleave IDs; copies of RTSPTransportField->interleaved_min/max - * for the selected transport. Only used for TCP. */ - int interleaved_min, interleaved_max; - - char control_url[1024]; /**< url for this stream (from SDP) */ - - /** The following are used only in SDP, not RTSP */ - //@{ - int sdp_port; /**< port (from SDP content) */ - struct in_addr sdp_ip; /**< IP address (from SDP content) */ - int sdp_ttl; /**< IP Time-To-Live (from SDP content) */ - int sdp_payload_type; /**< payload type */ - //@} - - /** rtp payload parsing infos from SDP (i.e. mapping between private - * payload IDs and media-types (string), so that we can derive what - * type of payload we're dealing with (and how to parse it). */ - RTPPayloadData rtp_payload_data; - - /** The following are used for dynamic protocols (rtp_*.c/rdt.c) */ - //@{ - /** handler structure */ - RTPDynamicProtocolHandler *dynamic_handler; - - /** private data associated with the dynamic protocol */ - PayloadContext *dynamic_protocol_context; - //@} -} RTSPStream; - -void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf, - HTTPAuthState *auth_state); - -#if LIBAVFORMAT_VERSION_INT < (53 << 16) -extern int rtsp_default_protocols; -#endif -extern int rtsp_rtp_port_min; -extern int rtsp_rtp_port_max; - -/** - * Send a command to the RTSP server without waiting for the reply. - * - * @param s RTSP (de)muxer context - * @param method the method for the request - * @param url the target url for the request - * @param headers extra header lines to include in the request - * @param send_content if non-null, the data to send as request body content - * @param send_content_length the length of the send_content data, or 0 if - * send_content is null - */ -void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, - const char *method, const char *url, - const char *headers, - const unsigned char *send_content, - int send_content_length); -/** - * Send a command to the RTSP server without waiting for the reply. - * - * @see rtsp_send_cmd_with_content_async - */ -void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, - const char *url, const char *headers); - -/** - * Send a command to the RTSP server and wait for the reply. - * - * @param s RTSP (de)muxer context - * @param method the method for the request - * @param url the target url for the request - * @param headers extra header lines to include in the request - * @param reply pointer where the RTSP message header will be stored - * @param content_ptr pointer where the RTSP message body, if any, will - * be stored (length is in reply) - * @param send_content if non-null, the data to send as request body content - * @param send_content_length the length of the send_content data, or 0 if - * send_content is null - */ -void ff_rtsp_send_cmd_with_content(AVFormatContext *s, - const char *method, const char *url, - const char *headers, - RTSPMessageHeader *reply, - unsigned char **content_ptr, - const unsigned char *send_content, - int send_content_length); - -/** - * Send a command to the RTSP server and wait for the reply. - * - * @see rtsp_send_cmd_with_content - */ -void ff_rtsp_send_cmd(AVFormatContext *s, const char *method, - const char *url, const char *headers, - RTSPMessageHeader *reply, unsigned char **content_ptr); - -/** - * Read a RTSP message from the server, or prepare to read data - * packets if we're reading data interleaved over the TCP/RTSP - * connection as well. - * - * @param s RTSP (de)muxer context - * @param reply pointer where the RTSP message header will be stored - * @param content_ptr pointer where the RTSP message body, if any, will - * be stored (length is in reply) - * @param return_on_interleaved_data whether the function may return if we - * encounter a data marker ('$'), which precedes data - * packets over interleaved TCP/RTSP connections. If this - * is set, this function will return 1 after encountering - * a '$'. If it is not set, the function will skip any - * data packets (if they are encountered), until a reply - * has been fully parsed. If no more data is available - * without parsing a reply, it will return an error. - * - * @return 1 if a data packets is ready to be received, -1 on error, - * and 0 on success. - */ -int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, - unsigned char **content_ptr, - int return_on_interleaved_data); - -/** - * Skip a RTP/TCP interleaved packet. - */ -void ff_rtsp_skip_packet(AVFormatContext *s); - -/** - * Connect to the RTSP server and set up the individual media streams. - * This can be used for both muxers and demuxers. - * - * @param s RTSP (de)muxer context - * - * @return 0 on success, < 0 on error. Cleans up all allocations done - * within the function on error. - */ -int ff_rtsp_connect(AVFormatContext *s); - -/** - * Close and free all streams within the RTSP (de)muxer - * - * @param s RTSP (de)muxer context - */ -void ff_rtsp_close_streams(AVFormatContext *s); - -#endif /* AVFORMAT_RTSP_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtspcodes.h b/tizen/distrib/ffmpeg/libavformat/rtspcodes.h deleted file mode 100644 index 9ee96bf..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtspcodes.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * RTSP definitions - * copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_RTSPCODES_H -#define AVFORMAT_RTSPCODES_H - -/** RTSP handling */ -enum RTSPStatusCode { -RTSP_STATUS_OK =200, /**< OK */ -RTSP_STATUS_METHOD =405, /**< Method Not Allowed */ -RTSP_STATUS_BANDWIDTH =453, /**< Not Enough Bandwidth */ -RTSP_STATUS_SESSION =454, /**< Session Not Found */ -RTSP_STATUS_STATE =455, /**< Method Not Valid in This State */ -RTSP_STATUS_AGGREGATE =459, /**< Aggregate operation not allowed */ -RTSP_STATUS_ONLY_AGGREGATE =460, /**< Only aggregate operation allowed */ -RTSP_STATUS_TRANSPORT =461, /**< Unsupported transport */ -RTSP_STATUS_INTERNAL =500, /**< Internal Server Error */ -RTSP_STATUS_SERVICE =503, /**< Service Unavailable */ -RTSP_STATUS_VERSION =505, /**< RTSP Version not supported */ -}; - -#endif /* AVFORMAT_RTSPCODES_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/rtspenc.c b/tizen/distrib/ffmpeg/libavformat/rtspenc.c deleted file mode 100644 index f7aadd6..0000000 --- a/tizen/distrib/ffmpeg/libavformat/rtspenc.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * RTSP muxer - * Copyright (c) 2010 Martin Storsjo - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" - -#include -#if HAVE_SYS_SELECT_H -#include -#endif -#include "network.h" -#include "rtsp.h" -#include - -static int rtsp_write_record(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - RTSPMessageHeader reply1, *reply = &reply1; - char cmd[1024]; - - snprintf(cmd, sizeof(cmd), - "Range: npt=%0.3f-\r\n", - (double) 0); - ff_rtsp_send_cmd(s, "RECORD", rt->control_uri, cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) - return -1; - rt->state = RTSP_STATE_STREAMING; - return 0; -} - -static int rtsp_write_header(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - int ret; - - ret = ff_rtsp_connect(s); - if (ret) - return ret; - - if (rtsp_write_record(s) < 0) { - ff_rtsp_close_streams(s); - url_close(rt->rtsp_hd); - return AVERROR_INVALIDDATA; - } - return 0; -} - -static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st) -{ - RTSPState *rt = s->priv_data; - AVFormatContext *rtpctx = rtsp_st->transport_priv; - uint8_t *buf, *ptr; - int size; - uint8_t interleave_header[4]; - - size = url_close_dyn_buf(rtpctx->pb, &buf); - ptr = buf; - while (size > 4) { - uint32_t packet_len = AV_RB32(ptr); - int id; - ptr += 4; - size -= 4; - if (packet_len > size || packet_len < 2) - break; - if (ptr[1] >= 200 && ptr[1] <= 204) - id = rtsp_st->interleaved_max; /* RTCP */ - else - id = rtsp_st->interleaved_min; /* RTP */ - interleave_header[0] = '$'; - interleave_header[1] = id; - AV_WB16(interleave_header + 2, packet_len); - url_write(rt->rtsp_hd, interleave_header, 4); - url_write(rt->rtsp_hd, ptr, packet_len); - ptr += packet_len; - size -= packet_len; - } - av_free(buf); - url_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE); - return 0; -} - -static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - RTSPState *rt = s->priv_data; - RTSPStream *rtsp_st; - fd_set rfds; - int n, tcp_fd; - struct timeval tv; - AVFormatContext *rtpctx; - AVPacket local_pkt; - int ret; - - tcp_fd = url_get_file_handle(rt->rtsp_hd); - - while (1) { - FD_ZERO(&rfds); - FD_SET(tcp_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 0; - n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv); - if (n <= 0) - break; - if (FD_ISSET(tcp_fd, &rfds)) { - RTSPMessageHeader reply; - - /* Don't let ff_rtsp_read_reply handle interleaved packets, - * since it would block and wait for an RTSP reply on the socket - * (which may not be coming any time soon) if it handles - * interleaved packets internally. */ - ret = ff_rtsp_read_reply(s, &reply, NULL, 1); - if (ret < 0) - return AVERROR(EPIPE); - if (ret == 1) - ff_rtsp_skip_packet(s); - /* XXX: parse message */ - if (rt->state != RTSP_STATE_STREAMING) - return AVERROR(EPIPE); - } - } - - if (pkt->stream_index < 0 || pkt->stream_index >= rt->nb_rtsp_streams) - return AVERROR_INVALIDDATA; - rtsp_st = rt->rtsp_streams[pkt->stream_index]; - rtpctx = rtsp_st->transport_priv; - - /* Use a local packet for writing to the chained muxer, otherwise - * the internal stream_index = 0 becomes visible to the muxer user. */ - local_pkt = *pkt; - local_pkt.stream_index = 0; - ret = av_write_frame(rtpctx, &local_pkt); - /* av_write_frame does all the RTP packetization. If using TCP as - * transport, rtpctx->pb is only a dyn_packet_buf that queues up the - * packets, so we need to send them out on the TCP connection separately. - */ - if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) - ret = tcp_write_packet(s, rtsp_st); - return ret; -} - -static int rtsp_write_close(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - - ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); - - ff_rtsp_close_streams(s); - url_close(rt->rtsp_hd); - ff_network_close(); - return 0; -} - -AVOutputFormat rtsp_muxer = { - "rtsp", - NULL_IF_CONFIG_SMALL("RTSP output format"), - NULL, - NULL, - sizeof(RTSPState), - CODEC_ID_PCM_MULAW, - CODEC_ID_NONE, - rtsp_write_header, - rtsp_write_packet, - rtsp_write_close, - .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER, -}; - diff --git a/tizen/distrib/ffmpeg/libavformat/sdp.c b/tizen/distrib/ffmpeg/libavformat/sdp.c deleted file mode 100644 index 6bf05db..0000000 --- a/tizen/distrib/ffmpeg/libavformat/sdp.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * copyright (c) 2007 Luca Abeni - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "libavutil/avstring.h" -#include "libavutil/base64.h" -#include "avformat.h" -#include "internal.h" -#include "avc.h" -#include "rtp.h" -#if CONFIG_NETWORK -#include "network.h" -#endif - -#if CONFIG_RTP_MUXER -#define MAX_EXTRADATA_SIZE ((INT_MAX - 10) / 2) - -struct sdp_session_level { - int sdp_version; /**< protocol version (currently 0) */ - int id; /**< session ID */ - int version; /**< session version */ - int start_time; /**< session start time (NTP time, in seconds), - or 0 in case of permanent session */ - int end_time; /**< session end time (NTP time, in seconds), - or 0 if the session is not bounded */ - int ttl; /**< TTL, in case of multicast stream */ - const char *user; /**< username of the session's creator */ - const char *src_addr; /**< IP address of the machine from which the session was created */ - const char *dst_addr; /**< destination IP address (can be multicast) */ - const char *name; /**< session name (can be an empty string) */ -}; - -static void sdp_write_address(char *buff, int size, const char *dest_addr, int ttl) -{ - if (dest_addr) { - if (ttl > 0) { - av_strlcatf(buff, size, "c=IN IP4 %s/%d\r\n", dest_addr, ttl); - } else { - av_strlcatf(buff, size, "c=IN IP4 %s\r\n", dest_addr); - } - } -} - -static void sdp_write_header(char *buff, int size, struct sdp_session_level *s) -{ - av_strlcatf(buff, size, "v=%d\r\n" - "o=- %d %d IN IP4 %s\r\n" - "s=%s\r\n", - s->sdp_version, - s->id, s->version, s->src_addr, - s->name); - sdp_write_address(buff, size, s->dst_addr, s->ttl); - av_strlcatf(buff, size, "t=%d %d\r\n" - "a=tool:libavformat " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\r\n", - s->start_time, s->end_time); -} - -#if CONFIG_NETWORK -static void resolve_destination(char *dest_addr, int size) -{ - struct addrinfo hints, *ai, *cur; - - if (!dest_addr[0]) - return; - - /* Resolve the destination, since it must be written - * as a numeric IP address in the SDP. */ - - memset(&hints, 0, sizeof(hints)); - /* We only support IPv4 addresses in the SDP at the moment. */ - hints.ai_family = AF_INET; - if (getaddrinfo(dest_addr, NULL, &hints, &ai)) - return; - for (cur = ai; cur; cur = cur->ai_next) { - if (cur->ai_family == AF_INET) { - getnameinfo(cur->ai_addr, cur->ai_addrlen, dest_addr, size, - NULL, 0, NI_NUMERICHOST); - break; - } - } - freeaddrinfo(ai); -} -#else -static void resolve_destination(char *dest_addr, int size) -{ -} -#endif - -static int sdp_get_address(char *dest_addr, int size, int *ttl, const char *url) -{ - int port; - const char *p; - char proto[32]; - - ff_url_split(proto, sizeof(proto), NULL, 0, dest_addr, size, &port, NULL, 0, url); - - *ttl = 0; - - if (strcmp(proto, "rtp")) { - /* The url isn't for the actual rtp sessions, - * don't parse out anything else than the destination. - */ - return 0; - } - - p = strchr(url, '?'); - if (p) { - char buff[64]; - int is_multicast = find_info_tag(buff, sizeof(buff), "multicast", p); - - if (is_multicast) { - if (find_info_tag(buff, sizeof(buff), "ttl", p)) { - *ttl = strtol(buff, NULL, 10); - } else { - *ttl = 5; - } - } - } - - return port; -} - -#define MAX_PSET_SIZE 1024 -static char *extradata2psets(AVCodecContext *c) -{ - char *psets, *p; - const uint8_t *r; - const char *pset_string = "; sprop-parameter-sets="; - - if (c->extradata_size > MAX_EXTRADATA_SIZE) { - av_log(c, AV_LOG_ERROR, "Too much extradata!\n"); - - return NULL; - } - - psets = av_mallocz(MAX_PSET_SIZE); - if (psets == NULL) { - av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the parameter sets.\n"); - return NULL; - } - memcpy(psets, pset_string, strlen(pset_string)); - p = psets + strlen(pset_string); - r = ff_avc_find_startcode(c->extradata, c->extradata + c->extradata_size); - while (r < c->extradata + c->extradata_size) { - const uint8_t *r1; - uint8_t nal_type; - - while (!*(r++)); - nal_type = *r & 0x1f; - r1 = ff_avc_find_startcode(r, c->extradata + c->extradata_size); - if (nal_type != 7 && nal_type != 8) { /* Only output SPS and PPS */ - r = r1; - continue; - } - if (p != (psets + strlen(pset_string))) { - *p = ','; - p++; - } - if (av_base64_encode(p, MAX_PSET_SIZE - (p - psets), r, r1 - r) == NULL) { - av_log(c, AV_LOG_ERROR, "Cannot Base64-encode %td %td!\n", MAX_PSET_SIZE - (p - psets), r1 - r); - av_free(psets); - - return NULL; - } - p += strlen(p); - r = r1; - } - - return psets; -} - -static char *extradata2config(AVCodecContext *c) -{ - char *config; - - if (c->extradata_size > MAX_EXTRADATA_SIZE) { - av_log(c, AV_LOG_ERROR, "Too much extradata!\n"); - - return NULL; - } - config = av_malloc(10 + c->extradata_size * 2); - if (config == NULL) { - av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n"); - return NULL; - } - memcpy(config, "; config=", 9); - ff_data_to_hex(config + 9, c->extradata, c->extradata_size, 0); - config[9 + c->extradata_size * 2] = 0; - - return config; -} - -static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type) -{ - char *config = NULL; - - switch (c->codec_id) { - case CODEC_ID_H264: - if (c->extradata_size) { - config = extradata2psets(c); - } - av_strlcatf(buff, size, "a=rtpmap:%d H264/90000\r\n" - "a=fmtp:%d packetization-mode=1%s\r\n", - payload_type, - payload_type, config ? config : ""); - break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n", payload_type); - break; - case CODEC_ID_MPEG4: - if (c->extradata_size) { - config = extradata2config(c); - } - av_strlcatf(buff, size, "a=rtpmap:%d MP4V-ES/90000\r\n" - "a=fmtp:%d profile-level-id=1%s\r\n", - payload_type, - payload_type, config ? config : ""); - break; - case CODEC_ID_AAC: - if (c->extradata_size) { - config = extradata2config(c); - } else { - /* FIXME: maybe we can forge config information based on the - * codec parameters... - */ - av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n"); - return NULL; - } - if (config == NULL) { - return NULL; - } - av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n" - "a=fmtp:%d profile-level-id=1;" - "mode=AAC-hbr;sizelength=13;indexlength=3;" - "indexdeltalength=3%s\r\n", - payload_type, c->sample_rate, c->channels, - payload_type, config); - break; - case CODEC_ID_PCM_S16BE: - if (payload_type >= RTP_PT_PRIVATE) - av_strlcatf(buff, size, "a=rtpmap:%d L16/%d/%d\r\n", - payload_type, - c->sample_rate, c->channels); - break; - case CODEC_ID_PCM_MULAW: - if (payload_type >= RTP_PT_PRIVATE) - av_strlcatf(buff, size, "a=rtpmap:%d PCMU/%d/%d\r\n", - payload_type, - c->sample_rate, c->channels); - break; - case CODEC_ID_PCM_ALAW: - if (payload_type >= RTP_PT_PRIVATE) - av_strlcatf(buff, size, "a=rtpmap:%d PCMA/%d/%d\r\n", - payload_type, - c->sample_rate, c->channels); - break; - case CODEC_ID_AMR_NB: - av_strlcatf(buff, size, "a=rtpmap:%d AMR/%d/%d\r\n" - "a=fmtp:%d octet-align=1\r\n", - payload_type, c->sample_rate, c->channels, - payload_type); - break; - case CODEC_ID_AMR_WB: - av_strlcatf(buff, size, "a=rtpmap:%d AMR-WB/%d/%d\r\n" - "a=fmtp:%d octet-align=1\r\n", - payload_type, c->sample_rate, c->channels, - payload_type); - break; - default: - /* Nothing special to do here... */ - break; - } - - av_free(config); - - return buff; -} - -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, const char *dest_addr, int port, int ttl) -{ - const char *type; - int payload_type; - - payload_type = ff_rtp_get_payload_type(c); - if (payload_type < 0) { - payload_type = RTP_PT_PRIVATE + (c->codec_type == AVMEDIA_TYPE_AUDIO); - } - - switch (c->codec_type) { - case AVMEDIA_TYPE_VIDEO : type = "video" ; break; - case AVMEDIA_TYPE_AUDIO : type = "audio" ; break; - case AVMEDIA_TYPE_SUBTITLE: type = "text" ; break; - default : type = "application"; break; - } - - av_strlcatf(buff, size, "m=%s %d RTP/AVP %d\r\n", type, port, payload_type); - sdp_write_address(buff, size, dest_addr, ttl); - if (c->bit_rate) { - av_strlcatf(buff, size, "b=AS:%d\r\n", c->bit_rate / 1000); - } - - sdp_write_media_attributes(buff, size, c, payload_type); -} - -int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size) -{ - AVMetadataTag *title = av_metadata_get(ac[0]->metadata, "title", NULL, 0); - struct sdp_session_level s; - int i, j, port, ttl; - char dst[32]; - - memset(buff, 0, size); - memset(&s, 0, sizeof(struct sdp_session_level)); - s.user = "-"; - s.src_addr = "127.0.0.1"; /* FIXME: Properly set this */ - s.name = title ? title->value : "No Name"; - - port = 0; - ttl = 0; - if (n_files == 1) { - port = sdp_get_address(dst, sizeof(dst), &ttl, ac[0]->filename); - resolve_destination(dst, sizeof(dst)); - if (dst[0]) { - s.dst_addr = dst; - s.ttl = ttl; - } - } - sdp_write_header(buff, size, &s); - - dst[0] = 0; - for (i = 0; i < n_files; i++) { - if (n_files != 1) { - port = sdp_get_address(dst, sizeof(dst), &ttl, ac[i]->filename); - resolve_destination(dst, sizeof(dst)); - } - for (j = 0; j < ac[i]->nb_streams; j++) { - ff_sdp_write_media(buff, size, - ac[i]->streams[j]->codec, dst[0] ? dst : NULL, - (port > 0) ? port + j * 2 : 0, ttl); - if (port <= 0) { - av_strlcatf(buff, size, - "a=control:streamid=%d\r\n", i + j); - } - } - } - - return 0; -} -#else -int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size) -{ - return AVERROR(ENOSYS); -} - -void ff_sdp_write_media(char *buff, int size, AVCodecContext *c, - const char *dest_addr, int port, int ttl) -{ -} -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/seek.c b/tizen/distrib/ffmpeg/libavformat/seek.c deleted file mode 100644 index 26b622f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/seek.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * seek utility functions for use within format handlers - * - * Copyright (c) 2009 Ivan Schreter - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "seek.h" -#include "libavutil/mem.h" -#include "internal.h" - -// NOTE: implementation should be moved here in another patch, to keep patches -// separated. - -/** - * helper structure describing keyframe search state of one stream - */ -typedef struct { - int64_t pos_lo; ///< position of the frame with low timestamp in file or INT64_MAX if not found (yet) - int64_t ts_lo; ///< frame presentation timestamp or same as pos_lo for byte seeking - - int64_t pos_hi; ///< position of the frame with high timestamp in file or INT64_MAX if not found (yet) - int64_t ts_hi; ///< frame presentation timestamp or same as pos_hi for byte seeking - - int64_t last_pos; ///< last known position of a frame, for multi-frame packets - - int64_t term_ts; ///< termination timestamp (which TS we already read) - AVRational term_ts_tb; ///< timebase for term_ts - int64_t first_ts; ///< first packet timestamp in this iteration (to fill term_ts later) - AVRational first_ts_tb; ///< timebase for first_ts - - int terminated; ///< termination flag for the current iteration -} AVSyncPoint; - -/** - * Compute a distance between timestamps. - * - * Distances are only comparable, if same time bases are used for computing - * distances. - * - * @param ts_hi high timestamp - * @param tb_hi high timestamp time base - * @param ts_lo low timestamp - * @param tb_lo low timestamp time base - * @return representation of distance between high and low timestamps - */ -static int64_t ts_distance(int64_t ts_hi, - AVRational tb_hi, - int64_t ts_lo, - AVRational tb_lo) -{ - int64_t hi, lo; - - hi = ts_hi * tb_hi.num * tb_lo.den; - lo = ts_lo * tb_lo.num * tb_hi.den; - - return hi - lo; -} - -/** - * Partial search for keyframes in multiple streams. - * - * This routine searches in each stream for the next lower and the next higher - * timestamp compared to the given target timestamp. The search starts at the current - * file position and ends at the file position, where all streams have already been - * examined (or when all higher key frames are found in the first iteration). - * - * This routine is called iteratively with an exponential backoff to find the lower - * timestamp. - * - * @param s format context - * @param timestamp target timestamp (or position, if AVSEEK_FLAG_BYTE) - * @param timebase time base for timestamps - * @param flags seeking flags - * @param sync array with information per stream - * @param keyframes_to_find count of keyframes to find in total - * @param found_lo ptr to the count of already found low timestamp keyframes - * @param found_hi ptr to the count of already found high timestamp keyframes - * @param first_iter flag for first iteration - */ -static void search_hi_lo_keyframes(AVFormatContext *s, - int64_t timestamp, - AVRational timebase, - int flags, - AVSyncPoint *sync, - int keyframes_to_find, - int *found_lo, - int *found_hi, - int first_iter) -{ - AVPacket pkt; - AVSyncPoint *sp; - AVStream *st; - int idx; - int flg; - int terminated_count = 0; - int64_t pos; - int64_t pts, dts; // PTS/DTS from stream - int64_t ts; // PTS in stream-local time base or position for byte seeking - AVRational ts_tb; // Time base of the stream or 1:1 for byte seeking - - for (;;) { - if (av_read_frame(s, &pkt) < 0) { - // EOF or error, make sure high flags are set - for (idx = 0; idx < s->nb_streams; ++idx) { - if (s->streams[idx]->discard < AVDISCARD_ALL) { - sp = &sync[idx]; - if (sp->pos_hi == INT64_MAX) { - // no high frame exists for this stream - (*found_hi)++; - sp->ts_hi = INT64_MAX; - sp->pos_hi = INT64_MAX - 1; - } - } - } - break; - } - - idx = pkt.stream_index; - st = s->streams[idx]; - if (st->discard >= AVDISCARD_ALL) - // this stream is not active, skip packet - continue; - - sp = &sync[idx]; - - flg = pkt.flags; - pos = pkt.pos; - pts = pkt.pts; - dts = pkt.dts; - if (pts == AV_NOPTS_VALUE) - // some formats don't provide PTS, only DTS - pts = dts; - - av_free_packet(&pkt); - - // Multi-frame packets only return position for the very first frame. - // Other frames are read with position == -1. Therefore, we note down - // last known position of a frame and use it if a frame without - // position arrives. In this way, it's possible to seek to proper - // position. Additionally, for parsers not providing position at all, - // an approximation will be used (starting position of this iteration). - if (pos < 0) - pos = sp->last_pos; - else - sp->last_pos = pos; - - // Evaluate key frames with known TS (or any frames, if AVSEEK_FLAG_ANY set). - if (pts != AV_NOPTS_VALUE && - ((flg & AV_PKT_FLAG_KEY) || (flags & AVSEEK_FLAG_ANY))) { - if (flags & AVSEEK_FLAG_BYTE) { - // for byte seeking, use position as timestamp - ts = pos; - ts_tb.num = 1; - ts_tb.den = 1; - } else { - // otherwise, get stream time_base - ts = pts; - ts_tb = st->time_base; - } - - if (sp->first_ts == AV_NOPTS_VALUE) { - // Note down termination timestamp for the next iteration - when - // we encounter a packet with the same timestamp, we will ignore - // any further packets for this stream in next iteration (as they - // are already evaluated). - sp->first_ts = ts; - sp->first_ts_tb = ts_tb; - } - - if (sp->term_ts != AV_NOPTS_VALUE && - av_compare_ts(ts, ts_tb, sp->term_ts, sp->term_ts_tb) > 0) { - // past the end position from last iteration, ignore packet - if (!sp->terminated) { - sp->terminated = 1; - ++terminated_count; - if (sp->pos_hi == INT64_MAX) { - // no high frame exists for this stream - (*found_hi)++; - sp->ts_hi = INT64_MAX; - sp->pos_hi = INT64_MAX - 1; - } - if (terminated_count == keyframes_to_find) - break; // all terminated, iteration done - } - continue; - } - - if (av_compare_ts(ts, ts_tb, timestamp, timebase) <= 0) { - // keyframe found before target timestamp - if (sp->pos_lo == INT64_MAX) { - // found first keyframe lower than target timestamp - (*found_lo)++; - sp->ts_lo = ts; - sp->pos_lo = pos; - } else if (sp->ts_lo < ts) { - // found a better match (closer to target timestamp) - sp->ts_lo = ts; - sp->pos_lo = pos; - } - } - if (av_compare_ts(ts, ts_tb, timestamp, timebase) >= 0) { - // keyframe found after target timestamp - if (sp->pos_hi == INT64_MAX) { - // found first keyframe higher than target timestamp - (*found_hi)++; - sp->ts_hi = ts; - sp->pos_hi = pos; - if (*found_hi >= keyframes_to_find && first_iter) { - // We found high frame for all. They may get updated - // to TS closer to target TS in later iterations (which - // will stop at start position of previous iteration). - break; - } - } else if (sp->ts_hi > ts) { - // found a better match (actually, shouldn't happen) - sp->ts_hi = ts; - sp->pos_hi = pos; - } - } - } - } - - // Clean up the parser. - ff_read_frame_flush(s); -} - -int64_t ff_gen_syncpoint_search(AVFormatContext *s, - int stream_index, - int64_t pos, - int64_t ts_min, - int64_t ts, - int64_t ts_max, - int flags) -{ - AVSyncPoint *sync, *sp; - AVStream *st; - int i; - int keyframes_to_find = 0; - int64_t curpos; - int64_t step; - int found_lo = 0, found_hi = 0; - int64_t min_distance, distance; - int64_t min_pos = 0; - int first_iter = 1; - AVRational time_base; - - if (flags & AVSEEK_FLAG_BYTE) { - // for byte seeking, we have exact 1:1 "timestamps" - positions - time_base.num = 1; - time_base.den = 1; - } else { - if (stream_index >= 0) { - // we have a reference stream, which time base we use - st = s->streams[stream_index]; - time_base = st->time_base; - } else { - // no reference stream, use AV_TIME_BASE as reference time base - time_base.num = 1; - time_base.den = AV_TIME_BASE; - } - } - - // Initialize syncpoint structures for each stream. - sync = av_malloc(s->nb_streams * sizeof(AVSyncPoint)); - if (!sync) - // cannot allocate helper structure - return -1; - - for (i = 0; i < s->nb_streams; ++i) { - st = s->streams[i]; - sp = &sync[i]; - - sp->pos_lo = INT64_MAX; - sp->ts_lo = INT64_MAX; - sp->pos_hi = INT64_MAX; - sp->ts_hi = INT64_MAX; - sp->terminated = 0; - sp->first_ts = AV_NOPTS_VALUE; - sp->term_ts = ts_max; - sp->term_ts_tb = time_base; - sp->last_pos = pos; - - st->cur_dts = AV_NOPTS_VALUE; - - if (st->discard < AVDISCARD_ALL) - ++keyframes_to_find; - } - - if (!keyframes_to_find) { - // no stream active, error - av_free(sync); - return -1; - } - - // Find keyframes in all active streams with timestamp/position just before - // and just after requested timestamp/position. - step = s->pb->buffer_size; - curpos = FFMAX(pos - step / 2, 0); - for (;;) { - url_fseek(s->pb, curpos, SEEK_SET); - search_hi_lo_keyframes(s, - ts, time_base, - flags, - sync, - keyframes_to_find, - &found_lo, &found_hi, - first_iter); - if (found_lo == keyframes_to_find && found_hi == keyframes_to_find) - break; // have all keyframes we wanted - if (!curpos) - break; // cannot go back anymore - - curpos = pos - step; - if (curpos < 0) - curpos = 0; - step *= 2; - - // switch termination positions - for (i = 0; i < s->nb_streams; ++i) { - st = s->streams[i]; - st->cur_dts = AV_NOPTS_VALUE; - - sp = &sync[i]; - if (sp->first_ts != AV_NOPTS_VALUE) { - sp->term_ts = sp->first_ts; - sp->term_ts_tb = sp->first_ts_tb; - sp->first_ts = AV_NOPTS_VALUE; - } - sp->terminated = 0; - sp->last_pos = curpos; - } - first_iter = 0; - } - - // Find actual position to start decoding so that decoder synchronizes - // closest to ts and between ts_min and ts_max. - pos = INT64_MAX; - - for (i = 0; i < s->nb_streams; ++i) { - st = s->streams[i]; - if (st->discard < AVDISCARD_ALL) { - sp = &sync[i]; - min_distance = INT64_MAX; - // Find timestamp closest to requested timestamp within min/max limits. - if (sp->pos_lo != INT64_MAX - && av_compare_ts(ts_min, time_base, sp->ts_lo, st->time_base) <= 0 - && av_compare_ts(sp->ts_lo, st->time_base, ts_max, time_base) <= 0) { - // low timestamp is in range - min_distance = ts_distance(ts, time_base, sp->ts_lo, st->time_base); - min_pos = sp->pos_lo; - } - if (sp->pos_hi != INT64_MAX - && av_compare_ts(ts_min, time_base, sp->ts_hi, st->time_base) <= 0 - && av_compare_ts(sp->ts_hi, st->time_base, ts_max, time_base) <= 0) { - // high timestamp is in range, check distance - distance = ts_distance(sp->ts_hi, st->time_base, ts, time_base); - if (distance < min_distance) { - min_distance = distance; - min_pos = sp->pos_hi; - } - } - if (min_distance == INT64_MAX) { - // no timestamp is in range, cannot seek - av_free(sync); - return -1; - } - if (min_pos < pos) - pos = min_pos; - } - } - - url_fseek(s->pb, pos, SEEK_SET); - av_free(sync); - return pos; -} - -AVParserState *ff_store_parser_state(AVFormatContext *s) -{ - int i; - AVStream *st; - AVParserStreamState *ss; - AVParserState *state = av_malloc(sizeof(AVParserState)); - if (!state) - return NULL; - - state->stream_states = av_malloc(sizeof(AVParserStreamState) * s->nb_streams); - if (!state->stream_states) { - av_free(state); - return NULL; - } - - state->fpos = url_ftell(s->pb); - - // copy context structures - state->cur_st = s->cur_st; - state->packet_buffer = s->packet_buffer; - state->raw_packet_buffer = s->raw_packet_buffer; - state->raw_packet_buffer_remaining_size = s->raw_packet_buffer_remaining_size; - - s->cur_st = NULL; - s->packet_buffer = NULL; - s->raw_packet_buffer = NULL; - s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; - - // copy stream structures - state->nb_streams = s->nb_streams; - for (i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - ss = &state->stream_states[i]; - - ss->parser = st->parser; - ss->last_IP_pts = st->last_IP_pts; - ss->cur_dts = st->cur_dts; - ss->reference_dts = st->reference_dts; - ss->cur_ptr = st->cur_ptr; - ss->cur_len = st->cur_len; - ss->probe_packets = st->probe_packets; - ss->cur_pkt = st->cur_pkt; - - st->parser = NULL; - st->last_IP_pts = AV_NOPTS_VALUE; - st->cur_dts = AV_NOPTS_VALUE; - st->reference_dts = AV_NOPTS_VALUE; - st->cur_ptr = NULL; - st->cur_len = 0; - st->probe_packets = MAX_PROBE_PACKETS; - av_init_packet(&st->cur_pkt); - } - - return state; -} - -void ff_restore_parser_state(AVFormatContext *s, AVParserState *state) -{ - int i; - AVStream *st; - AVParserStreamState *ss; - ff_read_frame_flush(s); - - if (!state) - return; - - url_fseek(s->pb, state->fpos, SEEK_SET); - - // copy context structures - s->cur_st = state->cur_st; - s->packet_buffer = state->packet_buffer; - s->raw_packet_buffer = state->raw_packet_buffer; - s->raw_packet_buffer_remaining_size = state->raw_packet_buffer_remaining_size; - - // copy stream structures - for (i = 0; i < state->nb_streams; i++) { - st = s->streams[i]; - ss = &state->stream_states[i]; - - st->parser = ss->parser; - st->last_IP_pts = ss->last_IP_pts; - st->cur_dts = ss->cur_dts; - st->reference_dts = ss->reference_dts; - st->cur_ptr = ss->cur_ptr; - st->cur_len = ss->cur_len; - st->probe_packets = ss->probe_packets; - st->cur_pkt = ss->cur_pkt; - } - - av_free(state->stream_states); - av_free(state); -} - -static void free_packet_list(AVPacketList *pktl) -{ - AVPacketList *cur; - while (pktl) { - cur = pktl; - pktl = cur->next; - av_free_packet(&cur->pkt); - av_free(cur); - } -} - -void ff_free_parser_state(AVFormatContext *s, AVParserState *state) -{ - int i; - AVParserStreamState *ss; - - if (!state) - return; - - for (i = 0; i < state->nb_streams; i++) { - ss = &state->stream_states[i]; - if (ss->parser) - av_parser_close(ss->parser); - av_free_packet(&ss->cur_pkt); - } - - free_packet_list(state->packet_buffer); - free_packet_list(state->raw_packet_buffer); - - av_free(state->stream_states); - av_free(state); -} - diff --git a/tizen/distrib/ffmpeg/libavformat/seek.h b/tizen/distrib/ffmpeg/libavformat/seek.h deleted file mode 100644 index 408f7d6..0000000 --- a/tizen/distrib/ffmpeg/libavformat/seek.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * seek utility functions for use within format handlers - * - * Copyright (c) 2009 Ivan Schreter - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_SEEK_H -#define AVFORMAT_SEEK_H - -#include "avformat.h" - -/** - * structure to store parser state of one AVStream - */ -typedef struct AVParserStreamState { - // saved members of AVStream - AVCodecParserContext *parser; - AVPacket cur_pkt; - int64_t last_IP_pts; - int64_t cur_dts; - int64_t reference_dts; - const uint8_t *cur_ptr; - int cur_len; - int probe_packets; -} AVParserStreamState; - -/** - * structure to store parser state of AVFormat - */ -typedef struct AVParserState { - int64_t fpos; ///< file position at the time of call - - // saved members of AVFormatContext - AVStream *cur_st; ///< current stream. - AVPacketList *packet_buffer; ///< packet buffer of original state - AVPacketList *raw_packet_buffer; ///< raw packet buffer of original state - int raw_packet_buffer_remaining_size; ///< remaining space in raw_packet_buffer - - // saved info for streams - int nb_streams; ///< number of streams with stored state - AVParserStreamState *stream_states; ///< states of individual streams (array) -} AVParserState; - -/** - * Search for the sync point of all active streams. - * - * This routine is not supposed to be called directly by a user application, - * but by demuxers. - * - * A sync point is defined as a point in stream, such that, when decoding start - * from this point, the decoded output of all streams synchronizes closest - * to the given timestamp ts. This routine also takes timestamp limits into account. - * Thus, the output will synchronize no sooner than ts_min and no later than ts_max. - * - * @param stream_index stream index for time base reference of timestamps - * @param pos approximate position where to start searching for key frames - * @param min_ts minimum allowed timestamp (position, if AVSEEK_FLAG_BYTE set) - * @param ts target timestamp (or position, if AVSEEK_FLAG_BYTE set in flags) - * @param max_ts maximum allowed timestamp (position, if AVSEEK_FLAG_BYTE set) - * @param flags if AVSEEK_FLAG_ANY is set, seek to any frame, otherwise only - * to a keyframe. If AVSEEK_FLAG_BYTE is set, search by - * position, not by timestamp. - * @return -1 if no such sync point could be found, otherwise stream position - * (stream is repositioned to this position) - */ -int64_t ff_gen_syncpoint_search(AVFormatContext *s, - int stream_index, - int64_t pos, - int64_t min_ts, - int64_t ts, - int64_t max_ts, - int flags); - -/** - * Store current parser state and file position. - * - * This function can be used by demuxers before a destructive seeking algorithm - * to store the parser state. Depending on the outcome of the seek, either the original - * state can be restored or the new state kept and the original state freed. - * - * @note As a side effect, the original parser state is reset, since structures - * are relinked to the stored state instead of being deeply-copied (for - * performance reasons and to keep the code simple). - * - * @param s context from which to save state - * @return parser state object or NULL if memory could not be allocated - */ -AVParserState *ff_store_parser_state(AVFormatContext *s); - -/** - * Restore previously saved parser state and file position. - * - * Saved state will be invalidated and freed by this call, since internal - * structures will be relinked back to the stored state instead of being - * deeply-copied. - * - * @param s context to which to restore state (same as used for storing state) - * @param state state to restore - */ -void ff_restore_parser_state(AVFormatContext *s, AVParserState *state); - -/** - * Free previously saved parser state. - * - * @param s context to which the state belongs (same as used for storing state) - * @param state state to free - */ -void ff_free_parser_state(AVFormatContext *s, AVParserState *state); - -#endif /* AVFORMAT_SEEK_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/segafilm.c b/tizen/distrib/ffmpeg/libavformat/segafilm.c deleted file mode 100644 index 6274041..0000000 --- a/tizen/distrib/ffmpeg/libavformat/segafilm.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Sega FILM Format (CPK) Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sega FILM (.cpk) file demuxer - * by Mike Melanson (melanson@pcisys.net) - * For more information regarding the Sega FILM file format, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define FILM_TAG MKBETAG('F', 'I', 'L', 'M') -#define FDSC_TAG MKBETAG('F', 'D', 'S', 'C') -#define STAB_TAG MKBETAG('S', 'T', 'A', 'B') -#define CVID_TAG MKBETAG('c', 'v', 'i', 'd') - -typedef struct { - int stream; - int64_t sample_offset; - unsigned int sample_size; - int64_t pts; - int keyframe; -} film_sample; - -typedef struct FilmDemuxContext { - int video_stream_index; - int audio_stream_index; - - enum CodecID audio_type; - unsigned int audio_samplerate; - unsigned int audio_bits; - unsigned int audio_channels; - - enum CodecID video_type; - unsigned int sample_count; - film_sample *sample_table; - unsigned int current_sample; - - unsigned int base_clock; - unsigned int version; - - /* buffer used for interleaving stereo PCM data */ - unsigned char *stereo_buffer; - int stereo_buffer_size; -} FilmDemuxContext; - -static int film_probe(AVProbeData *p) -{ - if (AV_RB32(&p->buf[0]) != FILM_TAG) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int film_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - FilmDemuxContext *film = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - unsigned char scratch[256]; - int i; - unsigned int data_offset; - unsigned int audio_frame_counter; - - film->sample_table = NULL; - film->stereo_buffer = NULL; - film->stereo_buffer_size = 0; - - /* load the main FILM header */ - if (get_buffer(pb, scratch, 16) != 16) - return AVERROR(EIO); - data_offset = AV_RB32(&scratch[4]); - film->version = AV_RB32(&scratch[8]); - - /* load the FDSC chunk */ - if (film->version == 0) { - /* special case for Lemmings .film files; 20-byte header */ - if (get_buffer(pb, scratch, 20) != 20) - return AVERROR(EIO); - /* make some assumptions about the audio parameters */ - film->audio_type = CODEC_ID_PCM_S8; - film->audio_samplerate = 22050; - film->audio_channels = 1; - film->audio_bits = 8; - } else { - /* normal Saturn .cpk files; 32-byte header */ - if (get_buffer(pb, scratch, 32) != 32) - return AVERROR(EIO); - film->audio_samplerate = AV_RB16(&scratch[24]); - film->audio_channels = scratch[21]; - film->audio_bits = scratch[22]; - if (film->audio_bits == 8) - film->audio_type = CODEC_ID_PCM_S8; - else if (film->audio_bits == 16) - film->audio_type = CODEC_ID_PCM_S16BE; - else - film->audio_type = CODEC_ID_NONE; - } - - if (AV_RB32(&scratch[0]) != FDSC_TAG) - return AVERROR_INVALIDDATA; - - if (AV_RB32(&scratch[8]) == CVID_TAG) { - film->video_type = CODEC_ID_CINEPAK; - } else - film->video_type = CODEC_ID_NONE; - - /* initialize the decoder streams */ - if (film->video_type) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - film->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = film->video_type; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = AV_RB32(&scratch[16]); - st->codec->height = AV_RB32(&scratch[12]); - } - - if (film->audio_type) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - film->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = film->audio_type; - st->codec->codec_tag = 1; - st->codec->channels = film->audio_channels; - st->codec->bits_per_coded_sample = film->audio_bits; - st->codec->sample_rate = film->audio_samplerate; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * - st->codec->bits_per_coded_sample / 8; - } - - /* load the sample table */ - if (get_buffer(pb, scratch, 16) != 16) - return AVERROR(EIO); - if (AV_RB32(&scratch[0]) != STAB_TAG) - return AVERROR_INVALIDDATA; - film->base_clock = AV_RB32(&scratch[8]); - film->sample_count = AV_RB32(&scratch[12]); - if(film->sample_count >= UINT_MAX / sizeof(film_sample)) - return -1; - film->sample_table = av_malloc(film->sample_count * sizeof(film_sample)); - - for(i=0; inb_streams; i++) - av_set_pts_info(s->streams[i], 33, 1, film->base_clock); - - audio_frame_counter = 0; - for (i = 0; i < film->sample_count; i++) { - /* load the next sample record and transfer it to an internal struct */ - if (get_buffer(pb, scratch, 16) != 16) { - av_free(film->sample_table); - return AVERROR(EIO); - } - film->sample_table[i].sample_offset = - data_offset + AV_RB32(&scratch[0]); - film->sample_table[i].sample_size = AV_RB32(&scratch[4]); - if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) { - film->sample_table[i].stream = film->audio_stream_index; - film->sample_table[i].pts = audio_frame_counter; - film->sample_table[i].pts *= film->base_clock; - film->sample_table[i].pts /= film->audio_samplerate; - - audio_frame_counter += (film->sample_table[i].sample_size / - (film->audio_channels * film->audio_bits / 8)); - } else { - film->sample_table[i].stream = film->video_stream_index; - film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF; - film->sample_table[i].keyframe = (scratch[8] & 0x80) ? 0 : 1; - } - } - - film->current_sample = 0; - - return 0; -} - -static int film_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - FilmDemuxContext *film = s->priv_data; - ByteIOContext *pb = s->pb; - film_sample *sample; - int ret = 0; - int i; - int left, right; - - if (film->current_sample >= film->sample_count) - return AVERROR(EIO); - - sample = &film->sample_table[film->current_sample]; - - /* position the stream (will probably be there anyway) */ - url_fseek(pb, sample->sample_offset, SEEK_SET); - - /* do a special song and dance when loading FILM Cinepak chunks */ - if ((sample->stream == film->video_stream_index) && - (film->video_type == CODEC_ID_CINEPAK)) { - pkt->pos= url_ftell(pb); - if (av_new_packet(pkt, sample->sample_size)) - return AVERROR(ENOMEM); - get_buffer(pb, pkt->data, sample->sample_size); - } else if ((sample->stream == film->audio_stream_index) && - (film->audio_channels == 2)) { - /* stereo PCM needs to be interleaved */ - - if (av_new_packet(pkt, sample->sample_size)) - return AVERROR(ENOMEM); - - /* make sure the interleave buffer is large enough */ - if (sample->sample_size > film->stereo_buffer_size) { - av_free(film->stereo_buffer); - film->stereo_buffer_size = sample->sample_size; - film->stereo_buffer = av_malloc(film->stereo_buffer_size); - } - - pkt->pos= url_ftell(pb); - ret = get_buffer(pb, film->stereo_buffer, sample->sample_size); - if (ret != sample->sample_size) - ret = AVERROR(EIO); - - left = 0; - right = sample->sample_size / 2; - for (i = 0; i < sample->sample_size; ) { - if (film->audio_bits == 8) { - pkt->data[i++] = film->stereo_buffer[left++]; - pkt->data[i++] = film->stereo_buffer[right++]; - } else { - pkt->data[i++] = film->stereo_buffer[left++]; - pkt->data[i++] = film->stereo_buffer[left++]; - pkt->data[i++] = film->stereo_buffer[right++]; - pkt->data[i++] = film->stereo_buffer[right++]; - } - } - } else { - ret= av_get_packet(pb, pkt, sample->sample_size); - if (ret != sample->sample_size) - ret = AVERROR(EIO); - } - - pkt->stream_index = sample->stream; - pkt->pts = sample->pts; - - film->current_sample++; - - return ret; -} - -static int film_read_close(AVFormatContext *s) -{ - FilmDemuxContext *film = s->priv_data; - - av_free(film->sample_table); - av_free(film->stereo_buffer); - - return 0; -} - -AVInputFormat segafilm_demuxer = { - "film_cpk", - NULL_IF_CONFIG_SMALL("Sega FILM/CPK format"), - sizeof(FilmDemuxContext), - film_probe, - film_read_header, - film_read_packet, - film_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/sierravmd.c b/tizen/distrib/ffmpeg/libavformat/sierravmd.c deleted file mode 100644 index c239f5c..0000000 --- a/tizen/distrib/ffmpeg/libavformat/sierravmd.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Sierra VMD Format Demuxer - * Copyright (c) 2004 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Sierra VMD file demuxer - * by Vladimir "VAG" Gneushev (vagsoft at mail.ru) - * for more information on the Sierra VMD file format, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define VMD_HEADER_SIZE 0x0330 -#define BYTES_PER_FRAME_RECORD 16 - -typedef struct { - int stream_index; - int64_t frame_offset; - unsigned int frame_size; - int64_t pts; - int keyframe; - unsigned char frame_record[BYTES_PER_FRAME_RECORD]; -} vmd_frame; - -typedef struct VmdDemuxContext { - int video_stream_index; - int audio_stream_index; - - unsigned int frame_count; - unsigned int frames_per_block; - vmd_frame *frame_table; - unsigned int current_frame; - int is_indeo3; - - int sample_rate; - int64_t audio_sample_counter; - int skiphdr; - - unsigned char vmd_header[VMD_HEADER_SIZE]; -} VmdDemuxContext; - -static int vmd_probe(AVProbeData *p) -{ - int w, h; - if (p->buf_size < 16) - return 0; - /* check if the first 2 bytes of the file contain the appropriate size - * of a VMD header chunk */ - if (AV_RL16(&p->buf[0]) != VMD_HEADER_SIZE - 2) - return 0; - w = AV_RL16(&p->buf[12]); - h = AV_RL16(&p->buf[14]); - if (!w || w > 2048 || !h || h > 2048) - return 0; - - /* only return half certainty since this check is a bit sketchy */ - return AVPROBE_SCORE_MAX / 2; -} - -static int vmd_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - VmdDemuxContext *vmd = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st = NULL, *vst; - unsigned int toc_offset; - unsigned char *raw_frame_table; - int raw_frame_table_size; - int64_t current_offset; - int i, j; - unsigned int total_frames; - int64_t current_audio_pts = 0; - unsigned char chunk[BYTES_PER_FRAME_RECORD]; - int num, den; - int sound_buffers; - - /* fetch the main header, including the 2 header length bytes */ - url_fseek(pb, 0, SEEK_SET); - if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE) - return AVERROR(EIO); - - if(vmd->vmd_header[16] == 'i' && vmd->vmd_header[17] == 'v' && vmd->vmd_header[18] == '3') - vmd->is_indeo3 = 1; - else - vmd->is_indeo3 = 0; - /* start up the decoders */ - vst = av_new_stream(s, 0); - if (!vst) - return AVERROR(ENOMEM); - av_set_pts_info(vst, 33, 1, 10); - vmd->video_stream_index = vst->index; - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = vmd->is_indeo3 ? CODEC_ID_INDEO3 : CODEC_ID_VMDVIDEO; - vst->codec->codec_tag = 0; /* no fourcc */ - vst->codec->width = AV_RL16(&vmd->vmd_header[12]); - vst->codec->height = AV_RL16(&vmd->vmd_header[14]); - if(vmd->is_indeo3 && vst->codec->width > 320){ - vst->codec->width >>= 1; - vst->codec->height >>= 1; - } - vst->codec->extradata_size = VMD_HEADER_SIZE; - vst->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(vst->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE); - - /* if sample rate is 0, assume no audio */ - vmd->sample_rate = AV_RL16(&vmd->vmd_header[804]); - if (vmd->sample_rate) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - vmd->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_VMDAUDIO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1; - st->codec->sample_rate = vmd->sample_rate; - st->codec->block_align = AV_RL16(&vmd->vmd_header[806]); - if (st->codec->block_align & 0x8000) { - st->codec->bits_per_coded_sample = 16; - st->codec->block_align = -(st->codec->block_align - 0x10000); - } else { - st->codec->bits_per_coded_sample = 8; - } - st->codec->bit_rate = st->codec->sample_rate * - st->codec->bits_per_coded_sample * st->codec->channels; - - /* calculate pts */ - num = st->codec->block_align; - den = st->codec->sample_rate * st->codec->channels; - av_reduce(&den, &num, den, num, (1UL<<31)-1); - av_set_pts_info(vst, 33, num, den); - av_set_pts_info(st, 33, num, den); - } - - toc_offset = AV_RL32(&vmd->vmd_header[812]); - vmd->frame_count = AV_RL16(&vmd->vmd_header[6]); - vmd->frames_per_block = AV_RL16(&vmd->vmd_header[18]); - url_fseek(pb, toc_offset, SEEK_SET); - - raw_frame_table = NULL; - vmd->frame_table = NULL; - sound_buffers = AV_RL16(&vmd->vmd_header[808]); - raw_frame_table_size = vmd->frame_count * 6; - if(vmd->frame_count * vmd->frames_per_block >= UINT_MAX / sizeof(vmd_frame) - sound_buffers){ - av_log(s, AV_LOG_ERROR, "vmd->frame_count * vmd->frames_per_block too large\n"); - return -1; - } - raw_frame_table = av_malloc(raw_frame_table_size); - vmd->frame_table = av_malloc((vmd->frame_count * vmd->frames_per_block + sound_buffers) * sizeof(vmd_frame)); - if (!raw_frame_table || !vmd->frame_table) { - av_free(raw_frame_table); - av_free(vmd->frame_table); - return AVERROR(ENOMEM); - } - if (get_buffer(pb, raw_frame_table, raw_frame_table_size) != - raw_frame_table_size) { - av_free(raw_frame_table); - av_free(vmd->frame_table); - return AVERROR(EIO); - } - - total_frames = 0; - for (i = 0; i < vmd->frame_count; i++) { - - current_offset = AV_RL32(&raw_frame_table[6 * i + 2]); - - /* handle each entry in index block */ - for (j = 0; j < vmd->frames_per_block; j++) { - int type; - uint32_t size; - - get_buffer(pb, chunk, BYTES_PER_FRAME_RECORD); - type = chunk[0]; - size = AV_RL32(&chunk[2]); - if(!size && type != 1) - continue; - switch(type) { - case 1: /* Audio Chunk */ - if (!st) break; - /* first audio chunk contains several audio buffers */ - vmd->frame_table[total_frames].frame_offset = current_offset; - vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index; - vmd->frame_table[total_frames].frame_size = size; - memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD); - vmd->frame_table[total_frames].pts = current_audio_pts; - total_frames++; - if(!current_audio_pts) - current_audio_pts += sound_buffers; - else - current_audio_pts++; - break; - case 2: /* Video Chunk */ - vmd->frame_table[total_frames].frame_offset = current_offset; - vmd->frame_table[total_frames].stream_index = vmd->video_stream_index; - vmd->frame_table[total_frames].frame_size = size; - memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD); - vmd->frame_table[total_frames].pts = i; - total_frames++; - break; - } - current_offset += size; - } - } - - av_free(raw_frame_table); - - vmd->current_frame = 0; - vmd->frame_count = total_frames; - - return 0; -} - -static int vmd_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - VmdDemuxContext *vmd = s->priv_data; - ByteIOContext *pb = s->pb; - int ret = 0; - vmd_frame *frame; - - if (vmd->current_frame >= vmd->frame_count) - return AVERROR(EIO); - - frame = &vmd->frame_table[vmd->current_frame]; - /* position the stream (will probably be there already) */ - url_fseek(pb, frame->frame_offset, SEEK_SET); - - if (av_new_packet(pkt, frame->frame_size + BYTES_PER_FRAME_RECORD)) - return AVERROR(ENOMEM); - pkt->pos= url_ftell(pb); - memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD); - if(vmd->is_indeo3) - ret = get_buffer(pb, pkt->data, frame->frame_size); - else - ret = get_buffer(pb, pkt->data + BYTES_PER_FRAME_RECORD, - frame->frame_size); - - if (ret != frame->frame_size) { - av_free_packet(pkt); - ret = AVERROR(EIO); - } - pkt->stream_index = frame->stream_index; - pkt->pts = frame->pts; - av_log(s, AV_LOG_DEBUG, " dispatching %s frame with %d bytes and pts %"PRId64"\n", - (frame->frame_record[0] == 0x02) ? "video" : "audio", - frame->frame_size + BYTES_PER_FRAME_RECORD, - pkt->pts); - - vmd->current_frame++; - - return ret; -} - -static int vmd_read_close(AVFormatContext *s) -{ - VmdDemuxContext *vmd = s->priv_data; - - av_free(vmd->frame_table); - - return 0; -} - -AVInputFormat vmd_demuxer = { - "vmd", - NULL_IF_CONFIG_SMALL("Sierra VMD format"), - sizeof(VmdDemuxContext), - vmd_probe, - vmd_read_header, - vmd_read_packet, - vmd_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/siff.c b/tizen/distrib/ffmpeg/libavformat/siff.c deleted file mode 100644 index 3a0b9bb..0000000 --- a/tizen/distrib/ffmpeg/libavformat/siff.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Beam Software SIFF demuxer - * Copyright (c) 2007 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -enum SIFFTags{ - TAG_SIFF = MKTAG('S', 'I', 'F', 'F'), - TAG_BODY = MKTAG('B', 'O', 'D', 'Y'), - TAG_VBHD = MKTAG('V', 'B', 'H', 'D'), - TAG_SHDR = MKTAG('S', 'H', 'D', 'R'), - TAG_VBV1 = MKTAG('V', 'B', 'V', '1'), - TAG_SOUN = MKTAG('S', 'O', 'U', 'N'), -}; - -enum VBFlags{ - VB_HAS_GMC = 0x01, - VB_HAS_AUDIO = 0x04, - VB_HAS_VIDEO = 0x08, - VB_HAS_PALETTE = 0x10, - VB_HAS_LENGTH = 0x20 -}; - -typedef struct SIFFContext{ - int frames; - int cur_frame; - int rate; - int bits; - int block_align; - - int has_video; - int has_audio; - - int curstrm; - int pktsize; - int gmcsize; - int sndsize; - - int flags; - uint8_t gmc[4]; -}SIFFContext; - -static int siff_probe(AVProbeData *p) -{ - uint32_t tag = AV_RL32(p->buf + 8); - /* check file header */ - if (AV_RL32(p->buf) != TAG_SIFF || - (tag != TAG_VBV1 && tag != TAG_SOUN)) - return 0; - return AVPROBE_SCORE_MAX; -} - -static int create_audio_stream(AVFormatContext *s, SIFFContext *c) -{ - AVStream *ast; - ast = av_new_stream(s, 0); - if (!ast) - return -1; - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = CODEC_ID_PCM_U8; - ast->codec->channels = 1; - ast->codec->bits_per_coded_sample = c->bits; - ast->codec->sample_rate = c->rate; - ast->codec->frame_size = c->block_align; - av_set_pts_info(ast, 16, 1, c->rate); - return 0; -} - -static int siff_parse_vbv1(AVFormatContext *s, SIFFContext *c, ByteIOContext *pb) -{ - AVStream *st; - int width, height; - - if (get_le32(pb) != TAG_VBHD){ - av_log(s, AV_LOG_ERROR, "Header chunk is missing\n"); - return -1; - } - if(get_be32(pb) != 32){ - av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n"); - return -1; - } - if(get_le16(pb) != 1){ - av_log(s, AV_LOG_ERROR, "Incorrect header version\n"); - return -1; - } - width = get_le16(pb); - height = get_le16(pb); - url_fskip(pb, 4); - c->frames = get_le16(pb); - if(!c->frames){ - av_log(s, AV_LOG_ERROR, "File contains no frames ???\n"); - return -1; - } - c->bits = get_le16(pb); - c->rate = get_le16(pb); - c->block_align = c->rate * (c->bits >> 3); - - url_fskip(pb, 16); //zeroes - - st = av_new_stream(s, 0); - if (!st) - return -1; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_VB; - st->codec->codec_tag = MKTAG('V', 'B', 'V', '1'); - st->codec->width = width; - st->codec->height = height; - st->codec->pix_fmt = PIX_FMT_PAL8; - av_set_pts_info(st, 16, 1, 12); - - c->cur_frame = 0; - c->has_video = 1; - c->has_audio = !!c->rate; - c->curstrm = -1; - if (c->has_audio && create_audio_stream(s, c) < 0) - return -1; - return 0; -} - -static int siff_parse_soun(AVFormatContext *s, SIFFContext *c, ByteIOContext *pb) -{ - if (get_le32(pb) != TAG_SHDR){ - av_log(s, AV_LOG_ERROR, "Header chunk is missing\n"); - return -1; - } - if(get_be32(pb) != 8){ - av_log(s, AV_LOG_ERROR, "Header chunk size is incorrect\n"); - return -1; - } - url_fskip(pb, 4); //unknown value - c->rate = get_le16(pb); - c->bits = get_le16(pb); - c->block_align = c->rate * (c->bits >> 3); - return create_audio_stream(s, c); -} - -static int siff_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - SIFFContext *c = s->priv_data; - uint32_t tag; - - if (get_le32(pb) != TAG_SIFF) - return -1; - url_fskip(pb, 4); //ignore size - tag = get_le32(pb); - - if (tag != TAG_VBV1 && tag != TAG_SOUN){ - av_log(s, AV_LOG_ERROR, "Not a VBV file\n"); - return -1; - } - - if (tag == TAG_VBV1 && siff_parse_vbv1(s, c, pb) < 0) - return -1; - if (tag == TAG_SOUN && siff_parse_soun(s, c, pb) < 0) - return -1; - if (get_le32(pb) != MKTAG('B', 'O', 'D', 'Y')){ - av_log(s, AV_LOG_ERROR, "'BODY' chunk is missing\n"); - return -1; - } - url_fskip(pb, 4); //ignore size - - return 0; -} - -static int siff_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - SIFFContext *c = s->priv_data; - int size; - - if (c->has_video){ - if (c->cur_frame >= c->frames) - return AVERROR(EIO); - if (c->curstrm == -1){ - c->pktsize = get_le32(s->pb) - 4; - c->flags = get_le16(s->pb); - c->gmcsize = (c->flags & VB_HAS_GMC) ? 4 : 0; - if (c->gmcsize) - get_buffer(s->pb, c->gmc, c->gmcsize); - c->sndsize = (c->flags & VB_HAS_AUDIO) ? get_le32(s->pb): 0; - c->curstrm = !!(c->flags & VB_HAS_AUDIO); - } - - if (!c->curstrm){ - size = c->pktsize - c->sndsize; - if (av_new_packet(pkt, size) < 0) - return AVERROR(ENOMEM); - AV_WL16(pkt->data, c->flags); - if (c->gmcsize) - memcpy(pkt->data + 2, c->gmc, c->gmcsize); - get_buffer(s->pb, pkt->data + 2 + c->gmcsize, size - c->gmcsize - 2); - pkt->stream_index = 0; - c->curstrm = -1; - }else{ - if (av_get_packet(s->pb, pkt, c->sndsize - 4) < 0) - return AVERROR(EIO); - pkt->stream_index = 1; - c->curstrm = 0; - } - if(!c->cur_frame || c->curstrm) - pkt->flags |= AV_PKT_FLAG_KEY; - if (c->curstrm == -1) - c->cur_frame++; - }else{ - size = av_get_packet(s->pb, pkt, c->block_align); - if(size <= 0) - return AVERROR(EIO); - } - return pkt->size; -} - -AVInputFormat siff_demuxer = { - "siff", - NULL_IF_CONFIG_SMALL("Beam Software SIFF"), - sizeof(SIFFContext), - siff_probe, - siff_read_header, - siff_read_packet, - .extensions = "vb,son" -}; diff --git a/tizen/distrib/ffmpeg/libavformat/smacker.c b/tizen/distrib/ffmpeg/libavformat/smacker.c deleted file mode 100644 index 0dcc286..0000000 --- a/tizen/distrib/ffmpeg/libavformat/smacker.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Smacker demuxer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * Based on http://wiki.multimedia.cx/index.php?title=Smacker - */ - -#include "libavutil/bswap.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define SMACKER_PAL 0x01 -#define SMACKER_FLAG_RING_FRAME 0x01 - -enum SAudFlags { - SMK_AUD_PACKED = 0x80000000, - SMK_AUD_16BITS = 0x20000000, - SMK_AUD_STEREO = 0x10000000, - SMK_AUD_BINKAUD = 0x08000000, - SMK_AUD_USEDCT = 0x04000000 -}; - -typedef struct SmackerContext { - /* Smacker file header */ - uint32_t magic; - uint32_t width, height; - uint32_t frames; - int pts_inc; - uint32_t flags; - uint32_t audio[7]; - uint32_t treesize; - uint32_t mmap_size, mclr_size, full_size, type_size; - uint32_t rates[7]; - uint32_t pad; - /* frame info */ - uint32_t *frm_size; - uint8_t *frm_flags; - /* internal variables */ - int cur_frame; - int is_ver4; - int64_t cur_pts; - /* current frame for demuxing */ - uint8_t pal[768]; - int indexes[7]; - int videoindex; - uint8_t *bufs[7]; - int buf_sizes[7]; - int stream_id[7]; - int curstream; - int64_t nextpos; - int64_t aud_pts[7]; -} SmackerContext; - -typedef struct SmackerFrame { - int64_t pts; - int stream; -} SmackerFrame; - -/* palette used in Smacker */ -static const uint8_t smk_pal[64] = { - 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, - 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C, - 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D, - 0x61, 0x65, 0x69, 0x6D, 0x71, 0x75, 0x79, 0x7D, - 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9A, 0x9E, - 0xA2, 0xA6, 0xAA, 0xAE, 0xB2, 0xB6, 0xBA, 0xBE, - 0xC3, 0xC7, 0xCB, 0xCF, 0xD3, 0xD7, 0xDB, 0xDF, - 0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF -}; - - -static int smacker_probe(AVProbeData *p) -{ - if(p->buf[0] == 'S' && p->buf[1] == 'M' && p->buf[2] == 'K' - && (p->buf[3] == '2' || p->buf[3] == '4')) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - SmackerContext *smk = s->priv_data; - AVStream *st, *ast[7]; - int i, ret; - int tbase; - - /* read and check header */ - smk->magic = get_le32(pb); - if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4')) - return -1; - smk->width = get_le32(pb); - smk->height = get_le32(pb); - smk->frames = get_le32(pb); - smk->pts_inc = (int32_t)get_le32(pb); - smk->flags = get_le32(pb); - if(smk->flags & SMACKER_FLAG_RING_FRAME) - smk->frames++; - for(i = 0; i < 7; i++) - smk->audio[i] = get_le32(pb); - smk->treesize = get_le32(pb); - - if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant) - av_log(s, AV_LOG_ERROR, "treesize too large\n"); - return -1; - } - -//FIXME remove extradata "rebuilding" - smk->mmap_size = get_le32(pb); - smk->mclr_size = get_le32(pb); - smk->full_size = get_le32(pb); - smk->type_size = get_le32(pb); - for(i = 0; i < 7; i++) - smk->rates[i] = get_le32(pb); - smk->pad = get_le32(pb); - /* setup data */ - if(smk->frames > 0xFFFFFF) { - av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames); - return -1; - } - smk->frm_size = av_malloc(smk->frames * 4); - smk->frm_flags = av_malloc(smk->frames); - - smk->is_ver4 = (smk->magic != MKTAG('S', 'M', 'K', '2')); - - /* read frame info */ - for(i = 0; i < smk->frames; i++) { - smk->frm_size[i] = get_le32(pb); - } - for(i = 0; i < smk->frames; i++) { - smk->frm_flags[i] = get_byte(pb); - } - - /* init video codec */ - st = av_new_stream(s, 0); - if (!st) - return -1; - smk->videoindex = st->index; - st->codec->width = smk->width; - st->codec->height = smk->height; - st->codec->pix_fmt = PIX_FMT_PAL8; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_SMACKVIDEO; - st->codec->codec_tag = smk->magic; - /* Smacker uses 100000 as internal timebase */ - if(smk->pts_inc < 0) - smk->pts_inc = -smk->pts_inc; - else - smk->pts_inc *= 100; - tbase = 100000; - av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1); - av_set_pts_info(st, 33, smk->pts_inc, tbase); - st->duration = smk->frames; - /* handle possible audio streams */ - for(i = 0; i < 7; i++) { - smk->indexes[i] = -1; - if(smk->rates[i] & 0xFFFFFF){ - ast[i] = av_new_stream(s, 0); - smk->indexes[i] = ast[i]->index; - ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO; - if (smk->rates[i] & SMK_AUD_BINKAUD) { - ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_RDFT; - } else if (smk->rates[i] & SMK_AUD_USEDCT) { - ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_DCT; - } else if (smk->rates[i] & SMK_AUD_PACKED){ - ast[i]->codec->codec_id = CODEC_ID_SMACKAUDIO; - ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A'); - } else { - ast[i]->codec->codec_id = CODEC_ID_PCM_U8; - } - ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1; - ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF; - ast[i]->codec->bits_per_coded_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8; - if(ast[i]->codec->bits_per_coded_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8) - ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE; - av_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate - * ast[i]->codec->channels * ast[i]->codec->bits_per_coded_sample / 8); - } - } - - - /* load trees to extradata, they will be unpacked by decoder */ - st->codec->extradata = av_malloc(smk->treesize + 16); - st->codec->extradata_size = smk->treesize + 16; - if(!st->codec->extradata){ - av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16); - av_free(smk->frm_size); - av_free(smk->frm_flags); - return -1; - } - ret = get_buffer(pb, st->codec->extradata + 16, st->codec->extradata_size - 16); - if(ret != st->codec->extradata_size - 16){ - av_free(smk->frm_size); - av_free(smk->frm_flags); - return AVERROR(EIO); - } - ((int32_t*)st->codec->extradata)[0] = le2me_32(smk->mmap_size); - ((int32_t*)st->codec->extradata)[1] = le2me_32(smk->mclr_size); - ((int32_t*)st->codec->extradata)[2] = le2me_32(smk->full_size); - ((int32_t*)st->codec->extradata)[3] = le2me_32(smk->type_size); - - smk->curstream = -1; - smk->nextpos = url_ftell(pb); - - return 0; -} - - -static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - SmackerContext *smk = s->priv_data; - int flags; - int ret; - int i; - int frame_size = 0; - int palchange = 0; - int pos; - - if (url_feof(s->pb) || smk->cur_frame >= smk->frames) - return AVERROR(EIO); - - /* if we demuxed all streams, pass another frame */ - if(smk->curstream < 0) { - url_fseek(s->pb, smk->nextpos, 0); - frame_size = smk->frm_size[smk->cur_frame] & (~3); - flags = smk->frm_flags[smk->cur_frame]; - /* handle palette change event */ - pos = url_ftell(s->pb); - if(flags & SMACKER_PAL){ - int size, sz, t, off, j, pos; - uint8_t *pal = smk->pal; - uint8_t oldpal[768]; - - memcpy(oldpal, pal, 768); - size = get_byte(s->pb); - size = size * 4 - 1; - frame_size -= size; - frame_size--; - sz = 0; - pos = url_ftell(s->pb) + size; - while(sz < 256){ - t = get_byte(s->pb); - if(t & 0x80){ /* skip palette entries */ - sz += (t & 0x7F) + 1; - pal += ((t & 0x7F) + 1) * 3; - } else if(t & 0x40){ /* copy with offset */ - off = get_byte(s->pb) * 3; - j = (t & 0x3F) + 1; - while(j-- && sz < 256) { - *pal++ = oldpal[off + 0]; - *pal++ = oldpal[off + 1]; - *pal++ = oldpal[off + 2]; - sz++; - off += 3; - } - } else { /* new entries */ - *pal++ = smk_pal[t]; - *pal++ = smk_pal[get_byte(s->pb) & 0x3F]; - *pal++ = smk_pal[get_byte(s->pb) & 0x3F]; - sz++; - } - } - url_fseek(s->pb, pos, 0); - palchange |= 1; - } - flags >>= 1; - smk->curstream = -1; - /* if audio chunks are present, put them to stack and retrieve later */ - for(i = 0; i < 7; i++) { - if(flags & 1) { - int size; - size = get_le32(s->pb) - 4; - frame_size -= size; - frame_size -= 4; - smk->curstream++; - smk->bufs[smk->curstream] = av_realloc(smk->bufs[smk->curstream], size); - smk->buf_sizes[smk->curstream] = size; - ret = get_buffer(s->pb, smk->bufs[smk->curstream], size); - if(ret != size) - return AVERROR(EIO); - smk->stream_id[smk->curstream] = smk->indexes[i]; - } - flags >>= 1; - } - if (av_new_packet(pkt, frame_size + 768)) - return AVERROR(ENOMEM); - if(smk->frm_size[smk->cur_frame] & 1) - palchange |= 2; - pkt->data[0] = palchange; - memcpy(pkt->data + 1, smk->pal, 768); - ret = get_buffer(s->pb, pkt->data + 769, frame_size); - if(ret != frame_size) - return AVERROR(EIO); - pkt->stream_index = smk->videoindex; - pkt->size = ret + 769; - smk->cur_frame++; - smk->nextpos = url_ftell(s->pb); - } else { - if (av_new_packet(pkt, smk->buf_sizes[smk->curstream])) - return AVERROR(ENOMEM); - memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]); - pkt->size = smk->buf_sizes[smk->curstream]; - pkt->stream_index = smk->stream_id[smk->curstream]; - pkt->pts = smk->aud_pts[smk->curstream]; - smk->aud_pts[smk->curstream] += AV_RL32(pkt->data); - smk->curstream--; - } - - return 0; -} - -static int smacker_read_close(AVFormatContext *s) -{ - SmackerContext *smk = s->priv_data; - int i; - - for(i = 0; i < 7; i++) - if(smk->bufs[i]) - av_free(smk->bufs[i]); - if(smk->frm_size) - av_free(smk->frm_size); - if(smk->frm_flags) - av_free(smk->frm_flags); - - return 0; -} - -AVInputFormat smacker_demuxer = { - "smk", - NULL_IF_CONFIG_SMALL("Smacker video"), - sizeof(SmackerContext), - smacker_probe, - smacker_read_header, - smacker_read_packet, - smacker_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/sol.c b/tizen/distrib/ffmpeg/libavformat/sol.c deleted file mode 100644 index 3ae2d04..0000000 --- a/tizen/distrib/ffmpeg/libavformat/sol.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Sierra SOL demuxer - * Copyright Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * Based on documents from Game Audio Player and own research - */ - -#include "libavutil/bswap.h" -#include "avformat.h" -#include "raw.h" - -/* if we don't know the size in advance */ -#define AU_UNKNOWN_SIZE ((uint32_t)(~0)) - -static int sol_probe(AVProbeData *p) -{ - /* check file header */ - uint16_t magic; - magic=le2me_16(*((uint16_t*)p->buf)); - if ((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) && - p->buf[2] == 'S' && p->buf[3] == 'O' && - p->buf[4] == 'L' && p->buf[5] == 0) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -#define SOL_DPCM 1 -#define SOL_16BIT 4 -#define SOL_STEREO 16 - -static enum CodecID sol_codec_id(int magic, int type) -{ - if (magic == 0x0B8D) - { - if (type & SOL_DPCM) return CODEC_ID_SOL_DPCM; - else return CODEC_ID_PCM_U8; - } - if (type & SOL_DPCM) - { - if (type & SOL_16BIT) return CODEC_ID_SOL_DPCM; - else if (magic == 0x0C8D) return CODEC_ID_SOL_DPCM; - else return CODEC_ID_SOL_DPCM; - } - if (type & SOL_16BIT) return CODEC_ID_PCM_S16LE; - return CODEC_ID_PCM_U8; -} - -static int sol_codec_type(int magic, int type) -{ - if (magic == 0x0B8D) return 1;//SOL_DPCM_OLD; - if (type & SOL_DPCM) - { - if (type & SOL_16BIT) return 3;//SOL_DPCM_NEW16; - else if (magic == 0x0C8D) return 1;//SOL_DPCM_OLD; - else return 2;//SOL_DPCM_NEW8; - } - return -1; -} - -static int sol_channels(int magic, int type) -{ - if (magic == 0x0B8D || !(type & SOL_STEREO)) return 1; - return 2; -} - -static int sol_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - int size; - unsigned int magic,tag; - ByteIOContext *pb = s->pb; - unsigned int id, channels, rate, type; - enum CodecID codec; - AVStream *st; - - /* check ".snd" header */ - magic = get_le16(pb); - tag = get_le32(pb); - if (tag != MKTAG('S', 'O', 'L', 0)) - return -1; - rate = get_le16(pb); - type = get_byte(pb); - size = get_le32(pb); - if (magic != 0x0B8D) - get_byte(pb); /* newer SOLs contain padding byte */ - - codec = sol_codec_id(magic, type); - channels = sol_channels(magic, type); - - if (codec == CODEC_ID_SOL_DPCM) - id = sol_codec_type(magic, type); - else id = 0; - - /* now we are ready: build format streams */ - st = av_new_stream(s, 0); - if (!st) - return -1; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = id; - st->codec->codec_id = codec; - st->codec->channels = channels; - st->codec->sample_rate = rate; - av_set_pts_info(st, 64, 1, rate); - return 0; -} - -#define MAX_SIZE 4096 - -static int sol_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret; - - if (url_feof(s->pb)) - return AVERROR(EIO); - ret= av_get_packet(s->pb, pkt, MAX_SIZE); - pkt->stream_index = 0; - - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - return 0; -} - -AVInputFormat sol_demuxer = { - "sol", - NULL_IF_CONFIG_SMALL("Sierra SOL format"), - 0, - sol_probe, - sol_read_header, - sol_read_packet, - NULL, - pcm_read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/sox.h b/tizen/distrib/ffmpeg/libavformat/sox.h deleted file mode 100644 index f4a12e9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/sox.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SoX native format common data - * Copyright (c) 2009 Daniel Verkamp - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_SOX_H -#define AVFORMAT_SOX_H - -#define SOX_FIXED_HDR (4 + 8 + 8 + 4 + 4) /**< Size of fixed header without magic */ - -#define SOX_TAG MKTAG('.', 'S', 'o', 'X') - -#endif /* AVFORMAT_SOX_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/soxdec.c b/tizen/distrib/ffmpeg/libavformat/soxdec.c deleted file mode 100644 index 42fa53e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/soxdec.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * SoX native format demuxer - * Copyright (c) 2009 Daniel Verkamp - * - * Based on libSoX sox-fmt.c - * Copyright (c) 2008 robs@users.sourceforge.net - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * SoX native format demuxer - * @file - * @author Daniel Verkamp - * @sa http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "raw.h" -#include "sox.h" - -static int sox_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == SOX_TAG || AV_RB32(p->buf) == SOX_TAG) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int sox_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - unsigned header_size, comment_size; - double sample_rate, sample_rate_frac; - AVStream *st; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - if (get_le32(pb) == SOX_TAG) { - st->codec->codec_id = CODEC_ID_PCM_S32LE; - header_size = get_le32(pb); - url_fskip(pb, 8); /* sample count */ - sample_rate = av_int2dbl(get_le64(pb)); - st->codec->channels = get_le32(pb); - comment_size = get_le32(pb); - } else { - st->codec->codec_id = CODEC_ID_PCM_S32BE; - header_size = get_be32(pb); - url_fskip(pb, 8); /* sample count */ - sample_rate = av_int2dbl(get_be64(pb)); - st->codec->channels = get_be32(pb); - comment_size = get_be32(pb); - } - - if (comment_size > 0xFFFFFFFFU - SOX_FIXED_HDR - 4U) { - av_log(s, AV_LOG_ERROR, "invalid comment size (%u)\n", comment_size); - return -1; - } - - if (sample_rate <= 0 || sample_rate > INT_MAX) { - av_log(s, AV_LOG_ERROR, "invalid sample rate (%f)\n", sample_rate); - return -1; - } - - sample_rate_frac = sample_rate - floor(sample_rate); - if (sample_rate_frac) - av_log(s, AV_LOG_WARNING, - "truncating fractional part of sample rate (%f)\n", - sample_rate_frac); - - if ((header_size + 4) & 7 || header_size < SOX_FIXED_HDR + comment_size - || st->codec->channels > 65535) /* Reserve top 16 bits */ { - av_log(s, AV_LOG_ERROR, "invalid header\n"); - return -1; - } - - if (comment_size && comment_size < UINT_MAX) { - char *comment = av_malloc(comment_size+1); - if (get_buffer(pb, comment, comment_size) != comment_size) { - av_freep(&comment); - return AVERROR(EIO); - } - comment[comment_size] = 0; - - av_metadata_set2(&s->metadata, "comment", comment, - AV_METADATA_DONT_STRDUP_VAL); - } - - url_fskip(pb, header_size - SOX_FIXED_HDR - comment_size); - - st->codec->sample_rate = sample_rate; - st->codec->bits_per_coded_sample = 32; - st->codec->bit_rate = st->codec->sample_rate * - st->codec->bits_per_coded_sample * - st->codec->channels; - st->codec->block_align = st->codec->bits_per_coded_sample * - st->codec->channels / 8; - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -#define SOX_SAMPLES 1024 - -static int sox_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret, size; - - if (url_feof(s->pb)) - return AVERROR_EOF; - - size = SOX_SAMPLES*s->streams[0]->codec->block_align; - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) - return AVERROR(EIO); - pkt->stream_index = 0; - pkt->size = ret; - - return 0; -} - -AVInputFormat sox_demuxer = { - "sox", - NULL_IF_CONFIG_SMALL("SoX native format"), - 0, - sox_probe, - sox_read_header, - sox_read_packet, - NULL, - pcm_read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/soxenc.c b/tizen/distrib/ffmpeg/libavformat/soxenc.c deleted file mode 100644 index 918bfad..0000000 --- a/tizen/distrib/ffmpeg/libavformat/soxenc.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SoX native format muxer - * Copyright (c) 2009 Daniel Verkamp - * - * Based on libSoX sox-fmt.c - * Copyright (c) 2008 robs@users.sourceforge.net - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * SoX native format muxer - * @file - * @author Daniel Verkamp - * @sa http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "sox.h" - -typedef struct { - int64_t header_size; -} SoXContext; - -static int sox_write_header(AVFormatContext *s) -{ - SoXContext *sox = s->priv_data; - ByteIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - AVMetadataTag *comment; - size_t comment_len = 0, comment_size; - - comment = av_metadata_get(s->metadata, "comment", NULL, 0); - if (comment) - comment_len = strlen(comment->value); - comment_size = (comment_len + 7) & ~7; - - sox->header_size = SOX_FIXED_HDR + comment_size; - - if (enc->codec_id == CODEC_ID_PCM_S32LE) { - put_tag(pb, ".SoX"); - put_le32(pb, sox->header_size); - put_le64(pb, 0); /* number of samples */ - put_le64(pb, av_dbl2int(enc->sample_rate)); - put_le32(pb, enc->channels); - put_le32(pb, comment_size); - } else if (enc->codec_id == CODEC_ID_PCM_S32BE) { - put_tag(pb, "XoS."); - put_be32(pb, sox->header_size); - put_be64(pb, 0); /* number of samples */ - put_be64(pb, av_dbl2int(enc->sample_rate)); - put_be32(pb, enc->channels); - put_be32(pb, comment_size); - } else { - av_log(s, AV_LOG_ERROR, "invalid codec; use pcm_s32le or pcm_s32be\n"); - return -1; - } - - if (comment_len) - put_buffer(pb, comment->value, comment_len); - - for ( ; comment_size > comment_len; comment_len++) - put_byte(pb, 0); - - put_flush_packet(pb); - - return 0; -} - -static int sox_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - put_buffer(pb, pkt->data, pkt->size); - return 0; -} - -static int sox_write_trailer(AVFormatContext *s) -{ - SoXContext *sox = s->priv_data; - ByteIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - - if (!url_is_streamed(s->pb)) { - /* update number of samples */ - int64_t file_size = url_ftell(pb); - int64_t num_samples = (file_size - sox->header_size - 4LL) >> 2LL; - url_fseek(pb, 8, SEEK_SET); - if (enc->codec_id == CODEC_ID_PCM_S32LE) { - put_le64(pb, num_samples); - } else - put_be64(pb, num_samples); - url_fseek(pb, file_size, SEEK_SET); - - put_flush_packet(pb); - } - - return 0; -} - -AVOutputFormat sox_muxer = { - "sox", - NULL_IF_CONFIG_SMALL("SoX native format"), - NULL, - "sox", - sizeof(SoXContext), - CODEC_ID_PCM_S32LE, - CODEC_ID_NONE, - sox_write_header, - sox_write_packet, - sox_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/spdif.c b/tizen/distrib/ffmpeg/libavformat/spdif.c deleted file mode 100644 index 1c53f73..0000000 --- a/tizen/distrib/ffmpeg/libavformat/spdif.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * IEC958 muxer - * Copyright (c) 2009 Bartlomiej Wolowiec - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * IEC-61937 encapsulation of various formats, used by S/PDIF - * @author Bartlomiej Wolowiec - */ - -/* - * Terminology used in specification: - * data-burst - IEC958 frame, contains header and encapsuled frame - * burst-preambule - IEC958 frame header, contains 16-bits words named Pa, Pb, Pc and Pd - * burst-payload - encapsuled frame - * Pa, Pb - syncword - 0xF872, 0x4E1F - * Pc - burst-info, contains data-type (bits 0-6), error flag (bit 7), data-type-dependent info (bits 8-12) - * and bitstream number (bits 13-15) - * data-type - determines type of encapsuled frames - * Pd - length code (number of bits or bytes of encapsuled frame - according to data_type) - * - * IEC958 frames at normal usage start every specific count of bytes, - * dependent from data-type (spaces between packets are filled by zeros) - */ - -#include "avformat.h" -#include "libavcodec/ac3.h" -#include "libavcodec/dca.h" -#include "libavcodec/aac_parser.h" - -#define SYNCWORD1 0xF872 -#define SYNCWORD2 0x4E1F -#define BURST_HEADER_SIZE 0x8 - -enum IEC958DataType { - IEC958_AC3 = 0x01, ///< AC-3 data - IEC958_MPEG1_LAYER1 = 0x04, ///< MPEG-1 layer 1 - IEC958_MPEG1_LAYER23 = 0x05, ///< MPEG-1 layer 2 or 3 data or MPEG-2 without extension - IEC958_MPEG2_EXT = 0x06, ///< MPEG-2 data with extension - IEC958_MPEG2_AAC = 0x07, ///< MPEG-2 AAC ADTS - IEC958_MPEG2_LAYER1_LSF = 0x08, ///< MPEG-2, layer-1 low sampling frequency - IEC958_MPEG2_LAYER2_LSF = 0x09, ///< MPEG-2, layer-2 low sampling frequency - IEC958_MPEG2_LAYER3_LSF = 0x0A, ///< MPEG-2, layer-3 low sampling frequency - IEC958_DTS1 = 0x0B, ///< DTS type I (512 samples) - IEC958_DTS2 = 0x0C, ///< DTS type II (1024 samples) - IEC958_DTS3 = 0x0D, ///< DTS type III (2048 samples) - IEC958_MPEG2_AAC_LSF_2048 = 0x13, ///< MPEG-2 AAC ADTS half-rate low sampling frequency - IEC958_MPEG2_AAC_LSF_4096 = 0x13 | 0x20, ///< MPEG-2 AAC ADTS quarter-rate low sampling frequency -}; - -typedef struct IEC958Context { - enum IEC958DataType data_type; ///< burst info - reference to type of payload of the data-burst - int pkt_size; ///< length code in bits - int pkt_offset; ///< data burst repetition period in bytes - uint8_t *buffer; ///< allocated buffer, used for swap bytes - int buffer_size; ///< size of allocated buffer - - /// function, which generates codec dependent header information. - /// Sets data_type and data_offset - int (*header_info) (AVFormatContext *s, AVPacket *pkt); -} IEC958Context; - -//TODO move to DSP -static void bswap_buf16(uint16_t *dst, const uint16_t *src, int w) -{ - int i; - - for (i = 0; i + 8 <= w; i += 8) { - dst[i + 0] = bswap_16(src[i + 0]); - dst[i + 1] = bswap_16(src[i + 1]); - dst[i + 2] = bswap_16(src[i + 2]); - dst[i + 3] = bswap_16(src[i + 3]); - dst[i + 4] = bswap_16(src[i + 4]); - dst[i + 5] = bswap_16(src[i + 5]); - dst[i + 6] = bswap_16(src[i + 6]); - dst[i + 7] = bswap_16(src[i + 7]); - } - for (; i < w; i++) - dst[i + 0] = bswap_16(src[i + 0]); -} - -static int spdif_header_ac3(AVFormatContext *s, AVPacket *pkt) -{ - IEC958Context *ctx = s->priv_data; - int bitstream_mode = pkt->data[6] & 0x7; - - ctx->data_type = IEC958_AC3 | (bitstream_mode << 8); - ctx->pkt_offset = AC3_FRAME_SIZE << 2; - return 0; -} - -static int spdif_header_dts(AVFormatContext *s, AVPacket *pkt) -{ - IEC958Context *ctx = s->priv_data; - uint32_t syncword_dts = AV_RB32(pkt->data); - int blocks; - - switch (syncword_dts) { - case DCA_MARKER_RAW_BE: - blocks = (AV_RB16(pkt->data + 4) >> 2) & 0x7f; - break; - case DCA_MARKER_RAW_LE: - blocks = (AV_RL16(pkt->data + 4) >> 2) & 0x7f; - break; - case DCA_MARKER_14B_BE: - blocks = - (((pkt->data[5] & 0x07) << 4) | ((pkt->data[6] & 0x3f) >> 2)); - break; - case DCA_MARKER_14B_LE: - blocks = - (((pkt->data[4] & 0x07) << 4) | ((pkt->data[7] & 0x3f) >> 2)); - break; - default: - av_log(s, AV_LOG_ERROR, "bad DTS syncword 0x%x\n", syncword_dts); - return -1; - } - blocks++; - switch (blocks) { - case 512 >> 5: ctx->data_type = IEC958_DTS1; break; - case 1024 >> 5: ctx->data_type = IEC958_DTS2; break; - case 2048 >> 5: ctx->data_type = IEC958_DTS3; break; - default: - av_log(s, AV_LOG_ERROR, "%i samples in DTS frame not supported\n", - blocks << 5); - return -1; - } - ctx->pkt_offset = blocks << 7; - - return 0; -} - -static const enum IEC958DataType mpeg_data_type[2][3] = { - // LAYER1 LAYER2 LAYER3 - { IEC958_MPEG2_LAYER1_LSF, IEC958_MPEG2_LAYER2_LSF, IEC958_MPEG2_LAYER3_LSF }, //MPEG2 LSF - { IEC958_MPEG1_LAYER1, IEC958_MPEG1_LAYER23, IEC958_MPEG1_LAYER23 }, //MPEG1 -}; - -static const uint16_t mpeg_pkt_offset[2][3] = { - //LAYER1 LAYER2 LAYER3 - { 3072, 9216, 4608 }, // MPEG2 LSF - { 1536, 4608, 4608 }, // MPEG1 -}; - -static int spdif_header_mpeg(AVFormatContext *s, AVPacket *pkt) -{ - IEC958Context *ctx = s->priv_data; - int version = (pkt->data[1] >> 3) & 3; - int layer = 3 - ((pkt->data[1] >> 1) & 3); - int extension = pkt->data[2] & 1; - - if (layer == 3 || version == 1) { - av_log(s, AV_LOG_ERROR, "Wrong MPEG file format\n"); - return -1; - } - av_log(s, AV_LOG_DEBUG, "version: %i layer: %i extension: %i\n", version, layer, extension); - if (version == 2 && extension) { - ctx->data_type = IEC958_MPEG2_EXT; - ctx->pkt_offset = 4608; - } else { - ctx->data_type = mpeg_data_type [version & 1][layer]; - ctx->pkt_offset = mpeg_pkt_offset[version & 1][layer]; - } - // TODO Data type dependant info (normal/karaoke, dynamic range control) - return 0; -} - -static int spdif_header_aac(AVFormatContext *s, AVPacket *pkt) -{ - IEC958Context *ctx = s->priv_data; - AACADTSHeaderInfo hdr; - GetBitContext gbc; - int ret; - - init_get_bits(&gbc, pkt->data, AAC_ADTS_HEADER_SIZE * 8); - ret = ff_aac_parse_header(&gbc, &hdr); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Wrong AAC file format\n"); - return -1; - } - - ctx->pkt_offset = hdr.samples << 2; - switch (hdr.num_aac_frames) { - case 1: - ctx->data_type = IEC958_MPEG2_AAC; - break; - case 2: - ctx->data_type = IEC958_MPEG2_AAC_LSF_2048; - break; - case 4: - ctx->data_type = IEC958_MPEG2_AAC_LSF_4096; - break; - default: - av_log(s, AV_LOG_ERROR, "%i samples in AAC frame not supported\n", - hdr.samples); - return -1; - } - //TODO Data type dependent info (LC profile/SBR) - return 0; -} - -static int spdif_write_header(AVFormatContext *s) -{ - IEC958Context *ctx = s->priv_data; - - switch (s->streams[0]->codec->codec_id) { - case CODEC_ID_AC3: - ctx->header_info = spdif_header_ac3; - break; - case CODEC_ID_MP1: - case CODEC_ID_MP2: - case CODEC_ID_MP3: - ctx->header_info = spdif_header_mpeg; - break; - case CODEC_ID_DTS: - ctx->header_info = spdif_header_dts; - break; - case CODEC_ID_AAC: - ctx->header_info = spdif_header_aac; - break; - default: - av_log(s, AV_LOG_ERROR, "codec not supported\n"); - return -1; - } - return 0; -} - -static int spdif_write_trailer(AVFormatContext *s) -{ - IEC958Context *ctx = s->priv_data; - av_freep(&ctx->buffer); - return 0; -} - -static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - IEC958Context *ctx = s->priv_data; - int ret, padding; - - ctx->pkt_size = FFALIGN(pkt->size, 2) << 3; - ret = ctx->header_info(s, pkt); - if (ret < 0) - return -1; - - padding = (ctx->pkt_offset - BURST_HEADER_SIZE - pkt->size) >> 1; - if (padding < 0) { - av_log(s, AV_LOG_ERROR, "bitrate is too high\n"); - return -1; - } - - put_le16(s->pb, SYNCWORD1); //Pa - put_le16(s->pb, SYNCWORD2); //Pb - put_le16(s->pb, ctx->data_type); //Pc - put_le16(s->pb, ctx->pkt_size); //Pd - -#if HAVE_BIGENDIAN - put_buffer(s->pb, pkt->data, pkt->size & ~1); -#else - av_fast_malloc(&ctx->buffer, &ctx->buffer_size, pkt->size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!ctx->buffer) - return AVERROR(ENOMEM); - bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)pkt->data, pkt->size >> 1); - put_buffer(s->pb, ctx->buffer, pkt->size & ~1); -#endif - - if (pkt->size & 1) - put_be16(s->pb, pkt->data[pkt->size - 1]); - - for (; padding > 0; padding--) - put_be16(s->pb, 0); - - av_log(s, AV_LOG_DEBUG, "type=%x len=%i pkt_offset=%i\n", - ctx->data_type, pkt->size, ctx->pkt_offset); - - put_flush_packet(s->pb); - return 0; -} - -AVOutputFormat spdif_muxer = { - "spdif", - NULL_IF_CONFIG_SMALL("IEC958 - S/PDIF (IEC-61937)"), - NULL, - "spdif", - sizeof(IEC958Context), - CODEC_ID_AC3, - CODEC_ID_NONE, - spdif_write_header, - spdif_write_packet, - spdif_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/swf.h b/tizen/distrib/ffmpeg/libavformat/swf.h deleted file mode 100644 index affebe9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/swf.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Flash Compatible Streaming Format common header. - * Copyright (c) 2000 Fabrice Bellard - * Copyright (c) 2003 Tinic Uro - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_SWF_H -#define AVFORMAT_SWF_H - -#include "libavutil/fifo.h" -#include "avformat.h" -#include "avio.h" -#include "riff.h" /* for CodecTag */ - -/* should have a generic way to indicate probable size */ -#define DUMMY_FILE_SIZE (100 * 1024 * 1024) -#define DUMMY_DURATION 600 /* in seconds */ - -#define TAG_END 0 -#define TAG_SHOWFRAME 1 -#define TAG_DEFINESHAPE 2 -#define TAG_FREECHARACTER 3 -#define TAG_PLACEOBJECT 4 -#define TAG_REMOVEOBJECT 5 -#define TAG_STREAMHEAD 18 -#define TAG_STREAMBLOCK 19 -#define TAG_JPEG2 21 -#define TAG_PLACEOBJECT2 26 -#define TAG_STREAMHEAD2 45 -#define TAG_VIDEOSTREAM 60 -#define TAG_VIDEOFRAME 61 -#define TAG_FILEATTRIBUTES 69 - -#define TAG_LONG 0x100 - -/* flags for shape definition */ -#define FLAG_MOVETO 0x01 -#define FLAG_SETFILL0 0x02 -#define FLAG_SETFILL1 0x04 - -#define AUDIO_FIFO_SIZE 65536 - -/* character id used */ -#define BITMAP_ID 0 -#define VIDEO_ID 0 -#define SHAPE_ID 1 - -#undef NDEBUG -#include - -typedef struct { - int64_t duration_pos; - int64_t tag_pos; - int64_t vframes_pos; - int samples_per_frame; - int sound_samples; - int swf_frame_number; - int video_frame_number; - int frame_rate; - int tag; - AVFifoBuffer *audio_fifo; - AVCodecContext *audio_enc, *video_enc; -} SWFContext; - -static const AVCodecTag swf_codec_tags[] = { - {CODEC_ID_FLV1, 0x02}, - {CODEC_ID_VP6F, 0x04}, - {CODEC_ID_NONE, 0}, -}; - -static const AVCodecTag swf_audio_codec_tags[] = { - {CODEC_ID_PCM_S16LE, 0x00}, - {CODEC_ID_ADPCM_SWF, 0x01}, - {CODEC_ID_MP3, 0x02}, - {CODEC_ID_PCM_S16LE, 0x03}, - //{CODEC_ID_NELLYMOSER, 0x06}, - {CODEC_ID_NONE, 0}, -}; - -#endif /* AVFORMAT_SWF_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/swfdec.c b/tizen/distrib/ffmpeg/libavformat/swfdec.c deleted file mode 100644 index 64f775f..0000000 --- a/tizen/distrib/ffmpeg/libavformat/swfdec.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Flash Compatible Streaming Format demuxer - * Copyright (c) 2000 Fabrice Bellard - * Copyright (c) 2003 Tinic Uro - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "swf.h" - -static int get_swf_tag(ByteIOContext *pb, int *len_ptr) -{ - int tag, len; - - if (url_feof(pb)) - return -1; - - tag = get_le16(pb); - len = tag & 0x3f; - tag = tag >> 6; - if (len == 0x3f) { - len = get_le32(pb); - } -// av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len); - *len_ptr = len; - return tag; -} - - -static int swf_probe(AVProbeData *p) -{ - /* check file header */ - if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' && - p->buf[2] == 'S') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = s->pb; - int nbits, len, tag; - - tag = get_be32(pb) & 0xffffff00; - - if (tag == MKBETAG('C', 'W', 'S', 0)) { - av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n"); - return AVERROR(EIO); - } - if (tag != MKBETAG('F', 'W', 'S', 0)) - return AVERROR(EIO); - get_le32(pb); - /* skip rectangle size */ - nbits = get_byte(pb) >> 3; - len = (4 * nbits - 3 + 7) / 8; - url_fskip(pb, len); - swf->frame_rate = get_le16(pb); /* 8.8 fixed */ - get_le16(pb); /* frame count */ - - swf->samples_per_frame = 0; - s->ctx_flags |= AVFMTCTX_NOHEADER; - return 0; -} - -static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *vst = NULL, *ast = NULL, *st = 0; - int tag, len, i, frame, v; - - for(;;) { - uint64_t pos = url_ftell(pb); - tag = get_swf_tag(pb, &len); - if (tag < 0) - return AVERROR(EIO); - if (tag == TAG_VIDEOSTREAM) { - int ch_id = get_le16(pb); - len -= 2; - - for (i=0; inb_streams; i++) { - st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) - goto skip; - } - - get_le16(pb); - get_le16(pb); - get_le16(pb); - get_byte(pb); - /* Check for FLV1 */ - vst = av_new_stream(s, ch_id); - if (!vst) - return -1; - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = ff_codec_get_id(swf_codec_tags, get_byte(pb)); - av_set_pts_info(vst, 16, 256, swf->frame_rate); - vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; - len -= 8; - } else if (tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) { - /* streaming found */ - int sample_rate_code; - - for (i=0; inb_streams; i++) { - st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) - goto skip; - } - - get_byte(pb); - v = get_byte(pb); - swf->samples_per_frame = get_le16(pb); - ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */ - if (!ast) - return -1; - ast->codec->channels = 1 + (v&1); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = ff_codec_get_id(swf_audio_codec_tags, (v>>4) & 15); - ast->need_parsing = AVSTREAM_PARSE_FULL; - sample_rate_code= (v>>2) & 3; - if (!sample_rate_code) - return AVERROR(EIO); - ast->codec->sample_rate = 11025 << (sample_rate_code-1); - av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - len -= 4; - } else if (tag == TAG_VIDEOFRAME) { - int ch_id = get_le16(pb); - len -= 2; - for(i=0; inb_streams; i++) { - st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) { - frame = get_le16(pb); - av_get_packet(pb, pkt, len-2); - pkt->pos = pos; - pkt->pts = frame; - pkt->stream_index = st->index; - return pkt->size; - } - } - } else if (tag == TAG_STREAMBLOCK) { - for (i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) { - if (st->codec->codec_id == CODEC_ID_MP3) { - url_fskip(pb, 4); - av_get_packet(pb, pkt, len-4); - } else { // ADPCM, PCM - av_get_packet(pb, pkt, len); - } - pkt->pos = pos; - pkt->stream_index = st->index; - return pkt->size; - } - } - } else if (tag == TAG_JPEG2) { - for (i=0; inb_streams; i++) { - st = s->streams[i]; - if (st->codec->codec_id == CODEC_ID_MJPEG && st->id == -2) - break; - } - if (i == s->nb_streams) { - vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */ - if (!vst) - return -1; - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_MJPEG; - av_set_pts_info(vst, 64, 256, swf->frame_rate); - vst->codec->time_base = (AVRational){ 256, swf->frame_rate }; - st = vst; - } - get_le16(pb); /* BITMAP_ID */ - av_new_packet(pkt, len-2); - get_buffer(pb, pkt->data, 4); - if (AV_RB32(pkt->data) == 0xffd8ffd9 || - AV_RB32(pkt->data) == 0xffd9ffd8) { - /* old SWF files containing SOI/EOI as data start */ - /* files created by swink have reversed tag */ - pkt->size -= 4; - get_buffer(pb, pkt->data, pkt->size); - } else { - get_buffer(pb, pkt->data + 4, pkt->size - 4); - } - pkt->pos = pos; - pkt->stream_index = st->index; - return pkt->size; - } - skip: - url_fskip(pb, len); - } - return 0; -} - -AVInputFormat swf_demuxer = { - "swf", - NULL_IF_CONFIG_SMALL("Flash format"), - sizeof(SWFContext), - swf_probe, - swf_read_header, - swf_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/swfenc.c b/tizen/distrib/ffmpeg/libavformat/swfenc.c deleted file mode 100644 index 1a1a9ab..0000000 --- a/tizen/distrib/ffmpeg/libavformat/swfenc.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Flash Compatible Streaming Format muxer - * Copyright (c) 2000 Fabrice Bellard - * Copyright (c) 2003 Tinic Uro - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/put_bits.h" -#include "avformat.h" -#include "swf.h" - -static void put_swf_tag(AVFormatContext *s, int tag) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = s->pb; - - swf->tag_pos = url_ftell(pb); - swf->tag = tag; - /* reserve some room for the tag */ - if (tag & TAG_LONG) { - put_le16(pb, 0); - put_le32(pb, 0); - } else { - put_le16(pb, 0); - } -} - -static void put_swf_end_tag(AVFormatContext *s) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t pos; - int tag_len, tag; - - pos = url_ftell(pb); - tag_len = pos - swf->tag_pos - 2; - tag = swf->tag; - url_fseek(pb, swf->tag_pos, SEEK_SET); - if (tag & TAG_LONG) { - tag &= ~TAG_LONG; - put_le16(pb, (tag << 6) | 0x3f); - put_le32(pb, tag_len - 4); - } else { - assert(tag_len < 0x3f); - put_le16(pb, (tag << 6) | tag_len); - } - url_fseek(pb, pos, SEEK_SET); -} - -static inline void max_nbits(int *nbits_ptr, int val) -{ - int n; - - if (val == 0) - return; - val = abs(val); - n = 1; - while (val != 0) { - n++; - val >>= 1; - } - if (n > *nbits_ptr) - *nbits_ptr = n; -} - -static void put_swf_rect(ByteIOContext *pb, - int xmin, int xmax, int ymin, int ymax) -{ - PutBitContext p; - uint8_t buf[256]; - int nbits, mask; - - init_put_bits(&p, buf, sizeof(buf)); - - nbits = 0; - max_nbits(&nbits, xmin); - max_nbits(&nbits, xmax); - max_nbits(&nbits, ymin); - max_nbits(&nbits, ymax); - mask = (1 << nbits) - 1; - - /* rectangle info */ - put_bits(&p, 5, nbits); - put_bits(&p, nbits, xmin & mask); - put_bits(&p, nbits, xmax & mask); - put_bits(&p, nbits, ymin & mask); - put_bits(&p, nbits, ymax & mask); - - flush_put_bits(&p); - put_buffer(pb, buf, put_bits_ptr(&p) - p.buf); -} - -static void put_swf_line_edge(PutBitContext *pb, int dx, int dy) -{ - int nbits, mask; - - put_bits(pb, 1, 1); /* edge */ - put_bits(pb, 1, 1); /* line select */ - nbits = 2; - max_nbits(&nbits, dx); - max_nbits(&nbits, dy); - - mask = (1 << nbits) - 1; - put_bits(pb, 4, nbits - 2); /* 16 bits precision */ - if (dx == 0) { - put_bits(pb, 1, 0); - put_bits(pb, 1, 1); - put_bits(pb, nbits, dy & mask); - } else if (dy == 0) { - put_bits(pb, 1, 0); - put_bits(pb, 1, 0); - put_bits(pb, nbits, dx & mask); - } else { - put_bits(pb, 1, 1); - put_bits(pb, nbits, dx & mask); - put_bits(pb, nbits, dy & mask); - } -} - -#define FRAC_BITS 16 - -static void put_swf_matrix(ByteIOContext *pb, - int a, int b, int c, int d, int tx, int ty) -{ - PutBitContext p; - uint8_t buf[256]; - int nbits; - - init_put_bits(&p, buf, sizeof(buf)); - - put_bits(&p, 1, 1); /* a, d present */ - nbits = 1; - max_nbits(&nbits, a); - max_nbits(&nbits, d); - put_bits(&p, 5, nbits); /* nb bits */ - put_bits(&p, nbits, a); - put_bits(&p, nbits, d); - - put_bits(&p, 1, 1); /* b, c present */ - nbits = 1; - max_nbits(&nbits, c); - max_nbits(&nbits, b); - put_bits(&p, 5, nbits); /* nb bits */ - put_bits(&p, nbits, c); - put_bits(&p, nbits, b); - - nbits = 1; - max_nbits(&nbits, tx); - max_nbits(&nbits, ty); - put_bits(&p, 5, nbits); /* nb bits */ - put_bits(&p, nbits, tx); - put_bits(&p, nbits, ty); - - flush_put_bits(&p); - put_buffer(pb, buf, put_bits_ptr(&p) - p.buf); -} - -static int swf_write_header(AVFormatContext *s) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = s->pb; - PutBitContext p; - uint8_t buf1[256]; - int i, width, height, rate, rate_base; - int version; - - swf->sound_samples = 0; - swf->swf_frame_number = 0; - swf->video_frame_number = 0; - - for(i=0;inb_streams;i++) { - AVCodecContext *enc = s->streams[i]->codec; - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - if (enc->codec_id == CODEC_ID_MP3) { - if (!enc->frame_size) { - av_log(s, AV_LOG_ERROR, "audio frame size not set\n"); - return -1; - } - swf->audio_enc = enc; - swf->audio_fifo= av_fifo_alloc(AUDIO_FIFO_SIZE); - if (!swf->audio_fifo) - return AVERROR(ENOMEM); - } else { - av_log(s, AV_LOG_ERROR, "SWF muxer only supports MP3\n"); - return -1; - } - } else { - if (enc->codec_id == CODEC_ID_VP6F || - enc->codec_id == CODEC_ID_FLV1 || - enc->codec_id == CODEC_ID_MJPEG) { - swf->video_enc = enc; - } else { - av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n"); - return -1; - } - } - } - - if (!swf->video_enc) { - /* currently, cannot work correctly if audio only */ - width = 320; - height = 200; - rate = 10; - rate_base= 1; - } else { - width = swf->video_enc->width; - height = swf->video_enc->height; - rate = swf->video_enc->time_base.den; - rate_base = swf->video_enc->time_base.num; - } - - if (!swf->audio_enc) - swf->samples_per_frame = (44100. * rate_base) / rate; - else - swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate; - - put_tag(pb, "FWS"); - - if (!strcmp("avm2", s->oformat->name)) - version = 9; - else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_VP6F) - version = 8; /* version 8 and above support VP6 codec */ - else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_FLV1) - version = 6; /* version 6 and above support FLV1 codec */ - else - version = 4; /* version 4 for mpeg audio support */ - put_byte(pb, version); - - put_le32(pb, DUMMY_FILE_SIZE); /* dummy size - (will be patched if not streamed) */ - - put_swf_rect(pb, 0, width * 20, 0, height * 20); - put_le16(pb, (rate * 256) / rate_base); /* frame rate */ - swf->duration_pos = url_ftell(pb); - put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */ - - /* avm2/swf v9 (also v8?) files require a file attribute tag */ - if (version == 9) { - put_swf_tag(s, TAG_FILEATTRIBUTES); - put_le32(pb, 1<<3); /* set ActionScript v3/AVM2 flag */ - put_swf_end_tag(s); - } - - /* define a shape with the jpeg inside */ - if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_MJPEG) { - put_swf_tag(s, TAG_DEFINESHAPE); - - put_le16(pb, SHAPE_ID); /* ID of shape */ - /* bounding rectangle */ - put_swf_rect(pb, 0, width, 0, height); - /* style info */ - put_byte(pb, 1); /* one fill style */ - put_byte(pb, 0x41); /* clipped bitmap fill */ - put_le16(pb, BITMAP_ID); /* bitmap ID */ - /* position of the bitmap */ - put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0, - 0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0); - put_byte(pb, 0); /* no line style */ - - /* shape drawing */ - init_put_bits(&p, buf1, sizeof(buf1)); - put_bits(&p, 4, 1); /* one fill bit */ - put_bits(&p, 4, 0); /* zero line bit */ - - put_bits(&p, 1, 0); /* not an edge */ - put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0); - put_bits(&p, 5, 1); /* nbits */ - put_bits(&p, 1, 0); /* X */ - put_bits(&p, 1, 0); /* Y */ - put_bits(&p, 1, 1); /* set fill style 1 */ - - /* draw the rectangle ! */ - put_swf_line_edge(&p, width, 0); - put_swf_line_edge(&p, 0, height); - put_swf_line_edge(&p, -width, 0); - put_swf_line_edge(&p, 0, -height); - - /* end of shape */ - put_bits(&p, 1, 0); /* not an edge */ - put_bits(&p, 5, 0); - - flush_put_bits(&p); - put_buffer(pb, buf1, put_bits_ptr(&p) - p.buf); - - put_swf_end_tag(s); - } - - if (swf->audio_enc && swf->audio_enc->codec_id == CODEC_ID_MP3) { - int v = 0; - - /* start sound */ - put_swf_tag(s, TAG_STREAMHEAD2); - switch(swf->audio_enc->sample_rate) { - case 11025: v |= 1 << 2; break; - case 22050: v |= 2 << 2; break; - case 44100: v |= 3 << 2; break; - default: - /* not supported */ - av_log(s, AV_LOG_ERROR, "swf does not support that sample rate, choose from (44100, 22050, 11025).\n"); - return -1; - } - v |= 0x02; /* 16 bit playback */ - if (swf->audio_enc->channels == 2) - v |= 0x01; /* stereo playback */ - put_byte(s->pb, v); - v |= 0x20; /* mp3 compressed */ - put_byte(s->pb, v); - put_le16(s->pb, swf->samples_per_frame); /* avg samples per frame */ - put_le16(s->pb, 0); - - put_swf_end_tag(s); - } - - put_flush_packet(s->pb); - return 0; -} - -static int swf_write_video(AVFormatContext *s, - AVCodecContext *enc, const uint8_t *buf, int size) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = s->pb; - - /* Flash Player limit */ - if (swf->swf_frame_number == 16000) - av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n"); - - if (enc->codec_id == CODEC_ID_VP6F || - enc->codec_id == CODEC_ID_FLV1) { - if (swf->video_frame_number == 0) { - /* create a new video object */ - put_swf_tag(s, TAG_VIDEOSTREAM); - put_le16(pb, VIDEO_ID); - swf->vframes_pos = url_ftell(pb); - put_le16(pb, 15000); /* hard flash player limit */ - put_le16(pb, enc->width); - put_le16(pb, enc->height); - put_byte(pb, 0); - put_byte(pb,ff_codec_get_tag(swf_codec_tags,enc->codec_id)); - put_swf_end_tag(s); - - /* place the video object for the first time */ - put_swf_tag(s, TAG_PLACEOBJECT2); - put_byte(pb, 0x36); - put_le16(pb, 1); - put_le16(pb, VIDEO_ID); - put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0); - put_le16(pb, swf->video_frame_number); - put_tag(pb, "video"); - put_byte(pb, 0x00); - put_swf_end_tag(s); - } else { - /* mark the character for update */ - put_swf_tag(s, TAG_PLACEOBJECT2); - put_byte(pb, 0x11); - put_le16(pb, 1); - put_le16(pb, swf->video_frame_number); - put_swf_end_tag(s); - } - - /* set video frame data */ - put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG); - put_le16(pb, VIDEO_ID); - put_le16(pb, swf->video_frame_number++); - put_buffer(pb, buf, size); - put_swf_end_tag(s); - } else if (enc->codec_id == CODEC_ID_MJPEG) { - if (swf->swf_frame_number > 0) { - /* remove the shape */ - put_swf_tag(s, TAG_REMOVEOBJECT); - put_le16(pb, SHAPE_ID); /* shape ID */ - put_le16(pb, 1); /* depth */ - put_swf_end_tag(s); - - /* free the bitmap */ - put_swf_tag(s, TAG_FREECHARACTER); - put_le16(pb, BITMAP_ID); - put_swf_end_tag(s); - } - - put_swf_tag(s, TAG_JPEG2 | TAG_LONG); - - put_le16(pb, BITMAP_ID); /* ID of the image */ - - /* a dummy jpeg header seems to be required */ - put_be32(pb, 0xffd8ffd9); - /* write the jpeg image */ - put_buffer(pb, buf, size); - - put_swf_end_tag(s); - - /* draw the shape */ - - put_swf_tag(s, TAG_PLACEOBJECT); - put_le16(pb, SHAPE_ID); /* shape ID */ - put_le16(pb, 1); /* depth */ - put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0); - put_swf_end_tag(s); - } - - swf->swf_frame_number++; - - /* streaming sound always should be placed just before showframe tags */ - if (swf->audio_enc && av_fifo_size(swf->audio_fifo)) { - int frame_size = av_fifo_size(swf->audio_fifo); - put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG); - put_le16(pb, swf->sound_samples); - put_le16(pb, 0); // seek samples - av_fifo_generic_read(swf->audio_fifo, pb, frame_size, &put_buffer); - put_swf_end_tag(s); - - /* update FIFO */ - swf->sound_samples = 0; - } - - /* output the frame */ - put_swf_tag(s, TAG_SHOWFRAME); - put_swf_end_tag(s); - - put_flush_packet(s->pb); - - return 0; -} - -static int swf_write_audio(AVFormatContext *s, - AVCodecContext *enc, uint8_t *buf, int size) -{ - SWFContext *swf = s->priv_data; - - /* Flash Player limit */ - if (swf->swf_frame_number == 16000) - av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n"); - - if (av_fifo_size(swf->audio_fifo) + size > AUDIO_FIFO_SIZE) { - av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n"); - return -1; - } - - av_fifo_generic_write(swf->audio_fifo, buf, size, NULL); - swf->sound_samples += enc->frame_size; - - /* if audio only stream make sure we add swf frames */ - if (!swf->video_enc) - swf_write_video(s, enc, 0, 0); - - return 0; -} - -static int swf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) - return swf_write_audio(s, codec, pkt->data, pkt->size); - else - return swf_write_video(s, codec, pkt->data, pkt->size); -} - -static int swf_write_trailer(AVFormatContext *s) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = s->pb; - AVCodecContext *enc, *video_enc; - int file_size, i; - - video_enc = NULL; - for(i=0;inb_streams;i++) { - enc = s->streams[i]->codec; - if (enc->codec_type == AVMEDIA_TYPE_VIDEO) - video_enc = enc; - else - av_fifo_free(swf->audio_fifo); - } - - put_swf_tag(s, TAG_END); - put_swf_end_tag(s); - - put_flush_packet(s->pb); - - /* patch file size and number of frames if not streamed */ - if (!url_is_streamed(s->pb) && video_enc) { - file_size = url_ftell(pb); - url_fseek(pb, 4, SEEK_SET); - put_le32(pb, file_size); - url_fseek(pb, swf->duration_pos, SEEK_SET); - put_le16(pb, swf->video_frame_number); - url_fseek(pb, swf->vframes_pos, SEEK_SET); - put_le16(pb, swf->video_frame_number); - url_fseek(pb, file_size, SEEK_SET); - } - return 0; -} - -#if CONFIG_SWF_MUXER -AVOutputFormat swf_muxer = { - "swf", - NULL_IF_CONFIG_SMALL("Flash format"), - "application/x-shockwave-flash", - "swf", - sizeof(SWFContext), - CODEC_ID_MP3, - CODEC_ID_FLV1, - swf_write_header, - swf_write_packet, - swf_write_trailer, -}; -#endif -#if CONFIG_AVM2_MUXER -AVOutputFormat avm2_muxer = { - "avm2", - NULL_IF_CONFIG_SMALL("Flash 9 (AVM2) format"), - "application/x-shockwave-flash", - NULL, - sizeof(SWFContext), - CODEC_ID_MP3, - CODEC_ID_FLV1, - swf_write_header, - swf_write_packet, - swf_write_trailer, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/tcp.c b/tizen/distrib/ffmpeg/libavformat/tcp.c deleted file mode 100644 index 79cabdf..0000000 --- a/tizen/distrib/ffmpeg/libavformat/tcp.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * TCP protocol - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include -#include "internal.h" -#include "network.h" -#include "os_support.h" -#if HAVE_SYS_SELECT_H -#include -#endif -#include - -typedef struct TCPContext { - int fd; -} TCPContext; - -/* return non zero if error */ -static int tcp_open(URLContext *h, const char *uri, int flags) -{ - struct addrinfo hints, *ai, *cur_ai; - int port, fd = -1; - TCPContext *s = NULL; - fd_set wfds; - int fd_max, ret; - struct timeval tv; - socklen_t optlen; - char hostname[1024],proto[1024],path[1024]; - char portstr[10]; - - ff_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), - &port, path, sizeof(path), uri); - if (strcmp(proto,"tcp") || port <= 0 || port >= 65536) - return AVERROR(EINVAL); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - snprintf(portstr, sizeof(portstr), "%d", port); - if (getaddrinfo(hostname, portstr, &hints, &ai)) - return AVERROR(EIO); - - cur_ai = ai; - - restart: - fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol); - if (fd < 0) - goto fail; - ff_socket_nonblock(fd, 1); - - redo: - ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); - if (ret < 0) { - if (ff_neterrno() == FF_NETERROR(EINTR)) - goto redo; - if (ff_neterrno() != FF_NETERROR(EINPROGRESS) && - ff_neterrno() != FF_NETERROR(EAGAIN)) - goto fail; - - /* wait until we are connected or until abort */ - for(;;) { - if (url_interrupt_cb()) { - ret = AVERROR(EINTR); - goto fail1; - } - fd_max = fd; - FD_ZERO(&wfds); - FD_SET(fd, &wfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(fd_max + 1, NULL, &wfds, NULL, &tv); - if (ret > 0 && FD_ISSET(fd, &wfds)) - break; - } - - /* test error */ - optlen = sizeof(ret); - getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen); - if (ret != 0) - goto fail; - } - s = av_malloc(sizeof(TCPContext)); - if (!s) { - freeaddrinfo(ai); - return AVERROR(ENOMEM); - } - h->priv_data = s; - h->is_streamed = 1; - s->fd = fd; - freeaddrinfo(ai); - return 0; - - fail: - if (cur_ai->ai_next) { - /* Retry with the next sockaddr */ - cur_ai = cur_ai->ai_next; - if (fd >= 0) - closesocket(fd); - goto restart; - } - ret = AVERROR(EIO); - fail1: - if (fd >= 0) - closesocket(fd); - freeaddrinfo(ai); - return ret; -} - -static int tcp_read(URLContext *h, uint8_t *buf, int size) -{ - TCPContext *s = h->priv_data; - int len, fd_max, ret; - fd_set rfds; - struct timeval tv; - - for (;;) { - if (url_interrupt_cb()) - return AVERROR(EINTR); - fd_max = s->fd; - FD_ZERO(&rfds); - FD_SET(s->fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(fd_max + 1, &rfds, NULL, NULL, &tv); - if (ret > 0 && FD_ISSET(s->fd, &rfds)) { - len = recv(s->fd, buf, size, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EINTR) && - ff_neterrno() != FF_NETERROR(EAGAIN)) - return AVERROR(ff_neterrno()); - } else return len; - } else if (ret < 0) { - if (ff_neterrno() == FF_NETERROR(EINTR)) - continue; - return -1; - } - } -} - -static int tcp_write(URLContext *h, uint8_t *buf, int size) -{ - TCPContext *s = h->priv_data; - int ret, size1, fd_max, len; - fd_set wfds; - struct timeval tv; - - size1 = size; - while (size > 0) { - if (url_interrupt_cb()) - return AVERROR(EINTR); - fd_max = s->fd; - FD_ZERO(&wfds); - FD_SET(s->fd, &wfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(fd_max + 1, NULL, &wfds, NULL, &tv); - if (ret > 0 && FD_ISSET(s->fd, &wfds)) { - len = send(s->fd, buf, size, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EINTR) && - ff_neterrno() != FF_NETERROR(EAGAIN)) - return AVERROR(ff_neterrno()); - continue; - } - size -= len; - buf += len; - } else if (ret < 0) { - if (ff_neterrno() == FF_NETERROR(EINTR)) - continue; - return -1; - } - } - return size1 - size; -} - -static int tcp_close(URLContext *h) -{ - TCPContext *s = h->priv_data; - closesocket(s->fd); - av_free(s); - return 0; -} - -static int tcp_get_file_handle(URLContext *h) -{ - TCPContext *s = h->priv_data; - return s->fd; -} - -URLProtocol tcp_protocol = { - "tcp", - tcp_open, - tcp_read, - tcp_write, - NULL, /* seek */ - tcp_close, - .url_get_file_handle = tcp_get_file_handle, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/thp.c b/tizen/distrib/ffmpeg/libavformat/thp.c deleted file mode 100644 index 82966dd..0000000 --- a/tizen/distrib/ffmpeg/libavformat/thp.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * THP Demuxer - * Copyright (c) 2007 Marco Gerards - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -typedef struct ThpDemuxContext { - int version; - int first_frame; - int first_framesz; - int last_frame; - int compoff; - int framecnt; - AVRational fps; - int frame; - int next_frame; - int next_framesz; - int video_stream_index; - int audio_stream_index; - int compcount; - unsigned char components[16]; - AVStream* vst; - int has_audio; - int audiosize; -} ThpDemuxContext; - - -static int thp_probe(AVProbeData *p) -{ - /* check file header */ - if (AV_RL32(p->buf) == MKTAG('T', 'H', 'P', '\0')) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int thp_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ThpDemuxContext *thp = s->priv_data; - AVStream *st; - ByteIOContext *pb = s->pb; - int i; - - /* Read the file header. */ - get_be32(pb); /* Skip Magic. */ - thp->version = get_be32(pb); - - get_be32(pb); /* Max buf size. */ - get_be32(pb); /* Max samples. */ - - thp->fps = av_d2q(av_int2flt(get_be32(pb)), INT_MAX); - thp->framecnt = get_be32(pb); - thp->first_framesz = get_be32(pb); - get_be32(pb); /* Data size. */ - - thp->compoff = get_be32(pb); - get_be32(pb); /* offsetDataOffset. */ - thp->first_frame = get_be32(pb); - thp->last_frame = get_be32(pb); - - thp->next_framesz = thp->first_framesz; - thp->next_frame = thp->first_frame; - - /* Read the component structure. */ - url_fseek (pb, thp->compoff, SEEK_SET); - thp->compcount = get_be32(pb); - - /* Read the list of component types. */ - get_buffer(pb, thp->components, 16); - - for (i = 0; i < thp->compcount; i++) { - if (thp->components[i] == 0) { - if (thp->vst != 0) - break; - - /* Video component. */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - /* The denominator and numerator are switched because 1/fps - is required. */ - av_set_pts_info(st, 64, thp->fps.den, thp->fps.num); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_THP; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = get_be32(pb); - st->codec->height = get_be32(pb); - st->codec->sample_rate = av_q2d(thp->fps); - thp->vst = st; - thp->video_stream_index = st->index; - - if (thp->version == 0x11000) - get_be32(pb); /* Unknown. */ - } else if (thp->components[i] == 1) { - if (thp->has_audio != 0) - break; - - /* Audio component. */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ADPCM_THP; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->channels = get_be32(pb); /* numChannels. */ - st->codec->sample_rate = get_be32(pb); /* Frequency. */ - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - thp->audio_stream_index = st->index; - thp->has_audio = 1; - } - } - - return 0; -} - -static int thp_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - ThpDemuxContext *thp = s->priv_data; - ByteIOContext *pb = s->pb; - int size; - int ret; - - if (thp->audiosize == 0) { - /* Terminate when last frame is reached. */ - if (thp->frame >= thp->framecnt) - return AVERROR(EIO); - - url_fseek(pb, thp->next_frame, SEEK_SET); - - /* Locate the next frame and read out its size. */ - thp->next_frame += thp->next_framesz; - thp->next_framesz = get_be32(pb); - - get_be32(pb); /* Previous total size. */ - size = get_be32(pb); /* Total size of this frame. */ - - /* Store the audiosize so the next time this function is called, - the audio can be read. */ - if (thp->has_audio) - thp->audiosize = get_be32(pb); /* Audio size. */ - else - thp->frame++; - - ret = av_get_packet(pb, pkt, size); - if (ret != size) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - pkt->stream_index = thp->video_stream_index; - } else { - ret = av_get_packet(pb, pkt, thp->audiosize); - if (ret != thp->audiosize) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - pkt->stream_index = thp->audio_stream_index; - thp->audiosize = 0; - thp->frame++; - } - - return 0; -} - -AVInputFormat thp_demuxer = { - "thp", - NULL_IF_CONFIG_SMALL("THP"), - sizeof(ThpDemuxContext), - thp_probe, - thp_read_header, - thp_read_packet -}; diff --git a/tizen/distrib/ffmpeg/libavformat/tiertexseq.c b/tizen/distrib/ffmpeg/libavformat/tiertexseq.c deleted file mode 100644 index 938eea5..0000000 --- a/tizen/distrib/ffmpeg/libavformat/tiertexseq.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Tiertex Limited SEQ File Demuxer - * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Tiertex Limited SEQ file demuxer - */ - -#include "avformat.h" - -#define SEQ_FRAME_SIZE 6144 -#define SEQ_FRAME_W 256 -#define SEQ_FRAME_H 128 -#define SEQ_NUM_FRAME_BUFFERS 30 -#define SEQ_AUDIO_BUFFER_SIZE 882 -#define SEQ_SAMPLE_RATE 22050 -#define SEQ_FRAME_RATE 25 - - -typedef struct TiertexSeqFrameBuffer { - int fill_size; - int data_size; - unsigned char *data; -} TiertexSeqFrameBuffer; - -typedef struct SeqDemuxContext { - int audio_stream_index; - int video_stream_index; - int current_frame_pts; - int current_frame_offs; - TiertexSeqFrameBuffer frame_buffers[SEQ_NUM_FRAME_BUFFERS]; - int frame_buffers_count; - unsigned int current_audio_data_size; - unsigned int current_audio_data_offs; - unsigned int current_pal_data_size; - unsigned int current_pal_data_offs; - unsigned int current_video_data_size; - unsigned char *current_video_data_ptr; - int audio_buffer_full; -} SeqDemuxContext; - - -static int seq_probe(AVProbeData *p) -{ - int i; - - if (p->buf_size < 258) - return 0; - - /* there's no real header in a .seq file, the only thing they have in common */ - /* is the first 256 bytes of the file which are always filled with 0 */ - for (i = 0; i < 256; i++) - if (p->buf[i]) - return 0; - - if(p->buf[256]==0 && p->buf[257]==0) - return 0; - - /* only one fourth of the score since the previous check is too naive */ - return AVPROBE_SCORE_MAX / 4; -} - -static int seq_init_frame_buffers(SeqDemuxContext *seq, ByteIOContext *pb) -{ - int i, sz; - TiertexSeqFrameBuffer *seq_buffer; - - url_fseek(pb, 256, SEEK_SET); - - for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++) { - sz = get_le16(pb); - if (sz == 0) - break; - else { - seq_buffer = &seq->frame_buffers[i]; - seq_buffer->fill_size = 0; - seq_buffer->data_size = sz; - seq_buffer->data = av_malloc(sz); - if (!seq_buffer->data) - return AVERROR(ENOMEM); - } - } - seq->frame_buffers_count = i; - return 0; -} - -static int seq_fill_buffer(SeqDemuxContext *seq, ByteIOContext *pb, int buffer_num, unsigned int data_offs, int data_size) -{ - TiertexSeqFrameBuffer *seq_buffer; - - if (buffer_num >= SEQ_NUM_FRAME_BUFFERS) - return AVERROR_INVALIDDATA; - - seq_buffer = &seq->frame_buffers[buffer_num]; - if (seq_buffer->fill_size + data_size > seq_buffer->data_size || data_size <= 0) - return AVERROR_INVALIDDATA; - - url_fseek(pb, seq->current_frame_offs + data_offs, SEEK_SET); - if (get_buffer(pb, seq_buffer->data + seq_buffer->fill_size, data_size) != data_size) - return AVERROR(EIO); - - seq_buffer->fill_size += data_size; - return 0; -} - -static int seq_parse_frame_data(SeqDemuxContext *seq, ByteIOContext *pb) -{ - unsigned int offset_table[4], buffer_num[4]; - TiertexSeqFrameBuffer *seq_buffer; - int i, e, err; - - seq->current_frame_offs += SEQ_FRAME_SIZE; - url_fseek(pb, seq->current_frame_offs, SEEK_SET); - - /* sound data */ - seq->current_audio_data_offs = get_le16(pb); - if (seq->current_audio_data_offs) { - seq->current_audio_data_size = SEQ_AUDIO_BUFFER_SIZE * 2; - } else { - seq->current_audio_data_size = 0; - } - - /* palette data */ - seq->current_pal_data_offs = get_le16(pb); - if (seq->current_pal_data_offs) { - seq->current_pal_data_size = 768; - } else { - seq->current_pal_data_size = 0; - } - - /* video data */ - for (i = 0; i < 4; i++) - buffer_num[i] = get_byte(pb); - - for (i = 0; i < 4; i++) - offset_table[i] = get_le16(pb); - - for (i = 0; i < 3; i++) { - if (offset_table[i]) { - for (e = i + 1; e < 3 && offset_table[e] == 0; e++); - err = seq_fill_buffer(seq, pb, buffer_num[1 + i], - offset_table[i], - offset_table[e] - offset_table[i]); - if (err) - return err; - } - } - - if (buffer_num[0] != 255) { - if (buffer_num[0] >= SEQ_NUM_FRAME_BUFFERS) - return AVERROR_INVALIDDATA; - - seq_buffer = &seq->frame_buffers[buffer_num[0]]; - seq->current_video_data_size = seq_buffer->fill_size; - seq->current_video_data_ptr = seq_buffer->data; - seq_buffer->fill_size = 0; - } else { - seq->current_video_data_size = 0; - seq->current_video_data_ptr = 0; - } - - return 0; -} - -static int seq_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - int i, rc; - SeqDemuxContext *seq = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - - /* init internal buffers */ - rc = seq_init_frame_buffers(seq, pb); - if (rc) - return rc; - - seq->current_frame_offs = 0; - - /* preload (no audio data, just buffer operations related data) */ - for (i = 1; i <= 100; i++) { - rc = seq_parse_frame_data(seq, pb); - if (rc) - return rc; - } - - seq->current_frame_pts = 0; - - seq->audio_buffer_full = 0; - - /* initialize the video decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 32, 1, SEQ_FRAME_RATE); - seq->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_TIERTEXSEQVIDEO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = SEQ_FRAME_W; - st->codec->height = SEQ_FRAME_H; - - /* initialize the audio decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 32, 1, SEQ_SAMPLE_RATE); - seq->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_S16BE; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = 1; - st->codec->sample_rate = SEQ_SAMPLE_RATE; - st->codec->bits_per_coded_sample = 16; - st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - - return 0; -} - -static int seq_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int rc; - SeqDemuxContext *seq = s->priv_data; - ByteIOContext *pb = s->pb; - - if (!seq->audio_buffer_full) { - rc = seq_parse_frame_data(seq, pb); - if (rc) - return rc; - - /* video packet */ - if (seq->current_pal_data_size + seq->current_video_data_size != 0) { - if (av_new_packet(pkt, 1 + seq->current_pal_data_size + seq->current_video_data_size)) - return AVERROR(ENOMEM); - - pkt->data[0] = 0; - if (seq->current_pal_data_size) { - pkt->data[0] |= 1; - url_fseek(pb, seq->current_frame_offs + seq->current_pal_data_offs, SEEK_SET); - if (get_buffer(pb, &pkt->data[1], seq->current_pal_data_size) != seq->current_pal_data_size) - return AVERROR(EIO); - } - if (seq->current_video_data_size) { - pkt->data[0] |= 2; - memcpy(&pkt->data[1 + seq->current_pal_data_size], - seq->current_video_data_ptr, - seq->current_video_data_size); - } - pkt->stream_index = seq->video_stream_index; - pkt->pts = seq->current_frame_pts; - - /* sound buffer will be processed on next read_packet() call */ - seq->audio_buffer_full = 1; - return 0; - } - } - - /* audio packet */ - if (seq->current_audio_data_offs == 0) /* end of data reached */ - return AVERROR(EIO); - - url_fseek(pb, seq->current_frame_offs + seq->current_audio_data_offs, SEEK_SET); - rc = av_get_packet(pb, pkt, seq->current_audio_data_size); - if (rc < 0) - return rc; - - pkt->stream_index = seq->audio_stream_index; - seq->current_frame_pts++; - - seq->audio_buffer_full = 0; - return 0; -} - -static int seq_read_close(AVFormatContext *s) -{ - int i; - SeqDemuxContext *seq = s->priv_data; - - for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++) - av_free(seq->frame_buffers[i].data); - - return 0; -} - -AVInputFormat tiertexseq_demuxer = { - "tiertexseq", - NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"), - sizeof(SeqDemuxContext), - seq_probe, - seq_read_header, - seq_read_packet, - seq_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/timefilter.c b/tizen/distrib/ffmpeg/libavformat/timefilter.c deleted file mode 100644 index 4a58224..0000000 --- a/tizen/distrib/ffmpeg/libavformat/timefilter.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Delay Locked Loop based time filter - * Copyright (c) 2009 Samalyse - * Copyright (c) 2009 Michael Niedermayer - * Author: Olivier Guilyardi - * Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "config.h" -#include "avformat.h" -#include "timefilter.h" - -struct TimeFilter { - /// Delay Locked Loop data. These variables refer to mathematical - /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf - double cycle_time; - double feedback2_factor; - double feedback3_factor; - double clock_period; - int count; -}; - -TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor) -{ - TimeFilter *self = av_mallocz(sizeof(TimeFilter)); - self->clock_period = clock_period; - self->feedback2_factor = feedback2_factor; - self->feedback3_factor = feedback3_factor; - return self; -} - -void ff_timefilter_destroy(TimeFilter *self) -{ - av_freep(&self); -} - -void ff_timefilter_reset(TimeFilter *self) -{ - self->count = 0; -} - -double ff_timefilter_update(TimeFilter *self, double system_time, double period) -{ - self->count++; - if (self->count==1) { - /// init loop - self->cycle_time = system_time; - } else { - double loop_error; - self->cycle_time += self->clock_period * period; - /// calculate loop error - loop_error = system_time - self->cycle_time; - - /// update loop - self->cycle_time += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error; - self->clock_period += self->feedback3_factor * loop_error / period; - } - return self->cycle_time; -} - -#ifdef TEST -#include "libavutil/lfg.h" -#define LFG_MAX ((1LL << 32) - 1) - -int main(void) -{ - AVLFG prng; - double n0,n1; -#define SAMPLES 1000 - double ideal[SAMPLES]; - double samples[SAMPLES]; -#if 1 - for(n0= 0; n0<40; n0=2*n0+1){ - for(n1= 0; n1<10; n1=2*n1+1){ -#else - {{ - n0=7; - n1=1; -#endif - double best_error= 1000000000; - double bestpar0=1; - double bestpar1=0.001; - int better, i; - - av_lfg_init(&prng, 123); - for(i=0; i - * Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_TIMEFILTER_H -#define AVFORMAT_TIMEFILTER_H - -/** - * Opaque type representing a time filter state - * - * The purpose of this filter is to provide a way to compute accurate time - * stamps that can be compared to wall clock time, especially when dealing - * with two clocks: the system clock and a hardware device clock, such as - * a soundcard. - */ -typedef struct TimeFilter TimeFilter; - - -/** - * Create a new Delay Locked Loop time filter - * - * feedback2_factor and feedback3_factor are the factors used for the - * multiplications that are respectively performed in the second and third - * feedback paths of the loop. - * - * Unless you know what you are doing, you should set these as follow: - * - * o = 2 * M_PI * bandwidth * period - * feedback2_factor = sqrt(2 * o) - * feedback3_factor = o * o - * - * Where bandwidth is up to you to choose. Smaller values will filter out more - * of the jitter, but also take a longer time for the loop to settle. A good - * starting point is something between 0.3 and 3 Hz. - * - * @param clock_period period of the hardware clock in seconds - * (for example 1.0/44100) - * - * For more details about these parameters and background concepts please see: - * http://www.kokkinizita.net/papers/usingdll.pdf - */ -TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor); - -/** - * Update the filter - * - * This function must be called in real time, at each process cycle. - * - * @param period the device cycle duration in clock_periods. For example, at - * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period - * was 1.0/44100, or 512/44100 if clock_period was 1. - * - * system_time, in seconds, should be the value of the system clock time, - * at (or as close as possible to) the moment the device hardware interrupt - * occured (or any other event the device clock raises at the beginning of a - * cycle). - * - * @return the filtered time, in seconds - */ -double ff_timefilter_update(TimeFilter *self, double system_time, double period); - -/** - * Reset the filter - * - * This function should mainly be called in case of XRUN. - * - * Warning: after calling this, the filter is in an undetermined state until - * the next call to ff_timefilter_update() - */ -void ff_timefilter_reset(TimeFilter *); - -/** - * Free all resources associated with the filter - */ -void ff_timefilter_destroy(TimeFilter *); - -#endif /* AVFORMAT_TIMEFILTER_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/tmv.c b/tizen/distrib/ffmpeg/libavformat/tmv.c deleted file mode 100644 index 4be2f32..0000000 --- a/tizen/distrib/ffmpeg/libavformat/tmv.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 8088flex TMV file demuxer - * Copyright (c) 2009 Daniel Verkamp - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * 8088flex TMV file demuxer - * @file - * @author Daniel Verkamp - * @sa http://www.oldskool.org/pc/8088_Corruption - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -enum { - TMV_PADDING = 0x01, - TMV_STEREO = 0x02, -}; - -#define TMV_TAG MKTAG('T', 'M', 'A', 'V') - -typedef struct TMVContext { - unsigned audio_chunk_size; - unsigned video_chunk_size; - unsigned padding; - unsigned stream_index; -} TMVContext; - -#define TMV_HEADER_SIZE 12 - -#define PROBE_MIN_SAMPLE_RATE 5000 -#define PROBE_MAX_FPS 120 -#define PROBE_MIN_AUDIO_SIZE (PROBE_MIN_SAMPLE_RATE / PROBE_MAX_FPS) - -static int tmv_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == TMV_TAG && - AV_RL16(p->buf+4) >= PROBE_MIN_SAMPLE_RATE && - AV_RL16(p->buf+6) >= PROBE_MIN_AUDIO_SIZE && - !p->buf[8] && // compression method - p->buf[9] && // char cols - p->buf[10]) // char rows - return AVPROBE_SCORE_MAX / - ((p->buf[9] == 40 && p->buf[10] == 25) ? 1 : 4); - return 0; -} - -static int tmv_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - TMVContext *tmv = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *vst, *ast; - AVRational fps; - unsigned comp_method, char_cols, char_rows, features; - - if (get_le32(pb) != TMV_TAG) - return -1; - - if (!(vst = av_new_stream(s, 0))) - return AVERROR(ENOMEM); - - if (!(ast = av_new_stream(s, 0))) - return AVERROR(ENOMEM); - - ast->codec->sample_rate = get_le16(pb); - if (!ast->codec->sample_rate) { - av_log(s, AV_LOG_ERROR, "invalid sample rate\n"); - return -1; - } - - tmv->audio_chunk_size = get_le16(pb); - if (!tmv->audio_chunk_size) { - av_log(s, AV_LOG_ERROR, "invalid audio chunk size\n"); - return -1; - } - - comp_method = get_byte(pb); - if (comp_method) { - av_log(s, AV_LOG_ERROR, "unsupported compression method %d\n", - comp_method); - return -1; - } - - char_cols = get_byte(pb); - char_rows = get_byte(pb); - tmv->video_chunk_size = char_cols * char_rows * 2; - - features = get_byte(pb); - if (features & ~(TMV_PADDING | TMV_STEREO)) { - av_log(s, AV_LOG_ERROR, "unsupported features 0x%02x\n", - features & ~(TMV_PADDING | TMV_STEREO)); - return -1; - } - - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = CODEC_ID_PCM_U8; - ast->codec->channels = features & TMV_STEREO ? 2 : 1; - ast->codec->bits_per_coded_sample = 8; - ast->codec->bit_rate = ast->codec->sample_rate * - ast->codec->bits_per_coded_sample; - av_set_pts_info(ast, 32, 1, ast->codec->sample_rate); - - fps.num = ast->codec->sample_rate * ast->codec->channels; - fps.den = tmv->audio_chunk_size; - av_reduce(&fps.num, &fps.den, fps.num, fps.den, 0xFFFFFFFFLL); - - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = CODEC_ID_TMV; - vst->codec->pix_fmt = PIX_FMT_PAL8; - vst->codec->width = char_cols * 8; - vst->codec->height = char_rows * 8; - av_set_pts_info(vst, 32, fps.den, fps.num); - - if (features & TMV_PADDING) - tmv->padding = - ((tmv->video_chunk_size + tmv->audio_chunk_size + 511) & ~511) - - (tmv->video_chunk_size + tmv->audio_chunk_size); - - vst->codec->bit_rate = ((tmv->video_chunk_size + tmv->padding) * - fps.num * 8) / fps.den; - - return 0; -} - -static int tmv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - TMVContext *tmv = s->priv_data; - ByteIOContext *pb = s->pb; - int ret, pkt_size = tmv->stream_index ? - tmv->audio_chunk_size : tmv->video_chunk_size; - - if (url_feof(pb)) - return AVERROR_EOF; - - ret = av_get_packet(pb, pkt, pkt_size); - - if (tmv->stream_index) - url_fskip(pb, tmv->padding); - - pkt->stream_index = tmv->stream_index; - tmv->stream_index ^= 1; - pkt->flags |= AV_PKT_FLAG_KEY; - - return ret; -} - -static int tmv_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - TMVContext *tmv = s->priv_data; - int64_t pos; - - if (stream_index) - return -1; - - pos = timestamp * - (tmv->audio_chunk_size + tmv->video_chunk_size + tmv->padding); - - url_fseek(s->pb, pos + TMV_HEADER_SIZE, SEEK_SET); - tmv->stream_index = 0; - return 0; -} - -AVInputFormat tmv_demuxer = { - "tmv", - NULL_IF_CONFIG_SMALL("8088flex TMV"), - sizeof(TMVContext), - tmv_probe, - tmv_read_header, - tmv_read_packet, - NULL, - tmv_read_seek, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/tta.c b/tizen/distrib/ffmpeg/libavformat/tta.c deleted file mode 100644 index 66d3bad..0000000 --- a/tizen/distrib/ffmpeg/libavformat/tta.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * TTA demuxer - * Copyright (c) 2006 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "id3v2.h" -#include "id3v1.h" - -typedef struct { - int totalframes, currentframe; -} TTAContext; - -static int tta_probe(AVProbeData *p) -{ - const uint8_t *d = p->buf; - - if (ff_id3v2_match(d)) - d += ff_id3v2_tag_len(d); - - if (d - p->buf >= p->buf_size) - return 0; - - if (d[0] == 'T' && d[1] == 'T' && d[2] == 'A' && d[3] == '1') - return 80; - return 0; -} - -static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - TTAContext *c = s->priv_data; - AVStream *st; - int i, channels, bps, samplerate, datalen, framelen; - uint64_t framepos, start_offset; - - ff_id3v2_read(s); - if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) - ff_id3v1_read(s); - - start_offset = url_ftell(s->pb); - if (get_le32(s->pb) != AV_RL32("TTA1")) - return -1; // not tta file - - url_fskip(s->pb, 2); // FIXME: flags - channels = get_le16(s->pb); - bps = get_le16(s->pb); - samplerate = get_le32(s->pb); - if(samplerate <= 0 || samplerate > 1000000){ - av_log(s, AV_LOG_ERROR, "nonsense samplerate\n"); - return -1; - } - - datalen = get_le32(s->pb); - if(datalen < 0){ - av_log(s, AV_LOG_ERROR, "nonsense datalen\n"); - return -1; - } - - url_fskip(s->pb, 4); // header crc - - framelen = samplerate*256/245; - c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0); - c->currentframe = 0; - - if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){ - av_log(s, AV_LOG_ERROR, "totalframes too large\n"); - return -1; - } - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - av_set_pts_info(st, 64, 1, samplerate); - st->start_time = 0; - st->duration = datalen; - - framepos = url_ftell(s->pb) + 4*c->totalframes + 4; - - for (i = 0; i < c->totalframes; i++) { - uint32_t size = get_le32(s->pb); - av_add_index_entry(st, framepos, i*framelen, size, 0, AVINDEX_KEYFRAME); - framepos += size; - } - url_fskip(s->pb, 4); // seektable crc - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_TTA; - st->codec->channels = channels; - st->codec->sample_rate = samplerate; - st->codec->bits_per_coded_sample = bps; - - st->codec->extradata_size = url_ftell(s->pb) - start_offset; - if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){ - //this check is redundant as get_buffer should fail - av_log(s, AV_LOG_ERROR, "extradata_size too large\n"); - return -1; - } - st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); - url_fseek(s->pb, start_offset, SEEK_SET); - get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size); - - return 0; -} - -static int tta_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - TTAContext *c = s->priv_data; - AVStream *st = s->streams[0]; - int size, ret; - - // FIXME! - if (c->currentframe > c->totalframes) - return -1; - - size = st->index_entries[c->currentframe].size; - - ret = av_get_packet(s->pb, pkt, size); - pkt->dts = st->index_entries[c->currentframe++].timestamp; - return ret; -} - -static int tta_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - TTAContext *c = s->priv_data; - AVStream *st = s->streams[stream_index]; - int index = av_index_search_timestamp(st, timestamp, flags); - if (index < 0) - return -1; - - c->currentframe = index; - url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET); - - return 0; -} - -AVInputFormat tta_demuxer = { - "tta", - NULL_IF_CONFIG_SMALL("True Audio"), - sizeof(TTAContext), - tta_probe, - tta_read_header, - tta_read_packet, - NULL, - tta_read_seek, - .extensions = "tta", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/txd.c b/tizen/distrib/ffmpeg/libavformat/txd.c deleted file mode 100644 index 38bdb1b..0000000 --- a/tizen/distrib/ffmpeg/libavformat/txd.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Renderware TeXture Dictionary (.txd) demuxer - * Copyright (c) 2007 Ivo van Poorten - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define TXD_FILE 0x16 -#define TXD_INFO 0x01 -#define TXD_EXTRA 0x03 -#define TXD_TEXTURE 0x15 -#define TXD_TEXTURE_DATA 0x01 -#define TXD_MARKER 0x1803ffff -#define TXD_MARKER2 0x1003ffff - -static int txd_probe(AVProbeData * pd) { - if (AV_RL32(pd->buf ) == TXD_FILE && - (AV_RL32(pd->buf+8) == TXD_MARKER || AV_RL32(pd->buf+8) == TXD_MARKER2)) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int txd_read_header(AVFormatContext *s, AVFormatParameters *ap) { - AVStream *st; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_TXD; - st->codec->time_base.den = 5; - st->codec->time_base.num = 1; - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -static int txd_read_packet(AVFormatContext *s, AVPacket *pkt) { - ByteIOContext *pb = s->pb; - unsigned int id, chunk_size, marker; - int ret; - -next_chunk: - id = get_le32(pb); - chunk_size = get_le32(pb); - marker = get_le32(pb); - - if (url_feof(s->pb)) - return AVERROR_EOF; - if (marker != TXD_MARKER && marker != TXD_MARKER2) { - av_log(s, AV_LOG_ERROR, "marker does not match\n"); - return AVERROR_INVALIDDATA; - } - - switch (id) { - case TXD_INFO: - if (chunk_size > 100) - break; - case TXD_EXTRA: - url_fskip(s->pb, chunk_size); - case TXD_FILE: - case TXD_TEXTURE: - goto next_chunk; - default: - av_log(s, AV_LOG_ERROR, "unknown chunk id %i\n", id); - return AVERROR_INVALIDDATA; - } - - ret = av_get_packet(s->pb, pkt, chunk_size); - if (ret < 0) - return ret; - pkt->stream_index = 0; - - return 0; -} - -AVInputFormat txd_demuxer = -{ - "txd", - NULL_IF_CONFIG_SMALL("Renderware TeXture Dictionary"), - 0, - txd_probe, - txd_read_header, - txd_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/udp.c b/tizen/distrib/ffmpeg/libavformat/udp.c deleted file mode 100644 index a11f4c3..0000000 --- a/tizen/distrib/ffmpeg/libavformat/udp.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * UDP prototype streaming system - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * UDP protocol - */ - -#define _BSD_SOURCE /* Needed for using struct ip_mreq with recent glibc */ -#include "avformat.h" -#include -#include "internal.h" -#include "network.h" -#include "os_support.h" -#if HAVE_SYS_SELECT_H -#include -#endif -#include - -#ifndef IPV6_ADD_MEMBERSHIP -#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP -#endif -#ifndef IN_MULTICAST -#define IN_MULTICAST(a) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000) -#endif -#ifndef IN6_IS_ADDR_MULTICAST -#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff) -#endif - -typedef struct { - int udp_fd; - int ttl; - int buffer_size; - int is_multicast; - int local_port; - int reuse_socket; - struct sockaddr_storage dest_addr; - int dest_addr_len; -} UDPContext; - -#define UDP_TX_BUF_SIZE 32768 -#define UDP_MAX_PKT_SIZE 65536 - -static int udp_set_multicast_ttl(int sockfd, int mcastTTL, - struct sockaddr *addr) -{ -#ifdef IP_MULTICAST_TTL - if (addr->sa_family == AF_INET) { - if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL): %s\n", strerror(errno)); - return -1; - } - } -#endif -#if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS) - if (addr->sa_family == AF_INET6) { - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS): %s\n", strerror(errno)); - return -1; - } - } -#endif - return 0; -} - -static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) -{ -#ifdef IP_ADD_MEMBERSHIP - if (addr->sa_family == AF_INET) { - struct ip_mreq mreq; - - mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - mreq.imr_interface.s_addr= INADDR_ANY; - if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif -#if HAVE_STRUCT_IPV6_MREQ - if (addr->sa_family == AF_INET6) { - struct ipv6_mreq mreq6; - - memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); - mreq6.ipv6mr_interface= 0; - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif - return 0; -} - -static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr) -{ -#ifdef IP_DROP_MEMBERSHIP - if (addr->sa_family == AF_INET) { - struct ip_mreq mreq; - - mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - mreq.imr_interface.s_addr= INADDR_ANY; - if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif -#if HAVE_STRUCT_IPV6_MREQ - if (addr->sa_family == AF_INET6) { - struct ipv6_mreq mreq6; - - memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); - mreq6.ipv6mr_interface= 0; - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif - return 0; -} - -static struct addrinfo* udp_resolve_host(const char *hostname, int port, - int type, int family, int flags) -{ - struct addrinfo hints, *res = 0; - int error; - char sport[16]; - const char *node = 0, *service = "0"; - - if (port > 0) { - snprintf(sport, sizeof(sport), "%d", port); - service = sport; - } - if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) { - node = hostname; - } - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = type; - hints.ai_family = family; - hints.ai_flags = flags; - if ((error = getaddrinfo(node, service, &hints, &res))) { - res = NULL; - av_log(NULL, AV_LOG_ERROR, "udp_resolve_host: %s\n", gai_strerror(error)); - } - - return res; -} - -static int udp_set_url(struct sockaddr_storage *addr, - const char *hostname, int port) -{ - struct addrinfo *res0; - int addr_len; - - res0 = udp_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); - if (res0 == 0) return AVERROR(EIO); - memcpy(addr, res0->ai_addr, res0->ai_addrlen); - addr_len = res0->ai_addrlen; - freeaddrinfo(res0); - - return addr_len; -} - -static int is_multicast_address(struct sockaddr_storage *addr) -{ - if (addr->ss_family == AF_INET) { - return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr)); - } -#if HAVE_STRUCT_SOCKADDR_IN6 - if (addr->ss_family == AF_INET6) { - return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr); - } -#endif - - return 0; -} - -static int udp_socket_create(UDPContext *s, - struct sockaddr_storage *addr, int *addr_len) -{ - int udp_fd = -1; - struct addrinfo *res0 = NULL, *res = NULL; - int family = AF_UNSPEC; - - if (((struct sockaddr *) &s->dest_addr)->sa_family) - family = ((struct sockaddr *) &s->dest_addr)->sa_family; - res0 = udp_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE); - if (res0 == 0) - goto fail; - for (res = res0; res; res=res->ai_next) { - udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); - if (udp_fd > 0) break; - av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno)); - } - - if (udp_fd < 0) - goto fail; - - memcpy(addr, res->ai_addr, res->ai_addrlen); - *addr_len = res->ai_addrlen; - - freeaddrinfo(res0); - - return udp_fd; - - fail: - if (udp_fd >= 0) - closesocket(udp_fd); - if(res0) - freeaddrinfo(res0); - return -1; -} - -static int udp_port(struct sockaddr_storage *addr, int addr_len) -{ - char sbuf[sizeof(int)*3+1]; - - if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) { - av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno)); - return -1; - } - - return strtol(sbuf, NULL, 10); -} - - -/** - * If no filename is given to av_open_input_file because you want to - * get the local port first, then you must call this function to set - * the remote server address. - * - * url syntax: udp://host:port[?option=val...] - * option: 'ttl=n' : set the ttl value (for multicast only) - * 'localport=n' : set the local port - * 'pkt_size=n' : set max packet size - * 'reuse=1' : enable reusing the socket - * - * @param s1 media file context - * @param uri of the remote server - * @return zero if no error. - */ -int udp_set_remote_url(URLContext *h, const char *uri) -{ - UDPContext *s = h->priv_data; - char hostname[256]; - int port; - - ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); - - /* set the destination address */ - s->dest_addr_len = udp_set_url(&s->dest_addr, hostname, port); - if (s->dest_addr_len < 0) { - return AVERROR(EIO); - } - s->is_multicast = is_multicast_address(&s->dest_addr); - - return 0; -} - -/** - * Return the local port used by the UDP connexion - * @param s1 media file context - * @return the local port number - */ -int udp_get_local_port(URLContext *h) -{ - UDPContext *s = h->priv_data; - return s->local_port; -} - -/** - * Return the udp file handle for select() usage to wait for several RTP - * streams at the same time. - * @param h media file context - */ -#if (LIBAVFORMAT_VERSION_MAJOR >= 53) -static -#endif -int udp_get_file_handle(URLContext *h) -{ - UDPContext *s = h->priv_data; - return s->udp_fd; -} - -/* put it in UDP context */ -/* return non zero if error */ -static int udp_open(URLContext *h, const char *uri, int flags) -{ - char hostname[1024]; - int port, udp_fd = -1, tmp, bind_ret = -1; - UDPContext *s = NULL; - int is_output; - const char *p; - char buf[256]; - struct sockaddr_storage my_addr; - int len; - - h->is_streamed = 1; - h->max_packet_size = 1472; - - is_output = (flags & URL_WRONLY); - - s = av_mallocz(sizeof(UDPContext)); - if (!s) - return AVERROR(ENOMEM); - - h->priv_data = s; - s->ttl = 16; - s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE; - - p = strchr(uri, '?'); - if (p) { - s->reuse_socket = find_info_tag(buf, sizeof(buf), "reuse", p); - if (find_info_tag(buf, sizeof(buf), "ttl", p)) { - s->ttl = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "localport", p)) { - s->local_port = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) { - h->max_packet_size = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "buffer_size", p)) { - s->buffer_size = strtol(buf, NULL, 10); - } - } - - /* fill the dest addr */ - ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); - - /* XXX: fix ff_url_split */ - if (hostname[0] == '\0' || hostname[0] == '?') { - /* only accepts null hostname if input */ - if (flags & URL_WRONLY) - goto fail; - } else { - udp_set_remote_url(h, uri); - } - - if (s->is_multicast && !(h->flags & URL_WRONLY)) - s->local_port = port; - udp_fd = udp_socket_create(s, &my_addr, &len); - if (udp_fd < 0) - goto fail; - - if (s->reuse_socket) - if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0) - goto fail; - - /* the bind is needed to give a port to the socket now */ - /* if multicast, try the multicast address bind first */ - if (s->is_multicast && !(h->flags & URL_WRONLY)) { - bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); - } - /* bind to the local address if not multicast or if the multicast - * bind failed */ - if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) - goto fail; - - len = sizeof(my_addr); - getsockname(udp_fd, (struct sockaddr *)&my_addr, &len); - s->local_port = udp_port(&my_addr, len); - - if (s->is_multicast) { - if (h->flags & URL_WRONLY) { - /* output */ - if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0) - goto fail; - } else { - /* input */ - if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) - goto fail; - } - } - - if (is_output) { - /* limit the tx buf size to limit latency */ - tmp = s->buffer_size; - if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno)); - goto fail; - } - } else { - /* set udp recv buffer size to the largest possible udp packet size to - * avoid losing data on OSes that set this too low by default. */ - tmp = s->buffer_size; - if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) { - av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno)); - } - /* make the socket non-blocking */ - ff_socket_nonblock(udp_fd, 1); - } - - s->udp_fd = udp_fd; - return 0; - fail: - if (udp_fd >= 0) - closesocket(udp_fd); - av_free(s); - return AVERROR(EIO); -} - -static int udp_read(URLContext *h, uint8_t *buf, int size) -{ - UDPContext *s = h->priv_data; - int len; - fd_set rfds; - int ret; - struct timeval tv; - - for(;;) { - if (url_interrupt_cb()) - return AVERROR(EINTR); - FD_ZERO(&rfds); - FD_SET(s->udp_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv); - if (ret < 0) { - if (ff_neterrno() == FF_NETERROR(EINTR)) - continue; - return AVERROR(EIO); - } - if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds))) - continue; - len = recv(s->udp_fd, buf, size, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(EINTR)) - return AVERROR(EIO); - } else { - break; - } - } - return len; -} - -static int udp_write(URLContext *h, uint8_t *buf, int size) -{ - UDPContext *s = h->priv_data; - int ret; - - for(;;) { - ret = sendto (s->udp_fd, buf, size, 0, - (struct sockaddr *) &s->dest_addr, - s->dest_addr_len); - if (ret < 0) { - if (ff_neterrno() != FF_NETERROR(EINTR) && - ff_neterrno() != FF_NETERROR(EAGAIN)) - return AVERROR(EIO); - } else { - break; - } - } - return size; -} - -static int udp_close(URLContext *h) -{ - UDPContext *s = h->priv_data; - - if (s->is_multicast && !(h->flags & URL_WRONLY)) - udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); - closesocket(s->udp_fd); - av_free(s); - return 0; -} - -URLProtocol udp_protocol = { - "udp", - udp_open, - udp_read, - udp_write, - NULL, /* seek */ - udp_close, - .url_get_file_handle = udp_get_file_handle, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/utils.c b/tizen/distrib/ffmpeg/libavformat/utils.c deleted file mode 100644 index 7e6bf75..0000000 --- a/tizen/distrib/ffmpeg/libavformat/utils.c +++ /dev/null @@ -1,3591 +0,0 @@ -/* - * various utility functions for use within FFmpeg - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "internal.h" -#include "libavcodec/opt.h" -#include "metadata.h" -#include "libavutil/avstring.h" -#include "riff.h" -#include "audiointerleave.h" -#include -#include -#include -#include -#if CONFIG_NETWORK -#include "network.h" -#endif - -#undef NDEBUG -#include - -/** - * @file - * various utility functions for use within FFmpeg - */ - -unsigned avformat_version(void) -{ - return LIBAVFORMAT_VERSION_INT; -} - -const char *avformat_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *avformat_license(void) -{ -#define LICENSE_PREFIX "libavformat license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} - -/* fraction handling */ - -/** - * f = val + (num / den) + 0.5. - * - * 'num' is normalized so that it is such as 0 <= num < den. - * - * @param f fractional number - * @param val integer value - * @param num must be >= 0 - * @param den must be >= 1 - */ -static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den) -{ - num += (den >> 1); - if (num >= den) { - val += num / den; - num = num % den; - } - f->val = val; - f->num = num; - f->den = den; -} - -/** - * Fractional addition to f: f = f + (incr / f->den). - * - * @param f fractional number - * @param incr increment, can be positive or negative - */ -static void av_frac_add(AVFrac *f, int64_t incr) -{ - int64_t num, den; - - num = f->num + incr; - den = f->den; - if (num < 0) { - f->val += num / den; - num = num % den; - if (num < 0) { - num += den; - f->val--; - } - } else if (num >= den) { - f->val += num / den; - num = num % den; - } - f->num = num; -} - -/** head of registered input format linked list */ -AVInputFormat *first_iformat = NULL; -/** head of registered output format linked list */ -AVOutputFormat *first_oformat = NULL; - -AVInputFormat *av_iformat_next(AVInputFormat *f) -{ - if(f) return f->next; - else return first_iformat; -} - -AVOutputFormat *av_oformat_next(AVOutputFormat *f) -{ - if(f) return f->next; - else return first_oformat; -} - -void av_register_input_format(AVInputFormat *format) -{ - AVInputFormat **p; - p = &first_iformat; - while (*p != NULL) p = &(*p)->next; - *p = format; - format->next = NULL; -} - -void av_register_output_format(AVOutputFormat *format) -{ - AVOutputFormat **p; - p = &first_oformat; - while (*p != NULL) p = &(*p)->next; - *p = format; - format->next = NULL; -} - -int av_match_ext(const char *filename, const char *extensions) -{ - const char *ext, *p; - char ext1[32], *q; - - if(!filename) - return 0; - - ext = strrchr(filename, '.'); - if (ext) { - ext++; - p = extensions; - for(;;) { - q = ext1; - while (*p != '\0' && *p != ',' && q-ext1name && short_name && !strcmp(fmt->name, short_name)) - score += 100; - if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type)) - score += 10; - if (filename && fmt->extensions && - av_match_ext(filename, fmt->extensions)) { - score += 5; - } - if (score > score_max) { - score_max = score; - fmt_found = fmt; - } - fmt = fmt->next; - } - return fmt_found; -} - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, - const char *mime_type) -{ - AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type); - - if (fmt) { - AVOutputFormat *stream_fmt; - char stream_format_name[64]; - - snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name); - stream_fmt = av_guess_format(stream_format_name, NULL, NULL); - - if (stream_fmt) - fmt = stream_fmt; - } - - return fmt; -} -#endif - -enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, - const char *filename, const char *mime_type, enum AVMediaType type){ - if(type == AVMEDIA_TYPE_VIDEO){ - enum CodecID codec_id= CODEC_ID_NONE; - -#if CONFIG_IMAGE2_MUXER - if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){ - codec_id= av_guess_image2_codec(filename); - } -#endif - if(codec_id == CODEC_ID_NONE) - codec_id= fmt->video_codec; - return codec_id; - }else if(type == AVMEDIA_TYPE_AUDIO) - return fmt->audio_codec; - else - return CODEC_ID_NONE; -} - -AVInputFormat *av_find_input_format(const char *short_name) -{ - AVInputFormat *fmt; - for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) { - if (match_format(short_name, fmt->name)) - return fmt; - } - return NULL; -} - -#if LIBAVFORMAT_VERSION_MAJOR < 53 && CONFIG_SHARED && HAVE_SYMVER -FF_SYMVER(void, av_destruct_packet_nofree, (AVPacket *pkt), "LIBAVFORMAT_52") -{ - av_destruct_packet_nofree(pkt); -} - -FF_SYMVER(void, av_destruct_packet, (AVPacket *pkt), "LIBAVFORMAT_52") -{ - av_destruct_packet(pkt); -} - -FF_SYMVER(int, av_new_packet, (AVPacket *pkt, int size), "LIBAVFORMAT_52") -{ - return av_new_packet(pkt, size); -} - -FF_SYMVER(int, av_dup_packet, (AVPacket *pkt), "LIBAVFORMAT_52") -{ - return av_dup_packet(pkt); -} - -FF_SYMVER(void, av_free_packet, (AVPacket *pkt), "LIBAVFORMAT_52") -{ - av_free_packet(pkt); -} - -FF_SYMVER(void, av_init_packet, (AVPacket *pkt), "LIBAVFORMAT_52") -{ - av_log(NULL, AV_LOG_WARNING, "Diverting av_*_packet function calls to libavcodec. Recompile to improve performance\n"); - av_init_packet(pkt); -} -#endif - -int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size) -{ - int ret= av_new_packet(pkt, size); - - if(ret<0) - return ret; - - pkt->pos= url_ftell(s); - - ret= get_buffer(s, pkt->data, size); - if(ret<=0) - av_free_packet(pkt); - else - av_shrink_packet(pkt, ret); - - return ret; -} - - -int av_filename_number_test(const char *filename) -{ - char buf[1024]; - return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0); -} - -AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max) -{ - AVInputFormat *fmt1, *fmt; - int score; - - fmt = NULL; - for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) { - if (!is_opened == !(fmt1->flags & AVFMT_NOFILE)) - continue; - score = 0; - if (fmt1->read_probe) { - score = fmt1->read_probe(pd); - } else if (fmt1->extensions) { - if (av_match_ext(pd->filename, fmt1->extensions)) { - score = 50; - } - } - if (score > *score_max) { - *score_max = score; - fmt = fmt1; - }else if (score == *score_max) - fmt = NULL; - } - return fmt; -} - -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){ - int score=0; - return av_probe_input_format2(pd, is_opened, &score); -} - -static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd, int score) -{ - AVInputFormat *fmt; - fmt = av_probe_input_format2(pd, 1, &score); - - if (fmt) { - av_log(s, AV_LOG_DEBUG, "Probe with size=%d, packets=%d detected %s with score=%d\n", - pd->buf_size, MAX_PROBE_PACKETS - st->probe_packets, fmt->name, score); - if (!strcmp(fmt->name, "mp3")) { - st->codec->codec_id = CODEC_ID_MP3; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } else if (!strcmp(fmt->name, "ac3")) { - st->codec->codec_id = CODEC_ID_AC3; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } else if (!strcmp(fmt->name, "eac3")) { - st->codec->codec_id = CODEC_ID_EAC3; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } else if (!strcmp(fmt->name, "mpegvideo")) { - st->codec->codec_id = CODEC_ID_MPEG2VIDEO; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - } else if (!strcmp(fmt->name, "m4v")) { - st->codec->codec_id = CODEC_ID_MPEG4; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - } else if (!strcmp(fmt->name, "h264")) { - st->codec->codec_id = CODEC_ID_H264; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - } else if (!strcmp(fmt->name, "dts")) { - st->codec->codec_id = CODEC_ID_DTS; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } else if (!strcmp(fmt->name, "aac")) { - st->codec->codec_id = CODEC_ID_AAC; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } - } - return !!fmt; -} - -/************************************************************/ -/* input media file */ - -/** - * Open a media file from an IO stream. 'fmt' must be specified. - */ -int av_open_input_stream(AVFormatContext **ic_ptr, - ByteIOContext *pb, const char *filename, - AVInputFormat *fmt, AVFormatParameters *ap) -{ - int err; - AVFormatContext *ic; - AVFormatParameters default_ap; - - if(!ap){ - ap=&default_ap; - memset(ap, 0, sizeof(default_ap)); - } - - if(!ap->prealloced_context) - ic = avformat_alloc_context(); - else - ic = *ic_ptr; - if (!ic) { - err = AVERROR(ENOMEM); - goto fail; - } - ic->iformat = fmt; - ic->pb = pb; - ic->duration = AV_NOPTS_VALUE; - ic->start_time = AV_NOPTS_VALUE; - av_strlcpy(ic->filename, filename, sizeof(ic->filename)); - - /* allocate private data */ - if (fmt->priv_data_size > 0) { - ic->priv_data = av_mallocz(fmt->priv_data_size); - if (!ic->priv_data) { - err = AVERROR(ENOMEM); - goto fail; - } - } else { - ic->priv_data = NULL; - } - - if (ic->iformat->read_header) { - err = ic->iformat->read_header(ic, ap); - if (err < 0) - goto fail; - } - - if (pb && !ic->data_offset) - ic->data_offset = url_ftell(ic->pb); - -#if LIBAVFORMAT_VERSION_MAJOR < 53 - ff_metadata_demux_compat(ic); -#endif - - ic->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; - - *ic_ptr = ic; - return 0; - fail: - if (ic) { - int i; - av_freep(&ic->priv_data); - for(i=0;inb_streams;i++) { - AVStream *st = ic->streams[i]; - if (st) { - av_free(st->priv_data); - av_free(st->codec->extradata); - } - av_free(st); - } - } - av_free(ic); - *ic_ptr = NULL; - return err; -} - -/** size of probe buffer, for guessing file type from file contents */ -#define PROBE_BUF_MIN 2048 -#define PROBE_BUF_MAX (1<<20) - -int ff_probe_input_buffer(ByteIOContext **pb, AVInputFormat **fmt, - const char *filename, void *logctx, - unsigned int offset, unsigned int max_probe_size) -{ - AVProbeData pd = { filename ? filename : "", NULL, -offset }; - unsigned char *buf = NULL; - int ret = 0, probe_size; - - if (!max_probe_size) { - max_probe_size = PROBE_BUF_MAX; - } else if (max_probe_size > PROBE_BUF_MAX) { - max_probe_size = PROBE_BUF_MAX; - } else if (max_probe_size < PROBE_BUF_MIN) { - return AVERROR(EINVAL); - } - - if (offset >= max_probe_size) { - return AVERROR(EINVAL); - } - - for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt && ret >= 0; - probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) { - int ret, score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0; - int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1; - - if (probe_size < offset) { - continue; - } - - /* read probe data */ - buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE); - if ((ret = get_buffer(*pb, buf + buf_offset, probe_size - buf_offset)) < 0) { - /* fail if error was not end of file, otherwise, lower score */ - if (ret != AVERROR_EOF) { - av_free(buf); - return ret; - } - score = 0; - ret = 0; /* error was end of file, nothing read */ - } - pd.buf_size += ret; - pd.buf = &buf[offset]; - - memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); - - /* guess file format */ - *fmt = av_probe_input_format2(&pd, 1, &score); - if(*fmt){ - if(score <= AVPROBE_SCORE_MAX/4){ //this can only be true in the last iteration - av_log(logctx, AV_LOG_WARNING, "Format detected only with low score of %d, misdetection possible!\n", score); - }else - av_log(logctx, AV_LOG_DEBUG, "Probed with size=%d and score=%d\n", probe_size, score); - } - } - - if (!*fmt) { - av_free(buf); - return AVERROR_INVALIDDATA; - } - - /* rewind. reuse probe buffer to avoid seeking */ - if ((ret = ff_rewind_with_probe_data(*pb, buf, pd.buf_size)) < 0) - av_free(buf); - - return ret; -} - -int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, - AVInputFormat *fmt, - int buf_size, - AVFormatParameters *ap) -{ - int err; - AVProbeData probe_data, *pd = &probe_data; - ByteIOContext *pb = NULL; - void *logctx= ap && ap->prealloced_context ? *ic_ptr : NULL; - - pd->filename = ""; - if (filename) - pd->filename = filename; - pd->buf = NULL; - pd->buf_size = 0; - - if (!fmt) { - /* guess format if no file can be opened */ - fmt = av_probe_input_format(pd, 0); - } - - /* Do not open file if the format does not need it. XXX: specific - hack needed to handle RTSP/TCP */ - if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { - /* if no file needed do not try to open one */ - if ((err=url_fopen(&pb, filename, URL_RDONLY)) < 0) { - goto fail; - } - if (buf_size > 0) { - url_setbufsize(pb, buf_size); - } - if (!fmt && (err = ff_probe_input_buffer(&pb, &fmt, filename, logctx, 0, logctx ? (*ic_ptr)->probesize : 0)) < 0) { - goto fail; - } - } - - /* if still no format found, error */ - if (!fmt) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - /* check filename in case an image number is expected */ - if (fmt->flags & AVFMT_NEEDNUMBER) { - if (!av_filename_number_test(filename)) { - err = AVERROR_NUMEXPECTED; - goto fail; - } - } - err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap); - if (err) - goto fail; - return 0; - fail: - av_freep(&pd->buf); - if (pb) - url_fclose(pb); - if (ap && ap->prealloced_context) - av_free(*ic_ptr); - *ic_ptr = NULL; - return err; - -} - -/*******************************************************/ - -static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt, - AVPacketList **plast_pktl){ - AVPacketList *pktl = av_mallocz(sizeof(AVPacketList)); - if (!pktl) - return NULL; - - if (*packet_buffer) - (*plast_pktl)->next = pktl; - else - *packet_buffer = pktl; - - /* add the packet in the buffered packet list */ - *plast_pktl = pktl; - pktl->pkt= *pkt; - return &pktl->pkt; -} - -int av_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, i; - AVStream *st; - - for(;;){ - AVPacketList *pktl = s->raw_packet_buffer; - - if (pktl) { - *pkt = pktl->pkt; - if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE || - !s->streams[pkt->stream_index]->probe_packets || - s->raw_packet_buffer_remaining_size < pkt->size){ - AVProbeData *pd = &s->streams[pkt->stream_index]->probe_data; - av_freep(&pd->buf); - pd->buf_size = 0; - s->raw_packet_buffer = pktl->next; - s->raw_packet_buffer_remaining_size += pkt->size; - av_free(pktl); - return 0; - } - } - - av_init_packet(pkt); - ret= s->iformat->read_packet(s, pkt); - if (ret < 0) { - if (!pktl || ret == AVERROR(EAGAIN)) - return ret; - for (i = 0; i < s->nb_streams; i++) - s->streams[i]->probe_packets = 0; - continue; - } - st= s->streams[pkt->stream_index]; - - switch(st->codec->codec_type){ - case AVMEDIA_TYPE_VIDEO: - if(s->video_codec_id) st->codec->codec_id= s->video_codec_id; - break; - case AVMEDIA_TYPE_AUDIO: - if(s->audio_codec_id) st->codec->codec_id= s->audio_codec_id; - break; - case AVMEDIA_TYPE_SUBTITLE: - if(s->subtitle_codec_id)st->codec->codec_id= s->subtitle_codec_id; - break; - } - - if(!pktl && (st->codec->codec_id != CODEC_ID_PROBE || - !st->probe_packets)) - return ret; - - add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end); - s->raw_packet_buffer_remaining_size -= pkt->size; - - if(st->codec->codec_id == CODEC_ID_PROBE){ - AVProbeData *pd = &st->probe_data; - av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index); - --st->probe_packets; - - pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); - memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); - pd->buf_size += pkt->size; - memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); - - if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){ - //FIXME we dont reduce score to 0 for the case of running out of buffer space in bytes - set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0); - if(st->codec->codec_id != CODEC_ID_PROBE){ - pd->buf_size=0; - av_freep(&pd->buf); - av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index); - } - } - } - } -} - -/**********************************************************/ - -/** - * Get the number of samples of an audio frame. Return -1 on error. - */ -static int get_audio_frame_size(AVCodecContext *enc, int size) -{ - int frame_size; - - if(enc->codec_id == CODEC_ID_VORBIS) - return -1; - - if (enc->frame_size <= 1) { - int bits_per_sample = av_get_bits_per_sample(enc->codec_id); - - if (bits_per_sample) { - if (enc->channels == 0) - return -1; - frame_size = (size << 3) / (bits_per_sample * enc->channels); - } else { - /* used for example by ADPCM codecs */ - if (enc->bit_rate == 0) - return -1; - frame_size = ((int64_t)size * 8 * enc->sample_rate) / enc->bit_rate; - } - } else { - frame_size = enc->frame_size; - } - return frame_size; -} - - -/** - * Return the frame duration in seconds. Return 0 if not available. - */ -static void compute_frame_duration(int *pnum, int *pden, AVStream *st, - AVCodecParserContext *pc, AVPacket *pkt) -{ - int frame_size; - - *pnum = 0; - *pden = 0; - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if(st->time_base.num*1000LL > st->time_base.den){ - *pnum = st->time_base.num; - *pden = st->time_base.den; - }else if(st->codec->time_base.num*1000LL > st->codec->time_base.den){ - *pnum = st->codec->time_base.num; - *pden = st->codec->time_base.den; - if (pc && pc->repeat_pict) { - *pnum = (*pnum) * (1 + pc->repeat_pict); - } - //If this codec can be interlaced or progressive then we need a parser to compute duration of a packet - //Thus if we have no parser in such case leave duration undefined. - if(st->codec->ticks_per_frame>1 && !pc){ - *pnum = *pden = 0; - } - } - break; - case AVMEDIA_TYPE_AUDIO: - frame_size = get_audio_frame_size(st->codec, pkt->size); - if (frame_size < 0) - break; - *pnum = frame_size; - *pden = st->codec->sample_rate; - break; - default: - break; - } -} - -static int is_intra_only(AVCodecContext *enc){ - if(enc->codec_type == AVMEDIA_TYPE_AUDIO){ - return 1; - }else if(enc->codec_type == AVMEDIA_TYPE_VIDEO){ - switch(enc->codec_id){ - case CODEC_ID_MJPEG: - case CODEC_ID_MJPEGB: - case CODEC_ID_LJPEG: - case CODEC_ID_RAWVIDEO: - case CODEC_ID_DVVIDEO: - case CODEC_ID_HUFFYUV: - case CODEC_ID_FFVHUFF: - case CODEC_ID_ASV1: - case CODEC_ID_ASV2: - case CODEC_ID_VCR1: - case CODEC_ID_DNXHD: - case CODEC_ID_JPEG2000: - return 1; - default: break; - } - } - return 0; -} - -static void update_initial_timestamps(AVFormatContext *s, int stream_index, - int64_t dts, int64_t pts) -{ - AVStream *st= s->streams[stream_index]; - AVPacketList *pktl= s->packet_buffer; - - if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE) - return; - - st->first_dts= dts - st->cur_dts; - st->cur_dts= dts; - - for(; pktl; pktl= pktl->next){ - if(pktl->pkt.stream_index != stream_index) - continue; - //FIXME think more about this check - if(pktl->pkt.pts != AV_NOPTS_VALUE && pktl->pkt.pts == pktl->pkt.dts) - pktl->pkt.pts += st->first_dts; - - if(pktl->pkt.dts != AV_NOPTS_VALUE) - pktl->pkt.dts += st->first_dts; - - if(st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE) - st->start_time= pktl->pkt.pts; - } - if (st->start_time == AV_NOPTS_VALUE) - st->start_time = pts; -} - -static void update_initial_durations(AVFormatContext *s, AVStream *st, AVPacket *pkt) -{ - AVPacketList *pktl= s->packet_buffer; - int64_t cur_dts= 0; - - if(st->first_dts != AV_NOPTS_VALUE){ - cur_dts= st->first_dts; - for(; pktl; pktl= pktl->next){ - if(pktl->pkt.stream_index == pkt->stream_index){ - if(pktl->pkt.pts != pktl->pkt.dts || pktl->pkt.dts != AV_NOPTS_VALUE || pktl->pkt.duration) - break; - cur_dts -= pkt->duration; - } - } - pktl= s->packet_buffer; - st->first_dts = cur_dts; - }else if(st->cur_dts) - return; - - for(; pktl; pktl= pktl->next){ - if(pktl->pkt.stream_index != pkt->stream_index) - continue; - if(pktl->pkt.pts == pktl->pkt.dts && pktl->pkt.dts == AV_NOPTS_VALUE - && !pktl->pkt.duration){ - pktl->pkt.dts= cur_dts; - if(!st->codec->has_b_frames) - pktl->pkt.pts= cur_dts; - cur_dts += pkt->duration; - pktl->pkt.duration= pkt->duration; - }else - break; - } - if(st->first_dts == AV_NOPTS_VALUE) - st->cur_dts= cur_dts; -} - -static void compute_pkt_fields(AVFormatContext *s, AVStream *st, - AVCodecParserContext *pc, AVPacket *pkt) -{ - int num, den, presentation_delayed, delay, i; - int64_t offset; - - if (s->flags & AVFMT_FLAG_NOFILLIN) - return; - - if((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE) - pkt->dts= AV_NOPTS_VALUE; - - if (st->codec->codec_id != CODEC_ID_H264 && pc && pc->pict_type == FF_B_TYPE) - //FIXME Set low_delay = 0 when has_b_frames = 1 - st->codec->has_b_frames = 1; - - /* do we have a video B-frame ? */ - delay= st->codec->has_b_frames; - presentation_delayed = 0; - /* XXX: need has_b_frame, but cannot get it if the codec is - not initialized */ - if (delay && - pc && pc->pict_type != FF_B_TYPE) - presentation_delayed = 1; - - if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts > pkt->pts && st->pts_wrap_bits<63 - /*&& pkt->dts-(1LL<pts_wrap_bits) < pkt->pts*/){ - pkt->dts -= 1LL<pts_wrap_bits; - } - - // some mpeg2 in mpeg-ps lack dts (issue171 / input_file.mpg) - // we take the conservative approach and discard both - // Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly. - if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){ - av_log(s, AV_LOG_WARNING, "invalid dts/pts combination\n"); - pkt->dts= pkt->pts= AV_NOPTS_VALUE; - } - - if (pkt->duration == 0) { - compute_frame_duration(&num, &den, st, pc, pkt); - if (den && num) { - pkt->duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num, AV_ROUND_DOWN); - - if(pkt->duration != 0 && s->packet_buffer) - update_initial_durations(s, st, pkt); - } - } - - /* correct timestamps with byte offset if demuxers only have timestamps - on packet boundaries */ - if(pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size){ - /* this will estimate bitrate based on this frame's duration and size */ - offset = av_rescale(pc->offset, pkt->duration, pkt->size); - if(pkt->pts != AV_NOPTS_VALUE) - pkt->pts += offset; - if(pkt->dts != AV_NOPTS_VALUE) - pkt->dts += offset; - } - - if (pc && pc->dts_sync_point >= 0) { - // we have synchronization info from the parser - int64_t den = st->codec->time_base.den * (int64_t) st->time_base.num; - if (den > 0) { - int64_t num = st->codec->time_base.num * (int64_t) st->time_base.den; - if (pkt->dts != AV_NOPTS_VALUE) { - // got DTS from the stream, update reference timestamp - st->reference_dts = pkt->dts - pc->dts_ref_dts_delta * num / den; - pkt->pts = pkt->dts + pc->pts_dts_delta * num / den; - } else if (st->reference_dts != AV_NOPTS_VALUE) { - // compute DTS based on reference timestamp - pkt->dts = st->reference_dts + pc->dts_ref_dts_delta * num / den; - pkt->pts = pkt->dts + pc->pts_dts_delta * num / den; - } - if (pc->dts_sync_point > 0) - st->reference_dts = pkt->dts; // new reference - } - } - - /* This may be redundant, but it should not hurt. */ - if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts) - presentation_delayed = 1; - -// av_log(NULL, AV_LOG_DEBUG, "IN delayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64" st:%d pc:%p\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts, pkt->stream_index, pc); - /* interpolate PTS and DTS if they are not present */ - //We skip H264 currently because delay and has_b_frames are not reliably set - if((delay==0 || (delay==1 && pc)) && st->codec->codec_id != CODEC_ID_H264){ - if (presentation_delayed) { - /* DTS = decompression timestamp */ - /* PTS = presentation timestamp */ - if (pkt->dts == AV_NOPTS_VALUE) - pkt->dts = st->last_IP_pts; - update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts); - if (pkt->dts == AV_NOPTS_VALUE) - pkt->dts = st->cur_dts; - - /* this is tricky: the dts must be incremented by the duration - of the frame we are displaying, i.e. the last I- or P-frame */ - if (st->last_IP_duration == 0) - st->last_IP_duration = pkt->duration; - if(pkt->dts != AV_NOPTS_VALUE) - st->cur_dts = pkt->dts + st->last_IP_duration; - st->last_IP_duration = pkt->duration; - st->last_IP_pts= pkt->pts; - /* cannot compute PTS if not present (we can compute it only - by knowing the future */ - } else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){ - if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){ - int64_t old_diff= FFABS(st->cur_dts - pkt->duration - pkt->pts); - int64_t new_diff= FFABS(st->cur_dts - pkt->pts); - if(old_diff < new_diff && old_diff < (pkt->duration>>3)){ - pkt->pts += pkt->duration; - // av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size); - } - } - - /* presentation is not delayed : PTS and DTS are the same */ - if(pkt->pts == AV_NOPTS_VALUE) - pkt->pts = pkt->dts; - update_initial_timestamps(s, pkt->stream_index, pkt->pts, pkt->pts); - if(pkt->pts == AV_NOPTS_VALUE) - pkt->pts = st->cur_dts; - pkt->dts = pkt->pts; - if(pkt->pts != AV_NOPTS_VALUE) - st->cur_dts = pkt->pts + pkt->duration; - } - } - - if(pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY){ - st->pts_buffer[0]= pkt->pts; - for(i=0; ipts_buffer[i] > st->pts_buffer[i+1]; i++) - FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]); - if(pkt->dts == AV_NOPTS_VALUE) - pkt->dts= st->pts_buffer[0]; - if(st->codec->codec_id == CODEC_ID_H264){ //we skiped it above so we try here - update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts); // this should happen on the first packet - } - if(pkt->dts > st->cur_dts) - st->cur_dts = pkt->dts; - } - -// av_log(NULL, AV_LOG_ERROR, "OUTdelayed:%d/%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64"\n", presentation_delayed, delay, pkt->pts, pkt->dts, st->cur_dts); - - /* update flags */ - if(is_intra_only(st->codec)) - pkt->flags |= AV_PKT_FLAG_KEY; - else if (pc) { - pkt->flags = 0; - /* keyframe computation */ - if (pc->key_frame == 1) - pkt->flags |= AV_PKT_FLAG_KEY; - else if (pc->key_frame == -1 && pc->pict_type == FF_I_TYPE) - pkt->flags |= AV_PKT_FLAG_KEY; - } - if (pc) - pkt->convergence_duration = pc->convergence_duration; -} - - -static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt) -{ - AVStream *st; - int len, ret, i; - - av_init_packet(pkt); - - for(;;) { - /* select current input stream component */ - st = s->cur_st; - if (st) { - if (!st->need_parsing || !st->parser) { - /* no parsing needed: we just output the packet as is */ - /* raw data support */ - *pkt = st->cur_pkt; st->cur_pkt.data= NULL; - compute_pkt_fields(s, st, NULL, pkt); - s->cur_st = NULL; - if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && - (pkt->flags & AV_PKT_FLAG_KEY) && pkt->dts != AV_NOPTS_VALUE) { - ff_reduce_index(s, st->index); - av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME); - } - break; - } else if (st->cur_len > 0 && st->discard < AVDISCARD_ALL) { - len = av_parser_parse2(st->parser, st->codec, &pkt->data, &pkt->size, - st->cur_ptr, st->cur_len, - st->cur_pkt.pts, st->cur_pkt.dts, - st->cur_pkt.pos); - st->cur_pkt.pts = AV_NOPTS_VALUE; - st->cur_pkt.dts = AV_NOPTS_VALUE; - /* increment read pointer */ - st->cur_ptr += len; - st->cur_len -= len; - - /* return packet if any */ - if (pkt->size) { - got_packet: - pkt->duration = 0; - pkt->stream_index = st->index; - pkt->pts = st->parser->pts; - pkt->dts = st->parser->dts; - pkt->pos = st->parser->pos; - pkt->destruct = NULL; - compute_pkt_fields(s, st, st->parser, pkt); - - if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY){ - ff_reduce_index(s, st->index); - av_add_index_entry(st, st->parser->frame_offset, pkt->dts, - 0, 0, AVINDEX_KEYFRAME); - } - - break; - } - } else { - /* free packet */ - av_free_packet(&st->cur_pkt); - s->cur_st = NULL; - } - } else { - AVPacket cur_pkt; - /* read next packet */ - ret = av_read_packet(s, &cur_pkt); - if (ret < 0) { - if (ret == AVERROR(EAGAIN)) - return ret; - /* return the last frames, if any */ - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - if (st->parser && st->need_parsing) { - av_parser_parse2(st->parser, st->codec, - &pkt->data, &pkt->size, - NULL, 0, - AV_NOPTS_VALUE, AV_NOPTS_VALUE, - AV_NOPTS_VALUE); - if (pkt->size) - goto got_packet; - } - } - /* no more packets: really terminate parsing */ - return ret; - } - st = s->streams[cur_pkt.stream_index]; - st->cur_pkt= cur_pkt; - - if(st->cur_pkt.pts != AV_NOPTS_VALUE && - st->cur_pkt.dts != AV_NOPTS_VALUE && - st->cur_pkt.pts < st->cur_pkt.dts){ - av_log(s, AV_LOG_WARNING, "Invalid timestamps stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d\n", - st->cur_pkt.stream_index, - st->cur_pkt.pts, - st->cur_pkt.dts, - st->cur_pkt.size); -// av_free_packet(&st->cur_pkt); -// return -1; - } - - if(s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n", - st->cur_pkt.stream_index, - st->cur_pkt.pts, - st->cur_pkt.dts, - st->cur_pkt.size, - st->cur_pkt.duration, - st->cur_pkt.flags); - - s->cur_st = st; - st->cur_ptr = st->cur_pkt.data; - st->cur_len = st->cur_pkt.size; - if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) { - st->parser = av_parser_init(st->codec->codec_id); - if (!st->parser) { - /* no parser available: just output the raw packets */ - st->need_parsing = AVSTREAM_PARSE_NONE; - }else if(st->need_parsing == AVSTREAM_PARSE_HEADERS){ - st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } - if(st->parser && (s->iformat->flags & AVFMT_GENERIC_INDEX)){ - st->parser->next_frame_offset= - st->parser->cur_offset= st->cur_pkt.pos; - } - } - } - } - if(s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n", - pkt->stream_index, - pkt->pts, - pkt->dts, - pkt->size, - pkt->duration, - pkt->flags); - - return 0; -} - -int av_read_frame(AVFormatContext *s, AVPacket *pkt) -{ - AVPacketList *pktl; - int eof=0; - const int genpts= s->flags & AVFMT_FLAG_GENPTS; - - for(;;){ - pktl = s->packet_buffer; - if (pktl) { - AVPacket *next_pkt= &pktl->pkt; - - if(genpts && next_pkt->dts != AV_NOPTS_VALUE){ - while(pktl && next_pkt->pts == AV_NOPTS_VALUE){ - if( pktl->pkt.stream_index == next_pkt->stream_index - && next_pkt->dts < pktl->pkt.dts - && pktl->pkt.pts != pktl->pkt.dts //not b frame - /*&& pktl->pkt.dts != AV_NOPTS_VALUE*/){ - next_pkt->pts= pktl->pkt.dts; - } - pktl= pktl->next; - } - pktl = s->packet_buffer; - } - - if( next_pkt->pts != AV_NOPTS_VALUE - || next_pkt->dts == AV_NOPTS_VALUE - || !genpts || eof){ - /* read packet from packet buffer, if there is data */ - *pkt = *next_pkt; - s->packet_buffer = pktl->next; - av_free(pktl); - return 0; - } - } - if(genpts){ - int ret= av_read_frame_internal(s, pkt); - if(ret<0){ - if(pktl && ret != AVERROR(EAGAIN)){ - eof=1; - continue; - }else - return ret; - } - - if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt, - &s->packet_buffer_end)) < 0) - return AVERROR(ENOMEM); - }else{ - assert(!s->packet_buffer); - return av_read_frame_internal(s, pkt); - } - } -} - -/* XXX: suppress the packet queue */ -static void flush_packet_queue(AVFormatContext *s) -{ - AVPacketList *pktl; - - for(;;) { - pktl = s->packet_buffer; - if (!pktl) - break; - s->packet_buffer = pktl->next; - av_free_packet(&pktl->pkt); - av_free(pktl); - } - while(s->raw_packet_buffer){ - pktl = s->raw_packet_buffer; - s->raw_packet_buffer = pktl->next; - av_free_packet(&pktl->pkt); - av_free(pktl); - } - s->packet_buffer_end= - s->raw_packet_buffer_end= NULL; - s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; -} - -/*******************************************************/ -/* seek support */ - -int av_find_default_stream_index(AVFormatContext *s) -{ - int first_audio_index = -1; - int i; - AVStream *st; - - if (s->nb_streams <= 0) - return -1; - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - return i; - } - if (first_audio_index < 0 && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - first_audio_index = i; - } - return first_audio_index >= 0 ? first_audio_index : 0; -} - -/** - * Flush the frame reader. - */ -void ff_read_frame_flush(AVFormatContext *s) -{ - AVStream *st; - int i, j; - - flush_packet_queue(s); - - s->cur_st = NULL; - - /* for each stream, reset read state */ - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - - if (st->parser) { - av_parser_close(st->parser); - st->parser = NULL; - av_free_packet(&st->cur_pkt); - } - st->last_IP_pts = AV_NOPTS_VALUE; - st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */ - st->reference_dts = AV_NOPTS_VALUE; - /* fail safe */ - st->cur_ptr = NULL; - st->cur_len = 0; - - st->probe_packets = MAX_PROBE_PACKETS; - - for(j=0; jpts_buffer[j]= AV_NOPTS_VALUE; - } -} - -void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){ - int i; - - for(i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - - st->cur_dts = av_rescale(timestamp, - st->time_base.den * (int64_t)ref_st->time_base.num, - st->time_base.num * (int64_t)ref_st->time_base.den); - } -} - -void ff_reduce_index(AVFormatContext *s, int stream_index) -{ - AVStream *st= s->streams[stream_index]; - unsigned int max_entries= s->max_index_size / sizeof(AVIndexEntry); - - if((unsigned)st->nb_index_entries >= max_entries){ - int i; - for(i=0; 2*inb_index_entries; i++) - st->index_entries[i]= st->index_entries[2*i]; - st->nb_index_entries= i; - } -} - -int av_add_index_entry(AVStream *st, - int64_t pos, int64_t timestamp, int size, int distance, int flags) -{ - AVIndexEntry *entries, *ie; - int index; - - if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry)) - return -1; - - entries = av_fast_realloc(st->index_entries, - &st->index_entries_allocated_size, - (st->nb_index_entries + 1) * - sizeof(AVIndexEntry)); - if(!entries) - return -1; - - st->index_entries= entries; - - index= av_index_search_timestamp(st, timestamp, AVSEEK_FLAG_ANY); - - if(index<0){ - index= st->nb_index_entries++; - ie= &entries[index]; - assert(index==0 || ie[-1].timestamp < timestamp); - }else{ - ie= &entries[index]; - if(ie->timestamp != timestamp){ - if(ie->timestamp <= timestamp) - return -1; - memmove(entries + index + 1, entries + index, sizeof(AVIndexEntry)*(st->nb_index_entries - index)); - st->nb_index_entries++; - }else if(ie->pos == pos && distance < ie->min_distance) //do not reduce the distance - distance= ie->min_distance; - } - - ie->pos = pos; - ie->timestamp = timestamp; - ie->min_distance= distance; - ie->size= size; - ie->flags = flags; - - return index; -} - -int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, - int flags) -{ - AVIndexEntry *entries= st->index_entries; - int nb_entries= st->nb_index_entries; - int a, b, m; - int64_t timestamp; - - a = - 1; - b = nb_entries; - - //optimize appending index entries at the end - if(b && entries[b-1].timestamp < wanted_timestamp) - a= b-1; - - while (b - a > 1) { - m = (a + b) >> 1; - timestamp = entries[m].timestamp; - if(timestamp >= wanted_timestamp) - b = m; - if(timestamp <= wanted_timestamp) - a = m; - } - m= (flags & AVSEEK_FLAG_BACKWARD) ? a : b; - - if(!(flags & AVSEEK_FLAG_ANY)){ - while(m>=0 && miformat; - int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit; - int64_t ts_min, ts_max, ts; - int index; - int64_t ret; - AVStream *st; - - if (stream_index < 0) - return -1; - -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "read_seek: %d %"PRId64"\n", stream_index, target_ts); -#endif - - ts_max= - ts_min= AV_NOPTS_VALUE; - pos_limit= -1; //gcc falsely says it may be uninitialized - - st= s->streams[stream_index]; - if(st->index_entries){ - AVIndexEntry *e; - - index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non-keyframe entries in index case, especially read_timestamp() - index= FFMAX(index, 0); - e= &st->index_entries[index]; - - if(e->timestamp <= target_ts || e->pos == e->min_distance){ - pos_min= e->pos; - ts_min= e->timestamp; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n", - pos_min,ts_min); -#endif - }else{ - assert(index==0); - } - - index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD); - assert(index < st->nb_index_entries); - if(index >= 0){ - e= &st->index_entries[index]; - assert(e->timestamp >= target_ts); - pos_max= e->pos; - ts_max= e->timestamp; - pos_limit= pos_max - e->min_distance; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n", - pos_max,pos_limit, ts_max); -#endif - } - } - - pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp); - if(pos<0) - return -1; - - /* do the seek */ - if ((ret = url_fseek(s->pb, pos, SEEK_SET)) < 0) - return ret; - - av_update_cur_dts(s, st, ts); - - return 0; -} - -int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){ - int64_t pos, ts; - int64_t start_pos, filesize; - int no_change; - -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts); -#endif - - if(ts_min == AV_NOPTS_VALUE){ - pos_min = s->data_offset; - ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX); - if (ts_min == AV_NOPTS_VALUE) - return -1; - } - - if(ts_max == AV_NOPTS_VALUE){ - int step= 1024; - filesize = url_fsize(s->pb); - pos_max = filesize - 1; - do{ - pos_max -= step; - ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step); - step += step; - }while(ts_max == AV_NOPTS_VALUE && pos_max >= step); - if (ts_max == AV_NOPTS_VALUE) - return -1; - - for(;;){ - int64_t tmp_pos= pos_max + 1; - int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX); - if(tmp_ts == AV_NOPTS_VALUE) - break; - ts_max= tmp_ts; - pos_max= tmp_pos; - if(tmp_pos >= filesize) - break; - } - pos_limit= pos_max; - } - - if(ts_min > ts_max){ - return -1; - }else if(ts_min == ts_max){ - pos_limit= pos_min; - } - - no_change=0; - while (pos_min < pos_limit) { -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n", - pos_min, pos_max, - ts_min, ts_max); -#endif - assert(pos_limit <= pos_max); - - if(no_change==0){ - int64_t approximate_keyframe_distance= pos_max - pos_limit; - // interpolate position (better than dichotomy) - pos = av_rescale(target_ts - ts_min, pos_max - pos_min, ts_max - ts_min) - + pos_min - approximate_keyframe_distance; - }else if(no_change==1){ - // bisection, if interpolation failed to change min or max pos last time - pos = (pos_min + pos_limit)>>1; - }else{ - /* linear search if bisection failed, can only happen if there - are very few or no keyframes between min/max */ - pos=pos_min; - } - if(pos <= pos_min) - pos= pos_min + 1; - else if(pos > pos_limit) - pos= pos_limit; - start_pos= pos; - - ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1 - if(pos == pos_max) - no_change++; - else - no_change=0; -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n", - pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts, pos_limit, - start_pos, no_change); -#endif - if(ts == AV_NOPTS_VALUE){ - av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n"); - return -1; - } - assert(ts != AV_NOPTS_VALUE); - if (target_ts <= ts) { - pos_limit = start_pos - 1; - pos_max = pos; - ts_max = ts; - } - if (target_ts >= ts) { - pos_min = pos; - ts_min = ts; - } - } - - pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; - ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; -#ifdef DEBUG_SEEK - pos_min = pos; - ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX); - pos_min++; - ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX); - av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n", - pos, ts_min, target_ts, ts_max); -#endif - *ts_ret= ts; - return pos; -} - -static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){ - int64_t pos_min, pos_max; -#if 0 - AVStream *st; - - if (stream_index < 0) - return -1; - - st= s->streams[stream_index]; -#endif - - pos_min = s->data_offset; - pos_max = url_fsize(s->pb) - 1; - - if (pos < pos_min) pos= pos_min; - else if(pos > pos_max) pos= pos_max; - - url_fseek(s->pb, pos, SEEK_SET); - -#if 0 - av_update_cur_dts(s, st, ts); -#endif - return 0; -} - -static int av_seek_frame_generic(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags) -{ - int index; - int64_t ret; - AVStream *st; - AVIndexEntry *ie; - - st = s->streams[stream_index]; - - index = av_index_search_timestamp(st, timestamp, flags); - - if(index < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp) - return -1; - - if(index < 0 || index==st->nb_index_entries-1){ - int i; - AVPacket pkt; - - if(st->nb_index_entries){ - assert(st->index_entries); - ie= &st->index_entries[st->nb_index_entries-1]; - if ((ret = url_fseek(s->pb, ie->pos, SEEK_SET)) < 0) - return ret; - av_update_cur_dts(s, st, ie->timestamp); - }else{ - if ((ret = url_fseek(s->pb, s->data_offset, SEEK_SET)) < 0) - return ret; - } - for(i=0;; i++) { - int ret; - do{ - ret = av_read_frame(s, &pkt); - }while(ret == AVERROR(EAGAIN)); - if(ret<0) - break; - av_free_packet(&pkt); - if(stream_index == pkt.stream_index){ - if((pkt.flags & AV_PKT_FLAG_KEY) && pkt.dts > timestamp) - break; - } - } - index = av_index_search_timestamp(st, timestamp, flags); - } - if (index < 0) - return -1; - - ff_read_frame_flush(s); - if (s->iformat->read_seek){ - if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0) - return 0; - } - ie = &st->index_entries[index]; - if ((ret = url_fseek(s->pb, ie->pos, SEEK_SET)) < 0) - return ret; - av_update_cur_dts(s, st, ie->timestamp); - - return 0; -} - -int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - int ret; - AVStream *st; - - ff_read_frame_flush(s); - - if(flags & AVSEEK_FLAG_BYTE) - return av_seek_frame_byte(s, stream_index, timestamp, flags); - - if(stream_index < 0){ - stream_index= av_find_default_stream_index(s); - if(stream_index < 0) - return -1; - - st= s->streams[stream_index]; - /* timestamp for default must be expressed in AV_TIME_BASE units */ - timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num); - } - - /* first, we try the format specific seek */ - if (s->iformat->read_seek) - ret = s->iformat->read_seek(s, stream_index, timestamp, flags); - else - ret = -1; - if (ret >= 0) { - return 0; - } - - if(s->iformat->read_timestamp) - return av_seek_frame_binary(s, stream_index, timestamp, flags); - else - return av_seek_frame_generic(s, stream_index, timestamp, flags); -} - -int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - if(min_ts > ts || max_ts < ts) - return -1; - - ff_read_frame_flush(s); - - if (s->iformat->read_seek2) - return s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags); - - if(s->iformat->read_timestamp){ - //try to seek via read_timestamp() - } - - //Fallback to old API if new is not implemented but old is - //Note the old has somewat different sematics - if(s->iformat->read_seek || 1) - return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0)); - - // try some generic seek like av_seek_frame_generic() but with new ts semantics -} - -/*******************************************************/ - -/** - * Returns TRUE if the stream has accurate duration in any stream. - * - * @return TRUE if the stream has accurate duration for at least one component. - */ -static int av_has_duration(AVFormatContext *ic) -{ - int i; - AVStream *st; - - for(i = 0;i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->duration != AV_NOPTS_VALUE) - return 1; - } - return 0; -} - -/** - * Estimate the stream timings from the one of each components. - * - * Also computes the global bitrate if possible. - */ -static void av_update_stream_timings(AVFormatContext *ic) -{ - int64_t start_time, start_time1, end_time, end_time1; - int64_t duration, duration1; - int i; - AVStream *st; - - start_time = INT64_MAX; - end_time = INT64_MIN; - duration = INT64_MIN; - for(i = 0;i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) { - start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q); - if (start_time1 < start_time) - start_time = start_time1; - if (st->duration != AV_NOPTS_VALUE) { - end_time1 = start_time1 - + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q); - if (end_time1 > end_time) - end_time = end_time1; - } - } - if (st->duration != AV_NOPTS_VALUE) { - duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q); - if (duration1 > duration) - duration = duration1; - } - } - if (start_time != INT64_MAX) { - ic->start_time = start_time; - if (end_time != INT64_MIN) { - if (end_time - start_time > duration) - duration = end_time - start_time; - } - } - if (duration != INT64_MIN) { - ic->duration = duration; - if (ic->file_size > 0) { - /* compute the bitrate */ - ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE / - (double)ic->duration; - } - } -} - -static void fill_all_stream_timings(AVFormatContext *ic) -{ - int i; - AVStream *st; - - av_update_stream_timings(ic); - for(i = 0;i < ic->nb_streams; i++) { - st = ic->streams[i]; - if (st->start_time == AV_NOPTS_VALUE) { - if(ic->start_time != AV_NOPTS_VALUE) - st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q, st->time_base); - if(ic->duration != AV_NOPTS_VALUE) - st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q, st->time_base); - } - } -} - -static void av_estimate_timings_from_bit_rate(AVFormatContext *ic) -{ - int64_t filesize, duration; - int bit_rate, i; - AVStream *st; - - /* if bit_rate is already set, we believe it */ - if (ic->bit_rate == 0) { - bit_rate = 0; - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - bit_rate += st->codec->bit_rate; - } - ic->bit_rate = bit_rate; - } - - /* if duration is already set, we believe it */ - if (ic->duration == AV_NOPTS_VALUE && - ic->bit_rate != 0 && - ic->file_size != 0) { - filesize = ic->file_size; - if (filesize > 0) { - for(i = 0; i < ic->nb_streams; i++) { - st = ic->streams[i]; - duration= av_rescale(8*filesize, st->time_base.den, ic->bit_rate*(int64_t)st->time_base.num); - if (st->duration == AV_NOPTS_VALUE) - st->duration = duration; - } - } - } -} - -#define DURATION_MAX_READ_SIZE 250000 -#define DURATION_MAX_RETRY 3 - -/* only usable for MPEG-PS streams */ -static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) -{ - AVPacket pkt1, *pkt = &pkt1; - AVStream *st; - int read_size, i, ret; - int64_t end_time, start_time[MAX_STREAMS]; - int64_t filesize, offset, duration; - int retry=0; - - ic->cur_st = NULL; - - /* flush packet queue */ - flush_packet_queue(ic); - - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - if(st->start_time != AV_NOPTS_VALUE){ - start_time[i]= st->start_time; - }else if(st->first_dts != AV_NOPTS_VALUE){ - start_time[i]= st->first_dts; - }else - av_log(st->codec, AV_LOG_WARNING, "start time is not set in av_estimate_timings_from_pts\n"); - - if (st->parser) { - av_parser_close(st->parser); - st->parser= NULL; - av_free_packet(&st->cur_pkt); - } - } - - /* estimate the end time (duration) */ - /* XXX: may need to support wrapping */ - filesize = ic->file_size; - end_time = AV_NOPTS_VALUE; - do{ - offset = filesize - (DURATION_MAX_READ_SIZE<pb, offset, SEEK_SET); - read_size = 0; - for(;;) { - if (read_size >= DURATION_MAX_READ_SIZE<<(FFMAX(retry-1,0))) - break; - - do{ - ret = av_read_packet(ic, pkt); - }while(ret == AVERROR(EAGAIN)); - if (ret != 0) - break; - read_size += pkt->size; - st = ic->streams[pkt->stream_index]; - if (pkt->pts != AV_NOPTS_VALUE && - start_time[pkt->stream_index] != AV_NOPTS_VALUE) { - end_time = pkt->pts; - duration = end_time - start_time[pkt->stream_index]; - if (duration < 0) - duration += 1LL<pts_wrap_bits; - if (duration > 0) { - if (st->duration == AV_NOPTS_VALUE || - st->duration < duration) - st->duration = duration; - } - } - av_free_packet(pkt); - } - }while( end_time==AV_NOPTS_VALUE - && filesize > (DURATION_MAX_READ_SIZE<pb, old_offset, SEEK_SET); - for(i=0; inb_streams; i++){ - st= ic->streams[i]; - st->cur_dts= st->first_dts; - st->last_IP_pts = AV_NOPTS_VALUE; - } -} - -static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset) -{ - int64_t file_size; - - /* get the file size, if possible */ - if (ic->iformat->flags & AVFMT_NOFILE) { - file_size = 0; - } else { - file_size = url_fsize(ic->pb); - if (file_size < 0) - file_size = 0; - } - ic->file_size = file_size; - - if ((!strcmp(ic->iformat->name, "mpeg") || - !strcmp(ic->iformat->name, "mpegts")) && - file_size && !url_is_streamed(ic->pb)) { - /* get accurate estimate from the PTSes */ - av_estimate_timings_from_pts(ic, old_offset); - } else if (av_has_duration(ic)) { - /* at least one component has timings - we use them for all - the components */ - fill_all_stream_timings(ic); - } else { - av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n"); - /* less precise: use bitrate info */ - av_estimate_timings_from_bit_rate(ic); - } - av_update_stream_timings(ic); - -#if 0 - { - int i; - AVStream *st; - for(i = 0;i < ic->nb_streams; i++) { - st = ic->streams[i]; - printf("%d: start_time: %0.3f duration: %0.3f\n", - i, (double)st->start_time / AV_TIME_BASE, - (double)st->duration / AV_TIME_BASE); - } - printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n", - (double)ic->start_time / AV_TIME_BASE, - (double)ic->duration / AV_TIME_BASE, - ic->bit_rate / 1000); - } -#endif -} - -static int has_codec_parameters(AVCodecContext *enc) -{ - int val; - switch(enc->codec_type) { - case AVMEDIA_TYPE_AUDIO: - val = enc->sample_rate && enc->channels && enc->sample_fmt != SAMPLE_FMT_NONE; - if(!enc->frame_size && - (enc->codec_id == CODEC_ID_VORBIS || - enc->codec_id == CODEC_ID_AAC || - enc->codec_id == CODEC_ID_MP1 || - enc->codec_id == CODEC_ID_MP2 || - enc->codec_id == CODEC_ID_MP3 || - enc->codec_id == CODEC_ID_SPEEX)) - return 0; - break; - case AVMEDIA_TYPE_VIDEO: - val = enc->width && enc->pix_fmt != PIX_FMT_NONE; - break; - default: - val = 1; - break; - } - return enc->codec_id != CODEC_ID_NONE && val != 0; -} - -static int try_decode_frame(AVStream *st, AVPacket *avpkt) -{ - int16_t *samples; - AVCodec *codec; - int got_picture, data_size, ret=0; - AVFrame picture; - - if(!st->codec->codec){ - codec = avcodec_find_decoder(st->codec->codec_id); - if (!codec) - return -1; - ret = avcodec_open(st->codec, codec); - if (ret < 0) - return ret; - } - - if(!has_codec_parameters(st->codec)){ - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - avcodec_get_frame_defaults(&picture); - ret = avcodec_decode_video2(st->codec, &picture, - &got_picture, avpkt); - break; - case AVMEDIA_TYPE_AUDIO: - data_size = FFMAX(avpkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE); - samples = av_malloc(data_size); - if (!samples) - goto fail; - ret = avcodec_decode_audio3(st->codec, samples, - &data_size, avpkt); - av_free(samples); - break; - default: - break; - } - } - fail: - return ret; -} - -unsigned int ff_codec_get_tag(const AVCodecTag *tags, int id) -{ - while (tags->id != CODEC_ID_NONE) { - if (tags->id == id) - return tags->tag; - tags++; - } - return 0; -} - -enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag) -{ - int i; - for(i=0; tags[i].id != CODEC_ID_NONE;i++) { - if(tag == tags[i].tag) - return tags[i].id; - } - for(i=0; tags[i].id != CODEC_ID_NONE; i++) { - if( toupper((tag >> 0)&0xFF) == toupper((tags[i].tag >> 0)&0xFF) - && toupper((tag >> 8)&0xFF) == toupper((tags[i].tag >> 8)&0xFF) - && toupper((tag >>16)&0xFF) == toupper((tags[i].tag >>16)&0xFF) - && toupper((tag >>24)&0xFF) == toupper((tags[i].tag >>24)&0xFF)) - return tags[i].id; - } - return CODEC_ID_NONE; -} - -unsigned int av_codec_get_tag(const AVCodecTag * const *tags, enum CodecID id) -{ - int i; - for(i=0; tags && tags[i]; i++){ - int tag= ff_codec_get_tag(tags[i], id); - if(tag) return tag; - } - return 0; -} - -enum CodecID av_codec_get_id(const AVCodecTag * const *tags, unsigned int tag) -{ - int i; - for(i=0; tags && tags[i]; i++){ - enum CodecID id= ff_codec_get_id(tags[i], tag); - if(id!=CODEC_ID_NONE) return id; - } - return CODEC_ID_NONE; -} - -static void compute_chapters_end(AVFormatContext *s) -{ - unsigned int i; - - for (i=0; i+1nb_chapters; i++) - if (s->chapters[i]->end == AV_NOPTS_VALUE) { - assert(s->chapters[i]->start <= s->chapters[i+1]->start); - assert(!av_cmp_q(s->chapters[i]->time_base, s->chapters[i+1]->time_base)); - s->chapters[i]->end = s->chapters[i+1]->start; - } - - if (s->nb_chapters && s->chapters[i]->end == AV_NOPTS_VALUE) { - assert(s->start_time != AV_NOPTS_VALUE); - assert(s->duration > 0); - s->chapters[i]->end = av_rescale_q(s->start_time + s->duration, - AV_TIME_BASE_Q, - s->chapters[i]->time_base); - } -} - -#define MAX_STD_TIMEBASES (60*12+5) -static int get_std_framerate(int i){ - if(i<60*12) return i*1001; - else return ((const int[]){24,30,60,12,15})[i-60*12]*1000*12; -} - -/* - * Is the time base unreliable. - * This is a heuristic to balance between quick acceptance of the values in - * the headers vs. some extra checks. - * Old DivX and Xvid often have nonsense timebases like 1fps or 2fps. - * MPEG-2 commonly misuses field repeat flags to store different framerates. - * And there are "variable" fps files this needs to detect as well. - */ -static int tb_unreliable(AVCodecContext *c){ - if( c->time_base.den >= 101L*c->time_base.num - || c->time_base.den < 5L*c->time_base.num -/* || c->codec_tag == AV_RL32("DIVX") - || c->codec_tag == AV_RL32("XVID")*/ - || c->codec_id == CODEC_ID_MPEG2VIDEO - || c->codec_id == CODEC_ID_H264 - ) - return 1; - return 0; -} - -int av_find_stream_info(AVFormatContext *ic) -{ - int i, count, ret, read_size, j; - AVStream *st; - AVPacket pkt1, *pkt; - int64_t last_dts[MAX_STREAMS]; - int64_t duration_gcd[MAX_STREAMS]={0}; - int duration_count[MAX_STREAMS]={0}; - double (*duration_error)[MAX_STD_TIMEBASES]; - int64_t old_offset = url_ftell(ic->pb); - int64_t codec_info_duration[MAX_STREAMS]={0}; - - duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error)); - if (!duration_error) return AVERROR(ENOMEM); - - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - if (st->codec->codec_id == CODEC_ID_AAC) { - st->codec->sample_rate = 0; - st->codec->frame_size = 0; - st->codec->channels = 0; - } - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ -/* if(!st->time_base.num) - st->time_base= */ - if(!st->codec->time_base.num) - st->codec->time_base= st->time_base; - } - //only for the split stuff - if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE)) { - st->parser = av_parser_init(st->codec->codec_id); - if(st->need_parsing == AVSTREAM_PARSE_HEADERS && st->parser){ - st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } - } - assert(!st->codec->codec); - //try to just open decoders, in case this is enough to get parameters - if(!has_codec_parameters(st->codec)){ - AVCodec *codec = avcodec_find_decoder(st->codec->codec_id); - if (codec) - avcodec_open(st->codec, codec); - } - } - - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - if (!has_codec_parameters(st->codec)) - break; - /* variable fps and no guess at the real fps */ - if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num) - && duration_count[i]<20 && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - break; - if(st->parser && st->parser->parser->split && !st->codec->extradata) - break; - if(st->first_dts == AV_NOPTS_VALUE) - break; - } - if (i == ic->nb_streams) { - /* NOTE: if the format has no header, then we need to read - some packets to get most of the streams, so we cannot - stop here */ - if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) { - /* if we found the info for all the codecs, we can stop */ - ret = count; - av_log(ic, AV_LOG_DEBUG, "All info found\n"); - break; - } - } - /* we did not get all the codec info, but we read too much data */ - if (read_size >= ic->probesize) { - ret = count; - av_log(ic, AV_LOG_DEBUG, "Probe buffer size limit %d reached\n", ic->probesize); - break; - } - - /* NOTE: a new stream can be added there if no header in file - (AVFMTCTX_NOHEADER) */ - ret = av_read_frame_internal(ic, &pkt1); - if(ret == AVERROR(EAGAIN)) - continue; - if (ret < 0) { - /* EOF or error */ - ret = -1; /* we could not have all the codec parameters before EOF */ - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - if (!has_codec_parameters(st->codec)){ - char buf[256]; - avcodec_string(buf, sizeof(buf), st->codec, 0); - av_log(ic, AV_LOG_WARNING, "Could not find codec parameters (%s)\n", buf); - } else { - ret = 0; - } - } - break; - } - - pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end); - if(av_dup_packet(pkt) < 0) { - av_free(duration_error); - return AVERROR(ENOMEM); - } - - read_size += pkt->size; - - st = ic->streams[pkt->stream_index]; - if(st->codec_info_nb_frames>1) { - if (st->time_base.den > 0 && av_rescale_q(codec_info_duration[st->index], st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration){ - av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n"); - break; - } - codec_info_duration[st->index] += pkt->duration; - } - st->codec_info_nb_frames++; - - { - int index= pkt->stream_index; - int64_t last= last_dts[index]; - int64_t duration= pkt->dts - last; - - if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){ - double dur= duration * av_q2d(st->time_base); - -// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) -// av_log(NULL, AV_LOG_ERROR, "%f\n", dur); - if(duration_count[index] < 2) - memset(duration_error[index], 0, sizeof(*duration_error)); - for(i=1; i 3) - duration_gcd[index] = av_gcd(duration_gcd[index], duration); - } - if(last == AV_NOPTS_VALUE || duration_count[index]<=1) - last_dts[pkt->stream_index]= pkt->dts; - } - if(st->parser && st->parser->parser->split && !st->codec->extradata){ - int i= st->parser->parser->split(st->codec, pkt->data, pkt->size); - if(i){ - st->codec->extradata_size= i; - st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size); - memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE); - } - } - - /* if still no information, we try to open the codec and to - decompress the frame. We try to avoid that in most cases as - it takes longer and uses more memory. For MPEG-4, we need to - decompress for QuickTime. */ - if (!has_codec_parameters(st->codec)) - try_decode_frame(st, pkt); - - count++; - } - - // close codecs which were opened in try_decode_frame() - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - if(st->codec->codec) - avcodec_close(st->codec); - } - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - if(st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && codec_info_duration[i]) - av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den, - codec_info_duration[i] *(int64_t)st->time_base.num, 60000); - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample) - st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt); - - // the check for tb_unreliable() is not completely correct, since this is not about handling - // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g. - // ipmovie.c produces. - if (tb_unreliable(st->codec) && duration_count[i] > 15 && duration_gcd[i] > 1 && !st->r_frame_rate.num) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * duration_gcd[i], INT_MAX); - if(duration_count[i] && !st->r_frame_rate.num - && tb_unreliable(st->codec) /*&& - //FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ... - st->time_base.num*duration_sum[i]/duration_count[i]*101LL > st->time_base.den*/){ - int num = 0; - double best_error= 2*av_q2d(st->time_base); - best_error= best_error*best_error*duration_count[i]*1000*12*30; - - for(j=1; jcodec->codec_type == AVMEDIA_TYPE_VIDEO) -// av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error); - if(error < best_error){ - best_error= error; - num = get_std_framerate(j); - } - } - // do not increase frame rate by more than 1 % in order to match a standard rate. - if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate))) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX); - } - - if (!st->r_frame_rate.num){ - if( st->codec->time_base.den * (int64_t)st->time_base.num - <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t)st->time_base.den){ - st->r_frame_rate.num = st->codec->time_base.den; - st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame; - }else{ - st->r_frame_rate.num = st->time_base.den; - st->r_frame_rate.den = st->time_base.num; - } - } - }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if(!st->codec->bits_per_coded_sample) - st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id); - } - } - - av_estimate_timings(ic, old_offset); - - compute_chapters_end(ic); - -#if 0 - /* correct DTS for B-frame streams with no timestamps */ - for(i=0;inb_streams;i++) { - st = ic->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if(b-frames){ - ppktl = &ic->packet_buffer; - while(ppkt1){ - if(ppkt1->stream_index != i) - continue; - if(ppkt1->pkt->dts < 0) - break; - if(ppkt1->pkt->pts != AV_NOPTS_VALUE) - break; - ppkt1->pkt->dts -= delta; - ppkt1= ppkt1->next; - } - if(ppkt1) - continue; - st->cur_dts -= delta; - } - } - } -#endif - - av_free(duration_error); - - return ret; -} - -/*******************************************************/ - -int av_read_play(AVFormatContext *s) -{ - if (s->iformat->read_play) - return s->iformat->read_play(s); - if (s->pb) - return av_url_read_fpause(s->pb, 0); - return AVERROR(ENOSYS); -} - -int av_read_pause(AVFormatContext *s) -{ - if (s->iformat->read_pause) - return s->iformat->read_pause(s); - if (s->pb) - return av_url_read_fpause(s->pb, 1); - return AVERROR(ENOSYS); -} - -void av_close_input_stream(AVFormatContext *s) -{ - int i; - AVStream *st; - - if (s->iformat->read_close) - s->iformat->read_close(s); - for(i=0;inb_streams;i++) { - /* free all data in a stream component */ - st = s->streams[i]; - if (st->parser) { - av_parser_close(st->parser); - av_free_packet(&st->cur_pkt); - } - av_metadata_free(&st->metadata); - av_free(st->index_entries); - av_free(st->codec->extradata); - av_free(st->codec); -#if LIBAVFORMAT_VERSION_INT < (53<<16) - av_free(st->filename); -#endif - av_free(st->priv_data); - av_free(st); - } - for(i=s->nb_programs-1; i>=0; i--) { -#if LIBAVFORMAT_VERSION_INT < (53<<16) - av_freep(&s->programs[i]->provider_name); - av_freep(&s->programs[i]->name); -#endif - av_metadata_free(&s->programs[i]->metadata); - av_freep(&s->programs[i]->stream_index); - av_freep(&s->programs[i]); - } - av_freep(&s->programs); - flush_packet_queue(s); - av_freep(&s->priv_data); - while(s->nb_chapters--) { -#if LIBAVFORMAT_VERSION_INT < (53<<16) - av_free(s->chapters[s->nb_chapters]->title); -#endif - av_metadata_free(&s->chapters[s->nb_chapters]->metadata); - av_free(s->chapters[s->nb_chapters]); - } - av_freep(&s->chapters); - av_metadata_free(&s->metadata); - av_free(s); -} - -void av_close_input_file(AVFormatContext *s) -{ - ByteIOContext *pb = s->iformat->flags & AVFMT_NOFILE ? NULL : s->pb; - av_close_input_stream(s); - if (pb) - url_fclose(pb); -} - -AVStream *av_new_stream(AVFormatContext *s, int id) -{ - AVStream *st; - int i; - - if (s->nb_streams >= MAX_STREAMS) - return NULL; - - st = av_mallocz(sizeof(AVStream)); - if (!st) - return NULL; - - st->codec= avcodec_alloc_context(); - if (s->iformat) { - /* no default bitrate if decoding */ - st->codec->bit_rate = 0; - } - st->index = s->nb_streams; - st->id = id; - st->start_time = AV_NOPTS_VALUE; - st->duration = AV_NOPTS_VALUE; - /* we set the current DTS to 0 so that formats without any timestamps - but durations get some timestamps, formats with some unknown - timestamps have their first few packets buffered and the - timestamps corrected before they are returned to the user */ - st->cur_dts = 0; - st->first_dts = AV_NOPTS_VALUE; - st->probe_packets = MAX_PROBE_PACKETS; - - /* default pts setting is MPEG-like */ - av_set_pts_info(st, 33, 1, 90000); - st->last_IP_pts = AV_NOPTS_VALUE; - for(i=0; ipts_buffer[i]= AV_NOPTS_VALUE; - st->reference_dts = AV_NOPTS_VALUE; - - st->sample_aspect_ratio = (AVRational){0,1}; - - s->streams[s->nb_streams++] = st; - return st; -} - -AVProgram *av_new_program(AVFormatContext *ac, int id) -{ - AVProgram *program=NULL; - int i; - -#ifdef DEBUG_SI - av_log(ac, AV_LOG_DEBUG, "new_program: id=0x%04x\n", id); -#endif - - for(i=0; inb_programs; i++) - if(ac->programs[i]->id == id) - program = ac->programs[i]; - - if(!program){ - program = av_mallocz(sizeof(AVProgram)); - if (!program) - return NULL; - dynarray_add(&ac->programs, &ac->nb_programs, program); - program->discard = AVDISCARD_NONE; - } - program->id = id; - - return program; -} - -AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title) -{ - AVChapter *chapter = NULL; - int i; - - for(i=0; inb_chapters; i++) - if(s->chapters[i]->id == id) - chapter = s->chapters[i]; - - if(!chapter){ - chapter= av_mallocz(sizeof(AVChapter)); - if(!chapter) - return NULL; - dynarray_add(&s->chapters, &s->nb_chapters, chapter); - } -#if LIBAVFORMAT_VERSION_INT < (53<<16) - av_free(chapter->title); -#endif - av_metadata_set2(&chapter->metadata, "title", title, 0); - chapter->id = id; - chapter->time_base= time_base; - chapter->start = start; - chapter->end = end; - - return chapter; -} - -/************************************************************/ -/* output media file */ - -int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) -{ - int ret; - - if (s->oformat->priv_data_size > 0) { - s->priv_data = av_mallocz(s->oformat->priv_data_size); - if (!s->priv_data) - return AVERROR(ENOMEM); - } else - s->priv_data = NULL; - - if (s->oformat->set_parameters) { - ret = s->oformat->set_parameters(s, ap); - if (ret < 0) - return ret; - } - return 0; -} - -int av_write_header(AVFormatContext *s) -{ - int ret, i; - AVStream *st; - - // some sanity checks - if (s->nb_streams == 0) { - av_log(s, AV_LOG_ERROR, "no streams\n"); - return -1; - } - - for(i=0;inb_streams;i++) { - st = s->streams[i]; - - switch (st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if(st->codec->sample_rate<=0){ - av_log(s, AV_LOG_ERROR, "sample rate not set\n"); - return -1; - } - if(!st->codec->block_align) - st->codec->block_align = st->codec->channels * - av_get_bits_per_sample(st->codec->codec_id) >> 3; - break; - case AVMEDIA_TYPE_VIDEO: - if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too? - av_log(s, AV_LOG_ERROR, "time base not set\n"); - return -1; - } - if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){ - av_log(s, AV_LOG_ERROR, "dimensions not set\n"); - return -1; - } - if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){ - av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n"); - return -1; - } - break; - } - - if(s->oformat->codec_tag){ - if(st->codec->codec_tag){ - //FIXME - //check that tag + id is in the table - //if neither is in the table -> OK - //if tag is in the table with another id -> FAIL - //if id is in the table with another tag -> FAIL unless strict < ? - }else - st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id); - } - - if(s->oformat->flags & AVFMT_GLOBALHEADER && - !(st->codec->flags & CODEC_FLAG_GLOBAL_HEADER)) - av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use global headers but container format requires global headers\n", i); - } - - if (!s->priv_data && s->oformat->priv_data_size > 0) { - s->priv_data = av_mallocz(s->oformat->priv_data_size); - if (!s->priv_data) - return AVERROR(ENOMEM); - } - -#if LIBAVFORMAT_VERSION_MAJOR < 53 - ff_metadata_mux_compat(s); -#endif - - /* set muxer identification string */ - if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { - AVMetadata *m; - AVMetadataTag *t; - - if (!(m = av_mallocz(sizeof(AVMetadata)))) - return AVERROR(ENOMEM); - av_metadata_set2(&m, "encoder", LIBAVFORMAT_IDENT, 0); - metadata_conv(&m, s->oformat->metadata_conv, NULL); - if ((t = av_metadata_get(m, "", NULL, AV_METADATA_IGNORE_SUFFIX))) - av_metadata_set2(&s->metadata, t->key, t->value, 0); - av_metadata_free(&m); - } - - if(s->oformat->write_header){ - ret = s->oformat->write_header(s); - if (ret < 0) - return ret; - } - - /* init PTS generation */ - for(i=0;inb_streams;i++) { - int64_t den = AV_NOPTS_VALUE; - st = s->streams[i]; - - switch (st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - den = (int64_t)st->time_base.num * st->codec->sample_rate; - break; - case AVMEDIA_TYPE_VIDEO: - den = (int64_t)st->time_base.num * st->codec->time_base.den; - break; - default: - break; - } - if (den != AV_NOPTS_VALUE) { - if (den <= 0) - return AVERROR_INVALIDDATA; - av_frac_init(&st->pts, 0, 0, den); - } - } - return 0; -} - -//FIXME merge with compute_pkt_fields -static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){ - int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames); - int num, den, frame_size, i; - -// av_log(s, AV_LOG_DEBUG, "av_write_frame: pts:%"PRId64" dts:%"PRId64" cur_dts:%"PRId64" b:%d size:%d st:%d\n", pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index); - -/* if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE) - return -1;*/ - - /* duration field */ - if (pkt->duration == 0) { - compute_frame_duration(&num, &den, st, NULL, pkt); - if (den && num) { - pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num); - } - } - - if(pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay==0) - pkt->pts= pkt->dts; - - //XXX/FIXME this is a temporary hack until all encoders output pts - if((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay){ - pkt->dts= -// pkt->pts= st->cur_dts; - pkt->pts= st->pts.val; - } - - //calculate dts from pts - if(pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY){ - st->pts_buffer[0]= pkt->pts; - for(i=1; ipts_buffer[i] == AV_NOPTS_VALUE; i++) - st->pts_buffer[i]= pkt->pts + (i-delay-1) * pkt->duration; - for(i=0; ipts_buffer[i] > st->pts_buffer[i+1]; i++) - FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]); - - pkt->dts= st->pts_buffer[0]; - } - - if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){ - av_log(s, AV_LOG_ERROR, - "st:%d error, non monotone timestamps %"PRId64" >= %"PRId64"\n", - st->index, st->cur_dts, pkt->dts); - return -1; - } - if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){ - av_log(s, AV_LOG_ERROR, "st:%d error, pts < dts\n", st->index); - return -1; - } - -// av_log(s, AV_LOG_DEBUG, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n", pkt->pts, pkt->dts); - st->cur_dts= pkt->dts; - st->pts.val= pkt->dts; - - /* update pts */ - switch (st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - frame_size = get_audio_frame_size(st->codec, pkt->size); - - /* HACK/FIXME, we skip the initial 0 size packets as they are most - likely equal to the encoder delay, but it would be better if we - had the real timestamps from the encoder */ - if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) { - av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size); - } - break; - case AVMEDIA_TYPE_VIDEO: - av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num); - break; - default: - break; - } - return 0; -} - -int av_write_frame(AVFormatContext *s, AVPacket *pkt) -{ - int ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt); - - if(ret<0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return ret; - - ret= s->oformat->write_packet(s, pkt); - if(!ret) - ret= url_ferror(s->pb); - return ret; -} - -void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, - int (*compare)(AVFormatContext *, AVPacket *, AVPacket *)) -{ - AVPacketList **next_point, *this_pktl; - - this_pktl = av_mallocz(sizeof(AVPacketList)); - this_pktl->pkt= *pkt; - pkt->destruct= NULL; // do not free original but only the copy - av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory - - if(s->streams[pkt->stream_index]->last_in_packet_buffer){ - next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next); - }else - next_point = &s->packet_buffer; - - if(*next_point){ - if(compare(s, &s->packet_buffer_end->pkt, pkt)){ - while(!compare(s, &(*next_point)->pkt, pkt)){ - next_point= &(*next_point)->next; - } - goto next_non_null; - }else{ - next_point = &(s->packet_buffer_end->next); - } - } - assert(!*next_point); - - s->packet_buffer_end= this_pktl; -next_non_null: - - this_pktl->next= *next_point; - - s->streams[pkt->stream_index]->last_in_packet_buffer= - *next_point= this_pktl; -} - -int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt) -{ - AVStream *st = s->streams[ pkt ->stream_index]; - AVStream *st2= s->streams[ next->stream_index]; - int64_t a= st2->time_base.num * (int64_t)st ->time_base.den; - int64_t b= st ->time_base.num * (int64_t)st2->time_base.den; - return av_rescale_rnd(pkt->dts, b, a, AV_ROUND_DOWN) < next->dts; -} - -int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){ - AVPacketList *pktl; - int stream_count=0; - int i; - - if(pkt){ - ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts); - } - - for(i=0; i < s->nb_streams; i++) - stream_count+= !!s->streams[i]->last_in_packet_buffer; - - if(stream_count && (s->nb_streams == stream_count || flush)){ - pktl= s->packet_buffer; - *out= pktl->pkt; - - s->packet_buffer= pktl->next; - if(!s->packet_buffer) - s->packet_buffer_end= NULL; - - if(s->streams[out->stream_index]->last_in_packet_buffer == pktl) - s->streams[out->stream_index]->last_in_packet_buffer= NULL; - av_freep(&pktl); - return 1; - }else{ - av_init_packet(out); - return 0; - } -} - -/** - * Interleaves an AVPacket correctly so it can be muxed. - * @param out the interleaved packet will be output here - * @param in the input packet - * @param flush 1 if no further packets are available as input and all - * remaining packets should be output - * @return 1 if a packet was output, 0 if no packet could be output, - * < 0 if an error occurred - */ -static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){ - if(s->oformat->interleave_packet) - return s->oformat->interleave_packet(s, out, in, flush); - else - return av_interleave_packet_per_dts(s, out, in, flush); -} - -int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){ - AVStream *st= s->streams[ pkt->stream_index]; - - //FIXME/XXX/HACK drop zero sized packets - if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size==0) - return 0; - -//av_log(NULL, AV_LOG_DEBUG, "av_interleaved_write_frame %d %"PRId64" %"PRId64"\n", pkt->size, pkt->dts, pkt->pts); - if(compute_pkt_fields2(s, st, pkt) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return -1; - - if(pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return -1; - - for(;;){ - AVPacket opkt; - int ret= av_interleave_packet(s, &opkt, pkt, 0); - if(ret<=0) //FIXME cleanup needed for ret<0 ? - return ret; - - ret= s->oformat->write_packet(s, &opkt); - - av_free_packet(&opkt); - pkt= NULL; - - if(ret<0) - return ret; - if(url_ferror(s->pb)) - return url_ferror(s->pb); - } -} - -int av_write_trailer(AVFormatContext *s) -{ - int ret, i; - - for(;;){ - AVPacket pkt; - ret= av_interleave_packet(s, &pkt, NULL, 1); - if(ret<0) //FIXME cleanup needed for ret<0 ? - goto fail; - if(!ret) - break; - - ret= s->oformat->write_packet(s, &pkt); - - av_free_packet(&pkt); - - if(ret<0) - goto fail; - if(url_ferror(s->pb)) - goto fail; - } - - if(s->oformat->write_trailer) - ret = s->oformat->write_trailer(s); -fail: - if(ret == 0) - ret=url_ferror(s->pb); - for(i=0;inb_streams;i++) { - av_freep(&s->streams[i]->priv_data); - av_freep(&s->streams[i]->index_entries); - } - av_freep(&s->priv_data); - return ret; -} - -void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx) -{ - int i, j; - AVProgram *program=NULL; - void *tmp; - - if (idx >= ac->nb_streams) { - av_log(ac, AV_LOG_ERROR, "stream index %d is not valid\n", idx); - return; - } - - for(i=0; inb_programs; i++){ - if(ac->programs[i]->id != progid) - continue; - program = ac->programs[i]; - for(j=0; jnb_stream_indexes; j++) - if(program->stream_index[j] == idx) - return; - - tmp = av_realloc(program->stream_index, sizeof(unsigned int)*(program->nb_stream_indexes+1)); - if(!tmp) - return; - program->stream_index = tmp; - program->stream_index[program->nb_stream_indexes++] = idx; - return; - } -} - -static void print_fps(double d, const char *postfix){ - uint64_t v= lrintf(d*100); - if (v% 100 ) av_log(NULL, AV_LOG_INFO, ", %3.2f %s", d, postfix); - else if(v%(100*1000)) av_log(NULL, AV_LOG_INFO, ", %1.0f %s", d, postfix); - else av_log(NULL, AV_LOG_INFO, ", %1.0fk %s", d/1000, postfix); -} - -static void dump_metadata(void *ctx, AVMetadata *m, const char *indent) -{ - if(m && !(m->count == 1 && av_metadata_get(m, "language", NULL, 0))){ - AVMetadataTag *tag=NULL; - - av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent); - while((tag=av_metadata_get(m, "", tag, AV_METADATA_IGNORE_SUFFIX))) { - if(strcmp("language", tag->key)) - av_log(ctx, AV_LOG_INFO, "%s %-16s: %s\n", indent, tag->key, tag->value); - } - } -} - -/* "user interface" functions */ -static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_output) -{ - char buf[256]; - int flags = (is_output ? ic->oformat->flags : ic->iformat->flags); - AVStream *st = ic->streams[i]; - int g = av_gcd(st->time_base.num, st->time_base.den); - AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0); - avcodec_string(buf, sizeof(buf), st->codec, is_output); - av_log(NULL, AV_LOG_INFO, " Stream #%d.%d", index, i); - /* the pid is an important information, so we display it */ - /* XXX: add a generic system */ - if (flags & AVFMT_SHOW_IDS) - av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id); - if (lang) - av_log(NULL, AV_LOG_INFO, "(%s)", lang->value); - av_log(NULL, AV_LOG_DEBUG, ", %d, %d/%d", st->codec_info_nb_frames, st->time_base.num/g, st->time_base.den/g); - av_log(NULL, AV_LOG_INFO, ": %s", buf); - if (st->sample_aspect_ratio.num && // default - av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)) { - AVRational display_aspect_ratio; - av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, - st->codec->width*st->sample_aspect_ratio.num, - st->codec->height*st->sample_aspect_ratio.den, - 1024*1024); - av_log(NULL, AV_LOG_INFO, ", PAR %d:%d DAR %d:%d", - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, - display_aspect_ratio.num, display_aspect_ratio.den); - } - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - if(st->avg_frame_rate.den && st->avg_frame_rate.num) - print_fps(av_q2d(st->avg_frame_rate), "fps"); - if(st->r_frame_rate.den && st->r_frame_rate.num) - print_fps(av_q2d(st->r_frame_rate), "tbr"); - if(st->time_base.den && st->time_base.num) - print_fps(1/av_q2d(st->time_base), "tbn"); - if(st->codec->time_base.den && st->codec->time_base.num) - print_fps(1/av_q2d(st->codec->time_base), "tbc"); - } - av_log(NULL, AV_LOG_INFO, "\n"); - dump_metadata(NULL, st->metadata, " "); -} - -void dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output) -{ - int i; - uint8_t *printed = av_mallocz(ic->nb_streams); - if (ic->nb_streams && !printed) - return; - - av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n", - is_output ? "Output" : "Input", - index, - is_output ? ic->oformat->name : ic->iformat->name, - is_output ? "to" : "from", url); - dump_metadata(NULL, ic->metadata, " "); - if (!is_output) { - av_log(NULL, AV_LOG_INFO, " Duration: "); - if (ic->duration != AV_NOPTS_VALUE) { - int hours, mins, secs, us; - secs = ic->duration / AV_TIME_BASE; - us = ic->duration % AV_TIME_BASE; - mins = secs / 60; - secs %= 60; - hours = mins / 60; - mins %= 60; - av_log(NULL, AV_LOG_INFO, "%02d:%02d:%02d.%02d", hours, mins, secs, - (100 * us) / AV_TIME_BASE); - } else { - av_log(NULL, AV_LOG_INFO, "N/A"); - } - if (ic->start_time != AV_NOPTS_VALUE) { - int secs, us; - av_log(NULL, AV_LOG_INFO, ", start: "); - secs = ic->start_time / AV_TIME_BASE; - us = ic->start_time % AV_TIME_BASE; - av_log(NULL, AV_LOG_INFO, "%d.%06d", - secs, (int)av_rescale(us, 1000000, AV_TIME_BASE)); - } - av_log(NULL, AV_LOG_INFO, ", bitrate: "); - if (ic->bit_rate) { - av_log(NULL, AV_LOG_INFO,"%d kb/s", ic->bit_rate / 1000); - } else { - av_log(NULL, AV_LOG_INFO, "N/A"); - } - av_log(NULL, AV_LOG_INFO, "\n"); - } - for (i = 0; i < ic->nb_chapters; i++) { - AVChapter *ch = ic->chapters[i]; - av_log(NULL, AV_LOG_INFO, " Chapter #%d.%d: ", index, i); - av_log(NULL, AV_LOG_INFO, "start %f, ", ch->start * av_q2d(ch->time_base)); - av_log(NULL, AV_LOG_INFO, "end %f\n", ch->end * av_q2d(ch->time_base)); - - dump_metadata(NULL, ch->metadata, " "); - } - if(ic->nb_programs) { - int j, k, total = 0; - for(j=0; jnb_programs; j++) { - AVMetadataTag *name = av_metadata_get(ic->programs[j]->metadata, - "name", NULL, 0); - av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id, - name ? name->value : ""); - dump_metadata(NULL, ic->programs[j]->metadata, " "); - for(k=0; kprograms[j]->nb_stream_indexes; k++) { - dump_stream_format(ic, ic->programs[j]->stream_index[k], index, is_output); - printed[ic->programs[j]->stream_index[k]] = 1; - } - total += ic->programs[j]->nb_stream_indexes; - } - if (total < ic->nb_streams) - av_log(NULL, AV_LOG_INFO, " No Program\n"); - } - for(i=0;inb_streams;i++) - if (!printed[i]) - dump_stream_format(ic, i, index, is_output); - - av_free(printed); -} - -#if LIBAVFORMAT_VERSION_MAJOR < 53 -int parse_image_size(int *width_ptr, int *height_ptr, const char *str) -{ - return av_parse_video_frame_size(width_ptr, height_ptr, str); -} - -int parse_frame_rate(int *frame_rate_num, int *frame_rate_den, const char *arg) -{ - AVRational frame_rate; - int ret = av_parse_video_frame_rate(&frame_rate, arg); - *frame_rate_num= frame_rate.num; - *frame_rate_den= frame_rate.den; - return ret; -} -#endif - -int64_t av_gettime(void) -{ - struct timeval tv; - gettimeofday(&tv,NULL); - return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; -} - -uint64_t ff_ntp_time(void) -{ - return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US; -} - -int64_t parse_date(const char *datestr, int duration) -{ - const char *p; - int64_t t; - struct tm dt; - int i; - static const char * const date_fmt[] = { - "%Y-%m-%d", - "%Y%m%d", - }; - static const char * const time_fmt[] = { - "%H:%M:%S", - "%H%M%S", - }; - const char *q; - int is_utc, len; - char lastch; - int negative = 0; - -#undef time - time_t now = time(0); - - len = strlen(datestr); - if (len > 0) - lastch = datestr[len - 1]; - else - lastch = '\0'; - is_utc = (lastch == 'z' || lastch == 'Z'); - - memset(&dt, 0, sizeof(dt)); - - p = datestr; - q = NULL; - if (!duration) { - if (!strncasecmp(datestr, "now", len)) - return (int64_t) now * 1000000; - - /* parse the year-month-day part */ - for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) { - q = small_strptime(p, date_fmt[i], &dt); - if (q) { - break; - } - } - - /* if the year-month-day part is missing, then take the - * current year-month-day time */ - if (!q) { - if (is_utc) { - dt = *gmtime(&now); - } else { - dt = *localtime(&now); - } - dt.tm_hour = dt.tm_min = dt.tm_sec = 0; - } else { - p = q; - } - - if (*p == 'T' || *p == 't' || *p == ' ') - p++; - - /* parse the hour-minute-second part */ - for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) { - q = small_strptime(p, time_fmt[i], &dt); - if (q) { - break; - } - } - } else { - /* parse datestr as a duration */ - if (p[0] == '-') { - negative = 1; - ++p; - } - /* parse datestr as HH:MM:SS */ - q = small_strptime(p, time_fmt[0], &dt); - if (!q) { - /* parse datestr as S+ */ - dt.tm_sec = strtol(p, (char **)&q, 10); - if (q == p) - /* the parsing didn't succeed */ - return INT64_MIN; - dt.tm_min = 0; - dt.tm_hour = 0; - } - } - - /* Now we have all the fields that we can get */ - if (!q) { - return INT64_MIN; - } - - if (duration) { - t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; - } else { - dt.tm_isdst = -1; /* unknown */ - if (is_utc) { - t = _mktimegm(&dt); - } else { - t = mktime(&dt); - } - } - - t *= 1000000; - - /* parse the .m... part */ - if (*q == '.') { - int val, n; - q++; - for (val = 0, n = 100000; n >= 1; n /= 10, q++) { - if (!isdigit(*q)) - break; - val += n * (*q - '0'); - } - t += val; - } - return negative ? -t : t; -} - -int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info) -{ - const char *p; - char tag[128], *q; - - p = info; - if (*p == '?') - p++; - for(;;) { - q = tag; - while (*p != '\0' && *p != '=' && *p != '&') { - if ((q - tag) < sizeof(tag) - 1) - *q++ = *p; - p++; - } - *q = '\0'; - q = arg; - if (*p == '=') { - p++; - while (*p != '&' && *p != '\0') { - if ((q - arg) < arg_size - 1) { - if (*p == '+') - *q++ = ' '; - else - *q++ = *p; - } - p++; - } - *q = '\0'; - } - if (!strcmp(tag, tag1)) - return 1; - if (*p != '&') - break; - p++; - } - return 0; -} - -int av_get_frame_filename(char *buf, int buf_size, - const char *path, int number) -{ - const char *p; - char *q, buf1[20], c; - int nd, len, percentd_found; - - q = buf; - p = path; - percentd_found = 0; - for(;;) { - c = *p++; - if (c == '\0') - break; - if (c == '%') { - do { - nd = 0; - while (isdigit(*p)) { - nd = nd * 10 + *p++ - '0'; - } - c = *p++; - } while (isdigit(c)); - - switch(c) { - case '%': - goto addchar; - case 'd': - if (percentd_found) - goto fail; - percentd_found = 1; - snprintf(buf1, sizeof(buf1), "%0*d", nd, number); - len = strlen(buf1); - if ((q - buf + len) > buf_size - 1) - goto fail; - memcpy(q, buf1, len); - q += len; - break; - default: - goto fail; - } - } else { - addchar: - if ((q - buf) < buf_size - 1) - *q++ = c; - } - } - if (!percentd_found) - goto fail; - *q = '\0'; - return 0; - fail: - *q = '\0'; - return -1; -} - -static void hex_dump_internal(void *avcl, FILE *f, int level, uint8_t *buf, int size) -{ - int len, i, j, c; -#undef fprintf -#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0) - - for(i=0;i 16) - len = 16; - PRINT("%08x ", i); - for(j=0;j<16;j++) { - if (j < len) - PRINT(" %02x", buf[i+j]); - else - PRINT(" "); - } - PRINT(" "); - for(j=0;j '~') - c = '.'; - PRINT("%c", c); - } - PRINT("\n"); - } -#undef PRINT -} - -void av_hex_dump(FILE *f, uint8_t *buf, int size) -{ - hex_dump_internal(NULL, f, 0, buf, size); -} - -void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size) -{ - hex_dump_internal(avcl, NULL, level, buf, size); -} - - //FIXME needs to know the time_base -static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload) -{ -#undef fprintf -#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0) - PRINT("stream #%d:\n", pkt->stream_index); - PRINT(" keyframe=%d\n", ((pkt->flags & AV_PKT_FLAG_KEY) != 0)); - PRINT(" duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE); - /* DTS is _always_ valid after av_read_frame() */ - PRINT(" dts="); - if (pkt->dts == AV_NOPTS_VALUE) - PRINT("N/A"); - else - PRINT("%0.3f", (double)pkt->dts / AV_TIME_BASE); - /* PTS may not be known if B-frames are present. */ - PRINT(" pts="); - if (pkt->pts == AV_NOPTS_VALUE) - PRINT("N/A"); - else - PRINT("%0.3f", (double)pkt->pts / AV_TIME_BASE); - PRINT("\n"); - PRINT(" size=%d\n", pkt->size); -#undef PRINT - if (dump_payload) - av_hex_dump(f, pkt->data, pkt->size); -} - -void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload) -{ - pkt_dump_internal(NULL, f, 0, pkt, dump_payload); -} - -void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload) -{ - pkt_dump_internal(avcl, NULL, level, pkt, dump_payload); -} - -void ff_url_split(char *proto, int proto_size, - char *authorization, int authorization_size, - char *hostname, int hostname_size, - int *port_ptr, - char *path, int path_size, - const char *url) -{ - const char *p, *ls, *at, *col, *brk; - - if (port_ptr) *port_ptr = -1; - if (proto_size > 0) proto[0] = 0; - if (authorization_size > 0) authorization[0] = 0; - if (hostname_size > 0) hostname[0] = 0; - if (path_size > 0) path[0] = 0; - - /* parse protocol */ - if ((p = strchr(url, ':'))) { - av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url)); - p++; /* skip ':' */ - if (*p == '/') p++; - if (*p == '/') p++; - } else { - /* no protocol means plain filename */ - av_strlcpy(path, url, path_size); - return; - } - - /* separate path from hostname */ - ls = strchr(p, '/'); - if(!ls) - ls = strchr(p, '?'); - if(ls) - av_strlcpy(path, ls, path_size); - else - ls = &p[strlen(p)]; // XXX - - /* the rest is hostname, use that to parse auth/port */ - if (ls != p) { - /* authorization (user[:pass]@hostname) */ - if ((at = strchr(p, '@')) && at < ls) { - av_strlcpy(authorization, p, - FFMIN(authorization_size, at + 1 - p)); - p = at + 1; /* skip '@' */ - } - - if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) { - /* [host]:port */ - av_strlcpy(hostname, p + 1, - FFMIN(hostname_size, brk - p)); - if (brk[1] == ':' && port_ptr) - *port_ptr = atoi(brk + 2); - } else if ((col = strchr(p, ':')) && col < ls) { - av_strlcpy(hostname, p, - FFMIN(col + 1 - p, hostname_size)); - if (port_ptr) *port_ptr = atoi(col + 1); - } else - av_strlcpy(hostname, p, - FFMIN(ls + 1 - p, hostname_size)); - } -} - -char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase) -{ - int i; - static const char hex_table_uc[16] = { '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'A', 'B', - 'C', 'D', 'E', 'F' }; - static const char hex_table_lc[16] = { '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' }; - const char *hex_table = lowercase ? hex_table_lc : hex_table_uc; - - for(i = 0; i < s; i++) { - buff[i * 2] = hex_table[src[i] >> 4]; - buff[i * 2 + 1] = hex_table[src[i] & 0xF]; - } - - return buff; -} - -void av_set_pts_info(AVStream *s, int pts_wrap_bits, - unsigned int pts_num, unsigned int pts_den) -{ - s->pts_wrap_bits = pts_wrap_bits; - - if(av_reduce(&s->time_base.num, &s->time_base.den, pts_num, pts_den, INT_MAX)){ - if(s->time_base.num != pts_num) - av_log(NULL, AV_LOG_DEBUG, "st:%d removing common factor %d from timebase\n", s->index, pts_num/s->time_base.num); - }else - av_log(NULL, AV_LOG_WARNING, "st:%d has too large timebase, reducing\n", s->index); - - if(!s->time_base.num || !s->time_base.den) - s->time_base.num= s->time_base.den= 0; -} - -int ff_url_join(char *str, int size, const char *proto, - const char *authorization, const char *hostname, - int port, const char *fmt, ...) -{ -#if CONFIG_NETWORK - struct addrinfo hints, *ai; -#endif - - str[0] = '\0'; - if (proto) - av_strlcatf(str, size, "%s://", proto); - if (authorization) - av_strlcatf(str, size, "%s@", authorization); -#if CONFIG_NETWORK && defined(AF_INET6) - /* Determine if hostname is a numerical IPv6 address, - * properly escape it within [] in that case. */ - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_NUMERICHOST; - if (!getaddrinfo(hostname, NULL, &hints, &ai)) { - if (ai->ai_family == AF_INET6) { - av_strlcat(str, "[", size); - av_strlcat(str, hostname, size); - av_strlcat(str, "]", size); - } else { - av_strlcat(str, hostname, size); - } - freeaddrinfo(ai); - } else -#endif - /* Not an IPv6 address, just output the plain string. */ - av_strlcat(str, hostname, size); - - if (port >= 0) - av_strlcatf(str, size, ":%d", port); - if (fmt) { - va_list vl; - int len = strlen(str); - - va_start(vl, fmt); - vsnprintf(str + len, size > len ? size - len : 0, fmt, vl); - va_end(vl); - } - return strlen(str); -} diff --git a/tizen/distrib/ffmpeg/libavformat/vc1test.c b/tizen/distrib/ffmpeg/libavformat/vc1test.c deleted file mode 100644 index 7a006f2..0000000 --- a/tizen/distrib/ffmpeg/libavformat/vc1test.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * VC1 Test Bitstreams Format Demuxer - * Copyright (c) 2006, 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * VC1 test bitstream file demuxer - * by Konstantin Shishkov - * Format specified in SMPTE standard 421 Annex L - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define VC1_EXTRADATA_SIZE 4 - -static int vc1t_probe(AVProbeData *p) -{ - if (p->buf_size < 24) - return 0; - if (p->buf[3] != 0xC5 || AV_RL32(&p->buf[4]) != 4 || AV_RL32(&p->buf[20]) != 0xC) - return 0; - - return AVPROBE_SCORE_MAX/2; -} - -static int vc1t_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - AVStream *st; - int frames; - uint32_t fps; - - frames = get_le24(pb); - if(get_byte(pb) != 0xC5 || get_le32(pb) != 4) - return -1; - - /* init video codec */ - st = av_new_stream(s, 0); - if (!st) - return -1; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_WMV3; - - st->codec->extradata = av_malloc(VC1_EXTRADATA_SIZE); - st->codec->extradata_size = VC1_EXTRADATA_SIZE; - get_buffer(pb, st->codec->extradata, VC1_EXTRADATA_SIZE); - st->codec->height = get_le32(pb); - st->codec->width = get_le32(pb); - if(get_le32(pb) != 0xC) - return -1; - url_fskip(pb, 8); - fps = get_le32(pb); - if(fps == 0xFFFFFFFF) - av_set_pts_info(st, 32, 1, 1000); - else{ - if (!fps) { - av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n"); - fps = 1; - } - av_set_pts_info(st, 24, 1, fps); - st->duration = frames; - } - - return 0; -} - -static int vc1t_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - int frame_size; - int keyframe = 0; - uint32_t pts; - - if(url_feof(pb)) - return AVERROR(EIO); - - frame_size = get_le24(pb); - if(get_byte(pb) & 0x80) - keyframe = 1; - pts = get_le32(pb); - if(av_get_packet(pb, pkt, frame_size) < 0) - return AVERROR(EIO); - if(s->streams[0]->time_base.den == 1000) - pkt->pts = pts; - pkt->flags |= keyframe ? AV_PKT_FLAG_KEY : 0; - pkt->pos -= 8; - - return pkt->size; -} - -AVInputFormat vc1t_demuxer = { - "vc1test", - NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"), - 0, - vc1t_probe, - vc1t_read_header, - vc1t_read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/vc1testenc.c b/tizen/distrib/ffmpeg/libavformat/vc1testenc.c deleted file mode 100644 index b4b1e02..0000000 --- a/tizen/distrib/ffmpeg/libavformat/vc1testenc.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * VC-1 test bitstreams format muxer. - * Copyright (c) 2008 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" - -typedef struct RCVContext { - int frames; -} RCVContext; - -static int vc1test_write_header(AVFormatContext *s) -{ - AVCodecContext *avc = s->streams[0]->codec; - ByteIOContext *pb = s->pb; - - if (avc->codec_id != CODEC_ID_WMV3) { - av_log(s, AV_LOG_ERROR, "Only WMV3 is accepted!\n"); - return -1; - } - put_le24(pb, 0); //frames count will be here - put_byte(pb, 0xC5); - put_le32(pb, 4); - put_buffer(pb, avc->extradata, 4); - put_le32(pb, avc->height); - put_le32(pb, avc->width); - put_le32(pb, 0xC); - put_le24(pb, 0); // hrd_buffer - put_byte(pb, 0x80); // level|cbr|res1 - put_le32(pb, 0); // hrd_rate - if (s->streams[0]->r_frame_rate.den && s->streams[0]->r_frame_rate.num == 1) - put_le32(pb, s->streams[0]->r_frame_rate.den); - else - put_le32(pb, 0xFFFFFFFF); //variable framerate - - return 0; -} - -static int vc1test_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - RCVContext *ctx = s->priv_data; - ByteIOContext *pb = s->pb; - - if (!pkt->size) - return 0; - put_le32(pb, pkt->size | ((pkt->flags & AV_PKT_FLAG_KEY) ? 0x80000000 : 0)); - put_le32(pb, pkt->pts); - put_buffer(pb, pkt->data, pkt->size); - put_flush_packet(pb); - ctx->frames++; - - return 0; -} - -static int vc1test_write_trailer(AVFormatContext *s) -{ - RCVContext *ctx = s->priv_data; - ByteIOContext *pb = s->pb; - - if (!url_is_streamed(s->pb)) { - url_fseek(pb, 0, SEEK_SET); - put_le24(pb, ctx->frames); - put_flush_packet(pb); - } - return 0; -} - -AVOutputFormat vc1t_muxer = { - "rcv", - NULL_IF_CONFIG_SMALL("VC-1 test bitstream"), - "", - "rcv", - sizeof(RCVContext), - CODEC_ID_NONE, - CODEC_ID_WMV3, - vc1test_write_header, - vc1test_write_packet, - vc1test_write_trailer, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/voc.c b/tizen/distrib/ffmpeg/libavformat/voc.c deleted file mode 100644 index eed8db8..0000000 --- a/tizen/distrib/ffmpeg/libavformat/voc.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Creative Voice File common data. - * Copyright (c) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "voc.h" - -const unsigned char ff_voc_magic[21] = "Creative Voice File\x1A"; - -const AVCodecTag ff_voc_codec_tags[] = { - {CODEC_ID_PCM_U8, 0x00}, - {CODEC_ID_ADPCM_SBPRO_4, 0x01}, - {CODEC_ID_ADPCM_SBPRO_3, 0x02}, - {CODEC_ID_ADPCM_SBPRO_2, 0x03}, - {CODEC_ID_PCM_S16LE, 0x04}, - {CODEC_ID_PCM_ALAW, 0x06}, - {CODEC_ID_PCM_MULAW, 0x07}, - {CODEC_ID_ADPCM_CT, 0x0200}, - {CODEC_ID_NONE, 0}, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/voc.h b/tizen/distrib/ffmpeg/libavformat/voc.h deleted file mode 100644 index 3f995ad..0000000 --- a/tizen/distrib/ffmpeg/libavformat/voc.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Creative Voice File demuxer. - * Copyright (c) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_VOC_H -#define AVFORMAT_VOC_H - -#include "avformat.h" -#include "riff.h" /* for CodecTag */ - -typedef struct voc_dec_context { - int64_t remaining_size; -} VocDecContext; - -typedef enum voc_type { - VOC_TYPE_EOF = 0x00, - VOC_TYPE_VOICE_DATA = 0x01, - VOC_TYPE_VOICE_DATA_CONT = 0x02, - VOC_TYPE_SILENCE = 0x03, - VOC_TYPE_MARKER = 0x04, - VOC_TYPE_ASCII = 0x05, - VOC_TYPE_REPETITION_START = 0x06, - VOC_TYPE_REPETITION_END = 0x07, - VOC_TYPE_EXTENDED = 0x08, - VOC_TYPE_NEW_VOICE_DATA = 0x09, -} VocType; - -extern const unsigned char ff_voc_magic[21]; -extern const AVCodecTag ff_voc_codec_tags[]; - -int voc_get_packet(AVFormatContext *s, AVPacket *pkt, - AVStream *st, int max_size); - -#endif /* AVFORMAT_VOC_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/vocdec.c b/tizen/distrib/ffmpeg/libavformat/vocdec.c deleted file mode 100644 index 13d48f7..0000000 --- a/tizen/distrib/ffmpeg/libavformat/vocdec.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Creative Voice File demuxer. - * Copyright (c) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "voc.h" - - -static int voc_probe(AVProbeData *p) -{ - int version, check; - - if (memcmp(p->buf, ff_voc_magic, sizeof(ff_voc_magic) - 1)) - return 0; - version = AV_RL16(p->buf + 22); - check = AV_RL16(p->buf + 24); - if (~version + 0x1234 != check) - return 10; - - return AVPROBE_SCORE_MAX; -} - -static int voc_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - VocDecContext *voc = s->priv_data; - ByteIOContext *pb = s->pb; - int header_size; - AVStream *st; - - url_fskip(pb, 20); - header_size = get_le16(pb) - 22; - if (header_size != 4) { - av_log(s, AV_LOG_ERROR, "unknown header size: %d\n", header_size); - return AVERROR(ENOSYS); - } - url_fskip(pb, header_size); - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - voc->remaining_size = 0; - return 0; -} - -int -voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) -{ - VocDecContext *voc = s->priv_data; - AVCodecContext *dec = st->codec; - ByteIOContext *pb = s->pb; - VocType type; - int size; - int sample_rate = 0; - int channels = 1; - - while (!voc->remaining_size) { - type = get_byte(pb); - if (type == VOC_TYPE_EOF) - return AVERROR(EIO); - voc->remaining_size = get_le24(pb); - if (!voc->remaining_size) { - if (url_is_streamed(s->pb)) - return AVERROR(EIO); - voc->remaining_size = url_fsize(pb) - url_ftell(pb); - } - max_size -= 4; - - switch (type) { - case VOC_TYPE_VOICE_DATA: - dec->sample_rate = 1000000 / (256 - get_byte(pb)); - if (sample_rate) - dec->sample_rate = sample_rate; - dec->channels = channels; - dec->codec_id = ff_codec_get_id(ff_voc_codec_tags, get_byte(pb)); - dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); - voc->remaining_size -= 2; - max_size -= 2; - channels = 1; - break; - - case VOC_TYPE_VOICE_DATA_CONT: - break; - - case VOC_TYPE_EXTENDED: - sample_rate = get_le16(pb); - get_byte(pb); - channels = get_byte(pb) + 1; - sample_rate = 256000000 / (channels * (65536 - sample_rate)); - voc->remaining_size = 0; - max_size -= 4; - break; - - case VOC_TYPE_NEW_VOICE_DATA: - dec->sample_rate = get_le32(pb); - dec->bits_per_coded_sample = get_byte(pb); - dec->channels = get_byte(pb); - dec->codec_id = ff_codec_get_id(ff_voc_codec_tags, get_le16(pb)); - url_fskip(pb, 4); - voc->remaining_size -= 12; - max_size -= 12; - break; - - default: - url_fskip(pb, voc->remaining_size); - max_size -= voc->remaining_size; - voc->remaining_size = 0; - break; - } - } - - dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample; - - if (max_size <= 0) - max_size = 2048; - size = FFMIN(voc->remaining_size, max_size); - voc->remaining_size -= size; - return av_get_packet(pb, pkt, size); -} - -static int voc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - return voc_get_packet(s, pkt, s->streams[0], 0); -} - -AVInputFormat voc_demuxer = { - "voc", - NULL_IF_CONFIG_SMALL("Creative Voice file format"), - sizeof(VocDecContext), - voc_probe, - voc_read_header, - voc_read_packet, - .codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0}, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/vocenc.c b/tizen/distrib/ffmpeg/libavformat/vocenc.c deleted file mode 100644 index f127c7e..0000000 --- a/tizen/distrib/ffmpeg/libavformat/vocenc.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Creative Voice File muxer. - * Copyright (c) 2006 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "voc.h" - - -typedef struct voc_enc_context { - int param_written; -} VocEncContext; - -static int voc_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - const int header_size = 26; - const int version = 0x0114; - - if (s->nb_streams != 1 - || s->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO) - return AVERROR_PATCHWELCOME; - - put_buffer(pb, ff_voc_magic, sizeof(ff_voc_magic) - 1); - put_le16(pb, header_size); - put_le16(pb, version); - put_le16(pb, ~version + 0x1234); - - return 0; -} - -static int voc_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - VocEncContext *voc = s->priv_data; - AVCodecContext *enc = s->streams[0]->codec; - ByteIOContext *pb = s->pb; - - if (!voc->param_written) { - if (enc->codec_tag > 0xFF) { - put_byte(pb, VOC_TYPE_NEW_VOICE_DATA); - put_le24(pb, pkt->size + 12); - put_le32(pb, enc->sample_rate); - put_byte(pb, enc->bits_per_coded_sample); - put_byte(pb, enc->channels); - put_le16(pb, enc->codec_tag); - put_le32(pb, 0); - } else { - if (s->streams[0]->codec->channels > 1) { - put_byte(pb, VOC_TYPE_EXTENDED); - put_le24(pb, 4); - put_le16(pb, 65536-256000000/(enc->sample_rate*enc->channels)); - put_byte(pb, enc->codec_tag); - put_byte(pb, enc->channels - 1); - } - put_byte(pb, VOC_TYPE_VOICE_DATA); - put_le24(pb, pkt->size + 2); - put_byte(pb, 256 - 1000000 / enc->sample_rate); - put_byte(pb, enc->codec_tag); - } - voc->param_written = 1; - } else { - put_byte(pb, VOC_TYPE_VOICE_DATA_CONT); - put_le24(pb, pkt->size); - } - - put_buffer(pb, pkt->data, pkt->size); - return 0; -} - -static int voc_write_trailer(AVFormatContext *s) -{ - put_byte(s->pb, 0); - return 0; -} - -AVOutputFormat voc_muxer = { - "voc", - NULL_IF_CONFIG_SMALL("Creative Voice file format"), - "audio/x-voc", - "voc", - sizeof(VocEncContext), - CODEC_ID_PCM_U8, - CODEC_ID_NONE, - voc_write_header, - voc_write_packet, - voc_write_trailer, - .codec_tag=(const AVCodecTag* const []){ff_voc_codec_tags, 0}, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/vorbiscomment.c b/tizen/distrib/ffmpeg/libavformat/vorbiscomment.c deleted file mode 100644 index d23c66d..0000000 --- a/tizen/distrib/ffmpeg/libavformat/vorbiscomment.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * VorbisComment writer - * Copyright (c) 2009 James Darnley - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "metadata.h" -#include "vorbiscomment.h" -#include "libavcodec/bytestream.h" - -/** - * VorbisComment metadata conversion mapping. - * from Ogg Vorbis I format specification: comment field and header specification - * http://xiph.org/vorbis/doc/v-comment.html - */ -const AVMetadataConv ff_vorbiscomment_metadata_conv[] = { - { "ALBUMARTIST", "album_artist"}, - { "TRACKNUMBER", "track" }, - { 0 } -}; - -int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string, - unsigned *count) -{ - int len = 8; - len += strlen(vendor_string); - *count = 0; - if (m) { - AVMetadataTag *tag = NULL; - while ( (tag = av_metadata_get(m, "", tag, AV_METADATA_IGNORE_SUFFIX) ) ) { - len += 4 +strlen(tag->key) + 1 + strlen(tag->value); - (*count)++; - } - } - return len; -} - -int ff_vorbiscomment_write(uint8_t **p, AVMetadata *m, - const char *vendor_string, const unsigned count) -{ - bytestream_put_le32(p, strlen(vendor_string)); - bytestream_put_buffer(p, vendor_string, strlen(vendor_string)); - if (m) { - AVMetadataTag *tag = NULL; - bytestream_put_le32(p, count); - while ( (tag = av_metadata_get(m, "", tag, AV_METADATA_IGNORE_SUFFIX) ) ) { - unsigned int len1 = strlen(tag->key); - unsigned int len2 = strlen(tag->value); - bytestream_put_le32(p, len1+1+len2); - bytestream_put_buffer(p, tag->key, len1); - bytestream_put_byte(p, '='); - bytestream_put_buffer(p, tag->value, len2); - } - } else - bytestream_put_le32(p, 0); - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavformat/vorbiscomment.h b/tizen/distrib/ffmpeg/libavformat/vorbiscomment.h deleted file mode 100644 index 714f1f2..0000000 --- a/tizen/distrib/ffmpeg/libavformat/vorbiscomment.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * VorbisComment writer - * Copyright (c) 2009 James Darnley - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFORMAT_VORBISCOMMENT_H -#define AVFORMAT_VORBISCOMMENT_H - -#include "avformat.h" -#include "metadata.h" - -/** - * Calculates the length in bytes of a VorbisComment. This is the minimum - * size required by ff_vorbiscomment_write(). - * - * @param m The metadata structure to be parsed. For no metadata, set to NULL. - * @param vendor_string The vendor string to be added into the VorbisComment. - * For no string, set to an empty string. - * @param count Pointer to store the number of tags in m because m->count is "not allowed" - * @return The length in bytes. - */ -int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string, - unsigned *count); - -/** - * Writes a VorbisComment into a buffer. The buffer, p, must have enough - * data to hold the whole VorbisComment. The minimum size required can be - * obtained by passing the same AVMetadata and vendor_string to - * ff_vorbiscomment_length() - * - * @param p The buffer in which to write. - * @param m The metadata struct to write. - * @param vendor_string The vendor string to write. - * @param count The number of tags in m because m->count is "not allowed" - */ -int ff_vorbiscomment_write(uint8_t **p, AVMetadata *m, - const char *vendor_string, const unsigned count); - -extern const AVMetadataConv ff_vorbiscomment_metadata_conv[]; - -#endif /* AVFORMAT_VORBISCOMMENT_H */ diff --git a/tizen/distrib/ffmpeg/libavformat/vqf.c b/tizen/distrib/ffmpeg/libavformat/vqf.c deleted file mode 100644 index b0ec020..0000000 --- a/tizen/distrib/ffmpeg/libavformat/vqf.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * VQF demuxer - * Copyright (c) 2009 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "libavutil/intreadwrite.h" - -typedef struct VqfContext { - int frame_bit_len; - uint8_t last_frame_bits; - int remaining_bits; -} VqfContext; - -static int vqf_probe(AVProbeData *probe_packet) -{ - if (AV_RL32(probe_packet->buf) != MKTAG('T','W','I','N')) - return 0; - - if (!memcmp(probe_packet->buf + 4, "97012000", 8)) - return AVPROBE_SCORE_MAX; - - if (!memcmp(probe_packet->buf + 4, "00052200", 8)) - return AVPROBE_SCORE_MAX; - - return AVPROBE_SCORE_MAX/2; -} - -static void add_metadata(AVFormatContext *s, const char *tag, - unsigned int tag_len, unsigned int remaining) -{ - int len = FFMIN(tag_len, remaining); - char *buf; - - if (len == UINT_MAX) - return; - - buf = av_malloc(len+1); - if (!buf) - return; - get_buffer(s->pb, buf, len); - buf[len] = 0; - av_metadata_set2(&s->metadata, tag, buf, AV_METADATA_DONT_STRDUP_VAL); -} - -static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - VqfContext *c = s->priv_data; - AVStream *st = av_new_stream(s, 0); - int chunk_tag; - int rate_flag = -1; - int header_size; - int read_bitrate = 0; - int size; - - if (!st) - return AVERROR(ENOMEM); - - url_fskip(s->pb, 12); - - header_size = get_be32(s->pb); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_TWINVQ; - st->start_time = 0; - - do { - int len; - chunk_tag = get_le32(s->pb); - - if (chunk_tag == MKTAG('D','A','T','A')) - break; - - len = get_be32(s->pb); - - if ((unsigned) len > INT_MAX/2) { - av_log(s, AV_LOG_ERROR, "Malformed header\n"); - return -1; - } - - header_size -= 8; - - switch(chunk_tag){ - case MKTAG('C','O','M','M'): - st->codec->channels = get_be32(s->pb) + 1; - read_bitrate = get_be32(s->pb); - rate_flag = get_be32(s->pb); - url_fskip(s->pb, len-12); - - st->codec->bit_rate = read_bitrate*1000; - st->codec->bits_per_coded_sample = 16; - break; - case MKTAG('N','A','M','E'): - add_metadata(s, "title" , len, header_size); - break; - case MKTAG('(','c',')',' '): - add_metadata(s, "copyright", len, header_size); - break; - case MKTAG('A','U','T','H'): - add_metadata(s, "author" , len, header_size); - break; - case MKTAG('A','L','B','M'): - add_metadata(s, "album" , len, header_size); - break; - case MKTAG('T','R','C','K'): - add_metadata(s, "track" , len, header_size); - break; - case MKTAG('C','O','M','T'): - add_metadata(s, "comment" , len, header_size); - break; - case MKTAG('F','I','L','E'): - add_metadata(s, "filename" , len, header_size); - break; - case MKTAG('D','S','I','Z'): - add_metadata(s, "size" , len, header_size); - break; - case MKTAG('D','A','T','E'): - add_metadata(s, "date" , len, header_size); - break; - case MKTAG('G','E','N','R'): - add_metadata(s, "genre" , len, header_size); - break; - default: - av_log(s, AV_LOG_ERROR, "Unknown chunk: %c%c%c%c\n", - ((char*)&chunk_tag)[0], ((char*)&chunk_tag)[1], - ((char*)&chunk_tag)[2], ((char*)&chunk_tag)[3]); - url_fskip(s->pb, FFMIN(len, header_size)); - break; - } - - header_size -= len; - - } while (header_size >= 0); - - switch (rate_flag) { - case -1: - av_log(s, AV_LOG_ERROR, "COMM tag not found!\n"); - return -1; - case 44: - st->codec->sample_rate = 44100; - break; - case 22: - st->codec->sample_rate = 22050; - break; - case 11: - st->codec->sample_rate = 11025; - break; - default: - st->codec->sample_rate = rate_flag*1000; - break; - } - - switch (((st->codec->sample_rate/1000) << 8) + - read_bitrate/st->codec->channels) { - case (11<<8) + 8 : - case (8 <<8) + 8 : - case (11<<8) + 10: - case (22<<8) + 32: - size = 512; - break; - case (16<<8) + 16: - case (22<<8) + 20: - case (22<<8) + 24: - size = 1024; - break; - case (44<<8) + 40: - case (44<<8) + 48: - size = 2048; - break; - default: - av_log(s, AV_LOG_ERROR, "Mode not suported: %d Hz, %d kb/s.\n", - st->codec->sample_rate, st->codec->bit_rate); - return -1; - } - c->frame_bit_len = st->codec->bit_rate*size/st->codec->sample_rate; - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -static int vqf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - VqfContext *c = s->priv_data; - int ret; - int size = (c->frame_bit_len - c->remaining_bits + 7)>>3; - - pkt->pos = url_ftell(s->pb); - pkt->stream_index = 0; - - if (av_new_packet(pkt, size+2) < 0) - return AVERROR(EIO); - - pkt->data[0] = 8 - c->remaining_bits; // Number of bits to skip - pkt->data[1] = c->last_frame_bits; - ret = get_buffer(s->pb, pkt->data+2, size); - - if (ret<=0) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - c->last_frame_bits = pkt->data[size+1]; - c->remaining_bits = (size << 3) - c->frame_bit_len + c->remaining_bits; - - return size+2; -} - -static int vqf_read_seek(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags) -{ - VqfContext *c = s->priv_data; - AVStream *st; - int ret; - int64_t pos; - - st = s->streams[stream_index]; - pos = av_rescale_rnd(timestamp * st->codec->bit_rate, - st->time_base.num, - st->time_base.den * (int64_t)c->frame_bit_len, - (flags & AVSEEK_FLAG_BACKWARD) ? - AV_ROUND_DOWN : AV_ROUND_UP); - pos *= c->frame_bit_len; - - st->cur_dts = av_rescale(pos, st->time_base.den, - st->codec->bit_rate * (int64_t)st->time_base.num); - - if ((ret = url_fseek(s->pb, ((pos-7) >> 3) + s->data_offset, SEEK_SET)) < 0) - return ret; - - c->remaining_bits = -7 - ((pos-7)&7); - return 0; -} - -AVInputFormat vqf_demuxer = { - "vqf", - NULL_IF_CONFIG_SMALL("Nippon Telegraph and Telephone Corporation (NTT) TwinVQ"), - sizeof(VqfContext), - vqf_probe, - vqf_read_header, - vqf_read_packet, - NULL, - vqf_read_seek, - .extensions = "vqf", -}; diff --git a/tizen/distrib/ffmpeg/libavformat/wav.c b/tizen/distrib/ffmpeg/libavformat/wav.c deleted file mode 100644 index da08558..0000000 --- a/tizen/distrib/ffmpeg/libavformat/wav.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * WAV muxer and demuxer - * Copyright (c) 2001, 2002 Fabrice Bellard - * - * Sony Wave64 demuxer - * RF64 demuxer - * Copyright (c) 2009 Daniel Verkamp - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "raw.h" -#include "riff.h" - -typedef struct { - int64_t data; - int64_t data_end; - int64_t minpts; - int64_t maxpts; - int last_duration; - int w64; -} WAVContext; - -#if CONFIG_WAV_MUXER -static int wav_write_header(AVFormatContext *s) -{ - WAVContext *wav = s->priv_data; - ByteIOContext *pb = s->pb; - int64_t fmt, fact; - - put_tag(pb, "RIFF"); - put_le32(pb, 0); /* file length */ - put_tag(pb, "WAVE"); - - /* format header */ - fmt = ff_start_tag(pb, "fmt "); - if (ff_put_wav_header(pb, s->streams[0]->codec) < 0) { - av_log(s, AV_LOG_ERROR, "%s codec not supported in WAVE format\n", - s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE"); - av_free(wav); - return -1; - } - ff_end_tag(pb, fmt); - - if (s->streams[0]->codec->codec_tag != 0x01 /* hence for all other than PCM */ - && !url_is_streamed(s->pb)) { - fact = ff_start_tag(pb, "fact"); - put_le32(pb, 0); - ff_end_tag(pb, fact); - } - - av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate); - wav->maxpts = wav->last_duration = 0; - wav->minpts = INT64_MAX; - - /* data header */ - wav->data = ff_start_tag(pb, "data"); - - put_flush_packet(pb); - - return 0; -} - -static int wav_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = s->pb; - WAVContext *wav = s->priv_data; - put_buffer(pb, pkt->data, pkt->size); - if(pkt->pts != AV_NOPTS_VALUE) { - wav->minpts = FFMIN(wav->minpts, pkt->pts); - wav->maxpts = FFMAX(wav->maxpts, pkt->pts); - wav->last_duration = pkt->duration; - } else - av_log(s, AV_LOG_ERROR, "wav_write_packet: NOPTS\n"); - return 0; -} - -static int wav_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = s->pb; - WAVContext *wav = s->priv_data; - int64_t file_size; - - if (!url_is_streamed(s->pb)) { - ff_end_tag(pb, wav->data); - - /* update file size */ - file_size = url_ftell(pb); - url_fseek(pb, 4, SEEK_SET); - put_le32(pb, (uint32_t)(file_size - 8)); - url_fseek(pb, file_size, SEEK_SET); - - put_flush_packet(pb); - - if(s->streams[0]->codec->codec_tag != 0x01) { - /* Update num_samps in fact chunk */ - int number_of_samples; - number_of_samples = av_rescale(wav->maxpts - wav->minpts + wav->last_duration, - s->streams[0]->codec->sample_rate * (int64_t)s->streams[0]->time_base.num, - s->streams[0]->time_base.den); - url_fseek(pb, wav->data-12, SEEK_SET); - put_le32(pb, number_of_samples); - url_fseek(pb, file_size, SEEK_SET); - put_flush_packet(pb); - } - } - return 0; -} - -AVOutputFormat wav_muxer = { - "wav", - NULL_IF_CONFIG_SMALL("WAV format"), - "audio/x-wav", - "wav", - sizeof(WAVContext), - CODEC_ID_PCM_S16LE, - CODEC_ID_NONE, - wav_write_header, - wav_write_packet, - wav_write_trailer, - .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, -}; -#endif /* CONFIG_WAV_MUXER */ - - -#if CONFIG_WAV_DEMUXER -/* return the size of the found tag */ -static int64_t find_tag(ByteIOContext *pb, uint32_t tag1) -{ - unsigned int tag; - int64_t size; - - for (;;) { - if (url_feof(pb)) - return -1; - tag = get_le32(pb); - size = get_le32(pb); - if (tag == tag1) - break; - url_fseek(pb, size, SEEK_CUR); - } - return size; -} - -static int wav_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf_size <= 32) - return 0; - if (!memcmp(p->buf + 8, "WAVE", 4)) { - if (!memcmp(p->buf, "RIFF", 4)) - /* - Since ACT demuxer has standard WAV header at top of it's own, - returning score is decreased to avoid probe conflict - between ACT and WAV. - */ - return AVPROBE_SCORE_MAX - 1; - else if (!memcmp(p->buf, "RF64", 4) && - !memcmp(p->buf + 12, "ds64", 4)) - return AVPROBE_SCORE_MAX; - } - return 0; -} - -/* wav input */ -static int wav_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - int64_t size, av_uninit(data_size); - int rf64; - unsigned int tag; - ByteIOContext *pb = s->pb; - AVStream *st; - WAVContext *wav = s->priv_data; - - /* check RIFF header */ - tag = get_le32(pb); - - rf64 = tag == MKTAG('R', 'F', '6', '4'); - if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) - return -1; - get_le32(pb); /* file size */ - tag = get_le32(pb); - if (tag != MKTAG('W', 'A', 'V', 'E')) - return -1; - - if (rf64) { - if (get_le32(pb) != MKTAG('d', 's', '6', '4')) - return -1; - size = get_le32(pb); - if (size < 16) - return -1; - get_le64(pb); /* RIFF size */ - data_size = get_le64(pb); - url_fskip(pb, size - 16); /* skip rest of ds64 chunk */ - } - - /* parse fmt header */ - size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); - if (size < 0) - return -1; - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - ff_get_wav_header(pb, st->codec, size); - st->need_parsing = AVSTREAM_PARSE_FULL; - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); - if (rf64) - size = data_size; - if (size < 0) - return -1; - if (!size) { - wav->data_end = INT64_MAX; - } else - wav->data_end= url_ftell(pb) + size; - return 0; -} - -/** Find chunk with w64 GUID by skipping over other chunks - * @return the size of the found chunk - */ -static int64_t find_guid(ByteIOContext *pb, const uint8_t guid1[16]) -{ - uint8_t guid[16]; - int64_t size; - - while (!url_feof(pb)) { - get_buffer(pb, guid, 16); - size = get_le64(pb); - if (size <= 24) - return -1; - if (!memcmp(guid, guid1, 16)) - return size; - url_fskip(pb, FFALIGN(size, INT64_C(8)) - 24); - } - return -1; -} - -static const uint8_t guid_data[16] = { 'd', 'a', 't', 'a', - 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; - -#define MAX_SIZE 4096 - -static int wav_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret, size; - int64_t left; - AVStream *st; - WAVContext *wav = s->priv_data; - - st = s->streams[0]; - - left = wav->data_end - url_ftell(s->pb); - if (left <= 0){ - if (CONFIG_W64_DEMUXER && wav->w64) - left = find_guid(s->pb, guid_data) - 24; - else - left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a')); - if (left < 0) - return AVERROR_EOF; - wav->data_end= url_ftell(s->pb) + left; - } - - size = MAX_SIZE; - if (st->codec->block_align > 1) { - if (size < st->codec->block_align) - size = st->codec->block_align; - size = (size / st->codec->block_align) * st->codec->block_align; - } - size = FFMIN(size, left); - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) - return ret; - pkt->stream_index = 0; - - return ret; -} - -static int wav_read_seek(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags) -{ - AVStream *st; - - st = s->streams[0]; - switch (st->codec->codec_id) { - case CODEC_ID_MP2: - case CODEC_ID_MP3: - case CODEC_ID_AC3: - case CODEC_ID_DTS: - /* use generic seeking with dynamically generated indexes */ - return -1; - default: - break; - } - return pcm_read_seek(s, stream_index, timestamp, flags); -} - -AVInputFormat wav_demuxer = { - "wav", - NULL_IF_CONFIG_SMALL("WAV format"), - sizeof(WAVContext), - wav_probe, - wav_read_header, - wav_read_packet, - NULL, - wav_read_seek, - .flags= AVFMT_GENERIC_INDEX, - .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, -}; -#endif /* CONFIG_WAV_DEMUXER */ - - -#if CONFIG_W64_DEMUXER -static const uint8_t guid_riff[16] = { 'r', 'i', 'f', 'f', - 0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 }; - -static const uint8_t guid_wave[16] = { 'w', 'a', 'v', 'e', - 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; - -static const uint8_t guid_fmt [16] = { 'f', 'm', 't', ' ', - 0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A }; - -static int w64_probe(AVProbeData *p) -{ - if (p->buf_size <= 40) - return 0; - if (!memcmp(p->buf, guid_riff, 16) && - !memcmp(p->buf + 24, guid_wave, 16)) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - int64_t size; - ByteIOContext *pb = s->pb; - WAVContext *wav = s->priv_data; - AVStream *st; - uint8_t guid[16]; - - get_buffer(pb, guid, 16); - if (memcmp(guid, guid_riff, 16)) - return -1; - - if (get_le64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */ - return -1; - - get_buffer(pb, guid, 16); - if (memcmp(guid, guid_wave, 16)) { - av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); - return -1; - } - - size = find_guid(pb, guid_fmt); - if (size < 0) { - av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); - return -1; - } - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - /* subtract chunk header size - normal wav file doesn't count it */ - ff_get_wav_header(pb, st->codec, size - 24); - url_fskip(pb, FFALIGN(size, INT64_C(8)) - size); - - st->need_parsing = AVSTREAM_PARSE_FULL; - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - size = find_guid(pb, guid_data); - if (size < 0) { - av_log(s, AV_LOG_ERROR, "could not find data guid\n"); - return -1; - } - wav->data_end = url_ftell(pb) + size - 24; - wav->w64 = 1; - - return 0; -} - -AVInputFormat w64_demuxer = { - "w64", - NULL_IF_CONFIG_SMALL("Sony Wave64 format"), - sizeof(WAVContext), - w64_probe, - w64_read_header, - wav_read_packet, - NULL, - wav_read_seek, - .flags = AVFMT_GENERIC_INDEX, - .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0}, -}; -#endif /* CONFIG_W64_DEMUXER */ diff --git a/tizen/distrib/ffmpeg/libavformat/wc3movie.c b/tizen/distrib/ffmpeg/libavformat/wc3movie.c deleted file mode 100644 index d5f0863..0000000 --- a/tizen/distrib/ffmpeg/libavformat/wc3movie.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Wing Commander III Movie (.mve) File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Wing Commander III Movie file demuxer - * by Mike Melanson (melanson@pcisys.net) - * for more information on the WC3 .mve file format, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define FORM_TAG MKTAG('F', 'O', 'R', 'M') -#define MOVE_TAG MKTAG('M', 'O', 'V', 'E') -#define PC__TAG MKTAG('_', 'P', 'C', '_') -#define SOND_TAG MKTAG('S', 'O', 'N', 'D') -#define BNAM_TAG MKTAG('B', 'N', 'A', 'M') -#define SIZE_TAG MKTAG('S', 'I', 'Z', 'E') -#define PALT_TAG MKTAG('P', 'A', 'L', 'T') -#define INDX_TAG MKTAG('I', 'N', 'D', 'X') -#define BRCH_TAG MKTAG('B', 'R', 'C', 'H') -#define SHOT_TAG MKTAG('S', 'H', 'O', 'T') -#define VGA__TAG MKTAG('V', 'G', 'A', ' ') -#define TEXT_TAG MKTAG('T', 'E', 'X', 'T') -#define AUDI_TAG MKTAG('A', 'U', 'D', 'I') - -/* video resolution unless otherwise specified */ -#define WC3_DEFAULT_WIDTH 320 -#define WC3_DEFAULT_HEIGHT 165 - -/* always use the same PCM audio parameters */ -#define WC3_SAMPLE_RATE 22050 -#define WC3_AUDIO_CHANNELS 1 -#define WC3_AUDIO_BITS 16 - -/* nice, constant framerate */ -#define WC3_FRAME_FPS 15 - -#define PALETTE_SIZE (256 * 3) -#define PALETTE_COUNT 256 - -typedef struct Wc3DemuxContext { - int width; - int height; - unsigned char *palettes; - int palette_count; - int64_t pts; - int video_stream_index; - int audio_stream_index; - - AVPaletteControl palette_control; - -} Wc3DemuxContext; - -/** - * palette lookup table that does gamma correction - * - * can be calculated by this formula: - * for i between 0 and 251 inclusive: - * wc3_pal_lookup[i] = round(pow(i / 256.0, 0.8) * 256); - * values 252, 253, 254 and 255 are all 0xFD - * calculating this at runtime should not cause any - * rounding issues, the maximum difference between - * the table values and the calculated doubles is - * about 0.497527 - */ -static const unsigned char wc3_pal_lookup[] = { - 0x00, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0E, - 0x10, 0x12, 0x13, 0x15, 0x16, 0x18, 0x19, 0x1A, - 0x1C, 0x1D, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, - 0x27, 0x28, 0x29, 0x2A, 0x2C, 0x2D, 0x2E, 0x2F, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x39, - 0x3A, 0x3B, 0x3C, 0x3D, 0x3F, 0x40, 0x41, 0x42, - 0x43, 0x44, 0x45, 0x46, 0x48, 0x49, 0x4A, 0x4B, - 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, - 0x54, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, - 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, - 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, - 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, - 0x7D, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, - 0x8C, 0x8D, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99, - 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, - 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, - 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, - 0xB7, 0xB8, 0xB9, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, - 0xBE, 0xBF, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, - 0xC5, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, - 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, - 0xD2, 0xD3, 0xD4, 0xD5, 0xD5, 0xD6, 0xD7, 0xD8, - 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, - 0xE6, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB, 0xEC, - 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2, - 0xF3, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF8, 0xF9, - 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD -}; - - -static int wc3_probe(AVProbeData *p) -{ - if (p->buf_size < 12) - return 0; - - if ((AV_RL32(&p->buf[0]) != FORM_TAG) || - (AV_RL32(&p->buf[8]) != MOVE_TAG)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int wc3_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - Wc3DemuxContext *wc3 = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned int fourcc_tag; - unsigned int size; - AVStream *st; - int ret = 0; - int current_palette = 0; - char *buffer; - int i; - unsigned char rotate; - - /* default context members */ - wc3->width = WC3_DEFAULT_WIDTH; - wc3->height = WC3_DEFAULT_HEIGHT; - wc3->palettes = NULL; - wc3->palette_count = 0; - wc3->pts = 0; - wc3->video_stream_index = wc3->audio_stream_index = 0; - - /* skip the first 3 32-bit numbers */ - url_fseek(pb, 12, SEEK_CUR); - - /* traverse through the chunks and load the header information before - * the first BRCH tag */ - fourcc_tag = get_le32(pb); - size = (get_be32(pb) + 1) & (~1); - - do { - switch (fourcc_tag) { - - case SOND_TAG: - case INDX_TAG: - /* SOND unknown, INDX unnecessary; ignore both */ - url_fseek(pb, size, SEEK_CUR); - break; - - case PC__TAG: - /* need the number of palettes */ - url_fseek(pb, 8, SEEK_CUR); - wc3->palette_count = get_le32(pb); - if((unsigned)wc3->palette_count >= UINT_MAX / PALETTE_SIZE){ - wc3->palette_count= 0; - return -1; - } - wc3->palettes = av_malloc(wc3->palette_count * PALETTE_SIZE); - break; - - case BNAM_TAG: - /* load up the name */ - buffer = av_malloc(size+1); - if (!buffer) - return AVERROR(ENOMEM); - if ((ret = get_buffer(pb, buffer, size)) != size) - return AVERROR(EIO); - buffer[size] = 0; - av_metadata_set2(&s->metadata, "title", buffer, - AV_METADATA_DONT_STRDUP_VAL); - break; - - case SIZE_TAG: - /* video resolution override */ - wc3->width = get_le32(pb); - wc3->height = get_le32(pb); - break; - - case PALT_TAG: - /* one of several palettes */ - if ((unsigned)current_palette >= wc3->palette_count) - return AVERROR_INVALIDDATA; - if ((ret = get_buffer(pb, - &wc3->palettes[current_palette * PALETTE_SIZE], - PALETTE_SIZE)) != PALETTE_SIZE) - return AVERROR(EIO); - - /* transform the current palette in place */ - for (i = current_palette * PALETTE_SIZE; - i < (current_palette + 1) * PALETTE_SIZE; i++) { - /* rotate each palette component left by 2 and use the result - * as an index into the color component table */ - rotate = ((wc3->palettes[i] << 2) & 0xFF) | - ((wc3->palettes[i] >> 6) & 0xFF); - wc3->palettes[i] = wc3_pal_lookup[rotate]; - } - current_palette++; - break; - - default: - av_log(s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24), - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24)); - return AVERROR_INVALIDDATA; - break; - } - - fourcc_tag = get_le32(pb); - /* chunk sizes are 16-bit aligned */ - size = (get_be32(pb) + 1) & (~1); - if (url_feof(pb)) - return AVERROR(EIO); - - } while (fourcc_tag != BRCH_TAG); - - /* initialize the decoder streams */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, WC3_FRAME_FPS); - wc3->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_XAN_WC3; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = wc3->width; - st->codec->height = wc3->height; - - /* palette considerations */ - st->codec->palctrl = &wc3->palette_control; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, WC3_FRAME_FPS); - wc3->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_S16LE; - st->codec->codec_tag = 1; - st->codec->channels = WC3_AUDIO_CHANNELS; - st->codec->bits_per_coded_sample = WC3_AUDIO_BITS; - st->codec->sample_rate = WC3_SAMPLE_RATE; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = WC3_AUDIO_BITS * WC3_AUDIO_CHANNELS; - - return 0; -} - -static int wc3_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - Wc3DemuxContext *wc3 = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned int fourcc_tag; - unsigned int size; - int packet_read = 0; - int ret = 0; - unsigned char text[1024]; - unsigned int palette_number; - int i; - unsigned char r, g, b; - int base_palette_index; - - while (!packet_read) { - - fourcc_tag = get_le32(pb); - /* chunk sizes are 16-bit aligned */ - size = (get_be32(pb) + 1) & (~1); - if (url_feof(pb)) - return AVERROR(EIO); - - switch (fourcc_tag) { - - case BRCH_TAG: - /* no-op */ - break; - - case SHOT_TAG: - /* load up new palette */ - palette_number = get_le32(pb); - if (palette_number >= wc3->palette_count) - return AVERROR_INVALIDDATA; - base_palette_index = palette_number * PALETTE_COUNT * 3; - for (i = 0; i < PALETTE_COUNT; i++) { - r = wc3->palettes[base_palette_index + i * 3 + 0]; - g = wc3->palettes[base_palette_index + i * 3 + 1]; - b = wc3->palettes[base_palette_index + i * 3 + 2]; - wc3->palette_control.palette[i] = (r << 16) | (g << 8) | (b); - } - wc3->palette_control.palette_changed = 1; - break; - - case VGA__TAG: - /* send out video chunk */ - ret= av_get_packet(pb, pkt, size); - pkt->stream_index = wc3->video_stream_index; - pkt->pts = wc3->pts; - packet_read = 1; - break; - - case TEXT_TAG: - /* subtitle chunk */ -#if 0 - url_fseek(pb, size, SEEK_CUR); -#else - if ((unsigned)size > sizeof(text) || (ret = get_buffer(pb, text, size)) != size) - ret = AVERROR(EIO); - else { - int i = 0; - av_log (s, AV_LOG_DEBUG, "Subtitle time!\n"); - av_log (s, AV_LOG_DEBUG, " inglish: %s\n", &text[i + 1]); - i += text[i] + 1; - av_log (s, AV_LOG_DEBUG, " doytsch: %s\n", &text[i + 1]); - i += text[i] + 1; - av_log (s, AV_LOG_DEBUG, " fronsay: %s\n", &text[i + 1]); - } -#endif - break; - - case AUDI_TAG: - /* send out audio chunk */ - ret= av_get_packet(pb, pkt, size); - pkt->stream_index = wc3->audio_stream_index; - pkt->pts = wc3->pts; - - /* time to advance pts */ - wc3->pts++; - - packet_read = 1; - break; - - default: - av_log (s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24), - (uint8_t)fourcc_tag, (uint8_t)(fourcc_tag >> 8), (uint8_t)(fourcc_tag >> 16), (uint8_t)(fourcc_tag >> 24)); - ret = AVERROR_INVALIDDATA; - packet_read = 1; - break; - } - } - - return ret; -} - -static int wc3_read_close(AVFormatContext *s) -{ - Wc3DemuxContext *wc3 = s->priv_data; - - av_free(wc3->palettes); - - return 0; -} - -AVInputFormat wc3_demuxer = { - "wc3movie", - NULL_IF_CONFIG_SMALL("Wing Commander III movie format"), - sizeof(Wc3DemuxContext), - wc3_probe, - wc3_read_header, - wc3_read_packet, - wc3_read_close, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/westwood.c b/tizen/distrib/ffmpeg/libavformat/westwood.c deleted file mode 100644 index 10d5798..0000000 --- a/tizen/distrib/ffmpeg/libavformat/westwood.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Westwood Studios Multimedia Formats Demuxer (VQA, AUD) - * Copyright (c) 2003 The ffmpeg Project - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Westwood Studios VQA & AUD file demuxers - * by Mike Melanson (melanson@pcisys.net) - * for more information on the Westwood file formats, visit: - * http://www.pcisys.net/~melanson/codecs/ - * http://www.geocities.com/SiliconValley/8682/aud3.txt - * - * Implementation note: There is no definite file signature for AUD files. - * The demuxer uses a probabilistic strategy for content detection. This - * entails performing sanity checks on certain header values in order to - * qualify a file. Refer to wsaud_probe() for the precise parameters. - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define AUD_HEADER_SIZE 12 -#define AUD_CHUNK_PREAMBLE_SIZE 8 -#define AUD_CHUNK_SIGNATURE 0x0000DEAF - -#define FORM_TAG MKBETAG('F', 'O', 'R', 'M') -#define WVQA_TAG MKBETAG('W', 'V', 'Q', 'A') -#define VQHD_TAG MKBETAG('V', 'Q', 'H', 'D') -#define FINF_TAG MKBETAG('F', 'I', 'N', 'F') -#define SND0_TAG MKBETAG('S', 'N', 'D', '0') -#define SND1_TAG MKBETAG('S', 'N', 'D', '1') -#define SND2_TAG MKBETAG('S', 'N', 'D', '2') -#define VQFR_TAG MKBETAG('V', 'Q', 'F', 'R') - -/* don't know what these tags are for, but acknowledge their existence */ -#define CINF_TAG MKBETAG('C', 'I', 'N', 'F') -#define CINH_TAG MKBETAG('C', 'I', 'N', 'H') -#define CIND_TAG MKBETAG('C', 'I', 'N', 'D') -#define PINF_TAG MKBETAG('P', 'I', 'N', 'F') -#define PINH_TAG MKBETAG('P', 'I', 'N', 'H') -#define PIND_TAG MKBETAG('P', 'I', 'N', 'D') -#define CMDS_TAG MKBETAG('C', 'M', 'D', 'S') - -#define VQA_HEADER_SIZE 0x2A -#define VQA_FRAMERATE 15 -#define VQA_PREAMBLE_SIZE 8 - -typedef struct WsAudDemuxContext { - int audio_samplerate; - int audio_channels; - int audio_bits; - enum CodecID audio_type; - int audio_stream_index; - int64_t audio_frame_counter; -} WsAudDemuxContext; - -typedef struct WsVqaDemuxContext { - int audio_samplerate; - int audio_channels; - int audio_bits; - - int audio_stream_index; - int video_stream_index; - - int64_t audio_frame_counter; -} WsVqaDemuxContext; - -static int wsaud_probe(AVProbeData *p) -{ - int field; - - /* Probabilistic content detection strategy: There is no file signature - * so perform sanity checks on various header parameters: - * 8000 <= sample rate (16 bits) <= 48000 ==> 40001 acceptable numbers - * flags <= 0x03 (2 LSBs are used) ==> 4 acceptable numbers - * compression type (8 bits) = 1 or 99 ==> 2 acceptable numbers - * first audio chunk signature (32 bits) ==> 1 acceptable number - * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 = - * 320008 acceptable number combinations. - */ - - if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE) - return 0; - - /* check sample rate */ - field = AV_RL16(&p->buf[0]); - if ((field < 8000) || (field > 48000)) - return 0; - - /* enforce the rule that the top 6 bits of this flags field are reserved (0); - * this might not be true, but enforce it until deemed unnecessary */ - if (p->buf[10] & 0xFC) - return 0; - - /* note: only check for WS IMA (type 99) right now since there is no - * support for type 1 */ - if (p->buf[11] != 99) - return 0; - - /* read ahead to the first audio chunk and validate the first header signature */ - if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE) - return 0; - - /* return 1/2 certainty since this file check is a little sketchy */ - return AVPROBE_SCORE_MAX / 2; -} - -static int wsaud_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - WsAudDemuxContext *wsaud = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - unsigned char header[AUD_HEADER_SIZE]; - - if (get_buffer(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE) - return AVERROR(EIO); - wsaud->audio_samplerate = AV_RL16(&header[0]); - if (header[11] == 99) - wsaud->audio_type = CODEC_ID_ADPCM_IMA_WS; - else - return AVERROR_INVALIDDATA; - - /* flag 0 indicates stereo */ - wsaud->audio_channels = (header[10] & 0x1) + 1; - /* flag 1 indicates 16 bit audio */ - wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8; - - /* initialize the audio decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, wsaud->audio_samplerate); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = wsaud->audio_type; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = wsaud->audio_channels; - st->codec->sample_rate = wsaud->audio_samplerate; - st->codec->bits_per_coded_sample = wsaud->audio_bits; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample / 4; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - - wsaud->audio_stream_index = st->index; - wsaud->audio_frame_counter = 0; - - return 0; -} - -static int wsaud_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - WsAudDemuxContext *wsaud = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE]; - unsigned int chunk_size; - int ret = 0; - - if (get_buffer(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) != - AUD_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - - /* validate the chunk */ - if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE) - return AVERROR_INVALIDDATA; - - chunk_size = AV_RL16(&preamble[0]); - ret= av_get_packet(pb, pkt, chunk_size); - if (ret != chunk_size) - return AVERROR(EIO); - pkt->stream_index = wsaud->audio_stream_index; - pkt->pts = wsaud->audio_frame_counter; - pkt->pts /= wsaud->audio_samplerate; - - /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ - wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels; - - return ret; -} - -static int wsvqa_probe(AVProbeData *p) -{ - /* need 12 bytes to qualify */ - if (p->buf_size < 12) - return 0; - - /* check for the VQA signatures */ - if ((AV_RB32(&p->buf[0]) != FORM_TAG) || - (AV_RB32(&p->buf[8]) != WVQA_TAG)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int wsvqa_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - WsVqaDemuxContext *wsvqa = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - unsigned char *header; - unsigned char scratch[VQA_PREAMBLE_SIZE]; - unsigned int chunk_tag; - unsigned int chunk_size; - - /* initialize the video decoder stream */ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, VQA_FRAMERATE); - wsvqa->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_WS_VQA; - st->codec->codec_tag = 0; /* no fourcc */ - - /* skip to the start of the VQA header */ - url_fseek(pb, 20, SEEK_SET); - - /* the VQA header needs to go to the decoder */ - st->codec->extradata_size = VQA_HEADER_SIZE; - st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - header = (unsigned char *)st->codec->extradata; - if (get_buffer(pb, st->codec->extradata, VQA_HEADER_SIZE) != - VQA_HEADER_SIZE) { - av_free(st->codec->extradata); - return AVERROR(EIO); - } - st->codec->width = AV_RL16(&header[6]); - st->codec->height = AV_RL16(&header[8]); - - /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */ - if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - av_set_pts_info(st, 33, 1, VQA_FRAMERATE); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - if (AV_RL16(&header[0]) == 1) - st->codec->codec_id = CODEC_ID_WESTWOOD_SND1; - else - st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS; - st->codec->codec_tag = 0; /* no tag */ - st->codec->sample_rate = AV_RL16(&header[24]); - if (!st->codec->sample_rate) - st->codec->sample_rate = 22050; - st->codec->channels = header[26]; - if (!st->codec->channels) - st->codec->channels = 1; - st->codec->bits_per_coded_sample = 16; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample / 4; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - - wsvqa->audio_stream_index = st->index; - wsvqa->audio_samplerate = st->codec->sample_rate; - wsvqa->audio_channels = st->codec->channels; - wsvqa->audio_frame_counter = 0; - } - - /* there are 0 or more chunks before the FINF chunk; iterate until - * FINF has been skipped and the file will be ready to be demuxed */ - do { - if (get_buffer(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) { - av_free(st->codec->extradata); - return AVERROR(EIO); - } - chunk_tag = AV_RB32(&scratch[0]); - chunk_size = AV_RB32(&scratch[4]); - - /* catch any unknown header tags, for curiousity */ - switch (chunk_tag) { - case CINF_TAG: - case CINH_TAG: - case CIND_TAG: - case PINF_TAG: - case PINH_TAG: - case PIND_TAG: - case FINF_TAG: - case CMDS_TAG: - break; - - default: - av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n", - scratch[0], scratch[1], - scratch[2], scratch[3]); - break; - } - - url_fseek(pb, chunk_size, SEEK_CUR); - } while (chunk_tag != FINF_TAG); - - return 0; -} - -static int wsvqa_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - WsVqaDemuxContext *wsvqa = s->priv_data; - ByteIOContext *pb = s->pb; - int ret = -1; - unsigned char preamble[VQA_PREAMBLE_SIZE]; - unsigned int chunk_type; - unsigned int chunk_size; - int skip_byte; - - while (get_buffer(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) { - chunk_type = AV_RB32(&preamble[0]); - chunk_size = AV_RB32(&preamble[4]); - skip_byte = chunk_size & 0x01; - - if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) { - - if (av_new_packet(pkt, chunk_size)) - return AVERROR(EIO); - ret = get_buffer(pb, pkt->data, chunk_size); - if (ret != chunk_size) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - if (chunk_type == SND2_TAG) { - pkt->stream_index = wsvqa->audio_stream_index; - /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ - wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels; - } else if(chunk_type == SND1_TAG) { - pkt->stream_index = wsvqa->audio_stream_index; - /* unpacked size is stored in header */ - wsvqa->audio_frame_counter += AV_RL16(pkt->data) / wsvqa->audio_channels; - } else { - pkt->stream_index = wsvqa->video_stream_index; - } - /* stay on 16-bit alignment */ - if (skip_byte) - url_fseek(pb, 1, SEEK_CUR); - - return ret; - } else { - switch(chunk_type){ - case CMDS_TAG: - case SND0_TAG: - break; - default: - av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type); - } - url_fseek(pb, chunk_size + skip_byte, SEEK_CUR); - } - } - - return ret; -} - -#if CONFIG_WSAUD_DEMUXER -AVInputFormat wsaud_demuxer = { - "wsaud", - NULL_IF_CONFIG_SMALL("Westwood Studios audio format"), - sizeof(WsAudDemuxContext), - wsaud_probe, - wsaud_read_header, - wsaud_read_packet, -}; -#endif -#if CONFIG_WSVQA_DEMUXER -AVInputFormat wsvqa_demuxer = { - "wsvqa", - NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"), - sizeof(WsVqaDemuxContext), - wsvqa_probe, - wsvqa_read_header, - wsvqa_read_packet, -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavformat/wv.c b/tizen/distrib/ffmpeg/libavformat/wv.c deleted file mode 100644 index 03b864b..0000000 --- a/tizen/distrib/ffmpeg/libavformat/wv.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * WavPack demuxer - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "apetag.h" -#include "id3v1.h" - -// specs say that maximum block size is 1Mb -#define WV_BLOCK_LIMIT 1047576 - -#define WV_EXTRA_SIZE 12 - -enum WV_FLAGS{ - WV_MONO = 0x0004, - WV_HYBRID = 0x0008, - WV_JOINT = 0x0010, - WV_CROSSD = 0x0020, - WV_HSHAPE = 0x0040, - WV_FLOAT = 0x0080, - WV_INT32 = 0x0100, - WV_HBR = 0x0200, - WV_HBAL = 0x0400, - WV_MCINIT = 0x0800, - WV_MCEND = 0x1000, -}; - -static const int wv_rates[16] = { - 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, - 32000, 44100, 48000, 64000, 88200, 96000, 192000, -1 -}; - -typedef struct{ - uint32_t blksize, flags; - int rate, chan, bpp; - uint32_t samples, soff; - int block_parsed; - uint8_t extra[WV_EXTRA_SIZE]; - int64_t pos; -}WVContext; - -static int wv_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf_size <= 32) - return 0; - if (p->buf[0] == 'w' && p->buf[1] == 'v' && - p->buf[2] == 'p' && p->buf[3] == 'k') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb) -{ - WVContext *wc = ctx->priv_data; - uint32_t tag, ver; - int size; - int rate, bpp, chan; - - wc->pos = url_ftell(pb); - tag = get_le32(pb); - if (tag != MKTAG('w', 'v', 'p', 'k')) - return -1; - size = get_le32(pb); - if(size < 24 || size > WV_BLOCK_LIMIT){ - av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size); - return -1; - } - wc->blksize = size; - ver = get_le16(pb); - if(ver < 0x402 || ver > 0x410){ - av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver); - return -1; - } - get_byte(pb); // track no - get_byte(pb); // track sub index - wc->samples = get_le32(pb); // total samples in file - wc->soff = get_le32(pb); // offset in samples of current block - get_buffer(pb, wc->extra, WV_EXTRA_SIZE); - wc->flags = AV_RL32(wc->extra + 4); - //parse flags - bpp = ((wc->flags & 3) + 1) << 3; - chan = 1 + !(wc->flags & WV_MONO); - rate = wv_rates[(wc->flags >> 23) & 0xF]; - if(rate == -1 && !wc->block_parsed){ - int64_t block_end = url_ftell(pb) + wc->blksize - 24; - if(url_is_streamed(pb)){ - av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); - return -1; - } - while(url_ftell(pb) < block_end){ - int id, size; - id = get_byte(pb); - size = (id & 0x80) ? get_le24(pb) : get_byte(pb); - size <<= 1; - if(id&0x40) - size--; - if((id&0x3F) == 0x27){ - rate = get_le24(pb); - break; - }else{ - url_fskip(pb, size); - } - } - if(rate == -1){ - av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); - return -1; - } - url_fseek(pb, block_end - wc->blksize + 24, SEEK_SET); - } - if(!wc->bpp) wc->bpp = bpp; - if(!wc->chan) wc->chan = chan; - if(!wc->rate) wc->rate = rate; - - if(wc->flags && bpp != wc->bpp){ - av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); - return -1; - } - if(wc->flags && chan != wc->chan){ - av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); - return -1; - } - if(wc->flags && rate != -1 && rate != wc->rate){ - av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); - return -1; - } - wc->blksize = size - 24; - return 0; -} - -static int wv_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - ByteIOContext *pb = s->pb; - WVContext *wc = s->priv_data; - AVStream *st; - - wc->block_parsed = 0; - if(wv_read_block_header(s, pb) < 0) - return -1; - - /* now we are ready: build format streams */ - st = av_new_stream(s, 0); - if (!st) - return -1; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_WAVPACK; - st->codec->channels = wc->chan; - st->codec->sample_rate = wc->rate; - st->codec->bits_per_coded_sample = wc->bpp; - av_set_pts_info(st, 64, 1, wc->rate); - st->start_time = 0; - st->duration = wc->samples; - - if(!url_is_streamed(s->pb)) { - int64_t cur = url_ftell(s->pb); - ff_ape_parse_tag(s); - if(!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) - ff_id3v1_read(s); - url_fseek(s->pb, cur, SEEK_SET); - } - - return 0; -} - -static int wv_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - WVContext *wc = s->priv_data; - int ret; - - if (url_feof(s->pb)) - return AVERROR(EIO); - if(wc->block_parsed){ - if(wv_read_block_header(s, s->pb) < 0) - return -1; - } - - if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE) < 0) - return AVERROR(ENOMEM); - memcpy(pkt->data, wc->extra, WV_EXTRA_SIZE); - ret = get_buffer(s->pb, pkt->data + WV_EXTRA_SIZE, wc->blksize); - if(ret != wc->blksize){ - av_free_packet(pkt); - return AVERROR(EIO); - } - pkt->stream_index = 0; - wc->block_parsed = 1; - pkt->size = ret + WV_EXTRA_SIZE; - pkt->pts = wc->soff; - av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); - return 0; -} - -static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - WVContext *wc = s->priv_data; - AVPacket pkt1, *pkt = &pkt1; - int ret; - int index = av_index_search_timestamp(st, timestamp, flags); - int64_t pos, pts; - - /* if found, seek there */ - if (index >= 0){ - wc->block_parsed = 1; - url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET); - return 0; - } - /* if timestamp is out of bounds, return error */ - if(timestamp < 0 || timestamp >= s->duration) - return -1; - - pos = url_ftell(s->pb); - do{ - ret = av_read_frame(s, pkt); - if (ret < 0){ - url_fseek(s->pb, pos, SEEK_SET); - return -1; - } - pts = pkt->pts; - av_free_packet(pkt); - }while(pts < timestamp); - return 0; -} - -AVInputFormat wv_demuxer = { - "wv", - NULL_IF_CONFIG_SMALL("WavPack"), - sizeof(WVContext), - wv_probe, - wv_read_header, - wv_read_packet, - NULL, - wv_read_seek, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/xa.c b/tizen/distrib/ffmpeg/libavformat/xa.c deleted file mode 100644 index 3a866b9..0000000 --- a/tizen/distrib/ffmpeg/libavformat/xa.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Maxis XA (.xa) File Demuxer - * Copyright (c) 2008 Robert Marston - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Maxis XA File Demuxer - * by Robert Marston (rmarston@gmail.com) - * for more information on the XA audio format see - * http://wiki.multimedia.cx/index.php?title=Maxis_XA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define XA00_TAG MKTAG('X', 'A', 0, 0) -#define XAI0_TAG MKTAG('X', 'A', 'I', 0) -#define XAJ0_TAG MKTAG('X', 'A', 'J', 0) - -typedef struct MaxisXADemuxContext { - uint32_t out_size; - uint32_t sent_bytes; - uint32_t audio_frame_counter; -} MaxisXADemuxContext; - -static int xa_probe(AVProbeData *p) -{ - int channels, srate, bits_per_sample; - if (p->buf_size < 24) - return 0; - switch(AV_RL32(p->buf)) { - case XA00_TAG: - case XAI0_TAG: - case XAJ0_TAG: - break; - default: - return 0; - } - channels = AV_RL16(p->buf + 10); - srate = AV_RL32(p->buf + 12); - bits_per_sample = AV_RL16(p->buf + 22); - if (!channels || channels > 8 || !srate || srate > 192000 || - bits_per_sample < 4 || bits_per_sample > 32) - return 0; - return AVPROBE_SCORE_MAX/2; -} - -static int xa_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - MaxisXADemuxContext *xa = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *st; - - /*Set up the XA Audio Decoder*/ - st = av_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_ADPCM_EA_MAXIS_XA; - url_fskip(pb, 4); /* Skip the XA ID */ - xa->out_size = get_le32(pb); - url_fskip(pb, 2); /* Skip the tag */ - st->codec->channels = get_le16(pb); - st->codec->sample_rate = get_le32(pb); - /* Value in file is average byte rate*/ - st->codec->bit_rate = get_le32(pb) * 8; - st->codec->block_align = get_le16(pb); - st->codec->bits_per_coded_sample = get_le16(pb); - - av_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -static int xa_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MaxisXADemuxContext *xa = s->priv_data; - AVStream *st = s->streams[0]; - ByteIOContext *pb = s->pb; - unsigned int packet_size; - int ret; - - if(xa->sent_bytes > xa->out_size) - return AVERROR(EIO); - /* 1 byte header and 14 bytes worth of samples * number channels per block */ - packet_size = 15*st->codec->channels; - - ret = av_get_packet(pb, pkt, packet_size); - if(ret < 0) - return ret; - - pkt->stream_index = st->index; - xa->sent_bytes += packet_size; - pkt->pts = xa->audio_frame_counter; - /* 14 bytes Samples per channel with 2 samples per byte */ - xa->audio_frame_counter += 28 * st->codec->channels; - - return ret; -} - -AVInputFormat xa_demuxer = { - "xa", - NULL_IF_CONFIG_SMALL("Maxis XA File Format"), - sizeof(MaxisXADemuxContext), - xa_probe, - xa_read_header, - xa_read_packet, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/yop.c b/tizen/distrib/ffmpeg/libavformat/yop.c deleted file mode 100644 index 54d3845..0000000 --- a/tizen/distrib/ffmpeg/libavformat/yop.c +++ /dev/null @@ -1,216 +0,0 @@ -/** - * @file - * Psygnosis YOP demuxer - * - * Copyright (C) 2010 Mohamed Naufal Basheer - * derived from the code by - * Copyright (C) 2009 Thomas P. Higdon - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -typedef struct yop_dec_context { - AVPacket video_packet; - - int odd_frame; - int frame_size; - int audio_block_length; - int palette_size; -} YopDecContext; - -static int yop_probe(AVProbeData *probe_packet) -{ - if (AV_RB16(probe_packet->buf) == AV_RB16("YO") && - probe_packet->buf[6] && - probe_packet->buf[7] && - !(probe_packet->buf[8] & 1) && - !(probe_packet->buf[10] & 1)) - return AVPROBE_SCORE_MAX * 3 / 4; - - return 0; -} - -static int yop_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - YopDecContext *yop = s->priv_data; - ByteIOContext *pb = s->pb; - - AVCodecContext *audio_dec, *video_dec; - AVStream *audio_stream, *video_stream; - - int frame_rate, ret; - - audio_stream = av_new_stream(s, 0); - video_stream = av_new_stream(s, 1); - - // Extra data that will be passed to the decoder - video_stream->codec->extradata_size = 8; - - video_stream->codec->extradata = av_mallocz(video_stream->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - - if (!video_stream->codec->extradata) - return AVERROR(ENOMEM); - - // Audio - audio_dec = audio_stream->codec; - audio_dec->codec_type = AVMEDIA_TYPE_AUDIO; - audio_dec->codec_id = CODEC_ID_ADPCM_IMA_WS; - audio_dec->channels = 1; - audio_dec->sample_rate = 22050; - - // Video - video_dec = video_stream->codec; - video_dec->codec_type = AVMEDIA_TYPE_VIDEO; - video_dec->codec_id = CODEC_ID_YOP; - - url_fskip(pb, 6); - - frame_rate = get_byte(pb); - yop->frame_size = get_byte(pb) * 2048; - video_dec->width = get_le16(pb); - video_dec->height = get_le16(pb); - - video_stream->sample_aspect_ratio = (AVRational){1, 2}; - - ret = get_buffer(pb, video_dec->extradata, 8); - if (ret < 8) - return ret < 0 ? ret : AVERROR_EOF; - - yop->palette_size = video_dec->extradata[0] * 3 + 4; - yop->audio_block_length = AV_RL16(video_dec->extradata + 6); - - // 1840 samples per frame, 1 nibble per sample; hence 1840/2 = 920 - if (yop->audio_block_length < 920 || - yop->audio_block_length + yop->palette_size >= yop->frame_size) { - av_log(s, AV_LOG_ERROR, "YOP has invalid header\n"); - return AVERROR_INVALIDDATA; - } - - url_fseek(pb, 2048, SEEK_SET); - - av_set_pts_info(video_stream, 32, 1, frame_rate); - - return 0; -} - -static int yop_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - YopDecContext *yop = s->priv_data; - ByteIOContext *pb = s->pb; - - int ret; - int actual_video_data_size = yop->frame_size - - yop->audio_block_length - yop->palette_size; - - yop->video_packet.stream_index = 1; - - if (yop->video_packet.data) { - *pkt = yop->video_packet; - yop->video_packet.data = NULL; - yop->video_packet.size = 0; - pkt->data[0] = yop->odd_frame; - pkt->flags |= AV_PKT_FLAG_KEY; - yop->odd_frame ^= 1; - return pkt->size; - } - ret = av_new_packet(&yop->video_packet, - yop->frame_size - yop->audio_block_length); - if (ret < 0) - return ret; - - yop->video_packet.pos = url_ftell(pb); - - ret = get_buffer(pb, yop->video_packet.data, yop->palette_size); - if (ret < 0) { - goto err_out; - }else if (ret < yop->palette_size) { - ret = AVERROR_EOF; - goto err_out; - } - - ret = av_get_packet(pb, pkt, 920); - if (ret < 0) - goto err_out; - - // Set position to the start of the frame - pkt->pos = yop->video_packet.pos; - - url_fskip(pb, yop->audio_block_length - ret); - - ret = get_buffer(pb, yop->video_packet.data + yop->palette_size, - actual_video_data_size); - if (ret < 0) - goto err_out; - else if (ret < actual_video_data_size) - av_shrink_packet(&yop->video_packet, yop->palette_size + ret); - - // Arbitrarily return the audio data first - return yop->audio_block_length; - -err_out: - av_free_packet(&yop->video_packet); - return ret; -} - -static int yop_read_close(AVFormatContext *s) -{ - YopDecContext *yop = s->priv_data; - av_free_packet(&yop->video_packet); - return 0; -} - -static int yop_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - YopDecContext *yop = s->priv_data; - int64_t frame_pos, pos_min, pos_max; - int frame_count; - - av_free_packet(&yop->video_packet); - - if (!stream_index) - return -1; - - pos_min = s->data_offset; - pos_max = url_fsize(s->pb) - yop->frame_size; - frame_count = (pos_max - pos_min) / yop->frame_size; - - timestamp = FFMAX(0, FFMIN(frame_count, timestamp)); - - frame_pos = timestamp * yop->frame_size + pos_min; - yop->odd_frame = timestamp & 1; - - url_fseek(s->pb, frame_pos, SEEK_SET); - return 0; -} - -AVInputFormat yop_demuxer = { - "yop", - NULL_IF_CONFIG_SMALL("Psygnosis YOP Format"), - sizeof(YopDecContext), - yop_probe, - yop_read_header, - yop_read_packet, - yop_read_close, - yop_read_seek, - .extensions = "yop", - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/tizen/distrib/ffmpeg/libavformat/yuv4mpeg.c b/tizen/distrib/ffmpeg/libavformat/yuv4mpeg.c deleted file mode 100644 index 99a1ce2..0000000 --- a/tizen/distrib/ffmpeg/libavformat/yuv4mpeg.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * YUV4MPEG format - * Copyright (c) 2001, 2002, 2003 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" - -#define Y4M_MAGIC "YUV4MPEG2" -#define Y4M_FRAME_MAGIC "FRAME" -#define Y4M_LINE_MAX 256 - -struct frame_attributes { - int interlaced_frame; - int top_field_first; -}; - -#if CONFIG_YUV4MPEGPIPE_MUXER -static int yuv4_generate_header(AVFormatContext *s, char* buf) -{ - AVStream *st; - int width, height; - int raten, rated, aspectn, aspectd, n; - char inter; - const char *colorspace = ""; - - st = s->streams[0]; - width = st->codec->width; - height = st->codec->height; - - av_reduce(&raten, &rated, st->codec->time_base.den, st->codec->time_base.num, (1UL<<31)-1); - - aspectn = st->sample_aspect_ratio.num; - aspectd = st->sample_aspect_ratio.den; - - if ( aspectn == 0 && aspectd == 1 ) aspectd = 0; // 0:0 means unknown - - inter = 'p'; /* progressive is the default */ - if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame) { - inter = st->codec->coded_frame->top_field_first ? 't' : 'b'; - } - - switch(st->codec->pix_fmt) { - case PIX_FMT_GRAY8: - colorspace = " Cmono"; - break; - case PIX_FMT_YUV411P: - colorspace = " C411 XYSCSS=411"; - break; - case PIX_FMT_YUV420P: - colorspace = (st->codec->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)?" C420paldv XYSCSS=420PALDV": - (st->codec->chroma_sample_location == AVCHROMA_LOC_LEFT) ?" C420mpeg2 XYSCSS=420MPEG2": - " C420jpeg XYSCSS=420JPEG"; - break; - case PIX_FMT_YUV422P: - colorspace = " C422 XYSCSS=422"; - break; - case PIX_FMT_YUV444P: - colorspace = " C444 XYSCSS=444"; - break; - } - - /* construct stream header, if this is the first frame */ - n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s\n", - Y4M_MAGIC, - width, - height, - raten, rated, - inter, - aspectn, aspectd, - colorspace); - - return n; -} - -static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVStream *st = s->streams[pkt->stream_index]; - ByteIOContext *pb = s->pb; - AVPicture *picture; - int* first_pkt = s->priv_data; - int width, height, h_chroma_shift, v_chroma_shift; - int i, m; - char buf2[Y4M_LINE_MAX+1]; - char buf1[20]; - uint8_t *ptr, *ptr1, *ptr2; - - picture = (AVPicture *)pkt->data; - - /* for the first packet we have to output the header as well */ - if (*first_pkt) { - *first_pkt = 0; - if (yuv4_generate_header(s, buf2) < 0) { - av_log(s, AV_LOG_ERROR, "Error. YUV4MPEG stream header write failed.\n"); - return AVERROR(EIO); - } else { - put_buffer(pb, buf2, strlen(buf2)); - } - } - - /* construct frame header */ - - m = snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC); - put_buffer(pb, buf1, strlen(buf1)); - - width = st->codec->width; - height = st->codec->height; - - ptr = picture->data[0]; - for(i=0;ilinesize[0]; - } - - if (st->codec->pix_fmt != PIX_FMT_GRAY8){ - // Adjust for smaller Cb and Cr planes - avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift, &v_chroma_shift); - width >>= h_chroma_shift; - height >>= v_chroma_shift; - - ptr1 = picture->data[1]; - ptr2 = picture->data[2]; - for(i=0;ilinesize[1]; - } - for(i=0;ilinesize[2]; - } - } - put_flush_packet(pb); - return 0; -} - -static int yuv4_write_header(AVFormatContext *s) -{ - int* first_pkt = s->priv_data; - - if (s->nb_streams != 1) - return AVERROR(EIO); - - if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) { - av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV stream, some mjpegtools might not work.\n"); - } - else if ((s->streams[0]->codec->pix_fmt != PIX_FMT_YUV420P) && - (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV422P) && - (s->streams[0]->codec->pix_fmt != PIX_FMT_GRAY8) && - (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV444P)) { - av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg only handles yuv444p, yuv422p, yuv420p, yuv411p and gray pixel formats. Use -pix_fmt to select one.\n"); - return AVERROR(EIO); - } - - *first_pkt = 1; - return 0; -} - -AVOutputFormat yuv4mpegpipe_muxer = { - "yuv4mpegpipe", - NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"), - "", - "y4m", - sizeof(int), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - yuv4_write_header, - yuv4_write_packet, - .flags = AVFMT_RAWPICTURE, -}; -#endif - -/* Header size increased to allow room for optional flags */ -#define MAX_YUV4_HEADER 80 -#define MAX_FRAME_HEADER 80 - -static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - char header[MAX_YUV4_HEADER+10]; // Include headroom for the longest option - char *tokstart,*tokend,*header_end; - int i; - ByteIOContext *pb = s->pb; - int width=-1, height=-1, raten=0, rated=0, aspectn=0, aspectd=0; - enum PixelFormat pix_fmt=PIX_FMT_NONE,alt_pix_fmt=PIX_FMT_NONE; - enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; - AVStream *st; - struct frame_attributes *s1 = s->priv_data; - - for (i=0; iinterlaced_frame = 0; - s1->top_field_first = 0; - header_end = &header[i+1]; // Include space - for(tokstart = &header[strlen(Y4M_MAGIC) + 1]; tokstart < header_end; tokstart++) { - if (*tokstart==0x20) continue; - switch (*tokstart++) { - case 'W': // Width. Required. - width = strtol(tokstart, &tokend, 10); - tokstart=tokend; - break; - case 'H': // Height. Required. - height = strtol(tokstart, &tokend, 10); - tokstart=tokend; - break; - case 'C': // Color space - if (strncmp("420jpeg",tokstart,7)==0) { - pix_fmt = PIX_FMT_YUV420P; - chroma_sample_location = AVCHROMA_LOC_CENTER; - } else if (strncmp("420mpeg2",tokstart,8)==0) { - pix_fmt = PIX_FMT_YUV420P; - chroma_sample_location = AVCHROMA_LOC_LEFT; - } else if (strncmp("420paldv", tokstart, 8)==0) { - pix_fmt = PIX_FMT_YUV420P; - chroma_sample_location = AVCHROMA_LOC_TOPLEFT; - } else if (strncmp("411", tokstart, 3)==0) - pix_fmt = PIX_FMT_YUV411P; - else if (strncmp("422", tokstart, 3)==0) - pix_fmt = PIX_FMT_YUV422P; - else if (strncmp("444alpha", tokstart, 8)==0) { - av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 YUV4MPEG stream.\n"); - return -1; - } else if (strncmp("444", tokstart, 3)==0) - pix_fmt = PIX_FMT_YUV444P; - else if (strncmp("mono",tokstart, 4)==0) { - pix_fmt = PIX_FMT_GRAY8; - } else { - av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown pixel format.\n"); - return -1; - } - while(tokstartinterlaced_frame=0; - break; - case 't': - s1->interlaced_frame=1; - s1->top_field_first=1; - break; - case 'b': - s1->interlaced_frame=1; - s1->top_field_first=0; - break; - case 'm': - av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed interlaced and non-interlaced frames.\n"); - return -1; - default: - av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n"); - return -1; - } - break; - case 'F': // Frame rate - sscanf(tokstart,"%d:%d",&raten,&rated); // 0:0 if unknown - while(tokstartcodec->width = width; - st->codec->height = height; - av_reduce(&raten, &rated, raten, rated, (1UL<<31)-1); - av_set_pts_info(st, 64, rated, raten); - st->codec->pix_fmt = pix_fmt; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->sample_aspect_ratio= (AVRational){aspectn, aspectd}; - st->codec->chroma_sample_location = chroma_sample_location; - - return 0; -} - -static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int i; - char header[MAX_FRAME_HEADER+1]; - int packet_size, width, height; - AVStream *st = s->streams[0]; - struct frame_attributes *s1 = s->priv_data; - - for (i=0; ipb); - if (header[i] == '\n') { - header[i+1] = 0; - break; - } - } - if (i == MAX_FRAME_HEADER) return -1; - if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) return -1; - - width = st->codec->width; - height = st->codec->height; - - packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); - if (packet_size < 0) - return -1; - - if (av_get_packet(s->pb, pkt, packet_size) != packet_size) - return AVERROR(EIO); - - if (s->streams[0]->codec->coded_frame) { - s->streams[0]->codec->coded_frame->interlaced_frame = s1->interlaced_frame; - s->streams[0]->codec->coded_frame->top_field_first = s1->top_field_first; - } - - pkt->stream_index = 0; - return 0; -} - -static int yuv4_probe(AVProbeData *pd) -{ - /* check file header */ - if (strncmp(pd->buf, Y4M_MAGIC, sizeof(Y4M_MAGIC)-1)==0) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -#if CONFIG_YUV4MPEGPIPE_DEMUXER -AVInputFormat yuv4mpegpipe_demuxer = { - "yuv4mpegpipe", - NULL_IF_CONFIG_SMALL("YUV4MPEG pipe format"), - sizeof(struct frame_attributes), - yuv4_probe, - yuv4_read_header, - yuv4_read_packet, - .extensions = "y4m" -}; -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/Makefile b/tizen/distrib/ffmpeg/libavutil/Makefile deleted file mode 100644 index 79506c0..0000000 --- a/tizen/distrib/ffmpeg/libavutil/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = avutil - -HEADERS = adler32.h \ - attributes.h \ - avstring.h \ - avutil.h \ - base64.h \ - common.h \ - crc.h \ - error.h \ - fifo.h \ - intfloat_readwrite.h \ - log.h \ - lzo.h \ - mathematics.h \ - md5.h \ - mem.h \ - pixdesc.h \ - pixfmt.h \ - rational.h \ - sha1.h \ - -BUILT_HEADERS = avconfig.h - -OBJS = adler32.o \ - aes.o \ - avstring.o \ - base64.o \ - crc.o \ - des.o \ - error.o \ - fifo.o \ - intfloat_readwrite.o \ - lfg.o \ - lls.o \ - log.o \ - lzo.o \ - mathematics.o \ - md5.o \ - mem.o \ - pixdesc.o \ - random_seed.o \ - rational.o \ - rc4.o \ - sha.o \ - tree.o \ - utils.o \ - -TESTPROGS = adler32 aes base64 crc des lls md5 pca sha softfloat tree -TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo - -DIRS = arm bfin sh4 x86 - -ARCH_HEADERS = bswap.h intmath.h intreadwrite.h timer.h - -include $(SUBDIR)../subdir.mak - -$(SUBDIR)lzo-test$(EXESUF): ELIBS = -llzo2 diff --git a/tizen/distrib/ffmpeg/libavutil/adler32.c b/tizen/distrib/ffmpeg/libavutil/adler32.c deleted file mode 100644 index 4f20010..0000000 --- a/tizen/distrib/ffmpeg/libavutil/adler32.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Compute the Adler-32 checksum of a data stream. - * This is a modified version based on adler32.c from the zlib library. - * - * Copyright (C) 1995 Mark Adler - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include "config.h" -#include "adler32.h" - -#define BASE 65521L /* largest prime smaller than 65536 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO4(buf) DO1(buf); DO1(buf); DO1(buf); DO1(buf); -#define DO16(buf) DO4(buf); DO4(buf); DO4(buf); DO4(buf); - -unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, unsigned int len) -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = adler >> 16; - - while (len>0) { -#if CONFIG_SMALL - while(len>4 && s2 < (1U<<31)){ - DO4(buf); len-=4; -#else - while(len>16 && s2 < (1U<<31)){ - DO16(buf); len-=16; -#endif - } - DO1(buf); len--; - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} - -#ifdef TEST -#include "log.h" -#include "timer.h" -#define LEN 7001 -volatile int checksum; -int main(void){ - int i; - char data[LEN]; - av_log_set_level(AV_LOG_DEBUG); - for(i=0; i>3) + 123*i; - for(i=0; i<1000; i++){ - START_TIMER - checksum= av_adler32_update(1, data, LEN); - STOP_TIMER("adler") - } - av_log(NULL, AV_LOG_DEBUG, "%X == 50E6E508\n", checksum); - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/adler32.h b/tizen/distrib/ffmpeg/libavutil/adler32.h deleted file mode 100644 index 9626c80..0000000 --- a/tizen/distrib/ffmpeg/libavutil/adler32.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * copyright (c) 2006 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ADLER32_H -#define AVUTIL_ADLER32_H - -#include -#include "attributes.h" - -unsigned long av_adler32_update(unsigned long adler, const uint8_t *buf, - unsigned int len) av_pure; - -#endif /* AVUTIL_ADLER32_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/aes.c b/tizen/distrib/ffmpeg/libavutil/aes.c deleted file mode 100644 index d3a271c..0000000 --- a/tizen/distrib/ffmpeg/libavutil/aes.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * copyright (c) 2007 Michael Niedermayer - * - * some optimization ideas from aes128.c by Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "common.h" -#include "aes.h" - -typedef struct AVAES{ - // Note: round_key[16] is accessed in the init code, but this only - // overwrites state, which does not matter (see also r7471). - uint8_t round_key[15][4][4]; - uint8_t state[2][4][4]; - int rounds; -}AVAES; - -const int av_aes_size= sizeof(AVAES); - -static const uint8_t rcon[10] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 -}; - -static uint8_t sbox[256]; -static uint8_t inv_sbox[256]; -#if CONFIG_SMALL -static uint32_t enc_multbl[1][256]; -static uint32_t dec_multbl[1][256]; -#else -static uint32_t enc_multbl[4][256]; -static uint32_t dec_multbl[4][256]; -#endif - -static inline void addkey(uint64_t dst[2], const uint64_t src[2], const uint64_t round_key[2]){ - dst[0] = src[0] ^ round_key[0]; - dst[1] = src[1] ^ round_key[1]; -} - -static void subshift(uint8_t s0[2][16], int s, const uint8_t *box){ - uint8_t (*s1)[16]= s0[0] - s; - uint8_t (*s3)[16]= s0[0] + s; - s0[0][0]=box[s0[1][ 0]]; s0[0][ 4]=box[s0[1][ 4]]; s0[0][ 8]=box[s0[1][ 8]]; s0[0][12]=box[s0[1][12]]; - s1[0][3]=box[s1[1][ 7]]; s1[0][ 7]=box[s1[1][11]]; s1[0][11]=box[s1[1][15]]; s1[0][15]=box[s1[1][ 3]]; - s0[0][2]=box[s0[1][10]]; s0[0][10]=box[s0[1][ 2]]; s0[0][ 6]=box[s0[1][14]]; s0[0][14]=box[s0[1][ 6]]; - s3[0][1]=box[s3[1][13]]; s3[0][13]=box[s3[1][ 9]]; s3[0][ 9]=box[s3[1][ 5]]; s3[0][ 5]=box[s3[1][ 1]]; -} - -static inline int mix_core(uint32_t multbl[4][256], int a, int b, int c, int d){ -#if CONFIG_SMALL -#define ROT(x,s) ((x<>(32-s))) - return multbl[0][a] ^ ROT(multbl[0][b], 8) ^ ROT(multbl[0][c], 16) ^ ROT(multbl[0][d], 24); -#else - return multbl[0][a] ^ multbl[1][b] ^ multbl[2][c] ^ multbl[3][d]; -#endif -} - -static inline void mix(uint8_t state[2][4][4], uint32_t multbl[4][256], int s1, int s3){ - ((uint32_t *)(state))[0] = mix_core(multbl, state[1][0][0], state[1][s1 ][1], state[1][2][2], state[1][s3 ][3]); - ((uint32_t *)(state))[1] = mix_core(multbl, state[1][1][0], state[1][s3-1][1], state[1][3][2], state[1][s1-1][3]); - ((uint32_t *)(state))[2] = mix_core(multbl, state[1][2][0], state[1][s3 ][1], state[1][0][2], state[1][s1 ][3]); - ((uint32_t *)(state))[3] = mix_core(multbl, state[1][3][0], state[1][s1-1][1], state[1][1][2], state[1][s3-1][3]); -} - -static inline void crypt(AVAES *a, int s, const uint8_t *sbox, const uint32_t *multbl){ - int r; - - for(r=a->rounds-1; r>0; r--){ - mix(a->state, multbl, 3-s, 1+s); - addkey(a->state[1], a->state[0], a->round_key[r]); - } - subshift(a->state[0][0], s, sbox); -} - -void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt){ - while(count--){ - addkey(a->state[1], src, a->round_key[a->rounds]); - if(decrypt) { - crypt(a, 0, inv_sbox, dec_multbl); - if(iv){ - addkey(a->state[0], a->state[0], iv); - memcpy(iv, src, 16); - } - addkey(dst, a->state[0], a->round_key[0]); - }else{ - if(iv) addkey(a->state[1], a->state[1], iv); - crypt(a, 2, sbox, enc_multbl); - addkey(dst, a->state[0], a->round_key[0]); - if(iv) memcpy(iv, dst, 16); - } - src+=16; - dst+=16; - } -} - -static void init_multbl2(uint8_t tbl[1024], const int c[4], const uint8_t *log8, const uint8_t *alog8, const uint8_t *sbox){ - int i, j; - for(i=0; i<1024; i++){ - int x= sbox[i>>2]; - if(x) tbl[i]= alog8[ log8[x] + log8[c[i&3]] ]; - } -#if !CONFIG_SMALL - for(j=256; j<1024; j++) - for(i=0; i<4; i++) - tbl[4*j+i]= tbl[4*j + ((i-1)&3) - 1024]; -#endif -} - -// this is based on the reference AES code by Paulo Barreto and Vincent Rijmen -int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) { - int i, j, t, rconpointer = 0; - uint8_t tk[8][4]; - int KC= key_bits>>5; - int rounds= KC + 6; - uint8_t log8[256]; - uint8_t alog8[512]; - - if(!enc_multbl[0][sizeof(enc_multbl)/sizeof(enc_multbl[0][0])-1]){ - j=1; - for(i=0; i<255; i++){ - alog8[i]= - alog8[i+255]= j; - log8[j]= i; - j^= j+j; - if(j>255) j^= 0x11B; - } - for(i=0; i<256; i++){ - j= i ? alog8[255-log8[i]] : 0; - j ^= (j<<1) ^ (j<<2) ^ (j<<3) ^ (j<<4); - j = (j ^ (j>>8) ^ 99) & 255; - inv_sbox[j]= i; - sbox [i]= j; - } - init_multbl2(dec_multbl[0], (const int[4]){0xe, 0x9, 0xd, 0xb}, log8, alog8, inv_sbox); - init_multbl2(enc_multbl[0], (const int[4]){0x2, 0x1, 0x1, 0x3}, log8, alog8, sbox); - } - - if(key_bits!=128 && key_bits!=192 && key_bits!=256) - return -1; - - a->rounds= rounds; - - memcpy(tk, key, KC*4); - - for(t= 0; t < (rounds+1)*16;) { - memcpy(a->round_key[0][0]+t, tk, KC*4); - t+= KC*4; - - for(i = 0; i < 4; i++) - tk[0][i] ^= sbox[tk[KC-1][(i+1)&3]]; - tk[0][0] ^= rcon[rconpointer++]; - - for(j = 1; j < KC; j++){ - if(KC != 8 || j != KC>>1) - for(i = 0; i < 4; i++) tk[j][i] ^= tk[j-1][i]; - else - for(i = 0; i < 4; i++) tk[j][i] ^= sbox[tk[j-1][i]]; - } - } - - if(decrypt){ - for(i=1; iround_key[i][0], 16); - subshift(tmp[1], 0, sbox); - mix(tmp, dec_multbl, 1, 3); - memcpy(a->round_key[i][0], tmp[0], 16); - } - }else{ - for(i=0; i<(rounds+1)>>1; i++){ - for(j=0; j<16; j++) - FFSWAP(int, a->round_key[i][0][j], a->round_key[rounds-i][0][j]); - } - } - - return 0; -} - -#ifdef TEST -#include "lfg.h" -#include "log.h" - -int main(void){ - int i,j; - AVAES ae, ad, b; - uint8_t rkey[2][16]= { - {0}, - {0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59}}; - uint8_t pt[16], rpt[2][16]= { - {0x6a, 0x84, 0x86, 0x7c, 0xd7, 0x7e, 0x12, 0xad, 0x07, 0xea, 0x1b, 0xe8, 0x95, 0xc5, 0x3f, 0xa3}, - {0}}; - uint8_t rct[2][16]= { - {0x73, 0x22, 0x81, 0xc0, 0xa0, 0xaa, 0xb8, 0xf7, 0xa5, 0x4a, 0x0c, 0x67, 0xa0, 0xc4, 0x5e, 0xcf}, - {0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65}}; - uint8_t temp[16]; - AVLFG prng; - - av_aes_init(&ae, "PI=3.141592654..", 128, 0); - av_aes_init(&ad, "PI=3.141592654..", 128, 1); - av_log_set_level(AV_LOG_DEBUG); - av_lfg_init(&prng, 1); - - for(i=0; i<2; i++){ - av_aes_init(&b, rkey[i], 128, 1); - av_aes_crypt(&b, temp, rct[i], 1, NULL, 1); - for(j=0; j<16; j++) - if(rpt[i][j] != temp[j]) - av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n", j, rpt[i][j], temp[j]); - } - - for(i=0; i<10000; i++){ - for(j=0; j<16; j++){ - pt[j] = av_lfg_get(&prng); - } -{START_TIMER - av_aes_crypt(&ae, temp, pt, 1, NULL, 0); - if(!(i&(i-1))) - av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n", temp[0], temp[5], temp[10], temp[15]); - av_aes_crypt(&ad, temp, temp, 1, NULL, 1); -STOP_TIMER("aes")} - for(j=0; j<16; j++){ - if(pt[j] != temp[j]){ - av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n", i,j, pt[j], temp[j]); - } - } - } - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/aes.h b/tizen/distrib/ffmpeg/libavutil/aes.h deleted file mode 100644 index 1ca853d..0000000 --- a/tizen/distrib/ffmpeg/libavutil/aes.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * copyright (c) 2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AES_H -#define AVUTIL_AES_H - -#include - -extern const int av_aes_size; - -struct AVAES; - -/** - * Initializes an AVAES context. - * @param key_bits 128, 192 or 256 - * @param decrypt 0 for encryption, 1 for decryption - */ -int av_aes_init(struct AVAES *a, const uint8_t *key, int key_bits, int decrypt); - -/** - * Encrypts / decrypts. - * @param count number of 16 byte blocks - * @param dst destination array, can be equal to src - * @param src source array, can be equal to dst - * @param iv initialization vector for CBC mode, if NULL then ECB will be used - * @param decrypt 0 for encryption, 1 for decryption - */ -void av_aes_crypt(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); - -#endif /* AVUTIL_AES_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/arm/bswap.h b/tizen/distrib/ffmpeg/libavutil/arm/bswap.h deleted file mode 100644 index 9126350..0000000 --- a/tizen/distrib/ffmpeg/libavutil/arm/bswap.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ARM_BSWAP_H -#define AVUTIL_ARM_BSWAP_H - -#include -#include "config.h" -#include "libavutil/attributes.h" - -#ifdef __ARMCC_VERSION - -#if HAVE_ARMV6 -#define bswap_16 bswap_16 -static av_always_inline av_const unsigned bswap_16(unsigned x) -{ - __asm { rev16 x, x } - return x; -} - -#define bswap_32 bswap_32 -static av_always_inline av_const uint32_t bswap_32(uint32_t x) -{ - return __rev(x); -} -#endif /* HAVE_ARMV6 */ - -#elif HAVE_INLINE_ASM - -#if HAVE_ARMV6 -#define bswap_16 bswap_16 -static av_always_inline av_const unsigned bswap_16(unsigned x) -{ - __asm__("rev16 %0, %0" : "+r"(x)); - return x; -} -#endif - -#define bswap_32 bswap_32 -static av_always_inline av_const uint32_t bswap_32(uint32_t x) -{ -#if HAVE_ARMV6 - __asm__("rev %0, %0" : "+r"(x)); -#else - uint32_t t; - __asm__ ("eor %1, %0, %0, ror #16 \n\t" - "bic %1, %1, #0xFF0000 \n\t" - "mov %0, %0, ror #8 \n\t" - "eor %0, %0, %1, lsr #8 \n\t" - : "+r"(x), "=&r"(t)); -#endif /* HAVE_ARMV6 */ - return x; -} - -#endif /* __ARMCC_VERSION */ - -#endif /* AVUTIL_ARM_BSWAP_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/arm/intmath.h b/tizen/distrib/ffmpeg/libavutil/arm/intmath.h deleted file mode 100644 index 48a05ea..0000000 --- a/tizen/distrib/ffmpeg/libavutil/arm/intmath.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ARM_INTMATH_H -#define AVUTIL_ARM_INTMATH_H - -#include "config.h" -#include "libavutil/attributes.h" - -#if HAVE_INLINE_ASM - -#if HAVE_ARMV6 -static inline av_const int FASTDIV(int a, int b) -{ - int r, t; - __asm__ volatile("cmp %3, #2 \n\t" - "ldr %1, [%4, %3, lsl #2] \n\t" - "lsrle %0, %2, #1 \n\t" - "smmulgt %0, %1, %2 \n\t" - : "=&r"(r), "=&r"(t) : "r"(a), "r"(b), "r"(ff_inverse)); - return r; -} -#else -static inline av_const int FASTDIV(int a, int b) -{ - int r, t; - __asm__ volatile("umull %1, %0, %2, %3" - : "=&r"(r), "=&r"(t) : "r"(a), "r"(ff_inverse[b])); - return r; -} -#endif - -#define FASTDIV FASTDIV - -#endif /* HAVE_INLINE_ASM */ - -#endif /* AVUTIL_ARM_INTMATH_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/arm/intreadwrite.h b/tizen/distrib/ffmpeg/libavutil/arm/intreadwrite.h deleted file mode 100644 index 011694d..0000000 --- a/tizen/distrib/ffmpeg/libavutil/arm/intreadwrite.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ARM_INTREADWRITE_H -#define AVUTIL_ARM_INTREADWRITE_H - -#include -#include "config.h" - -#if HAVE_FAST_UNALIGNED && HAVE_INLINE_ASM - -#define AV_RN16 AV_RN16 -static av_always_inline uint16_t AV_RN16(const void *p) -{ - uint16_t v; - __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(*(const uint16_t *)p)); - return v; -} - -#define AV_WN16 AV_WN16 -static av_always_inline void AV_WN16(void *p, uint16_t v) -{ - __asm__ ("strh %1, %0" : "=m"(*(uint16_t *)p) : "r"(v)); -} - -#define AV_RN32 AV_RN32 -static av_always_inline uint32_t AV_RN32(const void *p) -{ - uint32_t v; - __asm__ ("ldr %0, %1" : "=r"(v) : "m"(*(const uint32_t *)p)); - return v; -} - -#define AV_WN32 AV_WN32 -static av_always_inline void AV_WN32(void *p, uint32_t v) -{ - __asm__ ("str %1, %0" : "=m"(*(uint32_t *)p) : "r"(v)); -} - -#define AV_RN64 AV_RN64 -static av_always_inline uint64_t AV_RN64(const void *p) -{ - union { uint64_t v; uint32_t hl[2]; } v; - __asm__ ("ldr %0, %2 \n\t" - "ldr %1, %3 \n\t" - : "=&r"(v.hl[0]), "=r"(v.hl[1]) - : "m"(*(const uint32_t*)p), "m"(*((const uint32_t*)p+1))); - return v.v; -} - -#define AV_WN64 AV_WN64 -static av_always_inline void AV_WN64(void *p, uint64_t v) -{ - union { uint64_t v; uint32_t hl[2]; } vv = { v }; - __asm__ ("str %2, %0 \n\t" - "str %3, %1 \n\t" - : "=m"(*(uint32_t*)p), "=m"(*((uint32_t*)p+1)) - : "r"(vv.hl[0]), "r"(vv.hl[1])); -} - -#endif /* HAVE_INLINE_ASM */ - -#endif /* AVUTIL_ARM_INTREADWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/arm/timer.h b/tizen/distrib/ffmpeg/libavutil/arm/timer.h deleted file mode 100644 index 5e8bc8e..0000000 --- a/tizen/distrib/ffmpeg/libavutil/arm/timer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_ARM_TIMER_H -#define AVUTIL_ARM_TIMER_H - -#include -#include "config.h" - -#if HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) - -#define AV_READ_TIME read_time - -static inline uint64_t read_time(void) -{ - unsigned cc; - __asm__ volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cc)); - return cc; -} - -#endif /* HAVE_INLINE_ASM && __ARM_ARCH_7A__ */ - -#endif /* AVUTIL_ARM_TIMER_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/attributes.h b/tizen/distrib/ffmpeg/libavutil/attributes.h deleted file mode 100644 index da45234..0000000 --- a/tizen/distrib/ffmpeg/libavutil/attributes.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Macro definitions for various function/variable attributes - */ - -#ifndef AVUTIL_ATTRIBUTES_H -#define AVUTIL_ATTRIBUTES_H - -#ifdef __GNUC__ -# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y) -#else -# define AV_GCC_VERSION_AT_LEAST(x,y) 0 -#endif - -#ifndef av_always_inline -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_always_inline __attribute__((always_inline)) inline -#else -# define av_always_inline inline -#endif -#endif - -#ifndef av_noinline -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_noinline __attribute__((noinline)) -#else -# define av_noinline -#endif -#endif - -#ifndef av_pure -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define av_pure __attribute__((pure)) -#else -# define av_pure -#endif -#endif - -#ifndef av_const -#if AV_GCC_VERSION_AT_LEAST(2,6) -# define av_const __attribute__((const)) -#else -# define av_const -#endif -#endif - -#ifndef av_cold -#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) -# define av_cold __attribute__((cold)) -#else -# define av_cold -#endif -#endif - -#ifndef av_flatten -#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,1) -# define av_flatten __attribute__((flatten)) -#else -# define av_flatten -#endif -#endif - -#ifndef attribute_deprecated -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define attribute_deprecated __attribute__((deprecated)) -#else -# define attribute_deprecated -#endif -#endif - -#ifndef av_unused -#if defined(__GNUC__) -# define av_unused __attribute__((unused)) -#else -# define av_unused -#endif -#endif - -#ifndef av_uninit -#if defined(__GNUC__) && !defined(__ICC) -# define av_uninit(x) x=x -#else -# define av_uninit(x) x -#endif -#endif - -#ifdef __GNUC__ -# define av_builtin_constant_p __builtin_constant_p -#else -# define av_builtin_constant_p(x) 0 -#endif - -#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/avr32/bswap.h b/tizen/distrib/ffmpeg/libavutil/avr32/bswap.h deleted file mode 100644 index e8c8ddc..0000000 --- a/tizen/distrib/ffmpeg/libavutil/avr32/bswap.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AVR32_BSWAP_H -#define AVUTIL_AVR32_BSWAP_H - -#include -#include "config.h" -#include "libavutil/attributes.h" - -#if HAVE_INLINE_ASM - -#define bswap_16 bswap_16 -static av_always_inline av_const uint16_t bswap_16(uint16_t x) -{ - __asm__ ("swap.bh %0" : "+r"(x)); - return x; -} - -#define bswap_32 bswap_32 -static av_always_inline av_const uint32_t bswap_32(uint32_t x) -{ - __asm__ ("swap.b %0" : "+r"(x)); - return x; -} - -#endif /* HAVE_INLINE_ASM */ - -#endif /* AVUTIL_AVR32_BSWAP_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/avr32/intreadwrite.h b/tizen/distrib/ffmpeg/libavutil/avr32/intreadwrite.h deleted file mode 100644 index 3e468b4..0000000 --- a/tizen/distrib/ffmpeg/libavutil/avr32/intreadwrite.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AVR32_INTREADWRITE_H -#define AVUTIL_AVR32_INTREADWRITE_H - -#include -#include "config.h" -#include "libavutil/bswap.h" - -/* - * AVR32 does not support unaligned memory accesses, except for the AP - * series which suppports unaligned 32-bit loads and stores. 16-bit - * and 64-bit accesses must be aligned to 16 and 32 bits, respectively. - * This means we cannot use the byte-swapping load/store instructions - * here. - * - * For 16-bit, 24-bit, and (on UC series) 32-bit loads, we instead use - * the LDINS.B instruction, which gcc fails to utilise with the - * generic code. GCC also fails to use plain LD.W and ST.W even for - * AP processors, so we override the generic code. The 64-bit - * versions are improved by using our optimised 32-bit functions. - */ - -#define AV_RL16 AV_RL16 -static av_always_inline uint16_t AV_RL16(const void *p) -{ - uint16_t v; - __asm__ ("ld.ub %0, %1 \n\t" - "ldins.b %0:l, %2 \n\t" - : "=&r"(v) - : "m"(*(const uint8_t*)p), "RKs12"(*((const uint8_t*)p+1))); - return v; -} - -#define AV_RB16 AV_RB16 -static av_always_inline uint16_t AV_RB16(const void *p) -{ - uint16_t v; - __asm__ ("ld.ub %0, %2 \n\t" - "ldins.b %0:l, %1 \n\t" - : "=&r"(v) - : "RKs12"(*(const uint8_t*)p), "m"(*((const uint8_t*)p+1))); - return v; -} - -#define AV_RB24 AV_RB24 -static av_always_inline uint32_t AV_RB24(const void *p) -{ - uint32_t v; - __asm__ ("ld.ub %0, %3 \n\t" - "ldins.b %0:l, %2 \n\t" - "ldins.b %0:u, %1 \n\t" - : "=&r"(v) - : "RKs12"(* (const uint8_t*)p), - "RKs12"(*((const uint8_t*)p+1)), - "m" (*((const uint8_t*)p+2))); - return v; -} - -#define AV_RL24 AV_RL24 -static av_always_inline uint32_t AV_RL24(const void *p) -{ - uint32_t v; - __asm__ ("ld.ub %0, %1 \n\t" - "ldins.b %0:l, %2 \n\t" - "ldins.b %0:u, %3 \n\t" - : "=&r"(v) - : "m" (* (const uint8_t*)p), - "RKs12"(*((const uint8_t*)p+1)), - "RKs12"(*((const uint8_t*)p+2))); - return v; -} - -#if ARCH_AVR32_AP - -#define AV_RB32 AV_RB32 -static av_always_inline uint32_t AV_RB32(const void *p) -{ - uint32_t v; - __asm__ ("ld.w %0, %1" : "=r"(v) : "m"(*(const uint32_t*)p)); - return v; -} - -#define AV_WB32 AV_WB32 -static av_always_inline void AV_WB32(void *p, uint32_t v) -{ - __asm__ ("st.w %0, %1" : "=m"(*(uint32_t*)p) : "r"(v)); -} - -/* These two would be defined by generic code, but we need them sooner. */ -#define AV_RL32(p) bswap_32(AV_RB32(p)) -#define AV_WL32(p, v) AV_WB32(p, bswap_32(v)) - -#define AV_WB64 AV_WB64 -static av_always_inline void AV_WB64(void *p, uint64_t v) -{ - union { uint64_t v; uint32_t hl[2]; } vv = { v }; - AV_WB32(p, vv.hl[0]); - AV_WB32((uint32_t*)p+1, vv.hl[1]); -} - -#define AV_WL64 AV_WL64 -static av_always_inline void AV_WL64(void *p, uint64_t v) -{ - union { uint64_t v; uint32_t hl[2]; } vv = { v }; - AV_WL32(p, vv.hl[1]); - AV_WL32((uint32_t*)p+1, vv.hl[0]); -} - -#else /* ARCH_AVR32_AP */ - -#define AV_RB32 AV_RB32 -static av_always_inline uint32_t AV_RB32(const void *p) -{ - uint32_t v; - __asm__ ("ld.ub %0, %4 \n\t" - "ldins.b %0:l, %3 \n\t" - "ldins.b %0:u, %2 \n\t" - "ldins.b %0:t, %1 \n\t" - : "=&r"(v) - : "RKs12"(* (const uint8_t*)p), - "RKs12"(*((const uint8_t*)p+1)), - "RKs12"(*((const uint8_t*)p+2)), - "m" (*((const uint8_t*)p+3))); - return v; -} - -#define AV_RL32 AV_RL32 -static av_always_inline uint32_t AV_RL32(const void *p) -{ - uint32_t v; - __asm__ ("ld.ub %0, %1 \n\t" - "ldins.b %0:l, %2 \n\t" - "ldins.b %0:u, %3 \n\t" - "ldins.b %0:t, %4 \n\t" - : "=&r"(v) - : "m" (* (const uint8_t*)p), - "RKs12"(*((const uint8_t*)p+1)), - "RKs12"(*((const uint8_t*)p+2)), - "RKs12"(*((const uint8_t*)p+3))); - return v; -} - -#endif /* ARCH_AVR32_AP */ - -#define AV_RB64 AV_RB64 -static av_always_inline uint64_t AV_RB64(const void *p) -{ - union { uint64_t v; uint32_t hl[2]; } v; - v.hl[0] = AV_RB32(p); - v.hl[1] = AV_RB32((const uint32_t*)p+1); - return v.v; -} - -#define AV_RL64 AV_RL64 -static av_always_inline uint64_t AV_RL64(const void *p) -{ - union { uint64_t v; uint32_t hl[2]; } v; - v.hl[1] = AV_RL32(p); - v.hl[0] = AV_RL32((const uint32_t*)p+1); - return v.v; -} - -#endif /* AVUTIL_AVR32_INTREADWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/avstring.c b/tizen/distrib/ffmpeg/libavutil/avstring.c deleted file mode 100644 index 4844e28..0000000 --- a/tizen/distrib/ffmpeg/libavutil/avstring.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2007 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include "avstring.h" -#include "mem.h" - -int av_strstart(const char *str, const char *pfx, const char **ptr) -{ - while (*pfx && *pfx == *str) { - pfx++; - str++; - } - if (!*pfx && ptr) - *ptr = str; - return !*pfx; -} - -int av_stristart(const char *str, const char *pfx, const char **ptr) -{ - while (*pfx && toupper((unsigned)*pfx) == toupper((unsigned)*str)) { - pfx++; - str++; - } - if (!*pfx && ptr) - *ptr = str; - return !*pfx; -} - -char *av_stristr(const char *s1, const char *s2) -{ - if (!*s2) - return s1; - - do { - if (av_stristart(s1, s2, NULL)) - return s1; - } while (*s1++); - - return NULL; -} - -size_t av_strlcpy(char *dst, const char *src, size_t size) -{ - size_t len = 0; - while (++len < size && *src) - *dst++ = *src++; - if (len <= size) - *dst = 0; - return len + strlen(src) - 1; -} - -size_t av_strlcat(char *dst, const char *src, size_t size) -{ - size_t len = strlen(dst); - if (size <= len + 1) - return len + strlen(src); - return len + av_strlcpy(dst + len, src, size - len); -} - -size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) -{ - int len = strlen(dst); - va_list vl; - - va_start(vl, fmt); - len += vsnprintf(dst + len, size > len ? size - len : 0, fmt, vl); - va_end(vl); - - return len; -} - -char *av_d2str(double d) -{ - char *str= av_malloc(16); - if(str) snprintf(str, 16, "%f", d); - return str; -} diff --git a/tizen/distrib/ffmpeg/libavutil/avstring.h b/tizen/distrib/ffmpeg/libavutil/avstring.h deleted file mode 100644 index 01c2391..0000000 --- a/tizen/distrib/ffmpeg/libavutil/avstring.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2007 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AVSTRING_H -#define AVUTIL_AVSTRING_H - -#include - -/** - * Return non-zero if pfx is a prefix of str. If it is, *ptr is set to - * the address of the first character in str after the prefix. - * - * @param str input string - * @param pfx prefix to test - * @param ptr updated if the prefix is matched inside str - * @return non-zero if the prefix matches, zero otherwise - */ -int av_strstart(const char *str, const char *pfx, const char **ptr); - -/** - * Return non-zero if pfx is a prefix of str independent of case. If - * it is, *ptr is set to the address of the first character in str - * after the prefix. - * - * @param str input string - * @param pfx prefix to test - * @param ptr updated if the prefix is matched inside str - * @return non-zero if the prefix matches, zero otherwise - */ -int av_stristart(const char *str, const char *pfx, const char **ptr); - -/** - * Locate the first case-independent occurrence in the string haystack - * of the string needle. A zero-length string needle is considered to - * match at the start of haystack. - * - * This function is a case-insensitive version of the standard strstr(). - * - * @param haystack string to search in - * @param needle string to search for - * @return pointer to the located match within haystack - * or a null pointer if no match - */ -char *av_stristr(const char *haystack, const char *needle); - -/** - * Copy the string src to dst, but no more than size - 1 bytes, and - * null-terminate dst. - * - * This function is the same as BSD strlcpy(). - * - * @param dst destination buffer - * @param src source string - * @param size size of destination buffer - * @return the length of src - * - * WARNING: since the return value is the length of src, src absolutely - * _must_ be a properly 0-terminated string, otherwise this will read beyond - * the end of the buffer and possibly crash. - */ -size_t av_strlcpy(char *dst, const char *src, size_t size); - -/** - * Append the string src to the string dst, but to a total length of - * no more than size - 1 bytes, and null-terminate dst. - * - * This function is similar to BSD strlcat(), but differs when - * size <= strlen(dst). - * - * @param dst destination buffer - * @param src source string - * @param size size of destination buffer - * @return the total length of src and dst - * - * WARNING: since the return value use the length of src and dst, these absolutely - * _must_ be a properly 0-terminated strings, otherwise this will read beyond - * the end of the buffer and possibly crash. - */ -size_t av_strlcat(char *dst, const char *src, size_t size); - -/** - * Append output to a string, according to a format. Never write out of - * the destination buffer, and always put a terminating 0 within - * the buffer. - * @param dst destination buffer (string to which the output is - * appended) - * @param size total size of the destination buffer - * @param fmt printf-compatible format string, specifying how the - * following parameters are used - * @return the length of the string that would have been generated - * if enough space had been available - */ -size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...); - -/** - * Convert a number to a av_malloced string. - */ -char *av_d2str(double d); - -#endif /* AVUTIL_AVSTRING_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/avutil.h b/tizen/distrib/ffmpeg/libavutil/avutil.h deleted file mode 100644 index e9e07b9..0000000 --- a/tizen/distrib/ffmpeg/libavutil/avutil.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_AVUTIL_H -#define AVUTIL_AVUTIL_H - -/** - * @file - * external API header - */ - - -#define AV_STRINGIFY(s) AV_TOSTRING(s) -#define AV_TOSTRING(s) #s - -#define AV_GLUE(a, b) a ## b -#define AV_JOIN(a, b) AV_GLUE(a, b) - -#define AV_PRAGMA(s) _Pragma(#s) - -#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) -#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c -#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) - -#define LIBAVUTIL_VERSION_MAJOR 50 -#define LIBAVUTIL_VERSION_MINOR 15 -#define LIBAVUTIL_VERSION_MICRO 1 - -#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ - LIBAVUTIL_VERSION_MINOR, \ - LIBAVUTIL_VERSION_MICRO) -#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ - LIBAVUTIL_VERSION_MINOR, \ - LIBAVUTIL_VERSION_MICRO) -#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT - -#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) - -/** - * Returns the LIBAVUTIL_VERSION_INT constant. - */ -unsigned avutil_version(void); - -/** - * Returns the libavutil build-time configuration. - */ -const char *avutil_configuration(void); - -/** - * Returns the libavutil license. - */ -const char *avutil_license(void); - -enum AVMediaType { - AVMEDIA_TYPE_UNKNOWN = -1, - AVMEDIA_TYPE_VIDEO, - AVMEDIA_TYPE_AUDIO, - AVMEDIA_TYPE_DATA, - AVMEDIA_TYPE_SUBTITLE, - AVMEDIA_TYPE_ATTACHMENT, - AVMEDIA_TYPE_NB -}; - -#include "common.h" -#include "error.h" -#include "mathematics.h" -#include "rational.h" -#include "intfloat_readwrite.h" -#include "log.h" -#include "pixfmt.h" - -#endif /* AVUTIL_AVUTIL_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/base64.c b/tizen/distrib/ffmpeg/libavutil/base64.c deleted file mode 100644 index d84ca36..0000000 --- a/tizen/distrib/ffmpeg/libavutil/base64.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * @brief Base64 encode/decode - * @author Ryan Martell (with lots of Michael) - */ - -#include "common.h" -#include "base64.h" - -/* ---------------- private code */ -static const uint8_t map2[] = -{ - 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 -}; - -int av_base64_decode(uint8_t *out, const char *in, int out_size) -{ - int i, v; - uint8_t *dst = out; - - v = 0; - for (i = 0; in[i] && in[i] != '='; i++) { - unsigned int index= in[i]-43; - if (index>=FF_ARRAY_ELEMS(map2) || map2[index] == 0xff) - return -1; - v = (v << 6) + map2[index]; - if (i & 3) { - if (dst - out < out_size) { - *dst++ = v >> (6 - 2 * (i & 3)); - } - } - } - - return dst - out; -} - -/***************************************************************************** -* b64_encode: Stolen from VLC's http.c. -* Simplified by Michael. -* Fixed edge cases and made it work from data (vs. strings) by Ryan. -*****************************************************************************/ - -char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size) -{ - static const char b64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - char *ret, *dst; - unsigned i_bits = 0; - int i_shift = 0; - int bytes_remaining = in_size; - - if (in_size >= UINT_MAX / 4 || - out_size < (in_size+2) / 3 * 4 + 1) - return NULL; - ret = dst = out; - while (bytes_remaining) { - i_bits = (i_bits << 8) + *in++; - bytes_remaining--; - i_shift += 8; - - do { - *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; - i_shift -= 6; - } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0)); - } - while ((dst - ret) & 3) - *dst++ = '='; - *dst = '\0'; - - return ret; -} - -#ifdef TEST - -#undef printf - -#define MAX_DATA_SIZE 1024 -#define MAX_ENCODED_SIZE 2048 - -static int test_encode_decode(const uint8_t *data, unsigned int data_size, - const char *encoded_ref) -{ - char encoded[MAX_ENCODED_SIZE]; - uint8_t data2[MAX_DATA_SIZE]; - int data2_size, max_data2_size = MAX_DATA_SIZE; - - if (!av_base64_encode(encoded, MAX_ENCODED_SIZE, data, data_size)) { - printf("Failed: cannot encode the input data\n"); - return 1; - } - if (encoded_ref && strcmp(encoded, encoded_ref)) { - printf("Failed: encoded string differs from reference\n" - "Encoded:\n%s\nReference:\n%s\n", encoded, encoded_ref); - return 1; - } - - if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) < 0) { - printf("Failed: cannot decode the encoded string\n" - "Encoded:\n%s\n", encoded); - return 1; - } - if (memcmp(data2, data, data_size)) { - printf("Failed: encoded/decoded data differs from original data\n"); - return 1; - } - - printf("Passed!\n"); - return 0; -} - -int main(void) -{ - int i, error_count = 0; - struct test { - const uint8_t *data; - const char *encoded_ref; - } tests[] = { - { "", ""}, - { "1", "MQ=="}, - { "22", "MjI="}, - { "333", "MzMz"}, - { "4444", "NDQ0NA=="}, - { "55555", "NTU1NTU="}, - { "666666", "NjY2NjY2"}, - { "abc:def", "YWJjOmRlZg=="}, - }; - - printf("Encoding/decoding tests\n"); - for (i = 0; i < FF_ARRAY_ELEMS(tests); i++) - error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref); - - return error_count; -} - -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/base64.h b/tizen/distrib/ffmpeg/libavutil/base64.h deleted file mode 100644 index 103860e..0000000 --- a/tizen/distrib/ffmpeg/libavutil/base64.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_BASE64_H -#define AVUTIL_BASE64_H - -#include - -/** - * Decodes the base64-encoded string in in and puts the decoded - * data in out. - * - * @param out_size size in bytes of the out buffer, it should be at - * least 3/4 of the length of in - * @return the number of bytes written, or a negative value in case of - * error - */ -int av_base64_decode(uint8_t *out, const char *in, int out_size); - -/** - * Encodes in base64 the data in in and puts the resulting string - * in out. - * - * @param out_size size in bytes of the out string, it should be at - * least ((in_size + 2) / 3) * 4 + 1 - * @param in_size size in bytes of the in buffer - * @return the string containing the encoded data, or NULL in case of - * error - */ -char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size); - -#endif /* AVUTIL_BASE64_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/bfin/bswap.h b/tizen/distrib/ffmpeg/libavutil/bfin/bswap.h deleted file mode 100644 index ccdfeb7..0000000 --- a/tizen/distrib/ffmpeg/libavutil/bfin/bswap.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * byte swapping routines - */ - -#ifndef AVUTIL_BFIN_BSWAP_H -#define AVUTIL_BFIN_BSWAP_H - -#include -#include "config.h" -#include "libavutil/attributes.h" - -#define bswap_32 bswap_32 -static av_always_inline av_const uint32_t bswap_32(uint32_t x) -{ - unsigned tmp; - __asm__("%1 = %0 >> 8 (V); \n\t" - "%0 = %0 << 8 (V); \n\t" - "%0 = %0 | %1; \n\t" - "%0 = PACK(%0.L, %0.H); \n\t" - : "+d"(x), "=&d"(tmp)); - return x; -} - -#endif /* AVUTIL_BFIN_BSWAP_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/bfin/timer.h b/tizen/distrib/ffmpeg/libavutil/bfin/timer.h deleted file mode 100644 index 644573d..0000000 --- a/tizen/distrib/ffmpeg/libavutil/bfin/timer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2007 Marc Hoffman - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_BFIN_TIMER_H -#define AVUTIL_BFIN_TIMER_H - -#include - -#define AV_READ_TIME read_time - -static inline uint64_t read_time(void) -{ - union { - struct { - unsigned lo; - unsigned hi; - } p; - unsigned long long c; - } t; - __asm__ volatile ("%0=cycles; %1=cycles2;" : "=d" (t.p.lo), "=d" (t.p.hi)); - return t.c; -} - -#endif /* AVUTIL_BFIN_TIMER_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/bswap.h b/tizen/distrib/ffmpeg/libavutil/bswap.h deleted file mode 100644 index 6dd2a35..0000000 --- a/tizen/distrib/ffmpeg/libavutil/bswap.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * byte swapping routines - */ - -#ifndef AVUTIL_BSWAP_H -#define AVUTIL_BSWAP_H - -#include -#include "config.h" -#include "attributes.h" - -#if ARCH_ARM -# include "arm/bswap.h" -#elif ARCH_AVR32 -# include "avr32/bswap.h" -#elif ARCH_BFIN -# include "bfin/bswap.h" -#elif ARCH_SH4 -# include "sh4/bswap.h" -#elif ARCH_X86 -# include "x86/bswap.h" -#endif - -#define AV_BSWAP16C(x) (((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff)) -#define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16)) -#define AV_BSWAP64C(x) (AV_BSWAP32C(x) << 32 | AV_BSWAP32C((x) >> 32)) - -#define AV_BSWAPC(s, x) AV_BSWAP##s##C(x) - -#ifndef bswap_16 -static av_always_inline av_const uint16_t bswap_16(uint16_t x) -{ - x= (x>>8) | (x<<8); - return x; -} -#endif - -#ifndef bswap_32 -static av_always_inline av_const uint32_t bswap_32(uint32_t x) -{ - x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF); - x= (x>>16) | (x<<16); - return x; -} -#endif - -#ifndef bswap_64 -static inline uint64_t av_const bswap_64(uint64_t x) -{ -#if 0 - x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL); - x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL); - return (x>>32) | (x<<32); -#else - union { - uint64_t ll; - uint32_t l[2]; - } w, r; - w.ll = x; - r.l[0] = bswap_32 (w.l[1]); - r.l[1] = bswap_32 (w.l[0]); - return r.ll; -#endif -} -#endif - -// be2me ... big-endian to machine-endian -// le2me ... little-endian to machine-endian - -#if HAVE_BIGENDIAN -#define be2me_16(x) (x) -#define be2me_32(x) (x) -#define be2me_64(x) (x) -#define le2me_16(x) bswap_16(x) -#define le2me_32(x) bswap_32(x) -#define le2me_64(x) bswap_64(x) -#define AV_BE2MEC(s, x) (x) -#define AV_LE2MEC(s, x) AV_BSWAPC(s, x) -#else -#define be2me_16(x) bswap_16(x) -#define be2me_32(x) bswap_32(x) -#define be2me_64(x) bswap_64(x) -#define le2me_16(x) (x) -#define le2me_32(x) (x) -#define le2me_64(x) (x) -#define AV_BE2MEC(s, x) AV_BSWAPC(s, x) -#define AV_LE2MEC(s, x) (x) -#endif - -#define AV_BE2ME16C(x) AV_BE2MEC(16, x) -#define AV_BE2ME32C(x) AV_BE2MEC(32, x) -#define AV_BE2ME64C(x) AV_BE2MEC(64, x) -#define AV_LE2ME16C(x) AV_LE2MEC(16, x) -#define AV_LE2ME32C(x) AV_LE2MEC(32, x) -#define AV_LE2ME64C(x) AV_LE2MEC(64, x) - -#endif /* AVUTIL_BSWAP_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/common.h b/tizen/distrib/ffmpeg/libavutil/common.h deleted file mode 100644 index 4aa00a9..0000000 --- a/tizen/distrib/ffmpeg/libavutil/common.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * common internal and external API header - */ - -#ifndef AVUTIL_COMMON_H -#define AVUTIL_COMMON_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "attributes.h" - -//rounded division & shift -#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) -/* assume b>0 */ -#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) -#define FFSIGN(a) ((a) > 0 ? 1 : -1) - -#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) -#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) -#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) -#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) - -#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) -#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) -#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) - -/* misc math functions */ -extern const uint8_t ff_log2_tab[256]; - -extern const uint8_t av_reverse[256]; - -static inline av_const int av_log2_c(unsigned int v) -{ - int n = 0; - if (v & 0xffff0000) { - v >>= 16; - n += 16; - } - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -static inline av_const int av_log2_16bit_c(unsigned int v) -{ - int n = 0; - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -#ifdef HAVE_AV_CONFIG_H -# include "config.h" -# include "intmath.h" -#endif - -#ifndef av_log2 -# define av_log2 av_log2_c -#endif -#ifndef av_log2_16bit -# define av_log2_16bit av_log2_16bit_c -#endif - -/** - * Clips a signed integer value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static inline av_const int av_clip(int a, int amin, int amax) -{ - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** - * Clips a signed integer value into the 0-255 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const uint8_t av_clip_uint8(int a) -{ - if (a&(~0xFF)) return (-a)>>31; - else return a; -} - -/** - * Clips a signed integer value into the 0-65535 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const uint16_t av_clip_uint16(int a) -{ - if (a&(~0xFFFF)) return (-a)>>31; - else return a; -} - -/** - * Clips a signed integer value into the -32768,32767 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const int16_t av_clip_int16(int a) -{ - if ((a+0x8000) & ~0xFFFF) return (a>>31) ^ 0x7FFF; - else return a; -} - -/** - * Clips a signed 64-bit integer value into the -2147483648,2147483647 range. - * @param a value to clip - * @return clipped value - */ -static inline av_const int32_t av_clipl_int32(int64_t a) -{ - if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF; - else return a; -} - -/** - * Clips a float value into the amin-amax range. - * @param a value to clip - * @param amin minimum value of the clip range - * @param amax maximum value of the clip range - * @return clipped value - */ -static inline av_const float av_clipf(float a, float amin, float amax) -{ - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** Computes ceil(log2(x)). - * @param x value used to compute ceil(log2(x)) - * @return computed ceiling of log2(x) - */ -static inline av_const int av_ceil_log2(int x) -{ - return av_log2((x - 1) << 1); -} - -#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) -#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) - -/*! - * \def GET_UTF8(val, GET_BYTE, ERROR) - * Converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form - * \param val is the output and should be of type uint32_t. It holds the converted - * UCS-4 character and should be a left value. - * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be - * a function or a statement whose return value or evaluated value is of type - * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range, - * and up to 7 times in the general case. - * \param ERROR action that should be taken when an invalid UTF-8 byte is returned - * from GET_BYTE. It should be a statement that jumps out of the macro, - * like exit(), goto, return, break, or continue. - */ -#define GET_UTF8(val, GET_BYTE, ERROR)\ - val= GET_BYTE;\ - {\ - int ones= 7 - av_log2(val ^ 255);\ - if(ones==1)\ - ERROR\ - val&= 127>>ones;\ - while(--ones > 0){\ - int tmp= GET_BYTE - 128;\ - if(tmp>>6)\ - ERROR\ - val= (val<<6) + tmp;\ - }\ - } - -/*! - * \def GET_UTF16(val, GET_16BIT, ERROR) - * Converts a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form - * \param val is the output and should be of type uint32_t. It holds the converted - * UCS-4 character and should be a left value. - * \param GET_16BIT gets two bytes of UTF-16 encoded data converted to native endianness. - * It can be a function or a statement whose return value or evaluated value is of type - * uint16_t. It will be executed up to 2 times. - * \param ERROR action that should be taken when an invalid UTF-16 surrogate is - * returned from GET_BYTE. It should be a statement that jumps out of the macro, - * like exit(), goto, return, break, or continue. - */ -#define GET_UTF16(val, GET_16BIT, ERROR)\ - val = GET_16BIT;\ - {\ - unsigned int hi = val - 0xD800;\ - if (hi < 0x800) {\ - val = GET_16BIT - 0xDC00;\ - if (val > 0x3FFU || hi > 0x3FFU)\ - ERROR\ - val += (hi<<10) + 0x10000;\ - }\ - }\ - -/*! - * \def PUT_UTF8(val, tmp, PUT_BYTE) - * Converts a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). - * \param val is an input-only argument and should be of type uint32_t. It holds - * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If - * val is given as a function it is executed only once. - * \param tmp is a temporary variable and should be of type uint8_t. It - * represents an intermediate value during conversion that is to be - * output by PUT_BYTE. - * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. - * It could be a function or a statement, and uses tmp as the input byte. - * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be - * executed up to 4 times for values in the valid UTF-8 range and up to - * 7 times in the general case, depending on the length of the converted - * Unicode character. - */ -#define PUT_UTF8(val, tmp, PUT_BYTE)\ - {\ - int bytes, shift;\ - uint32_t in = val;\ - if (in < 0x80) {\ - tmp = in;\ - PUT_BYTE\ - } else {\ - bytes = (av_log2(in) + 4) / 5;\ - shift = (bytes - 1) * 6;\ - tmp = (256 - (256 >> bytes)) | (in >> shift);\ - PUT_BYTE\ - while (shift >= 6) {\ - shift -= 6;\ - tmp = 0x80 | ((in >> shift) & 0x3f);\ - PUT_BYTE\ - }\ - }\ - } - -/*! - * \def PUT_UTF16(val, tmp, PUT_16BIT) - * Converts a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). - * \param val is an input-only argument and should be of type uint32_t. It holds - * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If - * val is given as a function it is executed only once. - * \param tmp is a temporary variable and should be of type uint16_t. It - * represents an intermediate value during conversion that is to be - * output by PUT_16BIT. - * \param PUT_16BIT writes the converted UTF-16 data to any proper destination - * in desired endianness. It could be a function or a statement, and uses tmp - * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" - * PUT_BYTE will be executed 1 or 2 times depending on input character. - */ -#define PUT_UTF16(val, tmp, PUT_16BIT)\ - {\ - uint32_t in = val;\ - if (in < 0x10000) {\ - tmp = in;\ - PUT_16BIT\ - } else {\ - tmp = 0xD800 | ((in - 0x10000) >> 10);\ - PUT_16BIT\ - tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ - PUT_16BIT\ - }\ - }\ - - - -#include "mem.h" - -#ifdef HAVE_AV_CONFIG_H -# include "internal.h" -#endif /* HAVE_AV_CONFIG_H */ - -#endif /* AVUTIL_COMMON_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/crc.c b/tizen/distrib/ffmpeg/libavutil/crc.c deleted file mode 100644 index 2719bae..0000000 --- a/tizen/distrib/ffmpeg/libavutil/crc.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "common.h" -#include "bswap.h" -#include "crc.h" - -#if CONFIG_HARDCODED_TABLES -#include "crc_data.h" -#else -static struct { - uint8_t le; - uint8_t bits; - uint32_t poly; -} av_crc_table_params[AV_CRC_MAX] = { - [AV_CRC_8_ATM] = { 0, 8, 0x07 }, - [AV_CRC_16_ANSI] = { 0, 16, 0x8005 }, - [AV_CRC_16_CCITT] = { 0, 16, 0x1021 }, - [AV_CRC_32_IEEE] = { 0, 32, 0x04C11DB7 }, - [AV_CRC_32_IEEE_LE] = { 1, 32, 0xEDB88320 }, -}; -static AVCRC av_crc_table[AV_CRC_MAX][257]; -#endif - -/** - * Initializes a CRC table. - * @param ctx must be an array of size sizeof(AVCRC)*257 or sizeof(AVCRC)*1024 - * @param cts_size size of ctx in bytes - * @param le If 1, the lowest bit represents the coefficient for the highest - * exponent of the corresponding polynomial (both for poly and - * actual CRC). - * If 0, you must swap the CRC parameter and the result of av_crc - * if you need the standard representation (can be simplified in - * most cases to e.g. bswap16): - * bswap_32(crc << (32-bits)) - * @param bits number of bits for the CRC - * @param poly generator polynomial without the x**bits coefficient, in the - * representation as specified by le - * @return <0 on failure - */ -int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){ - int i, j; - uint32_t c; - - if (bits < 8 || bits > 32 || poly >= (1LL<>1)^(poly & (-(c&1))); - ctx[i] = c; - } else { - for (c = i << 24, j = 0; j < 8; j++) - c = (c<<1) ^ ((poly<<(32-bits)) & (((int32_t)c)>>31) ); - ctx[i] = bswap_32(c); - } - } - ctx[256]=1; -#if !CONFIG_SMALL - if(ctx_size >= sizeof(AVCRC)*1024) - for (i = 0; i < 256; i++) - for(j=0; j<3; j++) - ctx[256*(j+1) + i]= (ctx[256*j + i]>>8) ^ ctx[ ctx[256*j + i]&0xFF ]; -#endif - - return 0; -} - -/** - * Gets an initialized standard CRC table. - * @param crc_id ID of a standard CRC - * @return a pointer to the CRC table or NULL on failure - */ -const AVCRC *av_crc_get_table(AVCRCId crc_id){ -#if !CONFIG_HARDCODED_TABLES - if (!av_crc_table[crc_id][FF_ARRAY_ELEMS(av_crc_table[crc_id])-1]) - if (av_crc_init(av_crc_table[crc_id], - av_crc_table_params[crc_id].le, - av_crc_table_params[crc_id].bits, - av_crc_table_params[crc_id].poly, - sizeof(av_crc_table[crc_id])) < 0) - return NULL; -#endif - return av_crc_table[crc_id]; -} - -/** - * Calculates the CRC of a block. - * @param crc CRC of previous blocks if any or initial value for CRC - * @return CRC updated with the data from the given block - * - * @see av_crc_init() "le" parameter - */ -uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length){ - const uint8_t *end= buffer+length; - -#if !CONFIG_SMALL - if(!ctx[256]) { - while(((intptr_t) buffer & 3) && buffer < end) - crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8); - - while(buffer>8 )&0xFF)] - ^ctx[1*256 + ((crc>>16)&0xFF)] - ^ctx[0*256 + ((crc>>24) )]; - } - } -#endif - while(buffer> 8); - - return crc; -} - -#ifdef TEST -#undef printf -int main(void){ - uint8_t buf[1999]; - int i; - int p[4][3]={{AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04}, - {AV_CRC_32_IEEE , 0x04C11DB7, 0xC0F5BAE0}, - {AV_CRC_16_ANSI , 0x8005, 0x1FBB }, - {AV_CRC_8_ATM , 0x07, 0xE3 },}; - const AVCRC *ctx; - - for(i=0; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_CRC_H -#define AVUTIL_CRC_H - -#include -#include -#include "attributes.h" - -typedef uint32_t AVCRC; - -typedef enum { - AV_CRC_8_ATM, - AV_CRC_16_ANSI, - AV_CRC_16_CCITT, - AV_CRC_32_IEEE, - AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */ - AV_CRC_MAX, /*< Not part of public API! Do not use outside libavutil. */ -}AVCRCId; - -int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size); -const AVCRC *av_crc_get_table(AVCRCId crc_id); -uint32_t av_crc(const AVCRC *ctx, uint32_t start_crc, const uint8_t *buffer, size_t length) av_pure; - -#endif /* AVUTIL_CRC_H */ - diff --git a/tizen/distrib/ffmpeg/libavutil/crc_data.h b/tizen/distrib/ffmpeg/libavutil/crc_data.h deleted file mode 100644 index afa25e7..0000000 --- a/tizen/distrib/ffmpeg/libavutil/crc_data.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * copyright (c) 2008 Aurelien Jacobs - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_CRC_DATA_H -#define AVUTIL_CRC_DATA_H - -#include "crc.h" - -static const AVCRC av_crc_table[AV_CRC_MAX][257] = { - [AV_CRC_8_ATM] = { - 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, - 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, - 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, - 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, - 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, - 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, - 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE, - 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, - 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, - 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, - 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, - 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, - 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, - 0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, - 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, - 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, - 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, - 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, - 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7, - 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, - 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, - 0xFA, 0xFD, 0xF4, 0xF3, 0x01 - }, - [AV_CRC_16_ANSI] = { - 0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180, - 0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200, - 0x6380, 0x6600, 0x6C00, 0x6980, 0x7800, 0x7D80, 0x7780, 0x7200, - 0x5000, 0x5580, 0x5F80, 0x5A00, 0x4B80, 0x4E00, 0x4400, 0x4180, - 0xC380, 0xC600, 0xCC00, 0xC980, 0xD800, 0xDD80, 0xD780, 0xD200, - 0xF000, 0xF580, 0xFF80, 0xFA00, 0xEB80, 0xEE00, 0xE400, 0xE180, - 0xA000, 0xA580, 0xAF80, 0xAA00, 0xBB80, 0xBE00, 0xB400, 0xB180, - 0x9380, 0x9600, 0x9C00, 0x9980, 0x8800, 0x8D80, 0x8780, 0x8200, - 0x8381, 0x8601, 0x8C01, 0x8981, 0x9801, 0x9D81, 0x9781, 0x9201, - 0xB001, 0xB581, 0xBF81, 0xBA01, 0xAB81, 0xAE01, 0xA401, 0xA181, - 0xE001, 0xE581, 0xEF81, 0xEA01, 0xFB81, 0xFE01, 0xF401, 0xF181, - 0xD381, 0xD601, 0xDC01, 0xD981, 0xC801, 0xCD81, 0xC781, 0xC201, - 0x4001, 0x4581, 0x4F81, 0x4A01, 0x5B81, 0x5E01, 0x5401, 0x5181, - 0x7381, 0x7601, 0x7C01, 0x7981, 0x6801, 0x6D81, 0x6781, 0x6201, - 0x2381, 0x2601, 0x2C01, 0x2981, 0x3801, 0x3D81, 0x3781, 0x3201, - 0x1001, 0x1581, 0x1F81, 0x1A01, 0x0B81, 0x0E01, 0x0401, 0x0181, - 0x0383, 0x0603, 0x0C03, 0x0983, 0x1803, 0x1D83, 0x1783, 0x1203, - 0x3003, 0x3583, 0x3F83, 0x3A03, 0x2B83, 0x2E03, 0x2403, 0x2183, - 0x6003, 0x6583, 0x6F83, 0x6A03, 0x7B83, 0x7E03, 0x7403, 0x7183, - 0x5383, 0x5603, 0x5C03, 0x5983, 0x4803, 0x4D83, 0x4783, 0x4203, - 0xC003, 0xC583, 0xCF83, 0xCA03, 0xDB83, 0xDE03, 0xD403, 0xD183, - 0xF383, 0xF603, 0xFC03, 0xF983, 0xE803, 0xED83, 0xE783, 0xE203, - 0xA383, 0xA603, 0xAC03, 0xA983, 0xB803, 0xBD83, 0xB783, 0xB203, - 0x9003, 0x9583, 0x9F83, 0x9A03, 0x8B83, 0x8E03, 0x8403, 0x8183, - 0x8002, 0x8582, 0x8F82, 0x8A02, 0x9B82, 0x9E02, 0x9402, 0x9182, - 0xB382, 0xB602, 0xBC02, 0xB982, 0xA802, 0xAD82, 0xA782, 0xA202, - 0xE382, 0xE602, 0xEC02, 0xE982, 0xF802, 0xFD82, 0xF782, 0xF202, - 0xD002, 0xD582, 0xDF82, 0xDA02, 0xCB82, 0xCE02, 0xC402, 0xC182, - 0x4382, 0x4602, 0x4C02, 0x4982, 0x5802, 0x5D82, 0x5782, 0x5202, - 0x7002, 0x7582, 0x7F82, 0x7A02, 0x6B82, 0x6E02, 0x6402, 0x6182, - 0x2002, 0x2582, 0x2F82, 0x2A02, 0x3B82, 0x3E02, 0x3402, 0x3182, - 0x1382, 0x1602, 0x1C02, 0x1982, 0x0802, 0x0D82, 0x0782, 0x0202, - 0x0001 - }, - [AV_CRC_16_CCITT] = { - 0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xA550, 0xC660, 0xE770, - 0x0881, 0x2991, 0x4AA1, 0x6BB1, 0x8CC1, 0xADD1, 0xCEE1, 0xEFF1, - 0x3112, 0x1002, 0x7332, 0x5222, 0xB552, 0x9442, 0xF772, 0xD662, - 0x3993, 0x1883, 0x7BB3, 0x5AA3, 0xBDD3, 0x9CC3, 0xFFF3, 0xDEE3, - 0x6224, 0x4334, 0x2004, 0x0114, 0xE664, 0xC774, 0xA444, 0x8554, - 0x6AA5, 0x4BB5, 0x2885, 0x0995, 0xEEE5, 0xCFF5, 0xACC5, 0x8DD5, - 0x5336, 0x7226, 0x1116, 0x3006, 0xD776, 0xF666, 0x9556, 0xB446, - 0x5BB7, 0x7AA7, 0x1997, 0x3887, 0xDFF7, 0xFEE7, 0x9DD7, 0xBCC7, - 0xC448, 0xE558, 0x8668, 0xA778, 0x4008, 0x6118, 0x0228, 0x2338, - 0xCCC9, 0xEDD9, 0x8EE9, 0xAFF9, 0x4889, 0x6999, 0x0AA9, 0x2BB9, - 0xF55A, 0xD44A, 0xB77A, 0x966A, 0x711A, 0x500A, 0x333A, 0x122A, - 0xFDDB, 0xDCCB, 0xBFFB, 0x9EEB, 0x799B, 0x588B, 0x3BBB, 0x1AAB, - 0xA66C, 0x877C, 0xE44C, 0xC55C, 0x222C, 0x033C, 0x600C, 0x411C, - 0xAEED, 0x8FFD, 0xECCD, 0xCDDD, 0x2AAD, 0x0BBD, 0x688D, 0x499D, - 0x977E, 0xB66E, 0xD55E, 0xF44E, 0x133E, 0x322E, 0x511E, 0x700E, - 0x9FFF, 0xBEEF, 0xDDDF, 0xFCCF, 0x1BBF, 0x3AAF, 0x599F, 0x788F, - 0x8891, 0xA981, 0xCAB1, 0xEBA1, 0x0CD1, 0x2DC1, 0x4EF1, 0x6FE1, - 0x8010, 0xA100, 0xC230, 0xE320, 0x0450, 0x2540, 0x4670, 0x6760, - 0xB983, 0x9893, 0xFBA3, 0xDAB3, 0x3DC3, 0x1CD3, 0x7FE3, 0x5EF3, - 0xB102, 0x9012, 0xF322, 0xD232, 0x3542, 0x1452, 0x7762, 0x5672, - 0xEAB5, 0xCBA5, 0xA895, 0x8985, 0x6EF5, 0x4FE5, 0x2CD5, 0x0DC5, - 0xE234, 0xC324, 0xA014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544, - 0xDBA7, 0xFAB7, 0x9987, 0xB897, 0x5FE7, 0x7EF7, 0x1DC7, 0x3CD7, - 0xD326, 0xF236, 0x9106, 0xB016, 0x5766, 0x7676, 0x1546, 0x3456, - 0x4CD9, 0x6DC9, 0x0EF9, 0x2FE9, 0xC899, 0xE989, 0x8AB9, 0xABA9, - 0x4458, 0x6548, 0x0678, 0x2768, 0xC018, 0xE108, 0x8238, 0xA328, - 0x7DCB, 0x5CDB, 0x3FEB, 0x1EFB, 0xF98B, 0xD89B, 0xBBAB, 0x9ABB, - 0x754A, 0x545A, 0x376A, 0x167A, 0xF10A, 0xD01A, 0xB32A, 0x923A, - 0x2EFD, 0x0FED, 0x6CDD, 0x4DCD, 0xAABD, 0x8BAD, 0xE89D, 0xC98D, - 0x267C, 0x076C, 0x645C, 0x454C, 0xA23C, 0x832C, 0xE01C, 0xC10C, - 0x1FEF, 0x3EFF, 0x5DCF, 0x7CDF, 0x9BAF, 0xBABF, 0xD98F, 0xF89F, - 0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E, - 0x0001 - }, - [AV_CRC_32_IEEE] = { - 0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517, - 0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B, - 0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048, - 0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652, - 0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D, - 0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095, - 0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA, - 0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0, - 0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3, - 0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF, - 0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730, - 0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A, - 0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05, - 0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475, - 0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A, - 0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840, - 0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB, - 0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87, - 0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4, - 0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE, - 0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1, - 0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64, - 0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B, - 0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351, - 0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832, - 0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E, - 0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5, - 0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF, - 0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0, - 0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0, - 0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F, - 0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185, - 0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A, - 0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176, - 0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15, - 0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F, - 0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620, - 0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8, - 0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7, - 0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD, - 0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E, - 0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2, - 0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1, 0x00000001 - }, - [AV_CRC_32_IEEE_LE] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 0x00000001 - }, -}; - -#endif /* AVUTIL_CRC_DATA_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/des.c b/tizen/distrib/ffmpeg/libavutil/des.c deleted file mode 100644 index ab66a0b..0000000 --- a/tizen/distrib/ffmpeg/libavutil/des.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * DES encryption/decryption - * Copyright (c) 2007 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include "avutil.h" -#include "common.h" -#include "intreadwrite.h" -#include "des.h" - -typedef struct AVDES AVDES; - -#define T(a, b, c, d, e, f, g, h) 64-a,64-b,64-c,64-d,64-e,64-f,64-g,64-h -static const uint8_t IP_shuffle[] = { - T(58, 50, 42, 34, 26, 18, 10, 2), - T(60, 52, 44, 36, 28, 20, 12, 4), - T(62, 54, 46, 38, 30, 22, 14, 6), - T(64, 56, 48, 40, 32, 24, 16, 8), - T(57, 49, 41, 33, 25, 17, 9, 1), - T(59, 51, 43, 35, 27, 19, 11, 3), - T(61, 53, 45, 37, 29, 21, 13, 5), - T(63, 55, 47, 39, 31, 23, 15, 7) -}; -#undef T - -#define T(a, b, c, d) 32-a,32-b,32-c,32-d -static const uint8_t P_shuffle[] = { - T(16, 7, 20, 21), - T(29, 12, 28, 17), - T( 1, 15, 23, 26), - T( 5, 18, 31, 10), - T( 2, 8, 24, 14), - T(32, 27, 3, 9), - T(19, 13, 30, 6), - T(22, 11, 4, 25) -}; -#undef T - -#define T(a, b, c, d, e, f, g) 64-a,64-b,64-c,64-d,64-e,64-f,64-g -static const uint8_t PC1_shuffle[] = { - T(57, 49, 41, 33, 25, 17, 9), - T( 1, 58, 50, 42, 34, 26, 18), - T(10, 2, 59, 51, 43, 35, 27), - T(19, 11, 3, 60, 52, 44, 36), - T(63, 55, 47, 39, 31, 23, 15), - T( 7, 62, 54, 46, 38, 30, 22), - T(14, 6, 61, 53, 45, 37, 29), - T(21, 13, 5, 28, 20, 12, 4) -}; -#undef T - -#define T(a, b, c, d, e, f) 56-a,56-b,56-c,56-d,56-e,56-f -static const uint8_t PC2_shuffle[] = { - T(14, 17, 11, 24, 1, 5), - T( 3, 28, 15, 6, 21, 10), - T(23, 19, 12, 4, 26, 8), - T(16, 7, 27, 20, 13, 2), - T(41, 52, 31, 37, 47, 55), - T(30, 40, 51, 45, 33, 48), - T(44, 49, 39, 56, 34, 53), - T(46, 42, 50, 36, 29, 32) -}; -#undef T - -#if CONFIG_SMALL -static const uint8_t S_boxes[8][32] = { - { - 0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18, 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87, - 0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b, 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0, - }, { - 0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4, 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a, - 0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21, 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f, - }, { - 0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5, 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18, - 0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70, 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7, - }, { - 0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a, 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f, - 0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d, 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4, - }, { - 0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16, 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69, - 0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8, 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e, - }, { - 0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58, 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b, - 0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3, 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6, - }, { - 0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad, 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61, - 0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e, 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2, - }, { - 0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41, 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27, - 0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2, 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8, - } -}; -#else -/** - * This table contains the results of applying both the S-box and P-shuffle. - * It can be regenerated by compiling this file with -DCONFIG_SMALL -DTEST -DGENTABLES - */ -static const uint32_t S_boxes_P_shuffle[8][64] = { - { - 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, - 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002, - 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202, - 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000, - 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200, - 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202, - 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200, - 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002, - }, - { - 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, - 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010, - 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000, - 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010, - 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000, - 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000, - 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010, - 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000, - }, - { - 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, - 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104, - 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104, - 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000, - 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000, - 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004, - 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004, - 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100, - }, - { - 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, - 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000, - 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040, - 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040, - 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000, - 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040, - 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040, - }, - { - 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, - 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000, - 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080, - 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080, - 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080, - 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000, - 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000, - 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080, - }, - { - 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, - 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008, - 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008, - 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000, - 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008, - 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000, - 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008, - 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008, - }, - { - 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, - 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401, - 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001, - 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400, - 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001, - 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400, - 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401, - 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001, - }, - { - 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, - 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020, - 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800, - 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000, - 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820, - 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820, - 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000, - 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800, - }, -}; -#endif - -static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len) { - int i; - uint64_t res = 0; - for (i = 0; i < shuffle_len; i++) - res += res + ((in >> *shuffle++) & 1); - return res; -} - -static uint64_t shuffle_inv(uint64_t in, const uint8_t *shuffle, int shuffle_len) { - int i; - uint64_t res = 0; - shuffle += shuffle_len - 1; - for (i = 0; i < shuffle_len; i++) { - res |= (in & 1) << *shuffle--; - in >>= 1; - } - return res; -} - -static uint32_t f_func(uint32_t r, uint64_t k) { - int i; - uint32_t out = 0; - // rotate to get first part of E-shuffle in the lowest 6 bits - r = (r << 1) | (r >> 31); - // apply S-boxes, those compress the data again from 8 * 6 to 8 * 4 bits - for (i = 7; i >= 0; i--) { - uint8_t tmp = (r ^ k) & 0x3f; -#if CONFIG_SMALL - uint8_t v = S_boxes[i][tmp >> 1]; - if (tmp & 1) v >>= 4; - out = (out >> 4) | (v << 28); -#else - out |= S_boxes_P_shuffle[i][tmp]; -#endif - // get next 6 bits of E-shuffle and round key k into the lowest bits - r = (r >> 4) | (r << 28); - k >>= 6; - } -#if CONFIG_SMALL - out = shuffle(out, P_shuffle, sizeof(P_shuffle)); -#endif - return out; -} - -/** - * \brief rotate the two halves of the expanded 56 bit key each 1 bit left - * - * Note: the specification calls this "shift", so I kept it although - * it is confusing. - */ -static uint64_t key_shift_left(uint64_t CDn) { - uint64_t carries = (CDn >> 27) & 0x10000001; - CDn <<= 1; - CDn &= ~0x10000001; - CDn |= carries; - return CDn; -} - -static void gen_roundkeys(uint64_t K[16], uint64_t key) { - int i; - // discard parity bits from key and shuffle it into C and D parts - uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle)); - // generate round keys - for (i = 0; i < 16; i++) { - CDn = key_shift_left(CDn); - if (i > 1 && i != 8 && i != 15) - CDn = key_shift_left(CDn); - K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle)); - } -} - -static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) { - int i; - // used to apply round keys in reverse order for decryption - decrypt = decrypt ? 15 : 0; - // shuffle irrelevant to security but to ease hardware implementations - in = shuffle(in, IP_shuffle, sizeof(IP_shuffle)); - for (i = 0; i < 16; i++) { - uint32_t f_res; - f_res = f_func(in, K[decrypt ^ i]); - in = (in << 32) | (in >> 32); - in ^= f_res; - } - in = (in << 32) | (in >> 32); - // reverse shuffle used to ease hardware implementations - in = shuffle_inv(in, IP_shuffle, sizeof(IP_shuffle)); - return in; -} - -int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) { - if (key_bits != 64 && key_bits != 192) - return -1; - d->triple_des = key_bits > 64; - gen_roundkeys(d->round_keys[0], AV_RB64(key)); - if (d->triple_des) { - gen_roundkeys(d->round_keys[1], AV_RB64(key + 8)); - gen_roundkeys(d->round_keys[2], AV_RB64(key + 16)); - } - return 0; -} - -void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) { - uint64_t iv_val = iv ? be2me_64(*(uint64_t *)iv) : 0; - while (count-- > 0) { - uint64_t dst_val; - uint64_t src_val = src ? be2me_64(*(const uint64_t *)src) : 0; - if (decrypt) { - uint64_t tmp = src_val; - if (d->triple_des) { - src_val = des_encdec(src_val, d->round_keys[2], 1); - src_val = des_encdec(src_val, d->round_keys[1], 0); - } - dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val; - iv_val = iv ? tmp : 0; - } else { - dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0); - if (d->triple_des) { - dst_val = des_encdec(dst_val, d->round_keys[1], 1); - dst_val = des_encdec(dst_val, d->round_keys[2], 0); - } - iv_val = iv ? dst_val : 0; - } - *(uint64_t *)dst = be2me_64(dst_val); - src += 8; - dst += 8; - } - if (iv) - *(uint64_t *)iv = be2me_64(iv_val); -} - -#ifdef TEST -#undef printf -#undef rand -#undef srand -#include -#include -#include -static uint64_t rand64(void) { - uint64_t r = rand(); - r = (r << 32) | rand(); - return r; -} - -static const uint8_t test_key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; -static const DECLARE_ALIGNED(8, uint8_t, plain)[] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; -static const DECLARE_ALIGNED(8, uint8_t, crypt)[] = {0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18}; -static DECLARE_ALIGNED(8, uint8_t, tmp)[8]; -static DECLARE_ALIGNED(8, uint8_t, large_buffer)[10002][8]; -static const uint8_t cbc_key[] = { - 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, - 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 -}; - -static int run_test(int cbc, int decrypt) { - AVDES d; - int delay = cbc && !decrypt ? 2 : 1; - uint64_t res; - AV_WB64(large_buffer[0], 0x4e6f772069732074ULL); - AV_WB64(large_buffer[1], 0x1234567890abcdefULL); - AV_WB64(tmp, 0x1234567890abcdefULL); - av_des_init(&d, cbc_key, 192, decrypt); - av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt); - res = AV_RB64(large_buffer[9999 + delay]); - if (cbc) { - if (decrypt) - return res == 0xc5cecf63ecec514cULL; - else - return res == 0xcb191f85d1ed8439ULL; - } else { - if (decrypt) - return res == 0x8325397644091a0aULL; - else - return res == 0xdd17e8b8b437d232ULL; - } -} - -int main(void) { - AVDES d; - int i; -#ifdef GENTABLES - int j; -#endif - struct timeval tv; - uint64_t key[3]; - uint64_t data; - uint64_t ct; - uint64_t roundkeys[16]; - gettimeofday(&tv, NULL); - srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec); - key[0] = AV_RB64(test_key); - data = AV_RB64(plain); - gen_roundkeys(roundkeys, key[0]); - if (des_encdec(data, roundkeys, 0) != AV_RB64(crypt)) { - printf("Test 1 failed\n"); - return 1; - } - av_des_init(&d, test_key, 64, 0); - av_des_crypt(&d, tmp, plain, 1, NULL, 0); - if (memcmp(tmp, crypt, sizeof(crypt))) { - printf("Public API decryption failed\n"); - return 1; - } - if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) { - printf("Partial Monte-Carlo test failed\n"); - return 1; - } - for (i = 0; i < 1000000; i++) { - key[0] = rand64(); key[1] = rand64(); key[2] = rand64(); - data = rand64(); - av_des_init(&d, key, 192, 0); - av_des_crypt(&d, &ct, &data, 1, NULL, 0); - av_des_init(&d, key, 192, 1); - av_des_crypt(&d, &ct, &ct, 1, NULL, 1); - if (ct != data) { - printf("Test 2 failed\n"); - return 1; - } - } -#ifdef GENTABLES - printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n"); - for (i = 0; i < 8; i++) { - printf(" {"); - for (j = 0; j < 64; j++) { - uint32_t v = S_boxes[i][j >> 1]; - v = j & 1 ? v >> 4 : v & 0xf; - v <<= 28 - 4 * i; - v = shuffle(v, P_shuffle, sizeof(P_shuffle)); - printf((j & 7) == 0 ? "\n " : " "); - printf("0x%08X,", v); - } - printf("\n },\n"); - } - printf("};\n"); -#endif - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/des.h b/tizen/distrib/ffmpeg/libavutil/des.h deleted file mode 100644 index e80bdd3..0000000 --- a/tizen/distrib/ffmpeg/libavutil/des.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * DES encryption/decryption - * Copyright (c) 2007 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_DES_H -#define AVUTIL_DES_H - -#include - -struct AVDES { - uint64_t round_keys[3][16]; - int triple_des; -}; - -/** - * \brief Initializes an AVDES context. - * - * \param key_bits must be 64 or 192 - * \param decrypt 0 for encryption, 1 for decryption - */ -int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt); - -/** - * \brief Encrypts / decrypts using the DES algorithm. - * - * \param count number of 8 byte blocks - * \param dst destination array, can be equal to src, must be 8-byte aligned - * \param src source array, can be equal to dst, must be 8-byte aligned, may be NULL - * \param iv initialization vector for CBC mode, if NULL then ECB will be used, - * must be 8-byte aligned - * \param decrypt 0 for encryption, 1 for decryption - */ -void av_des_crypt(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); - -#endif /* AVUTIL_DES_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/error.c b/tizen/distrib/ffmpeg/libavutil/error.c deleted file mode 100644 index b6d6019..0000000 --- a/tizen/distrib/ffmpeg/libavutil/error.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avutil.h" -#include "avstring.h" - -int av_strerror(int errnum, char *errbuf, size_t errbuf_size) -{ - int ret = 0; - const char *errstr = NULL; - - switch (errnum) { - case AVERROR_EOF: errstr = "End of file"; break; - case AVERROR_INVALIDDATA: errstr = "Invalid data found when processing input"; break; - case AVERROR_NUMEXPECTED: errstr = "Number syntax expected in filename"; break; - case AVERROR_PATCHWELCOME: errstr = "Not yet implemented in FFmpeg, patches welcome"; break; - } - - if (errstr) { - av_strlcpy(errbuf, errstr, errbuf_size); - } else { -#if HAVE_STRERROR_R - ret = strerror_r(AVUNERROR(errnum), errbuf, errbuf_size); -#else - ret = -1; -#endif - if (ret < 0) - snprintf(errbuf, errbuf_size, "Error number %d occurred", errnum); - } - - return ret; -} diff --git a/tizen/distrib/ffmpeg/libavutil/error.h b/tizen/distrib/ffmpeg/libavutil/error.h deleted file mode 100644 index 13a9a35..0000000 --- a/tizen/distrib/ffmpeg/libavutil/error.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * error code definitions - */ - -#ifndef AVUTIL_ERROR_H -#define AVUTIL_ERROR_H - -#include -#include "avutil.h" - -/* error handling */ -#if EDOM > 0 -#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. -#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. -#else -/* Some platforms have E* and errno already negated. */ -#define AVERROR(e) (e) -#define AVUNERROR(e) (e) -#endif - -#if LIBAVUTIL_VERSION_MAJOR < 51 -#define AVERROR_INVALIDDATA AVERROR(EINVAL) ///< Invalid data found when processing input -#define AVERROR_IO AVERROR(EIO) ///< I/O error -#define AVERROR_NOENT AVERROR(ENOENT) ///< No such file or directory -#define AVERROR_NOFMT AVERROR(EILSEQ) ///< Unknown format -#define AVERROR_NOMEM AVERROR(ENOMEM) ///< Not enough memory -#define AVERROR_NOTSUPP AVERROR(ENOSYS) ///< Operation not supported -#define AVERROR_NUMEXPECTED AVERROR(EDOM) ///< Number syntax expected in filename -#define AVERROR_UNKNOWN AVERROR(EINVAL) ///< Unknown error -#endif - -#define AVERROR_EOF AVERROR(EPIPE) ///< End of file - -#define AVERROR_PATCHWELCOME (-MKTAG('P','A','W','E')) ///< Not yet implemented in FFmpeg, patches welcome - -#if LIBAVUTIL_VERSION_MAJOR > 50 -#define AVERROR_INVALIDDATA (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input -#define AVERROR_NUMEXPECTED (-MKTAG('N','U','E','X')) ///< Number syntax expected in filename -#endif - -/** - * Puts a description of the AVERROR code errnum in errbuf. - * In case of failure the global variable errno is set to indicate the - * error. Even in case of failure av_strerror() will print a generic - * error message indicating the errnum provided to errbuf. - * - * @param errbuf_size the size in bytes of errbuf - * @return 0 on success, a negative value if a description for errnum - * cannot be found - */ -int av_strerror(int errnum, char *errbuf, size_t errbuf_size); - -#endif /* AVUTIL_ERROR_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/fifo.c b/tizen/distrib/ffmpeg/libavutil/fifo.c deleted file mode 100644 index cfb716e..0000000 --- a/tizen/distrib/ffmpeg/libavutil/fifo.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * a very simple circular buffer FIFO implementation - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2006 Roman Shaposhnik - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "common.h" -#include "fifo.h" - -AVFifoBuffer *av_fifo_alloc(unsigned int size) -{ - AVFifoBuffer *f= av_mallocz(sizeof(AVFifoBuffer)); - if(!f) - return NULL; - f->buffer = av_malloc(size); - f->end = f->buffer + size; - av_fifo_reset(f); - if (!f->buffer) - av_freep(&f); - return f; -} - -void av_fifo_free(AVFifoBuffer *f) -{ - if(f){ - av_free(f->buffer); - av_free(f); - } -} - -void av_fifo_reset(AVFifoBuffer *f) -{ - f->wptr = f->rptr = f->buffer; - f->wndx = f->rndx = 0; -} - -int av_fifo_size(AVFifoBuffer *f) -{ - return (uint32_t)(f->wndx - f->rndx); -} - -int av_fifo_space(AVFifoBuffer *f) -{ - return f->end - f->buffer - av_fifo_size(f); -} - -int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) { - unsigned int old_size= f->end - f->buffer; - - if(old_size < new_size){ - int len= av_fifo_size(f); - AVFifoBuffer *f2= av_fifo_alloc(new_size); - - if (!f2) - return -1; - av_fifo_generic_read(f, f2->buffer, len, NULL); - f2->wptr += len; - f2->wndx += len; - av_free(f->buffer); - *f= *f2; - av_free(f2); - } - return 0; -} - -// src must NOT be const as it can be a context for func that may need updating (like a pointer or byte counter) -int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)) -{ - int total = size; - do { - int len = FFMIN(f->end - f->wptr, size); - if(func) { - if(func(src, f->wptr, len) <= 0) - break; - } else { - memcpy(f->wptr, src, len); - src = (uint8_t*)src + len; - } -// Write memory barrier needed for SMP here in theory - f->wptr += len; - if (f->wptr >= f->end) - f->wptr = f->buffer; - f->wndx += len; - size -= len; - } while (size > 0); - return total - size; -} - - -int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)) -{ -// Read memory barrier needed for SMP here in theory - do { - int len = FFMIN(f->end - f->rptr, buf_size); - if(func) func(dest, f->rptr, len); - else{ - memcpy(dest, f->rptr, len); - dest = (uint8_t*)dest + len; - } -// memory barrier needed for SMP here in theory - av_fifo_drain(f, len); - buf_size -= len; - } while (buf_size > 0); - return 0; -} - -/** Discard data from the FIFO. */ -void av_fifo_drain(AVFifoBuffer *f, int size) -{ - f->rptr += size; - if (f->rptr >= f->end) - f->rptr -= f->end - f->buffer; - f->rndx += size; -} diff --git a/tizen/distrib/ffmpeg/libavutil/fifo.h b/tizen/distrib/ffmpeg/libavutil/fifo.h deleted file mode 100644 index fb1ed47..0000000 --- a/tizen/distrib/ffmpeg/libavutil/fifo.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * a very simple circular buffer FIFO implementation - */ - -#ifndef AVUTIL_FIFO_H -#define AVUTIL_FIFO_H - -#include - -typedef struct AVFifoBuffer { - uint8_t *buffer; - uint8_t *rptr, *wptr, *end; - uint32_t rndx, wndx; -} AVFifoBuffer; - -/** - * Initializes an AVFifoBuffer. - * @param size of FIFO - * @return AVFifoBuffer or NULL in case of memory allocation failure - */ -AVFifoBuffer *av_fifo_alloc(unsigned int size); - -/** - * Frees an AVFifoBuffer. - * @param *f AVFifoBuffer to free - */ -void av_fifo_free(AVFifoBuffer *f); - -/** - * Resets the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied. - * @param *f AVFifoBuffer to reset - */ -void av_fifo_reset(AVFifoBuffer *f); - -/** - * Returns the amount of data in bytes in the AVFifoBuffer, that is the - * amount of data you can read from it. - * @param *f AVFifoBuffer to read from - * @return size - */ -int av_fifo_size(AVFifoBuffer *f); - -/** - * Returns the amount of space in bytes in the AVFifoBuffer, that is the - * amount of data you can write into it. - * @param *f AVFifoBuffer to write into - * @return size - */ -int av_fifo_space(AVFifoBuffer *f); - -/** - * Feeds data from an AVFifoBuffer to a user-supplied callback. - * @param *f AVFifoBuffer to read from - * @param buf_size number of bytes to read - * @param *func generic read function - * @param *dest data destination - */ -int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)); - -/** - * Feeds data from a user-supplied callback to an AVFifoBuffer. - * @param *f AVFifoBuffer to write to - * @param *src data source; non-const since it may be used as a - * modifiable context by the function defined in func - * @param size number of bytes to write - * @param *func generic write function; the first parameter is src, - * the second is dest_buf, the third is dest_buf_size. - * func must return the number of bytes written to dest_buf, or <= 0 to - * indicate no more data available to write. - * If func is NULL, src is interpreted as a simple byte array for source data. - * @return the number of bytes written to the FIFO - */ -int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)); - -/** - * Resizes an AVFifoBuffer. - * @param *f AVFifoBuffer to resize - * @param size new AVFifoBuffer size in bytes - * @return <0 for failure, >=0 otherwise - */ -int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size); - -/** - * Reads and discards the specified amount of data from an AVFifoBuffer. - * @param *f AVFifoBuffer to read from - * @param size amount of data to read in bytes - */ -void av_fifo_drain(AVFifoBuffer *f, int size); - -static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs) -{ - uint8_t *ptr = f->rptr + offs; - if (ptr >= f->end) - ptr -= f->end - f->buffer; - return *ptr; -} -#endif /* AVUTIL_FIFO_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/integer.c b/tizen/distrib/ffmpeg/libavutil/integer.c deleted file mode 100644 index 4f9b66c..0000000 --- a/tizen/distrib/ffmpeg/libavutil/integer.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * arbitrary precision integers - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * arbitrary precision integers - * @author Michael Niedermayer - */ - -#include "common.h" -#include "integer.h" - -AVInteger av_add_i(AVInteger a, AVInteger b){ - int i, carry=0; - - for(i=0; i>16) + a.v[i] + b.v[i]; - a.v[i]= carry; - } - return a; -} - -AVInteger av_sub_i(AVInteger a, AVInteger b){ - int i, carry=0; - - for(i=0; i>16) + a.v[i] - b.v[i]; - a.v[i]= carry; - } - return a; -} - -int av_log2_i(AVInteger a){ - int i; - - for(i=AV_INTEGER_SIZE-1; i>=0; i--){ - if(a.v[i]) - return av_log2_16bit(a.v[i]) + 16*i; - } - return -1; -} - -AVInteger av_mul_i(AVInteger a, AVInteger b){ - AVInteger out; - int i, j; - int na= (av_log2_i(a)+16) >> 4; - int nb= (av_log2_i(b)+16) >> 4; - - memset(&out, 0, sizeof(out)); - - for(i=0; i>16) + out.v[j] + a.v[i]*b.v[j-i]; - out.v[j]= carry; - } - } - - return out; -} - -int av_cmp_i(AVInteger a, AVInteger b){ - int i; - int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1]; - if(v) return (v>>16)|1; - - for(i=AV_INTEGER_SIZE-2; i>=0; i--){ - int v= a.v[i] - b.v[i]; - if(v) return (v>>16)|1; - } - return 0; -} - -AVInteger av_shr_i(AVInteger a, int s){ - AVInteger out; - int i; - - for(i=0; i>4); - unsigned int v=0; - if(index+1> (s&15); - } - return out; -} - -AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){ - int i= av_log2_i(a) - av_log2_i(b); - AVInteger quot_temp; - if(!quot) quot = "_temp; - - assert((int16_t)a[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b[AV_INTEGER_SIZE-1] >= 0); - assert(av_log2(b)>=0); - - if(i > 0) - b= av_shr_i(b, -i); - - memset(quot, 0, sizeof(AVInteger)); - - while(i-- >= 0){ - *quot= av_shr_i(*quot, -1); - if(av_cmp_i(a, b) >= 0){ - a= av_sub_i(a, b); - quot->v[0] += 1; - } - b= av_shr_i(b, 1); - } - return a; -} - -AVInteger av_div_i(AVInteger a, AVInteger b){ - AVInteger quot; - av_mod_i(", a, b); - return quot; -} - -AVInteger av_int2i(int64_t a){ - AVInteger out; - int i; - - for(i=0; i>=16; - } - return out; -} - -int64_t av_i2int(AVInteger a){ - int i; - int64_t out=(int8_t)a.v[AV_INTEGER_SIZE-1]; - - for(i= AV_INTEGER_SIZE-2; i>=0; i--){ - out = (out<<16) + a.v[i]; - } - return out; -} - -#ifdef TEST -#undef NDEBUG -#include - -const uint8_t ff_log2_tab[256]={ - 0,0,1,1,2,2,2,2,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,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, - 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, - 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, - 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, - 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 -}; - -int main(void){ - int64_t a,b; - - for(a=7; a<256*256*256; a+=13215){ - for(b=3; b<256*256*256; b+=27118){ - AVInteger ai= av_int2i(a); - AVInteger bi= av_int2i(b); - - assert(av_i2int(ai) == a); - assert(av_i2int(bi) == b); - assert(av_i2int(av_add_i(ai,bi)) == a+b); - assert(av_i2int(av_sub_i(ai,bi)) == a-b); - assert(av_i2int(av_mul_i(ai,bi)) == a*b); - assert(av_i2int(av_shr_i(ai, 9)) == a>>9); - assert(av_i2int(av_shr_i(ai,-9)) == a<<9); - assert(av_i2int(av_shr_i(ai, 17)) == a>>17); - assert(av_i2int(av_shr_i(ai,-17)) == a<<17); - assert(av_log2_i(ai) == av_log2(a)); - assert(av_i2int(av_div_i(ai,bi)) == a/b); - } - } - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/integer.h b/tizen/distrib/ffmpeg/libavutil/integer.h deleted file mode 100644 index fb46acb..0000000 --- a/tizen/distrib/ffmpeg/libavutil/integer.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * arbitrary precision integers - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * arbitrary precision integers - * @author Michael Niedermayer - */ - -#ifndef AVUTIL_INTEGER_H -#define AVUTIL_INTEGER_H - -#include -#include "common.h" - -#define AV_INTEGER_SIZE 8 - -typedef struct AVInteger{ - uint16_t v[AV_INTEGER_SIZE]; -} AVInteger; - -AVInteger av_add_i(AVInteger a, AVInteger b) av_const; -AVInteger av_sub_i(AVInteger a, AVInteger b) av_const; - -/** - * Returns the rounded-down value of the base 2 logarithm of the given - * AVInteger. This is simply the index of the most significant bit - * which is 1, or 0 if all bits are 0. - */ -int av_log2_i(AVInteger a) av_const; -AVInteger av_mul_i(AVInteger a, AVInteger b) av_const; - -/** - * Returns 0 if a==b, 1 if a>b and -1 if a - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * common internal API header - */ - -#ifndef AVUTIL_INTERNAL_H -#define AVUTIL_INTERNAL_H - -#if !defined(DEBUG) && !defined(NDEBUG) -# define NDEBUG -#endif - -#include -#include -#include -#include -#include "config.h" -#include "attributes.h" -#include "timer.h" - -#ifndef attribute_align_arg -#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,2) -# define attribute_align_arg __attribute__((force_align_arg_pointer)) -#else -# define attribute_align_arg -#endif -#endif - -#ifndef attribute_used -#if AV_GCC_VERSION_AT_LEAST(3,1) -# define attribute_used __attribute__((used)) -#else -# define attribute_used -#endif -#endif - -#ifndef av_alias -#if HAVE_ATTRIBUTE_MAY_ALIAS && (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(3,3) -# define av_alias __attribute__((may_alias)) -#else -# define av_alias -#endif -#endif - -#ifndef INT16_MIN -#define INT16_MIN (-0x7fff - 1) -#endif - -#ifndef INT16_MAX -#define INT16_MAX 0x7fff -#endif - -#ifndef INT32_MIN -#define INT32_MIN (-0x7fffffff - 1) -#endif - -#ifndef INT32_MAX -#define INT32_MAX 0x7fffffff -#endif - -#ifndef UINT32_MAX -#define UINT32_MAX 0xffffffff -#endif - -#ifndef INT64_MIN -#define INT64_MIN (-0x7fffffffffffffffLL - 1) -#endif - -#ifndef INT64_MAX -#define INT64_MAX INT64_C(9223372036854775807) -#endif - -#ifndef UINT64_MAX -#define UINT64_MAX UINT64_C(0xFFFFFFFFFFFFFFFF) -#endif - -#ifndef INT_BIT -# define INT_BIT (CHAR_BIT * sizeof(int)) -#endif - -#ifndef offsetof -# define offsetof(T, F) ((unsigned int)((char *)&((T *)0)->F)) -#endif - -/* Use to export labels from asm. */ -#define LABEL_MANGLE(a) EXTERN_PREFIX #a - -// Use rip-relative addressing if compiling PIC code on x86-64. -#if ARCH_X86_64 && defined(PIC) -# define LOCAL_MANGLE(a) #a "(%%rip)" -#else -# define LOCAL_MANGLE(a) #a -#endif - -#define MANGLE(a) EXTERN_PREFIX LOCAL_MANGLE(a) - -/* debug stuff */ - -/* dprintf macros */ -#ifdef DEBUG -# define dprintf(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__) -#else -# define dprintf(pctx, ...) -#endif - -#define av_abort() do { av_log(NULL, AV_LOG_ERROR, "Abort at %s:%d\n", __FILE__, __LINE__); abort(); } while (0) - -/* math */ - -#if ARCH_X86 -#define MASK_ABS(mask, level)\ - __asm__ volatile(\ - "cltd \n\t"\ - "xorl %1, %0 \n\t"\ - "subl %1, %0 \n\t"\ - : "+a" (level), "=&d" (mask)\ - ); -#else -#define MASK_ABS(mask, level)\ - mask = level >> 31;\ - level = (level ^ mask) - mask; -#endif - -/* avoid usage of dangerous/inappropriate system functions */ -#undef malloc -#define malloc please_use_av_malloc -#undef free -#define free please_use_av_free -#undef realloc -#define realloc please_use_av_realloc -#undef time -#define time time_is_forbidden_due_to_security_issues -#undef rand -#define rand rand_is_forbidden_due_to_state_trashing_use_av_lfg_get -#undef srand -#define srand srand_is_forbidden_due_to_state_trashing_use_av_lfg_init -#undef random -#define random random_is_forbidden_due_to_state_trashing_use_av_lfg_get -#undef sprintf -#define sprintf sprintf_is_forbidden_due_to_security_issues_use_snprintf -#undef strcat -#define strcat strcat_is_forbidden_due_to_security_issues_use_av_strlcat -#undef exit -#define exit exit_is_forbidden -#ifndef LIBAVFORMAT_BUILD -#undef printf -#define printf please_use_av_log_instead_of_printf -#undef fprintf -#define fprintf please_use_av_log_instead_of_fprintf -#undef puts -#define puts please_use_av_log_instead_of_puts -#undef perror -#define perror please_use_av_log_instead_of_perror -#endif - -#define FF_ALLOC_OR_GOTO(ctx, p, size, label)\ -{\ - p = av_malloc(size);\ - if (p == NULL && (size) != 0) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)\ -{\ - p = av_mallocz(size);\ - if (p == NULL && (size) != 0) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#include "libm.h" - -/** - * Returns NULL if CONFIG_SMALL is true, otherwise the argument - * without modification. Used to disable the definition of strings - * (for example AVCodec long_names). - */ -#if CONFIG_SMALL -# define NULL_IF_CONFIG_SMALL(x) NULL -#else -# define NULL_IF_CONFIG_SMALL(x) x -#endif - -#if HAVE_SYMVER_ASM_LABEL -# define FF_SYMVER(type, name, args, ver) \ - type ff_##name args __asm__ (EXTERN_PREFIX #name "@" ver); \ - type ff_##name args -#elif HAVE_SYMVER_GNU_ASM -# define FF_SYMVER(type, name, args, ver) \ - __asm__ (".symver ff_" #name "," EXTERN_PREFIX #name "@" ver); \ - type ff_##name args; \ - type ff_##name args -#endif - -#endif /* AVUTIL_INTERNAL_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.c b/tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.c deleted file mode 100644 index 79fe186..0000000 --- a/tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * portable IEEE float/double read/write functions - * - * Copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * portable IEEE float/double read/write functions - */ - -#include -#include -#include "intfloat_readwrite.h" - -double av_int2dbl(int64_t v){ - if(v+v > 0xFFEULL<<52) - return 0.0/0.0; - return ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075); -} - -float av_int2flt(int32_t v){ - if(v+v > 0xFF000000U) - return 0.0/0.0; - return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150); -} - -double av_ext2dbl(const AVExtFloat ext){ - uint64_t m = 0; - int e, i; - - for (i = 0; i < 8; i++) - m = (m<<8) + ext.mantissa[i]; - e = (((int)ext.exponent[0]&0x7f)<<8) | ext.exponent[1]; - if (e == 0x7fff && m) - return 0.0/0.0; - e -= 16383 + 63; /* In IEEE 80 bits, the whole (i.e. 1.xxxx) - * mantissa bit is written as opposed to the - * single and double precision formats. */ - if (ext.exponent[0]&0x80) - m= -m; - return ldexp(m, e); -} - -int64_t av_dbl2int(double d){ - int e; - if ( !d) return 0; - else if(d-d) return 0x7FF0000000000000LL + ((int64_t)(d<0)<<63) + (d!=d); - d= frexp(d, &e); - return (int64_t)(d<0)<<63 | (e+1022LL)<<52 | (int64_t)((fabs(d)-0.5)*(1LL<<53)); -} - -int32_t av_flt2int(float d){ - int e; - if ( !d) return 0; - else if(d-d) return 0x7F800000 + ((d<0)<<31) + (d!=d); - d= frexp(d, &e); - return (d<0)<<31 | (e+126)<<23 | (int64_t)((fabs(d)-0.5)*(1<<24)); -} - -AVExtFloat av_dbl2ext(double d){ - struct AVExtFloat ext= {{0}}; - int e, i; double f; uint64_t m; - - f = fabs(frexp(d, &e)); - if (f >= 0.5 && f < 1) { - e += 16382; - ext.exponent[0] = e>>8; - ext.exponent[1] = e; - m = (uint64_t)ldexp(f, 64); - for (i=0; i < 8; i++) - ext.mantissa[i] = m>>(56-(i<<3)); - } else if (f != 0.0) { - ext.exponent[0] = 0x7f; ext.exponent[1] = 0xff; - if (f != 1/0.0) - ext.mantissa[0] = ~0; - } - if (d < 0) - ext.exponent[0] |= 0x80; - return ext; -} - diff --git a/tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.h b/tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.h deleted file mode 100644 index 1b80fc6..0000000 --- a/tizen/distrib/ffmpeg/libavutil/intfloat_readwrite.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_INTFLOAT_READWRITE_H -#define AVUTIL_INTFLOAT_READWRITE_H - -#include -#include "attributes.h" - -/* IEEE 80 bits extended float */ -typedef struct AVExtFloat { - uint8_t exponent[2]; - uint8_t mantissa[8]; -} AVExtFloat; - -double av_int2dbl(int64_t v) av_const; -float av_int2flt(int32_t v) av_const; -double av_ext2dbl(const AVExtFloat ext) av_const; -int64_t av_dbl2int(double d) av_const; -int32_t av_flt2int(float d) av_const; -AVExtFloat av_dbl2ext(double d) av_const; - -#endif /* AVUTIL_INTFLOAT_READWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/intmath.h b/tizen/distrib/ffmpeg/libavutil/intmath.h deleted file mode 100644 index 95ee1ff..0000000 --- a/tizen/distrib/ffmpeg/libavutil/intmath.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_INTMATH_H -#define AVUTIL_INTMATH_H - -#include -#include "config.h" -#include "attributes.h" - -extern const uint32_t ff_inverse[257]; - -#if ARCH_ARM -# include "arm/intmath.h" -#elif ARCH_X86 -# include "x86/intmath.h" -#endif - -#if HAVE_FAST_CLZ && AV_GCC_VERSION_AT_LEAST(3,4) - -#ifndef av_log2 - -#define av_log2(x) (31 - __builtin_clz((x)|1)) - -#ifndef av_log2_16bit -#define av_log2_16bit av_log2 -#endif - -#endif /* av_log2 */ - -#endif /* AV_GCC_VERSION_AT_LEAST(3,4) */ - -#ifndef FASTDIV - -#if CONFIG_FASTDIV -# define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32)) -#else -# define FASTDIV(a,b) ((a) / (b)) -#endif - -#endif /* FASTDIV */ - -/* - * Get definition of av_log2_c from common.h. In the event we got - * here through common.h including this file, including it again will - * be a no-op due to multi-inclusion guards, so we must duplicate the - * fallback defines here. - */ - -#include "common.h" - -#ifndef av_log2 -# define av_log2 av_log2_c -#endif -#ifndef av_log2_16bit -# define av_log2_16bit av_log2_16bit_c -#endif - -extern const uint8_t ff_sqrt_tab[256]; - -static inline av_const unsigned int ff_sqrt(unsigned int a) -{ - unsigned int b; - - if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4; - else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2; -#if !CONFIG_SMALL - else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1; - else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8] ; -#endif - else { - int s = av_log2_16bit(a >> 16) >> 1; - unsigned int c = a >> (s + 2); - b = ff_sqrt_tab[c >> (s + 8)]; - b = FASTDIV(c,b) + (b << s); - } - - return b - (a < b * b); -} - -#endif /* AVUTIL_INTMATH_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/intreadwrite.h b/tizen/distrib/ffmpeg/libavutil/intreadwrite.h deleted file mode 100644 index c8026f0..0000000 --- a/tizen/distrib/ffmpeg/libavutil/intreadwrite.h +++ /dev/null @@ -1,516 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_INTREADWRITE_H -#define AVUTIL_INTREADWRITE_H - -#include -#include "config.h" -#include "bswap.h" -#include "common.h" - -typedef union { - uint64_t u64; - uint32_t u32[2]; - uint16_t u16[4]; - uint8_t u8 [8]; - double f64; - float f32[2]; -} av_alias av_alias64; - -typedef union { - uint32_t u32; - uint16_t u16[2]; - uint8_t u8 [4]; - float f32; -} av_alias av_alias32; - -typedef union { - uint16_t u16; - uint8_t u8 [2]; -} av_alias av_alias16; - -/* - * Arch-specific headers can provide any combination of - * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros. - * Preprocessor symbols must be defined, even if these are implemented - * as inline functions. - */ - -#if ARCH_ARM -# include "arm/intreadwrite.h" -#elif ARCH_AVR32 -# include "avr32/intreadwrite.h" -#elif ARCH_MIPS -# include "mips/intreadwrite.h" -#elif ARCH_PPC -# include "ppc/intreadwrite.h" -#elif ARCH_TOMI -# include "tomi/intreadwrite.h" -#elif ARCH_X86 -# include "x86/intreadwrite.h" -#endif - -/* - * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers. - */ - -#if HAVE_BIGENDIAN - -# if defined(AV_RN16) && !defined(AV_RB16) -# define AV_RB16(p) AV_RN16(p) -# elif !defined(AV_RN16) && defined(AV_RB16) -# define AV_RN16(p) AV_RB16(p) -# endif - -# if defined(AV_WN16) && !defined(AV_WB16) -# define AV_WB16(p, v) AV_WN16(p, v) -# elif !defined(AV_WN16) && defined(AV_WB16) -# define AV_WN16(p, v) AV_WB16(p, v) -# endif - -# if defined(AV_RN24) && !defined(AV_RB24) -# define AV_RB24(p) AV_RN24(p) -# elif !defined(AV_RN24) && defined(AV_RB24) -# define AV_RN24(p) AV_RB24(p) -# endif - -# if defined(AV_WN24) && !defined(AV_WB24) -# define AV_WB24(p, v) AV_WN24(p, v) -# elif !defined(AV_WN24) && defined(AV_WB24) -# define AV_WN24(p, v) AV_WB24(p, v) -# endif - -# if defined(AV_RN32) && !defined(AV_RB32) -# define AV_RB32(p) AV_RN32(p) -# elif !defined(AV_RN32) && defined(AV_RB32) -# define AV_RN32(p) AV_RB32(p) -# endif - -# if defined(AV_WN32) && !defined(AV_WB32) -# define AV_WB32(p, v) AV_WN32(p, v) -# elif !defined(AV_WN32) && defined(AV_WB32) -# define AV_WN32(p, v) AV_WB32(p, v) -# endif - -# if defined(AV_RN64) && !defined(AV_RB64) -# define AV_RB64(p) AV_RN64(p) -# elif !defined(AV_RN64) && defined(AV_RB64) -# define AV_RN64(p) AV_RB64(p) -# endif - -# if defined(AV_WN64) && !defined(AV_WB64) -# define AV_WB64(p, v) AV_WN64(p, v) -# elif !defined(AV_WN64) && defined(AV_WB64) -# define AV_WN64(p, v) AV_WB64(p, v) -# endif - -#else /* HAVE_BIGENDIAN */ - -# if defined(AV_RN16) && !defined(AV_RL16) -# define AV_RL16(p) AV_RN16(p) -# elif !defined(AV_RN16) && defined(AV_RL16) -# define AV_RN16(p) AV_RL16(p) -# endif - -# if defined(AV_WN16) && !defined(AV_WL16) -# define AV_WL16(p, v) AV_WN16(p, v) -# elif !defined(AV_WN16) && defined(AV_WL16) -# define AV_WN16(p, v) AV_WL16(p, v) -# endif - -# if defined(AV_RN24) && !defined(AV_RL24) -# define AV_RL24(p) AV_RN24(p) -# elif !defined(AV_RN24) && defined(AV_RL24) -# define AV_RN24(p) AV_RL24(p) -# endif - -# if defined(AV_WN24) && !defined(AV_WL24) -# define AV_WL24(p, v) AV_WN24(p, v) -# elif !defined(AV_WN24) && defined(AV_WL24) -# define AV_WN24(p, v) AV_WL24(p, v) -# endif - -# if defined(AV_RN32) && !defined(AV_RL32) -# define AV_RL32(p) AV_RN32(p) -# elif !defined(AV_RN32) && defined(AV_RL32) -# define AV_RN32(p) AV_RL32(p) -# endif - -# if defined(AV_WN32) && !defined(AV_WL32) -# define AV_WL32(p, v) AV_WN32(p, v) -# elif !defined(AV_WN32) && defined(AV_WL32) -# define AV_WN32(p, v) AV_WL32(p, v) -# endif - -# if defined(AV_RN64) && !defined(AV_RL64) -# define AV_RL64(p) AV_RN64(p) -# elif !defined(AV_RN64) && defined(AV_RL64) -# define AV_RN64(p) AV_RL64(p) -# endif - -# if defined(AV_WN64) && !defined(AV_WL64) -# define AV_WL64(p, v) AV_WN64(p, v) -# elif !defined(AV_WN64) && defined(AV_WL64) -# define AV_WN64(p, v) AV_WL64(p, v) -# endif - -#endif /* !HAVE_BIGENDIAN */ - -/* - * Define AV_[RW]N helper macros to simplify definitions not provided - * by per-arch headers. - */ - -#if HAVE_ATTRIBUTE_PACKED - -union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; -union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; -union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; - -# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) -# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) - -#elif defined(__DECC) - -# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) -# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) - -#elif HAVE_FAST_UNALIGNED - -# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s) -# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v)) - -#else - -#ifndef AV_RB16 -# define AV_RB16(x) \ - ((((const uint8_t*)(x))[0] << 8) | \ - ((const uint8_t*)(x))[1]) -#endif -#ifndef AV_WB16 -# define AV_WB16(p, d) do { \ - ((uint8_t*)(p))[1] = (d); \ - ((uint8_t*)(p))[0] = (d)>>8; \ - } while(0) -#endif - -#ifndef AV_RL16 -# define AV_RL16(x) \ - ((((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[0]) -#endif -#ifndef AV_WL16 -# define AV_WL16(p, d) do { \ - ((uint8_t*)(p))[0] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - } while(0) -#endif - -#ifndef AV_RB32 -# define AV_RB32(x) \ - ((((const uint8_t*)(x))[0] << 24) | \ - (((const uint8_t*)(x))[1] << 16) | \ - (((const uint8_t*)(x))[2] << 8) | \ - ((const uint8_t*)(x))[3]) -#endif -#ifndef AV_WB32 -# define AV_WB32(p, d) do { \ - ((uint8_t*)(p))[3] = (d); \ - ((uint8_t*)(p))[2] = (d)>>8; \ - ((uint8_t*)(p))[1] = (d)>>16; \ - ((uint8_t*)(p))[0] = (d)>>24; \ - } while(0) -#endif - -#ifndef AV_RL32 -# define AV_RL32(x) \ - ((((const uint8_t*)(x))[3] << 24) | \ - (((const uint8_t*)(x))[2] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[0]) -#endif -#ifndef AV_WL32 -# define AV_WL32(p, d) do { \ - ((uint8_t*)(p))[0] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - ((uint8_t*)(p))[2] = (d)>>16; \ - ((uint8_t*)(p))[3] = (d)>>24; \ - } while(0) -#endif - -#ifndef AV_RB64 -# define AV_RB64(x) \ - (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ - ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ - ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ - ((uint64_t)((const uint8_t*)(x))[3] << 32) | \ - ((uint64_t)((const uint8_t*)(x))[4] << 24) | \ - ((uint64_t)((const uint8_t*)(x))[5] << 16) | \ - ((uint64_t)((const uint8_t*)(x))[6] << 8) | \ - (uint64_t)((const uint8_t*)(x))[7]) -#endif -#ifndef AV_WB64 -# define AV_WB64(p, d) do { \ - ((uint8_t*)(p))[7] = (d); \ - ((uint8_t*)(p))[6] = (d)>>8; \ - ((uint8_t*)(p))[5] = (d)>>16; \ - ((uint8_t*)(p))[4] = (d)>>24; \ - ((uint8_t*)(p))[3] = (d)>>32; \ - ((uint8_t*)(p))[2] = (d)>>40; \ - ((uint8_t*)(p))[1] = (d)>>48; \ - ((uint8_t*)(p))[0] = (d)>>56; \ - } while(0) -#endif - -#ifndef AV_RL64 -# define AV_RL64(x) \ - (((uint64_t)((const uint8_t*)(x))[7] << 56) | \ - ((uint64_t)((const uint8_t*)(x))[6] << 48) | \ - ((uint64_t)((const uint8_t*)(x))[5] << 40) | \ - ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ - ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ - ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ - ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ - (uint64_t)((const uint8_t*)(x))[0]) -#endif -#ifndef AV_WL64 -# define AV_WL64(p, d) do { \ - ((uint8_t*)(p))[0] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - ((uint8_t*)(p))[2] = (d)>>16; \ - ((uint8_t*)(p))[3] = (d)>>24; \ - ((uint8_t*)(p))[4] = (d)>>32; \ - ((uint8_t*)(p))[5] = (d)>>40; \ - ((uint8_t*)(p))[6] = (d)>>48; \ - ((uint8_t*)(p))[7] = (d)>>56; \ - } while(0) -#endif - -#if HAVE_BIGENDIAN -# define AV_RN(s, p) AV_RB##s(p) -# define AV_WN(s, p, v) AV_WB##s(p, v) -#else -# define AV_RN(s, p) AV_RL##s(p) -# define AV_WN(s, p, v) AV_WL##s(p, v) -#endif - -#endif /* HAVE_FAST_UNALIGNED */ - -#ifndef AV_RN16 -# define AV_RN16(p) AV_RN(16, p) -#endif - -#ifndef AV_RN32 -# define AV_RN32(p) AV_RN(32, p) -#endif - -#ifndef AV_RN64 -# define AV_RN64(p) AV_RN(64, p) -#endif - -#ifndef AV_WN16 -# define AV_WN16(p, v) AV_WN(16, p, v) -#endif - -#ifndef AV_WN32 -# define AV_WN32(p, v) AV_WN(32, p, v) -#endif - -#ifndef AV_WN64 -# define AV_WN64(p, v) AV_WN(64, p, v) -#endif - -#if HAVE_BIGENDIAN -# define AV_RB(s, p) AV_RN##s(p) -# define AV_WB(s, p, v) AV_WN##s(p, v) -# define AV_RL(s, p) bswap_##s(AV_RN##s(p)) -# define AV_WL(s, p, v) AV_WN##s(p, bswap_##s(v)) -#else -# define AV_RB(s, p) bswap_##s(AV_RN##s(p)) -# define AV_WB(s, p, v) AV_WN##s(p, bswap_##s(v)) -# define AV_RL(s, p) AV_RN##s(p) -# define AV_WL(s, p, v) AV_WN##s(p, v) -#endif - -#define AV_RB8(x) (((const uint8_t*)(x))[0]) -#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0) - -#define AV_RL8(x) AV_RB8(x) -#define AV_WL8(p, d) AV_WB8(p, d) - -#ifndef AV_RB16 -# define AV_RB16(p) AV_RB(16, p) -#endif -#ifndef AV_WB16 -# define AV_WB16(p, v) AV_WB(16, p, v) -#endif - -#ifndef AV_RL16 -# define AV_RL16(p) AV_RL(16, p) -#endif -#ifndef AV_WL16 -# define AV_WL16(p, v) AV_WL(16, p, v) -#endif - -#ifndef AV_RB32 -# define AV_RB32(p) AV_RB(32, p) -#endif -#ifndef AV_WB32 -# define AV_WB32(p, v) AV_WB(32, p, v) -#endif - -#ifndef AV_RL32 -# define AV_RL32(p) AV_RL(32, p) -#endif -#ifndef AV_WL32 -# define AV_WL32(p, v) AV_WL(32, p, v) -#endif - -#ifndef AV_RB64 -# define AV_RB64(p) AV_RB(64, p) -#endif -#ifndef AV_WB64 -# define AV_WB64(p, v) AV_WB(64, p, v) -#endif - -#ifndef AV_RL64 -# define AV_RL64(p) AV_RL(64, p) -#endif -#ifndef AV_WL64 -# define AV_WL64(p, v) AV_WL(64, p, v) -#endif - -#ifndef AV_RB24 -# define AV_RB24(x) \ - ((((const uint8_t*)(x))[0] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[2]) -#endif -#ifndef AV_WB24 -# define AV_WB24(p, d) do { \ - ((uint8_t*)(p))[2] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - ((uint8_t*)(p))[0] = (d)>>16; \ - } while(0) -#endif - -#ifndef AV_RL24 -# define AV_RL24(x) \ - ((((const uint8_t*)(x))[2] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[0]) -#endif -#ifndef AV_WL24 -# define AV_WL24(p, d) do { \ - ((uint8_t*)(p))[0] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - ((uint8_t*)(p))[2] = (d)>>16; \ - } while(0) -#endif - -/* - * The AV_[RW]NA macros access naturally aligned data - * in a type-safe way. - */ - -#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s) -#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v)) - -#ifndef AV_RN16A -# define AV_RN16A(p) AV_RNA(16, p) -#endif - -#ifndef AV_RN32A -# define AV_RN32A(p) AV_RNA(32, p) -#endif - -#ifndef AV_RN64A -# define AV_RN64A(p) AV_RNA(64, p) -#endif - -#ifndef AV_WN16A -# define AV_WN16A(p, v) AV_WNA(16, p, v) -#endif - -#ifndef AV_WN32A -# define AV_WN32A(p, v) AV_WNA(32, p, v) -#endif - -#ifndef AV_WN64A -# define AV_WN64A(p, v) AV_WNA(64, p, v) -#endif - -/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be - * naturally aligned. They may be implemented using MMX, - * so emms_c() must be called before using any float code - * afterwards. - */ - -#define AV_COPY(n, d, s) \ - (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n) - -#ifndef AV_COPY16 -# define AV_COPY16(d, s) AV_COPY(16, d, s) -#endif - -#ifndef AV_COPY32 -# define AV_COPY32(d, s) AV_COPY(32, d, s) -#endif - -#ifndef AV_COPY64 -# define AV_COPY64(d, s) AV_COPY(64, d, s) -#endif - -#ifndef AV_COPY128 -# define AV_COPY128(d, s) \ - do { \ - AV_COPY64(d, s); \ - AV_COPY64((char*)(d)+8, (char*)(s)+8); \ - } while(0) -#endif - -#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b)) - -#ifndef AV_SWAP64 -# define AV_SWAP64(a, b) AV_SWAP(64, a, b) -#endif - -#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0) - -#ifndef AV_ZERO16 -# define AV_ZERO16(d) AV_ZERO(16, d) -#endif - -#ifndef AV_ZERO32 -# define AV_ZERO32(d) AV_ZERO(32, d) -#endif - -#ifndef AV_ZERO64 -# define AV_ZERO64(d) AV_ZERO(64, d) -#endif - -#ifndef AV_ZERO128 -# define AV_ZERO128(d) \ - do { \ - AV_ZERO64(d); \ - AV_ZERO64((char*)(d)+8); \ - } while(0) -#endif - -#endif /* AVUTIL_INTREADWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/lfg.c b/tizen/distrib/ffmpeg/libavutil/lfg.c deleted file mode 100644 index 1dad4e4..0000000 --- a/tizen/distrib/ffmpeg/libavutil/lfg.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Lagged Fibonacci PRNG - * Copyright (c) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "lfg.h" -#include "md5.h" -#include "intreadwrite.h" -#include "attributes.h" - -void av_cold av_lfg_init(AVLFG *c, unsigned int seed){ - uint8_t tmp[16]={0}; - int i; - - for(i=8; i<64; i+=4){ - AV_WL32(tmp, seed); tmp[4]=i; - av_md5_sum(tmp, tmp, 16); - c->state[i ]= AV_RL32(tmp); - c->state[i+1]= AV_RL32(tmp+4); - c->state[i+2]= AV_RL32(tmp+8); - c->state[i+3]= AV_RL32(tmp+12); - } - c->index=0; -} - -void av_bmg_get(AVLFG *lfg, double out[2]) -{ - double x1, x2, w; - - do { - x1 = 2.0/UINT_MAX*av_lfg_get(lfg) - 1.0; - x2 = 2.0/UINT_MAX*av_lfg_get(lfg) - 1.0; - w = x1*x1 + x2*x2; - } while (w >= 1.0); - - w = sqrt((-2.0 * log(w)) / w); - out[0] = x1 * w; - out[1] = x2 * w; -} - -#ifdef TEST -#include "log.h" -#include "timer.h" - -int main(void) -{ - int x=0; - int i, j; - AVLFG state; - - av_lfg_init(&state, 0xdeadbeef); - for (j = 0; j < 10000; j++) { - START_TIMER - for (i = 0; i < 624; i++) { -// av_log(NULL,AV_LOG_ERROR, "%X\n", av_lfg_get(&state)); - x+=av_lfg_get(&state); - } - STOP_TIMER("624 calls of av_lfg_get"); - } - av_log(NULL, AV_LOG_ERROR, "final value:%X\n", x); - - /* BMG usage example */ - { - double mean = 1000; - double stddev = 53; - - av_lfg_init(&state, 42); - - for (i = 0; i < 1000; i += 2) { - double bmg_out[2]; - av_bmg_get(&state, bmg_out); - av_log(NULL, AV_LOG_INFO, - "%f\n%f\n", - bmg_out[0] * stddev + mean, - bmg_out[1] * stddev + mean); - } - } - - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/lfg.h b/tizen/distrib/ffmpeg/libavutil/lfg.h deleted file mode 100644 index ac89d12..0000000 --- a/tizen/distrib/ffmpeg/libavutil/lfg.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Lagged Fibonacci PRNG - * Copyright (c) 2008 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LFG_H -#define AVUTIL_LFG_H - -typedef struct { - unsigned int state[64]; - int index; -} AVLFG; - -void av_lfg_init(AVLFG *c, unsigned int seed); - -/** - * Gets the next random unsigned 32-bit number using an ALFG. - * - * Please also consider a simple LCG like state= state*1664525+1013904223, - * it may be good enough and faster for your specific use case. - */ -static inline unsigned int av_lfg_get(AVLFG *c){ - c->state[c->index & 63] = c->state[(c->index-24) & 63] + c->state[(c->index-55) & 63]; - return c->state[c->index++ & 63]; -} - -/** - * Gets the next random unsigned 32-bit number using a MLFG. - * - * Please also consider av_lfg_get() above, it is faster. - */ -static inline unsigned int av_mlfg_get(AVLFG *c){ - unsigned int a= c->state[(c->index-55) & 63]; - unsigned int b= c->state[(c->index-24) & 63]; - return c->state[c->index++ & 63] = 2*a*b+a+b; -} - -/** - * Gets the next two numbers generated by a Box-Muller Gaussian - * generator using the random numbers issued by lfg. - * - * @param out[2] array where are placed the two generated numbers - */ -void av_bmg_get(AVLFG *lfg, double out[2]); - -#endif /* AVUTIL_LFG_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/libavutil.v b/tizen/distrib/ffmpeg/libavutil/libavutil.v deleted file mode 100644 index ec52f2b..0000000 --- a/tizen/distrib/ffmpeg/libavutil/libavutil.v +++ /dev/null @@ -1,4 +0,0 @@ -LIBAVUTIL_$MAJOR { - global: av_*; ff_*; avutil_*; - local: *; -}; diff --git a/tizen/distrib/ffmpeg/libavutil/libm.h b/tizen/distrib/ffmpeg/libavutil/libm.h deleted file mode 100644 index c7c28ac..0000000 --- a/tizen/distrib/ffmpeg/libavutil/libm.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Replacements for frequently missing libm functions - */ - -#ifndef AVUTIL_LIBM_H -#define AVUTIL_LIBM_H - -#include -#include "config.h" -#include "attributes.h" - -#if !HAVE_EXP2 -#undef exp2 -#define exp2(x) exp((x) * 0.693147180559945) -#endif /* HAVE_EXP2 */ - -#if !HAVE_EXP2F -#undef exp2f -#define exp2f(x) ((float)exp2(x)) -#endif /* HAVE_EXP2F */ - -#if !HAVE_LLRINT -#undef llrint -#define llrint(x) ((long long)rint(x)) -#endif /* HAVE_LLRINT */ - -#if !HAVE_LLRINTF -#undef llrintf -#define llrintf(x) ((long long)rint(x)) -#endif /* HAVE_LLRINT */ - -#if !HAVE_LOG2 -#undef log2 -#define log2(x) (log(x) * 1.44269504088896340736) -#endif /* HAVE_LOG2 */ - -#if !HAVE_LOG2F -#undef log2f -#define log2f(x) ((float)log2(x)) -#endif /* HAVE_LOG2F */ - -#if !HAVE_LRINT -static av_always_inline av_const long int lrint(double x) -{ - return rint(x); -} -#endif /* HAVE_LRINT */ - -#if !HAVE_LRINTF -static av_always_inline av_const long int lrintf(float x) -{ - return (int)(rint(x)); -} -#endif /* HAVE_LRINTF */ - -#if !HAVE_ROUND -static av_always_inline av_const double round(double x) -{ - return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); -} -#endif /* HAVE_ROUND */ - -#if !HAVE_ROUNDF -static av_always_inline av_const float roundf(float x) -{ - return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5); -} -#endif /* HAVE_ROUNDF */ - -#if !HAVE_TRUNCF -static av_always_inline av_const float truncf(float x) -{ - return (x > 0) ? floor(x) : ceil(x); -} -#endif /* HAVE_TRUNCF */ - -#endif /* AVUTIL_LIBM_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/lls.c b/tizen/distrib/ffmpeg/libavutil/lls.c deleted file mode 100644 index 3855792..0000000 --- a/tizen/distrib/ffmpeg/libavutil/lls.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * linear least squares model - * - * Copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * linear least squares model - */ - -#include -#include - -#include "lls.h" - -void av_init_lls(LLSModel *m, int indep_count){ - memset(m, 0, sizeof(LLSModel)); - - m->indep_count= indep_count; -} - -void av_update_lls(LLSModel *m, double *var, double decay){ - int i,j; - - for(i=0; i<=m->indep_count; i++){ - for(j=i; j<=m->indep_count; j++){ - m->covariance[i][j] *= decay; - m->covariance[i][j] += var[i]*var[j]; - } - } -} - -void av_solve_lls(LLSModel *m, double threshold, int min_order){ - int i,j,k; - double (*factor)[MAX_VARS+1]= (void*)&m->covariance[1][0]; - double (*covar )[MAX_VARS+1]= (void*)&m->covariance[1][1]; - double *covar_y = m->covariance[0]; - int count= m->indep_count; - - for(i=0; i=0; k--) - sum -= factor[i][k]*factor[j][k]; - - if(i==j){ - if(sum < threshold) - sum= 1.0; - factor[i][i]= sqrt(sum); - }else - factor[j][i]= sum / factor[i][i]; - } - } - for(i=0; i=0; k--) - sum -= factor[i][k]*m->coeff[0][k]; - m->coeff[0][i]= sum / factor[i][i]; - } - - for(j=count-1; j>=min_order; j--){ - for(i=j; i>=0; i--){ - double sum= m->coeff[0][i]; - for(k=i+1; k<=j; k++) - sum -= factor[k][i]*m->coeff[j][k]; - m->coeff[j][i]= sum / factor[i][i]; - } - - m->variance[j]= covar_y[0]; - for(i=0; i<=j; i++){ - double sum= m->coeff[j][i]*covar[i][i] - 2*covar_y[i+1]; - for(k=0; kcoeff[j][k]*covar[k][i]; - m->variance[j] += m->coeff[j][i]*sum; - } - } -} - -double av_evaluate_lls(LLSModel *m, double *param, int order){ - int i; - double out= 0; - - for(i=0; i<=order; i++) - out+= param[i]*m->coeff[order][i]; - - return out; -} - -#ifdef TEST - -#include -#include - -int main(void){ - LLSModel m; - int i, order; - - av_init_lls(&m, 3); - - for(i=0; i<100; i++){ - double var[4]; - double eval; - var[0] = (rand() / (double)RAND_MAX - 0.5)*2; - var[1] = var[0] + rand() / (double)RAND_MAX - 0.5; - var[2] = var[1] + rand() / (double)RAND_MAX - 0.5; - var[3] = var[2] + rand() / (double)RAND_MAX - 0.5; - av_update_lls(&m, var, 0.99); - av_solve_lls(&m, 0.001, 0); - for(order=0; order<3; order++){ - eval= av_evaluate_lls(&m, var+1, order); - printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n", - var[0], order, eval, sqrt(m.variance[order] / (i+1)), - m.coeff[order][0], m.coeff[order][1], m.coeff[order][2]); - } - } - return 0; -} - -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/lls.h b/tizen/distrib/ffmpeg/libavutil/lls.h deleted file mode 100644 index d168e59..0000000 --- a/tizen/distrib/ffmpeg/libavutil/lls.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linear least squares model - * - * Copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LLS_H -#define AVUTIL_LLS_H - -#define MAX_VARS 32 - -//FIXME avoid direct access to LLSModel from outside - -/** - * Linear least squares model. - */ -typedef struct LLSModel{ - double covariance[MAX_VARS+1][MAX_VARS+1]; - double coeff[MAX_VARS][MAX_VARS]; - double variance[MAX_VARS]; - int indep_count; -}LLSModel; - -void av_init_lls(LLSModel *m, int indep_count); -void av_update_lls(LLSModel *m, double *param, double decay); -void av_solve_lls(LLSModel *m, double threshold, int min_order); -double av_evaluate_lls(LLSModel *m, double *param, int order); - -#endif /* AVUTIL_LLS_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/log.c b/tizen/distrib/ffmpeg/libavutil/log.c deleted file mode 100644 index 9a8b66e..0000000 --- a/tizen/distrib/ffmpeg/libavutil/log.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * log functions - * Copyright (c) 2003 Michel Bardiaux - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * logging functions - */ - -#include -#include -#include "avutil.h" -#include "log.h" - -#if LIBAVUTIL_VERSION_MAJOR > 50 -static -#endif -int av_log_level = AV_LOG_INFO; - -static int use_ansi_color=-1; - -#undef fprintf -static void colored_fputs(int color, const char *str){ - if(use_ansi_color<0){ -#if HAVE_ISATTY && !defined(_WIN32) - use_ansi_color= getenv("TERM") && !getenv("NO_COLOR") && isatty(2); -#else - use_ansi_color= 0; -#endif - } - - if(use_ansi_color){ - fprintf(stderr, "\033[%d;3%dm", color>>4, color&15); - } - fputs(str, stderr); - if(use_ansi_color){ - fprintf(stderr, "\033[0m"); - } -} - -void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) -{ - static int print_prefix=1; - static int count; - static char line[1024], prev[1024]; - static const uint8_t color[]={0x41,0x41,0x11,0x03,9,9,9}; - AVClass* avc= ptr ? *(AVClass**)ptr : NULL; - if(level>av_log_level) - return; -#undef fprintf - if(print_prefix && avc) { - snprintf(line, sizeof(line), "[%s @ %p]", avc->item_name(ptr), ptr); - }else - line[0]=0; - - vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl); - - print_prefix= line[strlen(line)-1] == '\n'; - if(print_prefix && !strcmp(line, prev)){ - count++; - return; - } - if(count>0){ - fprintf(stderr, " Last message repeated %d times\n", count); - count=0; - } - colored_fputs(color[av_clip(level>>3, 0, 6)], line); - strcpy(prev, line); -} - -static void (*av_log_callback)(void*, int, const char*, va_list) = av_log_default_callback; - -void av_log(void* avcl, int level, const char *fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - av_vlog(avcl, level, fmt, vl); - va_end(vl); -} - -void av_vlog(void* avcl, int level, const char *fmt, va_list vl) -{ - av_log_callback(avcl, level, fmt, vl); -} - -int av_log_get_level(void) -{ - return av_log_level; -} - -void av_log_set_level(int level) -{ - av_log_level = level; -} - -void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)) -{ - av_log_callback = callback; -} diff --git a/tizen/distrib/ffmpeg/libavutil/log.h b/tizen/distrib/ffmpeg/libavutil/log.h deleted file mode 100644 index 1c3e490..0000000 --- a/tizen/distrib/ffmpeg/libavutil/log.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LOG_H -#define AVUTIL_LOG_H - -#include -#include "avutil.h" - -/** - * Describes the class of an AVClass context structure. That is an - * arbitrary struct of which the first field is a pointer to an - * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). - */ -typedef struct { - /** - * The name of the class; usually it is the same name as the - * context structure type to which the AVClass is associated. - */ - const char* class_name; - - /** - * A pointer to a function which returns the name of a context - * instance ctx associated with the class. - */ - const char* (*item_name)(void* ctx); - - /** - * a pointer to the first option specified in the class if any or NULL - * - * @see av_set_default_options() - */ - const struct AVOption *option; - - /** - * LIBAVUTIL_VERSION with which this structure was created. - * This is used to allow fields to be added without requiring major - * version bumps everywhere. - */ - - int version; -} AVClass; - -/* av_log API */ - -#define AV_LOG_QUIET -8 - -/** - * Something went really wrong and we will crash now. - */ -#define AV_LOG_PANIC 0 - -/** - * Something went wrong and recovery is not possible. - * For example, no header was found for a format which depends - * on headers or an illegal combination of parameters is used. - */ -#define AV_LOG_FATAL 8 - -/** - * Something went wrong and cannot losslessly be recovered. - * However, not all future data is affected. - */ -#define AV_LOG_ERROR 16 - -/** - * Something somehow does not look correct. This may or may not - * lead to problems. An example would be the use of '-vstrict -2'. - */ -#define AV_LOG_WARNING 24 - -#define AV_LOG_INFO 32 -#define AV_LOG_VERBOSE 40 - -/** - * Stuff which is only useful for libav* developers. - */ -#define AV_LOG_DEBUG 48 - -/** - * Sends the specified message to the log if the level is less than or equal - * to the current av_log_level. By default, all logging messages are sent to - * stderr. This behavior can be altered by setting a different av_vlog callback - * function. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - * @see av_vlog - */ -#ifdef __GNUC__ -void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); -#else -void av_log(void*, int level, const char *fmt, ...); -#endif - -void av_vlog(void*, int level, const char *fmt, va_list); -int av_log_get_level(void); -void av_log_set_level(int); -void av_log_set_callback(void (*)(void*, int, const char*, va_list)); -void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); - -#endif /* AVUTIL_LOG_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/lzo.c b/tizen/distrib/ffmpeg/libavutil/lzo.c deleted file mode 100644 index a876fc7..0000000 --- a/tizen/distrib/ffmpeg/libavutil/lzo.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * LZO 1x decompression - * Copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avutil.h" -#include "common.h" -//! Avoid e.g. MPlayers fast_memcpy, it slows things down here. -#undef memcpy -#include -#include "lzo.h" - -//! Define if we may write up to 12 bytes beyond the output buffer. -#define OUTBUF_PADDED 1 -//! Define if we may read up to 8 bytes beyond the input buffer. -#define INBUF_PADDED 1 -typedef struct LZOContext { - const uint8_t *in, *in_end; - uint8_t *out_start, *out, *out_end; - int error; -} LZOContext; - -/** - * \brief Reads one byte from the input buffer, avoiding an overrun. - * \return byte read - */ -static inline int get_byte(LZOContext *c) { - if (c->in < c->in_end) - return *c->in++; - c->error |= AV_LZO_INPUT_DEPLETED; - return 1; -} - -#ifdef INBUF_PADDED -#define GETB(c) (*(c).in++) -#else -#define GETB(c) get_byte(&(c)) -#endif - -/** - * \brief Decodes a length value in the coding used by lzo. - * \param x previous byte value - * \param mask bits used from x - * \return decoded length value - */ -static inline int get_len(LZOContext *c, int x, int mask) { - int cnt = x & mask; - if (!cnt) { - while (!(x = get_byte(c))) cnt += 255; - cnt += mask + x; - } - return cnt; -} - -//#define UNALIGNED_LOADSTORE -#define BUILTIN_MEMCPY -#ifdef UNALIGNED_LOADSTORE -#define COPY2(d, s) *(uint16_t *)(d) = *(uint16_t *)(s); -#define COPY4(d, s) *(uint32_t *)(d) = *(uint32_t *)(s); -#elif defined(BUILTIN_MEMCPY) -#define COPY2(d, s) memcpy(d, s, 2); -#define COPY4(d, s) memcpy(d, s, 4); -#else -#define COPY2(d, s) (d)[0] = (s)[0]; (d)[1] = (s)[1]; -#define COPY4(d, s) (d)[0] = (s)[0]; (d)[1] = (s)[1]; (d)[2] = (s)[2]; (d)[3] = (s)[3]; -#endif - -/** - * \brief Copies bytes from input to output buffer with checking. - * \param cnt number of bytes to copy, must be >= 0 - */ -static inline void copy(LZOContext *c, int cnt) { - register const uint8_t *src = c->in; - register uint8_t *dst = c->out; - if (cnt > c->in_end - src) { - cnt = FFMAX(c->in_end - src, 0); - c->error |= AV_LZO_INPUT_DEPLETED; - } - if (cnt > c->out_end - dst) { - cnt = FFMAX(c->out_end - dst, 0); - c->error |= AV_LZO_OUTPUT_FULL; - } -#if defined(INBUF_PADDED) && defined(OUTBUF_PADDED) - COPY4(dst, src); - src += 4; - dst += 4; - cnt -= 4; - if (cnt > 0) -#endif - memcpy(dst, src, cnt); - c->in = src + cnt; - c->out = dst + cnt; -} - -static inline void memcpy_backptr(uint8_t *dst, int back, int cnt); - -/** - * \brief Copies previously decoded bytes to current position. - * \param back how many bytes back we start - * \param cnt number of bytes to copy, must be >= 0 - * - * cnt > back is valid, this will copy the bytes we just copied, - * thus creating a repeating pattern with a period length of back. - */ -static inline void copy_backptr(LZOContext *c, int back, int cnt) { - register const uint8_t *src = &c->out[-back]; - register uint8_t *dst = c->out; - if (src < c->out_start || src > dst) { - c->error |= AV_LZO_INVALID_BACKPTR; - return; - } - if (cnt > c->out_end - dst) { - cnt = FFMAX(c->out_end - dst, 0); - c->error |= AV_LZO_OUTPUT_FULL; - } - memcpy_backptr(dst, back, cnt); - c->out = dst + cnt; -} - -static inline void memcpy_backptr(uint8_t *dst, int back, int cnt) { - const uint8_t *src = &dst[-back]; - if (back == 1) { - memset(dst, *src, cnt); - } else { -#ifdef OUTBUF_PADDED - COPY2(dst, src); - COPY2(dst + 2, src + 2); - src += 4; - dst += 4; - cnt -= 4; - if (cnt > 0) { - COPY2(dst, src); - COPY2(dst + 2, src + 2); - COPY2(dst + 4, src + 4); - COPY2(dst + 6, src + 6); - src += 8; - dst += 8; - cnt -= 8; - } -#endif - if (cnt > 0) { - int blocklen = back; - while (cnt > blocklen) { - memcpy(dst, src, blocklen); - dst += blocklen; - cnt -= blocklen; - blocklen <<= 1; - } - memcpy(dst, src, cnt); - } - } -} - -void av_memcpy_backptr(uint8_t *dst, int back, int cnt) { - memcpy_backptr(dst, back, cnt); -} - -int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen) { - int state= 0; - int x; - LZOContext c; - c.in = in; - c.in_end = (const uint8_t *)in + *inlen; - c.out = c.out_start = out; - c.out_end = (uint8_t *)out + * outlen; - c.error = 0; - x = GETB(c); - if (x > 17) { - copy(&c, x - 17); - x = GETB(c); - if (x < 16) c.error |= AV_LZO_ERROR; - } - if (c.in > c.in_end) - c.error |= AV_LZO_INPUT_DEPLETED; - while (!c.error) { - int cnt, back; - if (x > 15) { - if (x > 63) { - cnt = (x >> 5) - 1; - back = (GETB(c) << 3) + ((x >> 2) & 7) + 1; - } else if (x > 31) { - cnt = get_len(&c, x, 31); - x = GETB(c); - back = (GETB(c) << 6) + (x >> 2) + 1; - } else { - cnt = get_len(&c, x, 7); - back = (1 << 14) + ((x & 8) << 11); - x = GETB(c); - back += (GETB(c) << 6) + (x >> 2); - if (back == (1 << 14)) { - if (cnt != 1) - c.error |= AV_LZO_ERROR; - break; - } - } - } else if(!state){ - cnt = get_len(&c, x, 15); - copy(&c, cnt + 3); - x = GETB(c); - if (x > 15) - continue; - cnt = 1; - back = (1 << 11) + (GETB(c) << 2) + (x >> 2) + 1; - } else { - cnt = 0; - back = (GETB(c) << 2) + (x >> 2) + 1; - } - copy_backptr(&c, back, cnt + 2); - state= - cnt = x & 3; - copy(&c, cnt); - x = GETB(c); - } - *inlen = c.in_end - c.in; - if (c.in > c.in_end) - *inlen = 0; - *outlen = c.out_end - c.out; - return c.error; -} - -#ifdef TEST -#include -#include -#include "log.h" -#define MAXSZ (10*1024*1024) - -/* Define one of these to 1 if you wish to benchmark liblzo - * instead of our native implementation. */ -#define BENCHMARK_LIBLZO_SAFE 0 -#define BENCHMARK_LIBLZO_UNSAFE 0 - -int main(int argc, char *argv[]) { - FILE *in = fopen(argv[1], "rb"); - uint8_t *orig = av_malloc(MAXSZ + 16); - uint8_t *comp = av_malloc(2*MAXSZ + 16); - uint8_t *decomp = av_malloc(MAXSZ + 16); - size_t s = fread(orig, 1, MAXSZ, in); - lzo_uint clen = 0; - long tmp[LZO1X_MEM_COMPRESS]; - int inlen, outlen; - int i; - av_log_set_level(AV_LOG_DEBUG); - lzo1x_999_compress(orig, s, comp, &clen, tmp); - for (i = 0; i < 300; i++) { -START_TIMER - inlen = clen; outlen = MAXSZ; -#if BENCHMARK_LIBLZO_SAFE - if (lzo1x_decompress_safe(comp, inlen, decomp, &outlen, NULL)) -#elif BENCHMARK_LIBLZO_UNSAFE - if (lzo1x_decompress(comp, inlen, decomp, &outlen, NULL)) -#else - if (av_lzo1x_decode(decomp, &outlen, comp, &inlen)) -#endif - av_log(NULL, AV_LOG_ERROR, "decompression error\n"); -STOP_TIMER("lzod") - } - if (memcmp(orig, decomp, s)) - av_log(NULL, AV_LOG_ERROR, "decompression incorrect\n"); - else - av_log(NULL, AV_LOG_ERROR, "decompression OK\n"); - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/lzo.h b/tizen/distrib/ffmpeg/libavutil/lzo.h deleted file mode 100644 index 6788054..0000000 --- a/tizen/distrib/ffmpeg/libavutil/lzo.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * LZO 1x decompression - * copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_LZO_H -#define AVUTIL_LZO_H - -#include - -/** \defgroup errflags Error flags returned by av_lzo1x_decode - * \{ */ -//! end of the input buffer reached before decoding finished -#define AV_LZO_INPUT_DEPLETED 1 -//! decoded data did not fit into output buffer -#define AV_LZO_OUTPUT_FULL 2 -//! a reference to previously decoded data was wrong -#define AV_LZO_INVALID_BACKPTR 4 -//! a non-specific error in the compressed bitstream -#define AV_LZO_ERROR 8 -/** \} */ - -#define AV_LZO_INPUT_PADDING 8 -#define AV_LZO_OUTPUT_PADDING 12 - -/** - * \brief Decodes LZO 1x compressed data. - * \param out output buffer - * \param outlen size of output buffer, number of bytes left are returned here - * \param in input buffer - * \param inlen size of input buffer, number of bytes left are returned here - * \return 0 on success, otherwise a combination of the error flags above - * - * Make sure all buffers are appropriately padded, in must provide - * AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes. - */ -int av_lzo1x_decode(void *out, int *outlen, const void *in, int *inlen); - -/** - * \brief deliberately overlapping memcpy implementation - * \param dst destination buffer; must be padded with 12 additional bytes - * \param back how many bytes back we start (the initial size of the overlapping window) - * \param cnt number of bytes to copy, must be >= 0 - * - * cnt > back is valid, this will copy the bytes we just copied, - * thus creating a repeating pattern with a period length of back. - */ -void av_memcpy_backptr(uint8_t *dst, int back, int cnt); - -#endif /* AVUTIL_LZO_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/mathematics.c b/tizen/distrib/ffmpeg/libavutil/mathematics.c deleted file mode 100644 index c06cb16..0000000 --- a/tizen/distrib/ffmpeg/libavutil/mathematics.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * miscellaneous math routines and tables - */ - -#include -#include -#include -#include "mathematics.h" - -const uint8_t ff_sqrt_tab[256]={ - 0, 16, 23, 28, 32, 36, 40, 43, 46, 48, 51, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 77, 79, 80, 82, 84, 85, 87, 88, 90, - 91, 92, 94, 95, 96, 98, 99,100,102,103,104,105,107,108,109,110,111,112,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,144,145,146,147,148,149,150,151,151,152,153,154,155,156,156, -157,158,159,160,160,161,162,163,164,164,165,166,167,168,168,169,170,171,171,172,173,174,174,175,176,176,177,178,179,179,180,181, -182,182,183,184,184,185,186,186,187,188,188,189,190,190,191,192,192,193,194,194,195,196,196,197,198,198,199,200,200,201,202,202, -203,204,204,205,205,206,207,207,208,208,209,210,210,211,212,212,213,213,214,215,215,216,216,217,218,218,219,219,220,220,221,222, -222,223,223,224,224,225,226,226,227,227,228,228,229,230,230,231,231,232,232,233,233,234,235,235,236,236,237,237,238,238,239,239, -240,240,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255,255 -}; - -const uint8_t ff_log2_tab[256]={ - 0,0,1,1,2,2,2,2,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,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, - 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, - 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, - 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, - 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 -}; - -const uint8_t av_reverse[256]={ -0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, -0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8, -0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4, -0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC, -0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2, -0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA, -0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6, -0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE, -0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1, -0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9, -0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5, -0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD, -0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3, -0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB, -0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7, -0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF, -}; - -int64_t av_gcd(int64_t a, int64_t b){ - if(b) return av_gcd(b, a%b); - else return a; -} - -int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ - int64_t r=0; - assert(c > 0); - assert(b >=0); - assert(rnd >=0 && rnd<=5 && rnd!=4); - - if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); - - if(rnd==AV_ROUND_NEAR_INF) r= c/2; - else if(rnd&1) r= c-1; - - if(b<=INT_MAX && c<=INT_MAX){ - if(a<=INT_MAX) - return (a * b + r)/c; - else - return a/c*b + (a%c*b + r)/c; - }else{ -#if 1 - uint64_t a0= a&0xFFFFFFFF; - uint64_t a1= a>>32; - uint64_t b0= b&0xFFFFFFFF; - uint64_t b1= b>>32; - uint64_t t1= a0*b1 + a1*b0; - uint64_t t1a= t1<<32; - int i; - - a0 = a0*b0 + t1a; - a1 = a1*b1 + (t1>>32) + (a0=0; i--){ -// int o= a1 & 0x8000000000000000ULL; - a1+= a1 + ((a0>>i)&1); - t1+=t1; - if(/*o || */c <= a1){ - a1 -= c; - t1++; - } - } - return t1; - } -#else - AVInteger ai; - ai= av_mul_i(av_int2i(a), av_int2i(b)); - ai= av_add_i(ai, av_int2i(r)); - - return av_i2int(av_div_i(ai, av_int2i(c))); - } -#endif -} - -int64_t av_rescale(int64_t a, int64_t b, int64_t c){ - return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); -} - -int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq){ - int64_t b= bq.num * (int64_t)cq.den; - int64_t c= cq.num * (int64_t)bq.den; - return av_rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); -} - -int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b){ - int64_t a= tb_a.num * (int64_t)tb_b.den; - int64_t b= tb_b.num * (int64_t)tb_a.den; - if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) return -1; - if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a) return 1; - return 0; -} - -#ifdef TEST -#include "integer.h" -#undef printf -int main(void){ - int64_t a,b,c,d,e; - - for(a=7; a<(1LL<<62); a+=a/3+1){ - for(b=3; b<(1LL<<62); b+=b/4+1){ - for(c=9; c<(1LL<<62); c+=(c*2)/5+3){ - int64_t r= c/2; - AVInteger ai; - ai= av_mul_i(av_int2i(a), av_int2i(b)); - ai= av_add_i(ai, av_int2i(r)); - - d= av_i2int(av_div_i(ai, av_int2i(c))); - - e= av_rescale(a,b,c); - - if((double)a * (double)b / (double)c > (1LL<<63)) - continue; - - if(d!=e) printf("%"PRId64"*%"PRId64"/%"PRId64"= %"PRId64"=%"PRId64"\n", a, b, c, d, e); - } - } - } - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/mathematics.h b/tizen/distrib/ffmpeg/libavutil/mathematics.h deleted file mode 100644 index e198aef..0000000 --- a/tizen/distrib/ffmpeg/libavutil/mathematics.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * copyright (c) 2005 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_MATHEMATICS_H -#define AVUTIL_MATHEMATICS_H - -#include -#include -#include "attributes.h" -#include "rational.h" - -#ifndef M_E -#define M_E 2.7182818284590452354 /* e */ -#endif -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 /* log_e 2 */ -#endif -#ifndef M_LN10 -#define M_LN10 2.30258509299404568402 /* log_e 10 */ -#endif -#ifndef M_LOG2_10 -#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ -#endif -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif -#ifndef M_SQRT1_2 -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ -#endif -#ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#endif -#ifndef NAN -#define NAN (0.0/0.0) -#endif -#ifndef INFINITY -#define INFINITY (1.0/0.0) -#endif - -enum AVRounding { - AV_ROUND_ZERO = 0, ///< Round toward zero. - AV_ROUND_INF = 1, ///< Round away from zero. - AV_ROUND_DOWN = 2, ///< Round toward -infinity. - AV_ROUND_UP = 3, ///< Round toward +infinity. - AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. -}; - -/** - * Returns the greatest common divisor of a and b. - * If both a and b are 0 or either or both are <0 then behavior is - * undefined. - */ -int64_t av_const av_gcd(int64_t a, int64_t b); - -/** - * Rescales a 64-bit integer with rounding to nearest. - * A simple a*b/c isn't possible as it can overflow. - */ -int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; - -/** - * Rescales a 64-bit integer with specified rounding. - * A simple a*b/c isn't possible as it can overflow. - */ -int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const; - -/** - * Rescales a 64-bit integer by 2 rational numbers. - */ -int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; - -/** - * Compares 2 timestamps each in its own timebases. - * The result of the function is undefined if one of the timestamps - * is outside the int64_t range when represented in the others timebase. - * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position - */ -int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); - - -#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/md5.c b/tizen/distrib/ffmpeg/libavutil/md5.c deleted file mode 100644 index 39ee624..0000000 --- a/tizen/distrib/ffmpeg/libavutil/md5.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2006 Michael Niedermayer (michaelni@gmx.at) - * Copyright (C) 2003-2005 by Christopher R. Hertel (crh@ubiqx.mn.org) - * - * References: - * IETF RFC 1321: The MD5 Message-Digest Algorithm - * Ron Rivest. IETF, April, 1992 - * - * based on http://ubiqx.org/libcifs/source/Auth/MD5.c - * from Christopher R. Hertel (crh@ubiqx.mn.org) - * Simplified, cleaned and IMO redundant comments removed by michael. - * - * If you use gcc, then version 4.1 or later and -fomit-frame-pointer is - * strongly recommended. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "bswap.h" -#include "md5.h" - -typedef struct AVMD5{ - uint64_t len; - uint8_t block[64]; - uint32_t ABCD[4]; -} AVMD5; - -const int av_md5_size= sizeof(AVMD5); - -static const uint8_t S[4][4] = { - { 7, 12, 17, 22 }, /* round 1 */ - { 5, 9, 14, 20 }, /* round 2 */ - { 4, 11, 16, 23 }, /* round 3 */ - { 6, 10, 15, 21 } /* round 4 */ -}; - -static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32) - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* round 1 */ - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* round 2 */ - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* round 3 */ - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* round 4 */ - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, -}; - -#define CORE(i, a, b, c, d) \ - t = S[i>>4][i&3];\ - a += T[i];\ -\ - if(i<32){\ - if(i<16) a += (d ^ (b&(c^d))) + X[ i &15 ];\ - else a += (c ^ (d&(c^b))) + X[ (1+5*i)&15 ];\ - }else{\ - if(i<48) a += (b^c^d) + X[ (5+3*i)&15 ];\ - else a += (c^(b|~d)) + X[ ( 7*i)&15 ];\ - }\ - a = b + (( a << t ) | ( a >> (32 - t) )); - -static void body(uint32_t ABCD[4], uint32_t X[16]){ - - int t; - int i av_unused; - unsigned int a= ABCD[3]; - unsigned int b= ABCD[2]; - unsigned int c= ABCD[1]; - unsigned int d= ABCD[0]; - -#if HAVE_BIGENDIAN - for(i=0; i<16; i++) - X[i]= bswap_32(X[i]); -#endif - -#if CONFIG_SMALL - for( i = 0; i < 64; i++ ){ - CORE(i,a,b,c,d) - t=d; d=c; c=b; b=a; a=t; - } -#else -#define CORE2(i) CORE(i,a,b,c,d) CORE((i+1),d,a,b,c) CORE((i+2),c,d,a,b) CORE((i+3),b,c,d,a) -#define CORE4(i) CORE2(i) CORE2((i+4)) CORE2((i+8)) CORE2((i+12)) -CORE4(0) CORE4(16) CORE4(32) CORE4(48) -#endif - - ABCD[0] += d; - ABCD[1] += c; - ABCD[2] += b; - ABCD[3] += a; -} - -void av_md5_init(AVMD5 *ctx){ - ctx->len = 0; - - ctx->ABCD[0] = 0x10325476; - ctx->ABCD[1] = 0x98badcfe; - ctx->ABCD[2] = 0xefcdab89; - ctx->ABCD[3] = 0x67452301; -} - -void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len){ - int i, j; - - j= ctx->len & 63; - ctx->len += len; - - for( i = 0; i < len; i++ ){ - ctx->block[j++] = src[i]; - if( 64 == j ){ - body(ctx->ABCD, (uint32_t*) ctx->block); - j = 0; - } - } -} - -void av_md5_final(AVMD5 *ctx, uint8_t *dst){ - int i; - uint64_t finalcount= le2me_64(ctx->len<<3); - - av_md5_update(ctx, "\200", 1); - while((ctx->len & 63)!=56) - av_md5_update(ctx, "", 1); - - av_md5_update(ctx, (uint8_t*)&finalcount, 8); - - for(i=0; i<4; i++) - ((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]); -} - -void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len){ - AVMD5 ctx[1]; - - av_md5_init(ctx); - av_md5_update(ctx, src, len); - av_md5_final(ctx, dst); -} - -#ifdef TEST -#include -#include -#undef printf -int main(void){ - uint64_t md5val; - int i; - uint8_t in[1000]; - - for(i=0; i<1000; i++) in[i]= i*i; - av_md5_sum( (uint8_t*)&md5val, in, 1000); printf("%"PRId64"\n", md5val); - av_md5_sum( (uint8_t*)&md5val, in, 63); printf("%"PRId64"\n", md5val); - av_md5_sum( (uint8_t*)&md5val, in, 64); printf("%"PRId64"\n", md5val); - av_md5_sum( (uint8_t*)&md5val, in, 65); printf("%"PRId64"\n", md5val); - for(i=0; i<1000; i++) in[i]= i % 127; - av_md5_sum( (uint8_t*)&md5val, in, 999); printf("%"PRId64"\n", md5val); - - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/md5.h b/tizen/distrib/ffmpeg/libavutil/md5.h deleted file mode 100644 index 969202a..0000000 --- a/tizen/distrib/ffmpeg/libavutil/md5.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_MD5_H -#define AVUTIL_MD5_H - -#include - -extern const int av_md5_size; - -struct AVMD5; - -void av_md5_init(struct AVMD5 *ctx); -void av_md5_update(struct AVMD5 *ctx, const uint8_t *src, const int len); -void av_md5_final(struct AVMD5 *ctx, uint8_t *dst); -void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len); - -#endif /* AVUTIL_MD5_H */ - diff --git a/tizen/distrib/ffmpeg/libavutil/mem.c b/tizen/distrib/ffmpeg/libavutil/mem.c deleted file mode 100644 index 8cad089..0000000 --- a/tizen/distrib/ffmpeg/libavutil/mem.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * default memory allocator for libavutil - * Copyright (c) 2002 Fabrice Bellard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * default memory allocator for libavutil - */ - -#include "config.h" - -#include -#include -#include -#if HAVE_MALLOC_H -#include -#endif - -#include "avutil.h" -#include "mem.h" - -/* here we can use OS-dependent allocation functions */ -#undef free -#undef malloc -#undef realloc - -#ifdef MALLOC_PREFIX - -#define malloc AV_JOIN(MALLOC_PREFIX, malloc) -#define memalign AV_JOIN(MALLOC_PREFIX, memalign) -#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign) -#define realloc AV_JOIN(MALLOC_PREFIX, realloc) -#define free AV_JOIN(MALLOC_PREFIX, free) - -void *malloc(size_t size); -void *memalign(size_t align, size_t size); -int posix_memalign(void **ptr, size_t align, size_t size); -void *realloc(void *ptr, size_t size); -void free(void *ptr); - -#endif /* MALLOC_PREFIX */ - -/* You can redefine av_malloc and av_free in your project to use your - memory allocator. You do not need to suppress this file because the - linker will do it automatically. */ - -void *av_malloc(unsigned int size) -{ - void *ptr = NULL; -#if CONFIG_MEMALIGN_HACK - long diff; -#endif - - /* let's disallow possible ambiguous cases */ - if(size > (INT_MAX-16) ) - return NULL; - -#if CONFIG_MEMALIGN_HACK - ptr = malloc(size+16); - if(!ptr) - return ptr; - diff= ((-(long)ptr - 1)&15) + 1; - ptr = (char*)ptr + diff; - ((char*)ptr)[-1]= diff; -#elif HAVE_POSIX_MEMALIGN - if (posix_memalign(&ptr,16,size)) - ptr = NULL; -#elif HAVE_MEMALIGN - ptr = memalign(16,size); - /* Why 64? - Indeed, we should align it: - on 4 for 386 - on 16 for 486 - on 32 for 586, PPro - K6-III - on 64 for K7 (maybe for P3 too). - Because L1 and L2 caches are aligned on those values. - But I don't want to code such logic here! - */ - /* Why 16? - Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs - it will just trigger an exception and the unaligned load will be done in the - exception handler or it will just segfault (SSE2 on P4). - Why not larger? Because I did not see a difference in benchmarks ... - */ - /* benchmarks with P3 - memalign(64)+1 3071,3051,3032 - memalign(64)+2 3051,3032,3041 - memalign(64)+4 2911,2896,2915 - memalign(64)+8 2545,2554,2550 - memalign(64)+16 2543,2572,2563 - memalign(64)+32 2546,2545,2571 - memalign(64)+64 2570,2533,2558 - - BTW, malloc seems to do 8-byte alignment by default here. - */ -#else - ptr = malloc(size); -#endif - return ptr; -} - -void *av_realloc(void *ptr, unsigned int size) -{ -#if CONFIG_MEMALIGN_HACK - int diff; -#endif - - /* let's disallow possible ambiguous cases */ - if(size > (INT_MAX-16) ) - return NULL; - -#if CONFIG_MEMALIGN_HACK - //FIXME this isn't aligned correctly, though it probably isn't needed - if(!ptr) return av_malloc(size); - diff= ((char*)ptr)[-1]; - return (char*)realloc((char*)ptr - diff, size + diff) + diff; -#else - return realloc(ptr, size); -#endif -} - -void av_free(void *ptr) -{ - /* XXX: this test should not be needed on most libcs */ - if (ptr) -#if CONFIG_MEMALIGN_HACK - free((char*)ptr - ((char*)ptr)[-1]); -#else - free(ptr); -#endif -} - -void av_freep(void *arg) -{ - void **ptr= (void**)arg; - av_free(*ptr); - *ptr = NULL; -} - -void *av_mallocz(unsigned int size) -{ - void *ptr = av_malloc(size); - if (ptr) - memset(ptr, 0, size); - return ptr; -} - -char *av_strdup(const char *s) -{ - char *ptr= NULL; - if(s){ - int len = strlen(s) + 1; - ptr = av_malloc(len); - if (ptr) - memcpy(ptr, s, len); - } - return ptr; -} - diff --git a/tizen/distrib/ffmpeg/libavutil/mem.h b/tizen/distrib/ffmpeg/libavutil/mem.h deleted file mode 100644 index 1488792..0000000 --- a/tizen/distrib/ffmpeg/libavutil/mem.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * memory handling functions - */ - -#ifndef AVUTIL_MEM_H -#define AVUTIL_MEM_H - -#include "attributes.h" - -#if defined(__ICC) || defined(__SUNPRO_C) - #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v - #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v -#elif defined(__TI_COMPILER_VERSION__) - #define DECLARE_ALIGNED(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - t __attribute__((aligned(n))) v - #define DECLARE_ASM_CONST(n,t,v) \ - AV_PRAGMA(DATA_ALIGN(v,n)) \ - static const t __attribute__((aligned(n))) v -#elif defined(__GNUC__) - #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v - #define DECLARE_ASM_CONST(n,t,v) static const t attribute_used __attribute__ ((aligned (n))) v -#elif defined(_MSC_VER) - #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v - #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v -#else - #define DECLARE_ALIGNED(n,t,v) t v - #define DECLARE_ASM_CONST(n,t,v) static const t v -#endif - -#if AV_GCC_VERSION_AT_LEAST(3,1) - #define av_malloc_attrib __attribute__((__malloc__)) -#else - #define av_malloc_attrib -#endif - -#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) - #define av_alloc_size(n) __attribute__((alloc_size(n))) -#else - #define av_alloc_size(n) -#endif - -/** - * Allocates a block of size bytes with alignment suitable for all - * memory accesses (including vectors if available on the CPU). - * @param size Size in bytes for the memory block to be allocated. - * @return Pointer to the allocated block, NULL if the block cannot - * be allocated. - * @see av_mallocz() - */ -void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1); - -/** - * Allocates or reallocates a block of memory. - * If ptr is NULL and size > 0, allocates a new block. If - * size is zero, frees the memory block pointed to by ptr. - * @param size Size in bytes for the memory block to be allocated or - * reallocated. - * @param ptr Pointer to a memory block already allocated with - * av_malloc(z)() or av_realloc() or NULL. - * @return Pointer to a newly reallocated block or NULL if the block - * cannot be reallocated or the function is used to free the memory block. - * @see av_fast_realloc() - */ -void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2); - -/** - * Frees a memory block which has been allocated with av_malloc(z)() or - * av_realloc(). - * @param ptr Pointer to the memory block which should be freed. - * @note ptr = NULL is explicitly allowed. - * @note It is recommended that you use av_freep() instead. - * @see av_freep() - */ -void av_free(void *ptr); - -/** - * Allocates a block of size bytes with alignment suitable for all - * memory accesses (including vectors if available on the CPU) and - * zeroes all the bytes of the block. - * @param size Size in bytes for the memory block to be allocated. - * @return Pointer to the allocated block, NULL if it cannot be allocated. - * @see av_malloc() - */ -void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1); - -/** - * Duplicates the string s. - * @param s string to be duplicated - * @return Pointer to a newly allocated string containing a - * copy of s or NULL if the string cannot be allocated. - */ -char *av_strdup(const char *s) av_malloc_attrib; - -/** - * Frees a memory block which has been allocated with av_malloc(z)() or - * av_realloc() and set the pointer pointing to it to NULL. - * @param ptr Pointer to the pointer to the memory block which should - * be freed. - * @see av_free() - */ -void av_freep(void *ptr); - -#endif /* AVUTIL_MEM_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/mips/intreadwrite.h b/tizen/distrib/ffmpeg/libavutil/mips/intreadwrite.h deleted file mode 100644 index b7479d3..0000000 --- a/tizen/distrib/ffmpeg/libavutil/mips/intreadwrite.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2009 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_MIPS_INTREADWRITE_H -#define AVUTIL_MIPS_INTREADWRITE_H - -#include -#include "config.h" - -#define AV_RN32 AV_RN32 -static av_always_inline uint32_t AV_RN32(const void *p) -{ - uint32_t v; - __asm__ ("lwl %0, %1 \n\t" - "lwr %0, %2 \n\t" - : "=&r"(v) - : "m"(*(const uint32_t *)((const uint8_t *)p+3*!HAVE_BIGENDIAN)), - "m"(*(const uint32_t *)((const uint8_t *)p+3*HAVE_BIGENDIAN))); - return v; -} - -#define AV_WN32 AV_WN32 -static av_always_inline void AV_WN32(void *p, uint32_t v) -{ - __asm__ ("swl %2, %0 \n\t" - "swr %2, %1 \n\t" - : "=m"(*(uint32_t *)((uint8_t *)p+3*!HAVE_BIGENDIAN)), - "=m"(*(uint32_t *)((uint8_t *)p+3*HAVE_BIGENDIAN)) - : "r"(v)); -} - -#if ARCH_MIPS64 - -#define AV_RN64 AV_RN64 -static av_always_inline uint64_t AV_RN64(const void *p) -{ - uint64_t v; - __asm__ ("ldl %0, %1 \n\t" - "ldr %0, %2 \n\t" - : "=&r"(v) - : "m"(*(const uint64_t *)((const uint8_t *)p+7*!HAVE_BIGENDIAN)), - "m"(*(const uint64_t *)((const uint8_t *)p+7*HAVE_BIGENDIAN))); - return v; -} - -#define AV_WN64 AV_WN64 -static av_always_inline void AV_WN64(void *p, uint64_t v) -{ - __asm__ ("sdl %2, %0 \n\t" - "sdr %2, %1 \n\t" - : "=m"(*(uint64_t *)((uint8_t *)p+7*!HAVE_BIGENDIAN)), - "=m"(*(uint64_t *)((uint8_t *)p+7*HAVE_BIGENDIAN)) - : "r"(v)); -} - -#else - -#define AV_RN64 AV_RN64 -static av_always_inline uint64_t AV_RN64(const void *p) -{ - union { uint64_t v; uint32_t hl[2]; } v; - v.hl[0] = AV_RN32(p); - v.hl[1] = AV_RN32((const uint8_t *)p + 4); - return v.v; -} - -#define AV_WN64 AV_WN64 -static av_always_inline void AV_WN64(void *p, uint64_t v) -{ - union { uint64_t v; uint32_t hl[2]; } vv = { v }; - AV_WN32(p, vv.hl[0]); - AV_WN32((uint8_t *)p + 4, vv.hl[1]); -} - -#endif /* ARCH_MIPS64 */ - -#endif /* AVUTIL_MIPS_INTREADWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/pca.c b/tizen/distrib/ffmpeg/libavutil/pca.c deleted file mode 100644 index ce08e9c..0000000 --- a/tizen/distrib/ffmpeg/libavutil/pca.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * principal component analysis (PCA) - * Copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * principal component analysis (PCA) - */ - -#include "common.h" -#include "pca.h" - -typedef struct PCA{ - int count; - int n; - double *covariance; - double *mean; -}PCA; - -PCA *ff_pca_init(int n){ - PCA *pca; - if(n<=0) - return NULL; - - pca= av_mallocz(sizeof(PCA)); - pca->n= n; - pca->count=0; - pca->covariance= av_mallocz(sizeof(double)*n*n); - pca->mean= av_mallocz(sizeof(double)*n); - - return pca; -} - -void ff_pca_free(PCA *pca){ - av_freep(&pca->covariance); - av_freep(&pca->mean); - av_free(pca); -} - -void ff_pca_add(PCA *pca, double *v){ - int i, j; - const int n= pca->n; - - for(i=0; imean[i] += v[i]; - for(j=i; jcovariance[j + i*n] += v[i]*v[j]; - } - pca->count++; -} - -int ff_pca(PCA *pca, double *eigenvector, double *eigenvalue){ - int i, j, pass; - int k=0; - const int n= pca->n; - double z[n]; - - memset(eigenvector, 0, sizeof(double)*n*n); - - for(j=0; jmean[j] /= pca->count; - eigenvector[j + j*n] = 1.0; - for(i=0; i<=j; i++){ - pca->covariance[j + i*n] /= pca->count; - pca->covariance[j + i*n] -= pca->mean[i] * pca->mean[j]; - pca->covariance[i + j*n] = pca->covariance[j + i*n]; - } - eigenvalue[j]= pca->covariance[j + j*n]; - z[j]= 0; - } - - for(pass=0; pass < 50; pass++){ - double sum=0; - - for(i=0; icovariance[j + i*n]); - - if(sum == 0){ - for(i=0; i maxvalue){ - maxvalue= eigenvalue[j]; - k= j; - } - } - eigenvalue[k]= eigenvalue[i]; - eigenvalue[i]= maxvalue; - for(j=0; jcovariance[j + i*n]; - double t,c,s,tau,theta, h; - - if(pass < 3 && fabs(covar) < sum / (5*n*n)) //FIXME why pass < 3 - continue; - if(fabs(covar) == 0.0) //FIXME should not be needed - continue; - if(pass >=3 && fabs((eigenvalue[j]+z[j])/covar) > (1LL<<32) && fabs((eigenvalue[i]+z[i])/covar) > (1LL<<32)){ - pca->covariance[j + i*n]=0.0; - continue; - } - - h= (eigenvalue[j]+z[j]) - (eigenvalue[i]+z[i]); - theta=0.5*h/covar; - t=1.0/(fabs(theta)+sqrt(1.0+theta*theta)); - if(theta < 0.0) t = -t; - - c=1.0/sqrt(1+t*t); - s=t*c; - tau=s/(1.0+c); - z[i] -= t*covar; - z[j] += t*covar; - -#define ROTATE(a,i,j,k,l) {\ - double g=a[j + i*n];\ - double h=a[l + k*n];\ - a[j + i*n]=g-s*(h+g*tau);\ - a[l + k*n]=h+s*(g-h*tau); } - for(k=0; kcovariance,FFMIN(k,i),FFMAX(k,i),FFMIN(k,j),FFMAX(k,j)) - } - ROTATE(eigenvector,k,i,k,j) - } - pca->covariance[j + i*n]=0.0; - } - } - for (i=0; i -#include -#include "lfg.h" - -int main(void){ - PCA *pca; - int i, j, k; -#define LEN 8 - double eigenvector[LEN*LEN]; - double eigenvalue[LEN]; - AVLFG prng; - - av_lfg_init(&prng, 1); - - pca= ff_pca_init(LEN); - - for(i=0; i<9000000; i++){ - double v[2*LEN+100]; - double sum=0; - int pos = av_lfg_get(&prng) % LEN; - int v2 = av_lfg_get(&prng) % 101 - 50; - v[0] = av_lfg_get(&prng) % 101 - 50; - for(j=1; j<8; j++){ - if(j<=pos) v[j]= v[0]; - else v[j]= v2; - sum += v[j]; - } -/* for(j=0; jcount= 1; - pca->mean[i]= 0; - -// (0.5^|x|)^2 = 0.5^2|x| = 0.25^|x| - - -// pca.covariance[i + i*LEN]= pow(0.5, fabs - for(j=i; jcovariance[i + j*LEN]); - } - printf("\n"); - } - -#if 1 - for(i=0; icovariance[FFMIN(k,j) + FFMAX(k,j)*LEN] * eigenvector[i + k*LEN]; - } - v[j] /= eigenvalue[i]; - error += fabs(v[j] - eigenvector[i + j*LEN]); - } - printf("%f ", error); - } - printf("\n"); -#endif - for(i=0; i - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * principal component analysis (PCA) - */ - -#ifndef AVUTIL_PCA_H -#define AVUTIL_PCA_H - -struct PCA *ff_pca_init(int n); -void ff_pca_free(struct PCA *pca); -void ff_pca_add(struct PCA *pca, double *v); -int ff_pca(struct PCA *pca, double *eigenvector, double *eigenvalue); - -#endif /* AVUTIL_PCA_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/pixdesc.c b/tizen/distrib/ffmpeg/libavutil/pixdesc.c deleted file mode 100644 index 82b3631..0000000 --- a/tizen/distrib/ffmpeg/libavutil/pixdesc.c +++ /dev/null @@ -1,840 +0,0 @@ -/* - * pixel format descriptor - * Copyright (c) 2009 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "pixfmt.h" -#include "pixdesc.h" - -#include "intreadwrite.h" - -void read_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4], - const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component) -{ - AVComponentDescriptor comp= desc->comp[c]; - int plane= comp.plane; - int depth= comp.depth_minus1+1; - int mask = (1<flags; - - if (flags & PIX_FMT_BITSTREAM){ - int skip = x*step + comp.offset_plus1-1; - const uint8_t *p = data[plane] + y*linesize[plane] + (skip>>3); - int shift = 8 - depth - (skip&7); - - while(w--){ - int val = (*p >> shift) & mask; - if(read_pal_component) - val= data[1][4*val + c]; - shift -= step; - p -= shift>>3; - shift &= 7; - *dst++= val; - } - } else { - const uint8_t *p = data[plane]+ y*linesize[plane] + x*step + comp.offset_plus1-1; - - while(w--){ - int val; - if(flags & PIX_FMT_BE) val= AV_RB16(p); - else val= AV_RL16(p); - val = (val>>shift) & mask; - if(read_pal_component) - val= data[1][4*val + c]; - p+= step; - *dst++= val; - } - } -} - -void write_line(const uint16_t *src, uint8_t *data[4], const int linesize[4], - const AVPixFmtDescriptor *desc, int x, int y, int c, int w) -{ - AVComponentDescriptor comp = desc->comp[c]; - int plane = comp.plane; - int depth = comp.depth_minus1+1; - int step = comp.step_minus1+1; - int flags = desc->flags; - - if (flags & PIX_FMT_BITSTREAM) { - int skip = x*step + comp.offset_plus1-1; - uint8_t *p = data[plane] + y*linesize[plane] + (skip>>3); - int shift = 8 - depth - (skip&7); - - while (w--) { - *p |= *src++ << shift; - shift -= step; - p -= shift>>3; - shift &= 7; - } - } else { - int shift = comp.shift; - uint8_t *p = data[plane]+ y*linesize[plane] + x*step + comp.offset_plus1-1; - - while (w--) { - if (flags & PIX_FMT_BE) { - uint16_t val = AV_RB16(p) | (*src++<log2_chroma_w + pixdesc->log2_chroma_h; - - for (c = 0; c < pixdesc->nb_components; c++) { - int s = c==1 || c==2 ? 0 : log2_pixels; - bits += (pixdesc->comp[c].depth_minus1+1) << s; - } - - return bits >> log2_pixels; -} diff --git a/tizen/distrib/ffmpeg/libavutil/pixdesc.h b/tizen/distrib/ffmpeg/libavutil/pixdesc.h deleted file mode 100644 index 8e4c85d..0000000 --- a/tizen/distrib/ffmpeg/libavutil/pixdesc.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * pixel format descriptor - * Copyright (c) 2009 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PIXDESC_H -#define AVUTIL_PIXDESC_H - -#include - -typedef struct AVComponentDescriptor{ - uint16_t plane :2; ///< which of the 4 planes contains the component - - /** - * Number of elements between 2 horizontally consecutive pixels minus 1. - * Elements are bits for bitstream formats, bytes otherwise. - */ - uint16_t step_minus1 :3; - - /** - * Number of elements before the component of the first pixel plus 1. - * Elements are bits for bitstream formats, bytes otherwise. - */ - uint16_t offset_plus1 :3; - uint16_t shift :3; ///< number of least significant bits that must be shifted away to get the value - uint16_t depth_minus1 :4; ///< number of bits in the component minus 1 -}AVComponentDescriptor; - -/** - * Descriptor that unambiguously describes how the bits of a pixel are - * stored in the up to 4 data planes of an image. It also stores the - * subsampling factors and number of components. - * - * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV - * and all the YUV variants) AVPixFmtDescriptor just stores how values - * are stored not what these values represent. - */ -typedef struct AVPixFmtDescriptor{ - const char *name; - uint8_t nb_components; ///< The number of components each pixel has, (1-4) - - /** - * Amount to shift the luma width right to find the chroma width. - * For YV12 this is 1 for example. - * chroma_width = -((-luma_width) >> log2_chroma_w) - * The note above is needed to ensure rounding up. - * This value only refers to the chroma components. - */ - uint8_t log2_chroma_w; ///< chroma_width = -((-luma_width )>>log2_chroma_w) - - /** - * Amount to shift the luma height right to find the chroma height. - * For YV12 this is 1 for example. - * chroma_height= -((-luma_height) >> log2_chroma_h) - * The note above is needed to ensure rounding up. - * This value only refers to the chroma components. - */ - uint8_t log2_chroma_h; - uint8_t flags; - - /** - * Parameters that describe how pixels are packed. If the format - * has chroma components, they must be stored in comp[1] and - * comp[2]. - */ - AVComponentDescriptor comp[4]; -}AVPixFmtDescriptor; - -#define PIX_FMT_BE 1 ///< Pixel format is big-endian. -#define PIX_FMT_PAL 2 ///< Pixel format has a palette in data[1], values are indexes in this palette. -#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end. -#define PIX_FMT_HWACCEL 8 ///< Pixel format is an HW accelerated format. - -/** - * The array of all the pixel format descriptors. - */ -extern const AVPixFmtDescriptor av_pix_fmt_descriptors[]; - -/** - * Reads a line from an image, and writes the values of the - * pixel format component c to dst. - * - * @param data the array containing the pointers to the planes of the image - * @param linesizes the array containing the linesizes of the image - * @param desc the pixel format descriptor for the image - * @param x the horizontal coordinate of the first pixel to read - * @param y the vertical coordinate of the first pixel to read - * @param w the width of the line to read, that is the number of - * values to write to dst - * @param read_pal_component if not zero and the format is a paletted - * format writes the values corresponding to the palette - * component c in data[1] to dst, rather than the palette indexes in - * data[0]. The behavior is undefined if the format is not paletted. - */ -void read_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4], - const AVPixFmtDescriptor *desc, int x, int y, int c, int w, int read_pal_component); - -/** - * Writes the values from src to the pixel format component c of an - * image line. - * - * @param src array containing the values to write - * @param data the array containing the pointers to the planes of the - * image to write into. It is supposed to be zeroed. - * @param linesizes the array containing the linesizes of the image - * @param desc the pixel format descriptor for the image - * @param x the horizontal coordinate of the first pixel to write - * @param y the vertical coordinate of the first pixel to write - * @param w the width of the line to write, that is the number of - * values to write to the image line - */ -void write_line(const uint16_t *src, uint8_t *data[4], const int linesize[4], - const AVPixFmtDescriptor *desc, int x, int y, int c, int w); - -/** - * Returns the pixel format corresponding to name. - * - * If there is no pixel format with name name, then looks for a - * pixel format with the name corresponding to the native endian - * format of name. - * For example in a little-endian system, first looks for "gray16", - * then for "gray16le". - * - * Finally if no pixel format has been found, returns PIX_FMT_NONE. - */ -enum PixelFormat av_get_pix_fmt(const char *name); - -/** - * Returns the number of bits per pixel used by the pixel format - * described by pixdesc. - * - * The returned number of bits refers to the number of bits actually - * used for storing the pixel information, that is padding bits are - * not counted. - */ -int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc); - -#endif /* AVUTIL_PIXDESC_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/pixfmt.h b/tizen/distrib/ffmpeg/libavutil/pixfmt.h deleted file mode 100644 index d976f34..0000000 --- a/tizen/distrib/ffmpeg/libavutil/pixfmt.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PIXFMT_H -#define AVUTIL_PIXFMT_H - -/** - * @file - * pixel format definitions - * - * @warning This file has to be considered an internal but installed - * header, so it should not be directly included in your projects. - */ - -#include "libavutil/avconfig.h" - -/** - * Pixel format. Notes: - * - * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA - * color is put together as: - * (A << 24) | (R << 16) | (G << 8) | B - * This is stored as BGRA on little-endian CPU architectures and ARGB on - * big-endian CPUs. - * - * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized - * image data is stored in AVFrame.data[0]. The palette is transported in - * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is - * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is - * also endian-specific). Note also that the individual RGB palette - * components stored in AVFrame.data[1] should be in the range 0..255. - * This is important as many custom PAL8 video codecs that were designed - * to run on the IBM VGA graphics adapter use 6-bit palette components. - * - * For all the 8bit per pixel formats, an RGB32 palette is in data[1] like - * for pal8. This palette is filled in automatically by the function - * allocating the picture. - * - * Note, make sure that all newly added big endian formats have pix_fmt&1==1 - * and that all newly added little endian formats have pix_fmt&1==0 - * this allows simpler detection of big vs little endian. - */ -enum PixelFormat { - PIX_FMT_NONE= -1, - PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) - PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr - PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... - PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... - PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) - PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) - PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) - PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) - PIX_FMT_GRAY8, ///< Y , 8bpp - PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb - PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb - PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette - PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG) - PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG) - PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG) - PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing - PIX_FMT_XVMC_MPEG2_IDCT, - PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 - PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 - PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) - PIX_FMT_BGR4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) - PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) - PIX_FMT_RGB4, ///< packed RGB 1:2:1 bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits - PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) - PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) - PIX_FMT_NV21, ///< as above, but U and V bytes are swapped - - PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... - PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... - PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... - PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... - - PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian - PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian - PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) - PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG) - PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) - PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian - PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian - - PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian - PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian - PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 - PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 - - PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian - PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian - PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 - PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 - - PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers - PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers - PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - - PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian - PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian - PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian - PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian - PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian - PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian - PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers - PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer - - PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 - PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 - PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1 - PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1 - PIX_FMT_Y400A, ///< 8bit gray, 8bit alpha - PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions -}; - -#if AV_HAVE_BIGENDIAN -# define PIX_FMT_NE(be, le) PIX_FMT_##be -#else -# define PIX_FMT_NE(be, le) PIX_FMT_##le -#endif - -#define PIX_FMT_RGB32 PIX_FMT_NE(ARGB, BGRA) -#define PIX_FMT_RGB32_1 PIX_FMT_NE(RGBA, ABGR) -#define PIX_FMT_BGR32 PIX_FMT_NE(ABGR, RGBA) -#define PIX_FMT_BGR32_1 PIX_FMT_NE(BGRA, ARGB) - -#define PIX_FMT_GRAY16 PIX_FMT_NE(GRAY16BE, GRAY16LE) -#define PIX_FMT_RGB48 PIX_FMT_NE(RGB48BE, RGB48LE) -#define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE) -#define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE) -#define PIX_FMT_RGB444 PIX_FMT_NE(RGB444BE, RGB444LE) -#define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE) -#define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE) -#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE) - -#define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE) -#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE) -#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE) - -#endif /* AVUTIL_PIXFMT_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/ppc/intreadwrite.h b/tizen/distrib/ffmpeg/libavutil/ppc/intreadwrite.h deleted file mode 100644 index 3667703..0000000 --- a/tizen/distrib/ffmpeg/libavutil/ppc/intreadwrite.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2008 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PPC_INTREADWRITE_H -#define AVUTIL_PPC_INTREADWRITE_H - -#include -#include "config.h" - -#if HAVE_XFORM_ASM - -#define AV_RL16 AV_RL16 -static av_always_inline uint16_t AV_RL16(const void *p) -{ - uint16_t v; - __asm__ ("lhbrx %0, %y1" : "=r"(v) : "Z"(*(const uint16_t*)p)); - return v; -} - -#define AV_WL16 AV_WL16 -static av_always_inline void AV_WL16(void *p, uint16_t v) -{ - __asm__ ("sthbrx %1, %y0" : "=Z"(*(uint16_t*)p) : "r"(v)); -} - -#define AV_RL32 AV_RL32 -static av_always_inline uint32_t AV_RL32(const void *p) -{ - uint32_t v; - __asm__ ("lwbrx %0, %y1" : "=r"(v) : "Z"(*(const uint32_t*)p)); - return v; -} - -#define AV_WL32 AV_WL32 -static av_always_inline void AV_WL32(void *p, uint32_t v) -{ - __asm__ ("stwbrx %1, %y0" : "=Z"(*(uint32_t*)p) : "r"(v)); -} - -#if HAVE_LDBRX - -#define AV_RL64 AV_RL64 -static av_always_inline uint64_t AV_RL64(const void *p) -{ - uint64_t v; - __asm__ ("ldbrx %0, %y1" : "=r"(v) : "Z"(*(const uint64_t*)p)); - return v; -} - -#define AV_WL64 AV_WL64 -static av_always_inline void AV_WL64(void *p, uint64_t v) -{ - __asm__ ("stdbrx %1, %y0" : "=Z"(*(uint64_t*)p) : "r"(v)); -} - -#else - -#define AV_RL64 AV_RL64 -static av_always_inline uint64_t AV_RL64(const void *p) -{ - union { uint64_t v; uint32_t hl[2]; } v; - __asm__ ("lwbrx %0, %y2 \n\t" - "lwbrx %1, %y3 \n\t" - : "=&r"(v.hl[1]), "=r"(v.hl[0]) - : "Z"(*(const uint32_t*)p), "Z"(*((const uint32_t*)p+1))); - return v.v; -} - -#define AV_WL64 AV_WL64 -static av_always_inline void AV_WL64(void *p, uint64_t v) -{ - union { uint64_t v; uint32_t hl[2]; } vv = { v }; - __asm__ ("stwbrx %2, %y0 \n\t" - "stwbrx %3, %y1 \n\t" - : "=Z"(*(uint32_t*)p), "=Z"(*((uint32_t*)p+1)) - : "r"(vv.hl[1]), "r"(vv.hl[0])); -} - -#endif /* HAVE_LDBRX */ - -#endif /* HAVE_XFORM_ASM */ - -/* - * GCC fails miserably on the packed struct version which is used by - * default, so we override it here. - */ - -#define AV_RB64(p) (*(const uint64_t *)(p)) -#define AV_WB64(p, v) (*(uint64_t *)(p) = (v)) - -#endif /* AVUTIL_PPC_INTREADWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/ppc/timer.h b/tizen/distrib/ffmpeg/libavutil/ppc/timer.h deleted file mode 100644 index 155fc01..0000000 --- a/tizen/distrib/ffmpeg/libavutil/ppc/timer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2005 Luca Barbato - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_PPC_TIMER_H -#define AVUTIL_PPC_TIMER_H - -#include - -#define AV_READ_TIME read_time - -static inline uint64_t read_time(void) -{ - uint32_t tbu, tbl, temp; - - /* from section 2.2.1 of the 32-bit PowerPC PEM */ - __asm__ volatile( - "1:\n" - "mftbu %2\n" - "mftb %0\n" - "mftbu %1\n" - "cmpw %2,%1\n" - "bne 1b\n" - : "=r"(tbl), "=r"(tbu), "=r"(temp) - : - : "cc"); - - return (((uint64_t)tbu)<<32) | (uint64_t)tbl; -} - -#endif /* AVUTIL_PPC_TIMER_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/random_seed.c b/tizen/distrib/ffmpeg/libavutil/random_seed.c deleted file mode 100644 index 236cadd..0000000 --- a/tizen/distrib/ffmpeg/libavutil/random_seed.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "timer.h" -#include "random_seed.h" - -uint32_t ff_random_get_seed(void) -{ - uint32_t seed; - int fd; - - if ((fd = open("/dev/random", O_RDONLY)) == -1) - fd = open("/dev/urandom", O_RDONLY); - if (fd != -1){ - int err = read(fd, &seed, 4); - close(fd); - if (err == 4) - return seed; - } -#ifdef AV_READ_TIME - seed = AV_READ_TIME(); -#endif - // XXX what to do ? - return seed; -} diff --git a/tizen/distrib/ffmpeg/libavutil/random_seed.h b/tizen/distrib/ffmpeg/libavutil/random_seed.h deleted file mode 100644 index a954381..0000000 --- a/tizen/distrib/ffmpeg/libavutil/random_seed.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2009 Baptiste Coudurier - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_RANDOM_SEED_H -#define AVUTIL_RANDOM_SEED_H - -#include - -/** - * Gets a seed to use in conjunction with random functions. - */ -uint32_t ff_random_get_seed(void); - -#endif /* AVUTIL_RANDOM_SEED_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/rational.c b/tizen/distrib/ffmpeg/libavutil/rational.c deleted file mode 100644 index 3e8b885..0000000 --- a/tizen/distrib/ffmpeg/libavutil/rational.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * rational numbers - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * rational numbers - * @author Michael Niedermayer - */ - -#include -//#include -#include - -#include "common.h" -#include "mathematics.h" -#include "rational.h" - -int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max){ - AVRational a0={0,1}, a1={1,0}; - int sign= (num<0) ^ (den<0); - int64_t gcd= av_gcd(FFABS(num), FFABS(den)); - - if(gcd){ - num = FFABS(num)/gcd; - den = FFABS(den)/gcd; - } - if(num<=max && den<=max){ - a1= (AVRational){num, den}; - den=0; - } - - while(den){ - uint64_t x = num / den; - int64_t next_den= num - den*x; - int64_t a2n= x*a1.num + a0.num; - int64_t a2d= x*a1.den + a0.den; - - if(a2n > max || a2d > max){ - if(a1.num) x= (max - a0.num) / a1.num; - if(a1.den) x= FFMIN(x, (max - a0.den) / a1.den); - - if (den*(2*x*a1.den + a0.den) > num*a1.den) - a1 = (AVRational){x*a1.num + a0.num, x*a1.den + a0.den}; - break; - } - - a0= a1; - a1= (AVRational){a2n, a2d}; - num= den; - den= next_den; - } - assert(av_gcd(a1.num, a1.den) <= 1U); - - *dst_num = sign ? -a1.num : a1.num; - *dst_den = a1.den; - - return den==0; -} - -AVRational av_mul_q(AVRational b, AVRational c){ - av_reduce(&b.num, &b.den, b.num * (int64_t)c.num, b.den * (int64_t)c.den, INT_MAX); - return b; -} - -AVRational av_div_q(AVRational b, AVRational c){ - return av_mul_q(b, (AVRational){c.den, c.num}); -} - -AVRational av_add_q(AVRational b, AVRational c){ - av_reduce(&b.num, &b.den, b.num * (int64_t)c.den + c.num * (int64_t)b.den, b.den * (int64_t)c.den, INT_MAX); - return b; -} - -AVRational av_sub_q(AVRational b, AVRational c){ - return av_add_q(b, (AVRational){-c.num, c.den}); -} - -AVRational av_d2q(double d, int max){ - AVRational a; -#define LOG2 0.69314718055994530941723212145817656807550013436025 - int exponent= FFMAX( (int)(log(fabs(d) + 1e-20)/LOG2), 0); - int64_t den= 1LL << (61 - exponent); - if (isnan(d)) - return (AVRational){0,0}; - av_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max); - - return a; -} - -int av_nearer_q(AVRational q, AVRational q1, AVRational q2) -{ - /* n/d is q, a/b is the median between q1 and q2 */ - int64_t a = q1.num * (int64_t)q2.den + q2.num * (int64_t)q1.den; - int64_t b = 2 * (int64_t)q1.den * q2.den; - - /* rnd_up(a*d/b) > n => a*d/b > n */ - int64_t x_up = av_rescale_rnd(a, q.den, b, AV_ROUND_UP); - - /* rnd_down(a*d/b) < n => a*d/b < n */ - int64_t x_down = av_rescale_rnd(a, q.den, b, AV_ROUND_DOWN); - - return ((x_up > q.num) - (x_down < q.num)) * av_cmp_q(q2, q1); -} - -int av_find_nearest_q_idx(AVRational q, const AVRational* q_list) -{ - int i, nearest_q_idx = 0; - for(i=0; q_list[i].den; i++) - if (av_nearer_q(q, q_list[i], q_list[nearest_q_idx]) > 0) - nearest_q_idx = i; - - return nearest_q_idx; -} diff --git a/tizen/distrib/ffmpeg/libavutil/rational.h b/tizen/distrib/ffmpeg/libavutil/rational.h deleted file mode 100644 index 4d91f7b..0000000 --- a/tizen/distrib/ffmpeg/libavutil/rational.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * rational numbers - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * rational numbers - * @author Michael Niedermayer - */ - -#ifndef AVUTIL_RATIONAL_H -#define AVUTIL_RATIONAL_H - -#include -#include "attributes.h" - -/** - * rational number numerator/denominator - */ -typedef struct AVRational{ - int num; ///< numerator - int den; ///< denominator -} AVRational; - -/** - * Compares two rationals. - * @param a first rational - * @param b second rational - * @return 0 if a==b, 1 if a>b and -1 if a>63)|1; - else return 0; -} - -/** - * Converts rational to double. - * @param a rational to convert - * @return (double) a - */ -static inline double av_q2d(AVRational a){ - return a.num / (double) a.den; -} - -/** - * Reduces a fraction. - * This is useful for framerate calculations. - * @param dst_num destination numerator - * @param dst_den destination denominator - * @param num source numerator - * @param den source denominator - * @param max the maximum allowed for dst_num & dst_den - * @return 1 if exact, 0 otherwise - */ -int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); - -/** - * Multiplies two rationals. - * @param b first rational - * @param c second rational - * @return b*c - */ -AVRational av_mul_q(AVRational b, AVRational c) av_const; - -/** - * Divides one rational by another. - * @param b first rational - * @param c second rational - * @return b/c - */ -AVRational av_div_q(AVRational b, AVRational c) av_const; - -/** - * Adds two rationals. - * @param b first rational - * @param c second rational - * @return b+c - */ -AVRational av_add_q(AVRational b, AVRational c) av_const; - -/** - * Subtracts one rational from another. - * @param b first rational - * @param c second rational - * @return b-c - */ -AVRational av_sub_q(AVRational b, AVRational c) av_const; - -/** - * Converts a double precision floating point number to a rational. - * @param d double to convert - * @param max the maximum allowed numerator and denominator - * @return (AVRational) d - */ -AVRational av_d2q(double d, int max) av_const; - -/** - * @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer - * than q1, 0 if they have the same distance. - */ -int av_nearer_q(AVRational q, AVRational q1, AVRational q2); - -/** - * Finds the nearest value in q_list to q. - * @param q_list an array of rationals terminated by {0, 0} - * @return the index of the nearest value found in the array - */ -int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); - -#endif /* AVUTIL_RATIONAL_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/rc4.c b/tizen/distrib/ffmpeg/libavutil/rc4.c deleted file mode 100644 index 4e52ba5..0000000 --- a/tizen/distrib/ffmpeg/libavutil/rc4.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * RC4 encryption/decryption/pseudo-random number generator - * Copyright (c) 2007 Reimar Doeffinger - * - * loosely based on LibTomCrypt by Tom St Denis - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avutil.h" -#include "common.h" -#include "rc4.h" - -typedef struct AVRC4 AVRC4; - -int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt) { - int i, j; - uint8_t y; - uint8_t *state = r->state; - int keylen = key_bits >> 3; - if (key_bits & 7) - return -1; - for (i = 0; i < 256; i++) - state[i] = i; - y = 0; - // j is i % keylen - for (j = 0, i = 0; i < 256; i++, j++) { - if (j == keylen) j = 0; - y += state[i] + key[j]; - FFSWAP(uint8_t, state[i], state[y]); - } - r->x = 1; - r->y = state[1]; - return 0; -} - -void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) { - uint8_t x = r->x, y = r->y; - uint8_t *state = r->state; - while (count-- > 0) { - uint8_t sum = state[x] + state[y]; - FFSWAP(uint8_t, state[x], state[y]); - *dst++ = src ? *src++ ^ state[sum] : state[sum]; - x++; - y += state[x]; - } - r->x = x; r->y = y; -} diff --git a/tizen/distrib/ffmpeg/libavutil/rc4.h b/tizen/distrib/ffmpeg/libavutil/rc4.h deleted file mode 100644 index 07223a5..0000000 --- a/tizen/distrib/ffmpeg/libavutil/rc4.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * RC4 encryption/decryption/pseudo-random number generator - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_RC4_H -#define AVUTIL_RC4_H - -#include - -struct AVRC4 { - uint8_t state[256]; - int x, y; -}; - -/** - * \brief Initializes an AVRC4 context. - * - * \param key_bits must be a multiple of 8 - * \param decrypt 0 for encryption, 1 for decryption, currently has no effect - */ -int av_rc4_init(struct AVRC4 *d, const uint8_t *key, int key_bits, int decrypt); - -/** - * \brief Encrypts / decrypts using the RC4 algorithm. - * - * \param count number of bytes - * \param dst destination array, can be equal to src - * \param src source array, can be equal to dst, may be NULL - * \param iv not (yet) used for RC4, should be NULL - * \param decrypt 0 for encryption, 1 for decryption, not (yet) used - */ -void av_rc4_crypt(struct AVRC4 *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); - -#endif /* AVUTIL_RC4_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/sh4/bswap.h b/tizen/distrib/ffmpeg/libavutil/sh4/bswap.h deleted file mode 100644 index 6d237c5..0000000 --- a/tizen/distrib/ffmpeg/libavutil/sh4/bswap.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * byte swapping routines - */ - -#ifndef AVUTIL_SH4_BSWAP_H -#define AVUTIL_SH4_BSWAP_H - -#include -#include "config.h" -#include "libavutil/attributes.h" - -#define bswap_16 bswap_16 -static av_always_inline av_const uint16_t bswap_16(uint16_t x) -{ - __asm__("swap.b %0,%0" : "+r"(x)); - return x; -} - -#define bswap_32 bswap_32 -static av_always_inline av_const uint32_t bswap_32(uint32_t x) -{ - __asm__("swap.b %0,%0\n" - "swap.w %0,%0\n" - "swap.b %0,%0\n" - : "+r"(x)); - return x; -} - -#endif /* AVUTIL_SH4_BSWAP_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/sha.c b/tizen/distrib/ffmpeg/libavutil/sha.c deleted file mode 100644 index 5a3b575..0000000 --- a/tizen/distrib/ffmpeg/libavutil/sha.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2007 Michael Niedermayer - * Copyright (C) 2009 Konstantin Shishkov - * based on public domain SHA-1 code by Steve Reid - * and on BSD-licensed SHA-2 code by Aaron D. Gifford - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "avutil.h" -#include "bswap.h" -#include "sha.h" -#include "sha1.h" -#include "intreadwrite.h" - -/** hash context */ -typedef struct AVSHA { - uint8_t digest_len; ///< digest length in 32-bit words - uint64_t count; ///< number of bytes in buffer - uint8_t buffer[64]; ///< 512-bit buffer of input values used in hash updating - uint32_t state[8]; ///< current hash value - /** function used to update hash for 512-bit input block */ - void (*transform)(uint32_t *state, const uint8_t buffer[64]); -} AVSHA; - -const int av_sha_size = sizeof(AVSHA); - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define blk0(i) (block[i] = be2me_32(((const uint32_t*)buffer)[i])) -#define blk(i) (block[i] = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1)) - -#define R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk0(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30); -#define R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk (i) + 0x5A827999 + rol(v, 5); w = rol(w, 30); -#define R2(v,w,x,y,z,i) z += ( w^x ^y) + blk (i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30); -#define R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + blk (i) + 0x8F1BBCDC + rol(v, 5); w = rol(w, 30); -#define R4(v,w,x,y,z,i) z += ( w^x ^y) + blk (i) + 0xCA62C1D6 + rol(v, 5); w = rol(w, 30); - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -static void sha1_transform(uint32_t state[5], const uint8_t buffer[64]) -{ - uint32_t block[80]; - unsigned int i, a, b, c, d, e; - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; -#if CONFIG_SMALL - for (i = 0; i < 80; i++) { - int t; - if (i < 16) - t = be2me_32(((uint32_t*)buffer)[i]); - else - t = rol(block[i-3] ^ block[i-8] ^ block[i-14] ^ block[i-16], 1); - block[i] = t; - t += e + rol(a, 5); - if (i < 40) { - if (i < 20) - t += ((b&(c^d))^d) + 0x5A827999; - else - t += ( b^c ^d) + 0x6ED9EBA1; - } else { - if (i < 60) - t += (((b|c)&d)|(b&c)) + 0x8F1BBCDC; - else - t += ( b^c ^d) + 0xCA62C1D6; - } - e = d; - d = c; - c = rol(b, 30); - b = a; - a = t; - } -#else - for (i = 0; i < 15; i += 5) { - R0(a, b, c, d, e, 0 + i); - R0(e, a, b, c, d, 1 + i); - R0(d, e, a, b, c, 2 + i); - R0(c, d, e, a, b, 3 + i); - R0(b, c, d, e, a, 4 + i); - } - R0(a, b, c, d, e, 15); - R1(e, a, b, c, d, 16); - R1(d, e, a, b, c, 17); - R1(c, d, e, a, b, 18); - R1(b, c, d, e, a, 19); - for (i = 20; i < 40; i += 5) { - R2(a, b, c, d, e, 0 + i); - R2(e, a, b, c, d, 1 + i); - R2(d, e, a, b, c, 2 + i); - R2(c, d, e, a, b, 3 + i); - R2(b, c, d, e, a, 4 + i); - } - for (; i < 60; i += 5) { - R3(a, b, c, d, e, 0 + i); - R3(e, a, b, c, d, 1 + i); - R3(d, e, a, b, c, 2 + i); - R3(c, d, e, a, b, 3 + i); - R3(b, c, d, e, a, 4 + i); - } - for (; i < 80; i += 5) { - R4(a, b, c, d, e, 0 + i); - R4(e, a, b, c, d, 1 + i); - R4(d, e, a, b, c, 2 + i); - R4(c, d, e, a, b, 3 + i); - R4(b, c, d, e, a, 4 + i); - } -#endif - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; -} - -static const uint32_t K256[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - - -#define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z)) -#define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y))) - -#define Sigma0_256(x) (rol((x), 30) ^ rol((x), 19) ^ rol((x), 10)) -#define Sigma1_256(x) (rol((x), 26) ^ rol((x), 21) ^ rol((x), 7)) -#define sigma0_256(x) (rol((x), 25) ^ rol((x), 14) ^ ((x) >> 3)) -#define sigma1_256(x) (rol((x), 15) ^ rol((x), 13) ^ ((x) >> 10)) - -#undef blk -#define blk(i) (block[i] = block[i - 16] + sigma0_256(block[i - 15]) + \ - sigma1_256(block[i - 2]) + block[i - 7]) - -#define ROUND256(a,b,c,d,e,f,g,h) \ - T1 += (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[i]; \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - i++ - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = blk0(i); \ - ROUND256(a,b,c,d,e,f,g,h) - -#define ROUND256_16_TO_63(a,b,c,d,e,f,g,h) \ - T1 = blk(i); \ - ROUND256(a,b,c,d,e,f,g,h) - -static void sha256_transform(uint32_t *state, const uint8_t buffer[64]) -{ - unsigned int i, a, b, c, d, e, f, g, h; - uint32_t block[64]; - uint32_t T1, av_unused(T2); - - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - f = state[5]; - g = state[6]; - h = state[7]; -#if CONFIG_SMALL - for (i = 0; i < 64; i++) { - if (i < 16) - T1 = blk0(i); - else - T1 = blk(i); - T1 += h + Sigma1_256(e) + Ch(e, f, g) + K256[i]; - T2 = Sigma0_256(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - } -#else - for (i = 0; i < 16;) { - ROUND256_0_TO_15(a, b, c, d, e, f, g, h); - ROUND256_0_TO_15(h, a, b, c, d, e, f, g); - ROUND256_0_TO_15(g, h, a, b, c, d, e, f); - ROUND256_0_TO_15(f, g, h, a, b, c, d, e); - ROUND256_0_TO_15(e, f, g, h, a, b, c, d); - ROUND256_0_TO_15(d, e, f, g, h, a, b, c); - ROUND256_0_TO_15(c, d, e, f, g, h, a, b); - ROUND256_0_TO_15(b, c, d, e, f, g, h, a); - } - - for (; i < 64;) { - ROUND256_16_TO_63(a, b, c, d, e, f, g, h); - ROUND256_16_TO_63(h, a, b, c, d, e, f, g); - ROUND256_16_TO_63(g, h, a, b, c, d, e, f); - ROUND256_16_TO_63(f, g, h, a, b, c, d, e); - ROUND256_16_TO_63(e, f, g, h, a, b, c, d); - ROUND256_16_TO_63(d, e, f, g, h, a, b, c); - ROUND256_16_TO_63(c, d, e, f, g, h, a, b); - ROUND256_16_TO_63(b, c, d, e, f, g, h, a); - } -#endif - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - state[5] += f; - state[6] += g; - state[7] += h; -} - - -int av_sha_init(AVSHA* ctx, int bits) -{ - ctx->digest_len = bits >> 5; - switch (bits) { - case 160: // SHA-1 - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - ctx->transform = sha1_transform; - break; - case 224: // SHA-224 - ctx->state[0] = 0xC1059ED8; - ctx->state[1] = 0x367CD507; - ctx->state[2] = 0x3070DD17; - ctx->state[3] = 0xF70E5939; - ctx->state[4] = 0xFFC00B31; - ctx->state[5] = 0x68581511; - ctx->state[6] = 0x64F98FA7; - ctx->state[7] = 0xBEFA4FA4; - ctx->transform = sha256_transform; - break; - case 256: // SHA-256 - ctx->state[0] = 0x6A09E667; - ctx->state[1] = 0xBB67AE85; - ctx->state[2] = 0x3C6EF372; - ctx->state[3] = 0xA54FF53A; - ctx->state[4] = 0x510E527F; - ctx->state[5] = 0x9B05688C; - ctx->state[6] = 0x1F83D9AB; - ctx->state[7] = 0x5BE0CD19; - ctx->transform = sha256_transform; - break; - default: - return -1; - } - ctx->count = 0; - return 0; -} - -void av_sha_update(AVSHA* ctx, const uint8_t* data, unsigned int len) -{ - unsigned int i, j; - - j = ctx->count & 63; - ctx->count += len; -#if CONFIG_SMALL - for (i = 0; i < len; i++) { - ctx->buffer[j++] = data[i]; - if (64 == j) { - ctx->transform(ctx->state, ctx->buffer); - j = 0; - } - } -#else - if ((j + len) > 63) { - memcpy(&ctx->buffer[j], data, (i = 64 - j)); - ctx->transform(ctx->state, ctx->buffer); - for (; i + 63 < len; i += 64) - ctx->transform(ctx->state, &data[i]); - j = 0; - } else - i = 0; - memcpy(&ctx->buffer[j], &data[i], len - i); -#endif -} - -void av_sha_final(AVSHA* ctx, uint8_t *digest) -{ - int i; - uint64_t finalcount = be2me_64(ctx->count << 3); - - av_sha_update(ctx, "\200", 1); - while ((ctx->count & 63) != 56) - av_sha_update(ctx, "", 1); - av_sha_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ - for (i = 0; i < ctx->digest_len; i++) - AV_WB32(digest + i*4, ctx->state[i]); -} - -#if LIBAVUTIL_VERSION_MAJOR < 51 -struct AVSHA1 { - AVSHA sha; -}; - -const int av_sha1_size = sizeof(struct AVSHA1); - -void av_sha1_init(struct AVSHA1* context) -{ - av_sha_init(&context->sha, 160); -} - -void av_sha1_update(struct AVSHA1* context, const uint8_t* data, unsigned int len) -{ - av_sha_update(&context->sha, data, len); -} - -void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]) -{ - av_sha_final(&context->sha, digest); -} -#endif - -#ifdef TEST -#include -#undef printf - -int main(void) -{ - int i, j, k; - AVSHA ctx; - unsigned char digest[32]; - const int lengths[3] = { 160, 224, 256 }; - - for (j = 0; j < 3; j++) { - printf("Testing SHA-%d\n", lengths[j]); - for (k = 0; k < 3; k++) { - av_sha_init(&ctx, lengths[j]); - if (k == 0) - av_sha_update(&ctx, "abc", 3); - else if (k == 1) - av_sha_update(&ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56); - else - for (i = 0; i < 1000*1000; i++) - av_sha_update(&ctx, "a", 1); - av_sha_final(&ctx, digest); - for (i = 0; i < lengths[j] >> 3; i++) - printf("%02X", digest[i]); - putchar('\n'); - } - switch (j) { - case 0: - //test vectors (from FIPS PUB 180-1) - printf("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n" - "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n" - "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n"); - break; - case 1: - //test vectors (from FIPS PUB 180-2 Appendix A) - printf("23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7\n" - "75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525\n" - "20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67\n"); - break; - case 2: - //test vectors (from FIPS PUB 180-2) - printf("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad\n" - "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1\n" - "cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0\n"); - break; - } - } - - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/sha.h b/tizen/distrib/ffmpeg/libavutil/sha.h deleted file mode 100644 index 5a20230..0000000 --- a/tizen/distrib/ffmpeg/libavutil/sha.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_SHA_H -#define AVUTIL_SHA_H - -#include - -extern const int av_sha_size; - -struct AVSHA; - -/** - * Initializes SHA-1 or SHA-2 hashing. - * - * @param context pointer to the function context (of size av_sha_size) - * @param bits number of bits in digest (SHA-1 - 160 bits, SHA-2 224 or 256 bits) - * @return zero if initialization succeeded, -1 otherwise - */ -int av_sha_init(struct AVSHA* context, int bits); - -/** - * Updates hash value. - * - * @param context hash function context - * @param data input data to update hash with - * @param len input data length - */ -void av_sha_update(struct AVSHA* context, const uint8_t* data, unsigned int len); - -/** - * Finishes hashing and output digest value. - * - * @param context hash function context - * @param digest buffer where output digest value is stored - */ -void av_sha_final(struct AVSHA* context, uint8_t *digest); - -#endif /* AVUTIL_SHA_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/sha1.h b/tizen/distrib/ffmpeg/libavutil/sha1.h deleted file mode 100644 index cf7c4a6..0000000 --- a/tizen/distrib/ffmpeg/libavutil/sha1.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2007 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_SHA1_H -#define AVUTIL_SHA1_H - -#include - -extern const int av_sha1_size; - -struct AVSHA1; - -/** - * Initializes SHA-1 hashing. - * - * @param context pointer to the function context (of size av_sha_size) - * @deprecated use av_sha_init() instead - */ -void av_sha1_init(struct AVSHA1* context); - -/** - * Updates hash value. - * - * @param context hash function context - * @param data input data to update hash with - * @param len input data length - * @deprecated use av_sha_update() instead - */ -void av_sha1_update(struct AVSHA1* context, const uint8_t* data, unsigned int len); - -/** - * Finishes hashing and output digest value. - * - * @param context hash function context - * @param digest buffer where output digest value is stored - * @deprecated use av_sha_final() instead - */ -void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]); - -#endif /* AVUTIL_SHA1_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/softfloat.c b/tizen/distrib/ffmpeg/libavutil/softfloat.c deleted file mode 100644 index efa0420..0000000 --- a/tizen/distrib/ffmpeg/libavutil/softfloat.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include "softfloat.h" -#include "common.h" -#include "log.h" - -#undef printf - -int main(void){ - SoftFloat one= av_int2sf(1, 0); - SoftFloat sf1, sf2; - double d1, d2; - int i, j; - av_log_set_level(AV_LOG_DEBUG); - - d1= 1; - for(i= 0; i<10; i++){ - d1= 1/(d1+1); - } - printf("test1 double=%d\n", (int)(d1 * (1<<24))); - - sf1= one; - for(i= 0; i<10; i++){ - sf1= av_div_sf(one, av_normalize_sf(av_add_sf(one, sf1))); - } - printf("test1 sf =%d\n", av_sf2int(sf1, 24)); - - - for(i= 0; i<100; i++){ - START_TIMER - d1= i; - d2= i/100.0; - for(j= 0; j<1000; j++){ - d1= (d1+1)*d2; - } - STOP_TIMER("float add mul") - } - printf("test2 double=%d\n", (int)(d1 * (1<<24))); - - for(i= 0; i<100; i++){ - START_TIMER - sf1= av_int2sf(i, 0); - sf2= av_div_sf(av_int2sf(i, 2), av_int2sf(200, 3)); - for(j= 0; j<1000; j++){ - sf1= av_mul_sf(av_add_sf(sf1, one),sf2); - } - STOP_TIMER("softfloat add mul") - } - printf("test2 sf =%d (%d %d)\n", av_sf2int(sf1, 24), sf1.exp, sf1.mant); - return 0; -} diff --git a/tizen/distrib/ffmpeg/libavutil/softfloat.h b/tizen/distrib/ffmpeg/libavutil/softfloat.h deleted file mode 100644 index 97e09ea..0000000 --- a/tizen/distrib/ffmpeg/libavutil/softfloat.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_SOFTFLOAT_H -#define AVUTIL_SOFTFLOAT_H - -#include -#include "common.h" - -#define MIN_EXP -126 -#define MAX_EXP 126 -#define ONE_BITS 29 - -typedef struct SoftFloat{ - int32_t exp; - int32_t mant; -}SoftFloat; - -static av_const SoftFloat av_normalize_sf(SoftFloat a){ - if(a.mant){ -#if 1 - while((a.mant + 0x20000000U)<0x40000000U){ - a.mant += a.mant; - a.exp -= 1; - } -#else - int s=ONE_BITS + 1 - av_log2(a.mant ^ (a.mant<<1)); - a.exp -= s; - a.mant <<= s; -#endif - if(a.exp < MIN_EXP){ - a.exp = MIN_EXP; - a.mant= 0; - } - }else{ - a.exp= MIN_EXP; - } - return a; -} - -static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){ -#if 1 - if(a.mant + 0x40000000 < 0){ - a.exp++; - a.mant>>=1; - } - return a; -#elif 1 - int t= a.mant + 0x40000000 < 0; - return (SoftFloat){a.exp+t, a.mant>>t}; -#else - int t= (a.mant + 0x40000000U)>>31; - return (SoftFloat){a.exp+t, a.mant>>t}; -#endif -} - -/** - * @return Will not be more denormalized than a+b. So if either input is - * normalized, then the output will not be worse then the other input. - * If both are normalized, then the output will be normalized. - */ -static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){ - a.exp += b.exp; - a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS; - return av_normalize1_sf(a); -} - -/** - * b has to be normalized and not zero. - * @return Will not be more denormalized than a. - */ -static av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){ - a.exp -= b.exp+1; - a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant; - return av_normalize1_sf(a); -} - -static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){ - int t= a.exp - b.exp; - if(t<0) return (a.mant >> (-t)) - b.mant ; - else return a.mant - (b.mant >> t); -} - -static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){ - int t= a.exp - b.exp; - if(t<0) return av_normalize1_sf((SoftFloat){b.exp, b.mant + (a.mant >> (-t))}); - else return av_normalize1_sf((SoftFloat){a.exp, a.mant + (b.mant >> t )}); -} - -static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){ - return av_add_sf(a, (SoftFloat){b.exp, -b.mant}); -} - -//FIXME sqrt, log, exp, pow, sin, cos - -static inline av_const SoftFloat av_int2sf(int v, int frac_bits){ - return av_normalize_sf((SoftFloat){ONE_BITS-frac_bits, v}); -} - -/** - * Rounding is to -inf. - */ -static inline av_const int av_sf2int(SoftFloat v, int frac_bits){ - v.exp += frac_bits - ONE_BITS; - if(v.exp >= 0) return v.mant << v.exp ; - else return v.mant >>(-v.exp); -} - -#endif /* AVUTIL_SOFTFLOAT_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/timer.h b/tizen/distrib/ffmpeg/libavutil/timer.h deleted file mode 100644 index cd8fba8..0000000 --- a/tizen/distrib/ffmpeg/libavutil/timer.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file - * high precision timer, useful to profile code - * - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_TIMER_H -#define AVUTIL_TIMER_H - -#include -#include -#include "config.h" - -#if ARCH_ARM -# include "arm/timer.h" -#elif ARCH_BFIN -# include "bfin/timer.h" -#elif ARCH_PPC -# include "ppc/timer.h" -#elif ARCH_X86 -# include "x86/timer.h" -#endif - -#if !defined(AV_READ_TIME) && HAVE_GETHRTIME -# define AV_READ_TIME gethrtime -#endif - -#ifdef AV_READ_TIME -#define START_TIMER \ -uint64_t tend;\ -uint64_t tstart= AV_READ_TIME();\ - -#define STOP_TIMER(id) \ -tend= AV_READ_TIME();\ -{\ - static uint64_t tsum=0;\ - static int tcount=0;\ - static int tskip_count=0;\ - if(tcount<2 || tend - tstart < 8*tsum/tcount || tend - tstart < 2000){\ - tsum+= tend - tstart;\ - tcount++;\ - }else\ - tskip_count++;\ - if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\ - av_log(NULL, AV_LOG_ERROR, "%"PRIu64" dezicycles in %s, %d runs, %d skips\n",\ - tsum*10/tcount, id, tcount, tskip_count);\ - }\ -} -#else -#define START_TIMER -#define STOP_TIMER(id) {} -#endif - -#endif /* AVUTIL_TIMER_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/tomi/intreadwrite.h b/tizen/distrib/ffmpeg/libavutil/tomi/intreadwrite.h deleted file mode 100644 index 778b804..0000000 --- a/tizen/distrib/ffmpeg/libavutil/tomi/intreadwrite.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_TOMI_INTREADWRITE_H -#define AVUTIL_TOMI_INTREADWRITE_H - -#include -#include "config.h" - -#define AV_RB16 AV_RB16 -static av_always_inline uint16_t AV_RB16(const void *p) -{ - uint16_t v; - __asm__ ("loadacc, (%1+) \n\t" - "rol8 \n\t" - "storeacc, %0 \n\t" - "loadacc, (%1+) \n\t" - "add, %0 \n\t" - : "=r"(v), "+a"(p)); - return v; -} - -#define AV_WB16 AV_WB16 -static av_always_inline void AV_WB16(void *p, uint16_t v) -{ - __asm__ volatile ("loadacc, %1 \n\t" - "lsr8 \n\t" - "storeacc, (%0+) \n\t" - "loadacc, %1 \n\t" - "storeacc, (%0+) \n\t" - : "+&a"(p) : "r"(v)); -} - -#define AV_RL16 AV_RL16 -static av_always_inline uint16_t AV_RL16(const void *p) -{ - uint16_t v; - __asm__ ("loadacc, (%1+) \n\t" - "storeacc, %0 \n\t" - "loadacc, (%1+) \n\t" - "rol8 \n\t" - "add, %0 \n\t" - : "=r"(v), "+a"(p)); - return v; -} - -#define AV_WL16 AV_WL16 -static av_always_inline void AV_WL16(void *p, uint16_t v) -{ - __asm__ volatile ("loadacc, %1 \n\t" - "storeacc, (%0+) \n\t" - "lsr8 \n\t" - "storeacc, (%0+) \n\t" - : "+&a"(p) : "r"(v)); -} - -#define AV_RB32 AV_RB32 -static av_always_inline uint32_t AV_RB32(const void *p) -{ - uint32_t v; - __asm__ ("loadacc, (%1+) \n\t" - "rol8 \n\t" - "rol8 \n\t" - "rol8 \n\t" - "storeacc, %0 \n\t" - "loadacc, (%1+) \n\t" - "rol8 \n\t" - "rol8 \n\t" - "add, %0 \n\t" - "loadacc, (%1+) \n\t" - "rol8 \n\t" - "add, %0 \n\t" - "loadacc, (%1+) \n\t" - "add, %0 \n\t" - : "=r"(v), "+a"(p)); - return v; -} - -#define AV_WB32 AV_WB32 -static av_always_inline void AV_WB32(void *p, uint32_t v) -{ - __asm__ volatile ("loadacc, #4 \n\t" - "add, %0 \n\t" - "loadacc, %1 \n\t" - "storeacc, (-%0) \n\t" - "lsr8 \n\t" - "storeacc, (-%0) \n\t" - "lsr8 \n\t" - "storeacc, (-%0) \n\t" - "lsr8 \n\t" - "storeacc, (-%0) \n\t" - : "+&a"(p) : "r"(v)); -} - -#define AV_RL32 AV_RL32 -static av_always_inline uint32_t AV_RL32(const void *p) -{ - uint32_t v; - __asm__ ("loadacc, (%1+) \n\t" - "storeacc, %0 \n\t" - "loadacc, (%1+) \n\t" - "rol8 \n\t" - "add, %0 \n\t" - "loadacc, (%1+) \n\t" - "rol8 \n\t" - "rol8 \n\t" - "add, %0 \n\t" - "loadacc, (%1+) \n\t" - "rol8 \n\t" - "rol8 \n\t" - "rol8 \n\t" - "add, %0 \n\t" - : "=r"(v), "+a"(p)); - return v; -} - -#define AV_WL32 AV_WL32 -static av_always_inline void AV_WL32(void *p, uint32_t v) -{ - __asm__ volatile ("loadacc, %1 \n\t" - "storeacc, (%0+) \n\t" - "lsr8 \n\t" - "storeacc, (%0+) \n\t" - "lsr8 \n\t" - "storeacc, (%0+) \n\t" - "lsr8 \n\t" - "storeacc, (%0+) \n\t" - : "+&a"(p) : "r"(v)); -} - -#endif /* AVUTIL_TOMI_INTREADWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/tree.c b/tizen/distrib/ffmpeg/libavutil/tree.c deleted file mode 100644 index 8769c76..0000000 --- a/tizen/distrib/ffmpeg/libavutil/tree.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "log.h" -#include "tree.h" - -typedef struct AVTreeNode{ - struct AVTreeNode *child[2]; - void *elem; - int state; -}AVTreeNode; - -const int av_tree_node_size = sizeof(AVTreeNode); - -void *av_tree_find(const AVTreeNode *t, void *key, int (*cmp)(void *key, const void *b), void *next[2]){ - if(t){ - unsigned int v= cmp(key, t->elem); - if(v){ - if(next) next[v>>31]= t->elem; - return av_tree_find(t->child[(v>>31)^1], key, cmp, next); - }else{ - if(next){ - av_tree_find(t->child[0], key, cmp, next); - av_tree_find(t->child[1], key, cmp, next); - } - return t->elem; - } - } - return NULL; -} - -void *av_tree_insert(AVTreeNode **tp, void *key, int (*cmp)(void *key, const void *b), AVTreeNode **next){ - AVTreeNode *t= *tp; - if(t){ - unsigned int v= cmp(t->elem, key); - void *ret; - if(!v){ - if(*next) - return t->elem; - else if(t->child[0]||t->child[1]){ - int i= !t->child[0]; - void *next_elem[2]; - av_tree_find(t->child[i], key, cmp, next_elem); - key= t->elem= next_elem[i]; - v= -i; - }else{ - *next= t; - *tp=NULL; - return NULL; - } - } - ret= av_tree_insert(&t->child[v>>31], key, cmp, next); - if(!ret){ - int i= (v>>31) ^ !!*next; - AVTreeNode **child= &t->child[i]; - t->state += 2*i - 1; - - if(!(t->state&1)){ - if(t->state){ - /* The following code is equivalent to - if((*child)->state*2 == -t->state) - rotate(child, i^1); - rotate(tp, i); - - with rotate(): - static void rotate(AVTreeNode **tp, int i){ - AVTreeNode *t= *tp; - - *tp= t->child[i]; - t->child[i]= t->child[i]->child[i^1]; - (*tp)->child[i^1]= t; - i= 4*t->state + 2*(*tp)->state + 12; - t ->state= ((0x614586 >> i) & 3)-1; - (*tp)->state= ((*tp)->state>>1) + ((0x400EEA >> i) & 3)-1; - } - but such a rotate function is both bigger and slower - */ - if((*child)->state*2 == -t->state){ - *tp= (*child)->child[i^1]; - (*child)->child[i^1]= (*tp)->child[i]; - (*tp)->child[i]= *child; - *child= (*tp)->child[i^1]; - (*tp)->child[i^1]= t; - - (*tp)->child[0]->state= -((*tp)->state>0); - (*tp)->child[1]->state= (*tp)->state<0 ; - (*tp)->state=0; - }else{ - *tp= *child; - *child= (*child)->child[i^1]; - (*tp)->child[i^1]= t; - if((*tp)->state) t->state = 0; - else t->state>>= 1; - (*tp)->state= -t->state; - } - } - } - if(!(*tp)->state ^ !!*next) - return key; - } - return ret; - }else{ - *tp= *next; *next= NULL; - if(*tp){ - (*tp)->elem= key; - return NULL; - }else - return key; - } -} - -void av_tree_destroy(AVTreeNode *t){ - if(t){ - av_tree_destroy(t->child[0]); - av_tree_destroy(t->child[1]); - av_free(t); - } -} - -void av_tree_enumerate(AVTreeNode *t, void *opaque, int (*cmp)(void *opaque, void *elem), int (*enu)(void *opaque, void *elem)){ - if(t){ - int v= cmp ? cmp(opaque, t->elem) : 0; - if(v>=0) av_tree_enumerate(t->child[0], opaque, cmp, enu); - if(v==0) enu(opaque, t->elem); - if(v<=0) av_tree_enumerate(t->child[1], opaque, cmp, enu); - } -} - -#ifdef TEST - -#include "lfg.h" - -static int check(AVTreeNode *t){ - if(t){ - int left= check(t->child[0]); - int right= check(t->child[1]); - - if(left>999 || right>999) - return 1000; - if(right - left != t->state) - return 1000; - if(t->state>1 || t->state<-1) - return 1000; - return FFMAX(left, right)+1; - } - return 0; -} - -static void print(AVTreeNode *t, int depth){ - int i; - for(i=0; istate, t->elem); - print(t->child[0], depth+1); - print(t->child[1], depth+1); - }else - av_log(NULL, AV_LOG_ERROR, "NULL\n"); -} - -static int cmp(void *a, const void *b){ - return (uint8_t*)a-(const uint8_t*)b; -} - -int main(void){ - int i; - void *k; - AVTreeNode *root= NULL, *node=NULL; - AVLFG prng; - - av_lfg_init(&prng, 1); - - for(i=0; i<10000; i++){ - int j = av_lfg_get(&prng) % 86294; - if(check(root) > 999){ - av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i); - print(root, 0); - return -1; - } - av_log(NULL, AV_LOG_ERROR, "inserting %4d\n", j); - if(!node) - node= av_mallocz(av_tree_node_size); - av_tree_insert(&root, (void*)(j+1), cmp, &node); - - j = av_lfg_get(&prng) % 86294; - { - AVTreeNode *node2=NULL; - av_log(NULL, AV_LOG_ERROR, "removing %4d\n", j); - av_tree_insert(&root, (void*)(j+1), cmp, &node2); - k= av_tree_find(root, (void*)(j+1), cmp, NULL); - if(k) - av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i); - } - } - return 0; -} -#endif diff --git a/tizen/distrib/ffmpeg/libavutil/tree.h b/tizen/distrib/ffmpeg/libavutil/tree.h deleted file mode 100644 index dde2f10..0000000 --- a/tizen/distrib/ffmpeg/libavutil/tree.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * A tree container. - * Insertion, removal, finding equal, largest which is smaller than and - * smallest which is larger than, all have O(log n) worst case complexity. - * @author Michael Niedermayer - */ - -#ifndef AVUTIL_TREE_H -#define AVUTIL_TREE_H - -struct AVTreeNode; -extern const int av_tree_node_size; - -/** - * Finds an element. - * @param root a pointer to the root node of the tree - * @param next If next is not NULL, then next[0] will contain the previous - * element and next[1] the next element. If either does not exist, - * then the corresponding entry in next is unchanged. - * @return An element with cmp(key, elem)==0 or NULL if no such element exists in - * the tree. - */ -void *av_tree_find(const struct AVTreeNode *root, void *key, int (*cmp)(void *key, const void *b), void *next[2]); - -/** - * Inserts or removes an element. - * If *next is NULL, then the supplied element will be removed if it exists. - * If *next is not NULL, then the supplied element will be inserted, unless - * it already exists in the tree. - * @param rootp A pointer to a pointer to the root node of the tree; note that - * the root node can change during insertions, this is required - * to keep the tree balanced. - * @param next Used to allocate and free AVTreeNodes. For insertion the user - * must set it to an allocated and zeroed object of at least - * av_tree_node_size bytes size. av_tree_insert() will set it to - * NULL if it has been consumed. - * For deleting elements *next is set to NULL by the user and - * av_tree_node_size() will set it to the AVTreeNode which was - * used for the removed element. - * This allows the use of flat arrays, which have - * lower overhead compared to many malloced elements. - * You might want to define a function like: - * @code - * void *tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), AVTreeNode **next){ - * if(!*next) *next= av_mallocz(av_tree_node_size); - * return av_tree_insert(rootp, key, cmp, next); - * } - * void *tree_remove(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b, AVTreeNode **next)){ - * if(*next) av_freep(next); - * return av_tree_insert(rootp, key, cmp, next); - * } - * @endcode - * @return If no insertion happened, the found element; if an insertion or - * removal happened, then either key or NULL will be returned. - * Which one it is depends on the tree state and the implementation. You - * should make no assumptions that it's one or the other in the code. - */ -void *av_tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), struct AVTreeNode **next); -void av_tree_destroy(struct AVTreeNode *t); - -/** - * Applies enu(opaque, &elem) to all the elements in the tree in a given range. - * - * @param cmp a comparison function that returns < 0 for a element below the - * range, > 0 for a element above the range and == 0 for a - * element inside the range - * - * @note The cmp function should use the same ordering used to construct the - * tree. - */ -void av_tree_enumerate(struct AVTreeNode *t, void *opaque, int (*cmp)(void *opaque, void *elem), int (*enu)(void *opaque, void *elem)); - - -#endif /* AVUTIL_TREE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/utils.c b/tizen/distrib/ffmpeg/libavutil/utils.c deleted file mode 100644 index 8a1d32e..0000000 --- a/tizen/distrib/ffmpeg/libavutil/utils.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "avutil.h" - -/** - * @file - * various utility functions - */ - -unsigned avutil_version(void) -{ - return LIBAVUTIL_VERSION_INT; -} - -const char *avutil_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *avutil_license(void) -{ -#define LICENSE_PREFIX "libavutil license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} diff --git a/tizen/distrib/ffmpeg/libavutil/x86/bswap.h b/tizen/distrib/ffmpeg/libavutil/x86/bswap.h deleted file mode 100644 index 26dc4e2..0000000 --- a/tizen/distrib/ffmpeg/libavutil/x86/bswap.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * byte swapping routines - */ - -#ifndef AVUTIL_X86_BSWAP_H -#define AVUTIL_X86_BSWAP_H - -#include -#include "config.h" -#include "libavutil/attributes.h" - -#define bswap_16 bswap_16 -static av_always_inline av_const uint16_t bswap_16(uint16_t x) -{ - __asm__("rorw $8, %0" : "+r"(x)); - return x; -} - -#define bswap_32 bswap_32 -static av_always_inline av_const uint32_t bswap_32(uint32_t x) -{ -#if HAVE_BSWAP - __asm__("bswap %0" : "+r" (x)); -#else - __asm__("rorw $8, %w0 \n\t" - "rorl $16, %0 \n\t" - "rorw $8, %w0" - : "+r"(x)); -#endif - return x; -} - -#if ARCH_X86_64 -#define bswap_64 bswap_64 -static inline uint64_t av_const bswap_64(uint64_t x) -{ - __asm__("bswap %0": "=r" (x) : "0" (x)); - return x; -} -#endif - -#endif /* AVUTIL_X86_BSWAP_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/x86/intmath.h b/tizen/distrib/ffmpeg/libavutil/x86/intmath.h deleted file mode 100644 index f3acddc..0000000 --- a/tizen/distrib/ffmpeg/libavutil/x86/intmath.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_X86_INTMATH_H -#define AVUTIL_X86_INTMATH_H - -#define FASTDIV(a,b) \ - ({\ - int ret, dmy;\ - __asm__ volatile(\ - "mull %3"\ - :"=d"(ret), "=a"(dmy)\ - :"1"(a), "g"(ff_inverse[b])\ - );\ - ret;\ - }) - -#endif /* AVUTIL_X86_INTMATH_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/x86/intreadwrite.h b/tizen/distrib/ffmpeg/libavutil/x86/intreadwrite.h deleted file mode 100644 index 4061d19..0000000 --- a/tizen/distrib/ffmpeg/libavutil/x86/intreadwrite.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2010 Alexander Strange - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_X86_INTREADWRITE_H -#define AVUTIL_X86_INTREADWRITE_H - -#include -#include "config.h" -#include "libavutil/attributes.h" - -#if HAVE_MMX - -#if !HAVE_FAST_64BIT && defined(__MMX__) - -#define AV_COPY64 AV_COPY64 -static av_always_inline void AV_COPY64(void *d, const void *s) -{ - __asm__("movq %1, %%mm0 \n\t" - "movq %%mm0, %0 \n\t" - : "=m"(*(uint64_t*)d) - : "m" (*(const uint64_t*)s) - : "mm0"); -} - -#define AV_SWAP64 AV_SWAP64 -static av_always_inline void AV_SWAP64(void *a, void *b) -{ - __asm__("movq %1, %%mm0 \n\t" - "movq %0, %%mm1 \n\t" - "movq %%mm0, %0 \n\t" - "movq %%mm1, %1 \n\t" - : "+m"(*(uint64_t*)a), "+m"(*(uint64_t*)b) - ::"mm0", "mm1"); -} - -#define AV_ZERO64 AV_ZERO64 -static av_always_inline void AV_ZERO64(void *d) -{ - __asm__("pxor %%mm0, %%mm0 \n\t" - "movq %%mm0, %0 \n\t" - : "=m"(*(uint64_t*)d) - :: "mm0"); -} - -#endif /* !HAVE_FAST_64BIT && defined(__MMX__) */ - -#ifdef __SSE__ - -#define AV_COPY128 AV_COPY128 -static av_always_inline void AV_COPY128(void *d, const void *s) -{ - struct v {uint64_t v[2];}; - - __asm__("movaps %1, %%xmm0 \n\t" - "movaps %%xmm0, %0 \n\t" - : "=m"(*(struct v*)d) - : "m" (*(const struct v*)s) - : "xmm0"); -} - -#endif /* __SSE__ */ - -#ifdef __SSE2__ - -#define AV_ZERO128 AV_ZERO128 -static av_always_inline void AV_ZERO128(void *d) -{ - struct v {uint64_t v[2];}; - - __asm__("pxor %%xmm0, %%xmm0 \n\t" - "movdqa %%xmm0, %0 \n\t" - : "=m"(*(struct v*)d) - :: "xmm0"); -} - -#endif /* __SSE2__ */ - -#endif /* HAVE_MMX */ - -#endif /* AVUTIL_X86_INTREADWRITE_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/x86/timer.h b/tizen/distrib/ffmpeg/libavutil/x86/timer.h deleted file mode 100644 index 62a111f..0000000 --- a/tizen/distrib/ffmpeg/libavutil/x86/timer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_X86_TIMER_H -#define AVUTIL_X86_TIMER_H - -#include - -#define AV_READ_TIME read_time - -static inline uint64_t read_time(void) -{ - uint32_t a, d; - __asm__ volatile("rdtsc" : "=a" (a), "=d" (d)); - return ((uint64_t)d << 32) + a; -} - -#endif /* AVUTIL_X86_TIMER_H */ diff --git a/tizen/distrib/ffmpeg/libavutil/x86_cpu.h b/tizen/distrib/ffmpeg/libavutil/x86_cpu.h deleted file mode 100644 index 08d3146..0000000 --- a/tizen/distrib/ffmpeg/libavutil/x86_cpu.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * copyright (c) 2006 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_X86_CPU_H -#define AVUTIL_X86_CPU_H - -#include -#include "config.h" - -#if 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" -typedef int64_t x86_reg; - -# define REG_SP "rsp" -# define REG_BP "rbp" -# define REGBP rbp -# define REGa rax -# define REGb rbx -# define REGc rcx -# define REGd rdx -# define REGSP rsp - -#elif ARCH_X86_32 - -# 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" -typedef int32_t x86_reg; - -# define REG_SP "esp" -# define REG_BP "ebp" -# define REGBP ebp -# define REGa eax -# define REGb ebx -# define REGc ecx -# define REGd edx -# define REGSP esp -#else -typedef int x86_reg; -#endif - -#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE)) -#define HAVE_6REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE || HAVE_EBP_AVAILABLE)) - -#if ARCH_X86_64 && defined(PIC) -# define BROKEN_RELOCATIONS 1 -#endif - -#endif /* AVUTIL_X86_CPU_H */ diff --git a/tizen/distrib/ffmpeg/libpostproc/Makefile b/tizen/distrib/ffmpeg/libpostproc/Makefile deleted file mode 100644 index bd0b71e..0000000 --- a/tizen/distrib/ffmpeg/libpostproc/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = postproc -FFLIBS = avutil - -HEADERS = postprocess.h - -OBJS = postprocess.o - -include $(SUBDIR)../subdir.mak diff --git a/tizen/distrib/ffmpeg/libpostproc/libpostproc.v b/tizen/distrib/ffmpeg/libpostproc/libpostproc.v deleted file mode 100644 index e65d76f..0000000 --- a/tizen/distrib/ffmpeg/libpostproc/libpostproc.v +++ /dev/null @@ -1,4 +0,0 @@ -LIBPOSTPROC_$MAJOR { - global: postproc_*; pp_*; - local: *; -}; diff --git a/tizen/distrib/ffmpeg/libpostproc/postprocess.c b/tizen/distrib/ffmpeg/libpostproc/postprocess.c deleted file mode 100644 index 92c822b7..0000000 --- a/tizen/distrib/ffmpeg/libpostproc/postprocess.c +++ /dev/null @@ -1,1106 +0,0 @@ -/* - * Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at) - * - * AltiVec optimizations (C) 2004 Romain Dolbeau - * - * This file is part of FFmpeg. - * - * FFmpeg 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. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * 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 do not have a 3DNow! CPU -> it is untested, but no one said it does not work so it seems to work -# more or less selfinvented filters so the exactness is not too meaningful -E = Exact implementation -e = almost 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 Subversion log - -#include "config.h" -#include "libavutil/avutil.h" -#include -#include -#include -#include -//#undef HAVE_MMX2 -//#define HAVE_AMD3DNOW -//#undef HAVE_MMX -//#undef ARCH_X86 -//#define DEBUG_BRIGHTNESS -#include "postprocess.h" -#include "postprocess_internal.h" - -unsigned postproc_version(void) -{ - return LIBPOSTPROC_VERSION_INT; -} - -const char *postproc_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *postproc_license(void) -{ -#define LICENSE_PREFIX "libpostproc license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} - -#if HAVE_ALTIVEC_H -#include -#endif - -#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 ARCH_X86 -DECLARE_ASM_CONST(8, uint64_t, w05)= 0x0005000500050005LL; -DECLARE_ASM_CONST(8, uint64_t, w04)= 0x0004000400040004LL; -DECLARE_ASM_CONST(8, uint64_t, w20)= 0x0020002000200020LL; -DECLARE_ASM_CONST(8, uint64_t, b00)= 0x0000000000000000LL; -DECLARE_ASM_CONST(8, uint64_t, b01)= 0x0101010101010101LL; -DECLARE_ASM_CONST(8, uint64_t, b02)= 0x0202020202020202LL; -DECLARE_ASM_CONST(8, uint64_t, b08)= 0x0808080808080808LL; -DECLARE_ASM_CONST(8, uint64_t, b80)= 0x8080808080808080LL; -#endif - -DECLARE_ASM_CONST(8, int, 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 const char *replaceTable[]= -{ - "default", "hb:a,vb:a,dr:a", - "de", "hb:a,vb:a,dr:a", - "fast", "h1:a,v1:a,dr:a", - "fa", "h1:a,v1:a,dr:a", - "ac", "ha:a:128:7,va:a,dr:a", - NULL //End Marker -}; - - -#if ARCH_X86 -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 because 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= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) ); - d= FFMAX(d, 0); - - d= (5*d + 32) >> 6; - d*= FFSIGN(-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= FFABS(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 were passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter - * can only smooth blocks at the expected locations (it cannot smooth them if they did move) - * MMX2 version does correct clipping C version does not - * 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 = av_malloc(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= FFABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0]; - const int last= FFABS(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(FFABS(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= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) ); - d= FFMAX(d, 0); - - d= (5*d + 32) >> 6; - d*= FFSIGN(-middleEnergy); - - if(q>0){ - d= d<0 ? 0 : d; - d= d>q ? q : d; - }else{ - d= d>0 ? 0 : d; - d= dppMode= *ppMode; //FIXME - - // Using ifs here as they are faster than function pointers although the - // difference would not be measurable here but it is much better because - // someone might exchange the CPU whithout restarting MPlayer ;) -#if CONFIG_RUNTIME_CPUDETECT -#if ARCH_X86 - // ordered per speed fastest 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 -#if HAVE_ALTIVEC - if(c->cpuCaps & PP_CPU_CAPS_ALTIVEC) - postProcess_altivec(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); - else -#endif - postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); -#endif -#else //CONFIG_RUNTIME_CPUDETECT -#if HAVE_MMX2 - postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); -#elif HAVE_AMD3DNOW - postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); -#elif HAVE_MMX - postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); -#elif 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 //!CONFIG_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 -*/ -#if LIBPOSTPROC_VERSION_INT < (52<<16) -const char *const pp_help= -#else -const char pp_help[] = -#endif -"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" -"[:@Bjp?J5fpW;EGaxc+bVn2YBsoTRZ<1zM5H*> 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 diff --git a/tizen/skins/emul_320x480/default_w.png b/tizen/skins/emul_320x480/default_w.png deleted file mode 100644 index 691bcef72900c8d227c207c72b8941fc273b44a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28181 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�y-j;F4)3Mq5KXvD&C7orZ! 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 R1FxKcDa)(NmC2X|{tre`!_WW# diff --git a/tizen/skins/emul_320x480/default_w90_p.png b/tizen/skins/emul_320x480/default_w90_p.png deleted file mode 100644 index b1b4d65f05a113e1c56c943ee268f35303a83339..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30381 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 diff --git a/tizen/skins/emul_320x480/default_w_p.png b/tizen/skins/emul_320x480/default_w_p.png deleted file mode 100644 index 021e7bd09b28c4831d67cac90effc9301a26e05a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30057 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 - - - - - - - - - - - - default.png - default_p.png - default.png - default_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w90.png - default_w90_p.png - default_w90.png - default_w90_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_180.png - default_180_p.png - default_180.png - default_180_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w.png - default_w_p.png - default_w.png - default_w_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - -

- - - - - - - - - - - - - - diff --git a/tizen/skins/emul_3keys_320x480/default.png b/tizen/skins/emul_3keys_320x480/default.png deleted file mode 100644 index d97869a9c53ca54eea4b1f4a3754ee748845c944..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32138 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 z 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

}2!n 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 diff --git a/tizen/skins/emul_3keys_320x480/default_w.png b/tizen/skins/emul_3keys_320x480/default_w.png deleted file mode 100644 index c548e13a9e1983f58c6709e7b63bf8ca3e53fe14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28735 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 diff --git a/tizen/skins/emul_3keys_320x480/default_w90.png b/tizen/skins/emul_3keys_320x480/default_w90.png deleted file mode 100644 index 803dae2e691703eb3c67772d577c5de534933806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29494 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 RmO#LxEUzwCDr4sV{{iltqmTdq diff --git a/tizen/skins/emul_3keys_480x800/default.dbi b/tizen/skins/emul_3keys_480x800/default.dbi deleted file mode 100644 index a526f14..0000000 --- a/tizen/skins/emul_3keys_480x800/default.dbi +++ /dev/null @@ -1,592 +0,0 @@ - - - - - - - - - - - - - default.png - default_p.png - default.png - default_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w90.png - default_w90_p.png - default_w90.png - default_w90_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_180.png - default_180_p.png - default_180.png - default_180_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w.png - default_w_p.png - default_w.png - default_w_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - -

- - - - - - - - - - - - - - diff --git a/tizen/skins/emul_3keys_480x800/default.png b/tizen/skins/emul_3keys_480x800/default.png deleted file mode 100644 index 034fb0d36f9896d23aacfb595d37090bf7ff7828..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52823 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%0D0>n%!p5u;ov#@C~dnSTo~1lmj@3cz8oMvFJ7R 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 JF6*2UngFTt!+!t( diff --git a/tizen/skins/emul_3keys_480x800/default_180.png b/tizen/skins/emul_3keys_480x800/default_180.png deleted file mode 100644 index b70abd935372cd35d5fae85c0446f7c29407406b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52622 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 diff --git a/tizen/skins/emul_3keys_480x800/default_p.png b/tizen/skins/emul_3keys_480x800/default_p.png deleted file mode 100644 index 195fa2441a2b9b252ccafb45c180550962ce5bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56938 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

r99EY?a~?5b%>S6WC?BK(!- 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 ZFfGID3ZCwg)iChS&FeZEg=!Xo{}1BsF0%jt diff --git a/tizen/skins/emul_3keys_480x800/default_w90.png b/tizen/skins/emul_3keys_480x800/default_w90.png deleted file mode 100644 index 178e55b487e92eceb8161e3988a8980804c94453..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48670 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

Wh>H?6)Ij4_H6i)!heH#uiW{f?Gedv+vk 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 z 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�UQBM#!z%cBkw;=La7tBSz&xq zIf=kgR{Ilg>8kW<2+vSaM24ajc+|HmzQ~vl{5BWc$KG&9;Iw7p*f!bBqI6oZ;Xp~U?C?M3Ul{wv z8$d*q%y2Pu9%Vl9j$mtVK*#E?eB46F#6Q#3pcR|V=3b?;?0CX~+eh9930Bh-s=<0d zyUi;5geAhBAjPz7fs19Pv9Zx%vTx|P%v$8!*xaiMdctG(~Bb? z%L^SeWxX#V&S={kOCvh*M z*3>b+nQYp|?31v*zxLPI$-{#Q*1T&kie8t^DyB20T(mbxche`Ix49y?H}I!z^VNd; z5pr{OJq2@j#HvTY*c(r>VD9Zqa)-kj?i!Hpr5mXB}eZr)O?+6qbsbJUnoKl_o$e0 z#zjQqNB;pF#L!qL*mM4JWK%U8qHVci3)y)OJ3dr7D;gsua86uU>=(|HvrYas0?R1i zH*=`GHvnM#kz-tGE{<3;k%zs?H<4r_tV$mi0$}FApC57gaIr_y7O^ diff --git a/tizen/skins/emul_3keys_600x1024/default.dbi b/tizen/skins/emul_3keys_600x1024/default.dbi deleted file mode 100644 index f9db8a0..0000000 --- a/tizen/skins/emul_3keys_600x1024/default.dbi +++ /dev/null @@ -1,592 +0,0 @@ - - - - - - - - - - - - - default.png - default_p.png - default.png - default_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w90.png - default_w90_p.png - default_w90.png - default_w90_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_180.png - default_180_p.png - default_180.png - default_180_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w.png - default_w_p.png - default_w.png - default_w_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - -

- - - - - - - - - - - - - - diff --git a/tizen/skins/emul_3keys_600x1024/default.png b/tizen/skins/emul_3keys_600x1024/default.png deleted file mode 100644 index 31a6fee2aa2dd6daf8a155ebd28e349010bac873..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68771 zcmZ5{Wn7eBwDkZADE(LI1}SNfmM)bPDQQV1rF%dSL|RH3ETjdLP9=wuZboDVq+y5w zhGE__-uHgFAN--roaZ@bpB-zhy^S-_)1tV}cpUZA# zOI2BEen<6n_pTs>l_RfndqJp4>l`?Iuv`R?({KfaJDi;)?GS>%2{KYhr*3YiD03{1 zYEw1ak{}|Qpwl;1<{@dsO^9-ElImxOvL-=9{yQEcNYNFD?V$bBRfvHQ#FiJjHUWvq zKg|vyfLNq++#)DSg|Odne60>~k%v@_n!M3~n2ADeIz8-`h0F>;MDLqAX+yp?KsraL z$!Z~_U9BNsq9*XCT>}cNDES-7bK>p z!mNBF_v!B3l(HkV%TX5o5tPj!9w|xn`)~*XDN4NsPJ4(A9HFcl8Iek=r?e5;>>$Q* zK7G1+i5xBWQiecQe8a~s1x4x@BjkxA+%MnX-o4^tO;+TGj(4i1QvMDp+L$*z^upUl zqd28$ZVrh+%s%K=wXlPkhFv=Uu<10#x}Ak9T%eDCxBuae6t{}hx^nva$Iy|^C+5+& z*P@>;t|e<-G?3vgSSC2T?>}ua6S%o*_}_~p^_+x5@lTv_s&DywZja*}{=fw>M2hgc zkgv}b2|`kZzF654ojl~FHuLTL1AGeA;@LIHM@kgo616fKfZJ2TY8BmvL^$1l`vL;7 zR_7Le469S>BZWZJiy{TSsxTdO(F=AGGk0BG>>|6cm5Ns7?*5@lt$N)dg4x@azv87T zU(E1V76Dt4No5wvPD7WNG%rfwAI6Q8_q?di?MMr{_*x^cT~X;LyNc(~$FF>RoNIM{gdp8*8(m?s*f+##(ANr^@$3#9v;-v}%c^ zN7fqNnDlQglrY*=d{a^A85$cfFYTeS@|HY|^ z^ERar-mm%ic>KR{&2f)MTpNO=xsuw9TxkRI4z9H%vgv~Ccluu;@)17~5(p*)2g>4l z{!`@_A5V?`@I8V(f53pGMoJ=y9p8zo7=OrlwDhI;G0olNC#sdj^^d9zW53*x^vjVQ zj-tK)@Kfdcj0r{;Iv4b_>c76tG)oz*dRf0r#|JmG{$~9pItn1Ch`ANj_u83{A(x(n z-kBkQzWSZcXNHM*hQ7z5(qdch*0ZUyJ&nx->IFh?rNXXfJjme5U=k2{Tw39xtsa^tdmgDoQ_Bj-~2FR^9LUpyZxeGE6p#u1zU)cL8e z_R+AY#%8s(mz~U>p)OF6!gE(qdUPi3bvvc-@Q1^^VPey&R3Fk82)DY<{tkaex}coI!$7Zmab))S(#?#+U17jT3c;WRXZj5 zpW8HA%rTLaDt!-lEqS$^lSi)RuN%!7EtOm^q1C-7cU&c0=K6`LxJ5mn!=q&PT|v8b zM1hWH$#PKJ`Z;r$2=+17{k-H@i`YM<;f z?6Ov(Q=7&VK1^vQYEmUU>$P0vUUlzv@BP3-%)`O+PMoSi*h2dEb;Xkz39g$=g*5>p9BY5OFper5>G?SgpS?$lv`e-zaxN z%bCu($tUXYb$r~zmxIDtio&@}y-WRVhzGvMFRWIA$B*-K>vDhWd|9a8mD+u_8@pII zBw5H`U@qbF>u0~(Z$spm5?Nt}s4Ki8TwhH;()s&3mx#Scs%hoS*M?64WoWxSI>i%3 z@4{8ZRR!r~@nv(HA?ePB{)R#QpPmIaui$D>E}R1{7&itfiMUPROcWQX5@|t*ISmfw z=txqMTW~z7o!e1KC~8utc4D}(UA)4xdU*6iYc zhLiKYihX4oqm<V@ibRj38N&?ekQ-3YjybUo+?%MWKxkuj;U*RyJt0<3x{Z2{fjx7(?$cZ0Zl zBt8iuo1%G3Q(AQ>be3}E3TSiu+1AdFTKUm@Ts`j$S zBfdd|HG^cpwJxRNs=3hhdezT=A3x!n5g@5`b~JVB7>;=j|2Z zcK-YE-^$ziPcaWog;>ni+A5yQ)+)RRTDZP?>*}2t6XFVm#y9l>?o;~ZJEmDx;cYy@ zx~`GdU9gv3-w9l|$c(QeUxjTg&g@v}n~9jizuTS1j~?~UQGX1THf8{FzPh!w6V4|<-c z%-;(TqL896PR#55!{wzOgxEk|gQHm~??cQtXtH#pUAc-XipQXF$>6*rFDi_*K;CW$JMb0W5nT;8gmEP5D<*qS66u)IKPbzsc@e$hbJm+ z)$Xl_4<6LmuReS#|Kd+~&{Fi3@M8C}kA#M)DaupdJ{7%uU#9)#IaB1MQgE@h@%aO8 zzRIFsl^; zCybiTzwtS-URCTn9df?68YDNd@t9hblp~s26*J{X`agdqOsDzxtN;5`{7X1_ej{eL z1&ZEZ`PrAuEbIN$(NW_Z+s>>IxZi(%ey&+PlcrblQ-=#YkJR{=uUy7KpkPZ&i~PdE zf~n?*RPtE0CT}FHr`)vK`uu#R<1)*LAzshLP-OWaDd1vYrvV<0*|J7AbCFQ7rdL)9 z&CSlH93T4)us1F2JgA<@#X?~J_Ij)wq`*4pAfAmydd=d;Ys&80F)d-R{2)aS_u z?7}2Q6%M!QI!=2U2w|+gqxaAk)ggOr=*R`n4(#l~Y9I3N*az>^eY?5E#q`8PiVZYI zLV2V}2D9PcqAZR-yaAC}few#&zMiwv>VcW~7Rp63hv4wL>kI;xamV}Mk4Dg1wzGBc zpE%z3i|^H8J8coQ8ezYQ*ko`q(yc3qjfoOuciau{zrQ%<=I7snqnKM+<(ntf4Q%~7{OhCNAQQxXPN%WE=rp#5_uou@!ghh_SA zjn63u&T#OZc4jip)!HGm?8w8Bkt8=y&%sX*vk zqP87(Pt5pFDy56xO9AkuCS;}sVz$N}e;#ma2-KuqN9O4VY#9^Vv-`Z`Sm~uX$ZB{I%SGZKi;Xb-;ZYkL)7Ih{G-xrs+j^)c>$jQCtQcwr9Nbrq zg(11GwxNMHs!RFgVi));OKJ}%2sf?5{@Z}Oj^vN~GP4?B(?Zbf+OLC-{R$aVPH zNWe1cvvk{ikG5kI*}(mximIxSPN^uw($Z2`iUMPz)7MPyg2(o*S`N_ z?_y*x?>=if^fyVk?a}Wjs+0DO-1hr=g^EHJ78c_>{?5`o0RaKdnX9ex8YjeQXI&0N z1#JTkoq4)H6l5?*#?#LS^m=}Hlov|%jrz`sjrdI|3XxH5__(cYRWZS8D|U1TOV69W zf4}>huvlBA>2Jqji0+9{*xE@>&6CT8%OIDL7AJ>Y1_q3~r{`$JAoRQhDt9?oh&A_% z+s}(Y;axDJ17&&%Yok&;En4(naR29oHa3MzZxfvb9?HwTw2 zg&N9dey8DxPU!~`Db%p&9gly7Hx7#)#0SmbKpHQ)%bP~jnfOw!b3Z08dYs|#EAS}I=TagMePQ3ShVjfw7U}z znt!Ve?XDdX`Y^LK0E&oU+@gbcDhO|LhXme&KvhND*=X|RAP9~-V=qxu*k4qMm*Y0) z58FUSH`U9N;b3B7k|<0cdYPAvl=wB=VdtQfta$$A0#<$T=3?3to2kQd17Ao!XeGmn z)nXlde2l;uou*gG-_|wIF>RDf!1GqT=#L@|OLh*EF2qjiDxofO>+Z?sOQ`b8u#Ap7 zQS_{{za??7z0BYoUA zQ>e(Dq6@0aE~R(vTUL8-Lw1|AKyFuzPgGz{c64^u0v?DqPn9qVWlaIs4mG;m>A*Ii zw(CY=HTHc7P?){>P?vq&JFnV%%XXH^mfEu0ymi-uVNOFiHET%> zpHBj2YPoOIiCCvsL$O;ZE$ERJ%1G(hX!-Yu3?FWv3b%j6vKJV;2*qK&Hz)bcZJ@FW z){1u8P8uV5Er*wV9hjDmJGgTjoNLf#X$j)E8rsGz@2?ZwwoINB@9~tdf9>}h|CZ{} zOyfpj$%WbnQdjGwrf2GZHa+JRpTGF~g z;hADoqBqbLMe=E4V<^-JrONsU-b1k)7HznXAsYG)v;d2aB$ZE_*^eh zRQ*y9Oo&`%!!=&~rn)TBDVbp4UKhb2t;B-c3KBHAn*4Wi@YSLH;^m z*kjEyDzl+qA3Lc((1u=ap-MjtA3SrRXAmru56~+J{BtenXiTdFcL~Q~JiLl78gM6Y z)^>E;-i{JJC9Mr*o0B$f*V`{A%S5dTsxK;?YvHsn*Krqxb*C^;#(P&^__LEtZ;JTFOWc z+qOr2P&)r0o~`55K9DW%fiL3pH-coD{zej!An+(}#wuVy9zfX3e;c7BOlJd|scr?~ zEBEg+a8rn1#cH+n^*kT}*i^J$u;cf&nye(ucJZ484`?bImgVXmInZ4^jX})X-IXt@ z;fbvou^cwF3iQe7UARRqBGB?z+?&NfqR>;wvrTErO>Pi|*# z9S7q}ww*@HQk9##`#>s}76LJl=DnUD0Bc!3uHpjKbl-F`3e^y{(6EH*m2NluhcUbn zuiZR6cFEwG`YLT8*SA^gx1aWiz~E={P_6pYK zyb8P;o<^Z%NsT zS3jXLsrlH4WJLkI?T~B3xe`u8;p*1Ir1N`ds@)Ime| zZF{=>7Rv2a^PmGPaj?6mwd~L+K&R}aX2|`+gD^9|m86bip{KDZP);BBf@q|W-b>2e zF#=TypNVBdPrv2?e9jv9J8~JbjBcl!jKrgw(DNku-4y%2q=D(_OaKvg7JMbNM=sGQ zEttbOXKA9iH|PKeV#TKqq9)!uAw5UqhVx1%IUe8FYovtQn)A;Dc&}cue(%C?E z@!dK;=c2qOTi`b%!sw+i^b+0xzWP`Blumy~LC*nxeRhnuqgpKG0KV)xIyySN=vVV< zSjYgjRyw$$#4)ObYt57MdrpfY;)s4kf-$(l#}#e4X>$<|<*+#)&vK$g4jpsGH!N=W zI@sH*Q8LT0w$Oe3wkVW5fXpPd-RxUiTfj@D2J_y+b?Qd2U2GST z7qPf~Hbnh`M;gF+01n;PYaXPwOyKhQNTKsRsXUH;^z*8Mh)-oH3hf@2x!$9p7@e|} zb;x$n#g>k*8_Ixrj+}fLD$9HE7o6hXlLFcg^Qi)_B4a_AAAtH?;)ACtv$OB4#&4vW zpC*Mmdn~u|D_#6l5`-V=!X+_G(GeJ@=YLELdh}(uAtG<2TPq5y?A2RB`M>zcR_o?M z9HUcQv3MMCF`JB?b*+G{9t8HLEqR#Y`Ab-s6&~fF7k%{CSHL?LnfR2BeyO4J0kWXI z?&0TW+`C#s9{V$lI>ufUu{zpKX7M|S{!AVVSu0} z^sSm}H7`{uoFURshf26Zknn>V&Fg+;kFC0bz!@7`FdJ_`vW*R z09eS>lrbKR0n#lSeDq~8Xgwd4npR}|h{{=UENk!jnRlnccMe!o>nHiX!AyHG}E3t{; zb03E?%NbEOadYilH!r{5@#E8Xr$ZMV+5ITzW-5H5X+KW%3{?x?nF-&yYl2+yl4(&J z+e170`T5Zb?-H?{c4{~mg#xjIS;>FF~3Bcq$PI zrFI8={XbIG{@0o2IYCVl)fYS7(bT9?D0=U5slCOEQ~c0)WZb&CstN`!gZW ze+fXLfg)yZba!xCnhJJkf&@{sj;@G80V)&bNxQ-6Q{AsD>(kQDcrRZMX$n0y{g;Bn zJE-`$5Qgr8Nq$&MtHzjj-T|U>o;U1wp0YglJ9tMIBBQFER{Jn4`-RjVu^{SsZ42J5 zz}Xi;Izm4oLCWtou1>q1@xu?`C#J1XD{3aH!OeJlZawUjVky}T4q6|$+kX+y(hnA>}I{(zg9L4cYw z^wGKBE1PBL)veU@srZFLIqqEMs8I9I(|w@~JTNO?mD*=b8Ya$yK)%v#4n3>A*xkF_ zb-hSGw5H_5S6h6IJ$)hJ0sB;R(Md!VdI|KYIt1s$#YEaY9-7!nff}L zrrI`H=7#?tPBvBT4|p~g2LIH){Yi1}n!C!ZPC|=ah-b zRR9C?PW5V022PK=gyTXA3v2raO^`!}#S`t)LOb8={9L}t z{%kYZpDqq;_RgIj(}C2+Vh|2QfKw8D1*@$UCqizE+bFvGf%C=FiNF$>q#ZzzpX`wq zpTm9!EI(=0o+I0W!C-<3_BtX3{q1WrPfjX1RKfieV&@8nZ39`;C8FHHYJ9c@5~pd6TA!ubPZt;uOf7$d|Z#29*Zk`7-?qy@EMbMZE^Dn zPsIQ!$8a!efEWGh^&m-Z|47reB|fSCjHO}|qlAHStRU$*CqRhQE8%h;Ex^AJL{*%4 z{T)@~N#7-B&o)QMLbp$F~PP#n0Bf4ss#D?_;AU))fuQV@U5>-`pK~XQFL+pC5_F@8G)p= z-jBy?;$ywlZQDNPrtIB?=zV%9jf#ahU zP_BiJ0{hA9vyIO({?g@wy@9hyLyP%b`$O{(KwtzK_1y?Fx;Hy7*;3q0vpKGCL`!Y~ zDYp)LPXaOG95b@J3*6X*_QMY&UvR5Jo^defv9#xW`-|1yp;9@=nfRNObaY|lvfGv{ zfqs6a!V7$=x>{~Omx>-R2w$Y!O%j@Rh&CVv1d|B%UT0Ri>2e9al`$??w!c0uL;~THH zF@IYJRoZ$@ah9ofG*;jlxSnq+Edo%Fs^#;-Ib8C@B93M4X&U4FJqG}4n&@oOOA0QU zFILtSd2KNBrjDKgrT}b!Xo*TB;F!FgK1e^6t`Wq~w;m~LBTLAx#_&++(BWr}B}w?! zMde1vokz5GE1g|YsAW&g9aMdT5_j5xnaA>C>K)VS{^ez5fYE%PKs-3~^s+=991RMl z5#yyR9d|BuZ+$7G9qF6R(P*038DQEAsRPA}2|0u7tA^1j;$#^pW5t;%^EDz=NPBw7 zHQeN=`t$^08j~L5XrkiBhy|>QkweZ!!z1WM{$6^^Ub96rr?(%bnLL&&JE3HJ4~>p( zu=u*95Bq&?ao91q(GY$( zfnD1cfii;VYPk1}DjT{w1J#ZBP{XX~Yqos6i{5r!hhlqhT9nKRe0|9*p4gTR zUjeu;da3sN_uGZIpIUJdk<{YX2M$$u^DNTW!<491R|s1?4Mu#oPhVs|(2DsGd30X= z(unwnRuXH5bw>x)cD+;sp8b0xX2(pGB!;oO`*xsO_P3+d)ukGw0KoW(XRI3?s1`R; z8|;#+68d?z2-G9TC*&P&seKgCc)S(=*4S4Ifm2hm$O-l(v4rSa;Ges{!sRUq?`Rrj zx##~l_>NB)9G{w#`o~s#3gtr)uK{G^gpljc`hw4E#2Dib(EYh zyoq$wR^-u2W*Jb-_`Y@v{Jk%UHAr`k;T!9{;G^#yAy-@L;K-H?f}=5et%ooL@G;90 z$v_>PCFCsN5XRp0b;y+c3=oT+V-|VvAzgaVY5$-*|M^lem-o@Bn5?zI+F(j(>(_ix zU)~-AOy{?Wa1BR`Zx@K8@E7v4OW8lb19Sw*5DpW~gyMd!pNbW4-?UdTkQlTfbbAh!BK7-Ok;-i`GP_IZ|# z?%2?+>&VCMW1+a3 z3WC;3v#I2Y5~!aC_YSp~4-wV+85A_II^f2#9k_HmfC9imhByCWFTjPQg(+qU-}%$uylSZCC39{G8C+Hy!Py1Ft_ zo*?dYl&N^Kk@4bk%H4V37Tr=78Yr_KGT3%l#vabIRr}8YMbiGJi0k6>u9icn`0^H z`4gv;ZNWE+cCJ>&Vb;1+g~u-pgRtSy6V(3Dg#G|B%ld6vwY(4@pMZmYAH8Sa3{j<< zlCUCvXACQK$*?B>G)&OisQXaS)WDO$Oy5x;OT?z;gq)Iu2*|Cqmd$}GBW+$Lpn>P+ z<_5Ab>)aW&s-|tw^3IQ-z{WFTf;iHu%xZV8kad2I<^h~u)R;mWnCE6hPt7Z465kXkI3rmv~x!9Crc@p)sqlH=3mTKy# z$w#{i*gOybKTd3H2Q<0ZjR_Ok-1ud6)jK!c{(AaW#349GjISVkVT!8BQ2$s zPcZLBym!0Gp}Ag!V{}fWx0A;A$^nP}(vO9S);@Q-Fs3gwhD#Ex@Ps4Wg@yoOs{7?d z%5jrZkWQmb^i%j$%+OEoHz`B$D)Uqy?o-67fwu55VSd%Lf0}sMCt@n(T-7S;qhpQh z+M1-VuJ_L=I+4BAP;d5Qx+=)&K$+>DHF^l98A*$0BjA#&k^mi{lcAPpvb}UVfHoYm+)ac4dpuW!X);&blH&=?1W70Zp;N#8bxtXyU z2BSQ?<*j8Iewp`uKwqpyXo8tmkw0^F5(W;gY-0l$k-dei-y#5bw zZdtYNc$UDEbkUw;ISCs658H4&M2~RzS>z^;AXfcroY-fNC+D`p@%(wFitfB38DElA z<6pm|R#lvICZ+Z!3m=3H3jWO3TfeJhyqax#Ya(vJ*zvX}1(wADbpMbA!EQY|D zueC||dcktN0-ZpVZ=x_6Pwis1M_T292%%#%^~+S+@$BNO>SA!`!ffQG`=l-gbjjkuhu^OtLsg^B3NQ8u=n<}hMosebd&Rnpts_~Vz6#n*~A)uzA7i5oqZ5$oICs#)4i z?+^oU6mOzp#vfn>iZH*iv2g~3byNhk>fLCKY$E3Sj2zpU-+MkKyH9xei$!0lkQi}a z`}i0AZ&fgU)pf$PTxIV}v6L5~=8abD(FXVI3^hrE2;lY9Zj2QR+)USc#uI^kqBpOB z!}mAome6TV~eedxY4;QPj4XKeSN$Rb(Ry%Bc%mP3DYAb(`Q4Sk#lcSnV%B($yEvEL@a#< z!Ww9AvMPgT^W&e*$9YSG5FaM05#p+RFWA+4egG{lI_KI9+5J8&2jcb3#xLnVpXS!o zZ1}H?$IfXqakO~b0t4W^&hM9fIrEMPB@e;Z`{wS#GgFn-e;s>hA<|Y%czL9soln1H z;*}C92ZHdou13GM`OlRUeBh7rt02&Rdu0<(8JaAAQgzZ7J(uOVm{GCFK}d z-gpcYlWk}`C&6*>J)k)3GZrO840SG)J2FdZnv2oobAJB*dI7{=TNz+&XK?T>0(|_^ z5CG2njV*;P(mRy~zinB=1>c3i=!J3DJ|ghXVpFubayHRS2was}Ue|qEPU-W-v-0p> zr*XP0?EV~yFp4AkS2@P@#E2M3v-AeUlLi8ZmQ%q@-aoS6t+jyYu7&?g5m|S^_>%(b zsA~7E+jg*U5|D{oiR5ZU@Y%q6N_>V)5Y~TANZxeuZvKnAFl|>IKV7V2g!Nq^|B3U3 zC&})uw)okwqs?|QurknGS%O9lztV&?MS?Ej{k^wU)UxQRCOGVs=Tt6gc zG`cgz{NxywS0zQBOe%0^MT&z^Gx(}}{nVHakZfv!7$kVJvh06m$_K;M)qih(R-STp zsh8Tw*R8J}?)c6Ezu2pjTt4OH0*A!sxbFB5ME%3cj}K3EONM9 z96EkKoMi1xjSbTSm5 zN>UA+@{xSw?|Ve|AmCo(1Gzsw+v0)VG{YZsn<8rS4@e4V-mK19XL?-$X&WN_=CPy7 z5zT%A_2|Cuv%tnKTL>Rlgh-};^B1_UI5``(CST^$@Vc%RJAXXEn?(h-2np3@ifePY zOpOM5%GgG0_HME(Z;TtQAS0y3sC9|G!UPS5;@6Z`H!`&-cTPWv`Q05A{hg5V*;#zA zL_y@oPode)zov_;bUzwrFDv4zFT+M!^y#jrdEAh?Wud9q$-v=2_IA)x1mf7q%x`f+ zYDUxWBQeER^Y+un`6$VA$y^tsTrngk+wTNw0h5ecr<(rbbB5+A&BljQKcIP}W3K4#I3i(a4LitpZ|I7dVl+q!QM!^x^JJ*Z z7)sk@?Z9qz4TLi3E27N^Z#ma%E}CD?B);{}S`5BtUhTTsa@8`#a%tACXXceiBHbW(IMVdv6HGA|AgQbUFd?Uk!@u3kCzY>1^S$D|B zc+Ht#=aUb|XdMiFIPrQ`6$Z_ka^`Bu&vc&D;7+bZy)I0MaEdNtqTM&te4WLd{_C70 zT%0h6=E^YL;PrcFDo&ZqP(N}3zxBy zM7|!tXhjUgZ;BECT8NC2Tm95f82`3gGV+K=SWu&biJaJSUsYK`^{!phHhL_wcFkf_ zIez)zmx4!*(DrAc_kN1@@`qNJ0g9WR;;fEzXY=*9BEUveQzOKw<3oqy?*ERnvvec+ z#=qq{2fwBAGWj*9-&Wl%+N!vR@rfC;=kTJ*&m}Un1n!lfHrj&G~fm_>i{cZD;E?YbpcH4FbjpQ_oPh-rF-WS;FFC z^8(3}Q#-x1?}%~?pA;?b_|v`g&i>TIh9V+m-iV%JWrSZV<)MPonflzaDMEak!3 zK(xl(wgQ2#e_!^2M!SkE5dxHM?4|2L!_3wc5i(SuqZX&Z_qg9S)Ucm1xestHdeXsB zVlNWW5Bt;RhGm;zPEN&}h7T|#8KBrksCo3gZ7SuZ6RR?6?_WPOCqxY;@vp{N@>31q zb@$rZN2D+fVFrMAB5Hy~)g#1zGw%h8C-qggcaziPR1A^*@K_fU(1xY7^t>%}QH4X*? zO^A1qeNSVtZw z%odVE;1qolh2orv2TBa^E}pde?~3x8ul5AsYHSZsH&k(DCk-PH6XOp`jrv?9YcGcg z8I&bD6P{j0hW<%yjrm!O9|H#?QS92lJmRZA=p~=&yZPLuCx1LF#7-zlG{nbkAY99* z561SEmoxE`KVVe0be+I4nwh|^LV2g$CVtb3R#7DLMfG#T=~`OI%_3m$99vmWbNtLU zW1>Syhy_qs7|!sm=?yTF=?TBaM?y)~4`0mD?r{sQoJ+#E3b-G0zWa_u6|LOvOSkbS z9w^?CkC6ODF3LsG3}&z_8@>KPH))T>6wuVbPyg1{af!5_zW+D&8K)om-r{I3eC{a> zgF@nP7ahf?MWP>N>Z>9?-@i9snJ2t3?Vq2WQz*6bb!FLby-qCVmBon=0U@y7Hy76O zOZ<$tk^a5grd5`y!^65jJ^*4k0!)9*bevCBE28_kk{4}EsAwIfbkCCm53Vbh_UH@e zn*JtsA%16Q6}Bc(_)K8{Yru+_oVTwNh6FK&S%AqyG@)s(XZlkMXjQu``7rfqoBvHa{ATd_2q!fl_P?26rEOwnO4s-FLE@6+r*C(l4mVadYSo4v zWRz^oG2$zQ+q(=zZ^{ylAFN&xCBmnqin!nDZ;?y}Czv6Kb|+USnEfJt6YKD$?dg7^R)ii&TC1;Z?p{$+`log!ttyAFC5c9&rkz2u2_umoLT9U|(-r z>!)6^RaVz{+7nD&4#!c!5!BP6OTLJSjhhYeooh^94_p<#3gch?xsVkTa~t4TJ0*B2 z(PIJjYxswHeJng;1K8G!n0te_h@AVQG;uL^_OHbPdLy}9m)w|?u;Q4QT)h%JV<_cZ zS{(?d3s8!5RAz8NUVRyU`$%q}<$}W;=-6V0%Of3)&Yt-#d$f0@)34OY7>sFN7(t z&mJq$aj4IWA`2IJesZ8XoZ|F#aKE0KSRL6@q;I*1XX8iT2OJ3bh>S^tLOh;^B!yZd z%H=Yd&y^*V%{!n9(kuOqTUW^-%KmfG6g6qOeNxsYdJFIcMlGW(hVo9&ZIR45YsMcM z?T$WOK@bpZ8*Ste*i|OGg#jK4ABCOQcg>?q6`e*OY>x?VW=_z)E)Q?77%FR@s#+7u zj1P@Jhj2rNArhT=SNQ5S4jx5pk$Mx1@bkYq9f-GnLj5c65!;!RA`L#U4`XU6;K;@v z87+QZMuMW@1U3_=^JoatmeM-w+JE1YlJ~@}HV@Z_jCD-;efVYjOlpJ7idWKd4*oWk zDnd%uTKz5Q=xhWhkt5GtVbKSllxmKK9Zfm~6ifWx8@gyayyqtv0`nvT4yu~%nXCQT z>9mr4#6xCTTtrA}VO|2OBi^2NF-5!Ql8j=cF*8D)sl?F)L)y3bd`M$wN+v~&zhA3y zlCaFyFE6bOZ}OVpN5xec^;opnM*(cb}Klm_PHv5P+MAXJOb2w7R(d5(!f6!@I z^3QDr6KEND(&>#t+y`CRn>49lpg#(5!^XXd!poy0dp3;ON~b@AqC{-fK-4_C*i&HV zLnUf6DK+tY9r<+i`F!%{4TW_K;wiIL#Z{)Q4={S4RFQ->xWnecufE93?w@?6`aF3JXhmMUU)iWbJfd?M$bVr^I{(Q%?oA zPYg%4CTD-v14SXB&mMfaj*TW2OlpA)j~{qvJO33cw-*A(6y)LDlzK^+zEr^1-bp2= z&pU92)eqdY<0OB&nW<1Qu(B<}A9j^>V&<~u_^N4wzeqcn{{geD_~{)mN?c{}p2QK7 z9aLQS?T!NhEJ7mXzRjcj8@cw9V7?NUYo30%c^r(Nb+~)CsA9)pihA(YhLx7PU?I;B z-ud&K;S*_csljU;2iiA4bxOkW`MboGR*Mlxd~G#5tfD*Y03(o(uBET*PH5ni?z$ut zS2vpe()ws)mcAMqbDvjN>2K7MbH!`(L!}^XVIt)FI=Y#7bqIek-4T^E`<5z zw??bU;|?ulpNg-vWTGXP6;5{2b<{63IArSJ1TcvB4*FCoekh5B;mlX5`d?+52-mg$ z+J8(K?@j1M>#Y>(tmgLK(St&)XRZpvK(|p{KI!_D(o(&9K#^%dqg}v5g-^&Oi9n`C zICjocS=O#|>WTx;e|pj5yYGj2Z1l*(yQD-8j9<-5wfDqZJ6S@)^W|Vtdy^;kAaWEg zlnn18vHR&Hh@q?Y)?l=KhHNM0{(`wy&9VHkV2Gc(nG8fu1Jt5tE#;SM98KiuHGD)l z-xlm_bga$n^;S)Q+T3N^sXS@vT>4YuzS7Y*mMw3Yua+k}`2hx$!}r)vB)f|HjO&*! zHISx>m0NcZ*~3!bUSye_w4Bk!PePdE#rMf2W63~3`wg~iX_QP{bBeg1ze6RMx=`~h zM660T$Zu7;uTirs{6h+sqO^Rc0`pizm|*Bz%l!p=y_mY80W@4Nx@Jrz zzI&Y%B8`#N-M!7x(wyG2r|w_yD!u(VW!oqRk;K=EavNhykqYzlx^LxR@*sj|NAEw; zjq>Ho=wJF31K~3duK(6yww=#|J>lP)XvOrjRy;|++wlrA&>1i#t(&;&H2$eaJrB+~ zSBsbzm{I4Go5A^DDxLrp>_=1QG#Sekn# zU5pu~X+i zmWI`~|4-2a9}-L2M<vwM!cS_Km{h9Bxe<;TCq)?S`ZL)UtjCIS=P^5QN zEc*;11Ch-*ekx9=&ft}U@{?Mj^B9CK^*FY7+1mOIdy^8q<0rIo=^XNT4oxWMW)>rc z<%FfH=?&SnV1++$cT1ub>*$+vBo>ON+)h3`U)WNYe&*U#b@LvYSAj#@_eB;6OZr4oex>qT5`HN2a_cJO3j0K? zZ67}(n$z+687I8f-)FXuYPk5A>!xjQvzxO{)~nb%K2cjOff0|0GgF>6eU?kAvU-&H zNx);Zpl+Mc!o1bRhz<^el`@vh_c`{|`+YwP9kN@Y)o@TbP?hL(tIt;uaZ1l`0i6cP z<{mGZ?qk(Eq36-h1amxkH6~=jLQk~q2q-Dn?)?E3j`nduGv?A+L1PmkBd-8tR`z)Lp{h_dae2G z_tnLk*}u5OQ3Rv>D)?L{}=PW3zgkEpMX zYx)nr9U&nt9ZHIHj7BLD1SO?Ahrk#y7$Tt{C5_Udl#Ff|9nx%cj2K8asHB9*{e18J z-FyGv3-EOF$D}z)rGHb{XK`Q1iBp=F-PyRDioov4A@R~Nd zA$$yaFUL=xqzUzI9Dx?2pBz2+OKblK0y_O~La{7Y_G(KQWt~LTa8NavZ;Vm$c9~rI zFot=}z`Q4~(>bCI)jUWn+q%bE6Sq!0NmqeU`)zT~&2?Qq)MU-$*F-Q_jCQiOP^@U< zEIII%!p}B{E{2JFV~(I}=B?r;A<-@0lk%+B0q#|EPJ*0fz2$k44 zqAX-z$fMhbGXW%p8a_2XN0EZBatE`lrElKExh&4N-FfmIr9o~630-jD3!o=nFXWa> z31yG;4Ew$hid26|QEu6bZh#Dxv*g+9-ym>KTz62UBrx-wk<%q!Y!Wsm5Yc^{x3|u; z=0_8PpZHu#nRzF=s9hvje`?P41JnX>{nNqXcAfXPTd5BFNqVzYZ`*q~by|Xnvx6#O zw5*Ea=IeS*IzE7nx+=DoeA>`P3osefk(G1Y)_fll2x1}GwU-PeF9Njx9wGxv@q0uNSV_1;NKyL2=3`c?rMd6gK}lKX zvxN1d9v#}Xc-W9Ji?X$Wmm3<%u=pVOf;#1_K_}-r@4Nnvantx3CG>1& zCRG-~Jbej&D0XK^`!90;qB<+sp54Lhjpg9rtb3b-(zt3pc>SE3xVH#|0n8N3y7RxF zA>bE(?gaN_idjCRX;lO2|S#<`@2R_HKU;k zuynrLn%O_w3poyK>C9iYLu^3s+t1%dxr~;c#vlx=OaWHF(3WU6QVdtnplvi-lz$L# ziJ1Ez)DG9^PjLGb-kRW`KQ)?`4k8PC zeyLlc8RSHv{U=Y)h3IrYIZ+nE4)U z`s49Ph}4YDg1b(eOIp~*Q2cFH4Ms^gwIoJ%!^2I!}NP?DkhK zFxU)!WN^UT|7C3Q*~ELN;>B!g?OmZsm{9(U69B*fU448{S+E!7TDvzHU!APh-gSmA z28k7pdr1q0;$obT*G^oiH88=tp^KpogW1=cv`WpFfqi%JIL$MnG*lixHU1xZM;YwB z-Yks5%@Ingw$3qq20>Qj{$ms{xDbRK`TxczUvz+KVQ9HM!w@~mspq)8-R=Y4^jbfl#8p z=o5`^6#fl^`A>k25WwX8XH5IgDfl(vL9!KO4{ntjA!b*CUz=LYD{_tEqwvKEArJ%n z(`5NmyU8(uFShs`0i{C0*Ho0973KOv%p)NHfCH{GV6gem^$tV>aKHbz{a*3raQWZi z;{syHNG>xt*VT(yjQ*-zyV(fG;M%W*BYomlNY+SmRdvX==8NZs#8(c}DWJ$i94<&T zd#--SRtPW#)RLV4iADa8FB4EOtGzv_8Q7rBxp>yNQ`cn8M`XxhnD6fj5t9B4@;XgT>Hu%q=`=3VlfA*U;9f3DxHaC0T34rMP29k3pIb_3` z^Nx5`2fgc_YnNQxIl*w3K(%G%e^~%=#JN>BtGYBifsuQ)XEUNWp0n(E;zAM3rbNjhh9EgS+r|_=?p{P*4SU{zuC=sp348swJjzxDmU2uN zIG6kaH1vHW2Dah~Z75%dW-Af8T{6yA%o?hD}%?wT}hUpf{z;Yvs4jjU^dDq`9>jADm(|NKpS+z&lKaU{Or9jqcG;%J1#nPOJ^zQmj)~cnsszx&QVER_>-#?ND=sJ>&EbrZ*v1 zX2#nA)kdCQMzejoOUD@XjJwO*jJ?4kBT8$v>Yb%HKEdYSJk(AnP3;|*%C*f1TS(P@ z)?&Q}Z+CtM$bJOit_a4&RVBI(*jWrvZnH4xzoMOGt!zfqS!9rIZc(ur z+(9VMbCO@wyERu@sQOS)c+UYW-ag~m@?u3K z70-J0h|rwDZ%7bD3)_kI;3C-^epr3YfG&~z6cN2WyRKIsC^-Z*zNa(qAHF$yAPfF_ zNbj%SVR#;$Nck?<%;ctH54%!D!T0<(HjiHuFGl9eJ7|E4`PP=*)SYhi-WY1@cXgdT z`M^ozEHQuP1FEAkr94yv_6f@H?i)%M%FGLo>(Mo)H5N9?Nb4)icV_mm2tutA-eHXi zdSH#bhsR+g)@XO;RyXnO>(ZFI70cHmX{>J!^JV5VMuk;T5{fC`t`kNMwWf zyjS_%G<;{iw%EMK?U>+xJ684=M0I+7Nyeg*(&tQbjJE4wSx>!Nizk<-sn+yz%?utJ zP;L_m5uo|RHMZa;mZ|IV%4}QkT{YJelv+3vod_7}8SY?~$D^Pc(m5Pz!w z%XeekJ`W53^&d4xN~z|K_{n(K6;3%+{j50-g7IjkFdR4* z{!r!2D1J~Ve*fTG0Tvfw*hO#Z3qofYJ$j!wV&VTvp4##cy)sea$=Dar`xluQVA*3(Yn3A30`{f6gmsj^!IpL&mpKo0+{!K#7f;^rG8@q3^zsR zxc@gGMZUhxaQ3LqeLv|-{`*=?Guh?%tSdxE?mpsfsmvf!AyU1bPmY6$RBOY5Bt#t>sSk-GLim?R2#`$HU`;9&|OenXG;iVgFacc`bn>$ zjceZ4#Z}hPao(`fe4ih@D`UCfsmAk)yf6HH%IB-k$$>XT8SJ3hUjB!pzsUXKahf8U z_bCZiyI3i`p;SG$?>_v%lai0XHwB$QZy0!nNfxb$`giGbVrJ-+BrX6CFTV1)jQde| zt(qcU`s$4pWAeDjv5^ZD9r>DMTS(!+RT&g0)w4 zlT!8G>xyk)1iCLxup6I&wHvDnJ*H+vD+rly9R}(R27@Z@XG+y$(%5S-@(vN3b2ffP zp|zM85q_(mFP7xLzR%UZq#3iBzI)mCeL7+rOy643;?_i|4e%!k1KB(j{fenQrh=B= zG9`J`i#I;!*z1j2l%d}}ZS)DVZ2TqWttg_33U{?o9OvyX(#A2IjWB4T4sA$8c`ysl z)fHEoiGWxA(DRDY}rOq)%VYXa!`UVNRbT z^h{!_51t0YZI!1apDM?S{d}Asw(EavylR^NKHb&E3iL)w1aKjbj2&H(9!LA-z{7kBfyZ)~HRxn9NChu? zv{!Cpzj?sFpvGn=c-8Bw-olbDzLjeM`-a>+6<2f@xsU^$J_VZJRLXBcgY2`xg3r^| zru`SDNoT(>d6w#v<5;@dgT5Ug2vJ7a>|ye^pRTK1f72*#9dHce>9uzkVl`-91Uf3q zRkkb9IrCzypLjkfTL$OGe*UmQS3a2Mc;f9P=QZEyAm>hu7U@su86TF&L$D3iMgm8v z4oR}ZV;`xWvR}nCH3aafT1gwEH*CI<;%{YOf88<_QRoU*D$@B#)|D;IFhtI29}K)8 zk05cm584xBji&$2g~|6LEnhrsA2cZ(<9|?_nJ2edKi&1;r!3|!U~DUu-!63r@_qgtWPl}o9g7VlRfO2ymUpo~jg zp%;W(Lfx2u_qmz<`GP05850OuXIszHGIza?7;v(Rr$7Tg2D1iHB3|EMPEQLL0^twR zHh1krcwbVQ8s9-@ND17|RE&7)vrw6FG{2J*85rJXnIy(;WT?Cz&w zsa*0WyIJ8CZm_W>N)6fM;x#>WU`w8#E1J%${z``p7u7gdP~@!O{Ez-nyU~!te1$T3 z@3yRzKCm^bY6*Th2inImN-=b9>l7KZL`mLvu+Y@Xj6jqHL{-FXzMXizP-(WzaFZ^2 zeEDNc+blQ`rL>7^s+8e%&~r<>ba~#Jn06`Tr{_po!aiwirz7ufqcg< zh<{3%h`>FwGNEJ@B~!bN$A#wvJ)(oAqw1#>7ih{58S;~cX`CxCo$I!y%q(!u-}G5W zA=lQUS!Ss6{4Z~GbJipljTgy5?KU8y|i=A-hNg4`^RKJuc zX9m5}(bit0wnBg~50vLORjKdt43JcH^pDJLj+CCclBzlHGap^r=Wa4{zk~Y)BpXwY z;{&8?2*h@tlaC-EmiFdufYw_PhO*(q?tvz+CMk<4^Ql+Yt`-Mai0yw^k2Va?UX0*_ zawX1d_#aG+iE#5drR_d}0c?D)>}R??=fH{qxezPqW zaAtC|kY&~o^?T_>tI`VwQ9;oNfZG6z;g5joVy=Mw9cCgJoXGb6+Tj#u?a1k42U%hM zJ*6}iq`k|voL>{8KrhmD@F24(m>B5SpbuB)1NLf_WG^a3S2C&(q_r)q23X2(!iONS z*zyM=$HHG5O({*{jGc0#R4uWr27WSVT~P8it(ef24M)=RWN*W|b@g4cC~a@h>ke2!T)2wRGr`)y!By^DkP<=|5YU+E{&~(Zw59CE0hP zjfT}T#=sYTYq`4q`N;&-S-Fbi*2{}R4rFW?KLOZX%^i^5`khmhvMkVKA?EM6EgTU1 zSFvxKaHy_+Hfwh?MRBBPsD`RVP(3H|Msedr2I=v!fnPqR z_7Hb1v^@ofgH+xHwExN(1=fS;oE1FSEJvn^`eVCeAPcJlfXus5raY7+*EF=nE zKLaaM0O+19x2zIyStU$aF7`yFOlsuMrqbugoqgie&1Wid*r5rMT9G_)y8V!-PVd#y zBn56Gyy>DWwfkv|7NQWva_r@p*C)}%c5~d@XRdp{ujmBE@i8w{kYJP%UEMTRi5@T$C9bAG)u`!$HO)q0WD{?Avy#1*m9W3(^E*ogned z=?+a{ugh+_Y88RqnA^SI3{X@l-R#Ghnvq2{60%wMkw||&=m#g8F1DAhd(;@>RBocp zL}D9nq=c~TZujeY?fYsS)s;b64a1FNS`pd{HXD;hf8d#M&BVzeuZ1g_9dT0@9m1xl z8F$-xZoWv8unrZjz8aa`F)OFb8j36J1st|>ndt9THP-lW>dD_0f0d{kt{l|O!(;-B zm=rlDTVB_23u@xjGX6_Cta7c6hPwf3KTQY*)i}vSeR?;y)u>Wpy+IbF{q6VSK>F9r z>4~3zWa}*_F8O9N{1`OZvOZQ_I^Ogus5@><)i_C7v`d<1IK0%={wUK3aWJ#4bQDH& zJ_wdx76@@vSf}r)GkO!daD~KCyECp!pUJM zQm#C6wm?gKOT!%F{b%$V?sXlKJiqahdlpz5?jQ5xNmK#_{2v}A8)6xlhYZSee173A z)HFyeIWS%c{4s*BN9D}Gus9UblS#!#h(0Uc;j+;AOU&@v7eQ>x2P(4g+jtAOyYc5~1Q_8iO2?xdH0 zzc1UHo|ZRFo4;HgLlzEsUney55hbdD6#P2``P7*Gp*x11qQ0 z9Aq=Jti3*K#LrFW7i?{H*aDUMU`s_XKtA)21ULKv!|Mm zKo!{;L}r47u{{PaU0rj!wE7jgqoTav{q>OM1qCQp$`I zs=Uk%-`{74GQPtY{liT&L2e_Y=0{HGyF(7H@j00P{KYHSJp#F{>(y2=a+*#DZ!~et z&$7T*XP2BLW`ENw<{tPeM66V=4TzZ*Z<4_j5CLkg4l9+-f%*{Z-$2C zhlQ#;ajD=OcV+;T7<6thetK4GrMLUi6wbanW_`1$VtZJJ2llAMV^npL7?lIeMkR1K^@&xtPMcBshV}l z9cF(%fb9X(pXCObZ70?z_?i&d&jvg1K!qd`%pd%et;xn+S$j;Eg!Y;e)8{TyQ}mN3 zBnVe?*hc>qk2KCd53u*VPd4OXcHJENUOYEjas_Ybii!?K{HAEig`y9kXhS5*Spg92 z00F%;YgguG%X}eS@owh3z(V?~c;;cQ*^*&;4t2p=UcQf-FqQdjzu)vg0C7p3yy_n- z9q}KYuAB4k&QF#dGv9rRSKPak$hP&jNh5U0FlngQxfvtEzHs`c(xMV(15ev`({y_IYdHew6`$~1^@>{>@=G>i_NooRd}(e|2(hb$-V4~ zSbw8c+#i2IC>8KVZ!4Utf*Ve!MOJt>2kE>r?Su{w>$jNB#nC5&0LT+mVEgxQP88K}#O+sP;JjVOv z8U=18a}^LCN=--r07x*%6=I0y~VA}ZIO5FP!M=%ofCGN=d>;3YFYKB#|tg*=I;F)3ih5k zZ`R>hyPF;r6N@7>2Vwz)LTMA-Du*F9>(WuQ7DWfhAtg&yyN-_9IFx(lUa5oG!?)3? z2pN{Rxr5}x=jKb2frZ7C&GB?oK;+sa9>A3-!+Rku@)vFq72Y$CXf=)NyQwM}mFs+M zeH(NO4{XSV3LtwX^WUPSE0{VNNbFQvKJM8Hv?$}oaMAnwliRorQ)y;yb~7R=8wOy! z0jkKEut^ju=dGcC*l4*Zb~;j5^}0INNZXpX|G8X^OvRl0H1_P8LhAe&tlKXhX{(oc9%5te;)QJ5lCX5L!&vo_H)y35$z2s~IOJmIs z(GT7R3^%2sAXtB+FdsCKU*m9Pif}|6vRFs@ssu9FbB~vmF=(KT)Z6 zT1;a7ppx9QqOr@Ha^eaG=lF-~)_c|E4X|LD|8UHLZWe=vobK#izlEe}ctwR+9@or$X}`^yrdpM5O-ap_7Rz{nyRe zxg!F7W2OXP*mnwHzSURtU;@C3nZX*V1w>}vHb^~zgdg75R@kJ| z8s%r_Uf~>{^kwga-u~VvLwl+sc*g*8MF`y?BH8RI5!GHUKq{NrU94?FLcw1d#A98v z>Z{)%lBGBvT$|NyR`+nU$ReVwm>$3oee~RSOo+?3-IKG`xW)qd>_Sllt(`v(E~V2UzLXRd6M5=eJVa#ZuG@1xvHHu}P;tC(YUp5djZkLZ z%?i-Axx8w+cz%zj6|(k|+BYjukT0gTjN0YIV~sOx5WM<$kJf1)TXnyUu~|QzX}>fv zy9yJL;`bx&S&zBJX&XM;|Bo*W>tw^=M9$!gj$Psl4`29tWh5PyA1X7=3cPKCVHAB4 zO69tYACT`ouDh+x6cB$uV(f)YU~ep-s3E4g6MO*SR!NznEG^Ql!rs>Dcf`RBs)Za5 zrB6Pz?-W)1)+hQL`c{Q>h-D2LkCrB4m${be&;o>pZ9%Uv^6(|fa?BNG$}ir5Lb_^4 zg?U-)YNzar2$iw6Se}vPMhrowfotSpOE6?qD>tC|N}S4ckZkOmMaaJRUAqdvs#q3O z4RaX;|4OlnE;WB|M${?4ulv%u0&*y}>6`a9sK}G_c?>k-Wg7V_!+pe^t}g_7#x*LD zaOxA}Yw3)bihnKD<8vM9rjPVLlHTs;gM<42xW9TmGd;s;p`Y5IfFjT(kW9*#*D~ex zzXPX4i-RoqV9_^l`(l{SCBkhfZH_K*Ee%*oXYZLr$6VdN%G={E&!Q5mfdMb$O)7l= zki`}(%%{OCr)jz=5<_H%$z+!|b;5cCChw1VeT*#7wT=JY0t}DHnlE^O(}0pEz%7SN z<6NpkF(^^H(-Jha`@K%Lkvy%-jVx8Wk=>N21rL%d$;2VWjA=Y9tU+#GqQY8!+cgH6 z)#8Z_n>Ag5|_CRha>Kqf)s-I$P@3Z&%BLME1z}r!5Xd!ovJt zk|*mwA)|dmc5^dI`H8nAPc<~M1%w5h1?eXYQ<-n{UzhTiIsg!lQ7@jMI(S1?+Lksl z8%yTRqQbk(n*?J`7;tmHn`?FgaBvTQ_~ryd(0Iv=Zf-H~*8`vD-OOy<2KwTdKgVoM zY&p3vKzdMBo}UCm_-7FN)iv)@N5Z2zMEACB#a4p#?v9q=dlv(|Q3hP{=Od%0hPaRZ zG~-WyTSac|(4edx13O4EiB5S%n-B|nkF32@(r65ha=cne96Y8x=LgRUJN1%2rn^gI zY$Q6Z`qNzE%%jsl4Jj5I9&P1rQ|n*g#+u4<*$So@^O;ka)4_GYmP7jzrrjV||%3{1Gc1k~#8=e{JXI~4Pf zM(c1cvTkw+q4BzmToVtxhhbK8-Y$8rYm;`|?;02|9E_LU%N9~$2h*APiqi@b-z11* zJQrR88h{=oUAJoTnrvgp5?J`82=@4q5gO%1TBD<+-IA1!|Hi_dk!9BV0Lw{XyfrTI zb6&tA!2X^#Y;szr932u0FSlj6mxw$)hfXDkPCF7H>-ewq3>ssog{3hIY*QgSf>U2# zc9HO}e|0jAKg;J3VY;i#Jk?>7KAnEQdT1LKk_zpF8`vFXrkW8|AnFK3(3GaHDIz|% zIek*gh%H!Et=ARw-oZi+Cj{*yR5)br=@EJML>`)=Ym97)=dVkrXOjd_^j16fVQw~YbS+Ti9pMq6ro05z^KsW0L0H)n z0}=L^e@ka%TAzN^m8IpBik4t<@9Pm|JKS+v<05D-A^7v8VDz?i$fNr+ynSW=UXa7V zUUzy$O|8Pe%1+_&EBb&WZ7MxVhp&Nb<#}J^IDfh1S^f>@_ld6|`sB&8qDHrmq(S4k z-~>DbV{G_>7a0J-Wv*F|d81WMMZ31(%ICiXgK@yVyGiWFgP^mL63kOv{jdnt=N20~ z`b#R&y-?EGFZu79B0lC{!WNKj{A0ST_(>!v9To}nZt1k+ z#gu|V@_HN1ChK1ErnZ$Z;vb3w`Y~!_zK_)lXj%i512h1a`bIk;2HXa?28NWC5)TTi zkW~Ls;m+FCtF@E8uB&&|tN8$}Elcg^mgpyRub#ZIW&Qz5{uF)Z_2au?huVc`yVqdp zswh3NN(ZMb&Q9#St5X0WJ`|&&orKFryU0~KgfMDLQRyTl4?W%k@X`{S)uklbPjjD`w*e@x}Hlap!8Cb9Qq5u>m#h${=(I z`?JbP7N}s454OIP`BL)zp;OsS$7ibgh8>aX^8FZ1$ZaZYLt9yHE3LD(Bi#S@Wo)`i zw5zRLANZ9?vLZTj_3;LQB@|UbedXNx<(c8zvtMZ;wQ+PsdGQ`Q>nmkToKA~Ceck)c z^$+~i$VTrJ#4;IbJn*W7S&{LQ%Vak)3X_9WWMoO+R$*o=Ki}sfgeFrplH(8&)Qs~! zZ)?oL^x5`|8zeWV{xSVM_e&zb)&>*4gclnZshzn5o!1cnz;ej%iO#|+H|P&lCIfaD z`H|c}troL*`&^n=X-QDbZ%<|L$>t@8Kul2fJ@WJqvfbTyql#Z?aA$=?nC$KB?My}6 zzDE~Mv^WdTk1mz4a0|g})+ti{1=C7P8*?GSx?(Dr4KG?G(rDM4)^;Gje0DB()zg<^ zSX%T74-+f`=e88(Qp$FYk;_Fa>6+NELa!Fuv@L)))kaugIm_PkwfSC6O#;nN;Wi23 z&37Pllu(-~_lsUO{(?%@-h2Y*PkpUF!@Ej1TYc7xCy~;Mm6v0lpG1XhvDMF;TvatP z6r*gvUq*u*#pLI;M&GDq2~&Re9qWFQ4L;85(3x zL&wuBB48h@ccb&XMoIq=?JW35xWQd(710{R&P8B#7^eJQz}%m<3rk{vn-BNMV+cwD ziCtGs5gnup890~)i&P&1qTsGb!GD_P0}oT_W^1Z?N~6^MoKh2>lMp+_0`z(0HTflx zuQH>a@tbOBli2E{QLkZ!h)_Q767yaYx8d256m!p9a% zU*!bvfD903%7P3Gm^%h&=ZryUa}l>oMOgz1{~uf3nF%!wUaQsG=tC~1vD;hZI&}Sm zJ*~_qX$0W3dYwj$_ga7ddaoAN1%E!XNYHX`bJ3M%brqk`YGH-pvv%?!HRB_)XS+%;k&m|QLQ++|b#|HjiF7A937T-%6d_pFDVmz28isID8HkD^ zta&oq=#s5ARF&)YZvdQ_S|dP!*7W#Wq7+!8_ylFm`;_gy@P7GT;D+ciXYM=}!(Poc zIv;GrG=3-9%%`nHz?xNhk--x3dn$3W=I1tml4vs>JVGnv?ISm*J3@j3K#*^q-%&?B z6m|xcv~t~yJdIu!Lx!`6o<0`vA&X(*17$fk+w-?f08fS`$B5&}7~9oTCo^u2V(sb0 z@C=QvzW3NG1*FBL_wf$QJacX=1;N$}k-IO$$@E;yfF_&x&N;r}XR@uF^!v?eJB!EL zDK#a#*Fdg^{%2zE9b!9NI=UtpXlhO>1jBoIcTII@ee~I)<--ws9^MzRMxsTU(sHcK zJ5Qff!)99D0)uQerhGp3Cu?J#o4YceE$}V-@JbnMx(xkBazbtPa)^_;{bII+XB3MY z5#HmjdBsWYEicRzIhx~fnA&stv*uzOIYRjSn~>HH77sJU2IyV`a|`@ziL6c*CFNYUdywtr%de&=|@BIOwVF1QfvdujGL zhDZ@j^Yk6LC`;z5T0v_#k}RO|bACPEX6;LM{zLJ+v*qWH4YYMDDzrB^l@(_aye4t# zwIpYGJ~jOFEUhR8&nX566YBK#lCiY3_V&j6x+d#@+u7WVZEGMGEnnvSDM7XLACpT1 zM>9$cSFT(4km)_d>So;5NXN)DIpw7!RqR42Y8AkoLWn|e|ji!|vv%HY z8%!07G9K0#>E3l`GRKlK?(5xO_5Y4D_E|5Q`RoQhtJBn=)CYtZ+eQ=KRW1|}ZdTF? z@eAl^ew5O-WbSa+;|HPXitJ=fmroo^F{P*zhJ1jp!Y zdVEgoL5SPh zD}ib|Uy1OW(S^VRt@G>5-jLhixg1+eJ>V}W4ey9gY1A=RW*i%;y|VgNsqXtng+1+) zC9rUvXf$=;hVpT5#=Nz>TV4r_1q%*u`>*;Jd>$;gvx&TtWDF8^m~1bgpiBPlcAvvt zo)~Gpw+9MJksG^x5Cdl$KM;gEe#An$+d2CIW!!@Y_d2d7f~dpgu?TC~y>loyV;Vge z336f|GZ3gAmSZ}XyX$OXki)6r9WsDFB>rQ^cYa`;<6)RHqx66zw(5mdQK7GXQCt*sXR7*i9Y9$1&-`fI1LUb14`($`|a*lUu$ync#Hc>s1X88Cx_#p@J)4nDN%GX0+57^|`hm zcvxLM8u0Ows}CKQ5{o3lh(DEKJPBUnQ2;cH@z*lW2*O`ht*F zWd+7GwMU46@$Lp;GG@{^(l(?Ru5qo!TK*8?^-=VRB1XJ9UMsml=v{3Y`8y29@`mM1 zoF5)r7Ha_P6N6>_kP|*l(q=ysDfj6%@3V1AuOC~#=7p|Y0KB62YW&kvBBfdHt4D;!Vtj5}Z*c=x|^?5!E$cW(WoRqu4*L4 zF{|e2tl=czzl>MOW%7LZ@Pn%I?SoA~FX4N`>4@WA%!;oeK|E;EyD(q%$8&r>^A-G3 z(BsCgs&Lhlgon6Z$Nt~KW5+lAv#`528GWU(fJfA@3=w&nQXV(%&s)3e0!k{~#KqF? zKSoI1B};F3Lfdiv(o$?qR#o2-@M=n*{#D<4%#)pI4W_Qj2w#GW>zP?e(?D(7A6wMsr4SQFaLiwXHt(a1+t?_w z&mCK@&6EJ$_7Nlb#;Mnr4n z?X}}Q-XGb8k?v-2Dl}A%IT-0!+|bE0ugyw}0N!q)#|#?2^Iu!s1r)d2TpeRdH$@53 zcYRod__DH#m?~ZXqo=g6PtEhHu9n@`2TX7JaxLkg4SZG{YlU19EwF}%(l2Whye96V zI~EP>30!8ovblr?);_GBoPf&yDL67WvJgXfzFR9taq?JBVS=@T%uZ4#FVm~FaW-e( zY6wSG_@~=S3MFXLJdt+V?&CGJ!6@FR@^e=Bbt5hI5fIynvAOVz`Sh>^uqQhm^_+Vr zR{Y~CE{ivaDPdq#xbZ|OFX658&4gpgYj$xPq7F2Po_ka7)5Z_|bkUEdYGpK&{>^q+ zDQbjYLvaSZV*7B*~+0Bm~oBB1wV@ZrNT(<8 z*xD<^t8LR?(-{MIjx8;c#$!!oPWigizE1!;`dhH0 zk`b!I68@*w>=(F9e@eRELw!_g3Wc3(+4->-3@`Mgp^WqJHB&ylwtQpq-4ousek6rDFF8q#$J4Jfx zt^O+OtUx|ErM8sP>U|+{l~w!FTiQT3E4H(Z{BzKV1o$MoslyS{YF$xMA~h0F%y`m7 z$MiGil1oRbuiPprZYypyNKV??vebn~+PhLB@CnbyGUF(M^zqc4?7NvTVN!DBpK!*$fyAL{pL{D}3` z+wh*lU5bWQmv(((-=DE`UmdOfu;)fdy#OjVBxEi(Jm#%3)NOCzRIIOUMe=k+4WH)F z!C8V-GpklxZMT|6+wn)5zu7XdfC3aTKDZK%Kyu80T}jQUNJmKhf+;#}U8r7oYsSO5Ns?BT?Au^__y^jg|} z6AQJ9a!<#+?NB6h1mxVd)#|$y+{-oz&<5VfjVu;4-p*b%>dsad5%u%;>n3T$@E0~I z2}!ABfxLl2X=a56{twW5=E=^zXQpA9ERX9wzj9vV1~Op@JY3oPJCHLgUBf|IRX%nr zV!bSR3BHQG^NC(a;jm1j`;uDeT8I8@Utu&L_G?V$_1@U$vU%}_P13x|(mYMdB2}u{ z_FMIX`g-Ov_(m=pYi{4%Kxs)TuIqEj*gVSB`QzaN(kidT!tm&=FA$4m6!W5EIg|3W zNe8B+tM->KpgkLYsTK%qoj+9FPhTF#YU}_PzUah+H}HYBaOVZ>jx_XKrYXCkCk3G7vc+Ou zg|+aAmyRNe``(qn)dgC-N&PUfnV-_6W~mJ&m1oWTJ|^v+rr3^_2~RCRSCP1WXUotI zcx2|rkn^gKD$IGN($UFaDOZ-(@3zz%80IeWXVs6y-(-I|DjmxoH*1Wj`lk(m7;^{Q z`eg52^G6SkYvJg%#famSYEt%n-lHTrroX>BD|=qemzzM%U4;)h7cH8+6EX!g0Up?< zh}!(ofnpe#0l8pCoLs}PpLv^pE@LS+x4e2M`3c{w0!UJbBhGfE0Jw;v=u~*gP`0sj z-I_t#OWzE!hmh)rb?6sAc7mxeEC0u*bV7dr#cKGNno9&6dD*3)PC1MP?fBOMgAifzN}Fg;`Olrb)eLulM=%6Wp& z5SM7}?J*s^!G?iO$vcXOAQ-Oxdp(&NPR|D!c$&q#C#G-<5ILFkKmr^g*^pw+SR$pW zNn~T3zgDVCY5BMvU%jUXsA}{mqch3C*QO}0rG!G@__5-Gds5Qb3u1C7fQ#@_n6MWk z8S$e*H^NbvSjaN)Ljj=x%1l+ucqs zCQx^NkFJ3!{?YGlpBURv$>{69=v{oC_HUar&}yzePWzP!(C$w~)!vBO1d!Z?Duok+ zHdlB>)oweH6C9=QMqlp~OEdn~!u#f=;hvAQIk_a-r0cw#oPPb+QqF=|5Xdb3G0a^i zXq(ZHzH;Hx&vm}4J2<=EExXz zQ@JPt+VJcbP&3t8D$Ra@QdoJSb*9Rs_c?3a-QdtU>A+Fnw^RO5;KM}A9w5`?4xU3x zn-*0vZL{TI)6jlZ6hhvy!p9e$iuX=*t& zchIJZJ?t30Ezt%(F7d;|?3rSEzO+ID$qWW+PGy4uwafMewvjVyGBt_KpOgBSZ!5xU8P#B)c{8cfl zjK98|c5tVr*$Fh)mA%wG(+CaT^~K|fbOGO>sOLzUVaUtA14T2kaE9J)IkC z`jIoP%%#j#!y$Kdf1mf?&=Z@3&`hkS>ow7sVD_idD=nSOjHAq__6BA3aj1oz(2|D4 z@Cc~+k6I0OZ7?}DDsh76+WO07`F>6|{2Wc)BhgGE2q~b1tyTv%4w&3ijJE0amn@#*#`-N03#z$#Ij&Shhe+;ST(}=i26uhrVEpvY5Zma&(v4-$DJqP zO^Jz>HKcEKw2Go;H>S*HGRwueVz)41<~YXu)sPL&gJtni&2kk+^edCB1=?$&dNG_m zmygK-tJ%~k*2sov|4M$KUbA8MCE$L}Q_3-4DDS)Lh~on8(K#aZ3d~3odp1pGO}$ez zDf6bnxB|5)Oh!@ESHT&f=aYFwlL;}KI@u2RXHRLAv3B`!ufztjI^8e~QEKDwBgn`j z46)g&rS6`cM68Q6Ui#+2dSm1rvTv@rV!+C_ogVz^`pVte+|znXrtDh1mKUxP*bO+~ z2uu+b=YI&Ec&90iJgaok)$kHkA65g7!E0zY5|LGnx-_rO!|SexG!~VzqQHmmcL|pDe0D-7wTA=efxtRUd*X@fj8Xs;1IxtTrC~D>)_*%hFTt2gyPA zbJ-%~`*|Wf%%3jj$UX-`f%TsO#c$kYfN?6H@Q2iv1Gg3sIt8090+JNwJfE5Eye&_W z4--u7CKqS+VvxVWls$u3UptIVvkO)S0O(xNyVogOo-|g@45P41f|kO zDlMEjLaOq%^y1jmhO`{t;+#(55#Kti&x{ zJWUl$y|9doV+IyY&dt{W6WXrlnG9%&^+2bNy>$>(8WhZ-;?bh3fD_rZwHM93M!^ORXtTGx_w(qOY z@AvU!l+w8?{yLC`E2IL`s6rXTBEvnM;LyYg6LyzPo~LSgIo zJxKVBi!Ii*^8x+0@p=iQLTuAdZQ9E(L4A`J=a^e;ML-FncO|F(zJ|QbD8McEX?9k_ zZ+0cYj0<3y{=g6ZJ}z~Y$yl>`NOo6-b6a!xmJ{2ga$hTGNL5c&&)}4UsH3*1_|wFP z4nTrNP(}(szem-yJ>TR*V)5cj82ne&>5}YgKtA?QDA^ zY%=Ed7t||op%8`BPv7A9*}{M+h5FydN~nyH<8myS6!|h30mmNa#e4_v_^zR>4xWA} zix!&vF}10qc9lo~y9Zm51~A>F30>>WAsKneoDo?+Y!b51N*=acuIh zb(05Go02UQy`7|^QVfBnN)I~N|{_vHZ>4xBzXX&Kq`FYV;{p3`l@njBZ|L0Q2PLs=5X67lH>(_7|JJ$911tb;1wkWx>jJGAfbuTC9OLdm+s~7`dgEcE!mCe1Ijo7HQ|}%)=O$nZ1u&&W zmP3V=i(&|QU;|PQyr`bdVJd<9lgjR&ZsI79&2pGr+D8#IK$tS>7}kRVy$iImM@QgoUZ zR`4@{mnAnLxF0_*Rs|^5Ha25&fCWjjq2Hgmh}Z(x{3}3Pc}PHr`H}k$cKwa9kzEEk z({~+fMmPbTqDg*`%{5emeY^*`+xC7DN-o{NBn1fw5M(g8Ws2Iz= zxl*(m@%`g|%kWKt`Y#p}0?iE9S!?nwr*8GvVY!9NnSdPh#Cm$axNAgy5UCtlCy4d?q7$1hx$2qghv@7yhg# zP2HcU02*pPl+glxSQ#RU2+VNUPW`V+2soRcr`@#F>TW_9ppN>5LyEV`CFI|g`Iggl za^*$G!zJUm6IU>;7Zr*V5$Ml^Kmibii%QMWkP&-@eN@SBp*xA`5<<*AsW12ZPtlGI0v_~4W0tn!K`LR4KutWXU zk;_$TcPHN@z3^%<2eZ~d>IuE(5lAk7TBxAgLEzi$*EaV0^YjO|U z&!N~+GJ81KKCGtoUGcP3ey$XL$etsYqJd7)zq>GzN$Y1cKnZGc_Pz3Rnd@reV5KlH5^ka`Y~^mT>tPXoyyr3}y!~qi`~wtu*6gJ03AxQLdNK?UDh@io-Im+#R_M>9(-rx7v$2Ff+B8yD3t8AnZFsc5 zR!K)fXimG@XHP#YVvhbFUH+SHRS)5R#MMj%^ur%FH?Sg_!tnYAc~iUqZq z(8*eTu8h!=ffWxxa^OFWCJzsdp2)Ev0YQKnnaMBsVpPt9s~X2{EX_h*06X_^e2;~3 zrHBUNVmJ-b&G&{B>C z!s=9~4fm&_o{%}s=>!$6V-;{dJhRSdBT`lbLckn_Q+C`>vqT#bEkXTe>er?FI0aT8 z1BBQPW}2Vz46ezsioh=+$1x{Bqhr&Ro{F7HjJ>9N4G(u^U0FTZ3YyuXF$z@Q09^;f zB(4tSy;XB_e@N0+yl09KR**SRggh%2(?GdtPXw7uD#Aa-A5P!!x8da02G)dEV7=z= z)%dyY{%!DL_Kz1Nhn<0$A8j2A+{$0bHf6AmX1WTrIJ|ZN8kfcq)hX?-#r5T0%2o4X zA!DKMO&1c^yG^aVXPk^nyym6mRjW0CQ##IkgAbYfA>VlIJq7Jt^vo=#a_?N`+7LMZ z;o{hff1E_KN2g5v$>)lr*;+mGy&v0>HP^+h+E;3Z`3Sls+uMh308Se>xBqf<%tG%s zq==b8sE@t2&*-Y4D(|og_C~_7Dd=o}+rOWZUuuc?vv6bP0+!ugh*pb=kW`k)d^A`}6cnqrl7i1m z4n0Tw6O;F+1*xU?1d7=on0Nydopo~QSjioo;d=?tbF8+V!S}mMJ>iRa)>;sIBmZ2@ z+Mk!z&9xSy4@tJ9l%VAkpS9kbM-B{3T4t|PWl?-iV?k42fO&A0QNSLasEyGvEe_kh z5#WCRYUfi}mu&eni3;33j;&|Vim=RZZ^u7;^wgcHqUJCLS3ukXXz|ig?US$ZxU4To zdDhW5Q1oa+#W7GILVWlgVb(w2w+@@RVxsP-54|=H*z&EdSYOR@ zO|BAgizN%3{v5HjJosaxKwOk9KB3u@dzy) zvLA;K0@M(4A1}@qORzFaXLbI;9@o7WCiSQSQW#x{A>fcO=rMEY&+6@~DLxaL0%HR3 zYes=rF*wHC`5a9~n)C8L8J!PJ_!+pIJ?lRY8W@pqJw9(3E!TfP{80rZsCpDhG4de% z$zqQ_#Hue=ElAm>=zGwJI2oujJ1&q9O-M`di1u!g*NougMaO#Q*`}GlxtKJJe3%f~ z9N{Q1_{3N{e6NEdoB!UXMdW`f!Jkm%>C)Lr=!28MTjOsJMtdzTg!>83yg$(S3d`z0 zwO@61;Mafoc{)Dt_6g1L3+h)lAC}oI)Cp0!^hW&MZ_65uv5Q5&c53G3Ec*a0#p2!+ z5rvmX$A=TTR(47tBLJGjp zlGaHsb);*$SY1?yVNP?;n4bVpxpLqvL$7 z(hlFGBgx}@GlM!Ir#8Kcc65|xe`0?HsQjCmYy0u={SiBGzHAp0=|6m$Jq8-ogyh#9 ziUWkMH@F#=bSyI{(xgF(S9ZXPkV&Q;|D-LUOCRMJZd>UPtsuRQ?Nf&*lJO6Q_^BQg zu>r#sz;&Wt5TpJInl%k zPX-z6VzDli&S-MOt3LBR`!D3&br_@;Tp*teZ98 z{UPVNh-RMI8shOIryX%bU0?yu>fw8)5S+u9IS+@sY;HzO?W7;b!+uMKFYiIfZyRcj zn5X8<-g%GhKQm?2gQOfv8!D~Ozi>{^5$-6hD%h-*Aa1Intka=Uo*2>6Naugrp_d+% zL%fgNBb$=_>U-4)Y&^sV?;)WdHWoV|Kq7_L@bfgH^N|Y_xxxI<>bHHuvs)77COk@+ zk!9=Oskm8^f7{B8%HZy;=FAl9#A<_J+Dt|V{c4g~l7~9Y^ONDI5pvvp7D4te$oXe)$>|iY}8Qn`wX=p$JM+w=#mR|je(0EyH)@+1BBVF z{q+YQ6mkz@)6V6Z<7`MDe|^#}d=giUB|dP?VZ2`&th#CKns^aD9k$+o+gpER=%YvS zG#jE2a&O(lg0z{P`lqWIL$l=g;tJifRxMsmJE=5p1?n{&e)Ha4mo502%B4#=1md)I zLjTZZPyC`8IlJw>0M4;}(k9S!Ejp#&sg$NL^$%rE{C`W>_k|SpV!3A^e|hO5yP%L7 z!w?3}q)h+`1}k{Hs7?Me7}#Z}pmd;koBM=P{kI^Kf(V=(XUU;5jj(W9fpLtspVv_97S? zGuWR0>!I0mUKGb~9oXsczy_)Rp38IkYcw~OC>#XX?u#_s*J#vO;e3IL(tA&bkOH~Q zy>34~v85P4E9np(dtD||L9r=_2mX>6t81Ks*}YTLPxtGo;IcI&+-HsZVk~Mys^fMM zQ0ld_mJ$@FxS7&ny2Gd|24#hD;nrL^}Ks(8LuZC}n<%>d~1 zQfhUs5Rd!wbvWrBq*gKAWhh9H%wO`Vid_EADx=y^C2QO8gO8t7Lhrr_1{kCl&|`=$ zHuJKVb0vxv%nIdaUK3~kBla@;TmECGcn30e9B!1nU)nINvu}9WOnqsghym}X+V{ECk$X~&pRlzHS4jERq?dIW$ zNIn2?m#bWqMDpnBv1Uy5&+GN|abq@bv!{RE5??4%sc43R@Vsp@T7Dj0;?`S?KbktP z35Fp#Z!9J5x{TSB{w}Le=dfmV?yZu=d%7X)4xcBUOv%gJZW6R9h2XXoLc7by3FpI7 zPA2KWw@;8fW(~_|h7+J&8?Q~8O77CVH0<;vaq=Lz)(z3T-YYE2aC*NA$0*%k}lOCkgZB{;fb#4X7~!F8#~#EKe(2Jje58ZI#q2C#(Vf^e;AO z4ANhaa(O7ow|@2un9NKz{-D6~c5##V5*3<8HbO%=;+#D_<9_=jOs&GnNr|&AJxmr} zx6y4;R;GQ};Bnj>+d=mOUA63UXNo7k_#vIrx%D?LiLPPYPk(10hs4JDPlF)>KQ~?8 z+n8pT4KSM#J;mSIFJN9HvF;70=b%wko8lmG4ldV0B8LnZUQg$_SKt`Nw zXJ#7QyE25m_}b1L5!3Ij${I@JxS`5ZWmMZJjB7p*pisa<`$G$N zg6iU@jM*f$NJQ_asqS#UN###}1S7jtXSK<$LU!ntHLpldg92p>=HQoQ$_cA!5)+m+-KODl&+Id9j#C8)KJRFkSj|Bzd*yX>o07k2-ecBs zd=IEyto)g^3|9|5@xmKCM#w%oQIsZe}Q47 z;7zjvSA=s&T?OAuntHw{tJ5sW?_%dUu_#!LQ@3K{V`X87nFc<8)+Mjg%Hg7nDaeWY zo?!k+_IOUm{WXe=RSx&Rcj{^>)h1b&m)Xet&D`v$jUaL}$6=aRmP^nQRg(V?!er;%&78b^zDL=`rngrB>BcD&)adGja-< zKfVec54Zr-wc8Ry)FO5LXRC}ll%sLY9;jrMx@1wN-k?w5ZG29uY~k{7AIy#;zDxJq zY_kse1LNL=WJPC$hP@#rqz&u01zQYwq3Ap*6KfVVngdrzpd zMs7$5e=G0j=Lc4qWE!dd*p81mYgpY2I#Fpw=r~&j77puvuLJOz>qX15cdOx{4GMNu z`PW!?DtP{M-Ij=LeBv{Eyrb^0?1hPIF|;vZRvU_xK7?s}9{AfdO4U?uKbBqJIrVBm zcvtTh>OzO2d;}B)tUTJq2u#8 zZu8n$-OI=<%=4=C(!q_yr|NK9xXxPcz`zDYg3|B(pQ#$yh20wAZu;TWmq@Et-zls8 zgZ65gzJ19{@S^Kp^UJPUdO}X#)s#szWl{>0~)ff(yblyjZgChY8d0d zA7D8bB*FXzv3zeHfo@aFItg;!bc1*`M^9=04>ikPX_>BFMXK$C%@@LCmuve4{Vt#L zCZTY*)UgYnct)x#L$KJ4YNa8h13uFxQq)1>q(v-y*3;(6mXJ}IbzcZen($5;YD%cR z%#19QHCq?u43%dtdQxny+lGD_^`wC(LfH$X$F3&dXnXg$Dyr-%-&#jKz3^5vRD7=i zLC&`)S`HyUmDTh5hArT#G1PV_os{u_5U8K>a`>iH?lk*0#qCjDF_8DDaE40DFBEv^ zY0XC8o&#&3y_P>^?zU8VMqy(%=;-`yX`Yv-@fy6Oz4P!T8EgVI-l>Z+)Y7<7fVf(Z zT-h~0c!QwWM1K>>K5r4vW+O=}q0cfm)PX%_OgDzw^8KX?#cQNbvsUl`p(T4gNP`5M239+V7H)rqa;P%e*y->ZZwGQaRrz4@zUAe%eQxedqr=tcjn zDFv<%c&cp06)(9{{sP{EZ{_KsebW|3NXah6 z8P!R8vZ{4SooxDzl4A1qK9jAHFv}Xyj5lMqF>dPDcg<&*Bn=De7GOM)&d*^E5Oj6b z*bHo&Xc}shj0;vS(^tkxq;X?55u3H{`u~OVZ?)Ry*5#arypcm3+k>kTFFtz!H+J^d zI_vC;n__uVqG*?o<3^0;8U*?CWP4rBrpHlqh(vjziXiBB3~2@{Pk{85c?HDiELp6! z6|R+h7@d{y%XiP4FWGznh?UayPxSjU`^hK3PTx~s9!_=gvjGRX9nM?(;MP_F#ti4w zi+lah-fG43^cztRvVco9!&lSwASR6)>Q5{Vpw%e1o;3q!H)#y7u7+&duw1ugFOU(7 z#GdMO5LTbLvt~DLDpDt6N)WcpLv1IAJJu7cI-=@X=x+#%$Q_-FLF3}^v zJuJ_|zb5WkfKS8#~g85({svI(o#RHGmtCs8U=_B+iej77v?>wdxaXv?W?wtLtf5@Eu zqRopl)`tg<6~6w>XtE`oeDEi}`=7J)4OJysW^A-?*1u66byntf5|bA1eqbqUfk2Y& zBZ{8LL-`=KcZe}R;orWPaC{vT5^1n{Da?3PVp!v98t(=75;;Er=7V+`Cn4l+aF3b> zn>o~qV!+6z-^&)ZYri(hKMaORy!v|$rNCVnD->x8|CUVCANiN!`jub*fyyS!?2 zRd)SFAyr!F!{~ummR0~dRN~~oyL1dD7Lis=7k0C_&nU0qoz$kk*_ucCF;I$zNz^C>>;6X%b--UG(-jvzj(Xy-Z6=^ z#H})+Y#%h;y;6acJ`bkBq@qFv~W$@3LzX4y~!^iEXj>Hsn|B}I^X!^j@=nW ze&zWl;D3t(3M6Xka;?PFL?3~qma%;z&K|qjmNca=|BZNGaDDg%FXp80j*gzo{n-0~ zNiE?>t73^S*H1mkkIJLj_NZ2oQcnmFFhCZ_sju~gXzyraUt8Mzc%dN||H{3h{d>X4 zrT0WTduSD@vi~c$gnpaslH}>jNy2CJ@;AfAr*&nEYqrt`f?w+1VX=8pfp1>wO)RGB z-tx}ANAetP^!r18^U>#8Z9n=QJsC*gBkQcT=AGcEt=CT-?y?7WJ`B7kiMYGwx-D+4 z&8}ykwN#AQ^vDmT$su#*p9{CLewtl+^%&F~PBwJ26CA@yN%~18Jbx$8?x{q}gAGTC zP3uLxnn}O9)vY@6VUXX|2wpj%(s!MVOG(;7yzyr{82ts&*Ps1h#@<^APfN~qxHigl zTWO!&@c$nD$%1@vnSy*1BmQp8F+bD&L6sJ)On$6q?>C%`m<;mvTLWbknGi&j<2}&@>!P=-XZ7 z$l4-!pZ-PI8yU8#I!oQqL7AeCMsS*Q{rEfM!(>;5wql&G?R3B>$|%>y!RKj?cn?aJ z#dAevj<)`~@2Kmn2tbr@6w}82!2~qodvg|q{Tck|#=g&-9#h7a-LM?{>f9j=3+5Qa zWligFc6q+CCDHqXrESgMr#JhXD8%bc9z64_ltAx+->Y~!?6a5-g<*t zn@6#whklIw0J0>zk;LGvNVyigHLbdu*=Z+6VaFa=(GitQ(IlpHlJlv&=Doc?q@(Vt zkNM!d>uGP<_9C%k7n>L&WzVKPQpG8z+J9EboQC;?XtV`2tJR6*TA<$D%+#EFK%;ey zeWUBn>`bpJ=^SzI5ZUjO+x~pgO$cmnx|wv0O$&rw+TH&4dQ0KDw#ug1%e`y}Mo%4htWuG1coxtpD zwFs`)egmZpgGaY1<}?D4NRypL(MxvDABFYFxiK^fm&zuE?VjG;RRn7@xS#QHo5V}c z*&k$n7`P<6Uf-JF0w+X+i|Q|Up4x$AXZhuD8inTM-p!qnLfooHXy=cWiOY@-Cx?;ieaAqSLXRzctOx}1TlH+DGNrj4okrI zu((`3=nhGeyn#N6Okny+9$Z8E_5gK;O@!W~<>iEvuK@xxwY1sOCX`OF8spU`sLQi6 zRr5%2`o-tHosTAg>~7CPeXD;a8lkeQegqI_54sKwv`O6{H|i9C@{QlB`$Uh+G}4o? zfOkc}Tv1>5y^x>|XC2Wxvx2a=FKfeY=?yoNN^tiip3Dm!$H#+BlV|1$Cy1^*+k@Bm znRSM{{vf#f!$)bDvioH%z`=U~ly@tf6gE7}$rBqoKh~KTVJ~vw{*rRKsKHTCvx;Y2K#w>Z?-jCwx7eM(6he$s~cTpDAFt}zT=sKsh#D)5o{5t(H5AjD+ z&fIX>JuAyNDe1J48H;|4W)B_+*-MlBug8ni?xp(tmE4_0DfYqXan}>=ynyAoNxGoC z^Oz>u>wgP3n?nJRR2rs`FCr{Q_UaI>&HRw-D_%$fUbz_fVjInbD8I4bHFG@;ca3Vc zIMpmXzd^W#+H!|;rv}{bPuoupWIWbsbj5cVhImyDHD`1Uf515Rh{N#d2O{_|`}!Ng zxAYtH_$H+(ffTgLo~RXX$egYoCKmf&wPBd3mY-+MjaLfXR18Cf9WHtYr(W$>n4V9> zmPdGUH$whaLW1X9@lw0T5i?BMO}$sg%I>&~Tb2gu5d!t)_Q5`pOhzfYK4qj-bl6}O zl-DrBs(+&?c`T3z9sspS5$5;-Q|m(li_lrwI<3F|?6SYucH&t+i+HvWO8!>gKRFF) zM5voMsoU)PeT>#v>RRY@RW=)fKeaHq+}#$;H}^@Fv7)898?oJTmLs6dVcDMta3xcG z$Z@`93!QE+;~{v?Ey^FamVr&<9gIu1aaOb&;fjk@FrLI@*AlNYXZx!A&NJHFjL!VI z@-rHOScaiJCWkG4Po8$%;44Q#x_tK>9Bd6r`4L?tS9kt-@FOd_Pw7|8@~-1E6Qjdx zl_0rCWI$mbzP3b4Qm~Q~DJ@p{<45W+VNKjVTg*NDi@2H&5op-?wUv}u=@STM9jF76 zhrMqiwJDKK{K^b^gsGdhQfbykIQEBgJyA2OaNTGh0?n|Aqdep35@ErK(ZTt{)zt7{e;w#3J zhXa;(KI~{$YZECr)*|Ii#A`^im8r<248Z?PJYgN47JVX(H* z)&Y{jo1u*rYw@TUOhTY9+a7rWwc5vutYyDs`DCSML_}9_tLvp&u3^@wiCBkifDvfa z_f>5*n0(N8!Q{+vv8TNAA zd8b}d-5U}ZN+uoc;}zjQ9}A=Z8BnI>XBakk1hAhDkb{U(+$4Snv9Q`-oQ3E?#}MZQ zo2jbcOJ}~{+)vL|in{q>K@0~zN!QXMfsvB{zoMoQj!SJ+Cz?Vs0wGRyC}{7Lelet0 zh)wSO{87ThHvv+e58SRG|5I&Y;fRzq{$yt0NgpzWELYa?K>DFzy+Gf=K64M3{3TEE zHxF$V=fK%Nh~!me*@@tvV!|Q0q@F&hlNO+_71GMo_x9P?!*|{c_n@J46A74LNv6js z8#j#@eD-=>jTeJFL`$zuHG8;D{Q8s_V%@2*?#9OZ*f&*%>nxzF679-3{`es@rrpKQ>t@RKTnfJ05VG}xeLfn6LIG7V{sIRgb0og9S!QBD`WyXeF3cF@O ze9g1Go4kv)ne`x-h1$EwXH|oXgvc|MwlSm}U0%ci7XKzuZBqDFK8FK!UgU}?F-=Tp zCHviBbHj+tUMKBPSkf!M0nm3kpF{vm+wXG_+%#qy#kM2;SXg$~{r4nI9^lqodXLE- zJ8c<=38w6lJH)MxAG#|{1vE*w1EsLE6!%{+53vXblt9x?EZR0q5tyc%l@|lt0?K^~ zhU(-%o}_rqK|+nNYKh zRNeBz^z&jZS-m&~K>ic+W|RKxF-#<$8_EhqE*)I z>d{4%9*ZN3d^SM-EI9+#w353^G15`Hjw2h4j$E;#%6PB+@OuqZ@k^9GZB4K-{`rf| zL1)>-25Zh3l5;;??l2K+PFU!$MNbj76_XOFV-edC@3@8f8?$OCDTXGZyhuWVh!t+d zky!$Ot&2{oc)Qv3DBSayl9W@8RwE#XFnf}^fp5l;Jqb)wM6yx$sM;|c`QU>g5U}M> zEU=)FMesTc+uku0`cV#HQe9GU>37xc=0YHrC`#I9A$-R-tqJ>`A#1?}^fphhiG9qENSB ztJ3Q0t=_kCbJu7Yl|j!50`j~^%BnAaj?T!cDfCjF&)%7FS&b`SYp53@)C)@+%o{)d zlN0B&ELT~VI>09!DSN4i1W5LWHN>5GbQg*nQ{a`)-lQ1x$?YA-aH2XE4!=NcloZ%= zJ9~8cRI+!8qsSXZifdnu%w499yl`C`3i0{dlM1hM`bDO?x%3!l-u^M5_IU+bQ(;=B z@FR8QR*2k$2+B=SEuw2Pg88I+sdAFZieLNU_c`%$H>QMj|z ziwh$4x#{`_&gn}ZCvnxRnC*0mv`u`CG*Eef&UDFU>JR7Tk}(*6$ve=$;B)XTbVpyc~a1R;iS&`@;97;BBj1s0Ei4() zyrv<4L!e~G+OoJ+VJVFZ; zm>95BU`xpu3_``$W&jFHg!}pKF^TK#9xt=b-~R~9Wx%_L`RSNgB$bDXCgyMR)0Tm3cc{$QY(gqG$pJ8vb~>S1gG7ixTfL{G*#ml-hHSgOGz#apbKvXp;Lq@|<{GH5NF?5iTir@qHGt)HLE20*9_&VX9^pKs8R5s`!@Xx=i97w+i=6~d#Bmr= z6Lp#Iy9nang_Za8$Pm9P(-_S{1$pM-1I* zbYrN{$faA{6b{9_cq0vHECSae2r%a+3C!S|C_gSJxN#s3!HFtwkA6Z zR@qM(TBU1)){7v#KGaE0aGN-Dz~%fvuvY+%zfbZDZt@n%BfCQHI-2CA0`^PCdb56YM#o*yOzl&asK)^?!Jtu8o^_iAhK64*q5t%sDTQy@u^%~512ar%(r#bo^CT&Xd6d+=oO6oA;U`Q5v*_O zKknLiqvMXLjF9z1aag`;d6nfWi+natbu<^kJOortmkgs{$lV5oJ(D#>=D=7exDPTHy80)Mt z$KJ@^l$4Vc$%|K-78U226!T(B#BRBN9&mR;3}1T5bCa}7$lNYZ>Qu|h5+BfT8{;_5%VLE&_t44%StqNA0 zDu{N^;cWZo@5*&w>mlUwrCT10G#!Umu>R39u$0njD4dpH0hJaCb#))7 z{50w>arpYz%3!t;$E;_F^R{{^|3KAh>ZjPn4uUn=tvTRf;C;4T&0o#;f%})<=ON{g z%){qyEH1-!x4-nwq8c4soh~3kEWWkEkP?EOc}f`o^)E67jfiAuEBDcdX~=G|>j7Ey z9*rGsZmVZ!W~Gmxj{TxVy^+Q1u_9l06?3HYYJH?1%J&Uw|AU8pc}K+$pup>H?qyS; z>Gfwy|HiFH-T21W=s)%C^>(|%+=WpXTM|0If;hWy$mcrObJYAu&~XJ; zzI_Z#vIzfijrgY3f+_kzewIkkAm}-^Ks8(xvwayGRG>grA=v(<95zSY7F_YEEO0Jo z1?Kx^E9&jefyFe-SK-LskQ?aA!9p_si6HXP2w%?~O2En@THfz^HgESUiJ&4Bc4BK1 zE&C9p>GdxTdOylYRmzs*NG}5&|38}%r{I)(@-|C}1*zGt{Jb|wa z=78W$QLB89K1)nos;a!FosP}QwBZmO6CQ6K`aZ)(>|d$1aJzOT2YCLvMxY5}S`uhY zZ;FjNwC`&rg(XBX4;>N)IlWFIN6F3tt3k%Flsr%D9_O*A^}rS{OCh=I94~16k9K61 z(CxyRbdNfETTP?7f^8nZt(X^bSJD!tvL*c)%ZO;Kk6#|60nbks9b;&oP-3pdgpS%Z zj<3K40bz*E5m0%p&HVoyk|Gn}ArZKR^Lc`9^J?JQto#v#dURCCl|^cFGKFYN1{!kc zw2o5_%TT~FyR}~ieV!^V`BmJ=!1vaKEQo)OLS#cgnR*Ga$7RyiDjb@bxP(K{Hi6GQ z^Tt06hUC2PEyMn(ldMRvN#xk_8uCq5cFuWaNv4d{qxO8mZj`c|R`*Om;RokDVFt&* zf12{Fm6j3$?WtJtd)m*kK$!mUm>vfC$s|OlDcV-h=*4Kh>N6yCDpbI`BfJd|M^@mb zBb(63*`Ns@=9Cc~^Y(I&yf;Am@9ub#qxzH+1(3(_xl)Q)s5L_G+$!7pVtl91%dFvw zq%=2vD1fVfF8cH#dxSzRpi1!iUIABcK+gYyF}(;6#p6j11Ct#<64brnip>>$!{akz z6pU40$*|AYYx7gvM|zWZ-8$WmpgiM`v5l!fRRIKX3~$C>*gKu&>UHU#B|*QNzJJ=O zo5O(za97mxTKVM<+yiC)Gh3Pt&{Z38c=X7l_Vj*St`JL4e-dj2g*RGObg!xJt>Mov~XQscf$ zc__NF0DPXfCH&hG3@pG@vP=|hd)r!VZ7kT?zBZ@7?Mu5vf4y|dj$heRuTS=x2o2RR z5%dKnM9=E`2GYTf-sLRa~!f^xCA!o$<=+sHyh~?>A zqc>>5L&IuP(0%Kr2mZN2^!^y4uev;w5K!*TBYjJF#X|avv+N(QwQD0o^r{rSAZ&Yc zT+2I#IJ8&px~#p zBYy(wKheL{bnNkp2hZi1S?Ac~&9CsxP|uei)>hqa@UY2ibdrxxSmy3a4714kUtlN9 z_M1tkkSFc41Ky~XMj!C-%8*WMLSl6pstc>%c!10S4@%4)?xOVVp(cCZRDS5QMRi)MR_A*E_|Cwf%rzWXX2$^Gm%OxzQrEsMo zX40GU<@mkr_UL8D%JwASY#B}&l7C+hH-B}O&C~UA%Y*uGWvp>p0Y>-5o5T^CtwkW}c?MtU&0{rt@y2?GMUZCg)wV^^y>=n*Lv7fXEjw*e{G?lg7QM(yo zWaG$4OGUM@Pwt_QjOZhcc>_-NZaPRIekKNsO5KFfer)^o8c<})_ z8E>;T=)m9J9-THY%2Nbn9dH*k26FL4JfEYMJu((v+PRXU@KN+A@6e*s>6sTRXVXri zwwXGq*~w;xWj=u3upi42Jm=l$)xOmh(0J8q>V4U7cSvY?MTV8)i-^j`0r0aXsbNX(PuOe4A5(DW zR)<9&m~)(BT+#s#5|I>nCqoW2ocWb~jijPnEPi{oFz|4m84_9~7-}k4Z$g{|H`Hwu z1RgGMz5}1jywNE32sK-|1OK%7_E~CooXis*z*M?n8i#2gHMyE-{CK2TagrU#w;^@G z!Q*F+<}*m$4?L9PNfA!>ce?)ltVN*6k?_Vz`sl%&7$pM{dj9W{y=k-0^GXN_ z7fdmp!IhB1cLuF*tpMa_(D0#U?QfhI#YH~7Lwe#la7IlCg`TW(uf z!&iPH9rQ{c#u@$o7fS$gcMi)#S?a2@1n9_eQ8O^IzFVsqQ{zJB+K~eW*p`6?3xG{; zwJc_5Q;5imrx|yi+w;vQ#njuZ$~sPNS}U02@Ef zkzvAw22IR@-|Mjvk-mi_S?&Kt3>~uTdgbN^94ZP+?ba`>YEg_8-KP$smT>w>;a>Ic z5Lt|*R9bh{)fimU3HMA27Qipx8;Bnk(Ia(W;HC%*S5;eQWjNg#a%rAMXy(WB?-~>u z6g?one+Eo3*cpi>T)WE_4wd}L0{P;9x(fvxdr$g$@8%9V7g3u!(JxbL_-n+>s(-O9 zrHBQzeG4$b8cwlm$L-Q6I@WP3XWuIFFvQ8~iC{@tbHdOdu!!J1mwf-{pQ3Y7Slr_s z{wad}7h4l>8i1pSWqLb=)|u|h$w{$k{rFkf_L}FZinAn&HzS#L zUk_xI_)36Q>wvUW}SK*%+3|16)|AznF)^vw!EDZgA@s-R-P8 zxz-hOucGe>;cBS{U`gE`oWNgd1)66O8S5Sm5u(cnz=2(Uv}<{k-GYmbC)T}W z`~!%fom;XInfxsVBxp_tYD-JGoh_ruTmcY|19H6j$Zz`u$x{6$1oWn%O&a9ba^}FM z%BH_)m!w8(wt+$Hr-2KX0sRr6sx>oT5kXNKr?1V@-g6;Ueh^#Qki3NS zJ2I=z)C)H!#M@E@K|HA;h0_n{*O(mnoe;XBH5%UXd)-}h-^@`lsN*6*2YKcj6a`Bz!?#o4LM-%KV@FLv^qr`0We(n zC;Q{t$=^vmY{^BQpJ)omzFD47@t0mfY4{Zv@HTtisDdoqCTiqf<77mo{aC)uOM=}VIDP&`Ft%@spo{)kcmbL|=G`NBL%xfB0s~+Mya6Y+ z&M#e4`{*+l;yIm(AKHsa^@LCKao|ivdg!!qdGq~=Lou(!T(Kz%I`DABhQ_R{xGyws zr2%v($P_MqLtr%qnGvBgz~hC8TxP1qmu-|4k%uG}T3w0f?VDsA0=7y9$g0&h65r)= zfVZm4G{d(;=RN-7gGY)PVABDU5$p*MejZZ*bd_#-%ci+lj_QcE)*_FO&?1 ztDQ@oKc20IGo{s!d{8>^WsA@3%>lDw)4jt+v} zMnUGs=>Vq4!AcXor72AQwSho6>fEDglkBYU%ghROsnFwJ`d*yF`&tBQp5g=^Xt|HD zG^qFh8-O^3T|R|I>W>6}O}3DHqh53~C3d@*I6-}(B|-9X$=cf~C!yyO*c#AIPFz_6(GJa;~iw` z54D?yn1Kvg)NrhM%1?~Sp=IFYs(jr3d@T^EXOr(Z(NM(GP(^<=hZK?Wy22cMl(%1Yp2SqE8gbYA z(4REW4&$G3Dn7%|JNE#$HoTmwL0Vv8tF(^^$0hYutUsPAjc>Bjkyz(+j<>n(TuMuM z`8iL4jYVg-M1+ml1u|jr8NwA=$QZlKW)|xgG71|u>l7a2)1io0g_q=5QmE=%B)|XB zYljnW^Ohyh7(4a($6)ciq7O}ABB+}rEs^X^W`xEXTQ}Kg$$=^6b5-w|rzSwI3YTT^Pr)<$w+7@ewWqYv9j$)!&Li zQmP;1t?lS}rd7+soThpy?3W@uo0C5Oj#hQ6hP8t5Di2cuU|d6wyCYx~RP# zPNwGvUMykQX~QXz=9vS{Ar_{J?ixRyxmn2K$1!S-ZQVX+P}tch=7^0_>>FlB6`ogi z&oiY+TD^Bq}tE-8O?nd^g%+^Z1EdcZS_aU*Ei49hdgRK&!{*FA^jX^u=+<@qP7f@{>W0ec23a_OUYwjRqfaW zn-`f__cSeHCo@%QtgfA5MUoN7QrJMZZ_dZBJzwlxK;r-TVA+R1e}Niirzr z`ykYzc6^!^w-;DcYSs?`NZ`cMF-(IV>?45>$X7F`40c|-JnxC;bxKL_%U>wtc>Li* zn2#b!u9|BYr}XG+IYu|7Mp{h0Mb%&MNS)YOexK~BhZ1rU!ewGgpHOF%R8(dwej08% z+uIyJr8tx@G7iN?;?S<<&bk;Y=J3eUyb3CQmP=m8>rkk3w6rYT;MY^xbdMt!Y&tC@ ztCS9MZj!}oA`T19fvoh?IbJLR)t$Es1v8v~2a_RRyApp@Tz>s&F=4enS^AB>cZ=kH zyM#f-G2}OWa!EK0sp6d{y^T<^LpN^k?bx?lxkoOL-c4fv z+wHh`#J*nTjB_=}<9GU~{I~819X(F=6`1zrF0`T|djYV7EE{=~MJB zVl_$(x%-{$^>SwY95>-Q94dmZXx;cFXv5<*vR6TdN++V=NL)8NC(Ez= zLkImWFRVViMwQ&nI}f1IQFqlp*|dzTJhFbs8N|Krsw-=~Ksj{#M?#*>#bRXHI*k?B1U+v5l5ZT(Hd9%CZww!%6n51H{GBOMR|} zQ&?r;6&;S5#P&+`J7?$c=3C4(KOtzY%e@OO zsYpDAb}OW0SZd8*PW3w#hDED;32|EJuSSF0DQ8Rx zQp3)ZzmEcQh!dZ&lP^nelr-JlA-p{#1EDcO)4*ccrXVS;t3RPDJdC9|R7=(^UK8N) zEEvv(ZGw|{K^e`$QN;>2K`M4%>zfy zWQ*r?VUwaWY zf4bZn*7@seJyCgu`@miTt+&t2BJBx^>oil217D8R(d#EgrDs%Ot9&KUnB zGu?{LdL|XxSn%PgLY!lAIe+}SVdteEAGbX$cksp78WSsEoi*#vO8T4Lm$Jt(tW?b0 zqKvaCwbiA%RFRfUa+X+pH!QMrXR*hl>J9Us#3L&k^2ihfr1}-*BcV)=Oin>*IV{I1)5>t?PY>vPEPg|j{B^U25Pr@z~(IbjN+x= zVykTReX(Sf4;!Uhr=cDq-wSAs>hAN2;_sVFlp7Id=#*z-^@sS=$>LDv(W&!5@ws)* z*C0{cT7lM0=yexpQE0StB92K6pQV*GZIEbs|~4!Il}bjqshhpSxLq$d$c<93O#7mZz^qIRC z;Iwhex?~(F<-|EyZ*yKewJP@1If$yEB35ndD59kj!}c|A{BfBXnXD%E(RBlJxVJ0~ z$9af{u|yGfy!iQQWy+b|RKOYM{Vw^}Oxh`zOspa%wroh&VG&bBbHZp`gbmGr3esdF z>ON}C@^wQO)z`w*o|&eD7Jb*W{n4F)KjfB6vhdx0I)Ec(O!sjSx7oRPJ-?NkjqZOh zwWP`PyT?O|*LH&xQhMbA=|T$pcuU%74K}nbT~k`JoEqiiA>}!5*l^0!wSrmz9K?kr zi7*Fe6mon2#3%iDmsMeE;LZJe1bHtE3Gw0fL$Zzhmw0tH5Y9+IPK4#{hZM7+NK5~Q z3Zb9P9oW4{K`f5dn@ANp2%`MmZlJk-MI48sXOC$*=uw7lZeO}7$(8|;&5i_sN7;QgT9Rsn@A+f{g)x(_KvqY`iZcq7a?!L`WBb zT=h!i0snJ$4GQo?BAxeMQcdNPo`tLitLOpw^P5TGy<8$cTGztFP8K%UkSY%$h!&&4 zBm0BXIA@(vFl`Hu)Usk+~p#Qq(TAEVX)@sBixvNjaGOk)Su{0oHs_nL&e3-&j} zU#;g2@u()@YXm8#`<#WeNE|tUCu5zlIUee_-oLjrFdJX9`Fq$rqk5vLN!x)#P!l3x zBL^0dUO^WQTO!qajFfWCN2ww{Q34)|ZRimM^sSC1AAg5L+fOZG4X6Yzgfegxw39yy@t54f zEc5;Q>O}%Zi1@EuL8VJDjcnc`O1{sRuqNwU*Z9wpY>s6uGpo7w3G>nsnwl)cZ9Qf0hChw|1@ z4qem5b}eF+8s9N=Aqy(Px1Jvh6SF3@S9$n`t`rAVVjEQQ$U`~LCUla9(|$h7kF*iW zJR}04Q9r6#DQ^xwstCmHN$x0JWycp{!?q3>W#YM2Y70fQal&pgks{WclSPb12ex`_ zI4S~|wNuER(D6acCWB*E6D4O?a45hO_*H#UZ{k^T`~K{?BfIYZ!B;Ri7wIdfpC zkFIQG92ygFpD8HQd2cYkc`(Hamjwj(q0V;GdqE=vXkSp1k zAHk%jiYIQfsX+Silry$LJPtQHoR;N==zjNeB=9ew*@Ih}t^j4sK54e`1?SV}8J6P;6%ssX@J*ORLhmGdM#KPz6b>Oqs(40OsE@`&6kuWjiw4g{g4w6();`62 zSD@H8q9NALy+u^o{cspXuCZ(gmoWLohbxpaQAP8R*sT4N&!Ep_Iv0nP zzJhkb0=V(F3r*g%*$BHA%(L)#&QhlTt$GIid=tfMl@(5sHm~!?dRcZYSbNh9kTBt3 zPE*zE7pY8X7J(V`Q?NcL9n;IVNg5eC$HrtWsrJeO_YNYYnPn%=OkgJS?hb?!nr!bmgVhO4;iJVxqA2(+$wpdb-7zjlI#+8LQ6wNwTT z3v*!oZz^VSS@om4OamDdLMb_BpSnl{Z-lf?hLIY<(*f@Q;%bSQU(b&-fzQvfVNV-r zSdanrLsW~@v4R<$*W+Sg4yGBr6`~QtjbtE2;bmS!95<3JhFHyo9j*?kRN*3I6TZv7 z`6AODji;~6OCXQ&8dHCMC%)Zosfq)9SDG64%zp!aEHnf%^zM=c>NL}P7om*}z7cyt z4QduB>LZnt$_|++{hJK;-G5}~1AnI70WK6ZN+rBSUGs9-M}UuKE|!K4TbobhAp8n~ z!eRch^`+ehl7i$@H8p$iFb#*V1*KPZG<%RMURy`UatF`PdP_Nq(?_%gJH~Viatsbz*=kpnb&skuPHz>zrxr;zTfH(4cEBL*4lz!cmb-jdi zJ^m5Z#5bF87x)Gw>S{=Bc*BeLoZq?V$dpM|RzSs4g@W2)P!`X~gns4TZ#FB3SPicN z{#~P2+#O3_A0lah2SA^M;a(~P1czeX(NJcZ!MSA`ZU6zv=?*{R0RhlLz+H5I}W4(7Gy|?u@nR~Yut~!(muL;8;mt+-DW9_ z945ygsyE-9Q7;f=~bs0FcinA^h--*X`y z=^FHj!7l4c4Gz7KG_rMSexCz|JP2Bycz8HQr*-mL@v>PM=B9)sGNE6U*&{~b8Rc9z z3c?!+O`lvxQPy2wZl|Y7d%q@TlIBWDN%_5fjNqg0{Q5MZqT%YWINf_O>d_W%ELmff zkrVdL2BTOQFO~tdVLRmXw@u{?`?mMCC%SIiyEs+S{e_6AsG@?ItLyQfz?)QC=Lfkm zQkUZ$(wbGwHH1v4^S$;j687=oP`cb1Va)@7ZK}eX#|yn;KiXfU?5Bv@p-%Ug(bLsV zd(Ag_J15F4(9MB2L65^lHm1`MuQiSIWC)6*rk5?$+W5CgmvI(ud?IX#vLqea`RzN{ z3oER{6trS2V-_Jv(8g=sfQ9&9u#vOSB?Qg`APM6R8H1$&2IQb@=qc_J^%4}geW&RL^+U5~?y`M)d`rT# z;h@v>D#Qus9;P9r_8ru$FZGjz#r+or)Z4SdUfR5eFadB@52k*!cq_hJj~8sZ>EeWa z0I>*wNVJo)=NLe9 znDmTlY;~n4AAda_)IN;&34Uxrm4ST{3AE?i&VWfO*`FY4i`#-6{k4WY50pa%;Cfg4 zu8I7!c-rz|q95^Nsj3YKabR31j*DI@w|(Dneq20R`7kMh$250%YkIW0vrq6o-m-Z7Yb72@&fO*4JEj5pI*wQ{R@Xu;|$@P+m`q< zOQMW0r1_U6bwnEJK$|4XB35jIVjb9#Om9hk)n*MzO&X5mYMo}0t$xx>ww{rCtfAD| z4!0}of*I^G4D{S*4ouVth=0Qvz584V50vD%`Ov$qscf+iVexnAn+~y9GLppYO1iM5 z00Lz4vAFBFRW%twIM}d-*fOw6K9N0nnsmb*G^A9jq$UooGGGRu2Ov!Ye*g9&M1aPy z&|W;2Bi;b@E&BfR`~6_AMb&j&)CX>PO#FV}jl!yS}4x~n5 z>IVXA*?J1I`_hcc*L1f5;e#Xj;U)XeUfH&R;edpUO$~ZPBHzV13D*R$L9qXOge4hQ z!sV<4=pXrxeiGoBEI<6)X9ywy3C^kx&YFCzj}uDSLZ1c zf}!v-js6lO;=Ct=e?v*fK^+_B5`3EnaM&fA0>hUrUVs%0Vm3gqxJ`E&b zjNny{--J`LJa9Y;e@C3o2M->UmX^N2Ln-pmV7gsHv+-DN3v(QMNa^V4BsB?SfQHq0 zECJD4voh5^S--%cGnh4qzv{VW1P#2wcUrGo^Avw2>o2tc|H6EdnYzS6115v{LHX#M zqqwLDwYIiqb!Cn~-1zV3tA38sLV8JxNx+9N$8m_O_i>>@dG?Kg<6=H|d_UB~4>T(O z_k;MW$70b$(((-9~CW~RRJBejytRe}NZd~w{I6n0-qvRLfDzUa?w zxSVS6UcOlV0j!3ZmZdZJy4wEl`&21UP21@zmV$x;0mcY~g~cNSuU$p=jgpQ<^7Iph z%w6jL&T{ZA_%6+3?S8c*`XhL-{Rvp1CL`tqUc>sUkz$|2>PL+3i&v%nO1P*59(@x< z(ApeKn2hYS$3lAO&6$oDa5szrK+paE=f8V5P(!QbJGm>{|E5Ihm?yxa-}=4%zoyBI z#Wcyse1&n+|DXTf{(MFVh2xEAlhlQ>qMSk*3(P8Q?_lm zbP;!$53she=`HLjl641rSlQ10x=+Px5SyFs^SYw45&=dqIhhR7^u)|eT$fq%BCs}Q zATGn}hh|n*PchS})fe|T`1b3x*DhYywp#HMqZB8gHKjE*HT_x>IeYb8{!Ox&^B&K* zrvKV$zPUGU8qtOBPWU>sstgvKPSmy&bmP7SmJnlr{YbArjZiZ8iMILr^Q{=q?K-Vz z>C)W6Buw##ht44A`*?OKh{e_N*?yi`7=;1t#y;gFyPObVq3XE@qU$6GLl=uOL ziHX=GjmoLG@87w}+)wvrOO9M5_dr%E_Ksi>$hM{Z2jWe%-&o}JYc78Z84w+8`h zbd8S2d+mlA#sXi|)zt;T;yleq3h%tbVevOeAiZki-t|LFmwP%oIzg(S%7)8L$Lq`E z?sbD>31Hv^+scPiXimSS_ukVw!on3dsnb!3a>5IQ4-L-RW!d3!85)%oM zXDiuzHyd_tI_}OZ(h%YpY}u&fYJmS>em)H}Jh|b1F!%_)*cJ18^_}^1o~851L!$pi z#Lrm$S#mOQr=>7@F?(5$x-`I#X~LCCfBw7+@GRc&3T+r~HC6=P8cw=Py?ZDKc=qH^ ztG(`qi*Co&-*+b_C!+@~?=0-PQO<7lBnh&zmIZJCYy+8!H2*7j3#cxQUeZk+*h_H{ zVdWTay-4Nrmue9e_kfdGoTOW;NH5CpqRlWi`%%P`%Bjyfaavkh=s!*VW%e!;p%4IV z7_8$g7+deXdRRM)yW)4-XHMUV&#ndyu~M z5&s*-mmY4GGER%)r=YZyFWV=XN!V~dbFN(5i@O@ciOj}auTAm81d zO0&_uRHywI8G?y1YirxCv$Helr%AkE2MP?P(2Z3hTwN3JKN=17-f}U+msT*S;FH;H zB?mDwyyc!fsGR0DkMBNKJ1cB;43ZS+nd;PG)L>3xMxxNk&%w3`2U*7PVB7&j-q<0e zF4}D#1cd-K;o{!Y1Tiiw95msb{n16jG+u*WV&~Vi!i*8<`L@t=uUNr?J+Et0Pi9Z% zk4-=LuX~d@)y;<#i{34EJ{R{|R3^opSbsLhI##3~)6J`IGLNN6DJl-@BTU_=E7#QS zs}x?xHNgymzuB?UYRB375HW?-|MuhWq~Qex`izm#IzE*HEg&Mx>m$-Sf0( zxpEuspPyMUaZL5x4jG3{z@qx=`T~WkML24$so{@4(GzVUJKq8P0!Xg?3hU)kdMYm3 zOH6Dt_|fdGG{4e_FB~CKky4}+v)cj)9KGU+c8nJ8$s#+FHIfgILv$WAC78hxi>Va!N!iV<%%sGv8Y?m1I|Zkvg^G0--x< zo7%BaHs6bjd8gfY8{R!G(yv|m89wp%9e_=7`#(r}83*uKq$gVGa6gn_`R8 zKA{$pk!mOU_bAb-4_p5=i`l`oz-^kW) z>^{(c&HK@n#B1X0*WX{^*@N~>7p1tYhLNf64|{5j#9-*2Wp2Ay?2`1Qc|HwpI<|(j z`86|BV?~sVcpzZ|{N~c7CBTg~E#=5QIg*{rTo@e{Jqkpck|-1%*IrzT>qbqy1vP5x zr&l!9l}0PGW>kpm`A9sA1#Vb(Bp1rrH@JBU2Ewr}_|rrCKaKUnBO895XagKY#=;FiMehyDJG(?B+(VD@N%&wBms093E(> z{dQUOhV_X|yJyRB*iey$(UNVm)z;Q>9@8DkE}Ay%(>@Z<-gAFpv9E~NRPhJ-@u#*c1Nn z2+RnSa?8dON$YJ{Ayign*JwirW{`*p7wW*>@89-J+}yg}^o-#Eg=iDl7q6lWrjEV`u~lh3ck5*lrIM zKFbxfstxG``Q4{M=G>f=CBS50Y02DpW&T3cGD*=LbUmGbpg~dqz;>2AjGVA}8NP>J3T_{@gq0Iue+5prq01F+@4&Im(vE2S8 z@O1Zqw9W5L7mG%50P$Dn+X=nBz22HPxn)480;{1hAA!MJxdPJnYf!#Gn4Tpde+?v5 zLDIA)>#bW(?cczZfqVt1vA>Vdi>UUteF`UweQ98%8U~=YsYCr!h0>d$?^jN(yhX z5~2k;^ZW^KStoI@eD&d|F1ljMHU>jm?ZsY>9L2>^RBu*HErM$}9&LbO>m=!$0nQNU zt$>$F>WtxRfUNGiNtzCC(3MNx0eKd%RFE&7zN&f$Qlj^l`x`6(&o<&qJY^02wYD8^ z*9o9ERop2kNgnUUcQ6~L2elrDYa7=VREtH14LnR&JHhCkzb)rH!snXBV=)+-7A$?h z0$A@^y$A^otlHx+KcsWxnk_)Rvj)&zK;wJsxw~b>(^bzX=F9*salE=XJ*LJ*kVVzi zNrAzF37Zpjc^wI)S9Y1Pf~?EvwIgRv%yPSYZ*0?ODAaUp4hZcRQN!9uX=idLT7>_0_EO@cN#z_J2v8lPMBN~p- zPU%p`*#%=j9cO0^*3T&4?*TGLh~uBsVBlh8)|z(84_LLG#S+H;uC7`N3V>)Xo-U_j zs)dlw0*BaQFrICn<63lW{d(=fH`dxLszJsD#-o4eq5?jze>%ILcHB8qpmiJ= zRO_%1Bzb+Y4=i6+YzJT^ACNT3okp0TdYTG5h600{$)j#|<5QQtSS*l7X`$%fw@0U@ zrnJDt!Qfyzy1G-9(B;ox9%V=U+W)+5b_9mEes;KCT3vk~Sb)*@!lC-|XbQbDm|Y53 zyHn*jAlP=7qjqt%+x5Cv>%N!87#G3tp1<~0+w-Y!(7dmTi;KIzSI%zVLZftY{j$-EN zsf!snMu!Cz3vj))4XZi~Q^nL)=@&7+tQcZ{v6_CBCwab6w$~%ruicFt+jK!6P1z-k z0nK`^5k}IvSvkjp83_2zULHnJ-cC$S#Q@*#UWkz40Y(Ij+04QMxAJCy`i@7x=d9qq zRNApiXQMlCeX#a=4LU=!sftzv^X5R2y(cA)Ow+A2zY==zM&bAumq3JaexFi;gP0F;+M8;-{AFvY1ZBG|To zLjknt^@?$Ibw#&_)9p<=_5Z9_7&AQRULPw4XW8mebC+IKRyqKc?$w#$^*Sci5a`!? zxyP%lg1YSU*CJ_5VIb*dzf{J>Dro9wg+Qiy*ShX6sfv3Z6<&0uUwrV|a!OCp(E>*3 z31AI)KZfxMJD>d&j4FSQrE2D|aC~$GihI=TY#JC2jUXu(Hafw;WA!3Q(Bc`z3{OuX z3am3ALBCd2?V>RYQ${z6@pFK7dNuDJKTDIm4w62cZ&U;-KeOT;!*~7qg z^USM8#`s+&8n+q1jsZ7>!g1Mv)k z9^9>11Z#tVS+%Q0wZ+xk^!Q*#59O_@1!7DghAE*&M@P+V-&ACZGsQarWdZ|y|5GOF z55DqZ6a))jCr~=gv$F+csRJA&@m`S^ob9nt>wQ$)Ie%}i%0Zq-uWIMjdWP5TeB1S0 zrO$fhvobyhKt=@B`*Ia}jZSMD&TG*z=@)m5LrCGzn;a=m=RpYVb+SctHu>YCi)y!` z$LhA69e4i70bfhk5w`Z<1L!a_qmQYbG0_R?a=Xr>qoWPohW|)c?a^VRAC-I$i?3dZ zd!Lp6I{5vxYz00c>Y*d>mFxOZg^a;3w_V-u{(BF8c&!4(MBE2>0Vw^0Ff~42-cJk<*?srzu2fH})6d1tDOhd?V%D+BUJe7aKzd+hbwr~mPUoo_s(4pJo~rlp zXe=9_#J&8EQR&!0wv4;Fn!7$Pd+Ie&pKzC^tKJxcfEys{G2sTr5S>?(@O}@3r_Vf$ z>7?-;00O`%7C{^dYPjZXz~_LYUCcC`yP}tUua+%FiGb!IhpC4!-~g-xBm>pav9V*n zd|uIDV3BMpEg)#d%xc&(A^HMj1euQ&juq6mvnq1FNSYI=Uah z95XlSmCZALP*j4tR%qps@4+K*7p;etP?en=lY(bR$f9)KM`5xwa89$~7rOYd{b^F? z7R8=3>$5IEG?|!~h{B-o3qzOcJ2$&`*<|+E_6i!#3d*dXgQ!VikHJ6Y2jnkH`lN{j z^>0Eho0DAUZJS*wuOuNEsKV>{IGpnOh)1`JMy6M1#s66JZ!*0ZIdk zGr`a&S1;y(ymT=H=96UnPi1_m3rN%6ZiKJb(qu|ofg#XGFcOzbtzbeZ02Yf;GXM@7 z{_IoFPnWvN`lZj~FqUr%r9yvAFo>R+nb9#7%267Ckm>*^Dg#o4K`d~u5u+S99NojdlP6D_-AkukmL^3Neg zM->*)57}rq41c*foPlI9y-gIWsF3D!whCljFP$R2YF2=r4%nrjJRwj>s31{0)*sJles)duqn?4yUj{@ z9(`Z#`%Gu1i3XXo(}*t;$frQ7DlXyN28O|vIgvZv36|;U`Hx{pY{d!05`shCYji`bYs2|WG$Np{xd}14$c1dh_(dR1unHYbnJV5-2F&;FN)@&`9-4Z?&doQjA5yG^dgtjJf9i3{k?(F>-#3Gwb;~s z=0DuC#dy@o#zYw=hjoF-5OON*JLj~ZL<7R}1Yqd(3Db4rY= zZ{mLzvS2nJR#{b7?n$gdVdG0ki-Y&r&F4io|NDWWt(KwUxqQ}UaL?P}bPw_KO=olS z`!%(A8!FpMy0|Ady3B5sXcO+b(SK0D>Q9#$^F2DPZdhiD2oDceU?o$?e%{m9m%sTP z;jUMN{Clwj$D6MArt|jp{`D{f{PEGayu1XN5UX^8i;|MkC^?6qtHMSLf%1}$P+;}b z<_h}o0Y40!i>qDSM@#)`=dZl05Upx>M1-k{36_(SQ@){&t=(qo@V%DOqV+20bxI(B z_tpl0Q?H1!1~dXX>i{fnR;Kf_Y__=>>th=$SN97~XUpWA*F5a(?4+S>q~S^$OwwK} z24PN@ThTywDPBL?oYEq|@vqUV$Sx@%OU{uS5*m5W5&_SIuwY;K$nfab1OO_Ii7y*f zWd-o(!4P1!4q&;;D=XPPKVwVp*W$i`3#ln;*>owWUj#Eb-kvkHwkC{H{&E2ht!a}m zJdQZI3xu|vU+(+uKIcc=?Dy_Pb(sw>N>@&Of6cddD(P5FFOU@W`g{wB_Enz8JQcPx zsM=sKGs{2;rzOIznc86I^--3%CoJHKF%E{4?ZL`I0lxQs`q;6j|7(Pm=&h z4!D-YYptiQj2kup`9GSi^DOZ`cL7>CD=A)MDc527AHAiPh26&G{if~X7Cyp}S}%|m z6LY$1KVYtQW4y|NjmO|u2$=KF(zb-rCr2K2oOF{F;qN5EySg6#@;D@b!C-C|CnZ)T z{g=Tw2#A=^MHS%1Jl0bcL^d`yr0|TFoO$dv)h!>VHiL@RN#U4l@exu7`GK*5XqxZ) z{4gI|4P(mgr%q0SXXob*dy9{6hbjsiepl!C7Re=;IkpZS9Dw7k)O=E5_gB92J~NYr zkeGP>Z%c5I;VzAjn>r2>2)dKCuG{US-*w3d0*$DHCIb|t<+S6!o+U~#M$po?@R8zS z^U26WfK>PA>hgTUke!v4^|cc86hxz#!#pF(1;G$ zR7F%bnon5xD|`=JMz3M5>>@UU5CYmoK~YiKEMEHug`4 z6=Wu&pL53T{Aq%LYv5*QXa70}Mh%IlRvofm>?8xJn-;)K-rEv;Th{pv$^mBvgJLQ_ zSs+7e#|HxIfDiyHNk~Mbqn0K)=!;%Hdm~2!A*L5opR9Juot>D-^N2?iDpglFmS_jq zO#QIYeU*TS_(<4WDs1ZEK@0MDODGlZ&K~;dkpMXv8QCSPs;cUEgRcyDq$aGsUK)=j z|9y#*{-R^G-p>L54Mj@$x4VCSuL{lYiUkD+^NWdT8*F^=3}uXk8g0+kkE8vk_848u+Rs-0)#LI28K0nH8qmvzkHLE;CX62r_VE$A)fp`AySFYlsHmzMdwJ2z%gg8a`T5m+<-?JY;(*C|dYx#A`YEt=V~(+JcJT@r%oa z-gkjNoatBV@l@&Y96H&!L|L`%+$J4Gcq#j6!t2_tEk5VnM)hgLchVh;F+YOg*vc^4u8k$Fg>2!Gc9ng*H8K; zI=K9Q6s@mCl4Bt#Cf!RuXO6p*f(3f+tnFgXaatxQ^NN$=B_{<%Jep;$yNA7{q~~p4 zBv$~k8x7A?Zv<`FZ+!^ZApHRzkILt*F45WeGd?mxvAwaOSL?oS4x-!SaBXDAO)_7| zkSF0e7o~A>jt4x-AN(+)=w$G6x$WY2VB9u(h^R#XTy=0cgDW)Lkf673`c7HAb#CM~ zqUnXt)V6hcoS)7WQ=17H0D27#4Y%tnDb}dYgO!z)n!Dm64V*%Z67M=UR#tWb;VeQT zA|@mGuXawo@-uaLm{`yCQonjxXox`$-)ZQI$E!*2!BO`ZfQebp=wqQTe-@);hJ;iv z87!DV-^*^hV+6Cy5p#D2m+PCp<^4`G0cG|WAgNTTTk5FE!PV7NfpL~V6m?y$aagrtxonEr}9)#J-x^eZ-O>lc>sa@s-W7Qz#!sK|d#eE5UQ(5j%jkF&H4SEn9@@6l&sk@qtH zJL{CGscCUePL2zA3ct=1D7d$Exc%4O&Eo0P(9wYb%-V348ZW?3xl; zk}w0Ff;rjDIocSx@MJN!l=UET-moTg=OHBp1;K`C&xl(WcBQ&)x#Hi304940&i2$) zU!MWX5Bb_kjfdnOubIuZgN>}YG6vYrDl)*}?wvx@k82^)z2r_j6bb#yQN89-PrmX= zNlA$c2@RJQc9`VhcByk5R8?137uVO<^H38uW1u;c{YpIj?P6QOOHSX{HzP5iRUfXG zH70)jl=3cj_xm@=onVpBj-BRZiRtOrW1w34)6>&4r`ams;#g4S^6uS5c76R7ZQaWbooUXCRcXSl;7(5arYs8C zq*-!(owwluLaIY=U02w^l(LG?)!N1dRGpM?z;DLnyy@%j>$^I1rNO20bi-t;kgG7X sCdR{9aS;FaKUqwxa}WsR`Wgng@kK4m4?!{veuO+$e5OzYH+uhn0Dh=7QUCw| diff --git a/tizen/skins/emul_3keys_600x1024/default_180.png b/tizen/skins/emul_3keys_600x1024/default_180.png deleted file mode 100644 index cd9913973d21fdfa07d11bbfa3b22c8884ca6a93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68427 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ðiSzDR28xv>7US+t8Dav z0&W5Rrj?m=VK?yHya5Ipmd)7x zV`XSbtR?f*z%jw>2G(}V-)~{L9FR1Zyb5Q~poN`*m92r`#|ZumFwI9msyrlR?(sd3 zHDryaWV#8E3|aXHAXFZ*E`5DtiI)tt3eXM2!s>*}{)B!y?|Fg4U$1q*8rX({+$lar z9(4cRxRqgm9mPEmvoW^@VpbT$+ER_{k^#%b!0-46LKfW?%VoBLaikhn;$x z5lcX~F_t(2+tYGhynIe`JYV6zHN}G!B`<%FUL}Ht3_TZgWvc>sE9in;{wBQ!ePwSg zpu&h8vTCzZz(J&ATkS%HyuB|S#EE0bpzYl+Wy2^Hthk-fbQs5re88Io!E6ecPyoXm z++aYY6lA~Q@6_hlUhwI1@1|zgXyYv#|hcP=0<@ z(H(ht(oyE$%`~J=;j{pb0~A~!s~?=MCV(7Ph1H+{ceb{)w7i$&zuJ2T5O_cddCnI1 zuFQ=sEG&!#o8u0?u7FQrQ9PjKf$0+xa;`o=ZNiSuNbh%3V4pQgaxzTS^$m0|z>E}x z24)cjNy4hrzfJh~o7mpq7xyTu?f+}H+45ru*6Le!RJQq-cqF+C^ zj@N*7-H!hl(2ztP>?Z`7V&%c=fE@=UcF^Tu?Fn`uA^pksKB9gw-~f`$ztIrvTmse@ z#R;;Khtw|4&Wr2Iy*aUD(VDQL3Z>ZRjmoRK$^;VlO_`2}IyKW4FHJC;1e7Y4f6eSg zFbL8A|5^}Oy8&956K?t|Vtvy?lIR;yj6rhv$J&AA%)#W+=l~eRvVHWmsj=~1LVzdz9a8}EkG&3Pf7AiO8*5?g-6!<9ArW`sZpdih z-`FX#9k0B%Zt2#^)-wVd!+M>S)zy4$Bv=m)cKhOnEYqg{Xq%5duC}pf!e*&-9C+n*PUG~{ITX0n4F78vYA_%Ozw%; zyQJ)|f#wN8z`~|H6=T>d-}_^863CWnB_G zJ;gWi0o?B8mEKd`OEWiLQA`Ugm+@W?c{~>^1u%)wWzJZc%q>x566j zZg}M&2F*cwKhGv;lP4&;*}zUguxRzaJ9~%A^qhMIw8S>P610Iy{_hOX5mkjKH3{y< z%?CLzsdz0j%}mACbV&a9be0b!zK&)p7crqvAdYU8qLEvF7G1^$qj@0Cl44jZU~^LR z_N{LHh}cw-`*GMd4YWi74u%C^L8y9e{KpVQ27QS=V$TObUb7?XJE=)BJ^JrRKMG}( z^O`r7FNGgCo>8Y*qi;k9C6=3ZRlQ6R9g#h2~`J<#50)B_!^X5so+t@leX@cy4 z^{mCk{MNtUi4?^Ay}iXY;^rm;6uC7W4`-{~(AjENHq0{5_q}K5Cmu&Pus*d!(CFBMZ{kfYtZ-D6-d;hUTzGcXY0^3eK`NTb8bzC9ny{$q8EqK;{N1^k7pv z=sD1dc&Do^Y?T>335SJB8eEmxz3hV5exR7~&&Z&k@Ypd&+8B?Mc<)xl-40A37Nh?! zaNJy78L=r4yHk)|27b4Jd;V90I47J05PQDUE%|}ii3aqdUp1H7$C!ZLJ7~IF8TZ;yoJBl% zHTxyC*JSJT*HD}zbEOIKT^!A(m(uig`7EG6rn5LRW4wpHAZjB9t$gL;G2%?}7xCZe zQRQ%dMY*3egFZRZLzx(2(77O(gdm-p{BqbNrm>0>wl6vt9KTJZqfAhAzc4rS@B1E# z1i{x_P|1Gfv77mt;o_ff95t8y{j=CniT>3~gonLS5e1kuea2h2z(P{+xt>dCN_6k4 zKwdBz)KeZNe4mHgR+5$kG+FgiCQ842!xgYchY#bv*0i*@%zxn2+U@j@vl58hw1)Bl z@_U2hx1kxf2mFbZ9VL-M72+n4Az1kN!95-S)h#Zma1Nd0tnA^(94;A_dz^Ra_Xohx zD@AHWggLgUX--QuXVYRA%^`&Y;{G)RF-UTV#6N!;r>lJ4**n!B;$yp|<}fQ_DDc&~ z!=lN;-?r6NfPP{#^#@THncy8n&wo=u`#ec=Q66ju^NpKicfs9r*pbIfE&mJ``1iEJ z-1jOo$0aKVfsUE>LtGQaY#KA>(-hlt?(N%)qKBG_hKSVrS`KoN|FO-p zt~U+HX!v=FD6~wSt{DW}RAmWk4RyOtnitd=ad%}7Bjfw9%<(hSzoIsdF)Wb+XbTD> zG6UW0eYZ&D2@i{Q+p@#dP7i!qwp)~n9^RKbjuKeCMHWW}giUMuRckp=2h2Nf>F3*&SXqhUq5~oa0>Yq1nKQA7O^7MbgfHO)^q=xmZR>nRy z!Z_iaEr>9-JQ5W3H?SYGm6QGm7J|MDb(>*M9A6=;pc*!4fo^qBUVKDk;qok#^X@ru zisbg%z7VIaJv7c{=@f$A4iUUDr29OlrSWu0&}5F1ZS3#o*?tZ))ZSC6etc<`u-Lb5 zr4v~JlV>#0{*jWob(nin2{ARHN;lg@0pE53!7ZSBF`DBcJY}Q^KH_okc0p#>Ih|ko z5ude-3~@}nd{AVthMP+c{T6%xltpP(zVo2g5d!#v2h1LctOi0{CruG$LzHHP;1*P8 z_g}Sjxj@$L_0Os&V8Pa%b zC0-{5XZX|4{rKWw!=Y{@-v*@-0zPS$x0orf#dC;D|8AZ+K3|wn_LSlo{S>1?Z#~Tt zTCKn&n7HDr=q6uMrnh zFDE_o4Z%^H6#hiXj*jvrM@l>a8RZhfe9E8*6^TlbOqu&kKm*@8R#Sj;bK^4UJK?JL zglb56z67M#zIgq}s8>c61|3iN5dIR_WFRg(OCb$YN?|MK(fjGGeR(F)49MeatA}q@XmExJXmF9z%CICAxKASA z2Wo41rul168kg*I>2X>X$GW%@uA5V3m-dp=9y4f_VqJT@|H6W8!d?dhS4jHyLg$Yz zxF}uUR7>&s9`(0X*N1nKiWIh)dDM^BTXdp%ax~ie!E6d>|9!+io1G<+2MazTLR63( zGTo#t);a%a6}a`oN@)B2lR$@?!Yq`+>?k1RP`dewhe6hkdgBEq^_rWtlIXzSKHN(^ z?DCJ1E$4y?lHR(JyvdL;jo!Q~O80hkJUvm(kk8?PpBA-cpLo$jc^E%6x9JxsqIh0( zkDU-VA9~|uiu<_t($C}HQv>ZU-}^iv7;Wd0dc|RO=W(Q%RxDBUf2l1CRbXQHX@c9X z!8(pSK{#%Lga)rMG{VU15xb!#Y2Qm(a8}7Ht$hmg`yT|5O8DNU3*}oiMZR={ zb(SNjT=z%3hXUPsyn{5K+k!Ocdk@EW3(gWMOpCS1Q&!M8$djv4b9`YI`Ljl)B4Vr& zf(6HK-G5LgnF6gJ~Y!L{z*=z1=3?DRA}fh{&b3!}i_Pm}9|sf$Cj$?-nyK zd96-*XkR^)AqXME%{wtQ^?XsaIXYXfGGQukmyjIlY%5RW8eb{5sq*1Qs#IP)7TFe2 z5qx^=+y~!1HXD*EaF_bdLq+-)@SoYU1VM*n~-kx)G9PNOlWqIoA`X)_2oHO52pE+vkkLITpM0tqPDn``{qO zsA|D9T9}*hiI+?KX{??yfqV(T(*gHMB0ZqY4mbI~Hdk-3SW$xGXxS6H32eW87a9CW z2vHmRMn(C8F2OB(i|azLGnO(~kcKb#)~tDDoRj;#mfD`~HjVWEswtvhImDmEKX92S zpk1@aH{ndszz z&scBZlt&@W3*{m^S;w!Zdj_$-57^~E*O|{8FqcK{L1(G@48QD#aEq|)T`rqX@-L5S zhF=GH${-u{Zk-QtkAILe4X&+#<3>S-Awq-(O+DKF8;T6gd$%`^} zwP%KPkNhSNue_Vz#(UD?(E)u_$yBKS;cD`^xIHaZcYegZijIvOxqS+`v8#_@s%#S- zu!J6fyQ8q*6nOj?s~do>^2v#)Or()M%cz_q#ewFL`W&uzqx8>`YCSgMhu9kG*gJvp zB7VB(B0XgHh&?8%6(zH`=|770A1%gy8DgPSyFgX|Otk<>;QG29OEb;=_mzA}ar*k7 zTZ~N~-*tHY)!H2=6DJ$TX6;t0(&Ovx(d+GR)^b5}bBm&rNAfJ*R}OVcW*Gyb$7os9 z`^`7C#`YuKMdB3pD+j})RtSkD{OhOOW^LR##5ce*tnQ|g6FuBfsdzDQ!X!;4+WVeT z0Y1`->j6=oO@JW7eyf?(;P&z@o`~$1&$SxTor)|Aki0b4Nh0+*8B5?eVdx}gXSpXg z8@JKY`B+KzH;o-$CV62jb41>cLCLx1cIDIkNm0W`p99dA3ozh#w_70jI4ZMoK$T!& zoY*}we~}2oK{yxS7Jhne@$siNM5r(pqSWm#A1wG^>qsYy6JF}fui`D-3?=%fS!~&) z5peFP_nyu(++$`)7qfWq6@`~7dX4K4wU`Umv_N1NYf3Wdk|VcoF{u`r)4ATW`W9a| z3MB8xDG&K|(gf?zoA=V|R7o2f4TUJrZdS<&qt!p1#Wl=mJpam%BKe*AEae&TBjnh;*I6 zS>L>MlkM!m@SbyO#e(^9%;-&={6Di!Ew#Dp0-tgee<|DB7et=C8Z2`B1N+Trak(Wi zxwqoX#%*O7lj)Ifk}=%S?qE3=VX9-ES-a?id^=WxU?cWqmEqp6x5>(up$gLli8!$Ck)e4OGXh`%>piPq7do@8gMO-?l? z{8{wY?Twb4&cyf`X7L~dojxSX!Hn_#yD41yQ~A39#QI@3U9m6<9wYJJoU}$8C^$|f zn7@J(tT);5>o%L&+lv|!{L!T`TZY5mD$0hPs!Of&U!MwhdR$v`9^m{axrovD?`6X~ zi977L3-$N{Cw3u#*p$MYZ``+6aChvC^`_Cm^{`yFBfNW6J{r06Z&xlip7Ywts8&(q(ov^zMdICo1=ApQG|rEw@Bi~0Js zKO$zIx~RhD{%9|m?`A&j3U6fnK+G%v6;eWg$;}WT3ofxC)IcUccRF`3Yo@ zP#$jd_#pp_#TS?aO+Ekz`oRofx4C08GP?c0_AkLXaM-OVUb=Z4Sz9D!|dCM z+AM;$7kb*|JRBjyd@u#7Z8i%X4OAJ3gD!MPN1#DVL)5Z;d_EO}2))<(OMa<~9B)l|(mqCMMj`TatxJ*kA1w-U$|bO2AvsG$LR$ z*`7E@oxEevI?Ot!hkoAJI-oh*jYlM0x+vQ^7%X_>pk}Ey&KiG;V6{ewM029vUZ-?I zH*NpDvj6~7eS{7*5TVi6kV0B@&IY6HsaaW`lbm>`IxiDcIJ4U0_~1r)CHzU zYjPY=7EW*xI9~1PaZ@Ojw(MDQmeW(&hkwfDW8OJ*6LcBq{YG|BSib(sDbcR`{0A+r z>k7yZ4q%!AK&La2I6IOa`PGS2 z?7?)ghiBaz^?=c$jY#^reO_EduNdR-iw`rncQ2R}?>JQpCMX6h^V6xDQ>~fNzb58z zCk$5(wk?!!e9_xN%&yY*<&~IM={U)3m0oad+gUcVcnU6cOU`Wm_~AHV>Y*YG7I_!b zwqfgd`s>b%&8HJz!gcz%*FybQ_cLvK_9asZiFHnKH)3aYVajGb70L<{;o<+a=>7?) zYMb|&bB)&dofYbTjS3|EtwI07QOmkY|8C)DYJY#!^eyfQ_PDkUKg~g!oG2V;zld+h zZ_0*;#S@!kUO3`@4qW^7yNK7A>IaLhRVkQnExUS@coHe+u?DN*ZTfqk+S2^RYFWMt{ zNDgq)gH4+|HFn;0D@fG$6bvIYFm{rRHiI@3@Tjdz|FmhJNt{Oim*#6sLIPga(;O`> z|HsjF$3y-9aU)ws_NF0Z9xjB8NI1?odvo@gk&%^EcDd|XB6rr2vq!cw%Q()?$_mMj zexL8}Uylzryxy9UHIHy7gkZ% zRIPP=oR^uPBFS+ic5WS_gnBi7Jr_@|*ef8a<$LtI!#k9RX=~o9)B){x1zVaR?}T0I zdeE(lg!RT1h|Bm#($!EP4Uqh7O#DWikHkXNY0Oa{#_4}o*5;2Whr7~M@)Q#RiA04% zt50*|2EyjE=+L{Z^cni!?~~_Nd_g4yN#L940Tk1ZhjCGS4+)t>NjI0 zS$V`d=c3VJENx>vi0f)sEq7CqX}!LIBsP2icDoRI^a&Hl7`+3s>U4P-KJh#d?zV;^ zIEj49-*Hj=_pp2gHAYpGjSHT6^Iys&7~BZUzTiH{_kL7@!H1;L2ayBF!t)05!Dpba zNdEEcU$3e|4bk0;Z&ug@_P)Wg%!hZAHSb(d1?f=(57vRZY!l7v&)R|mW$A#-apuEj zSQyNeYSMAjS#NMETyjw5hsE0fK=1GuIE&Lb!84QV8 zs0ZMvfQg7z5u$yuyz0LuNKKUd9$l1Sevg3mUW&5B(yB98X>G8R#L+ zi@F~g$@Dsu6^M&RnAK@@@rU4V=QK_20=8A&SfEzTQ1D05^^9 zUz|8qHFvzR8Z5;X#}{yXthD9^=zr8_A4D&3?(R3S$I*Sr`Fdwk5ns%fg6m9RJ_IupF63OZw}i~|FsV#6!U2R_YNcJ1Ig%n+i9X@ zt_C7zS6W2IU8QM1>|P79ZYZdDqGB2nn^u1C+olKBWRr|I6%nlw!->E%J7qu1r=AD- zP04x&%g==*LsV<`qFW@y;g*1k zycZWFjw4Ixk+tAbfrELimI5OokvpQsBtTNO(~ixK z>Yg(Dw9N8Csy&zvenYN|L^?(}#x2z(7XZeh$UYJ%0d-stvrgRw@mGZ&cym-3-<+zk zemhoQE4s?hx9nMIZTy{PPOwXzX#Fnn>+3f!TGc4^%bPoA57^6|XH}yN2mUMO7M=Vj zL^wv`qMg*LD5Za^aFnj!fP|w!%&PIR`$H->(0k6RDkb4fee%4kFR|_+GwC=T_9AY^ zyzdWvlVOwv>sca#afmxy6eN-8rFpxCc>PTe%GVqxB=$+Lx}o{n%oD zLAu}ByO!WZnPT&nJpvI-=dl6sDEW;ow*4!!b!A9vC6+Enwldu1b|z-;_Z;G~g07QL zV0(UC|0&kvUGI&`Ur%xR{Vr_(mJRLnO`#jXv zAY6gB<;!fBG=ThIIu4 z0}!D}%rnG7clfh0RMUOzt6v?nmLfq1+%y2NSP%S<#=NZ^;ZmWi)_35MMz9dozxh6O zQurxrIr7$|J%RKKaLP1_(kjFpNg{XmEdqYCX2zmKQD-h9U}fZZX7k}Jvg+h0sh5bx zc#?+x7KRw=EO0`p6I7c!`vVjmW3ung6q=LK1s1j>v(!B`H@61{;y>Ex&Fi`;HW@^= z-7q)z{n#bU0fLcq^G#<6CH9kX&=X7BTfmNY=?#?4=q>|{ojzLcMxwZp4}^Bxi^ z@<{)lC_G!{t@DMM4P=6j;H~E zU_@dRX)aMgGQ=3=mt-TFndXH%nM8etjdWPXbfqcoA^bTW#=<9#28_cu1tlIp2!M(t z`B*wPuh2!LB%C5EYKmc#qKNjhf5b+-wq+PEk_NM%aaD(%?rukLkq*`?E-mtLN22dDINO#K^Mhn_h0zu_d6NK{Z1f(#dgh(-d5FkA^~RVZ=@A54n#Pu@5wEn ze4cTi$inCbg^AXD>0&;9Ls#ut`KZ9>KKpxyRN;Soa~2H!(@5v zEORMah!h+tSp4|(sd|Z!2Cki2dd}9XRp%Pzv_(dPTK1OZoBDKa2s*b_imZTzC48G~ zj|VA^sN((3 z8Gf!3ApnI2Kdi-G2U@$EJN`2b_N|4#$XB})P$Y*8AARuqyf!mgTAA`DRhFSx)>{W5 zV8AxnEfSd|2HBG_upbkgJP$8G1$`Ux{6jSexlBn0zjU28F&`@vQ&zwIav{@&9ZEir zB;v#jtc>X}h0WY32n+cM;nlYK#4ynX+lroi_ybyGo}MpU=1-czMDkxs+xdI`@8Ka) zUbR2pdTRE%~WQflP4~ zkNAzrA%j(G%}7uu_2(ya{ZfQm6IMrIX%c@nMN5YT4YvHa25Fw=t^3V7njv~ zdZ2wK+Bg*9SdZun!M`!JCC5<)O;eT<)&0A?Xue;=EhH3Ao?krUu_~Flr+gR;9fv)# zBC2)cf^Y|-4ac2$6RemAFz>HOpxA#e<65^ojzMKsDGFrz6950zU+c@^D~qN>SM_u0 z?p%b|XHK2+POgIgd|MBw0aQTr;Pg*m1XH0&40RS3{Wo@+EfTcMeY=Qc_E&dv+N5MabI%skq8kDU;n!KA9N9TeRnGFvR9SM6?=RJcJt7#vAzLk+jEYV z{+AR7O|gj17hYF6VSGv}dY=wg1=ic+J8n^gX1ro+^0JUJax76A#digVAo<%>TN+RHybR6_d3T+Z}-RqGI; z6Ej|Xj#gz71XgumjTImf&*y!t9A=a1yEIT5>JBm5bm#YgId$v_sOV7R?w`y%d{RAN zK=&Uc?vbh~;jb;9<`}E31~j^eqOZUB(VNb)I^2|(wEiZ=YDbRT8>?rhOZ0Ff)lhF_ z1BxSQd8^$M(h@8#xrMq|%l;P;F1%o99PEWC=3u`0X4R(C?`}~ZwQDbXbUt-j!^p>- z7QUA~Cl^HfB1ewi<3KV6qm8Hqn~?bBoR4YrSW1)>RMfvq2Jt@3k~jCT0-U9xD2U$A+}!uHQFmzfXx@q>hXa%X#cQMeVNq7uoA}#PIyR;lzBS7!7mRnOfQr8eyxeg(npSkj zV5#@^I}*i~v(L7V4m?QCKt%}BfB-gRsigJEqX2bQ+;yqj*IP^-I|@l3aA$a)G897R zihrp#m{z8remE#I%1?zup3JQEhr+L?jhb>}MQ_f2f>-tX5@m>UYA3_@M^+x$0p$B# zll}+0xoOA!E=R7TtaqHFVgKUVeT^~*5pZk|AaH-D&gTt8KV;z`0c#J2 zRijtdT@`sPl^CcL3%z+bkx{HHzM=is>0wb85=`S<}=b#sr!p<>GEn_X42asmb}Q6w@lnj(q42E?teZHkm+g zAB#Og&VY?#-vnk4q!>(%)@B`HSLJzA(?gofWbqDO(w)1!IdYK{KnYN(4Y@qL-T$b= zahC$mAtxkL8=~A>+vNTSWaK7M0Ve(r&{Eyy>WEL}Zf(C9=`AC&@T6f(Acp%NN&Xoz z;gTsM8pZ@=HYpd;I*|;D^cQWn;S${WivSc-0B|djPvyWj!vUpZ4@C6Sc#zC6w5E&y zzIM+m6aU^cRcW*Np+mR6Vf#J@z*;JZ|Em_cFJ{R+37(`i+zdkL6BA-S*>OqGVvJsb zbh^sah7G!P7TdqH9){~H)0+z$KK`-vDKJgHJBJMyuI9Eamk=LAx7O(=9bg{P9iyTq z_Gf{jo~uw}g;_wXIVk;VIRA&K7P!n=U3VvJ;L=-^;@Uca9WEI1h2HQdS5)GyNhxK% zc4nRHHM42!JqdG8&rd;GEuqWidg_C({66!e86B+QIpbO1x~AK#Vs*0`ONEOhh7P%@ zpRXEBxAl3DlP+O~ndyl$-rj>w|MoT2T6d`LqmBRT3rjz9G&((A2UateG$bv_8xb_G z&lGRW^ei3*4X50ql=C3FakEqRkimNI|GeO(-*5!W{gK*>Sxl&8BetE5qcAN`EyA78 z!}0`Zn>nnI+Mw(A43MRC)sSKm1T_G@J_qNrNugPwnks(UX|&w^|87k(Bh|O~6t#x> zpE$ZoQvqf(E6w3$Nk!M7$uc^v|5A)ihBJJc-a-$`5%HXB({@^R`x*jj`YJn*DWg zuWGmV!w60M2r$s_+RzZ*E4|nQLQ#bGzD2To=PdO%aO}Hv%c~@`zF)569^Qxk) z!|3rqf8Kb9O(RxdO{7}9itk6g(I%fFPWPP?D`Q`}%kUSufijm-*OL&p15m$7K@PLG zS9N}^i@X+;Zfj3&nwG?(s#-p&XtYgtO*ruF&Wuy*F{=B8fU6w0T1Dq)h1ZjQ`|O6T zv)dB?Wq;cDR`?f+6@xpuHD66ONcSY3ViUS$#K!GI+rjmiUt_QJ=^Xc_8=J~VhKtLB zXjl}Z;QsC`AM;+Alub14q0hqjv)SU{_-XPggklM^@V6-mESXSzU7TBfd^`T8>1iNl zl<6N=`v~^SYX}fwzQ8N4Hps69t!06u7>e%(0+Q|Y!5CtSoalz3b%jAy#jHCrj3LA` z4eeElGe5w1{3IRI3VHFT5liM@h7Cemx%;!*-GCF40D`}~EbKccUN_ji4Nost67|Q6 zG16~Am39R&`TQ_8YcWr~9lH;fiPEr?+C~sdMQm8Fy()5(WfZm`p2=! zCU<0v3KW#gu;1>h1T7bF|0rc_seIX5QhjsH>%_$)`%1X?z64h{`$KKSIQJvT^!l#r zdVnc#Xo1IhlMk$?TDBej)`}W^3&cC_y0_OK-fGBy4C&0C^clJYWsDdx$y|~+qxO1< zfBe6cKG=&MpTPJ+CFYguS=1Ht_2dUK`Bg4;w>Bo|s9*Px7XAOJN3B)p`F`d83dpy# z=8nw|)@VfxCq1=E>_RE;Kf%Bs5b#`eF`~wzb(oof7&u+)mpnk3zW-u@eKRhu{kD>U zQgXlJYy1zhxErIKt;15R448mahSd!9==B+9TA|!uf74K_vj^^R)PvaX5wio#E0-Kn zZw)J-1t?ki+t0E$@k&!C6O9gep1`YhQh68QcJeF+K2PNNe>@9(6y9@ZC!401gtoLx zLpNEXm@T|u1X}P7iP|$zxx2elyGaa`g-<)pLSL3a?$FKINU@SdYo znjLXP!MTmvm;jD6_h3EU1yU#-8vsNj_3cU(Wr=b)MH?84*{E9C)5ymp(z4rKvQ3RA z5~uD21NVeTj)XBVA*+5p@U?@IV3KOCT)v z6ikAxfS7t98NY3<$B{woqarVScH`Y@j8pCuGsJ2F{>yvra8_gg%ttQiB(_Mq#o@8X zJCI~L6Gsi%f7DD~N{ddZ--UX-P@*rV_LXSez2mbrLAQTuh{FAoGa-G%Ww>$gY7USS zY41L83r$kt*hw_h+AA8@Y74&^oIXV|q8ur2yzi%#{U8#60?iP4IP}kKVD5QDSgeGr zko2#Rze81+iZiW={n_1)!ysD5`;=pxYSLB&20uNgPF6FzTSz0^lI8Jfy(tpy7sgj) z-dn(~U63=-G{150V}eqE=W|9I1Nh&$8Ody2fQic~dK`dS$eq=s8lAUmbbo3PE%T%& zTU2>mo*ESt1{61r&}0tz3PjYl$g_3D?amG9_9{hmx;8&1vOEIKo`~ywu~Z>>*ByGO zMf@&TrR+`YXK^T7hZPMp@G)Ola{UGy*mlS0^Nyzw{-!{y^u2fkgCJx!^H-&c(nT=3 zr=c$=LOw>mY6PreK4vxkQ}~D@gE8@i{IPntKv0I!ALEAKLTn!JG5oL%U^=I@kqo}; z9kr((8nFLO@FehCo6IMt+=huv#E=7q7;f!R=Kp+TV^jnnaBRBuw)n|04_bNxiGTIJvnhVivQ{x*Hi)%FnjtKwZ zcqITisW*8gT)q^!ttnqKh!nXyH%wCrmws~``)Ok9#(pvxvfFmdNF0cS0_;TVY-3)o|qWYtZ&{xCb@a_l*45>nUize-Z)SpeImWK>efq0Av?_UNp47|RefAA+9?8n` z$;MEL9)(E!{xRK@QU2kkI4JQ;z5i_44PZ+Ca7>I zcgWIZQL(NpXFcr(ZX|Q;wP=RI-H7~ef8W;AUpgF!msve|QiqTV&VXP)dUs`=S2xGG z54mvNTALYeT;U2Kgrundi8%{05YY*9R!Dr}YyFvX)F2>yE`$zH5;vuUVPNxhH}!>` ztBJg>RE} znMOKC&N4nB9_p-h%dRaPr%6rAGkl~jVz}~S)kutQ>_YA}vvwdUuq|%WAu}S4$2Q`? zOkDv8YiY95PJ;tk#*nXfpOXwGJv%?%335~4J%zGaG8I)|_R7ObP=gcPM!ju+dCNmG z>qES$a*2>_UQj_tr$gPAtxXNCl4>ZW>EUSA5mNjjd@gGhby_R$j8>7~7{{1Bv=AHT z*6D4Vv^Pg1A|DoUD+YP!HC9#T3l=ruqJJG3pQ37BqkOvr>3izms6OOD@2xf!=#@QV z<1&B0C{YS7B^oxKry;%le-x4N{Ks20V%jClKrxG2IccB3Nc_2aDzJ8e5TvUd)BVg< zPA*aRfB}=wG^@!+@*f{higeQ7qrvEUq+ia6^fBU!TVc@u%oe1j+0^IE!a}lvQ7)hr zNMXHr*>mr*Ib$DbD-dJ{SyuuRH$tim0+Jvlxf3VvjCF6ue~;ZXj+B=%120Gj2YDNX z2|!_83iTQV956?=f1Wv#T5upC>8i?zp+x+z3C|Lk;#_ycMP+uO85O*G3}jGs zMn*2Y;3TnGV5Lbg@)jiwo%ZpnwY3WQm2e7( zT^UdgKGPeBlXZK#!;7E{dmAXtq1%)Y^t?W(aY|N>g$qb-|+8B?N?*W(vk$6#__d|NVwTOuy2pQ;#Mik=vau$~YhC>!S+{>3YZ%;2i zX~|t9RMFssJ$Z$>yS_nlnq4XGp%!K;j?=RHy2I8?18H%>W$E8(CpcB5kPjnr!|-b^ zFx%T1O6g#lFQT>H2F14uB`5@?ZDLv%D{GaoH}y$nj6NvnnhA!IX)k`{u6t#WRR+>Zmfnjv(u9%12RW1O1glkN8PRWhl+F74aimUR3p@B zdt3HI9;yG7P!hKdXYD1CEo&3hH@ zFWxJ=f);_GC*L%Vn(e)cg!8kRrEnt|B_ue(ytxwOgoiF{6ltD`H8e%?aJ!SkEeqY6 zBqDf8kUgkA>MVq&(y?O@OtA2QxR6PaRl+V`z+U%$*qKx4acr>)0Kik!1~gLsi$@vJ zkQD_~^R0e6GaWG@(kVB$1btI3hW3Uy5CS8`MEGYlVEbe|@0MizbA%noz)e_KbJ0Q!&ADSkn!g8HFh za}BB;jZf&Ic0Juqfrb3UFe285Yu74h} zD@isur1%Cg6xfm@k!Zs$B=ciKerh-N_lkYsy0zX&UB#hAP)s-5*2*msD@CI4xvdY) zCIj~t5VP3fKA?@{Q0651Wrlr1X)tkkG4~b)5sp}oL|L5po%M0V!cK#dlO;unRp|D1 zCowPl-!iS_jwN3tJnJ@jDfI0zNi60-7NZfJ+3n;Ch#qIPZ@Nruh{%7;B^ckAwaN{g zX)dE=Isa1mo&ch2{4#iQ<@qT@+RcBsm?_3C=7AzEVdD3t3ZbI`Ci@!tR+>)pX zC>bV&2V%59jI$@L%LwND9To{+22Cq1I?;mT&q+eM>&WN`tYyu-PnP0YOj%AOr%Wa& zW>Ho{C&dPZiDE_E_?(>`pLghJgW@#}a2TW#|J^Pz!=p!B#r($w<(=tNRhcq6>cayF zwSVdGP@3u5k#E}AQ`@pystXaw-tR@Q{p^=33`y0qP={CRSy3&rLYwDiiMGA_9<~)! zuK1+}VYS~V?V#eZu%)qlH}BewfD$h-L!|j>8)ETJEGks0G&FIKtShdrC<$15#{#3x zRGBnxx+l}gFJ!Xgo1TgKzSn3-Nj~3~6_a`Auu=fE?{qOEzlVxiXRc;M=S73cGy_Ph z-t6SOt~;TM4ei*YOd4;z7x{!f|5Dz{r#1%-3(iJ#Q`B%%u=kPA zM}q9~C*wX>rdn~+eYu$nsdfV?6>fD{l7E5BnM@hY-zeQw!m0Rj9_*54SsTyS`G(oa zD=upWB0WRoAh1GUjIqjXs4Z{1`hiEGe--0oURp(BMeE@%6t>;n$57}$vU8tI<@;=Z zE^d;BRtguTVnt1+_eC8s@v;pTQTA*=d!a-4==-#o3lHIpMcPUxSzmLnPyZu+q&|K& z_J#btv07}?lM3Iw56hH>J0q_-nh~ejVp(FO?juuoHxYLtYO4;%oh)g0;MxW2><@ln z3U`=z*IAkRo(_LTd(4Q)7|8aT=l&2W4k?9{M0gn5ESUVQ-P-(!JH-)f|CEs8nx|oi zb6@LOr$-~XTOJsWd^DKgHJZp4OAy{R`Gl4}4C7kih7=w( zM`Zr{6{NUvPJbiMsPsW|1-*0^s+$6hxP{S+Zu*H}lhy|3E1;r!D3O-cGh z)A>}`w8>SwH&p7TP9$i2ewrK@ed)QSCXrz`Pn%)8?zBjQoOI>s2IDZ7kBl^zEY0;Z>wR`$Ph^R^&Qe#ugbIs!@HN?tcfyPByGr zvNjVFL?4i~{mj8S4qErgkM-X-`UL$z6MK~HKB}Q0Z|T;ob-Lk|(vyY~TUQfYGthIY zySpJ$z{brb|2fQA)%Tv|;hf4_6IuHJ)adC_Tdfj(KpAT0hEAj3j zkhu=NTEZ(o>acngJ6-4QX#qjU*rS!Th{h95zCHtH9ocFz*TP1r zKvr8RUnbJzBpQx`FF%NM&XHfifhqs$iDP9j=?NL2XyuM9-{Ne)lxChOjgh6^Uf1A? z$*Q=^MkpRKj`F$YFYK!wl&S#y(x3TR-@RYr;X$wADA7&MM}o{Aex?L%2fq^G4V~kV zHWWY1i3Zv2QsfztZ;Ti0WDOa4M6R28QmU4=0zUaATspMgW8jC8*z7x=Dz(WFA9HuP ziLiDdWS7Rz{@TkmTV_t;99aMxc)&et@;-cw1bX1xtURjJE42c(oka+C9J1saL}@;6}*ijtl~xcO&)sV%L2s@@eSq5i}% zU~!L+|9Kx26SBv1al`e7(AM9(c9nf_k{E@w9L=X%^1{=l(w$K zSjX)69GttAph<3ne-+m&)|Y$q8W$-10hgrZa-{k_@owN$Ce#K%hg>k3SaV_BPe{uE zJ250%gCKU=ZS(K`tcZ2;d_^MAODGP>R1cVs!MgllNwJOeyPGbXk(S6lLFGnZK(JLw zg&~;IZU7t6BbdcU_smknY~%xGQh26`*KbfPY1l`?@V0-BP<;Ij#ApQsxQ#Mb>)2%T zQgEYrOWv?-AB}`m{dlv%&)3O~D#CI@zj#EpNB5<|CIgsMA zxjHgjdB^KGUsLCnjR%jg(PbG6oSkGdgA8CKA{FnuV_p$3G6SOfjmH!O%_>r2 zObl=B^C~iTj7k_s=aUTW?(goO1P9pk2!&?xE7KpG+r-Ggt|podvf|d@kLv=mM)Cf} ze{C?&WmR?~l%}5l9Ew#!meEE0@~feH6GYio6XyPS((j{G8@Dk}JT@_srdk!YpGD>E zv&e_|k+RcwJ9nNxcTKH|5GUveI6xh8KCpC=Nq#!82)B)mw6cDX!9d&CS*QyL!as7) ztbGhpo2Sth;+u8%2E3+J(aTiWx%@#1~=Kh_k7D*gw}*+NO6xJGcGAV=331YV7{4Y20CeYU+Y3uQIh8V@LcJ1Rq{B<3Ib`s>qAG zrX03+f-dj>B^HwYhMec}_VXXvH1V8cO~?QKh8IxL$$$fr`Kcsa28=)0jI4|Akk}pyF)6#K?LFoA%4v5#Kkm5hyhGfcU=Koux`F zceCK`H=pD*f39>>d0!~D&FxT-EzlD3HDF@CuhiyN0>fmfkCyMmL$~VkL)TC(L-oEy zhFZCpR<{e14Q6}ui2%cRC6&2Ui+Gy~k$(*pqWlMCmy1#{Ry~2Q9&Ka_8}U`QoCu9& zBIw|XYV~t{d4P4mrlqk})A zwCKx-xPu&@FP)0BaijwtaLf-5>?5iK?b*shlOW0EeZ!zCZKJsmK}WsgjEf^ykvk=F zUXdWs1w+sCn&Bsxo=#uK|9-3RzC?#0qgJ06%^v@qerb&}>aSbE1U4Df7PDb>G|SGg zo1mMyBPY2zTnPSIr^2(v`P_`}ULW8r=QC!1D=FF^3kI^J0Cs8QTZ?~Y7~Cl}+>7~C zLy+~M(Wpohb1sK4b%a0ra8Ge-bJ#L&0{Q|Y<(5gMWh)EDw%PaYLj==f?Ztyqjw@yf z_zmc<;@&>??`^S)i!sow1>27#aMtEVUbBtV%k}_+9Q<*fP)IseW#{0EzgOJB@VhSH zD%5jQU<1q4(cjhM#e|G4qDz*5i~_C*4M2z-eV)GQ;zLX&sQeB=g6s4R8t2~8 zz=LD2hkw9;nKnHN6*@<0`YmXnH;!U(YA7pJex>;~A2nZ=wK5YYo=i>h`@FhQ8tT;@ z%uSyJZeDF-BY2zPZULUA`lrQJqy^71inYH`F}g zGD0MBi5h7-H6kbw_%~g4J(`*DunHnYrnK$NM1ik?2Xya!qrmO@5{Pkhbu9Aj*k_R$y+_yqz!=Qg_XO?s>QFR4%urUuflhysT60XA#rIwMoEjciblPB=+Fh%`J=7pY*mV zqFqwJ?(nznW$AQH>fUE+Iq6uHCd!2JczL&d8awmN3*_(SC$3J4+hvmWQTC5dT`g3r zA+9~BVa8G=X2Gb1=ilCyg0Tq4{Eq71E$EHt!AYMA>Ep|1Lr;gR95U4@yI%|2%$_cN zl>CGO@#ShLcsHrUvo}Z zhlI->`j)MzcLIPcWIPS@;O9%aI6fmE0aAx;u7l>3R(K-HAA-O_`(An7anMk zq44G1QM)JgxgBr8O3kMCTNo}YfMbjyBZ%|5m|Q*Ra_(gC76^d>)<8C{r?%RdcBiL&Ob zi6^{*$ut@Pp@EfLymeeq_WM>=>gi?lxkP)$a8^|r%y#9`oa&=Ehe27O_p+N!eq!3o zdqs?7dXo->?o-wx_9~eoX22;;kfm92oM41e+2f7NnLk&aA)Of`si52(WF?k|GD9}~wlbAo&_d@IZy>xsh*!CxLTnhd5gSnP zA^*Ik7HxNh^eNihxME`}CO5~;R$Y@d^^0kJ)5EvLJq~@W(%W@P?G7*AaF8Q|rL{|v z;dU-4r}_-ho18WvR@GYl7Ts4~3zx&uL30T&F-k2M#0T-O{4uqYg4KYfo^t2gb^u=^ z2q?-MVSlWJdz%%-~tFb10%RY#$w0PDt#2A8sC3d$zf`u_yj5?-Ds6tO z_6_@4i;D}r7@GZ}dE|6EMdMl;UzE4KVeHvZnrUl_83HSBPn#h0qj`k;MB?T2%27M+ zK9RP}M`!N2ccl3Gxas0Y>H6Q6nZJl|mAg9_veE%54}OoqSH6=QX8S?vdE2|X8f$#j zCbBpQ!;8!{qI<@3eixV~<14>sG=uRYN8DZh%_yd@`EcV2=^)X5JAL=D z+i5q2@NoiQ(TFSPdco1^jI-n9f#0{aMY#Vg7>Pg67a6ztn_s%}06~lzB*p=?J$>+o z3VBu({L|%q8+Z{c(Rj^3QwU4eG%CoqDxi|-h<9T2uzX9eqDPuFXn4zO>G0+Eega@o zz?wkGnv;gJZfFXesG%W}SF*zf+p0haAXxno1aCdC zOdLYZI5P!q>>+Lya{caFkcocA1tm`--k7wLFQt{68CD`**J6zjV;bBD%k8QdYq%7Q z-$7Z8Jqi9L2s#yHkx{0SgjE@p(8XYf24U`u#ms}mdw z!Mf&bViQ<K zE;vXGnhcPl>@02DnK`+YJzQ9EWfxbTMs8WYw?V%+%h@3UZWz3`AhWBsYH{mbCU`Q? zm9|OykZicjH2b;tmx;0qU1ru{V_r?uM8tKVjVx~qb3VkR$f-)xR3&R<44Z08nW)!ztrL1;amp)QFo{b$@+LNK3i*qLXm2ZhVuUYvbjmPC})`%fpq|BO+4Zw2)-iQt0Nh6<$u87o*{1RF1$NPf6o zM~XJOo=U1T62!zrwxwj}IalAY>+KnWBwjnX1R)P6oLo>g>&(;s)6y#Pvm<(zm)je| zQ#KqG!-7V|w*%%{h1Nd&3ea8Ktnz~}1*3+-!Mv$Dm#=Qd*5gi;9O=H=c{x1LrbHU$ zA;EOtn;HYD{fkG7`?0YKR_#GEk#R6QcWQsD*=p-+>I_HgO=$BKb0`-vT<|px?0)Vl zUV8KKlU&{Y`*ltIO5SRb@K&I088l5d{dBWPcW}G$Vi4{QvgA!EU7?12ADKd^&lxMj ziv^AZB#xFlcFBs|jupB1?L?G0Bx;vrd*Dm)lB38^rTcDE?nNAV%FyVrQVqm(DktY zMN)f{wP3zc7*k(`h%JxbGYtgaN^DTAWvB@`lQ2G~=WoW9?u4plq2uHqe!g5gIS=$+ z+t)rNT^l2vLHoi$Xkd1D0PzUi)8cP|EL8KNIDh`_$v)RyG5bx4*ASqYX=4#S<=pAa z%L}C9)auLl8_^I1S?kmZMztWUmpgrk{txS6b@yXWUm2g5f4Vp9JT~ zo{sQK6@N-iS{v;yi60zH7k?U?mC5P&@njqAN>s4#@w1USMqJ#WrN=N;^U&=chQ9l8 z0V$jBuirF9aAfwVa9|kh_J3SHBs(2f)~o(LDpFLjp8kp5@SB_aQ`ee`^1Jn=$Fx2g z?HXShV=_c7u-|Xhsx*HSfld?Mz>JdJM6Aj?@;ucdy~{WicmZz2 zE;ygBpbl6rg+p!e->fKISe{omkAb}X-0vS5+4?&Q#l)oPhx4}r-Vd6dpAq}BcjsaO zKPb-#t~s2FxzR=nbKxE|k@(ZaZytxoF-SqWG{BS8;f|+U-Sh$Ro@3MJ@z>Qikt5Kj zg)`0f$LuXUKx&XlkyJnPg-x*K8Y*q=f52@ zLdPhoI#)HRKG}wbQ+|nUihRHoXq6ejgm!G3EE4*!9}gdP=*uadNM<+*1i9FhT@mXm z8xnmMwZ&g6_G@K>ZSj|XqWOld_91d#JnOyD6-oGnRJ9ZnnOP_zj4L=a2Zg{G)$Rf zYR;*mb5+Mrnik(YVIT=1ES7~P!j|s26z!vGBA&CCR3bJi;#cngc;xWKkyY0nZeqc8 z%=2NLVE1S%m;Haro1gEOGNvrhpm~0Ze%Ow*{dXTf_knggueL+RF;jy5T_-d2{2bRQ zyAjtow}4uU4jsSz){f#`e|(~>d8nGL92Wp(KBj9nklX$WGVD@`dST}D(bdzx?6_Yi z1XtSeb9;Mk6QM8NtE2V(nLG0KrNGtpqpN3pOt5&p*z&`tmX-w4>cq>7oe$diWSQ8_ z3`ExP>ktuDBlGrA!a#C|rZT0g8YO@*e*OKHP-LHbhuXlJx8Gq2VM}lH>eWKR3+=(; z3*}$+GqdP={_NMNe=ILVg{zi9?i! zC5Y+Y9(Pte0UO1EAuC+cp38e0rS}tLd}!#}#)>S>fLV8$hesRt;2*%6dq%=?{|z`` zx7Y&g9FihF9k?xx#mWX%J>8Ht+dDp9N+JDxWwdLGi1Vp*d?p(sG_6 z<0=SFW01pZb6_)r;t-WrFMF$ zibW$fbt~TWkA^}-zYrM%^{@i3{PIp+P0cw*6I4vMrn4#|ZEwvmvgdiL8GH!#t)>;Uz`Hl?o4$9i>j2 zGXm;c94e1<0Fz*xSTmpTXu4H!v*^WJJ_Zs-_KPmZx9ll>_biv%hAC3&rU+{(f$87* z`$2+$8dT?@#2$WMpkidlA2}XC65hM?B;n36tDt0oWr-7%pT4*K=OUlY46PMgaDzm3 z{Do@oRt1a!0aXQ2mMB2Y?-aORhG`T_KVQ_kOQ0nl+kE^KT~yOwVgpA-tzI|U4Mw!2zHTCLb7z2?HujD~n} zI7||Dd^WQKd$Wz0evoj}JL~VJ_|>>+(MGVR1#?h@0oY4>?EYdDx0Lg^P-HS!;Gr
miGfJRd)sw|(3LmByE$~}RcHd3HxLKhfVe-(KLQ+U`6LHiG;L!u53p;a` zD&*I+6OJSP7KJfuJ_7PDR@<@-w2_UlNkhd@CgF%~AoZRF5-VwB{p&D*XY^~I>3l*a zvA-pe3ENW!Uz(!<0LGJ|%>EHfn!<8{6G2l@9omEN6@{i2hczL-rTKe{8 zQ8ID$?PpkE44z7m_1_9V=05~^PFrj-!!T0OsCsQtJM$JF9O8hGQ75*#2mh|Hn(G zGNatUy_*wB!|CXxIZr^yTOI2%Z0IV3~Zxjq*!@)xabfH_u+q#BkJ12lL{kVD=^2H?jy8Yw4&r z@91PAviw@@>H_n|Zrs;BBzM7I+$m1rh<{qTH9USPA$XiWguiYD zn3!(lehi`$jQj&k(yinKoEymbOD7_9ffVmoYgKUnEc^XV+4RB2{~++VBEV<+gASX* zgOnv>;7hzkHQd1<*0(Ya{YqV!@X)2!NjCERc41p-K>}9G1LF;P$E>L<2y|WmoGC5m zkx+FVC)sPt9EUs$sQS|8@%KwJ$?6pN-XyM?Q2&Y}{H_fRv%}W(O3^ZK*~n;+9GZ;J z{MzeG%ns5d{{5`O{|xnbISf<(fM_Z?9PlX~BBjwOw8=?h#OI+SgIM$n7qJASr(WiKeiK0Ymvy z3to%kRrw`V7BdJT-Q0t~hmjtF0Ioi*2Y(h9&V#v+Tgz2uwr4LiRMpw3dZE3(-IjXS zQ&FBTJD^LZuWc41b4!zXW$rHF+J_29@%Ub!WJXSBUm!>rj_X{@Uut#rjs{%jaKv{@ zxG#ch>q?`POfp-kNQQN%x?A@IFn2(B*Ad)q+DUv(qG%Mok1`(^r7mXAlco0SG3ya~ z&=hNCNTlQM*bH=5ZqY-%de3_Vbw3shOXv44Ea~<^BsIYkU%fb&A^o>`-8Zu@x<2rZ zg2{vx0$kWb*}^tyerqw3A%r)t8leE2>FB3$5)q9Ov5fU?7M+2X+2BzLol?(Z`^8hm4)VJ7= z2;2R5rK-NPahydk|8kAuV-DLH2^l(mVW-~DQUS?Fc-p)@o)Wew<#cB z$-7(iTQO|o1(cbw9V;~)(s`l#X`xfYIM72>5 zN!#J;UtVu}!i1%95O>SX(31_++0t3OZEGT|qWXP_Q2rAtM(WH^&%JWCx4K-#;kv;4 z{M?J_cO#TF8E+7vsD?x4V5%%Wxp3^z;nZZls{0^L4;Z%t*LSGQ6I3>(wPXx*I)#cU zQb&eOGScc9*huZkxHIr>hqX`=I}=GU!azXUbMtrwvpc3Pnc#4S&}akf#3xZztA1>x z^>EOH^GK{V^>@%|72!_d8_wK>1>!*I#J|IFe ziWHV2twj279~arRm4`38tr~r2KfiVz`S>4h$b`sD>v&5Z8*(Z^k`0QEF&iUTZxY{zaJ?4#ATf zSpW;jpfsUj=|$ynU3FD$e5!R>_Gg8dhSC__imtpGy4xv3#itq_tk&-q;UuuMq5^sx zX&~{)^gZ#2{==;G*urzOot8aoxHY?8-|ZNxXR*?Vj;ZHBdY8v%$^KfZzms7!nsv8v zXC~@%UMZL4BEU_mv*=VQ?7MArWInJ8+-jou(z+eZRQs_agnE3%sD28Uq~(}Z-rKtu z8Q#T7AOkYtU^4JU;nHdr4VUR@UFS$G8GopSLf9{vgM&X4#^RG`fu(*8RRLP5V>Ext zg5wLpyfEM!CUq7BA*{GVRTAJoEIv$Vg=x@=?~!H}s%=l)oi~fLEcdk6%t!;vkx&%A zik$FsN8xlw2MXQxlCTSvN5|OxQNaM!1bZ`@#`B(c=EGbV;Tb?rQB^;LPJ z;3<=JpQN_Shmf2Tlt1lEl~yqVPU~NV(^LLzpZp!3hGm;}4_w-+IiP8R)jQnfG2dqa z(cSg-mb6cqdBOK|jbu|@#V|{fG)p2_QE#Fx;+=CX-#E44|9QK7}#PG>1qSFCz{At}ohVHRw`y z^)V4xo`yv&O14=Re6tj;aGtzh9HZ6G&cl-O)FS)t*!D?CaE%`O^(h9|a?ftnOM%pm z0nF!>zsaiQpwSuT0-ml{4PtXEGO@JV8uMhuc$sJycMERr5g%b<&hz5dM-|I;(N(EX^vK@P!w#%5%BAA0O%3mAMn3U9j4KDzN48T2l#+f| z{k-VFr1?o6`}mgq9*eO9g%dqD?-#JGV6isfzVrTznf&d#(hMd{a$9BoPH$)nRb9Dn zE}&dRd4`yWOGI-z!S<<8E4}M5eR_ZD$Laty%9A+qE%>1?g5#Z*nG|dy0!w-RG<+j) zk&Zc8i;@Er^Ot1wt@sI%;R2VvG~(uBB5sFrcwduUF%J(!87;{0#<<<+%TK!Nm4X=9 z#Sfv)kSwQgL$)MbMTR^|@)cUEFuc%9FiVf)FA;Q~bQ4aLS*;HA5Jxs%42R$qt}kFJ zkxlqes+t{I-I-40y*Dt8hVceH-W}gV`=0zTg33+@y5(KQ-AUUje@5TcAEMoo zMkkCM$^3HdR1Xw6^fL-lJJTy`dFGWn_A^5?Z|hu-2G}$d&X-F8S}X#(YAT>;JYnW? z#<<-qNGD|Joyo}iswA25?~7qP1P&5JIDY~i)NFn}dujxdn6ngIHRy|PsWopN=P{r+O zdBSA2T*(Og(MZ#k?d0NR#_&0EfdF@J+&&ctBaGs)70x-9-?mZ3BE7f39)}a5{R-X& z)tCoM9HWHMlF#+`eGku2%DSZtf3ql9Q@Tt}8(~iy#yA9A!2_uNkH61KpN@}JYy-v0 z+Pz(J9^LQvLpzgE2^&UoUs$^EBASxsqz)<6uGeg{JG|;czZ1F&DtiFa7I_4ybvk zq`EM7p$AwNko^OQHg9};=t1Qjd?$KK`?M-3AiMtkYsz|hFM0A|NZt~z6CGMM?)PvX>Se=5WpeeV92jo4 zRgB!qPgDshm~?a=B!2|p(Q2*E$N@PvOpiqxCqZkw2r}G{x+lls;p$-W!w|2y8rsdy ztrrl=v1Up4Ng|K!F60);Ff(jNDTXn=cJIQ=iY2(>&whx-j`D95!+hFRB0lQF{#_10 zB1KBm#iMT%B}XYAWm&ufV;Evdqy*a6;&ub9vr+iTCO!HlF}Ou+%ppM&mX2uTU5{VF zP)hCoz_1E(NfosxB=RdJ88X~rZyF+#4~(sJ<+Cw4tGPVJpU0UjH$Keq{7Fe?DT38M-%clEd|fWekg?@W!nn&<*@;cD2+cr3EQof zhg)ud&qw|8iuiU~P&Lm^ed(T*OGDwlj>pGv?W`&kNG8Sr19HGlJ|Hqtr;tA&^x`m7 z8s%$;6I;4zuS2SB&F-Wci|3A)Vn=ki&!*-()mg8`K2y=9HuTi9Pr&DXxk5E*u|d%z zpxIs$EpAB)*rkS1jyo{}(}HEm-^1o>QoWrf8}EG{O+6HlGDE5hx~FMSZO)#okltjY zxs$%?L31jY!7~rKg25Yw_-jAAJGfdLDYKIdIn}UTd=}Vy>7Tvx9#Pp+$scE^?|wY* zh(X%c7#Rmmoe_gdtWGkvU!dL{cHa_1Viw%}FNln$O}lrFBpi_6NmIcTy-Imz7J*s2 zf3L8W?9ius;;kkaY=p#CpODK0Zj>-$b-0RF8CJEvuJyN`q>lvn578&CqVPWkHw)V6 zbV34#u$tK;ZG-3oD}~$MT)J{1WcEd#7|@dxWQ}OZ(}kWk8iR@ihZ#CPc+JdBZ5uP4 zL~XWnxgK0i1`jI*4`|4v2GB(X_e=4m*6QDf0d7sf&91(t<$EC8IdB4cuM*rXA)EA@ zbGPM+FpJ^2K_@7XbtxkF z`G`Vhs4qPxh{UwPph29>At-O0!$tb5;pw?D^P9I&I?&K4n{7rNHAAWuNY_P%nR{Pp zzV*=yJC-vUwu#oA7PK!zV?>8&j1=s|b*5v4=zJ|T^yQr{I)M+MA@jY%B|e5j!5N@9 z_AaJjXSFFv7{$ww6Qh_f=~S(@QcoQiU#*g*XU@AmL-WL4@9+$bb*L0ve_6M-A&-ZW z4pWzL65GUHy&R!7^B1V4TX9dNP&g5&+OaTUtl#dNV84kptt8nDxST(2r*59SvWz)x zto!7Vu!~KZq~%Ut+fkBO6NQCTdK49-iCV#^Zi=1$n+vc7Je3zJ(PZY@v_yQ7SSv6r zfmi((nhzGZd83+M2Cn<2k8gU&u0{v&<@0;mpmKj}Cz0^1r4e$qw!4A~H)N^Z04}#( zG12tbC4HN&HoGatk`olN{Cv8qRZd`j7r2(Cir0yY$~m*^O0f2D=pLFL2J>N5*f%l? zmC7&q^q@2Q=j#i%0bIiEzE>d<%AMx8(Ju%FoY9QeYOVbOieaqlJHLFwUWYZ6+(CQ*l>h|P51Cc zp(|UrlBB`;L`OrdV|s=3K{+$<4nx#5W#ILuZR zcDlD=o_ksSNPg>@Bm2_i{K%f0p#-50I~n`fbgDx-HFt^%(ZkT^p8+Ku`cVyp4BpK| zEmh;OxK8bBg{fzov?iS?!JQcVhq!^Jhsw2#i;XG^z6b7ezfVNj&Ml*LBmMLXhDM&2 z{p7&x7pAuAxSrlQ7M3<(K))j>F>x4KWb`RwMt9xUZ1c)rg^u{#GeK2spBuBi159be zFRh~OBQK`g++NA1eIk>J<$rewxjcBFJQXfOLx$5L{i(FSU=Ue^Dy23;d6AE3!+{_3 ze4NBh)&d}5b(smeP;y}f(&kd{kJV4#x(=6Ho|vQVG>rX28BMs%(Q!h%nXvUsn>;cq zA1V^GQoyN*uo<${&@Nm*hbHSvDId-KUW$7GDG^rcOUzO&cvywPh~L+A{E{@bjZ8jD zi-YNNJ!{j@B(;U4amBYZ%u8I-7TA^|r+!6tb2g|$OCnsydfbwrPrXY9v0C;shJSSV z?NYP*$_q|3KMg)Ue@+ZIgPktncEumlf8YvORPM3jh;UR`h!7{4L|=1Kdp#mT08jvu?#2>%Jj>Rt}2IezPFs zWQCXT%B->5YAp--aQM?^c@_C|yT*fvI!%f9`GT(YEOHse{Y=KMIHpXzjw64^ar9gL z;c>gXmdrTq^w5;a*!}O?>oQ-xt1YB!P*H7x$;WjDv#1`d{cT8m;o|26V()Dv`3?3E z6$~_)N8%>3_7ymMFs3p%RcrX(UeBfD1(S73XQTI6X~BLG9h%#-A)aRpu4Y$8e1kZf zV0=OVZG5vo80m?RQM9~E^YyQYy3C4WD)y)FvA^p{2YMQGAsTO0Z$xa+dozU1NY?*w zBW37jkW2SSj=oy!PoWP?DSF=T7{V|=X{n`$`POB_>L;T5pZB$4L-$%E8zeUXwBuO= z`+#gd|Z0Y`mx9#gGHumGB*b}GjfjpYyvf>U4!gwJxv#)-gStB zE9RwPn&>O^r5!V!f_TmH=B)_|F$J#UBHrV}As~onT0n9!t%5B$kz2a|nbArQ4~ZRB ze{*u!aVAR7Txb6YFaN3;lZ1yd&+q_b;URBLpTT1qbpUWR8~zU(MPDT%MrcWofAt!r z^?Vqp6h|_R9V^MZFch{+?BDn-)OID*7kUjMEh#BIT>Z^k3nV%drRuI}Wx>7WfD27T zrzMk`lz+#LzrtQM2%okOH}tQ0Z!pnwU?NYSsIgbs6!PQyHfsgVFjj>zmY~GJJHkjS zPCaAd%%4V>k4WqAT|3hHT`@=VZwavRWrXwyP?;s}$Y!j)XO@s_5R9f*rceh&HJTFN z?B1sSg;E>j{R{B;`|s@vY{t1&{zH7ln(G8Dy1u<*C?gNDP+`Q$S&=K zKO?3(;|J_j@r#=e#-P^5SW;IOgM81&b9I&6d^o*8?T*QC3dTom;dD1+D2JpM-`Z!n zTi2V6Sj^LogCZcG(c~N-ay8}d7C`i|GF}v5FtS%OBayL0oxNE9JtYQGD0aLrM?P%6 zDUH#;J0X_L^H&L`q^JqC=jU+X+ko&dD^M#+kxP~yQ4kZ(=Q3Rj-IQ>UpT;NZIdOG& zxD{9gg<%)nI(11{-;YBY9a!4b8b!<7PCO+inm@XunFJIex`6fWGBoOe**3TJYkr$n z^F3pY^0*AenRwmh-zQkWe^AIq%r-J3OPY%7T?2trYfyV|Em2`9aqxYczzemG!xc_`%%A9D#>MyUfTIsMl5wZR(`O32 zNiF_WN8|HXFJ2^1q%D{@_|qtlxi8j%asA$pu5P6z(}zhOY7hJ<`j^iEBv{J#B}Dn4 zp-h_xAHIq&ll{s3BUk(ogYAFXScg*m)qTs-MdedcqvD>bkE_Y+WIgiES`CgllVs`P z!hle{)CV3Hm#DT(^ovfEP7K^kju7yY$O55ibqkvGaFRFIRv8HvOs+gpXu=n!KT~!_qsc9@lFuDP~cH%LqsUM3NQ$EjQx|mCG}%`bD0?)@h9-Su5HR zcKRjJsr?~Es+M&Dk#*YT=vb%#s*;KyJ;f$3{xT>U>M)yoPzaQIW9-I#?)3?UVK zx{Ue!>jEVE+Aie@@4L9i6u1cY=^nF%B70`E;LPU06~5Z_!a7?Of85TT^_^H+kVD)X z`50qzQ$_s^y1ImPDAKa{vWQw(cInyYR?%4E3ry9uRa!BV&UDm)E4RVvm2&ddUHZFk zmg0f^0ZrdF@L{+x+cbnR4XDxs4uwhGZkcfuA*xHJM-6(E4ypI0e zKIfPc+iyLv_FN?+O1&C&8V5flz-v5l0`cV;@)poBt>1o1R$Rx``^{w^g-OS{q?36l zZz41KMP9jyNpki1r%LbO@H%Wk%$hoh$!guwQ;j1(Y#OfRvKNgu zp1Vh}tV6SDS||U8d_lY!dB_C#Bo>FgAC)iq2iho8C$6tz5`xj>1c;4*9_Z{(gI>de zoYy98zIYOjc9AlB$=!%zomD_FJ@BOhmjRSiyu;yoXjf^K}`TT!efS>JcPv7w~enQ%Xy z+=xqxVA=Dmp$&R$XGVu!`ap%AUdzg^`0vnH=^)HBe?`4M%#(N-1YgKPh2ul@WuYcKf>suY2Uv)LQl@cEekfGTQKx5Fpym z!xxxnqkCy4$~l}S1D@0O38(fq_3)42zKsT`IkJd>}S`GJ>w z0yA1#s`dPPhAoahW`4&S6x9wt{}d7Tn?QEcX!CkWp|Hv@3_IVfw=gevtetjAd~{~K zz+%yeD#d=SqIoVw{X=3aGmfL^n}%xDm+KA>-JrIhrLz-<=yg+DUQe9$+Y?Q$`iXz2 z++WTpyVhze3HAyI$W!$3{VWw2@xTo%_Oa$+A#=VIsjU#o7pz-4Dlgfy4RjTJQs+h` zUZ_QC-BWFEfsnNB%VYlLRlN?DcwLm)@}|6!s}u$BBok>9fB!n_|8A%A^^$- zP92z7Z0Fb$!my(xk(7KJvCs%Sz>Ptfo(7{u3&i6CPe~qB?78|b7iBCgL@(m~8axd? zjpS^$d=LH%oDfp1kKJVj87~0;+2-%)u}=3_hPjz=;`TSa<%Qzsi}(*qw`L_SvZ#}4 zxA!10)d-hev`;K@(|8+PJC(tB;X zy{`uQUMFr~FLLAQ*kSt(BqQ3AO)!Ibno)IGugW0_0mX5}R5y#Kq$p3m4WXN@i=#V1 zAR@u;ee6RkZdib!Rd-RMx7aQVON_+s3m=0%D2rrr{9lO?8E3m|=8Qy=G52B+(6-@u zJV?Ic*eImJ!}9P-t19${3wWh;|IRB%O!;|=hDpvc@_iz z-}6otMZB~L+`-wKW_aeOhFjTyBHc1cn@Wo2?!dCMsyo1NB!q$X$_UFdBz9S63vRpm>LozE<3J^k`g?m_-|V-|b7PBr1`A-YGsicj;@1eJT;_e))m| z3W5dA7#%y^rt7bf5N4GEk{1RlBlzknxM)7Vf zX5AE&#^K*r@OiViZr8F6?{jU!#^JB6jc%g*KksY!2%w3laIGFW=SCH(1scCvG_QH>(+lq!CoWpxe*{>2OGK#Qu z&8SQCT#xl;-ATjZEcKKbdKq6(iTVVY@HR)5q#shei&$sc;z5>hd1uyq>Xo(nL68eK zj?!T921snujDsU>>1cPe&0KluanwMuTj?9bLS@Pe4`n`Xwc_u{4kVsDin>Gu1T;(r z_*Qu^;`KLd4XSs^Ptr^ljYmC+MO^6DhKpnhMlsuZCx*+=DpF(ym$V)qC!6#ZjDaLG zw4=W0H`HO+@&olyB&t9gsJ?xPx{IfrK0#xH@=@*#5~}tMM7fg ziM+{1uhu!YuH}89(g-vY>B5$fgzCGQBol6`nC6bPJ*@PGm&u_Esys$(MY^h3v{2J) zR$DC<)l0o2)|G=>E#bOUl>4A9xlfB9s?=q&WI(8Y6IU|&;>gyZB%fGrQ{t;2pvBSq zwYMeh-|)9U*s~8vpIqo1+3v5fv=`Xy3y+mnPtlm;ki{s*0D2MGzM?wPyfva8iK75l z?R|8b-zR3HJZOfk<>?v3cJe;^JNq^tA`(vhxQrAF-NeM1?jR(uqfip@PfiWPO5yZj#x4j?h zzZ;f__a1=|j0V8&!z|0to1Y%++_jK2gl#&dBO11NyGC_1S9dxUZdI>kBLj+in8+Wb zswktXrNgA$=R$W@kXg6=%yR0e%aX1%EKjDNJ{akikb6ZDrD+g*Orgs_2}H`~hKjJk zyk(C1y}NU$CuYq*Me|HJLXp?fclk`^taRER=EK`P=6Vo-j?N_yY_ z4U=@mVfo&!4~E(P45l(u)PDFf>BR@QC7z^hCgMEYeb{2n(;hToIdJ-OjivZ!?Rmys zs1$Qg_+VTjHn@U;DO=2{ias;K=?ka&d>~4ItBX8UoaAH8^icKFf`(>1b*&{uGg@$P z)24niz?lmY8!(w9z{`&#v`3yn&`M67h{YpB{4;@*w~<=hd2kEhn<_RFUi^cu4xk+WOn-nvS^f?0?w@ zgG>q%EX`?Fi}tOik8%y(w46aV3at?jQi7ZAt~+1<1^A9POvc0GOZqbqnsQ#ME{$)m zEwl)7NqX@lx5dJ?ve0Ijwn*zyNe3dXYlC2SrSH3Y?;a&La1`G)4L}?1*eN6o+jJFm0r@G2N zJ9=2#j-#VXe)i8mm+v3U&2XOEHwS_O7?b1*=)7jC1@>^%FG}65022l7Of8CW1V*cJ zLJmc9uu^V(5YP6=!2^KRuFrS8NiucDD8^dFL@n+d!0qHvTDQ|9+*6Pyii2CneUN_9 zV93ZvaQ9&Yo1{;6vfiecx>=ef>OPdA``iUXZ=jGB_+G3+2R`T)-zofnq3JWY=`IfJZ2EfQR4xxTJVHei#dW0c&f5 zUUvRyz@%5rfBBj?HIe`VZaZSSkPfbL@W$s$L{TK#2!w8yCh9RdagT<;Cr3~+Y%8`m zh%q9Am@}t^X8*s((DM{|64}WFO)?S?mo7l6#oihGUR)0LaKAei-tdFgxQ?tb5#M-z zS)>qb*oxJxjMKbfP6IZyVvLeevm}xLt419c%p7FLwPR_e)f&^XO`&XFrkOxH|;mzcpfbJ?3W)SHhmp=Q8C8PT7=mi1@;!F168yr6@h8KsDZ zkuPofZ_}6}{<|{*+oj?r@+%Cl)@f4bW`=qHQ}}XGj`-4;FC&{@PWJGyGm*x}9PnE> zeXVrm*|IG0#b?EXJGqi8lSBMlxU4M?1|=8-;4rIM-cz-^fEp3pe#=Ah{P&3d9~q@t zbl7agPgAyQ*)5u@h@~u*GyH3Zi`)HGDhg7QbUffebpZJPl5``pO%2_SkN-lTP#yzk z#~DPG^6g-~`_aDFYDhOrPYGg%R=1;@UGGK@{a&ApP{f~5Na>I03n(V+_R%$h8gCm| zQ&3bxr7hSFvCm47*JO#aP@`mJPoufXL`2pty=MnV@S?d*Edk$W%=z$pSDX7+%Dg47 z|4xb~@^^EueDq|fmr+LfSmI5}TmX101wcU=5)`CWT~Dd}p`noU zzsDTCD7c<#L^{**1-@Z^TsIN_V)emmJidG>yMLQd*0RO@4%^!(2^>aC(WZ}#BzOO1 z3Mx4rygR`E*Ngx_2#*y2Q;!T$E>?F`E!4rUBK$e#QbGLD(~TJt4)xX3i~qcDND%a0 z*L|ThMsOvPuW|%#umE`IP~~}~r7#I%pF8%Br)w@=LFEsgN>6X`*;$ttuaVY9~FX#ry>|eXC$iN@{B@y*`T3RL#8K-$i zx|0z9$Ws5TM~FsjBCP!nfx#6o^5~-;>gYBS>{P(jhcg^7-n_0m?<=m{74g!?Y=2L? zq26do029e3M>5oMwQ%#w(g-7GSySmrhzzc8_ed*}gI{*v&y0giNB|MG@}0ynY=Qh8 z$q%I*rGHoO{qMNX7y0TEv^Di7keGF5D%Uzm@DW1B>}}0nlyOgYbn<54*B(9rMRDEI z&=+$G%?4sczT&*DHx_EBn;Otfo=c&6fn}&)hPmKCyp4n1EvJ_wO! zbqMIT7s}5T33kaE&qMU@cp6%x|W7&n4@T08jiJ-;afg!6N!KF-xgdY zhfb@!)g^_}<4TSI;@1FA7hP)aZv}d@t>sth?tTsWwP;n(=~Ed^1L}v-nUsCXB8o+- zL-hGai0vCL;oaypP;C8j46nKmr!T**K435%AFWlJ`S0dV;Sr=)7q;WbYz~29}_LomXGzxps%HcWJ7D<}yw9%KyG0MLsj|2A03>a#*f* z)WY(FubS~}t{HID^VYu9bJ`LP3WrVbr=+oA7CqnlHO$kosms!!Sww*E4z_K&DPTN4*YT?+cwB-Q`VT=d=mxQN_zeyZJ7a%1(le}WWF|+6KZNcy_ zLpo4O?ph-2X9B_a_M8R73QA=WdL*>KbqqbT@Vo16sNL}_g3F5{!Kj`?mx24;p&sCe zF7T;;_53BV6q^)k z)+HB4n*EkT_)=BzyDL{hFD9US@^!64tBz)ys5enTT^>_BAt-UjJLza05+Mr4>nnO0#Nt3v86gp3H_9{ z+Njzu#=R|n4IDTIu^4}HKi`?J}nK# z?Ozu2ZP5XC*q_AvB}C7bPRUva=j*WQx`)s8`oodq@s=mgO(Kvfzt=enSUqKFTpdb# z8&-CWl(=<0ZrG>ZFrCy4WYSEqn6IVIIu*`XzDFj>dpNdTnNpb0;K}{p?xu?e@Va^I z(3ur!?m{8d-xqH~f?mMHnedN|C678yOtwFI!>EsO)n`lNv32C@_@tg$p7 zp|mh}xwF#hfo;U4qT!5CXu~S|Y`R7ss;R*{w@n=1EwLkpD+GNnN+b!OkaGCATtffs zCtx@7yw^<9(jy(k_*=eRKjl>ftZf{{a1KXZ;*fHOK7=x+@7G&=JaGpv?+BU@zWbxKFSlMrOg= znnM?`Tte*q@<4J~X1C>|!o}~D>jQ{13<(pUNz3xdLbeTp#FO1gQn#K!Brj-S=wo`M z$Ag(%+Xm`I(I(SP_IL1&`noQ4 zCcg49`t8U2-rdJR)~==;`~r$XvDmnO>ws(C-uacmn28Lo5v7!sC-ohjboVjxep^Bw zHS++-lIU*kvKDgCa2%v+-eZr_7JC(okNKHiGBraHgqF#4Io^3{moyfu`h+_fwHnhC zUMU#vBk)L(VbQ-S@<1!HgE)CpKBr%bs(_1RAZV{Uo^FzKHQXl^7`SS`Xvqa8B88UM>y6L@c3+DR6lRs`|uG~D{rM<;!?AXoZztV z{%XZu&ZlpO70UPblvr^h18&h>V#ztm!jdn;zhxwiP4^cz;}_g5UbeXAZIpU<9y1!V zJqeh}pdkjn#dN68^5$c0J>I)FobIs(U<}e-+LGMz)8<`vj2AbS@mJ81i z>Kss$E5|O1g0zzvT<{WT!yuf?OQ+Ct{r_JL;2nnwuXV@%)JgmK#(u?qX2GA?#9iob z^G-XvhIh)V5ET2MflL)>JX{(I+&h4xro1rnUZUrX1+V2@XyPmUS7zvm0`zzo8h3_j z32*worhSInHpDMkcX5^A?Eq#J@DYWO+x$UwqNfepPL{@OHDfp3)=0)H#^tCpTpTLI zC)&r5jr*AMS1)0V?m zi?-{Q^}zA(unX78->wMh+*utzd%}nR#(iWj470*}fhR%I;W-TdzbnZV>;->)DDJd0 zhep{D`%bKuZ%`s&1=k&D6hPVZGQFpUn@YTQ$==-{-S~6k>byox0o084H+^EK)DXuQ;u+NspJ(s z5+;&1K^E$~nLPitloAXS+U(!%qu0_aHruUFgYkl^y`N1_ei9=W{<9#`6nuJz{V7_D z>RjD%czTfoW0sAfGR-6 z(NUSSe%|13%R>gUzIBMqlJnN$-wnxuH zx0(+d^+|`kyWAh`-Yakqxc2OX!Y#T%=1EY>^o(@(5w12DF3FAu;A7-Q1zggMC#tOy z2m7SJJ)~*Q>iy#%g_^*EooS6xua1heC0Rk_IV28y6#u`1-8Inh0R6AG zw~mUsi~dH3?h>RW6$V9GN~B8#0Rib|=#Xw0T4|-b6r@W)B$b{aMd?x)I%EKmzGr-X z>%D8;`>yx?cV|6o;WKe!pBEVaTO`gWG7~4R_OgH*Oka76Po~r4`-l!Gl}JgE+Q$M z6rSeDyTRb1n*HqpW3^1!%I~+EWZ(Lg9XVFbZ>G#_M3-zHiD3E71;_l1|cyqm4~L?HLG?PJF~of-R2CrQ~rL`rvU zLXu5=MXk{(j}fiF|G6VRXT6^xGH2|BWs6IXGr+i~(k7fl3Kfe;9;@CJs-9N1A=O^o z);;J^`s?{-y~X~M%GI^{#8-P6yXa;HtbB`^S9B6p+c<*=xfySN@%-8aT)T>^tH60z zYI>flMULrm?K`!1D~I)ZD;yoQp+~v5il0aY&s_|%TbFdr#X+nEu~g@Em|-Srny zcm38xe$*(TGllzP?NO&XTdfPUPiViQW*XJ>?oPOxwz-EzqN4zz`v!M zK=n0QW~j96s9t%_Is9o{ufo>+g!f;qS9wNV482W6j&<1_ckC6!0U;_P8t0!n2-~y} z$3;RK)Sar%&qYI9h62pEw^f|@Nt$TQmKmTWWDs{=2=bU32c=1|F>~cBZ9VF>ussL* zL{xQ_hn1K8T`eIo{Ktj8AC+qE%L+{qq^wKYb=ds57)`@!Z2Cpibhq_pjTvq1TnWEg zpK%RhP3r~QyDf`W7)9#S8rzxntYBiz-o4WlFKJl`Q9JxRtjDvsY&e;+=(|jGmp)ek zFJxOtbJ7>|t%$ZoGnr?MQuEqx*RpCrqzsyT%wuv8)oaEKB-NYnhMEc018AqKgLkWszpjg(q zCtM!*fGqcnd_VTloTCS3{R_t+C~1hB^p3o+Kq+pLt|*-5EX=s#>^$uG6tH8YP@~Yc zatj>M23?(&jxwj4P3HGnKdQLo_>6s>xO#iB#^Jrp?ii_f z!=QlZ!JNvQ8+&iI&VHN-5=#*ol_l?^tXX4Bfj!^`z!j@J9NkNO$a1e-rshG=WM3}rHDJ1pI7M-mX zR2;nz{J(`E9xrur8vq)saY?En#7RG9%tXn(9k8Zg^(LPszlX8Ig=2zn2$CKP_CJE4 zo@f@eL^R^-yD-{r-?+$*NTIoQx#}$GcQ(j&imLk?wOWtIuek9&NAd<%Z(&n7SSNw1 zH!dRgneAq}bH?}jAzvRa4UB{tLMHW18i@E>ixa1;gn+(x-D&Fu z4cn^mfcpL}vN(rW1ZS*^!C9Rm$tq%%QckLGodvW-I}4O=8FnJmeIhLuL};?!V+xDz zOL~`rzEzW@0vBOpc0bp?=Mzttxi0=hlh3B@w_9zw{i&6aU|Y%4=h^cc*`^hIG$Yrh zi`NyuV&~qy6&~*>2`Oe!)8@bN9CrBXat9APL7^5)bxk7iMvA&^do4q&<6WjGds(5) z%?DJ?ZI!C3)Eae2U(@uT^e_v$EQ(nzgV77F6?fC(Pv=y?&of}G-%|4gJ1+82L=A1Pva1Edc8>XD(U5Bs+j*L6AWv zJ-rhyOb@%Pt=wA@jGo~Ir!{*02&~hxyZybRl=OjRI413uT}z%P=T+c@BkMc^<2*K= z08h@DYyBW8XWy?MOlO`GP1l|ANS*Va;kbGCOv!JdKj&Y+dnfLMsCht6d4%v|dcXx`_ zkJ}u5J{Z13^6tfPO?)j${0g}gX8}DpoC)}(j*vargV&?l5>fNypH#Ev?goZZW=U&I zq{z0G4hz0DQW{w70|=SOw`c9%Kb6)@fhEy&!oI6MU*n=odOt`9<Zt+9Y&YgNUZ6C#bvn6*ULPh zTlk=lltEWGKLWcD!;o?9WjGi`J+(Jf&%ud&mggunRC+%*JMA2G?Q*tUd3Ii2ARdz2 zFEs0%?>M2wJO+tO z;6o(to8u*6!E6QWnMecssrrM>l263!14!$>z=bUvD4K6!conL`JICa%=7v=N%3--> zl-%Wn+|wujjy3X%%rwLZs*ep8cwe%4r^0Eap@r&f*4kNT&qycbJ#Y1-7j43YD}sFT zLHl+2pU)#F#&j9mt4@>HXm+Q8E}%>m2$HZ?Q}#9kq>wi>Q;s9G6VZXhwWl$#S+-A` z?7Z3nddHG{3NmW9pvK<0u){*)%Gu!G6=C)h;elMVVc=O(U;G$*Ryb)bI_~s_Ac9uZ zoV5_UV{enVFQ|k0W2iS7Nl=_-3-9i2Y30E4*3IiKke%r-;6=VMx@d_X_RunRPJ>PES#h$o z4SFHW$ETi#C$_9LAlSy{U2b8&n}KWZkU$vtg`PtYjG=wUK_db+{$858bp3`er zyvnj3bAnG>5~s~WSLmIw-fGblFeBG!v`O8dOrfLRqtTsqtT+WTBg(~>+IT6?%&-US zv4uthu?v`EW?5uo$-b@cXB%Fjlvu7b*=X!+!sQR*cyuq}*5C>F=no}+uS^yLv;s^b zBJB)l)ODsRCiIXoO%b?-G`MnbH-c=e)#W`hHWdh>w-O@#l!pId;3REK#bPTjXT)ak z;J%iWu^pNPS&iDpE8M-zrcJi@hunCnOgMlG5W;MZIJ6Z?tVL(-1P1naln${+#O{={ z#l}bb>i$eAITY?x&Q;@P?|(~O5(>B4nR1{`8j>QVO)>f6N(fm$?C4ll#-VqJm>4Uh z29}%G9tTdEgM)a(pI0sBlblH3w%|E;Ka4D8 zkCD6=YQbv8Q<*Y#PSz~B^J2bNe{SfB#l0pe&oNJ`=tRvprU!6lT3&Zo+0&+ktZT!g z%Q4#blm&uK0ge!EYVYX}J>s3v-V`%tUuCE7KO4z_B2x%RL(qHa2IyF~L(;OpWRaZ* zF1AkZ$C3w%l11AIrRkm(?$}n}rR*b4>k@uK7Ng+62`7D5lIG8sSxHxDW2gG1)#>x< zaeW+D)4Eo9G-s%7k1{D6PRz$!ntyOBrN6w3w-vHpy~CM z*#j0va;_5WH!v$QS)5lNA3bBzj#iYve*+7ZMAxXZ;$!updL6;yELuXCz((uD40#4a4|H{;C!V;^X@E+Lbc&_$-E4ZTEt-$VMkm`hQMNV6Ltj zroKP%Bm(|8p-HTG4Fu(fh>OV7)+sI{@$+ScnQp{{%!4F#=J5a}^m=IYV(4gLKe#zZ zCd9O$nbL9k^fT?vwy!N5lv*Pee8eA*QDIJQ!BBNZ3`uRNR`c_@}_A0$@WSz-fF0*c*5psk0|7(s!PqB z6yjtlONR6cmfKLL@0B>TIdZg5)|mtWx1n1L-AZ@qqG-)s_ElFuwzy? z7p(z^8h>wjYV@s^LL4v2C=@+1GUDI4l)mZd&->95{M=V6ZQM=-XN`uvf$^ICSiS{MDMYdG;p%Cm_OJfTVA% zG;_g0F-NRZY=K_v#p4?pDlK!n^^8UlsEnOggH{gIDcbP0`bb6~i5EYcsbu>Sraw}q z98$(A738pPOx*CNLKI>RjDT zag+g?7!fOlP;zxQN^}?OHOQ4Cy+0SFF6+wZ80*tA8&-6y?|Jn*0$H5MBb+Ae5-BtA zj3U7=KTXhawcnkG+Mi0A*&(K|X@(obq>cn`k5zhTLyBf9H|Zb@`YKg&ExbpTlDRA- z?GW(DQ-*VyRr-s7&~ASwf}q|KH8ZS%>9D(@?wKkQ6oUg5hwq{J?`xc0whX%#a0OcV z_=*^6RgpHf9*-rYncq(&0#S}*gx3$=nEb#(^BGY&wkn%_KOivbQHn|HC(6h_gT#wA zLD_HO+fao1uYY(Kq}VP!gwh?};m1LZJwjwjeVE;OJ=mJ_%NRQgi@HY~6E>>HMIfaR zj8FA(koJ&rZ*%fTFeY|J!uLen5TQT6jp=bw^dt$8i0KLCL+_qn@9}b|V(1{y(D+AE ztoLPGGWh+1i;YuM{InK!V2us2N@7lQ%O4&NWPO9%pLn;{I#WeteXfb!?$M#geW?r= zbbj(fxj@83l@AX!U(rUGqTa)O{$YrYBgesnH}H78==|(s+14YgI6V9uD$2*L5bHB& zr_1dm5}E-Yrw5nMpFtXn|GC=ZqCCln? zocu8GbLIU@rR-~t8n=V<-rCocjR{X#|!(1{8SK+b388P54bs0*^##oHa~6{* zs{@m>Do?ZE@3`qt6ZRO0tAc~5=z5M+xvu6`G16~(VDUg_JUdZuO8?i4r)pHJXfNaF zyfr(10hO&X#M+#uRVTE5H-U_O#P3Z|@BV2VL*B{!=dg0vln>S7SW|Av*`QZ>*Y{8= zxJ~6I#SXr59gn1Dg4g&rUwFJ4jmysoy==G*gc0)2wU$YC(n0S=>gkIIX}#*M9k5|< z`>1qH1!nl#TI_>MJdtrTh)~nPMH4oRX7cv8yryBAfjK9=Tv8Up_7ix)%zApTHO_n1 zZWkOj#Gx~D3f)bzGIYb|+7%&_>|q=mub-n{P0@ExvJ+dI>}?4b=jh4De>(qZwvYI} z

ux29GnTBzPd#LfC_p%_MgwM^3*WQx2Ll!OxDcV-sb$G<_ejJ!X=HRFCPm3_2&Jok z452DbJ610SNWjZGo0qAsD^DYXVy5r&NqozW$UhtMs{QBeE4r3U#$IUi=FWwH&Ya`) z852{s44&Apy1K1P?N^sTyv9@?)-lLFyO9#mZps7YCq}*`YAfV_K5OwkHON_BS#3C1 z>9kmHW=bT{hxjmP+>#WyVWFb^PQpn!Y*3$869XfoWYZd-xu~h_V;jodd*@0UOs<5r z%s-dFC|u@iqQ!#QdnGTbGMO}v2v zVPK-hgJ~xjt2L$~R3>82ByC1_0~sHfdB1r5`b2_!RR}+iiY>{(3^Fhj%_irkyP;Gw zWhFoZ|3Le}46mnpu4&-Kgy67j!xA3rD}2Z%(=5D7iXW)YL@m=*Ek2f2k~(>_4{XHW zw`+e8{Kkno7R5UwGB3)vQ*mfQlS<&Dz@xF@Ukbh#&+mGJ@*wbsWQEx5SRNaccp}*| z0viuS-OducAp--1&^bhLjv4X<;y5SZ96>x?TSGW_*tPR@?KI%~Yv%`4u4E$pofZ?N zPT!As;Bi$SXi^TxVwJL^tBzh)iH$qXG(NdMmeaS!GG{D*6y&h` zB{uGExO;F0D80B17GVG+^#B;M3w%~d-Od@Ctv39~su`Q&FmB+FiEzV(# zC~q0dte)#i5_dQ)vs?wc+Uo&@~TOb>z`dZs|_Sb40 zzpjZc8s;;Q(axy9!j~uP!b+;6)65G+&(3DWDHlK2%sYXuU-JcrjCVFZlg<8#T{s=r zz6rmxXcGa?`aVm*)>>y!v2d6pIr^bdw#C8!QwACueS^S>L^jCJA!s)FD>GIO6}An; z8p6;zS0-{~X#ne>r#OrxmM@&S<=*#N=PMn=HsTxp3jHkNi~J5~*$Mcc7iklHx)p{l zif^{>&zk+1ZlZ!iUs*4w&Fh@q*2^wC&B0{#M34Z;B8X&94;^YzrFbNwi^gJf>P?qT zysr!F8(X(Xo<4yXln#){JDq*Z6*c$KDKK8s+Vhk&Rp2*v?U^l{P(GH(x1tS?7QMrN zSgu6lBgli?{iK;_r{C{ETA+SpbLIJj)-WbU4R?BC*(4(?=>)rlYHI=nv2nBc=Z|hN2?eRN*0P?rhq@n}d&$k*CKS0m*A@NV z?y}Jpb@^wF5x@eAQkfagO^w;8OR0(~ISGEP_76g42eyTgrqi>x6^=%-e6=8dL)Y}h zAZJgC80*Rh!(L-@_3R-%L9RIhi*?v-5+$a4ST~JQGyogwrX~) z&a(KjGkTzLm}t?MRl1df!jLSHNW(bW+70J-w?2NMhH8L5RBi)cv@p-{?wsqZi={M_ z#&OHw9BD7%EptnRMb2o$=hPK>#KEni1;WB3Sv=ViGU++MPsmSRJW#V%?_E2g%*xmS z!5Vj}6fG}R5{3w#GdUwFd0Ap-yd&*N=kMp=wKdv(QHYy^^=j_=e8H$f22an%L3(7i zts05qT@RmeBVqYhwr?8K+L;?6D2kvBg_EFV9M+6HNv|jMyvcywSWVW=V(TpnL>A?> z?VnZ}hybSaot)qFrk5<81TAr|kK`uD$CCl1T;JKrAO1zQ zskzx`!BcCL-^C-f{?!uZa@jy(d0E2U#MVcU`a7DmRDPoYixa1L z`=@y-tiH>kts42#L6!pa7_@wO8Pwvvo7MLBSFHQbuXyVPG~Msw->cW9rH*tbJYU)Y z>w;52GXFpjPmgRv{@7CRouA5_sa(Ix6`|~U_h^_lJ;j0w_{+ ztNK@Mk!D-1b9vuSp=+oW9H6{kOBXtSB+zUs2n>&RE_R;H<7x?h(2XviwoDFMcObRm zx3;v@DsiPWms=WZ@|>ey$@x-TY4?`8lX)==m%iHc_9iE;+L+46M6i|*jh09C(fC7N zySQ1|{HsTF*eo0Tv#Qw;6a@ZZ*IKy!XKNG^7NkWhuho40oY06(1P87R$G%iyvZpR^ z!W|MJ|JXz}s|@Wc-$u#Q;0Ss-ecuaxU_osP@B$Y8(H-Y^&Tw~~Z=Z=uDYvu3(iz4Y zTII%?A&??hED&~R7{eOE>g2^5z7nN6%Z|^xDyjNNhJ|>7HF%`3QtT20R>I%qIbA)Xe^*Qnqo>oLuw9cSP`X{DTPZ{`$aX#Gv; z8fYXaa{;Nd!b#?(0uq}@yrGP}ClDv;jSLoo2-{;IR>fiYRWk!SF7t#ksAYFAx$O6g z(C2EYm&Tnm5o4~h!txM~-O^mByC%7FxR^x^Qnd8OQntSvg}ewQcE$$5>}w8O7_REK zXI%{JlXkL1vdVBF?AwocrPXH{jjkz6LMf9JL&jdvP(nvt=heB%vV#w=H101jdcY2_ z)jQd6naBA*((&M+C_}|w@LO%2z9yQ00FC=+ooUj;{kCKl+zfje>^v#~h5T>9DYXA@2mIZ{=Da zUy8c(C#UcJ@Hz+mh#I#Z>sVF=Z4`Ri{4s*nEn-u9-aB*xpWX+y`f{r*bgj$R#P z`2FHk-VMux>C=xRdF_)k*@jNC*H<>CY-icQvg&<;tVkhD-OPnk*S2loXrC2Evuw== z?6=o9G;p??Y5)~+;45_wda^nhs!5)O(#g4A4kN{_V)aL-SCU8;*0egVug>?S0{&Dw zIXe$}N~VIA-W)>b*Z(}{;-A#eo#tIlvn;jQ_)>$>Ku^KNft_i#zQ`-tFYy1{W4;Sq z)M+kZ#&~NH#$kBN)OH!1#=0iIf|vQQOYOB?fy9w|k{ixlda*Oy!pH&uO%nay#xnH- zCq1YU4@SdkmwX4?&Sr(wF$W8GP53fQQ(bdJ?$d_)2;H?`qL4fUT(qAKq&iIMkb4}8 z_LTyz(1k2(!Mqv|)>|9%KhD%+ag^AQO;#ExG*Ow8fjqi7wD+ZWj$g{Uf-og9$UNL% zJOWjy{}v}|LJHb=k2ppHLn*tQeB?@NDCK2YgCc1{-SdR~sGxKnJUEDfo?m!`-}DIC z;fWpcU*PTr82v&v4CgOmi{1>R87;4vDx)vp)YNHtUwWP?BxwJnu+ssZ;`n5*y6Uv$Lt%&>;);QsS zeB3R0P&@k`tzXx@4zeskymypVF-cmQpnQX`0OeSm<>DBFhb)oc8etVKY|c_xo_*+E z0R!bLKW7|&%0t}3tb(>mng_6Qs%*TmI5=^Slrq#nlMnkqNOO%{-iZTfG(vG@P-1Bbzw(ISBj;i11jDXujP`-@QJSxbMQ503+FPY$>C>O%=`tQqx zRS*<&Sh`=z!ClVpF3H$ARPt~^d8}}>P@)ipg)#Q*g^T5p%)g1)G)-?7OR5-C6wWR6*@gs5&9g(xbTMag+tTOX5RfnQF9QLZ+|?I4-bwJ%okU za()8zyz`JjFpVMJP2d>CP|1&nVVuq{=9*htBkc%Y0m4Gb-&nGoaC&wcJZMc-)u5fo zT|Af+C@G&@i>=6M4&KLw>Zw!oTS!MxQpUqAA~c^DsjEwYc9*dxmA3sqW{_W2(TsldRT*vg=uzl0`0-QV_4^rFBwL3wlb z6lUl;JMAII5jH5=4$7UA{2K%F$;X~zWA1G{@GtNITPWnw|o<1H> z$sRKTDJH4-4P4-w#sfsdyoC#;lg%6>`S0V~7})s@C!jZu4zoP)dEq%V(>5S;G*-ZlTI`L_B>2Td9P)irNwje?Y!5N2?oc_ zEH0L;|2O6Lt@O*~NBe#n>j53>0W3kwp#*!@mWx!;8@ix zjFz%*T1s~=i>y0!a*eUd*=n~6-Xjds1;KX?00Kk)EZ65>PbXeZi+qpjL?iCSfwKZz zxOb32YR0_ zB;ntBlb#MY*w3Vc237x^i!!EZ0%olLufGN_mVU&mQh~+BNj) z8cZnn*(NlCrrtK+MG=fPRI#-G6bP4TO*7gDTo<=C;95DzNKjCn@KB?}aF7ia;Oi;0 z&9VO@5PApf3Yqr%) zrB*{S1uzc)z;mg`$Hy;{oDTg7v4)7{T6}%6z;0p~-m33=ui#r z6~sCsDINqxwuepoB!1IGgTm%&T*>Br9s=~@B(WRbtwQvq0A>hkQI@xu(c~9%@IJ&s z`3dDyv_jIT>u)pV3ewf zwM?xLa9H|2oX!wNDev4^SI5r8#3aN_jsbvuD}pzNITpsymz+qUMuHh28|jx-OZzLj z${*O-)*YYTQr^uLDdMRDO*4e5YHE-m=CHHBkF*ncD{MPDIH+9;^Er7(I*IS8iHoRL zb6IF(k0u~Me?1%>Jl>wNLFI~xit2>bQ@p{#Dg49#Q;E-OO)Kw&m%22LQV0(pIA!GI zsogBjKSeDk=&Spnp}{p;)}TOD)7mj{3IXgG}!{y5ol){Y+NXy&3%l_to8z^%Dj`4eya7bFxP5$3i>>^_9i>DmLHo8lrGyW{Ve2fYUpPjzVP6#DDIJOd zgiRh)e3mcG$-Vz+B|~g~rbddB-z4~PwXvU4lSYpCAD;`}`TVLXveoZ{$sCd5#+L3> z^6CPVa1<1OP~VFSn)}{WRU|tzLB-hnVa9 zr``R(2A^c+7H8kOlydTS{Qc$pj3I*3;cK~)sy8v>(1KP;b>vX3zKcC#77jx3=rWCq zc&WcpVu1XC;hv>t=g_O4`)7MI`|&FM6k-PrwZWnc8o=rgnhPWi$CLS;qS8^EtfvDz z>xN(X6fXjr52`tJDBi{zXEoUCs#K3x(w%mO0*M(^0);eAL$0^@6%|)Q2|6B6PENwa znV*ObZWIt=WFjcYL{w}Nw%$XOX_FcF2V@Fm&O)w!XDBGg)(`Es;iOPG^p%+sC(zK< z)DuG?!tx)=fEI`YM-#7%uIs!CL2dnbbea&&nx@ye_P~8Tm(E&%KIw_XMU|RjiTg^Q z`sqb+etP2Nu?mWs^*Y12wTYXfi0@W`t7e`Wml{I^BgBJRbT|96o52MEXr@xwWN2oV z-rcPrAtjZfB7M%|x7v_jq5MkS_xLW6HmL;OL*A8}-;OUoSh> z?tuQl_XAyJxPI(p{rF9u&bzuey5F29Sui9%Myi7~J@)b6|&Vg+cZ9t)YBo!#)Z zuSJidx3Lg)9$oSzFjj;m(Uz%t`&NSZPrx5xBC9=&bqLD>Z?G)7})L9ea5Z)O0eMDkW4acxfcK5#5|0uIR+ewE6BMtXf8mF4`TSZw_S z;WK!hS9LRi8@;!D=D%!Ul{Hr2%z^Kpiqz3={twEYW^z^u$qLj2end~WWZX3p8fbd)fUuSSOPi(Fx z@t%WMpWNwWl@USr&zIhx%(ci-^V1}Bd;=ESz4KizS=vYTf(v0v!2D=^ zMURiasmlPa#NE@Y7|L=2grE1jr|Epa`^-!99gsWii)WgO4@WmTPW^FN_Y9<2V2qf~LYUnORtx{y-A@tpNAjp2sf4F94=XG<->~eM`5W zxdmV@P8Oh?n3mb`#nxQ5|Sph~!(n~I9cvx#ALnqpv` zDuK-aF|(=8t7BpO`z3c-NbwuSVlT7{07X+x8@x)6D)ed)S63Y%O>Xc>DG&ZAdOc^Y z^Kz~;R|^>Z6lM_*HVXE0#G^iNhhPz%);uKcDU>-x{u>3*uy#&(I8ICOrN2aA^MkD! z+x&&r;LEc*1p*Ke0Ez)bsNMBDd=HA|eU^gaZvVquLd1hWh8k*1o7;Dtg;lBsrrL%< zJVdzEg~i)#rH{<-pqK8XG8CQOd4aO6Hfa?Vc9P6}0`ldJjg3}$D5;BIt)1ts4C?=I zlC|1pu$ics80z`Llu-xD$Ohx}^74ukpa4w?2ngz%o4L(S5qf!b_=xJ7f;k0nGx~%^^A*p zW@#xML#tBh<1#TL92nIbJySm=aIM0&lsGn%KgJZqZ<9;&{I}}8G=tHD+?_8$kXJ%n zJOiul)leJent*-|n&P61LZBS%kW&6bBM8G{v@|C4bl!P=o)~FDGeH|W5T^vB9EC`| zhh9zAkaoG1lJEQLb#o^sJhajmZ(wo;n$|rGo!&pO-IU-;ejT{(6I=?ca_~LQ*nbGr z(B9To1;Cg2Hb3pFO_|G5;dLjL>>S%x%F`_F(~S+)YO_v0{G|J90opfK(PzOI{UJGTl>V(XzOkc&4`3AK;y0L})7$g?PBY+I@b++M800*3 zjs}v)!U9&T2OvP6FYL#0d?=bg=I@sV%rsyf9&5U^r^@rHdD<-*mti^oA>t2Zd!JUw zfwjRfhRkWQj6|#{G_7i+8x9~XX1sVNv41f+is0Yjwz;A8uLdSGWFED+qYyiqX3q{W z6m996|C@i_l5Z99-w8P%p9jq>ETn=f53T`obE{RZLEFFql7P}NfDWI7m=$i8=I80O zL~ChYt%6x+=*$AOTo&7SfHI&Bdqc+t@N)kX!|N`J3pj?d+??_MhW$m|bpfva58&SF>R___@s_UNN$b*m%oP{s)W7Jz7+zjpHc#99 zg&8gIY$89n!2^WlPqRBuv-|S`_9TGVf5sqDpmJXYR#_r|LG^51urfuto;SHBv!2(n zTJ`*+&e#(SZUsOMvx&`#QdIu+VMs9Vs@^ISPfS329%*#9!Of2Kynts{Ypz#ob>%0Z zuqx~MbU#bruh-lq{GAu|m}7Y$b~XSD6<(&lGJom+N`6-8KO1MgdKj3dSx@{N9p(Q}gPmROYf|H00{AyNz%VoSCie z`PpR$Nbdq_0b8|nF}%ckjW)Y_Y6JPFBR{JHFoD^Qgrwv@re8c?JYjj*#f@&;=BxMoL61%SH}A~M%_U!6US{e^ zXwaqWZ6hZJFTZPC(x9sT+mj$hO#vQT1u}}!rJdI&*V2cK>$-p4HAff@fojF5iqrM{ zbU;4&#gmScs;PF@DVyS}vzqI(NZUL=WuT|I#9S9sy1Tm#B)&+Mn(Xn7QY&7kgH8R@ zh{FFxF$MvT zT2XLO2+~o%I1{CW{H{*dF`hrrNMu0AQBq|_n$j>yWU2v-H~?rQ?T0j4{5m9y;qE8; zz{_&qo0piGoqY?8-5_Q_0Xxy*lZw?S%;^8-adl9b zQc}R&jXNUIkUEIK#N~m8604X`FWnz_Xb#i}@cF=iz|^RG7PW~YDQ zrpWxMOKiU?X1&~Kq^te4McpTUqM7If@QTk5`wa?t>*4sQvnQ3%reoJ@03*}HP zRa?$%-oL)g|7oD0sHk{E-C$UyseAME^b~skzLE%|l7$8P-co1c=g*S2ZxC4_w|u1% zK#TA|6Up4D>g|mDd=&xuo}M0De}Dh4K|w*S&4HTu@R5;cJ|Q6?mVtrHg_?vUBqV*+ zLG?thQ^tlh!hSgP0);)cxJa%(;Y&*eUY8NX#KgU_ zzCHhB%xBdWEkz{6pkTvyF9y4HA>qv%s*g=gmM>o>*;0c!$3;t_U{>O!D@hbGzQ+%;eKfqVJybC>CqsVq>)hUowv7J$mZn>FJ~@_&1sW z1`+q!GyYswMx?8&``cGaSwC%(#AGTykH$mu1q~i;EZ*+!uAQT!0x#_fgEAoR$KkJa zCH4a&BLKh(D1ROv9ksf?y8IM)DijkN8!t!k&BlU!u)JIz++v-uSLC1qlg7oz7nYV1 z0EpV`^xbM9rGON&KANu~CL+?ce)whO09@*v`*b(y+vlO4c+--OE0WwPZYM2-S83U?ivDJtF?!9|jIyw>a^TvQQR${68ylHO7Y%p&R z^Wc-cTh*rRF##ug2Tr#+I5=iGZqrnh6PHd9f&Y}WC_#zS*NT+n(OL!uuYr5AyfI$P zFv0ul;1g8_>>?Ww1%U_~wow3mzeE^&=jWOG`ufJ^=2{C=SMO7$U@ZgRhp2POwW7LO z+09MR-Q7KoyQ}TP=zKG;9(8#+<4I|0soVO(-xrH>YeCu)gnQ+Q{I} zB~xu}oWy<{uw`9ci$+7L#C|HU@z`FWKDerD3^?>W@iHM9KQt~#xc7ot1O)}Z2xov) zX&Bm2&g)U3PgTwN+k&-Po3NQJykbSu)6k7I_>T44}MHee%(I) zigK5m_!zfv4t7FIM;E{5((>!Cj(J+2oBi$d>>=mi!?ocoJq%kbwk2I1;n^A(FrW_) z@nuz27IOBrwgb^39Qj&D?PwY9bB>FH(l^ri-yUAXFZ!|KI@ z&OD1cIu@H8r}%uOSXS58Y=#Weu5KQVZR*^`TOMtSOSM9+b~rh4$Qj80aVX5d%6#?e z)y71qAM9n?&TV#J6d7mKOR^s88c3^@SY{B24q(dy>Um1WM@Hfejf_}YT4Lki;0ywn zdOBpf&gF-!?{Zh@3Am`^d9t?vlv^|sg~({+*7zh6UE_3>HrDoHKf5Jec`+-%3C#3r zBjmPO=6+3D_HB*Fz53Gq^F#&ZcXf0he66E-fW^j=$a&+nxxYUnfCL+xo0*$iTW9?g z?a=A1(BHsN)y>Wt>Xsw@{QNX&dNbnc>O*D%lkd^Z7phR z%VB4_t~(=+UGG+z4&uY@r~9!j54z{+I74UV6|BeyNCz>8v`vCo%RWsF^q8w?@poDj z=y7NSs*Tea>9nc|jVLSQiAzZMb$Ym7gHJ#ZvhZ!or_EolDoFF)_qX!SNE4 zki1Dww%R!+>mux|kByD6@~~=YDIaM#!N?dHd^z0nk` zzppL>;t~@}&(F@T4uKbBCU!~RY$aY_FJWZ-P|IY0fy1JKZho`{@{_T53MI4_NTvk!2FPon7 z6CzeSuTn1bwoBPDM|dpU>F=87&d!vSanc3MaX(O<@`aRK+}tt=adD(=LFa##jLxu^ zZL3OvH$uKM-!ftJ{Q28;_m;R_iU;c9-9P^tjSeAnvoYs&behEb!;+z#4a;E43+Oou zH#aRV{RnRGGHdfaKzd6mBd@jR5KA)QLAz$oeN5)g2}n26LsQaUEWfYC8( zu25|dOB(pWDm$dAP|Lyy0QTXbR7W#5iOD20$v%tcKsB% zBYmT8?hOKw-@E#|2Fl904+4?tx+p2>={bA)czQc~zG2l+Qeu7M<>~0+<^Tfu&*d6A z85yGKWKNebidwPZsal=}v?QzsiV5K~$&Y#1NU1bq*$QWA^}Ft>s1Pys7sTH9{5kw1 ztv=uFc(NJdRkotf?~7yO5f{rr#jaBwr)$6Q&C{~$HAlHkBg8*QZl|jY>5GKlu2f{c z`}cj{uioWVe)$M8@EZ^nNs~RBH;&^P=qyxPnwR|taVO}S{{%S+=!bUpkEah~2$Y+O znO4`rKV19alPs=95>5k>5B#iH29j637M}a%u_35{2=rp`mE8(R?+NGyXV}^VC_MKp zGw2$~GL?;Q>Vd|(3`q~QmF-%3? z2qL)+da55A#SJ0~0=?+x;P3~1$OO@-9-2xY@YYeS^8lX8Y?OwAB~&6TNuInVHZ|pE z<{H+Z=cN&SdHrRUJpa#tOa{RSVamTpLm*H=GA&^35zc@3PTlaZ=;xL@wof+Uw+QTZ zb}M+)Nc9_e5NO#abPUfY(DWc&>Q=ZrzUa{|k+ThXf$wR8VaDqgPQTstmsp}{j8kz@kp?gJx&qA-ScRiVE+%vcX2}&DFXWX zTJ~B{@{ag9j>kk*njd17p%Oie-Jvp3O!6Q((qXy(H2xOxS z<~Kq#$@P(dK*|LXJYN+UF{`hp>dy?~jaZGFQYruo~1@K z>dXAO-K+$y5PR@JwTOJw-sf3XB3(iDsMog#G9N_?*GH?JDd!SpmHM9k*tkzD^vmrj ze{Z*9gE${)%B#T!_L|$(y$`;c)ZA!~JAO6N;73Fqq4I-Nl*mt!^(C`{y4iCxof-8C z)`wu>yK|&sq&Gh3|Kwy(snGiNxb5!wulsg_&tlBf`8cMi6YmL71;r};5(87mDG72y zldfwtlo*XukE@P*7;vEZDzk;vA8@1$%-Op(5=*4=vGVput>&(FuL`X)uCg6klI7aT zzb!d4{KsX0c&*8RqCyFyZaI7rR4^{iGFYrAG`cI2XrWkJ*kVwxA5(Ep*f&e!_j@`G ztNp zyVB9iO8$zW$)AtSm7+S@H$vpsspgb8d^305aMp0KoUEKqTSoG@j=##al(Dc~*$?hfzWXJw((R?C70Zd+NG(Q(!3}Z6TjWZuh)m74saB5!X5O^h!Y+5`0wYAi*>h$Fvz3hpsSN@9ZinQ30 z;F7uRkl2sb{?~YNEic^hd;XJbR#Z8A;R+d#aUo58~n4Jk9uDq1(^h{Tx{)wgtk8BnHYw0<$HsLn8UVcaOp-Hn` zGYvPbhZ6ieb)p__oyg0bqnLlW|HxN@=)VZ`TfYe?9R7)kDyOUDr{T(Ph13br+P8ggtu?NltpJSjDED(&Dt~wC4D3u*M;(5#QsH&?>;3Mm*r! zlvH!m{0Ui$V%dg~1=lnWaif!isU!S%96}tt(%<7-c-$v-t9MK@>Ox_U1GQZvY`PGUUCq~A zx5$mjP*EXU3)4H+x@H3A$mW;W=v+ow+PL^SntA#R+OQd}1%DJ{j3)w~xsdv;vicX) ze#CLy5xutbB+v3rdR4|+#vKoe*|~2NNRw|n$0sWD0vW%#=G))5C_#(i(%(BA$_Ivj zOUW6P7-5XCMxwjpi_I^m&pgI<8G|}bgtsT>EjvzevICv-#@CFsCmkmpE;KHhPUY(2 zs?cZY7w*=zI___G`fiNhz!7uYX_J;t7^_OioM!uNAWnvsAMUvo0*{EZcO4WXGm9mjW-< z=2<9ngr&^`G>?o1T;|Y`6DdxIBOi0qazjG-&lg_I7qtYfzZyoqru5uvqw-lES0N;< zOLa&MTOEG)Ic%Iq-821enpH1p>%Qr;DUDB=(Cur_Y0s*ITDd}Z17XcUj;CnGJh9$U0Cby=C$G(geW*lauz}~#4p_%ZDj zBPn%PgIUA42+rpX$A+Wj7by%WDFmV$Uyd$c2|bwy_$KQsbpve>DDV*o6#gCrIwt`4 zXb{NvDG0Rr0tAx$0s_%{LTr0fLDwEiYA7oh`Oj_RTxy;S_#(;c`eCOGyHLZ$!f4CZ zTaD^zRqDy9$_YLRPvpeFe;Gmr-DFx91>O9wKX|$taozrYw8Q;d*!RRUkz>1}bGo5{ zl<5={iS?*ZI*X=D=K<&VRPz#blLm3)r>bF_9-J0pG zZ1Z&ebO)dH;oRxnCD_Hzv`x@XB6dmj?(3-pHRga-A$kFuV9fSx(>mpyJIOf=2S?!j>`U2_GLH<#L_eA{-9);4?349bRta zsOa8bjsIC`V9*26fcz=2>hjK8Pc7rFopx;txe#4!^G#R^y>Ji29Z!2&!9#K0^_|#F zmTO#$e4nv4LXBRsq6F)MNynzb-;PRseSKFpwE1q)!2lC{aM)v0Il}n}l2UJ~B!)R~ z!_c(e2KNIsm_bj^Z&lFbG%`Lmc9-elL$@end-IlKWka0sH7Jhozp#z^tJj5pKPT*n zo&OfY(grcHuuLTHrMRRLd3r+-`^#H>e-ojT zFROj!qsiAQgD9`+qw1M2e1n?=ll_I8L;HM6|NTUzg4ezD>JOxod(|>_)KG2hJifK0NepY{n3wjvn4>9DD9?HEX-mlzaempphNMp(q~i^<*iUyY2( zH1u0DqsYEwKZRNGyEI#j*)h2@4Bz^)v@^99SymRmUNM7xOPcfSEA7 zcR74b9$M%J+p?a{^ZyqYvvgeNH3cU6w@0McgtwJ~=aHg`ySo$A zIois{{V>720TYq9^Xu%-v|76$vY@`)6>3#)ut-ePH(gdrdM7 zFAZc6P^&;)YWeLh6t1ki0z6{5OgE|G+;+*^8g@)G5qda#bBIcwyd`?VuK_vn`=q+8 zXWLsGl*-1%Z014d;yQBkck7Yych{cRE?HCX`a^zGX_F|&?VX*muC8lLOiW{5(30ao zZO_j0$JX%BTp%GHVgJ#?zuSDIzQFRe>e9jv1{EVWMA|jO4mbc$Ogp4#R~usm?(s^GoqiwmAyA9B?Y+GT*Ls+$0Q^$Wy8Yd!D`Nxk=j&VKxXtSN@m4s_ox{EA z)(tv4l0$kD_xC|0As{jznq2L^-_wZ{;g| zINh~w3p(|n7y+JG9`jedG8qlVVqE5s$Z}zAbn~=LF}-bYawm4OejG65qPJZ3xbmp$ z{UNd3S=Y)bY%e58SLT>T1~aPUbFw`vSu7t$Y+b| z-fmf5AG5_g4YJA#h)E)2V>kZ(4VS%Krkpqp-8&sulRdoK=7XkQ>4S;Qpip0dk)_;lg2`Wr*gRX;0!}5)djaXS6T6dxzzga&H zl;hs0T|-3|G+wvvCx2Fh2o=qR65`M0vf)c#vag@c=l`r!=G1TbY3s)5a7~Wohn#%E z)m7m_aF}r|fi4A*f?oa7#nS0`{$)xSBy=MtG!_Cb1nl_p*Gj>=nNUNPvWP_1XX=tD zc*2h9LXNVLCF^-XpJk6SN9+mbas(%iw}Uzg=ZTlea_mR~{&WIpAKIpMR)xjI9Mp=V zj!l(P)mfJ*;L3>@Ae}}512(M?@Do?KD*P+~t`1;br_;2(lr<^HoYJbx<6=EKke_zG zSH6k6zJ%vX=DvKQ%m_bK?om?Fyl9$h`FJN#&;S-oKGr9Re76b20{<)j>>lRIlVumX z?TH@9P8iCi?%$Uq>3XKpD^zT41w1*rGvA8F9&cfy1cD<%38!KCp$RJi@lndwtmbns*w$)$S)yds5F$t7#WuK^dL+>#H#P@UOwmHxq9v+9~*99gl}a*8Rmi z77FHDJzt?>Se+a1+_|$+%!1>>Z6xA1OvF`%v{WY|ENBa=?a~QX5=L5Rqp7=G- z*Y6d!3NDiqgTY}~ba~GOk`RgoT7`~e(21M1S6kp~XOp)s9^)wn@pFk zSo5p*-@Li4cZ=&r>NP~q-o0D z!dfKh0p&6C+M0TT-86-3jz}Nf4#7_3r?U{w`kFt`oBbvs#NbC+=7OjFLNfdh2RP9O zeJtgGhk+h9qba?}=Q(q``TM(_2RIy@aEd0m z(v)ACe>sp}!+UBR@Fm+A-^f=CK-3itlO92zoqbsfKKhON?<)UeY<sLsT z7q;Edw~?&ITzIhuhYzQ8%(}IBafp$}`rp>bCLRy|4PpwC9)bverM zF7kksD*v+eUZ`$tv-@aL!zrF1!!j~xJBWP<0mp438~1YTXoOE)U^cIwDo~Xe!}rPI z@*{EtY1~#Au71nSNip`xh*wsbh?)&RvH*^KH*lwUdSmT(_WFO9wq~^7q?oHKeef$K zQTmWX2D?#=`Ei5t&q43+q=c$JKC~&p08b|Tv%Mt89@`Rp+ukfIS|b4d+W$#e;GtO8 z_q7>OK5}+*LKu00Wef}1qH`~ombro_xkssUXo3AYb+&^|Xea4#ns(!jtiBsZj!j)p zBUshj^8(fwutz|hO^o2TN2V%2RA({%Zk#oK3%zRhD~WPCK*5&)fGRDqzR-JA5wfAg zqRA4xuh8a&BD=aupXHx7H6bM)W|I{_^OmgcSzcztO@v`}(X9YP6_GZF7r3i?dE3<0 z|JE*TlUlZExRJydZW(GqrjG~r81c~EBuV(dWu8Ps4jF*hHx_hUhP}S*w>Q2FZ2&{f zlAq7X4c3OO+nF=3uObDxJGByw0~U+}w%11DOU$UBq$_K@WPDT#vr{kt-`q$j3c1O_ z`Q!`BbpAe<5|zE?e*plBp9^--%P7KYGKuBUshK&vnmUd*jRX6nmK3hAo)WMMA@%VS z^+t-W?D?Ugu1vH4eit!%bF$jEU&Xt-&kMSsdGr=&$Am*$ycYJXPmVd*B;o$@?Sll5 ziww*3JNHhi=Ej-c&!2$AI{F$f+qvW|;>UpzIhzMmdR@BI?Xvdz4#Io>L~qdA9b(A> z0W*HK)es!fx{-h+&!o?DPS(?aft787b@&h*tEGNz%V~7l?;kL)-$4a@cB7{vVwg1T zJfy{vhb;??3gE^CCTXz{aHXrKQQ9Ri@LiGUD-5mgI3xo)dC&pC+d40M1VRtkObRah z0nTy;0K^zj%;-bZ;5Rtjw!LpcxR&kw@85#YT6jvrvfQWu;ZR^Aeo$f=y{LuSaWH4N{k8N^aTAf*h)3hV6K_71J|$?J4Hx*I}I2mZoqqO_PKNIlNN3 z^5&_YWF~~A~EjkZBIcWg_alR^|)rZs@#!~ zoDwlHakEf!ym_7C4`9&Dl?%&b4#DV4%F33tE(LBWq#ZGk!_NK^%lQYR#~-y3@E89P zKA>CH4`*2Id<1wy732f_GzhLn*tEs*w(WIZ07ENf@wG@+wHL^B4V@N{+2e$t9K3Yk zlz%Z0RjwYpMEge5OTPwo=t6n$TRnVG{%Yf;`9m7HK_$rG``(e|lRdf%PPxJN*o$+o zunVEVe?qCL>(({ukAswrx%%u>!09Tn>ITtKf0pSq&=k54Kmxm;ptpdWTUCc2Nx_xm z&Qs(x0O0dwMpf~6r*W}s8%p|a(#TxycVqs(ryPGzDXY$M`Ik7cJZ~^o?R+_g1;6bV zcIvlxW&IWQTwxhNK>+T5Y;RE-S^X~s>AymOjUnu_jH4&Yi=*s6Jlfw=v*Pd$=`Htc zWs~5XJG@VCvpU|#N>{2DpdW3+ry0xtFZ_|nt1l_{_Pl)`vP06~Me!lK+tGPB2yFo` zG3n@Ebq}K(cgOUV#fh!BYp8_Lh*hx0> za_u4~^6*un%*oOf#~B7b2DJN9!*U&c2v`Iq#s)=XUarXDSHK?%-oL+L6+-f~GTy(q zo2)l~zLg@h=+^K-8cqk_LNQ$dUyZUmEJOs4GP=a8v~l&=~xsw{cEQhs-n-vbtgY^CA_1rF8*}Uk3|NU zkoI!D?(7s?0&{`v1;AtEjfle5h8Wn{fz+*=@Hc|)^626H2)oEJ?-3cb3;|o!XmXOs zj|#^X#BqRnBftyd)!ABpJNe96b*FU-_fDNew6d}~q1~f~KML*kfGAJJgnEdowibS~= z^{L8|L|Sc3)mmc22y4ia{0nG)bwV-;8!%)8`V25_t7~dpi3(TI`kgI?{v@_Ul_-nd zXtE_>r}Mq8Bd+v~VSsi_*6mJ|>l)^*|HlsctZyQ&MuVd@Z7ez;?{YP>itYiNf;9M8 z(}$p=*Uizv^)g^AR^MjoZKtuOI1eE^p#&dvb0&?rjWL}OnlAPIY?c0;PIY<-bxD+z z@Fu?F!y+OfC%Ip&=Ntv$(uz~I`1yvkO(I!6KJ`t}oo=odnUYPB>c2RF@_L?+{Zqa{ zA9g^GRtsHKdtL4Z0Ryto71soaKae~?W4wNa_Lw=>`YXg!qh}o>LjWj$UXMJIK`N=K zsrdjSnxyyIZ6;=BK(+GS{LHh_R`ugF5kDqZWxb+)gIFPn^i!T?OUD4J3?})@u7TD> zKOnhsIKV2xYX$k~la~P>BlFrghxNLH?11Hh<#=04PBqON2~rIQM{;xjBnKUK0hxY5 zPEAqe0L|3;*k93H$kammo%mo691QSqc!ZJ6%9yX1wD2VygTZmc6!O>5|^%SKhrz);tHwAnp;|$ zEK?=%SD&Xd#7Xmpi;t*-8L0y--2Pg+#WsrQx3DI=Kgio@RJWaa!)}<#Q%AJg zQ5E{6`o2TNnLSBl&L%*6Fotr+hM24Bs3lJ_I#0`9?ga4iztH&YKD+|TVo{9CO%ypj zKVQ{m;Kjv-vXR?SRvy7}KUd54m6>l-tOfvd%}Wb1oNU(&F4xOKjW zzMK92o~6w?qAADCeWqGwfcCb)$)=BMKqHR=^b+Q5vcOw)fHLmz+9|AKm5>-14A$LH z2{N>EcuAhR^?h~xeU4M9n#7}IPjyE|>hoyj7B)n><-rs?uaGxYS{{lzU4u?9-xQi< zc`$$?bQj-NNOHw(kKp-mlW?pldMH!Kx1kLX>HJaBBUkbipbcKZ2fs~+I6|qKA~ip7 zvvT^1ka|Q}sdEFQ_50E)+lPv7{?7doRA;f0MAu3=W|Kx)EHQE*E|%dRaPCa)BowuYkKe{CSnTy!3|&9AIx_2 zaq1k>Xs-dCDL!6up*GhPv`y)s0*{O6H?p$Dvs8^QPDZd8FDK_H+Zb>03cg5suG2AO zpqF0iTWSnwyrzi8kD+T$q0yoLI71^(PEMQ~%#x^z9QC*#)tc~LCFYeLJDew@1;`nH zTmhwH`w?#e(5*`oj7c|vHg+Y5NRMnir#GhUMBs2jK-&jo-w!|8sfeJxTXdnKT6!5T zsRxRdDoj6Er6zSqbN%p#>IO8L(qU(cgWt*zZj0vHhUG5#zSN+!5!Z71JUrTkXRb}x z()eA{78P-A2Jj)Sp!{(~24L`IK$1I|Ej_Vxw%&Zekl)E*c~+i>_}twtWXK{i5gC6gL?_G4(f7YrK-8SCcMWl3?@m?)_62GG6b-2{mw{^Y#* zR4I`S?ft36-C8~Do>u5l62;4w`5;oa9gP`d z+u5sihMLi2hTZnG8ZPBCXmMa*su#nY)JkC%#XQForfmv!JNJ34ZKai=;=Yg&CAvHp zeOfN_92(xc1`rwv(&Qu>NUR{c=Iih!)+Y~%6rTHBO`GTWgaE8}*zU;W0(WVNu=ZAn z7i~2&P*0gcP8;K;S}b9}OcMHoi_5k%_EshZ#RHfySSLdD*T){F0mI?KDL z1ToOTg@0n-(5?$M`opXITAU>E480z@yS^cSD}@_5{a`J6kjkrC`vn6iOZ>K-m#d=( z-}E*CD(gqU<3lNa0Xo#us<8InHIyxG(zbN-Nbi2q@?kKSIa3|3ZB7^~b?Tqe^R8co zsklQefWbrGKaJAa_woVmN4N4`&>?r=8Gg`bZ6hhYbV7bj0{Zcv_J;yP;)`#s7UN^f z*K#E!OPXvid2r>P3kB`f^V0* zP5lwExytk*uaivF#J3lZoa4b;hn%LRb8v+yR46vQ?q^|V6l}H z02ho*$Ev&ee?=ZT_9h&v>FFSSectDVuKSI@ryrSE@=_2S;r{Jy!AIA#;J+E$iJ4=< z5<;+Bm}XOt(I%vSTI0fyxEVMyFK|^5wh}>(S>E%HT?#=Exn9KQAjA|nXwpb5+?0*7Ap`|O-5m0LXE(mQY}$doUBb>})5*j3>_<^?n} z%vfURw>zXB>CKOe+ANS)NG=nU4(tE{MR<8Q7}ih1W!vF@kn1#@12B;Hl3m_eWj(48 z)fp9)z5L5n&aIImY8D~|K4!8Op2N6XG>=bvxdafw0~*PT|9%srMl++Kx6n?W27xA zMBww}@Pq3LRI4V_b=Jl8Av>;DB6OBmcENL_4)i=An|krUoBVWgU4dri#Q%_qX>#9k zhrb3QC02a^jG5Us{>xFdm+z>E%!w4aTSMLQyf^)fhJ{oVV|OGfs`^c@3C2-FQrNY# zoPTi(#M8V5T2$Z&E(r6Z=ja>U!oa3;j)Pq?fGEK)Ie*h zZ?v^~dJ6%Jp@809S^K@6Z_pWLW0+M2Y-qkOyHb#*4-n6k8p+KvZ?KA9i!%%gCW{+0 zp8ee2JV`OIvi6|iX7KT2SvH-jgUPoDdtg-pJ+z{SE~OW7afF*C(?l}MXri~r z*q(eS5MBgy??M<%28&>nz>UDqFMN)6=2KA&#>PihIQsxqF=VGU;m8v&8-jLJ1^NOi zvY{}F%I9PwiCHQ)MICZaT_@ewO*F1#W@viOvh1AyIReQ26VH7&4<&9-ur=$T1}XRtEIcF}WMQ$?>d zLntCVxdvHsq(*$a274`bTsh%{CLCAimoR#EsFpxso9* zHp2FKS17Wcc!$dzu98}#)6qZhuY~6%Zz!Y7GAqfy8rSK%F#r=M=*T5z=co+ZI*M*p z*$dEnVV?t=E$(UCX|pkzHSA}x_!+;dssiQ%tF^QUwoPYqiNqY46V z*wVf`K-YIXZ{1@~5&r&C_gHOBVzD#mc|IO7=zFHp+~CO;tK7*Ag3@O2smzLf>eQU@ z*+Papl0<$-1G`1Ozi!-}{Ja2MBSnbu!y`N%KU?=|=#Xn~XNSoo$!aVxjjnF)j{*94 z+P1viZ*TnkX#LtiQqivp+fP#CUj%s8?wV+)JvyER{SH4Ud1&^CmF{atg*T5W`X6;> zN-AloxrI~PRf~ku+wdbK2Xh=4r?*5xcB3-T@SsgacfYK(_8%JQ;a1;_Q{8E`_X1~S zwkR}B=ku@k#0KcUqi`#05!=ZK5qnf8RZ?SW8`A7Jj3~CkwMMSG=qp_ zV{B-H#2!i)^J#Hwr(ng=WqdPTE%g;&8#M2#DVwJoFNH=X`)7&|n6BEFS>h(H?Ge+u|G{fBHS>l)vtN$uC6FOkn1D4>mx^z-N{Cca5Xu zY=H`ag4<&9-$NB^!!lBa97x-l_MZ&)6kt2}{#iKOoHT$WDH|-15Arj&VTUUR=@_F_ z+oru6aQ6*x?GL3I`IX1R9jQ~xR66Dbx$E4Lv&A_P-b<%xLtDam%0^|+5nS|xsQ-EZ!i0Jdl1Y?^e7V~SvlY6aaZD+YjoC%6M+59JDimrd;#fqQJkky zZcDtr_chphsqUxW>T{w<*U�T13Y)1jOHn&|{S`u0V)F*VkpC`a?} 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 B9RvUX diff --git a/tizen/skins/emul_3keys_600x1024/default_p.png b/tizen/skins/emul_3keys_600x1024/default_p.png deleted file mode 100644 index 4e3220038957155850a3a30fd1449ef343b53124..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73990 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ⅆ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

KBJBG_8PIG(?;GM6dXYzVcXkOfh3jvdP5 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�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 Vv*&leOVBfSZ$D5gQ+W~m{{hTGzT5x+ diff --git a/tizen/skins/emul_3keys_600x1024/default_w90.png b/tizen/skins/emul_3keys_600x1024/default_w90.png deleted file mode 100644 index c438dd337ce3f8220d76228ef5a729c6b9b471bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65387 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

Pjnk8A?+!b|ZGrIF9;vs^V~}|K{5>%+ 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%0Dcg5sxRlN9`X& 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�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 - - - - - - - - - - - - default.png - default_p.png - default.png - default_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w90.png - default_w90_p.png - default_w90.png - default_w90_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_180.png - default_180_p.png - default_180.png - default_180_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w.png - default_w_p.png - default_w.png - default_w_p.png - - - - - - - - - - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - DIKS_EXT_CALL - - 100 - KEY_SEND - - GDK_Send - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - DIKS_EXT_END - - 102 - KEY_END - - GDK_End - - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tizen/skins/emul_3keys_720x1280/default.png b/tizen/skins/emul_3keys_720x1280/default.png deleted file mode 100644 index b0d49cfe3d2ba3c3038062399df3b11b7fcaf90a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83969 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

Gy{Ggr3$CI$v}W5(tufQ|!{b@9Z`_#jen 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Ⓢ}jArGX7RljX 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 diff --git a/tizen/skins/emul_3keys_720x1280/default_180.png b/tizen/skins/emul_3keys_720x1280/default_180.png deleted file mode 100644 index 8b59e00806d52a543364a7a1b476da319f50b56f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84060 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%0Dvt&(#4i{|{6Wl64Pzw>+0{mYQ_ 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

QQ;@k{p23S@Ek(=X3`JJ9yn#bWy$P) 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%0AJ}{W9hkU#?FF2D$QZ*bT4tr(G?0;Ljf#_Z-2M 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 L^PkS$e)9hSA(}%- diff --git a/tizen/skins/emul_3keys_720x1280/default_w90_p.png b/tizen/skins/emul_3keys_720x1280/default_w90_p.png deleted file mode 100644 index 35d3c974b6fb4fce50658e3b6807ab5017216cc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89604 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 Qhx;M1& diff --git a/tizen/skins/emul_3keys_720x1280/default_w_p.png b/tizen/skins/emul_3keys_720x1280/default_w_p.png deleted file mode 100644 index d582bfa9d04efc360d1cc3958e71c8f3c61ef182..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89976 zcmZU(2{@E(8#g{mMJZc_>)>Pq0{Km57}-5GTDz`rFtewu9sVXs+tu(I4UeI6p0qUu-r%fF$P&F-OZ>TxbTyP zE?M)g!TmRMMao=^v+ugvJLeX~9=^Q@b^|fcRKMi)B=J*$4uj<7Z}a`UfCN$b4PT-G z{nSnWd50tHlzv?~)q?6x2-Q!o_y^iFZ?1wK`o}02fF7z-y~+3_XaxE~4SL>V{bB+1 zNEGz^CSrLQ^d{plHGm3ap2T~N>PtL`huJ1v6=W|5Djj(8K@DVj2Xxg|yIlq}E(*E> zHL=wMeX9li>}R-C1)`w?-7yFc6#`KQfS&*2=l27Jq=K%h@0iGM-!5lZ5e9ZDwMxDo zETi_;oJQ3Bf{BS3*R6gi%k8UDR%fiz9*VWTPGysPdyjs0w-*HZ5`PVN+Fg=g|CRFo zeyNz6D=^V@)cI4s7cUmbO9Lft4?&!zUt)%5! z4eG<$*4{mxe2#$x+K?Ah%dr|KwUa=JQ1;CkS;2 z44uB5$A}!Cg<$T3zP*A_1;mSfwX{A<(7wrF>h*K}00i1;bZr^AMRWFz{kypV-&4FI zN#lzE=#4Ej!5sv8rV18&{JUDQiv|Qz{qk1$n-cq83#-V_^BgVbrdlqYJeLYl2Di5= zGbmqt`G&*exln1a@~!uM-#CSzi;q0yy!X?<{(Yj`6|q+1x+@B9^h7I~%$8eCZ)vHO ze$g;n@lJ+Qz4&0tA49{E8hXgvqDjpZ3FhezziPmz9e-a_!tldm9%D_;9R-gwGGP|# z4e@fnK$5{H@0&CvlHOJsD2&kkP^teaeIrCY=hB~-UJ_}s*T1Cy@%Vm2AxbKHDk7Jed~crUuveeYCmbE zsC|`rthkgkO?6E5#x=k4aDeYIPSQ%#o((Z*y~&sORr|YO1LILU>kCPVFjGwt{!yk_ zW^smqaFupxFjItzO(Gu{A(gb>Gw2m@F#XpzI3d*Ad@7*bNg55 zV#Z?I;@w5|Mcy6riy1E-y5}7l&EGQo{Yr~%iDBv9(s`Rtl1j$8X@=8ZvmZ0wkA13K zmR)05VG#C}`JQ*0Oy9ffQ0@G(oR7md>{;v&94c158W^WPa_Ob~F&XMv(^ySeJ-g>i zclrIbcU|Fjx7gBIFRxw`RPqlF^ck>nEN;*3XFBX%RZBDt?&#dcp^ zA1mesnUNySo3-h*>8s=!e5r&jGaN4s*XFl9IB!^~B@(7X_P!9AUN2^$N?;^dTM z(-O@RgAxsFvs5{*Fr%PZtdit(z7%HSA*h&tt022yE>`TA z&z{|=>WgwI-29Y@eD)?&$F*?gb@K|511?T_OmZd`?rYGQp0B0@pGVX6v&whecXyTN z6z@WB8>m>eJyglJ`e>Ch7ZP7TD4+XRJzAYU%AwO@0leVc>D-wscwUfKP+NChcQegU zx4uBAKu$+ar>n2GFQ;!b^?tg7#F*qt`bzp(I;QsdQ@^JoHD7D$Y@k((PYcX8Ynog_ zpURl!n;Jj0tX40}C=(cMENd)eEUec{)GNsxwQKvfUDI7tRLk~lY5Y98yvDf(Ze{m^ z#jduaylpeFIT79fk0vQxxEwZdrG)b-XOQQ2kE^mzWM|U)KW{3+JNA;-#O+K67zW1g zF4Qph2(>$87^M$u*s<8vd%oKZkBra`?h#9Yh^4c4PXB6N)biSQx194I+RsR@PH)A1 zMOSP}Z8~g*O=b1o%M!{oyX*O&*E1&w~`yH-? zJ_=eL{d2);*($Ovi0)=+Sg6T+#Td76(;I^lDffK`r&K&KszlXf)tPiV34NIgQLX#J zkYce{@{`gH_Zk#C#ca)b|C(l)LY=fZWW2h=FE14>J_t)r)3)jxwe*ffrseIjs8e!+Z z`XxA%l=7fvL4RGxx6fLB2eQOTzPJ<$$4-smEcH#r%`iW#i0?DlA=e^4lwU=& zq+COc-GPube&_uYm@fU60 zbU=c1BhkiG#=3uP|JocwkE;(9%Oi@{4wH|aEz9(r-Em!Kht85N@L#DJs~`ExIi&E| zFn07dR^v(+H@>nj2C(ja-pylIyqFsq@;YLN76!)S0AJ$ikf0z1HQ)iNpF` zjh`FS%Ihs0>o@(Ie+1Ybtg&ZG_fPLNzuvxnI{G(LMq#>n*WdM^<6s|ieLBeFCaJ%t zal-fJW?7Sd6KwAxPH94AI_$5aIeBUvKZSVp)A!5n;FQL}`OtR*fr+uS00G#*c(Q=$ofhr0XU(l2 z2H!)_v45jtXN?kd=|>SBaCa>2PeRdTFVZ^XqoRs~?&XuORKVyMOWJ z<;A7NrSf+8@S{rZ`ho7<@mN3nkGz*p?3O1Ow>wxW`JV(~_;1M_MYN|oFk5)e(HZg?}Wx7IBG!s-SrDfD3?vNe|of8s>iH*hU z6b_qX4m+jElV6TCi|SUY-@SXMpC#kDJU=rtlTRX%-r;c0QC-%+3k*HOOPv5NB2SMx zSf_62)bL+rUn?)f5A2pbLw?uSPzbcw#>m#41Y!;hv#KojE$zKGpW15TyaqePkocU; zn%|eQomGmg*)e&fu)FGEe~>jHE=I;K#`Gs9I=TdN7UAZ-fFx>R`Y1YB1 z;Idl6-dy}%By|Avr+5P1+c0PwfBn?feHz7T1tZJp8ui-VokAhFySlpS0uIDnFv#dJ z7=ly0d5;NsvLuc=DM1lS=+AYBhNuoH5?6Dx5IyEI9weZw<~Js)$I!>JX> zLB~Mg@?E?t06BSxo$i~cldU#-6mGsF@`3Lr2Z2CvTkd7k5lobcKI-^&WSrMt_4UZu zU@sC(n#ZIJJiBfNQv_|z00@Bw=A)+~hg# zAY5YB$s+U2@!J6~$w*&ezqO5C@#OFT`UOKv)Z9?76FKekks;ocdrCk!4l& zR3Xb#S0rpGtTMq5Ic`1epBQ1iunA*;Jl271p!J4Hg}F6&5HS z{YCzxo}5Zpwr?x-;2%}=@`erj14D^m< zCW8F>gp5BWn<(xV=_@Q*av!M=A-3Lee^xl0eYbFlMQnDe-t(^s^p8GJd3{HN_TTTl zeK^5bJyA-;@7OJ&uwW7&FN}$-o3n1BHZq1Vf&HR$mgIqQ`=(o)n|64ZKF{H_w4r)m zWp&Z}omN6fdt#seq^WPhFI&#WrrOD*YwxC_`_ahCiXN39-~F=2%iXzg5j%0CMDQB! zZzx#d^+gyK?MH>S_q zGu@tZ)75aZAPCLhe%~i5@XYCsw!l<06I?79I8I#~c-#42L;N;_yyIx74Z;YY^g z<|L--2|54)AIQqKddYS;Nwv+*@lsk1;HFD{gb6!W_{jn{YBrR+PH>GoaH|D_K%-{} zc3gp5N*2xj*I2|XzV59Y92``lP_fO;3Qn%B0KxXL`N?Kve)t4SrmFKQwn=@5MKngd ztmv5(8P0^Mos4DGm%3Ey(~Pi09-o^X<^vZ%yrz?R1zmB5HS|o1VEU6+cHyd-(dLrb z>-)szlqd`K7{#40ZsYhYUQYG8??zv-#>4QL@6OqaXR9YNv$vSRYi%3&a%`3j?F%f* z{F)g`3k3i#)4u&-LO>bbX#HgUMb4!EOVa4*lYL`IHJ7epdSCHk)xqX;TQs}$R+%gO z66|E2WxHEHXlHi-a=g*_nfO+_^^mxatxzN%F3a8duWb25a`LPo@XMv&L=gR z#Y$HDir{D!8s2+IyT`V~(VtI4283O|?>H$I1>)`xNCQA-f5Es``GsD)T;BbTN23n~ znY!M88!epD^}}0cEww8HkYjFi+mLxU!CV?LMpjmE&Ji+{>o#1C&$zc1sJD z7z`P8+oXJUc9xAmbfIzX&oXYL_4NBx8y!2gwj2eHyC>@jfpuVxDe2f4adG~_&b=Ke{q@Bsvp$-jd27UN%JVWvsqG*E=f z0GlO^+`b&RUjpl(>>5QNfVOse#7$0JswFn7QUz&-+oN$b!ojoi5j-^g(tw8lYz~O_ z2eC|+L@UYES)hV|7&(KpX@L{}6WH7tGNE>1yNer^Cg)|D1h;%vDE98|jp$;OQ2sF1 zU>^{(KO@DF;R6Wr?xE``4h1LEpKj5Y{l=IItZ@fyREk?P`rsxL^&w{QyCxOSI+l7; z+yVLqLp_AqoS^-M4o?;A3|eg^Q+qR_bOf0J^&Yr%8`fe6*=0Lv;Xa`P^d?)=(Q>-y zm{@YgJVQvVsbKcY<6_g-ZZ$fWdQ}5x#iA?}d%Th7hQ~hXj`XCI>=fj&cpd4b6H~WL zG6tNEOTBj+H>K*F3M=3Z8?NZ4F?3RHZiViE5U+z<`c4?@43=7{y`FrNhA&7&y*K5v zo5I0YhBJ6LK49C9+?&;MLGe&2a8-r76%Za4k4b!HuoQlA8`pKHO%Gn+ADt}cyE(hH z#Zc=q-P$9LidxAGxRQ0)eiKQibf>$c=T}k54QJN?^w`W%zb}M9s6}zcLWsAnT)E=5 zHY8xt6`9G zK|ZNdmtle-cxDqB0~@m%52}|#DWMFS!&e>Bo-lKDU1prOg(NK+sPL~@9&?3^rwUO&47A-r!a-S0QpdY@JO$bZUX*bJ_>I&@=_F z^;9GvikS%lY^QVd2v!Vf8WRl=B)$s(l@*9d!a?K((EcytPKiZqk}7Gs(bt_)*+@7$ zMUrL)Y|5N0yONhFsubn__qYE*=WM`=9OmfvK6Z?LhEP*GS5%nU${#Bq43O({Utbn; zbMrzyZ7sg4Ahm4p7`8p|wej3=7Wp1|7eO94?8BVs0;Fb~ck)uQg+TDx_uY>|?JrhF zUQ%O<4T%-+76ilDU*z}L7ISs$Ge8&^zbCRM)ehMYKR5}n%&=I~?E13r=-4(@E9%_o znN^im%Kc<1;$oe$#>uxU*Tj)m;cMnkZPeokSJ{ z+D+Se#}!aE8*k~)P( z6cE$U(4eqYnBs|5;OPNE5s5!W(yt6;!GuDM5VfOOmdWN?rO5h~wHaaMFFf zAr#gU-*B|)i#k3r#}J=TG?m|CyoTG+&XTZ%)3je?+HR!(u7C^*aEteJx3y7w+J|GO zMA*WQv1jRtjYWyu`Fpww?oJbP)Qpqh6RGG_`K}z^b5!ZX8q)kRR>1 z2D|UhChQ5w*gmgA!xXy_W{h`HqbOqZ@2Ma$PaCdFLejs+N5ay}YsH2zqn;K`wO(V> zNupjypNe)gCy%4mf`cU194(>wbX;ZHQ-Dw5;N}Ksb-zyA+k5&Mk%Nw zZib{2H-+#3*^DPp8&|-@u)qQt{~@y?pxS3prw6CxCkJop)Ui3PyHZQ-_@Y^@i~QE6E^f|TtYIO!djT?yJ;aa-x<1X!ISW&lmy(cgbX zFtMA15p~N^B{=>+DF!Bvb3+*~BF0;Hr3muGKJ;Q7+BzzU4Q>%zAayQzV`{cDl{u0xy#U84dhdduW= z9o7*`UX7hsz`q_S%BzYDoA(a=*l^MZh!skQ>@Mpz?G0%k&aRb)joT}H73;O%hZ7*)pyA!Zlc!N_`s79Z`PEe# zUN^WcJ?_W_xL9fNGW zrI#lFmCUX$zfDciVV~uEub|Or&mk#qvve?27Cu(Puh z^FW?7?g#@M1!k~UX$`rY&OxlISUqr3bXGEFbV_qG-E5;DI<5Q$(Y6F@tk zWjxOZ1O%|gcKxcN$V=cvA%IVgJ^2+os}Z!Qp$DxH7fch)vRogvGkYI!usKHwM&QR% z&*1yUf#lt+u8LD)1?F%GMqaw`y;i%n8Ul1I%#U)KIG_~hDbPRPa)G-v>aq002>G7~GU+U1qv9`lZCd}qe#{>l8FORo80 zW>=9|xyn~Gyk};ao0iV?Q%W}w{XTCzDei|pdXn%%h$$(4k4PNqx@F4^^+)^sFk8uX z7(%aGPY+bebXtt|?Qyj4vk#u%fB9`;yKX)v5!^zlN$jX7MH(ya8!3j;2W`Fc+`;D8 zz>k_OxRbR+^Y{7&2N_*vnj$EDnsq$2vIRTEA^Z>7uWfa43uw7&H(6ce{t^&wZLR4eZXizar*IA~uKA&S?Y|M4Yzq3$ zuK{doB}8Uj`n82qc+5VWNgf|GNnhJxoJJNbyhh5my=*2DjWOY`vrcOI=Cn(9jnMC^ zjHM+4D-DJ#=Z&%&`gfJS>C?W@e5A#z3n<(V3k%l&CoTbw6$o-D$N`k>HXL&RKb+$x zTb;Ba4(V?{tEcPKOn9l6rqENRbz~!%3VNuvOu=5jT)+>T0Tr+UIi46mYM977? zk2OL9ag+BcSXAe+bkWDh2Lu8P$?)3M;kCV_UR_JyAUnGY(1h8pppCArcZ!GaD3wGp z!xTYIFTVxq&r~p1`}4oqscHn^+9(OtUlUjd4qcm_)CvGsf0knG=@Q}ywv|F2g0-5U zh<~*fkYr;n!$OA-fYZCDdz%Rn5WsFXkl6unvO9p1fddDD1C8FJ=IK*?0OQO}9Ai$& z+dmw~wtn%)&H`D`U#Lp5&8I$F(49gVn0gg(ldT%VZ@;nO2Nn;OP?-d>PY%jFo?W@Kz_&(UjnkTvtRG6^_&z7WHke>vWpwRfk&JkYaouqPnV>IP=_RWMWGQQHKokdd0qW=*u+{X;g zY6k+RP}fs}D{3qAplM|S>Ak@jgTPJx!21E|+BOibE$l4yP*|k=e9~fI0@%1}Of8s9 zA(<@|#XS|Eef(zMUU1u-k^zYIu74(v$lF1Vjl035hvviYshwGJqn&=q{Rvxb{C-v` zorzj0U9A#nQzUAf(&P?))#5N0j4HpGBuaY%xD9~V zex9YD#knHn$gQx$OL(k#?K7)&Ks2L~gw@>G4;Q!t836D8b7tmQ{(vVCPOo`g6ta2t zNa@emk5$xOzW5yeBm+em0a!G6MeIoZ?`*>7R{lSxvcdZjpwoksm?%AiBGsN=KRwAh z-4zZ-J`NUw9vMn3A0DzA{uZWz16@J!E5rJV(I~}f3OG+@>B&4H40V3nd;nR60Rsi5J!&he zCjV|EpFLtSjR3a4J4P6C*oAbn>h38Bc+Brv6KGr9mA|>t@IfdJHFuDPvgfIH?Y5W| zx0(G`v%|KUF~`mSp~;19Rsi}y!ZUI`lK)Ixe0+V~0YlS-b9QaZI`%|tzO%#*2_=x@ zHMovQz?|dd!R+i8zVT|2Hi~!v&QPSMShX^riv&O&&;fT+b+&R9iMbRtSMRw(DL3{1 z2PmKXUylJ`$^!&hp1g@6HTrGVuN42>CHnp|DFS};W5xqubpZhZ6xavAubl#g;@(9X zg_^{hnSS$Ufw2W8=>k?P!4+E)cWU@9$kDOnm1>a^0x+j1 zcssx0p;4GEl0E+LocmAbcOj+5`tQaxgNuSW_;ko{7n&wS5vfl%MiyJw&$>J?1GLAV zNRb{l;4y*v-oW7~=9*%VqhUuMVJ*O(e)|WsZnJ&9ryF13AP~kM^3(oaD*(P+@I8Y- zAbAW7Nb&z}3&6?A_R7poa&34di};gNr~D)UzW4{<98Xk7%YL{0mF2%)n2++9H511aJgU@Eu%{q29PBv3i4=_UXX_eW!6W8Hx=1^z6F1V8D=pIiwd z*dc1>>uPIigmWPO*FT|t_sQOfrbPboz#QQ4=LN`?Ca@U3f6@iTAfP7Q=338fY;K-; znBQh(TVt$cY()m-<;UJWMN;AERiH+Jp;UJ7WhHwH5s_oQaTDs}H&QWUncp3x(+6D$ zfu*rgQL&`_#%GpH$ppavk^0>8P%vfJ+F0*}GzU}szOIz{egL}0)d)65ey9k355WU0 zv#>t~(?|eQfbl=gvH#a(<@;LCmt9~Jf&3M4eyE{B%;aP%Kzmz<3$Y6Wr$>sX%IQ1i zm5YG=Umdo&8koA_EtNh8U^w5ZwnAn@Zy!ZPF4P8LYl{~vqrTjv5u4TYVwk$qWn&k- zd%jBsr)J1gE|X6mKj6;R)tKNZ+9IKobu&Dhw?~pPWCR`+D0@JRoX&EeysNh-O464Y z7SDHRuN{D)6oR3kC?(n8b~W;`P9XpOcpC)=I@aLk>PN$mra?t5Mq1NJAx%k4iUe!L z_tVps8+g2lEa88^lzQ$`UJ{VYsiqZBnh0{#tv_!Pv}B^!Jp=kQTp&(Q0HiZu)Bceh zz+c0xq$Q(21GwISujn2q5sqf5Z3z*1k89gJESfY zApG3izWI_*UIP;UR=)6MV#1dT9`neghKcEEfPN3xvd9j=ly&a^%wP0w(7afk{VPLY zQ$i0ff9F?f9Mq#Gxr|F)1VY>6Gw_KrOYP8egtJ}rN{1g3j%R?w1vHs)AdonB!H#Yt zY{cG*fc_&sqttUhG;v3(|5G3B%=-5PTiHXuEAEdN!H^WqLLd|yQ92TkeG^XSg={`{ z_&7RVqL?{AC=HON27szyrTlkhrqll33;O>Rj59A}Gv3TUz#Ld-4A9&ms1S7`+N7t9W^G&0)`AAu&$INY1 zGD>{+lEBS|7b)Na=rU2tZopC>*3j9CM-YKQHUL`l0Iwgv)BWwJIs~h8Qv$%ynASQ! zsW8t4D3sCB>%g?Q5~xo7z;vCi1y5JA%a+VTOf7Y zFKW=9nwPptq(qY_((@%LnBffNso&8{&96!)?&(907E>tNu({bXej}eJ=(Q~9x!$@h z!0V@g>C&J~*MZOp*kj{-T0TPP`P|Uf&AY9nPrSVY(ChJ_mv`z==kOemJcvL-s z3@9u8&5e!6p~Crk8CO7`5*vS-34@djIXcn?F3-DEYh=lkuzEyP#zyg z`Vd6@(;}uJARze|2l?-QqE-Ri+F(p!p_y(@|aekT?_P25u0S5}Cd41{9+Z)vb zFXXvQz;J~$ee;{y96zxj!F9YSb?L_~XSGfW>-w&N0xpX^p3k$VI9rd}+1B3=V zuW^;B`XF<*Yg#>zRTiVg&*N8~%2^nu@0=@Y!CSsMKaS|;4nDIEHR&>hAS=}wcvZ9_ z0FMaz3H*7=WXw3i8ry9>e6PbxwoKEXmm1I`6k4I=Zn0&zt%1M3J>L-qbjO_=(O;5^ z^IWt5hN`N+MFbS*$tIrc^6^gc)4hK~7Vx?1*EmB;Ok=1;38a{_4psAcj1u;>inO?% zX_-N1fUuhqJjBZH{0jB9DYf|n4BgZzDd^rR*6KK)5Xc5SO&tg<7%C9w|9`IF@ZAFt zErGKCFw(k-yPuz_`@F!Z<*T8TCYdUE-v=YO>3UdoT`Nr+2arzWBkJFH=9H1fGM)whirM7>#8?i;oUxO#`gzLr` z0+^#LWW3};%D^0P2Ce{JSKzhL`Pwo5wfrQ_1ZseEfdT#0q~sIzAw>X(QH?- z(=jK4Aq;;JMzNW!t$c5uD^_yTOs3Z4HQP&1c9p@s<+}=z1(-p=(5fm{VQ!{7xfJVr z5yKdAJQd)dhI<|kdJmW$G(vFrODQ(Y)Rk=czjfF?k#8b)ZW>>OTM8pjin)o-0E_^o znj#KER;?f1Hrs1%ZoZUnp$q*j{%XjCUMOcR3qd}TNyv=CyM-HDzkg;w^e-G1Sg zizVauI+)*y*B3YH4>?mSeNxMyPcfVau5gs*tYJ|Vu`99&B(McL6Stwn1bbMZeMTt^ zyp9Rn?UNbGNIeE7|C||TKBmMe*HynRp zoVFN`pd?fyyBfq*^o^YeSfWl1>q#W2e(^dlI~MvD^h z2r@`PimZ}J$DgPEecw%9nK|ZtOEU1wuz=335>ZJ20~FetA?K^tSKUKHl&ru4i&%2i zDoXbsIeEb=U@*}A`M*wuCOG^WaAby|=S{hlV2a=}ge{|E=mN|A9<3Kh`TM5wy#Ic? z={aVqpz@<|HD$pOAIbwvFK^iR??obv^zSs%EeMMD+cfM&?nnow9=-#7-XM*|3H5}F z;F+Dmz(kv{9j9~xcU48Gq<%*nYn0=Ux|Mhj(zBEtx(=zH1h$$oL`uVbQg1Oh#xiR{ z+TE#nV+Z5xB7NZCn>Zkj)(|6?yK+iRbajrKo2av(_c+zOCca;>fa{A?4&z z_d63dLAZr5Z?+|f_nrIdjd7KN^d5mQ>?g>*xdzv}fGPQ@)*R-z?cK6rQ#E1C>MK+# z&t`fJsn0MK!pwW{k=}dT*a z8|>Nk>u#;yi+TO*5`wO&tAR7ZuuYXewfnK&Vax?xm6x&{&0S!?v)&D4b=6&;ztqxe z5l20DkoE)069CvysZeqCF=kZ}cDG4;zx~LFZIFx|26r&) z{HL2{s3xu&SB^TQ*`uAyH9cJOR8*K+;H{f00}_2uw_LsS${;Ikfe_*eEAy?Rbu4(b zjdNGU|6n^AIt9;F=^3{%4@|UPJ${YJy#tSP*&cL}#r}EHH4V0!F`jSB^J%I`kSh?# zu^`r6Ntccok6mhZs;a0HaFX7LWqQ7 z2>OGp7dvh6ti`W`SBKa%!IukFA-UP*b42^&+QBkgJ}Afq(_sGyt8K#z6C|OW9Y@#_^BB$0C#jP z_J)xLf5jK6ze)Z6ay_ug+HI8@ek(x=yjnG|1RX$ydyVclPbXh*J$a7B?#|D|CAe?|4s6)Iw<7#lSQM{;A2g2!s(&4=)$~W}`N6YEeOcZ_0HHFGPVu>IJO~!qx-}jYb8f(stX;UkC zQ9=EK+5ILJe))&q_^UT0+wcA`7*bmGK2AhtS;{R#={UrG_|uj3!07RN&_@SQx8j8( zOQtFxD4iqUPD3QFfzXIMIBtMQ{fHf3G!b;U_M=(IsWIc3# zKC8wGGt}vb{kvLtW6EcQjVdF>{EYrEwbKhPBxq+TimSdo{Is;y--(IlIByHME zNPrzU=g(x?cr+b9&g^?>85l-4T%fXkTyDs&D$O3Id5=UESxFO`@i4 zYWuh2;2;%tx=KWtmhzvm{qX^B)o-`?`qb+qL-rXoRZJY!Sqx6f^IbI`4(m}fvQvt+ z<(voDCh?11YP;LwKV9p8x&ydrR%-V5^UINO`;|=lkOR1r59g$5!Nz4JhRU~K z(i^FdQ@vNv+)hagk+JcmAF6e@Xb#OX2bg3k2Y4ZWJvH&H1m8L-_A?PLRIYS|(#4ef zrzUt08lUPK3OOgV*9eWNDx}2<4s65!PVsoCe^<3pBj1oOP0^chdxEt>K3;8h2sm{hBA zMIY`txsa`ngBM_bC&BdSZd)-Y<5-bR!ywGB#ZSNbjR#k1(3;R}7d(k!?3@mtHiIe* zEO=f~`YE-<#^p^0tWt31QYa+Isdj?Jj2(mH#x@i?v5ZAi!xKF(Ixm?VS-^%0reZrC zeEUh%bBfg%Dm&DdBOQTanB)b{_yZq``H$?V5_Vz1DDa)!M$yw19rN;i9WM$ zpRsyh>d1P4U`Fo2=fDm`d9CVZSHmf>f%SD3`1&h!XNl&t zu}%3-WjSP|z}Yh4Vg-L0IwnzSY5kM-BW5Z=WrUn-VPqzg6{;lR|ctkBOPLY zNF49dN!DU$OTVPTiEmhU{jlc?ul|UAR4xB-0}o}v&hVD~sPE5#)9|T+3%GQ0GIGddyFRP^aJoeRWEVA71Hjj2V1)Wo7JMv!rq@ugtOWm*NX|zoZcy*eW1h` zL=3HfKvUUk?za<;%5hxpq#kr1J;3l=aHsx=93VI|yIHF^%0D^X7X9Xs7!n={t}Z{R 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 X5sJIs^70a*>iZq-UF>pyICkM5_w<}( diff --git a/tizen/skins/emul_480x800/default.dbi b/tizen/skins/emul_480x800/default.dbi deleted file mode 100644 index b6b4484..0000000 --- a/tizen/skins/emul_480x800/default.dbi +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - - - - - - default.png - default_p.png - default.png - default_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w90.png - default_w90_p.png - default_w90.png - default_w90_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_180.png - default_180_p.png - default_180.png - default_180_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w.png - default_w_p.png - default_w.png - default_w_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - -

- - - - - - - - - - - - - - diff --git a/tizen/skins/emul_480x800/default.png b/tizen/skins/emul_480x800/default.png deleted file mode 100644 index 6d33f38e8f92d74ca92cd583faddcbfdc291c4cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52469 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 diff --git a/tizen/skins/emul_480x800/default_180.png b/tizen/skins/emul_480x800/default_180.png deleted file mode 100644 index 5e8d2766eda6d574099797debb7fa7f4e5c2424c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52169 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 diff --git a/tizen/skins/emul_480x800/default_180_p.png b/tizen/skins/emul_480x800/default_180_p.png deleted file mode 100644 index 8b50699cdc9fc9dd2644ab4053cf6044317eae9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55315 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 TD(Ax#9DZ!9>@7>o&qx0cTiM~^ diff --git a/tizen/skins/emul_480x800/default_p.png b/tizen/skins/emul_480x800/default_p.png deleted file mode 100644 index 2f1da59f8727aacc029818a651039dd021dceab0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54897 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 diff --git a/tizen/skins/emul_480x800/default_w90_p.png b/tizen/skins/emul_480x800/default_w90_p.png deleted file mode 100644 index ca239555502eb7071194cb6f9f3f8aa25858d76c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50686 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≥vHx>*@}yPuZx^{&;8of#*hj25S4_14mer3PA>C+#h4- zBw2=PyRMR6XwJeDLr1BhwD$j!zeDi(NjGnl|MG$9&hV8;`seCy`8T(VynQ_|}tn!b;U{ zjq>*|arVv35&1wZk~yMJe#4i1tI*%H?SW@RO+P-QW1!KaXx6<%RpoI3q~hrMyY2hp zZJsyNnl+so*tVY4VV;3;O^6epPRQdPZfL;5-wjmXBTGmozU6E0)lcy*z}C3#lUQZX z;Zs`Y>h}c}HEJpB5q+;;ZRyo!{$F+6cD z7AduaxzAk6o{;Ob%-3zY*PsLRO@90I*q6nI+clnW1*dnL>FX%)Po~x5QEMKwg@jXG zsmsEZ^N%#~3Fc1>L+6v1%cpGhYTGP@U7gDg_bl(M9ER<2HA{+Gu`fY^y zO1FL{7aa2*M9M~P``~BS6v^LB>D|lA|MmBDzahFQvc|~rjcdl?QrA#_sxN;!W%HtN zHb&@S=kem(_59=3`+V}X&m2|nO}>k2KR*vxYLe9XMsA^Y*19d5<5R7cRYj&Z!$#DM zKY#Ge2)M=}Kik(7+S@>)T=aI|OG5_w^R3@;1P>Z&TeX#Io59NYv=pJZ%m~Bk0vT>q!>enXvKLZhP$=(7N;()0{9sv?oD4fg*!EN-AjVR>l?#^H^-| zlaf{_J(&2S-01I~@bv>lHFFpnv!q*)+|_Q;b=~8=d;2GF%ogXUV(F4?1)ZwrDf)YU zlmAVGuAe01NegQ6(Kna2%-O+oVD{Om`)6TPs1nD8KR98l=qC)xw0a+qcR$(-9+16_#c zfJ+{FGnzE(P+cQ4`M2gXqAISl9+77gyR-aHc+@!-o)k!`?_b{21{}xb7I(NV>9o8U z|A!^_%~iXCFfa9Zhpv6PP|oP8|~29%2h}LQ*#=L(8thH3jRe(Gpb~ zvLSnB`?tagMy=G%%w$Pnqu)&%y?qmC_Yh%=4SmAJDM0`I`OjC6g;8lQ8a(oUsw>ge zI88hv^xqe>{rX(~%_LG;ow{?%n-D)|Jz#<1ojl8DXNan7=|J zf3uUMVlTaLm3tvmeipJ+ie4H6iYefx8G&Tb|TDFk3?^`0Y^9bp2sQMGiPcB-tTJ#Zni_ZebK%YT@@^xQ7#5@5uM6=bCOIghMzXP7-0ZZ_x2lFmU`x3@JN|^Lot9 zv4Ksf;+hT_sF7&hDk0Tlgl3ovh+-_Dr-M_N&6$H;y^#P1joFPHiVfFZ>%{Q&m(MiZ zbhNbl)9-&1q1`!1*FKM|5!+`@?Rn*O|A|TRJoD~kGwSBcf778_kQQyWJ*&0;*KVO1 zaVBY6@%~v9aQv;qRmm0-mlg{D%$l^QE%d|j4GOcrY@ zPEomYsoW>jl!da+JyjamrWy;6=_mtl5mhgF@W6Awq$1vrYXoMO9p))u)_O#cn)D98%U{u^N?zAqp}V!Q?NV3M(>#1pcHvRak-_V@UP0w-jGGRRl~kIw7J=aC;%*_Q9x zo<}Ao+zky^_gxW9WD{HEE$Sq0WZ1r-0{;Dp3NO3MwI%paeE%s}eZzshhMiZLBIJ(u zkr{&&M=@!SV1&FHa!tm0|JQErkMe}uZw&DeQBHNkvKUHAHqpY8hd)|yVj(sjK2?QYGP{zcwwB+o-Sp-gqd-|2#kTb`;vtt)J{*NsItptPBr=q2g_vLpJJEo^ zoEAHwUx3wY8h^ByBv&<69Uky;#8w~Hfkx9>yDwjvA$-hk)hlETFX-Kw$k7++i!Cr{ z3F_$%wcq6@V`6dl;r61p>u>75(h4%zV{6tybEM;ief|}xgz(Sz*X2o`JEtA|w#$1s ztpL_Ut1x?$2QGFT8TG`3cW_l*JW=JKcM1|X1bD^D6hE_`bq$^G|5y>b_4^ehS^*r_ zHmJOEiqspR>~!w#{^PzS$%47d8;P!kYqkELttgx8I&zy{N9O-KAAQ>JeLHHp__XSZ z>6|Nk!iKN>VzpZZsNvTIAo^@MwvHqY9n`pP%d9tq$u4t25;)T?Sk zWRj)i{{283my3==w5DxuFMtAWU+QNk13ko9g&|i#n_&76v_#`Dr6Su+OOFq2=!Q}xyH6CxD~eNG9K|3% z^u*u7inX$oZj$lz-xC86ET>{ReUD2Z>l`V4gN_-_GRzRZa~IYMB^tqoo(C0w#4wW4 zHSVAEC+vtf3K-}y6lGzFicY7^2Q6$VdBqFTmbYVu~D+zg?%5G_bC`a?T>ooFTY|@(?47 zX20*2WSAO5FQy{J%Z+k?8ip<_!4D?PnC<+7N5gYzo{J4zeD16DH;ExXgy|P*qX&HH z@8>y%-ZcCQ-n`)|BF1}(Qm2&FS$32mWZ_FI;@czzLNEVKC17J9_#|_@98O@-G+J2D zMgTXNa|{CDM7%%m-6G&zT40vQ{XnAJzCmO~{#DCre=Bf(XDN@9TLa%MqhtuQv7*N` z;CbGQ>9;#e{p6R(@G!}zI2U7+r{()eHW)e47TXJQgEx9PCPJ0ouJA9G`md|&=RB?} z-g9Z-`{z#QJeFgDK?985EA}j4`rCMW1tLZE{^-GgUwi}AE@&pt-;x2$Mn(FU6b9eI zJ1|Fc+?SPkF--Zj}S{(#7k9E`TG6bJTvzVS#(E|e?@%zi6< zElbDd_m=k5;p}cAmF;Q`84wg6J~vlwj53ZM_KT55f8|9Y^al~s-W|b-$-{V z{g(Ms-W#=QcY-l>k5Lx8xbQ=q(r-{ki?cwYZe07E8>~BL>Vz+{u~z7o1xGK5E_xUF zfrZgajec?_8ONROt`A0BhMIUp_?FzwJLaW@)3+}o!^Rf=84I11D0?1_N=&BQKo4(x zee+De=(I4eXd>5YRUFe^kgiXzTI9`1h?i?R7q)(;$xg~~)FEbDA>E03fBt<91^= z=^vyGGh$|ly3rPloY{_+F`R9VkT(2#<<9gk;Qkl){)(bI_!kP_9-I7gc5a#hI!Y(nyHMS=i5xGz`NO+3A7ms&yF#O77xaUZuX!}ZqQaA|I8#Ih_T7V z2HS(F@0!ZGu?#07y_!rve3W|*S|ze?N0%_s7zV+$M13G_R|r(_>)dVaI6HuPwt zt$vhgmzPeb?xNBTGW1Q8RUVkfA-B}#S+bSfqP9d?s~jQ`TxIzNg18Jz0hyV30jBiCR58xC|r zN}?ROl`dp%Qfl-jw?zN{HT4!yQFmSY@C-vri_$3wibzWiB_ODjiXhTAEes*uNFynT z)X<6u0us`V(lB%l>CoLH{hhg==Y9U4i{)Ct@S8JxpB-nPeOMg`jN%#ibVHq zs-C2hAqeUv4`eW7)rCHleLLAT5#=?raTLmGNsMQ$Nbmn`Z>91`vh24aCHp(bFDlWj z+`@T-X)H3t4jb`@|5?*h^n$(D=^;U_{oL);oeJyhVeVTwU^LEGjr7l9b8iJ^PD1t9 z=B~y%))L1xhnA1UK%p;3B9U+?NU9(DQy=jfCBib#+$jQ5{CnBJ*}eSDUbKX>cel+uM*`Wv>aBqJI1NN1K>)46Lu+f0ZDcr=h% zVEoEySJPS3(Arbo)vl5z`8lsGu7>le$BcjNeQ%+7_79q1w@{!GjVtoxX6{|IU_tIk z?J0YrAYa8+8#C)@Ehlr>&a_sUD2A)@9ISZ5G+hdn!NKR)ElC3@sj1m?c#UOlR()iS z*(2i&9c0@Jb9v6Erz|~Ld9&4dFMGg{^Q5c9Cow$S?f!kzkR_j0SK#)HN~&Ja+<)-T zP+%#Af(PvY&#E~6&sFh55`4*hzRx7j)}yyQV>oX$$*Ivka&jON)gPgJeK^`vXTA5A zVZ+VLH~VXacSM%b+14$EPu{&qGyap*}AXtub#k-$rL){gZB z9V-8su`LgZ)wmX%gS4&!!^5W?t0Fu;>yNr9L>-J9 z8trzRkxv;vVY|ma#z~c z14yVdeJH0K1AEo$B3r+qkNIrBN6_0tlb}$sS&BIfo14!0>G2`IN_H2H6+t<(W?=?1 zO*`E#RiJRIbgeI<31nJq%O4A09WZ2(LFqZt+8I|$CqE+$N_s|W0`9>@ZRo7n3#P=H zS%O3GRUv%To(%L$$I?74kUJLvclL>zWHQUq9BP_tfZW4AAvglmt4v2jy2i9+{iklXWK=PYo%uI?D(n zB|j=rQLRKwHXAIz0tr%<_pA$LQIR17DY%Xy=a4*u;zOTvOluNjP>D|WdtQZ7Q$X>+ z_Zst?ORWhFPMRv7o!(_wyS|=;D@# zO#MLjq)#Qz=xN;Is7 zwJs52;^H_bKaoq8jp86i)s{OG;|8X|H;NBEX=~G|ZqI5=9J4cwL$bW3sXzt#%82pB zNa|ObqO{fXFZ@MFX%+E)tTomrQmQBp&mXc3veW=c^agUvd-mG{nF-mnCfZxE@O__H z9|xDF^8f!$3}t-ihm~izn-~=rC$lsoy`xq5R(8>1GbFw|bCyCvML$T%w9OYaIBITV z11C0P8}rlw=Z0YyF0>mUl5dp+HrMJ5iQR$JwT*lGB)ON|+Q8 zx-Dv2X1!9%g}XkYKM(Q7xaOhX^$(eccht^;dMDN(jl=0LD6%GV)BkDB^;x&bFml-S zCd%tV?>*Uph$Eh0xU$1!avOL-R!Vtr#kES$^~<oK@%2CVV5^_~T?L#g5~%os)_mNyY}ch%o@n2sBiC*zw^rmh zxMLMJy>Z0Lc7T#S)4O#G+z}9<$nfdSuLZ@iXccg}pt*?0Nd^l{LSdpc%w^-{QUkdT(z-H8YOz$-0qZ!2Jl(qoeIbZguhg)C`WG}_$=|$_ zU3yWTX-~Z}4~$ken-09=Bjx4r1|>CJbUHj&ZDQItoi(m4Off!v+2^$fio#f4p2vX- z#*BnhNOx~ZUZ-WX+Yy;IQ-vsNLaiB(4)eMoF$u|?J2bb8 zpj<>LUnRNr-Qj)1$5P%m7i#Eh4X4kL+`4UD!z>;en8E=#-uU3EJNG+h#RpRdNO4(V zt^T&MCtB?pR`h2OnrWuPwAUpC#XrmwI-U)(7kfECg)Nau!+ur}p<+Ug(uH~v_h0_ZGVnw>Lzh*iDlqT*Z(nCRm+Zc9zjT)^JjQpl zw^j^RC!7SCvSH2J5HK(Ax6^mmC=-+jK8D3N>Ns`K4_q|}3ictw)Xd0o~h%n zehfb^gF)zadg{P$bCbnrte92i zT|DRX=Pys1?s-KGI|aa7>U_xgA_-QecHu=}Xq+jKM+6MNIavQk5hlZ#$&CKMl0H~0 z)D9Nf$8u2Z9w*d2>tJ+j<#33)Ye--%kV4i4dTkh+4QM~Bzy}htYLg}P`9;M8tzr@g zt7K5gTBaXshpMWZ?6E=jXRV?vPIiRo>ib`v%gfChWjRbL9uAPEM`HTlDAFl-5w~YB zTl13+DywE3*VxAVhGa;3WgsRG$S~w(o@B|(7j6i2P{gbiq(XY$E^wT|^y~VRiHIPS zkmH*f`&G=rdw+561>M&|9Is~V(79I<%OY#$ou9~hqvs|4MfMy4Uhj@B%m$fV{1`1^ zq!nO?Gc^Nz(Q@DA6ywUxXcwH5lLk;8+aN|$O;OkcuJGCEub6aA?T)-qv9Z7k|3q)u z$~s@3OYXxdccUT*E(r8oOI}8kCp5Sf93Q5vUc9wv;>7ORzWIb8-tj-A!}kyya3pSP z(b<|i`RgzoLQ1!q$3!{U*x+qlJe&>YKfX>*%cV2+$OsPyV+XfEflZ?cX?QsQEttKZ zy{OhVZ$_?{GJq0@{Pym5=T^ke*NbOh;HTlK|7F`1(Zwv!rGJIn(zR!d!y=k;kFS=K zu5KTB%ltc5uqBeL)%Q7=4(mTQTAJPCZN(el6ll$YSO7zS=QesR?AxTFZlu9y=DDrh z;yNpR>0tgVm~{P~ zaYG+$zC_bDHa(JcrFKiXvr^v?GxhL(`#pRQ%WGh)-yj$f30wfUrL3-!B*p_nI>Ej9 zb}>x;{YH?WtcQ{K*UKTpH%|!Fa@Arcj;r77!d%#sI*8ikKHtcw$sc_K{b*W`spW9< z3=-3jCr4KiIEB!g|V*MsdlGo-@xY)8ZlXvcXT^HdA=M55=y%(}C|hA-wE4 zD5|=~BVQ3I4C zfe@637CWS>ZTwo0l1#-Ud{!OLTA$XeC0wc44$E&Ln5dm>T+%DLIIb$<2x3oOVo<;@mf<+0av)Z@y8boBrVTzO4?m zG2E&kKq6xCTI!?3+A@OK2>>EFxnkWofpiv6H~xuJ-3~W5l!jbSsyKv6b;B-p^&nM3 zOj343m2hR&n_i3#$BdvR@uYb2HYG&oXsZs(?M1I#r6=yVMjX2g0qs1wBq-Rdq{qs9 zdXNw_C7a3+qTr^nZj+kRM~3b@kxHvj|K%F7&BX63)6>a2{D_9^0UFFA%jBFQL4eX0 zSPd0Bs|kPpg=@*=qX2%=e8I|-iaBjZw?W&mhCwh>kSiF0`C_hJXK;+)EdOkrLU;T2 z_*v`Cc6RaR$x7LdS!?ep)8RToH?G-dV9Zu4*Sj-QYAUp2teP4tH&eGDc6a+}LI-Po zzlVTAH5(w?4Me8fnT}LnB z>`@$H9l|TZ+T04^-L~xp)^iPlcNLPOoe5`|sFok%mY-bl`6s#e;B@G1{rZ=AFi|p& z24C}538xdu_A}yRym=a+YASBIX-;~*M~wFh+Mc8tCEPXnmHkLq#YF73+N*JiCFbR= z?mv9+DS&STQ!%)bXV@zQ#$$ML~MHN(VUd~&b&Gm+K;A3 zD}{K#^G5|@cErgrF9w>9V&j#Y_a$bcJO;cmq3mi#f(B8NV!8q`5gg7r3y)RUlF5c@ zrvy%s)9pE32YAPi+PL3c5GpL)Or8Dqieh3p%fAM7a;~$AUuE&mHH`M}dQs104 zzCZY8pSy+~X*Vmhj_p1cmrM$Gd*7&Ih;6jSe~aXipfAWlXE7lqz1K^{83Vqqdl~jM zKoznhC_O+U)x(2dq@;@Ap*eTJU~7nI+{^jJZjX6C48bVPy+tV-b)(S2DF1 zqXf)JRMr>Mz;Y5S^s?+!YZPi0-D(o<&Nz)g~WIm*oli`o@n z?A9ed5a{I{n)y-ge`iZ5?no@P+=rW#sn7_L>0bkS7HQVQ|67Sh?E5aNI{OMQP8rb) zyEWPYa`yH8_Yr}N;~Z0=SjdWZzAe((|8kF_#hcZQ4PTECWlDeT2nY6oD-n22 zXWFCIAot51po7Z_B43>>{?U_2TX{TU94Z5*tFGLod^)3rNbLBv_)b<~?vHGweN$nI zng!ELvPkdh)8UrMtS*{+02z(pE@!J?=UZBXjJf;D!r5G%nD!2<-lRY0F2607h z!K~AZ?-Dn3GrL}jA7BAf0&aGH$$#Xi+Goe=MB9?LZ%1> z4*A%ZgpX@}Mjl*<-`3V2H3*`zG$@I1qupk}_t1e; z(Rg><<{x8iMC@Jc(68f-H);6?-EaIY7advM`ERph{Or;mjtj|d1?UIcMcVRY(Z%1c z%&?ktBrOq%dN4}E$Nje95#_qXfv~E%m+CY7Cp*q|t-hm2%vlto@G9=9o5Yi$?6CQi z@H_8s-R)2x)}AUwqzQ6B^3^dh8%CD8(AUSwcuHt!-*h{&Xg&%HJtYdfpwNS$gyFxQ z-QY0S{{!24l26`RI4!7Q7p>+}XMr1s5h^LdHd@i{C_n4_l$l?i$^=7mirU3_H^DF=!$i52Q3A_J?o?rgv zSH>?8{mz?hBoG#=J=w4&+U0O zPXHXyXYQ*Y8Gr*uP(F_5`p6YgxoG0y!7+#-dA$AW_*uH_%Oe&;Gi4=xW#f{VslMMQ z=nyNEnAy0tqmHMn`C@xHkwVtp&(Ho@X|Aqo-IK2{leqpE`6EMyo#)y0A zZyKtHRYH#pM02#UiEB$Tb|kJa)r}pZVzaJaWszciiMvvY+*9A^IYF8u>=vl>mezIa zt?$w7=xK6UeMoHvDbqS%noAL~BQ|1w^OTm3>0zsSslvP~aOqTw^vtO~MaA5%3$hso z1lD@k5Lh!Uba><>3hmnY29~rJ^@iHRD#e7Zc?`H}k>DDb9W?XKCc+m3FY{q54Mz5zmzm(Rlae>mW&4&NB>$Z}Xm#vZs!9E)QwpI^vO zU-0iYb}_ogUt(jL-=wfZj~J`oAY=~%OPi;AyE^N{%Eryt7>;lK z%#oMI<)A$x;^6(g_QcJNMf|=zD1q=>n4@5cyw(E_JEm5y+k2-UDhN_4)OitYEKe+1 z*xGM2dD6_=vAJM;&Bmo!j#)r*HqSsv`p{JHajQgWyF@8D@Ja!eF)NPL$kOUaPrOR{ zc3Pls!Edhy?Z?S)FqJ35vPNU211h{s#HhU>{oDOL#f?d(vB0Y^ytON9%@8g>ofQ)Z zEQBCZ=@{7&x=n9cg1`=6@tmxD9#)BdP&p9~UW&K+kd~fBjDfl`^q;gwp68+Cnn%tA zabks6=E&H#gMg@M54IFbGx=2j35^Qt7`%LkoitL!TasB+4ChN8bYg=H`J6=@NZ5KY zqjSFs&b4K{lL4G`9N|>V+dQwldxXo-cJl37p zP8E1fn9HE-{jGMT=mBvJLJ6yYF_J<4R?#HeL{C5c=E*VN{s8p}&L6fQeGKkO_0(5O zS)>vU1I7-iD58=f5mXnGtuYL{i|Kga*nS=p0?|kC%kz&Yfzngpx_Z4$D(@Mq`A!2u zid)GiGdwuz>4%Qzo^}j`$^CA%CgFu}v9PxedG|LJd@|Xl^}%Yuoa@x>;}pDd*Qtn| zWLRr0^z~sm`$5eg;z2dAAW|djtVmb{Cky zpby6IPj;wV@!ly%{aO#W0Z7XV{ccS33?{}2Gzh7s{YmMaxkolJq!DA0uYD-Po+>Ar zb{G}OXBFZ}y2CJSHc^Vp`URaHzy*XeQ%&twtDD3u2X#oaAU3kic7IwU$h&^;8nt?N z5lWNba`k|l4>Or8J)l`K3t070dO}q+X>VEk_2v|;K@^rgSQfWwxyjyb4HMjZwItpV z_m(_MGSsOs)H#%+ zKMezJC?PD)wuM)gjGl%Jv2A2c0aVR}5cw!!lzA8PUQsDL!kK>7$sWNJn2sBX-Wfnb zk-$ZEJ&pXjJt~}(N`_QIo%sIJtYt#`hqVV;r31D)XC^%gR01KZcv$WVQT1raVjEv= zY+XSUD411OY3k02Z_!a-@Se_g){lE~zTbeq7#pCOSt(|kC_q6S3GwR&u)9*QZLkX$ z>F3e-2L@-!oG!4ejfQjOXoA6xVONUbchtV}`A~#ly=f0+hQp!IFFj&(`!7PtH(3*2 z{3CCdp^Rl6*UHS(#J?6W(=nSuKys2ox^sIX9H(wkHSSk66&n`zPaeHWh>=eOW@F}#?cTo| zuu{wFxQ+atN7W;<4_~ey;qrTTUhDLcxxO|t4f__qV49$Yt3!|cBYSKB+NEv?zeHq~ z2e$_Lz#Aqr>H*6pjy;VXwI;Oe2u=TPDS8oYJ>DPIp`KtK;+I{hH21l@-Y7-X=ew1?Y=6Q~_* z(M%$KAPT9Q8FtL*5ci3n-yQJ`MGE1o7m{u~EHXoP#2|hmEyiChKX3CyQd^zTyBDc5 z(|uCIw?cPFK-kQP0^fsrzt&om>7V##fm#x>*ti$h1wUXlmR~KbLixS^Q9pd1=186w zeSf@#VPVR$=>YMgRIS36qnrRGvN-ba-Mv|>7gILzNd{F!so}vM*~&3IFEgxDRJlAn+{eBN66mT5~GvG;H#}ed2-aEQRD?0f|c&K&qi#?yWBx|7` zY>YBH?^s#Dd|=2eh>u75k}>77!yN(O83f1pWW~uS{6gPHn@;Bx7j=7@^d?Ia6|&wF z3lw=Hk3KSbrw#+bo>=Sdc{RUP(66WObu&{9+FlYEPi?*e+l~??6PwgkQ z&@#>i(j}UO66u_65m*-+S&veY#}NwlFgqh@3*%n(He%x{kIQ*HwnV}-Pad#r zKj9nzEM33Zu6x4uC!r{WUX0vM5h&91R@+Z0v*2pTEX3NIqn6l3@WilQz$3@s# z^GFnrZvB8V6^sh+lWQzp@vP-Ic-q|wng1OB9}BM=Zc`?}%lSP&)HIinQN^9~I^m7q z60C)cB1O{O2}kD8BK}POnCxLm|9t$@Ayq?z{6uP<36fI3Y56Pn2-Aa^1TD|Q_Dge#1+E`WIH(*KWNPlf zmL}>~qm;$|y!+Dq9<4WrYD^r0sjNF36Bn&(C2i0(U3B)k=3~zF^u5=Xga`_~^2pGn zdp8NH<-;Fu$&*{3nGA&-*B&Du#!<8!klCc4OK5yo?OzBLve2hR3}Rm#JEKgIbPaie zhkvoL5oR>=o2)Kv6z}d|o4n_d!Lbn~!&Hyr_A)m-E6(5Je$(4su*7%Z`R7%eXFRn< zc~WZKLVnrjo8uTLa?fx$!wPa27e2qlN2%~P_uPCBDLaSO-ZhB8Hy*@jSl+3MIp`F` zSBKbo%#CDpa65=V#*kLg`m*FS%Xsp#xW7Eblkt>_{>P)F4@9btID(u4j;R}Wir)Bi zRr6H#&2eY;h&hPN>mvNo*Ne&7LqO0}+V;#;Co-Ws`@ZI$)=FL#PQZXs`4Tpv6c_re zt4Y(~u2o3Xw7m>bx}~X8)j3GL5K|mFm`12)SH$O-C$_g zDogrrO8jGx*zDJRnAT^ah}?Jm&>ZLx#M00#9@F|M98gHKWhs%Y3`Q+$&+NIT_ zh=W9i?>Kdl_7Qx748u((+kfBCZ|H+qiOlthp&x_f9GGt4v$f3==zvc&%_QObZ6~5+ zx7=8D<{pUE0d!;uD}_t*!@GjXVZSwC1du*)Xz~^nd2(eHrFw{EeG*7QT8ml4xPf%p z)$9ee9ql8q83#IelPDH($NPcoQM@9jDlfeygU~1jubAoD^iZFOojC!o4ZDplBrH{{+H@$+;v~O56wAD z8ETh}YvcWE^kNDXB#v)*U!~bi7Zk(#E|MWD%X99MoHeUX5snC4YC;8JgcKdp-)ec< z{?Df;l%7)`5DP$GoDa90T~cux?RQrWhXbC?(`h9(_eI*G(!w~Q;2cl1gx^ayzt_$ ztb2eMLC#C&CNioP`9G9BQXS!UJF1EZMP~(mh(oGyPZWf<%0uPvc~Y3u-xYf(YQp%# zuI-hIU$w=(o&j`Z2wE@1< zYE}Mr2Q^LuCP$nJ!CW1r$*W1lm!CX~n}Pkstn z#!2UUfU`yxLBKM}z%6JGVYt}M&!+X0qhZAg;Mi>B=!TnQtxZhQ#%{)=iYC8azv{v0 zVGzxf652$8V!Q5DbJ9N`Icwmh8BuGg4=?htO1sFwOU9W<>(h<`vkA-3PK4HzAl`-w z79YYR#rlmsXYyNobJ0${E8NDNO)tud~IjYtAuM7Gp+HW zEgxFiGbI>L5k6rqAz;6T`&b;i2?UJO@|}6L9hFBB-_5!L;EArtm*Y{irhK(zqudMw z0hR&fg&p%AB`@VN1AKvsp;_P-&AJakO`ws}k)uw9z(e*6cdLck4wGxJSQM#A78jxQ zaA%@`e~b5g><~W!81vW0M1s6B+AMAFFm=4OywJ4u5EA_r^|XGQx~j=X14@6T{w<1F zduV(5q#ZLl6Ie5$Z`q!A;v2GXjO7K1k{Q;W_HlvjkTy!In;`;BH7&#r9hdlsn(PL> zRL)fE-Yel)J$Pjdm7aNr+u4i>rW$j39w|#Z%X1zJa}32*M;Hh$Al4#NcxKARCwD)l zz9s$S8Y46u;Z~*;w~yGeEY|z@N}gJI{=B%8CJE*)z-v324^{Jf%wD-G`yjg(P9b9d}&cy zh89HzA(q8jod~r${Ql%}oRpyhMKFJ~VxDBEQQD_04VCbp5$yNdstcXB_?Z%Fi&iFbzg!U}w8(_*uvc`AxKlMVyw%$UdDuKj zrtPwYM^<4&#j_4Q|1rCyhN0rVH2#W~-%{WnxULzr6oJDYac}{g2=dxEO-WJUiPqk` zi5w2%WJ12QA&QR`coJy5eh^22_ra5gWiiMzJ<&>m4)UU4;1#gcQC6lOq>h9V|M`8n zL|C6z_@c4Bq9~msi@c{Sc zC@O6WG98w%%g_FI7$1O1e>-RNt8qs(MUTyx3CS`sUHj|##N?xEEyJFEoqU)_ScwOF z%)&8|SPDDR01c8ECC{mf6nr*t;B?^NW`2uF;@v=ZXZas9gsnXpaYdZ)kX6swcGS~n(^|W zJpq>93gq*f{6H5~Sk3k-&wlmcLq@B&d8MXk&`c)t`1+G!m*7qgVnT{2CVC@yl-bK! zDE~8+@PIN03U?>FE?G(t1!;A+c!}R!8#vjkfuT0OEYzU48j&r|j}}fy{5?HW0QUAL z8gVFLE+gO8>C^!cu@Ip@mExOM^4S184_)pI7-@i?@^=VDh z6MCvZFfI1n$8NwNmi2o%yNR$v|m4#ROEkSYWi+Slm)tKhva_z5b%+?PGj4>GRDWp zQHN)~0M}~XdO*E+c&-H#^0^v%dt?oC2Kk^ucl zrEPrg-o1~gox}@(P6zZSRcIMK#tdCu-B{N;L(s~>2WNwO#I*{3cB_jHqbOsvgAUlU zQ7(NgP`nX98P{7nQ>h@*{Thlil~d62B~Xw*1GIH_-iM+;g4Sa&K}MMxfj~59GiEd$ z|17!qwYb5XMka_9=-tepq-h zy>F#KQ?XmxB^+}B!LT3nP4YNm?-BU z{U+YT(>PnN9{pJW(~kvD{bD0!Zg>ma_~wsqsGn~uc{IALT?e1%8MvPT%!9*gpsgHS z)ZBf4%WJ%DR@v6p7LdsWOG6ZTjYW&`N^Bl|ClB@03ok!9Svtl%l-sZi>e|77QQz13 z0jdyZ?R!?`FMZ@C)BV;5Tn=aFR-?Cu#>U2e?Sv*=F8qq1F*efI_XhNalvr^G@SZo6 z!CS4}ckmcTqFUm3#M>EU7 z-OrHKv!ioEcxFE~jAVzu-Z(;C#v1I^CmyAd*^7Cz{>^gc@jxG(Dlr2m2Ps&@lF&ujJMA9UmS*o-s8$%NlA`_4@vk_+TJm0ID7W7#@Fz zAuLZQLhfv{T+V%aT5@W7nwhm?#-39A8K4+BZQMDN#Ub6dX6oqN@&5Zr0AwuOImy_` z23RA|b(kX&6P8k$z?JRSq{+m@Lh^C^UL0w4+K(E8Y!Id6p z%ztfY*dVb*|6<|fWF_+oyMoI63OcFY{Cq7cC#MOX4%+vDkN{jF_F^J-aBcYO+I&k; zHRu0V74{8IL|7wkAdpt*XuHr!;yl#%Ioy2j>zaWrn@>Y4~g z<%Wb1th-2YW~2R&N-kf%sX|xSju&&(fDXTZp_AZ$A{Jn#vb*mn2Y`(M(*^RK+7bgU z>wQl6*!aKC(a3Sm(B|E&sn2PaXBUHzr&T8J|9_C@ob;OH2Eh_>ac$ z$I8k|YcsPT9bMhEnw1Q1XEP7(TV9tZD^0HJBX>c!8j!Kv_pNEr*NxtK4kYb=B5-xv zu+b;QzIKfpw5hv;>;3;KawreH=U|xJ`2vT8d!6CFZze4*?H%Z8N~+kgj3%nN7jCEW%$c>nzj zpVhCWsPkIR|4iGUwZ=Gg22XqJ0Z86^2)7HLwlGG|HAIldo2fajk_UDZilOb zq`>6}r%SuX42gaL&c?K|44AePGhl&Lkvo0nwIV(D7ytpcs^&C`bV%K=|L+asb9SyS zcfJ~*elgAgMvi;KpFfqK-S`g;FAh3nluK3}?o)1TIRCH4EdUs^!uaJU$A*pl-) zyu%{r=Tm)EGh_dPKJ+73*8mJqlw5R|oL{@>j6Ek#m+}6zU5%l@@#t*d`QL8f(v~|( zkb5k5bs#7A90l<3FA7I<*om!yVEfahRRH8H2PeIo1Tm#n^_=->{-Cq0kd*B|LY{>^anp((mB+~YwZi=xTNlV4?kd1 z{@a>YhnjLnBQG=uH%glPqCv?VVBi03C(Tx2^Zh7$b%Gjhz|KC!xj23Mnh**$Sv8Qt zRHOg*)>;+~D>6ITn*OK5hm}_)HTWm>&S>?)w)NXR_r zx@dPeC-hww$;|%p<@VH1TRK2v1F{DY#bgW=R*$?s=B)|dUoFEYM^fRi2vWH>xHeGQwLaK{M7O{nknU#z`@}b`kT)9vx5%?7iI5y zoh&6W1(geWa5DxwHXVRCzj1+`0~|wac^7BcVIVr7LIC6v;8TCG@9V$FLyQOF=NC=i z^%sX>{(r*`e+&41z(pu~`j!COj{`FJ4W;PF1_TDd)9W>N$p;hLN5p$1r{IGRv zgDPymhe!gqt7x))}-7WNMl0$wJX7BeC&hi5SSSvKX;05j^5a(LF zwrf@dyB1DCQ#n1pDIefQ6T=t!wBng~wN+fVor4Q0*@|JSeGYyiGd>4>ibQsVJ$lMt zdxxjr`~>uKpv@3uMmR@b)p&FtC*HN`8fP5D8JN+8za01v(^{;4s01h#+^-JZeaGD| zHq&Mgxoc0B({PyvZa;!30Gv-KOPps;c_ivsaiyVWGIqtYE%O{dWllH!N(Rh`y6Shu zTbA7`w9f2xPIj|P$Fzi61#FaRXHa&Oer*t|{5|HJBGzx1=3m1W+g79g^LI6RNNS23 zgJejsXe!U2-*j(x^$blrbWZ`WOM7fzl5GE_fqAH;Dr3Jvqa8_Ci zlIL_;-_(D7P$sbEm0+W~?`eNwa=S3P?WU{C23&l_NuBuC51H=@&PkwZx-kgsJx_L+|d|{lORDRT`~uc1Eyu5Ijgk{BgTL7N-xp zrnxn#GiP$Mb`Z>u9?c3v%alV}>nPd^9-gU3#w3r;Ite28UYAZiKVD%cessxCiJm;! zUy3Qe>Tg8jo>ebzOyyaSeGOqh1n2E>aR=vtfg+^bx0xIEyYDqQo&Vjt zQXYHY&1-*tHg|Pd(r^Mc;=w{&*uPr`NdEP!S6L?~CkyNEzN<#g-kVgXo?$IKPT!^0jjQmU0biB6y*% zTaEVzNtIvA_wK3({_*iE+~gr^Td*pZ3o}(UrGH*G!@4JI#ZUnbusA7$^A9fh1DUWj z_znm0<J+n#9gS=BS_&ez1mn>a7$D#Zd22jQTb z_rTHMm?voIvFXe-(YGfa%ThI+=kcH zxo=(Mp*805rwZ)Ew@uO0>0Yk&C`|p}?~8$y7oz{tAK9dATtR^*oJAb7*TLq0+AqCRzcY}n2(0k(!^HrImTlUY6OCT``Ra@Q1V7CujD#M` z7c4IpCO;GYZ2TYNNw54_V5ET03cnnj|h=o9~v1>8imSV2&56S`e8 z4>yJk5lH`)xg+wOODUgI#>W0hiLmN6pfUhb07-?S<^jlb1(1@?%X69F@ZI6MSJ+`e zbNPW&#c#b5ZSOq?TwJ5Cg+&NR2W>#n0=V{2r=61tkI95|(#cB1J1d%&={y+}GWsT6 z)DwMjUo`u(U$~Ac)QvF71Q9rTpLOKoQk*3NQJ$;57+ciq zlwrrB4;&pEg4u=0R}ge8_%Wl=i|c#lQxEbFdV6NY?|*R8yA3-6$#Bf0XBB{LpdXyR zeGfpwE!UN(DKoqt{l6SqA@0q|Dh?m@-!EL%^ndvvxU~4cpW}+1|NHspXIEEH$XJje VMUs%$8U*}%tgN9_{Lm!u{{x2|$2|Z5 diff --git a/tizen/skins/emul_480x800/default_w_p.png b/tizen/skins/emul_480x800/default_w_p.png deleted file mode 100644 index 98de699ac3e414a4e096507a4b34a3c7e808491e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50292 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 W^ogiU|HwhWkA|9#YKgK%$o~UD1_!$U diff --git a/tizen/skins/emul_600x1024/default.dbi b/tizen/skins/emul_600x1024/default.dbi deleted file mode 100644 index d93bf49..0000000 --- a/tizen/skins/emul_600x1024/default.dbi +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - - - - - - default.png - default_p.png - default.png - default_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w90.png - default_w90_p.png - default_w90.png - default_w90_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_180.png - default_180_p.png - default_180.png - default_180_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - default_w.png - default_w_p.png - default_w.png - default_w_p.png - - - - - - - - - - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - - DIKS_EXT_HOME - - 101 - KEY_MENU - - GDK_Home - - Home - - - - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - - DIKS_EXT_CAMERA - - 212 - KEY_CAMERA - - GDK_Camera - - Power - - - - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - - DIKS_PAGE_UP - - 115 - KEY_SCROLLUP - - GDK_KP_Page_Up - - Volume-up - - - - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - - DIKS_PAGE_DOWN - - 114 - KEY_SCROLLDOWN - - GDK_KP_Page_Down - - Volume-down - - - - - - - - -

- - - - - - - - - - - - - - diff --git a/tizen/skins/emul_600x1024/default.png b/tizen/skins/emul_600x1024/default.png deleted file mode 100644 index bf63d2fc0e7e3bb1308d40c61a4cc5e105c6bbe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68407 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 diff --git a/tizen/skins/emul_600x1024/default_180.png b/tizen/skins/emul_600x1024/default_180.png deleted file mode 100644 index 198d4e966c42192172a780da4b3610478db62bf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67941 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

=M#PVY2M@UCN;K##Od#2QM5Z~NCG-Q-VNRP+< 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 diff --git a/tizen/skins/emul_480x800/default_w.png b/tizen/skins/emul_480x800/default_w.png deleted file mode 100644 index 7be72f73f80ed03e3eb88b678449aef9bc0569a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46793 zcmZU(cRba9*gt-#j1W>}L?|mGI~*gjoviGgafoAP99u+1B-`Ogh3q;w*0E(f$KE3u zCwm+tnztnAP|kF#!~|j=n4)5A{C_| z177iQc+UZ`G7!F43}Rdpvv11mB=H&NlB;mmNR$qwtfq}s_IqN zuFr3;#K(un-PRYRet&&}e2Mc*eB{@+?|V)cg1)+rVUAY%&#T52@Fj%o3LJSe1$C;1 zxV~gKb)hml{qM-m_Kt-mVWo)c_dP*$6crAfK16O3(7#YH_#sy_c_WA*m)C@s1 zKVplypj}hWup|kOB58h=_*k1F{1!+lFkU$yq@+d?o}JEP2>N^#WZP^1ViBY#1hVA~ zTNwt0XaCCxA^}+>bKWNToCvzd;Q00_$XO0lf-`=v3Nn2Jy5*$ZE(4kn0zJ|+anb<& zs0KA->8Ma33Tn_J{kL!UL05x7wq4xZ0idW1&@Ht+6Y%cCGCI5fP^k%a zkQcd$i7-1KR+H)BEh#%vyG$kFR(J-pScC-aZ$cjk^f~c1aJK|v0QN>17AqBxzF{M@ z)ttx^@}^Xild z!Sk{g-P*UW zlgEbpL>cvBW+g%WteWcL?CvmEyXK2pQ-NEH`ZvAepJv7p#PYb_DSzVs^we1}!DceHmTNODRA;tQQOft*Tb1dQuRDaZ zdE4@ryjJFm?*DODz*b~L>8?bxzH@Yv=MCXjqnaD?p0p=+6v!4nOa$fCCtVZ_cAQgh zNnX4+<&LLd%6RjSvqj_T&Di_*y5HW?=h9A;)DSgz|NNej#@#)6Z&H~UOSQU0xh{~{ z>$7N#x@d9)N?(42x=N+?yEIFb+83$;hgYJR35=f+1KyP^@^MnR_<>?)+NlHumCi@a zfA5fsx4S(O?r2l~`B;!L$-eg|R|$1-2g?uRk}LJ^4(xG1{jc7PP;I7^y6Ufd&yM|x zhN+I}vk8sw_t@@B&`(iHQ(lSEZ{_7m`mSBcQ%8T?e&>alXpE_bAotkK1O^ehptmaR z()Vw^QxW5>{Ya|$^V{>Gn?q_t?greef`teP4HoXC?kNXX6uC^Y;Jt@kZ_fHj_iC3 z9|K_&s-58$mvQ`9PJw++0OH`e=^ulpgx^=w?0(w(#JYPW?A@u#+t!@54{H*yBI<=yXmaavqX{n~g8pZm>>gx?s zWt#=r`3zAMr>y{oTc)uyD9 zXP07^wh)zAI|%+ds`f#RHqNEPa`FBmtOM5Zm4}RnlSdn}2HDCqfYj#m=gaBH>2&t@ z^?&If%aBCKi;j!o5qQKnV!qneJiuHK{T*H7sEJxK&o|pbW8B}E%b4Yv8kt*FsFh}y zJ{YSntuLT2sC}07tQa{4ZTqo{?nW0@GyhngAe$~j!_Xmi&=*Y5>R)ATTS*N`A$1`i zi1Oq#F_Sln@0#BY^{Mo}C2K4@mx;~VQVjXEpSmgnHO0~4Cd3!f488pAF4=~NVRa}I zwALq*@HY0H_Um5ZGzDPgxBl{=B2`YxBiH$oP+b+>2xt|aTf|-@(WG?zM|GZm(UILYlft2bcg~{1 zB3OD(Y|hN4PrA9ftGZXW%>!xkW?m(X`@-QO@L~{D5dMG!dgWcjlL!ma(|>`%oK5kH zveS--sL9PIai43S+=1S` z>l-!AHq~^~W|I*XD3fw`Yn(sZB*gs5{zJ7G#FQ@5W#tLa#kTIhDPSxVz9}f1s-*Mw z+2iD$Cv*be8RH)8G59}-zYcG`+Y03p8I&4)JE3AJ!2WDcLjV%^X(JIM3BUhKJWp`B zHj20KBSwctXBHugWX$xt2NRQ*Z4iz8l=#t0xrh^zgods`SDgHMOB~;z&VRYbR*SHw zkaxRQd@Q+UCUhOGod5T^Ip4SdIST4%;?>u16-d82PY&v#+9O`lEE#cFx7-&DNU> zpU`>H+9pDGO;;L9Udo`rUhwJbi?^>mj5a1K0oS}o3&2Koi#JWu%0e4>0wJyu)-64+ zTdGK0*Qt!IFTV*{pBdk@(lr$^o3FAviOyzKxc%;Z*{x}&wA*15d@}*dtT7%vO&K%E zm4(IawGKF^A*a=qIU%IQjntyFm9!h~G?P=6H1o!ln+J!g(;{j8eAD%jXqDQpP2d`g zV?j5zUrzD)x99uMPo7I{4b4{BjsJ5W++q#F97=4APFrA(hzi|}(?%plkWr^m$5YMI ziX+9ccSWoJQcq!4rO#kqo1IsNt`Nz&Z=lC(M@H`s$v-zp7<;&`exsA4@jQFmUx-GE z#^^&<#~*Ibr|_lKBg*+Bb{g3!zqp{11@d7Izq`=8A}^IQ_cGNGhMA`pFD&YG`xFMp z*5(4w)TcRUvn0S~a4o{~ZkMUm*TYHBJzQLNN_I%7@bQf8^cQpx-X1&ulGbCpj_%dM zkm^M&UJfINwcM+DwTGHsW-zHS$t;((fvvq-1D_`i>vq;>)n}H~TDsP51vXR#IUTLC zBBimj`wj42#*490q>TJ*10m4k=-1J~JmYMrH!l&}TR-W~yH$$O#n|jCZ9bV)nT;7$ zv^bxc*q#Y{+3f$BFgT-rMD`{Ucb<5VK&x^sAtRwTnkIT3`B*_l=8vK`arLY~1?Pa{ zK{B0xIqxlFViXDeH@ZHK9ZVn0P1{RLYJvsl5!ag6naig;T07Vqy92~Ut@n*jH(UH? z{O@jmou}1Z3ceS{cj0{e^T2SR;53OjDe2l_>LgZby!!;B@e}M!&2C3;G>fuL>x!tIseHV8)8XDDx@O9_t8WQ(7m0UB;@YEy z7LOdX^-G{nQ*UXfhOzKJt7=L7f;*$s=e8Obnddor6cj=NqUA?^6s-}ivD`-- zZCTY9`E4E)R=q5p@_c+NicXn=^YUB2akjA1|2*Z43Wxr`*8|l4|1WlZ&CF!=|I_}C zwxpzFX2iXkRtnLdmy(i#SU)&1Xt1unL98F;=sVvn7b|>lu!_!X1t0kI%zCQEKQTw>dP!#UOlpYSvAFrBGmYgZJWJbx zUUXaT{%OdnU;S6b`uciQLxa$GnN?D;NqG+er+D$t2Pc2@rjtEr<3fuasfz?3x7c^a z6Wf8~jvsDL^FDm|5LH(vP+VM$s;s=<+uJ+jUY$4k^22W#!>0MP7TbG~ElMZEbKi?> z;)RRAl3e&B)zbDMo zpoN$5-}ZbQTLhm5j5#qygK(T)nx)3|Te=+{RpyYjgA?BiHhf)ZlSqTLu55Pv#^z@C z)>fIDyL(T{LlXykdlg};y89xSoz^OkkaY`=uzw3NVVwK{ji+1nIWpc$T^R=lzLQO1 zO@cx~-9tm4BoGiYpa-L)MlMna?sA{87BhhS)CWuF>UMNbzK#txMrV{ z9m^%W4xCjb8ec-Id;rSZ;6iF z`U#Yr100}tS@6qBqtQG--7hO`U9Md``YEvCT%g=*#g6?*LigPNaC#1r9H@r$8H{vU(7Rs;=e*>Hsuu zKTsa{ncF0ktZQ-}a-MN@rF+Mn3AcXg79kaIgBfiPCTvh4C0VICBWoT8+*q!yWKmJw z7Ka5ZN8(NKI&Y8mu6>SeelDj`hbgE1zIP3mJM|_v5NTE7$jm3r@?jkm2=*{ygk%vj z`dmj}R(%_NsaY|}c6a(NEp7tPGm&E#YMW<5aQDr{UJ6 zJ0*i1-^J3LV5Y}`+sXuRfh|)$1x~dY4!$3BhI_tL_S({fJMOqx#YTUrPqN3;G1BZY>pF*ojhYKx)mU1*D0 z9>`Vk{@qMsW?_+(mzTGW>0{oH_dojw$M3#@-HhgqfP?$wPLI3kJQ>uqx|&x{^89^i zlc2Bc$u{+JCmjDY>6P97n#*Bcn}<0jabr2>aga^Sd>A0*(zyf|PSX>eV;7pY`CwKF zi;Rf&sOxU`bUd9IpJE%HNf4Sotn}$kT9{_uct*9(e$k*Avlf6YqR#JZ806vtaO~&r z?+Asems!?w0R)5r6Z*vWen-+;pAN(*RI*eZixhdOfTcJ z5;yZ|7=mhS6b4xB@bFNLb7GQMksT$dKT-2gaXRA8h2FEs1+#Fl!ktA9a|>2-{xMI& zq|_R?;L4=x{G=v#b&niJ9o}qM?Wx<5K+p%V3{({i{G1q{DfR^t_3L!5CWHK8+1_ya z^=@I(u&D)^XpgGWlQChEe*dr-OR{mlCY|Xe#I@0+3lEm*e%VmD?zjx~I$+WOBJA&n z)CTN+!R!xd@3m5iba5wuxpGcM3eJE3>|{T6tl9~lhE<1bN|wX>5%KKu0_yQ>iPP@& z5ch@y<4b<3oQ4&Sz8qRV_%^-S@aAnR{dGF?1O@5*`K5vRw3TN z0UC+~y~u_q55)ZXvK|1yEVHWT5otO@fp^;(_9pBTy73A}wN2-(OpQD8Yrl`n>bFi1 zz$rK5lX!J|GQ^=vD+rHNgh!*<4YtRRv?S-YkJJ|?m<6F1Gn12vxZoA>y$oEi8hh~0 zlUl#cDZbOgnj;wx3YwwZ-JjA`R93~KYTZleRCSC2Nx7zF@=HekE4|S*lYgO1bKw4_ z#q~Mi_06epHjCd5FB^^JD>l|ja(f>U?vNluKYQqzXMH5`s-C_(>OVI-n?gK2>b02L zV>}+@AnG5JU;O6iinv0a&l7`HZWAYWYntassSLctd2S5*Cz0RqA=HPI*MH0um^ajdu;YjgHx zeeMxt8rx;=g0r{)Z{YB%vWs*E2K1~uL;z*Rz{i(n#2hHWN?1k6$C z&E*t4yJMLmPTLgSFnm7$0Icle+8iM#dnb)W>YvPWQ~ zFAZmu9t$hEhWb2SQVh}-=MpY@Ag4;RE&#H)w%2oB*4N*NZKrPz3 za(7>KFd>;j5wIiG-J>Bdj4LLSFFOe+2-{;%B|tBi{``vd{?kqgKdPS>QoJB2iW~%n zyp+uATb){cwFIc>-iV=YH^6&F+#oAT?QxkZWU+U%Tx?O);YcA1L;kyWie-;vOyO|J!c$w8+4-;+zG$;{#$ ztXxv3*s-if@)r^K$|?*-P(6V?1@J{{iBosrMx>FzBmqzSWW4@F0fxZi zRbv%kahu`3zDA8_%ObsU^T*GQdrTU+pxCU$;R4-W8tIvPrN*w6i17dC^M?R;cR6i) z8x^>oOBqX4XHVof$>sQ@8+J1MmAlDI!l!&Z=~)3c7Z>1^yoVvu-GKb@D(}y3m}QFECWgGe=kdL zS*4~OswU4-0Wg616GL8Iq@|qq(%Y=dwqbTV^l9duD)=wQ4JeMbw)UQD)1m9$s%}`| z5)7+cN#DwsXA`hhDW&q_Kp^Ij4Lxn?kQIyEUShr1{EBp&PWgLQ-E0~7cqwTJpbkRL z1?H?b>{vwgshUyN%c@M^IFkTx2Q~=*Cw(4GR@N6Mm|JR?DH$%)u9KI)6+@+X(6KN81Z$edlA$CFm#SL@=LRc`RY^H~Csgsc$f~#(MN4RDU+TJ`h)D1D8Fss? zK;eKNn1=t!Zkhmq09~Lzo~EAh2xwz_)O9)`v1-5GUF9Eg@?esBp(5A+S}_D(XO9O^{W>;2($tw z;xbHlK2E+23Y*pQ!WVxzh+oq_v=A;c4?95mfZ5J7F77@&L{pPR>I>mRP7k}AE{-m& zPl%0|X584=m||S5{3c~H;}NA#1azr3ARe_@y-b59QY(xZT6FjS%m15hQo`+yv>U@A z*2ss6?`AVn$s!|wR7mB$^ZUv1s14D`rOKQ;oc%`3rD|Tr0U*p?wzz()Zatkopb=;b zQr7c#_$6;${RNm*^U~D+3pF|C`vuFrHs>fnqryw3DD?7mKh53;C1*rdD#pVtC8Dyb z__KXQmyalvRC8CSs$7S*kCr3I**_)(FL47UzZ3`H?OxSet-g{qC?9tW39-7Ih2ve0 zi(RNd8zGTf-QCKM;`*A*1^(hJ=RfEBZ^sU3T->eyEjDMlEI`&-kG+&b z7o|h(+kb5OSpc{CO7<=g@P}SjE$u9{{pV?*0xg8@Bwob;pa7Q{0Dv~It4N-cqnbSb z*QqGXBy9N+$i_e#=CPD}vfzjv7b(PE`xGV$WoBJ5*4nN|?}}wS7m9`>m7NYH zps>MR;d}LKuVlS9rz9rdA<&$P@szHdBwnHV`F1Oqk1|8a6~}be>($^oT5Gpl9nA@ zgGQmmda`C$UzHWFpH-EIK%}IkmZDkRo7buDybydK%VChdon^Pe96)x9VBT#xBEtjn zGF^<=F9Hns*jTEYhevOLBGKjYyuhsdZ{kQCz34o}7+*)~WH<{y#?zREZA&Wk5FGIV42B7CKg`!qg@sU@<;s zPWGk8_x*Xr#I7#7a2XrE;x5~ zMX6S~?}$lU>5=W6ma<(YUZ~o6)9a*&HuqL?CJb8V9d1?z8AagXO>$J&V$!PB4{x{- z6!2{mva3umwx#Se)sy!2I~k@HMSZKP2!VX5b+;*o+!g}Rw(unWkVb$AE~l{h3T+o+ zZa-f?v%)z(}#A!L;g4BGGyRzKP%$`oj zjHa@OAODnaU*F6o$V08rEh`~zmg8zcuqyFi+rDmoHg01YH4p4R}hpZGO^ z4QWxDT2fZl({MC*8Zonj!C-<7)&4MpY00h>j;~)HWGGJ?*y6~`UV%(Vk!B6Q*-Ks_ z8OXxUysLFEOHlxQ8xD8g9DfxePopmx<-zUXbi+^fF2J38L)s!A_WTY`iHQ|8fUDTs zL$QGacJf`u(^=3Bm6fklfD{63*oqQ#8?4iM(?qlZUk}v%(;Jez;T5f}1?SQs zx1#sul6BTIPu+|eU&4r@4}T`b1_{^YysN5M6VK>6%fhqgtCT^Ab6=J$9b1ziF;Tkp z`KywBzv>s(1Fk7&0D30DLUXw#$O6L+URF(Y>1Vb00Q_-qaL`t}Pz$WB#61}k*IUu9 zRha<&#J&Y^VS6>);RMoB72=pZmTq;&^H3UH=rBtwvov#5WqOjtLE6?n=>ShmIY3IUV= zT;zSQHo88BrT)BrP&cyf3(#bNcbm`GL1*3QG6#_SvlR-v&x7Z8T9}jn!e$M!e5J!Xf5Lo5yK&$;gc$vrP<2Mht5$~F4nJ3;?{_Mki4@6?L zrj^0!?x%IC9TNFpRWy$Lz0H$-$p&f{;O2i4iugC_e`I+po@nLgZR(($1|XD~5z7JN z&safj_Kg!$?c&F0Wtc%JETis}N2ZDcjOSdyC%c>Q%RE;CrKGqaUGAYo*)!c*4yJI&B_=6Bu4>+_Og|tPF(==Pqf!8*mlKrQMig``ePGi$tmA`$yHL@cThZ= z*LyOZlF3>XSzbo1?#}~bEAS)#%>^&t{6V!YAEaN+&eNDI`TF;~sI@65HLmft^letWA zdaM*FW0k&z?`zb!2HHNJX}0;wwjEc+9E1DjuIi?V**jY-8oP6Xe z@`wxv(%!88wJSeBw_P9e&zD=6T~QMEHqNWj}|>k;b*ulks2BT^LC zu&3Prw2}%93gXU998u>7G$2`@$TJva)vJagbKmHDPA;ujql*sqo}KP;XeO3 zbS(&dQX^B11uDK=n{^cA*pS47i$I()W>6U67JuS`N>vvKs?&~Z zeW*>ACG>m~2ERg2iX?G55&r=ln3B$HHWS}}iSz#~6wIP`coc`m#zl|K3+Md0kHL{j zB<0Sa$3AmG)0o~^BiI-ipcRlR{(S>jVJSa_Sqy%`^RX;dB%P;w!K_07^gNonKhC8F z$M8wi@(^6g_|^{&vjCO)igTqZ3}q?_wx2)kV!hNP!2h-kv;cTQUfFq;qskNe zE*DW6&!T3BjFK6+-3xuqGJ%iMr8KIxL(i9*mwbzmn^In5H9GJzE`m~9raj6}PD=hg zJ93ivM5*4LVo~LmlVX7%drsAxbKg-ZCZs6C5x;qH&4#?h2oF2C)$qdaMr8L=et5qq zm2YW;qTY|4K5~{e-b$&c%-b`L2!roQSyN6ip2%DlsnS!CMBI^&3w@Iz8Rx-->ej(s0KovciTRjhL7@K>-L-jw3 zQ${A)KlU*E{I?=wA3Ggxg=qsY!{-^9?1Sw~NXGQ@_dS?nO75{VznabSk|E(rLhnbs zs^rpFBmG=u9U3yTHvh$_avkY9RUlO}~x8ZmqF*B^YF+Lwft zx+ugu^qpp4@cED^zSv-1%wyV(6`@^;UUB!A4TT0biofq!b9cGN=13AfwdfPssHfIb zwvuD*wvD-FK6@hL>!y9od5|YxQ_)jogI;=l(>BAciB%(LsSpkZ=3KX=$g9NlfVChkqEfOrBd4O8iL2GXZ>F<(mkfVFdDYa<%1L2!elWz6vhs%^MQk#wh zW-$csLpXi-2YwRMxOZJ{4JN`H^7k%BT#1UzvgtB+ZC`m?*mB>x0{93m$mAev=l=8bowziTWC3fN`Sqe=XHrAx2Z+Pt96zC?c_&tA z5sC9HLGYEnKv4Yo7%_;2L?pUDd7`z_s@bFDT~nnyTl;>aZlo(icafV%aB{;~iQWu+ zVMeMWXewmy%s)eL%2DM*ta70yuCCj)KA0TxASf2z|3o8}&*;r3X;Q<`P?~}3k58HX zO*)v!OwC;_ik92mmP=TeaCoIT~_Z#M3RKKqVsmmZDl_+eMW_1DZL%&@s6C z(D0n@^B$mL&SwilJ z(??`_sFuebUD^o{v128w3cVmYM%BcRp)xOHwcs%`!6ij}=I5RoKY@OUhgpaBQ0Y5% zVm9E;<38W{Fqw}lT-$;+zS1~K+d8F$J+wHr@X=Iu^Slb?PX5;sK6d!+I<~N{;-h?j zTrR>-SRikS)wrj5yF?22I#r;9hzZJ=dR(}+DMfPPSSCK{julyt_&3r-8IVK26Zhnf zL)e>Fho5|~fgRm`6tAe6XJ8-7w_OdWW@#}UPrPI^cHt52S0{JW9CGH<$R$B@@SM~aMCc0PG{sA>~5 z{Q^>AG-`SviJY1jve}GX4H?|g$v+K6wU2Op7QVuzdSNr?V8qk$rK@3YE@&^4r)`aZ zWVIf_J2vTN1{Ozty z?_7QD!?!4VO#Ws*tZeG$@Jh<&`oDPV*o7{-L&|ySZ|eGRBwWUn!d}!|S;F*%_DY_M zU=`~IXF!I1k$>s68&LSMPGCU~wv;Qk-bnsWzBnCpyhMzQuw{f^(oYe4rdnp_jnzev zD_}Z}k|vB`k=@?5!&3~4$L>)j%@y04Hw4!=E1q}qJok(zNw%M9{&D=Qw(lmp#RuHL zxITj&RuwmZtza%f##-;6I${}_V1~CfM6M*O`pEs04cpjbwLLvI!g}el#)uuuNH~bo zPAc@C&g@)6k>MzQ{UA|dgs#Lmc{(+Ao?61i)MMs!3E*5uly=%dS6zVLwB+mJ!v;!R zVJvjma!*5raYrxW)(-$D(e%WX1>{d&N}r4YE&DDBc4!d6%IA;t=K7QGP-m;k@->VA zsiS$55M0bBt-*snA<0_TQV{^ty8%47{4p(7gp`kJow$={&t^x4^IP*NIpRPLzj{Ew#!yen)9Vy zoQQ6tvJ+F_@95TQ7#pnRH15l5Xp~;y4#1i7n1P9okJ5(4BiGQg3AxN4@=;e^?~oh% zW)be&`cx&_zaaWbmKjOWNsty4?!c68a{gvkbv8|s;KzEAXOZCbPV7>TV2pp?NW>d` zdQzLklv_TXFJEcYtC+!JgP?OhJqJ}z?!boUpcbw)2r@p605a>p6$2-Oj&P)2k1YLK z>0$$#{^eiq;Ho)ZT&<1`;<^+LfvvY0_1xy7{J6ItHYol}HMgXXfWH z)L#hJMD8Iak*N;-BP)JHwH>*!*VF|R5SqWc)Kp(H&0oVZUi+kqGxZ~&*LaY+wBDnH zVc`lW6Ui8t{huL*;#?~Q3{J_1?b28~dFIcP;M1EYM=>bkGlDhKuwZ#fLSxqcGe(z~ zP4o@2D~p;fd)QeQCByr<>4kXO5EyC~<|(RpEIf%&nMl__Wa>P7W85HqyGWyj;&}^F=9^dJ882jc7*X-su;8yau~51rDn83kf1B~ zX0H)=n?gxaUUw`?`??rZSvW5e#6EKnXuHN2@nOh_=l6`Ch5i|r8*6T}6q~_5OXnvx zL3C|8Q>LXN1CpwN&_DifqON@G*y)Q^;mVSR3_Z`E(|E>M1EWNd_9>gbflnO2ECsIF ze>>Tp&cZ2t1y{yZbbkViW`C{Nw5u8{9%VJ47PBH-Db zk1rxbV9mvxoa%3PSck-?qs``JfcWUds+ptwSDoXB+m)i&XtM;~Iu>c$Vuw)ck$5wF zYVV=y*cjMTVY608+1?C<^qp0O!U;~K{=_mzqUAU0O#Zimr}Y&ly}mBItW`NbO94@# zyH3VsxKVNEL|bkrBWu{`<>=H_7$VO=g1Ihp1yc+~Np|pHUzxm7OY&)NuV>$5JD`XB zsoOW^Tck5w6}Sqv|28DD_L(=;69yhT4Apg27U}mHAC;_%ayY$SF5+!9412X)g_Pcc zCw-XQe{XVpG2D#NvLIOU>Z)xQZ5vH~5VojFCPc5L)k0JF(!_9b3JQSHNP(O3)kwDkUvtQT9*-{QOMafrJ_1~U9kdkx{{}(D!`J~z<9qrri!ki9CsYC6u zRrKf?xqN*`lWdkz5{tGs<|`|u+cP8neet1}D$Eg|CG@zAMJ(ID?B5R;9i@=D<9B+W zcBlnUCEW};j*>AQ=rDC3Wnswg4VJB*F@IlCbOko+Gs3D=Bx~sH5!qJ}y#bIIrMG8+{M2mJz2Um2HVN zRN?V1ZauxF*0~$;W%+Gz@=3;M$8J;gAP<9p?%OvtDy>syI&DTiguGy3fr^8Y%ScAC zw3~k0e?56A>uT0)!(t=%Bh&h`!-fQzB0KJ`16kX}j9z7@ln*gvXiB?TC%*L>~vr>@ja@0swWki8KuOK+rZN{z}r@1 z)lcBc#lt)DoNr1qOm;vXkW^%7U>$;rTI+k$njK!;!SH2Puwj@G|5n@z)O%yuK|Y$FyhJ z>u|?!ZrzAK%;;MJ;{)4=s9ggdAOAVoY4mt8*AeZc-+e*0Ym_(&y=yy*cU78ev&1OA zzkFIt;Zg+)*ulnBNePmEDk9`j{Lb8eltN>MKE9C|eB@RcHnp8v_!GgTQT*CR&@->_ z)otjd59GWBoB!=AH7tUT5V?PcX164BTMBXg;j3B_I>S$o<`<0}+FGA-)Xwo`rm}TA z(YQ1Cra@sho@*vcd5Gsax1vy*RXjOu2WpX}=6#vJi~Hm|Rr-qieu^P(DM&#l+?1Mq zz9{AA25VhsB`v$BY{;{&*CO*Y{9v}J5xZ-wNxHP>U+E@X_fp;Zt#?DMK^5DO!*p!3 z&E(D!CKs!^Q1RDn3WX4i4aGg>FGLYOZ%o{FsVLmu#{>yy(!!DA+wjdVA-7Qd?rY2_ zuPfgA5<6L$(lSz}V-pG{Kk$KqhMLVxnblJ(+bf#imRPc?MxLWrbKjGEDsBbrk`drb zm)TWqzrT!Xt~AFg#KDuGS+N*seiA%oQ;{jrTs5ac3tp@mX5(x4OZs2*i}5QfUHo9~ z_WbwHYPkC>wzpr_s};FM(%OzqU6^AvU%F^d9;VJ}h$Ye$Ygsv@{kG%!nF`sF3eg?5 zTjMM>5|$RFGoZmmIdl#xntw2*Q7q3ZH`ry1p~kA-US8>IaMb`pp zOJi5c$@}H~?eLHf-2u$}G&l<$l6awkqh+HH%W`@0+_meFuUx-hijkyiK6*%SXDm#x zQYDPtKurFC%nf%|H+=U8d`_l@9`vh6vAcUzx-R)6^^OH*&Rbh6YC0gcHD>(B1kIhY zA7mL4(UU01D-J&L&rq}GhJXs0qhcDLk+1lS;EOdH`b5b z#FT_peZx7?3f$mY~@!Yq*0(;Gh=HzX1 z8l_ux<1%kfdNQeRSS*Z5$w%|Z*DA<&8Q~*(A3;pkWBC){i8^cf`1kMNV#ORz@NY$j zc+6CblyX;ZoPFX?@y*fFwN>13fsy=&;f{gmwAp0!$~B@+>a~Z2dLu5;A`ERnj{eP^ zlDldVjz>TG$h0zH=-TP6DJuAJW#d2q3p8v2lx zr-5Pw7Va|&8E6xB+{dVTG9G?18J!7 z$pd+n2wxaNS&AVxuP)Siy?WPkQBS4Qs=BrWkL8)Ed)z_anrU+j4XHL9mKN}MEi()~ zGeqkvS27=`7L+>aFhqA-mWmjxHYH=QXnaKKR7GQJ7R*XI%JpR*#pduoRK~7!J5-Xg zK~?^jYEDZsuk3b}Ti>QYC&^wkjjI5Mv+UD`wF`?^O(?UK-l(e6O8A}wvBSD^3~~dR z!M3l`gS*oj@2;W5dh>YVPl89;RVHnU4EZ~PCmk!|5myaq>?ZQZ7K@-c_`)8zn;~61u)n__xE=Xi*+Q9L zB##6fVx#ztFf8?fJIC5LX&{&0lqo{}ZFFU9?UFYJ-(p1%5}3jpHNQ0WMv1{JuBNDJ z(WOBCINh8nDmzwCS;UXNkQ$A4$>@T(wbodxNJNOdYy0TpwZfdMBuz@^g9S*0;emH> zHf5Hd$DCIfA+M(c%XQBuB+lh#It(UN6RthZiB&xrYoB>H$w)!m5LY%IjXU^7K67Sc zVKEdl(3Wpysfb2tsos0ucIV%rSiM+uG0*kuBqNeb*`8KCusu8>dYkcDBmCfPZ!|T+ zR9Yt{QTMbKW&Kyo)mESOxKJQQ-=70UebKtyew`PsWsWy0Mc~4-n{|3xW$MHzulO@cW74o3{;hq90n&LK--LwW# zO+&*PKhmLH&nvQD%W?hVasx8f*Y44s$Mq&}mkSxYD}RD-48S`a$8fiphg)nP$uhv~ z&y6Q39xW$|Q+^gLwHM}A`0=n6HG4RI^n3yBIYMO}l4y~IAAl+yd|Hw$m*Evybj@|DV7&kvf zxpkHI(@=bXeuwcs*!wv*iQR*(2P(Awfv}#JiM`a7E4IA)5!S#;X!Y!E^|<}0d)mVh z$BoaXb?odJsdZr>43A)JBxrRi3tpx-@%)G*T8c`A$^s!s$&uvezMy#n7T(5d6Q{75eapFa9Dn*1sU66q@u| z?7nM!Z|bF9Yixo|yb2euvxe}{QzdMN4kc&HN~Xv#eV1QI(p+ry6N0cx>RR2ISD=>r z0Idy4trIh1sD9~OLFtS>AjEd9&k<($SreRQ z8Neu!7GHRMR235`rELdsjmh78r8+l{fpt>_siNejr`kPkE>tnXJ;y^9;GIBDw3 zSDHLFKnt3Tx~+>&3^~xNzx>T?`fL%d(iNW3lfEJoxe_?nC+=ohDOzr4G^TCO^4xNM zyrbTZNN@w!Ew(xj|0L*f!rSe*_QIAc^-E}eiuU^v7 z4D(?}T*c{Qao99g?DoPpdQ(Vwi;~PvoE{3n%n8r7pE0G#oq0P}0WJIFRvYa!?t_JD z_-VPqGDP{4B5DQOlPUYl44`!adKrgWQ*6^k3)B2f+6o<${uhg)YR%#u%E?N~HTBuM z=9N@ibK?ki44aScTeY;+nGbJGSM zuD!!f=c68Exw%y?(TpQ~FT~dM=lZ%-<=uIDzCjw*d2%1>-cm}Tx$}XQsj%3s@>)nt zT#HYfb;+#=Gwt+B4~-o!g<(fcq?lU3q=5j>wDALnnO~-pI*dzuv#;)MZSJ`Rk#P`K z(EadrhH$H7v4@BsMH}<=8@MkEznrfA64faPv!f^e=C`V$}A%#NivVoArVSuR`zy`b0RX1T_J^#?HEZ> z_B_@xLbh|rI5<`rhmdiM?B8`h-{0?#-#2dUGjTSo;yaa@+ND!$d=l!3+6%rFZyO@ z?Gnx}dEU!2a;wgjR?CF7YhX!1)!E+f*L>}Gt#6B0F7cMU2VIoZh4G?!pQzyYRP;y_ z29dq%hE+}b`BuYGYNx`p z96!8P(11)ob@oDtG*yXqY-ORRZOMmcb;5!Rl9dEwtpkT?tXUC}KDln5cI zQ>y7Jv)V-c5)x4oHMb_Zg+Wg&{N{Wb&*Es(X}48{cls?(_%$ztz2)Y{_l`5`WpP>d zlzPY)I-7(ZwlQZ&SM_Q=O8RG2tbwWDpkCYfe4RN55g}8`hyKKFp;YtM!NM^bPC!{A zZL1!>%K3CXy`U;bSh``dMTF{B3ERu0M;DF0C{-Xn7S~J63Bt!OS+L6+ztnrO5&e7I zdEl?N*za(UDQv-lKD@=n%Dzqgl~6*2j&s^u8OH@N>M^xh<&{dEEDjl&JV$I!y+uNg zAIixQ3n{k}rHaCg7e;YUL_yn)n)n>=k1Y&_its!0z)5~TEWbDEmNA_PjhdWMqj>_K zi)4EV>(LTG%;hYI7NO-o-M%=nOZ#d?-nLB;CRx<)G~=T1NwUA!$&K_qDZhEO5e~za zq`v?sI%UYU4B9S8>ksYXJ8H7|1z|>R=AG4n1o&d&K;pc%>ateYaBJndl#R0Fnhave z?H;4fl6PH`2U2}9(e{$v*BVA@{Wjl6Lz^5XIRvp#TdNnbZ)G|kbl7kb)K9w&EThzrB(D(RcZH8jTDEr`*Q|(PK(cJNbm+p4S(?8!Tv5XZVUA+VYq?7E zRE+VPnrfkCFsiWCc3h!VEhg9imfu^1Q^RqZFz=r$mdyst>gjT=xu=euI1v==uUvh> zLAh}8%p^6A?i-D#3D?Wz8qbdESS62foS5uL&#u~rX$xhOJcSq`M+MeR-jH1wzW1&1vkw$q;DRjNeLC(V!%moT?l)6 zxcu0h*M%c4C#TsW;JzhA?wW*09jl(>vwa2d%8W98Eop%{Gx>7m;r{(e|lAyrW!%uC{)n7IIPqs9Oo#`s9N1|n?BiUyzju4 zR}l8(4V7R?g|6Ewb;@`>;zWn_q0aXv>KCjVm&Iwqf6Agm)n3c?*1#se>`j_bDW^>P zr0m#Ph9Mgs+7N$3D{i;c7Z8e2ggi%^(v0^QH zQw%eLmKBFPSyl%jZu3A$C2O}HU|faPB)NK{iePHWU%TYzCD%=+XG;BpYgS2j{6~@a zH1;OTsvvX|wb4~MIAXrG2a_4(OMF?u9(w%+4>%na*65==i@IGx^fZmlb@D(D-kVc@ z^)@EKG%Z8B4UxnGzhLte9jk3Ec>ZC!==}vZQZD?e1fJi-=R%(&?cai(aP3gnw05g< zWvm=O@utAprOl%*DX1Hb2(*9k@P}_|W${YHW!JSoCq}C05jaQGdceq`p+ulIF2uxp z1mXWcTU}!8-PN*7qlkk>kp|<`k}2q&hKif#{RUZ{Cmbi?g-aDo@)TpgX)_X5;&0+= z5j=KQZ)L!Q>rlrFaZar>3&ZzWmcV|LDl0lPtqzkVI44AW0Ie46z6iL9LVChNQ<%Srp~gxyjaNUdSPard ze)1~P+7eA*F_zhKmb?5u)bws7TYXF@Oj&*mR!y1I^nn(1GMWU%1-;ohP!fFRUsRPr zK(Cp47@ZWnBUZ1Dt6#9~6M}X)Vn3(T`drBQDTLEmlwg;EtBd(tze~Jck(txDio@N_ zHlIfpP+#YQw6t=CLc4qD-D&NI7qaoHe8Ivk@#Nmhf19BLv}M8Q|P-`hZ7om7&0{ir_j zzWc$I?f6ja{CXehL2@_=dThNQTJqKlGuLb{C_UK@t<>Kt*33>z6^w!ibr9{RBLz&p zlmy4~(T4G0~axt%)>rmcRV`IJRo^frAoOj9uH#=*Nca8Upf* z5=+X+i~i>_Z8YTlQ6_QYCeJR4h}`nikIJI=-Yk|GED@O@R0vEOg=!nb{Bjw*QnDpE zmi~HZI{cCQmYlE~t(r2s0OJO{p--8i<#LZa6csxEDNrT;@K6+I&rPRF;c7DdLo(m@Eq1UQZ^KMU8Y{>^`k0A=4nJ=qYD(!&6kyeeSPm$w6h(7nBUnfYFTtv|0-cfcj z^OFM6vE;N1q=S)bU)lG0+4nOmc+S55ZbQ=>H7aG2<-qo4c?@c!O68~iaHk{e+sqdz zhnMzBV<4Yx8EX?)Z)%?paJ5u zZ@-%!+C@&A?sXe*_n|esCvZd;ykFN2Cd{hks!EHOXGC*9(SsF>@Y0wz?ijziHsH5g z>x}4^w9miJgO1tzxWqMH0pmeT+p|%Sup^T93}h;OvQA_b`CyhcJpms&|CRpkmRv}a zO{42}^t^5$j%avb7{6~5(1@zGjXRzyQtFy3&c+jkR8vV!y^bGcaHqHCzL%y$-6wV= zA7V#$B(FDEj6G2HPwi`wyT*i5`d}MQcc^s1CUrpW;y-)cNbIz#hVOvEJk;)V0**N9gnosCFdLSiU*#XqoVVmi^#*V z>Ol)>!Djl{4a`oPY@%*~bF#ZRx~0m&3Vpz^E=7LY9re2Ic0FSl?G z<`}v#?PmoSZ>JbZKbSCTdg+3Soy)-wDVtIc2wtqLm=gh`pH7kc-WSpx5w-KDILK8NUfrNIPix!*H)#ynMhw;g==g$?*@l}l_gr^3*N6!Y$ z`t$G+7=8mE?Ns7gl{_u_@!7@VAC}w4<(B?cn$F%?CtWHfu$P{~KEgSK#e>%$j7~y9 zd$eYw72kbQ6_F1NWv%SIqFMgjhAs^53S7l3%J2uJxNkJ-rS3kQkp69X?TyqLb8o`G zj!T9qjWgFoQ+GAfb)Yi)yyF{Ny6+3$YOC=)s?`!=+0JyvjU3^qE2Cz6^KRff#y2qC zJv}W!@s-DpDsHeTeEWpkRjPKQr(2@A0bus3c_!qNFkxGWaDp^piQu@>QBIrGpC^s# z4<{8G7d`?r6Y9AF{|ya3)8nzqK%Rr!VbjA(+F~p@H6FU(bLHy=nHfY=Hf{SNAv!D7 z8(}aD_iRelv~qTv>+l`FX|R`;^h+^JX23X1eMHhQ4{8H>Sr8c`v945EVzj+V`ZqrR z9Ot<@{uPXK#i-|QtjlmSle_VkU%Wy#C%l9)6D#bf*t3t9E9X;UVdc;Bet!P$ za(5+oTO6X*cfPEq6^f`7OgZs%YeJbxTP}mS!xvtkkSnXw4_UDbi=!4e&f3 ztB(JI+^Wwb zKG!cb*H4wObm|&D%#k?qXWbanoOTL;ZaH|BGPpT5c7h|wv@K(-vruF)%T+Bpg1T_o`K<1l=a&v#{}4I2U=U1#P^jy~ zo0eo>yrJTD1quE5wS+AJG_49SZf2{bR4Wor4VTloQp=mILGD& zahAZaazcbWVcZwdTHgP>OeR}8v(RVfZ~fPuBIYK9P*N{RO2`H=dT8-uQg;|tYFcyxq zyGD}cDYt!Ha-|19(ZIN_#bz6nOq9e?-j+$#aB;WMO8Dl59U?zStJ1<43m4aH!*l`3 zWCwf5da;Bk;iBI7GY(aB8 zv%MG-vEaPbYIr|M^4R6~Wv@Z+&suEN7@1Eu6nlo0xhS+b+Ucg$xh5wJa|a_Cv#PHd z4%W``@_am)?AzG{M+w_3{>$0;}Vi>ZC@y~H+7Jr zl@yFOG;D{)=D&SNXJ9{n^^tkfp~H$H7~BM<&jVN%%MquoG&iR1B9r13d^zsM{j_%Tmdw&aitO!2Os?tN ze*JoCF2Z|=jm+nh3tshOW1I29eS2x@JOjlbZW9?WL3RcvS4sxmMxi7iiWS_F!Mg8X ze;Xi5esuL@>diQtwTn%;t?EcU!Euu$1g6+;@j7CU%rYOvS5%z&eqt&2q(Zj{%ij|{(Tno?jbeNOrQgk@R}~P$@@;{GtN1(|(wMT*MI94E_qu}QHEL?ZW4olZ zXyZD=mQbg;g}pfxfr$5Nhm0;rQrz3WJ4Z~AvdP*xoWLa9L}uH+*0MLc(VvW+<^49Q9omX*MX1#wiWW*)TBMx_KN~f_fUr`%O zuMxusAaX_~AaoWfsfGUieNPMUE9#3sp>rk9nZ7(hl4);jwxTPv=U9~;?7y3YP-Q>g z?zRyJ9>{j>!10sot56t1e6Dgz$!)_m)WMp*K&xtK`_+O7yy;=8&B#iM{CO7<`=Z!u z4pBBEhE6k|c$F^j+7Nh@Aos_9OypFDWxQQU`@_Q{(4C;3_Eu`l5zB&_r0AItAGc0` zC04TO8;x?tgoev<<@k-P>=b>kjM1b3sg25n>^TcRq*jWCLsJ;f0`zYhF2`4 z9WZ~6Zm)cUtZD1+a6VjJ@dUOqZ}ihuJPIwpAQE`D!J1d^+?j}K%98$F13|NOh4wnw zm7Y-u55?4)kI}um8_}PnH?)$K)6RTDbIkU&h?w23eVW zBbgn#_{Ym4z#M@kxpX-AC?PK=R%hK`5S8LNBSt*W!j}Rjpuu=lZji*C8r9*AqBST9 zL&Jk^w5nvk_kdBo?HFf^;MNG?LjlUjz^4Kz6|8v#c zW^_G9)zd0gQk)ttcmPRO;yU*RIBo|Qm+r0|FpTD3TFL4s=9wqf{@EIRZ`UZe2`+!m z{2p)+KK`K$ek(u08UgcSYd#H83eVPccj<6_rMNB{<2of1OlwfH?w72mdJ?ptYZRozm6BVlgoPhd%ho@+{{KfLs& zQ0L%cMj>~dJ$FIxsJWPDKZbYVxs8|`CPn7Rl9F1Wy#+#b5+rPH4hHR{0qLq|$I?UmEt%=`Yu^=q!XvlQiRi^&REs(g!*Y3sOa*gjDCYqJJ4VXa%z_N2+m-_5tU<{JqK)#*RX zc;bu@8OQ3I&B<^wVICNqp~N+{F#V`=u9Y5sH;Ge^K=8z+c820v5VnWGl`TJvRL})w zxj|DyfhE%>-Dno*GzpR)1iM#i_i^EjBM)uiqBuSggA2vX5WS}~h6B{QTPl+WZ19N6 z1;yRLYzWrI_zIsk*K9L0zUF?+fM^;W+_ zOT%Zv_86U}dvo52cQdhciG|#)Ib5e^p*;MweM`4!peg^v8{}%Z83OC+Dt(xvAP~O5 zaDT$?U+rFO(akiIOM-+Q5ROL-wUP?M?xL6wvT4`)j4XY#b4Iy8D#U6<`yWMn?&2izKN%<-e$uvERPiXEIf=jOr+y;Kw4{0kpMB=4Sj)|Dq?>=` z7x>c}#GUGXiJ$WVGIjJ0UZhcP#0wPuW<|MUE05*yzsqMq1lC)W-J~LKP%_7KjS>!8 z^3PcRW&y{&5W665T>%HuZrT~+HVfZ0N^^UN6Hh1z-fPERh-Y5w8{Ho+XwH{$n3$)H zMC<*nSYL)lmUuSzVN-aS4X#KO3V@1Noytuy`F9-bx5GQHf>hs;o2oGC%AmS;~|Q3vYUJ z4s`sRJWuALP>E)JN0HV0*VQe|`{G~PsAUi&<>WB=O^8owCtFk~IvJ_>bbfE?Fon(V zFer`6bI>=!pIr=-qiwoMmlsq6Y6^65;B8sxp%DWIlF{Ghm{{B}sEg2a6$gjp|vXd>B{N%~g3re+t)as{qg z3tmKV@}Z7xxvy#~X2(bkaZ`?aqdJ(IP48uc!PwL2*A>id5)Ps7e;jJ<{;A3l`2pXc zlYdPdwoZ;~Yg9dNg!5uA?eV@*>N4@Q`jQx?i*uL03JsC(I2^uqWU~A?`xy48sr;3f zmX)Kyy3T()i?Q+V-r<+gUQRe;kKVHLJ>_W5^PqW_5Fvg$%c=Nnvlge85`X75Zj6(U zhdvE%F=KKJBX~)db~M`LHI6u9;S-b58<$3G=f@pEnjjN7URJoN zj<(C#L&{W@ZZWcSN+svKe>tjTYrt>k=VK(&o+R)$fSNy1syzqcU)$vV@Op8MNj=?O}C}yae}uwl3#+PKcUQV4B(FpiT~WT#R)>htM!o0XsC#ep z=)|Fw8d2|%v4%M#MyZ68QOLx4(>MAzS`BQli730Rx?v@UoWkPl{nY*MPkny5_;X{J zsb6j7<3#ZL0-Q|+Q(T0vquHqzf&VMp1oxKzEO(c-gT-iI$M}ov^f3?AqCPt5{8h(L zAMblTdS4jZC8C4g@zBCQP~b$E>~EX;XixWc$luK#??Wi1&_>ogpB^8Ts-^i|L7H;R z`%|$V^+>lY#{2uQ#S2q~p0nbI*w2WSpgv{!!dxhGBFEHF^-GvSG$B8}K>iQ{ODn7v zyyPAj9e1|&ssTFJ%WpS6^g8;9VacC*9mY9tMOvem-y<~Ib~7Ygpo@)pQFTNHEMf{a zdQ{W+cK#31a`B1yrWGn(ihESr;3JsA4rt6uDmu#Hsx>OTr1H;4bDB7IpT2fzN;mra z7A>y4saA|)$~SpKuh+;WS|_yz^+jS!8KinV1KBXRMRJhm;CddWq@=O9Bq7-4-9OHA zZ}9gkZt9KF{w$}c8a)J?RseD#E{Lay%eBqkUDrrei@=yKQ(5vY<}9DpLIvLHqRXtL zV0keNVnkAKKMaJ2YNLA%pU7W;X-2&#e%gQPz(hnyr=?m8g(9J=6PJWJO!=NrILh*g} zwWv^g6v=^?DXnkA!W*s?Q|T5b_ETpl>!0MB$39f)JqK{LcQfBJ=bxk$CH-B&y@K zQgv7#ya#{wSBv0WmZmuFTkK}eV+-k7+&7E0*ft$pCpav5*ASRbo-#f9a)h4oQ4z*U zzBvuN#yqsC1?T)+Sw8SNw-s}~0zV^mmAcAuXi*9^#)2Z|+&K)CXexwc52?38ZqHh( zCxBA=>xw&(5bw3PXyeu(q*9pP*wMiDI48=~-*R-y+xEy+wC>4vdOF+j7!@<2yVc^& zA`!{Xku_LwOuTi~ZV)#v%;i{luC{yEtsn`rq>!c|&)D$yg+ezX(e>;ZzF&lLu=~_Q z<#tYBla#PK8>?Fx?hIUIh|rYYZ12n$u3PCtt)<$-i6!ZQ1q@*a+ZL$MLd>s4^vhu< z>pD)=A)M821~RGthKZi#;+~LdsR7Nxr`Z00grpv9{^PY1p*T$R!e0T<#lyYIx+a}X1|IXDxB(e{WPYRXm zG=C~EDMUYLuf5vA`-2gyK0AIXG=d77zRqLcfQWdM((hw=akV-+VN|Nvh|;9j0!_aO zk!8<2&WN2DGb#nqMG3fJp9Vp_j!KJQCN1vHJk2jZIGePWAmUs-N6NxszWP7XU^5+w zxWj)?YedD2r4y{g^Uj);jS1?J7%nblTzW&F{p+7#i)0Q4OJ z-pC02GX;%5r2=gnRb-(e-%gfklwa)c>{~{|RY9cG3JXHmV^mODzQYsv1uzQ0F`^>Y z@HBm!UB_x@C(XuW+B1Q^Q5x?!>YqnwuV0jUca?f!vkzaX3ITRu?wE)wv*M50y{_L1hS>sK!rJ4a)llA_weOE$f@Q7*ulP$?5U-8Vbr(jzR2E7J#{*)0JK@a!tgyA*6p1^9-i;s z+Iknb&>M0+Wc%dQ91u4he0>46#Q0|z4E5-x9pwTGcK9IF&!p_hs7KAXwU|IV-p@sz z1h+T%?nLL4wvYIe=~0)g>;L^mrB&=}&xe;TOHU6~-~XDkZ7AF!`!?(6tCHbQl&Pi5 z-@q4x0#wfMJjbc^`Ujra%kft3{BA2NTjxU-Ve|d&$U@BC)Ts*i34o93PyfrH8NH&y0jbp#zP2aJkG{5;F7E3RctKvWZG#9Q`vvb#fV@sGG~cimtHX4sD4(v zO-t~L_-^B2*|8$JJpmbL$l^#}%sC%h#vZCOby##})b7M|k=8Eb#25g(0Jk&GOx%nvd4laiF=_sJ@ zmYAG*uZ`14F|7(}MHffUL5S+Y*C(Bhn~UCivinc1?0kaSU*?v^xmBVM+S4ay3)aG( z33jBPyi)^!t_KfxON(`nPtDEE0d}#wOqQ-d=jUo{Ot(TQJofzS{ODhQC66X(Yh7@jzLbes2B96bB9~xAJ|`5mr{NiYBRyx zT?dGPDmiLhxYjONW`^1r@ zb<6zK4E)YmxL#|I`b-+P;E?^(#SD17lH~sT`ma$4DKDSFT|&Vcl-DQoyJweew{qpV z$c`ll;oh*vIgZ_z=85Uk|2kyV9r>gYvNp!A*m$zSMeum5^EF>to4Oc@ZMWv<0`sDX zqK95h#Eh7Lv1pco)W)%SOj+hr_{3>8Q)3p5qe&V@8-RRG^C_SGuFvtyrk_&3*}Rg2 zRh+(X*MF-!e||g7+%Trn3|G0v)LJ5S(QWTtgx$Q$xx!3Q)-TLU)l^;#UTtS)CorQ| z_1<@L(qzohIs?#o7k&@(Er+$F)cr2#T4lSA=V}f@KGqJ9MvTPkPzqJGd0r|l8x`bK zlVt$5*qf^q_|AB`50oL4xfNZ%s8%CgH*pBK~2ZeAWXGmyoA zu?R71?qHKjC26gm@%Vhfn%hLGfl>n7xaeKS%4Bc-^C3yv*9^ux5JFuAk}xSf>>_-QN*rqAWZfIB`)gm_CEc%u^5`S&H>9}=FCRogxnb7Ur;98Omr%@ zwD)6`4%0&s@JABNccP{d+OQ@|xNG8C)aI$|Uwy32c#?+c;ZsWNGNrV5t5<%RMCcM> z;LBQ{*NA)I&_e&aP_Hz|rA9QZ?q3YYWQxSnR$nRox~k6=gALd%!@>3p>CCZPIH^U1 z?}$X#T-q+>B%~xMzi8A(yjE;gfqEg1tt*@X5Ii{5UFfD^Os6jvq4sa|*+O)VBMXN+$T zy&w2~r)rmaVq1d2dKihe@fc%(p)awofK9zEXSjA@2=`1fI%Lb=sIeD<#ZP45o1{eC zw5S$6+Z^OBYvvE7G4_;X-`I^?8;}*zF3F_GoIZ>&d-V<(_T)0pqCPjN{2fD^S3Hes zluDYmwkvAmx8&<`TxCVc2bOUKdpFk%=^fPafG5xK7kURRWH$*)@Q};k@?X2vtn!Yp zjD_&)>W9{(UnvE9T=v;Yxs7xS9Nt-sleJ%2$5(a$e=u6IXHiiWx=v(A>i<{%`0wz^ zwL0UDPRUDoLtVoqN9UgCO5NCCx;Uap29zWm+veFkL-bR>I>#sZ@lE3JSvh68968V{ z*v3pQ)d0fQ)Uz7Bm}z93{vxsB^x6ODZh+mU90l5hJ(R{B8r}^b+^$%@G$F5d0d)b? z762OF+2B0C%w47O{@XFQWyx>$UtwjvN4y`ilOJY8=*c`^9M_`;uE{FN(I=1Yy(Ds0>J`;2#ph1CO_XJ>=Z71eV z@AXCmEc9HG4>`dA+Egs&SEh~zpg($C>1&|6ogI;S`{5`;pqSe z>E9T9MH)uy4%qd!iE}K9j9E8c*8L}dpqE))I<(xixR_^A>v5mVF|G68DF9Zc4q$Tu zs7ueRn7zXxe8okf&5c@9rds#z#q_bn)U$J7pM+a?UVi_#P*F(*ZJ$O^j@sY-a=AVR z&pQZ%HXA=*taHc(bxt?}@s^Czio3gxF(8wU$(&Sx=(FaI>Cnop8HZb)#Wq^4E9kzk z^246UpX86j-=8SD5dolbzWwcmt@#Aqp1Ih2VgL*7(o(@MDlDv-d)E=s7zG$Y$OvYiM1`o1zHObqzAOmq%SNJceiLR}! ztxuMXC)QvVZVP%?nVE5OwM;$3n`<~&EsL6t9URmbm6npR$brWz)+wNZN=DZ&f%yaH z!_aFpEvwY7z0VX<7MLi2HXIE2}>dU``GD3B8zU} zm&u)t3=<&!APLxlfPhAr-i08+h3}Bp45(fL2?u|me^8W?k^;!Hv8_c?uaVHifGv!d z&**cr%--kg;4l~#zwVdTFjYbZBZ4|Bpti9-fSJ}1*3f{By$=Z5Lf`?BneMWa93U{ix^ORI-WRy5&LqiQO zzLw5HmV9y=PZ2F0jB^|=!LN7%(qI=L!rhXcdXZ2?SYxG-CUY}d4LVf$-aGn@rLV#jxA7@N zf5UK#Qaf?P>NY=nuKWX4sEi+f6r?3G?$-5?MR}Z^)bv-;i-%-vJ>X#Wd^5;*aCCH> zmv~lfMrLReaoH(*&8Np(zoYK-0B+_Bh0ORGBrlUL^&B(=fO4UyM zvjX@Xu#zD99UUE=C!@~;SMB){Vq#+SBhiT5Yt$rB_#qJA*vdW`3i$v;EV7eons$mk zf3=1Ip1SqXZ;mhcm2Lpk1Z+Pu9&sLGg3KuLTzN-j6j4gi2Tddv z&2+OJ#k{eK#rx=9vI`yAI21)oTnmu4e;D9hBeU)M%9s1c*737+*OnqZE!KFzEd7sE z4&)8U8Y(mEkHO9c|F{pJ_56JMT^eLacrGB)DwG4OLS7=&eE&kh5=8<93lZ?}`7%e8 z0O*y>;3KncQ^YJkG&VN=+*q{-^)1OOQJdTWA^r6_XfBx(nAMtN``KH=0iE^xwm)lk zT!igE3-YrHDE{vA(xJXuxMEQ_G7pgcG5?oStIpWd)AKGvF~C^qU@*34q|l_;FZW#m zIG6xpCG)C$2XT|Zhierfr@;V^pALQ#S&M{hvjO{<9bnqGgpvALXC%W`OTgxMxR>_uTWNMLr{XwB;u_PiR z#i4gt3WZ6IiM2@bS$O0Fvjg4Vzd!9=VWK4`BV^dTi4{_f3_2%bGZO$Ru@{(a0QhBn zSKP-L^@~?%{S98euZaPXB@wbD+a9P|$`1UwvNLTanUD=+Ci1vcLNOoi&u2d5cunrYd8>u=LXC>0*+|8x>Y{}TI zS`)5V&q==L(KKNNjrSmmZ~TN}J zj|}d9!|T6P@6~U5Oa!oQD(0c-E|(DNT{EG^X`zz*kwQ3$%hDo$wGn*F;^JZ3ugJ>>c37-lo~&xQ79> z-hAdD8AHlk$2_b22=1p99h9QNa2=qUb8(+Xouz0oQfc(1Z7q(tb z^-=HZdS(QvM$C5LVxV#3IhN>DDZ236V5v|nZJvVKK>_nJ;GGqaGCDoDLXrz2TL0b4 zAHj)vX(vR)F$$Kr-iBZJQdeP5Z+36il+Yn%1><$(AGs|$IMekbLux1U{?{d027WcV z9EJ^eMTAE*ZS14m2F(xRL-_Qa^``sd^R+QNXN5Wj4Y%*_9wvAv9v&-IC$he~oK8GG zr~H~Fy;{9YiJw`s2}_!fN|lr|dBnCjwB&i_t3X5{$4!D`1J;ZEnIf-$%o_vz<@43d zH*2g3py>9r(vd&kIq=O%ANR!hDuJ*LPznkY4~?mD+luzAA)Fz9!?yM_ao31THVgt` zKQFyXRj3wYlKhOtESfnQRMdh;4QSMTR0GjeeE+|fN%RpwgS81=R z{f-g#qOMh`Nc6&^^o0sT{HK!wS7&4THs0pZd6|y;bwkS!xcr%yq}b_lwr2R+pYmU< z{BVyH{XK7HR>pMVhw+Cp5u6P}tM(pHMdG8}a#)gCr?ZR6T|*zX(b9!6afAX|_CCmq z;(hIJUbELBIE8*&+4gTt`xwol$M_=m1wZFQ4Z581-+fXd@C{HySsmi6UU-z{T`VH7 zkkCv3!DAWpTo30i87izfGU_-)_vNe82nTF*CZC2K0!8J4@^43*W2-pNfFj5R?&d}V zQ}KB-;N^X=q=acei27RM<2c<<&L@`vqcbQm_`X9RBx3&?qTfa;UJ(lJ}*p)eFPg*KhOa zF3MPOGsH@&2umBqpu4?-z$YI@$&sLxGT%~GO}AIkhn?QF)%|Wd&swyc8qxGUXl66= z)pDM;t6%B4g@p3x1^-MKBNLqikYuKWR`-fUB?O2XSX_8X z0e&GjSgnaPm^<|y4x=kprDrb-hJB(nEMA+_5+|=hacKTI{X9+S{Z*37M`*Aym!5iy zVTLkCz+ttb*N7W|X6Ry$>^5w4AQ6N9yWkV~+qOxm~+r>@!kw5IIpdQ`tzDmj#UM5;k02N1W{@^Hm zZJ_Nc%?)&p22DoTch4w8C={u|;WO<9%Yk{D;QC?9BAp~+RR^WZ+1ABjA+g7z;s~D2 ztDX-JV|b{5evB0<9p5F}ysr&hzsTJ@V6-iLr>C4qG9O24w{3ma0CzR< z@}j^6ua5aTyA&_HY*A``$jAx>B2xY}%g@jCH|0<}zTk#H7F9x;1>D~Kzw0N@K%l2z z*EItCB#8L%%_lo#{O`dbNHYM+eE#;GpS#b`V{TK6Hu(IHXirWYESdsMv6**okoo5S zi}yb0js}?$8jV)xp^Q-%G-)2wS_Ce3Q&=!8PLThxZO|Dg z*z9Rf;IOO}v{*(^;MvzNGw%B80I?kigD*G&1b1=!-k#UJ8)wg5j`MFU$s^Z`$(hbc z_r3ia73Jld1rY0|K;*V>)a-Z_@IgR}Yo5#yKRH4|d*~=7L)la?*>nP*pOj}J(VE5M zV#gPBp#mIttP(RbGg&9sR#&?~)H$EI9+(f(h`VP8O=kmv%)owK_MtpECj;_n@49@U zjUXe~>bX_gC53}}S)w;w3fR&!kDoQqG@nb%54UR2L3e0emY7+R<+IOSo`kQGo)}n% zLvX40wt4KDa{f6&ZO1(1E^F5_WtCbrir}E6Xfl_6;=hCdltjUe2#`hD96_SmskB=j zpO3HJs{)G^AdksGPw*}*#CZB(w5F%di})FoP(UCDUWG}iRZ=AkN7i?18hYNpxPUKuW7h+HU#V-8duucSm4*fb8yZG3$0 zio&%!joTl9W*&$g$T|oC0p?cz%h!?HgBl=~1(fm>p9V|N-!2R~TJ&jGyFH)MQBFke z=kHCIH))jnEm5-3un2zE7)EAMb(5kaf#d~9u*mdzaUzhVxpbFqZGeCZ2AQ#!^ zIQ?zi70$>pKd8Z%M9dDc$_hEzXH|}!aU0Fv^yxoL>$@8a5}E%buz+6QfBP4Nbo1bD zE{8k9(pqs~#gkdua5y}&%a`rlf_`$Jo0pf@yb*2U%XYm9z9)PUkZHJG*bJ;ZCI|AG zkK%1JPQ|q}0v&Opv!RoJ>kl-=&lF@IASK%GkZlqGymAnR&Hvk+%N-z!iXMR10mAJC zW_Q2Wfw;XuT$dc!^5EeBjT18Oo!pfu1^RPfA)U-=n**DmQx`OEZ-eqf(e^M%a-ciI z2INnJ)EbHn2ng^5IvL2L&CUf79F2DIWWGF=*27|YO#khC>OaGz80N>Zbm4$GH~D`V zi!yx+3EE~W8Q1_)3G0&u>mHCoub=!~PZrd8Z*lgMDP*~u)I3KFt-P1Ouecn9rI4p4 zs^>}^5dUQ}C0B+xl}&><4D6t-_6xdQ)aRl6Q_p-2Pm!R&M1f>WWTm?LGq7ZsLb{z; zJ-EpE$wHiaNa{rt)V(N(dXj%$Jp(C5Ie0aMrwP>3=O0@id;m|mi)`q~awR|`B(`NF zMbdd1l$XeAOMvf97D3tiHy0b*QVYZc_DRIztRLzv)G9{A^u;>UF9@^jTf^1Lx1feD zDNg(%6Oh?+JqCSa5xva$=U;f(*4EWrLz#{==W-x$e=n|4rE(w%omMDNoMIt^uhJLq7o z9La(zqcfz$sx(%4kDSmYl?JMT!yR(X!?TT9w(IB5pI;YAat~tPxai*9gED4S1~|bo zJMa5LdH#U{fCW&UA!h>QiqDEu&b*SV2sNkj6&1QrS|AOgd^_m<)t5v`n@sIc(Q!P; z|Hv9+_+za_R&4MyvyRp7(=5lXXx-Y)5I$W<^8M|9%^@yPtP|xbi0-Pf0dw_;_Z;D9!EbD}mw;zc3CpHZD(e$(nN^zPr(@-%mA<2~{la zH{H7PkxRhlqJ*_wdK83NGuo&<@IIaP1z1+TvKN=2ty$#GwRs(}lA&27G%x@fefRt@ z41o(S#jn@~3ew2Q@0${oBk)#dFFW5fqSFiCftx`Tx_V+*3PeC49lDBPT(3Ig2PU6X zzI8r+K-oYSPXAi?obV27{S~&b!!TzP@m$LEC+Ei1{TJC$%yd6WH8-IBoZ`0p(XTys z&yqtV2kt=2`(mua3JMC>IiF>dZ# zqV3Is-|PJ{VBGj{`EAUbvBPKy^^)Z~$xKQ!1@vbTvKydPk8 zgO)@psdrIBbs6vWDkCo^Q#yvl8B<(+Zsu=~m0OWQOH9sj!q^-I!kpep;p`b_fLc?= zy$~x-P#9T35!0ym$^ zN~d-X-txe#Y|Xw8G)gT7a?;vH3lKP`eqoUv=W>?cf!cqjfZ9zS>+RcfkMFf_PUfxm zTfDCcLEcO2t$Mks2IxRi5~dU^UM&liwyU-70g+aU6be^7&e;aD`J|7^zH&crcTNkR zbc<)}`@O&r>A67%&8uN{hh1UpA4;lelA>UPCl+agAM7}5j9(XPHc0d2I*kjh3x16earBh0Y?DQ01P|g6F>@5&>EtxUN`YtFpBhRMP>oL5 zghlVe3^I9|FupldsX~#vgY38Gk`GK_x7~PVXja)1JLEtUBoK-K2K~pk(-5S~Bi^F} zY8TL(D++btmVQW_jLeDFDWXt3S5l(bq|`Wj(?7$qF{)_XHa5VOr@9Zn4N_!swjb_w zr+0UBwD9Eg?_c!MsnU@EE2|5nt1?s9~nOCx~2*IJR{JUgH%_FajO4CQ06F!=hbsBTJ$zI5rB>u&cJ5Dp~B>Dt~?+{BzY}nxE79sxHS+u2UJ|dmZ928mOMW&N!1Y z&~%6HhsZ3~=AcTnqMb$Bt!?lpt9>lXMjut!@1;E!;{DYePl>*Gy+#~F;JpkUG2@(i zUTlWC>9$Moom9cdU@#zjM<$AX4ofn{pnL0Ea;T(987Fk~8LHN@PfuBWu9I>2fo0;6 zexu3+*CB&w4u$9wZO{N+1m#l!3~qX{1Bqb24VKTcA@Epa-!xHgQS}`Q;xJ7$TejRU zQ=aNV=Rw$7xc1$f1rI53beqrFv5G@D1w!fdK*Fw9KEZMXE0xDy&;6j*5QIWShVDjbUB}?dgj?Y2WQtTe@6&b?3(;)V` zR{`vo{qYDc@l_3f(&r}=9g6MOZ1MzpJ1d>3U9#6Cf@WBVc^$r)4j#)vZ_4Wcc$by& zeF99Uo4TbWIMAN&)0@E;s37W;*bQf9iqhwoRsHz>EpGJxLbYWm`;UAEsPPc}^TiJL zBN1Xl&-!s76cEbleKF&_yrQOVoCS%n`TBzvn|_$#d}AV-d~p?JsLivl$BxY-T1 zubc$`2|f|I{H5wSxU`C}4=cJ~&bKh8<5>D#SJ$+lV**7nW|I`yS6%>ENCba67<$8{!|$(w(AoiF8OQ zFat=pbPioZeEaZvKkxJCy)yUAjvFM^#)D!AizAo|d3#co^(m-i0 zksQK!bEb3nO-&wGNdnuKvc-a*@8E(6{>aP{*W&Z@WtvuJ`Z{7zq<5!(;fK%WLRcaa zW88QKvw!Y!MV{*|1NEAOk!NdMhRTf4C=;IsG={sRbQ^u`Truv&&E}H9Sxy+a(a0at zn5*n#@-y@|{M!n<^!K)vr@h$4h==2hFg}u^CX@lpq!;C`&@UWd8I0y=(*Y9;?l`c0 znRRHJf}LpGcJH1KcGjT(Qf!O*UQ(;z2OF}(tC+<4H&W0s#o}cTmfF0Z@8WkG>11B& zX|=3OpL+qoijFD2Y{gK9-3m+I9%mRoF`?mJAj?wKHPJrwUquJJ8+b4zf@J(I8HD0v z`I-RgY0A|%Q$B?L3EIjfmDW1aR=Be{@5)iBs*8!siZJlc(u=7``{N&!}{^L2eSXfkfY7lWh~=rPxXI&qK^oo2K`GQ2%} zmD=lCA^eXi*B{PkW?%NTbXX(c|N}u4giMLrzu0 zB&|JrL8c}=#!xf6SgEkshEhF7kVP0|magv zwgK0}7{Q|f2Quv?8M{nS#`UrKery>**?Hr*@mgc`csiAE(z3P!URR~AXdcpW$%NMS zc~|uhr###S#tE(Qz-20ZP@h9@tYP0`U!_w${;|QJjKUALCX^lS{Mx#B1`%J{1j*(N z>1sfFzvCv|lNQ3yZ`V`2m0^WoyCXtmIxMhkaNVR4XP>y$3zW;=-ImTLGna9BL*4PL zFdDA_Og~4x1Kx=6f-b<>@R+X}YnMn4;VIKx1_ ztSmoUIJDk##I8ld{-YTmV{Bf};=W=N%h zfjss&-j)a+d&(wN%C-`Mk(KZJzOZ>??}EC7Y8Oqh>(=eeu9b`h)xO5JE-t1rFdqCv z7>`UB7HDg~|Ho7(-6Qx~&`RR)A8XAc;s!BA%eirvg275*4>g~VscIJb4J0 zUrv{Skt)KU(WqEpdu;BtjJV6lSvRWTGB%hGT*pnk3<1}&uQ$zSX=ff44VQhfXBcTR zsnvbN{KtV|qPEzgO+pzhBe)Xz0u>PIL6&=Eqyh3}Pn0X{% z>=X!Y8xl-KEV{lDG=-Tumj-51=hjQzdb039)G zeA5Fvr)@(ye2?Ri*s?1;t)%?X%&{4R^Fl56i0jWPo_4w8v~)vt!aXU?{3k8LIS(b3?UC^cHs-TTLd_|0=` z`$@}Q-yURt?eHT1&tH9nVXx66*eQd)n+d0(vidM#@J-vHWYnU)d&~j76frQX8%kDw zTQzoMe``N|w0n;h=6?(~m3k~^4GVU>p4kr8l`?r@H?L3CQO`tk1_Z`4jrtFG^7f08 zec&F*-lKcPHX?^~GlZZRbt%b>Hl`1DWZ`yXG*VdoQWYKUIknsyS#^mjgh^fQ4geomjbbK z=GWAU;M~`3hwC{z->z{x)!n+-=v-U3_s zbDnpY1!uC6mISg*m>@H%t(oUZL5B9_@yUr`ofe|%4p`5g=KD7RmUcB8cQrurW z5QLxrTbet!uw-Qzjtd`KpiewoHiYhc@*K9&1@+0}Tp0#xTSO3ow`iaskIePd8Sj-= zTuHu%rNt|S4p<@A*Z5sAUhn;ImUdm(MDM2iwYu9Fh>&&-S50a41>D5>GdM1cj$Iak z*%KA6Y=t2Gb@q%fMSW%rH)LoD)Bfd45ZnX4a@DuZA;(aeE}hkDDcn0~CIcg#r24qu z78Bgf9@V_pWhNJ^_+#Ditqh4*J-sP4LF6RoEGr%hQ%k2-yPXg`77ecz22lo5OmZN$kskb%piYP#*;7HWE!P#SK$ zgS@i!%}%3{1Yz6gHcumualaFuicclI9+BPr-Jk^nkN9KGcD?(M$NAjqU-qTafjRUZ z*ZfFo^KqzewzS~H=&KzuXfzCw00G6Ig?m&&x3rbhTPWzYIjo2$Y=U1FYryUR_?hWn zkurbYnbOim{l+H4g3%J-X;Q);a}dwKTQsTU6fS|KRN{>5AbLn@9{t((%7OJsaaZ3w zd;kppqmh0ans)j)9}}6>T4U(D@{HtX>A=`i#vb9BmrOozYNzL4Xlh_w;G?#`cz0Wr zTvYG;dG(sn2zf|Y)?Aq;Q3}{+l(cDX;jyuP{&q^UIEXZ%!OFpjRUk&`L{O=n3%T9=X!j$F0>?4tWUiDo# z$CccT&{V*!&77f{R{8?$GzN5#L2dfnBZNhf;4b#{8Tf(a_{8!z)VIUX4_^G@0s@_G zlOY4OeGB~iFOFQ-u&dYIL04^Wct(y;)qp`%AlNqab1m{LB(23*v1jmBg}3YQ2=50mm$+hw2!G2wcfCVw@eX6uOMC>lfy*#4zyrKW0BUK z%~9#|U{n^_*^3|gI8Zm!wx$qLrJNM!9BG?O$%4^{ppdUe==-HF3FH~Ln6i2rmUD0x zPn@z4YpPbnsr=q#{^3?xgU9H+C3=??i#DeGOmQ{IrFQ^nn$_V z4le5)+{tOZejv*DX&K3A`0PkvwH9Dh3XmYL^~cNxw@@mj2Xa%ey>Ay}zonwwzcufU z0WBnjv{^nLFpb}6!$Ha&XpW~P%BF%wBd9U@JR(&qt4PW@*2J>!61E`MTJu!ag${q* z)Z{Rk;E${NW1D9Dvt6Q7)gq=NJeQ2s z>xT_-WeDYtbaIMvu~@$VYVKD?`Pcr`Ws2w4Fgdl{$T7@( zgezTB4G2vGv`N2)cclPp`z!M~VXnp6yB=0Fguh9h1wJ#jlrmVU{=}f{xKW19s|k9X zePvf(y&l#ytkS7X2Mf5g83vpcE;vMugmDWHRx^T+;8P)z!bm@1x?mx9r1$S4_4V3^ zzGwElX->4En|Zil00PLuP))uhw;Z?JKFwLu9qNRLe3a$1?z|lNY|jxX4Q}(3W?sxS zKkwn#Pad{JJ-r?Z?fBw&1~A6b4fjUV1A%<(K9BrT_tId@P%%R9aOW!_-J0UMI3cA}8)g-|lJqcyP*tccN2O(i_AKP3zeRnRRB>bEB^% zijnHZuSe5xinr!}b(NpcmQlKKu1i@o+?y@*Zp{7jG-*a0MuCA~)#wU8SNFW|lINxw zhbNiB-IeIKhMX?1v(dIDeS@8@Q;uY`5; z+Eu+mNS5bEs%IUCMBT9I!51_wJE?NJ_3)6)p$f-1uJ>WifMF!ie9IgdM6u3^~+6vA7!U^BU9i3n-WKyv{ zzO1&41FMS0pW||#du2s4j5F-uqJZu7>Lx?H5o~$LLUWcqiRgU5H6dS{G;di~K6yBr zAjv8IlhKb)F84y>S#HWLsvqE5NrO$^`aXGodCH(;To!}ooEkK}j4N@>vrtQxclN1L zA9HkeiuxOuqL$Xp+1|&mQ7d6S_aO&qOhLdaijgH5l4_o)uXCo~hz)(Ah#uj%WuY!8 zedzP4UzF1wuLN8uN@_5OVR)Am3z>uSEZesj6TM zYImH+H670%e~|TAH-6FeI3F{*QrdZAg~DlY7io_TyvK=5#{@WXz{|vqa}3jljt^E? z?ML-kd4ntSB+HLxX(fE}&a|HbyOZzs3-=|<_r;W2SA^XbmBkv|In@7x>~a2pBBQCZ z8%+S8327&k33S(_b?<$OXW8UD-t0(rjpu9Y3WM5a|5-%z=VTPA)9u-?$qyn3)@RJz zRc_rphqNA}}S!TgCw!skr zyoZf*Yzs5Q=VScZ%=bdT<%2TU*Q3HUM;tS%bZ^=gU!d7c?h1-?;f+9>Iq(84BUPvE zuFKeHkNqkm5nc{Y&)?PGD!w6kF<3gF=XMh6nlOpW(vqwJ4>Rd!}XpTS*8fn}~wRGcSdwI&)MjPREK5^LQ?oG6Jho$+A^C zCT}XC%aHLkr5HhA$x_On>W?kc;w_$*4f!mg{TeVPuTDIq2*_dM-R^pA@*haEe9iQP zgMKIpvwKMfpvauq6kZxl$hC0#Q9oBpti4TD-<@TJ)(|KW{;ju@$nQR2n>Fk{*-;Q$ zouh(9ZHt|v-RnJjJCF%1ba*lkejav2#a{DgA;@lLu`~s!NkbN;wcURDw`y3Q$J0{f zQj|&(@a96UcLL%X8Vyf1#)EJs!c2x@orfI){67ecH7+s9$PJ2$^)|Q46wPcqXb&i$ z`3-mN%Q2EW++Td+1_nmXnnTuD1Wz$odp_u6ZV2AlRj#`y3e+25u9FbcsCW2(n-{dVZHc=HS|H^u6<8aM0eLPw#)V_-UMDhHW|l0xa{==X7VD zj)PEC%yc;Juojf+3x(y?));2|Bt|kmt_)pY#-Jyt+lFTD#_B0Gv(7Q+YM{=>WAMqJ zepHt3Jg@g9f;+Umz$%Fy=WDDv5@xk|E#+W>b2Jfn4r}z2n?4aUdi};Pf*z$)V31{W zxE0z-t{CXoZ1;4!dlW^t`qWb({-Y+&YPMKTgcn`vJ^Yf_G%j%U2XjVBVZc7_)QO4+Y zU@K6kUnhA28iD7V&VfW?OY;ngM-(YrYX8Pw_)$2&QEOa@XUOyZ3sJWZb`r+&>yk{n zLhYvXW(g39V1!aw$g~NA8!0ak?Fn~8t_f)y#Rd|LWYVNa{L%=tpL!Qr0qgVOorPRy zR0`%rh?SDpSam(GS|CHqJy-^F^=nY_diaNTBfSY*RCV8l<&bwh=s+;c%$Vz6JTMfo zD7=+nXc<~`VtCWRGvHk?(Ew$w-GQb&nBCx^xYyGl)UpahThTnRA=l5)TS+hv?XVcD zUs|a04CwkqC%S1P6Sk*>M%$cfcqs4d;@HYTgUz~vlhJ01-|?|&S2Z?C0YA>OuM8RH z`3R2HC&engB|9qc%8)Pcc4JXhcz_~8kccnHF4;W3*W$G1DR}$yNL9ZWT~Ns!5dMfP zEElgYvr!Euxyu6Hamo?Rei*od(FTlV=9cwF=c87@PR=l8l6Hp1NYXXu=*IAjlRqhq(HO2c!&B? z7zR>5T>S+}5uOIdnnSpHyw&qEBEDH#9m!yV3?FD!z(o3+8Ww_Mgsd;~8<#pT{tgRE zq~-j0S({ej;uoQ1==48I(3XJFL-Z}N#f{97KXz$0ug$RksCVdoRH4ga+{i9`BM%)> zcos)3fj2o|%E&Pta5sl>lg872laJ=4Jf5g>79x-0G_MS-G;TKvIDKI8`2n9rptKcS zgvHjl7us*Y+#F^Z+`B3}kn2dYKPR|lM5H-Zl+N$d#NQhZj8v%Nh*+0A#A}5?+vRJM z*toUT`i9RP z^IHW+o__5X^|B$zcNp>JfFlpZkFopnRGJ?9@G2;}q>+}_%v$u;hvC$YK1~+syQnbE z-}tO#HT5EskZsr(J7pfz1blk{nXgLx5iH}ps+({Bm7fCfPbF%q4EF zeJ-gWLX!X^XZI0MPzl87=R{$>!1^s!F=2sK2U#^3QkdzjqY$ba&n`X-$XZ~Gn8{H{ z5wfC9DOieN%cFXvwpVA0^4mBW=LeE3UmPa!Gq7V-1B}7W9$O0B&_cRPL|Ki>ocfk3 zEmZSNFYDSHuQtW?`ttW8C-@ zhS66@1Lc6Fiq+?^N+Mf=e*8`REJK(XL9YWkQ3I*3MQpp|Dc4mAu68lV3^(NI^y!C- zYwFNZWM)c;yGWoSTh*8OdIm{Q`t!9O&ZQhMlh~wfvFuqwwm!*;I^zdA^HJp{b^Edt zjmkPQAFt_{mFyH$`f4C66(=S!QeNJeNyvhefOnBTL}VFNSU;?gj@oTw_nR>Xn;#)* zxxN5)(T`V}5p(}f>85%R9-|}cdqegdV)71o>W=W=j_RuK_!+0|s5uLIIVO%UQckLK z%+(lQJBp`$evkZs_pl+Q0l`I}9&*)IpJEHf5o` zwwZOCZx4pBeK3)MZ~i#MI)Ypkl3)u2bjpCv*<1=*2B?M_q=4E^p&|#h zFC*y16(X5o)ILgUZUUWRav?;7IeXO3z_uQC6d^Q_j5Amub5Pe*xgp}VztY8{RWbqq zD0zSe0Hq-iu!5KIT*~N%0{sb~h2#Q)?C9ty7X07xX8r9o;IBJG?cfGSthnRx(sXFqFWP}R_9U`U-NGWh!O_XF@+u1V#A(ln5@46npA)c zKv)O-$K1)rSVhw)kUGquBAb7_{q{aM9}*7~eVFTLnf%S7Z9{f zj*k6U222G|gH3M-2_pAcpB+26roYAzA#Y=s^>?E8FooR-NT}Ev_EQnKtxCW`Jk|lb zh<0i?>9vWw!XwpW8)L*C`Y!|O3}6q*Cw07o#;A>rFwTVjV_TtE@N6(v_A{PG-IvD< zm;Td;%;)i({dkZh69{D%)NR}+CLlRy$p}pgJkArS{WNu47e6O9i4N|09IOr5fQNzN zrVQFD3!?O^kl=PX%^i>)Nc6u)1pN61m?X{V-P@2%bJZh1b`NMeKw&Q+IV}J2gN>_x zyLCQr?gR+>bVmWd1zHViE&%RP&TbYoZNU2bBI+!)sSWqeRf_^hUX?Ih%rV44QoUUl zFh>w}V_cEQaw8@`-Rl$|JSsO{=X9~RR}tLmPD&bmRqWI-*4NU);M4 z=!zPnD;P2dUCjlh6F?!<4V3puymw;s|2On4$`#=*D=W903c%UI!a{kVy8S0l^w|O+$IG`=~)FJ7J*61ZG*sO1W<$O@85HQ z7}9+Pts{5sf2I-;C33#*eO>|~iPO{5-^wkW>$Cyo<|lS>Jdfb4?UQ!7SQ2b<{hj+f z-UtX%W5Wx9?}E-26>*GBPR2GJ9bKf=Z(7+HzJ@FhYG^_Kk@w}%Z^?_!%i~&E{pZi0 z124V{A_x#)-vf5z=W#aA(3JZ~EHng2vbWAUI)VVc6#nb&hpsMkeN`1p)5UrdB<2Yt z`u9Xelm@Vt%U#`z-?%9iS~`%tI5(FC7)msxQZ|ef2bG-<>|6HQh$THXfcVn>WcNL& zI|9@~BKCHWWdKBqR>VQxYfsQS1_;Cdxruhu`9u?k;EYFwL!CCT^Xvz&Kx-k*Eu>TZ zqpI8;EO|CJ-!ZE$yKu6cE{Ps^&eaX%cFq&-`qu9j7b{C{x=A& zgLO0K)~?HHIbmh? zeF89|CHOO5DEAq5$pcl%cGG{8MPgr^ezBS!r+ayz8~?xP32JVIgn$NhU7VxAew%LBrl$xlrf-r1lsM+TRPwC&k*hX~1z;8N4>iI*Y~6 z_XmL%>nY(E;1J+X*c1@^e)n4czHr}r_db>Qe+E2!z$>}OyNlz!jWb}%C#SRAqIU-@ zO+fN0E4wg|`+T>D7tsY#1{S)f1M$=PglSJ?8!rw@N+f}D^=d|d4&Ml%&2QDzo*FfQ zJ^)o2vyT_TeY%a6>EE}M=XoELTzsxad7@~Z$eGMenpYKzE}v~wAbvr*V}`R?oRQG! zY@Iy)NQu)G2C?H=|6TAyh3^xeo$AERRe*JaMFX-fpi)2itb20nq+tdv{$ri zJ?U@&0LMwTN3-Tf(jj(N7l;muHB}jGhLC7AS6b zos@ObyU*@)GQ>l~ELc+klBpB#>uzEK35VZ9!EPJJTSa2$gK`(~TX0R-LOy~e13hk2kUX1oT~8h1b6 zr+1mffRxdofZYP&I5ns&$w4f6R_d_@Pj^3qr=us2;u>tMglONIAJc#Z zFn)R`!kPAR8g;I7CA$aq^k*A5Pq>`n>yX+Z^YHpX@3T(thfV0ZCUyWD(`HBhb0gE@ zz7%0*l-E(+V!YRCJS1JO;WZrBC=xg|0kiZ?t>hQrCYW{4*VGm-&?reXWcq-cQVTL6 zjTUU&3FkU*CO&K4fgBXVch$AEKLfV`>Dhk%|A?Kp-}wDjz*^&dvFy#saEc6G0M9WI z_;1y!Rq{SUU1&ogm*sMs;o_>A(Jo(T2qazkFn4LUQJ{u3J2bh!u`zch;Zy*Rtg0Nz=*C`x18fADpQC!9a|Fa_QdZ=QEe*HXaaw`+df%4x(iNDfy*i z7({(jXFX78qGF8pyjyHw%wO_!CHu-P(}`C7sLDkw}=U7~Z?4nM>i@+gb5T09b;z@7Nz(+&Y*&uR($tpOSa-Q+L+y|Z%jozwLwr)6h z3x=GT*a6HuNH;*afZEZ0@Jx_*fS#<(R7gTWwn?W%H+|kxtV0}YZv%Dj(g-QBIa9^z z-Z#3HTcAyyHX%pjAs)YqPO48^m%yvqoD4lYtyKDA!1Dl<)jI-;9c-N+O}m#&LL@w3vLTKNq;;aAqEMy*IIUXkfI@%Xggy}`+5|w& zeiN}P&+fdm2I6)n*1U6_hg_eH{hv)Rz0DD?9;a^&9v(TUq}D1fx%Dj*wflpwD73g) zNY2HW=y@yxH7K#YBR*i@JzCpzZxlPNcM9H*il~^V$%dcJR9yBYSf4FdFgMH-^_nRm zHy*;{0^C4~BWpxHRu5JtwPLMkkOeBGc^;~}u4D!aNFKKk7pt!-C#Q|@n)IDXI#0VU z6NA`X5o?nX#G8r~P znFX4}J5?^3_7jA3UJ75_4`oU_JepS;+(7Xv^<+g)Y#x4Nis4n71S#kh77Z922#dDy zMo;YKa(S+DHJ&YUU4E%D0Yc5QAi?^%c1-|!FC_AsEPz<|Sv6m&+ZPKb2Lyxf6Lf)g zAo+pvfTne)I%pZQ+XD3zu>D)UT?p%txYNd(Jg$<9p4ZTbS?1iR zqO`iq*J`;Y=V6L?qB)S%#?zGC3n zGQ?GOIB4RSS<%wfT5OW)OfNYimMB!%Re_0Uh8J$9kcD9(&Ip=si0$#NHp3rE;)r1( z7~$PUWMw-Qy)ing1PQ!x>tH(sL5uK%wKrGjBOr1(wQKJpBrngZAoA`K4ebtHbg zUwvH#1A`KESV0~!h&Zf7Km;DB@L+U#aSjT~Jp{RDw*TL;J4&Lx$VH zySP7JxlywPa#gTr50|ds(yF<0wPgdC|2_qS`$n1W?dxC7zQI#gBSg23FF`4m%ZRF~ zszG*kb{w#admA4Y7XhviGJae9Kol*;r9SFnY_%CPao{P#ZbsJXM|Z;%F76#<{l)69 zNM&GI1X`p(i#=dH(4iMuLYJ&q_`z&<^73+9%f!%dzI_V(0#HCG2r#a5(NF15p1gce zwM`o{eR25RhEB*nz_YpZj$3W@3#+5T)ppko9v3rAA#A30!hr4$--6IQ%d1E9=gwtnT9nO zE;!8!1@06HPq+Q7i1@$1E{yn#E4&#>yv22v-F69%vNoIs2bv@EKQeHMNL*Y(KWd9> z_!4s|aq);j(o3sxKbMPV`)auy4b|Cva(W8`;cMpT_=bpHj8$;jWqyUF=VAl^Ik`H&4E}G0nXmu$gXoZC=mu$AH#6+?-xxK$@R>bdBT3jWR9)Pu`=x)m$n zSEUqXSA*sV1`TkLoB&vrFBu8FP!Dd)1d$vU)xu^@27hlpPlRhF1PB{ z`wHooPDBe3>;{-VkJRX=(8pVK_RY8kfT)M)Mfw>?|Br$F(@TK;0ff1No#ThKMLI6) zMsN;wGTJF2aP}u(;($nw{wm>d@6T_LZ(@qc>Z_1BUn{v-+b*u#`Xm!f1b9{I+~4Uv z+k%NHcYf~*>bP64=|!ZLnO13l(>K6!K=qA46`f5dbgksrW%60w&J4(nv%Qr>gL%BL zueKJ@PGmRjs6N>L_P=hKZ(L0Y#u~IAx%^u_VO?kA>3Ob_-CwiyKIN^db-4@L=#yV} zypvAtS$7Uj%%wO-cS~UtL&^IQP#X)__HK-_#K{3j{L)i7uXY9-PaF@K&cO@j|Mm%8 vFPA diff --git a/tizen/skins/emul_480x800/default_w90.png b/tizen/skins/emul_480x800/default_w90.png deleted file mode 100644 index 76d008f51e84c43ed93e6206268cb53fb7f4072f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47991 zcmY&;1yodF+wIUDg3_soN=tVm4IbJX>>i2lS8K-%n3t_jt+== zroo0Efjft_!I&2vm>(7~gjn;*x1DK)Z;js9&x&uCpJ&!VusX5vlN5L~_yX`tr0Jfl z1`hQ0uWfKhe#d2U1QBD`SunaFU!Z`l{X|7spLb%lgHSxD@UTIhs_C6vG@%bfd(x>! zC;>qzovv|$%Gd!r@{U zkl`=JXDB&wAO=#)Fj(6dYC+ie zATEut;5Q(2AJE6a7cV?PL8+jp@6L2ZPgyI8w^@LdO05-bViJ=3Zivn9gr%#?LHBx0 zk(~7@zZt4onj}ZJS1KjUSr5wDUC=#ud|Vs3+}Ni1 z`OS@uIi+4{L$e`W-+QZW(@tHa-Ho5<9sF{&eVyq$xAAv*^y}5`kqeaq8b~}&(5J<% z82P&fyoWp5spq|lpPKYop29RpoT6pZqRzPso`*}vzv+89`CzfW!iGQ-U*Q8)e-TIV ziDNG|Hb=WsenqV3+PMw~fzDbSy8gY!MhmbGT!VN#97`bOb6$c1J}bsMfj}m*OdMK6 zbrJ*EAdqa%ca~}?>WeN4woXi%E{w%4yt|M5LDEdU-O|L;xE294&L7{D|B!wiGFnZ` z@{#kOBrR{JhIL4SBOyn(b|ayfBhjrHc2?Kx*6%pzQiIr}W{eAAD4!zqUPNP)rv_g$ zb}68fL^3h_4STBbTse+U;q8YAEe34`+A}d{RH0C#cg=AkgCOo7cOk9vZ-0HS)e!rK zUoX>CEI<|XE)Q?q!u4%h3|UV4xbq(>u_*rB?eQ{eqJbdv9KojCmH9?}eEbW#d>Dtc;j3dIaGOuSDP za0GDBf;75cJx?fB{=?k-ENL zO_EH$oBaCW#V%V(I{l3;* zfBj+TixTA~@h0ykrezAZly-jFho$0NttWgj2GSL|;15+Ap~a-UZfQcJfnRT zQ&iUE)^MAu9oOb3ONn%9$>X|{!@Kf3$vbEl9{25RrKl8A zPDN41~jS%}+rzFy{<(fM!gEG;QW+LlPM(vn;u86G7b-MSCwzdlP~!BU*AGhEeh zwqF+|pZi5DKRtf4{)W1cSEcE#rIBrEQgV`BnL?RHnf!hmf8}9OW?`FLi$3Bzq11rV zE2CHPRxx83ncJH4noC8vMP#aC!k3jCrM3msxh=9D9bb!%QnK1j0C zIgwgO``e;Rd3-(0I(#NfDE=6QXdj=GgD5TM0Q6Kt#<)jProb%GEO{*`u4zIvfBN0e zcSKP({YEe*n0>!}e?BuNGb6LI>YnOR+6UF9!Z(E?Dk3Taqa&kvqcf>|>0)nZxwq4| z(`VCH8a^6$8nA(j!Ht%RwHpS7`bXf_ufYaF`UQI02F7*oDl#ix&a_mt6g??wQcF-P z%bKz3sXhh&1(!5XR&UN>LMy@cU|%zj*EWjb$83`1V~S?Q&Y_L5Lx9JTNfn@S9$nOwIHuc`I_OCYQkTu*h)bAHy8U z;vDJJ{Y!&w8%nO1PR48Alb4z4b?M!Q#n7rF{v(^C(8cT#-t0G7`aCYN4uzt?IX5aGG<*=~m2EHxzi3!p)A!#jnJjvti;eQGsRdWqs2TfzF1( zhGF#{hb+_J6&e2*4;ByJ4-=rGfR`v%XyM|r-%c5e8?zw{e($$4Gmd4pWfs}vhyN-#G*~x8BHA%bk80v= zGM~r9qKwOm?5%8)>~gx*TXmr-b|pR*@luX2q6-4eyv-8*9G~?^ru8!Q6z!C0gg96# z`M=t=uiPD;hpuO?y*wlJ zco~iB)lJ)N^_+8peXIZdntt@pvcZ`M)2_=&)D1yn1u~Aa9}Y>nN!H@Q1tH41?6i7YZRKBt zYDJyApt!JS7_1>WnB}645nvYkY4x&0-Q-HYHfC>C+wUe_LqEFeQEd0|v~f3sefJk< z4~^CJIQ3WR&2B?7sl}g#M^rwAk|#g&pL@ONxk(-BFw~K{`0GzeS#OgC6&Q>!%v3I>LcP4GkeS4ck)nrq6}V9eJ`bR zt-m%4yFaE9tj-`&nTeUcejGQ8AE9|*pKbH8l`ljN$IZm9Ym;&hk=r7zB4b8pjjm_4 z&`na^M%}b3VN?4(*FDkugemobmW-CP$|fV*rX%mRdY{kmUFs}>v89VPuT!#zndvMc zv8A?iZwGiE{BnhC$4oH>)V$16=(L34{o>s5qW_mpkDT*~ zMR_=8a3JJ9?lOi*1|udlW;lc(WIsz#Tu5kL!Wp@HS0n?mfG}r~-{;*ASCW%)`dv@& z&yG!`Oynk?B`0*)e=9)lb?#GELHoP=>DvE#^1L;<&_Nt_c`SO+9_OzRsc(E^@PGYa zeN%I(IbMWFpiD@3Ku1eCzcc4yhXQ_+!Cc{kDhTBL5(Eke1c7cIfa5L*+(FV#5`X@@K0k!&JKWlYLRii$}V zajTz5p1$M&h5OW?k$WK7dCu=aR-*9G74G5Pqp78psy*D*zGHzY;Nc?ftCp=9o)^Y| z{o{Y1RFy2vp#S^o2M9upF7>}p&yfH9)DMQl(tNys`?SZN1Ew@W&Kp^W(1v4cUaF^Z zPvkUY%_sPR(2Q`23d&WF=|6|>P54m6J)9(I#so#JYRJ^8}{t;m$|KUefIw8ta}bCHt?U$boGZgeF|{BDhC>go`h&_(xv zE){!s;oY`T1U+Q-cNfmwfS6RtAG)UtXO1PUc(fRQX@LGabWg|z-jyO=JXt0BaEnqg z{pFuEZ?Q?0W}8XTyZoBXqIo;!?0r{Z*ULR^@B5qWU5SV72P3JDg_WxRR$bj=#wi_O zb$EOHfb0mRNAAe8>Q2O24qZCYN~oNoiR_@LJ;1B|_a98WxhcSDWL18bRqlPP zhDf3>b@MdWnpLJm20O087Ynvk6Xr2uWXOdoq`@=f7l#h%|D2?YFtiPufLvHVj_%t@ zS5?~s^0=zJvhqXS{O@=9Qq!d(OU4yCCDUIfy1P+ng`9(q+7U-Xfkfihbtau0}%&8|`j9(f9jOPo=7&V!f;TUxXwdoamHk58e-*!OCa}8KK}0 z6;)MJTU%QMl((3NkraQj^B&-VR|Xfy^Mkds>mkp6&B6`vhZyFv#i}2Kz1!&cs0jAl zTNao}4R7l|l)SIdfjZOtMdJP!Vj`^quIfAoj@T#VC*Ru~*HDd{U3WvI=+RN+G=7QN z?RE?hZ57L6_R!tlhkns&zT;i(D>;Q}UGK8_pNhu`+DQ4&bO_dTO_%A~`1;Z!7iOyx zmHHz5g8z$JTJc2_8jPX#xi#Wd{ZtOqc9oU8ErH#kL{?c@G~M`hEPiAxf%o-0n~XU+ad=i zA9Iq)-38G-b;_rT)T_jAck+4C)6@SR-@=uD)Bkodqw0~CxRnsGb7RHt$+iDE1uvps zzJ|CSHc9nCVQmA$!^3}CTU(?3>g)ce0gP&U=zR{}&P5Wp$j*ATpO1<7JNWtCcmDhL zZ|rm3{Nv`W*zp^}YPV9`nMt>2-PCBeHM|I+(e^!W<=co=8X%YEYl53GJV!i}mEkZW z8vCxf1pkct-n77I?TzbG4?z+SX9@ClTJ;~JtTm$?^Sy<~F3acr0ofsU7pRg8=|Iu2 z;E=CHQ$h_*O-(hxqqVly+1t``^M?Lz6{`c+lP=eMAR1^5LfYns)vmyXqq&+uu)~U4 zU0ofon3!sX4r};fjIJeSuxf9al+(5B-AXf73Hu4#rARzT0O_R`$h&W)+HPIouLc(i z^<{=otOW^Yf=UoP!d145BGLm)$fThb4eVyUHCq5nmDaUYcJjc{P0>S`I_p^9+o4J}^#>n;%kEW{t-8np)=ZvG zU8b^S$ppL=hb`O)N{~ZiNpjm>iziu|CWIuP=xP&sB)(K`$4L*|Mo9m zM?Bwi75=yDYHe@-GbuUQ#?37eIP6XqD6>XJM*6#Njiko-U_gi@?oL=6mc93LeGyj^ zKqWR`zeX1p7Fs(ybDwe#us%Cgzhx$b`o!|p(XLXSWLzQwtn~YXaeCMwH0xBNEhnk9 zj%>79_O`HsZgybp|{PWWr>MU-1v`ZWfy;Ozk!4`9Id`0@LyrL z@+;BpxZx8v_x9gA@d<% zZd(k(aY;Eb!)+KSU5oV+FVfZk{*bE1OeUf;by+dxNGtb*os)AamB(slGugCI*TgGW zEmPQS>+h><(T{wh9XF#6_h&H=*D(^;{Q~WAR|oSlK3501fB;WjT<}hR;d`F z9RO1C)Gm`hy;hhg=BioNj+5Mw{Iq`EgtRPth$)8`DRD z3`El+4jxsR$79*+6|Jae?A6hdvWUl#O6#c8Yj>JxTI#UC+L}ubSMSxUV-1xDp@WsP zRttMHee$+llIY`4qmH|LjM~zPs^%J2hW4ke@CL6~M)N7u)D5sRGt`{VASKEp9B(7P zzwSt(lslHIe3WM37k-U+$J8+R`wN?#FHWrvMm0;5e>1R0zwX%(U3s{N z+qk$S{6C}E!u$5Elza@G>OF$M!4nODY0TB}iu!-nNX+{e;0Z3h+j>u_9z3dMp(Ns2 zl`{Zvch>tNFV-VDCruwNO{WCfPk#=Wemm_G2oKy2rSsltLL7HITmy_FgGEI5`_bLp z-F=IvWxwK;*Z9+yPlI-z$f~;&bH5X_vv2w!47B=6{^+P`sZN=q{6)(xqsY?`Gv{N( zvEc+luS5&z5<4%)$14_!r(5GL&lJAOOgmsD&o8l~2_!i;zZS;2_7>x}c6U!&1{}i_ z6277yBYK8CIx@n9Q(z8`+LtcMPln;D0i5$6sC%@Z)85WBv|n~>s*Aa$Q+VF5Vo7*z zJ(}hAmZRoKLV9r(02jZ*!*L?=Ue6EHl+mXF{rr&P_W<|Lrt`g+=)Dx@Pn0!acC%jo*ALgWN(9i+)xFqHtY*eYtKpH86L?==TdRre*!ji%O5S zNWZ-zAWu5ag1;}Cny-B(NHDS6JO$L`x-~+1dpp~qwgM0inRxq<3@vP;NhrB_paBAZIe*>43Yq~OuQto*0;((_aw@GqMGA&moz=f^@jS7}X1fBh zcFFzL$ah}Q-(UltP|`Ics99pt3jmyn@1^!_ddCg*ZDhxFWSzR$rB+GWc){vT8^H8` zA3-zM247D1%qW}QOL_+nHF|h7^t&r}>Had?W10E$^ZIG2skytmHfd>T&1Psq=v`a` zz57#_P;b>na`*bg^YiAPhDW&Q`sAo~->nkg+vV9?22`t9fZ+9sV&KwXOwE%KzE=w8 zYCR!SWiRBT$2;z4AJXVNS5bgLAV60 z^3Vo{BEXjY9_N#;VWc?U!84MmoT%TA_aw-$%w+1StH`n%yV^O)a=ySI7j;>Vd=4M! z{Sh|QuF1#TI3Te~skHwci!SHkg#I3F6atyLy%h%R{3`}phe#V2AvTJ^dg)%L)ISveMI)mEL1WIm*nJsQd0|Uf^|{ z-~j{PPUm;DKY%CsQg47g5u*2tBP;7(s^c0;UKxX-JJ6y$8{CBL?AEFP`S{a{@c7f9 zIxuL2`yFljMf<@7{9b(D7QEqo@-lbv=es~cT4CA85|^9?XeIJ7vLxqBjD5HNip1rB&_R*^$h}1sC{(LN%lde^?Xg~A|NFa^ za~hGl?VC7xIM8IOKN|rUfwa$9#Zrp}~QE$q#W@Wg+(UGvxfy&04Iq`x;&e4dgD=%-$%Q z-jeuk@nrwUY6EIR(oGF?hx7%P7=8^Yb%l2X8W3Y9LarxolzDVDOTg&^g z!CtyE(FaWElcCawQ;B=5C13c`MN&g+Fi@E_0C3F5^TfG6+dc|i-Rbb-Zzo)<% z3=9qPUq=+r+kF5g9smpvci9gv5qV*cMji+UuxCTQ5|ae{JSL68FnUpmH>>dnnX#-u zi|qEj6ZOqyX`)xtMb*TK0FvU4fBS_JuTVSx$>^+z})oE$cO(+12P19tI$ z^Nhp!Ix7J@QDBnk;RHHeLh)|;YeNaJB5fw>ll~7A^vEZ^@RpT=n;S2S=@8J+4ygk< z4rquX(7J;fCU|V}bwu@kBvM>L9;7v>87lYemAYxN}$N30rA#WQ7J;@lvgguUEkbkr9a8y-QCjhpb-oHf8Dw}3` zd@$WW1Md!iZz8h7#SL8!CXNhC(?j8jHSPjP8m6 zVk?Zxrma7H`jIxu?0bKnT?B+y02wGe#r(f9W%x9C$F&@=OKQ>$f&Up-Wo3bX_J|3f z!KSQ2ef_Q7s{n~!>;QV<4er0*U|tSvt*fgwFiw0?7RKGq{30PkNsX|1l7)YQ}jXaNwS4?x)QpJers zqkUo2D>;vbCMzps)++#TVkh0_Ibtl3{Jpuw0d}8O?iJ2kW5Xz}Oh{sci(;b$SJv^V9K|Dej%QwrVa@eKf^mtvIeG2^CylBuPq`qE7qG&*C=GbY( z%qu4SazQAoOmtTFPn9-X)Kjk+?J>*vW%6VWW7Hta@o>^tJ7DNnWs;9rQj)-6U7?c? zPzzvhWjaLuS&IHQ9LRf}2e1NA!&5n6tSr$fn}Eegr~&y=$tC{H%fI38L1TL{hFi@`{$6=d3}lSXFKY~FPi$vEN+a&y;{;e{ z=ZePKo#_YXlt&1G0d4~>fD0d>2Hc+5(&;^gc3NzR2SA9&KnH06#IxEoyZ_{gMw{P~ zKC*}Yo@@RA|HiUcA?qp1*q+It@b_ffkrJvZunf;^ozWIu)BC{rK6m9duttA}J>=(Z zaBAy$buR|y8%S)aEn(05`Nj={sP$40!toH5oj!8Y-#~Z_WZ&T&z}bPKf&BvJOCZ#S z`vkU&aM}3)0iR^uyvnN3eF-pO1F7S|eBGmS{Q2&MlZOoP2D4y3=b;I295>-Nwq0f^ zj`r-A7xwGe8h-P{Eu9G<8F#3&0CHWx*C^T(_;Z4FpK@De+I#S5HvVN*o)DI9+o8*={Zj z{H=ebaakX|Fl&2WXF1hfio3dr{#WXdx}n2!vEAd@Vcl+9BnD{kT}630(+Lfl8_lH# zu#wYW4oC1I0ANS|P`60%np;{1hlK%j;Y}Bd?|4P*S@3P;vtttBsKQmSt(KGBH1XF` z*X9A)Woi_2$n5!R^0lfFZf$4YlWzK(J&ww{>`vc zFvE3Wp4DOu3Jo(eGht!iAUjeG5*vVEuB<|~-{nuJ^zhJeVfT}pm~aJbtk?!HFwAR7 zeI*XgRo4nKAr~tAE7ncq^te2PzWk>j1RCZyO%HD?VwQrw zbG*Vyvlmb@f~ZvHFYzDwkDX;c-=3*IuEWnsnH#R)In_q)SoD0+yk!zD9=C7ySq>=#gkM# zQ{^uZ$uN9b4Tsto9p`f&9l_#_M8pVkzL2$PzFGPdP2j8OXt;-1f_RiNAYO{MlZdI8fyN$r zRonr?1bgw4a(xK-PjmGf`>rU1DD}jvlq4`px$LuVrh7SvS6hjpz3+MSx zR_a`?9Rxqs>LSBvBGagAJV#} zPq7TL@RYT3O4Dq` z;4ibS1}xG|+MO?FPa9)i@&y_41u02X9=S*oug-tU$Lpsy^;c+rH5r5BsN*9#<(6n1 z^qCZA8gvEARpWk7j-gH%^XCFt%d*^&VTdc(v(qHK8cC-t-&C0g<3ARIU3AI-izA8k z9*mx3-zpEXnl~TeWmCq|r$&%e+Y$0>fg|z!R2J2r6=Y+2c}E5rDN{ZKE@WBKY<+ht z;VaONZqXRG^Ujt)N6Dh)`UDzvKfsv1Ji|N~5=&BhpMaV1VGM@HhPeG2yOpUEhyPdW zx4b?Bjc!`WNZsF>7`MeXmRiotd>TEvan?ObPE8SLQuA8IcEA$B?uTc_Ae1ANvC2P+ zXTzGCo>Ll}`rZ%H?xSra{l6;ti$y~(;6L||Y3PsgRY3$&!W#wKlthK5oQ@ZPEtr7> zj5A!HhUlpo=kHr3RJ;nbUyf6`MVIGJEEd%CXTDO$JY=(9{RVdgZXcj$-CsT|MZr$A#cYxZIVmM6k0}z6)+B}6|7d1zq6qL3 zx6(wgQ1o;fXXC`6y+%FAvG>|&X=PV@wGJ`?+azcr_%as^=#FH|@0dDV%xR$5qs0E% zh|lkpKsM9F>}}|Yf6SW*b@+|wK~$)sed6H-|SVaMW^ z^X?qBTe*%uJFpPS{*puMw#>GzB{pkGfU^aPkuqDPDJZTD35>zRn8kq!x9u-N$gCt# zzA_eD%()YzgM~!~)%Gx<-Ei+X-e@7nakD zp}0Nm+&~dN^5OqNf7Iy5h8t3P6}v5@_JDlN^RCu{RY2RtXx8Ux0HF{Tgkn5ab@gCM z+=`85o?wjQ*PrgYK=Fws9pezNJ>OWt(chmj+Wc|Pl9MwL&4OfMT8IANQFk;4$+1oz zlO3*Kj=o3r8l?ksp=Zxo2EK>iCtNQoc03eT8RsQ8DfkRgK)u9bV3H-+i_X(VM-L{c z3&Z-|jgd47FAVuYv2-l0+ie`RkS1~14Tbr~3;>g05r-q#=CD25EJ*j9(}XGy&4&4z zzb4=gvt;=s!jxbBOUCGDTTu+Op;MSX4Boo_MiIg`F3eHqN@i)Vtg|zkc4{PF!dWTK z&6nJTz(>hq3?r^2K*{h`{$zD-ggWmfQR_X>NcOhr=Urp1V%*if!pHu#&E#LT0_%{+tcTll0Gv>{^cN(xV5Vqq=wAt-ZCD#V0_)_{=Z;fGc(?YI4&&%hl&%w%< z>loWkjnRyJF*q5x#9Bt{q7cvPyIswH6>cKw^+76g;$G=)SIH$-!?HF^vmT#Y<5{h8;#Ve(DcJ>LGEbXt4mE@aB~O%aKz#Xgs;!5cA3qqN$v5qUR$&>j}a6 zR#Hi(5z~#X&Ny2$7gwd0rbZ5Dvt<0Xppn^e>B>(U$|2Q&*LIqNhMxU0XfK9B+@aX7 znb*iy?dW-xi>Gb(Gq#*7Y@jP>a-B^o^nJu1FjwmWMz|ns1FgpWWhLu%MlOQ7ByXeN z4q>cWl95G7bIOODwnFmNj(G;8QPIPLtgz1rGJKoq0X|yAm+ZZqU-tMQYN3C$`Pw`S zuiy12XF|bXV_SV;4C4)D9s75R?gqx~Rmu=ld@fUjevyazhYwF@17?F^3UFSipZL^y zO%>g)C_=ocEt*-$|5=I9C`#9d&Y)p)L#B+3GEqIs9nB~9jHgQ<^U#^mDMPLBKT^Ca ztWt(=*nTm6+o|toC`jNjy*(*3yCa$mn#{MNHy|2R^yg@RgWf&pkJbVpwdM z^LY6SRQGJm-p9}G%1>F@TDQMNXfQo>zr@SUe!`bIW_8Eyx?*1^6;_q z20pqz0VF`MMQWrle5yBcR$Kiyy7eVxhU%e!3r3p#>zd7B5ymQyG+R0dZYu1GC3&ef z|M|_Vpq{qaO0nKI3XCYZ@1nzbk{Z^Vr4kkAneluupJjyku!!0Fbk*tJ|43NylTZet zRkjB9b`blu23g9+?6FXY2 zoQ{J)#sHqmp5I0P+^s{B=kIT_MWPz*Xm?uq%7KJOmLfd!cjf{B_(+9+p|TGu8lkA34v zbSyg^wR}{)YTTxG-<@$`pWt&zbqLLEPXbf)_Srxzeh0r-+DplHR-7P}dixABn@^&p z#q1fgBF30m5i`adlcpKDi~3^i0DBD|yh$eMu2{cWk9MXYn~t@VQVMOLs83@w)siEZ z)Vq$w83UmM?yI-B2P&U@72 z)fV5g%0YymeEDPRM&O8B)k{L)i$9;P`_8>j%FCxl+gWo`#E_=Y<}i7Q<2kLd=XtFw9G~n* zTldCK|6_I?Jst_i5)pMm)Q#wXLc3b!hE}7%*0K;sqH+BDA4)?aGD?(e&ycvC!61ld zN!~H<5|(NF&v|U0O3T`-KB%2c(02kz#Su4mDWCO<(@d-mt+`+9>>q1A7TxES&u2CJ zhg0wIfaFJIlSTqYl|IO9j#ZCdsRDKEoBVckKaIk-7pXt8>p?q+U8u?KK5r|DQ- zUz6}0JMYuZSB_vlWw3pY9Sg4np3&xC=8ERUajuV=^$)4%DH)xRHVAm6k)_4oQ%|vi zdmAzp!e;qrC_1K`xXL_kNE=aUXY7LgDbxzP)@%J;BY%Gw0UU*K;mD+DOl7!vYofI? zu0gEOEKdQ4h4dVwp<%+6gzK4ODM`CvJLjb@liR_gV>AzaQaIOZ#uhx};EB=AW3Bb2kw0XXksTQ(529u_UX1PdorDVm#-DwD*!alw zA$l#&xH5%s85BfC&BvioQ*maT1Ow*3;9dieRUMMCCc5QcaIn+L_S{3+zPFalrC{u8 zaY=fESYYR`VOvp_eYc5PE&YJjgZ6ngr59z{V!7~1#KN1YDhayG?V*hqVs*A;L}4-Kc-uT&Y!>t2wgb7V z5;FT?E{DD9m7gqYze#qm>T`E)RK1=U7fZ31NSx7C9dti!g~VQ-;DK082)&Bq1Wql;8SBdPQOc-Aqua=VZ=LXMHYuEZ< zW2}sTd*m!vOwriv3LZ}e<`KL=g}g3H+ib-PVdX3C7Er*6-f$-U@9E+sQLCK;P3Wza zUYNr~RF~ZFP}Gl6w&k7Y)xviE?C?BF`J3X4OBdR*gG)z1)fL_eiBwU4*kT zKPN-+UUsX`=cZh5qZBu?VqKKe#Yk?s1wmYpP}`E6S&;&T*YfR3Ve58jeD)@#yk){< z;%*0b{U2?qN*lq@J7Ohmsn|X|LU6{4M@-$u+mZ#SjZ2EeFC?9E<1F~+<~__wGO7ZS z_SXY_d7l`4Q-hYMbYb7UrbETM)$Wo4fuAG(y>18sUAN))veQJ`c(<>rG51X;iJC!- zme*a`SISL_TW5d41@lFBVMFrIPNkD@^dTRZ?fxB~1zm23bFI=z^xRhN7=8G>CL^B& zzg~WNDqeOLWR)qQ)uz7Y8}g@%M{@pH4l|QsW74;J9uz}FcN)KiC9d6sJ47)g*IvacJLmek zHqym;Mtt+YN7Gz_s8KPkp?WU;p-~))!-D84z-Anz?K+PNRZ#3mxvEz5esWF0Z9m1Q ztg>Snn5@+hXTi+`Wu_R98;^wP*?b(?cVagH+iI1Ral<&(4^1kaObR)`dvNc0Zatdt zMnMFh!(46nO(={f!+cIw;Sa&G2cXCA-#vt(sOS!)IhboFYitkKeH3PGuRL|o4DYN> zO;crmUmSFux9LBW)V#h-D)x27$>cq&Az73yO4W|o-)624%y_Odwj*`$EDS~#aV!FFB_w{_LqZ82IM;j*1|x%nVluYfF`y9~T{JzTu&U2KzE8gWnM zj>%^!w0#d*V$h@l06jn-w1*c$n|0@BPg&=oc69?k>VDG9T5^}iPO;j+S{U(yo?tNvHh)%xYD1nor#k&#Jz@oN+{XW3=rSo6Ybf-de68PaTm4oLAqRZ z<<-&KvPnP|uN#8={s}##EZ|kFdyT>5wz!>#k1*(_!O!Qbng+UZ`r>O5!`d(ZQ8iR+ z_M>GF_+$#8HLz4U>Zh>YBH5nE%GGA?r*+h9Q$D(YzKfp@^Mv+9vq|U~B+3#f8J0b@ zy<*cJwy>89iu$|C!mSw8C#$&e@D~+F`h(TB-?;D*QVjh|)DiR3{<^<f_ zo9#UTn&h<4kC#6^jJ;@#f}|whpnH;Wz3seqDsnJlQ!PLs+P$OguLRR+%7l5u%CM)W znjQ?gzm>KS39Yim41le{2Y$h3jhl-Z1(gw=paC%}*zN0KAuK5ztGT^K+d){@7->kw z5VZjldJF!E%S(+BYLqUVN|J=o#KQz9=^cUJG+8KtM{uH}@2&TjVs=!kFT$0GO~93 zG#s+4Wn6n1T3Z^y5nzYquiH8%z9d7Puk$;|JJhVPfJrUYyyQ%Ra4BfBYIkwp)=2pJUY+W9qiy=4@MSlS(s_HK|xV-dv3teuc$4116@F z{4KXQFQ&+WHU%Bagv}h4UsWtqGtcXH&&3@|Zx@&iNoi2SL#*)M`y=FraDV@fwIKx^ zC=b?GtQz&VbWfAvAd=hyvVNYY?h+qy!;9>;Hd=E8v7a|yeToT;sAcT(k}i?&O5~{W zpKpKdeMqx1JlW62kowBPXn^Kb!Bt&p8)U8sA4nUpE$i$2nN|dhiC@~s6#hb3z)UPl z;Gd0zs7c4|NV)bGvzeCy?NBp@qn}lt6Civ$G)7YuqNv?(Q95=!|00YwjPc*2yt9m# zOf0b}x4j=Ewd}znT@0Hky*Jb7Sl>MYOG!Ll|t==E)^%aU|^=vj4^N^GCaR zmRIA;+iWtCCqa+L{F?kwrP z;u>HEw=JDFC>gSTyJ#Exl!%YXMp_K;X%;4C@ ztFZ~%rtddsKQ6G%pj;vPP_`zM+FuAf^IkPa{_Wm z7Q5`~9TBTkp9bm|nqso=%iK7vwOP8B&uh8O?e%s%XBH;Bpaa_7#RvD>t#Dbl9gk+t zq0bhaQ(vhMKY0REN1aTyt?kOZUhUxQ+b?*aWZFPs=rFRi_)FkM+oGkE%;b3yPlmB& zN?Y_>z5_&!hd`NBmF>eh!;6d;UHWnE5q!VH$CCnEQvPIof`pa+pG@g8|SeV1X%T{O&sBq{#k!@UV702}G2%$Hh1$1YsB-?V>?QNdI5Ugk!G#BHfb zcaMM3!JxnjKzHx&sC!i%(Pg4)5(P`bU2g#f)yS)_4J%thZp6hU{J$fa71j?#qMhXy z0|qZmSPUZ~Uc4cP!`Gb*TqoqV{cNXJv}-^NyLywiIH;mMjU;pA#nV6e)487yn+Oz< zPcsu$?g|f=_LSP|4X(`*mD<`RsuuSxRhlhZC;EJhWU8dPOsx$_{Hi-4u35wPa`=<{ zgwRW(FpJCEnEmW>I)~|S>^inWN2mkKcF*%j(&|}YAYJX=^Q&fDi-nk2&3>O@E(W9M zXfMBdgIQRz{Y9_Mq$DTf*@6oDuc#l%<<*+ZH`;M*WBHQRD%c+Lh-^1AhGCE4AI|gp z>^x&b;xb-5zpXHojD@&eEkEdDT>q!*I=OE_zJ;xAg`~PALHveS>QGk|?MS=QZU@yv zjU)B&vJ@Vu7_2zwLS}G&-5ir{={7aPu%ei z3aUg_S;BvjpB@mF5=Cu;@8+EBk9p9&@E|F~(^tX6e4kXo13C`XLtq8?kkW~>OM~`p zyAUa#mz#8LP%G)8S$XL~JRg%tmB-uTx)1&P>2y<;ZC93UM{@Dbn>Sx4eEVoD3$&QN z4^MK?{_TnQrJwMLbr*ewn{q*DxeWA8;VIxICb0OI(G;_1ZK_?Uq=liyw~Nd@6E8v6 zjj$9{-SEg@<{@x#F{8D+`jwYOhNdJuRDNT7L@l7)=WaOx85B|uw7eH2`+<}KAgJ#siOZUG*(COHIy&TIBEMY@wLLyktX+)e=uSSE{!hJ}KIZFP02B1$%nWy>s2D;62@u zkt5o$D@?1=?o2o(OLIe`|4MynjV`~7_p%U^gU+7D3Xf3oGaFXtj@1Q5w3CB%5bEo) z7V$TZduOF@bw|}Qk=DXxe{l6S*iQ4$Qh91ZXDvLN>|Ge)b5r{H>9!KQMQbZWTQr;H zLl@eV45Mi&%5s#iX)jYE4;eE|v-dgDw*IJfob$Y}h;giEUD8G3wi6kS5YpD? zC@nA2mBTJobI2bPlDw4ueso@TfJSSG)d-23B{ja#r+(U>afP3x%9K>#n_)6kKJ?)} zg4Nu6qDkHA*HGjA>XiaCsW-9*YRD_QY-xz=Oq^v*EjfwL`xmbGY3EOgwk}TDaQxM` zQtqtAfyBRWKeNynypmPILDBK5_%MV+c&nyUJefJ~tA%M%NrPwf&hz2)Om=YR%yBCi zE{ZhfHA)p3@iGz_kTQIzdyjr0X#2*Ba@%s>n*30c&^q}e-it^s_KmbV0O;E=2EL^cFP)(R*Dz2vMTfV2R!(dM6}Si!OREtBblp z@Spwuo;S~NcxSoqopQ}}UNiGK%lelG-R`4Pu*bD>o53xrBJJ@ct=}m=Gjg|Pv{KF@ z_A)Ahv$bn`x1&sog|eBWKStj|14~83maJj&&`ljkjpgF)ke~CkutId&uXQucHI$!j z$1jrc1Iw2W<>M=QZa4-mu~X2Y3^@FtDe zh;emAz-zh?&eO$|U6+|p2*#NbQR$TG%iTMu!v=mHK60mS*s;ZVfiJqv)8(wPd!Gwk zU@%LRoi|wpg?wGKa3!md|a}hZfGH7sVKX4oL4UegB zu!V3Q$;VgDz{pw&VFaL6Wbg1uqZb0Xgxgv;izH19Q<9R1Dh{rAYzA_N3YlewjU1W} zAhlKvbl&alH{Lf-89ikR;xuiJj!S1Bpu`v5T`5=}k@Y|MGQz(}Ky;mCK~41P_u}(p z?p4OT*Y(@Ax*rb_JQZx#EWBsJa0;4f3B5p(J(E^)sZ%jh8e{!tbBR%2PbT#rqOanr ztYVz3%Y&U3s&RG=mLjlc1Pi7k92E2&&Jc1vszwvyFAR^3thl(V z<9_1A+0=bhoU}f!3)kFt^T2X^twb$`o^;sZoqjVo)j%eo?!|JD(0I*N)LA>|v0J_` zGK};4;+68;!OR@U zo95j3RC{HZK%td{xMJVCO>*s!|Kvpt|79_gGh@z)K4N`iX%bqUe-<$Rw5Ik^Y6|bz zaYLH6J=duCOU$T7-&|%ZoYA_MD^^=rK>v@queO>hoju-VM(m|yv%b-;}N`nriygd`cqa~hr%kklfY=z6_6G^OM!#y!loEO{kvYHBI!60T&%?Kz&L zv|(PwvGa(sOMW2%VFHmB8qLne-abuhAM|*5y4b~d)9nN{{F(*Tr5e9OF~PiVpk}S^ z=DTEUd$`Zu9#haWTzH;b-MGV{*Nd50?hxpa?UR6=Fv&)_9SEm*SwP@*gu!DNZ|Y54 z`bxX3Hg~Aj;Pua**NL}-?2N|IQxsgJGQYn0ekXI!_6l|#1A8~!W5H5(IlT|bQ*t~VPVy?FXqghr?N5Mc%1Q@w-2;sHz;q2l97LR~q=HG5yt=OigKCi^d zKveI`jEJm%40Onol8rR; z#~D>CORmL?%0OoOcBMx{w4l2S@iXJSVp}CoVxp1xrbV+eMzd2!Wo|u`geii{#XwCf z2XvT+nYVNLgN_jQZvOqSV>C8Zo?=IAvyrpU8HJuK7i$zA1)Zbc;x!oa_5<|QtPuwY z3i1>8&D&VKn$<#E#xyaIn$l1oRrUVGU>ZxWLPeS|E-Pcj~;0< zJSy6A^_br1>hE->y~)rEP3MeDw8-PYutB)&2vjswVpR(iuI=ms3>{F7$@wzc=mFzU^r8VAP*npp5ROj`pvuzqjE-Jr(j~DF=8EE@r^s>f+3-! zx-Es3Nd?~h76#hUsc|_p)yn6&VD?QFK+vtalc1yF5!$1pTlrFD}Q-Y?CkCM{8AF**V?$;APx8N zQ&Sq0eUX1?pp{Tm&f_0j4(i()5UZ4Kc!;2y`phvT(xMQ2VBoA=(T=$m^}iJlN7SDZ>EAn?NL{zv{6PsZQ&V(JlsLq%jU%VdTcpGbomv z;;S_P-l9}WvGW=CA0YG?$4ALJm}}Hw+YsuSezDI z#f}Is>rAtV(p)G1qP~&Y`|%~_@FHBV15wvM*s{s7EZ-Xy!=ffkcU`xiMpFgmwSe2VBFww@eV~Y;kP(Rr#B*D2f zO@Cyl&uDUy`=3^zHWLQ_=q!9TSB#)@D55>?nl{qLiOA87HvQ>|t|7%B{z6!v%)L0r z=W*eO8ILGm%0mrOZ_2R6$*pCY^^P_;{khb;NBJXk=P+nymV%EhU&no?B4B1IR2 z9s;K>d@I$AGFXm?cqj0f>EitWlfuSo2=(@$?}?+5**p8i-Q_UTO(Q+uA9|4e=Jw6S z4TcJffeXjfz&kxT<XDrR^cnjs*2bFZoj9M5X%WJnYntjx{ zUSedpRofrk@q2mRZ%LnJ#{I-y8p8q_76e|Lq86H6OVdA$;@Qx)s^Sg_-^L4s;_|^T zjm6jO2(Qe*A0i{%42IKRI~sfG12iLC$?&O27@kKn;)T-da9U?=qlIvQ18xiy89V$M z(y!N-ZKrQy^q7NnQeRZq=4RQ~5yoJNFutyxa^61hP!9`AnbCm>J);U0tA5hlvmJAJ z)qEU_?yAEx+ZAa2dP=&>pv86>)f8&Q^dR}0ZwMxCH@{TD53e1rivoA|39`@7AUiT# z$w{quwwh>UM}nVcN2^78FY`P~l^6>)Xl_?Hvs|B5NDqrw*Bv0Z_lr32>w5|G?w74iMk>$yX3`ny*Y4gvQ3+Fk*RF(Y3Du&dL=%Zu}DS2j5vlGD@XFY^y7YEW(16RU&Fl{na9>-VZDAZ(!+jz+%Xyex49O-K?ft#o+fm_Ni=s z-Nh;W(EOW>p`$Wx?YAn^f4P$hK7C}v3H?TAO>R!HY=h&D12x6oZYTX_cU&|O<(~1S zvTZwWzsSXtm3SzLNY#%nTzVsszwI(_!z0v#E?#|nQ*jaMMW);=1dBh%LCYB>i%b{Z z7t%qkE>A*z*RjkORZ-jMq8U2aKJX&)LqPoJnOCT@rB-IU;)Cq;BxAVJAgG|4Qwg?Y zJ@6TMJ3F5srRI+Dp|Ek+K8F3T0k47rZP!7IE=v)$r=vQk6x6Z1G?(+T>>5%x^_TPe zMT?5oo#aO_XPMrHv$II~V_N%W}y=L}$u;;bMUM7s~wF^nn zvEtRPa1M(;2+12VHKk(y0prAd&Q>4sQJJByL?`q(&a)+Ajwjt-sE!Q%vLF;Gn=^}B z8T&xk$t;SC?V%OXo&9@WYvDX(-KDh;JPpmYwG52-c=pfPDwIxBnPI4ifTWkt5zV|m zQJJl`t7|Q4dPl_B;o*Cq2jn05r%VRB_b|1Oo{m_$OQXaP1BA-=A){#6@VOgP`1`E+ zwqntLMq5z5IFDIqqWCdf&w6G%#E|Qu7W7OR-|06m_bkECB5W;|WtD1wBShRKiETu4 zuRX?Jo)P_&<%0djj2)eIccYL&m~b$JlJZ!O`Y0^L`|S$<53Etah_lZqGS7I{9Yjq; za`#?!ve)P-;&RjCX6yQ@3BOmjdB&59QvUW%_nQ(MWlBr#xJB;TtWGvL-B3#CdWMg% zg9==j711&3@6;QY7_sS=Srd5v0KFWX1|yJO-}38kJUZ3o;t+HVWr2xPZ2ekCagOtA zDj*OY;aF!^d0obC@Z-evDDa3Smzfs+>obAs#qzlrZk=NmcOCR8;ecT>q~)D4y(cw3 z8W9s6)Tx}(;rWYl6b(}|T2c$RNKXwmWqdL0m6mxu?>{4(ch=P>x|>4Qm)-8a$W1l^ z7B8|EmwSb6GO~?ffh;xYLZdcAekrg9f#Yww9HFtFH-z|~+mvb0`ltAJn4t}BsN^W4 zXf9a%VqO(oQXgQhpx0P4JcXK)e}CN|9sd)TA3jBUT{hv`XdMg3%*-DvdVcVk)Z8nc zpLXL{#QZ5qoV6;1ulnEsa>?M4e)1gcNS@y=zOB!@#%*cds5zybM&He?!w;EqXefiuOG}En!2n%wTM|>=?;@Z1su2x_-grZ zQ-r=7T5CU@R=#q??fQ*5(mMZZX+^&G`%wGyp(z!vz1>goGhK?p%OzqDj!^SZc*C7# z6BK;6{Z2CbI~_?;<^ys)Kgf7M>uj|jn?`WI%-Ffk9_)xICrK`Mn&h}4jiSO;m zV}L-{W4~%rN(_@x>a%3~Pa&eMzH(j1dPpX-lYf0%gkXJ$ZcT219o4&tYV_>O0uk76 z@Jd-mrKoTUbBG~rjC|t}>N!5T&k@z*Mx!_INf(VWy~JpmLOD3zU*h*xg8*@2eu2bA zv%j|Y8*W51hmN0p3Tv9>@&>zXDq?QbKR)8t*f0K+UNa5LQV^X>41R};Aksz~C7}<0 znu!VbD&;WH`@y3#N6sP!Gl}pW=h30{H}djJ_KfsV!DBsq$rl4Qqm_M|VUA`smX8Yp zC}JOdDD$LlIhtkl>Mot&h8-O^GN=w zG-WsZ$pIL42!dJyDD&~kk7ezqo1PSy!P{DnsGG+{iwH3&je7sa9^zb8@UUz<^l99y z>D~~trgTaVyUxaRTv{&vCb!(C;k&JKk2h1sZ{87mPra29*=(KJXU6Sd3MFYD@V+2i zB@89_UN_S5ZKCeY%^21+-Q#4+pGDzj`y%lwC;|dO3Y0(DZw$eSQn;6ElaAiIw`7*l z4kl#;K7x>J3p$JG<9!Rd4GxCojdqwd%sVr7S)T7L41R#U<=e$a{@0wFf3r6bCKU3c zw@&40x8QN;pqyeWIj5&plYmx1%RNnbZOp^7`qIwF(=!%$j-H{azugQkttEDjO$44z z!q|1Nvnvf6hUK*RNa<(SSKkSkxDJPqY5qr>i6aUgS-hJ6dFW+Z^ z^|;O<0hi*Zmu%=NWzsi__Y!N$X~n%foO^RRIi5p({x$Yr%3kG?FBuG=J{N(LQ^VPZ zYp!pcbo)IMEz{>B5`wCSs0Md2E1jFNLflPsAhU2(6z87C<1Yt1sHl%e6&ZXzUw zyT0Fc`N|zpBgF!fe7@(GmauCWw-ksBa)s|iccQ%L?Vt3Dvlz{ZgLsb7ZB^1)mwlQ2 z!vgM_+J)HI-DD~rYVeVvRn2~n`dc^kk*#sIS(9I_JjUY3~X zcxhzqw8g=YFAvR%vk2tYHzZaxD>*2$^h?$Zg}z1my!(o$RmpGS z2_vf&W2i(@nwTdqeaM488!^_jLpr)< zsECthCo8Y0Os@Ae?YnHKz{rGNc{8M<*KCpVj+@~r?_K)mj`YaSrzf^*RoA_V=xa^e|TktjSl_W z{blpryh_q@MM^UfSlq}25BsM8)3wav+~8@;LV`yXR4(#yUwWyXulc#ek6EC+w1)R* z3g0(zNxAu1i-%;3f_15nTg3+cNVMTDXdhQNZ4mw;j0&}xj)*Gb_{#oWE~)7?c1lLb z+oN#D^4`mdkp87hM(E4QjZo361)g4LodjeKBfOj(Ux=ZJqrWslCM(HbIXg@*-B%}Y z@tkhUGm|Zgz}9L4%drh7E#x&IsO?IJjWt1P-rvkOcYj28jG|6`2r?R>Ixi13`LlU0vbvAXM)f#^>7$Zpm?F&{W#0c z(jg@}{7rh*twR`VrbB!AvZDBKou1&7q5N<6>RL+?IBBwSyY8>}q@+pZouSGz5}Vw| zm@uIQulWiSrlF=sA&s=oMHggJ%Lf;GM^C5xBeFwm`u~N#uL)%1tk)~DF&Vt`kJ`w$ zy@`C!Nv^9hyv?y?Rxv`t#ZcGr!(YgDjZ*`cwc1}`*jEkR{U5?@v{N}GEkNSGw#C{b z0`RE){xpuCzPzc4Mh0za;Tc&3OS;qP<**Vim-M5r%Y4Kft*~%*7Z$jXCaUz}AC|+V zUI7hdW3d5u(`*QBpLqQ3KzrZ&TDhl-4S$@BEe3vfYArdVu&+KLAsC&YHze6n!Fs0` zQTIu?L5N{w^F){+IPP;zaW3JJn&3iNO*_rFjzM`+zIlSNq#*+fZhjP;9`R6)aGT^C zLa^sM;Hvb@wcwP_EkHf8Nzq98x!!1u3cWTYw{QxDtCb?ZU@1GWm~nW1TV$BTLR2+H zF8KF;ejW#HUQsUjvQ1abc#&p+6vw8x*v%c$ERDXCEMr|IY?UUgT-B~Dq)$4KLBKFA zI_Op8d-nz{`M+M2MD+~9PZ2#Kp03`gos+o_fymz!Iv2q~V?L{V5#r5@L3ZP9Q71zo zn;_+@?=+=+@*=DM&S7F9>!Pl>r|HbMe~@WROE^xKa+$qb{`9OY|FU{-Q&)TYIoVB2 z%Q32tWOJHk?M?>(|C}(vB<(cmytv3B3Vxv+Mk6TaDsCg#pVWPqP0;uKZOAScd1B{> z+8q%%0+Fb}D=%ansC|~~skJk8Wk`mvC74pP?l;mRbL%zQBPfk}c$-hDB3dO6)ZrZ-7x>%}Tgl~$DL!3bB{7T_>^2$PvE zl}JcBF%;l&6L+yjV5+M8DB7Uh%6`&3&kQ+9-7q}%6fwShhVT=2ATW%xY;`nWXg7E) zbuiLVe?g~oNXmgH^k6iBmfK(e#y^c+el2gk&RTY(p!VGrN=~Hsx8@VRkNl{fH;o6^ zscU@T0B%PujZ21>0LS_KkJlR`q8221Yk^oqU>uV|Ndn<4$!P{K||90ceML?k? zgBIe>IqoX)hW71gM-SP_*c&=1=P#MFz`d|6V6TTZQja+e?wheV!5y^83f-v1VhLG_QOveX4Kw z?Ud-S2O$eZ3*8$JHU#YoRYp3&J8#Xe#k^dW??-QzG3%*&p;4kc>Y&vdG<7GW<1|5d z6_%$g|CSm^LQ;F7kvz^e*KR_6_E@Lt<4>)uEaaWn3wp(zcB@?LZfyJ!bz%sbhDPBb z`czt<-LDQ0G}G`Vvay`!Ea!+i50epdUYcl&14pcjPx{%!Dqf`&PDs(dtMvHJ9Qoeb z{r<~{vg!xyj~*xHV{R=y`id7}>@HQin}!AEr3B3te?}@EaBgD-#PRC%;SV>Anoc+K zxZO|CZK;L?He8RS1~HdMN$4KiOj~CRbf1b|!FLZ~Kn({D&~1 z8<$;=oqQyj(&tEpZDYxuN=6)Kt$UkeIGQ(avwtL+miLwn#Y%HgY%K@nIXEcYcOfFp z0M+&Rsq!p_Z?%89ZZ5WeW=zu@>sQnt(g`xYjdqMmgC_s>xb7rPW|L2Ll{g4 z*;il5BD@}mU>R7w-xZd?38j{5u`S~c2{k=DTe=}I#~`{{zHdHG;Pn;6L=(&|Ah1kvv588Nvk^iq*8&q}ol;tUUR{9I94)fV@>t}Qji8s)VrI$tC8bWk z25)DVUdq)5JMBAksR9DMD{u1^{#B9~+ywqVCR2aMa(<}7PngZ9Sxc2i{^lU+7X7!F zm;7l5`gDCsy=*Q81umHt6lNv302G0Tz@^`h7UR7h{xb;*PaYCpefmXzoKrj~v#+Lq z2OTl79-!;b>;pQ&v*`RyM59#mVCUxf$Y(TJ=P>AVYQNx!javLi1%t+AuQ~c}gm<-A zv{lv1hFSBTbF>f3#74h5`}S5--KLWcYcS+p=ao*lGe5?;>!_{_4L||yoH(75h#yaKi~uJa(>}J3j_I+&i2T&&f zbAsv<%k4_;UxxED6F}luz!zOOw8yqiRVXQQby)Iu^h&wa zf^_M|@~czmjYlRShTJ*WOHG)bp9Q#ba_rFD-yR;1B72L>@JOwp_oqmQb$khRB@@d7 z*`3Cv(}sB7M*5o7meO&};s-7?(YK_>0jvU4zo_p5-R(bL9<)SpnYJc$*KuyuIi5$C zsxTFx{Zl+tmBPokdMUwk$8hpz7*oz|XSvFy{nPy61GQJ`g&Hz)atq!Ed384AWo9)F zzwU;%l=+;_-TZ%fMy8T;5*E30z)z^)7wamebxv#o1HM4>)`q8zy`jeCMWDOE6faj`{d*sCXLNAg~<$|T` zZ}w5R-9-Cz`D2Aw=_$3}jt74)>SKOsjGvn=SafcJh1S+c+27=sa`v&bkD}n=5XCmi zj(qo6c9nGAc$)u_jnVJVm&lK$G7c5bPjKsdW2%FO&xkzyA`2nZ!e18TY6WQpK6|Y^ zJi?^VyU1admnl8E(Sm`P8TXv@kyG;i+B}y$N!g{0D$a_+w$oW&$n5}%ESTgD7@tGg z)DnyL6CGpcGO|^o8SF^jd0vXMwl8R}w0sn*(*^0u=Is%WruVN>>=#4tZ7G)8Z^NiY zE_)Rh1v+mkoc-i3^DQ(oOeqAg*JN(`D?+L&pFqqH~m}BI`-x>M`T-e zM%k%VI(ublctCG=tS3#Pf?&PpJv={B5&?*%2;!m82vg%>Vh^nUHnaX!?8@;qA^L2E|r%_ z%Ll0quoMFO1uIWqhe@>nI#&1M!$Fq35rrE5?m5YVDX=j}5FFemc0>#I_2j8&4dd>Y zBbOEBq7ErN+j$6*krG@rgWsvEgezVx9d#c2xNh$Z zWtQFmM$;%RW!7D%%x##m*1U*Ycv^2zBArG?pqJvtm&su}MyJhHQ&#V85f)c8SW#o& zRe5BzYuzW4=xzlOA0+CgL?N8>%U%0|ybGNzZO9^dG@)h~_pQEO3D9c`Qd1os$p>iC zqlS1%MaRkMS<`##?g+pG`No@C`|>vD$6Hs$N8S3QAtD=IZA*<*DS?D@X|*{KXSWXc zQVUZL7QT-*UZU5J!~PS=Sk>PY4)=qD_XbGi>KjHppn+A3PQU7?DoFP{rEy=HxY-!$ z69!vXPfip3Fxp0!KYJYvDZLwWNVQbj3(c)>J(J+jJr5?AVnqOAZ(fg3Xh8c*3dICL z-{00_R`X~7{_Oih4fJChvqXtgHM}D9qzX4BUL>w%wH-UDTBUBicH8mFz5vxshF7!F ze^V*+bhn#Z2_)ZijPhKL+t_krNOSxd&Y6vZzxESbXBU%M+=4i=ZLL#flrG;_TaMQ4 zc1~WzUZzK?gz;VWwBj#w`N4(v6ZiS{P_e;`I@JTbEnp)6Xj~veNL8`kT+F#^s?4Q6 zcd?+*Cc=1xfeLVFyxxXOQ&EN@^w({YBV3&0-z=NP_XhFgQ*=WFsjw>Yf7eFcJe@XA z-MrXTS4rQxfsh+HQaF^yk;;z~8rHOk4@#hxh2!9oZxd!Q%x|~0$ai9oAzaMl)?f7d z{EsyT)@o;prh+^FM`GkxCjV9dXby15s;aB6QAY=Repf%qhKikF5X*CTK?4O!nIpfd zUizw@XRB86S6c@B%*$RbSOmOr0$FCK3%9Piim`odYA?Thr%2alGsU&sC}H5b;rnfn ziGZhFnKl?Log&UXR*qdOblK6J>i;6X!9^q#uDd2-hfNDcRgb}^kQBF1p9qZ%4S6Rd zRaOlJcK$7`+#mTo>^LTl&Y#&AQ=D7);?Y%IcDaK=IUQKq`bne!(~;0%=J0!jB4zEG zaALNxG+Kf*Q6E0WfIev6fdOS?q6eDWsA>W*3J;e%vbN!HfR$pFqFvYpG%<<@07v{_ zk%8jUMVlM3A@r}!s0t9iRPSEh|M*IWfeNUGt?pZRNKpCqHp}$B7ZSV&0Ded|xLJ+O zLou7Og33pp6ZcO}XwxgIv}?ydhrftw2tMn{#L!gtPkhBxq(hkowHaqR)QWpQ$D*0m z3NwKTWK?1wF9bFa8V%Nu!pEF^4;juWt8-Nwj6M~Yl#n*(fQJ+)#!pn6w%GyLI`s za+$R&EjiCT@ZIJUT+h<#LlO4(PK;afK8SE!U{AW=>CZNLRH<8^I<&LZJepMfOOCoo zo}lz!Q1H$Ly=FutWv$n;_s_54-|?hFbo!4ZYNqX#%T@q64@vY~av$PE5->r}skHy% zWkdLNaIOLnwwZ7Bw7v1F@bVkld&>JC&_95o2&kq=Qn%kx3w-Aap3BOZztrY4d36SF zKz#wOspr5bF6T<1Leh`M!Q_0JKczOgYsza!q_WU!jO7^})N}xU#X7AGd8lT#AQbPO zt;~C<3>wr- z$7=eN&Q%^-3I^_M$%u(_v+MKY$vm241N~i71m<5RL{!f2N|+qqbuSk)VGq)mRwqUr-^Df`GjTCSl`2U|etWq#67UVI}r^ z-OBRz20Cf6c;aK}&x^I*oZ~j}^?%67PJnL*DR-mO!VWN#I9-J-qLchx;XT=2 zzA0hfP21g{#yy(|>1}MSUyPw~JKU@{5Z3tZu&cRAy|dukF#+c^hxi|9q!r)Y-t7K8*{F9}kw79q0pnjT<=~S9pjZMw7o=-KNp8?*FdBc2 zjIfXP{CeEzG@l{V_TRekWCyan%xb4P@Tl7V>GaKEjN;&9*9W1i5#ocpl`$a_Aw1WF zMDK%SbESx&n3SN|DYyMq|2iYQj$1Oc=r{jA88ex8cX#OE<|FXUdQKPl|hM zypAKkxph6W^2u%SewZjug&;aiUD993#TA=$pLP^X=GhfJZcj#1-2qz^jMS!(GXVMK zyzU|Ilmfv-jl{i3`t^tPKga(wqR}@n*qzM1dl9&b{v@xdkj zZ!aR(zSH;-WC=`WZdeDtKZ!$`&`YWsrkn(v)u;w}CK#j`F{}*^yr2N59|(LQzz_hY z002-4kdVk&(s_I6GI@Nvd_3OZFq5Ptv$P=w{3g8HJhukPt~Vs_ECD3e^ZpjWO1A?d z1X36FMn0TeT%<8=asL21>mb}lJR+i9TR!_Dz>8C%*;CAb(Ao6%QJDKR%ql`2X%vHI zD@&BSKDGluhe(((n5fKAy+G9i5@xIK3FGbeC;w1^#{sKaf@@w8>2*7SC5Dznt-uGn(h#W>8uTSjp$rmQQcj5%SOf=iT^TqS-9|Xx! zHSG+@)YsRy_3$A5GW(d)vU-VHxrNH)NqW-t;P&CmjF~YPqP{G`Xnt#$*@7o095e~Q z!=AT{2F6vJv@j07C&55|l}Yl>KOd;)ktj6JV_)WlJq}Zc>#5{!Yn-Hs5}k0dOQpuiBQ<9*(l8;{IfqhwO=^J54qp z%s>!<@%E~jmu}%~@$)Vflim6xmy)XzWTvmQmNZV>t~&+*!BZ>`C69i|vhTOiY1l{! zDOSsB-GLj*ccMN5j9smJ4-ijw{#~8rH(h?PPy)-wB3l3LMPVwJNXntrvxt)@Rw#Y` zz8ADcR$vrr?EFU%6yIY9Fh7RQOBcDJdiBnh32vB1^bGe}y>vCqdc?8l#+Xd%7 zC@+XG2(zB@NJ=IA{8Kq-DKtTy{V!LTo5bcB%L0kN+Xr*ii#-oHzQT?H@KBDS+(<{~ zu+hVG?_V@$AKB686gL(w9n!{vq^L2ZL*TL8fk!+OivyqY_uHW9kIDaw>LBnG*o zYU?R~p9m}wnM+l{0kj|pxvEg|PeO1|F2!<`Pi&BA^W~1mNK}#qCJ!dS>7qgf&?ZVT zUJY~=Nt|v*%^<`^N9^rZgtmC83J(Q-Co&CBU0lTTj#y$!C!n}zPvL`alrY#r7xJH< zQ`+}B4B7QH#bpgG&%jX+n$};$cn+2m&!53OtGXsO%ATZvQktr_#~TKeo{kXunOq$X z&s8%iAS?ClS3lj4&}(?T;IcQSwo+a=GuiajzEs{9)4%5prB~{y-Y7Ifd5q&uzUO3= zr;Cav*o)bXj5{Rwql;@DkRgmB$v|(r#5h_>sOUl?Q@0*!A_@PiiaqW)q60uXozgzS zwwB_@D8=-Y4KbGjbr5jS%-*u3Yov}-AxG|y_to_T3^&vqALK%yU`AAj_8$a#422pm zMge@3erogLMZC5NTzI5WeE4h-qORjwu|ehOm!L;08W>xzC_EChw12^aE=5%Mb2VHV zABiRovGFco;I5Z{H2$^53fEL0b3jBzKC@Y)PbF!~R%5<^hV>jT6h%Yyzej=3yRSlC z|1zGQH-c00q5hVSGZ0KPp@>lCtD(q19Ykt+ z_oh$$o2``w8T|i5u(mw^dQqh$+9KQMzn{cE*(FTLd|x3QrDwhI0U;l&fwPoZRWxgW z5hl| z7orEZz5Cq*{(Az)2OH9{#(K{PXUU*!eS>Pd;~%v%&v_R!D%8*Oj!UG4LEUZ#eHx4N zzyF@_yhnx>1Gn-ld!g<6I#)v?sAJ^J@w>=qYj3Vv>acboG-&iDZ_EMZIYy>H5R+us z>#0yjo(WW9@N&SHZ7dbuw$bzDNzna;$Y@2)3?#0s)%GnH>9Pl{YxN$D)+6SIWXn-^ zpvWQ^pnN!Jh5jqvdbeND)*Z2ArI2sHL^h*ZfwIU6 z#bLGwEB${idK{r}v7&OJ_mDBTy4amx4tx%o7)M7mYPdhP*MY~x&pjMmawbPkoTd== zhQL`;5EL+^!Q5dY3RuAgU1QeL$jIt#Y%WQN*P)JHxAy@H=ajhE@nO{^?+cSHfpqak z6`l)XKc}vDxQDQ}z%4k$<^xK*bTkZl|kJPhfK zr}TOO3UZ)PfF2sRECaU)JIuNm+`e&T87ns)x+P?{(dc2h>`bgvw%-0dtoL);iWuD; z#DO;bS{wrf4!7S9A$%Ctxe0X=&tKELZ~n9-y@A`uV})1Eb4lON?HWh<7IC!Xxi|F; zFI37Z3&6=i=Io&=|KzCZ$HAX$GJ+u)_u}LBJ9rfA32QWRKVoP6$D^Pt#Ux@nQd;bv(Ll7|%O;r4C>kgDL%WOMGV6a|a}?=TkZw<9&S* z{oXIB2u1wP*+6xI)A3RIFf(IOk^6o%K?tJbJ`7}?weG)mrI&LrsJv1baNNm48E{ZQ zocmFcLEFPqs9sX{v$q|<+CftGGVmnkO(C$1aXbD4mQzrN_k_{<0ACd4AmB#Vuy9z| zvA)`}gCBj1C1-rc=EJrf*k>J2juibloZSSPU@7fEL+K_36OJ8!RGMfE0Pw-DHpQF3 z|9`m>z>l;C0{LMRN;wAT0HpZFH@J2KvL)ZT-}nkT99nm~N|k zL?5k<-3ft{amEu!wlr*TL9p7gND{n`le6;#P>sk;W+Ycq13sEtg0wi>+hYgHHw4^@ z!*WDn#_2f&=V^abQSg9ajr=I!CpY~&+MBL8=a)R=uXkDy1f~DC^GLcn@N1E{9*G75A%4~j_bor}Qf{Xbg)oFuZ1N#=sqJ6G-){R`AxZ`y2Ir8(I4D%Hg z74`lI=j&ORgu>a`86!$7$a;YJ8qy8%KQoA%Z=mo8N(=vGkbfd2U$u|1KkeJI7VY9l za1Y4+xRdy>y%R312cMHmI}Fl1(%5De@SwF?VT$i4{4bCxh2^y)4HUpPgg`PMlat#4 zU4z{00ObNu2s{J$G^AyaHbunw2kwCP)n*;#FCO_#olSrQDkuml@#p=+v4!PJ!B)Qu zb|8u_{BpoJL?*>%kS(%S??b=k3NT`doXYpJQJTfa$Gv3U&7BW_QxwM91O-mt34c>-<0q{VB zg?_yCa$zd6amj__?d*z8^^&X|mL$rLTZy`|4w8BM8~*n;MvcG$0Tg|ZEzqeZYEr=gr^Gg9_XRpM@wH}Rw+D(qIM+DM$3;8@^;;O2uXTchE5UARW zQqa18JSp)wxM%U4qeQkwG)FyYVhIZ!uTKPH%}^>gZ^e8ne`So7DBR}D8&D$yQb>=T zOayYu1Po_%fFJ{ge?T*Xq;H@ZY(~i$RGR=Cx;)bOrDKcJ<%>~O+GZ18FVEGkM)~5( zOJMx~1d3k8^kxZ2vB95%q_3W}dI6l2v2}CfeZM`s0k$=e-1h%M6aT1KvXG#GzJ3aV zS~bUJ$sg+SFF@}2eii!}WB#YvpRhr*vjtiy{K40yzWq z*&RjWQNOUCd8hmf+7CugVdzHRoP3=uCOA~Dw&yh`Lay{7lJ78yKn}8i)g1OU0cBSg z5QRZ^0WStn)8Fx5xuHWUbLW<=$H@8(7|)cWjkL07pcg^EjRVKPoy~z{&(qBTCSnhQ zi~KcVe4_ouv-W!52DdYFni(PG8mZBNVQn+FvErPa(Y*nxtJv+Cwd5p8+x;KA_lXVKhXf41=Km1 zyCOO2r=i2}0o<42&Rp5e&YH;E$K z#^}wPlII51=J9;t5|Q*``^zH?C^k5ue<}+`VW{W-nQ?d-nVA)nvZ{~$|J6#f9f~+$ z$0qA_y>hb#84H4YQuz4Ydn{H1I~?SA15$Y=oddi3NpSkp_Z<#AL>QHa+qb;BdMVTkEvT9da&LXrV zLtB(0O40jY0UGJw1TmnpvK)0ugZt0Iu}~4s$3G9XO<{((Vu%_7R~h$!SbChK3C$C; zt-rGl4h}B^;OAuqJHX(mU~6VS03<`@#CSe-=U=zT3M9yIiY`K z=nwq(Kl{OC&3!GJSxIiI+r_+K)#D0aE+i{HuHVhy^o7Vj#Zu|WQ=}#S>KBaeDP#WC z6=tkA4iDQSEQXhPQ*t|vYDCT?`Ci{+F>FtTt*Ddu8^6w?v{VZ%2J`~@^drn8a66GpNU4ZW*WgmD*Eh_B4!!YE zxbe#DkzL!Ts9uz@yO26UGn??7J%_NNZVZZW9<0rBqwRO=eKJH=3#xs;W4|ZC7xVQc$V4hqriRA@l zkRo#t)g(2%ZP*eQeC#xg`hr+^4#B>%!J`7X!A7XuHe7wh#0kxFuk{=CAc}Y)%=^9# z2XcG*t?H13fRcjR{#vo8Q+GOKZE#jAkdx%7B+4!J3e`i%kpOH-$4t)^$$!qwq5SJI zlU8GfeL&wG^B`Fe10wp4SRxXFdm9U<3;jdz!d{{?gtR(n$ zrgULf^FJkKW<_+A9O2-3Ro59usIx3;jQWa1F3UD1onb+QXyO(>7-+A}>d_TYb;Bm!ypZ7VhbleQy zBxHaMC$RqWj<+pk0Xw8%W4fZ619mN+=I3FQ=fnqGr%TSYi-O^|C2BTy2B%4vDUlue?fGaYC6o4W=|@~ge(BS%UL^J8hRC2xtK)x!_8Q6@#*0( zE0k~&aZU72QlKeX5omdnP!e^h9S1CF8rQ2nptN|d@%1UHRoJ|)=RqV@hj+$~ZzH~? z3`+sFY<6fBJ**Wfuu)Cei{`{gnwdJq3M?&95Zs9}B~Yw4XZwf%bU`Qnu=57BJ=eLZ zo%1K_-V1WL$dY=LA0E{;F!}dxp)AJ@rT@e|aF}vLo{RjRSAZa~3Ul5Mc{pu{ukk

)=`h?rjL3=l%UOMuB6lf-Oc0Yp--par*x)CD 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缜v83*^@wT5R5v{ep~mne-KMZHi}Xo7~lS4J7;@%LvaSglcJ z-~>MjLTWr(1xe-`BnOSrFj#q)ZICHYxuU1u-JX3`>hX-3GQTO>AhI&$8c;P(-XrS%En-n5+Jt#RS6_UTtOm!H5ajWaUnwdAE_9Q9hhaKXTz7&vZXE9$!_f zHTtMc7_3>lgT#u-UXJEF`pNG~E(9BIBJ!9~2W8z+wiNgXc(&SAArP~Vk56^m0@<*L z;ahbq_K))D!@K;)gtPWu96Dme)d{VY$37!9sZdpG2WWHTz zks5efGJsP|2*Bk%hlEULZT;kNdFtP@9r7Jfq%xh>zwdTSsis#(hcKG!JiU%(;fGRZ zZd`=UO$lO;%a)J6ggvp@UEcD8PZV?m6~Scrj+S4?xo$;yu2OI1+U|x1eSgIHNcucL zWpH}=$oP9e6kJ^etD5^K%g7bhz8+TrLf%f6Gttj3vP{4^D_K3PYD)izo|HAaPeNFG zkDyBQ14U9zguwM5;JPdnoa&zL0Gwp2;imMe`n&) z964=?cb`U;wnp3@ypzKCO|d`qxKURWPFkGg^D|(pf_{5~MsMRK9Vt5wh^8TU@$tns} z78w86F4}@0{z=me$giK~bOzgrU1m&m_hx4?$1BynI35_EuYiCupu5`$=7^O6XNc11 zp8OzoU{Kaw@iGB|?tV=;CqNwE^BN?am|2cCt$E%KlXtB~ECEM4$HxIrgy{nlcoJ|> zK$73Kf@ zHvK-uj_9rGy)O?Yu6|L|8NMm|OE#)QBiAWmk4-W2th1ZH8;q_0DV?3{l(jiTEB?4# zWhIoZbqLS5k^h8gUf&oG$Xc#=vSR&frG`^l3PTOjp{IXTuJ6OFkquJ2;qiw>#lKtv z69&N?79IuApXo3~(iWWZcDTvq+Tz+z|pb5rjI(3k^0clSIPyz3F-1Vm4HbY8XB0l- zy*{0`;om#x|0%aTMZEPVDHsuH4?im0;qNlnc?wJHdv1Pzg3fSEBrO$r)+qwZJIz=` zn*(rEuWy5kq=JM&tDD(t9XBd>d$1_0adqtBHzMd z^fO%n^AVBT`tdLAGvGmAJ%DeTqNASef0zaZ4?U}OwPT_bJCm*2EEiAU*;7wf$D~AM z0^KAe^-BhJH_hHI=&#zdCBK?s=elWim2If)n{Ja!kh*&GK*t|3hAJQ=Az4# zsjIOdus8H3yUo)B0~9womEVOJ6c7KoySOOk(lovQTY2gs;&?e-Y+6SJs5?}A6$+bH z2noP=m6c`}2jrBqQzvrV1PS3$s|8%a1@dsLR|L^S$R@_9}(`A<95s4RmG1AZdtT$QnmUdO?Oe{#n>AU6CSrz*jE3A=x zaKtRrK?#b2<1sOa4u|R*XA=h%m0F5pJ>d_coBYj37VFh6$r_*P&e}L}H(`4y9UO8G z?@z=WlPvC;@Jn@gIv|6`%f+?M^;{41|-SVBpi<$&p6E88q!6|U0}IUKSw zUK%TrC%JJ{;y3yD>uWJo9Ncm;hS$y29mv9qJIar}x}{^y1XyB8%7WN>!7thy`rB;W zh*1X#kEc_h+SYE;c*P{kslqjdf>w{itL(m`&Hc9Qyr=%a;Y@afXfid%0jDcNk-V&M zeld3atmmgTu^lIC0aq4N7Cw=OD}IeOFEc}w>h6yqkHouf^W0m4?zZYWc*yw{a6tx` zs{yb7`;G(NH?$g7a_6Q5Hkl;KQop?c%po&dl~B&5<<+jrVZM?H4HxZ^NJ(3%x2?5F zR2c>Xb<%)H(=nj?I?TUNY5-OxHW%^);AWj`B0h%95AUzj9(U;sVaU!2FuGPGcwq}9n6yMfFD`}0f3(G z&>6rNi_W_On7+y;RM4T`=EcX8R;@D*D*}{zE6|76F~PV#R>w}oDf^=Gz4N+0^Cs2+ zS!TLqyEs1owiREj45PiELl;m1EuGwlk7c7?>kD>T;lh%r<(I>ev`nf#kM6hS8~EJG z+qFMe!CCsr)YfEEwWhGw#o0rNP2U<)e9`)2 zab}+JJ9cgC&&w}5>meiR)+pkDz5%p3Br_!K?jKLjw3>K*ANZb)z_N2muq##mm8Gk= zz#M|)=d-4yzS?JdUej;%!LZoTu=v4w;^p=lg@@>)i?a3v3!sSVkM=OW&a3Rjx3x0f zDN-!-F`ZyiT|i=V_VXKt6e-iGnPn*n{PIKiHkxvEj(VK2TyX|wbJ23qk#w#W-dnW! zvgau!t--3Hk4A{fg2?oasiriYN)_T-21R#p+jnI{pU_b|&FehI=NTCXQve5Y;B1-5 z=y*QjH|5S9?*-0kvd#yJYCfmPa5eR-F-6(sz@_^SgVFb3hda87>>(D<#zAkSbEj@_ zt*Gj_1p)>&g?Rw^EfNgK%YYnZ_1m$kqY{ID<%QV5M%c`yMFwHUmT~nzHL4Jz?2?px z`1&HAlYuaNBRr|Jy7QNI8KsH|e&#)g&M*@X!%J5Hph$5qGMyd+)|h5Wq4afhQd&qm!Z$K=92$@@ko<H@P(X zNYtvoYC3%()4yY@A1_)$Wnu^=or3v;ge{)7a&3iyr!v4(T;b3BfX3xSj?1+P zDv;^iT}@E3Hsjif$JpJKAdaD>p!C)hsqi$=TWq(4uZ;$2?;b?#HzY0_v_g+fhrpqk<7Id;N-owirK1m!VY^?v#I?RJCMwQfRdf^T?5Yy3*TR}qURPv|}UuO-fgrtFL-%5vWq!io6Kx5{wtHs&1AY6aYi!`47yS*173 zO;~HN+Dp18zTElhpby`xIk#Ag4FTC*oUXUe2va_ug^S!-3PRbADdXTAo;(B4JryWu z3tq!fLN@9F&x(M2n2T;O34eK98*p|t??pwppb|gcO=%aAuQYYTFg_A*0*s7iZ ze5h`t^(d1bqQ-f#mKHb#DW^I?G298cf8#y)ZY>?r)H%*5pzc3RK(f+d767a7SMIjF zFW(kGdw34TzWC@UgBeED_oSHI{GiQ4vsm$Lg{g>b44rv>no4TVe3ufvizSN6iyVQZ zvh^{Is)Megm9_BC4mNnF4Sn!J+m@_)ih?wp;}8}#mK*n5BsvY;OWEa$Qw+7pE(F+} zNwU_V2UyVdInk#lFYmsO|NVq+=#}NI9O?u;LMw**T&Y!==V(#SMWQZh3mzt0hG?vc zay{+vh^N~|c&QlHpQY3AxtG%&Uqf$wm2nu7%15q@s`OQNx&STJS^t|YfJwIp=6|hE z)oGCEu41}D+Sh39`%Bp`9;}=>wbI(#ACphg3HAegCxAEVnPA_lMjQrI9G$7nrEhTV zyg0G~#>9iK@vNM?Gp7BKb%)CYe7oto(%7zZNt+ac^HzFR9UJxTk;1pO_Z$@1kT1Ox zpwVw5>%UOBJzpbw?rB$S=p(+S>&DOWmX__~lme+drFSsWPKSH|TD?Oh(vEIwq<~`AF z$R~%dp;+@?cnw5y4OJXkpMmcSIW>=Hwl~YlNTef)y}|2R-?D&jA(O69e&7g;9(=n? z>B=q0G^*dBHw8TE}l<`iVp z1m-s_Ytqy5PCD7?m(>h|y?iV!5DXlM4v^P}YG(gC;Q~5prS2xq+2)ZyTKBmO8*f_lSzh>Qn)sGE#{b7t9% z-HTdbSIpd8Uv-pa{l&6!sI?>=C(22eqkTA5e zU4^trVev27fBV>8GbJO`cXd13waI5OSVVBH!^wwP-IRQ;^WGpf$@2G|2vOphC!7~c z1ajyQmODJxApz?{)#8M-_k+HGIdc?8`Mm+f zrD}wpq?^LtLwM2)e#(cmGe= zqD|=uNPHLm-W~|PXnMo~ic|atGk2Cn4!s%?s^*+1v6pz8S>b8u?ZOAl!zb>I$nQHv z8FH-AUHYK>&DUlL-tlxfbBOzF0tRQpgsUzru9_iTB|pd+m7f9X+N!ES#>B~_cOp@} zrCIeoomE1YoLg#oU!T8WF1meu418Q736Ry6PuhW=t*2)=I1Xf_WUiIhIm6edT8$K1 z-Z7syEuUWy*jh`NA~AD>dsmc_1+7 z4c0nStkV0sWx1|{P2Y$-urny2qW3|w%UDW)OY_a{LR#-&{gdQx!s@^>k6}w8kFA4 zTl^J$=<|4!4^EXv5;lx3_eK?@rz>J#@BjWsu^?y&8 z)MLw;gRo^f`u3JDD{aN0N|IJk>KG~XyL=3&-Rx1@9iA&`UBXX83YN4+C>J^%jKafi`sI zonM>`pXBD5u5|K35r5%#gfU&XVkf)Hl)8oEu~nMLk#>w7yZ5_)TR7!clC8}#wwZIE zGgruoC=07?bIG2?0Ck>u%8!Q!O!jy4`?z=%9O(%;FJ&#HI*qEMVcp^pc3hDhd)p`X zietg`nMz|Uu{t+K8kbDtdpP?@+Kr*4Q59sNn4D)-0VnNHFZyB+bBIWVTJ5<3gsIx( z-{;bj2ID6%MfSwl-N-&RAz(}U{Cw;S8ZHqzk2vYp1qFO8zED@V%6g+bs@#iQ7LsOi zYra-d@<2RPrYveF)+^AZd(0)qOceE)>GsPRrw&N9wYuzX16opd95a*FlRCAMKq-?)5n&x3CMlnw;vk#jnZO8^o3)hMQ6isz&Dz z#lNi(He9`{=(<#J=B<_5nq{V|A9umK%x{+E+|=7B4w+4H48+gNrQlK?5qHa<4^;i? z@n8FM*y*loiJzCeHQxvuKOo<$b&Pmv!;Vh=FH>Ux^OAVzDq4(9pTVfNhaewm+?f6fWb>Yyhz3vffC~L)5+M(xHolJ8zqdBYlZb!>Z|1LOJbP<@YsnNOEFXY!!;YDE+7%r->i)qb32_GEMt7ValWf09vprZ)2+CYi98?Kt%&u2ew^lr8vS z@J0Qx`0&>T!}97?wg%lu1|pf<;a@N*yx8H-u>iQH&`jqbeS9X2TvhUqC7UXK5_Ud& zta8&jj6vj%y=?KzTYr4;D>az&B?Q+3Jwg7bexlGAV%%fSs&mlGl?daP1P zU9$pt5DInca+#$~I49QWN-b)u^xN=QR&yNYf#dVc1BrZaNnvOP>zPn(f z)r!|n_skVWM;#<-RWv(*9 zHnIn`(QKO!N6=!_t?@!pLxMrB?e@zv_a`Aw6$WAlWFUg$ja+lfi^_1F9)VC6I{c;Q zbCKil5U>OJcOv(V%?X-dR4lwhPx1CI+0Ncjc%VMKd0XY$&@Uz&2Rkgf2{b)7d$@hL z3~3QNV>|^EC%#%%KAZn|N`dNQt?PvX_3G7XX&0bV36 zTf(WXM{JddeVN+mQd6=E+UO@KZlMy7iS(wZtvvd?kPa0 zbEMYAS3x?g&~sIAOXohbioO9wN_$6mVXUmkOLBt*9^R@HFzGxp<9v%Z{VtybbzRCK zJYM_O$ec59bA0@6bHAIo%u~4KKEmD`{qB`%s)RPWy6M<1$F0d}K#UGG22Rh>GShn* zLiISgem}6(Zb3u5h`>(=rs)Ivp3Rlq;leJ;m*W{*iv7mBN$b>$*1`_Y_i<(pUI>7L zdR?1aHGnayB1^%I5bgSIpzi*wybo#P&?^_9%9q@K&A8hH5yorbo zY=}YDnsJnimd4i#=JuD1{LwYqG#MMT0Bc;ty~kfB=j9_Kq3DIKsFKxsee?f$?q45kWU=g)JHy z+P^*%IvO0mSygaVK~kLb2>42LptU?>1Hm<+J{-vt$JtMz{&sAch*`&aZ75jLeUv`hIX_y|$8>ZtCAl=2vUe4V&_QcCAIA=fbLA9&~pysl9+ za?@aj#bHhqY7W$;S#vs*HToZR0d=dY-LX0B*G`#2pGD=H<0sn|g0po4d`LIW2Gt%a zC?^vI$ZsY}TK$rEuSFCc<2MjD==z#it3(EVPNrwjvXw2562p5|WEbo2qds3tH{>3D zrgsYXk9RguYdHOiW21Y;Fvn%mN&aRU&&LWeDY=ghQ9_!OrFI1D^>%E#S*!U?>7-(P zZ&XP5@ShLAbl)~(2tM z&-c_m?19hyZtDhtYq=Q&hgHX~KeifSuENTEbdVlHfyz}Ld>igEAP?bRTJGDK3(t?h zw9nW^btt9I%`(x6Cx!$(c6#U&#PVrK6kNb7hQ%_H4fpvS>L9ka77XPuv3u+|*M!TB zy-Ym{qBN5wf9&Hp1))c2-7=?ITjy*}CKpLaaTBRXOdBfwg(}yoKJ{C0X@`DO7mbo&St_?p;_4v&>HVP>{ilFWemnaxP$Gzd4sFnO! zxwTkC*FJ8b{<-f6+|7m4&92Of1Uh7WQz|cPhPm>9Fznbam1IKqnYkx?~Q}A72)*A z28>A@y-EtYGm=aPK5f4!X^OR{s_=$6Z}7>4j=kEj7>>yoDtEWMi-n1VD(XHoJGkbt(x%r(oJDA=sn^*${nAxEl0@xq5>B!ri~FrrCxG z0(g)fni_iZtlZ`AnJ<>BQ}PyT_*3?V=V2t|oQvKf# zTqMY>YBKo?j-H{K47ZM}&jd>?5Z^AXbqVD+GkE-$F#{-?sO+-BCsV+qY)`Sa?@4lLT>&ydka?Hp^=*SE zz3-D6jG6#MhIG1tBGgIgXK2V|aD7EaIdOR0N7_*W9YVXfq*zctDgKzObBwoP!E-PaOA+T(gtdQkpw%7oiTF5+yd+oVM?wJq_?NnYVg0gjoML3PbXBFZ+au|rJKLBu!f0g|ZVzo@4!D5L8ZuT)r*(dY zP7)P7GCdll3X3aZxy;W65WVi!xBM7*mTftX!TVQ`DcP$fJ(Rez7i-jGV6+f5AC_~n^MmRMDifA%@?mV zOON>|j#+KVE%q5TB6C08x#7g4mzLX?Fz-6_Y3n8LoHsK13Yau#r#PQ2I zgeW`k$kKtTMAZ!`#Wi!>i2CT|NASfmYxA?fdo`rPSwgGLL;B@_C2e7a$}7Xdwe$V% zVirD^M<5AeaFhK5D;va`iby#H9%H+`?2-aqUCDz*1qbfm5y7+3DZT%`yC1UOGyLsn zSX(eXqx2ll#c=@pWc*HZrXUz++CtyiS81YFlx4jYoe$*7`)0NDU#4tSY$rI_kjQsc z>rU#;z)W45ux@lO>=L&l@x@bbDs!+cFo7?$!>VK=e7u7Zul*sS6!RE0& z5dW3MO83hlE<0K|e8N%tQR^#e3(=H(z%Pc3{*}&rWEN|kZFBGTt&jAIE!yJQ5kd>0r9oE zj-;u>6ff7|mQgsk3+)$Fd)u1&B`asLy&91$tnexf zocJQb*6@01xbbUZrh@hPwBf=7^%cGsEwGeqeW#NNDTOy3uO^XkXd-6=tl+3}OxW&m zdtO0nIC&9e-Lp#J#c{T+99w;qurOCADf%Ix!gq{uSoBu9fA%sP4BF2GUw!q054XMU z(1rk7rmDWIN)j!&G^=lHJ*UR-BCDV=OA^fu$YIwRW+7g=!(D!bkkb_P1Qfnvf^!js zJ|Im@|BQGU0vC894E9B_{u0x&XrB!+c5|S-)iYHA#T4y$-i4K3g;MBh1uIe^{1Ec7 zot2c71KR%PiXmwg+4IO%#%~-bm*G#W(bQz@vMEeZXX5dRS-gqT^I#t5d4=gld;1g1 z%YRBk^rW@boQ1!*y%&wzfwNqQz2{}h2Vd|N-Ffl(t4QD4Wg!>dk2lM)!o4<8#<>g1VRizfVo{_GVfj`ha^z|QR4EGt{D|ln8$|X!xQDWF zp*LXqDS`>SYR~E-*>S&WxK9orjV-)CDpvQR;&vy7o?Qcx|SE8q1_1f5H zWt8LWJExoCE1XreZHJk1Nlt6*?dLJX}WheCC(yyK-lI%H_h!%-tt^! z>mDJ($p{d|sS_9=9XXw+x=rtF5PvQ{x7jf6jjzWyD1hI0b31WpSOX(s?8`p16D6@X0L0}P%QZD|%CuIRaA6G?B#2nuR?1h=!J#D!Z6mpf}B zYr_YMtb`qEr3a5rYo|Z8{Ew_RkB9Po-^ND~Wsf(?t`Zd!S<1c>h9b#2A|Zw>lQ4ry z_BFDGEXls_%TRWc?Awebdv?Y?V|gy`&-4Age$VGSf27x#xn1{lU(0zO*Kr<)($-DH zxzyM?dQ=V4z+*T{FP5sK`}w|M%i&g9?0 zF{1P1JLFYc6pe^LU0;5(pK);i`0%#fX~kgIC(E-L-67#CIN4ohazUWT0z}nUBqWlR zvetXt4ihtU67VX7qFYm&x;sUiMlNRT9?aC5*q` zo9oALu;*+pTii|*LyB~%99o8>s!Eo0(oA<3Wo21|YITM(=NX#aJ+BGnq>7n(uHX9@ zQ3>TAJ~qWuS**GKNw>je+b5Nbyjee5-uOqguVzwieIR?=0Tws%`}?9DUq?Wt`=XJv z%xwdQvB=6FHzBbi<@43Nh-~8Vb3V=vueJuO6^zmo3DX|?mIDDeJ3 z<%n?rf806yu32{1%oN%v>#?ai+mTwns)C~*X4v^s80)uz5}~eramhM zxA{Z0Q4-n)4wmj5P)t+l`O85dA_}$a9A`ZI z$aLLuyVPFHR}o(A8iv2(<}Z``pJlI|v!z{gBJt_Po#aj1Q*v8hV7H&x@Ev?pkZh0WWE%+uZ$NR>qtQSq(tF5cTE4(>c(r2FyIfyvm$C&Q*nf0 zyk{l9ywSe+BYgeZHYFN2AeYebxTs{+Y;s~{*Z3k~B_#(*uP7$#_X29NRJh65bhGIn zKt!iPy@xnZmpg~DUL)m~t%b=*S@yI227VN8W;3mjyFg2=Hw{8)^17ahO6JtY$U45T9V@(j za8z&Mno=CK_l?$??ocnZr}WoDsi$CTD7{j7jw-_mV(X{j`GFeqh%$sZ{h=APCCv4U z|1xVK|pH$J`>+A3h4K?P|z=y>tX2Ac8KD>w0v*S9xZKC4gexh_JH-P`qh9Fdk?5u+rz_its8G=lTA z9!q2vDQP+3o&M)-y#iZp$``K=^JLbXOh_Q+mp9e16h-`#Ho0ai9KK_hafYhziGK}4 zRD`%GKk&|dq_@+)WY=(+m@I@L-z?mImsivmd-1x&QViM59HueG;2;?hwg z%0_E(m`}QL;b_fEl}d9Ikb?_PuPx~_!5D*f@qQeGTlgq%szNl@CYYa=^>^W|4{KD% z$oKL5CZnEl{%+4h8~*&Pa!?gX+(F>`7LbS+8RpnFbHwbK+Ph2-u)g@hFvm!i)|q$? z(s;pvT8<6pX3Va$D*EcBxAGsWK7`d~e1ycs5_1>|Yojw3ug7!vTM~1}z<-UJt1hPC zNP1*8RxovkF(J3R2lY!D=`*aRV}U?CIK5-SxP<8M9sH-+0pGLBc|$H^9vu!dPT?ky zP^54n-nuoj%M!TXFP4*$Q7il##eYTjJ}aRTN?(q(7V>5`@g&O8X?QT%9BO!cI3=t0 z{j$>~Az!${pm(g4qb?qND>lST{H{;@3$1ujAs#!1zgFx6mRyS!9AZeJ5L!4AZI@j{ zfXuS`Evbj3|3#b8Vg5G2KDeMR01%%%`%EIFQxsymEce+?;GHR#(?>m9{IGd7B3pEj5@zke~&T3vbk(=f9l#8x%>jdAR0Wj94zC5GiS zGJ%jws9xO|YJS3QXJyJE-0rr8)L;dONnOjX7aEV6Fm=d-7E0HbeLi_PG2)E4Hi0fb zEG=TxV#HkK?NKz7CS8VcI|8tkM<_pJ=T4TJQ?4!PKK_0z^g3$jd+p(xrTx?zL(-#v zR_^C_>N@y5)KjObN^rzlzY-&Iuh6}2Tz5wH{&fv4l71;E%d?rlRVon7^k7a)Q7&fi zGN=pV=4Lp`xz?*Q%3|s3CfVfA`DOH1o2wO8C=}Xme>)W}?6=;I(^Iqaptm}=_Z7i< zdM9bY>Fd_d!B@43xjc>evYliFd6>+&v|~L-t+wmLTfPWzl*Vu|AE!90tK|=wjy3%g==BsNPuK8aSmoYqu^(n+aC3ams&V%qFPE9+Qp4}V6O8EN-igRPh| zw>mJHEkyQgkB@F6VkbrtHSHffgeoWemG{I37WvtgJ;4_M=PX+>VPu|K% zT#aWFRmRg%Tl7c7SI0l84V9GOGmabUQ4@1@K&$2nyxi9Mf?T39jrpzxcNWAYu>3^e zB6jKQANDpTe3551m(;B#YL;V-f9=HI2c~L$Tl4Y&IFcKV70hbjO-vCb>y1-n`j2^N zNhL602DZe4AS>8Pyru@~#e6pz9E>VrvFe^zM*^5FvdmVp4oY^1-UAuUtm7^u^T#48 zWPw$3tg{lyjIwfSQ55!Rg|;HL!yD#4pHIT|%z5Q*dZ4|e7u~n+Gp$c2&$>#>340F>5~xZlGN3Hs>9JxXqWQZ?Vhr>L2)c$9IyG% zvfms>`qH^i)F^whCT;!1HjY_2EqtQV&&MSF`K?CwW{$D>W8;1W8o*>J;iN`)ylO4HZ}Cf zJSnFPH8i%6Xs#?)rwdk-#LUjeV`r$fwvgkNn-?}(B>QYAGV+FPi1&mH~EZ8P~&%ic81jCZ`f zfrj^&r19dF5lXg1DE+SB8+(V_smQ$v7U5yD72yO{#+85+B(%0@yUZh{r++wxk$`|c ztm;dl(jhu@Qj{JjUh;;7hJ`*@7#$t`>-Nxr33&Vgo*l4Zd)WUyK!Vd?HY>Ta8PlyC zXi6h!To!~7Kd5TkgFoem!|m>9>7JKr7vWwj(-Cl4szVM4j&VriguN@c$*XqX#kXx* z!!?C8T^DeZh4cbu!!@h=#=_7MwhpVZje@e{(tX2gb65@nKi#Gh^KwvDge#|iHJxwK z2RX1}4eZkfD0i0L=`2dGxi1kJ=A`k{W_4rO)CTdm0G9s4q2jm}R@^3_3Xhsb@=;cx zoxeJdJ2N7dR`MuPm)ezJ$paMyrsWl}dxNk4q$*uvkA|BMU&(N|Se{lWzEXI;EBipy ztowy%i7~$)@$N9M%Hsfg*G(IDLjP<}Z_4!RzpYMSW%$&$qs-1ZwYZQwP7}{80nvL# zHFnYvLo!cxyCKo4+ifR|8Y=jG53SZ~UzGzR`y%~M*25u@OzJ*mPA&0{5jXr$uQq<63mX7evcUbM4i z#8kv~??4d7rXz{xZVhYI;i<5N1mlroX`#bLMAcMo5gtXolV;wLiv~O4rtRz@4qCc< z=op>D9`~)K@6Fx*d9DOty9DfERk{)-?5`Nku-ZBOEWeE`H{owtypIZg6Y4IbaY%TE zUr~ggL+>63?u2uQ`3L@bB>C*B$~oGkmB0H zg;c!5F#5~;55o1>3?1P2?So}{fO{j8oxS!Y0&K*Ew;@35#Q@&k*O5Jna6z67U>C9w z75QoXtk+#1Msu+eyxzwzW;Zpoo`@Yc7ZxZHyMBP|vXNe4d&GMMW3hSs58h2mmXQ~p zmA{4Tysw0=u2iF;t)eZFgk)09rg-^RUX9Yi?*vit>r44L1jOUqCe(&)JeFfRcV*9S zNBzb~oD}j=po4SLGUs!Wu8pZrB|twEna;>{6=w^X&RvARDJdAPsaTN~Gk=6&AMp^f zl7Hk@B9~uy({!gwR0{L!25_}9P7OE6rgshtH=8MDM+AjA3^F#J>un5&C8w=jsBjkK zpsTJu5_G>l@&G85BkIdZyI;aV^b|_6vhHZ?PlE#4>NjVbjHOm>zwxEzK^{q zZZl~?(H-8w8b>6HT-wcS=o4DzEewzbCNMarx|R{TgL5nHOf>o;Sw+}3y<5@&B5%5~ zTB|fZ>o;=XuGz!t+mW}Z4Ox4Ll?_j)hqD^1F~6QPs}>e6AX5bm$}?Rr9)DHEe)(RK zT8O9Wkq3-VU=9aPhhRyrV9rudh9Sdigfu*6D;=pmhc+)U+-3M#-( z=d__iyYgVkjK(hw-L>j1*o{RO2uS1a*S}W>E3S-#$H2BHvGIT`*Fjs zcC+s{UmtrV@{O8tFW9E2gW^PIXXpG%@sB;@$HI+jeZ6l=z8Ch@KXoLKJW^5v!$CW4 zO1w7qW91Hr6W%l7{bsH(dY*kvy$cjrg~{|Z1nzjG+_ZB-M(v2GGca;mkC_xbYs#!Tml$wOnq&BeBCVME9G85pN8q}xpo*|Jv)4?EDj-CA$?eZp*{6`9P~(d@Ag?C%sJtF|7NWr4~e zKTki-Vm%Mse0>=g3+l;aQf)nDXX*LeYVGmNbm5yY--XcjGbiA3 z42CVD{ULrVL8Hh{`5!G~_Nno%*%*A@rma&G=N{VLU!Aq<1n!+O>u{CqmA^dA^GP=Pu_i1A&=v{$6LY~ zbtB)TOJyBxt5;pdjuuFSXE3y0(pRp2^re-4<{H91+MEbIBHxe9h&XS3o92NR1#-zc zH?XB3L$&s+-z(w}3lyMwFpW30XLosbr-!VqXb`IlFV+GUg20|Mqpzbn8I3~ZM5V3K zo!i2PziBJvC-<}V*&xnzWhs>j;l&ue(WX>a@_L55Cmg%f4LOev2(5ZYyU2Dwdv24L zu1Nu8d2~43fhL|Xm{VjYEml#o^xqtB!BitUj-74 zKVL_6<*aR+O?X($$Qs2acks$XJK9UPb{c}hRkL;fDX6Klb7~66zUdosa^}_gpA;q! z^Thjeg7uXP1x-MtaZj~-v9LjJJCh`gQpd*k zE^x}>D>|p}GIxTfA)Wga6=uZnpbr<5?6SJTo`^@(FF~IwFDlcYCnFh^hT6 zKXRx0l@P2qaRMO=A+hL~zV>e+NK}ip6cvmwsnc|pf34@n;>oIoy-xX+tU;*9^0eI@muFKS@nv_76^deI-UBG>=?y zDs}69A zi|UpF-Jwhm0E$K@%UX!${gZzS-G9wUQBsz(ddCcpu9Z!&Iq}RjG%=k2*zmlZ@t>sS z8-*cslBNsiN9F=n_*Bdg*ORm{!u01B>043Ib7J8JiT&JTZ(lAs$@O>LA;`nwL4IP; zQSTyHBN925Q*@}-e4{%p)ZUt|2e{HQEr?SQkSp9jv#z9ZJ-;4%>>Qf&tiy@hoO@74 z`0h(GUx|)~+<#|+sgMmx2h7WBx6C?fRii_)hotQEOfTA68#yeb58pZ%IW}&p@yL2WEYElw_BHGWB2clq<0|ga>E?Gf5Us?oT{ZZjQ7FTCQ0yUJHcjnh zzH+p3xM$Wno+CPm{qz33GE>MHOsuHia=`Zapd2wlGrWb-1C&Zzoet-~{3jEH)d$!X zc4%}OcY-9n&wCS&Kn+Inz4SgF7(C(Ej~QDh!CGIlFJVk0VEjHsiSphuT$Iobz&weO z7)|@mrSUkPXPy>$zNv?-e{Gu|)Z^Xs)i`?Bs_^!>v-O7eSEpa0hk2B1h$`FJ7uU=l zX&~~KwBEiKK7-9Tp?*RKFUd5Bp4|C6-LG za9vu5_AI6&+}XE#z(_$}oIs9Q;QS<8`WOV8N3(>FvQ72Jv;~(P8f`WVkh~ z;yIO`ZqJ*orSl{#DvY0;CKZv5zSg*Y2%FT04Ox^;%0ZnG{fnk>f#nrTU2eXFHaWWt z-68aEsi@(3ipI2vv9x+u^S@QHBcn3ob}sSrvxVo@a=bMaF^S4tijydO3kPlPJi2mH zQ4DQr&1cL3fhcf|Qh$n;>xErVFiADKskZMad;7uXm4jlfQ}gTLMCQLJ+y~RS6I8Jy z?s{D1#jVXuSPg1$VE15gx!++VXVlcX6WB?PB>NuTlS3gOt^w(8k&6w!BWZ-^h#A8-`=uV1-#ctnKF zjEof-`$W9tB-KU8PFm!0Ydi&{WZl_c?$YvXnH?TUGhHgf{$?-|E-@J9I-oIK*f)#d zi$*W>4Zpto=w`*o;iE$l4i4LT!yj*w4lsUCLW*$OJ~lJxtNK-LIgPs9o5vJ-DT_Dt zhJksxVDS6ofEi>o%k#Ex8Y*Jw`+Gd|ux4Ov-*o4r_yS8uy$!o&==*+_v;WaLxD2r!9f@9V8+dtn zW}99AF};M(RQtCqjPP5t5jkPL-6V72WZeDoU)(S_!MLIUd!7v!U-7U5AXO`hqEt9&}V zp+D?C%aeXfI@EC>$u();7lbX^-bd|vSack)rJ~Vc*D77Vwhuyc-vbxaTO9+?0nXbf z$Cig)8CbQFL&-N8-CLYQVaQ)opHJ)libky$q~~G9^d(kN(8Ey84bPwgL6d5R!Ka)m z2fr6L1~w4X|Xqvu5pdgO;eOZme2 z^idZXci8QjpOlu2;||}m``(tkO>(hyauTZfTYnHNA}QzTdaA6S0G1 zobr2wg1{*P*$tw0kP^=@`o&_M1BKn*4i?QuJk{PKx2BL+I#=$YALhpO9`4{JSXbI` ztop6PUv%(G>$d?*p!ALxPe6T7of(g?kG5jAdiKM1x;d%uIuOWLr+Rw+Pm?cIzC3+r zu0N)2KEwL+<?BG) zjc2!k_Lu_?fmCzBht&E5h#rL8C)A02dy4~P2RertfW~%@(lzjXp4K~+5DOau z1glzz8j)LDPI=ECN0XGOC8o;2s>*mYn$XWmiD`QTk2*C=H8=w{L3Cck=L+PBO;&oI zIjm*~s|>VHweb!|)$iDm9y`3zS;BGv>UCJfQLpN|nz;&-2VyE8&-w97JlYU*V6u8u zF^Cf%qP9}b5C}HPP275WXLf6Jl=q3|8lwyGN2Fv;3H5Gyz$9TBID|kTGhZ5?EM|^K z)cB)**#BkMOkzw$;&oh~qzg$OXz*GRCO=3-4HuG1FR~{U>rWKfnX2yBZOV?orG<$7 zw_cV!-9|&xBCZu~jNjd=PyuNZ-`vgUpgE8A3Ao;A@FRU$CFUVZ768quuTr2GZKWYp z+<8$u#@nr>H8fTEf+}K(d((yQyK_GVXT=!g2=U~UN#k2)7FGNttF%@FmieX_=JGt| z^4`nLavc|7r4+4dtp2f3%44^Tmrshy^_L>Ukd?E#*$=n~acI}Fn?(J>kvAign1vHQ z@XM_=!-rJ`>M$Kc-#C?mVuxd_CKja4R9Nd)ol1zGI+cI2(HWr7h++R%ekj2%$$#eb ztBd21@rUA`%SrRSl79s+(PY;DfZE=~u|t}6Ykk;^Tg4r`#mwTDNSB|$8@UPmZ=Cl@o7v&Rk>f@;M6F@y5@AkRdp`2PL~(_gxYjpIp;gGkW?l{m~p($#a$ z7)%(0?l=aD+)}nbuK32m8&KCvPX_tA%jRScwJ^<0?b**;a&-=Syk&fCcZ?0{^L^!L zi9fyHEK|??}Vc#o$HO@nHMj7=+6cW4ea}*VROOaj1yx|0_hL~ zxxBf9`)CN}sQjUsSf7=tmQawQ>&5^Rro#d1#qFm$;B&=ZqsjG;zAj8)3^4 zw~=X~EYU@E8Ip*OJ&CSF*!n;=Yb4qHO%Hlo-bG4yIjHT9wY9f?&Dm!RJLai`o=2Hp zUCqT@Wj!=jab|xoFV2xIemDWfmB$bJS5|bhjU+BLyly%pQ1Ts*k}M(=iVjhC%X~@UjAtX=aPa)wg*wc=eU5KQUPvFNd$$!QgwK2q+e_+{T_oB5-7`qJ8G@x2&H2!jqcErRCxuMZM( z`WFO+00Q_xMkc1u_ImU5-C(Kcb+rzIuC`CL10ZmG&N_npX=7gY0|1g9id;YUgpN2K zD_9vpKqwI~V7RAqVNdKFl{ti~RA%*vpJ4byIU@hzD=UE~_g%MXj=3x1rzej-N+q$fzVftjI9~*N zhdA*-3YQICx2V-FV9xzhwcL;>oE0j#JU-m%J>rSS_@oP2uOGbXN_?VYV93^BEbAbftM;dHq0m;-44jn&>H%jY%!&V6i zE5dQRQHFTr6_$(Z5*r?WafNAIxdpdAP?NQM@2z@8m+cxy;9)$0T+&HeeKAW>C$!l!$z z(l(2CaeoW{o%}#(!@H-drlp+ssqQmW~Rf5=DNhX+uL*Q*cH$ zDW#eE2EXTDl9N@)plULEZ^yo=aTB@;lq})^3sLoP$M9aIL#Ue8{tHU?jjnH6aW+sF3kME0ORPyx9 zg@``?VmDJNk>8I8aw+YVR01O>Q;lUAlKU$ktVL{)DcpZT+Q^w`_!jpAaHaM)xI1fH zzl-3m4uwk#guo`jM~l4zVAsxLx(DuUB`UvU=P-OLwvf0SsvU z=66Df^LaQSiZnTuADUhXom%uF<&v0yFi82p#=h>+{yklJAxTHmxDOxBdz@0r3AE2z zF$QHsJUvelt?6ENi!fw^vC^NvD9fGKBV{l5)rj@ju9hp0;8fQIoyz=ONwQuQltZBy zi+?pDF3qoydkC#D%^Y9D;s%D4vg~}iw~tiZK)|-Jtr7UjG=R7k067nVG<~5a)>Jp1 zCPI%}eQb=L9zvh_M~7G~O25_b!`s{nl}a70!!Znd#CDz!t9+c72(@+~u1du*;92Mm zVUc-!k62O_09{CbGXHc05EINH*5@oW3Y^Vp&yI&EC#%G;sxaco!~K(&&C#GA{}}b$slHN?E)gc&_n}Bc+8^>eFKe)#B7W z&(@b#M2@u!kX4aoQSBcVG=&Z>i!0Oj&gF%{{T)xAtk6a-qeN1bPbxV4ej)OCZQ;WW zFIQGG3aKPVuRtJ>QT(U{o6B@veRSA^%-$c$e<^czTL)WmpQx6`BcxKZvafQ=b45gl zN78psS*@pv40X4$J}3!H%@j$i2VaL^hUIbxCaSBoOS{`t>RwyUp3^YgptoaMC5p~S zc`w~-uU}dmX&4{2kv{m_nApZWWfhj^+@&6TB`NNv{neXVyqLt&HtPraG8Pd_TDN+w z%J}!yn=DBm9m<#~kYUIL!n0-N#(7_Qo~J1uM7tX2*;)<`jt-LirsD95_?0YUXKrf| zqd4mxWAPt$w;F@?Yj7>Xr8x^!JLW}(D+JX6>)r+KESxqrjxLeT%{0`S_ctSd*DFHP z*OfAGjALUoyqpkN9!bE7#E1rb5vF`cski@t2!YHpTHHpMj!*e?udhD1Dl+(pcZ&0y z&I6?fcQh1f6gNxkQ>CI=5s**{=Ms%bcjPE*$Z6!VS^&&ax_aBJ@R3BBoW!K?WP)cG zJNZ9NKE4u^RME%BA(zWkoNnE9Oi9b?>ZZ@eTyw<|c*qsA&p~$E7Zjv>qOHe*I0%Sq zbMG)k1*>VJw_85=F{ng5`{>z4cR&tI92l-rgk4X1@p!%OeQ;)~?!Y5; z-;v5RYVjiH{8SH;W=YgcYvEPm_nsZGtmWLT%l7akYq4>onXVHIzMME^polqQ%H6~& zo~vwGKf#6<&$jQ4a+>r%9So3qeh(7pVr4e{Z*8c@pcLNp5Of1Rb;ZL`ji?jm>Tp2LTki1?>@9SUOTFS8GS?X~(qe77$8 zqIElaU-Et*$hq}S6I-UwNGS#{45r!s&S&7Z3A)k0Kg9CZ`8WR#O(vVt}!cA@H+80t8(^BLn<+3sw!h_h` zhic|uM(>6k@woJt^#u*Edzzy+z#D;L}9J1H#8nWjbyWY$r4vK{(C%*W7Q6G03Q)XDQ zY`o)+LGjMz=$JjBvi{Xam}H~4J~G>1nhNUsut!_p*ix;HJ_+81=xst#$BJIB-`)7L z;)@3E*9{u?@)t6TPA>MnO$*+_P$1>xi}oE&=KJ}7*Dm{9RefuS;J{yhx@c1|`UWso z0>eSY^7@|dAWp>KG-FDrN-KEAxMTk{um6k>fOVE>Al|$;LBXzNaQgkNDLGb)z{dn% z9{B|AVyzi=#jZq0v%jS0ffq!ASb2vi`T|dMNh=i>*Um$}y2{^edF1fN@>S1a>dLNX z8HL8Jnrb6Akqhsxl-^0YxHV5vB$&wQKx`-JovaHK2z+CQGv>wv9t z&_a@2c%m{h3<8II^&yM5^f^s$xz&eXZC5q{{EmX^{L5EW*oBfr*f$1V2lnln71Ar} z1zi$DCwwnh^g|_-R8k`loQ}5tnLRNcCyaQvU02AO_eXeukTy@K@5{!Y@?;PmezhbM zmt9=6%Wk5EMCWMg;ETVxO@(^>wk)$|WA9N%A=p1s;ytzdelh9a){-HGU3pt~VJ2K_ zk6OM-E#=1!eFL0EM!+6?n6j83$%A`9C;h00VJ-eWL(rdKPKZ1?n3)$~S1gSo5+vWo zk5BjXB8yG{-+h3RjIEsqCa;u#{%emVQ`6)ix5Bl+9fo87l!p{NM;KG{zfuX>fJqfk zb$DZzb62xRZIGS4bh_Oi{OE54v+ZYlt_J+3tYR>G?IlnM}ms#;NDs-#(Q9C z=N%QG7Hqm(?#Ycakh10e=^j|_0*u68z~qobQU=04!Lkn`{i zm3O`Oz5L;hM^r99Dd6qHtxgtopwY7RX2eVa8&65d;xk!H2{eAcfK0X~hcOvq9VJudk)$CdJmQoknWKAv&OgOmQz$VPHAPd7dlistt ztt>P8im;7HG5cpu>oHdvJ47#8x)}PN23%AjbaeyHe4V%u8JzRX64ZP?2+ZQ%a|6Q$9M2DPRvM1HEYcYv0x$*0Mb zc34rYKHv`b-v(v6f7ZO-uJU5~jH=f;fG&&wy(c{j?FKpv3hGUJ-eRF^0b2$S`@ zpK|av?kPb=9whBDTvn`*HWu7@sWJAnz&!}Wg5&%Vlb(%jS7+?8kIBqx>Eh>~j|F>+ zh{?5l=%m!!r(R-L0b%je+8V+JpbUCGuX7MbGfJ11=xXb+PmRA5_(nvPFnK%?n-qdQ zObT^mNiV)mK&C(&pZPOJc~87Ba4b#Keg%_!X`TBqU4SJvZ)zj;?VH`6qf_|a3BhA% z@#$$pC=M!kO$X$x99&#o3kzARtE=R7k9W=dnYa71VofIZN!p*SCdg9kNrQ*S0Fs`I zOy$;P#QJX0Z%P;2xwk-@HXwi1Aq2uctd>Q7Wc?6I9%|BLm<8v zz&>~BGTQaMK~P9~WOK7JBjXjC3xwe+j6n*D@NjHuDsE!J47?=@7^dl{LvXGFu6mQ4 zC>ns)kHQ?;?Do9A|K+%@!(Pxy*sS)tVWDYMkI%_AA)yDQ1`^C9NvEzF*F}b9vOA8C z^fE#tp^XcI6o>H+?*cCz@VxPVxu=+Kf>2-mkW9u6mZ!2%iK@BfiktJx;!zHto<}CK z=?9J=SXf}e06+r336LD~EI8MkR=?k{k$iC{DJhAM@1FA{t91-IA>d?ZX#nKFc4K&a zv`vb~%UHU_UkUfhvQex_0|qsFXa@nTd!4rWjLW;>z1vZ}t?v)(u9^zhn;qy)c-?mh z&jSlp3)zd%_x0EkDhSW;*6q&~RFD?wbrEkeh{C03)U$==O`x>iXr~S&+n_(JfkIc6 z_excl^yC&@jmvy6O@Q)QTD@AKp9o5XOiWC`6V#!a9@>!zA@s$?-4MR~Ca-U2XncpS zNVOY`jvAj+3KzgjqCM;Mjk6d4$9hg*> z895p57Hn%zd7QuoZ6>U{vRr=`dA6nR*D|!BE8v11ag2m{R)xTB2xNUkI4u@RUcx0p z2Np4iUhAvE&mMihThi;8N5O=sKVEZ+`<~*d$>lM}cqL5jUK$$Q&)#0;nI@z;de`7^ z@Vnd%DCQtt=JaU$-gEmChUa~$uf`0IwLPA%t-wz`JyuKF=MYX_K=mJ46m3%F*xBH< z|I(+iqT)uJu-T_{fw{>BFT!dWu+TnEPEOWIibpb5l{nbydwiGRwMd}Vc04fSTF=jm za3b}5&sU73)Uf|WQM|;hGORp+zHrv&(VNwNf30JVKp)KKd{6ll!0r94vZ~64ag&{$ z{p?YD9L~qh+xYC+%(t?_V?gO8_N`2cYERMS3D%37$desUS&!+DtSkdg>;<{84c|q3iai#Y64vDKNjarpfRow*q{eKY`+OzQ)fnK#Dc0_GfQqa35zMbrl^2gLTq|1-W4*0vKTPLx%9rsi%jjXVA)q*A!`P zJ`SG3Df;DstD5`>wgFBGB{$zh&f+&ioPqIB&qfwxUl&hG%{xY*Za2Mv}8EsnqTJh{b_e@Mq z#uj<+<`EiCMovFTyRZKuN2ktt2m@#@_H=LRB&mKY%qa#eQD?mmS_dYb%lh~OkC~vG zb8TVlw<%;;Q>BZDJ`z(Kv!8xv#nt;`(njLjr`qQmDoLJKu7JSNT88V|Cq*$UFxRJ8 z8EGIpp=3L%5J=lt@0I_G+^^KGQke;;?t|^&Y=Ad3$bz-7EX2|sAZ&5oOL231Yj{28 zk5|txdI(E8O~#}ikEMR*K8)gyYHn_3vKDT8pmxQ$5@1+ zPt11mt>JE?a`ibRIsN%;FN-JMg8DF{d-4lBZ$au3TX8k%>Di2c90RlEJj)zAG6Z;H z>+6LMj*h=4%fOD-BY#?7zxk7TQg1xpQZ%81wedjpZ1B&Wt&02WW@jiUpu-R5=mRkH zg=m6X_z6&{%G`r3)c!qvB#Ad({`v!R)dA?Q1W}v8cJv_yRxFidC|a=!YRU_~MbFv6 zZV^Mpe-ka9=nl#~FMRm1x}la4B|};*0}7hidxRpedmPT)lo#|_aXJ>N@!Bs8tbg<8 z?!TK@NMJVc9HhyRdw&-L7#UOq2*kOEVvzL1CDRkiXnFnY&JJF%nZ659KHFYc`oa7r z)byZr0PPOv647quv0k${CykkvetB913Mnk^Mozzu-)UoR3Q%a&i2P1}?(7Png>S@G zSpPc~2s4QOqe3(O_UGFP+k9vcF5JOB332>4 z7)|nRoii`+zD!B5gg%z4on7vilq;^^ZUa zcFcPH+fCpf22o{gAf(f=ee_Piqvh@YydB60w3RnCW34{{q(i{ttPB40(xAxWlT|X2 zsifik7@i}FE6fWEiB+~80f;Wh!&?r(@g~SS9y7bW2Djsgpjg2Na5SBLb$aX9fG#$S zePkX$zLTf#=q)1?-`3ra?e3o;+SiW{y-3ij=|Gx!AcitfjunkH^`X_oNx-!KH;W16 z`_Es8K%!inec&o8k9-oRZ%lOa^>I!AE;!~DuB#3F4d49*LO4Ntu)21>;PXhCW&WQp zT`Xzzc^vsSNm<7eV%q}voqzNU&u)n-%)Chb&wIii=zECo=6`4CTm1cHf4!cmA;0 z^P!na=%4qdhKU7lA*Q}{M~G2v-7ruDNU=t&_2jB5odx*Zge%|SAMl6bnaFU2|J}!t z(Q>@S9x|1tyC-^)P}dF;^Bft(5})}^CdH-WQg6ZOBOh=Pjdx&g;N$!GJM9V>4_{La z7zsd?g5eSP)lWtIG^OP&@IQ##^ZzW>lu=w36o_^GV%3zzvcCsu6)WDWM|Z9K{NdkD-6!3$+& zkf|Q8i;vCfa>!WEOR>WbpG9V8DS3jHT#xG)E*_VTjW7fR{$YOY-2bdhkCN8?X_@@i z)k7xDm|M>a+B1OLg*5HIBYO{sN#H5VgPJD?VeX-s_)x{-*lr_<wxL02<88b2+{rPi>@;<;CbWIlXve2j*mZ7Qa{{GPRuQuN5pu+A)S5j!X~;>23wsvgQqrY`>{xr< zG1jPIZs}^KC-?BZFZpW6rirrT-kxIl&v1a-gKVa^^M8+~nd_fG^_bjU5n)YbJ)3(^ znLpO=^lQ1ie$4|UspCLk0Z`jx(*C?xnx%E7H6I~wEy?7hT~-Yzd;B{)BfGVpU6oD zg-otx$ZY@o&uL599er1}4^7}X{1S&0XP@ClcSjU7|1Y>gqkPMuMzG#>G5jpwaGCG= z2P7q6-~*_m2DuVjzk%KWOU9g`&#s|O)Jmb`r!xr#35m0W{{I&%doJAou`=i@5F@&; zk4K%wjxMA<1fz%04LZ~Zg3`pR7yuaiNjxQk98+ydE0{u#=zP7&A%g$UQIEgktIJM*qY2jI|IVOO~-^DcP3_V{AqC zw2*C(@G(e2mKh@o*_Wco7EwtCk!?_xvSf`xLJC>3&NRmMT+{da$M1Q5&tG{pbI*O> z*L9Zn`$1z7&ZOH1rUi#+7%WbKVlWDw1Gc9fFq53cCi%zcZXGr09mL}qRC-pcKn4@`9- zn=cxvKjN$IXaGC|$|rw;?M>?opHroa9Ec4hoAau z<$RqF?=<^?k4$jGN9ZrIzdLJJCwHCFqwB!98l644fV^wnmrh%5@6&@@Hi>J9(YuH{!Wd8$mx9QMH4PpOV zv08bb8IU9){}$&p$NWSX^rOR63M&{wTsTmq{S5&u3+#>EzSVbmUD_UvCgKR0+m3bh~$<#4R0HI6+zkAZu6H@O{xa@%i<^_IK#QonHj|4&yc(Zp_-xa6A#XH^z#uH zTe9ZAe35I?Y(G~d#wZa4C&E$9`1JoDmI>U95#ZE9+2ulc8}JeN?w`RCe}m~_aeHN4 z{eMC?lTT28;xFasB9V^)JP#p%z4mJ}@1PNEXkMy(*veouQ1;({cg|0FeH`gt)QF(A z-sGbj%5k;I8W)>?frDNUuTqqdC@ac#QBT8JcVpI@R|27?3U168&qFPZvO%u=eXWszvTP`}P4mRf*cUXGWgY^06lB3hmvHypQNybox zZmnAXKM?1$($?V&{g99uZ*ZOkjMUivHjfPcG5@OY?v?1bbC>fDR^5f(Ey8PPt6xn$ zjGTCuUaukmy}3QN^MEx3!k>w~VytHO_Hz4G!<(4Wfm}QXc2w)?|3=h}nv9);ZPXA~ zbP;>c=C`}LZMq|zrP@Z1ZSX&O*N6&IJ1+Rf&!)@N@pZ&2mcuO%@@Q^;7&x?L7dx2@ z;gRv?P?${wlvv93+uXPQu~Cm=sAYEiRsKUen^CsgC1z1>Rm6DNhx#3}>&yD1DlEDX zN!^e}|Ib~&0lkdB zp87qwOW1z(^h4L6C*D`GJf5>a-F!!{cd!`BVc;`05oW|!#R^*oN*W)OeLfkyV$)~c zLu`#l1G>>4cR2O?D08RL$y`t$`};qDQU~zo82UNII)co;9xMcRujn_)Y4#`mPezXH zFFn}jhjut3^$S!$RDp2H*`M41*xpg}6nsuloOY&$HoC$-Fiks?_(5w7-W<@YUqhj0 zvuomuyYu<>Yepd&o{&F=b)g%D$hxGvnB?;^?39*OFvfK9B?6-7IsbpMt&$RZm3o2a zo?RcSkguN({MvWN9aJ`0^WNoz7~fG7O;CkMs$Y-$N5qF}n>uN8^%YL{!WI1r9bD>T zY$+#%NBrZ-3LU(O6?`UsT9>|$gl%Ypk=ezv$zplAXgmrak^G4L;WN%9?{8jgGGp}s zy4906{8#9Ip#YE+bBvh-#usEFx#`6XC;9>!;VlDOIO*~iA`50wyjiB*>do(bf7_=-I z;`#j_@DVrcI?nSzh0guTUk1M5Ev+bLmXD>`BGU3vyx4Q@Ea7lZ52(NQ{|1n*hDEi6 z&$2cnm+5x$9v%jn^5-OQR-eTy9vtdLIA-t{;IMW+<;CV1r=%j1)}Ix;yZ?JbLK?o$ zP<$w^uRwAJZ%>+-;K1z*C54FBzw4wo|{_~>(cVoDj6mko_F&e2RZp&!2{K=HQ0Y6Ef!OoOQp;WJJ!1JNj!?@%G7JZMRdr zGzWnKotI#7SO4y?yS8+QwiF^}l1WSr(bk&bm+~Av)2ZQd?ZHFRpg1_rv6@~UgkxN~ zJNLWfS4ZL!9lx(0w6G`}n?J~cNI&7g932?H>x;S6DF8+xEsFo-XnGyYW0d#c*2iK3 z)Z>ijY_lqHC)fY;tY5!sny!<<{1E`U&YS``S9 zreOKcA0WpYj}#-U&kGps=;xnS5r9vKQhho*B_NuJyKd+dUx;957Vv|C zBahSA4+)M^%2zHhp2$}uEpcus{tfDv7>;N4={rB}eU^)JnG_km1PlPh_-?>W8BPR(8C{s zocLQ~-N0$-;a>MNK&~RMuF++4!*2I~%npnFE&Ud&i?k-cIs;h+-ct2=`={gwC07)z6uRzWTMLEhP z!>oa2aYhxKO`^&>J_~M#y}8k+;ngA#1Z)EY#otM$%zRJ`7b~We9-b7Z;>=jssi#(2 zg<}-Kr=HBIqPG1oA^Ba7yh~0pNdM%wNy>&qiSVZ{q`_dD$)qnSR^<|C?)I8F%#Km~8zgc5*2bAh!~=RZ?( zABr{#kJ~`KB9={Z`aJ5p+2lAj96V91@<6;g+Fh}5;Un3d*v8nQ6fW5OF%t^c1M^}b zbnByjiL`2HtDCfJ9%k@xKXyvB#9DC?q=)^%jFT4T2e;u!F4VIHgg@=3{K`WsPOA9c z6I@p)V;)O5{x%#H#`Qb$Gi=Q!JhvuhfhK^Q{(gkDDCPD}$?&MFPryhb6{^r=KqtWS zfG|So7C$H@BI_b+-kK9DsZXtvBT7aUxfcZIvx4y&oxuwYDaXH^<_FW6TiRIgtC!xQ zG%gK_L`DSQ0q6Js!@IORn|2e0|tmv00t zJ?%U4sGXY7E)Oa~7YyPp1A$b?R+fPnjg`Fy542SG&~St8MI()LU64hS(Ao*8{|MN` zcurQ*gYcl7+(b9a5FY(8{XdFwY~+N1ndElXt%S33U(S}f*#`WG!E?X{>B4T?W2Laj zghE^_L?&2Mxp9WgP(CLi84mTcO6Vw^h2tRVv7n@S2hi^9bi?_`N6ON|&gPE!9%YC8 zaA=XXa8~Lu2nYE95eG_qAr2XHzx2zw&buL*SM%H%ifjFpzued1Q_$IO zceJwEvkDmKp>iZzqg-sb;WYo|5ua4o2otPB5vT>3g`OV9O9M?fdVJaDS(({LwyfN4 z!oJ?b?5h8Gd`;Uvm6_tIz%(+m#o2MCi*uTdZb0}>VM0r<9mPg_hKgtmh@S2xCG=u5 z6JSSFB1y;!|9Vrx0;|MQ6c zO#W5W*Y4Lq+JRYb^_Z09Rd5DqyYWE_j6iLoPlh9eO7AT8{@~JmNbntBx$!!jmF%^3 z`qE6BHz~LkU>LN88|Vx0Vr*a`g2QuVqv(v7l*i&u?r!dz-WC%Zgj~~KI1I%J(c5CQ2uL1fR<}lup*+bFZ2i@S~xSiyOIITHA zAg8xobFCt|qT1zt__ zrY~H`gY9ap_{&5So}Cr4AD}GHKoADl3P>I)9&3I)`@F`r>iC12L8-exo^w4+7VBpS z&{#629j$>wwm_1U{H6c9HqPD*8<+oi?lvL6xzf9mXI5nTd4h|0pVpR0elK(yufZS- z7L(bK8NIBJT_1`a&-H)DyT)?j@}5g?nZi-Mi1K7X+ zD&}t=4TpJJVv3q4_2X_EmL_+uaxKjYcyOPY6*SNnthIS+YNzTdnXhB;&h+7R-nK*F z{iMzglqkhjTA`y%?cw@+QSKkFeb{t~zSN<${NXw)sT&Onl||_K%<4<%m6&LHc4<}(N!bfV;Y@&W^GUJGsj z2@M>f9zo@Z4I12uLS}aUaISVdzVfLf?OeTl-b!eR*l>*Wi0TEj$7!T+H#OxyUL9|S zk?a;?a!q{LZfkQ3FW4IBu#5+z=i=k8`A&_l^XHhF$gI5&SSh4*Wcv5_IbAuQucz0i zE;2(Xe(>d%!iSV%-|4S^s-K5xiJhxCrFjn<8f04hc6zkOuUayYVVwVi>$zvH(Vyrb z;=_?wJ(%3J`HaQ$(dk55M;fK0)-qZlNRrg)hnV`6>?J?FBt61U5_X+fC1|ohLcp~s z&A_IYw%jzV9)_PNUKkUgIbKPz2o#R%WtJneG14mL)JKjDb3o24vHW0LZ=-MC#tVce z%a+_)dVuI3HTdro$Gsb7#3%PW5#A!|!z_`aw%4YEso(?)G3Fr3gl>aAGp(JaMIH`Y zKU>*cS@oG<|JEo%R%zq^7dakATfq+^mjUYFdETY^sz#%oG^WW;h>fe z5}z_!3dwfL6FIc))ApV|aaMl8s!tXp#j<}_V-iq^%sur{T?*m;Wla}dHb^WGOigQn zGvRURw$39?o&ANmuA5ITx0|B>v~~^&dE4Z0zLX4N$)EaXs|!W)pGa+y|L^N1EpZfREtIIlaLe*H;zxld;XkSP)igYNI+8W2^RxxxI>F%eu%p2 zM6aA8P+SJTRq%l{B;FT%qhgw6T=94q;SkyW!XP*Bl?ptw8qq(6ShspkmFW%IRVnMb zD2{VNPw9Y=Z@TTKp&lXCr0(=tZDTjH+hga6ZOFFJex%d%^YsLypSYVGA3`%IrY@_W zk27b(GQbTOWNMhk<9gX~Pk+9Uy`#J3&i`g5(l(EB=EazzVAKy^&cX$|zXZ@V;m`y; z>mN9_T{t7llWO&QTUfuTIjA_fXej30j%(R!qRZ}$TsM)ZK9EJCdvDumJ+YOTPo{hN z1pYjMl9^R;)}jQa^&~s0sN3~~03J6!%0>T`OTbOojc4!T>NQK#ADy%;sNXF=${H_?Qw-bu`OW;YW8L+3nucrpeR6J-u zuyG9j!3oU(>nTqJ&J}%X`ODqkrTcP+$l|o4_jD*n+B>-yo&?)onBgHE7Epx!0HTXG zIb3mC<0GZ@k>by8CmZfX0|YsGF+0YgWiG2c&G6oyN!)Q3egL%4^nvwVD zKZMawwvQIdtdqcuSjH=ss0Aq{6ZlL+PIuryPl_!DV@_Z*nf;{m+a@0L9zk;7wttW# zqoz(c&6nD6@{Ht}L=TovxSSoc<9IA*L| z&L~&$==*nZlj0f5C-MyQJ&3N@&s8LE0w;5apK*-1G*qD#YY8}mp3o1TmiM#y2^vd( zK9rYFSfszr$j;5^yr6+2O?iZHEqq+bOc3FEnmkiQWrXA(7>A-&3YKu%NL}-)D1SOaDPYKsGb|I z^4_sao60m~fL4D8z7K|~r*DV|`NfLxXr2**$X%FspVu5=@WrjI-Y+9gndj2l%d8!3 zFWJ-ZeY&>ov7Cv=TnITEC? zK>b=%aYUXw59o>qYUq^tq;$?&l-Mlh;dRU(pT6%=Jm;-};a{Zwc=e6AY~%Y-ttN4< z5|$m>>mI*{w|1+uG4m)PU<`?~-aV#JKJd9A=0&;zl;!cfQxEn3d~Z6%66_25vq-LtAHk&hBfIRCJrR!UwgHvTS9NDFJMs>xjoBQ_T zQGMEEfi&3r6=p}4JkX;4&-6)Ts)v-X+P z5uepzH^MZ`zr(N+H3>O@Q6G_@kTz4nS+A5uS^#t8$izKXX`Mih)9R3ZQ(bV3RDueB zn`WNaml93s`x=@>SrfT|k`;X)=b(NLLs~iW@?Y*n!EXdV{a-hu7{zy3@{UUmmz+B< zMvBp`c`$;LBU>_tj_@bES%ximWMmT$_k*?LIluh(*N^=Zw}(|puHY%*WirS&LpbqT z)Bp6bv2wCp%U&f}JBAnCxHkEh4v)k0o?|P7Q1W0WjX@IV&YkMDRoWizjqEmfa*r>$ zpaQzw%?ff)-??+HIN@*?pT50kSqWu+3^UQ6yVO0^ZJyA#f9yXn9SE`!$Rnk6I^srG zgV%}u(ObMj-^8Lj-K(rF#lfI9R*9xq(2*kK_mZ={Z&5SXG>GI~L(bEy`)@ry zK6+z=ufq}~()kEV%y}nH9|_`U9|h*o#%`&CuOmiI5sK!Nz%nEyCH;Jq>3n@#RZB}t z;Gqf6+Ovh+3y6*j;WaG!*sMJX>BxqY@>M}CK~ER&p%AOu?bp)-m5}h|cd$WtDpCBx zg$tl=ak4l99QF48Rly=HEUh8^^YX-fbH{IFFuG~RUM@aXVI}@nUasRMB%?t-XM{qr zGl7|z(n~#!cluD7?UTAJXE-u39$P~Y6#BkqbT5mOifNW1t7*!SBMbvuM%V4}DdK6w z@&a1cVX-ZfY}2MS#JGBr#*r)i1N}+I?_bcsuV6-gaz?MDvjP`vQ08G1ryV; z%8mTYw#I?}2yZwbAVBrjO%!Z1!Dtt4mAesI6%tWN@ ziD;U@MD~JT%haF%zpG%g&C?;fyh>!T&R`{rb2$7xJ=Bq9On?dT=kkA3b=-D4tlu<( zOtj^sVskdbKFtQb+ElowyTiB`&jGa{0eFyNrk;lfdThd#YgP5Z%^7DIi>6KG5@4)b zE&EY>uoZSHbBimm$J$3aiW=ie-o&N3Fz^g9pK1$lP(DO9{Q6b_5pcY1PV?nf7$Z$- z{#N0_7^0%{VqXc^x@i{RUD5i*&k9coWlJ<^u-ExGJbqS6BfH=D6Dbfb^@#X|grI!u zrKJXH_gg?{1c)D~Fle0LVxyhTZjl`)8HLy!T{JklWOo7Oxj)^ILr8S*xmFh8=|<6~ zicbr1odfPCm&F~a+z}zxn~3fbn(7Z=F5$%Sn^y~vZrNs{{_K-C%Sf{db?qA(ltHTV8@0>c{`zM*{N zzvE%u=0QCHtt#T;?c0h*)<*Wvwhx05f_0XM@O60NA;?@TO_a1H^?s~Xm$XJYDcSdt ze{7AKcR}r4@I&kQ_)GO|=os52BZO&~usiPOQs3o~Ou4t$#@v=1t6p3W#=CQYhy@o3 z{_riYXFBhqg(21f_eB3j)91u|Q!T<-j!_F@S2W79x$sXlh^%G-RS}zMzg`NrHTKfb z=elK{sr+vK{*PJl7bS5frTpBAzx~1+Ys;-#BHeVfU@Q5>4hmE8sMWc;aI)aR=B2+z z3JFa36tPK;ifyZ_N2J|aE|As;u!jK*8TTqisvQzM@O~;uZEAl?6#7eKZL9pCa4Co8 zB5?K@C==dRgpn^lWU@ItW?-ot5z)4yBn0>J}zc2YB`+v|ezG zw>JD5<9MDmqVWY{Aw;w8ncX!dX~H$U+BmN++!n-4lw8pB=sZg`9cwELZfHqYAvf>R zWvr~k32(UZ=e+PtF?O#aTUex3ga7O0~im!Ev#Fyxt70H<9caTKL<>E3-dbq=2~H5c|sS z>eacMv7aq32{CXj%-&U4vZAoOe4}RVe3-v3*~KZc$vz$?)x$B+?iiY z*;9X4*Y`C`WTUZzCjCsMaulKoL6-r9M@z7M$5nG6jRc4OJSQ9`$C4+z6Fm|0B*g8B z7vE}4{69X8RDmzqjWa`!fv&O7;h#xXs1Iyan=cAw3)~Mi-;=&W5Nbv4hN$u(%mRC3 zP>8-p3*WGDW>T`72c$)RusB2O%wfe8^RFyadEvZZ#~|l{61n)Wn&mi8OQGTsKUdM_ ztOnb@=$h|0bX%O#-w8u>BhV7v5#9Sh$}`WnF2TWJzE9flYv(&Vqv{e4*VR+X$#%l< zia+@Yh67caML0+qq`lY|hY?yX5xY+kld38uhJzzyT${2(#lN{Z)8uAvu?I+aOHyFV zqmY($1S^9f?Kl88AP;uV>pk*?8=7S~v*RX1w+lGk_Tjq1sjm3uR z=X>mZc&hGWUm4Mkg9yrPjIRN7rXv=M<349VTbb&u;7ZKB8F`LB|Du{6ioZBND~M-& zJuhe@DyhE}#=r8bOQx$g#`|EC{Jp>HXXwzAA7?T)m>t|EZO&*L=9ehemujW%Q+0f( z2Og{6TxaXQRPB99l`$l}&vNx?fVM=q;j99KVN>NiEbSN^nW|Td=Rf(Dr(0h9i zt{0jLhrxM`BC9n|k8jKcs05dytkVh zR`X_C8}A~2vYc_h@fM+vpZIW5`3Y9VP`>qOx z=OlOYUbg9z&B-mMmBVP@Z|fyHf)O4=$*zP_k@WP}NVe4P$?fCrGcfK+Tr)UjYihr2 zR5~@@!bbSsBo<<;IMs4`s@RJk-qhfh{M@cobLj}K00(`JG;Tifu)UCiMIXF6C~;7j zEfu%i0I~35@4aZZ>!l5=vxf`5?wd-EN3=ZMb)5!=h=#_y*%tt7Dc<44pdL!m71Q)64Wzt+(-G7H0vuM-{!{As-= z#UJ69eu?)_j3wO|P|d9D=x2t?@y2hp_**IGJdo+VuWaT2yL0DG{(Q#86YAOK!ixii z4_naXoS$F(Z9q_Q%ZYFHKC2fXS87mYEF_1iHl%7-tz&-efNx%Mop`)x7u28vXVqOXq}S>#kYW9Lwz-t)!m^`!4Ct91Bc%pNMgJ>axp zgGszO(Y@KX!?I@z6`|_AE4?Da7@FISM8w*>MBx3z2K`_GwKuQ4x$4hYu@G{ZAL-Pi z`Xq*H(Pvp#@em2?)d)rOmaQcLPHfzF|GvJ4{7?9UOqX)&LF!lBzW? zTRq0A(iheH0s7G>$G$EFD#WN` zA|=I2biiEpee>pby-wGnY1QLjGl(}{+fIojs6^1zIo+C@YQ*{*#`?Hf_Izb37a}Q) zBmuhYw^>d#MoOY>*igssLHY_rl~&Fh#EC%dR8WQ`Rg&Cn@(QOhR(UK^a8p-LldROo zm-$D8a3%lm9+kIp;fdz@F&{?sQ3qi*dE~Sa-tGA$F^_XGEXAND52tl>`h9?lw=Jha ze({Qc4X!tUb!$0}ACc4N z(=O|W!?yUL0N{Xbq4mVp{2TT@2NmRvEwk|753OA6UAypwAqyOZ0itSQ_}KdnlyXgR|p{NyNOiQG4-E9LR`vfl`!84qqn+pa!-Ha$PyE}$~X%owVf*ZUn5+=c@bn8Wreyte&aw-;;5-Ey|s7`AtV z~LO>OI(iQ&bs`+~r(~D=xCZl~{ z_Y={aND5-gd86)*{P7D56`D7uIKa6PAb``iP>YxBZVWN#r6b_@?)l+tH3UiiZYR^V zxofxHC8y}Dj>Owj2)@fzcx;)U@)<~qO+u$41ij7}zXR+0RmXUS(mU`X&aWmO#7t4n zLEhyO18sXcOyDDwgJ~Y)dm*}FSltuu<`2=J2Gt<+o18bVHQzR8yMy5j`c(PXJ9+k^ zy()i2Fxg+RmH22+DeT(8xFB?uzS2j&SKJReL4rB&Ft&c7b^q9SvxQYIs}~y|dMrH} zw->NMMCE(vvM<}U`Z^DmPlJiWP>X)tYKTH)1;GvZJLG;@XqC_St8?PthAa|J2Vidd z=U&M7IG7*D9b40Z*a3fpI{AJ1HQ5=FzSQh_6(=(?_NkALt8Rc}&-wSA2gKwPd2`x~ zp_KGxnZ1XJvG>n&n0k-2w5US#Na-kPI1 z44vX~$DL>ie)A=Elk&)IX_NbJmh-yKbO8RHc)DmyRC_c#yehY^GxiYkq2(2?iE1Nx zo1MyJ!TBZ?;^)Rr%LL~+{}KPc6btRqeGeXnSyM;|T-V5&_6hfKp8CllJH+?)-iP}M zG_?-P@!7A#J)uKBs&aP&KkG6sQfQrw6I=^>VaR*6O#w2SI>-<6&}YC8rUzW-p2q%o zI2}95N>(6yXWkDrc^OZBk>rz?^ugq0zS)1mkqDgGM2A|}g?!6{ZPwpCy5&hifIB{b zN$A|=(S9OvoSNotp@FSOR+5+Rgr_FtIUZd+k$T0?lk4+wl#+#zi`#JxDLYX(cBAjS zac#q%Ekmgcl4XI@1LRmz^DQupto5u(Wi`4Suusutmxp#(J!+y}d*_?a_Gt<^IE9fu zRy3b@EH=jk)zSfXYH@B7vofP`wafUPq)BAQujjmG>+4rZCMkz%{xD#Kypexk=?;Er z*9}5y_I3<+&BBd!U}!6@->t79womftbaSPs$!C2vj-JL1iRMS!Fu!Mkl6Yu6?qvSGKfN&pu6$4alnur&A=>lo})6uMyCrD#GT^Br!bA+{=;s3tzH=_l#b$ zc^ALw^YAlXM(Kdr0GvSGgcx>F&xC99dL%I#?YPmt!y4xDRc|aMNDO;P+a2@j_pyu` zJgQu?G%J~1sGlx!d_s#RVIjw4Z#^j4aWB%jY5w#S=2#Q`ChnbC6qj80J$GH>9=v7j z6in<8D3{@Y@$zU&+JRDRQgnUom!0YTT0iQS!7>hx+JDeK!37W zJ1R#Rix5^L5y`ks{9+^>f2%yP%2zxyBsxf~2`4??F8b(Qwhm99^dCtlX8a6bH<;my z7z(+fcfpSlB~9Ut_MdAczi}NNhT+g>mCO6z+T{O00#u`Ypko zeRErT;+aRo;8X)chSdCg^=OpZVq+?PphUgOIlqSp8)!8`WTErAT?ODeeUx8g$*HDC)Mjv}|By(y6PhwY|TPW|cS6D0PVN-F3%|RT#U)(OTU^T({1# ztTzMTu{Y6W!b_IKj#Gn9@u9uwbX(ib<=a*+Gdzg2uz=5LJh zMBj7txkzc$auI$?IZAE@wf&I&=gq!ihTt&70mFv26B<$$YAUNvQ-H%A2Xn^i0cq6CDC zqVaCaIfEWf=m2;m=*#>Q~5`lI=(d1hBE z?Iel@R2{Dze`0J4lfkO?*|?H0^;9-xj9wDJu-8pIm!i{`3l@Q=rplvu<)7Zd*qxQ^ zTE;HdQ^Ugz`e%RScoiv2DZkREjHaWG+^UD4tu0h0yeZP1}lFw3-wih#MMP z3%^E7?#}cF);QVG-de^GoKy5Er@-cp9*po(_?Io?zP^_q$)r{KF)T+p@B0NOq`bgXPdehisq%$Pq~++N{Z*_j@#X9%GW*sadGC?n@xHBk*X%rRmYqYCqBixm z$hI8_N0$fvxjl)C=ehORu(I2@r;kZLo`1TL9+6gl>W7Zc2a;;U_lw=S0FTe(v*K(; zp|t2(UueX(hnl6mUt5gSo?4l2xO_giC1vZ3WtgurnKj2LGRMyw-7NOF3DS>D#woR) zM<7G)qrfP4WPp;l7-S4g`&9+c9CORb!B;GOmd%J0R~{4@w$s$2X;Mp`uQ(J)SwTv1 zc+0hwr+(qb=F=52<2}K(<+|Q1c3Y4VE4ZFP{y)a)-`kSE%bZjSLXbYof2gW~Nwp?r znv)hbQO={tW6Zv^9$qc(g_V;mkrV%(@p=IJlJq_#zzd9nDZfUZ;nAd~g5=HJEn2E# z=Twn(`OBa(nfI;=LO9epb_9=@q<)s?YtA3xX@E1U^8b(=&p{qR(~DOa6nt5^anvX` zzuk2nkX&0?3Al>Y&aZSy5GV1Vqndo&)0$YfD37A>Ny()w-e>k9()G&s5S}TCR&R%> z%=Yxio{%(e?I%$h#mCD<0PeLpK4ns8|?a#$0|G6&0!A5l$N#b>ym_{UEy} z-~ad96SnZ2w~h@m4|;qSQSvO+Fq8^_ba){)XD&vkM|nZde#`vMn9&zWTW&UaEGajj z{N(%-=||01xo+(2l0^EIrx;u#9m#q*!O!KL;M89-b76Bx$e3T{H%!=W*EZ!)G;6f% zNB)79YV@aJ_15CRNVBl~Ri(cbd;~=>r?DBXb{NW}^8mO6T!JP9OC<-uo|w+jZf247 zt68RK4?dGO$i;Fy))YHx++OLaJq~E_KF|OS0&6y9JuImSX0zKtP@5yqNOfMkexWr> ziRFd$Dw#P+;meaIxZ4P`?ug1_9M)@WdeOa_b!#poa-lmM9pGGW057AX4}2g-&4I_p z=PiqS)@1EqsK3lV=k!2OSmIm5*W6*joxw_2WUh+Clk_ul%utK)nLo@egkI)(d}V4e zd)Jz^t&%@ZWA8l&B02sy@-Wi?KFHN!T&q^RziPCAo%Yy|Ap4XNKapa>S;54{^&|xC zJypnl&=u>Kg9Q*F@wWN9k3mA|N2Kf~4*gia|3pLL%Y+@DJM|iKMJ|jU4q>@<$K@v` zGKG&$8n;`Qjv-eR*=Q{Pj!Rt+A^U3}4lpU13O#fvb6cH2lrAe`#ZN zyU~uI(i4O!Ap7^+;@QZ(4aZ*X3x=9+IjxeKX1}Vnj-4lb=L_?Bwi;Q}=G0s{pDv$% zTQ;h01m~P)#5pZ(=K!i8he-)s(N-3=N!^Gg%>tsvm}+SgqdOFo%r^Jo&S1NNhKN%-EQ z#LU@`7vev^svW9H9AO#|T?haPKDQw1liO>8{vu>%{F{IFh_~5RG?u%XOL+VCE{AK= zvl^coi&zRO&lTso;>y|Ol&K@TehLS>MK6Ku<5Q^QTvJ^!Ot}$&&~(9!i9M)0!y-P; zfbA$>_kHL?EV~Ar(Zugr>XRC%;vbz2y>|lifnMn; z$?wt;|0Dj|;F+Sd6~J)~e~x?5g)=|ri@FMhwP^Q>3_I^$54d zn4ep7Z#o~_f(ROai1LdF$#BC(OdpXNk%0t6fiUMPR!ZN>H{V+R2p@F6opB@}H`#4sp6xA6%n|I`=c%`{xE-ZHl&S9?MU8=d!0))rT~&TKnh`yZQTZGRpESF{6DP?+76QGfi3h@L<6u z$@vWB0q%#5R`H2p(~W&r5cimg@6}+gctLDo+4ZjMCA#;?I4Zz(W>tI+{ChaOA$&40 z_E6_{v0)n-&PCoSbo!M%T#DOsTfgi{Mj}e9!9#Ow)A!MZn_7V?UO53h98i%tA3s#F zRw zPeP|V3cY0T7I|Oqe9J4xHS?^-`~AvX&?1*xh)0M46#*8!<$XJ;gaalNw)ivb){U;5 zC@b~dP%$97S#|Bq4b;mrVH%Y6HrF;Hl)?;lSN;>`s`j`Pw-|T-({q2gmPTv3A8j83 zTJ*d}vJAGYNQyX`$Mv^>1wzSyZ$pe18822}yAVQbmQp>dUX8oS-aZmMNc4V>+IcQpuv#FB+rQCOPP zB~8}9xEig%P750!5Q=Qjt|Y$%t#jv@nE#Q078F}e9}qa|CB9#QzTdHcjJNU&9eN+m z^Ja%BJNECN>Jzw@t3u1`C)@-gMRis9?D`;d0FY7vK9rc~be`JcLo3UWngpYvHvjCT zto2`KauS(8l{L@RaNzWEYQKsyhVFD5y=>q05?GG}Im6yY#~h9YZe{idd0CL1cR zk-Zz{wI2N_c9+l!=$NiJ_L0f1@mSa&_|6zmYGeERZnG=b7Q7(ByK+<~*{hyd?14)E`jgU!Al_$Dj z+;qUv?U1(Ewlye48(bj2L5(?Q<8=5}>eq~1kyxwGp!>3@gF}Sl(nL>uS-}fx?nZ2C zsp>v#O%Pa-TdoBc!lf!I)FFybnUV+lADPTKK0^QxRr*Mcoj>miQLt@nZ8xgbA$Gc- z(a^@kvfgC%)W%$B3)NB?bv*WtdnJJ@Q!10Fv<% zb@-9L>EoX?pF4r&MnGLfH(By(HUgYmh-oTuOkN1+y@4n=R^pxgT#U8xar`+h^s0Q6CenoS!_IjtOdBG~?5OFidoz z{FMz&-KVLk7J^+Fnp^jNddAnLqn>k&9L4-B_Al;_&Km4TV=u744OgTu$k5a?E0|#| zR{=spdx{68pkQse-gQg6~3xc_vjH-s%fSD z)xpbi{hg0$pT;$J-Jm{Gv4X4T_m03@U7was5eKYNwi&m)C z5A=>JCX5;WZ?{%f@fRF2OCeRz=H#)UiN8ixR{~mDS=RSJi||&ES?? z)XD?)XD5Oh)wip)eQPoyqp^8}RU-FQzFVh`U$xdttUXgp5&0Q=u38*YwIr@;`?0ET z&Q;-;_H#A!T0~SIJoPkB?c>ZBmpTxQl2(W`yz|l!dDxqEYns-vC$*4F$;HYuz%(|m z$GDM=MLy&o6bXx2H#!*Uj)+dY+ua#Ixl$zW(1%PhxtrJGhR)23t`n`l&tSTH?^H_O z9V}9(F|AEk<(wS-$f`q#^d7crUvzMz+_R*<5BdeDl3SjeW*${!<97OL^sUFZe=@%L z!BQNN^Rjb=l*u7M$_>iy4U_SEPsuL$5xHkIt>O7XRnIhoEqke^&QH*%8GdgcNzhjo z*+2aJ@x@yySgoHlPHT+qZ&9`9`~h{5JlUO5*HQi`2|Fz0T>{pRjsYXx2?}mAU33S?Kq;3kKP_urG z#Dq;T|CVfCj|1l5z@5sGW62HaFVPEo5$HP8buM+w>` ztX(p2a7p94aT3OD9o@a)P{Yl2lLJKcdd1$cM^~0I`7H8q!kVSb9HfZy`1|e?4%T}R zG^O_X&}@$T5pJ23ku=;^bo1GF?3F2XNjUqPMjs%mo%hI3vmad52~dp=9rHYvN7lJJ z?LfYD$s`$>wBnK{sQUErQnP`Ruf%U38TZ38yqBz@4T_7eSV=rMQFr+J_wP`>{&%Z- zcsF{=i%_vaS0d-x?xIoi1G*B-!@&sUmPl$`EZnC2-4GHk!;=g==@nW)?b=7<++&XW z1$WtceBH@)CBP}Mf7|tlqiGUR(-g%PpA|E@60f>kW{};lw-PcR*t(ampr4{rOWdV$ z;jrEBc1jI_7?_;1df9I1AI|o}6ZXa;xGzrMW%$Y0XX&@rpujMy3 za?mELNBYgAG20-cZO$Bfk7=Wh#Cg*OBZ|oG#bo#K-u$p`xZ?7=y?i@25WFoGv34}r zzAbX@ZMREtC23Tty@x(yhNo0wZ%!DqTko1-UvMVy=>PtrW8%}Nt+lm!q}^;*!~VZx z435nN5g60#d(18u-$N-TvMRe18ucUYEJPOe=?QPB{%$W1-S~F5T67Njlw10^aVQ9OAi5#IRWkv(a1eQsv+Ay$2E>ie?VoJM-{ZHt5~ zcE8%e#_V%1J6(!3Cw!ZSr==BJ!~2-<9q}jh3kwUqc_}>?Gl^bR$a*JHE$SG=a ziLB_YXU$ogW9}#@Dgt4ivc-R9I7vv|+D6-Fqkx2LVL1DAPQt`p=8LmNIKpgy1B%r6 z#_UqD#f8Ga;a5pzN33_OO}|~O=38CE(BXa&?>O;$R4|cSB97_;jh)kDBdVKve1qL% z((pFQVU)95u35*_)YNN|<%LX@ght(5Gx~=tG;!t96)W`F7P)u8_W#>XO?m6gdGA`g zJoX6Hqf~1jZF)W=6H`idzp!f^r4kw3<@jb-JBdWH#+hNIheyLbMUUnqDh{eQWrhM7 zuhY(dI}*A6KruDsEKE0wX-5&CH_P?ipT!yA{M1tv-yE|e4w3RnW?%?pTwGL? z3DnM3m&X(PikDw8H$RhWc1}VROowzIGtCe_=4i$RhiEQC{Bj9_vsZ(}i^9T&A^^m4_L&>s8gn3cH%pg}G)Y zi!DsLTrQ+?zbQKJ{nO#~J0#R>VeAoWT#uF>8_rvWAY`R|J75gE;(dSy`ami^%TPx{ z!~ezE>{oqmyOu7r-?z!W(0twUh#g4lvp%0pUYu-EQ>0$?&nML+qEy`ax`S@SN8_ZOf1xfr!I(TIdbU%NKPeVdHV!cabaN=gak z&mwY2Uoh>nidJ&ZwA|(eBkh8tz^)TcVf;$MuJ~0?->a>;Vr$P zP90-nbT;jD>xU0_@4dfPe?|kAYkA=G_ah`3!%QOlW$49=7b6S%R3nHW_$`5w4jmVF zt-FA|0KcA^G4s1WSiTmBnQT*9>~Wc>+WCNe!Ip~R`fOOT^YejM%C6h^JscL7Z?~=p zn0yxzu{bv;=M}|63CgxaL^^Z7#1w-f!eqfBl@+k+eYq?zi`9R+&iS^&nsrpZC9?h# za3(*nn?0=v#vTUxEHSZ7$eKq8JFKJi>hDqy%IkPIVYWG@a*5$RkCK&zG#$Y_spH%bp#TeTU^+*PvPs~9Xq2H1?b7>y0xFjrGk3!>+i z4s0q)x~0#i(P)Yul=5}ERaCHM*z7JB{rZ9Mt;nY>RHyy_Xnqmsgbuex=X~1f=NJCd z_i~hAF4Q`5mGr$+=DaLZf?f&A&7Epv86H{7#D*EV>Gh5&vlpUv0Z!KXsc^$OYh#j`<10K z9HGOW-r*Dy!hKUSiANLW$EkexaGX=q|>-1_m)d#=h`^QRJgzt%?KMT3MGW!L)X*!3w5cHk7w?}}#@rt*wEE9bw* z&pavhh~)!+=F6;?FMWZZ63oztvJeE-Ys_Rvdt@II)DhV1dxQjnZU242melzsM<$-g z!Gn+Tm-d$2Ff!=a7HQ4|Lh^PYmumpQ-a+Hq2!}xw48DDPXpge;YYzw{o@^=bLm)mXuB!o{lw?9i_q=0lx!=v`ajc zRih-e)Bo63UKjSFfCNr!6ucW4n)Bd`)G=KnBd-jOAI~VHZP)kQQf=!AmIVPTfi5IS zck=!7D#K*$;Moxde}b`JQ**O(zs(Zl;b;_0d&JSdHF1@e%C12{7L1DNQ*QHlHDS%$=_a%;$&7J0Wz=>KjEU0eB`{)fbQ;jObg0`tb%wB%`i<25S zYvLQQ8sOv>>pr(s?uk7kYs!K1hiz>dx)LKe{wR*wYm07M@#kf7UJ42d%un7V8gQ*k zFGRAC3UOy(kolL!TJcaH$)~AV%CjOrgwLHvdvxA0iDEJ;ITL(PYZ@rJa2P)oE(=z6 zU48w5ef!pIk`dLF?~a6sgjpKODb@5HT?@o9|F$)@AT<(#lOuy{ws&Wt($;*j;n|uDBShavviojMCPO(GUU>K-%E^ zfroiyD*#EXA70wNQ)BZ=aBQGu@bFp~+y_E(P3gk{4`u%2kTF@8c8`klKZ`TP1wX_$ z%gUnnkCvSV2nmv!ny*+MaT^}_Y%3fVR!?A{ITW+#A$t;YiQGnFlV`m9d~VJN6k|a> zZ5%?#Q|1pIu}o4~AKi92^2at&8v{_&sLI=NtztSXT>=ymV7Dh!W_pGUN-^dB$i7#i z9xdBrEts*ULv0mlwhuR$c4`TdwS8whPAUE#obh#Va9~d08KZzvbf}aQoRafDeYpVn z`IcDL)I2v9lrjd5R>Cy9aAwEbzOW}X*4pSFyJdBj`8^%JPpEA(jWA?3P>bdyCT zQnKIeFFimy=S;OQd3m4adZ_eFnp1xu3;OB^^wwi4=Dg@Ok}ExKn7mylI$b2e>(* z`FASGKP2g@ot++Z2~|cyvv8q2I^Zg%^6wD=wP2%AF>oP6N&WhYHsr}R8BaTcKS3TwdW^VN{5PRX+myec26kpV$h~Pqw)Fi zIZS+1$$I{t5EJQ}PwPtfghbS$-!3x^a{ec*v9M_W`ZZl>5`giS07VdnLixj?DI4!J zACshQrvYX0l|zA3-&m7_^}Zvme~(j%)=*@q8)CC>4^QWyiG;hUJV}S{4bksM=wIJQ zvw;Ws&2UPv@*4IZqf})oEVx3Wy-e-K3D`KQ??8xU^s2bp!MV&6{-PXkxGu%7g>q3= zc5!ep*r06LI!6@n`qfB>)iigLBX_l*gcvnaCdi4)=P-J{)IgP9b*NcHb?xBz16zrW}&pz98^cOclYD z3cJO>G6TLgNb&cGL~e$KeA_15=E<$|91(IC`;GVe_8gj?wDqVSn+HELxz3^WAEOZ8 zXb-MV&#@H{>=|6e)CpQDpO#v(5|49@xARj>^NI2QbZsuf)g4DzB=q9k21GOU2v~*7`xt;i+BXs2_{2RE8v4 z{c&bjcY>m}9Y;*9=2fe3ZzFg#Q&%Way%K44&^7r_Q}R3bS=NRHpo zjkhCZ7zpFx2_ncyhe`4;v-XCUc@J)y{Ss05{@NLcF@(sLStsS`(#nQ9r5B}gN)Voq=XaO z0k$_cHH~oRr`Z$!M6K!S6)IyVU$;cv1L6Mo{4Vt{_eagkYBx5(6(`03p`Q?3>NnP# zHaY1P^WecQh+ex~vMq7}LHOGBMtbTUt)C5&TH|@M?4c~5+}ZgU;;WWa9jcdZ6*wM1 zD%*`*=d*ff~FYI^4@6m<7BwPUl4Gmb4C+us2N#yr;eyLG(Am z01(~|CgFjs&YRfSSiI;wY9W$)w)bI~`WBf4nSq#oH}zkEY_8db?DOy%A*iHO1fBx~ z^#J(E-)9SL-Em3xu%hsmW())fiAGge7AZjWv*NUqwS*mrMrA4@_aigM5Y~GxOB&Ozzl)2*?)So$F zcB3kK+O3c%>JsOEP!-T>&r_9+0#}?kK>y@}Qa5 zDDI%F*iYkS@*<{v?S0c^%>(`rmN5DY9npRhp8(sFOWdQCR-+r z{4%KyAOzI%<8vY~-)CiIG1+vSiVm=wlRI28LY_%~d#S^tO@xVw^S?m~>SZ;06Wnfs zxpNK)v4juq0P$>lhp4brAIN)ac?xo2eQqT+G=eB|;tqpvJ{Loz=tTS9n_%D0}=E&;Uf#k}Yt??+H1Z~{a)yjgUQPNQ5C~I5I znk#mTo8{bP^6LaOZ?Nu~kE6z=mye|(!$N!&Pezuza}y`^Mo$l}y!||*;>R$2BKj~| zN3rP%+OauOAcV6YFJilPwBg&FUYTK?y}Zr{5!w9o@K5+H1WnqHM=z;vkK=%2JUK`4 zrV4hNe5d|vtzc|sy#l{23N^fCMsvkZ z?$d}&{Jt@KsES9aspS5x1hTK6yX0*{&z3C8%Oh!Nr}E z*SEMHKy?n-b@HFI2o&&3_a1KPN(ua)cxGGwhs^0VU^3wFAen@;0~?Ykt>xzg6ZPz8 z$}`-+z#tt5kPw#k15Dtt;d&By*}s>eYnKtrNk!;r=9fN$Ng~d7uP&ECC}0fAwR83! z+S*=th8Z|GVQaAN_|R1)zh^dz3wNvUGf0$lv!=QS|9wJ%5E_i^xrWOvf{pCt>hr-G z76z8AiTIt=lXeVWM<*_|Tp&XJ>MC@m}7!(s*aI3RnUPBzVYoI$uf z52!<0UT3TyTx;54hC|9LOIw z&UnAEOZN2_*iECl;sa`4^fnH$4lW}fj2m!+Ts384caV|4eQ$ll+(gF5VEgvD#w4^r zJ7q6bDa`6@WQmlH&Gx0Y4WC;>)~l)MzA#SIpoVzQ&JU+jT`hG~&t!@Vflclru~lO! zNlBe0?qrBPUxVa@nDoH|gFYr@<>n1z7q!Y2P*T?|GtmO8xs}zE!*_JzIyEv7T#Zyk zQESqMW0{U|j?;C?(Y6%9m6mt@H8^EXM5FuUHq^Jd5X(?ErH*bwLbE-7jpx(##J9U< z$>bpaCv_% zt(?gMqhsh{g9?SbY*EFvkewlkWhAZPL!`V2Cov4$_dS8|m z#kIP<>+O9CD4Ovxi&3ffoU`y2tGU{S7c6Zrse`HHP|MYZ zf{}guudb%?EXqD)`U`-thpTKq6SYEbCONhDW4KQqXMl9;n(PwPMk zJ6AQX$yq}?27{eWMsjA6*GVbb`07UcnvCoJgiNshCd!?j_w1>*sfi5rv))Wr%0LY0 z%Fi557${i~ZHP8xR4ar#mQ8}eyDPTTkP8Fdral#%6F6quiz}D*e9HVQA$1VbZ9`Uz z3z$_U=U&c3JASAakX)=OO#E~q=O6|UFFZoTyJwFxB>bR0oG>#xWr~`Llf44D$-#pA z6}yF%J5!eufl3SO`UHV6b0Z-S6V?GAV8TG>aN0mp8%P z1=U_^>o%1Afa3M|!uZ(=T?NA1$)x7~ zC=-%#0U_%Bx>LDlqW3_vI#j9hJSZQHb0^b#_lTPhs*ldGb}17ha{mHqX82ia>2% z{|I*@#-T790OA!9d|BBgyf3|*+tk!F12&y!eaN_Oc-u-q7xT^6@&n``RNNv#E_}3H zSK>YtOra8?MC@0gEi{^NNg%JfvA|<)Zc?Xb^HWzOl~-8o5n(kRf}L<=Dk+}&nWBd& zDfgwD5iD{mRkEKn*lm8)UwP_tXNRYo$3-ez-d2LR#_|>pl_?vB9luF9g3mP-b1o%A zjmiw{s9cznEY?|0s;xymJt8M7)W=mGi=<+cSj30~cV!h7R}YUjR@klqh((Hx6*@lH z?HjjIw~!Ep{67rWr|9w=CDyh03~~0p&NlwAL7g74WR&myaQ3nZ-Xb?inX1pe;E#7+ z$@}EF5*a8IQLW(Kd#&ky|H|p)h1&nWbGW@EZ8zMKtm*yzzD&U9TMvx(Bz>r6 z)Oe?uaf0VWH=cSj8Rb!I^oB~VW@UD{K3YzdxT6zo%_7qoJXA^l^q`~_#Nl9yQOpe4 zwp+i3-m2TG>!i`Ya?PUH0bQ_vaE;v$Hmdw8oW~9%zE>=U?bGSu%ZD1EKzc7j3E><; z^%o>I*iEqeocC{T zs}H=2j6Pb}SNl7Uu>RJn0+g}vd$h3bJ zH>TrUZXfLHO;1m=>oh9UUZ$cnkKul0JC2Cy!bdo17_QL^s-N$zN6gN)WgKUa^KI+3 z-&(%0O?NFN`2DWpmb4Ck*ZRZB3)X7bQMIJbfO@=2}madM5U>SC>?@;AYHn&M5Ncy zJ4ER{LPAMM`A?qrKKH)k8-K=dgkZusd#|+JQM|DJ{h z|8pNNM;CVo5GZgu)7Z(xc%4)Aa2~JzAUgch123bC4E#pwap4ydgl-C)WxF3O@MY?v zVGFyK)+z3;?C6v4--o}wXeh=Mdv20`Ng(HaWNvh9&+(s-T(|M2!;P01eaNb zrvJ&nl%y+TC>PFDsLsp&JF>H_kJAT@2e@XQn;V^H=f(34(! zyG76=anKWC_{s<!y#G|jQzZ6D|U)#gPLC zSjq+l#@}YieYI$jC@_w7T)zcm`7{%!q^rsowoe-u%I^6$_T(}+~ zZ4;q$>ge~cKD^%7tLTqsU)jyB#Osji7^x(l5y7^5cJ<~rFDx3K_kORL_7*4oRWL^V zqiFk$Vd}F5jM(u>Fh&ma-4#q1k|6%g#{T5N17SAv7e5ycL7=@xua;2}hLhpWk$=zu zR4jz7lYIje?s)H`Hwa{_d0oP!rwY=^00L=dN8J2=mmA-5N$lsDt1YKzTNp`C@ zZ~LXrrhe{O_*I`Lq9rfYMc(v(=ehYra#W2+_NSrqo5bfV62DA;u&6#~B|c@yY7uFQ zID6`D7X!yrf$3;EyIAvU?-{sKUmppy=$<+scb&gG`hub0g9JHUDWg~uep6kZJyo9* zic!|u4GGF!AnBK+H%&THpCT#^RY#d>H0r-8TzRFP!#Mctg;ZKRXLkCaPxTemxAI?B z2aBCqr{lpIowt9kU80w1bH6Ro(W+i?N9=5(eQ$+e2~%;$mG6&BPBzBu+oLN2PMwd? z`gvCVRDe4FQ{KC}=6dE2Cw0H^U%f8NK7CfT$h)d6{ilcKM7$iu7I6+%%)PZ(mH< z<>D>XOTW|_l^aHVwaZYBOaul{MAN)cj`c&CrVp zJ?B2(|19*G`=+ExVNrh3d=aB5&a~GgzR=bfR;Fz#W4u^+b~LHjv?%k@rZKm%Q=#&= zs3NCtUM7&dFbi_b8H-lERs)SZ!|V#^Vp9h{qy6QoKrsO~=HfSg5pr!p75!78{x=&_ z$UKd4szrrg6g6b-%a~Oe;XXM+=oeGGk1}37Ji97Vkcf`bmpq@l<{1_xdKjoRi*th zi6XbJ++P|s15lm?J1JR6+wd$suY&oY=2hZVm?YVR>_IHp*I_b0Q^j=s%nZ}OC6#tL zZ!Z-d$DT9r<}2$d>vi_`_2=}Dr^=;?4?6CW05jXSk|->vPgEv&ozeR=ZCOj)f* zE$pe29hXyGds*vFVsj#_0rrlpO3xfM#Zt^;$rI*V?Q=otvC@3nK*kOP){akFmvk~m zv!N$t7Hc_rMcZ65jnhYToVc9oeIs$vaWM~G_DUp!CDOS&=DM1f?!Vagw)qo0yq}p~ zmHun{+f4b6{Eo{`)GVS;79pBtA>%vP+NJT^aCr#Ai1>Wl4O0?kpkWZ3p-@B!Edu?SvNQJ9yWw}AF3{H*J$>osWg%7VVeXuz*gpHYLUL!g52 z8+1-5V_L#@3}v?swi=@Oy1KSi6L#{q82h27#BmhQY5=< zo(Fvy_=SI6z*#79UQ8)TO)vW4olk%7vfcc~`S!*hN5GBu=YoFm{BjbM9FiZ3p470u z$@_3m_ojaE$E}1WxuEOqGGE1(>t6{MerVET)|*RL%HmA(=l76SRce-s{Fv~;TfIm? zKe5(n!)e9QzqiEUbtR?UGp(-z|AYSr`COe{qvZqipeIhZ-3`eS+& zlZvx$^>6o8^~`)w$iO0~+vk6s|MRi->zfB=;ymUn%_Xjil`7srGv^jBp1$?w@tG2p zAF;JJJ;n@*x6P8v!kUGG_1z+DTY6r$)X=$YGMb)Sehu54o!GW9FqgEz)I24=$>auK zjEOC~FvFF65k4t08@S9J<<)~qo&8i@Slm|s4DC4VxV|zko@K?7RFu4u%;L#BHC@e& zd0f4{f1ouZncOcj(->K+QJ;%a`O)N1&^^$v3^B94WWPSlT% z@eHe)7{!m@+SFm`+2u>s=D^3101GCCHnJ=Y9cT0cCCIpk$ln)ZJiQu2p>gwLPH ziAT~^J#8;dJKZ?#*vihT!JrR3G`=w(OwyU*W6h9Nu?V`4GwF7jUVk}~=(LA^oB25t z7A8TMeKM0%8?tIYfN^E@!ZxtI_%p0UjayZ2QXa70`|)D0a%P#s?1x!exf0Z4^7u;4iHa$+L&)X5Ya z$zDc$2H>0g_PR#;AW-lP5GXtn1R_v@XMmLY-3Ea+o`66~DIgG+*GFi(Hi%B*#68Ws zCV|siWQ!7qPCrb1xy<|*FV;ibgKZ%#qdeVv`Ac0N&)=$Crh9z;LFKbMQVVx?HQedt zKd3x=$@h{;_r#^MOu`Iytp}1}U5V7Qq{xJ}+jed8Ti0tZS|vP7_#|S~8o$6_sfeG2 z707Ji;Lba(FayL>R=JWQVrV$0=s|OcS*fKQ%x&AWwELMLaP$8@erL%G{rfZU{P(1w z>i@kA7iL?h`@feeL+z(__vSF!hT+??v%=Dw!pGwIYma-zf3FY4n%>|=6w zuM8G}bFQ%*fo%I*O>ZB>z_Blsgej_2Y8AD4%(XjECCP1~Y%X}Ge$|%P3L&+2Ix9>w z|IdX6?+)JmNiQz({#_!J_!XK)`prto-rCyIEf`4<>wQSN9N#HSd8?hfj`;IDZ~?PQ zzRYw+`pUa}Y9BR(QnJ9GLKRg8NpLU4Mn0yXJ?oTtMuVHPUMTUb`!_ODt7ihh{J;l% z_BTuk!^z0&)B_A;e8~EomfwsVI z6hVQSuirT2`9G@+XL-qTLgI_zwZ(GMXVe}^7`z)ZzCBa-6@z_HK9SDi^XNIr-)ek( z{8>nd)%-ziU3Xn*Z(TL=Fa&kDS=6@|6O`fdL>z`9dg!Ka1 z@4?@dVZ`dK?d|Ss@hU!&|F^<$o58z95iB3oxb0v5xD&85J53}uR9ohKyZNAQ=JUIE z%!7P6IpL+oPlvv{*yGtL#tr-jwI{m+q zR8w5z-yLp0Tta(^)ZO$`*h$b17PgoJDaS)7W-SSF*y3dOjn*UEk z9^TE1e+%ShHKILIEM1P=-@Tc#f3Na8Z`)?Q{%X_C zk}M_!-=0un)!HX-|JzowKg7A$IGKanTO?5?_Cx6E8ISHty)xV8n-k?wz9G+Q?*G~S z?8xlM@CTN?88`iT1Aj+QYmrFg1orTFyLMjr#e-_Y5b0EWrI-~I3WYxp2&hBV)ZA#c z_1bxTzN!EoM^W^8lBRG+;&|3+s`2Kyx6)ugCB*x0FV$*3s|v1wb?RKKxXR1hv)r3Z z-`UxTuCpv%1j6rLW0|__?_nU6IR8xA0%~OyLi^KjB7VJbx-?clS^uU3#nZw{oOn1K zso%1Kqrfb<`)i$c;PmwLKFd9yTZV>)aNGXJ=9+H=KfVUbe^rqf@g(*rr|MZwa;dvU zrNCZ?h4YP^3Ab7NR=!!O6E?JT3c*yAWz6%;*VnfQx_?amjJ4wIw$ROH160PTQGahAPegY@5?hU)wA#@pt>(INA=DcmX=Iy*Nv z2L|$eWo0G5q`Vx_h5Ljsap8HT;dPCB*}&WPYsEl*&$DC2ir9j*-od3q4Om^dfAO&` z-!gMIvTR!kD_uBBej{xM*LQdeW6H_stNK!EzdO4HK0&bVy`5M#C6>+=lnWf*wG(MGZuNw z8@Bc(ig$KqW)r)!(=%1&wA_~}Q(0dx%FWF^j6F24{_z2BWb|yzNgB6j-%qh|&XlWe z5qjn1x?}YvdNV)Ec$sj8GhONvT>_XlBCmVGKp^fqDT|8nRptC4X3yZC_ts_Ku)`59 zU!#bA%zmV94SC&U>o<4k2)i5ilXpZ$@3{S$^xZsz->H@z7nnC+T9nFhZAG>IG5HPw zgOgfYHR}B~$9HSoCbAlXa4WuMW!8jmn(BWA$qI0s0{kEo8@k#!zn4_!z6IQVz3=K0 zaQi+RqlJaHF#uRDgi3Ll>?S5?y|1{b-&GRG*Asq`_#`n$*DLr}{2xVAumYn?LX<8d zOSfFB$y0DP%EW*f<>X3=wdg7i`5F7%YCAv={#yIGDvE0ayE||c7GP^R#I`b&kJZUz zb%SR>7!$x0r-m!W?ke!dR^s^^7N4RZ=td|BtL0Jqt=Q2*2#7+ZSmK}OcP_5Qzkk2< z_wOSX7M5plIP~D~aJl0hH+^~Y!88{%X!$crgpMOmm)dnLo>U%yI-bMAW@hI74;I?v zDjOS>-z5P>kZ4;j+-!?2W8`w=aWF(4Gzh|WQBk878du%f))y^bjb3E4vsn@tzBW8V zvf-fbiN-I(4K`bJqED1)TfGq+b}LV>)yOrCN|DG(l%vjXeKF@@Kbru~3V3tSXsH=I zfr{7V8>jr}K1ypCXP=g_DSa&)gU6jZp7OpKpC_q38n1or@;hzmt1SOP+YHL_&``n_ z7TepOuCTnf+-qhVvRxxA2}P2go_(9GNyHM%u)!1?Z16;+S5U9j5{ZDTY;G1WFhC@| zd-u-eQ)rSyz+9O1iw`73oc!&o0{LPIggNKEa=CH~rbuQ%m~|YRCh@2zT(|r%fPH78t=WGF00zwk;U^*NGt=Uen>u@TCS@)0W*xx zWJmB%mU8?&$X9$0AxH~VJkL;K;# zG1r7da5(0l#Ii16&Gmal&@=OW)4j@d`pCi?OkH(f{c^gzgjI zeDR&qmzee#ot6)_XMD&+KOmLNY~d@ZP6wKbMOs9I&;^bOBq1F|m_5m=!XFY6;WHMhCIT=8sZ5M<;;N?(AJdhv6gyR+4{;5zI}FIM@I+fnzH(@ zeK*I&>;1RWtQ%ge?-wA#EKAMHjq<3yaDpT>7;`)yu=^*9FR8g%6<`w?C8eeJ>Si+K z&Ff~GZ(*CFGo15C9MKC@N%uHhuKj z<;~=jQ%oM|S%dPyqM8M662eAth7Wk$!VjZbl9>Bxl+iWwPy^iD3>Ol8CfJlDsuY}a=LP=ir^Xb$> z&$^HaM9y~vR9g8eOF?oE@71e%xf@ZfUuKaoE6@2RQ2^T#l5K<6zm|vX7azLeq)Y|L z#~3Q507;%fk!`%-$1}^wU|J}x^hnFe&@e=jztOc}_+BDHh3E_4L6{Cb)*RX>VQ#on~h_C#` zhlbT?xW9bseM-qx#(_nWzGPyv_u?CCRG1BoQUb|ci9$)5mD_#>R!R81+sOy{`X#d| z4$pT4IP`m&7(%8Od{r4E$|Y%=kzXsC^#R}v4^Wt7+wy<~nKx6q1QpA$$9E(@QtPz1 zx;SxH`tyrY`=Kb20N8GQuSB~3>Akr1TZnBf-RL;dBxe({_rrb9;f7yEVh6GHS)$7b ze}ULH9|}}HAB-Dmb1XVB2*PaCrzG35d@*Jg8fh~c$UE|*HI>^9$vlf}>)Xj^6Ku^c z8$Sq;k)($ieu7@mhurF0MT@NDNm3{|jP`L<)DeXgq*W0n{|kx18W`sT4MI^xB_qEP z=-Np%Z2j}+%WPASF^yH0BZ)qZO2t zXglP$>n&&r`(FTk-BpbA0up;Jm9%Kr8sB|&g5g5@4qCR zoXNAx?G;~$?qe?$u1xe;Zj~)xPTQ+>o2_!Q3=ng@bwYXH=)$tr{DrM#a){JTq#o}v z2^HVD$Wfb>yqx!~l@nugVI$7MVy|+^!gMcVzs?JjWL4+cJyvW+YlS}B({lBpgi4je zSzoiPFyeYh)6`6IB6-w+Ji4Ze4Ki4bpy&Otz3o9m;{E;o!bd11GAvojN%Cdp#T8s) zM^GId7o;)8?_&^;r@UN$lgQDO2q_3{{&^%R(f-Wrhu+SoiSs^r89PEXK8XkgUV(1| zzIL1-`}gwkQxv}}K3s&J-pklGqxyY8C0a%nTFt?Z{ZcvGHxmt<9<;~b$E z)>MvxO1uCs`_|4$4YR$nmqP(a^3J(o3Ce)`!(;33=+h*X25_%55Z6!K3Z8me#0esl2-8>tH(O+kx&z9|lb_pww+uk=59*&?ai*g(~^H)7LW%t*!0{&`!N8n;I1 z_G|bMCmV{qE52o5GrYlw59+v--K^E4)#yeHrsJ#YEx7~jfF_X#a;WmDde7|bHRg%q zbv=OcR5|(`DSV=qYYvh|t($T_wq_j2-3V!($0J981_)dZPzthUgkC7+7eJb~WXbvy%e`RIA668JjG>Ybk&8Uo547$BXkd2_kM2U_0-A70 zn-}uRw%Z}hc2yCtayeRo3 zER~E}9zjs50qjO}xgp>Ow91Tqy@K7+4lH zfKZAdiW5c)z;YLtad9X17|2ZmvFhX|=ipa5gLhItv#-a2-5b1C(a-EogA#Fh`BLrv z6f;mMd8&PSBEZ(mDtUgKKrX`W!nlk-%VrC0W*7GBed?UJ@j<`GV+JWdJ=v!0F+FXf zXoHEcZ`6|@HkKZ`D2j~udoc%OM0h;RRJy@O`5U!dP8mbpgMKVtkKt4uYkJyw%1{n?7>3t@n}m@%;nu*N%3R!tJ4|0G9F5zI&3T;Rh6c*Br6rBb=TgwHk=Mm_So%zonoQ$szzXTx}+*bTKqn2xyQ-={JO`!B9uHdHUYA1 z595PQ@DFQj;e%BPZt(5$ZUf4aK~F0yL<}%CjDaTU1mnG$MNMr!=?Cb)GV6N5WC@#( zT+mQM~WAESS8O8{g9&$F;mQRYfE3G#d1< zKxSJ6=VQgyPRQw^(8K@I@1dy#$UkX8BqIUd&`Tr+OBGV__}sn)UJ$=f#A)Y{pZSwl zxT7p31lQ+OITGfP&^E#0Mo&Jz1UxwOwp_yegt>!nNx(jM1lQyRylQwY=aLq>WzUxg z$H!9=W<#*eBTf53_cQFyW!PQ0%AOj#FDMw%iTyYXG=g>p#JvScrW zTtGFU9K}=3fhZbi4y=lL?y2BG;o;%TEpM3hp+yXnABpyf<{rgTW|g-peto@U657$U zDxOx?6ZZPM*tv#6RlDfCa$`r$;412zrcJ2k@XTL?&~k;UV|r!6cB8)a+{q_7s&WI1 z(fI5HfK9?zu_PYCI)dV|z8@^yMx0`F^lbqfL?jkCK>$CHX4cUxw|{CbD@dCcPTG9{ zAdeYV#>RG0kbD@5J`7#F#z*L~nkVlB^uA`~qFJi)3JMPP_V&Sd-NWpp(%q0LzJS03 zdQAdp7ER6|MN$9q<;`sO(E5g(+k@KL+I+%R9Qz?C{M(6YcK=`V;i?t6Qw^pTPLdDo z4TZlxoN^j_=PD5bvdZ7KDt&w-!OjA?pYK;ZJzgf+dHv(OwN3G-nSC<>Frec7{VY~S zeTExd?MKkwQ=Oqn{RfxYh|GGl&8O}`DGvy1IuIqG)VTUqlKWOJM0N=$#xR{ZSs#SU z2jtehf3gv1!Z&Ehf}+g&qMQ4lDK-l69Uu>zv4wm`5qyEY3a}9c{cCGDMmww0@t9eN zppRex$(@BD30r@#XAIdl-Xr1A2EJ2Xo}LeLSG&boK_Cfl?@N6rhLO$2HBtwo_By5V zGRxQUVf}5mYL!;U`ZS{HNOX{XnAP&%8{@l$8+WI2B&Dh+zqvz)M)Q$a0%-aIXnv_? z!Zr~_uA|oeW80Iq(3BE)PtPn}w?z79fS0-siL2k3_{Y@-%-Jnqzu$H)MoHQ>9i^Jt z1}$6Ze;)a!OHHN>LxasE2EBmJ-O=&pMdRH1_K$W3Vh%qfq-9f*vLM-mCeNbpl}{uB z{+)}&G0FGj|Cph`Q@AuK8Q90ADg?QN)CfPsF2S%N7`&Pi)p)cFurs5(OeQ?*W&jsT zv_5cmL3Sfdg_n9daajf^>QdBxoi-nFFlq@_RB0$f`Y=Qh$>N`Qn8fZ zztzI_gyBZu{X&E8@$sY#FwF8H0xZ6{xw({1|A>M8WcB62Gm~5)Ck{?#$3JD1PqmH=t zelbdRK`5QnK&8iM?a@`keE=AN(MsOPx-PKQG*CD=sGSYKzyKd(zb2q*ktdm!jI%S< z*6+r!hd}y4f&K^y+@Wdz|8QqW!h(=N2Ldki=)wl>8xaks;PxuwVS2WqyINCIQwf=w zJOD?-o2=3QUjT2n0Nsvi7)C6BTM8w1%l>Wxnnmskj^X&va}fZ}v~v@x0SWsERaJG3 zRpoEE3UMu$>+s-!lIIe1MQ0d35dfQL#83|EdUtlpGL-x_${yI^Ocd&GBg|yubN=b7 z5MnMQSddDZp1!i~0lIqk8NJ7u>XWq{Z^F0jsuN;-T!PLFqAE_xp9X<&q!vC>L@1zk zKS7UcpozeCa~R?Q-w?PpJarX5y?%qYftvaai{v(=ycrQlk_YRBbk?F&J)0d%W zT$GVZq6Oift110J@7yr_mp0!0}GklJm4?xxcWVIq-;|2Wz5-^`DlT=F;W;Sa`R*5e@QMg#@E<=fv^|@*?fw>$ zkDxmsrO3&G?Abj|f)wFEoeILKSSrlI$|_xZ^e|WzAh9EjX1?3UfYbXvK3+?6X|&Lo zMn!{;{zNU$Ah&1UZz54iy3{YMur-1gG2d&0#)N@(QNY#C5~V?tSuIcaEt2jv&SmA- zb!!oUoP zfLEt`|!{As?82OWAcw(~)Bp@G)J5nFacL0&&4wZtqi&)APfVP)G$4FkD=R`L z{%frK?KdB#6)r+!SAgcEv86DSBw$0O?ZEC_eK^t_7Y&SSX;PGSU7%kt0qGiAw4r?K z))JNm<-r)(Ax+T%xTMDc*ssK<=X0KBv?*_+O%PzLE;+#uoC<^)gD!ww{++ji)VP;m z^ty>;GK`RlAY2AgpJrk78zAV@S1peKtC=ZE1DLPVl3|EQ4hSR z2jyV=pax*|-vW60NFIS!b%B9*#79fiFs?OAe56P?KQQeEXUVYLI9l!jJxg=&&a0Rp>!2b*S+d_}}+S7PH4v&RXk5NbCbx2cxe}8~S>eH7tsR5t~ydP-i zE?*kw%9@TA;`VS5Dh>#Q08IlSk?++29`f(Q6hn9FfKgjwH(=w>$3Un= zDAf%JGC=2+0Im*P_bw2t|9w2_cLL)s6BdDTZXBMEZc0rDoLc>w-N(f@fN7i0&a7fR zFp-RY823CIlh@e&^fk-THE6?1bgSXyHv4xr0NT^uOnClnj8-oL&iobEF zBU-G$`XM9R{#wt1*p9h}@NNzm!~1#Ec`SL}4Cs7I`1O&18=YuIenB8743=`J1OzpR zo&8@wNA$mtJKP^h94qhPBM|vMzjaAcZmU4Q2t!UYEjQ~;; z87VABWmbHrNQ`TXc>5N|v*mv3qUAA+MFKp7rvzR&=B_&#&tHg~vMQyaSa+(7(-JUK zWBnWyCYnG2egZ%>)kT6J*8A-CB|We5iwPVqoPmk#(xZIz@AS!-)0tz2PA=xEx;dvGY{|9pI9<2 z0;3w*?pbq&&`yT{ZZ8ilxM+}4CX1lz^@>4$OOY-4lT_H5t@wMB)9>}^_@0T={ru6> za6#|r@!6$j4>iP(C6CxZfvb55 z-!#)_9vJBsth)j;NPxh>ytAByMx1ZEuNux+=!Wl4C@6&uX9zl&=0IdJFK{_Ohg3J8TK4P`g7 zQG2pOE8LVE?tSK`JE~|8vso6k76SU9L}Lar@A7~-s&Yayc%m2AMI@b=0(xd?=#J58 za;X<=Gm<7wX?(W`D6#1wXIXu}#MK2-izx%-o4enM&kvc`@rM^Na5v*PTu2=5d#Q} znzJhLE)NA%{XmwIpX(K7XrB%O^LPdzO$m6Q=Y&xY;qc(6V)bkP9v=eSHBK;j-2j*h zAY$>Qj~~!xn!gWJPU?q6Yyngp)|*vtau*VEK$AreUmtWolZM^Pf(jeBjjX?TcIRpj zhk=R!%?V1#`tPtrN1#JjWQ-HQte)uHb>9lG0sA=ceh&|Q;C_>1mmZAF(U>2ROu1d-&2-)v}{LqmQ7p9Kwn!&1aA~_2&xj+1YT=_1|L?R zeB$ID)BK(LVAl=GfgTziKjJx%F%%|s!O}}A>r3UO*7@oOFKnb_(Z@=JbX20;jHvlX zp$Z_A)hQ>$KfD;I0@;sXlx*#{+|_^vq<6&DPR^>h$xwj5|3DdV5G3$9r6BOihqyhU zr_(eJ+r57~Q@0x4PtmfJ^9nmivo%f<8K_Pjki%K0psCF%F^&NGg$&_1WAVTceFxy1 z0H6v#6pVX%T+a{C1R4-bpeXw;&w#c3SIWpEci(x<-WUelA{CwHXx+xSBmk6wrsKq= z>h-iCo%CipgJg0CLMMVO0c;9jGDjQGjgNB{dj1sE6dSY!l3nKD)Yj|%7c&LjGO}Nz zqNjL|r!w~8Df>J#QGe- z1jcLAT(Ni>!7&aeMYMlXATaJh%25;|9<{vg1u_pDeyqm*#OdezNtTeW4jh>Jw{lb8 zVjgi8t7^ELxnJIylubuihcrs|-18JP3t}P+)O^P11YL>;;h!&dymNUKIuGF@vnRM5 zq-u$o49BgzI`XM-Yti@Nj;Q=n}1U%EgE4X141M z@j<_i1p%_nwDa$~dqi@F*xb*89%TVubmkFN>nWJk2f^$QO$u`SgSh~ANq7Wp`r?1* z>afzk9|0VD)%H+))i08JLwfhKN|QWjN+L4FSQ!3@f(B$&P{RJdZ`E>N(mo{LfN({f z0OhF`T+||1M1&bWPP1s}wXKYvA}Q$!1>XTkzxI<|j%S(mr*zTB9;lfWoIZHQlsj+B z?aNzZWY5L)@Pq~H)S`Zy(U~^o9&jsOD^XwKy-l@FmG|Y997OSP8E{--dVZq4p*IZm ze*3YKo{)A5l(Sn=a3A>ymTgR(=yie)(i{R=`+Uep~k= zk4O0#`KS6ChRTFakKRo9Ynn?)ChL6`Sv7?QPi}RB+cuQ2a=Xi#yO+~gM6E-+a~$+Q zAms~^QQ~C*MT4cdg{kOZc~Lf;(ADESW8@^bh0$=*f9gy{-tDtBXqT($>NvL*h=Tvm z0srk>(fF#E24}tIoVfsZ1_S+>yOEb3oBpi!{;iz;vP0|21x!v&`R{i{>)Ay~enTx9 zpAV-S9{gPL)z>7t%?UdzkAlJzHz6E%x99R-gTi0Dj!Wt34AjO%&!O2?7dNO&O7!8A z#F~5&Lve>a8x{{y=M?*2HT%-LRx??TeA|MfML&X!EknXyZU7!L;?XBD8)dYO|3I6eu>3&-meF*9XpV=00 z#yuwug1KRfh9WSbuR-x)=i$dGT@G7S5?6XY#G)F`zbVc?H^e{M*u{apHeBx+%WCB? zCN?^=!Do@AR5=gy$4w(Au>I&)!zw{w{3jtr1{zOe)!;|E#yEZ1Oe=3fOJ zz30}2iJVoSpXOaxb5KmR^EQuD{1pv|4Ksy$wt-g5afF{Lwfkq>gh4R!kS1!&?%|V< z5u?-79j|o+X8KIi^MpPn&I|3d{1B`>~bOFzQDV=$+P?tz&T~Xxo3u8-R3#t z`^C9m-~s~$s=U(3lWk+k?3=BkaRz^;b>@tf_|;yGNzFU+vF@^m2dd@K%kNIg7wr*x z`0f$>2sci^f)@=K)}7c^EbN~Mhb$N2j^&LOjyU!7!3K>_5W|1|7Ok2!<42ysMTwzP zt7&W4e50LD0`QflLx~Us_JMo)d+#q-!KtoZ+=~sx1%Wocw2)VW#8__aoD{zUk{V;!&SLe?~e^f%JC5;eQ{_TP@GM zRra0{k%VkBsZq~)yd5!;$1FdwX;ZeJ_Hw=Kr7Ot@sulRi3o;jZ0-x^|iUDW-fH_;a zH?yy&{2smb7~^)4PxPsgGsb+UnIUM_@!=_u75{J*!9FLy-xLYKKd_W@ zzY^$_kv?xS@3B!SxANw&Xk*faTy9-2glhSzUVbSPK z2ji*~_jm`C@&2$ahyQym5&tQLjr?$FxiV*797v5d8n5@nz2om$EcP6kFg>4npQ@Ez zK$S7*F!bzS;I;pn86e32sSd$xMd-P;J(DHm?sCm3WaO~yW?~F6>UO8Z`R|J1=Z-Ul z<`HSN5sz5eB%%QaCszK_sA;)}vGVgj-{pB52a_g+PBpsSGsqcwJSmh#*)hIdx2)s9 za@Ou*qK$T~8^QIO$rtdr&vztUG^1wl8RIj5+h8w0NqRRcpH{v$7=?S7h`z=LKU&t` zm!RKpEPGfOH(F-Akn)f*r@bIK#!X_Py?D4`(zP{c-|KuKbcGC94+Tu6k2l-Uspk!y z5SzLB$zLfhmYtOjrFJuqP#{&y5=QLi1FJXS^&!a(XoWPlLk8hJd|Ii~zpa|Zl z$%pH~1;zT$#e6vznz8~4nv$OKM0w~>Ow`@s_+@PpnhzYg^V9N2KsCjJz4Ux@dr8~* z^G-!P_E}i=FBTf0wo|}*zwT|}@iW$fj3A-4=}VwVce=dB7X6B=z>Z1cDXl3HrQf*JNI9yo z@`lpTm6?NGiiuChwb7CM!YQ6Fy!=el`FwYP1MqjQRx+H@eJ+!3r)YF}lWlF6r-LcL zAx`mk#J<3*m2#z`mVFJg`#rGD}eG8iQLuwACI?t1$OHBGRKj1gTLDC zRak8nm(kAe$&R>79&IYGZS1@nFXfzvX}c$XHLrC*nF)>c=3Ef*>)qT?w@&1WN+Q&Y z^|~Hw*@QF<#6edn5nABK3c_JyVUL!Pk){bFrpGax-WB&RbB-yt^}euqd!ytY2ybVd zhpyDC6pPERl5vhOK&d_Y#TtrAJS4z8b-8+6d4(@M*hZx*(kbW7&wpV&$ZsPyB<~E#I6r^js*AUwvUvhIpPVuif9-K~jT<|WmkKHd9x5*nSO9;_-F)cdq zNL+Lgaq-%?`UVuP+EA+m2Jx%6S+f8cO;6m8yJMgVvOYYGsqfPtYkfh`k4>-5Y3xOg zys0Gzg6P6~(XlAOz(I>va6jrsa8io}2=G5wq3^Qg|5zd=*I@ zgZF@z)+cqJWd1O3e#sTCU=hY`ScIHl2G2akDUE(&`KjVkKsF+zou{^dL0^Vz_n*81 zzSH2h!MCCu#P`bGs((QRl&37;!9N+Lw3^bhyu*#DueB(DYA}5}i&!Obdhi|>$8FsR zFlsP#ifK8!Okms~#515jx%mT{-ue0yg~TJ^=rd2YHA{s z@bZlsgL57nt-thfUrPnRW+5nDn~aGa?Ay4f(~oCb97~dca{+sq{j>J~YeXP<^=J;Jcp%HU}f+7vy1quo(614J&5>w=D#5 zeNHMo8F7Zvp$Ga)pMVFk^$A9);CGwiwS2E0XlBQ^maoT$8?0BRq8Yg~JXY;SYx~zM zN(+5MZACV7=F3nE--4%H6TeX|yc!;r{HVo5A6^Oc#qWg#)^PS73P zYbs;FAKer2h`z&GZ4vB|*bw+(^(AWy%e2qY`urs_&g1o*k5^7)P%t%R*Bwt2b+` zGm6IH@-bYSDf#Qe_g5aE9KL_N^u#4rbJ=mo8y~tn?Fmh%hf+DL zllXSRZKA*!A^jR;g5Tf+G1F~QqwH3v^Zp8;O9E<7Q;N}t)(|L!D&9@Hp zy7HUu#?g*25J>0|_dPT}ec{n*L;Ty5wHrk?M~vbx=L)>etMZvC%EC{7BwDu-M>52% z8K(TQjCHcTZIVr2P8U&;Mel`j(~3vGx;|?z)wqxzC1cr9GDY3F7Cg0N#w(=hXceVW zHqj|hQvQlhmM6YUs)h)$>__L*|9!yC0m{1ueq|!DH+Ygfj({J%ot}`UIAfEg3d%$& zbl=zQD<-_zuk1-jJrNd{|3<8Gczs+sdT|D}>@)GZT&U+)vw8pXgmX+hAdp_9E-UE6 z;LA&Y;~UbCO^7F8MomXob5wq&|G4kl@?*V@1ny`~!PIR%7ku?1zOYQ04)j~UAqB)= z%6yk$`M%BdQ$+Xs+&9{Si0t8xkg-pKn)WdD&5`0))@Iu_dJhcuo4=H@S{F=v@0MNK zT&gl4enXsT^obDz^$qV&?b7{ac1NfmNBOKjb5>l4d3FwkX;)ft{$Y|B^x99`d9f<~ z>QTP$+w`L;Q?z-K@1*v?i^M|X9@6{%IK|%4uQ7MVuJ8A5h3FTQ6#7CUyX*UE*PM!& zxd=;5SE=&2Sjh(CpY1k^U@c!h>>%kcE4Ss{ed-JPRhHx>cx>9YS~{Dge|*IdKzP62fnvV{6K4=3dU~er~^bqkUROQl9kEIT!@_kjNX}Uzz4pq1IYgL%6p! zL@YdupFTF|sud_#$(!}EUu&H1plB`M|MPpcBLq02px)BI{KxO@c4vd^*1kZVo*;+1>4=w7xQGR7rD>;C*q^Hzl&u8ss&|*3snyk2J19hLq!}L3h zF*v@U-*nk=XT$ZSYtPkCtS8gnmkSI=t#W+98@#JeNv---Z6o4P!!A{FcT&Xap|PE# z@l)7ArO^y{TvN91TL0#XY@K(I6UR{S7$%vZJhD)U)ul*B`RRMC^eAwW>y%&vFSt|Z ztx_(9^d`-Wn~9lXoT?;83!R+Znv}SBd;>whSu}&gUn%Tdt!#605}c{Xd=oY>c|M=V zSz*h*M_xdC)yxA^IaFD3WL$yNZ-1D$?J!-Zr%9SAsVYWZ$Q4;FdRS4*;hTMZ?vQPR zZZ=$(_2-)_YNgb_yz@HL?2^fAo{g336GK9#f+KSK9Eo<-IH;e{FLKuxOwh>A< z(lWw#&-)MThu!hL?sKm5x!|`*oppkaZh)_Mt$7%}e&qinKg;&p{Efy=A@j%QVLzqc zNKJ+uF^}*S8$tn=Nf)6%%?EZ+XJQ|~-Kk%GA2~1cZ&Lqa5L&w>dMkbx{XC1GcqcYL z>$jSi%NLin`}rz@wtYH$c1_0C9bKj?%1uAyqs2g;pH9!tYYyczafF`kMjiExWBCU& zvP%h-B0FmLjLg_Lmuon^?N>@V(Ep;>er!O&n;V9@R*}^uc26d-C_jqow+cwe8swls zEn*?(ozLJ~Z#9Mk{#^7(eYSdLE z^vzh4`*rP475_MlfumeT4m4lQ(c*DTwl3COR>!upCFg|D4kwF{ze6ARzh4aYyyjjY zzn8WLY>w7Xcs$5%bKnfre_tt(FBAMHt7^6YqH(ug^X8IP{L{iLY;F-6>}=#0xg=$E z#Y)|(7YvjJm3#fFGALpSdQxN?fS$LRkv1^kc^w*j;xt2++`!{5Du&*EZOyLS2tb{G z>3v*xD z<0~rXxKiWeDLBND{bKJEUgxF7vbL)CA)g5nUWl|l(O7l9cgY!s)V2boT}}YkJYahZ zcH!=Q{lZy1_?8tfYdxw}FHaytv!AZ(Anu^>u> z@&aM&N9!`;Pk7lJeM@*=%28g!t7JrKE>YEG@79{DGCTyTBBwO4C+JFSog#V%8DP3) z<$K8N`K(=3V{fADr~pQxzJA5bsJDJT2SHzo%B8eAM3Zqgf|zQtkL~*DXC2w6QRZ&l zSf;eMqTnQ5Fv<>>mFdB=TU5`uW~`H@@fa~OLHZ=m(PTVAJW24V{} zHbAdmsgU{_$;|g#@_xytayc_vRiexxZZ}xan!Ni^`q)|i z#4xjU3*%*0>C{r=Hw&pLiA4zKL#{eTb?rlUWYRfdrQtS*zqAs+66%7iCuu!y0&KrW z>ht3?`g#%>9e-RT&YwQ?`mQ3Ucg4BAPQKtGqePLvzu;SOTrar2q`KPG&GVZh9jG)z zw(|&)Dzag7Xl%l^WbM6HTnSD`SmXs8;s0&4*TxE1<6UuQc1O5NB)CqJ63e~caZund zq;ab3VU-f_@1_^fg_EpOU)gH_>tT#n)*hn)h}!T7W`(sq?@mS4CyMaX_rce!JV@iA z<}0Pa72W5UVuUBU{Ca1Q?uf#TXk=2aJy%Xm@V10(YXyHxtfs_I#`w$Yw;{Ag~y9%){1<~zm8i8vE(GZ*Z8 zBx}DZ47uo4!S&lh_tGBgu34)<{fukr5sGAV0KGJgc;}bwQzqfiaZ+Lb6DOCa%x1<11z&#>cnt&sxOz8gdX#M`#N%5-c|V<_MM~!1lbXYRiF;~t@?_+X?%qmnT5l5>`<13>{pWDPP}Hk%r}DB(N8TEY*>XMSMNn)bS_I4N zw=4DL73GmtOP_}{`6HIQy71bpXx?u#6-x|!RVJ2X%$HqXnElWLmR~RoB+nQs)I;_i zDz6huROgNhP!QuE?E9glM(=S`rVHhh0b~-PyE{KBt3`B+5^PEjhR;yiMokc>^OobI z+X$1Uv~6bWc(bMbub&^(+Tj47p2 z(6*ZN0#s#C5E0>a#}QSo(8#1<}aW z15e#|NJ3F>Ai78Ke#YavZBtUxpNV{4a zy1n44pfzXxcB3U;%$|ocpPMbu&a;z%T^y~6uS6qDnihVJntzB!od*~4drp{^5 zN_-53B%_X2GL~;hdx`z7X(fwnY-x5$ocf}eSvA{Trn|m9Bz#_o3avzR!0)&Py4YbE za=;(_MvuFviNqj+O3>kbZI3s9=%3`Y_8SVC3B=&RvjGy?tKx% z8W}hgx3!Tnc<><`lC>l>qnWOMTBC_6j?#h=Tl+r5L1xnnqa2OfMJ`@$%+DagfKZ)g zw~_&gTc z@F&RqO)yPP&ZGQ7nr>z!PpX=o>(g@0*yZ6gB$8}JT9o5urvc%WnfH1~?6Q5IhOxeB0-|Ld*D@!Yx ztbcZ!Eq3hG3y&U@%?P;Y`_g>X;Ez^wpb3;R?a=&ExMRma9KD0+ien*t*YTcjJ&?l+ zzeFDJLbgf;JAWp*L+|90k`0%IpLD&ihl6154tNyv?kCWt1I5#bl%v@5vE?*!>SVRDDL0A5{~0|!5NUs( zB3LqLM1drPGo<=;TxG8klU`RAOL0a##P+%~a&8cd&{7_*AefOtM2A36 zjpB>Q@>;w0E(DxTzN-bP@ee)lW=zM~R5;lX{^qYnzP-ut6($wM`u9gaCgV-I8eh{6 z$92SL`Nx&2b`%fa2X*MmHu?R04S#f%`z2#SiRGm!Ka|&zsE`M9uHtOfr=)Pv+{B;+BT%cViJjlS{2U z`>E7|1R4Q$iWqdANJn$=ZU6grwhS-z2>fnR0`}^x2-Hituw90tCUNzzN?iVk^KGuF z-BNaB&qabeT-USWHy0!Tod~8te!GlHnHxqt0+N)Uno82TbkViH5FBifdmB;>OlQLTeL;bnz`uB3|CVI<YOY`Tt;_#On*Wuh@x{!0# ze@bkf=m=1;ifh^?p6eJXLUtq^A;+$WbXnoWMgn<$oK#5wrV3-|0b^5vTCH0H4{WBf zzXin3$b-uTldsSO(Xn~{aDIG3fAv8o6j5P$6n{D`&M%v=0>;&RFq#KnHj?TzOZWV1 z{s z{o07CIv;s?X`{qmJ_dVC;7@`1JF19V;O>_OB1UiDfXw)09S`X&x!)?bE(~reM_XH3 zO@`qP9&-mxuGkPwsS*}pLo&?waZy_pS z+mCqwT|4SBalYUU4%=BIQMF9jDI%lX1W25zfWZoQ*9c8&mA$qN{cq*@Y4`{HSQwbYOyp?+=xRNvZqzjV#s-ht_dK$>(M_ z-4HMc&yRDV8Gg@HwnR-YfG+p>9g0bS zTUKeggbF$9-xkX~h$8wPorvsJpv6hzDZGEvL|e8TJk0`1SjJ{e52->O0p|Z%H)XUG1WBFWoPU z12tQqGhzkJmep)qqe-qYT0nhReO9`($U(GsZ8v_|FqPM`lThUcIT?vU_T>_}{E z`fpIM!|>$IZ>3AODEg#%?g}S8uizkCyKr_r@r8}bP}I94qu@F0@r`0QXua`aMl4|^ zjpgq%weQ~k3CbP!xs^Kf%iu?w&9;zqY^jN!NvGSm=&FuSF?SOjHCyaFC)@7m#Uoqq zT4Qw7`jpg6XT5Q!1+wMlELodrQ`l$83>c#rzyQ;$yi>r6y#=$sA=khKeQ|3h09SHa z3SCFZd?`k@1sJsfs?7|TIcS_ac$4pX3tjiP=-6FuH`{#04-dcN@RY{ExlG)v3MWYQ z228n@1c*9rE(|d3gV!XExu0{hmP~?wjvL8Ww!|JBNTB_?Aey?c+`IN(j#N7I#d&y|~8l=!kuaou+TlXP2_eej|^PJ_Q=-OKH>0Qxty{XtLa zGG#mT#X4jiUB_<5)g9|Wiaj-38|8i8f_okZ!IA_g+1+zuyTNBuz1`InK~=?He&xbk z3havaPMZuBo$qrZB+!+CtWcm(jE?@br4t136UxZdYG0FZU*C=(YcM60py;qenH;JtE^TXM?r5^_AE z+fz@0?2@`Gb|5>-)NA;_Na1KzXvj>Hm&cVE%W@fVn9!zpYQIp z&&Xmv_5WB_F(J=)9`cxgbfSs_ahTp5LLD!7rAk~(F)%;c@@SxDbPx-?1mkFOQ$~GS zYkxs3OgX78<=Mlm42Z*nfBN~3KTb!g!b{r?u|Sa?$|+Bs3U27Dq(F@+E3Hv4&}mCs zck6dxGrmIkeUG=I{((%S@vL>C{D-2$ z5i;XB7x$Z>kch$FlEAktdA!ziPk_|A)+>H)#%7#hTUaD@@M#k6_^*F<3Z-&;*o;w@ zM~l;yGw#x#-3f&xEZZl36k&vWsJ+6Z&GxJWSnI)iZmJ;}Vn(am$Hqgm_==((Rs*&@ zSzlN!pJR>lB*}ylR7K*){I#We2x(Y*uGY`dX@*?^+y2V@#(Bp&0pntur=9}o&PPaE zV8OKsPx_Y?A6wp3+ouTZl(*ya>jqE$et`ktqibA{uKIYt{)rbV_wLPbwhMu7m9O#NZqC?AH= zr+-L)Hq*yAwJn7mwHoCz==|HZezh<=BUO-`-+FHL@!LHKi80!%SdMK@s6$9+9D4MX z4o1n~&Ri4e5a@;3lI&VmDflt~YvA1=hJI>lL*}80mIu8yYO;` zr^t|R*T-j#NK{m`9P#2XD_-%5Z;TY|-5neCa5ecTkVmXcR|iCn{vhLge6mGLad8(# zg^)aAKyJF9w?Isi8d*>)^z@~nIfOa*Gieh?TbKM#GJbvQx&BQ&66@BsR!6o!OZ>)Q zda-Dy9Sj&FINw&H;pR2y+{|zK5I=s<#-;siusF=6b@->*1HiAi|5wko*QOFdON5-` zJNRteDVK0y;p9U^ndk)-QMv9y?euev@AWD0s*7bq^E;DdPzC8q>E=uwa^*aD)$8@Z z@T8*e)U}>b+e8t&O97fkqW~F-fcSjx8`Bi;rvsBL-hV1}(GT*?^Z0&Eat3OW^-=lw6qsWsH*nZCdht#sdvCvh)ucl$Ai9ux2k-PLET(a0k!bZXxuq}y1} zpz@Puziv}%TZfZ)9tG`%;{4ibf2!(EFUAYG;Dh*W2i4sIOnuPz*T2fdRz>scG2Ov# z$M=Si>q<`v58^r;!fO6^iKc+yppM93g^0dko8Sb@XAhTK`N6oMnyACmrTGk5nri60zF%E zi`jplf0BHIr z+s`_w(Gzl3$7-!}jNMz@k1=Jx*SAs!QzNw0)}NPb?(aQ94;;G+`?hXWYCY5Woia#* zVFnPJ33F=Cb1xu5qgrdssL%@W1UxRcU}LuX`TfDD!3z`2K=D@Ma)IYks&P*#Wjc6?8F9mx3M&l~L!Lb1!~ z&l|vvI;(WmL(7${Bro)^vjkcUwGLMJS?Aw={(hR`=F9%qW~0f%?TsJB7iP$Sdq1c} zd}Ru06;KX2*+;fM4j@tuo(#(;4X$`8evY&YuH6lkDsEbi$;Jvjft+2m$`bXzy^tu^ z%Uo&voV{Uv&*m@)B3zMrexAFRDz#FgLPv2sHk`8L{FJJOX#i|+%)PtA$9@n{P0)kd z6n{^1DzOoHc~JnRJx6KayR_FM>b4XgU#Ssv<4+L#DNtO?29D;ITYl?)R=A1il^IsA zb%Yxfloxsa-Ym(M=7zb7E0c}`8#gtyw8(WLh^nCC;w^8s+F^xcV#$OP#jog*&NvPt zlva93hRQl;NU#63p#y38(uDI1t-WOg0fLKz-}9e(!6I0&>e8{*|L(;Bz}KH-2Bnrp zIv`~k4fKQUEbAESZK~DheCn#BR)7qbicX=S8y@9-5BPKMfjXA~+Z06JbFa5wS^o7H z?cY5TB+F5Ba94wc@0+ibUZPuK8xI_%(S9XC#1EB8oyG6he6UiFDx0r)uwptii?35{ z;5d;s+ZIbRSm4U%b2U=JD$vE!EG_cn*N>DzWC-u?P9~^D%51OqqeAgiYlY%C`j)@S z0u-W}c54rL;ZahjS@9j_5&=c^n=72>4K+TyGwPaPeO>MDqbVMNK$bOO^clgh z2R|tYYsW0vDv%2=WcRHV5cKDJ5BagjO3O|>J6augUqA_(4-0Zmn%djT+?UWIs%tX1ymJ)YZBhY|%__b_l!kRj%zhYBZ!$=wn8^=tR#=^W(98 zOtGWEp_dis*<@S(WPP|b22MP9U^0BT3w^izcoWJ0ys1JZ!0nBqqaAfPtB4d4x-if9 zr^){6TJ*46(^(%W1=TFk#TNhu5;j=PFn(z)cX4^d6Shy2NLr{DD=i+~$`xCKRIMXl#L zZpJ~1q`l1VSHd)zfieU%~o^ZAT&Q2nDv3|3-{btg5YxMz_17c;&Y!FW{}p9z%= zx)jj9w!)zBPV<0BmP%y^soDPPE22>O(Fet4C#m2!Pc@^xA>P+OtQr9ud;GbphpO4T zLI!hH6FXW5_0Xm$$RxxhV951{R^zX+k7_}f4mza4gdsNG^N`ef;FbQ%8K;Y(SUs%# zb<>QtWMGtz-zoC%X9;eQBMus-4?6u*az@6kG?b{D>DASGJgnaGsOa-@fdQuLAZWUZ z4A0*!;tbUC8lPDn@_+rvu-U*Mrue2>taXLReot$?1sFQT!qhLf`2El?qHLM{A=f6` zcOE`XZfDWTwYuw2Ocq4Dgq0h>EfdafvR0Rvpyas$&m8Ek(B01}U-VRIZ#zvK$b; z*;{DxvdJAkAe*-aMONSXhecYAJE~^zoH>EzvV0wW^#dzm7s?l zp9CCgS|OV(&iS<;*&kbG?=;T@o!k_218lyf^r5i)npezU!Prd3lcE{WZ-W`D$s;9n zPW+BGbq6_6%_@2$?Z>l+(487q4`<<^Xr$Gk$`={bTQ^uhi(-}g=v~-SJU;0<1qrTYZ0@pT>k)PGLF6-WB+sXGb@Rx^b&ngbgZ<=0Tzg{aK$WQo{aV19d> zxU}Dm>Vf)I#HlAVrt@U8?Jm&xbz}JQ1SPBi`{I;07sgKSyipO}3=;J+bkHhlNdNTX z=);iqcyB{6MS8TQro1iyx$xE#@lwp=vXZ2`9KYp6s1!jmXx05M)#p*ELmBMzE=e#G zK8Mu#aNKt)e(-Z4d!OpfijGSTLy>JNx^J{p00Fg6tZRg%f(ft~R)IP;Yb8wJ zuT!|Y!tS-0;2oh{)0ViCf%}z$y=`&f0gOma;!TddK#qW}R^|{Jk#}YhvlVRe#6|n{ zt4ks{3te{5$>n&6y7dhYXaCrmWXs+jRa1p^(#ttt*5s}AicoQ1p)|!hdgN@~izt!c z96#jmJTT8QswqL`1U?z?pwDmHN9*C4sBj(`yiSyw{M4tP_nU#O6K5YnQ`jHm41J(j zsI`K|r+l2XlIV+;7zQ!OSsUYnrbiYA^dKGP|M4#ey?onrq4hTh%`P$VOX*mS!zN?6~=1Bwzh^}q4uBJ9XqL4j=pNg zVF)0|#to-f|5P!!i>~7R!nEqr(gVF>ofa=KX+T##%=7wm1W&0PU z{vqASNW*ja2EBCkgHiX>7X%-<(OE>O`y6=5AI9~aD0e6qjm^fXJ*@GZem>X3r*?2; zFGVAxahuW++)#Xlc#RvtEf};k=FPfXLf1~Pt~!VygZ^Y%c6Qyj){A%EZ}LMr?C*`~ zfU1%IBynYWKS}=J)S^#J!d>LV&PxE}?-BZLp6&?Y(C2R%&)QN&{r3^kTYD4n`vvGa zooicMT2`U1@0*7`10EzvmAWYgNVMS$cZRjo%IOHn2J(43*fllA>_<@;yo2x z(?7^j3}L0E*(<+~(-72iIWbHXEA53vMO2jg4e0u35LTL1zc>?Pu{|4@9S5SDHObP% z)&EVr5%I6RVrO^SbXaE|;)#_cJ_wqMrq_*bC?+CI>5lSH*tE>g>z)uq?mR%ot zU972j*6%c1ngDu0BCNmp{!L%mr=-~^&|ySSkd~#}*{Ny;tc`*f67UN^1^MudIO`Gh zI?6R|E;;(eVrm=$F_mXsmYc;d#%&k84h&B%Bay3KpNDHCr~GtIbx>e2Oq2Uep-ZdV zgvhiv@l%a@i+HB~Y)1yB*IfylqV`-A{k}aq+}3tR)`~CDm%fn#@wGm%z%o+0b@LUm zo0>4T^F{-UQp}Z-fL*uo_S_lx=-ug^-^Ps^9D|P(D9LtDr;Y#EZ^`5nAGEf#5R;C- za{QCi0^q^BImYZ#5L5ZTMwViEe#1uWUD~VG&q?0G?3(Ih@pcw1%-#2v9n)1{uy>oD zo3*>OC~4?nLZJ$$1TJzKwf~yL^?t+Vy46xTMrYB_$5UoSuI*l9@fTOpKUlEXuZ_}B zS+3^_N3+@etcG9ZPBFbAM5I;sSYqbN4cPs+ zgt{j9v?wO#ckbmtI`D?(=VRzLOQ;Jx*IaU#E@;~v6x)-LsL1Zox_%$6Tb;p&FHtRx zE_%7I;b~D9nCO{&qC!H!Q3AG_1J#5=m--floJmvou7_g5Qj~BawWsI<-Kd_T_zwro z=jB6)VGtP<;A7tXU!-@gMZ+|Z=Ep8XLOKEe{i1GSW_2|7 zvZH4H(ZpjYk~EIGWzEO&kqdU~(c=9DXEmbnf>=tTZc0SFkf3;*ceN+nqa zfK%PTG8VKc>PM7@ocz56(|YOS!1+}+>wZYS9H>C~iDZ-z_I$}ebRl|6Ac0+)6#?tz z(LC9`;m|`SD^s@#{-^rXP$9T)XZ2yCJVb~5|8l5nvMmR7;P9LrlxQuaB=cr3Bj@Nk z#yA1`@bW?)5M*4{7}4JUm>tGa@Px8DAZ>HbBeNId6z==k?B#1O=qNDx zD}q-Vt4K!Uh%8H>tU8G>y!3Qi% zzpUx*2o9I-lc!s8yg_^;>^OPpkY5`+*m8qr5|QVM1d>j9!6lSbk^Y=Q;XAJaa3IQ@AnApbQYaYvfRZr?@UE$ z8B00xWFk6q;L6KH^?u!Lr^YEf>QF?o#mE%K0PlK#0FM2SP zVHlcLE}=D|?)9vUO>J6FyvF6O+Pohr?>nxW8h({2m+wAmYc|gP1X*mFM*1#>&keR* z{#xLAjt+0H0Hz|9-JA`EYhA#25N0ZN8-CQXFSHK%*^8$@u%m2$B=dbrbF6I@VftoH zLpT4L`mGu0?0K4Q%lp=-YmQdZ}l9MTuVJ&`>jJrLNipX0e{7aYl z!{ctuXby%nb>L+XDS#P^NsEp4+5PbT@i%GcZ}I%V^`9z(H9bz8=wl`gA|<@;_RNF@fztPCnh5Ozbv|fTCTrxAN?1WGs`i`)I58lZYW4lu(21$&2tS=vq!FtUPJMT0X8`aIMyqN#`wSKPYj}pmO zLh^A=;RF4eTZd2Of-Dc2s>_Or-96pwbpg`{r{@JBA*V;>Ey2OZS^EqjI}>I=3i!-u zk3w_a8~}0ta2XJ+JE{%x5XLffFy&0;ZeFg;nN&LnJShd8S(5s?VT|pRxYuzYUD%b3 z9Tpi6R{J0OgQJa9+ z8EsCVnBA$PE8*I-Q}HK${85a|`oVl9W4TR%kcAMcft>89ek&|{Gkbd_#MO(Sz*Rs?ew|QnrA+KD_S%5&B}l7Rom25S9&UC6U95Cc9mZ- ze%A~6xHNz%rv&8nzDU#mXH(scZ3KGtJDTcyC1U;+`aEATQM}d`dVZR$g-*R{pG1Jy z-%3-N(oj-?i$?!ex8$Ui!LLr8ZLSHD?=N>52WK~p1+^)pJZ(o38~Xz7YWa#?;^lvm z^el6sYx)MdNVH{GnyB8jeW<=tw_S0_gqG5H7~dv-Z2K{G(?Wj9xa6YuEtLZ;<(Qa1 z*R2_qX`>s>QV1r9NQ8bq{_=e?gQT}`w?AWi+W{Fe=yxoi(u?w^C#?w>V9qV%n4Jb> zwjN!pPPni3v8k#AVp|POK@^+~=_%uELr|Y7&Q*BP0zgDf+ngtEouS+C}&>EF`PM`-C)J}J>(o^LUhUBzV>lk5-v{*d?&C<05 z9cH-W&~;#=Wp(a?iT4zf9gZbbc>SVz1OF6}uNNAJyQsT+F8tGhnmZv&kmpeW`>rcV z0jXvZU<02^C7d+6Sm35_`CrX3H+FJpzfJ5>fld4Vdh}z$`-{oS$d|QmaZxhWWui0r zQZDpw_OrG+ch>nh@YU~2m8PGCo(a9Eb!{^qg3KMH%Ur3>K{nPag|UB0ca6?unsNj`KJssRs-YZ7(T! zV_D5gjcoIuWJ5eOr%W16el<~pR<<7Tsdf%W(y-iL%%?R}O?Y5^^z<;j*oFgL1OIs8 zGRJK|)(Y&TsyfMD32Dboce$dN2(Y?DBf?s1{TN{M;iBn9H z-aXop$M|Q3v|r<@?*C#IOp;lmxz)n~L;XSCryRNT4s8_JG3LVT?A)-6Rw~RBxOL;b zBKv#84g+r~G)TYY>t<mGOjnz9Q_+W>5RM$q;{x>>t}m{EV>lVr_H%* zx!K0EQH5N|{27&D@v%P+R00b(9sR2dq`ArAZ z-&}0|G_LXjrQtvQjY^q~+FUMSqpbHZ%W>vH7j_2^Nk}=jX>Ez{(tm)zJ(2qA(!;qi zI#gAFuh^e=l9YP|fW0?wWqNuyLtcOuA3MNKKe&BUOp=qyiGC^;%=mkLr2b(>1a$4G zL26#HngP7uV#yxzb6Bq=4(iv3~sN8V-S;=avE7N^C%$yQ$?~$rr_f zOOSA{X`yV%t9#Yq19Zy(Wy;GX4zP)TRUGUYH*9)JfU*UIpA?lwHnwvpfPk#lhlJXm z$9ExgLSRxio>Lf`+g`6dfuhUOQyIDxUlV9M@=5iRP%o zfh9sJD+L}(9h;g4ZMS;MqonWnz$lq}7EX#DZHN_IenYLE8(rt+Fnq1Mohz4?0#>24 zMVDU_)E;7!X9g07bZ$39*ppdUOWH}=zW}*rwVu5`7LHDK-lC4)wvj^kz-s3KWTYZf z70>@e3Pnk32Ix@tro1B@Oi7Wxv=ytq>vMx@>(scbvi`0P>w#FDiQu5H_E4cr_UV(tMclER zby2G%%HT;N&%WT*!yNi@gvl{QNbt$DMA$qU@T2vHjNK!)MhRRF@xId|oJ;dYsx{)k z#oK%8shvu`WOIT|uiK1WWJT=S;|P|#J(!znQ1Upol5la2fH)6|*|GfK3R!w|UNww= zy|e)=kPUk#vY!?fOkY>dbAp?-SMK#AVCAcAipfwNf~SI-s^zn1CP+si^$rQRzGLOi zp7Txk2F16VdIRU*J$W*?1P~oV5vVl&^;{nNlWi#7P|w!`mR`T!lGs6-FoG>_J+US`=XY0Sp+v?@8m;FM0NYNPOV_s?~MUB;JD93 z+d=gsifyl3D-R<5Z9|Oih|G;I@X#|AwhmuwBdWuoVu-wg^j}=&psS z@&mjzo4EmRG=6=J0nxW@TjmbIc&|Ccuul@VWe#*0*8=MPMplvuMIl)wCDG64g=6%> zgRP$#Aotp*jORi}_*pqnSR)5tk)N!KQ~+CwZ~l(>y4#wGL%^fnHjeV%u zDm`q0)bZs*Z!8;}ZLF*HtJc*pWbI4__{Kn#$a&t{kG=-@c!-}mwvsI<0@ zWunc1#P2;fa|lNuW;^Q`h6=CT7V%VOBV*iWmfURThOoH9r!zEyRu?d{q7vaT!u9Tw zl)Qc~Tz7x~%yR9)D(MyXiy@X581Qo^u`& z9==@TKf7?6nSrAcc&E?IvZQOJmB|V5Zs$z?Yn;(EYr-wzqV450?e4gHm!Enkmxd3& zrciPf3_LG#AzmZB>&yl1WpeZ-X}I>snIYrRDKp-oO2)SXLob` z2Tamku71|YeG4#wvi`K3UCafKZw~s&mdvptJ z)CTM?gEs!TljhWBKH*CgVQkvgiuwXSypI}NJ{f>lboW%#9qg~a%(X!nhsn2jeXaZD zguA;D4($$hRADr|P)+0Cckk*h}`61{NV@`9e3(CSCVr*KY;?9M>5H2R3qGJ$#zC0tdZH znQSs5UqOJxYvo(d3OcG~X3>ux*RF3faEF~hat|T=SCdc95m-=A6%;Q5l#V=V5~)Fn zj&==4jqX~c+>v-Ad_nWZCp_N_OXys_$SN?3#@q5sq3G36u`!T15pK#rftJ4EMOI5L zkUud<=kd#nR(sM9kFC99mxhg+=^7w&;j`rL_`u@bcV_6N(W>Plm8_&2Hi6**U{a}z zT*IJJ*+X@4F9EZqvELX@{#KO)qKJbB55g)@3uOX3C4t3J zbNQ{`LI4I7+XwIvm@6ub+$ojPWSPZ3u{p;2`5&a(=WM#bofS<}Ksv^VUHgX3MsCL()5jmx3JGG)2^uM+N}> zp{So@oMNN(b3OK_P2BN4X#rpMH#71r?a%ogua66`{;Tx^J%)h$$oG}h$ribCd^j!R498@PGYlsizR3cl}YpooPdnykbHcg5-Xc!BMASx$v9D`LpLBS zizw1Hd{}?f!qWR_%kiqFe%=@87r00>VYcj9U(}4Lz&)cLWuq=okcml#pjok9|KAFn z)*C4D`S@{Qg;~j&0rVTOTc-d894H^d`pwSOM(GUEkx%b-u0xe=g*_uvrSWN%II zqz}+Idhy8o6<*o*vSffgu!mFUgk5-!we5WBJ>>$upy-#MK2H~MkHjkXb3WRhGwm-r zq$c|1e!AlE_2sR=BMC;3_hC!L>749bjK_4fpeGtUHJZVJn0OJ1Ns>d6Y)1nk-?@)h zPj%s`pn<*6OHCWz5KH6zCZ^C5uNUs)$4j<>M)AI*Pfa*dJmc+oj(l;PTdnd6R8@NOQkpPw1A2r%-Vka;$qyAbHUAimU&Kl zl<*2Nrp1!HsQQ-l@t4|DfDB;{S>aW(xTlcL-MSvIPB#dhg)c?rf&$s8m}igRHNIiW@wsVfbjrv7S0nUi{T+!l!h$LA;?I zE7R-y^ROhFStcXcrk@KxpLpcp4~*AYyzD^1s$Kk}2m^U}!jyM+ucCxTe%v*)(W^49 z?}{aUId5kboX^scluU800ffSx{eH6s7gSd{GQrT zzG63t%7CKN=@KI{7jXP=E2Q>h7IOLo*hQH_qx()ZS1OIq%?{#6^ZVXS9_h0d3Oth{ z0qf?C9(1%_5KBFScc?YbufDsn#;W|iu4z)WAA9M$c=ku4q~7@8m$)dWdV)}04CE1K zYeq%lFvDg>xDQrZ&Kfjy()_nB_U4P)veK+A*}2-3qqOsX2qqc1I4abfNx_ypcDx3( zFY~k|!!3nA1iMVBDjS~Mt}XVccRV$1il6AV#-Nbn6oe|`e6s7a8`(W~ecuI>AciTG zN!FS@@(#=j#C$5n zjt3gq-gt2PcD9dS(JvA>=jusy(p+}{tZ?$41!x@3KgB~ExRT@RXKvID1{)I`c5mU| zy&lRf3dDP*#(6)gSV4=ap?muhmtCVtq zVVsrYf=xoI)aH_kH&h?YE}BIOuG3iypnd$_9+me0Un06avmI#RN5Sa3q z6~%zjRxUPlWjc|=roWPz!@Aoqc%6z21lJ%n4`lp)-IoCTz5Wj!$cy+6q_{KdUtU@$ zS?lhQ3>ZxccH|(HFYT;7JS<+^;J>$9pnZe2?uq41QgLj?0X?K?f8#0#hN%p~qiL$9 zzgJ(8ZuYF)*%A(SHVq1vfkBc*{Spyc2jeZN^wls*HOZx@s2ERyAxoZ}?gwx#9^!3u ziYfsVuBe(IjmBBflpY+PCFEdnkd1AvwY)@bMjf0Z-b%yc#E^qE%4EfS(W4nCqU!uY z1o_n$XT5Ck>TLWKrByGm=v+N{<$+~@YT(^#t~0IG zrul9ZuIumlHqX-|WRu4^v7cS(xqkj}I!3VI?W27!yFXN%tnOT3TBPOO+=Fx7vr~4% zAk5EVw9U5$x{7+24DxXaPE~7&UD%twxlsF+lAy9v65KB1t1$m=i9?X?{RldQ(z|q8Z{Vow#A(P#{ z@mLcwVMc1ZQgPWoW(^xyU|qBzY`Lt6M#ZWrG;bYOa>fux0*95aV5*Q_Otn>CrJx%`SR z;8Cc6CsOdkADY&pD9Y)F5X$5L8H^(PT13jR{avI`iZlGrxmf##@<(%NE8ABksUsOv zF65dAt70yJ^ljj+SC1R(m*Ogfv*m}2xq2+6IGHe_Ur!qcUK56)gN!?mez;Mh7@JF@ z5M2E#m>KOXPlEeQeWqO}_SN0nRBr6)p^A!;j`I=(b1upA7-A>`@h;Z@43i~s|81aT z2F@KF2L-@?)qIcK3hvNRAtu`p?HXsx3)8_*9Y}8(^<*e~0p}uNAt%3t8tS$ng~fYL zjRvmCMay|@NCs0VM@jA0k}zVXL{0|SljVo_lK}o^A40!dH8s)FPj;JeaN>8i<)o#} zV4^CGoIw#syuHb-_Nj-}C2&BRC8u-K>)D>S4~*g!GPSZC{J#WMaW}r8O!}o<7Mev0 z|LyK-i|+O$w7*t38qa<{_)4i>o9Wcw><7GCW>OYwtlqZN5Og!0tWy)!Pgn%t^oEZ7 z#GIFxM0CyLN?r0>bEXd_J$&+&kY#3PLjWc z!(&o6L!2$4rk&_zgg()?v#;fWEZ@h6-6l%&K~NX>Z?N)fKKckM_xZ<01{~)V1_s?sd;eCp^i&Lg;zD(E%pyEIe8kdtWS2wNpJWmzXB|naJw7g=qb9`P9H!N*J ziTsLX7k`pyb+WuU9`-+;-a0O-FIpcyAPS0d$v$)TGWK&6qA z5)hCYy1NEcq=xPgP`YF2q2A5C_x;U3@KNT>nSJ(N@vLX9Cko9r6+hhnzMj|9+jg?f zg!ay4YjvN=;`g6^6gtNt-;Xe+&LBVWsvxKC@aEfaV7PRukh0NVbs%h*G3VP$Gp{Nienr$uU9DQ zZtL%b3iT8-HdI&H@$jq0kcFxpHH4YTc;yO^V+z^H=W|u!+-qV~?>IlA6V09me)uM^ zF>iuyU4lMO`#*w73m?)}%hiK|7OJLmA2YJTT8AU64^GhXF@iYl^pm_B46eg-F59Y0mtWq@@+;ZB_Z47ANjT}6#Ip8YHWqI8=n(f2$ zlzP@6Xm8`tWr=78)vY|Uom|8*|B6p^I(xVcIjrr4Z!t|dln9JKJLOF7Wtobrll%=$ z*)r2e2nz>6Up8fTclqoU0vZFTc%PbxUcf>MAzPv?M8=s;=evp zA5ZJj(JERUnKweS4(HEX+m$IBA7sh%wea7XM^sarzBQba;15m}*`7XE^@MMiHCD9hy(#N`op~mo&=0IWSNxVoX_>CdJY; z*)~N1Cwgu`gB+zYL6|%?KKSCKvn6_5PJUH7{30FbNOI>!wfxAI;oU&vVB3h zzO^fFl)Atd*Oo=5rtCghRk|XY=V&odv7v(st6aTbP6a$q)bJk9dsXPjFhv0waJSM^uRFBHaAFSHa?TY(Qf@!lDT^)Dn?9}j<6;z=_v>Kae7`K7Q0aYZ{)}8cf3&_yRkH0 z^IqfTmO%FQ*MkyvRu-eNZkIfC9uBY#a*#PolJW6E@6h9(nv z`Gxh56JxM@$P%l~9T$q2!eZ*xf|>V&yD@j>6(*~93m&J$a#z`?PX48au*(yU(_^Bq zXs`K|$zE|I5T|t3PeeoS^wc3yX~sd9h=cq3uq-K}xFyTa^D!u@YK4*7{SMxRr~sr>-VwXhC;zwZvzbpx_}vr~lZ()8~)i z^>u`(%Q)W*%y;J?^637^8nyUl(s)efbSKu6U@R@aa4yzpxvlO;a4zO|P+8xac4e4q z+pk&9n5Ds<-IMBTa^s^5MXZjqS|{u;V$q25Wk&^_Kr42XKZa)H=&zFv3BtRaVSK$F zhQU{@6|?8zk%JZdqMe%quH{_TKw4#RNQOk$yN!yRmASI&M-#N(N0zo5c(net^IbZO zWi(&om0?ismodsoFHN5F?=0NodtUi_c1a5Zw>@mxZjHT4^c{Dm;~UgVs0fXSVZyZX zZ_GK3o8v!6Qj7;^r{r_RF622|voF%8t{kZq{03tLicq;u`UT25v%(=w_1rK+jvFY!Df6c0XlT6ZdB)Yr42ufAg zi`MrdsA_vZb{ASVHOd@yjLI$6+#R=B<8ixL`(2^&tE;yDL$Vie7H`y>Uu`JGrlijk zA_?-{nbN52#|H0d3N5`&69zk#(TNrj5@(~YLW24RP&H54Vps8k6_xJesvCwxT!SWv zt|-v~e!izG@JFc6h0CK7^WyVBka;h)hz~tHVIJ(;wh0LykU@o%Pweb}(5(7W4F=f9 zGH>C&X%602*ThF1SiXn`reRh-6>^tE(#K_5uKiU#hB zpuBT(5%Bx9SXt7^pSbW?bLQn`EsgXo^)A|YX9@ik0n_q`{x@s4VnLbM7-IPx zsp8L`wxJ_Md+)-?uPM~@N%%=Vk~b{2=-fBncT1Z0sTQ2pNgy>OLhw+lsx{3h$tq19 z7`r}CzA)lz0aOj)+=#_zCLJ71ZHy1D8nEC9p>Hi#|DmkXxmZiRy&^wJcuNjY{HV0E ztUuEH1TC{Z7+r7GSW8RVD87wEbDRFTs)K<)va98~sA51E|5irx>kNNIBgT8f!4V)2 zB-I*$cnmb5zoWj0A2dcu;nu&RjFh{(_!O~<*8&85yZ9;;3Uu^laJ(u0kKHG4ovU47 z)|Q9z;1AE;$c`u0jxyscJeXW@B1i*mY8?W|BNp$8?18y59 zW-JDGj!uFSWEH@aFnnB+y>*zFiFYACB`k;Y3Rd#Rq-kbDqj32L&a_Ij=__--F=7sJ z5iw#%Oui4>pA_5d&ef5#4D1U34%WREov$ zlest~I7LhC>^&HH=gZVhO^y@h#<2F#G*(+Z4=-j;fjhkfDIQ;EQb`z@m$kd`4b=S~ zGDw4eheupc!xJ3?Vsow00&+e@vI*7#g@}86JG*CFPAm3N{chTqHcYT#mI22Ji-E5tZBl-MqY!T{XGoN&)-zc zrCZswV&r~A{7%nR$4`pbWf<{H7*zu&gnai(_y)?q4m9SbPtDoP=wc$bwNuCWSyy9t z{k?PcpFjP@p8s^H5`Bd;i5T)o&6{vjW8}1~_50#+*UPu|pwgx9{m&Vjm<%;pjpQqY zsV{cHD3*2>lLzwChqNCoJV#JmRV?05CEps@kh(HYk(In92HmHPPr{}Gw--t_77R|w z#FHaNVqSk%2hEpcc%^#>oap?HtHY%r(?)i7(R@~RF<}h=t(kG% zk#+_ahU+~Kla%FBeg~eP7c6{Pmhd*4SVAqn)v!D@FZw}F*;=zcxg|1|_O*=tLaUOT zr2@>9@Lp3DmOh6nm}GgtgyH^*mw|n&iXI#IkFVb%Uu^15h^sXn#@@AzHK|3WQg~Th z5OScsTfRci8=HiaCq)=rUvrr!?1Q>iRxYq>Hff42R-2@XW9b(pR{m!-TS&-~9S;%M~J_%4S6^ z*E);XwjxyoCT>e4#UxlL>>`X0XP@y}GRGOEFP?l9pE=lNnNC`+7F~+*_!!W;Qt>`f`uUn9Uf5bXbFhs3vp77eSI{^*)j~J5XBPh*6aG9Jo&XfM!08^O z$A$8_Rz4ugN<2`u9;Y0g!x^kEG<`mL`c*Vzs`;AHqz37mfe2xKWWt}l>JMc7&QWJb zLuVR&m{(Z(SHzA-!c0L3p$M2CSgFNSb9-K$k#O?VGoq5*>EUv=d(CUtjk(!}{pdA; z!9WY3j7H0ldf^nsyya<>U^+nuzBe_5y3foD2#UT(ls0;m=sH}~w7dbvm2(u7D^AC@ zIkdO})J|d}Uco0$ltbbN0=D5FyAQ{gbwamG(?*=fMuh$2a?5J!ip>uqt1fp?_6pul zfGPV6n%$L(cM%_jy9P0n(T47^!+xkp{e-cMr(52y@Nu=pHKM)UrWc2GQq03lkJ6%$-b*C9yO`CK&JH!f(tCXE)+t$!g}rqTtaikL!&e#)eX1OoV;``>Oca z#m9ReSnifeRd`y|s0qE747BekiaWVh@#lx^P(w0CM{El@7^5OeGlSu$+eZnC2L4&; zN}z2sOtLxAjYyJz1ve!eHe0lFwUoincwrD(`d2Y#kbo)LMDQa6_>2s|mVTNi$WLo+IeFFun z^4l-RzTPa*6&anJC+9#Ns>#+lCsjBmcp1d#&L9+k0KrSeqe01?|@8*0~TPlHk zx^>3x$sfZ7x{pG1vXH%-dyL~u{w+Y|)0S6tyEEoqR7K*cer~mk`jad0B+q+-0%>~h zStXJ7*Tf}LL$5A$LC00FXDDaG7$o0}KAwoGBiJB?iaR(Jo?D)yaAh zJVmio*`LnOZK#OlyH#kTTqjD^ojC0^I}1rK@{5?>OI5g4P&uW2%ah3-p;;K10`8k~ z4n#)-9-P;HurE}I>0^~)9;>Z1cOVG=oPQv@YMlI7X!16He5lA%J!{VgVe%;fdpEJu zg}h2(TiB~8v_MG|VV>oEqbwzdeHR1OcpB?x7x2MRoA)BEu;UcS0+~-cH0yOz=|AI?=-^5s9!rfW}xDt%NV(0h1`!Kp2~X8 z(79!qWUg@hRDMlIS#;p{P;P2B_D!gX#PQd;Jd9HmFODAf>z_R>3qV{x-GV4-*T;aw z;}NrHIs@k;DCUE+Sg;0Xvpk`Rz^I$4<}lTlREuD~Vb<0DHaV@PX1;%Mqr;<=uq~oo z{ho2q;7@eSy;jpV{p&%Q<;Ek~Ccqx}lnVJ?suJ8v+T+rCydd{x7#`n;@h)?5&wQXM zcJ`|%8JX#{n~=wMaH54o$d`@ES}lC%LqTZ1Nr$5tKyN5ZimRy)kV@LHY!-k=+H2>&i+aq@GjsE zytbp5-)I>7Ab>PRL^&t%RGKValv;#Id1hcj<49BL+)%{sjQhP)dxUa^eqfj2js48V ze%@7#C^(~|1M}%L~tp}fIO?n(D7@-!KjivRSK#Vs2Bct)2A9a zS|P5ILqSpK5?;%z>M>VkOA`CJ5$gN=#%bV0;|b-i@=aZmz`qfRY!}K`zs~+lW^?m+$%FfX53vI?@40HrgCJ7jR zq*&1(-ft`_YT)9N;$L#^y`aD>xHFCRh%?`9t^bT4apkyn#xx-8Gpj^r z#N&T#9L3gxwHkUhV+CE0mUtnNOo6YwItg_aPj(_Z$7b0i8Z?-2ECC6)j=ZWJqpdNd z&ZP8pzRnfUiOCg@Y(L|`3f;eXjpOC${72-lO8|d;+kc)cvnv(wE}HgPrz5fb-+UEU z{%3-6Ndy<iUHi2;Yo_TBp8>0&1$yBCzpRj0{+!AN!Fpj z9c20nX#EfBTPZ?lJ%0RCj6n8LkD{k~Ql9R>MAyUk1G4(K(8UV0;q~7$!YYDRHU?zk z3#hE@oqn0hKQI1Gs)%H*4aEHVv$)%7*oD9w6}3^Mdh9B6jN6r83~@cXFZfe2)#x@0 z5b21rdvPtzI6kbRAe)MmU>OTR;u?ycOrKug6vv6gDtuaAc=nm%$sggJZ_mlEBI6ab zCO$}UPgnMKJyeNZs(}eqzD-ryHCWGu2^${J<7y0-P}(Q)xo*~vPe;8YEz45aF^-A* zNkY2{!!G!DLQz1Xt#M2wB69Tns^L?4>9Nw<5z%=*N?F_2(i<olI1Owq2Y=?$wPy1IK2N>7X7E0I4UJ|rQqUQlc-};2Bw=XhK8;>y;zcGlr&PiSyQ^agj?!XzBD?_ZAh{g`$dXG=_^x{ zQfL>61487jBtqA#htBHav+EZWEELw+ocG!k*uN97CUN)b@u_C)aYXO-e$&jN7if^yape$EbKg(zC4gQ5 z$~N|z3(9SO(b=M@bUI@-OC*%x8Drqpe#U5!;ROB>G z(wZ46*_=qk+}!wU)vxn{eUVhF3c&bo3sGXp7qB=Ff z(yED*6s%{B#{D_`7cFYmlJ}`M#G7hc&BNQ~>RIOzC(qkIHu5|8SBTkSzkLh}cuoS8 zx%f0#S3>(g*)*@mIi=iNInkOPyNfBBd0Tdt7^17sr(LLjcQDW!&X1{F(WGS!5;;&w zGP%(u>AoX^8IguG;ROdTbmBeQ%#z9#a57==?y~hFdK?hB4ojA&x=FRVFKtl&R}Dls z%3d${T5XLsTHUXtQ7hFYjX4q}@nx)q?#egt*iUc0lGY9BpvYg8K3Ew2?N}p0!sE45 z_^gaatMXod%6U6cxurF7tZj6Z7PeL}9FGXUC~5^I4cC2tSsvIoAm**D&ewHvcOE+; z?Wg`oUizmhkJsEithbgjKpR+C z0(M&tv)VvAftPGO3}|5b+2b2=1wzr9rqd;6pq*>e4wkaNF~MHR7{)$ri; zk_;W`evK_WdO7Y=N3Vk_3+6TJjFKsqs&b^)(Ytt6+O%>TUbWQ1ZCX?4Y{EXhFz4-W z7|D+=ysj51Htx-ZC{fUqj!YMj>!e$~=9_xOmn$ff0_k*xa=?6kFFSfGi$7b;xYb_J zE(cM~)2VM3lBLVvIJ#cXhZW_Qhy50p+of&Q88_{sDky9)WTq=BG%eIwN0CEN=UeT} zQEqwv3OU7=D_Wts9v(hM*`a!S8iREI%4m?U)lqNpg!bMlpfX_;v# z$${*^h)z|8ylx3>5%M3+Y%NCnSw2BI&ZX~xa=$tZY zy(i|ke=AB*>m1J^ly+a&`n2d+3DclP_dfhx&nhCpb>m;>5nk!vJHUoo5J8`>I86Au z`bUSSpbKb4;eR6<;aZ~rt0v$42W)9RlLc*4%NBJ#a`WgH|w&Q)Kp0ciSR*#g&t6JZ8 z$7i&{TMjKlm6CprY0X>YMxZ}&CCwF5I3x=(9vBa3a2uVb9WvLkn|zyA_pH@zZp?6y7{g@yOp?wLT%(y#f$ z5v*1gl%evsr$rWih5sY$LvQUo$kC>%K^S}MRu;fuY^i~O?gyXz1!o#`UbgH!NOYXD z<_XNd@|wvc!9v>5`M7?!m5M2Fc4E^p;SKiY)MAFN^)~MP zQkCd_Le&VC4$)BDvFmtoaGcu|z)#oNz?S9Rr23z2qUeJP2cG%jbTuW>6a4HCrHWH- znL|Ap6O$-^Sb(LfnU484E@jX+b%n@7(f?hi?Btp!BbVL4y4ZXcakCqNTAxe5c#!_h zd_!?sRt>r0;#g_-!7p*`u0-oXA6|ZXV?8Gh8w}ymM_N8BCU`qO+GcdGYV=9zesDT- z>IJBu>~*xXT~DQR7?@rzdtq}PHf7<248)K^E3$QT*WMS?d9G{u?5;dYFYkCz#g6zV z0S~J}p2NkQ^j zsC?GPSO9kn37J~)PcYugV18X-OmFRU<<8IdYG(IQhV)DIr?jvsJAK=k_|YEfIb;_7 zz<)4*o*N?S<_o)PpLI9Z%|6eu8Z|A1K0t-%db~IGYlw5UZGQhaw)=7a-d@De1l5e+ zb0lPPHHb+&Y7Z`|htVqG@v07J_&SkJ{6j-V;H(G^cp_g$b?{$a@u%;ul)Lbagq1R( zKZl7YR}IeSutx`fR?eUXkjYh#3A)$E3OD4X<<%uznMcK40JiH~!a6XiM*Uqp#NgR@ z9{OtV+h2C+;V_>W^OK{lmB#gCK{Tzy#v}_W`7c}JXMUz#F2y?U@CZ(e)Lti#e{}&0 z$7Ne!wY3Dj1?~;qofqk$P7BlKB2gvT_e?D`YWa_WSRmjZ_J{#P^f$UFj)28KENTr$ zWpoXGDxV~>ZAPAk!Z~s#_0npHyE&j#yRcA#$Sp z8|tO1&PV= zUrl_*^PJrIu$ZH$X!O?QLA|t`LW~iO_@}ETlva5vLFxKk^3wf#L5;rrga~5D;SKO~iTrV7?`z=d zEP4Hz6iJjealEgE8Q(x>tn4y_aY7sqW zm`t!MwOdtNAsL#1CP?=Hxb|5zC0kvVQzJH5b!F!w&_D)_Nl(5p4W6Nr)1eDQ{Pfy`S@ zvL9d(FcQ|Ou;OO~`L;jh|1<>PPgv~yma^`s7HV47n5Ws?H&ha`zNKjtp$&T}V##1& z6BbOXRbau`W@yB0J-7+_f-QvW9?HWqJ;Y*aQ=s6I7QC)Mekfywis~1GWJLuXjA%~< z5Bb`?3f?P!QAm5$<1Uq@t%N$_xsi%uFFrV*>M#+Y=XD4CK>dM_`gP{a`QAM?oXT&LxXjCUqZ?@4qjW#wT3FmyQ#k zoz#S=+O8^~y{FM(NyzKZv!xQZin+7`0I*xj$uu~6YvQ+E%P~$=UdrJFGxVFHaDOz; z(T{#pUWN#QV(-zcn6vc?XIAR&*^)(PkEo(VTSI5oBwmgxzN&lj*1iAdV5RJa0Sf#a^s0$=tJI#f~J>v1dZ_Twt-(`GeCip&X zz9M5e8E`-h%{-=BsWfiM=E_SYvwZB@N7=oVN2ayKmS%MOzA4J=KroCHMV4Mur~syH z7{|`=1AvRB0WG@dS90)1I;OQoRk*RK%o-zm*XL@h(RX!%<_GP2Bl$ z2Ku`dDPd%wVeu5gt#n0qD27KwJiwOaasoUuYj8!idNS6ym;(qv4|dlCgr!}d46I|Z zbyPJ~C~-!89m=Ffug^b{?h~4!SRtjCg**erDQm99{bT%%f^ft`G(+eIZy+8)}4XP;6DcswIPH!33(dp3TNZsPY3atP^ z^|AVC-mO!#TgO39_|5Q$h1w+yUoUcnOI%7S5>T0eEcUfe1WC_UHRzxXKcnm58f!!+zBF-BKo_7P=` z^$&qmc3i(bCk@}9hhnyWB9~ImE-sbOfxk7`QnTzI6xU{V! zTT3^Ifwle1CtN)mo$TehkeuB1PKvhU;;^##QggeqQbhdmV|&wx=VCE1zE0~epJv+N zMYNL>am`gc{vBml8`M1JV1Ji(jUMNP%5vIyp^5ld6E@q^yD|gL8_@~dx=n<4;wR+=6wFpe1>Dnpj1z}JGvm%~56_cn6 ze||cioXp^HhPy*Wbvzrb* z+5$CxY(gZ)&8p!)@G~qE{iz$MI&eXlF!Q~`^SDlY<&t-uFvFhC|;Bd7{A92DBRo#+j`3e zsS*#fHWnj?IV^+K*oC5k>DQY)xYhx``guxUMh_$oN?nu={qOiXN5@~`G3VytC|?p^L) zL*K6sjt=WK940Of3+uf(s{Vph$5^K0AZJN8HCK1{$cywxQ9~~07Kr0KBV&uY^`^o) zi(%yo9Bb3wgID#GYWa)IAU-}l9cA29TqdX27tmO%u`-p|87YrKp;%&`p5Qfz7xIg0FSD1M z*W9k-j-Z7s+s)N413Ffjf@uxldXV7TvsqoTr2AS6H4byin8v6^Qkq3fb~xpGiJ1!Q zVPFN-fyaz*Fa25(-ydGDTEzK9<#BjeF}?8hYEk|}mmM$B!B&fI#Fi7e(cY$E5U?yy z{>}FHwLa*K=+0}n;!s(4CSRo&^0BT}!pVbYKW)abnHUlX#XE~7inV)p-hXt*e}|gn718(eF*=JSJv|0wNNd)!b&f+gkvk%(uHzl6P(o09=F6u^F#}>Xe=6`# zX<}x77ts<)nygr=4Ogx^Rb*c;+o{)Yt<`nx;4eqKh@=pgPf@sH6FhYm&+xV_Vxv^D zDzh+$!sX|CDDqkl>xu|M!?d>Ki@J5qf|ci2>asJf-NP7ieN($hrTucfE$&{%h&Ir$ z0NnkjAI-;S5B8qCF%BM`sR-Q%6Y|7UT5L>CiJ^O`(0A3**MU73xk}%Ke$b>K<*TZz z;a=tjo{iq;XtDGSDiYxltwFdArZdY(;QHAb)y7YR4NBjD!N|uW>JekaR>)=Lp^G4D zDEgD%W1BnHl2+3-Y}`kc+S~_AI9(*zbC+wa=vjf@Nugu-g6c=M{tt}OCz4rZr06_um z%<*!d1U@WY7v|JQ#o{0Wzg?2m2Y!dU7t^K5Y<4TR@48NE@ z6+>7fN8$4A1Q7J*JQMTgBOg0w@1gg+*}#gcqT>AaU+5DgD?m!Pn$deVx?|q&p3J?Q zl=D}1O|AKaOf55&$lYVL z?AtW9Q|v7N$^Ojn8&al)!4yWgsI(S$(n-vKP?l@^++ems2_ktW`A{-6C0eC*$@J7h z`03Mjg$ln{r=%uLlZ=LMt{+LfF#*}(s&4lalT&KkH7nfWr_7EF!|@;0%sm{-`7?-o zHEl)3jROiJziPb{N~JVzxbc2@qRszudZzBM^wQjld?|@u_1UZc?fT?}A!+4wP}&g_ zbml8@#h1MOiOC0ksbfEzEgNjlLHHgXb(0Vpp)o3FjVxBWXF9|XVtV>UK$TCP@#i|V z;4vo`L`5dgqhjSEC!BsUcTj1D;p5lYwRZ#-v6Lcc{u@(O$CBnV(!i|+ zffE6-kjv`Hj385~mZvD|d9Dyb&>Zk@vPR#6_SiW@4AQmlf7mTX&S(7J{@50{_$TH# z+{AS{Hr5=ALU&6|(-J8Z!nb!|VdA|;=P6;&6i^|p`l2kNJ|@^kdQeIA%(dq0%62Uk zSiViLT`D}ud9|L!ex>RGg6N14IwSoKG}NEfO%+v4BEa}Mjxrq{{ISOcW_@Y#%qR{H z^73r2W8Kk(*NS+(G*9gtjA3hj4g|lN!@tSa#x(i zku@dXJ8O*Tm7)nc&kX< zdi=tKePHys_VfZcd+g3m=^qSAl3UUsA~Thv&pHCCxHZFLT<<^fol8`qE zU^-h{TZ2h`AeB(NFsPq`?QDe#_aJYkRLA#Tcrga2%48f}g!W!mMjQ(Z3p*AU(e#Xr zorMO~=_PJ7@mJoIQydvsEc9MIo=q+LD21Z*b+|dO$JQbN;dw*}*45A6ihu+_R8%x` za^oq;mR#$3lai9ks;fE7dsAX7D=TyDQ_Z#RN3;zVkAU%*H`dC>Ux%G__<^T^ps$&O zEA6>j*=SZgxafSp3RCRvQZII7Bo4H4tstXAcRVmhJMPH%H%+RUsdtv@r#AOAvj?M$ zi^a|kPtD7CqJO+$uC|@}@+_XOV^C9u_wx749Kq+j!4QMg3;6Z6q^g>G;G}C8@o7!0 zc!}?U7Y*OY^w4k2zrnagWh^{4h~(%|LDdE*96yxDxYKHQL33*Q@b|W1gEOe>!9~*y z>AE4!q`-D3Yp8%0I7P+F6_A|XA@`V%QhDd*rXwmQmfgP#f{pC2yyqQCC)}*4>_Kss zfu-ZEU7tlCT>JTsJCB_Q)?oezF;fgbYULTO>rrn|Q2X?BO2ff~^^Y6-Ka{{779vZU z_zQ#E71_(&{>gi1uP2AXc|(7~Q!UqKWe`8TxasyLXc!IL%|FLKwUX(&uE(tZUvuyI zg_H!029SeZQ0^-?T!u=z4H~n3#M?B!C7=b@adn7`iV8IR;4p`cnvAHu7vob?u^>BS zwF}wBT;?=u`|r%m6fT?lyu7^dOPUvZns8y-j!lr{V36YNLt+|=cKS;O~gW>z%6W?%gwiVyT=%uzV^aP6Zw=hk=1XS#2#B zIF^dGc&RgW!4Pj(L~=2~?lW`q-2s}xnfWG3U>3OScg>yar&bn9FAozK9jKLxj|mF0 zv9rUj6*n;&(nUt6gnb{xcTYx+7c|+))u{;!!iEb{(&$|?MV0RWC{51$K-slfCx>le zNSBz%)6MmOWvI&RV^M( z3fTf3!#yd|50`q9qw{r&JEJvWT>Kb7MLbzA{{o`wu(0+H>|67T`2u``VUW+!zrY1v zJC9JQgE2G58Ps9N`8fs*5TuH-+{B-3HJJd2`A>s~RtggLk^g8FSk&Fq zsvJZnkYwh2bn?SOI5A}B7!U#<7l@)8As+%+cj)x$%3ZSB`D~dq?^X{agSRk z*klF8#hMvoyPE_mX z(I20SGn|6Vp2DTY5VM=U9VJP148RUtTy=xe^lr*wJ1Kty^QB$r?p6mKK5h<(BJ~RG z{Nb|1x@+6;RzA1+)P#l0fD5XJ1d93?pHEJcC{++&`j)?`=gWsDgL^_Vr`VV-iOSz5(uR2Haj6 z1xnR+s_p^6X29KlgQ4^pk=t?}7bi3P7i&Ie{8UkY(^u-z^oV|+>IXfd9>!BMXFsVU zum=ZK>+3eps+-vTKkw&>`sNyybY@lUgpzV)O4&=JV~>+hSw{_H>{#2`kaC?)M18i+ z?Ds9inh(L&{i4#JD(&@pvwjOE?sZV$EWwbV#y+s&x^Q~Di_7-GXX8@O2YtRIiP>ok zj@2>J?0Rh$8P&62Y&4yT0pEsWnAu?%48jAKBPl5f#BeA&F74h#rF9twlaiv^l=l`F z_B!_3kUhcL`Xk#vHGD#~Y*>>T`<xGLE0_Tmi}(UXS!rKiB(>KT7;(wjyCy8bU|cnctsz;d#t$kxADN&IZGt3D3x9wDwFdC zlQ`?qB5-rB=d1xo0IUj2(+*t|i_GpLnMdkPgJAXdRt6pa{q(0^@dPgFqeVnfoSc$k zQ{P2YgmN=XhYrk1(|*B02={cSnOH>N`g4?gb9+lN+<-%%y= zB0~nx20*)4wXjq*c1L%2PEG0k7^$PbpFq;0IN$R@A!QM*+eW#ZD6BE8{xP?LUGy7# z{}G3s@qJ10V=wK_a?V?0uZh1N8tR0`!M9u!!dn(td1F<##t$BjjB3}h#$#R`Fp?*k zJ@>ZkwDFUgjXOCegk;x_e$$vkl=zyqqpQ%HRNHFFZuQi`t;2xF*=TEwH`nfAxVOo0-Z z-P5F;-ZF)_@zBRMp+mdV*1NN#+%jg^CJ@eo!>pV^_3;tpJLmE&XMt3%K;`qLr_?{=KIH^I; zi;tSyNO_^HCQ3t{q!8yH+M(`~{EH#lWX8gB$%6`%+ab%()lk*hr*_Yrx;F4pzRsLQ z1QQzvuR{CkM85)@2q0H6{I5P3`+eJst?{12C;Q@GUxwt{XsvdloqLqGwion4Q5>uZ zU=E3$5nivC51NDeT92Y6C7E05%CA(lMnKzQ5X5L&?8?5;GSzHbjg5>uyRK2;>zi?{pJL9{C!Entq^-? z^`|1K=rHe7Rq#TwYG*@lTa8eH8ais{7r~cZHkpPB@A-PcI%_Pv{Z@4T$PY#!2eB>m1`#cN*nfw~9s3Il4 z=3D%h4y@A^Kv!8Ob z5+8FIX9OM=yc_zcxQ6uq4ur~@zmY(jr74@O@EiBoBZI4N3s%?}R=G^sVH?b)7*pFX z&C-8ZA$m~g`rp^b%cOllE#sB>!l-sA9X%ct$7rJk8ZnkGltZ1f|)0GuWv-mB>7n9un?j;|GyJ~!x zmAlU{fQ(CYy(a5=%uGH<_U?8>mjO+Lmx*3!h9{9%E>TtJ<Q{GGwlvv= zJmyk~s}GgfS*a8LP_5{k*+O(mNyMb0DKr!4iP3-BrA@U`JP$E$qHuLa!T)zlklpNq zscxx$7}3r?+svWEimN0mtE0O;rA-F4^xae=bBaKl82I=jkouqt05kz=%wX5e-Twc- z67-OnLmGNzDwOcYCHLV+DG2gY%pYd8kn;eUJ9uUKiAAM^QB}2~C1zykqD;D&{s$%b z{}&IsIiQm!#vaVX(bkOQw=H~srssYpTT5F5<BnO__4AmWkJkleZ}=oOvY^J?W-QCRJeHvJd{3ZjxQ8oWBH0x4P@4cc9*Gv41LwR z&#Dq6K+~~R;;*K-I==0>%%JQ`_<5-k+ULVnne5F!l_12o&W?SsSC6FvrMRpisEY^E zVtgk4?yALzPmT<@EsOWAg#c5B+u3QR_?&xGx>1ADUhPtf*MA_2*(cG?*_sVlI9_gp z@g;9EM1vHggyfptCwR|g(2M)@LpI@vdk8er*9a5nSml1Gy0c{ZnuN~Wb|4W z^q39inBU%h4zKlUOp(GbXMm@heSrYRsZxkaoaL`IAY{I|?y{*>^4nc1MY(Os()zv3 z%Kv+Ix=MU+%=JVY^97dv{*}cn7+{pVcg1|PKxi>!squfo(A1W9_04OaR(!ycgA`ec zm!B2&;SXmK-C)Z}9_&}k(rtC`nSeq>wE+WNeX9!W{L;9sO3;RVqy^Cqw8~SVC1pSI za_d#b^06oQ2k7O4(FD*oyuP)CeIxL-=otk$`TPfB#zyoxBRntSCSOQw_ZUHP&%|RU6dUBAu3cF3YSS z@EI*OiBCNWPL1^0FFudG%&XP6EkG6yX63X~Tx?TdfBg6W>VTjo3H<2%NTC64HNRK` z>xo3tt9eya-YxjL>@&?Yxdq#~*g945nBD2cI`zUHiWQsipObO6243)Z9sW-{05gan z9nbJC9%uWb3zehB(U)=G#$+{!JMMh|dy!cXNoq>sc)46FQERV2;16O_@mkl7iQpko zunuvJjncOtG%G*rt3d!NB( zX@0y07;BsW7PyQ^`I}D5zRCC)g9Hk|Siqv-CajA)h-HrCI?B{QKI5$b;F8S;{%T-J zL4tb;!faifZ^cufmK83)GDsr^Iq{d@*Qrt#yKE|e1hPwi$#&-co+u>w}n=OC156;MqAn8=y8383*w?GI^PCU78e zyG*B9-3ESNCV8;!4;1Yg5isumkE{0%r}F>f$M0iHwv6nN@lHlW!Z~IrQfZLAqB>SW z#^H!U_9!c>jCyD9d61RDv9gX$_I4Z`4!@W8_j7%J*Y9`rN7r@Eecbo`dcB_G@p!IA z!iz@H|AE0@j`F4dqAH$T0o!;+3b?x)Z8VskK0USDTLU|vUasmbIBq|!;X&w|C{rmbVX(#oR*tdBU{Ho3izJ6Whdhw1k zKL<9YI{y*5)W8UnAY%++HsyptEr6jx|KeM+RyuTb`(p^A2?7fXApP0G9R7NY5z4!h z7U#R!@R&%#gpM<>So$nqQu0_y0NnEa{`}70-#c%m{nXEtiTBCjVqUEaoUnKb-!ybf zHzvpdfd%mJ%$At+IS^@TEu)3k(WIwtb?h15R8t%3jbxE7tHQv#+*Cg4ju%~ zAh)tWdd>fJ277w|hX@+(KdX4MgC8*b4T!EYr~s%HypJk#jeE`7hs%%u1Amp3qMN8q z-@oMi2WS9&zOkp+kKzsQ@n0!?vFnx(7`gu#JXO*F$bJC12XzzaAH|0Mf=sLW)*!XkelmGyUfhtM{&kNpfrI3yYSS z_mNj6eHM_xfIiod1OoMf+i8K*c!586SUpr39SuHdQej|Zv?a_Tk3p<~i1lvn@-9Elmzi4k1fRS;uqg5x&anBl zJZ#}>knXc0afr`DTmdHraChLeQ;t$aYWt+d?v!C)l_WPPv-rOh`rEyR6T7f#Rkv0+ zHCk?9j&boExYxy-u^5Lfjfmv}YCy1@|6>xD zGT@;EakJl0H2zmC-rFbj_>9Q}>J>0ZR6)&n zhxgx*Qs%WHXU{cW>+vGx`Qon+XN|VrR5V_QoeYLP3sTqW@<||K!$N_sQuUIkaoyDR z*(5vaHr1~|Vu2w3=L-t_h`fjbKyxhu#Z*u%>`B!G<~FUx(Cq;&aE9U9Be{1Du>lr< zw>&e!XXF(SwSlihvta3SyEU&ZkB?@nRW1*5wEf4tAy5{Db91&p$)=p?4sawuG9Eb5 z|M9{_mW&E-;2pqc@&CQK7Lb~D-Tdz*>D_#9gnMy-fcKS;VR$Kpk7Ei&Z9CQM^WllL zalqfZk9#fjl*~V{+ol*{CD$YkOgXjpN-E%_pTUW^Dwp3t;~QqzcS;9zC;y@1C@9&T zk~l{wJ8e7|*S<03C?D6-(jp)omKJg?)}IhhWkBX<4kw`a6YuOtbuutAOxDXk5_Lz+ zY~5otwUj+LE)_g=06{eKm6XL#WE8-&u_}c14uSX(l=MR2!5OV|a9}(%G?bfI%}%+i z64wx6C`GLC{&Di})bHOOM}+mSYZGmM)r8OD7$q;#YpK-vG)zPUtzf;;fM02)Y}$lC z3KtW3jrin$zR?|{!LFP2(%fRdPR8pSFE2EJ+`_)6y)?J7GrT^N&B)fldd_nAKw6kX z%Xy{_p>)jo1HNA8%(h0fC;1u4^sg*nQ?B#a(A)+E9ZrVEW!&Z7HESHC{F1BsryXen zM=Qw6-$wc-@!>m%>sZL6o!<|HFFVi#n&C+`UkH+kf}PM>iN{T5fBDP(`tr4OWf z+d*J%4*1cZ%deFsQYQIL)$2XGmvHjg%MzTwfH!9KuZv>6#=frBdr2P&H3vJLRX8XP z{+~{NATm&Gpz?zpB9U!<;9TLDRhMP;2ik2iS4Eq@y3rb zY`5Wr7ysI(;VEghE&MI@m~UQ~PqIHK=~9YCzzxk?-m!x{vl*2yEwncJKZxtxcOXa) zs@4snzJp04@DtkQS7&a%tE&JjbMpMDa?b+tplMg!GQIr z=>piNY>@>Nq00|TF2r(iKQ9-v(wy3h`tuGCPBXe#R;s`1$(1j36qejymVL!s zj=hCTBFpwKiZ%{@pz&5X9_076Wkr&yWxQo0(LhUOBNWAod(^$RhHr`$*2eBgwI&{K z{(sd_ss*RAEZ)M%&O|h*d0I>AaQk&c6}cK)xOVG}CdLx-J-aeP)e`cv$Py$wBQg=W z85#L)-?GtPHDlxNj|Ps1gEb%u3ntY7g6Y+(U*&qvnRCL+Igch&F9Uuo%_s*7J)unMqz;&oC4V1w-GWw%&r2VgV7z6kzYjNQ@J zwI){}%7cMoB)T7XO26}_&x^U2{%>#(I<{4fnr zcRG*&((r2LsDlE5;s((uBm+!f>8*qM(iAYxn=Myrvc{q?>lS?|K_gG&&K7JOX5 z$+~Rd@@QxAP(N92G4E+GQSUGD%+>Fz5br7*B}aSH(O$77|IDTk=!!##TK>7uK@8yJ zo=H-e7yLsh7<|I`ztC;l^E<@SgR%K)-8R4> z6nmo}Jo(Cb=#Qghe_}T+;^@?zLG-ZhH>S*Z$mSdW>2U_gCW~6zSi4o!=sCO@3Cb>1 zR1$)Mg1(7k7w93i#Wx?fxsJ$A-WGLSW*0DnPTrz`z0>&ND1zeCMsOP-Ty|}gi|QlI z2*WOB*cbnR;MPw^`H!HpW{vmi$1|6v6hy-e?8zZ(XBs9`G+ZXje~=e@Nbx2J$A`~A^HPmTmV?S`;Z=uvH)o%(oTr^CSe(!n?eY=+UF@a!q=$#8$JklevL0Bx-P;tD6a4QOY#6) z|DKu2;^F6Sj4gdC5)z_wHMxBLC}5g82UllXO2So*(iokof^RMlAN z^U@mJQH|%7lS(sfa(3P%1b-AcuPBmswB=YOq?&{(Tj+c?N z-9v4HW9gAMDmy-^ncm|kvMP{6N5*7mO#cqh*wx|qtNqo|e8_v%(ctg7&J0^W2S+FC+WOG2|7HF3 z{kat>zNFdAx_;r}-a zDI%}VWRJ^5>L=D>?UyJYRIWcQ8>N%7qV4Rv5}Y>hRW3xnTQOE)t>fl3r=y&alZ&hR z=`U9_8|~p_P*NMQt)%V2wHk5kJ9@BXHaN$)op-gPPYk77ZjN;tBQ+<)fu4ob#6hMu zm|<}~IdoxUgMs3zM;Y*+K0;jyY>JWQ`~yxS^GoJx&iuod`kSO zYNvUpi$w)9Y* zSq8JaIc!q~sl8{}bba6px&vmkYHgC$pJ}&60S&ErLV;-<T2rmRF3}z|6ct)seGwNawj-QzEW1qD zNJ5?x)|as{Ui?gFi~X4Fx%=F+hOxn4ipTbCQ!4_mYosPkkY6)4$!zjGmFkEB~U+4@48Fpx)4XvG9+9 zm7Ld3N3kcCAlg&vb;36~2^S;z8$K!c2!d%!4HcJ66yjX!w?3Vr=;)4Y42)eB9iT4n zq-8oMH+aEOY~@@RR*f5WLJ1LM`Sdata~QpQm%xthoQ`Io?wo8fo+g^ryfhgaCcfNQ zGa0>6ArZfAY*B+RRoTTS0*i3{ zQN-jUs95<&O2if-6YaXbsyjtReA95EcKXtV`ihXGQxTThh;?aOoiumDi2^T8aE2hM zr7_N48_p2`PC$hD46bnx7yWiQZfull+&(=a`U$fOfvnlg<4;*LuB>%xy6cWO#C<%1 z_$l2pv&UK`1I2g}Vh;AU%l68I!TGb%ZX+YtW54)U76OmHw6e0@u7`{sYHXLfH$Rx zVWFpu>EX1gZ48n3Z)Gzm>fAUS```^c3?Kbx&KhIku`5)N&H9(DNWlni$bY%N_9)+Fu8ixXdxWN(pFjyBrH)w!z;dB`JB~RQ`HejK2|Q!)dZMu1q&a-3 zeg-Fgv+=1)gm3zL6x_i8Fp%GDFHO+1vKCLbh{`5J6R53_IXxrc*IfJ*vL=c-JgBUS z+ONMcfXdbH_&}on082|^=07*WXcO5>pTo2!+&~>J$2co&y=%Ywo;zKN6q0Ku|%sEKEjyzyj@ZS4`nC zQ)Rb}^BfaS=xH;2kl3dqF74FyB(lqh7)sP1^&!6{_P4DT*TzLuY6%ktM~$LRA?GS1j=TIbtXvKnJ1 zy}-@d${R3VGN@_tjqTNBD;gwu3_kaAB?jZTjx0_8mX93`foM>?I4cSW-L#bAFA$4o znj`C|WI`8*O5fwt{gYU6lvS`ZnqPG}mFQgepj~F@kM(G{IMEfAEG-)-d)~5rbL$e6 z0Tu;&@@i&;QuyS@(keTKx2}!BKh{L-ou6agBWv;!-85Lt$O zhDnUi6d^xaNCOQvRT3_6mwRW_%|{_h^{)YqJzY&>w&b8(&szk$aIf4#_VvZ$DC_Pp zeli6L-4F#)AeM3o;Xa_~*QSWkmd!tyzfT%k(p>ujLFG0oVyb<&ByU0psHv#9?Bh#j zgUzb7ijXVoVuC0waTQrw^>g*so+Sf|7g2I;a2EyK{-JZeAu?*zwB z-sq4VdKUfZscLE^%65YzE83(hYlId;P@|0n#Z+ZzVW4I|ZcES4EYV!Uk+GGCN9qMw z@j;oJXT|(}z3s9vbl8=((rt;WguvHFncqEcCYhPvA(|amhBxptX=6XN5^0ZQI^>?h z&=$4lUwvO4bgnY=O96=)xdDI~>$H0#=8fb}BzSGZQ#W0miXM=H2~E-W3sXInNB^-r zZ(CJVN%zg=!f^Z< zaIP|a7WhBv5riQ69D|J+^_;ty#T{?^2_cWN*$lA8Ux)pLtj|q;J4cYESb!Ap<}UpS z*|?Jtt_%s=vFN1`w19+fr*gL8`=2QRh2(woJdBxQNA<4 zAwU(!zHCmjRPgBct!y|HP6K61uNJsS_TiuS30;z{iQxVBxcO*>+jT&eO3k;uZO+s#ogQYZ}l*fh48DSWJYp7QEh{&)mI z_PY18y{_~w#)n7mUv;y2Ja)bjHYQnl<7G)EsQW8ro#UPU5@9WfRmSsXc0*Ut3gqH( z*`RFr-!w{A zLTx4dCVSS%Kc1$n1{uz2s08!W2F|LbBE0%o^kI5s(`LzqN@_Hd-W^$js*G?yITU{S z8W~(LihOoiT1fET-nWQLH2Cc(i7vUW-TyU%5>i$Bd~(aO*FgvVrR^q=7sWw^ffSD9 z8Yv8h>j)(Pe$sU%A$(8Fm&vf2^F&)g83kmQ<%qQJwT?UAWV3Vp{>8qSmd++^>yRD^=kd5lJW(0S{sdZOp zeo!$m&Px#Zt0o_3Jebz0D3serMGt5dZq?8;t<0@+)b!pu%~4%4w2t=1TMwy^gsPtR zCxc|cAKx?;sUrDPd5Av$b-tXOJC{kp@*vMtSzxe8N(>&hZnUX`hmm%90|mijQu|R0 zSb()hX%8HMCS*bI#Ew#?&+Gk;Itm{L`|J;q!^)IdaQTvSB{Jm~+cU=PAs~in!d*N` zK|qz8kIyllP>Sm9%#Lio{xs+d6Ugu6f~C~v>>QRvmd4&ucTv?S6MUme$i`+XO66U3 zC>_dn&aQ<)y*hD1BuDv|Cq12Zvws^P$$uR!SEy3f?hwnwQDGD7fO>xMP4uRpj9=V3_u8-gv>2NC7Tb`3JfGS7MB@)kXthAPRqlHpr8 zp=4Ab$3IYwf2h8__DwBpdKGdTxKjgy&`m^Tkg6HKFC!zTq-J(vm|#@x(Zaa2Dp>J> zO8u(nl)id-bVby~l^`|7{L5R)$B+QeRLg0zyk0oo2ur3;SKdRQ=8nCD%t+~YC^yMX3&X3J(vN5x|DW#@$$omP-) z4+0XPG8iOhPx$ZZ3uCVV3MMRtI*%20k~_taU7w}@Z7*wZV6t^3F=b3}kL@}WR&-3q zn~7x&7pxpV`&C$-fBQguj_<5*s}}JBC}aCP2Y?shN0KikesDOK-uAa)(VtDG)vSMu zvMq9ZcYEEpzZ4RM4uH2g5_INYJqaX)|FA%6kcMJkQEXfM`dZN_=d7uV2~@+@|F|fU zc8zG{^hTx!f(K33DMm1@c*$<2oGIJUPNA(*w#6{<|D1AHCwN0)5xj<2h;sjk8a zkQ(Uz3mJj=2@pib``ccKR}xeA_K0VB@L4oH9BU znoJUt_cu#%!Yu2Y{IM!UU_yz&q%7T(t$w(hvrX3z3yDI~w(l_;GzkVJB*~+@nNM_h z$#DYDIH;IbCJ2lfB$;40&SrR2$@O4Q{VeIY5O{-kk{a_$BJm{Liusta=>m9d=)Dtc z>jk=rl(J+#q44GaC;7JM$r7STg&u8b3tAQv&W2sl*!5qElkhWTHYgf!vHew~PfXph zw~yC83f?%9jl81OS4L&So0?vb1R{TTKu?<{o1jRRlct+wII*ck=9Pi978*i1IqJ&f zcC3e3@w>KDBXh4=M#vgmDk%z$=v!T0>v;{DH;PX2ewG#-vE97u#}kyantUVN)56HCu?6);T1At}4_@A~rQYRyQIarhv*xh$MGb+LU$!BmqAwm`i0=%( zfhJb=5hb@?9Niu3f23qSIF%E5t=s_v53_cb{E@_Q`sBfFlnv{W5q6j7hyD8WB!Nd` zT5b?#^96*18>bTY_UNBAY;W#XgP9&65oLb;tuAAyez2@_HnVn1$rY!+SPP!#G8WIS z6uro@(0UNMCwoY$H+cS>ltOHK_%4Rh=NAZq(u^EX5FF}1TRa2#$5MHfcR&dB(YFkj zDm}aqSTKm$U_5kMjlUOF%=SypJnC{`ht%g45>mwW>x*05^K4%h%^RXs@HFXAmm#zb zf{P$6@2nm|_9pLp}F+iv{vJ8MmK{2+`DwCBt4R! zFl@|6L39NtpE`KK_COL2a|2BGrMmr39Zd8yugR12zj9P&VzkJ#A9OG&7zq;oaPG>3 zn2bkkOV=|seznYKk1oS!7zfh3_0dynx|I(MtE;Ot_;+U~P}H<(5v_2in&IM?(B-0- zl<2Q!$;Cc00ZdZlAoC7Z3^Luwxwdo{WnzT)y@0Z0$`O&Mc zM;5th%#CPW>A&x?ly}_u#fpk=0i4}{19WsVa%_$YMX=_33K-EHAt24 z5?)g%2^6J+$umR!86edJ@bwZP_8o(ay3Q!4&_)q6Hs20qvdm-{8a4}@7^Hsa(0`CglNCu(VIWxq$ zs%mQ!WKn?3-iQbP-Ix=}&|FT*tnagO@yT;2*vEa7L66g3D%1t8{>jiq|D2Pvu56X+ z>P;)qWD54ORI-KU8hBeOueIAXqXK=8S+^MBpuei2M}%52V*uz%O1i(2L4(hi<}@88 z@5PEMqAoO@2b$1|ZX}YRSDAiLe&^`zxYRe=J;B^ewc@-qn+;ZpNcAqu{L7AXeo^2d zA=yA6hx!`{v5|58J|N5@+PX;G*&ozW=dQFB*7a@eWi-P{&6mh$FS2N3Q<4r<3_yoB z`Lit;`nl4*ps@b3)WoLcVo)fPCc@2$_47)10)HQ0YRJ-&Y?NZx<>dk~8ir;aaWNv9 zKkOSAq68sR1PO3ff_6 zX24eAmF$6T=<+kBmGzIpA4@{TeUW*8s+gDN((;U7lrpsIpc@p_e83O1uFq_B@;N$j zD0sLHb7WbBxa3F*)s{>DK>2v;9WtE{gdf)=__tl;98sLBf@;s+K{FIXs-~c|jL1TM zTinz7$~f$BpQ&__cCchfDW~>1e#W?ig~De@I6tq1`^YepB;Zk-1l{NN6N{&Pmuc|% za^AvD&I5(x;F6B2hHDjWm>Ip!#g9%q<0XK;uE&>|-AneYV6bXSr=uL0cihcC>e-$9a45G0H7^8hYRYFg+#L zGSxA=sc^-ulKkE+nmyS{#l9(YV~(s;>s9|e`Mff?J?fTkwml=}fMSarn0A?18*&9H z73r@IwL2Yb!9E43izR$pN7onkV>;F!ESggU5NHQEz`SQ}rsY7r^IMTWS9=yHZJZr~ zi3c4t?X882NF0u9l#_SqqeeXGLpPuOi5HMkBVqP0aQ`W!_JQ%v1 z72PR;EjSGz^jv8#+|55aZE(m~Q0W;-7wO4zZjz<-ocMP+k@Y0h>|Rzc`vU>(3n4VL z4?|lhHU1H}@a?gHPc!}3uPh(_k*Zb;&1L!AWFW0!6qoDPQ@MH_uCFpzvRH5Uf`7;> z)}XLnbZcRXTbYO#+@Udta1qS?w zQpM%ShhsvChMz4EsGI$Z8~(_-10o@do2-H4a7|WtTNz9~h>-%-1Zpuir*-aY#wFCI z(d>D4bC_zoQ22WFP~#Re!;h-J`xbB7D};8SKb?aFz^*orwoI@qi+hucC`1%3&jsFf zX+Ku9ZWxt(Ej%J;0WZ8j;nQ<(_Qvdu_Cyuj;NeUe14S_xxXZNDbW1m595+WtA`8

j4l(N^9ipgq}3rGXWsyblJ5~hZlZNUZvxb7&BeLGMH4mu z3XV4dbgB(PD2@8pJ4wQNbnM5A5;gvH!8vx=tuK0a%rM~VgY5D{ZTM#d`&O*?1dhF_lFJ$ArGyO`$KPs30 zS>ngNmcR!^fscLrZjmnWa?eSCH9?Q)pd*SxP?IRsO3Bh>%fe};r9~VjxN;`J{@cj| zULMre z!gm0ayiU;RM!pktwvq1#$x&1^cf(!@$Y0^Bj4l_x+UN@5YmBZGzS-yn!k_)5b6X|+ zIinW{UvG4!@C`;+2;XRQx$sR!mkGao+Vq6DG$VT_K;3v3NY)`g54y$3FM)n!y3?_+J zDg0Wa7YM(0w{+91iZ}*POC`L>=t|*Zjjj-`GP+!Nh0$fgt$aYA<-*-YmkEyoPEq2&%L(S82uUQNYCxql*o{hw5@XOsu4-Bnx{m-1bLHX$ry%W~ z*B9CRn6ud?n|01+TH?oHw*V@6!V^Z93r`wdAzU!JQh1xu3xqqabkW&4M?@!}1QzZx zx>C5?=nCO=Mwbh(H@ZxCBS5FA)GP+WD$mj~;cNkqRJZ^NE@J_%f67g;` zSRj11(UrpI7+oR!9;3^J&o#PC__Kghl=x3+^#DNjlnL*L1NysLikprD}}#o^a9~4u5#)9 zv?HcrRFs5w8(k@UrO_3_R~cO{e6`VK!rukRxTizJlX3(V0Ch>|)s9@Z9waryTu3gl za4YERCjA$XbVXHAZh8Qv@%z9Za>iZ3r++0H(yr}XVYwE)w|P}$o=qZxd)iPrmrsyF z3Y{f)h+)*u24@s6=e>D*VemD%AICoclrzFVG`d{)0i!E~A2hmB_{T;s5FWVNxvdi3 zX!HW%L8B{$HyK?aJY;ma@VL=s!WSA{C47<53xq#nbfxgcMpp=5VsyFirAC(tUv6|& zh~Tq?vBJr!re6#`1c)+C>@nV0c&Qn$0G(iDrZme7C7N6+tA%@=)phRxSy-y3gR`ja zw5B%GI=UOtm4H%T_$s5zg|9ZcLiie^D}_I8^aA0^>wG&T;w6CUh42AJR|+3!bcOH& zqsxU~YIK?K8vxg!iFl(KED%20=t|*ZjIIz~WOTXku|}5(zx@WUC}hCcwG7z-rPX^r zO(p_vAbLH-w*eV^7yJW&nbq?`D2gUo_Y%|l0rE}Ayx<9w;6>dvL>Mo4q3<=NtOXwn ztw^Q34_Dx0cip(P#ezQ_E?Ro1K2o8OL*DgSHn)JNQUwnc^x&DJy+@*hCsO)RKr-Q5 z0JSBcdCr5hFnk@6ypNyM{a5&pe@ZU8SCKFimPSE$0TZPs5&IId)KAIJ14@#u3x#DT z3Vv`F2UFH=cTTFNg&zY5=HsB_o$EB1zeS|5#K9aVeLfG+%B&25d;T+Iw3Ag$*MLs} zqD+mPGzBM@kbYkVq6+#9ta6|@ijpVz!0UpC3d;_~>ejSS1cz}XW$^^(sA^ic3BWI* zJb?T6o^=|;mrbr1?Qx+_BfklgZvt`T*M5!_Rbby_Yf^r~A!#lIx!z4EKViXwLk`bg z&N&YIZvpUKNLHgY&C{qvJ%E}8;eMmbg+FBULg5d4x$rKd%R*X;ztGEsFE+Yd_+F!{ zgumzS_%#-)eNZ@Vks&D14Te3-2^K)gk^o zFB9JOd1Xpr_Z$)10VRm=qc?kl5ZeP0HaiO!I*ae~wD1=I3f`eN5omylunu%GpiWVE zlM{EZ_yR!!u>1+olYndpciZ{#{)V^2jk;A*9|h!FmXh zil{ui6A&$Io>xyl4}G}vrfORFL`PRoXWnN+h@X;VzW^vyLW^Cz+m&8d8L8k{T-!q! zWbw}cC-IVfCz2yru?WLRvaYN>oMAF(NGC zvPSY>@ajH*kPG>AT^~Yn7UBLJpu`dW27pzepBgFjCnJR_@dFD&M;TeHYTu+{_jz-Y zR2>)lDqlMtG{QYuIvteq!fXF@P^mFSOBOi7k;VHmBI%ZT_OB3qsxU4Ho8ps7{DnCQ9kAtR0=t|*LMlTRP z_=_&tcFqy;azN=X{0gHhg%2^hLikXl%Y_#jT_*el;D%BmWZh`r=6t%aT=<;;DJFCl zz_#_A>GL6OFuBkdg8UJPr%f*Oypf0D#ZdrSgx=tMWb<3ZFHBzSIaTl0v*i0{0hpW4 z5+Q%6CqfqN=s$Hr_!vaEa4LvoP8QPk5K`HYif@>WJ3&7*@*&Xgj1*E7WI03y`Ygre zXcy*op#mUr2)`1*V!ci_6+?#9Ld`}B$q{k7ICXUc0!xT>K~a_qRntlbDaFlgE&wY` z!EI-Wki)oU2N^?<$27bQ8iTwfsoP72<~6DCX%s%=l+rYS|6+8x@Hz%=l$M*yMXU!X zcICnwj4l&?JK!t@uTMkJ=Pd~5zU(YK;)pdc>L`ULZ}SGh<@4Bn3kGy%LaQ9v_8!os zMhgAekzGOw3Me5$`#Z9$4Ro?eh2%ptw!8-Y2Oy$)H@(&yiw^$pM0SodFO&&iY;>jY z$Gkk)-3@=GmkD2Gbh+@gMpp=5XLP0T=Zsz;{En}>$lvdX%`mFc!ox;a3Xd3FAv|hy zx$wBrWx``$_ln|>-GvXNj8HRnsEcFXYSbJm3XeLA?LzW|;+t7q7c}0E>6)*&aqg3G zA(K2(AS=<7^0Ca-bFr%+kF353m)?Ui23%?34D!h8qRguPSv0j8inRuLWL4H0&FV`@%QUP(9$9@|X7vqm0D?TSx*e;R znbyWQU4uNbx*KcXn#F36M^?uvMq2W zmBL@~@?dul{I|VK_)eqCg@0*urSKD8F8mv#Q~#cZf5yv%|7di%@Uuo&2>;3GO5wj4 zy+HU)-*i=Hk0XwUQ5_UM!RSiiHyd3c{1&6jg;yF~Cj3EwHgJz4K4b<9ggY9AD}}#gbcOJjjV>3y&FD0F#=k*-4$u$?UFyhn zLd)@rhTyFrg$(i{(6o_4*8#jdQ8F#!5t9q8zzZ5wp%zDW3!Mtkj@G>$+~>qyLKiu* zTj&Z$wh1ZJQMtR7;C$1CtWD@(=hr%+!vXjDg@RdY@*6g&;DfoDmHI+7TbiR*c}21MRk8XJ=FQ%rl8atDWt4)K@3*!MDU=Q3;o5B z?ZI>yR!*YmAAn~^11$5LvhR^4)4}Q|PA>0{*(vsVJqGQNzZF6u$5U>5@lrSN|lT_v1++vLKp zH@XU``>Nm(<9ldy3_??bkGA;aJM=zZgzS_~triH)k=;hPG-*xngY2p8H^l{U|&pP@|)50%u zp+0_E_z*{*FfDwnqu)F&TI zaK9t&fl)SuB%Xr*EWpZ*(B}Zgec2+<7=meM-WHr(0sFr>k-79x)eqj=OzJ2q%nywg1}26FdbSSa`^HAbdnN|*{e{Woh7(zE z+PZOUVx*^#-#RccIW#t!+!YJ^#zr>|4Ngt;6lA1_TT}bPLwy6IlLN_fPM9C^YDNdP z7m~vn`1NefkHxZPlT8c^4owmo!Zbcr$eWGiy+wv&Q-#R%4l^Z`eVg*qzqHxuADkMP zoD3?SLpDR8XFyFbS(q5;83`8uf}FsaQQuhqKwolts}pS;8ttDMuKzZJ!GS`4yr*yT zKq2WSrExtzG1faU!){ITgBLPN^!%gJV|-xLyRjf8f5CwKiM91kZQM98ku2_TP6&8^ z@cOG=St$DlHug*n7xF%81bkq7vZC8*b8a?H^o$JTHx5rtZc1)Jj`vgJ{XGRrz|@4x z{X=Q7@q1#Rf2vPWk%spm!=_{MlLI{yBzR$HWMHz;GcukWyWW}h^edIHo*x)3OzcQ5 z+u+2Rx5))3ImsZ=H6_Ubr#Q*vz`*9b1+8~zva?O~;L6$?cn++>(B{XGik;SkN;? zp?}4&`7t~;8A^fA(ew8<*{I-u)8wNA+mzdbL|}8nn6qgzm!iovh-OxH<&-bCCyzV(QA=P3`Elx^8iOOY6j|uc z$I9uq(P;`=fe#;cCO(7w= zFk=L@kX#VxWlP{LbDXjS<|@ZbQXl9h`X`Yv@=v_sJt9Yv?Q=LH-Ply0be2lz;OJCe zerr#Dm_8sGlBltjr0Ls?<8jZ9^h|7~Y@LHknL5`$!7SI^JkUSX)45}OAQ>)Wk#V%J z0%zNdtX>9vw$U!AAB3Lrc0TH9XX$FsEUv-Djh=B%z5;`b@dCvm`5{cMyWRDCJ;TX= z&1Cl_Au%1B8toq%9ZafWL$qE`51i|+9qyT&OqM{m4Q(G7Zg8D!^4NNc3 zGttvWJ3*2T^(8}@jSgz~K=SEK(B3mTIFQ_Df=v@+BRx%Heb%+ldkKe_`dS$TObqo8 zB&W<|H^Jt*+j>Sj`g%r_duDJCc+T~Xw;W&=9rG>6G^iQl?Ohod-REeR47Fp7Oz6;8 z9cA$%WrAqok*O$oJ~K|l+wO?t8Vkww_@ciUB#D7#mLB`r6cKn_8QR zp!53IzktCjiw%+!-@u+vdsCxEP7_n(h1ylgilbRM+ff*3Yz_K`kf>M|dQ^ow>5vLD zB*}F%Se$K5e&$4^L|<~?F>>z6!yVbCQAHi9lCC2DG_&eT5pfDV!Bpq%5<1=1y*g~RvHa`hXN&zq6P7v zrWD~@kKqJRg0a@!o}j7wD{wFHFmNMqJ8%*3DPSw`e&8fv6nG2J4jch21NH@80X&7y zzXRU`9tCa&?glOeJ`0=5 zW}qGj-`2x%l7)ZK4*#w#yKOaQS8l`if3+_irvT%? zR-hl)1cXm!lIgFmcLJ-3v*Iqhm9+4(E4ShMzuK3MLxC#bO~9*x*8$;^nPdmyx55zq zAA1!trG@OuZTSAL_MczQV=OBur}Ux^0jB~ZK=^7g%LC^ly9}5Q91)psIv)Fg{?PS@ zK=@ur{=2u*<^ad9;@CH^Cr4WfUcQoc6?z}=K|uK4kJ;}UI9j`!V<>Nytj z3_Oil6*zpd|4|^=4}aAb%zNqyFA)AWEc}(2?4PoRb{RAMYuP)&=K$gRf9vj=TEbdK zIYIySD4Z`OmmS3`#54GRDRF-m_%pD8wY2cPkbHeJ@c}LaJ^|=IdGz-^;d@a#eKVkc zf%xuv(!SgN5u+Db(iv=V*kJ?h0HD7tcoJ9%JOqSKW|i>a<$l?@?qtFUJ~Xl?`T59$ zz2N?Z3@)d=gnxDEOqEz)zx7SbDd2zV3-pJd+$uAg8m2V4t$2KWoI zgTcQ8KMjQMh3xN-UD=nrx!~~0ub@L_;rrDK$X}1!qk(?|9*XoF2d!r%-vj6g$?)l^ z$a>&n;1j@yfL%Z%&<=#J$@7)CfH)rnTts|73S0nu z2ng{G{{6G|O3@{|;ei+FR60th{LsrL@u!jA8wK>L%KL%vDKDP}jvz1J z4TQ%|l!rG(`S{P;yNfdUFF<(iBfJ2j7f5~!=#3IRu(A7Wj?4indp~BuP_LS(EQYTZ zT70n{+5aB)!zX?}_)1_flK&lg$xic2Z~Ezdkd@~ISIjm4f%%QN{T{H3a;35vKFNLn z{2i!xx4jDT7wE@;CxGy^VWy`(O7ZtifFAYu8xTJ6lYrjq_(mizcK0jHVs{UrOL6%P zd8LOf^nQ!dIDCrZ#{lJ}Uct~)6^cU(X|FmTzJJzU3%Uk@SkF+T=O3A0Oqtf}7kbA+ z55R>_vbzC2hat1@y^#Egi)jxpp*;lpf$+VMeC5Y!hc2i81)c}q3w!|xU$|MU8@VzM z-$T3c<4W3GpbrS2u}K z{nNoVa}qDtbqL92ej5wxgB zzK(nWdH`K-2w#xjgiP{bK({GmPnRshS8Pu=B6KO^H{jm^vcCxk-~U(p3A* zC4B*%)SLozZt_GRd{5lQ+!y#0pwnpK6TLt1dO%0djsRW*R04+r;oAf~3VaOEVX}*W zOMtDw*+BRnf_@m7`&Bz#Rs!A!cmmlUBYWD`{~(|}b?wE6uePBVp~DO>ou`CzA>Gruuq@hkIFQOoj)xvN)X&+clG$hsN3F7-J)BXjuDvg`Nqw zg*h2^F?zN4GFs543tK0=Xl zx4qZaxIW*|+?n6d)xD&;s*Sy?VZR&LJH)P+_9Q3W)(9^{Pxu`?ZBhnz>${t4^UZDb zt82)a+RiMpZEej(8)5nU#t{;TyH*8o^U7bo?0jX|FI&jle@5)R|YfF9DWlTM7?&_#-%hjH^+^1?=dt<(3 zRTiku_OALhbuPcy2hR5oj86=(^)=9+Sy8CFs+X;*PlhQincVqTv?H$~F*0&^VME55Bg~2=(g!BrV;Qf6C%FzG{QWu?#^|)ByQNOmkv97)~Gw7x` ztxwo(ot)|&9~f4Xz`pU0%tCY9l3Y_q;`UGz*US{g#;qJtLVE`wb^J%0@x(aKPMmhJ z2^jTlxDQiK1+g9PtHj9EcB`MmBWx0%qmDV^v#wYrbZ7@#5LV zOA>1>qU~mOj|=(6HqH`|AUb>H1ZqY5HVyP`o}3yfR@K;?%dhK*D@sFC)G)4UZYyp< zg6_#g=TFG+_^1Y@$2RCT7lxCODMDjsiP)fS?5NGP*X3QkAeA=J(g#(cf>GFpwxX8C zyKiiGia$lMlG52;o9}ArXsfSnY-p^n^G!(a6un{;pXPSe-E3pk?YhzSs9NHoJLxg& z0jR7vx)!yW7+Lb=UEh;%R3Se+-e=ABW=5>I$XEM(A16*YViC2ljSUU?RU10%+q+t-v1Pl@3iMVIE#AE)J!Wq6Z{Ir7 zM{`6R>4RLk!v7h^^u}!~T_u9fJu2RH-K+8)U8_19JJm&CI!Z#($8l6|GNE}=WYQ|z zo?B-vS*T=n>$`I``R=AVBHTBuSVzajT<7feXYEAL@Yv|!Le*`CAB>td_oz$sB}m;R zg~K^>Twv7SP* zd0+<_l6FR`R<|!*svdH(Kxy#~GTrEQ(-Ns*$151Fa@vYI9IWg!D{bnmXm^2cj*bWh#(*m%#Dsdy|B zSI?1NSNet~^W-we1Qd_r!%>tm)d%XRJIT>MIZi#D+?so4-(6vlXjgOB_&};kAp*o96*Vg2907GL?*M#G^ z_{f4a0BVqQyeI1a)sl1S$#OF^yW^DUG*r#G+WN(=#39WSpU7-YU2}K7ZFNVML)6XI zw$6O#hBk&PO}W(_nWC2Zrlt+etsV941Ta1|k{vbd+2Y3Wql1jw(g2*engM*zRz^(8 z_~ec}hl5fh^{A_wy4rIa(v;OW&Xv;Mu?bEJy4=tiB^{;A9CkHzHYQf!G~`xM_Y(r2 zp_$cmK-V61!^UjYRD5 ztjptc(2ky&M_F_(o06ruWZq_v)U_FhswW0?*p{Knggb3yO=TKrH+o%>MWVZP{kmLx zy=p8eXVbW33mL*$)c&DKdOW6ej4M(F-EE6qdRp(q;mUBvD6+9Mw!SPaajq^ii;HZk zJ&iLoHLB}qtZi&z0N5B0a~sz;`H7;X=8WQ2G@M@1 z(apTGaaA(Z=gN=GF|CVd+)V#Fz%b7pq|742tXtXcS~;Ef=^Gp0F)=i_DH^dfcQ}uj z<@t`B=^`a{aEA@ad&dfeu@RaMH_%~75RM9lfvfuN=$t*nRTn(Y^KG`tu!|w927^&C zZEsy`U5AfF&*b<3Qw!IxtJ0;1CDXKTXlkq_6f+KCrtR^Ps;Zn@chD?PrE!YG#^Zg| z#dHR)870Gdx(hPFO)r>QWasp2k`c}>=3R5bdc@4>p_WI+dv?&R(s=9GFDXjjr>O%c zJn8>b?bDEk*2NEdX`kW=pvH#z_SUYJx_nnu>N;qsPqZ8#Q(I{xb#4tzFtlSRVY7gI z&)}e|Xj?Ur>SYcc28W{z52L14oe?9|`r0*VL1zH4WQlrJ^}IUc=nj~LBy8!fuCbZP zD3y40ioba5b!S_dvki_$>8N3Rn)Tt{g{6mvH`!FGXR5GiY+~qi8>*$LqZOSR*O~jH zv#CjYQ;lB@2uHNj^%T|X&~LhR2`f`Bkw#hH@u_3|V2Bbm`)x~VsM?W0-FAAyE%mv% zDawg@W(aNd)iq0!!X^d}WX5oox0=%?aW7fh+S1XNQVVX(}Qgi=N$#Nkc10>vNN z((&7MDbtLsV#7t>vp{dIN!EDjwjTKTi-y)>L90AYDgeDiA^-c9|?JblwY8xepu_Yxpv)akQ56zf* zruv7*LUXGIh1J$-y3U!y^<_(`t-cQlE0t;3J61O)gJbE{p5SkHF4xwWZ*Hw^O&C1s zFgk0OW4bBR!{l2Nk!T9sUf+;xW66`cm38i^57v%pYTnWOHpUsg2ey%oMype!eFb_H zcPEQzjm{W&y5$m$kn?R#xt3ge!u^jCs{_{NPbQ4ex2UL7%(T9vxnkn}?$;cvdQWITv$Q^5vXoBp%gI0x8m7UCT za(*U0Habl6ZkMToTeoCkqXoBCw$YZZmHxv6+vyK_hqXlR*SNfCs(n4xHtM$GiBf7O z%ka7r7iR&B#Y;lF)~DM;6x*KhG;(T4<#udV87#V)oM4fWDuLPGXf=c@VE zPA)rd5_T1seaVmcgI$+7Ohv9oNLTL)0mAJq}XY&=Ej=+H1()q z8uLwR4~QjR4Jbl7Zs^*e32v5fZu2Hw!P{#M&s7FD8P+a^wGXK`ZibR+VkoT14(kZq zU}1?ljd->{qH^Sxh|=(M*R|!k^4+!7iJK((_Bn)hH4{j;^qu<2=rV1rT-i%a8e3R- zqCwhVqfdWcnN;RDpvjbX;0G`sn$r;V5h3vRyR|)mE%dS1l@_zcmIhbZ=wjO3P$O|GPwC8s!jNgv zP;h;syIYJLtgodn*y37@bhymW!ObBiYm$w2Fcfr$Za_o!QRBj2zUB)|OzP(v*P zbJsb~2sis%R!?S3lxgePKw^rS#?YFV&NXdX!X4R>@9~)J2gmniRy$f+*SVpi8yLBT z@UWva?q*be`JR!EpI4}yC6nwVgKk>`6)MCuhEEQYA`>-YO|VcU0+M{x2|RXp+;91+uAekq~=xKR_9#iqmj0ZWny|u5M3-cm|0xbw8>hUR1d>^_7c>Njrn_7zWYtb z^lZk3ebUsGm4$duG}qbAAT1i6YhchQy%b}crZN=S-aj1`meM~g>}JHZ>}jM;){n7=4eB%IkzU4sd63KjHS}HT+@oM!kwg>LTLo*I@!Fm z)oMQm*Swf~4UIeVWsOR#cDLtRR@b|&YPH#}%-H-Ox|@sJy|12YIe&mt0yG`j_DUKE zbqUqhHmFbHny=s7_L0sr6jL1BXpFyb&yQ#j?e_XDb*MLXgPhTaE9L%LzAf~Iy-Ibr zehig*?YgR(CGom#ceA$iSkZ}Q>0K+VHBA@uQw8n0eDx9zGDK$xvhB36G!kl8@SbfX zcX&YUUexX|?P3j?(MYP@a(M~Iq=}X$3YJ$<23g}BYM(79x+x>eVT`BUsw0_~^T`AV?Hx00H~67+eiIqPDmXK1>yuRWE#Pj+$`?OZ)U~n^by79~qSYDLQgn@y zCU)2rU|q&ewz*_bkye_9eIM-{uIgM~bzBy#4idu+$SlkJW}RR5aq}4(Ra%X(s~4(> z_9kie5*vS~Y0I)CM+i>L^tX4jP@zKPo|$kyrA1EztQB$2wB_PG9O_LnI6T%%y!_-- z4WzqFJ~A*eLVKQh;}#|B*Sm433lgn_7S*hnX7)Ne7$l^jwPM~JDKAc+2 z_Ee(rQRnLJOjUDZGwXt>gWA^C6V-TW8%v$U7MhN{o`2Y)VUCv0lHLhclH5{q++H&< zBtNvDIS*25>EjPMRqPw1V}!6p=Q>oglHY={5p8;(Oj{N^9xF+BJ%#zv1oA9I#H4DR1wtsmeIlVYzuT>6CRS zGoNcfZr9ke#frN6h8(*-NxvfJmK8}LYHu2x#um<=M7_M@7Z;f?DdLx^FE83k&_L8z zHfp1mko|neH4%AIw!fO;8i-X)p~Z%l7+UJu$aG0BE@JIDZ4Ty|w0cJrnX0*Ietwed zE?S(^el(fJ!6%pdtPVvF6}UybWZT%p=AH?yAW~ddHcV4uZD%{(Thy6#R4;QUX_!IM zW>2^U@GR*=Q3+3J%zTO>)#}=FmvO0xAv4+1{uE7=va|-uVjRy5e%2uxV2S#E!Me1dxfzAe*5LZ zqPe0ig2#Te)vnjjf(jWAgV*O;^6Mz!Y3NL#^$ovx-%_7z&ubE9qm#mz^^|e<&f4?L z?!B&UeWuZkY@=qawmE9nY}o7PiyG&;g#%kPve~>XmB!h;n3;~wYPtcWDl+3(TOf5S z3`I+6;Y1@Vl!H1Y$@sxWo<7CWn0K0rHz_UDrJatbcU0T+)cBrM`kOUx;1l7 zW!;??QrTVZV1R-HHVN3gp%&;U%A}1p`^ToVP?iQp!=J9&GfXIt)}PQ;k#@v*^PetHO2KM z*S8b>ZWfabgxNjM5~`ueP5TB|{i5z`-OZh1i-(zNk4|cBcf$$4*%ywwhA7#(lv^C5 zY^A*{W7D4D@l8D{hI=)%Ss0q!qI#Md?QJKq+^D0z#WgiVD05oZ$gG$`vu$9aPscaq z%(g7UJiX}5XX;C~0A>>~f;juDW;1faCP+3Cu{VI+%RMZ7Q;6LT+3J?Ag|!QpELys# zCYn0Uz8YnxWJtt%PJc3A8K78Ik$Ycw}X3sUi76^AQY-B}Iy#tzxn%SnjMbm){Q)?}od5sFT3WWnlgZi&X7 z%^m7=(^OW@5;x9UWDj*r47e=}H2GsoeLdqny+a&{)lnwDcV*>* z&9>r6ZC2}PU)a;?nE94m^fV3?-Y?n}O-D>c$GQf#xpV?byC>P`E60kLJDZf>I3A5O zx@$R9Gj6L1u56^uS(*@TTf6AMgm!>i8*A&6Xz7GC?ro~WS!?2^Q=|ZkcdS2#4nIHG z*H3%KyG1krZqYUw*;*B4ZRT@F&bDPW_Q@8PZLyfV@)Kzd*{%C$@xV6JY%#*^)A@B! zLbpSqOO>&$1*338!1x4yB1L*%x?r-r~vs6ROAJ=bXrd>9qU=5yIL8G`M=G3}8GBs`!7q;No^47psyVAa49%Q!U%1NjfE?rn; z-J%knC6KNtq+#t`+vpa+?ZG~(3WGeiUqeN5%3PP_&WHKAa?-Ib*T&)2@q`^mj@fo1XA#DE?++I-NY=Rk-#|fSoweI2%qjPD zf|pTRcCO2X+8Qf6XR{D*qhKn@w5Acy?%d@omv4Cux&-S3obPpUaIpQnPqpl&`MLV?uKJ88fx}X z{&w*6V%kb*r%VUKGH1DtXmsQj50+`wJ-^kei0=_XJX<(d6*+d7ury!F(c{@fcd~Cx zSAgsig&*n`Kk>?LU04i=nz~GHM{5gfg~3mytvkd`Cg@Ipciuu zg*&T~#&BInzI$!Xj+o3i$H9(mYl|ktN=(;7QA3KC1j)@tU2LkSitK=i4&|I!zrh-H zyG}9VjZZ9VR-e{c_8~}?Y;5!!S)4EEX3{1~U0P z=X)mHWk=U6r3ul|)zY5h3|!CFp^XeU#s_$hSqo??aYJdR8@dRTyg z?!+i*5zPR*T25rkws-dy?WkcGs8h3O`(+JjB{m!o&*twNU+nJn$Jw%Qs6=zOA>k^l>0HI1E76Cq!7O zSty&i{p))#txqSc@v(1J;FPe|4KsTdNiw-;UBX|HN&LcuKQvR+h>(O@z3yaNf0idb z(}Yymo4XWvo6TrJdhbVfQ|s%vYPqhpmD?jNb=siSc&Fbr!0zeOk*$`Lx)#hrzZS>_ zMy6bCWbZK5B2PQqnj(dc`ZVTh)&xh&sUw-SER)xEMp7Cdm$o(q@spd7CUh$9SfD+I z%fi0p9<@tnV3?w~?wOr?9iLEfpwjlaJ-r#jTZOQ}g%CUG_PnmysLW{cM;5!uf$clf zjnOd|ZFe`bq!cc@rcF+?6yu+(c0&z6PK;(Yx-e+HsP-3pCpu&1PHZ$gN|UvreO;Hb z(JhaK=eODHC5mqHZ*zjwx+U-G}e0deQhR z^F7zn%;_G|8Q*kA*kT;2jceAm@T%S>-RW~pms_cFqw0a}{iyo=IGSbeuaxuy+dqYl1Plt2b5gt3(#rG)OOUeil?5! zbrckGH@ryAnJPE6c62n=vziyTUa5szou^92x#3y+)R@x^x`FK$S=4WDB^K`btd?7} z$`VqI1790-;>)hHSlvpsv~eyWWw-+qGYvY}uWL+fgEB2+=9oU zZLM4S!jX>Dhb07ypgRtiR;SckcIjzm1_xV-bwZ5GIIy?VvoJ7a`vgv+DM zG}2Z)nq%3e(Y)(itfSBgce+QvOyTmZR`uG>R%TN>+jNhDpb0leFWlH_lo7rgT4d%N z&(5xhi$~ zqDoG@nL((whap^cYh5cOD|}|9m!sVcws`o?IwJ2m*sBQScpv)Q34t`gj4J%XxE;-6 zF2Te?GY@T_amFk}R{h*6ET5>_7G2P@hRV+AWAG@^xuC0C3!q;{6vger4_as;2YG z&M!T;r1Y(G_M2asyBqO6nBFzNtZv>8N#+jz1=+r@>=a&=ijPxODw6pmyPCS=@ycUh*sVaC(!D7C3j0)6z95m zrPsLd6sr)Sk+yu_o|$mf^Gem2bCGpE`6`Slk{(3L*iJCEko6$>}PTBUp?lL>jl z{N1IirKNP;Y&upE5VF#JyO#0-5meyy3iSaIzo&?Q1pZZ#c_nXBi$569w-O#JidWq^ zC1ZEYFU!n!&SG|gbH!^nn0?#a&5TR!{BcSbS$EYeSzbRcxZlOgoSTZujHM$PKmWAS zE@fbG>7*3!*sXnU;$=+pzjppYg1(VzLFhx-t-}0n%xmZGoU`tnvf=Yf&MPfBozmn= zZkB$@@mAhfc(qmVdiW--gJe$@u9YP>>>a8kl;MQPecbuEk|gLjuWZfvrEAVDDLKU# zV&!9q|8599$YlORWkH^`%wJj3KTAnPL5P3bn|V#h+^dyH={{ci zg|b=7LvCKlnM$Uj@Ty^1=u(09_HDfE1x-3M%&(|Buk`$ql67}eR_>W!7V=^zcFrq` z6N&1Iu}iD1C9~wZrN6wXZ003W^CN1EPFoYgUvkdg&KJrd-%YsP3ATJX)rBwb!x#F6 zsuun()$+2|^$YdZtk%vywB%2FbqggYBf?(VFSv9L_2Q;h>OXO%6QFBpJGbPVeOk^h z-R4VZUD~EUvX1pZCwnD%4kIOO93Z8qnNOq?rO5+KkgS^C}#A8|LqtL&9vJ@}FPYLZd;?n4yec7=a+Vzv(I{(m~%@Cna!-+FWi#0>rLmC_i=-m2&MDnWhTeTg?YxdV$Tj4_pVP2+ z3B0uxR_+;_rS+*~YKPP9vzWjA)J*TO_CiJ&Nb(it~tNt zoU)QNgq1GUjn9TL)3*zITL}2faGsWhQ=_orzMa~6ql#N`V_r9}01n$9aFTqK2c^;_<^o2EWZ!`;~3QIrOu*=U(xRr35SK~qBz`l*Esh+B%> z&&Y%SMnQ3XUo&r=VpcTnR8dSeDZ%*0ck`m>UV3+C?MunO%@VTQycS7|(xzcv+bq&t zI`+EhO8z`yFTch^GL-!C1p*t=;Qp(4<(V+g%-^c49Gy2yP*>0EnKe-833_*5&A%n2 za8)hFX2J>B*tB$yKpz55Gt=0-83+0&ae#{j{#sq85 zDSNwylJ9V(3t7-nb)&Vb=s1S~?839Wj!;H-V%|%gV5qM=rJe86(4yq)l+(NXm~ljP{nAjL!dRFF-TEV%@^8%+U)Mi}^w%E@zY%>d4=ZU#yT|~V&)~QIJUI3{ zxYHj6&*m=FOZ^G(clK)Avo_aF%=c={R?RDEo~2AO(l}(!-t~2fPY3-gYrn-IZJ)D7 zbA3_skJscw;bBWaOa!&=nK zN%}>0eXXarcVb{`vPf1;;tnB1yxz3Jd`wQIyLwUeOm>O6HXEr?-(&#;`MM~dA6m9z z*&=r(hUd#RO^t3|)VKYAG3>=K3lJ-lF*`oht351YkXb>d%QG`%+_Pf`FpcO;j(8-C z*w%8(UW-P@3ImHc1a}N8>D(!g6uZ^rWYHjJwZlMI8SoE2jTc#3Nk5gfa^MKyc0lF9DWrxeX66fAKMcjzF<$|Q0WVw^nGlfz-4Bu5XJVsa4#<~pS`!ew;+n+anqg> z_siKza`V z^!@hiIcZ-gUit(Yugc!O-mh~0(lGdi*qI66?CD^y;sxwI5V?`NO6*;Gjwt)&m%i@< zGve{m(qx=4C>{p_3WMVDC=lF0CSN1~hwm%OzF_t+Y^-nP!CAh&6tkf3&(Oh*G(1pI zl1$E0{{DzrtZz-E?`4<;efyy-*4J=ANwN_0@CCDdA!2=P=u=%(eAVv-eJ{sea3dWX z(YIR(;=f?_T5nJFN#DLll_ZDN8m(X16Vw#hJ94PR)m7Qi7wjGH?U|G@H1^_8_Vl$D z*=xhzk;{}bfGr86{&j|z-4j|!yYStyG>D~Xw) zG}$jr8|^2Q?4`fL#cMZa+9QzpQk;i%eDP|h!kYZv?)P`?PFRPR`Ma?n*2wp^KR>w` z^RWIcbFFk5|_!M0NMhnR=DEB?pu*|&f4Gx#hO zDw1EoADddJNPY$16!E`Kj9}Mo(;F;tcc%-vc%NIe-+6*_^$<)5$#Lh zRR-;=NL~j2oxoy#82m#KeH=45l^$3EROig;SY@XE8!20_)o*Djt6}= zz#kRyx4^$K;=claY{Y*HzCPmbf?pGb_q*^nMf?xovu1ez3HT=6H^FP23NBnc}7f1I03;vOapF>)!?Y6HXc@g|W5x+ltd0GMYPY#6FKY!Y{ zfAVtpuSND>34e3MzXtw~5&uT`#e~7WiliETZNx8!Z%ezK{gXGt|0(jX7G8BAxNn5d z+KeybE4!vwfAx$?yjU7MDHn-I4u4_^(I)jlf?Jg=Z3eJTl(_e{sa01%GO! z?_BuTMeaWUUly5P2tN|>m%-m3+5ZH5Ra(LKPp*bn8MUt>`3(HU5&wDkvm*YB@RJe$ zHTbVZ{I}uniTHcqzaR1U!T&7cAAtW`#Ou$({~GcC0smqkgzuNoDg%N44fNcIe+IfN z;{O7zG!FLv4*lMU--o*Kk%(7YaCyWZ2){exUjhGxh<_FQ>mvSj@Jl29Sor3MUk1M} z;@=FPkN7(H%@Kbhyvk$?oQB7OtB(lD5x27gDy>tBKYHR4C%e-`mm@Q+3O8Sq*A zS>gUs__@gZ{g{^l!M_Wk_0PwF|0wif5kC!mWW;|8`VA3(1N5e-Jl+cb(TM*V{L;w& z?a;?Z{J%iIHR3}^giDjdVirDaIGntc5#;@;TgCw;2PD6Wc(nt6E8^#+ZJo6f2f&B( zCI{fd(M9IR7x8O~__am+rXqez5r0Mze_j#)!6N<>Mf~+e{Fh>$dUqduIIE%fJPf~k zsg04uKNs0QpyVY<1#Q)y$ow$)N8n#Y+R6SgzAaNSzJ!t2@$lg+hs;lemsv3103XhF z$b14moaYdK0em>aA^v0V;ZuHHS;SutAI@yZe%2OS{@o$_{!E6po|Ar#IT0DzZI)5SeZ!I!!F5=e}@x4X7{;4~BN{_SQ zcccH)(9*B73gHZf_|L<<)~7mE0I!iTdHvahxzoRbiLeUbgI%YL(+gOK_6;KSJl@ejj?a}462 zmwBt5MG!wPn#?P`4k_YaU&L1z@hgk?weaEmf%NB#%tvH?vYjK4`8$iu&xH?r{xbh~ zk@+?7Veek%H^YbhdGU9_hdp@lKazdF-!A?M`0y#de-+P!r4c0ac}%v#zPR{9;KQD` z_+zulm>Xx+74d6}_}(IZyomom5r1V7|IH%)J4O7%;+cRn`0)Rx$o%i{VJ}_buV7y& z?3;@}0zQ07kHz9IwS94!yMu||g3Q}75BuRV?Mf_#9-!1c+i#J?9l z>{W`t96o#s|FuQ@t?*&LQug=2hdoB|_rr%hMe#p_4||E?e+wV>4#oec%)e#(d*aJk z*s9uN`*z|F7XNMApA&x+eE1Z;6X3(XoXpo0nRgcP`650Ee+%`(|DYD$f8`RSf7FqK z)ZRLqR0G_z@sBmWz$M>BTpu4DSfuxy{LA_2C9RrSWSkl2x}VqV?~%;%cUy~=Em`iK zb&F2ary-ox{?f(EIU2s#|8^}}wzTSn43_B;rdeDp$Lm=QR&eWmR)gb~9XHGKnAvsw z;l4%7YtWiWrktcIS=6++W~uvK#&4|zwc>d`h@Tq$u-(~I%U)(vt+TRR)C&C^rypKw z)339{EBvCJ-D;kI5#!U5sxBC;@mDaSI(0;;aVy9uT#lh)ZZ2mg?Jh_A0B~HG?BIYzKaT<6VQKruA5~pX0bGyX3UFz&F zb@rD!JxiUdrOwq-XLG4@yVSW|>U>%1+%9uAmpNBlJ-`<-U%yW0GUtl?L9*P@D~xtJ zm$~2NX5Z;t?zAm;dX_uCmOJ?hv*UbR?)+NeewSMqoXr)^EthNY>p17j3Uh0w=DX9p z!nr!mX*kYl=6xZ#a(0e$c8)VWX4C08&grS9&||f_%9&U5c%ZmYR-CuhzO+!LolO%~ zIWMZKoc8J}=T&u;*XaULU2RsZXjS{t=8Kz^qG~HN)mBETeSzVYt~~O^%1V^}DZvTN zBQAM4&H`@*w%W>SH3fIJjePd%^Q)U$SLK@Wtqlzw_51-*ju)o#SoRmzxiGU?*F$tK zj%zNi8L^j0)ntYD`LMth6Fu#hpWu39#PUW1?^|r`A9BzA>l8uy46R)k#hjM{y}4I{ zY$_A#;Sn^3hXQny58iI|(H82l0_PzQM(JI2cML$m=HdP!{%edE#`RW%HJADD?nWx$ z3QhDMDzhaLryWw;;hq;B&iI!dduSm1&nc!e{vB=RGXyTM{@v90k5DWYvp%SblkBEH zah~8psIC+12_n5$gL(1)j!Ha3Hru08q?Z5p!jR8q%O$R~x(6<11QK8M_%>)X_^yBu z9tC2?!>R7s4tvo`4`6RB@b?Yz<1ILt+(iCu_AlW%4<`orPXcpej?==_&poE??!st~N)gUE-jzgu8ri zy18OymzV9P91i@AO?wLszUWzD7b4XVuf=(+KVqFMzRQnE@gp>dHtM~p5Iz2UfQMGN z@a8U+hNnrfuZ2^JYz!4!m0C1LH2(Z44Lqwn2m zk{M^&W-`4xLbR=+P|4Kw-x&g)3*p6M9X{fpZrv+_YA&R8rlT1G9KpN%N%Mu*^g@f| zGfoOrB}|b@=HAx^gK5aK%u~x-pZ)sRA2Z^zUU%Oji*HU#W*$R{W z%^%LA{!Nu2E1i*n3EjU<>sllFGQ*kAsit0qOU(E{TQK_td^fiDgL+qE^3lJ7qRC|T zyoQwzS3^u}g76mL-d2MN)xcdo^>}Qfd-^N7AZ<=*ss`KxCds5qks48+QzNxTHanCz zJg9#sv--nBFVr0D@kiAO|7|MEuIqJ_??yI`xjIN>R2?nM?sWiV1kymyczFYP)Uan| zDy>r#3NA2*<|53=q%Y8J^a3Al`O7TO&WwCfIkguBVANErKA}K%U9ofTl)8%UifLL0 ztj^8sDZD=SRG-|d59;ABf-{&mJGZ0=o2QZ$(&p#B(`_@Ltbr-$nAjc)W;peDMPwU*Yis9`DCGx6E@M zZ}<4~9zWsnVXXJcUZ=+&@c4F*|I=gbIm+H?!W<|#9jx$u+4Dd5SnI1w#|qXJW$)D< zpWtz)$HN}K$KxwJzSZM@_4sj*|J&mQtmjGZ(H?94QT!<$7d+nO@i#pFmB$NMACvu@ z$D$O4^7s^w2f<2@36Ib8SnEQPf5hWY zdi)uWwGJfnZ+U#L$N%Q>BOd?8<3D>mXTG^x3|2ij4y<~x6I^yHd%a%%Z7=V7F>=KR!44mRE8?rP!Nl4OhnQe|J^Y=1EB;NKoe*aK>VRX--ofCx><=vzelzWcms-uzC_ zGXYM@zRBJ+cjABsoXs z=($ro?tUpAcglO=Bf)d)lH~QmxZ{y$=WeykZ|1C#c-&np9{c~|@ne$LC&{mcardk+ z{=JAYBzJ9Kx!WQhcb9nlImsJ{k1+1OCXBo9%N%z<6;F7c6kd&tyq5gMV7WU?7&&Vj zPF^RTaPV}TlaG4&4)LVN`Cfjtm*42+Ul(4(*%>c?Og#QRJ18^CiLxhv}B_jvhzlE007@$%nz`Cq}McX9TP zGAccXfTiaR;L>~8Pm%odoPG21cFD1So|j+XpNKMF_OD5D zCRpLVL>Rr7gXQ1#V7V`&E|h(b_*mLBf>wW{t5p(dnCd?Bmcm1cLP}Nz6zFq%c;wXe-BvZ zgJ7ATCHc>JAH&P9_41cdr^_Bml10M5pnVm_-wz5uO8YMS7`mwIWsh@zO!$}FwGl?X z*5e+J&jrih4}j(GXTfS`{vh1M`EBZ6*{>L%2otXtQ5O`hMc}#3lppbw@6&~!Op*@? z%sW{ zFnDfjlKe_M_U2Hx=C+~JG|c9`Lf?rpM|maYVt_w{RXhye;BNO?qSkS^2foF zzlpGxJxf0({0wIuNi+4IONBRZc1QRm#z)|?KXGPV_&M5bu=M-^EIogd{3+~`mUB;L zya`q~MumS(xJkpZKU2<0!?M35$qz`oxu?)xgO%&()e zEBQcw6K5Z3J9{e>dMrI}#6bO{d2?IMQBr!|a?a{U(XVecXKVTcrO)dy>ElRn{ignw zdXRjm_r2Bees8tkf31$I*We(}v|7h1dryC3Z_nzwvKm+5b$K%snqjs5W~=cTh6K5U zy`kf@I{&k!*Spy2cve{*W0Lzio}1F^y(7KeZbMbq{5gine|6nT_lHaOce@@Q7RnYI z)N@PM>&W!_yS1*=dsBbM^{}wedFq#`=Nzv3e|7)2x-RRCkb20bgUu8cS}4Lv#%yQ(?YY&t zyDEJiMvaw!>v+ehu54}+}E!$_-hJXQKUY`2=P<9NpEIHK(s-A|;Cqci>9^aoqL z*5m2FYjwS?w7TAQxv%*STFrOd>YDh)ea&}O`unDc_~5$FA${F9l<9MZg*sF3PJK4@ z4b(rUe${oo9(S#dGvhp|Kg`c#bv{a9C9I3h@CBS`FYD(uTx&JY4)Rg_1s_@MFT?y` zKb5R#f0`6iMVTg~?w`8fRx)PJR(b3t%E@=2eM@-qE@!a`5mykVhMb=}i`a1f+eyQ)*Y>}`~(qj3Aex9*gL!s&)%5-6&mt=(A`=gz;-2-R6 z=QAvkdXGm+@3+3Q-s>-rUvrMr@mRgbXSlB8NU%l2LZ7%^Pv4(A@6gw2tNuN!^Ivvp zaD0`ek8i3>Urf(rQeRJfm+RVprH|x&{rn|;J^y1nYn{ua?jd=lujh)==dHT*yiH`f zM18;Feq>lEa=Fy?(86BRex=9HlpddPh3aSZyqDE_8rkAuq3-0Z(&KkYkB?Xxj4xm{ zzM0kdSgZX^!TFeMHSU7+JXfUWc|Jk)tGbS4gzkm!IP3M;EIn?E^te5)U)0aPGD7#h zJ689${HvtyX;ISKb#m4{tedT?zwx&9^z%CXcbx0%`xECKn%B9eehyk4Y+qPL=$==` z>RwmPs^8juji2hQd)-{Cd)z`hOW)7gI$D?XI;wsgI2dP2uV;bPdNxr{a@Kk-IBWjf z&e~t?HNo~RrSq%K>PM`VsrouABWCM9X>|{M&T9X2+}F4doVA}5&RS2#Pn5O)64JS> zv-(x7_Wz3O+HQ=q_Lt$sNi4rLV6c(%08C*YyzZeCi)k-|Tuh-KVJkLj8g36~aQ*HwE+5mY%1f zOkX}M^orGSyib1~{T;4X4hwx}Pv}0QHALv%R8{)t^LS_7i_df z_Y9wx9MZ=VC;fYja!IQ1*7>yR*Ol%MkrBGb9F<+7xbc8{&L%b;`O z?P|;PwZcMOr29jy`XlMDmA*c2$n>?t^b31=S${ie^>wI|{W%mGXZ1lqE3F=4{oP*C zeNNY2`ty2T*XsSUL3;krrT71%jL^OBy!$#w51e&xOQ&nlIYRm#_oS_+uSe9YI_uuk zggn4m_mG)Z;}%n2?yP%368W^V#yzwem*uNqKRKnZ+fw9u&bkLQCHJ=V!a{GlzDU;- z^_Ao=$cLPDJm;MCTHbcn@q}#;awh5HDPXn#veYX(>v$TIUv$-CHm^?_E$wZ^sx3vDK64Cxxl z5IkEORyz3X6Pwp{S02P_IWytelFYjIzGS% zokQ0P;8XZCHbs9fp2zjZH*gZp#$~t(cj6&DgV*prW=w}drWk`gaR~ZZXCL2k+=M&uJ3NKq zdLw&$PArc#(f>Z({pQ#jW6;mPx!)c8;y@gRqi{UN;S8LG^YKGmfopIhCgL{Sjr;L? z`~iQ$bC`<1;Vrz2|Df+#KE6zt4Rd2bEQY1A0{VG5Z(j@RV>CX8ZLlN0j6Lx+9E^T$ z&hw7J2{;A)cMa~(!4GgLCg3Ny8Moke+=~bB2%f~VcnNRg-}n&2GY9L*jM*^{7Q#p@ zgB7tl*2V_d1Y2TT^mBMV{#URU`q^FAUq?TW=j^}luoH1A&cwOs=kq-7BV2{+@KgK( z{k)#Xe~kyx&+WN>0#D-wyn;9IPxRlLc)NcweMFG6U{1`3MX&^x#mZO%>!6?S^Zd=Q z6}HDt*bV#O033>=@GbOnex7$G#-pG2bA1J_#m)Ey?!-_>}3 z>9Pc7!CY7Xi(wh8gf*}(Hpb_$Exv@^urCh6SbP&F;dGpZ3vel}!u9w$Zo@rz0FU5F zJd3G#4gbJ<_!u)j5uB%N=)WiO`74Zmp3u1*R>fM_0Q~`p9@h$EunYRRLihXO5FCl) zaWcM(b8!(a$2GVKx8P3PkB9Ljp2N#{6Yt_9%#bx$Z#K+}MX@wi!kSngn__G1h+VNS z4#p8U9;e`YI3JhdYTSrha3}7^!*~+U;bpvuckvNs$j0%bpF{NPR}@QQC9H|{u_?C3 zj@T9Z;$R$s<8cbUhx2hMuEveH1$W|pJd7vt9A3toco!dGhU^?a=Eb5|8Y^K1!uHZan#e!HCYhg3=-(jX*57-|kV?3_JgLncTWA^_9^AyF3SQlGjXB>r7F$wqJ zVLXf1@c~BU4)*sHK8;PWH@<y5tA_mQ}GU_(=YJ+I_Jic7=_UogS{~p<1ii*FcFh61yk`3rYpq$u_Q)eG{#_W zjKw&N#{^8oWK6+Syo2cqvwtj!Q5cOe*c)Rp4&yNa6EPW6Fct4$x+3f!OJWp8V+{7j zSd7DXOu$4;#uQA&JD5(txJ`Tgu_Q)eG{#_WjKw&N#{^8oWK6+Syo2eUWdB$aqc9p{ zus6nH9L8e;CSo$CU@G3hbj8>|mc%HG#u)64u^5N(n1Csmigz$wB>TgX7=_UogS{~p z<1ii*FcFh61yk`3rYp|=u_Q)eG{#_WjKw&N#{^8oWK6+Syo2dVuzxIxQ5cOe*c)Rp z4&yNa6EPW!mkjn(8S7&g?2n^y8ZN-qn1soA953Q+e2m#k1^X?ENAN6O$LDp=_4}?9 zzJ`-A9#`ULxCf8o&lp`MnD0I|d@9H_*dIsZG~9@-$_Mie!m;=cF2c3=C4Pe^ z@eYPp;QU}DR>20?8ehSI_$JQ4XDSBsy^I5J1o|_eeI3n2KgZ+z2`1qlJc8#iPo-dd zF|2^i@kQ*3gK;d*zz=XWCgNT^is$fme2h6O2kR(~Rj>g*haIsuzJZf)HZH?WxDyZI z8N7z~F>{q*9r>{g*2E?_07v6AT!5?bYy1H(;4OTNIjZtHU=@58+hBJbf)j8SF2l{Z z8;|07yoHZ3M>Y13Rq$DCgMMDh*O#A@vJ-F?F2l{Z8_(k{e2h7&vtO)&&teK{JHcrR) zaUL$lRk#_y!f)^drlLQ4)axsTFJKoOj#F_CuEG@j9Ur2fKl8j#V>EWgN%#@2!!Ph_ zJc3v7Ps~(5n7<^}#pW1;eqPP%n1Ks$4StS4;5p3EAlR-V*2bpT4*TFx9FH?_39iL0 zxEK8#oY!{&Z{mH-`fSiIfTgh-Ho>;o75n2joR0Hx1%8S<@LN2Ie`Dr`!8&r|lUM=k zV+)MI?ii1&@l)K62k|n7HwyMw3_IZf9F5CyJ${L2@Ggcm4(7{_g|IwUx8b^8v5t+@ zzYoK9R)WmHBU162mF!xUzj~Q7+(a-V{L3?!}a%s z*pYfS>_>f&)z2>Ds87LJ^y4vs`Ud=h`d3!le@8t9&(Xh#e^7sb>6--W%WSoM9;@Ro zilwd2Lp7`8sENzs!Rt>#^goA3zz3ownLv5sai?9UEastMPu$)cYBV6LAXtrR0yT=3QsCzOSe!<3Z{_kWb@ftL=WH zf1i4I^I*T3tmex}&P#rhT;6K?%G4WBZ;q{~cO-YizSIX;9p?z@3@V9 z@ibn;TUPTuAU`H&X`#B#V*xB`HLfhVlGSlGA~z$yNbYI1p1#xv<4CJ{CRxotjrwfr zA5vdV{>*BgEmr&6OaB}4QSvFgU^V|e%<){1^IOeR82y~E_g@_wVpFT_J76rnMgKkg z5SPSf6lu_pCsa&v5JbzFVP z{jJXD1acfX-fDkKa0T^sWIqS(G&S?1?0_E=iw`>d3NCe>c`1H;(6-V$iL(NsE4-- z=E;bWR`XXNSHU*aUnFzt2^=&z)|mAs#P%xe4zJVpN^{acu+ zb+F$&SkP+SRmru;jjiTuhArvG(C>*ua2oxY93)`fxMf3 zG9ID-6JEgkR_n~rCYaZsvEcbjS=FPkF}A}VR^$3$f9k`nj$<5oI{leAoBksDiR2yh z_gK9Shp3;#)6`SRH}Ee0Yqj1iZG&}X$NyNZrudE9oR`VXCeu?@` z{FC}WdE8-c#Qgg@dEWrcpo2Oj*h``=CL|o1+X~v@>q>}O>BzK;mcO%t3P?L)$25#`c#~S z^XM-nuOcUscUZl?2d&n12#?XfLjMo)W6b_yu#P-d+gHRo*w|{mX4ukd-2-qmPQ_VP z`&nvRZ#hjKap)9(&az1i#av5?>Y=YhCzmBog z-y+A6-zUeDKO!fPH(6Z=iB`w=CGMernEV6&Nd2PKdA?$G{;yO2oBBWGjIRXa@>m^b zq}6^(VOjbO=(omKa3GGf+TU36RPwvz1>}!$J@qfh+sWUMzbF4lzKqwX-z8`0%KEXO z)p3-vI&bByj=vWD82UqSEKb9C+>75~)^5SP1+30b5sb7t?x*QDA~z$qBfm%&9)waz8fSK~VBiR5If@dv18@prsqHSa@mhVIH*Z+6U&C9KZZQ&!{aSna0) zHn-ZYz18{cM!grlN`D;vcX2I#i3jn7)%>UMtkwLN>E9;j>=Ep*h}HN=EM+70IU82% z>0l%E^RLzVds)>7+ekg1ZngcJIKyh(T&r#19dItThR`vW=^`g|vP=DHLzB<&KS&eH=Zf~`HSL&}?jUPaNB=rea z1=x~$JF9Wya6YcU z&v6%ik3ZoR{1YGJ6TO3Z3t<#Ki@k6%&c-FU7L#xfp2Mttg855hHLQ=_aT30R3vi_k z*Y$+!tj^nac+~2=oF-qxTht$rGxrU)%a28@wyT3Ju?r5s5mx(qll%@Y#?@Bu_f1yo z{M?q(?-{JNJ3u~0{)v3Sme$u3>UXWSzi+j@KkLogXSd4v$tA4Dm7)GL^=GjKwx<6g zxu?~3eQ^Z!3FJ7d{lrsWf-9)6BPUwT^Ck5I)Q{mw>Q~9P@jiyXrtNiHPhcJ_gEg=| zHnZAaORM#Dq28U`j~r_?ZWQ%6>eI<{$cu4})%f-Fw^QFk{+4_k&smMXNdFJ&f0G}R zGxyUt9bYaige9@E)jZWP8k=KVtL-~u53A#TgFM=5`*HXV^#$a`R^!)E-%Q?0PPV#U z4_VD~41d8Zcn=?9*8Uo=b^XU`{=!z*ZyD+p$o^bHkE=^=ZZ-ZT>OHLX+XqL|A8R$= z44h{*&m!_CR@-gFZS=n(e`mFy)6~zCe~=P|4CC-4;g+w>n&4-E>&rMH@| zh}HI`sF%fx^qv_4C(@r`HQyYo^~}db^ta(2t8s_uAHx&$@6%5|SmU(L z|6qQrc?)Bt)jT!uS*!7_$(^mncg3Fcr_i5=pW|LUWHrxeJa08mD*kG<--np#^7-cnoEo@3X24A*X_iOYA;t=}F@MEiSo9KUzU(i28{~F$<{(zieXt2&KR`cYt zT30@Dahp@GE4jZ_e=rWSI?mPflW;fnedMF$bC^m!-!N^j{g%S2R`b`u+E(*-#(p^1 z>O8+;wf%e47g%k-nEuDqH{(|P#%jCcR^xxf)AavAf99w6pWSMFUaRqi@JXzNb*znrW9iSOzm0qV4^jV#d=-DE{m$ER z?qjumKda*yO??thr9O*1&uaWaTtWR~@;XeUzSnBr6XbLBFH--5`U8ASJ@asFr}bvD z+CCq-u+{#HVOi>R$PKKu^&^-< z{Ve$+`5O6_)%JJrA@!^yf_hFYXtkbFR_iQBu0ei=+=SfGYTnM+js9qyOno}ew3>H5 z{Z+URk6F!k0#8|uzexW!W*@1#)>#RkvD(g`_iGzjZP$hVtJDYJ>-2}ypGbW&PNzSI z{&L(({TochU+Mpa*+vEHD{HlmO61z)`s5bmPT19I{XKCQ^$EDb>bN)3{|vX#KTQ8D zUdME!gLM?gGFJO3k5#PZt&3goRr&+)b*tl=O-7X4+op8jS`w3>GZ{qONN z%=Ko_&u6v%#@L#Adva&1{r4dEBM-u%R{NPxe>HBT{~2zv8n=u7w`6|~wd-f8Kfr8b zgZ<{h;#T9zV-4!Hth17l`rYXdp*|Ylrau)IP+x|hP~T`Z|4!=P;4%6q@DlZ# z_&@6ZSZ)8rxM2Nx@JXxlS^}$6uZvBoKZl*E_rgKchvG!)Gcca|2be&8114F$?mOu3 z!F}`((?5$3@QLxkcDb$ApC1cby*>@;x5Li#yJAnPaRca&!4GgPerh#;5^lBHZZG{~ zcpiVpN0{|3jo0xN#`5?K_OP072)>2y<43s0Y8~rwJN5nKZ}BAcb5{HPjrvXegZ=~h zr6&aA>RYX&F}aP+sjt7}p5#}_!>q>7B`>yG-$%HTzCWkk>o|Zv;#It3wcY>lAFFxG zO$@As4XoyAX*K=@Y)^jx{V_NlKfsT1zt#5N;wc-c&nLz|tonDY-Y;R3f_@gvjYY7O z)w-(T3pfnpa6YcZFK{3JfIs7H41YVAKMxki%67m0?t$FU9?;LZVKO|F_J0vig+l4| zziejAYRl^HFfk7npkIU>i8=*oM`{Iq@^EPzEY5=&uOtcdz(Uppf*1#s%0sG)^oQ(5u z6(-?6Jb{<+FC3OX*#9IfQ6R|GaUQP1B#bH;jElw?JdVHMpSZM;#_!k99rl2J|63&R z-jl&R*NX-H%q0Tho|nUceaQXD zYstR9c>FQ4?+?y?pL%=0Po4e#a`yYnIf=ZLe2@H)Tu);>zM<7Wt;lW3uaJ9?2a$)8 z$B`$JXOd@=*OE7o_mK~h)29pepV_L`gxrGMhun`mlRTTeguI-5ihP!w_PMk=zRc;F z-zxjRYwG>=A@?KiAnzgP@%=#K3s{XGL>@|>O-}oKSM`sPPtecm_q(=F`y5yGtCDM2 z<#FVR^f*!#2Ur+qG`ay@b%`u)h$$!VXbsqtsY z7wG4V2L7q-d`}|1tH;_N2e~f&BoHGmaS+9>=k35<@j=Yt;gM5K}iQM*y zV7?Ak^Nk}aA?L{&j4xm{ej<4?c@KFXxj?pHd=abhL&?L*v&r+wpOTZvC&;JB zf06HzBeMtdm$I6_54j(C6?rZB5cwGS9{C|TXO3XLJXZ5{Aa^1UCyyr2B+n*qAb(0O lpc|F1ry^GKwIz2Tk0y^JFDI`eA0!{Ly0@PqpS8Nj{~s%WGwJ{U diff --git a/tizen/distrib/ffmpeg/lib/libavformat.dll.a b/tizen/distrib/ffmpeg/lib/libavformat.dll.a deleted file mode 100644 index ecb47b74f8222ee38766cfd003df57a7452fd09c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109306 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 diff --git a/tizen/distrib/ffmpeg/lib/libavutil.dll.a b/tizen/distrib/ffmpeg/lib/libavutil.dll.a deleted file mode 100644 index 8ce40ab946cecff5f1324d401768d7e87d6a6529..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61512 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

h5?Jse+A=?Yx_YM{#s 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
_aUHIw`zjcB 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�Eh&ouwTwlHpi&QjE3cis9cU%8t@ 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%0D_vI6k?T$0K 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⁣JCekA_9&b2Daz|IZsnaq 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%0Dm_SHzvbt`ogS&M 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 cr1zf__T+glC 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 PJR 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

~`tczr*OLVD-)$))F2 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 diff --git a/pc-bios/optionrom/multiboot.S b/pc-bios/optionrom/multiboot.S index 9131837..cc5ca1b 100644 --- a/pc-bios/optionrom/multiboot.S +++ b/pc-bios/optionrom/multiboot.S @@ -20,6 +20,8 @@ #include "optionrom.h" +#define BOOT_ROM_PRODUCT "multiboot loader" + #define MULTIBOOT_MAGIC 0x2badb002 #define GS_PROT_JUMP 0 diff --git a/pc-bios/optionrom/optionrom.h b/pc-bios/optionrom/optionrom.h index fbdd48a..aa783de 100644 --- a/pc-bios/optionrom/optionrom.h +++ b/pc-bios/optionrom/optionrom.h @@ -97,22 +97,28 @@ #define BOOT_ROM_START \ OPTION_ROM_START \ - push %eax; \ - push %ds; \ - \ - /* setup ds so we can access the IVT */ \ - xor %ax, %ax; \ - mov %ax, %ds; \ - \ - /* install our int 19 handler */ \ - movw $int19_handler, (0x19*4); \ - mov %cs, (0x19*4+2); \ - \ - pop %ds; \ - pop %eax; \ lret; \ - \ - int19_handler:; \ + .org 0x18; \ + .short 0; \ + .short _pnph; \ + _pnph: \ + .ascii "$PnP"; \ + .byte 0x01; \ + .byte ( _pnph_len / 16 ); \ + .short 0x0000; \ + .byte 0x00; \ + .byte 0x00; \ + .long 0x00000000; \ + .short _manufacturer; \ + .short _product; \ + .long 0x00000000; \ + .short 0x0000; \ + .short 0x0000; \ + .short _bev; \ + .short 0x0000; \ + .short 0x0000; \ + .equ _pnph_len, . - _pnph; \ + _bev:; \ /* DS = CS */ \ movw %cs, %ax; \ movw %ax, %ds; @@ -122,5 +128,9 @@ _end: #define BOOT_ROM_END \ + _manufacturer:; \ + .asciz "QEMU"; \ + _product:; \ + .asciz BOOT_ROM_PRODUCT; \ OPTION_ROM_END diff --git a/pc-bios/pxe-e1000.bin b/pc-bios/pxe-e1000.bin deleted file mode 100644 index 7ac744eb39f55aa1d6f18cc9257efe1aa3be401d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72192 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℘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 O0MuIH|J(nKJMh0mlr&=i diff --git a/pc-bios/pxe-ne2k_pci.bin b/pc-bios/pxe-ne2k_pci.bin deleted file mode 100644 index 5cb68ab2da08df832be1a5451ad4806281abd7ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56320 zcmZs?2Uru^w>LcLfdmpD^cEBlq$|?F&_O^$k={#)bRhv0l@dTg2-af*R75;B6pzvs z2q54=6tE!yDJo73RgoekU;N*D-}1cQ_cknS*zec&7mY@P8jUfD&K^ zknLT)$as0>!_plrRELE=rv<9xHDwXt^57V~e z>cyb|XA%JsQfbm9eUM)B;dHTDH837l0t%;z0_-w|H$1B(-fE}0xDEvSX{WKKt&8-bfF8{Y3i*|n6TRb zX4GEVu1OJ?L<5vl$SfG{Hq{cQDZGpZ_~_QvKP)h?7QwhZF24cz-y%Ic=(GQiNN(%q zpYdEMC7gn*M?wJ#XF`O6kn@89j9vi+_pFz}!?i+yH`8%QN}RBvp<6ftOCiSrLd{S@ z&9DVSv;!+0cz`D16$ivY|GOCpS?0fF%IL$G1491iptU5>56WBsPecD`Phr{U!YD?| zLYYDXQaF<$u|IE8m^Oy6ZlMlvN`w*DX!*a5D{>#`oLbjXK?48ro&;2AS$pXJbe6Uo zEgK2+f8J~r`C}YOXlo(>Vxg@XFc1lCfeOGPNV%|`3~kkhflH7II$Ru_0&sV5l_=GS zMk3HBD*7kFh+6-D!KY2sBLYNWTnJA|WPoUA=PkVQ@BoOe`+bbe0a0>lOj;Vzo|c-R zXGf$Z6Qh!oD2HO{sWC)AUtb>(75x*|!h_2+OLH_6&4QZ`_fuWF= z{o~*S@JG+vkk(2V=nko%3H7u9^eL5DFpALk2z`Nm7OY?H53~Ogy8n;7wD?0Q#6PKW zC@GdmNli}tUvhETPH4Bq(?j zTKeW`uP&L&g7p#8Xc4LZ;TV${6Gf*TN=_05D83Xw6{NSgD)X}mD_hc})S2L?$qK=0 zvK+<#4_3j@FbefZjPP!$dT=uJ7ql-ZCe6lZGt+(^ugi&`BZVt~Zi^(urtFWdcyXzElxSu|y^Sv?W|6#lQ298UFV{ z_C8o3pdpG7&U{=83V0%JB}#|)<7>tG@gYI}o#gxZLIZ-s0{*gpCxz3C2jRky>%|v# zfl#2ZtGyQv!T{l!td6r1RXSt=7$_O|A4)h>eM>mBPgWI$s}w?*kbzKm1#>2(lhY1o+Cv#p z(1jv;Kg@C9E!#=3ZR@ z00RV+uu?9i>8%4q*z^bHKqo=fc|f3Y7O1);%#!nPh>*Ad2tnJA+$fF&1GfArVSl=X zQ5+$ROJUjYq#WF!7|l{V_^8;M6bP3N0~3JMC81|1BrpV^NVJ1~K-w<~1B9hY3SEVc zEk;tDD2xRG&6C1>PBD4`nhHm~0FC~f=@JxMaL0dWwLi0Lg`eC_;HS{3j6n#+SLkD! zHSkkYC@PeH=8rf`EQO^)Va#n%B)FZF5J~_g=>N)zjObbc?=}or@5le{gv*o%A_eo@ zY%5|astE!-5s^3IJ`onlkx#mQ1bMqk9er~t%BFx$}3 zu4DAV2q#2XqgkSgH^o<6m@?_yBmo~r@#_Q{;UuX)lTwkCvj5y_l%sC;DrU?YuE0V>&8)!6LL?w=- zS}a2cRE2T&x|DwO2mYz znJM$sLFT`3of1LezKWcyFkwmTQcTe+x6Bt~i7D>%JinP7MmD+bs(&LE!Uz2O1%duL zgcFU>11-!bG-9;*bpa&mxDVv@Yq3U#%n|V)PCHMSnQa;**n7H@>Eg0aN0BIhRe!;l zpe7_jm{|dT3OgkP5=sesI)#+grwohACLLcz2I`~fhLq*{&9Ixy)fN{33$Ay~@$!=1svJ>a4!4Yfd!q!;HUXiNmCRIBiUGx8{VF+>Qc9B8Io)lgvUads z6k-az*oMJbsV{B7 zht8I~lY4srj0g&8p$8cgbTofULuC9AD$^P3f=u9l(17yYSRO#*)VH|VzSNJ~1OE#S zO5K>4g3iZpcTqa?bMlc}>G2yvXkyIZ>9YILFehMx(&W;d-Y`)c@yMMQC6M3c%S9V( z#D$_02&$+95iAz}(}~Gw^_g#d!c|G0a)dwz5pLDZjlD@6(-edWQ=OL`@tI579c_-3 zg45{?8wC_V7foF0#v%Sj^h1@Rt7M%zPKu2aJHbK0Ps0lz!UYcnnEoYjRuC20Z2hN_ z(II{PWtCP9a;hIs0(OCz@)!OApWoiGtYCG?(oWgdUfN}=4(MvSY&Wt zp_{=*xi#6BzHR?d$-lQ-a_D8BMmnb8S31ycjr)C5b0~AO85`)Wkc!t8V)s$~(w%Ft z^3YCntF*}{%0W@{kelCZ;3Wg;Jhtqt1zf+^3htfI2LSzvL26NwrE)C7-nu#cI!*QQ zrQfy+X;8!~ne-AAdI!bj7)ScaY;`vO8w4sbNU`*R(>E>QX=mzNlKWUbEU2YBmW~KU zryH{xk{jM*U?LQ49r?kuXa_DO*~~A69F15u;CvQsT^LUvqBQ2>f!10Wct`Mt!xya} z2Gx$gVumVFBD6K|B_+pdE^9FG_|5F~aj-@pEL7Hj73~4H(_Cc&MpyCkZOxbcRM%!} zDc+@&j>tn&Jb&Ii6B<^)?Wwo#8rYtW>_H*~g8r|=vgrsqlC7De1Yl{R?|$Dbv!O%R zd_5^%g4sEz$~D(GRGTkjjbyzsVxzcS~-`&5gv3kuu`y&P7SI)9%ZXSQYQ;Y~xY z%|)V^>MKtcuD}aU2G|LXb~M;U@qD07p&_9K%l7Hq<=NKj!}fwy+aH?V2-rdRo5b-M zcnI193!dIWF{PQ{37ywW=5IzfK6h&l-jtL~xNXPe``!&&RlbI%B;ybRj^Y4;|X4GtZ#MNfa3z$q^&b2M?fklOU_)({Z&IA@~>T|2w@qQ?XP5>WgTYQi<8KPm^;41;xGECW6WR{}A; zx~Ngnpk85x3RV2ra4}y80yVoQEKLV60JL7rndti83j>iq%ZC5+Fu1>2_Md$a(NNzU zf}zrCxdOreyH%1F?xxCTuUeT37aZ_wuTkePKYH_UWdQ2E$43+}D(rcoJLRqE=A2;ci57h zdYhmv!WL@@rNfQd`8bwH?wUM(y7Bq7-$OAsvjph}{bGff*5ja#?L?tlH@V7i0l-q$ zW9{ZEr=Y>bidnt-F?p7h2>fU}$!$OWH z3mRHpJZIiuk^W+KGv)|Py68#^VQl_H+C?4a$BmzN^SVhhj@?cN9A};iL!j6o1CzWwV$;q z>jGLJv)72zo7qKO*h-Gtn4mebq|G#ycH3c%xCM52-1%(#G*geGgvX7EBEvLv0hg{) zxquN}<6~Kp`71+wv7m-$AN{Z_FElgSCE10aU-+JSa&c_Sjq4N1l|O`jOQ+0 zGIOvwI6e&{^~sYA#$d6i^xtx6E6Az)?;QgO%k2R}DM%fA^nmtKHLc=?aa5k-`;* zLN`qUZrk``x!E-1>1GA1YO zPPrq40u-*`$+A9nsDlZo3gi#T^#G)H~WoH!er%5;~KD~jPbaCk6S&@QS zi54nPRpx0@tc6sW{$!~nR{LfRLX__C^48OQlab5ui3HkSg;nB0VuoUN!L&7{(dvDy zMfZiO#F~8%N0Es4YGW!%oui}RJ@?NQjE=zo7S6W(-L;{I4SJ{ zkcK7OX6l!>I+c(pUt_84C@xOk$ymuuh-v&oMr?$_{Bkojagsme0*54@eKL{yMF7+XFl|V ze_-XFZKqBK?XlVQW6TIfMj%D7Wa@qEj1P+LaRTaS5LocfUXhgW$~sFT&WA(0-abC! zM<&Ar*H*sL;H`Rlz)*`G5*gc*`z_idS+VU)G}|SdsT>$BCCCv6#Pm0iNy{X62<;$Q z{dqj9tq$v?!e|dS=UjQguTa4v6D7X*_jV*reET4!OW!HUSz`52fo02kON#j{vXJd|SLFB+Z@Bp6Shr+3es8&a>NLoFC!u(=!lncM z9-B}%BBo!s%JvrJAKQ_wlW=3v>O}b3cn{5rCCj=t{OhqZmldjY&=O9TWd0t$L5kN7 zI)D)2)ztEBjD7eLZE~UlWBFOpr%68~4?7O{=WeBK*DZNceFEF;J9)2mOzRl)6}VNh zxlFHOWG_UmNAT@X=N(y>tcJ{=ly9~^dxP#4?F>#Js2qJ6 z(9n=^aVRr5i-}_TDOj}5n}1l=i*9VPr|G$=7YBH9Hf^4q>psg|6bF|*ugkhCh1z|+ ziSJ`Qk7snGYNao2lE&sTE2W-08(b!y*6d-F zVf~JUOd?2re$s{uG5!lRi}@Rihf^4!G@ z3;=wMu!By$*U^i!+k_(XdY_-brduIiUdsBInwd}>Mhsid=CP%nBJz{JAO^s0dy8WU{`(4w|27Y`IB}-r-oNGe`h0?jEASm?C#q_q_8zNu-#sdC?!%KVM&n z=>{VY$z{2*o;{kO8Q)ux>#+}&C~K*WQqn`ZoK@nhxONyzg-vn3!#-#)4)SzyFWB|5 z#*9o|`WdtdJt#Q=qm0;1j- zRT>4K((>HvJ$@yyp?8e0s?4fRHipYAcX%LjA)JwH!S#=7>Bw9j%FcWwb?nz%1MGvI zSzAXVf!E}o`jmsNWBtOn&>G{O6mSnxe(Iqj@1T#F-cXl=`KgCRG&~{YV3l*Wr;a|J zDa@!vo;T>SWQ ziggZEZx*h<`iBqo(EaNnDiu>Jr971~1wk1#d#6MGR^9t_s!23Osn~t2p4C8TBG2TQ z9aG)YgpV&1uefmfJ`z(PNlCjZmZ!Kc*=MRC@T^xHlvD^JYEt~gu#IxJ-b^?(v|MZx zz0-u)?J9Er0n0R;tCD~A7XX)U-!(J*G307&GchRf0nM*C8%*+(JjIl8G`4Qbz+3C3 z-#d_jOf#@%|~jXq=9hL30- z`u@-R?iSSs4H7JnWR@;!X>Vm%h^hP3s($5*=Bb3W(srIb@&1US&3!yRq9e#0?ab4; zU+vKPY>}$9H@ClS%jPrVsNAo~st1Qh%E>-=i>%j1Y)adHE4;eJ$&tKddU73!?mF;B z1dlhVmu^o)No0=3$tg6=}mZ(vfT9)Td(qj z?-^c&&~L6<$ftD!f87gXSt*HE*6lGgc>}ZBo7s?Vc3r2WT0KrHU2go|81%`PWYAMb zS&VZ_CjBdmfQB0LMJB6eOY*ys>Bm;TuoF4qT23}i-xe1Qj5#VRlPMsZs>@GUS`N}v zAUQy3sMOs^7(ZsAKqk2gvft{Y^>0w-?pEj7b%K%LP>fSffVq=Zst@&mu9+V!WUs4U zRmZf&vxXB&na?+0EN(9oJ4Pe0_LFWoCFR*4BFOI1A+iokPSn(2@e3WK7uPmAX3`!q zd}d?#a|TP+;q#%efXPfb-dak78thaKZxJPY(p7V~lHEvk+!$Y(d?d~!?CjPcM z_@yc4Ben+v;%5~4P2FpW3s(XbmUluJI&TL%j?V=#t*X`9PgLBkl zI57W?waKSDKTIm_lts_K=GdJr#?tASro1*_JT5+gZ^B$FcANn(U9C@F&v5DKhQln_ z2LwmuAcSSc9iIOTfw@wqm(IbTZAzdtG{?XjHQhjTW8`|4qNC373E0+&UJz z<>lvz0LicksuoegzNLf5le_&zeNW+e@V@w93aXABvy}MaM}xuxX$`}hc6IObOpi^W zPx8)RZHj)-{Kc+8VN%Sr9c(*2B4ULI&m5Xfl~G@EP+od*DOWacY3R;05j@o86){w} zu9Q=7rt^W`=>39i4i(HrUdN7$pLvFtMtO5T{tcD2`bFS(WG!5%LL^h-uSwcRTe-zp zM6+1QL0}GzIhX)R!{2G92qkr{^RqRj$)mt^D0I8P~J=nDK|=#C<}b=Wjt ztp=M|T?~dGo`go}&|fKz9ns1H$*VnC{DhioO4C@!0uJL&h z_mj~i*K}lAnUx5V5GW@y(6P9plw*P?c}m}QS?NSZ>gCxdOWRW*h{&jW9aK?XO7!6e zvec&Hnr~}bgT9q^37g6}Yx;EQYqI%S277`t7PJt>u$*&6qIR=2ldHuZfMdRluEC;K zue71Z>f3JUGLwmL5m!$uLXT_A$DV{|TgMyM05RyNNtyd0cwro;@}cKGm8)fK!|ZDN1L&~tm*(vqIZs7q54 zvg)|V2odRK)U^Lw%E;}vVOQI8Yz%PcH6O3s+RLD@#h)CPV|(tDRIH4Bo^j(%K34~S zI5e}_)59CTAM(bR+Ok+3EaymHCVPSWu#}p#jMFd`HEqJOWAH!$OL8MLd`|~1I zAz+{Od`MJk#qqj)sCHPkl8jdE;NS1ysrzEs!S>gDw7*-}y6EgFnFSFLOM^5Yncw7{ zxP6|#WgJkCA7e(O4L8htGfZ26dkw}9&Tog`dt@v5*iHNa=R1c-@pBz9P*7Oq;w@qD z)W2B1#ycd)`r$F=a^!;Spy551Tz((6*wL6E<=5I3698KNlQ?R&)-y1%SHy_ebs<HSD>(1(@9QAw`U>ZN!5ohM(v;b*sfJhhPyt#^KDwbGJN>kg69l1 zOg9yCvc7Bb%Gu+m%SS)eJK&n{N_R6>d$$vJlv#qAYN}<$x&x7SVoAo;S+#Wqk;kr3 zdbeF+DG&6jemWJKlW@yTxGD+H$$B05%JJpN`s1x*2L}=cv-Vx4*-I|iIp?_58SZt> z!Z^N?SpAu(c*%ZYJ3CZ;A4hL^EcR-$$4k%O_?lzbD%c(t9}P?7RN>{G23W--SH<>S~LPf77E5QN8YqjoARuv2=cIKYVc`<@#I0Py^x9 z_-}Pz{ZnNfZ=^=k6H+B*k5=7ZThv~IsWx{`K%@4Q*3)c;k0=+k4U!hRwYQitpw-ZV z4i-*DOxfDBDO)~hM$lx z{!Oi9arFqnLG6E^J?omBg*gr48>FH3OgGbaQ>~(u z*(?-;4jaCa&45*K2DV_QBV)|S z(xVnDRnYU&iqiYbE-1uDq^9D|w~r$I17V%Ksdh2rU{asjm|+(Wd@D8gAi9Fpjll1> zo|H*8@(o$6RXaYnEYn$|s0wBKidWUT_SU+{4~O0*eZ+D_i+Yp2{ZthaJ>s$J(e`3_ ziCLBtwNUA~>q{zdG*_Ya8Ddiomx_f;SKED1fzG+WYqG9-+qBO%|8~T=)kY+d0ydJl zCASALiv*)NTgDoS{$rnFIrVwLn@6n=^k@w?AR~tM7^Lh9+kbZ>&K_y)aq%-W#;ljt(lWa$=1tXC`?ddqUVwiHnm+bX z0iIIfi{018%VnHcWlzn`r<;(q!KuwzG{VxCo=orA7~al-ezW-l%7Bet9Y z%+nlV^smL7<}sN^)`Z~-MB@gA(za5n{}T>1>p`Hk8hdzEdbmfT=0y;^@8v`FCuQ*N zBqWlUASj?9G|Pq<9k`jfFZm*`Tx9(X+qWJ+@x;d8(y;FlXT#g1A*F9Fii#-(^ed0d zHHj~D2ak;b&l`f^(zn2g!(@q9_edmTMtU*8SqeN7$Jhl9Ta8WgY`H zcd|AoiNp==RkJ0vtV?#;FCd%M+@?C5F23l`$(E}$g%%bR^z6B*w`}?ORQJW^CSHkH z?p8@UDo5;*M5Coz3e-od3I8R$_^(kg+Lxj76=NckB+jz>JIs54)eTingsMnbT|ga3 zIRE`UG!QQJEBI6L_yJvqZoD1gx_kaHO)D6#2^S<*d8G;qk7`nCZm|FA+JjQR*ZBAX zp#;LTLOW~e4%msmpIxVCWyY(yG@U`&;b{qTFfpfF;E8U~3W>;KATjNb^d(JCi}=3F zt#b`xAM6_LGTZKAv8WzforZD?iPk;{wwBCKTA3~$IBV}NWdP4 zRG!@~(-xOpvRy&X%exAHZS%yliiBBAs%R4eZ}6g)1fx80fvHxk)M=YsmB00{fSu80lm88%SE-vyb0!w;PF19mwD|c?V(~swLTM6?#HsoA$OMbK3BN*jsZSK8zIzxAMs@XstO@j;@PR zQFsD0k5u8}Bkbh!#-4@z>oqD)re-LD$IkfNeV(Fu*YB*|T&aeC&KuROse0ly!7$=XJE%OiZ!Z@xAX9zL`*~z1Q}&s;#bsd-KyOo6LvlJ42<$ zuB-a58ZGmU1O&vD(>eZ#9eenPI>*9}k7++=TNP>Z4Gqr*%u z`iRntGV|5lPalQlv6Ko)Rm0YZbL&a4eMzK!`drO_&K}PAAx{N>A{lVH^si=~n5jId z8O2wxeCx?3uWn1ABC5MDnBOlgct-7VSzn^1T+Y#=(dK)y6MI+Wq+6)R zO@lh-hWRQHe9_V-xtM@8&FAubs{rbDhKHuY?6NUwT;?nz@x`oc`stBJRcd)Uu@{Ye z=WDC=k1VtI-H}t_ou2a@L~1AxhiUHm(II!VvS65SCQoggsC#dZFQO2BaMt9x;=9{^ z;XRID>h=w6o2ZFVeq!eq1O+*#;g{}d)Jr9bfANLHgwr!xzSvnBq)y@(?UG63bKldu z-!MNt(Pnv=6Pg;));{sDPX&UH!(I=5L2FM&+Qtcd*NUAJO{XB;&fhJMy9}8?k(W%? zKi-(zz9RyEw}|{AQUozK>55*UTU&fAeL&RBvhq6wMrU>uN}6w%^|O0i5{1l5>FRT^ zVIK@*&SDwbVLyagD+y)e4zS z0w`f(+PV6^ME#|PT1h@$Jrn+B7>ZehK6}S}U8K}LHLu^EbU}F{m5&n`*T9wMNuN)0 zi2}p;tgGGWVwcUgsn0)-xcMU2d`3!om9DaWjq-l$ebrP%Xz zLf)uZpqWfux5%#SWmlRmxh_Ugt?~DsjOOZcHd%qlO6 zQoWj?J?Hbvk7;hUxFL1x>#k#1~?qDFYJ?emcWv2(s<#~7Q31vR> zOyF+ga~pv{`v3ocX7tC0{!5i#UOqUI!2=Af9mV$vJAp|SS9{SsPw7dFr@oiz*v z@PVRKb+l9o{S@6x*~;GEgdmJm^zVK%m30WPxs2_Y+?VC_efwYEdPB!qoO zoKU1ow}cxm@#Ax8PnkbU%ci*eHWWRC|Bp2YABZceHZ6YOL1Mi6I$g7_YdSNmMpwR1xTH`vpdiT8)*fg z)8q%Oy)HV_hf85al7j%|C8}ng)bS66F z?KX|r`}P%D+*jF+=QE%+IbvG!&I# zkSf;dc8}U%A~Pdz8tMF2cLpMV0EU~4dOgxMv}V_VsQI!f5MT#$$3*TTJQ@BKzeQRO zsMEr^E|A}HpxDbtcRszcz{AC8n7aigkXvyh_xbvI?z^!Y44bPBv=BiX-x}$yztU5cP+oF$Z5BHeVwo;IUc8oS%=-`=DtNDRH21C+ zudmF2EG6^B9a46VHVKJ-)b@C3q|lzDyLp(}TTQ`#|R@`)GZ z@S_0^S7PMrdFesFD;i$PIw&uN3>ubqc;JOrx0^ZrsQmyW+Y~M$p|IWJnBtCe^oG(= zFjMwa=i9wrALHDtvAytROEkywwj&}C-x8UjnuPcaqy7jD%H6e_nYG;$bq{`^holQk z2OW(ZG41}H>jQ@EmiB0x4RiE{oo@Byhv&F@RUAoHGxfg4amI+<=TocB zQ_^-W&Sdx_Zd}o6uQS>QCUYL~`H=%!f-eWRv0x?^Xx)pj3iE-!9#%b7N%BKyVC>>W z3zL3UN?j(NFK+arYh283k(pwiMxf0y*CdTus%6`uN3`7JQj+v`vob`!e5`r|HGD$V zS%DPm2Ne?Vf%-daL$VLyVfKV{(6Q4=`9}2aw=oMgDIJeaHoa^Ql9A0?uIM6;eBU<* z?CJ4ZZz+ED8A4$yTpIK?vB4*gO^Hf~FeV^=OlV!NV^Ptm_p*7_il5lFkbhHFk*1y8 zjtpr#j;c~YxEjj1K!xacIWl6~8{5{W{C&MUexouJJ18tdv2=I6lqh^BMLTy^@p-=S zA(kA=WsH&ftHvdOOn{MJo=HOVrm%2wFXjF42)AU>0%yFXbL92{RZ`17r5;R^GvRiT zUsgO!Mv0DstUFtJ*2i3#3i0h`wjk*1m}msp8E7#Z22)bDgtc^0uU zhQvcG;8K+;to=nIh5;A$`}+FlK%=kQBGcUpFaFIJbE`|R4q|jWCEgHAmDydu6%ijU z(Q48Yck6DI=duP2sZPbn{C0h?UQli8jZ;cfvUHJ4lVxr(3&XVtDB)Agop}*eUt#+n zrii3m?uVD}x4fu$^Hbjh=$*BrQ{hGX=~_Rzf404-BxnQ`=xW}QemB7{)ZyixdGX`~ zYo_#4r>CfsKn>oxGNe{_dw5zMBZA;PtH0xDsVp*Bj!&v;lxDywe<|n`G>N#yb@lg} zZ0SX|Y2@YnEQJ5`QDvO&Ng(06c;m_RItFZ^=cQX^t`=zG}CfaI>0Nf z#jWO5F~R~ojvS&`Ro0_^sIwhQiFHxv+VlAE^1|0V>jZ#m#6zs05 z?l6d-&}5yE5mM0H1D^9-Xs*RzN{5-C3w;4@mJ zf7M>=mUhRm{^oLm@ZVJhFHT6LX#e|grJmk39^K8^QdN83sAEMM6MKS~Isrwd87Vlb zX)et!u#Q`M%ru7CoFdZhJUTe@%#|gz%eJQFxb~u@dOA#d`SO|dj}O-OH16ER7lr&V z8BdjcqT?)ljfgHc&MH}WU+*^P&BcO-n?6#34!37$iW3|`ohi* z=$1+N0tgj?-}zzNKGM+rF-Cvlm%NKtOjyttzk6;wisfAyo<`+}sMAr;h?cYHD^=Nty2qrV6W0vmdz>_1Yh|alBDAOn4t?n6Y|`RR{?w% z=2R>Pxon6yAr9_&UPxcSckt!!V-#ekExE1=3c8N==~OjH1Mzj34aZG+*xGnj?x{La z_ScyrH2CvgPyWb^AIlTyR2X>#m(F-GoTMa*)R6|TqR_*bU=itsZdm!tQe{hNi1<1b z`2-^EGc)I+QZFL)nSDO>(HyjV=%d8hDBtr5v#F}-VsE2Go9)}H6q0*4M_qI*RSm#k zopv{ZNx2U73BK8Qcs^>omowpr4AtY8$B`piTioXt&+tz6l&Bj*fC$bfd)UFK{NuJO z1qx$0LXHYk(VH6WAo4r0AI%y!(-;9&ZLccT^L2JRa3cqGGB3#FynQg;;#pJ|<3X(; zw1KtHI~t$A7`oY&nj1-$*f`Y9Xb}6S7|KRi%ZTU)T~A~w>@3`_5j|4j;OfPn+_QCM z9>Xf=qjFN+{g>qM7<(NrHYsf4c#zVFqG6TmkH!rPl9*At*zG&SaI8g_#+2MWF@K|u zQw#Y~;6fWcv-y(6!4?Sx%QOH-)rH~bZm!Y_RF0kspM9NikNgyNg0GVE`^^clkns5V ze2cGA_J%8_kXOf4Y7ft`$$}dv_cRsRv)-JVzNga_b>?OXnCEBN^OPfJxb(qFC(VhBn*hGq#mPD58*+yIwcQBVh+G$o%nt8$=iZ_>R1sv;aW zxE`i{SEe(}JE3uLaVd6`LnbOCku1b6i*d?3gu*BEN!mE}f_!Gxcw6=Ohkvwv4^s7X zM$(bc1xY*&PXB0@8+6{^!y@PW4CI+xyLaJfv`=NlFvTe$2I&ZWP{1vG=4c!6e(vI3 z?ifk5O;;Vh>=cP;(+$4f_-ch42M^v>^30~88(?2y1<~H*BN~yr#}DKm^d{@~ zAB)OZlLRIHWy)Lr`x1XFS)1B?ReUFlJ@%+LqxnYG0iKi$?-c3UbCK>vP_j#nCJXKY zGnRXVKS+wbWiw0P?ZC|REIo2iHDkt2F813SdC++ zGZ3}J^WJYMNHMJOrUI8@pIyeZBB;+<<0gI5jPVc#rNQ+ehB_#5xGZ_yhGjn~X2F#V z4GbuowUj&wdZ`3O0=%2)=WFvkdICK_+x9_tYeIYDnbT+BGRVf{+9ok2#hl--4&CoC z59e4v1AR&eDH;|xFiV6<;v#&DXd>~IlvwW@2N^I*5^sXeP+#tF_87Q>-b?d;3~ecb zeg0+_SOQFUAgkUl2A!k|Mks7=sobeNW;pKC+j9C^!hqi94+7iQmi#r3?3gFeSV5+< z2`K6?AJGjZlI+YEJ3^*uKi+^wHIIbmv|;zmO{vp;3V3*bi#cX4UW zZT$T9Ghz1rmZ9j>c>+$;3~1S=JyMPv$=iHjKV#mR`km!lDAVpR@=T`#0eboe;vIe} zrk!-tYH^`zm{)A8#tfdlDCV&)>ecl@D_xpTJuR*%BKq{s>dN;eevA+M@#g0X87!yl zYc6~l2|Mn+`B5nYx{G;78q-OYAMr-@Nv;A4cZzOMG*aDA<97U-m3&6@cj9!%!!}EU z-R&K|=)VK6R4Z)B*~y>y3|`egq#3y5LXNJQELn1_pi2&#tBwyuq)_#k*2iZdio7(`fWQaB>TMVm0#ghP&T;eCug-mvDj|0 z_lME!Cz!e2;`(e)s>E|UDBA&wK{&1_<{z!vG@ix(4VOi-f~piGUrm$mi|W;lm#KY! z#cRo;qO}Hm+HPO`_sUIh$vRez(m+3bgQfBTZwo^CJe4=8?n_t?+P7pIIDcHIf_qK7BU%m_z#q&wKwr*S7vDddf zYPDCJog1%gH^=BU@`iq4f-oIkXjWAO7&JXVP zk@v^AHI4R2p5+mmq{sbrNC%H93iR(yNKB+F2Kd{$=HH6<8Sx`r2*jqyaOPS275$%; zH24oIJj=FQb(xji2Q5F|&Frn?FbB{bf(^p6?;?XdQRctY2XphzDg9PC@Sx6?u0z-L z{eE#iqnk%pfB?fU@tPv)x7`p^A@eNhok!hR*sK1g?#J$<`uJ9iwbDW~e^4W-ewT>M z)C&Ks?Ue7>aFSgH7Q1>m*9k16oSx-NN)4Yf6zPDp6>Zv^uctm@`o~q?1m-n{i(2u^ zBBUzpTGB1IZOuRwiYk6yDk5CR$jPo9LM2lTtWTtG7d>aDHEK7rKSKtI_s`Kbo9?q| zR7`$^mWxYxKZr=2ja@)I1NVfFld`B{Vcuj?)YTO(L0-4;#+gAt9XPrdS z{H1iM3WhA3HKXF7kWSj&HjlQT+)P7DXj`E{z<5*1Thoct33ioMxgCop?DjB#)Z{j6 z-sVk83g^nCh@$f6QQJtI30q8@@n?ruj^;$v#x5<$v6`NmTRMCC6MtRgQ*yIB4&F6- zr66kXNP5H5B|6ocK4`BAd-;C3AueN6j3c~8|&c&dt79_(in8jN$ZHaRvb}sUv z%H)M}yZ|$q69Yj~Cz~`}9#4VF;dew*Okxf{G`^0@yLQ=llr*UX?H2DGi{0+=|FLw| zZ%wf8|6ccCg8`#QNtbkQbcl3F2%^Fsq=bzW+!!_HRGzn;geW5TfFdn0+6Dwf5eaK! zfS?FSe*GNB_Yb&#xqrHj>-9R%t1d7ia;aokNU&*yESYQH(a~Bn1Ej7UTDMXa1>2JN zbK;2js;%m>h^-b!jDzHIh}xa(Vg_VeLXK9#iPgwme4u}=Uo@{jX%T*XqqXW`Que`; z<{z@g&8qo_%qTF{QuFVTw7Ocz!fkMg2M`#jS?=b(3{!VC7v3Q`# z55~sMEWA2|v*sU=K1QU7L}8PdA4mb?6Vx9}Sf)Y`JTpNmHQ(~f{5=s?&;HNb4d-<6 z(v$jl&OrmOdkJ)HD4Gi?UNSB5sd5sR04w(Y5R1J(<3a1VFwpto1HX@x^m5IoV};`> zextm=T!H_uaT;@-Oc^$R*)kBR%TSC2ww(Wq9B`#R)pKobU|VfSe#;R>YQ+GnHyW@n z3-EtkTOFmxca2CYr}bLDDz@*;MQf}PxEK5_D{+$P@bd3u#&h5RPIHs&^)-JlpQfFoC6)~i*EtVZuD=u;ze0=i zF%VlG8FxOL7Q8t=Cb-z{-K2uBa?DGH_2{HYG&`#6QnVZYgu0ZM=5)F=i7 z1rk-^-(TBiJ{E13dQ>t%8*BKpWNF*=C?&UNx@4MciRjXmYu)macIaq}!d-Wl!cp}I z!@(a+XTCHyM_ye$eBq8b1RUe?2m0|TzCXI`mVb1`P}=p9+E(<95o$ApA81^GYnD1+ zU&?mUnK|*pVyJjtj)Q%QX>!Q}gwH`+P2_IqvNF@tRQ2kf(1&o7Y3A-h#;TafHOpP7 zs4S)v!nL1m`eZXGME;Aj_&|T7uLK(do~p2RTF^dt-8|RIhzy4}i$BvGOg*j9BpMgZ zF6Op;FM!t1JPz$T0x&p*y}Gn3(}d!K-K$Tq)y(JQg<2og0>+JgkLzx~OV{-CiG}TP zeu!~YKtbN-LYWNNw$AnZacAoRC>p^3#}2~OD)0GV>|)qe9wFpXaoPhJkW_WO#vc>S zV2;_%+bxfyA z>F?UlMQ#K(Qc@AGLj93ZK;j-TI4B9%>b;!?}{IoFr!`1&#%%yuUi%T`GzV<{4*ceD15$)&V|g|AVrk4kDq2>|1b z|Ml=T8h(PCfy(2(BV_&`{h(L7ZM&y#KtOf1vUFp)Le5yigTYTSoC}vv^cU-;g7f@g zn4^fGbawv_>4JU;^MKK`j&&xTE2t$M>uuXPeX2*-_Tzl?diS1azBs$#2m&CL?uPwv z{ZiUwyctWXZCCyCS|CaeNTcp>z`%?|ZuCz^Q z?n=z8T+l^TTXI+et&mxZ1q^=&3II^9-o3 zMy(q({`?(;8_{`oX=36rzXWVjbEx>p=a}D#+Q1gg3GcuYQ7#qG^vP=#nq(V=wPjs= z8B}!7z@+5R$zX$Jmpc&=?`8#L^P&M(ZYKo1CGXp5bF?M+PMOF6L#BP{=#pok2)B+5 zORgf|7IHCD6MFUDQaz?hEkx7BUtsSIbPJ8Oi=d^uXg9#f|8Rga_MpVJc!}Q>kPoI; z7Kae;_2v0(Uka(V8+6hkUP0&LCXch^G(Q$D92T|UGb z*;7F{vv}$Yl6vVxtFNU8l375&%S@}k-C?kNTg(<;SH`D+z`xkz5Zm^5NFoNyF$duQ zWD3x04)KG!F;5N%$`c60N(h%@r`paJaJ;2BBHM-AhDCHpltc*gJvM8Bn}>4D1;B`6 zWEjF$^a~LJ(177jPEf>it>l2Q*w~lw13-ECe+5&alGP0NXOc+)xd1}DSqt^C`Pzq8-+K8t&_ z-|r&$YYy{fODJ6t^O9A@U?Lc|^XtwwP$pCKJs1ij0({c-+5Y8WQJn>_!mAEnkBOk1?|<9nWNbkeT8trI0w5UDS$R@sO^Q_2I?G01L?n z_o$LtS;y@j-SS0fHz0cty6~M*1Q7KpEb58<(7#>z{&Y zet$b-&TS%@Z?_mr3I2HgvN%5paj6QnaVK(RBGl@?Yy+n0ytB{9aGF`6(RpDc<|Vw9 zSSw0J7TbOOb1FvWOtIC7_-An*J0B3MvE_`@cx#y%5uq{Uo8)+->t`{zWa7)Z^VzN8 z7_*=jRkRTd75QBe^t@e{?tKGJ_J6zDX7X~Ydp{X>U|>c4C- zk%2eOXYZ;!eR_oX5={uNA@dDukM})BMkNYF+I!i;W&?$XG-|%=&-MM5Ge1+#e*V3<}%ukh}N?hHb{%+46kC zG`!6ba=nu5F7~Y}C<$6Ngd$@E z%wz*}9rksdi?-IEX|IC@6d=2+BsG z--Pq417^`r<vrAYTtA zb&k)xQyC;$m;h&DWtE<~@1_3y830Itd;$P4D_=3lc7&b*Ux~atT9P|8EZ#~`EF|lJ z?9zc@)P_Ad!}P=%7M5@ea!9D{A{qDYT4Ar47t2XsOMz9CDKMJTP&(>FWETYD*$6UznFvU z^irq;`fruoMVrv3y`}Gp$&x>;&R~~qNEDi8ZH+PO?C6u$IdF6I$4czoIh++#{n+Q| zg7YyZbTuDCpdv8pR;XY^B7dIhdNoU@mgh{K!)QxTQb1YP9UU^4&~N-8Wrt+?X1i6+ zYmu|xTh5^Csh5n^f1F|1L+O2ZTWQ<|r$)7TYhTo{M*&BjAiE=h!?B_NCQBHL(KdP& zGz)(g555_RZxsENmV$=d(KP+pWDKOM=L&!z(YSZyg+vhY_4yS+tVqC2$0D3~&R81# zI7YT6R|2Mb;<(7f``3*KA`OWo`W~1_oiG(8K1#-*bCTm?Cg1-fixtgAiWtj}7ZVpm z#C|7#OKp_Lp|d3LsvDrc?;fX$h!gXW1mg6P_~HUn6vrClLdL znKrYJU}pn{vU?4s=(A}Ut=1SJIz`1W9-W$ljjM0hof(w%eFijIuh|m$V$DypnL|sA zb4}VltF8fgB43Gbkc2cZvv0(ymyix>oWh##a+q>eCk7xPp0K{So8Z*ZBFFDw!36(F zB_Z3ktlv~-U4MU4RimR8w%9S%Bq+vtTMN9A81c?q*|)x}2c(KTNIV-8O8dw5&08ed z;b20F`JZgBUyNkE8}bIofy}M!wtM^Th)si?T#HUgz`Z}evS&Lo(fGuUuyn1ekDWh`cJxHx&_NxKPFPIsOfG)wxQXn9 zNKiV0PQc_laM+TqUt%b|jxVw3LE*3MQ~AmzXqaS&Dq*I+>JO@8=qTtijQyu2UH<-V znyga>0hd7`5yDT^mK65|cE5T6Wof??7LwWbd?dT^@Ug_r8V~Z?XI9}=f`ve-s2?DqV_W>WD&zDT8=H~81X`sT}-)sZZf}Cwp zk~xw8I;P=?8&tytsRIqp``bV=xDRs#V-EyqpQCtw8T|M)YFM(@bL0=LI^a}|#)P)r zj)BhDoIyd>{@rM;g#=jPzjpuhPy6vhafTWW(R3Po>XTH9L|~a}G2zMTXE3J?w(XQx4;o4^*JTf>0`LG6_?)i z0L$bJu-S_&_Zi#u z3rQrrh4P>12c|8Y=4)7P?kWEHO2;Z#K^4zF4dT;gEUf^N(b}m&=6zBc(Fk&ds>qdS zXzW2dH&uyhf47<_1YLyTB@rswL2@>MNUkzGbK}Ca* zkVSVWkJW_Kv9xEW{}6waBvZ(fa@uMGI5F*$I;22SCT}}mpVOzEiUbcqJ7o)|BONY3 zK-UJ?E>+p3@W#s%IC`zLV&v4ka7ms6~(z0E2xPI zdTy|HTB2k4{IXI6|EQi1Qe z@giBB3s&HE6BKFJFk}&yLl#lnVcV`E%T0@mKt$X~y8 zkdU8r`84Y$Z}uBPP~m&D8EOm;*+L^Enkr=tA8gbi9Nh)Ze^VPXb5nUC`2+5sp*@70 z*fov|j*Bs1d*PmFxS-`Cu6`52q%@{(+9mCR=OH?(c^Jk@+#UH50~Z(OgaBS_532Cr zQ51h~WTcL~5D^kOQFjIU!U$er*C6Jp$?>7GJwjP7G){?i2I2yBLP-TBqPN}TV>o}z z#*{TceX23>_?XW;fjQumI|?5a+<^g$3v_iJp-jq^5A4;*eW(KOx2rx_Fb58%6#X)X z#}F`*K_P|RYEC;bwn-#zCb&(+BoSaf?~JSc4Wb7(7KMHm+VqFaI1~H8`T;@Jp)e>} zxyarqRJ#$5C5<8wP>yHIaU?w#^)dL!UGe^Z05T!kMZw;A+GH}3VY=vZEZIK#7 zHuUf6w=u>Md|w17*Iz^vWkf%N!V1ckpwj(h5wK`V5mj~LuliL?G}nm^hT4pW4_W~O zm6G^!=kJkH8kr;LlX8{mwv404V`DPWULR`(mbeZ24GIryK%C!`Fl1 z3=(_{r}Ism&1qQR`ebY;-(Q?GxS zI6^g$XB5hv9U2nJIJF{zmFh**a8`f6!yT8i7qGDK*y`NZV?L3 zgDZD643ygyex?=pGcNV0hb6jPQ)8RBEkk`+Gqo+rvDALzQqHXc{wG%OdZW9*P%#6~ z$Z(+Ra>DX4SF&|HWIw0{mxjIj;6IjZFN%0bjqy6->Ix5YI}4-8cCv@` zOlHGf25{BJ)~8dz1`+n4JJ=cX3cdGEtE|24=sH(j9Sl(LZFg_asnlp6Q=NJm8?#7C z`*TJfd1rb6wxl)$)i}m~7afAMcm(J7lrbODp@;bO=*hT0*?Ena4g^6GOw8|mdxKRv;| z;xkDYLirp3W2{nTxaZAG?ifC|&Lz+Ven@Y~`^seC_Z?zK)SvUJ!z=Y;AgFCb9QB=>&|dSk3zmQ!{Hl-%!kL!_nEe!jl2ov1 z2SBn$p>d1jJt^?NpMd8wsifVEJ>V|a+7jnP1tVv&lS`Pr7ruHn>{ZKk>ad;z+0bAO zyRdSW>p?lsC@8OMPxbOd?@~TP{#rQVlZJebgPN|+1P!c8a^CxZhocBvR?TwQQ_E-c z1j8NKkwK;UmNjyXE)R_x2+K{BVu(?Z)ABTWYP8z>7l+^=6yBL6_nfVn=6IU;5RiAS zP{g|N=?q*9?7NO=&FAh739z6GT*f=QZ<@KnhL=4TOI68n*k6WZ9o5+t*vm|+eX032 ziK`5lxLd%gf&N$3ag;KkH_Wi=J`Su8l*h({a{eg_LUAonZ zu4ElKWkL$i{5$65{m2eg<$XpT(+=rt6?d9>hkfkUAn9EJIvFtbVd{*RpW(A(5|**~ zWgZXBs4mU^^|Cwx6&&_bASU>9OPhCy$X}9?wUYWcUT_0}`bxaditO;oN<0%RFf({~ zRl`}Jb0)26?P`@fg`{`$?& zPN%%(e(DhNq<)3eh+UscA_Y+PUIZ*mR&LRe^;ex1Zm?NVHEg_X+=Ep`P?>5q$g@ax z>3tgLDl-fJhYGr}aq|4lS}_$5Rr}V9k$x?F75C>J5a?ft=k(=laN3sv>X3>rRG??l zWIwnR_H;ym18oic=qb_N+HWuS9tgN_2B*Up{56b@`kmL70l<#lFqn;b5GtqnB5xE- zxkB}Z#naU(I_KWSvlYKo`}G&1UvoWT!#|qfiY()tYq8x!kX9Q-0W1~T7+}2-g>Kd1 zk1@fiXm{PEKh`RQk6O1po%mwUN~iwE&^Z9^$D;8KLB04HnzyIp)%4O(uN>YfJ4KcR zpjjDA+Gn88eBBtSd@@v7p@uI9SvsQVkCG|@YaKE1Xa$W4!a{M_!#BDlM&x=yCtL50 z^UXUPIA+8<@n6#&uUlwolqw_~vURCN%G%!ex0so^kan7HOM(b`ab7~R&Aq(^5v2Hq zlID*-nuA0t2f~qH$HQj0xOM{%4|B@B0qVG<&Mne@$g|mQM1OGb;i1Ca|LJ&`)#Kh= zC$c;oim54ndk&h`2wHd=K{P0Nf4p@R^LFrH{=6{3S}$+(&DuldG?X<`eBijX!SN(3 zXI1M1_$Pono#b`T!drm;qPPF2!0%50uOz~-j4VwcJ$+sXfxfDjM?Xy;6ULy_6~Yt> zpjbF50nOD}1`c1D13$AZ&6=q_rAjk@W@qj!#WW9p#!r-d8zVLLHBu-?rXSiXpYk?^ z9l*IA95`&~D@Qd5_8S8@esuI2H%LC6`gO%$%KFTiDBy)|`BuQ_0l2ldbm%38oh?=7 z=04hDnek)Up@uAh=Ek^KE7{6KMbvClQu*Ntc^%;cmhFSZ8en0>j`^lN_UZdJXGn#W zI6$3WCvf03O;1yeaV?P#=DDEK=!(5PIn8VF1d%cMf7-KVZ^l073I5XQ148hx%C+v% zvPu0~P;@0@P6K!cIoWv9{y6*FA<_}{KYa4GSl>w;JA>d@G-)2 zXwQokNF_dIOr2@QDcGrME@-YnyHXr9;&FD_)_q`(TIrIm6_9gU2PZCJuKAMv-AVsZ zAN8CPw90)zrn0KX2BR(7L_HH2qxn2o26uJ}^-{jajBVoAY>?SQ>x!8l$`IvWKRx5S zqU3_}j&Th}_jxK-P!-IDm62|$Pj_qy>r`9Zg(J1i9a+>_lP+X0Or9iSMSb$@*qsXU zPK7zW6qrBx>6`@gx3`b)o&twZc4Zop=OXBfG5=oKkSNgS8+SxXAkN)vHD>a zyUA_yP4V0P7#r+*zao8k;uRoO6cAkVvQ=Nq`@TZJ;Th%>S#}=Yc1kD$X)`j`0U1LM z_giV!@|jnSE8g5BiQofEW>b~QtDI8^EGVb>TxMGOXT^@om%gbOpBDgjrw}H?3cNWG z7{{7bw09Wx`i=w%VV@ktHTmMBDO3E1Z4e%VIRAYzP}yB`BTn%dbVjXslA8=&f;!7` z3D)hnr2I_2sYqn=Q(%J*eR<>`DR$!CC+B8e!p+}U#Q_Ko<-qEOD41v_m?i%(m#cH~ zMm0%eIs7GH5Us7ARs4ap>b^;H9CjJ=i!XTQJ% z$d>O74XZy2t>b?-oMh<>Ewn0SfT~S>1Y;?HhjfvAd;J6Y|L}au5B|^$=+?!h*s$=YRBb6o|-3q%;B?9BF zF}5B{-InxlEU(nEN9RJ&&6~6V$He{q7ZE3K%0U|{DI`#SY#DifZQQv9PalkJ7yNh! z_*&_~0Q=HR%4A^E)l3Wn{+?tV_d)M!s)Dr+B8PSFX(Qla+wRy8RXI_%;-c_%Il8}N!&V zITl-|K9sf@f_`1b2OD+;_QCT+FnqR(eubzcBINF$fV&&v)g>Lg)=;O%%8yH(0qi2J zFm~o@5~%fX-HWHwN$N%iVR%8@RrYxG`Ur2+qw+GyjOz|OZZ{WhKjaGNB>XWcdKljh?#8YN3|kJFG1VrC{f2Tc7P);_MYU& zpZ{kd81Rp326L-=6t1|NJRL-hahB5_o{rPgf}<7@pI_N1QP%ke=d{H02=Vi5^r`SLg#r+e`_&91L`CIdGiYAPx}f z@t?jfkcmg1PyZsD@;!A`VV1wU>4N2}9n{Wf{GFF(w!*)nYO#_0F%$rx)H1x=MH1RI zM09kfAh~VmO?_jFx1wBmZF61Gxi+b)FoXvq9f*+z&Xz{w5?^vij@HS;CsttyeBzRL zLfHKM4`vl#B}g{(*@R&kPdFTvCqW+2%5>bZXUF+~4|)ZkQTKq&n?6;sD$HK?J>PpP z;5Wlkm*x+us3p%RYoV_eh4|E#JN7e6BR9%ee~ALyGtyLrNwG?yfu?RB?D#Rj^#DxV z@MK5D4E6ZP#0L|?1-Di90fEI5`gG|yPAIAUN|m<-xil-28w!^ZcyjP@@!;6Z7R=!! zAiQc4?+pFoWOv!TAKcb^TrhLi=Im({^pnHO%i6lgSZ?C-jE126vxS8v?a%V{SdQ4b zApa^i5CoX61V#fZR2d)-f5Zn`Tju%ri5ErLi)7&!p`--OWDKS|rP@Xc!(&wjtwyuM zi&3ePW=#E4!Se~j9(2ilV&EAmq6T+lmL)V~ONd)~5zI{EuUSMRD1`!_(eX(P_~B~ZU~d^L1T8N=LFrS!g2J3uJVSlb)wb{^Bp zL!HJXl&!gi46M2AmwBo(AOhL$7W#8sj2WWC!Wo&OUPq4gpZogE=c_PH{>2UT``Py^ zB1D3W{e5A5oHXlqRhdKL+>3ikgyoAxx3KHDBw~B>Z8l%nKjR8G(}zEQL{2QZTiN!d zrQcJ+MT(blnQP2($-_syfhmY!`Qpn(G6yyJ5B4DpLeGT6p|71Xy}mnPIbk_!$r6`Q z?W-z6a4>^cXYXf7%*}`5nZ>vXK3J=7LIgUZdVCWgnM1y+wn=;)Zm{C{R4wzHWC{8m ze}k*Rf*r<*$=!NdHGINBQu5;OLt+$w0yCAbBO4PRl{ei?7Hxw-;l1bohi}%GocAWX z?MxxuEpnx@kk))XykjgUsv>h1hL&@G{E@qN`}5L~*&c|swcyuqTbQFdo(FHRIWT~2 zR!M5w0f&S3hDK?QYF3c{@EmzHp|jZ~`L?+I=0cKo;j(i z|A#8{Ps=KY=b_3K12zq4*q{1k^M@hMc!!x*j93)qINFm#$lsJ zSk1W!?K)%>{Tt(k-j(Iuu+7`yq;UhhzU66TH7gTQLFz^qf;gawC_ued81F~1IO7=c*NA+(W17|4(0q2+Z zrT#8`WcBCuW<_jhm3z5^j^O<@;A&&u54V1ZEi^QM^Pj$E#|KE|?#0=DN84*kj8pi% zNA|$43uvyrB%b=gP$iws?@XhrC`-w1en6%1)9;;dnAX>zQpDGM+b-O-S+y@g8Bwbq ze_nl1-y?SWP_R>H@^>#_n)>sXlKj+oH+sc%u#>nAgod(fopiX+FWlO=AMQh-dwo^) z5=WFF$Pr!AEOLg-E-gH!X^5nA)O`ACIo+l$BG*PxE zjDA1a(rJ4z-IkjvhF;aX0IcU=Nq=)wU~QH5=Pvsv5ZOe?Yt8=q(s^QsaP3ZFYzjh$ zmD`x~ygVcJT@?INaNsMc>vDDB0GPQr(B7b8PC^#Qv3$_S9X~0^mTBGdYW5yg0?>GZ zL`ap{6MlrJsth+4a)2=6%-!`n32HZ4_Zn6Fa)sPBh z$KM_Pw1^!owuIvMvv$FaQzcvW&3beVvXM6Ot@ExlwEgcjpT5`lf@$6hT(PRt6oehV zrA3f?nHrmU{+@08%<)SVfZvKoU1Tq3ifeCtZR;(E-EFGg=fWQms?L}e4==}MHY3hB z4g)jsZ`0r5hEspEMH))V8->>?MQJV*#Hh9W9hswTWqy3PTj*3MbBlK5^=>%r0sDjP z@e#>)i>0QI?PBY%sZ0E0Cd)2Ir=kZ#u@XIu)?oI;&P*GsIk(L*PR7EBE*>&8QJQG+ zLp6ZG&acOfD5gu)J;KFrB!7Z@Dc@|~nO^IOf)SCq8KE{h=(``520HGjv~4P_jS3%B zT2>qEO8!Uih2&QgP5@vJ8B$@7+Rty2W_-r z@bsnTZ_~fm{beOz99Q#`c)t%(ij!WP!~boW%YV$2w11lQ&3Sb*qE zqf5{GGYP)GI}|<#t>#yY|4X7b@xx^LVTdR6o2x~-ONgB3TvtKnMx%U&HU$Jmut63S zjg%qNatSAhtkv@_dq8Ig$H#zu=z2twV9=tOcK&ks$Ltz5<0oIYh z*1st;FM&(qWkxa;D}cjtw8%0@ylctCu6u%6?lm1~`fv|Ku)iGxSmN~n056+eVWu?O z2CYB#tFHs_C@Qc=%V+v8e~B4zXa^BdIa5zB9xnq(llV?X4yw($Xnfy)#BW6!ty%#W zE@yj8*lZJ&{nS%UuM&bF8f7>2fa{S6qGyDHg2% zt_a?^Fqy#fNi~V2Bw1Sl!=B%`XxjAsjl99eIa!K23wln_BHM;xllJA6zP<^p$1aOz zQ=It5Px{(^W1N9#7@4W@1(DqX;oMl-O=L&QH-}QQgk(( z=YxS9t1xTITUv4eC+>Zvb(Gl>VqeAK%?;oIZz3I^p9=8(lN5RHYnwY|6Z z6mvis@jO}LWuy1C$#6lc^47uO#^0_6e81?gZ6<2;R?zQLG5A| z`wx5W$M>GdcvY(f552xa0Z6Jb)@fU<8_22v4mEJ|G#ylzD^oDEzT|webqiI;T53_L z>pZpI`Q-W1f^{|Bt1bW@KzFGF?hexJ>W3AMJ^CYSq;1#*|B$mK+od?wR={cdGJ+}ilkoeHG2 zMxXdi6A}&8bQThZ7#Cub?_#e|2on&GW7@hiR}5@lD{H?=bUYIx$P$OPrKi@jF)plh zNawGfeE6`er)>ax#p6bmPxZrhqWYFkbGb(%Vta@}qI7rV1G?D;Hlx)AC&z`Jg_gy( z%{KQ@M#53fPw`UE_&M`8*&E7*FXVHE6MzTQN80Tj#V=T4s^2#rFl=zbKRBc5h)O*{ zG2T605Y*B$NVD?AzTRYiS7ZOtAG?dN)JfOOW8R-#x`l}{V`P@_a+Og}N9`HuAjH(J=d>U}jQAa+IPbUy= z&f!fsv~i~-d9D3}CnWxN?kS!^{ZCJq;Kz57J`X-orsduMYW3VF_o5pz;|Y0DAL6;d z@8@-UDMzQLv5#ZO<>OU{m@5b=i`b!B=*6INwe+}sJBK`3*}E{_e=>UH%>kiF1!ToT zw-~a&)x~()q*}aJN1xjj4>f6KwoRhkak9-oXx(U4;N0&?XU`}3Y1$UMrv}b&PKIqf z248oy9Xyeshn%LE^6y9P?Ww<>Ar20DiihBaCrV69JeR?l+t!BWb-8Bmy@9MQvaili zop5t=Xkz=7r*FU``C-b_XX?inij*x=CW0VJ1Ffp%C%_{XLtwv6049&&)BLGu#*bY+ zBUBqb#G`0OAVMLTSe(vl=j}aj?L$2e%h|sS-tFz)C>W+URvpiq>w4f{E(c}m8)K?~ z_;3H4pq!zO5ETbNN%)JI2?GwBH%$nNpZGrC^s_z#K14YgQKv2VXG0`m(doceO>Q3} z)oTDwyzFE+{(Pzk-qGLy8{B?3<}PoJVd))t>rj)G8#yQVN7BMR;966&_cvDm$6aGb z{<`icpl=;jS_z2vW=9D_h}+x;Fd7j3wxxDm03Y4WTmFIkfWzYBR*DgMt0I@-@FI8- z`N!yS1G0CqoO#Y^-HF=(Ale%t*0IF4Y`Y|LHJxvPcqnc`n%MX73G9qyng@BY>rCkZ ztwV@bu(t*%LaQ*6;4pV6R8zO~Za#NvV)Em~ftpfyO%RJG?$c@L>yyFt^W}!m_&K4u zi0l2*hsSg72iwFrEeCQuZC`+VO=iORSIlLlQI`zIZ`6@fpLYc_G6rUMl{5lJ5jLdf zAQoLHn(Z(!a0Pf4b;?%K$)&a!13xE;`NDU{sHmdF*m?jNJbDs#6P)W!?}75PVPF_M zzbnunAfH7&a@IfgN>{M;pK-E1@HzBMc<1Fko*u9#qHGpkZEj7MX?rQ!P%$G!=FgD*idH%+MZ_@X*L$oq^V&pTk)&G++3~c0H$aRlf=MSX=7DFg? z;>9>VuRAS}v1v({!Ummha&BVY*W4>X;}nGh2B>ELH@`lcbs+ey15XBpbNleK*967~ zPjZkew)U+C3JekaNACsAmB55?Ii^aKjB6JveJ1h;{Ki1Y#R)nb$iE>GCF^|m*te@g zxRlTcr^tW;Q2^@vu`lMD*1{LXJB|J_@}^ z_&(dOKj)P_6VzHzb2ocSL6XO?!f;+|5wC(|_c`ChyjoX*vijE1`!1cnzPXXR(C738 z{^-~1m26(O5X0E4p=wXq$*}f$om{)*fPpIFX~>1^n0|xYqB!bVoE8a=hEtRZPUerS z4XP`EH7qiq{9E^C`Aa`w{PTywd^U`I7;~HMxa|Cm?IE}A+#S}WD;0PYRbP8C2IU5@ zHtaey21f(yZ(wd{^QBAZ(I5HhPa-E^2J=qBCfX`FukzqmoyRw>;CLya>D+A4HB!>U zNj69`u1db_KNXn7VTfqJ=eC;}ivM@J#I1@LaianHd7~#R*LmiNp;(ft=Ej%&U-K*U z@9)8<%pf(KU{!70S(9!>Wp&|DDqAv(lsgx%eHOtCtfKf(!>JdMP70VxN_2u1N zCe(0KP6&<56E9cjBE%`k`>T~w!>Vz-_oObNxQXs@bampQ??3~A$ikEOw(~sb=ndg7dRbd|P0$0n_Km+3@cn2apTdY<_Np_JK{x)PdLTkn4ZC1n zo}~_p@UB|jkod2tRy4(>ujl}N);$hQ05sHMWF&pku+SDa*=6@*E3nadT1 zPg9GJG4?gK&A~@BhuA_ldTB?mu6qyJ&wQBva|#Aq`83yPjx%+U?fq5f-oMi<+&nZH*pInWrELOWk1;D4^jY z$klv;)^b3i=gr3-==*5j3-kfz9cRA*i{S@vGx%|dy@jQU*nS8R@L78dedQYEMAyH9 zE?7x!>v~voU1!t&;eh}EU}7b-N5ZMW#9yHw|3_hWTbGWagar??d`x(CPYO zxbZp7CHC^KBhN}v`B$dG+S2Dg zJ%H~f{6|4Kw>Xqm*#>rojQ0waYUG;*8m%=-f=3BRq}Pq-WDp=RL4u<9m*N=;j+Ijy z5H#bxW2zh&#S6HOW(7IP50!U?JMh)CwDX=mMX$4Zm13x|`bulvIj_LL15_Gu9%d;+ zAt*0dKB-#!jwE$+ia~xp`kn#UV(Rqd?^{{c6Eg~u)B8mg| zUgchaf|{eil{rewj7-giS}qVZM%XgjwHKdRf)W>P zq>kNmf2FpC>qlLAc5I}nZSJ5rT-;qXer=*~}_tYg4iG~{&q)qj<0@_VP7w%M1U zo9pvv@gG_f-!y{S^3gDuRWfL>MprARW`F8ltI@W@x7&r=^1hG5htv<*CV^*^6`)&M$RL5iKN<0d^ZbFuE`tX@RVbOC%oWQbUTa}BN(kr-&OD;2zxJ3%=xl&CFqd!dz!o-L{4@x z?xzz{hJ;Y5e@^!fxXgJ6?%k7px40zXMs7e2Y~CY93>va(Kz;yN><+USdSl3iMYHdj zLn@nCrHU(KDT=CrVEViEjV!Q3d>@oPy?SQjOHf}LD+9s@I%yw*viTb?K@vG9ixk9z z{5eteqL$=6fehO8D7*yatVuQAvcMePWSh?GB7|5}I#PdF_vKLWDvGtn7~ifT6-yom zpuf`o%fte%?+70Pt;6is!}|Fxf(@N`OCuv zz9!9gH_@Pk1m+HhvN(2bXo~5M3BdT}xAJ_}1GNnXJ`aM=E z6;ZMiVg?tE)cPH{XZgJB@gG)rjG1PScZT!=7kupD`D@@$!&|+3z(;A4o{h{U&KFQh z2IqCKG}qscU5B}EuAK2-R0k<^A#3dr(>+q^&-1j_T~BSLR)%w9TM%&Xiz`if*VfiK z9TwcBp9YX!rlIMlUhX4G2wX2SYp+J{1~UnI$p@O4Zui$(JVVC4-52v_TIPy%df+Z{d$cu)n{k*0K?WxH|@dfX>02X?n#Xe}f zOdy)-8;}FwSA(epd)R2`bj_d;`()rspAWk&4*RN!a$~D21kB(j35`|h$$%TOS5kwi zC#RHaa0%tFp}YAc(HJWUMY;BDlV+%hs^kYH1-|)L#IV{)2Coe+YUagT`;@db1fg== zE`CV3`%-!@yfHH@e~zqWQ-M12R^Z2IyJ=9DaMAnwMo^3N`=s){+|m1KXMfcge3d!$ zrsH$zgiLVf7R863r?{>dodQT=MW?lpywfR?xtH{Jm%vvh9(E!iQ+;ufH&X_d4nA}} z>{*ms;3>;Zn{4qFt(EChJ3*29vwuHrY+#Vfv&b#;pH>2Ej)B@WUh%#)Lz92rwT|GM zdBpBisl^TCDOe=r=|C30^FAs>Z7xO53&~d=GS2G5e>`AciRSjid@3UzRDhU-Qn%yJ zc(zG3lNAjvu#bohNx3p7*D~Nu^E2gSd6KQYaND`4 z-fsm7*8h;-mI~MZDzciD;U7a-G6HX5EUWII7ghLL%|1JC;c^xzTk(v8uNtiIlt*ic z3x5K-PAcAlb4WSNcJ9{Ihg{2% zR>nIOhlfCQPB8XyUJ*YLe~dKN$9-zn=8*gwU|0L_nZ<(|3aP@Rfukeo=v{@yz{hRdl zEx&s0>RiFn?j~ouIMW*)hbNKtzaRfrks!hD7UF9?W9HV7cNSg1Z~!_mn5uiFxg8#T zD4GYeY+Qu43*D>fzL|<%ScGqnp^$H=9d{F;0wb)7@MM4NP7I3yvax;kw+2)?mN#{$ zFyH6IFv7?nuC0dWpZ4jY?=;M!homoVayy7!1pX(sliJ9FkAHtSovtul3W*9$ zahm(KbP2zEEJ~Ec_3u@z5PPg1`3O*y`G11xont zino7q^xXcj;r$hxX7w-dcSw1~K^NByD6*`FtOG=p4d3K0wkZB#w)3-ZP9{%h+^dmJ z@Q&=+43EA;mU8vodd-QGY+vd@B=2VM05+>M%nj7~A5|V?=4`aLTg4R_x#B8ZPiAin z;F6|)v0eS?&Knoy7)BQTZ@1Gsqm5LWEB(p%;H)}t$NhYNcRE4F#|^6J6qlprK$eqt z;vKecXx_Rb6c3z%Vq1!47+-Sze*QsbQp}ZgPe7Oi7Ooc*kL9?-Utz_;S&V7EDpCc4f_p zyJhn4`;?yAvzVP@EC+6%f(jq-NaYIg%j}&mc0iPPxg|c$_qM)wNA5?Kfv=H7iN7XFz69Rw#=OLX|t5}1LOOt zlRyS@QigdergU|jvu>O+QC)bsQktdkYoM!UBbB!XciSlmfP)Pu zWzn0>MShWT75$p7I+7t1T@~aD{?HT@C$Lb1Y#e20O&aXRUcbU*mr$Re1qkO)biYir zR+ww(w0(A2c7Op>{qv-lP+_Kc=lpVULmNB}-GhOTZYCqBXAgTGf7$SAf1vZ|q5nRP zc(ox1{W4^pqA&((R(o#e6cMc{0R=`Q{()(mJ>*dz+ML!i15y;=Qa1XEgC2IF;yhue z{IM9|3JR~CtJT>=My!4JET+g$mK_8xya^B=wYbC5|3w+&J~V)};Dg`7|86b{a5liH z+lzO~6;%|%iH-p=bOH)zAO7eFijfF$pTdG<5=J^oysdT%Pc?y0?bk5mq*6GEZS zUDSmBFPB^JFqRBvowRqRW`FnSuj#7rp7qb2>VaY5tKw~Xf`WvNo0E0U>*S^zl25lA zVRlP;!h*~O#d8tbC$mWMVL@xWg}ak&oi;pCcf;%$z!x4Y^Xl@HF4ubpr>&2{)Ht9O zf|$_FT+|gq!}zWN&W~8{ou z6^Dj42~|t5c%}EH065p4Msi=Q3;6HbiN6v|Nq3M`!fMhtI0=W=+Mbl`ak_KrT~y7f z|2&rBwA}_%(pp|dfw6?vHdK@*Qn+W9x4SXMC<0`=8EorQ2{{8YpM|}E91y4MGa0)X zqPSQ{L(;&qV7^}=HhOnB<-`#ufnQOFxRVkm1Vlek{|*T{G6hQI^qruzK2!_YJ!L6} zRD9RZ5Gdr?)g;6hF&oe`c{>wd$itC+H{3BCX3mzTSbn3~T;O=ml zN`g9X0kN+h;+D1zc*=0)Us;~C_2p*AFeA@_<~Zi1%MV5aDQ5&j>FIqZ^c|E2hDdrR z&O4NA7^t-bu-6Rv!gp!VCRj`)ST`4Envk+aA@W{l0sB`(njOR0ELx(m3dOYAokm%a z*`;rm37mqH<_%g*62x<^K~ZAKi@^ZJ_Os>UaL;>IPWP#0)V)>-l;*m~PUpjFL>R)W zsPwIzA3&pR*P`C2P*s{Wj5Kv9lceNxz1lh!hBm{Sy`~W)gUfgQ_ zTMXe*F~}a*zn~!?B=M6ia2)zb0^?-crnr@aHlxEi5*sLQf|Ki(aKq3_X0@;Y1qCC- zfoHc=JWth8caK2AFEA5Lyr3LAc*a(}P+qq$_K*}=9t$EV&*I1OZ_h@{XdQO<@gHdN zmJ8;$8F?ehY65R^KkY@2eJzH`62s2Q>F8}sjS>XrJG%x(gjpoaKz8X9X}p5K=39lv z8WPZ%`@+3Or#u$~yJL66;`DZr@_8!q{dq{SyYs@o&h)?aduVXu1Ruu)S}G2=y7E{g zk8i>|OQ-CW?5&oObpY*N9C}Uq`<{y~rT8N0n!Wwri#Wv}67W~vVIP-cm!aJ>`>KE# z;2G)F%9u}ScITVuU9br043-T1&g&B-bz)_TW*t16hn`M+}=H)#Uo+2B zX{D@{f~`Oxz!`$P@_v{umhRy7k}Jp$$Dmx_rH2=%@y^8JfLM4m?03qkFj8lmb%n+-m|_W4@;VRDBwGpxEA^K2+=Zg8wv$F7<5- za?TCu-0oc<<<~~3z0@`PEt=?KYJh@mf77BA23X4{&I6p7+7@+4#cC;+U;wO2!(w62 zA1hr8QQ}gWXEyQ9PnyVZ@$l{PrlsXtWFRRGr0P&XY$9Z)$5b)AwmL@S+HJp zMCcVv5J(mES;#m|N@S;Fxl*+k=6K zK)cBM=yvw|h`S25)1}vs+<%FN6PB${_$<4rXy*#uD-_j&|I0>*k6X+~0Re`--rk#Z z(%)u7*}0ccHYl%1p1n3O3Gxdy!-TS=9To5bKWxAG`Q!a-F!V3rfD}*gagl zK(eg*{RhxrZiMjb@&hSD(Pg3`XXIWvA_WXiDH}Z}Au`Nz4Texu#Np3F&JErROC4Bu zM^h~eP_@CHe`lgPj-Qr`5Og=0+NVGtyS?jTQiJ0SFxzefUmsnOKY!%y>WBY+1#wd> zH(m!uXHKHpUZqI3Q;Mvu3OxJ8-Tq4y6@AB)vhXtGo92-vi8k@+a;&$m41rhsK;s7!b> zZW3ftyZ}$JYep&Q=osymf&1uH>IobYOkz0h724u6nl`E}fz1Quf7?HBE}>L(_QBs8 zWFqk7BZ8yboPiPL`#b?n?cQ-eh3646Et2SP?f2Fto8fSW_&fi3+#iOeI|VncDtV*O znPSj3ZVj}&NlCPP0HMXR^C*tdi5 z2GP`}HaEKr%p1wN(~kJ_QunX;(d$IU2GGSp7>frQ;LE_j9;0p|deIE@Htjb*UQ2Y- z)yC&=@*^*h8g_>71C?2;tMCNpDb__{F%@Dw=5Z%y@j7R){fo5V0?JUr`v7N)sVx4r zo?e+QBX)1e4~s_qG&X1(OC-M(*f%=S!%~OZf8Zki6+o=aScuZoH(bWoXGW5U0=gW# z;>_tP%}K3QEIZ!TT`p>tU4uFC=!%U%PXZ+=JPAjEw8nk9z;{kfi%DJN+|$q29^*&6 zzX=;U>z1ms&bDy~K-d$ufTN>%P&U&x-AfA7E-||H3dIr-$NXQ-9*m0OoaK;soPnSP zcR9{O7x~&K(~@2IQE7qNFz14C17u(=I-6QG=N?3ZvBE{1-&HxGDDmOE-A zjRoRIsq=(SDPoMl?iTU>JQV71Q7>W#pJ~bF{}Q-es{9TD8ziCrIX{+aDS0$K5oGU& z*4UvzZSm(pLr%0kUD};6xiTCa@Q0_-qCY_Bd$2zM^o%3^^wvp0dZu0Q0o)ePe6PGs z0$-V$1e0H&2^p4i0;KUvZi)G^6U~OJw3qM_&qNFF6!km%gxU={cX$cc;I*~O(okDo zE13uFFcsH2`ZG0wSVO0dFcEvH^o6mogLKO&LtX8Y?+uQMHKk}` z<$!eOAJ4?-V6k+V80c$#>TGPvRlV=6?^^v7=9LMDBVd#Y;=4=aQIuw}BOxm0lqWZoc_*=j->6`R2CpUNRwjBN=afoK+ zmjDK|MrND8*KiRO$o4Hmyp9Qm!H#Rs4S#0ZVeNKoP*I_J?5*5a2@yN{{&HVDUhp zaV$!@BzUTmZ5;wSo}zL}u;&{@V*mZFJk&?U4|eS%=P3>%dH!?fFnRGn->O(`r4vK| z%ozQH)ia+o{PUr>e+}|H#rhA?Kml$`%MLEFR(X^G^-*|?80On0c(m6WH0)51*o$T^ zO2}=HYWubq#_`&okp4Nx^oW<%)Yd^*V^hPP7YmU}Y3_LBS-lP+NrIWPJ)(o`O2N#@ zTiO5>av9orm%+sCjOLtW_D4+jrp&$3%INFwf3$39qd6ic*vMEXBoN~C)LMjzrsw;E zXbk%SOksy2>q%W~mLTDHk-@UZ_9`_qrZ+V(o4~t2OzW_wnHP)CYTc?!GOyR-9|9qR z1-WT&bWsDjaX;gPR!w6=V@9}`e~8RvyuK;aDyiRkVYhew$47rWdfYr6uVag{&(4`q zlLnHnTI%Y0s9MA}K7JDqPl;3W^oY2Yu$`WH^6$6-UiQFqvo>s!EyJD z^+zKQM-IG<)q1c!NoED`2bE$T0{}7}vT?W!+Er_-jbJN$kf_7%+n(b9%-ORBje72b z!XdY*fJym9p*g>ct7uJ>{ld-v6}d8m*8`r6<;;3-dx?R(CBeIgu3td%Nr zBcTmX4*~_}<-au%Pr2dSM7g;Ww27T8hIIYnv7rvKf<6VKX$F){kY63m2!4%hac6zq zCv1}rC!Xd#EKwXnRLF9X{Y^jmvRS8nIn_QS9=HpVYm3Xl^M(yWojD$Z=`@{r9t3K! z`p^If0Pynp?`NXLSOHO$N{JPi*z251(R8TMlir-hDivP^W|eNZAe?Woyb(pHGpG*; zT2dMd0Ceai;gv7^_4SDP$mT`ttKUYCo8mp%dnpI&9iZ>>P!=RP|7~Z0Z-BL2);K=X zmm)fgZ+?Jp*g3^iKQ1WA=uhMw1Vm|9 zUW^BE6euz}0?tni$5ir;yN(V0 zq4NdOIuSS>CpoUT_20P;FZNW~#yWcj6d|i>2Ro8u`=f>RTSGNX#%BFFr*1C)jeJu# z;w=sm$d#9g`zQVQ?C%5X zI&&}Cu7Oo0D}|Gb5m^(F#)8PJsFXHu?kY0n8Yw0K&}P584NSnY_L7^1D=z^nqL!2Z z1oXCfpOCGWiWloSKh)0Tts^kN_wRnW%sM-ixho{j`v{&o{Ix9SL!`K_n*EhFQUHzu zhlC^ctk!o|h`vUoP^NF^Ay;F2wwzb70=weJGQhK%>Nm=n*~^>-2{S8ocDot>ES*M_ z>m}(7>y;|MeCdl{H7=ZO8$S`lI{{B5j$u$m4FMhu2k6fTX@343Q%9i1ZD2#RIt$gX za6{g7=z0aF-6GFvl&d%~N{0wZ6QpvnH08F-#o-3l)bm^kp4a2)DI%>x2m=J>ZBJp~ z_*b3}#C~1H{smJ`LU@gslIa#ENFqC&9GKtD74I2Oa86&MPKwRG@Vnl;Vk5n&Vo%i@ z-0tU(4<3)d%`$~OK@P#+mm#ccr<6d0!Ah1`*E3G4Ao6v&GY@#fnI*Tlu8|FPHzo>0 z#k>7FTSovghGiZs$e(w#D_ODJOn26R4F@{xGMlPhJ`RO_mcKly71F#JqL}oxnOe`W zHw@}JsZ?r!ov$6kCYtJ)TN9zBswo~|{T~R0{kXjntw-Z;!@=T#|8TT5Ekt(+87JFD zO1X*f(3WOExZ5r>tt3%5jHyo8!zMR0TT!S0qh*aEc{naCrOIwdVjyMNsts*M#}Tfq zHT`i#KpNMuy{;(t(}jrpl+zVgRVF?ZVy%^HGqAQDl22?|4HJ>D#$==Cl+|tejBB?7 zqeQn(17W9Uk|ymbdBM7caJi@YT6=Jz9;}?-ByZEIW7(`@)Vu$eZ>#QF{E90p&f58g zPOF`o8RTSTe_X+B?IbCndMjAzvRfFp|H9bip?$~FLc8|9d-ru0?^;2dR0+`U@UMar zN5F8wGFLw`-+$g)KUIm<(m0_gDDF!8U~>Xu<+}g#yc#>&v&n_jm-BZ_xk^is8~D+} zN-m~ivkYhPP+*ebI{UNG72Xtp+@CmGV>p05(gxo)y*m`t^=#m~WNhlh+ToYb zwF$w-emjo0Kv+ERvx?Qtc&2M@vyo zX@xAiL5xbiCfChGU{S&)JH~(1Y8WVE2+W?I z-|}deo1Sx%{N3QqOOOCC9mJjM#0a7-KE`Nym{byYLCvrbWVHmLB6=09YEx(619?)S z35p?=4lf2Xd+?;Wicy}(P-zw#(<1crG53ipgonjj=2AR4SxNoaExToVJ-&IA>d9<* zhOJe1?;D&{SQ2cny-UI#f3ZIQ$wkmW0q2#^C!mZwfZ4_u-6`U(n&lGL0BKZp^ z4T8EU4(18~v$lb&!Z|Dg^w)o2$?$?g46w;sC(@GZU~6=xNkopSL+c(2WJpjZ=B~Sq zL7Cuv$M@%dRS|?!0thc4$2^p1*f^Hm>~(**_%>@N@O539_+V8>2Mb+2U77n;mdgxpdQx-$$fvxC3<-F!p?i8wA!%)!CoxzdzJ? zxKBWS%XJgS@d+9^Z&|_nxnQn8h_!|d(pMh7R!b^I7`TB@CVAz+ag$WouCu_&TPpHW zs^SI{SXpD5ki$uuLjaKUhMSl-+U`l6&I0LXt=Qp$1l~tmdEs_mhuo(~UwU(uGsE83MwNncXa10jxJ zuu7$VeZV!GcCGgkYahwcO4h(G<4z3jcaziUIP795KE`4do~_%0>fqbFZIoUbxy=GA zW;Pi+_N1y!SibL-Qu+w2R#3Ch_dSTl)yOnI>yl>1P}#@G^J8kQOiLC93`&uLC33z8 zP06?1bv&1;>@{eh&e?KLJ=1O&=2KyTEBg@JTjynJ#ndwm@Q=t;-56k(8(nFr$=^5% zZ3w!|@vOb(7y*2w=HOx^_Dl{ry9*UC2dh@Od*_~^=%;)wa6l(@(Rm|9xl0Ln8qeiP z>y#)btTO3#`!w@h#uLx5d?K|YDy7i%2kt(gR_Rp{RVWpWR@eEA)7DqA2Hu=KJy8ph zorHIZqyh`R#-P$iT;_*t+)#E>0+8&5Q`wV`pa;e1dz+jAjOd{Ue*UNj8MI}u$G}lX z4CTECzG+hD;6s;z{n(l`qLpx`!8Sf0@+egNX@ikbRUfDapd?hZctrIcUr3#ITVT%> zcZ(-3Jj&OIKUaTYHH}fhA>g~lm<0btm7C6-Ry^N^WNe{{U+#ofgJdh??@hG)gBi0v zK~lh0v7D?n%^2Q+n)(_*(va+*`D|$72D8nttj;Ry5h(TkFplpW2U>r!VbC?vMQu=N z2iyBTO494gPood4{l~;e;OmPxQvKNwNb!LuNk8A)j+!|%7;2`(zmz-`M0XZU$bi`#)cR4b6_PdD0)+&emA&9eITU(>jA2_nURNd5VT)6gMWiYLkR zrXS|re--=5xP|oGj!MB zSpPvUe3Q?$!L?sA?pK*98nk1r407VSw5#dX0m?ou(@&LG65ODf#i6qv3g< z%;-Ec1W_|(EkKs!=pDbX|`7|)N$${q^4EZ3AG z^jPEM!7PIQ^gjx^n48=7TpzZ;7w71mJG=`$&ooP0gF2>vew!J|yy>p<%G@3Q6z=r^ z>XTo!pY*1=p;{JlXRo&gx4}XxgsA?!@jSzOD+ zG)*zG;rDh^5rozVouOapYO1~uDc14?%04fYRiUd+yH5`1ukVNd;0DeMedl99wbd59 z{BNJ%YE=a}y1MrrnOdek&krHk2$|1?)E7^!`NPD^=cJx4HaX96=vNM2$z}FXKP(jn zwv91A1WYu2W?g(Vd*ja?4mJjD9vK@wwDnpRb9>W(Hu51N-P$g4uV;5xO%QKH@9=Av zx3O$FU#gzKysGR>iUf3SyKii)1-@sB2=%1YV*vvN z{f5S}ylP!0^|VyS&WW)vh>Qf%@s!YsIGV9lnLI5{0I=c5`x<-T({@0;tq!h>D@qu% zy?@LEdnk<|Gv0H(otK!(e4t0vh$q<29a_nHURJt8{Ei+`4hu7)-sMV(b7Ns;`L$NiHPeXY05fZZFM zMO3YSSH7QvX1h_0Lf?9ynj27)8`yPP@_sr$mX5(BW zrh_Ts{B7JN(uBanZ)bh<&Od!IWI*75K50OhK1hutjB6nR%#iRVU8*$uW`tjWnI8%i zhsENn-c`3twG(@**^|lx<{5}u@rr8xq|~rG_B@-ZcF>;?m@gqlkEj9Xc~d*;AO`mr zsLaOB{)%RsUJKCMh0czuB{2HoKAvh%!@hwTx>Xsf!9qkX<4u2h$GI)P=RLL|La?FI zS>XAPB#NDAj9^y&a!usF<$BYPmfRoQ+vvyp&iN{p+^9MimZseZul?f0&{E~%F7ec= zB{GrwPR1Gy72P%JX==AXV>RE&mk0JC&X^Dzw)6?18CEeR@CkLG!v@RPK=zNoR&=_Q#EnP7gabX!OD{MbKR-|5n>W+ z%IF{n-t=^7LnphpU)(N6O=>9oz2*24&-m#PgYp+!bjbtvK}teo9QVmo=DAIIzM@hO zrog;-r&Qodirg(a)cmpn4_cfON2yTKWRs? zH}sMtA3RwAqcoN!pGT9$RS#yFrAzYaB zxrhDZfG$u(X9dt|k!bO1qrbkUiBa+=?U+LA+V{bwhJeBzK-9Dga4XmAJRU5JYd8^KV6OGk{d5oTPO5#J9>@4qwrz+j9vVJFJEAVr$ zTtPi{0I1-RMNIaf&JLeYW&cjQtQQSQG?myio7<6UpFV@7|JSO?{cdWB+@yV{n+83_ z=<}Y*UZ1RI-Y=PxUbeoCZ@7~M+&?6#@697m+iqx=yaC*8J^40mpEL#d47A5qOe5dW zvCJGt^WV6NORla#vayRdTZo_KznU^Jq(_@46$o5l?x25KGf9j*5a_gSA6THyo zJ9=C-UmZL7B|XnCAo+m0*o-tT=Qt#Ai&9KkG(}@mZ?ZCcLwXJ5fK8~W(5n=)N(5zW zKN!HcaUA*M>C%{oRz<{iH+v*sP#Lv}9!904I34d(k#oibmgefvCsNbIlsxb*`Ratw z&!89WDQo+O$wsOoEF6&ajJ7Ea*Xi>rL>dgPThJ24THp4-dynb)rZ4hVZk5d(Xg&%z z3PbP!yH315FK<5ozN=2VusS#@%>0Kq>6B0YiG3CZ3jJYQh&uAS%-FX3B0{Hl-zs{- zrJ{x{biH)(iK+~k6C0j2_)jU+{TGPBH2T1@ydX;wiw+Fb_=0+l_Y^KfXxTxqM`LfV zyPric=X+tlKH*ZIw&@3qFmnV+GVbuB!y{fhRQ?w8hP6>Oj@M>^sCR&21-lwzIq`ty zzwM_xeJrgxXQi|r~lx+AS8{%jyRM8E>5Vq3b9eiU;PYPuo6K09gWhbd!sP}8)UpN3^aA!mW@4)Bu=>v*OpfKIP zz$#&w z1Ri=%5Z1zOd(6Hhz+=P)9}x_Q%lyPmZXN1*H4ToUm%)T(c*xfX>_6c-`o)cnMierx z^nL``)z4Km-UfQX@uSAN3Qrx;c^`*@^t(X_q?*8s&26I5URK5SVapeq9biN5UZRnu zNVDA%Lpu8=1TMeQC%yAAKdQFT2g{_NV+kMb^ks7<;m3sGNB7rg9z)v%BK4Sib4OXo zm_Lp}jHU3vdvQ}BM>w2_cfo>vz>ud=EJGGXp9^Ejf_*-|+x5ZbZ9eezl>C(1 zX}Ob88e7Z6ABb<;z;+(zWU!T>|NIf8Alta=6n$g>^R?t8n6<)YeFlOxZCQsK?(Uc8 zAc4xq*hI4BWuP`S=Ti`9?~}W)nn>{V@umytUm)m<)POCnt=(mHrLX|N=HZfl2Zv$O z&I*|*D!B5j1EA$pS-x#XvdeaeBHG2LzUJ};Up;O zQ$69L8q>$rZ)!i)HM#_tK=1n<6 zq}=T~N#e|dHnydWQkalFn!{JX zF}lT*=;bIyriK43N40_etF3#~ZkuIWYR@UaoI&M;0zf9kG?)iR{hPg!(}$P05$ zfeEHUz)QIuYT$D3?oqdvQzIC9hceY^caa`a1Itef%0O`{>{Q{ek| z>n?plE8SZnE$N0lV40QIs4xTD*8(Egp=z~49L>xRp=ZD!>#(c(T@R^n0)}jq@%&Al zR-K{uW$y#1b88i&AZ*8;`3_*XECw_SmRf_6&mWg0HlzgPsNpC|l^0TW2{;kjT+%@k zRudqT=`4v4ONq*G6Dc)G6xnNCDPcMCaup29QJEC`_zf6LH5VnWlTryQskDFN0~l>I zV@BNVM(51SxrHou%B!n4%}Z4#w=t@W?ht}s0NZM_J(*dVGE}leG^x&4zx?>ZYn6wp z4L2+`SW1)=<#BL8)9C@OiVJ+?K6QUH@O0&55 zrrofw>2Lj%DYDYy*;df+jT~4m0tjEr;CQ_+B9+d(nAeq{)PiGIY_{%9!Kz81RyxfF zAqI(Bqx6ktK>A7&gb^7PLtdIp%$){E*HO;l8wXqa5 zo^r`D?lKg=%R<+{^>2^ikl;kanL5C9)lX$`c`K^Y!D+=vndb)CpS2i0h9CwItk+$1b7GImJ zqXp18)HV)hgyvg4^l;q*Bn)1^)&4n>OZZzczmAFIioQlZsDZk1pM7=34(u^bhN+iC z`aM-&3+~jJ*7791C!W9J5Cx=xh`X{Zv@G^?jEcEAc34SYDRr2E^&RLGXH^S>Npqu0D_>ckBf!w8iqoulGm`j#lKpVf zbm$B1iqn%U=XCOw5eq-;1QHnW)v0p$QAdIy`-l0{R=AM~r`-{XUA9rJHH${Nl*@*m zdJ|czs^U!sr9r;?QA<+-F2v_Z>l1w_A2J8^9LW9I(~m1+O81-_X3!CBb86y`J-Z#- z+Hxsu%R|Vz_9__T327e(+24Nzl7iVT`5c*&IsGSGgY2|oP}BD{O8gxjaX({y;%kKX z%LaNJzRz>ZDODx;jBo3PTMvFdqq`1QeFpk^2IlcbaraKJQg-y)e9+m~>$7FnWQ7lW znskU{y=Ya3h=G1?28vZq%U}0nC|J~Ft98RjurqUCmD)S%Y&2D(#mqbkMYH0>IWOU+ zyKqoDVCiyvMIdKfu>rtiD0>2~XSyWH*S8JFQ}8O9dA*HOa_L%E7j8BvK*UE#C3@-* zj5y}WBdqa3)7XtxhAKW4PQQ(}ZOA!A>~Erxef=AV4SNOMdj^bj;Q118rQ7K&_LL=J z&v9R8^E}oayTG9TGLRM6^g7N{mj9nCfBrBrrLmlbbYGRK#ynEE3PD!s=yRsmy@r6k zRBSRCOS^`^v78F+Mg?UFicf3i(sWkQkHA0$Iz&~FA7;o6=8#}SaAF5D4dc-NZSn%J z?!cCL7BCg=Wzv`4EfYD0r;pcBQBu^yq*A^D-||b5A254 zXyX-CAr*z)+6f>)8Sp&4NCAF}TPV+H%tSPCMr<+YgCz?r1sw;hh4RMdACU@V0z)tK zWTpzK(8RIvCZ9;j5k%zV{DR<7PxN&fqFv`U^79R`D>NNG9ml2V3AUr;KfbRcsTn}+ z6iud?FcA)LcAlQ1;;4`Ms1-iXDkH*B>2cta2*TA5Rx+Srvj8B+UfSq5pj*M7C(;Hs zX~BS}i$H+HJW%`wOPL?RWCS-WYxQJ%pUSs3mNf*v*{UREa3kLF6cb3G=j)&JT0p~b zA;$B--3M!wAP9f1?msEgz}iH{QpiEYe2+c|i78ZY-TT(1O|Zu{KYnS~kl}FC#h~D!JN3O5!XCF7Y_?sPEZv ze^E=Xd91;c+P!{fA+ToS@Cc3%T|4~>*cceWzx*!Z%3O>bPDpC%Dz~L&QWs<6WU;MS z>z%-@oY9TGIn*yrlPB{b+_QB8GgdS@j>F&Q7{Ug;;;c(=PqV7ry1)Sd{o@gh zn2*WqvJ|UrU3T>XKJDR5roJS(S9{S+ZGZ$BmQ+ndvL6L76-5ZZIc#6P`_KcBCb8cN zn(zwNut`cCaf#A(PzqBa_dXwSb&#WeUm%&t_;KdK7y%A-n`&Jgu+|xyyF;@49S3@t zMkNzBV^fdAa`<-rxkrH%B3!&56ypk!9lv9pfB~3SUdjvnVgu-da-o5@E3|Bv6%VF` zp7`yRr&DBzTvQ=~?A%L@1}C#rKMN3^w=z*i*9`40izqv>_6L z4aN4)VniUJvaKDjxKY>@smhv3F57Qz>82hq7*(;=zsseD=URWA5x8KO8cAO;@u+K8%-wgQEbrCf zBecX@YV`Ig^phi;!fC39u!tD$!c%buZ_BsGMabH%i*}+;z`#qoFHg6dUZN4ps zw>&kU&_;l%`^=fZ^;QW4ghaX8k0z}ecuH?8KfzDeNPqHzmjB#Us5lsW1_GJRn+5^?KJr6qO{YzH!m0np zu54@^w2}I&zPm|aza{DT8rGM*87J~^`a=)}S;7`)UfRD(^F}(ty5f!%Wx#*dyUHxy zeL;(!xtO$YJXcBk*bnhHX}LbkgyTR@~moxcvo}>j_rlk(O;Oua`LuWZDD6XH|8_*!%wG z$fl~d$Z23dAW%Fxp?eW8gB%Mjqc=GYb%P>MD-MG0W5eif1fJ*m@9kuLgyz6skX8>6 z*i!*J0{ssR+QYvvJUW;Eic1E=L0m2r+^#g3>vXZx7V@$3-qnU)l0hN^)!<|{w#^K1 z&bw*`S_SnxaP8YP1Of&DfzJkU8I9@>p6t9FaZ0fBri@MlQmQ+O&QGB4E8Sc2*4Q7u zGOB|st3@lluwT@9BQrgC%~B`bUhY5)gqiPpJruNBOX&-5m^N(pk+D2c480@c-rfS` zEWhpSgk3NB6&-xn7xRpME zVm!D85&*i_onTqUqOBefx-N!*HI5xnc`8HOh;5MlG5SY}FG-n|q?F31ZbvfQ(YZ=0>2$+O)@Y?}vLS@zekQf38_C~?Z>*?Mo+(YX;f`>RRcUkc)WqtumBD~lQrgRLx4s$p zw(i1ie!_#UoYGq3y?@$)YRIPzs@fA{WN|jhsgPgyefzM63DYgHZ zEF(A)RxYeq!G~&mtGSyAjl!emo!Rp743BH{-p1KT8e3F#@W z|E6%xffsF+Q~meTyc(&3GcmG;WlLAFFgbGc-C>q8OpEyRF_aadpaG+6Lo--l?M3vG@3&4u_g%lqp2B$3m~;J4C2aC6BzYb!8KQOK<+tAPP$Jbd>kIum~${a`HTT1M*kkWC=9-g{u~M5iy7dj@`?~7sjls&fQHVyH3$Fma z)HFMX6ps~Gxoz`^P1#Y=zH3+@5S-ujuIk`;;3Wa^B5^#n}Hwzj3E)4;XS@rexuJ+u$0xOeU5#4v$NxyJ8``joiH zlpMPcWd50QRO2PVQHRQ}_Y-<$M8dSu!|D@_d3sO)aZY4c2O{~__OxZ5U{Ba5+Ag3W z+MzrxuQTJY{z46!}z@58}xlw_kO4 z$kiX8EczTY8sq6*)x&BA*o}4rc{+ldpJ3N>2_~C{3ukn0^SX2Toiwl*Lq>RX5?(eU z1S{_*L{%w=&>mYUd5^cX)7NIt?=%e_%!@CYSIMGryHw!ia;;(ITuZ2vC)>tl@Ca!oz`x9`3mZ7){4g+?t5 zZ*K{WB{7?d&!pn_y>-p0RvSsQWT3}y*%Zay`fs7<#n}?8sIngIz1~F>hc@K1uG6b@ z^;BB?pkX6*B|-Fhn?ZW}Fnu1qH*{Cts-j=YsaCf_MDd)=zVcU@(r_$IjJ%**Jg&4n zQ&foS>>V>*VxLzEqX-igV7W3c^-avvl9rKeYN0ohm5RobqQK-lM~Kil+Mn>bUoQ@w zQ#yzDdrUc&Z^?VJR&TTCIz;<<^Fhvs4-0?JmKX(0ystxn4O8!?SDhXxO8UN`XyL6D zaCdXC-JIcw`zqET80*t0H~GAlqSs`>ul)A)!<&Lk!7O42t8yU+Bg(tmF}>vzm;f9B zz5T+eTLYhN8wo^MhLS@TD&~!=T|Jk`pMsGXJJ-s4oOlQ)uFn53Kac)zg1v5`Zz2Z$ zcp^+ZD{3oi+V*xU9_6|<2GM+M;W+xM>(O7CDpjF*RZvl*+U9>TMH_oAYbUr3E$ef> zKZCXiLmeg%oTtzVV#nQyQ-QKu(fGqf@9XA{(i1?v&;5sXqH3Cr`v9L*om)3HDM`Md z8Vo|dRu&oAc|3844YAp;9#j}OAOOvzTrOauyVTGk^-*dmYz^7ko42K@JVSI&$^8^_znt1d60W_{?heS9`$+_{~nD$mfo=6LCe{{PIg@ zKX&XX-2-0%AKPAG%^qy>0!vJGLLK1TnN9)Zk1eGx1NRf>RJEsRfpkVta7bv_itvcY zsOZH9rN>lUd_v-?q}9pnG!B=So{^cgjxP|3#M$d5z`RN&mF38D^YS-PoL#7{ZtfnQ zUJi>cj7Ii@{s=XM8d$S<1o_HfV%yyh%4~x5=f~G?Uc_zu&;HJq5Zz!(17e>l{6AIj z!q9=Dtc$aZs%B=$;F?NH?Hc}`^@~W=frTCP{4*AqD`9CiOJ@RF0=icwuU&TTuHqvL zPacTV`(F-2t@!=%p?mYs$KO91vlxIpdbeo){bNcmISBRf-PyU5s?(=c)4zw+#2MQn z?B9Cz70;~SV#z)t{2x}s^WO!=r>;|HpS%uF4ey-EzILPQPGK$am+kRS<&^0~ccwR^ zD6_3W{V#_9J*a#?xABBIFY&@HhNaz)zfu|&x9#cmR(sET)$Q52mbd$%hW=vy&P_ie zp0diyqYE3vqwgL6EPAWN4xBu$jfpBLjGJ})=6${M*`WQd=M}}jyVw5E&^7>3>RNi} zZ{SZPj5kDMar&E%qwPcebyPN7r{?fSThxHC7`aYXHsn8Vq9U-lTnSGq_2J2cY$;z) znv?cst=M#eyMEv);BEWm?)YOeHq4DuCBeWb@rdX1- z!6r*A(x03cw*`7@xg^YLVemop8F(HizHnNXW_% zrTv&wEHDivGJz+>#p|m;i%)WMNlh6tXv)Q;8FIZ`DOmZu+$SCQAk4lj5x7tQfG;`T zu51gYx@5cDk-Om!uWq~0E)s9zha132;f;JvM2!z=`a1BXr(7k^VtcxCyj}mgzQJx^+&`HwqKLxOZAVhxin}@)z@>ObY2&tc8SH?S=eZ# zNb0Ds*kYj7PcRUngi5W>4-&Sfw2~JXmDsP~h$}dm1b2cZ%~DrdTX1~dlS>c@66L}t zwF?HxRJ=3=3xu2!8I6DhUo+NC4o@+qyC36wK1G%v<=+)^aqQ}-VU&=txvA@d)TB9X zDJ3f#lV5zvIb6ZWc*$kD7nIHt!u1XYt2kaA=3&J1B|190(3gZHAjsbP;z%tC5GY*mo2+VsN}z;vnNWWMrKpwe3p|=KlR# z@H!oo+DMJt)y42_=e&GfcAj^!&8f&{LYTz=BD*E2aX|6V)1`V+2y4ihIXwTof`FtM zPd~rVED<-+b!!eH$`7;RN=;h$89-);6YMFu{Nra%Fu^E%4%3VUB;qB}PmKj69S&)W zBWx7h9p#u#a;BLjIb4mRmLJ%bhF0Qtn-7MG;M86==DrIeCQ&dk@=MC%s{4-QFwo?s z{s7Ks)_$x@NlJ__!b**jNhPIMm-f6gc@z7T0MOk9B)SP_ix8@+~FxwAWzekn_X3rjNJx`9IS!J2d7?(F*!moMNaadD6x}RvQ%BxY@K0s zj`!ZXlVMfxp2OQ82tzmnIuZA>;sn0nk{uw^E;zK$c*HEvU{&R&L5;%ojwLzSV~7jN z5!7-qKggI}%>CG0KGajg{DI6nZY0>LVCiuE+yK3IRj4s8z@=x|<$fk5w=pADd&6__ zN!~s~9`iy}5IQyqrNLrK$wt>~3xf3QeKD9Oz#_kNM_aRXKD5CoEnlW9Wxm>Un1zan zroCpUpZMI|Is@1P>Ytplc1^kuX`(O$Og&jUBiD#3^c~qy_%O@MvQK_;6VutN5NXMz zsWIps%FB+yfmD5p2g14NII}#w)epGy=;_My8vWq_1t)6A9!=X2W~xz6kB*$nrT&8| z0Mlfefzi?NJN2w)zl+?$q5{K;zn<1=kc)!|Y1jm!;{|;k{p}ajpM0@-FuEoA> z!?TvexO|P}W%#h4UrFFFFA&7hdiGh4Tu*nIjTN$Z=@h{TMy?P^npVw}L^?aN#kv9m zU_L939vAk=_DM`C@9eTMlQS6&4b`llbDUoNiO?CD_^zGe0RMdPx)r1*hem~?oM%Eh z72SLa2TynxB*p*Bx%BJ7w)W*{zcm`}|Lt}SOLB;CqTZ1q+VJmbfdew$Rpyqex8av1 z0eL)3x9S=HD8%v<D|Q=%YOrhFtv`}oHc&MR$~U_yEfeWsb;$= zH8~unNpX`kHV6x#ofkXE%|fD@9-)|U>NR$!Xa0nQ!>cVUP)-GJ7UmZ4Os%Qz!c5u6 zlcm}lcwG_~r`W^i8G?-1x6p;tDH8pY)wT(dL9t<5y4IQ)XC&DOGJ62x&EBUL)!Q+0 z0pCXR^;1ujvpf3Adt-tYZ;=#j_9eh!o&5^n06{~Inx_6T4WPUug_(+iZAlsTz2_qvSk}5Y91Z}{)8?(w?`DMmO<| zHAon}ZG&2!>0#gYN=8gzKsnrbk(0IWOT-!y#jC`rCUx?($~z${JSuus)ZtKC4AQaM zsPTm)h>ib}4|-5wR4cn&ylU1sWN43W#f;im3OEFu`cm`t9h}J zwUA?;V45Sh{VQWGN4TAo?dSQ?Woh6Fsa4th7Cjet7iU-3L~4A`NM$(0bFtr~n|-l= zBsS_F{eUMil6Ei5-~Y)Uy_{-s-WS72sEU?c+FG`+<4|#?NXKXfm@P>@d3j5j?H2_~ zuqpz`5?m&vdXnl>b#2^pgZD~YZt`x*A8Q5H0!C)y zqOI@)?t7W^;BPlV^t`<^bX4p?^)&4=*|xaWxeDiFXGx(pZtnND3$TPp4{Oh=XTVVZ zbTb|udL(9cCB|<)AQ6Z);BoK7X+0*$w_LwhsvA>s4q&W;v`XoAE$vA9zHaXxo)|$?1k`k zdh>Ml51HX=6Hx|_`gElGU!-7%*{`%Q<_TInE#hWKHmx^^nsAtKW2`5HU1Wn?ht+VA z_lj&s-4Ni1FaP{QD4he`F~f&W7&)A32e)75A3F1Mc#oCg?4j0Iv8=+<{ZNG#*rsm^ z92@kJ!=X!uSOt)y767;bn67fOKRT<#G{2rdPTc_9KCMC^JSI#GX9ADb|1j9v9{om3 z!fi3BHyp%SxJS0UO51J-8FI{GOye7reHjN(VE4@9T(}h|vAOyHj0&=UOwjhSiy;jBqm^ z;2i_Opm0&c5W2SbeFe^~{8r`bg#czzm(h}YwwzEfe*7HoUf2o|Qn<@1mGy0fwT-Z? zlu>=?HhljUsI_6ApAx#|v+9D+mZ|LJf^UIz_iVb%8v&$7Ci8--I7Mi$0;MD*;J~uU zmL2ou4o0g$pNEqJEc;v0+xxbG9@}@mk!FzpYzuj@9CUbe!AB_rAAj&>zJz{&PD(Qa zT}-a;K?gls^5i%UJXV`RKJ41rHzG9w2`#?RgJW{KTE<|FPnBWe@k>nN5O^dp1T=5_ zxkhLIpzd<8<_naC792*XA(0p))N^T{M@n!1D}(-2u(rbw^z_T0p_+*w`e@uW?du&c zI@D(hs?u3AQkI$)9tIiD`DDeIhZ5fYjBLA?ZXOKY2&IO4#KWds!s3E@%K8cstB9mp z8)>;fQ{#E;w)yX4Plg8COd_AlMDIsBArppLL`TzV_w3<#FWegF!&rIq1da;{hOA^$ zea;2elv%&=yJei*z4eW874O3@lSUI2%f6BkRMNSurWQtsyHaL;bshEkb={xQpTWrI zIpRYhwzqX3^d0MR`%UmtLv^!?)@G_9dCZ z41vn!d|kSqs(!kw@ik7@Xnm{4>lU3jwTtwZd$kd^tU=9ZuwI~vz~?DPPTJN(8y6J(?n_0)&Cg%p?5!c!SLoZ{ zA!q2F7p0f?{CUE%vreVZp)*UkJi$R}r4p#i%5RM?hW7M5z7ptY3w^WS;GiA({Q533 zbP$PKCV!JoR>`&UyTSBnFukOd5yA*(6et7fW zjZ95fL@LHuWu8(52ETB5<|fOC&g1y*FNW%rV;%3|JzhQa&{5N?xc;eoerER}9pX#K zXKD?5;M^Bz1`2c1I+&qp#zdzrgIryGHV*e;nQLU5 z@W*NJ2`q5S$x`fPRkEBp}$b~FrEERLuVaN%b)fu;%gBuK%XnH|izDThG|a`fQD zDCn$oW5wez69qq<$kZfy$O*9i4~|X`+7qc^Kvsr$B!xV^Xpie!j^ebis7bE48-8#w zIpxTei4FwrB|Hiq4lF%$smVvV{E9QV4|g9P!5zBUA?hYi!V9>Yf+?-TQz>~aH{6fG zf4MXj>mD_a1biG@8gNXGVjhn{Fr8t4s`-9g_yB234jhL=rNSAwjY(~$P!3#x!+=cq z5|HA4xNWW=$=|_UO;mEpa+t=_xt|{ OfQzC2zsBAFFa8hrhr+M` diff --git a/pc-bios/pxe-pcnet.bin b/pc-bios/pxe-pcnet.bin deleted file mode 100644 index 7a54baba1e485a8c97866df5369c0d3392361b6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56832 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 aJJq(+IulZJ{-1Dg#SaVo@00KUU;hWfvWUL` diff --git a/pc-bios/pxe-rtl8139.bin b/pc-bios/pxe-rtl8139.bin deleted file mode 100644 index db7d76d9ca41889cb993fdfd73a9f260f0debbd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56320 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∋T z8_U8cY!tx?Wcyi4N&YT=Tky8KscADwYksiZuAqUL9qLPJbO7xTem~T+DuV1Uv|Dw# zQq(Ak7ULoDHmz8_PkjEF>M6F1zWaGf(E%%A5)SnFNITQ4HY6vkhu{WJM-2-)^ANDzD?lDy^Z?)Ysc?Bs%WPz3dctt0F^ zC{2qUE%ZToBQE>vjJ(IK$ALmfA!#K-Lag%Kuq=IY5OYkA zevkD*#MnLQ1GRY@v5o;=Jkos;+0_8>7hS=OW2G7lsSezEDmd_+XkgXrd13D1*zTnS zA}>5=-c<4?0yO~zy9rn3hMx9&mN@cx-caY^H5L1Ljcc8o_i8GftfJ;`?UfIT|4yIn zvsclTAiua!{-H{i%op@qj&lr- z?sY%tQ-ysAIwo}Rv$;%aqGaB@x7j977u}l41gFAy=yt7T{3o^1KW4XG?0A#^G2{=K zYaImlV$tfe3dKTlZY;9_&5yRO*4!*hY~$oX896W+httu9n@r@$9g~rht}aW#HHXQZ zL$P!11S;~JTklHVPYJ*=Z)8Y4KW4;K2OVo|FFaH;Xu~!n-hKS><&PW2YAP1NZi0QD zHI2XXurfu=jK#E*yyrNi3@*o&Z@9I)dl8gckaxcMle=m^0#m=I)nvs-fLHCG>Nq=7 z#|V)(i-$FC&&1)xbGmW{h>!@4f}Q^~(7WX~{B96)oo$M2RLu~yptON|?YIS+Z}L9D zc(WdmWnF*%0zbh_E3e|tQjlC4$_y#ecf?HR<#g&@N3(-M4S>5Rn9DZ`ZUcG?hySPI z?C zj9ysc?xSf&_AhvegjUj`+;B9XM4=x}pvvSZcyf* z_2mU0#!6}MZ|P6lKghKx2>EA}nbu&mWo-{BGZg_?qNJIgyrwBhYOc_yA{Sgso;2@- zq#dAGnIbTn9$geAbu{KBcOJBkUJ15g_3^>K%GbMUKvCt4S(TeYbRO_7lEvzH-WdPw zFgc8MwC5O(bsT@z!USgvg2(`LXV=*%wm%{q@e;XbkHGrSp-(BhZfslEn{M80&B7@) z6JM1WA}3#L&63bG;`Zv@|4aJMB+R6CoLvm^yVb3}U?6?E8Q0QuxKr9vL3L5p2AGMM zRymKebhErY%U1lmtZ52-X&>;nEXhdqHS4?GSy{X6^O{hIQ@4rf7&Q!|F4&~{GSohz z-cJH21x{V`={98Pdp7GtF9;4w-WxbB$m_^;z-Ohy<3+452%i^KbAkSmJEF=0@-LobdCZElJBK3_0mlbagsnfXT!Ec9{AIje9sf|3f{Xms|JW$t;Tc&h;elboH5>r&x zD6^XC*k|*SZ)rO{=Pl+G&kh+iM<9RHhH4)t^3|kpY;?mV5cO*NLC^U78p)VlcRytI zH=$`l9d6Ie$Qn>{0{nMWYOw%-X0Uy(*&AWL=|m0e>0vGpj8pLfM*S-Mw+c&uw;&K7 zhPOlk19o1HH<6@lpqllHWl>Jyq4smg_KDx`v& zgK|>vxlnfVoJ{)_!>+Q=m%qvDotxJml>RNkILVy_fpNJrGT)IPJ`C3|;03Y~Ng?;5 zwt&2cQwxQ{R_El8%&s?H+KiKV0p%n^m!S|+Ix9z#gU{DQ3u-s=38nFR35kGm zF;=1`{?;1a9N2`F>4P}gR2(>_ZfBUhVx*blu}W(4PD&GGV0~$AILa~yByp)rJHF~p zsfTRs>h4g=;IiTrb6Y_o`KyN_p!}n;Xb|gKSq!{)cVJC96-~&V)1AoG<{PW+Z7SGK z!M zlr9xvi>*B;sdF4Ru8i>+@`_FbpM+lwt6$O$YOQtk?@-W^eLc`_{eZbprfe2L7T>`>!fN^hWo_|(F zhMPIg=)Su)#cuE#O&1UeN;^Qw(>+yT!L>JQjxE3d2I6$rj=xRt3Yghv9kObhVUtYU z#1JJ4O+bYE-kX_AMfQ;ka|g+s3PT3znm&(&^TJg9cS3+sH7DELVSsSy>h?4mY-)*x zNt>_!0@B|f(Y8l?+x1jAR``(@@OrmEu4%+4en(FhbH+;VH(*3$trHEY-;bK>`*jE^ zwvac3zYS$L)t90b`l5l)+8cOMT66NyEanO0?W~X5XhDQknvkDvrxS+vPXkw7q!8NntBQ}F7lLg#2FY; z^lf8^yJg6sR+bMr0gqVDf<|CGE!m`xsuzM(h${Z+HziaU0V=3RUTUG4&`<6BtvK1? zSPlHs`wqtqJYeJTUN_OO`B3R%KiG4-)zV38z0jX{ggiLN23^Xv769Lo9hia=7w2g* zL>8$joeFN32HF&Xw?6AEgA#rKcDwllZ@g+DsP+Sd(up;oeQuT$ebdP6vzr`-qIs|J zxw6-t9w=_UO~q2KAwtB9Eh6k9=NXX)An+DA3diSW-d%WuoARYL+Mi2(329&sPHFk! zZj=cj=Js1Tq`2~8ch=uu_~++W;oux;2bN;w*KO(d5sZBobG;*h6ZpuFl1E=*ZWb9{u z#gE;naElC4%M+N*f+o-yr(OiW*Wx{UyPO`N@;d#CB=5-zZ)YpQVMWLR%Tqk0e!TIA zw`+PD@2Z0FX7Z;1001|FB2Ej;_OfTG)JaHALtF8#p7F3CM@rpDQ*gE}GxsGTk&zC> zhyz6gVql4{lN%A%&j;`SUXEwreuz{V!V+&)m3@6?W=?krZVsr2!%=ynwl^6TgNljP zEOz{ODa`M*@-unU=_{C#g6vg~a|{zr8a~_=kPa%VL5m_t(9lvDcV?CCLdlRO4v!g^ z-f2}a&QM7b zUpGs{#1(I75P#h`3Sm_+?>;p)fw8PC<8{05JA9QqZ2H^ax>s=&CD+6*p5s*eVu*_^ z78*C42Po@-^I4LBE4zdD4c+wNWA|2_6@Z@lAmEqwX4MrQM-9EUC)7w5hybK)_e8blbzh%LCTKPBRk$B0hdzZ&FQ>h5f<=qj->w z<~uANA7GC#>g^Gd#V2Xhk4l9XIU$WzOsyW(RtCGul`x{+fGG%D&OWqX+#xyp9_J%G z8I{X>Ah{+wPEOBM;d+*Vo~e#$&rGg}L`5NjU3t6+(|=8Lc45L_h>08j1|6bO@`+cA zw~(D(g4Yzch;N^zqm|kfGrkd^OC}bB6(v`Lal#~h=z#w1XN2rEd7OU6Vd2NTRZ~P~ zF)6y4BG?A$DRnswg+H&qxL~CY+Hk8s5R|FeE}3I`5^0tYQ06aWTa_{Meg=jned6ri z>4un<&Mk+XoBuV~R%@$lUW4#|#CR{;DaC992Z446M*3|P$7RzwY$-*)PHWv_TjxF_ zK3N_3rnX1BZ~A*n*03*o%%#t)D#j4!D?lKsWg1j8D8^QrXgK#5Iw_>N*2?7x zg7OJfVTT`n z+|a$UlC~A5rr1_Wq720fcqn-PDg3d;F?9v>ZIcwrTP@7$PTUwWn>I++v(~63 zjp9ZNK*q$syp;pJ5DTlC zsvci$)%K4byDwKEy|xzDWf@sQyN}Bl$?Is2H9_d~(p4cd7Ox|1uZ3r0vp=4&;HBU9 zys;t{Nj)bL)5e?qF+dm)oc!~|w?o2^)OF{upIt}tch%`M>z5Ssv112*OFrPyUCkjh z6un6))sh#<=5If(460LIxcySWH3d;3F2rbOH~@L}|DK8}M%l>>!~iu0Z##tuS|t93 z!bIx%uAGF853*TeqYno|Rr_zHn{qVJt(wQ+*$|qDxA|BSqDTNo1U_N71oE<3UEFy$ zI%<@uTsf<1PFeu{^%wh3vOADonXEeNkdSV{$v9M;Rx$#tV`Is^U(q4ae0BEW7Xx5x zglcc4wwESXJWtqwWrffTw1&97EIn@MQ(7Fe?ej*A!5nAaAQ|<*;>1LN);d5o{ZmD{ z$@lqeiB>?+v9ev)=0fhgrU@O92nlf^`*2+pBsejvq6LM}*5TXx>OHWvtc~UEO4fLA z)W0-k_}|XNNTzgQydB~PiW}o0V>s<;&03&~{6#}vtJU4UJX6I>7x*x*iwNgnP#ht7 zNStzH#s}Ph8U~pYFb9@o${4r3H~Ja#>yty`NV9ZQ`^c0IU3B!*>@akQ+zvHMU$SZ6 z@nJ&+wa2$YQ=z#FV;PP4lfp=fAqR;~9QkRS2G*%Z3O@1&!A7H|ZTKUJ4Kl+y*d*}i zaQ!;f`#vYC#q1aOWe{mw)+n@9RChnaQ z>iH>jYKr^HD;n5@gRp|WfbwBykWN`K8LpDesB=dy{{$S}D*s$58zG{;`IYDXyrRzA zyj01dmJ?o|J9~aLF2kJ$Xl_Pi2-((4MF^&^w1w)%6^`qBNbOf$brYu6ffB@Oc%q)6 z2cmaRZ~`U+nA<_L2ds}4N8BV^b%qE}?j-d1EvDAZD~nE&Q_+RCh6Knvte>A0HBMAh z+Yw+4ty&oa;Sod@h-4!I(PbnR=!sh;07upb!kAd4;*(!xMZWqimCfoX^}!oh2p|bE zt}9jpI>CnleKh{Pk_~N>HTlK19~`7SsKHkCsJC6(Af>;L-;QISP!^X^@VF+%6Jt$` z86ZnOCSL6`@x9lyYdOt#0pZ~kcHQWgauorVW+oJ$G;orXONyyt4a#xyxVjTT?&|Wy70XqI0b_7+&6tVt8;d} z3-T*5XWC=6?J7jVct71Xwj@UcZXBUAQml4W)?OKLne2pv!XdjNamk;X|4prT@A%>J z$g1z|asPFi@AkEC%Db$0wpBSh@^z94yi@op`%#nLDVib)BKSnxs(W5PHPITqe z=V-Xx<*#g9X4At}}AE&d! z_H6K}q5gdjlC15RbqTZ{^0cMKa`U&TwT;C%qUIGvPf-^ob%sael23zB*05rRSf34k zuh7!-b8NUI(D>|XpS}%GkM})@m^jlP| zmmJ4<2a8!=ZpIxe5E#KKr()Yd##SmREs(PeZTAM#m*3oVScfzDq3RkM?>ws{`0x*e z|7@TBx4yfp3W;E(7bLwg2!8PDC)3650hM#&1T?&4-tC{MvA5kKBDI_mqdI^w?t3nL zg`{bMQ8n<}UAtv_s*v;pw&k*K{0B5HQL?Cr&!#?rP6=G_8&0u2s4|ZPs&*{c{NQ?Tqb7 z@wfBmZ5q<8{I(~i;AAnP-cm*|J00^kcctuC^`BcqJ`HUA;Ur$Xn{&cZ zgDvimM5&n8;ETrbrltdELKPqA#((JFr#&4&zZjb~*qeTkjx*7JpfttE_Nn)+CqdI$ zSZE)R#JWd{pK&_TzZ6~m;Z#2REB6ZpBKl>9neOo38Z&<=klpVMw~Os|_+=<0E}nvL zlmb&a_5mFa1FXHK83*oXBj^zGbh6!YLD_#24~_taNW9PzT)gA?gF8-%O*yT_P?f=M z$b9>T0!qMrqXm#)bL(w$JFii!lba7KsQvx+g@p%@W7rjd>9eWXA|>g7h)Azh{_?*v zfH;|Fx8Fu#f)ZG0{OInNzcvaQ%!!!%v)rE^wzdDDH*IWpeCD=*hDjAVk-u*E?$)Tw z*$D*nz4#}#;5(R`x#WoZlR|d-(K#6d-rEwJNZ|IsP9v66@0tRCzkD+Et?~OiDV@!; zk_u%D=dI>jB!5_=OzgE;Z(V*X`g%j+tn7H5oz`(&9JFms@5mFyT<>N(+?>uBrDFg` zKBgYio#40jy?PEtx8+VcnsuOV>_uf{+p9T*w#5~DXwK6zVCc?2Ts;|oldM3sk$>%W zkw2sEs^ZPLe?wy31CndrULIXBwLcVIUvBdnneKO#$si{X4wP475@b^m7Ybx(=VAxq zgObL)JIQ;u34e#@<^JgTal2VprzBKZ*FqnZ1qgk2{KAcZ*8uJ0#nc}uh>d;_ZGIt> z5Hz1E_c1UIkm#txEBp=F;i|v9@$>KQZVx2166^VAal@YCkf845D0kRC>;WU5W%U`K zl-aElmm*-9(aJlu>=Q zPSQcOIT8jV8_V{`TDMWPxyvo`wH;X-9jY&v7tN~ZuC?B9Z@NP*aHpScSvN+EeEdgp zzq$>)Dd1C)n*3uW@G|D{pTYH=rRB$4pue@C<+{zbFr7v31@1!vlfK^T)bTr1@b)(N>;$1Af$sRY~yO((f32HxlhLh}W|J+UF z6UDpAefbHi%;T*NI1&eX2IVoDI@8=^HH5`iXQ;AY@JDI zX9d~e-#GmH+!OI9xs({3HA_}QdPg%^vw0eUS{QZPYk3pTigpim&wKFfONHjT#oyX? z+CFM@jgnwZ&j}UaLqNfw&inA_c%k5Dvz5CpYTD3S^nLxYqCco0?aq&1A~f-yJckms z{|>;uIKfHN`#{uJj;M86*~%9JAx=7=~HE)mtGB8n>8x^ zJM5C1oeUcXVr^Ep_8OOZ@(J~lBFMhh%M~7LIq6fyWunc{(ywTyq%FEs`>Y0#>j6xF z^0G)1_Ijg)&+5iIS$(J3#{xHRXdD2l_Qxh%Sas2>;t2)s?kb;Qo?d+GBI1wZNF4>A zcUc8z{58`BGt+Hc+<>{A^?GKq3=ih`-#0FMAvoH@Tld8dLlL^lKC<|@@F7-p*H^Yr zi_L3I8!{e9^E?3nm;LUsos`@3s*s-ME7C#7&UJ?%-a&%JAkNnI7kAw*=q~~YtY13s zcO`mHHSQcL;pfeIu#=NIp=;X31lwvofB5;*I{46OnLw|Fus%>ipG|VKOAq`r&)r`; zbB@u7@S3AeDYaG_6u~~G16yx#>=;3=eeljJcBdQmO%}r25wfuUzw`zV&uUDrR@gA# zVoxM6I}aonTYG=g)WUzu?ftYr z5Vx`d38-H|e#8|$`7JPu+=GhYl!y^r{VezcsT#em97q5F(QXLgc6+7IA@e(aQkq8>d`QH$CAnMiBFe!z}$+y zJ+esTG(a>LsLBbI?@ILa-~>&3-sl~#BqgB~dXJ4V0y2HrE*7tXcvsc@P=3|AW8jGR zNL($2al8-VHK97QgIL0haf%1{g4s4ih6=i`4=*K3g<0%i;OELDMZr!Oc@Whv=_*=y z@A*a*P1vwo-Oyu15(c53-|17DFOJdiKI0YfgQ6u7KSr_ENeu%5JFe_IsqFI}CiMH2#7dna*;o#^g$VaD+vBt};MIF#ofWrAh^5p{3X9UwK_u+GYy zXzy;$fmdBRAX)dOz7cq_tf2Q(-5t?`o-l6DPGFKBAS+{i*=%wxfxdK9o)$o1NbQ_Eyhk0y=XBk`ee3lNfD9)5ZhWFr5TI)DXzvh&CBMf5etv?w=^ zpgm0Eh-bHc05^4)bSFk>33#>#Qf11r`?l}xu3*k2(s?8{b5Hd}!}8@i~<$RlChJ$}H$*t=5+FNtUx^9y@K zBd&{TZ@F44Oj4Z@qW`IE`YY&mPBiqeUfv{pMfsgaH@Bj#^1YeDp;hfFHC1g_;xQ5g z5$gkztE}-tw4KewexP-C<0I9xTjm0CDD%EM#^JKvVqI!@blw{wM!AL5ic{A|%T0$> zKFG%UHMR(qC(LDZ+SmS=nWFK7ral!7JWp+koP`gm4zTzK=p$E}aqZody$pc}f)I~=a zzojn?PL8{)IooAqK@yg`d=QRZx=SF(S6>0MM&kkRJ~;-RD_yxr?_+9SGYK{xd@y`` z>6-=gA2|`*3n2o0n}$0_^5nps28EQs3-hh9fz8pS`M^OV*tqvO@cNH{ZqbR|5_^E0 z(Q#5eu_K82Z{F?5K=(g`QO>cx?YFiRkwj3!yD6uo+zs*(hc_Z8I``6<{xLER7NmrOT?{0QU_CuGM+ z^Qu8hl(ucbF4D8%+tQ^JX7KyRL%4W&ros$gD`+cu5szZz*;kpQ8&})vgx3kHUdS*a zNE(z-p}D(A-?+!kd=k3C=+#zjx5(MknFt2@QwDIeFvn^<0{#6ptScuW;swmckB&c8 z8-5>_{3KB}5>MpdAIdnj=shJS;q60!Uk#h^RmZQJ?TOIzV~ygxfyn$R8;%}1@m+#- zmr{F{1x>C6AneAd*kiLt{Qf(&+Id6Zwv10F41tCf)POsSF0SpKx?H=Jy9?xOK{ax| zWO{@4;wu6NlJR~-44IG!H| zp90tH+`5iX^^pO)uGboQ?nTn+qfdK~e0*5@n~RuPk~L;|wfDqqY=oG?5?&f2y4Mn3 zZsJJ>^Fv!sY|>_x)0~y{5v2Ra>&8nsrQiB1k?M z(s<IG@B=_%O{JfKEyE|wd*t$JdEoeIzsfqbo-w{V^bksmEbUJZ4b z0<5Ynlr61M*Rd<(RP0qI2yom+a)^^ywFD*4tagCa1!pB+av*G=vu^0RGH>D;NG#`U zNktsbGmG?H(h*On#VQ#l6G5l)*Q8ojYJgRGKM(37xENG6Ydb#@X)vmfqOVat)ICm4 z@zIh>CW;Y9v!0uwpP;wtkM&=RuHZ)lFnehlhk?qMDxgx*-ZK{X(bVJG+J|ZCTB9WD zd5@`LUfZTM=C6d5kbT?&)Wc2fS8hTQD;+_aqe0`-`5mX!deB58*LwBJfk zV5BZ&046dKyd7O>!3Uq8thRbu)?lu!J}NcW@0TOJ$OIpq-n`ZRYjm4mKln)QZ^jo8 zHHYysGQBv;PMR4KY@xCsQ-2}nc|!Nv0h;HYS?E}y)ZeFeQY)jwoqyX4lRFS_zbh-7 zjBZP2%!tj>@1KT{2(x&6_e3{Ctj6>;w=ox^e@Bo9WBs9rlDfNkKG9}MUbBssb-Z*< zH}`7+ELm(K*5Yl}ijz0;FzhN51E=N`UPZzN(&F3Ht}vnK*Hc1}|1h*gbU8LA=>dPZ z!$B}LG*&yMG%N?eIZX9=(T|Qr&(scshf*P^A%B&}4J2VB0=LZ#$N*aFa82G-cs+RX z5jFJ<Cx`bJzKHTo(k6AbF3<|^xx;t43YpN_#&&V5eSo4N*1WL`UcNwz;}8e)1H3w4NoOepZ} z?vg?dPwH0{OpA;NIq=r#FOk^`fe6YK%y~y*mMkX_Zl;jFcNp}*^DxLvF|HI`+(&++ zrzDI5HV!uTmAS5(GTmfN(uY*bvO{3@qVj-8)|5~*O0!soZ0fQj_Sjz~t&_%MtqVSn zo;0U5TI9*hoX{XS)Um_#igdyU2CXBApx*39g(B{wd*oG4&js$u9<&?mi*AA`Y zJQ&Qss&EDYDR&2<9)wkqDw}NVhFe4Xaa@QdoW2v#M0D{(TrBgLx$~#rU5@ij#;*@g z%~Zlc;yJuzs2&kNu62SkjsM{WqaV`)j1;+D8cW=BH@iaR=~kJh)N&Xh2c>eMdk_0v zlOZLOCEYDOIMFoWmd^~rvE32OdG=Rkc#OO38M+(=`5U6QkUHAv2@0<`vQwH(v|EIG zO1(6`A>_nb#!%m(c8@Rj&m%D{frrK%MN8w=be{v9FlCZ*P)nET^xiNbQk3s=^$x{{ zz+A=1C>Ihm+BWs3kFumD65F>wwku%#htS^i&Yt4;qKVs-2lg7H^ir9 zcVwykCwd0JYe!V&-Y|zmhYgF-T_TV@+tkrhNk(7>D^15}n>dw?2Tvp`v@e7H#c}pb zjoI=?XYQCm_iR4Vs3V*x;}kMHod4DmJxnmEhPVI7)GcCa&*jEy{>7y&HfuoJRHOOd zr0v&3N;Vtaz|x+k=Xx14NQXa!m~7dGKdNFRIImK>ImNi|on^g;GxBnh5) zAdv;Lx*C&g+T!`3Me+j6aw|3JH{!C5ZdYRogD|yKI~*}fu&$&)w_HC-0onfB#T+m0 zIx$r_dSWy$fNq#l%L<8YR_l8Nv+Va5wYqP=$CQ6AvcDyHG?P8!F3eP%DTO3Nsvj1@ zfZr`xuc;j?Amr`8QX=6@zNec0ehm%A zLAbHrF?H}aX&mQ$G!JgZvl~}++SVwgBP0wx+$>PWk8n+G?Blr8sG6QAPlwJVDrrY+ zl(OQtE{RprCq{HqsjAk9UDo~zS1C|BGWa6GA`YmP?)Xt3JrS+du06cXt-}pB^q6D2 zjN2iCSN!X>{{nw^O7L+MDUXFB%le6WnMUyqK*Ul9_AjksH_$lr@JtTqL$Iaxp8iwD zQ_{&dZ@zU`wTuH}+?ypx7HQHj`%a|59n^{UJB6UN$nWk`b!!j0M@QBiE|3@s!a_%t zGG>0&Nf0Nfyeo2Ve8~NB^s7CIVj?cmb^Ojmq%u3ildLA=?+%T7+R&-vNR*RrVjbj9 z+_={rjRVd?F&)oMl+O>&{``wHI{K8Le*!{N`=yj#DO6hVguh7cW4mHR7w3J}@ECJo za z@O1sZidAZOa}O*nrUn4I6P1!f1s~R)RbI*G6xyh=7T8iHFwd%~Ro@YQHw!aqof8;1 zk`kn23xp(++PWq-RJEVsP$Z@@P!ajlHg6G@^B#jVj)%Uj%%DTtA%GLtaxDi|0y5eRET&waH znbExUl|e7W>>TZ5D~&P<_??CguEgdaPI&eqTHLI$EDw1ySC0Hj(2Rs8 z-c;V5<|H0zz*L5y#;mzrf0f5oM+4+=2F_S>t8{2o4pu$-{r2Y6JqCl=Ew?1;-XyIm zxFyNY-Luw4m>+QO^(4ir99L)&52A*?$$EJSGcHr_LUjVZ+G!zJma4Gob>7I5lJinl ztM8l-0vU~DE96%PnLU3T^C{OeG9HFbx4kAsK->Vne6G%7j}peFe%Tku8V^Nzs>iNV_u1J%BMkQ$YJ z*@k?ElkYt6iBX27AVxF8f^d{^|F6q-dif8pD9e?{T zSTj8%6Kq}BI05TnVVfn6-EXA$%m2!x<{`IWMA>%H~xU`+5Oj=7S*7n{QxoKUwMIYOXN z72qArO;hH1F1K#D^mx;BvSm~6f&v!6pk2}9Bf+R2`3Yb+h$tM3$%2B@vknyHgL*{1 zggWfJ;c0VKott(rZ-R5^dXMvtENvk)7ypn}M^#I)w@=8qVReBdgx8o;7>v(k*QDMMaVQZgl9F+CQ?wKtcQrBKLXVYJqJ! zK<}?dNLbbyvO*1j6q)H3ozbRD8TO+;Uxx5Q5-ut3)n0MDB#*)!EF6NBil%$scn5pj zBzB4Ag|GZYGevMsUaiNQmsQ?;SX`v;uTCA{Btrtu^!b*PGE1AjGGa!J_T$X0*!7W(e1p>+VEn(};6d{(*RtFP1Oi%$ZL52-wc0Mg!a zyY4jBRWH6bL9UE}I)dt7D2+QT9hPP`{2E)~!-3gwHPgkY1wP_8_%}-s1E7LdnXd{# z3Tf1*c{0#0(`-wN8ON#5%ve-x>WizbqX5@#tMcCyE@s?Y-jPG$bI;rj`_;0T37z)b zki%omID9u098M6{%G0K=&p=}PcYdms+K7o=y%rlY8o0iNQ<5&ZOKgRRr;B7dNISN0 zOLF7pOa^V*kHne8gcog5J+j7H1Q!eRQ)=z3%9r2t^uT)L19Vo)6VHi!1_p|CR3SH) z=|{z$`4rlWn}secM@hSj?;;-bEeG@t%0Q|$;;_P_B>${R*_ zAhXAV%uGz+@?b#~P4ktM9`FgJsNp){YL@Ax*EAck1|iX98w1cp?mMB!SaPi_73}@k z>XcZDb9mJhC6@?ItO(Ks` z?nx3T3H_350Q-#J)T~(o(qmeqDFKX1@Z;{9V?EW-`IqQgmXb|I$Aa?bWX!M@h^_YS z@T5XyzIlJ>Tr>7Ruq@tC|oW3*i9TGlS>m+UNEA+_Ps}Z&H zBsC6u?428hBj9LZ1x;O)wMyk*doIUu4%R{|>ntdnHT^Bv#*n@={#A@6i;VgTo#+!L zG`6T|vKHsmEsMJSW=|Wf?5N)wv?rv^i3rGUib zyf1~5Uvq&|L_f1I`}9>O9cqxBT!N_6xUc+xsPOo5Y$BCfjD{U;@^Ka1W?)@ z5rjoj=wyf_$bPqVP(J|(fkW%XFh<^(8C%Vc>ds<_ZPl4x6HwM<%%?2t80>Wv6pRox z>h9zlac4C>Jjp0_}MR?A!01O2lcM)Dkx9@VYrX(*DcJ@5h;Ut0d-YWTy0n1+C|_#oE((0Moy z{qf@TdVjwJI0)l^gG=XlU@1?{=*!i25sV!5DD6ESb(Bs9oe@`F=#9&M3}{75{hi%; zayHUq+@o^WLIirA7C0b1+yj#Uunsq9N0RWIS!Q?6V>9&*UcB) zN*cXSXKkYZTp%%p3J@w!y4%y^Wh!fcSV4pqHol+#{piXJ&IO+62txa){z@MBHu7d6j%aaU z8T~Mu8DD^89*fv|9h#y=T3gzx{fC~#U~RWww-_8f8%y3%`?H-Lw=u{im?)rRUTYX6x>gUv4v2m6{wqmdx)zkw5+*HrYgJGW3V& zm0jYk>k7Nd64S#$>OKT2su~X?Dova>EhCCfUyEu4F2H5+o^oU@H-a?VQ}&ats+yeC zt*cynOX9DjxmLHHWgpNru@M_owyItw0#UZ?SW+caQV#KFWFuq+*iYgQmaQgqzeQlT zQ)b2xk07=g0pe3$N{_;k`7f1Bnt`UnNI%m~iBz+EOwYhfvV3EK^x{@jN(E}q--kd3 zde}X449zc?!0%PGn<>4OR`ZOMuC{D*!hhKv$0_7`R$z-GvoP0rrD_R4z#V`*KeiDEM$g+(F=%#|f)UtG0RLYq7Yr_%a;7IN3Bm7wQaZ>kl zPbV{-z%bmDWy6$=js_$lj?)(*u&G;gph9V+$W+6T|1#$lwy(%vntZeR5v!wN^xR7F zGHly~V|!w*5amM}uy*@k$8$w$XN((~>L4$z&R6{J0j^7qXd@(kKn zSv`u>>5?}*Hf)LSwq#%|2&@p}XvAmt2tBDN$VYwth%{FoH9}@3M2iGYd+V4ED zW(<8KtBH``f+0gjU#MelYpRV8*Nv{~E4B(WUq_x6C11y&_@7tV6>sl0=b@Sber>t% zwu_6|RC{SKPu2ugnE()CdxFt)xo(b=XPkORQq{pbJ$-G%C{-ETazWcRy?8@hcyv-irJ19Ta}T+@tv{wsr2tMqIs9pSo4oEv}ol$g-;P z?$sh~?=9ZW3Nq&DGVbXj?zAFI%SU(Saew(cDF%a-bH1Z|@nu&4jvAPI>$U>y7Z z-g5RrhTu;)d1ZJkChpmP1`=k+@H72&(fZS6M{Y81ZOpzNXoy1{K@8j?4{1Nu`teen zsfOk0Tkd!}h}6O~%YC;ung~;Q;zBfZbd`g+T;ZNu|8E~w!g$O7BF(u>h@0JwG7_^s z!rcxTA8j0*s-Q0|6%6oxShg&$JdItU3*>+I(>0+EADK`MU;`qL-g&fBySwzv?e`gY z4!%Rai7Z!8arVr8Oo2)c-2SRvL9N1xr>$qe_1B>U#TN;R^v76KFIfFPzPs}DjN_Rn z?M1st@!z=3b~`y|dK$YJYF!bMF(B-50f(Vym;GKnW5icVfsdkdJR3_y_;VpI80S8B z<#{p)EXFVcpM*|(L@=4jXKfQ{(EP-(8X2(V8GJq$Qn0uQV^(t=nT>Hi$`z*PIu%B zcrN^%i^_H}d}T@qCaTxfNm zX>$_}wPSUb4fOXDSx~1Cnl?}aZV}^RI zcyjk@x}5^Cxx}~iwyTsu#omlFdR2d#%OI|ToUPj+xCWyL`9UgNC(@`Cx z8-H;}uPR|-j(crS3(82|&w|+EiG@{L(z5l5i)m0`HZ6mD3}o0AH1xfMZaO5y?z9>m z_O&4X6+0%eo{m)F#4HmkFlpp4-||CN{V~Q8)7Xl zdhRh02?o|G;C;<*E(q*e2-%auoR{Dqhx8&#f18Zy=m`|>H`l(ES^m+cA6r0c)c#PW zHlC!bCPPD2N|`iTvQ|qJjV%d>%5?1u+jP}9VWH=-EO_2{(I`em+GaHN7phm$ln_bZ z1}e^p4sWdw*cao@Hv_d!cB!a9AD=U>&_4-KqvU9)-9EhWsyDja`v_?i1O%AI;N$$& z94#Mmaz_#JT1OM43v8l5UC~&-<5We6*ulr0gS^`l44d1KE*xxVl1QHZ^x|8n?HF1W zk#*t-K_MO>BUq};-Ek?}V~pRr_i6fbxH%cVl9d;Ut?%dlM}O(B_(2t@#-kVnYR0`2 zsu2dzv?Z}a7ZV>>IA{WELPIv^<+BAy`Nj`d1hAIYJ<7OZ@trJB9P(T_IobF_)cgWf zfw}D2eMcT@tGg%6iZxeo2q-ekUncmJwbZmp!<89dp)HjNF5vmk{K(su6c$#&IgyNS zBB}ijNs@Ym?dAAgwtu`iszFX}hbS(4`P|pw_)%rrSJhb3qd^ye85(bS<2q@T?CK9X z>;rMvzCFA~1Y7B&8o1U$L+|gK>eF z^Q4U7!++=O-Yaj_Pw`T>OodZZG`t#9!kXi}ap@lEZrHtsI2tBn=R=uBySTJ=jrVSf z)}Gro>)$7D=d>s5tiAKeKv6A{TGHif0YHjbfzo1}Ys5~QUL||I5_0{wU5^ZH=)Ip? zwz!)@(#xkph4LEA=A|-k^&18Xn|e1dpBP{)4XEnEWO4}r16^*j z;3h#R=3UaUc;Xd%25|&&Z;bbZjrajooR`8e9{3YjU?tq`!qj}6Ldv?HFpXxJ9i+Fw zdSnO$0C*9YE|#WgXtMMm2YEmOA>4H%yCe6%z0m#e^$ zgO{$-C}*ag^?7Ezrh$22fO1&PifzZ041=92#J;?DQrP7AL5M?By2<4mY}87aPH4c$@R7`M3&`7?h(5knx9$(0E+ir&X-SqBcGU*Km4Op z(m<)=(p=8{gS_-~St%udq{$`qVIF7C4dyEHLV<`*y-8S#BHAQPbv?ii7swJ@N39e9 zFY13E9N4;v=QWfxF@9+9ay;LhE!uqd%XN<8Mx-A&wB1wj?E-{T&W1=a-QsE^j%&ZJ zQe-raenliJ;VT4RBl~fZII73Ye?`bkbd6gtRIR~oIPD)dTn^-qednBTtp2#LOQ*{o z7cy5Z!Yn+vVIOX?R2>Fsa$+^R48rG^QR(76ciCx#qt1@B?=niQ&<4htV3P3qQ>syf zUIEgNB=VTThhc9#*l$mDLVtlhMvkCb0YNqg*03PJWKBF~ZS2Vw^>E@XP2Y#C(dTbY zvfb*MO|f3~w`UY^OH!&-kxX9F$9`Zx-xX6BB0X(j1#)Xes3fV!q5tRdKJY?KRpo$d} z5C?4`c>qWWZ<$#)j_oqw7KbR)JM^-5JGM+>ITw4gtl7(rd))SZUeG8=^v=f&|29dG z$KBUytixxxmvjfwLjwrUS<@V%UtQ=9@l#Q_; zAR0$ecE3!NT6W*)^ss!}?`_B?sxd*%s4Qr8g-p;%G0unS-l*_aLDiHQR?PZYUN>A@ zHd01Grqsg*c0{;u(Q#k6r^l%BTOe{FJ2QWde9)ghyd3lPmD) zyH~h=k?OXMmsKNbAsXhDk=v5o0s7W3mLM(E9e*T~>+Rolg&t>d-^yU(YgvtlH)bo@ zaNDSX?10xduUL&F1v;iqsHh{-CRTHNVgX~ntu_~?EsDz9u(tsJrK3!)czRrkH&c(R zTIMaBhnOYM2QGV5uJPg%zf~-T?SN-9<}uy#2D9)*`Ci2&V5^Ouh2i@W5`C@}tx-#e zICCM)!p)_k+WmkDNKJ83mRbB&l@sf6G#ij?=%pNVTZ=Hyj0k~~m2?FL%Faif?w-dG zii?3YSI2ae)qu>02~e}b8t_W%<7d}^i}cikh1Id7J&-PbYv7;4CWzmOMoU1`v{a2bpXq~aXI?js6%cE~O}7ml>M2p;!H@sk}2ZksG$?8EAg zo02)cgaSx~oTsKrB=;)Ic7$}}w$E{Btb zEB=-azQ*eT5M43KrlEz7Yf9sF1X|@Ta=Eo^5-4N8h0>o^=QI0C=L@HrOjqG~`W;R! z(o*=MplWQ#qumheRudC`r$tpaS5q!}>P%P_)v$hot+4WggU%6-K&jrKi_z zAkHd(HjWL~L1cySUV)TlZrEDbumnL`XllH|OpxM$Wb2`QMZduNMPKed-?wPyMO+Y=@kHLh8B=22649CwG|clXdUkb5E%nuHRaj=SrTUeV!| zFmPNsYr%bS=-0(QkwJYQ&uo2>+jMy~i&DW*!!esG$3vD>=UW(^I6?|N+)^92+=JK! zMXaS(|E->?j-XFN$XUsZV_n+a_$SAbSo>;6Xn)DQ6MrSNuGZN)>-cec$FX`)ri(sk z^D!!4u}wm1R^@{o0_roie1wLU53Q-w6vS{f$b{17xhTlR7mp_?ZM_*k9h;4`sj1Jz z?HuA`R92!Fh4BF@-f@ib*VjsV6`lM@4Bs@vm!R~x5qiNbxh^DU2+z5!BJypI!MtYc zb;nh?S&IE&^$5LGDKJ z_7L~z?1?I^BkQ{K5~1?~EjvCf^c$2GkTweymRSuM8$cS-3g9=_q;;a<0<8~iSCuN`*TkM+?z<`v+kAmT}MCpd*$T1Lk|ovEQ`*UUVd4D>G+!`dHx1B|^JE!+M2KOJ++ZBcm5qpZw(-82-4L82i0@l((W(W_NH zqS&PHcx%Mg34LC4Mst9RnI0slB3q%e1={+cW*v_?576BRxjeW1i za&Z_wob`T7ebd*uZ3S`xBu$RRzddNSvCoAoZ+rV;xc(_T)LXGD0r1iDXm9tPkf3X! zwZitu!hl{s6AlFhy@a_t4>B+Q0ns}MLI{NPu9&{#)ac2wa0=%sbhB-jXI1)d#pb>3}uDeD+o+HysBVw-{p{uJpJK{#e=fn zYwnr@H<%*Dw~Wf-;1v86>7Dk*<`CM-o178`*<*-bJPoeVY1{_pz7y=LxOB96Gk+a5 zm=*Fn6|^-p23n-YEVI?qd6#O3-@I1ko_)#V7s}Qv*^l5S8 zkVYdFxNt8OV%XACZ{iGKSG3tK_9$AP=<2?2epe@vq}uo{X%uK(# z*+Flfz%+ZkQSJF1LXW4~egk&m>7=U27_v%WLFN*!)dztC7*s13h9 z8ggZH=p{u*o%uj4vnQY>sWkpnvT=Vab5~_Nzikq3OoC>K%C}SvJ&zqqJh_-~zl}eO zg83T5KdZ0|t-^oucQg+t8r(YIJg9PjNvueH+=<#?It8;EuWz=u^g8AZBXXhD0xK;I)V^LJ74xN`Sh5U^ZIL$!_q0spW< z?p~Gk!_JDlkea^;@%DowNN}UM@2{lt%T94LoA=d*m)&6UzJal2LALrFP-;q*s&!b# z4NoUBD1N*$qnD4mQkXtOn&0!VaH{y0-?I4gds4xMDc*52px9(n!Q&%PO+D2?>U{_Q z6Vp*a(qc6~BeVJ8Y<>2{^cNEm}si4Fp)yw;!!@=gM7=teE@TC40MC0Y8{nfUewtt>QENoM=eXNcM8 z=$_f6=hK+t0`|ZbYS?w!6}p|YLjE^VnSU^c*I0^Wn2Jn z)eh0a!ZQy}WU1V?RuGj&=J9 z1EEN;dqufRzaDwAVm;Bn)%Y@Kc-2aJ+2+6I($3GgoDp%;03gPH#!kZE?SSWWo_ezq zr$PcE69K0dC`6XJp4IuN4|Pm4jVlU}Jj}h~n>zLKn`V^-!BS*tuh*8cfn}6822xNK z9+k3ldhL_7;VvFOvENPm2HdR5_UNfELImFCNF?x>){l0>it(pHZz$Hi1<95MoW4&y&f%3$A0JYcb5YQ)QYGl= zHnu4~m{W_8e~=zcMS#gLg=gJzZl6S^aKJG_iJLi7&mue{!SL;-BfXTZDEXLeEZnv) zyQO3WU@=a*djxJAgJ2CrUI$3zy+SAFV2#lbnFo;xFar|BB-l4x8vyut zy#M5)(9j-r-p3QZsdNuPTNr>POlJan9~oED@{2);_FXcb@Wi4_1Nj`)i>%R`b3l|- z<_VA*0AG%0@=s!GtTudXo}E-ryjJeX32j)`*E}%^i0940d6VbH>h{D?sR4&}U^(Bp_ktvHm*5Ot%V%XEgF%A*+}zwz>loGH6*s zEp`@WS#h;ovTy&2?Y-7R-QxQJ@GI&x!hFTfl)^I3QF&llOjS4J8M>Y%G#`d2CtWx^ z_8j~s2+p(R<)O&9gnQf&=OvOBRC1%fW1*c}iJSU(^Lt|43$0C6mZl-{T9hdS z<_@tV)k5MH?hD4f*cCQZt3mBd+Av&o zR&j*nzknKUEK%MPvyVihA#IbwkZv^O&A)(C7Nl!jXQ$*hHO|QK%5ri}t!v@mbb;-?g31uje~T^=A9t8< zAyEGXCr^P?%@R)8d3>hu|zp(4=rebOG7;_!@gCE=m*jLNEXRXN%q-Vo8w$> zLZt~iGDm%|QAy`ULyP^$ikx~7>N}M8mqqf1bCr085HAe_omRC54S8f3%JK>i58UHO zwXAR-(~R_tOde+dthT@4c#|SC3G2bPUNOFH@Azu8iF!;Bcz~av#~PN3<5&8~p$^|4 zpkDrFO`gm|09RQvAI1A)kyUqg5&quFmz`8jKMGaJ_qSj2Xc{kJ85{j(vYwTQwShU5 z@Y{Y}=Jja{%vre}0%HLr*`75Pq#ml_arLXZF5VrR_+!D}EmZ16KCh3i79_uHf6J;X zX+P5F?^eh`!QNVScxFV2K^1z|Ko%`itp|8&K?6T9{P2kc0fWo$HCihGoFFey8Xz{Y z&&1<1zz{n%5eQ-~RVO|Rz_^=S8QVd=;@&;Pwbma1H2=LT(2-`nKP<=9;8D)xpiYkC zFx3_ZHZZFLg|kYWyvJKfa3eJZzU0fR(Tj$Se%JiSC=kY-dlR6uOV_+O`z-+k2RpR^ zIzk2FL!s2rd=0}OsO}Lm>65I#{02cQ%jA>mzR^F zI;6FQk#l{-Vbb2Xp(g7l8>u{qlBc{ml=x2RKTku#7DxgQ`F4{TB3lgg8C1K0Y5)qv zy5Ggja9%3L3GXPMu(gDM6!eb{CHm1G;j^7$`?^&V zCUgz^cMv$F>(NeBC1k2ah(a3h0>o`JE#Tkb@*C!OQ-Pv^0+*1S1OU#Q!u`bfRmIV^Z}0#;CtEG(9ceLMAYLQ~9f zF`$k|w@{+pqVE@Wq)|$w$^KD~%JS~TU1{SR4YdZj4M*D>_&?bO`brKm5=!!a?c%+D zcTrS2JE*HKMk$TAztGsWgNo4*L#_2-JS7BIC-W-c;|5uh0iirhNFq>jQ3(1*8$;NO zX-4*tDebC0g;|1y`@Jaf^iR^z4ahK~r4(p)Bk@eiH7GuUuEV#u-ETC)IWgzgWf9Zg zXT{IpC^B-Wi3GJW%JI`#yUIOC$~rl%Pe}!3S$r3?zb|<@2n-dIbA#w+&bk2mwv-Dh zFN_uyFo*83Va4+7f|<{o$H?MOmJUN13OZ`E#c@mq!q`D{_eDuhpZof2loKO^#VwKF zZ{)=v*W9^9Uv2^h<*r=UeV_yaR^>pY8R#}ZW>$267qRp z$3zJywcYx15`i|_<^KU(q3Ma7TZu;h+@ITTh}J@ghf0oZ)@v6h!&1kdW2{W7XlEuj za^WlebKG~g;TkYBp&~&eV195?BPNXB2-e5nd_y zu@M%O6S6qXcY-#3DxAldCqh8wvbl1chG=zFKO#sb{ZgTH>EqDT&`*Y~srk|;Z3RF_ z-eBfT!%XmE1$Q?E_0$*Ad{&|Vm=rG35?+Aj+g_#}fKlj#cw*FAG2;nU!AJaA|1qI+ zhQXYPTbZjJ`kEm6{+#wIA3pgtPV_~B{s52nft>{_%P)M`4l&vP`KS~?>se8Y z&Oz7?urjqNOt{Pa9Qg0hNKY%?H$qJjtH{%{SDZ|V{p z!+eSV5?^HOiX)jOHY-Ayo3J8ZO^AXhsn1XCjPg=)PbWp)lYE@;43`jnP6xMaORO7} zSqTVf#y4L!)}tBzI0!EuI6~?br<05WTr4ohjX~CdVdvqNz1I)t=bx%!w9`Xq3Z==6 z=Ij7fzrA~J-ES$9RX)O{*}<=t`KDs}h!~V#1KQiU#QrjGmlm5ty#ZT?hmL}Qie$*T z$9=vNr#J=zBgVCQcw{MTA{QA#&T8@2SMe;^03Dd=%#z_vDFx}*kWlS9qx~kNg9L?M zeI#JjXn@4aHB&-rY7FePfRvW|LI40=99e^tf>qZ|2La6Q8LG_oz#$s90C6q7h}N{* zIx*KcyhRV*{)bN#RZe`+(Xz!nqil&jnEfB{^Ao3*JDdtQ>{ncV{;zc=nx8Y=oR~PY zxjWJbvl67oCMz+6ws3q<@|qu0{IG^ld#vdU4JIJhftc&m<*eQI<#1(fMS2L-s_^>u zs+2J3jS*`Z5O7@f55qy)IQB29ESn|p0-9i@bqNA&7U--5a!;2@KM~os96jiP4lTAZ zku_?u$5{P~qwBn(rWu^76~ISR7j+ka?K(^h-+VjBkrBdNU7PeKna$+)b=Y^c$bREprlyt6`FFAnbH=Z#Uq|=g;;gPqH&VCk(%C&EDF6&ag{^ zm3IWA%9|R^x~mISF&z}ig0A6G=hI;x#Vbb0W>o#SuS z!~e!5atWUgELJWFh7q{> zq8vy_W^77FES}%u-^u_0L&~;jmVP7w_}p_BlaQk4Cq4Yjp6r_GWcJi;A9$n#{DcQW zmBPkPkbJk$Cc2tr)wgdIxU=KHx!FZ^WqmN$W?i(&yVux*@a^FZT*TyrCo+aozD#xh0;T;2CI?9p0FUrL4 zwA?nI_}Q)W_0%V^5|BM#iV74je^*kv+|JpD|5uyP5L37c?mKe?=plfM_JV>G4JjWg zch;N(WtVk4&)zonK>;IxdN9F{+5*T|^8ff2>76%{MU}FVF^JMd*Q#veL>I^Es^X+; z3pONbeOIxt$rOAUjMT0)6q@&e;fVAgN`ae}k;vi6gq?|X5(YbMnUNZ63MF~+{|V=P z%sy8D3mY1w0p=C_RLzHY3-()wol{U;Wfg_?sor=$;#7~Fo@5EBtkS|&ol}MC18qk*8L;rH9e-8NZm4$*B^XFp+UI(5zU^1fK*A?Iu zWYTzSuU{PkYM(D#3W?f}iiMikCqcU3+6Lbbn)D7l3Hm7at)Ls~3Hm5Cbo+r7RDRYB z-7wh60{M}T*}2%WK+YPUL%alN<>-_CZRAB$#LeiQW?03UveHEpW(qLxjsviUpZZ6J zx_FmEn-|;N-llZOY>X^`fRB@5nSDyRU1Ye9hSX}jp0SjLlmt`9-eNtvL+83l)&BAb zCq~s7HweMGp2`S*d$WBeOAk`9Ic0KHA{n>_&XeES%5m6gdwh)zE7M&PuQ+d1$8*A9 zGqcYeUS#=cXiqgFkDmWuZ&&^fW&i!}ahth^8-p23CJeHKVeGq%86<0#$TTr##+YW) zY-qJpD5XV-7M{{Vv{)-kMLk7IS(<2HE!9&Gp0@e={1e~z&*yrdbDdw#xz6=kwxa9W z0$LG+$H}GLdVFlAwK!z!|g(l zh+Nv^t_!kC#!3)xOHDJ?&guP__29Q_DudSM$Bsy6rllvfTY|P?q~}r3`zAj)96k9= zJ2f-DJpE}g>gS(be@`0|R6U82zF5=tcH8S0ehHFfp0#@WV zzJ~K_@8+3L9WaaxZ?HMJ^2~|qT?+SSvL4r!pIQoxKRlXURa=*;`k*4BWW3EQBmt*= z&02rW=Dy%vlWNgVme@KkmUrYyv@K7K{!tCbKerw4{;(%G%xgMRVs!L(tZIbUHwj!S z3V1WM+tKiY&~(7RSoY)1nHnn9dfqgG2dk z<0`k9AnW7HoKb}P6Jarl(;AlOs-m8*y}7pt2)xzJbFWrIomhwwLdGxZdR8>N*NH1= zAIP~dm^Zhtoe*2fE-!7@wFJ6@ALb3K50G&`$h~%X4KA6mAkU`dU1 z^6u%gj|0JvJ_WT|(meBt|Ne#ZKd-b2st$f~7q|DHLUF7E7cud1hAj7Lt>*i>sTv zho_gFqY?n#Br(v44Jx2gxie(Ee$&{xwt)|d48n@Jq3gXDG28yN?Jo`y4KKOV29p{P z2ZMi)SLJXoE>KHbXtc2nyOuszn(I{XDmPdC-b2YgZHB%Qnrdk>A89Ib5zQyxXK_hE$d9kjF4hH4sE9bb z!)=vHyoaIJkCOS##pa9}frjVX-_%bx>d!v-YboPYSV~yee8#oz8~r<~ZGKpv{8UK# z{1|CmqWQmih96J7J)(HGxb2iFd)*i7j%8I@JzQ*3| z-#;rK(hCZsb~K1yytDs2lZO84!WNVu{%j2_R%kNu%56 z1q=xfCy}LM2-?)SsqX7f88W^GhaqKWGO}%g0+R;QNO&5uu z3l$3P7E7*3s2AwXW#U%>Awf#z_(B}PQi34ZI606s)#D{>F_Fw+3#FXK-@KJ|jwA;! zgn`ZK-B(ASi6jOP20 z0$r}srkHOb@d+$ZKi5^77U=ExvvIc7ait^4l4%qu1ycFE)4bNJ@-1wwhoDsb!yJt# z6wF=gdCvsmf_GeyU6lC<^vJ)nvXb4$n+@>1P=MOne8rwT%fx1&p8L~&h^2f_*b8#; zNVnrfH8#FIo~^1aza(aRzOhb9R_;H^%GS63%T*!(J#vjqn# zq#{D9Nc2=4nMtFv2eKu4qUo#j<}p2-Gl@XEHJsY!_?S&sk5Uy%?6rO}l=CG7ePJ4x zBNH<;B_cjMaCRIoh+G%IOeeS#%*pRI+FUWmUe;w1g#2})lX}nOf^9C>CCOJIci!@l zdV;TU)OdT#9&t94-R;XvmcA}hv}Q;8--tHg3J4y=TQ`c*Zp4~=;Mz}I8p=Rt=TbQ{ zntlBTSQiOlxM~uA;z$6_1`UrQ$1P7Eze+^Y_EDfQ#_H$WCt4>mYj|4-GRa2*bu}eg zBTSycXS!@;7#JC^Pwl4jGq~;y(4Dr4uIT{G%KHirs9WxrJYaIysvW0Iuvxh@rVw}K zkpQnx{hGlaG2mTk6o{p#r_)ZjFScBsWdI+62oZ{j9WI)>OBq4H^DguZtc$@&7%oUl2d{-0WA=n92S05%7)GM1(X-J_Vu@V z2f4BRwv%QSR@ume+|4rfN&=qET2`n%bm*i%`_HgC{!j*rA-=12!7Z;jK~lNTAKOfR zS4C(ny>p5Dt|@$_*ZHaAJyXjXXhh*QA~A|7s2--B-oqtp(*h2au}+2ZCs7xA(w}6c zy=10$=_&SaHs@$Bidbf?Nyrepq|Wm^Eqj40M}t3=o^yTd`g@BQC{qFn#`hS!h7u{O zfZ)|BEpQ8xB4j<)YGfnL4%T8?(M>8V2HAETx6a1L+@xUE6K)>9%Fb*`V$@-E&ClHl zh|R__vb=K-Rk+_Kgo^zyjus52UTwYa>FjZ-ji@1~$=Lo`o-+u>grDDPu8_6P!D$p3 z>4%m?WCBR8*=?!8B^{G-tMC8Gf(b2fzpl_lELs+&tFot%#w2EJOpmnhrT381h)(24 zm%@sfo}{YXsiqXtc+ps>5WYKx!fQDrq904>Uz<~DEH&S!GJjyf(%EysP(fUme)Sm- z2+C2<%ik6@$Y?j|dq@B%t;QK5cRrDVFFnCpF7GWf1`HFGTxl}@p-~{n#~mTG-{zZ% zZ{_1@U2Td(lRhe|(IkPYhL4NvYNHf%#YFin5bnJq*C{%^tR}UC`z$3!dLJmB%iXbC zZv$(0>bHIja#cpi)b-V>sr!X!JR9=C)DV_OiX2*2sLqJQCLD|H7HZOS>~~w`TqZjo zq8&RF_|pdSEO4f``YdZDAl2FGYA5?ja?Tn`*tNYq?aQn^nn#pnyhNl;jykLo@q&yP zxvY=n#9R6mwC}1}C+PzzK38;E|GEJ<7GRugk7iN0D>G?r9nU+%*L%bEgt$a+A7l{f zOX~BPm_(!ooo3xWbUkHj5Y84b+y8|?$j;AR@S5s}wiu>nOR>l3$fpkkvhXPK5vtlL zz!vam9~f2paA?uw8mau#UnP^vGGI<+}K(l zHSN7M@yFjS^>J@^Z(j9tKeOV7-v-yvL_5#P_QI452bcbL9SEEYDL@aN6f}o?0oJe zMr9$Wa8frjBXkjYJQJblpjpZ$#Rg7It~f&f{4Mjhf!@pvm|w8L&oQ*BXWxJ&>uyCr zLbH~Px#Sl*-dG-_4xpR_HiaRI%uXC3m*AN_D~}OPi<#`|;GKfZtvXZZuCte~_)Cy3 z-NOG^m(RW-c6Ny2#ONJ6PkjYlsC$&0C@$y9ts~>Ew<|k__UCHdw*VT3ILbgtn1D94dEN3qkEg8c_B1&?ebgCk>W~G34s6s_LHu=;K+Ft6&R^eU^~q zste8(syb(ZY~5403RT0yH>|#K-JDvq3QvxS_Sd!Gt4?^U^1k>$#T?sKQC2o9ok{y^ zG;DrJ{q#n~LGrb6N*?8pZ%jB+(S(2tDF4{RQz6-0PS`<~mC!*-BzZmBscX{c(B&N; z85S9p5IK;jkh}fVKzzA)0F&f3et>q7w)WlIjT+8(CLl^=Oex`3-I0W=9%Z50JC2`i32nMf zl$2Gf_pY};OUU{S6q4E*;PC34324jS=!LbuK#YC{iu{4i`g&X*+F2u>3nWrPeauGs z`W-Bz;!jfT9*@u4k{xR}5gMfewo%+?CJSm@F6>)VyOA(N98N{)%2HQ03YKL>6p)b* zJ0u!EX=n9-djgglpibT)OXnFnkx~lD!%uK^Fi9cT*Fs3`oW1{RO(!jMVWv=!rPaIaTOD&pB@tOoc z^V`~nx36qW-zI$V-(B88&}e6Cy(Ek_5>Wy!kk~AK(Qr1%-7f5uL?LCKz*0UUZLVS; zHR>h>AJ$O+dRIGx`#5FjiQ_j^Qe++s<>O?p#Ur)kW&-yX5S&lbMg6zmSa~~#9Uxr% zd;&*HG@z*6U`)PyY?@{u4EJM>o*Eo#V25qeaccP-HZFZE$oMWbc-k|SwjM9!u-~e_ zq`5rgR~Vln$C1N(UE+VFhKR`$^X`h4>P*3a92BPZ_N(61EfIZJT1}!�OC$lv5n%3xi{UJC%+fPZP@xqoyML}ctd z`X~J{-0@k7KzK~!&ukorv%l*Tu0=h^d)(PKc*bDt^u<>0Q9+pj)Wp0Jy_{1$G`X<~ z30^W!2DP6PfbbD}R-pa!E(8x5aQODB8SRz1uwR*PNUgcopqc0B`@y#1q9`mpiPh23 zeNat4`d;@lpqGOEuWWmiyGsDl+$R9We7lxC^$?3XZ@6C9;G{(wYli;`XF!A@4{e8+ z6H4XY&lXFV>7Q#4AeS^f5P%K}(WfO8g>#1@#|<%4o?z3TWLEX*v-J=FRCyuf0pmdY{EbR6cM&U&Ekn)zWMDf_mAKEyLL9o2ekK1!1)%t zXPaHu5lfObQ>+>r6i=m$M3tm`Ls<$kzE4lQ>CAS{c>)p0^s_@?dR>(^aT?)g%1@v*8e zLZz?y;1^X@v??X}LECr=6YQ8~na z^u8bjR66){@%E@#AMizhPm6adzEsb`&n6tLKTr~aK}G$tdVB+%-p;o(s$aI4fj+yt z3D1|pSq3b)OPF;H*cI*3uMZVg%sPegi4nhdX^C#CjFh2tU7far8?*)=LH1L(kcmu7dC-OcDJrlz5ZHFT6=W z=gLe(B{fw2oKu9V+M?3*o`)s^L_r!D9XsDZ%Ef!dZDF@tSN{YroZs^YT>Sms=930o zP+kZUjC>OJ^^Uqgv>5{PxT8M;EUWUj$fst`9{{0AyF?#tUfZM`Jc`7Gqrh8GgQ|g5 zXN^w_qy=wRwZ}rX5 zHDBWr)Oe*Ux5GVRq;K<`8shsf{YzMt?gg(q9Y;y-d9g%`IIz*5P z`tX%GU~uH?n@r!*caPk*Jc3TZZ@l);jT<*DLc-;0ZWv=D=yH)T#M_1l`RpM>=67cA z6Qe^NlA)Kiemvhy$hFYGvj&nr*fZJfd)|#h?l1^`2)T_#kGY+jf|Qlk_#I2$a{!VFtLLhpyDKe_THguwtx<$fG?{K)-Ul+T~kt(tfn+K-Fv?Dph!~#H9j(^E zDRh^_wHQh=%*9-&J9!EYySN>bR?&pNv1%u#xZ6$2>8gN_I3^=7>lTuZ&O|;1zXawJ z937ld(?`|UQs6jDPt&ps(~fCyCZ_iteA#$%;veU3cSqESj*DqyNM>II;Ikd`%h5wn zm@-MrgZG*iV2&lWEgyyJF~}CU9rK+rDTeyt`xrDxgNNf2J|7!gtUEmT$|GO#9>hMz z3P&^+VZH+LxPkwySy`F^X6C)-bj=kI&Uo0bU8uV6B7Qm7D}xo3x-D?^I1p8Hc9WrM v_2$2zQrAg+TvtA{t;C8FJ+eu@(FOQxcjpf14fsD$5U@ny`riTV|M~qNI?NBh diff --git a/pc-bios/pxe-virtio.bin b/pc-bios/pxe-virtio.bin deleted file mode 100644 index 6dde514c79304041837ed0de99678149844d9419..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56320 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 diff --git a/pc-bios/s390-zipl.rom b/pc-bios/s390-zipl.rom index f7af9b155dc27500d4619ea6c9eb530d27a79f5d..3115128efe465a024b2deb780573358ae1b829a4 100644 GIT binary patch literal 3304 zcmZuzdvH`&8UOC?hP%xJ4gtbake-C44GpDB0K-eVH#`h2rHiy0klJiXfJjJU*wBL2 zu98~fSXolRYISA>mgBTqR@7m3wA0&`I)nZJR#L3~;o=?oM|YfFXzU;XuD|ar0V>{^ z`#9hEp1<#LuDZ07)R6y-Vy9C#g~; zyiW#_?m-n26a}9nAQk{6b4=2>V>KlANSdN%kze)ESiF5IK@-#vl{v!wIqmBgG(I<; zszC{;8J?$xMOxbrnAZjk_ed-V3;$L_-iM}H_`TaqVYS8}c=HzSU*iryU&s+sP{4^w zqAE3m$cYFa?aMt+;anBfG)3%Dg&H!bB3ds3&B6|_MNk4%q3$HZk#>-Rp?R5xYhK7w zYsiR^3`T_wf*i&dZ zg!=^K4YiU)zfE^I615YyB5pbcEVRB2;N6JTVYYGYUyxV`+pF~6YPHVrYx+6J9ETP| z(;GqeY5JgEFJzyzkJUh<7MMu)IHd|l857{Za_s9d)8y{(|E(~MB$XHDP=v}=9aj>_ z$y_;2<2Y`{QW&Q>fSH==U%xj18M5#*7d)|?GgHl#3&vo1Ah`f(d>R}35 z%VMNPlh2wf$U3BJq!(*H`sZ~gk_}OKKedn(%?b)T`7AojNu$xiPAnTl-V^l7>(!?T zwd+$S=rAx9w9kpfkOOpcy%S4j;vbbrdL?*HSJ z_U5Gl16D=ePbpyYVXlvdX9Cur@7j0>06$7^$Pls%Y~TDs2Hwne_4~16qW7~UiqR{wWR%~ z;EO=v|+iL7lUO0ocxH9426A5%)W$j-C)#PM`}H z>pfHRipm=Jjs8WI4(a}^)AVjTLS(#)`a-VV3_7CL0RAARCQSey!NzD>BM&K|9)yKO zxbMCm%Mz_)_3ber_l8C?%yHt3d4tbFK4W}!+}ljeypfdZq%7u?XG0Y#k-I=#d;$62>qdEQUv0se1B;fe{~H!-Ev<~b@&2ISP3wse)E3V0-jy@^$>!5_ zla;k4&z|@C;r$9HmE?L8>^&v~PA7QC=i~ydaS<|*plRwPyqb~%4_5_t*K-WaiTq4a zrwkY8-g##+W!G-mOBg=$E(r1^3I^&Ce%$I6>*!dbiyYtyuCXtEGd zLlMJ4zqnOLmFBHt>w|w*&B%L`k#_{!wIV{-L!C0bG1Ln0q9uhW zo;3PQ46rr&yN!uPXiw@MHW0^G@mQ?t3n6e&_kaU!JwNwyyf_Z|~{< z?$5qwzHsjG@Vzq@edWIU&F_PCZ!%-foc_d;2h0>pnr3&)!fDZaK38MLpWN8mwrTU0 z_ScSreBshpw{~pn?CSnn&k?oH956rl=JrJIj;Eg9x$Bp&vfRr*`RQf6e(|dL$}_zF zy4ARJ+42>iZ(3=-_=Eii&2K#T(5i=5KN4H>1@pkSet77m4WF!i^sz5~sd?S{tLBfu zADLZ0XYRbuHq2jOnm@+6h{Po|TjjR+ z=Jt)WDc;`E)+#%?;;rqSo8|Vl&D+{K6Qv{cp5D$*rtfO+?trcx?LCS1t|xlh;;kbb zBa+OqP}1ryS!B{8a#L4tXX`AvBHq!#YMzX5+$s}Yu-(}k?~s5j-rJFou-LP6#D`K^ gQS=FXtXw{_R&MI)+9tQeds<~{`}VD$3JT%<7a#uHJ^%m! literal 3336 zcmZuzeQ*@z8GrU}!=CwoO@I&xl{ev#L=cZaAwY_|;lp4po`M#rtvN`5laQn#p@LPe zB}Fa$I8w2#w&S5(-WJ<>L#L%d9k+hWl==q@GXbpA61t^!ygyhlb*O=Cf6se~(y2GI zd+$E`eEgo@`#jIP^6D;PT1nzbK~v=%3d(LO#(zL|(nL8(1+MA+f(|@o z(uBSVQ~`-Dt9@S%nJE=tH-`H)uQwV(gn!FH{{zDShP>>n-Z~0PO(Q(rhwHbv-h$6E z*Ayn{t|f>{Wi^o-F#~jmQOO3RsBSMxb#=05!3tJIU7==xljYtL1N2CT*1lR&v0c2c8y27SgmKiXHvnRbq zaCiztoRmZUI-sn_wdQD^mqO+#XwRiWDpW{KRs+%sXyo;UD2V?*f{|&iutKEo4d+o` zfbIu_rJrRF%h`PuU^q-;WEE+!G+_xuax!=j0z9l2mM**fck!NFlfBAXqG-g@t%zCZ zT9;WH60lMkjhLbA$;;3&2H^`eLFAae|L%_LC9fUq5BZG;xemH%29TEEy>6SPR%Vyi zD|x5?G2}JywcHV~dt9!Ehl{@NSE%QmauHGX(q*vd3_{wHTN}fMk>d>!8e|#J==7#s zMJDVuSD;?PcEn3X!JqQ85jvajbeMe)e+cb5C4WG!3Xoi{1(p1L*c^iwO}%S?JfP(7 zsb`C^C~VbWp$ZiwyknF^{$RuyM1UtgJlKz@T;r+dI#AbCkg zp4+_02;TjS67_{BT7_aJz`K3!QCR$)`&~VCIT^^h)N?ylhn+^;A9fPBKkg)P-|x}@ zQL=>V;vcR#pn*kHB^9C4^N`6+RO5<)0443{K%N{+0efDQ>}7)N!-8$PAPXYX*IX-8 zMqxLSF>xQrp#R(y+A!=!Ga(8eq(*|)k=Ke(k$j7KT?^fK06iYgmT-@c^mGJ0t;_Op zzU>Tr&W$8sX;((j4GDO)D}gh=yKd}#CQjb2s{TBd>bGU`s+ z3OVO0jqOlhr?}FxFMClnG1f`g!g~$!T7+4RO5utQ7N5qH7sTtpopyzwgNCYxnb3XH zNkLj?XS`l8SFmhuis~a?FW2bxY-Ynrcf@!2C$hG6>Fg0<`Tvxgw zbSn3DHBPxfn#Guuyvd0WY3F1EW^dF>Q&LuG;2Xl^Ydzz(eJ6xE4Jt5=?@H$APs6SQf8H^LFrN&bK2 zWDx=q=J_(_%pR|n_y2k$&LKp!9rZ1tCfD^s=3YDBAM{e{G*L57`wOGG_NRm7=s>j9 zPC3HC#5uDE=o{QbJG{7=6yK96%xGpASFN&g)vTN$PXN`c3Fx3UUcuY-oC9lOe{Oc` zFb#6K&m76U2l9OR4o;ern4O)zi!Y9T&R2U@`Q3}y)9qAB*yfc~pP)m~FL%whLhkW(!G4*bPtnz)=`j96x&fM&tE9b!2NWbtN zYOio_p3!+HT_%d_m~&9vU2Emu(Cq%8L#UnZ-1(s8-rdTxy8nGwz)Z(}!&b#ytLoEm z99XUZo`tT-@A`x0jXtI*-4I9be_O5tlctJZs}0zesp`Vw>134f7YU#KA-MriEK8FM z{42IFP4t}3Sqxo-}hL(GJ- zxQcH(RGhN=J>UH;$m}o`s3--Wepw93(Ju?c$^8PDpD_O9H?H2wt$lw))}(=+K+w3! z*n_jZps;A{IJ3B9ypbO=$|ggiep3x2e^R+x=8eH$DKB-tO_*p*5&qup@1%@(+0$Zu}Jbk-0VV=6`;{!rDcK@hqNmOw6I8e4^Wy3R zyNTkhJ7X>JCb2!XCBBI^$Kox`O`@eO))a5uB6c)y+1}jRnLjG;=xS|c`R;go3w-U2 zcXY@M`SW64L*%;fjO?0*)c57FxMS!wc rS4*cr#ExB~81iXl4iog)xwvPI*xb>!U2KhYG>NA8j&1*w6w>=Il#<+z diff --git a/pc-bios/vgabios-tizenvga.bin b/pc-bios/vgabios-tizenvga.bin deleted file mode 100644 index d79f0a54df61c9802c411ab0474e71692597f81f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38912 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 diff --git a/pflib.c b/pflib.c index 1154d0c..64cb2b3 100644 --- a/pflib.c +++ b/pflib.c @@ -145,7 +145,7 @@ static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt { if (conv->conv_cnt < cnt) { conv->conv_cnt = cnt; - conv->conv_buf = qemu_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt); + conv->conv_buf = g_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt); } conv->conv_from(&conv->src, conv->conv_buf, src, cnt); conv->conv_to(&conv->dst, dst, conv->conv_buf, cnt); @@ -156,7 +156,7 @@ static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src) { - QemuPfConv *conv = qemu_mallocz(sizeof(QemuPfConv)); + QemuPfConv *conv = g_malloc0(sizeof(QemuPfConv)); conv->src = *src; conv->dst = *dst; @@ -195,7 +195,7 @@ QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src) return conv; err: - qemu_free(conv); + g_free(conv); return NULL; } @@ -207,7 +207,7 @@ void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt) void qemu_pf_conv_put(QemuPfConv *conv) { if (conv) { - qemu_free(conv->conv_buf); - qemu_free(conv); + g_free(conv->conv_buf); + g_free(conv); } } diff --git a/poison.h b/poison.h index d7db7f4..5354e77 100644 --- a/poison.h +++ b/poison.h @@ -10,6 +10,7 @@ #pragma GCC poison TARGET_ALPHA #pragma GCC poison TARGET_ARM #pragma GCC poison TARGET_CRIS +#pragma GCC poison TARGET_LM32 #pragma GCC poison TARGET_M68K #pragma GCC poison TARGET_MIPS #pragma GCC poison TARGET_MIPS64 @@ -36,15 +37,27 @@ #pragma GCC poison CPUState #pragma GCC poison env +#pragma GCC poison lduw_phys +#pragma GCC poison ldl_phys +#pragma GCC poison ldq_phys +#pragma GCC poison stl_phys_notdirty +#pragma GCC poison stq_phys_notdirty +#pragma GCC poison stw_phys +#pragma GCC poison stl_phys +#pragma GCC poison stq_phys + #pragma GCC poison CPU_INTERRUPT_HARD #pragma GCC poison CPU_INTERRUPT_EXITTB -#pragma GCC poison CPU_INTERRUPT_TIMER -#pragma GCC poison CPU_INTERRUPT_FIQ #pragma GCC poison CPU_INTERRUPT_HALT -#pragma GCC poison CPU_INTERRUPT_SMI #pragma GCC poison CPU_INTERRUPT_DEBUG -#pragma GCC poison CPU_INTERRUPT_VIRQ -#pragma GCC poison CPU_INTERRUPT_NMI +#pragma GCC poison CPU_INTERRUPT_TGT_EXT_0 +#pragma GCC poison CPU_INTERRUPT_TGT_EXT_1 +#pragma GCC poison CPU_INTERRUPT_TGT_EXT_2 +#pragma GCC poison CPU_INTERRUPT_TGT_EXT_3 +#pragma GCC poison CPU_INTERRUPT_TGT_EXT_4 +#pragma GCC poison CPU_INTERRUPT_TGT_INT_0 +#pragma GCC poison CPU_INTERRUPT_TGT_INT_1 +#pragma GCC poison CPU_INTERRUPT_TGT_INT_2 #endif #endif diff --git a/posix-aio-compat.c b/posix-aio-compat.c index fa5494d..0c0035c 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include "block/raw-posix-aio.h" +static void do_spawn_thread(void); struct qemu_paiocb { BlockDriverAIOCB common; @@ -42,7 +42,6 @@ struct qemu_paiocb { int aio_niov; size_t aio_nbytes; #define aio_ioctl_cmd aio_nbytes /* for QEMU_AIO_IOCTL */ - int ev_signo; off_t aio_offset; QTAILQ_ENTRY(qemu_paiocb) node; @@ -50,8 +49,6 @@ struct qemu_paiocb { ssize_t ret; int active; struct qemu_paiocb *next; - - int async_context_id; }; typedef struct PosixAioState { @@ -67,6 +64,9 @@ static pthread_attr_t attr; static int max_threads = 64; static int cur_threads = 0; static int idle_threads = 0; +static int new_threads = 0; /* backlog of threads we need to create */ +static int pending_threads = 0; /* threads created but not running yet */ +static QEMUBH *new_thread_bh; static QTAILQ_HEAD(, qemu_paiocb) request_list; #ifdef CONFIG_PREADV @@ -180,7 +180,6 @@ qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset) static ssize_t handle_aiocb_rw_vector(struct qemu_paiocb *aiocb) { - size_t offset = 0; ssize_t len; do { @@ -188,12 +187,12 @@ static ssize_t handle_aiocb_rw_vector(struct qemu_paiocb *aiocb) len = qemu_pwritev(aiocb->aio_fildes, aiocb->aio_iov, aiocb->aio_niov, - aiocb->aio_offset + offset); + aiocb->aio_offset); else len = qemu_preadv(aiocb->aio_fildes, aiocb->aio_iov, aiocb->aio_niov, - aiocb->aio_offset + offset); + aiocb->aio_offset); } while (len == -1 && errno == EINTR); if (len == -1) @@ -201,6 +200,12 @@ static ssize_t handle_aiocb_rw_vector(struct qemu_paiocb *aiocb) return len; } +/* + * Read/writes the data to/from a given linear buffer. + * + * Returns the number of bytes handles or -errno in case of an error. Short + * reads are only returned if the end of the file is reached. + */ static ssize_t handle_aiocb_rw_linear(struct qemu_paiocb *aiocb, char *buf) { ssize_t offset = 0; @@ -302,11 +307,14 @@ static ssize_t handle_aiocb_rw(struct qemu_paiocb *aiocb) return nbytes; } +static void posix_aio_notify_event(void); + static void *aio_thread(void *unused) { - pid_t pid; - - pid = getpid(); + mutex_lock(&lock); + pending_threads--; + mutex_unlock(&lock); + do_spawn_thread(); while (1) { struct qemu_paiocb *aiocb; @@ -322,7 +330,9 @@ static void *aio_thread(void *unused) while (QTAILQ_EMPTY(&request_list) && !(ret == ETIMEDOUT)) { + idle_threads++; ret = cond_timedwait(&cond, &lock, &ts); + idle_threads--; } if (QTAILQ_EMPTY(&request_list)) @@ -331,11 +341,23 @@ static void *aio_thread(void *unused) aiocb = QTAILQ_FIRST(&request_list); QTAILQ_REMOVE(&request_list, aiocb, node); aiocb->active = 1; - idle_threads--; mutex_unlock(&lock); switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { case QEMU_AIO_READ: + ret = handle_aiocb_rw(aiocb); + if (ret >= 0 && ret < aiocb->aio_nbytes && aiocb->common.bs->growable) { + /* A short read means that we have reached EOF. Pad the buffer + * with zeros for bytes after EOF. */ + QEMUIOVector qiov; + + qemu_iovec_init_external(&qiov, aiocb->aio_iov, + aiocb->aio_niov); + qemu_iovec_memset_skip(&qiov, 0, aiocb->aio_nbytes - ret, ret); + + ret = aiocb->aio_nbytes; + } + break; case QEMU_AIO_WRITE: ret = handle_aiocb_rw(aiocb); break; @@ -353,25 +375,31 @@ static void *aio_thread(void *unused) mutex_lock(&lock); aiocb->ret = ret; - idle_threads++; mutex_unlock(&lock); - if (kill(pid, aiocb->ev_signo)) die("kill failed"); + posix_aio_notify_event(); } - idle_threads--; cur_threads--; mutex_unlock(&lock); return NULL; } -static void spawn_thread(void) +static void do_spawn_thread(void) { sigset_t set, oldset; - cur_threads++; - idle_threads++; + mutex_lock(&lock); + if (!new_threads) { + mutex_unlock(&lock); + return; + } + + new_threads--; + pending_threads++; + + mutex_unlock(&lock); /* block all signals */ if (sigfillset(&set)) die("sigfillset"); @@ -382,6 +410,27 @@ static void spawn_thread(void) if (sigprocmask(SIG_SETMASK, &oldset, NULL)) die("sigprocmask restore"); } +static void spawn_thread_bh_fn(void *opaque) +{ + do_spawn_thread(); +} + +static void spawn_thread(void) +{ + cur_threads++; + new_threads++; + /* If there are threads being created, they will spawn new workers, so + * we don't spend time creating many threads in a loop holding a mutex or + * starving the current vcpu. + * + * If there are no idle threads, ask the main thread to create one, so we + * inherit the correct affinity instead of the vcpu affinity. + */ + if (!pending_threads) { + qemu_bh_schedule(new_thread_bh); + } +} + static void qemu_paio_submit(struct qemu_paiocb *aiocb) { aiocb->ret = -EINPROGRESS; @@ -423,7 +472,6 @@ static int posix_aio_process_queue(void *opaque) struct qemu_paiocb *acb, **pacb; int ret; int result = 0; - int async_context_id = get_async_context_id(); for(;;) { pacb = &s->first_aio; @@ -432,12 +480,6 @@ static int posix_aio_process_queue(void *opaque) if (!acb) return result; - /* we're only interested in requests in the right context */ - if (acb->async_context_id != async_context_id) { - pacb = &acb->next; - continue; - } - ret = qemu_paio_error(acb); if (ret == ECANCELED) { /* remove the request */ @@ -455,6 +497,9 @@ static int posix_aio_process_queue(void *opaque) } else { ret = -ret; } + + trace_paio_complete(acb, acb->common.opaque, ret); + /* remove the request */ *pacb = acb->next; /* call the callback */ @@ -499,18 +544,14 @@ static int posix_aio_flush(void *opaque) static PosixAioState *posix_aio_state; -static void aio_signal_handler(int signum) +static void posix_aio_notify_event(void) { - if (posix_aio_state) { - char byte = 0; - ssize_t ret; - - ret = write(posix_aio_state->wfd, &byte, sizeof(byte)); - if (ret < 0 && errno != EAGAIN) - die("write()"); - } + char byte = 0; + ssize_t ret; - qemu_service_io(); + ret = write(posix_aio_state->wfd, &byte, sizeof(byte)); + if (ret < 0 && errno != EAGAIN) + die("write()"); } static void paio_remove(struct qemu_paiocb *acb) @@ -537,6 +578,8 @@ static void paio_cancel(BlockDriverAIOCB *blockacb) struct qemu_paiocb *acb = (struct qemu_paiocb *)blockacb; int active = 0; + trace_paio_cancel(acb, acb->common.opaque); + mutex_lock(&lock); if (!acb->active) { QTAILQ_REMOVE(&request_list, acb, node); @@ -572,8 +615,6 @@ BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd, return NULL; acb->aio_type = type; acb->aio_fildes = fd; - acb->ev_signo = SIGUSR2; - acb->async_context_id = get_async_context_id(); if (qiov) { acb->aio_iov = qiov->iov; @@ -601,8 +642,6 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd, return NULL; acb->aio_type = QEMU_AIO_IOCTL; acb->aio_fildes = fd; - acb->ev_signo = SIGUSR2; - acb->async_context_id = get_async_context_id(); acb->aio_offset = 0; acb->aio_ioctl_buf = buf; acb->aio_ioctl_cmd = req; @@ -616,7 +655,6 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd, int paio_init(void) { - struct sigaction act; PosixAioState *s; int fds[2]; int ret; @@ -624,16 +662,12 @@ int paio_init(void) if (posix_aio_state) return 0; - s = qemu_malloc(sizeof(PosixAioState)); - - sigfillset(&act.sa_mask); - act.sa_flags = 0; /* do not restart syscalls to interrupt select() */ - act.sa_handler = aio_signal_handler; - sigaction(SIGUSR2, &act, NULL); + s = g_malloc(sizeof(PosixAioState)); s->first_aio = NULL; if (qemu_pipe(fds) == -1) { fprintf(stderr, "failed to create pipe\n"); + g_free(s); return -1; } @@ -655,6 +689,7 @@ int paio_init(void) die2(ret, "pthread_attr_setdetachstate"); QTAILQ_INIT(&request_list); + new_thread_bh = qemu_bh_new(spawn_thread_bh_fn, NULL); posix_aio_state = s; return 0; diff --git a/ppc.ld b/ppc.ld index 5248ef1..2a0dcad 100644 --- a/ppc.ld +++ b/ppc.ld @@ -49,8 +49,20 @@ SECTIONS .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } + .rel.plt : + { + *(.rel.plt) + PROVIDE (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE (__rel_iplt_end = .); + } + .rela.plt : + { + *(.rela.plt) + PROVIDE (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE (__rela_iplt_end = .); + } .init : { KEEP (*(.init)) @@ -79,36 +91,34 @@ SECTIONS } .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. */ . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000); /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } /* Thread Local Storage sections */ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } .preinit_array : { - PROVIDE_HIDDEN (__preinit_array_start = .); + PROVIDE (__preinit_array_start = .); KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE (__preinit_array_end = .); } .init_array : { - PROVIDE_HIDDEN (__init_array_start = .); + PROVIDE (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE (__init_array_end = .); } .fini_array : { - PROVIDE_HIDDEN (__fini_array_start = .); + PROVIDE (__fini_array_start = .); KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE (__fini_array_end = .); } .ctors : { diff --git a/ppc64.ld b/ppc64.ld index dea0dbd..e2dafa0 100644 --- a/ppc64.ld +++ b/ppc64.ld @@ -54,8 +54,20 @@ SECTIONS *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } + .rel.plt : + { + *(.rel.plt) + PROVIDE (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE (__rel_iplt_end = .); + } + .rela.plt : + { + *(.rela.plt) + PROVIDE (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE (__rela_iplt_end = .); + } .rela.tocbss : { *(.rela.tocbss) } .init : { @@ -81,14 +93,12 @@ SECTIONS .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) -*(.gcc_except_table.*) } /* Adjust the address for the data segment. We want to -adjust up to + the same address within the page on the next page up. */ + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000); /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } /* Thread Local Storage sections */ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } diff --git a/qbool.c b/qbool.c index ad4873f..590cd71 100644 --- a/qbool.c +++ b/qbool.c @@ -31,7 +31,7 @@ QBool *qbool_from_int(int value) { QBool *qb; - qb = qemu_malloc(sizeof(*qb)); + qb = g_malloc(sizeof(*qb)); qb->value = value; QOBJECT_INIT(qb, &qbool_type); @@ -64,5 +64,5 @@ QBool *qobject_to_qbool(const QObject *obj) static void qbool_destroy_obj(QObject *obj) { assert(obj != NULL); - qemu_free(qobject_to_qbool(obj)); + g_free(qobject_to_qbool(obj)); } diff --git a/qdict.c b/qdict.c index dee0fb4..4bf308b 100644 --- a/qdict.c +++ b/qdict.c @@ -35,7 +35,7 @@ QDict *qdict_new(void) { QDict *qdict; - qdict = qemu_mallocz(sizeof(*qdict)); + qdict = g_malloc0(sizeof(*qdict)); QOBJECT_INIT(qdict, &qdict_type); return qdict; @@ -75,8 +75,8 @@ static QDictEntry *alloc_entry(const char *key, QObject *value) { QDictEntry *entry; - entry = qemu_mallocz(sizeof(*entry)); - entry->key = qemu_strdup(key); + entry = g_malloc0(sizeof(*entry)); + entry->key = g_strdup(key); entry->value = value; return entry; @@ -410,8 +410,8 @@ static void qentry_destroy(QDictEntry *e) assert(e->value != NULL); qobject_decref(e->value); - qemu_free(e->key); - qemu_free(e); + g_free(e->key); + g_free(e); } /** @@ -452,5 +452,5 @@ static void qdict_destroy_obj(QObject *obj) } } - qemu_free(qdict); + g_free(qdict); } diff --git a/qemu-barrier.h b/qemu-barrier.h index b77fce2..c11bb2b 100644 --- a/qemu-barrier.h +++ b/qemu-barrier.h @@ -1,10 +1,38 @@ #ifndef __QEMU_BARRIER_H #define __QEMU_BARRIER_H 1 -/* FIXME: arch dependant, x86 version */ -#define smp_wmb() asm volatile("" ::: "memory") - /* Compiler barrier */ #define barrier() asm volatile("" ::: "memory") +#if defined(__i386__) || defined(__x86_64__) + +/* + * Because of the strongly ordered x86 storage model, wmb() is a nop + * on x86(well, a compiler barrier only). Well, at least as long as + * qemu doesn't do accesses to write-combining memory or non-temporal + * load/stores from C code. + */ +#define smp_wmb() barrier() + +#elif defined(_ARCH_PPC) + +/* + * We use an eieio() for a wmb() on powerpc. This assumes we don't + * need to order cacheable and non-cacheable stores with respect to + * each other + */ +#define smp_wmb() asm volatile("eieio" ::: "memory") + +#else + +/* + * For (host) platforms we don't have explicit barrier definitions + * for, we use the gcc __sync_synchronize() primitive to generate a + * full barrier. This should be safe on all platforms, though it may + * be overkill. + */ +#define smp_wmb() __sync_synchronize() + +#endif + #endif diff --git a/qemu-char.c b/qemu-char.c index 795aec0..299fd59 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -31,11 +31,10 @@ #include "hw/usb.h" #include "hw/baum.h" #include "hw/msmouse.h" -#include "qemu-objects.h" +#include "qmp-commands.h" #include #include -#include #include #include #include @@ -107,7 +106,7 @@ static QTAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs = QTAILQ_HEAD_INITIALIZER(chardevs); -static void qemu_chr_event(CharDriverState *s, int event) +void qemu_chr_be_event(CharDriverState *s, int event) { /* Keep track if the char device is open */ switch (event) { @@ -127,7 +126,7 @@ static void qemu_chr_event(CharDriverState *s, int event) static void qemu_chr_generic_open_bh(void *opaque) { CharDriverState *s = opaque; - qemu_chr_event(s, CHR_EVENT_OPENED); + qemu_chr_be_event(s, CHR_EVENT_OPENED); qemu_bh_delete(s->bh); s->bh = NULL; } @@ -140,63 +139,66 @@ void qemu_chr_generic_open(CharDriverState *s) } } -int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len) +int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len) { return s->chr_write(s, buf, len); } -int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg) +int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg) { if (!s->chr_ioctl) return -ENOTSUP; return s->chr_ioctl(s, cmd, arg); } -int qemu_chr_can_read(CharDriverState *s) +int qemu_chr_be_can_write(CharDriverState *s) { if (!s->chr_can_read) return 0; return s->chr_can_read(s->handler_opaque); } -void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len) +void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len) { s->chr_read(s->handler_opaque, buf, len); } -int qemu_chr_get_msgfd(CharDriverState *s) +int qemu_chr_fe_get_msgfd(CharDriverState *s) { return s->get_msgfd ? s->get_msgfd(s) : -1; } +int qemu_chr_add_client(CharDriverState *s, int fd) +{ + return s->chr_add_client ? s->chr_add_client(s, fd) : -1; +} + void qemu_chr_accept_input(CharDriverState *s) { if (s->chr_accept_input) s->chr_accept_input(s); } -void qemu_chr_printf(CharDriverState *s, const char *fmt, ...) +void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) { char buf[READ_BUF_LEN]; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); - qemu_chr_write(s, (uint8_t *)buf, strlen(buf)); + qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf)); va_end(ap); } -void qemu_chr_send_event(CharDriverState *s, int event) -{ - if (s->chr_send_event) - s->chr_send_event(s, event); -} - void qemu_chr_add_handlers(CharDriverState *s, IOCanReadHandler *fd_can_read, IOReadHandler *fd_read, IOEventHandler *fd_event, void *opaque) { + if (!opaque && !fd_can_read && !fd_read && !fd_event) { + /* chr driver being released. */ + ++s->avail_connections; + } s->chr_can_read = fd_can_read; s->chr_read = fd_read; s->chr_event = fd_event; @@ -216,13 +218,15 @@ static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) return len; } -static CharDriverState *qemu_chr_open_null(QemuOpts *opts) +static int qemu_chr_open_null(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; - chr = qemu_mallocz(sizeof(CharDriverState)); + chr = g_malloc0(sizeof(CharDriverState)); chr->chr_write = null_chr_write; - return chr; + + *_chr= chr; + return 0; } /* MUX driver for serial I/O splitting */ @@ -267,7 +271,7 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len) int64_t ti; int secs; - ti = qemu_get_clock(rt_clock); + ti = qemu_get_clock_ms(rt_clock); if (d->timestamps_start == -1) d->timestamps_start = ti; ti -= d->timestamps_start; @@ -355,7 +359,7 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) bdrv_commit_all(); break; case 'b': - qemu_chr_event(chr, CHR_EVENT_BREAK); + qemu_chr_be_event(chr, CHR_EVENT_BREAK); break; case 'c': /* Switch to the next registered device */ @@ -467,8 +471,8 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) CharDriverState *chr; MuxDriver *d; - chr = qemu_mallocz(sizeof(CharDriverState)); - d = qemu_mallocz(sizeof(MuxDriver)); + chr = g_malloc0(sizeof(CharDriverState)); + d = g_malloc0(sizeof(MuxDriver)); chr->opaque = d; d->drv = drv; @@ -476,6 +480,9 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) chr->chr_write = mux_chr_write; chr->chr_update_read_handler = mux_chr_update_read_handler; chr->chr_accept_input = mux_chr_accept_input; + /* Frontend guest-open / -close notification is not support with muxes */ + chr->chr_guest_open = NULL; + chr->chr_guest_close = NULL; /* Muxes are always open on creation */ qemu_chr_generic_open(chr); @@ -531,6 +538,9 @@ int send_all(int fd, const void *_buf, int len1) } #endif /* !_WIN32 */ +#define STDIO_MAX_CLIENTS 1 +static int stdio_nb_clients; + #ifndef _WIN32 typedef struct { @@ -538,8 +548,6 @@ typedef struct { int max_size; } FDCharDriver; -#define STDIO_MAX_CLIENTS 1 -static int stdio_nb_clients = 0; static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { @@ -552,7 +560,7 @@ static int fd_chr_read_poll(void *opaque) CharDriverState *chr = opaque; FDCharDriver *s = chr->opaque; - s->max_size = qemu_chr_can_read(chr); + s->max_size = qemu_chr_be_can_write(chr); return s->max_size; } @@ -572,11 +580,11 @@ static void fd_chr_read(void *opaque) if (size == 0) { /* FD has been closed. Remove it from the active list. */ qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); return; } if (size > 0) { - qemu_chr_read(chr, buf, size); + qemu_chr_be_write(chr, buf, size); } } @@ -604,8 +612,8 @@ static void fd_chr_close(struct CharDriverState *chr) } } - qemu_free(s); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } /* open a character device to a unix fd */ @@ -614,8 +622,8 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) CharDriverState *chr; FDCharDriver *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(FDCharDriver)); + chr = g_malloc0(sizeof(CharDriverState)); + s = g_malloc0(sizeof(FDCharDriver)); s->fd_in = fd_in; s->fd_out = fd_out; chr->opaque = s; @@ -628,18 +636,21 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) return chr; } -static CharDriverState *qemu_chr_open_file_out(QemuOpts *opts) +static int qemu_chr_open_file_out(QemuOpts *opts, CharDriverState **_chr) { int fd_out; TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"), O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666)); - if (fd_out < 0) - return NULL; - return qemu_chr_open_fd(-1, fd_out); + if (fd_out < 0) { + return -errno; + } + + *_chr = qemu_chr_open_fd(-1, fd_out); + return 0; } -static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts) +static int qemu_chr_open_pipe(QemuOpts *opts, CharDriverState **_chr) { int fd_in, fd_out; char filename_in[256], filename_out[256]; @@ -647,7 +658,7 @@ static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts) if (filename == NULL) { fprintf(stderr, "chardev: pipe: no filename given\n"); - return NULL; + return -EINVAL; } snprintf(filename_in, 256, "%s.in", filename); @@ -659,11 +670,14 @@ static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts) close(fd_in); if (fd_out >= 0) close(fd_out); - TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY)); - if (fd_in < 0) - return NULL; + TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY)); + if (fd_in < 0) { + return -errno; + } } - return qemu_chr_open_fd(fd_in, fd_out); + + *_chr = qemu_chr_open_fd(fd_in, fd_out); + return 0; } @@ -680,8 +694,8 @@ static int stdio_read_poll(void *opaque) CharDriverState *chr = opaque; /* try to flush the queue if needed */ - if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) { - qemu_chr_read(chr, term_fifo, 1); + if (term_fifo_size != 0 && qemu_chr_be_can_write(chr) > 0) { + qemu_chr_be_write(chr, term_fifo, 1); term_fifo_size = 0; } /* see if we can absorb more chars */ @@ -701,12 +715,12 @@ static void stdio_read(void *opaque) if (size == 0) { /* stdin has been closed. Remove it from the active list. */ qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); return; } if (size > 0) { - if (qemu_chr_can_read(chr) > 0) { - qemu_chr_read(chr, buf, 1); + if (qemu_chr_be_can_write(chr) > 0) { + qemu_chr_be_write(chr, buf, 1); } else if (term_fifo_size == 0) { term_fifo[term_fifo_size++] = buf[0]; } @@ -754,12 +768,14 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr) fd_chr_close(chr); } -static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts) +static int qemu_chr_open_stdio(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; - if (stdio_nb_clients >= STDIO_MAX_CLIENTS) - return NULL; + if (stdio_nb_clients >= STDIO_MAX_CLIENTS) { + return -EBUSY; + } + if (stdio_nb_clients == 0) { old_fd0_flags = fcntl(0, F_GETFL); tcgetattr (0, &oldtty); @@ -774,9 +790,10 @@ static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts) stdio_nb_clients++; stdio_allow_signal = qemu_opt_get_bool(opts, "signal", display_type != DT_NOGRAPHIC); - qemu_chr_set_echo(chr, false); + qemu_chr_fe_set_echo(chr, false); - return chr; + *_chr = chr; + return 0; } #ifdef __sun__ @@ -868,7 +885,7 @@ static int pty_chr_read_poll(void *opaque) CharDriverState *chr = opaque; PtyCharDriver *s = chr->opaque; - s->read_bytes = qemu_chr_can_read(chr); + s->read_bytes = qemu_chr_be_can_write(chr); return s->read_bytes; } @@ -892,7 +909,7 @@ static void pty_chr_read(void *opaque) } if (size > 0) { pty_chr_state(chr, 1); - qemu_chr_read(chr, buf, size); + qemu_chr_be_write(chr, buf, size); } } @@ -911,7 +928,7 @@ static void pty_chr_update_read_handler(CharDriverState *chr) * timeout to the normal (much longer) poll interval before the * timer triggers. */ - qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10); + qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 10); } static void pty_chr_state(CharDriverState *chr, int connected) @@ -925,7 +942,7 @@ static void pty_chr_state(CharDriverState *chr, int connected) /* (re-)connect poll interval for idle guests: once per second. * We check more frequently in case the guests sends data to * the virtual device linked to our pty. */ - qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000); + qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 1000); } else { if (!s->connected) qemu_chr_generic_open(chr); @@ -959,16 +976,16 @@ static void pty_chr_close(struct CharDriverState *chr) close(s->fd); qemu_del_timer(s->timer); qemu_free_timer(s->timer); - qemu_free(s); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -static CharDriverState *qemu_chr_open_pty(QemuOpts *opts) +static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; PtyCharDriver *s; struct termios tty; - int slave_fd, len; + int master_fd, slave_fd, len; #if defined(__OpenBSD__) || defined(__DragonFly__) char pty_name[PATH_MAX]; #define q_ptsname(x) pty_name @@ -977,11 +994,8 @@ static CharDriverState *qemu_chr_open_pty(QemuOpts *opts) #define q_ptsname(x) ptsname(x) #endif - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(PtyCharDriver)); - - if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) { - return NULL; + if (openpty(&master_fd, &slave_fd, pty_name, NULL, NULL) < 0) { + return -errno; } /* Set raw attributes on the pty. */ @@ -990,20 +1004,25 @@ static CharDriverState *qemu_chr_open_pty(QemuOpts *opts) tcsetattr(slave_fd, TCSAFLUSH, &tty); close(slave_fd); - len = strlen(q_ptsname(s->fd)) + 5; - chr->filename = qemu_malloc(len); - snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd)); - qemu_opt_set(opts, "path", q_ptsname(s->fd)); - fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd)); + chr = g_malloc0(sizeof(CharDriverState)); + len = strlen(q_ptsname(master_fd)) + 5; + chr->filename = g_malloc(len); + snprintf(chr->filename, len, "pty:%s", q_ptsname(master_fd)); + qemu_opt_set(opts, "path", q_ptsname(master_fd)); + fprintf(stderr, "char device redirected to %s\n", q_ptsname(master_fd)); + + s = g_malloc0(sizeof(PtyCharDriver)); chr->opaque = s; chr->chr_write = pty_chr_write; chr->chr_update_read_handler = pty_chr_update_read_handler; chr->chr_close = pty_chr_close; - s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr); + s->fd = master_fd; + s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr); - return chr; + *_chr = chr; + return 0; } static void tty_serial_init(int fd, int speed, @@ -1204,30 +1223,28 @@ static void qemu_chr_close_tty(CharDriverState *chr) } } -static CharDriverState *qemu_chr_open_tty(QemuOpts *opts) +static int qemu_chr_open_tty(QemuOpts *opts, CharDriverState **_chr) { const char *filename = qemu_opt_get(opts, "path"); CharDriverState *chr; int fd; - TFR(fd = open(filename, O_RDWR | O_NONBLOCK)); + TFR(fd = qemu_open(filename, O_RDWR | O_NONBLOCK)); if (fd < 0) { - return NULL; + return -errno; } tty_serial_init(fd, 115200, 'N', 8, 1); chr = qemu_chr_open_fd(fd, fd); - if (!chr) { - close(fd); - return NULL; - } chr->chr_ioctl = tty_serial_ioctl; chr->chr_close = qemu_chr_close_tty; - return chr; + + *_chr = chr; + return 0; } #else /* ! __linux__ && ! __sun__ */ -static CharDriverState *qemu_chr_open_pty(QemuOpts *opts) +static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr) { - return NULL; + return -ENOTSUP; } #endif /* __linux__ || __sun__ */ @@ -1337,11 +1354,11 @@ static void pp_close(CharDriverState *chr) pp_hw_mode(drv, IEEE1284_MODE_COMPAT); ioctl(fd, PPRELEASE); close(fd); - qemu_free(drv); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + g_free(drv); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -static CharDriverState *qemu_chr_open_pp(QemuOpts *opts) +static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr) { const char *filename = qemu_opt_get(opts, "path"); CharDriverState *chr; @@ -1349,19 +1366,20 @@ static CharDriverState *qemu_chr_open_pp(QemuOpts *opts) int fd; TFR(fd = open(filename, O_RDWR)); - if (fd < 0) - return NULL; + if (fd < 0) { + return -errno; + } if (ioctl(fd, PPCLAIM) < 0) { close(fd); - return NULL; + return -errno; } - drv = qemu_mallocz(sizeof(ParallelCharDriver)); + drv = g_malloc0(sizeof(ParallelCharDriver)); drv->fd = fd; drv->mode = IEEE1284_MODE_COMPAT; - chr = qemu_mallocz(sizeof(CharDriverState)); + chr = g_malloc0(sizeof(CharDriverState)); chr->chr_write = null_chr_write; chr->chr_ioctl = pp_ioctl; chr->chr_close = pp_close; @@ -1369,14 +1387,15 @@ static CharDriverState *qemu_chr_open_pp(QemuOpts *opts) qemu_chr_generic_open(chr); - return chr; + *_chr = chr; + return 0; } #endif /* __linux__ */ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) { - int fd = (int)(long)chr->opaque; + int fd = (int)(intptr_t)chr->opaque; uint8_t b; switch(cmd) { @@ -1411,26 +1430,31 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) return 0; } -static CharDriverState *qemu_chr_open_pp(QemuOpts *opts) +static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr) { const char *filename = qemu_opt_get(opts, "path"); CharDriverState *chr; int fd; - fd = open(filename, O_RDWR); - if (fd < 0) - return NULL; + fd = qemu_open(filename, O_RDWR); + if (fd < 0) { + return -errno; + } - chr = qemu_mallocz(sizeof(CharDriverState)); - chr->opaque = (void *)(long)fd; + chr = g_malloc0(sizeof(CharDriverState)); + chr->opaque = (void *)(intptr_t)fd; chr->chr_write = null_chr_write; chr->chr_ioctl = pp_ioctl; - return chr; + + *_chr = chr; + return 0; } #endif #else /* _WIN32 */ +static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS]; + typedef struct { int max_size; HANDLE hcom, hrecv, hsend; @@ -1439,6 +1463,14 @@ typedef struct { DWORD len; } WinCharState; +typedef struct { + HANDLE hStdIn; + HANDLE hInputReadyEvent; + HANDLE hInputDoneEvent; + HANDLE hInputThread; + uint8_t win_stdio_buf; +} WinStdioCharState; + #define NSENDBUF 2048 #define NRECVBUF 2048 #define MAXCONNECT 1 @@ -1468,7 +1500,7 @@ static void win_chr_close(CharDriverState *chr) else qemu_del_polling_cb(win_chr_poll, chr); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } static int win_chr_init(CharDriverState *chr, const char *filename) @@ -1490,9 +1522,22 @@ static int win_chr_init(CharDriverState *chr, const char *filename) fprintf(stderr, "Failed CreateEvent\n"); goto fail; } - - s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, +#ifndef CONFIG_MARU + s->hcom = CreateFile(filename, + GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); +#else + int open_flags = O_BINARY | O_RDWR; + // TODO : FILE_FLAG_OVERLAPPED + + int ret = qemu_open(filename, open_flags, 0644); + if (ret < 0) { + error_report("win_chr_init failed(%d) \n", ret); + return -errno; + } + s->hcom = (HANDLE)_get_osfhandle(ret); + +#endif if (s->hcom == INVALID_HANDLE_VALUE) { fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError()); s->hcom = NULL; @@ -1576,7 +1621,7 @@ static int win_chr_read_poll(CharDriverState *chr) { WinCharState *s = chr->opaque; - s->max_size = qemu_chr_can_read(chr); + s->max_size = qemu_chr_be_can_write(chr); return s->max_size; } @@ -1598,7 +1643,7 @@ static void win_chr_readfile(CharDriverState *chr) } if (size > 0) { - qemu_chr_read(chr, buf, size); + qemu_chr_be_write(chr, buf, size); } } @@ -1631,25 +1676,27 @@ static int win_chr_poll(void *opaque) return 0; } -static CharDriverState *qemu_chr_open_win(QemuOpts *opts) +static int qemu_chr_open_win(QemuOpts *opts, CharDriverState **_chr) { const char *filename = qemu_opt_get(opts, "path"); CharDriverState *chr; WinCharState *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(WinCharState)); + chr = g_malloc0(sizeof(CharDriverState)); + s = g_malloc0(sizeof(WinCharState)); chr->opaque = s; chr->chr_write = win_chr_write; chr->chr_close = win_chr_close; if (win_chr_init(chr, filename) < 0) { - free(s); - free(chr); - return NULL; + g_free(s); + g_free(chr); + return -EIO; } qemu_chr_generic_open(chr); - return chr; + + *_chr = chr; + return 0; } static int win_chr_pipe_poll(void *opaque) @@ -1731,57 +1778,285 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename) } -static CharDriverState *qemu_chr_open_win_pipe(QemuOpts *opts) +static int qemu_chr_open_win_pipe(QemuOpts *opts, CharDriverState **_chr) { const char *filename = qemu_opt_get(opts, "path"); CharDriverState *chr; WinCharState *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(WinCharState)); + chr = g_malloc0(sizeof(CharDriverState)); + s = g_malloc0(sizeof(WinCharState)); chr->opaque = s; chr->chr_write = win_chr_write; chr->chr_close = win_chr_close; if (win_chr_pipe_init(chr, filename) < 0) { - free(s); - free(chr); - return NULL; + g_free(s); + g_free(chr); + return -EIO; } qemu_chr_generic_open(chr); - return chr; + + *_chr = chr; + return 0; } -static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) +static int qemu_chr_open_win_file(HANDLE fd_out, CharDriverState **pchr) { CharDriverState *chr; WinCharState *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(WinCharState)); + chr = g_malloc0(sizeof(CharDriverState)); + s = g_malloc0(sizeof(WinCharState)); s->hcom = fd_out; chr->opaque = s; chr->chr_write = win_chr_write; qemu_chr_generic_open(chr); - return chr; + *pchr = chr; + return 0; } -static CharDriverState *qemu_chr_open_win_con(QemuOpts *opts) +static int qemu_chr_open_win_con(QemuOpts *opts, CharDriverState **chr) { - return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE)); + return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), chr); } -static CharDriverState *qemu_chr_open_win_file_out(QemuOpts *opts) +static int qemu_chr_open_win_file_out(QemuOpts *opts, CharDriverState **_chr) { const char *file_out = qemu_opt_get(opts, "path"); HANDLE fd_out; +#ifndef CONFIG_MARU fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (fd_out == INVALID_HANDLE_VALUE) - return NULL; + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +#else + int open_flags = O_BINARY | O_RDWR | O_CREAT | O_TRUNC; + + int ret = qemu_open(file_out, open_flags, 0644); + if (ret < 0) { + error_report("qemu_chr_open_win_file_out failed(%d) \n", ret); + return -errno; + } + fd_out = (HANDLE)_get_osfhandle(ret); + +#endif + + if (fd_out == INVALID_HANDLE_VALUE) { + return -EIO; + } + + return qemu_chr_open_win_file(fd_out, _chr); +} + +static int win_stdio_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwSize; + int len1; + + len1 = len; + + while (len1 > 0) { + if (!WriteFile(hStdOut, buf, len1, &dwSize, NULL)) { + break; + } + buf += dwSize; + len1 -= dwSize; + } + + return len - len1; +} + +static void win_stdio_wait_func(void *opaque) +{ + CharDriverState *chr = opaque; + WinStdioCharState *stdio = chr->opaque; + INPUT_RECORD buf[4]; + int ret; + DWORD dwSize; + int i; + + ret = ReadConsoleInput(stdio->hStdIn, buf, sizeof(buf) / sizeof(*buf), + &dwSize); + + if (!ret) { + /* Avoid error storm */ + qemu_del_wait_object(stdio->hStdIn, NULL, NULL); + return; + } + + for (i = 0; i < dwSize; i++) { + KEY_EVENT_RECORD *kev = &buf[i].Event.KeyEvent; + + if (buf[i].EventType == KEY_EVENT && kev->bKeyDown) { + int j; + if (kev->uChar.AsciiChar != 0) { + for (j = 0; j < kev->wRepeatCount; j++) { + if (qemu_chr_be_can_write(chr)) { + uint8_t c = kev->uChar.AsciiChar; + qemu_chr_be_write(chr, &c, 1); + } + } + } + } + } +} + +static DWORD WINAPI win_stdio_thread(LPVOID param) +{ + CharDriverState *chr = param; + WinStdioCharState *stdio = chr->opaque; + int ret; + DWORD dwSize; + + while (1) { + + /* Wait for one byte */ + ret = ReadFile(stdio->hStdIn, &stdio->win_stdio_buf, 1, &dwSize, NULL); + + /* Exit in case of error, continue if nothing read */ + if (!ret) { + break; + } + if (!dwSize) { + continue; + } + + /* Some terminal emulator returns \r\n for Enter, just pass \n */ + if (stdio->win_stdio_buf == '\r') { + continue; + } + + /* Signal the main thread and wait until the byte was eaten */ + if (!SetEvent(stdio->hInputReadyEvent)) { + break; + } + if (WaitForSingleObject(stdio->hInputDoneEvent, INFINITE) + != WAIT_OBJECT_0) { + break; + } + } + + qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); + return 0; +} + +static void win_stdio_thread_wait_func(void *opaque) +{ + CharDriverState *chr = opaque; + WinStdioCharState *stdio = chr->opaque; + + if (qemu_chr_be_can_write(chr)) { + qemu_chr_be_write(chr, &stdio->win_stdio_buf, 1); + } + + SetEvent(stdio->hInputDoneEvent); +} + +static void qemu_chr_set_echo_win_stdio(CharDriverState *chr, bool echo) +{ + WinStdioCharState *stdio = chr->opaque; + DWORD dwMode = 0; + + GetConsoleMode(stdio->hStdIn, &dwMode); + + if (echo) { + SetConsoleMode(stdio->hStdIn, dwMode | ENABLE_ECHO_INPUT); + } else { + SetConsoleMode(stdio->hStdIn, dwMode & ~ENABLE_ECHO_INPUT); + } +} + +static void win_stdio_close(CharDriverState *chr) +{ + WinStdioCharState *stdio = chr->opaque; - return qemu_chr_open_win_file(fd_out); + if (stdio->hInputReadyEvent != INVALID_HANDLE_VALUE) { + CloseHandle(stdio->hInputReadyEvent); + } + if (stdio->hInputDoneEvent != INVALID_HANDLE_VALUE) { + CloseHandle(stdio->hInputDoneEvent); + } + if (stdio->hInputThread != INVALID_HANDLE_VALUE) { + TerminateThread(stdio->hInputThread, 0); + } + + g_free(chr->opaque); + g_free(chr); + stdio_nb_clients--; +} + +static int qemu_chr_open_win_stdio(QemuOpts *opts, CharDriverState **_chr) +{ + CharDriverState *chr; + WinStdioCharState *stdio; + DWORD dwMode; + int is_console = 0; + + if (stdio_nb_clients >= STDIO_MAX_CLIENTS + || ((display_type != DT_NOGRAPHIC) && (stdio_nb_clients != 0))) { + return -EIO; + } + + chr = g_malloc0(sizeof(CharDriverState)); + stdio = g_malloc0(sizeof(WinStdioCharState)); + + stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); + if (stdio->hStdIn == INVALID_HANDLE_VALUE) { + fprintf(stderr, "cannot open stdio: invalid handle\n"); + exit(1); + } + + is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; + + chr->opaque = stdio; + chr->chr_write = win_stdio_write; + chr->chr_close = win_stdio_close; + + if (stdio_nb_clients == 0) { + if (is_console) { + if (qemu_add_wait_object(stdio->hStdIn, + win_stdio_wait_func, chr)) { + fprintf(stderr, "qemu_add_wait_object: failed\n"); + } + } else { + DWORD dwId; + + stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, + chr, 0, &dwId); + + if (stdio->hInputThread == INVALID_HANDLE_VALUE + || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE + || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) { + fprintf(stderr, "cannot create stdio thread or event\n"); + exit(1); + } + if (qemu_add_wait_object(stdio->hInputReadyEvent, + win_stdio_thread_wait_func, chr)) { + fprintf(stderr, "qemu_add_wait_object: failed\n"); + } + } + } + + dwMode |= ENABLE_LINE_INPUT; + + stdio_clients[stdio_nb_clients++] = chr; + if (stdio_nb_clients == 1 && is_console) { + /* set the terminal in raw mode */ + /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */ + dwMode |= ENABLE_PROCESSED_INPUT; + } + + SetConsoleMode(stdio->hStdIn, dwMode); + + chr->chr_set_echo = qemu_chr_set_echo_win_stdio; + qemu_chr_fe_set_echo(chr, false); + + *_chr = chr; + + return 0; } #endif /* !_WIN32 */ @@ -1808,15 +2083,15 @@ static int udp_chr_read_poll(void *opaque) CharDriverState *chr = opaque; NetCharDriver *s = chr->opaque; - s->max_size = qemu_chr_can_read(chr); + s->max_size = qemu_chr_be_can_write(chr); /* If there were any stray characters in the queue process them * first */ while (s->max_size > 0 && s->bufptr < s->bufcnt) { - qemu_chr_read(chr, &s->buf[s->bufptr], 1); + qemu_chr_be_write(chr, &s->buf[s->bufptr], 1); s->bufptr++; - s->max_size = qemu_chr_can_read(chr); + s->max_size = qemu_chr_be_can_write(chr); } return s->max_size; } @@ -1828,16 +2103,16 @@ static void udp_chr_read(void *opaque) if (s->max_size == 0) return; - s->bufcnt = recv(s->fd, (void *)s->buf, sizeof(s->buf), 0); + s->bufcnt = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0); s->bufptr = s->bufcnt; if (s->bufcnt <= 0) return; s->bufptr = 0; while (s->max_size > 0 && s->bufptr < s->bufcnt) { - qemu_chr_read(chr, &s->buf[s->bufptr], 1); + qemu_chr_be_write(chr, &s->buf[s->bufptr], 1); s->bufptr++; - s->max_size = qemu_chr_can_read(chr); + s->max_size = qemu_chr_be_can_write(chr); } } @@ -1855,25 +2130,27 @@ static void udp_chr_close(CharDriverState *chr) { NetCharDriver *s = chr->opaque; if (s->fd >= 0) { - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); closesocket(s->fd); } - qemu_free(s); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -static CharDriverState *qemu_chr_open_udp(QemuOpts *opts) +static int qemu_chr_open_udp(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr = NULL; NetCharDriver *s = NULL; int fd = -1; + int ret; - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(NetCharDriver)); + chr = g_malloc0(sizeof(CharDriverState)); + s = g_malloc0(sizeof(NetCharDriver)); fd = inet_dgram_opts(opts); if (fd < 0) { fprintf(stderr, "inet_dgram_opts failed\n"); + ret = -errno; goto return_err; } @@ -1884,16 +2161,17 @@ static CharDriverState *qemu_chr_open_udp(QemuOpts *opts) chr->chr_write = udp_chr_write; chr->chr_update_read_handler = udp_chr_update_read_handler; chr->chr_close = udp_chr_close; - return chr; + + *_chr = chr; + return 0; return_err: - if (chr) - free(chr); - if (s) - free(s); - if (fd >= 0) + g_free(chr); + g_free(s); + if (fd >= 0) { closesocket(fd); - return NULL; + } + return ret; } /***********************************************************/ @@ -1928,7 +2206,7 @@ static int tcp_chr_read_poll(void *opaque) TCPCharDriver *s = chr->opaque; if (!s->connected) return 0; - s->max_size = qemu_chr_can_read(chr); + s->max_size = qemu_chr_be_can_write(chr); return s->max_size; } @@ -1961,7 +2239,7 @@ static void tcp_chr_process_IAC_bytes(CharDriverState *chr, } else { if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) { /* Handle IAC break commands by sending a serial break */ - qemu_chr_event(chr, CHR_EVENT_BREAK); + qemu_chr_be_event(chr, CHR_EVENT_BREAK); s->do_telnetopt++; } s->do_telnetopt++; @@ -2043,7 +2321,7 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) { TCPCharDriver *s = chr->opaque; - return recv(s->fd, buf, len, 0); + return qemu_recv(s->fd, buf, len, 0); } #endif @@ -2064,17 +2342,17 @@ static void tcp_chr_read(void *opaque) /* connection closed */ s->connected = 0; if (s->listen_fd >= 0) { - qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr); + qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); } - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); closesocket(s->fd); s->fd = -1; - qemu_chr_event(chr, CHR_EVENT_CLOSED); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } else if (size > 0) { if (s->do_telnetopt) tcp_chr_process_IAC_bytes(chr, s, buf, &size); if (size > 0) - qemu_chr_read(chr, buf, size); + qemu_chr_be_write(chr, buf, size); } } @@ -2117,6 +2395,22 @@ static void socket_set_nodelay(int fd) setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); } +static int tcp_chr_add_client(CharDriverState *chr, int fd) +{ + TCPCharDriver *s = chr->opaque; + if (s->fd != -1) + return -1; + + socket_set_nonblock(fd); + if (s->do_nodelay) + socket_set_nodelay(fd); + s->fd = fd; + qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL); + tcp_chr_connect(chr); + + return 0; +} + static void tcp_chr_accept(void *opaque) { CharDriverState *chr = opaque; @@ -2149,30 +2443,26 @@ static void tcp_chr_accept(void *opaque) break; } } - socket_set_nonblock(fd); - if (s->do_nodelay) - socket_set_nodelay(fd); - s->fd = fd; - qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); - tcp_chr_connect(chr); + if (tcp_chr_add_client(chr, fd) < 0) + close(fd); } static void tcp_chr_close(CharDriverState *chr) { TCPCharDriver *s = chr->opaque; if (s->fd >= 0) { - qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); closesocket(s->fd); } if (s->listen_fd >= 0) { - qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); + qemu_set_fd_handler2(s->listen_fd, NULL, NULL, NULL, NULL); closesocket(s->listen_fd); } - qemu_free(s); - qemu_chr_event(chr, CHR_EVENT_CLOSED); + g_free(s); + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) +static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr = NULL; TCPCharDriver *s = NULL; @@ -2182,6 +2472,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) int do_nodelay; int is_unix; int is_telnet; + int ret; is_listen = qemu_opt_get_bool(opts, "server", 0); is_waitconnect = qemu_opt_get_bool(opts, "wait", 1); @@ -2191,8 +2482,8 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) if (!is_listen) is_waitconnect = 0; - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(TCPCharDriver)); + chr = g_malloc0(sizeof(CharDriverState)); + s = g_malloc0(sizeof(TCPCharDriver)); if (is_unix) { if (is_listen) { @@ -2207,8 +2498,10 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) fd = inet_connect_opts(opts); } } - if (fd < 0) + if (fd < 0) { + ret = -errno; goto fail; + } if (!is_waitconnect) socket_set_nonblock(fd); @@ -2224,10 +2517,11 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) chr->chr_write = tcp_chr_write; chr->chr_close = tcp_chr_close; chr->get_msgfd = tcp_get_msgfd; + chr->chr_add_client = tcp_chr_add_client; if (is_listen) { s->listen_fd = fd; - qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr); + qemu_set_fd_handler2(s->listen_fd, NULL, tcp_chr_accept, NULL, chr); if (is_telnet) s->do_telnetopt = 1; @@ -2239,7 +2533,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) } /* for "info chardev" monitor command */ - chr->filename = qemu_malloc(256); + chr->filename = g_malloc(256); if (is_unix) { snprintf(chr->filename, 256, "unix:%s%s", qemu_opt_get(opts, "path"), @@ -2260,14 +2554,16 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) tcp_chr_accept(chr); socket_set_nonblock(s->listen_fd); } - return chr; + + *_chr = chr; + return 0; fail: if (fd >= 0) closesocket(fd); - qemu_free(s); - qemu_free(chr); - return NULL; + g_free(s); + g_free(chr); + return ret; } /***********************************************************/ @@ -2288,7 +2584,7 @@ static int mem_chr_write(CharDriverState *chr, const uint8_t *buf, int len) /* grow outbuf */ d->outbuf_capacity += len; d->outbuf_capacity *= 2; - d->outbuf = qemu_realloc(d->outbuf, d->outbuf_capacity); + d->outbuf = g_realloc(d->outbuf, d->outbuf_capacity); } memcpy(d->outbuf + d->outbuf_size, buf, len); @@ -2301,10 +2597,10 @@ void qemu_chr_init_mem(CharDriverState *chr) { MemoryDriver *d; - d = qemu_malloc(sizeof(*d)); + d = g_malloc(sizeof(*d)); d->outbuf_size = 0; d->outbuf_capacity = 4096; - d->outbuf = qemu_mallocz(d->outbuf_capacity); + d->outbuf = g_malloc0(d->outbuf_capacity); memset(chr, 0, sizeof(*chr)); chr->opaque = d; @@ -2317,13 +2613,13 @@ QString *qemu_chr_mem_to_qs(CharDriverState *chr) return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1); } -/* NOTE: this driver can not be closed with qemu_chr_close()! */ +/* NOTE: this driver can not be closed with qemu_chr_delete()! */ void qemu_chr_close_mem(CharDriverState *chr) { MemoryDriver *d = chr->opaque; - qemu_free(d->outbuf); - qemu_free(chr->opaque); + g_free(d->outbuf); + g_free(chr->opaque); chr->opaque = NULL; chr->chr_write = NULL; } @@ -2460,7 +2756,7 @@ fail: static const struct { const char *name; - CharDriverState *(*open)(QemuOpts *opts); + int (*open)(QemuOpts *opts, CharDriverState **chr); } backend_table[] = { { .name = "null", .open = qemu_chr_open_null }, { .name = "socket", .open = qemu_chr_open_socket }, @@ -2472,6 +2768,7 @@ static const struct { { .name = "pipe", .open = qemu_chr_open_win_pipe }, { .name = "console", .open = qemu_chr_open_win_con }, { .name = "serial", .open = qemu_chr_open_win }, + { .name = "stdio", .open = qemu_chr_open_win_stdio }, #else { .name = "file", .open = qemu_chr_open_file_out }, { .name = "pipe", .open = qemu_chr_open_pipe }, @@ -2495,11 +2792,12 @@ static const struct { #endif }; -CharDriverState *qemu_chr_open_opts(QemuOpts *opts, +CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, void (*init)(struct CharDriverState *s)) { CharDriverState *chr; int i; + int ret; if (qemu_opts_id(opts) == NULL) { fprintf(stderr, "chardev: no id specified\n"); @@ -2521,32 +2819,35 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts, return NULL; } - chr = backend_table[i].open(opts); - if (!chr) { - fprintf(stderr, "chardev: opening backend \"%s\" failed\n", - qemu_opt_get(opts, "backend")); + ret = backend_table[i].open(opts, &chr); + if (ret < 0) { + fprintf(stderr, "chardev: opening backend \"%s\" failed: %s\n", + qemu_opt_get(opts, "backend"), strerror(-ret)); return NULL; } if (!chr->filename) - chr->filename = qemu_strdup(qemu_opt_get(opts, "backend")); + chr->filename = g_strdup(qemu_opt_get(opts, "backend")); chr->init = init; QTAILQ_INSERT_TAIL(&chardevs, chr, next); if (qemu_opt_get_bool(opts, "mux", 0)) { CharDriverState *base = chr; int len = strlen(qemu_opts_id(opts)) + 6; - base->label = qemu_malloc(len); + base->label = g_malloc(len); snprintf(base->label, len, "%s-base", qemu_opts_id(opts)); chr = qemu_chr_open_mux(base); chr->filename = base->filename; + chr->avail_connections = MAX_MUX; QTAILQ_INSERT_TAIL(&chardevs, chr, next); + } else { + chr->avail_connections = 1; } - chr->label = qemu_strdup(qemu_opts_id(opts)); + chr->label = g_strdup(qemu_opts_id(opts)); return chr; } -CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) +CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s)) { const char *p; CharDriverState *chr; @@ -2560,7 +2861,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i if (!opts) return NULL; - chr = qemu_chr_open_opts(opts, init); + chr = qemu_chr_new_from_opts(opts, init); if (chr && qemu_opt_get_bool(opts, "mux", 0)) { monitor_init(chr, MONITOR_USE_READLINE); } @@ -2568,52 +2869,53 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i return chr; } -void qemu_chr_set_echo(struct CharDriverState *chr, bool echo) +void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo) { if (chr->chr_set_echo) { chr->chr_set_echo(chr, echo); } } -void qemu_chr_close(CharDriverState *chr) +void qemu_chr_fe_open(struct CharDriverState *chr) { - QTAILQ_REMOVE(&chardevs, chr, next); - if (chr->chr_close) - chr->chr_close(chr); - qemu_free(chr->filename); - qemu_free(chr->label); - qemu_free(chr); + if (chr->chr_guest_open) { + chr->chr_guest_open(chr); + } } -static void qemu_chr_qlist_iter(QObject *obj, void *opaque) +void qemu_chr_fe_close(struct CharDriverState *chr) { - QDict *chr_dict; - Monitor *mon = opaque; - - chr_dict = qobject_to_qdict(obj); - monitor_printf(mon, "%s: filename=%s\n", qdict_get_str(chr_dict, "label"), - qdict_get_str(chr_dict, "filename")); + if (chr->chr_guest_close) { + chr->chr_guest_close(chr); + } } -void qemu_chr_info_print(Monitor *mon, const QObject *ret_data) +void qemu_chr_delete(CharDriverState *chr) { - qlist_iter(qobject_to_qlist(ret_data), qemu_chr_qlist_iter, mon); + QTAILQ_REMOVE(&chardevs, chr, next); + if (chr->chr_close) + chr->chr_close(chr); + g_free(chr->filename); + g_free(chr->label); + g_free(chr); } -void qemu_chr_info(Monitor *mon, QObject **ret_data) +ChardevInfoList *qmp_query_chardev(Error **errp) { - QList *chr_list; + ChardevInfoList *chr_list = NULL; CharDriverState *chr; - chr_list = qlist_new(); - QTAILQ_FOREACH(chr, &chardevs, next) { - QObject *obj = qobject_from_jsonf("{ 'label': %s, 'filename': %s }", - chr->label, chr->filename); - qlist_append_obj(chr_list, obj); + ChardevInfoList *info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->label = g_strdup(chr->label); + info->value->filename = g_strdup(chr->filename); + + info->next = chr_list; + chr_list = info; } - *ret_data = QOBJECT(chr_list); + return chr_list; } CharDriverState *qemu_chr_find(const char *name) diff --git a/qemu-char.h b/qemu-char.h index 56d9954..8ca1e2d 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -7,6 +7,7 @@ #include "qemu-config.h" #include "qobject.h" #include "qstring.h" +#include "main-loop.h" /* character device */ @@ -57,47 +58,185 @@ struct CharDriverState { void (*chr_update_read_handler)(struct CharDriverState *s); int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg); int (*get_msgfd)(struct CharDriverState *s); + int (*chr_add_client)(struct CharDriverState *chr, int fd); IOEventHandler *chr_event; IOCanReadHandler *chr_can_read; IOReadHandler *chr_read; void *handler_opaque; - void (*chr_send_event)(struct CharDriverState *chr, int event); void (*chr_close)(struct CharDriverState *chr); void (*chr_accept_input)(struct CharDriverState *chr); void (*chr_set_echo)(struct CharDriverState *chr, bool echo); + void (*chr_guest_open)(struct CharDriverState *chr); + void (*chr_guest_close)(struct CharDriverState *chr); void *opaque; QEMUBH *bh; char *label; char *filename; int opened; + int avail_connections; QTAILQ_ENTRY(CharDriverState) next; }; -QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); -CharDriverState *qemu_chr_open_opts(QemuOpts *opts, +/** + * @qemu_chr_new_from_opts: + * + * Create a new character backend from a QemuOpts list. + * + * @opts see qemu-config.c for a list of valid options + * @init not sure.. + * + * Returns: a new character backend + */ +CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, void (*init)(struct CharDriverState *s)); -CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s)); -void qemu_chr_set_echo(struct CharDriverState *chr, bool echo); -void qemu_chr_close(CharDriverState *chr); -void qemu_chr_printf(CharDriverState *s, const char *fmt, ...) + +/** + * @qemu_chr_new: + * + * Create a new character backend from a URI. + * + * @label the name of the backend + * @filename the URI + * @init not sure.. + * + * Returns: a new character backend + */ +CharDriverState *qemu_chr_new(const char *label, const char *filename, + void (*init)(struct CharDriverState *s)); + +/** + * @qemu_chr_delete: + * + * Destroy a character backend. + */ +void qemu_chr_delete(CharDriverState *chr); + +/** + * @qemu_chr_fe_set_echo: + * + * Ask the backend to override its normal echo setting. This only really + * applies to the stdio backend and is used by the QMP server such that you + * can see what you type if you try to type QMP commands. + * + * @echo true to enable echo, false to disable echo + */ +void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo); + +/** + * @qemu_chr_fe_open: + * + * Open a character backend. This function call is an indication that the + * front end is ready to begin doing I/O. + */ +void qemu_chr_fe_open(struct CharDriverState *chr); + +/** + * @qemu_chr_fe_close: + * + * Close a character backend. This function call indicates that the front end + * no longer is able to process I/O. To process I/O again, the front end will + * call @qemu_chr_fe_open. + */ +void qemu_chr_fe_close(struct CharDriverState *chr); + +/** + * @qemu_chr_fe_printf: + * + * Write to a character backend using a printf style interface. + * + * @fmt see #printf + */ +void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); -void qemu_chr_send_event(CharDriverState *s, int event); + +/** + * @qemu_chr_fe_write: + * + * Write data to a character backend from the front end. This function will + * send data from the front end to the back end. + * + * @buf the data + * @len the number of bytes to send + * + * Returns: the number of bytes consumed + */ +int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len); + +/** + * @qemu_chr_fe_ioctl: + * + * Issue a device specific ioctl to a backend. + * + * @cmd see CHR_IOCTL_* + * @arg the data associated with @cmd + * + * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the + * return value depends on the semantics of @cmd + */ +int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg); + +/** + * @qemu_chr_fe_get_msgfd: + * + * For backends capable of fd passing, return the latest file descriptor passed + * by a client. + * + * Returns: -1 if fd passing isn't supported or there is no pending file + * descriptor. If a file descriptor is returned, subsequent calls to + * this function will return -1 until a client sends a new file + * descriptor. + */ +int qemu_chr_fe_get_msgfd(CharDriverState *s); + +/** + * @qemu_chr_be_can_write: + * + * Determine how much data the front end can currently accept. This function + * returns the number of bytes the front end can accept. If it returns 0, the + * front end cannot receive data at the moment. The function must be polled + * to determine when data can be received. + * + * Returns: the number of bytes the front end can receive via @qemu_chr_be_write + */ +int qemu_chr_be_can_write(CharDriverState *s); + +/** + * @qemu_chr_be_write: + * + * Write data from the back end to the front end. Before issuing this call, + * the caller should call @qemu_chr_be_can_write to determine how much data + * the front end can currently accept. + * + * @buf a buffer to receive data from the front end + * @len the number of bytes to receive from the front end + */ +void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len); + + +/** + * @qemu_chr_be_event: + * + * Send an event from the back end to the front end. + * + * @event the event to send + */ +void qemu_chr_be_event(CharDriverState *s, int event); + void qemu_chr_add_handlers(CharDriverState *s, IOCanReadHandler *fd_can_read, IOReadHandler *fd_read, IOEventHandler *fd_event, void *opaque); -int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg); + void qemu_chr_generic_open(CharDriverState *s); -int qemu_chr_can_read(CharDriverState *s); -void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len); -int qemu_chr_get_msgfd(CharDriverState *s); void qemu_chr_accept_input(CharDriverState *s); +int qemu_chr_add_client(CharDriverState *s, int fd); void qemu_chr_info_print(Monitor *mon, const QObject *ret_data); void qemu_chr_info(Monitor *mon, QObject **ret_data); CharDriverState *qemu_chr_find(const char *name); +QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); + /* add an eventfd to the qemu devices that are polled */ CharDriverState *qemu_chr_open_eventfd(int eventfd); @@ -109,15 +248,4 @@ void qemu_chr_close_mem(CharDriverState *chr); QString *qemu_chr_mem_to_qs(CharDriverState *chr); size_t qemu_chr_mem_osize(const CharDriverState *chr); -/* async I/O support */ - -int qemu_set_fd_handler2(int fd, - IOCanReadHandler *fd_read_poll, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque); -int qemu_set_fd_handler(int fd, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque); #endif diff --git a/qemu-common.h b/qemu-common.h index 14ed6b9..2ce47aa 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -2,22 +2,22 @@ #ifndef QEMU_COMMON_H #define QEMU_COMMON_H +#include "compiler.h" #include "config-host.h" -#define QEMU_NORETURN __attribute__ ((__noreturn__)) -#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT -#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define QEMU_WARN_UNUSED_RESULT +#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__) +#define WORDS_ALIGNED #endif -#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; +#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) typedef struct QEMUTimer QEMUTimer; typedef struct QEMUFile QEMUFile; -typedef struct QEMUBH QEMUBH; typedef struct DeviceState DeviceState; +struct Monitor; +typedef struct Monitor Monitor; + /* we put basic includes here to avoid repeating them in device drivers */ #include #include @@ -33,7 +33,18 @@ typedef struct DeviceState DeviceState; #include #include #include +#include #include +#include +#include + +#ifdef _WIN32 +#include "qemu-os-win32.h" +#endif + +#ifdef CONFIG_POSIX +#include "qemu-os-posix.h" +#endif #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -68,22 +79,6 @@ struct iovec { #include #endif -#if defined __GNUC__ -# if (__GNUC__ < 4) || \ - defined(__GNUC_MINOR__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4) - /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) -# else - /* Use gnu_printf when supported (qemu uses standard format strings). */ -# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) -# endif -#else -#define GCC_ATTR /**/ -#define GCC_FMT_ATTR(n, m) -#endif - typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3); @@ -98,17 +93,15 @@ static inline char *realpath(const char *path, char *resolved_path) _fullpath(resolved_path, path, _MAX_PATH); return resolved_path; } - -#define PRId64 "I64d" -#define PRIx64 "I64x" -#define PRIu64 "I64u" -#define PRIo64 "I64o" #endif +/* icount */ +void configure_icount(const char *option); +extern int use_icount; + /* FIXME: Remove NEED_CPU_H. */ #ifndef NEED_CPU_H -#include #include "osdep.h" #include "bswap.h" @@ -118,26 +111,10 @@ static inline char *realpath(const char *path, char *resolved_path) #endif /* !defined(NEED_CPU_H) */ -/* bottom halves */ -typedef void QEMUBHFunc(void *opaque); - -void async_context_push(void); -void async_context_pop(void); -int get_async_context_id(void); - -QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque); -void qemu_bh_schedule(QEMUBH *bh); -/* Bottom halfs that are scheduled from a bottom half handler are instantly - * invoked. This can create an infinite loop if a bottom half handler - * schedules itself. qemu_bh_schedule_idle() avoids this infinite loop by - * ensuring that the bottom half isn't executed until the next main loop - * iteration. - */ -void qemu_bh_schedule_idle(QEMUBH *bh); -void qemu_bh_cancel(QEMUBH *bh); -void qemu_bh_delete(QEMUBH *bh); -int qemu_bh_poll(void); -void qemu_bh_update_timeout(int *timeout); +/* main function, renamed */ +#if defined(CONFIG_COCOA) +int qemu_main(int argc, char **argv, char **envp); +#endif void qemu_get_timedate(struct tm *tm, int offset); int qemu_timedate_diff(struct tm *tm); @@ -152,6 +129,7 @@ time_t mktimegm(struct tm *tm); int qemu_fls(int i); int qemu_fdatasync(int fd); int fcntl_setfl(int fd, int flag); +int qemu_parse_fd(const char *param); /* * strtosz() suffixes used to specify the default treatment of an @@ -167,6 +145,8 @@ int fcntl_setfl(int fd, int flag); #define STRTOSZ_DEFSUFFIX_B 'B' int64_t strtosz(const char *nptr, char **end); int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix); +int64_t strtosz_suffix_unit(const char *nptr, char **end, + const char default_suffix, int64_t unit); /* path.c */ void init_paths(const char *prefix); @@ -188,21 +168,7 @@ const char *path(const char *pathname); #define qemu_isascii(c) isascii((unsigned char)(c)) #define qemu_toascii(c) toascii((unsigned char)(c)) -#ifdef _WIN32 -/* ffs() in oslib-win32.c for WIN32, strings.h for the rest of the world */ -int ffs(int i); -#endif - void *qemu_oom_check(void *ptr); -void *qemu_malloc(size_t size); -void *qemu_realloc(void *ptr, size_t size); -void *qemu_mallocz(size_t size); -void qemu_free(void *ptr); -char *qemu_strdup(const char *str); -char *qemu_strndup(const char *str, size_t size); - -void qemu_mutex_lock_iothread(void); -void qemu_mutex_unlock_iothread(void); int qemu_open(const char *name, int flags, ...); ssize_t qemu_write_full(int fd, const void *buf, size_t count) @@ -214,15 +180,16 @@ int qemu_eventfd(int pipefd[2]); int qemu_pipe(int pipefd[2]); #endif +#ifdef _WIN32 +#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags) +#else +#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags) +#endif + /* Error handling. */ void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -/* IO callbacks. */ -typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); -typedef int IOCanReadHandler(void *opaque); -typedef void IOHandler(void *opaque); - struct ParallelIOArg { void *buffer; int count; @@ -241,7 +208,7 @@ typedef struct DisplayState DisplayState; typedef struct DisplayChangeListener DisplayChangeListener; typedef struct DisplaySurface DisplaySurface; typedef struct DisplayAllocator DisplayAllocator; -typedef struct QEMU_PixelFormat PixelFormat; +typedef struct PixelFormat PixelFormat; typedef struct TextConsole TextConsole; typedef TextConsole QEMUConsole; typedef struct CharDriverState CharDriverState; @@ -271,24 +238,24 @@ typedef struct I2SCodec I2SCodec; typedef struct SSIBus SSIBus; typedef struct EventNotifier EventNotifier; typedef struct VirtIODevice VirtIODevice; +typedef struct QEMUSGList QEMUSGList; typedef uint64_t pcibus_t; -void cpu_exec_init_all(unsigned long tb_size); +void tcg_exec_init(unsigned long tb_size); +bool tcg_enabled(void); + +void cpu_exec_init_all(void); /* CPU save/load. */ void cpu_save(QEMUFile *f, void *opaque); int cpu_load(QEMUFile *f, void *opaque, int version_id); -/* Force QEMU to stop what it's doing and service IO */ -void qemu_service_io(void); - -/* Force QEMU to process pending events */ -void qemu_notify_event(void); - /* Unblock cpu */ void qemu_cpu_kick(void *env); -int qemu_cpu_self(void *env); +void qemu_cpu_kick_self(void); +int qemu_cpu_is_self(void *env); +bool all_cpu_threads_idle(void); /* work queue */ struct qemu_work_item { @@ -325,8 +292,19 @@ void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count); void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count, size_t skip); -struct Monitor; -typedef struct Monitor Monitor; +void qemu_progress_init(int enabled, float min_skip); +void qemu_progress_end(void); +void qemu_progress_print(float delta, int max); + +#define QEMU_FILE_TYPE_BIOS 0 +#define QEMU_FILE_TYPE_KEYMAP 1 +char *qemu_find_file(int type, const char *name); + +/* OS specific functions */ +void os_setup_early_signal_handling(void); +char *os_find_datadir(const char *argv0); +void os_parse_cmd_args(int index, const char *optarg); +void os_pidfile_error(void); /* Convert a byte between binary and BCD. */ static inline uint8_t to_bcd(uint8_t val) diff --git a/qemu-config.c b/qemu-config.c index 323d3c2..597d7e1 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -2,7 +2,6 @@ #include "qemu-error.h" #include "qemu-option.h" #include "qemu-config.h" -#include "sysemu.h" #include "hw/qdev.h" static QemuOptsList qemu_drive_opts = { @@ -24,6 +23,7 @@ static QemuOptsList qemu_drive_opts = { },{ .name = "index", .type = QEMU_OPT_NUMBER, + .help = "index number", },{ .name = "cyls", .type = QEMU_OPT_NUMBER, @@ -47,6 +47,7 @@ static QemuOptsList qemu_drive_opts = { },{ .name = "snapshot", .type = QEMU_OPT_BOOL, + .help = "enable/disable snapshot mode", },{ .name = "file", .type = QEMU_OPT_STRING, @@ -54,7 +55,8 @@ static QemuOptsList qemu_drive_opts = { },{ .name = "cache", .type = QEMU_OPT_STRING, - .help = "host cache usage (none, writeback, writethrough, unsafe)", + .help = "host cache usage (none, writeback, writethrough, " + "directsync, unsafe)", },{ .name = "aio", .type = QEMU_OPT_STRING, @@ -66,12 +68,15 @@ static QemuOptsList qemu_drive_opts = { },{ .name = "serial", .type = QEMU_OPT_STRING, + .help = "disk serial number", },{ .name = "rerror", .type = QEMU_OPT_STRING, + .help = "read error action", },{ .name = "werror", .type = QEMU_OPT_STRING, + .help = "write error action", },{ .name = "addr", .type = QEMU_OPT_STRING, @@ -79,6 +84,7 @@ static QemuOptsList qemu_drive_opts = { },{ .name = "readonly", .type = QEMU_OPT_BOOL, + .help = "open drive file as read-only", }, { /* end of list */ } }, @@ -159,11 +165,11 @@ static QemuOptsList qemu_chardev_opts = { QemuOptsList qemu_fsdev_opts = { .name = "fsdev", - .implied_opt_name = "fstype", + .implied_opt_name = "fsdriver", .head = QTAILQ_HEAD_INITIALIZER(qemu_fsdev_opts.head), .desc = { { - .name = "fstype", + .name = "fsdriver", .type = QEMU_OPT_STRING, }, { .name = "path", @@ -171,18 +177,25 @@ QemuOptsList qemu_fsdev_opts = { }, { .name = "security_model", .type = QEMU_OPT_STRING, + }, { + .name = "writeout", + .type = QEMU_OPT_STRING, + }, { + .name = "readonly", + .type = QEMU_OPT_BOOL, }, + { /*End of list */ } }, }; QemuOptsList qemu_virtfs_opts = { .name = "virtfs", - .implied_opt_name = "fstype", + .implied_opt_name = "fsdriver", .head = QTAILQ_HEAD_INITIALIZER(qemu_virtfs_opts.head), .desc = { { - .name = "fstype", + .name = "fsdriver", .type = QEMU_OPT_STRING, }, { .name = "path", @@ -193,6 +206,12 @@ QemuOptsList qemu_virtfs_opts = { }, { .name = "security_model", .type = QEMU_OPT_STRING, + }, { + .name = "writeout", + .type = QEMU_OPT_STRING, + }, { + .name = "readonly", + .type = QEMU_OPT_BOOL, }, { /*End of list */ } @@ -297,20 +316,21 @@ static QemuOptsList qemu_mon_opts = { }, }; -#ifdef CONFIG_SIMPLE_TRACE static QemuOptsList qemu_trace_opts = { .name = "trace", .implied_opt_name = "trace", .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head), .desc = { { + .name = "events", + .type = QEMU_OPT_STRING, + },{ .name = "file", .type = QEMU_OPT_STRING, }, - { /* end if list */ } + { /* end of list */ } }, }; -#endif static QemuOptsList qemu_cpudef_opts = { .name = "cpudef", @@ -386,6 +406,12 @@ QemuOptsList qemu_spice_opts = { .name = "disable-ticketing", .type = QEMU_OPT_BOOL, },{ + .name = "disable-copy-paste", + .type = QEMU_OPT_BOOL, + },{ + .name = "sasl", + .type = QEMU_OPT_BOOL, + },{ .name = "x509-dir", .type = QEMU_OPT_STRING, },{ @@ -431,7 +457,7 @@ QemuOptsList qemu_spice_opts = { .name = "playback-compression", .type = QEMU_OPT_BOOL, }, - { /* end if list */ } + { /* end of list */ } }, }; @@ -447,7 +473,51 @@ QemuOptsList qemu_option_rom_opts = { .name = "romfile", .type = QEMU_OPT_STRING, }, - { /* end if list */ } + { /* end of list */ } + }, +}; + +static QemuOptsList qemu_machine_opts = { + .name = "machine", + .implied_opt_name = "type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head), + .desc = { + { + .name = "type", + .type = QEMU_OPT_STRING, + .help = "emulated machine" + }, { + .name = "accel", + .type = QEMU_OPT_STRING, + .help = "accelerator list", + }, + { /* End of list */ } + }, +}; + +QemuOptsList qemu_boot_opts = { + .name = "boot-opts", + .head = QTAILQ_HEAD_INITIALIZER(qemu_boot_opts.head), + .desc = { + /* the three names below are not used now */ + { + .name = "order", + .type = QEMU_OPT_STRING, + }, { + .name = "once", + .type = QEMU_OPT_STRING, + }, { + .name = "menu", + .type = QEMU_OPT_STRING, + /* following are really used */ + }, { + .name = "splash", + .type = QEMU_OPT_STRING, + }, { + .name = "splash-time", + .type = QEMU_OPT_STRING, + }, + { /*End of list */ } }, }; @@ -461,10 +531,10 @@ static QemuOptsList *vm_config_groups[32] = { &qemu_global_opts, &qemu_mon_opts, &qemu_cpudef_opts, -#ifdef CONFIG_SIMPLE_TRACE &qemu_trace_opts, -#endif &qemu_option_rom_opts, + &qemu_machine_opts, + &qemu_boot_opts, NULL, }; diff --git a/qemu-doc.texi b/qemu-doc.texi index 86e017c..9c3cb62 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -110,6 +110,7 @@ For system emulation, the following hardware targets are supported: @item Syborg SVP base model (ARM Cortex-A8). @item AXIS-Devboard88 (CRISv32 ETRAX-FS). @item Petalogix Spartan 3aDSP1800 MMU ref design (MicroBlaze). +@item Avnet LX60/LX110/LX200 boards (Xtensa) @end itemize @cindex supported user mode targets @@ -226,7 +227,7 @@ QEMU uses YM3812 emulation by Tatsuyuki Satoh. QEMU uses GUS emulation (GUSEMU32 @url{http://www.deinmeister.de/gusemu/}) by Tibor "TS" Schütz. -Not that, by default, GUS shares IRQ(7) with parallel ports and so +Note that, by default, GUS shares IRQ(7) with parallel ports and so qemu must be told to not have parallel ports to have working GUS @example @@ -278,12 +279,24 @@ targets do not need a disk image. @c man begin OPTIONS -During the graphical emulation, you can use the following keys: +During the graphical emulation, you can use special key combinations to change +modes. The default key mappings are shown below, but if you use @code{-alt-grab} +then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt) and if you use +@code{-ctrl-grab} then the modifier is the right Ctrl key (instead of Ctrl-Alt): + @table @key @item Ctrl-Alt-f @kindex Ctrl-Alt-f Toggle full screen +@item Ctrl-Alt-+ +@kindex Ctrl-Alt-+ +Enlarge the screen + +@item Ctrl-Alt-- +@kindex Ctrl-Alt-- +Shrink the screen + @item Ctrl-Alt-u @kindex Ctrl-Alt-u Restore the screen's un-scaled dimensions @@ -408,6 +421,7 @@ snapshots. * disk_images_fat_images:: Virtual FAT disk images * disk_images_nbd:: NBD access * disk_images_sheepdog:: Sheepdog disk images +* disk_images_iscsi:: iSCSI LUNs @end menu @node disk_images_quickstart @@ -682,6 +696,61 @@ qemu-img create sheepdog:@var{hostname}:@var{port}:@var{image} @var{size} qemu sheepdog:@var{hostname}:@var{port}:@var{image} @end example +@node disk_images_iscsi +@subsection iSCSI LUNs + +iSCSI is a popular protocol used to access SCSI devices across a computer +network. + +There are two different ways iSCSI devices can be used by QEMU. + +The first method is to mount the iSCSI LUN on the host, and make it appear as +any other ordinary SCSI device on the host and then to access this device as a +/dev/sd device from QEMU. How to do this differs between host OSes. + +The second method involves using the iSCSI initiator that is built into +QEMU. This provides a mechanism that works the same way regardless of which +host OS you are running QEMU on. This section will describe this second method +of using iSCSI together with QEMU. + +In QEMU, iSCSI devices are described using special iSCSI URLs + +@example +URL syntax: +iscsi://[[%]@@][:]// +@end example + +Username and password are optional and only used if your target is set up +using CHAP authentication for access control. +Alternatively the username and password can also be set via environment +variables to have these not show up in the process list + +@example +export LIBISCSI_CHAP_USERNAME= +export LIBISCSI_CHAP_PASSWORD= +iscsi://// +@end example + +Howto set up a simple iSCSI target on loopback and accessing it via QEMU: +@example +This example shows how to set up an iSCSI target with one CDROM and one DISK +using the Linux STGT software target. This target is available on Red Hat based +systems as the package 'scsi-target-utils'. + +tgtd --iscsi portal=127.0.0.1:3260 +tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test +tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \ + -b /IMAGES/disk.img --device-type=disk +tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \ + -b /IMAGES/cd.iso --device-type=cd +tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL + +qemu-system-i386 -boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \ + -cdrom iscsi://127.0.0.1/iqn.qemu.test/2 +@end example + + + @node pcsys_network @section Network emulation @@ -1434,6 +1503,7 @@ differences are mentioned in the following sections. * Cris System emulator:: * Microblaze System emulator:: * SH4 System emulator:: +* Xtensa System emulator:: @end menu @node PowerPC System emulator @@ -1735,7 +1805,7 @@ PC Keyboard IDE controller @end itemize -The mipssim pseudo board emulation provides an environment similiar +The mipssim pseudo board emulation provides an environment similar to what the proprietary MIPS emulator uses for running Linux. It supports: @@ -2112,6 +2182,59 @@ TODO TODO +@node Xtensa System emulator +@section Xtensa System emulator +@cindex system emulation (Xtensa) + +Two executables cover simulation of both Xtensa endian options, +@file{qemu-system-xtensa} and @file{qemu-system-xtensaeb}. +Two different machine types are emulated: + +@itemize @minus +@item +Xtensa emulator pseudo board "sim" +@item +Avnet LX60/LX110/LX200 board +@end itemize + +The sim pseudo board emulation provides an environment similar +to one provided by the proprietary Tensilica ISS. +It supports: + +@itemize @minus +@item +A range of Xtensa CPUs, default is the DC232B +@item +Console and filesystem access via semihosting calls +@end itemize + +The Avnet LX60/LX110/LX200 emulation supports: + +@itemize @minus +@item +A range of Xtensa CPUs, default is the DC232B +@item +16550 UART +@item +OpenCores 10/100 Mbps Ethernet MAC +@end itemize + +@c man begin OPTIONS + +The following options are specific to the Xtensa emulation: + +@table @option + +@item -semihosting +Enable semihosting syscall emulation. + +Xtensa semihosting provides basic file IO calls, such as open/read/write/seek/select. +Tensilica baremetal libc for ISS and linux platform "sim" use this interface. + +Note that this allows guest direct access to the host filesystem, +so should only be used with trusted guest OS. + +@end table @node QEMU User space emulator @chapter QEMU User space emulator diff --git a/qemu-error.c b/qemu-error.c index 5a35e7c..4b20d28 100644 --- a/qemu-error.c +++ b/qemu-error.c @@ -12,7 +12,6 @@ #include #include "monitor.h" -#include "sysemu.h" /* * Print to current monitor if we have one, else to stderr. @@ -194,6 +193,8 @@ void error_print_loc(void) /* * Print an error message to current monitor if we have one, else to stderr. + * Format arguments like sprintf(). The result should not contain + * newlines. * Prepend the current location and append a newline. * It's wrong to call this in a QMP monitor. Use qerror_report() there. */ diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index 6c7176f..49dce7c 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -22,15 +22,15 @@ STEXI ETEXI DEF("commit", img_commit, - "commit [-f fmt] filename") + "commit [-f fmt] [-t cache] filename") STEXI -@item commit [-f @var{fmt}] @var{filename} +@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename} ETEXI DEF("convert", img_convert, - "convert [-c] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename") + "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename") STEXI -@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} ETEXI DEF("info", img_info, @@ -46,9 +46,9 @@ STEXI ETEXI DEF("rebase", img_rebase, - "rebase [-f fmt] [-u] -b backing_file [-F backing_fmt] filename") + "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename") STEXI -@item rebase [-f @var{fmt}] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} +@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} ETEXI DEF("resize", img_resize, diff --git a/qemu-img.c b/qemu-img.c index 7e3cc4c..01cc0d3 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -40,6 +40,7 @@ typedef struct img_cmd_t { /* Default to cache=writeback as data integrity is not important for qemu-tcg. */ #define BDRV_O_FLAGS BDRV_O_CACHE_WB +#define BDRV_DEFAULT_CACHE "writeback" static void format_print(void *opaque, const char *name) { @@ -64,6 +65,9 @@ static void help(void) "Command parameters:\n" " 'filename' is a disk image filename\n" " 'fmt' is the disk image format. It is guessed automatically in most cases\n" + " 'cache' is the cache mode used to write the output disk image, the valid\n" + " options are: 'none', 'writeback' (default), 'writethrough', 'directsync'\n" + " and 'unsafe'\n" " 'size' is the disk image size in bytes. Optional suffixes\n" " 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n" " and T (terabyte, 1024G) are supported. 'b' is ignored.\n" @@ -77,6 +81,9 @@ static void help(void) " match exactly. The image doesn't need a working backing file before\n" " rebasing in this case (useful for renaming the backing file)\n" " '-h' with or without a command shows this help and lists the supported formats\n" + " '-p' show progress of command (only certain commands)\n" + " '-S' indicates the consecutive number of bytes that must contain only zeros\n" + " for qemu-img to create a sparse image during conversion\n" "\n" "Parameters to snapshot subcommand:\n" " 'snapshot' is the name of the snapshot to create, apply or delete\n" @@ -303,11 +310,11 @@ static int img_create(int argc, char **argv) fmt = optarg; break; case 'e': - error_report("qemu-img: option -e is deprecated, please use \'-o " + error_report("option -e is deprecated, please use \'-o " "encryption\' instead!"); return 1; case '6': - error_report("qemu-img: option -6 is deprecated, please use \'-o " + error_report("option -6 is deprecated, please use \'-o " "compat6\' instead!"); return 1; case 'o': @@ -325,8 +332,9 @@ static int img_create(int argc, char **argv) /* Get image size, if specified */ if (optind < argc) { int64_t sval; - sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B); - if (sval < 0) { + char *end; + sval = strtosz_suffix(argv[optind++], &end, STRTOSZ_DEFSUFFIX_B); + if (sval < 0 || *end) { error_report("Invalid image size specified! You may use k, M, G or " "T suffixes for "); error_report("kilobytes, megabytes, gigabytes and terabytes."); @@ -440,13 +448,14 @@ static int img_check(int argc, char **argv) static int img_commit(int argc, char **argv) { - int c, ret; - const char *filename, *fmt; + int c, ret, flags; + const char *filename, *fmt, *cache; BlockDriverState *bs; fmt = NULL; + cache = BDRV_DEFAULT_CACHE; for(;;) { - c = getopt(argc, argv, "f:h"); + c = getopt(argc, argv, "f:ht:"); if (c == -1) { break; } @@ -458,6 +467,9 @@ static int img_commit(int argc, char **argv) case 'f': fmt = optarg; break; + case 't': + cache = optarg; + break; } } if (optind >= argc) { @@ -465,7 +477,14 @@ static int img_commit(int argc, char **argv) } filename = argv[optind++]; - bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR); + flags = BDRV_O_RDWR; + ret = bdrv_parse_cache_flags(cache, &flags); + if (ret < 0) { + error_report("Invalid cache option: %s", cache); + return -1; + } + + bs = bdrv_new_open(filename, fmt, flags); if (!bs) { return 1; } @@ -495,14 +514,37 @@ static int img_commit(int argc, char **argv) return 0; } +/* + * Checks whether the sector is not a zero sector. + * + * Attention! The len must be a multiple of 4 * sizeof(long) due to + * restriction of optimizations in this function. + */ static int is_not_zero(const uint8_t *sector, int len) { + /* + * Use long as the biggest available internal data type that fits into the + * CPU register and unroll the loop to smooth out the effect of memory + * latency. + */ + int i; - len >>= 2; - for(i = 0;i < len; i++) { - if (((uint32_t *)sector)[i] != 0) + long d0, d1, d2, d3; + const long * const data = (const long *) sector; + + len /= sizeof(long); + + for(i = 0; i < len; i += 4) { + d0 = data[i + 0]; + d1 = data[i + 1]; + d2 = data[i + 2]; + d3 = data[i + 3]; + + if (d0 || d1 || d2 || d3) { return 1; + } } + return 0; } @@ -532,6 +574,48 @@ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum) } /* + * Like is_allocated_sectors, but if the buffer starts with a used sector, + * up to 'min' consecutive sectors containing zeros are ignored. This avoids + * breaking up write requests for only small sparse areas. + */ +static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum, + int min) +{ + int ret; + int num_checked, num_used; + + if (n < min) { + min = n; + } + + ret = is_allocated_sectors(buf, n, pnum); + if (!ret) { + return ret; + } + + num_used = *pnum; + buf += BDRV_SECTOR_SIZE * *pnum; + n -= *pnum; + num_checked = num_used; + + while (n > 0) { + ret = is_allocated_sectors(buf, n, pnum); + + buf += BDRV_SECTOR_SIZE * *pnum; + n -= *pnum; + num_checked += *pnum; + if (ret) { + num_used = num_checked; + } else if (*pnum >= min) { + break; + } + } + + *pnum = num_used; + return 1; +} + +/* * Compares two buffers sector by sector. Returns 0 if the first sector of both * buffers matches, non-zero otherwise. * @@ -567,7 +651,8 @@ static int compare_sectors(const uint8_t *buf1, const uint8_t *buf2, int n, static int img_convert(int argc, char **argv) { int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors; - const char *fmt, *out_fmt, *out_baseimg, *out_filename; + int progress = 0, flags; + const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename; BlockDriver *drv, *proto_drv; BlockDriverState **bs = NULL, *out_bs = NULL; int64_t total_sectors, nb_sectors, sector_num, bs_offset; @@ -579,13 +664,16 @@ static int img_convert(int argc, char **argv) QEMUOptionParameter *out_baseimg_param; char *options = NULL; const char *snapshot_name = NULL; + float local_progress; + int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */ fmt = NULL; out_fmt = "raw"; + cache = "unsafe"; out_baseimg = NULL; compress = 0; for(;;) { - c = getopt(argc, argv, "f:O:B:s:hce6o:"); + c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:"); if (c == -1) { break; } @@ -607,11 +695,11 @@ static int img_convert(int argc, char **argv) compress = 1; break; case 'e': - error_report("qemu-img: option -e is deprecated, please use \'-o " + error_report("option -e is deprecated, please use \'-o " "encryption\' instead!"); return 1; case '6': - error_report("qemu-img: option -6 is deprecated, please use \'-o " + error_report("option -6 is deprecated, please use \'-o " "compat6\' instead!"); return 1; case 'o': @@ -620,6 +708,25 @@ static int img_convert(int argc, char **argv) case 's': snapshot_name = optarg; break; + case 'S': + { + int64_t sval; + char *end; + sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B); + if (sval < 0 || *end) { + error_report("Invalid minimum zero buffer size for sparse output specified"); + return 1; + } + + min_sparse = sval / BDRV_SECTOR_SIZE; + break; + } + case 'p': + progress = 1; + break; + case 't': + cache = optarg; + break; } } @@ -642,7 +749,10 @@ static int img_convert(int argc, char **argv) goto out; } - bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *)); + qemu_progress_init(progress, 2.0); + qemu_progress_print(0, 100); + + bs = g_malloc0(bs_n * sizeof(BlockDriverState *)); total_sectors = 0; for (bs_i = 0; bs_i < bs_n; bs_i++) { @@ -658,12 +768,12 @@ static int img_convert(int argc, char **argv) if (snapshot_name != NULL) { if (bs_n > 1) { - error_report("No support for concatenating multiple snapshot\n"); + error_report("No support for concatenating multiple snapshot"); ret = -1; goto out; } if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) { - error_report("Failed to load snapshot\n"); + error_report("Failed to load snapshot"); ret = -1; goto out; } @@ -716,6 +826,8 @@ static int img_convert(int argc, char **argv) if (compress) { QEMUOptionParameter *encryption = get_option_parameter(param, BLOCK_OPT_ENCRYPT); + QEMUOptionParameter *preallocation = + get_option_parameter(param, BLOCK_OPT_PREALLOC); if (!drv->bdrv_write_compressed) { error_report("Compression not supported for this file format"); @@ -729,6 +841,15 @@ static int img_convert(int argc, char **argv) ret = -1; goto out; } + + if (preallocation && preallocation->value.s + && strcmp(preallocation->value.s, "off")) + { + error_report("Compression and preallocation not supported at " + "the same time"); + ret = -1; + goto out; + } } /* Create the new image */ @@ -747,8 +868,14 @@ static int img_convert(int argc, char **argv) goto out; } - out_bs = bdrv_new_open(out_filename, out_fmt, - BDRV_O_FLAGS | BDRV_O_RDWR | BDRV_O_NO_FLUSH); + flags = BDRV_O_RDWR; + ret = bdrv_parse_cache_flags(cache, &flags); + if (ret < 0) { + error_report("Invalid cache option: %s", cache); + return -1; + } + + out_bs = bdrv_new_open(out_filename, out_fmt, flags); if (!out_bs) { ret = -1; goto out; @@ -757,7 +884,7 @@ static int img_convert(int argc, char **argv) bs_i = 0; bs_offset = 0; bdrv_get_geometry(bs[0], &bs_sectors); - buf = qemu_malloc(IO_BUF_SIZE); + buf = qemu_blockalign(out_bs, IO_BUF_SIZE); if (compress) { ret = bdrv_get_info(out_bs, &bdi); @@ -773,6 +900,11 @@ static int img_convert(int argc, char **argv) } cluster_sectors = cluster_size >> 9; sector_num = 0; + + nb_sectors = total_sectors; + local_progress = (float)100 / + (nb_sectors / MIN(nb_sectors, cluster_sectors)); + for(;;) { int64_t bs_num; int remainder; @@ -808,7 +940,8 @@ static int img_convert(int argc, char **argv) ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow); if (ret < 0) { - error_report("error while reading"); + error_report("error while reading sector %" PRId64 ": %s", + bs_num, strerror(-ret)); goto out; } @@ -826,12 +959,13 @@ static int img_convert(int argc, char **argv) ret = bdrv_write_compressed(out_bs, sector_num, buf, cluster_sectors); if (ret != 0) { - error_report("error while compressing sector %" PRId64, - sector_num); + error_report("error while compressing sector %" PRId64 + ": %s", sector_num, strerror(-ret)); goto out; } } sector_num += n; + qemu_progress_print(local_progress, 100); } /* signal EOF to align */ bdrv_write_compressed(out_bs, 0, NULL, 0); @@ -839,6 +973,10 @@ static int img_convert(int argc, char **argv) int has_zero_init = bdrv_has_zero_init(out_bs); sector_num = 0; // total number of sectors converted so far + nb_sectors = total_sectors - sector_num; + local_progress = (float)100 / + (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512)); + for(;;) { nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) { @@ -885,7 +1023,8 @@ static int img_convert(int argc, char **argv) ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n); if (ret < 0) { - error_report("error while reading"); + error_report("error while reading sector %" PRId64 ": %s", + sector_num - bs_offset, strerror(-ret)); goto out; } /* NOTE: at the same time we convert, we do not write zero @@ -901,10 +1040,11 @@ static int img_convert(int argc, char **argv) sectors that are entirely 0, since whatever data was already there is garbage, not 0s. */ if (!has_zero_init || out_baseimg || - is_allocated_sectors(buf1, n, &n1)) { + is_allocated_sectors_min(buf1, n, &n1, min_sparse)) { ret = bdrv_write(out_bs, sector_num, buf1, n1); if (ret < 0) { - error_report("error while writing"); + error_report("error while writing sector %" PRId64 + ": %s", sector_num, strerror(-ret)); goto out; } } @@ -912,12 +1052,14 @@ static int img_convert(int argc, char **argv) n -= n1; buf1 += n1 * 512; } + qemu_progress_print(local_progress, 100); } } out: + qemu_progress_end(); free_option_parameters(create_options); free_option_parameters(param); - qemu_free(buf); + qemu_vfree(buf); if (out_bs) { bdrv_delete(out_bs); } @@ -927,7 +1069,7 @@ out: bdrv_delete(bs[bs_i]); } } - qemu_free(bs); + g_free(bs); } if (ret) { return 1; @@ -935,35 +1077,6 @@ out: return 0; } -#ifdef _WIN32 -static int64_t get_allocated_file_size(const char *filename) -{ - typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high); - get_compressed_t get_compressed; - struct _stati64 st; - - /* WinNT support GetCompressedFileSize to determine allocate size */ - get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA"); - if (get_compressed) { - DWORD high, low; - low = get_compressed(filename, &high); - if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR) - return (((int64_t) high) << 32) + low; - } - - if (_stati64(filename, &st) < 0) - return -1; - return st.st_size; -} -#else -static int64_t get_allocated_file_size(const char *filename) -{ - struct stat st; - if (stat(filename, &st) < 0) - return -1; - return (int64_t)st.st_blocks * 512; -} -#endif static void dump_snapshots(BlockDriverState *bs) { @@ -980,7 +1093,7 @@ static void dump_snapshots(BlockDriverState *bs) sn = &sn_tab[i]; printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn)); } - qemu_free(sn_tab); + g_free(sn_tab); } static int img_info(int argc, char **argv) @@ -1023,7 +1136,7 @@ static int img_info(int argc, char **argv) bdrv_get_format(bs, fmt_name, sizeof(fmt_name)); bdrv_get_geometry(bs, &total_sectors); get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512); - allocated_size = get_allocated_file_size(filename); + allocated_size = bdrv_get_allocated_file_size(bs); if (allocated_size < 0) { snprintf(dsize_buf, sizeof(dsize_buf), "unavailable"); } else { @@ -1181,17 +1294,18 @@ static int img_rebase(int argc, char **argv) BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL; BlockDriver *old_backing_drv, *new_backing_drv; char *filename; - const char *fmt, *out_basefmt, *out_baseimg; + const char *fmt, *cache, *out_basefmt, *out_baseimg; int c, flags, ret; int unsafe = 0; + int progress = 0; /* Parse commandline parameters */ fmt = NULL; + cache = BDRV_DEFAULT_CACHE; out_baseimg = NULL; out_basefmt = NULL; - for(;;) { - c = getopt(argc, argv, "uhf:F:b:"); + c = getopt(argc, argv, "uhf:F:b:pt:"); if (c == -1) { break; } @@ -1212,21 +1326,36 @@ static int img_rebase(int argc, char **argv) case 'u': unsafe = 1; break; + case 'p': + progress = 1; + break; + case 't': + cache = optarg; + break; } } - if ((optind >= argc) || !out_baseimg) { + if ((optind >= argc) || (!unsafe && !out_baseimg)) { help(); } filename = argv[optind++]; + qemu_progress_init(progress, 2.0); + qemu_progress_print(0, 100); + + flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0); + ret = bdrv_parse_cache_flags(cache, &flags); + if (ret < 0) { + error_report("Invalid cache option: %s", cache); + return -1; + } + /* * Open the images. * * Ignore the old backing file for unsafe rebase in case we want to correct * the reference to a renamed or moved backing file. */ - flags = BDRV_O_FLAGS | BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0); bs = bdrv_new_open(filename, fmt, flags); if (!bs) { return 1; @@ -1291,16 +1420,23 @@ static int img_rebase(int argc, char **argv) */ if (!unsafe) { uint64_t num_sectors; + uint64_t old_backing_num_sectors; + uint64_t new_backing_num_sectors; uint64_t sector; int n; uint8_t * buf_old; uint8_t * buf_new; + float local_progress; - buf_old = qemu_malloc(IO_BUF_SIZE); - buf_new = qemu_malloc(IO_BUF_SIZE); + buf_old = qemu_blockalign(bs, IO_BUF_SIZE); + buf_new = qemu_blockalign(bs, IO_BUF_SIZE); bdrv_get_geometry(bs, &num_sectors); + bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors); + bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors); + local_progress = (float)100 / + (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512)); for (sector = 0; sector < num_sectors; sector += n) { /* How many sectors can we handle with the next read? */ @@ -1316,16 +1452,36 @@ static int img_rebase(int argc, char **argv) continue; } - /* Read old and new backing file */ - ret = bdrv_read(bs_old_backing, sector, buf_old, n); - if (ret < 0) { - error_report("error while reading from old backing file"); - goto out; + /* + * Read old and new backing file and take into consideration that + * backing files may be smaller than the COW image. + */ + if (sector >= old_backing_num_sectors) { + memset(buf_old, 0, n * BDRV_SECTOR_SIZE); + } else { + if (sector + n > old_backing_num_sectors) { + n = old_backing_num_sectors - sector; + } + + ret = bdrv_read(bs_old_backing, sector, buf_old, n); + if (ret < 0) { + error_report("error while reading from old backing file"); + goto out; + } } - ret = bdrv_read(bs_new_backing, sector, buf_new, n); - if (ret < 0) { - error_report("error while reading from new backing file"); - goto out; + + if (sector >= new_backing_num_sectors) { + memset(buf_new, 0, n * BDRV_SECTOR_SIZE); + } else { + if (sector + n > new_backing_num_sectors) { + n = new_backing_num_sectors - sector; + } + + ret = bdrv_read(bs_new_backing, sector, buf_new, n); + if (ret < 0) { + error_report("error while reading from new backing file"); + goto out; + } } /* If they differ, we need to write to the COW file */ @@ -1348,10 +1504,11 @@ static int img_rebase(int argc, char **argv) written += pnum; } + qemu_progress_print(local_progress, 100); } - qemu_free(buf_old); - qemu_free(buf_new); + qemu_vfree(buf_old); + qemu_vfree(buf_new); } /* @@ -1368,6 +1525,7 @@ static int img_rebase(int argc, char **argv) out_baseimg, strerror(-ret)); } + qemu_progress_print(100, 0); /* * TODO At this point it is possible to check if any clusters that are * allocated in the COW file are the same in the backing file. If so, they @@ -1375,10 +1533,15 @@ static int img_rebase(int argc, char **argv) * backing file, in case of a crash this would lead to corruption. */ out: + qemu_progress_end(); /* Cleanup */ if (!unsafe) { - bdrv_delete(bs_old_backing); - bdrv_delete(bs_new_backing); + if (bs_old_backing != NULL) { + bdrv_delete(bs_old_backing); + } + if (bs_new_backing != NULL) { + bdrv_delete(bs_new_backing); + } } bdrv_delete(bs); @@ -1404,6 +1567,16 @@ static int img_resize(int argc, char **argv) { NULL } }; + /* Remove size from argv manually so that negative numbers are not treated + * as options by getopt. */ + if (argc < 3) { + help(); + return 1; + } + + size = argv[--argc]; + + /* Parse getopt arguments */ fmt = NULL; for(;;) { c = getopt(argc, argv, "f:h"); @@ -1420,11 +1593,10 @@ static int img_resize(int argc, char **argv) break; } } - if (optind + 1 >= argc) { + if (optind >= argc) { help(); } filename = argv[optind++]; - size = argv[optind++]; /* Choose grow, shrink, or absolute resize mode */ switch (size[0]) { diff --git a/qemu-img.texi b/qemu-img.texi index ced64a4..b2ca3a5 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -38,6 +38,17 @@ by the used format or see the format descriptions below for details. indicates that target image must be compressed (qcow format only) @item -h with or without a command shows help and lists the supported formats +@item -p +display progress bar (convert and rebase commands only) +@item -S @var{size} +indicates the consecutive number of bytes that must contain only zeros +for qemu-img to create a sparse image during conversion. This value is rounded +down to the nearest 512 bytes. You may use the common size suffixes like +@code{k} for kilobytes. +@item -t @var{cache} +specifies the cache mode that should be used with the (destination) file. See +the documentation of the emulator's @code{-drive cache=...} option for allowed +values. @end table Parameters to snapshot subcommand: @@ -80,11 +91,11 @@ this case. @var{backing_file} will never be modified unless you use the The size can also be specified using the @var{size} option with @code{-o}, it doesn't need to be specified separately in this case. -@item commit [-f @var{fmt}] @var{filename} +@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename} Commit the changes recorded in @var{filename} in its base image. -@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c} @@ -114,7 +125,7 @@ they are displayed too. List, apply, create or delete snapshots in image @var{filename}. -@item rebase [-f @var{fmt}] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} +@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} Changes the backing file of an image. Only the formats @code{qcow2} and @code{qed} support changing the backing file. @@ -173,12 +184,6 @@ Linux or NTFS on Windows), then only the written sectors will reserve space. Use @code{qemu-img info} to know the real size used by the image or @code{ls -ls} on Unix/Linux. -@item host_device - -Host device format. This format should be used instead of raw when -converting to block devices or other devices where "holes" are not -supported. - @item qcow2 QEMU image format, the most versatile format. Use it to have smaller images (useful if your filesystem does not supports holes, for example diff --git a/qemu-io.c b/qemu-io.c index 4470e49..de26422 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -20,7 +20,7 @@ #define VERSION "0.0.1" -#define CMD_NOFILE_OK 0x01 +#define CMD_NOFILE_OK 0x01 char *progname; static BlockDriverState *bs; @@ -35,16 +35,16 @@ static int misalign; */ static int parse_pattern(const char *arg) { - char *endptr = NULL; - long pattern; + char *endptr = NULL; + long pattern; - pattern = strtol(arg, &endptr, 0); - if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') { - printf("%s is not a valid pattern byte\n", arg); - return -1; - } + pattern = strtol(arg, &endptr, 0); + if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') { + printf("%s is not a valid pattern byte\n", arg); + return -1; + } - return pattern; + return pattern; } /* @@ -54,70 +54,73 @@ static int parse_pattern(const char *arg) * that is specified on the command line. */ -#define MISALIGN_OFFSET 16 +#define MISALIGN_OFFSET 16 static void *qemu_io_alloc(size_t len, int pattern) { - void *buf; - - if (misalign) - len += MISALIGN_OFFSET; - buf = qemu_blockalign(bs, len); - memset(buf, pattern, len); - if (misalign) - buf += MISALIGN_OFFSET; - return buf; + void *buf; + + if (misalign) { + len += MISALIGN_OFFSET; + } + buf = qemu_blockalign(bs, len); + memset(buf, pattern, len); + if (misalign) { + buf += MISALIGN_OFFSET; + } + return buf; } static void qemu_io_free(void *p) { - if (misalign) - p -= MISALIGN_OFFSET; - qemu_vfree(p); + if (misalign) { + p -= MISALIGN_OFFSET; + } + qemu_vfree(p); } -static void -dump_buffer(const void *buffer, int64_t offset, int len) +static void dump_buffer(const void *buffer, int64_t offset, int len) { - int i, j; - const uint8_t *p; - - for (i = 0, p = buffer; i < len; i += 16) { - const uint8_t *s = p; - - printf("%08" PRIx64 ": ", offset + i); - for (j = 0; j < 16 && i + j < len; j++, p++) - printf("%02x ", *p); - printf(" "); - for (j = 0; j < 16 && i + j < len; j++, s++) { - if (isalnum(*s)) - printf("%c", *s); - else - printf("."); - } - printf("\n"); - } + int i, j; + const uint8_t *p; + + for (i = 0, p = buffer; i < len; i += 16) { + const uint8_t *s = p; + + printf("%08" PRIx64 ": ", offset + i); + for (j = 0; j < 16 && i + j < len; j++, p++) { + printf("%02x ", *p); + } + printf(" "); + for (j = 0; j < 16 && i + j < len; j++, s++) { + if (isalnum(*s)) { + printf("%c", *s); + } else { + printf("."); + } + } + printf("\n"); + } } -static void -print_report(const char *op, struct timeval *t, int64_t offset, - int count, int total, int cnt, int Cflag) +static void print_report(const char *op, struct timeval *t, int64_t offset, + int count, int total, int cnt, int Cflag) { - char s1[64], s2[64], ts[64]; - - timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); - if (!Cflag) { - cvtstr((double)total, s1, sizeof(s1)); - cvtstr(tdiv((double)total, *t), s2, sizeof(s2)); - printf("%s %d/%d bytes at offset %" PRId64 "\n", - op, total, count, offset); - printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n", - s1, cnt, ts, s2, tdiv((double)cnt, *t)); - } else {/* bytes,ops,time,bytes/sec,ops/sec */ - printf("%d,%d,%s,%.3f,%.3f\n", - total, cnt, ts, - tdiv((double)total, *t), - tdiv((double)cnt, *t)); - } + char s1[64], s2[64], ts[64]; + + timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); + if (!Cflag) { + cvtstr((double)total, s1, sizeof(s1)); + cvtstr(tdiv((double)total, *t), s2, sizeof(s2)); + printf("%s %d/%d bytes at offset %" PRId64 "\n", + op, total, count, offset); + printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n", + s1, cnt, ts, s2, tdiv((double)cnt, *t)); + } else {/* bytes,ops,time,bytes/sec,ops/sec */ + printf("%d,%d,%s,%.3f,%.3f\n", + total, cnt, ts, + tdiv((double)total, *t), + tdiv((double)cnt, *t)); + } } /* @@ -127,192 +130,200 @@ print_report(const char *op, struct timeval *t, int64_t offset, static void * create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) { - size_t *sizes = calloc(nr_iov, sizeof(size_t)); - size_t count = 0; - void *buf = NULL; - void *p; - int i; - - for (i = 0; i < nr_iov; i++) { - char *arg = argv[i]; - int64_t len; - - len = cvtnum(arg); - if (len < 0) { - printf("non-numeric length argument -- %s\n", arg); - goto fail; - } - - /* should be SIZE_T_MAX, but that doesn't exist */ - if (len > INT_MAX) { - printf("too large length argument -- %s\n", arg); - goto fail; - } - - if (len & 0x1ff) { - printf("length argument %" PRId64 - " is not sector aligned\n", len); - goto fail; - } - - sizes[i] = len; - count += len; - } - - qemu_iovec_init(qiov, nr_iov); - - buf = p = qemu_io_alloc(count, pattern); - - for (i = 0; i < nr_iov; i++) { - qemu_iovec_add(qiov, p, sizes[i]); - p += sizes[i]; - } + size_t *sizes = calloc(nr_iov, sizeof(size_t)); + size_t count = 0; + void *buf = NULL; + void *p; + int i; + + for (i = 0; i < nr_iov; i++) { + char *arg = argv[i]; + int64_t len; + + len = cvtnum(arg); + if (len < 0) { + printf("non-numeric length argument -- %s\n", arg); + goto fail; + } + + /* should be SIZE_T_MAX, but that doesn't exist */ + if (len > INT_MAX) { + printf("too large length argument -- %s\n", arg); + goto fail; + } + + if (len & 0x1ff) { + printf("length argument %" PRId64 + " is not sector aligned\n", len); + goto fail; + } + + sizes[i] = len; + count += len; + } + + qemu_iovec_init(qiov, nr_iov); + + buf = p = qemu_io_alloc(count, pattern); + + for (i = 0; i < nr_iov; i++) { + qemu_iovec_add(qiov, p, sizes[i]); + p += sizes[i]; + } fail: - free(sizes); - return buf; + free(sizes); + return buf; } static int do_read(char *buf, int64_t offset, int count, int *total) { - int ret; + int ret; - ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9); - if (ret < 0) - return ret; - *total = count; - return 1; + ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9); + if (ret < 0) { + return ret; + } + *total = count; + return 1; } static int do_write(char *buf, int64_t offset, int count, int *total) { - int ret; + int ret; - ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9); - if (ret < 0) - return ret; - *total = count; - return 1; + ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9); + if (ret < 0) { + return ret; + } + *total = count; + return 1; } static int do_pread(char *buf, int64_t offset, int count, int *total) { - *total = bdrv_pread(bs, offset, (uint8_t *)buf, count); - if (*total < 0) - return *total; - return 1; + *total = bdrv_pread(bs, offset, (uint8_t *)buf, count); + if (*total < 0) { + return *total; + } + return 1; } static int do_pwrite(char *buf, int64_t offset, int count, int *total) { - *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count); - if (*total < 0) - return *total; - return 1; + *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count); + if (*total < 0) { + return *total; + } + return 1; } static int do_load_vmstate(char *buf, int64_t offset, int count, int *total) { - *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count); - if (*total < 0) - return *total; - return 1; + *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count); + if (*total < 0) { + return *total; + } + return 1; } static int do_save_vmstate(char *buf, int64_t offset, int count, int *total) { - *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count); - if (*total < 0) - return *total; - return 1; + *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count); + if (*total < 0) { + return *total; + } + return 1; } #define NOT_DONE 0x7fffffff static void aio_rw_done(void *opaque, int ret) { - *(int *)opaque = ret; + *(int *)opaque = ret; } static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total) { - BlockDriverAIOCB *acb; - int async_ret = NOT_DONE; + BlockDriverAIOCB *acb; + int async_ret = NOT_DONE; - acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9, - aio_rw_done, &async_ret); - if (!acb) - return -EIO; - - while (async_ret == NOT_DONE) - qemu_aio_wait(); + acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9, + aio_rw_done, &async_ret); + if (!acb) { + return -EIO; + } + while (async_ret == NOT_DONE) { + qemu_aio_wait(); + } - *total = qiov->size; - return async_ret < 0 ? async_ret : 1; + *total = qiov->size; + return async_ret < 0 ? async_ret : 1; } static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total) { - BlockDriverAIOCB *acb; - int async_ret = NOT_DONE; + BlockDriverAIOCB *acb; + int async_ret = NOT_DONE; - acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9, - aio_rw_done, &async_ret); - if (!acb) - return -EIO; + acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9, + aio_rw_done, &async_ret); + if (!acb) { + return -EIO; + } - while (async_ret == NOT_DONE) - qemu_aio_wait(); + while (async_ret == NOT_DONE) { + qemu_aio_wait(); + } - *total = qiov->size; - return async_ret < 0 ? async_ret : 1; + *total = qiov->size; + return async_ret < 0 ? async_ret : 1; } struct multiwrite_async_ret { - int num_done; - int error; + int num_done; + int error; }; static void multiwrite_cb(void *opaque, int ret) { - struct multiwrite_async_ret *async_ret = opaque; + struct multiwrite_async_ret *async_ret = opaque; - async_ret->num_done++; - if (ret < 0) { - async_ret->error = ret; - } + async_ret->num_done++; + if (ret < 0) { + async_ret->error = ret; + } } static int do_aio_multiwrite(BlockRequest* reqs, int num_reqs, int *total) { - int i, ret; - struct multiwrite_async_ret async_ret = { - .num_done = 0, - .error = 0, - }; - - *total = 0; - for (i = 0; i < num_reqs; i++) { - reqs[i].cb = multiwrite_cb; - reqs[i].opaque = &async_ret; - *total += reqs[i].qiov->size; - } - - ret = bdrv_aio_multiwrite(bs, reqs, num_reqs); - if (ret < 0) { - return ret; - } - - while (async_ret.num_done < num_reqs) { - qemu_aio_wait(); - } - - return async_ret.error < 0 ? async_ret.error : 1; + int i, ret; + struct multiwrite_async_ret async_ret = { + .num_done = 0, + .error = 0, + }; + + *total = 0; + for (i = 0; i < num_reqs; i++) { + reqs[i].cb = multiwrite_cb; + reqs[i].opaque = &async_ret; + *total += reqs[i].qiov->size; + } + + ret = bdrv_aio_multiwrite(bs, reqs, num_reqs); + if (ret < 0) { + return ret; + } + + while (async_ret.num_done < num_reqs) { + qemu_aio_wait(); + } + + return async_ret.error < 0 ? async_ret.error : 1; } -static void -read_help(void) +static void read_help(void) { - printf( + printf( "\n" " reads a range of bytes from the given offset\n" "\n" @@ -335,94 +346,95 @@ read_help(void) static int read_f(int argc, char **argv); static const cmdinfo_t read_cmd = { - .name = "read", - .altname = "r", - .cfunc = read_f, - .argmin = 2, - .argmax = -1, - .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len", - .oneline = "reads a number of bytes at a specified offset", - .help = read_help, + .name = "read", + .altname = "r", + .cfunc = read_f, + .argmin = 2, + .argmax = -1, + .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len", + .oneline = "reads a number of bytes at a specified offset", + .help = read_help, }; -static int -read_f(int argc, char **argv) +static int read_f(int argc, char **argv) { - struct timeval t1, t2; - int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; - int Pflag = 0, sflag = 0, lflag = 0, bflag = 0; - int c, cnt; - char *buf; - int64_t offset; - int count; - /* Some compilers get confused and warn if this is not initialized. */ - int total = 0; - int pattern = 0, pattern_offset = 0, pattern_count = 0; - - while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) { - switch (c) { - case 'b': - bflag = 1; - break; - case 'C': - Cflag = 1; - break; - case 'l': - lflag = 1; - pattern_count = cvtnum(optarg); - if (pattern_count < 0) { - printf("non-numeric length argument -- %s\n", optarg); - return 0; - } - break; - case 'p': - pflag = 1; - break; - case 'P': - Pflag = 1; - pattern = parse_pattern(optarg); - if (pattern < 0) - return 0; - break; - case 'q': - qflag = 1; - break; - case 's': - sflag = 1; - pattern_offset = cvtnum(optarg); - if (pattern_offset < 0) { - printf("non-numeric length argument -- %s\n", optarg); - return 0; - } - break; - case 'v': - vflag = 1; - break; - default: - return command_usage(&read_cmd); - } - } - - if (optind != argc - 2) - return command_usage(&read_cmd); - - if (bflag && pflag) { - printf("-b and -p cannot be specified at the same time\n"); - return 0; - } - - offset = cvtnum(argv[optind]); - if (offset < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } - - optind++; - count = cvtnum(argv[optind]); - if (count < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } + struct timeval t1, t2; + int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; + int Pflag = 0, sflag = 0, lflag = 0, bflag = 0; + int c, cnt; + char *buf; + int64_t offset; + int count; + /* Some compilers get confused and warn if this is not initialized. */ + int total = 0; + int pattern = 0, pattern_offset = 0, pattern_count = 0; + + while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) { + switch (c) { + case 'b': + bflag = 1; + break; + case 'C': + Cflag = 1; + break; + case 'l': + lflag = 1; + pattern_count = cvtnum(optarg); + if (pattern_count < 0) { + printf("non-numeric length argument -- %s\n", optarg); + return 0; + } + break; + case 'p': + pflag = 1; + break; + case 'P': + Pflag = 1; + pattern = parse_pattern(optarg); + if (pattern < 0) { + return 0; + } + break; + case 'q': + qflag = 1; + break; + case 's': + sflag = 1; + pattern_offset = cvtnum(optarg); + if (pattern_offset < 0) { + printf("non-numeric length argument -- %s\n", optarg); + return 0; + } + break; + case 'v': + vflag = 1; + break; + default: + return command_usage(&read_cmd); + } + } + + if (optind != argc - 2) { + return command_usage(&read_cmd); + } + + if (bflag && pflag) { + printf("-b and -p cannot be specified at the same time\n"); + return 0; + } + + offset = cvtnum(argv[optind]); + if (offset < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } + + optind++; + count = cvtnum(argv[optind]); + if (count < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } if (!Pflag && (lflag || sflag)) { return command_usage(&read_cmd); @@ -437,66 +449,68 @@ read_f(int argc, char **argv) return 0; } - if (!pflag) - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - - if (count & 0x1ff) { - printf("count %d is not sector aligned\n", - count); - return 0; - } - } - - buf = qemu_io_alloc(count, 0xab); - - gettimeofday(&t1, NULL); - if (pflag) - cnt = do_pread(buf, offset, count, &total); - else if (bflag) - cnt = do_load_vmstate(buf, offset, count, &total); - else - cnt = do_read(buf, offset, count, &total); - gettimeofday(&t2, NULL); - - if (cnt < 0) { - printf("read failed: %s\n", strerror(-cnt)); - goto out; - } - - if (Pflag) { - void* cmp_buf = malloc(pattern_count); - memset(cmp_buf, pattern, pattern_count); - if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) { - printf("Pattern verification failed at offset %" - PRId64 ", %d bytes\n", - offset + pattern_offset, pattern_count); - } - free(cmp_buf); - } - - if (qflag) - goto out; - - if (vflag) - dump_buffer(buf, offset, count); - - /* Finally, report back -- -C gives a parsable format */ - t2 = tsub(t2, t1); - print_report("read", &t2, offset, count, total, cnt, Cflag); + if (!pflag) { + if (offset & 0x1ff) { + printf("offset %" PRId64 " is not sector aligned\n", + offset); + return 0; + } + if (count & 0x1ff) { + printf("count %d is not sector aligned\n", + count); + return 0; + } + } + + buf = qemu_io_alloc(count, 0xab); + + gettimeofday(&t1, NULL); + if (pflag) { + cnt = do_pread(buf, offset, count, &total); + } else if (bflag) { + cnt = do_load_vmstate(buf, offset, count, &total); + } else { + cnt = do_read(buf, offset, count, &total); + } + gettimeofday(&t2, NULL); + + if (cnt < 0) { + printf("read failed: %s\n", strerror(-cnt)); + goto out; + } + + if (Pflag) { + void *cmp_buf = malloc(pattern_count); + memset(cmp_buf, pattern, pattern_count); + if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) { + printf("Pattern verification failed at offset %" + PRId64 ", %d bytes\n", + offset + pattern_offset, pattern_count); + } + free(cmp_buf); + } + + if (qflag) { + goto out; + } + + if (vflag) { + dump_buffer(buf, offset, count); + } + + /* Finally, report back -- -C gives a parsable format */ + t2 = tsub(t2, t1); + print_report("read", &t2, offset, count, total, cnt, Cflag); out: - qemu_io_free(buf); + qemu_io_free(buf); - return 0; + return 0; } -static void -readv_help(void) +static void readv_help(void) { - printf( + printf( "\n" " reads a range of bytes from the given offset into multiple buffers\n" "\n" @@ -516,111 +530,115 @@ readv_help(void) static int readv_f(int argc, char **argv); static const cmdinfo_t readv_cmd = { - .name = "readv", - .cfunc = readv_f, - .argmin = 2, - .argmax = -1, - .args = "[-Cqv] [-P pattern ] off len [len..]", - .oneline = "reads a number of bytes at a specified offset", - .help = readv_help, + .name = "readv", + .cfunc = readv_f, + .argmin = 2, + .argmax = -1, + .args = "[-Cqv] [-P pattern ] off len [len..]", + .oneline = "reads a number of bytes at a specified offset", + .help = readv_help, }; -static int -readv_f(int argc, char **argv) +static int readv_f(int argc, char **argv) { - struct timeval t1, t2; - int Cflag = 0, qflag = 0, vflag = 0; - int c, cnt; - char *buf; - int64_t offset; - /* Some compilers get confused and warn if this is not initialized. */ - int total = 0; - int nr_iov; - QEMUIOVector qiov; - int pattern = 0; - int Pflag = 0; - - while ((c = getopt(argc, argv, "CP:qv")) != EOF) { - switch (c) { - case 'C': - Cflag = 1; - break; - case 'P': - Pflag = 1; - pattern = parse_pattern(optarg); - if (pattern < 0) - return 0; - break; - case 'q': - qflag = 1; - break; - case 'v': - vflag = 1; - break; - default: - return command_usage(&readv_cmd); - } - } - - if (optind > argc - 2) - return command_usage(&readv_cmd); - - - offset = cvtnum(argv[optind]); - if (offset < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } - optind++; - - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - - nr_iov = argc - optind; - buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab); - - gettimeofday(&t1, NULL); - cnt = do_aio_readv(&qiov, offset, &total); - gettimeofday(&t2, NULL); - - if (cnt < 0) { - printf("readv failed: %s\n", strerror(-cnt)); - goto out; - } - - if (Pflag) { - void* cmp_buf = malloc(qiov.size); - memset(cmp_buf, pattern, qiov.size); - if (memcmp(buf, cmp_buf, qiov.size)) { - printf("Pattern verification failed at offset %" - PRId64 ", %zd bytes\n", - offset, qiov.size); - } - free(cmp_buf); - } - - if (qflag) - goto out; - - if (vflag) - dump_buffer(buf, offset, qiov.size); - - /* Finally, report back -- -C gives a parsable format */ - t2 = tsub(t2, t1); - print_report("read", &t2, offset, qiov.size, total, cnt, Cflag); + struct timeval t1, t2; + int Cflag = 0, qflag = 0, vflag = 0; + int c, cnt; + char *buf; + int64_t offset; + /* Some compilers get confused and warn if this is not initialized. */ + int total = 0; + int nr_iov; + QEMUIOVector qiov; + int pattern = 0; + int Pflag = 0; + + while ((c = getopt(argc, argv, "CP:qv")) != EOF) { + switch (c) { + case 'C': + Cflag = 1; + break; + case 'P': + Pflag = 1; + pattern = parse_pattern(optarg); + if (pattern < 0) { + return 0; + } + break; + case 'q': + qflag = 1; + break; + case 'v': + vflag = 1; + break; + default: + return command_usage(&readv_cmd); + } + } + + if (optind > argc - 2) { + return command_usage(&readv_cmd); + } + + + offset = cvtnum(argv[optind]); + if (offset < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } + optind++; + + if (offset & 0x1ff) { + printf("offset %" PRId64 " is not sector aligned\n", + offset); + return 0; + } + + nr_iov = argc - optind; + buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab); + if (buf == NULL) { + return 0; + } + + gettimeofday(&t1, NULL); + cnt = do_aio_readv(&qiov, offset, &total); + gettimeofday(&t2, NULL); + + if (cnt < 0) { + printf("readv failed: %s\n", strerror(-cnt)); + goto out; + } + + if (Pflag) { + void *cmp_buf = malloc(qiov.size); + memset(cmp_buf, pattern, qiov.size); + if (memcmp(buf, cmp_buf, qiov.size)) { + printf("Pattern verification failed at offset %" + PRId64 ", %zd bytes\n", offset, qiov.size); + } + free(cmp_buf); + } + + if (qflag) { + goto out; + } + + if (vflag) { + dump_buffer(buf, offset, qiov.size); + } + + /* Finally, report back -- -C gives a parsable format */ + t2 = tsub(t2, t1); + print_report("read", &t2, offset, qiov.size, total, cnt, Cflag); out: - qemu_io_free(buf); - return 0; + qemu_io_free(buf); + return 0; } -static void -write_help(void) +static void write_help(void) { - printf( + printf( "\n" " writes a range of bytes from the given offset\n" "\n" @@ -640,121 +658,124 @@ write_help(void) static int write_f(int argc, char **argv); static const cmdinfo_t write_cmd = { - .name = "write", - .altname = "w", - .cfunc = write_f, - .argmin = 2, - .argmax = -1, - .args = "[-abCpq] [-P pattern ] off len", - .oneline = "writes a number of bytes at a specified offset", - .help = write_help, + .name = "write", + .altname = "w", + .cfunc = write_f, + .argmin = 2, + .argmax = -1, + .args = "[-abCpq] [-P pattern ] off len", + .oneline = "writes a number of bytes at a specified offset", + .help = write_help, }; -static int -write_f(int argc, char **argv) +static int write_f(int argc, char **argv) { - struct timeval t1, t2; - int Cflag = 0, pflag = 0, qflag = 0, bflag = 0; - int c, cnt; - char *buf; - int64_t offset; - int count; - /* Some compilers get confused and warn if this is not initialized. */ - int total = 0; - int pattern = 0xcd; - - while ((c = getopt(argc, argv, "bCpP:q")) != EOF) { - switch (c) { - case 'b': - bflag = 1; - break; - case 'C': - Cflag = 1; - break; - case 'p': - pflag = 1; - break; - case 'P': - pattern = parse_pattern(optarg); - if (pattern < 0) - return 0; - break; - case 'q': - qflag = 1; - break; - default: - return command_usage(&write_cmd); - } - } - - if (optind != argc - 2) - return command_usage(&write_cmd); - - if (bflag && pflag) { - printf("-b and -p cannot be specified at the same time\n"); - return 0; - } - - offset = cvtnum(argv[optind]); - if (offset < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } - - optind++; - count = cvtnum(argv[optind]); - if (count < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } - - if (!pflag) { - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - - if (count & 0x1ff) { - printf("count %d is not sector aligned\n", - count); - return 0; - } - } - - buf = qemu_io_alloc(count, pattern); - - gettimeofday(&t1, NULL); - if (pflag) - cnt = do_pwrite(buf, offset, count, &total); - else if (bflag) - cnt = do_save_vmstate(buf, offset, count, &total); - else - cnt = do_write(buf, offset, count, &total); - gettimeofday(&t2, NULL); - - if (cnt < 0) { - printf("write failed: %s\n", strerror(-cnt)); - goto out; - } - - if (qflag) - goto out; - - /* Finally, report back -- -C gives a parsable format */ - t2 = tsub(t2, t1); - print_report("wrote", &t2, offset, count, total, cnt, Cflag); + struct timeval t1, t2; + int Cflag = 0, pflag = 0, qflag = 0, bflag = 0; + int c, cnt; + char *buf; + int64_t offset; + int count; + /* Some compilers get confused and warn if this is not initialized. */ + int total = 0; + int pattern = 0xcd; + + while ((c = getopt(argc, argv, "bCpP:q")) != EOF) { + switch (c) { + case 'b': + bflag = 1; + break; + case 'C': + Cflag = 1; + break; + case 'p': + pflag = 1; + break; + case 'P': + pattern = parse_pattern(optarg); + if (pattern < 0) { + return 0; + } + break; + case 'q': + qflag = 1; + break; + default: + return command_usage(&write_cmd); + } + } + + if (optind != argc - 2) { + return command_usage(&write_cmd); + } + + if (bflag && pflag) { + printf("-b and -p cannot be specified at the same time\n"); + return 0; + } + + offset = cvtnum(argv[optind]); + if (offset < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } + + optind++; + count = cvtnum(argv[optind]); + if (count < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } + + if (!pflag) { + if (offset & 0x1ff) { + printf("offset %" PRId64 " is not sector aligned\n", + offset); + return 0; + } + + if (count & 0x1ff) { + printf("count %d is not sector aligned\n", + count); + return 0; + } + } + + buf = qemu_io_alloc(count, pattern); + + gettimeofday(&t1, NULL); + if (pflag) { + cnt = do_pwrite(buf, offset, count, &total); + } else if (bflag) { + cnt = do_save_vmstate(buf, offset, count, &total); + } else { + cnt = do_write(buf, offset, count, &total); + } + gettimeofday(&t2, NULL); + + if (cnt < 0) { + printf("write failed: %s\n", strerror(-cnt)); + goto out; + } + + if (qflag) { + goto out; + } + + /* Finally, report back -- -C gives a parsable format */ + t2 = tsub(t2, t1); + print_report("wrote", &t2, offset, count, total, cnt, Cflag); out: - qemu_io_free(buf); + qemu_io_free(buf); - return 0; + return 0; } static void writev_help(void) { - printf( + printf( "\n" " writes a range of bytes from the given offset source from multiple buffers\n" "\n" @@ -772,96 +793,100 @@ writev_help(void) static int writev_f(int argc, char **argv); static const cmdinfo_t writev_cmd = { - .name = "writev", - .cfunc = writev_f, - .argmin = 2, - .argmax = -1, - .args = "[-Cq] [-P pattern ] off len [len..]", - .oneline = "writes a number of bytes at a specified offset", - .help = writev_help, + .name = "writev", + .cfunc = writev_f, + .argmin = 2, + .argmax = -1, + .args = "[-Cq] [-P pattern ] off len [len..]", + .oneline = "writes a number of bytes at a specified offset", + .help = writev_help, }; -static int -writev_f(int argc, char **argv) +static int writev_f(int argc, char **argv) { - struct timeval t1, t2; - int Cflag = 0, qflag = 0; - int c, cnt; - char *buf; - int64_t offset; - /* Some compilers get confused and warn if this is not initialized. */ - int total = 0; - int nr_iov; - int pattern = 0xcd; - QEMUIOVector qiov; - - while ((c = getopt(argc, argv, "CqP:")) != EOF) { - switch (c) { - case 'C': - Cflag = 1; - break; - case 'q': - qflag = 1; - break; - case 'P': - pattern = parse_pattern(optarg); - if (pattern < 0) - return 0; - break; - default: - return command_usage(&writev_cmd); - } - } - - if (optind > argc - 2) - return command_usage(&writev_cmd); - - offset = cvtnum(argv[optind]); - if (offset < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } - optind++; - - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - - nr_iov = argc - optind; - buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern); - - gettimeofday(&t1, NULL); - cnt = do_aio_writev(&qiov, offset, &total); - gettimeofday(&t2, NULL); - - if (cnt < 0) { - printf("writev failed: %s\n", strerror(-cnt)); - goto out; - } - - if (qflag) - goto out; - - /* Finally, report back -- -C gives a parsable format */ - t2 = tsub(t2, t1); - print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag); + struct timeval t1, t2; + int Cflag = 0, qflag = 0; + int c, cnt; + char *buf; + int64_t offset; + /* Some compilers get confused and warn if this is not initialized. */ + int total = 0; + int nr_iov; + int pattern = 0xcd; + QEMUIOVector qiov; + + while ((c = getopt(argc, argv, "CqP:")) != EOF) { + switch (c) { + case 'C': + Cflag = 1; + break; + case 'q': + qflag = 1; + break; + case 'P': + pattern = parse_pattern(optarg); + if (pattern < 0) { + return 0; + } + break; + default: + return command_usage(&writev_cmd); + } + } + + if (optind > argc - 2) { + return command_usage(&writev_cmd); + } + + offset = cvtnum(argv[optind]); + if (offset < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } + optind++; + + if (offset & 0x1ff) { + printf("offset %" PRId64 " is not sector aligned\n", + offset); + return 0; + } + + nr_iov = argc - optind; + buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern); + if (buf == NULL) { + return 0; + } + + gettimeofday(&t1, NULL); + cnt = do_aio_writev(&qiov, offset, &total); + gettimeofday(&t2, NULL); + + if (cnt < 0) { + printf("writev failed: %s\n", strerror(-cnt)); + goto out; + } + + if (qflag) { + goto out; + } + + /* Finally, report back -- -C gives a parsable format */ + t2 = tsub(t2, t1); + print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag); out: - qemu_io_free(buf); - return 0; + qemu_io_free(buf); + return 0; } -static void -multiwrite_help(void) +static void multiwrite_help(void) { - printf( + printf( "\n" " writes a range of bytes from the given offset source from multiple buffers,\n" " in a batch of requests that may be merged by qemu\n" "\n" " Example:\n" -" 'multiwrite 512 1k 1k ; 4k 1k' \n" +" 'multiwrite 512 1k 1k ; 4k 1k'\n" " writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n" "\n" " Writes into a segment of the currently open file, using a buffer\n" @@ -876,217 +901,223 @@ multiwrite_help(void) static int multiwrite_f(int argc, char **argv); static const cmdinfo_t multiwrite_cmd = { - .name = "multiwrite", - .cfunc = multiwrite_f, - .argmin = 2, - .argmax = -1, - .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]", - .oneline = "issues multiple write requests at once", - .help = multiwrite_help, + .name = "multiwrite", + .cfunc = multiwrite_f, + .argmin = 2, + .argmax = -1, + .args = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]", + .oneline = "issues multiple write requests at once", + .help = multiwrite_help, }; -static int -multiwrite_f(int argc, char **argv) +static int multiwrite_f(int argc, char **argv) { - struct timeval t1, t2; - int Cflag = 0, qflag = 0; - int c, cnt; - char **buf; - int64_t offset, first_offset = 0; - /* Some compilers get confused and warn if this is not initialized. */ - int total = 0; - int nr_iov; - int nr_reqs; - int pattern = 0xcd; - QEMUIOVector *qiovs; - int i; - BlockRequest *reqs; - - while ((c = getopt(argc, argv, "CqP:")) != EOF) { - switch (c) { - case 'C': - Cflag = 1; - break; - case 'q': - qflag = 1; - break; - case 'P': - pattern = parse_pattern(optarg); - if (pattern < 0) - return 0; - break; - default: - return command_usage(&writev_cmd); - } - } - - if (optind > argc - 2) - return command_usage(&writev_cmd); - - nr_reqs = 1; - for (i = optind; i < argc; i++) { - if (!strcmp(argv[i], ";")) { - nr_reqs++; - } - } - - reqs = qemu_malloc(nr_reqs * sizeof(*reqs)); - buf = qemu_malloc(nr_reqs * sizeof(*buf)); - qiovs = qemu_malloc(nr_reqs * sizeof(*qiovs)); - - for (i = 0; i < nr_reqs; i++) { - int j; - - /* Read the offset of the request */ - offset = cvtnum(argv[optind]); - if (offset < 0) { - printf("non-numeric offset argument -- %s\n", argv[optind]); - return 0; - } - optind++; - - if (offset & 0x1ff) { - printf("offset %lld is not sector aligned\n", - (long long)offset); - return 0; - } + struct timeval t1, t2; + int Cflag = 0, qflag = 0; + int c, cnt; + char **buf; + int64_t offset, first_offset = 0; + /* Some compilers get confused and warn if this is not initialized. */ + int total = 0; + int nr_iov; + int nr_reqs; + int pattern = 0xcd; + QEMUIOVector *qiovs; + int i; + BlockRequest *reqs; + + while ((c = getopt(argc, argv, "CqP:")) != EOF) { + switch (c) { + case 'C': + Cflag = 1; + break; + case 'q': + qflag = 1; + break; + case 'P': + pattern = parse_pattern(optarg); + if (pattern < 0) { + return 0; + } + break; + default: + return command_usage(&writev_cmd); + } + } + + if (optind > argc - 2) { + return command_usage(&writev_cmd); + } + + nr_reqs = 1; + for (i = optind; i < argc; i++) { + if (!strcmp(argv[i], ";")) { + nr_reqs++; + } + } + + reqs = g_malloc0(nr_reqs * sizeof(*reqs)); + buf = g_malloc0(nr_reqs * sizeof(*buf)); + qiovs = g_malloc(nr_reqs * sizeof(*qiovs)); + + for (i = 0; i < nr_reqs && optind < argc; i++) { + int j; + + /* Read the offset of the request */ + offset = cvtnum(argv[optind]); + if (offset < 0) { + printf("non-numeric offset argument -- %s\n", argv[optind]); + goto out; + } + optind++; + + if (offset & 0x1ff) { + printf("offset %lld is not sector aligned\n", + (long long)offset); + goto out; + } if (i == 0) { first_offset = offset; } - /* Read lengths for qiov entries */ - for (j = optind; j < argc; j++) { - if (!strcmp(argv[j], ";")) { - break; - } - } + /* Read lengths for qiov entries */ + for (j = optind; j < argc; j++) { + if (!strcmp(argv[j], ";")) { + break; + } + } - nr_iov = j - optind; + nr_iov = j - optind; - /* Build request */ - reqs[i].qiov = &qiovs[i]; - buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern); - reqs[i].sector = offset >> 9; - reqs[i].nb_sectors = reqs[i].qiov->size >> 9; + /* Build request */ + buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern); + if (buf[i] == NULL) { + goto out; + } - optind = j + 1; + reqs[i].qiov = &qiovs[i]; + reqs[i].sector = offset >> 9; + reqs[i].nb_sectors = reqs[i].qiov->size >> 9; - offset += reqs[i].qiov->size; - pattern++; - } + optind = j + 1; - gettimeofday(&t1, NULL); - cnt = do_aio_multiwrite(reqs, nr_reqs, &total); - gettimeofday(&t2, NULL); + pattern++; + } - if (cnt < 0) { - printf("aio_multiwrite failed: %s\n", strerror(-cnt)); - goto out; - } + /* If there were empty requests at the end, ignore them */ + nr_reqs = i; - if (qflag) - goto out; + gettimeofday(&t1, NULL); + cnt = do_aio_multiwrite(reqs, nr_reqs, &total); + gettimeofday(&t2, NULL); + + if (cnt < 0) { + printf("aio_multiwrite failed: %s\n", strerror(-cnt)); + goto out; + } - /* Finally, report back -- -C gives a parsable format */ - t2 = tsub(t2, t1); - print_report("wrote", &t2, first_offset, total, total, cnt, Cflag); + if (qflag) { + goto out; + } + + /* Finally, report back -- -C gives a parsable format */ + t2 = tsub(t2, t1); + print_report("wrote", &t2, first_offset, total, total, cnt, Cflag); out: - for (i = 0; i < nr_reqs; i++) { - qemu_io_free(buf[i]); - qemu_iovec_destroy(&qiovs[i]); - } - qemu_free(buf); - qemu_free(reqs); - qemu_free(qiovs); - return 0; + for (i = 0; i < nr_reqs; i++) { + qemu_io_free(buf[i]); + if (reqs[i].qiov != NULL) { + qemu_iovec_destroy(&qiovs[i]); + } + } + g_free(buf); + g_free(reqs); + g_free(qiovs); + return 0; } struct aio_ctx { - QEMUIOVector qiov; - int64_t offset; - char *buf; - int qflag; - int vflag; - int Cflag; - int Pflag; - int pattern; - struct timeval t1; + QEMUIOVector qiov; + int64_t offset; + char *buf; + int qflag; + int vflag; + int Cflag; + int Pflag; + int pattern; + struct timeval t1; }; -static void -aio_write_done(void *opaque, int ret) +static void aio_write_done(void *opaque, int ret) { - struct aio_ctx *ctx = opaque; - struct timeval t2; + struct aio_ctx *ctx = opaque; + struct timeval t2; - gettimeofday(&t2, NULL); + gettimeofday(&t2, NULL); - if (ret < 0) { - printf("aio_write failed: %s\n", strerror(-ret)); - goto out; - } + if (ret < 0) { + printf("aio_write failed: %s\n", strerror(-ret)); + goto out; + } - if (ctx->qflag) { - goto out; - } + if (ctx->qflag) { + goto out; + } - /* Finally, report back -- -C gives a parsable format */ - t2 = tsub(t2, ctx->t1); - print_report("wrote", &t2, ctx->offset, ctx->qiov.size, - ctx->qiov.size, 1, ctx->Cflag); + /* Finally, report back -- -C gives a parsable format */ + t2 = tsub(t2, ctx->t1); + print_report("wrote", &t2, ctx->offset, ctx->qiov.size, + ctx->qiov.size, 1, ctx->Cflag); out: - qemu_io_free(ctx->buf); - free(ctx); + qemu_io_free(ctx->buf); + free(ctx); } -static void -aio_read_done(void *opaque, int ret) +static void aio_read_done(void *opaque, int ret) { - struct aio_ctx *ctx = opaque; - struct timeval t2; - - gettimeofday(&t2, NULL); - - if (ret < 0) { - printf("readv failed: %s\n", strerror(-ret)); - goto out; - } - - if (ctx->Pflag) { - void *cmp_buf = malloc(ctx->qiov.size); - - memset(cmp_buf, ctx->pattern, ctx->qiov.size); - if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) { - printf("Pattern verification failed at offset %" - PRId64 ", %zd bytes\n", - ctx->offset, ctx->qiov.size); - } - free(cmp_buf); - } - - if (ctx->qflag) { - goto out; - } - - if (ctx->vflag) { - dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size); - } - - /* Finally, report back -- -C gives a parsable format */ - t2 = tsub(t2, ctx->t1); - print_report("read", &t2, ctx->offset, ctx->qiov.size, - ctx->qiov.size, 1, ctx->Cflag); + struct aio_ctx *ctx = opaque; + struct timeval t2; + + gettimeofday(&t2, NULL); + + if (ret < 0) { + printf("readv failed: %s\n", strerror(-ret)); + goto out; + } + + if (ctx->Pflag) { + void *cmp_buf = malloc(ctx->qiov.size); + + memset(cmp_buf, ctx->pattern, ctx->qiov.size); + if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) { + printf("Pattern verification failed at offset %" + PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size); + } + free(cmp_buf); + } + + if (ctx->qflag) { + goto out; + } + + if (ctx->vflag) { + dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size); + } + + /* Finally, report back -- -C gives a parsable format */ + t2 = tsub(t2, ctx->t1); + print_report("read", &t2, ctx->offset, ctx->qiov.size, + ctx->qiov.size, 1, ctx->Cflag); out: - qemu_io_free(ctx->buf); - free(ctx); + qemu_io_free(ctx->buf); + free(ctx); } -static void -aio_read_help(void) +static void aio_read_help(void) { - printf( + printf( "\n" " asynchronously reads a range of bytes from the given offset\n" "\n" @@ -1107,88 +1138,90 @@ aio_read_help(void) static int aio_read_f(int argc, char **argv); static const cmdinfo_t aio_read_cmd = { - .name = "aio_read", - .cfunc = aio_read_f, - .argmin = 2, - .argmax = -1, - .args = "[-Cqv] [-P pattern ] off len [len..]", - .oneline = "asynchronously reads a number of bytes", - .help = aio_read_help, + .name = "aio_read", + .cfunc = aio_read_f, + .argmin = 2, + .argmax = -1, + .args = "[-Cqv] [-P pattern ] off len [len..]", + .oneline = "asynchronously reads a number of bytes", + .help = aio_read_help, }; -static int -aio_read_f(int argc, char **argv) +static int aio_read_f(int argc, char **argv) { - int nr_iov, c; - struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx)); - BlockDriverAIOCB *acb; - - while ((c = getopt(argc, argv, "CP:qv")) != EOF) { - switch (c) { - case 'C': - ctx->Cflag = 1; - break; - case 'P': - ctx->Pflag = 1; - ctx->pattern = parse_pattern(optarg); - if (ctx->pattern < 0) { - free(ctx); - return 0; - } - break; - case 'q': - ctx->qflag = 1; - break; - case 'v': - ctx->vflag = 1; - break; - default: - free(ctx); - return command_usage(&aio_read_cmd); - } - } - - if (optind > argc - 2) { - free(ctx); - return command_usage(&aio_read_cmd); - } - - ctx->offset = cvtnum(argv[optind]); - if (ctx->offset < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - free(ctx); - return 0; - } - optind++; - - if (ctx->offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - ctx->offset); - free(ctx); - return 0; - } - - nr_iov = argc - optind; - ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab); - - gettimeofday(&ctx->t1, NULL); - acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov, - ctx->qiov.size >> 9, aio_read_done, ctx); - if (!acb) { - free(ctx->buf); - free(ctx); - return -EIO; - } - - return 0; + int nr_iov, c; + struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx)); + BlockDriverAIOCB *acb; + + while ((c = getopt(argc, argv, "CP:qv")) != EOF) { + switch (c) { + case 'C': + ctx->Cflag = 1; + break; + case 'P': + ctx->Pflag = 1; + ctx->pattern = parse_pattern(optarg); + if (ctx->pattern < 0) { + free(ctx); + return 0; + } + break; + case 'q': + ctx->qflag = 1; + break; + case 'v': + ctx->vflag = 1; + break; + default: + free(ctx); + return command_usage(&aio_read_cmd); + } + } + + if (optind > argc - 2) { + free(ctx); + return command_usage(&aio_read_cmd); + } + + ctx->offset = cvtnum(argv[optind]); + if (ctx->offset < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + free(ctx); + return 0; + } + optind++; + + if (ctx->offset & 0x1ff) { + printf("offset %" PRId64 " is not sector aligned\n", + ctx->offset); + free(ctx); + return 0; + } + + nr_iov = argc - optind; + ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab); + if (ctx->buf == NULL) { + free(ctx); + return 0; + } + + gettimeofday(&ctx->t1, NULL); + acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov, + ctx->qiov.size >> 9, aio_read_done, ctx); + if (!acb) { + free(ctx->buf); + free(ctx); + return -EIO; + } + + return 0; } -static void -aio_write_help(void) +static void aio_write_help(void) { - printf( + printf( "\n" -" asynchronously writes a range of bytes from the given offset source \n" +" asynchronously writes a range of bytes from the given offset source\n" " from multiple buffers\n" "\n" " Example:\n" @@ -1207,199 +1240,201 @@ aio_write_help(void) static int aio_write_f(int argc, char **argv); static const cmdinfo_t aio_write_cmd = { - .name = "aio_write", - .cfunc = aio_write_f, - .argmin = 2, - .argmax = -1, - .args = "[-Cq] [-P pattern ] off len [len..]", - .oneline = "asynchronously writes a number of bytes", - .help = aio_write_help, + .name = "aio_write", + .cfunc = aio_write_f, + .argmin = 2, + .argmax = -1, + .args = "[-Cq] [-P pattern ] off len [len..]", + .oneline = "asynchronously writes a number of bytes", + .help = aio_write_help, }; -static int -aio_write_f(int argc, char **argv) +static int aio_write_f(int argc, char **argv) { - int nr_iov, c; - int pattern = 0xcd; - struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx)); - BlockDriverAIOCB *acb; - - while ((c = getopt(argc, argv, "CqP:")) != EOF) { - switch (c) { - case 'C': - ctx->Cflag = 1; - break; - case 'q': - ctx->qflag = 1; - break; - case 'P': - pattern = parse_pattern(optarg); - if (pattern < 0) - return 0; - break; - default: - free(ctx); - return command_usage(&aio_write_cmd); - } - } - - if (optind > argc - 2) { - free(ctx); - return command_usage(&aio_write_cmd); - } - - ctx->offset = cvtnum(argv[optind]); - if (ctx->offset < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - free(ctx); - return 0; - } - optind++; - - if (ctx->offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - ctx->offset); - free(ctx); - return 0; - } - - nr_iov = argc - optind; - ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern); - - gettimeofday(&ctx->t1, NULL); - acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov, - ctx->qiov.size >> 9, aio_write_done, ctx); - if (!acb) { - free(ctx->buf); - free(ctx); - return -EIO; - } - - return 0; + int nr_iov, c; + int pattern = 0xcd; + struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx)); + BlockDriverAIOCB *acb; + + while ((c = getopt(argc, argv, "CqP:")) != EOF) { + switch (c) { + case 'C': + ctx->Cflag = 1; + break; + case 'q': + ctx->qflag = 1; + break; + case 'P': + pattern = parse_pattern(optarg); + if (pattern < 0) { + free(ctx); + return 0; + } + break; + default: + free(ctx); + return command_usage(&aio_write_cmd); + } + } + + if (optind > argc - 2) { + free(ctx); + return command_usage(&aio_write_cmd); + } + + ctx->offset = cvtnum(argv[optind]); + if (ctx->offset < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + free(ctx); + return 0; + } + optind++; + + if (ctx->offset & 0x1ff) { + printf("offset %" PRId64 " is not sector aligned\n", + ctx->offset); + free(ctx); + return 0; + } + + nr_iov = argc - optind; + ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern); + if (ctx->buf == NULL) { + free(ctx); + return 0; + } + + gettimeofday(&ctx->t1, NULL); + acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov, + ctx->qiov.size >> 9, aio_write_done, ctx); + if (!acb) { + free(ctx->buf); + free(ctx); + return -EIO; + } + + return 0; } -static int -aio_flush_f(int argc, char **argv) +static int aio_flush_f(int argc, char **argv) { - qemu_aio_flush(); - return 0; + qemu_aio_flush(); + return 0; } static const cmdinfo_t aio_flush_cmd = { - .name = "aio_flush", - .cfunc = aio_flush_f, - .oneline = "completes all outstanding aio requests" + .name = "aio_flush", + .cfunc = aio_flush_f, + .oneline = "completes all outstanding aio requests" }; -static int -flush_f(int argc, char **argv) +static int flush_f(int argc, char **argv) { - bdrv_flush(bs); - return 0; + bdrv_flush(bs); + return 0; } static const cmdinfo_t flush_cmd = { - .name = "flush", - .altname = "f", - .cfunc = flush_f, - .oneline = "flush all in-core file state to disk", + .name = "flush", + .altname = "f", + .cfunc = flush_f, + .oneline = "flush all in-core file state to disk", }; -static int -truncate_f(int argc, char **argv) +static int truncate_f(int argc, char **argv) { - int64_t offset; - int ret; - - offset = cvtnum(argv[1]); - if (offset < 0) { - printf("non-numeric truncate argument -- %s\n", argv[1]); - return 0; - } - - ret = bdrv_truncate(bs, offset); - if (ret < 0) { - printf("truncate: %s\n", strerror(-ret)); - return 0; - } - - return 0; + int64_t offset; + int ret; + + offset = cvtnum(argv[1]); + if (offset < 0) { + printf("non-numeric truncate argument -- %s\n", argv[1]); + return 0; + } + + ret = bdrv_truncate(bs, offset); + if (ret < 0) { + printf("truncate: %s\n", strerror(-ret)); + return 0; + } + + return 0; } static const cmdinfo_t truncate_cmd = { - .name = "truncate", - .altname = "t", - .cfunc = truncate_f, - .argmin = 1, - .argmax = 1, - .args = "off", - .oneline = "truncates the current file at the given offset", + .name = "truncate", + .altname = "t", + .cfunc = truncate_f, + .argmin = 1, + .argmax = 1, + .args = "off", + .oneline = "truncates the current file at the given offset", }; -static int -length_f(int argc, char **argv) +static int length_f(int argc, char **argv) { - int64_t size; - char s1[64]; - - size = bdrv_getlength(bs); - if (size < 0) { - printf("getlength: %s\n", strerror(-size)); - return 0; - } - - cvtstr(size, s1, sizeof(s1)); - printf("%s\n", s1); - return 0; + int64_t size; + char s1[64]; + + size = bdrv_getlength(bs); + if (size < 0) { + printf("getlength: %s\n", strerror(-size)); + return 0; + } + + cvtstr(size, s1, sizeof(s1)); + printf("%s\n", s1); + return 0; } static const cmdinfo_t length_cmd = { - .name = "length", - .altname = "l", - .cfunc = length_f, - .oneline = "gets the length of the current file", + .name = "length", + .altname = "l", + .cfunc = length_f, + .oneline = "gets the length of the current file", }; -static int -info_f(int argc, char **argv) +static int info_f(int argc, char **argv) { - BlockDriverInfo bdi; - char s1[64], s2[64]; - int ret; + BlockDriverInfo bdi; + char s1[64], s2[64]; + int ret; - if (bs->drv && bs->drv->format_name) - printf("format name: %s\n", bs->drv->format_name); - if (bs->drv && bs->drv->protocol_name) - printf("format name: %s\n", bs->drv->protocol_name); + if (bs->drv && bs->drv->format_name) { + printf("format name: %s\n", bs->drv->format_name); + } + if (bs->drv && bs->drv->protocol_name) { + printf("format name: %s\n", bs->drv->protocol_name); + } - ret = bdrv_get_info(bs, &bdi); - if (ret) - return 0; + ret = bdrv_get_info(bs, &bdi); + if (ret) { + return 0; + } - cvtstr(bdi.cluster_size, s1, sizeof(s1)); - cvtstr(bdi.vm_state_offset, s2, sizeof(s2)); + cvtstr(bdi.cluster_size, s1, sizeof(s1)); + cvtstr(bdi.vm_state_offset, s2, sizeof(s2)); - printf("cluster size: %s\n", s1); - printf("vm state offset: %s\n", s2); + printf("cluster size: %s\n", s1); + printf("vm state offset: %s\n", s2); - return 0; + return 0; } static const cmdinfo_t info_cmd = { - .name = "info", - .altname = "i", - .cfunc = info_f, - .oneline = "prints information about the current file", + .name = "info", + .altname = "i", + .cfunc = info_f, + .oneline = "prints information about the current file", }; -static void -discard_help(void) +static void discard_help(void) { - printf( + printf( "\n" " discards a range of bytes from the given offset\n" "\n" @@ -1415,148 +1450,147 @@ discard_help(void) static int discard_f(int argc, char **argv); static const cmdinfo_t discard_cmd = { - .name = "discard", - .altname = "d", - .cfunc = discard_f, - .argmin = 2, - .argmax = -1, - .args = "[-Cq] off len", - .oneline = "discards a number of bytes at a specified offset", - .help = discard_help, + .name = "discard", + .altname = "d", + .cfunc = discard_f, + .argmin = 2, + .argmax = -1, + .args = "[-Cq] off len", + .oneline = "discards a number of bytes at a specified offset", + .help = discard_help, }; -static int -discard_f(int argc, char **argv) +static int discard_f(int argc, char **argv) { - struct timeval t1, t2; - int Cflag = 0, qflag = 0; - int c, ret; - int64_t offset; - int count; - - while ((c = getopt(argc, argv, "Cq")) != EOF) { - switch (c) { - case 'C': - Cflag = 1; - break; - case 'q': - qflag = 1; - break; - default: - return command_usage(&discard_cmd); - } - } - - if (optind != argc - 2) { - return command_usage(&discard_cmd); - } - - offset = cvtnum(argv[optind]); - if (offset < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } - - optind++; - count = cvtnum(argv[optind]); - if (count < 0) { - printf("non-numeric length argument -- %s\n", argv[optind]); - return 0; - } - - gettimeofday(&t1, NULL); - ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS, count >> BDRV_SECTOR_BITS); - gettimeofday(&t2, NULL); - - if (ret < 0) { - printf("discard failed: %s\n", strerror(-ret)); - goto out; - } - - /* Finally, report back -- -C gives a parsable format */ - if (!qflag) { - t2 = tsub(t2, t1); - print_report("discard", &t2, offset, count, count, 1, Cflag); - } + struct timeval t1, t2; + int Cflag = 0, qflag = 0; + int c, ret; + int64_t offset; + int count; + + while ((c = getopt(argc, argv, "Cq")) != EOF) { + switch (c) { + case 'C': + Cflag = 1; + break; + case 'q': + qflag = 1; + break; + default: + return command_usage(&discard_cmd); + } + } + + if (optind != argc - 2) { + return command_usage(&discard_cmd); + } + + offset = cvtnum(argv[optind]); + if (offset < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } + + optind++; + count = cvtnum(argv[optind]); + if (count < 0) { + printf("non-numeric length argument -- %s\n", argv[optind]); + return 0; + } + + gettimeofday(&t1, NULL); + ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS, + count >> BDRV_SECTOR_BITS); + gettimeofday(&t2, NULL); + + if (ret < 0) { + printf("discard failed: %s\n", strerror(-ret)); + goto out; + } + + /* Finally, report back -- -C gives a parsable format */ + if (!qflag) { + t2 = tsub(t2, t1); + print_report("discard", &t2, offset, count, count, 1, Cflag); + } out: - return 0; + return 0; } -static int -alloc_f(int argc, char **argv) +static int alloc_f(int argc, char **argv) { - int64_t offset; - int nb_sectors, remaining; - char s1[64]; - int num, sum_alloc; - int ret; - - offset = cvtnum(argv[1]); - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - - if (argc == 3) - nb_sectors = cvtnum(argv[2]); - else - nb_sectors = 1; - - remaining = nb_sectors; - sum_alloc = 0; - while (remaining) { - ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num); - remaining -= num; - if (ret) { - sum_alloc += num; - } - } - - cvtstr(offset, s1, sizeof(s1)); - - printf("%d/%d sectors allocated at offset %s\n", - sum_alloc, nb_sectors, s1); - return 0; + int64_t offset; + int nb_sectors, remaining; + char s1[64]; + int num, sum_alloc; + int ret; + + offset = cvtnum(argv[1]); + if (offset & 0x1ff) { + printf("offset %" PRId64 " is not sector aligned\n", + offset); + return 0; + } + + if (argc == 3) { + nb_sectors = cvtnum(argv[2]); + } else { + nb_sectors = 1; + } + + remaining = nb_sectors; + sum_alloc = 0; + while (remaining) { + ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num); + remaining -= num; + if (ret) { + sum_alloc += num; + } + } + + cvtstr(offset, s1, sizeof(s1)); + + printf("%d/%d sectors allocated at offset %s\n", + sum_alloc, nb_sectors, s1); + return 0; } static const cmdinfo_t alloc_cmd = { - .name = "alloc", - .altname = "a", - .argmin = 1, - .argmax = 2, - .cfunc = alloc_f, - .args = "off [sectors]", - .oneline = "checks if a sector is present in the file", + .name = "alloc", + .altname = "a", + .argmin = 1, + .argmax = 2, + .cfunc = alloc_f, + .args = "off [sectors]", + .oneline = "checks if a sector is present in the file", }; -static int -map_f(int argc, char **argv) +static int map_f(int argc, char **argv) { - int64_t offset; - int64_t nb_sectors; - char s1[64]; - int num, num_checked; - int ret; - const char *retstr; - - offset = 0; - nb_sectors = bs->total_sectors; - - do { - num_checked = MIN(nb_sectors, INT_MAX); - ret = bdrv_is_allocated(bs, offset, num_checked, &num); - retstr = ret ? " allocated" : "not allocated"; - cvtstr(offset << 9ULL, s1, sizeof(s1)); - printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n", - offset << 9ULL, num, num_checked, retstr, s1, ret); - - offset += num; - nb_sectors -= num; - } while(offset < bs->total_sectors); - - return 0; + int64_t offset; + int64_t nb_sectors; + char s1[64]; + int num, num_checked; + int ret; + const char *retstr; + + offset = 0; + nb_sectors = bs->total_sectors; + + do { + num_checked = MIN(nb_sectors, INT_MAX); + ret = bdrv_is_allocated(bs, offset, num_checked, &num); + retstr = ret ? " allocated" : "not allocated"; + cvtstr(offset << 9ULL, s1, sizeof(s1)); + printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n", + offset << 9ULL, num, num_checked, retstr, s1, ret); + + offset += num; + nb_sectors -= num; + } while (offset < bs->total_sectors); + + return 0; } static const cmdinfo_t map_cmd = { @@ -1569,50 +1603,49 @@ static const cmdinfo_t map_cmd = { }; -static int -close_f(int argc, char **argv) +static int close_f(int argc, char **argv) { - bdrv_close(bs); - bs = NULL; - return 0; + bdrv_delete(bs); + bs = NULL; + return 0; } static const cmdinfo_t close_cmd = { - .name = "close", - .altname = "c", - .cfunc = close_f, - .oneline = "close the current open file", + .name = "close", + .altname = "c", + .cfunc = close_f, + .oneline = "close the current open file", }; static int openfile(char *name, int flags, int growable) { - if (bs) { - fprintf(stderr, "file open already, try 'help close'\n"); - return 1; - } - - if (growable) { - if (bdrv_file_open(&bs, name, flags)) { - fprintf(stderr, "%s: can't open device %s\n", progname, name); - return 1; - } - } else { - bs = bdrv_new("hda"); - - if (bdrv_open(bs, name, flags, NULL) < 0) { - fprintf(stderr, "%s: can't open device %s\n", progname, name); - bs = NULL; - return 1; - } - } - - return 0; + if (bs) { + fprintf(stderr, "file open already, try 'help close'\n"); + return 1; + } + + if (growable) { + if (bdrv_file_open(&bs, name, flags)) { + fprintf(stderr, "%s: can't open device %s\n", progname, name); + return 1; + } + } else { + bs = bdrv_new("hda"); + + if (bdrv_open(bs, name, flags, NULL) < 0) { + fprintf(stderr, "%s: can't open device %s\n", progname, name); + bdrv_delete(bs); + bs = NULL; + return 1; + } + } + + return 0; } -static void -open_help(void) +static void open_help(void) { - printf( + printf( "\n" " opens a new file in the requested mode\n" "\n" @@ -1630,80 +1663,78 @@ open_help(void) static int open_f(int argc, char **argv); static const cmdinfo_t open_cmd = { - .name = "open", - .altname = "o", - .cfunc = open_f, - .argmin = 1, - .argmax = -1, - .flags = CMD_NOFILE_OK, - .args = "[-Crsn] [path]", - .oneline = "open the file specified by path", - .help = open_help, + .name = "open", + .altname = "o", + .cfunc = open_f, + .argmin = 1, + .argmax = -1, + .flags = CMD_NOFILE_OK, + .args = "[-Crsn] [path]", + .oneline = "open the file specified by path", + .help = open_help, }; -static int -open_f(int argc, char **argv) +static int open_f(int argc, char **argv) { - int flags = 0; - int readonly = 0; - int growable = 0; - int c; - - while ((c = getopt(argc, argv, "snrg")) != EOF) { - switch (c) { - case 's': - flags |= BDRV_O_SNAPSHOT; - break; - case 'n': - flags |= BDRV_O_NOCACHE; - break; - case 'r': - readonly = 1; - break; - case 'g': - growable = 1; - break; - default: - return command_usage(&open_cmd); - } - } - - if (!readonly) { - flags |= BDRV_O_RDWR; + int flags = 0; + int readonly = 0; + int growable = 0; + int c; + + while ((c = getopt(argc, argv, "snrg")) != EOF) { + switch (c) { + case 's': + flags |= BDRV_O_SNAPSHOT; + break; + case 'n': + flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; + break; + case 'r': + readonly = 1; + break; + case 'g': + growable = 1; + break; + default: + return command_usage(&open_cmd); } + } - if (optind != argc - 1) - return command_usage(&open_cmd); + if (!readonly) { + flags |= BDRV_O_RDWR; + } + + if (optind != argc - 1) { + return command_usage(&open_cmd); + } - return openfile(argv[optind], flags, growable); + return openfile(argv[optind], flags, growable); } -static int -init_args_command( - int index) +static int init_args_command(int index) { - /* only one device allowed so far */ - if (index >= 1) - return 0; - return ++index; + /* only one device allowed so far */ + if (index >= 1) { + return 0; + } + return ++index; } -static int -init_check_command( - const cmdinfo_t *ct) +static int init_check_command(const cmdinfo_t *ct) { - if (ct->flags & CMD_FLAG_GLOBAL) - return 1; - if (!(ct->flags & CMD_NOFILE_OK) && !bs) { - fprintf(stderr, "no file open, try 'help open'\n"); - return 0; - } - return 1; + if (ct->flags & CMD_FLAG_GLOBAL) { + return 1; + } + if (!(ct->flags & CMD_NOFILE_OK) && !bs) { + fprintf(stderr, "no file open, try 'help open'\n"); + return 0; + } + return 1; } static void usage(const char *name) { - printf( + printf( "Usage: %s [-h] [-V] [-rsnm] [-c cmd] ... [file]\n" "QEMU Disk exerciser\n" "\n" @@ -1717,115 +1748,117 @@ static void usage(const char *name) " -h, --help display this help and exit\n" " -V, --version output version information and exit\n" "\n", - name); + name); } int main(int argc, char **argv) { - int readonly = 0; - int growable = 0; - const char *sopt = "hVc:rsnmgk"; - const struct option lopt[] = { - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { "offset", 1, NULL, 'o' }, - { "cmd", 1, NULL, 'c' }, - { "read-only", 0, NULL, 'r' }, - { "snapshot", 0, NULL, 's' }, - { "nocache", 0, NULL, 'n' }, - { "misalign", 0, NULL, 'm' }, - { "growable", 0, NULL, 'g' }, - { "native-aio", 0, NULL, 'k' }, - { NULL, 0, NULL, 0 } - }; - int c; - int opt_index = 0; - int flags = 0; - - progname = basename(argv[0]); - - while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) { - switch (c) { - case 's': - flags |= BDRV_O_SNAPSHOT; - break; - case 'n': - flags |= BDRV_O_NOCACHE; - break; - case 'c': - add_user_command(optarg); - break; - case 'r': - readonly = 1; - break; - case 'm': - misalign = 1; - break; - case 'g': - growable = 1; - break; - case 'k': - flags |= BDRV_O_NATIVE_AIO; - break; - case 'V': - printf("%s version %s\n", progname, VERSION); - exit(0); - case 'h': - usage(progname); - exit(0); - default: - usage(progname); - exit(1); - } - } - - if ((argc - optind) > 1) { - usage(progname); - exit(1); - } - - bdrv_init(); - - /* initialize commands */ - quit_init(); - help_init(); - add_command(&open_cmd); - add_command(&close_cmd); - add_command(&read_cmd); - add_command(&readv_cmd); - add_command(&write_cmd); - add_command(&writev_cmd); - add_command(&multiwrite_cmd); - add_command(&aio_read_cmd); - add_command(&aio_write_cmd); - add_command(&aio_flush_cmd); - add_command(&flush_cmd); - add_command(&truncate_cmd); - add_command(&length_cmd); - add_command(&info_cmd); - add_command(&discard_cmd); - add_command(&alloc_cmd); - add_command(&map_cmd); - - add_args_command(init_args_command); - add_check_command(init_check_command); - - /* open the device */ - if (!readonly) { - flags |= BDRV_O_RDWR; + int readonly = 0; + int growable = 0; + const char *sopt = "hVc:rsnmgk"; + const struct option lopt[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "offset", 1, NULL, 'o' }, + { "cmd", 1, NULL, 'c' }, + { "read-only", 0, NULL, 'r' }, + { "snapshot", 0, NULL, 's' }, + { "nocache", 0, NULL, 'n' }, + { "misalign", 0, NULL, 'm' }, + { "growable", 0, NULL, 'g' }, + { "native-aio", 0, NULL, 'k' }, + { NULL, 0, NULL, 0 } + }; + int c; + int opt_index = 0; + int flags = 0; + + progname = basename(argv[0]); + + while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) { + switch (c) { + case 's': + flags |= BDRV_O_SNAPSHOT; + break; + case 'n': + flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; + break; + case 'c': + add_user_command(optarg); + break; + case 'r': + readonly = 1; + break; + case 'm': + misalign = 1; + break; + case 'g': + growable = 1; + break; + case 'k': + flags |= BDRV_O_NATIVE_AIO; + break; + case 'V': + printf("%s version %s\n", progname, VERSION); + exit(0); + case 'h': + usage(progname); + exit(0); + default: + usage(progname); + exit(1); } + } + + if ((argc - optind) > 1) { + usage(progname); + exit(1); + } - if ((argc - optind) == 1) - openfile(argv[optind], flags, growable); - command_loop(); + bdrv_init(); + + /* initialize commands */ + quit_init(); + help_init(); + add_command(&open_cmd); + add_command(&close_cmd); + add_command(&read_cmd); + add_command(&readv_cmd); + add_command(&write_cmd); + add_command(&writev_cmd); + add_command(&multiwrite_cmd); + add_command(&aio_read_cmd); + add_command(&aio_write_cmd); + add_command(&aio_flush_cmd); + add_command(&flush_cmd); + add_command(&truncate_cmd); + add_command(&length_cmd); + add_command(&info_cmd); + add_command(&discard_cmd); + add_command(&alloc_cmd); + add_command(&map_cmd); + + add_args_command(init_args_command); + add_check_command(init_check_command); + + /* open the device */ + if (!readonly) { + flags |= BDRV_O_RDWR; + } + + if ((argc - optind) == 1) { + openfile(argv[optind], flags, growable); + } + command_loop(); - /* - * Make sure all outstanding requests get flushed the program exits. - */ - qemu_aio_flush(); + /* + * Make sure all outstanding requests get flushed the program exits. + */ + qemu_aio_flush(); - if (bs) - bdrv_close(bs); - return 0; + if (bs) { + bdrv_delete(bs); + } + return 0; } diff --git a/qemu-lock.h b/qemu-lock.h index 65ca084..a72edda 100644 --- a/qemu-lock.h +++ b/qemu-lock.h @@ -15,15 +15,11 @@ * License along with this library; if not, see */ -/* Locking primitives. Most of this code should be redundant - - system emulation doesn't need/use locking, NPTL userspace uses - pthread mutexes, and non-NPTL userspace isn't threadsafe anyway. - In either case a spinlock is probably the wrong kind of lock. - Spinlocks are only good if you know annother CPU has the lock and is - likely to release it soon. In environments where you have more threads - than physical CPUs (the extreme case being a single CPU host) a spinlock - simply wastes CPU until the OS decides to preempt it. */ -#if defined(CONFIG_USE_NPTL) +/* configure guarantees us that we have pthreads on any host except + * mingw32, which doesn't support any of the user-only targets. + * So we can simply assume we have pthread mutexes here. + */ +#if defined(CONFIG_USER_ONLY) #include #define spin_lock pthread_mutex_lock @@ -33,198 +29,15 @@ #else -#if defined(__hppa__) - -typedef int spinlock_t[4]; - -#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } - -static inline void resetlock (spinlock_t *p) -{ - (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; -} - -#else - +/* Empty implementations, on the theory that system mode emulation + * is single-threaded. This means that these functions should only + * be used from code run in the TCG cpu thread, and cannot protect + * data structures which might also be accessed from the IO thread + * or from signal handlers. + */ typedef int spinlock_t; - #define SPIN_LOCK_UNLOCKED 0 -static inline void resetlock (spinlock_t *p) -{ - *p = SPIN_LOCK_UNLOCKED; -} - -#endif - -#if defined(_ARCH_PPC) -static inline int testandset (int *p) -{ - int ret; - __asm__ __volatile__ ( - " lwarx %0,0,%1\n" - " xor. %0,%3,%0\n" - " bne $+12\n" - " stwcx. %2,0,%1\n" - " bne- $-16\n" - : "=&r" (ret) - : "r" (p), "r" (1), "r" (0) - : "cr0", "memory"); - return ret; -} -#elif defined(__i386__) -static inline int testandset (int *p) -{ - long int readval = 0; - - __asm__ __volatile__ ("lock; cmpxchgl %2, %0" - : "+m" (*p), "+a" (readval) - : "r" (1) - : "cc"); - return readval; -} -#elif defined(__x86_64__) -static inline int testandset (int *p) -{ - long int readval = 0; - - __asm__ __volatile__ ("lock; cmpxchgl %2, %0" - : "+m" (*p), "+a" (readval) - : "r" (1) - : "cc"); - return readval; -} -#elif defined(__s390__) -static inline int testandset (int *p) -{ - int ret; - - __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" - " jl 0b" - : "=&d" (ret) - : "r" (1), "a" (p), "0" (*p) - : "cc", "memory" ); - return ret; -} -#elif defined(__alpha__) -static inline int testandset (int *p) -{ - int ret; - unsigned long one; - - __asm__ __volatile__ ("0: mov 1,%2\n" - " ldl_l %0,%1\n" - " stl_c %2,%1\n" - " beq %2,1f\n" - ".subsection 2\n" - "1: br 0b\n" - ".previous" - : "=r" (ret), "=m" (*p), "=r" (one) - : "m" (*p)); - return ret; -} -#elif defined(__sparc__) -static inline int testandset (int *p) -{ - int ret; - - __asm__ __volatile__("ldstub [%1], %0" - : "=r" (ret) - : "r" (p) - : "memory"); - - return (ret ? 1 : 0); -} -#elif defined(__arm__) -static inline int testandset (int *spinlock) -{ - register unsigned int ret; - __asm__ __volatile__("swp %0, %1, [%2]" - : "=r"(ret) - : "0"(1), "r"(spinlock)); - - return ret; -} -#elif defined(__mc68000) -static inline int testandset (int *p) -{ - char ret; - __asm__ __volatile__("tas %1; sne %0" - : "=r" (ret) - : "m" (p) - : "cc","memory"); - return ret; -} -#elif defined(__hppa__) - -/* Because malloc only guarantees 8-byte alignment for malloc'd data, - and GCC only guarantees 8-byte alignment for stack locals, we can't - be assured of 16-byte alignment for atomic lock data even if we - specify "__attribute ((aligned(16)))" in the type declaration. So, - we use a struct containing an array of four ints for the atomic lock - type and dynamically select the 16-byte aligned int from the array - for the semaphore. */ -#define __PA_LDCW_ALIGNMENT 16 -static inline void *ldcw_align (void *p) { - unsigned long a = (unsigned long)p; - a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); - return (void *)a; -} - -static inline int testandset (spinlock_t *p) -{ - unsigned int ret; - p = ldcw_align(p); - __asm__ __volatile__("ldcw 0(%1),%0" - : "=r" (ret) - : "r" (p) - : "memory" ); - return !ret; -} - -#elif defined(__ia64) - -#include - -static inline int testandset (int *p) -{ - return __sync_lock_test_and_set (p, 1); -} -#elif defined(__mips__) -static inline int testandset (int *p) -{ - int ret; - - __asm__ __volatile__ ( - " .set push \n" - " .set noat \n" - " .set mips2 \n" - "1: li $1, 1 \n" - " ll %0, %1 \n" - " sc $1, %1 \n" - " beqz $1, 1b \n" - " .set pop " - : "=r" (ret), "+R" (*p) - : - : "memory"); - - return ret; -} -#else -#error unimplemented CPU support -#endif - -#if defined(CONFIG_USER_ONLY) -static inline void spin_lock(spinlock_t *lock) -{ - while (testandset(lock)); -} - -static inline void spin_unlock(spinlock_t *lock) -{ - resetlock(lock); -} -#else static inline void spin_lock(spinlock_t *lock) { } @@ -232,6 +45,5 @@ static inline void spin_lock(spinlock_t *lock) static inline void spin_unlock(spinlock_t *lock) { } -#endif #endif diff --git a/qemu-malloc.c b/qemu-malloc.c deleted file mode 100644 index b9b3851..0000000 --- a/qemu-malloc.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * malloc-like functions for system emulation. - * - * Copyright (c) 2006 Fabrice Bellard - * - * 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 AUTHORS OR 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. - */ -#include "qemu-common.h" -#include "trace.h" -#include - -void qemu_free(void *ptr) -{ - trace_qemu_free(ptr); - free(ptr); -} - -static int allow_zero_malloc(void) -{ -#if defined(CONFIG_ZERO_MALLOC) - return 1; -#else - return 0; -#endif -} - -void *qemu_malloc(size_t size) -{ - void *ptr; - if (!size && !allow_zero_malloc()) { - abort(); - } - ptr = qemu_oom_check(malloc(size ? size : 1)); - trace_qemu_malloc(size, ptr); - return ptr; -} - -void *qemu_realloc(void *ptr, size_t size) -{ - void *newptr; - if (!size && !allow_zero_malloc()) { - abort(); - } - newptr = qemu_oom_check(realloc(ptr, size ? size : 1)); - trace_qemu_realloc(ptr, size, newptr); - return newptr; -} - -void *qemu_mallocz(size_t size) -{ - void *ptr; - if (!size && !allow_zero_malloc()) { - abort(); - } - ptr = qemu_oom_check(calloc(1, size ? size : 1)); - trace_qemu_malloc(size, ptr); - return ptr; -} - -char *qemu_strdup(const char *str) -{ - char *ptr; - size_t len = strlen(str); - ptr = qemu_malloc(len + 1); - memcpy(ptr, str, len + 1); - return ptr; -} - -char *qemu_strndup(const char *str, size_t size) -{ - const char *end = memchr(str, 0, size); - char *new; - - if (end) { - size = end - str; - } - - new = qemu_malloc(size + 1); - new[size] = 0; - - return memcpy(new, str, size); -} diff --git a/qemu-nbd.c b/qemu-nbd.c index e858033..291cba2 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -16,7 +16,7 @@ * along with this program; if not, see . */ -#include +#include "qemu-common.h" #include "block_int.h" #include "nbd.h" @@ -31,12 +31,17 @@ #include #include #include +#include #define SOCKET_PATH "/var/lock/qemu-nbd-%s" #define NBD_BUFFER_SIZE (1024*1024) +static int sigterm_wfd; static int verbose; +static char *device; +static char *srcpath; +static char *sockpath; static void usage(const char *name) { @@ -163,21 +168,80 @@ static int find_partition(BlockDriverState *bs, int partition, return -1; } -static void show_parts(const char *device) +static void termsig_handler(int signum) { - if (fork() == 0) { - int nbd; + static int sigterm_reported; + if (!sigterm_reported) { + sigterm_reported = (write(sigterm_wfd, "", 1) == 1); + } +} - /* linux just needs an open() to trigger - * the partition table update - * but remember to load the module with max_part != 0 : - * modprobe nbd max_part=63 - */ - nbd = open(device, O_RDWR); - if (nbd != -1) - close(nbd); - exit(0); +static void *show_parts(void *arg) +{ + int nbd; + + /* linux just needs an open() to trigger + * the partition table update + * but remember to load the module with max_part != 0 : + * modprobe nbd max_part=63 + */ + nbd = open(device, O_RDWR); + if (nbd != -1) { + close(nbd); + } + return NULL; +} + +static void *nbd_client_thread(void *arg) +{ + int fd = *(int *)arg; + off_t size; + size_t blocksize; + uint32_t nbdflags; + int sock; + int ret; + pthread_t show_parts_thread; + + do { + sock = unix_socket_outgoing(sockpath); + if (sock == -1) { + goto out; + } + } while (sock == -1); + + ret = nbd_receive_negotiate(sock, NULL, &nbdflags, + &size, &blocksize); + if (ret == -1) { + goto out; + } + + ret = nbd_init(fd, sock, nbdflags, size, blocksize); + if (ret == -1) { + goto out; + } + + /* update partition table */ + pthread_create(&show_parts_thread, NULL, show_parts, NULL); + + if (verbose) { + fprintf(stderr, "NBD device %s is now connected to %s\n", + device, srcpath); + } else { + /* Close stderr so that the qemu-nbd process exits. */ + dup2(STDOUT_FILENO, STDERR_FILENO); + } + + ret = nbd_client(fd); + if (ret) { + goto out; } + close(fd); + kill(getpid(), SIGTERM); + return (void *) EXIT_SUCCESS; + +out: + kill(getpid(), SIGTERM); + return (void *) EXIT_FAILURE; } int main(int argc, char **argv) @@ -185,16 +249,13 @@ int main(int argc, char **argv) BlockDriverState *bs; off_t dev_offset = 0; off_t offset = 0; - bool readonly = false; + uint32_t nbdflags = 0; bool disconnect = false; const char *bindto = "0.0.0.0"; int port = NBD_DEFAULT_PORT; struct sockaddr_in addr; socklen_t addr_len = sizeof(addr); off_t fd_size; - char *device = NULL; - char *socket = NULL; - char sockpath[128]; const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t"; struct option lopt[] = { { "help", 0, NULL, 'h' }, @@ -230,7 +291,21 @@ int main(int argc, char **argv) int nb_fds = 0; int max_fd; int persistent = 0; - uint32_t nbdflags; + pthread_t client_thread; + + /* The client thread uses SIGTERM to interrupt the server. A signal + * handler ensures that "qemu-nbd -v -c" exits with a nice status code. + */ + struct sigaction sa_sigterm; + int sigterm_fd[2]; + if (qemu_pipe(sigterm_fd) == -1) { + err(EXIT_FAILURE, "Error setting up communication pipe"); + } + + sigterm_wfd = sigterm_fd[1]; + memset(&sa_sigterm, 0, sizeof(sa_sigterm)); + sa_sigterm.sa_handler = termsig_handler; + sigaction(SIGTERM, &sa_sigterm, NULL); while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { switch (ch) { @@ -238,7 +313,7 @@ int main(int argc, char **argv) flags |= BDRV_O_SNAPSHOT; break; case 'n': - flags |= BDRV_O_NOCACHE; + flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; break; case 'b': bindto = optarg; @@ -263,7 +338,7 @@ int main(int argc, char **argv) } break; case 'r': - readonly = true; + nbdflags |= NBD_FLAG_READ_ONLY; flags &= ~BDRV_O_RDWR; break; case 'P': @@ -274,8 +349,8 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, "Invalid partition %d", partition); break; case 'k': - socket = optarg; - if (socket[0] != '/') + sockpath = optarg; + if (sockpath[0] != '/') errx(EXIT_FAILURE, "socket path must be absolute\n"); break; case 'd': @@ -333,137 +408,141 @@ int main(int argc, char **argv) return 0; } - bdrv_init(); - - bs = bdrv_new("hda"); - - if ((ret = bdrv_open(bs, argv[optind], flags, NULL)) < 0) { - errno = -ret; - err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]); - } - - fd_size = bs->total_sectors * 512; - - if (partition != -1 && - find_partition(bs, partition, &dev_offset, &fd_size)) - err(EXIT_FAILURE, "Could not find partition %d", partition); - - if (device) { + if (device && !verbose) { + int stderr_fd[2]; pid_t pid; - int sock; + int ret; - /* want to fail before daemonizing */ - if (access(device, R_OK|W_OK) == -1) { - err(EXIT_FAILURE, "Could not access '%s'", device); + if (qemu_pipe(stderr_fd) == -1) { + err(EXIT_FAILURE, "Error setting up communication pipe"); } - if (!verbose) { - /* detach client and server */ - if (daemon(0, 0) == -1) { + /* Now daemonize, but keep a communication channel open to + * print errors and exit with the proper status code. + */ + pid = fork(); + if (pid == 0) { + close(stderr_fd[0]); + ret = qemu_daemon(0, 0); + + /* Temporarily redirect stderr to the parent's pipe... */ + dup2(stderr_fd[1], STDERR_FILENO); + if (ret == -1) { err(EXIT_FAILURE, "Failed to daemonize"); } - } - if (socket == NULL) { - snprintf(sockpath, sizeof(sockpath), SOCKET_PATH, - basename(device)); - socket = sockpath; - } - - pid = fork(); - if (pid < 0) - return 1; - if (pid != 0) { - off_t size; - size_t blocksize; - - ret = 0; - bdrv_close(bs); - - do { - sock = unix_socket_outgoing(socket); - if (sock == -1) { - if (errno != ENOENT && errno != ECONNREFUSED) { - ret = 1; - goto out; - } - sleep(1); /* wait children */ + /* ... close the descriptor we inherited and go on. */ + close(stderr_fd[1]); + } else { + bool errors = false; + char *buf; + + /* In the parent. Print error messages from the child until + * it closes the pipe. + */ + close(stderr_fd[1]); + buf = g_malloc(1024); + while ((ret = read(stderr_fd[0], buf, 1024)) > 0) { + errors = true; + ret = qemu_write_full(STDERR_FILENO, buf, ret); + if (ret == -1) { + exit(EXIT_FAILURE); } - } while (sock == -1); - - fd = open(device, O_RDWR); - if (fd == -1) { - ret = 1; - goto out; } - - ret = nbd_receive_negotiate(sock, NULL, &nbdflags, - &size, &blocksize); if (ret == -1) { - ret = 1; - goto out; + err(EXIT_FAILURE, "Cannot read from daemon"); } - ret = nbd_init(fd, sock, size, blocksize); - if (ret == -1) { - ret = 1; - goto out; - } + /* Usually the daemon should not print any message. + * Exit with zero status in that case. + */ + exit(errors); + } + } - printf("NBD device %s is now connected to file %s\n", - device, argv[optind]); + if (device) { + /* Open before spawning new threads. In the future, we may + * drop privileges after opening. + */ + fd = open(device, O_RDWR); + if (fd == -1) { + err(EXIT_FAILURE, "Failed to open %s", device); + } - /* update partition table */ + if (sockpath == NULL) { + sockpath = g_malloc(128); + snprintf(sockpath, 128, SOCKET_PATH, basename(device)); + } + } - show_parts(device); + bdrv_init(); + atexit(bdrv_close_all); - ret = nbd_client(fd); - if (ret) { - ret = 1; - } - close(fd); - out: - kill(pid, SIGTERM); - unlink(socket); + bs = bdrv_new("hda"); + srcpath = argv[optind]; + if ((ret = bdrv_open(bs, srcpath, flags, NULL)) < 0) { + errno = -ret; + err(EXIT_FAILURE, "Failed to bdrv_open '%s'", argv[optind]); + } - return ret; - } - /* children */ + fd_size = bs->total_sectors * 512; + + if (partition != -1 && + find_partition(bs, partition, &dev_offset, &fd_size)) { + err(EXIT_FAILURE, "Could not find partition %d", partition); } - sharing_fds = qemu_malloc((shared + 1) * sizeof(int)); + sharing_fds = g_malloc((shared + 1) * sizeof(int)); - if (socket) { - sharing_fds[0] = unix_socket_incoming(socket); + if (sockpath) { + sharing_fds[0] = unix_socket_incoming(sockpath); } else { sharing_fds[0] = tcp_socket_incoming(bindto, port); } if (sharing_fds[0] == -1) return 1; + + if (device) { + int ret; + + ret = pthread_create(&client_thread, NULL, nbd_client_thread, &fd); + if (ret != 0) { + errx(EXIT_FAILURE, "Failed to create client thread: %s", + strerror(ret)); + } + } else { + /* Shut up GCC warnings. */ + memset(&client_thread, 0, sizeof(client_thread)); + } + max_fd = sharing_fds[0]; nb_fds++; data = qemu_blockalign(bs, NBD_BUFFER_SIZE); - if (data == NULL) + if (data == NULL) { errx(EXIT_FAILURE, "Cannot allocate data buffer"); + } do { - FD_ZERO(&fds); + FD_SET(sigterm_fd[0], &fds); for (i = 0; i < nb_fds; i++) FD_SET(sharing_fds[i], &fds); - ret = select(max_fd + 1, &fds, NULL, NULL, NULL); - if (ret == -1) + do { + ret = select(max_fd + 1, &fds, NULL, NULL, NULL); + } while (ret == -1 && errno == EINTR); + if (ret == -1 || FD_ISSET(sigterm_fd[0], &fds)) { break; + } if (FD_ISSET(sharing_fds[0], &fds)) ret--; for (i = 1; i < nb_fds && ret; i++) { if (FD_ISSET(sharing_fds[i], &fds)) { if (nbd_trip(bs, sharing_fds[i], fd_size, dev_offset, - &offset, readonly, data, NBD_BUFFER_SIZE) != 0) { + &offset, nbdflags, data, NBD_BUFFER_SIZE) != 0) { close(sharing_fds[i]); nb_fds--; sharing_fds[i] = sharing_fds[nb_fds]; @@ -479,7 +558,7 @@ int main(int argc, char **argv) (struct sockaddr *)&addr, &addr_len); if (sharing_fds[nb_fds] != -1 && - nbd_negotiate(sharing_fds[nb_fds], fd_size) != -1) { + nbd_negotiate(sharing_fds[nb_fds], fd_size, nbdflags) != -1) { if (sharing_fds[nb_fds] > max_fd) max_fd = sharing_fds[nb_fds]; nb_fds++; @@ -490,10 +569,16 @@ int main(int argc, char **argv) qemu_vfree(data); close(sharing_fds[0]); - bdrv_close(bs); - qemu_free(sharing_fds); - if (socket) - unlink(socket); + g_free(sharing_fds); + if (sockpath) { + unlink(sockpath); + } - return 0; + if (device) { + void *ret; + pthread_join(client_thread, &ret); + exit(ret != NULL); + } else { + exit(EXIT_SUCCESS); + } } diff --git a/qemu-option.c b/qemu-option.c index 65db542..f97a758 100644 --- a/qemu-option.c +++ b/qemu-option.c @@ -168,7 +168,7 @@ QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, return NULL; } -static int parse_option_bool(const char *name, const char *value, int *ret) +static int parse_option_bool(const char *name, const char *value, bool *ret) { if (value != NULL) { if (!strcmp(value, "on")) { @@ -258,7 +258,7 @@ static int parse_option_size(const char *name, const char *value, uint64_t *ret) int set_option_parameter(QEMUOptionParameter *list, const char *name, const char *value) { - int flag; + bool flag; // Find a matching parameter list = get_option_parameter(list, name); @@ -277,7 +277,7 @@ int set_option_parameter(QEMUOptionParameter *list, const char *name, case OPT_STRING: if (value != NULL) { - list->value.s = qemu_strdup(value); + list->value.s = g_strdup(value); } else { fprintf(stderr, "Option '%s' needs a parameter\n", name); return -1; @@ -337,12 +337,12 @@ void free_option_parameters(QEMUOptionParameter *list) while (cur && cur->name) { if (cur->type == OPT_STRING) { - qemu_free(cur->value.s); + g_free(cur->value.s); } cur++; } - qemu_free(list); + g_free(list); } /* @@ -377,7 +377,7 @@ QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest, num_options += count_option_parameters(list); - dest = qemu_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter)); + dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter)); dest[num_dest_options].name = NULL; while (list && list->name) { @@ -508,7 +508,7 @@ struct QemuOpt { const QemuOptDesc *desc; union { - int boolean; + bool boolean; uint64_t uint; } value; @@ -542,7 +542,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name) return opt ? opt->str : NULL; } -int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval) +bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval) { QemuOpt *opt = qemu_opt_find(opts, name); @@ -594,9 +594,9 @@ static int qemu_opt_parse(QemuOpt *opt) static void qemu_opt_del(QemuOpt *opt) { QTAILQ_REMOVE(&opt->opts->head, opt, next); - qemu_free((/* !const */ char*)opt->name); - qemu_free((/* !const */ char*)opt->str); - qemu_free(opt); + g_free((/* !const */ char*)opt->name); + g_free((/* !const */ char*)opt->str); + g_free(opt); } int qemu_opt_set(QemuOpts *opts, const char *name, const char *value) @@ -619,15 +619,15 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value) } } - opt = qemu_mallocz(sizeof(*opt)); - opt->name = qemu_strdup(name); + opt = g_malloc0(sizeof(*opt)); + opt->name = g_strdup(name); opt->opts = opts; QTAILQ_INSERT_TAIL(&opts->head, opt, next); if (desc[i].name != NULL) { opt->desc = desc+i; } if (value) { - opt->str = qemu_strdup(value); + opt->str = g_strdup(value); } if (qemu_opt_parse(opt) < 0) { qemu_opt_del(opt); @@ -636,6 +636,37 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value) return 0; } +int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val) +{ + QemuOpt *opt; + const QemuOptDesc *desc = opts->list->desc; + int i; + + for (i = 0; desc[i].name != NULL; i++) { + if (strcmp(desc[i].name, name) == 0) { + break; + } + } + if (desc[i].name == NULL) { + if (i == 0) { + /* empty list -> allow any */; + } else { + qerror_report(QERR_INVALID_PARAMETER, name); + return -1; + } + } + + opt = g_malloc0(sizeof(*opt)); + opt->name = g_strdup(name); + opt->opts = opts; + QTAILQ_INSERT_TAIL(&opts->head, opt, next); + if (desc[i].name != NULL) { + opt->desc = desc+i; + } + opt->value.boolean = !!val; + return 0; +} + int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, int abort_on_failure) { @@ -701,9 +732,9 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exist } } } - opts = qemu_mallocz(sizeof(*opts)); + opts = g_malloc0(sizeof(*opts)); if (id) { - opts->id = qemu_strdup(id); + opts->id = g_strdup(id); } opts->list = list; loc_save(&opts->loc); @@ -754,8 +785,8 @@ void qemu_opts_del(QemuOpts *opts) qemu_opt_del(opt); } QTAILQ_REMOVE(&opts->list->head, opts, next); - qemu_free(opts->id); - qemu_free(opts); + g_free(opts->id); + g_free(opts); } int qemu_opts_print(QemuOpts *opts, void *dummy) diff --git a/qemu-option.h b/qemu-option.h index b515813..07958e4 100644 --- a/qemu-option.h +++ b/qemu-option.h @@ -105,10 +105,11 @@ struct QemuOptsList { }; const char *qemu_opt_get(QemuOpts *opts, const char *name); -int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval); +bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval); uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval); uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval); int qemu_opt_set(QemuOpts *opts, const char *name, const char *value); +int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val); typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque); int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, int abort_on_failure); diff --git a/qemu-options.hx b/qemu-options.hx index 945edf3..76d0826 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -27,14 +27,29 @@ STEXI Display version information and exit ETEXI -DEF("M", HAS_ARG, QEMU_OPTION_M, - "-M machine select emulated machine (-M ? for list)\n", QEMU_ARCH_ALL) +DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ + "-machine [type=]name[,prop[=value][,...]]\n" + " selects emulated machine (-machine ? for list)\n" + " property accel=accel1[:accel2[:...]] selects accelerator\n" + " supported accelerators are kvm, xen, tcg (default: tcg)\n", + QEMU_ARCH_ALL) STEXI -@item -M @var{machine} -@findex -M -Select the emulated @var{machine} (@code{-M ?} for list) +@item -machine [type=]@var{name}[,prop=@var{value}[,...]] +@findex -machine +Select the emulated machine by @var{name}. Use @code{-machine ?} to list +available machines. Supported machine properties are: +@table @option +@item accel=@var{accels1}[:@var{accels2}[:...]] +This is used to enable an accelerator. Depending on the target architecture, +kvm, xen, or tcg can be available. By default, tcg is used. If there is more +than one accelerator specified, the next one is used if the previous one fails +to initialize. +@end table ETEXI +HXCOMM Deprecated by -machine +DEF("M", HAS_ARG, QEMU_OPTION_M, "", QEMU_ARCH_ALL) + DEF("cpu", HAS_ARG, QEMU_OPTION_cpu, "-cpu cpu select CPU (-cpu ? for list)\n", QEMU_ARCH_ALL) STEXI @@ -118,7 +133,7 @@ ETEXI DEF("drive", HAS_ARG, QEMU_OPTION_drive, "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n" " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n" - " [,cache=writethrough|writeback|none|unsafe][,format=f]\n" + " [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n" " [,serial=s][,addr=A][,id=name][,aio=threads|native]\n" " [,readonly=on|off]\n" " use 'file' as a drive image\n", QEMU_ARCH_ALL) @@ -133,6 +148,9 @@ Define a new drive. Valid options are: This option defines which disk image (@pxref{disk_images}) to use with this drive. If the filename contains comma, you must double it (for instance, "file=my,,file" to use file "my,file"). + +Special files such as iSCSI devices can be specified using protocol +specific URLs. See the section for "Device URL Syntax" for more information. @item if=@var{interface} This option defines on which type on interface the drive is connected. Available types are: ide, scsi, sd, mtd, floppy, pflash, virtio. @@ -149,7 +167,7 @@ These options have the same definition as they have in @option{-hdachs}. @item snapshot=@var{snapshot} @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). @item cache=@var{cache} -@var{cache} is "none", "writeback", "unsafe", or "writethrough" and controls how the host cache is used to access block data. +@var{cache} is "none", "writeback", "unsafe", "directsync" or "writethrough" and controls how the host cache is used to access block data. @item aio=@var{aio} @var{aio} is "threads", or "native" and selects between pthread based disk I/O and native Linux AIO. @item format=@var{format} @@ -160,6 +178,14 @@ an untrusted format header. This option specifies the serial number to assign to the device. @item addr=@var{addr} Specify the controller's PCI address (if=virtio only). +@item werror=@var{action},rerror=@var{action} +Specify which @var{action} to take on write and read errors. Valid actions are: +"ignore" (ignore the error and try to continue), "stop" (pause QEMU), +"report" (report the error to the guest), "enospc" (pause QEMU only if the +host disk is full; report the error to the guest otherwise). +The default setting is @option{werror=enospc} and @option{rerror=report}. +@item readonly +Open drive @option{file} as read-only. Guest write attempts will fail. @end table By default, writethrough caching is used for all block device. This means that @@ -176,6 +202,10 @@ The host page cache can be avoided entirely with @option{cache=none}. This will attempt to do disk IO directly to the guests memory. QEMU may still perform an internal copy of the data. +The host page cache can be avoided while only sending write notifications to +the guest when the data has been reported as written by the storage subsystem +using @option{cache=directsync}. + Some block drivers perform badly with @option{cache=writethrough}, most notably, qcow2. If performance is more important than correctness, @option{cache=writeback} should be used with qcow2. @@ -280,10 +310,13 @@ ETEXI DEF("boot", HAS_ARG, QEMU_OPTION_boot, "-boot [order=drives][,once=drives][,menu=on|off]\n" - " 'drives': floppy (a), hard disk (c), CD-ROM (d), network (n)\n", + " [,splash=sp_name][,splash-time=sp_time]\n" + " 'drives': floppy (a), hard disk (c), CD-ROM (d), network (n)\n" + " 'sp_name': the file's name that would be passed to bios as logo picture, if menu=on\n" + " 'sp_time': the period that splash picture last if menu=on, unit is ms\n", QEMU_ARCH_ALL) STEXI -@item -boot [order=@var{drives}][,once=@var{drives}][,menu=on|off] +@item -boot [order=@var{drives}][,once=@var{drives}][,menu=on|off][,splash=@var{sp_name}][,splash-time=@var{sp_time}] @findex -boot Specify boot order @var{drives} as a string of drive letters. Valid drive letters depend on the target achitecture. The x86 PC uses: a, b @@ -295,11 +328,20 @@ particular boot order only on the first startup, specify it via Interactive boot menus/prompts can be enabled via @option{menu=on} as far as firmware/BIOS supports them. The default is non-interactive boot. +A splash picture could be passed to bios, enabling user to show it as logo, +when option splash=@var{sp_name} is given and menu=on, If firmware/BIOS +supports them. Currently Seabios for X86 system support it. +limitation: The splash file could be a jpeg file or a BMP file in 24 BPP +format(true color). The resolution should be supported by the SVGA mode, so +the recommended is 320x240, 640x480, 800x640. + @example # try to boot from network first, then from hard disk qemu -boot order=nc # boot from CD-ROM first, switch back to default order after reboot qemu -boot once=d +# boot with a splash picture for 5 seconds. +qemu -boot menu=on,splash=/root/boot.bmp,splash-time=5000 @end example Note: The legacy format '-boot @var{drives}' is still supported but its @@ -483,76 +525,121 @@ possible drivers and properties, use @code{-device ?} and @code{-device @var{driver},?}. ETEXI +DEFHEADING() + DEFHEADING(File system options:) DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev, - "-fsdev local,id=id,path=path,security_model=[mapped|passthrough|none]\n", + "-fsdev fsdriver,id=id,path=path,[security_model={mapped|passthrough|none}]\n" + " [,writeout=immediate][,readonly]\n", QEMU_ARCH_ALL) STEXI -The general form of a File system device option is: -@table @option - -@item -fsdev @var{fstype} ,id=@var{id} [,@var{options}] +@item -fsdev @var{fsdriver},id=@var{id},path=@var{path},[security_model=@var{security_model}][,writeout=@var{writeout}][,readonly] @findex -fsdev -Fstype is one of: -@option{local}, -The specific Fstype will determine the applicable options. - -Options to each backend are described below. - -@item -fsdev local ,id=@var{id} ,path=@var{path} ,security_model=@var{security_model} - -Create a file-system-"device" for local-filesystem. - -@option{local} is only available on Linux. - -@option{path} specifies the path to be exported. @option{path} is required. - -@option{security_model} specifies the security model to be followed. -@option{security_model} is required. +Define a new file system device. Valid options are: +@table @option +@item @var{fsdriver} +This option specifies the fs driver backend to use. +Currently "local" and "handle" file system drivers are supported. +@item id=@var{id} +Specifies identifier for this device +@item path=@var{path} +Specifies the export path for the file system device. Files under +this path will be available to the 9p client on the guest. +@item security_model=@var{security_model} +Specifies the security model to be used for this export path. +Supported security models are "passthrough", "mapped" and "none". +In "passthrough" security model, files are stored using the same +credentials as they are created on the guest. This requires qemu +to run as root. In "mapped" security model, some of the file +attributes like uid, gid, mode bits and link target are stored as +file attributes. Directories exported by this security model cannot +interact with other unix tools. "none" security model is same as +passthrough except the sever won't report failures if it fails to +set file attributes like ownership. Security model is mandatory +only for local fsdriver. Other fsdrivers (like handle) don't take +security model as a parameter. +@item writeout=@var{writeout} +This is an optional argument. The only supported value is "immediate". +This means that host page cache will be used to read and write data but +write notification will be sent to the guest only when the data has been +reported as written by the storage subsystem. +@item readonly +Enables exporting 9p share as a readonly mount for guests. By default +read-write access is given. +@end table +-fsdev option is used along with -device driver "virtio-9p-pci". +@item -device virtio-9p-pci,fsdev=@var{id},mount_tag=@var{mount_tag} +Options for virtio-9p-pci driver are: +@table @option +@item fsdev=@var{id} +Specifies the id value specified along with -fsdev option +@item mount_tag=@var{mount_tag} +Specifies the tag name to be used by the guest to mount this export point @end table + ETEXI +DEFHEADING() + DEFHEADING(Virtual File system pass-through options:) DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs, - "-virtfs local,path=path,mount_tag=tag,security_model=[mapped|passthrough|none]\n", + "-virtfs local,path=path,mount_tag=tag,security_model=[mapped|passthrough|none]\n" + " [,writeout=immediate][,readonly]\n", QEMU_ARCH_ALL) STEXI -The general form of a Virtual File system pass-through option is: -@table @option - -@item -virtfs @var{fstype} [,@var{options}] +@item -virtfs @var{fsdriver},path=@var{path},mount_tag=@var{mount_tag},security_model=@var{security_model}[,writeout=@var{writeout}][,readonly] @findex -virtfs -Fstype is one of: -@option{local}, -The specific Fstype will determine the applicable options. - -Options to each backend are described below. - -@item -virtfs local ,path=@var{path} ,mount_tag=@var{mount_tag} ,security_model=@var{security_model} - -Create a Virtual file-system-pass through for local-filesystem. - -@option{local} is only available on Linux. - -@option{path} specifies the path to be exported. @option{path} is required. - -@option{security_model} specifies the security model to be followed. -@option{security_model} is required. - - -@option{mount_tag} specifies the tag with which the exported file is mounted. -@option{mount_tag} is required. +The general form of a Virtual File system pass-through options are: +@table @option +@item @var{fsdriver} +This option specifies the fs driver backend to use. +Currently "local" and "handle" file system drivers are supported. +@item id=@var{id} +Specifies identifier for this device +@item path=@var{path} +Specifies the export path for the file system device. Files under +this path will be available to the 9p client on the guest. +@item security_model=@var{security_model} +Specifies the security model to be used for this export path. +Supported security models are "passthrough", "mapped" and "none". +In "passthrough" security model, files are stored using the same +credentials as they are created on the guest. This requires qemu +to run as root. In "mapped" security model, some of the file +attributes like uid, gid, mode bits and link target are stored as +file attributes. Directories exported by this security model cannot +interact with other unix tools. "none" security model is same as +passthrough except the sever won't report failures if it fails to +set file attributes like ownership. Security model is mandatory only +for local fsdriver. Other fsdrivers (like handle) don't take security +model as a parameter. +@item writeout=@var{writeout} +This is an optional argument. The only supported value is "immediate". +This means that host page cache will be used to read and write data but +write notification will be sent to the guest only when the data has been +reported as written by the storage subsystem. +@item readonly +Enables exporting 9p share as a readonly mount for guests. By default +read-write access is given. @end table ETEXI +DEF("virtfs_synth", 0, QEMU_OPTION_virtfs_synth, + "-virtfs_synth Create synthetic file system image\n", + QEMU_ARCH_ALL) +STEXI +@item -virtfs_synth +@findex -virtfs_synth +Create synthetic file system image +ETEXI + DEFHEADING() DEF("name", HAS_ARG, QEMU_OPTION_name, @@ -590,6 +677,37 @@ STEXI @table @option ETEXI +DEF("display", HAS_ARG, QEMU_OPTION_display, + "-display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off]\n" + " [,window_close=on|off]|curses|none|\n" + " vnc=[,]\n" + " select display type\n", QEMU_ARCH_ALL) +STEXI +@item -display @var{type} +@findex -display +Select type of display to use. This option is a replacement for the +old style -sdl/-curses/... options. Valid values for @var{type} are +@table @option +@item sdl +Display video output via SDL (usually in a separate graphics +window; see the SDL documentation for other possibilities). +@item curses +Display video output via curses. For graphics device models which +support a text mode, QEMU can display this output using a +curses/ncurses interface. Nothing is displayed when the graphics +device is in graphical mode or if the graphics device does not support +a text mode. Generally only the VGA device models support text mode. +@item none +Do not display video output. The guest will still see an emulated +graphics card, but its output will not be displayed to the QEMU +user. This option differs from the -nographic option in that it +only affects what is done with video output; -nographic also changes +the destination of the serial and parallel port data. +@item vnc +Start a VNC server on display +@end table +ETEXI + DEF("nographic", 0, QEMU_OPTION_nographic, "-nographic disable graphical output and redirect serial I/Os to console\n", QEMU_ARCH_ALL) @@ -603,11 +721,9 @@ the console. Therefore, you can still use QEMU to debug a Linux kernel with a serial console. ETEXI -#ifdef CONFIG_CURSES DEF("curses", 0, QEMU_OPTION_curses, "-curses use a curses/ncurses interface instead of SDL\n", QEMU_ARCH_ALL) -#endif STEXI @item -curses @findex curses @@ -616,11 +732,9 @@ QEMU can display the VGA output when in text mode using a curses/ncurses interface. Nothing is displayed in graphical mode. ETEXI -#ifdef CONFIG_SDL DEF("no-frame", 0, QEMU_OPTION_no_frame, "-no-frame open SDL window without a frame and window decorations\n", QEMU_ARCH_ALL) -#endif STEXI @item -no-frame @findex -no-frame @@ -629,42 +743,36 @@ available screen space. This makes the using QEMU in a dedicated desktop workspace more convenient. ETEXI -#ifdef CONFIG_SDL DEF("alt-grab", 0, QEMU_OPTION_alt_grab, "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n", QEMU_ARCH_ALL) -#endif STEXI @item -alt-grab @findex -alt-grab -Use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt). +Use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt). Note that this also +affects the special keys (for fullscreen, monitor-mode switching, etc). ETEXI -#ifdef CONFIG_SDL DEF("ctrl-grab", 0, QEMU_OPTION_ctrl_grab, "-ctrl-grab use Right-Ctrl to grab mouse (instead of Ctrl-Alt)\n", QEMU_ARCH_ALL) -#endif STEXI @item -ctrl-grab @findex -ctrl-grab -Use Right-Ctrl to grab mouse (instead of Ctrl-Alt). +Use Right-Ctrl to grab mouse (instead of Ctrl-Alt). Note that this also +affects the special keys (for fullscreen, monitor-mode switching, etc). ETEXI -#ifdef CONFIG_SDL DEF("no-quit", 0, QEMU_OPTION_no_quit, "-no-quit disable SDL window close capability\n", QEMU_ARCH_ALL) -#endif STEXI @item -no-quit @findex -no-quit Disable SDL window close capability. ETEXI -#ifdef CONFIG_SDL DEF("sdl", 0, QEMU_OPTION_sdl, "-sdl enable SDL\n", QEMU_ARCH_ALL) -#endif STEXI @item -sdl @findex -sdl @@ -693,9 +801,25 @@ Force using the specified IP version. @item password= Set the password you need to authenticate. +@item sasl +Require that the client use SASL to authenticate with the spice. +The exact choice of authentication method used is controlled from the +system / user's SASL configuration file for the 'qemu' service. This +is typically found in /etc/sasl2/qemu.conf. If running QEMU as an +unprivileged user, an environment variable SASL_CONF_PATH can be used +to make it search alternate locations for the service config. +While some SASL auth methods can also provide data encryption (eg GSSAPI), +it is recommended that SASL always be combined with the 'tls' and +'x509' settings to enable use of SSL and server certificates. This +ensures a data encryption preventing compromise of authentication +credentials. + @item disable-ticketing Allow client connects without authentication. +@item disable-copy-paste +Disable copy paste between the client and the guest. + @item tls-port= Set the TCP port spice is listening on for encrypted channels. @@ -750,6 +874,15 @@ STEXI Rotate graphical output 90 deg left (only PXA LCD). ETEXI +DEF("rotate", HAS_ARG, QEMU_OPTION_rotate, + "-rotate rotate graphical output some deg left (only PXA LCD)\n", + QEMU_ARCH_ALL) +STEXI +@item -rotate +@findex -rotate +Rotate graphical output some deg left (only PXA LCD). +ETEXI + DEF("vga", HAS_ARG, QEMU_OPTION_vga, "-vga [std|cirrus|vmware|qxl|xenfb|none]\n" " select video card type\n", QEMU_ARCH_ALL) @@ -913,6 +1046,15 @@ option is set, VNC client may receive lossy framebuffer updates depending on its encoding settings. Enabling this option can save a lot of bandwidth at the expense of quality. +@item non-adaptive + +Disable adaptive encodings. Adaptive encodings are enabled by default. +An adaptive encoding will try to detect frequently updated screen regions, +and send updates in these regions using a lossy encoding (like JPEG). +This can be really helpful to save bandwidth when playing videos. Disabling +adaptive encodings allows to restore the original static behavior of encodings +like Tight. + @end table ETEXI @@ -984,12 +1126,17 @@ Enable virtio balloon device (default), optionally with PCI address ETEXI DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable, - "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,data=file1[:file2]...]\n" + "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n" " ACPI table description\n", QEMU_ARCH_I386) STEXI @item -acpitable [sig=@var{str}][,rev=@var{n}][,oem_id=@var{str}][,oem_table_id=@var{str}][,oem_rev=@var{n}] [,asl_compiler_id=@var{str}][,asl_compiler_rev=@var{n}][,data=@var{file1}[:@var{file2}]...] @findex -acpitable Add ACPI table with specified header fields and context from specified files. +For file=, take whole ACPI table from the specified files, including all +ACPI headers (possible overridden by other options). +For data=, only data +portion of the table is used, all header information is specified in the +command line. ETEXI DEF("smbios", HAS_ARG, QEMU_OPTION_smbios, @@ -1037,7 +1184,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net, "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n" " create a new Network Interface Card and connect it to VLAN 'n'\n" #ifdef CONFIG_SLIRP - "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n" + "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=on|off]\n" " [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n" " [,hostfwd=rule][,guestfwd=rule]" #ifndef _WIN32 @@ -1124,23 +1271,23 @@ Assign symbolic name for use in monitor commands. @item net=@var{addr}[/@var{mask}] Set IP network address the guest will see. Optionally specify the netmask, either in the form a.b.c.d or as number of valid top-most bits. Default is -10.0.2.0/8. +10.0.2.0/24. @item host=@var{addr} Specify the guest-visible address of the host. Default is the 2nd IP in the guest network, i.e. x.x.x.2. -@item restrict=y|yes|n|no -If this options is enabled, the guest will be isolated, i.e. it will not be +@item restrict=on|off +If this option is enabled, the guest will be isolated, i.e. it will not be able to contact the host and no guest IP packets will be routed over the host -to the outside. This option does not affect explicitly set forwarding rule. +to the outside. This option does not affect any explicitly set forwarding rules. @item hostname=@var{name} Specifies the client hostname reported by the builtin DHCP server. @item dhcpstart=@var{addr} Specify the first of the 16 IPs the built-in DHCP server can assign. Default -is the 16th to 31st IP in the guest network, i.e. x.x.x.16 to x.x.x.31. +is the 15th to 31st IP in the guest network, i.e. x.x.x.15 to x.x.x.31. @item dns=@var{addr} Specify the guest-visible address of the virtual nameserver. The address must @@ -1178,9 +1325,9 @@ or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000). Then @file{@var{dir}} can be accessed in @file{\\smbserver\qemu}. -Note that a SAMBA server must be installed on the host OS in -@file{/usr/sbin/smbd}. QEMU was tested successfully with smbd versions from -Red Hat 9, Fedora Core 3 and OpenSUSE 11.x. +Note that a SAMBA server must be installed on the host OS. +QEMU was tested successfully with smbd versions from Red Hat 9, +Fedora Core 3 and OpenSUSE 11.x. @item hostfwd=[tcp|udp]:[@var{hostaddr}]:@var{hostport}-[@var{guestaddr}]:@var{guestport} Redirect incoming TCP or UDP connections to the host port @var{hostport} to @@ -1313,7 +1460,7 @@ qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \ Connect VLAN @var{n} to PORT @var{n} of a vde switch running on host and listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname} and MODE @var{octalmode} to change default ownership and permissions for -communication port. This option is available only if QEMU has been compiled +communication port. This option is only available if QEMU has been compiled with vde support enabled. Example: @@ -1574,21 +1721,108 @@ Connect to a local parallel port. @option{path} specifies the path to the parallel port device. @option{path} is required. -#if defined(CONFIG_SPICE) @item -chardev spicevmc ,id=@var{id} ,debug=@var{debug}, name=@var{name} +@option{spicevmc} is only available when spice support is built in. + @option{debug} debug level for spicevmc @option{name} name of spice channel to connect to Connect to a spice virtual machine channel, such as vdiport. -#endif @end table ETEXI DEFHEADING() +STEXI +DEFHEADING(Device URL Syntax:) + +In addition to using normal file images for the emulated storage devices, +QEMU can also use networked resources such as iSCSI devices. These are +specified using a special URL syntax. + +@table @option +@item iSCSI +iSCSI support allows QEMU to access iSCSI resources directly and use as +images for the guest storage. Both disk and cdrom images are supported. + +Syntax for specifying iSCSI LUNs is +``iscsi://[:]//'' + +Example (without authentication): +@example +qemu -cdrom iscsi://192.0.2.1/iqn.2001-04.com.example/2 \ +--drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1 +@end example + +Example (CHAP username/password via URL): +@example +qemu --drive file=iscsi://user%password@@192.0.2.1/iqn.2001-04.com.example/1 +@end example + +Example (CHAP username/password via environment variables): +@example +LIBISCSI_CHAP_USERNAME="user" \ +LIBISCSI_CHAP_PASSWORD="password" \ +qemu --drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1 +@end example + +iSCSI support is an optional feature of QEMU and only available when +compiled and linked against libiscsi. + +@item NBD +QEMU supports NBD (Network Block Devices) both using TCP protocol as well +as Unix Domain Sockets. + +Syntax for specifying a NBD device using TCP +``nbd::[:exportname=]'' + +Syntax for specifying a NBD device using Unix Domain Sockets +``nbd:unix:[:exportname=]'' + + +Example for TCP +@example +qemu --drive file=nbd:192.0.2.1:30000 +@end example + +Example for Unix Domain Sockets +@example +qemu --drive file=nbd:unix:/tmp/nbd-socket +@end example + +@item Sheepdog +Sheepdog is a distributed storage system for QEMU. +QEMU supports using either local sheepdog devices or remote networked +devices. + +Syntax for specifying a sheepdog device +@table @list +``sheepdog:'' + +``sheepdog::'' + +``sheepdog::'' + +``sheepdog:::'' + +``sheepdog::::'' + +``sheepdog::::'' +@end table + +Example +@example +qemu --drive file=sheepdog:192.0.2.1:30000:MyVirtualMachine +@end example + +See also @url{http://http://www.osrg.net/sheepdog/}. + +@end table +ETEXI + DEFHEADING(Bluetooth(R) options:) DEF("bt", HAS_ARG, QEMU_OPTION_bt, \ @@ -1961,6 +2195,15 @@ STEXI Output log in /tmp/qemu.log ETEXI +DEF("D", HAS_ARG, QEMU_OPTION_D, \ + "-D logfile output log to logfile (instead of the default /tmp/qemu.log)\n", + QEMU_ARCH_ALL) +STEXI +@item -D +@findex -D +Output log in logfile instead of /tmp/qemu.log +ETEXI + DEF("hdachs", HAS_ARG, QEMU_OPTION_hdachs, \ "-hdachs c,h,s[,t]\n" \ " force hard disk 0 physical geometry and the optional BIOS\n" \ @@ -2002,6 +2245,25 @@ Enable KVM full virtualization support. This option is only available if KVM support is enabled when compiling. ETEXI +DEF("enable-gl", 0, QEMU_OPTION_enable_gl, \ + "-enable-gl enable OpenGL passthrough support\n", QEMU_ARCH_ALL) +STEXI +@item -enable-gl +@findex -enable-gl +Enable OpenGL passthrough support. This option requires the support of a +special libGL installed on the guest OS. +ETEXI + + +DEF("enable-hax", 0, QEMU_OPTION_enable_hax, \ + "-enable-hax enable HAX virtualization support\n", QEMU_ARCH_I386) +STEXI +@item -enable-hax +@findex -enable-hax +Enable HAX (Hardware-based Acceleration eXecution) support. When HAX support detected, emulator will enable it by default. This option will disable the default action +HAX is only supported in MAC and Windows platform and is not conflict with KVM. +ETEXI + DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid, "-xen-domid id specify xen guest domain id\n", QEMU_ARCH_ALL) DEF("xen-create", 0, QEMU_OPTION_xen_create, @@ -2288,11 +2550,11 @@ STEXI Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only). ETEXI DEF("semihosting", 0, QEMU_OPTION_semihosting, - "-semihosting semihosting mode\n", QEMU_ARCH_ARM | QEMU_ARCH_M68K) + "-semihosting semihosting mode\n", QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA) STEXI @item -semihosting @findex -semihosting -Semihosting mode (ARM, M68K only). +Semihosting mode (ARM, M68K, Xtensa only). ETEXI DEF("old-param", 0, QEMU_OPTION_old_param, "-old-param old param mode\n", QEMU_ARCH_ARM) @@ -2328,17 +2590,51 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and @var{sysconfdir}/target-@var{ARCH}.conf on startup. The @code{-nodefconfig} option will prevent QEMU from loading these configuration files at startup. ETEXI -#ifdef CONFIG_SIMPLE_TRACE DEF("trace", HAS_ARG, QEMU_OPTION_trace, - "-trace\n" - " Specify a trace file to log traces to\n", + "-trace [events=][,file=]\n" + " specify tracing options\n", QEMU_ARCH_ALL) STEXI -@item -trace +HXCOMM This line is not accurate, as some sub-options are backend-specific but +HXCOMM HX does not support conditional compilation of text. +@item -trace [events=@var{file}][,file=@var{file}] @findex -trace -Specify a trace file to log output traces to. + +Specify tracing options. + +@table @option +@item events=@var{file} +Immediately enable events listed in @var{file}. +The file must contain one event name (as listed in the @var{trace-events} file) +per line. +This option is only available if QEMU has been compiled with +either @var{simple} or @var{stderr} tracing backend. +@item file=@var{file} +Log output traces to @var{file}. + +This option is only available if QEMU has been compiled with +the @var{simple} tracing backend. +@end table +ETEXI + +DEF("max-touch-point", HAS_ARG, QEMU_OPTION_max_touch_point, \ + "-max-touch-point [count]\n" + " define maximum number of touch point\n", + QEMU_ARCH_ALL) +STEXI +@item -max-touch-point @var{max_count} +@findex -max-touch-point +Use @var{max_count} as Integer +ETEXI + +DEF("disable-skin", 0, QEMU_OPTION_disable_skin, \ + "-disable-skin\n" + " do not start with java skin process\n", + QEMU_ARCH_ALL) +STEXI +@item -disable-skin +@findex -disable-skin ETEXI -#endif HXCOMM This is the last statement. Insert new options before this line! STEXI diff --git a/qemu-os-posix.h b/qemu-os-posix.h index 81fd9ab..8e1149d 100644 --- a/qemu-os-posix.h +++ b/qemu-os-posix.h @@ -26,10 +26,6 @@ #ifndef QEMU_OS_POSIX_H #define QEMU_OS_POSIX_H -static inline void os_host_main_loop_wait(int *timeout) -{ -} - void os_set_line_buffering(void); void os_set_proc_name(const char *s); void os_setup_signal_handling(void); @@ -48,7 +44,6 @@ typedef struct timeval qemu_timeval; #endif #endif typedef struct timespec qemu_timespec; -int qemu_utimensat(int dirfd, const char *path, const qemu_timespec *times, - int flags); +int qemu_utimens(const char *path, const qemu_timespec *times); #endif diff --git a/qemu-os-win32.h b/qemu-os-win32.h index 1a07e5e..8eda4bd 100644 --- a/qemu-os-win32.h +++ b/qemu-os-win32.h @@ -26,21 +26,12 @@ #ifndef QEMU_OS_WIN32_H #define QEMU_OS_WIN32_H -/* Polling handling */ +#include +#include +#include "main-loop.h" -/* return TRUE if no sleep should be done afterwards */ -typedef int PollingFunc(void *opaque); - -int qemu_add_polling_cb(PollingFunc *func, void *opaque); -void qemu_del_polling_cb(PollingFunc *func, void *opaque); - -/* Wait objects handling */ -typedef void WaitObjectFunc(void *opaque); - -int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); -void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); - -void os_host_main_loop_wait(int *timeout); +/* Declaration of ffs() is missing in MinGW's strings.h. */ +int ffs(int i); static inline void os_setup_signal_handling(void) {} static inline void os_daemonize(void) {} diff --git a/qemu-queue.h b/qemu-queue.h index 1d07745..2214230 100644 --- a/qemu-queue.h +++ b/qemu-queue.h @@ -76,6 +76,8 @@ * For details on the use of these macros, see the queue(3) manual page. */ +#include "qemu-barrier.h" /* for smp_wmb() */ + /* * List definitions. */ @@ -122,6 +124,17 @@ struct { \ (elm)->field.le_prev = &(head)->lh_first; \ } while (/*CONSTCOND*/0) +#define QLIST_INSERT_HEAD_RCU(head, elm, field) do { \ + (elm)->field.le_prev = &(head)->lh_first; \ + (elm)->field.le_next = (head)->lh_first; \ + smp_wmb(); /* fill elm before linking it */ \ + if ((head)->lh_first != NULL) { \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next; \ + } \ + (head)->lh_first = (elm); \ + smp_wmb(); \ +} while (/* CONSTCOND*/0) + #define QLIST_REMOVE(elm, field) do { \ if ((elm)->field.le_next != NULL) \ (elm)->field.le_next->field.le_prev = \ diff --git a/qemu-sockets.c b/qemu-sockets.c index 70419e9..fc5b465 100644 --- a/qemu-sockets.c +++ b/qemu-sockets.c @@ -572,6 +572,7 @@ int unix_connect_opts(QemuOpts *opts) snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); if (connect(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { fprintf(stderr, "connect(unix:%s): %s\n", path, strerror(errno)); + close(sock); return -1; } @@ -593,10 +594,10 @@ int unix_listen(const char *str, char *ostr, int olen) if (optstr) { len = optstr - str; if (len) { - path = qemu_malloc(len+1); + path = g_malloc(len+1); snprintf(path, len+1, "%.*s", len, str); qemu_opt_set(opts, "path", path); - qemu_free(path); + g_free(path); } } else { qemu_opt_set(opts, "path", str); @@ -627,25 +628,53 @@ int unix_connect(const char *path) int unix_listen_opts(QemuOpts *opts) { fprintf(stderr, "unix sockets are not available on windows\n"); + errno = ENOTSUP; return -1; } int unix_connect_opts(QemuOpts *opts) { fprintf(stderr, "unix sockets are not available on windows\n"); + errno = ENOTSUP; return -1; } int unix_listen(const char *path, char *ostr, int olen) { fprintf(stderr, "unix sockets are not available on windows\n"); + errno = ENOTSUP; return -1; } int unix_connect(const char *path) { fprintf(stderr, "unix sockets are not available on windows\n"); + errno = ENOTSUP; return -1; } #endif + +#ifdef _WIN32 +static void socket_cleanup(void) +{ + WSACleanup(); +} +#endif + +int socket_init(void) +{ +#ifdef _WIN32 + WSADATA Data; + int ret, err; + + ret = WSAStartup(MAKEWORD(2,0), &Data); + if (ret != 0) { + err = WSAGetLastError(); + fprintf(stderr, "WSAStartup: %d\n", err); + return -1; + } + atexit(socket_cleanup); +#endif + return 0; +} diff --git a/qemu-tech.texi b/qemu-tech.texi index 138e3ce..62afe45 100644 --- a/qemu-tech.texi +++ b/qemu-tech.texi @@ -42,13 +42,14 @@ @chapter Introduction @menu -* intro_features:: Features -* intro_x86_emulation:: x86 and x86-64 emulation -* intro_arm_emulation:: ARM emulation -* intro_mips_emulation:: MIPS emulation -* intro_ppc_emulation:: PowerPC emulation -* intro_sparc_emulation:: Sparc32 and Sparc64 emulation -* intro_other_emulation:: Other CPU emulation +* intro_features:: Features +* intro_x86_emulation:: x86 and x86-64 emulation +* intro_arm_emulation:: ARM emulation +* intro_mips_emulation:: MIPS emulation +* intro_ppc_emulation:: PowerPC emulation +* intro_sparc_emulation:: Sparc32 and Sparc64 emulation +* intro_xtensa_emulation:: Xtensa emulation +* intro_other_emulation:: Other CPU emulation @end menu @node intro_features @@ -259,6 +260,31 @@ Current QEMU limitations: @end itemize +@node intro_xtensa_emulation +@section Xtensa emulation + +@itemize + +@item Core Xtensa ISA emulation, including most options: code density, +loop, extended L32R, 16- and 32-bit multiplication, 32-bit division, +MAC16, miscellaneous operations, boolean, multiprocessor synchronization, +conditional store, exceptions, relocatable vectors, unaligned exception, +interrupts (including high priority and timer), hardware alignment, +region protection, region translation, MMU, windowed registers, thread +pointer, processor ID. + +@item Not implemented options: FP coprocessor, coprocessor context, +data/instruction cache (including cache prefetch and locking), XLMI, +processor interface, debug. Also options not covered by the core ISA +(e.g. FLIX, wide branches) are not implemented. + +@item Can run most Xtensa Linux binaries. + +@item New core configuration that requires no additional instructions +may be created from overlay with minimal amount of hand-written code. + +@end itemize + @node intro_other_emulation @section Other CPU emulation @@ -409,7 +435,7 @@ generate an addition for the segment base. @node Translation cache @section Translation cache -A 16 MByte cache holds the most recently used translations. For +A 32 MByte cache holds the most recently used translations. For simplicity, it is completely flushed when it is full. A translation unit contains just a single basic block (a block of x86 instructions terminated by a jump or by a virtual CPU state change which the diff --git a/qemu-thread.c b/qemu-thread.c deleted file mode 100644 index fbc78fe..0000000 --- a/qemu-thread.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Wrappers around mutex/cond/thread functions - * - * Copyright Red Hat, Inc. 2009 - * - * Author: - * Marcelo Tosatti - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include "qemu-thread.h" - -static void error_exit(int err, const char *msg) -{ - fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err)); - exit(1); -} - -void qemu_mutex_init(QemuMutex *mutex) -{ - int err; - - err = pthread_mutex_init(&mutex->lock, NULL); - if (err) - error_exit(err, __func__); -} - -void qemu_mutex_destroy(QemuMutex *mutex) -{ - int err; - - err = pthread_mutex_destroy(&mutex->lock); - if (err) - error_exit(err, __func__); -} - -void qemu_mutex_lock(QemuMutex *mutex) -{ - int err; - - err = pthread_mutex_lock(&mutex->lock); - if (err) - error_exit(err, __func__); -} - -int qemu_mutex_trylock(QemuMutex *mutex) -{ - return pthread_mutex_trylock(&mutex->lock); -} - -static void timespec_add_ms(struct timespec *ts, uint64_t msecs) -{ - ts->tv_sec = ts->tv_sec + (long)(msecs / 1000); - ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000); - if (ts->tv_nsec >= 1000000000) { - ts->tv_nsec -= 1000000000; - ts->tv_sec++; - } -} - -int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs) -{ - int err; - struct timespec ts; - - clock_gettime(CLOCK_REALTIME, &ts); - timespec_add_ms(&ts, msecs); - - err = pthread_mutex_timedlock(&mutex->lock, &ts); - if (err && err != ETIMEDOUT) - error_exit(err, __func__); - return err; -} - -void qemu_mutex_unlock(QemuMutex *mutex) -{ - int err; - - err = pthread_mutex_unlock(&mutex->lock); - if (err) - error_exit(err, __func__); -} - -void qemu_cond_init(QemuCond *cond) -{ - int err; - - err = pthread_cond_init(&cond->cond, NULL); - if (err) - error_exit(err, __func__); -} - -void qemu_cond_destroy(QemuCond *cond) -{ - int err; - - err = pthread_cond_destroy(&cond->cond); - if (err) - error_exit(err, __func__); -} - -void qemu_cond_signal(QemuCond *cond) -{ - int err; - - err = pthread_cond_signal(&cond->cond); - if (err) - error_exit(err, __func__); -} - -void qemu_cond_broadcast(QemuCond *cond) -{ - int err; - - err = pthread_cond_broadcast(&cond->cond); - if (err) - error_exit(err, __func__); -} - -void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) -{ - int err; - - err = pthread_cond_wait(&cond->cond, &mutex->lock); - if (err) - error_exit(err, __func__); -} - -int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs) -{ - struct timespec ts; - int err; - - clock_gettime(CLOCK_REALTIME, &ts); - timespec_add_ms(&ts, msecs); - - err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts); - if (err && err != ETIMEDOUT) - error_exit(err, __func__); - return err; -} - -void qemu_thread_create(QemuThread *thread, - void *(*start_routine)(void*), - void *arg) -{ - int err; - - /* Leave signal handling to the iothread. */ - sigset_t set, oldset; - - sigfillset(&set); - pthread_sigmask(SIG_SETMASK, &set, &oldset); - err = pthread_create(&thread->thread, NULL, start_routine, arg); - if (err) - error_exit(err, __func__); - - pthread_sigmask(SIG_SETMASK, &oldset, NULL); -} - -void qemu_thread_signal(QemuThread *thread, int sig) -{ - int err; - - err = pthread_kill(thread->thread, sig); - if (err) - error_exit(err, __func__); -} - -void qemu_thread_self(QemuThread *thread) -{ - thread->thread = pthread_self(); -} - -int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2) -{ - return pthread_equal(thread1->thread, thread2->thread); -} - -void qemu_thread_exit(void *retval) -{ - pthread_exit(retval); -} diff --git a/qemu-thread.h b/qemu-thread.h index 19bb30c..e008b60 100644 --- a/qemu-thread.h +++ b/qemu-thread.h @@ -1,44 +1,44 @@ #ifndef __QEMU_THREAD_H #define __QEMU_THREAD_H 1 -#include "semaphore.h" -#include "pthread.h" -struct QemuMutex { - pthread_mutex_t lock; -}; - -struct QemuCond { - pthread_cond_t cond; -}; - -struct QemuThread { - pthread_t thread; -}; +#include typedef struct QemuMutex QemuMutex; typedef struct QemuCond QemuCond; typedef struct QemuThread QemuThread; +#ifdef _WIN32 +#include "qemu-thread-win32.h" +#else +#include "qemu-thread-posix.h" +#endif + void qemu_mutex_init(QemuMutex *mutex); void qemu_mutex_destroy(QemuMutex *mutex); void qemu_mutex_lock(QemuMutex *mutex); int qemu_mutex_trylock(QemuMutex *mutex); -int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs); void qemu_mutex_unlock(QemuMutex *mutex); +#define rcu_read_lock() do { } while (0) +#define rcu_read_unlock() do { } while (0) + void qemu_cond_init(QemuCond *cond); void qemu_cond_destroy(QemuCond *cond); + +/* + * IMPORTANT: The implementation does not guarantee that pthread_cond_signal + * and pthread_cond_broadcast can be called except while the same mutex is + * held as in the corresponding pthread_cond_wait calls! + */ void qemu_cond_signal(QemuCond *cond); void qemu_cond_broadcast(QemuCond *cond); void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex); -int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs); void qemu_thread_create(QemuThread *thread, void *(*start_routine)(void*), void *arg); -void qemu_thread_signal(QemuThread *thread, int sig); -void qemu_thread_self(QemuThread *thread); -int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2); +void qemu_thread_get_self(QemuThread *thread); +int qemu_thread_is_self(QemuThread *thread); void qemu_thread_exit(void *retval); #endif diff --git a/qemu-timer.c b/qemu-timer.c index b0db780..cd026c6 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -39,15 +39,6 @@ #include #endif -#ifdef __linux__ -#include -#include -/* For the benefit of older linux systems which don't supply it, - we use a local copy of hpet.h. */ -/* #include */ -#include "hpet.h" -#endif - #ifdef _WIN32 #include #include @@ -55,96 +46,6 @@ #include "qemu-timer.h" -/* Conversion factor from emulated instructions to virtual clock ticks. */ -int icount_time_shift; -/* Arbitrarily pick 1MIPS as the minimum allowable speed. */ -#define MAX_ICOUNT_SHIFT 10 -/* Compensate for varying guest execution speed. */ -int64_t qemu_icount_bias; -static QEMUTimer *icount_rt_timer; -static QEMUTimer *icount_vm_timer; - -/***********************************************************/ -/* guest cycle counter */ - -typedef struct TimersState { - int64_t cpu_ticks_prev; - int64_t cpu_ticks_offset; - int64_t cpu_clock_offset; - int32_t cpu_ticks_enabled; - int64_t dummy; -} TimersState; - -TimersState timers_state; - -/* return the host CPU cycle counter and handle stop/restart */ -int64_t cpu_get_ticks(void) -{ - if (use_icount) { - return cpu_get_icount(); - } - if (!timers_state.cpu_ticks_enabled) { - return timers_state.cpu_ticks_offset; - } else { - int64_t ticks; - ticks = cpu_get_real_ticks(); - if (timers_state.cpu_ticks_prev > ticks) { - /* Note: non increasing ticks may happen if the host uses - software suspend */ - timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks; - } - timers_state.cpu_ticks_prev = ticks; - return ticks + timers_state.cpu_ticks_offset; - } -} - -/* return the host CPU monotonic timer and handle stop/restart */ -static int64_t cpu_get_clock(void) -{ - int64_t ti; - if (!timers_state.cpu_ticks_enabled) { - return timers_state.cpu_clock_offset; - } else { - ti = get_clock(); - return ti + timers_state.cpu_clock_offset; - } -} - -static int64_t qemu_icount_delta(void) -{ - if (!use_icount) { - return 5000 * (int64_t) 1000000; - } else if (use_icount == 1) { - /* When not using an adaptive execution frequency - we tend to get badly out of sync with real time, - so just delay for a reasonable amount of time. */ - return 0; - } else { - return cpu_get_icount() - cpu_get_clock(); - } -} - -/* enable cpu_get_ticks() */ -void cpu_enable_ticks(void) -{ - if (!timers_state.cpu_ticks_enabled) { - timers_state.cpu_ticks_offset -= cpu_get_real_ticks(); - timers_state.cpu_clock_offset -= get_clock(); - timers_state.cpu_ticks_enabled = 1; - } -} - -/* disable cpu_get_ticks() : the clock is stopped. You must not call - cpu_get_ticks() after that. */ -void cpu_disable_ticks(void) -{ - if (timers_state.cpu_ticks_enabled) { - timers_state.cpu_ticks_offset = cpu_get_ticks(); - timers_state.cpu_clock_offset = cpu_get_clock(); - timers_state.cpu_ticks_enabled = 0; - } -} - /***********************************************************/ /* timers */ @@ -155,12 +56,17 @@ void cpu_disable_ticks(void) struct QEMUClock { int type; int enabled; - /* XXX: add frequency */ + + QEMUTimer *active_timers; + + NotifierList reset_notifiers; + int64_t last; }; struct QEMUTimer { QEMUClock *clock; - int64_t expire_time; + int64_t expire_time; /* in nanoseconds */ + int scale; QEMUTimerCB *cb; void *opaque; struct QEMUTimer *next; @@ -170,15 +76,24 @@ struct qemu_alarm_timer { char const *name; int (*start)(struct qemu_alarm_timer *t); void (*stop)(struct qemu_alarm_timer *t); - void (*rearm)(struct qemu_alarm_timer *t); - void *priv; - + void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns); +#if defined(__linux__) + int fd; + timer_t timer; +#elif defined(_WIN32) + HANDLE timer; +#endif char expired; char pending; }; static struct qemu_alarm_timer *alarm_timer; +static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time) +{ + return timer_head && (timer_head->expire_time <= current_time); +} + int qemu_alarm_pending(void) { return alarm_timer->pending; @@ -189,12 +104,46 @@ static inline int alarm_has_dynticks(struct qemu_alarm_timer *t) return !!t->rearm; } +static int64_t qemu_next_alarm_deadline(void) +{ + int64_t delta; + int64_t rtdelta; + + if (!use_icount && vm_clock->active_timers) { + delta = vm_clock->active_timers->expire_time - + qemu_get_clock_ns(vm_clock); + } else { + delta = INT32_MAX; + } + if (host_clock->active_timers) { + int64_t hdelta = host_clock->active_timers->expire_time - + qemu_get_clock_ns(host_clock); + if (hdelta < delta) { + delta = hdelta; + } + } + if (rt_clock->active_timers) { + rtdelta = (rt_clock->active_timers->expire_time - + qemu_get_clock_ns(rt_clock)); + if (rtdelta < delta) { + delta = rtdelta; + } + } + + return delta; +} + static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) { - if (!alarm_has_dynticks(t)) + int64_t nearest_delta_ns; + assert(alarm_has_dynticks(t)); + if (!rt_clock->active_timers && + !vm_clock->active_timers && + !host_clock->active_timers) { return; - - t->rearm(t); + } + nearest_delta_ns = qemu_next_alarm_deadline(); + t->rearm(t, nearest_delta_ns); } /* TODO: MIN_TIMER_REARM_NS should be optimized */ @@ -202,107 +151,40 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) #ifdef _WIN32 -struct qemu_alarm_win32 { - MMRESULT timerId; - unsigned int period; -} alarm_win32_data = {0, 0}; +static int mm_start_timer(struct qemu_alarm_timer *t); +static void mm_stop_timer(struct qemu_alarm_timer *t); +static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); static int win32_start_timer(struct qemu_alarm_timer *t); static void win32_stop_timer(struct qemu_alarm_timer *t); -static void win32_rearm_timer(struct qemu_alarm_timer *t); +static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); #else static int unix_start_timer(struct qemu_alarm_timer *t); static void unix_stop_timer(struct qemu_alarm_timer *t); +static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); #ifdef __linux__ static int dynticks_start_timer(struct qemu_alarm_timer *t); static void dynticks_stop_timer(struct qemu_alarm_timer *t); -static void dynticks_rearm_timer(struct qemu_alarm_timer *t); - -static int hpet_start_timer(struct qemu_alarm_timer *t); -static void hpet_stop_timer(struct qemu_alarm_timer *t); - -static int rtc_start_timer(struct qemu_alarm_timer *t); -static void rtc_stop_timer(struct qemu_alarm_timer *t); +static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); #endif /* __linux__ */ #endif /* _WIN32 */ -/* Correlation between real and virtual time is always going to be - fairly approximate, so ignore small variation. - When the guest is idle real and virtual time will be aligned in - the IO wait loop. */ -#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10) - -static void icount_adjust(void) -{ - int64_t cur_time; - int64_t cur_icount; - int64_t delta; - static int64_t last_delta; - /* If the VM is not running, then do nothing. */ - if (!vm_running) - return; - - cur_time = cpu_get_clock(); - cur_icount = qemu_get_clock(vm_clock); - delta = cur_icount - cur_time; - /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ - if (delta > 0 - && last_delta + ICOUNT_WOBBLE < delta * 2 - && icount_time_shift > 0) { - /* The guest is getting too far ahead. Slow time down. */ - icount_time_shift--; - } - if (delta < 0 - && last_delta - ICOUNT_WOBBLE > delta * 2 - && icount_time_shift < MAX_ICOUNT_SHIFT) { - /* The guest is getting too far behind. Speed time up. */ - icount_time_shift++; - } - last_delta = delta; - qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift); -} - -static void icount_adjust_rt(void * opaque) -{ - qemu_mod_timer(icount_rt_timer, - qemu_get_clock(rt_clock) + 1000); - icount_adjust(); -} - -static void icount_adjust_vm(void * opaque) -{ - qemu_mod_timer(icount_vm_timer, - qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10); - icount_adjust(); -} - -int64_t qemu_icount_round(int64_t count) -{ - return (count + (1 << icount_time_shift) - 1) >> icount_time_shift; -} - static struct qemu_alarm_timer alarm_timers[] = { #ifndef _WIN32 #ifdef __linux__ {"dynticks", dynticks_start_timer, - dynticks_stop_timer, dynticks_rearm_timer, NULL}, - /* HPET - if available - is preferred */ - {"hpet", hpet_start_timer, hpet_stop_timer, NULL, NULL}, - /* ...otherwise try RTC */ - {"rtc", rtc_start_timer, rtc_stop_timer, NULL, NULL}, + dynticks_stop_timer, dynticks_rearm_timer}, #endif - {"unix", unix_start_timer, unix_stop_timer, NULL, NULL}, + {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer}, #else - {"dynticks", win32_start_timer, - win32_stop_timer, win32_rearm_timer, &alarm_win32_data}, - {"win32", win32_start_timer, - win32_stop_timer, NULL, &alarm_win32_data}, + {"mmtimer", mm_start_timer, mm_stop_timer, mm_rearm_timer}, + {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer}, #endif {NULL, } }; @@ -330,7 +212,7 @@ void configure_alarms(char const *opt) exit(0); } - arg = qemu_strdup(opt); + arg = g_strdup(opt); /* Reorder the array */ name = strtok(arg, ","); @@ -359,7 +241,7 @@ next: name = strtok(NULL, ","); } - qemu_free(arg); + g_free(arg); if (cur) { /* Disable remaining timers */ @@ -371,42 +253,72 @@ next: } } -#define QEMU_NUM_CLOCKS 3 - QEMUClock *rt_clock; QEMUClock *vm_clock; QEMUClock *host_clock; -static QEMUTimer *active_timers[QEMU_NUM_CLOCKS]; - static QEMUClock *qemu_new_clock(int type) { QEMUClock *clock; - clock = qemu_mallocz(sizeof(QEMUClock)); + + clock = g_malloc0(sizeof(QEMUClock)); clock->type = type; clock->enabled = 1; + clock->last = INT64_MIN; + notifier_list_init(&clock->reset_notifiers); return clock; } void qemu_clock_enable(QEMUClock *clock, int enabled) { + bool old = clock->enabled; clock->enabled = enabled; + if (enabled && !old) { + qemu_rearm_alarm_timer(alarm_timer); + } } -QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque) +int64_t qemu_clock_has_timers(QEMUClock *clock) +{ + return !!clock->active_timers; +} + +int64_t qemu_clock_expired(QEMUClock *clock) +{ + return (clock->active_timers && + clock->active_timers->expire_time < qemu_get_clock_ns(clock)); +} + +int64_t qemu_clock_deadline(QEMUClock *clock) +{ + /* To avoid problems with overflow limit this to 2^32. */ + int64_t delta = INT32_MAX; + + if (clock->active_timers) { + delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock); + } + if (delta < 0) { + delta = 0; + } + return delta; +} + +QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale, + QEMUTimerCB *cb, void *opaque) { QEMUTimer *ts; - ts = qemu_mallocz(sizeof(QEMUTimer)); + ts = g_malloc0(sizeof(QEMUTimer)); ts->clock = clock; ts->cb = cb; ts->opaque = opaque; + ts->scale = scale; return ts; } void qemu_free_timer(QEMUTimer *ts) { - qemu_free(ts); + g_free(ts); } /* stop a timer, but do not dealloc it */ @@ -416,7 +328,7 @@ void qemu_del_timer(QEMUTimer *ts) /* NOTE: this code must be signal safe because qemu_timer_expired() can be called from a signal. */ - pt = &active_timers[ts->clock->type]; + pt = &ts->clock->active_timers; for(;;) { t = *pt; if (!t) @@ -431,7 +343,7 @@ void qemu_del_timer(QEMUTimer *ts) /* modify the current timer so that it will be fired when current_time >= expire_time. The corresponding callback will be called. */ -void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) +void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time) { QEMUTimer **pt, *t; @@ -440,13 +352,12 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) /* add the timer in the sorted list */ /* NOTE: this code must be signal safe because qemu_timer_expired() can be called from a signal. */ - pt = &active_timers[ts->clock->type]; + pt = &ts->clock->active_timers; for(;;) { t = *pt; - if (!t) - break; - if (t->expire_time > expire_time) + if (!qemu_timer_expired_ns(t, expire_time)) { break; + } pt = &t->next; } ts->expire_time = expire_time; @@ -454,20 +365,27 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) *pt = ts; /* Rearm if necessary */ - if (pt == &active_timers[ts->clock->type]) { + if (pt == &ts->clock->active_timers) { if (!alarm_timer->pending) { qemu_rearm_alarm_timer(alarm_timer); } /* Interrupt execution to force deadline recalculation. */ - if (use_icount) + qemu_clock_warp(ts->clock); + if (use_icount) { qemu_notify_event(); + } } } +void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) +{ + qemu_mod_timer_ns(ts, expire_time * ts->scale); +} + int qemu_timer_pending(QEMUTimer *ts) { QEMUTimer *t; - for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) { + for (t = ts->clock->active_timers; t != NULL; t = t->next) { if (t == ts) return 1; } @@ -476,9 +394,7 @@ int qemu_timer_pending(QEMUTimer *ts) int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time) { - if (!timer_head) - return 0; - return (timer_head->expire_time <= current_time); + return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale); } static void qemu_run_timers(QEMUClock *clock) @@ -489,12 +405,13 @@ static void qemu_run_timers(QEMUClock *clock) if (!clock->enabled) return; - current_time = qemu_get_clock (clock); - ptimer_head = &active_timers[clock->type]; + current_time = qemu_get_clock_ns(clock); + ptimer_head = &clock->active_timers; for(;;) { ts = *ptimer_head; - if (!ts || ts->expire_time > current_time) + if (!qemu_timer_expired_ns(ts, current_time)) { break; + } /* remove timer from the list before calling the callback */ *ptimer_head = ts->next; ts->next = NULL; @@ -504,25 +421,10 @@ static void qemu_run_timers(QEMUClock *clock) } } -int64_t qemu_get_clock(QEMUClock *clock) -{ - switch(clock->type) { - case QEMU_CLOCK_REALTIME: - return get_clock() / 1000000; - default: - case QEMU_CLOCK_VIRTUAL: - if (use_icount) { - return cpu_get_icount(); - } else { - return cpu_get_clock(); - } - case QEMU_CLOCK_HOST: - return get_clock_realtime(); - } -} - int64_t qemu_get_clock_ns(QEMUClock *clock) { + int64_t now, last; + switch(clock->type) { case QEMU_CLOCK_REALTIME: return get_clock(); @@ -534,86 +436,36 @@ int64_t qemu_get_clock_ns(QEMUClock *clock) return cpu_get_clock(); } case QEMU_CLOCK_HOST: - return get_clock_realtime(); + now = get_clock_realtime(); + last = clock->last; + clock->last = now; + if (now < last) { + notifier_list_notify(&clock->reset_notifiers, &now); + } + return now; } } -void init_clocks(void) +void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) { - rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME); - vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL); - host_clock = qemu_new_clock(QEMU_CLOCK_HOST); - - rtc_clock = host_clock; + notifier_list_add(&clock->reset_notifiers, notifier); } -/* save a timer */ -void qemu_put_timer(QEMUFile *f, QEMUTimer *ts) +void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) { - uint64_t expire_time; - - if (qemu_timer_pending(ts)) { - expire_time = ts->expire_time; - } else { - expire_time = -1; - } - qemu_put_be64(f, expire_time); + notifier_list_remove(&clock->reset_notifiers, notifier); } -void qemu_get_timer(QEMUFile *f, QEMUTimer *ts) +void init_clocks(void) { - uint64_t expire_time; - - expire_time = qemu_get_be64(f); - if (expire_time != -1) { - qemu_mod_timer(ts, expire_time); - } else { - qemu_del_timer(ts); - } + rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME); + vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL); + host_clock = qemu_new_clock(QEMU_CLOCK_HOST); } -static const VMStateDescription vmstate_timers = { - .name = "timer", - .version_id = 2, - .minimum_version_id = 1, - .minimum_version_id_old = 1, - .fields = (VMStateField []) { - VMSTATE_INT64(cpu_ticks_offset, TimersState), - VMSTATE_INT64(dummy, TimersState), - VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2), - VMSTATE_END_OF_LIST() - } -}; - -void configure_icount(const char *option) +uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts) { - vmstate_register(NULL, 0, &vmstate_timers, &timers_state); - if (!option) - return; - - if (strcmp(option, "auto") != 0) { - icount_time_shift = strtol(option, NULL, 0); - use_icount = 1; - return; - } - - use_icount = 2; - - /* 125MIPS seems a reasonable initial guess at the guest speed. - It will be corrected fairly quickly anyway. */ - icount_time_shift = 3; - - /* Have both realtime and virtual time triggers for speed adjustment. - The realtime trigger catches emulated time passing too slowly, - the virtual time trigger catches emulated time passing too fast. - Realtime triggers occur even when idle, so use them less frequently - than VM triggers. */ - icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL); - qemu_mod_timer(icount_rt_timer, - qemu_get_clock(rt_clock) + 1000); - icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL); - qemu_mod_timer(icount_vm_timer, - qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10); + return qemu_timer_pending(ts) ? ts->expire_time : -1; } void qemu_run_all_timers(void) @@ -627,20 +479,13 @@ void qemu_run_all_timers(void) } /* vm time timers */ - if (vm_running) { - qemu_run_timers(vm_clock); - } - + qemu_run_timers(vm_clock); qemu_run_timers(rt_clock); qemu_run_timers(host_clock); } -static int64_t qemu_next_alarm_deadline(void); - #ifdef _WIN32 -static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, - DWORD_PTR dwUser, DWORD_PTR dw1, - DWORD_PTR dw2) +static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused) #else static void host_alarm_handler(int host_signum) #endif @@ -655,7 +500,7 @@ static void host_alarm_handler(int host_signum) static int64_t delta_min = INT64_MAX; static int64_t delta_max, delta_cum, last_clock, delta, ti; static int count; - ti = qemu_get_clock(vm_clock); + ti = qemu_get_clock_ns(vm_clock); if (last_clock != 0) { delta = ti - last_clock; if (delta < delta_min) @@ -686,157 +531,9 @@ static void host_alarm_handler(int host_signum) } } -int64_t qemu_next_deadline(void) -{ - /* To avoid problems with overflow limit this to 2^32. */ - int64_t delta = INT32_MAX; - - if (active_timers[QEMU_CLOCK_VIRTUAL]) { - delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time - - qemu_get_clock_ns(vm_clock); - } - if (active_timers[QEMU_CLOCK_HOST]) { - int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time - - qemu_get_clock_ns(host_clock); - if (hdelta < delta) - delta = hdelta; - } - - if (delta < 0) - delta = 0; - - return delta; -} - -static int64_t qemu_next_alarm_deadline(void) -{ - int64_t delta; - int64_t rtdelta; - - if (!use_icount && active_timers[QEMU_CLOCK_VIRTUAL]) { - delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time - - qemu_get_clock(vm_clock); - } else { - delta = INT32_MAX; - } - if (active_timers[QEMU_CLOCK_HOST]) { - int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time - - qemu_get_clock_ns(host_clock); - if (hdelta < delta) - delta = hdelta; - } - if (active_timers[QEMU_CLOCK_REALTIME]) { - rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time * 1000000 - - qemu_get_clock_ns(rt_clock)); - if (rtdelta < delta) - delta = rtdelta; - } - - return delta; -} - #if defined(__linux__) -#define RTC_FREQ 1024 - -static void enable_sigio_timer(int fd) -{ - struct sigaction act; - - /* timer signal */ - sigfillset(&act.sa_mask); - act.sa_flags = 0; - act.sa_handler = host_alarm_handler; - - sigaction(SIGIO, &act, NULL); - fcntl_setfl(fd, O_ASYNC); - fcntl(fd, F_SETOWN, getpid()); -} - -static int hpet_start_timer(struct qemu_alarm_timer *t) -{ - struct hpet_info info; - int r, fd; - - fd = qemu_open("/dev/hpet", O_RDONLY); - if (fd < 0) - return -1; - - /* Set frequency */ - r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ); - if (r < 0) { - fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n" - "error, but for better emulation accuracy type:\n" - "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n"); - goto fail; - } - - /* Check capabilities */ - r = ioctl(fd, HPET_INFO, &info); - if (r < 0) - goto fail; - - /* Enable periodic mode */ - r = ioctl(fd, HPET_EPI, 0); - if (info.hi_flags && (r < 0)) - goto fail; - - /* Enable interrupt */ - r = ioctl(fd, HPET_IE_ON, 0); - if (r < 0) - goto fail; - - enable_sigio_timer(fd); - t->priv = (void *)(long)fd; - - return 0; -fail: - close(fd); - return -1; -} - -static void hpet_stop_timer(struct qemu_alarm_timer *t) -{ - int fd = (long)t->priv; - - close(fd); -} - -static int rtc_start_timer(struct qemu_alarm_timer *t) -{ - int rtc_fd; - unsigned long current_rtc_freq = 0; - - TFR(rtc_fd = qemu_open("/dev/rtc", O_RDONLY)); - if (rtc_fd < 0) - return -1; - ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq); - if (current_rtc_freq != RTC_FREQ && - ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { - fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n" - "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n" - "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n"); - goto fail; - } - if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) { - fail: - close(rtc_fd); - return -1; - } - - enable_sigio_timer(rtc_fd); - - t->priv = (void *)(long)rtc_fd; - - return 0; -} - -static void rtc_stop_timer(struct qemu_alarm_timer *t) -{ - int rtc_fd = (long)t->priv; - - close(rtc_fd); -} +#include "compatfd.h" static int dynticks_start_timer(struct qemu_alarm_timer *t) { @@ -857,6 +554,12 @@ static int dynticks_start_timer(struct qemu_alarm_timer *t) memset(&ev, 0, sizeof(ev)); ev.sigev_value.sival_int = 0; ev.sigev_notify = SIGEV_SIGNAL; +#ifdef SIGEV_THREAD_ID + if (qemu_signalfd_available()) { + ev.sigev_notify = SIGEV_THREAD_ID; + ev._sigev_un._tid = qemu_get_thread_id(); + } +#endif /* SIGEV_THREAD_ID */ ev.sigev_signo = SIGALRM; if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) { @@ -868,32 +571,25 @@ static int dynticks_start_timer(struct qemu_alarm_timer *t) return -1; } - t->priv = (void *)(long)host_timer; + t->timer = host_timer; return 0; } static void dynticks_stop_timer(struct qemu_alarm_timer *t) { - timer_t host_timer = (timer_t)(long)t->priv; + timer_t host_timer = t->timer; timer_delete(host_timer); } -static void dynticks_rearm_timer(struct qemu_alarm_timer *t) +static void dynticks_rearm_timer(struct qemu_alarm_timer *t, + int64_t nearest_delta_ns) { - timer_t host_timer = (timer_t)(long)t->priv; + timer_t host_timer = t->timer; struct itimerspec timeout; - int64_t nearest_delta_ns = INT64_MAX; int64_t current_ns; - assert(alarm_has_dynticks(t)); - if (!active_timers[QEMU_CLOCK_REALTIME] && - !active_timers[QEMU_CLOCK_VIRTUAL] && - !active_timers[QEMU_CLOCK_HOST]) - return; - - nearest_delta_ns = qemu_next_alarm_deadline(); if (nearest_delta_ns < MIN_TIMER_REARM_NS) nearest_delta_ns = MIN_TIMER_REARM_NS; @@ -925,8 +621,6 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t) static int unix_start_timer(struct qemu_alarm_timer *t) { struct sigaction act; - struct itimerval itv; - int err; /* timer signal */ sigfillset(&act.sa_mask); @@ -934,18 +628,28 @@ static int unix_start_timer(struct qemu_alarm_timer *t) act.sa_handler = host_alarm_handler; sigaction(SIGALRM, &act, NULL); + return 0; +} - itv.it_interval.tv_sec = 0; - /* for i386 kernel 2.6 to get 1 ms */ - itv.it_interval.tv_usec = 999; - itv.it_value.tv_sec = 0; - itv.it_value.tv_usec = 10 * 1000; +static void unix_rearm_timer(struct qemu_alarm_timer *t, + int64_t nearest_delta_ns) +{ + struct itimerval itv; + int err; - err = setitimer(ITIMER_REAL, &itv, NULL); - if (err) - return -1; + if (nearest_delta_ns < MIN_TIMER_REARM_NS) + nearest_delta_ns = MIN_TIMER_REARM_NS; - return 0; + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */ + itv.it_value.tv_sec = nearest_delta_ns / 1000000000; + itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000; + err = setitimer(ITIMER_REAL, &itv, NULL); + if (err) { + perror("setitimer"); + fprintf(stderr, "Internal timer error: aborting\n"); + exit(1); + } } static void unix_stop_timer(struct qemu_alarm_timer *t) @@ -961,81 +665,154 @@ static void unix_stop_timer(struct qemu_alarm_timer *t) #ifdef _WIN32 -static int win32_start_timer(struct qemu_alarm_timer *t) +static MMRESULT mm_timer; +static unsigned mm_period; + +static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, + DWORD_PTR dwUser, DWORD_PTR dw1, + DWORD_PTR dw2) +{ + struct qemu_alarm_timer *t = alarm_timer; + if (!t) { + return; + } + if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) { + t->expired = alarm_has_dynticks(t); + t->pending = 1; + qemu_notify_event(); + } +} + +static int mm_start_timer(struct qemu_alarm_timer *t) { TIMECAPS tc; - struct qemu_alarm_win32 *data = t->priv; UINT flags; memset(&tc, 0, sizeof(tc)); timeGetDevCaps(&tc, sizeof(tc)); - data->period = tc.wPeriodMin; - timeBeginPeriod(data->period); + mm_period = tc.wPeriodMin; + timeBeginPeriod(mm_period); flags = TIME_CALLBACK_FUNCTION; - if (alarm_has_dynticks(t)) + if (alarm_has_dynticks(t)) { flags |= TIME_ONESHOT; - else + } else { flags |= TIME_PERIODIC; + } - data->timerId = timeSetEvent(1, // interval (ms) - data->period, // resolution - host_alarm_handler, // function - (DWORD)t, // parameter - flags); + mm_timer = timeSetEvent(1, /* interval (ms) */ + mm_period, /* resolution */ + mm_alarm_handler, /* function */ + (DWORD_PTR)t, /* parameter */ + flags); - if (!data->timerId) { + if (!mm_timer) { fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", GetLastError()); - timeEndPeriod(data->period); + timeEndPeriod(mm_period); return -1; } return 0; } -static void win32_stop_timer(struct qemu_alarm_timer *t) +static void mm_stop_timer(struct qemu_alarm_timer *t) { - struct qemu_alarm_win32 *data = t->priv; - - timeKillEvent(data->timerId); - timeEndPeriod(data->period); + timeKillEvent(mm_timer); + timeEndPeriod(mm_period); } -static void win32_rearm_timer(struct qemu_alarm_timer *t) +static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta) { - struct qemu_alarm_win32 *data = t->priv; - - assert(alarm_has_dynticks(t)); - if (!active_timers[QEMU_CLOCK_REALTIME] && - !active_timers[QEMU_CLOCK_VIRTUAL] && - !active_timers[QEMU_CLOCK_HOST]) - return; - - timeKillEvent(data->timerId); + int nearest_delta_ms = (delta + 999999) / 1000000; + if (nearest_delta_ms < 1) { + nearest_delta_ms = 1; + } - data->timerId = timeSetEvent(1, - data->period, - host_alarm_handler, - (DWORD)t, - TIME_ONESHOT | TIME_CALLBACK_FUNCTION); + timeKillEvent(mm_timer); + mm_timer = timeSetEvent(nearest_delta_ms, + mm_period, + mm_alarm_handler, + (DWORD_PTR)t, + TIME_ONESHOT | TIME_CALLBACK_FUNCTION); - if (!data->timerId) { + if (!mm_timer) { fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", GetLastError()); - timeEndPeriod(data->period); + timeEndPeriod(mm_period); exit(1); } } +static int win32_start_timer(struct qemu_alarm_timer *t) +{ + HANDLE hTimer; + BOOLEAN success; + + /* If you call ChangeTimerQueueTimer on a one-shot timer (its period + is zero) that has already expired, the timer is not updated. Since + creating a new timer is relatively expensive, set a bogus one-hour + interval in the dynticks case. */ + success = CreateTimerQueueTimer(&hTimer, + NULL, + host_alarm_handler, + t, + 1, + alarm_has_dynticks(t) ? 3600000 : 1, + WT_EXECUTEINTIMERTHREAD); + + if (!success) { + fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", + GetLastError()); + return -1; + } + + t->timer = hTimer; + return 0; +} + +static void win32_stop_timer(struct qemu_alarm_timer *t) +{ + HANDLE hTimer = t->timer; + + if (hTimer) { + DeleteTimerQueueTimer(NULL, hTimer, NULL); + } +} + +static void win32_rearm_timer(struct qemu_alarm_timer *t, + int64_t nearest_delta_ns) +{ + HANDLE hTimer = t->timer; + int nearest_delta_ms; + BOOLEAN success; + + nearest_delta_ms = (nearest_delta_ns + 999999) / 1000000; + if (nearest_delta_ms < 1) { + nearest_delta_ms = 1; + } + success = ChangeTimerQueueTimer(NULL, + hTimer, + nearest_delta_ms, + 3600000); + + if (!success) { + fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n", + GetLastError()); + exit(-1); + } + +} + #endif /* _WIN32 */ -static void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason) +static void quit_timers(void) { - if (running) - qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque); + struct qemu_alarm_timer *t = alarm_timer; + alarm_timer = NULL; + t->stop(t); } int init_timer_alarm(void) @@ -1057,9 +834,9 @@ int init_timer_alarm(void) } /* first event is at time 0 */ + atexit(quit_timers); t->pending = 1; alarm_timer = t; - qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t); return 0; @@ -1067,55 +844,8 @@ fail: return err; } -void quit_timers(void) -{ - struct qemu_alarm_timer *t = alarm_timer; - alarm_timer = NULL; - t->stop(t); -} - int qemu_calculate_timeout(void) { - int timeout; - -#ifdef CONFIG_IOTHREAD - /* When using icount, making forward progress with qemu_icount when the - guest CPU is idle is critical. We only use the static io-thread timeout - for non icount runs. */ - if (!use_icount) { - return 1000; - } -#endif - - if (!vm_running) - timeout = 5000; - else { - /* XXX: use timeout computed from timers */ - int64_t add; - int64_t delta; - /* Advance virtual time to the next event. */ - delta = qemu_icount_delta(); - if (delta > 0) { - /* If virtual time is ahead of real time then just - wait for IO. */ - timeout = (delta + 999999) / 1000000; - } else { - /* Wait for either IO to occur or the next - timer event. */ - add = qemu_next_deadline(); - /* We advance the timer before checking for IO. - Limit the amount we advance so that early IO - activity won't get the guest too far ahead. */ - if (add > 10000000) - add = 10000000; - delta += add; - qemu_icount += qemu_icount_round (add); - timeout = delta / 1000000; - if (timeout < 0) - timeout = 0; - } - } - - return timeout; + return 1000; } diff --git a/qemu-timer.h b/qemu-timer.h index 8cd8f83..67ca72e 100644 --- a/qemu-timer.h +++ b/qemu-timer.h @@ -2,16 +2,21 @@ #define QEMU_TIMER_H #include "qemu-common.h" +#include "main-loop.h" +#include "notify.h" #include #include #ifdef _WIN32 #include -#include #endif /* timers */ +#define SCALE_MS 1000000 +#define SCALE_US 1000 +#define SCALE_NS 1 + typedef struct QEMUClock QEMUClock; typedef void QEMUTimerCB(void *opaque); @@ -33,26 +38,54 @@ extern QEMUClock *vm_clock; the virtual clock. */ extern QEMUClock *host_clock; -int64_t qemu_get_clock(QEMUClock *clock); int64_t qemu_get_clock_ns(QEMUClock *clock); +int64_t qemu_clock_has_timers(QEMUClock *clock); +int64_t qemu_clock_expired(QEMUClock *clock); +int64_t qemu_clock_deadline(QEMUClock *clock); void qemu_clock_enable(QEMUClock *clock, int enabled); +void qemu_clock_warp(QEMUClock *clock); + +void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier); +void qemu_unregister_clock_reset_notifier(QEMUClock *clock, + Notifier *notifier); -QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque); +QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale, + QEMUTimerCB *cb, void *opaque); void qemu_free_timer(QEMUTimer *ts); void qemu_del_timer(QEMUTimer *ts); +void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time); void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time); int qemu_timer_pending(QEMUTimer *ts); int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time); +uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts); void qemu_run_all_timers(void); int qemu_alarm_pending(void); -int64_t qemu_next_deadline(void); void configure_alarms(char const *opt); -void configure_icount(const char *option); int qemu_calculate_timeout(void); void init_clocks(void); int init_timer_alarm(void); -void quit_timers(void); + +int64_t cpu_get_ticks(void); +void cpu_enable_ticks(void); +void cpu_disable_ticks(void); + +static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb, + void *opaque) +{ + return qemu_new_timer(clock, SCALE_NS, cb, opaque); +} + +static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock, QEMUTimerCB *cb, + void *opaque) +{ + return qemu_new_timer(clock, SCALE_MS, cb, opaque); +} + +static inline int64_t qemu_get_clock_ms(QEMUClock *clock) +{ + return qemu_get_clock_ns(clock) / SCALE_MS; +} static inline int64_t get_ticks_per_sec(void) { @@ -118,16 +151,10 @@ uint64_t ptimer_get_count(ptimer_state *s); void ptimer_set_count(ptimer_state *s, uint64_t count); void ptimer_run(ptimer_state *s, int oneshot); void ptimer_stop(ptimer_state *s); -void qemu_put_ptimer(QEMUFile *f, ptimer_state *s); -void qemu_get_ptimer(QEMUFile *f, ptimer_state *s); /* icount */ -int64_t qemu_icount_round(int64_t count); -extern int64_t qemu_icount; -extern int use_icount; -extern int icount_time_shift; -extern int64_t qemu_icount_bias; int64_t cpu_get_icount(void); +int64_t cpu_get_clock(void); /*******************************************/ /* host CPU ticks (if available) */ @@ -283,22 +310,6 @@ static inline int64_t cpu_get_real_ticks (void) } #endif -#ifdef NEED_CPU_H -/* Deterministic execution requires that IO only be performed on the last - instruction of a TB so that interrupts take effect immediately. */ -static inline int can_do_io(CPUState *env) -{ - if (!use_icount) - return 1; - - /* If not executing code then assume we are ok. */ - if (!env->current_tb) - return 1; - - return env->can_do_io != 0; -} -#endif - #ifdef CONFIG_PROFILER static inline int64_t profile_getclock(void) { diff --git a/qemu-tool.c b/qemu-tool.c index 392e1c9..5df7279 100644 --- a/qemu-tool.c +++ b/qemu-tool.c @@ -15,11 +15,12 @@ #include "monitor.h" #include "qemu-timer.h" #include "qemu-log.h" -#include "sysemu.h" +#include "migration.h" #include QEMUClock *rt_clock; +QEMUClock *vm_clock; FILE *logfile; @@ -29,10 +30,6 @@ struct QEMUBH void *opaque; }; -void qemu_service_io(void) -{ -} - Monitor *cur_mon; int monitor_cur_is_qmp(void) @@ -56,58 +53,51 @@ void monitor_print_filename(Monitor *mon, const char *filename) { } -void async_context_push(void) +void monitor_protocol_event(MonitorEvent event, QObject *data) { } -void async_context_pop(void) +int qemu_set_fd_handler2(int fd, + IOCanReadHandler *fd_read_poll, + IOHandler *fd_read, + IOHandler *fd_write, + void *opaque) { + return 0; } -int get_async_context_id(void) +void qemu_notify_event(void) { - return 0; } -void monitor_protocol_event(MonitorEvent event, QObject *data) +QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale, + QEMUTimerCB *cb, void *opaque) { + return g_malloc(1); } -QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque) +void qemu_free_timer(QEMUTimer *ts) { - QEMUBH *bh; - - bh = qemu_malloc(sizeof(*bh)); - bh->cb = cb; - bh->opaque = opaque; - - return bh; + g_free(ts); } -int qemu_bh_poll(void) +void qemu_del_timer(QEMUTimer *ts) { - return 0; } -void qemu_bh_schedule(QEMUBH *bh) +void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) { - bh->cb(bh->opaque); } -void qemu_bh_cancel(QEMUBH *bh) +int64_t qemu_get_clock_ns(QEMUClock *clock) { + return 0; } -void qemu_bh_delete(QEMUBH *bh) +void migrate_add_blocker(Error *reason) { - qemu_free(bh); } -int qemu_set_fd_handler2(int fd, - IOCanReadHandler *fd_read_poll, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque) +void migrate_del_blocker(Error *reason) { - return 0; } diff --git a/qemu_configure.sh b/qemu_configure.sh deleted file mode 100755 index ab17041..0000000 --- a/qemu_configure.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -# OS specific -#--target-list=i386-softmmu,arm-softmmu \ -targetos=`uname -s` -case $targetos in -Linux*) -echo "checking for os... targetos $targetos" -exec ./configure \ - --target-list=i386-softmmu \ - --disable-werror \ - --audio-drv-list=pa \ - --enable-mixemu \ - --disable-vnc-tls \ - --enable-tcg-x86-opt \ - --enable-v4l2 \ - --enable-ffmpeg -# --enable-debug \ -# --enable-profiler \ -# --enable-gles2 --gles2dir=/usr -;; -CYGWIN*) -echo "checking for os... targetos $targetos" -exec ./configure \ - --target-list=i386-softmmu \ - --audio-drv-list=winwave \ - --audio-card-list=es1370 \ - --enable-mixemu \ - --disable-vnc-tls -;; -MINGW*) -echo "checking for os... targetos $targetos" -exec ./configure \ - --target-list=i386-softmmu \ - --audio-drv-list=winwave \ - --audio-card-list=es1370 \ - --enable-mixemu \ - --disable-vnc-tls \ - --enable-ffmpeg -# --disable-vnc-jpeg \ -# --disable-jpeg -;; -esac diff --git a/qemu_socket.h b/qemu_socket.h index 2f33e64..9e32fac 100644 --- a/qemu_socket.h +++ b/qemu_socket.h @@ -35,6 +35,7 @@ int inet_aton(const char *cp, struct in_addr *ia); /* misc helpers */ int qemu_socket(int domain, int type, int protocol); int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +void socket_set_block(int fd); void socket_set_nonblock(int fd); int send_all(int fd, const void *buf, int len1); @@ -54,7 +55,6 @@ int unix_connect(const char *path); /* Old, ipv4 only bits. Don't use for new code. */ int parse_host_port(struct sockaddr_in *saddr, const char *str); -int parse_host_src_port(struct sockaddr_in *haddr, - struct sockaddr_in *saddr, - const char *str); +int socket_init(void); + #endif /* QEMU_SOCKET_H */ diff --git a/qerror.c b/qerror.c index 4855604..25bc91e 100644 --- a/qerror.c +++ b/qerror.c @@ -49,6 +49,10 @@ static const QErrorStringTable qerror_table[] = { .desc = "Device '%(device)' can't go on a %(bad_bus_type) bus", }, { + .error_fmt = QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + .desc = "Block format '%(format)' used by device '%(name)' does not support feature '%(feature)'", + }, + { .error_fmt = QERR_BUS_NOT_FOUND, .desc = "Bus '%(bus)' not found", }, @@ -73,6 +77,10 @@ static const QErrorStringTable qerror_table[] = { .desc = "Device '%(device)' is in use", }, { + .error_fmt = QERR_DEVICE_FEATURE_BLOCKS_MIGRATION, + .desc = "Migration is disabled when using feature '%(feature)' in device '%(device)'", + }, + { .error_fmt = QERR_DEVICE_LOCKED, .desc = "Device '%(device)' is locked", }, @@ -117,6 +125,10 @@ static const QErrorStringTable qerror_table[] = { .desc = "No file descriptor supplied via SCM_RIGHTS", }, { + .error_fmt = QERR_FEATURE_DISABLED, + .desc = "The feature '%(name)' is not enabled", + }, + { .error_fmt = QERR_INVALID_BLOCK_FORMAT, .desc = "Invalid block format '%(name)'", }, @@ -141,6 +153,11 @@ static const QErrorStringTable qerror_table[] = { .desc = "Invalid JSON syntax", }, { + .error_fmt = QERR_JSON_PARSE_ERROR, + .desc = "JSON parse error, %(message)", + + }, + { .error_fmt = QERR_KVM_MISSING_CAP, .desc = "Using KVM without %(capability), %(feature) unavailable", }, @@ -189,10 +206,18 @@ static const QErrorStringTable qerror_table[] = { .desc = "QMP input object member '%(member)' is unexpected", }, { + .error_fmt = QERR_RESET_REQUIRED, + .desc = "Resetting the Virtual Machine is required", + }, + { .error_fmt = QERR_SET_PASSWD_FAILED, .desc = "Could not set password", }, { + .error_fmt = QERR_ADD_CLIENT_FAILED, + .desc = "Could not add client", + }, + { .error_fmt = QERR_TOO_MANY_FILES, .desc = "Too many open files", }, @@ -201,14 +226,31 @@ static const QErrorStringTable qerror_table[] = { .desc = "An undefined error has ocurred", }, { + .error_fmt = QERR_UNSUPPORTED, + .desc = "this feature or command is not currently supported", + }, + { .error_fmt = QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, .desc = "'%(device)' uses a %(format) feature which is not " "supported by this qemu version: %(feature)", }, { + .error_fmt = QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION, + .desc = "Migration is disabled when VirtFS export path '%(path)' " + "is mounted in the guest using mount_tag '%(tag)'", + }, + { .error_fmt = QERR_VNC_SERVER_FAILED, .desc = "Could not start VNC server on %(target)", }, + { + .error_fmt = QERR_QGA_LOGGING_FAILED, + .desc = "Guest agent failed to log non-optional log statement", + }, + { + .error_fmt = QERR_QGA_COMMAND_FAILED, + .desc = "Guest agent command failed, error was '%(message)'", + }, {} }; @@ -221,7 +263,7 @@ QError *qerror_new(void) { QError *qerr; - qerr = qemu_mallocz(sizeof(*qerr)); + qerr = g_malloc0(sizeof(*qerr)); QOBJECT_INIT(qerr, &qerror_type); return qerr; @@ -326,12 +368,14 @@ QError *qerror_from_info(const char *file, int linenr, const char *func, return qerr; } -static void parse_error(const QError *qerror, int c) +static void parse_error(const QErrorStringTable *entry, int c) { - qerror_abort(qerror, "expected '%c' in '%s'", c, qerror->entry->desc); + fprintf(stderr, "expected '%c' in '%s'", c, entry->desc); + abort(); } -static const char *append_field(QString *outstr, const QError *qerror, +static const char *append_field(QDict *error, QString *outstr, + const QErrorStringTable *entry, const char *start) { QObject *obj; @@ -340,23 +384,23 @@ static const char *append_field(QString *outstr, const QError *qerror, const char *end, *key; if (*start != '%') - parse_error(qerror, '%'); + parse_error(entry, '%'); start++; if (*start != '(') - parse_error(qerror, '('); + parse_error(entry, '('); start++; end = strchr(start, ')'); if (!end) - parse_error(qerror, ')'); + parse_error(entry, ')'); key_qs = qstring_from_substr(start, 0, end - start - 1); key = qstring_get_str(key_qs); - qdict = qobject_to_qdict(qdict_get(qerror->error, "data")); + qdict = qobject_to_qdict(qdict_get(error, "data")); obj = qdict_get(qdict, key); if (!obj) { - qerror_abort(qerror, "key '%s' not found in QDict", key); + abort(); } switch (qobject_type(obj)) { @@ -367,41 +411,60 @@ static const char *append_field(QString *outstr, const QError *qerror, qstring_append_int(outstr, qdict_get_int(qdict, key)); break; default: - qerror_abort(qerror, "invalid type '%c'", qobject_type(obj)); + abort(); } QDECREF(key_qs); return ++end; } -/** - * qerror_human(): Format QError data into human-readable string. - * - * Formats according to member 'desc' of the specified QError object. - */ -QString *qerror_human(const QError *qerror) +static QString *qerror_format_desc(QDict *error, + const QErrorStringTable *entry) { - const char *p; QString *qstring; + const char *p; - assert(qerror->entry != NULL); + assert(entry != NULL); qstring = qstring_new(); - for (p = qerror->entry->desc; *p != '\0';) { + for (p = entry->desc; *p != '\0';) { if (*p != '%') { qstring_append_chr(qstring, *p++); } else if (*(p + 1) == '%') { qstring_append_chr(qstring, '%'); p += 2; } else { - p = append_field(qstring, qerror, p); + p = append_field(error, qstring, entry, p); } } return qstring; } +QString *qerror_format(const char *fmt, QDict *error) +{ + const QErrorStringTable *entry = NULL; + int i; + + for (i = 0; qerror_table[i].error_fmt; i++) { + if (strcmp(qerror_table[i].error_fmt, fmt) == 0) { + entry = &qerror_table[i]; + break; + } + } + + return qerror_format_desc(error, entry); +} + +/** + * qerror_human(): Format QError data into human-readable string. + */ +QString *qerror_human(const QError *qerror) +{ + return qerror_format_desc(qerror->error, qerror->entry); +} + /** * qerror_print(): Print QError data * @@ -436,6 +499,39 @@ void qerror_report_internal(const char *file, int linenr, const char *func, } } +/* Evil... */ +struct Error +{ + QDict *obj; + const char *fmt; + char *msg; +}; + +void qerror_report_err(Error *err) +{ + QError *qerr; + int i; + + qerr = qerror_new(); + loc_save(&qerr->loc); + QINCREF(err->obj); + qerr->error = err->obj; + + for (i = 0; qerror_table[i].error_fmt; i++) { + if (strcmp(qerror_table[i].error_fmt, err->fmt) == 0) { + qerr->entry = &qerror_table[i]; + break; + } + } + + if (monitor_cur_is_qmp()) { + monitor_set_error(cur_mon, qerr); + } else { + qerror_print(qerr); + QDECREF(qerr); + } +} + /** * qobject_to_qerror(): Convert a QObject into a QError */ @@ -459,5 +555,5 @@ static void qerror_destroy_obj(QObject *obj) qerr = qobject_to_qerror(obj); QDECREF(qerr->error); - qemu_free(qerr); + g_free(qerr); } diff --git a/qerror.h b/qerror.h index f732d45..6414cd9 100644 --- a/qerror.h +++ b/qerror.h @@ -15,6 +15,7 @@ #include "qdict.h" #include "qstring.h" #include "qemu-error.h" +#include "error.h" #include typedef struct QErrorStringTable { @@ -39,6 +40,8 @@ QString *qerror_human(const QError *qerror); void qerror_print(QError *qerror); void qerror_report_internal(const char *file, int linenr, const char *func, const char *fmt, ...) GCC_FMT_ATTR(4, 5); +void qerror_report_err(Error *err); +QString *qerror_format(const char *fmt, QDict *error); #define qerror_report(fmt, ...) \ qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__) QError *qobject_to_qerror(const QObject *obj); @@ -51,6 +54,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_BAD_BUS_FOR_DEVICE \ "{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }" +#define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \ + "{ 'class': 'BlockFormatFeatureNotSupported', 'data': { 'format': %s, 'name': %s, 'feature': %s } }" + #define QERR_BUS_NOT_FOUND \ "{ 'class': 'BusNotFound', 'data': { 'bus': %s } }" @@ -69,6 +75,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_DEVICE_IN_USE \ "{ 'class': 'DeviceInUse', 'data': { 'device': %s } }" +#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \ + "{ 'class': 'DeviceFeatureBlocksMigration', 'data': { 'device': %s, 'feature': %s } }" + #define QERR_DEVICE_LOCKED \ "{ 'class': 'DeviceLocked', 'data': { 'device': %s } }" @@ -120,6 +129,12 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_JSON_PARSING \ "{ 'class': 'JSONParsing', 'data': {} }" +#define QERR_JSON_PARSE_ERROR \ + "{ 'class': 'JSONParseError', 'data': { 'message': %s } }" + +#define QERR_BUFFER_OVERRUN \ + "{ 'class': 'BufferOverrun', 'data': {} }" + #define QERR_KVM_MISSING_CAP \ "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }" @@ -156,19 +171,40 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_QMP_EXTRA_MEMBER \ "{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }" +#define QERR_RESET_REQUIRED \ + "{ 'class': 'ResetRequired', 'data': {} }" + #define QERR_SET_PASSWD_FAILED \ "{ 'class': 'SetPasswdFailed', 'data': {} }" +#define QERR_ADD_CLIENT_FAILED \ + "{ 'class': 'AddClientFailed', 'data': {} }" + #define QERR_TOO_MANY_FILES \ "{ 'class': 'TooManyFiles', 'data': {} }" #define QERR_UNDEFINED_ERROR \ "{ 'class': 'UndefinedError', 'data': {} }" +#define QERR_UNSUPPORTED \ + "{ 'class': 'Unsupported', 'data': {} }" + #define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \ "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }" +#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \ + "{ 'class': 'VirtFSFeatureBlocksMigration', 'data': { 'path': %s, 'tag': %s } }" + #define QERR_VNC_SERVER_FAILED \ "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }" +#define QERR_FEATURE_DISABLED \ + "{ 'class': 'FeatureDisabled', 'data': { 'name': %s } }" + +#define QERR_QGA_LOGGING_FAILED \ + "{ 'class': 'QgaLoggingFailed', 'data': {} }" + +#define QERR_QGA_COMMAND_FAILED \ + "{ 'class': 'QgaCommandFailed', 'data': { 'message': %s } }" + #endif /* QERROR_H */ diff --git a/qfloat.c b/qfloat.c index f8c8a2e..98338f3 100644 --- a/qfloat.c +++ b/qfloat.c @@ -31,7 +31,7 @@ QFloat *qfloat_from_double(double value) { QFloat *qf; - qf = qemu_malloc(sizeof(*qf)); + qf = g_malloc(sizeof(*qf)); qf->value = value; QOBJECT_INIT(qf, &qfloat_type); @@ -64,5 +64,5 @@ QFloat *qobject_to_qfloat(const QObject *obj) static void qfloat_destroy_obj(QObject *obj) { assert(obj != NULL); - qemu_free(qobject_to_qfloat(obj)); + g_free(qobject_to_qfloat(obj)); } diff --git a/qint.c b/qint.c index fb3823a..ee51804 100644 --- a/qint.c +++ b/qint.c @@ -30,7 +30,7 @@ QInt *qint_from_int(int64_t value) { QInt *qi; - qi = qemu_malloc(sizeof(*qi)); + qi = g_malloc(sizeof(*qi)); qi->value = value; QOBJECT_INIT(qi, &qint_type); @@ -63,5 +63,5 @@ QInt *qobject_to_qint(const QObject *obj) static void qint_destroy_obj(QObject *obj) { assert(obj != NULL); - qemu_free(qobject_to_qint(obj)); + g_free(qobject_to_qint(obj)); } diff --git a/qlist.c b/qlist.c index 5730fb8..88498b1 100644 --- a/qlist.c +++ b/qlist.c @@ -31,7 +31,7 @@ QList *qlist_new(void) { QList *qlist; - qlist = qemu_malloc(sizeof(*qlist)); + qlist = g_malloc(sizeof(*qlist)); QTAILQ_INIT(&qlist->head); QOBJECT_INIT(qlist, &qlist_type); @@ -64,7 +64,7 @@ void qlist_append_obj(QList *qlist, QObject *value) { QListEntry *entry; - entry = qemu_malloc(sizeof(*entry)); + entry = g_malloc(sizeof(*entry)); entry->value = value; QTAILQ_INSERT_TAIL(&qlist->head, entry, next); @@ -98,7 +98,7 @@ QObject *qlist_pop(QList *qlist) QTAILQ_REMOVE(&qlist->head, entry, next); ret = entry->value; - qemu_free(entry); + g_free(entry); return ret; } @@ -150,8 +150,8 @@ static void qlist_destroy_obj(QObject *obj) QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) { QTAILQ_REMOVE(&qlist->head, entry, next); qobject_decref(entry->value); - qemu_free(entry); + g_free(entry); } - qemu_free(qlist); + g_free(qlist); } diff --git a/qlist.h b/qlist.h index dbe7b92..d426bd4 100644 --- a/qlist.h +++ b/qlist.h @@ -16,6 +16,7 @@ #include "qobject.h" #include "qemu-queue.h" #include "qemu-common.h" +#include "qemu-queue.h" typedef struct QListEntry { QObject *value; @@ -50,4 +51,14 @@ QObject *qlist_peek(QList *qlist); int qlist_empty(const QList *qlist); QList *qobject_to_qlist(const QObject *obj); +static inline const QListEntry *qlist_first(const QList *qlist) +{ + return QTAILQ_FIRST(&qlist->head); +} + +static inline const QListEntry *qlist_next(const QListEntry *entry) +{ + return QTAILQ_NEXT(entry, next); +} + #endif /* QLIST_H */ diff --git a/qmp-commands.hx b/qmp-commands.hx index df40a3d..97975a5 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -42,7 +42,7 @@ and we're going to establish a deprecation policy for badly defined commands. If you're planning to adopt QMP, please observe the following: - 1. The deprecation policy will take efect and be documented soon, please + 1. The deprecation policy will take effect and be documented soon, please check the documentation of each used command as soon as a new release of QEMU is available @@ -63,10 +63,7 @@ EQMP { .name = "quit", .args_type = "", - .params = "", - .help = "quit the emulator", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_quit, + .mhandler.cmd_new = qmp_marshal_input_quit, }, SQMP @@ -181,10 +178,7 @@ EQMP { .name = "stop", .args_type = "", - .params = "", - .help = "stop emulation", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_stop, + .mhandler.cmd_new = qmp_marshal_input_stop, }, SQMP @@ -229,10 +223,7 @@ EQMP { .name = "system_reset", .args_type = "", - .params = "", - .help = "reset the system", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_system_reset, + .mhandler.cmd_new = qmp_marshal_input_system_reset, }, SQMP @@ -340,10 +331,7 @@ EQMP { .name = "cpu", .args_type = "index:i", - .params = "index", - .help = "set the default CPU", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_cpu_set, + .mhandler.cmd_new = qmp_marshal_input_cpu, }, SQMP @@ -430,6 +418,33 @@ Example: EQMP { + .name = "inject-nmi", + .args_type = "", + .params = "", + .help = "", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_inject_nmi, + }, + +SQMP +inject-nmi +---------- + +Inject an NMI on guest's CPUs. + +Arguments: None. + +Example: + +-> { "execute": "inject-nmi" } +<- { "return": {} } + +Note: inject-nmi is only supported for x86 guest currently, it will + returns "Unsupported" error for non-x86 guest. + +EQMP + + { .name = "migrate", .args_type = "detach:-d,blk:-b,inc:-i,uri:s", .params = "[-d] [-b] [-i] uri", @@ -503,79 +518,80 @@ EQMP }, SQMP -client_migrate_info ------------------- +migrate_set_speed +----------------- -Set the spice/vnc connection info for the migration target. The spice/vnc -server will ask the spice/vnc client to automatically reconnect using the -new parameters (if specified) once the vm migration finished successfully. +Set maximum speed for migrations. Arguments: -- "protocol": protocol: "spice" or "vnc" (json-string) -- "hostname": migration target hostname (json-string) -- "port": spice/vnc tcp port for plaintext channels (json-int, optional) -- "tls-port": spice tcp port for tls-secured channels (json-int, optional) -- "cert-subject": server certificate subject (json-string, optional) +- "value": maximum speed, in bytes per second (json-int) Example: --> { "execute": "client_migrate_info", - "arguments": { "protocol": "spice", - "hostname": "virt42.lab.kraxel.org", - "port": 1234 } } +-> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } } <- { "return": {} } EQMP { - .name = "client_migrate_info", - .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?", - .params = "protocol hostname port tls-port cert-subject", - .help = "send migration info to spice/vnc client", + .name = "migrate_set_downtime", + .args_type = "value:T", + .params = "value", + .help = "set maximum tolerated downtime (in seconds) for migrations", .user_print = monitor_user_noop, - .mhandler.cmd_new = client_migrate_info, + .mhandler.cmd_new = do_migrate_set_downtime, }, SQMP -migrate_set_speed ------------------ +migrate_set_downtime +-------------------- -Set maximum speed for migrations. +Set maximum tolerated downtime (in seconds) for migrations. Arguments: -- "value": maximum speed, in bytes per second (json-int) +- "value": maximum downtime (json-number) Example: --> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } } +-> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } } <- { "return": {} } EQMP { - .name = "migrate_set_downtime", - .args_type = "value:T", - .params = "value", - .help = "set maximum tolerated downtime (in seconds) for migrations", + .name = "client_migrate_info", + .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?", + .params = "protocol hostname port tls-port cert-subject", + .help = "send migration info to spice/vnc client", .user_print = monitor_user_noop, - .mhandler.cmd_new = do_migrate_set_downtime, + .mhandler.cmd_async = client_migrate_info, + .flags = MONITOR_CMD_ASYNC, }, SQMP -migrate_set_downtime --------------------- +client_migrate_info +------------------ -Set maximum tolerated downtime (in seconds) for migrations. +Set the spice/vnc connection info for the migration target. The spice/vnc +server will ask the spice/vnc client to automatically reconnect using the +new parameters (if specified) once the vm migration finished successfully. Arguments: -- "value": maximum downtime (json-number) +- "protocol": protocol: "spice" or "vnc" (json-string) +- "hostname": migration target hostname (json-string) +- "port": spice/vnc tcp port for plaintext channels (json-int, optional) +- "tls-port": spice tcp port for tls-secured channels (json-int, optional) +- "cert-subject": server certificate subject (json-string, optional) Example: --> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } } +-> { "execute": "client_migrate_info", + "arguments": { "protocol": "spice", + "hostname": "virt42.lab.kraxel.org", + "port": 1234 } } <- { "return": {} } EQMP @@ -667,6 +683,40 @@ Example: EQMP { + .name = "blockdev-snapshot-sync", + .args_type = "device:B,snapshot-file:s?,format:s?", + .params = "device [new-image-file] [format]", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_snapshot_blkdev, + }, + +SQMP +blockdev-snapshot-sync +---------------------- + +Synchronous snapshot of a block device. snapshot-file specifies the +target of the new image. If the file exists, or if it is a device, the +snapshot will be created in the existing file/device. If does not +exist, a new file will be created. format specifies the format of the +snapshot image, default is qcow2. + +Arguments: + +- "device": device name to snapshot (json-string) +- "snapshot-file": name of new image file (json-string) +- "format": format of new image (json-string, optional) + +Example: + +-> { "execute": "blockdev-snapshot-sync", "arguments": { "device": "ide-hd0", + "snapshot-file": + "/some/place/my-image", + "format": "qcow2" } } +<- { "return": {} } + +EQMP + + { .name = "balloon", .args_type = "value:M", .params = "target", @@ -858,6 +908,33 @@ Example: EQMP { + .name = "add_client", + .args_type = "protocol:s,fdname:s,skipauth:b?", + .params = "protocol fdname skipauth", + .help = "add a graphics client", + .user_print = monitor_user_noop, + .mhandler.cmd_new = add_graphics_client, + }, + +SQMP +add_client +---------- + +Add a graphics client + +Arguments: + +- "protocol": protocol name (json-string) +- "fdname": file descriptor name (json-string) + +Example: + +-> { "execute": "add_client", "arguments": { "protocol": "vnc", + "fdname": "myclient" } } +<- { "return": {} } + +EQMP + { .name = "qmp_capabilities", .args_type = "", .params = "", @@ -965,6 +1042,12 @@ Example: EQMP + { + .name = "query-version", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_version, + }, + SQMP query-commands -------------- @@ -996,6 +1079,12 @@ Note: This example has been shortened as the real response is too long. EQMP + { + .name = "query-commands", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_commands, + }, + SQMP query-chardev ------------- @@ -1026,6 +1115,12 @@ Example: EQMP + { + .name = "query-chardev", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_chardev, + }, + SQMP query-block ----------- @@ -1039,9 +1134,12 @@ Each json-object contain the following: - "device": device name (json-string) - "type": device type (json-string) - - Possible values: "hd", "cdrom", "floppy", "unknown" + - deprecated, retained for backward compatibility + - Possible values: "unknown" - "removable": true if the device is removable, false otherwise (json-bool) - "locked": true if the device is locked, false otherwise (json-bool) +- "tray-open": only present if removable, true if the device has a tray, + and it is open (json-bool) - "inserted": only present if the device is inserted, it is a json-object containing the following: - "file": device file name (json-string) @@ -1054,6 +1152,10 @@ Each json-object contain the following: "tftp", "vdi", "vmdk", "vpc", "vvfat" - "backing_file": backing file name (json-string, optional) - "encrypted": true if encrypted, false otherwise (json-bool) +- "io-status": I/O operation status, only present if the device supports it + and the VM is configured to stop on errors. It's always reset + to "ok" when the "cont" command is issued (json_string, optional) + - Possible values: "ok", "failed", "nospace" Example: @@ -1061,6 +1163,7 @@ Example: <- { "return":[ { + "io-status": "ok", "device":"ide0-hd0", "locked":false, "removable":false, @@ -1070,31 +1173,38 @@ Example: "encrypted":false, "file":"disks/test.img" }, - "type":"hd" + "type":"unknown" }, { + "io-status": "ok", "device":"ide1-cd0", "locked":false, "removable":true, - "type":"cdrom" + "type":"unknown" }, { "device":"floppy0", "locked":false, "removable":true, - "type": "floppy" + "type":"unknown" }, { "device":"sd0", "locked":false, "removable":true, - "type":"floppy" + "type":"unknown" } ] } EQMP + { + .name = "query-block", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_block, + }, + SQMP query-blockstats ---------------- @@ -1112,6 +1222,10 @@ Each json-object contain the following: - "wr_bytes": bytes written (json-int) - "rd_operations": read operations (json-int) - "wr_operations": write operations (json-int) + - "flush_operations": cache flush operations (json-int) + - "wr_total_time_ns": total time spend on writes in nano-seconds (json-int) + - "rd_total_time_ns": total time spend on reads in nano-seconds (json-int) + - "flush_total_time_ns": total time spend on cache flushes in nano-seconds (json-int) - "wr_highest_offset": Highest offset of a sector written since the BlockDriverState has been opened (json-int) - "parent": Contains recursively the statistics of the underlying @@ -1133,6 +1247,10 @@ Example: "wr_operations":751, "rd_bytes":122567168, "rd_operations":36772 + "wr_total_times_ns":313253456 + "rd_total_times_ns":3465673657 + "flush_total_times_ns":49653 + "flush_operations":61, } }, "stats":{ @@ -1141,6 +1259,10 @@ Example: "wr_operations":692, "rd_bytes":122739200, "rd_operations":36604 + "flush_operations":51, + "wr_total_times_ns":313253456 + "rd_total_times_ns":3465673657 + "flush_total_times_ns":49653 } }, { @@ -1151,6 +1273,10 @@ Example: "wr_operations":0, "rd_bytes":0, "rd_operations":0 + "flush_operations":0, + "wr_total_times_ns":0 + "rd_total_times_ns":0 + "flush_total_times_ns":0 } }, { @@ -1161,6 +1287,10 @@ Example: "wr_operations":0, "rd_bytes":0, "rd_operations":0 + "flush_operations":0, + "wr_total_times_ns":0 + "rd_total_times_ns":0 + "flush_total_times_ns":0 } }, { @@ -1171,6 +1301,10 @@ Example: "wr_operations":0, "rd_bytes":0, "rd_operations":0 + "flush_operations":0, + "wr_total_times_ns":0 + "rd_total_times_ns":0 + "flush_total_times_ns":0 } } ] @@ -1178,6 +1312,12 @@ Example: EQMP + { + .name = "query-blockstats", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_blockstats, + }, + SQMP query-cpus ---------- @@ -1194,6 +1334,7 @@ Return a json-array. Each CPU is represented by a json-object, which contains: "nip": PPC (json-int) "pc" and "npc": sparc (json-int) "PC": mips (json-int) +- "thread_id": ID of the underlying host thread (json-int) Example: @@ -1205,18 +1346,26 @@ Example: "current":true, "halted":false, "pc":3227107138 + "thread_id":3134 }, { "CPU":1, "current":false, "halted":true, "pc":7108165 + "thread_id":3135 } ] } EQMP + { + .name = "query-cpus", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_cpus, + }, + SQMP query-pci --------- @@ -1428,6 +1577,12 @@ Note: This example has been shortened as the real response is too long. EQMP + { + .name = "query-pci", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_pci, + }, + SQMP query-kvm --------- @@ -1446,6 +1601,12 @@ Example: EQMP + { + .name = "query-kvm", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_kvm, + }, + SQMP query-status ------------ @@ -1455,13 +1616,36 @@ Return a json-object with the following information: - "running": true if the VM is running, or false if it is paused (json-bool) - "singlestep": true if the VM is in single step mode, false otherwise (json-bool) +- "status": one of the following values (json-string) + "debug" - QEMU is running on a debugger + "inmigrate" - guest is paused waiting for an incoming migration + "internal-error" - An internal error that prevents further guest + execution has occurred + "io-error" - the last IOP has failed and the device is configured + to pause on I/O errors + "paused" - guest has been paused via the 'stop' command + "postmigrate" - guest is paused following a successful 'migrate' + "prelaunch" - QEMU was started with -S and guest has not started + "finish-migrate" - guest is paused to finish the migration process + "restore-vm" - guest is paused to restore VM state + "running" - guest is actively running + "save-vm" - guest is paused to save the VM state + "shutdown" - guest is shut down (and -no-shutdown is in use) + "watchdog" - the watchdog action is configured to pause and + has been triggered Example: -> { "execute": "query-status" } -<- { "return": { "running": true, "singlestep": false } } +<- { "return": { "running": true, "singlestep": false, "status": "running" } } EQMP + + { + .name = "query-status", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_status, + }, SQMP query-mice @@ -1501,6 +1685,12 @@ Example: EQMP + { + .name = "query-mice", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_mice, + }, + SQMP query-vnc --------- @@ -1558,6 +1748,12 @@ Example: EQMP + { + .name = "query-vnc", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_vnc, + }, + SQMP query-spice ----------- @@ -1628,6 +1824,14 @@ Example: EQMP +#if defined(CONFIG_SPICE) + { + .name = "query-spice", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_spice, + }, +#endif + SQMP query-name ---------- @@ -1645,6 +1849,12 @@ Example: EQMP + { + .name = "query-name", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_name, + }, + SQMP query-uuid ---------- @@ -1662,6 +1872,12 @@ Example: EQMP + { + .name = "query-uuid", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_uuid, + }, + SQMP query-migrate ------------- @@ -1739,6 +1955,12 @@ Examples: EQMP + { + .name = "query-migrate", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_migrate, + }, + SQMP query-balloon ------------- @@ -1774,3 +1996,8 @@ Example: EQMP + { + .name = "query-balloon", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_balloon, + }, diff --git a/qstring.c b/qstring.c index 4e2ba08..b7e12e4 100644 --- a/qstring.c +++ b/qstring.c @@ -40,12 +40,12 @@ QString *qstring_from_substr(const char *str, int start, int end) { QString *qstring; - qstring = qemu_malloc(sizeof(*qstring)); + qstring = g_malloc(sizeof(*qstring)); qstring->length = end - start + 1; qstring->capacity = qstring->length; - qstring->string = qemu_malloc(qstring->capacity + 1); + qstring->string = g_malloc(qstring->capacity + 1); memcpy(qstring->string, str + start, qstring->length); qstring->string[qstring->length] = 0; @@ -70,7 +70,7 @@ static void capacity_increase(QString *qstring, size_t len) qstring->capacity += len; qstring->capacity *= 2; /* use exponential growth */ - qstring->string = qemu_realloc(qstring->string, qstring->capacity + 1); + qstring->string = g_realloc(qstring->string, qstring->capacity + 1); } } @@ -136,6 +136,6 @@ static void qstring_destroy_obj(QObject *obj) assert(obj != NULL); qs = qobject_to_qstring(obj); - qemu_free(qs->string); - qemu_free(qs); + g_free(qs->string); + g_free(qs); } diff --git a/readline.c b/readline.c index 92f9cd1..a6c0039 100644 --- a/readline.c +++ b/readline.c @@ -236,7 +236,7 @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline) new_entry = hist_entry; /* Put this entry at the end of history */ memmove(&rs->history[idx], &rs->history[idx + 1], - (READLINE_MAX_CMDS - idx + 1) * sizeof(char *)); + (READLINE_MAX_CMDS - (idx + 1)) * sizeof(char *)); rs->history[READLINE_MAX_CMDS - 1] = NULL; for (; idx < READLINE_MAX_CMDS; idx++) { if (rs->history[idx] == NULL) @@ -264,7 +264,7 @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline) void readline_add_completion(ReadLineState *rs, const char *str) { if (rs->nb_completions < READLINE_MAX_COMPLETIONS) { - rs->completions[rs->nb_completions++] = qemu_strdup(str); + rs->completions[rs->nb_completions++] = g_strdup(str); } } @@ -281,11 +281,11 @@ static void readline_completion(ReadLineState *rs) rs->nb_completions = 0; - cmdline = qemu_malloc(rs->cmd_buf_index + 1); + cmdline = g_malloc(rs->cmd_buf_index + 1); memcpy(cmdline, rs->cmd_buf, rs->cmd_buf_index); cmdline[rs->cmd_buf_index] = '\0'; rs->completion_finder(cmdline); - qemu_free(cmdline); + g_free(cmdline); /* no completion found */ if (rs->nb_completions <= 0) @@ -466,7 +466,7 @@ const char *readline_get_history(ReadLineState *rs, unsigned int index) ReadLineState *readline_init(Monitor *mon, ReadLineCompletionFunc *completion_finder) { - ReadLineState *rs = qemu_mallocz(sizeof(*rs)); + ReadLineState *rs = g_malloc0(sizeof(*rs)); rs->hist_entry = -1; rs->mon = mon; diff --git a/roms/seabios/COPYING b/roms/seabios/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/roms/seabios/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, 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 -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state 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 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 3 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, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/roms/seabios/COPYING.LESSER b/roms/seabios/COPYING.LESSER deleted file mode 100644 index fc8a5de..0000000 --- a/roms/seabios/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - 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 that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU 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 as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/roms/seabios/Makefile b/roms/seabios/Makefile deleted file mode 100644 index 9805f85..0000000 --- a/roms/seabios/Makefile +++ /dev/null @@ -1,202 +0,0 @@ -# SeaBIOS build system -# -# Copyright (C) 2008,2009 Kevin O'Connor -# -# This file may be distributed under the terms of the GNU LGPLv3 license. - -# Program version -VERSION=0.6.1.2-$(shell date +"%Y%m%d_%H%M%S")-$(shell hostname) - -# Output directory -OUT=out/ - -# Source files -SRCBOTH=misc.c pmm.c stacks.c output.c util.c block.c floppy.c ata.c mouse.c \ - kbd.c pci.c serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \ - pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \ - usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c \ - virtio-ring.c virtio-pci.c virtio-blk.c -SRC16=$(SRCBOTH) system.c disk.c apm.c font.c -SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \ - acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \ - lzmadecode.c bootsplash.c jpeg.c usb-hub.c paravirt.c dev-i440fx.c -SRC32SEG=util.c output.c pci.c pcibios.c apm.c stacks.c - -cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \ - /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;) - -# Default compiler flags -COMMONCFLAGS = -Os -MD -Wall -Wno-strict-aliasing -Wold-style-definition \ - $(call cc-option,$(CC),-Wtype-limits,) \ - -m32 -march=i386 -mregparm=3 -mpreferred-stack-boundary=2 \ - -mrtd -minline-all-stringops \ - -freg-struct-return -ffreestanding -fomit-frame-pointer \ - -fno-delete-null-pointer-checks \ - -ffunction-sections -fdata-sections -fno-common -COMMONCFLAGS += $(call cc-option,$(CC),-nopie,) -COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,) -COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,) - -CFLAGS32FLAT = $(COMMONCFLAGS) -g -DMODE16=0 -DMODESEGMENT=0 -CFLAGSSEG = $(COMMONCFLAGS) -DMODESEGMENT=1 -fno-defer-pop \ - $(call cc-option,$(CC),-fno-jump-tables,-DMANUAL_NO_JUMP_TABLE) \ - $(call cc-option,$(CC),-fno-tree-switch-conversion,) -CFLAGS32SEG = $(CFLAGSSEG) -DMODE16=0 -g -CFLAGS16INC = $(CFLAGSSEG) -DMODE16=1 \ - $(call cc-option,$(CC),--param large-stack-frame=4,-fno-inline) -CFLAGS16 = $(CFLAGS16INC) -g - -all: $(OUT) $(OUT)bios.bin - -# Run with "make V=1" to see the actual compile commands -ifdef V -Q= -else -Q=@ -endif - -OBJCOPY=objcopy -OBJDUMP=objdump -STRIP=strip - -.PHONY : all FORCE - -vpath %.c src vgasrc -vpath %.S src vgasrc - -################ Build rules - -# Verify the gcc configuration and test if -fwhole-program works. -TESTGCC:=$(shell CC="$(CC)" tools/test-gcc.sh) -ifeq "$(TESTGCC)" "-1" -$(error "Please upgrade GCC") -endif - -ifndef COMPSTRAT -COMPSTRAT=$(TESTGCC) -endif - -# Do a whole file compile - three methods are supported. -ifeq "$(COMPSTRAT)" "1" -# First method - use -fwhole-program without -combine. -define whole-compile -@echo " Compiling whole program $3" -$(Q)printf '$(foreach i,$2,#include "../$i"\n)' > $3.tmp.c -$(Q)$(CC) $1 -fwhole-program -DWHOLE_PROGRAM -c $3.tmp.c -o $3 -endef -else -ifeq "$(COMPSTRAT)" "2" -# Second menthod - don't use -fwhole-program at all. -define whole-compile -@echo " Compiling whole program $3" -$(Q)printf '$(foreach i,$2,#include "../$i"\n)' > $3.tmp.c -$(Q)$(CC) $1 -c $3.tmp.c -o $3 -endef -else -# Third (and preferred) method - use -fwhole-program with -combine -define whole-compile -@echo " Compiling whole program $3" -$(Q)$(CC) $1 -fwhole-program -DWHOLE_PROGRAM -combine -c $2 -o $3 -endef -endif -endif - -%.strip.o: %.o - @echo " Stripping $@" - $(Q)$(STRIP) $< -o $@ - -$(OUT)%.s: %.c - @echo " Compiling to assembler $@" - $(Q)$(CC) $(CFLAGS16INC) -S -c $< -o $@ - -$(OUT)%.lds: %.lds.S - @echo " Precompiling $@" - $(Q)$(CPP) -P -D__ASSEMBLY__ $< -o $@ - -$(OUT)asm-offsets.h: $(OUT)asm-offsets.s - @echo " Generating offset file $@" - $(Q)./tools/gen-offsets.sh $< $@ - - -$(OUT)ccode.16.s: ; $(call whole-compile, $(CFLAGS16) -S, $(addprefix src/, $(SRC16)),$@) - -$(OUT)code32seg.o: ; $(call whole-compile, $(CFLAGS32SEG), $(addprefix src/, $(SRC32SEG)),$@) - -$(OUT)ccode32flat.o: ; $(call whole-compile, $(CFLAGS32FLAT), $(addprefix src/, $(SRC32FLAT)),$@) - -$(OUT)code16.o: romlayout.S $(OUT)ccode.16.s $(OUT)asm-offsets.h - @echo " Compiling (16bit) $@" - $(Q)$(CC) $(CFLAGS16INC) -c -D__ASSEMBLY__ $< -o $@ - -$(OUT)romlayout16.lds $(OUT)romlayout32seg.lds $(OUT)romlayout32flat.lds $(OUT)code32flat.o: $(OUT)ccode32flat.o $(OUT)code32seg.o $(OUT)code16.o tools/layoutrom.py - @echo " Building ld scripts (version \"$(VERSION)\")" - $(Q)echo 'const char VERSION[] = "$(VERSION)";' > $(OUT)version.c - $(Q)$(CC) $(CFLAGS32FLAT) -c $(OUT)version.c -o $(OUT)version.o - $(Q)$(LD) -melf_i386 -r $(OUT)ccode32flat.o $(OUT)version.o -o $(OUT)code32flat.o - $(Q)$(OBJDUMP) -thr $(OUT)code32flat.o > $(OUT)code32flat.o.objdump - $(Q)$(OBJDUMP) -thr $(OUT)code32seg.o > $(OUT)code32seg.o.objdump - $(Q)$(OBJDUMP) -thr $(OUT)code16.o > $(OUT)code16.o.objdump - $(Q)./tools/layoutrom.py $(OUT)code16.o.objdump $(OUT)code32seg.o.objdump $(OUT)code32flat.o.objdump $(OUT)romlayout16.lds $(OUT)romlayout32seg.lds $(OUT)romlayout32flat.lds - - -$(OUT)rom16.o: $(OUT)code16.o $(OUT)romlayout16.lds - @echo " Linking $@" - $(Q)$(LD) -T $(OUT)romlayout16.lds $< -o $@ - -$(OUT)rom32seg.o: $(OUT)code32seg.o $(OUT)romlayout32seg.lds - @echo " Linking $@" - $(Q)$(LD) -T $(OUT)romlayout32seg.lds $< -o $@ - -$(OUT)rom.o: $(OUT)rom16.strip.o $(OUT)rom32seg.strip.o $(OUT)code32flat.o $(OUT)romlayout32flat.lds - @echo " Linking $@" - $(Q)$(LD) -T $(OUT)romlayout32flat.lds $(OUT)rom16.strip.o $(OUT)rom32seg.strip.o $(OUT)code32flat.o -o $@ - -$(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py - @echo " Prepping $@" - $(Q)$(OBJDUMP) -thr $< > $<.objdump - $(Q)$(OBJCOPY) -O binary $< $(OUT)bios.bin.raw - $(Q)./tools/checkrom.py $<.objdump $(OUT)bios.bin.raw $(OUT)bios.bin - $(Q)$(STRIP) -R .comment $< -o $(OUT)bios.bin.elf - - -################ VGA build rules - -# VGA src files -SRCVGA=src/output.c src/util.c vgasrc/vga.c vgasrc/vgafb.c vgasrc/vgaio.c \ - vgasrc/vgatables.c vgasrc/vgafonts.c vgasrc/clext.c - -$(OUT)vgaccode.16.s: ; $(call whole-compile, $(CFLAGS16) -S -Isrc, $(SRCVGA),$@) - -$(OUT)vgalayout16.o: vgaentry.S $(OUT)vgaccode.16.s $(OUT)asm-offsets.h - @echo " Compiling (16bit) $@" - $(Q)$(CC) $(CFLAGS16INC) -c -D__ASSEMBLY__ -Isrc $< -o $@ - -$(OUT)vgarom.o: $(OUT)vgalayout16.o $(OUT)vgalayout.lds - @echo " Linking $@" - $(Q)$(LD) --gc-sections -T $(OUT)vgalayout.lds $(OUT)vgalayout16.o -o $@ - -$(OUT)vgabios.bin.raw: $(OUT)vgarom.o - @echo " Extracting binary $@" - $(Q)$(OBJCOPY) -O binary $< $@ - -$(OUT)vgabios.bin: $(OUT)vgabios.bin.raw tools/buildrom.py - @echo " Finalizing rom $@" - $(Q)./tools/buildrom.py $< $@ - -####### dsdt build rules -src/%.hex: src/%.dsl - @echo "Compiling DSDT" - $(Q)cpp -P $< > $(OUT)$*.dsl.i - $(Q)iasl -tc -p $(OUT)$* $(OUT)$*.dsl.i - $(Q)cp $(OUT)$*.hex $@ - -$(OUT)ccode32flat.o: src/acpi-dsdt.hex - -####### Generic rules -clean: - $(Q)rm -rf $(OUT) - -$(OUT): - $(Q)mkdir $@ - --include $(OUT)*.d diff --git a/roms/seabios/README b/roms/seabios/README deleted file mode 100644 index 8f1bd20..0000000 --- a/roms/seabios/README +++ /dev/null @@ -1,190 +0,0 @@ -This code implements an X86 legacy bios. It is intended to be -compiled using standard gnu tools (eg, gas and gcc). - -To build, one should be able to run "make" in the main directory. The -resulting file "out/bios.bin" contains the processed bios image. - - -Testing of images: - -To test the bios under bochs, one will need to instruct bochs to use -the new bios image. Use the 'romimage' option - for example: - -bochs -q 'floppya: 1_44=myfdimage.img' 'romimage: file=out/bios.bin' - -To test under qemu, one will need to create a directory with all the -bios images and then overwrite the main bios image. For example: - -cp /usr/share/qemu/*.bin mybiosdir/ -cp out/bios.bin mybiosdir/ - -Once this is setup, one can instruct qemu to use the newly created -directory for rom images. For example: - -qemu -L mybiosdir/ -fda myfdimage.img - - -The following payloads have been tested: - -Freedos - see http://www.freedos.org/ . Useful tests include: booting -from installation cdrom, installing to hard drive and floppy, making -sure hard drive and floppy boots then work. It is also useful to take -the bootable floppy and hard-drive images, write them to an el-torito -bootable cdrom using the Linux mkisofs utility, and then boot those -cdrom images. - -Linux - useful hard drive image available from -http://fabrice.bellard.free.fr/qemu/linux-0.2.img.bz2 . It is also -useful to test standard distribution bootup and live cdroms. - -NetBSD - useful hard drive image available from -http://nopid.free.fr/small.ffs.bz2 . It is also useful to test -standard distribution installation cdroms. - - -Overview of files: - -The src/ directory contains the bios source code. Several of the -files are compiled twice - once for 16bit mode and once for 32bit -mode. (The build system will remove code that is not needed for a -particular mode.) - -The tools/ directory contains helper utilities for manipulating and -building the final rom. - -The out/ directory is created by the build process - it contains all -temporary and final files. - - -Build overview: - -The 16bit code is compiled via gcc to assembler (file out/ccode.16.s). -The gcc "-fwhole-program" and "-ffunction-sections -fdata-sections" -options are used to optimize the process so that gcc can efficiently -compile and discard unneeded code. (In the code, one can use the -macros 'VISIBLE16' and 'VISIBLE32' to instruct a symbol to be -outputted in 16bit and 32bit mode respectively.) - -This resulting assembler code is pulled into romlayout.S. The gas -option ".code16gcc" is used prior to including the gcc generated -assembler - this option enables gcc to generate valid 16 bit code. - -The post code (post.c) is entered, via the function _start(), in 32bit -mode. The 16bit post vector (in romlayout.S) transitions the cpu into -32 bit mode before calling the post.c code. - -In the last step of compilation, the 32 bit code is merged into the 16 -bit code so that one binary file contains both. Currently, both 16bit -and 32bit code will be located in the 64K block at segment 0xf000. - - -GCC 16 bit limitations: - -Although the 16bit code is compiled with gcc, developers need to be -aware of the environment. In particular, global variables _must_ be -treated specially. - -The code has full access to stack variables and general purpose -registers. The entry code in romlayout.S will push the original -registers on the stack before calling the C code and then pop them off -(including any required changes) before returning from the interrupt. -Changes to CS, DS, and ES segment registers in C code is also safe. -Changes to other segment registers (SS, FS, GS) need to be restored -manually. - -Stack variables (and pointers to stack variables) work as they -normally do in standard C code. - -However, variables stored outside the stack need to be accessed via -the GET_VAR and SET_VAR macros (or one of the helper macros described -below). This is due to the 16bit segment nature of the X86 cpu when -it is in "real mode". The C entry code will set DS and SS to point to -the stack segment. Variables not on the stack need to be accessed via -an explicit segment register. Any other access requires altering one -of the other segment registers (usually ES) and then accessing the -variable via that segment register. - -There are three low-level ways to access a remote variable: -GET/SET_VAR, GET/SET_FARVAR, and GET/SET_FLATPTR. The first set takes -an explicit segment descriptor (eg, "CS") and offset. The second set -will take a segment id and offset, set ES to the segment id, and then -make the access via the ES segment. The last method is similar to the -second, except it takes a pointer that would be valid in 32-bit flat -mode instead of a segment/offset pair. - -Most BIOS variables are stored in global variables, the "BDA", or -"EBDA" memory areas. Because this is common, three sets of helper -macros (GET/SET_GLOBAL, GET/SET_BDA, and GET/SET_EBDA) are available -to simplify these accesses. - -Global variables defined in the C code can be read in 16bit mode if -the variable declaration is marked with VAR16, VAR16VISIBLE, -VAR16EXPORT, or VAR16FIXED. The GET_GLOBAL macro will then allow read -access to the variable. Global variables are stored in the 0xf000 -segment, and their values are persistent across soft resets. Because -the f-segment is marked read-only during run-time, the 16bit code is -not permitted to change the value of 16bit variables (use of the -SET_GLOBAL macro from 16bit mode will cause a link error). Code -running in 32bit mode can not access variables with VAR16, but can -access variables marked with VAR16VISIBLE, VAR16EXPORT, VAR16FIXED, or -with no marking at all. The 32bit code can use the GET/SET_GLOBAL -macros, but they are not required. - - -GCC 16 bit stack limitations: - -Another limitation of gcc is its use of 32-bit temporaries. Gcc will -allocate 32-bits of space for every variable - even if that variable -is only defined as a 'u8' or 'u16'. If one is not careful, using too -much stack space can break old DOS applications. - -There does not appear to be explicit documentation on the minimum -stack space available for bios calls. However, Freedos has been -observed to call into the bios with less than 150 bytes available. - -Note that the post code and boot code (irq 18/19) do not have a stack -limitation because the entry points for these functions transition the -cpu to 32bit mode and reset the stack to a known state. Only the -general purpose 16-bit service entry points are affected. - -There are some ways to reduce stack usage: making sure functions are -tail-recursive often helps, reducing the number of parameters passed -to functions often helps, sometimes reordering variable declarations -helps, inlining of functions can sometimes help, and passing of packed -structures can also help. It is also possible to transition to/from -an extra stack stored in the EBDA using the stack_hop helper function. - -Some useful stats: the overhead for the entry to a bios handler that -takes a 'struct bregs' is 42 bytes of stack space (6 bytes from -interrupt insn, 32 bytes to store registers, and 4 bytes for call -insn). An entry to an ISR handler without args takes 30 bytes (6 + 20 -+ 4). - - -Debugging the bios: - -The bios will output information messages to a special debug port. -Under qemu, one can view these messages by enabling the '#define -DEBUG_BIOS' definition in 'qemu/hw/pc.c'. Once this is done (and qemu -is recompiled), one should see status messages on the console. - -The gdb-server mechanism of qemu is also useful. One can use gdb with -qemu to debug system images. To use this, add '-s -S' to the qemu -command line. For example: - -qemu -L mybiosdir/ -fda myfdimage.img -s -S - -Then, in another session, run gdb with either out/rom16.o (to debug -bios 16bit code) or out/rom32.o (to debug bios 32bit code). For -example: - -gdb out/rom16.o - -Once in gdb, use the command "target remote localhost:1234" to have -gdb connect to qemu. See the qemu documentation for more information -on using gdb and qemu in this mode. Note that gdb seems to get -breakpoints confused when the cpu is in 16-bit real mode. This makes -stepping through the program difficult (though 'step instruction' -still works). Also, one may need to set 16bit break points at both -the cpu address and memory address (eg, break *0x1234 ; break -*0xf1234). diff --git a/roms/seabios/TODO b/roms/seabios/TODO deleted file mode 100644 index d49aeb8..0000000 --- a/roms/seabios/TODO +++ /dev/null @@ -1,29 +0,0 @@ -If POST is rerun, try to do a machine reboot. - -Review changes committed to coreboot, virtualbox, qemu, kvm, and bochs -cvs tip. - * bochs cvs (20100104): - -- changes synched - * coreboot (r3348): (bochs 20060708) - -- no noteworthy enhancements - * qemu - now uses SeaBIOS - * kvm - now uses SeaBIOS - * virtualbox (r13560): (bochs 20061231) - -- lots of mouse changes, logo, scsi/etherboot hooks, - floppy data rate?, int19 calls post - -Possibly move code from entry_post in romlayout.S to C code in -handle_resume and always call 16bit C code on post. - -The __call16 code does a long jump to the interrupt trampolines - this -is unnecessary. - -Support PCIv3 roms? Add support for PCI "configuration code" -extensions? - -Possibly add option to eliminate tsc based delays on emulators. - -Add a kconfig style configuration program instead of requiring users -to modify config.h. - -Possibly support sending debug information over EHCI debug port. diff --git a/roms/seabios/src/acpi-dsdt.dsl b/roms/seabios/src/acpi-dsdt.dsl deleted file mode 100644 index 79f122e..0000000 --- a/roms/seabios/src/acpi-dsdt.dsl +++ /dev/null @@ -1,860 +0,0 @@ -/* - * Bochs/QEMU ACPI DSDT ASL definition - * - * Copyright (c) 2006 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 version 2 as published by the Free Software Foundation. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -DefinitionBlock ( - "acpi-dsdt.aml", // Output Filename - "DSDT", // Signature - 0x01, // DSDT Compliance Revision - "BXPC", // OEMID - "BXDSDT", // TABLE ID - 0x1 // OEM Revision - ) -{ - Scope (\) - { - /* Debug Output */ - OperationRegion (DBG, SystemIO, 0xb044, 0x04) - Field (DBG, DWordAcc, NoLock, Preserve) - { - DBGL, 32, - } - } - - - /* PCI Bus definition */ - Scope(\_SB) { - Device(PCI0) { - Name (_HID, EisaId ("PNP0A03")) - Name (_ADR, 0x00) - Name (_UID, 1) - Name(_PRT, Package() { - /* PCI IRQ routing table, example from ACPI 2.0a specification, - section 6.2.8.1 */ - /* Note: we provide the same info as the PCI routing - table of the Bochs BIOS */ -#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \ - Package() { nr##ffff, 0, lnk0, 0 }, \ - Package() { nr##ffff, 1, lnk1, 0 }, \ - Package() { nr##ffff, 2, lnk2, 0 }, \ - Package() { nr##ffff, 3, lnk3, 0 } - -#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC) -#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD) -#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA) -#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB) - prt_slot0(0x0000), - /* Device 1 is power mgmt device, and can only use irq 9 */ - Package() { 0x0001ffff, 0, LNKS, 0 }, - Package() { 0x0001ffff, 1, LNKB, 0 }, - Package() { 0x0001ffff, 2, LNKC, 0 }, - Package() { 0x0001ffff, 3, LNKD, 0 }, - prt_slot2(0x0002), - prt_slot3(0x0003), - prt_slot0(0x0004), - prt_slot1(0x0005), - prt_slot2(0x0006), - prt_slot3(0x0007), - prt_slot0(0x0008), - prt_slot1(0x0009), - prt_slot2(0x000a), - prt_slot3(0x000b), - prt_slot0(0x000c), - prt_slot1(0x000d), - prt_slot2(0x000e), - prt_slot3(0x000f), - prt_slot0(0x0010), - prt_slot1(0x0011), - prt_slot2(0x0012), - prt_slot3(0x0013), - prt_slot0(0x0014), - prt_slot1(0x0015), - prt_slot2(0x0016), - prt_slot3(0x0017), - prt_slot0(0x0018), - prt_slot1(0x0019), - prt_slot2(0x001a), - prt_slot3(0x001b), - prt_slot0(0x001c), - prt_slot1(0x001d), - prt_slot2(0x001e), - prt_slot3(0x001f), - }) - - OperationRegion(PCST, SystemIO, 0xae00, 0x08) - Field (PCST, DWordAcc, NoLock, WriteAsZeros) - { - PCIU, 32, - PCID, 32, - } - - OperationRegion(SEJ, SystemIO, 0xae08, 0x04) - Field (SEJ, DWordAcc, NoLock, WriteAsZeros) - { - B0EJ, 32, - } - -#define hotplug_slot(name, nr) \ - Device (S##name) { \ - Name (_ADR, nr##0000) \ - Method (_EJ0,1) { \ - Store(ShiftLeft(1, nr), B0EJ) \ - Return (0x0) \ - } \ - Name (_SUN, name) \ - } - - hotplug_slot(1, 0x0001) - hotplug_slot(2, 0x0002) - hotplug_slot(3, 0x0003) - hotplug_slot(4, 0x0004) - hotplug_slot(5, 0x0005) - hotplug_slot(6, 0x0006) - hotplug_slot(7, 0x0007) - hotplug_slot(8, 0x0008) - hotplug_slot(9, 0x0009) - hotplug_slot(10, 0x000a) - hotplug_slot(11, 0x000b) - hotplug_slot(12, 0x000c) - hotplug_slot(13, 0x000d) - hotplug_slot(14, 0x000e) - hotplug_slot(15, 0x000f) - hotplug_slot(16, 0x0010) - hotplug_slot(17, 0x0011) - hotplug_slot(18, 0x0012) - hotplug_slot(19, 0x0013) - hotplug_slot(20, 0x0014) - hotplug_slot(21, 0x0015) - hotplug_slot(22, 0x0016) - hotplug_slot(23, 0x0017) - hotplug_slot(24, 0x0018) - hotplug_slot(25, 0x0019) - hotplug_slot(26, 0x001a) - hotplug_slot(27, 0x001b) - hotplug_slot(28, 0x001c) - hotplug_slot(29, 0x001d) - hotplug_slot(30, 0x001e) - hotplug_slot(31, 0x001f) - - Name (_CRS, ResourceTemplate () - { - WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, - 0x0000, // Address Space Granularity - 0x0000, // Address Range Minimum - 0x00FF, // Address Range Maximum - 0x0000, // Address Translation Offset - 0x0100, // Address Length - ,, ) - IO (Decode16, - 0x0CF8, // Address Range Minimum - 0x0CF8, // Address Range Maximum - 0x01, // Address Alignment - 0x08, // Address Length - ) - WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, - 0x0000, // Address Space Granularity - 0x0000, // Address Range Minimum - 0x0CF7, // Address Range Maximum - 0x0000, // Address Translation Offset - 0x0CF8, // Address Length - ,, , TypeStatic) - WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, - 0x0000, // Address Space Granularity - 0x0D00, // Address Range Minimum - 0xFFFF, // Address Range Maximum - 0x0000, // Address Translation Offset - 0xF300, // Address Length - ,, , TypeStatic) - DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, - 0x00000000, // Address Space Granularity - 0x000A0000, // Address Range Minimum - 0x000BFFFF, // Address Range Maximum - 0x00000000, // Address Translation Offset - 0x00020000, // Address Length - ,, , AddressRangeMemory, TypeStatic) - DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, - 0x00000000, // Address Space Granularity - 0xE0000000, // Address Range Minimum - 0xFEBFFFFF, // Address Range Maximum - 0x00000000, // Address Translation Offset - 0x1EC00000, // Address Length - ,, , AddressRangeMemory, TypeStatic) - }) - } - - Device(HPET) { - Name(_HID, EISAID("PNP0103")) - Name(_UID, 0) - Method (_STA, 0, NotSerialized) { - Return(0x0F) - } - Name(_CRS, ResourceTemplate() { - DWordMemory( - ResourceConsumer, PosDecode, MinFixed, MaxFixed, - NonCacheable, ReadWrite, - 0x00000000, - 0xFED00000, - 0xFED003FF, - 0x00000000, - 0x00000400 /* 1K memory: FED00000 - FED003FF */ - ) - }) - } - } - - Scope(\_SB.PCI0) { - Device (VGA) { - Name (_ADR, 0x00020000) - Method (_S1D, 0, NotSerialized) - { - Return (0x00) - } - Method (_S2D, 0, NotSerialized) - { - Return (0x00) - } - Method (_S3D, 0, NotSerialized) - { - Return (0x00) - } - } - - /* PIIX3 ISA bridge */ - Device (ISA) { - Name (_ADR, 0x00010000) - - /* PIIX PCI to ISA irq remapping */ - OperationRegion (P40C, PCI_Config, 0x60, 0x04) - - /* Real-time clock */ - Device (RTC) - { - Name (_HID, EisaId ("PNP0B00")) - Name (_CRS, ResourceTemplate () - { - IO (Decode16, 0x0070, 0x0070, 0x10, 0x02) - IRQNoFlags () {8} - IO (Decode16, 0x0072, 0x0072, 0x02, 0x06) - }) - } - - /* Keyboard seems to be important for WinXP install */ - Device (KBD) - { - Name (_HID, EisaId ("PNP0303")) - Method (_STA, 0, NotSerialized) - { - Return (0x0f) - } - - Method (_CRS, 0, NotSerialized) - { - Name (TMP, ResourceTemplate () - { - IO (Decode16, - 0x0060, // Address Range Minimum - 0x0060, // Address Range Maximum - 0x01, // Address Alignment - 0x01, // Address Length - ) - IO (Decode16, - 0x0064, // Address Range Minimum - 0x0064, // Address Range Maximum - 0x01, // Address Alignment - 0x01, // Address Length - ) - IRQNoFlags () - {1} - }) - Return (TMP) - } - } - - /* PS/2 mouse */ - Device (MOU) - { - Name (_HID, EisaId ("PNP0F13")) - Method (_STA, 0, NotSerialized) - { - Return (0x0f) - } - - Method (_CRS, 0, NotSerialized) - { - Name (TMP, ResourceTemplate () - { - IRQNoFlags () {12} - }) - Return (TMP) - } - } - - /* PS/2 floppy controller */ - Device (FDC0) - { - Name (_HID, EisaId ("PNP0700")) - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Method (_CRS, 0, NotSerialized) - { - Name (BUF0, ResourceTemplate () - { - IO (Decode16, 0x03F2, 0x03F2, 0x00, 0x04) - IO (Decode16, 0x03F7, 0x03F7, 0x00, 0x01) - IRQNoFlags () {6} - DMA (Compatibility, NotBusMaster, Transfer8) {2} - }) - Return (BUF0) - } - } - - /* Parallel port */ - Device (LPT) - { - Name (_HID, EisaId ("PNP0400")) - Method (_STA, 0, NotSerialized) - { - Store (\_SB.PCI0.PX13.DRSA, Local0) - And (Local0, 0x80000000, Local0) - If (LEqual (Local0, 0)) - { - Return (0x00) - } - Else - { - Return (0x0F) - } - } - Method (_CRS, 0, NotSerialized) - { - Name (BUF0, ResourceTemplate () - { - IO (Decode16, 0x0378, 0x0378, 0x08, 0x08) - IRQNoFlags () {7} - }) - Return (BUF0) - } - } - - /* Serial Ports */ - Device (COM1) - { - Name (_HID, EisaId ("PNP0501")) - Name (_UID, 0x01) - Method (_STA, 0, NotSerialized) - { - Store (\_SB.PCI0.PX13.DRSC, Local0) - And (Local0, 0x08000000, Local0) - If (LEqual (Local0, 0)) - { - Return (0x00) - } - Else - { - Return (0x0F) - } - } - Method (_CRS, 0, NotSerialized) - { - Name (BUF0, ResourceTemplate () - { - IO (Decode16, 0x03F8, 0x03F8, 0x00, 0x08) - IRQNoFlags () {4} - }) - Return (BUF0) - } - } - - Device (COM2) - { - Name (_HID, EisaId ("PNP0501")) - Name (_UID, 0x02) - Method (_STA, 0, NotSerialized) - { - Store (\_SB.PCI0.PX13.DRSC, Local0) - And (Local0, 0x80000000, Local0) - If (LEqual (Local0, 0)) - { - Return (0x00) - } - Else - { - Return (0x0F) - } - } - Method (_CRS, 0, NotSerialized) - { - Name (BUF0, ResourceTemplate () - { - IO (Decode16, 0x02F8, 0x02F8, 0x00, 0x08) - IRQNoFlags () {3} - }) - Return (BUF0) - } - } - } - - /* PIIX4 PM */ - Device (PX13) { - Name (_ADR, 0x00010003) - - OperationRegion (P13C, PCI_Config, 0x5c, 0x24) - Field (P13C, DWordAcc, NoLock, Preserve) - { - DRSA, 32, - DRSB, 32, - DRSC, 32, - DRSE, 32, - DRSF, 32, - DRSG, 32, - DRSH, 32, - DRSI, 32, - DRSJ, 32 - } - } - } - - /* PCI IRQs */ - Scope(\_SB) { - Field (\_SB.PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) - { - PRQ0, 8, - PRQ1, 8, - PRQ2, 8, - PRQ3, 8 - } - - Device(LNKA){ - Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link - Name(_UID, 1) - Name(_PRS, ResourceTemplate(){ - Interrupt (, Level, ActiveHigh, Shared) - { 5, 10, 11 } - }) - Method (_STA, 0, NotSerialized) - { - Store (0x0B, Local0) - If (And (0x80, PRQ0, Local1)) - { - Store (0x09, Local0) - } - Return (Local0) - } - Method (_DIS, 0, NotSerialized) - { - Or (PRQ0, 0x80, PRQ0) - } - Method (_CRS, 0, NotSerialized) - { - Name (PRR0, ResourceTemplate () - { - Interrupt (, Level, ActiveHigh, Shared) - {1} - }) - CreateDWordField (PRR0, 0x05, TMP) - Store (PRQ0, Local0) - If (LLess (Local0, 0x80)) - { - Store (Local0, TMP) - } - Else - { - Store (Zero, TMP) - } - Return (PRR0) - } - Method (_SRS, 1, NotSerialized) - { - CreateDWordField (Arg0, 0x05, TMP) - Store (TMP, PRQ0) - } - } - Device(LNKB){ - Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link - Name(_UID, 2) - Name(_PRS, ResourceTemplate(){ - Interrupt (, Level, ActiveHigh, Shared) - { 5, 10, 11 } - }) - Method (_STA, 0, NotSerialized) - { - Store (0x0B, Local0) - If (And (0x80, PRQ1, Local1)) - { - Store (0x09, Local0) - } - Return (Local0) - } - Method (_DIS, 0, NotSerialized) - { - Or (PRQ1, 0x80, PRQ1) - } - Method (_CRS, 0, NotSerialized) - { - Name (PRR0, ResourceTemplate () - { - Interrupt (, Level, ActiveHigh, Shared) - {1} - }) - CreateDWordField (PRR0, 0x05, TMP) - Store (PRQ1, Local0) - If (LLess (Local0, 0x80)) - { - Store (Local0, TMP) - } - Else - { - Store (Zero, TMP) - } - Return (PRR0) - } - Method (_SRS, 1, NotSerialized) - { - CreateDWordField (Arg0, 0x05, TMP) - Store (TMP, PRQ1) - } - } - Device(LNKC){ - Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link - Name(_UID, 3) - Name(_PRS, ResourceTemplate(){ - Interrupt (, Level, ActiveHigh, Shared) - { 5, 10, 11 } - }) - Method (_STA, 0, NotSerialized) - { - Store (0x0B, Local0) - If (And (0x80, PRQ2, Local1)) - { - Store (0x09, Local0) - } - Return (Local0) - } - Method (_DIS, 0, NotSerialized) - { - Or (PRQ2, 0x80, PRQ2) - } - Method (_CRS, 0, NotSerialized) - { - Name (PRR0, ResourceTemplate () - { - Interrupt (, Level, ActiveHigh, Shared) - {1} - }) - CreateDWordField (PRR0, 0x05, TMP) - Store (PRQ2, Local0) - If (LLess (Local0, 0x80)) - { - Store (Local0, TMP) - } - Else - { - Store (Zero, TMP) - } - Return (PRR0) - } - Method (_SRS, 1, NotSerialized) - { - CreateDWordField (Arg0, 0x05, TMP) - Store (TMP, PRQ2) - } - } - Device(LNKD){ - Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link - Name(_UID, 4) - Name(_PRS, ResourceTemplate(){ - Interrupt (, Level, ActiveHigh, Shared) - { 5, 10, 11 } - }) - Method (_STA, 0, NotSerialized) - { - Store (0x0B, Local0) - If (And (0x80, PRQ3, Local1)) - { - Store (0x09, Local0) - } - Return (Local0) - } - Method (_DIS, 0, NotSerialized) - { - Or (PRQ3, 0x80, PRQ3) - } - Method (_CRS, 0, NotSerialized) - { - Name (PRR0, ResourceTemplate () - { - Interrupt (, Level, ActiveHigh, Shared) - {1} - }) - CreateDWordField (PRR0, 0x05, TMP) - Store (PRQ3, Local0) - If (LLess (Local0, 0x80)) - { - Store (Local0, TMP) - } - Else - { - Store (Zero, TMP) - } - Return (PRR0) - } - Method (_SRS, 1, NotSerialized) - { - CreateDWordField (Arg0, 0x05, TMP) - Store (TMP, PRQ3) - } - } - Device(LNKS){ - Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link - Name(_UID, 5) - Name(_PRS, ResourceTemplate(){ - Interrupt (, Level, ActiveHigh, Shared) - { 9 } - }) - Method (_STA, 0, NotSerialized) - { - Store (0x0B, Local0) - If (And (0x80, PRQ0, Local1)) - { - Store (0x09, Local0) - } - Return (Local0) - } - Method (_DIS, 0, NotSerialized) - { - Or (PRQ0, 0x80, PRQ0) - } - Method (_CRS, 0, NotSerialized) - { - Name (PRR0, ResourceTemplate () - { - Interrupt (, Level, ActiveHigh, Shared) - {9} - }) - CreateDWordField (PRR0, 0x05, TMP) - Store (PRQ0, Local0) - If (LLess (Local0, 0x80)) - { - Store (Local0, TMP) - } - Else - { - Store (Zero, TMP) - } - Return (PRR0) - } - } - } - - /* - * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes: - * must match piix4 emulation. - */ - Name (\_S3, Package (0x04) - { - 0x01, /* PM1a_CNT.SLP_TYP */ - 0x01, /* PM1b_CNT.SLP_TYP */ - Zero, /* reserved */ - Zero /* reserved */ - }) - Name (\_S4, Package (0x04) - { - Zero, /* PM1a_CNT.SLP_TYP */ - Zero, /* PM1b_CNT.SLP_TYP */ - Zero, /* reserved */ - Zero /* reserved */ - }) - Name (\_S5, Package (0x04) - { - Zero, /* PM1a_CNT.SLP_TYP */ - Zero, /* PM1b_CNT.SLP_TYP */ - Zero, /* reserved */ - Zero /* reserved */ - }) - - /* CPU hotplug */ - Scope(\_SB) { - /* Objects filled in by run-time generated SSDT */ - External(NTFY, MethodObj) - External(CPON, PkgObj) - - /* Methods called by run-time generated SSDT Processor objects */ - Method (CPMA, 1, NotSerialized) { - // _MAT method - create an madt apic buffer - // Local0 = CPON flag for this cpu - Store(DerefOf(Index(CPON, Arg0)), Local0) - // Local1 = Buffer (in madt apic form) to return - Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1) - // Update the processor id, lapic id, and enable/disable status - Store(Arg0, Index(Local1, 2)) - Store(Arg0, Index(Local1, 3)) - Store(Local0, Index(Local1, 4)) - Return (Local1) - } - Method (CPST, 1, NotSerialized) { - // _STA method - return ON status of cpu - // Local0 = CPON flag for this cpu - Store(DerefOf(Index(CPON, Arg0)), Local0) - If (Local0) { Return(0xF) } Else { Return(0x0) } - } - Method (CPEJ, 2, NotSerialized) { - // _EJ0 method - eject callback - Sleep(200) - } - - /* CPU hotplug notify method */ - OperationRegion(PRST, SystemIO, 0xaf00, 32) - Field (PRST, ByteAcc, NoLock, Preserve) - { - PRS, 256 - } - Method(PRSC, 0) { - // Local5 = active cpu bitmap - Store (PRS, Local5) - // Local2 = last read byte from bitmap - Store (Zero, Local2) - // Local0 = cpuid iterator - Store (Zero, Local0) - While (LLess(Local0, SizeOf(CPON))) { - // Local1 = CPON flag for this cpu - Store(DerefOf(Index(CPON, Local0)), Local1) - If (And(Local0, 0x07)) { - // Shift down previously read bitmap byte - ShiftRight(Local2, 1, Local2) - } Else { - // Read next byte from cpu bitmap - Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2) - } - // Local3 = active state for this cpu - Store(And(Local2, 1), Local3) - - If (LNotEqual(Local1, Local3)) { - // State change - update CPON with new state - Store(Local3, Index(CPON, Local0)) - // Do CPU notify - If (LEqual(Local3, 1)) { - NTFY(Local0, 1) - } Else { - NTFY(Local0, 3) - } - } - Increment(Local0) - } - Return(One) - } - } - - Scope (\_GPE) - { - Name(_HID, "ACPI0006") - - Method(_L00) { - Return(0x01) - } - -#define gen_pci_hotplug(nr) \ - If (And(\_SB.PCI0.PCIU, ShiftLeft(1, nr))) { \ - Notify(\_SB.PCI0.S##nr, 1) \ - } \ - If (And(\_SB.PCI0.PCID, ShiftLeft(1, nr))) { \ - Notify(\_SB.PCI0.S##nr, 3) \ - } - - Method(_L01) { - gen_pci_hotplug(1) - gen_pci_hotplug(2) - gen_pci_hotplug(3) - gen_pci_hotplug(4) - gen_pci_hotplug(5) - gen_pci_hotplug(6) - gen_pci_hotplug(7) - gen_pci_hotplug(8) - gen_pci_hotplug(9) - gen_pci_hotplug(10) - gen_pci_hotplug(11) - gen_pci_hotplug(12) - gen_pci_hotplug(13) - gen_pci_hotplug(14) - gen_pci_hotplug(15) - gen_pci_hotplug(16) - gen_pci_hotplug(17) - gen_pci_hotplug(18) - gen_pci_hotplug(19) - gen_pci_hotplug(20) - gen_pci_hotplug(21) - gen_pci_hotplug(22) - gen_pci_hotplug(23) - gen_pci_hotplug(24) - gen_pci_hotplug(25) - gen_pci_hotplug(26) - gen_pci_hotplug(27) - gen_pci_hotplug(28) - gen_pci_hotplug(29) - gen_pci_hotplug(30) - gen_pci_hotplug(31) - - Return (0x01) - - } - Method(_L02) { - // CPU hotplug event - Return(\_SB.PRSC()) - } - Method(_L03) { - Return(0x01) - } - Method(_L04) { - Return(0x01) - } - Method(_L05) { - Return(0x01) - } - Method(_L06) { - Return(0x01) - } - Method(_L07) { - Return(0x01) - } - Method(_L08) { - Return(0x01) - } - Method(_L09) { - Return(0x01) - } - Method(_L0A) { - Return(0x01) - } - Method(_L0B) { - Return(0x01) - } - Method(_L0C) { - Return(0x01) - } - Method(_L0D) { - Return(0x01) - } - Method(_L0E) { - Return(0x01) - } - Method(_L0F) { - Return(0x01) - } - } - -} diff --git a/roms/seabios/src/acpi-dsdt.hex b/roms/seabios/src/acpi-dsdt.hex deleted file mode 100644 index 0a017fe..0000000 --- a/roms/seabios/src/acpi-dsdt.hex +++ /dev/null @@ -1,1030 +0,0 @@ -/* - * - * Intel ACPI Component Architecture - * ASL Optimizing Compiler version 20090123 [Jul 26 2009] - * Copyright (C) 2000 - 2009 Intel Corporation - * Supports ACPI Specification Revision 3.0a - * - * Compilation of "out/acpi-dsdt.dsl.i" - Sun Oct 31 18:36:06 2010 - * - * C source code output - * - */ -unsigned char AmlCode[] = -{ - 0x44,0x53,0x44,0x54,0xB7,0x1F,0x00,0x00, /* 00000000 "DSDT...." */ - 0x01,0x19,0x42,0x58,0x50,0x43,0x00,0x00, /* 00000008 "..BXPC.." */ - 0x42,0x58,0x44,0x53,0x44,0x54,0x00,0x00, /* 00000010 "BXDSDT.." */ - 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ - 0x23,0x01,0x09,0x20,0x10,0x1C,0x5C,0x00, /* 00000020 "#.. ..\." */ - 0x5B,0x80,0x44,0x42,0x47,0x5F,0x01,0x0B, /* 00000028 "[.DBG_.." */ - 0x44,0xB0,0x0A,0x04,0x5B,0x81,0x0B,0x44, /* 00000030 "D...[..D" */ - 0x42,0x47,0x5F,0x03,0x44,0x42,0x47,0x4C, /* 00000038 "BG_.DBGL" */ - 0x20,0x10,0x4A,0xD6,0x5F,0x53,0x42,0x5F, /* 00000040 " .J._SB_" */ - 0x5B,0x82,0x4B,0xD1,0x50,0x43,0x49,0x30, /* 00000048 "[.K.PCI0" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000050 "._HID.A." */ - 0x0A,0x03,0x08,0x5F,0x41,0x44,0x52,0x00, /* 00000058 "..._ADR." */ - 0x08,0x5F,0x55,0x49,0x44,0x01,0x08,0x5F, /* 00000060 "._UID.._" */ - 0x50,0x52,0x54,0x12,0x4B,0x73,0x80,0x12, /* 00000068 "PRT.Ks.." */ - 0x0B,0x04,0x0B,0xFF,0xFF,0x00,0x4C,0x4E, /* 00000070 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0B,0x04,0x0B,0xFF, /* 00000078 "KD......" */ - 0xFF,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000080 "..LNKA.." */ - 0x0C,0x04,0x0B,0xFF,0xFF,0x0A,0x02,0x4C, /* 00000088 ".......L" */ - 0x4E,0x4B,0x42,0x00,0x12,0x0C,0x04,0x0B, /* 00000090 "NKB....." */ - 0xFF,0xFF,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000098 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01, /* 000000A0 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x53,0x00,0x12, /* 000000A8 "..LNKS.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01, /* 000000B0 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000000B8 "LNKB...." */ - 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x4C, /* 000000C0 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 000000C8 "NKC....." */ - 0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C,0x4E, /* 000000D0 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000000D8 "KD......" */ - 0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 000000E0 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02, /* 000000E8 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000000F0 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 000000F8 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 00000100 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03, /* 00000108 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000110 "LNKA...." */ - 0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C,0x4E, /* 00000118 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000120 "KC......" */ - 0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 00000128 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 00000130 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 00000138 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000140 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000148 "..LNKB.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00, /* 00000150 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000158 "LNKD...." */ - 0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C,0x4E, /* 00000160 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000168 "KA......" */ - 0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000170 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000178 "B......." */ - 0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000180 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05, /* 00000188 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000190 "..LNKA.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01, /* 00000198 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000001A0 "LNKB...." */ - 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x4C, /* 000001A8 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 000001B0 "NKC....." */ - 0xFF,0xFF,0x05,0x00,0x0A,0x03,0x4C,0x4E, /* 000001B8 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000001C0 "KD......" */ - 0xFF,0x06,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 000001C8 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06, /* 000001D0 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000001D8 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 000001E0 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000001E8 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03, /* 000001F0 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 000001F8 "LNKA...." */ - 0x0C,0xFF,0xFF,0x07,0x00,0x00,0x4C,0x4E, /* 00000200 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000208 "KC......" */ - 0xFF,0x07,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 00000210 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07, /* 00000218 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 00000220 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00, /* 00000228 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000230 "..LNKB.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00, /* 00000238 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000240 "LNKD...." */ - 0x0C,0xFF,0xFF,0x08,0x00,0x01,0x4C,0x4E, /* 00000248 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000250 "KA......" */ - 0xFF,0x08,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000258 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000260 "B......." */ - 0x08,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000268 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x09, /* 00000270 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000278 "..LNKA.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01, /* 00000280 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000288 "LNKB...." */ - 0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x4C, /* 00000290 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000298 "NKC....." */ - 0xFF,0xFF,0x09,0x00,0x0A,0x03,0x4C,0x4E, /* 000002A0 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000002A8 "KD......" */ - 0xFF,0x0A,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 000002B0 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A, /* 000002B8 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000002C0 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 000002C8 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000002D0 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03, /* 000002D8 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 000002E0 "LNKA...." */ - 0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x4C,0x4E, /* 000002E8 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000002F0 "KC......" */ - 0xFF,0x0B,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 000002F8 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000300 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 00000308 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00, /* 00000310 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000318 "..LNKB.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00, /* 00000320 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000328 "LNKD...." */ - 0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x4C,0x4E, /* 00000330 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000338 "KA......" */ - 0xFF,0x0C,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000340 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000348 "B......." */ - 0x0C,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000350 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000358 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000360 "..LNKA.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01, /* 00000368 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000370 "LNKB...." */ - 0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x4C, /* 00000378 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000380 "NKC....." */ - 0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C,0x4E, /* 00000388 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000390 "KD......" */ - 0xFF,0x0E,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 00000398 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E, /* 000003A0 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000003A8 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 000003B0 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000003B8 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03, /* 000003C0 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 000003C8 "LNKA...." */ - 0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x4C,0x4E, /* 000003D0 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000003D8 "KC......" */ - 0xFF,0x0F,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 000003E0 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F, /* 000003E8 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 000003F0 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00, /* 000003F8 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000400 "..LNKB.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x10,0x00,0x00, /* 00000408 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 00000410 "LNKD...." */ - 0x0C,0xFF,0xFF,0x10,0x00,0x01,0x4C,0x4E, /* 00000418 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000420 "KA......" */ - 0xFF,0x10,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000428 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000430 "B......." */ - 0x10,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000438 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x11, /* 00000440 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000448 "..LNKA.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x11,0x00,0x01, /* 00000450 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000458 "LNKB...." */ - 0x0C,0xFF,0xFF,0x11,0x00,0x0A,0x02,0x4C, /* 00000460 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000468 "NKC....." */ - 0xFF,0xFF,0x11,0x00,0x0A,0x03,0x4C,0x4E, /* 00000470 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000478 "KD......" */ - 0xFF,0x12,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 00000480 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x12, /* 00000488 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000490 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x12,0x00,0x0A, /* 00000498 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000004A0 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x12,0x00,0x0A,0x03, /* 000004A8 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 000004B0 "LNKA...." */ - 0x0C,0xFF,0xFF,0x13,0x00,0x00,0x4C,0x4E, /* 000004B8 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000004C0 "KC......" */ - 0xFF,0x13,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 000004C8 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x13, /* 000004D0 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 000004D8 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x13,0x00, /* 000004E0 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 000004E8 "..LNKB.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x14,0x00,0x00, /* 000004F0 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 000004F8 "LNKD...." */ - 0x0C,0xFF,0xFF,0x14,0x00,0x01,0x4C,0x4E, /* 00000500 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000508 "KA......" */ - 0xFF,0x14,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000510 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000518 "B......." */ - 0x14,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000520 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x15, /* 00000528 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000530 "..LNKA.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x15,0x00,0x01, /* 00000538 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000540 "LNKB...." */ - 0x0C,0xFF,0xFF,0x15,0x00,0x0A,0x02,0x4C, /* 00000548 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000550 "NKC....." */ - 0xFF,0xFF,0x15,0x00,0x0A,0x03,0x4C,0x4E, /* 00000558 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000560 "KD......" */ - 0xFF,0x16,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 00000568 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x16, /* 00000570 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000578 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x16,0x00,0x0A, /* 00000580 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 00000588 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x16,0x00,0x0A,0x03, /* 00000590 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000598 "LNKA...." */ - 0x0C,0xFF,0xFF,0x17,0x00,0x00,0x4C,0x4E, /* 000005A0 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000005A8 "KC......" */ - 0xFF,0x17,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 000005B0 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x17, /* 000005B8 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 000005C0 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x17,0x00, /* 000005C8 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 000005D0 "..LNKB.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x18,0x00,0x00, /* 000005D8 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 000005E0 "LNKD...." */ - 0x0C,0xFF,0xFF,0x18,0x00,0x01,0x4C,0x4E, /* 000005E8 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000005F0 "KA......" */ - 0xFF,0x18,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000005F8 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000600 "B......." */ - 0x18,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 00000608 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x19, /* 00000610 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000618 "..LNKA.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x19,0x00,0x01, /* 00000620 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000628 "LNKB...." */ - 0x0C,0xFF,0xFF,0x19,0x00,0x0A,0x02,0x4C, /* 00000630 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000638 "NKC....." */ - 0xFF,0xFF,0x19,0x00,0x0A,0x03,0x4C,0x4E, /* 00000640 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000648 "KD......" */ - 0xFF,0x1A,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 00000650 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x1A, /* 00000658 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000660 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x1A,0x00,0x0A, /* 00000668 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 00000670 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x1A,0x00,0x0A,0x03, /* 00000678 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000680 "LNKA...." */ - 0x0C,0xFF,0xFF,0x1B,0x00,0x00,0x4C,0x4E, /* 00000688 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000690 "KC......" */ - 0xFF,0x1B,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 00000698 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x1B, /* 000006A0 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 000006A8 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x1B,0x00, /* 000006B0 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 000006B8 "..LNKB.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x1C,0x00,0x00, /* 000006C0 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04, /* 000006C8 "LNKD...." */ - 0x0C,0xFF,0xFF,0x1C,0x00,0x01,0x4C,0x4E, /* 000006D0 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000006D8 "KA......" */ - 0xFF,0x1C,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000006E0 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000006E8 "B......." */ - 0x1C,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43, /* 000006F0 "....LNKC" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x1D, /* 000006F8 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000700 "..LNKA.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x1D,0x00,0x01, /* 00000708 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000710 "LNKB...." */ - 0x0C,0xFF,0xFF,0x1D,0x00,0x0A,0x02,0x4C, /* 00000718 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 00000720 "NKC....." */ - 0xFF,0xFF,0x1D,0x00,0x0A,0x03,0x4C,0x4E, /* 00000728 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000730 "KD......" */ - 0xFF,0x1E,0x00,0x00,0x4C,0x4E,0x4B,0x42, /* 00000738 "....LNKB" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x1E, /* 00000740 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000748 "..LNKC.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x1E,0x00,0x0A, /* 00000750 "........" */ - 0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 00000758 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x1E,0x00,0x0A,0x03, /* 00000760 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000768 "LNKA...." */ - 0x0C,0xFF,0xFF,0x1F,0x00,0x00,0x4C,0x4E, /* 00000770 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000778 "KC......" */ - 0xFF,0x1F,0x00,0x01,0x4C,0x4E,0x4B,0x44, /* 00000780 "....LNKD" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x1F, /* 00000788 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00, /* 00000790 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x1F,0x00, /* 00000798 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x5B, /* 000007A0 "..LNKB.[" */ - 0x80,0x50,0x43,0x53,0x54,0x01,0x0B,0x00, /* 000007A8 ".PCST..." */ - 0xAE,0x0A,0x08,0x5B,0x81,0x10,0x50,0x43, /* 000007B0 "...[..PC" */ - 0x53,0x54,0x43,0x50,0x43,0x49,0x55,0x20, /* 000007B8 "STCPCIU " */ - 0x50,0x43,0x49,0x44,0x20,0x5B,0x80,0x53, /* 000007C0 "PCID [.S" */ - 0x45,0x4A,0x5F,0x01,0x0B,0x08,0xAE,0x0A, /* 000007C8 "EJ_....." */ - 0x04,0x5B,0x81,0x0B,0x53,0x45,0x4A,0x5F, /* 000007D0 ".[..SEJ_" */ - 0x43,0x42,0x30,0x45,0x4A,0x20,0x5B,0x82, /* 000007D8 "CB0EJ [." */ - 0x25,0x53,0x31,0x5F,0x5F,0x08,0x5F,0x41, /* 000007E0 "%S1__._A" */ - 0x44,0x52,0x0C,0x00,0x00,0x01,0x00,0x14, /* 000007E8 "DR......" */ - 0x0F,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 000007F0 "._EJ0.p." */ - 0x02,0x42,0x30,0x45,0x4A,0xA4,0x00,0x08, /* 000007F8 ".B0EJ..." */ - 0x5F,0x53,0x55,0x4E,0x01,0x5B,0x82,0x26, /* 00000800 "_SUN.[.&" */ - 0x53,0x32,0x5F,0x5F,0x08,0x5F,0x41,0x44, /* 00000808 "S2__._AD" */ - 0x52,0x0C,0x00,0x00,0x02,0x00,0x14,0x0F, /* 00000810 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,0x04, /* 00000818 "_EJ0.p.." */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 00000820 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x02,0x5B,0x82,0x26, /* 00000828 "SUN..[.&" */ - 0x53,0x33,0x5F,0x5F,0x08,0x5F,0x41,0x44, /* 00000830 "S3__._AD" */ - 0x52,0x0C,0x00,0x00,0x03,0x00,0x14,0x0F, /* 00000838 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,0x08, /* 00000840 "_EJ0.p.." */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 00000848 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x03,0x5B,0x82,0x26, /* 00000850 "SUN..[.&" */ - 0x53,0x34,0x5F,0x5F,0x08,0x5F,0x41,0x44, /* 00000858 "S4__._AD" */ - 0x52,0x0C,0x00,0x00,0x04,0x00,0x14,0x0F, /* 00000860 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,0x10, /* 00000868 "_EJ0.p.." */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 00000870 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x04,0x5B,0x82,0x26, /* 00000878 "SUN..[.&" */ - 0x53,0x35,0x5F,0x5F,0x08,0x5F,0x41,0x44, /* 00000880 "S5__._AD" */ - 0x52,0x0C,0x00,0x00,0x05,0x00,0x14,0x0F, /* 00000888 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,0x20, /* 00000890 "_EJ0.p. " */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 00000898 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x05,0x5B,0x82,0x26, /* 000008A0 "SUN..[.&" */ - 0x53,0x36,0x5F,0x5F,0x08,0x5F,0x41,0x44, /* 000008A8 "S6__._AD" */ - 0x52,0x0C,0x00,0x00,0x06,0x00,0x14,0x0F, /* 000008B0 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,0x40, /* 000008B8 "_EJ0.p.@" */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 000008C0 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x06,0x5B,0x82,0x26, /* 000008C8 "SUN..[.&" */ - 0x53,0x37,0x5F,0x5F,0x08,0x5F,0x41,0x44, /* 000008D0 "S7__._AD" */ - 0x52,0x0C,0x00,0x00,0x07,0x00,0x14,0x0F, /* 000008D8 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,0x80, /* 000008E0 "_EJ0.p.." */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 000008E8 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x07,0x5B,0x82,0x27, /* 000008F0 "SUN..[.'" */ - 0x53,0x38,0x5F,0x5F,0x08,0x5F,0x41,0x44, /* 000008F8 "S8__._AD" */ - 0x52,0x0C,0x00,0x00,0x08,0x00,0x14,0x10, /* 00000900 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0B,0x00, /* 00000908 "_EJ0.p.." */ - 0x01,0x42,0x30,0x45,0x4A,0xA4,0x00,0x08, /* 00000910 ".B0EJ..." */ - 0x5F,0x53,0x55,0x4E,0x0A,0x08,0x5B,0x82, /* 00000918 "_SUN..[." */ - 0x27,0x53,0x39,0x5F,0x5F,0x08,0x5F,0x41, /* 00000920 "'S9__._A" */ - 0x44,0x52,0x0C,0x00,0x00,0x09,0x00,0x14, /* 00000928 "DR......" */ - 0x10,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0B, /* 00000930 "._EJ0.p." */ - 0x00,0x02,0x42,0x30,0x45,0x4A,0xA4,0x00, /* 00000938 "..B0EJ.." */ - 0x08,0x5F,0x53,0x55,0x4E,0x0A,0x09,0x5B, /* 00000940 "._SUN..[" */ - 0x82,0x27,0x53,0x31,0x30,0x5F,0x08,0x5F, /* 00000948 ".'S10_._" */ - 0x41,0x44,0x52,0x0C,0x00,0x00,0x0A,0x00, /* 00000950 "ADR....." */ - 0x14,0x10,0x5F,0x45,0x4A,0x30,0x01,0x70, /* 00000958 ".._EJ0.p" */ - 0x0B,0x00,0x04,0x42,0x30,0x45,0x4A,0xA4, /* 00000960 "...B0EJ." */ - 0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,0x0A, /* 00000968 ".._SUN.." */ - 0x5B,0x82,0x27,0x53,0x31,0x31,0x5F,0x08, /* 00000970 "[.'S11_." */ - 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x0B, /* 00000978 "_ADR...." */ - 0x00,0x14,0x10,0x5F,0x45,0x4A,0x30,0x01, /* 00000980 "..._EJ0." */ - 0x70,0x0B,0x00,0x08,0x42,0x30,0x45,0x4A, /* 00000988 "p...B0EJ" */ - 0xA4,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00000990 "..._SUN." */ - 0x0B,0x5B,0x82,0x27,0x53,0x31,0x32,0x5F, /* 00000998 ".[.'S12_" */ - 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 000009A0 "._ADR..." */ - 0x0C,0x00,0x14,0x10,0x5F,0x45,0x4A,0x30, /* 000009A8 "...._EJ0" */ - 0x01,0x70,0x0B,0x00,0x10,0x42,0x30,0x45, /* 000009B0 ".p...B0E" */ - 0x4A,0xA4,0x00,0x08,0x5F,0x53,0x55,0x4E, /* 000009B8 "J..._SUN" */ - 0x0A,0x0C,0x5B,0x82,0x27,0x53,0x31,0x33, /* 000009C0 "..[.'S13" */ - 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 000009C8 "_._ADR.." */ - 0x00,0x0D,0x00,0x14,0x10,0x5F,0x45,0x4A, /* 000009D0 "....._EJ" */ - 0x30,0x01,0x70,0x0B,0x00,0x20,0x42,0x30, /* 000009D8 "0.p.. B0" */ - 0x45,0x4A,0xA4,0x00,0x08,0x5F,0x53,0x55, /* 000009E0 "EJ..._SU" */ - 0x4E,0x0A,0x0D,0x5B,0x82,0x27,0x53,0x31, /* 000009E8 "N..[.'S1" */ - 0x34,0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C, /* 000009F0 "4_._ADR." */ - 0x00,0x00,0x0E,0x00,0x14,0x10,0x5F,0x45, /* 000009F8 "......_E" */ - 0x4A,0x30,0x01,0x70,0x0B,0x00,0x40,0x42, /* 00000A00 "J0.p..@B" */ - 0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F,0x53, /* 00000A08 "0EJ..._S" */ - 0x55,0x4E,0x0A,0x0E,0x5B,0x82,0x27,0x53, /* 00000A10 "UN..[.'S" */ - 0x31,0x35,0x5F,0x08,0x5F,0x41,0x44,0x52, /* 00000A18 "15_._ADR" */ - 0x0C,0x00,0x00,0x0F,0x00,0x14,0x10,0x5F, /* 00000A20 "......._" */ - 0x45,0x4A,0x30,0x01,0x70,0x0B,0x00,0x80, /* 00000A28 "EJ0.p..." */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 00000A30 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x0F,0x5B,0x82,0x29, /* 00000A38 "SUN..[.)" */ - 0x53,0x31,0x36,0x5F,0x08,0x5F,0x41,0x44, /* 00000A40 "S16_._AD" */ - 0x52,0x0C,0x00,0x00,0x10,0x00,0x14,0x12, /* 00000A48 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0C,0x00, /* 00000A50 "_EJ0.p.." */ - 0x00,0x01,0x00,0x42,0x30,0x45,0x4A,0xA4, /* 00000A58 "...B0EJ." */ - 0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,0x10, /* 00000A60 ".._SUN.." */ - 0x5B,0x82,0x29,0x53,0x31,0x37,0x5F,0x08, /* 00000A68 "[.)S17_." */ - 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x11, /* 00000A70 "_ADR...." */ - 0x00,0x14,0x12,0x5F,0x45,0x4A,0x30,0x01, /* 00000A78 "..._EJ0." */ - 0x70,0x0C,0x00,0x00,0x02,0x00,0x42,0x30, /* 00000A80 "p.....B0" */ - 0x45,0x4A,0xA4,0x00,0x08,0x5F,0x53,0x55, /* 00000A88 "EJ..._SU" */ - 0x4E,0x0A,0x11,0x5B,0x82,0x29,0x53,0x31, /* 00000A90 "N..[.)S1" */ - 0x38,0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C, /* 00000A98 "8_._ADR." */ - 0x00,0x00,0x12,0x00,0x14,0x12,0x5F,0x45, /* 00000AA0 "......_E" */ - 0x4A,0x30,0x01,0x70,0x0C,0x00,0x00,0x04, /* 00000AA8 "J0.p...." */ - 0x00,0x42,0x30,0x45,0x4A,0xA4,0x00,0x08, /* 00000AB0 ".B0EJ..." */ - 0x5F,0x53,0x55,0x4E,0x0A,0x12,0x5B,0x82, /* 00000AB8 "_SUN..[." */ - 0x29,0x53,0x31,0x39,0x5F,0x08,0x5F,0x41, /* 00000AC0 ")S19_._A" */ - 0x44,0x52,0x0C,0x00,0x00,0x13,0x00,0x14, /* 00000AC8 "DR......" */ - 0x12,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0C, /* 00000AD0 "._EJ0.p." */ - 0x00,0x00,0x08,0x00,0x42,0x30,0x45,0x4A, /* 00000AD8 "....B0EJ" */ - 0xA4,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00000AE0 "..._SUN." */ - 0x13,0x5B,0x82,0x29,0x53,0x32,0x30,0x5F, /* 00000AE8 ".[.)S20_" */ - 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00000AF0 "._ADR..." */ - 0x14,0x00,0x14,0x12,0x5F,0x45,0x4A,0x30, /* 00000AF8 "...._EJ0" */ - 0x01,0x70,0x0C,0x00,0x00,0x10,0x00,0x42, /* 00000B00 ".p.....B" */ - 0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F,0x53, /* 00000B08 "0EJ..._S" */ - 0x55,0x4E,0x0A,0x14,0x5B,0x82,0x29,0x53, /* 00000B10 "UN..[.)S" */ - 0x32,0x31,0x5F,0x08,0x5F,0x41,0x44,0x52, /* 00000B18 "21_._ADR" */ - 0x0C,0x00,0x00,0x15,0x00,0x14,0x12,0x5F, /* 00000B20 "......._" */ - 0x45,0x4A,0x30,0x01,0x70,0x0C,0x00,0x00, /* 00000B28 "EJ0.p..." */ - 0x20,0x00,0x42,0x30,0x45,0x4A,0xA4,0x00, /* 00000B30 " .B0EJ.." */ - 0x08,0x5F,0x53,0x55,0x4E,0x0A,0x15,0x5B, /* 00000B38 "._SUN..[" */ - 0x82,0x29,0x53,0x32,0x32,0x5F,0x08,0x5F, /* 00000B40 ".)S22_._" */ - 0x41,0x44,0x52,0x0C,0x00,0x00,0x16,0x00, /* 00000B48 "ADR....." */ - 0x14,0x12,0x5F,0x45,0x4A,0x30,0x01,0x70, /* 00000B50 ".._EJ0.p" */ - 0x0C,0x00,0x00,0x40,0x00,0x42,0x30,0x45, /* 00000B58 "...@.B0E" */ - 0x4A,0xA4,0x00,0x08,0x5F,0x53,0x55,0x4E, /* 00000B60 "J..._SUN" */ - 0x0A,0x16,0x5B,0x82,0x29,0x53,0x32,0x33, /* 00000B68 "..[.)S23" */ - 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 00000B70 "_._ADR.." */ - 0x00,0x17,0x00,0x14,0x12,0x5F,0x45,0x4A, /* 00000B78 "....._EJ" */ - 0x30,0x01,0x70,0x0C,0x00,0x00,0x80,0x00, /* 00000B80 "0.p....." */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 00000B88 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x17,0x5B,0x82,0x29, /* 00000B90 "SUN..[.)" */ - 0x53,0x32,0x34,0x5F,0x08,0x5F,0x41,0x44, /* 00000B98 "S24_._AD" */ - 0x52,0x0C,0x00,0x00,0x18,0x00,0x14,0x12, /* 00000BA0 "R......." */ - 0x5F,0x45,0x4A,0x30,0x01,0x70,0x0C,0x00, /* 00000BA8 "_EJ0.p.." */ - 0x00,0x00,0x01,0x42,0x30,0x45,0x4A,0xA4, /* 00000BB0 "...B0EJ." */ - 0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,0x18, /* 00000BB8 ".._SUN.." */ - 0x5B,0x82,0x29,0x53,0x32,0x35,0x5F,0x08, /* 00000BC0 "[.)S25_." */ - 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x19, /* 00000BC8 "_ADR...." */ - 0x00,0x14,0x12,0x5F,0x45,0x4A,0x30,0x01, /* 00000BD0 "..._EJ0." */ - 0x70,0x0C,0x00,0x00,0x00,0x02,0x42,0x30, /* 00000BD8 "p.....B0" */ - 0x45,0x4A,0xA4,0x00,0x08,0x5F,0x53,0x55, /* 00000BE0 "EJ..._SU" */ - 0x4E,0x0A,0x19,0x5B,0x82,0x29,0x53,0x32, /* 00000BE8 "N..[.)S2" */ - 0x36,0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C, /* 00000BF0 "6_._ADR." */ - 0x00,0x00,0x1A,0x00,0x14,0x12,0x5F,0x45, /* 00000BF8 "......_E" */ - 0x4A,0x30,0x01,0x70,0x0C,0x00,0x00,0x00, /* 00000C00 "J0.p...." */ - 0x04,0x42,0x30,0x45,0x4A,0xA4,0x00,0x08, /* 00000C08 ".B0EJ..." */ - 0x5F,0x53,0x55,0x4E,0x0A,0x1A,0x5B,0x82, /* 00000C10 "_SUN..[." */ - 0x29,0x53,0x32,0x37,0x5F,0x08,0x5F,0x41, /* 00000C18 ")S27_._A" */ - 0x44,0x52,0x0C,0x00,0x00,0x1B,0x00,0x14, /* 00000C20 "DR......" */ - 0x12,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0C, /* 00000C28 "._EJ0.p." */ - 0x00,0x00,0x00,0x08,0x42,0x30,0x45,0x4A, /* 00000C30 "....B0EJ" */ - 0xA4,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00000C38 "..._SUN." */ - 0x1B,0x5B,0x82,0x29,0x53,0x32,0x38,0x5F, /* 00000C40 ".[.)S28_" */ - 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00000C48 "._ADR..." */ - 0x1C,0x00,0x14,0x12,0x5F,0x45,0x4A,0x30, /* 00000C50 "...._EJ0" */ - 0x01,0x70,0x0C,0x00,0x00,0x00,0x10,0x42, /* 00000C58 ".p.....B" */ - 0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F,0x53, /* 00000C60 "0EJ..._S" */ - 0x55,0x4E,0x0A,0x1C,0x5B,0x82,0x29,0x53, /* 00000C68 "UN..[.)S" */ - 0x32,0x39,0x5F,0x08,0x5F,0x41,0x44,0x52, /* 00000C70 "29_._ADR" */ - 0x0C,0x00,0x00,0x1D,0x00,0x14,0x12,0x5F, /* 00000C78 "......._" */ - 0x45,0x4A,0x30,0x01,0x70,0x0C,0x00,0x00, /* 00000C80 "EJ0.p..." */ - 0x00,0x20,0x42,0x30,0x45,0x4A,0xA4,0x00, /* 00000C88 ". B0EJ.." */ - 0x08,0x5F,0x53,0x55,0x4E,0x0A,0x1D,0x5B, /* 00000C90 "._SUN..[" */ - 0x82,0x29,0x53,0x33,0x30,0x5F,0x08,0x5F, /* 00000C98 ".)S30_._" */ - 0x41,0x44,0x52,0x0C,0x00,0x00,0x1E,0x00, /* 00000CA0 "ADR....." */ - 0x14,0x12,0x5F,0x45,0x4A,0x30,0x01,0x70, /* 00000CA8 ".._EJ0.p" */ - 0x0C,0x00,0x00,0x00,0x40,0x42,0x30,0x45, /* 00000CB0 "....@B0E" */ - 0x4A,0xA4,0x00,0x08,0x5F,0x53,0x55,0x4E, /* 00000CB8 "J..._SUN" */ - 0x0A,0x1E,0x5B,0x82,0x29,0x53,0x33,0x31, /* 00000CC0 "..[.)S31" */ - 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 00000CC8 "_._ADR.." */ - 0x00,0x1F,0x00,0x14,0x12,0x5F,0x45,0x4A, /* 00000CD0 "....._EJ" */ - 0x30,0x01,0x70,0x0C,0x00,0x00,0x00,0x80, /* 00000CD8 "0.p....." */ - 0x42,0x30,0x45,0x4A,0xA4,0x00,0x08,0x5F, /* 00000CE0 "B0EJ..._" */ - 0x53,0x55,0x4E,0x0A,0x1F,0x08,0x5F,0x43, /* 00000CE8 "SUN..._C" */ - 0x52,0x53,0x11,0x42,0x07,0x0A,0x6E,0x88, /* 00000CF0 "RS.B..n." */ - 0x0D,0x00,0x02,0x0C,0x00,0x00,0x00,0x00, /* 00000CF8 "........" */ - 0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x47, /* 00000D00 ".......G" */ - 0x01,0xF8,0x0C,0xF8,0x0C,0x01,0x08,0x88, /* 00000D08 "........" */ - 0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,0x00, /* 00000D10 "........" */ - 0x00,0xF7,0x0C,0x00,0x00,0xF8,0x0C,0x88, /* 00000D18 "........" */ - 0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,0x00, /* 00000D20 "........" */ - 0x0D,0xFF,0xFF,0x00,0x00,0x00,0xF3,0x87, /* 00000D28 "........" */ - 0x17,0x00,0x00,0x0C,0x03,0x00,0x00,0x00, /* 00000D30 "........" */ - 0x00,0x00,0x00,0x0A,0x00,0xFF,0xFF,0x0B, /* 00000D38 "........" */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02, /* 00000D40 "........" */ - 0x00,0x87,0x17,0x00,0x00,0x0C,0x01,0x00, /* 00000D48 "........" */ - 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF, /* 00000D50 "........" */ - 0xFF,0xBF,0xFE,0x00,0x00,0x00,0x00,0x00, /* 00000D58 "........" */ - 0x00,0xC0,0x1E,0x79,0x00,0x5B,0x82,0x45, /* 00000D60 "...y.[.E" */ - 0x04,0x48,0x50,0x45,0x54,0x08,0x5F,0x48, /* 00000D68 ".HPET._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x01,0x03,0x08, /* 00000D70 "ID.A...." */ - 0x5F,0x55,0x49,0x44,0x00,0x14,0x09,0x5F, /* 00000D78 "_UID..._" */ - 0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 00000D80 "STA....." */ - 0x5F,0x43,0x52,0x53,0x11,0x1F,0x0A,0x1C, /* 00000D88 "_CRS...." */ - 0x87,0x17,0x00,0x00,0x0D,0x01,0x00,0x00, /* 00000D90 "........" */ - 0x00,0x00,0x00,0x00,0xD0,0xFE,0xFF,0x03, /* 00000D98 "........" */ - 0xD0,0xFE,0x00,0x00,0x00,0x00,0x00,0x04, /* 00000DA0 "........" */ - 0x00,0x00,0x79,0x00,0x10,0x4D,0x2B,0x2E, /* 00000DA8 "..y..M+." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00000DB0 "_SB_PCI0" */ - 0x5B,0x82,0x2A,0x56,0x47,0x41,0x5F,0x08, /* 00000DB8 "[.*VGA_." */ - 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x02, /* 00000DC0 "_ADR...." */ - 0x00,0x14,0x08,0x5F,0x53,0x31,0x44,0x00, /* 00000DC8 "..._S1D." */ - 0xA4,0x00,0x14,0x08,0x5F,0x53,0x32,0x44, /* 00000DD0 "...._S2D" */ - 0x00,0xA4,0x00,0x14,0x08,0x5F,0x53,0x33, /* 00000DD8 "....._S3" */ - 0x44,0x00,0xA4,0x00,0x5B,0x82,0x42,0x23, /* 00000DE0 "D...[.B#" */ - 0x49,0x53,0x41,0x5F,0x08,0x5F,0x41,0x44, /* 00000DE8 "ISA_._AD" */ - 0x52,0x0C,0x00,0x00,0x01,0x00,0x5B,0x80, /* 00000DF0 "R.....[." */ - 0x50,0x34,0x30,0x43,0x02,0x0A,0x60,0x0A, /* 00000DF8 "P40C..`." */ - 0x04,0x5B,0x82,0x2D,0x52,0x54,0x43,0x5F, /* 00000E00 ".[.-RTC_" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000E08 "._HID.A." */ - 0x0B,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000E10 "..._CRS." */ - 0x18,0x0A,0x15,0x47,0x01,0x70,0x00,0x70, /* 00000E18 "...G.p.p" */ - 0x00,0x10,0x02,0x22,0x00,0x01,0x47,0x01, /* 00000E20 "..."..G." */ - 0x72,0x00,0x72,0x00,0x02,0x06,0x79,0x00, /* 00000E28 "r.r...y." */ - 0x5B,0x82,0x44,0x04,0x4B,0x42,0x44,0x5F, /* 00000E30 "[.D.KBD_" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000E38 "._HID.A." */ - 0x03,0x03,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000E40 "...._STA" */ - 0x00,0xA4,0x0A,0x0F,0x14,0x29,0x5F,0x43, /* 00000E48 ".....)_C" */ - 0x52,0x53,0x00,0x08,0x54,0x4D,0x50,0x5F, /* 00000E50 "RS..TMP_" */ - 0x11,0x18,0x0A,0x15,0x47,0x01,0x60,0x00, /* 00000E58 "....G.`." */ - 0x60,0x00,0x01,0x01,0x47,0x01,0x64,0x00, /* 00000E60 "`...G.d." */ - 0x64,0x00,0x01,0x01,0x22,0x02,0x00,0x79, /* 00000E68 "d..."..y" */ - 0x00,0xA4,0x54,0x4D,0x50,0x5F,0x5B,0x82, /* 00000E70 "..TMP_[." */ - 0x33,0x4D,0x4F,0x55,0x5F,0x08,0x5F,0x48, /* 00000E78 "3MOU_._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14, /* 00000E80 "ID.A...." */ - 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000E88 "._STA..." */ - 0x0F,0x14,0x19,0x5F,0x43,0x52,0x53,0x00, /* 00000E90 "..._CRS." */ - 0x08,0x54,0x4D,0x50,0x5F,0x11,0x08,0x0A, /* 00000E98 ".TMP_..." */ - 0x05,0x22,0x00,0x10,0x79,0x00,0xA4,0x54, /* 00000EA0 "."..y..T" */ - 0x4D,0x50,0x5F,0x5B,0x82,0x47,0x04,0x46, /* 00000EA8 "MP_[.G.F" */ - 0x44,0x43,0x30,0x08,0x5F,0x48,0x49,0x44, /* 00000EB0 "DC0._HID" */ - 0x0C,0x41,0xD0,0x07,0x00,0x14,0x09,0x5F, /* 00000EB8 ".A....._" */ - 0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x14, /* 00000EC0 "STA....." */ - 0x2C,0x5F,0x43,0x52,0x53,0x00,0x08,0x42, /* 00000EC8 ",_CRS..B" */ - 0x55,0x46,0x30,0x11,0x1B,0x0A,0x18,0x47, /* 00000ED0 "UF0....G" */ - 0x01,0xF2,0x03,0xF2,0x03,0x00,0x04,0x47, /* 00000ED8 ".......G" */ - 0x01,0xF7,0x03,0xF7,0x03,0x00,0x01,0x22, /* 00000EE0 "......."" */ - 0x40,0x00,0x2A,0x04,0x00,0x79,0x00,0xA4, /* 00000EE8 "@.*..y.." */ - 0x42,0x55,0x46,0x30,0x5B,0x82,0x4B,0x05, /* 00000EF0 "BUF0[.K." */ - 0x4C,0x50,0x54,0x5F,0x08,0x5F,0x48,0x49, /* 00000EF8 "LPT_._HI" */ - 0x44,0x0C,0x41,0xD0,0x04,0x00,0x14,0x28, /* 00000F00 "D.A....(" */ - 0x5F,0x53,0x54,0x41,0x00,0x70,0x5E,0x5E, /* 00000F08 "_STA.p^^" */ - 0x5E,0x2E,0x50,0x58,0x31,0x33,0x44,0x52, /* 00000F10 "^.PX13DR" */ - 0x53,0x41,0x60,0x7B,0x60,0x0C,0x00,0x00, /* 00000F18 "SA`{`..." */ - 0x00,0x80,0x60,0xA0,0x06,0x93,0x60,0x00, /* 00000F20 "..`...`." */ - 0xA4,0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x14, /* 00000F28 "........" */ - 0x21,0x5F,0x43,0x52,0x53,0x00,0x08,0x42, /* 00000F30 "!_CRS..B" */ - 0x55,0x46,0x30,0x11,0x10,0x0A,0x0D,0x47, /* 00000F38 "UF0....G" */ - 0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22, /* 00000F40 ".x.x..."" */ - 0x80,0x00,0x79,0x00,0xA4,0x42,0x55,0x46, /* 00000F48 "..y..BUF" */ - 0x30,0x5B,0x82,0x41,0x06,0x43,0x4F,0x4D, /* 00000F50 "0[.A.COM" */ - 0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000F58 "1._HID.A" */ - 0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,0x44, /* 00000F60 "...._UID" */ - 0x01,0x14,0x28,0x5F,0x53,0x54,0x41,0x00, /* 00000F68 "..(_STA." */ - 0x70,0x5E,0x5E,0x5E,0x2E,0x50,0x58,0x31, /* 00000F70 "p^^^.PX1" */ - 0x33,0x44,0x52,0x53,0x43,0x60,0x7B,0x60, /* 00000F78 "3DRSC`{`" */ - 0x0C,0x00,0x00,0x00,0x08,0x60,0xA0,0x06, /* 00000F80 ".....`.." */ - 0x93,0x60,0x00,0xA4,0x00,0xA1,0x04,0xA4, /* 00000F88 ".`......" */ - 0x0A,0x0F,0x14,0x21,0x5F,0x43,0x52,0x53, /* 00000F90 "...!_CRS" */ - 0x00,0x08,0x42,0x55,0x46,0x30,0x11,0x10, /* 00000F98 "..BUF0.." */ - 0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03, /* 00000FA0 "..G....." */ - 0x00,0x08,0x22,0x10,0x00,0x79,0x00,0xA4, /* 00000FA8 ".."..y.." */ - 0x42,0x55,0x46,0x30,0x5B,0x82,0x42,0x06, /* 00000FB0 "BUF0[.B." */ - 0x43,0x4F,0x4D,0x32,0x08,0x5F,0x48,0x49, /* 00000FB8 "COM2._HI" */ - 0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F, /* 00000FC0 "D.A...._" */ - 0x55,0x49,0x44,0x0A,0x02,0x14,0x28,0x5F, /* 00000FC8 "UID...(_" */ - 0x53,0x54,0x41,0x00,0x70,0x5E,0x5E,0x5E, /* 00000FD0 "STA.p^^^" */ - 0x2E,0x50,0x58,0x31,0x33,0x44,0x52,0x53, /* 00000FD8 ".PX13DRS" */ - 0x43,0x60,0x7B,0x60,0x0C,0x00,0x00,0x00, /* 00000FE0 "C`{`...." */ - 0x80,0x60,0xA0,0x06,0x93,0x60,0x00,0xA4, /* 00000FE8 ".`...`.." */ - 0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x14,0x21, /* 00000FF0 ".......!" */ - 0x5F,0x43,0x52,0x53,0x00,0x08,0x42,0x55, /* 00000FF8 "_CRS..BU" */ - 0x46,0x30,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00001000 "F0....G." */ - 0xF8,0x02,0xF8,0x02,0x00,0x08,0x22,0x08, /* 00001008 "......"." */ - 0x00,0x79,0x00,0xA4,0x42,0x55,0x46,0x30, /* 00001010 ".y..BUF0" */ - 0x5B,0x82,0x40,0x05,0x50,0x58,0x31,0x33, /* 00001018 "[.@.PX13" */ - 0x08,0x5F,0x41,0x44,0x52,0x0C,0x03,0x00, /* 00001020 "._ADR..." */ - 0x01,0x00,0x5B,0x80,0x50,0x31,0x33,0x43, /* 00001028 "..[.P13C" */ - 0x02,0x0A,0x5C,0x0A,0x24,0x5B,0x81,0x33, /* 00001030 "..\.$[.3" */ - 0x50,0x31,0x33,0x43,0x03,0x44,0x52,0x53, /* 00001038 "P13C.DRS" */ - 0x41,0x20,0x44,0x52,0x53,0x42,0x20,0x44, /* 00001040 "A DRSB D" */ - 0x52,0x53,0x43,0x20,0x44,0x52,0x53,0x45, /* 00001048 "RSC DRSE" */ - 0x20,0x44,0x52,0x53,0x46,0x20,0x44,0x52, /* 00001050 " DRSF DR" */ - 0x53,0x47,0x20,0x44,0x52,0x53,0x48,0x20, /* 00001058 "SG DRSH " */ - 0x44,0x52,0x53,0x49,0x20,0x44,0x52,0x53, /* 00001060 "DRSI DRS" */ - 0x4A,0x20,0x10,0x4B,0x3C,0x5F,0x53,0x42, /* 00001068 "J .K<_SB" */ - 0x5F,0x5B,0x81,0x24,0x2F,0x03,0x50,0x43, /* 00001070 "_[.$/.PC" */ - 0x49,0x30,0x49,0x53,0x41,0x5F,0x50,0x34, /* 00001078 "I0ISA_P4" */ - 0x30,0x43,0x01,0x50,0x52,0x51,0x30,0x08, /* 00001080 "0C.PRQ0." */ - 0x50,0x52,0x51,0x31,0x08,0x50,0x52,0x51, /* 00001088 "PRQ1.PRQ" */ - 0x32,0x08,0x50,0x52,0x51,0x33,0x08,0x5B, /* 00001090 "2.PRQ3.[" */ - 0x82,0x4D,0x0B,0x4C,0x4E,0x4B,0x41,0x08, /* 00001098 ".M.LNKA." */ - 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 000010A0 "_HID.A.." */ - 0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,0x08, /* 000010A8 ".._UID.." */ - 0x5F,0x50,0x52,0x53,0x11,0x16,0x0A,0x13, /* 000010B0 "_PRS...." */ - 0x89,0x0E,0x00,0x09,0x03,0x05,0x00,0x00, /* 000010B8 "........" */ - 0x00,0x0A,0x00,0x00,0x00,0x0B,0x00,0x00, /* 000010C0 "........" */ - 0x00,0x79,0x00,0x14,0x1A,0x5F,0x53,0x54, /* 000010C8 ".y..._ST" */ - 0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D, /* 000010D0 "A.p..`.." */ - 0x7B,0x0A,0x80,0x50,0x52,0x51,0x30,0x61, /* 000010D8 "{..PRQ0a" */ - 0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,0x11, /* 000010E0 "p..`.`.." */ - 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x52, /* 000010E8 "_DIS.}PR" */ - 0x51,0x30,0x0A,0x80,0x50,0x52,0x51,0x30, /* 000010F0 "Q0..PRQ0" */ - 0x14,0x45,0x04,0x5F,0x43,0x52,0x53,0x00, /* 000010F8 ".E._CRS." */ - 0x08,0x50,0x52,0x52,0x30,0x11,0x0E,0x0A, /* 00001100 ".PRR0..." */ - 0x0B,0x89,0x06,0x00,0x09,0x01,0x01,0x00, /* 00001108 "........" */ - 0x00,0x00,0x79,0x00,0x8A,0x50,0x52,0x52, /* 00001110 "..y..PRR" */ - 0x30,0x0A,0x05,0x54,0x4D,0x50,0x5F,0x70, /* 00001118 "0..TMP_p" */ - 0x50,0x52,0x51,0x30,0x60,0xA0,0x0B,0x95, /* 00001120 "PRQ0`..." */ - 0x60,0x0A,0x80,0x70,0x60,0x54,0x4D,0x50, /* 00001128 "`..p`TMP" */ - 0x5F,0xA1,0x07,0x70,0x00,0x54,0x4D,0x50, /* 00001130 "_..p.TMP" */ - 0x5F,0xA4,0x50,0x52,0x52,0x30,0x14,0x17, /* 00001138 "_.PRR0.." */ - 0x5F,0x53,0x52,0x53,0x01,0x8A,0x68,0x0A, /* 00001140 "_SRS..h." */ - 0x05,0x54,0x4D,0x50,0x5F,0x70,0x54,0x4D, /* 00001148 ".TMP_pTM" */ - 0x50,0x5F,0x50,0x52,0x51,0x30,0x5B,0x82, /* 00001150 "P_PRQ0[." */ - 0x4E,0x0B,0x4C,0x4E,0x4B,0x42,0x08,0x5F, /* 00001158 "N.LNKB._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 00001160 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x08, /* 00001168 "._UID..." */ - 0x5F,0x50,0x52,0x53,0x11,0x16,0x0A,0x13, /* 00001170 "_PRS...." */ - 0x89,0x0E,0x00,0x09,0x03,0x05,0x00,0x00, /* 00001178 "........" */ - 0x00,0x0A,0x00,0x00,0x00,0x0B,0x00,0x00, /* 00001180 "........" */ - 0x00,0x79,0x00,0x14,0x1A,0x5F,0x53,0x54, /* 00001188 ".y..._ST" */ - 0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D, /* 00001190 "A.p..`.." */ - 0x7B,0x0A,0x80,0x50,0x52,0x51,0x31,0x61, /* 00001198 "{..PRQ1a" */ - 0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,0x11, /* 000011A0 "p..`.`.." */ - 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x52, /* 000011A8 "_DIS.}PR" */ - 0x51,0x31,0x0A,0x80,0x50,0x52,0x51,0x31, /* 000011B0 "Q1..PRQ1" */ - 0x14,0x45,0x04,0x5F,0x43,0x52,0x53,0x00, /* 000011B8 ".E._CRS." */ - 0x08,0x50,0x52,0x52,0x30,0x11,0x0E,0x0A, /* 000011C0 ".PRR0..." */ - 0x0B,0x89,0x06,0x00,0x09,0x01,0x01,0x00, /* 000011C8 "........" */ - 0x00,0x00,0x79,0x00,0x8A,0x50,0x52,0x52, /* 000011D0 "..y..PRR" */ - 0x30,0x0A,0x05,0x54,0x4D,0x50,0x5F,0x70, /* 000011D8 "0..TMP_p" */ - 0x50,0x52,0x51,0x31,0x60,0xA0,0x0B,0x95, /* 000011E0 "PRQ1`..." */ - 0x60,0x0A,0x80,0x70,0x60,0x54,0x4D,0x50, /* 000011E8 "`..p`TMP" */ - 0x5F,0xA1,0x07,0x70,0x00,0x54,0x4D,0x50, /* 000011F0 "_..p.TMP" */ - 0x5F,0xA4,0x50,0x52,0x52,0x30,0x14,0x17, /* 000011F8 "_.PRR0.." */ - 0x5F,0x53,0x52,0x53,0x01,0x8A,0x68,0x0A, /* 00001200 "_SRS..h." */ - 0x05,0x54,0x4D,0x50,0x5F,0x70,0x54,0x4D, /* 00001208 ".TMP_pTM" */ - 0x50,0x5F,0x50,0x52,0x51,0x31,0x5B,0x82, /* 00001210 "P_PRQ1[." */ - 0x4E,0x0B,0x4C,0x4E,0x4B,0x43,0x08,0x5F, /* 00001218 "N.LNKC._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 00001220 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x0A,0x03,0x08, /* 00001228 "._UID..." */ - 0x5F,0x50,0x52,0x53,0x11,0x16,0x0A,0x13, /* 00001230 "_PRS...." */ - 0x89,0x0E,0x00,0x09,0x03,0x05,0x00,0x00, /* 00001238 "........" */ - 0x00,0x0A,0x00,0x00,0x00,0x0B,0x00,0x00, /* 00001240 "........" */ - 0x00,0x79,0x00,0x14,0x1A,0x5F,0x53,0x54, /* 00001248 ".y..._ST" */ - 0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D, /* 00001250 "A.p..`.." */ - 0x7B,0x0A,0x80,0x50,0x52,0x51,0x32,0x61, /* 00001258 "{..PRQ2a" */ - 0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,0x11, /* 00001260 "p..`.`.." */ - 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x52, /* 00001268 "_DIS.}PR" */ - 0x51,0x32,0x0A,0x80,0x50,0x52,0x51,0x32, /* 00001270 "Q2..PRQ2" */ - 0x14,0x45,0x04,0x5F,0x43,0x52,0x53,0x00, /* 00001278 ".E._CRS." */ - 0x08,0x50,0x52,0x52,0x30,0x11,0x0E,0x0A, /* 00001280 ".PRR0..." */ - 0x0B,0x89,0x06,0x00,0x09,0x01,0x01,0x00, /* 00001288 "........" */ - 0x00,0x00,0x79,0x00,0x8A,0x50,0x52,0x52, /* 00001290 "..y..PRR" */ - 0x30,0x0A,0x05,0x54,0x4D,0x50,0x5F,0x70, /* 00001298 "0..TMP_p" */ - 0x50,0x52,0x51,0x32,0x60,0xA0,0x0B,0x95, /* 000012A0 "PRQ2`..." */ - 0x60,0x0A,0x80,0x70,0x60,0x54,0x4D,0x50, /* 000012A8 "`..p`TMP" */ - 0x5F,0xA1,0x07,0x70,0x00,0x54,0x4D,0x50, /* 000012B0 "_..p.TMP" */ - 0x5F,0xA4,0x50,0x52,0x52,0x30,0x14,0x17, /* 000012B8 "_.PRR0.." */ - 0x5F,0x53,0x52,0x53,0x01,0x8A,0x68,0x0A, /* 000012C0 "_SRS..h." */ - 0x05,0x54,0x4D,0x50,0x5F,0x70,0x54,0x4D, /* 000012C8 ".TMP_pTM" */ - 0x50,0x5F,0x50,0x52,0x51,0x32,0x5B,0x82, /* 000012D0 "P_PRQ2[." */ - 0x4E,0x0B,0x4C,0x4E,0x4B,0x44,0x08,0x5F, /* 000012D8 "N.LNKD._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 000012E0 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,0x08, /* 000012E8 "._UID..." */ - 0x5F,0x50,0x52,0x53,0x11,0x16,0x0A,0x13, /* 000012F0 "_PRS...." */ - 0x89,0x0E,0x00,0x09,0x03,0x05,0x00,0x00, /* 000012F8 "........" */ - 0x00,0x0A,0x00,0x00,0x00,0x0B,0x00,0x00, /* 00001300 "........" */ - 0x00,0x79,0x00,0x14,0x1A,0x5F,0x53,0x54, /* 00001308 ".y..._ST" */ - 0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D, /* 00001310 "A.p..`.." */ - 0x7B,0x0A,0x80,0x50,0x52,0x51,0x33,0x61, /* 00001318 "{..PRQ3a" */ - 0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,0x11, /* 00001320 "p..`.`.." */ - 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x52, /* 00001328 "_DIS.}PR" */ - 0x51,0x33,0x0A,0x80,0x50,0x52,0x51,0x33, /* 00001330 "Q3..PRQ3" */ - 0x14,0x45,0x04,0x5F,0x43,0x52,0x53,0x00, /* 00001338 ".E._CRS." */ - 0x08,0x50,0x52,0x52,0x30,0x11,0x0E,0x0A, /* 00001340 ".PRR0..." */ - 0x0B,0x89,0x06,0x00,0x09,0x01,0x01,0x00, /* 00001348 "........" */ - 0x00,0x00,0x79,0x00,0x8A,0x50,0x52,0x52, /* 00001350 "..y..PRR" */ - 0x30,0x0A,0x05,0x54,0x4D,0x50,0x5F,0x70, /* 00001358 "0..TMP_p" */ - 0x50,0x52,0x51,0x33,0x60,0xA0,0x0B,0x95, /* 00001360 "PRQ3`..." */ - 0x60,0x0A,0x80,0x70,0x60,0x54,0x4D,0x50, /* 00001368 "`..p`TMP" */ - 0x5F,0xA1,0x07,0x70,0x00,0x54,0x4D,0x50, /* 00001370 "_..p.TMP" */ - 0x5F,0xA4,0x50,0x52,0x52,0x30,0x14,0x17, /* 00001378 "_.PRR0.." */ - 0x5F,0x53,0x52,0x53,0x01,0x8A,0x68,0x0A, /* 00001380 "_SRS..h." */ - 0x05,0x54,0x4D,0x50,0x5F,0x70,0x54,0x4D, /* 00001388 ".TMP_pTM" */ - 0x50,0x5F,0x50,0x52,0x51,0x33,0x5B,0x82, /* 00001390 "P_PRQ3[." */ - 0x4E,0x09,0x4C,0x4E,0x4B,0x53,0x08,0x5F, /* 00001398 "N.LNKS._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 000013A0 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x0A,0x05,0x08, /* 000013A8 "._UID..." */ - 0x5F,0x50,0x52,0x53,0x11,0x0E,0x0A,0x0B, /* 000013B0 "_PRS...." */ - 0x89,0x06,0x00,0x09,0x01,0x09,0x00,0x00, /* 000013B8 "........" */ - 0x00,0x79,0x00,0x14,0x1A,0x5F,0x53,0x54, /* 000013C0 ".y..._ST" */ - 0x41,0x00,0x70,0x0A,0x0B,0x60,0xA0,0x0D, /* 000013C8 "A.p..`.." */ - 0x7B,0x0A,0x80,0x50,0x52,0x51,0x30,0x61, /* 000013D0 "{..PRQ0a" */ - 0x70,0x0A,0x09,0x60,0xA4,0x60,0x14,0x11, /* 000013D8 "p..`.`.." */ - 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x52, /* 000013E0 "_DIS.}PR" */ - 0x51,0x30,0x0A,0x80,0x50,0x52,0x51,0x30, /* 000013E8 "Q0..PRQ0" */ - 0x14,0x45,0x04,0x5F,0x43,0x52,0x53,0x00, /* 000013F0 ".E._CRS." */ - 0x08,0x50,0x52,0x52,0x30,0x11,0x0E,0x0A, /* 000013F8 ".PRR0..." */ - 0x0B,0x89,0x06,0x00,0x09,0x01,0x09,0x00, /* 00001400 "........" */ - 0x00,0x00,0x79,0x00,0x8A,0x50,0x52,0x52, /* 00001408 "..y..PRR" */ - 0x30,0x0A,0x05,0x54,0x4D,0x50,0x5F,0x70, /* 00001410 "0..TMP_p" */ - 0x50,0x52,0x51,0x30,0x60,0xA0,0x0B,0x95, /* 00001418 "PRQ0`..." */ - 0x60,0x0A,0x80,0x70,0x60,0x54,0x4D,0x50, /* 00001420 "`..p`TMP" */ - 0x5F,0xA1,0x07,0x70,0x00,0x54,0x4D,0x50, /* 00001428 "_..p.TMP" */ - 0x5F,0xA4,0x50,0x52,0x52,0x30,0x08,0x5F, /* 00001430 "_.PRR0._" */ - 0x53,0x33,0x5F,0x12,0x06,0x04,0x01,0x01, /* 00001438 "S3_....." */ - 0x00,0x00,0x08,0x5F,0x53,0x34,0x5F,0x12, /* 00001440 "..._S4_." */ - 0x06,0x04,0x00,0x00,0x00,0x00,0x08,0x5F, /* 00001448 "......._" */ - 0x53,0x35,0x5F,0x12,0x06,0x04,0x00,0x00, /* 00001450 "S5_....." */ - 0x00,0x00,0x10,0x49,0x0E,0x5F,0x53,0x42, /* 00001458 "...I._SB" */ - 0x5F,0x14,0x35,0x43,0x50,0x4D,0x41,0x01, /* 00001460 "_.5CPMA." */ - 0x70,0x83,0x88,0x43,0x50,0x4F,0x4E,0x68, /* 00001468 "p..CPONh" */ - 0x00,0x60,0x70,0x11,0x0B,0x0A,0x08,0x00, /* 00001470 ".`p....." */ - 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x61, /* 00001478 ".......a" */ - 0x70,0x68,0x88,0x61,0x0A,0x02,0x00,0x70, /* 00001480 "ph.a...p" */ - 0x68,0x88,0x61,0x0A,0x03,0x00,0x70,0x60, /* 00001488 "h.a...p`" */ - 0x88,0x61,0x0A,0x04,0x00,0xA4,0x61,0x14, /* 00001490 ".a....a." */ - 0x1A,0x43,0x50,0x53,0x54,0x01,0x70,0x83, /* 00001498 ".CPST.p." */ - 0x88,0x43,0x50,0x4F,0x4E,0x68,0x00,0x60, /* 000014A0 ".CPONh.`" */ - 0xA0,0x05,0x60,0xA4,0x0A,0x0F,0xA1,0x03, /* 000014A8 "..`....." */ - 0xA4,0x00,0x14,0x0A,0x43,0x50,0x45,0x4A, /* 000014B0 "....CPEJ" */ - 0x02,0x5B,0x22,0x0A,0xC8,0x5B,0x80,0x50, /* 000014B8 ".["..[.P" */ - 0x52,0x53,0x54,0x01,0x0B,0x00,0xAF,0x0A, /* 000014C0 "RST....." */ - 0x20,0x5B,0x81,0x0C,0x50,0x52,0x53,0x54, /* 000014C8 " [..PRST" */ - 0x01,0x50,0x52,0x53,0x5F,0x40,0x10,0x14, /* 000014D0 ".PRS_@.." */ - 0x4C,0x06,0x50,0x52,0x53,0x43,0x00,0x70, /* 000014D8 "L.PRSC.p" */ - 0x50,0x52,0x53,0x5F,0x65,0x70,0x00,0x62, /* 000014E0 "PRS_ep.b" */ - 0x70,0x00,0x60,0xA2,0x46,0x05,0x95,0x60, /* 000014E8 "p.`.F..`" */ - 0x87,0x43,0x50,0x4F,0x4E,0x70,0x83,0x88, /* 000014F0 ".CPONp.." */ - 0x43,0x50,0x4F,0x4E,0x60,0x00,0x61,0xA0, /* 000014F8 "CPON`.a." */ - 0x0A,0x7B,0x60,0x0A,0x07,0x00,0x7A,0x62, /* 00001500 ".{`...zb" */ - 0x01,0x62,0xA1,0x0C,0x70,0x83,0x88,0x65, /* 00001508 ".b..p..e" */ - 0x7A,0x60,0x0A,0x03,0x00,0x00,0x62,0x70, /* 00001510 "z`....bp" */ - 0x7B,0x62,0x01,0x00,0x63,0xA0,0x22,0x92, /* 00001518 "{b..c."." */ - 0x93,0x61,0x63,0x70,0x63,0x88,0x43,0x50, /* 00001520 ".acpc.CP" */ - 0x4F,0x4E,0x60,0x00,0xA0,0x0A,0x93,0x63, /* 00001528 "ON`....c" */ - 0x01,0x4E,0x54,0x46,0x59,0x60,0x01,0xA1, /* 00001530 ".NTFY`.." */ - 0x08,0x4E,0x54,0x46,0x59,0x60,0x0A,0x03, /* 00001538 ".NTFY`.." */ - 0x75,0x60,0xA4,0x01,0x10,0x42,0xA7,0x5F, /* 00001540 "u`...B._" */ - 0x47,0x50,0x45,0x08,0x5F,0x48,0x49,0x44, /* 00001548 "GPE._HID" */ - 0x0D,0x41,0x43,0x50,0x49,0x30,0x30,0x30, /* 00001550 ".ACPI000" */ - 0x36,0x00,0x14,0x08,0x5F,0x4C,0x30,0x30, /* 00001558 "6..._L00" */ - 0x00,0xA4,0x01,0x14,0x4C,0x9C,0x5F,0x4C, /* 00001560 "....L._L" */ - 0x30,0x31,0x00,0xA0,0x25,0x7B,0x5C,0x2F, /* 00001568 "01..%{\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001570 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x55,0x0A,0x02,0x00, /* 00001578 "0PCIU..." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001580 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x5F,0x5F, /* 00001588 "PCI0S1__" */ - 0x01,0xA0,0x26,0x7B,0x5C,0x2F,0x03,0x5F, /* 00001590 "..&{\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 00001598 "SB_PCI0P" */ - 0x43,0x49,0x44,0x0A,0x02,0x00,0x86,0x5C, /* 000015A0 "CID....\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 000015A8 "/._SB_PC" */ - 0x49,0x30,0x53,0x31,0x5F,0x5F,0x0A,0x03, /* 000015B0 "I0S1__.." */ - 0xA0,0x25,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 000015B8 ".%{\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 000015C0 "B_PCI0PC" */ - 0x49,0x55,0x0A,0x04,0x00,0x86,0x5C,0x2F, /* 000015C8 "IU....\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 000015D0 "._SB_PCI" */ - 0x30,0x53,0x32,0x5F,0x5F,0x01,0xA0,0x26, /* 000015D8 "0S2__..&" */ - 0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000015E0 "{\/._SB_" */ - 0x50,0x43,0x49,0x30,0x50,0x43,0x49,0x44, /* 000015E8 "PCI0PCID" */ - 0x0A,0x04,0x00,0x86,0x5C,0x2F,0x03,0x5F, /* 000015F0 "....\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 000015F8 "SB_PCI0S" */ - 0x32,0x5F,0x5F,0x0A,0x03,0xA0,0x25,0x7B, /* 00001600 "2__...%{" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001608 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x55,0x0A, /* 00001610 "CI0PCIU." */ - 0x08,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001618 "...\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x33, /* 00001620 "B_PCI0S3" */ - 0x5F,0x5F,0x01,0xA0,0x26,0x7B,0x5C,0x2F, /* 00001628 "__..&{\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001630 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x44,0x0A,0x08,0x00, /* 00001638 "0PCID..." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001640 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x33,0x5F,0x5F, /* 00001648 "PCI0S3__" */ - 0x0A,0x03,0xA0,0x25,0x7B,0x5C,0x2F,0x03, /* 00001650 "...%{\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001658 "_SB_PCI0" */ - 0x50,0x43,0x49,0x55,0x0A,0x10,0x00,0x86, /* 00001660 "PCIU...." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001668 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x34,0x5F,0x5F,0x01, /* 00001670 "CI0S4__." */ - 0xA0,0x26,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 00001678 ".&{\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 00001680 "B_PCI0PC" */ - 0x49,0x44,0x0A,0x10,0x00,0x86,0x5C,0x2F, /* 00001688 "ID....\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001690 "._SB_PCI" */ - 0x30,0x53,0x34,0x5F,0x5F,0x0A,0x03,0xA0, /* 00001698 "0S4__..." */ - 0x25,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 000016A0 "%{\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 000016A8 "_PCI0PCI" */ - 0x55,0x0A,0x20,0x00,0x86,0x5C,0x2F,0x03, /* 000016B0 "U. ..\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 000016B8 "_SB_PCI0" */ - 0x53,0x35,0x5F,0x5F,0x01,0xA0,0x26,0x7B, /* 000016C0 "S5__..&{" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 000016C8 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x44,0x0A, /* 000016D0 "CI0PCID." */ - 0x20,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 000016D8 " ..\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x35, /* 000016E0 "B_PCI0S5" */ - 0x5F,0x5F,0x0A,0x03,0xA0,0x25,0x7B,0x5C, /* 000016E8 "__...%{\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 000016F0 "/._SB_PC" */ - 0x49,0x30,0x50,0x43,0x49,0x55,0x0A,0x40, /* 000016F8 "I0PCIU.@" */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001700 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x36,0x5F, /* 00001708 "_PCI0S6_" */ - 0x5F,0x01,0xA0,0x26,0x7B,0x5C,0x2F,0x03, /* 00001710 "_..&{\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001718 "_SB_PCI0" */ - 0x50,0x43,0x49,0x44,0x0A,0x40,0x00,0x86, /* 00001720 "PCID.@.." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001728 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x36,0x5F,0x5F,0x0A, /* 00001730 "CI0S6__." */ - 0x03,0xA0,0x25,0x7B,0x5C,0x2F,0x03,0x5F, /* 00001738 "..%{\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 00001740 "SB_PCI0P" */ - 0x43,0x49,0x55,0x0A,0x80,0x00,0x86,0x5C, /* 00001748 "CIU....\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001750 "/._SB_PC" */ - 0x49,0x30,0x53,0x37,0x5F,0x5F,0x01,0xA0, /* 00001758 "I0S7__.." */ - 0x26,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001760 "&{\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 00001768 "_PCI0PCI" */ - 0x44,0x0A,0x80,0x00,0x86,0x5C,0x2F,0x03, /* 00001770 "D....\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001778 "_SB_PCI0" */ - 0x53,0x37,0x5F,0x5F,0x0A,0x03,0xA0,0x26, /* 00001780 "S7__...&" */ - 0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001788 "{\/._SB_" */ - 0x50,0x43,0x49,0x30,0x50,0x43,0x49,0x55, /* 00001790 "PCI0PCIU" */ - 0x0B,0x00,0x01,0x00,0x86,0x5C,0x2F,0x03, /* 00001798 ".....\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 000017A0 "_SB_PCI0" */ - 0x53,0x38,0x5F,0x5F,0x01,0xA0,0x27,0x7B, /* 000017A8 "S8__..'{" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 000017B0 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x44,0x0B, /* 000017B8 "CI0PCID." */ - 0x00,0x01,0x00,0x86,0x5C,0x2F,0x03,0x5F, /* 000017C0 "....\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 000017C8 "SB_PCI0S" */ - 0x38,0x5F,0x5F,0x0A,0x03,0xA0,0x26,0x7B, /* 000017D0 "8__...&{" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 000017D8 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x55,0x0B, /* 000017E0 "CI0PCIU." */ - 0x00,0x02,0x00,0x86,0x5C,0x2F,0x03,0x5F, /* 000017E8 "....\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 000017F0 "SB_PCI0S" */ - 0x39,0x5F,0x5F,0x01,0xA0,0x27,0x7B,0x5C, /* 000017F8 "9__..'{\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001800 "/._SB_PC" */ - 0x49,0x30,0x50,0x43,0x49,0x44,0x0B,0x00, /* 00001808 "I0PCID.." */ - 0x02,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001810 "...\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x39, /* 00001818 "B_PCI0S9" */ - 0x5F,0x5F,0x0A,0x03,0xA0,0x26,0x7B,0x5C, /* 00001820 "__...&{\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001828 "/._SB_PC" */ - 0x49,0x30,0x50,0x43,0x49,0x55,0x0B,0x00, /* 00001830 "I0PCIU.." */ - 0x04,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001838 "...\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x31, /* 00001840 "B_PCI0S1" */ - 0x30,0x5F,0x01,0xA0,0x27,0x7B,0x5C,0x2F, /* 00001848 "0_..'{\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001850 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x44,0x0B,0x00,0x04, /* 00001858 "0PCID..." */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001860 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x30, /* 00001868 "_PCI0S10" */ - 0x5F,0x0A,0x03,0xA0,0x26,0x7B,0x5C,0x2F, /* 00001870 "_...&{\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001878 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x55,0x0B,0x00,0x08, /* 00001880 "0PCIU..." */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001888 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x31, /* 00001890 "_PCI0S11" */ - 0x5F,0x01,0xA0,0x27,0x7B,0x5C,0x2F,0x03, /* 00001898 "_..'{\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 000018A0 "_SB_PCI0" */ - 0x50,0x43,0x49,0x44,0x0B,0x00,0x08,0x00, /* 000018A8 "PCID...." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000018B0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x31,0x5F, /* 000018B8 "PCI0S11_" */ - 0x0A,0x03,0xA0,0x26,0x7B,0x5C,0x2F,0x03, /* 000018C0 "...&{\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 000018C8 "_SB_PCI0" */ - 0x50,0x43,0x49,0x55,0x0B,0x00,0x10,0x00, /* 000018D0 "PCIU...." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000018D8 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x32,0x5F, /* 000018E0 "PCI0S12_" */ - 0x01,0xA0,0x27,0x7B,0x5C,0x2F,0x03,0x5F, /* 000018E8 "..'{\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 000018F0 "SB_PCI0P" */ - 0x43,0x49,0x44,0x0B,0x00,0x10,0x00,0x86, /* 000018F8 "CID....." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001900 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x31,0x32,0x5F,0x0A, /* 00001908 "CI0S12_." */ - 0x03,0xA0,0x26,0x7B,0x5C,0x2F,0x03,0x5F, /* 00001910 "..&{\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 00001918 "SB_PCI0P" */ - 0x43,0x49,0x55,0x0B,0x00,0x20,0x00,0x86, /* 00001920 "CIU.. .." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001928 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x31,0x33,0x5F,0x01, /* 00001930 "CI0S13_." */ - 0xA0,0x27,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 00001938 ".'{\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 00001940 "B_PCI0PC" */ - 0x49,0x44,0x0B,0x00,0x20,0x00,0x86,0x5C, /* 00001948 "ID.. ..\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001950 "/._SB_PC" */ - 0x49,0x30,0x53,0x31,0x33,0x5F,0x0A,0x03, /* 00001958 "I0S13_.." */ - 0xA0,0x26,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 00001960 ".&{\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 00001968 "B_PCI0PC" */ - 0x49,0x55,0x0B,0x00,0x40,0x00,0x86,0x5C, /* 00001970 "IU..@..\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001978 "/._SB_PC" */ - 0x49,0x30,0x53,0x31,0x34,0x5F,0x01,0xA0, /* 00001980 "I0S14_.." */ - 0x27,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001988 "'{\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 00001990 "_PCI0PCI" */ - 0x44,0x0B,0x00,0x40,0x00,0x86,0x5C,0x2F, /* 00001998 "D..@..\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 000019A0 "._SB_PCI" */ - 0x30,0x53,0x31,0x34,0x5F,0x0A,0x03,0xA0, /* 000019A8 "0S14_..." */ - 0x26,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 000019B0 "&{\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 000019B8 "_PCI0PCI" */ - 0x55,0x0B,0x00,0x80,0x00,0x86,0x5C,0x2F, /* 000019C0 "U.....\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 000019C8 "._SB_PCI" */ - 0x30,0x53,0x31,0x35,0x5F,0x01,0xA0,0x27, /* 000019D0 "0S15_..'" */ - 0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000019D8 "{\/._SB_" */ - 0x50,0x43,0x49,0x30,0x50,0x43,0x49,0x44, /* 000019E0 "PCI0PCID" */ - 0x0B,0x00,0x80,0x00,0x86,0x5C,0x2F,0x03, /* 000019E8 ".....\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 000019F0 "_SB_PCI0" */ - 0x53,0x31,0x35,0x5F,0x0A,0x03,0xA0,0x28, /* 000019F8 "S15_...(" */ - 0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001A00 "{\/._SB_" */ - 0x50,0x43,0x49,0x30,0x50,0x43,0x49,0x55, /* 00001A08 "PCI0PCIU" */ - 0x0C,0x00,0x00,0x01,0x00,0x00,0x86,0x5C, /* 00001A10 ".......\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001A18 "/._SB_PC" */ - 0x49,0x30,0x53,0x31,0x36,0x5F,0x01,0xA0, /* 00001A20 "I0S16_.." */ - 0x29,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001A28 "){\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 00001A30 "_PCI0PCI" */ - 0x44,0x0C,0x00,0x00,0x01,0x00,0x00,0x86, /* 00001A38 "D......." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001A40 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x31,0x36,0x5F,0x0A, /* 00001A48 "CI0S16_." */ - 0x03,0xA0,0x28,0x7B,0x5C,0x2F,0x03,0x5F, /* 00001A50 "..({\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 00001A58 "SB_PCI0P" */ - 0x43,0x49,0x55,0x0C,0x00,0x00,0x02,0x00, /* 00001A60 "CIU....." */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001A68 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x31,0x37, /* 00001A70 "_PCI0S17" */ - 0x5F,0x01,0xA0,0x29,0x7B,0x5C,0x2F,0x03, /* 00001A78 "_..){\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001A80 "_SB_PCI0" */ - 0x50,0x43,0x49,0x44,0x0C,0x00,0x00,0x02, /* 00001A88 "PCID...." */ - 0x00,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001A90 "...\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x31, /* 00001A98 "B_PCI0S1" */ - 0x37,0x5F,0x0A,0x03,0xA0,0x28,0x7B,0x5C, /* 00001AA0 "7_...({\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001AA8 "/._SB_PC" */ - 0x49,0x30,0x50,0x43,0x49,0x55,0x0C,0x00, /* 00001AB0 "I0PCIU.." */ - 0x00,0x04,0x00,0x00,0x86,0x5C,0x2F,0x03, /* 00001AB8 ".....\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001AC0 "_SB_PCI0" */ - 0x53,0x31,0x38,0x5F,0x01,0xA0,0x29,0x7B, /* 00001AC8 "S18_..){" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001AD0 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x44,0x0C, /* 00001AD8 "CI0PCID." */ - 0x00,0x00,0x04,0x00,0x00,0x86,0x5C,0x2F, /* 00001AE0 "......\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001AE8 "._SB_PCI" */ - 0x30,0x53,0x31,0x38,0x5F,0x0A,0x03,0xA0, /* 00001AF0 "0S18_..." */ - 0x28,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001AF8 "({\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 00001B00 "_PCI0PCI" */ - 0x55,0x0C,0x00,0x00,0x08,0x00,0x00,0x86, /* 00001B08 "U......." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001B10 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x31,0x39,0x5F,0x01, /* 00001B18 "CI0S19_." */ - 0xA0,0x29,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 00001B20 ".){\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 00001B28 "B_PCI0PC" */ - 0x49,0x44,0x0C,0x00,0x00,0x08,0x00,0x00, /* 00001B30 "ID......" */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001B38 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x31,0x39,0x5F, /* 00001B40 "PCI0S19_" */ - 0x0A,0x03,0xA0,0x28,0x7B,0x5C,0x2F,0x03, /* 00001B48 "...({\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001B50 "_SB_PCI0" */ - 0x50,0x43,0x49,0x55,0x0C,0x00,0x00,0x10, /* 00001B58 "PCIU...." */ - 0x00,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001B60 "...\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x32, /* 00001B68 "B_PCI0S2" */ - 0x30,0x5F,0x01,0xA0,0x29,0x7B,0x5C,0x2F, /* 00001B70 "0_..){\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001B78 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x44,0x0C,0x00,0x00, /* 00001B80 "0PCID..." */ - 0x10,0x00,0x00,0x86,0x5C,0x2F,0x03,0x5F, /* 00001B88 "....\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 00001B90 "SB_PCI0S" */ - 0x32,0x30,0x5F,0x0A,0x03,0xA0,0x28,0x7B, /* 00001B98 "20_...({" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001BA0 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x55,0x0C, /* 00001BA8 "CI0PCIU." */ - 0x00,0x00,0x20,0x00,0x00,0x86,0x5C,0x2F, /* 00001BB0 ".. ...\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001BB8 "._SB_PCI" */ - 0x30,0x53,0x32,0x31,0x5F,0x01,0xA0,0x29, /* 00001BC0 "0S21_..)" */ - 0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001BC8 "{\/._SB_" */ - 0x50,0x43,0x49,0x30,0x50,0x43,0x49,0x44, /* 00001BD0 "PCI0PCID" */ - 0x0C,0x00,0x00,0x20,0x00,0x00,0x86,0x5C, /* 00001BD8 "... ...\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001BE0 "/._SB_PC" */ - 0x49,0x30,0x53,0x32,0x31,0x5F,0x0A,0x03, /* 00001BE8 "I0S21_.." */ - 0xA0,0x28,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 00001BF0 ".({\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 00001BF8 "B_PCI0PC" */ - 0x49,0x55,0x0C,0x00,0x00,0x40,0x00,0x00, /* 00001C00 "IU...@.." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001C08 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x32,0x32,0x5F, /* 00001C10 "PCI0S22_" */ - 0x01,0xA0,0x29,0x7B,0x5C,0x2F,0x03,0x5F, /* 00001C18 "..){\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 00001C20 "SB_PCI0P" */ - 0x43,0x49,0x44,0x0C,0x00,0x00,0x40,0x00, /* 00001C28 "CID...@." */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001C30 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x32,0x32, /* 00001C38 "_PCI0S22" */ - 0x5F,0x0A,0x03,0xA0,0x28,0x7B,0x5C,0x2F, /* 00001C40 "_...({\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001C48 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x55,0x0C,0x00,0x00, /* 00001C50 "0PCIU..." */ - 0x80,0x00,0x00,0x86,0x5C,0x2F,0x03,0x5F, /* 00001C58 "....\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 00001C60 "SB_PCI0S" */ - 0x32,0x33,0x5F,0x01,0xA0,0x29,0x7B,0x5C, /* 00001C68 "23_..){\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001C70 "/._SB_PC" */ - 0x49,0x30,0x50,0x43,0x49,0x44,0x0C,0x00, /* 00001C78 "I0PCID.." */ - 0x00,0x80,0x00,0x00,0x86,0x5C,0x2F,0x03, /* 00001C80 ".....\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001C88 "_SB_PCI0" */ - 0x53,0x32,0x33,0x5F,0x0A,0x03,0xA0,0x28, /* 00001C90 "S23_...(" */ - 0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001C98 "{\/._SB_" */ - 0x50,0x43,0x49,0x30,0x50,0x43,0x49,0x55, /* 00001CA0 "PCI0PCIU" */ - 0x0C,0x00,0x00,0x00,0x01,0x00,0x86,0x5C, /* 00001CA8 ".......\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001CB0 "/._SB_PC" */ - 0x49,0x30,0x53,0x32,0x34,0x5F,0x01,0xA0, /* 00001CB8 "I0S24_.." */ - 0x29,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001CC0 "){\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 00001CC8 "_PCI0PCI" */ - 0x44,0x0C,0x00,0x00,0x00,0x01,0x00,0x86, /* 00001CD0 "D......." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001CD8 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x32,0x34,0x5F,0x0A, /* 00001CE0 "CI0S24_." */ - 0x03,0xA0,0x28,0x7B,0x5C,0x2F,0x03,0x5F, /* 00001CE8 "..({\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 00001CF0 "SB_PCI0P" */ - 0x43,0x49,0x55,0x0C,0x00,0x00,0x00,0x02, /* 00001CF8 "CIU....." */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001D00 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x32,0x35, /* 00001D08 "_PCI0S25" */ - 0x5F,0x01,0xA0,0x29,0x7B,0x5C,0x2F,0x03, /* 00001D10 "_..){\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001D18 "_SB_PCI0" */ - 0x50,0x43,0x49,0x44,0x0C,0x00,0x00,0x00, /* 00001D20 "PCID...." */ - 0x02,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001D28 "...\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x32, /* 00001D30 "B_PCI0S2" */ - 0x35,0x5F,0x0A,0x03,0xA0,0x28,0x7B,0x5C, /* 00001D38 "5_...({\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001D40 "/._SB_PC" */ - 0x49,0x30,0x50,0x43,0x49,0x55,0x0C,0x00, /* 00001D48 "I0PCIU.." */ - 0x00,0x00,0x04,0x00,0x86,0x5C,0x2F,0x03, /* 00001D50 ".....\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001D58 "_SB_PCI0" */ - 0x53,0x32,0x36,0x5F,0x01,0xA0,0x29,0x7B, /* 00001D60 "S26_..){" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001D68 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x44,0x0C, /* 00001D70 "CI0PCID." */ - 0x00,0x00,0x00,0x04,0x00,0x86,0x5C,0x2F, /* 00001D78 "......\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001D80 "._SB_PCI" */ - 0x30,0x53,0x32,0x36,0x5F,0x0A,0x03,0xA0, /* 00001D88 "0S26_..." */ - 0x28,0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001D90 "({\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x50,0x43,0x49, /* 00001D98 "_PCI0PCI" */ - 0x55,0x0C,0x00,0x00,0x00,0x08,0x00,0x86, /* 00001DA0 "U......." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001DA8 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x32,0x37,0x5F,0x01, /* 00001DB0 "CI0S27_." */ - 0xA0,0x29,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 00001DB8 ".){\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 00001DC0 "B_PCI0PC" */ - 0x49,0x44,0x0C,0x00,0x00,0x00,0x08,0x00, /* 00001DC8 "ID......" */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001DD0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x32,0x37,0x5F, /* 00001DD8 "PCI0S27_" */ - 0x0A,0x03,0xA0,0x28,0x7B,0x5C,0x2F,0x03, /* 00001DE0 "...({\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001DE8 "_SB_PCI0" */ - 0x50,0x43,0x49,0x55,0x0C,0x00,0x00,0x00, /* 00001DF0 "PCIU...." */ - 0x10,0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53, /* 00001DF8 "...\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x53,0x32, /* 00001E00 "B_PCI0S2" */ - 0x38,0x5F,0x01,0xA0,0x29,0x7B,0x5C,0x2F, /* 00001E08 "8_..){\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001E10 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x44,0x0C,0x00,0x00, /* 00001E18 "0PCID..." */ - 0x00,0x10,0x00,0x86,0x5C,0x2F,0x03,0x5F, /* 00001E20 "....\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 00001E28 "SB_PCI0S" */ - 0x32,0x38,0x5F,0x0A,0x03,0xA0,0x28,0x7B, /* 00001E30 "28_...({" */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001E38 "\/._SB_P" */ - 0x43,0x49,0x30,0x50,0x43,0x49,0x55,0x0C, /* 00001E40 "CI0PCIU." */ - 0x00,0x00,0x00,0x20,0x00,0x86,0x5C,0x2F, /* 00001E48 "... ..\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001E50 "._SB_PCI" */ - 0x30,0x53,0x32,0x39,0x5F,0x01,0xA0,0x29, /* 00001E58 "0S29_..)" */ - 0x7B,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001E60 "{\/._SB_" */ - 0x50,0x43,0x49,0x30,0x50,0x43,0x49,0x44, /* 00001E68 "PCI0PCID" */ - 0x0C,0x00,0x00,0x00,0x20,0x00,0x86,0x5C, /* 00001E70 ".... ..\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001E78 "/._SB_PC" */ - 0x49,0x30,0x53,0x32,0x39,0x5F,0x0A,0x03, /* 00001E80 "I0S29_.." */ - 0xA0,0x28,0x7B,0x5C,0x2F,0x03,0x5F,0x53, /* 00001E88 ".({\/._S" */ - 0x42,0x5F,0x50,0x43,0x49,0x30,0x50,0x43, /* 00001E90 "B_PCI0PC" */ - 0x49,0x55,0x0C,0x00,0x00,0x00,0x40,0x00, /* 00001E98 "IU....@." */ - 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00001EA0 ".\/._SB_" */ - 0x50,0x43,0x49,0x30,0x53,0x33,0x30,0x5F, /* 00001EA8 "PCI0S30_" */ - 0x01,0xA0,0x29,0x7B,0x5C,0x2F,0x03,0x5F, /* 00001EB0 "..){\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x50, /* 00001EB8 "SB_PCI0P" */ - 0x43,0x49,0x44,0x0C,0x00,0x00,0x00,0x40, /* 00001EC0 "CID....@" */ - 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00001EC8 "..\/._SB" */ - 0x5F,0x50,0x43,0x49,0x30,0x53,0x33,0x30, /* 00001ED0 "_PCI0S30" */ - 0x5F,0x0A,0x03,0xA0,0x28,0x7B,0x5C,0x2F, /* 00001ED8 "_...({\/" */ - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001EE0 "._SB_PCI" */ - 0x30,0x50,0x43,0x49,0x55,0x0C,0x00,0x00, /* 00001EE8 "0PCIU..." */ - 0x00,0x80,0x00,0x86,0x5C,0x2F,0x03,0x5F, /* 00001EF0 "....\/._" */ - 0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x53, /* 00001EF8 "SB_PCI0S" */ - 0x33,0x31,0x5F,0x01,0xA0,0x29,0x7B,0x5C, /* 00001F00 "31_..){\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001F08 "/._SB_PC" */ - 0x49,0x30,0x50,0x43,0x49,0x44,0x0C,0x00, /* 00001F10 "I0PCID.." */ - 0x00,0x00,0x80,0x00,0x86,0x5C,0x2F,0x03, /* 00001F18 ".....\/." */ - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001F20 "_SB_PCI0" */ - 0x53,0x33,0x31,0x5F,0x0A,0x03,0xA4,0x01, /* 00001F28 "S31_...." */ - 0x14,0x11,0x5F,0x4C,0x30,0x32,0x00,0xA4, /* 00001F30 ".._L02.." */ - 0x5C,0x2E,0x5F,0x53,0x42,0x5F,0x50,0x52, /* 00001F38 "\._SB_PR" */ - 0x53,0x43,0x14,0x08,0x5F,0x4C,0x30,0x33, /* 00001F40 "SC.._L03" */ - 0x00,0xA4,0x01,0x14,0x08,0x5F,0x4C,0x30, /* 00001F48 "....._L0" */ - 0x34,0x00,0xA4,0x01,0x14,0x08,0x5F,0x4C, /* 00001F50 "4....._L" */ - 0x30,0x35,0x00,0xA4,0x01,0x14,0x08,0x5F, /* 00001F58 "05....._" */ - 0x4C,0x30,0x36,0x00,0xA4,0x01,0x14,0x08, /* 00001F60 "L06....." */ - 0x5F,0x4C,0x30,0x37,0x00,0xA4,0x01,0x14, /* 00001F68 "_L07...." */ - 0x08,0x5F,0x4C,0x30,0x38,0x00,0xA4,0x01, /* 00001F70 "._L08..." */ - 0x14,0x08,0x5F,0x4C,0x30,0x39,0x00,0xA4, /* 00001F78 ".._L09.." */ - 0x01,0x14,0x08,0x5F,0x4C,0x30,0x41,0x00, /* 00001F80 "..._L0A." */ - 0xA4,0x01,0x14,0x08,0x5F,0x4C,0x30,0x42, /* 00001F88 "...._L0B" */ - 0x00,0xA4,0x01,0x14,0x08,0x5F,0x4C,0x30, /* 00001F90 "....._L0" */ - 0x43,0x00,0xA4,0x01,0x14,0x08,0x5F,0x4C, /* 00001F98 "C....._L" */ - 0x30,0x44,0x00,0xA4,0x01,0x14,0x08,0x5F, /* 00001FA0 "0D....._" */ - 0x4C,0x30,0x45,0x00,0xA4,0x01,0x14,0x08, /* 00001FA8 "L0E....." */ - 0x5F,0x4C,0x30,0x46,0x00,0xA4,0x01, -}; diff --git a/roms/seabios/src/acpi.c b/roms/seabios/src/acpi.c deleted file mode 100644 index 18830dc..0000000 --- a/roms/seabios/src/acpi.c +++ /dev/null @@ -1,694 +0,0 @@ -// Support for generating ACPI tables (on emulators) -// -// Copyright (C) 2008-2010 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "acpi.h" // struct rsdp_descriptor -#include "util.h" // memcpy -#include "pci.h" // pci_find_device -#include "biosvar.h" // GET_EBDA -#include "pci_ids.h" // PCI_VENDOR_ID_INTEL -#include "pci_regs.h" // PCI_INTERRUPT_LINE -#include "paravirt.h" -#include "dev-i440fx.h" // piix4_fadt_init - -/****************************************************/ -/* ACPI tables init */ - -/* Table structure from Linux kernel (the ACPI tables are under the - BSD license) */ - -struct acpi_table_header /* ACPI common table header */ -{ - ACPI_TABLE_HEADER_DEF -} PACKED; - -/* - * ACPI 1.0 Root System Description Table (RSDT) - */ -#define RSDT_SIGNATURE 0x54445352 // RSDT -struct rsdt_descriptor_rev1 -{ - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 table_offset_entry[0]; /* Array of pointers to other */ - /* ACPI tables */ -} PACKED; - -/* - * ACPI 1.0 Firmware ACPI Control Structure (FACS) - */ -#define FACS_SIGNATURE 0x53434146 // FACS -struct facs_descriptor_rev1 -{ - u32 signature; /* ACPI Signature */ - u32 length; /* Length of structure, in bytes */ - u32 hardware_signature; /* Hardware configuration signature */ - u32 firmware_waking_vector; /* ACPI OS waking vector */ - u32 global_lock; /* Global Lock */ - u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ - u32 reserved1 : 31; /* Must be 0 */ - u8 resverved3 [40]; /* Reserved - must be zero */ -} PACKED; - - -/* - * MADT values and structures - */ - -/* Values for MADT PCATCompat */ - -#define DUAL_PIC 0 -#define MULTIPLE_APIC 1 - - -/* Master MADT */ - -#define APIC_SIGNATURE 0x43495041 // APIC -struct multiple_apic_table -{ - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 local_apic_address; /* Physical address of local APIC */ -#if 0 - u32 PCATcompat : 1; /* A one indicates system also has dual 8259s */ - u32 reserved1 : 31; -#else - u32 flags; -#endif -} PACKED; - - -/* Values for Type in APIC sub-headers */ - -#define APIC_PROCESSOR 0 -#define APIC_IO 1 -#define APIC_XRUPT_OVERRIDE 2 -#define APIC_NMI 3 -#define APIC_LOCAL_NMI 4 -#define APIC_ADDRESS_OVERRIDE 5 -#define APIC_IO_SAPIC 6 -#define APIC_LOCAL_SAPIC 7 -#define APIC_XRUPT_SOURCE 8 -#define APIC_RESERVED 9 /* 9 and greater are reserved */ - -/* - * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE) - */ -#define ACPI_SUB_HEADER_DEF /* Common ACPI sub-structure header */\ - u8 type; \ - u8 length; - -/* Sub-structures for MADT */ - -struct madt_processor_apic -{ - ACPI_SUB_HEADER_DEF - u8 processor_id; /* ACPI processor id */ - u8 local_apic_id; /* Processor's local APIC id */ -#if 0 - u32 processor_enabled: 1; /* Processor is usable if set */ - u32 reserved2 : 31; /* Reserved, must be zero */ -#else - u32 flags; -#endif -} PACKED; - -struct madt_io_apic -{ - ACPI_SUB_HEADER_DEF - u8 io_apic_id; /* I/O APIC ID */ - u8 reserved; /* Reserved - must be zero */ - u32 address; /* APIC physical address */ - u32 interrupt; /* Global system interrupt where INTI - * lines start */ -} PACKED; - -/* IRQs 5,9,10,11 */ -#define PCI_ISA_IRQ_MASK 0x0e20 - -struct madt_intsrcovr { - ACPI_SUB_HEADER_DEF - u8 bus; - u8 source; - u32 gsi; - u16 flags; -} PACKED; - -/* - * ACPI 2.0 Generic Address Space definition. - */ -struct acpi_20_generic_address { - u8 address_space_id; - u8 register_bit_width; - u8 register_bit_offset; - u8 reserved; - u64 address; -} PACKED; - -/* - * HPET Description Table - */ -struct acpi_20_hpet { - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 timer_block_id; - struct acpi_20_generic_address addr; - u8 hpet_number; - u16 min_tick; - u8 page_protect; -} PACKED; -#define ACPI_HPET_ADDRESS 0xFED00000UL - -/* - * SRAT (NUMA topology description) table - */ - -#define SRAT_PROCESSOR 0 -#define SRAT_MEMORY 1 - -struct system_resource_affinity_table -{ - ACPI_TABLE_HEADER_DEF - u32 reserved1; - u32 reserved2[2]; -} PACKED; - -struct srat_processor_affinity -{ - ACPI_SUB_HEADER_DEF - u8 proximity_lo; - u8 local_apic_id; - u32 flags; - u8 local_sapic_eid; - u8 proximity_hi[3]; - u32 reserved; -} PACKED; - -struct srat_memory_affinity -{ - ACPI_SUB_HEADER_DEF - u8 proximity[4]; - u16 reserved1; - u32 base_addr_low,base_addr_high; - u32 length_low,length_high; - u32 reserved2; - u32 flags; - u32 reserved3[2]; -} PACKED; - -#include "acpi-dsdt.hex" - -static void -build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) -{ - h->signature = sig; - h->length = cpu_to_le32(len); - h->revision = rev; - memcpy(h->oem_id, CONFIG_APPNAME6, 6); - memcpy(h->oem_table_id, CONFIG_APPNAME4, 4); - memcpy(h->asl_compiler_id, CONFIG_APPNAME4, 4); - memcpy(h->oem_table_id + 4, (void*)&sig, 4); - h->oem_revision = cpu_to_le32(1); - h->asl_compiler_revision = cpu_to_le32(1); - h->checksum -= checksum(h, len); -} - -static const struct pci_device_id fadt_init_tbl[] = { - /* PIIX4 Power Management device (for ACPI) */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - piix4_fadt_init), - - PCI_DEVICE_END -}; - -static void* -build_fadt(int bdf) -{ - struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt)); - struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs)); - void *dsdt = malloc_high(sizeof(AmlCode)); - - if (!fadt || !facs || !dsdt) { - warn_noalloc(); - return NULL; - } - - /* FACS */ - memset(facs, 0, sizeof(*facs)); - facs->signature = FACS_SIGNATURE; - facs->length = cpu_to_le32(sizeof(*facs)); - - /* DSDT */ - memcpy(dsdt, AmlCode, sizeof(AmlCode)); - - /* FADT */ - memset(fadt, 0, sizeof(*fadt)); - fadt->firmware_ctrl = cpu_to_le32((u32)facs); - fadt->dsdt = cpu_to_le32((u32)dsdt); - fadt->model = 1; - fadt->reserved1 = 0; - int pm_sci_int = pci_config_readb(bdf, PCI_INTERRUPT_LINE); - fadt->sci_int = cpu_to_le16(pm_sci_int); - fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD); - fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE); - fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04); - fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08); - fadt->pm1_evt_len = 4; - fadt->pm1_cnt_len = 2; - fadt->pm_tmr_len = 4; - fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported - fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported - pci_init_device(fadt_init_tbl, bdf, fadt); - /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */ - fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6)); - - build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1); - - return fadt; -} - -static void* -build_madt(void) -{ - int madt_size = (sizeof(struct multiple_apic_table) - + sizeof(struct madt_processor_apic) * MaxCountCPUs - + sizeof(struct madt_io_apic) - + sizeof(struct madt_intsrcovr) * 16); - struct multiple_apic_table *madt = malloc_high(madt_size); - if (!madt) { - warn_noalloc(); - return NULL; - } - memset(madt, 0, madt_size); - madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR); - madt->flags = cpu_to_le32(1); - struct madt_processor_apic *apic = (void*)&madt[1]; - int i; - for (i=0; itype = APIC_PROCESSOR; - apic->length = sizeof(*apic); - apic->processor_id = i; - apic->local_apic_id = i; - if (i < CountCPUs) - apic->flags = cpu_to_le32(1); - else - apic->flags = cpu_to_le32(0); - apic++; - } - struct madt_io_apic *io_apic = (void*)apic; - io_apic->type = APIC_IO; - io_apic->length = sizeof(*io_apic); - io_apic->io_apic_id = CountCPUs; - io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR); - io_apic->interrupt = cpu_to_le32(0); - - struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1]; - if (qemu_cfg_irq0_override()) { - memset(intsrcovr, 0, sizeof(*intsrcovr)); - intsrcovr->type = APIC_XRUPT_OVERRIDE; - intsrcovr->length = sizeof(*intsrcovr); - intsrcovr->source = 0; - intsrcovr->gsi = 2; - intsrcovr->flags = 0; /* conforms to bus specifications */ - intsrcovr++; - } - for (i = 1; i < 16; i++) { - if (!(PCI_ISA_IRQ_MASK & (1 << i))) - /* No need for a INT source override structure. */ - continue; - memset(intsrcovr, 0, sizeof(*intsrcovr)); - intsrcovr->type = APIC_XRUPT_OVERRIDE; - intsrcovr->length = sizeof(*intsrcovr); - intsrcovr->source = i; - intsrcovr->gsi = i; - intsrcovr->flags = 0xd; /* active high, level triggered */ - intsrcovr++; - } - - build_header((void*)madt, APIC_SIGNATURE, (void*)intsrcovr - (void*)madt, 1); - return madt; -} - -// Encode a hex value -static inline char getHex(u32 val) { - val &= 0x0f; - return (val <= 9) ? ('0' + val) : ('A' + val - 10); -} - -// Encode a length in an SSDT. -static u8 * -encodeLen(u8 *ssdt_ptr, int length, int bytes) -{ - switch (bytes) { - default: - case 4: ssdt_ptr[3] = ((length >> 20) & 0xff); - case 3: ssdt_ptr[2] = ((length >> 12) & 0xff); - case 2: ssdt_ptr[1] = ((length >> 4) & 0xff); - ssdt_ptr[0] = (((bytes-1) & 0x3) << 6) | (length & 0x0f); - break; - case 1: ssdt_ptr[0] = length & 0x3f; - } - return ssdt_ptr + bytes; -} - -// AML Processor() object. See src/ssdt-proc.dsl for info. -static unsigned char ssdt_proc[] = { - 0x5b,0x83,0x42,0x05,0x43,0x50,0x41,0x41, - 0xaa,0x10,0xb0,0x00,0x00,0x06,0x08,0x49, - 0x44,0x5f,0x5f,0x0a,0xaa,0x08,0x5f,0x48, - 0x49,0x44,0x0d,0x41,0x43,0x50,0x49,0x30, - 0x30,0x30,0x37,0x00,0x14,0x0f,0x5f,0x4d, - 0x41,0x54,0x00,0xa4,0x43,0x50,0x4d,0x41, - 0x49,0x44,0x5f,0x5f,0x14,0x0f,0x5f,0x53, - 0x54,0x41,0x00,0xa4,0x43,0x50,0x53,0x54, - 0x49,0x44,0x5f,0x5f,0x14,0x0f,0x5f,0x45, - 0x4a,0x30,0x01,0x43,0x50,0x45,0x4a,0x49, - 0x44,0x5f,0x5f,0x68 -}; -#define SD_OFFSET_CPUHEX 6 -#define SD_OFFSET_CPUID1 8 -#define SD_OFFSET_CPUID2 20 - -#define SSDT_SIGNATURE 0x54445353 // SSDT -static void* -build_ssdt(void) -{ - int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs; - // length = ScopeOp + procs + NTYF method + CPON package - int length = ((1+3+4) - + (acpi_cpus * sizeof(ssdt_proc)) - + (1+2+5+(12*acpi_cpus)) - + (6+2+1+(1*acpi_cpus))); - u8 *ssdt = malloc_high(sizeof(struct acpi_table_header) + length); - if (! ssdt) { - warn_noalloc(); - return NULL; - } - u8 *ssdt_ptr = ssdt + sizeof(struct acpi_table_header); - - // build Scope(_SB_) header - *(ssdt_ptr++) = 0x10; // ScopeOp - ssdt_ptr = encodeLen(ssdt_ptr, length-1, 3); - *(ssdt_ptr++) = '_'; - *(ssdt_ptr++) = 'S'; - *(ssdt_ptr++) = 'B'; - *(ssdt_ptr++) = '_'; - - // build Processor object for each processor - int i; - for (i=0; i> 4); - ssdt_ptr[SD_OFFSET_CPUHEX+1] = getHex(i); - ssdt_ptr[SD_OFFSET_CPUID1] = i; - ssdt_ptr[SD_OFFSET_CPUID2] = i; - ssdt_ptr += sizeof(ssdt_proc); - } - - // build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}" - *(ssdt_ptr++) = 0x14; // MethodOp - ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*acpi_cpus), 2); - *(ssdt_ptr++) = 'N'; - *(ssdt_ptr++) = 'T'; - *(ssdt_ptr++) = 'F'; - *(ssdt_ptr++) = 'Y'; - *(ssdt_ptr++) = 0x02; - for (i=0; i> 4); - *(ssdt_ptr++) = getHex(i); - *(ssdt_ptr++) = 0x69; // Arg1Op - } - - // build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" - *(ssdt_ptr++) = 0x08; // NameOp - *(ssdt_ptr++) = 'C'; - *(ssdt_ptr++) = 'P'; - *(ssdt_ptr++) = 'O'; - *(ssdt_ptr++) = 'N'; - *(ssdt_ptr++) = 0x12; // PackageOp - ssdt_ptr = encodeLen(ssdt_ptr, 2+1+(1*acpi_cpus), 2); - *(ssdt_ptr++) = acpi_cpus; - for (i=0; itimer_block_id = cpu_to_le32(0x8086a201); - hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS); - build_header((void*)hpet, HPET_SIGNATURE, sizeof(*hpet), 1); - - return hpet; -} - -static void -acpi_build_srat_memory(struct srat_memory_affinity *numamem, - u64 base, u64 len, int node, int enabled) -{ - numamem->type = SRAT_MEMORY; - numamem->length = sizeof(*numamem); - memset (numamem->proximity, 0 ,4); - numamem->proximity[0] = node; - numamem->flags = cpu_to_le32(!!enabled); - numamem->base_addr_low = base & 0xFFFFFFFF; - numamem->base_addr_high = base >> 32; - numamem->length_low = len & 0xFFFFFFFF; - numamem->length_high = len >> 32; -} - -#define SRAT_SIGNATURE 0x54415253 //HPET -static void * -build_srat(void) -{ - int nb_numa_nodes = qemu_cfg_get_numa_nodes(); - - if (nb_numa_nodes == 0) - return NULL; - - u64 *numadata = malloc_tmphigh(sizeof(u64) * (MaxCountCPUs + nb_numa_nodes)); - if (!numadata) { - warn_noalloc(); - return NULL; - } - - qemu_cfg_get_numa_data(numadata, MaxCountCPUs + nb_numa_nodes); - - struct system_resource_affinity_table *srat; - int srat_size = sizeof(*srat) + - sizeof(struct srat_processor_affinity) * MaxCountCPUs + - sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2); - - srat = malloc_high(srat_size); - if (!srat) { - warn_noalloc(); - free(numadata); - return NULL; - } - - memset(srat, 0, srat_size); - srat->reserved1=1; - struct srat_processor_affinity *core = (void*)(srat + 1); - int i; - u64 curnode; - - for (i = 0; i < MaxCountCPUs; ++i) { - core->type = SRAT_PROCESSOR; - core->length = sizeof(*core); - core->local_apic_id = i; - curnode = *numadata++; - core->proximity_lo = curnode; - memset(core->proximity_hi, 0, 3); - core->local_sapic_eid = 0; - if (i < CountCPUs) - core->flags = cpu_to_le32(1); - else - core->flags = 0; - core++; - } - - - /* the memory map is a bit tricky, it contains at least one hole - * from 640k-1M and possibly another one from 3.5G-4G. - */ - struct srat_memory_affinity *numamem = (void*)core; - int slots = 0; - u64 mem_len, mem_base, next_base = 0; - - acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1); - next_base = 1024 * 1024; - numamem++; - slots++; - for (i = 1; i < nb_numa_nodes + 1; ++i) { - mem_base = next_base; - mem_len = *numadata++; - if (i == 1) - mem_len -= 1024 * 1024; - next_base = mem_base + mem_len; - - /* Cut out the PCI hole */ - if (mem_base <= RamSize && next_base > RamSize) { - mem_len -= next_base - RamSize; - if (mem_len > 0) { - acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1); - numamem++; - slots++; - } - mem_base = 1ULL << 32; - mem_len = next_base - RamSize; - next_base += (1ULL << 32) - RamSize; - } - acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1); - numamem++; - slots++; - } - for (; slots < nb_numa_nodes + 2; slots++) { - acpi_build_srat_memory(numamem, 0, 0, 0, 0); - numamem++; - } - - build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1); - - free(numadata); - return srat; -} - -static const struct pci_device_id acpi_find_tbl[] = { - /* PIIX4 Power Management device. */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL), - - PCI_DEVICE_END, -}; - -struct rsdp_descriptor *RsdpAddr; - -#define MAX_ACPI_TABLES 20 -void -acpi_bios_init(void) -{ - if (! CONFIG_ACPI) - return; - - dprintf(3, "init ACPI tables\n"); - - // This code is hardcoded for PIIX4 Power Management device. - int bdf = pci_find_init_device(acpi_find_tbl, NULL); - if (bdf < 0) - // Device not found - return; - - // Create initial rsdt table - struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp)); - if (!rsdp) { - warn_noalloc(); - return; - } - - u32 tables[MAX_ACPI_TABLES], tbl_idx = 0; - -#define ACPI_INIT_TABLE(X) \ - do { \ - tables[tbl_idx] = (u32)(X); \ - if (tables[tbl_idx]) \ - tbl_idx++; \ - } while(0) - - // Add tables - ACPI_INIT_TABLE(build_fadt(bdf)); - ACPI_INIT_TABLE(build_ssdt()); - ACPI_INIT_TABLE(build_madt()); - ACPI_INIT_TABLE(build_hpet()); - ACPI_INIT_TABLE(build_srat()); - - u16 i, external_tables = qemu_cfg_acpi_additional_tables(); - - for(i = 0; i < external_tables; i++) { - u16 len = qemu_cfg_next_acpi_table_len(); - void *addr = malloc_high(len); - if (!addr) { - warn_noalloc(); - continue; - } - ACPI_INIT_TABLE(qemu_cfg_next_acpi_table_load(addr, len)); - if (tbl_idx == MAX_ACPI_TABLES) { - warn_noalloc(); - break; - } - } - - struct rsdt_descriptor_rev1 *rsdt; - size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx; - rsdt = malloc_high(rsdt_len); - - if (!rsdt) { - warn_noalloc(); - return; - } - memset(rsdt, 0, rsdt_len); - memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx); - - build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1); - - // Build rsdp pointer table - memset(rsdp, 0, sizeof(*rsdp)); - rsdp->signature = RSDP_SIGNATURE; - memcpy(rsdp->oem_id, CONFIG_APPNAME6, 6); - rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt); - rsdp->checksum -= checksum(rsdp, 20); - RsdpAddr = rsdp; - dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt); -} - -u32 -find_resume_vector(void) -{ - dprintf(4, "rsdp=%p\n", RsdpAddr); - if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE) - return 0; - struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address; - dprintf(4, "rsdt=%p\n", rsdt); - if (!rsdt || rsdt->signature != RSDT_SIGNATURE) - return 0; - void *end = (void*)rsdt + rsdt->length; - int i; - for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) { - struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i]; - if (!fadt || fadt->signature != FACP_SIGNATURE) - continue; - dprintf(4, "fadt=%p\n", fadt); - struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; - dprintf(4, "facs=%p\n", facs); - if (! facs || facs->signature != FACS_SIGNATURE) - return 0; - // Found it. - dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector); - return facs->firmware_waking_vector; - } - return 0; -} diff --git a/roms/seabios/src/acpi.h b/roms/seabios/src/acpi.h deleted file mode 100644 index e01315a..0000000 --- a/roms/seabios/src/acpi.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef __ACPI_H -#define __ACPI_H - -#include "types.h" // u32 - -void acpi_bios_init(void); -u32 find_resume_vector(void); - -#define RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR " - -struct rsdp_descriptor { /* Root System Descriptor Pointer */ - u64 signature; /* ACPI signature, contains "RSD PTR " */ - u8 checksum; /* To make sum of struct == 0 */ - u8 oem_id [6]; /* OEM identification */ - u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */ - u32 rsdt_physical_address; /* 32-bit physical address of RSDT */ - u32 length; /* XSDT Length in bytes including hdr */ - u64 xsdt_physical_address; /* 64-bit physical address of XSDT */ - u8 extended_checksum; /* Checksum of entire table */ - u8 reserved [3]; /* Reserved field must be 0 */ -}; - -extern struct rsdp_descriptor *RsdpAddr; - -/* Table structure from Linux kernel (the ACPI tables are under the - BSD license) */ - -#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \ - u32 signature; /* ACPI signature (4 ASCII characters) */ \ - u32 length; /* Length of table, in bytes, including header */ \ - u8 revision; /* ACPI Specification minor version # */ \ - u8 checksum; /* To make sum of entire table == 0 */ \ - u8 oem_id [6]; /* OEM identification */ \ - u8 oem_table_id [8]; /* OEM table identification */ \ - u32 oem_revision; /* OEM revision number */ \ - u8 asl_compiler_id [4]; /* ASL compiler vendor ID */ \ - u32 asl_compiler_revision; /* ASL compiler revision number */ - - -/* - * ACPI 1.0 Fixed ACPI Description Table (FADT) - */ -#define FACP_SIGNATURE 0x50434146 // FACP -struct fadt_descriptor_rev1 -{ - ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 firmware_ctrl; /* Physical address of FACS */ - u32 dsdt; /* Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 reserved1; /* Reserved */ - u16 sci_int; /* System vector of SCI interrupt */ - u32 smi_cmd; /* Port address of SMI command port */ - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 reserved2; /* Reserved - must be zero */ - u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ - u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ - u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ - u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tmr_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ - u8 reserved3; /* Reserved */ - u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Size of area read to flush caches */ - u16 flush_stride; /* Stride used in flushing caches */ - u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */ - u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */ - u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* Index to century in RTC CMOS RAM */ - u8 reserved4; /* Reserved */ - u8 reserved4a; /* Reserved */ - u8 reserved4b; /* Reserved */ -#if 0 - u32 wb_invd : 1; /* The wbinvd instruction works properly */ - u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ - u32 proc_c1 : 1; /* All processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */ - u32 reserved5 : 23; /* Reserved - must be zero */ -#else - u32 flags; -#endif -} PACKED; - -#endif // acpi.h diff --git a/roms/seabios/src/apm.c b/roms/seabios/src/apm.c deleted file mode 100644 index 1b151e9..0000000 --- a/roms/seabios/src/apm.c +++ /dev/null @@ -1,232 +0,0 @@ -// Basic support for apmbios callbacks. -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2005 Struan Bartlett -// Copyright (C) 2004 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "farptr.h" // GET_VAR -#include "bregs.h" // struct bregs -#include "ioport.h" // outb -#include "util.h" // wait_irq -#include "config.h" // CONFIG_* -#include "biosvar.h" // GET_GLOBAL - -static void -out_str(const char *str_cs) -{ - if (CONFIG_COREBOOT) { - dprintf(1, "APM request '%s'\n", str_cs); - return; - } - - u8 *s = (u8*)str_cs; - for (;;) { - u8 c = GET_GLOBAL(*s); - if (!c) - break; - outb(c, PORT_BIOS_APM); - s++; - } -} - -// APM installation check -static void -handle_155300(struct bregs *regs) -{ - regs->ah = 1; // APM major version - regs->al = 2; // APM minor version - regs->bh = 'P'; - regs->bl = 'M'; - // bit 0 : 16 bit interface supported - // bit 1 : 32 bit interface supported - regs->cx = 0x03; - set_success(regs); -} - -// APM real mode interface connect -static void -handle_155301(struct bregs *regs) -{ - set_success(regs); -} - -// Assembler entry points defined in romlayout.S -extern void apm16protected_entry(void); -extern void apm32protected_entry(void); - -// APM 16 bit protected mode interface connect -static void -handle_155302(struct bregs *regs) -{ - regs->bx = (u32)apm16protected_entry; - regs->ax = SEG_BIOS; // 16 bit code segment base - regs->si = 0xfff0; // 16 bit code segment size - regs->cx = SEG_BIOS; // data segment address - regs->di = 0xfff0; // data segment length - set_success(regs); -} - -// APM 32 bit protected mode interface connect -static void -handle_155303(struct bregs *regs) -{ - regs->ax = SEG_BIOS; // 32 bit code segment base - regs->ebx = (u32)apm32protected_entry; - regs->cx = SEG_BIOS; // 16 bit code segment base - // 32 bit code segment size (low 16 bits) - // 16 bit code segment size (high 16 bits) - regs->esi = 0xfff0fff0; - regs->dx = SEG_BIOS; // data segment address - regs->di = 0xfff0; // data segment length - set_success(regs); -} - -// APM interface disconnect -static void -handle_155304(struct bregs *regs) -{ - set_success(regs); -} - -// APM cpu idle -static void -handle_155305(struct bregs *regs) -{ - wait_irq(); - set_success(regs); -} - -// APM cpu busy -static void -handle_155306(struct bregs *regs) -{ - set_success(regs); -} - -// APM Set Power State -static void -handle_155307(struct bregs *regs) -{ - if (regs->bx != 1) { - set_success(regs); - return; - } - switch (regs->cx) { - case 1: - out_str("Standby"); - break; - case 2: - out_str("Suspend"); - break; - case 3: - irq_disable(); - out_str("Shutdown"); - for (;;) - hlt(); - break; - } - set_success(regs); -} - -static void -handle_155308(struct bregs *regs) -{ - set_success(regs); -} - -// Get Power Status -static void -handle_15530a(struct bregs *regs) -{ - regs->bh = 0x01; // on line - regs->bl = 0xff; // unknown battery status - regs->ch = 0x80; // no system battery - regs->cl = 0xff; // unknown remaining time - regs->dx = 0xffff; // unknown remaining time - regs->si = 0x00; // zero battery - set_success(regs); -} - -#define RET_ENOEVENT 0x80 - -// Get PM Event -static void -handle_15530b(struct bregs *regs) -{ - set_code_invalid_silent(regs, RET_ENOEVENT); -} - -// APM Driver Version -static void -handle_15530e(struct bregs *regs) -{ - regs->ah = 1; - regs->al = 2; - set_success(regs); -} - -// APM Engage / Disengage -static void -handle_15530f(struct bregs *regs) -{ - set_success(regs); -} - -// APM Get Capabilities -static void -handle_155310(struct bregs *regs) -{ - regs->bl = 0; - regs->cx = 0; - set_success(regs); -} - -static void -handle_1553XX(struct bregs *regs) -{ - set_unimplemented(regs); -} - -void -handle_1553(struct bregs *regs) -{ - if (! CONFIG_APMBIOS) { - set_code_invalid(regs, RET_EUNSUPPORTED); - return; - } - - //debug_stub(regs); - switch (regs->al) { - case 0x00: handle_155300(regs); break; - case 0x01: handle_155301(regs); break; - case 0x02: handle_155302(regs); break; - case 0x03: handle_155303(regs); break; - case 0x04: handle_155304(regs); break; - case 0x05: handle_155305(regs); break; - case 0x06: handle_155306(regs); break; - case 0x07: handle_155307(regs); break; - case 0x08: handle_155308(regs); break; - case 0x0a: handle_15530a(regs); break; - case 0x0b: handle_15530b(regs); break; - case 0x0e: handle_15530e(regs); break; - case 0x0f: handle_15530f(regs); break; - case 0x10: handle_155310(regs); break; - default: handle_1553XX(regs); break; - } -} - -void VISIBLE16 -handle_apm16(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_apm); - handle_1553(regs); -} - -void VISIBLE32SEG -handle_apm32(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_apm); - handle_1553(regs); -} diff --git a/roms/seabios/src/asm-offsets.c b/roms/seabios/src/asm-offsets.c deleted file mode 100644 index 5035cef..0000000 --- a/roms/seabios/src/asm-offsets.c +++ /dev/null @@ -1,31 +0,0 @@ -// Generate assembler offsets. - -#include "gen-defs.h" // OFFSET -#include "bregs.h" // struct bregs -#include "biosvar.h" // struct bios_data_area_s - -/* workaround for a warning with -Wmissing-prototypes */ -void foo(void) VISIBLE16; - -void foo(void) -{ - COMMENT("BREGS"); - OFFSET(BREGS_es, bregs, es); - OFFSET(BREGS_ds, bregs, ds); - OFFSET(BREGS_eax, bregs, eax); - OFFSET(BREGS_ebx, bregs, ebx); - OFFSET(BREGS_ecx, bregs, ecx); - OFFSET(BREGS_edx, bregs, edx); - OFFSET(BREGS_ebp, bregs, ebp); - OFFSET(BREGS_esi, bregs, esi); - OFFSET(BREGS_edi, bregs, edi); - OFFSET(BREGS_flags, bregs, flags); - OFFSET(BREGS_code, bregs, code); - - COMMENT("BDA"); - OFFSET(BDA_ebda_seg, bios_data_area_s, ebda_seg); - - COMMENT("EBDA"); - DEFINE(EBDA_OFFSET_TOP_STACK, EBDA_OFFSET_TOP_STACK); - DEFINE(EBDA_SEGMENT_START, EBDA_SEGMENT_START); -} diff --git a/roms/seabios/src/ata.c b/roms/seabios/src/ata.c deleted file mode 100644 index e9a8df7..0000000 --- a/roms/seabios/src/ata.c +++ /dev/null @@ -1,1042 +0,0 @@ -// Low level ATA disk access -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "types.h" // u8 -#include "ioport.h" // inb -#include "util.h" // dprintf -#include "cmos.h" // inb_cmos -#include "pic.h" // enable_hwirq -#include "biosvar.h" // GET_EBDA -#include "pci.h" // foreachpci -#include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER -#include "pci_regs.h" // PCI_INTERRUPT_LINE -#include "boot.h" // add_bcv_hd -#include "disk.h" // struct ata_s -#include "ata.h" // ATA_CB_STAT -#include "blockcmd.h" // CDB_CMD_READ_10 - -#define IDE_TIMEOUT 32000 //32 seconds max for IDE ops - - -/**************************************************************** - * Helper functions - ****************************************************************/ - -// Wait for the specified ide state -static inline int -await_ide(u8 mask, u8 flags, u16 base, u16 timeout) -{ - u64 end = calc_future_tsc(timeout); - for (;;) { - u8 status = inb(base+ATA_CB_STAT); - if ((status & mask) == flags) - return status; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - yield(); - } -} - -// Wait for the device to be not-busy. -static int -await_not_bsy(u16 base) -{ - return await_ide(ATA_CB_STAT_BSY, 0, base, IDE_TIMEOUT); -} - -// Wait for the device to be ready. -static int -await_rdy(u16 base) -{ - return await_ide(ATA_CB_STAT_RDY, ATA_CB_STAT_RDY, base, IDE_TIMEOUT); -} - -// Wait for ide state - pauses for one ata cycle first. -static inline int -pause_await_not_bsy(u16 iobase1, u16 iobase2) -{ - // Wait one PIO transfer cycle. - inb(iobase2 + ATA_CB_ASTAT); - - return await_not_bsy(iobase1); -} - -// Wait for ide state - pause for 400ns first. -static inline int -ndelay_await_not_bsy(u16 iobase1) -{ - ndelay(400); - return await_not_bsy(iobase1); -} - -// Reset a drive -static void -ata_reset(struct atadrive_s *adrive_g) -{ - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u8 slave = GET_GLOBAL(adrive_g->slave); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - - dprintf(6, "ata_reset drive=%p\n", &adrive_g->drive); - // Pulse SRST - outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST, iobase2+ATA_CB_DC); - udelay(5); - outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC); - msleep(2); - - // wait for device to become not busy. - int status = await_not_bsy(iobase1); - if (status < 0) - goto done; - if (slave) { - // Change device. - u64 end = calc_future_tsc(IDE_TIMEOUT); - for (;;) { - outb(ATA_CB_DH_DEV1, iobase1 + ATA_CB_DH); - status = ndelay_await_not_bsy(iobase1); - if (status < 0) - goto done; - if (inb(iobase1 + ATA_CB_DH) == ATA_CB_DH_DEV1) - break; - // Change drive request failed to take effect - retry. - if (check_tsc(end)) { - warn_timeout(); - goto done; - } - } - } else { - // QEMU doesn't reset dh on reset, so set it explicitly. - outb(ATA_CB_DH_DEV0, iobase1 + ATA_CB_DH); - } - - // On a user-reset request, wait for RDY if it is an ATA device. - u8 type=GET_GLOBAL(adrive_g->drive.type); - if (type == DTYPE_ATA) - status = await_rdy(iobase1); - -done: - // Enable interrupts - outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC); - - dprintf(6, "ata_reset exit status=%x\n", status); -} - -// Check for drive RDY for 16bit interface command. -static int -isready(struct atadrive_s *adrive_g) -{ - // Read the status from controller - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u8 status = inb(iobase1 + ATA_CB_STAT); - if ((status & (ATA_CB_STAT_BSY|ATA_CB_STAT_RDY)) == ATA_CB_STAT_RDY) - return DISK_RET_SUCCESS; - return DISK_RET_ENOTREADY; -} - -// Default 16bit command demuxer for ATA and ATAPI devices. -static int -process_ata_misc_op(struct disk_op_s *op) -{ - if (!CONFIG_ATA) - return 0; - - struct atadrive_s *adrive_g = container_of( - op->drive_g, struct atadrive_s, drive); - switch (op->command) { - case CMD_RESET: - ata_reset(adrive_g); - return DISK_RET_SUCCESS; - case CMD_ISREADY: - return isready(adrive_g); - case CMD_FORMAT: - case CMD_VERIFY: - case CMD_SEEK: - return DISK_RET_SUCCESS; - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} - - -/**************************************************************** - * ATA send command - ****************************************************************/ - -struct ata_pio_command { - u8 feature; - u8 sector_count; - u8 lba_low; - u8 lba_mid; - u8 lba_high; - u8 device; - u8 command; - - u8 feature2; - u8 sector_count2; - u8 lba_low2; - u8 lba_mid2; - u8 lba_high2; -}; - -// Send an ata command to the drive. -static int -send_cmd(struct atadrive_s *adrive_g, struct ata_pio_command *cmd) -{ - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u8 slave = GET_GLOBAL(adrive_g->slave); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - - // Select device - int status = await_not_bsy(iobase1); - if (status < 0) - return status; - u8 newdh = ((cmd->device & ~ATA_CB_DH_DEV1) - | (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)); - u8 olddh = inb(iobase1 + ATA_CB_DH); - outb(newdh, iobase1 + ATA_CB_DH); - if ((olddh ^ newdh) & (1<<4)) { - // Was a device change - wait for device to become not busy. - status = ndelay_await_not_bsy(iobase1); - if (status < 0) - return status; - } - - // Check for ATA_CMD_(READ|WRITE)_(SECTORS|DMA)_EXT commands. - if ((cmd->command & ~0x11) == ATA_CMD_READ_SECTORS_EXT) { - outb(cmd->feature2, iobase1 + ATA_CB_FR); - outb(cmd->sector_count2, iobase1 + ATA_CB_SC); - outb(cmd->lba_low2, iobase1 + ATA_CB_SN); - outb(cmd->lba_mid2, iobase1 + ATA_CB_CL); - outb(cmd->lba_high2, iobase1 + ATA_CB_CH); - } - outb(cmd->feature, iobase1 + ATA_CB_FR); - outb(cmd->sector_count, iobase1 + ATA_CB_SC); - outb(cmd->lba_low, iobase1 + ATA_CB_SN); - outb(cmd->lba_mid, iobase1 + ATA_CB_CL); - outb(cmd->lba_high, iobase1 + ATA_CB_CH); - outb(cmd->command, iobase1 + ATA_CB_CMD); - - return 0; -} - -// Wait for data after calling 'send_cmd'. -static int -ata_wait_data(u16 iobase1) -{ - int status = ndelay_await_not_bsy(iobase1); - if (status < 0) - return status; - - if (status & ATA_CB_STAT_ERR) { - dprintf(6, "send_cmd : read error (status=%02x err=%02x)\n" - , status, inb(iobase1 + ATA_CB_ERR)); - return -4; - } - if (!(status & ATA_CB_STAT_DRQ)) { - dprintf(6, "send_cmd : DRQ not set (status %02x)\n", status); - return -5; - } - - return 0; -} - -// Send an ata command that does not transfer any further data. -int -ata_cmd_nondata(struct atadrive_s *adrive_g, struct ata_pio_command *cmd) -{ - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - - // Disable interrupts - outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC); - - int ret = send_cmd(adrive_g, cmd); - if (ret) - goto fail; - ret = ndelay_await_not_bsy(iobase1); - if (ret < 0) - goto fail; - - if (ret & ATA_CB_STAT_ERR) { - dprintf(6, "nondata cmd : read error (status=%02x err=%02x)\n" - , ret, inb(iobase1 + ATA_CB_ERR)); - ret = -4; - goto fail; - } - if (ret & ATA_CB_STAT_DRQ) { - dprintf(6, "nondata cmd : DRQ set (status %02x)\n", ret); - ret = -5; - goto fail; - } - -fail: - // Enable interrupts - outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC); - - return ret; -} - - -/**************************************************************** - * ATA PIO transfers - ****************************************************************/ - -// Transfer 'op->count' blocks (of 'blocksize' bytes) to/from drive -// 'op->drive_g'. -static int -ata_pio_transfer(struct disk_op_s *op, int iswrite, int blocksize) -{ - dprintf(16, "ata_pio_transfer id=%p write=%d count=%d bs=%d buf=%p\n" - , op->drive_g, iswrite, op->count, blocksize, op->buf_fl); - - struct atadrive_s *adrive_g = container_of( - op->drive_g, struct atadrive_s, drive); - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - int count = op->count; - void *buf_fl = op->buf_fl; - int status; - for (;;) { - if (iswrite) { - // Write data to controller - dprintf(16, "Write sector id=%p dest=%p\n", op->drive_g, buf_fl); - if (CONFIG_ATA_PIO32) - outsl_fl(iobase1, buf_fl, blocksize / 4); - else - outsw_fl(iobase1, buf_fl, blocksize / 2); - } else { - // Read data from controller - dprintf(16, "Read sector id=%p dest=%p\n", op->drive_g, buf_fl); - if (CONFIG_ATA_PIO32) - insl_fl(iobase1, buf_fl, blocksize / 4); - else - insw_fl(iobase1, buf_fl, blocksize / 2); - } - buf_fl += blocksize; - - status = pause_await_not_bsy(iobase1, iobase2); - if (status < 0) { - // Error - op->count -= count; - return status; - } - - count--; - if (!count) - break; - status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR); - if (status != ATA_CB_STAT_DRQ) { - dprintf(6, "ata_pio_transfer : more sectors left (status %02x)\n" - , status); - op->count -= count; - return -6; - } - } - - status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ - | ATA_CB_STAT_ERR); - if (!iswrite) - status &= ~ATA_CB_STAT_DF; - if (status != 0) { - dprintf(6, "ata_pio_transfer : no sectors left (status %02x)\n", status); - return -7; - } - - return 0; -} - - -/**************************************************************** - * ATA DMA transfers - ****************************************************************/ - -#define BM_CMD 0 -#define BM_CMD_MEMWRITE 0x08 -#define BM_CMD_START 0x01 -#define BM_STATUS 2 -#define BM_STATUS_IRQ 0x04 -#define BM_STATUS_ERROR 0x02 -#define BM_STATUS_ACTIVE 0x01 -#define BM_TABLE 4 - -struct sff_dma_prd { - u32 buf_fl; - u32 count; -}; - -// Check if DMA available and setup transfer if so. -static int -ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize) -{ - if (! CONFIG_ATA_DMA) - return -1; - u32 dest = (u32)op->buf_fl; - if (dest & 1) - // Need minimum alignment of 1. - return -1; - struct atadrive_s *adrive_g = container_of( - op->drive_g, struct atadrive_s, drive); - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u16 iomaster = GET_GLOBALFLAT(chan_gf->iomaster); - if (! iomaster) - return -1; - u32 bytes = op->count * blocksize; - if (! bytes) - return -1; - - // Build PRD dma structure. - struct sff_dma_prd *dma = MAKE_FLATPTR( - get_ebda_seg() - , (void*)offsetof(struct extended_bios_data_area_s, extra_stack)); - struct sff_dma_prd *origdma = dma; - while (bytes) { - if (dma >= &origdma[16]) - // Too many descriptors.. - return -1; - u32 count = bytes; - u32 max = 0x10000 - (dest & 0xffff); - if (count > max) - count = max; - - SET_FLATPTR(dma->buf_fl, dest); - bytes -= count; - if (!bytes) - // Last descriptor. - count |= 1<<31; - dprintf(16, "dma@%p: %08x %08x\n", dma, dest, count); - dest += count; - SET_FLATPTR(dma->count, count); - dma++; - } - - // Program bus-master controller. - outl((u32)origdma, iomaster + BM_TABLE); - u8 oldcmd = inb(iomaster + BM_CMD) & ~(BM_CMD_MEMWRITE|BM_CMD_START); - outb(oldcmd | (iswrite ? 0x00 : BM_CMD_MEMWRITE), iomaster + BM_CMD); - outb(BM_STATUS_ERROR|BM_STATUS_IRQ, iomaster + BM_STATUS); - - return 0; -} - -// Transfer data using DMA. -static int -ata_dma_transfer(struct disk_op_s *op) -{ - if (! CONFIG_ATA_DMA) - return -1; - dprintf(16, "ata_dma_transfer id=%p buf=%p\n", op->drive_g, op->buf_fl); - - struct atadrive_s *adrive_g = container_of( - op->drive_g, struct atadrive_s, drive); - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u16 iomaster = GET_GLOBALFLAT(chan_gf->iomaster); - - // Start bus-master controller. - u8 oldcmd = inb(iomaster + BM_CMD); - outb(oldcmd | BM_CMD_START, iomaster + BM_CMD); - - u64 end = calc_future_tsc(IDE_TIMEOUT); - u8 status; - for (;;) { - status = inb(iomaster + BM_STATUS); - if (status & BM_STATUS_IRQ) - break; - // Transfer in progress - if (check_tsc(end)) { - // Timeout. - warn_timeout(); - break; - } - yield(); - } - outb(oldcmd & ~BM_CMD_START, iomaster + BM_CMD); - - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - int idestatus = pause_await_not_bsy(iobase1, iobase2); - - if ((status & (BM_STATUS_IRQ|BM_STATUS_ACTIVE)) == BM_STATUS_IRQ - && idestatus >= 0x00 - && (idestatus & (ATA_CB_STAT_BSY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ - | ATA_CB_STAT_ERR)) == 0x00) - // Success. - return 0; - - dprintf(6, "IDE DMA error (dma=%x ide=%x/%x/%x)\n", status, idestatus - , inb(iobase2 + ATA_CB_ASTAT), inb(iobase1 + ATA_CB_ERR)); - op->count = 0; - return -1; -} - - -/**************************************************************** - * ATA hard drive functions - ****************************************************************/ - -// Transfer data to harddrive using PIO protocol. -static int -ata_pio_cmd_data(struct disk_op_s *op, int iswrite, struct ata_pio_command *cmd) -{ - struct atadrive_s *adrive_g = container_of( - op->drive_g, struct atadrive_s, drive); - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - - // Disable interrupts - outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC); - - int ret = send_cmd(adrive_g, cmd); - if (ret) - goto fail; - ret = ata_wait_data(iobase1); - if (ret) - goto fail; - ret = ata_pio_transfer(op, iswrite, DISK_SECTOR_SIZE); - -fail: - // Enable interrupts - outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC); - return ret; -} - -// Transfer data to harddrive using DMA protocol. -static int -ata_dma_cmd_data(struct disk_op_s *op, struct ata_pio_command *cmd) -{ - if (! CONFIG_ATA_DMA) - return -1; - struct atadrive_s *adrive_g = container_of( - op->drive_g, struct atadrive_s, drive); - int ret = send_cmd(adrive_g, cmd); - if (ret) - return ret; - return ata_dma_transfer(op); -} - -// Read/write count blocks from a harddrive. -static int -ata_readwrite(struct disk_op_s *op, int iswrite) -{ - u64 lba = op->lba; - - int usepio = ata_try_dma(op, iswrite, DISK_SECTOR_SIZE); - - struct ata_pio_command cmd; - memset(&cmd, 0, sizeof(cmd)); - - if (op->count >= (1<<8) || lba + op->count >= (1<<28)) { - cmd.sector_count2 = op->count >> 8; - cmd.lba_low2 = lba >> 24; - cmd.lba_mid2 = lba >> 32; - cmd.lba_high2 = lba >> 40; - lba &= 0xffffff; - - if (usepio) - cmd.command = (iswrite ? ATA_CMD_WRITE_SECTORS_EXT - : ATA_CMD_READ_SECTORS_EXT); - else - cmd.command = (iswrite ? ATA_CMD_WRITE_DMA_EXT - : ATA_CMD_READ_DMA_EXT); - } else { - if (usepio) - cmd.command = (iswrite ? ATA_CMD_WRITE_SECTORS - : ATA_CMD_READ_SECTORS); - else - cmd.command = (iswrite ? ATA_CMD_WRITE_DMA - : ATA_CMD_READ_DMA); - } - - cmd.sector_count = op->count; - cmd.lba_low = lba; - cmd.lba_mid = lba >> 8; - cmd.lba_high = lba >> 16; - cmd.device = ((lba >> 24) & 0xf) | ATA_CB_DH_LBA; - - int ret; - if (usepio) - ret = ata_pio_cmd_data(op, iswrite, &cmd); - else - ret = ata_dma_cmd_data(op, &cmd); - if (ret) - return DISK_RET_EBADTRACK; - return DISK_RET_SUCCESS; -} - -// 16bit command demuxer for ATA harddrives. -int -process_ata_op(struct disk_op_s *op) -{ - if (!CONFIG_ATA) - return 0; - - switch (op->command) { - case CMD_READ: - return ata_readwrite(op, 0); - case CMD_WRITE: - return ata_readwrite(op, 1); - default: - return process_ata_misc_op(op); - } -} - - -/**************************************************************** - * ATAPI functions - ****************************************************************/ - -#define CDROM_CDB_SIZE 12 - -// Low-level atapi command transmit function. -int -atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize) -{ - struct atadrive_s *adrive_g = container_of( - op->drive_g, struct atadrive_s, drive); - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - - struct ata_pio_command cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.lba_mid = blocksize; - cmd.lba_high = blocksize >> 8; - cmd.command = ATA_CMD_PACKET; - - // Disable interrupts - outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC); - - int ret = send_cmd(adrive_g, &cmd); - if (ret) - goto fail; - ret = ata_wait_data(iobase1); - if (ret) - goto fail; - - // Send command to device - outsw_fl(iobase1, MAKE_FLATPTR(GET_SEG(SS), cdbcmd), CDROM_CDB_SIZE / 2); - - int status = pause_await_not_bsy(iobase1, iobase2); - if (status < 0) { - ret = status; - goto fail; - } - - if (status & ATA_CB_STAT_ERR) { - u8 err = inb(iobase1 + ATA_CB_ERR); - // skip "Not Ready" - if (err != 0x20) - dprintf(6, "send_atapi_cmd : read error (status=%02x err=%02x)\n" - , status, err); - ret = -2; - goto fail; - } - if (!(status & ATA_CB_STAT_DRQ)) { - dprintf(6, "send_atapi_cmd : DRQ not set (status %02x)\n", status); - ret = -3; - goto fail; - } - - ret = ata_pio_transfer(op, 0, blocksize); - -fail: - // Enable interrupts - outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC); - if (ret) - return DISK_RET_EBADTRACK; - return DISK_RET_SUCCESS; -} - -// 16bit command demuxer for ATAPI cdroms. -int -process_atapi_op(struct disk_op_s *op) -{ - if (!CONFIG_ATA) - return 0; - switch (op->command) { - case CMD_READ: - return cdb_read(op); - case CMD_FORMAT: - case CMD_WRITE: - return DISK_RET_EWRITEPROTECT; - default: - return process_ata_misc_op(op); - } -} - - -/**************************************************************** - * ATA detect and init - ****************************************************************/ - -// Send an identify device or identify device packet command. -static int -send_ata_identity(struct atadrive_s *adrive_g, u16 *buffer, int command) -{ - memset(buffer, 0, DISK_SECTOR_SIZE); - - struct disk_op_s dop; - memset(&dop, 0, sizeof(dop)); - dop.drive_g = &adrive_g->drive; - dop.count = 1; - dop.lba = 1; - dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer); - - struct ata_pio_command cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = command; - - return ata_pio_cmd_data(&dop, 0, &cmd); -} - -// Extract the ATA/ATAPI version info. -static int -extract_version(u16 *buffer) -{ - // Extract ATA/ATAPI version. - u16 ataversion = buffer[80]; - u8 version; - for (version=15; version>0; version--) - if (ataversion & (1<0 && model[i] == 0x20; i--) - model[i] = 0x00; - - return model; -} - -// Common init code between ata and atapi -static struct atadrive_s * -init_atadrive(struct atadrive_s *dummy, u16 *buffer) -{ - char *desc = malloc_tmp(MAXDESCSIZE); - struct atadrive_s *adrive_g = malloc_fseg(sizeof(*adrive_g)); - if (!adrive_g || !desc) { - warn_noalloc(); - free(desc); - free(adrive_g); - return NULL; - } - memset(adrive_g, 0, sizeof(*adrive_g)); - adrive_g->drive.desc = desc; - adrive_g->chan_gf = dummy->chan_gf; - adrive_g->slave = dummy->slave; - adrive_g->drive.cntl_id = adrive_g->chan_gf->chanid * 2 + dummy->slave; - adrive_g->drive.removable = (buffer[0] & 0x80) ? 1 : 0; - return adrive_g; -} - -// Detect if the given drive is an atapi - initialize it if so. -static struct atadrive_s * -init_drive_atapi(struct atadrive_s *dummy, u16 *buffer) -{ - // Send an IDENTIFY_DEVICE_PACKET command to device - int ret = send_ata_identity(dummy, buffer, ATA_CMD_IDENTIFY_PACKET_DEVICE); - if (ret) - return NULL; - - // Success - setup as ATAPI. - struct atadrive_s *adrive_g = init_atadrive(dummy, buffer); - if (!adrive_g) - return NULL; - adrive_g->drive.type = DTYPE_ATAPI; - adrive_g->drive.blksize = CDROM_SECTOR_SIZE; - adrive_g->drive.sectors = (u64)-1; - u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05; - char model[MAXMODEL+1]; - snprintf(adrive_g->drive.desc, MAXDESCSIZE, "ata%d-%d: %s ATAPI-%d %s" - , adrive_g->chan_gf->chanid, adrive_g->slave - , extract_model(model, buffer), extract_version(buffer) - , (iscd ? "DVD/CD" : "Device")); - dprintf(1, "%s\n", adrive_g->drive.desc); - - // fill cdidmap - if (iscd) - map_cd_drive(&adrive_g->drive); - - return adrive_g; -} - -// Detect if the given drive is a regular ata drive - initialize it if so. -static struct atadrive_s * -init_drive_ata(struct atadrive_s *dummy, u16 *buffer) -{ - // Send an IDENTIFY_DEVICE command to device - int ret = send_ata_identity(dummy, buffer, ATA_CMD_IDENTIFY_DEVICE); - if (ret) - return NULL; - - // Success - setup as ATA. - struct atadrive_s *adrive_g = init_atadrive(dummy, buffer); - if (!adrive_g) - return NULL; - adrive_g->drive.type = DTYPE_ATA; - adrive_g->drive.blksize = DISK_SECTOR_SIZE; - - adrive_g->drive.pchs.cylinders = buffer[1]; - adrive_g->drive.pchs.heads = buffer[3]; - adrive_g->drive.pchs.spt = buffer[6]; - - u64 sectors; - if (buffer[83] & (1 << 10)) // word 83 - lba48 support - sectors = *(u64*)&buffer[100]; // word 100-103 - else - sectors = *(u32*)&buffer[60]; // word 60 and word 61 - adrive_g->drive.sectors = sectors; - u64 adjsize = sectors >> 11; - char adjprefix = 'M'; - if (adjsize >= (1 << 16)) { - adjsize >>= 10; - adjprefix = 'G'; - } - char model[MAXMODEL+1]; - snprintf(adrive_g->drive.desc, MAXDESCSIZE - , "ata%d-%d: %s ATA-%d Hard-Disk (%u %ciBytes)" - , adrive_g->chan_gf->chanid, adrive_g->slave - , extract_model(model, buffer), extract_version(buffer) - , (u32)adjsize, adjprefix); - dprintf(1, "%s\n", adrive_g->drive.desc); - - // Setup disk geometry translation. - setup_translation(&adrive_g->drive); - - // Register with bcv system. - add_bcv_internal(&adrive_g->drive); - - return adrive_g; -} - -static u64 SpinupEnd; - -// Wait for non-busy status and check for "floating bus" condition. -static int -powerup_await_non_bsy(u16 base) -{ - u8 orstatus = 0; - u8 status; - for (;;) { - status = inb(base+ATA_CB_STAT); - if (!(status & ATA_CB_STAT_BSY)) - break; - orstatus |= status; - if (orstatus == 0xff) { - dprintf(4, "powerup IDE floating\n"); - return orstatus; - } - if (check_tsc(SpinupEnd)) { - warn_timeout(); - return -1; - } - yield(); - } - dprintf(6, "powerup iobase=%x st=%x\n", base, status); - return status; -} - -// Detect any drives attached to a given controller. -static void -ata_detect(void *data) -{ - struct ata_channel_s *chan_gf = data; - struct atadrive_s dummy; - memset(&dummy, 0, sizeof(dummy)); - dummy.chan_gf = chan_gf; - // Device detection - int didreset = 0; - u8 slave; - for (slave=0; slave<=1; slave++) { - // Wait for not-bsy. - u16 iobase1 = chan_gf->iobase1; - int status = powerup_await_non_bsy(iobase1); - if (status < 0) - continue; - u8 newdh = slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0; - outb(newdh, iobase1+ATA_CB_DH); - ndelay(400); - status = powerup_await_non_bsy(iobase1); - if (status < 0) - continue; - - // Check if ioport registers look valid. - outb(newdh, iobase1+ATA_CB_DH); - u8 dh = inb(iobase1+ATA_CB_DH); - outb(0x55, iobase1+ATA_CB_SC); - outb(0xaa, iobase1+ATA_CB_SN); - u8 sc = inb(iobase1+ATA_CB_SC); - u8 sn = inb(iobase1+ATA_CB_SN); - dprintf(6, "ata_detect ata%d-%d: sc=%x sn=%x dh=%x\n" - , chan_gf->chanid, slave, sc, sn, dh); - if (sc != 0x55 || sn != 0xaa || dh != newdh) - continue; - - // Prepare new drive. - dummy.slave = slave; - - // reset the channel - if (!didreset) { - ata_reset(&dummy); - didreset = 1; - } - - // check for ATAPI - u16 buffer[256]; - struct atadrive_s *adrive_g = init_drive_atapi(&dummy, buffer); - if (!adrive_g) { - // Didn't find an ATAPI drive - look for ATA drive. - u8 st = inb(iobase1+ATA_CB_STAT); - if (!st) - // Status not set - can't be a valid drive. - continue; - - // Wait for RDY. - int ret = await_rdy(iobase1); - if (ret < 0) - continue; - - // check for ATA. - adrive_g = init_drive_ata(&dummy, buffer); - if (!adrive_g) - // No ATA drive found - continue; - } - - u16 resetresult = buffer[93]; - dprintf(6, "ata_detect resetresult=%04x\n", resetresult); - if (!slave && (resetresult & 0xdf61) == 0x4041) - // resetresult looks valid and device 0 is responding to - // device 1 requests - device 1 must not be present - skip - // detection. - break; - } -} - -// Initialize an ata controller and detect its drives. -static void -init_controller(int chanid, int bdf, int irq, u32 port1, u32 port2, u32 master) -{ - struct ata_channel_s *chan_gf = malloc_fseg(sizeof(*chan_gf)); - if (!chan_gf) { - warn_noalloc(); - return; - } - chan_gf->chanid = chanid; - chan_gf->irq = irq; - chan_gf->pci_bdf = bdf; - chan_gf->iobase1 = port1; - chan_gf->iobase2 = port2; - chan_gf->iomaster = master; - dprintf(1, "ATA controller %d at %x/%x/%x (irq %d dev %x)\n" - , chanid, port1, port2, master, irq, bdf); - run_thread(ata_detect, chan_gf); -} - -#define IRQ_ATA1 14 -#define IRQ_ATA2 15 - -// Locate and init ata controllers. -static void -ata_init(void) -{ - // Scan PCI bus for ATA adapters - int count=0, pcicount=0; - int bdf, max; - foreachpci(bdf, max) { - pcicount++; - if (pci_config_readw(bdf, PCI_CLASS_DEVICE) != PCI_CLASS_STORAGE_IDE) - continue; - - u8 pciirq = pci_config_readb(bdf, PCI_INTERRUPT_LINE); - u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG); - int master = 0; - if (CONFIG_ATA_DMA && prog_if & 0x80) { - // Check for bus-mastering. - u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_4); - if (bar & PCI_BASE_ADDRESS_SPACE_IO) { - master = bar & PCI_BASE_ADDRESS_IO_MASK; - pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); - } - } - - u32 port1, port2, irq; - if (prog_if & 1) { - port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_0) - & PCI_BASE_ADDRESS_IO_MASK); - port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_1) - & PCI_BASE_ADDRESS_IO_MASK); - irq = pciirq; - } else { - port1 = PORT_ATA1_CMD_BASE; - port2 = PORT_ATA1_CTRL_BASE; - irq = IRQ_ATA1; - } - init_controller(count, bdf, irq, port1, port2, master); - count++; - - if (prog_if & 4) { - port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_2) - & PCI_BASE_ADDRESS_IO_MASK); - port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_3) - & PCI_BASE_ADDRESS_IO_MASK); - irq = pciirq; - } else { - port1 = PORT_ATA2_CMD_BASE; - port2 = PORT_ATA2_CTRL_BASE; - irq = IRQ_ATA2; - } - init_controller(count, bdf, irq, port1, port2, master ? master + 8 : 0); - count++; - } - - if (!CONFIG_COREBOOT && !pcicount) { - // No PCI devices found - probably a QEMU "-M isapc" machine. - // Try using ISA ports for ATA controllers. - init_controller(0, -1, IRQ_ATA1 - , PORT_ATA1_CMD_BASE, PORT_ATA1_CTRL_BASE, 0); - init_controller(1, -1, IRQ_ATA2 - , PORT_ATA2_CMD_BASE, PORT_ATA2_CTRL_BASE, 0); - } -} - -void -ata_setup(void) -{ - ASSERT32FLAT(); - if (!CONFIG_ATA) - return; - - dprintf(3, "init hard drives\n"); - - SpinupEnd = calc_future_tsc(IDE_TIMEOUT); - ata_init(); - - SET_BDA(disk_control_byte, 0xc0); - - enable_hwirq(14, FUNC16(entry_76)); -} diff --git a/roms/seabios/src/ata.h b/roms/seabios/src/ata.h deleted file mode 100644 index 94f60ee..0000000 --- a/roms/seabios/src/ata.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef __ATA_H -#define __ATA_H - -#include "types.h" // u8 -#include "config.h" // CONFIG_MAX_ATA_INTERFACES -#include "disk.h" // struct drive_s - -struct ata_channel_s { - u16 iobase1; - u16 iobase2; - u16 iomaster; - u8 irq; - u8 chanid; - int pci_bdf; -}; - -struct atadrive_s { - struct drive_s drive; - struct ata_channel_s *chan_gf; - u8 slave; -}; - -// ata.c -int cdrom_read(struct disk_op_s *op); -int atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); -void ata_setup(void); -int process_ata_op(struct disk_op_s *op); -int process_atapi_op(struct disk_op_s *op); - -// Global defines -- ATA register and register bits. -// command block & control block regs -#define ATA_CB_DATA 0 // data reg in/out pio_base_addr1+0 -#define ATA_CB_ERR 1 // error in pio_base_addr1+1 -#define ATA_CB_FR 1 // feature reg out pio_base_addr1+1 -#define ATA_CB_SC 2 // sector count in/out pio_base_addr1+2 -#define ATA_CB_SN 3 // sector number in/out pio_base_addr1+3 -#define ATA_CB_CL 4 // cylinder low in/out pio_base_addr1+4 -#define ATA_CB_CH 5 // cylinder high in/out pio_base_addr1+5 -#define ATA_CB_DH 6 // device head in/out pio_base_addr1+6 -#define ATA_CB_STAT 7 // primary status in pio_base_addr1+7 -#define ATA_CB_CMD 7 // command out pio_base_addr1+7 - -#define ATA_CB_ASTAT 2 // alternate status in pio_base_addr2+2 -#define ATA_CB_DC 2 // device control out pio_base_addr2+2 -#define ATA_CB_DA 3 // device address in pio_base_addr2+3 - -#define ATA_CB_ER_ICRC 0x80 // ATA Ultra DMA bad CRC -#define ATA_CB_ER_BBK 0x80 // ATA bad block -#define ATA_CB_ER_UNC 0x40 // ATA uncorrected error -#define ATA_CB_ER_MC 0x20 // ATA media change -#define ATA_CB_ER_IDNF 0x10 // ATA id not found -#define ATA_CB_ER_MCR 0x08 // ATA media change request -#define ATA_CB_ER_ABRT 0x04 // ATA command aborted -#define ATA_CB_ER_NTK0 0x02 // ATA track 0 not found -#define ATA_CB_ER_NDAM 0x01 // ATA address mark not found - -#define ATA_CB_ER_P_SNSKEY 0xf0 // ATAPI sense key (mask) -#define ATA_CB_ER_P_MCR 0x08 // ATAPI Media Change Request -#define ATA_CB_ER_P_ABRT 0x04 // ATAPI command abort -#define ATA_CB_ER_P_EOM 0x02 // ATAPI End of Media -#define ATA_CB_ER_P_ILI 0x01 // ATAPI Illegal Length Indication - -// ATAPI Interrupt Reason bits in the Sector Count reg (CB_SC) -#define ATA_CB_SC_P_TAG 0xf8 // ATAPI tag (mask) -#define ATA_CB_SC_P_REL 0x04 // ATAPI release -#define ATA_CB_SC_P_IO 0x02 // ATAPI I/O -#define ATA_CB_SC_P_CD 0x01 // ATAPI C/D - -// bits 7-4 of the device/head (CB_DH) reg -#define ATA_CB_DH_DEV0 0xa0 // select device 0 -#define ATA_CB_DH_DEV1 0xb0 // select device 1 -#define ATA_CB_DH_LBA 0x40 // use LBA - -// status reg (CB_STAT and CB_ASTAT) bits -#define ATA_CB_STAT_BSY 0x80 // busy -#define ATA_CB_STAT_RDY 0x40 // ready -#define ATA_CB_STAT_DF 0x20 // device fault -#define ATA_CB_STAT_WFT 0x20 // write fault (old name) -#define ATA_CB_STAT_SKC 0x10 // seek complete -#define ATA_CB_STAT_SERV 0x10 // service -#define ATA_CB_STAT_DRQ 0x08 // data request -#define ATA_CB_STAT_CORR 0x04 // corrected -#define ATA_CB_STAT_IDX 0x02 // index -#define ATA_CB_STAT_ERR 0x01 // error (ATA) -#define ATA_CB_STAT_CHK 0x01 // check (ATAPI) - -// device control reg (CB_DC) bits -#define ATA_CB_DC_HD15 0x08 // bit should always be set to one -#define ATA_CB_DC_SRST 0x04 // soft reset -#define ATA_CB_DC_NIEN 0x02 // disable interrupts - -// Most mandtory and optional ATA commands (from ATA-3), -#define ATA_CMD_NOP 0x00 -#define ATA_CMD_CFA_REQUEST_EXT_ERR_CODE 0x03 -#define ATA_CMD_DEVICE_RESET 0x08 -#define ATA_CMD_RECALIBRATE 0x10 -#define ATA_CMD_READ_SECTORS 0x20 -#define ATA_CMD_READ_SECTORS_EXT 0x24 -#define ATA_CMD_READ_DMA_EXT 0x25 -#define ATA_CMD_READ_DMA_QUEUED_EXT 0x26 -#define ATA_CMD_READ_NATIVE_MAX_ADDRESS_EXT 0x27 -#define ATA_CMD_READ_MULTIPLE_EXT 0x29 -#define ATA_CMD_READ_LOG_EXT 0x2F -#define ATA_CMD_WRITE_SECTORS 0x30 -#define ATA_CMD_WRITE_SECTORS_EXT 0x34 -#define ATA_CMD_WRITE_DMA_EXT 0x35 -#define ATA_CMD_WRITE_DMA_QUEUED_EXT 0x36 -#define ATA_CMD_SET_MAX_ADDRESS_EXT 0x37 -#define ATA_CMD_CFA_WRITE_SECTORS_WO_ERASE 0x38 -#define ATA_CMD_WRITE_MULTIPLE_EXT 0x39 -#define ATA_CMD_WRITE_VERIFY 0x3C -#define ATA_CMD_WRITE_LOG_EXT 0x3F -#define ATA_CMD_READ_VERIFY_SECTORS 0x40 -#define ATA_CMD_READ_VERIFY_SECTORS_EXT 0x42 -#define ATA_CMD_FORMAT_TRACK 0x50 -#define ATA_CMD_SEEK 0x70 -#define ATA_CMD_CFA_TRANSLATE_SECTOR 0x87 -#define ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC 0x90 -#define ATA_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91 -#define ATA_CMD_STANDBY_IMMEDIATE2 0x94 -#define ATA_CMD_IDLE_IMMEDIATE2 0x95 -#define ATA_CMD_STANDBY2 0x96 -#define ATA_CMD_IDLE2 0x97 -#define ATA_CMD_CHECK_POWER_MODE2 0x98 -#define ATA_CMD_SLEEP2 0x99 -#define ATA_CMD_PACKET 0xA0 -#define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1 -#define ATA_CMD_CFA_ERASE_SECTORS 0xC0 -#define ATA_CMD_READ_MULTIPLE 0xC4 -#define ATA_CMD_WRITE_MULTIPLE 0xC5 -#define ATA_CMD_SET_MULTIPLE_MODE 0xC6 -#define ATA_CMD_READ_DMA_QUEUED 0xC7 -#define ATA_CMD_READ_DMA 0xC8 -#define ATA_CMD_WRITE_DMA 0xCA -#define ATA_CMD_WRITE_DMA_QUEUED 0xCC -#define ATA_CMD_CFA_WRITE_MULTIPLE_WO_ERASE 0xCD -#define ATA_CMD_STANDBY_IMMEDIATE 0xE0 -#define ATA_CMD_IDLE_IMMEDIATE 0xE1 -#define ATA_CMD_STANDBY 0xE2 -#define ATA_CMD_IDLE 0xE3 -#define ATA_CMD_READ_BUFFER 0xE4 -#define ATA_CMD_CHECK_POWER_MODE 0xE5 -#define ATA_CMD_SLEEP 0xE6 -#define ATA_CMD_FLUSH_CACHE 0xE7 -#define ATA_CMD_WRITE_BUFFER 0xE8 -#define ATA_CMD_IDENTIFY_DEVICE 0xEC -#define ATA_CMD_SET_FEATURES 0xEF -#define ATA_CMD_READ_NATIVE_MAX_ADDRESS 0xF8 -#define ATA_CMD_SET_MAX 0xF9 - -#endif // ata.h diff --git a/roms/seabios/src/biosvar.h b/roms/seabios/src/biosvar.h deleted file mode 100644 index 2b755e3..0000000 --- a/roms/seabios/src/biosvar.h +++ /dev/null @@ -1,332 +0,0 @@ -// Variable layouts of bios. -// -// Copyright (C) 2008-2010 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __BIOSVAR_H -#define __BIOSVAR_H - -#include "types.h" // u8 -#include "farptr.h" // GET_FARVAR -#include "config.h" // CONFIG_* -#include "disk.h" // struct chs_s - - -/**************************************************************** - * Interupt vector table - ****************************************************************/ - -struct rmode_IVT { - struct segoff_s ivec[256]; -}; - -#define GET_IVT(vector) \ - GET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector]) -#define SET_IVT(vector, segoff) \ - SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector], segoff) - -#define FUNC16(func) ({ \ - ASSERT32FLAT(); \ - extern void func (void); \ - SEGOFF(SEG_BIOS, (u32)func - BUILD_BIOS_ADDR); \ - }) - - -/**************************************************************** - * Bios Data Area (BDA) - ****************************************************************/ - -struct bios_data_area_s { - // 40:00 - u16 port_com[4]; - u16 port_lpt[3]; - u16 ebda_seg; - // 40:10 - u16 equipment_list_flags; - u8 pad1; - u16 mem_size_kb; - u8 pad2; - u8 ps2_ctrl_flag; - u8 kbd_flag0; - u8 kbd_flag1; - u8 alt_keypad; - u16 kbd_buf_head; - u16 kbd_buf_tail; - // 40:1e - u8 kbd_buf[32]; - u8 floppy_recalibration_status; - u8 floppy_motor_status; - // 40:40 - u8 floppy_motor_counter; - u8 floppy_last_status; - u8 floppy_return_status[7]; - u8 video_mode; - u16 video_cols; - u16 video_pagesize; - u16 video_pagestart; - // 40:50 - u16 cursor_pos[8]; - // 40:60 - u16 cursor_type; - u8 video_page; - u16 crtc_address; - u8 video_msr; - u8 video_pal; - struct segoff_s jump; - u8 other_6b; - u32 timer_counter; - // 40:70 - u8 timer_rollover; - u8 break_flag; - u16 soft_reset_flag; - u8 disk_last_status; - u8 hdcount; - u8 disk_control_byte; - u8 port_disk; - u8 lpt_timeout[4]; - u8 com_timeout[4]; - // 40:80 - u16 kbd_buf_start_offset; - u16 kbd_buf_end_offset; - u8 video_rows; - u16 char_height; - u8 video_ctl; - u8 video_switches; - u8 modeset_ctl; - u8 dcc_index; - u8 floppy_last_data_rate; - u8 disk_status_controller; - u8 disk_error_controller; - u8 disk_interrupt_flag; - u8 floppy_harddisk_info; - // 40:90 - u8 floppy_media_state[4]; - u8 floppy_track[2]; - u8 kbd_flag2; - u8 kbd_led; - struct segoff_s user_wait_complete_flag; - u32 user_wait_timeout; - // 40:A0 - u8 rtc_wait_flag; - u8 other_a1[7]; - struct segoff_s video_savetable; - u8 other_ac[4]; - // 40:B0 - u8 other_b0[10]; - u16 vbe_mode; -} PACKED; - -// BDA floppy_recalibration_status bitdefs -#define FRS_TIMEOUT (1<<7) - -// BDA rtc_wait_flag bitdefs -#define RWS_WAIT_PENDING (1<<0) -#define RWS_WAIT_ELAPSED (1<<7) - -// BDA floppy_media_state bitdefs -#define FMS_DRIVE_STATE_MASK (0x07) -#define FMS_MEDIA_DRIVE_ESTABLISHED (1<<4) -#define FMS_DOUBLE_STEPPING (1<<5) -#define FMS_DATA_RATE_MASK (0xc0) - -// Accessor functions -#define GET_BDA(var) \ - GET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var) -#define SET_BDA(var, val) \ - SET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var, (val)) -#define CLEARBITS_BDA(var, val) do { \ - typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \ - SET_BDA(var, (__val & ~(val))); \ - } while (0) -#define SETBITS_BDA(var, val) do { \ - typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \ - SET_BDA(var, (__val | (val))); \ - } while (0) - - -/**************************************************************** - * Extended Bios Data Area (EBDA) - ****************************************************************/ - -// DPTE definition -struct dpte_s { - u16 iobase1; - u16 iobase2; - u8 prefix; - u8 unused; - u8 irq; - u8 blkcount; - u8 dma; - u8 pio; - u16 options; - u16 reserved; - u8 revision; - u8 checksum; -}; - -// ElTorito Device Emulation data -struct cdemu_s { - struct drive_s *emulated_drive_gf; - u32 ilba; - u16 buffer_segment; - u16 load_segment; - u16 sector_count; - u8 active; - u8 media; - u8 emulated_extdrive; - - // Virtual device - struct chs_s lchs; -}; - -struct fdpt_s { - u16 cylinders; - u8 heads; - u8 a0h_signature; - u8 phys_sectors; - u16 precompensation; - u8 reserved; - u8 drive_control_byte; - u16 phys_cylinders; - u8 phys_heads; - u16 landing_zone; - u8 sectors; - u8 checksum; -} PACKED; - -struct usbkeyinfo { - union { - struct { - u8 modifiers; - u8 repeatcount; - u8 keys[6]; - }; - u64 data; - }; -}; - -struct extended_bios_data_area_s { - u8 size; - u8 reserved1[0x21]; - struct segoff_s far_call_pointer; - u8 mouse_flag1; - u8 mouse_flag2; - u8 mouse_data[0x08]; - // 0x30 - u8 other1[0x0d]; - - // 0x3d - struct fdpt_s fdpt[2]; - - // 0x5d - u8 other2[0xC4]; - - // 0x121 - Begin custom storage. - u8 ps2ctr; - struct usbkeyinfo usbkey_last; - - int RTCusers; - - // El Torito Emulation data - struct cdemu_s cdemu; - - // Buffer for disk DPTE table - struct dpte_s dpte; - - // Locks for removable devices - u8 cdrom_locks[CONFIG_MAX_EXTDRIVE]; - - u16 boot_sequence; - - // Stack space available for code that needs it. - u8 extra_stack[512] __aligned(8); -} PACKED; - -// The initial size and location of EBDA -#define EBDA_SIZE_START \ - DIV_ROUND_UP(sizeof(struct extended_bios_data_area_s), 1024) -#define EBDA_SEGMENT_START \ - FLATPTR_TO_SEG(BUILD_LOWRAM_END - EBDA_SIZE_START*1024) - -// Accessor functions -static inline u16 get_ebda_seg(void) { - return GET_BDA(ebda_seg); -} -static inline struct extended_bios_data_area_s * -get_ebda_ptr(void) -{ - ASSERT32FLAT(); - return MAKE_FLATPTR(get_ebda_seg(), 0); -} -#define GET_EBDA2(eseg, var) \ - GET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var) -#define SET_EBDA2(eseg, var, val) \ - SET_FARVAR(eseg, ((struct extended_bios_data_area_s *)0)->var, (val)) -#define GET_EBDA(var) \ - GET_EBDA2(get_ebda_seg(), var) -#define SET_EBDA(var, val) \ - SET_EBDA2(get_ebda_seg(), var, (val)) - -#define EBDA_OFFSET_TOP_STACK \ - offsetof(struct extended_bios_data_area_s, extra_stack[ \ - FIELD_SIZEOF(struct extended_bios_data_area_s \ - , extra_stack)]) - - -/**************************************************************** - * Global variables - ****************************************************************/ - -#if MODE16 == 0 && MODESEGMENT == 1 -// In 32bit segmented mode %cs may not be readable and the code may be -// relocated. The entry code sets up %gs with a readable segment and -// the code offset can be determined by get_global_offset(). -#define GLOBAL_SEGREG GS -static inline u32 __attribute_const get_global_offset(void) { - u32 ret; - asm(" calll 1f\n" - "1:popl %0\n" - " subl $1b, %0" - : "=r"(ret)); - return ret; -} -#else -#define GLOBAL_SEGREG CS -static inline u32 __attribute_const get_global_offset(void) { - return 0; -} -#endif -static inline u16 get_global_seg(void) { - return GET_SEG(GLOBAL_SEGREG); -} -#define GET_GLOBAL(var) \ - GET_VAR(GLOBAL_SEGREG, *(typeof(&(var)))((void*)&(var) \ - + get_global_offset())) -#define SET_GLOBAL(var, val) do { \ - ASSERT32FLAT(); \ - (var) = (val); \ - } while (0) -#if MODESEGMENT -#define GLOBALFLAT2GLOBAL(var) ((typeof(var))((void*)(var) - BUILD_BIOS_ADDR)) -#else -#define GLOBALFLAT2GLOBAL(var) (var) -#endif -// Access a "flat" pointer known to point to the f-segment. -#define GET_GLOBALFLAT(var) GET_GLOBAL(*GLOBALFLAT2GLOBAL(&(var))) - - -/**************************************************************** - * Bios Config Table - ****************************************************************/ - -struct bios_config_table_s { - u16 size; - u8 model; - u8 submodel; - u8 biosrev; - u8 feature1, feature2, feature3, feature4, feature5; -} PACKED; - -extern struct bios_config_table_s BIOS_CONFIG_TABLE __aligned(1); - -#endif // __BIOSVAR_H diff --git a/roms/seabios/src/block.c b/roms/seabios/src/block.c deleted file mode 100644 index b6b1902..0000000 --- a/roms/seabios/src/block.c +++ /dev/null @@ -1,342 +0,0 @@ -// Disk setup and access -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "disk.h" // struct ata_s -#include "biosvar.h" // GET_GLOBAL -#include "cmos.h" // inb_cmos -#include "util.h" // dprintf -#include "ata.h" // process_ata_op -#include "usb-msc.h" // process_usb_op -#include "virtio-blk.h" // process_virtio_op - -struct drives_s Drives VAR16VISIBLE; - -struct drive_s * -getDrive(u8 exttype, u8 extdriveoffset) -{ - if (extdriveoffset >= ARRAY_SIZE(Drives.idmap[0])) - return NULL; - struct drive_s *drive_gf = GET_GLOBAL(Drives.idmap[exttype][extdriveoffset]); - if (!drive_gf) - return NULL; - return GLOBALFLAT2GLOBAL(drive_gf); -} - - -/**************************************************************** - * Disk geometry translation - ****************************************************************/ - -static u8 -get_translation(struct drive_s *drive_g) -{ - u8 type = GET_GLOBAL(drive_g->type); - if (! CONFIG_COREBOOT && type == DTYPE_ATA) { - // Emulators pass in the translation info via nvram. - u8 ataid = GET_GLOBAL(drive_g->cntl_id); - u8 channel = ataid / 2; - u8 translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2); - translation >>= 2 * (ataid % 4); - translation &= 0x03; - return translation; - } - - // Otherwise use a heuristic to determine translation type. - u16 heads = GET_GLOBAL(drive_g->pchs.heads); - u16 cylinders = GET_GLOBAL(drive_g->pchs.cylinders); - u16 spt = GET_GLOBAL(drive_g->pchs.spt); - u64 sectors = GET_GLOBAL(drive_g->sectors); - u64 psectors = (u64)heads * cylinders * spt; - if (!heads || !cylinders || !spt || psectors > sectors) - // pchs doesn't look valid - use LBA. - return TRANSLATION_LBA; - - if (cylinders <= 1024 && heads <= 16 && spt <= 63) - return TRANSLATION_NONE; - if (cylinders * heads <= 131072) - return TRANSLATION_LARGE; - return TRANSLATION_LBA; -} - -void -setup_translation(struct drive_s *drive_g) -{ - u8 translation = get_translation(drive_g); - SET_GLOBAL(drive_g->translation, translation); - - u16 heads = GET_GLOBAL(drive_g->pchs.heads); - u16 cylinders = GET_GLOBAL(drive_g->pchs.cylinders); - u16 spt = GET_GLOBAL(drive_g->pchs.spt); - u64 sectors = GET_GLOBAL(drive_g->sectors); - const char *desc = NULL; - - switch (translation) { - default: - case TRANSLATION_NONE: - desc = "none"; - break; - case TRANSLATION_LBA: - desc = "lba"; - spt = 63; - if (sectors > 63*255*1024) { - heads = 255; - cylinders = 1024; - break; - } - u32 sect = (u32)sectors / 63; - heads = sect / 1024; - if (heads>128) - heads = 255; - else if (heads>64) - heads = 128; - else if (heads>32) - heads = 64; - else if (heads>16) - heads = 32; - else - heads = 16; - cylinders = sect / heads; - break; - case TRANSLATION_RECHS: - desc = "r-echs"; - // Take care not to overflow - if (heads==16) { - if (cylinders>61439) - cylinders=61439; - heads=15; - cylinders = (u16)((u32)(cylinders)*16/15); - } - // then go through the large bitshift process - case TRANSLATION_LARGE: - if (translation == TRANSLATION_LARGE) - desc = "large"; - while (cylinders > 1024) { - cylinders >>= 1; - heads <<= 1; - - // If we max out the head count - if (heads > 127) - break; - } - break; - } - // clip to 1024 cylinders in lchs - if (cylinders > 1024) - cylinders = 1024; - dprintf(1, "drive %p: PCHS=%u/%d/%d translation=%s LCHS=%d/%d/%d s=%d\n" - , drive_g - , drive_g->pchs.cylinders, drive_g->pchs.heads, drive_g->pchs.spt - , desc - , cylinders, heads, spt - , (u32)sectors); - - SET_GLOBAL(drive_g->lchs.heads, heads); - SET_GLOBAL(drive_g->lchs.cylinders, cylinders); - SET_GLOBAL(drive_g->lchs.spt, spt); -} - - -/**************************************************************** - * Drive mapping - ****************************************************************/ - -// Fill in Fixed Disk Parameter Table (located in ebda). -static void -fill_fdpt(struct drive_s *drive_g, int hdid) -{ - if (hdid > 1) - return; - - u16 nlc = GET_GLOBAL(drive_g->lchs.cylinders); - u16 nlh = GET_GLOBAL(drive_g->lchs.heads); - u16 nlspt = GET_GLOBAL(drive_g->lchs.spt); - - u16 npc = GET_GLOBAL(drive_g->pchs.cylinders); - u16 nph = GET_GLOBAL(drive_g->pchs.heads); - u16 npspt = GET_GLOBAL(drive_g->pchs.spt); - - struct fdpt_s *fdpt = &get_ebda_ptr()->fdpt[hdid]; - fdpt->precompensation = 0xffff; - fdpt->drive_control_byte = 0xc0 | ((nph > 8) << 3); - fdpt->landing_zone = npc; - fdpt->cylinders = nlc; - fdpt->heads = nlh; - fdpt->sectors = nlspt; - - if (nlc != npc || nlh != nph || nlspt != npspt) { - // Logical mapping present - use extended structure. - - // complies with Phoenix style Translated Fixed Disk Parameter - // Table (FDPT) - fdpt->phys_cylinders = npc; - fdpt->phys_heads = nph; - fdpt->phys_sectors = npspt; - fdpt->a0h_signature = 0xa0; - - // Checksum structure. - fdpt->checksum -= checksum(fdpt, sizeof(*fdpt)); - } - - if (hdid == 0) - SET_IVT(0x41, SEGOFF(get_ebda_seg(), offsetof( - struct extended_bios_data_area_s, fdpt[0]))); - else - SET_IVT(0x46, SEGOFF(get_ebda_seg(), offsetof( - struct extended_bios_data_area_s, fdpt[1]))); -} - -// Map a drive (that was registered via add_bcv_hd) -void -map_hd_drive(struct drive_s *drive_g) -{ - // fill hdidmap - u8 hdcount = GET_BDA(hdcount); - if (hdcount >= ARRAY_SIZE(Drives.idmap[0])) { - warn_noalloc(); - return; - } - dprintf(3, "Mapping hd drive %p to %d\n", drive_g, hdcount); - Drives.idmap[EXTTYPE_HD][hdcount] = drive_g; - SET_BDA(hdcount, hdcount + 1); - - // Fill "fdpt" structure. - fill_fdpt(drive_g, hdcount); -} - -// Find spot to add a drive -static void -add_ordered_drive(struct drive_s **idmap, u8 *count, struct drive_s *drive_g) -{ - if (*count >= ARRAY_SIZE(Drives.idmap[0])) { - warn_noalloc(); - return; - } - struct drive_s **pos = &idmap[*count]; - *count = *count + 1; - if (CONFIG_THREADS) { - // Add to idmap with assured drive order. - struct drive_s **end = pos; - for (;;) { - struct drive_s **prev = pos - 1; - if (prev < idmap) - break; - struct drive_s *prevdrive = *prev; - if (prevdrive->type < drive_g->type - || (prevdrive->type == drive_g->type - && prevdrive->cntl_id < drive_g->cntl_id)) - break; - pos--; - } - if (pos != end) - memmove(pos+1, pos, (void*)end-(void*)pos); - } - *pos = drive_g; -} - -// Map a cd -void -map_cd_drive(struct drive_s *drive_g) -{ - dprintf(3, "Mapping cd drive %p\n", drive_g); - add_ordered_drive(Drives.idmap[EXTTYPE_CD], &Drives.cdcount, drive_g); -} - -// Map a floppy -void -map_floppy_drive(struct drive_s *drive_g) -{ - // fill idmap - dprintf(3, "Mapping floppy drive %p\n", drive_g); - add_ordered_drive(Drives.idmap[EXTTYPE_FLOPPY], &Drives.floppycount - , drive_g); - - // Update equipment word bits for floppy - if (Drives.floppycount == 1) { - // 1 drive, ready for boot - SETBITS_BDA(equipment_list_flags, 0x01); - SET_BDA(floppy_harddisk_info, 0x07); - } else if (Drives.floppycount >= 2) { - // 2 drives, ready for boot - SETBITS_BDA(equipment_list_flags, 0x41); - SET_BDA(floppy_harddisk_info, 0x77); - } -} - - -/**************************************************************** - * 16bit calling interface - ****************************************************************/ - -// Execute a disk_op request. -int -process_op(struct disk_op_s *op) -{ - ASSERT16(); - u8 type = GET_GLOBAL(op->drive_g->type); - switch (type) { - case DTYPE_FLOPPY: - return process_floppy_op(op); - case DTYPE_ATA: - return process_ata_op(op); - case DTYPE_ATAPI: - return process_atapi_op(op); - case DTYPE_RAMDISK: - return process_ramdisk_op(op); - case DTYPE_CDEMU: - return process_cdemu_op(op); - case DTYPE_USB: - return process_usb_op(op); - case DTYPE_VIRTIO: - return process_virtio_op(op); - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} - -// Execute a "disk_op_s" request - this runs on a stack in the ebda. -static int -__send_disk_op(struct disk_op_s *op_far, u16 op_seg) -{ - struct disk_op_s dop; - memcpy_far(GET_SEG(SS), &dop - , op_seg, op_far - , sizeof(dop)); - - dprintf(DEBUG_HDL_13, "disk_op d=%p lba=%d buf=%p count=%d cmd=%d\n" - , dop.drive_g, (u32)dop.lba, dop.buf_fl - , dop.count, dop.command); - - int status = process_op(&dop); - - // Update count with total sectors transferred. - SET_FARVAR(op_seg, op_far->count, dop.count); - - return status; -} - -// Execute a "disk_op_s" request by jumping to a stack in the ebda. -int -send_disk_op(struct disk_op_s *op) -{ - ASSERT16(); - if (! CONFIG_DRIVES) - return -1; - - return stack_hop((u32)op, GET_SEG(SS), __send_disk_op); -} - - -/**************************************************************** - * Setup - ****************************************************************/ - -void -drive_setup(void) -{ - memset(&Drives, 0, sizeof(Drives)); -} diff --git a/roms/seabios/src/blockcmd.c b/roms/seabios/src/blockcmd.c deleted file mode 100644 index 48568e6..0000000 --- a/roms/seabios/src/blockcmd.c +++ /dev/null @@ -1,78 +0,0 @@ -// Support for several common scsi like command data block requests -// -// Copyright (C) 2010 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "biosvar.h" // GET_GLOBAL -#include "util.h" // htonl -#include "disk.h" // struct disk_op_s -#include "blockcmd.h" // struct cdb_request_sense -#include "ata.h" // atapi_cmd_data -#include "usb-msc.h" // usb_cmd_data - -// Route command to low-level handler. -static int -cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize) -{ - u8 type = GET_GLOBAL(op->drive_g->type); - switch (type) { - case DTYPE_ATAPI: - return atapi_cmd_data(op, cdbcmd, blocksize); - case DTYPE_USB: - return usb_cmd_data(op, cdbcmd, blocksize); - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} - -int -cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data) -{ - struct cdb_request_sense cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = CDB_CMD_INQUIRY; - cmd.length = sizeof(*data); - op->count = 1; - op->buf_fl = data; - return cdb_cmd_data(op, &cmd, sizeof(*data)); -} - -// Request SENSE -int -cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data) -{ - struct cdb_request_sense cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = CDB_CMD_REQUEST_SENSE; - cmd.length = sizeof(*data); - op->count = 1; - op->buf_fl = data; - return cdb_cmd_data(op, &cmd, sizeof(*data)); -} - -// Request capacity -int -cdb_read_capacity(struct disk_op_s *op, struct cdbres_read_capacity *data) -{ - struct cdb_read_capacity cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = CDB_CMD_READ_CAPACITY; - op->count = 1; - op->buf_fl = data; - return cdb_cmd_data(op, &cmd, sizeof(*data)); -} - -// Read sectors. -int -cdb_read(struct disk_op_s *op) -{ - struct cdb_rwdata_10 cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.command = CDB_CMD_READ_10; - cmd.lba = htonl(op->lba); - cmd.count = htons(op->count); - return cdb_cmd_data(op, &cmd, GET_GLOBAL(op->drive_g->blksize)); -} diff --git a/roms/seabios/src/blockcmd.h b/roms/seabios/src/blockcmd.h deleted file mode 100644 index 903c435..0000000 --- a/roms/seabios/src/blockcmd.h +++ /dev/null @@ -1,77 +0,0 @@ -// Definitions for SCSI style command data blocks. -#ifndef __BLOCKCMD_H -#define __BLOCKCMD_H - -#include "types.h" // u8 - -#define CDB_CMD_READ_10 0x28 -#define CDB_CMD_VERIFY_10 0x2f -#define CDB_CMD_WRITE_10 0x2a - -struct cdb_rwdata_10 { - u8 command; - u8 flags; - u32 lba; - u8 resreved_06; - u16 count; - u8 reserved_09; - u8 pad[6]; -} PACKED; - -#define CDB_CMD_READ_CAPACITY 0x25 - -struct cdb_read_capacity { - u8 command; - u8 flags; - u8 resreved_02[8]; - u8 pad[6]; -} PACKED; - -struct cdbres_read_capacity { - u32 sectors; - u32 blksize; -} PACKED; - -#define CDB_CMD_INQUIRY 0x12 -#define CDB_CMD_REQUEST_SENSE 0x03 - -struct cdb_request_sense { - u8 command; - u8 flags; - u16 reserved_02; - u8 length; - u8 reserved_05; - u8 pad[10]; -} PACKED; - -struct cdbres_request_sense { - u8 errcode; - u8 segment; - u8 flags; - u32 info; - u8 additional; - u32 specific; - u8 asc; - u8 ascq; - u32 reserved_0e; -} PACKED; - -struct cdbres_inquiry { - u8 pdt; - u8 removable; - u8 reserved_02[2]; - u8 additional; - u8 reserved_05[3]; - char vendor[8]; - char product[16]; - char rev[4]; -} PACKED; - -// blockcmd.c -int cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data); -int cdb_get_sense(struct disk_op_s *op, struct cdbres_request_sense *data); -int cdb_read_capacity(struct disk_op_s *op, struct cdbres_read_capacity *data); -int cdb_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data); -int cdb_read(struct disk_op_s *op); - -#endif // blockcmd.h diff --git a/roms/seabios/src/boot.c b/roms/seabios/src/boot.c deleted file mode 100644 index 021b8ac..0000000 --- a/roms/seabios/src/boot.c +++ /dev/null @@ -1,508 +0,0 @@ -// Code to load disk image and start system boot. -// -// Copyright (C) 2008-2010 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA -#include "config.h" // CONFIG_* -#include "disk.h" // cdrom_boot -#include "bregs.h" // struct bregs -#include "boot.h" // struct ipl_s -#include "cmos.h" // inb_cmos -#include "paravirt.h" - -struct ipl_s IPL; - - -/**************************************************************** - * IPL and BCV handlers - ****************************************************************/ - -void -boot_setup(void) -{ - if (! CONFIG_BOOT) - return; - dprintf(3, "init boot device ordering\n"); - - memset(&IPL, 0, sizeof(IPL)); - struct ipl_entry_s *ie = &IPL.bev[0]; - - // Floppy drive - ie->type = IPL_TYPE_FLOPPY; - ie->description = "Floppy"; - ie++; - - // First HDD - ie->type = IPL_TYPE_HARDDISK; - ie->description = "Hard Disk"; - ie++; - - // CDROM - if (CONFIG_CDROM_BOOT) { - ie->type = IPL_TYPE_CDROM; - ie->description = "DVD/CD"; - ie++; - } - - if (CONFIG_COREBOOT && CONFIG_COREBOOT_FLASH) { - ie->type = IPL_TYPE_CBFS; - ie->description = "CBFS"; - ie++; - } - - IPL.bevcount = ie - IPL.bev; - SET_EBDA(boot_sequence, 0xffff); - if (CONFIG_COREBOOT) { - // XXX - hardcode defaults for coreboot. - IPL.bootorder = 0x87654231; - IPL.checkfloppysig = 1; - } else { - // On emulators, get boot order from nvram. - IPL.bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2) - | ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4)); - if (!(inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1)) - IPL.checkfloppysig = 1; - } -} - -// Add a BEV vector for a given pnp compatible option rom. -void -add_bev(u16 seg, u16 bev, u16 desc) -{ - if (! CONFIG_BOOT) - return; - if (IPL.bevcount >= ARRAY_SIZE(IPL.bev)) - return; - - struct ipl_entry_s *ie = &IPL.bev[IPL.bevcount++]; - ie->type = IPL_TYPE_BEV; - ie->vector = (seg << 16) | bev; - const char *d = "Unknown"; - if (desc) - d = MAKE_FLATPTR(seg, desc); - ie->description = d; -} - -// Add a bcv entry for an expansion card harddrive or legacy option rom -void -add_bcv(u16 seg, u16 ip, u16 desc) -{ - if (! CONFIG_BOOT) - return; - if (IPL.bcvcount >= ARRAY_SIZE(IPL.bcv)) - return; - - struct ipl_entry_s *ie = &IPL.bcv[IPL.bcvcount++]; - ie->type = BCV_TYPE_EXTERNAL; - ie->vector = (seg << 16) | ip; - const char *d = "Legacy option rom"; - if (desc) - d = MAKE_FLATPTR(seg, desc); - ie->description = d; -} - -// Add a bcv entry for an internal harddrive -void -add_bcv_internal(struct drive_s *drive_g) -{ - if (! CONFIG_BOOT) - return; - if (IPL.bcvcount >= ARRAY_SIZE(IPL.bcv)) - return; - - struct ipl_entry_s *ie = &IPL.bcv[IPL.bcvcount++]; - if (CONFIG_THREADS) { - // Add to bcv list with assured drive order. - struct ipl_entry_s *end = ie; - for (;;) { - struct ipl_entry_s *prev = ie - 1; - if (prev < IPL.bcv || prev->type != BCV_TYPE_INTERNAL) - break; - struct drive_s *prevdrive = (void*)prev->vector; - if (prevdrive->type < drive_g->type - || (prevdrive->type == drive_g->type - && prevdrive->cntl_id < drive_g->cntl_id)) - break; - ie--; - } - if (ie != end) - memmove(ie+1, ie, (void*)end-(void*)ie); - } - ie->type = BCV_TYPE_INTERNAL; - ie->vector = (u32)drive_g; - ie->description = ""; -} - - -/**************************************************************** - * Boot menu and BCV execution - ****************************************************************/ - -// Show a generic menu item -static int -menu_show_default(struct ipl_entry_s *ie, int menupos) -{ - char desc[33]; - printf("%d. %s\n", menupos - , strtcpy(desc, ie->description, ARRAY_SIZE(desc))); - return 1; -} - -// Show floppy menu item - but only if there exists a floppy drive. -static int -menu_show_floppy(struct ipl_entry_s *ie, int menupos) -{ - int i; - for (i = 0; i < Drives.floppycount; i++) { - struct drive_s *drive_g = getDrive(EXTTYPE_FLOPPY, i); - printf("%d. Floppy [%s]\n", menupos + i, drive_g->desc); - } - return Drives.floppycount; -} - -// Show menu items from BCV list. -static int -menu_show_harddisk(struct ipl_entry_s *ie, int menupos) -{ - int i; - for (i = 0; i < IPL.bcvcount; i++) { - struct ipl_entry_s *ie = &IPL.bcv[i]; - struct drive_s *drive_g = (void*)ie->vector; - switch (ie->type) { - case BCV_TYPE_INTERNAL: - printf("%d. %s\n", menupos + i, drive_g->desc); - break; - default: - menu_show_default(ie, menupos+i); - break; - } - } - return IPL.bcvcount; -} - -// Show cdrom menu item - but only if there exists a cdrom drive. -static int -menu_show_cdrom(struct ipl_entry_s *ie, int menupos) -{ - int i; - for (i = 0; i < Drives.cdcount; i++) { - struct drive_s *drive_g = getDrive(EXTTYPE_CD, i); - printf("%d. DVD/CD [%s]\n", menupos + i, drive_g->desc); - } - return Drives.cdcount; -} - -// Show coreboot-fs menu item. -static int -menu_show_cbfs(struct ipl_entry_s *ie, int menupos) -{ - int count = 0; - struct cbfs_file *file = NULL; - for (;;) { - file = cbfs_findprefix("img/", file); - if (!file) - break; - const char *filename = cbfs_filename(file); - printf("%d. Payload [%s]\n", menupos + count, &filename[4]); - count++; - if (count > 8) - break; - } - return count; -} - -// Show IPL option menu. -static void -interactive_bootmenu(void) -{ - if (! CONFIG_BOOTMENU || ! qemu_cfg_show_boot_menu()) - return; - - while (get_keystroke(0) >= 0) - ; - - printf("Press F12 for boot menu.\n\n"); - - enable_bootsplash(); - int scan_code = get_keystroke(CONFIG_BOOTMENU_WAIT); - disable_bootsplash(); - if (scan_code != 0x86) - /* not F12 */ - return; - - while (get_keystroke(0) >= 0) - ; - - printf("Select boot device:\n\n"); - wait_threads(); - - int subcount[ARRAY_SIZE(IPL.bev)]; - int menupos = 1; - int i; - for (i = 0; i < IPL.bevcount; i++) { - struct ipl_entry_s *ie = &IPL.bev[i]; - int sc; - switch (ie->type) { - case IPL_TYPE_FLOPPY: - sc = menu_show_floppy(ie, menupos); - break; - case IPL_TYPE_HARDDISK: - sc = menu_show_harddisk(ie, menupos); - break; - case IPL_TYPE_CDROM: - sc = menu_show_cdrom(ie, menupos); - break; - case IPL_TYPE_CBFS: - sc = menu_show_cbfs(ie, menupos); - break; - default: - sc = menu_show_default(ie, menupos); - break; - } - subcount[i] = sc; - menupos += sc; - } - - for (;;) { - scan_code = get_keystroke(1000); - if (scan_code == 0x01) - // ESC - break; - if (scan_code < 1 || scan_code > menupos) - continue; - int choice = scan_code - 1; - - // Find out which IPL this was for. - int bev = 0; - while (choice > subcount[bev]) { - choice -= subcount[bev]; - bev++; - } - IPL.bev[bev].subchoice = choice-1; - - // Add user choice to the boot order. - IPL.bootorder = (IPL.bootorder << 4) | (bev+1); - break; - } - printf("\n"); -} - -// Run the specified bcv. -static void -run_bcv(struct ipl_entry_s *ie) -{ - switch (ie->type) { - case BCV_TYPE_INTERNAL: - map_hd_drive((void*)ie->vector); - break; - case BCV_TYPE_EXTERNAL: - call_bcv(ie->vector >> 16, ie->vector & 0xffff); - break; - } -} - -// Prepare for boot - show menu and run bcvs. -void -boot_prep(void) -{ - if (! CONFIG_BOOT) { - wait_threads(); - return; - } - - // XXX - show available drives? - - // Allow user to modify BCV/IPL order. - interactive_bootmenu(); - wait_threads(); - - // Setup floppy boot order - int override = IPL.bev[0].subchoice; - struct drive_s *tmp = Drives.idmap[EXTTYPE_FLOPPY][0]; - Drives.idmap[EXTTYPE_FLOPPY][0] = Drives.idmap[EXTTYPE_FLOPPY][override]; - Drives.idmap[EXTTYPE_FLOPPY][override] = tmp; - - // Run BCVs - override = IPL.bev[1].subchoice; - if (override < IPL.bcvcount) - run_bcv(&IPL.bcv[override]); - int i; - for (i=0; isignature) != MBR_SIGNATURE) { - printf("Boot failed: not a bootable disk\n\n"); - return; - } - } - - /* Canonicalize bootseg:bootip */ - u16 bootip = (bootseg & 0x0fff) << 4; - bootseg &= 0xf000; - - call_boot_entry(bootseg, bootip, bootdrv); -} - -// Boot from a CD-ROM -static void -boot_cdrom(struct ipl_entry_s *ie) -{ - if (! CONFIG_CDROM_BOOT) - return; - int status = cdrom_boot(ie->subchoice); - if (status) { - printf("Boot failed: Could not read from CDROM (code %04x)\n", status); - return; - } - - u16 ebda_seg = get_ebda_seg(); - u8 bootdrv = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); - u16 bootseg = GET_EBDA2(ebda_seg, cdemu.load_segment); - /* Canonicalize bootseg:bootip */ - u16 bootip = (bootseg & 0x0fff) << 4; - bootseg &= 0xf000; - - call_boot_entry(bootseg, bootip, bootdrv); -} - -// Boot from a CBFS payload -static void -boot_cbfs(struct ipl_entry_s *ie) -{ - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) - return; - int count = ie->subchoice; - struct cbfs_file *file = NULL; - for (;;) { - file = cbfs_findprefix("img/", file); - if (!file) - return; - if (count--) - continue; - cbfs_run_payload(file); - } -} - -static void -do_boot(u16 seq_nr) -{ - if (! CONFIG_BOOT) - panic("Boot support not compiled in.\n"); - - u32 bootdev = IPL.bootorder; - bootdev >>= 4 * seq_nr; - bootdev &= 0xf; - - /* Translate bootdev to an IPL table offset by subtracting 1 */ - bootdev -= 1; - - if (bootdev >= IPL.bevcount) { - printf("No bootable device.\n"); - // Loop with irqs enabled - this allows ctrl+alt+delete to work. - for (;;) - wait_irq(); - } - - /* Do the loading, and set up vector as a far pointer to the boot - * address, and bootdrv as the boot drive */ - struct ipl_entry_s *ie = &IPL.bev[bootdev]; - char desc[33]; - printf("Booting from %s...\n" - , strtcpy(desc, ie->description, ARRAY_SIZE(desc))); - - switch (ie->type) { - case IPL_TYPE_FLOPPY: - boot_disk(0x00, IPL.checkfloppysig); - break; - case IPL_TYPE_HARDDISK: - boot_disk(0x80, 1); - break; - case IPL_TYPE_CDROM: - boot_cdrom(ie); - break; - case IPL_TYPE_CBFS: - boot_cbfs(ie); - break; - case IPL_TYPE_BEV: - call_boot_entry(ie->vector >> 16, ie->vector & 0xffff, 0); - break; - } - - // Boot failed: invoke the boot recovery function - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_IF; - call16_int(0x18, &br); -} - -// Boot Failure recovery: try the next device. -void VISIBLE32FLAT -handle_18(void) -{ - debug_serial_setup(); - debug_enter(NULL, DEBUG_HDL_18); - u16 ebda_seg = get_ebda_seg(); - u16 seq = GET_EBDA2(ebda_seg, boot_sequence) + 1; - SET_EBDA2(ebda_seg, boot_sequence, seq); - do_boot(seq); -} - -// INT 19h Boot Load Service Entry Point -void VISIBLE32FLAT -handle_19(void) -{ - debug_serial_setup(); - debug_enter(NULL, DEBUG_HDL_19); - SET_EBDA(boot_sequence, 0); - do_boot(0); -} diff --git a/roms/seabios/src/boot.h b/roms/seabios/src/boot.h deleted file mode 100644 index db046e3..0000000 --- a/roms/seabios/src/boot.h +++ /dev/null @@ -1,48 +0,0 @@ -// Storage for boot definitions. -#ifndef __BOOT_H -#define __BOOT_H - - -/**************************************************************** - * Initial Program Load (IPL) - ****************************************************************/ - -struct ipl_entry_s { - u16 type; - u16 subchoice; - u32 vector; - const char *description; -}; - -struct ipl_s { - struct ipl_entry_s bev[8]; - struct ipl_entry_s bcv[8]; - int bevcount, bcvcount; - u32 bootorder; - int checkfloppysig; -}; - -#define IPL_TYPE_FLOPPY 0x01 -#define IPL_TYPE_HARDDISK 0x02 -#define IPL_TYPE_CDROM 0x03 -#define IPL_TYPE_CBFS 0x20 -#define IPL_TYPE_BEV 0x80 - -#define BCV_TYPE_EXTERNAL 0x80 -#define BCV_TYPE_INTERNAL 0x02 - - -/**************************************************************** - * Function defs - ****************************************************************/ - -// boot.c -extern struct ipl_s IPL; -void boot_setup(void); -void add_bev(u16 seg, u16 bev, u16 desc); -void add_bcv(u16 seg, u16 ip, u16 desc); -struct drive_s; -void add_bcv_internal(struct drive_s *drive_g); -void boot_prep(void); - -#endif // __BOOT_H diff --git a/roms/seabios/src/bootsplash.c b/roms/seabios/src/bootsplash.c deleted file mode 100644 index 8f42dfd..0000000 --- a/roms/seabios/src/bootsplash.c +++ /dev/null @@ -1,258 +0,0 @@ -// Option rom scanning code. -// -// Copyright (C) 2009-2010 coresystems GmbH -// Copyright (C) 2010 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "bregs.h" // struct bregs -#include "farptr.h" // FLATPTR_TO_SEG -#include "config.h" // CONFIG_* -#include "util.h" // dprintf -#include "jpeg.h" // splash -#include "biosvar.h" // SET_EBDA -#include "paravirt.h" // romfile_find - - -/**************************************************************** - * VESA structures - ****************************************************************/ - -struct vesa_info { - u32 vesa_signature; - u16 vesa_version; - struct segoff_s oem_string_ptr; - u8 capabilities[4]; - struct segoff_s video_mode_ptr; - u16 total_memory; - u16 oem_software_rev; - struct segoff_s oem_vendor_name_ptr; - struct segoff_s oem_product_name_ptr; - struct segoff_s oem_product_rev_ptr; - u8 reserved[222]; - u8 oem_data[256]; -} PACKED; - -#define VESA_SIGNATURE 0x41534556 // VESA -#define VBE2_SIGNATURE 0x32454256 // VBE2 - -struct vesa_mode_info { - u16 mode_attributes; - u8 win_a_attributes; - u8 win_b_attributes; - u16 win_granularity; - u16 win_size; - u16 win_a_segment; - u16 win_b_segment; - u32 win_func_ptr; - u16 bytes_per_scanline; - u16 x_resolution; - u16 y_resolution; - u8 x_charsize; - u8 y_charsize; - u8 number_of_planes; - u8 bits_per_pixel; - u8 number_of_banks; - u8 memory_model; - u8 bank_size; - u8 number_of_image_pages; - u8 reserved_page; - u8 red_mask_size; - u8 red_mask_pos; - u8 green_mask_size; - u8 green_mask_pos; - u8 blue_mask_size; - u8 blue_mask_pos; - u8 reserved_mask_size; - u8 reserved_mask_pos; - u8 direct_color_mode_info; - void *phys_base_ptr; - u32 offscreen_mem_offset; - u16 offscreen_mem_size; - u8 reserved[206]; -} PACKED; - - -/**************************************************************** - * Helper functions - ****************************************************************/ - -// Call int10 vga handler. -static void -call16_int10(struct bregs *br) -{ - br->flags = F_IF; - start_preempt(); - call16_int(0x10, br); - finish_preempt(); -} - - -/**************************************************************** - * VGA text / graphics console - ****************************************************************/ - -void -enable_vga_console(void) -{ - dprintf(1, "Turning on vga text mode console\n"); - struct bregs br; - - /* Enable VGA text mode */ - memset(&br, 0, sizeof(br)); - br.ax = 0x0003; - call16_int10(&br); - - // Write to screen. - printf("SeaBIOS (version %s)\n\n", VERSION); -} - -static int -find_videomode(struct vesa_info *vesa_info, struct vesa_mode_info *mode_info - , int width, int height) -{ - dprintf(3, "Finding vesa mode with dimensions %d/%d\n", width, height); - u16 *videomodes = SEGOFF_TO_FLATPTR(vesa_info->video_mode_ptr); - for (;; videomodes++) { - u16 videomode = *videomodes; - if (videomode == 0xffff) { - dprintf(1, "Unable to find vesa video mode dimensions %d/%d\n" - , width, height); - return -1; - } - struct bregs br; - memset(&br, 0, sizeof(br)); - br.ax = 0x4f01; - br.cx = (1 << 14) | videomode; - br.di = FLATPTR_TO_OFFSET(mode_info); - br.es = FLATPTR_TO_SEG(mode_info); - call16_int10(&br); - if (br.ax != 0x4f) { - dprintf(1, "get_mode failed.\n"); - continue; - } - if (mode_info->x_resolution != width - || mode_info->y_resolution != height) - continue; - u8 depth = mode_info->bits_per_pixel; - if (depth != 16 && depth != 24 && depth != 32) - continue; - return videomode; - } -} - -static int BootsplashActive; - -void -enable_bootsplash(void) -{ - if (!CONFIG_BOOTSPLASH) - return; - dprintf(3, "Checking for bootsplash\n"); - u32 file = romfile_find("bootsplash.jpg"); - if (!file) - return; - int filesize = romfile_size(file); - - u8 *picture = NULL; - u8 *filedata = malloc_tmphigh(filesize); - struct vesa_info *vesa_info = malloc_tmplow(sizeof(*vesa_info)); - struct vesa_mode_info *mode_info = malloc_tmplow(sizeof(*mode_info)); - struct jpeg_decdata *jpeg = jpeg_alloc(); - if (!filedata || !jpeg || !vesa_info || !mode_info) { - warn_noalloc(); - goto done; - } - - /* Check whether we have a VESA 2.0 compliant BIOS */ - memset(vesa_info, 0, sizeof(struct vesa_info)); - vesa_info->vesa_signature = VBE2_SIGNATURE; - struct bregs br; - memset(&br, 0, sizeof(br)); - br.ax = 0x4f00; - br.di = FLATPTR_TO_OFFSET(vesa_info); - br.es = FLATPTR_TO_SEG(vesa_info); - call16_int10(&br); - if (vesa_info->vesa_signature != VESA_SIGNATURE) { - dprintf(1,"No VBE2 found.\n"); - goto done; - } - - /* Print some debugging information about our card. */ - char *vendor = SEGOFF_TO_FLATPTR(vesa_info->oem_vendor_name_ptr); - char *product = SEGOFF_TO_FLATPTR(vesa_info->oem_product_name_ptr); - dprintf(3, "VESA %d.%d\nVENDOR: %s\nPRODUCT: %s\n", - vesa_info->vesa_version>>8, vesa_info->vesa_version&0xff, - vendor, product); - - // Parse jpeg and get image size. - dprintf(5, "Copying bootsplash.jpg\n"); - romfile_copy(file, filedata, filesize); - dprintf(5, "Decoding bootsplash.jpg\n"); - int ret = jpeg_decode(jpeg, filedata); - if (ret) { - dprintf(1, "jpeg_decode failed with return code %d...\n", ret); - goto done; - } - int width, height; - jpeg_get_size(jpeg, &width, &height); - - // Try to find a graphics mode with the corresponding dimensions. - int videomode = find_videomode(vesa_info, mode_info, width, height); - if (videomode < 0) - goto done; - void *framebuffer = mode_info->phys_base_ptr; - int depth = mode_info->bits_per_pixel; - dprintf(3, "mode: %04x\n", videomode); - dprintf(3, "framebuffer: %p\n", framebuffer); - dprintf(3, "bytes per scanline: %d\n", mode_info->bytes_per_scanline); - dprintf(3, "bits per pixel: %d\n", depth); - - // Allocate space for image and decompress it. - int imagesize = width * height * (depth / 8); - picture = malloc_tmphigh(imagesize); - if (!picture) { - warn_noalloc(); - goto done; - } - dprintf(5, "Decompressing bootsplash.jpg\n"); - ret = jpeg_show(jpeg, picture, width, height, depth); - if (ret) { - dprintf(1, "jpeg_show failed with return code %d...\n", ret); - goto done; - } - - /* Switch to graphics mode */ - dprintf(5, "Switching to graphics mode\n"); - memset(&br, 0, sizeof(br)); - br.ax = 0x4f02; - br.bx = (1 << 14) | videomode; - call16_int10(&br); - if (br.ax != 0x4f) { - dprintf(1, "set_mode failed.\n"); - goto done; - } - - /* Show the picture */ - dprintf(5, "Showing bootsplash.jpg\n"); - iomemcpy(framebuffer, picture, imagesize); - dprintf(5, "Bootsplash copy complete\n"); - BootsplashActive = 1; - -done: - free(filedata); - free(picture); - free(vesa_info); - free(mode_info); - free(jpeg); - return; -} - -void -disable_bootsplash(void) -{ - if (!CONFIG_BOOTSPLASH || !BootsplashActive) - return; - BootsplashActive = 0; - enable_vga_console(); -} diff --git a/roms/seabios/src/bregs.h b/roms/seabios/src/bregs.h deleted file mode 100644 index 9a381d0..0000000 --- a/roms/seabios/src/bregs.h +++ /dev/null @@ -1,96 +0,0 @@ -// Structure layout of cpu registers the the bios uses. -// -// Copyright (C) 2008 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#ifndef __BREGS_H -#define __BREGS_H - -// CPU flag bitdefs -#define F_CF (1<<0) -#define F_ZF (1<<6) -#define F_IF (1<<9) - -// CR0 flags -#define CR0_PG (1<<31) // Paging -#define CR0_CD (1<<30) // Cache disable -#define CR0_NW (1<<29) // Not Write-through -#define CR0_PE (1<<0) // Protection enable - - -#ifndef __ASSEMBLY__ - -#include "farptr.h" // struct segoff_s - -/**************************************************************** - * Registers saved/restored in romlayout.S - ****************************************************************/ - -#include "types.h" // u16 - -#define UREG(ER, R, RH, RL) union { u32 ER; struct { u16 R; u16 R ## _hi; }; struct { u8 RL; u8 RH; u8 R ## _hilo; u8 R ## _hihi; }; } - -// Layout of registers passed in to irq handlers. Note that this -// layout corresponds to code in romlayout.S - don't change it here -// without also updating the assembler code. -struct bregs { - u16 ds; - u16 es; - UREG(edi, di, di_hi, di_lo); - UREG(esi, si, si_hi, si_lo); - UREG(ebp, bp, bp_hi, bp_lo); - UREG(ebx, bx, bh, bl); - UREG(edx, dx, dh, dl); - UREG(ecx, cx, ch, cl); - UREG(eax, ax, ah, al); - struct segoff_s code; - u16 flags; -} PACKED; - - -/**************************************************************** - * Helper functions - ****************************************************************/ - -static inline void -set_cf(struct bregs *regs, int cond) -{ - if (cond) - regs->flags |= F_CF; - else - regs->flags &= ~F_CF; -} - -// Frequently used return codes -#define RET_EUNSUPPORTED 0x86 - -static inline void -set_success(struct bregs *regs) -{ - set_cf(regs, 0); -} - -static inline void -set_code_success(struct bregs *regs) -{ - regs->ah = 0; - set_cf(regs, 0); -} - -static inline void -set_invalid_silent(struct bregs *regs) -{ - set_cf(regs, 1); -} - -static inline void -set_code_invalid_silent(struct bregs *regs, u8 code) -{ - regs->ah = code; - set_cf(regs, 1); -} - -#endif // !__ASSEMBLY__ - -#endif // bregs.h diff --git a/roms/seabios/src/cdrom.c b/roms/seabios/src/cdrom.c deleted file mode 100644 index 655ee00..0000000 --- a/roms/seabios/src/cdrom.c +++ /dev/null @@ -1,380 +0,0 @@ -// Support for booting from cdroms (the "El Torito" spec). -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "disk.h" // cdrom_13 -#include "util.h" // memset -#include "bregs.h" // struct bregs -#include "biosvar.h" // GET_EBDA -#include "ata.h" // ATA_CMD_REQUEST_SENSE -#include "blockcmd.h" // CDB_CMD_REQUEST_SENSE - - -/**************************************************************** - * CD emulation - ****************************************************************/ - -struct drive_s *cdemu_drive_gf VAR16VISIBLE; -u8 *cdemu_buf_fl VAR16VISIBLE; - -static int -cdemu_read(struct disk_op_s *op) -{ - u16 ebda_seg = get_ebda_seg(); - struct drive_s *drive_g; - drive_g = GLOBALFLAT2GLOBAL(GET_EBDA2(ebda_seg, cdemu.emulated_drive_gf)); - struct disk_op_s dop; - dop.drive_g = drive_g; - dop.command = op->command; - dop.lba = GET_EBDA2(ebda_seg, cdemu.ilba) + op->lba / 4; - - int count = op->count; - op->count = 0; - u8 *cdbuf_fl = GET_GLOBAL(cdemu_buf_fl); - - if (op->lba & 3) { - // Partial read of first block. - dop.count = 1; - dop.buf_fl = cdbuf_fl; - int ret = process_op(&dop); - if (ret) - return ret; - u8 thiscount = 4 - (op->lba & 3); - if (thiscount > count) - thiscount = count; - count -= thiscount; - memcpy_fl(op->buf_fl, cdbuf_fl + (op->lba & 3) * 512, thiscount * 512); - op->buf_fl += thiscount * 512; - op->count += thiscount; - dop.lba++; - } - - if (count > 3) { - // Read n number of regular blocks. - dop.count = count / 4; - dop.buf_fl = op->buf_fl; - int ret = process_op(&dop); - op->count += dop.count * 4; - if (ret) - return ret; - u8 thiscount = count & ~3; - count &= 3; - op->buf_fl += thiscount * 512; - dop.lba += thiscount / 4; - } - - if (count) { - // Partial read on last block. - dop.count = 1; - dop.buf_fl = cdbuf_fl; - int ret = process_op(&dop); - if (ret) - return ret; - u8 thiscount = count; - memcpy_fl(op->buf_fl, cdbuf_fl, thiscount * 512); - op->count += thiscount; - } - - return DISK_RET_SUCCESS; -} - -int -process_cdemu_op(struct disk_op_s *op) -{ - if (!CONFIG_CDROM_EMU) - return 0; - - switch (op->command) { - case CMD_READ: - return cdemu_read(op); - case CMD_WRITE: - case CMD_FORMAT: - return DISK_RET_EWRITEPROTECT; - case CMD_VERIFY: - case CMD_RESET: - case CMD_SEEK: - case CMD_ISREADY: - return DISK_RET_SUCCESS; - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} - -void -cdemu_setup(void) -{ - if (!CONFIG_CDROM_EMU) - return; - cdemu_drive_gf = NULL; - cdemu_buf_fl = NULL; - if (!Drives.cdcount) - return; - - struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g)); - u8 *buf = malloc_low(CDROM_SECTOR_SIZE); - if (!drive_g || !buf) { - warn_noalloc(); - free(drive_g); - free(buf); - return; - } - cdemu_drive_gf = drive_g; - cdemu_buf_fl = buf; - memset(drive_g, 0, sizeof(*drive_g)); - drive_g->type = DTYPE_CDEMU; - drive_g->blksize = DISK_SECTOR_SIZE; - drive_g->sectors = (u64)-1; -} - -struct eltorito_s { - u8 size; - u8 media; - u8 emulated_drive; - u8 controller_index; - u32 ilba; - u16 device_spec; - u16 buffer_segment; - u16 load_segment; - u16 sector_count; - u8 cylinders; - u8 sectors; - u8 heads; -}; - -#define SET_INT13ET(regs,var,val) \ - SET_FARVAR((regs)->ds, ((struct eltorito_s*)((regs)->si+0))->var, (val)) - -// ElTorito - Terminate disk emu -void -cdemu_134b(struct bregs *regs) -{ - // FIXME ElTorito Hardcoded - u16 ebda_seg = get_ebda_seg(); - SET_INT13ET(regs, size, 0x13); - SET_INT13ET(regs, media, GET_EBDA2(ebda_seg, cdemu.media)); - SET_INT13ET(regs, emulated_drive - , GET_EBDA2(ebda_seg, cdemu.emulated_extdrive)); - struct drive_s *drive_gf = GET_EBDA2(ebda_seg, cdemu.emulated_drive_gf); - u8 cntl_id = 0; - if (drive_gf) - cntl_id = GET_GLOBALFLAT(drive_gf->cntl_id); - SET_INT13ET(regs, controller_index, cntl_id / 2); - SET_INT13ET(regs, device_spec, cntl_id % 2); - SET_INT13ET(regs, ilba, GET_EBDA2(ebda_seg, cdemu.ilba)); - SET_INT13ET(regs, buffer_segment, GET_EBDA2(ebda_seg, cdemu.buffer_segment)); - SET_INT13ET(regs, load_segment, GET_EBDA2(ebda_seg, cdemu.load_segment)); - SET_INT13ET(regs, sector_count, GET_EBDA2(ebda_seg, cdemu.sector_count)); - SET_INT13ET(regs, cylinders, GET_EBDA2(ebda_seg, cdemu.lchs.cylinders)); - SET_INT13ET(regs, sectors, GET_EBDA2(ebda_seg, cdemu.lchs.spt)); - SET_INT13ET(regs, heads, GET_EBDA2(ebda_seg, cdemu.lchs.heads)); - - // If we have to terminate emulation - if (regs->al == 0x00) { - // FIXME ElTorito Various. Should be handled accordingly to spec - SET_EBDA2(ebda_seg, cdemu.active, 0x00); // bye bye - - // XXX - update floppy/hd count. - } - - disk_ret(regs, DISK_RET_SUCCESS); -} - - -/**************************************************************** - * CD booting - ****************************************************************/ - -static int -atapi_is_ready(struct disk_op_s *op) -{ - dprintf(6, "atapi_is_ready (drive=%p)\n", op->drive_g); - - /* Retry READ CAPACITY for 5 seconds unless MEDIUM NOT PRESENT is - * reported by the device. If the device reports "IN PROGRESS", - * 30 seconds is added. */ - struct cdbres_read_capacity info; - int in_progress = 0; - u64 end = calc_future_tsc(5000); - for (;;) { - if (check_tsc(end)) { - dprintf(1, "read capacity failed\n"); - return -1; - } - - int ret = cdb_read_capacity(op, &info); - if (!ret) - // Success - break; - - struct cdbres_request_sense sense; - ret = cdb_get_sense(op, &sense); - if (ret) - // Error - retry. - continue; - - // Sense succeeded. - if (sense.asc == 0x3a) { /* MEDIUM NOT PRESENT */ - dprintf(1, "Device reports MEDIUM NOT PRESENT\n"); - return -1; - } - - if (sense.asc == 0x04 && sense.ascq == 0x01 && !in_progress) { - /* IN PROGRESS OF BECOMING READY */ - printf("Waiting for device to detect medium... "); - /* Allow 30 seconds more */ - end = calc_future_tsc(30000); - in_progress = 1; - } - } - - u32 blksize = ntohl(info.blksize), sectors = ntohl(info.sectors); - if (blksize != GET_GLOBAL(op->drive_g->blksize)) { - printf("Unsupported sector size %u\n", blksize); - return -1; - } - - dprintf(6, "sectors=%u\n", sectors); - printf("%dMB medium detected\n", sectors>>(20-11)); - return 0; -} - -int -cdrom_boot(int cdid) -{ - struct disk_op_s dop; - memset(&dop, 0, sizeof(dop)); - dop.drive_g = getDrive(EXTTYPE_CD, cdid); - if (!dop.drive_g) - return 1; - - int ret = atapi_is_ready(&dop); - if (ret) - dprintf(1, "atapi_is_ready returned %d\n", ret); - - // Read the Boot Record Volume Descriptor - u8 buffer[2048]; - dop.lba = 0x11; - dop.count = 1; - dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer); - ret = cdb_read(&dop); - if (ret) - return 3; - - // Validity checks - if (buffer[0]) - return 4; - if (strcmp((char*)&buffer[1], "CD001\001EL TORITO SPECIFICATION") != 0) - return 5; - - // ok, now we calculate the Boot catalog address - u32 lba = *(u32*)&buffer[0x47]; - - // And we read the Boot Catalog - dop.lba = lba; - dop.count = 1; - ret = cdb_read(&dop); - if (ret) - return 7; - - // Validation entry - if (buffer[0x00] != 0x01) - return 8; // Header - if (buffer[0x01] != 0x00) - return 9; // Platform - if (buffer[0x1E] != 0x55) - return 10; // key 1 - if (buffer[0x1F] != 0xAA) - return 10; // key 2 - - // Initial/Default Entry - if (buffer[0x20] != 0x88) - return 11; // Bootable - - u16 ebda_seg = get_ebda_seg(); - u8 media = buffer[0x21]; - SET_EBDA2(ebda_seg, cdemu.media, media); - - SET_EBDA2(ebda_seg, cdemu.emulated_drive_gf, dop.drive_g); - - u16 boot_segment = *(u16*)&buffer[0x22]; - if (!boot_segment) - boot_segment = 0x07C0; - SET_EBDA2(ebda_seg, cdemu.load_segment, boot_segment); - SET_EBDA2(ebda_seg, cdemu.buffer_segment, 0x0000); - - u16 nbsectors = *(u16*)&buffer[0x26]; - SET_EBDA2(ebda_seg, cdemu.sector_count, nbsectors); - - lba = *(u32*)&buffer[0x28]; - SET_EBDA2(ebda_seg, cdemu.ilba, lba); - - // And we read the image in memory - dop.lba = lba; - dop.count = DIV_ROUND_UP(nbsectors, 4); - dop.buf_fl = MAKE_FLATPTR(boot_segment, 0); - ret = cdb_read(&dop); - if (ret) - return 12; - - if (media == 0) { - // No emulation requested - return success. - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, EXTSTART_CD + cdid); - return 0; - } - - // Emulation of a floppy/harddisk requested - if (! CONFIG_CDROM_EMU || !cdemu_drive_gf) - return 13; - - // Set emulated drive id and increase bios installed hardware - // number of devices - if (media < 4) { - // Floppy emulation - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x00); - // XXX - get and set actual floppy count. - SETBITS_BDA(equipment_list_flags, 0x41); - - switch (media) { - case 0x01: // 1.2M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 15); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); - break; - case 0x02: // 1.44M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 18); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); - break; - case 0x03: // 2.88M floppy - SET_EBDA2(ebda_seg, cdemu.lchs.spt, 36); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders, 80); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, 2); - break; - } - } else { - // Harddrive emulation - SET_EBDA2(ebda_seg, cdemu.emulated_extdrive, 0x80); - SET_BDA(hdcount, GET_BDA(hdcount) + 1); - - // Peak at partition table to get chs. - struct mbr_s *mbr = (void*)0; - u8 sptcyl = GET_FARVAR(boot_segment, mbr->partitions[0].last.sptcyl); - u8 cyllow = GET_FARVAR(boot_segment, mbr->partitions[0].last.cyllow); - u8 heads = GET_FARVAR(boot_segment, mbr->partitions[0].last.heads); - - SET_EBDA2(ebda_seg, cdemu.lchs.spt, sptcyl & 0x3f); - SET_EBDA2(ebda_seg, cdemu.lchs.cylinders - , ((sptcyl<<2)&0x300) + cyllow + 1); - SET_EBDA2(ebda_seg, cdemu.lchs.heads, heads + 1); - } - - // everything is ok, so from now on, the emulation is active - SET_EBDA2(ebda_seg, cdemu.active, 0x01); - dprintf(6, "cdemu media=%d\n", media); - - return 0; -} diff --git a/roms/seabios/src/clock.c b/roms/seabios/src/clock.c deleted file mode 100644 index f6a43e9..0000000 --- a/roms/seabios/src/clock.c +++ /dev/null @@ -1,651 +0,0 @@ -// 16bit code to handle system clocks. -// -// Copyright (C) 2008-2010 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "biosvar.h" // SET_BDA -#include "util.h" // debug_enter -#include "disk.h" // floppy_tick -#include "cmos.h" // inb_cmos -#include "pic.h" // eoi_pic1 -#include "bregs.h" // struct bregs -#include "biosvar.h" // GET_GLOBAL -#include "usb-hid.h" // usb_check_event - -// RTC register flags -#define RTC_A_UIP 0x80 - -#define RTC_B_SET 0x80 -#define RTC_B_PIE 0x40 -#define RTC_B_AIE 0x20 -#define RTC_B_UIE 0x10 -#define RTC_B_BIN 0x04 -#define RTC_B_24HR 0x02 -#define RTC_B_DSE 0x01 - - -// Bits for PORT_PS2_CTRLB -#define PPCB_T2GATE (1<<0) -#define PPCB_SPKR (1<<1) -#define PPCB_T2OUT (1<<5) - -// Bits for PORT_PIT_MODE -#define PM_SEL_TIMER0 (0<<6) -#define PM_SEL_TIMER1 (1<<6) -#define PM_SEL_TIMER2 (2<<6) -#define PM_SEL_READBACK (3<<6) -#define PM_ACCESS_LATCH (0<<4) -#define PM_ACCESS_LOBYTE (1<<4) -#define PM_ACCESS_HIBYTE (2<<4) -#define PM_ACCESS_WORD (3<<4) -#define PM_MODE0 (0<<1) -#define PM_MODE1 (1<<1) -#define PM_MODE2 (2<<1) -#define PM_MODE3 (3<<1) -#define PM_MODE4 (4<<1) -#define PM_MODE5 (5<<1) -#define PM_CNT_BINARY (0<<0) -#define PM_CNT_BCD (1<<0) - - -/**************************************************************** - * TSC timer - ****************************************************************/ - -#define CALIBRATE_COUNT 0x800 // Approx 1.7ms - -u32 cpu_khz VAR16VISIBLE; - -static void -calibrate_tsc(void) -{ - // Setup "timer2" - u8 orig = inb(PORT_PS2_CTRLB); - outb((orig & ~PPCB_SPKR) | PPCB_T2GATE, PORT_PS2_CTRLB); - /* binary, mode 0, LSB/MSB, Ch 2 */ - outb(PM_SEL_TIMER2|PM_ACCESS_WORD|PM_MODE0|PM_CNT_BINARY, PORT_PIT_MODE); - /* LSB of ticks */ - outb(CALIBRATE_COUNT & 0xFF, PORT_PIT_COUNTER2); - /* MSB of ticks */ - outb(CALIBRATE_COUNT >> 8, PORT_PIT_COUNTER2); - - u64 start = rdtscll(); - while ((inb(PORT_PS2_CTRLB) & PPCB_T2OUT) == 0) - ; - u64 end = rdtscll(); - - // Restore PORT_PS2_CTRLB - outb(orig, PORT_PS2_CTRLB); - - // Store calibrated cpu khz. - u64 diff = end - start; - dprintf(6, "tsc calibrate start=%u end=%u diff=%u\n" - , (u32)start, (u32)end, (u32)diff); - u32 hz = diff * PIT_TICK_RATE / CALIBRATE_COUNT; - SET_GLOBAL(cpu_khz, hz / 1000); - - dprintf(1, "CPU Mhz=%u\n", hz / 1000000); -} - -static void -tscdelay(u64 diff) -{ - u64 start = rdtscll(); - u64 end = start + diff; - while (!check_tsc(end)) - cpu_relax(); -} - -static void -tscsleep(u64 diff) -{ - u64 start = rdtscll(); - u64 end = start + diff; - while (!check_tsc(end)) - yield(); -} - -void ndelay(u32 count) { - tscdelay(count * GET_GLOBAL(cpu_khz) / 1000000); -} -void udelay(u32 count) { - tscdelay(count * GET_GLOBAL(cpu_khz) / 1000); -} -void mdelay(u32 count) { - tscdelay(count * GET_GLOBAL(cpu_khz)); -} - -void nsleep(u32 count) { - tscsleep(count * GET_GLOBAL(cpu_khz) / 1000000); -} -void usleep(u32 count) { - tscsleep(count * GET_GLOBAL(cpu_khz) / 1000); -} -void msleep(u32 count) { - tscsleep(count * GET_GLOBAL(cpu_khz)); -} - -// Return the TSC value that is 'msecs' time in the future. -u64 -calc_future_tsc(u32 msecs) -{ - u32 khz = GET_GLOBAL(cpu_khz); - return rdtscll() + ((u64)khz * msecs); -} -u64 -calc_future_tsc_usec(u32 usecs) -{ - u32 khz = GET_GLOBAL(cpu_khz); - return rdtscll() + ((u64)(khz/1000) * usecs); -} - - -/**************************************************************** - * Init - ****************************************************************/ - -static int -rtc_updating(void) -{ - // This function checks to see if the update-in-progress bit - // is set in CMOS Status Register A. If not, it returns 0. - // If it is set, it tries to wait until there is a transition - // to 0, and will return 0 if such a transition occurs. A -1 - // is returned only after timing out. The maximum period - // that this bit should be set is constrained to (1984+244) - // useconds, but we wait for longer just to be sure. - - if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0) - return 0; - u64 end = calc_future_tsc(15); - for (;;) { - if ((inb_cmos(CMOS_STATUS_A) & RTC_A_UIP) == 0) - return 0; - if (check_tsc(end)) - // update-in-progress never transitioned to 0 - return -1; - yield(); - } -} - -static void -pit_setup(void) -{ - // timer0: binary count, 16bit count, mode 2 - outb(PM_SEL_TIMER0|PM_ACCESS_WORD|PM_MODE2|PM_CNT_BINARY, PORT_PIT_MODE); - // maximum count of 0000H = 18.2Hz - outb(0x0, PORT_PIT_COUNTER0); - outb(0x0, PORT_PIT_COUNTER0); -} - -static void -init_rtc(void) -{ - outb_cmos(0x26, CMOS_STATUS_A); // 32,768Khz src, 976.5625us updates - u8 regB = inb_cmos(CMOS_STATUS_B); - outb_cmos((regB & RTC_B_DSE) | RTC_B_24HR, CMOS_STATUS_B); - inb_cmos(CMOS_STATUS_C); - inb_cmos(CMOS_STATUS_D); -} - -static u32 -bcd2bin(u8 val) -{ - return (val & 0xf) + ((val >> 4) * 10); -} - -void -timer_setup(void) -{ - dprintf(3, "init timer\n"); - calibrate_tsc(); - pit_setup(); - - init_rtc(); - rtc_updating(); - u32 seconds = bcd2bin(inb_cmos(CMOS_RTC_SECONDS)); - u32 minutes = bcd2bin(inb_cmos(CMOS_RTC_MINUTES)); - u32 hours = bcd2bin(inb_cmos(CMOS_RTC_HOURS)); - u32 ticks = (hours * 60 + minutes) * 60 + seconds; - ticks = ((u64)ticks * PIT_TICK_RATE) / PIT_TICK_INTERVAL; - SET_BDA(timer_counter, ticks); - SET_BDA(timer_rollover, 0); - - enable_hwirq(0, FUNC16(entry_08)); - enable_hwirq(8, FUNC16(entry_70)); -} - - -/**************************************************************** - * Standard clock functions - ****************************************************************/ - -#define TICKS_PER_DAY (u32)((u64)60*60*24*PIT_TICK_RATE / PIT_TICK_INTERVAL) - -// Calculate the timer value at 'count' number of full timer ticks in -// the future. -u32 -calc_future_timer_ticks(u32 count) -{ - return (GET_BDA(timer_counter) + count + 1) % TICKS_PER_DAY; -} - -// Return the timer value that is 'msecs' time in the future. -u32 -calc_future_timer(u32 msecs) -{ - if (!msecs) - return GET_BDA(timer_counter); - u32 kticks = DIV_ROUND_UP((u64)msecs * PIT_TICK_RATE, PIT_TICK_INTERVAL); - u32 ticks = DIV_ROUND_UP(kticks, 1000); - return calc_future_timer_ticks(ticks); -} - -// Check if the given timer value has passed. -int -check_timer(u32 end) -{ - return (((GET_BDA(timer_counter) + TICKS_PER_DAY - end) % TICKS_PER_DAY) - < (TICKS_PER_DAY/2)); -} - -// get current clock count -static void -handle_1a00(struct bregs *regs) -{ - yield(); - u32 ticks = GET_BDA(timer_counter); - regs->cx = ticks >> 16; - regs->dx = ticks; - regs->al = GET_BDA(timer_rollover); - SET_BDA(timer_rollover, 0); // reset flag - set_success(regs); -} - -// Set Current Clock Count -static void -handle_1a01(struct bregs *regs) -{ - u32 ticks = (regs->cx << 16) | regs->dx; - SET_BDA(timer_counter, ticks); - SET_BDA(timer_rollover, 0); // reset flag - // XXX - should use set_code_success()? - regs->ah = 0; - set_success(regs); -} - -// Read CMOS Time -static void -handle_1a02(struct bregs *regs) -{ - if (rtc_updating()) { - set_invalid(regs); - return; - } - - regs->dh = inb_cmos(CMOS_RTC_SECONDS); - regs->cl = inb_cmos(CMOS_RTC_MINUTES); - regs->ch = inb_cmos(CMOS_RTC_HOURS); - regs->dl = inb_cmos(CMOS_STATUS_B) & RTC_B_DSE; - regs->ah = 0; - regs->al = regs->ch; - set_success(regs); -} - -// Set CMOS Time -static void -handle_1a03(struct bregs *regs) -{ - // Using a debugger, I notice the following masking/setting - // of bits in Status Register B, by setting Reg B to - // a few values and getting its value after INT 1A was called. - // - // try#1 try#2 try#3 - // before 1111 1101 0111 1101 0000 0000 - // after 0110 0010 0110 0010 0000 0010 - // - // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 - // My assumption: RegB = ((RegB & 01100000b) | 00000010b) - if (rtc_updating()) { - init_rtc(); - // fall through as if an update were not in progress - } - outb_cmos(regs->dh, CMOS_RTC_SECONDS); - outb_cmos(regs->cl, CMOS_RTC_MINUTES); - outb_cmos(regs->ch, CMOS_RTC_HOURS); - // Set Daylight Savings time enabled bit to requested value - u8 val8 = ((inb_cmos(CMOS_STATUS_B) & (RTC_B_PIE|RTC_B_AIE)) - | RTC_B_24HR | (regs->dl & RTC_B_DSE)); - outb_cmos(val8, CMOS_STATUS_B); - regs->ah = 0; - regs->al = val8; // val last written to Reg B - set_success(regs); -} - -// Read CMOS Date -static void -handle_1a04(struct bregs *regs) -{ - regs->ah = 0; - if (rtc_updating()) { - set_invalid(regs); - return; - } - regs->cl = inb_cmos(CMOS_RTC_YEAR); - regs->dh = inb_cmos(CMOS_RTC_MONTH); - regs->dl = inb_cmos(CMOS_RTC_DAY_MONTH); - if (CONFIG_COREBOOT) { - if (regs->cl > 0x80) - regs->ch = 0x19; - else - regs->ch = 0x20; - } else { - regs->ch = inb_cmos(CMOS_CENTURY); - } - regs->al = regs->ch; - set_success(regs); -} - -// Set CMOS Date -static void -handle_1a05(struct bregs *regs) -{ - // Using a debugger, I notice the following masking/setting - // of bits in Status Register B, by setting Reg B to - // a few values and getting its value after INT 1A was called. - // - // try#1 try#2 try#3 try#4 - // before 1111 1101 0111 1101 0000 0010 0000 0000 - // after 0110 1101 0111 1101 0000 0010 0000 0000 - // - // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 - // My assumption: RegB = (RegB & 01111111b) - if (rtc_updating()) { - init_rtc(); - set_invalid(regs); - return; - } - outb_cmos(regs->cl, CMOS_RTC_YEAR); - outb_cmos(regs->dh, CMOS_RTC_MONTH); - outb_cmos(regs->dl, CMOS_RTC_DAY_MONTH); - if (!CONFIG_COREBOOT) - outb_cmos(regs->ch, CMOS_CENTURY); - // clear halt-clock bit - u8 val8 = inb_cmos(CMOS_STATUS_B) & ~RTC_B_SET; - outb_cmos(val8, CMOS_STATUS_B); - regs->ah = 0; - regs->al = val8; // AL = val last written to Reg B - set_success(regs); -} - -// Set Alarm Time in CMOS -static void -handle_1a06(struct bregs *regs) -{ - // Using a debugger, I notice the following masking/setting - // of bits in Status Register B, by setting Reg B to - // a few values and getting its value after INT 1A was called. - // - // try#1 try#2 try#3 - // before 1101 1111 0101 1111 0000 0000 - // after 0110 1111 0111 1111 0010 0000 - // - // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 - // My assumption: RegB = ((RegB & 01111111b) | 00100000b) - u8 val8 = inb_cmos(CMOS_STATUS_B); // Get Status Reg B - regs->ax = 0; - if (val8 & RTC_B_AIE) { - // Alarm interrupt enabled already - set_invalid(regs); - return; - } - if (rtc_updating()) { - init_rtc(); - // fall through as if an update were not in progress - } - outb_cmos(regs->dh, CMOS_RTC_SECONDS_ALARM); - outb_cmos(regs->cl, CMOS_RTC_MINUTES_ALARM); - outb_cmos(regs->ch, CMOS_RTC_HOURS_ALARM); - // enable Status Reg B alarm bit, clear halt clock bit - outb_cmos((val8 & ~RTC_B_SET) | RTC_B_AIE, CMOS_STATUS_B); - set_success(regs); -} - -// Turn off Alarm -static void -handle_1a07(struct bregs *regs) -{ - // Using a debugger, I notice the following masking/setting - // of bits in Status Register B, by setting Reg B to - // a few values and getting its value after INT 1A was called. - // - // try#1 try#2 try#3 try#4 - // before 1111 1101 0111 1101 0010 0000 0010 0010 - // after 0100 0101 0101 0101 0000 0000 0000 0010 - // - // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 - // My assumption: RegB = (RegB & 01010111b) - u8 val8 = inb_cmos(CMOS_STATUS_B); // Get Status Reg B - // clear clock-halt bit, disable alarm bit - outb_cmos(val8 & ~(RTC_B_SET|RTC_B_AIE), CMOS_STATUS_B); - regs->ah = 0; - regs->al = val8; // val last written to Reg B - set_success(regs); -} - -// Unsupported -static void -handle_1aXX(struct bregs *regs) -{ - set_unimplemented(regs); -} - -// INT 1Ah Time-of-day Service Entry Point -void VISIBLE16 -handle_1a(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_1a); - switch (regs->ah) { - case 0x00: handle_1a00(regs); break; - case 0x01: handle_1a01(regs); break; - case 0x02: handle_1a02(regs); break; - case 0x03: handle_1a03(regs); break; - case 0x04: handle_1a04(regs); break; - case 0x05: handle_1a05(regs); break; - case 0x06: handle_1a06(regs); break; - case 0x07: handle_1a07(regs); break; - case 0xb1: handle_1ab1(regs); break; - default: handle_1aXX(regs); break; - } -} - -// INT 08h System Timer ISR Entry Point -void VISIBLE16 -handle_08(void) -{ - debug_isr(DEBUG_ISR_08); - - floppy_tick(); - - u32 counter = GET_BDA(timer_counter); - counter++; - // compare to one days worth of timer ticks at 18.2 hz - if (counter >= TICKS_PER_DAY) { - // there has been a midnight rollover at this point - counter = 0; - SET_BDA(timer_rollover, GET_BDA(timer_rollover) + 1); - } - - SET_BDA(timer_counter, counter); - - usb_check_event(); - - // chain to user timer tick INT #0x1c - u32 eax=0, flags; - call16_simpint(0x1c, &eax, &flags); - - eoi_pic1(); -} - - -/**************************************************************** - * Periodic timer - ****************************************************************/ - -void -useRTC(void) -{ - u16 ebda_seg = get_ebda_seg(); - int count = GET_EBDA2(ebda_seg, RTCusers); - SET_EBDA2(ebda_seg, RTCusers, count+1); - if (count) - return; - // Turn on the Periodic Interrupt timer - u8 bRegister = inb_cmos(CMOS_STATUS_B); - outb_cmos(bRegister | RTC_B_PIE, CMOS_STATUS_B); -} - -void -releaseRTC(void) -{ - u16 ebda_seg = get_ebda_seg(); - int count = GET_EBDA2(ebda_seg, RTCusers); - SET_EBDA2(ebda_seg, RTCusers, count-1); - if (count != 1) - return; - // Clear the Periodic Interrupt. - u8 bRegister = inb_cmos(CMOS_STATUS_B); - outb_cmos(bRegister & ~RTC_B_PIE, CMOS_STATUS_B); -} - -static int -set_usertimer(u32 usecs, u16 seg, u16 offset) -{ - if (GET_BDA(rtc_wait_flag) & RWS_WAIT_PENDING) - return -1; - - // Interval not already set. - SET_BDA(rtc_wait_flag, RWS_WAIT_PENDING); // Set status byte. - SET_BDA(user_wait_complete_flag, SEGOFF(seg, offset)); - SET_BDA(user_wait_timeout, usecs); - useRTC(); - return 0; -} - -static void -clear_usertimer(void) -{ - if (!(GET_BDA(rtc_wait_flag) & RWS_WAIT_PENDING)) - return; - // Turn off status byte. - SET_BDA(rtc_wait_flag, 0); - releaseRTC(); -} - -#define RET_ECLOCKINUSE 0x83 - -// Wait for CX:DX microseconds -void -handle_1586(struct bregs *regs) -{ - // Use the rtc to wait for the specified time. - u8 statusflag = 0; - u32 count = (regs->cx << 16) | regs->dx; - int ret = set_usertimer(count, GET_SEG(SS), (u32)&statusflag); - if (ret) { - set_code_invalid(regs, RET_ECLOCKINUSE); - return; - } - while (!statusflag) - wait_irq(); - set_success(regs); -} - -// Set Interval requested. -static void -handle_158300(struct bregs *regs) -{ - int ret = set_usertimer((regs->cx << 16) | regs->dx, regs->es, regs->bx); - if (ret) - // Interval already set. - set_code_invalid(regs, RET_EUNSUPPORTED); - else - set_success(regs); -} - -// Clear interval requested -static void -handle_158301(struct bregs *regs) -{ - clear_usertimer(); - set_success(regs); -} - -static void -handle_1583XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EUNSUPPORTED); - regs->al--; -} - -void -handle_1583(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_158300(regs); break; - case 0x01: handle_158301(regs); break; - default: handle_1583XX(regs); break; - } -} - -#define USEC_PER_RTC DIV_ROUND_CLOSEST(1000000, 1024) - -// int70h: IRQ8 - CMOS RTC -void VISIBLE16 -handle_70(void) -{ - debug_isr(DEBUG_ISR_70); - - // Check which modes are enabled and have occurred. - u8 registerB = inb_cmos(CMOS_STATUS_B); - u8 registerC = inb_cmos(CMOS_STATUS_C); - - if (!(registerB & (RTC_B_PIE|RTC_B_AIE))) - goto done; - if (registerC & RTC_B_AIE) { - // Handle Alarm Interrupt. - u32 eax=0, flags; - call16_simpint(0x4a, &eax, &flags); - } - if (!(registerC & RTC_B_PIE)) - goto done; - - // Handle Periodic Interrupt. - - check_preempt(); - - if (!GET_BDA(rtc_wait_flag)) - goto done; - - // Wait Interval (Int 15, AH=83) active. - u32 time = GET_BDA(user_wait_timeout); // Time left in microseconds. - if (time < USEC_PER_RTC) { - // Done waiting - write to specified flag byte. - struct segoff_s segoff = GET_BDA(user_wait_complete_flag); - u16 ptr_seg = segoff.seg; - u8 *ptr_far = (u8*)(segoff.offset+0); - u8 oldval = GET_FARVAR(ptr_seg, *ptr_far); - SET_FARVAR(ptr_seg, *ptr_far, oldval | 0x80); - - clear_usertimer(); - } else { - // Continue waiting. - time -= USEC_PER_RTC; - SET_BDA(user_wait_timeout, time); - } - -done: - eoi_pic2(); -} diff --git a/roms/seabios/src/cmos.h b/roms/seabios/src/cmos.h deleted file mode 100644 index e4b6462..0000000 --- a/roms/seabios/src/cmos.h +++ /dev/null @@ -1,74 +0,0 @@ -// Definitions for X86 CMOS non-volatile memory access. -// -// Copyright (C) 2008 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __CMOS_H -#define __CMOS_H - -#define CMOS_RTC_SECONDS 0x00 -#define CMOS_RTC_SECONDS_ALARM 0x01 -#define CMOS_RTC_MINUTES 0x02 -#define CMOS_RTC_MINUTES_ALARM 0x03 -#define CMOS_RTC_HOURS 0x04 -#define CMOS_RTC_HOURS_ALARM 0x05 -#define CMOS_RTC_DAY_WEEK 0x06 -#define CMOS_RTC_DAY_MONTH 0x07 -#define CMOS_RTC_MONTH 0x08 -#define CMOS_RTC_YEAR 0x09 -#define CMOS_STATUS_A 0x0a -#define CMOS_STATUS_B 0x0b -#define CMOS_STATUS_C 0x0c -#define CMOS_STATUS_D 0x0d -#define CMOS_RESET_CODE 0x0f -#define CMOS_FLOPPY_DRIVE_TYPE 0x10 -#define CMOS_DISK_DATA 0x12 -#define CMOS_EQUIPMENT_INFO 0x14 -#define CMOS_DISK_DRIVE1_TYPE 0x19 -#define CMOS_DISK_DRIVE2_TYPE 0x1a -#define CMOS_DISK_DRIVE1_CYL 0x1b -#define CMOS_DISK_DRIVE2_CYL 0x24 -#define CMOS_MEM_EXTMEM_LOW 0x30 -#define CMOS_MEM_EXTMEM_HIGH 0x31 -#define CMOS_CENTURY 0x32 -#define CMOS_MEM_EXTMEM2_LOW 0x34 -#define CMOS_MEM_EXTMEM2_HIGH 0x35 -#define CMOS_BIOS_BOOTFLAG1 0x38 -#define CMOS_BIOS_DISKTRANSFLAG 0x39 -#define CMOS_BIOS_BOOTFLAG2 0x3d -#define CMOS_MEM_HIGHMEM_LOW 0x5b -#define CMOS_MEM_HIGHMEM_MID 0x5c -#define CMOS_MEM_HIGHMEM_HIGH 0x5d -#define CMOS_BIOS_SMP_COUNT 0x5f - -// CMOS_FLOPPY_DRIVE_TYPE bitdefs -#define CFD_NO_DRIVE 0 -#define CFD_360KB 1 -#define CFD_12MB 2 -#define CFD_720KB 3 -#define CFD_144MB 4 -#define CFD_288MB 5 - -#ifndef __ASSEMBLY__ - -#include "ioport.h" // inb, outb - -static inline u8 -inb_cmos(u8 reg) -{ - reg |= NMI_DISABLE_BIT; - outb(reg, PORT_CMOS_INDEX); - return inb(PORT_CMOS_DATA); -} - -static inline void -outb_cmos(u8 val, u8 reg) -{ - reg |= NMI_DISABLE_BIT; - outb(reg, PORT_CMOS_INDEX); - outb(val, PORT_CMOS_DATA); -} - -#endif // !__ASSEMBLY__ - -#endif // cmos.h diff --git a/roms/seabios/src/config.h b/roms/seabios/src/config.h deleted file mode 100644 index 4572ee5..0000000 --- a/roms/seabios/src/config.h +++ /dev/null @@ -1,230 +0,0 @@ -#ifndef __CONFIG_H -#define __CONFIG_H - -// Configuration definitions. - -//#define CONFIG_APPNAME "QEMU" -//#define CONFIG_CPUNAME8 "QEMUCPU " -//#define CONFIG_APPNAME6 "QEMU " -//#define CONFIG_APPNAME4 "QEMU" -#define CONFIG_APPNAME "Bochs" -#define CONFIG_CPUNAME8 "BOCHSCPU" -#define CONFIG_APPNAME6 "BOCHS " -#define CONFIG_APPNAME4 "BXPC" - -// Configure as a coreboot payload. -#define CONFIG_COREBOOT 0 - -// Control how verbose debug output is. -#define CONFIG_DEBUG_LEVEL 1 -// Send debugging information to serial port -#define CONFIG_DEBUG_SERIAL 0 -// Screen writes are also sent to debug ports. -#define CONFIG_SCREEN_AND_DEBUG 1 - -// Support running hardware initialization in parallel -#define CONFIG_THREADS 1 -// Allow hardware init to run in parallel with optionrom execution -#define CONFIG_THREAD_OPTIONROMS 0 -// Support int13 disk/floppy drive functions -#define CONFIG_DRIVES 1 -// Support floppy drive access -#define CONFIG_FLOPPY 1 -// Support USB devices -#define CONFIG_USB 1 -// Support USB UHCI controllers -#define CONFIG_USB_UHCI 1 -// Support USB OHCI controllers -#define CONFIG_USB_OHCI 1 -// Support USB EHCI controllers -#define CONFIG_USB_EHCI 1 -// Support USB disks -#define CONFIG_USB_MSC 1 -// Support USB hubs -#define CONFIG_USB_HUB 1 -// Support USB keyboards -#define CONFIG_USB_KEYBOARD 1 -// Support USB mice -#define CONFIG_USB_MOUSE 1 -// Support PS2 ports (keyboard and mouse) -#define CONFIG_PS2PORT 1 -// Support for IDE disk code -#define CONFIG_ATA 1 -// Detect and try to use ATA bus mastering DMA controllers. -#define CONFIG_ATA_DMA 0 -// Use 32bit PIO accesses on ATA (minor optimization on PCI transfers) -#define CONFIG_ATA_PIO32 0 -// Support for booting from a CD -#define CONFIG_CDROM_BOOT 1 -// Support for emulating a boot CD as a floppy/harddrive -#define CONFIG_CDROM_EMU 1 -// Support int 1a/b1 PCI BIOS calls -#define CONFIG_PCIBIOS 1 -// Support int 15/53 APM BIOS calls -#define CONFIG_APMBIOS 1 -// Support PnP BIOS entry point. -#define CONFIG_PNPBIOS 1 -// Support Post Memory Manager (PMM) entry point. -#define CONFIG_PMM 1 -// Support int 19/18 system bootup support -#define CONFIG_BOOT 1 -// Support an interactive boot menu at end of post. -#define CONFIG_BOOTMENU 1 -// Amount of time (in ms) to wait at menu before selecting normal boot. -#define CONFIG_BOOTMENU_WAIT 2500 -// Support int 14 serial port calls -#define CONFIG_SERIAL 1 -// Support int 17 parallel port calls -#define CONFIG_LPT 1 -// Support int 16 keyboard calls -#define CONFIG_KEYBOARD 1 -// Support calling int155f on each keyboard event -#define CONFIG_KBD_CALL_INT15_4F 1 -// Disable A20 on 16bit boot -#define CONFIG_DISABLE_A20 0 -// Support for int15c2 mouse calls -#define CONFIG_MOUSE 1 -// If the target machine has multiple independent root buses, the -// extra buses may be specified here. -#define CONFIG_PCI_ROOT1 0x00 -#define CONFIG_PCI_ROOT2 0x00 -// Support searching coreboot flash format. -#define CONFIG_COREBOOT_FLASH 1 -// Support floppy images in the coreboot flash. -#define CONFIG_FLASH_FLOPPY 1 -// Support the lzma decompression algorighm. -#define CONFIG_LZMA 1 -// Support finding and running option roms during post. -#define CONFIG_OPTIONROMS 1 -// Set if option roms are already copied to 0xc0000-0xf0000 -#define CONFIG_OPTIONROMS_DEPLOYED 0 -// When option roms are not pre-deployed, SeaBIOS can copy an optionrom -// from flash for up to 2 devices. -#define OPTIONROM_VENDEV_1 0x00000000 -#define OPTIONROM_MEM_1 0x00000000 -#define OPTIONROM_VENDEV_2 0x00000000 -#define OPTIONROM_MEM_2 0x00000000 - -// Support generation of a PIR table in 0xf000 segment (for emulators) -#define CONFIG_PIRTABLE 1 -// Support generation of MPTable (for emulators) -#define CONFIG_MPTABLE 1 -// Support generation of SM BIOS tables (for emulators) -#define CONFIG_SMBIOS 1 -// Support finding a UUID (for smbios) via "magic" outl sequence. -#define CONFIG_UUID_BACKDOOR 1 -// Support generation of ACPI tables (for emulators) -#define CONFIG_ACPI 1 -// Support bios callbacks specific to via vgabios. -#define CONFIG_VGAHOOKS 0 -// Support S3 resume handler. -#define CONFIG_S3_RESUME 1 -// Run the vga rom during S3 resume. -#define CONFIG_S3_RESUME_VGA_INIT 0 -// Support boot splash -#define CONFIG_BOOTSPLASH 1 -// define it if the (emulated) hardware supports SMM mode -#define CONFIG_USE_SMM 1 -// Maximum number of map entries in the e820 map -#define CONFIG_MAX_E820 32 -// Space to reserve in f-segment for dynamic allocations -#define CONFIG_MAX_BIOSTABLE 2048 -// Space to reserve in high-memory for tables -#define CONFIG_MAX_HIGHTABLE (64*1024) -// Largest supported externaly facing drive id -#define CONFIG_MAX_EXTDRIVE 16 - -#define CONFIG_MODEL_ID 0xFC -#define CONFIG_SUBMODEL_ID 0x00 -#define CONFIG_BIOS_REVISION 0x01 - -// Support boot from virtio storage -#define CONFIG_VIRTIO_BLK 1 - -// Various memory addresses used by the code. -#define BUILD_STACK_ADDR 0x7000 -#define BUILD_S3RESUME_STACK_ADDR 0x1000 -#define BUILD_AP_BOOT_ADDR 0x10000 -#define BUILD_EBDA_MINIMUM 0x90000 -#define BUILD_LOWRAM_END 0xa0000 -#define BUILD_ROM_START 0xc0000 -#define BUILD_BIOS_ADDR 0xf0000 -#define BUILD_BIOS_SIZE 0x10000 -// 32KB for shadow ram copying (works around emulator deficiencies) -#define BUILD_BIOS_TMP_ADDR 0x30000 -#define BUILD_MAX_HIGHMEM 0xe0000000 - -// Support old pci mem assignment behaviour -//#define CONFIG_OLD_PCIMEM_ASSIGNMENT 1 -#if CONFIG_OLD_PCIMEM_ASSIGNMENT -#define BUILD_PCIMEM_START 0xf0000000 -#define BUILD_PCIMEM_SIZE (BUILD_PCIMEM_END - BUILD_PCIMEM_START) -#define BUILD_PCIMEM_END 0xfec00000 /* IOAPIC is mapped at */ -#define BUILD_PCIPREFMEM_START 0 -#define BUILD_PCIPREFMEM_SIZE 0 -#define BUILD_PCIPREFMEM_END 0 -#else -#define BUILD_PCIMEM_START 0xf0000000 -#define BUILD_PCIMEM_SIZE 0x08000000 /* half- of pci window */ -#define BUILD_PCIMEM_END (BUILD_PCIMEM_START + BUILD_PCIMEM_SIZE) -#define BUILD_PCIPREFMEM_START BUILD_PCIMEM_END -#define BUILD_PCIPREFMEM_SIZE (BUILD_PCIPREFMEM_END - BUILD_PCIPREFMEM_START) -#define BUILD_PCIPREFMEM_END 0xfec00000 /* IOAPIC is mapped at */ -#endif - -#define BUILD_APIC_ADDR 0xfee00000 -#define BUILD_IOAPIC_ADDR 0xfec00000 - -#define BUILD_SMM_INIT_ADDR 0x38000 -#define BUILD_SMM_ADDR 0xa8000 -#define BUILD_SMM_SIZE 0x8000 - -// Important real-mode segments -#define SEG_IVT 0x0000 -#define SEG_BDA 0x0040 -#define SEG_BIOS 0xf000 - -// Segment definitions in protected mode (see rombios32_gdt in misc.c) -#define SEG32_MODE32_CS (1 << 3) -#define SEG32_MODE32_DS (2 << 3) -#define SEG32_MODE16_CS (3 << 3) -#define SEG32_MODE16_DS (4 << 3) -#define SEG32_MODE16BIG_CS (5 << 3) -#define SEG32_MODE16BIG_DS (6 << 3) - -// Debugging levels. If non-zero and CONFIG_DEBUG_LEVEL is greater -// than the specified value, then the corresponding irq handler will -// report every enter event. -#define DEBUG_ISR_02 1 -#define DEBUG_HDL_05 1 -#define DEBUG_ISR_08 20 -#define DEBUG_ISR_09 9 -#define DEBUG_ISR_0e 9 -#define DEBUG_HDL_10 20 -#define DEBUG_HDL_11 2 -#define DEBUG_HDL_12 2 -#define DEBUG_HDL_13 10 -#define DEBUG_HDL_14 2 -#define DEBUG_HDL_15 9 -#define DEBUG_HDL_16 9 -#define DEBUG_HDL_17 2 -#define DEBUG_HDL_18 1 -#define DEBUG_HDL_19 1 -#define DEBUG_HDL_1a 9 -#define DEBUG_HDL_40 1 -#define DEBUG_ISR_70 9 -#define DEBUG_ISR_74 9 -#define DEBUG_ISR_75 1 -#define DEBUG_ISR_76 10 -#define DEBUG_ISR_hwpic1 5 -#define DEBUG_ISR_hwpic2 5 -#define DEBUG_HDL_pnp 1 -#define DEBUG_HDL_pmm 1 -#define DEBUG_HDL_pcibios32 9 -#define DEBUG_HDL_apm 9 - -#define DEBUG_unimplemented 2 -#define DEBUG_invalid 3 -#define DEBUG_thread 2 - -#endif // config.h diff --git a/roms/seabios/src/coreboot.c b/roms/seabios/src/coreboot.c deleted file mode 100644 index 554ea81..0000000 --- a/roms/seabios/src/coreboot.c +++ /dev/null @@ -1,607 +0,0 @@ -// Coreboot interface support. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "memmap.h" // add_e820 -#include "util.h" // dprintf -#include "pci.h" // struct pir_header -#include "acpi.h" // struct rsdp_descriptor -#include "mptable.h" // MPTABLE_SIGNATURE -#include "biosvar.h" // GET_EBDA -#include "lzmadecode.h" // LzmaDecode -#include "smbios.h" // smbios_init - - -/**************************************************************** - * Memory map - ****************************************************************/ - -struct cb_header { - u32 signature; - u32 header_bytes; - u32 header_checksum; - u32 table_bytes; - u32 table_checksum; - u32 table_entries; -}; - -#define CB_SIGNATURE 0x4f49424C // "LBIO" - -struct cb_memory_range { - u64 start; - u64 size; - u32 type; -}; - -#define CB_MEM_TABLE 16 - -struct cb_memory { - u32 tag; - u32 size; - struct cb_memory_range map[0]; -}; - -#define CB_TAG_MEMORY 0x01 - -#define MEM_RANGE_COUNT(_rec) \ - (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0])) - -struct cb_mainboard { - u32 tag; - u32 size; - u8 vendor_idx; - u8 part_idx; - char strings[0]; -}; - -#define CB_TAG_MAINBOARD 0x0003 - -struct cb_forward { - u32 tag; - u32 size; - u64 forward; -}; - -#define CB_TAG_FORWARD 0x11 - -static u16 -ipchksum(char *buf, int count) -{ - u16 *p = (u16*)buf; - u32 sum = 0; - while (count > 1) { - sum += *p++; - count -= 2; - } - if (count) - sum += *(u8*)p; - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - return ~sum; -} - -// Try to locate the coreboot header in a given address range. -static struct cb_header * -find_cb_header(char *addr, int len) -{ - char *end = addr + len; - for (; addr < end; addr += 16) { - struct cb_header *cbh = (struct cb_header *)addr; - if (cbh->signature != CB_SIGNATURE) - continue; - if (! cbh->table_bytes) - continue; - if (ipchksum(addr, sizeof(*cbh)) != 0) - continue; - if (ipchksum(addr + sizeof(*cbh), cbh->table_bytes) - != cbh->table_checksum) - continue; - return cbh; - } - return NULL; -} - -// Try to find the coreboot memory table in the given coreboot table. -static void * -find_cb_subtable(struct cb_header *cbh, u32 tag) -{ - char *tbl = (char *)cbh + sizeof(*cbh); - int i; - for (i=0; itable_entries; i++) { - struct cb_memory *cbm = (struct cb_memory *)tbl; - tbl += cbm->size; - if (cbm->tag == tag) - return cbm; - } - return NULL; -} - -static struct cb_memory *CBMemTable; - -// Populate max ram and e820 map info by scanning for a coreboot table. -static void -coreboot_fill_map(void) -{ - dprintf(3, "Attempting to find coreboot table\n"); - - CBMemTable = NULL; - - // Find coreboot table. - struct cb_header *cbh = find_cb_header(0, 0x1000); - if (!cbh) - goto fail; - struct cb_forward *cbf = find_cb_subtable(cbh, CB_TAG_FORWARD); - if (cbf) { - dprintf(3, "Found coreboot table forwarder.\n"); - cbh = find_cb_header((char *)((u32)cbf->forward), 0x100); - if (!cbh) - goto fail; - } - dprintf(3, "Now attempting to find coreboot memory map\n"); - struct cb_memory *cbm = CBMemTable = find_cb_subtable(cbh, CB_TAG_MEMORY); - if (!cbm) - goto fail; - - u64 maxram = 0, maxram_over4G = 0; - int i, count = MEM_RANGE_COUNT(cbm); - for (i=0; imap[i]; - u32 type = m->type; - if (type == CB_MEM_TABLE) { - type = E820_RESERVED; - } else if (type == E820_ACPI || type == E820_RAM) { - u64 end = m->start + m->size; - if (end > 0x100000000ull) { - end -= 0x100000000ull; - if (end > maxram_over4G) - maxram_over4G = end; - } else if (end > maxram) - maxram = end; - } - add_e820(m->start, m->size, type); - } - - RamSize = maxram; - RamSizeOver4G = maxram_over4G; - - // Ughh - coreboot likes to set a map at 0x0000-0x1000, but this - // confuses grub. So, override it. - add_e820(0, 16*1024, E820_RAM); - - struct cb_mainboard *cbmb = find_cb_subtable(cbh, CB_TAG_MAINBOARD); - if (cbmb) { - const char *vendor = &cbmb->strings[cbmb->vendor_idx]; - const char *part = &cbmb->strings[cbmb->part_idx]; - dprintf(1, "Found mainboard %s %s\n", vendor, part); - - vgahook_setup(vendor, part); - } - - return; - -fail: - // No table found.. Use 16Megs as a dummy value. - dprintf(1, "Unable to find coreboot table!\n"); - RamSize = 16*1024*1024; - RamSizeOver4G = 0; - add_e820(0, 16*1024*1024, E820_RAM); - return; -} - - -/**************************************************************** - * BIOS table copying - ****************************************************************/ - -static void -copy_pir(void *pos) -{ - struct pir_header *p = pos; - if (p->signature != PIR_SIGNATURE) - return; - if (PirOffset) - return; - if (p->size < sizeof(*p)) - return; - if (checksum(pos, p->size) != 0) - return; - void *newpos = malloc_fseg(p->size); - if (!newpos) { - warn_noalloc(); - return; - } - dprintf(1, "Copying PIR from %p to %p\n", pos, newpos); - memcpy(newpos, pos, p->size); - PirOffset = (u32)newpos - BUILD_BIOS_ADDR; -} - -static void -copy_mptable(void *pos) -{ - struct mptable_floating_s *p = pos; - if (p->signature != MPTABLE_SIGNATURE) - return; - if (!p->physaddr) - return; - if (checksum(pos, sizeof(*p)) != 0) - return; - u32 length = p->length * 16; - u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length; - struct mptable_floating_s *newpos = malloc_fseg(length + mpclength); - if (!newpos) { - warn_noalloc(); - return; - } - dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos); - memcpy(newpos, pos, length); - newpos->physaddr = (u32)newpos + length; - newpos->checksum -= checksum(newpos, sizeof(*newpos)); - memcpy((void*)newpos + length, (void*)p->physaddr, mpclength); -} - -static void -copy_acpi_rsdp(void *pos) -{ - if (RsdpAddr) - return; - struct rsdp_descriptor *p = pos; - if (p->signature != RSDP_SIGNATURE) - return; - u32 length = 20; - if (checksum(pos, length) != 0) - return; - if (p->revision > 1) { - length = p->length; - if (checksum(pos, length) != 0) - return; - } - void *newpos = malloc_fseg(length); - if (!newpos) { - warn_noalloc(); - return; - } - dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos); - memcpy(newpos, pos, length); - RsdpAddr = newpos; -} - -// Attempt to find (and relocate) any standard bios tables found in a -// given address range. -static void -scan_tables(u32 start, u32 size) -{ - void *p = (void*)ALIGN(start, 16); - void *end = (void*)start + size; - for (; pmap[i]; - if (m->type == CB_MEM_TABLE) - scan_tables(m->start, m->size); - } - - // XXX - just create dummy smbios table for now - should detect if - // smbios/dmi table is found from coreboot and use that instead. - smbios_init(); -} - - -/**************************************************************** - * ulzma - ****************************************************************/ - -// Uncompress data in flash to an area of memory. -static int -ulzma(u8 *dst, u32 maxlen, const u8 *src, u32 srclen) -{ - dprintf(3, "Uncompressing data %d@%p to %d@%p\n", srclen, src, maxlen, dst); - CLzmaDecoderState state; - int ret = LzmaDecodeProperties(&state.Properties, src, LZMA_PROPERTIES_SIZE); - if (ret != LZMA_RESULT_OK) { - dprintf(1, "LzmaDecodeProperties error - %d\n", ret); - return -1; - } - u8 scratch[15980]; - int need = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - if (need > sizeof(scratch)) { - dprintf(1, "LzmaDecode need %d have %d\n", need, (unsigned int)sizeof(scratch)); - return -1; - } - state.Probs = (CProb *)scratch; - - u32 dstlen = *(u32*)(src + LZMA_PROPERTIES_SIZE); - if (dstlen > maxlen) { - dprintf(1, "LzmaDecode too large (max %d need %d)\n", maxlen, dstlen); - return -1; - } - u32 inProcessed, outProcessed; - ret = LzmaDecode(&state, src + LZMA_PROPERTIES_SIZE + 8, srclen - , &inProcessed, dst, dstlen, &outProcessed); - if (ret) { - dprintf(1, "LzmaDecode returned %d\n", ret); - return -1; - } - return dstlen; -} - - -/**************************************************************** - * Coreboot flash format - ****************************************************************/ - -#define CBFS_HEADER_MAGIC 0x4F524243 -#define CBFS_HEADPTR_ADDR 0xFFFFFFFc -#define CBFS_VERSION1 0x31313131 - -struct cbfs_header { - u32 magic; - u32 version; - u32 romsize; - u32 bootblocksize; - u32 align; - u32 offset; - u32 pad[2]; -} PACKED; - -static struct cbfs_header *CBHDR; - -static void -cbfs_setup(void) -{ - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) - return; - - CBHDR = *(void **)CBFS_HEADPTR_ADDR; - if (CBHDR->magic != htonl(CBFS_HEADER_MAGIC)) { - dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n" - , CBHDR, CBHDR->magic, htonl(CBFS_HEADER_MAGIC)); - CBHDR = NULL; - return; - } - - dprintf(1, "Found CBFS header at %p\n", CBHDR); -} - -#define CBFS_FILE_MAGIC 0x455649484352414cLL // LARCHIVE - -struct cbfs_file { - u64 magic; - u32 len; - u32 type; - u32 checksum; - u32 offset; - char filename[0]; -} PACKED; - -// Verify a cbfs entry looks valid. -static struct cbfs_file * -cbfs_verify(struct cbfs_file *file) -{ - if (file < (struct cbfs_file *)(0xFFFFFFFF - ntohl(CBHDR->romsize))) - return NULL; - u64 magic = file->magic; - if (magic == CBFS_FILE_MAGIC) { - dprintf(5, "Found CBFS file %s\n", file->filename); - return file; - } - return NULL; -} - -// Return the first file in the CBFS archive -static struct cbfs_file * -cbfs_getfirst(void) -{ - if (! CBHDR) - return NULL; - return cbfs_verify((void *)(0 - ntohl(CBHDR->romsize) + ntohl(CBHDR->offset))); -} - -// Return the file after the given file. -static struct cbfs_file * -cbfs_getnext(struct cbfs_file *file) -{ - file = (void*)file + ALIGN(ntohl(file->len) + ntohl(file->offset), ntohl(CBHDR->align)); - return cbfs_verify(file); -} - -// Find the file with the given filename. -struct cbfs_file * -cbfs_findfile(const char *fname) -{ - dprintf(3, "Searching CBFS for %s\n", fname); - struct cbfs_file *file; - for (file = cbfs_getfirst(); file; file = cbfs_getnext(file)) - if (strcmp(fname, file->filename) == 0) - return file; - return NULL; -} - -// Find next file with the given filename prefix. -struct cbfs_file * -cbfs_findprefix(const char *prefix, struct cbfs_file *last) -{ - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) - return NULL; - - dprintf(3, "Searching CBFS for prefix %s\n", prefix); - int len = strlen(prefix); - struct cbfs_file *file; - if (! last) - file = cbfs_getfirst(); - else - file = cbfs_getnext(last); - for (; file; file = cbfs_getnext(file)) - if (memcmp(prefix, file->filename, len) == 0) - return file; - return NULL; -} - -// Find a file with the given filename (possibly with ".lzma" extension). -struct cbfs_file * -cbfs_finddatafile(const char *fname) -{ - int fnlen = strlen(fname); - struct cbfs_file *file = NULL; - for (;;) { - file = cbfs_findprefix(fname, file); - if (!file) - return NULL; - if (file->filename[fnlen] == '\0' - || strcmp(&file->filename[fnlen], ".lzma") == 0) - return file; - } -} - -// Determine whether the file has a ".lzma" extension. -static int -cbfs_iscomp(struct cbfs_file *file) -{ - int fnamelen = strlen(file->filename); - return fnamelen > 5 && strcmp(&file->filename[fnamelen-5], ".lzma") == 0; -} - -// Return the filename of a given file. -const char * -cbfs_filename(struct cbfs_file *file) -{ - return file->filename; -} - -// Determine the uncompressed size of a datafile. -u32 -cbfs_datasize(struct cbfs_file *file) -{ - void *src = (void*)file + ntohl(file->offset); - if (cbfs_iscomp(file)) - return *(u32*)(src + LZMA_PROPERTIES_SIZE); - return ntohl(file->len); -} - -// Copy a file to memory (uncompressing if necessary) -int -cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen) -{ - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !file) - return -1; - - u32 size = ntohl(file->len); - void *src = (void*)file + ntohl(file->offset); - if (cbfs_iscomp(file)) { - // Compressed - copy to temp ram and uncompress it. - void *temp = malloc_tmphigh(size); - if (!temp) - return -1; - iomemcpy(temp, src, size); - int ret = ulzma(dst, maxlen, temp, size); - yield(); - free(temp); - return ret; - } - - // Not compressed. - dprintf(3, "Copying data %d@%p to %d@%p\n", size, src, maxlen, dst); - if (size > maxlen) { - warn_noalloc(); - return -1; - } - iomemcpy(dst, src, size); - return size; -} - -struct cbfs_payload_segment { - u32 type; - u32 compression; - u32 offset; - u64 load_addr; - u32 len; - u32 mem_len; -} PACKED; - -#define PAYLOAD_SEGMENT_BSS 0x20535342 -#define PAYLOAD_SEGMENT_ENTRY 0x52544E45 - -#define CBFS_COMPRESS_NONE 0 -#define CBFS_COMPRESS_LZMA 1 - -struct cbfs_payload { - struct cbfs_payload_segment segments[1]; -}; - -void -cbfs_run_payload(struct cbfs_file *file) -{ - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !file) - return; - dprintf(1, "Run %s\n", file->filename); - struct cbfs_payload *pay = (void*)file + ntohl(file->offset); - struct cbfs_payload_segment *seg = pay->segments; - for (;;) { - void *src = (void*)pay + ntohl(seg->offset); - void *dest = (void*)ntohl((u32)seg->load_addr); - u32 src_len = ntohl(seg->len); - u32 dest_len = ntohl(seg->mem_len); - switch (seg->type) { - case PAYLOAD_SEGMENT_BSS: - dprintf(3, "BSS segment %d@%p\n", dest_len, dest); - memset(dest, 0, dest_len); - break; - case PAYLOAD_SEGMENT_ENTRY: { - dprintf(1, "Calling addr %p\n", dest); - void (*func)() = dest; - func(); - return; - } - default: - dprintf(3, "Segment %x %d@%p -> %d@%p\n" - , seg->type, src_len, src, dest_len, dest); - if (seg->compression == htonl(CBFS_COMPRESS_NONE)) { - if (src_len > dest_len) - src_len = dest_len; - memcpy(dest, src, src_len); - } else if (CONFIG_LZMA - && seg->compression == htonl(CBFS_COMPRESS_LZMA)) { - int ret = ulzma(dest, dest_len, src, src_len); - if (ret < 0) - return; - src_len = ret; - } else { - dprintf(1, "No support for compression type %x\n" - , seg->compression); - return; - } - if (dest_len > src_len) - memset(dest + src_len, 0, dest_len - src_len); - break; - } - seg++; - } -} - -void -coreboot_setup(void) -{ - coreboot_fill_map(); - cbfs_setup(); -} diff --git a/roms/seabios/src/dev-i440fx.c b/roms/seabios/src/dev-i440fx.c deleted file mode 100644 index 346f6d0..0000000 --- a/roms/seabios/src/dev-i440fx.c +++ /dev/null @@ -1,116 +0,0 @@ -// initialization function which are specific to i440fx chipset -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// Copyright (C) 2010 Isaku Yamahata -// Split out from pciinit.c -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -// - -#include "config.h" // CONFIG_DEBUG_LEVEL -#include "util.h" // dprintf -#include "ioport.h" // outb -#include "pci.h" // pci_config_writeb -#include "pci_ids.h" -#include "pci_regs.h" // PCI_INTERRUPT_LINE -#include "acpi.h" -#include "dev-i440fx.h" - -#define I440FX_PAM0 0x59 - -void i440fx_bios_make_writable(u16 bdf, void *arg) -{ - make_bios_writable_intel(bdf, I440FX_PAM0); -} - -void i440fx_bios_make_readonly(u16 bdf, void *arg) -{ - make_bios_readonly_intel(bdf, I440FX_PAM0); -} - -/* PIIX3/PIIX4 PCI to ISA bridge */ -void piix_isa_bridge_init(u16 bdf, void *arg) -{ - int i, irq; - u8 elcr[2]; - - elcr[0] = 0x00; - elcr[1] = 0x00; - for (i = 0; i < 4; i++) { - irq = pci_irqs[i]; - /* set to trigger level */ - elcr[irq >> 3] |= (1 << (irq & 7)); - /* activate irq remapping in PIIX */ - pci_config_writeb(bdf, 0x60 + i, irq); - } - outb(elcr[0], 0x4d0); - outb(elcr[1], 0x4d1); - dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]); -} - -/* PIIX3/PIIX4 IDE */ -void piix_ide_init(u16 bdf, void *arg) -{ - pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0 - pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1 - pci_bios_allocate_regions(bdf, NULL); -} - -/* PIIX4 Power Management device (for ACPI) */ -void piix4_pm_init(u16 bdf, void *arg) -{ - // acpi sci is hardwired to 9 - pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9); - - pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1); - pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */ - pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1); - pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */ -} - -#define PIIX4_ACPI_ENABLE 0xf1 -#define PIIX4_ACPI_DISABLE 0xf0 -#define PIIX4_GPE0_BLK 0xafe0 -#define PIIX4_GPE0_BLK_LEN 4 - -void piix4_fadt_init(u16 bdf, void *arg) -{ - struct fadt_descriptor_rev1 *fadt = arg; - fadt->acpi_enable = PIIX4_ACPI_ENABLE; - fadt->acpi_disable = PIIX4_ACPI_DISABLE; - fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK); - fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN; -} - -#define I440FX_SMRAM 0x72 -#define PIIX_DEVACTB 0x58 -#define PIIX_APMC_EN (1 << 25) - -// This code is hardcoded for PIIX4 Power Management device. -void piix4_apmc_smm_init(u16 bdf, void *arg) -{ - int i440_bdf = pci_find_device(PCI_VENDOR_ID_INTEL - , PCI_DEVICE_ID_INTEL_82441); - if (i440_bdf < 0) - return; - - /* check if SMM init is already done */ - u32 value = pci_config_readl(bdf, PIIX_DEVACTB); - if (value & PIIX_APMC_EN) - return; - - /* enable the SMM memory window */ - pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x48); - - smm_save_and_copy(); - - /* enable SMI generation when writing to the APMC register */ - pci_config_writel(bdf, PIIX_DEVACTB, value | PIIX_APMC_EN); - - smm_relocate_and_restore(); - - /* close the SMM memory window and enable normal SMM */ - pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x08); -} diff --git a/roms/seabios/src/dev-i440fx.h b/roms/seabios/src/dev-i440fx.h deleted file mode 100644 index ab5a4d1..0000000 --- a/roms/seabios/src/dev-i440fx.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __I440FX_H -#define __I440FX_H - -#include "types.h" // u16 - -void i440fx_bios_make_writable(u16 bdf, void *arg); -void i440fx_bios_make_readonly(u16 bdf, void *arg); -void piix_isa_bridge_init(u16 bdf, void *arg); -void piix_ide_init(u16 bdf, void *arg); -void piix4_pm_init(u16 bdf, void *arg); -void piix4_fadt_init(u16 bdf, void *arg); -void piix4_apmc_smm_init(u16 bdf, void *arg); - -#endif // __I440FX_H diff --git a/roms/seabios/src/disk.c b/roms/seabios/src/disk.c deleted file mode 100644 index 242c742..0000000 --- a/roms/seabios/src/disk.c +++ /dev/null @@ -1,864 +0,0 @@ -// 16bit code to access hard drives. -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "disk.h" // floppy_13 -#include "biosvar.h" // SET_BDA -#include "config.h" // CONFIG_* -#include "util.h" // debug_enter -#include "pic.h" // eoi_pic2 -#include "bregs.h" // struct bregs -#include "pci.h" // pci_bdf_to_bus -#include "ata.h" // ATA_CB_DC - - -/**************************************************************** - * Helper functions - ****************************************************************/ - -void -__disk_ret(struct bregs *regs, u32 linecode, const char *fname) -{ - u8 code = linecode; - if (regs->dl < EXTSTART_HD) - SET_BDA(floppy_last_status, code); - else - SET_BDA(disk_last_status, code); - if (code) - __set_code_invalid(regs, linecode, fname); - else - set_code_success(regs); -} - -void -__disk_ret_unimplemented(struct bregs *regs, u32 linecode, const char *fname) -{ - u8 code = linecode; - if (regs->dl < EXTSTART_HD) - SET_BDA(floppy_last_status, code); - else - SET_BDA(disk_last_status, code); - __set_code_unimplemented(regs, linecode, fname); -} - -static void -__disk_stub(struct bregs *regs, int lineno, const char *fname) -{ - __warn_unimplemented(regs, lineno, fname); - __disk_ret(regs, DISK_RET_SUCCESS | (lineno << 8), fname); -} - -#define DISK_STUB(regs) \ - __disk_stub((regs), __LINE__, __func__) - -// Get the cylinders/heads/sectors for the given drive. -static void -fillLCHS(struct drive_s *drive_g, u16 *nlc, u16 *nlh, u16 *nlspt) -{ - if (CONFIG_CDROM_EMU - && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) { - // Emulated drive - get info from ebda. (It's not possible to - // populate the geometry directly in the driveid because the - // geometry is only known after the bios segment is made - // read-only). - u16 ebda_seg = get_ebda_seg(); - *nlc = GET_EBDA2(ebda_seg, cdemu.lchs.cylinders); - *nlh = GET_EBDA2(ebda_seg, cdemu.lchs.heads); - *nlspt = GET_EBDA2(ebda_seg, cdemu.lchs.spt); - return; - } - *nlc = GET_GLOBAL(drive_g->lchs.cylinders); - *nlh = GET_GLOBAL(drive_g->lchs.heads); - *nlspt = GET_GLOBAL(drive_g->lchs.spt); -} - -// Perform read/write/verify using old-style chs accesses -static void -basic_access(struct bregs *regs, struct drive_s *drive_g, u16 command) -{ - struct disk_op_s dop; - dop.drive_g = drive_g; - dop.command = command; - - u8 count = regs->al; - u16 cylinder = regs->ch | ((((u16)regs->cl) << 2) & 0x300); - u16 sector = regs->cl & 0x3f; - u16 head = regs->dh; - - if (count > 128 || count == 0 || sector == 0) { - warn_invalid(regs); - disk_ret(regs, DISK_RET_EPARAM); - return; - } - dop.count = count; - - u16 nlc, nlh, nlspt; - fillLCHS(drive_g, &nlc, &nlh, &nlspt); - - // sanity check on cyl heads, sec - if (cylinder >= nlc || head >= nlh || sector > nlspt) { - warn_invalid(regs); - disk_ret(regs, DISK_RET_EPARAM); - return; - } - - // translate lchs to lba - dop.lba = (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt) - + (u32)sector - 1); - - dop.buf_fl = MAKE_FLATPTR(regs->es, regs->bx); - - int status = send_disk_op(&dop); - - regs->al = dop.count; - - disk_ret(regs, status); -} - -// Perform read/write/verify using new-style "int13ext" accesses. -static void -extended_access(struct bregs *regs, struct drive_s *drive_g, u16 command) -{ - struct disk_op_s dop; - // Get lba and check. - dop.lba = GET_INT13EXT(regs, lba); - dop.command = command; - dop.drive_g = drive_g; - if (dop.lba >= GET_GLOBAL(drive_g->sectors)) { - warn_invalid(regs); - disk_ret(regs, DISK_RET_EPARAM); - return; - } - - dop.buf_fl = SEGOFF_TO_FLATPTR(GET_INT13EXT(regs, data)); - dop.count = GET_INT13EXT(regs, count); - - int status = send_disk_op(&dop); - - SET_INT13EXT(regs, count, dop.count); - - disk_ret(regs, status); -} - - -/**************************************************************** - * Hard Drive functions - ****************************************************************/ - -// disk controller reset -static void -disk_1300(struct bregs *regs, struct drive_s *drive_g) -{ - struct disk_op_s dop; - dop.drive_g = drive_g; - dop.command = CMD_RESET; - int status = send_disk_op(&dop); - disk_ret(regs, status); -} - -// read disk status -static void -disk_1301(struct bregs *regs, struct drive_s *drive_g) -{ - u8 v; - if (regs->dl < EXTSTART_HD) - // Floppy - v = GET_BDA(floppy_last_status); - else - v = GET_BDA(disk_last_status); - regs->ah = v; - set_cf(regs, v); - // XXX - clear disk_last_status? -} - -// read disk sectors -static void -disk_1302(struct bregs *regs, struct drive_s *drive_g) -{ - basic_access(regs, drive_g, CMD_READ); -} - -// write disk sectors -static void -disk_1303(struct bregs *regs, struct drive_s *drive_g) -{ - basic_access(regs, drive_g, CMD_WRITE); -} - -// verify disk sectors -static void -disk_1304(struct bregs *regs, struct drive_s *drive_g) -{ - basic_access(regs, drive_g, CMD_VERIFY); -} - -// format disk track -static void -disk_1305(struct bregs *regs, struct drive_s *drive_g) -{ - debug_stub(regs); - - u16 nlc, nlh, nlspt; - fillLCHS(drive_g, &nlc, &nlh, &nlspt); - - u8 num_sectors = regs->al; - u8 head = regs->dh; - - if (head >= nlh || num_sectors == 0 || num_sectors > nlspt) { - disk_ret(regs, DISK_RET_EPARAM); - return; - } - - struct disk_op_s dop; - dop.drive_g = drive_g; - dop.command = CMD_FORMAT; - dop.lba = head; - dop.count = num_sectors; - dop.buf_fl = MAKE_FLATPTR(regs->es, regs->bx); - int status = send_disk_op(&dop); - disk_ret(regs, status); -} - -// read disk drive parameters -static void -disk_1308(struct bregs *regs, struct drive_s *drive_g) -{ - u16 ebda_seg = get_ebda_seg(); - // Get logical geometry from table - u16 nlc, nlh, nlspt; - fillLCHS(drive_g, &nlc, &nlh, &nlspt); - nlc--; - nlh--; - u8 count; - if (regs->dl < EXTSTART_HD) { - // Floppy - count = GET_GLOBAL(Drives.floppycount); - - if (CONFIG_CDROM_EMU - && drive_g == GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf))) - regs->bx = GET_EBDA2(ebda_seg, cdemu.media) * 2; - else - regs->bx = GET_GLOBAL(drive_g->floppy_type); - - // set es & di to point to 11 byte diskette param table in ROM - regs->es = SEG_BIOS; - regs->di = (u32)&diskette_param_table2; - } else if (regs->dl < EXTSTART_CD) { - // Hard drive - count = GET_BDA(hdcount); - nlc--; // last sector reserved - } else { - // Not supported on CDROM - disk_ret(regs, DISK_RET_EPARAM); - return; - } - - if (CONFIG_CDROM_EMU && GET_EBDA2(ebda_seg, cdemu.active)) { - u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); - if (((emudrive ^ regs->dl) & 0x80) == 0) - // Note extra drive due to emulation. - count++; - if (regs->dl < EXTSTART_HD && count > 2) - // Max of two floppy drives. - count = 2; - } - - regs->al = 0; - regs->ch = nlc & 0xff; - regs->cl = ((nlc >> 2) & 0xc0) | (nlspt & 0x3f); - regs->dh = nlh; - - disk_ret(regs, DISK_RET_SUCCESS); - regs->dl = count; -} - -// initialize drive parameters -static void -disk_1309(struct bregs *regs, struct drive_s *drive_g) -{ - DISK_STUB(regs); -} - -// seek to specified cylinder -static void -disk_130c(struct bregs *regs, struct drive_s *drive_g) -{ - DISK_STUB(regs); -} - -// alternate disk reset -static void -disk_130d(struct bregs *regs, struct drive_s *drive_g) -{ - DISK_STUB(regs); -} - -// check drive ready -static void -disk_1310(struct bregs *regs, struct drive_s *drive_g) -{ - // should look at 40:8E also??? - - struct disk_op_s dop; - dop.drive_g = drive_g; - dop.command = CMD_ISREADY; - int status = send_disk_op(&dop); - disk_ret(regs, status); -} - -// recalibrate -static void -disk_1311(struct bregs *regs, struct drive_s *drive_g) -{ - DISK_STUB(regs); -} - -// controller internal diagnostic -static void -disk_1314(struct bregs *regs, struct drive_s *drive_g) -{ - DISK_STUB(regs); -} - -// read disk drive size -static void -disk_1315(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret(regs, DISK_RET_SUCCESS); - if (regs->dl < EXTSTART_HD || regs->dl >= EXTSTART_CD) { - // Floppy or cdrom - regs->ah = 1; - return; - } - // Hard drive - - // Get logical geometry from table - u16 nlc, nlh, nlspt; - fillLCHS(drive_g, &nlc, &nlh, &nlspt); - - // Compute sector count seen by int13 - u32 lba = (u32)(nlc - 1) * (u32)nlh * (u32)nlspt; - regs->cx = lba >> 16; - regs->dx = lba & 0xffff; - regs->ah = 3; // hard disk accessible -} - -static void -disk_1316(struct bregs *regs, struct drive_s *drive_g) -{ - if (regs->dl >= EXTSTART_HD) { - // Hard drive - disk_ret(regs, DISK_RET_EPARAM); - return; - } - disk_ret(regs, DISK_RET_ECHANGED); -} - -// IBM/MS installation check -static void -disk_1341(struct bregs *regs, struct drive_s *drive_g) -{ - regs->bx = 0xaa55; // install check - regs->cx = 0x0007; // ext disk access and edd, removable supported - disk_ret(regs, DISK_RET_SUCCESS); - regs->ah = 0x30; // EDD 3.0 -} - -// IBM/MS extended read -static void -disk_1342(struct bregs *regs, struct drive_s *drive_g) -{ - extended_access(regs, drive_g, CMD_READ); -} - -// IBM/MS extended write -static void -disk_1343(struct bregs *regs, struct drive_s *drive_g) -{ - extended_access(regs, drive_g, CMD_WRITE); -} - -// IBM/MS verify -static void -disk_1344(struct bregs *regs, struct drive_s *drive_g) -{ - extended_access(regs, drive_g, CMD_VERIFY); -} - -// lock -static void -disk_134500(struct bregs *regs, struct drive_s *drive_g) -{ - u16 ebda_seg = get_ebda_seg(); - int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA2(ebda_seg, cdrom_locks[cdid]); - if (locks == 0xff) { - regs->al = 1; - disk_ret(regs, DISK_RET_ETOOMANYLOCKS); - return; - } - SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks + 1); - regs->al = 1; - disk_ret(regs, DISK_RET_SUCCESS); -} - -// unlock -static void -disk_134501(struct bregs *regs, struct drive_s *drive_g) -{ - u16 ebda_seg = get_ebda_seg(); - int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA2(ebda_seg, cdrom_locks[cdid]); - if (locks == 0x00) { - regs->al = 0; - disk_ret(regs, DISK_RET_ENOTLOCKED); - return; - } - locks--; - SET_EBDA2(ebda_seg, cdrom_locks[cdid], locks); - regs->al = (locks ? 1 : 0); - disk_ret(regs, DISK_RET_SUCCESS); -} - -// status -static void -disk_134502(struct bregs *regs, struct drive_s *drive_g) -{ - int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA(cdrom_locks[cdid]); - regs->al = (locks ? 1 : 0); - disk_ret(regs, DISK_RET_SUCCESS); -} - -static void -disk_1345XX(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret_unimplemented(regs, DISK_RET_EPARAM); -} - -// IBM/MS lock/unlock drive -static void -disk_1345(struct bregs *regs, struct drive_s *drive_g) -{ - if (regs->dl < EXTSTART_CD) { - // Always success for HD - disk_ret(regs, DISK_RET_SUCCESS); - return; - } - - switch (regs->al) { - case 0x00: disk_134500(regs, drive_g); break; - case 0x01: disk_134501(regs, drive_g); break; - case 0x02: disk_134502(regs, drive_g); break; - default: disk_1345XX(regs, drive_g); break; - } -} - -// IBM/MS eject media -static void -disk_1346(struct bregs *regs, struct drive_s *drive_g) -{ - if (regs->dl < EXTSTART_CD) { - // Volume Not Removable - disk_ret(regs, DISK_RET_ENOTREMOVABLE); - return; - } - - int cdid = regs->dl - EXTSTART_CD; - u8 locks = GET_EBDA(cdrom_locks[cdid]); - if (locks != 0) { - disk_ret(regs, DISK_RET_ELOCKED); - return; - } - - // FIXME should handle 0x31 no media in device - // FIXME should handle 0xb5 valid request failed - - // Call removable media eject - struct bregs br; - memset(&br, 0, sizeof(br)); - br.ah = 0x52; - br.dl = regs->dl; - call16_int(0x15, &br); - - if (br.ah || br.flags & F_CF) { - disk_ret(regs, DISK_RET_ELOCKED); - return; - } - disk_ret(regs, DISK_RET_SUCCESS); -} - -// IBM/MS extended seek -static void -disk_1347(struct bregs *regs, struct drive_s *drive_g) -{ - extended_access(regs, drive_g, CMD_SEEK); -} - -// IBM/MS get drive parameters -static void -disk_1348(struct bregs *regs, struct drive_s *drive_g) -{ - u16 size = GET_INT13DPT(regs, size); - - // Buffer is too small - if (size < 26) { - disk_ret(regs, DISK_RET_EPARAM); - return; - } - - // EDD 1.x - - u8 type = GET_GLOBAL(drive_g->type); - u16 npc = GET_GLOBAL(drive_g->pchs.cylinders); - u16 nph = GET_GLOBAL(drive_g->pchs.heads); - u16 npspt = GET_GLOBAL(drive_g->pchs.spt); - u64 lba = GET_GLOBAL(drive_g->sectors); - u16 blksize = GET_GLOBAL(drive_g->blksize); - - dprintf(DEBUG_HDL_13, "disk_1348 size=%d t=%d chs=%d,%d,%d lba=%d bs=%d\n" - , size, type, npc, nph, npspt, (u32)lba, blksize); - - SET_INT13DPT(regs, size, 26); - if (type == DTYPE_ATAPI) { - // 0x74 = removable, media change, lockable, max values - SET_INT13DPT(regs, infos, 0x74); - SET_INT13DPT(regs, cylinders, 0xffffffff); - SET_INT13DPT(regs, heads, 0xffffffff); - SET_INT13DPT(regs, spt, 0xffffffff); - SET_INT13DPT(regs, sector_count, (u64)-1); - } else { - if (lba > (u64)npspt*nph*0x3fff) { - SET_INT13DPT(regs, infos, 0x00); // geometry is invalid - SET_INT13DPT(regs, cylinders, 0x3fff); - } else { - SET_INT13DPT(regs, infos, 0x02); // geometry is valid - SET_INT13DPT(regs, cylinders, (u32)npc); - } - SET_INT13DPT(regs, heads, (u32)nph); - SET_INT13DPT(regs, spt, (u32)npspt); - SET_INT13DPT(regs, sector_count, lba); - } - SET_INT13DPT(regs, blksize, blksize); - - if (size < 30 || (type != DTYPE_ATA && type != DTYPE_ATAPI)) { - disk_ret(regs, DISK_RET_SUCCESS); - return; - } - - // EDD 2.x - - u16 ebda_seg = get_ebda_seg(); - SET_INT13DPT(regs, size, 30); - - SET_INT13DPT(regs, dpte_segment, ebda_seg); - SET_INT13DPT(regs, dpte_offset - , offsetof(struct extended_bios_data_area_s, dpte)); - - // Fill in dpte - struct atadrive_s *adrive_g = container_of( - drive_g, struct atadrive_s, drive); - struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf); - u8 slave = GET_GLOBAL(adrive_g->slave); - u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1); - u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2); - u8 irq = GET_GLOBALFLAT(chan_gf->irq); - - u16 options = 0; - if (type == DTYPE_ATA) { - u8 translation = GET_GLOBAL(drive_g->translation); - if (translation != TRANSLATION_NONE) { - options |= 1<<3; // CHS translation - if (translation == TRANSLATION_LBA) - options |= 1<<9; - if (translation == TRANSLATION_RECHS) - options |= 3<<9; - } - } else { - // ATAPI - options |= 1<<5; // removable device - options |= 1<<6; // atapi device - } - options |= 1<<4; // lba translation - if (CONFIG_ATA_PIO32) - options |= 1<<7; - - SET_EBDA2(ebda_seg, dpte.iobase1, iobase1); - SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC); - SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) - | ATA_CB_DH_LBA)); - SET_EBDA2(ebda_seg, dpte.unused, 0xcb); - SET_EBDA2(ebda_seg, dpte.irq, irq); - SET_EBDA2(ebda_seg, dpte.blkcount, 1); - SET_EBDA2(ebda_seg, dpte.dma, 0); - SET_EBDA2(ebda_seg, dpte.pio, 0); - SET_EBDA2(ebda_seg, dpte.options, options); - SET_EBDA2(ebda_seg, dpte.reserved, 0); - SET_EBDA2(ebda_seg, dpte.revision, 0x11); - - u8 sum = checksum_far( - ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15); - SET_EBDA2(ebda_seg, dpte.checksum, -sum); - - if (size < 66) { - disk_ret(regs, DISK_RET_SUCCESS); - return; - } - - // EDD 3.x - SET_INT13DPT(regs, key, 0xbedd); - SET_INT13DPT(regs, dpi_length, 36); - SET_INT13DPT(regs, reserved1, 0); - SET_INT13DPT(regs, reserved2, 0); - - int bdf = GET_GLOBALFLAT(chan_gf->pci_bdf); - if (bdf != -1) { - SET_INT13DPT(regs, host_bus[0], 'P'); - SET_INT13DPT(regs, host_bus[1], 'C'); - SET_INT13DPT(regs, host_bus[2], 'I'); - SET_INT13DPT(regs, host_bus[3], 0); - - u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8) - | (pci_bdf_to_fn(bdf) << 16)); - SET_INT13DPT(regs, iface_path, path); - } else { - // ISA - SET_INT13DPT(regs, host_bus[0], 'I'); - SET_INT13DPT(regs, host_bus[1], 'S'); - SET_INT13DPT(regs, host_bus[2], 'A'); - SET_INT13DPT(regs, host_bus[3], 0); - - SET_INT13DPT(regs, iface_path, iobase1); - } - - SET_INT13DPT(regs, iface_type[0], 'A'); - SET_INT13DPT(regs, iface_type[1], 'T'); - SET_INT13DPT(regs, iface_type[2], 'A'); - SET_INT13DPT(regs, iface_type[3], 0); - SET_INT13DPT(regs, iface_type[4], 0); - SET_INT13DPT(regs, iface_type[5], 0); - SET_INT13DPT(regs, iface_type[6], 0); - SET_INT13DPT(regs, iface_type[7], 0); - - SET_INT13DPT(regs, device_path, slave); - - SET_INT13DPT(regs, checksum - , -checksum_far(regs->ds, (void*)(regs->si+30), 35)); - - disk_ret(regs, DISK_RET_SUCCESS); -} - -// IBM/MS extended media change -static void -disk_1349(struct bregs *regs, struct drive_s *drive_g) -{ - if (regs->dl < EXTSTART_CD) { - // Always success for HD - disk_ret(regs, DISK_RET_SUCCESS); - return; - } - set_invalid(regs); - // always send changed ?? - regs->ah = DISK_RET_ECHANGED; -} - -static void -disk_134e01(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret(regs, DISK_RET_SUCCESS); -} - -static void -disk_134e03(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret(regs, DISK_RET_SUCCESS); -} - -static void -disk_134e04(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret(regs, DISK_RET_SUCCESS); -} - -static void -disk_134e06(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret(regs, DISK_RET_SUCCESS); -} - -static void -disk_134eXX(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret(regs, DISK_RET_EPARAM); -} - -// IBM/MS set hardware configuration -static void -disk_134e(struct bregs *regs, struct drive_s *drive_g) -{ - switch (regs->al) { - case 0x01: disk_134e01(regs, drive_g); break; - case 0x03: disk_134e03(regs, drive_g); break; - case 0x04: disk_134e04(regs, drive_g); break; - case 0x06: disk_134e06(regs, drive_g); break; - default: disk_134eXX(regs, drive_g); break; - } -} - -static void -disk_13XX(struct bregs *regs, struct drive_s *drive_g) -{ - disk_ret_unimplemented(regs, DISK_RET_EPARAM); -} - -static void -disk_13(struct bregs *regs, struct drive_s *drive_g) -{ - //debug_stub(regs); - - // clear completion flag - SET_BDA(disk_interrupt_flag, 0); - - switch (regs->ah) { - case 0x00: disk_1300(regs, drive_g); break; - case 0x01: disk_1301(regs, drive_g); break; - case 0x02: disk_1302(regs, drive_g); break; - case 0x03: disk_1303(regs, drive_g); break; - case 0x04: disk_1304(regs, drive_g); break; - case 0x05: disk_1305(regs, drive_g); break; - case 0x08: disk_1308(regs, drive_g); break; - case 0x09: disk_1309(regs, drive_g); break; - case 0x0c: disk_130c(regs, drive_g); break; - case 0x0d: disk_130d(regs, drive_g); break; - case 0x10: disk_1310(regs, drive_g); break; - case 0x11: disk_1311(regs, drive_g); break; - case 0x14: disk_1314(regs, drive_g); break; - case 0x15: disk_1315(regs, drive_g); break; - case 0x16: disk_1316(regs, drive_g); break; - case 0x41: disk_1341(regs, drive_g); break; - case 0x42: disk_1342(regs, drive_g); break; - case 0x43: disk_1343(regs, drive_g); break; - case 0x44: disk_1344(regs, drive_g); break; - case 0x45: disk_1345(regs, drive_g); break; - case 0x46: disk_1346(regs, drive_g); break; - case 0x47: disk_1347(regs, drive_g); break; - case 0x48: disk_1348(regs, drive_g); break; - case 0x49: disk_1349(regs, drive_g); break; - case 0x4e: disk_134e(regs, drive_g); break; - default: disk_13XX(regs, drive_g); break; - } -} - -static void -floppy_13(struct bregs *regs, struct drive_s *drive_g) -{ - // Only limited commands are supported on floppies. - switch (regs->ah) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x08: - case 0x15: - case 0x16: - disk_13(regs, drive_g); - break; - default: disk_13XX(regs, drive_g); break; - } -} - - -/**************************************************************** - * Entry points - ****************************************************************/ - -static void -handle_legacy_disk(struct bregs *regs, u8 extdrive) -{ - if (! CONFIG_DRIVES) { - // XXX - support handle_1301 anyway? - disk_ret(regs, DISK_RET_EPARAM); - return; - } - - if (extdrive < EXTSTART_HD) { - struct drive_s *drive_g = getDrive(EXTTYPE_FLOPPY, extdrive); - if (!drive_g) - goto fail; - floppy_13(regs, drive_g); - return; - } - - struct drive_s *drive_g; - if (extdrive >= EXTSTART_CD) - drive_g = getDrive(EXTTYPE_CD, extdrive - EXTSTART_CD); - else - drive_g = getDrive(EXTTYPE_HD, extdrive - EXTSTART_HD); - if (!drive_g) - goto fail; - disk_13(regs, drive_g); - return; - -fail: - // XXX - support 1301/1308/1315 anyway? - disk_ret(regs, DISK_RET_EPARAM); -} - -void VISIBLE16 -handle_40(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_40); - handle_legacy_disk(regs, regs->dl); -} - -// INT 13h Fixed Disk Services Entry Point -void VISIBLE16 -handle_13(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_13); - u8 extdrive = regs->dl; - - if (CONFIG_CDROM_EMU) { - if (regs->ah == 0x4b) { - cdemu_134b(regs); - return; - } - u16 ebda_seg = get_ebda_seg(); - if (GET_EBDA2(ebda_seg, cdemu.active)) { - u8 emudrive = GET_EBDA2(ebda_seg, cdemu.emulated_extdrive); - if (extdrive == emudrive) { - // Access to an emulated drive. - struct drive_s *cdemu_g; - cdemu_g = GLOBALFLAT2GLOBAL(GET_GLOBAL(cdemu_drive_gf)); - if (regs->ah > 0x16) { - // Only old-style commands supported. - disk_13XX(regs, cdemu_g); - return; - } - disk_13(regs, cdemu_g); - return; - } - if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0) - // Adjust id to make room for emulated drive. - extdrive--; - } - } - handle_legacy_disk(regs, extdrive); -} - -// record completion in BIOS task complete flag -void VISIBLE16 -handle_76(void) -{ - debug_isr(DEBUG_ISR_76); - SET_BDA(disk_interrupt_flag, 0xff); - eoi_pic2(); -} - -// Old Fixed Disk Parameter Table (newer tables are in the ebda). -struct fdpt_s OldFDPT VAR16FIXED(0xe401); diff --git a/roms/seabios/src/disk.h b/roms/seabios/src/disk.h deleted file mode 100644 index 9e5b083..0000000 --- a/roms/seabios/src/disk.h +++ /dev/null @@ -1,258 +0,0 @@ -// Definitions for X86 bios disks. -// -// Copyright (C) 2008 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __DISK_H -#define __DISK_H - -#include "types.h" // u8 -#include "config.h" // CONFIG_* -#include "farptr.h" // struct segoff_s - -#define DISK_RET_SUCCESS 0x00 -#define DISK_RET_EPARAM 0x01 -#define DISK_RET_EADDRNOTFOUND 0x02 -#define DISK_RET_EWRITEPROTECT 0x03 -#define DISK_RET_ECHANGED 0x06 -#define DISK_RET_EBOUNDARY 0x09 -#define DISK_RET_EBADTRACK 0x0c -#define DISK_RET_ECONTROLLER 0x20 -#define DISK_RET_ETIMEOUT 0x80 -#define DISK_RET_ENOTLOCKED 0xb0 -#define DISK_RET_ELOCKED 0xb1 -#define DISK_RET_ENOTREMOVABLE 0xb2 -#define DISK_RET_ETOOMANYLOCKS 0xb4 -#define DISK_RET_EMEDIA 0xC0 -#define DISK_RET_ENOTREADY 0xAA - - -/**************************************************************** - * Interface structs - ****************************************************************/ - -// Bios disk structures. -struct int13ext_s { - u8 size; - u8 reserved; - u16 count; - struct segoff_s data; - u64 lba; -} PACKED; - -#define GET_INT13EXT(regs,var) \ - GET_FARVAR((regs)->ds, ((struct int13ext_s*)((regs)->si+0))->var) -#define SET_INT13EXT(regs,var,val) \ - SET_FARVAR((regs)->ds, ((struct int13ext_s*)((regs)->si+0))->var, (val)) - -// Disk Physical Table definition -struct int13dpt_s { - u16 size; - u16 infos; - u32 cylinders; - u32 heads; - u32 spt; - u64 sector_count; - u16 blksize; - u16 dpte_offset; - u16 dpte_segment; - u16 key; - u8 dpi_length; - u8 reserved1; - u16 reserved2; - u8 host_bus[4]; - u8 iface_type[8]; - u64 iface_path; - u64 device_path; - u8 reserved3; - u8 checksum; -} PACKED; - -#define GET_INT13DPT(regs,var) \ - GET_FARVAR((regs)->ds, ((struct int13dpt_s*)((regs)->si+0))->var) -#define SET_INT13DPT(regs,var,val) \ - SET_FARVAR((regs)->ds, ((struct int13dpt_s*)((regs)->si+0))->var, (val)) - -// Floppy "Disk Base Table" -struct floppy_dbt_s { - u8 specify1; - u8 specify2; - u8 shutoff_ticks; - u8 bps_code; - u8 sectors; - u8 interblock_len; - u8 data_len; - u8 gap_len; - u8 fill_byte; - u8 settle_time; - u8 startup_time; -} PACKED; - -struct floppy_ext_dbt_s { - struct floppy_dbt_s dbt; - // Extra fields - u8 max_track; - u8 data_rate; - u8 drive_type; -} PACKED; - -// Helper function for setting up a return code. -struct bregs; -void __disk_ret(struct bregs *regs, u32 linecode, const char *fname); -#define disk_ret(regs, code) \ - __disk_ret((regs), (code) | (__LINE__ << 8), __func__) -void __disk_ret_unimplemented(struct bregs *regs, u32 linecode - , const char *fname); -#define disk_ret_unimplemented(regs, code) \ - __disk_ret_unimplemented((regs), (code) | (__LINE__ << 8), __func__) - - -/**************************************************************** - * Master boot record - ****************************************************************/ - -struct packed_chs_s { - u8 heads; - u8 sptcyl; - u8 cyllow; -}; - -struct partition_s { - u8 status; - struct packed_chs_s first; - u8 type; - struct packed_chs_s last; - u32 lba; - u32 count; -} PACKED; - -struct mbr_s { - u8 code[440]; - // 0x01b8 - u32 diskseg; - // 0x01bc - u16 null; - // 0x01be - struct partition_s partitions[4]; - // 0x01fe - u16 signature; -} PACKED; - -#define MBR_SIGNATURE 0xaa55 - - -/**************************************************************** - * Disk command request - ****************************************************************/ - -struct disk_op_s { - u64 lba; - void *buf_fl; - struct drive_s *drive_g; - u16 count; - u8 command; -}; - -#define CMD_RESET 0x00 -#define CMD_READ 0x02 -#define CMD_WRITE 0x03 -#define CMD_VERIFY 0x04 -#define CMD_FORMAT 0x05 -#define CMD_SEEK 0x07 -#define CMD_ISREADY 0x10 - - -/**************************************************************** - * Global storage - ****************************************************************/ - -struct chs_s { - u16 heads; // # heads - u16 cylinders; // # cylinders - u16 spt; // # sectors / track -}; - -struct drive_s { - u8 type; // Driver type (DTYPE_*) - u8 floppy_type; // Type of floppy (only for floppy drives). - struct chs_s lchs; // Logical CHS - u64 sectors; // Total sectors count - char *desc; // Drive description (only available during POST) - u32 cntl_id; // Unique id for a given driver type. - u8 removable; // Is media removable (currently unused) - - // Info for EDD calls - u8 translation; // type of translation - u16 blksize; // block size - struct chs_s pchs; // Physical CHS -}; - -#define DISK_SECTOR_SIZE 512 -#define CDROM_SECTOR_SIZE 2048 - -#define DTYPE_NONE 0x00 -#define DTYPE_FLOPPY 0x01 -#define DTYPE_ATA 0x02 -#define DTYPE_ATAPI 0x03 -#define DTYPE_RAMDISK 0x04 -#define DTYPE_CDEMU 0x05 -#define DTYPE_USB 0x06 -#define DTYPE_VIRTIO 0x07 - -#define MAXDESCSIZE 80 - -#define TRANSLATION_NONE 0 -#define TRANSLATION_LBA 1 -#define TRANSLATION_LARGE 2 -#define TRANSLATION_RECHS 3 - -struct drives_s { - // map between bios floppy/hd/cd id and drive_s struct - u8 floppycount; - u8 cdcount; - struct drive_s *idmap[3][CONFIG_MAX_EXTDRIVE]; -}; - -#define EXTTYPE_FLOPPY 0 -#define EXTTYPE_HD 1 -#define EXTTYPE_CD 2 - -#define EXTSTART_HD 0x80 -#define EXTSTART_CD 0xE0 - - -/**************************************************************** - * Function defs - ****************************************************************/ - -// block.c -extern struct drives_s Drives; -struct drive_s *getDrive(u8 exttype, u8 extdriveoffset); -void setup_translation(struct drive_s *drive_g); -void map_floppy_drive(struct drive_s *drive_g); -void map_hd_drive(struct drive_s *drive_g); -void map_cd_drive(struct drive_s *drive_g); -int process_op(struct disk_op_s *op); -int send_disk_op(struct disk_op_s *op); -void drive_setup(void); - -// floppy.c -extern struct floppy_ext_dbt_s diskette_param_table2; -void floppy_setup(void); -struct drive_s *addFloppy(int floppyid, int ftype, int driver); -int find_floppy_type(u32 size); -int process_floppy_op(struct disk_op_s *op); -void floppy_tick(void); - -// cdrom.c -extern struct drive_s *cdemu_drive_gf; -int process_cdemu_op(struct disk_op_s *op); -void cdemu_setup(void); -void cdemu_134b(struct bregs *regs); -int cdrom_boot(int cdid); - -// ramdisk.c -void ramdisk_setup(void); -int process_ramdisk_op(struct disk_op_s *op); - -#endif // disk.h diff --git a/roms/seabios/src/entryfuncs.S b/roms/seabios/src/entryfuncs.S deleted file mode 100644 index 3c29b3f..0000000 --- a/roms/seabios/src/entryfuncs.S +++ /dev/null @@ -1,173 +0,0 @@ -// Macros for entering C code -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - - -/**************************************************************** - * Entry macros - ****************************************************************/ - - // Call a C function - this does the minimal work necessary to - // call into C. It sets up %ds, backs up %es, and backs up - // those registers that are call clobbered by the C compiler. - .macro ENTRY cfunc - cli // In case something far-calls instead of using "int" - cld - pushl %eax // Save registers clobbered by C code - pushl %ecx - pushl %edx - pushw %es - pushw %ds - movw %ss, %ax // Move %ss to %ds - movw %ax, %ds - pushl %esp // Backup %esp, then clear high bits - movzwl %sp, %esp - calll \cfunc - popl %esp // Restore %esp (including high bits) - popw %ds // Restore registers saved above - popw %es - popl %edx - popl %ecx - popl %eax - .endm - - // As above, but get calling function from stack. - .macro ENTRY_ST - cli - cld - pushl %ecx - pushl %edx - pushw %es - pushw %ds - movw %ss, %cx // Move %ss to %ds - movw %cx, %ds - pushl %esp // Backup %esp, then clear high bits - movzwl %sp, %esp - movl 16(%esp), %ecx // Get calling function - movl %eax, 16(%esp) // Save %eax - calll *%ecx - popl %esp // Restore %esp (including high bits) - popw %ds // Restore registers saved above - popw %es - popl %edx - popl %ecx - popl %eax - .endm - - // Call a C function with current register list as an - // argument. This backs up the registers and sets %eax - // to point to the backup. On return, the registers are - // restored from the structure. - .macro ENTRY_ARG cfunc - cli - cld - pushl %eax // Save registers (matches struct bregs) - pushl %ecx - pushl %edx - pushl %ebx - pushl %ebp - pushl %esi - pushl %edi - pushw %es - pushw %ds - movw %ss, %ax // Move %ss to %ds - movw %ax, %ds - movl %esp, %ebx // Backup %esp, then zero high bits - movzwl %sp, %esp - movl %esp, %eax // First arg is pointer to struct bregs - calll \cfunc - movl %ebx, %esp // Restore %esp (including high bits) - popw %ds // Restore registers (from struct bregs) - popw %es - popl %edi - popl %esi - popl %ebp - popl %ebx - popl %edx - popl %ecx - popl %eax - .endm - - // As above, but get calling function from stack. - .macro ENTRY_ARG_ST - cli - cld - pushl %ecx - pushl %edx - pushl %ebx - pushl %ebp - pushl %esi - pushl %edi - pushw %es - pushw %ds - movw %ss, %cx // Move %ss to %ds - movw %cx, %ds - movl %esp, %ebx // Backup %esp, then zero high bits - movzwl %sp, %esp - movl 28(%esp), %ecx // Get calling function - movl %eax, 28(%esp) // Save %eax - movl %esp, %eax // First arg is pointer to struct bregs - calll *%ecx - movl %ebx, %esp // Restore %esp (including high bits) - popw %ds // Restore registers (from struct bregs) - popw %es - popl %edi - popl %esi - popl %ebp - popl %ebx - popl %edx - popl %ecx - popl %eax - .endm - - // Same as ENTRY_ARG, but don't mangle %esp - .macro ENTRY_ARG_ESP cfunc - cli - cld - pushl %eax // Save registers (matches struct bregs) - pushl %ecx - pushl %edx - pushl %ebx - pushl %ebp - pushl %esi - pushl %edi - pushw %es - pushw %ds - movw %ss, %ax // Move %ss to %ds - movw %ax, %ds - movl %esp, %eax // First arg is pointer to struct bregs - calll \cfunc - popw %ds // Restore registers (from struct bregs) - popw %es - popl %edi - popl %esi - popl %ebp - popl %ebx - popl %edx - popl %ecx - popl %eax - .endm - - // Reset stack, transition to 32bit mode, and call a C function. - // Clobbers %ax - .macro ENTRY_INTO32 cfunc - xorw %ax, %ax - movw %ax, %ss - movl $ BUILD_STACK_ADDR , %esp - pushl $ \cfunc - jmp transition32 - .endm - - // Declare a function - .macro DECLFUNC func - .section .text.asm.\func - .global \func - .endm - - // Declare an exported function - .macro EXPORTFUNC func - .section .text.asm.export.\func - .global \func - .endm diff --git a/roms/seabios/src/farptr.h b/roms/seabios/src/farptr.h deleted file mode 100644 index 3dbf545..0000000 --- a/roms/seabios/src/farptr.h +++ /dev/null @@ -1,204 +0,0 @@ -// Code to access multiple segments within gcc. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __FARPTR_H -#define __FARPTR_H - -#include "ioport.h" // insb - -// Dummy definitions used to make sure gcc understands dependencies -// between SET_SEG and GET/READ/WRITE_SEG macros. -extern u16 __segment_ES, __segment_CS, __segment_DS, __segment_SS; -extern u16 __segment_FS, __segment_GS; - -// Low level macros for reading/writing memory via a segment selector. -#define READ8_SEG(prefix, SEG, value, var) \ - __asm__(prefix "movb %%" #SEG ":%1, %b0" : "=Qi"(value) \ - : "m"(var), "m"(__segment_ ## SEG)) -#define READ16_SEG(prefix, SEG, value, var) \ - __asm__(prefix "movw %%" #SEG ":%1, %w0" : "=ri"(value) \ - : "m"(var), "m"(__segment_ ## SEG)) -#define READ32_SEG(prefix, SEG, value, var) \ - __asm__(prefix "movl %%" #SEG ":%1, %0" : "=ri"(value) \ - : "m"(var), "m"(__segment_ ## SEG)) -#define READ64_SEG(prefix, SEG, value, var) do { \ - union u64_u32_u __value; \ - union u64_u32_u *__r64_ptr = (union u64_u32_u *)&(var); \ - READ32_SEG(prefix, SEG, __value.hi, __r64_ptr->hi); \ - READ32_SEG(prefix, SEG, __value.lo, __r64_ptr->lo); \ - *(u64*)&(value) = __value.val; \ - } while (0) -#define WRITE8_SEG(prefix, SEG, var, value) \ - __asm__(prefix "movb %b1, %%" #SEG ":%0" : "=m"(var) \ - : "Q"(value), "m"(__segment_ ## SEG)) -#define WRITE16_SEG(prefix, SEG, var, value) \ - __asm__(prefix "movw %w1, %%" #SEG ":%0" : "=m"(var) \ - : "r"(value), "m"(__segment_ ## SEG)) -#define WRITE32_SEG(prefix, SEG, var, value) \ - __asm__(prefix "movl %1, %%" #SEG ":%0" : "=m"(var) \ - : "r"(value), "m"(__segment_ ## SEG)) -#define WRITE64_SEG(prefix, SEG, var, value) do { \ - union u64_u32_u __value; \ - union u64_u32_u *__w64_ptr = (union u64_u32_u *)&(var); \ - typeof(var) __value_tmp = (value); \ - __value.val = *(u64*)&__value_tmp; \ - WRITE32_SEG(prefix, SEG, __w64_ptr->hi, __value.hi); \ - WRITE32_SEG(prefix, SEG, __w64_ptr->lo, __value.lo); \ - } while (0) - -// Macros for automatically choosing the appropriate memory size -// access method. -extern void __force_link_error__unknown_type(void); - -#define __GET_VAR(prefix, seg, var) ({ \ - typeof(var) __val; \ - if (sizeof(__val) == 1) \ - READ8_SEG(prefix, seg, __val, var); \ - else if (sizeof(__val) == 2) \ - READ16_SEG(prefix, seg, __val, var); \ - else if (sizeof(__val) == 4) \ - READ32_SEG(prefix, seg, __val, var); \ - else if (sizeof(__val) == 8) \ - READ64_SEG(prefix, seg, __val, var); \ - else \ - __force_link_error__unknown_type(); \ - __val; }) - -#define __SET_VAR(prefix, seg, var, val) do { \ - if (sizeof(var) == 1) \ - WRITE8_SEG(prefix, seg, var, (val)); \ - else if (sizeof(var) == 2) \ - WRITE16_SEG(prefix, seg, var, (val)); \ - else if (sizeof(var) == 4) \ - WRITE32_SEG(prefix, seg, var, (val)); \ - else if (sizeof(var) == 8) \ - WRITE64_SEG(prefix, seg, var, (val)); \ - else \ - __force_link_error__unknown_type(); \ - } while (0) - -// Low level macros for getting/setting a segment register. -#define __SET_SEG(SEG, value) \ - __asm__("movw %w1, %%" #SEG : "=m"(__segment_ ## SEG) \ - : "rm"(value)) -#define __GET_SEG(SEG) ({ \ - u16 __seg; \ - __asm__("movw %%" #SEG ", %w0" : "=rm"(__seg) \ - : "m"(__segment_ ## SEG)); \ - __seg;}) - -// Macros for accessing a variable in another segment. (They -// automatically update the %es segment and then make the appropriate -// access.) -#define __GET_FARVAR(seg, var) ({ \ - SET_SEG(ES, (seg)); \ - GET_VAR(ES, (var)); }) -#define __SET_FARVAR(seg, var, val) do { \ - typeof(var) __sfv_val = (val); \ - SET_SEG(ES, (seg)); \ - SET_VAR(ES, (var), __sfv_val); \ - } while (0) - -// Macros for accesssing a 32bit flat mode pointer from 16bit real -// mode. (They automatically update the %es segment, break the -// pointer into segment/offset, and then make the access.) -#define __GET_FLATPTR(ptr) ({ \ - typeof(&(ptr)) __ptr = &(ptr); \ - GET_FARVAR(FLATPTR_TO_SEG(__ptr) \ - , *(typeof(__ptr))FLATPTR_TO_OFFSET(__ptr)); }) -#define __SET_FLATPTR(ptr, val) do { \ - typeof (&(ptr)) __ptr = &(ptr); \ - SET_FARVAR(FLATPTR_TO_SEG(__ptr) \ - , *(typeof(__ptr))FLATPTR_TO_OFFSET(__ptr) \ - , (val)); \ - } while (0) - -// Macros for converting to/from 32bit flat mode pointers to their -// equivalent 16bit segment/offset values. -#define FLATPTR_TO_SEG(p) (((u32)(p)) >> 4) -#define FLATPTR_TO_OFFSET(p) (((u32)(p)) & 0xf) -#define MAKE_FLATPTR(seg,off) ((void*)(((u32)(seg)<<4)+(u32)(off))) - - -#if MODESEGMENT == 1 - -// Definitions when using segmented mode. -#define GET_FARVAR(seg, var) __GET_FARVAR((seg), (var)) -#define SET_FARVAR(seg, var, val) __SET_FARVAR((seg), (var), (val)) -#define GET_VAR(seg, var) __GET_VAR("", seg, (var)) -#define SET_VAR(seg, var, val) __SET_VAR("", seg, (var), (val)) -#define SET_SEG(SEG, value) __SET_SEG(SEG, (value)) -#define GET_SEG(SEG) __GET_SEG(SEG) -#define GET_FLATPTR(ptr) __GET_FLATPTR(ptr) -#define SET_FLATPTR(ptr, val) __SET_FLATPTR((ptr), (val)) - -static inline void insb_fl(u16 port, void *ptr_fl, u16 count) { - SET_SEG(ES, FLATPTR_TO_SEG(ptr_fl)); - insb(port, (u8*)FLATPTR_TO_OFFSET(ptr_fl), count); -} -static inline void insw_fl(u16 port, void *ptr_fl, u16 count) { - SET_SEG(ES, FLATPTR_TO_SEG(ptr_fl)); - insw(port, (u16*)FLATPTR_TO_OFFSET(ptr_fl), count); -} -static inline void insl_fl(u16 port, void *ptr_fl, u16 count) { - SET_SEG(ES, FLATPTR_TO_SEG(ptr_fl)); - insl(port, (u32*)FLATPTR_TO_OFFSET(ptr_fl), count); -} -static inline void outsb_fl(u16 port, void *ptr_fl, u16 count) { - SET_SEG(ES, FLATPTR_TO_SEG(ptr_fl)); - outsb(port, (u8*)FLATPTR_TO_OFFSET(ptr_fl), count); -} -static inline void outsw_fl(u16 port, void *ptr_fl, u16 count) { - SET_SEG(ES, FLATPTR_TO_SEG(ptr_fl)); - outsw(port, (u16*)FLATPTR_TO_OFFSET(ptr_fl), count); -} -static inline void outsl_fl(u16 port, void *ptr_fl, u16 count) { - SET_SEG(ES, FLATPTR_TO_SEG(ptr_fl)); - outsl(port, (u32*)FLATPTR_TO_OFFSET(ptr_fl), count); -} - -#else - -// In 32-bit flat mode there is no need to mess with the segments. -#define GET_FARVAR(seg, var) \ - (*((typeof(&(var)))MAKE_FLATPTR((seg), &(var)))) -#define SET_FARVAR(seg, var, val) \ - do { GET_FARVAR((seg), (var)) = (val); } while (0) -#define GET_VAR(seg, var) (var) -#define SET_VAR(seg, var, val) do { (var) = (val); } while (0) -#define SET_SEG(SEG, value) ((void)(value)) -#define GET_SEG(SEG) 0 -#define GET_FLATPTR(ptr) (ptr) -#define SET_FLATPTR(ptr, val) do { (ptr) = (val); } while (0) - -#define insb_fl(port, ptr_fl, count) insb(port, ptr_fl, count) -#define insw_fl(port, ptr_fl, count) insw(port, ptr_fl, count) -#define insl_fl(port, ptr_fl, count) insl(port, ptr_fl, count) -#define outsb_fl(port, ptr_fl, count) outsb(port, ptr_fl, count) -#define outsw_fl(port, ptr_fl, count) outsw(port, ptr_fl, count) -#define outsl_fl(port, ptr_fl, count) outsl(port, ptr_fl, count) - -#endif - -// Definition for common 16bit segment/offset pointers. -struct segoff_s { - union { - struct { - u16 offset; - u16 seg; - }; - u32 segoff; - }; -}; -#define SEGOFF(s,o) ({struct segoff_s __so; __so.offset=(o); __so.seg=(s); __so;}) - -static inline struct segoff_s FLATPTR_TO_SEGOFF(void *p) { - return SEGOFF(FLATPTR_TO_SEG(p), FLATPTR_TO_OFFSET(p)); -} -static inline void *SEGOFF_TO_FLATPTR(struct segoff_s so) { - return MAKE_FLATPTR(so.seg, so.offset); -} - -#endif // farptr.h diff --git a/roms/seabios/src/floppy.c b/roms/seabios/src/floppy.c deleted file mode 100644 index 6491b96..0000000 --- a/roms/seabios/src/floppy.c +++ /dev/null @@ -1,614 +0,0 @@ -// 16bit code to access floppy drives. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "types.h" // u8 -#include "disk.h" // DISK_RET_SUCCESS -#include "config.h" // CONFIG_FLOPPY -#include "biosvar.h" // SET_BDA -#include "util.h" // wait_irq -#include "cmos.h" // inb_cmos -#include "pic.h" // eoi_pic1 -#include "bregs.h" // struct bregs - -#define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors -#define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 -#define FLOPPY_MOTOR_TICKS 37 // ~2 seconds -#define FLOPPY_FILLBYTE 0xf6 -#define FLOPPY_GAPLEN 0x1B -#define FLOPPY_FORMAT_GAPLEN 0x6c - -// New diskette parameter table adding 3 parameters from IBM -// Since no provisions are made for multiple drive types, most -// values in this table are ignored. I set parameters for 1.44M -// floppy here -struct floppy_ext_dbt_s diskette_param_table2 VAR16VISIBLE = { - .dbt = { - .specify1 = 0xAF, // step rate 12ms, head unload 240ms - .specify2 = 0x02, // head load time 4ms, DMA used - .shutoff_ticks = FLOPPY_MOTOR_TICKS, // ~2 seconds - .bps_code = FLOPPY_SIZE_CODE, - .sectors = 18, - .interblock_len = FLOPPY_GAPLEN, - .data_len = FLOPPY_DATALEN, - .gap_len = FLOPPY_FORMAT_GAPLEN, - .fill_byte = FLOPPY_FILLBYTE, - .settle_time = 0x0F, // 15ms - .startup_time = 0x08, // 1 second - }, - .max_track = 79, // maximum track - .data_rate = 0, // data transfer rate - .drive_type = 4, // drive type in cmos -}; - -// Since no provisions are made for multiple drive types, most -// values in this table are ignored. I set parameters for 1.44M -// floppy here -struct floppy_dbt_s diskette_param_table VAR16FIXED(0xefc7) = { - .specify1 = 0xAF, - .specify2 = 0x02, - .shutoff_ticks = FLOPPY_MOTOR_TICKS, - .bps_code = FLOPPY_SIZE_CODE, - .sectors = 18, - .interblock_len = FLOPPY_GAPLEN, - .data_len = FLOPPY_DATALEN, - .gap_len = FLOPPY_FORMAT_GAPLEN, - .fill_byte = FLOPPY_FILLBYTE, - .settle_time = 0x0F, - .startup_time = 0x08, -}; - -struct floppyinfo_s { - struct chs_s chs; - u8 config_data; - u8 media_state; -}; - -struct floppyinfo_s FloppyInfo[] VAR16VISIBLE = { - // Unknown - { {0, 0, 0}, 0x00, 0x00}, - // 1 - 360KB, 5.25" - 2 heads, 40 tracks, 9 sectors - { {2, 40, 9}, 0x00, 0x25}, - // 2 - 1.2MB, 5.25" - 2 heads, 80 tracks, 15 sectors - { {2, 80, 15}, 0x00, 0x25}, - // 3 - 720KB, 3.5" - 2 heads, 80 tracks, 9 sectors - { {2, 80, 9}, 0x00, 0x17}, - // 4 - 1.44MB, 3.5" - 2 heads, 80 tracks, 18 sectors - { {2, 80, 18}, 0x00, 0x17}, - // 5 - 2.88MB, 3.5" - 2 heads, 80 tracks, 36 sectors - { {2, 80, 36}, 0xCC, 0xD7}, - // 6 - 160k, 5.25" - 1 heads, 40 tracks, 8 sectors - { {1, 40, 8}, 0x00, 0x27}, - // 7 - 180k, 5.25" - 1 heads, 40 tracks, 9 sectors - { {1, 40, 9}, 0x00, 0x27}, - // 8 - 320k, 5.25" - 2 heads, 40 tracks, 8 sectors - { {2, 40, 8}, 0x00, 0x27}, -}; - -struct drive_s * -addFloppy(int floppyid, int ftype, int driver) -{ - if (ftype <= 0 || ftype >= ARRAY_SIZE(FloppyInfo)) { - dprintf(1, "Bad floppy type %d\n", ftype); - return NULL; - } - - char *desc = malloc_tmp(MAXDESCSIZE); - struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g)); - if (!drive_g || !desc) { - warn_noalloc(); - free(desc); - free(drive_g); - return NULL; - } - memset(drive_g, 0, sizeof(*drive_g)); - drive_g->cntl_id = floppyid; - drive_g->type = driver; - drive_g->blksize = DISK_SECTOR_SIZE; - drive_g->floppy_type = ftype; - drive_g->sectors = (u64)-1; - drive_g->desc = desc; - snprintf(desc, MAXDESCSIZE, "drive %c", 'A' + floppyid); - - memcpy(&drive_g->lchs, &FloppyInfo[ftype].chs - , sizeof(FloppyInfo[ftype].chs)); - - map_floppy_drive(drive_g); - return drive_g; -} - -void -floppy_setup(void) -{ - if (! CONFIG_FLOPPY) - return; - dprintf(3, "init floppy drives\n"); - - if (CONFIG_COREBOOT) { - // XXX - disable floppies on coreboot for now. - } else { - u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE); - if (type & 0xf0) - addFloppy(0, type >> 4, DTYPE_FLOPPY); - if (type & 0x0f) - addFloppy(1, type & 0x0f, DTYPE_FLOPPY); - } - - outb(0x02, PORT_DMA1_MASK_REG); - - enable_hwirq(6, FUNC16(entry_0e)); -} - -// Find a floppy type that matches a given image size. -int -find_floppy_type(u32 size) -{ - int i; - for (i=1; icylinders * c->heads * c->spt * DISK_SECTOR_SIZE == size) - return i; - } - return -1; -} - - -/**************************************************************** - * Low-level floppy IO - ****************************************************************/ - -static void -floppy_reset_controller(void) -{ - // Reset controller - u8 val8 = inb(PORT_FD_DOR); - outb(val8 & ~0x04, PORT_FD_DOR); - outb(val8 | 0x04, PORT_FD_DOR); - - // Wait for controller to come out of reset - while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80) - ; -} - -static int -wait_floppy_irq(void) -{ - ASSERT16(); - u8 v; - for (;;) { - if (!GET_BDA(floppy_motor_counter)) - return -1; - v = GET_BDA(floppy_recalibration_status); - if (v & FRS_TIMEOUT) - break; - // Could use wait_irq() here, but that causes issues on - // bochs, so use yield() instead. - yield(); - } - - v &= ~FRS_TIMEOUT; - SET_BDA(floppy_recalibration_status, v); - return 0; -} - -static void -floppy_prepare_controller(u8 floppyid) -{ - CLEARBITS_BDA(floppy_recalibration_status, FRS_TIMEOUT); - - // turn on motor of selected drive, DMA & int enabled, normal operation - u8 prev_reset = inb(PORT_FD_DOR) & 0x04; - u8 dor = 0x10; - if (floppyid) - dor = 0x20; - dor |= 0x0c; - dor |= floppyid; - outb(dor, PORT_FD_DOR); - - // reset the disk motor timeout value of INT 08 - SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); - - // wait for drive readiness - while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80) - ; - - if (!prev_reset) - wait_floppy_irq(); -} - -static int -floppy_pio(u8 *cmd, u8 cmdlen) -{ - floppy_prepare_controller(cmd[1] & 1); - - // send command to controller - u8 i; - for (i=0; ibuf_fl; - - // check for 64K boundary overrun - u16 end = count - 1; - u32 last_addr = addr + end; - if ((addr >> 16) != (last_addr >> 16)) - return DISK_RET_EBOUNDARY; - - u8 mode_register = 0x4a; // single mode, increment, autoinit disable, - if (cmd[0] == 0xe6) - // read - mode_register = 0x46; - - //DEBUGF("floppy dma c2\n"); - outb(0x06, PORT_DMA1_MASK_REG); - outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop - outb(addr, PORT_DMA_ADDR_2); - outb(addr>>8, PORT_DMA_ADDR_2); - outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop - outb(end, PORT_DMA_CNT_2); - outb(end>>8, PORT_DMA_CNT_2); - - // port 0b: DMA-1 Mode Register - // transfer type=write, channel 2 - outb(mode_register, PORT_DMA1_MODE_REG); - - // port 81: DMA-1 Page Register, channel 2 - outb(addr>>16, PORT_DMA_PAGE_2); - - outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2 - - int ret = floppy_pio(cmd, cmdlen); - if (ret) - return DISK_RET_ETIMEOUT; - - // check port 3f4 for accessibility to status bytes - if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0) - return DISK_RET_ECONTROLLER; - - // read 7 return status bytes from controller - u8 i; - for (i=0; i<7; i++) { - u8 v = inb(PORT_FD_DATA); - cmd[i] = v; - SET_BDA(floppy_return_status[i], v); - } - - return DISK_RET_SUCCESS; -} - - -/**************************************************************** - * Floppy media sense - ****************************************************************/ - -static inline void -set_diskette_current_cyl(u8 floppyid, u8 cyl) -{ - SET_BDA(floppy_track[floppyid], cyl); -} - -static void -floppy_drive_recal(u8 floppyid) -{ - // send Recalibrate command (2 bytes) to controller - u8 data[12]; - data[0] = 0x07; // 07: Recalibrate - data[1] = floppyid; // 0=drive0, 1=drive1 - floppy_pio(data, 2); - - SETBITS_BDA(floppy_recalibration_status, 1<floppy_type); - SET_BDA(floppy_last_data_rate, GET_GLOBAL(FloppyInfo[ftype].config_data)); - u8 floppyid = GET_GLOBAL(drive_g->cntl_id); - SET_BDA(floppy_media_state[floppyid] - , GET_GLOBAL(FloppyInfo[ftype].media_state)); - return DISK_RET_SUCCESS; -} - -static int -check_recal_drive(struct drive_s *drive_g) -{ - u8 floppyid = GET_GLOBAL(drive_g->cntl_id); - if ((GET_BDA(floppy_recalibration_status) & (1<lba; - - u32 tmp = lba + 1; - u16 nlspt = GET_GLOBAL(op->drive_g->lchs.spt); - *sector = tmp % nlspt; - - tmp /= nlspt; - u16 nlh = GET_GLOBAL(op->drive_g->lchs.heads); - *head = tmp % nlh; - - tmp /= nlh; - *track = tmp; -} - -// diskette controller reset -static int -floppy_reset(struct disk_op_s *op) -{ - u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); - set_diskette_current_cyl(floppyid, 0); // current cylinder - return DISK_RET_SUCCESS; -} - -// Read Diskette Sectors -static int -floppy_read(struct disk_op_s *op) -{ - int res = check_recal_drive(op->drive_g); - if (res) - goto fail; - - u8 track, sector, head; - lba2chs(op, &track, §or, &head); - - // send read-normal-data command (9 bytes) to controller - u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); - u8 data[12]; - data[0] = 0xe6; // e6: read normal data - data[1] = (head << 2) | floppyid; // HD DR1 DR2 - data[2] = track; - data[3] = head; - data[4] = sector; - data[5] = FLOPPY_SIZE_CODE; - data[6] = sector + op->count - 1; // last sector to read on track - data[7] = FLOPPY_GAPLEN; - data[8] = FLOPPY_DATALEN; - - res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9); - if (res) - goto fail; - - if (data[0] & 0xc0) { - res = DISK_RET_ECONTROLLER; - goto fail; - } - - // ??? should track be new val from return_status[3] ? - set_diskette_current_cyl(floppyid, track); - return DISK_RET_SUCCESS; -fail: - op->count = 0; // no sectors read - return res; -} - -// Write Diskette Sectors -static int -floppy_write(struct disk_op_s *op) -{ - int res = check_recal_drive(op->drive_g); - if (res) - goto fail; - - u8 track, sector, head; - lba2chs(op, &track, §or, &head); - - // send write-normal-data command (9 bytes) to controller - u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); - u8 data[12]; - data[0] = 0xc5; // c5: write normal data - data[1] = (head << 2) | floppyid; // HD DR1 DR2 - data[2] = track; - data[3] = head; - data[4] = sector; - data[5] = FLOPPY_SIZE_CODE; - data[6] = sector + op->count - 1; // last sector to write on track - data[7] = FLOPPY_GAPLEN; - data[8] = FLOPPY_DATALEN; - - res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9); - if (res) - goto fail; - - if (data[0] & 0xc0) { - if (data[1] & 0x02) - res = DISK_RET_EWRITEPROTECT; - else - res = DISK_RET_ECONTROLLER; - goto fail; - } - - // ??? should track be new val from return_status[3] ? - set_diskette_current_cyl(floppyid, track); - return DISK_RET_SUCCESS; -fail: - op->count = 0; // no sectors read - return res; -} - -// Verify Diskette Sectors -static int -floppy_verify(struct disk_op_s *op) -{ - int res = check_recal_drive(op->drive_g); - if (res) - goto fail; - - u8 track, sector, head; - lba2chs(op, &track, §or, &head); - - // ??? should track be new val from return_status[3] ? - u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); - set_diskette_current_cyl(floppyid, track); - return DISK_RET_SUCCESS; -fail: - op->count = 0; // no sectors read - return res; -} - -// format diskette track -static int -floppy_format(struct disk_op_s *op) -{ - int ret = check_recal_drive(op->drive_g); - if (ret) - return ret; - - u8 head = op->lba; - - // send format-track command (6 bytes) to controller - u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id); - u8 data[12]; - data[0] = 0x4d; // 4d: format track - data[1] = (head << 2) | floppyid; // HD DR1 DR2 - data[2] = FLOPPY_SIZE_CODE; - data[3] = op->count; // number of sectors per track - data[4] = FLOPPY_FORMAT_GAPLEN; - data[5] = FLOPPY_FILLBYTE; - - ret = floppy_cmd(op, op->count * 4, data, 6); - if (ret) - return ret; - - if (data[0] & 0xc0) { - if (data[1] & 0x02) - return DISK_RET_EWRITEPROTECT; - return DISK_RET_ECONTROLLER; - } - - set_diskette_current_cyl(floppyid, 0); - return DISK_RET_SUCCESS; -} - -int -process_floppy_op(struct disk_op_s *op) -{ - if (!CONFIG_FLOPPY) - return 0; - - switch (op->command) { - case CMD_RESET: - return floppy_reset(op); - case CMD_READ: - return floppy_read(op); - case CMD_WRITE: - return floppy_write(op); - case CMD_VERIFY: - return floppy_verify(op); - case CMD_FORMAT: - return floppy_format(op); - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} - - -/**************************************************************** - * HW irqs - ****************************************************************/ - -// INT 0Eh Diskette Hardware ISR Entry Point -void VISIBLE16 -handle_0e(void) -{ - debug_isr(DEBUG_ISR_0e); - if (! CONFIG_FLOPPY) - goto done; - - if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0) { - outb(0x08, PORT_FD_DATA); // sense interrupt status - while ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0) - ; - do { - inb(PORT_FD_DATA); - } while ((inb(PORT_FD_STATUS) & 0xc0) == 0xc0); - } - // diskette interrupt has occurred - SETBITS_BDA(floppy_recalibration_status, FRS_TIMEOUT); - -done: - eoi_pic1(); -} - -// Called from int08 handler. -void -floppy_tick(void) -{ - if (! CONFIG_FLOPPY) - return; - - // time to turn off drive(s)? - u8 fcount = GET_BDA(floppy_motor_counter); - if (fcount) { - fcount--; - SET_BDA(floppy_motor_counter, fcount); - if (fcount == 0) - // turn motor(s) off - outb(inb(PORT_FD_DOR) & 0xcf, PORT_FD_DOR); - } -} diff --git a/roms/seabios/src/font.c b/roms/seabios/src/font.c deleted file mode 100644 index 3f8662f..0000000 --- a/roms/seabios/src/font.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "types.h" // u8 - -// Character Font for 320x200 & 640x200 Graphics (lower 128 characters) - -/* - * This font comes from the fntcol16.zip package (c) by Joseph Gil - * found at ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip - * This font is public domain - */ -u8 vgafont8[128*8] VAR16FIXED(0xfa6e) = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, - 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, - 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, - 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, - 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, - 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, - 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, - 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, - 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, - 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, - 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, - 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, - 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, - 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, - 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, - 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, - 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, - 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, - 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, - 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, - 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, - 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, - 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, - 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, - 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, - 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, - 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, - 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, - 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, - 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, - 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, - 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, - 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, - 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, - 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, - 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, - 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, - 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, - 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, - 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, - 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, - 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, - 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, - 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, - 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, - 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, - 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, - 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, - 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, - 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, - 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, - 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, - 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, -}; diff --git a/roms/seabios/src/gen-defs.h b/roms/seabios/src/gen-defs.h deleted file mode 100644 index dabf64c..0000000 --- a/roms/seabios/src/gen-defs.h +++ /dev/null @@ -1,19 +0,0 @@ -// Tool for building defintions accessible from assembler code. This -// is based on code from the Linux Kernel. -#ifndef __GEN_DEFS_H -#define __GEN_DEFS_H - - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define BLANK() \ - asm volatile("\n->" : : ) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)) - -#define COMMENT(x) \ - asm volatile("\n->#" x) - -#endif // gen-defs.h diff --git a/roms/seabios/src/ioport.h b/roms/seabios/src/ioport.h deleted file mode 100644 index ba099a7..0000000 --- a/roms/seabios/src/ioport.h +++ /dev/null @@ -1,134 +0,0 @@ -// Definitions for X86 IO port access. -// -// Copyright (C) 2008 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __IOPORT_H -#define __IOPORT_H - -#define PORT_DMA_ADDR_2 0x0004 -#define PORT_DMA_CNT_2 0x0005 -#define PORT_DMA1_MASK_REG 0x000a -#define PORT_DMA1_MODE_REG 0x000b -#define PORT_DMA1_CLEAR_FF_REG 0x000c -#define PORT_DMA1_MASTER_CLEAR 0x000d -#define PORT_PIC1_CMD 0x0020 -#define PORT_PIC1_DATA 0x0021 -#define PORT_PIT_COUNTER0 0x0040 -#define PORT_PIT_COUNTER1 0x0041 -#define PORT_PIT_COUNTER2 0x0042 -#define PORT_PIT_MODE 0x0043 -#define PORT_PS2_DATA 0x0060 -#define PORT_PS2_CTRLB 0x0061 -#define PORT_PS2_STATUS 0x0064 -#define PORT_CMOS_INDEX 0x0070 -#define PORT_CMOS_DATA 0x0071 -#define PORT_DIAG 0x0080 -#define PORT_DMA_PAGE_2 0x0081 -#define PORT_A20 0x0092 -#define PORT_PIC2_CMD 0x00a0 -#define PORT_PIC2_DATA 0x00a1 -#define PORT_SMI_CMD 0x00b2 -#define PORT_SMI_STATUS 0x00b3 -#define PORT_DMA2_MASK_REG 0x00d4 -#define PORT_DMA2_MODE_REG 0x00d6 -#define PORT_DMA2_MASTER_CLEAR 0x00da -#define PORT_MATH_CLEAR 0x00f0 -#define PORT_ATA2_CMD_BASE 0x0170 -#define PORT_ATA1_CMD_BASE 0x01f0 -#define PORT_LPT2 0x0278 -#define PORT_SERIAL4 0x02e8 -#define PORT_SERIAL2 0x02f8 -#define PORT_ATA2_CTRL_BASE 0x0374 -#define PORT_LPT1 0x0378 -#define PORT_SERIAL3 0x03e8 -#define PORT_ATA1_CTRL_BASE 0x03f4 -#define PORT_FD_DOR 0x03f2 -#define PORT_FD_STATUS 0x03f4 -#define PORT_FD_DATA 0x03f5 -#define PORT_HD_DATA 0x03f6 -#define PORT_FD_DIR 0x03f7 -#define PORT_SERIAL1 0x03f8 -#define PORT_PCI_CMD 0x0cf8 -#define PORT_PCI_DATA 0x0cfc -#define PORT_BIOS_DEBUG 0x0402 -#define PORT_QEMU_CFG_CTL 0x0510 -#define PORT_QEMU_CFG_DATA 0x0511 -#define PORT_ACPI_PM_BASE 0xb000 -#define PORT_SMB_BASE 0xb100 -#define PORT_BIOS_APM 0x8900 - -// Serial port offsets -#define SEROFF_DATA 0 -#define SEROFF_DLL 0 -#define SEROFF_IER 1 -#define SEROFF_DLH 1 -#define SEROFF_IIR 2 -#define SEROFF_LCR 3 -#define SEROFF_LSR 5 -#define SEROFF_MSR 6 - -// PORT_A20 bitdefs -#define A20_ENABLE_BIT 0x02 - -// PORT_CMOS_INDEX nmi disable bit -#define NMI_DISABLE_BIT 0x80 - -#ifndef __ASSEMBLY__ - -#include "types.h" // u8 - -static inline void outb(u8 value, u16 port) { - __asm__ __volatile__("outb %b0, %w1" : : "a"(value), "Nd"(port)); -} -static inline void outw(u16 value, u16 port) { - __asm__ __volatile__("outw %w0, %w1" : : "a"(value), "Nd"(port)); -} -static inline void outl(u32 value, u16 port) { - __asm__ __volatile__("outl %0, %w1" : : "a"(value), "Nd"(port)); -} -static inline u8 inb(u16 port) { - u8 value; - __asm__ __volatile__("inb %w1, %b0" : "=a"(value) : "Nd"(port)); - return value; -} -static inline u16 inw(u16 port) { - u16 value; - __asm__ __volatile__("inw %w1, %w0" : "=a"(value) : "Nd"(port)); - return value; -} -static inline u32 inl(u16 port) { - u32 value; - __asm__ __volatile__("inl %w1, %0" : "=a"(value) : "Nd"(port)); - return value; -} - -static inline void insb(u16 port, u8 *data, u32 count) { - asm volatile("rep insb (%%dx), %%es:(%%edi)" - : "+c"(count), "+D"(data) : "d"(port) : "memory"); -} -static inline void insw(u16 port, u16 *data, u32 count) { - asm volatile("rep insw (%%dx), %%es:(%%edi)" - : "+c"(count), "+D"(data) : "d"(port) : "memory"); -} -static inline void insl(u16 port, u32 *data, u32 count) { - asm volatile("rep insl (%%dx), %%es:(%%edi)" - : "+c"(count), "+D"(data) : "d"(port) : "memory"); -} -// XXX - outs not limited to es segment -static inline void outsb(u16 port, u8 *data, u32 count) { - asm volatile("rep outsb %%es:(%%esi), (%%dx)" - : "+c"(count), "+S"(data) : "d"(port) : "memory"); -} -static inline void outsw(u16 port, u16 *data, u32 count) { - asm volatile("rep outsw %%es:(%%esi), (%%dx)" - : "+c"(count), "+S"(data) : "d"(port) : "memory"); -} -static inline void outsl(u16 port, u32 *data, u32 count) { - asm volatile("rep outsl %%es:(%%esi), (%%dx)" - : "+c"(count), "+S"(data) : "d"(port) : "memory"); -} - -#endif // !__ASSEMBLY__ - -#endif // ioport.h diff --git a/roms/seabios/src/jpeg.c b/roms/seabios/src/jpeg.c deleted file mode 100644 index 1068291..0000000 --- a/roms/seabios/src/jpeg.c +++ /dev/null @@ -1,1041 +0,0 @@ -/* - * Copyright (C) 2001, Novell Inc. - * Copyright (C) 2010 Kevin O'Connor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of Novell nor the names of the contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * a tiny jpeg decoder. - * - * written in August 2001 by Michael Schroeder - * - */ - -#define __LITTLE_ENDIAN -#include "util.h" -#include "jpeg.h" -#define ISHIFT 11 - -#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5)) -#define IMULT(a, b) (((a) * (b)) >> ISHIFT) -#define ITOINT(a) ((a) >> ISHIFT) - -#ifndef __P -# define __P(x) x -#endif - -/* special markers */ -#define M_BADHUFF -1 -#define M_EOF 0x80 - -struct in { - unsigned char *p; - unsigned int bits; - int left; - int marker; - - int (*func) __P((void *)); - void *data; -}; - -/*********************************/ -struct dec_hufftbl; -struct enc_hufftbl; - -union hufftblp { - struct dec_hufftbl *dhuff; - struct enc_hufftbl *ehuff; -}; - -struct scan { - int dc; /* old dc value */ - - union hufftblp hudc; - union hufftblp huac; - int next; /* when to switch to next scan */ - - int cid; /* component id */ - int hv; /* horiz/vert, copied from comp */ - int tq; /* quant tbl, copied from comp */ -}; - -/*********************************/ - -#define DECBITS 10 /* seems to be the optimum */ - -struct dec_hufftbl { - int maxcode[17]; - int valptr[16]; - unsigned char vals[256]; - unsigned int llvals[1 << DECBITS]; -}; - -static void decode_mcus __P((struct in *, int *, int, struct scan *, int *)); -static int dec_readmarker __P((struct in *)); -static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *)); - -static void setinput __P((struct in *, unsigned char *)); -/*********************************/ - -#undef PREC -#define PREC int - -static void idctqtab __P((unsigned char *, PREC *)); -static void idct __P((int *, int *, PREC *, PREC, int)); -static void scaleidctqtab __P((PREC *, PREC)); - -/*********************************/ - -static void initcol __P((PREC[][64])); - -static void col221111 __P((int *, unsigned char *, int)); -static void col221111_16 __P((int *, unsigned char *, int)); -static void col221111_32 __P((int *, unsigned char *, int)); - -/*********************************/ - -#define ERR_NO_SOI 1 -#define ERR_NOT_8BIT 2 -#define ERR_HEIGHT_MISMATCH 3 -#define ERR_WIDTH_MISMATCH 4 -#define ERR_BAD_WIDTH_OR_HEIGHT 5 -#define ERR_TOO_MANY_COMPPS 6 -#define ERR_ILLEGAL_HV 7 -#define ERR_QUANT_TABLE_SELECTOR 8 -#define ERR_NOT_YCBCR_221111 9 -#define ERR_UNKNOWN_CID_IN_SCAN 10 -#define ERR_NOT_SEQUENTIAL_DCT 11 -#define ERR_WRONG_MARKER 12 -#define ERR_NO_EOI 13 -#define ERR_BAD_TABLES 14 -#define ERR_DEPTH_MISMATCH 15 - -/*********************************/ - -#define M_SOI 0xd8 -#define M_APP0 0xe0 -#define M_DQT 0xdb -#define M_SOF0 0xc0 -#define M_DHT 0xc4 -#define M_DRI 0xdd -#define M_SOS 0xda -#define M_RST0 0xd0 -#define M_EOI 0xd9 -#define M_COM 0xfe - -struct comp { - int cid; - int hv; - int tq; -}; - -#define MAXCOMP 4 -struct jpginfo { - int nc; /* number of components */ - int ns; /* number of scans */ - int dri; /* restart interval */ - int nm; /* mcus til next marker */ - int rm; /* next restart marker */ -}; - -struct jpeg_decdata { - int dcts[6 * 64 + 16]; - int out[64 * 6]; - int dquant[3][64]; - - unsigned char *datap; - struct jpginfo info; - struct comp comps[MAXCOMP]; - struct scan dscans[MAXCOMP]; - unsigned char quant[4][64]; - struct dec_hufftbl dhuff[4]; - struct in in; - - int height, width; -}; - -static int getbyte(struct jpeg_decdata *jpeg) -{ - return *jpeg->datap++; -} - -static int getword(struct jpeg_decdata *jpeg) -{ - int c1, c2; - c1 = *jpeg->datap++; - c2 = *jpeg->datap++; - return c1 << 8 | c2; -} - -static int readtables(struct jpeg_decdata *jpeg, int till) -{ - int m, l, i, j, lq, pq, tq; - int tc, th, tt; - - for (;;) { - if (getbyte(jpeg) != 0xff) - return -1; - if ((m = getbyte(jpeg)) == till) - break; - - switch (m) { - case 0xc2: - return 0; - - case M_DQT: - lq = getword(jpeg); - while (lq > 2) { - pq = getbyte(jpeg); - tq = pq & 15; - if (tq > 3) - return -1; - pq >>= 4; - if (pq != 0) - return -1; - for (i = 0; i < 64; i++) - jpeg->quant[tq][i] = getbyte(jpeg); - lq -= 64 + 1; - } - break; - - case M_DHT: - l = getword(jpeg); - while (l > 2) { - int hufflen[16], k; - unsigned char huffvals[256]; - - tc = getbyte(jpeg); - th = tc & 15; - tc >>= 4; - tt = tc * 2 + th; - if (tc > 1 || th > 1) - return -1; - for (i = 0; i < 16; i++) - hufflen[i] = getbyte(jpeg); - l -= 1 + 16; - k = 0; - for (i = 0; i < 16; i++) { - for (j = 0; j < hufflen[i]; j++) - huffvals[k++] = getbyte(jpeg); - l -= hufflen[i]; - } - dec_makehuff(jpeg->dhuff + tt, hufflen, huffvals); - } - break; - - case M_DRI: - l = getword(jpeg); - jpeg->info.dri = getword(jpeg); - break; - - default: - l = getword(jpeg); - while (l-- > 2) - getbyte(jpeg); - break; - } - } - return 0; -} - -static void dec_initscans(struct jpeg_decdata *jpeg) -{ - int i; - - jpeg->info.nm = jpeg->info.dri + 1; - jpeg->info.rm = M_RST0; - for (i = 0; i < jpeg->info.ns; i++) - jpeg->dscans[i].dc = 0; -} - -static int dec_checkmarker(struct jpeg_decdata *jpeg) -{ - int i; - - if (dec_readmarker(&jpeg->in) != jpeg->info.rm) - return -1; - jpeg->info.nm = jpeg->info.dri; - jpeg->info.rm = (jpeg->info.rm + 1) & ~0x08; - for (i = 0; i < jpeg->info.ns; i++) - jpeg->dscans[i].dc = 0; - return 0; -} - -struct jpeg_decdata *jpeg_alloc(void) -{ - struct jpeg_decdata *jpeg = malloc_tmphigh(sizeof(*jpeg)); - return jpeg; -} - -int jpeg_decode(struct jpeg_decdata *jpeg, unsigned char *buf) -{ - int i, j, m, tac, tdc; - - if (!jpeg || !buf) - return -1; - jpeg->datap = buf; - if (getbyte(jpeg) != 0xff) - return ERR_NO_SOI; - if (getbyte(jpeg) != M_SOI) - return ERR_NO_SOI; - if (readtables(jpeg, M_SOF0)) - return ERR_BAD_TABLES; - getword(jpeg); - i = getbyte(jpeg); - if (i != 8) - return ERR_NOT_8BIT; - jpeg->height = getword(jpeg); - jpeg->width = getword(jpeg); - if ((jpeg->height & 15) || (jpeg->width & 15)) - return ERR_BAD_WIDTH_OR_HEIGHT; - jpeg->info.nc = getbyte(jpeg); - if (jpeg->info.nc > MAXCOMP) - return ERR_TOO_MANY_COMPPS; - for (i = 0; i < jpeg->info.nc; i++) { - int h, v; - jpeg->comps[i].cid = getbyte(jpeg); - jpeg->comps[i].hv = getbyte(jpeg); - v = jpeg->comps[i].hv & 15; - h = jpeg->comps[i].hv >> 4; - jpeg->comps[i].tq = getbyte(jpeg); - if (h > 3 || v > 3) - return ERR_ILLEGAL_HV; - if (jpeg->comps[i].tq > 3) - return ERR_QUANT_TABLE_SELECTOR; - } - if (readtables(jpeg, M_SOS)) - return ERR_BAD_TABLES; - getword(jpeg); - jpeg->info.ns = getbyte(jpeg); - if (jpeg->info.ns != 3) - return ERR_NOT_YCBCR_221111; - for (i = 0; i < 3; i++) { - jpeg->dscans[i].cid = getbyte(jpeg); - tdc = getbyte(jpeg); - tac = tdc & 15; - tdc >>= 4; - if (tdc > 1 || tac > 1) - return ERR_QUANT_TABLE_SELECTOR; - for (j = 0; j < jpeg->info.nc; j++) - if (jpeg->comps[j].cid == jpeg->dscans[i].cid) - break; - if (j == jpeg->info.nc) - return ERR_UNKNOWN_CID_IN_SCAN; - jpeg->dscans[i].hv = jpeg->comps[j].hv; - jpeg->dscans[i].tq = jpeg->comps[j].tq; - jpeg->dscans[i].hudc.dhuff = &jpeg->dhuff[tdc]; - jpeg->dscans[i].huac.dhuff = &jpeg->dhuff[2 + tac]; - } - - i = getbyte(jpeg); - j = getbyte(jpeg); - m = getbyte(jpeg); - - if (i != 0 || j != 63 || m != 0) - return ERR_NOT_SEQUENTIAL_DCT; - - if (jpeg->dscans[0].cid != 1 || jpeg->dscans[1].cid != 2 - || jpeg->dscans[2].cid != 3) - return ERR_NOT_YCBCR_221111; - - if (jpeg->dscans[0].hv != 0x22 || jpeg->dscans[1].hv != 0x11 - || jpeg->dscans[2].hv != 0x11) - return ERR_NOT_YCBCR_221111; - - idctqtab(jpeg->quant[jpeg->dscans[0].tq], jpeg->dquant[0]); - idctqtab(jpeg->quant[jpeg->dscans[1].tq], jpeg->dquant[1]); - idctqtab(jpeg->quant[jpeg->dscans[2].tq], jpeg->dquant[2]); - initcol(jpeg->dquant); - setinput(&jpeg->in, jpeg->datap); - -#if 0 - /* landing zone */ - img[len] = 0; - img[len + 1] = 0xff; - img[len + 2] = M_EOF; -#endif - - dec_initscans(jpeg); - - return 0; -} - -void jpeg_get_size(struct jpeg_decdata *jpeg, int *width, int *height) -{ - *width = jpeg->width; - *height = jpeg->height; -} - -int jpeg_show(struct jpeg_decdata *jpeg, unsigned char *pic - , int width, int height, int depth) -{ - int m, mcusx, mcusy, mx, my; - int max[6]; - - if (jpeg->height != height) - return ERR_HEIGHT_MISMATCH; - if (jpeg->width != width) - return ERR_WIDTH_MISMATCH; - - mcusx = jpeg->width >> 4; - mcusy = jpeg->height >> 4; - - jpeg->dscans[0].next = 6 - 4; - jpeg->dscans[1].next = 6 - 4 - 1; - jpeg->dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */ - for (my = 0; my < mcusy; my++) { - for (mx = 0; mx < mcusx; mx++) { - if (jpeg->info.dri && !--jpeg->info.nm) - if (dec_checkmarker(jpeg)) - return ERR_WRONG_MARKER; - - decode_mcus(&jpeg->in, jpeg->dcts, 6, jpeg->dscans, max); - idct(jpeg->dcts, jpeg->out, jpeg->dquant[0], - IFIX(128.5), max[0]); - idct(jpeg->dcts + 64, jpeg->out + 64, jpeg->dquant[0], - IFIX(128.5), max[1]); - idct(jpeg->dcts + 128, jpeg->out + 128, jpeg->dquant[0], - IFIX(128.5), max[2]); - idct(jpeg->dcts + 192, jpeg->out + 192, jpeg->dquant[0], - IFIX(128.5), max[3]); - idct(jpeg->dcts + 256, jpeg->out + 256, jpeg->dquant[1], - IFIX(0.5), max[4]); - idct(jpeg->dcts + 320, jpeg->out + 320, jpeg->dquant[2], - IFIX(0.5), max[5]); - - switch (depth) { - case 32: - col221111_32(jpeg->out, - pic + (my * 16 * mcusx + mx) * 16 * 4, - mcusx * 16 * 4); - break; - case 24: - col221111(jpeg->out, - pic + (my * 16 * mcusx + mx) * 16 * 3, - mcusx * 16 * 3); - break; - case 16: - col221111_16(jpeg->out, - pic + (my * 16 * mcusx + mx) * (16 * 2), - mcusx * (16 * 2)); - break; - default: - return ERR_DEPTH_MISMATCH; - break; - } - } - } - - m = dec_readmarker(&jpeg->in); - if (m != M_EOI) - return ERR_NO_EOI; - - return 0; -} - -/****************************************************************/ -/************** huffman decoder ***************/ -/****************************************************************/ - -static int fillbits __P((struct in *, int, unsigned int)); -static int dec_rec2 __P((struct in *, struct dec_hufftbl *, int *, int, int)); - -static void setinput(struct in *in, unsigned char *p) -{ - in->p = p; - in->left = 0; - in->bits = 0; - in->marker = 0; -} - -static int fillbits(struct in *in, int le, unsigned int bi) -{ - int b, m; - - if (in->marker) { - if (le <= 16) - in->bits = bi << 16, le += 16; - return le; - } - while (le <= 24) { - b = *in->p++; - if (b == 0xff && (m = *in->p++) != 0) { - if (m == M_EOF) { - if (in->func && (m = in->func(in->data)) == 0) - continue; - } - in->marker = m; - if (le <= 16) - bi = bi << 16, le += 16; - break; - } - bi = bi << 8 | b; - le += 8; - } - in->bits = bi; /* tmp... 2 return values needed */ - return le; -} - -static int dec_readmarker(struct in *in) -{ - int m; - - in->left = fillbits(in, in->left, in->bits); - if ((m = in->marker) == 0) - return 0; - in->left = 0; - in->marker = 0; - return m; -} - -#define LEBI_DCL int le, bi -#define LEBI_GET(in) (le = in->left, bi = in->bits) -#define LEBI_PUT(in) (in->left = le, in->bits = bi) - -#define GETBITS(in, n) ( \ - (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \ - (le -= (n)), \ - bi >> le & ((1 << (n)) - 1) \ -) - -#define UNGETBITS(in, n) ( \ - le += (n) \ -) - - -static int dec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, - int c, int i) -{ - LEBI_DCL; - - LEBI_GET(in); - if (i) { - UNGETBITS(in, i & 127); - *runp = i >> 8 & 15; - i >>= 16; - } else { - for (i = DECBITS; - (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++); - if (i >= 16) { - in->marker = M_BADHUFF; - return 0; - } - i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2]; - *runp = i >> 4; - i &= 15; - } - if (i == 0) { /* sigh, 0xf0 is 11 bit */ - LEBI_PUT(in); - return 0; - } - /* receive part */ - c = GETBITS(in, i); - if (c < (1 << (i - 1))) - c += (-1 << i) + 1; - LEBI_PUT(in); - return c; -} - -#define DEC_REC(in, hu, r, i) ( \ - r = GETBITS(in, DECBITS), \ - i = hu->llvals[r], \ - i & 128 ? \ - ( \ - UNGETBITS(in, i & 127), \ - r = i >> 8 & 15, \ - i >> 16 \ - ) \ - : \ - ( \ - LEBI_PUT(in), \ - i = dec_rec2(in, hu, &r, r, i), \ - LEBI_GET(in), \ - i \ - ) \ -) - -static void decode_mcus(struct in *in, int *dct, int n, struct scan *sc, - int *maxp) -{ - struct dec_hufftbl *hu; - int i, r, t; - LEBI_DCL; - - memset(dct, 0, n * 64 * sizeof(*dct)); - LEBI_GET(in); - while (n-- > 0) { - hu = sc->hudc.dhuff; - *dct++ = (sc->dc += DEC_REC(in, hu, r, t)); - - hu = sc->huac.dhuff; - i = 63; - while (i > 0) { - t = DEC_REC(in, hu, r, t); - if (t == 0 && r == 0) { - dct += i; - break; - } - dct += r; - *dct++ = t; - i -= r + 1; - } - *maxp++ = 64 - i; - if (n == sc->next) - sc++; - } - LEBI_PUT(in); -} - -static void dec_makehuff(struct dec_hufftbl *hu, int *hufflen, - unsigned char *huffvals) -{ - int code, k, i, j, d, x, c, v; - for (i = 0; i < (1 << DECBITS); i++) - hu->llvals[i] = 0; - - /* - * llvals layout: - * - * value v already known, run r, backup u bits: - * vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu - * value unknown, size b bits, run r, backup u bits: - * 000000000000bbbb 0000 rrrr 0 uuuuuuu - * value and size unknown: - * 0000000000000000 0000 0000 0 0000000 - */ - - code = 0; - k = 0; - for (i = 0; i < 16; i++, code <<= 1) { /* sizes */ - hu->valptr[i] = k; - for (j = 0; j < hufflen[i]; j++) { - hu->vals[k] = *huffvals++; - if (i < DECBITS) { - c = code << (DECBITS - 1 - i); - v = hu->vals[k] & 0x0f; /* size */ - for (d = 1 << (DECBITS - 1 - i); --d >= 0;) { - if (v + i < DECBITS) { /* both fit in table */ - x = d >> (DECBITS - 1 - v - i); - if (v && x < (1 << (v - 1))) - x += (-1 << v) + 1; - x = x << 16 | (hu->vals[k] & 0xf0) << 4 | - (DECBITS - (i + 1 + v)) | 128; - } else - x = v << 16 | (hu->vals[k] & 0xf0) << 4 | - (DECBITS - (i + 1)); - hu->llvals[c | d] = x; - } - } - code++; - k++; - } - hu->maxcode[i] = code; - } - hu->maxcode[16] = 0x20000; /* always terminate decode */ -} - -/****************************************************************/ -/************** idct ***************/ -/****************************************************************/ - -#define ONE ((PREC)IFIX(1.)) -#define S2 ((PREC)IFIX(0.382683432)) -#define C2 ((PREC)IFIX(0.923879532)) -#define C4 ((PREC)IFIX(0.707106781)) - -#define S22 ((PREC)IFIX(2 * 0.382683432)) -#define C22 ((PREC)IFIX(2 * 0.923879532)) -#define IC4 ((PREC)IFIX(1 / 0.707106781)) - -#define C3IC1 ((PREC)IFIX(0.847759065)) /* c3/c1 */ -#define C5IC1 ((PREC)IFIX(0.566454497)) /* c5/c1 */ -#define C7IC1 ((PREC)IFIX(0.198912367)) /* c7/c1 */ - -#define XPP(a,b) (t = a + b, b = a - b, a = t) -#define XMP(a,b) (t = a - b, b = a + b, a = t) -#define XPM(a,b) (t = a + b, b = b - a, a = t) - -#define ROT(a,b,s,c) ( t = IMULT(a + b, s), \ - a = IMULT(a, c - s) + t, \ - b = IMULT(b, c + s) - t) - -#define IDCT \ -( \ - XPP(t0, t1), \ - XMP(t2, t3), \ - t2 = IMULT(t2, IC4) - t3, \ - XPP(t0, t3), \ - XPP(t1, t2), \ - XMP(t4, t7), \ - XPP(t5, t6), \ - XMP(t5, t7), \ - t5 = IMULT(t5, IC4), \ - ROT(t4, t6, S22, C22), \ - t6 -= t7, \ - t5 -= t6, \ - t4 -= t5, \ - XPP(t0, t7), \ - XPP(t1, t6), \ - XPP(t2, t5), \ - XPP(t3, t4) \ -) - -static unsigned char zig2[64] = { - 0, 2, 3, 9, 10, 20, 21, 35, - 14, 16, 25, 31, 39, 46, 50, 57, - 5, 7, 12, 18, 23, 33, 37, 48, - 27, 29, 41, 44, 52, 55, 59, 62, - 15, 26, 30, 40, 45, 51, 56, 58, - 1, 4, 8, 11, 19, 22, 34, 36, - 28, 42, 43, 53, 54, 60, 61, 63, - 6, 13, 17, 24, 32, 38, 47, 49 -}; - -static void idct(int *in, int *out, PREC * quant, PREC off, int max) -{ - PREC t0, t1, t2, t3, t4, t5, t6, t7, t; - PREC tmp[64], *tmpp; - int i, j; - unsigned char *zig2p; - - t0 = off; - if (max == 1) { - t0 += in[0] * quant[0]; - for (i = 0; i < 64; i++) - out[i] = ITOINT(t0); - return; - } - zig2p = zig2; - tmpp = tmp; - for (i = 0; i < 8; i++) { - j = *zig2p++; - t0 += in[j] * quant[j]; - j = *zig2p++; - t5 = in[j] * quant[j]; - j = *zig2p++; - t2 = in[j] * quant[j]; - j = *zig2p++; - t7 = in[j] * quant[j]; - j = *zig2p++; - t1 = in[j] * quant[j]; - j = *zig2p++; - t4 = in[j] * quant[j]; - j = *zig2p++; - t3 = in[j] * quant[j]; - j = *zig2p++; - t6 = in[j] * quant[j]; - IDCT; - tmpp[0 * 8] = t0; - tmpp[1 * 8] = t1; - tmpp[2 * 8] = t2; - tmpp[3 * 8] = t3; - tmpp[4 * 8] = t4; - tmpp[5 * 8] = t5; - tmpp[6 * 8] = t6; - tmpp[7 * 8] = t7; - tmpp++; - t0 = 0; - } - for (i = 0; i < 8; i++) { - t0 = tmp[8 * i + 0]; - t1 = tmp[8 * i + 1]; - t2 = tmp[8 * i + 2]; - t3 = tmp[8 * i + 3]; - t4 = tmp[8 * i + 4]; - t5 = tmp[8 * i + 5]; - t6 = tmp[8 * i + 6]; - t7 = tmp[8 * i + 7]; - IDCT; - out[8 * i + 0] = ITOINT(t0); - out[8 * i + 1] = ITOINT(t1); - out[8 * i + 2] = ITOINT(t2); - out[8 * i + 3] = ITOINT(t3); - out[8 * i + 4] = ITOINT(t4); - out[8 * i + 5] = ITOINT(t5); - out[8 * i + 6] = ITOINT(t6); - out[8 * i + 7] = ITOINT(t7); - } -} - -static unsigned char zig[64] = { - 0, 1, 5, 6, 14, 15, 27, 28, - 2, 4, 7, 13, 16, 26, 29, 42, - 3, 8, 12, 17, 25, 30, 41, 43, - 9, 11, 18, 24, 31, 40, 44, 53, - 10, 19, 23, 32, 39, 45, 52, 54, - 20, 22, 33, 38, 46, 51, 55, 60, - 21, 34, 37, 47, 50, 56, 59, 61, - 35, 36, 48, 49, 57, 58, 62, 63 -}; - -static PREC aaidct[8] = { - IFIX(0.3535533906), IFIX(0.4903926402), - IFIX(0.4619397663), IFIX(0.4157348062), - IFIX(0.3535533906), IFIX(0.2777851165), - IFIX(0.1913417162), IFIX(0.0975451610) -}; - - -static void idctqtab(unsigned char *qin, PREC * qout) -{ - int i, j; - - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) - qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] * - IMULT(aaidct[i], aaidct[j]); -} - -static void scaleidctqtab(PREC * q, PREC sc) -{ - int i; - - for (i = 0; i < 64; i++) - q[i] = IMULT(q[i], sc); -} - -/****************************************************************/ -/************** color decoder ***************/ -/****************************************************************/ - -#define ROUND - -/* - * YCbCr Color transformation: - * - * y:0..255 Cb:-128..127 Cr:-128..127 - * - * R = Y + 1.40200 * Cr - * G = Y - 0.34414 * Cb - 0.71414 * Cr - * B = Y + 1.77200 * Cb - * - * => - * Cr *= 1.40200; - * Cb *= 1.77200; - * Cg = 0.19421 * Cb + .50937 * Cr; - * R = Y + Cr; - * G = Y - Cg; - * B = Y + Cb; - * - * => - * Cg = (50 * Cb + 130 * Cr + 128) >> 8; - */ - -static void initcol(PREC q[][64]) -{ - scaleidctqtab(q[1], IFIX(1.77200)); - scaleidctqtab(q[2], IFIX(1.40200)); -} - -/* This is optimized for the stupid sun SUNWspro compiler. */ -#define STORECLAMP(a,x) \ -( \ - (a) = (x), \ - (unsigned int)(x) >= 256 ? \ - ((a) = (x) < 0 ? 0 : 255) \ - : \ - 0 \ -) - -#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x)) - -#ifdef ROUND - -#define CBCRCG(yin, xin) \ -( \ - cb = outc[0 +yin*8+xin], \ - cr = outc[64+yin*8+xin], \ - cg = (50 * cb + 130 * cr + 128) >> 8 \ -) - -#else - -#define CBCRCG(yin, xin) \ -( \ - cb = outc[0 +yin*8+xin], \ - cr = outc[64+yin*8+xin], \ - cg = (3 * cb + 8 * cr) >> 4 \ -) - -#endif - -#define PIC(yin, xin, p, xout) \ -( \ - y = outy[(yin) * 8 + xin], \ - STORECLAMP(p[(xout) * 3 + 0], y + cr), \ - STORECLAMP(p[(xout) * 3 + 1], y - cg), \ - STORECLAMP(p[(xout) * 3 + 2], y + cb) \ -) - -#ifdef __LITTLE_ENDIAN -#define PIC_16(yin, xin, p, xout, add) \ -( \ - y = outy[(yin) * 8 + xin], \ - y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \ - ((CLAMP(y - cg + add ) & 0xfc) << 3) | \ - ((CLAMP(y + cb + add*2+1) ) >> 3), \ - p[(xout) * 2 + 0] = y & 0xff, \ - p[(xout) * 2 + 1] = y >> 8 \ -) -#else -#ifdef CONFIG_PPC -#define PIC_16(yin, xin, p, xout, add) \ -( \ - y = outy[(yin) * 8 + xin], \ - y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 7) | \ - ((CLAMP(y - cg + add*2+1) & 0xf8) << 2) | \ - ((CLAMP(y + cb + add*2+1) ) >> 3), \ - p[(xout) * 2 + 0] = y >> 8, \ - p[(xout) * 2 + 1] = y & 0xff \ -) -#else -#define PIC_16(yin, xin, p, xout, add) \ -( \ - y = outy[(yin) * 8 + xin], \ - y = ((CLAMP(y + cr + add*2+1) & 0xf8) << 8) | \ - ((CLAMP(y - cg + add ) & 0xfc) << 3) | \ - ((CLAMP(y + cb + add*2+1) ) >> 3), \ - p[(xout) * 2 + 0] = y >> 8, \ - p[(xout) * 2 + 1] = y & 0xff \ -) -#endif -#endif - -#define PIC_32(yin, xin, p, xout) \ -( \ - y = outy[(yin) * 8 + xin], \ - STORECLAMP(p[(xout) * 4 + 0], y + cr), \ - STORECLAMP(p[(xout) * 4 + 1], y - cg), \ - STORECLAMP(p[(xout) * 4 + 2], y + cb), \ - p[(xout) * 4 + 3] = 0 \ -) - -#define PIC221111(xin) \ -( \ - CBCRCG(0, xin), \ - PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \ - PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \ - PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \ - PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \ -) - -#define PIC221111_16(xin) \ -( \ - CBCRCG(0, xin), \ - PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \ - PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \ - PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \ - PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \ -) - -#define PIC221111_32(xin) \ -( \ - CBCRCG(0, xin), \ - PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0), \ - PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1), \ - PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0), \ - PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \ -) - -static void col221111(int *out, unsigned char *pic, int width) -{ - int i, j, k; - unsigned char *pic0, *pic1; - int *outy, *outc; - int cr, cg, cb, y; - - pic0 = pic; - pic1 = pic + width; - outy = out; - outc = out + 64 * 4; - for (i = 2; i > 0; i--) { - for (j = 4; j > 0; j--) { - for (k = 0; k < 8; k++) { - PIC221111(k); - } - outc += 8; - outy += 16; - pic0 += 2 * width; - pic1 += 2 * width; - } - outy += 64 * 2 - 16 * 4; - } -} - -static void col221111_16(int *out, unsigned char *pic, int width) -{ - int i, j, k; - unsigned char *pic0, *pic1; - int *outy, *outc; - int cr, cg, cb, y; - - pic0 = pic; - pic1 = pic + width; - outy = out; - outc = out + 64 * 4; - for (i = 2; i > 0; i--) { - for (j = 4; j > 0; j--) { - for (k = 0; k < 8; k++) { - PIC221111_16(k); - } - outc += 8; - outy += 16; - pic0 += 2 * width; - pic1 += 2 * width; - } - outy += 64 * 2 - 16 * 4; - } -} - -static void col221111_32(int *out, unsigned char *pic, int width) -{ - int i, j, k; - unsigned char *pic0, *pic1; - int *outy, *outc; - int cr, cg, cb, y; - - pic0 = pic; - pic1 = pic + width; - outy = out; - outc = out + 64 * 4; - for (i = 2; i > 0; i--) { - for (j = 4; j > 0; j--) { - for (k = 0; k < 8; k++) { - PIC221111_32(k); - } - outc += 8; - outy += 16; - pic0 += 2 * width; - pic1 += 2 * width; - } - outy += 64 * 2 - 16 * 4; - } -} diff --git a/roms/seabios/src/jpeg.h b/roms/seabios/src/jpeg.h deleted file mode 100644 index a2ac501..0000000 --- a/roms/seabios/src/jpeg.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __JPEG_H -#define __JPEG_H - -struct jpeg_decdata; -struct jpeg_decdata *jpeg_alloc(void); -int jpeg_decode(struct jpeg_decdata *jpeg, unsigned char *buf); -void jpeg_get_size(struct jpeg_decdata *jpeg, int *width, int *height); -int jpeg_show(struct jpeg_decdata *jpeg, unsigned char *pic - , int width, int height, int depth); - -#endif diff --git a/roms/seabios/src/kbd.c b/roms/seabios/src/kbd.c deleted file mode 100644 index 1977c5d..0000000 --- a/roms/seabios/src/kbd.c +++ /dev/null @@ -1,573 +0,0 @@ -// 16bit code to handle keyboard requests. -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "biosvar.h" // GET_BDA -#include "util.h" // debug_enter -#include "config.h" // CONFIG_* -#include "bregs.h" // struct bregs -#include "ps2port.h" // ps2_kbd_command -#include "usb-hid.h" // usb_kbd_command - -// Bit definitions for BDA kbd_flag[012] -#define KF0_RSHIFT (1<<0) -#define KF0_LSHIFT (1<<1) -#define KF0_CTRLACTIVE (1<<2) -#define KF0_ALTACTIVE (1<<3) -#define KF0_SCROLLACTIVE (1<<4) -#define KF0_NUMACTIVE (1<<5) -#define KF0_CAPSACTIVE (1<<6) - -#define KF1_LCTRL (1<<0) -#define KF1_LALT (1<<1) -#define KF1_PAUSEACTIVE (1<<3) -#define KF1_SCROLL (1<<4) -#define KF1_NUM (1<<5) -#define KF1_CAPS (1<<6) - -#define KF2_LAST_E1 (1<<0) -#define KF2_LAST_E0 (1<<1) -#define KF2_RCTRL (1<<2) -#define KF2_RALT (1<<3) -#define KF2_101KBD (1<<4) - -void -kbd_setup(void) -{ - dprintf(3, "init keyboard\n"); - u16 x = offsetof(struct bios_data_area_s, kbd_buf); - SET_BDA(kbd_flag2, KF2_101KBD); - SET_BDA(kbd_buf_head, x); - SET_BDA(kbd_buf_tail, x); - SET_BDA(kbd_buf_start_offset, x); - - SET_BDA(kbd_buf_end_offset - , x + FIELD_SIZEOF(struct bios_data_area_s, kbd_buf)); -} - -static u8 -enqueue_key(u8 scan_code, u8 ascii_code) -{ - u16 buffer_start = GET_BDA(kbd_buf_start_offset); - u16 buffer_end = GET_BDA(kbd_buf_end_offset); - - u16 buffer_head = GET_BDA(kbd_buf_head); - u16 buffer_tail = GET_BDA(kbd_buf_tail); - - u16 temp_tail = buffer_tail; - buffer_tail += 2; - if (buffer_tail >= buffer_end) - buffer_tail = buffer_start; - - if (buffer_tail == buffer_head) - return 0; - - SET_FARVAR(SEG_BDA, *(u8*)(temp_tail+0), ascii_code); - SET_FARVAR(SEG_BDA, *(u8*)(temp_tail+1), scan_code); - SET_BDA(kbd_buf_tail, buffer_tail); - return 1; -} - -static void -dequeue_key(struct bregs *regs, int incr, int extended) -{ - yield(); - u16 buffer_head; - u16 buffer_tail; - for (;;) { - buffer_head = GET_BDA(kbd_buf_head); - buffer_tail = GET_BDA(kbd_buf_tail); - - if (buffer_head != buffer_tail) - break; - if (!incr) { - regs->flags |= F_ZF; - return; - } - wait_irq(); - } - - u8 ascii_code = GET_FARVAR(SEG_BDA, *(u8*)(buffer_head+0)); - u8 scan_code = GET_FARVAR(SEG_BDA, *(u8*)(buffer_head+1)); - if ((ascii_code == 0xF0 && scan_code != 0) - || (ascii_code == 0xE0 && !extended)) - ascii_code = 0; - regs->ax = (scan_code << 8) | ascii_code; - - if (!incr) { - regs->flags &= ~F_ZF; - return; - } - u16 buffer_start = GET_BDA(kbd_buf_start_offset); - u16 buffer_end = GET_BDA(kbd_buf_end_offset); - - buffer_head += 2; - if (buffer_head >= buffer_end) - buffer_head = buffer_start; - SET_BDA(kbd_buf_head, buffer_head); -} - -static inline int -kbd_command(int command, u8 *param) -{ - if (usb_kbd_active()) - return usb_kbd_command(command, param); - return ps2_kbd_command(command, param); -} - -// read keyboard input -static void -handle_1600(struct bregs *regs) -{ - dequeue_key(regs, 1, 0); -} - -// check keyboard status -static void -handle_1601(struct bregs *regs) -{ - dequeue_key(regs, 0, 0); -} - -// get shift flag status -static void -handle_1602(struct bregs *regs) -{ - yield(); - regs->al = GET_BDA(kbd_flag0); -} - -// store key-stroke into buffer -static void -handle_1605(struct bregs *regs) -{ - regs->al = !enqueue_key(regs->ch, regs->cl); -} - -// GET KEYBOARD FUNCTIONALITY -static void -handle_1609(struct bregs *regs) -{ - // bit Bochs Description - // 7 0 reserved - // 6 0 INT 16/AH=20h-22h supported (122-key keyboard support) - // 5 1 INT 16/AH=10h-12h supported (enhanced keyboard support) - // 4 1 INT 16/AH=0Ah supported - // 3 0 INT 16/AX=0306h supported - // 2 0 INT 16/AX=0305h supported - // 1 0 INT 16/AX=0304h supported - // 0 0 INT 16/AX=0300h supported - // - regs->al = 0x30; -} - -// GET KEYBOARD ID -static void -handle_160a(struct bregs *regs) -{ - u8 param[2]; - int ret = kbd_command(ATKBD_CMD_GETID, param); - if (ret) { - regs->bx = 0; - return; - } - regs->bx = (param[1] << 8) | param[0]; -} - -// read MF-II keyboard input -static void -handle_1610(struct bregs *regs) -{ - dequeue_key(regs, 1, 1); -} - -// check MF-II keyboard status -static void -handle_1611(struct bregs *regs) -{ - dequeue_key(regs, 0, 1); -} - -// get extended keyboard status -static void -handle_1612(struct bregs *regs) -{ - yield(); - regs->al = GET_BDA(kbd_flag0); - regs->ah = ((GET_BDA(kbd_flag1) & ~(KF2_RCTRL|KF2_RALT)) - | (GET_BDA(kbd_flag2) & (KF2_RCTRL|KF2_RALT))); - //BX_DEBUG_INT16("int16: func 12 sending %04x\n",AX); -} - -static void -handle_166f(struct bregs *regs) -{ - if (regs->al == 0x08) - // unsupported, aka normal keyboard - regs->ah = 2; -} - -// keyboard capability check called by DOS 5.0+ keyb -static void -handle_1692(struct bregs *regs) -{ - // function int16 ah=0x10-0x12 supported - regs->ah = 0x80; -} - -// 122 keys capability check called by DOS 5.0+ keyb -static void -handle_16a2(struct bregs *regs) -{ - // don't change AH : function int16 ah=0x20-0x22 NOT supported -} - -static void -handle_16XX(struct bregs *regs) -{ - warn_unimplemented(regs); -} - -static void -set_leds(void) -{ - u8 shift_flags = (GET_BDA(kbd_flag0) >> 4) & 0x07; - u8 kbd_led = GET_BDA(kbd_led); - u8 led_flags = kbd_led & 0x07; - if (shift_flags == led_flags) - return; - - int ret = kbd_command(ATKBD_CMD_SETLEDS, &shift_flags); - if (ret) - // Error - return; - kbd_led = (kbd_led & ~0x07) | shift_flags; - SET_BDA(kbd_led, kbd_led); -} - -// INT 16h Keyboard Service Entry Point -void VISIBLE16 -handle_16(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_16); - if (! CONFIG_KEYBOARD) - return; - - // XXX - set_leds should be called from irq handler - set_leds(); - - switch (regs->ah) { - case 0x00: handle_1600(regs); break; - case 0x01: handle_1601(regs); break; - case 0x02: handle_1602(regs); break; - case 0x05: handle_1605(regs); break; - case 0x09: handle_1609(regs); break; - case 0x0a: handle_160a(regs); break; - case 0x10: handle_1610(regs); break; - case 0x11: handle_1611(regs); break; - case 0x12: handle_1612(regs); break; - case 0x92: handle_1692(regs); break; - case 0xa2: handle_16a2(regs); break; - case 0x6f: handle_166f(regs); break; - default: handle_16XX(regs); break; - } -} - -#define none 0 -#define MNUM KF0_NUMACTIVE -#define MCAP KF0_CAPSACTIVE - -static struct scaninfo { - u16 normal; - u16 shift; - u16 control; - u16 alt; - u8 lock_flags; -} scan_to_scanascii[] VAR16 = { - { none, none, none, none, none }, - { 0x011b, 0x011b, 0x011b, 0x0100, none }, /* escape */ - { 0x0231, 0x0221, none, 0x7800, none }, /* 1! */ - { 0x0332, 0x0340, 0x0300, 0x7900, none }, /* 2@ */ - { 0x0433, 0x0423, none, 0x7a00, none }, /* 3# */ - { 0x0534, 0x0524, none, 0x7b00, none }, /* 4$ */ - { 0x0635, 0x0625, none, 0x7c00, none }, /* 5% */ - { 0x0736, 0x075e, 0x071e, 0x7d00, none }, /* 6^ */ - { 0x0837, 0x0826, none, 0x7e00, none }, /* 7& */ - { 0x0938, 0x092a, none, 0x7f00, none }, /* 8* */ - { 0x0a39, 0x0a28, none, 0x8000, none }, /* 9( */ - { 0x0b30, 0x0b29, none, 0x8100, none }, /* 0) */ - { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200, none }, /* -_ */ - { 0x0d3d, 0x0d2b, none, 0x8300, none }, /* =+ */ - { 0x0e08, 0x0e08, 0x0e7f, none, none }, /* backspace */ - { 0x0f09, 0x0f00, none, none, none }, /* tab */ - { 0x1071, 0x1051, 0x1011, 0x1000, MCAP }, /* Q */ - { 0x1177, 0x1157, 0x1117, 0x1100, MCAP }, /* W */ - { 0x1265, 0x1245, 0x1205, 0x1200, MCAP }, /* E */ - { 0x1372, 0x1352, 0x1312, 0x1300, MCAP }, /* R */ - { 0x1474, 0x1454, 0x1414, 0x1400, MCAP }, /* T */ - { 0x1579, 0x1559, 0x1519, 0x1500, MCAP }, /* Y */ - { 0x1675, 0x1655, 0x1615, 0x1600, MCAP }, /* U */ - { 0x1769, 0x1749, 0x1709, 0x1700, MCAP }, /* I */ - { 0x186f, 0x184f, 0x180f, 0x1800, MCAP }, /* O */ - { 0x1970, 0x1950, 0x1910, 0x1900, MCAP }, /* P */ - { 0x1a5b, 0x1a7b, 0x1a1b, none, none }, /* [{ */ - { 0x1b5d, 0x1b7d, 0x1b1d, none, none }, /* ]} */ - { 0x1c0d, 0x1c0d, 0x1c0a, none, none }, /* Enter */ - { none, none, none, none, none }, /* L Ctrl */ - { 0x1e61, 0x1e41, 0x1e01, 0x1e00, MCAP }, /* A */ - { 0x1f73, 0x1f53, 0x1f13, 0x1f00, MCAP }, /* S */ - { 0x2064, 0x2044, 0x2004, 0x2000, MCAP }, /* D */ - { 0x2166, 0x2146, 0x2106, 0x2100, MCAP }, /* F */ - { 0x2267, 0x2247, 0x2207, 0x2200, MCAP }, /* G */ - { 0x2368, 0x2348, 0x2308, 0x2300, MCAP }, /* H */ - { 0x246a, 0x244a, 0x240a, 0x2400, MCAP }, /* J */ - { 0x256b, 0x254b, 0x250b, 0x2500, MCAP }, /* K */ - { 0x266c, 0x264c, 0x260c, 0x2600, MCAP }, /* L */ - { 0x273b, 0x273a, none, none, none }, /* ;: */ - { 0x2827, 0x2822, none, none, none }, /* '" */ - { 0x2960, 0x297e, none, none, none }, /* `~ */ - { none, none, none, none, none }, /* L shift */ - { 0x2b5c, 0x2b7c, 0x2b1c, none, none }, /* |\ */ - { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00, MCAP }, /* Z */ - { 0x2d78, 0x2d58, 0x2d18, 0x2d00, MCAP }, /* X */ - { 0x2e63, 0x2e43, 0x2e03, 0x2e00, MCAP }, /* C */ - { 0x2f76, 0x2f56, 0x2f16, 0x2f00, MCAP }, /* V */ - { 0x3062, 0x3042, 0x3002, 0x3000, MCAP }, /* B */ - { 0x316e, 0x314e, 0x310e, 0x3100, MCAP }, /* N */ - { 0x326d, 0x324d, 0x320d, 0x3200, MCAP }, /* M */ - { 0x332c, 0x333c, none, none, none }, /* ,< */ - { 0x342e, 0x343e, none, none, none }, /* .> */ - { 0x352f, 0x353f, none, none, none }, /* /? */ - { none, none, none, none, none }, /* R Shift */ - { 0x372a, 0x372a, none, none, none }, /* * */ - { none, none, none, none, none }, /* L Alt */ - { 0x3920, 0x3920, 0x3920, 0x3920, none }, /* space */ - { none, none, none, none, none }, /* caps lock */ - { 0x3b00, 0x5400, 0x5e00, 0x6800, none }, /* F1 */ - { 0x3c00, 0x5500, 0x5f00, 0x6900, none }, /* F2 */ - { 0x3d00, 0x5600, 0x6000, 0x6a00, none }, /* F3 */ - { 0x3e00, 0x5700, 0x6100, 0x6b00, none }, /* F4 */ - { 0x3f00, 0x5800, 0x6200, 0x6c00, none }, /* F5 */ - { 0x4000, 0x5900, 0x6300, 0x6d00, none }, /* F6 */ - { 0x4100, 0x5a00, 0x6400, 0x6e00, none }, /* F7 */ - { 0x4200, 0x5b00, 0x6500, 0x6f00, none }, /* F8 */ - { 0x4300, 0x5c00, 0x6600, 0x7000, none }, /* F9 */ - { 0x4400, 0x5d00, 0x6700, 0x7100, none }, /* F10 */ - { none, none, none, none, none }, /* Num Lock */ - { none, none, none, none, none }, /* Scroll Lock */ - { 0x4700, 0x4737, 0x7700, none, MNUM }, /* 7 Home */ - { 0x4800, 0x4838, none, none, MNUM }, /* 8 UP */ - { 0x4900, 0x4939, 0x8400, none, MNUM }, /* 9 PgUp */ - { 0x4a2d, 0x4a2d, none, none, none }, /* - */ - { 0x4b00, 0x4b34, 0x7300, none, MNUM }, /* 4 Left */ - { 0x4c00, 0x4c35, none, none, MNUM }, /* 5 */ - { 0x4d00, 0x4d36, 0x7400, none, MNUM }, /* 6 Right */ - { 0x4e2b, 0x4e2b, none, none, none }, /* + */ - { 0x4f00, 0x4f31, 0x7500, none, MNUM }, /* 1 End */ - { 0x5000, 0x5032, none, none, MNUM }, /* 2 Down */ - { 0x5100, 0x5133, 0x7600, none, MNUM }, /* 3 PgDn */ - { 0x5200, 0x5230, none, none, MNUM }, /* 0 Ins */ - { 0x5300, 0x532e, none, none, MNUM }, /* Del */ - { none, none, none, none, none }, - { none, none, none, none, none }, - { 0x565c, 0x567c, none, none, none }, /* \| */ - { 0x8500, 0x8700, 0x8900, 0x8b00, none }, /* F11 */ - { 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */ -}; - -// Handle a scancode read from the ps2 port. Note that "noinline" is -// used to make sure the call to call16_simpint in process_key doesn't -// have the overhead of this function's stack. -static void noinline -__process_key(u8 scancode) -{ - u8 flags0 = GET_BDA(kbd_flag0); - u8 flags1 = GET_BDA(kbd_flag1); - u8 flags2 = GET_BDA(kbd_flag2); - - if (flags2 & KF2_LAST_E1) { - // Part of "pause" key (sequence is e1 1d 45 e1 9d c5) - if ((scancode & ~0x80) == 0x1d) - // Second key of sequence - return; - // Third key of sequence - clear flag. - flags2 &= ~KF2_LAST_E1; - SET_BDA(kbd_flag2, flags2); - - if (scancode == 0xc5) { - // Final key in sequence. - - // XXX - do actual pause. - } - return; - } - - // XXX - PrtScr should cause int 0x05 - // XXX - Ctrl+Break should cause int 0x1B - // XXX - SysReq should cause int 0x15/0x85 - - switch (scancode) { - case 0x00: - dprintf(1, "KBD: int09 handler: AL=0\n"); - return; - - case 0x3a: /* Caps Lock press */ - flags0 ^= KF0_CAPSACTIVE; - flags1 |= KF1_CAPS; - break; - case 0xba: /* Caps Lock release */ - flags1 &= ~KF1_CAPS; - break; - - case 0x2a: /* L Shift press */ - flags0 |= KF0_LSHIFT; - break; - case 0xaa: /* L Shift release */ - flags0 &= ~KF0_LSHIFT; - break; - - case 0x36: /* R Shift press */ - flags0 |= KF0_RSHIFT; - break; - case 0xb6: /* R Shift release */ - flags0 &= ~KF0_RSHIFT; - break; - - case 0x1d: /* Ctrl press */ - flags0 |= KF0_CTRLACTIVE; - if (flags2 & KF2_LAST_E0) - flags2 |= KF2_RCTRL; - else - flags1 |= KF1_LCTRL; - break; - case 0x9d: /* Ctrl release */ - flags0 &= ~KF0_CTRLACTIVE; - if (flags2 & KF2_LAST_E0) - flags2 &= ~KF2_RCTRL; - else - flags1 &= ~KF1_LCTRL; - break; - - case 0x38: /* Alt press */ - flags0 |= KF0_ALTACTIVE; - if (flags2 & KF2_LAST_E0) - flags2 |= KF2_RALT; - else - flags1 |= KF1_LALT; - break; - case 0xb8: /* Alt release */ - flags0 &= ~KF0_ALTACTIVE; - if (flags2 & KF2_LAST_E0) - flags2 &= ~KF2_RALT; - else - flags1 &= ~KF1_LALT; - break; - - case 0x45: /* Num Lock press */ - flags1 |= KF1_NUM; - flags0 ^= KF0_NUMACTIVE; - break; - case 0xc5: /* Num Lock release */ - flags1 &= ~KF1_NUM; - break; - - case 0x46: /* Scroll Lock press */ - flags1 |= KF1_SCROLL; - flags0 ^= KF0_SCROLLACTIVE; - break; - case 0xc6: /* Scroll Lock release */ - flags1 &= ~KF1_SCROLL; - break; - - case 0xe0: - // Extended key - flags2 |= KF2_LAST_E0; - SET_BDA(kbd_flag2, flags2); - return; - case 0xe1: - // Start of pause key sequence - flags2 |= KF2_LAST_E1; - break; - - default: - if (scancode & 0x80) - // toss key releases - break; - if (scancode == 0x53 - && ((flags0 & (KF0_CTRLACTIVE|KF0_ALTACTIVE)) - == (KF0_CTRLACTIVE|KF0_ALTACTIVE))) { - // Ctrl+alt+del - reset machine. - SET_BDA(soft_reset_flag, 0x1234); - reset_vector(); - } - if (scancode >= ARRAY_SIZE(scan_to_scanascii)) { - dprintf(1, "KBD: int09h_handler(): unknown scancode read: 0x%02x!\n" - , scancode); - return; - } - u8 asciicode; - struct scaninfo *info = &scan_to_scanascii[scancode]; - if (flags0 & KF0_ALTACTIVE) { - asciicode = GET_GLOBAL(info->alt); - scancode = GET_GLOBAL(info->alt) >> 8; - } else if (flags0 & KF0_CTRLACTIVE) { - asciicode = GET_GLOBAL(info->control); - scancode = GET_GLOBAL(info->control) >> 8; - } else if (flags2 & KF2_LAST_E0 - && scancode >= 0x47 && scancode <= 0x53) { - /* extended keys handling */ - asciicode = 0xe0; - scancode = GET_GLOBAL(info->normal) >> 8; - } else if (flags0 & (KF0_RSHIFT|KF0_LSHIFT)) { - /* check if lock state should be ignored because a SHIFT - * key is pressed */ - - if (flags0 & GET_GLOBAL(info->lock_flags)) { - asciicode = GET_GLOBAL(info->normal); - scancode = GET_GLOBAL(info->normal) >> 8; - } else { - asciicode = GET_GLOBAL(info->shift); - scancode = GET_GLOBAL(info->shift) >> 8; - } - } else { - /* check if lock is on */ - if (flags0 & GET_GLOBAL(info->lock_flags)) { - asciicode = GET_GLOBAL(info->shift); - scancode = GET_GLOBAL(info->shift) >> 8; - } else { - asciicode = GET_GLOBAL(info->normal); - scancode = GET_GLOBAL(info->normal) >> 8; - } - } - if (scancode==0 && asciicode==0) - dprintf(1, "KBD: scancode & asciicode are zero?\n"); - enqueue_key(scancode, asciicode); - break; - } - flags2 &= ~KF2_LAST_E0; - - SET_BDA(kbd_flag0, flags0); - SET_BDA(kbd_flag1, flags1); - SET_BDA(kbd_flag2, flags2); -} - -void -process_key(u8 key) -{ - if (!CONFIG_KEYBOARD) - return; - - if (CONFIG_KBD_CALL_INT15_4F) { - // allow for keyboard intercept - u32 eax = (0x4f << 8) | key; - u32 flags; - call16_simpint(0x15, &eax, &flags); - if (!(flags & F_CF)) - return; - key = eax; - } - __process_key(key); -} diff --git a/roms/seabios/src/lzmadecode.c b/roms/seabios/src/lzmadecode.c deleted file mode 100644 index 65819b5..0000000 --- a/roms/seabios/src/lzmadecode.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - LzmaDecode.c - LZMA Decoder (optimized for Speed version) - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this Code, expressly permits you to - statically or dynamically link your Code (or bind by name) to the - interfaces of this file without subjecting your linked Code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. -*/ - -#include "lzmadecode.h" - -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_READ_BYTE (*Buffer++) - -#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ - { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} - - -#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } - -#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 - - -#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } - -#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) -#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; -#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; - -#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ - { UpdateBit0(p); mi <<= 1; A0; } else \ - { UpdateBit1(p); mi = (mi + mi) + 1; A1; } - -#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) - -#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ - { int i = numLevels; res = 1; \ - do { CProb *cp = probs + res; RC_GET_BIT(cp, res) } while(--i != 0); \ - res -= (1 << numLevels); } - - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) -{ - unsigned char prop0; - if (size < LZMA_PROPERTIES_SIZE) - return LZMA_RESULT_DATA_ERROR; - prop0 = propsData[0]; - if (prop0 >= (9 * 5 * 5)) - return LZMA_RESULT_DATA_ERROR; - { - for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); - for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); - propsRes->lc = prop0; - /* - unsigned char remainder = (unsigned char)(prop0 / 9); - propsRes->lc = prop0 % 9; - propsRes->pb = remainder / 5; - propsRes->lp = remainder % 5; - */ - } - - return LZMA_RESULT_OK; -} - -#define kLzmaStreamWasFinishedId (-1) - -int LzmaDecode(CLzmaDecoderState *vs, - const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, - unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) -{ - CProb *p = vs->Probs; - SizeT nowPos = 0; - Byte previousByte = 0; - UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; - UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; - int lc = vs->Properties.lc; - - - int state = 0; - UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; - int len = 0; - const Byte *Buffer; - const Byte *BufferLim; - UInt32 Range; - UInt32 Code; - - *inSizeProcessed = 0; - *outSizeProcessed = 0; - - { - UInt32 i; - UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); - for (i = 0; i < numProbs; i++) - p[i] = kBitModelTotal >> 1; - } - - RC_INIT(inStream, inSize); - - - while(nowPos < outSize) - { - CProb *prob; - UInt32 bound; - int posState = (int)( - (nowPos - ) - & posStateMask); - - prob = p + IsMatch + (state << kNumPosBitsMax) + posState; - IfBit0(prob) - { - int symbol = 1; - UpdateBit0(prob) - prob = p + Literal + (LZMA_LIT_SIZE * - ((( - (nowPos - ) - & literalPosMask) << lc) + (previousByte >> (8 - lc)))); - - if (state >= kNumLitStates) - { - int matchByte; - matchByte = outStream[nowPos - rep0]; - do - { - int bit; - CProb *probLit; - matchByte <<= 1; - bit = (matchByte & 0x100); - probLit = prob + 0x100 + bit + symbol; - RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) - } - while (symbol < 0x100); - } - while (symbol < 0x100) - { - CProb *probLit = prob + symbol; - RC_GET_BIT(probLit, symbol) - } - previousByte = (Byte)symbol; - - outStream[nowPos++] = previousByte; - if (state < 4) state = 0; - else if (state < 10) state -= 3; - else state -= 6; - } - else - { - UpdateBit1(prob); - prob = p + IsRep + state; - IfBit0(prob) - { - UpdateBit0(prob); - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - state = state < kNumLitStates ? 0 : 3; - prob = p + LenCoder; - } - else - { - UpdateBit1(prob); - prob = p + IsRepG0 + state; - IfBit0(prob) - { - UpdateBit0(prob); - prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; - IfBit0(prob) - { - UpdateBit0(prob); - - if (nowPos == 0) - return LZMA_RESULT_DATA_ERROR; - - state = state < kNumLitStates ? 9 : 11; - previousByte = outStream[nowPos - rep0]; - outStream[nowPos++] = previousByte; - - continue; - } - else - { - UpdateBit1(prob); - } - } - else - { - UInt32 distance; - UpdateBit1(prob); - prob = p + IsRepG1 + state; - IfBit0(prob) - { - UpdateBit0(prob); - distance = rep1; - } - else - { - UpdateBit1(prob); - prob = p + IsRepG2 + state; - IfBit0(prob) - { - UpdateBit0(prob); - distance = rep2; - } - else - { - UpdateBit1(prob); - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = p + RepLenCoder; - } - { - int numBits, offset; - CProb *probLen = prob + LenChoice; - IfBit0(probLen) - { - UpdateBit0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - numBits = kLenNumLowBits; - } - else - { - UpdateBit1(probLen); - probLen = prob + LenChoice2; - IfBit0(probLen) - { - UpdateBit0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - numBits = kLenNumMidBits; - } - else - { - UpdateBit1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - numBits = kLenNumHighBits; - } - } - RangeDecoderBitTreeDecode(probLen, numBits, len); - len += offset; - } - - if (state < 4) - { - int posSlot; - state += kNumLitStates; - prob = p + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - rep0 = (2 | ((UInt32)posSlot & 1)); - if (posSlot < kEndPosModelIndex) - { - rep0 <<= numDirectBits; - prob = p + SpecPos + rep0 - posSlot - 1; - } - else - { - numDirectBits -= kNumAlignBits; - do - { - RC_NORMALIZE - Range >>= 1; - rep0 <<= 1; - if (Code >= Range) - { - Code -= Range; - rep0 |= 1; - } - } - while (--numDirectBits != 0); - prob = p + Align; - rep0 <<= kNumAlignBits; - numDirectBits = kNumAlignBits; - } - { - int i = 1; - int mi = 1; - do - { - CProb *prob3 = prob + mi; - RC_GET_BIT2(prob3, mi, ; , rep0 |= i); - i <<= 1; - } - while(--numDirectBits != 0); - } - } - else - rep0 = posSlot; - if (++rep0 == (UInt32)(0)) - { - /* it's for stream version */ - len = kLzmaStreamWasFinishedId; - break; - } - } - - len += kMatchMinLen; - if (rep0 > nowPos) - return LZMA_RESULT_DATA_ERROR; - - - do - { - previousByte = outStream[nowPos - rep0]; - len--; - outStream[nowPos++] = previousByte; - } - while(len != 0 && nowPos < outSize); - } - } - RC_NORMALIZE; - - - *inSizeProcessed = (SizeT)(Buffer - inStream); - *outSizeProcessed = nowPos; - return LZMA_RESULT_OK; -} diff --git a/roms/seabios/src/lzmadecode.h b/roms/seabios/src/lzmadecode.h deleted file mode 100644 index dedde0d..0000000 --- a/roms/seabios/src/lzmadecode.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - LzmaDecode.h - LZMA Decoder interface - - LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) - http://www.7-zip.org/ - - LZMA SDK is licensed under two licenses: - 1) GNU Lesser General Public License (GNU LGPL) - 2) Common Public License (CPL) - It means that you can select one of these two licenses and - follow rules of that license. - - SPECIAL EXCEPTION: - Igor Pavlov, as the author of this code, expressly permits you to - statically or dynamically link your code (or bind by name) to the - interfaces of this file without subjecting your linked code to the - terms of the CPL or GNU LGPL. Any modifications or additions - to this file, however, are subject to the LGPL or CPL terms. -*/ - -#ifndef __LZMADECODE_H -#define __LZMADECODE_H - -typedef unsigned char Byte; -typedef unsigned short UInt16; -typedef unsigned int UInt32; -typedef UInt32 SizeT; - -#define CProb UInt16 - -#define LZMA_RESULT_OK 0 -#define LZMA_RESULT_DATA_ERROR 1 - - -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 - -#define LZMA_PROPERTIES_SIZE 5 - -typedef struct _CLzmaProperties -{ - int lc; - int lp; - int pb; -}CLzmaProperties; - -int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); - -#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) - -#define kLzmaNeedInitId (-2) - -typedef struct _CLzmaDecoderState -{ - CLzmaProperties Properties; - CProb *Probs; - - -} CLzmaDecoderState; - - -int LzmaDecode(CLzmaDecoderState *vs, - const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, - unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); - -#endif diff --git a/roms/seabios/src/memmap.c b/roms/seabios/src/memmap.c deleted file mode 100644 index 84bc4fa..0000000 --- a/roms/seabios/src/memmap.c +++ /dev/null @@ -1,134 +0,0 @@ -// Support for building memory maps suitable for int 15 e820 calls. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "memmap.h" // struct e820entry -#include "util.h" // dprintf.h -#include "biosvar.h" // SET_EBDA - - -/**************************************************************** - * e820 memory map - ****************************************************************/ - -// Remove an entry from the e820_list. -static void -remove_e820(int i) -{ - e820_count--; - memmove(&e820_list[i], &e820_list[i+1] - , sizeof(e820_list[0]) * (e820_count - i)); -} - -// Insert an entry in the e820_list at the given position. -static void -insert_e820(int i, u64 start, u64 size, u32 type) -{ - if (e820_count >= CONFIG_MAX_E820) { - warn_noalloc(); - return; - } - - memmove(&e820_list[i+1], &e820_list[i] - , sizeof(e820_list[0]) * (e820_count - i)); - e820_count++; - struct e820entry *e = &e820_list[i]; - e->start = start; - e->size = size; - e->type = type; -} - -// Show the current e820_list. -static void -dump_map(void) -{ - dprintf(1, "e820 map has %d items:\n", e820_count); - int i; - for (i=0; istart + e->size; - dprintf(1, " %d: %08x%08x - %08x%08x = %d\n", i - , (u32)(e->start >> 32), (u32)e->start - , (u32)(e_end >> 32), (u32)e_end - , e->type); - } -} - -// Add a new entry to the list. This scans for overlaps and keeps the -// list sorted. -void -add_e820(u64 start, u64 size, u32 type) -{ - dprintf(8, "Add to e820 map: %08x %08x %d\n", (u32)start, (u32)size, type); - - if (! size) - // Huh? Nothing to do. - return; - - // Find position of new item (splitting existing item if needed). - u64 end = start + size; - int i; - for (i=0; istart + e->size; - if (start > e_end) - continue; - // Found position - check if an existing item needs to be split. - if (start > e->start) { - if (type == e->type) { - // Same type - merge them. - size += start - e->start; - start = e->start; - } else { - // Split existing item. - e->size = start - e->start; - i++; - if (e_end > end) - insert_e820(i, end, e_end - end, e->type); - } - } - break; - } - // Remove/adjust existing items that are overlapping. - while (istart) - // No overlap - done. - break; - u64 e_end = e->start + e->size; - if (end >= e_end) { - // Existing item completely overlapped - remove it. - remove_e820(i); - continue; - } - // Not completely overlapped - adjust its start. - e->start = end; - e->size = e_end - end; - if (type == e->type) { - // Same type - merge them. - size += e->size; - remove_e820(i); - } - break; - } - // Insert new item. - if (type != E820_HOLE) - insert_e820(i, start, size, type); - //dump_map(); -} - -// Prep for memmap stuff - init bios table locations. -void -memmap_setup(void) -{ - e820_count = 0; -} - -// Report on final memory locations. -void -memmap_finalize(void) -{ - dump_map(); -} diff --git a/roms/seabios/src/memmap.h b/roms/seabios/src/memmap.h deleted file mode 100644 index d4154c1..0000000 --- a/roms/seabios/src/memmap.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __E820MAP_H -#define __E820MAP_H - -#include "types.h" // u64 - -#define E820_RAM 1 -#define E820_RESERVED 2 -#define E820_ACPI 3 -#define E820_NVS 4 -#define E820_UNUSABLE 5 -#define E820_HOLE ((u32)-1) // Useful for removing entries - -struct e820entry { - u64 start; - u64 size; - u32 type; -}; - -void add_e820(u64 start, u64 size, u32 type); -void memmap_setup(void); -void memmap_finalize(void); - -// A typical OS page size -#define PAGE_SIZE 4096 - -// e820 map storage (defined in system.c) -extern struct e820entry e820_list[]; -extern int e820_count; - -// Space for exported bios tables (defined in misc.c) -extern char BiosTableSpace[]; - -#endif // e820map.h diff --git a/roms/seabios/src/misc.c b/roms/seabios/src/misc.c deleted file mode 100644 index 9db49e3..0000000 --- a/roms/seabios/src/misc.c +++ /dev/null @@ -1,190 +0,0 @@ -// Code for misc 16bit handlers and variables. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "bregs.h" // struct bregs -#include "biosvar.h" // GET_BDA -#include "util.h" // debug_enter -#include "pic.h" // enable_hwirq - -// Amount of continuous ram under 4Gig -u32 RamSize VAR16VISIBLE; -// Amount of continuous ram >4Gig -u64 RamSizeOver4G; -// Space for bios tables built an run-time. -char BiosTableSpace[CONFIG_MAX_BIOSTABLE] __aligned(MALLOC_MIN_ALIGN) VAR16VISIBLE; - - -/**************************************************************** - * Misc 16bit ISRs - ****************************************************************/ - -// INT 12h Memory Size Service Entry Point -void VISIBLE16 -handle_12(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_12); - regs->ax = GET_BDA(mem_size_kb); -} - -// INT 11h Equipment List Service Entry Point -void VISIBLE16 -handle_11(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_11); - regs->ax = GET_BDA(equipment_list_flags); -} - -// INT 05h Print Screen Service Entry Point -void VISIBLE16 -handle_05(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_05); -} - -// INT 10h Video Support Service Entry Point -void VISIBLE16 -handle_10(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_10); - // dont do anything, since the VGA BIOS handles int10h requests -} - -// NMI handler -void VISIBLE16 -handle_02(void) -{ - debug_isr(DEBUG_ISR_02); -} - -void -mathcp_setup(void) -{ - dprintf(3, "math cp init\n"); - // 80x87 coprocessor installed - SETBITS_BDA(equipment_list_flags, 0x02); - enable_hwirq(13, FUNC16(entry_75)); -} - -// INT 75 - IRQ13 - MATH COPROCESSOR EXCEPTION -void VISIBLE16 -handle_75(void) -{ - debug_isr(DEBUG_ISR_75); - - // clear irq13 - outb(0, PORT_MATH_CLEAR); - // clear interrupt - eoi_pic2(); - // legacy nmi call - u32 eax=0, flags; - call16_simpint(0x02, &eax, &flags); -} - - -/**************************************************************** - * BIOS_CONFIG_TABLE - ****************************************************************/ - -// DMA channel 3 used by hard disk BIOS -#define CBT_F1_DMA3USED (1<<7) -// 2nd interrupt controller (8259) installed -#define CBT_F1_2NDPIC (1<<6) -// Real-Time Clock installed -#define CBT_F1_RTC (1<<5) -// INT 15/AH=4Fh called upon INT 09h -#define CBT_F1_INT154F (1<<4) -// wait for external event (INT 15/AH=41h) supported -#define CBT_F1_WAITEXT (1<<3) -// extended BIOS area allocated (usually at top of RAM) -#define CBT_F1_EBDA (1<<2) -// bus is Micro Channel instead of ISA -#define CBT_F1_MCA (1<<1) -// system has dual bus (Micro Channel + ISA) -#define CBT_F1_MCAISA (1<<0) - -// INT 16/AH=09h (keyboard functionality) supported -#define CBT_F2_INT1609 (1<<6) - -struct bios_config_table_s BIOS_CONFIG_TABLE VAR16FIXED(0xe6f5) = { - .size = sizeof(BIOS_CONFIG_TABLE) - 2, - .model = CONFIG_MODEL_ID, - .submodel = CONFIG_SUBMODEL_ID, - .biosrev = CONFIG_BIOS_REVISION, - .feature1 = ( - CBT_F1_2NDPIC | CBT_F1_RTC | CBT_F1_EBDA - | (CONFIG_KBD_CALL_INT15_4F ? CBT_F1_INT154F : 0)), - .feature2 = CBT_F2_INT1609, - .feature3 = 0, - .feature4 = 0, - .feature5 = 0, -}; - - -/**************************************************************** - * GDT and IDT tables - ****************************************************************/ - -// Real mode IDT descriptor -struct descloc_s rmode_IDT_info VAR16VISIBLE = { - .length = sizeof(struct rmode_IVT) - 1, - .addr = (u32)MAKE_FLATPTR(SEG_IVT, 0), -}; - -// Dummy IDT that forces a machine shutdown if an irq happens in -// protected mode. -u8 dummy_IDT VAR16VISIBLE; - -// Protected mode IDT descriptor -struct descloc_s pmode_IDT_info VAR16VISIBLE = { - .length = sizeof(dummy_IDT) - 1, - .addr = (u32)MAKE_FLATPTR(SEG_BIOS, &dummy_IDT), -}; - -// GDT -u64 rombios32_gdt[] VAR16VISIBLE __aligned(8) = { - // First entry can't be used. - 0x0000000000000000LL, - // 32 bit flat code segment (SEG32_MODE32_CS) - GDT_GRANLIMIT(0xffffffff) | GDT_CODE | GDT_B, - // 32 bit flat data segment (SEG32_MODE32_DS) - GDT_GRANLIMIT(0xffffffff) | GDT_DATA | GDT_B, - // 16 bit code segment base=0xf0000 limit=0xffff (SEG32_MODE16_CS) - GDT_LIMIT(BUILD_BIOS_SIZE-1) | GDT_CODE | GDT_BASE(BUILD_BIOS_ADDR), - // 16 bit data segment base=0x0 limit=0xffff (SEG32_MODE16_DS) - GDT_LIMIT(0x0ffff) | GDT_DATA, - // 16 bit code segment base=0xf0000 limit=0xffffffff (SEG32_MODE16BIG_CS) - GDT_GRANLIMIT(0xffffffff) | GDT_CODE | GDT_BASE(BUILD_BIOS_ADDR), - // 16 bit data segment base=0 limit=0xffffffff (SEG32_MODE16BIG_DS) - GDT_GRANLIMIT(0xffffffff) | GDT_DATA, -}; - -// GDT descriptor -struct descloc_s rombios32_gdt_48 VAR16VISIBLE = { - .length = sizeof(rombios32_gdt) - 1, - .addr = (u32)MAKE_FLATPTR(SEG_BIOS, rombios32_gdt), -}; - - -/**************************************************************** - * Misc fixed vars - ****************************************************************/ - -char BiosCopyright[] VAR16FIXED(0xff00) = - "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team."; - -// BIOS build date -char BiosDate[] VAR16FIXED(0xfff5) = "06/23/99"; - -u8 BiosModelId VAR16FIXED(0xfffe) = CONFIG_MODEL_ID; - -u8 BiosChecksum VAR16FIXED(0xffff); - -// XXX - Initial Interrupt Vector Offsets Loaded by POST -u8 InitVectors[13] VAR16FIXED(0xfef3); - -// XXX - INT 1D - SYSTEM DATA - VIDEO PARAMETER TABLES -u8 VideoParams[88] VAR16FIXED(0xf0a4); diff --git a/roms/seabios/src/mouse.c b/roms/seabios/src/mouse.c deleted file mode 100644 index 09273b0..0000000 --- a/roms/seabios/src/mouse.c +++ /dev/null @@ -1,344 +0,0 @@ -// 16bit code to handle mouse events. -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "biosvar.h" // GET_EBDA -#include "util.h" // debug_isr -#include "pic.h" // eoi_pic2 -#include "bregs.h" // struct bregs -#include "ps2port.h" // ps2_mouse_command -#include "usb-hid.h" // usb_mouse_command - -void -mouse_setup(void) -{ - if (! CONFIG_MOUSE) - return; - dprintf(3, "init mouse\n"); - // pointing device installed - SETBITS_BDA(equipment_list_flags, 0x04); -} - -static inline int -mouse_command(int command, u8 *param) -{ - if (usb_mouse_active()) - return usb_mouse_command(command, param); - return ps2_mouse_command(command, param); -} - -#define RET_SUCCESS 0x00 -#define RET_EINVFUNCTION 0x01 -#define RET_EINVINPUT 0x02 -#define RET_EINTERFACE 0x03 -#define RET_ENEEDRESEND 0x04 -#define RET_ENOHANDLER 0x05 - -static int -disable_mouse(u16 ebda_seg) -{ - u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr); - ps2ctr |= I8042_CTR_AUXDIS; - ps2ctr &= ~I8042_CTR_AUXINT; - SET_EBDA2(ebda_seg, ps2ctr, ps2ctr); - - return mouse_command(PSMOUSE_CMD_DISABLE, NULL); -} - -// Disable Mouse -static void -mouse_15c20000(struct bregs *regs) -{ - u16 ebda_seg = get_ebda_seg(); - int ret = disable_mouse(ebda_seg); - if (ret) - set_code_invalid(regs, RET_ENEEDRESEND); - else - set_code_success(regs); -} - -// Enable Mouse -static void -mouse_15c20001(struct bregs *regs) -{ - u16 ebda_seg = get_ebda_seg(); - u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2); - if ((mouse_flags_2 & 0x80) == 0) { - set_code_invalid(regs, RET_ENOHANDLER); - return; - } - - u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr); - ps2ctr &= ~I8042_CTR_AUXDIS; - ps2ctr |= I8042_CTR_AUXINT; - SET_EBDA2(ebda_seg, ps2ctr, ps2ctr); - - int ret = mouse_command(PSMOUSE_CMD_ENABLE, NULL); - if (ret) - set_code_invalid(regs, RET_ENEEDRESEND); - else - set_code_success(regs); -} - -static void -mouse_15c200XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EINVFUNCTION); -} - -// Disable/Enable Mouse -static void -mouse_15c200(struct bregs *regs) -{ - switch (regs->bh) { - case 0x00: mouse_15c20000(regs); break; - case 0x01: mouse_15c20001(regs); break; - default: mouse_15c200XX(regs); break; - } -} - -// Reset Mouse -static void -mouse_15c201(struct bregs *regs) -{ - u8 param[2]; - int ret = mouse_command(PSMOUSE_CMD_RESET_BAT, param); - if (ret) { - set_code_invalid(regs, RET_ENEEDRESEND); - return; - } - regs->bl = param[0]; - regs->bh = param[1]; - set_code_success(regs); -} - -// Set Sample Rate -static void -mouse_15c202(struct bregs *regs) -{ - static u8 VAR16 sample_rates[7] = {10, 20, 40, 60, 80, 100, 200}; - if (regs->bh >= ARRAY_SIZE(sample_rates)) { - set_code_invalid(regs, RET_EINVINPUT); - return; - } - u8 mouse_data1 = GET_GLOBAL(sample_rates[regs->bh]); - int ret = mouse_command(PSMOUSE_CMD_SETRATE, &mouse_data1); - if (ret) - set_code_invalid(regs, RET_ENEEDRESEND); - else - set_code_success(regs); -} - -// Set Resolution -static void -mouse_15c203(struct bregs *regs) -{ - // BH: - // 0 = 25 dpi, 1 count per millimeter - // 1 = 50 dpi, 2 counts per millimeter - // 2 = 100 dpi, 4 counts per millimeter - // 3 = 200 dpi, 8 counts per millimeter - if (regs->bh >= 4) { - set_code_invalid(regs, RET_EINVINPUT); - return; - } - u8 param = regs->bh; - int ret = mouse_command(PSMOUSE_CMD_SETRES, ¶m); - if (ret) - set_code_invalid(regs, RET_ENEEDRESEND); - else - set_code_success(regs); -} - -// Get Device ID -static void -mouse_15c204(struct bregs *regs) -{ - u8 param[2]; - int ret = mouse_command(PSMOUSE_CMD_GETID, param); - if (ret) { - set_code_invalid(regs, RET_ENEEDRESEND); - return; - } - regs->bh = param[0]; - set_code_success(regs); -} - -// Initialize Mouse -static void -mouse_15c205(struct bregs *regs) -{ - if (regs->bh != 3) { - set_code_invalid(regs, RET_EINTERFACE); - return; - } - u16 ebda_seg = get_ebda_seg(); - SET_EBDA2(ebda_seg, mouse_flag1, 0x00); - SET_EBDA2(ebda_seg, mouse_flag2, regs->bh); - - // Reset Mouse - mouse_15c201(regs); -} - -// Return Status -static void -mouse_15c20600(struct bregs *regs) -{ - u8 param[3]; - int ret = mouse_command(PSMOUSE_CMD_GETINFO, param); - if (ret) { - set_code_invalid(regs, RET_ENEEDRESEND); - return; - } - regs->bl = param[0]; - regs->cl = param[1]; - regs->dl = param[2]; - set_code_success(regs); -} - -// Set Scaling Factor to 1:1 -static void -mouse_15c20601(struct bregs *regs) -{ - int ret = mouse_command(PSMOUSE_CMD_SETSCALE11, NULL); - if (ret) - set_code_invalid(regs, RET_ENEEDRESEND); - else - set_code_success(regs); -} - -// Set Scaling Factor to 2:1 -static void -mouse_15c20602(struct bregs *regs) -{ - int ret = mouse_command(PSMOUSE_CMD_SETSCALE21, NULL); - if (ret) - set_code_invalid(regs, RET_ENEEDRESEND); - else - set_code_success(regs); -} - -static void -mouse_15c206XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EINVFUNCTION); -} - -// Return Status & Set Scaling Factor... -static void -mouse_15c206(struct bregs *regs) -{ - switch (regs->bh) { - case 0x00: mouse_15c20600(regs); break; - case 0x01: mouse_15c20601(regs); break; - case 0x02: mouse_15c20602(regs); break; - default: mouse_15c206XX(regs); break; - } -} - -// Set Mouse Handler Address -static void -mouse_15c207(struct bregs *regs) -{ - struct segoff_s farptr = SEGOFF(regs->es, regs->bx); - u16 ebda_seg = get_ebda_seg(); - u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2); - if (! farptr.segoff) { - /* remove handler */ - if ((mouse_flags_2 & 0x80) != 0) { - mouse_flags_2 &= ~0x80; - disable_mouse(ebda_seg); - } - } else { - /* install handler */ - mouse_flags_2 |= 0x80; - } - SET_EBDA2(ebda_seg, mouse_flag2, mouse_flags_2); - SET_EBDA2(ebda_seg, far_call_pointer, farptr); - set_code_success(regs); -} - -static void -mouse_15c2XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EINVFUNCTION); -} - -void -handle_15c2(struct bregs *regs) -{ - //debug_stub(regs); - - if (! CONFIG_MOUSE) { - set_code_invalid(regs, RET_EUNSUPPORTED); - return; - } - - switch (regs->al) { - case 0x00: mouse_15c200(regs); break; - case 0x01: mouse_15c201(regs); break; - case 0x02: mouse_15c202(regs); break; - case 0x03: mouse_15c203(regs); break; - case 0x04: mouse_15c204(regs); break; - case 0x05: mouse_15c205(regs); break; - case 0x06: mouse_15c206(regs); break; - case 0x07: mouse_15c207(regs); break; - default: mouse_15c2XX(regs); break; - } -} - -void noinline -process_mouse(u8 data) -{ - if (!CONFIG_MOUSE) - return; - - u16 ebda_seg = get_ebda_seg(); - u8 mouse_flags_1 = GET_EBDA2(ebda_seg, mouse_flag1); - u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2); - - if (! (mouse_flags_2 & 0x80)) - // far call handler not installed - return; - - u8 package_count = mouse_flags_2 & 0x07; - u8 index = mouse_flags_1 & 0x07; - SET_EBDA2(ebda_seg, mouse_data[index], data); - - if ((index+1) < package_count) { - mouse_flags_1++; - SET_EBDA2(ebda_seg, mouse_flag1, mouse_flags_1); - return; - } - - u16 status = GET_EBDA2(ebda_seg, mouse_data[0]); - u16 X = GET_EBDA2(ebda_seg, mouse_data[1]); - u16 Y = GET_EBDA2(ebda_seg, mouse_data[2]); - SET_EBDA2(ebda_seg, mouse_flag1, 0); - - struct segoff_s func = GET_EBDA2(ebda_seg, far_call_pointer); - dprintf(16, "mouse farcall s=%04x x=%04x y=%04x func=%04x:%04x\n" - , status, X, Y, func.seg, func.offset); - - asm volatile( - "pushl %%ebp\n" - "sti\n" - - "pushl %0\n" - "pushw %w1\n" // status - "pushw %w2\n" // X - "pushw %w3\n" // Y - "pushw $0\n" // Z - "lcallw *8(%%esp)\n" - "addl $12, %%esp\n" - - "cli\n" - "cld\n" - "popl %%ebp" - : "+a"(func.segoff), "+c"(status), "+d"(X), "+b"(Y) - : - : "edi", "esi", "cc", "memory"); -} diff --git a/roms/seabios/src/mptable.c b/roms/seabios/src/mptable.c deleted file mode 100644 index e5952c3..0000000 --- a/roms/seabios/src/mptable.c +++ /dev/null @@ -1,206 +0,0 @@ -// MPTable generation (on emulators) -// -// Copyright (C) 2008-2010 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "config.h" // CONFIG_* -#include "mptable.h" // MPTABLE_SIGNATURE -#include "paravirt.h" // qemu_cfg_irq0_override -#include "pci.h" -#include "pci_regs.h" - -void -mptable_init(void) -{ - if (! CONFIG_MPTABLE) - return; - - dprintf(3, "init MPTable\n"); - - // Config structure in temp area. - struct mptable_config_s *config = malloc_tmp(32*1024); - if (!config) { - warn_noalloc(); - return; - } - memset(config, 0, sizeof(*config)); - config->signature = MPCONFIG_SIGNATURE; - config->spec = 4; - memcpy(config->oemid, CONFIG_CPUNAME8, sizeof(config->oemid)); - memcpy(config->productid, "0.1 ", sizeof(config->productid)); - config->lapic = BUILD_APIC_ADDR; - - // Detect cpu info - u32 cpuid_signature, ebx, ecx, cpuid_features; - cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features); - if (! cpuid_signature) { - // Use default values. - cpuid_signature = 0x600; - cpuid_features = 0x201; - } - int pkgcpus = 1; - if (cpuid_features & (1 << 28)) { - /* Only populate the MPS tables with the first logical CPU in - each package */ - pkgcpus = (ebx >> 16) & 0xff; - pkgcpus = 1 << (__fls(pkgcpus - 1) + 1); /* round up to power of 2 */ - } - u8 apic_version = readl((u8*)BUILD_APIC_ADDR + 0x30) & 0xff; - - // CPU definitions. - struct mpt_cpu *cpus = (void*)&config[1], *cpu = cpus; - int i; - for (i = 0; i < MaxCountCPUs; i+=pkgcpus) { - memset(cpu, 0, sizeof(*cpu)); - cpu->type = MPT_TYPE_CPU; - cpu->apicid = i; - cpu->apicver = apic_version; - /* cpu flags: enabled, bootstrap cpu */ - cpu->cpuflag = ((icpusignature = cpuid_signature; - cpu->featureflag = cpuid_features; - cpu++; - } - int entrycount = cpu - cpus; - - // PCI buses - struct mpt_bus *buses = (void*)cpu, *bus = buses; - int bdf, max, lastbus = -1; - foreachpci(bdf, max) { - int curbus = pci_bdf_to_bus(bdf); - if (curbus == lastbus) - continue; - lastbus = curbus; - memset(bus, 0, sizeof(*bus)); - bus->type = MPT_TYPE_BUS; - bus->busid = curbus; - memcpy(bus->bustype, "PCI ", sizeof(bus->bustype)); - bus++; - } - - /* isa bus */ - int isabusid; - memset(bus, 0, sizeof(*bus)); - bus->type = MPT_TYPE_BUS; - isabusid = bus->busid = lastbus + 1; - memcpy(bus->bustype, "ISA ", sizeof(bus->bustype)); - bus++; - entrycount += bus - buses; - - /* ioapic */ - u8 ioapic_id = CountCPUs; - struct mpt_ioapic *ioapic = (void*)bus; - memset(ioapic, 0, sizeof(*ioapic)); - ioapic->type = MPT_TYPE_IOAPIC; - ioapic->apicid = ioapic_id; - ioapic->apicver = 0x11; - ioapic->flags = 1; // enable - ioapic->apicaddr = BUILD_IOAPIC_ADDR; - entrycount++; - - /* irqs */ - struct mpt_intsrc *intsrcs = (void*)&ioapic[1], *intsrc = intsrcs; - int dev = -1; - unsigned short mask = 0, pinmask = 0; - - foreachpci(bdf, max) { - int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN); - int irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE); - if (pin == 0) - continue; - if (dev != pci_bdf_to_busdev(bdf)) { - dev = pci_bdf_to_busdev(bdf); - pinmask = 0; - } - if (pinmask & (1 << pin)) /* pin was seen already */ - continue; - pinmask |= (1 << pin); - mask |= (1 << irq); - memset(intsrc, 0, sizeof(*intsrc)); - intsrc->type = MPT_TYPE_INTSRC; - intsrc->irqtype = 0; /* INT */ - intsrc->irqflag = 1; /* active high */ - intsrc->srcbus = pci_bdf_to_bus(bdf); /* PCI bus */ - intsrc->srcbusirq = (pci_bdf_to_dev(bdf) << 2) | (pin - 1); - intsrc->dstapic = ioapic_id; - intsrc->dstirq = irq; - intsrc++; - } - - for (i = 0; i < 16; i++) { - memset(intsrc, 0, sizeof(*intsrc)); - if (mask & (1 << i)) - continue; - intsrc->type = MPT_TYPE_INTSRC; - intsrc->irqtype = 0; /* INT */ - intsrc->irqflag = 0; /* conform to bus spec */ - intsrc->srcbus = isabusid; /* ISA bus */ - intsrc->srcbusirq = i; - intsrc->dstapic = ioapic_id; - intsrc->dstirq = i; - if (qemu_cfg_irq0_override()) { - /* Destination 2 is covered by irq0->inti2 override (i == - 0). Source IRQ 2 is unused */ - if (i == 0) - intsrc->dstirq = 2; - else if (i == 2) - intsrc--; - } - intsrc++; - } - - /* Local interrupt assignment */ - intsrc->type = MPT_TYPE_LOCAL_INT; - intsrc->irqtype = 3; /* ExtINT */ - intsrc->irqflag = 0; /* PO, EL default */ - intsrc->srcbus = isabusid; /* ISA */ - intsrc->srcbusirq = 0; - intsrc->dstapic = 0; /* BSP == APIC #0 */ - intsrc->dstirq = 0; /* LINTIN0 */ - intsrc++; - - intsrc->type = MPT_TYPE_LOCAL_INT; - intsrc->irqtype = 1; /* NMI */ - intsrc->irqflag = 0; /* PO, EL default */ - intsrc->srcbus = isabusid; /* ISA */ - intsrc->srcbusirq = 0; - intsrc->dstapic = 0; /* BSP == APIC #0 */ - intsrc->dstirq = 1; /* LINTIN1 */ - intsrc++; - entrycount += intsrc - intsrcs; - - // Finalize config structure. - int length = (void*)intsrc - (void*)config; - config->entrycount = entrycount; - config->length = length; - config->checksum -= checksum(config, length); - - // Allocate final memory locations. (In theory the config - // structure can go in high memory, but Linux kernels before - // v2.6.30 crash with that.) - struct mptable_config_s *finalconfig = malloc_fseg(length); - struct mptable_floating_s *floating = malloc_fseg(sizeof(*floating)); - if (!finalconfig || !floating) { - warn_noalloc(); - free(config); - free(finalconfig); - free(floating); - return; - } - memcpy(finalconfig, config, length); - free(config); - - /* floating pointer structure */ - memset(floating, 0, sizeof(*floating)); - floating->signature = MPTABLE_SIGNATURE; - floating->physaddr = (u32)finalconfig; - floating->length = 1; - floating->spec_rev = 4; - floating->checksum -= checksum(floating, sizeof(*floating)); - - dprintf(1, "MP table addr=%p MPC table addr=%p size=%d\n", - floating, finalconfig, length); -} diff --git a/roms/seabios/src/mptable.h b/roms/seabios/src/mptable.h deleted file mode 100644 index c4e3c51..0000000 --- a/roms/seabios/src/mptable.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef __MPTABLE_H -#define __MPTABLE_H - -#include "types.h" // u32 - -#define MPTABLE_SIGNATURE 0x5f504d5f // "_MP_" - -struct mptable_floating_s { - u32 signature; - u32 physaddr; - u8 length; - u8 spec_rev; - u8 checksum; - u8 feature1; - u8 feature2; - u8 reserved[3]; -}; - -#define MPCONFIG_SIGNATURE 0x504d4350 // "PCMP" - -struct mptable_config_s { - u32 signature; - u16 length; - u8 spec; - u8 checksum; - char oemid[8]; - char productid[12]; - u32 oemptr; - u16 oemsize; - u16 entrycount; - u32 lapic; - u16 exttable_length; - u8 exttable_checksum; - u8 reserved; -} PACKED; - -#define MPT_TYPE_CPU 0 -#define MPT_TYPE_BUS 1 -#define MPT_TYPE_IOAPIC 2 -#define MPT_TYPE_INTSRC 3 -#define MPT_TYPE_LOCAL_INT 4 - -struct mpt_cpu { - u8 type; - u8 apicid; - u8 apicver; - u8 cpuflag; - u32 cpusignature; - u32 featureflag; - u32 reserved[2]; -} PACKED; - -struct mpt_bus { - u8 type; - u8 busid; - char bustype[6]; -} PACKED; - -struct mpt_ioapic { - u8 type; - u8 apicid; - u8 apicver; - u8 flags; - u32 apicaddr; -} PACKED; - -struct mpt_intsrc { - u8 type; - u8 irqtype; - u16 irqflag; - u8 srcbus; - u8 srcbusirq; - u8 dstapic; - u8 dstirq; -} PACKED; - -// mptable.c -void mptable_init(void); - -#endif // mptable.h diff --git a/roms/seabios/src/mtrr.c b/roms/seabios/src/mtrr.c deleted file mode 100644 index ed239c8..0000000 --- a/roms/seabios/src/mtrr.c +++ /dev/null @@ -1,102 +0,0 @@ -// Initialize MTRRs - mostly useful on KVM. -// -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA - -#define MSR_MTRRcap 0x000000fe -#define MSR_MTRRfix64K_00000 0x00000250 -#define MSR_MTRRfix16K_80000 0x00000258 -#define MSR_MTRRfix16K_A0000 0x00000259 -#define MSR_MTRRfix4K_C0000 0x00000268 -#define MSR_MTRRfix4K_C8000 0x00000269 -#define MSR_MTRRfix4K_D0000 0x0000026a -#define MSR_MTRRfix4K_D8000 0x0000026b -#define MSR_MTRRfix4K_E0000 0x0000026c -#define MSR_MTRRfix4K_E8000 0x0000026d -#define MSR_MTRRfix4K_F0000 0x0000026e -#define MSR_MTRRfix4K_F8000 0x0000026f -#define MSR_MTRRdefType 0x000002ff - -#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) -#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) - -#define MTRR_MEMTYPE_UC 0 -#define MTRR_MEMTYPE_WC 1 -#define MTRR_MEMTYPE_WT 4 -#define MTRR_MEMTYPE_WP 5 -#define MTRR_MEMTYPE_WB 6 - -void mtrr_setup(void) -{ - if (CONFIG_COREBOOT) - return; - - u32 eax, ebx, ecx, edx, cpuid_features; - cpuid(1, &eax, &ebx, &ecx, &cpuid_features); - if (!(cpuid_features & CPUID_MTRR)) - return; - if (!(cpuid_features & CPUID_MSR)) - return; - - dprintf(3, "init mtrr\n"); - - u32 mtrr_cap = rdmsr(MSR_MTRRcap); - int vcnt = mtrr_cap & 0xff; - int fix = mtrr_cap & 0x100; - if (!vcnt || !fix) - return; - - // Disable MTRRs - wrmsr_smp(MSR_MTRRdefType, 0); - - // Set fixed MTRRs - union u64b { - u8 valb[8]; - u64 val; - } u; - u.val = 0; - int i; - for (i = 0; i < 8; i++) - if (RamSize >= 65536 * (i + 1)) - u.valb[i] = MTRR_MEMTYPE_WB; - wrmsr_smp(MSR_MTRRfix64K_00000, u.val); - u.val = 0; - for (i = 0; i < 8; i++) - if (RamSize >= 0x80000 + 16384 * (i + 1)) - u.valb[i] = MTRR_MEMTYPE_WB; - wrmsr_smp(MSR_MTRRfix16K_80000, u.val); - wrmsr_smp(MSR_MTRRfix16K_A0000, 0); // 0xA0000-0xC0000 is uncached - int j; - for (j = 0; j < 8; j++) { - u.val = 0; - for (i = 0; i < 8; i++) - if (RamSize >= 0xC0000 + j * 0x8000 + 4096 * (i + 1)) - u.valb[i] = MTRR_MEMTYPE_WP; - wrmsr_smp(MSR_MTRRfix4K_C0000 + j, u.val); - } - - // Set variable MTRRs - int phys_bits = 36; - cpuid(0x80000000u, &eax, &ebx, &ecx, &edx); - if (eax >= 0x80000008) { - /* Get physical bits from leaf 0x80000008 (if available) */ - cpuid(0x80000008u, &eax, &ebx, &ecx, &edx); - phys_bits = eax & 0xff; - } - u64 phys_mask = ((1ull << phys_bits) - 1); - for (i=0; i -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "bregs.h" // struct bregs -#include "farptr.h" // FLATPTR_TO_SEG -#include "config.h" // CONFIG_* -#include "util.h" // dprintf -#include "pci.h" // foreachpci -#include "pci_regs.h" // PCI_ROM_ADDRESS -#include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA -#include "boot.h" // IPL -#include "paravirt.h" // qemu_cfg_* - - -/**************************************************************** - * Definitions - ****************************************************************/ - -struct rom_header { - u16 signature; - u8 size; - u8 initVector[4]; - u8 reserved[17]; - u16 pcioffset; - u16 pnpoffset; -} PACKED; - -struct pci_data { - u32 signature; - u16 vendor; - u16 device; - u16 vitaldata; - u16 dlen; - u8 drevision; - u8 class_lo; - u16 class_hi; - u16 ilen; - u16 irevision; - u8 type; - u8 indicator; - u16 reserved; -} PACKED; - -struct pnp_data { - u32 signature; - u8 revision; - u8 len; - u16 nextoffset; - u8 reserved_08; - u8 checksum; - u32 devid; - u16 manufacturer; - u16 productname; - u8 type_lo; - u16 type_hi; - u8 dev_flags; - u16 bcv; - u16 dv; - u16 bev; - u16 reserved_1c; - u16 staticresource; -} PACKED; - -#define OPTION_ROM_SIGNATURE 0xaa55 -#define OPTION_ROM_ALIGN 2048 -#define OPTION_ROM_INITVECTOR offsetof(struct rom_header, initVector[0]) -#define PCI_ROM_SIGNATURE 0x52494350 // PCIR -#define PCIROM_CODETYPE_X86 0 - -// The end of the last deployed rom. -u32 RomEnd; - - -/**************************************************************** - * Helper functions - ****************************************************************/ - -// Execute a given option rom. -static void -__callrom(struct rom_header *rom, u16 offset, u16 bdf) -{ - u16 seg = FLATPTR_TO_SEG(rom); - dprintf(1, "Running option rom at %04x:%04x\n", seg, offset); - - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_IF; - br.ax = bdf; - br.bx = 0xffff; - br.dx = 0xffff; - br.es = SEG_BIOS; - br.di = get_pnp_offset(); - br.code = SEGOFF(seg, offset); - start_preempt(); - call16big(&br); - finish_preempt(); - - debug_serial_setup(); -} - -// Execute a given option rom at the standard entry vector. -static void -callrom(struct rom_header *rom, u16 bdf) -{ - __callrom(rom, OPTION_ROM_INITVECTOR, bdf); -} - -// Execute a BCV option rom registered via add_bcv(). -void -call_bcv(u16 seg, u16 ip) -{ - __callrom(MAKE_FLATPTR(seg, 0), ip, 0); -} - -// Verify that an option rom looks valid -static int -is_valid_rom(struct rom_header *rom) -{ - dprintf(6, "Checking rom %p (sig %x size %d)\n" - , rom, rom->signature, rom->size); - if (rom->signature != OPTION_ROM_SIGNATURE) - return 0; - if (! rom->size) - return 0; - u32 len = rom->size * 512; - u8 sum = checksum(rom, len); - if (sum != 0) { - dprintf(1, "Found option rom with bad checksum: loc=%p len=%d sum=%x\n" - , rom, len, sum); - return 0; - } - return 1; -} - -// Check if a valid option rom has a pnp struct; return it if so. -static struct pnp_data * -get_pnp_rom(struct rom_header *rom) -{ - struct pnp_data *pnp = (void*)((u8*)rom + rom->pnpoffset); - if (pnp->signature != PNP_SIGNATURE) - return NULL; - return pnp; -} - -// Check for multiple pnp option rom headers. -static struct pnp_data * -get_pnp_next(struct rom_header *rom, struct pnp_data *pnp) -{ - if (! pnp->nextoffset) - return NULL; - pnp = (void*)((u8*)rom + pnp->nextoffset); - if (pnp->signature != PNP_SIGNATURE) - return NULL; - return pnp; -} - -// Check if a valid option rom has a pci struct; return it if so. -static struct pci_data * -get_pci_rom(struct rom_header *rom) -{ - struct pci_data *pci = (void*)((u32)rom + rom->pcioffset); - if (pci->signature != PCI_ROM_SIGNATURE) - return NULL; - return pci; -} - -// Return the memory position up to which roms may be located. -static inline u32 -max_rom(void) -{ - extern u8 code32flat_start[]; - if ((u32)code32flat_start > BUILD_BIOS_ADDR) - return BUILD_BIOS_ADDR; - return (u32)code32flat_start; -} - -// Copy a rom to its permanent location below 1MiB -static struct rom_header * -copy_rom(struct rom_header *rom) -{ - u32 romsize = rom->size * 512; - if (RomEnd + romsize > max_rom()) { - // Option rom doesn't fit. - warn_noalloc(); - return NULL; - } - dprintf(4, "Copying option rom (size %d) from %p to %x\n" - , romsize, rom, RomEnd); - iomemcpy((void*)RomEnd, rom, romsize); - return (void*)RomEnd; -} - -// Run rom init code and note rom size. -static int -init_optionrom(struct rom_header *rom, u16 bdf, int isvga) -{ - if (! is_valid_rom(rom)) - return -1; - - if (isvga || get_pnp_rom(rom)) - // Only init vga and PnP roms here. - callrom(rom, bdf); - - RomEnd = (u32)rom + ALIGN(rom->size * 512, OPTION_ROM_ALIGN); - - return 0; -} - - -/**************************************************************** - * Roms in CBFS - ****************************************************************/ - -// Check if an option rom is at a hardcoded location or in CBFS. -static struct rom_header * -lookup_hardcode(u32 vendev) -{ - if (OPTIONROM_VENDEV_1 - && ((OPTIONROM_VENDEV_1 >> 16) - | ((OPTIONROM_VENDEV_1 & 0xffff)) << 16) == vendev) - return copy_rom((void*)OPTIONROM_MEM_1); - if (OPTIONROM_VENDEV_2 - && ((OPTIONROM_VENDEV_2 >> 16) - | ((OPTIONROM_VENDEV_2 & 0xffff)) << 16) == vendev) - return copy_rom((void*)OPTIONROM_MEM_2); - char fname[17]; - snprintf(fname, sizeof(fname), "pci%04x,%04x.rom" - , pci_vd_to_ven(vendev), pci_vd_to_dev(vendev)); - int ret = romfile_copy(romfile_find(fname), (void*)RomEnd - , max_rom() - RomEnd); - if (ret <= 0) - return NULL; - return (void*)RomEnd; -} - -// Run all roms in a given CBFS directory. -static void -run_file_roms(const char *prefix, int isvga) -{ - u32 file = 0; - for (;;) { - file = romfile_findprefix(prefix, file); - if (!file) - break; - int ret = romfile_copy(file, (void*)RomEnd, max_rom() - RomEnd); - if (ret > 0) - init_optionrom((void*)RomEnd, 0, isvga); - } -} - - -/**************************************************************** - * PCI roms - ****************************************************************/ - -// Map the option rom of a given PCI device. -static struct rom_header * -map_pcirom(u16 bdf, u32 vendev) -{ - dprintf(6, "Attempting to map option rom on dev %02x:%02x.%x\n" - , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)); - - u8 htype = pci_config_readb(bdf, PCI_HEADER_TYPE); - if ((htype & 0x7f) != PCI_HEADER_TYPE_NORMAL) { - dprintf(6, "Skipping non-normal pci device (type=%x)\n", htype); - return NULL; - } - - u32 orig = pci_config_readl(bdf, PCI_ROM_ADDRESS); - pci_config_writel(bdf, PCI_ROM_ADDRESS, ~PCI_ROM_ADDRESS_ENABLE); - u32 sz = pci_config_readl(bdf, PCI_ROM_ADDRESS); - - dprintf(6, "Option rom sizing returned %x %x\n", orig, sz); - orig &= ~PCI_ROM_ADDRESS_ENABLE; - if (!sz || sz == 0xffffffff) - goto fail; - - if (orig == sz || (u32)(orig + 4*1024*1024) < 20*1024*1024) { - // Don't try to map to a pci addresses at its max, in the last - // 4MiB of ram, or the first 16MiB of ram. - dprintf(6, "Preset rom address doesn't look valid\n"); - goto fail; - } - - // Looks like a rom - enable it. - pci_config_writel(bdf, PCI_ROM_ADDRESS, orig | PCI_ROM_ADDRESS_ENABLE); - - struct rom_header *rom = (void*)orig; - for (;;) { - dprintf(5, "Inspecting possible rom at %p (vd=%04x:%04x" - " bdf=%02x:%02x.%x)\n" - , rom, pci_vd_to_ven(vendev), pci_vd_to_dev(vendev) - , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)); - if (rom->signature != OPTION_ROM_SIGNATURE) { - dprintf(6, "No option rom signature (got %x)\n", rom->signature); - goto fail; - } - struct pci_data *pci = get_pci_rom(rom); - if (! pci) { - dprintf(6, "No valid pci signature found\n"); - goto fail; - } - - u32 vd = pci_vd(pci->vendor, pci->device); - if (vd == vendev && pci->type == PCIROM_CODETYPE_X86) - // A match - break; - dprintf(6, "Didn't match dev/ven (got %08x) or type (got %d)\n" - , vd, pci->type); - if (pci->indicator & 0x80) { - dprintf(6, "No more images left\n"); - goto fail; - } - rom = (void*)((u32)rom + pci->ilen * 512); - } - - rom = copy_rom(rom); - pci_config_writel(bdf, PCI_ROM_ADDRESS, orig); - return rom; -fail: - // Not valid - restore original and exit. - pci_config_writel(bdf, PCI_ROM_ADDRESS, orig); - return NULL; -} - -// Attempt to map and initialize the option rom on a given PCI device. -static int -init_pcirom(u16 bdf, int isvga) -{ - u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID); - dprintf(4, "Attempting to init PCI bdf %02x:%02x.%x (vd %04x:%04x)\n" - , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf) - , pci_vd_to_ven(vendev), pci_vd_to_dev(vendev)); - struct rom_header *rom = lookup_hardcode(vendev); - if (! rom) - rom = map_pcirom(bdf, vendev); - if (! rom) - // No ROM present. - return -1; - return init_optionrom(rom, bdf, isvga); -} - - -/**************************************************************** - * Non-VGA option rom init - ****************************************************************/ - -void -optionrom_setup(void) -{ - if (! CONFIG_OPTIONROMS) - return; - - dprintf(1, "Scan for option roms\n"); - - u32 post_vga = RomEnd; - - if (CONFIG_OPTIONROMS_DEPLOYED) { - // Option roms are already deployed on the system. - u32 pos = RomEnd; - while (pos < max_rom()) { - int ret = init_optionrom((void*)pos, 0, 0); - if (ret) - pos += OPTION_ROM_ALIGN; - else - pos = RomEnd; - } - } else { - // Find and deploy PCI roms. - int bdf, max; - foreachpci(bdf, max) { - u16 v = pci_config_readw(bdf, PCI_CLASS_DEVICE); - if (v == 0x0000 || v == 0xffff || v == PCI_CLASS_DISPLAY_VGA - || (CONFIG_ATA && v == PCI_CLASS_STORAGE_IDE)) - continue; - init_pcirom(bdf, 0); - } - - // Find and deploy CBFS roms not associated with a device. - run_file_roms("genroms/", 0); - } - - // All option roms found and deployed - now build BEV/BCV vectors. - - u32 pos = post_vga; - while (pos < RomEnd) { - struct rom_header *rom = (void*)pos; - if (! is_valid_rom(rom)) { - pos += OPTION_ROM_ALIGN; - continue; - } - pos += ALIGN(rom->size * 512, OPTION_ROM_ALIGN); - struct pnp_data *pnp = get_pnp_rom(rom); - if (! pnp) { - // Legacy rom. - add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0); - continue; - } - // PnP rom. - if (pnp->bev) - // Can boot system - add to IPL list. - add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname); - else - // Check for BCV (there may be multiple). - while (pnp && pnp->bcv) { - add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname); - pnp = get_pnp_next(rom, pnp); - } - } -} - - -/**************************************************************** - * VGA init - ****************************************************************/ - -// Call into vga code to turn on console. -void -vga_setup(void) -{ - VGAbdf = -1; - RomEnd = BUILD_ROM_START; - - if (! CONFIG_OPTIONROMS) - return; - - dprintf(1, "Scan for VGA option rom\n"); - - if (CONFIG_OPTIONROMS_DEPLOYED) { - // Option roms are already deployed on the system. - init_optionrom((void*)BUILD_ROM_START, 0, 1); - } else { - // Find and deploy PCI VGA rom. - int bdf = VGAbdf = pci_find_vga(); - if (bdf >= 0) - init_pcirom(bdf, 1); - - // Find and deploy CBFS vga-style roms not associated with a device. - run_file_roms("vgaroms/", 1); - } - - if (RomEnd == BUILD_ROM_START) { - // No VGA rom found - RomEnd += OPTION_ROM_ALIGN; - return; - } - - enable_vga_console(); -} - -void -s3_resume_vga_init(void) -{ - if (!CONFIG_S3_RESUME_VGA_INIT) - return; - struct rom_header *rom = (void*)BUILD_ROM_START; - if (! is_valid_rom(rom)) - return; - callrom(rom, 0); -} diff --git a/roms/seabios/src/output.c b/roms/seabios/src/output.c deleted file mode 100644 index 936d3d8..0000000 --- a/roms/seabios/src/output.c +++ /dev/null @@ -1,556 +0,0 @@ -// Raw screen writing and debug output code. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include // va_list - -#include "farptr.h" // GET_VAR -#include "util.h" // printf -#include "bregs.h" // struct bregs -#include "config.h" // CONFIG_* -#include "biosvar.h" // GET_GLOBAL - -struct putcinfo { - void (*func)(struct putcinfo *info, char c); -}; - - -/**************************************************************** - * Debug output - ****************************************************************/ - -#define DEBUG_PORT PORT_SERIAL1 -#define DEBUG_TIMEOUT 100000 - -void -debug_serial_setup(void) -{ - if (!CONFIG_DEBUG_SERIAL) - return; - // setup for serial logging: 8N1 - u8 oldparam, newparam = 0x03; - oldparam = inb(DEBUG_PORT+SEROFF_LCR); - outb(newparam, DEBUG_PORT+SEROFF_LCR); - // Disable irqs - u8 oldier, newier = 0; - oldier = inb(DEBUG_PORT+SEROFF_IER); - outb(newier, DEBUG_PORT+SEROFF_IER); - - if (oldparam != newparam || oldier != newier) - dprintf(1, "Changing serial settings was %x/%x now %x/%x\n" - , oldparam, oldier, newparam, newier); -} - -// Write a character to the serial port. -static void -debug_serial(char c) -{ - if (!CONFIG_DEBUG_SERIAL) - return; - int timeout = DEBUG_TIMEOUT; - while ((inb(DEBUG_PORT+SEROFF_LSR) & 0x60) != 0x60) - if (!timeout--) - // Ran out of time. - return; - outb(c, DEBUG_PORT+SEROFF_DATA); -} - -// Make sure all serial port writes have been completely sent. -static void -debug_serial_flush(void) -{ - if (!CONFIG_DEBUG_SERIAL) - return; - int timeout = DEBUG_TIMEOUT; - while ((inb(DEBUG_PORT+SEROFF_LSR) & 0x40) != 0x40) - if (!timeout--) - // Ran out of time. - return; -} - -// Write a character to debug port(s). -static void -putc_debug(struct putcinfo *action, char c) -{ - if (! CONFIG_DEBUG_LEVEL) - return; - if (! CONFIG_COREBOOT) - // Send character to debug port. - outb(c, PORT_BIOS_DEBUG); - if (c == '\n') - debug_serial('\r'); - debug_serial(c); -} - -// In segmented mode just need a dummy variable (putc_debug is always -// used anyway), and in 32bit flat mode need a pointer to the 32bit -// instance of putc_debug(). -#if MODE16 -static struct putcinfo debuginfo VAR16; -#elif MODESEGMENT -static struct putcinfo debuginfo VAR32SEG; -#else -static struct putcinfo debuginfo = { putc_debug }; -#endif - - -/**************************************************************** - * Screen writing - ****************************************************************/ - -// Show a character on the screen. -static void -screenc(char c) -{ - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_IF; - br.ah = 0x0e; - br.al = c; - call16_int(0x10, &br); -} - -// Handle a character from a printf request. -static void -putc_screen(struct putcinfo *action, char c) -{ - if (CONFIG_SCREEN_AND_DEBUG) - putc_debug(&debuginfo, c); - if (c == '\n') - screenc('\r'); - screenc(c); -} - -static struct putcinfo screeninfo = { putc_screen }; - - -/**************************************************************** - * Xprintf code - ****************************************************************/ - -// Output a character. -static void -putc(struct putcinfo *action, char c) -{ - if (MODESEGMENT) { - // Only debugging output supported in segmented mode. - putc_debug(action, c); - return; - } - - void (*func)(struct putcinfo *info, char c) = GET_GLOBAL(action->func); - func(action, c); -} - -// Ouptut a string. -static void -puts(struct putcinfo *action, const char *s) -{ - for (; *s; s++) - putc(action, *s); -} - -// Output a string that is in the CS segment. -static void -puts_cs(struct putcinfo *action, const char *s) -{ - char *vs = (char*)s; - for (;; vs++) { - char c = GET_GLOBAL(*vs); - if (!c) - break; - putc(action, c); - } -} - -// Output an unsigned integer. -static void -putuint(struct putcinfo *action, u32 val) -{ - char buf[12]; - char *d = &buf[sizeof(buf) - 1]; - *d-- = '\0'; - for (;;) { - *d = (val % 10) + '0'; - val /= 10; - if (!val) - break; - d--; - } - puts(action, d); -} - -// Output a single digit hex character. -static inline void -putsinglehex(struct putcinfo *action, u32 val) -{ - if (val <= 9) - val = '0' + val; - else - val = 'a' + val - 10; - putc(action, val); -} - -// Output an integer in hexadecimal. -static void -puthex(struct putcinfo *action, u32 val, int width, int spacepad) -{ - if (!width) { - u32 tmp = val; - width = 1; - while (tmp >>= 4) - width++; - } else if (spacepad) { - u32 tmp = val; - u32 count = 1; - while (tmp >>= 4) - count++; - if (width > count) { - count = width - count; - width -= count; - while (count--) - putc(action, ' '); - } - } - - switch (width) { - default: putsinglehex(action, (val >> 28) & 0xf); - case 7: putsinglehex(action, (val >> 24) & 0xf); - case 6: putsinglehex(action, (val >> 20) & 0xf); - case 5: putsinglehex(action, (val >> 16) & 0xf); - case 4: putsinglehex(action, (val >> 12) & 0xf); - case 3: putsinglehex(action, (val >> 8) & 0xf); - case 2: putsinglehex(action, (val >> 4) & 0xf); - case 1: putsinglehex(action, (val >> 0) & 0xf); - } -} - -static inline int -isdigit(u8 c) -{ - return ((u8)(c - '0')) < 10; -} - -static void -bvprintf(struct putcinfo *action, const char *fmt, va_list args) -{ - const char *s = fmt; - for (;; s++) { - char c = GET_GLOBAL(*(u8*)s); - if (!c) - break; - if (c != '%') { - putc(action, c); - continue; - } - const char *n = s+1; - int field_width = 0; - int spacepad = 1; - for (;;) { - c = GET_GLOBAL(*(u8*)n); - if (!isdigit(c)) - break; - if (!field_width && (c == '0')) - spacepad = 0; - else - field_width = field_width * 10 + c - '0'; - n++; - } - if (c == 'l') { - // Ignore long format indicator - n++; - c = GET_GLOBAL(*(u8*)n); - } - s32 val; - const char *sarg; - switch (c) { - case '%': - putc(action, '%'); - break; - case 'd': - val = va_arg(args, s32); - if (val < 0) { - putc(action, '-'); - val = -val; - } - putuint(action, val); - break; - case 'u': - val = va_arg(args, s32); - putuint(action, val); - break; - case 'p': - /* %p always has 0x prepended */ - putc(action, '0'); - putc(action, 'x'); - field_width = 8; - spacepad = 0; - case 'x': - val = va_arg(args, s32); - puthex(action, val, field_width, spacepad); - break; - case 'c': - val = va_arg(args, int); - putc(action, val); - break; - case '.': - // Hack to support "%.s" - meaning string on stack. - if (GET_GLOBAL(*(u8*)(n+1)) != 's') - break; - n++; - sarg = va_arg(args, const char *); - puts(action, sarg); - break; - case 's': - sarg = va_arg(args, const char *); - puts_cs(action, sarg); - break; - default: - putc(action, '%'); - n = s; - } - s = n; - } -} - -void -panic(const char *fmt, ...) -{ - if (CONFIG_DEBUG_LEVEL) { - va_list args; - va_start(args, fmt); - bvprintf(&debuginfo, fmt, args); - va_end(args); - debug_serial_flush(); - } - - // XXX - use PANIC PORT. - irq_disable(); - for (;;) - hlt(); -} - -void -__dprintf(const char *fmt, ...) -{ - if (!MODESEGMENT && CONFIG_THREADS && CONFIG_DEBUG_LEVEL >= DEBUG_thread - && *fmt != '\\' && *fmt != '/') { - struct thread_info *cur = getCurThread(); - if (cur != &MainThread) { - // Show "thread id" for this debug message. - putc_debug(&debuginfo, '|'); - puthex(&debuginfo, (u32)cur, 8, 0); - putc_debug(&debuginfo, '|'); - putc_debug(&debuginfo, ' '); - } - } - - va_list args; - va_start(args, fmt); - bvprintf(&debuginfo, fmt, args); - va_end(args); - debug_serial_flush(); -} - -void -printf(const char *fmt, ...) -{ - ASSERT32FLAT(); - va_list args; - va_start(args, fmt); - bvprintf(&screeninfo, fmt, args); - va_end(args); - if (CONFIG_SCREEN_AND_DEBUG) - debug_serial_flush(); -} - - -/**************************************************************** - * snprintf - ****************************************************************/ - -struct snprintfinfo { - struct putcinfo info; - char *str, *end; -}; - -static void -putc_str(struct putcinfo *info, char c) -{ - struct snprintfinfo *sinfo = container_of(info, struct snprintfinfo, info); - if (sinfo->str >= sinfo->end) - return; - *sinfo->str = c; - sinfo->str++; -} - -// Build a formatted string. Note, this function returns the actual -// number of bytes used (not including null) even in the overflow -// case. -int -snprintf(char *str, size_t size, const char *fmt, ...) -{ - ASSERT32FLAT(); - if (!size) - return 0; - struct snprintfinfo sinfo = { { putc_str }, str, str + size }; - va_list args; - va_start(args, fmt); - bvprintf(&sinfo.info, fmt, args); - va_end(args); - char *end = sinfo.str; - if (end >= sinfo.end) - end = sinfo.end - 1; - *end = '\0'; - return end - str; -} - - -/**************************************************************** - * Misc helpers - ****************************************************************/ - -void -hexdump(const void *d, int len) -{ - int count=0; - while (len > 0) { - if (count % 8 == 0) { - putc(&debuginfo, '\n'); - puthex(&debuginfo, count*4, 8, 0); - putc(&debuginfo, ':'); - } else { - putc(&debuginfo, ' '); - } - puthex(&debuginfo, *(u32*)d, 8, 0); - count++; - len-=4; - d+=4; - } - putc(&debuginfo, '\n'); - debug_serial_flush(); -} - -static void -dump_regs(struct bregs *regs) -{ - if (!regs) { - dprintf(1, " NULL\n"); - return; - } - dprintf(1, " a=%08x b=%08x c=%08x d=%08x ds=%04x es=%04x ss=%04x\n" - , regs->eax, regs->ebx, regs->ecx, regs->edx - , regs->ds, regs->es, GET_SEG(SS)); - dprintf(1, " si=%08x di=%08x bp=%08x sp=%08x cs=%04x ip=%04x f=%04x\n" - , regs->esi, regs->edi, regs->ebp, (u32)®s[1] - , regs->code.seg, regs->code.offset, regs->flags); -} - -// Report entry to an Interrupt Service Routine (ISR). -void -__debug_isr(const char *fname) -{ - puts_cs(&debuginfo, fname); - putc(&debuginfo, '\n'); - debug_serial_flush(); -} - -// Function called on handler startup. -void -__debug_enter(struct bregs *regs, const char *fname) -{ - dprintf(1, "enter %s:\n", fname); - dump_regs(regs); -} - -// Send debugging output info. -void -__debug_stub(struct bregs *regs, int lineno, const char *fname) -{ - dprintf(1, "stub %s:%d:\n", fname, lineno); - dump_regs(regs); -} - -// Report on an invalid parameter. -void -__warn_invalid(struct bregs *regs, int lineno, const char *fname) -{ - if (CONFIG_DEBUG_LEVEL >= DEBUG_invalid) { - dprintf(1, "invalid %s:%d:\n", fname, lineno); - dump_regs(regs); - } -} - -// Report on an unimplemented feature. -void -__warn_unimplemented(struct bregs *regs, int lineno, const char *fname) -{ - if (CONFIG_DEBUG_LEVEL >= DEBUG_unimplemented) { - dprintf(1, "unimplemented %s:%d:\n", fname, lineno); - dump_regs(regs); - } -} - -// Report a detected internal inconsistency. -void -__warn_internalerror(int lineno, const char *fname) -{ - dprintf(1, "WARNING - internal error detected at %s:%d!\n" - , fname, lineno); -} - -// Report on an allocation failure. -void -__warn_noalloc(int lineno, const char *fname) -{ - dprintf(1, "WARNING - Unable to allocate resource at %s:%d!\n" - , fname, lineno); -} - -// Report on a timeout exceeded. -void -__warn_timeout(int lineno, const char *fname) -{ - dprintf(1, "WARNING - Timeout at %s:%d!\n", fname, lineno); -} - -// Report a handler reporting an invalid parameter to the caller. -void -__set_invalid(struct bregs *regs, int lineno, const char *fname) -{ - __warn_invalid(regs, lineno, fname); - set_invalid_silent(regs); -} - -// Report a call of an unimplemented function. -void -__set_unimplemented(struct bregs *regs, int lineno, const char *fname) -{ - __warn_unimplemented(regs, lineno, fname); - set_invalid_silent(regs); -} - -// Report a handler reporting an invalid parameter code to the -// caller. Note, the lineno and return code are encoded in the same -// parameter as gcc does a better job of scheduling function calls -// when there are 3 or less parameters. -void -__set_code_invalid(struct bregs *regs, u32 linecode, const char *fname) -{ - u8 code = linecode; - u32 lineno = linecode >> 8; - __warn_invalid(regs, lineno, fname); - set_code_invalid_silent(regs, code); -} - -// Report a call of an unimplemented function. -void -__set_code_unimplemented(struct bregs *regs, u32 linecode, const char *fname) -{ - u8 code = linecode; - u32 lineno = linecode >> 8; - __warn_unimplemented(regs, lineno, fname); - set_code_invalid_silent(regs, code); -} diff --git a/roms/seabios/src/paravirt.c b/roms/seabios/src/paravirt.c deleted file mode 100644 index ca646d4..0000000 --- a/roms/seabios/src/paravirt.c +++ /dev/null @@ -1,359 +0,0 @@ -// Paravirtualization support. -// -// Copyright (C) 2009 Red Hat Inc. -// -// Authors: -// Gleb Natapov -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "config.h" // CONFIG_COREBOOT -#include "util.h" // ntoh[ls] -#include "ioport.h" // outw -#include "paravirt.h" // qemu_cfg_port_probe -#include "smbios.h" // struct smbios_structure_header - -int qemu_cfg_present; - -static void -qemu_cfg_select(u16 f) -{ - outw(f, PORT_QEMU_CFG_CTL); -} - -static void -qemu_cfg_read(u8 *buf, int len) -{ - insb(PORT_QEMU_CFG_DATA, buf, len); -} - -static void -qemu_cfg_skip(int len) -{ - while (len--) - inb(PORT_QEMU_CFG_DATA); -} - -static void -qemu_cfg_read_entry(void *buf, int e, int len) -{ - qemu_cfg_select(e); - qemu_cfg_read(buf, len); -} - -void qemu_cfg_port_probe(void) -{ - char *sig = "QEMU"; - int i; - - if (CONFIG_COREBOOT) - return; - - qemu_cfg_present = 1; - - qemu_cfg_select(QEMU_CFG_SIGNATURE); - - for (i = 0; i < 4; i++) - if (inb(PORT_QEMU_CFG_DATA) != sig[i]) { - qemu_cfg_present = 0; - break; - } - dprintf(4, "qemu_cfg_present=%d\n", qemu_cfg_present); -} - -void qemu_cfg_get_uuid(u8 *uuid) -{ - if (!qemu_cfg_present) - return; - - qemu_cfg_read_entry(uuid, QEMU_CFG_UUID, 16); -} - -int qemu_cfg_show_boot_menu(void) -{ - u16 v; - if (!qemu_cfg_present) - return 1; - - qemu_cfg_read_entry(&v, QEMU_CFG_BOOT_MENU, sizeof(v)); - - return v; -} - -int qemu_cfg_irq0_override(void) -{ - u8 v; - - if (!qemu_cfg_present) - return 0; - - qemu_cfg_read_entry(&v, QEMU_CFG_IRQ0_OVERRIDE, sizeof(v)); - - return v; -} - -u16 qemu_cfg_acpi_additional_tables(void) -{ - u16 cnt; - - if (!qemu_cfg_present) - return 0; - - qemu_cfg_read_entry(&cnt, QEMU_CFG_ACPI_TABLES, sizeof(cnt)); - - return cnt; -} - -u16 qemu_cfg_next_acpi_table_len(void) -{ - u16 len; - - qemu_cfg_read((u8*)&len, sizeof(len)); - - return len; -} - -void* qemu_cfg_next_acpi_table_load(void *addr, u16 len) -{ - qemu_cfg_read(addr, len); - return addr; -} - -u16 qemu_cfg_smbios_entries(void) -{ - u16 cnt; - - if (!qemu_cfg_present) - return 0; - - qemu_cfg_read_entry(&cnt, QEMU_CFG_SMBIOS_ENTRIES, sizeof(cnt)); - - return cnt; -} - -u32 qemu_cfg_e820_entries(void) -{ - u32 cnt; - - if (!qemu_cfg_present) - return 0; - - qemu_cfg_read_entry(&cnt, QEMU_CFG_E820_TABLE, sizeof(cnt)); - return cnt; -} - -void* qemu_cfg_e820_load_next(void *addr) -{ - qemu_cfg_read(addr, sizeof(struct e820_reservation)); - return addr; -} - -struct smbios_header { - u16 length; - u8 type; -} PACKED; - -struct smbios_field { - struct smbios_header header; - u8 type; - u16 offset; - u8 data[]; -} PACKED; - -struct smbios_table { - struct smbios_header header; - u8 data[]; -} PACKED; - -#define SMBIOS_FIELD_ENTRY 0 -#define SMBIOS_TABLE_ENTRY 1 - -size_t qemu_cfg_smbios_load_field(int type, size_t offset, void *addr) -{ - int i; - - for (i = qemu_cfg_smbios_entries(); i > 0; i--) { - struct smbios_field field; - - qemu_cfg_read((u8 *)&field, sizeof(struct smbios_header)); - field.header.length -= sizeof(struct smbios_header); - - if (field.header.type != SMBIOS_FIELD_ENTRY) { - qemu_cfg_skip(field.header.length); - continue; - } - - qemu_cfg_read((u8 *)&field.type, - sizeof(field) - sizeof(struct smbios_header)); - field.header.length -= sizeof(field) - sizeof(struct smbios_header); - - if (field.type != type || field.offset != offset) { - qemu_cfg_skip(field.header.length); - continue; - } - - qemu_cfg_read(addr, field.header.length); - return (size_t)field.header.length; - } - return 0; -} - -int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs, - unsigned *max_struct_size, char *end) -{ - static u64 used_bitmap[4] = { 0 }; - char *start = *p; - int i; - - /* Check if we've already reported these tables */ - if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f))) - return 1; - - /* Don't introduce spurious end markers */ - if (type == 127) - return 0; - - for (i = qemu_cfg_smbios_entries(); i > 0; i--) { - struct smbios_table table; - struct smbios_structure_header *header = (void *)*p; - int string; - - qemu_cfg_read((u8 *)&table, sizeof(struct smbios_header)); - table.header.length -= sizeof(struct smbios_header); - - if (table.header.type != SMBIOS_TABLE_ENTRY) { - qemu_cfg_skip(table.header.length); - continue; - } - - if (end - *p < sizeof(struct smbios_structure_header)) { - warn_noalloc(); - break; - } - - qemu_cfg_read((u8 *)*p, sizeof(struct smbios_structure_header)); - table.header.length -= sizeof(struct smbios_structure_header); - - if (header->type != type) { - qemu_cfg_skip(table.header.length); - continue; - } - - *p += sizeof(struct smbios_structure_header); - - /* Entries end with a double NULL char, if there's a string at - * the end (length is greater than formatted length), the string - * terminator provides the first NULL. */ - string = header->length < table.header.length + - sizeof(struct smbios_structure_header); - - /* Read the rest and terminate the entry */ - if (end - *p < table.header.length) { - warn_noalloc(); - *p -= sizeof(struct smbios_structure_header); - continue; - } - qemu_cfg_read((u8 *)*p, table.header.length); - *p += table.header.length; - *((u8*)*p) = 0; - (*p)++; - if (!string) { - *((u8*)*p) = 0; - (*p)++; - } - - (*nr_structs)++; - if (*p - (char *)header > *max_struct_size) - *max_struct_size = *p - (char *)header; - } - - if (start != *p) { - /* Mark that we've reported on this type */ - used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f)); - return 1; - } - - return 0; -} - -int qemu_cfg_get_numa_nodes(void) -{ - u64 cnt; - - qemu_cfg_read_entry(&cnt, QEMU_CFG_NUMA, sizeof(cnt)); - - return (int)cnt; -} - -void qemu_cfg_get_numa_data(u64 *data, int n) -{ - int i; - - for (i = 0; i < n; i++) - qemu_cfg_read((u8*)(data + i), sizeof(u64)); -} - -u16 qemu_cfg_get_max_cpus(void) -{ - u16 cnt; - - if (!qemu_cfg_present) - return 0; - - qemu_cfg_read_entry(&cnt, QEMU_CFG_MAX_CPUS, sizeof(cnt)); - - return cnt; -} - -static QemuCfgFile LastFile; - -static u32 -__cfg_next_prefix_file(const char *prefix, int prefixlen, u32 prevselect) -{ - if (!qemu_cfg_present) - return 0; - - u32 count; - qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count)); - count = ntohl(count); - u32 e; - for (e = 0; e < count; e++) { - qemu_cfg_read((void*)&LastFile, sizeof(LastFile)); - u32 select = ntohs(LastFile.select); - if (select <= prevselect) - continue; - if (memcmp(prefix, LastFile.name, prefixlen) == 0) - return select; - } - return 0; -} - -u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect) -{ - return __cfg_next_prefix_file(prefix, strlen(prefix), prevselect); -} - -u32 qemu_cfg_find_file(const char *name) -{ - return __cfg_next_prefix_file(name, strlen(name) + 1, 0); -} - -int qemu_cfg_size_file(u32 select) -{ - if (select != ntohs(LastFile.select)) - return -1; - return ntohl(LastFile.size); -} - -int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen) -{ - if (!qemu_cfg_present) - return -1; - if (!select || select != ntohs(LastFile.select)) - return -1; - int len = qemu_cfg_size_file(select); - if (len < 0 || len > maxlen) - return -1; - qemu_cfg_read_entry(dst, select, len); - return len; -} diff --git a/roms/seabios/src/paravirt.h b/roms/seabios/src/paravirt.h deleted file mode 100644 index 7d4bc02..0000000 --- a/roms/seabios/src/paravirt.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef __PV_H -#define __PV_H - -#include "util.h" - -/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It - * should be used to determine that a VM is running under KVM. - */ -#define KVM_CPUID_SIGNATURE 0x40000000 - -static inline int kvm_para_available(void) -{ - unsigned int eax, ebx, ecx, edx; - char signature[13]; - - cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); - memcpy(signature + 0, &ebx, 4); - memcpy(signature + 4, &ecx, 4); - memcpy(signature + 8, &edx, 4); - signature[12] = 0; - - if (strcmp(signature, "KVMKVMKVM") == 0) - return 1; - - return 0; -} - -#define QEMU_CFG_SIGNATURE 0x00 -#define QEMU_CFG_ID 0x01 -#define QEMU_CFG_UUID 0x02 -#define QEMU_CFG_NUMA 0x0d -#define QEMU_CFG_BOOT_MENU 0x0e -#define QEMU_CFG_MAX_CPUS 0x0f -#define QEMU_CFG_FILE_DIR 0x19 -#define QEMU_CFG_ARCH_LOCAL 0x8000 -#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0) -#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1) -#define QEMU_CFG_IRQ0_OVERRIDE (QEMU_CFG_ARCH_LOCAL + 2) -#define QEMU_CFG_E820_TABLE (QEMU_CFG_ARCH_LOCAL + 3) - -extern int qemu_cfg_present; - -void qemu_cfg_port_probe(void); -int qemu_cfg_show_boot_menu(void); -void qemu_cfg_get_uuid(u8 *uuid); -int qemu_cfg_irq0_override(void); -u16 qemu_cfg_acpi_additional_tables(void); -u16 qemu_cfg_next_acpi_table_len(void); -void *qemu_cfg_next_acpi_table_load(void *addr, u16 len); -u16 qemu_cfg_smbios_entries(void); -size_t qemu_cfg_smbios_load_field(int type, size_t offset, void *addr); -int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs, - unsigned *max_struct_size, char *end); -int qemu_cfg_get_numa_nodes(void); -void qemu_cfg_get_numa_data(u64 *data, int n); -u16 qemu_cfg_get_max_cpus(void); - -typedef struct QemuCfgFile { - u32 size; /* file size */ - u16 select; /* write this to 0x510 to read it */ - u16 reserved; - char name[56]; -} QemuCfgFile; - -struct e820_reservation { - u64 address; - u64 length; - u32 type; -}; - -u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect); -u32 qemu_cfg_find_file(const char *name); -int qemu_cfg_size_file(u32 select); -int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen); - -// Wrappers that select cbfs or qemu_cfg file interface. -static inline u32 romfile_findprefix(const char *prefix, u32 previd) { - if (CONFIG_COREBOOT) - return (u32)cbfs_findprefix(prefix, (void*)previd); - return qemu_cfg_next_prefix_file(prefix, previd); -} -static inline u32 romfile_find(const char *name) { - if (CONFIG_COREBOOT) - return (u32)cbfs_finddatafile(name); - return qemu_cfg_find_file(name); -} -static inline u32 romfile_size(u32 fileid) { - if (CONFIG_COREBOOT) - return cbfs_datasize((void*)fileid); - return qemu_cfg_size_file(fileid); -} -static inline int romfile_copy(u32 fileid, void *dst, u32 maxlen) { - if (CONFIG_COREBOOT) - return cbfs_copyfile((void*)fileid, dst, maxlen); - return qemu_cfg_read_file(fileid, dst, maxlen); -} - -u32 qemu_cfg_e820_entries(void); -void* qemu_cfg_e820_load_next(void *addr); - -#endif diff --git a/roms/seabios/src/pci.c b/roms/seabios/src/pci.c deleted file mode 100644 index 611d0e2..0000000 --- a/roms/seabios/src/pci.c +++ /dev/null @@ -1,217 +0,0 @@ -// PCI config space access functions. -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "pci.h" // pci_config_writel -#include "ioport.h" // outl -#include "util.h" // dprintf -#include "config.h" // CONFIG_* -#include "pci_regs.h" // PCI_VENDOR_ID -#include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA - -void pci_config_writel(u16 bdf, u32 addr, u32 val) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outl(val, PORT_PCI_DATA); -} - -void pci_config_writew(u16 bdf, u32 addr, u16 val) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outw(val, PORT_PCI_DATA + (addr & 2)); -} - -void pci_config_writeb(u16 bdf, u32 addr, u8 val) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - outb(val, PORT_PCI_DATA + (addr & 3)); -} - -u32 pci_config_readl(u16 bdf, u32 addr) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inl(PORT_PCI_DATA); -} - -u16 pci_config_readw(u16 bdf, u32 addr) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inw(PORT_PCI_DATA + (addr & 2)); -} - -u8 pci_config_readb(u16 bdf, u32 addr) -{ - outl(0x80000000 | (bdf << 8) | (addr & 0xfc), PORT_PCI_CMD); - return inb(PORT_PCI_DATA + (addr & 3)); -} - -void -pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on) -{ - u16 val = pci_config_readw(bdf, addr); - val = (val & ~off) | on; - pci_config_writew(bdf, addr, val); -} - -// Helper function for foreachpci() macro - return next device -int -pci_next(int bdf, int *pmax) -{ - if (pci_bdf_to_fn(bdf) == 1 - && (pci_config_readb(bdf-1, PCI_HEADER_TYPE) & 0x80) == 0) - // Last found device wasn't a multi-function device - skip to - // the next device. - bdf += 7; - - int max = *pmax; - for (;;) { - if (bdf >= max) { - if (CONFIG_PCI_ROOT1 && bdf <= (CONFIG_PCI_ROOT1 << 8)) - bdf = CONFIG_PCI_ROOT1 << 8; - else if (CONFIG_PCI_ROOT2 && bdf <= (CONFIG_PCI_ROOT2 << 8)) - bdf = CONFIG_PCI_ROOT2 << 8; - else - return -1; - *pmax = max = bdf + 0x0100; - } - - u16 v = pci_config_readw(bdf, PCI_VENDOR_ID); - if (v != 0x0000 && v != 0xffff) - // Device is present. - break; - - if (pci_bdf_to_fn(bdf) == 0) - bdf += 8; - else - bdf += 1; - } - - // Check if found device is a bridge. - u32 v = pci_config_readb(bdf, PCI_HEADER_TYPE); - v &= 0x7f; - if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) { - v = pci_config_readl(bdf, PCI_PRIMARY_BUS); - int newmax = (v & 0xff00) + 0x0100; - if (newmax > max) - *pmax = newmax; - } - - return bdf; -} - -// Find a vga device with legacy address decoding enabled. -int -pci_find_vga(void) -{ - int bdf = 0x0000, max = 0x0100; - for (;;) { - if (bdf >= max) { - if (CONFIG_PCI_ROOT1 && bdf <= (CONFIG_PCI_ROOT1 << 8)) - bdf = CONFIG_PCI_ROOT1 << 8; - else if (CONFIG_PCI_ROOT2 && bdf <= (CONFIG_PCI_ROOT2 << 8)) - bdf = CONFIG_PCI_ROOT2 << 8; - else - return -1; - max = bdf + 0x0100; - } - - u16 cls = pci_config_readw(bdf, PCI_CLASS_DEVICE); - if (cls == 0x0000 || cls == 0xffff) { - // Device not present. - if (pci_bdf_to_fn(bdf) == 0) - bdf += 8; - else - bdf += 1; - continue; - } - if (cls == PCI_CLASS_DISPLAY_VGA) { - u16 cmd = pci_config_readw(bdf, PCI_COMMAND); - if (cmd & PCI_COMMAND_IO && cmd & PCI_COMMAND_MEMORY) - // Found active vga card - return bdf; - } - - // Check if device is a bridge. - u8 hdr = pci_config_readb(bdf, PCI_HEADER_TYPE); - u8 ht = hdr & 0x7f; - if (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS) { - u32 ctrl = pci_config_readb(bdf, PCI_BRIDGE_CONTROL); - if (ctrl & PCI_BRIDGE_CTL_VGA) { - // Found a VGA enabled bridge. - u32 pbus = pci_config_readl(bdf, PCI_PRIMARY_BUS); - bdf = (pbus & 0xff00); - max = bdf + 0x100; - continue; - } - } - - if (pci_bdf_to_fn(bdf) == 0 && (hdr & 0x80) == 0) - // Last found device wasn't a multi-function device - skip to - // the next device. - bdf += 8; - else - bdf += 1; - } -} - -// Search for a device with the specified vendor and device ids. -int -pci_find_device(u16 vendid, u16 devid) -{ - u32 id = (devid << 16) | vendid; - int bdf, max; - foreachpci(bdf, max) { - u32 v = pci_config_readl(bdf, PCI_VENDOR_ID); - if (v == id) - return bdf; - } - return -1; -} - -// Search for a device with the specified class id. -int -pci_find_class(u16 classid) -{ - int bdf, max; - foreachpci(bdf, max) { - u16 v = pci_config_readw(bdf, PCI_CLASS_DEVICE); - if (v == classid) - return bdf; - } - return -1; -} - -int pci_init_device(const struct pci_device_id *ids, u16 bdf, void *arg) -{ - u16 vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID); - u16 device_id = pci_config_readw(bdf, PCI_DEVICE_ID); - u16 class = pci_config_readw(bdf, PCI_CLASS_DEVICE); - - while (ids->vendid || ids->class_mask) { - if ((ids->vendid == PCI_ANY_ID || ids->vendid == vendor_id) && - (ids->devid == PCI_ANY_ID || ids->devid == device_id) && - !((ids->class ^ class) & ids->class_mask)) { - if (ids->func) { - ids->func(bdf, arg); - } - return 0; - } - ids++; - } - return -1; -} - -int pci_find_init_device(const struct pci_device_id *ids, void *arg) -{ - int bdf, max; - - foreachpci(bdf, max) { - if (pci_init_device(ids, bdf, arg) == 0) { - return bdf; - } - } - return -1; -} diff --git a/roms/seabios/src/pci.h b/roms/seabios/src/pci.h deleted file mode 100644 index 9c3108c..0000000 --- a/roms/seabios/src/pci.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef __PCI_H -#define __PCI_H - -#include "types.h" // u32 - -static inline u8 pci_bdf_to_bus(u16 bdf) { - return bdf >> 8; -} -static inline u8 pci_bdf_to_devfn(u16 bdf) { - return bdf & 0xff; -} -static inline u16 pci_bdf_to_busdev(u16 bdf) { - return bdf & ~0x07; -} -static inline u8 pci_bdf_to_dev(u16 bdf) { - return (bdf >> 3) & 0x1f; -} -static inline u8 pci_bdf_to_fn(u16 bdf) { - return bdf & 0x07; -} -static inline u16 pci_to_bdf(int bus, int dev, int fn) { - return (bus<<8) | (dev<<3) | fn; -} -static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devfn) { - return (bus << 8) | devfn; -} - -static inline u32 pci_vd(u16 vendor, u16 device) { - return (device << 16) | vendor; -} -static inline u16 pci_vd_to_ven(u32 vd) { - return vd & 0xffff; -} -static inline u16 pci_vd_to_dev(u32 vd) { - return vd >> 16; -} - -void pci_config_writel(u16 bdf, u32 addr, u32 val); -void pci_config_writew(u16 bdf, u32 addr, u16 val); -void pci_config_writeb(u16 bdf, u32 addr, u8 val); -u32 pci_config_readl(u16 bdf, u32 addr); -u16 pci_config_readw(u16 bdf, u32 addr); -u8 pci_config_readb(u16 bdf, u32 addr); -void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on); - -int pci_find_vga(void); -int pci_find_device(u16 vendid, u16 devid); -int pci_find_class(u16 classid); - -int pci_next(int bdf, int *pmax); -#define foreachpci(BDF, MAX) \ - for (MAX=0x0100, BDF=pci_next(0, &MAX) \ - ; BDF >= 0 \ - ; BDF=pci_next(BDF+1, &MAX)) - -#define foreachpci_in_bus(BDF, MAX, BUS) \ - for (MAX = pci_bus_devfn_to_bdf(BUS, 0) + 0x0100, \ - BDF = pci_next(pci_bus_devfn_to_bdf(BUS, 0), &MAX) \ - ; BDF >= 0 && BDF < pci_bus_devfn_to_bdf(BUS, 0) + 0x0100 \ - ; MAX = pci_bus_devfn_to_bdf(BUS, 0) + 0x0100, \ - BDF = pci_next(BDF + 1, &MAX)) - -#define PCI_ANY_ID (~0) -struct pci_device_id { - u32 vendid; - u32 devid; - u32 class; - u32 class_mask; - void (*func)(u16 bdf, void *arg); -}; - -#define PCI_DEVICE(vendor_id, device_id, init_func) \ - { \ - .vendid = (vendor_id), \ - .devid = (device_id), \ - .class = PCI_ANY_ID, \ - .class_mask = 0, \ - .func = (init_func) \ - } - -#define PCI_DEVICE_CLASS(vendor_id, device_id, class_code, init_func) \ - { \ - .vendid = (vendor_id), \ - .devid = (device_id), \ - .class = (class_code), \ - .class_mask = ~0, \ - .func = (init_func) \ - } - -#define PCI_DEVICE_END \ - { \ - .vendid = 0, \ - } - -int pci_init_device(const struct pci_device_id *table, u16 bdf, void *arg); -int pci_find_init_device(const struct pci_device_id *ids, void *arg); - -// pirtable.c -void create_pirtable(void); - - -/**************************************************************** - * PIR table - ****************************************************************/ - -extern u16 PirOffset; - -struct link_info { - u8 link; - u16 bitmap; -} PACKED; - -struct pir_slot { - u8 bus; - u8 dev; - struct link_info links[4]; - u8 slot_nr; - u8 reserved; -} PACKED; - -struct pir_header { - u32 signature; - u16 version; - u16 size; - u8 router_bus; - u8 router_devfunc; - u16 exclusive_irqs; - u32 compatible_devid; - u32 miniport_data; - u8 reserved[11]; - u8 checksum; - struct pir_slot slots[0]; -} PACKED; - -#define PIR_SIGNATURE 0x52495024 // $PIR - - -#endif diff --git a/roms/seabios/src/pci_ids.h b/roms/seabios/src/pci_ids.h deleted file mode 100644 index e1cded2..0000000 --- a/roms/seabios/src/pci_ids.h +++ /dev/null @@ -1,2610 +0,0 @@ -/* - * PCI Class, Vendor and Device IDs - * - * Please keep sorted. - */ - -/* Device classes and subclasses */ - -#define PCI_CLASS_NOT_DEFINED 0x0000 -#define PCI_CLASS_NOT_DEFINED_VGA 0x0001 - -#define PCI_BASE_CLASS_STORAGE 0x01 -#define PCI_CLASS_STORAGE_SCSI 0x0100 -#define PCI_CLASS_STORAGE_IDE 0x0101 -#define PCI_CLASS_STORAGE_FLOPPY 0x0102 -#define PCI_CLASS_STORAGE_IPI 0x0103 -#define PCI_CLASS_STORAGE_RAID 0x0104 -#define PCI_CLASS_STORAGE_SATA 0x0106 -#define PCI_CLASS_STORAGE_SATA_AHCI 0x010601 -#define PCI_CLASS_STORAGE_SAS 0x0107 -#define PCI_CLASS_STORAGE_OTHER 0x0180 - -#define PCI_BASE_CLASS_NETWORK 0x02 -#define PCI_CLASS_NETWORK_ETHERNET 0x0200 -#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201 -#define PCI_CLASS_NETWORK_FDDI 0x0202 -#define PCI_CLASS_NETWORK_ATM 0x0203 -#define PCI_CLASS_NETWORK_OTHER 0x0280 - -#define PCI_BASE_CLASS_DISPLAY 0x03 -#define PCI_CLASS_DISPLAY_VGA 0x0300 -#define PCI_CLASS_DISPLAY_XGA 0x0301 -#define PCI_CLASS_DISPLAY_3D 0x0302 -#define PCI_CLASS_DISPLAY_OTHER 0x0380 - -#define PCI_BASE_CLASS_MULTIMEDIA 0x04 -#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400 -#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 -#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402 -#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 - -#define PCI_BASE_CLASS_MEMORY 0x05 -#define PCI_CLASS_MEMORY_RAM 0x0500 -#define PCI_CLASS_MEMORY_FLASH 0x0501 -#define PCI_CLASS_MEMORY_OTHER 0x0580 - -#define PCI_BASE_CLASS_BRIDGE 0x06 -#define PCI_CLASS_BRIDGE_HOST 0x0600 -#define PCI_CLASS_BRIDGE_ISA 0x0601 -#define PCI_CLASS_BRIDGE_EISA 0x0602 -#define PCI_CLASS_BRIDGE_MC 0x0603 -#define PCI_CLASS_BRIDGE_PCI 0x0604 -#define PCI_CLASS_BRIDGE_PCMCIA 0x0605 -#define PCI_CLASS_BRIDGE_NUBUS 0x0606 -#define PCI_CLASS_BRIDGE_CARDBUS 0x0607 -#define PCI_CLASS_BRIDGE_RACEWAY 0x0608 -#define PCI_CLASS_BRIDGE_OTHER 0x0680 - -#define PCI_BASE_CLASS_COMMUNICATION 0x07 -#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 -#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701 -#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702 -#define PCI_CLASS_COMMUNICATION_MODEM 0x0703 -#define PCI_CLASS_COMMUNICATION_OTHER 0x0780 - -#define PCI_BASE_CLASS_SYSTEM 0x08 -#define PCI_CLASS_SYSTEM_PIC 0x0800 -#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010 -#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020 -#define PCI_CLASS_SYSTEM_DMA 0x0801 -#define PCI_CLASS_SYSTEM_TIMER 0x0802 -#define PCI_CLASS_SYSTEM_RTC 0x0803 -#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804 -#define PCI_CLASS_SYSTEM_SDHCI 0x0805 -#define PCI_CLASS_SYSTEM_OTHER 0x0880 - -#define PCI_BASE_CLASS_INPUT 0x09 -#define PCI_CLASS_INPUT_KEYBOARD 0x0900 -#define PCI_CLASS_INPUT_PEN 0x0901 -#define PCI_CLASS_INPUT_MOUSE 0x0902 -#define PCI_CLASS_INPUT_SCANNER 0x0903 -#define PCI_CLASS_INPUT_GAMEPORT 0x0904 -#define PCI_CLASS_INPUT_OTHER 0x0980 - -#define PCI_BASE_CLASS_DOCKING 0x0a -#define PCI_CLASS_DOCKING_GENERIC 0x0a00 -#define PCI_CLASS_DOCKING_OTHER 0x0a80 - -#define PCI_BASE_CLASS_PROCESSOR 0x0b -#define PCI_CLASS_PROCESSOR_386 0x0b00 -#define PCI_CLASS_PROCESSOR_486 0x0b01 -#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02 -#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10 -#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20 -#define PCI_CLASS_PROCESSOR_MIPS 0x0b30 -#define PCI_CLASS_PROCESSOR_CO 0x0b40 - -#define PCI_BASE_CLASS_SERIAL 0x0c -#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00 -#define PCI_CLASS_SERIAL_FIREWIRE_OHCI 0x0c0010 -#define PCI_CLASS_SERIAL_ACCESS 0x0c01 -#define PCI_CLASS_SERIAL_SSA 0x0c02 -#define PCI_CLASS_SERIAL_USB 0x0c03 -#define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300 -#define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 -#define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 -#define PCI_CLASS_SERIAL_FIBER 0x0c04 -#define PCI_CLASS_SERIAL_SMBUS 0x0c05 - -#define PCI_BASE_CLASS_WIRELESS 0x0d -#define PCI_CLASS_WIRELESS_RF_CONTROLLER 0x0d10 -#define PCI_CLASS_WIRELESS_WHCI 0x0d1010 - -#define PCI_BASE_CLASS_INTELLIGENT 0x0e -#define PCI_CLASS_INTELLIGENT_I2O 0x0e00 - -#define PCI_BASE_CLASS_SATELLITE 0x0f -#define PCI_CLASS_SATELLITE_TV 0x0f00 -#define PCI_CLASS_SATELLITE_AUDIO 0x0f01 -#define PCI_CLASS_SATELLITE_VOICE 0x0f03 -#define PCI_CLASS_SATELLITE_DATA 0x0f04 - -#define PCI_BASE_CLASS_CRYPT 0x10 -#define PCI_CLASS_CRYPT_NETWORK 0x1000 -#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001 -#define PCI_CLASS_CRYPT_OTHER 0x1080 - -#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11 -#define PCI_CLASS_SP_DPIO 0x1100 -#define PCI_CLASS_SP_OTHER 0x1180 - -#define PCI_CLASS_OTHERS 0xff - -/* Vendors and devices. Sort key: vendor first, device next. */ - -#define PCI_VENDOR_ID_TTTECH 0x0357 -#define PCI_DEVICE_ID_TTTECH_MC322 0x000a - -#define PCI_VENDOR_ID_DYNALINK 0x0675 -#define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702 - -#define PCI_VENDOR_ID_BERKOM 0x0871 -#define PCI_DEVICE_ID_BERKOM_A1T 0xffa1 -#define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2 -#define PCI_DEVICE_ID_BERKOM_A4T 0xffa4 -#define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO 0xffa8 - -#define PCI_VENDOR_ID_COMPAQ 0x0e11 -#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508 -#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc -#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 -#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 -#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34 -#define PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE 0xae33 -#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35 -#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40 -#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43 -#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011 -#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060 -#define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178 -#define PCI_DEVICE_ID_COMPAQ_CISSC 0x46 -#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130 -#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150 - -#define PCI_VENDOR_ID_NCR 0x1000 -#define PCI_VENDOR_ID_LSI_LOGIC 0x1000 -#define PCI_DEVICE_ID_NCR_53C810 0x0001 -#define PCI_DEVICE_ID_NCR_53C820 0x0002 -#define PCI_DEVICE_ID_NCR_53C825 0x0003 -#define PCI_DEVICE_ID_NCR_53C815 0x0004 -#define PCI_DEVICE_ID_LSI_53C810AP 0x0005 -#define PCI_DEVICE_ID_NCR_53C860 0x0006 -#define PCI_DEVICE_ID_LSI_53C1510 0x000a -#define PCI_DEVICE_ID_NCR_53C896 0x000b -#define PCI_DEVICE_ID_NCR_53C895 0x000c -#define PCI_DEVICE_ID_NCR_53C885 0x000d -#define PCI_DEVICE_ID_NCR_53C875 0x000f -#define PCI_DEVICE_ID_NCR_53C1510 0x0010 -#define PCI_DEVICE_ID_LSI_53C895A 0x0012 -#define PCI_DEVICE_ID_LSI_53C875A 0x0013 -#define PCI_DEVICE_ID_LSI_53C1010_33 0x0020 -#define PCI_DEVICE_ID_LSI_53C1010_66 0x0021 -#define PCI_DEVICE_ID_LSI_53C1030 0x0030 -#define PCI_DEVICE_ID_LSI_1030_53C1035 0x0032 -#define PCI_DEVICE_ID_LSI_53C1035 0x0040 -#define PCI_DEVICE_ID_NCR_53C875J 0x008f -#define PCI_DEVICE_ID_LSI_FC909 0x0621 -#define PCI_DEVICE_ID_LSI_FC929 0x0622 -#define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623 -#define PCI_DEVICE_ID_LSI_FC919 0x0624 -#define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625 -#define PCI_DEVICE_ID_LSI_FC929X 0x0626 -#define PCI_DEVICE_ID_LSI_FC939X 0x0642 -#define PCI_DEVICE_ID_LSI_FC949X 0x0640 -#define PCI_DEVICE_ID_LSI_FC949ES 0x0646 -#define PCI_DEVICE_ID_LSI_FC919X 0x0628 -#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701 -#define PCI_DEVICE_ID_LSI_61C102 0x0901 -#define PCI_DEVICE_ID_LSI_63C815 0x1000 -#define PCI_DEVICE_ID_LSI_SAS1064 0x0050 -#define PCI_DEVICE_ID_LSI_SAS1064R 0x0411 -#define PCI_DEVICE_ID_LSI_SAS1066 0x005E -#define PCI_DEVICE_ID_LSI_SAS1068 0x0054 -#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C -#define PCI_DEVICE_ID_LSI_SAS1064E 0x0056 -#define PCI_DEVICE_ID_LSI_SAS1066E 0x005A -#define PCI_DEVICE_ID_LSI_SAS1068E 0x0058 -#define PCI_DEVICE_ID_LSI_SAS1078 0x0060 - -#define PCI_VENDOR_ID_ATI 0x1002 -/* Mach64 */ -#define PCI_DEVICE_ID_ATI_68800 0x4158 -#define PCI_DEVICE_ID_ATI_215CT222 0x4354 -#define PCI_DEVICE_ID_ATI_210888CX 0x4358 -#define PCI_DEVICE_ID_ATI_215ET222 0x4554 -/* Mach64 / Rage */ -#define PCI_DEVICE_ID_ATI_215GB 0x4742 -#define PCI_DEVICE_ID_ATI_215GD 0x4744 -#define PCI_DEVICE_ID_ATI_215GI 0x4749 -#define PCI_DEVICE_ID_ATI_215GP 0x4750 -#define PCI_DEVICE_ID_ATI_215GQ 0x4751 -#define PCI_DEVICE_ID_ATI_215XL 0x4752 -#define PCI_DEVICE_ID_ATI_215GT 0x4754 -#define PCI_DEVICE_ID_ATI_215GTB 0x4755 -#define PCI_DEVICE_ID_ATI_215_IV 0x4756 -#define PCI_DEVICE_ID_ATI_215_IW 0x4757 -#define PCI_DEVICE_ID_ATI_215_IZ 0x475A -#define PCI_DEVICE_ID_ATI_210888GX 0x4758 -#define PCI_DEVICE_ID_ATI_215_LB 0x4c42 -#define PCI_DEVICE_ID_ATI_215_LD 0x4c44 -#define PCI_DEVICE_ID_ATI_215_LG 0x4c47 -#define PCI_DEVICE_ID_ATI_215_LI 0x4c49 -#define PCI_DEVICE_ID_ATI_215_LM 0x4c4D -#define PCI_DEVICE_ID_ATI_215_LN 0x4c4E -#define PCI_DEVICE_ID_ATI_215_LR 0x4c52 -#define PCI_DEVICE_ID_ATI_215_LS 0x4c53 -#define PCI_DEVICE_ID_ATI_264_LT 0x4c54 -/* Mach64 VT */ -#define PCI_DEVICE_ID_ATI_264VT 0x5654 -#define PCI_DEVICE_ID_ATI_264VU 0x5655 -#define PCI_DEVICE_ID_ATI_264VV 0x5656 -/* Rage128 GL */ -#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245 -#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246 -#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x5247 -/* Rage128 VR */ -#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b -#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c -#define PCI_DEVICE_ID_ATI_RAGE128_SE 0x5345 -#define PCI_DEVICE_ID_ATI_RAGE128_SF 0x5346 -#define PCI_DEVICE_ID_ATI_RAGE128_SG 0x5347 -#define PCI_DEVICE_ID_ATI_RAGE128_SH 0x5348 -#define PCI_DEVICE_ID_ATI_RAGE128_SK 0x534b -#define PCI_DEVICE_ID_ATI_RAGE128_SL 0x534c -#define PCI_DEVICE_ID_ATI_RAGE128_SM 0x534d -#define PCI_DEVICE_ID_ATI_RAGE128_SN 0x534e -/* Rage128 Ultra */ -#define PCI_DEVICE_ID_ATI_RAGE128_TF 0x5446 -#define PCI_DEVICE_ID_ATI_RAGE128_TL 0x544c -#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452 -#define PCI_DEVICE_ID_ATI_RAGE128_TS 0x5453 -#define PCI_DEVICE_ID_ATI_RAGE128_TT 0x5454 -#define PCI_DEVICE_ID_ATI_RAGE128_TU 0x5455 -/* Rage128 M3 */ -#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45 -#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46 -/* Rage128 M4 */ -#define PCI_DEVICE_ID_ATI_RAGE128_MF 0x4d46 -#define PCI_DEVICE_ID_ATI_RAGE128_ML 0x4d4c -/* Rage128 Pro GL */ -#define PCI_DEVICE_ID_ATI_RAGE128_PA 0x5041 -#define PCI_DEVICE_ID_ATI_RAGE128_PB 0x5042 -#define PCI_DEVICE_ID_ATI_RAGE128_PC 0x5043 -#define PCI_DEVICE_ID_ATI_RAGE128_PD 0x5044 -#define PCI_DEVICE_ID_ATI_RAGE128_PE 0x5045 -#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046 -/* Rage128 Pro VR */ -#define PCI_DEVICE_ID_ATI_RAGE128_PG 0x5047 -#define PCI_DEVICE_ID_ATI_RAGE128_PH 0x5048 -#define PCI_DEVICE_ID_ATI_RAGE128_PI 0x5049 -#define PCI_DEVICE_ID_ATI_RAGE128_PJ 0x504A -#define PCI_DEVICE_ID_ATI_RAGE128_PK 0x504B -#define PCI_DEVICE_ID_ATI_RAGE128_PL 0x504C -#define PCI_DEVICE_ID_ATI_RAGE128_PM 0x504D -#define PCI_DEVICE_ID_ATI_RAGE128_PN 0x504E -#define PCI_DEVICE_ID_ATI_RAGE128_PO 0x504F -#define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050 -#define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051 -#define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052 -#define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053 -#define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054 -#define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055 -#define PCI_DEVICE_ID_ATI_RAGE128_PV 0x5056 -#define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057 -#define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058 -/* Rage128 M4 */ -/* Radeon R100 */ -#define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144 -#define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145 -#define PCI_DEVICE_ID_ATI_RADEON_QF 0x5146 -#define PCI_DEVICE_ID_ATI_RADEON_QG 0x5147 -/* Radeon RV100 (VE) */ -#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159 -#define PCI_DEVICE_ID_ATI_RADEON_QZ 0x515a -/* Radeon R200 (8500) */ -#define PCI_DEVICE_ID_ATI_RADEON_QL 0x514c -#define PCI_DEVICE_ID_ATI_RADEON_QN 0x514e -#define PCI_DEVICE_ID_ATI_RADEON_QO 0x514f -#define PCI_DEVICE_ID_ATI_RADEON_Ql 0x516c -#define PCI_DEVICE_ID_ATI_RADEON_BB 0x4242 -/* Radeon R200 (9100) */ -#define PCI_DEVICE_ID_ATI_RADEON_QM 0x514d -/* Radeon RV200 (7500) */ -#define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157 -#define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158 -/* Radeon NV-100 */ -/* Radeon RV250 (9000) */ -#define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964 -#define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965 -#define PCI_DEVICE_ID_ATI_RADEON_If 0x4966 -#define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967 -/* Radeon RV280 (9200) */ -#define PCI_DEVICE_ID_ATI_RADEON_Ya 0x5961 -#define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964 -/* Radeon R300 (9500) */ -/* Radeon R300 (9700) */ -#define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44 -#define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45 -#define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46 -#define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47 -/* Radeon R350 (9800) */ -/* Radeon RV350 (9600) */ -/* Radeon M6 */ -#define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59 -#define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a -/* Radeon M7 */ -#define PCI_DEVICE_ID_ATI_RADEON_LW 0x4c57 -#define PCI_DEVICE_ID_ATI_RADEON_LX 0x4c58 -/* Radeon M9 */ -#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4c64 -#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4c65 -#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66 -#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67 -/* Radeon */ -/* RadeonIGP */ -#define PCI_DEVICE_ID_ATI_RS100 0xcab0 -#define PCI_DEVICE_ID_ATI_RS200 0xcab2 -#define PCI_DEVICE_ID_ATI_RS200_B 0xcbb2 -#define PCI_DEVICE_ID_ATI_RS250 0xcab3 -#define PCI_DEVICE_ID_ATI_RS300_100 0x5830 -#define PCI_DEVICE_ID_ATI_RS300_133 0x5831 -#define PCI_DEVICE_ID_ATI_RS300_166 0x5832 -#define PCI_DEVICE_ID_ATI_RS300_200 0x5833 -#define PCI_DEVICE_ID_ATI_RS350_100 0x7830 -#define PCI_DEVICE_ID_ATI_RS350_133 0x7831 -#define PCI_DEVICE_ID_ATI_RS350_166 0x7832 -#define PCI_DEVICE_ID_ATI_RS350_200 0x7833 -#define PCI_DEVICE_ID_ATI_RS400_100 0x5a30 -#define PCI_DEVICE_ID_ATI_RS400_133 0x5a31 -#define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 -#define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 -#define PCI_DEVICE_ID_ATI_RS480 0x5950 -/* ATI IXP Chipset */ -#define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 -#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 -#define PCI_DEVICE_ID_ATI_IXP300_SMBUS 0x4363 -#define PCI_DEVICE_ID_ATI_IXP300_IDE 0x4369 -#define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e -#define PCI_DEVICE_ID_ATI_IXP400_SMBUS 0x4372 -#define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 -#define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 -#define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a -#define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380 -#define PCI_DEVICE_ID_ATI_SBX00_SMBUS 0x4385 -#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c -#define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390 -#define PCI_DEVICE_ID_ATI_IXP700_IDE 0x439c - -#define PCI_VENDOR_ID_VLSI 0x1004 -#define PCI_DEVICE_ID_VLSI_82C592 0x0005 -#define PCI_DEVICE_ID_VLSI_82C593 0x0006 -#define PCI_DEVICE_ID_VLSI_82C594 0x0007 -#define PCI_DEVICE_ID_VLSI_82C597 0x0009 -#define PCI_DEVICE_ID_VLSI_82C541 0x000c -#define PCI_DEVICE_ID_VLSI_82C543 0x000d -#define PCI_DEVICE_ID_VLSI_82C532 0x0101 -#define PCI_DEVICE_ID_VLSI_82C534 0x0102 -#define PCI_DEVICE_ID_VLSI_82C535 0x0104 -#define PCI_DEVICE_ID_VLSI_82C147 0x0105 -#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 - -#define PCI_VENDOR_ID_ADL 0x1005 -#define PCI_DEVICE_ID_ADL_2301 0x2301 - -#define PCI_VENDOR_ID_NS 0x100b -#define PCI_DEVICE_ID_NS_87415 0x0002 -#define PCI_DEVICE_ID_NS_87560_LIO 0x000e -#define PCI_DEVICE_ID_NS_87560_USB 0x0012 -#define PCI_DEVICE_ID_NS_83815 0x0020 -#define PCI_DEVICE_ID_NS_83820 0x0022 -#define PCI_DEVICE_ID_NS_CS5535_ISA 0x002b -#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d -#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e -#define PCI_DEVICE_ID_NS_CS5535_USB 0x002f -#define PCI_DEVICE_ID_NS_GX_VIDEO 0x0030 -#define PCI_DEVICE_ID_NS_SATURN 0x0035 -#define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500 -#define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501 -#define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502 -#define PCI_DEVICE_ID_NS_SCx200_AUDIO 0x0503 -#define PCI_DEVICE_ID_NS_SCx200_VIDEO 0x0504 -#define PCI_DEVICE_ID_NS_SCx200_XBUS 0x0505 -#define PCI_DEVICE_ID_NS_SC1100_BRIDGE 0x0510 -#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 -#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 -#define PCI_DEVICE_ID_NS_87410 0xd001 - -#define PCI_DEVICE_ID_NS_GX_HOST_BRIDGE 0x0028 - -#define PCI_VENDOR_ID_TSENG 0x100c -#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 -#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205 -#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206 -#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207 -#define PCI_DEVICE_ID_TSENG_ET6000 0x3208 - -#define PCI_VENDOR_ID_WEITEK 0x100e -#define PCI_DEVICE_ID_WEITEK_P9000 0x9001 -#define PCI_DEVICE_ID_WEITEK_P9100 0x9100 - -#define PCI_VENDOR_ID_DEC 0x1011 -#define PCI_DEVICE_ID_DEC_BRD 0x0001 -#define PCI_DEVICE_ID_DEC_TULIP 0x0002 -#define PCI_DEVICE_ID_DEC_TGA 0x0004 -#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 -#define PCI_DEVICE_ID_DEC_TGA2 0x000D -#define PCI_DEVICE_ID_DEC_FDDI 0x000F -#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 -#define PCI_DEVICE_ID_DEC_21142 0x0019 -#define PCI_DEVICE_ID_DEC_21052 0x0021 -#define PCI_DEVICE_ID_DEC_21150 0x0022 -#define PCI_DEVICE_ID_DEC_21152 0x0024 -#define PCI_DEVICE_ID_DEC_21153 0x0025 -#define PCI_DEVICE_ID_DEC_21154 0x0026 -#define PCI_DEVICE_ID_DEC_21285 0x1065 -#define PCI_DEVICE_ID_COMPAQ_42XX 0x0046 - -#define PCI_VENDOR_ID_CIRRUS 0x1013 -#define PCI_DEVICE_ID_CIRRUS_7548 0x0038 -#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0 -#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4 -#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8 -#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac -#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8 -#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc -#define PCI_DEVICE_ID_CIRRUS_5462 0x00d0 -#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4 -#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6 -#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 -#define PCI_DEVICE_ID_CIRRUS_6832 0x1110 -#define PCI_DEVICE_ID_CIRRUS_7543 0x1202 -#define PCI_DEVICE_ID_CIRRUS_4610 0x6001 -#define PCI_DEVICE_ID_CIRRUS_4612 0x6003 -#define PCI_DEVICE_ID_CIRRUS_4615 0x6004 - -#define PCI_VENDOR_ID_IBM 0x1014 -#define PCI_DEVICE_ID_IBM_TR 0x0018 -#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e -#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc -#define PCI_DEVICE_ID_IBM_SNIPE 0x0180 -#define PCI_DEVICE_ID_IBM_CITRINE 0x028C -#define PCI_DEVICE_ID_IBM_GEMSTONE 0xB166 -#define PCI_DEVICE_ID_IBM_OBSIDIAN 0x02BD -#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1 0x0031 -#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2 0x0219 -#define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX 0x021A -#define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251 -#define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE 0x0361 -#define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252 - -#define PCI_VENDOR_ID_UNISYS 0x1018 -#define PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR 0x001C - -#define PCI_VENDOR_ID_COMPEX2 0x101a /* pci.ids says "AT&T GIS (NCR)" */ -#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 - -#define PCI_VENDOR_ID_WD 0x101c -#define PCI_DEVICE_ID_WD_90C 0xc24a - -#define PCI_VENDOR_ID_AMI 0x101e -#define PCI_DEVICE_ID_AMI_MEGARAID3 0x1960 -#define PCI_DEVICE_ID_AMI_MEGARAID 0x9010 -#define PCI_DEVICE_ID_AMI_MEGARAID2 0x9060 - -#define PCI_VENDOR_ID_AMD 0x1022 -#define PCI_DEVICE_ID_AMD_K8_NB 0x1100 -#define PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP 0x1101 -#define PCI_DEVICE_ID_AMD_K8_NB_MEMCTL 0x1102 -#define PCI_DEVICE_ID_AMD_K8_NB_MISC 0x1103 -#define PCI_DEVICE_ID_AMD_10H_NB_HT 0x1200 -#define PCI_DEVICE_ID_AMD_10H_NB_MAP 0x1201 -#define PCI_DEVICE_ID_AMD_10H_NB_DRAM 0x1202 -#define PCI_DEVICE_ID_AMD_10H_NB_MISC 0x1203 -#define PCI_DEVICE_ID_AMD_10H_NB_LINK 0x1204 -#define PCI_DEVICE_ID_AMD_11H_NB_HT 0x1300 -#define PCI_DEVICE_ID_AMD_11H_NB_MAP 0x1301 -#define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302 -#define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 -#define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 -#define PCI_DEVICE_ID_AMD_LANCE 0x2000 -#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 -#define PCI_DEVICE_ID_AMD_SCSI 0x2020 -#define PCI_DEVICE_ID_AMD_SERENADE 0x36c0 -#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006 -#define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007 -#define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C -#define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E -#define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401 -#define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409 -#define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B -#define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410 -#define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411 -#define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413 -#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440 -#define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441 -#define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443 -#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443 -#define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445 -#define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 -#define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 -#define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a -#define PCI_DEVICE_ID_AMD_8111_SMBUS 0x746b -#define PCI_DEVICE_ID_AMD_8111_AUDIO 0x746d -#define PCI_DEVICE_ID_AMD_8151_0 0x7454 -#define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 -#define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 -#define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458 -#define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 -#define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 -#define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093 -#define PCI_DEVICE_ID_AMD_CS5536_OHC 0x2094 -#define PCI_DEVICE_ID_AMD_CS5536_EHC 0x2095 -#define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096 -#define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097 -#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A - -#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 -#define PCI_DEVICE_ID_AMD_LX_AES 0x2082 - -#define PCI_VENDOR_ID_TRIDENT 0x1023 -#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 -#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001 -#define PCI_DEVICE_ID_TRIDENT_9320 0x9320 -#define PCI_DEVICE_ID_TRIDENT_9388 0x9388 -#define PCI_DEVICE_ID_TRIDENT_9397 0x9397 -#define PCI_DEVICE_ID_TRIDENT_939A 0x939A -#define PCI_DEVICE_ID_TRIDENT_9520 0x9520 -#define PCI_DEVICE_ID_TRIDENT_9525 0x9525 -#define PCI_DEVICE_ID_TRIDENT_9420 0x9420 -#define PCI_DEVICE_ID_TRIDENT_9440 0x9440 -#define PCI_DEVICE_ID_TRIDENT_9660 0x9660 -#define PCI_DEVICE_ID_TRIDENT_9750 0x9750 -#define PCI_DEVICE_ID_TRIDENT_9850 0x9850 -#define PCI_DEVICE_ID_TRIDENT_9880 0x9880 -#define PCI_DEVICE_ID_TRIDENT_8400 0x8400 -#define PCI_DEVICE_ID_TRIDENT_8420 0x8420 -#define PCI_DEVICE_ID_TRIDENT_8500 0x8500 - -#define PCI_VENDOR_ID_AI 0x1025 -#define PCI_DEVICE_ID_AI_M1435 0x1435 - -#define PCI_VENDOR_ID_DELL 0x1028 -#define PCI_DEVICE_ID_DELL_RACIII 0x0008 -#define PCI_DEVICE_ID_DELL_RAC4 0x0012 -#define PCI_DEVICE_ID_DELL_PERC5 0x0015 - -#define PCI_VENDOR_ID_MATROX 0x102B -#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 -#define PCI_DEVICE_ID_MATROX_MIL 0x0519 -#define PCI_DEVICE_ID_MATROX_MYS 0x051A -#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b -#define PCI_DEVICE_ID_MATROX_MYS_AGP 0x051e -#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f -#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10 -#define PCI_DEVICE_ID_MATROX_G100_MM 0x1000 -#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001 -#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520 -#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521 -#define PCI_DEVICE_ID_MATROX_G400 0x0525 -#define PCI_DEVICE_ID_MATROX_G200EV_PCI 0x0530 -#define PCI_DEVICE_ID_MATROX_G550 0x2527 -#define PCI_DEVICE_ID_MATROX_VIA 0x4536 - -#define PCI_VENDOR_ID_CT 0x102c -#define PCI_DEVICE_ID_CT_69000 0x00c0 -#define PCI_DEVICE_ID_CT_65545 0x00d8 -#define PCI_DEVICE_ID_CT_65548 0x00dc -#define PCI_DEVICE_ID_CT_65550 0x00e0 -#define PCI_DEVICE_ID_CT_65554 0x00e4 -#define PCI_DEVICE_ID_CT_65555 0x00e5 - -#define PCI_VENDOR_ID_MIRO 0x1031 -#define PCI_DEVICE_ID_MIRO_36050 0x5601 -#define PCI_DEVICE_ID_MIRO_DC10PLUS 0x7efe -#define PCI_DEVICE_ID_MIRO_DC30PLUS 0xd801 - -#define PCI_VENDOR_ID_NEC 0x1033 -#define PCI_DEVICE_ID_NEC_CBUS_1 0x0001 /* PCI-Cbus Bridge */ -#define PCI_DEVICE_ID_NEC_LOCAL 0x0002 /* Local Bridge */ -#define PCI_DEVICE_ID_NEC_ATM 0x0003 /* ATM LAN Controller */ -#define PCI_DEVICE_ID_NEC_R4000 0x0004 /* R4000 Bridge */ -#define PCI_DEVICE_ID_NEC_486 0x0005 /* 486 Like Peripheral Bus Bridge */ -#define PCI_DEVICE_ID_NEC_ACCEL_1 0x0006 /* Graphic Accelerator */ -#define PCI_DEVICE_ID_NEC_UXBUS 0x0007 /* UX-Bus Bridge */ -#define PCI_DEVICE_ID_NEC_ACCEL_2 0x0008 /* Graphic Accelerator */ -#define PCI_DEVICE_ID_NEC_GRAPH 0x0009 /* PCI-CoreGraph Bridge */ -#define PCI_DEVICE_ID_NEC_VL 0x0016 /* PCI-VL Bridge */ -#define PCI_DEVICE_ID_NEC_STARALPHA2 0x002c /* STAR ALPHA2 */ -#define PCI_DEVICE_ID_NEC_CBUS_2 0x002d /* PCI-Cbus Bridge */ -#define PCI_DEVICE_ID_NEC_USB 0x0035 /* PCI-USB Host */ -#define PCI_DEVICE_ID_NEC_CBUS_3 0x003b -#define PCI_DEVICE_ID_NEC_NAPCCARD 0x003e -#define PCI_DEVICE_ID_NEC_PCX2 0x0046 /* PowerVR */ -#define PCI_DEVICE_ID_NEC_VRC5476 0x009b -#define PCI_DEVICE_ID_NEC_VRC4173 0x00a5 -#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00a6 -#define PCI_DEVICE_ID_NEC_PC9821CS01 0x800c /* PC-9821-CS01 */ -#define PCI_DEVICE_ID_NEC_PC9821NRB06 0x800d /* PC-9821NR-B06 */ - -#define PCI_VENDOR_ID_FD 0x1036 -#define PCI_DEVICE_ID_FD_36C70 0x0000 - -#define PCI_VENDOR_ID_SI 0x1039 -#define PCI_DEVICE_ID_SI_5591_AGP 0x0001 -#define PCI_DEVICE_ID_SI_6202 0x0002 -#define PCI_DEVICE_ID_SI_503 0x0008 -#define PCI_DEVICE_ID_SI_ACPI 0x0009 -#define PCI_DEVICE_ID_SI_SMBUS 0x0016 -#define PCI_DEVICE_ID_SI_LPC 0x0018 -#define PCI_DEVICE_ID_SI_5597_VGA 0x0200 -#define PCI_DEVICE_ID_SI_6205 0x0205 -#define PCI_DEVICE_ID_SI_501 0x0406 -#define PCI_DEVICE_ID_SI_496 0x0496 -#define PCI_DEVICE_ID_SI_300 0x0300 -#define PCI_DEVICE_ID_SI_315H 0x0310 -#define PCI_DEVICE_ID_SI_315 0x0315 -#define PCI_DEVICE_ID_SI_315PRO 0x0325 -#define PCI_DEVICE_ID_SI_530 0x0530 -#define PCI_DEVICE_ID_SI_540 0x0540 -#define PCI_DEVICE_ID_SI_550 0x0550 -#define PCI_DEVICE_ID_SI_540_VGA 0x5300 -#define PCI_DEVICE_ID_SI_550_VGA 0x5315 -#define PCI_DEVICE_ID_SI_620 0x0620 -#define PCI_DEVICE_ID_SI_630 0x0630 -#define PCI_DEVICE_ID_SI_633 0x0633 -#define PCI_DEVICE_ID_SI_635 0x0635 -#define PCI_DEVICE_ID_SI_640 0x0640 -#define PCI_DEVICE_ID_SI_645 0x0645 -#define PCI_DEVICE_ID_SI_646 0x0646 -#define PCI_DEVICE_ID_SI_648 0x0648 -#define PCI_DEVICE_ID_SI_650 0x0650 -#define PCI_DEVICE_ID_SI_651 0x0651 -#define PCI_DEVICE_ID_SI_655 0x0655 -#define PCI_DEVICE_ID_SI_661 0x0661 -#define PCI_DEVICE_ID_SI_730 0x0730 -#define PCI_DEVICE_ID_SI_733 0x0733 -#define PCI_DEVICE_ID_SI_630_VGA 0x6300 -#define PCI_DEVICE_ID_SI_735 0x0735 -#define PCI_DEVICE_ID_SI_740 0x0740 -#define PCI_DEVICE_ID_SI_741 0x0741 -#define PCI_DEVICE_ID_SI_745 0x0745 -#define PCI_DEVICE_ID_SI_746 0x0746 -#define PCI_DEVICE_ID_SI_755 0x0755 -#define PCI_DEVICE_ID_SI_760 0x0760 -#define PCI_DEVICE_ID_SI_900 0x0900 -#define PCI_DEVICE_ID_SI_961 0x0961 -#define PCI_DEVICE_ID_SI_962 0x0962 -#define PCI_DEVICE_ID_SI_963 0x0963 -#define PCI_DEVICE_ID_SI_965 0x0965 -#define PCI_DEVICE_ID_SI_966 0x0966 -#define PCI_DEVICE_ID_SI_968 0x0968 -#define PCI_DEVICE_ID_SI_1180 0x1180 -#define PCI_DEVICE_ID_SI_5511 0x5511 -#define PCI_DEVICE_ID_SI_5513 0x5513 -#define PCI_DEVICE_ID_SI_5517 0x5517 -#define PCI_DEVICE_ID_SI_5518 0x5518 -#define PCI_DEVICE_ID_SI_5571 0x5571 -#define PCI_DEVICE_ID_SI_5581 0x5581 -#define PCI_DEVICE_ID_SI_5582 0x5582 -#define PCI_DEVICE_ID_SI_5591 0x5591 -#define PCI_DEVICE_ID_SI_5596 0x5596 -#define PCI_DEVICE_ID_SI_5597 0x5597 -#define PCI_DEVICE_ID_SI_5598 0x5598 -#define PCI_DEVICE_ID_SI_5600 0x5600 -#define PCI_DEVICE_ID_SI_7012 0x7012 -#define PCI_DEVICE_ID_SI_7013 0x7013 -#define PCI_DEVICE_ID_SI_7016 0x7016 -#define PCI_DEVICE_ID_SI_7018 0x7018 - -#define PCI_VENDOR_ID_HP 0x103c -#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005 -#define PCI_DEVICE_ID_HP_VISUALIZE_FX6 0x1006 -#define PCI_DEVICE_ID_HP_VISUALIZE_FX4 0x1008 -#define PCI_DEVICE_ID_HP_VISUALIZE_FX2 0x100a -#define PCI_DEVICE_ID_HP_TACHYON 0x1028 -#define PCI_DEVICE_ID_HP_TACHLITE 0x1029 -#define PCI_DEVICE_ID_HP_J2585A 0x1030 -#define PCI_DEVICE_ID_HP_J2585B 0x1031 -#define PCI_DEVICE_ID_HP_J2973A 0x1040 -#define PCI_DEVICE_ID_HP_J2970A 0x1042 -#define PCI_DEVICE_ID_HP_DIVA 0x1048 -#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049 -#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A -#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B -#define PCI_DEVICE_ID_HP_REO_IOC 0x10f1 -#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b -#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223 -#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226 -#define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227 -#define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a -#define PCI_DEVICE_ID_HP_PCIX_LBA 0x122e -#define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c -#define PCI_DEVICE_ID_HP_DIVA_EVEREST 0x1282 -#define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290 -#define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301 -#define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a -#define PCI_DEVICE_ID_HP_CISSA 0x3220 -#define PCI_DEVICE_ID_HP_CISSC 0x3230 -#define PCI_DEVICE_ID_HP_CISSD 0x3238 -#define PCI_DEVICE_ID_HP_CISSE 0x323a -#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031 - -#define PCI_VENDOR_ID_PCTECH 0x1042 -#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 -#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 -#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020 - -#define PCI_VENDOR_ID_ASUSTEK 0x1043 -#define PCI_DEVICE_ID_ASUSTEK_0675 0x0675 - -#define PCI_VENDOR_ID_DPT 0x1044 -#define PCI_DEVICE_ID_DPT 0xa400 - -#define PCI_VENDOR_ID_OPTI 0x1045 -#define PCI_DEVICE_ID_OPTI_82C558 0xc558 -#define PCI_DEVICE_ID_OPTI_82C621 0xc621 -#define PCI_DEVICE_ID_OPTI_82C700 0xc700 -#define PCI_DEVICE_ID_OPTI_82C825 0xd568 - -#define PCI_VENDOR_ID_ELSA 0x1048 -#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000 -#define PCI_DEVICE_ID_ELSA_QS3000 0x3000 - -#define PCI_VENDOR_ID_BUSLOGIC 0x104B -#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 -#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040 -#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 - -#define PCI_VENDOR_ID_TI 0x104c -#define PCI_DEVICE_ID_TI_TVP4020 0x3d07 -#define PCI_DEVICE_ID_TI_4450 0x8011 -#define PCI_DEVICE_ID_TI_TSB43AB22 0x8023 -#define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 -#define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 -#define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 -#define PCI_DEVICE_ID_TI_X515 0x8036 -#define PCI_DEVICE_ID_TI_XX12 0x8039 -#define PCI_DEVICE_ID_TI_XX12_FM 0x803b -#define PCI_DEVICE_ID_TI_1130 0xac12 -#define PCI_DEVICE_ID_TI_1031 0xac13 -#define PCI_DEVICE_ID_TI_1131 0xac15 -#define PCI_DEVICE_ID_TI_1250 0xac16 -#define PCI_DEVICE_ID_TI_1220 0xac17 -#define PCI_DEVICE_ID_TI_1221 0xac19 -#define PCI_DEVICE_ID_TI_1210 0xac1a -#define PCI_DEVICE_ID_TI_1450 0xac1b -#define PCI_DEVICE_ID_TI_1225 0xac1c -#define PCI_DEVICE_ID_TI_1251A 0xac1d -#define PCI_DEVICE_ID_TI_1211 0xac1e -#define PCI_DEVICE_ID_TI_1251B 0xac1f -#define PCI_DEVICE_ID_TI_4410 0xac41 -#define PCI_DEVICE_ID_TI_4451 0xac42 -#define PCI_DEVICE_ID_TI_4510 0xac44 -#define PCI_DEVICE_ID_TI_4520 0xac46 -#define PCI_DEVICE_ID_TI_7510 0xac47 -#define PCI_DEVICE_ID_TI_7610 0xac48 -#define PCI_DEVICE_ID_TI_7410 0xac49 -#define PCI_DEVICE_ID_TI_1410 0xac50 -#define PCI_DEVICE_ID_TI_1420 0xac51 -#define PCI_DEVICE_ID_TI_1451A 0xac52 -#define PCI_DEVICE_ID_TI_1620 0xac54 -#define PCI_DEVICE_ID_TI_1520 0xac55 -#define PCI_DEVICE_ID_TI_1510 0xac56 -#define PCI_DEVICE_ID_TI_X620 0xac8d -#define PCI_DEVICE_ID_TI_X420 0xac8e -#define PCI_DEVICE_ID_TI_XX20_FM 0xac8f - -#define PCI_VENDOR_ID_SONY 0x104d - -/* Winbond have two vendor IDs! See 0x10ad as well */ -#define PCI_VENDOR_ID_WINBOND2 0x1050 -#define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a -#define PCI_DEVICE_ID_WINBOND2_6692 0x6692 - -#define PCI_VENDOR_ID_ANIGMA 0x1051 -#define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100 - -#define PCI_VENDOR_ID_EFAR 0x1055 -#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 -#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463 - -#define PCI_VENDOR_ID_MOTOROLA 0x1057 -#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001 -#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 -#define PCI_DEVICE_ID_MOTOROLA_MPC107 0x0004 -#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 -#define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802 -#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 -#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b -#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803 -#define PCI_DEVICE_ID_MOTOROLA_MPC5200B 0x5809 - -#define PCI_VENDOR_ID_PROMISE 0x105a -#define PCI_DEVICE_ID_PROMISE_20265 0x0d30 -#define PCI_DEVICE_ID_PROMISE_20267 0x4d30 -#define PCI_DEVICE_ID_PROMISE_20246 0x4d33 -#define PCI_DEVICE_ID_PROMISE_20262 0x4d38 -#define PCI_DEVICE_ID_PROMISE_20263 0x0D38 -#define PCI_DEVICE_ID_PROMISE_20268 0x4d68 -#define PCI_DEVICE_ID_PROMISE_20269 0x4d69 -#define PCI_DEVICE_ID_PROMISE_20270 0x6268 -#define PCI_DEVICE_ID_PROMISE_20271 0x6269 -#define PCI_DEVICE_ID_PROMISE_20275 0x1275 -#define PCI_DEVICE_ID_PROMISE_20276 0x5275 -#define PCI_DEVICE_ID_PROMISE_20277 0x7275 - -#define PCI_VENDOR_ID_UMC 0x1060 -#define PCI_DEVICE_ID_UMC_UM8673F 0x0101 -#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a -#define PCI_DEVICE_ID_UMC_UM8886A 0x886a - -#define PCI_VENDOR_ID_PICOPOWER 0x1066 -#define PCI_DEVICE_ID_PICOPOWER_PT86C523 0x0002 -#define PCI_DEVICE_ID_PICOPOWER_PT86C523BBP 0x8002 - -#define PCI_VENDOR_ID_MYLEX 0x1069 -#define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001 -#define PCI_DEVICE_ID_MYLEX_DAC960_PD 0x0002 -#define PCI_DEVICE_ID_MYLEX_DAC960_PG 0x0010 -#define PCI_DEVICE_ID_MYLEX_DAC960_LA 0x0020 -#define PCI_DEVICE_ID_MYLEX_DAC960_LP 0x0050 -#define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56 -#define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166 - -#define PCI_VENDOR_ID_APPLE 0x106b -#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001 -#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e -#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018 -#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020 -#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021 -#define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024 -#define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 -#define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d -#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e -#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 -#define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033 -#define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034 -#define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b -#define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043 -#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b -#define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c -#define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050 -#define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051 -#define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058 -#define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059 -#define PCI_DEVICE_ID_APPLE_IPID2_AGP 0x0066 -#define PCI_DEVICE_ID_APPLE_IPID2_ATA 0x0069 -#define PCI_DEVICE_ID_APPLE_IPID2_FW 0x006a -#define PCI_DEVICE_ID_APPLE_IPID2_GMAC 0x006b -#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645 - -#define PCI_VENDOR_ID_YAMAHA 0x1073 -#define PCI_DEVICE_ID_YAMAHA_724 0x0004 -#define PCI_DEVICE_ID_YAMAHA_724F 0x000d -#define PCI_DEVICE_ID_YAMAHA_740 0x000a -#define PCI_DEVICE_ID_YAMAHA_740C 0x000c -#define PCI_DEVICE_ID_YAMAHA_744 0x0010 -#define PCI_DEVICE_ID_YAMAHA_754 0x0012 - -#define PCI_VENDOR_ID_QLOGIC 0x1077 -#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016 -#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 -#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080 -#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216 -#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240 -#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280 -#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 -#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200 -#define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300 -#define PCI_DEVICE_ID_QLOGIC_ISP2312 0x2312 -#define PCI_DEVICE_ID_QLOGIC_ISP2322 0x2322 -#define PCI_DEVICE_ID_QLOGIC_ISP6312 0x6312 -#define PCI_DEVICE_ID_QLOGIC_ISP6322 0x6322 -#define PCI_DEVICE_ID_QLOGIC_ISP2422 0x2422 -#define PCI_DEVICE_ID_QLOGIC_ISP2432 0x2432 -#define PCI_DEVICE_ID_QLOGIC_ISP2512 0x2512 -#define PCI_DEVICE_ID_QLOGIC_ISP2522 0x2522 -#define PCI_DEVICE_ID_QLOGIC_ISP5422 0x5422 -#define PCI_DEVICE_ID_QLOGIC_ISP5432 0x5432 - -#define PCI_VENDOR_ID_CYRIX 0x1078 -#define PCI_DEVICE_ID_CYRIX_5510 0x0000 -#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001 -#define PCI_DEVICE_ID_CYRIX_5520 0x0002 -#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100 -#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102 -#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103 -#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104 - -#define PCI_VENDOR_ID_CONTAQ 0x1080 -#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693 - -#define PCI_VENDOR_ID_OLICOM 0x108d -#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012 -#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013 -#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 - -#define PCI_VENDOR_ID_SUN 0x108e -#define PCI_DEVICE_ID_SUN_EBUS 0x1000 -#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001 -#define PCI_DEVICE_ID_SUN_RIO_EBUS 0x1100 -#define PCI_DEVICE_ID_SUN_RIO_GEM 0x1101 -#define PCI_DEVICE_ID_SUN_RIO_1394 0x1102 -#define PCI_DEVICE_ID_SUN_RIO_USB 0x1103 -#define PCI_DEVICE_ID_SUN_GEM 0x2bad -#define PCI_DEVICE_ID_SUN_SIMBA 0x5000 -#define PCI_DEVICE_ID_SUN_PBM 0x8000 -#define PCI_DEVICE_ID_SUN_SCHIZO 0x8001 -#define PCI_DEVICE_ID_SUN_SABRE 0xa000 -#define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001 -#define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801 -#define PCI_DEVICE_ID_SUN_CASSINI 0xabba - -#define PCI_VENDOR_ID_CMD 0x1095 -#define PCI_DEVICE_ID_CMD_643 0x0643 -#define PCI_DEVICE_ID_CMD_646 0x0646 -#define PCI_DEVICE_ID_CMD_648 0x0648 -#define PCI_DEVICE_ID_CMD_649 0x0649 - -#define PCI_DEVICE_ID_SII_680 0x0680 -#define PCI_DEVICE_ID_SII_3112 0x3112 -#define PCI_DEVICE_ID_SII_1210SA 0x0240 - -#define PCI_VENDOR_ID_BROOKTREE 0x109e -#define PCI_DEVICE_ID_BROOKTREE_878 0x0878 -#define PCI_DEVICE_ID_BROOKTREE_879 0x0879 - -#define PCI_VENDOR_ID_SGI 0x10a9 -#define PCI_DEVICE_ID_SGI_IOC3 0x0003 -#define PCI_DEVICE_ID_SGI_LITHIUM 0x1002 -#define PCI_DEVICE_ID_SGI_IOC4 0x100a - -#define PCI_VENDOR_ID_WINBOND 0x10ad -#define PCI_DEVICE_ID_WINBOND_82C105 0x0105 -#define PCI_DEVICE_ID_WINBOND_83C553 0x0565 - -#define PCI_VENDOR_ID_PLX 0x10b5 -#define PCI_DEVICE_ID_PLX_R685 0x1030 -#define PCI_DEVICE_ID_PLX_ROMULUS 0x106a -#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076 -#define PCI_DEVICE_ID_PLX_1077 0x1077 -#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103 -#define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151 -#define PCI_DEVICE_ID_PLX_R753 0x1152 -#define PCI_DEVICE_ID_PLX_OLITEC 0x1187 -#define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196 -#define PCI_DEVICE_ID_PLX_9030 0x9030 -#define PCI_DEVICE_ID_PLX_9050 0x9050 -#define PCI_DEVICE_ID_PLX_9080 0x9080 -#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 - -#define PCI_VENDOR_ID_MADGE 0x10b6 -#define PCI_DEVICE_ID_MADGE_MK2 0x0002 - -#define PCI_VENDOR_ID_3COM 0x10b7 -#define PCI_DEVICE_ID_3COM_3C985 0x0001 -#define PCI_DEVICE_ID_3COM_3C940 0x1700 -#define PCI_DEVICE_ID_3COM_3C339 0x3390 -#define PCI_DEVICE_ID_3COM_3C359 0x3590 -#define PCI_DEVICE_ID_3COM_3C940B 0x80eb -#define PCI_DEVICE_ID_3COM_3CR990 0x9900 -#define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902 -#define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903 -#define PCI_DEVICE_ID_3COM_3CR990B 0x9904 -#define PCI_DEVICE_ID_3COM_3CR990_FX 0x9905 -#define PCI_DEVICE_ID_3COM_3CR990SVR95 0x9908 -#define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909 -#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a - -#define PCI_VENDOR_ID_AL 0x10b9 -#define PCI_DEVICE_ID_AL_M1533 0x1533 -#define PCI_DEVICE_ID_AL_M1535 0x1535 -#define PCI_DEVICE_ID_AL_M1541 0x1541 -#define PCI_DEVICE_ID_AL_M1563 0x1563 -#define PCI_DEVICE_ID_AL_M1621 0x1621 -#define PCI_DEVICE_ID_AL_M1631 0x1631 -#define PCI_DEVICE_ID_AL_M1632 0x1632 -#define PCI_DEVICE_ID_AL_M1641 0x1641 -#define PCI_DEVICE_ID_AL_M1644 0x1644 -#define PCI_DEVICE_ID_AL_M1647 0x1647 -#define PCI_DEVICE_ID_AL_M1651 0x1651 -#define PCI_DEVICE_ID_AL_M1671 0x1671 -#define PCI_DEVICE_ID_AL_M1681 0x1681 -#define PCI_DEVICE_ID_AL_M1683 0x1683 -#define PCI_DEVICE_ID_AL_M1689 0x1689 -#define PCI_DEVICE_ID_AL_M5219 0x5219 -#define PCI_DEVICE_ID_AL_M5228 0x5228 -#define PCI_DEVICE_ID_AL_M5229 0x5229 -#define PCI_DEVICE_ID_AL_M5451 0x5451 -#define PCI_DEVICE_ID_AL_M7101 0x7101 - -#define PCI_VENDOR_ID_NEOMAGIC 0x10c8 -#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 -#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 -#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016 - -#define PCI_VENDOR_ID_TCONRAD 0x10da -#define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508 - -#define PCI_VENDOR_ID_NVIDIA 0x10de -#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020 -#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028 -#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029 -#define PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN 0x002a -#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C -#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS 0x0034 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 -#define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 -#define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA 0x0040 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800 0x0041 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_LE 0x0042 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x0045 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_4000 0x004E -#define PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS 0x0052 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 -#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 -#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 -#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 -#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005d -#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 -#define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 -#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 -#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069 -#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a -#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS 0x0084 -#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 -#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086 -#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089 -#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a -#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c -#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT 0x0090 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX 0x0091 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800 0x0098 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX 0x0099 -#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0 -#define PCI_DEVICE_ID_GEFORCE_6800A 0x00c1 -#define PCI_DEVICE_ID_GEFORCE_6800A_LE 0x00c2 -#define PCI_DEVICE_ID_GEFORCE_GO_6800 0x00c8 -#define PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA 0x00c9 -#define PCI_DEVICE_ID_QUADRO_FX_GO1400 0x00cc -#define PCI_DEVICE_ID_QUADRO_FX_1400 0x00ce -#define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 -#define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4 -#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 -#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 -#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9 -#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da -#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df -#define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 -#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3 -#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS 0x00e4 -#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5 -#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6 -#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea -#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee -#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0 -#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1 0x00f1 -#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2 0x00f2 -#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1 0x00f3 -#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x00f9 -#define PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280 0x00fd -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101 -#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX 0x0110 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2 0x0111 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO 0x0112 -#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR 0x0113 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT 0x0140 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600 0x0141 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6610_XL 0x0145 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_540 0x014E -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6200 0x014F -#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS 0x0150 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152 -#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE 0x0161 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200 0x0164 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250 0x0166 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1 0x0167 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1 0x0168 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460 0x0170 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440 0x0171 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420 0x0172 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_SE 0x0173 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO 0x0174 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO 0x0175 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32 0x0176 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_460_GO 0x0177 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL 0x0178 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64 0x0179 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_200 0x017A -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL 0x017B -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL 0x017C -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_410_GO_M16 0x017D -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X 0x0181 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X 0x0182 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X 0x0183 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_4000 0x0185 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO 0x0186 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO 0x0187 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_580_XGL 0x0188 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_MAC 0x0189 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_280_NVS 0x018A -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_380_XGL 0x018B -#define PCI_DEVICE_ID_NVIDIA_IGEFORCE2 0x01a0 -#define PCI_DEVICE_ID_NVIDIA_NFORCE 0x01a4 -#define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO 0x01b1 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01b4 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc -#define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM 0x01c1 -#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3 -#define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B 0x0211 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE 0x0212 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT 0x0215 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600 0x0250 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400 0x0251 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200 0x0253 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS 0x0264 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS 0x0368 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F -#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 -#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO 0x0286 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_980_XGL 0x0288 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_780_XGL 0x0289 -#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700_GOGL 0x028C -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA 0x0301 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800 0x0302 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_2000 0x0308 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1000 0x0309 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA 0x0311 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600 0x0312 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600SE 0x0314 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5600 0x031A -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5650 0x031B -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO700 0x031C -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200 0x0320 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA 0x0321 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1 0x0322 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE 0x0323 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5200 0x0324 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250 0x0325 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5500 0x0326 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5100 0x0327 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250_32 0x0328 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200 0x0329 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_NVS_280_PCI 0x032A -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_500 0x032B -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5300 0x032C -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5100 0x032D -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA 0x0330 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900 0x0331 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT 0x0332 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA 0x0333 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900ZT 0x0334 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_3000 0x0338 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_700 0x033F -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA 0x0341 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700 0x0342 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700LE 0x0343 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE 0x0344 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_1 0x0347 -#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2 0x0348 -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000 0x034C -#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E -#define PCI_DEVICE_ID_NVIDIA_NVENET_14 0x0372 -#define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 -#define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5 -#define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS 0x03EB -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC -#define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE -#define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS 0x0446 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448 -#define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450 -#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451 -#define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452 -#define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453 -#define PCI_DEVICE_ID_NVIDIA_NVENET_24 0x054C -#define PCI_DEVICE_ID_NVIDIA_NVENET_25 0x054D -#define PCI_DEVICE_ID_NVIDIA_NVENET_26 0x054E -#define PCI_DEVICE_ID_NVIDIA_NVENET_27 0x054F -#define PCI_DEVICE_ID_NVIDIA_NVENET_28 0x07DC -#define PCI_DEVICE_ID_NVIDIA_NVENET_29 0x07DD -#define PCI_DEVICE_ID_NVIDIA_NVENET_30 0x07DE -#define PCI_DEVICE_ID_NVIDIA_NVENET_31 0x07DF -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560 -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE 0x056C -#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759 -#define PCI_DEVICE_ID_NVIDIA_NVENET_32 0x0760 -#define PCI_DEVICE_ID_NVIDIA_NVENET_33 0x0761 -#define PCI_DEVICE_ID_NVIDIA_NVENET_34 0x0762 -#define PCI_DEVICE_ID_NVIDIA_NVENET_35 0x0763 -#define PCI_DEVICE_ID_NVIDIA_NVENET_36 0x0AB0 -#define PCI_DEVICE_ID_NVIDIA_NVENET_37 0x0AB1 -#define PCI_DEVICE_ID_NVIDIA_NVENET_38 0x0AB2 -#define PCI_DEVICE_ID_NVIDIA_NVENET_39 0x0AB3 - -#define PCI_VENDOR_ID_IMS 0x10e0 -#define PCI_DEVICE_ID_IMS_TT128 0x9128 -#define PCI_DEVICE_ID_IMS_TT3D 0x9135 - -#define PCI_VENDOR_ID_INTERG 0x10ea -#define PCI_DEVICE_ID_INTERG_1682 0x1682 -#define PCI_DEVICE_ID_INTERG_2000 0x2000 -#define PCI_DEVICE_ID_INTERG_2010 0x2010 -#define PCI_DEVICE_ID_INTERG_5000 0x5000 -#define PCI_DEVICE_ID_INTERG_5050 0x5050 - -#define PCI_VENDOR_ID_REALTEK 0x10ec -#define PCI_DEVICE_ID_REALTEK_8139 0x8139 - -#define PCI_VENDOR_ID_XILINX 0x10ee -#define PCI_DEVICE_ID_RME_DIGI96 0x3fc0 -#define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1 -#define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2 -#define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3 -#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 -#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6 - -#define PCI_VENDOR_ID_INIT 0x1101 - -#define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */ -#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 - -#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */ -#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 - -#define PCI_VENDOR_ID_TTI 0x1103 -#define PCI_DEVICE_ID_TTI_HPT343 0x0003 -#define PCI_DEVICE_ID_TTI_HPT366 0x0004 -#define PCI_DEVICE_ID_TTI_HPT372 0x0005 -#define PCI_DEVICE_ID_TTI_HPT302 0x0006 -#define PCI_DEVICE_ID_TTI_HPT371 0x0007 -#define PCI_DEVICE_ID_TTI_HPT374 0x0008 -#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 /* apparently a 372N variant? */ - -#define PCI_VENDOR_ID_VIA 0x1106 -#define PCI_DEVICE_ID_VIA_8763_0 0x0198 -#define PCI_DEVICE_ID_VIA_8380_0 0x0204 -#define PCI_DEVICE_ID_VIA_3238_0 0x0238 -#define PCI_DEVICE_ID_VIA_PT880 0x0258 -#define PCI_DEVICE_ID_VIA_PT880ULTRA 0x0308 -#define PCI_DEVICE_ID_VIA_PX8X0_0 0x0259 -#define PCI_DEVICE_ID_VIA_3269_0 0x0269 -#define PCI_DEVICE_ID_VIA_K8T800PRO_0 0x0282 -#define PCI_DEVICE_ID_VIA_3296_0 0x0296 -#define PCI_DEVICE_ID_VIA_8363_0 0x0305 -#define PCI_DEVICE_ID_VIA_P4M800CE 0x0314 -#define PCI_DEVICE_ID_VIA_P4M890 0x0327 -#define PCI_DEVICE_ID_VIA_VT3324 0x0324 -#define PCI_DEVICE_ID_VIA_VT3336 0x0336 -#define PCI_DEVICE_ID_VIA_VT3351 0x0351 -#define PCI_DEVICE_ID_VIA_VT3364 0x0364 -#define PCI_DEVICE_ID_VIA_8371_0 0x0391 -#define PCI_DEVICE_ID_VIA_8501_0 0x0501 -#define PCI_DEVICE_ID_VIA_82C561 0x0561 -#define PCI_DEVICE_ID_VIA_82C586_1 0x0571 -#define PCI_DEVICE_ID_VIA_82C576 0x0576 -#define PCI_DEVICE_ID_VIA_82C586_0 0x0586 -#define PCI_DEVICE_ID_VIA_82C596 0x0596 -#define PCI_DEVICE_ID_VIA_82C597_0 0x0597 -#define PCI_DEVICE_ID_VIA_82C598_0 0x0598 -#define PCI_DEVICE_ID_VIA_8601_0 0x0601 -#define PCI_DEVICE_ID_VIA_8605_0 0x0605 -#define PCI_DEVICE_ID_VIA_82C686 0x0686 -#define PCI_DEVICE_ID_VIA_82C691_0 0x0691 -#define PCI_DEVICE_ID_VIA_82C576_1 0x1571 -#define PCI_DEVICE_ID_VIA_82C586_2 0x3038 -#define PCI_DEVICE_ID_VIA_82C586_3 0x3040 -#define PCI_DEVICE_ID_VIA_82C596_3 0x3050 -#define PCI_DEVICE_ID_VIA_82C596B_3 0x3051 -#define PCI_DEVICE_ID_VIA_82C686_4 0x3057 -#define PCI_DEVICE_ID_VIA_82C686_5 0x3058 -#define PCI_DEVICE_ID_VIA_8233_5 0x3059 -#define PCI_DEVICE_ID_VIA_8233_0 0x3074 -#define PCI_DEVICE_ID_VIA_8633_0 0x3091 -#define PCI_DEVICE_ID_VIA_8367_0 0x3099 -#define PCI_DEVICE_ID_VIA_8653_0 0x3101 -#define PCI_DEVICE_ID_VIA_8622 0x3102 -#define PCI_DEVICE_ID_VIA_8235_USB_2 0x3104 -#define PCI_DEVICE_ID_VIA_8233C_0 0x3109 -#define PCI_DEVICE_ID_VIA_8361 0x3112 -#define PCI_DEVICE_ID_VIA_XM266 0x3116 -#define PCI_DEVICE_ID_VIA_612X 0x3119 -#define PCI_DEVICE_ID_VIA_862X_0 0x3123 -#define PCI_DEVICE_ID_VIA_8753_0 0x3128 -#define PCI_DEVICE_ID_VIA_8233A 0x3147 -#define PCI_DEVICE_ID_VIA_8703_51_0 0x3148 -#define PCI_DEVICE_ID_VIA_8237_SATA 0x3149 -#define PCI_DEVICE_ID_VIA_XN266 0x3156 -#define PCI_DEVICE_ID_VIA_6410 0x3164 -#define PCI_DEVICE_ID_VIA_8754C_0 0x3168 -#define PCI_DEVICE_ID_VIA_8235 0x3177 -#define PCI_DEVICE_ID_VIA_8385_0 0x3188 -#define PCI_DEVICE_ID_VIA_8377_0 0x3189 -#define PCI_DEVICE_ID_VIA_8378_0 0x3205 -#define PCI_DEVICE_ID_VIA_8783_0 0x3208 -#define PCI_DEVICE_ID_VIA_8237 0x3227 -#define PCI_DEVICE_ID_VIA_8251 0x3287 -#define PCI_DEVICE_ID_VIA_8237A 0x3337 -#define PCI_DEVICE_ID_VIA_8237S 0x3372 -#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x5324 -#define PCI_DEVICE_ID_VIA_8231 0x8231 -#define PCI_DEVICE_ID_VIA_8231_4 0x8235 -#define PCI_DEVICE_ID_VIA_8365_1 0x8305 -#define PCI_DEVICE_ID_VIA_CX700 0x8324 -#define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581 -#define PCI_DEVICE_ID_VIA_VX800 0x8353 -#define PCI_DEVICE_ID_VIA_8371_1 0x8391 -#define PCI_DEVICE_ID_VIA_82C598_1 0x8598 -#define PCI_DEVICE_ID_VIA_838X_1 0xB188 -#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 - -#define PCI_VENDOR_ID_SIEMENS 0x110A -#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 - -#define PCI_VENDOR_ID_VORTEX 0x1119 -#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 -#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001 -#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002 -#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003 -#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004 -#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005 -#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006 -#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007 -#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008 -#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009 -#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a -#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b -#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c -#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d -#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100 -#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101 -#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102 -#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103 -#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104 -#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105 - -#define PCI_VENDOR_ID_EF 0x111a -#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 -#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002 -#define PCI_DEVICE_ID_EF_ATM_LANAI2 0x0003 -#define PCI_DEVICE_ID_EF_ATM_LANAIHB 0x0005 - -#define PCI_VENDOR_ID_IDT 0x111d -#define PCI_DEVICE_ID_IDT_IDT77201 0x0001 - -#define PCI_VENDOR_ID_FORE 0x1127 -#define PCI_DEVICE_ID_FORE_PCA200E 0x0300 - -#define PCI_VENDOR_ID_PHILIPS 0x1131 -#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146 -#define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730 - -#define PCI_VENDOR_ID_EICON 0x1133 -#define PCI_DEVICE_ID_EICON_DIVA20 0xe002 -#define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004 -#define PCI_DEVICE_ID_EICON_DIVA201 0xe005 -#define PCI_DEVICE_ID_EICON_DIVA202 0xe00b -#define PCI_DEVICE_ID_EICON_MAESTRA 0xe010 -#define PCI_DEVICE_ID_EICON_MAESTRAQ 0xe012 -#define PCI_DEVICE_ID_EICON_MAESTRAQ_U 0xe013 -#define PCI_DEVICE_ID_EICON_MAESTRAP 0xe014 - -#define PCI_VENDOR_ID_CISCO 0x1137 - -#define PCI_VENDOR_ID_ZIATECH 0x1138 -#define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550 - - -#define PCI_VENDOR_ID_SYSKONNECT 0x1148 -#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 -#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300 -#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320 -#define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400 -#define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500 - -#define PCI_VENDOR_ID_DIGI 0x114f -#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070 -#define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 -#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 -#define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073 -#define PCI_DEVICE_ID_NEO_2DB9 0x00C8 -#define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9 -#define PCI_DEVICE_ID_NEO_2RJ45 0x00CA -#define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB -#define PCIE_DEVICE_ID_NEO_4_IBM 0x00F4 - -#define PCI_VENDOR_ID_XIRCOM 0x115d -#define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101 -#define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103 - -#define PCI_VENDOR_ID_SERVERWORKS 0x1166 -#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 -#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 -#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 -#define PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB 0x0036 -#define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103 -#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 -#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 -#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 -#define PCI_DEVICE_ID_SERVERWORKS_HT1000SB 0x0205 -#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 -#define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212 -#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 -#define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 -#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 -#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 - -#define PCI_VENDOR_ID_SBE 0x1176 -#define PCI_DEVICE_ID_SBE_WANXL100 0x0301 -#define PCI_DEVICE_ID_SBE_WANXL200 0x0302 -#define PCI_DEVICE_ID_SBE_WANXL400 0x0104 - -#define PCI_VENDOR_ID_TOSHIBA 0x1179 -#define PCI_DEVICE_ID_TOSHIBA_PICCOLO 0x0102 -#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 0x0103 -#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 0x0105 -#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a -#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f -#define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617 - -#define PCI_VENDOR_ID_TOSHIBA_2 0x102f -#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 -#define PCI_DEVICE_ID_TOSHIBA_TC35815_NWU 0x0031 -#define PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939 0x0032 -#define PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE 0x0105 -#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 -#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 - -#define PCI_VENDOR_ID_ATTO 0x117c - -#define PCI_VENDOR_ID_RICOH 0x1180 -#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 -#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466 -#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475 -#define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 -#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 -#define PCI_DEVICE_ID_RICOH_R5C822 0x0822 -#define PCI_DEVICE_ID_RICOH_R5C832 0x0832 -#define PCI_DEVICE_ID_RICOH_R5C843 0x0843 - -#define PCI_VENDOR_ID_DLINK 0x1186 -#define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00 - -#define PCI_VENDOR_ID_ARTOP 0x1191 -#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 -#define PCI_DEVICE_ID_ARTOP_ATP860 0x0006 -#define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007 -#define PCI_DEVICE_ID_ARTOP_ATP865 0x0008 -#define PCI_DEVICE_ID_ARTOP_ATP865R 0x0009 -#define PCI_DEVICE_ID_ARTOP_AEC7610 0x8002 -#define PCI_DEVICE_ID_ARTOP_AEC7612UW 0x8010 -#define PCI_DEVICE_ID_ARTOP_AEC7612U 0x8020 -#define PCI_DEVICE_ID_ARTOP_AEC7612S 0x8030 -#define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040 -#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050 -#define PCI_DEVICE_ID_ARTOP_8060 0x8060 - -#define PCI_VENDOR_ID_ZEITNET 0x1193 -#define PCI_DEVICE_ID_ZEITNET_1221 0x0001 -#define PCI_DEVICE_ID_ZEITNET_1225 0x0002 - -#define PCI_VENDOR_ID_FUJITSU_ME 0x119e -#define PCI_DEVICE_ID_FUJITSU_FS155 0x0001 -#define PCI_DEVICE_ID_FUJITSU_FS50 0x0003 - -#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9 -#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334 - -#define PCI_VENDOR_ID_MARVELL 0x11ab -#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146 -#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 -#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 -#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 -#define PCI_DEVICE_ID_MARVELL_88ALP01_NAND 0x4100 -#define PCI_DEVICE_ID_MARVELL_88ALP01_SD 0x4101 -#define PCI_DEVICE_ID_MARVELL_88ALP01_CCIC 0x4102 - -#define PCI_VENDOR_ID_V3 0x11b0 -#define PCI_DEVICE_ID_V3_V960 0x0001 -#define PCI_DEVICE_ID_V3_V351 0x0002 - -#define PCI_VENDOR_ID_ATT 0x11c1 -#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480 - -#define PCI_VENDOR_ID_SPECIALIX 0x11cb -#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 -#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 -#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004 - -#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4 -#define PCI_DEVICE_ID_AD1889JS 0x1889 - -#define PCI_DEVICE_ID_SEGA_BBA 0x1234 - -#define PCI_VENDOR_ID_ZORAN 0x11de -#define PCI_DEVICE_ID_ZORAN_36057 0x6057 -#define PCI_DEVICE_ID_ZORAN_36120 0x6120 - -#define PCI_VENDOR_ID_COMPEX 0x11f6 -#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112 - -#define PCI_VENDOR_ID_RP 0x11fe -#define PCI_DEVICE_ID_RP32INTF 0x0001 -#define PCI_DEVICE_ID_RP8INTF 0x0002 -#define PCI_DEVICE_ID_RP16INTF 0x0003 -#define PCI_DEVICE_ID_RP4QUAD 0x0004 -#define PCI_DEVICE_ID_RP8OCTA 0x0005 -#define PCI_DEVICE_ID_RP8J 0x0006 -#define PCI_DEVICE_ID_RP4J 0x0007 -#define PCI_DEVICE_ID_RP8SNI 0x0008 -#define PCI_DEVICE_ID_RP16SNI 0x0009 -#define PCI_DEVICE_ID_RPP4 0x000A -#define PCI_DEVICE_ID_RPP8 0x000B -#define PCI_DEVICE_ID_RP4M 0x000D -#define PCI_DEVICE_ID_RP2_232 0x000E -#define PCI_DEVICE_ID_RP2_422 0x000F -#define PCI_DEVICE_ID_URP32INTF 0x0801 -#define PCI_DEVICE_ID_URP8INTF 0x0802 -#define PCI_DEVICE_ID_URP16INTF 0x0803 -#define PCI_DEVICE_ID_URP8OCTA 0x0805 -#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C -#define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D -#define PCI_DEVICE_ID_CRP16INTF 0x0903 - -#define PCI_VENDOR_ID_CYCLADES 0x120e -#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100 -#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101 -#define PCI_DEVICE_ID_CYCLOM_4Y_Lo 0x0102 -#define PCI_DEVICE_ID_CYCLOM_4Y_Hi 0x0103 -#define PCI_DEVICE_ID_CYCLOM_8Y_Lo 0x0104 -#define PCI_DEVICE_ID_CYCLOM_8Y_Hi 0x0105 -#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200 -#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201 -#define PCI_DEVICE_ID_PC300_RX_2 0x0300 -#define PCI_DEVICE_ID_PC300_RX_1 0x0301 -#define PCI_DEVICE_ID_PC300_TE_2 0x0310 -#define PCI_DEVICE_ID_PC300_TE_1 0x0311 -#define PCI_DEVICE_ID_PC300_TE_M_2 0x0320 -#define PCI_DEVICE_ID_PC300_TE_M_1 0x0321 - -#define PCI_VENDOR_ID_ESSENTIAL 0x120f -#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001 - -#define PCI_VENDOR_ID_O2 0x1217 -#define PCI_DEVICE_ID_O2_6729 0x6729 -#define PCI_DEVICE_ID_O2_6730 0x673a -#define PCI_DEVICE_ID_O2_6832 0x6832 -#define PCI_DEVICE_ID_O2_6836 0x6836 - -#define PCI_VENDOR_ID_3DFX 0x121a -#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 -#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002 -#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 -#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005 -#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 - -#define PCI_VENDOR_ID_AVM 0x1244 -#define PCI_DEVICE_ID_AVM_B1 0x0700 -#define PCI_DEVICE_ID_AVM_C4 0x0800 -#define PCI_DEVICE_ID_AVM_A1 0x0a00 -#define PCI_DEVICE_ID_AVM_A1_V2 0x0e00 -#define PCI_DEVICE_ID_AVM_C2 0x1100 -#define PCI_DEVICE_ID_AVM_T1 0x1200 - -#define PCI_VENDOR_ID_STALLION 0x124d - -/* Allied Telesyn */ -#define PCI_VENDOR_ID_AT 0x1259 -#define PCI_SUBDEVICE_ID_AT_2700FX 0x2701 -#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703 - -#define PCI_VENDOR_ID_ESS 0x125d -#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 -#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 -#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988 -#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989 -#define PCI_DEVICE_ID_ESS_CANYON3D_2LE 0x1990 -#define PCI_DEVICE_ID_ESS_CANYON3D_2 0x1992 -#define PCI_DEVICE_ID_ESS_MAESTRO3 0x1998 -#define PCI_DEVICE_ID_ESS_MAESTRO3_1 0x1999 -#define PCI_DEVICE_ID_ESS_MAESTRO3_HW 0x199a -#define PCI_DEVICE_ID_ESS_MAESTRO3_2 0x199b - -#define PCI_VENDOR_ID_SATSAGEM 0x1267 -#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016 - -#define PCI_VENDOR_ID_ENSONIQ 0x1274 -#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 -#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000 -#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 - -#define PCI_VENDOR_ID_TRANSMETA 0x1279 -#define PCI_DEVICE_ID_EFFICEON 0x0060 - -#define PCI_VENDOR_ID_ROCKWELL 0x127A - -#define PCI_VENDOR_ID_ITE 0x1283 -#define PCI_DEVICE_ID_ITE_8211 0x8211 -#define PCI_DEVICE_ID_ITE_8212 0x8212 -#define PCI_DEVICE_ID_ITE_8213 0x8213 -#define PCI_DEVICE_ID_ITE_8152 0x8152 -#define PCI_DEVICE_ID_ITE_8872 0x8872 -#define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886 - -/* formerly Platform Tech */ -#define PCI_DEVICE_ID_ESS_ESS0100 0x0100 - -#define PCI_VENDOR_ID_ALTEON 0x12ae - -#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232 0x0002 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232 0x0003 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485 0x0004 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4 0x0005 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485 0x0006 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2 0x0007 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485 0x0008 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6 0x0009 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ 0x000C -#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_PTM 0x000D -#define PCI_SUBDEVICE_ID_CONNECT_TECH_NT960PCI 0x0100 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2 0x0201 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4 0x0202 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232 0x0300 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232 0x0301 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232 0x0302 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1 0x0310 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2 0x0311 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4 0x0312 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2 0x0320 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4 0x0321 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8 0x0322 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485 0x0330 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485 0x0331 -#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485 0x0332 - -#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 -#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018 - -#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0 -#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031 -#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021 -#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16 0x0011 -#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC 0x0041 -#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D -#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4 0xF001 -#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8 0xF010 - -#define PCI_VENDOR_ID_AUREAL 0x12eb -#define PCI_DEVICE_ID_AUREAL_VORTEX_1 0x0001 -#define PCI_DEVICE_ID_AUREAL_VORTEX_2 0x0002 -#define PCI_DEVICE_ID_AUREAL_ADVANTAGE 0x0003 - -#define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8 -#define PCI_DEVICE_ID_LML_33R10 0x8a02 - -#define PCI_VENDOR_ID_ESDGMBH 0x12fe -#define PCI_DEVICE_ID_ESDGMBH_CPCIASIO4 0x0111 - -#define PCI_VENDOR_ID_SIIG 0x131f -#define PCI_SUBVENDOR_ID_SIIG 0x131f -#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000 -#define PCI_DEVICE_ID_SIIG_1S_10x_650 0x1001 -#define PCI_DEVICE_ID_SIIG_1S_10x_850 0x1002 -#define PCI_DEVICE_ID_SIIG_1S1P_10x_550 0x1010 -#define PCI_DEVICE_ID_SIIG_1S1P_10x_650 0x1011 -#define PCI_DEVICE_ID_SIIG_1S1P_10x_850 0x1012 -#define PCI_DEVICE_ID_SIIG_1P_10x 0x1020 -#define PCI_DEVICE_ID_SIIG_2P_10x 0x1021 -#define PCI_DEVICE_ID_SIIG_2S_10x_550 0x1030 -#define PCI_DEVICE_ID_SIIG_2S_10x_650 0x1031 -#define PCI_DEVICE_ID_SIIG_2S_10x_850 0x1032 -#define PCI_DEVICE_ID_SIIG_2S1P_10x_550 0x1034 -#define PCI_DEVICE_ID_SIIG_2S1P_10x_650 0x1035 -#define PCI_DEVICE_ID_SIIG_2S1P_10x_850 0x1036 -#define PCI_DEVICE_ID_SIIG_4S_10x_550 0x1050 -#define PCI_DEVICE_ID_SIIG_4S_10x_650 0x1051 -#define PCI_DEVICE_ID_SIIG_4S_10x_850 0x1052 -#define PCI_DEVICE_ID_SIIG_1S_20x_550 0x2000 -#define PCI_DEVICE_ID_SIIG_1S_20x_650 0x2001 -#define PCI_DEVICE_ID_SIIG_1S_20x_850 0x2002 -#define PCI_DEVICE_ID_SIIG_1P_20x 0x2020 -#define PCI_DEVICE_ID_SIIG_2P_20x 0x2021 -#define PCI_DEVICE_ID_SIIG_2S_20x_550 0x2030 -#define PCI_DEVICE_ID_SIIG_2S_20x_650 0x2031 -#define PCI_DEVICE_ID_SIIG_2S_20x_850 0x2032 -#define PCI_DEVICE_ID_SIIG_2P1S_20x_550 0x2040 -#define PCI_DEVICE_ID_SIIG_2P1S_20x_650 0x2041 -#define PCI_DEVICE_ID_SIIG_2P1S_20x_850 0x2042 -#define PCI_DEVICE_ID_SIIG_1S1P_20x_550 0x2010 -#define PCI_DEVICE_ID_SIIG_1S1P_20x_650 0x2011 -#define PCI_DEVICE_ID_SIIG_1S1P_20x_850 0x2012 -#define PCI_DEVICE_ID_SIIG_4S_20x_550 0x2050 -#define PCI_DEVICE_ID_SIIG_4S_20x_650 0x2051 -#define PCI_DEVICE_ID_SIIG_4S_20x_850 0x2052 -#define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060 -#define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061 -#define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 -#define PCI_DEVICE_ID_SIIG_8S_20x_550 0x2080 -#define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081 -#define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082 -#define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 - -#define PCI_VENDOR_ID_RADISYS 0x1331 - -#define PCI_VENDOR_ID_MICRO_MEMORY 0x1332 -#define PCI_DEVICE_ID_MICRO_MEMORY_5415CN 0x5415 -#define PCI_DEVICE_ID_MICRO_MEMORY_5425CN 0x5425 -#define PCI_DEVICE_ID_MICRO_MEMORY_6155 0x6155 - -#define PCI_VENDOR_ID_DOMEX 0x134a -#define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 - -#define PCI_VENDOR_ID_INTASHIELD 0x135a -#define PCI_DEVICE_ID_INTASHIELD_IS200 0x0d80 -#define PCI_DEVICE_ID_INTASHIELD_IS400 0x0dc0 - -#define PCI_VENDOR_ID_QUATECH 0x135C -#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 -#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 -#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 -#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 -#define PCI_DEVICE_ID_QUATECH_SPPXP_100 0x0278 - -#define PCI_VENDOR_ID_SEALEVEL 0x135e -#define PCI_DEVICE_ID_SEALEVEL_U530 0x7101 -#define PCI_DEVICE_ID_SEALEVEL_UCOMM2 0x7201 -#define PCI_DEVICE_ID_SEALEVEL_UCOMM422 0x7402 -#define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202 -#define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401 -#define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801 -#define PCI_DEVICE_ID_SEALEVEL_UCOMM8 0x7804 - -#define PCI_VENDOR_ID_HYPERCOPE 0x1365 -#define PCI_DEVICE_ID_HYPERCOPE_PLX 0x9050 -#define PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO 0x0104 -#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106 -#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107 -#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108 - -#define PCI_VENDOR_ID_KAWASAKI 0x136b -#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 - -#define PCI_VENDOR_ID_CNET 0x1371 -#define PCI_DEVICE_ID_CNET_GIGACARD 0x434e - -#define PCI_VENDOR_ID_LMC 0x1376 -#define PCI_DEVICE_ID_LMC_HSSI 0x0003 -#define PCI_DEVICE_ID_LMC_DS3 0x0004 -#define PCI_DEVICE_ID_LMC_SSI 0x0005 -#define PCI_DEVICE_ID_LMC_T1 0x0006 - -#define PCI_VENDOR_ID_NETGEAR 0x1385 -#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a - -#define PCI_VENDOR_ID_APPLICOM 0x1389 -#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001 -#define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002 -#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003 - -#define PCI_VENDOR_ID_MOXA 0x1393 -#define PCI_DEVICE_ID_MOXA_RC7000 0x0001 -#define PCI_DEVICE_ID_MOXA_CP102 0x1020 -#define PCI_DEVICE_ID_MOXA_CP102UL 0x1021 -#define PCI_DEVICE_ID_MOXA_CP102U 0x1022 -#define PCI_DEVICE_ID_MOXA_C104 0x1040 -#define PCI_DEVICE_ID_MOXA_CP104U 0x1041 -#define PCI_DEVICE_ID_MOXA_CP104JU 0x1042 -#define PCI_DEVICE_ID_MOXA_CP104EL 0x1043 -#define PCI_DEVICE_ID_MOXA_CT114 0x1140 -#define PCI_DEVICE_ID_MOXA_CP114 0x1141 -#define PCI_DEVICE_ID_MOXA_CP118U 0x1180 -#define PCI_DEVICE_ID_MOXA_CP118EL 0x1181 -#define PCI_DEVICE_ID_MOXA_CP132 0x1320 -#define PCI_DEVICE_ID_MOXA_CP132U 0x1321 -#define PCI_DEVICE_ID_MOXA_CP134U 0x1340 -#define PCI_DEVICE_ID_MOXA_C168 0x1680 -#define PCI_DEVICE_ID_MOXA_CP168U 0x1681 -#define PCI_DEVICE_ID_MOXA_CP168EL 0x1682 -#define PCI_DEVICE_ID_MOXA_CP204J 0x2040 -#define PCI_DEVICE_ID_MOXA_C218 0x2180 -#define PCI_DEVICE_ID_MOXA_C320 0x3200 - -#define PCI_VENDOR_ID_CCD 0x1397 -#define PCI_DEVICE_ID_CCD_HFC4S 0x08B4 -#define PCI_SUBDEVICE_ID_CCD_PMX2S 0x1234 -#define PCI_DEVICE_ID_CCD_HFC8S 0x16B8 -#define PCI_DEVICE_ID_CCD_2BD0 0x2bd0 -#define PCI_DEVICE_ID_CCD_HFCE1 0x30B1 -#define PCI_SUBDEVICE_ID_CCD_SPD4S 0x3136 -#define PCI_SUBDEVICE_ID_CCD_SPDE1 0x3137 -#define PCI_DEVICE_ID_CCD_B000 0xb000 -#define PCI_DEVICE_ID_CCD_B006 0xb006 -#define PCI_DEVICE_ID_CCD_B007 0xb007 -#define PCI_DEVICE_ID_CCD_B008 0xb008 -#define PCI_DEVICE_ID_CCD_B009 0xb009 -#define PCI_DEVICE_ID_CCD_B00A 0xb00a -#define PCI_DEVICE_ID_CCD_B00B 0xb00b -#define PCI_DEVICE_ID_CCD_B00C 0xb00c -#define PCI_DEVICE_ID_CCD_B100 0xb100 -#define PCI_SUBDEVICE_ID_CCD_IOB4ST 0xB520 -#define PCI_SUBDEVICE_ID_CCD_IOB8STR 0xB521 -#define PCI_SUBDEVICE_ID_CCD_IOB8ST 0xB522 -#define PCI_SUBDEVICE_ID_CCD_IOB1E1 0xB523 -#define PCI_SUBDEVICE_ID_CCD_SWYX4S 0xB540 -#define PCI_SUBDEVICE_ID_CCD_JH4S20 0xB550 -#define PCI_SUBDEVICE_ID_CCD_IOB8ST_1 0xB552 -#define PCI_SUBDEVICE_ID_CCD_BN4S 0xB560 -#define PCI_SUBDEVICE_ID_CCD_BN8S 0xB562 -#define PCI_SUBDEVICE_ID_CCD_BNE1 0xB563 -#define PCI_SUBDEVICE_ID_CCD_BNE1D 0xB564 -#define PCI_SUBDEVICE_ID_CCD_BNE1DP 0xB565 -#define PCI_SUBDEVICE_ID_CCD_BN2S 0xB566 -#define PCI_SUBDEVICE_ID_CCD_BN1SM 0xB567 -#define PCI_SUBDEVICE_ID_CCD_BN4SM 0xB568 -#define PCI_SUBDEVICE_ID_CCD_BN2SM 0xB569 -#define PCI_SUBDEVICE_ID_CCD_BNE1M 0xB56A -#define PCI_SUBDEVICE_ID_CCD_BN8SP 0xB56B -#define PCI_SUBDEVICE_ID_CCD_HFC4S 0xB620 -#define PCI_SUBDEVICE_ID_CCD_HFC8S 0xB622 -#define PCI_DEVICE_ID_CCD_B700 0xb700 -#define PCI_DEVICE_ID_CCD_B701 0xb701 -#define PCI_SUBDEVICE_ID_CCD_HFCE1 0xC523 -#define PCI_SUBDEVICE_ID_CCD_OV2S 0xE884 -#define PCI_SUBDEVICE_ID_CCD_OV4S 0xE888 -#define PCI_SUBDEVICE_ID_CCD_OV8S 0xE998 - -#define PCI_VENDOR_ID_EXAR 0x13a8 -#define PCI_DEVICE_ID_EXAR_XR17C152 0x0152 -#define PCI_DEVICE_ID_EXAR_XR17C154 0x0154 -#define PCI_DEVICE_ID_EXAR_XR17C158 0x0158 - -#define PCI_VENDOR_ID_MICROGATE 0x13c0 -#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 -#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 - -#define PCI_VENDOR_ID_3WARE 0x13C1 -#define PCI_DEVICE_ID_3WARE_1000 0x1000 -#define PCI_DEVICE_ID_3WARE_7000 0x1001 -#define PCI_DEVICE_ID_3WARE_9000 0x1002 - -#define PCI_VENDOR_ID_IOMEGA 0x13ca -#define PCI_DEVICE_ID_IOMEGA_BUZ 0x4231 - -#define PCI_VENDOR_ID_ABOCOM 0x13D1 -#define PCI_DEVICE_ID_ABOCOM_2BD1 0x2BD1 - -#define PCI_VENDOR_ID_SUNDANCE 0x13f0 - -#define PCI_VENDOR_ID_CMEDIA 0x13f6 -#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100 -#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101 -#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111 -#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112 - -#define PCI_VENDOR_ID_LAVA 0x1407 -#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */ -#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */ -#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */ -#define PCI_DEVICE_ID_LAVA_OCTO_A 0x0180 /* 4x 16550A, half of 8 port */ -#define PCI_DEVICE_ID_LAVA_OCTO_B 0x0181 /* 4x 16550A, half of 8 port */ -#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */ -#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */ -#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */ -#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */ -#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */ -#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000 -#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */ -#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */ -#define PCI_DEVICE_ID_LAVA_BOCA_IOPPAR 0x8800 - -#define PCI_VENDOR_ID_TIMEDIA 0x1409 -#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168 - -#define PCI_VENDOR_ID_ICE 0x1412 -#define PCI_DEVICE_ID_ICE_1712 0x1712 -#define PCI_DEVICE_ID_VT1724 0x1724 - -#define PCI_VENDOR_ID_OXSEMI 0x1415 -#define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403 -#define PCI_DEVICE_ID_OXSEMI_PCIe840 0xC000 -#define PCI_DEVICE_ID_OXSEMI_PCIe840_G 0xC004 -#define PCI_DEVICE_ID_OXSEMI_PCIe952_0 0xC100 -#define PCI_DEVICE_ID_OXSEMI_PCIe952_0_G 0xC104 -#define PCI_DEVICE_ID_OXSEMI_PCIe952_1 0xC110 -#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_G 0xC114 -#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_U 0xC118 -#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU 0xC11C -#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501 -#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 -#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513 -#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521 -#define PCI_DEVICE_ID_OXSEMI_16PCI952PP 0x9523 - -#define PCI_VENDOR_ID_CHELSIO 0x1425 - -#define PCI_VENDOR_ID_SAMSUNG 0x144d - -#define PCI_VENDOR_ID_MYRICOM 0x14c1 - -#define PCI_VENDOR_ID_TITAN 0x14D2 -#define PCI_DEVICE_ID_TITAN_010L 0x8001 -#define PCI_DEVICE_ID_TITAN_100L 0x8010 -#define PCI_DEVICE_ID_TITAN_110L 0x8011 -#define PCI_DEVICE_ID_TITAN_200L 0x8020 -#define PCI_DEVICE_ID_TITAN_210L 0x8021 -#define PCI_DEVICE_ID_TITAN_400L 0x8040 -#define PCI_DEVICE_ID_TITAN_800L 0x8080 -#define PCI_DEVICE_ID_TITAN_100 0xA001 -#define PCI_DEVICE_ID_TITAN_200 0xA005 -#define PCI_DEVICE_ID_TITAN_400 0xA003 -#define PCI_DEVICE_ID_TITAN_800B 0xA004 - -#define PCI_VENDOR_ID_PANACOM 0x14d4 -#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 -#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402 - -#define PCI_VENDOR_ID_SIPACKETS 0x14d9 -#define PCI_DEVICE_ID_SP1011 0x0010 - -#define PCI_VENDOR_ID_AFAVLAB 0x14db -#define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 -#define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 -#define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 - -#define PCI_VENDOR_ID_BROADCOM 0x14e4 -#define PCI_DEVICE_ID_TIGON3_5752 0x1600 -#define PCI_DEVICE_ID_TIGON3_5752M 0x1601 -#define PCI_DEVICE_ID_NX2_5709 0x1639 -#define PCI_DEVICE_ID_NX2_5709S 0x163a -#define PCI_DEVICE_ID_TIGON3_5700 0x1644 -#define PCI_DEVICE_ID_TIGON3_5701 0x1645 -#define PCI_DEVICE_ID_TIGON3_5702 0x1646 -#define PCI_DEVICE_ID_TIGON3_5703 0x1647 -#define PCI_DEVICE_ID_TIGON3_5704 0x1648 -#define PCI_DEVICE_ID_TIGON3_5704S_2 0x1649 -#define PCI_DEVICE_ID_NX2_5706 0x164a -#define PCI_DEVICE_ID_NX2_5708 0x164c -#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d -#define PCI_DEVICE_ID_NX2_57710 0x164e -#define PCI_DEVICE_ID_NX2_57711 0x164f -#define PCI_DEVICE_ID_NX2_57711E 0x1650 -#define PCI_DEVICE_ID_TIGON3_5705 0x1653 -#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654 -#define PCI_DEVICE_ID_TIGON3_5720 0x1658 -#define PCI_DEVICE_ID_TIGON3_5721 0x1659 -#define PCI_DEVICE_ID_TIGON3_5722 0x165a -#define PCI_DEVICE_ID_TIGON3_5723 0x165b -#define PCI_DEVICE_ID_TIGON3_5705M 0x165d -#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e -#define PCI_DEVICE_ID_TIGON3_5714 0x1668 -#define PCI_DEVICE_ID_TIGON3_5714S 0x1669 -#define PCI_DEVICE_ID_TIGON3_5780 0x166a -#define PCI_DEVICE_ID_TIGON3_5780S 0x166b -#define PCI_DEVICE_ID_TIGON3_5705F 0x166e -#define PCI_DEVICE_ID_TIGON3_5754M 0x1672 -#define PCI_DEVICE_ID_TIGON3_5755M 0x1673 -#define PCI_DEVICE_ID_TIGON3_5756 0x1674 -#define PCI_DEVICE_ID_TIGON3_5750 0x1676 -#define PCI_DEVICE_ID_TIGON3_5751 0x1677 -#define PCI_DEVICE_ID_TIGON3_5715 0x1678 -#define PCI_DEVICE_ID_TIGON3_5715S 0x1679 -#define PCI_DEVICE_ID_TIGON3_5754 0x167a -#define PCI_DEVICE_ID_TIGON3_5755 0x167b -#define PCI_DEVICE_ID_TIGON3_5750M 0x167c -#define PCI_DEVICE_ID_TIGON3_5751M 0x167d -#define PCI_DEVICE_ID_TIGON3_5751F 0x167e -#define PCI_DEVICE_ID_TIGON3_5787F 0x167f -#define PCI_DEVICE_ID_TIGON3_5761E 0x1680 -#define PCI_DEVICE_ID_TIGON3_5761 0x1681 -#define PCI_DEVICE_ID_TIGON3_5764 0x1684 -#define PCI_DEVICE_ID_TIGON3_5787M 0x1693 -#define PCI_DEVICE_ID_TIGON3_5782 0x1696 -#define PCI_DEVICE_ID_TIGON3_5784 0x1698 -#define PCI_DEVICE_ID_TIGON3_5785 0x1699 -#define PCI_DEVICE_ID_TIGON3_5786 0x169a -#define PCI_DEVICE_ID_TIGON3_5787 0x169b -#define PCI_DEVICE_ID_TIGON3_5788 0x169c -#define PCI_DEVICE_ID_TIGON3_5789 0x169d -#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 -#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 -#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 -#define PCI_DEVICE_ID_NX2_5706S 0x16aa -#define PCI_DEVICE_ID_NX2_5708S 0x16ac -#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6 -#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7 -#define PCI_DEVICE_ID_TIGON3_5781 0x16dd -#define PCI_DEVICE_ID_TIGON3_5753 0x16f7 -#define PCI_DEVICE_ID_TIGON3_5753M 0x16fd -#define PCI_DEVICE_ID_TIGON3_5753F 0x16fe -#define PCI_DEVICE_ID_TIGON3_5901 0x170d -#define PCI_DEVICE_ID_BCM4401B1 0x170c -#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e -#define PCI_DEVICE_ID_TIGON3_5906 0x1712 -#define PCI_DEVICE_ID_TIGON3_5906M 0x1713 -#define PCI_DEVICE_ID_BCM4401 0x4401 -#define PCI_DEVICE_ID_BCM4401B0 0x4402 - -#define PCI_VENDOR_ID_TOPIC 0x151f -#define PCI_DEVICE_ID_TOPIC_TP560 0x0000 - -#define PCI_VENDOR_ID_MAINPINE 0x1522 -#define PCI_DEVICE_ID_MAINPINE_PBRIDGE 0x0100 -#define PCI_VENDOR_ID_ENE 0x1524 -#define PCI_DEVICE_ID_ENE_CB712_SD 0x0550 -#define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551 -#define PCI_DEVICE_ID_ENE_CB714_SD 0x0750 -#define PCI_DEVICE_ID_ENE_CB714_SD_2 0x0751 -#define PCI_DEVICE_ID_ENE_1211 0x1211 -#define PCI_DEVICE_ID_ENE_1225 0x1225 -#define PCI_DEVICE_ID_ENE_1410 0x1410 -#define PCI_DEVICE_ID_ENE_710 0x1411 -#define PCI_DEVICE_ID_ENE_712 0x1412 -#define PCI_DEVICE_ID_ENE_1420 0x1420 -#define PCI_DEVICE_ID_ENE_720 0x1421 -#define PCI_DEVICE_ID_ENE_722 0x1422 - -#define PCI_SUBVENDOR_ID_PERLE 0x155f -#define PCI_SUBDEVICE_ID_PCI_RAS4 0xf001 -#define PCI_SUBDEVICE_ID_PCI_RAS8 0xf010 - -#define PCI_VENDOR_ID_SYBA 0x1592 -#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782 -#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783 - -#define PCI_VENDOR_ID_MORETON 0x15aa -#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 - -#define PCI_VENDOR_ID_ZOLTRIX 0x15b0 -#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 - -#define PCI_VENDOR_ID_MELLANOX 0x15b3 -#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 -#define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46 -#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278 -#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282 -#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c -#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 - -#define PCI_VENDOR_ID_QUICKNET 0x15e2 -#define PCI_DEVICE_ID_QUICKNET_XJ 0x0500 - -/* - * ADDI-DATA GmbH communication cards - */ -#define PCI_VENDOR_ID_ADDIDATA_OLD 0x10E8 -#define PCI_VENDOR_ID_ADDIDATA 0x15B8 -#define PCI_DEVICE_ID_ADDIDATA_APCI7500 0x7000 -#define PCI_DEVICE_ID_ADDIDATA_APCI7420 0x7001 -#define PCI_DEVICE_ID_ADDIDATA_APCI7300 0x7002 -#define PCI_DEVICE_ID_ADDIDATA_APCI7800 0x818E -#define PCI_DEVICE_ID_ADDIDATA_APCI7500_2 0x7009 -#define PCI_DEVICE_ID_ADDIDATA_APCI7420_2 0x700A -#define PCI_DEVICE_ID_ADDIDATA_APCI7300_2 0x700B -#define PCI_DEVICE_ID_ADDIDATA_APCI7500_3 0x700C -#define PCI_DEVICE_ID_ADDIDATA_APCI7420_3 0x700D -#define PCI_DEVICE_ID_ADDIDATA_APCI7300_3 0x700E -#define PCI_DEVICE_ID_ADDIDATA_APCI7800_3 0x700F - -#define PCI_VENDOR_ID_PDC 0x15e9 - -#define PCI_VENDOR_ID_FARSITE 0x1619 -#define PCI_DEVICE_ID_FARSITE_T2P 0x0400 -#define PCI_DEVICE_ID_FARSITE_T4P 0x0440 -#define PCI_DEVICE_ID_FARSITE_T1U 0x0610 -#define PCI_DEVICE_ID_FARSITE_T2U 0x0620 -#define PCI_DEVICE_ID_FARSITE_T4U 0x0640 -#define PCI_DEVICE_ID_FARSITE_TE1 0x1610 -#define PCI_DEVICE_ID_FARSITE_TE1C 0x1612 - -#define PCI_VENDOR_ID_ARIMA 0x161f - -#define PCI_VENDOR_ID_BROCADE 0x1657 - -#define PCI_VENDOR_ID_SIBYTE 0x166d -#define PCI_DEVICE_ID_BCM1250_PCI 0x0001 -#define PCI_DEVICE_ID_BCM1250_HT 0x0002 - -#define PCI_VENDOR_ID_ATHEROS 0x168c - -#define PCI_VENDOR_ID_NETCELL 0x169c -#define PCI_DEVICE_ID_REVOLUTION 0x0044 - -#define PCI_VENDOR_ID_CENATEK 0x16CA -#define PCI_DEVICE_ID_CENATEK_IDE 0x0001 - -#define PCI_VENDOR_ID_VITESSE 0x1725 -#define PCI_DEVICE_ID_VITESSE_VSC7174 0x7174 - -#define PCI_VENDOR_ID_LINKSYS 0x1737 -#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 - -#define PCI_VENDOR_ID_ALTIMA 0x173b -#define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8 -#define PCI_DEVICE_ID_ALTIMA_AC1001 0x03e9 -#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea -#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb - -#define PCI_VENDOR_ID_BELKIN 0x1799 -#define PCI_DEVICE_ID_BELKIN_F5D7010V7 0x701f - -#define PCI_VENDOR_ID_RDC 0x17f3 -#define PCI_DEVICE_ID_RDC_R6020 0x6020 -#define PCI_DEVICE_ID_RDC_R6030 0x6030 -#define PCI_DEVICE_ID_RDC_R6040 0x6040 -#define PCI_DEVICE_ID_RDC_R6060 0x6060 -#define PCI_DEVICE_ID_RDC_R6061 0x6061 - -#define PCI_VENDOR_ID_LENOVO 0x17aa - -#define PCI_VENDOR_ID_ARECA 0x17d3 -#define PCI_DEVICE_ID_ARECA_1110 0x1110 -#define PCI_DEVICE_ID_ARECA_1120 0x1120 -#define PCI_DEVICE_ID_ARECA_1130 0x1130 -#define PCI_DEVICE_ID_ARECA_1160 0x1160 -#define PCI_DEVICE_ID_ARECA_1170 0x1170 -#define PCI_DEVICE_ID_ARECA_1200 0x1200 -#define PCI_DEVICE_ID_ARECA_1201 0x1201 -#define PCI_DEVICE_ID_ARECA_1202 0x1202 -#define PCI_DEVICE_ID_ARECA_1210 0x1210 -#define PCI_DEVICE_ID_ARECA_1220 0x1220 -#define PCI_DEVICE_ID_ARECA_1230 0x1230 -#define PCI_DEVICE_ID_ARECA_1260 0x1260 -#define PCI_DEVICE_ID_ARECA_1270 0x1270 -#define PCI_DEVICE_ID_ARECA_1280 0x1280 -#define PCI_DEVICE_ID_ARECA_1380 0x1380 -#define PCI_DEVICE_ID_ARECA_1381 0x1381 -#define PCI_DEVICE_ID_ARECA_1680 0x1680 -#define PCI_DEVICE_ID_ARECA_1681 0x1681 - -#define PCI_VENDOR_ID_S2IO 0x17d5 -#define PCI_DEVICE_ID_S2IO_WIN 0x5731 -#define PCI_DEVICE_ID_S2IO_UNI 0x5831 -#define PCI_DEVICE_ID_HERC_WIN 0x5732 -#define PCI_DEVICE_ID_HERC_UNI 0x5832 - -#define PCI_VENDOR_ID_SITECOM 0x182d -#define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069 - -#define PCI_VENDOR_ID_TOPSPIN 0x1867 - -#define PCI_VENDOR_ID_TDI 0x192E -#define PCI_DEVICE_ID_TDI_EHCI 0x0101 - -#define PCI_VENDOR_ID_FREESCALE 0x1957 -#define PCI_DEVICE_ID_MPC8548E 0x0012 -#define PCI_DEVICE_ID_MPC8548 0x0013 -#define PCI_DEVICE_ID_MPC8543E 0x0014 -#define PCI_DEVICE_ID_MPC8543 0x0015 -#define PCI_DEVICE_ID_MPC8547E 0x0018 -#define PCI_DEVICE_ID_MPC8545E 0x0019 -#define PCI_DEVICE_ID_MPC8545 0x001a -#define PCI_DEVICE_ID_MPC8568E 0x0020 -#define PCI_DEVICE_ID_MPC8568 0x0021 -#define PCI_DEVICE_ID_MPC8567E 0x0022 -#define PCI_DEVICE_ID_MPC8567 0x0023 -#define PCI_DEVICE_ID_MPC8533E 0x0030 -#define PCI_DEVICE_ID_MPC8533 0x0031 -#define PCI_DEVICE_ID_MPC8544E 0x0032 -#define PCI_DEVICE_ID_MPC8544 0x0033 -#define PCI_DEVICE_ID_MPC8572E 0x0040 -#define PCI_DEVICE_ID_MPC8572 0x0041 -#define PCI_DEVICE_ID_MPC8536E 0x0050 -#define PCI_DEVICE_ID_MPC8536 0x0051 -#define PCI_DEVICE_ID_MPC8641 0x7010 -#define PCI_DEVICE_ID_MPC8641D 0x7011 -#define PCI_DEVICE_ID_MPC8610 0x7018 - -#define PCI_VENDOR_ID_PASEMI 0x1959 - -#define PCI_VENDOR_ID_ATTANSIC 0x1969 -#define PCI_DEVICE_ID_ATTANSIC_L1 0x1048 -#define PCI_DEVICE_ID_ATTANSIC_L2 0x2048 - -#define PCI_VENDOR_ID_JMICRON 0x197B -#define PCI_DEVICE_ID_JMICRON_JMB360 0x2360 -#define PCI_DEVICE_ID_JMICRON_JMB361 0x2361 -#define PCI_DEVICE_ID_JMICRON_JMB363 0x2363 -#define PCI_DEVICE_ID_JMICRON_JMB365 0x2365 -#define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 -#define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 -#define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 -#define PCI_DEVICE_ID_JMICRON_JMB38X_MMC 0x2382 -#define PCI_DEVICE_ID_JMICRON_JMB38X_MS 0x2383 - -#define PCI_VENDOR_ID_KORENIX 0x1982 -#define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 -#define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff - -#define PCI_VENDOR_ID_TEKRAM 0x1de1 -#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 - -#define PCI_VENDOR_ID_TEHUTI 0x1fc9 -#define PCI_DEVICE_ID_TEHUTI_3009 0x3009 -#define PCI_DEVICE_ID_TEHUTI_3010 0x3010 -#define PCI_DEVICE_ID_TEHUTI_3014 0x3014 - -#define PCI_VENDOR_ID_HINT 0x3388 -#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013 - -#define PCI_VENDOR_ID_3DLABS 0x3d3d -#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007 -#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009 - -#define PCI_VENDOR_ID_NETXEN 0x4040 -#define PCI_DEVICE_ID_NX2031_10GXSR 0x0001 -#define PCI_DEVICE_ID_NX2031_10GCX4 0x0002 -#define PCI_DEVICE_ID_NX2031_4GCU 0x0003 -#define PCI_DEVICE_ID_NX2031_IMEZ 0x0004 -#define PCI_DEVICE_ID_NX2031_HMEZ 0x0005 -#define PCI_DEVICE_ID_NX2031_XG_MGMT 0x0024 -#define PCI_DEVICE_ID_NX2031_XG_MGMT2 0x0025 -#define PCI_DEVICE_ID_NX3031 0x0100 - -#define PCI_VENDOR_ID_AKS 0x416c -#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100 - -#define PCI_VENDOR_ID_S3 0x5333 -#define PCI_DEVICE_ID_S3_TRIO 0x8811 -#define PCI_DEVICE_ID_S3_868 0x8880 -#define PCI_DEVICE_ID_S3_968 0x88f0 -#define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25 -#define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04 -#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 - -#define PCI_VENDOR_ID_DUNORD 0x5544 -#define PCI_DEVICE_ID_DUNORD_I3000 0x0001 - -#define PCI_VENDOR_ID_DCI 0x6666 -#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 -#define PCI_DEVICE_ID_DCI_PCCOM8 0x0002 -#define PCI_DEVICE_ID_DCI_PCCOM2 0x0004 - -#define PCI_VENDOR_ID_INTEL 0x8086 -#define PCI_DEVICE_ID_INTEL_EESSC 0x0008 -#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 -#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 -#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 -#define PCI_DEVICE_ID_INTEL_PXH_1 0x032A -#define PCI_DEVICE_ID_INTEL_PXHV 0x032C -#define PCI_DEVICE_ID_INTEL_82375 0x0482 -#define PCI_DEVICE_ID_INTEL_82424 0x0483 -#define PCI_DEVICE_ID_INTEL_82378 0x0484 -#define PCI_DEVICE_ID_INTEL_I960 0x0960 -#define PCI_DEVICE_ID_INTEL_I960RM 0x0962 -#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 -#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 -#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 -#define PCI_DEVICE_ID_INTEL_7505_0 0x2550 -#define PCI_DEVICE_ID_INTEL_7205_0 0x255d -#define PCI_DEVICE_ID_INTEL_82437 0x122d -#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e -#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 -#define PCI_DEVICE_ID_INTEL_82371MX 0x1234 -#define PCI_DEVICE_ID_INTEL_82441 0x1237 -#define PCI_DEVICE_ID_INTEL_82380FB 0x124b -#define PCI_DEVICE_ID_INTEL_82439 0x1250 -#define PCI_DEVICE_ID_INTEL_80960_RP 0x1960 -#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 -#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 -#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 -#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 -#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 -#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 -#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415 -#define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416 -#define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418 -#define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420 -#define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421 -#define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423 -#define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425 -#define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426 -#define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428 -#define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440 -#define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443 -#define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445 -#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448 -#define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a -#define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b -#define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c -#define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e -#define PCI_DEVICE_ID_INTEL_82801E_0 0x2450 -#define PCI_DEVICE_ID_INTEL_82801E_11 0x245b -#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480 -#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483 -#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485 -#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486 -#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a -#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b -#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c -#define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0 -#define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1 -#define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3 -#define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5 -#define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6 -#define PCI_DEVICE_ID_INTEL_82801DB_9 0x24c9 -#define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca -#define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb -#define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc -#define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0 -#define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1 -#define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3 -#define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5 -#define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6 -#define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db -#define PCI_DEVICE_ID_INTEL_82801EB_12 0x24dc -#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd -#define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1 -#define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2 -#define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4 -#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6 -#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab -#define PCI_DEVICE_ID_INTEL_82820_HB 0x2500 -#define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501 -#define PCI_DEVICE_ID_INTEL_82850_HB 0x2530 -#define PCI_DEVICE_ID_INTEL_82860_HB 0x2531 -#define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c -#define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560 -#define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562 -#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570 -#define PCI_DEVICE_ID_INTEL_82865_IG 0x2572 -#define PCI_DEVICE_ID_INTEL_82875_HB 0x2578 -#define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580 -#define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 -#define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 -#define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 -#define PCI_DEVICE_ID_INTEL_5000_ERR 0x25F0 -#define PCI_DEVICE_ID_INTEL_5000_FBD0 0x25F5 -#define PCI_DEVICE_ID_INTEL_5000_FBD1 0x25F6 -#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 -#define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 -#define PCI_DEVICE_ID_INTEL_3000_HB 0x2778 -#define PCI_DEVICE_ID_INTEL_82945GM_HB 0x27A0 -#define PCI_DEVICE_ID_INTEL_82945GM_IG 0x27A2 -#define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 -#define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 -#define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 -#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a -#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d -#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e -#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f -#define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670 -#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698 -#define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b -#define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e -#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 -#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 -#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 -#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd -#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da -#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd -#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de -#define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df -#define PCI_DEVICE_ID_INTEL_ICH8_0 0x2810 -#define PCI_DEVICE_ID_INTEL_ICH8_1 0x2811 -#define PCI_DEVICE_ID_INTEL_ICH8_2 0x2812 -#define PCI_DEVICE_ID_INTEL_ICH8_3 0x2814 -#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 -#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e -#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 -#define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910 -#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2917 -#define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912 -#define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913 -#define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914 -#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919 -#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930 -#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916 -#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918 -#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 -#define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 -#define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a -#define PCI_DEVICE_ID_INTEL_IOAT_TBG6 0x342b -#define PCI_DEVICE_ID_INTEL_IOAT_TBG7 0x342c -#define PCI_DEVICE_ID_INTEL_IOAT_TBG0 0x3430 -#define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x3431 -#define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x3432 -#define PCI_DEVICE_ID_INTEL_IOAT_TBG3 0x3433 -#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 -#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 -#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580 -#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582 -#define PCI_DEVICE_ID_INTEL_E7520_MCH 0x3590 -#define PCI_DEVICE_ID_INTEL_E7320_MCH 0x3592 -#define PCI_DEVICE_ID_INTEL_MCH_PA 0x3595 -#define PCI_DEVICE_ID_INTEL_MCH_PA1 0x3596 -#define PCI_DEVICE_ID_INTEL_MCH_PB 0x3597 -#define PCI_DEVICE_ID_INTEL_MCH_PB1 0x3598 -#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599 -#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a -#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e -#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b -#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c -#define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14 -#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16 -#define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18 -#define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a -#define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30 -#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 -#define PCI_DEVICE_ID_INTEL_PCH_LPC_MIN 0x3b00 -#define PCI_DEVICE_ID_INTEL_PCH_LPC_MAX 0x3b1f -#define PCI_DEVICE_ID_INTEL_PCH_SMBUS 0x3b30 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f -#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 -#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 -#define PCI_DEVICE_ID_INTEL_5100_22 0x65f6 -#define PCI_DEVICE_ID_INTEL_5400_ERR 0x4030 -#define PCI_DEVICE_ID_INTEL_5400_FBD0 0x4035 -#define PCI_DEVICE_ID_INTEL_5400_FBD1 0x4036 -#define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff -#define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031 -#define PCI_DEVICE_ID_INTEL_TOLAPAI_1 0x5032 -#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 -#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 -#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 -#define PCI_DEVICE_ID_INTEL_82437VX 0x7030 -#define PCI_DEVICE_ID_INTEL_82439TX 0x7100 -#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 -#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 -#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 -#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 -#define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120 -#define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121 -#define PCI_DEVICE_ID_INTEL_82810_MC3 0x7122 -#define PCI_DEVICE_ID_INTEL_82810_IG3 0x7123 -#define PCI_DEVICE_ID_INTEL_82810E_MC 0x7124 -#define PCI_DEVICE_ID_INTEL_82810E_IG 0x7125 -#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180 -#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181 -#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190 -#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191 -#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 -#define PCI_DEVICE_ID_INTEL_440MX 0x7195 -#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196 -#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198 -#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199 -#define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b -#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 -#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 -#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 -#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 -#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a -#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 -#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 -#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca -#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb -#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea -#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500 -#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 -#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 - -#define PCI_VENDOR_ID_SCALEMP 0x8686 -#define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010 - -#define PCI_VENDOR_ID_COMPUTONE 0x8e0e -#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291 -#define PCI_DEVICE_ID_COMPUTONE_PG 0x0302 -#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e -#define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001 -#define PCI_SUBDEVICE_ID_COMPUTONE_PG8 0x0002 -#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003 - -#define PCI_VENDOR_ID_KTI 0x8e2e - -#define PCI_VENDOR_ID_ADAPTEC 0x9004 -#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078 -#define PCI_DEVICE_ID_ADAPTEC_7821 0x2178 -#define PCI_DEVICE_ID_ADAPTEC_38602 0x3860 -#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078 -#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578 -#define PCI_DEVICE_ID_ADAPTEC_3860 0x6038 -#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075 -#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078 -#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178 -#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078 -#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178 -#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278 -#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378 -#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478 -#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895 -#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078 -#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178 -#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278 -#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378 -#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478 -#define PCI_DEVICE_ID_ADAPTEC_7885 0x8578 -#define PCI_DEVICE_ID_ADAPTEC_7886 0x8678 -#define PCI_DEVICE_ID_ADAPTEC_7887 0x8778 -#define PCI_DEVICE_ID_ADAPTEC_7888 0x8878 - -#define PCI_VENDOR_ID_ADAPTEC2 0x9005 -#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010 -#define PCI_DEVICE_ID_ADAPTEC2_2930U2 0x0011 -#define PCI_DEVICE_ID_ADAPTEC2_7890B 0x0013 -#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f -#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050 -#define PCI_DEVICE_ID_ADAPTEC2_3950U2D 0x0051 -#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f -#define PCI_DEVICE_ID_ADAPTEC2_7892A 0x0080 -#define PCI_DEVICE_ID_ADAPTEC2_7892B 0x0081 -#define PCI_DEVICE_ID_ADAPTEC2_7892D 0x0083 -#define PCI_DEVICE_ID_ADAPTEC2_7892P 0x008f -#define PCI_DEVICE_ID_ADAPTEC2_7899A 0x00c0 -#define PCI_DEVICE_ID_ADAPTEC2_7899B 0x00c1 -#define PCI_DEVICE_ID_ADAPTEC2_7899D 0x00c3 -#define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf -#define PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN 0x0500 -#define PCI_DEVICE_ID_ADAPTEC2_SCAMP 0x0503 - -#define PCI_VENDOR_ID_HOLTEK 0x9412 -#define PCI_DEVICE_ID_HOLTEK_6565 0x6565 - -#define PCI_VENDOR_ID_NETMOS 0x9710 -#define PCI_DEVICE_ID_NETMOS_9705 0x9705 -#define PCI_DEVICE_ID_NETMOS_9715 0x9715 -#define PCI_DEVICE_ID_NETMOS_9735 0x9735 -#define PCI_DEVICE_ID_NETMOS_9745 0x9745 -#define PCI_DEVICE_ID_NETMOS_9755 0x9755 -#define PCI_DEVICE_ID_NETMOS_9805 0x9805 -#define PCI_DEVICE_ID_NETMOS_9815 0x9815 -#define PCI_DEVICE_ID_NETMOS_9835 0x9835 -#define PCI_DEVICE_ID_NETMOS_9845 0x9845 -#define PCI_DEVICE_ID_NETMOS_9855 0x9855 - -#define PCI_VENDOR_ID_3COM_2 0xa727 - -#define PCI_VENDOR_ID_DIGIUM 0xd161 -#define PCI_DEVICE_ID_DIGIUM_HFC4S 0xb410 - -#define PCI_SUBVENDOR_ID_EXSYS 0xd84d -#define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014 -#define PCI_SUBDEVICE_ID_EXSYS_4055 0x4055 - -#define PCI_VENDOR_ID_TIGERJET 0xe159 -#define PCI_DEVICE_ID_TIGERJET_300 0x0001 -#define PCI_DEVICE_ID_TIGERJET_100 0x0002 - -#define PCI_VENDOR_ID_XILINX_RME 0xea60 -#define PCI_DEVICE_ID_RME_DIGI32 0x9896 -#define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897 -#define PCI_DEVICE_ID_RME_DIGI32_8 0x9898 - -#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 -#define PCI_DEVICE_ID_VIRTIO_BLK 0x1001 diff --git a/roms/seabios/src/pci_regs.h b/roms/seabios/src/pci_regs.h deleted file mode 100644 index e5effd4..0000000 --- a/roms/seabios/src/pci_regs.h +++ /dev/null @@ -1,556 +0,0 @@ -/* - * pci_regs.h - * - * PCI standard defines - * Copyright 1994, Drew Eckhardt - * Copyright 1997--1999 Martin Mares - * - * For more information, please consult the following manuals (look at - * http://www.pcisig.com/ for how to get them): - * - * PCI BIOS Specification - * PCI Local Bus Specification - * PCI to PCI Bridge Specification - * PCI System Design Guide - * - * For hypertransport information, please consult the following manuals - * from http://www.hypertransport.org - * - * The Hypertransport I/O Link Specification - */ - -#ifndef LINUX_PCI_REGS_H -#define LINUX_PCI_REGS_H - -/* - * Under PCI, each device has 256 bytes of configuration address space, - * of which the first 64 bytes are standardized as follows: - */ -#define PCI_VENDOR_ID 0x00 /* 16 bits */ -#define PCI_DEVICE_ID 0x02 /* 16 bits */ -#define PCI_COMMAND 0x04 /* 16 bits */ -#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ -#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ -#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ -#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ -#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ -#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ -#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ -#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ -#define PCI_COMMAND_SERR 0x100 /* Enable SERR */ -#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ -#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ - -#define PCI_STATUS 0x06 /* 16 bits */ -#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */ -#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ -#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */ -#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ -#define PCI_STATUS_PARITY 0x100 /* Detected parity error */ -#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */ -#define PCI_STATUS_DEVSEL_FAST 0x000 -#define PCI_STATUS_DEVSEL_MEDIUM 0x200 -#define PCI_STATUS_DEVSEL_SLOW 0x400 -#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */ -#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */ -#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */ -#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */ -#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */ - -#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */ -#define PCI_REVISION_ID 0x08 /* Revision ID */ -#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */ -#define PCI_CLASS_DEVICE 0x0a /* Device class */ - -#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ -#define PCI_LATENCY_TIMER 0x0d /* 8 bits */ -#define PCI_HEADER_TYPE 0x0e /* 8 bits */ -#define PCI_HEADER_TYPE_NORMAL 0 -#define PCI_HEADER_TYPE_BRIDGE 1 -#define PCI_HEADER_TYPE_CARDBUS 2 - -#define PCI_BIST 0x0f /* 8 bits */ -#define PCI_BIST_CODE_MASK 0x0f /* Return result */ -#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */ -#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */ - -/* - * Base addresses specify locations in memory or I/O space. - * Decoded size can be determined by writing a value of - * 0xffffffff to the register, and reading it back. Only - * 1 bits are decoded. - */ -#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ -#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */ -#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */ -#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ -#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */ -#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */ -#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */ -#define PCI_BASE_ADDRESS_SPACE_IO 0x01 -#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 -#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 -#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */ -#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ -#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ -#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ -#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) -#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) -/* bit 1 is reserved if address_space = 1 */ - -/* Header type 0 (normal devices) */ -#define PCI_CARDBUS_CIS 0x28 -#define PCI_SUBSYSTEM_VENDOR_ID 0x2c -#define PCI_SUBSYSTEM_ID 0x2e -#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */ -#define PCI_ROM_ADDRESS_ENABLE 0x01 -#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) - -#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */ - -/* 0x35-0x3b are reserved */ -#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ -#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ -#define PCI_MIN_GNT 0x3e /* 8 bits */ -#define PCI_MAX_LAT 0x3f /* 8 bits */ - -/* Header type 1 (PCI-to-PCI bridges) */ -#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ -#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */ -#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */ -#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */ -#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ -#define PCI_IO_LIMIT 0x1d -#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */ -#define PCI_IO_RANGE_TYPE_16 0x00 -#define PCI_IO_RANGE_TYPE_32 0x01 -#define PCI_IO_RANGE_MASK (~0x0fUL) -#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */ -#define PCI_MEMORY_BASE 0x20 /* Memory range behind */ -#define PCI_MEMORY_LIMIT 0x22 -#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL -#define PCI_MEMORY_RANGE_MASK (~0x0fUL) -#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ -#define PCI_PREF_MEMORY_LIMIT 0x26 -#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL -#define PCI_PREF_RANGE_TYPE_32 0x00 -#define PCI_PREF_RANGE_TYPE_64 0x01 -#define PCI_PREF_RANGE_MASK (~0x0fUL) -#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ -#define PCI_PREF_LIMIT_UPPER32 0x2c -#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ -#define PCI_IO_LIMIT_UPPER16 0x32 -/* 0x34 same as for htype 0 */ -/* 0x35-0x3b is reserved */ -#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */ -/* 0x3c-0x3d are same as for htype 0 */ -#define PCI_BRIDGE_CONTROL 0x3e -#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */ -#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */ -#define PCI_BRIDGE_CTL_ISA 0x04 /* Enable ISA mode */ -#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */ -#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */ -#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */ -#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */ - -/* Header type 2 (CardBus bridges) */ -#define PCI_CB_CAPABILITY_LIST 0x14 -/* 0x15 reserved */ -#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */ -#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */ -#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */ -#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */ -#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */ -#define PCI_CB_MEMORY_BASE_0 0x1c -#define PCI_CB_MEMORY_LIMIT_0 0x20 -#define PCI_CB_MEMORY_BASE_1 0x24 -#define PCI_CB_MEMORY_LIMIT_1 0x28 -#define PCI_CB_IO_BASE_0 0x2c -#define PCI_CB_IO_BASE_0_HI 0x2e -#define PCI_CB_IO_LIMIT_0 0x30 -#define PCI_CB_IO_LIMIT_0_HI 0x32 -#define PCI_CB_IO_BASE_1 0x34 -#define PCI_CB_IO_BASE_1_HI 0x36 -#define PCI_CB_IO_LIMIT_1 0x38 -#define PCI_CB_IO_LIMIT_1_HI 0x3a -#define PCI_CB_IO_RANGE_MASK (~0x03UL) -/* 0x3c-0x3d are same as for htype 0 */ -#define PCI_CB_BRIDGE_CONTROL 0x3e -#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */ -#define PCI_CB_BRIDGE_CTL_SERR 0x02 -#define PCI_CB_BRIDGE_CTL_ISA 0x04 -#define PCI_CB_BRIDGE_CTL_VGA 0x08 -#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20 -#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */ -#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */ -#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */ -#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200 -#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400 -#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40 -#define PCI_CB_SUBSYSTEM_ID 0x42 -#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */ -/* 0x48-0x7f reserved */ - -/* Capability lists */ - -#define PCI_CAP_LIST_ID 0 /* Capability ID */ -#define PCI_CAP_ID_PM 0x01 /* Power Management */ -#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */ -#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */ -#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */ -#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ -#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ -#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ -#define PCI_CAP_ID_HT 0x08 /* HyperTransport */ -#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific */ -#define PCI_CAP_ID_DBG 0x0A /* Debug port */ -#define PCI_CAP_ID_CCRC 0x0B /* CompactPCI Central Resource Control */ -#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ -#define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */ -#define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */ -#define PCI_CAP_ID_EXP 0x10 /* PCI Express */ -#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ -#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ -#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ -#define PCI_CAP_SIZEOF 4 - -/* Power Management Registers */ - -#define PCI_PM_PMC 2 /* PM Capabilities Register */ -#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */ -#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */ -#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */ -#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */ -#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */ -#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */ -#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */ -#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */ -#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */ -#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */ -#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */ -#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */ -#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */ -#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */ -#define PCI_PM_CAP_PME_SHIFT 11 /* Start of the PME Mask in PMC */ -#define PCI_PM_CTRL 4 /* PM control and status register */ -#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ -#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */ -#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */ -#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */ -#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */ -#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */ -#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */ -#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */ -#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */ -#define PCI_PM_DATA_REGISTER 7 /* (??) */ -#define PCI_PM_SIZEOF 8 - -/* AGP registers */ - -#define PCI_AGP_VERSION 2 /* BCD version number */ -#define PCI_AGP_RFU 3 /* Rest of capability flags */ -#define PCI_AGP_STATUS 4 /* Status register */ -#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */ -#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */ -#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */ -#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */ -#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */ -#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */ -#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */ -#define PCI_AGP_COMMAND 8 /* Control register */ -#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */ -#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */ -#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */ -#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */ -#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */ -#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */ -#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */ -#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */ -#define PCI_AGP_SIZEOF 12 - -/* Vital Product Data */ - -#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */ -#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */ -#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */ -#define PCI_VPD_DATA 4 /* 32-bits of data returned here */ - -/* Slot Identification */ - -#define PCI_SID_ESR 2 /* Expansion Slot Register */ -#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */ -#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */ -#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */ - -/* Message Signalled Interrupts registers */ - -#define PCI_MSI_FLAGS 2 /* Various flags */ -#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */ -#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */ -#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */ -#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */ -#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */ -#define PCI_MSI_RFU 3 /* Rest of capability flags */ -#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */ -#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ -#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ -#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ -#define PCI_MSI_MASK_BIT 16 /* Mask bits register */ - -/* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */ -#define PCI_MSIX_FLAGS 2 -#define PCI_MSIX_FLAGS_QSIZE 0x7FF -#define PCI_MSIX_FLAGS_ENABLE (1 << 15) -#define PCI_MSIX_FLAGS_MASKALL (1 << 14) -#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) -#define PCI_MSIX_FLAGS_BITMASK (1 << 0) - -/* CompactPCI Hotswap Register */ - -#define PCI_CHSWP_CSR 2 /* Control and Status Register */ -#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */ -#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */ -#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */ -#define PCI_CHSWP_LOO 0x08 /* LED On / Off */ -#define PCI_CHSWP_PI 0x30 /* Programming Interface */ -#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */ -#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */ - -/* PCI-X registers */ - -#define PCI_X_CMD 2 /* Modes & Features */ -#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */ -#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ -#define PCI_X_CMD_READ_512 0x0000 /* 512 byte maximum read byte count */ -#define PCI_X_CMD_READ_1K 0x0004 /* 1Kbyte maximum read byte count */ -#define PCI_X_CMD_READ_2K 0x0008 /* 2Kbyte maximum read byte count */ -#define PCI_X_CMD_READ_4K 0x000c /* 4Kbyte maximum read byte count */ -#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */ - /* Max # of outstanding split transactions */ -#define PCI_X_CMD_SPLIT_1 0x0000 /* Max 1 */ -#define PCI_X_CMD_SPLIT_2 0x0010 /* Max 2 */ -#define PCI_X_CMD_SPLIT_3 0x0020 /* Max 3 */ -#define PCI_X_CMD_SPLIT_4 0x0030 /* Max 4 */ -#define PCI_X_CMD_SPLIT_8 0x0040 /* Max 8 */ -#define PCI_X_CMD_SPLIT_12 0x0050 /* Max 12 */ -#define PCI_X_CMD_SPLIT_16 0x0060 /* Max 16 */ -#define PCI_X_CMD_SPLIT_32 0x0070 /* Max 32 */ -#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */ -#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ -#define PCI_X_STATUS 4 /* PCI-X capabilities */ -#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */ -#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */ -#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */ -#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */ -#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */ -#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */ -#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */ -#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */ -#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */ -#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */ -#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */ -#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ -#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ - -/* PCI Express capability registers */ - -#define PCI_EXP_FLAGS 2 /* Capabilities register */ -#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */ -#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */ -#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */ -#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */ -#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ -#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */ -#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ -#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */ -#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ -#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */ -#define PCI_EXP_DEVCAP 4 /* Device capabilities */ -#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */ -#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */ -#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */ -#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */ -#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */ -#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ -#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ -#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ -#define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ -#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ -#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ -#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ -#define PCI_EXP_DEVCTL 8 /* Device Control */ -#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ -#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ -#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */ -#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */ -#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */ -#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ -#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */ -#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */ -#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ -#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ -#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ -#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ -#define PCI_EXP_DEVSTA 10 /* Device Status */ -#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ -#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ -#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */ -#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */ -#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ -#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ -#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ -#define PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */ -#define PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */ -#define PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */ -#define PCI_EXP_LNKCAP_CLKPM 0x40000 /* L1 Clock Power Management */ -#define PCI_EXP_LNKCTL 16 /* Link Control */ -#define PCI_EXP_LNKCTL_RL 0x20 /* Retrain Link */ -#define PCI_EXP_LNKCTL_CCC 0x40 /* Common Clock COnfiguration */ -#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ -#define PCI_EXP_LNKSTA 18 /* Link Status */ -#define PCI_EXP_LNKSTA_LT 0x800 /* Link Training */ -#define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */ -#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ -#define PCI_EXP_SLTCTL 24 /* Slot Control */ -#define PCI_EXP_SLTSTA 26 /* Slot Status */ -#define PCI_EXP_RTCTL 28 /* Root Control */ -#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */ -#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */ -#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */ -#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */ -#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ -#define PCI_EXP_RTCAP 30 /* Root Capabilities */ -#define PCI_EXP_RTSTA 32 /* Root Status */ -#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ -#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ -#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ -#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ - -/* Extended Capabilities (PCI-X 2.0 and Express) */ -#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) -#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) -#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) - -#define PCI_EXT_CAP_ID_ERR 1 -#define PCI_EXT_CAP_ID_VC 2 -#define PCI_EXT_CAP_ID_DSN 3 -#define PCI_EXT_CAP_ID_PWR 4 -#define PCI_EXT_CAP_ID_ARI 14 - -/* Advanced Error Reporting */ -#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ -#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */ -#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ -#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ -#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */ -#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */ -#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */ -#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */ -#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */ -#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */ -#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */ -#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */ -#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */ - /* Same bits as above */ -#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */ - /* Same bits as above */ -#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */ -#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */ -#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */ -#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */ -#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */ -#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */ -#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */ - /* Same bits as above */ -#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */ -#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */ -#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */ -#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */ -#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */ -#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ -#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */ -#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */ -/* Correctable Err Reporting Enable */ -#define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 -/* Non-fatal Err Reporting Enable */ -#define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002 -/* Fatal Err Reporting Enable */ -#define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004 -#define PCI_ERR_ROOT_STATUS 48 -#define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */ -/* Multi ERR_COR Received */ -#define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002 -/* ERR_FATAL/NONFATAL Recevied */ -#define PCI_ERR_ROOT_UNCOR_RCV 0x00000004 -/* Multi ERR_FATAL/NONFATAL Recevied */ -#define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008 -#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */ -#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ -#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ -#define PCI_ERR_ROOT_COR_SRC 52 -#define PCI_ERR_ROOT_SRC 54 - -/* Virtual Channel */ -#define PCI_VC_PORT_REG1 4 -#define PCI_VC_PORT_REG2 8 -#define PCI_VC_PORT_CTRL 12 -#define PCI_VC_PORT_STATUS 14 -#define PCI_VC_RES_CAP 16 -#define PCI_VC_RES_CTRL 20 -#define PCI_VC_RES_STATUS 26 - -/* Power Budgeting */ -#define PCI_PWR_DSR 4 /* Data Select Register */ -#define PCI_PWR_DATA 8 /* Data Register */ -#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */ -#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */ -#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */ -#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */ -#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */ -#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */ -#define PCI_PWR_CAP 12 /* Capability */ -#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ - -/* - * Hypertransport sub capability types - * - * Unfortunately there are both 3 bit and 5 bit capability types defined - * in the HT spec, catering for that is a little messy. You probably don't - * want to use these directly, just use pci_find_ht_capability() and it - * will do the right thing for you. - */ -#define HT_3BIT_CAP_MASK 0xE0 -#define HT_CAPTYPE_SLAVE 0x00 /* Slave/Primary link configuration */ -#define HT_CAPTYPE_HOST 0x20 /* Host/Secondary link configuration */ - -#define HT_5BIT_CAP_MASK 0xF8 -#define HT_CAPTYPE_IRQ 0x80 /* IRQ Configuration */ -#define HT_CAPTYPE_REMAPPING_40 0xA0 /* 40 bit address remapping */ -#define HT_CAPTYPE_REMAPPING_64 0xA2 /* 64 bit address remapping */ -#define HT_CAPTYPE_UNITID_CLUMP 0x90 /* Unit ID clumping */ -#define HT_CAPTYPE_EXTCONF 0x98 /* Extended Configuration Space Access */ -#define HT_CAPTYPE_MSI_MAPPING 0xA8 /* MSI Mapping Capability */ -#define HT_MSI_FLAGS 0x02 /* Offset to flags */ -#define HT_MSI_FLAGS_ENABLE 0x1 /* Mapping enable */ -#define HT_MSI_FLAGS_FIXED 0x2 /* Fixed mapping only */ -#define HT_MSI_FIXED_ADDR 0x00000000FEE00000ULL /* Fixed addr */ -#define HT_MSI_ADDR_LO 0x04 /* Offset to low addr bits */ -#define HT_MSI_ADDR_LO_MASK 0xFFF00000 /* Low address bit mask */ -#define HT_MSI_ADDR_HI 0x08 /* Offset to high addr bits */ -#define HT_CAPTYPE_DIRECT_ROUTE 0xB0 /* Direct routing configuration */ -#define HT_CAPTYPE_VCSET 0xB8 /* Virtual Channel configuration */ -#define HT_CAPTYPE_ERROR_RETRY 0xC0 /* Retry on error configuration */ -#define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */ -#define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */ - -/* Alternative Routing-ID Interpretation */ -#define PCI_ARI_CAP 0x04 /* ARI Capability Register */ -#define PCI_ARI_CAP_MFVC 0x0001 /* MFVC Function Groups Capability */ -#define PCI_ARI_CAP_ACS 0x0002 /* ACS Function Groups Capability */ -#define PCI_ARI_CAP_NFN(x) (((x) >> 8) & 0xff) /* Next Function Number */ -#define PCI_ARI_CTRL 0x06 /* ARI Control Register */ -#define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */ -#define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */ -#define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */ - -#endif /* LINUX_PCI_REGS_H */ diff --git a/roms/seabios/src/pcibios.c b/roms/seabios/src/pcibios.c deleted file mode 100644 index a23248b..0000000 --- a/roms/seabios/src/pcibios.c +++ /dev/null @@ -1,234 +0,0 @@ -// PCI BIOS (int 1a/b1) calls -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "types.h" // u32 -#include "util.h" // handle_1ab1 -#include "pci.h" // pci_config_readl -#include "bregs.h" // struct bregs -#include "biosvar.h" // GET_EBDA -#include "pci_regs.h" // PCI_VENDOR_ID - -// romlayout.S -extern void bios32_entry(void); -extern void pcibios32_entry(void); - -#define RET_FUNC_NOT_SUPPORTED 0x81 -#define RET_BAD_VENDOR_ID 0x83 -#define RET_DEVICE_NOT_FOUND 0x86 -#define RET_BUFFER_TOO_SMALL 0x89 - -// installation check -static void -handle_1ab101(struct bregs *regs) -{ - // Find max bus. - int bdf, max; - foreachpci(bdf, max) { - } - - regs->al = 0x01; // Flags - "Config Mechanism #1" supported. - regs->bx = 0x0210; // PCI version 2.10 - regs->cl = pci_bdf_to_bus(max - 1); - regs->edx = 0x20494350; // "PCI " - regs->edi = (u32)pcibios32_entry + BUILD_BIOS_ADDR; - set_code_success(regs); -} - -// find pci device -static void -handle_1ab102(struct bregs *regs) -{ - u32 id = (regs->cx << 16) | regs->dx; - int count = regs->si; - int bdf, max; - foreachpci(bdf, max) { - u32 v = pci_config_readl(bdf, PCI_VENDOR_ID); - if (v != id) - continue; - if (count--) - continue; - regs->bx = bdf; - set_code_success(regs); - return; - } - set_code_invalid(regs, RET_DEVICE_NOT_FOUND); -} - -// find class code -static void -handle_1ab103(struct bregs *regs) -{ - int count = regs->si; - u32 classprog = regs->ecx; - int bdf, max; - foreachpci(bdf, max) { - u32 v = pci_config_readl(bdf, PCI_CLASS_REVISION); - if ((v>>8) != classprog) - continue; - if (count--) - continue; - regs->bx = bdf; - set_code_success(regs); - return; - } - set_code_invalid(regs, RET_DEVICE_NOT_FOUND); -} - -// read configuration byte -static void -handle_1ab108(struct bregs *regs) -{ - regs->cl = pci_config_readb(regs->bx, regs->di); - set_code_success(regs); -} - -// read configuration word -static void -handle_1ab109(struct bregs *regs) -{ - regs->cx = pci_config_readw(regs->bx, regs->di); - set_code_success(regs); -} - -// read configuration dword -static void -handle_1ab10a(struct bregs *regs) -{ - regs->ecx = pci_config_readl(regs->bx, regs->di); - set_code_success(regs); -} - -// write configuration byte -static void -handle_1ab10b(struct bregs *regs) -{ - pci_config_writeb(regs->bx, regs->di, regs->cl); - set_code_success(regs); -} - -// write configuration word -static void -handle_1ab10c(struct bregs *regs) -{ - pci_config_writew(regs->bx, regs->di, regs->cx); - set_code_success(regs); -} - -// write configuration dword -static void -handle_1ab10d(struct bregs *regs) -{ - pci_config_writel(regs->bx, regs->di, regs->ecx); - set_code_success(regs); -} - -// get irq routing options -static void -handle_1ab10e(struct bregs *regs) -{ - struct pir_header *pirtable_g = (void*)(GET_GLOBAL(PirOffset) + 0); - if (! pirtable_g) { - set_code_invalid(regs, RET_FUNC_NOT_SUPPORTED); - return; - } - - struct param_s { - u16 size; - u16 buf_off; - u16 buf_seg; - } *param_far = (void*)(regs->di+0); - - // Validate and update size. - u16 bufsize = GET_FARVAR(regs->es, param_far->size); - u16 pirsize = GET_GLOBAL(pirtable_g->size) - sizeof(struct pir_header); - SET_FARVAR(regs->es, param_far->size, pirsize); - if (bufsize < pirsize) { - set_code_invalid(regs, RET_BUFFER_TOO_SMALL); - return; - } - - // Get dest buffer. - void *buf_far = (void*)(GET_FARVAR(regs->es, param_far->buf_off)+0); - u16 buf_seg = GET_FARVAR(regs->es, param_far->buf_seg); - - // Memcpy pir table slots to dest buffer. - memcpy_far(buf_seg, buf_far - , get_global_seg() - , (void*)(pirtable_g->slots) + get_global_offset() - , pirsize); - - // XXX - bochs bios sets bx to (1 << 9) | (1 << 11) - regs->bx = GET_GLOBAL(pirtable_g->exclusive_irqs); - set_code_success(regs); -} - -static void -handle_1ab1XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_FUNC_NOT_SUPPORTED); -} - -void -handle_1ab1(struct bregs *regs) -{ - //debug_stub(regs); - - if (! CONFIG_PCIBIOS) { - set_invalid(regs); - return; - } - - switch (regs->al) { - case 0x01: handle_1ab101(regs); break; - case 0x02: handle_1ab102(regs); break; - case 0x03: handle_1ab103(regs); break; - case 0x08: handle_1ab108(regs); break; - case 0x09: handle_1ab109(regs); break; - case 0x0a: handle_1ab10a(regs); break; - case 0x0b: handle_1ab10b(regs); break; - case 0x0c: handle_1ab10c(regs); break; - case 0x0d: handle_1ab10d(regs); break; - case 0x0e: handle_1ab10e(regs); break; - default: handle_1ab1XX(regs); break; - } -} - - -/**************************************************************** - * 32bit interface - ****************************************************************/ - -// Entry point for 32bit pci bios functions. -void VISIBLE32SEG -handle_pcibios32(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_pcibios32); - handle_1ab1(regs); -} - -struct bios32_s { - u32 signature; - u32 entry; - u8 version; - u8 length; - u8 checksum; - u8 reserved[5]; -} PACKED; - -struct bios32_s BIOS32HEADER __aligned(16) VAR16EXPORT = { - .signature = 0x5f32335f, // _32_ - .length = sizeof(BIOS32HEADER) / 16, -}; - -void -bios32_setup(void) -{ - dprintf(3, "init bios32\n"); - - BIOS32HEADER.entry = (u32)bios32_entry; - BIOS32HEADER.checksum -= checksum(&BIOS32HEADER, sizeof(BIOS32HEADER)); -} diff --git a/roms/seabios/src/pciinit.c b/roms/seabios/src/pciinit.c deleted file mode 100644 index 0346423..0000000 --- a/roms/seabios/src/pciinit.c +++ /dev/null @@ -1,420 +0,0 @@ -// Initialize PCI devices (on emulators) -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "pci.h" // pci_config_readl -#include "biosvar.h" // GET_EBDA -#include "pci_ids.h" // PCI_VENDOR_ID_INTEL -#include "pci_regs.h" // PCI_COMMAND -#include "dev-i440fx.h" - -#define PCI_ROM_SLOT 6 -#define PCI_NUM_REGIONS 7 - -static void pci_bios_init_device_in_bus(int bus); - -static u32 pci_bios_io_addr; -static u32 pci_bios_mem_addr; -static u32 pci_bios_prefmem_addr; -/* host irqs corresponding to PCI irqs A-D */ -const u8 pci_irqs[4] = { - 10, 10, 11, 11 -}; - -static u32 pci_bar(u16 bdf, int region_num) -{ - if (region_num != PCI_ROM_SLOT) { - return PCI_BASE_ADDRESS_0 + region_num * 4; - } - -#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80 - u8 type = pci_config_readb(bdf, PCI_HEADER_TYPE); - type &= ~PCI_HEADER_TYPE_MULTI_FUNCTION; - return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS; -} - -static void pci_set_io_region_addr(u16 bdf, int region_num, u32 addr) -{ - u32 ofs; - - ofs = pci_bar(bdf, region_num); - - pci_config_writel(bdf, ofs, addr); - dprintf(1, "region %d: 0x%08x\n", region_num, addr); -} - -/* - * return value - * 0: 32bit BAR - * non 0: 64bit BAR - */ -static int pci_bios_allocate_region(u16 bdf, int region_num) -{ - u32 *paddr; - u32 ofs = pci_bar(bdf, region_num); - - u32 old = pci_config_readl(bdf, ofs); - u32 mask; - if (region_num == PCI_ROM_SLOT) { - mask = PCI_ROM_ADDRESS_MASK; - pci_config_writel(bdf, ofs, mask); - } else { - if (old & PCI_BASE_ADDRESS_SPACE_IO) - mask = PCI_BASE_ADDRESS_IO_MASK; - else - mask = PCI_BASE_ADDRESS_MEM_MASK; - pci_config_writel(bdf, ofs, ~0); - } - u32 val = pci_config_readl(bdf, ofs); - pci_config_writel(bdf, ofs, old); - - u32 size = (~(val & mask)) + 1; - if (val != 0) { - if (val & PCI_BASE_ADDRESS_SPACE_IO) { - paddr = &pci_bios_io_addr; - if (ALIGN(*paddr, size) + size >= 64 * 1024) { - dprintf(1, - "io region of (bdf 0x%x bar %d) can't be mapped.\n", - bdf, region_num); - size = 0; - } - } else if ((val & PCI_BASE_ADDRESS_MEM_PREFETCH) && - /* keep behaviour on bus = 0 */ - pci_bdf_to_bus(bdf) != 0 && - /* If pci_bios_prefmem_addr == 0, keep old behaviour */ - pci_bios_prefmem_addr != 0) { - paddr = &pci_bios_prefmem_addr; - if (ALIGN(*paddr, size) + size >= BUILD_PCIPREFMEM_END) { - dprintf(1, - "prefmem region of (bdf 0x%x bar %d) can't be mapped. " - "decrease BUILD_PCIMEM_SIZE and recompile. size %x\n", - bdf, region_num, BUILD_PCIPREFMEM_SIZE); - size = 0; - } - } else { - paddr = &pci_bios_mem_addr; - if (ALIGN(*paddr, size) + size >= BUILD_PCIMEM_END) { - dprintf(1, - "mem region of (bdf 0x%x bar %d) can't be mapped. " - "increase BUILD_PCIMEM_SIZE and recompile. size %x\n", - bdf, region_num, BUILD_PCIMEM_SIZE); - size = 0; - } - } - if (size > 0) { - *paddr = ALIGN(*paddr, size); - pci_set_io_region_addr(bdf, region_num, *paddr); - *paddr += size; - } - } - - int is_64bit = !(val & PCI_BASE_ADDRESS_SPACE_IO) && - (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64; - if (is_64bit && size > 0) { - pci_config_writel(bdf, ofs + 4, 0); - } - return is_64bit; -} - -void pci_bios_allocate_regions(u16 bdf, void *arg) -{ - int i; - for (i = 0; i < PCI_NUM_REGIONS; i++) { - int is_64bit = pci_bios_allocate_region(bdf, i); - if (is_64bit){ - i++; - } - } -} - -/* return the global irq number corresponding to a given device irq - pin. We could also use the bus number to have a more precise - mapping. */ -static int pci_slot_get_pirq(u16 bdf, int irq_num) -{ - int slot_addend = pci_bdf_to_dev(bdf) - 1; - return (irq_num + slot_addend) & 3; -} - -static const struct pci_device_id pci_isa_bridge_tbl[] = { - /* PIIX3/PIIX4 PCI to ISA bridge */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, - piix_isa_bridge_init), - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, - piix_isa_bridge_init), - - PCI_DEVICE_END -}; - -#define PCI_IO_ALIGN 4096 -#define PCI_IO_SHIFT 8 -#define PCI_MEMORY_ALIGN (1UL << 20) -#define PCI_MEMORY_SHIFT 16 -#define PCI_PREF_MEMORY_ALIGN (1UL << 20) -#define PCI_PREF_MEMORY_SHIFT 16 - -static void pci_bios_init_device_bridge(u16 bdf, void *arg) -{ - pci_bios_allocate_region(bdf, 0); - pci_bios_allocate_region(bdf, 1); - pci_bios_allocate_region(bdf, PCI_ROM_SLOT); - - u32 io_old = pci_bios_io_addr; - u32 mem_old = pci_bios_mem_addr; - u32 prefmem_old = pci_bios_prefmem_addr; - - /* IO BASE is assumed to be 16 bit */ - pci_bios_io_addr = ALIGN(pci_bios_io_addr, PCI_IO_ALIGN); - pci_bios_mem_addr = ALIGN(pci_bios_mem_addr, PCI_MEMORY_ALIGN); - pci_bios_prefmem_addr = - ALIGN(pci_bios_prefmem_addr, PCI_PREF_MEMORY_ALIGN); - - u32 io_base = pci_bios_io_addr; - u32 mem_base = pci_bios_mem_addr; - u32 prefmem_base = pci_bios_prefmem_addr; - - u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS); - if (secbus > 0) { - pci_bios_init_device_in_bus(secbus); - } - - pci_bios_io_addr = ALIGN(pci_bios_io_addr, PCI_IO_ALIGN); - pci_bios_mem_addr = ALIGN(pci_bios_mem_addr, PCI_MEMORY_ALIGN); - pci_bios_prefmem_addr = - ALIGN(pci_bios_prefmem_addr, PCI_PREF_MEMORY_ALIGN); - - u32 io_end = pci_bios_io_addr; - if (io_end == io_base) { - pci_bios_io_addr = io_old; - io_base = 0xffff; - io_end = 1; - } - pci_config_writeb(bdf, PCI_IO_BASE, io_base >> PCI_IO_SHIFT); - pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0); - pci_config_writeb(bdf, PCI_IO_LIMIT, (io_end - 1) >> PCI_IO_SHIFT); - pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0); - - u32 mem_end = pci_bios_mem_addr; - if (mem_end == mem_base) { - pci_bios_mem_addr = mem_old; - mem_base = 0xffffffff; - mem_end = 1; - } - pci_config_writew(bdf, PCI_MEMORY_BASE, mem_base >> PCI_MEMORY_SHIFT); - pci_config_writew(bdf, PCI_MEMORY_LIMIT, (mem_end -1) >> PCI_MEMORY_SHIFT); - - u32 prefmem_end = pci_bios_prefmem_addr; - if (prefmem_end == prefmem_base) { - pci_bios_prefmem_addr = prefmem_old; - prefmem_base = 0xffffffff; - prefmem_end = 1; - } - pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, - prefmem_base >> PCI_PREF_MEMORY_SHIFT); - pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, - (prefmem_end - 1) >> PCI_PREF_MEMORY_SHIFT); - pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, 0); - pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, 0); - - dprintf(1, "PCI: br io = [0x%x, 0x%x)\n", io_base, io_end); - dprintf(1, "PCI: br mem = [0x%x, 0x%x)\n", mem_base, mem_end); - dprintf(1, "PCI: br pref = [0x%x, 0x%x)\n", prefmem_base, prefmem_end); - - u16 cmd = pci_config_readw(bdf, PCI_COMMAND); - cmd &= ~PCI_COMMAND_IO; - if (io_end > io_base) { - cmd |= PCI_COMMAND_IO; - } - cmd &= ~PCI_COMMAND_MEMORY; - if (mem_end > mem_base || prefmem_end > prefmem_base) { - cmd |= PCI_COMMAND_MEMORY; - } - cmd |= PCI_COMMAND_MASTER; - pci_config_writew(bdf, PCI_COMMAND, cmd); - - pci_config_maskw(bdf, PCI_BRIDGE_CONTROL, 0, PCI_BRIDGE_CTL_SERR); -} - -static void storage_ide_init(u16 bdf, void *arg) -{ - /* IDE: we map it as in ISA mode */ - pci_set_io_region_addr(bdf, 0, PORT_ATA1_CMD_BASE); - pci_set_io_region_addr(bdf, 1, PORT_ATA1_CTRL_BASE); - pci_set_io_region_addr(bdf, 2, PORT_ATA2_CMD_BASE); - pci_set_io_region_addr(bdf, 3, PORT_ATA2_CTRL_BASE); -} - -static void pic_ibm_init(u16 bdf, void *arg) -{ - /* PIC, IBM, MPIC & MPIC2 */ - pci_set_io_region_addr(bdf, 0, 0x80800000 + 0x00040000); -} - -static void apple_macio_init(u16 bdf, void *arg) -{ - /* macio bridge */ - pci_set_io_region_addr(bdf, 0, 0x80800000); -} - -static const struct pci_device_id pci_class_tbl[] = { - /* STORAGE IDE */ - PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, - PCI_CLASS_STORAGE_IDE, piix_ide_init), - PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, - PCI_CLASS_STORAGE_IDE, piix_ide_init), - PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, - storage_ide_init), - - /* PIC, IBM, MIPC & MPIC2 */ - PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0x0046, PCI_CLASS_SYSTEM_PIC, - pic_ibm_init), - PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0xFFFF, PCI_CLASS_SYSTEM_PIC, - pic_ibm_init), - - /* 0xff00 */ - PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_init), - PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_init), - - /* PCI bridge */ - PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI, - pci_bios_init_device_bridge), - - /* default */ - PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID, pci_bios_allocate_regions), - - PCI_DEVICE_END, -}; - -static const struct pci_device_id pci_device_tbl[] = { - /* PIIX4 Power Management device (for ACPI) */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - piix4_pm_init), - - PCI_DEVICE_END, -}; - -static void pci_bios_init_device(u16 bdf) -{ - int pin, pic_irq, vendor_id, device_id; - - vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID); - device_id = pci_config_readw(bdf, PCI_DEVICE_ID); - dprintf(1, "PCI: bus=%d devfn=0x%02x: vendor_id=0x%04x device_id=0x%04x\n" - , pci_bdf_to_bus(bdf), pci_bdf_to_devfn(bdf), vendor_id, device_id); - pci_init_device(pci_class_tbl, bdf, NULL); - - /* enable memory mappings */ - pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY); - - /* map the interrupt */ - pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN); - if (pin != 0) { - pin = pci_slot_get_pirq(bdf, pin - 1); - pic_irq = pci_irqs[pin]; - pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pic_irq); - } - - pci_init_device(pci_device_tbl, bdf, NULL); -} - -static void pci_bios_init_device_in_bus(int bus) -{ - int bdf, max; - foreachpci_in_bus(bdf, max, bus) { - pci_bios_init_device(bdf); - } -} - -static void -pci_bios_init_bus_rec(int bus, u8 *pci_bus) -{ - int bdf, max; - u16 class; - - dprintf(1, "PCI: %s bus = 0x%x\n", __func__, bus); - - /* prevent accidental access to unintended devices */ - foreachpci_in_bus(bdf, max, bus) { - class = pci_config_readw(bdf, PCI_CLASS_DEVICE); - if (class == PCI_CLASS_BRIDGE_PCI) { - pci_config_writeb(bdf, PCI_SECONDARY_BUS, 255); - pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0); - } - } - - foreachpci_in_bus(bdf, max, bus) { - class = pci_config_readw(bdf, PCI_CLASS_DEVICE); - if (class != PCI_CLASS_BRIDGE_PCI) { - continue; - } - dprintf(1, "PCI: %s bdf = 0x%x\n", __func__, bdf); - - u8 pribus = pci_config_readb(bdf, PCI_PRIMARY_BUS); - if (pribus != bus) { - dprintf(1, "PCI: primary bus = 0x%x -> 0x%x\n", pribus, bus); - pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus); - } else { - dprintf(1, "PCI: primary bus = 0x%x\n", pribus); - } - - u8 secbus = pci_config_readb(bdf, PCI_SECONDARY_BUS); - (*pci_bus)++; - if (*pci_bus != secbus) { - dprintf(1, "PCI: secondary bus = 0x%x -> 0x%x\n", - secbus, *pci_bus); - secbus = *pci_bus; - pci_config_writeb(bdf, PCI_SECONDARY_BUS, secbus); - } else { - dprintf(1, "PCI: secondary bus = 0x%x\n", secbus); - } - - /* set to max for access to all subordinate buses. - later set it to accurate value */ - u8 subbus = pci_config_readb(bdf, PCI_SUBORDINATE_BUS); - pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255); - - pci_bios_init_bus_rec(secbus, pci_bus); - - if (subbus != *pci_bus) { - dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n", - subbus, *pci_bus); - subbus = *pci_bus; - } else { - dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus); - } - pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, subbus); - } -} - -static void -pci_bios_init_bus(void) -{ - u8 pci_bus = 0; - pci_bios_init_bus_rec(0 /* host bus */, &pci_bus); -} - -void -pci_setup(void) -{ - if (CONFIG_COREBOOT) - // Already done by coreboot. - return; - - dprintf(3, "pci setup\n"); - - pci_bios_io_addr = 0xc000; - pci_bios_mem_addr = BUILD_PCIMEM_START; - pci_bios_prefmem_addr = BUILD_PCIPREFMEM_START; - - pci_bios_init_bus(); - - int bdf, max; - foreachpci(bdf, max) { - pci_init_device(pci_isa_bridge_tbl, bdf, NULL); - } - pci_bios_init_device_in_bus(0 /* host bus */); -} diff --git a/roms/seabios/src/pic.c b/roms/seabios/src/pic.c deleted file mode 100644 index 8992a8b..0000000 --- a/roms/seabios/src/pic.c +++ /dev/null @@ -1,52 +0,0 @@ -// Helpers for working with i8259 interrupt controller. -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "pic.h" // get_pic1_isr -#include "util.h" // dprintf -#include "config.h" // CONFIG_* - -void -set_pics(u8 irq0, u8 irq8) -{ - // Send ICW1 (select OCW1 + will send ICW4) - outb(0x11, PORT_PIC1_CMD); - outb(0x11, PORT_PIC2_CMD); - // Send ICW2 (base irqs: 0x08-0x0f for irq0-7, 0x70-0x77 for irq8-15) - outb(irq0, PORT_PIC1_DATA); - outb(irq8, PORT_PIC2_DATA); - // Send ICW3 (cascaded pic ids) - outb(0x04, PORT_PIC1_DATA); - outb(0x02, PORT_PIC2_DATA); - // Send ICW4 (enable 8086 mode) - outb(0x01, PORT_PIC1_DATA); - outb(0x01, PORT_PIC2_DATA); - // Mask all irqs (except cascaded PIC2 irq) - outb(~PIC1_IRQ2, PORT_PIC1_DATA); - outb(~0, PORT_PIC2_DATA); -} - -void -pic_setup(void) -{ - dprintf(3, "init pic\n"); - set_pics(0x08, 0x70); -} - -// Handler for otherwise unused hardware irqs. -void VISIBLE16 -handle_hwpic1(struct bregs *regs) -{ - dprintf(DEBUG_ISR_hwpic1, "handle_hwpic1 irq=%x\n", get_pic1_isr()); - eoi_pic1(); -} - -void VISIBLE16 -handle_hwpic2(struct bregs *regs) -{ - dprintf(DEBUG_ISR_hwpic2, "handle_hwpic2 irq=%x\n", get_pic2_isr()); - eoi_pic2(); -} diff --git a/roms/seabios/src/pic.h b/roms/seabios/src/pic.h deleted file mode 100644 index c75af3e..0000000 --- a/roms/seabios/src/pic.h +++ /dev/null @@ -1,97 +0,0 @@ -// Helpers for working with i8259 interrupt controller. -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __PIC_H -#define __PIC_H - -#include "ioport.h" // PORT_PIC* -#include "biosvar.h" // SET_IVT - -// PORT_PIC1 bitdefs -#define PIC1_IRQ0 (1<<0) -#define PIC1_IRQ1 (1<<1) -#define PIC1_IRQ2 (1<<2) -#define PIC1_IRQ5 (1<<5) -#define PIC1_IRQ6 (1<<6) -// PORT_PIC2 bitdefs -#define PIC2_IRQ8 (1<<0) -#define PIC2_IRQ12 (1<<4) -#define PIC2_IRQ13 (1<<5) -#define PIC2_IRQ14 (1<<6) - -static inline void -eoi_pic1(void) -{ - // Send eoi (select OCW2 + eoi) - outb(0x20, PORT_PIC1_CMD); -} - -static inline void -eoi_pic2(void) -{ - // Send eoi (select OCW2 + eoi) - outb(0x20, PORT_PIC2_CMD); - eoi_pic1(); -} - -static inline void -unmask_pic1(u8 irq) -{ - outb(inb(PORT_PIC1_DATA) & ~irq, PORT_PIC1_DATA); -} - -static inline void -unmask_pic2(u8 irq) -{ - outb(inb(PORT_PIC2_DATA) & ~irq, PORT_PIC2_DATA); -} - -static inline void -mask_pic1(u8 irq) -{ - outb(inb(PORT_PIC1_DATA) | irq, PORT_PIC1_DATA); -} - -static inline void -mask_pic2(u8 irq) -{ - outb(inb(PORT_PIC2_DATA) | irq, PORT_PIC2_DATA); -} - -static inline u8 -get_pic1_isr(void) -{ - // 0x0b == select OCW1 + read ISR - outb(0x0b, PORT_PIC1_CMD); - return inb(PORT_PIC1_CMD); -} - -static inline u8 -get_pic2_isr(void) -{ - // 0x0b == select OCW1 + read ISR - outb(0x0b, PORT_PIC2_CMD); - return inb(PORT_PIC2_CMD); -} - -static inline void -enable_hwirq(int hwirq, struct segoff_s func) -{ - int vector; - if (hwirq < 8) { - unmask_pic1(1 << hwirq); - vector = 0x08 + hwirq; - } else { - unmask_pic2(1 << (hwirq - 8)); - vector = 0x70 + hwirq - 8; - } - SET_IVT(vector, func); -} - -void set_pics(u8 irq0, u8 irq8); -void pic_setup(void); - -#endif // pic.h diff --git a/roms/seabios/src/pirtable.c b/roms/seabios/src/pirtable.c deleted file mode 100644 index 4c3f1ff..0000000 --- a/roms/seabios/src/pirtable.c +++ /dev/null @@ -1,105 +0,0 @@ -// PIR table generation (for emulators) -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "pci.h" // struct pir_header -#include "util.h" // checksum -#include "biosvar.h" // SET_EBDA - -u16 PirOffset VAR16VISIBLE; - -struct pir_table { - struct pir_header pir; - struct pir_slot slots[6]; -} PACKED; - -extern struct pir_table PIR_TABLE; -#if CONFIG_PIRTABLE && !CONFIG_COREBOOT -struct pir_table PIR_TABLE __aligned(16) VAR16EXPORT = { - .pir = { - .version = 0x0100, - .size = sizeof(struct pir_table), - .router_devfunc = 0x08, - .compatible_devid = 0x122e8086, - }, - .slots = { - { - // first slot entry PCI-to-ISA (embedded) - .dev = 1<<3, - .links = { - {.link = 0x60, .bitmap = 0xdef8}, // INTA# - {.link = 0x61, .bitmap = 0xdef8}, // INTB# - {.link = 0x62, .bitmap = 0xdef8}, // INTC# - {.link = 0x63, .bitmap = 0xdef8}, // INTD# - }, - .slot_nr = 0, // embedded - }, { - // second slot entry: 1st PCI slot - .dev = 2<<3, - .links = { - {.link = 0x61, .bitmap = 0xdef8}, // INTA# - {.link = 0x62, .bitmap = 0xdef8}, // INTB# - {.link = 0x63, .bitmap = 0xdef8}, // INTC# - {.link = 0x60, .bitmap = 0xdef8}, // INTD# - }, - .slot_nr = 1, - }, { - // third slot entry: 2nd PCI slot - .dev = 3<<3, - .links = { - {.link = 0x62, .bitmap = 0xdef8}, // INTA# - {.link = 0x63, .bitmap = 0xdef8}, // INTB# - {.link = 0x60, .bitmap = 0xdef8}, // INTC# - {.link = 0x61, .bitmap = 0xdef8}, // INTD# - }, - .slot_nr = 2, - }, { - // 4th slot entry: 3rd PCI slot - .dev = 4<<3, - .links = { - {.link = 0x63, .bitmap = 0xdef8}, // INTA# - {.link = 0x60, .bitmap = 0xdef8}, // INTB# - {.link = 0x61, .bitmap = 0xdef8}, // INTC# - {.link = 0x62, .bitmap = 0xdef8}, // INTD# - }, - .slot_nr = 3, - }, { - // 5th slot entry: 4rd PCI slot - .dev = 5<<3, - .links = { - {.link = 0x60, .bitmap = 0xdef8}, // INTA# - {.link = 0x61, .bitmap = 0xdef8}, // INTB# - {.link = 0x62, .bitmap = 0xdef8}, // INTC# - {.link = 0x63, .bitmap = 0xdef8}, // INTD# - }, - .slot_nr = 4, - }, { - // 6th slot entry: 5rd PCI slot - .dev = 6<<3, - .links = { - {.link = 0x61, .bitmap = 0xdef8}, // INTA# - {.link = 0x62, .bitmap = 0xdef8}, // INTB# - {.link = 0x63, .bitmap = 0xdef8}, // INTC# - {.link = 0x60, .bitmap = 0xdef8}, // INTD# - }, - .slot_nr = 5, - }, - } -}; -#endif // CONFIG_PIRTABLE && !CONFIG_COREBOOT - -void -create_pirtable(void) -{ - if (! CONFIG_PIRTABLE) - return; - - dprintf(3, "init PIR table\n"); - - PIR_TABLE.pir.signature = PIR_SIGNATURE; - PIR_TABLE.pir.checksum -= checksum(&PIR_TABLE, sizeof(PIR_TABLE)); - PirOffset = (u32)&PIR_TABLE.pir - BUILD_BIOS_ADDR; -} diff --git a/roms/seabios/src/pmm.c b/roms/seabios/src/pmm.c deleted file mode 100644 index 682be39..0000000 --- a/roms/seabios/src/pmm.c +++ /dev/null @@ -1,602 +0,0 @@ -// Post memory manager (PMM) calls -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // checksum -#include "config.h" // BUILD_BIOS_ADDR -#include "memmap.h" // struct e820entry -#include "farptr.h" // GET_FARVAR -#include "biosvar.h" // GET_BDA - - -#if MODESEGMENT -// The 16bit pmm entry points runs in "big real" mode, and can -// therefore read/write to the 32bit malloc variables. -#define GET_PMMVAR(var) ({ \ - SET_SEG(ES, 0); \ - __GET_VAR("addr32 ", ES, (var)); }) -#define SET_PMMVAR(var, val) do { \ - SET_SEG(ES, 0); \ - __SET_VAR("addr32 ", ES, (var), (val)); \ - } while (0) -#else -#define GET_PMMVAR(var) (var) -#define SET_PMMVAR(var, val) do { (var) = (val); } while (0) -#endif - -// Information on a reserved area. -struct allocinfo_s { - struct allocinfo_s *next, **pprev; - void *data, *dataend, *allocend; -}; - -// Information on a tracked memory allocation. -struct allocdetail_s { - struct allocinfo_s detailinfo; - struct allocinfo_s datainfo; - u32 handle; -}; - -// The various memory zones. -struct zone_s { - struct allocinfo_s *info; -}; - -struct zone_s ZoneLow VAR32FLATVISIBLE; -struct zone_s ZoneHigh VAR32FLATVISIBLE; -struct zone_s ZoneFSeg VAR32FLATVISIBLE; -struct zone_s ZoneTmpLow VAR32FLATVISIBLE; -struct zone_s ZoneTmpHigh VAR32FLATVISIBLE; - -struct zone_s *Zones[] VAR32FLATVISIBLE = { - &ZoneTmpLow, &ZoneLow, &ZoneFSeg, &ZoneTmpHigh, &ZoneHigh -}; - - -/**************************************************************** - * low-level memory reservations - ****************************************************************/ - -// Find and reserve space from a given zone -static void * -allocSpace(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) -{ - struct allocinfo_s *info; - for (info = GET_PMMVAR(zone->info); info; info = GET_PMMVAR(info->next)) { - void *dataend = GET_PMMVAR(info->dataend); - void *allocend = GET_PMMVAR(info->allocend); - void *newallocend = (void*)ALIGN_DOWN((u32)allocend - size, align); - if (newallocend >= dataend && newallocend <= allocend) { - // Found space - now reserve it. - struct allocinfo_s **pprev = GET_PMMVAR(info->pprev); - if (!fill) - fill = newallocend; - SET_PMMVAR(fill->next, info); - SET_PMMVAR(fill->pprev, pprev); - SET_PMMVAR(fill->data, newallocend); - SET_PMMVAR(fill->dataend, newallocend + size); - SET_PMMVAR(fill->allocend, allocend); - - SET_PMMVAR(info->allocend, newallocend); - SET_PMMVAR(info->pprev, &fill->next); - SET_PMMVAR(*pprev, fill); - return newallocend; - } - } - return NULL; -} - -// Release space allocated with allocSpace() -static void -freeSpace(struct allocinfo_s *info) -{ - struct allocinfo_s *next = GET_PMMVAR(info->next); - struct allocinfo_s **pprev = GET_PMMVAR(info->pprev); - SET_PMMVAR(*pprev, next); - if (next) { - if (GET_PMMVAR(next->allocend) == GET_PMMVAR(info->data)) - SET_PMMVAR(next->allocend, GET_PMMVAR(info->allocend)); - SET_PMMVAR(next->pprev, pprev); - } -} - -// Add new memory to a zone -static void -addSpace(struct zone_s *zone, void *start, void *end) -{ - // Find position to add space - struct allocinfo_s **pprev = &zone->info, *info; - for (;;) { - info = GET_PMMVAR(*pprev); - if (!info || GET_PMMVAR(info->data) < start) - break; - pprev = &info->next; - } - - // Add space using temporary allocation info. - struct allocdetail_s tempdetail; - tempdetail.datainfo.next = info; - tempdetail.datainfo.pprev = pprev; - tempdetail.datainfo.data = tempdetail.datainfo.dataend = start; - tempdetail.datainfo.allocend = end; - struct allocdetail_s *tempdetailp = MAKE_FLATPTR(GET_SEG(SS), &tempdetail); - SET_PMMVAR(*pprev, &tempdetailp->datainfo); - if (info) - SET_PMMVAR(info->pprev, &tempdetailp->datainfo.next); - - // Allocate final allocation info. - struct allocdetail_s *detail = allocSpace( - &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); - if (!detail) { - detail = allocSpace(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); - if (!detail) { - SET_PMMVAR(*tempdetail.datainfo.pprev, tempdetail.datainfo.next); - if (tempdetail.datainfo.next) - SET_PMMVAR(tempdetail.datainfo.next->pprev - , tempdetail.datainfo.pprev); - warn_noalloc(); - return; - } - } - - // Replace temp alloc space with final alloc space - memcpy_fl(&detail->datainfo, &tempdetailp->datainfo - , sizeof(detail->datainfo)); - SET_PMMVAR(detail->handle, PMM_DEFAULT_HANDLE); - - SET_PMMVAR(*tempdetail.datainfo.pprev, &detail->datainfo); - if (tempdetail.datainfo.next) - SET_PMMVAR(tempdetail.datainfo.next->pprev, &detail->datainfo.next); -} - -// Search all zones for an allocation obtained from allocSpace() -static struct allocinfo_s * -findAlloc(void *data) -{ - int i; - for (i=0; iinfo); info; info = GET_PMMVAR(info->next)) - if (GET_PMMVAR(info->data) == data) - return info; - } - return NULL; -} - -// Return the last sentinal node of a zone -static struct allocinfo_s * -findLast(struct zone_s *zone) -{ - struct allocinfo_s *info = GET_PMMVAR(zone->info); - if (!info) - return NULL; - for (;;) { - struct allocinfo_s *next = GET_PMMVAR(info->next); - if (!next) - return info; - info = next; - } -} - - -/**************************************************************** - * Setup - ****************************************************************/ - -void -malloc_setup(void) -{ - ASSERT32FLAT(); - dprintf(3, "malloc setup\n"); - - ZoneLow.info = ZoneHigh.info = ZoneFSeg.info = NULL; - ZoneTmpLow.info = ZoneTmpHigh.info = NULL; - - // Clear memory in 0xf0000 area. - extern u8 code32flat_start[]; - if ((u32)code32flat_start > BUILD_BIOS_ADDR) - // Clear unused parts of f-segment - memset((void*)BUILD_BIOS_ADDR, 0 - , (u32)code32flat_start - BUILD_BIOS_ADDR); - memset(BiosTableSpace, 0, CONFIG_MAX_BIOSTABLE); - - // Populate temp high ram - u32 highram = 0; - int i; - for (i=e820_count-1; i>=0; i--) { - struct e820entry *en = &e820_list[i]; - u64 end = en->start + en->size; - if (end < 1024*1024) - break; - if (en->type != E820_RAM || end > 0xffffffff) - continue; - u32 s = en->start, e = end; - if (!highram) { - u32 newe = ALIGN_DOWN(e - CONFIG_MAX_HIGHTABLE, MALLOC_MIN_ALIGN); - if (newe <= e && newe >= s) { - highram = newe; - e = newe; - } - } - addSpace(&ZoneTmpHigh, (void*)s, (void*)e); - } - - // Populate other regions - addSpace(&ZoneTmpLow, (void*)BUILD_STACK_ADDR, (void*)BUILD_EBDA_MINIMUM); - addSpace(&ZoneFSeg, BiosTableSpace, &BiosTableSpace[CONFIG_MAX_BIOSTABLE]); - addSpace(&ZoneLow, (void*)BUILD_LOWRAM_END, (void*)BUILD_LOWRAM_END); - if (highram) { - addSpace(&ZoneHigh, (void*)highram - , (void*)highram + CONFIG_MAX_HIGHTABLE); - add_e820(highram, CONFIG_MAX_HIGHTABLE, E820_RESERVED); - } -} - -void -malloc_finalize(void) -{ - dprintf(3, "malloc finalize\n"); - - // Reserve more low-mem if needed. - u32 endlow = GET_BDA(mem_size_kb)*1024; - add_e820(endlow, BUILD_LOWRAM_END-endlow, E820_RESERVED); - - // Give back unused high ram. - struct allocinfo_s *info = findLast(&ZoneHigh); - if (info) { - u32 giveback = ALIGN_DOWN(info->allocend - info->dataend, PAGE_SIZE); - add_e820((u32)info->dataend, giveback, E820_RAM); - dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback); - } - - // Clear low-memory allocations. - memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR); -} - - -/**************************************************************** - * ebda movement - ****************************************************************/ - -// Move ebda -static int -relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size) -{ - u32 lowram = GET_BDA(mem_size_kb) * 1024; - if (oldebda != lowram) - // EBDA isn't at end of ram - give up. - return -1; - - // Do copy (this assumes memcpy copies forward - otherwise memmove - // is needed) - memcpy_fl((void*)newebda, (void*)oldebda, ebda_size * 1024); - - // Update indexes - dprintf(1, "ebda moved from %x to %x\n", oldebda, newebda); - SET_BDA(mem_size_kb, newebda / 1024); - SET_BDA(ebda_seg, FLATPTR_TO_SEG(newebda)); - return 0; -} - -// Support expanding the ZoneLow dynamically. -static void -zonelow_expand(u32 size, u32 align) -{ - struct allocinfo_s *info = findLast(&ZoneLow); - if (!info) - return; - u32 oldpos = (u32)GET_PMMVAR(info->allocend); - u32 newpos = ALIGN_DOWN(oldpos - size, align); - u32 bottom = (u32)GET_PMMVAR(info->dataend); - if (newpos >= bottom && newpos <= oldpos) - // Space already present. - return; - u16 ebda_seg = get_ebda_seg(); - u32 ebda_pos = (u32)MAKE_FLATPTR(ebda_seg, 0); - u8 ebda_size = GET_EBDA2(ebda_seg, size); - u32 ebda_end = ebda_pos + ebda_size * 1024; - if (ebda_end != bottom) - // Something else is after ebda - can't use any existing space. - newpos = ALIGN_DOWN(ebda_end - size, align); - u32 newbottom = ALIGN_DOWN(newpos, 1024); - u32 newebda = ALIGN_DOWN(newbottom - ebda_size * 1024, 1024); - if (newebda < BUILD_EBDA_MINIMUM) - // Not enough space. - return; - - // Move ebda - int ret = relocate_ebda(newebda, ebda_pos, ebda_size); - if (ret) - return; - - // Update zone - if (ebda_end == bottom) { - SET_PMMVAR(info->data, (void*)newbottom); - SET_PMMVAR(info->dataend, (void*)newbottom); - } else - addSpace(&ZoneLow, (void*)newbottom, (void*)ebda_end); -} - -// Check if can expand the given zone to fulfill an allocation -static void * -allocExpandSpace(struct zone_s *zone, u32 size, u32 align - , struct allocinfo_s *fill) -{ - void *data = allocSpace(zone, size, align, fill); - if (data || zone != &ZoneLow) - return data; - - // Make sure to not move ebda while an optionrom is running. - if (unlikely(wait_preempt())) { - data = allocSpace(zone, size, align, fill); - if (data) - return data; - } - - zonelow_expand(size, align); - return allocSpace(zone, size, align, fill); -} - - -/**************************************************************** - * tracked memory allocations - ****************************************************************/ - -// Allocate memory from the given zone and track it as a PMM allocation -void * __malloc -pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align) -{ - if (!size) - return NULL; - - // Find and reserve space for bookkeeping. - struct allocdetail_s *detail = allocSpace( - &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); - if (!detail) { - detail = allocSpace(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); - if (!detail) - return NULL; - } - - // Find and reserve space for main allocation - void *data = allocExpandSpace(zone, size, align, &detail->datainfo); - if (!data) { - freeSpace(&detail->detailinfo); - return NULL; - } - - dprintf(8, "pmm_malloc zone=%p handle=%x size=%d align=%x" - " ret=%p (detail=%p)\n" - , zone, handle, size, align - , data, detail); - SET_PMMVAR(detail->handle, handle); - - return data; -} - -// Free a data block allocated with pmm_malloc -int -pmm_free(void *data) -{ - struct allocinfo_s *info = findAlloc(data); - if (!info || data == (void*)info || data == GET_PMMVAR(info->dataend)) - return -1; - struct allocdetail_s *detail = container_of( - info, struct allocdetail_s, datainfo); - dprintf(8, "pmm_free %p (detail=%p)\n", data, detail); - freeSpace(info); - freeSpace(&detail->detailinfo); - return 0; -} - -// Find the amount of free space in a given zone. -static u32 -pmm_getspace(struct zone_s *zone) -{ - // XXX - doesn't account for ZoneLow being able to grow. - // XXX - results not reliable when CONFIG_THREAD_OPTIONROMS - u32 maxspace = 0; - struct allocinfo_s *info; - for (info = GET_PMMVAR(zone->info); info; info = GET_PMMVAR(info->next)) { - u32 space = GET_PMMVAR(info->allocend) - GET_PMMVAR(info->dataend); - if (space > maxspace) - maxspace = space; - } - - if (zone != &ZoneTmpHigh && zone != &ZoneTmpLow) - return maxspace; - // Account for space needed for PMM tracking. - u32 reserve = ALIGN(sizeof(struct allocdetail_s), MALLOC_MIN_ALIGN); - if (maxspace <= reserve) - return 0; - return maxspace - reserve; -} - -// Find the data block allocated with pmm_malloc with a given handle. -static void * -pmm_find(u32 handle) -{ - int i; - for (i=0; iinfo); info - ; info = GET_PMMVAR(info->next)) { - if (GET_PMMVAR(info->data) != (void*)info) - continue; - struct allocdetail_s *detail = container_of( - info, struct allocdetail_s, detailinfo); - if (GET_PMMVAR(detail->handle) == handle) - return GET_PMMVAR(detail->datainfo.data); - } - } - return NULL; -} - - -/**************************************************************** - * pmm interface - ****************************************************************/ - -struct pmmheader { - u32 signature; - u8 version; - u8 length; - u8 checksum; - u16 entry_offset; - u16 entry_seg; - u8 reserved[5]; -} PACKED; - -extern struct pmmheader PMMHEADER; - -#define PMM_SIGNATURE 0x4d4d5024 // $PMM - -#if CONFIG_PMM -struct pmmheader PMMHEADER __aligned(16) VAR16EXPORT = { - .version = 0x01, - .length = sizeof(PMMHEADER), - .entry_seg = SEG_BIOS, -}; -#endif - -#define PMM_FUNCTION_NOT_SUPPORTED 0xffffffff - -// PMM - allocate -static u32 -handle_pmm00(u16 *args) -{ - u32 length = *(u32*)&args[1], handle = *(u32*)&args[3]; - u16 flags = args[5]; - dprintf(3, "pmm00: length=%x handle=%x flags=%x\n" - , length, handle, flags); - struct zone_s *lowzone = &ZoneTmpLow, *highzone = &ZoneTmpHigh; - if (flags & 8) { - // Permanent memory request. - lowzone = &ZoneLow; - highzone = &ZoneHigh; - } - if (!length) { - // Memory size request - switch (flags & 3) { - default: - case 0: - return 0; - case 1: - return pmm_getspace(lowzone); - case 2: - return pmm_getspace(highzone); - case 3: { - u32 spacelow = pmm_getspace(lowzone); - u32 spacehigh = pmm_getspace(highzone); - if (spacelow > spacehigh) - return spacelow; - return spacehigh; - } - } - } - u32 size = length * 16; - if ((s32)size <= 0) - return 0; - u32 align = MALLOC_MIN_ALIGN; - if (flags & 4) { - align = 1<<__ffs(size); - if (align < MALLOC_MIN_ALIGN) - align = MALLOC_MIN_ALIGN; - } - switch (flags & 3) { - default: - case 0: - return 0; - case 1: - return (u32)pmm_malloc(lowzone, handle, size, align); - case 2: - return (u32)pmm_malloc(highzone, handle, size, align); - case 3: { - void *data = pmm_malloc(lowzone, handle, size, align); - if (data) - return (u32)data; - return (u32)pmm_malloc(highzone, handle, size, align); - } - } -} - -// PMM - find -static u32 -handle_pmm01(u16 *args) -{ - u32 handle = *(u32*)&args[1]; - dprintf(3, "pmm01: handle=%x\n", handle); - if (handle == PMM_DEFAULT_HANDLE) - return 0; - return (u32)pmm_find(handle); -} - -// PMM - deallocate -static u32 -handle_pmm02(u16 *args) -{ - u32 buffer = *(u32*)&args[1]; - dprintf(3, "pmm02: buffer=%x\n", buffer); - int ret = pmm_free((void*)buffer); - if (ret) - // Error - return 1; - return 0; -} - -static u32 -handle_pmmXX(u16 *args) -{ - return PMM_FUNCTION_NOT_SUPPORTED; -} - -u32 VISIBLE16 -handle_pmm(u16 *args) -{ - if (! CONFIG_PMM) - return PMM_FUNCTION_NOT_SUPPORTED; - - u16 arg1 = args[0]; - dprintf(DEBUG_HDL_pmm, "pmm call arg1=%x\n", arg1); - - switch (arg1) { - case 0x00: return handle_pmm00(args); - case 0x01: return handle_pmm01(args); - case 0x02: return handle_pmm02(args); - default: return handle_pmmXX(args); - } -} - -// romlayout.S -extern void entry_pmm(void); - -void -pmm_setup(void) -{ - if (! CONFIG_PMM) - return; - - dprintf(3, "init PMM\n"); - - PMMHEADER.signature = PMM_SIGNATURE; - PMMHEADER.entry_offset = (u32)entry_pmm - BUILD_BIOS_ADDR; - PMMHEADER.checksum -= checksum(&PMMHEADER, sizeof(PMMHEADER)); -} - -void -pmm_finalize(void) -{ - if (! CONFIG_PMM) - return; - - dprintf(3, "finalize PMM\n"); - - PMMHEADER.signature = 0; - PMMHEADER.entry_offset = 0; -} diff --git a/roms/seabios/src/pnpbios.c b/roms/seabios/src/pnpbios.c deleted file mode 100644 index b1bebc9..0000000 --- a/roms/seabios/src/pnpbios.c +++ /dev/null @@ -1,103 +0,0 @@ -// PNP BIOS calls -// -// Copyright (C) 2008 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // checksum -#include "config.h" // BUILD_BIOS_ADDR -#include "farptr.h" // SET_FARVAR - -struct pnpheader { - u32 signature; - u8 version; - u8 length; - u16 control; - u8 checksum; - u32 eventloc; - u16 real_ip; - u16 real_cs; - u16 prot_ip; - u32 prot_base; - u32 oemid; - u16 real_ds; - u32 prot_database; -} PACKED; - -extern struct pnpheader PNPHEADER; -extern char pnp_string[]; - -#if CONFIG_PNPBIOS -struct pnpheader PNPHEADER __aligned(16) VAR16EXPORT = { - .signature = PNP_SIGNATURE, - .version = 0x10, - .length = sizeof(PNPHEADER), - .real_cs = SEG_BIOS, - .prot_base = BUILD_BIOS_ADDR, - .real_ds = SEG_BIOS, - .prot_database = BUILD_BIOS_ADDR, -}; -#else -// We need a copy of this string in the 0xf000 segment, but we are not -// actually a PnP BIOS, so make sure it is *not* aligned, so OSes will -// not see it if they scan. -char pnp_string[] __aligned(2) VAR16VISIBLE = " $PnP"; -#endif - -#define FUNCTION_NOT_SUPPORTED 0x82 - -// BBS - Get Version and Installation Check -static u16 -handle_pnp60(u16 *args) -{ - u16 version_ptr = args[1]; - u16 version_seg = args[2]; - SET_FARVAR(version_seg, *(u16*)(version_ptr+0), 0x0101); - return 0; -} - -static u16 -handle_pnpXX(u16 *args) -{ - return FUNCTION_NOT_SUPPORTED; -} - -u16 VISIBLE16 -handle_pnp(u16 *args) -{ - if (! CONFIG_PNPBIOS) - return FUNCTION_NOT_SUPPORTED; - - u16 arg1 = args[0]; - dprintf(DEBUG_HDL_pnp, "pnp call arg1=%x\n", arg1); - - switch (arg1) { - case 0x60: return handle_pnp60(args); - default: return handle_pnpXX(args); - } -} - -u16 -get_pnp_offset(void) -{ - if (! CONFIG_PNPBIOS) - return (u32)pnp_string + 1 - BUILD_BIOS_ADDR; - return (u32)&PNPHEADER - BUILD_BIOS_ADDR; -} - -// romlayout.S -extern void entry_pnp_real(void); -extern void entry_pnp_prot(void); - -void -pnp_setup(void) -{ - if (! CONFIG_PNPBIOS) - return; - - dprintf(3, "init PNPBIOS table\n"); - - PNPHEADER.real_ip = (u32)entry_pnp_real - BUILD_BIOS_ADDR; - PNPHEADER.prot_ip = (u32)entry_pnp_prot - BUILD_BIOS_ADDR; - PNPHEADER.checksum -= checksum(&PNPHEADER, sizeof(PNPHEADER)); -} diff --git a/roms/seabios/src/post.c b/roms/seabios/src/post.c deleted file mode 100644 index 5d0e2cb..0000000 --- a/roms/seabios/src/post.c +++ /dev/null @@ -1,274 +0,0 @@ -// 32bit code to Power On Self Test (POST) a machine. -// -// Copyright (C) 2008-2010 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "ioport.h" // PORT_* -#include "config.h" // CONFIG_* -#include "cmos.h" // CMOS_* -#include "util.h" // memset -#include "biosvar.h" // struct bios_data_area_s -#include "disk.h" // floppy_drive_setup -#include "ata.h" // ata_setup -#include "memmap.h" // add_e820 -#include "pic.h" // pic_setup -#include "pci.h" // create_pirtable -#include "acpi.h" // acpi_bios_init -#include "bregs.h" // struct bregs -#include "mptable.h" // mptable_init -#include "boot.h" // IPL -#include "usb.h" // usb_setup -#include "smbios.h" // smbios_init -#include "paravirt.h" // qemu_cfg_port_probe -#include "ps2port.h" // ps2port_setup -#include "virtio-blk.h" // virtio_blk_setup - -static void -init_ivt(void) -{ - dprintf(3, "init ivt\n"); - - // Initialize all vectors to the default handler. - int i; - for (i=0; i<256; i++) - SET_IVT(i, FUNC16(entry_iret_official)); - - // Initialize all hw vectors to a default hw handler. - for (i=0x08; i<=0x0f; i++) - SET_IVT(i, FUNC16(entry_hwpic1)); - for (i=0x70; i<=0x77; i++) - SET_IVT(i, FUNC16(entry_hwpic2)); - - // Initialize software handlers. - SET_IVT(0x02, FUNC16(entry_02)); - SET_IVT(0x10, FUNC16(entry_10)); - SET_IVT(0x11, FUNC16(entry_11)); - SET_IVT(0x12, FUNC16(entry_12)); - SET_IVT(0x13, FUNC16(entry_13_official)); - SET_IVT(0x14, FUNC16(entry_14)); - SET_IVT(0x15, FUNC16(entry_15)); - SET_IVT(0x16, FUNC16(entry_16)); - SET_IVT(0x17, FUNC16(entry_17)); - SET_IVT(0x18, FUNC16(entry_18)); - SET_IVT(0x19, FUNC16(entry_19_official)); - SET_IVT(0x1a, FUNC16(entry_1a)); - SET_IVT(0x40, FUNC16(entry_40)); - - // INT 60h-66h reserved for user interrupt - for (i=0x60; i<=0x66; i++) - SET_IVT(i, SEGOFF(0, 0)); - - // set vector 0x79 to zero - // this is used by 'gardian angel' protection system - SET_IVT(0x79, SEGOFF(0, 0)); - - SET_IVT(0x1E, SEGOFF(SEG_BIOS, (u32)&diskette_param_table2 - BUILD_BIOS_ADDR)); -} - -static void -init_bda(void) -{ - dprintf(3, "init bda\n"); - - struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0); - memset(bda, 0, sizeof(*bda)); - - int esize = EBDA_SIZE_START; - SET_BDA(mem_size_kb, BUILD_LOWRAM_END/1024 - esize); - u16 eseg = EBDA_SEGMENT_START; - SET_BDA(ebda_seg, eseg); - - // Init ebda - struct extended_bios_data_area_s *ebda = get_ebda_ptr(); - memset(ebda, 0, sizeof(*ebda)); - ebda->size = esize; -} - -static void -ram_probe(void) -{ - dprintf(3, "Find memory size\n"); - if (CONFIG_COREBOOT) { - coreboot_setup(); - } else { - // On emulators, get memory size from nvram. - u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) - | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); - if (rs) - rs += 16 * 1024 * 1024; - else - rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) - | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) - + 1 * 1024 * 1024); - RamSize = rs; - add_e820(0, rs, E820_RAM); - - // Check for memory over 4Gig - u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) - | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) - | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); - RamSizeOver4G = high; - add_e820(0x100000000ull, high, E820_RAM); - - /* reserve 256KB BIOS area at the end of 4 GB */ - add_e820(0xfffc0000, 256*1024, E820_RESERVED); - } - - // Don't declare any memory between 0xa0000 and 0x100000 - add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); - - // Mark known areas as reserved. - u16 ebda_seg = get_ebda_seg(); - add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA2(ebda_seg, size) * 1024 - , E820_RESERVED); - add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); - - u32 count = qemu_cfg_e820_entries(); - if (count) { - struct e820_reservation entry; - int i; - - for (i = 0; i < count; i++) { - qemu_cfg_e820_load_next(&entry); - add_e820(entry.address, entry.length, entry.type); - } - } else if (kvm_para_available()) { - // Backwards compatibility - provide hard coded range. - // 4 pages before the bios, 3 pages for vmx tss pages, the - // other page for EPT real mode pagetable - add_e820(0xfffbc000, 4*4096, E820_RESERVED); - } - - dprintf(1, "Ram Size=0x%08x (0x%08x%08x high)\n" - , RamSize, (u32)(RamSizeOver4G >> 32), (u32)RamSizeOver4G); -} - -static void -init_bios_tables(void) -{ - if (CONFIG_COREBOOT) { - coreboot_copy_biostable(); - return; - } - - create_pirtable(); - - mptable_init(); - - smbios_init(); - - acpi_bios_init(); -} - -// Initialize hardware devices -static void -init_hw(void) -{ - usb_setup(); - ps2port_setup(); - lpt_setup(); - serial_setup(); - - floppy_setup(); - ata_setup(); - ramdisk_setup(); - virtio_blk_setup(); -} - -// Main setup code. -static void -post(void) -{ - // Detect and init ram. - init_ivt(); - init_bda(); - memmap_setup(); - qemu_cfg_port_probe(); - ram_probe(); - malloc_setup(); - thread_setup(); - - // Init base pc hardware. - pic_setup(); - timer_setup(); - mathcp_setup(); - - // Initialize mtrr - smp_probe_setup(); - mtrr_setup(); - - // Initialize pci - pci_setup(); - smm_init(); - - // Initialize internal tables - boot_setup(); - drive_setup(); - - // Start hardware initialization (if optionrom threading) - if (CONFIG_THREADS && CONFIG_THREAD_OPTIONROMS) - init_hw(); - - // Find and initialize other cpus - smp_probe(); - - // Setup interfaces that option roms may need - bios32_setup(); - pmm_setup(); - pnp_setup(); - kbd_setup(); - mouse_setup(); - init_bios_tables(); - - // Run vga option rom - vga_setup(); - - // Do hardware initialization (if running synchronously) - if (!CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS) { - init_hw(); - wait_threads(); - } - - // Run option roms - optionrom_setup(); - - // Run BCVs and show optional boot menu - boot_prep(); - - // Finalize data structures before boot - cdemu_setup(); - pmm_finalize(); - malloc_finalize(); - memmap_finalize(); -} - -// 32-bit entry point. -void VISIBLE32FLAT -_start(void) -{ - init_dma(); - - debug_serial_setup(); - dprintf(1, "Start bios (version %s)\n", VERSION); - - // Allow writes to modify bios area (0xf0000) - make_bios_writable(); - - // Perform main setup code. - post(); - - // Setup bios checksum. - BiosChecksum -= checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE); - - // Write protect bios memory. - make_bios_readonly(); - - // Invoke int 19 to start boot process. - dprintf(3, "Jump to int19\n"); - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_IF; - call16_int(0x19, &br); -} diff --git a/roms/seabios/src/ps2port.c b/roms/seabios/src/ps2port.c deleted file mode 100644 index ccbd2f6..0000000 --- a/roms/seabios/src/ps2port.c +++ /dev/null @@ -1,460 +0,0 @@ -// Support for handling the PS/2 mouse/keyboard ports. -// -// Copyright (C) 2008 Kevin O'Connor -// Several ideas taken from code Copyright (c) 1999-2004 Vojtech Pavlik -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "ioport.h" // inb -#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA -#include "ps2port.h" // ps2_kbd_command -#include "pic.h" // eoi_pic1 - - -/**************************************************************** - * Low level i8042 commands. - ****************************************************************/ - -// Timeout value. -#define I8042_CTL_TIMEOUT 10000 - -#define I8042_BUFFER_SIZE 16 - -static int -i8042_wait_read(void) -{ - dprintf(7, "i8042_wait_read\n"); - int i; - for (i=0; i> 8) & 0xf; - int send = (command >> 12) & 0xf; - - // Send the command. - int ret = i8042_wait_write(); - if (ret) - return ret; - outb(command, PORT_PS2_STATUS); - - // Send parameters (if any). - int i; - for (i = 0; i < send; i++) { - ret = i8042_wait_write(); - if (ret) - return ret; - outb(param[i], PORT_PS2_DATA); - } - - // Receive parameters (if any). - for (i = 0; i < receive; i++) { - ret = i8042_wait_read(); - if (ret) - return ret; - param[i] = inb(PORT_PS2_DATA); - dprintf(7, "i8042 param=%x\n", param[i]); - } - - return 0; -} - -int -i8042_command(int command, u8 *param) -{ - dprintf(7, "i8042_command cmd=%x\n", command); - int ret = __i8042_command(command, param); - if (ret) - dprintf(2, "i8042 command %x failed\n", command); - return ret; -} - -static int -i8042_kbd_write(u8 c) -{ - dprintf(7, "i8042_kbd_write c=%d\n", c); - int ret = i8042_wait_write(); - if (! ret) - outb(c, PORT_PS2_DATA); - return ret; -} - -static int -i8042_aux_write(u8 c) -{ - return i8042_command(I8042_CMD_AUX_SEND, &c); -} - - -/**************************************************************** - * Device commands. - ****************************************************************/ - -#define PS2_RET_ACK 0xfa -#define PS2_RET_NAK 0xfe - -static int -ps2_recvbyte(int aux, int needack, int timeout) -{ - u64 end = calc_future_tsc(timeout); - for (;;) { - u8 status = inb(PORT_PS2_STATUS); - if (status & I8042_STR_OBF) { - u8 data = inb(PORT_PS2_DATA); - dprintf(7, "ps2 read %x\n", data); - - if (!!(status & I8042_STR_AUXDATA) == aux) { - if (!needack) - return data; - if (data == PS2_RET_ACK) - return data; - if (data == PS2_RET_NAK) { - dprintf(1, "Got ps2 nak (status=%x)\n", status); - return data; - } - } - - // This data not part of command - just discard it. - dprintf(1, "Discarding ps2 data %02x (status=%02x)\n", data, status); - } - - if (check_tsc(end)) { - // Don't warn on second byte of a reset - if (timeout > 100) - warn_timeout(); - return -1; - } - yield(); - } -} - -static int -ps2_sendbyte(int aux, u8 command, int timeout) -{ - dprintf(7, "ps2_sendbyte aux=%d cmd=%x\n", aux, command); - int ret; - if (aux) - ret = i8042_aux_write(command); - else - ret = i8042_kbd_write(command); - if (ret) - return ret; - - // Read ack. - ret = ps2_recvbyte(aux, 1, timeout); - if (ret < 0) - return ret; - if (ret != PS2_RET_ACK) - return -1; - - return 0; -} - -static int -__ps2_command(int aux, int command, u8 *param) -{ - int ret2; - int receive = (command >> 8) & 0xf; - int send = (command >> 12) & 0xf; - - // Disable interrupts and keyboard/mouse. - u8 ps2ctr = GET_EBDA(ps2ctr); - u8 newctr = ((ps2ctr | I8042_CTR_AUXDIS | I8042_CTR_KBDDIS) - & ~(I8042_CTR_KBDINT|I8042_CTR_AUXINT)); - dprintf(6, "i8042 ctr old=%x new=%x\n", ps2ctr, newctr); - int ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr); - if (ret) - return ret; - - // Flush any interrupts already pending. - yield(); - - // Enable port command is being sent to. - if (aux) - newctr &= ~I8042_CTR_AUXDIS; - else - newctr &= ~I8042_CTR_KBDDIS; - ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr); - if (ret) - goto fail; - - if (command == ATKBD_CMD_RESET_BAT) { - // Reset is special wrt timeouts and bytes received. - - // Send command. - ret = ps2_sendbyte(aux, command, 1000); - if (ret) - goto fail; - - // Receive parameters. - ret = ps2_recvbyte(aux, 0, 4000); - if (ret < 0) - goto fail; - param[0] = ret; - ret = ps2_recvbyte(aux, 0, 100); - if (ret < 0) - // Some devices only respond with one byte on reset. - ret = 0; - param[1] = ret; - } else if (command == ATKBD_CMD_GETID) { - // Getid is special wrt bytes received. - - // Send command. - ret = ps2_sendbyte(aux, command, 200); - if (ret) - goto fail; - - // Receive parameters. - ret = ps2_recvbyte(aux, 0, 500); - if (ret < 0) - goto fail; - param[0] = ret; - if (ret == 0xab || ret == 0xac || ret == 0x2b || ret == 0x5d - || ret == 0x60 || ret == 0x47) { - // These ids (keyboards) return two bytes. - ret = ps2_recvbyte(aux, 0, 500); - if (ret < 0) - goto fail; - param[1] = ret; - } else { - param[1] = 0; - } - } else { - // Send command. - ret = ps2_sendbyte(aux, command, 200); - if (ret) - goto fail; - - // Send parameters (if any). - int i; - for (i = 0; i < send; i++) { - ret = ps2_sendbyte(aux, param[i], 200); - if (ret) - goto fail; - } - - // Receive parameters (if any). - for (i = 0; i < receive; i++) { - ret = ps2_recvbyte(aux, 0, 500); - if (ret < 0) - goto fail; - param[i] = ret; - } - } - - ret = 0; - -fail: - // Restore interrupts and keyboard/mouse. - ret2 = i8042_command(I8042_CMD_CTL_WCTR, &ps2ctr); - if (ret2) - return ret2; - - return ret; -} - -static int -ps2_command(int aux, int command, u8 *param) -{ - dprintf(7, "ps2_command aux=%d cmd=%x\n", aux, command); - int ret = __ps2_command(aux, command, param); - if (ret) - dprintf(2, "ps2 command %x failed (aux=%d)\n", command, aux); - return ret; -} - -int -ps2_kbd_command(int command, u8 *param) -{ - return ps2_command(0, command, param); -} - -int -ps2_mouse_command(int command, u8 *param) -{ - return ps2_command(1, command, param); -} - - -/**************************************************************** - * IRQ handlers - ****************************************************************/ - -// INT74h : PS/2 mouse hardware interrupt -void VISIBLE16 -handle_74(void) -{ - if (! CONFIG_PS2PORT) - return; - - debug_isr(DEBUG_ISR_74); - - u8 v = inb(PORT_PS2_STATUS); - if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA)) - != (I8042_STR_OBF|I8042_STR_AUXDATA)) { - dprintf(1, "ps2 mouse irq but no mouse data.\n"); - goto done; - } - v = inb(PORT_PS2_DATA); - - if (!(GET_EBDA(ps2ctr) & I8042_CTR_AUXINT)) - // Interrupts not enabled. - goto done; - - process_mouse(v); - -done: - eoi_pic2(); -} - -// INT09h : Keyboard Hardware Service Entry Point -void VISIBLE16 -handle_09(void) -{ - if (! CONFIG_PS2PORT) - return; - - debug_isr(DEBUG_ISR_09); - - // read key from keyboard controller - u8 v = inb(PORT_PS2_STATUS); - if (v & I8042_STR_AUXDATA) { - dprintf(1, "ps2 keyboard irq but found mouse data?!\n"); - goto done; - } - v = inb(PORT_PS2_DATA); - - if (!(GET_EBDA(ps2ctr) & I8042_CTR_KBDINT)) - // Interrupts not enabled. - goto done; - - process_key(v); - -done: - eoi_pic1(); -} - - -/**************************************************************** - * Setup - ****************************************************************/ - -static void -keyboard_init(void *data) -{ - /* flush incoming keys */ - int ret = i8042_flush(); - if (ret) - return; - - // Controller self-test. - u8 param[2]; - ret = i8042_command(I8042_CMD_CTL_TEST, param); - if (ret) - return; - if (param[0] != 0x55) { - dprintf(1, "i8042 self test failed (got %x not 0x55)\n", param[0]); - return; - } - - // Controller keyboard test. - ret = i8042_command(I8042_CMD_KBD_TEST, param); - if (ret) - return; - if (param[0] != 0x00) { - dprintf(1, "i8042 keyboard test failed (got %x not 0x00)\n", param[0]); - return; - } - - // Disable keyboard and mouse events. - SET_EBDA(ps2ctr, I8042_CTR_KBDDIS | I8042_CTR_AUXDIS); - - - /* ------------------- keyboard side ------------------------*/ - /* reset keyboard and self test (keyboard side) */ - ret = ps2_kbd_command(ATKBD_CMD_RESET_BAT, param); - if (ret) - return; - if (param[0] != 0xaa) { - dprintf(1, "keyboard self test failed (got %x not 0xaa)\n", param[0]); - return; - } - - /* Disable keyboard */ - ret = ps2_kbd_command(ATKBD_CMD_RESET_DIS, NULL); - if (ret) - return; - - // Set scancode command (mode 2) - param[0] = 0x02; - ret = ps2_kbd_command(ATKBD_CMD_SSCANSET, param); - if (ret) - return; - - // Keyboard Mode: disable mouse, scan code convert, enable kbd IRQ - SET_EBDA(ps2ctr, I8042_CTR_AUXDIS | I8042_CTR_XLATE | I8042_CTR_KBDINT); - - /* Enable keyboard */ - ret = ps2_kbd_command(ATKBD_CMD_ENABLE, NULL); - if (ret) - return; - - dprintf(1, "PS2 keyboard initialized\n"); -} - -void -ps2port_setup(void) -{ - ASSERT32FLAT(); - if (! CONFIG_PS2PORT) - return; - dprintf(3, "init ps2port\n"); - - enable_hwirq(1, FUNC16(entry_09)); - enable_hwirq(12, FUNC16(entry_74)); - - run_thread(keyboard_init, NULL); -} diff --git a/roms/seabios/src/ps2port.h b/roms/seabios/src/ps2port.h deleted file mode 100644 index afb0e78..0000000 --- a/roms/seabios/src/ps2port.h +++ /dev/null @@ -1,64 +0,0 @@ -// Basic ps2 port (keyboard/mouse) command handling. -#ifndef __PS2PORT_H -#define __PS2PORT_H - -#include "types.h" // u8 - -// Standard commands. -#define I8042_CMD_CTL_RCTR 0x0120 -#define I8042_CMD_CTL_WCTR 0x1060 -#define I8042_CMD_CTL_TEST 0x01aa - -#define I8042_CMD_KBD_TEST 0x01ab -#define I8042_CMD_KBD_DISABLE 0x00ad -#define I8042_CMD_KBD_ENABLE 0x00ae - -#define I8042_CMD_AUX_DISABLE 0x00a7 -#define I8042_CMD_AUX_ENABLE 0x00a8 -#define I8042_CMD_AUX_SEND 0x10d4 - -// Keyboard commands -#define ATKBD_CMD_SETLEDS 0x10ed -#define ATKBD_CMD_SSCANSET 0x10f0 -#define ATKBD_CMD_GETID 0x02f2 -#define ATKBD_CMD_ENABLE 0x00f4 -#define ATKBD_CMD_RESET_DIS 0x00f5 -#define ATKBD_CMD_RESET_BAT 0x02ff - -// Mouse commands -#define PSMOUSE_CMD_SETSCALE11 0x00e6 -#define PSMOUSE_CMD_SETSCALE21 0x00e7 -#define PSMOUSE_CMD_SETRES 0x10e8 -#define PSMOUSE_CMD_GETINFO 0x03e9 -#define PSMOUSE_CMD_GETID 0x02f2 -#define PSMOUSE_CMD_SETRATE 0x10f3 -#define PSMOUSE_CMD_ENABLE 0x00f4 -#define PSMOUSE_CMD_DISABLE 0x00f5 -#define PSMOUSE_CMD_RESET_BAT 0x02ff - -// Status register bits. -#define I8042_STR_PARITY 0x80 -#define I8042_STR_TIMEOUT 0x40 -#define I8042_STR_AUXDATA 0x20 -#define I8042_STR_KEYLOCK 0x10 -#define I8042_STR_CMDDAT 0x08 -#define I8042_STR_MUXERR 0x04 -#define I8042_STR_IBF 0x02 -#define I8042_STR_OBF 0x01 - -// Control register bits. -#define I8042_CTR_KBDINT 0x01 -#define I8042_CTR_AUXINT 0x02 -#define I8042_CTR_IGNKEYLOCK 0x08 -#define I8042_CTR_KBDDIS 0x10 -#define I8042_CTR_AUXDIS 0x20 -#define I8042_CTR_XLATE 0x40 - -// functions -int i8042_flush(void); -int i8042_command(int command, u8 *param); -int ps2_kbd_command(int command, u8 *param); -int ps2_mouse_command(int command, u8 *param); -void ps2port_setup(void); - -#endif // ps2port.h diff --git a/roms/seabios/src/ramdisk.c b/roms/seabios/src/ramdisk.c deleted file mode 100644 index be1de56..0000000 --- a/roms/seabios/src/ramdisk.c +++ /dev/null @@ -1,100 +0,0 @@ -// Code for emulating a drive via high-memory accesses. -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "disk.h" // process_ramdisk_op -#include "util.h" // dprintf -#include "memmap.h" // add_e820 -#include "biosvar.h" // GET_GLOBAL -#include "bregs.h" // struct bregs - -void -ramdisk_setup(void) -{ - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY) - return; - - // Find image. - struct cbfs_file *file = cbfs_findprefix("floppyimg/", NULL); - if (!file) - return; - u32 size = cbfs_datasize(file); - dprintf(3, "Found floppy file %s of size %d\n", cbfs_filename(file), size); - int ftype = find_floppy_type(size); - if (ftype < 0) { - dprintf(3, "No floppy type found for ramdisk size\n"); - return; - } - - // Allocate ram for image. - void *pos = memalign_tmphigh(PAGE_SIZE, size); - if (!pos) { - warn_noalloc(); - return; - } - add_e820((u32)pos, size, E820_RESERVED); - - // Copy image into ram. - cbfs_copyfile(file, pos, size); - - // Setup driver. - dprintf(1, "Mapping CBFS floppy %s to addr %p\n", cbfs_filename(file), pos); - struct drive_s *drive_g = addFloppy((u32)pos, ftype, DTYPE_RAMDISK); - if (!drive_g) - strtcpy(drive_g->desc, cbfs_filename(file), MAXDESCSIZE); -} - -static int -ramdisk_copy(struct disk_op_s *op, int iswrite) -{ - u32 offset = GET_GLOBAL(op->drive_g->cntl_id); - offset += (u32)op->lba * DISK_SECTOR_SIZE; - u64 opd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)op->buf_fl); - u64 ramd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE(offset); - - u64 gdt[6]; - if (iswrite) { - gdt[2] = opd; - gdt[3] = ramd; - } else { - gdt[2] = ramd; - gdt[3] = opd; - } - - // Call int 1587 to copy data. - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_CF|F_IF; - br.ah = 0x87; - br.es = GET_SEG(SS); - br.si = (u32)gdt; - br.cx = op->count * DISK_SECTOR_SIZE / 2; - call16_int(0x15, &br); - - if (br.flags & F_CF) - return DISK_RET_EBADTRACK; - return DISK_RET_SUCCESS; -} - -int -process_ramdisk_op(struct disk_op_s *op) -{ - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY) - return 0; - - switch (op->command) { - case CMD_READ: - return ramdisk_copy(op, 0); - case CMD_WRITE: - return ramdisk_copy(op, 1); - case CMD_VERIFY: - case CMD_FORMAT: - case CMD_RESET: - return DISK_RET_SUCCESS; - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} diff --git a/roms/seabios/src/resume.c b/roms/seabios/src/resume.c deleted file mode 100644 index 81ad1ac..0000000 --- a/roms/seabios/src/resume.c +++ /dev/null @@ -1,125 +0,0 @@ -// Code for handling calls to "post" that are resume related. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "ioport.h" // outb -#include "pic.h" // eoi_pic2 -#include "biosvar.h" // struct bios_data_area_s -#include "bregs.h" // struct bregs -#include "acpi.h" // find_resume_vector - -// Reset DMA controller -void -init_dma(void) -{ - // first reset the DMA controllers - outb(0, PORT_DMA1_MASTER_CLEAR); - outb(0, PORT_DMA2_MASTER_CLEAR); - - // then initialize the DMA controllers - outb(0xc0, PORT_DMA2_MODE_REG); - outb(0x00, PORT_DMA2_MASK_REG); -} - -// Handler for post calls that look like a resume. -void VISIBLE16 -handle_resume(u8 status) -{ - init_dma(); - - debug_serial_setup(); - dprintf(1, "In resume (status=%d)\n", status); - - switch (status) { - case 0xfe: - if (CONFIG_S3_RESUME) { - // S3 resume request. Jump to 32bit mode to handle the resume. - asm volatile( - "movw %w1, %%ss\n" - "movl %0, %%esp\n" - "pushl $s3_resume\n" - "jmp transition32\n" - : : "i"(BUILD_S3RESUME_STACK_ADDR), "r"(0) - ); - break; - } - // NO BREAK - case 0x00: - case 0x0d ... 0xfd: - case 0xff: - // Normal post - now that status has been cleared a reset will - // run regular boot code.. - reset_vector(); - break; - - case 0x05: - // flush keyboard (issue EOI) and jump via 40h:0067h - eoi_pic2(); - // NO BREAK - case 0x0a: -#define BDA_JUMP (((struct bios_data_area_s *)0)->jump) - // resume execution by jump via 40h:0067h - asm volatile( - "movw %w1, %%ds\n" - "ljmpw *%0\n" - : : "m"(BDA_JUMP), "r"(SEG_BDA) - ); - break; - - case 0x0b: - // resume execution via IRET via 40h:0067h - asm volatile( - "movw %w1, %%ds\n" - "lssw %0, %%sp\n" - "iretw\n" - : : "m"(BDA_JUMP), "r"(SEG_BDA) - ); - break; - - case 0x0c: - // resume execution via RETF via 40h:0067h - asm volatile( - "movw %w1, %%ds\n" - "lssw %0, %%sp\n" - "lretw\n" - : : "m"(BDA_JUMP), "r"(SEG_BDA) - ); - break; - } - - panic("Unimplemented shutdown status: %02x\n", status); -} - -void VISIBLE32FLAT -s3_resume(void) -{ - ASSERT32FLAT(); - if (!CONFIG_S3_RESUME) - panic("S3 resume support not compiled in.\n"); - - dprintf(1, "In 32bit resume\n"); - - smm_init(); - - s3_resume_vga_init(); - - make_bios_readonly(); - - u32 s3_resume_vector = find_resume_vector(); - - // Invoke the resume vector. - struct bregs br; - memset(&br, 0, sizeof(br)); - if (s3_resume_vector) { - dprintf(1, "Jump to resume vector (%x)\n", s3_resume_vector); - br.code = FLATPTR_TO_SEGOFF((void*)s3_resume_vector); - } else { - dprintf(1, "No resume vector set!\n"); - // Jump to the post vector to restart with a normal boot. - br.code = SEGOFF(SEG_BIOS, (u32)reset_vector - BUILD_BIOS_ADDR); - } - call16big(&br); -} diff --git a/roms/seabios/src/romlayout.S b/roms/seabios/src/romlayout.S deleted file mode 100644 index a469596..0000000 --- a/roms/seabios/src/romlayout.S +++ /dev/null @@ -1,582 +0,0 @@ -// Rom layout and bios assembler to C interface. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - - -/**************************************************************** - * Include of 16bit C code - ****************************************************************/ - - .code16gcc -.include "out/ccode.16.s" - -#include "config.h" // CONFIG_* -#include "ioport.h" // PORT_A20 -#include "bregs.h" // CR0_* -#include "cmos.h" // CMOS_RESET_CODE -#include "../out/asm-offsets.h" // BREGS_* -#include "entryfuncs.S" // ENTRY_* - - -/**************************************************************** - * Call trampolines - ****************************************************************/ - -// Place CPU into 32bit mode from 16bit mode. -// Clobbers: ecx, flags, segment registers, cr0, idt/gdt - DECLFUNC transition32 -transition32: - movl %eax, %ecx - - // Disable irqs (and clear direction flag) - cli - cld - - // Disable nmi - movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax - outb %al, $PORT_CMOS_INDEX - inb $PORT_CMOS_DATA, %al - - // enable a20 - inb $PORT_A20, %al - orb $A20_ENABLE_BIT, %al - outb %al, $PORT_A20 - - // Set segment descriptors - lidtw %cs:pmode_IDT_info - lgdtw %cs:rombios32_gdt_48 - - // Enable protected mode - movl %cr0, %eax - orl $CR0_PE, %eax - movl %eax, %cr0 - - // start 32bit protected mode code - ljmpl $SEG32_MODE32_CS, $(BUILD_BIOS_ADDR + 1f) - - .code32 -1: - // init data segments - movl $SEG32_MODE32_DS, %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw %ax, %fs - movw %ax, %gs - - movl %ecx, %eax - retl - -// Place CPU into 16bit mode from 32bit mode. -// Clobbers: ecx, flags, segment registers, cr0, idt/gdt - DECLFUNC transition16 - .global transition16big -transition16: - movl %eax, %ecx - - // restore data segment limits to 0xffff - movl $SEG32_MODE16_DS, %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw %ax, %fs - movw %ax, %gs - -#if CONFIG_DISABLE_A20 - // disable a20 - inb $PORT_A20, %al - andb $~A20_ENABLE_BIT, %al - outb %al, $PORT_A20 -#endif - - // Jump to 16bit mode - ljmpw $SEG32_MODE16_CS, $1f - -transition16big: - movl %eax, %ecx - - movl $SEG32_MODE16BIG_DS, %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw %ax, %fs - movw %ax, %gs - - ljmpw $SEG32_MODE16BIG_CS, $1f - - .code16gcc -1: - // Disable protected mode - movl %cr0, %eax - andl $~CR0_PE, %eax - movl %eax, %cr0 - - // far jump to flush CPU queue after transition to real mode - ljmpw $SEG_BIOS, $2f - -2: - // restore IDT to normal real-mode defaults - lidtw %cs:rmode_IDT_info - - // Clear segment registers - xorw %ax, %ax - movw %ax, %fs - movw %ax, %gs - movw %ax, %es - movw %ax, %ds - movw %ax, %ss // Assume stack is in segment 0 - - movl %ecx, %eax - retl - -// Call a 16bit function from 16bit mode with a specified cpu register state -// %eax = address of struct bregs -// Clobbers: %e[bcd]x, %e[ds]i, flags - DECLFUNC __call16 -__call16: - // Save %eax, %ebp - pushl %ebp - pushl %eax - - // Setup for iretw call - pushw %cs - pushw $1f // return point - pushw BREGS_flags(%eax) // flags - pushl BREGS_code(%eax) // CS:IP - - // Load calling registers. - movl BREGS_edi(%eax), %edi - movl BREGS_esi(%eax), %esi - movl BREGS_ebp(%eax), %ebp - movl BREGS_ebx(%eax), %ebx - movl BREGS_edx(%eax), %edx - movl BREGS_ecx(%eax), %ecx - movw BREGS_es(%eax), %es - movw BREGS_ds(%eax), %ds - movl %ss:BREGS_eax(%eax), %eax - - // Invoke call - iretw // XXX - just do a lcalll -1: - // Store flags, eax, ecx - pushfw - pushl %eax - movl 0x06(%esp), %eax - movl %ecx, %ss:BREGS_ecx(%eax) - movw %ds, %ss:BREGS_ds(%eax) - movw %ss, %cx - movw %cx, %ds // Restore %ds == %ss - popl %ecx - movl %ecx, BREGS_eax(%eax) - popw %cx - movw %cx, BREGS_flags(%eax) - - // Store remaining registers - movw %es, BREGS_es(%eax) - movl %edi, BREGS_edi(%eax) - movl %esi, BREGS_esi(%eax) - movl %ebp, BREGS_ebp(%eax) - movl %ebx, BREGS_ebx(%eax) - movl %edx, BREGS_edx(%eax) - - // Remove %eax, restore %ebp - popl %eax - popl %ebp - - retl - -// Call a 16bit function from 32bit mode. -// %eax = address of struct bregs -// Clobbers: %e[bcd]x, %e[ds]i, flags, segment registers, idt/gdt - DECLFUNC __call16_from32 - .global __call16big_from32 - .code32 -__call16_from32: - pushl $1f - jmp transition16 -__call16big_from32: - pushl $1f - jmp transition16big - - // Make call. - .code16gcc -1: calll __call16 - // Return via transition32 - jmp transition32 - -// IRQ trampolines - .macro IRQ_TRAMPOLINE num - DECLFUNC irq_trampoline_0x\num - irq_trampoline_0x\num : - int $0x\num - lretw - .endm - - IRQ_TRAMPOLINE 10 - IRQ_TRAMPOLINE 13 - IRQ_TRAMPOLINE 15 - IRQ_TRAMPOLINE 16 - IRQ_TRAMPOLINE 18 - IRQ_TRAMPOLINE 19 - - -/**************************************************************** - * POST entry point - ****************************************************************/ - - DECLFUNC entry_post -entry_post: - // Enable cache - movl %cr0, %eax - andl $~(CR0_CD|CR0_NW), %eax - movl %eax, %cr0 - - // Disable interrupts - cli - cld - - // Check for restart indicator. - movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax - outb %al, $PORT_CMOS_INDEX - inb $PORT_CMOS_DATA, %al - cmpb $0x0, %al - jnz 1f - - // Normal entry point - ENTRY_INTO32 _start - - // Entry point when a post call looks like a resume. -1: - // Save old shutdown status. - movl %eax, %ebx - - // Clear shutdown status register. - movl $CMOS_RESET_CODE|NMI_DISABLE_BIT, %eax - outb %al, $PORT_CMOS_INDEX - xorl %eax, %eax - outb %al, $PORT_CMOS_DATA - - // Use a stack in EBDA - movw $SEG_BDA, %ax - movw %ax, %ds - movw BDA_ebda_seg, %ax - - cmpw $EBDA_SEGMENT_START, %ax - jle 2f - // EBDA segment doesn't look valid - use startup value. - movw $EBDA_SEGMENT_START, %ax - -2: movw %ax, %ds - movw %ax, %ss - movl $EBDA_OFFSET_TOP_STACK, %esp - - // Call handler. - movl %ebx, %eax - jmp handle_resume - - -/**************************************************************** - * Misc. entry points. - ****************************************************************/ - -// PMM entry point - DECLFUNC entry_pmm -entry_pmm: - pushl %esp // Backup %esp, then clear high bits - movzwl %sp, %esp - pushfl // Save registers clobbered by C code - cli - cld - pushl %eax - pushl %ecx - pushl %edx - pushw %es - pushw %ds - movw %ss, %cx // Move %ss to %ds - movw %cx, %ds - leal 28(%esp), %eax // %eax points to start of args - calll handle_pmm - movw %ax, 12(%esp) // Modify %ax:%dx to return %eax - shrl $16, %eax - movw %ax, 4(%esp) - popw %ds // Restore saved registers - popw %es - popl %edx - popl %ecx - popl %eax - popfl - popl %esp - lretw - -// PnP entry points - DECLFUNC entry_pnp_real - .global entry_pnp_prot -entry_pnp_prot: - pushl %esp - jmp 1f -entry_pnp_real: - pushl %esp // Backup %esp, then clear high bits - movzwl %sp, %esp -1: - pushfl // Save registers clobbered by C code - cli - cld - pushl %eax - pushl %ecx - pushl %edx - pushw %es - pushw %ds - movw %ss, %cx // Move %ss to %ds - movw %cx, %ds - leal 28(%esp), %eax // %eax points to start of u16 args - calll handle_pnp - movw %ax, 12(%esp) // Modify %eax to return %ax - popw %ds - popw %es - popl %edx - popl %ecx - popl %eax - popfl - popl %esp - lretw - -// APM entry points - DECLFUNC apm16protected_entry -apm16protected_entry: - pushfw // save flags - pushl %eax // dummy - ENTRY_ARG handle_apm16 - addw $4, %sp // pop dummy - popfw // restore flags - lretw - - .code32 - DECLFUNC apm32protected_entry -apm32protected_entry: - pushfl - pushl %gs - pushl %cs // Move second descriptor after %cs to %gs - addl $16, (%esp) - popl %gs - ENTRY_ARG_ESP handle_apm32 - popl %gs - popfl - lretl - -// PCI-BIOS 32bit entry point - DECLFUNC pcibios32_entry -pcibios32_entry: - pushfl - pushl %gs // Backup %gs and set %gs=%ds - pushl %ds - popl %gs - ENTRY_ARG_ESP handle_pcibios32 - popl %gs - popfl - lretl - -// BIOS32 support - EXPORTFUNC bios32_entry -bios32_entry: - pushfl -#if CONFIG_PCIBIOS - // Check for PCI-BIOS request - cmpl $0x49435024, %eax // $PCI - jne 1f - movl $BUILD_BIOS_ADDR, %ebx - movl $BUILD_BIOS_SIZE, %ecx - movl $pcibios32_entry, %edx - xorb %al, %al - jmp 2f -#endif - // Unknown request -1: movb $0x80, %al - // Return to caller -2: popfl - lretl - -// 32bit elf entry point - EXPORTFUNC post32 -post32: - cli - cld - lidtl (BUILD_BIOS_ADDR + pmode_IDT_info) - lgdtl (BUILD_BIOS_ADDR + rombios32_gdt_48) - movl $SEG32_MODE32_DS, %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - movl $BUILD_STACK_ADDR, %esp - ljmpl $SEG32_MODE32_CS, $_start - - .code16gcc - - -/**************************************************************** - * Interrupt entry points - ****************************************************************/ - - // Define an entry point for an interrupt (no args passed). - .macro IRQ_ENTRY num - .global entry_\num - entry_\num : - pushl $ handle_\num - jmp irqentry - .endm - - // Define an entry point for an interrupt (can read/modify args). - .macro IRQ_ENTRY_ARG num - .global entry_\num - entry_\num : - pushl $ handle_\num - jmp irqentryarg - .endm - - // Macros that put each handler into its own section - .macro DECL_IRQ_ENTRY num - DECLFUNC entry_\num - IRQ_ENTRY \num - .endm - .macro DECL_IRQ_ENTRY_ARG num - DECLFUNC entry_\num - IRQ_ENTRY_ARG \num - .endm - - // Main entry point for interrupts without args - DECLFUNC irqentry -irqentry: - ENTRY_ST - iretw - - // Main entry point for interrupts with args - DECLFUNC irqentryarg -irqentryarg: - ENTRY_ARG_ST - iretw - - DECL_IRQ_ENTRY_ARG 13 - DECL_IRQ_ENTRY 76 - DECL_IRQ_ENTRY 70 - DECL_IRQ_ENTRY 74 - DECL_IRQ_ENTRY 75 - DECL_IRQ_ENTRY hwpic1 - DECL_IRQ_ENTRY hwpic2 - - // int 18/19 are special - they reset stack and call into 32bit mode. - DECLFUNC entry_19 -entry_19: - ENTRY_INTO32 handle_19 - - DECLFUNC entry_18 -entry_18: - ENTRY_INTO32 handle_18 - - -/**************************************************************** - * Fixed position entry points - ****************************************************************/ - - // Specify a location in the fixed part of bios area. - .macro ORG addr - .section .fixedaddr.\addr - .endm - - ORG 0xe05b -entry_post_official: - jmp entry_post - - ORG 0xe2c3 - IRQ_ENTRY 02 - - ORG 0xe3fe - .global entry_13_official -entry_13_official: - jmp entry_13 - - // 0xe401 - OldFDPT in disk.c - - ORG 0xe6f2 - .global entry_19_official -entry_19_official: - jmp entry_19 - - // 0xe6f5 - BIOS_CONFIG_TABLE in misc.c - - // 0xe729 - BaudTable in serial.c - - ORG 0xe739 - IRQ_ENTRY_ARG 14 - - ORG 0xe82e - IRQ_ENTRY_ARG 16 - - ORG 0xe987 - IRQ_ENTRY 09 - - ORG 0xec59 - IRQ_ENTRY_ARG 40 - - ORG 0xef57 - IRQ_ENTRY 0e - - // 0xefc7 - diskette_param_table in floppy.c - - ORG 0xefd2 - IRQ_ENTRY_ARG 17 - - ORG 0xf045 -entry_10_0x0f: - // XXX - INT 10 Functions 0-Fh Entry Point - iretw - - ORG 0xf065 - IRQ_ENTRY_ARG 10 - - // 0xf0a4 - VideoParams in misc.c - - ORG 0xf841 - IRQ_ENTRY_ARG 12 - - ORG 0xf84d - IRQ_ENTRY_ARG 11 - - ORG 0xf859 - IRQ_ENTRY_ARG 15 - - // 0xfa6e - vgafont8 in font.c - - ORG 0xfe6e - IRQ_ENTRY_ARG 1a - - ORG 0xfea5 - IRQ_ENTRY 08 - - // 0xfef3 - InitVectors in misc.c - - // 0xff00 - BiosCopyright in misc.c - - ORG 0xff53 - .global entry_iret_official -entry_iret_official: - iretw - - ORG 0xff54 - IRQ_ENTRY_ARG 05 - - ORG 0xfff0 // Power-up Entry Point - .global reset_vector -reset_vector: - ljmpw $SEG_BIOS, $entry_post_official - - // 0xfff5 - BiosDate in misc.c - - // 0xfffe - BiosModelId in misc.c - - // 0xffff - BiosChecksum in misc.c - - .end diff --git a/roms/seabios/src/serial.c b/roms/seabios/src/serial.c deleted file mode 100644 index 21b4bd0..0000000 --- a/roms/seabios/src/serial.c +++ /dev/null @@ -1,315 +0,0 @@ -// 16bit code to handle serial and printer services. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "biosvar.h" // SET_BDA -#include "util.h" // debug_enter -#include "bregs.h" // struct bregs - - -/**************************************************************** - * COM ports - ****************************************************************/ - -static u16 -detect_serial(u16 port, u8 timeout, u8 count) -{ - outb(0x02, port+SEROFF_IER); - u8 ier = inb(port+SEROFF_IER); - if (ier != 0x02) - return 0; - u8 iir = inb(port+SEROFF_IIR); - if ((iir & 0x3f) != 0x02) - return 0; - - outb(0x00, port+SEROFF_IER); - SET_BDA(port_com[count], port); - SET_BDA(com_timeout[count], timeout); - return 1; -} - -void -serial_setup(void) -{ - if (! CONFIG_SERIAL) - return; - dprintf(3, "init serial\n"); - - u16 count = 0; - count += detect_serial(PORT_SERIAL1, 0x0a, count); - count += detect_serial(PORT_SERIAL2, 0x0a, count); - count += detect_serial(PORT_SERIAL3, 0x0a, count); - count += detect_serial(PORT_SERIAL4, 0x0a, count); - dprintf(1, "Found %d serial ports\n", count); - - // Equipment word bits 9..11 determing # serial ports - u16 eqb = GET_BDA(equipment_list_flags); - SET_BDA(equipment_list_flags, (eqb & 0xf1ff) | (count << 9)); -} - -static u16 -getComAddr(struct bregs *regs) -{ - if (regs->dx >= 4) { - set_invalid(regs); - return 0; - } - u16 addr = GET_BDA(port_com[regs->dx]); - if (! addr) - set_invalid(regs); - return addr; -} - -// SERIAL - INITIALIZE PORT -static void -handle_1400(struct bregs *regs) -{ - u16 addr = getComAddr(regs); - if (!addr) - return; - outb(inb(addr+SEROFF_LCR) | 0x80, addr+SEROFF_LCR); - if ((regs->al & 0xE0) == 0) { - outb(0x17, addr+SEROFF_DLL); - outb(0x04, addr+SEROFF_DLH); - } else { - u16 val16 = 0x600 >> ((regs->al & 0xE0) >> 5); - outb(val16 & 0xFF, addr+SEROFF_DLL); - outb(val16 >> 8, addr+SEROFF_DLH); - } - outb(regs->al & 0x1F, addr+SEROFF_LCR); - regs->ah = inb(addr+SEROFF_LSR); - regs->al = inb(addr+SEROFF_MSR); - set_success(regs); -} - -// SERIAL - WRITE CHARACTER TO PORT -static void -handle_1401(struct bregs *regs) -{ - u16 addr = getComAddr(regs); - if (!addr) - return; - u32 end = calc_future_timer_ticks(GET_BDA(com_timeout[regs->dx])); - for (;;) { - u8 lsr = inb(addr+SEROFF_LSR); - if ((lsr & 0x60) == 0x60) { - // Success - can write data - outb(regs->al, addr+SEROFF_DATA); - // XXX - reread lsr? - regs->ah = lsr; - break; - } - if (check_timer(end)) { - // Timed out - can't write data. - regs->ah = lsr | 0x80; - break; - } - yield(); - } - set_success(regs); -} - -// SERIAL - READ CHARACTER FROM PORT -static void -handle_1402(struct bregs *regs) -{ - u16 addr = getComAddr(regs); - if (!addr) - return; - u32 end = calc_future_timer_ticks(GET_BDA(com_timeout[regs->dx])); - for (;;) { - u8 lsr = inb(addr+SEROFF_LSR); - if (lsr & 0x01) { - // Success - can read data - regs->al = inb(addr+SEROFF_DATA); - regs->ah = lsr; - break; - } - if (check_timer(end)) { - // Timed out - can't read data. - regs->ah = lsr | 0x80; - break; - } - yield(); - } - set_success(regs); -} - -// SERIAL - GET PORT STATUS -static void -handle_1403(struct bregs *regs) -{ - u16 addr = getComAddr(regs); - if (!addr) - return; - regs->ah = inb(addr+SEROFF_LSR); - regs->al = inb(addr+SEROFF_MSR); - set_success(regs); -} - -static void -handle_14XX(struct bregs *regs) -{ - set_unimplemented(regs); -} - -// INT 14h Serial Communications Service Entry Point -void VISIBLE16 -handle_14(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_14); - if (! CONFIG_SERIAL) { - handle_14XX(regs); - return; - } - - switch (regs->ah) { - case 0x00: handle_1400(regs); break; - case 0x01: handle_1401(regs); break; - case 0x02: handle_1402(regs); break; - case 0x03: handle_1403(regs); break; - default: handle_14XX(regs); break; - } -} - -// XXX - Baud Rate Generator Table -u8 BaudTable[16] VAR16FIXED(0xe729); - - -/**************************************************************** - * LPT ports - ****************************************************************/ - -static u16 -detect_parport(u16 port, u8 timeout, u8 count) -{ - // clear input mode - outb(inb(port+2) & 0xdf, port+2); - - outb(0xaa, port); - if (inb(port) != 0xaa) - // Not present - return 0; - SET_BDA(port_lpt[count], port); - SET_BDA(lpt_timeout[count], timeout); - return 1; -} - -void -lpt_setup(void) -{ - if (! CONFIG_LPT) - return; - dprintf(3, "init lpt\n"); - - u16 count = 0; - count += detect_parport(PORT_LPT1, 0x14, count); - count += detect_parport(PORT_LPT2, 0x14, count); - dprintf(1, "Found %d lpt ports\n", count); - - // Equipment word bits 14..15 determing # parallel ports - u16 eqb = GET_BDA(equipment_list_flags); - SET_BDA(equipment_list_flags, (eqb & 0x3fff) | (count << 14)); -} - -static u16 -getLptAddr(struct bregs *regs) -{ - if (regs->dx >= 3) { - set_invalid(regs); - return 0; - } - u16 addr = GET_BDA(port_lpt[regs->dx]); - if (! addr) - set_invalid(regs); - return addr; -} - -// INT 17 - PRINTER - WRITE CHARACTER -static void -handle_1700(struct bregs *regs) -{ - u16 addr = getLptAddr(regs); - if (!addr) - return; - - u32 end = calc_future_timer_ticks(GET_BDA(lpt_timeout[regs->dx])); - - outb(regs->al, addr); - u8 val8 = inb(addr+2); - outb(val8 | 0x01, addr+2); // send strobe - udelay(5); - outb(val8 & ~0x01, addr+2); - - for (;;) { - u8 v = inb(addr+1); - if (!(v & 0x40)) { - // Success - regs->ah = v ^ 0x48; - break; - } - if (check_timer(end)) { - // Timeout - regs->ah = (v ^ 0x48) | 0x01; - break; - } - yield(); - } - - set_success(regs); -} - -// INT 17 - PRINTER - INITIALIZE PORT -static void -handle_1701(struct bregs *regs) -{ - u16 addr = getLptAddr(regs); - if (!addr) - return; - - u8 val8 = inb(addr+2); - outb(val8 & ~0x04, addr+2); // send init - udelay(5); - outb(val8 | 0x04, addr+2); - - regs->ah = inb(addr+1) ^ 0x48; - set_success(regs); -} - -// INT 17 - PRINTER - GET STATUS -static void -handle_1702(struct bregs *regs) -{ - u16 addr = getLptAddr(regs); - if (!addr) - return; - regs->ah = inb(addr+1) ^ 0x48; - set_success(regs); -} - -static void -handle_17XX(struct bregs *regs) -{ - set_unimplemented(regs); -} - -// INT17h : Printer Service Entry Point -void VISIBLE16 -handle_17(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_17); - if (! CONFIG_LPT) { - handle_17XX(regs); - return; - } - - switch (regs->ah) { - case 0x00: handle_1700(regs); break; - case 0x01: handle_1701(regs); break; - case 0x02: handle_1702(regs); break; - default: handle_17XX(regs); break; - } -} diff --git a/roms/seabios/src/shadow.c b/roms/seabios/src/shadow.c deleted file mode 100644 index e91e54e..0000000 --- a/roms/seabios/src/shadow.c +++ /dev/null @@ -1,145 +0,0 @@ -// Support for enabling/disabling BIOS ram shadowing. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // memcpy -#include "pci.h" // pci_config_writeb -#include "config.h" // CONFIG_* -#include "pci_ids.h" // PCI_VENDOR_ID_INTEL -#include "dev-i440fx.h" - -// Test if 'addr' is in the range from 'start'..'start+size' -#define IN_RANGE(addr, start, size) ({ \ - u32 __addr = (addr); \ - u32 __start = (start); \ - u32 __size = (size); \ - (__addr - __start < __size); \ - }) - -// On the emulators, the bios at 0xf0000 is also at 0xffff0000 -#define BIOS_SRC_ADDR 0xffff0000 - -// Enable shadowing and copy bios. -static void -__make_bios_writable_intel(u16 bdf, u32 pam0) -{ - // Make ram from 0xc0000-0xf0000 writable - int clear = 0; - int i; - for (i=0; i<6; i++) { - u32 pam = pam0 + 1 + i; - int reg = pci_config_readb(bdf, pam); - if ((reg & 0x11) != 0x11) { - // Need to copy optionroms to work around qemu implementation - void *mem = (void*)(BUILD_ROM_START + i * 32*1024); - memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024); - pci_config_writeb(bdf, pam, 0x33); - memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024); - clear = 1; - } else { - pci_config_writeb(bdf, pam, 0x33); - } - } - if (clear) - memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024); - - // Make ram from 0xf0000-0x100000 writable - int reg = pci_config_readb(bdf, pam0); - pci_config_writeb(bdf, pam0, 0x30); - if (reg & 0x10) - // Ram already present. - return; - - // Copy bios. - memcpy((void*)BUILD_BIOS_ADDR, (void*)BIOS_SRC_ADDR, BUILD_BIOS_SIZE); -} - -void -make_bios_writable_intel(u16 bdf, u32 pam0) -{ - int reg = pci_config_readb(bdf, pam0); - if (!(reg & 0x10)) { - // QEMU doesn't fully implement the piix shadow capabilities - - // if ram isn't backing the bios segment when shadowing is - // disabled, the code itself wont be in memory. So, run the - // code from the high-memory flash location. - u32 pos = (u32)__make_bios_writable_intel - BUILD_BIOS_ADDR + - BIOS_SRC_ADDR; - void (*func)(u16 bdf, u32 pam0) = (void*)pos; - func(bdf, pam0); - return; - } - // Ram already present - just enable writes - __make_bios_writable_intel(bdf, pam0); -} - -void -make_bios_readonly_intel(u16 bdf, u32 pam0) -{ - // Flush any pending writes before locking memory. - wbinvd(); - - // Write protect roms from 0xc0000-0xf0000 - int i; - for (i=0; i<6; i++) { - u32 mem = BUILD_ROM_START + i * 32*1024; - u32 pam = pam0 + 1 + i; - if (RomEnd <= mem + 16*1024) { - if (RomEnd > mem) - pci_config_writeb(bdf, pam, 0x31); - break; - } - pci_config_writeb(bdf, pam, 0x11); - } - - // Write protect 0xf0000-0x100000 - pci_config_writeb(bdf, pam0, 0x10); -} - -static const struct pci_device_id dram_controller_make_writable_tbl[] = { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, - i440fx_bios_make_writable), - PCI_DEVICE_END -}; - -// Make the 0xc0000-0x100000 area read/writable. -void -make_bios_writable(void) -{ - if (CONFIG_COREBOOT) - return; - - dprintf(3, "enabling shadow ram\n"); - - // at this point, staticlly alloacted variable can't written. - // so stack should be used. - - // Locate chip controlling ram shadowing. - int bdf = pci_find_init_device(dram_controller_make_writable_tbl, NULL); - if (bdf < 0) { - dprintf(1, "Unable to unlock ram - bridge not found\n"); - } -} - -static const struct pci_device_id dram_controller_make_readonly_tbl[] = { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, - i440fx_bios_make_readonly), - PCI_DEVICE_END -}; - -// Make the BIOS code segment area (0xf0000) read-only. -void -make_bios_readonly(void) -{ - if (CONFIG_COREBOOT) - return; - - dprintf(3, "locking shadow ram\n"); - int bdf = pci_find_init_device(dram_controller_make_readonly_tbl, NULL); - if (bdf < 0) { - dprintf(1, "Unable to lock ram - bridge not found\n"); - } -} diff --git a/roms/seabios/src/smbios.c b/roms/seabios/src/smbios.c deleted file mode 100644 index 8df0f2d..0000000 --- a/roms/seabios/src/smbios.c +++ /dev/null @@ -1,514 +0,0 @@ -// smbios table generation (on emulators) -// -// Copyright (C) 2008,2009 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "biosvar.h" // GET_EBDA -#include "paravirt.h" // qemu_cfg_smbios_load_field -#include "smbios.h" // struct smbios_entry_point - -static void -smbios_entry_point_init(u16 max_structure_size, - u16 structure_table_length, - void *structure_table_address, - u16 number_of_structures) -{ - struct smbios_entry_point *ep = malloc_fseg(sizeof(*ep)); - void *finaltable = malloc_high(structure_table_length); - if (!ep || !finaltable) { - warn_noalloc(); - free(ep); - free(finaltable); - return; - } - memcpy(finaltable, structure_table_address, structure_table_length); - - memcpy(ep->anchor_string, "_SM_", 4); - ep->length = 0x1f; - ep->smbios_major_version = 2; - ep->smbios_minor_version = 4; - ep->max_structure_size = max_structure_size; - ep->entry_point_revision = 0; - memset(ep->formatted_area, 0, 5); - memcpy(ep->intermediate_anchor_string, "_DMI_", 5); - - ep->structure_table_length = structure_table_length; - ep->structure_table_address = (u32)finaltable; - ep->number_of_structures = number_of_structures; - ep->smbios_bcd_revision = 0x24; - - ep->checksum -= checksum(ep, 0x10); - - ep->intermediate_checksum -= checksum((void*)ep + 0x10, ep->length - 0x10); - - dprintf(1, "SMBIOS ptr=%p table=%p\n", ep, finaltable); -} - -#define load_str_field_with_default(type, field, def) \ - do { \ - size = qemu_cfg_smbios_load_field(type, \ - offsetof(struct smbios_type_##type, \ - field), end); \ - if (size > 0) { \ - end += size; \ - } else { \ - memcpy(end, def, sizeof(def)); \ - end += sizeof(def); \ - } \ - p->field = ++str_index; \ - } while (0) - -#define load_str_field_or_skip(type, field) \ - do { \ - size = qemu_cfg_smbios_load_field(type, \ - offsetof(struct smbios_type_##type, \ - field), end); \ - if (size > 0) { \ - end += size; \ - p->field = ++str_index; \ - } else { \ - p->field = 0; \ - } \ - } while (0) - -#define set_field_with_default(type, field, def) \ - do { \ - if (!qemu_cfg_smbios_load_field(type, \ - offsetof(struct smbios_type_##type, \ - field), &p->field)) { \ - p->field = def; \ - } \ - } while (0) - -/* Type 0 -- BIOS Information */ -#define RELEASE_DATE_STR "01/01/2007" -static void * -smbios_init_type_0(void *start) -{ - struct smbios_type_0 *p = (struct smbios_type_0 *)start; - char *end = (char *)start + sizeof(struct smbios_type_0); - size_t size; - int str_index = 0; - - p->header.type = 0; - p->header.length = sizeof(struct smbios_type_0); - p->header.handle = 0; - - load_str_field_with_default(0, vendor_str, CONFIG_APPNAME); - load_str_field_with_default(0, bios_version_str, CONFIG_APPNAME); - - p->bios_starting_address_segment = 0xe800; - - load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR); - - p->bios_rom_size = 0; /* FIXME */ - - if (!qemu_cfg_smbios_load_field(0, offsetof(struct smbios_type_0, - bios_characteristics), - &p->bios_characteristics)) { - memset(p->bios_characteristics, 0, 8); - /* BIOS characteristics not supported */ - p->bios_characteristics[0] = 0x08; - } - - if (!qemu_cfg_smbios_load_field(0, offsetof(struct smbios_type_0, - bios_characteristics_extension_bytes), - &p->bios_characteristics_extension_bytes)) { - p->bios_characteristics_extension_bytes[0] = 0; - /* Enable targeted content distribution. Needed for SVVP */ - p->bios_characteristics_extension_bytes[1] = 4; - } - - set_field_with_default(0, system_bios_major_release, 1); - set_field_with_default(0, system_bios_minor_release, 0); - set_field_with_default(0, embedded_controller_major_release, 0xff); - set_field_with_default(0, embedded_controller_minor_release, 0xff); - - *end = 0; - end++; - - return end; -} - -/* Type 1 -- System Information */ -static void * -smbios_init_type_1(void *start) -{ - struct smbios_type_1 *p = (struct smbios_type_1 *)start; - char *end = (char *)start + sizeof(struct smbios_type_1); - size_t size; - int str_index = 0; - - p->header.type = 1; - p->header.length = sizeof(struct smbios_type_1); - p->header.handle = 0x100; - - load_str_field_with_default(1, manufacturer_str, CONFIG_APPNAME); - load_str_field_with_default(1, product_name_str, CONFIG_APPNAME); - load_str_field_or_skip(1, version_str); - load_str_field_or_skip(1, serial_number_str); - - if (!qemu_cfg_smbios_load_field(1, offsetof(struct smbios_type_1, - uuid), &p->uuid)) { - memset(p->uuid, 0, 16); - } - - set_field_with_default(1, wake_up_type, 0x06); /* power switch */ - - load_str_field_or_skip(1, sku_number_str); - load_str_field_or_skip(1, family_str); - - *end = 0; - end++; - if (!str_index) { - *end = 0; - end++; - } - - return end; -} - -/* Type 3 -- System Enclosure */ -static void * -smbios_init_type_3(void *start) -{ - struct smbios_type_3 *p = (struct smbios_type_3 *)start; - char *end = (char *)start + sizeof(struct smbios_type_3); - size_t size; - int str_index = 0; - - p->header.type = 3; - p->header.length = sizeof(struct smbios_type_3); - p->header.handle = 0x300; - - load_str_field_with_default(3, manufacturer_str, CONFIG_APPNAME); - set_field_with_default(3, type, 0x01); /* other */ - - load_str_field_or_skip(3, version_str); - load_str_field_or_skip(3, serial_number_str); - load_str_field_or_skip(3, asset_tag_number_str); - - set_field_with_default(3, boot_up_state, 0x03); /* safe */ - set_field_with_default(3, power_supply_state, 0x03); /* safe */ - set_field_with_default(3, thermal_state, 0x03); /* safe */ - set_field_with_default(3, security_status, 0x02); /* unknown */ - - set_field_with_default(3, oem_defined, 0); - set_field_with_default(3, height, 0); - set_field_with_default(3, number_of_power_cords, 0); - set_field_with_default(3, contained_element_count, 0); - - *end = 0; - end++; - if (!str_index) { - *end = 0; - end++; - } - - return end; -} - -/* Type 4 -- Processor Information */ -static void * -smbios_init_type_4(void *start, unsigned int cpu_number) -{ - struct smbios_type_4 *p = (struct smbios_type_4 *)start; - char *end = (char *)start + sizeof(struct smbios_type_4); - size_t size; - int str_index = 0; - char name[1024]; - - p->header.type = 4; - p->header.length = sizeof(struct smbios_type_4); - p->header.handle = 0x400 + cpu_number; - - size = qemu_cfg_smbios_load_field(4, offsetof(struct smbios_type_4, - socket_designation_str), - name); - if (size) - snprintf(name + size - 1, sizeof(name) - size, "%2x", cpu_number); - else - snprintf(name, sizeof(name), "CPU%2x", cpu_number); - - memcpy(end, name, strlen(name) + 1); - end += strlen(name) + 1; - p->socket_designation_str = ++str_index; - - set_field_with_default(4, processor_type, 0x03); /* CPU */ - set_field_with_default(4, processor_family, 0x01); /* other */ - - load_str_field_with_default(4, processor_manufacturer_str, CONFIG_APPNAME); - - if (!qemu_cfg_smbios_load_field(4, offsetof(struct smbios_type_4, - processor_id), p->processor_id)) { - u32 cpuid_signature, ebx, ecx, cpuid_features; - cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features); - p->processor_id[0] = cpuid_signature; - p->processor_id[1] = cpuid_features; - } - - load_str_field_or_skip(4, processor_version_str); - set_field_with_default(4, voltage, 0); - set_field_with_default(4, external_clock, 0); - - set_field_with_default(4, max_speed, 2000); - set_field_with_default(4, current_speed, 2000); - - set_field_with_default(4, status, 0x41); /* socket populated, CPU enabled */ - set_field_with_default(4, processor_upgrade, 0x01); /* other */ - - /* cache information structure not provided */ - p->l1_cache_handle = 0xffff; - p->l2_cache_handle = 0xffff; - p->l3_cache_handle = 0xffff; - - *end = 0; - end++; - if (!str_index) { - *end = 0; - end++; - } - - return end; -} - -/* Type 16 -- Physical Memory Array */ -static void * -smbios_init_type_16(void *start, u32 memory_size_mb, int nr_mem_devs) -{ - struct smbios_type_16 *p = (struct smbios_type_16*)start; - - p->header.type = 16; - p->header.length = sizeof(struct smbios_type_16); - p->header.handle = 0x1000; - - set_field_with_default(16, location, 0x01); /* other */ - set_field_with_default(16, use, 0x03); /* system memory */ - /* Multi-bit ECC to make Microsoft happy */ - set_field_with_default(16, error_correction, 0x06); - /* 0x80000000 = unknown, accept sizes < 2TB - TODO multiple arrays */ - p->maximum_capacity = memory_size_mb < 2 << 20 ? - memory_size_mb << 10 : 0x80000000; - p->memory_error_information_handle = 0xfffe; /* none provided */ - p->number_of_memory_devices = nr_mem_devs; - - start += sizeof(struct smbios_type_16); - *((u16 *)start) = 0; - - return start + 2; -} - -/* Type 17 -- Memory Device */ -static void * -smbios_init_type_17(void *start, u32 size_mb, int instance) -{ - struct smbios_type_17 *p = (struct smbios_type_17 *)start; - char *end = (char *)start + sizeof(struct smbios_type_17); - size_t size; - int str_index = 0; - char name[1024]; - - p->header.type = 17; - p->header.length = sizeof(struct smbios_type_17); - p->header.handle = 0x1100 + instance; - - p->physical_memory_array_handle = 0x1000; - set_field_with_default(17, total_width, 64); - set_field_with_default(17, data_width, 64); -/* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */ - p->size = size_mb; - set_field_with_default(17, form_factor, 0x09); /* DIMM */ - p->device_set = 0; - - size = qemu_cfg_smbios_load_field(17, offsetof(struct smbios_type_17, - device_locator_str), - name); - if (size) - snprintf(name + size - 1, sizeof(name) - size, "%d", instance); - else - snprintf(name, sizeof(name), "DIMM %d", instance); - - memcpy(end, name, strlen(name) + 1); - end += strlen(name) + 1; - p->device_locator_str = ++str_index; - - load_str_field_or_skip(17, bank_locator_str); - set_field_with_default(17, memory_type, 0x07); /* RAM */ - set_field_with_default(17, type_detail, 0); - - *end = 0; - end++; - if (!str_index) { - *end = 0; - end++; - } - - return end; -} - -/* Type 19 -- Memory Array Mapped Address */ -static void * -smbios_init_type_19(void *start, u32 start_mb, u32 size_mb, int instance) -{ - struct smbios_type_19 *p = (struct smbios_type_19 *)start; - - p->header.type = 19; - p->header.length = sizeof(struct smbios_type_19); - p->header.handle = 0x1300 + instance; - - p->starting_address = start_mb << 10; - p->ending_address = p->starting_address + (size_mb << 10) - 1; - p->memory_array_handle = 0x1000; - p->partition_width = 1; - - start += sizeof(struct smbios_type_19); - *((u16 *)start) = 0; - - return start + 2; -} - -/* Type 20 -- Memory Device Mapped Address */ -static void * -smbios_init_type_20(void *start, u32 start_mb, u32 size_mb, int instance, - int dev_handle, int array_handle) -{ - struct smbios_type_20 *p = (struct smbios_type_20 *)start; - - p->header.type = 20; - p->header.length = sizeof(struct smbios_type_20); - p->header.handle = 0x1400 + instance; - - p->starting_address = start_mb << 10; - p->ending_address = p->starting_address + (size_mb << 10) - 1; - p->memory_device_handle = 0x1100 + dev_handle; - p->memory_array_mapped_address_handle = 0x1300 + array_handle; - p->partition_row_position = 1; - p->interleave_position = 0; - p->interleaved_data_depth = 0; - - start += sizeof(struct smbios_type_20); - - *((u16 *)start) = 0; - return start+2; -} - -/* Type 32 -- System Boot Information */ -static void * -smbios_init_type_32(void *start) -{ - struct smbios_type_32 *p = (struct smbios_type_32 *)start; - - p->header.type = 32; - p->header.length = sizeof(struct smbios_type_32); - p->header.handle = 0x2000; - memset(p->reserved, 0, 6); - set_field_with_default(32, boot_status, 0); /* no errors detected */ - - start += sizeof(struct smbios_type_32); - *((u16 *)start) = 0; - - return start+2; -} - -/* Type 127 -- End of Table */ -static void * -smbios_init_type_127(void *start) -{ - struct smbios_type_127 *p = (struct smbios_type_127 *)start; - - p->header.type = 127; - p->header.length = sizeof(struct smbios_type_127); - p->header.handle = 0x7f00; - - start += sizeof(struct smbios_type_127); - *((u16 *)start) = 0; - - return start + 2; -} - -#define TEMPSMBIOSSIZE (32 * 1024) - -void -smbios_init(void) -{ - if (! CONFIG_SMBIOS) - return; - - dprintf(3, "init SMBIOS tables\n"); - - char *start = malloc_tmphigh(TEMPSMBIOSSIZE); - if (! start) { - warn_noalloc(); - return; - } - - u32 nr_structs = 0, max_struct_size = 0; - char *q, *p = start; - char *end = start + TEMPSMBIOSSIZE - sizeof(struct smbios_type_127); - -#define add_struct(type, args...) \ - do { \ - if (!qemu_cfg_smbios_load_external(type, &p, &nr_structs, \ - &max_struct_size, end)) { \ - q = smbios_init_type_##type(args); \ - nr_structs++; \ - if ((q - p) > max_struct_size) \ - max_struct_size = q - p; \ - p = q; \ - } \ - } while (0) - - add_struct(0, p); - add_struct(1, p); - add_struct(3, p); - - int cpu_num; - for (cpu_num = 1; cpu_num <= MaxCountCPUs; cpu_num++) - add_struct(4, p, cpu_num); - - int ram_mb = (RamSize + RamSizeOver4G) >> 20; - int nr_mem_devs = (ram_mb + 0x3fff) >> 14; - add_struct(16, p, ram_mb, nr_mem_devs); - - int i, j; - for (i = 0; i < nr_mem_devs; i++) { - u32 dev_mb = ((i == (nr_mem_devs - 1)) - ? (((ram_mb - 1) & 0x3fff) + 1) - : 16384); - add_struct(17, p, dev_mb, i); - } - - add_struct(19, p, 0, RamSize >> 20, 0); - if (RamSizeOver4G) - add_struct(19, p, 4096, RamSizeOver4G >> 20, 1); - - add_struct(20, p, 0, RamSize >> 20, 0, 0, 0); - if (RamSizeOver4G) { - u32 start_mb = 4096; - for (j = 1, i = 0; i < nr_mem_devs; i++, j++) { - u32 dev_mb = ((i == (nr_mem_devs - 1)) - ? (((ram_mb - 1) & 0x3fff) + 1) - : 16384); - if (i == 0) - dev_mb -= RamSize >> 20; - - add_struct(20, p, start_mb, dev_mb, j, i, 1); - start_mb += dev_mb; - } - } - - add_struct(32, p); - /* Add any remaining provided entries before the end marker */ - for (i = 0; i < 256; i++) - qemu_cfg_smbios_load_external(i, &p, &nr_structs, &max_struct_size, - end); - add_struct(127, p); - -#undef add_struct - - smbios_entry_point_init(max_struct_size, p - start, start, nr_structs); - free(start); -} diff --git a/roms/seabios/src/smbios.h b/roms/seabios/src/smbios.h deleted file mode 100644 index 7bf2bed..0000000 --- a/roms/seabios/src/smbios.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __SMBIOS_H -#define __SMBIOS_H - -// smbios.c -void smbios_init(void); - -/* SMBIOS entry point -- must be written to a 16-bit aligned address - between 0xf0000 and 0xfffff. - */ -struct smbios_entry_point { - char anchor_string[4]; - u8 checksum; - u8 length; - u8 smbios_major_version; - u8 smbios_minor_version; - u16 max_structure_size; - u8 entry_point_revision; - u8 formatted_area[5]; - char intermediate_anchor_string[5]; - u8 intermediate_checksum; - u16 structure_table_length; - u32 structure_table_address; - u16 number_of_structures; - u8 smbios_bcd_revision; -} PACKED; - -/* This goes at the beginning of every SMBIOS structure. */ -struct smbios_structure_header { - u8 type; - u8 length; - u16 handle; -} PACKED; - -/* SMBIOS type 0 - BIOS Information */ -struct smbios_type_0 { - struct smbios_structure_header header; - u8 vendor_str; - u8 bios_version_str; - u16 bios_starting_address_segment; - u8 bios_release_date_str; - u8 bios_rom_size; - u8 bios_characteristics[8]; - u8 bios_characteristics_extension_bytes[2]; - u8 system_bios_major_release; - u8 system_bios_minor_release; - u8 embedded_controller_major_release; - u8 embedded_controller_minor_release; -} PACKED; - -/* SMBIOS type 1 - System Information */ -struct smbios_type_1 { - struct smbios_structure_header header; - u8 manufacturer_str; - u8 product_name_str; - u8 version_str; - u8 serial_number_str; - u8 uuid[16]; - u8 wake_up_type; - u8 sku_number_str; - u8 family_str; -} PACKED; - -/* SMBIOS type 3 - System Enclosure (v2.3) */ -struct smbios_type_3 { - struct smbios_structure_header header; - u8 manufacturer_str; - u8 type; - u8 version_str; - u8 serial_number_str; - u8 asset_tag_number_str; - u8 boot_up_state; - u8 power_supply_state; - u8 thermal_state; - u8 security_status; - u32 oem_defined; - u8 height; - u8 number_of_power_cords; - u8 contained_element_count; - // contained elements follow -} PACKED; - -/* SMBIOS type 4 - Processor Information (v2.0) */ -struct smbios_type_4 { - struct smbios_structure_header header; - u8 socket_designation_str; - u8 processor_type; - u8 processor_family; - u8 processor_manufacturer_str; - u32 processor_id[2]; - u8 processor_version_str; - u8 voltage; - u16 external_clock; - u16 max_speed; - u16 current_speed; - u8 status; - u8 processor_upgrade; - u16 l1_cache_handle; - u16 l2_cache_handle; - u16 l3_cache_handle; -} PACKED; - -/* SMBIOS type 16 - Physical Memory Array - * Associated with one type 17 (Memory Device). - */ -struct smbios_type_16 { - struct smbios_structure_header header; - u8 location; - u8 use; - u8 error_correction; - u32 maximum_capacity; - u16 memory_error_information_handle; - u16 number_of_memory_devices; -} PACKED; - -/* SMBIOS type 17 - Memory Device - * Associated with one type 19 - */ -struct smbios_type_17 { - struct smbios_structure_header header; - u16 physical_memory_array_handle; - u16 memory_error_information_handle; - u16 total_width; - u16 data_width; - u16 size; - u8 form_factor; - u8 device_set; - u8 device_locator_str; - u8 bank_locator_str; - u8 memory_type; - u16 type_detail; -} PACKED; - -/* SMBIOS type 19 - Memory Array Mapped Address */ -struct smbios_type_19 { - struct smbios_structure_header header; - u32 starting_address; - u32 ending_address; - u16 memory_array_handle; - u8 partition_width; -} PACKED; - -/* SMBIOS type 20 - Memory Device Mapped Address */ -struct smbios_type_20 { - struct smbios_structure_header header; - u32 starting_address; - u32 ending_address; - u16 memory_device_handle; - u16 memory_array_mapped_address_handle; - u8 partition_row_position; - u8 interleave_position; - u8 interleaved_data_depth; -} PACKED; - -/* SMBIOS type 32 - System Boot Information */ -struct smbios_type_32 { - struct smbios_structure_header header; - u8 reserved[6]; - u8 boot_status; -} PACKED; - -/* SMBIOS type 127 -- End-of-table */ -struct smbios_type_127 { - struct smbios_structure_header header; -} PACKED; - -#endif // smbios.h diff --git a/roms/seabios/src/smm.c b/roms/seabios/src/smm.c deleted file mode 100644 index 7e52892..0000000 --- a/roms/seabios/src/smm.c +++ /dev/null @@ -1,127 +0,0 @@ -// System Management Mode support (on emulators) -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "pci.h" // pci_config_writel -#include "util.h" // wbinvd -#include "config.h" // CONFIG_* -#include "ioport.h" // outb -#include "pci_ids.h" // PCI_VENDOR_ID_INTEL -#include "dev-i440fx.h" - -ASM32FLAT( - ".global smm_relocation_start\n" - ".global smm_relocation_end\n" - ".global smm_code_start\n" - ".global smm_code_end\n" - " .code16\n" - - /* code to relocate SMBASE to 0xa0000 */ - "smm_relocation_start:\n" - " mov $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7efc, %ebx\n" - " addr32 mov (%ebx), %al\n" /* revision ID to see if x86_64 or x86 */ - " cmp $0x64, %al\n" - " je 1f\n" - " mov $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7ef8, %ebx\n" - " jmp 2f\n" - "1:\n" - " mov $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7f00, %ebx\n" - "2:\n" - " movl $" __stringify(BUILD_SMM_ADDR) " - 0x8000, %eax\n" - " addr32 movl %eax, (%ebx)\n" - /* indicate to the BIOS that the SMM code was executed */ - " mov $0x00, %al\n" - " movw $" __stringify(PORT_SMI_STATUS) ", %dx\n" - " outb %al, %dx\n" - " rsm\n" - "smm_relocation_end:\n" - - /* minimal SMM code to enable or disable ACPI */ - "smm_code_start:\n" - " movw $" __stringify(PORT_SMI_CMD) ", %dx\n" - " inb %dx, %al\n" - " cmp $0xf0, %al\n" - " jne 1f\n" - - /* ACPI disable */ - " mov $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */ - " inw %dx, %ax\n" - " andw $~1, %ax\n" - " outw %ax, %dx\n" - - " jmp 2f\n" - - "1:\n" - " cmp $0xf1, %al\n" - " jne 2f\n" - - /* ACPI enable */ - " mov $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */ - " inw %dx, %ax\n" - " orw $1, %ax\n" - " outw %ax, %dx\n" - - "2:\n" - " rsm\n" - "smm_code_end:\n" - " .code32\n" - ); - -extern u8 smm_relocation_start, smm_relocation_end; -extern u8 smm_code_start, smm_code_end; - -void -smm_save_and_copy(void) -{ - /* save original memory content */ - memcpy((void *)BUILD_SMM_ADDR, (void *)BUILD_SMM_INIT_ADDR, BUILD_SMM_SIZE); - - /* copy the SMM relocation code */ - memcpy((void *)BUILD_SMM_INIT_ADDR, &smm_relocation_start, - &smm_relocation_end - &smm_relocation_start); -} - -void -smm_relocate_and_restore(void) -{ - /* init APM status port */ - outb(0x01, PORT_SMI_STATUS); - - /* raise an SMI interrupt */ - outb(0x00, PORT_SMI_CMD); - - /* wait until SMM code executed */ - while (inb(PORT_SMI_STATUS) != 0x00) - ; - - /* restore original memory content */ - memcpy((void *)BUILD_SMM_INIT_ADDR, (void *)BUILD_SMM_ADDR, BUILD_SMM_SIZE); - - /* copy the SMM code */ - memcpy((void *)BUILD_SMM_ADDR, &smm_code_start - , &smm_code_end - &smm_code_start); - wbinvd(); -} - -static const struct pci_device_id smm_init_tbl[] = { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - piix4_apmc_smm_init), - - PCI_DEVICE_END, -}; - -void -smm_init(void) -{ - if (CONFIG_COREBOOT) - // SMM only supported on emulators. - return; - if (!CONFIG_USE_SMM) - return; - - dprintf(3, "init smm\n"); - pci_find_init_device(smm_init_tbl, NULL); -} diff --git a/roms/seabios/src/smp.c b/roms/seabios/src/smp.c deleted file mode 100644 index 38e117e..0000000 --- a/roms/seabios/src/smp.c +++ /dev/null @@ -1,137 +0,0 @@ -// CPU count detection -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2006 Fabrice Bellard -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "config.h" // CONFIG_* -#include "cmos.h" // CMOS_BIOS_SMP_COUNT -#include "paravirt.h" - -#define APIC_ICR_LOW ((u8*)BUILD_APIC_ADDR + 0x300) -#define APIC_SVR ((u8*)BUILD_APIC_ADDR + 0x0F0) -#define APIC_LINT0 ((u8*)BUILD_APIC_ADDR + 0x350) -#define APIC_LINT1 ((u8*)BUILD_APIC_ADDR + 0x360) - -#define APIC_ENABLED 0x0100 - -struct { u32 ecx, eax, edx; } smp_mtrr[16] VAR16VISIBLE; -u32 smp_mtrr_count VAR16VISIBLE; - -void -wrmsr_smp(u32 index, u64 val) -{ - wrmsr(index, val); - if (smp_mtrr_count >= ARRAY_SIZE(smp_mtrr)) - return; - smp_mtrr[smp_mtrr_count].ecx = index; - smp_mtrr[smp_mtrr_count].eax = val; - smp_mtrr[smp_mtrr_count].edx = val >> 32; - smp_mtrr_count++; -} - -u32 CountCPUs VAR16VISIBLE; -u32 MaxCountCPUs VAR16VISIBLE; -extern void smp_ap_boot_code(void); -ASM16( - " .global smp_ap_boot_code\n" - "smp_ap_boot_code:\n" - - // Setup data segment - " movw $" __stringify(SEG_BIOS) ", %ax\n" - " movw %ax, %ds\n" - - // MTRR setup - " movl $smp_mtrr, %esi\n" - " movl smp_mtrr_count, %ebx\n" - "1:testl %ebx, %ebx\n" - " jz 2f\n" - " movl 0(%esi), %ecx\n" - " movl 4(%esi), %eax\n" - " movl 8(%esi), %edx\n" - " wrmsr\n" - " addl $12, %esi\n" - " decl %ebx\n" - " jmp 1b\n" - "2:\n" - - // Increment the cpu counter - " lock incl CountCPUs\n" - - // Halt the processor. - "1:hlt\n" - " jmp 1b\n" - ); - -// find and initialize the CPUs by launching a SIPI to them -void -smp_probe(void) -{ - ASSERT32FLAT(); - u32 eax, ebx, ecx, cpuid_features; - cpuid(1, &eax, &ebx, &ecx, &cpuid_features); - if (eax < 1 || !(cpuid_features & CPUID_APIC)) { - // No apic - only the main cpu is present. - dprintf(1, "No apic - only the main cpu is present.\n"); - CountCPUs= 1; - MaxCountCPUs = 1; - return; - } - - // Init the counter. - writel(&CountCPUs, 1); - - // Setup jump trampoline to counter code. - u64 old = *(u64*)BUILD_AP_BOOT_ADDR; - // ljmpw $SEG_BIOS, $(smp_ap_boot_code - BUILD_BIOS_ADDR) - u64 new = (0xea | ((u64)SEG_BIOS<<24) - | (((u32)smp_ap_boot_code - BUILD_BIOS_ADDR) << 8)); - *(u64*)BUILD_AP_BOOT_ADDR = new; - - // enable local APIC - u32 val = readl(APIC_SVR); - writel(APIC_SVR, val | APIC_ENABLED); - - if (! CONFIG_COREBOOT) { - /* Set LINT0 as Ext_INT, level triggered */ - writel(APIC_LINT0, 0x8700); - - /* Set LINT1 as NMI, level triggered */ - writel(APIC_LINT1, 0x8400); - } - - // broadcast SIPI - barrier(); - writel(APIC_ICR_LOW, 0x000C4500); - u32 sipi_vector = BUILD_AP_BOOT_ADDR >> 12; - writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector); - - // Wait for other CPUs to process the SIPI. - if (CONFIG_COREBOOT) { - msleep(10); - } else { - u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT); - while (cmos_smp_count + 1 != readl(&CountCPUs)) - yield(); - } - - // Restore memory. - *(u64*)BUILD_AP_BOOT_ADDR = old; - - MaxCountCPUs = qemu_cfg_get_max_cpus(); - if (!MaxCountCPUs || MaxCountCPUs < CountCPUs) - MaxCountCPUs = CountCPUs; - - dprintf(1, "Found %d cpu(s) max supported %d cpu(s)\n", readl(&CountCPUs), - MaxCountCPUs); -} - -// Reset variables to zero -void -smp_probe_setup(void) -{ - CountCPUs = 0; - smp_mtrr_count = 0; -} diff --git a/roms/seabios/src/ssdt-proc.dsl b/roms/seabios/src/ssdt-proc.dsl deleted file mode 100644 index 358afa8..0000000 --- a/roms/seabios/src/ssdt-proc.dsl +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is the basis for the ssdt_proc[] variable in src/acpi.c. - * It defines the contents of the per-cpu Processor() object. At - * runtime, a dynamically generated SSDT will contain one copy of this - * AML snippet for every possible cpu in the system. The objects will - * be placed in the \_SB_ namespace. - * - * To generate a new ssdt_proc[], run the commands: - * cpp -P src/ssdt-proc.dsl > out/ssdt-proc.dsl.i - * iasl -ta -p out/ssdt-proc out/ssdt-proc.dsl.i - * tail -c +37 < out/ssdt-proc.aml | hexdump -e '" " 8/1 "0x%02x," "\n"' - * and then cut-and-paste the output into the src/acpi.c ssdt_proc[] - * array. - * - * In addition to the aml code generated from this file, the - * src/acpi.c file creates a NTFY method with an entry for each cpu: - * Method(NTFY, 2) { - * If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) } - * If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) } - * ... - * } - * and a CPON array with the list of active and inactive cpus: - * Name(CPON, Package() { One, One, ..., Zero, Zero, ... }) - */ -DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1) -/* v------------------ DO NOT EDIT ------------------v */ -{ - Processor (CPAA, 0xAA, 0x0000b010, 0x06) { - Name (ID, 0xAA) -/* ^------------------ DO NOT EDIT ------------------^ - * - * The src/acpi.c code requires the above layout so that it can update - * CPAA and 0xAA with the appropriate CPU id (see - * SD_OFFSET_CPUHEX/CPUID1/CPUID2). Don't change the above without - * also updating the C code. - */ - Name (_HID, "ACPI0007") - External(CPMA, MethodObj) - External(CPST, MethodObj) - External(CPEJ, MethodObj) - Method(_MAT, 0) { - Return(CPMA(ID)) - } - Method (_STA, 0) { - Return(CPST(ID)) - } - Method (_EJ0, 1, NotSerialized) { - CPEJ(ID, Arg0) - } - } -} diff --git a/roms/seabios/src/stacks.c b/roms/seabios/src/stacks.c deleted file mode 100644 index f5feeeb..0000000 --- a/roms/seabios/src/stacks.c +++ /dev/null @@ -1,404 +0,0 @@ -// Code for manipulating stack locations. -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "biosvar.h" // get_ebda_seg -#include "util.h" // dprintf -#include "bregs.h" // CR0_PE - -// Thread info - stored at bottom of each thread stack - don't change -// without also updating the inline assembler below. -struct thread_info { - struct thread_info *next; - void *stackpos; - struct thread_info **pprev; -}; -struct thread_info VAR16VISIBLE MainThread; - - -/**************************************************************** - * Low level helpers - ****************************************************************/ - -static inline u32 getcr0(void) { - u32 cr0; - asm("movl %%cr0, %0" : "=r"(cr0)); - return cr0; -} -static inline void sgdt(struct descloc_s *desc) { - asm("sgdtl %0" : "=m"(*desc)); -} -static inline void lgdt(struct descloc_s *desc) { - asm("lgdtl %0" : : "m"(*desc) : "memory"); -} - -// Call a 32bit SeaBIOS function from a 16bit SeaBIOS function. -static inline int -call32(void *func) -{ - ASSERT16(); - u32 cr0 = getcr0(); - if (cr0 & CR0_PE) - // Called in 16bit protected mode?! - return -1; - - // Backup cmos index register and disable nmi - u8 cmosindex = inb(PORT_CMOS_INDEX); - outb(cmosindex | NMI_DISABLE_BIT, PORT_CMOS_INDEX); - inb(PORT_CMOS_DATA); - - // Backup fs/gs and gdt - u16 fs = GET_SEG(FS), gs = GET_SEG(GS); - struct descloc_s gdt; - sgdt(&gdt); - - u32 bkup_ss, bkup_esp; - asm volatile( - // Backup ss/esp / set esp to flat stack location - " movl %%ss, %0\n" - " movl %%esp, %1\n" - " shll $4, %0\n" - " addl %0, %%esp\n" - " movl %%ss, %0\n" - - // Transition to 32bit mode, call func, return to 16bit - " pushl $(" __stringify(BUILD_BIOS_ADDR) " + 1f)\n" - " jmp transition32\n" - " .code32\n" - "1:calll *%2\n" - " pushl $2f\n" - " jmp transition16big\n" - - // Restore ds/ss/esp - " .code16gcc\n" - "2:movl %0, %%ds\n" - " movl %0, %%ss\n" - " movl %1, %%esp\n" - : "=&r" (bkup_ss), "=&r" (bkup_esp) - : "r" (func) - : "eax", "ecx", "edx", "cc", "memory"); - - // Restore gdt and fs/gs - lgdt(&gdt); - SET_SEG(FS, fs); - SET_SEG(GS, gs); - - // Restore cmos index register - outb(cmosindex, PORT_CMOS_INDEX); - inb(PORT_CMOS_DATA); - return 0; -} - -// 16bit trampoline for enabling irqs from 32bit mode. -ASM16( - " .global trampoline_checkirqs\n" - "trampoline_checkirqs:\n" - " rep ; nop\n" - " lretw" - ); - -static void -check_irqs(void) -{ - if (MODESEGMENT) { - asm volatile( - "sti\n" - "nop\n" - "rep ; nop\n" - "cli\n" - "cld\n" - : : :"memory"); - return; - } - extern void trampoline_checkirqs(); - struct bregs br; - br.flags = F_IF; - br.code.seg = SEG_BIOS; - br.code.offset = (u32)&trampoline_checkirqs; - call16big(&br); -} - -// 16bit trampoline for waiting for an irq from 32bit mode. -ASM16( - " .global trampoline_waitirq\n" - "trampoline_waitirq:\n" - " sti\n" - " hlt\n" - " lretw" - ); - -// Wait for next irq to occur. -void -wait_irq(void) -{ - if (MODESEGMENT) { - asm volatile("sti ; hlt ; cli ; cld": : :"memory"); - return; - } - if (CONFIG_THREADS && MainThread.next != &MainThread) { - // Threads still active - do a yield instead. - yield(); - return; - } - extern void trampoline_waitirq(); - struct bregs br; - br.flags = 0; - br.code.seg = SEG_BIOS; - br.code.offset = (u32)&trampoline_waitirq; - call16big(&br); -} - - -/**************************************************************** - * Stack in EBDA - ****************************************************************/ - -// Switch to the extra stack in ebda and call a function. -inline u32 -stack_hop(u32 eax, u32 edx, void *func) -{ - ASSERT16(); - u16 ebda_seg = get_ebda_seg(), bkup_ss; - u32 bkup_esp; - asm volatile( - // Backup current %ss/%esp values. - "movw %%ss, %w3\n" - "movl %%esp, %4\n" - // Copy ebda seg to %ds/%ss and set %esp - "movw %w6, %%ds\n" - "movw %w6, %%ss\n" - "movl %5, %%esp\n" - // Call func - "calll *%2\n" - // Restore segments and stack - "movw %w3, %%ds\n" - "movw %w3, %%ss\n" - "movl %4, %%esp" - : "+a" (eax), "+d" (edx), "+c" (func), "=&r" (bkup_ss), "=&r" (bkup_esp) - : "i" (EBDA_OFFSET_TOP_STACK), "r" (ebda_seg) - : "cc", "memory"); - return eax; -} - - -/**************************************************************** - * Threads - ****************************************************************/ - -#define THREADSTACKSIZE 4096 -int VAR16VISIBLE CanPreempt; - -void -thread_setup(void) -{ - MainThread.next = &MainThread; - MainThread.pprev = &MainThread.next; - MainThread.stackpos = NULL; - CanPreempt = 0; -} - -// Return the 'struct thread_info' for the currently running thread. -struct thread_info * -getCurThread(void) -{ - u32 esp = getesp(); - if (esp <= BUILD_STACK_ADDR) - return &MainThread; - return (void*)ALIGN_DOWN(esp, THREADSTACKSIZE); -} - -// Switch to next thread stack. -static void -switch_next(struct thread_info *cur) -{ - struct thread_info *next = cur->next; - if (cur == next) - // Nothing to do. - return; - asm volatile( - " pushl $1f\n" // store return pc - " pushl %%ebp\n" // backup %ebp - " movl %%esp, 4(%%eax)\n" // cur->stackpos = %esp - " movl 4(%%ecx), %%esp\n" // %esp = next->stackpos - " popl %%ebp\n" // restore %ebp - " retl\n" // restore pc - "1:\n" - : "+a"(cur), "+c"(next) - : - : "ebx", "edx", "esi", "edi", "cc", "memory"); -} - -// Briefly permit irqs to occur. -void -yield(void) -{ - if (MODESEGMENT || !CONFIG_THREADS) { - // Just directly check irqs. - check_irqs(); - return; - } - struct thread_info *cur = getCurThread(); - if (cur == &MainThread) - // Permit irqs to fire - check_irqs(); - - // Switch to the next thread - switch_next(cur); -} - -// Last thing called from a thread (called on "next" stack). -static void -__end_thread(struct thread_info *old) -{ - old->next->pprev = old->pprev; - *old->pprev = old->next; - free(old); - dprintf(DEBUG_thread, "\\%08x/ End thread\n", (u32)old); - if (MainThread.next == &MainThread) - dprintf(1, "All threads complete.\n"); -} - -// Create a new thread and start executing 'func' in it. -void -run_thread(void (*func)(void*), void *data) -{ - ASSERT32FLAT(); - if (! CONFIG_THREADS) - goto fail; - struct thread_info *thread; - thread = memalign_tmphigh(THREADSTACKSIZE, THREADSTACKSIZE); - if (!thread) - goto fail; - - thread->stackpos = (void*)thread + THREADSTACKSIZE; - struct thread_info *cur = getCurThread(); - thread->next = cur; - thread->pprev = cur->pprev; - cur->pprev = &thread->next; - *thread->pprev = thread; - - dprintf(DEBUG_thread, "/%08x\\ Start thread\n", (u32)thread); - asm volatile( - // Start thread - " pushl $1f\n" // store return pc - " pushl %%ebp\n" // backup %ebp - " movl %%esp, 4(%%edx)\n" // cur->stackpos = %esp - " movl 4(%%ebx), %%esp\n" // %esp = thread->stackpos - " calll *%%ecx\n" // Call func - - // End thread - " movl (%%ebx), %%ecx\n" // %ecx = thread->next - " movl 4(%%ecx), %%esp\n" // %esp = next->stackpos - " movl %%ebx, %%eax\n" - " calll %4\n" // call __end_thread(thread) - " popl %%ebp\n" // restore %ebp - " retl\n" // restore pc - "1:\n" - : "+a"(data), "+c"(func), "+b"(thread), "+d"(cur) - : "m"(*(u8*)__end_thread) - : "esi", "edi", "cc", "memory"); - return; - -fail: - func(data); -} - -// Wait for all threads (other than the main thread) to complete. -void -wait_threads(void) -{ - ASSERT32FLAT(); - if (! CONFIG_THREADS) - return; - while (MainThread.next != &MainThread) - yield(); -} - -void -mutex_lock(struct mutex_s *mutex) -{ - ASSERT32FLAT(); - if (! CONFIG_THREADS) - return; - while (mutex->isLocked) - yield(); - mutex->isLocked = 1; -} - -void -mutex_unlock(struct mutex_s *mutex) -{ - ASSERT32FLAT(); - if (! CONFIG_THREADS) - return; - mutex->isLocked = 0; -} - - -/**************************************************************** - * Thread preemption - ****************************************************************/ - -static u32 PreemptCount; - -// Turn on RTC irqs and arrange for them to check the 32bit threads. -void -start_preempt(void) -{ - if (! CONFIG_THREADS || ! CONFIG_THREAD_OPTIONROMS) - return; - CanPreempt = 1; - PreemptCount = 0; - useRTC(); -} - -// Turn off RTC irqs / stop checking for thread execution. -void -finish_preempt(void) -{ - if (! CONFIG_THREADS || ! CONFIG_THREAD_OPTIONROMS) { - yield(); - return; - } - CanPreempt = 0; - releaseRTC(); - dprintf(9, "Done preempt - %d checks\n", PreemptCount); - yield(); -} - -// Check if preemption is on, and wait for it to complete if so. -int -wait_preempt(void) -{ - if (MODESEGMENT || !CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS - || !CanPreempt) - return 0; - while (CanPreempt) - yield(); - return 1; -} - -extern void yield_preempt(void); -#if MODESEGMENT == 0 -// Try to execute 32bit threads. -void VISIBLE32FLAT -yield_preempt(void) -{ - PreemptCount++; - switch_next(&MainThread); -} -#endif - -// 16bit code that checks if threads are pending and executes them if so. -void -check_preempt(void) -{ - if (! CONFIG_THREADS || ! CONFIG_THREAD_OPTIONROMS - || !GET_GLOBAL(CanPreempt) - || GET_GLOBAL(MainThread.next) == &MainThread) - return; - - call32(yield_preempt); -} diff --git a/roms/seabios/src/system.c b/roms/seabios/src/system.c deleted file mode 100644 index 898c3cc..0000000 --- a/roms/seabios/src/system.c +++ /dev/null @@ -1,365 +0,0 @@ -// Handler for int 0x15 "system" calls -// -// Copyright (C) 2008 Kevin O'Connor -// Copyright (C) 2002 MandrakeSoft S.A. -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // memcpy_far -#include "biosvar.h" // BIOS_CONFIG_TABLE -#include "ioport.h" // inb -#include "memmap.h" // E820_RAM -#include "pic.h" // eoi_pic2 -#include "bregs.h" // struct bregs - -// Use PS2 System Control port A to set A20 enable -static inline u8 -set_a20(u8 cond) -{ - // get current setting first - u8 newval, oldval = inb(PORT_A20); - if (cond) - newval = oldval | A20_ENABLE_BIT; - else - newval = oldval & ~A20_ENABLE_BIT; - outb(newval, PORT_A20); - - return (oldval & A20_ENABLE_BIT) != 0; -} - -static void -handle_152400(struct bregs *regs) -{ - set_a20(0); - set_code_success(regs); -} - -static void -handle_152401(struct bregs *regs) -{ - set_a20(1); - set_code_success(regs); -} - -static void -handle_152402(struct bregs *regs) -{ - regs->al = (inb(PORT_A20) & A20_ENABLE_BIT) != 0; - set_code_success(regs); -} - -static void -handle_152403(struct bregs *regs) -{ - regs->bx = 3; - set_code_success(regs); -} - -static void -handle_1524XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EUNSUPPORTED); -} - -static void -handle_1524(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_152400(regs); break; - case 0x01: handle_152401(regs); break; - case 0x02: handle_152402(regs); break; - case 0x03: handle_152403(regs); break; - default: handle_1524XX(regs); break; - } -} - -// removable media eject -static void -handle_1552(struct bregs *regs) -{ - set_code_success(regs); -} - -static void -handle_1587(struct bregs *regs) -{ - // +++ should probably have descriptor checks - // +++ should have exception handlers - - u8 prev_a20_enable = set_a20(1); // enable A20 line - - // 128K max of transfer on 386+ ??? - // source == destination ??? - - // ES:SI points to descriptor table - // offset use initially comments - // ============================================== - // 00..07 Unused zeros Null descriptor - // 08..0f GDT zeros filled in by BIOS - // 10..17 source ssssssss source of data - // 18..1f dest dddddddd destination of data - // 20..27 CS zeros filled in by BIOS - // 28..2f SS zeros filled in by BIOS - -// check for access rights of source & dest here - - // Initialize GDT descriptor - u32 si = regs->si; - u64 *gdt_far = (void*)si; - u16 gdt_seg = regs->es; - u32 loc = (u32)MAKE_FLATPTR(gdt_seg, gdt_far); - SET_FARVAR(gdt_seg, gdt_far[1], GDT_DATA | GDT_LIMIT((6*sizeof(u64))-1) - | GDT_BASE(loc)); - // Initialize CS descriptor - SET_FARVAR(gdt_seg, gdt_far[4], GDT_CODE | GDT_LIMIT(BUILD_BIOS_SIZE-1) - | GDT_BASE(BUILD_BIOS_ADDR)); - // Initialize SS descriptor - loc = (u32)MAKE_FLATPTR(GET_SEG(SS), 0); - SET_FARVAR(gdt_seg, gdt_far[5], GDT_DATA | GDT_LIMIT(0x0ffff) - | GDT_BASE(loc)); - - u16 count = regs->cx; - asm volatile( - // Load new descriptor tables - " lgdtw %%es:(1<<3)(%%si)\n" - " lidtw %%cs:pmode_IDT_info\n" - - // Enable protected mode - " movl %%cr0, %%eax\n" - " orl $" __stringify(CR0_PE) ", %%eax\n" - " movl %%eax, %%cr0\n" - - // far jump to flush CPU queue after transition to protected mode - " ljmpw $(4<<3), $1f\n" - - // GDT points to valid descriptor table, now load DS, ES - "1:movw $(2<<3), %%ax\n" // 2nd descriptor in table, TI=GDT, RPL=00 - " movw %%ax, %%ds\n" - " movw $(3<<3), %%ax\n" // 3rd descriptor in table, TI=GDT, RPL=00 - " movw %%ax, %%es\n" - - // move CX words from DS:SI to ES:DI - " xorw %%si, %%si\n" - " xorw %%di, %%di\n" - " rep movsw\n" - - // Restore DS and ES segment limits to 0xffff - " movw $(5<<3), %%ax\n" // 5th descriptor in table (SS) - " movw %%ax, %%ds\n" - " movw %%ax, %%es\n" - - // Disable protected mode - " movl %%cr0, %%eax\n" - " andl $~" __stringify(CR0_PE) ", %%eax\n" - " movl %%eax, %%cr0\n" - - // far jump to flush CPU queue after transition to real mode - " ljmpw $" __stringify(SEG_BIOS) ", $2f\n" - - // restore IDT to normal real-mode defaults - "2:lidtw %%cs:rmode_IDT_info\n" - - // Restore %ds (from %ss) - " movw %%ss, %%ax\n" - " movw %%ax, %%ds\n" - : "+c"(count), "+S"(si) - : : "eax", "di", "cc"); // XXX - also clobbers %es - - set_a20(prev_a20_enable); - - set_code_success(regs); -} - -// Get the amount of extended memory (above 1M) -static void -handle_1588(struct bregs *regs) -{ - u32 rs = GET_GLOBAL(RamSize); - - // According to Ralf Brown's interrupt the limit should be 15M, - // but real machines mostly return max. 63M. - if (rs > 64*1024*1024) - regs->ax = 63 * 1024; - else - regs->ax = (rs - 1*1024*1024) / 1024; - set_success(regs); -} - -// Switch to protected mode -static void -handle_1589(struct bregs *regs) -{ - set_a20(1); - - set_pics(regs->bl, regs->bh); - - u64 *gdt_far = (void*)(regs->si + 0); - u16 gdt_seg = regs->es; - SET_FARVAR(gdt_seg, gdt_far[7], GDT_CODE | GDT_LIMIT(BUILD_BIOS_SIZE-1) - | GDT_BASE(BUILD_BIOS_ADDR)); - - regs->ds = 3<<3; // 3rd gdt descriptor is %ds - regs->es = 4<<3; // 4th gdt descriptor is %es - regs->code.seg = 6<<3; // 6th gdt descriptor is %cs - - set_code_success(regs); - - asm volatile( - // Load new descriptor tables - " lgdtw %%es:(1<<3)(%%si)\n" - " lidtw %%es:(2<<3)(%%si)\n" - - // Enable protected mode - " movl %%cr0, %%eax\n" - " orl $" __stringify(CR0_PE) ", %%eax\n" - " movl %%eax, %%cr0\n" - - // far jump to flush CPU queue after transition to protected mode - " ljmpw $(7<<3), $1f\n" - - // GDT points to valid descriptor table, now load SS - "1:movw $(5<<3), %%ax\n" - " movw %%ax, %%ds\n" - " movw %%ax, %%ss\n" - : - : "S"(gdt_far) - : "eax", "cc"); -} - -// Device busy interrupt. Called by Int 16h when no key available -static void -handle_1590(struct bregs *regs) -{ -} - -// Interrupt complete. Called by Int 16h when key becomes available -static void -handle_1591(struct bregs *regs) -{ -} - -// keyboard intercept -static void -handle_154f(struct bregs *regs) -{ - set_invalid_silent(regs); -} - -static void -handle_15c0(struct bregs *regs) -{ - regs->es = SEG_BIOS; - regs->bx = (u32)&BIOS_CONFIG_TABLE; - set_code_success(regs); -} - -static void -handle_15c1(struct bregs *regs) -{ - regs->es = get_ebda_seg(); - set_success(regs); -} - -static void -handle_15e801(struct bregs *regs) -{ - // my real system sets ax and bx to 0 - // this is confirmed by Ralph Brown list - // but syslinux v1.48 is known to behave - // strangely if ax is set to 0 - // regs.u.r16.ax = 0; - // regs.u.r16.bx = 0; - - u32 rs = GET_GLOBAL(RamSize); - - // Get the amount of extended memory (above 1M) - if (rs > 16*1024*1024) { - // limit to 15M - regs->cx = 15*1024; - // Get the amount of extended memory above 16M in 64k blocks - regs->dx = (rs - 16*1024*1024) / (64*1024); - } else { - regs->cx = (rs - 1*1024*1024) / 1024; - regs->dx = 0; - } - - // Set configured memory equal to extended memory - regs->ax = regs->cx; - regs->bx = regs->dx; - - set_success(regs); -} - -// Info on e820 map location and size. -struct e820entry e820_list[CONFIG_MAX_E820] VAR16VISIBLE; -int e820_count VAR16VISIBLE; - -static void -handle_15e820(struct bregs *regs) -{ - int count = GET_GLOBAL(e820_count); - if (regs->edx != 0x534D4150 || regs->bx >= count - || regs->ecx < sizeof(e820_list[0])) { - set_code_invalid(regs, RET_EUNSUPPORTED); - return; - } - - memcpy_far(regs->es, (void*)(regs->di+0) - , get_global_seg(), &e820_list[regs->bx] - , sizeof(e820_list[0])); - if (regs->bx == count-1) - regs->ebx = 0; - else - regs->ebx++; - regs->eax = 0x534D4150; - regs->ecx = sizeof(e820_list[0]); - set_success(regs); -} - -static void -handle_15e8XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EUNSUPPORTED); -} - -static void -handle_15e8(struct bregs *regs) -{ - switch (regs->al) { - case 0x01: handle_15e801(regs); break; - case 0x20: handle_15e820(regs); break; - default: handle_15e8XX(regs); break; - } -} - -static void -handle_15XX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EUNSUPPORTED); -} - -// INT 15h System Services Entry Point -void VISIBLE16 -handle_15(struct bregs *regs) -{ - debug_enter(regs, DEBUG_HDL_15); - switch (regs->ah) { - case 0x24: handle_1524(regs); break; - case 0x4f: handle_154f(regs); break; - case 0x52: handle_1552(regs); break; - case 0x53: handle_1553(regs); break; - case 0x5f: handle_155f(regs); break; - case 0x83: handle_1583(regs); break; - case 0x86: handle_1586(regs); break; - case 0x87: handle_1587(regs); break; - case 0x88: handle_1588(regs); break; - case 0x89: handle_1589(regs); break; - case 0x90: handle_1590(regs); break; - case 0x91: handle_1591(regs); break; - case 0xc0: handle_15c0(regs); break; - case 0xc1: handle_15c1(regs); break; - case 0xc2: handle_15c2(regs); break; - case 0xe8: handle_15e8(regs); break; - default: handle_15XX(regs); break; - } -} diff --git a/roms/seabios/src/types.h b/roms/seabios/src/types.h deleted file mode 100644 index 5083941..0000000 --- a/roms/seabios/src/types.h +++ /dev/null @@ -1,138 +0,0 @@ -// Basic type definitions for X86 cpus. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __TYPES_H -#define __TYPES_H - -typedef unsigned char u8; -typedef signed char s8; -typedef unsigned short u16; -typedef signed short s16; -typedef unsigned int u32; -typedef signed int s32; -typedef unsigned long long u64; -typedef signed long long s64; -typedef u32 size_t; - -union u64_u32_u { - struct { u32 hi, lo; }; - u64 val; -}; - -#ifdef MANUAL_NO_JUMP_TABLE -# define default case 775324556: asm(""); default -#endif - -#ifdef WHOLE_PROGRAM -# define __VISIBLE __attribute__((externally_visible)) -#else -# define __VISIBLE -#endif - -#define UNIQSEC __FILE__ "." __stringify(__LINE__) - -#define __noreturn __attribute__((noreturn)) -extern void __force_link_error__only_in_32bit_flat(void) __noreturn; -extern void __force_link_error__only_in_32bit_segmented(void) __noreturn; -extern void __force_link_error__only_in_16bit(void) __noreturn; - -#define __ASM(code) asm(".section .text.asm." UNIQSEC "\n\t" code) - -#if MODE16 == 1 -// Notes a function as externally visible in the 16bit code chunk. -# define VISIBLE16 __VISIBLE -// Notes a function as externally visible in the 32bit flat code chunk. -# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline __weak -// Notes a function as externally visible in the 32bit segmented code chunk. -# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline __weak -// Designate a variable as (only) visible to 16bit code. -# define VAR16 __section(".data16." UNIQSEC) -// Designate a variable as visible to 16bit, 32bit, and assembler code. -# define VAR16VISIBLE VAR16 __VISIBLE -// Designate a variable as externally visible (in addition to all internal code). -# define VAR16EXPORT __section(".data16.export." UNIQSEC) __VISIBLE -// Designate a variable at a specific 16bit address -# define VAR16FIXED(addr) __aligned(1) __VISIBLE __section(".fixedaddr." __stringify(addr)) -// Designate a variable as (only) visible to 32bit segmented code. -# define VAR32SEG __section(".discard.var32seg." UNIQSEC) -// Designate a 32bit variable also available in 16bit "big real" mode. -# define VAR32FLATVISIBLE __section(".discard.var32flat." UNIQSEC) __VISIBLE __weak -// Designate top-level assembler as 16bit only. -# define ASM16(code) __ASM(code) -// Designate top-level assembler as 32bit flat only. -# define ASM32FLAT(code) -// Compile time check for a given mode. -# define ASSERT16() do { } while (0) -# define ASSERT32SEG() __force_link_error__only_in_32bit_segmented() -# define ASSERT32FLAT() __force_link_error__only_in_32bit_flat() -#elif MODESEGMENT == 1 -# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline __weak -# define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline __weak -# define VISIBLE32SEG __VISIBLE -# define VAR16 __section(".discard.var16." UNIQSEC) -# define VAR16VISIBLE VAR16 __VISIBLE __weak -# define VAR16EXPORT VAR16VISIBLE -# define VAR16FIXED(addr) VAR16VISIBLE -# define VAR32SEG __section(".data32seg." UNIQSEC) -# define VAR32FLATVISIBLE __section(".discard.var32flat." UNIQSEC) __VISIBLE __weak -# define ASM16(code) -# define ASM32FLAT(code) -# define ASSERT16() __force_link_error__only_in_16bit() -# define ASSERT32SEG() do { } while (0) -# define ASSERT32FLAT() __force_link_error__only_in_32bit_flat() -#else -# define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline __weak -# define VISIBLE32FLAT __VISIBLE -# define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline __weak -# define VAR16 __section(".discard.var16." UNIQSEC) -# define VAR16VISIBLE VAR16 __VISIBLE __weak -# define VAR16EXPORT VAR16VISIBLE -# define VAR16FIXED(addr) VAR16VISIBLE -# define VAR32SEG __section(".discard.var32seg." UNIQSEC) -# define VAR32FLATVISIBLE __VISIBLE -# define ASM16(code) -# define ASM32FLAT(code) __ASM(code) -# define ASSERT16() __force_link_error__only_in_16bit() -# define ASSERT32SEG() __force_link_error__only_in_32bit_segmented() -# define ASSERT32FLAT() do { } while (0) -#endif - -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) -#define DIV_ROUND_CLOSEST(x, divisor)({ \ - typeof(divisor) __divisor = divisor; \ - (((x) + ((__divisor) / 2)) / (__divisor)); \ - }) -#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) -#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) -#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1)) -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) - -#define NULL ((void*)0) - -#define __weak __attribute__((weak)) -#define __section(S) __attribute__((section(S))) - -#define PACKED __attribute__((packed)) -#define __aligned(x) __attribute__((aligned(x))) - -#define barrier() __asm__ __volatile__("": : :"memory") - -#define noinline __attribute__((noinline)) -#define __always_inline inline __attribute__((always_inline)) -#define __malloc __attribute__((__malloc__)) -#define __attribute_const __attribute__((__const__)) - -#define __stringify_1(x) #x -#define __stringify(x) __stringify_1(x) - -#endif // types.h diff --git a/roms/seabios/src/usb-ehci.c b/roms/seabios/src/usb-ehci.c deleted file mode 100644 index 4e228bd..0000000 --- a/roms/seabios/src/usb-ehci.c +++ /dev/null @@ -1,760 +0,0 @@ -// Code for handling EHCI USB controllers. -// -// Copyright (C) 2010 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "pci.h" // pci_bdf_to_bus -#include "config.h" // CONFIG_* -#include "ioport.h" // outw -#include "usb-ehci.h" // struct ehci_qh -#include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI -#include "pci_regs.h" // PCI_BASE_ADDRESS_0 -#include "usb.h" // struct usb_s -#include "farptr.h" // GET_FLATPTR -#include "usb-uhci.h" // init_uhci -#include "usb-ohci.h" // init_ohci - -struct companion_s { - u16 bdf; - u16 type; -}; - -struct usb_ehci_s { - struct usb_s usb; - struct ehci_caps *caps; - struct ehci_regs *regs; - struct ehci_qh *async_qh; - struct companion_s companion[8]; - int checkports; - int legacycount; -}; - - -/**************************************************************** - * Root hub - ****************************************************************/ - -#define EHCI_TIME_POSTPOWER 20 -#define EHCI_TIME_POSTRESET 2 - -// Check if need companion controllers for full/low speed devices -static void -ehci_note_port(struct usb_ehci_s *cntl) -{ - if (--cntl->checkports) - // Ports still being detected. - return; - if (! cntl->legacycount) - // No full/low speed devices found. - return; - // Start companion controllers. - int i; - for (i=0; icompanion); i++) { - u16 type = cntl->companion[i].type; - if (type == USB_TYPE_UHCI) - uhci_init(cntl->companion[i].bdf, cntl->usb.busid + i); - else if (type == USB_TYPE_OHCI) - ohci_init(cntl->companion[i].bdf, cntl->usb.busid + i); - else - return; - } -} - -// Check if device attached to port -static int -ehci_hub_detect(struct usbhub_s *hub, u32 port) -{ - struct usb_ehci_s *cntl = container_of(hub->cntl, struct usb_ehci_s, usb); - u32 *portreg = &cntl->regs->portsc[port]; - u32 portsc = readl(portreg); - - // Power up port. - if (!(portsc & PORT_POWER)) { - portsc |= PORT_POWER; - writel(portreg, portsc); - msleep(EHCI_TIME_POSTPOWER); - } else { - msleep(1); // XXX - time for connect to be detected. - } - portsc = readl(portreg); - - if (!(portsc & PORT_CONNECT)) - // No device present - goto doneearly; - - if ((portsc & PORT_LINESTATUS_MASK) == PORT_LINESTATUS_KSTATE) { - // low speed device - cntl->legacycount++; - writel(portreg, portsc | PORT_OWNER); - goto doneearly; - } - - // XXX - if just powered up, need to wait for USB_TIME_ATTDB? - - // Begin reset on port - portsc = (portsc & ~PORT_PE) | PORT_RESET; - writel(portreg, portsc); - msleep(USB_TIME_DRSTR); - return 0; - -doneearly: - ehci_note_port(cntl); - return -1; -} - -// Reset device on port -static int -ehci_hub_reset(struct usbhub_s *hub, u32 port) -{ - struct usb_ehci_s *cntl = container_of(hub->cntl, struct usb_ehci_s, usb); - u32 *portreg = &cntl->regs->portsc[port]; - u32 portsc = readl(portreg); - - // Finish reset on port - portsc &= ~PORT_RESET; - writel(portreg, portsc); - msleep(EHCI_TIME_POSTRESET); - - int rv = -1; - portsc = readl(portreg); - if (!(portsc & PORT_CONNECT)) - // No longer connected - goto resetfail; - if (!(portsc & PORT_PE)) { - // full speed device - cntl->legacycount++; - writel(portreg, portsc | PORT_OWNER); - goto resetfail; - } - - rv = USB_HIGHSPEED; -resetfail: - ehci_note_port(cntl); - return rv; -} - -// Disable port -static void -ehci_hub_disconnect(struct usbhub_s *hub, u32 port) -{ - struct usb_ehci_s *cntl = container_of(hub->cntl, struct usb_ehci_s, usb); - u32 *portreg = &cntl->regs->portsc[port]; - u32 portsc = readl(portreg); - writel(portreg, portsc & ~PORT_PE); -} - -static struct usbhub_op_s ehci_HubOp = { - .detect = ehci_hub_detect, - .reset = ehci_hub_reset, - .disconnect = ehci_hub_disconnect, -}; - -// Find any devices connected to the root hub. -static int -check_ehci_ports(struct usb_ehci_s *cntl) -{ - ASSERT32FLAT(); - struct usbhub_s hub; - memset(&hub, 0, sizeof(hub)); - hub.cntl = &cntl->usb; - hub.portcount = cntl->checkports; - hub.op = &ehci_HubOp; - usb_enumerate(&hub); - return hub.devcount; -} - - -/**************************************************************** - * Setup - ****************************************************************/ - -static void -configure_ehci(void *data) -{ - struct usb_ehci_s *cntl = data; - - // Allocate ram for schedule storage - struct ehci_framelist *fl = memalign_high(sizeof(*fl), sizeof(*fl)); - struct ehci_qh *intr_qh = memalign_high(EHCI_QH_ALIGN, sizeof(*intr_qh)); - struct ehci_qh *async_qh = memalign_high(EHCI_QH_ALIGN, sizeof(*async_qh)); - if (!fl || !intr_qh || !async_qh) { - warn_noalloc(); - goto fail; - } - - // XXX - check for halted? - - // Reset the HC - u32 cmd = readl(&cntl->regs->usbcmd); - writel(&cntl->regs->usbcmd, (cmd & ~(CMD_ASE | CMD_PSE)) | CMD_HCRESET); - u64 end = calc_future_tsc(250); - for (;;) { - cmd = readl(&cntl->regs->usbcmd); - if (!(cmd & CMD_HCRESET)) - break; - if (check_tsc(end)) { - warn_timeout(); - goto fail; - } - yield(); - } - - // Disable interrupts (just to be safe). - writel(&cntl->regs->usbintr, 0); - - // Set schedule to point to primary intr queue head - memset(intr_qh, 0, sizeof(*intr_qh)); - intr_qh->next = EHCI_PTR_TERM; - intr_qh->info2 = (0x01 << QH_SMASK_SHIFT); - intr_qh->token = QTD_STS_HALT; - intr_qh->qtd_next = intr_qh->alt_next = EHCI_PTR_TERM; - int i; - for (i=0; ilinks); i++) - fl->links[i] = (u32)intr_qh | EHCI_PTR_QH; - writel(&cntl->regs->periodiclistbase, (u32)fl); - - // Set async list to point to primary async queue head - memset(async_qh, 0, sizeof(*async_qh)); - async_qh->next = (u32)async_qh | EHCI_PTR_QH; - async_qh->info1 = QH_HEAD; - async_qh->token = QTD_STS_HALT; - async_qh->qtd_next = async_qh->alt_next = EHCI_PTR_TERM; - cntl->async_qh = async_qh; - writel(&cntl->regs->asynclistbase, (u32)async_qh); - - // Enable queues - writel(&cntl->regs->usbcmd, cmd | CMD_ASE | CMD_PSE | CMD_RUN); - - // Set default of high speed for root hub. - writel(&cntl->regs->configflag, 1); - cntl->checkports = readl(&cntl->caps->hcsparams) & HCS_N_PORTS_MASK; - - // Find devices - int count = check_ehci_ports(cntl); - free_pipe(cntl->usb.defaultpipe); - if (count) - // Success - return; - - // No devices found - shutdown and free controller. - writel(&cntl->regs->usbcmd, cmd & ~CMD_RUN); - msleep(4); // 2ms to stop reading memory - XXX -fail: - free(fl); - free(intr_qh); - free(async_qh); - free(cntl); -} - -int -ehci_init(u16 bdf, int busid, int compbdf) -{ - if (! CONFIG_USB_EHCI) - return -1; - - u32 baseaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0); - struct ehci_caps *caps = (void*)(baseaddr & PCI_BASE_ADDRESS_MEM_MASK); - u32 hcc_params = readl(&caps->hccparams); - if (hcc_params & HCC_64BIT_ADDR) { - dprintf(1, "No support for 64bit EHCI\n"); - return -1; - } - - struct usb_ehci_s *cntl = malloc_tmphigh(sizeof(*cntl)); - memset(cntl, 0, sizeof(*cntl)); - cntl->usb.busid = busid; - cntl->usb.type = USB_TYPE_EHCI; - cntl->caps = caps; - cntl->regs = (void*)caps + readb(&caps->caplength); - - dprintf(1, "EHCI init on dev %02x:%02x.%x (regs=%p)\n" - , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf) - , pci_bdf_to_fn(bdf), cntl->regs); - - pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); - - // XXX - check for and disable SMM control? - - // Find companion controllers. - int count = 0; - int max = pci_to_bdf(pci_bdf_to_bus(bdf) + 1, 0, 0); - for (;;) { - if (compbdf < 0 || compbdf >= bdf) - break; - u32 code = pci_config_readl(compbdf, PCI_CLASS_REVISION) >> 8; - if (code == PCI_CLASS_SERIAL_USB_UHCI) { - cntl->companion[count].bdf = compbdf; - cntl->companion[count].type = USB_TYPE_UHCI; - count++; - } else if (code == PCI_CLASS_SERIAL_USB_OHCI) { - cntl->companion[count].bdf = compbdf; - cntl->companion[count].type = USB_TYPE_OHCI; - count++; - } - compbdf = pci_next(compbdf+1, &max); - } - - run_thread(configure_ehci, cntl); - return 0; -} - - -/**************************************************************** - * End point communication - ****************************************************************/ - -static int -ehci_wait_qh(struct usb_ehci_s *cntl, struct ehci_qh *qh) -{ - // XXX - 500ms just a guess - u64 end = calc_future_tsc(500); - for (;;) { - if (qh->qtd_next & EHCI_PTR_TERM) - // XXX - confirm - return 0; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - yield(); - } -} - -// Wait for next USB async frame to start - for ensuring safe memory release. -static void -ehci_waittick(struct usb_ehci_s *cntl) -{ - if (MODE16) { - msleep(10); - return; - } - // Wait for access to "doorbell" - barrier(); - u32 cmd, sts; - u64 end = calc_future_tsc(100); - for (;;) { - sts = readl(&cntl->regs->usbsts); - if (!(sts & STS_IAA)) { - cmd = readl(&cntl->regs->usbcmd); - if (!(cmd & CMD_IAAD)) - break; - } - if (check_tsc(end)) { - warn_timeout(); - return; - } - yield(); - } - // Ring "doorbell" - writel(&cntl->regs->usbcmd, cmd | CMD_IAAD); - // Wait for completion - for (;;) { - sts = readl(&cntl->regs->usbsts); - if (sts & STS_IAA) - break; - if (check_tsc(end)) { - warn_timeout(); - return; - } - yield(); - } - // Ack completion - writel(&cntl->regs->usbsts, STS_IAA); -} - -struct ehci_pipe { - struct ehci_qh qh; - struct ehci_qtd *next_td, *tds; - void *data; - struct usb_pipe pipe; -}; - -void -ehci_free_pipe(struct usb_pipe *p) -{ - if (! CONFIG_USB_EHCI) - return; - dprintf(7, "ehci_free_pipe %p\n", p); - struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe); - struct usb_ehci_s *cntl = container_of( - pipe->pipe.cntl, struct usb_ehci_s, usb); - - struct ehci_qh *start = cntl->async_qh; - struct ehci_qh *pos = start; - for (;;) { - struct ehci_qh *next = (void*)(pos->next & ~EHCI_PTR_BITS); - if (next == start) { - // Not found?! Exit without freeing. - warn_internalerror(); - return; - } - if (next == &pipe->qh) { - pos->next = next->next; - ehci_waittick(cntl); - free(pipe); - return; - } - pos = next; - } -} - -struct usb_pipe * -ehci_alloc_control_pipe(struct usb_pipe *dummy) -{ - if (! CONFIG_USB_EHCI) - return NULL; - struct usb_ehci_s *cntl = container_of( - dummy->cntl, struct usb_ehci_s, usb); - dprintf(7, "ehci_alloc_control_pipe %p\n", &cntl->usb); - - // Allocate a queue head. - struct ehci_pipe *pipe = memalign_tmphigh(EHCI_QH_ALIGN, sizeof(*pipe)); - if (!pipe) { - warn_noalloc(); - return NULL; - } - memset(pipe, 0, sizeof(*pipe)); - memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe)); - pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM; - pipe->qh.token = QTD_STS_HALT; - - // Add queue head to controller list. - struct ehci_qh *async_qh = cntl->async_qh; - pipe->qh.next = async_qh->next; - barrier(); - async_qh->next = (u32)&pipe->qh | EHCI_PTR_QH; - return &pipe->pipe; -} - -static int -fillTDbuffer(struct ehci_qtd *td, u16 maxpacket, const void *buf, int bytes) -{ - u32 dest = (u32)buf; - u32 *pos = td->buf; - while (bytes) { - if (pos >= &td->buf[ARRAY_SIZE(td->buf)]) - // More data than can transfer in a single qtd - only use - // full packets to prevent a babble error. - return ALIGN_DOWN(dest - (u32)buf, maxpacket); - u32 count = bytes; - u32 max = 0x1000 - (dest & 0xfff); - if (count > max) - count = max; - *pos = dest; - bytes -= count; - dest += count; - pos++; - } - return dest - (u32)buf; -} - -int -ehci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize - , void *data, int datasize) -{ - ASSERT32FLAT(); - if (! CONFIG_USB_EHCI) - return -1; - dprintf(5, "ehci_control %p\n", p); - if (datasize > 4*4096 || cmdsize > 4*4096) { - // XXX - should support larger sizes. - warn_noalloc(); - return -1; - } - struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe); - struct usb_ehci_s *cntl = container_of( - pipe->pipe.cntl, struct usb_ehci_s, usb); - - u16 maxpacket = pipe->pipe.maxpacket; - int speed = pipe->pipe.speed; - - // Setup fields in qh - pipe->qh.info1 = ( - (1 << QH_MULT_SHIFT) | (speed != USB_HIGHSPEED ? QH_CONTROL : 0) - | (maxpacket << QH_MAXPACKET_SHIFT) - | QH_TOGGLECONTROL - | (speed << QH_SPEED_SHIFT) - | (pipe->pipe.ep << QH_EP_SHIFT) - | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT)); - pipe->qh.info2 = ((1 << QH_MULT_SHIFT) - | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT) - | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT)); - - // Setup transfer descriptors - struct ehci_qtd *tds = memalign_tmphigh(EHCI_QTD_ALIGN, sizeof(*tds) * 3); - if (!tds) { - warn_noalloc(); - return -1; - } - memset(tds, 0, sizeof(*tds) * 3); - struct ehci_qtd *td = tds; - - td->qtd_next = (u32)&td[1]; - td->alt_next = EHCI_PTR_TERM; - td->token = (ehci_explen(cmdsize) | QTD_STS_ACTIVE - | QTD_PID_SETUP | ehci_maxerr(3)); - fillTDbuffer(td, maxpacket, cmd, cmdsize); - td++; - - if (datasize) { - td->qtd_next = (u32)&td[1]; - td->alt_next = EHCI_PTR_TERM; - td->token = (QTD_TOGGLE | ehci_explen(datasize) | QTD_STS_ACTIVE - | (dir ? QTD_PID_IN : QTD_PID_OUT) | ehci_maxerr(3)); - fillTDbuffer(td, maxpacket, data, datasize); - td++; - } - - td->qtd_next = EHCI_PTR_TERM; - td->alt_next = EHCI_PTR_TERM; - td->token = (QTD_TOGGLE | QTD_STS_ACTIVE - | (dir ? QTD_PID_OUT : QTD_PID_IN) | ehci_maxerr(3)); - - // Transfer data - barrier(); - pipe->qh.qtd_next = (u32)tds; - barrier(); - pipe->qh.token = 0; - int ret = ehci_wait_qh(cntl, &pipe->qh); - pipe->qh.token = QTD_STS_HALT; - if (ret) { - pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM; - // XXX - halt qh? - ehci_waittick(cntl); - } - free(tds); - return ret; -} - -struct usb_pipe * -ehci_alloc_bulk_pipe(struct usb_pipe *dummy) -{ - // XXX - this func is same as alloc_control except for malloc_low - if (! CONFIG_USB_EHCI) - return NULL; - struct usb_ehci_s *cntl = container_of( - dummy->cntl, struct usb_ehci_s, usb); - dprintf(7, "ehci_alloc_bulk_pipe %p\n", &cntl->usb); - - // Allocate a queue head. - struct ehci_pipe *pipe = memalign_low(EHCI_QH_ALIGN, sizeof(*pipe)); - if (!pipe) { - warn_noalloc(); - return NULL; - } - memset(pipe, 0, sizeof(*pipe)); - memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe)); - pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM; - pipe->qh.token = QTD_STS_HALT; - - // Add queue head to controller list. - struct ehci_qh *async_qh = cntl->async_qh; - pipe->qh.next = async_qh->next; - barrier(); - async_qh->next = (u32)&pipe->qh | EHCI_PTR_QH; - return &pipe->pipe; -} - -static int -ehci_wait_td(struct ehci_qtd *td) -{ - u64 end = calc_future_tsc(5000); // XXX - lookup real time. - u32 status; - for (;;) { - status = td->token; - if (!(status & QTD_STS_ACTIVE)) - break; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - yield(); - } - if (status & QTD_STS_HALT) { - dprintf(1, "ehci_wait_td error - status=%x\n", status); - return -2; - } - return 0; -} - -#define STACKQTDS 4 - -int -ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) -{ - if (! CONFIG_USB_EHCI) - return -1; - struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe); - dprintf(7, "ehci_send_bulk qh=%p dir=%d data=%p size=%d\n" - , &pipe->qh, dir, data, datasize); - - // Allocate 4 tds on stack (16byte aligned) - u8 tdsbuf[sizeof(struct ehci_qtd) * STACKQTDS + EHCI_QTD_ALIGN - 1]; - struct ehci_qtd *tds = (void*)ALIGN((u32)tdsbuf, EHCI_QTD_ALIGN); - memset(tds, 0, sizeof(*tds) * STACKQTDS); - - // Setup fields in qh - u16 maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - SET_FLATPTR(pipe->qh.info1 - , ((1 << QH_MULT_SHIFT) - | (maxpacket << QH_MAXPACKET_SHIFT) - | (GET_FLATPTR(pipe->pipe.speed) << QH_SPEED_SHIFT) - | (GET_FLATPTR(pipe->pipe.ep) << QH_EP_SHIFT) - | (GET_FLATPTR(pipe->pipe.devaddr) << QH_DEVADDR_SHIFT))); - SET_FLATPTR(pipe->qh.info2 - , ((1 << QH_MULT_SHIFT) - | (GET_FLATPTR(pipe->pipe.tt_port) << QH_HUBPORT_SHIFT) - | (GET_FLATPTR(pipe->pipe.tt_devaddr) << QH_HUBADDR_SHIFT))); - barrier(); - SET_FLATPTR(pipe->qh.qtd_next, (u32)MAKE_FLATPTR(GET_SEG(SS), tds)); - barrier(); - SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE); - - int tdpos = 0; - while (datasize) { - struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS]; - int ret = ehci_wait_td(td); - if (ret) - goto fail; - - struct ehci_qtd *nexttd_fl = MAKE_FLATPTR(GET_SEG(SS) - , &tds[tdpos % STACKQTDS]); - - int transfer = fillTDbuffer(td, maxpacket, data, datasize); - td->qtd_next = (transfer==datasize ? EHCI_PTR_TERM : (u32)nexttd_fl); - td->alt_next = EHCI_PTR_TERM; - barrier(); - td->token = (ehci_explen(transfer) | QTD_STS_ACTIVE - | (dir ? QTD_PID_IN : QTD_PID_OUT) | ehci_maxerr(3)); - - data += transfer; - datasize -= transfer; - } - int i; - for (i=0; iqh.qtd_next, EHCI_PTR_TERM); - SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM); - // XXX - halt qh? - struct usb_ehci_s *cntl = container_of( - GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb); - ehci_waittick(cntl); - return -1; -} - -struct usb_pipe * -ehci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp) -{ - if (! CONFIG_USB_EHCI) - return NULL; - struct usb_ehci_s *cntl = container_of( - dummy->cntl, struct usb_ehci_s, usb); - dprintf(7, "ehci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); - - if (frameexp > 10) - frameexp = 10; - int maxpacket = dummy->maxpacket; - // Determine number of entries needed for 2 timer ticks. - int ms = 1<pipe, dummy, sizeof(pipe->pipe)); - pipe->next_td = pipe->tds = tds; - pipe->data = data; - - pipe->qh.info1 = ( - (1 << QH_MULT_SHIFT) - | (maxpacket << QH_MAXPACKET_SHIFT) - | (pipe->pipe.speed << QH_SPEED_SHIFT) - | (pipe->pipe.ep << QH_EP_SHIFT) - | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT)); - pipe->qh.info2 = ((1 << QH_MULT_SHIFT) - | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT) - | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT) - | (0x01 << QH_SMASK_SHIFT) - | (0x1c << QH_CMASK_SHIFT)); - pipe->qh.qtd_next = (u32)tds; - - int i; - for (i=0; iqtd_next = (i==count-1 ? (u32)tds : (u32)&td[1]); - td->alt_next = EHCI_PTR_TERM; - td->token = (ehci_explen(maxpacket) | QTD_STS_ACTIVE - | QTD_PID_IN | ehci_maxerr(3)); - td->buf[0] = (u32)data + maxpacket * i; - } - - // Add to interrupt schedule. - struct ehci_framelist *fl = (void*)readl(&cntl->regs->periodiclistbase); - if (frameexp == 0) { - // Add to existing interrupt entry. - struct ehci_qh *intr_qh = (void*)(fl->links[0] & ~EHCI_PTR_BITS); - pipe->qh.next = intr_qh->next; - barrier(); - intr_qh->next = (u32)&pipe->qh | EHCI_PTR_QH; - } else { - int startpos = 1<<(frameexp-1); - pipe->qh.next = fl->links[startpos]; - barrier(); - for (i=startpos; ilinks); i+=ms) - fl->links[i] = (u32)&pipe->qh | EHCI_PTR_QH; - } - - return &pipe->pipe; -fail: - free(pipe); - free(tds); - free(data); - return NULL; -} - -int -ehci_poll_intr(struct usb_pipe *p, void *data) -{ - ASSERT16(); - if (! CONFIG_USB_EHCI) - return -1; - struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe); - struct ehci_qtd *td = GET_FLATPTR(pipe->next_td); - u32 token = GET_FLATPTR(td->token); - if (token & QTD_STS_ACTIVE) - // No intrs found. - return -1; - // XXX - check for errors. - - // Copy data. - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - int pos = td - GET_FLATPTR(pipe->tds); - void *tddata = GET_FLATPTR(pipe->data) + maxpacket * pos; - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(tddata), (void*)FLATPTR_TO_OFFSET(tddata) - , maxpacket); - - // Reenable this td. - struct ehci_qtd *next = (void*)(GET_FLATPTR(td->qtd_next) & ~EHCI_PTR_BITS); - SET_FLATPTR(pipe->next_td, next); - SET_FLATPTR(td->buf[0], (u32)tddata); - barrier(); - SET_FLATPTR(td->token, (ehci_explen(maxpacket) | QTD_STS_ACTIVE - | QTD_PID_IN | ehci_maxerr(3))); - - return 0; -} diff --git a/roms/seabios/src/usb-ehci.h b/roms/seabios/src/usb-ehci.h deleted file mode 100644 index bb8df52..0000000 --- a/roms/seabios/src/usb-ehci.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef __USB_EHCI_H -#define __USB_EHCI_H - -// usb-ehci.c -int ehci_init(u16 bdf, int busid, int compbdf); -struct usb_pipe; -void ehci_free_pipe(struct usb_pipe *p); -struct usb_pipe *ehci_alloc_control_pipe(struct usb_pipe *dummy); -int ehci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize - , void *data, int datasize); -struct usb_pipe *ehci_alloc_bulk_pipe(struct usb_pipe *dummy); -int ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize); -struct usb_pipe *ehci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp); -int ehci_poll_intr(struct usb_pipe *p, void *data); - - -/**************************************************************** - * ehci structs and flags - ****************************************************************/ - -struct ehci_caps { - u8 caplength; - u8 reserved_01; - u16 hciversion; - u32 hcsparams; - u32 hccparams; - u64 portroute; -} PACKED; - -#define HCC_64BIT_ADDR 1 - -#define HCS_N_PORTS_MASK 0xf - -struct ehci_regs { - u32 usbcmd; - u32 usbsts; - u32 usbintr; - u32 frindex; - u32 ctrldssegment; - u32 periodiclistbase; - u32 asynclistbase; - u32 reserved[9]; - u32 configflag; - u32 portsc[0]; -} PACKED; - -#define CMD_PARK (1<<11) -#define CMD_PARK_CNT(c) (((c)>>8)&3) -#define CMD_LRESET (1<<7) -#define CMD_IAAD (1<<6) -#define CMD_ASE (1<<5) -#define CMD_PSE (1<<4) -#define CMD_HCRESET (1<<1) -#define CMD_RUN (1<<0) - -#define STS_ASS (1<<15) -#define STS_PSS (1<<14) -#define STS_RECL (1<<13) -#define STS_HALT (1<<12) -#define STS_IAA (1<<5) -#define STS_FATAL (1<<4) -#define STS_FLR (1<<3) -#define STS_PCD (1<<2) -#define STS_ERR (1<<1) -#define STS_INT (1<<0) - -#define FLAG_CF (1<<0) - -#define PORT_WKOC_E (1<<22) -#define PORT_WKDISC_E (1<<21) -#define PORT_WKCONN_E (1<<20) -#define PORT_TEST_PKT (0x4<<16) -#define PORT_LED_OFF (0<<14) -#define PORT_LED_AMBER (1<<14) -#define PORT_LED_GREEN (2<<14) -#define PORT_LED_MASK (3<<14) -#define PORT_OWNER (1<<13) -#define PORT_POWER (1<<12) -#define PORT_LINESTATUS_MASK (3<<10) -#define PORT_LINESTATUS_KSTATE (1<<10) -#define PORT_RESET (1<<8) -#define PORT_SUSPEND (1<<7) -#define PORT_RESUME (1<<6) -#define PORT_OCC (1<<5) -#define PORT_OC (1<<4) -#define PORT_PEC (1<<3) -#define PORT_PE (1<<2) -#define PORT_CSC (1<<1) -#define PORT_CONNECT (1<<0) -#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) - - -#define EHCI_QH_ALIGN 64 // Can't span a 4K boundary, so increase to 64 - -struct ehci_qh { - u32 next; - u32 info1; - u32 info2; - u32 current; - - u32 qtd_next; - u32 alt_next; - u32 token; - u32 buf[5]; - // u32 buf_hi[5]; -} PACKED; - -#define QH_CONTROL (1 << 27) -#define QH_MAXPACKET_SHIFT 16 -#define QH_MAXPACKET_MASK (0x7ff << QH_MAXPACKET_SHIFT) -#define QH_HEAD (1 << 15) -#define QH_TOGGLECONTROL (1 << 14) -#define QH_SPEED_SHIFT 12 -#define QH_SPEED_MASK (0x3 << QH_SPEED_SHIFT) -#define QH_EP_SHIFT 8 -#define QH_EP_MASK (0xf << QH_EP_SHIFT) -#define QH_DEVADDR_SHIFT 0 -#define QH_DEVADDR_MASK (0x7f << QH_DEVADDR_SHIFT) - -#define QH_SMASK_SHIFT 0 -#define QH_SMASK_MASK (0xff << QH_SMASK_SHIFT) -#define QH_CMASK_SHIFT 8 -#define QH_CMASK_MASK (0xff << QH_CMASK_SHIFT) -#define QH_HUBADDR_SHIFT 16 -#define QH_HUBADDR_MASK (0x7f << QH_HUBADDR_SHIFT) -#define QH_HUBPORT_SHIFT 23 -#define QH_HUBPORT_MASK (0x7f << QH_HUBPORT_SHIFT) -#define QH_MULT_SHIFT 30 -#define QH_MULT_MASK (0x3 << QH_MULT_SHIFT) - -#define EHCI_PTR_BITS 0x001F -#define EHCI_PTR_TERM 0x0001 -#define EHCI_PTR_QH 0x0002 - - -#define EHCI_QTD_ALIGN 32 - -struct ehci_qtd { - u32 qtd_next; - u32 alt_next; - u32 token; - u32 buf[5]; - //u32 buf_hi[5]; -} PACKED; - -#define QTD_TOGGLE (1 << 31) -#define QTD_LENGTH_SHIFT 16 -#define QTD_LENGTH_MASK (0x7fff << QTD_LENGTH_SHIFT) -#define QTD_CERR_SHIFT 10 -#define QTD_CERR_MASK (0x3 << QTD_CERR_SHIFT) -#define QTD_IOC (1 << 15) -#define QTD_PID_OUT (0x0 << 8) -#define QTD_PID_IN (0x1 << 8) -#define QTD_PID_SETUP (0x2 << 8) -#define QTD_STS_ACTIVE (1 << 7) -#define QTD_STS_HALT (1 << 6) -#define QTD_STS_DBE (1 << 5) -#define QTD_STS_BABBLE (1 << 4) -#define QTD_STS_XACT (1 << 3) -#define QTD_STS_MMF (1 << 2) -#define QTD_STS_STS (1 << 1) -#define QTD_STS_PING (1 << 0) - -#define ehci_explen(len) (((len) << QTD_LENGTH_SHIFT) & QTD_LENGTH_MASK) - -#define ehci_maxerr(err) (((err) << QTD_CERR_SHIFT) & QTD_CERR_MASK) - - -struct ehci_framelist { - u32 links[1024]; -} PACKED; - -#endif // usb-ehci.h diff --git a/roms/seabios/src/usb-hid.c b/roms/seabios/src/usb-hid.c deleted file mode 100644 index b88d684..0000000 --- a/roms/seabios/src/usb-hid.c +++ /dev/null @@ -1,427 +0,0 @@ -// Code for handling USB Human Interface Devices (HID). -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "usb-hid.h" // usb_keyboard_setup -#include "config.h" // CONFIG_* -#include "usb.h" // usb_ctrlrequest -#include "biosvar.h" // GET_GLOBAL -#include "ps2port.h" // ATKBD_CMD_GETID - -struct usb_pipe *keyboard_pipe VAR16VISIBLE; -struct usb_pipe *mouse_pipe VAR16VISIBLE; - - -/**************************************************************** - * Setup - ****************************************************************/ - -// Send USB HID protocol message. -static int -set_protocol(struct usb_pipe *pipe, u16 val) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; - req.bRequest = HID_REQ_SET_PROTOCOL; - req.wValue = val; - req.wIndex = 0; - req.wLength = 0; - return send_default_control(pipe, &req, NULL); -} - -// Send USB HID SetIdle request. -static int -set_idle(struct usb_pipe *pipe, int ms) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; - req.bRequest = HID_REQ_SET_IDLE; - req.wValue = (ms/4)<<8; - req.wIndex = 0; - req.wLength = 0; - return send_default_control(pipe, &req, NULL); -} - -#define KEYREPEATWAITMS 500 -#define KEYREPEATMS 33 - -static int -usb_kbd_init(struct usb_pipe *pipe, struct usb_endpoint_descriptor *epdesc) -{ - if (! CONFIG_USB_KEYBOARD) - return -1; - if (keyboard_pipe) - // XXX - this enables the first found keyboard (could be random) - return -1; - - if (epdesc->wMaxPacketSize != 8) - return -1; - - // Enable "boot" protocol. - int ret = set_protocol(pipe, 0); - if (ret) - return -1; - // Periodically send reports to enable key repeat. - ret = set_idle(pipe, KEYREPEATMS); - if (ret) - return -1; - - keyboard_pipe = alloc_intr_pipe(pipe, epdesc); - if (!keyboard_pipe) - return -1; - - dprintf(1, "USB keyboard initialized\n"); - return 0; -} - -static int -usb_mouse_init(struct usb_pipe *pipe, struct usb_endpoint_descriptor *epdesc) -{ - if (! CONFIG_USB_MOUSE) - return -1; - if (mouse_pipe) - // XXX - this enables the first found mouse (could be random) - return -1; - - if (epdesc->wMaxPacketSize < 3 || epdesc->wMaxPacketSize > 8) - return -1; - - // Enable "boot" protocol. - int ret = set_protocol(pipe, 0); - if (ret) - return -1; - - mouse_pipe = alloc_intr_pipe(pipe, epdesc); - if (!mouse_pipe) - return -1; - - dprintf(1, "USB mouse initialized\n"); - return 0; -} - -// Initialize a found USB HID device (if applicable). -int -usb_hid_init(struct usb_pipe *pipe - , struct usb_interface_descriptor *iface, int imax) -{ - if (! CONFIG_USB_KEYBOARD || ! CONFIG_USB_MOUSE) - return -1; - dprintf(2, "usb_hid_init %p\n", pipe); - - if (iface->bInterfaceSubClass != USB_INTERFACE_SUBCLASS_BOOT) - // Doesn't support boot protocol. - return -1; - - // Find intr in endpoint. - struct usb_endpoint_descriptor *epdesc = findEndPointDesc( - iface, imax, USB_ENDPOINT_XFER_INT, USB_DIR_IN); - if (!epdesc) { - dprintf(1, "No usb hid intr in?\n"); - return -1; - } - - if (iface->bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD) - return usb_kbd_init(pipe, epdesc); - if (iface->bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) - return usb_mouse_init(pipe, epdesc); - return -1; -} - -void -usb_hid_setup(void) -{ - if (CONFIG_USB_KEYBOARD) - keyboard_pipe = NULL; - if (CONFIG_USB_MOUSE) - mouse_pipe = NULL; -} - - -/**************************************************************** - * Keyboard events - ****************************************************************/ - -// Mapping from USB key id to ps2 key sequence. -static u16 KeyToScanCode[] VAR16 = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x001e, 0x0030, 0x002e, 0x0020, - 0x0012, 0x0021, 0x0022, 0x0023, 0x0017, 0x0024, 0x0025, 0x0026, - 0x0032, 0x0031, 0x0018, 0x0019, 0x0010, 0x0013, 0x001f, 0x0014, - 0x0016, 0x002f, 0x0011, 0x002d, 0x0015, 0x002c, 0x0002, 0x0003, - 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, - 0x001c, 0x0001, 0x000e, 0x000f, 0x0039, 0x000c, 0x000d, 0x001a, - 0x001b, 0x002b, 0x0000, 0x0027, 0x0028, 0x0029, 0x0033, 0x0034, - 0x0035, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, - 0x0041, 0x0042, 0x0043, 0x0044, 0x0057, 0x0058, 0xe037, 0x0046, - 0xe11d, 0xe052, 0xe047, 0xe049, 0xe053, 0xe04f, 0xe051, 0xe04d, - 0xe04b, 0xe050, 0xe048, 0x0045, 0xe035, 0x0037, 0x004a, 0x004e, - 0xe01c, 0x004f, 0x0050, 0x0051, 0x004b, 0x004c, 0x004d, 0x0047, - 0x0048, 0x0049, 0x0052, 0x0053 -}; - -// Mapping from USB modifier id to ps2 key sequence. -static u16 ModifierToScanCode[] VAR16 = { - //lcntl, lshift, lalt, lgui, rcntl, rshift, ralt, rgui - 0x001d, 0x002a, 0x0038, 0xe05b, 0xe01d, 0x0036, 0xe038, 0xe05c -}; - -#define RELEASEBIT 0x80 - -// Format of USB keyboard event data -struct keyevent { - u8 modifiers; - u8 reserved; - u8 keys[6]; -}; - -// Translate data from KeyToScanCode[] to calls to process_key(). -static void -prockeys(u16 keys) -{ - if (keys > 0xff) { - u8 key = keys>>8; - if (key == 0xe1) { - // Pause key - process_key(0xe1); - process_key(0x1d | (keys & RELEASEBIT)); - process_key(0x45 | (keys & RELEASEBIT)); - return; - } - process_key(key); - } - process_key(keys); -} - -// Handle a USB key press/release event. -static void -procscankey(u8 key, u8 flags) -{ - if (key >= ARRAY_SIZE(KeyToScanCode)) - return; - u16 keys = GET_GLOBAL(KeyToScanCode[key]); - if (keys) - prockeys(keys | flags); -} - -// Handle a USB modifier press/release event. -static void -procmodkey(u8 mods, u8 flags) -{ - int i; - for (i=0; mods; i++) - if (mods & (1<modifiers, data->keys[0]); - - // Load old keys. - u16 ebda_seg = get_ebda_seg(); - struct usbkeyinfo old; - old.data = GET_EBDA2(ebda_seg, usbkey_last.data); - - // Check for keys no longer pressed. - int addpos = 0; - int i; - for (i=0; i=ARRAY_SIZE(data->keys)) { - // Key released. - procscankey(key, RELEASEBIT); - if (i+1 >= ARRAY_SIZE(old.keys) || !old.keys[i+1]) - // Last pressed key released - disable repeat. - old.repeatcount = 0xff; - break; - } - if (data->keys[j] == key) { - // Key still pressed. - data->keys[j] = 0; - old.keys[addpos++] = key; - break; - } - } - } - procmodkey(old.modifiers & ~data->modifiers, RELEASEBIT); - - // Process new keys - procmodkey(data->modifiers & ~old.modifiers, 0); - old.modifiers = data->modifiers; - for (i=0; ikeys); i++) { - u8 key = data->keys[i]; - if (!key) - continue; - // New key pressed. - procscankey(key, 0); - old.keys[addpos++] = key; - old.repeatcount = KEYREPEATWAITMS / KEYREPEATMS + 1; - } - if (addpos < ARRAY_SIZE(old.keys)) - old.keys[addpos] = 0; - - // Check for key repeat event. - if (addpos) { - if (!old.repeatcount) - procscankey(old.keys[addpos-1], 0); - else if (old.repeatcount != 0xff) - old.repeatcount--; - } - - // Update old keys - SET_EBDA2(ebda_seg, usbkey_last.data, old.data); -} - -// Check if a USB keyboard event is pending and process it if so. -static void -usb_check_key(void) -{ - if (! CONFIG_USB_KEYBOARD) - return; - struct usb_pipe *pipe = GET_GLOBAL(keyboard_pipe); - if (!pipe) - return; - - for (;;) { - struct keyevent data; - int ret = usb_poll_intr(pipe, &data); - if (ret) - break; - handle_key(&data); - } -} - -// Test if USB keyboard is active. -inline int -usb_kbd_active(void) -{ - if (! CONFIG_USB_KEYBOARD) - return 0; - return GET_GLOBAL(keyboard_pipe) != NULL; -} - -// Handle a ps2 style keyboard command. -inline int -usb_kbd_command(int command, u8 *param) -{ - if (! CONFIG_USB_KEYBOARD) - return -1; - dprintf(9, "usb keyboard cmd=%x\n", command); - switch (command) { - case ATKBD_CMD_GETID: - // Return the id of a standard AT keyboard. - param[0] = 0xab; - param[1] = 0x83; - return 0; - default: - return -1; - } -} - - -/**************************************************************** - * Mouse events - ****************************************************************/ - -// Format of USB mouse event data -struct mouseevent { - u8 buttons; - u8 x, y; - u8 reserved[5]; -}; - -// Process USB mouse data. -static void -handle_mouse(struct mouseevent *data) -{ - dprintf(9, "Got mouse b=%x x=%x y=%x\n", data->buttons, data->x, data->y); - - s8 x = data->x, y = -data->y; - u8 flag = ((data->buttons & 0x7) | (1<<3) - | (x & 0x80 ? (1<<4) : 0) | (y & 0x80 ? (1<<5) : 0)); - process_mouse(flag); - process_mouse(x); - process_mouse(y); -} - -// Check if a USB mouse event is pending and process it if so. -static void -usb_check_mouse(void) -{ - if (! CONFIG_USB_MOUSE) - return; - struct usb_pipe *pipe = GET_GLOBAL(mouse_pipe); - if (!pipe) - return; - - for (;;) { - struct mouseevent data; - int ret = usb_poll_intr(pipe, &data); - if (ret) - break; - handle_mouse(&data); - } -} - -// Test if USB mouse is active. -inline int -usb_mouse_active(void) -{ - if (! CONFIG_USB_MOUSE) - return 0; - return GET_GLOBAL(mouse_pipe) != NULL; -} - -// Handle a ps2 style mouse command. -inline int -usb_mouse_command(int command, u8 *param) -{ - if (! CONFIG_USB_MOUSE) - return -1; - dprintf(9, "usb mouse cmd=%x\n", command); - switch (command) { - case PSMOUSE_CMD_ENABLE: - case PSMOUSE_CMD_DISABLE: - case PSMOUSE_CMD_SETSCALE11: - return 0; - case PSMOUSE_CMD_SETSCALE21: - case PSMOUSE_CMD_SETRATE: - case PSMOUSE_CMD_SETRES: - // XXX - return 0; - case PSMOUSE_CMD_RESET_BAT: - case PSMOUSE_CMD_GETID: - // Return the id of a standard AT mouse. - param[0] = 0xaa; - param[1] = 0x00; - return 0; - - case PSMOUSE_CMD_GETINFO: - param[0] = 0x00; - param[1] = 4; - param[2] = 100; - return 0; - - default: - return -1; - } -} - -// Check for USB events pending - called periodically from timer interrupt. -void -usb_check_event(void) -{ - usb_check_key(); - usb_check_mouse(); -} diff --git a/roms/seabios/src/usb-hid.h b/roms/seabios/src/usb-hid.h deleted file mode 100644 index d8199b9..0000000 --- a/roms/seabios/src/usb-hid.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __USB_HID_H -#define __USB_HID_H - -// usb-hid.c -struct usb_interface_descriptor; -struct usb_pipe; -int usb_hid_init(struct usb_pipe *pipe - , struct usb_interface_descriptor *iface, int imax); -void usb_hid_setup(void); -inline int usb_kbd_active(void); -inline int usb_kbd_command(int command, u8 *param); -inline int usb_mouse_active(void); -inline int usb_mouse_command(int command, u8 *param); -void usb_check_event(void); - - -/**************************************************************** - * hid flags - ****************************************************************/ - -#define USB_INTERFACE_SUBCLASS_BOOT 1 -#define USB_INTERFACE_PROTOCOL_KEYBOARD 1 -#define USB_INTERFACE_PROTOCOL_MOUSE 2 - -#define HID_REQ_GET_REPORT 0x01 -#define HID_REQ_GET_IDLE 0x02 -#define HID_REQ_GET_PROTOCOL 0x03 -#define HID_REQ_SET_REPORT 0x09 -#define HID_REQ_SET_IDLE 0x0A -#define HID_REQ_SET_PROTOCOL 0x0B - -#endif // ush-hid.h diff --git a/roms/seabios/src/usb-hub.c b/roms/seabios/src/usb-hub.c deleted file mode 100644 index b2d9ff2..0000000 --- a/roms/seabios/src/usb-hub.c +++ /dev/null @@ -1,185 +0,0 @@ -// Code for handling standard USB hubs. -// -// Copyright (C) 2010 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "config.h" // CONFIG_USB_HUB -#include "usb-hub.h" // struct usb_hub_descriptor -#include "usb.h" // struct usb_s - -static int -get_hub_desc(struct usb_pipe *pipe, struct usb_hub_descriptor *desc) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE; - req.bRequest = USB_REQ_GET_DESCRIPTOR; - req.wValue = USB_DT_HUB<<8; - req.wIndex = 0; - req.wLength = sizeof(*desc); - return send_default_control(pipe, &req, desc); -} - -static int -set_port_feature(struct usbhub_s *hub, int port, int feature) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER; - req.bRequest = USB_REQ_SET_FEATURE; - req.wValue = feature; - req.wIndex = port + 1; - req.wLength = 0; - mutex_lock(&hub->lock); - int ret = send_default_control(hub->pipe, &req, NULL); - mutex_unlock(&hub->lock); - return ret; -} - -static int -clear_port_feature(struct usbhub_s *hub, int port, int feature) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER; - req.bRequest = USB_REQ_CLEAR_FEATURE; - req.wValue = feature; - req.wIndex = port + 1; - req.wLength = 0; - mutex_lock(&hub->lock); - int ret = send_default_control(hub->pipe, &req, NULL); - mutex_unlock(&hub->lock); - return ret; -} - -static int -get_port_status(struct usbhub_s *hub, int port, struct usb_port_status *sts) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER; - req.bRequest = USB_REQ_GET_STATUS; - req.wValue = 0; - req.wIndex = port + 1; - req.wLength = sizeof(*sts); - mutex_lock(&hub->lock); - int ret = send_default_control(hub->pipe, &req, sts); - mutex_unlock(&hub->lock); - return ret; -} - -// Check if device attached to port -static int -usb_hub_detect(struct usbhub_s *hub, u32 port) -{ - // Turn on power to port. - int ret = set_port_feature(hub, port, USB_PORT_FEAT_POWER); - if (ret) - goto fail; - - // Wait for port power to stabilize. - msleep(hub->powerwait); - - // Check periodically for a device connect. - struct usb_port_status sts; - u64 end = calc_future_tsc(USB_TIME_SIGATT); - for (;;) { - ret = get_port_status(hub, port, &sts); - if (ret) - goto fail; - if (sts.wPortStatus & USB_PORT_STAT_CONNECTION) - // Device connected. - break; - if (check_tsc(end)) - // No device found. - return -1; - msleep(5); - } - - // XXX - wait USB_TIME_ATTDB time? - - return 0; - -fail: - dprintf(1, "Failure on hub port %d detect\n", port); - return -1; -} - -// Disable port -static void -usb_hub_disconnect(struct usbhub_s *hub, u32 port) -{ - int ret = clear_port_feature(hub, port, USB_PORT_FEAT_ENABLE); - if (ret) - dprintf(1, "Failure on hub port %d disconnect\n", port); -} - -// Reset device on port -static int -usb_hub_reset(struct usbhub_s *hub, u32 port) -{ - int ret = set_port_feature(hub, port, USB_PORT_FEAT_RESET); - if (ret) - goto fail; - - // Wait for reset to complete. - struct usb_port_status sts; - u64 end = calc_future_tsc(USB_TIME_DRST * 2); - for (;;) { - ret = get_port_status(hub, port, &sts); - if (ret) - goto fail; - if (!(sts.wPortStatus & USB_PORT_STAT_RESET)) - break; - if (check_tsc(end)) { - warn_timeout(); - goto fail; - } - msleep(5); - } - - // Reset complete. - if (!(sts.wPortStatus & USB_PORT_STAT_CONNECTION)) - // Device no longer present - return -1; - - return ((sts.wPortStatus & USB_PORT_STAT_SPEED_MASK) - >> USB_PORT_STAT_SPEED_SHIFT); - -fail: - dprintf(1, "Failure on hub port %d reset\n", port); - usb_hub_disconnect(hub, port); - return -1; -} - -static struct usbhub_op_s HubOp = { - .detect = usb_hub_detect, - .reset = usb_hub_reset, - .disconnect = usb_hub_disconnect, -}; - -// Configure a usb hub and then find devices connected to it. -int -usb_hub_init(struct usb_pipe *pipe) -{ - ASSERT32FLAT(); - if (!CONFIG_USB_HUB) - return -1; - - struct usb_hub_descriptor desc; - int ret = get_hub_desc(pipe, &desc); - if (ret) - return ret; - - struct usbhub_s hub; - memset(&hub, 0, sizeof(hub)); - hub.pipe = pipe; - hub.cntl = pipe->cntl; - hub.powerwait = desc.bPwrOn2PwrGood * 2; - hub.portcount = desc.bNbrPorts; - hub.op = &HubOp; - usb_enumerate(&hub); - - dprintf(1, "Initialized USB HUB (%d ports used)\n", hub.devcount); - if (hub.devcount) - return 0; - return -1; -} diff --git a/roms/seabios/src/usb-hub.h b/roms/seabios/src/usb-hub.h deleted file mode 100644 index 7672028..0000000 --- a/roms/seabios/src/usb-hub.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __USB_HUB_H -#define __USB_HUB_H - -// usb-hub.c -struct usb_pipe; -int usb_hub_init(struct usb_pipe *pipe); - - -/**************************************************************** - * hub flags - ****************************************************************/ - -#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) - -struct usb_hub_descriptor { - u8 bDescLength; - u8 bDescriptorType; - u8 bNbrPorts; - u16 wHubCharacteristics; - u8 bPwrOn2PwrGood; - u8 bHubContrCurrent; - // Variable length fields for DeviceRemovable[], PortPwrCtrlMask[] follow. -} PACKED; - -#define USB_PORT_FEAT_CONNECTION 0 -#define USB_PORT_FEAT_ENABLE 1 -#define USB_PORT_FEAT_SUSPEND 2 -#define USB_PORT_FEAT_OVER_CURRENT 3 -#define USB_PORT_FEAT_RESET 4 -#define USB_PORT_FEAT_POWER 8 -#define USB_PORT_FEAT_LOWSPEED 9 -#define USB_PORT_FEAT_C_CONNECTION 16 -#define USB_PORT_FEAT_C_ENABLE 17 -#define USB_PORT_FEAT_C_SUSPEND 18 -#define USB_PORT_FEAT_C_OVER_CURRENT 19 -#define USB_PORT_FEAT_C_RESET 20 -#define USB_PORT_FEAT_TEST 21 -#define USB_PORT_FEAT_INDICATOR 22 -#define USB_PORT_FEAT_C_PORT_L1 23 - -struct usb_port_status { - u16 wPortStatus; - u16 wPortChange; -} PACKED; - -#define USB_PORT_STAT_CONNECTION 0x0001 -#define USB_PORT_STAT_ENABLE 0x0002 -#define USB_PORT_STAT_SUSPEND 0x0004 -#define USB_PORT_STAT_OVERCURRENT 0x0008 -#define USB_PORT_STAT_RESET 0x0010 -#define USB_PORT_STAT_L1 0x0020 -#define USB_PORT_STAT_POWER 0x0100 -#define USB_PORT_STAT_SPEED_SHIFT 9 -#define USB_PORT_STAT_SPEED_MASK (0x3 << USB_PORT_STAT_SPEED_SHIFT) -#define USB_PORT_STAT_LOW_SPEED 0x0200 -#define USB_PORT_STAT_HIGH_SPEED 0x0400 -#define USB_PORT_STAT_TEST 0x0800 -#define USB_PORT_STAT_INDICATOR 0x1000 - -#endif // ush-hid.h diff --git a/roms/seabios/src/usb-msc.c b/roms/seabios/src/usb-msc.c deleted file mode 100644 index 968cae3..0000000 --- a/roms/seabios/src/usb-msc.c +++ /dev/null @@ -1,252 +0,0 @@ -// Code for handling USB Mass Storage Controller devices. -// -// Copyright (C) 2010 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "config.h" // CONFIG_USB_MSC -#include "usb-msc.h" // usb_msc_init -#include "usb.h" // struct usb_s -#include "biosvar.h" // GET_GLOBAL -#include "blockcmd.h" // cdb_read -#include "disk.h" // DTYPE_USB -#include "boot.h" // add_bcv_internal - -struct usbdrive_s { - struct drive_s drive; - struct usb_pipe *bulkin, *bulkout; -}; - - -/**************************************************************** - * Bulk-only drive command processing - ****************************************************************/ - -#define USB_CDB_SIZE 12 - -#define CBW_SIGNATURE 0x43425355 // USBC - -struct cbw_s { - u32 dCBWSignature; - u32 dCBWTag; - u32 dCBWDataTransferLength; - u8 bmCBWFlags; - u8 bCBWLUN; - u8 bCBWCBLength; - u8 CBWCB[16]; -} PACKED; - -#define CSW_SIGNATURE 0x53425355 // USBS - -struct csw_s { - u32 dCSWSignature; - u32 dCSWTag; - u32 dCSWDataResidue; - u8 bCSWStatus; -} PACKED; - -// Low-level usb command transmit function. -int -usb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize) -{ - dprintf(16, "usb_cmd_data id=%p write=%d count=%d bs=%d buf=%p\n" - , op->drive_g, 0, op->count, blocksize, op->buf_fl); - struct usbdrive_s *udrive_g = container_of( - op->drive_g, struct usbdrive_s, drive); - struct usb_pipe *bulkin = GET_GLOBAL(udrive_g->bulkin); - struct usb_pipe *bulkout = GET_GLOBAL(udrive_g->bulkout); - - // Setup command block wrapper. - u32 bytes = blocksize * op->count; - struct cbw_s cbw; - memset(&cbw, 0, sizeof(cbw)); - cbw.dCBWSignature = CBW_SIGNATURE; - cbw.dCBWTag = 999; // XXX - cbw.dCBWDataTransferLength = bytes; - cbw.bmCBWFlags = USB_DIR_IN; // XXX - cbw.bCBWLUN = 0; // XXX - cbw.bCBWCBLength = USB_CDB_SIZE; - memcpy(cbw.CBWCB, cdbcmd, USB_CDB_SIZE); - - // Transfer cbw to device. - int ret = usb_send_bulk(bulkout, USB_DIR_OUT - , MAKE_FLATPTR(GET_SEG(SS), &cbw), sizeof(cbw)); - if (ret) - goto fail; - - // Transfer data from device. - ret = usb_send_bulk(bulkin, USB_DIR_IN, op->buf_fl, bytes); - if (ret) - goto fail; - - // Transfer csw info. - struct csw_s csw; - ret = usb_send_bulk(bulkin, USB_DIR_IN - , MAKE_FLATPTR(GET_SEG(SS), &csw), sizeof(csw)); - if (ret) - goto fail; - - if (!csw.bCSWStatus) - return DISK_RET_SUCCESS; - if (csw.bCSWStatus == 2) - goto fail; - - op->count -= csw.dCSWDataResidue / blocksize; - return DISK_RET_EBADTRACK; - -fail: - // XXX - reset connection - dprintf(1, "USB transmission failed\n"); - op->count = 0; - return DISK_RET_EBADTRACK; -} - - -/**************************************************************** - * Drive ops - ****************************************************************/ - -// 16bit command demuxer for ATAPI cdroms. -int -process_usb_op(struct disk_op_s *op) -{ - if (!CONFIG_USB_MSC) - return 0; - switch (op->command) { - case CMD_READ: - return cdb_read(op); - case CMD_FORMAT: - case CMD_WRITE: - return DISK_RET_EWRITEPROTECT; - case CMD_RESET: - case CMD_ISREADY: - case CMD_VERIFY: - case CMD_SEEK: - return DISK_RET_SUCCESS; - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} - - -/**************************************************************** - * Setup - ****************************************************************/ - -static int -setup_drive_cdrom(struct disk_op_s *op) -{ - op->drive_g->blksize = CDROM_SECTOR_SIZE; - op->drive_g->sectors = (u64)-1; - map_cd_drive(op->drive_g); - return 0; -} - -static int -setup_drive_hd(struct disk_op_s *op) -{ - struct cdbres_read_capacity info; - int ret = cdb_read_capacity(op, &info); - if (ret) - return ret; - // XXX - retry for some timeout? - - u32 blksize = ntohl(info.blksize), sectors = ntohl(info.sectors); - if (blksize != DISK_SECTOR_SIZE) { - if (blksize == CDROM_SECTOR_SIZE) - return setup_drive_cdrom(op); - dprintf(1, "Unsupported USB MSC block size %d\n", blksize); - return -1; - } - op->drive_g->blksize = blksize; - op->drive_g->sectors = sectors; - dprintf(1, "USB MSC blksize=%d sectors=%d\n", blksize, sectors); - - // Setup disk geometry translation. - setup_translation(op->drive_g); - - // Register with bcv system. - add_bcv_internal(op->drive_g); - - return 0; -} - -// Configure a usb msc device. -int -usb_msc_init(struct usb_pipe *pipe - , struct usb_interface_descriptor *iface, int imax) -{ - if (!CONFIG_USB_MSC) - return -1; - - // Verify right kind of device - if ((iface->bInterfaceSubClass != US_SC_SCSI && - iface->bInterfaceSubClass != US_SC_ATAPI_8070 && - iface->bInterfaceSubClass != US_SC_ATAPI_8020) - || iface->bInterfaceProtocol != US_PR_BULK) { - dprintf(1, "Unsupported MSC USB device (subclass=%02x proto=%02x)\n" - , iface->bInterfaceSubClass, iface->bInterfaceProtocol); - return -1; - } - - // Allocate drive structure. - char *desc = malloc_tmphigh(MAXDESCSIZE); - struct usbdrive_s *udrive_g = malloc_fseg(sizeof(*udrive_g)); - if (!udrive_g || !desc) { - warn_noalloc(); - goto fail; - } - memset(udrive_g, 0, sizeof(*udrive_g)); - udrive_g->drive.type = DTYPE_USB; - - // Find bulk in and bulk out endpoints. - struct usb_endpoint_descriptor *indesc = findEndPointDesc( - iface, imax, USB_ENDPOINT_XFER_BULK, USB_DIR_IN); - struct usb_endpoint_descriptor *outdesc = findEndPointDesc( - iface, imax, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT); - if (!indesc || !outdesc) - goto fail; - udrive_g->bulkin = alloc_bulk_pipe(pipe, indesc); - udrive_g->bulkout = alloc_bulk_pipe(pipe, outdesc); - if (!udrive_g->bulkin || !udrive_g->bulkout) - goto fail; - - // Validate drive and find block size and sector count. - struct disk_op_s dop; - memset(&dop, 0, sizeof(dop)); - dop.drive_g = &udrive_g->drive; - struct cdbres_inquiry data; - int ret = cdb_get_inquiry(&dop, &data); - if (ret) - goto fail; - char vendor[sizeof(data.vendor)+1], product[sizeof(data.product)+1]; - char rev[sizeof(data.rev)+1]; - int pdt = data.pdt & 0x1f; - int removable = !!(data.removable & 0x80); - dprintf(1, "USB MSC vendor='%s' product='%s' rev='%s'" - " type=%d removable=%d\n" - , strtcpy(vendor, data.vendor, sizeof(vendor)) - , strtcpy(product, data.product, sizeof(product)) - , strtcpy(rev, data.rev, sizeof(rev)) - , pdt, removable); - udrive_g->drive.removable = removable; - - if (pdt == USB_MSC_TYPE_CDROM) - ret = setup_drive_cdrom(&dop); - else - ret = setup_drive_hd(&dop); - if (ret) - goto fail; - - snprintf(desc, MAXDESCSIZE, "USB Drive %s %s %s", vendor, product, rev); - udrive_g->drive.desc = desc; - - return 0; -fail: - dprintf(1, "Unable to configure USB MSC device.\n"); - free(desc); - free(udrive_g); - return -1; -} diff --git a/roms/seabios/src/usb-msc.h b/roms/seabios/src/usb-msc.h deleted file mode 100644 index 71adb20..0000000 --- a/roms/seabios/src/usb-msc.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __USB_MSC_H -#define __USB_MSC_H - -// usb-msc.c -struct disk_op_s; -int usb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); -struct usb_interface_descriptor; -struct usb_pipe; -int usb_msc_init(struct usb_pipe *pipe - , struct usb_interface_descriptor *iface, int imax); -int process_usb_op(struct disk_op_s *op); - - -/**************************************************************** - * MSC flags - ****************************************************************/ - -#define US_SC_ATAPI_8020 0x02 -#define US_SC_ATAPI_8070 0x05 -#define US_SC_SCSI 0x06 - -#define US_PR_BULK 0x50 - -#define USB_MSC_TYPE_DISK 0x00 -#define USB_MSC_TYPE_CDROM 0x05 - -#endif // ush-msc.h diff --git a/roms/seabios/src/usb-ohci.c b/roms/seabios/src/usb-ohci.c deleted file mode 100644 index 7b975d9..0000000 --- a/roms/seabios/src/usb-ohci.c +++ /dev/null @@ -1,516 +0,0 @@ -// Code for handling OHCI USB controllers. -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "pci.h" // pci_bdf_to_bus -#include "config.h" // CONFIG_* -#include "usb-ohci.h" // struct ohci_hcca -#include "pci_regs.h" // PCI_BASE_ADDRESS_0 -#include "usb.h" // struct usb_s -#include "farptr.h" // GET_FLATPTR - -#define FIT (1 << 31) - -struct usb_ohci_s { - struct usb_s usb; - struct ohci_regs *regs; -}; - - -/**************************************************************** - * Root hub - ****************************************************************/ - -// Check if device attached to port -static int -ohci_hub_detect(struct usbhub_s *hub, u32 port) -{ - struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb); - u32 sts = readl(&cntl->regs->roothub_portstatus[port]); - if (!(sts & RH_PS_CCS)) - // No device. - return -1; - - // XXX - need to wait for USB_TIME_ATTDB if just powered up? - - return 0; -} - -// Disable port -static void -ohci_hub_disconnect(struct usbhub_s *hub, u32 port) -{ - struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb); - writel(&cntl->regs->roothub_portstatus[port], RH_PS_CCS|RH_PS_LSDA); -} - -// Reset device on port -static int -ohci_hub_reset(struct usbhub_s *hub, u32 port) -{ - struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb); - writel(&cntl->regs->roothub_portstatus[port], RH_PS_PRS); - u32 sts; - u64 end = calc_future_tsc(USB_TIME_DRSTR * 2); - for (;;) { - sts = readl(&cntl->regs->roothub_portstatus[port]); - if (!(sts & RH_PS_PRS)) - // XXX - need to ensure USB_TIME_DRSTR time in reset? - break; - if (check_tsc(end)) { - // Timeout. - warn_timeout(); - ohci_hub_disconnect(hub, port); - return -1; - } - yield(); - } - - if ((sts & (RH_PS_CCS|RH_PS_PES)) != (RH_PS_CCS|RH_PS_PES)) - // Device no longer present - return -1; - - return !!(sts & RH_PS_LSDA); -} - -static struct usbhub_op_s ohci_HubOp = { - .detect = ohci_hub_detect, - .reset = ohci_hub_reset, - .disconnect = ohci_hub_disconnect, -}; - -// Find any devices connected to the root hub. -static int -check_ohci_ports(struct usb_ohci_s *cntl) -{ - ASSERT32FLAT(); - // Turn on power for all devices on roothub. - u32 rha = readl(&cntl->regs->roothub_a); - rha &= ~(RH_A_PSM | RH_A_OCPM); - writel(&cntl->regs->roothub_status, RH_HS_LPSC); - writel(&cntl->regs->roothub_b, RH_B_PPCM); - msleep((rha >> 24) * 2); - // XXX - need to sleep for USB_TIME_SIGATT if just powered up? - - struct usbhub_s hub; - memset(&hub, 0, sizeof(hub)); - hub.cntl = &cntl->usb; - hub.portcount = rha & RH_A_NDP; - hub.op = &ohci_HubOp; - usb_enumerate(&hub); - return hub.devcount; -} - - -/**************************************************************** - * Setup - ****************************************************************/ - -static int -start_ohci(struct usb_ohci_s *cntl, struct ohci_hcca *hcca) -{ - u32 oldfminterval = readl(&cntl->regs->fminterval); - u32 oldrwc = readl(&cntl->regs->control) & OHCI_CTRL_RWC; - - // XXX - check if already running? - - // Do reset - writel(&cntl->regs->control, OHCI_USB_RESET | oldrwc); - readl(&cntl->regs->control); // flush writes - msleep(USB_TIME_DRSTR); - - // Do software init (min 10us, max 2ms) - u64 end = calc_future_tsc_usec(10); - writel(&cntl->regs->cmdstatus, OHCI_HCR); - for (;;) { - u32 status = readl(&cntl->regs->cmdstatus); - if (! status & OHCI_HCR) - break; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - } - - // Init memory - writel(&cntl->regs->ed_controlhead, 0); - writel(&cntl->regs->ed_bulkhead, 0); - writel(&cntl->regs->hcca, (u32)hcca); - - // Init fminterval - u32 fi = oldfminterval & 0x3fff; - writel(&cntl->regs->fminterval - , (((oldfminterval & FIT) ^ FIT) - | fi | (((6 * (fi - 210)) / 7) << 16))); - writel(&cntl->regs->periodicstart, ((9 * fi) / 10) & 0x3fff); - readl(&cntl->regs->control); // flush writes - - // XXX - verify that fminterval was setup correctly. - - // Go into operational state - writel(&cntl->regs->control - , (OHCI_CTRL_CBSR | OHCI_CTRL_CLE | OHCI_CTRL_PLE - | OHCI_USB_OPER | oldrwc)); - readl(&cntl->regs->control); // flush writes - - return 0; -} - -static void -stop_ohci(struct usb_ohci_s *cntl) -{ - u32 oldrwc = readl(&cntl->regs->control) & OHCI_CTRL_RWC; - writel(&cntl->regs->control, oldrwc); - readl(&cntl->regs->control); // flush writes -} - -static void -configure_ohci(void *data) -{ - struct usb_ohci_s *cntl = data; - - // Allocate memory - struct ohci_hcca *hcca = memalign_high(256, sizeof(*hcca)); - struct ohci_ed *intr_ed = malloc_high(sizeof(*intr_ed)); - if (!hcca || !intr_ed) { - warn_noalloc(); - goto free; - } - memset(hcca, 0, sizeof(*hcca)); - memset(intr_ed, 0, sizeof(*intr_ed)); - intr_ed->hwINFO = ED_SKIP; - int i; - for (i=0; iint_table); i++) - hcca->int_table[i] = (u32)intr_ed; - - int ret = start_ohci(cntl, hcca); - if (ret) - goto err; - - int count = check_ohci_ports(cntl); - free_pipe(cntl->usb.defaultpipe); - if (! count) - goto err; - return; - -err: - stop_ohci(cntl); -free: - free(hcca); - free(intr_ed); -} - -void -ohci_init(u16 bdf, int busid) -{ - if (! CONFIG_USB_OHCI) - return; - struct usb_ohci_s *cntl = malloc_tmphigh(sizeof(*cntl)); - memset(cntl, 0, sizeof(*cntl)); - cntl->usb.busid = busid; - cntl->usb.type = USB_TYPE_OHCI; - - u32 baseaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0); - cntl->regs = (void*)(baseaddr & PCI_BASE_ADDRESS_MEM_MASK); - - dprintf(1, "OHCI init on dev %02x:%02x.%x (regs=%p)\n" - , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf) - , pci_bdf_to_fn(bdf), cntl->regs); - - // Enable bus mastering and memory access. - pci_config_maskw(bdf, PCI_COMMAND - , 0, PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY); - - // XXX - check for and disable SMM control? - - // Disable interrupts - writel(&cntl->regs->intrdisable, ~0); - writel(&cntl->regs->intrstatus, ~0); - - run_thread(configure_ohci, cntl); -} - - -/**************************************************************** - * End point communication - ****************************************************************/ - -static int -wait_ed(struct ohci_ed *ed) -{ - // XXX - 500ms just a guess - u64 end = calc_future_tsc(500); - for (;;) { - if (ed->hwHeadP == ed->hwTailP) - return 0; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - yield(); - } -} - -// Wait for next USB frame to start - for ensuring safe memory release. -static void -ohci_waittick(struct usb_ohci_s *cntl) -{ - barrier(); - struct ohci_hcca *hcca = (void*)cntl->regs->hcca; - u32 startframe = hcca->frame_no; - u64 end = calc_future_tsc(1000 * 5); - for (;;) { - if (hcca->frame_no != startframe) - break; - if (check_tsc(end)) { - warn_timeout(); - return; - } - yield(); - } -} - -static void -signal_freelist(struct usb_ohci_s *cntl) -{ - u32 v = readl(&cntl->regs->control); - if (v & OHCI_CTRL_CLE) { - writel(&cntl->regs->control, v & ~(OHCI_CTRL_CLE|OHCI_CTRL_BLE)); - ohci_waittick(cntl); - writel(&cntl->regs->ed_controlcurrent, 0); - writel(&cntl->regs->ed_bulkcurrent, 0); - writel(&cntl->regs->control, v); - } else { - ohci_waittick(cntl); - } -} - -struct ohci_pipe { - struct ohci_ed ed; - struct usb_pipe pipe; - void *data; - int count; - struct ohci_td *tds; -}; - -void -ohci_free_pipe(struct usb_pipe *p) -{ - if (! CONFIG_USB_OHCI) - return; - dprintf(7, "ohci_free_pipe %p\n", p); - struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe); - struct usb_ohci_s *cntl = container_of( - pipe->pipe.cntl, struct usb_ohci_s, usb); - - u32 *pos = &cntl->regs->ed_controlhead; - for (;;) { - struct ohci_ed *next = (void*)*pos; - if (!next) { - // Not found?! Exit without freeing. - warn_internalerror(); - return; - } - if (next == &pipe->ed) { - *pos = next->hwNextED; - signal_freelist(cntl); - free(pipe); - return; - } - pos = &next->hwNextED; - } -} - -struct usb_pipe * -ohci_alloc_control_pipe(struct usb_pipe *dummy) -{ - if (! CONFIG_USB_OHCI) - return NULL; - struct usb_ohci_s *cntl = container_of( - dummy->cntl, struct usb_ohci_s, usb); - dprintf(7, "ohci_alloc_control_pipe %p\n", &cntl->usb); - - // Allocate a queue head. - struct ohci_pipe *pipe = malloc_tmphigh(sizeof(*pipe)); - if (!pipe) { - warn_noalloc(); - return NULL; - } - memset(pipe, 0, sizeof(*pipe)); - memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe)); - pipe->ed.hwINFO = ED_SKIP; - - // Add queue head to controller list. - pipe->ed.hwNextED = cntl->regs->ed_controlhead; - barrier(); - cntl->regs->ed_controlhead = (u32)&pipe->ed; - return &pipe->pipe; -} - -int -ohci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize - , void *data, int datasize) -{ - if (! CONFIG_USB_OHCI) - return -1; - dprintf(5, "ohci_control %p\n", p); - if (datasize > 4096) { - // XXX - should support larger sizes. - warn_noalloc(); - return -1; - } - struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe); - struct usb_ohci_s *cntl = container_of( - pipe->pipe.cntl, struct usb_ohci_s, usb); - int maxpacket = pipe->pipe.maxpacket; - int lowspeed = pipe->pipe.speed; - int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7); - - // Setup transfer descriptors - struct ohci_td *tds = malloc_tmphigh(sizeof(*tds) * 3); - if (!tds) { - warn_noalloc(); - return -1; - } - struct ohci_td *td = tds; - td->hwINFO = TD_DP_SETUP | TD_T_DATA0 | TD_CC; - td->hwCBP = (u32)cmd; - td->hwNextTD = (u32)&td[1]; - td->hwBE = (u32)cmd + cmdsize - 1; - td++; - if (datasize) { - td->hwINFO = (dir ? TD_DP_IN : TD_DP_OUT) | TD_T_DATA1 | TD_CC; - td->hwCBP = (u32)data; - td->hwNextTD = (u32)&td[1]; - td->hwBE = (u32)data + datasize - 1; - td++; - } - td->hwINFO = (dir ? TD_DP_OUT : TD_DP_IN) | TD_T_DATA1 | TD_CC; - td->hwCBP = 0; - td->hwNextTD = (u32)&td[1]; - td->hwBE = 0; - td++; - - // Transfer data - pipe->ed.hwINFO = ED_SKIP; - barrier(); - pipe->ed.hwHeadP = (u32)tds; - pipe->ed.hwTailP = (u32)td; - barrier(); - pipe->ed.hwINFO = devaddr | (maxpacket << 16) | (lowspeed ? ED_LOWSPEED : 0); - writel(&cntl->regs->cmdstatus, OHCI_CLF); - - int ret = wait_ed(&pipe->ed); - pipe->ed.hwINFO = ED_SKIP; - if (ret) - ohci_waittick(cntl); - free(tds); - return ret; -} - -struct usb_pipe * -ohci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp) -{ - if (! CONFIG_USB_OHCI) - return NULL; - struct usb_ohci_s *cntl = container_of( - dummy->cntl, struct usb_ohci_s, usb); - dprintf(7, "ohci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); - - if (frameexp > 5) - frameexp = 5; - int maxpacket = dummy->maxpacket; - int lowspeed = dummy->speed; - int devaddr = dummy->devaddr | (dummy->ep << 7); - // Determine number of entries needed for 2 timer ticks. - int ms = 1<pipe, dummy, sizeof(pipe->pipe)); - pipe->data = data; - pipe->count = count; - pipe->tds = tds; - - struct ohci_ed *ed = &pipe->ed; - ed->hwHeadP = (u32)&tds[0]; - ed->hwTailP = (u32)&tds[count-1]; - ed->hwINFO = devaddr | (maxpacket << 16) | (lowspeed ? ED_LOWSPEED : 0); - - int i; - for (i=0; iregs->hcca; - if (frameexp == 0) { - // Add to existing interrupt entry. - struct ohci_ed *intr_ed = (void*)hcca->int_table[0]; - ed->hwNextED = intr_ed->hwNextED; - intr_ed->hwNextED = (u32)ed; - } else { - int startpos = 1<<(frameexp-1); - ed->hwNextED = hcca->int_table[startpos]; - for (i=startpos; iint_table); i+=ms) - hcca->int_table[i] = (u32)ed; - } - - return &pipe->pipe; - -err: - free(pipe); - free(tds); - free(data); - return NULL; -} - -int -ohci_poll_intr(struct usb_pipe *p, void *data) -{ - ASSERT16(); - if (! CONFIG_USB_OHCI) - return -1; - - struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe); - struct ohci_td *tds = GET_FLATPTR(pipe->tds); - struct ohci_td *head = (void*)GET_FLATPTR(pipe->ed.hwHeadP); - struct ohci_td *tail = (void*)GET_FLATPTR(pipe->ed.hwTailP); - int count = GET_FLATPTR(pipe->count); - int pos = (tail - tds + 1) % count; - struct ohci_td *next = &tds[pos]; - if (head == next) - // No intrs found. - return -1; - // XXX - check for errors. - - // Copy data. - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - void *pipedata = GET_FLATPTR(pipe->data); - void *intrdata = pipedata + maxpacket * pos; - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(intrdata), (void*)FLATPTR_TO_OFFSET(intrdata) - , maxpacket); - - // Reenable this td. - SET_FLATPTR(tail->hwINFO, TD_DP_IN | TD_T_TOGGLE | TD_CC); - intrdata = pipedata + maxpacket * (tail-tds); - SET_FLATPTR(tail->hwCBP, (u32)intrdata); - SET_FLATPTR(tail->hwNextTD, (u32)next); - SET_FLATPTR(tail->hwBE, (u32)intrdata + maxpacket - 1); - barrier(); - SET_FLATPTR(pipe->ed.hwTailP, (u32)next); - - return 0; -} diff --git a/roms/seabios/src/usb-ohci.h b/roms/seabios/src/usb-ohci.h deleted file mode 100644 index 0cadbd6..0000000 --- a/roms/seabios/src/usb-ohci.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef __USB_OHCI_H -#define __USB_OHCI_H - -// usb-ohci.c -void ohci_init(u16 bdf, int busid); -struct usb_pipe; -void ohci_free_pipe(struct usb_pipe *p); -struct usb_pipe *ohci_alloc_control_pipe(struct usb_pipe *dummy); -int ohci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize - , void *data, int datasize); -struct usb_pipe *ohci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp); -int ohci_poll_intr(struct usb_pipe *p, void *data); - - -/**************************************************************** - * ohci structs and flags - ****************************************************************/ - -struct ohci_ed { - u32 hwINFO; - u32 hwTailP; - u32 hwHeadP; - u32 hwNextED; -} PACKED; - -#define ED_ISO (1 << 15) -#define ED_SKIP (1 << 14) -#define ED_LOWSPEED (1 << 13) -#define ED_OUT (0x01 << 11) -#define ED_IN (0x02 << 11) - -#define ED_C (0x02) -#define ED_H (0x01) - -struct ohci_td { - u32 hwINFO; - u32 hwCBP; - u32 hwNextTD; - u32 hwBE; -} PACKED; - -#define TD_CC 0xf0000000 -#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) -#define TD_DI 0x00E00000 - -#define TD_DONE 0x00020000 -#define TD_ISO 0x00010000 - -#define TD_EC 0x0C000000 -#define TD_T 0x03000000 -#define TD_T_DATA0 0x02000000 -#define TD_T_DATA1 0x03000000 -#define TD_T_TOGGLE 0x00000000 -#define TD_DP 0x00180000 -#define TD_DP_SETUP 0x00000000 -#define TD_DP_IN 0x00100000 -#define TD_DP_OUT 0x00080000 - -#define TD_R 0x00040000 - -struct ohci_hcca { - u32 int_table[32]; - u32 frame_no; - u32 done_head; - u8 reserved[120]; -} PACKED; - -struct ohci_regs { - u32 revision; - u32 control; - u32 cmdstatus; - u32 intrstatus; - u32 intrenable; - u32 intrdisable; - - u32 hcca; - u32 ed_periodcurrent; - u32 ed_controlhead; - u32 ed_controlcurrent; - u32 ed_bulkhead; - u32 ed_bulkcurrent; - u32 donehead; - - u32 fminterval; - u32 fmremaining; - u32 fmnumber; - u32 periodicstart; - u32 lsthresh; - - u32 roothub_a; - u32 roothub_b; - u32 roothub_status; - u32 roothub_portstatus[15]; -} PACKED; - -#define OHCI_CTRL_CBSR (3 << 0) -#define OHCI_CTRL_PLE (1 << 2) -#define OHCI_CTRL_CLE (1 << 4) -#define OHCI_CTRL_BLE (1 << 5) -#define OHCI_CTRL_HCFS (3 << 6) -# define OHCI_USB_RESET (0 << 6) -# define OHCI_USB_OPER (2 << 6) -#define OHCI_CTRL_RWC (1 << 9) - -#define OHCI_HCR (1 << 0) -#define OHCI_CLF (1 << 1) - -#define OHCI_INTR_MIE (1 << 31) - -#define RH_PS_CCS 0x00000001 -#define RH_PS_PES 0x00000002 -#define RH_PS_PSS 0x00000004 -#define RH_PS_POCI 0x00000008 -#define RH_PS_PRS 0x00000010 -#define RH_PS_PPS 0x00000100 -#define RH_PS_LSDA 0x00000200 -#define RH_PS_CSC 0x00010000 -#define RH_PS_PESC 0x00020000 -#define RH_PS_PSSC 0x00040000 -#define RH_PS_OCIC 0x00080000 -#define RH_PS_PRSC 0x00100000 - -#define RH_HS_LPS 0x00000001 -#define RH_HS_OCI 0x00000002 -#define RH_HS_DRWE 0x00008000 -#define RH_HS_LPSC 0x00010000 -#define RH_HS_OCIC 0x00020000 -#define RH_HS_CRWE 0x80000000 - -#define RH_B_DR 0x0000ffff -#define RH_B_PPCM 0xffff0000 - -#define RH_A_NDP (0xff << 0) -#define RH_A_PSM (1 << 8) -#define RH_A_NPS (1 << 9) -#define RH_A_DT (1 << 10) -#define RH_A_OCPM (1 << 11) -#define RH_A_NOCP (1 << 12) -#define RH_A_POTPGT (0xff << 24) - -#endif // usb-ohci.h diff --git a/roms/seabios/src/usb-uhci.c b/roms/seabios/src/usb-uhci.c deleted file mode 100644 index 6549808..0000000 --- a/roms/seabios/src/usb-uhci.c +++ /dev/null @@ -1,603 +0,0 @@ -// Code for handling UHCI USB controllers. -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "pci.h" // pci_bdf_to_bus -#include "config.h" // CONFIG_* -#include "ioport.h" // outw -#include "usb-uhci.h" // USBLEGSUP -#include "pci_regs.h" // PCI_BASE_ADDRESS_4 -#include "usb.h" // struct usb_s -#include "farptr.h" // GET_FLATPTR - -struct usb_uhci_s { - struct usb_s usb; - u16 iobase; - struct uhci_qh *control_qh, *bulk_qh; - struct uhci_framelist *framelist; -}; - - -/**************************************************************** - * Root hub - ****************************************************************/ - -// Check if device attached to a given port -static int -uhci_hub_detect(struct usbhub_s *hub, u32 port) -{ - struct usb_uhci_s *cntl = container_of(hub->cntl, struct usb_uhci_s, usb); - u16 ioport = cntl->iobase + USBPORTSC1 + port * 2; - - u16 status = inw(ioport); - if (!(status & USBPORTSC_CCS)) - // No device - return -1; - - // XXX - if just powered up, need to wait for USB_TIME_ATTDB? - - // Begin reset on port - outw(USBPORTSC_PR, ioport); - msleep(USB_TIME_DRSTR); - return 0; -} - -// Reset device on port -static int -uhci_hub_reset(struct usbhub_s *hub, u32 port) -{ - struct usb_uhci_s *cntl = container_of(hub->cntl, struct usb_uhci_s, usb); - u16 ioport = cntl->iobase + USBPORTSC1 + port * 2; - - // Finish reset on port - outw(0, ioport); - udelay(6); // 64 high-speed bit times - u16 status = inw(ioport); - if (!(status & USBPORTSC_CCS)) - // No longer connected - return -1; - outw(USBPORTSC_PE, ioport); - return !!(status & USBPORTSC_LSDA); -} - -// Disable port -static void -uhci_hub_disconnect(struct usbhub_s *hub, u32 port) -{ - struct usb_uhci_s *cntl = container_of(hub->cntl, struct usb_uhci_s, usb); - u16 ioport = cntl->iobase + USBPORTSC1 + port * 2; - outw(0, ioport); -} - -static struct usbhub_op_s uhci_HubOp = { - .detect = uhci_hub_detect, - .reset = uhci_hub_reset, - .disconnect = uhci_hub_disconnect, -}; - -// Find any devices connected to the root hub. -static int -check_uhci_ports(struct usb_uhci_s *cntl) -{ - ASSERT32FLAT(); - struct usbhub_s hub; - memset(&hub, 0, sizeof(hub)); - hub.cntl = &cntl->usb; - hub.portcount = 2; - hub.op = &uhci_HubOp; - usb_enumerate(&hub); - return hub.devcount; -} - - -/**************************************************************** - * Setup - ****************************************************************/ - -static void -reset_uhci(struct usb_uhci_s *cntl, u16 bdf) -{ - // XXX - don't reset if not needed. - - // Reset PIRQ and SMI - pci_config_writew(bdf, USBLEGSUP, USBLEGSUP_RWC); - - // Reset the HC - outw(USBCMD_HCRESET, cntl->iobase + USBCMD); - udelay(5); - - // Disable interrupts and commands (just to be safe). - outw(0, cntl->iobase + USBINTR); - outw(0, cntl->iobase + USBCMD); -} - -static void -configure_uhci(void *data) -{ - struct usb_uhci_s *cntl = data; - - // Allocate ram for schedule storage - struct uhci_td *term_td = malloc_high(sizeof(*term_td)); - struct uhci_framelist *fl = memalign_high(sizeof(*fl), sizeof(*fl)); - struct uhci_qh *intr_qh = malloc_high(sizeof(*intr_qh)); - struct uhci_qh *term_qh = malloc_high(sizeof(*term_qh)); - if (!term_td || !fl || !intr_qh || !term_qh) { - warn_noalloc(); - goto fail; - } - - // Work around for PIIX errata - memset(term_td, 0, sizeof(*term_td)); - term_td->link = UHCI_PTR_TERM; - term_td->token = (uhci_explen(0) | (0x7f << TD_TOKEN_DEVADDR_SHIFT) - | USB_PID_IN); - memset(term_qh, 0, sizeof(*term_qh)); - term_qh->element = (u32)term_td; - term_qh->link = UHCI_PTR_TERM; - - // Set schedule to point to primary intr queue head - memset(intr_qh, 0, sizeof(*intr_qh)); - intr_qh->element = UHCI_PTR_TERM; - intr_qh->link = (u32)term_qh | UHCI_PTR_QH; - int i; - for (i=0; ilinks); i++) - fl->links[i] = (u32)intr_qh | UHCI_PTR_QH; - cntl->framelist = fl; - cntl->control_qh = cntl->bulk_qh = intr_qh; - barrier(); - - // Set the frame length to the default: 1 ms exactly - outb(USBSOF_DEFAULT, cntl->iobase + USBSOF); - - // Store the frame list base address - outl((u32)fl->links, cntl->iobase + USBFLBASEADD); - - // Set the current frame number - outw(0, cntl->iobase + USBFRNUM); - - // Mark as configured and running with a 64-byte max packet. - outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, cntl->iobase + USBCMD); - - // Find devices - int count = check_uhci_ports(cntl); - free_pipe(cntl->usb.defaultpipe); - if (count) - // Success - return; - - // No devices found - shutdown and free controller. - outw(0, cntl->iobase + USBCMD); -fail: - free(term_td); - free(fl); - free(intr_qh); - free(term_qh); - free(cntl); -} - -void -uhci_init(u16 bdf, int busid) -{ - if (! CONFIG_USB_UHCI) - return; - struct usb_uhci_s *cntl = malloc_tmphigh(sizeof(*cntl)); - memset(cntl, 0, sizeof(*cntl)); - cntl->usb.busid = busid; - cntl->usb.type = USB_TYPE_UHCI; - cntl->iobase = (pci_config_readl(bdf, PCI_BASE_ADDRESS_4) - & PCI_BASE_ADDRESS_IO_MASK); - - dprintf(1, "UHCI init on dev %02x:%02x.%x (io=%x)\n" - , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf) - , pci_bdf_to_fn(bdf), cntl->iobase); - - pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); - - reset_uhci(cntl, bdf); - - run_thread(configure_uhci, cntl); -} - - -/**************************************************************** - * End point communication - ****************************************************************/ - -static int -wait_qh(struct usb_uhci_s *cntl, struct uhci_qh *qh) -{ - // XXX - 500ms just a guess - u64 end = calc_future_tsc(500); - for (;;) { - if (qh->element & UHCI_PTR_TERM) - return 0; - if (check_tsc(end)) { - warn_timeout(); - struct uhci_td *td = (void*)(qh->element & ~UHCI_PTR_BITS); - dprintf(1, "Timeout on wait_qh %p (td=%p s=%x c=%x/%x)\n" - , qh, td, td->status - , inw(cntl->iobase + USBCMD) - , inw(cntl->iobase + USBSTS)); - return -1; - } - yield(); - } -} - -// Wait for next USB frame to start - for ensuring safe memory release. -static void -uhci_waittick(u16 iobase) -{ - barrier(); - u16 startframe = inw(iobase + USBFRNUM); - u64 end = calc_future_tsc(1000 * 5); - for (;;) { - if (inw(iobase + USBFRNUM) != startframe) - break; - if (check_tsc(end)) { - warn_timeout(); - return; - } - yield(); - } -} - -struct uhci_pipe { - struct uhci_qh qh; - struct uhci_td *next_td; - struct usb_pipe pipe; - u16 iobase; - u8 toggle; -}; - -void -uhci_free_pipe(struct usb_pipe *p) -{ - if (! CONFIG_USB_UHCI) - return; - dprintf(7, "uhci_free_pipe %p\n", p); - struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); - struct usb_uhci_s *cntl = container_of( - pipe->pipe.cntl, struct usb_uhci_s, usb); - - struct uhci_qh *pos = (void*)(cntl->framelist->links[0] & ~UHCI_PTR_BITS); - for (;;) { - u32 link = pos->link; - if (link == UHCI_PTR_TERM) { - // Not found?! Exit without freeing. - warn_internalerror(); - return; - } - struct uhci_qh *next = (void*)(link & ~UHCI_PTR_BITS); - if (next == &pipe->qh) { - pos->link = next->link; - if (cntl->control_qh == next) - cntl->control_qh = pos; - if (cntl->bulk_qh == next) - cntl->bulk_qh = pos; - uhci_waittick(cntl->iobase); - free(pipe); - return; - } - pos = next; - } -} - -struct usb_pipe * -uhci_alloc_control_pipe(struct usb_pipe *dummy) -{ - if (! CONFIG_USB_UHCI) - return NULL; - struct usb_uhci_s *cntl = container_of( - dummy->cntl, struct usb_uhci_s, usb); - dprintf(7, "uhci_alloc_control_pipe %p\n", &cntl->usb); - - // Allocate a queue head. - struct uhci_pipe *pipe = malloc_tmphigh(sizeof(*pipe)); - if (!pipe) { - warn_noalloc(); - return NULL; - } - memset(pipe, 0, sizeof(*pipe)); - memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe)); - pipe->qh.element = UHCI_PTR_TERM; - pipe->iobase = cntl->iobase; - - // Add queue head to controller list. - struct uhci_qh *control_qh = cntl->control_qh; - pipe->qh.link = control_qh->link; - barrier(); - control_qh->link = (u32)&pipe->qh | UHCI_PTR_QH; - if (cntl->bulk_qh == control_qh) - cntl->bulk_qh = &pipe->qh; - return &pipe->pipe; -} - -int -uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize - , void *data, int datasize) -{ - ASSERT32FLAT(); - if (! CONFIG_USB_UHCI) - return -1; - dprintf(5, "uhci_control %p\n", p); - struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); - struct usb_uhci_s *cntl = container_of( - pipe->pipe.cntl, struct usb_uhci_s, usb); - - int maxpacket = pipe->pipe.maxpacket; - int lowspeed = pipe->pipe.speed; - int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7); - - // Setup transfer descriptors - int count = 2 + DIV_ROUND_UP(datasize, maxpacket); - struct uhci_td *tds = malloc_tmphigh(sizeof(*tds) * count); - if (!tds) { - warn_noalloc(); - return -1; - } - - tds[0].link = (u32)&tds[1] | UHCI_PTR_DEPTH; - tds[0].status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0) - | TD_CTRL_ACTIVE); - tds[0].token = (uhci_explen(cmdsize) | (devaddr << TD_TOKEN_DEVADDR_SHIFT) - | USB_PID_SETUP); - tds[0].buffer = (void*)cmd; - int toggle = TD_TOKEN_TOGGLE; - int i; - for (i=1; iqh.element = (u32)&tds[0]; - int ret = wait_qh(cntl, &pipe->qh); - if (ret) { - pipe->qh.element = UHCI_PTR_TERM; - uhci_waittick(pipe->iobase); - } - free(tds); - return ret; -} - -struct usb_pipe * -uhci_alloc_bulk_pipe(struct usb_pipe *dummy) -{ - if (! CONFIG_USB_UHCI) - return NULL; - struct usb_uhci_s *cntl = container_of( - dummy->cntl, struct usb_uhci_s, usb); - dprintf(7, "uhci_alloc_bulk_pipe %p\n", &cntl->usb); - - // Allocate a queue head. - struct uhci_pipe *pipe = malloc_low(sizeof(*pipe)); - if (!pipe) { - warn_noalloc(); - return NULL; - } - memset(pipe, 0, sizeof(*pipe)); - memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe)); - pipe->qh.element = UHCI_PTR_TERM; - pipe->iobase = cntl->iobase; - - // Add queue head to controller list. - struct uhci_qh *bulk_qh = cntl->bulk_qh; - pipe->qh.link = bulk_qh->link; - barrier(); - bulk_qh->link = (u32)&pipe->qh | UHCI_PTR_QH; - - return &pipe->pipe; -} - -static int -wait_td(struct uhci_td *td) -{ - u64 end = calc_future_tsc(5000); // XXX - lookup real time. - u32 status; - for (;;) { - status = td->status; - if (!(status & TD_CTRL_ACTIVE)) - break; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - yield(); - } - if (status & TD_CTRL_ANY_ERROR) { - dprintf(1, "wait_td error - status=%x\n", status); - return -2; - } - return 0; -} - -#define STACKTDS 4 -#define TDALIGN 16 - -int -uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) -{ - if (! CONFIG_USB_UHCI) - return -1; - struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); - dprintf(7, "uhci_send_bulk qh=%p dir=%d data=%p size=%d\n" - , &pipe->qh, dir, data, datasize); - int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - int lowspeed = GET_FLATPTR(pipe->pipe.speed); - int devaddr = (GET_FLATPTR(pipe->pipe.devaddr) - | (GET_FLATPTR(pipe->pipe.ep) << 7)); - int toggle = GET_FLATPTR(pipe->toggle) ? TD_TOKEN_TOGGLE : 0; - - // Allocate 4 tds on stack (16byte aligned) - u8 tdsbuf[sizeof(struct uhci_td) * STACKTDS + TDALIGN - 1]; - struct uhci_td *tds = (void*)ALIGN((u32)tdsbuf, TDALIGN); - memset(tds, 0, sizeof(*tds) * STACKTDS); - - // Enable tds - barrier(); - SET_FLATPTR(pipe->qh.element, (u32)MAKE_FLATPTR(GET_SEG(SS), tds)); - - int tdpos = 0; - while (datasize) { - struct uhci_td *td = &tds[tdpos++ % STACKTDS]; - int ret = wait_td(td); - if (ret) - goto fail; - - int transfer = datasize; - if (transfer > maxpacket) - transfer = maxpacket; - struct uhci_td *nexttd_fl = MAKE_FLATPTR(GET_SEG(SS) - , &tds[tdpos % STACKTDS]); - td->link = (transfer==datasize ? UHCI_PTR_TERM : (u32)nexttd_fl); - td->token = (uhci_explen(transfer) | toggle - | (devaddr << TD_TOKEN_DEVADDR_SHIFT) - | (dir ? USB_PID_IN : USB_PID_OUT)); - td->buffer = data; - barrier(); - td->status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0) - | TD_CTRL_ACTIVE); - toggle ^= TD_TOKEN_TOGGLE; - - data += transfer; - datasize -= transfer; - } - int i; - for (i=0; itoggle, !!toggle); - return 0; -fail: - dprintf(1, "uhci_send_bulk failed\n"); - SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM); - uhci_waittick(GET_FLATPTR(pipe->iobase)); - return -1; -} - -struct usb_pipe * -uhci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp) -{ - if (! CONFIG_USB_UHCI) - return NULL; - struct usb_uhci_s *cntl = container_of( - dummy->cntl, struct usb_uhci_s, usb); - dprintf(7, "uhci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); - - if (frameexp > 10) - frameexp = 10; - int maxpacket = dummy->maxpacket; - int lowspeed = dummy->speed; - int devaddr = dummy->devaddr | (dummy->ep << 7); - // Determine number of entries needed for 2 timer ticks. - int ms = 1<pipe, dummy, sizeof(pipe->pipe)); - pipe->qh.element = (u32)tds; - pipe->next_td = &tds[0]; - pipe->iobase = cntl->iobase; - - int toggle = 0; - int i; - for (i=0; iframelist; - if (frameexp == 0) { - // Add to existing interrupt entry. - struct uhci_qh *intr_qh = (void*)(fl->links[0] & ~UHCI_PTR_BITS); - pipe->qh.link = intr_qh->link; - barrier(); - intr_qh->link = (u32)&pipe->qh | UHCI_PTR_QH; - if (cntl->control_qh == intr_qh) - cntl->control_qh = &pipe->qh; - if (cntl->bulk_qh == intr_qh) - cntl->bulk_qh = &pipe->qh; - } else { - int startpos = 1<<(frameexp-1); - pipe->qh.link = fl->links[startpos]; - barrier(); - for (i=startpos; ilinks); i+=ms) - fl->links[i] = (u32)&pipe->qh | UHCI_PTR_QH; - } - - return &pipe->pipe; -fail: - free(pipe); - free(tds); - free(data); - return NULL; -} - -int -uhci_poll_intr(struct usb_pipe *p, void *data) -{ - ASSERT16(); - if (! CONFIG_USB_UHCI) - return -1; - - struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe); - struct uhci_td *td = GET_FLATPTR(pipe->next_td); - u32 status = GET_FLATPTR(td->status); - u32 token = GET_FLATPTR(td->token); - if (status & TD_CTRL_ACTIVE) - // No intrs found. - return -1; - // XXX - check for errors. - - // Copy data. - void *tddata = GET_FLATPTR(td->buffer); - memcpy_far(GET_SEG(SS), data - , FLATPTR_TO_SEG(tddata), (void*)FLATPTR_TO_OFFSET(tddata) - , uhci_expected_length(token)); - - // Reenable this td. - struct uhci_td *next = (void*)(GET_FLATPTR(td->link) & ~UHCI_PTR_BITS); - SET_FLATPTR(pipe->next_td, next); - barrier(); - SET_FLATPTR(td->status, (uhci_maxerr(0) | (status & TD_CTRL_LS) - | TD_CTRL_ACTIVE)); - - return 0; -} diff --git a/roms/seabios/src/usb-uhci.h b/roms/seabios/src/usb-uhci.h deleted file mode 100644 index 3c2c298..0000000 --- a/roms/seabios/src/usb-uhci.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef __USB_UHCI_H -#define __USB_UHCI_H - -// usb-uhci.c -void uhci_init(u16 bdf, int busid); -struct usb_pipe; -void uhci_free_pipe(struct usb_pipe *p); -struct usb_pipe *uhci_alloc_control_pipe(struct usb_pipe *dummy); -int uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize - , void *data, int datasize); -struct usb_pipe *uhci_alloc_bulk_pipe(struct usb_pipe *dummy); -int uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize); -struct usb_pipe *uhci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp); -int uhci_poll_intr(struct usb_pipe *p, void *data); - - -/**************************************************************** - * uhci structs and flags - ****************************************************************/ - -/* USB port status and control registers */ -#define USBPORTSC1 16 -#define USBPORTSC2 18 -#define USBPORTSC_CCS 0x0001 /* Current Connect Status - * ("device present") */ -#define USBPORTSC_CSC 0x0002 /* Connect Status Change */ -#define USBPORTSC_PE 0x0004 /* Port Enable */ -#define USBPORTSC_PEC 0x0008 /* Port Enable Change */ -#define USBPORTSC_DPLUS 0x0010 /* D+ high (line status) */ -#define USBPORTSC_DMINUS 0x0020 /* D- high (line status) */ -#define USBPORTSC_RD 0x0040 /* Resume Detect */ -#define USBPORTSC_RES1 0x0080 /* reserved, always 1 */ -#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */ -#define USBPORTSC_PR 0x0200 /* Port Reset */ - -/* Legacy support register */ -#define USBLEGSUP 0xc0 -#define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ - -/* Command register */ -#define USBCMD 0 -#define USBCMD_RS 0x0001 /* Run/Stop */ -#define USBCMD_HCRESET 0x0002 /* Host reset */ -#define USBCMD_GRESET 0x0004 /* Global reset */ -#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */ -#define USBCMD_FGR 0x0010 /* Force Global Resume */ -#define USBCMD_SWDBG 0x0020 /* SW Debug mode */ -#define USBCMD_CF 0x0040 /* Config Flag (sw only) */ -#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */ - -/* Status register */ -#define USBSTS 2 -#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ -#define USBSTS_ERROR 0x0002 /* Interrupt due to error */ -#define USBSTS_RD 0x0004 /* Resume Detect */ -#define USBSTS_HSE 0x0008 /* Host System Error: PCI problems */ -#define USBSTS_HCPE 0x0010 /* Host Controller Process Error: - * the schedule is buggy */ -#define USBSTS_HCH 0x0020 /* HC Halted */ - -/* Interrupt enable register */ -#define USBINTR 4 -#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */ -#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */ -#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */ -#define USBINTR_SP 0x0008 /* Short packet interrupt enable */ - -#define USBFRNUM 6 -#define USBFLBASEADD 8 -#define USBSOF 12 -#define USBSOF_DEFAULT 64 /* Frame length is exactly 1 ms */ - -struct uhci_framelist { - u32 links[1024]; -} PACKED; - -#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ -#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */ -#define TD_CTRL_C_ERR_SHIFT 27 -#define TD_CTRL_LS (1 << 26) /* Low Speed Device */ -#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ -#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ -#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */ -#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */ -#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */ -#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */ -#define TD_CTRL_NAK (1 << 19) /* NAK Received */ -#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */ -#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ -#define TD_CTRL_ACTLEN_MASK 0x7FF /* actual length, encoded as n - 1 */ - -#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ - TD_CTRL_BABBLE | TD_CTRL_CRCTIMEO | \ - TD_CTRL_BITSTUFF) -#define uhci_maxerr(err) ((err) << TD_CTRL_C_ERR_SHIFT) - -#define TD_TOKEN_DEVADDR_SHIFT 8 -#define TD_TOKEN_TOGGLE_SHIFT 19 -#define TD_TOKEN_TOGGLE (1 << 19) -#define TD_TOKEN_EXPLEN_SHIFT 21 -#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n-1 */ -#define TD_TOKEN_PID_MASK 0xFF - -#define uhci_explen(len) ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \ - TD_TOKEN_EXPLEN_SHIFT) - -#define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \ - 1) & TD_TOKEN_EXPLEN_MASK) - -struct uhci_td { - u32 link; - u32 status; - u32 token; - void *buffer; -} PACKED; - -struct uhci_qh { - u32 link; - u32 element; -} PACKED; - -#define UHCI_PTR_BITS 0x000F -#define UHCI_PTR_TERM 0x0001 -#define UHCI_PTR_QH 0x0002 -#define UHCI_PTR_DEPTH 0x0004 -#define UHCI_PTR_BREADTH 0x0000 - -#endif // usb-uhci.h diff --git a/roms/seabios/src/usb.c b/roms/seabios/src/usb.c deleted file mode 100644 index 7e6a18b..0000000 --- a/roms/seabios/src/usb.c +++ /dev/null @@ -1,471 +0,0 @@ -// Main code for handling USB controllers and devices. -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "pci.h" // foreachpci -#include "config.h" // CONFIG_* -#include "pci_regs.h" // PCI_CLASS_REVISION -#include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI -#include "usb-uhci.h" // uhci_init -#include "usb-ohci.h" // ohci_init -#include "usb-ehci.h" // ehci_init -#include "usb-hid.h" // usb_keyboard_setup -#include "usb-hub.h" // usb_hub_init -#include "usb-msc.h" // usb_msc_init -#include "usb.h" // struct usb_s -#include "biosvar.h" // GET_GLOBAL - - -/**************************************************************** - * Controller function wrappers - ****************************************************************/ - -// Free an allocated control or bulk pipe. -void -free_pipe(struct usb_pipe *pipe) -{ - ASSERT32FLAT(); - if (!pipe) - return; - switch (pipe->type) { - default: - case USB_TYPE_UHCI: - return uhci_free_pipe(pipe); - case USB_TYPE_OHCI: - return ohci_free_pipe(pipe); - case USB_TYPE_EHCI: - return ehci_free_pipe(pipe); - } -} - -// Allocate a control pipe to a default endpoint (which can only be -// used by 32bit code) -static struct usb_pipe * -alloc_default_control_pipe(struct usb_pipe *dummy) -{ - switch (dummy->type) { - default: - case USB_TYPE_UHCI: - return uhci_alloc_control_pipe(dummy); - case USB_TYPE_OHCI: - return ohci_alloc_control_pipe(dummy); - case USB_TYPE_EHCI: - return ehci_alloc_control_pipe(dummy); - } -} - -// Send a message on a control pipe using the default control descriptor. -static int -send_control(struct usb_pipe *pipe, int dir, const void *cmd, int cmdsize - , void *data, int datasize) -{ - ASSERT32FLAT(); - switch (pipe->type) { - default: - case USB_TYPE_UHCI: - return uhci_control(pipe, dir, cmd, cmdsize, data, datasize); - case USB_TYPE_OHCI: - return ohci_control(pipe, dir, cmd, cmdsize, data, datasize); - case USB_TYPE_EHCI: - return ehci_control(pipe, dir, cmd, cmdsize, data, datasize); - } -} - -// Fill "pipe" endpoint info from an endpoint descriptor. -static void -desc2pipe(struct usb_pipe *newpipe, struct usb_pipe *origpipe - , struct usb_endpoint_descriptor *epdesc) -{ - memcpy(newpipe, origpipe, sizeof(*newpipe)); - newpipe->ep = epdesc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - newpipe->maxpacket = epdesc->wMaxPacketSize; -} - -struct usb_pipe * -alloc_bulk_pipe(struct usb_pipe *pipe, struct usb_endpoint_descriptor *epdesc) -{ - struct usb_pipe dummy; - desc2pipe(&dummy, pipe, epdesc); - switch (pipe->type) { - default: - case USB_TYPE_UHCI: - return uhci_alloc_bulk_pipe(&dummy); - case USB_TYPE_OHCI: - return NULL; - case USB_TYPE_EHCI: - return ehci_alloc_bulk_pipe(&dummy); - } -} - -int -usb_send_bulk(struct usb_pipe *pipe_fl, int dir, void *data, int datasize) -{ - switch (GET_FLATPTR(pipe_fl->type)) { - default: - case USB_TYPE_UHCI: - return uhci_send_bulk(pipe_fl, dir, data, datasize); - case USB_TYPE_OHCI: - return -1; - case USB_TYPE_EHCI: - return ehci_send_bulk(pipe_fl, dir, data, datasize); - } -} - -struct usb_pipe * -alloc_intr_pipe(struct usb_pipe *pipe, struct usb_endpoint_descriptor *epdesc) -{ - struct usb_pipe dummy; - desc2pipe(&dummy, pipe, epdesc); - // Find the exponential period of the requested time. - int period = epdesc->bInterval; - int frameexp; - if (pipe->speed != USB_HIGHSPEED) - frameexp = (period <= 0) ? 0 : __fls(period); - else - frameexp = (period <= 4) ? 0 : period - 4; - switch (pipe->type) { - default: - case USB_TYPE_UHCI: - return uhci_alloc_intr_pipe(&dummy, frameexp); - case USB_TYPE_OHCI: - return ohci_alloc_intr_pipe(&dummy, frameexp); - case USB_TYPE_EHCI: - return ehci_alloc_intr_pipe(&dummy, frameexp); - } -} - -int noinline -usb_poll_intr(struct usb_pipe *pipe_fl, void *data) -{ - switch (GET_FLATPTR(pipe_fl->type)) { - default: - case USB_TYPE_UHCI: - return uhci_poll_intr(pipe_fl, data); - case USB_TYPE_OHCI: - return ohci_poll_intr(pipe_fl, data); - case USB_TYPE_EHCI: - return ehci_poll_intr(pipe_fl, data); - } -} - - -/**************************************************************** - * Helper functions - ****************************************************************/ - -// Find the first endpoing of a given type in an interface description. -struct usb_endpoint_descriptor * -findEndPointDesc(struct usb_interface_descriptor *iface, int imax - , int type, int dir) -{ - struct usb_endpoint_descriptor *epdesc = (void*)&iface[1]; - for (;;) { - if ((void*)epdesc >= (void*)iface + imax - || epdesc->bDescriptorType == USB_DT_INTERFACE) { - return NULL; - } - if (epdesc->bDescriptorType == USB_DT_ENDPOINT - && (epdesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir - && (epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == type) - return epdesc; - epdesc = (void*)epdesc + epdesc->bLength; - } -} - -// Send a message to the default control pipe of a device. -int -send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *req - , void *data) -{ - return send_control(pipe, req->bRequestType & USB_DIR_IN - , req, sizeof(*req), data, req->wLength); -} - -// Get the first 8 bytes of the device descriptor. -static int -get_device_info8(struct usb_pipe *pipe, struct usb_device_descriptor *dinfo) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; - req.bRequest = USB_REQ_GET_DESCRIPTOR; - req.wValue = USB_DT_DEVICE<<8; - req.wIndex = 0; - req.wLength = 8; - return send_default_control(pipe, &req, dinfo); -} - -static struct usb_config_descriptor * -get_device_config(struct usb_pipe *pipe) -{ - struct usb_config_descriptor cfg; - - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; - req.bRequest = USB_REQ_GET_DESCRIPTOR; - req.wValue = USB_DT_CONFIG<<8; - req.wIndex = 0; - req.wLength = sizeof(cfg); - int ret = send_default_control(pipe, &req, &cfg); - if (ret) - return NULL; - - void *config = malloc_tmphigh(cfg.wTotalLength); - if (!config) - return NULL; - req.wLength = cfg.wTotalLength; - ret = send_default_control(pipe, &req, config); - if (ret) - return NULL; - //hexdump(config, cfg.wTotalLength); - return config; -} - -static int -set_configuration(struct usb_pipe *pipe, u16 val) -{ - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; - req.bRequest = USB_REQ_SET_CONFIGURATION; - req.wValue = val; - req.wIndex = 0; - req.wLength = 0; - return send_default_control(pipe, &req, NULL); -} - - -/**************************************************************** - * Initialization and enumeration - ****************************************************************/ - -// Assign an address to a device in the default state on the given -// controller. -static struct usb_pipe * -usb_set_address(struct usbhub_s *hub, int port, int speed) -{ - ASSERT32FLAT(); - struct usb_s *cntl = hub->cntl; - dprintf(3, "set_address %p\n", cntl); - if (cntl->maxaddr >= USB_MAXADDR) - return NULL; - - struct usb_pipe *defpipe = cntl->defaultpipe; - if (!defpipe) { - // Create a pipe for the default address. - struct usb_pipe dummy; - memset(&dummy, 0, sizeof(dummy)); - dummy.cntl = cntl; - dummy.type = cntl->type; - dummy.maxpacket = 8; - cntl->defaultpipe = defpipe = alloc_default_control_pipe(&dummy); - if (!defpipe) - return NULL; - } - defpipe->speed = speed; - if (hub->pipe) { - if (hub->pipe->speed == USB_HIGHSPEED) { - defpipe->tt_devaddr = hub->pipe->devaddr; - defpipe->tt_port = port; - } else { - defpipe->tt_devaddr = hub->pipe->tt_devaddr; - defpipe->tt_port = hub->pipe->tt_port; - } - } else { - defpipe->tt_devaddr = defpipe->tt_port = 0; - } - - msleep(USB_TIME_RSTRCY); - - struct usb_ctrlrequest req; - req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; - req.bRequest = USB_REQ_SET_ADDRESS; - req.wValue = cntl->maxaddr + 1; - req.wIndex = 0; - req.wLength = 0; - int ret = send_default_control(defpipe, &req, NULL); - if (ret) - return NULL; - - msleep(USB_TIME_SETADDR_RECOVERY); - - cntl->maxaddr++; - defpipe->devaddr = cntl->maxaddr; - struct usb_pipe *pipe = alloc_default_control_pipe(defpipe); - defpipe->devaddr = 0; - return pipe; -} - -// Called for every found device - see if a driver is available for -// this device and do setup if so. -static int -configure_usb_device(struct usb_pipe *pipe) -{ - ASSERT32FLAT(); - dprintf(3, "config_usb: %p\n", pipe); - - // Set the max packet size for endpoint 0 of this device. - struct usb_device_descriptor dinfo; - int ret = get_device_info8(pipe, &dinfo); - if (ret) - return 0; - dprintf(3, "device rev=%04x cls=%02x sub=%02x proto=%02x size=%02x\n" - , dinfo.bcdUSB, dinfo.bDeviceClass, dinfo.bDeviceSubClass - , dinfo.bDeviceProtocol, dinfo.bMaxPacketSize0); - if (dinfo.bMaxPacketSize0 < 8 || dinfo.bMaxPacketSize0 > 64) - return 0; - pipe->maxpacket = dinfo.bMaxPacketSize0; - - // Get configuration - struct usb_config_descriptor *config = get_device_config(pipe); - if (!config) - return 0; - - // Determine if a driver exists for this device - only look at the - // first interface of the first configuration. - struct usb_interface_descriptor *iface = (void*)(&config[1]); - if (iface->bInterfaceClass != USB_CLASS_HID - && iface->bInterfaceClass != USB_CLASS_MASS_STORAGE - && iface->bInterfaceClass != USB_CLASS_HUB) - // Not a supported device. - goto fail; - - // Set the configuration. - ret = set_configuration(pipe, config->bConfigurationValue); - if (ret) - goto fail; - - // Configure driver. - int imax = (void*)config + config->wTotalLength - (void*)iface; - if (iface->bInterfaceClass == USB_CLASS_HUB) - ret = usb_hub_init(pipe); - else if (iface->bInterfaceClass == USB_CLASS_MASS_STORAGE) - ret = usb_msc_init(pipe, iface, imax); - else - ret = usb_hid_init(pipe, iface, imax); - if (ret) - goto fail; - - free(config); - return 1; -fail: - free(config); - return 0; -} - -static void -usb_init_hub_port(void *data) -{ - struct usbhub_s *hub = data; - u32 port = hub->port; // XXX - find better way to pass port - - // Detect if device present (and possibly start reset) - int ret = hub->op->detect(hub, port); - if (ret) - // No device present - goto done; - - // Reset port and determine device speed - mutex_lock(&hub->cntl->resetlock); - ret = hub->op->reset(hub, port); - if (ret < 0) - // Reset failed - goto resetfail; - - // Set address of port - struct usb_pipe *pipe = usb_set_address(hub, port, ret); - if (!pipe) { - hub->op->disconnect(hub, port); - goto resetfail; - } - mutex_unlock(&hub->cntl->resetlock); - - // Configure the device - int count = configure_usb_device(pipe); - free_pipe(pipe); - if (!count) - hub->op->disconnect(hub, port); - hub->devcount += count; -done: - hub->threads--; - return; - -resetfail: - mutex_unlock(&hub->cntl->resetlock); - goto done; -} - -void -usb_enumerate(struct usbhub_s *hub) -{ - u32 portcount = hub->portcount; - hub->threads = portcount; - - // Launch a thread for every port. - int i; - for (i=0; iport = i; - run_thread(usb_init_hub_port, hub); - } - - // Wait for threads to complete. - while (hub->threads) - yield(); -} - -void -usb_setup(void) -{ - ASSERT32FLAT(); - if (! CONFIG_USB) - return; - - dprintf(3, "init usb\n"); - - usb_hid_setup(); - - // Look for USB controllers - int ehcibdf = -1; - int count = 0; - int bdf, max; - foreachpci(bdf, max) { - u32 code = pci_config_readl(bdf, PCI_CLASS_REVISION) >> 8; - - if (code >> 8 != PCI_CLASS_SERIAL_USB) - continue; - - if (bdf > ehcibdf) { - // Check to see if this device has an ehci controller - ehcibdf = bdf; - u32 ehcicode = code; - int found = 0; - for (;;) { - if (ehcicode == PCI_CLASS_SERIAL_USB_EHCI) { - // Found an ehci controller. - int ret = ehci_init(ehcibdf, count++, bdf); - if (ret) - // Error - break; - count += found; - bdf = ehcibdf; - code = 0; - break; - } - if (ehcicode >> 8 == PCI_CLASS_SERIAL_USB) - found++; - ehcibdf = pci_next(ehcibdf+1, &max); - if (ehcibdf < 0 - || pci_bdf_to_busdev(ehcibdf) != pci_bdf_to_busdev(bdf)) - // No ehci controller found. - break; - ehcicode = pci_config_readl(ehcibdf, PCI_CLASS_REVISION) >> 8; - } - } - - if (code == PCI_CLASS_SERIAL_USB_UHCI) - uhci_init(bdf, count++); - else if (code == PCI_CLASS_SERIAL_USB_OHCI) - ohci_init(bdf, count++); - } -} diff --git a/roms/seabios/src/usb.h b/roms/seabios/src/usb.h deleted file mode 100644 index f28a3a7..0000000 --- a/roms/seabios/src/usb.h +++ /dev/null @@ -1,214 +0,0 @@ -// USB functions and data. -#ifndef __USB_H -#define __USB_H - -#include "util.h" // struct mutex_s - -// Information on a USB end point. -struct usb_pipe { - struct usb_s *cntl; - u8 type; - u8 ep; - u8 devaddr; - u8 speed; - u16 maxpacket; - u8 tt_devaddr; - u8 tt_port; -}; - -// Common information for usb controllers. -struct usb_s { - struct usb_pipe *defaultpipe; - struct mutex_s resetlock; - int busid; - u8 type; - u8 maxaddr; -}; - -// Information for enumerating USB hubs -struct usbhub_s { - struct usbhub_op_s *op; - struct usb_pipe *pipe; - struct usb_s *cntl; - struct mutex_s lock; - u32 powerwait; - u32 port; - u32 threads; - u32 portcount; - u32 devcount; -}; - -// Hub callback (32bit) info -struct usbhub_op_s { - int (*detect)(struct usbhub_s *hub, u32 port); - int (*reset)(struct usbhub_s *hub, u32 port); - void (*disconnect)(struct usbhub_s *hub, u32 port); -}; - -#define USB_TYPE_UHCI 1 -#define USB_TYPE_OHCI 2 -#define USB_TYPE_EHCI 3 - -#define USB_FULLSPEED 0 -#define USB_LOWSPEED 1 -#define USB_HIGHSPEED 2 - -#define USB_MAXADDR 127 - - -/**************************************************************** - * usb structs and flags - ****************************************************************/ - -// USB mandated timings (in ms) -#define USB_TIME_SIGATT 100 -#define USB_TIME_ATTDB 100 -#define USB_TIME_DRST 10 -#define USB_TIME_DRSTR 50 -#define USB_TIME_RSTRCY 10 - -#define USB_TIME_SETADDR_RECOVERY 2 - -#define USB_PID_OUT 0xe1 -#define USB_PID_IN 0x69 -#define USB_PID_SETUP 0x2d - -#define USB_DIR_OUT 0 /* to device */ -#define USB_DIR_IN 0x80 /* to host */ - -#define USB_TYPE_MASK (0x03 << 5) -#define USB_TYPE_STANDARD (0x00 << 5) -#define USB_TYPE_CLASS (0x01 << 5) -#define USB_TYPE_VENDOR (0x02 << 5) -#define USB_TYPE_RESERVED (0x03 << 5) - -#define USB_RECIP_MASK 0x1f -#define USB_RECIP_DEVICE 0x00 -#define USB_RECIP_INTERFACE 0x01 -#define USB_RECIP_ENDPOINT 0x02 -#define USB_RECIP_OTHER 0x03 - -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 -#define USB_REQ_SET_FEATURE 0x03 -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C - -struct usb_ctrlrequest { - u8 bRequestType; - u8 bRequest; - u16 wValue; - u16 wIndex; - u16 wLength; -} PACKED; - -#define USB_DT_DEVICE 0x01 -#define USB_DT_CONFIG 0x02 -#define USB_DT_STRING 0x03 -#define USB_DT_INTERFACE 0x04 -#define USB_DT_ENDPOINT 0x05 -#define USB_DT_DEVICE_QUALIFIER 0x06 -#define USB_DT_OTHER_SPEED_CONFIG 0x07 - -struct usb_device_descriptor { - u8 bLength; - u8 bDescriptorType; - - u16 bcdUSB; - u8 bDeviceClass; - u8 bDeviceSubClass; - u8 bDeviceProtocol; - u8 bMaxPacketSize0; - u16 idVendor; - u16 idProduct; - u16 bcdDevice; - u8 iManufacturer; - u8 iProduct; - u8 iSerialNumber; - u8 bNumConfigurations; -} PACKED; - -#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ -#define USB_CLASS_AUDIO 1 -#define USB_CLASS_COMM 2 -#define USB_CLASS_HID 3 -#define USB_CLASS_PHYSICAL 5 -#define USB_CLASS_STILL_IMAGE 6 -#define USB_CLASS_PRINTER 7 -#define USB_CLASS_MASS_STORAGE 8 -#define USB_CLASS_HUB 9 - -struct usb_config_descriptor { - u8 bLength; - u8 bDescriptorType; - - u16 wTotalLength; - u8 bNumInterfaces; - u8 bConfigurationValue; - u8 iConfiguration; - u8 bmAttributes; - u8 bMaxPower; -} PACKED; - -struct usb_interface_descriptor { - u8 bLength; - u8 bDescriptorType; - - u8 bInterfaceNumber; - u8 bAlternateSetting; - u8 bNumEndpoints; - u8 bInterfaceClass; - u8 bInterfaceSubClass; - u8 bInterfaceProtocol; - u8 iInterface; -} PACKED; - -struct usb_endpoint_descriptor { - u8 bLength; - u8 bDescriptorType; - - u8 bEndpointAddress; - u8 bmAttributes; - u16 wMaxPacketSize; - u8 bInterval; -} PACKED; - -#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ -#define USB_ENDPOINT_DIR_MASK 0x80 - -#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ -#define USB_ENDPOINT_XFER_CONTROL 0 -#define USB_ENDPOINT_XFER_ISOC 1 -#define USB_ENDPOINT_XFER_BULK 2 -#define USB_ENDPOINT_XFER_INT 3 -#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 - - -/**************************************************************** - * function defs - ****************************************************************/ - -// usb.c -void usb_setup(void); -void usb_enumerate(struct usbhub_s *hub); -int send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *req - , void *data); -int usb_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize); -void free_pipe(struct usb_pipe *pipe); -struct usb_pipe *alloc_bulk_pipe(struct usb_pipe *pipe - , struct usb_endpoint_descriptor *epdesc); -struct usb_pipe *alloc_intr_pipe(struct usb_pipe *pipe - , struct usb_endpoint_descriptor *epdesc); -int usb_poll_intr(struct usb_pipe *pipe, void *data); -struct usb_endpoint_descriptor *findEndPointDesc( - struct usb_interface_descriptor *iface, int imax, int type, int dir); -u32 mkendpFromDesc(struct usb_pipe *pipe - , struct usb_endpoint_descriptor *epdesc); - -#endif // usb.h diff --git a/roms/seabios/src/util.c b/roms/seabios/src/util.c deleted file mode 100644 index 8e02d1e..0000000 --- a/roms/seabios/src/util.c +++ /dev/null @@ -1,296 +0,0 @@ -// Misc utility functions. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // call16 -#include "bregs.h" // struct bregs -#include "config.h" // BUILD_STACK_ADDR - - -/**************************************************************** - * 16bit calls - ****************************************************************/ - -// Call a function with a specified register state. Note that on -// return, the interrupt enable/disable flag may be altered. -inline void -call16(struct bregs *callregs) -{ - if (!MODESEGMENT && getesp() > BUILD_STACK_ADDR) - panic("call16 with invalid stack\n"); - asm volatile( -#if MODE16 == 1 - "calll __call16\n" - "cli\n" - "cld" -#else - "calll __call16_from32" -#endif - : "+a" (callregs), "+m" (*callregs) - : - : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory"); -} - -inline void -call16big(struct bregs *callregs) -{ - ASSERT32FLAT(); - if (getesp() > BUILD_STACK_ADDR) - panic("call16 with invalid stack\n"); - asm volatile( - "calll __call16big_from32" - : "+a" (callregs), "+m" (*callregs) - : - : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory"); -} - -inline void -__call16_int(struct bregs *callregs, u16 offset) -{ - if (MODESEGMENT) - callregs->code.seg = GET_SEG(CS); - else - callregs->code.seg = SEG_BIOS; - callregs->code.offset = offset; - call16(callregs); -} - - -/**************************************************************** - * String ops - ****************************************************************/ - -// Sum the bytes in the specified area. -u8 -checksum_far(u16 buf_seg, void *buf_far, u32 len) -{ - SET_SEG(ES, buf_seg); - u32 i; - u8 sum = 0; - for (i=0; i 3) { - u32 copylen = len; - if (copylen > 2048) - copylen = 2048; - copylen /= 4; - len -= copylen * 4; - asm volatile( - "rep movsl (%%esi),%%es:(%%edi)" - : "+c"(copylen), "+S"(s), "+D"(d) - : : "cc", "memory"); - yield(); - } - if (len) - // Copy any remaining bytes. - memcpy(d, s, len); -} - -void * -memmove(void *d, const void *s, size_t len) -{ - if (s >= d) - return memcpy(d, s, len); - - d += len-1; - s += len-1; - while (len--) { - *(char*)d = *(char*)s; - d--; - s--; - } - - return d; -} - -// Copy a string - truncating it if necessary. -char * -strtcpy(char *dest, const char *src, size_t len) -{ - char *d = dest; - while (--len && *src != '\0') - *d++ = *src++; - *d = '\0'; - return dest; -} - - -/**************************************************************** - * Keyboard calls - ****************************************************************/ - -// See if a keystroke is pending in the keyboard buffer. -static int -check_for_keystroke(void) -{ - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_IF; - br.ah = 1; - call16_int(0x16, &br); - return !(br.flags & F_ZF); -} - -// Return a keystroke - waiting forever if necessary. -static int -get_raw_keystroke(void) -{ - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_IF; - call16_int(0x16, &br); - return br.ah; -} - -// Read a keystroke - waiting up to 'msec' milliseconds. -int -get_keystroke(int msec) -{ - u32 end = calc_future_timer(msec); - for (;;) { - if (check_for_keystroke()) - return get_raw_keystroke(); - if (check_timer(end)) - return -1; - wait_irq(); - } -} diff --git a/roms/seabios/src/util.h b/roms/seabios/src/util.h deleted file mode 100644 index 3d68d45..0000000 --- a/roms/seabios/src/util.h +++ /dev/null @@ -1,455 +0,0 @@ -// Basic x86 asm functions and function defs. -// -// Copyright (C) 2008,2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. -#ifndef __UTIL_H -#define __UTIL_H - -#include "types.h" // u32 - -static inline void irq_disable(void) -{ - asm volatile("cli": : :"memory"); -} - -static inline void irq_enable(void) -{ - asm volatile("sti": : :"memory"); -} - -static inline unsigned long irq_save(void) -{ - unsigned long flags; - asm volatile("pushfl ; popl %0" : "=g" (flags): :"memory"); - irq_disable(); - return flags; -} - -static inline void irq_restore(unsigned long flags) -{ - asm volatile("pushl %0 ; popfl" : : "g" (flags) : "memory", "cc"); -} - -static inline void cpu_relax(void) -{ - asm volatile("rep ; nop": : :"memory"); -} - -static inline void nop(void) -{ - asm volatile("nop"); -} - -static inline void hlt(void) -{ - asm volatile("hlt": : :"memory"); -} - -static inline void wbinvd(void) -{ - asm volatile("wbinvd": : :"memory"); -} - -#define CPUID_MSR (1 << 5) -#define CPUID_APIC (1 << 9) -#define CPUID_MTRR (1 << 12) -static inline void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) -{ - asm("cpuid" - : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) - : "0" (index)); -} - -static inline u64 rdmsr(u32 index) -{ - u64 ret; - asm ("rdmsr" : "=A"(ret) : "c"(index)); - return ret; -} - -static inline void wrmsr(u32 index, u64 val) -{ - asm volatile ("wrmsr" : : "c"(index), "A"(val)); -} - -static inline u64 rdtscll(void) -{ - u64 val; - asm volatile("rdtsc" : "=A" (val)); - return val; -} - -static inline u32 __ffs(u32 word) -{ - asm("bsf %1,%0" - : "=r" (word) - : "rm" (word)); - return word; -} -static inline u32 __fls(u32 word) -{ - asm("bsr %1,%0" - : "=r" (word) - : "rm" (word)); - return word; -} - -static inline u16 __htons_constant(u16 val) { - return (val<<8) | (val>>8); -} -static inline u32 __htonl_constant(u32 val) { - return (val<<24) | ((val&0xff00)<<8) | ((val&0xff0000)>>8) | (val>>24); -} -static inline u32 __htonl(u32 val) { - asm("bswapl %0" : "+r"(val)); - return val; -} -#define htonl(x) (__builtin_constant_p((u32)(x)) ? __htonl_constant(x) : __htonl(x)) -#define ntohl(x) htonl(x) -#define htons(x) __htons_constant(x) -#define ntohs(x) htons(x) - -static inline u16 cpu_to_le16(u16 x) -{ - return x; -} - -static inline u32 cpu_to_le32(u32 x) -{ - return x; -} - -static inline u32 getesp(void) { - u32 esp; - asm("movl %%esp, %0" : "=rm"(esp)); - return esp; -} - -static inline void writel(void *addr, u32 val) { - *(volatile u32 *)addr = val; -} -static inline void writew(void *addr, u16 val) { - *(volatile u16 *)addr = val; -} -static inline void writeb(void *addr, u8 val) { - *(volatile u8 *)addr = val; -} -static inline u32 readl(const void *addr) { - return *(volatile const u32 *)addr; -} -static inline u16 readw(const void *addr) { - return *(volatile const u16 *)addr; -} -static inline u8 readb(const void *addr) { - return *(volatile const u8 *)addr; -} - -#define call16_simpint(nr, peax, pflags) do { \ - ASSERT16(); \ - asm volatile( \ - "pushl %%ebp\n" \ - "sti\n" \ - "stc\n" \ - "int %2\n" \ - "pushfl\n" \ - "popl %1\n" \ - "cli\n" \ - "cld\n" \ - "popl %%ebp" \ - : "+a"(*peax), "=c"(*pflags) \ - : "i"(nr) \ - : "ebx", "edx", "esi", "edi", "cc", "memory"); \ - } while (0) - -// GDT bits -#define GDT_CODE (0x9bULL << 40) // Code segment - P,R,A bits also set -#define GDT_DATA (0x93ULL << 40) // Data segment - W,A bits also set -#define GDT_B (0x1ULL << 54) // Big flag -#define GDT_G (0x1ULL << 55) // Granularity flag -// GDT bits for segment base -#define GDT_BASE(v) ((((u64)(v) & 0xff000000) << 32) \ - | (((u64)(v) & 0x00ffffff) << 16)) -// GDT bits for segment limit (0-1Meg) -#define GDT_LIMIT(v) ((((u64)(v) & 0x000f0000) << 32) \ - | (((u64)(v) & 0x0000ffff) << 0)) -// GDT bits for segment limit (0-4Gig in 4K chunks) -#define GDT_GRANLIMIT(v) (GDT_G | GDT_LIMIT((v) >> 12)) - -struct descloc_s { - u16 length; - u32 addr; -} PACKED; - -// util.c -struct bregs; -inline void call16(struct bregs *callregs); -inline void call16big(struct bregs *callregs); -inline void __call16_int(struct bregs *callregs, u16 offset); -#define call16_int(nr, callregs) do { \ - extern void irq_trampoline_ ##nr (); \ - __call16_int((callregs), (u32)&irq_trampoline_ ##nr ); \ - } while (0) -u8 checksum_far(u16 buf_seg, void *buf_far, u32 len); -u8 checksum(void *buf, u32 len); -size_t strlen(const char *s); -int memcmp(const void *s1, const void *s2, size_t n); -int strcmp(const char *s1, const char *s2); -inline void memset_far(u16 d_seg, void *d_far, u8 c, size_t len); -inline void memset16_far(u16 d_seg, void *d_far, u16 c, size_t len); -void *memset(void *s, int c, size_t n); -inline void memcpy_far(u16 d_seg, void *d_far - , u16 s_seg, const void *s_far, size_t len); -void memcpy_fl(void *d_fl, const void *s_fl, size_t len); -void *memcpy(void *d1, const void *s1, size_t len); -#if MODESEGMENT == 0 -#define memcpy __builtin_memcpy -#endif -void iomemcpy(void *d, const void *s, u32 len); -void *memmove(void *d, const void *s, size_t len); -char *strtcpy(char *dest, const char *src, size_t len); -int get_keystroke(int msec); - -// stacks.c -inline u32 stack_hop(u32 eax, u32 edx, void *func); -extern struct thread_info MainThread; -void thread_setup(void); -struct thread_info *getCurThread(void); -void yield(void); -void wait_irq(void); -void run_thread(void (*func)(void*), void *data); -void wait_threads(void); -struct mutex_s { u32 isLocked; }; -void mutex_lock(struct mutex_s *mutex); -void mutex_unlock(struct mutex_s *mutex); -void start_preempt(void); -void finish_preempt(void); -int wait_preempt(void); -void check_preempt(void); - -// output.c -void debug_serial_setup(void); -void panic(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))) __noreturn; -void printf(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -int snprintf(char *str, size_t size, const char *fmt, ...) - __attribute__ ((format (printf, 3, 4))); -void __dprintf(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -void __debug_enter(struct bregs *regs, const char *fname); -void __debug_isr(const char *fname); -void __debug_stub(struct bregs *regs, int lineno, const char *fname); -void __warn_invalid(struct bregs *regs, int lineno, const char *fname); -void __warn_unimplemented(struct bregs *regs, int lineno, const char *fname); -void __warn_internalerror(int lineno, const char *fname); -void __warn_noalloc(int lineno, const char *fname); -void __warn_timeout(int lineno, const char *fname); -void __set_invalid(struct bregs *regs, int lineno, const char *fname); -void __set_unimplemented(struct bregs *regs, int lineno, const char *fname); -void __set_code_invalid(struct bregs *regs, u32 linecode, const char *fname); -void __set_code_unimplemented(struct bregs *regs, u32 linecode - , const char *fname); -void hexdump(const void *d, int len); - -#define dprintf(lvl, fmt, args...) do { \ - if (CONFIG_DEBUG_LEVEL && (lvl) <= CONFIG_DEBUG_LEVEL) \ - __dprintf((fmt) , ##args ); \ - } while (0) -#define debug_enter(regs, lvl) do { \ - if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ - __debug_enter((regs), __func__); \ - } while (0) -#define debug_isr(lvl) do { \ - if ((lvl) && (lvl) <= CONFIG_DEBUG_LEVEL) \ - __debug_isr(__func__); \ - } while (0) -#define debug_stub(regs) \ - __debug_stub((regs), __LINE__, __func__) -#define warn_invalid(regs) \ - __warn_invalid((regs), __LINE__, __func__) -#define warn_unimplemented(regs) \ - __warn_unimplemented((regs), __LINE__, __func__) -#define warn_internalerror() \ - __warn_internalerror(__LINE__, __func__) -#define warn_noalloc() \ - __warn_noalloc(__LINE__, __func__) -#define warn_timeout() \ - __warn_timeout(__LINE__, __func__) -#define set_invalid(regs) \ - __set_invalid((regs), __LINE__, __func__) -#define set_code_invalid(regs, code) \ - __set_code_invalid((regs), (code) | (__LINE__ << 8), __func__) -#define set_unimplemented(regs) \ - __set_unimplemented((regs), __LINE__, __func__) -#define set_code_unimplemented(regs, code) \ - __set_code_unimplemented((regs), (code) | (__LINE__ << 8), __func__) - -// kbd.c -void kbd_setup(void); -void handle_15c2(struct bregs *regs); -void process_key(u8 key); - -// mouse.c -void mouse_setup(void); -void process_mouse(u8 data); - -// system.c -extern u32 RamSize; -extern u64 RamSizeOver4G; -void mathcp_setup(void); - -// serial.c -void serial_setup(void); -void lpt_setup(void); - -// clock.c -#define PIT_TICK_RATE 1193180 // Underlying HZ of PIT -#define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer -static inline int check_tsc(u64 end) { - return (s64)(rdtscll() - end) > 0; -} -void timer_setup(void); -void ndelay(u32 count); -void udelay(u32 count); -void mdelay(u32 count); -void nsleep(u32 count); -void usleep(u32 count); -void msleep(u32 count); -u64 calc_future_tsc(u32 msecs); -u64 calc_future_tsc_usec(u32 usecs); -u32 calc_future_timer_ticks(u32 count); -u32 calc_future_timer(u32 msecs); -int check_timer(u32 end); -void handle_1583(struct bregs *regs); -void handle_1586(struct bregs *regs); -void useRTC(void); -void releaseRTC(void); - -// apm.c -void handle_1553(struct bregs *regs); - -// pcibios.c -void handle_1ab1(struct bregs *regs); -void bios32_setup(void); - -// shadow.c -void make_bios_writable(void); -void make_bios_readonly(void); -void make_bios_writable_intel(u16 bdf, u32 pam0); -void make_bios_readonly_intel(u16 bdf, u32 pam0); - -// smm.c -void smm_save_and_copy(void); -void smm_relocate_and_restore(void); - -// pciinit.c -extern const u8 pci_irqs[4]; -void pci_bios_allocate_regions(u16 bdf, void *arg); -void pci_setup(void); - -// smm.c -void smm_init(void); - -// smp.c -extern u32 CountCPUs; -extern u32 MaxCountCPUs; -void wrmsr_smp(u32 index, u64 val); -void smp_probe(void); -void smp_probe_setup(void); - -// coreboot.c -struct cbfs_file; -struct cbfs_file *cbfs_finddatafile(const char *fname); -struct cbfs_file *cbfs_findprefix(const char *prefix, struct cbfs_file *last); -u32 cbfs_datasize(struct cbfs_file *file); -const char *cbfs_filename(struct cbfs_file *file); -int cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen); -void cbfs_run_payload(struct cbfs_file *file); -void coreboot_copy_biostable(void); -void coreboot_setup(void); - -// vgahooks.c -extern int VGAbdf; -void handle_155f(struct bregs *regs); -void vgahook_setup(const char *vendor, const char *part); - -// optionroms.c -void call_bcv(u16 seg, u16 ip); -void optionrom_setup(void); -void vga_setup(void); -void s3_resume_vga_init(void); -extern u32 RomEnd; - -// bootsplash.c -void enable_vga_console(void); -void enable_bootsplash(void); -void disable_bootsplash(void); - -// resume.c -void init_dma(void); - -// pnpbios.c -#define PNP_SIGNATURE 0x506e5024 // $PnP -u16 get_pnp_offset(void); -void pnp_setup(void); - -// pmm.c -extern struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh; -void malloc_setup(void); -void malloc_finalize(void); -void *pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align); -int pmm_free(void *data); -void pmm_setup(void); -void pmm_finalize(void); -#define PMM_DEFAULT_HANDLE 0xFFFFFFFF -// Minimum alignment of malloc'd memory -#define MALLOC_MIN_ALIGN 16 -// Helper functions for memory allocation. -static inline void *malloc_low(u32 size) { - return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); -} -static inline void *malloc_high(u32 size) { - return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); -} -static inline void *malloc_fseg(u32 size) { - return pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); -} -static inline void *malloc_tmplow(u32 size) { - return pmm_malloc(&ZoneTmpLow, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); -} -static inline void *malloc_tmphigh(u32 size) { - return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, MALLOC_MIN_ALIGN); -} -static inline void *malloc_tmp(u32 size) { - void *ret = malloc_tmphigh(size); - if (ret) - return ret; - return malloc_tmplow(size); -} -static inline void *memalign_low(u32 align, u32 size) { - return pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align); -} -static inline void *memalign_high(u32 align, u32 size) { - return pmm_malloc(&ZoneHigh, PMM_DEFAULT_HANDLE, size, align); -} -static inline void *memalign_tmphigh(u32 align, u32 size) { - return pmm_malloc(&ZoneTmpHigh, PMM_DEFAULT_HANDLE, size, align); -} -static inline void free(void *data) { - pmm_free(data); -} - -// mtrr.c -void mtrr_setup(void); - -// romlayout.S -void reset_vector(void) __noreturn; - -// misc.c -extern u8 BiosChecksum; - -// version (auto generated file out/version.c) -extern const char VERSION[]; - -#endif // util.h diff --git a/roms/seabios/src/vgahooks.c b/roms/seabios/src/vgahooks.c deleted file mode 100644 index 14678be..0000000 --- a/roms/seabios/src/vgahooks.c +++ /dev/null @@ -1,317 +0,0 @@ -// Hooks for via vgabios calls into main bios. -// -// Copyright (C) 2008 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "bregs.h" // set_code_invalid -#include "biosvar.h" // GET_GLOBAL -#include "pci.h" // pci_find_device -#include "pci_regs.h" // PCI_VENDOR_ID -#include "pci_ids.h" // PCI_VENDOR_ID_VIA -#include "util.h" // handle_155f -#include "config.h" // CONFIG_* - -// The Bus/Dev/Fn of the primary VGA device. -int VGAbdf VAR16VISIBLE; -// Coreboot board detected. -int CBmainboard VAR16VISIBLE; - -#define MAINBOARD_DEFAULT 0 -#define KONTRON_986LCD_M 1 -#define GETAC_P470 2 -#define RODA_RK886EX 3 - -struct mainboards { - char *vendor; - char *device; - int type; -}; - -struct mainboards mainboard_list[] = { - { "KONTRON", "986LCD-M", KONTRON_986LCD_M }, - { "GETAC", "P470", GETAC_P470 }, - { "RODA", "RK886EX", RODA_RK886EX }, -}; - -static void -handle_155fXX(struct bregs *regs) -{ - set_code_unimplemented(regs, RET_EUNSUPPORTED); -} - - -/**************************************************************** - * Via hooks - ****************************************************************/ - -static void -via_155f01(struct bregs *regs) -{ - regs->eax = 0x5f; - regs->cl = 2; // panel type = 2 = 1024 * 768 - set_success(regs); - dprintf(1, "Warning: VGA panel type is hardcoded\n"); -} - -static void -via_155f02(struct bregs *regs) -{ - regs->eax = 0x5f; - regs->bx = 2; - regs->cx = 0x401; // PAL + crt only - regs->dx = 0; // TV Layout - default - set_success(regs); - dprintf(1, "Warning: VGA TV/CRT output type is hardcoded\n"); -} - -static int -getFBSize(u16 bdf) -{ - /* FB config */ - u8 reg = pci_config_readb(bdf, 0xa1); - - /* GFX disabled ? */ - if (!(reg & 0x80)) - return -1; - - static u8 mem_power[] VAR16 = {0, 3, 4, 5, 6, 7, 8, 9}; - return GET_GLOBAL(mem_power[(reg >> 4) & 0x7]); -} - -static int -getViaRamSpeed(u16 bdf) -{ - return (pci_config_readb(bdf, 0x90) & 0x07) + 3; -} - -static int -getAMDRamSpeed(void) -{ - int bdf = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MEMCTL); - if (bdf < 0) - return -1; - - /* mem clk 0 = DDR2 400 */ - return (pci_config_readb(bdf, 0x94) & 0x7) + 6; -} - -/* int 0x15 - 5f18 - - ECX = unknown/dont care - EBX[3..0] Frame Buffer Size 2^N MiB - EBX[7..4] Memory speed: - 0: SDR 66Mhz - 1: SDR 100Mhz - 2: SDR 133Mhz - 3: DDR 100Mhz (PC1600 or DDR200) - 4: DDR 133Mhz (PC2100 or DDR266) - 5: DDR 166Mhz (PC2700 or DDR333) - 6: DDR 200Mhz (PC3200 or DDR400) - 7: DDR2 133Mhz (DDR2 533) - 8: DDR2 166Mhz (DDR2 667) - 9: DDR2 200Mhz (DDR2 800) - A: DDR2 233Mhz (DDR2 1066) - B: and above: Unknown - EBX[?..8] Total memory size? - EAX = 0x5f for success -*/ - -#define PCI_DEVICE_ID_VIA_K8M890CE_3 0x3336 -#define PCI_DEVICE_ID_VIA_VX855_MEMCTRL 0x3409 - -static void -via_155f18(struct bregs *regs) -{ - int ramspeed, fbsize; - - int bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3); - if (bdf >= 0) { - fbsize = getFBSize(bdf); - ramspeed = getAMDRamSpeed(); - goto done; - } - bdf = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_MEMCTRL); - if (bdf >= 0) { - fbsize = getFBSize(bdf); - ramspeed = getViaRamSpeed(bdf); - goto done; - } - - dprintf(1, "Warning: VGA memory size and speed is hardcoded\n"); - fbsize = 5; // 32M frame buffer - ramspeed = 4; // MCLK = DDR266 - -done: - if (fbsize < 0 || ramspeed < 0) { - set_code_invalid(regs, RET_EUNSUPPORTED); - return; - } - regs->eax = 0x5f; - regs->ebx = 0x500 | (ramspeed << 4) | fbsize; - regs->ecx = 0x060; - set_success(regs); -} - -static void -via_155f19(struct bregs *regs) -{ - set_invalid_silent(regs); -} - -static void -via_155f(struct bregs *regs) -{ - switch (regs->al) { - case 0x01: via_155f01(regs); break; - case 0x02: via_155f02(regs); break; - case 0x18: via_155f18(regs); break; - case 0x19: via_155f19(regs); break; - default: handle_155fXX(regs); break; - } -} - -/**************************************************************** - * Intel VGA hooks - ****************************************************************/ -#define BOOT_DISPLAY_DEFAULT (0) -#define BOOT_DISPLAY_CRT (1 << 0) -#define BOOT_DISPLAY_TV (1 << 1) -#define BOOT_DISPLAY_EFP (1 << 2) -#define BOOT_DISPLAY_LCD (1 << 3) -#define BOOT_DISPLAY_CRT2 (1 << 4) -#define BOOT_DISPLAY_TV2 (1 << 5) -#define BOOT_DISPLAY_EFP2 (1 << 6) -#define BOOT_DISPLAY_LCD2 (1 << 7) - -static void -roda_155f35(struct bregs *regs) -{ - regs->ax = 0x005f; - // regs->cl = BOOT_DISPLAY_DEFAULT; - regs->cl = BOOT_DISPLAY_LCD; - set_success(regs); -} - -static void -roda_155f40(struct bregs *regs) -{ - u8 display_id; - //display_id = inb(0x60f) & 0x0f; // Correct according to Crete - display_id = 3; // Correct according to empirical studies - - regs->ax = 0x005f; - regs->cl = display_id; - set_success(regs); -} - -static void -roda_155f(struct bregs *regs) -{ - dprintf(1, "Executing RODA specific interrupt %02x.\n", regs->al); - switch (regs->al) { - case 0x35: roda_155f35(regs); break; - case 0x40: roda_155f40(regs); break; - default: handle_155fXX(regs); break; - } -} - -static void -kontron_155f35(struct bregs *regs) -{ - regs->ax = 0x005f; - regs->cl = BOOT_DISPLAY_CRT; - set_success(regs); -} - -static void -kontron_155f40(struct bregs *regs) -{ - u8 display_id; - display_id = 3; - - regs->ax = 0x005f; - regs->cl = display_id; - set_success(regs); -} - -static void -kontron_155f(struct bregs *regs) -{ - dprintf(1, "Executing Kontron specific interrupt %02x.\n", regs->al); - switch (regs->al) { - case 0x35: kontron_155f35(regs); break; - case 0x40: kontron_155f40(regs); break; - default: handle_155fXX(regs); break; - } -} - -static void -getac_155f(struct bregs *regs) -{ - dprintf(1, "Executing Getac specific interrupt %02x.\n", regs->al); - switch (regs->al) { - default: handle_155fXX(regs); break; - } -} - -/**************************************************************** - * Entry and setup - ****************************************************************/ - -// Main 16bit entry point -void -handle_155f(struct bregs *regs) -{ - int bdf, cbmb; - - if (! CONFIG_VGAHOOKS) - goto fail; - - cbmb = GET_GLOBAL(CBmainboard); - - switch (cbmb) { - case KONTRON_986LCD_M: - kontron_155f(regs); - return; - case RODA_RK886EX: - roda_155f(regs); - return; - case GETAC_P470: - getac_155f(regs); - return; - case MAINBOARD_DEFAULT: - bdf = GET_GLOBAL(VGAbdf); - if (bdf < 0) - goto fail; - - u16 vendor = pci_config_readw(bdf, PCI_VENDOR_ID); - if (vendor == PCI_VENDOR_ID_VIA) { - via_155f(regs); - return; - } - } - -fail: - handle_155fXX(regs); -} - -// Setup -void -vgahook_setup(const char *vendor, const char *part) -{ - int i; - - if (! CONFIG_VGAHOOKS) - return; - - CBmainboard = 0; - for (i=0; i<(sizeof(mainboard_list) / sizeof(mainboard_list[0])); i++) { - if (!strcmp(vendor, mainboard_list[i].vendor) && - !strcmp(part, mainboard_list[i].device)) { - printf("Found mainboard %s %s\n", vendor, part); - CBmainboard = mainboard_list[i].type; - break; - } - } -} diff --git a/roms/seabios/src/virtio-blk.c b/roms/seabios/src/virtio-blk.c deleted file mode 100644 index 7a25826..0000000 --- a/roms/seabios/src/virtio-blk.c +++ /dev/null @@ -1,190 +0,0 @@ -// Virtio block boot support. -// -// Copyright (C) 2010 Red Hat Inc. -// -// Authors: -// Gleb Natapov -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "util.h" // dprintf -#include "pci.h" // foreachpci -#include "config.h" // CONFIG_* -#include "biosvar.h" // GET_GLOBAL -#include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK -#include "pci_regs.h" // PCI_VENDOR_ID -#include "boot.h" // add_bcv_internal -#include "virtio-pci.h" -#include "virtio-ring.h" -#include "virtio-blk.h" -#include "disk.h" - -struct virtiodrive_s { - struct drive_s drive; - struct vring_virtqueue *vq; - u16 ioaddr; -}; - -static int -virtio_blk_op(struct disk_op_s *op, int write) -{ - struct virtiodrive_s *vdrive_g = - container_of(op->drive_g, struct virtiodrive_s, drive); - struct vring_virtqueue *vq = GET_GLOBAL(vdrive_g->vq); - struct virtio_blk_outhdr hdr = { - .type = write ? VIRTIO_BLK_T_OUT : VIRTIO_BLK_T_IN, - .ioprio = 0, - .sector = op->lba, - }; - u8 status = VIRTIO_BLK_S_UNSUPP; - struct vring_list sg[] = { - { - .addr = MAKE_FLATPTR(GET_SEG(SS), &hdr), - .length = sizeof(hdr), - }, - { - .addr = op->buf_fl, - .length = GET_GLOBAL(vdrive_g->drive.blksize) * op->count, - }, - { - .addr = MAKE_FLATPTR(GET_SEG(SS), &status), - .length = sizeof(status), - }, - }; - - /* Add to virtqueue and kick host */ - if (write) - vring_add_buf(vq, sg, 2, 1, 0, 0); - else - vring_add_buf(vq, sg, 1, 2, 0, 0); - vring_kick(GET_GLOBAL(vdrive_g->ioaddr), vq, 1); - - /* Wait for reply */ - while (!vring_more_used(vq)) - usleep(5); - - /* Reclaim virtqueue element */ - vring_get_buf(vq, NULL); - - /* Clear interrupt status register. Avoid leaving interrupts stuck if - * VRING_AVAIL_F_NO_INTERRUPT was ignored and interrupts were raised. - */ - vp_get_isr(GET_GLOBAL(vdrive_g->ioaddr)); - - return status == VIRTIO_BLK_S_OK ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK; -} - -int -process_virtio_op(struct disk_op_s *op) -{ - if (! CONFIG_VIRTIO_BLK || CONFIG_COREBOOT) - return 0; - switch (op->command) { - case CMD_READ: - return virtio_blk_op(op, 0); - case CMD_WRITE: - return virtio_blk_op(op, 1); - case CMD_FORMAT: - case CMD_RESET: - case CMD_ISREADY: - case CMD_VERIFY: - case CMD_SEEK: - return DISK_RET_SUCCESS; - default: - op->count = 0; - return DISK_RET_EPARAM; - } -} - -static void -init_virtio_blk(u16 bdf) -{ - dprintf(1, "found virtio-blk at %x:%x\n", pci_bdf_to_bus(bdf), - pci_bdf_to_dev(bdf)); - char *desc = malloc_tmphigh(MAXDESCSIZE); - struct virtiodrive_s *vdrive_g = malloc_fseg(sizeof(*vdrive_g)); - struct vring_virtqueue *vq = memalign_low(PAGE_SIZE, sizeof(*vq)); - if (!vdrive_g || !desc || !vq) { - warn_noalloc(); - goto fail; - } - memset(vdrive_g, 0, sizeof(*vdrive_g)); - memset(vq, 0, sizeof(*vq)); - vdrive_g->drive.type = DTYPE_VIRTIO; - vdrive_g->drive.cntl_id = bdf; - vdrive_g->vq = vq; - - u16 ioaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) & - PCI_BASE_ADDRESS_IO_MASK; - - vdrive_g->ioaddr = ioaddr; - - vp_reset(ioaddr); - vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE | - VIRTIO_CONFIG_S_DRIVER ); - - if (vp_find_vq(ioaddr, 0, vdrive_g->vq) < 0 ) { - dprintf(1, "fail to find vq for virtio-blk %x:%x\n", - pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)); - goto fail; - } - - struct virtio_blk_config cfg; - vp_get(ioaddr, 0, &cfg, sizeof(cfg)); - - u32 f = vp_get_features(ioaddr); - vdrive_g->drive.blksize = (f & (1 << VIRTIO_BLK_F_BLK_SIZE)) ? - cfg.blk_size : DISK_SECTOR_SIZE; - - vdrive_g->drive.sectors = cfg.capacity; - dprintf(3, "virtio-blk %x:%x blksize=%d sectors=%u\n", - pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), - vdrive_g->drive.blksize, (u32)vdrive_g->drive.sectors); - - if (vdrive_g->drive.blksize != DISK_SECTOR_SIZE) { - dprintf(1, "virtio-blk %x:%x block size %d is unsupported\n", - pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), - vdrive_g->drive.blksize); - goto fail; - } - - vdrive_g->drive.pchs.cylinders = cfg.cylinders; - vdrive_g->drive.pchs.heads = cfg.heads; - vdrive_g->drive.pchs.spt = cfg.sectors; - - setup_translation(&vdrive_g->drive); - add_bcv_internal(&vdrive_g->drive); - - snprintf(desc, MAXDESCSIZE, "Virtio disk PCI:%x:%x", - pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)); - - vdrive_g->drive.desc = desc; - - vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE | - VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK); - return; - -fail: - free(vdrive_g); - free(desc); - free(vq); -} - -void -virtio_blk_setup(void) -{ - ASSERT32FLAT(); - if (! CONFIG_VIRTIO_BLK || CONFIG_COREBOOT) - return; - - dprintf(3, "init virtio-blk\n"); - - int bdf, max; - u32 id = PCI_VENDOR_ID_REDHAT_QUMRANET | (PCI_DEVICE_ID_VIRTIO_BLK << 16); - foreachpci(bdf, max) { - u32 v = pci_config_readl(bdf, PCI_VENDOR_ID); - if (v != id) - continue; - init_virtio_blk(bdf); - } -} diff --git a/roms/seabios/src/virtio-blk.h b/roms/seabios/src/virtio-blk.h deleted file mode 100644 index 7243704..0000000 --- a/roms/seabios/src/virtio-blk.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _VIRTIO_BLK_H -#define _VIRTIO_BLK_H - -struct virtio_blk_config -{ - u64 capacity; - u32 size_max; - u32 seg_max; - u16 cylinders; - u8 heads; - u8 sectors; - u32 blk_size; - u8 physical_block_exp; - u8 alignment_offset; - u16 min_io_size; - u32 opt_io_size; -} __attribute__((packed)); - -#define VIRTIO_BLK_F_BLK_SIZE 6 - -/* These two define direction. */ -#define VIRTIO_BLK_T_IN 0 -#define VIRTIO_BLK_T_OUT 1 - -/* This is the first element of the read scatter-gather list. */ -struct virtio_blk_outhdr { - /* VIRTIO_BLK_T* */ - u32 type; - /* io priority. */ - u32 ioprio; - /* Sector (ie. 512 byte offset) */ - u64 sector; -}; - -#define VIRTIO_BLK_S_OK 0 -#define VIRTIO_BLK_S_IOERR 1 -#define VIRTIO_BLK_S_UNSUPP 2 - -struct disk_op_s; -int process_virtio_op(struct disk_op_s *op); -void virtio_blk_setup(void); - -#endif /* _VIRTIO_BLK_H */ diff --git a/roms/seabios/src/virtio-pci.c b/roms/seabios/src/virtio-pci.c deleted file mode 100644 index db19e97..0000000 --- a/roms/seabios/src/virtio-pci.c +++ /dev/null @@ -1,69 +0,0 @@ -/* virtio-pci.c - pci interface for virtio interface - * - * (c) Copyright 2008 Bull S.A.S. - * - * Author: Laurent Vivier - * - * some parts from Linux Virtio PCI driver - * - * Copyright IBM Corp. 2007 - * Authors: Anthony Liguori - * - * Adopted for Seabios: Gleb Natapov - * - * This work is licensed under the terms of the GNU LGPLv3 - * See the COPYING file in the top-level directory. - */ - -#include "virtio-ring.h" -#include "virtio-pci.h" -#include "config.h" // CONFIG_DEBUG_LEVEL -#include "util.h" // dprintf - -int vp_find_vq(unsigned int ioaddr, int queue_index, - struct vring_virtqueue *vq) -{ - struct vring * vr = &vq->vring; - u16 num; - - ASSERT32FLAT(); - /* select the queue */ - - outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL); - - /* check if the queue is available */ - - num = inw(ioaddr + VIRTIO_PCI_QUEUE_NUM); - if (!num) { - dprintf(1, "ERROR: queue size is 0\n"); - return -1; - } - - if (num > MAX_QUEUE_NUM) { - dprintf(1, "ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM); - return -1; - } - - /* check if the queue is already active */ - - if (inl(ioaddr + VIRTIO_PCI_QUEUE_PFN)) { - dprintf(1, "ERROR: queue already active\n"); - return -1; - } - - vq->queue_index = queue_index; - - /* initialize the queue */ - - vring_init(vr, num, (unsigned char*)&vq->queue); - - /* activate the queue - * - * NOTE: vr->desc is initialized by vring_init() - */ - - outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT, - ioaddr + VIRTIO_PCI_QUEUE_PFN); - - return num; -} diff --git a/roms/seabios/src/virtio-pci.h b/roms/seabios/src/virtio-pci.h deleted file mode 100644 index d21d5a5..0000000 --- a/roms/seabios/src/virtio-pci.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef _VIRTIO_PCI_H -#define _VIRTIO_PCI_H - -#include "ioport.h" // inl - -/* A 32-bit r/o bitmask of the features supported by the host */ -#define VIRTIO_PCI_HOST_FEATURES 0 - -/* A 32-bit r/w bitmask of features activated by the guest */ -#define VIRTIO_PCI_GUEST_FEATURES 4 - -/* A 32-bit r/w PFN for the currently selected queue */ -#define VIRTIO_PCI_QUEUE_PFN 8 - -/* A 16-bit r/o queue size for the currently selected queue */ -#define VIRTIO_PCI_QUEUE_NUM 12 - -/* A 16-bit r/w queue selector */ -#define VIRTIO_PCI_QUEUE_SEL 14 - -/* A 16-bit r/w queue notifier */ -#define VIRTIO_PCI_QUEUE_NOTIFY 16 - -/* An 8-bit device status register. */ -#define VIRTIO_PCI_STATUS 18 - -/* An 8-bit r/o interrupt status register. Reading the value will return the - * current contents of the ISR and will also clear it. This is effectively - * a read-and-acknowledge. */ -#define VIRTIO_PCI_ISR 19 - -/* The bit of the ISR which indicates a device configuration change. */ -#define VIRTIO_PCI_ISR_CONFIG 0x2 - -/* The remaining space is defined by each driver as the per-driver - * configuration space */ -#define VIRTIO_PCI_CONFIG 20 - -/* Virtio ABI version, this must match exactly */ -#define VIRTIO_PCI_ABI_VERSION 0 - -static inline u32 vp_get_features(unsigned int ioaddr) -{ - return inl(ioaddr + VIRTIO_PCI_HOST_FEATURES); -} - -static inline void vp_set_features(unsigned int ioaddr, u32 features) -{ - outl(features, ioaddr + VIRTIO_PCI_GUEST_FEATURES); -} - -static inline void vp_get(unsigned int ioaddr, unsigned offset, - void *buf, unsigned len) -{ - u8 *ptr = buf; - unsigned i; - - for (i = 0; i < len; i++) - ptr[i] = inb(ioaddr + VIRTIO_PCI_CONFIG + offset + i); -} - -static inline u8 vp_get_status(unsigned int ioaddr) -{ - return inb(ioaddr + VIRTIO_PCI_STATUS); -} - -static inline void vp_set_status(unsigned int ioaddr, u8 status) -{ - if (status == 0) /* reset */ - return; - outb(status, ioaddr + VIRTIO_PCI_STATUS); -} - -static inline u8 vp_get_isr(unsigned int ioaddr) -{ - return inb(ioaddr + VIRTIO_PCI_ISR); -} - -static inline void vp_reset(unsigned int ioaddr) -{ - outb(0, ioaddr + VIRTIO_PCI_STATUS); - (void)inb(ioaddr + VIRTIO_PCI_ISR); -} - -static inline void vp_notify(unsigned int ioaddr, int queue_index) -{ - outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); -} - -static inline void vp_del_vq(unsigned int ioaddr, int queue_index) -{ - /* select the queue */ - - outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL); - - /* deactivate the queue */ - - outl(0, ioaddr + VIRTIO_PCI_QUEUE_PFN); -} - -struct vring_virtqueue; -int vp_find_vq(unsigned int ioaddr, int queue_index, - struct vring_virtqueue *vq); -#endif /* _VIRTIO_PCI_H_ */ diff --git a/roms/seabios/src/virtio-ring.c b/roms/seabios/src/virtio-ring.c deleted file mode 100644 index 97a3ffe..0000000 --- a/roms/seabios/src/virtio-ring.c +++ /dev/null @@ -1,151 +0,0 @@ -/* virtio-pci.c - virtio ring management - * - * (c) Copyright 2008 Bull S.A.S. - * - * Author: Laurent Vivier - * - * some parts from Linux Virtio Ring - * - * Copyright Rusty Russell IBM Corporation 2007 - * - * Adopted for Seabios: Gleb Natapov - * - * This work is licensed under the terms of the GNU LGPLv3 - * See the COPYING file in the top-level directory. - * - * - */ - -#include "virtio-ring.h" -#include "virtio-pci.h" -#include "biosvar.h" // GET_GLOBAL -#include "util.h" // dprintf - -#define BUG() do { \ - dprintf(1, "BUG: failure at %s:%d/%s()!\n", \ - __FILE__, __LINE__, __func__); \ - while(1); \ - } while (0) -#define BUG_ON(condition) do { if (condition) BUG(); } while (0) - -/* - * vring_more_used - * - * is there some used buffers ? - * - */ - -int vring_more_used(struct vring_virtqueue *vq) -{ - struct vring_used *used = GET_FLATPTR(vq->vring.used); - int more = GET_FLATPTR(vq->last_used_idx) != GET_FLATPTR(used->idx); - /* Make sure ring reads are done after idx read above. */ - smp_rmb(); - return more; -} - -/* - * vring_free - * - * put at the begin of the free list the current desc[head] - */ - -void vring_detach(struct vring_virtqueue *vq, unsigned int head) -{ - struct vring *vr = &vq->vring; - struct vring_desc *desc = GET_FLATPTR(vr->desc); - unsigned int i; - - /* find end of given descriptor */ - - i = head; - while (GET_FLATPTR(desc[i].flags) & VRING_DESC_F_NEXT) - i = GET_FLATPTR(desc[i].next); - - /* link it with free list and point to it */ - - SET_FLATPTR(desc[i].next, GET_FLATPTR(vq->free_head)); - SET_FLATPTR(vq->free_head, head); -} - -/* - * vring_get_buf - * - * get a buffer from the used list - * - */ - -int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len) -{ - struct vring *vr = &vq->vring; - struct vring_used_elem *elem; - struct vring_used *used = GET_FLATPTR(vq->vring.used); - u32 id; - int ret; - -// BUG_ON(!vring_more_used(vq)); - - elem = &used->ring[GET_FLATPTR(vq->last_used_idx) % GET_FLATPTR(vr->num)]; - id = GET_FLATPTR(elem->id); - if (len != NULL) - *len = GET_FLATPTR(elem->len); - - ret = GET_FLATPTR(vq->vdata[id]); - - vring_detach(vq, id); - - SET_FLATPTR(vq->last_used_idx, GET_FLATPTR(vq->last_used_idx) + 1); - - return ret; -} - -void vring_add_buf(struct vring_virtqueue *vq, - struct vring_list list[], - unsigned int out, unsigned int in, - int index, int num_added) -{ - struct vring *vr = &vq->vring; - int i, av, head, prev; - struct vring_desc *desc = GET_FLATPTR(vr->desc); - struct vring_avail *avail = GET_FLATPTR(vr->avail); - - BUG_ON(out + in == 0); - - prev = 0; - head = GET_FLATPTR(vq->free_head); - for (i = head; out; i = GET_FLATPTR(desc[i].next), out--) { - SET_FLATPTR(desc[i].flags, VRING_DESC_F_NEXT); - SET_FLATPTR(desc[i].addr, (u64)virt_to_phys(list->addr)); - SET_FLATPTR(desc[i].len, list->length); - prev = i; - list++; - } - for ( ; in; i = GET_FLATPTR(desc[i].next), in--) { - SET_FLATPTR(desc[i].flags, VRING_DESC_F_NEXT|VRING_DESC_F_WRITE); - SET_FLATPTR(desc[i].addr, (u64)virt_to_phys(list->addr)); - SET_FLATPTR(desc[i].len, list->length); - prev = i; - list++; - } - SET_FLATPTR(desc[prev].flags, - GET_FLATPTR(desc[prev].flags) & ~VRING_DESC_F_NEXT); - - SET_FLATPTR(vq->free_head, i); - - SET_FLATPTR(vq->vdata[head], index); - - av = (GET_FLATPTR(avail->idx) + num_added) % GET_FLATPTR(vr->num); - SET_FLATPTR(avail->ring[av], head); -} - -void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added) -{ - struct vring *vr = &vq->vring; - struct vring_avail *avail = GET_FLATPTR(vr->avail); - - /* Make sure idx update is done after ring write. */ - smp_wmb(); - SET_FLATPTR(avail->idx, GET_FLATPTR(avail->idx) + num_added); - - vp_notify(ioaddr, GET_FLATPTR(vq->queue_index)); -} diff --git a/roms/seabios/src/virtio-ring.h b/roms/seabios/src/virtio-ring.h deleted file mode 100644 index b7a7aaf..0000000 --- a/roms/seabios/src/virtio-ring.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef _VIRTIO_RING_H -#define _VIRTIO_RING_H - -#include "types.h" // u64 -#include "memmap.h" // PAGE_SIZE - -#define PAGE_SHIFT 12 -#define PAGE_MASK (PAGE_SIZE-1) - -#define virt_to_phys(v) (unsigned long)(v) -#define phys_to_virt(p) (void*)(p) -/* Compiler barrier is enough as an x86 CPU does not reorder reads or writes */ -#define smp_rmb() barrier() -#define smp_wmb() barrier() - -/* Status byte for guest to report progress, and synchronize features. */ -/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ -#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 -/* We have found a driver for the device. */ -#define VIRTIO_CONFIG_S_DRIVER 2 -/* Driver has used its parts of the config, and is happy */ -#define VIRTIO_CONFIG_S_DRIVER_OK 4 -/* We've given up on this device. */ -#define VIRTIO_CONFIG_S_FAILED 0x80 - -#define MAX_QUEUE_NUM (128) - -#define VRING_DESC_F_NEXT 1 -#define VRING_DESC_F_WRITE 2 - -#define VRING_AVAIL_F_NO_INTERRUPT 1 - -#define VRING_USED_F_NO_NOTIFY 1 - -struct vring_desc -{ - u64 addr; - u32 len; - u16 flags; - u16 next; -}; - -struct vring_avail -{ - u16 flags; - u16 idx; - u16 ring[0]; -}; - -struct vring_used_elem -{ - u32 id; - u32 len; -}; - -struct vring_used -{ - u16 flags; - u16 idx; - struct vring_used_elem ring[]; -}; - -struct vring { - unsigned int num; - struct vring_desc *desc; - struct vring_avail *avail; - struct vring_used *used; -}; - -#define vring_size(num) \ - (((((sizeof(struct vring_desc) * num) + \ - (sizeof(struct vring_avail) + sizeof(u16) * num)) \ - + PAGE_MASK) & ~PAGE_MASK) + \ - (sizeof(struct vring_used) + sizeof(struct vring_used_elem) * num)) - -typedef unsigned char virtio_queue_t[vring_size(MAX_QUEUE_NUM)]; - -struct vring_virtqueue { - virtio_queue_t queue; - struct vring vring; - u16 free_head; - u16 last_used_idx; - u16 vdata[MAX_QUEUE_NUM]; - /* PCI */ - int queue_index; -}; - -struct vring_list { - char *addr; - unsigned int length; -}; - -static inline void vring_init(struct vring *vr, - unsigned int num, unsigned char *queue) -{ - unsigned int i; - unsigned long pa; - - ASSERT32FLAT(); - vr->num = num; - - /* physical address of desc must be page aligned */ - - pa = virt_to_phys(queue); - pa = (pa + PAGE_MASK) & ~PAGE_MASK; - vr->desc = phys_to_virt(pa); - - vr->avail = (struct vring_avail *)&vr->desc[num]; - /* disable interrupts */ - vr->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; - - /* physical address of used must be page aligned */ - - pa = virt_to_phys(&vr->avail->ring[num]); - pa = (pa + PAGE_MASK) & ~PAGE_MASK; - vr->used = phys_to_virt(pa); - - for (i = 0; i < num - 1; i++) - vr->desc[i].next = i + 1; - vr->desc[i].next = 0; -} - -int vring_more_used(struct vring_virtqueue *vq); -void vring_detach(struct vring_virtqueue *vq, unsigned int head); -int vring_get_buf(struct vring_virtqueue *vq, unsigned int *len); -void vring_add_buf(struct vring_virtqueue *vq, struct vring_list list[], - unsigned int out, unsigned int in, - int index, int num_added); -void vring_kick(unsigned int ioaddr, struct vring_virtqueue *vq, int num_added); - -#endif /* _VIRTIO_RING_H_ */ diff --git a/roms/seabios/tools/buildrom.py b/roms/seabios/tools/buildrom.py deleted file mode 100644 index 19b715a..0000000 --- a/roms/seabios/tools/buildrom.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -# Fill in checksum/size of an option rom, and pad it to proper length. -# -# Copyright (C) 2009 Kevin O'Connor -# -# This file may be distributed under the terms of the GNU GPLv3 license. - -import sys - -def alignpos(pos, alignbytes): - mask = alignbytes - 1 - return (pos + mask) & ~mask - -def checksum(data): - ords = map(ord, data) - return sum(ords) - -def main(): - inname = sys.argv[1] - outname = sys.argv[2] - - # Read data in - f = open(inname, 'rb') - data = f.read() - count = len(data) - - # Pad to a 512 byte boundary - data += "\0" * (alignpos(count, 512) - count) - count = len(data) - - # Fill in size field; clear checksum field - data = data[:2] + chr(count/512) + data[3:6] + "\0" + data[7:] - - # Checksum rom - newsum = (256 - checksum(data)) & 0xff - data = data[:6] + chr(newsum) + data[7:] - - # Write new rom - f = open(outname, 'wb') - f.write(data) - -if __name__ == '__main__': - main() diff --git a/roms/seabios/tools/checkrom.py b/roms/seabios/tools/checkrom.py deleted file mode 100644 index 039010d..0000000 --- a/roms/seabios/tools/checkrom.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -# Script to check a bios image and report info on it. -# -# Copyright (C) 2008 Kevin O'Connor -# -# This file may be distributed under the terms of the GNU GPLv3 license. - -import sys -import layoutrom - -def main(): - # Get args - objinfo, rawfile, outfile = sys.argv[1:] - - # Read in symbols - objinfofile = open(objinfo, 'rb') - symbols = layoutrom.parseObjDump(objinfofile)[1] - syms = {} - for name, (addr, section) in symbols.items(): - syms[name] = addr - - # Read in raw file - f = open(rawfile, 'rb') - rawdata = f.read() - f.close() - datasize = len(rawdata) - finalsize = 64*1024 - if datasize > 64*1024: - finalsize = 128*1024 - - # Sanity checks - start = syms['code32flat_start'] - end = syms['code32flat_end'] - expend = layoutrom.BUILD_BIOS_ADDR + layoutrom.BUILD_BIOS_SIZE - if end != expend: - print "Error! Code does not end at 0x%x (got 0x%x)" % ( - expend, end) - sys.exit(1) - if datasize > finalsize: - print "Error! Code is too big (0x%x vs 0x%x)" % ( - datasize, finalsize) - sys.exit(1) - expdatasize = end - start - if datasize != expdatasize: - print "Error! Unknown extra data (0x%x vs 0x%x)" % ( - datasize, expdatasize) - sys.exit(1) - - # Print statistics - print "Total size: %d Free space: %d Percent used: %.1f%% (%dKiB rom)" % ( - datasize, finalsize - datasize - , (datasize / float(finalsize)) * 100.0 - , finalsize / 1024) - - # Write final file - f = open(outfile, 'wb') - f.write(("\0" * (finalsize - datasize)) + rawdata) - f.close() - -if __name__ == '__main__': - main() diff --git a/roms/seabios/tools/checkstack.py b/roms/seabios/tools/checkstack.py deleted file mode 100644 index 2fbc160..0000000 --- a/roms/seabios/tools/checkstack.py +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/env python -# Script that tries to find how much stack space each function in an -# object is using. -# -# Copyright (C) 2008 Kevin O'Connor -# -# This file may be distributed under the terms of the GNU GPLv3 license. - -# Usage: -# objdump -m i386 -M i8086 -M suffix -d out/rom16.o | tools/checkstack.py - -import sys -import re - -# Functions that change stacks -STACKHOP = ['__send_disk_op'] -# List of functions we can assume are never called. -#IGNORE = ['panic', '__dprintf'] -IGNORE = ['panic'] - -OUTPUTDESC = """ -#funcname1[preamble_stack_usage,max_usage_with_callers]: -# insn_addr:called_function [usage_at_call_point+caller_preamble,total_usage] -# -#funcname2[p,m,max_usage_to_yield_point]: -# insn_addr:called_function [u+c,t,usage_to_yield_point] -""" - -# Find out maximum stack usage for a function -def calcmaxstack(funcs, funcaddr): - info = funcs[funcaddr] - # Find max of all nested calls. - maxusage = info[1] - maxyieldusage = doesyield = 0 - if info[3] is not None: - maxyieldusage = info[3] - doesyield = 1 - info[2] = maxusage - info[4] = info[3] - seenbefore = {} - totcalls = 0 - for insnaddr, calladdr, usage in info[6]: - callinfo = funcs.get(calladdr) - if callinfo is None: - continue - if callinfo[2] is None: - calcmaxstack(funcs, calladdr) - if callinfo[0] not in seenbefore: - seenbefore[callinfo[0]] = 1 - totcalls += 1 + callinfo[5] - funcnameroot = callinfo[0].split('.')[0] - if funcnameroot in IGNORE: - # This called function is ignored - don't contribute it to - # the max stack. - continue - if funcnameroot in STACKHOP: - if usage > maxusage: - maxusage = usage - if callinfo[4] is not None: - doesyield = 1 - if usage > maxyieldusage: - maxyieldusage = usage - continue - totusage = usage + callinfo[2] - if totusage > maxusage: - maxusage = totusage - if callinfo[4] is not None: - doesyield = 1 - totyieldusage = usage + callinfo[4] - if totyieldusage > maxyieldusage: - maxyieldusage = totyieldusage - info[2] = maxusage - if doesyield: - info[4] = maxyieldusage - info[5] = totcalls - -# Try to arrange output so that functions that call each other are -# near each other. -def orderfuncs(funcaddrs, availfuncs): - l = [(availfuncs[funcaddr][5], availfuncs[funcaddr][0], funcaddr) - for funcaddr in funcaddrs if funcaddr in availfuncs] - l.sort() - l.reverse() - out = [] - while l: - count, name, funcaddr = l.pop(0) - if funcaddr not in availfuncs: - continue - calladdrs = [calls[1] for calls in availfuncs[funcaddr][6]] - del availfuncs[funcaddr] - out = out + orderfuncs(calladdrs, availfuncs) + [funcaddr] - return out - -# Update function info with a found "yield" point. -def noteYield(info, stackusage): - prevyield = info[3] - if prevyield is None or prevyield < stackusage: - info[3] = stackusage - -# Update function info with a found "call" point. -def noteCall(info, subfuncs, insnaddr, calladdr, stackusage): - if (calladdr, stackusage) in subfuncs: - # Already noted a nearly identical call - ignore this one. - return - info[6].append((insnaddr, calladdr, stackusage)) - subfuncs[(calladdr, stackusage)] = 1 - -hex_s = r'[0-9a-f]+' -re_func = re.compile(r'^(?P' + hex_s + r') <(?P.*)>:$') -re_asm = re.compile( - r'^[ ]*(?P' + hex_s - + r'):\t.*\t(addr32 )?(?P.+?)[ ]*((?P' + hex_s - + r') <(?P.*)>)?$') -re_usestack = re.compile( - r'^(push[f]?[lw])|(sub.* [$](?P0x' + hex_s + r'),%esp)$') - -def calc(): - # funcs[funcaddr] = [funcname, basicstackusage, maxstackusage - # , yieldusage, maxyieldusage, totalcalls - # , [(insnaddr, calladdr, stackusage), ...]] - funcs = {-1: ['', 0, 0, None, None, 0, []]} - cur = None - atstart = 0 - stackusage = 0 - - # Parse input lines - for line in sys.stdin.readlines(): - m = re_func.match(line) - if m is not None: - # Found function - funcaddr = int(m.group('funcaddr'), 16) - funcs[funcaddr] = cur = [m.group('func'), 0, None, None, None, 0, []] - stackusage = 0 - atstart = 1 - subfuncs = {} - continue - m = re_asm.match(line) - if m is not None: - insn = m.group('insn') - - im = re_usestack.match(insn) - if im is not None: - if insn[:5] == 'pushl' or insn[:6] == 'pushfl': - stackusage += 4 - continue - elif insn[:5] == 'pushw' or insn[:6] == 'pushfw': - stackusage += 2 - continue - stackusage += int(im.group('num'), 16) - - if atstart: - if insn == 'movl %esp,%ebp': - # Still part of initial header - continue - cur[1] = stackusage - atstart = 0 - - insnaddr = m.group('insnaddr') - calladdr = m.group('calladdr') - if calladdr is None: - if insn[:6] == 'lcallw': - noteCall(cur, subfuncs, insnaddr, -1, stackusage + 4) - noteYield(cur, stackusage + 4) - elif insn[:3] == 'int': - noteCall(cur, subfuncs, insnaddr, -1, stackusage + 6) - noteYield(cur, stackusage + 6) - elif insn[:3] == 'sti': - noteYield(cur, stackusage) - else: - # misc instruction - continue - else: - # Jump or call insn - calladdr = int(calladdr, 16) - ref = m.group('ref') - if '+' in ref: - # Inter-function jump. - pass - elif insn[:1] == 'j': - # Tail call - noteCall(cur, subfuncs, insnaddr, calladdr, 0) - elif insn[:5] == 'calll': - noteCall(cur, subfuncs, insnaddr, calladdr, stackusage + 4) - else: - print "unknown call", ref - noteCall(cur, subfuncs, insnaddr, calladdr, stackusage) - # Reset stack usage to preamble usage - stackusage = cur[1] - - #print "other", repr(line) - - # Calculate maxstackusage - for funcaddr, info in funcs.items(): - if info[2] is not None: - continue - calcmaxstack(funcs, funcaddr) - - # Sort functions for output - funcaddrs = orderfuncs(funcs.keys(), funcs.copy()) - - # Show all functions - print OUTPUTDESC - for funcaddr in funcaddrs: - name, basicusage, maxusage, yieldusage, maxyieldusage, count, calls = \ - funcs[funcaddr] - if maxusage == 0 and maxyieldusage is None: - continue - yieldstr = "" - if maxyieldusage is not None: - yieldstr = ",%d" % maxyieldusage - print "\n%s[%d,%d%s]:" % (name, basicusage, maxusage, yieldstr) - for insnaddr, calladdr, stackusage in calls: - callinfo = funcs.get(calladdr, ("", 0, 0, 0, None)) - yieldstr = "" - if callinfo[4] is not None: - yieldstr = ",%d" % (stackusage + callinfo[4]) - print " %04s:%-40s [%d+%d,%d%s]" % ( - insnaddr, callinfo[0], stackusage, callinfo[1] - , stackusage+callinfo[2], yieldstr) - -def main(): - calc() - -if __name__ == '__main__': - main() diff --git a/roms/seabios/tools/checksum.py b/roms/seabios/tools/checksum.py deleted file mode 100644 index 8c7665d..0000000 --- a/roms/seabios/tools/checksum.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python -# Script to report the checksum of a file. -# -# Copyright (C) 2009 Kevin O'Connor -# -# This file may be distributed under the terms of the GNU GPLv3 license. - -import sys - -def main(): - data = sys.stdin.read() - ords = map(ord, data) - print "sum=%x\n" % sum(ords) - -if __name__ == '__main__': - main() diff --git a/roms/seabios/tools/gen-offsets.sh b/roms/seabios/tools/gen-offsets.sh deleted file mode 100644 index 99fdc53..0000000 --- a/roms/seabios/tools/gen-offsets.sh +++ /dev/null @@ -1,17 +0,0 @@ -: -# Extract definitions from an assembler file. This is based on code -# from the Linux Kernel. -INFILE=$1 -OUTFILE=$2 -cat > "$OUTFILE" </{s:->#\(.*\):/* \1 */:; \ - s:^->\([^ ]*\) [\$\#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ - s:->::; p;}" < "$INFILE" >> "$OUTFILE" -cat >> "$OUTFILE" < -# -# This file may be distributed under the terms of the GNU GPLv3 license. - -import sys - -# LD script headers/trailers -COMMONHEADER = """ -/* DO NOT EDIT! This is an autogenerated file. See tools/layoutrom.py. */ -OUTPUT_FORMAT("elf32-i386") -OUTPUT_ARCH("i386") -SECTIONS -{ -""" -COMMONTRAILER = """ - - /* Discard regular data sections to force a link error if - * code attempts to access data not marked with VAR16 (or other - * appropriate macro) - */ - /DISCARD/ : { - *(.text*) *(.data*) *(.bss*) *(.rodata*) - *(COMMON) *(.discard*) *(.eh_frame) - } -} -""" - - -###################################################################### -# Determine section locations -###################################################################### - -# Align 'pos' to 'alignbytes' offset -def alignpos(pos, alignbytes): - mask = alignbytes - 1 - return (pos + mask) & ~mask - -# Determine the final addresses for a list of sections that end at an -# address. -def getSectionsStart(sections, endaddr, minalign=1): - totspace = 0 - for size, align, name in sections: - if align > minalign: - minalign = align - totspace = alignpos(totspace, align) + size - startaddr = (endaddr - totspace) / minalign * minalign - curaddr = startaddr - # out = [(addr, sectioninfo), ...] - out = [] - for sectioninfo in sections: - size, align, name = sectioninfo - curaddr = alignpos(curaddr, align) - out.append((curaddr, sectioninfo)) - curaddr += size - return out, startaddr - -# Return the subset of sections with a given name prefix -def getSectionsPrefix(sections, prefix): - lp = len(prefix) - out = [] - for size, align, name in sections: - if name[:lp] == prefix: - out.append((size, align, name)) - return out - -# The 16bit code can't exceed 64K of space. -BUILD_BIOS_ADDR = 0xf0000 -BUILD_BIOS_SIZE = 0x10000 - -# Layout the 16bit code. This ensures sections with fixed offset -# requirements are placed in the correct location. It also places the -# 16bit code as high as possible in the f-segment. -def fitSections(sections, fillsections): - canrelocate = list(fillsections) - # fixedsections = [(addr, sectioninfo), ...] - fixedsections = [] - for sectioninfo in sections: - size, align, name = sectioninfo - if name[:11] == '.fixedaddr.': - addr = int(name[11:], 16) - fixedsections.append((addr, sectioninfo)) - if align != 1: - print "Error: Fixed section %s has non-zero alignment (%d)" % ( - name, align) - sys.exit(1) - - # Find freespace in fixed address area - fixedsections.sort() - # fixedAddr = [(freespace, sectioninfo), ...] - fixedAddr = [] - for i in range(len(fixedsections)): - fixedsectioninfo = fixedsections[i] - addr, section = fixedsectioninfo - if i == len(fixedsections) - 1: - nextaddr = BUILD_BIOS_SIZE - else: - nextaddr = fixedsections[i+1][0] - avail = nextaddr - addr - section[0] - fixedAddr.append((avail, fixedsectioninfo)) - - # Attempt to fit other sections into fixed area - extrasections = [] - fixedAddr.sort() - canrelocate.sort() - totalused = 0 - for freespace, fixedsectioninfo in fixedAddr: - fixedaddr, fixedsection = fixedsectioninfo - addpos = fixedaddr + fixedsection[0] - totalused += fixedsection[0] - nextfixedaddr = addpos + freespace -# print "Filling section %x uses %d, next=%x, available=%d" % ( -# fixedaddr, fixedsection[0], nextfixedaddr, freespace) - while 1: - canfit = None - for fitsection in canrelocate: - fitsize, fitalign, fitname = fitsection - if addpos + fitsize > nextfixedaddr: - # Can't fit and nothing else will fit. - break - fitnextaddr = alignpos(addpos, fitalign) + fitsize -# print "Test %s - %x vs %x" % ( -# fitname, fitnextaddr, nextfixedaddr) - if fitnextaddr > nextfixedaddr: - # This item can't fit. - continue - canfit = (fitnextaddr, fitsection) - if canfit is None: - break - # Found a section that can fit. - fitnextaddr, fitsection = canfit - canrelocate.remove(fitsection) - extrasections.append((addpos, fitsection)) - addpos = fitnextaddr - totalused += fitsection[0] -# print " Adding %s (size %d align %d) pos=%x avail=%d" % ( -# fitsection[2], fitsection[0], fitsection[1] -# , fitnextaddr, nextfixedaddr - fitnextaddr) - firstfixed = fixedsections[0][0] - - # Report stats - total = BUILD_BIOS_SIZE-firstfixed - slack = total - totalused - print ("Fixed space: 0x%x-0x%x total: %d slack: %d" - " Percent slack: %.1f%%" % ( - firstfixed, BUILD_BIOS_SIZE, total, slack, - (float(slack) / total) * 100.0)) - - return fixedsections + extrasections, firstfixed - -def doLayout(sections16, sections32seg, sections32flat): - # Determine 16bit positions - textsections = getSectionsPrefix(sections16, '.text.') - rodatasections = (getSectionsPrefix(sections16, '.rodata.str1.1') - + getSectionsPrefix(sections16, '.rodata.__func__.')) - datasections = getSectionsPrefix(sections16, '.data16.') - fixedsections = getSectionsPrefix(sections16, '.fixedaddr.') - - locs16fixed, firstfixed = fitSections(fixedsections, textsections) - prunesections = [i[1] for i in locs16fixed] - remsections = [i for i in textsections+rodatasections+datasections - if i not in prunesections] - locs16, code16_start = getSectionsStart(remsections, firstfixed) - locs16 = locs16 + locs16fixed - locs16.sort() - - # Determine 32seg positions - textsections = getSectionsPrefix(sections32seg, '.text.') - rodatasections = (getSectionsPrefix(sections32seg, '.rodata.str1.1') - + getSectionsPrefix(sections32seg, '.rodata.__func__.')) - datasections = getSectionsPrefix(sections32seg, '.data32seg.') - - locs32seg, code32seg_start = getSectionsStart( - textsections + rodatasections + datasections, code16_start) - - # Determine 32flat positions - textsections = getSectionsPrefix(sections32flat, '.text.') - rodatasections = getSectionsPrefix(sections32flat, '.rodata') - datasections = getSectionsPrefix(sections32flat, '.data.') - bsssections = getSectionsPrefix(sections32flat, '.bss.') - - locs32flat, code32flat_start = getSectionsStart( - textsections + rodatasections + datasections + bsssections - , code32seg_start + BUILD_BIOS_ADDR, 16) - - # Print statistics - size16 = BUILD_BIOS_SIZE - code16_start - size32seg = code16_start - code32seg_start - size32flat = code32seg_start + BUILD_BIOS_ADDR - code32flat_start - print "16bit size: %d" % size16 - print "32bit segmented size: %d" % size32seg - print "32bit flat size: %d" % size32flat - - return locs16, locs32seg, locs32flat - - -###################################################################### -# Linker script output -###################################################################### - -# Write LD script includes for the given cross references -def outXRefs(xrefs, finallocs, delta=0): - out = "" - for symbol, (fileid, section, addr) in xrefs.items(): - if fileid < 2: - addr += delta - out += "%s = 0x%x ;\n" % (symbol, finallocs[(fileid, section)] + addr) - return out - -# Write LD script includes for the given sections using relative offsets -def outRelSections(locs, startsym): - out = "" - for addr, sectioninfo in locs: - size, align, name = sectioninfo - out += ". = ( 0x%x - %s ) ;\n" % (addr, startsym) - if name == '.rodata.str1.1': - out += "_rodata = . ;\n" - out += "*(%s)\n" % (name,) - return out - -# Layout the 32bit segmented code. This places the code as high as possible. -def writeLinkerScripts(locs16, locs32seg, locs32flat - , xref16, xref32seg, xref32flat - , out16, out32seg, out32flat): - # Index to final location for each section - # finallocs[(fileid, section)] = addr - finallocs = {} - for fileid, locs in ((0, locs16), (1, locs32seg), (2, locs32flat)): - for addr, sectioninfo in locs: - finallocs[(fileid, sectioninfo[2])] = addr - - # Write 16bit linker script - code16_start = locs16[0][0] - output = open(out16, 'wb') - output.write(COMMONHEADER + outXRefs(xref16, finallocs) + """ - code16_start = 0x%x ; - .text16 code16_start : { -""" % (code16_start) - + outRelSections(locs16, 'code16_start') - + """ - } -""" - + COMMONTRAILER) - output.close() - - # Write 32seg linker script - code32seg_start = code16_start - if locs32seg: - code32seg_start = locs32seg[0][0] - output = open(out32seg, 'wb') - output.write(COMMONHEADER + outXRefs(xref32seg, finallocs) + """ - code32seg_start = 0x%x ; - .text32seg code32seg_start : { -""" % (code32seg_start) - + outRelSections(locs32seg, 'code32seg_start') - + """ - } -""" - + COMMONTRAILER) - output.close() - - # Write 32flat linker script - output = open(out32flat, 'wb') - output.write(COMMONHEADER - + outXRefs(xref32flat, finallocs, BUILD_BIOS_ADDR) + """ - code32flat_start = 0x%x ; - .text code32flat_start : { -""" % (locs32flat[0][0]) - + outRelSections(locs32flat, 'code32flat_start') - + """ - . = ( 0x%x - code32flat_start ) ; - *(.text32seg) - . = ( 0x%x - code32flat_start ) ; - *(.text16) - code32flat_end = ABSOLUTE(.) ; - } :text -""" % (code32seg_start + BUILD_BIOS_ADDR, code16_start + BUILD_BIOS_ADDR) - + COMMONTRAILER - + """ -ENTRY(post32) -PHDRS -{ - text PT_LOAD AT ( code32flat_start ) ; -} -""") - output.close() - - -###################################################################### -# Section garbage collection -###################################################################### - -# Find and keep the section associated with a symbol (if available). -def keepsymbol(symbol, infos, pos, callerpos=None): - addr, section = infos[pos][1].get(symbol, (None, None)) - if section is None or '*' in section or section[:9] == '.discard.': - return -1 - if callerpos is not None and symbol not in infos[callerpos][4]: - # This symbol reference is a cross section reference (an xref). - # xref[symbol] = (fileid, section, addr) - infos[callerpos][4][symbol] = (pos, section, addr) - keepsection(section, infos, pos) - return 0 - -# Note required section, and recursively set all referenced sections -# as required. -def keepsection(name, infos, pos=0): - if name in infos[pos][3]: - # Already kept - nothing to do. - return - infos[pos][3].append(name) - relocs = infos[pos][2].get(name) - if relocs is None: - return - # Keep all sections that this section points to - for symbol in relocs: - ret = keepsymbol(symbol, infos, pos) - if not ret: - continue - # Not in primary sections - it may be a cross 16/32 reference - ret = keepsymbol(symbol, infos, (pos+1)%3, pos) - if not ret: - continue - ret = keepsymbol(symbol, infos, (pos+2)%3, pos) - if not ret: - continue - -# Return a list of kept sections. -def getSectionsList(sections, names): - return [i for i in sections if i[2] in names] - -# Determine which sections are actually referenced and need to be -# placed into the output file. -def gc(info16, info32seg, info32flat): - # infos = ((sections, symbols, relocs, keep sections, xrefs), ...) - infos = ((info16[0], info16[1], info16[2], [], {}), - (info32seg[0], info32seg[1], info32seg[2], [], {}), - (info32flat[0], info32flat[1], info32flat[2], [], {})) - # Start by keeping sections that are globally visible. - for size, align, section in info16[0]: - if section[:11] == '.fixedaddr.' or '.export.' in section: - keepsection(section, infos) - keepsymbol('post32', infos, 0, 2) - # Return sections found. - keep16 = getSectionsList(info16[0], infos[0][3]), infos[0][4] - keep32seg = getSectionsList(info32seg[0], infos[1][3]), infos[1][4] - keep32flat = getSectionsList(info32flat[0], infos[2][3]), infos[2][4] - return keep16, keep32seg, keep32flat - - -###################################################################### -# Startup and input parsing -###################################################################### - -# Read in output from objdump -def parseObjDump(file): - # sections = [(size, align, section), ...] - sections = [] - # symbols[symbol] = (addr, section) - symbols = {} - # relocs[section] = [symbol, ...] - relocs = {} - - state = None - for line in file.readlines(): - line = line.rstrip() - if line == 'Sections:': - state = 'section' - continue - if line == 'SYMBOL TABLE:': - state = 'symbol' - continue - if line[:24] == 'RELOCATION RECORDS FOR [': - state = 'reloc' - relocsection = line[24:-2] - continue - - if state == 'section': - try: - idx, name, size, vma, lma, fileoff, align = line.split() - if align[:3] != '2**': - continue - sections.append((int(size, 16), 2**int(align[3:]), name)) - except: - pass - continue - if state == 'symbol': - try: - section, size, symbol = line[17:].split() - size = int(size, 16) - addr = int(line[:8], 16) - symbols[symbol] = addr, section - except: - pass - continue - if state == 'reloc': - try: - off, type, symbol = line.split() - off = int(off, 16) - relocs.setdefault(relocsection, []).append(symbol) - except: - pass - return sections, symbols, relocs - -def main(): - # Get output name - in16, in32seg, in32flat, out16, out32seg, out32flat = sys.argv[1:] - - # Read in the objdump information - infile16 = open(in16, 'rb') - infile32seg = open(in32seg, 'rb') - infile32flat = open(in32flat, 'rb') - - # infoX = (sections, symbols, relocs) - info16 = parseObjDump(infile16) - info32seg = parseObjDump(infile32seg) - info32flat = parseObjDump(infile32flat) - - # Figure out which sections to keep. - # keepX = (sections, xrefs) - keep16, keep32seg, keep32flat = gc(info16, info32seg, info32flat) - - # Determine the final memory locations of each kept section. - # locsX = [(addr, sectioninfo), ...] - locs16, locs32seg, locs32flat = doLayout( - keep16[0], keep32seg[0], keep32flat[0]) - - # Write out linker script files. - writeLinkerScripts(locs16, locs32seg, locs32flat - , keep16[1], keep32seg[1], keep32flat[1] - , out16, out32seg, out32flat) - -if __name__ == '__main__': - main() diff --git a/roms/seabios/tools/readserial.py b/roms/seabios/tools/readserial.py deleted file mode 100644 index 505c014..0000000 --- a/roms/seabios/tools/readserial.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env python -# Script that can read from a serial device and show timestamps. -# -# Copyright (C) 2009 Kevin O'Connor -# -# This file may be distributed under the terms of the GNU GPLv3 license. - -# Usage: -# tools/readserial.py /dev/ttyUSB0 115200 - -import sys -import time -import select -import optparse - -# Reset time counter after this much idle time. -RESTARTINTERVAL = 60 -# Alter timing reports based on how much time would be spent writing -# to serial. -ADJUSTBAUD = 1 -# Number of bits in a transmitted byte - 8N1 is 1 start bit + 8 data -# bits + 1 stop bit. -BITSPERBYTE = 10 - -def readserial(infile, logfile, baudrate): - lasttime = 0 - byteadjust = 0.0 - if ADJUSTBAUD: - byteadjust = float(BITSPERBYTE) / baudrate - while 1: - # Read data - try: - res = select.select([infile, sys.stdin], [], []) - except KeyboardInterrupt: - sys.stdout.write("\n") - break - if sys.stdin in res[0]: - # Got keyboard input - force reset on next serial input - sys.stdin.read(1) - lasttime = 0 - if len(res[0]) == 1: - continue - d = infile.read(4096) - if not d: - break - datatime = time.time() - - datatime -= len(d) * byteadjust - - # Reset start time if no data for some time - if datatime - lasttime > RESTARTINTERVAL: - starttime = datatime - charcount = 0 - isnewline = 1 - msg = "\n\n======= %s (adjust=%d)\n" % ( - time.asctime(time.localtime(datatime)), ADJUSTBAUD) - sys.stdout.write(msg) - logfile.write(msg) - lasttime = datatime - - # Translate unprintable chars; add timestamps - out = "" - for c in d: - if isnewline: - delta = datatime - starttime - (charcount * byteadjust) - out += "%06.3f: " % delta - isnewline = 0 - oc = ord(c) - charcount += 1 - datatime += byteadjust - if oc == 0x0d: - continue - if oc == 0x00: - out += "<00>\n" - isnewline = 1 - continue - if oc == 0x0a: - out += "\n" - isnewline = 1 - continue - if oc < 0x20 or oc >= 0x7f and oc != 0x09: - out += "<%02x>" % oc - continue - out += c - - sys.stdout.write(out) - sys.stdout.flush() - logfile.write(out) - logfile.flush() - -def main(): - usage = "%prog [options] [ []]" - opts = optparse.OptionParser(usage) - opts.add_option("-f", "--file", - action="store_false", dest="serial", default=True, - help="read from file instead of serialdevice") - opts.add_option("-n", "--no-adjust", - action="store_false", dest="adjustbaud", default=True, - help="don't adjust times by serial rate") - options, args = opts.parse_args() - serialport = 0 - baud = 115200 - if len(args) > 2: - opts.error("Too many arguments") - if len(args) > 0: - serialport = args[0] - if len(args) > 1: - baud = int(args[1]) - global ADJUSTBAUD - ADJUSTBAUD=options.adjustbaud - - if options.serial: - # Read from serial port - import serial - ser = serial.Serial(serialport, baud, timeout=0) - else: - # Read from a file - ser = open(serialport, 'rb') - import fcntl - import os - fcntl.fcntl(ser, fcntl.F_SETFL - , fcntl.fcntl(ser, fcntl.F_GETFL) | os.O_NONBLOCK) - - logname = time.strftime("seriallog-%Y%m%d_%H%M%S.log") - f = open(logname, 'wb') - readserial(ser, f, baud) - -if __name__ == '__main__': - main() diff --git a/roms/seabios/tools/test-gcc.sh b/roms/seabios/tools/test-gcc.sh deleted file mode 100644 index ce3497b..0000000 --- a/roms/seabios/tools/test-gcc.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh -# Script to test if gcc "-fwhole-program" works properly. - -mkdir -p out -TMPFILE1=out/tmp_testcompile1.c -TMPFILE1o=out/tmp_testcompile1.o -TMPFILE2=out/tmp_testcompile2.c -TMPFILE2o=out/tmp_testcompile2.o -TMPFILE3o=out/tmp_testcompile3.o - -# Test for "-fwhole-program". Older versions of gcc (pre v4.1) don't -# support the whole-program optimization - detect that. -$CC -fwhole-program -S -o /dev/null -xc /dev/null > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo " Working around no -fwhole-program" > /dev/fd/2 - echo 2 - exit 0 -fi - -# Test if "visible" variables and functions are marked global. On -# OpenSuse 10.3 "visible" variables declared with "extern" first -# aren't marked as global in the resulting assembler. On Ubuntu 7.10 -# "visible" functions aren't marked as global in the resulting -# assembler. -cat - > $TMPFILE1 < /dev/null 2>&1 -cat - > $TMPFILE2 < /dev/null 2>&1 -$CC -nostdlib -Os $TMPFILE1o $TMPFILE2o -o $TMPFILE3o > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo " Working around non-functional -fwhole-program" > /dev/fd/2 - echo 2 - exit 0 -fi - -# Test if "-combine" works. On Ubuntu 8.04 the compiler doesn't work -# correctly with combine and the "struct bregs" register due to the -# anonymous unions and structs. On Fedora Core 12 the compiler throws -# an internal compiler error when multiple files access global -# variables with debugging enabled. -cat - > $TMPFILE1 <v=0; -} -EOF -cat - > $TMPFILE2 < /dev/null 2>&1 -if [ $? -eq 0 ]; then - echo 0 -else - echo " Working around non-functional -combine" > /dev/fd/2 - echo 1 -fi - -# Also, on several compilers, -combine fails if code is emitted with a -# reference to an extern variable that is later found to be externally -# visible - the compiler does not mark those variables as global. -# This is being worked around by ordering the compile objects to avoid -# this case. - -# Also, the Ubuntu 8.04 compiler has a bug causing corruption when the -# "ebp" register is clobberred in an "asm" statement. The code has -# been modified to not clobber "ebp" - no test is available yet. - -rm -f $TMPFILE1 $TMPFILE1o $TMPFILE2 $TMPFILE2o $TMPFILE3o diff --git a/roms/seabios/tools/transdump.py b/roms/seabios/tools/transdump.py deleted file mode 100644 index 4caaeb7..0000000 --- a/roms/seabios/tools/transdump.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python - -# This script is useful for taking the output of memdump() and -# converting it back into binary output. This can be useful, for -# example, when one wants to push that data into other tools like -# objdump or hexdump. -# -# (C) Copyright 2010 Kevin O'Connor -# -# This file may be distributed under the terms of the GNU GPLv3 license. - -import sys -import struct - -def unhex(str): - return int(str, 16) - -def parseMem(filehdl): - mem = [] - for line in filehdl: - parts = line.split(':') - if len(parts) < 2: - continue - try: - vaddr = unhex(parts[0]) - parts = parts[1].split() - mem.extend([unhex(v) for v in parts]) - except ValueError: - continue - return mem - -def printUsage(): - sys.stderr.write("Usage:\n %s \n" - % (sys.argv[0],)) - sys.exit(1) - -def main(): - if len(sys.argv) != 2: - printUsage() - filename = sys.argv[1] - if filename == '-': - filehdl = sys.stdin - else: - filehdl = open(filename, 'r') - mem = parseMem(filehdl) - for i in mem: - sys.stdout.write(struct.pack(" -// Copyright (c) 2004 Makoto Suzuki (suzu) -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "vgatables.h" // cirrus_init -#include "biosvar.h" // GET_GLOBAL -#include "util.h" // dprintf - -struct cirrus_mode_s { - /* + 0 */ - u16 mode; - u16 width; - u16 height; - u16 depth; - /* + 8 */ - u16 hidden_dac; /* 0x3c6 */ - u16 *seq; /* 0x3c4 */ - u16 *graph; /* 0x3ce */ - u16 *crtc; /* 0x3d4 */ - /* +16 */ - u8 bitsperpixel; - u8 vesacolortype; - u8 vesaredmask; - u8 vesaredpos; - u8 vesagreenmask; - u8 vesagreenpos; - u8 vesabluemask; - u8 vesabluepos; - /* +24 */ - u8 vesareservedmask; - u8 vesareservedpos; -}; - -/* VGA */ -static u16 cseq_vga[] VAR16 = {0x0007,0xffff}; -static u16 cgraph_vga[] VAR16 = {0x0009,0x000a,0x000b,0xffff}; -static u16 ccrtc_vga[] VAR16 = {0x001a,0x001b,0x001d,0xffff}; - -/* extensions */ -static u16 cgraph_svgacolor[] VAR16 = { - 0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08, - 0x0009,0x000a,0x000b, - 0xffff -}; -/* 640x480x8 */ -static u16 cseq_640x480x8[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, - 0x580b,0x580c,0x580d,0x580e, - 0x0412,0x0013,0x2017, - 0x331b,0x331c,0x331d,0x331e, - 0xffff -}; -static u16 ccrtc_640x480x8[] VAR16 = { - 0x2c11, - 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, - 0x4009,0x000c,0x000d, - 0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18, - 0x001a,0x221b,0x001d, - 0xffff -}; -/* 640x480x16 */ -static u16 cseq_640x480x16[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, - 0x580b,0x580c,0x580d,0x580e, - 0x0412,0x0013,0x2017, - 0x331b,0x331c,0x331d,0x331e, - 0xffff -}; -static u16 ccrtc_640x480x16[] VAR16 = { - 0x2c11, - 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, - 0x4009,0x000c,0x000d, - 0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18, - 0x001a,0x221b,0x001d, - 0xffff -}; -/* 640x480x24 */ -static u16 cseq_640x480x24[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, - 0x580b,0x580c,0x580d,0x580e, - 0x0412,0x0013,0x2017, - 0x331b,0x331c,0x331d,0x331e, - 0xffff -}; -static u16 ccrtc_640x480x24[] VAR16 = { - 0x2c11, - 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, - 0x4009,0x000c,0x000d, - 0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18, - 0x001a,0x321b,0x001d, - 0xffff -}; -/* 800x600x8 */ -static u16 cseq_800x600x8[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, - 0x230b,0x230c,0x230d,0x230e, - 0x0412,0x0013,0x2017, - 0x141b,0x141c,0x141d,0x141e, - 0xffff -}; -static u16 ccrtc_800x600x8[] VAR16 = { - 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, - 0x6009,0x000c,0x000d, - 0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18, - 0x001a,0x221b,0x001d, - 0xffff -}; -/* 800x600x16 */ -static u16 cseq_800x600x16[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, - 0x230b,0x230c,0x230d,0x230e, - 0x0412,0x0013,0x2017, - 0x141b,0x141c,0x141d,0x141e, - 0xffff -}; -static u16 ccrtc_800x600x16[] VAR16 = { - 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, - 0x6009,0x000c,0x000d, - 0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18, - 0x001a,0x221b,0x001d, - 0xffff -}; -/* 800x600x24 */ -static u16 cseq_800x600x24[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, - 0x230b,0x230c,0x230d,0x230e, - 0x0412,0x0013,0x2017, - 0x141b,0x141c,0x141d,0x141e, - 0xffff -}; -static u16 ccrtc_800x600x24[] VAR16 = { - 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, - 0x6009,0x000c,0x000d, - 0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18, - 0x001a,0x321b,0x001d, - 0xffff -}; -/* 1024x768x8 */ -static u16 cseq_1024x768x8[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, - 0x760b,0x760c,0x760d,0x760e, - 0x0412,0x0013,0x2017, - 0x341b,0x341c,0x341d,0x341e, - 0xffff -}; -static u16 ccrtc_1024x768x8[] VAR16 = { - 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, - 0x6009,0x000c,0x000d, - 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, - 0x001a,0x221b,0x001d, - 0xffff -}; -/* 1024x768x16 */ -static u16 cseq_1024x768x16[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, - 0x760b,0x760c,0x760d,0x760e, - 0x0412,0x0013,0x2017, - 0x341b,0x341c,0x341d,0x341e, - 0xffff -}; -static u16 ccrtc_1024x768x16[] VAR16 = { - 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, - 0x6009,0x000c,0x000d, - 0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18, - 0x001a,0x321b,0x001d, - 0xffff -}; -/* 1024x768x24 */ -static u16 cseq_1024x768x24[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, - 0x760b,0x760c,0x760d,0x760e, - 0x0412,0x0013,0x2017, - 0x341b,0x341c,0x341d,0x341e, - 0xffff -}; -static u16 ccrtc_1024x768x24[] VAR16 = { - 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, - 0x6009,0x000c,0x000d, - 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, - 0x001a,0x321b,0x001d, - 0xffff -}; -/* 1280x1024x8 */ -static u16 cseq_1280x1024x8[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, - 0x760b,0x760c,0x760d,0x760e, - 0x0412,0x0013,0x2017, - 0x341b,0x341c,0x341d,0x341e, - 0xffff -}; -static u16 ccrtc_1280x1024x8[] VAR16 = { - 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, - 0x6009,0x000c,0x000d, - 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, - 0x001a,0x221b,0x001d, - 0xffff -}; -/* 1280x1024x16 */ -static u16 cseq_1280x1024x16[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, - 0x760b,0x760c,0x760d,0x760e, - 0x0412,0x0013,0x2017, - 0x341b,0x341c,0x341d,0x341e, - 0xffff -}; -static u16 ccrtc_1280x1024x16[] VAR16 = { - 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, - 0x6009,0x000c,0x000d, - 0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18, - 0x001a,0x321b,0x001d, - 0xffff -}; - -/* 1600x1200x8 */ -static u16 cseq_1600x1200x8[] VAR16 = { - 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, - 0x760b,0x760c,0x760d,0x760e, - 0x0412,0x0013,0x2017, - 0x341b,0x341c,0x341d,0x341e, - 0xffff -}; -static u16 ccrtc_1600x1200x8[] VAR16 = { - 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, - 0x6009,0x000c,0x000d, - 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, - 0x001a,0x221b,0x001d, - 0xffff -}; - -static struct cirrus_mode_s cirrus_modes[] VAR16 = { - {0x5f,640,480,8,0x00, - cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x64,640,480,16,0xe1, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x66,640,480,15,0xf0, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 6,5,10,5,5,5,0,1,15}, - {0x71,640,480,24,0xe5, - cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, - 6,8,16,8,8,8,0,0,0}, - - {0x5c,800,600,8,0x00, - cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x65,800,600,16,0xe1, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x67,800,600,15,0xf0, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 6,5,10,5,5,5,0,1,15}, - - {0x60,1024,768,8,0x00, - cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x74,1024,768,16,0xe1, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x68,1024,768,15,0xf0, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 6,5,10,5,5,5,0,1,15}, - - {0x78,800,600,24,0xe5, - cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, - 6,8,16,8,8,8,0,0,0}, - {0x79,1024,768,24,0xe5, - cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, - 6,8,16,8,8,8,0,0,0}, - - {0x6d,1280,1024,8,0x00, - cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x69,1280,1024,15,0xf0, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 6,5,10,5,5,5,0,1,15}, - {0x75,1280,1024,16,0xe1, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 6,5,11,6,5,5,0,0,0}, - - {0x7b,1600,1200,8,0x00, - cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, - 4,0,0,0,0,0,0,0,0}, - - {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, - 0xff,0,0,0,0,0,0,0,0}, -}; - -static struct cirrus_mode_s * -cirrus_get_modeentry(u8 mode) -{ - struct cirrus_mode_s *table_g = cirrus_modes; - while (table_g < &cirrus_modes[ARRAY_SIZE(cirrus_modes)]) { - u16 tmode = GET_GLOBAL(table_g->mode); - if (tmode == mode) - return table_g; - table_g++; - } - return NULL; -} - -static void -cirrus_switch_mode_setregs(u16 *data, u16 port) -{ - for (;;) { - u16 val = GET_GLOBAL(*data); - if (val == 0xffff) - return; - outw(val, port); - data++; - } -} - -static u16 -cirrus_get_crtc(void) -{ - if (inb(VGAREG_READ_MISC_OUTPUT) & 1) - return VGAREG_VGA_CRTC_ADDRESS; - return VGAREG_MDA_CRTC_ADDRESS; -} - -static void -cirrus_switch_mode(struct cirrus_mode_s *table) -{ - // Unlock cirrus special - outw(0x1206, VGAREG_SEQU_ADDRESS); - cirrus_switch_mode_setregs(GET_GLOBAL(table->seq), VGAREG_SEQU_ADDRESS); - cirrus_switch_mode_setregs(GET_GLOBAL(table->graph), VGAREG_GRDC_ADDRESS); - cirrus_switch_mode_setregs(GET_GLOBAL(table->crtc), cirrus_get_crtc()); - - outb(0x00, VGAREG_PEL_MASK); - inb(VGAREG_PEL_MASK); - inb(VGAREG_PEL_MASK); - inb(VGAREG_PEL_MASK); - inb(VGAREG_PEL_MASK); - outb(GET_GLOBAL(table->hidden_dac), VGAREG_PEL_MASK); - outb(0xff, VGAREG_PEL_MASK); - - u8 vesacolortype = GET_GLOBAL(table->vesacolortype); - u8 v = vgahw_get_single_palette_reg(0x10) & 0xfe; - if (vesacolortype == 3) - v |= 0x41; - else if (vesacolortype) - v |= 0x01; - vgahw_set_single_palette_reg(0x10, v); -} - -void -cirrus_set_video_mode(u8 mode) -{ - dprintf(1, "cirrus mode %d\n", mode); - SET_BDA(vbe_mode, 0); - struct cirrus_mode_s *table_g = cirrus_get_modeentry(mode & 0x7f); - if (table_g) { - //XXX - cirrus_set_video_mode_extended(table); - return; - } - table_g = cirrus_get_modeentry(0xfe); - cirrus_switch_mode(table_g); - dprintf(1, "cirrus mode switch regular\n"); -} - -static int -cirrus_check(void) -{ - outw(0x9206, VGAREG_SEQU_ADDRESS); - return inb(VGAREG_SEQU_DATA) == 0x12; -} - -void -cirrus_init(void) -{ - dprintf(1, "cirrus init\n"); - if (! cirrus_check()) - return; - dprintf(1, "cirrus init 2\n"); - - // memory setup - outb(0x0f, VGAREG_SEQU_ADDRESS); - u8 v = inb(VGAREG_SEQU_DATA); - outb(((v & 0x18) << 8) | 0x0a, VGAREG_SEQU_ADDRESS); - // set vga mode - outw(0x0007, VGAREG_SEQU_ADDRESS); - // reset bitblt - outw(0x0431, VGAREG_GRDC_ADDRESS); - outw(0x0031, VGAREG_GRDC_ADDRESS); -} diff --git a/roms/seabios/vgasrc/vga.c b/roms/seabios/vgasrc/vga.c deleted file mode 100644 index d734e23..0000000 --- a/roms/seabios/vgasrc/vga.c +++ /dev/null @@ -1,1387 +0,0 @@ -// VGA bios implementation -// -// Copyright (C) 2009 Kevin O'Connor -// Copyright (C) 2001-2008 the LGPL VGABios developers Team -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - - -// TODO: -// * review correctness of converted asm by comparing with RBIL -// -// * convert vbe/clext code - -#include "bregs.h" // struct bregs -#include "biosvar.h" // GET_BDA -#include "util.h" // memset -#include "vgatables.h" // find_vga_entry - -// XXX -#define CONFIG_VBE 0 -#define CONFIG_CIRRUS 0 - -// XXX -#define DEBUG_VGA_POST 1 -#define DEBUG_VGA_10 3 - -#define SET_VGA(var, val) SET_FARVAR(get_global_seg(), (var), (val)) - - -/**************************************************************** - * Helper functions - ****************************************************************/ - -static inline void -call16_vgaint(u32 eax, u32 ebx) -{ - asm volatile( - "int $0x10\n" - "cli\n" - "cld" - : - : "a"(eax), "b"(ebx) - : "cc", "memory"); -} - -static void -perform_gray_scale_summing(u16 start, u16 count) -{ - vgahw_screen_disable(); - int i; - for (i = start; i < start+count; i++) { - u8 rgb[3]; - vgahw_get_dac_regs(GET_SEG(SS), rgb, i, 1); - - // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue ) - u16 intensity = ((77 * rgb[0] + 151 * rgb[1] + 28 * rgb[2]) + 0x80) >> 8; - if (intensity > 0x3f) - intensity = 0x3f; - - vgahw_set_dac_regs(GET_SEG(SS), rgb, i, 1); - } - vgahw_screen_enable(); -} - -static void -set_cursor_shape(u8 start, u8 end) -{ - start &= 0x3f; - end &= 0x1f; - - u16 curs = (start << 8) + end; - SET_BDA(cursor_type, curs); - - u8 modeset_ctl = GET_BDA(modeset_ctl); - u16 cheight = GET_BDA(char_height); - if ((modeset_ctl & 0x01) && (cheight > 8) && (end < 8) && (start < 0x20)) { - if (end != (start + 1)) - start = ((start + 1) * cheight / 8) - 1; - else - start = ((end + 1) * cheight / 8) - 2; - end = ((end + 1) * cheight / 8) - 1; - } - vgahw_set_cursor_shape(start, end); -} - -static u16 -get_cursor_shape(u8 page) -{ - if (page > 7) - return 0; - // FIXME should handle VGA 14/16 lines - return GET_BDA(cursor_type); -} - -static void -set_cursor_pos(struct cursorpos cp) -{ - // Should not happen... - if (cp.page > 7) - return; - - // Bios cursor pos - SET_BDA(cursor_pos[cp.page], (cp.y << 8) | cp.x); - - // Set the hardware cursor - u8 current = GET_BDA(video_page); - if (cp.page != current) - return; - - // Get the dimensions - u16 nbcols = GET_BDA(video_cols); - u16 nbrows = GET_BDA(video_rows) + 1; - - // Calculate the address knowing nbcols nbrows and page num - u16 address = (SCREEN_IO_START(nbcols, nbrows, cp.page) - + cp.x + cp.y * nbcols); - - vgahw_set_cursor_pos(address); -} - -static struct cursorpos -get_cursor_pos(u8 page) -{ - if (page == 0xff) - // special case - use current page - page = GET_BDA(video_page); - if (page > 7) { - struct cursorpos cp = { 0, 0, 0xfe }; - return cp; - } - // FIXME should handle VGA 14/16 lines - u16 xy = GET_BDA(cursor_pos[page]); - struct cursorpos cp = {xy, xy>>8, page}; - return cp; -} - -static void -set_active_page(u8 page) -{ - if (page > 7) - return; - - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // Get pos curs pos for the right page - struct cursorpos cp = get_cursor_pos(page); - - u16 address; - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { - // Get the dimensions - u16 nbcols = GET_BDA(video_cols); - u16 nbrows = GET_BDA(video_rows) + 1; - - // Calculate the address knowing nbcols nbrows and page num - address = SCREEN_MEM_START(nbcols, nbrows, page); - SET_BDA(video_pagestart, address); - - // Start address - address = SCREEN_IO_START(nbcols, nbrows, page); - } else { - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - address = page * GET_GLOBAL(vparam_g->slength); - } - - vgahw_set_active_page(address); - - // And change the BIOS page - SET_BDA(video_page, page); - - dprintf(1, "Set active page %02x address %04x\n", page, address); - - // Display the cursor, now the page is active - set_cursor_pos(cp); -} - -static void -set_scan_lines(u8 lines) -{ - vgahw_set_scan_lines(lines); - if (lines == 8) - set_cursor_shape(0x06, 0x07); - else - set_cursor_shape(lines - 4, lines - 3); - SET_BDA(char_height, lines); - u16 vde = vgahw_get_vde(); - u8 rows = vde / lines; - SET_BDA(video_rows, rows - 1); - u16 cols = GET_BDA(video_cols); - SET_BDA(video_pagesize, rows * cols * 2); -} - - -/**************************************************************** - * Character writing - ****************************************************************/ - -// Scroll the screen one line. This function is designed to be called -// tail-recursive to reduce stack usage. -static void noinline -scroll_one(u16 nbrows, u16 nbcols, u8 page) -{ - struct cursorpos ul = {0, 0, page}; - struct cursorpos lr = {nbcols-1, nbrows-1, page}; - vgafb_scroll(1, -1, ul, lr); -} - -// Write a character to the screen at a given position. Implement -// special characters and scroll the screen if necessary. -static void -write_teletype(struct cursorpos *pcp, struct carattr ca) -{ - struct cursorpos cp = *pcp; - - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - switch (ca.car) { - case 7: - //FIXME should beep - break; - case 8: - if (cp.x > 0) - cp.x--; - break; - case '\r': - cp.x = 0; - break; - case '\n': - cp.y++; - break; - case '\t': - do { - struct carattr dummyca = {' ', ca.attr, ca.use_attr}; - vgafb_write_char(cp, dummyca); - cp.x++; - } while (cp.x < nbcols && cp.x % 8); - break; - default: - vgafb_write_char(cp, ca); - cp.x++; - } - - // Do we need to wrap ? - if (cp.x == nbcols) { - cp.x = 0; - cp.y++; - } - // Do we need to scroll ? - if (cp.y < nbrows) { - *pcp = cp; - return; - } - // Scroll screen - cp.y--; - *pcp = cp; - scroll_one(nbrows, nbcols, cp.page); -} - -// Write out a buffer of alternating characters and attributes. -static void -write_attr_string(struct cursorpos *pcp, u16 count, u16 seg, u8 *offset_far) -{ - while (count--) { - u8 car = GET_FARVAR(seg, *offset_far); - offset_far++; - u8 attr = GET_FARVAR(seg, *offset_far); - offset_far++; - - struct carattr ca = {car, attr, 1}; - write_teletype(pcp, ca); - } -} - -// Write out a buffer of characters. -static void -write_string(struct cursorpos *pcp, u8 attr, u16 count, u16 seg, u8 *offset_far) -{ - while (count--) { - u8 car = GET_FARVAR(seg, *offset_far); - offset_far++; - - struct carattr ca = {car, attr, 1}; - write_teletype(pcp, ca); - } -} - - -/**************************************************************** - * Save and restore bda state - ****************************************************************/ - -static void -save_bda_state(u16 seg, struct saveBDAstate *info) -{ - SET_FARVAR(seg, info->video_mode, GET_BDA(video_mode)); - SET_FARVAR(seg, info->video_cols, GET_BDA(video_cols)); - SET_FARVAR(seg, info->video_pagesize, GET_BDA(video_pagesize)); - SET_FARVAR(seg, info->crtc_address, GET_BDA(crtc_address)); - SET_FARVAR(seg, info->video_rows, GET_BDA(video_rows)); - SET_FARVAR(seg, info->char_height, GET_BDA(char_height)); - SET_FARVAR(seg, info->video_ctl, GET_BDA(video_ctl)); - SET_FARVAR(seg, info->video_switches, GET_BDA(video_switches)); - SET_FARVAR(seg, info->modeset_ctl, GET_BDA(modeset_ctl)); - SET_FARVAR(seg, info->cursor_type, GET_BDA(cursor_type)); - u16 i; - for (i=0; i<8; i++) - SET_FARVAR(seg, info->cursor_pos[i], GET_BDA(cursor_pos[i])); - SET_FARVAR(seg, info->video_pagestart, GET_BDA(video_pagestart)); - SET_FARVAR(seg, info->video_page, GET_BDA(video_page)); - /* current font */ - SET_FARVAR(seg, info->font0, GET_IVT(0x1f)); - SET_FARVAR(seg, info->font1, GET_IVT(0x43)); -} - -static void -restore_bda_state(u16 seg, struct saveBDAstate *info) -{ - SET_BDA(video_mode, GET_FARVAR(seg, info->video_mode)); - SET_BDA(video_cols, GET_FARVAR(seg, info->video_cols)); - SET_BDA(video_pagesize, GET_FARVAR(seg, info->video_pagesize)); - SET_BDA(crtc_address, GET_FARVAR(seg, info->crtc_address)); - SET_BDA(video_rows, GET_FARVAR(seg, info->video_rows)); - SET_BDA(char_height, GET_FARVAR(seg, info->char_height)); - SET_BDA(video_ctl, GET_FARVAR(seg, info->video_ctl)); - SET_BDA(video_switches, GET_FARVAR(seg, info->video_switches)); - SET_BDA(modeset_ctl, GET_FARVAR(seg, info->modeset_ctl)); - SET_BDA(cursor_type, GET_FARVAR(seg, info->cursor_type)); - u16 i; - for (i = 0; i < 8; i++) - SET_BDA(cursor_pos[i], GET_FARVAR(seg, info->cursor_pos[i])); - SET_BDA(video_pagestart, GET_FARVAR(seg, info->video_pagestart)); - SET_BDA(video_page, GET_FARVAR(seg, info->video_page)); - /* current font */ - SET_IVT(0x1f, GET_FARVAR(seg, info->font0)); - SET_IVT(0x43, GET_FARVAR(seg, info->font1)); -} - - -/**************************************************************** - * VGA int 10 handler - ****************************************************************/ - -// set video mode -static void -handle_1000(struct bregs *regs) -{ - u8 noclearmem = regs->al & 0x80; - u8 mode = regs->al & 0x7f; - - // Set regs->al - if (mode > 7) - regs->al = 0x20; - else if (mode == 6) - regs->al = 0x3f; - else - regs->al = 0x30; - - if (CONFIG_CIRRUS) - cirrus_set_video_mode(mode); - - if (CONFIG_VBE) - if (vbe_has_vbe_display()) - dispi_set_enable(VBE_DISPI_DISABLED); - - // find the entry in the video modes - struct vgamode_s *vmode_g = find_vga_entry(mode); - dprintf(1, "mode search %02x found %p\n", mode, vmode_g); - if (!vmode_g) - return; - - // Read the bios mode set control - u8 modeset_ctl = GET_BDA(modeset_ctl); - - // Then we know the number of lines -// FIXME - - // if palette loading (bit 3 of modeset ctl = 0) - if ((modeset_ctl & 0x08) == 0) { // Set the PEL mask - vgahw_set_pel_mask(GET_GLOBAL(vmode_g->pelmask)); - - // From which palette - u8 *palette_g = GET_GLOBAL(vmode_g->dac); - u16 palsize = GET_GLOBAL(vmode_g->dacsize) / 3; - - // Always 256*3 values - vgahw_set_dac_regs(get_global_seg(), palette_g, 0, palsize); - u16 i; - for (i = palsize; i < 0x0100; i++) { - static u8 rgb[3] VAR16; - vgahw_set_dac_regs(get_global_seg(), rgb, i, 1); - } - - if ((modeset_ctl & 0x02) == 0x02) - perform_gray_scale_summing(0x00, 0x100); - } - - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - vgahw_set_mode(vparam_g); - - if (noclearmem == 0x00) - clear_screen(vmode_g); - - // Set CRTC address VGA or MDA - u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; - if (GET_GLOBAL(vmode_g->memmodel) == MTEXT) - crtc_addr = VGAREG_MDA_CRTC_ADDRESS; - - // Set the BIOS mem - u16 cheight = GET_GLOBAL(vparam_g->cheight); - SET_BDA(video_mode, mode); - SET_BDA(video_cols, GET_GLOBAL(vparam_g->twidth)); - SET_BDA(video_pagesize, GET_GLOBAL(vparam_g->slength)); - SET_BDA(crtc_address, crtc_addr); - SET_BDA(video_rows, GET_GLOBAL(vparam_g->theightm1)); - SET_BDA(char_height, cheight); - SET_BDA(video_ctl, (0x60 | noclearmem)); - SET_BDA(video_switches, 0xF9); - SET_BDA(modeset_ctl, GET_BDA(modeset_ctl) & 0x7f); - - // FIXME We nearly have the good tables. to be reworked - SET_BDA(dcc_index, 0x08); // 8 is VGA should be ok for now - SET_BDA(video_savetable - , SEGOFF(get_global_seg(), (u32)video_save_pointer_table)); - - // FIXME - SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but... - SET_BDA(video_pal, 0x00); // Unavailable on vanilla vga, but... - - // Set cursor shape - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - set_cursor_shape(0x06, 0x07); - // Set cursor pos for page 0..7 - int i; - for (i = 0; i < 8; i++) { - struct cursorpos cp = {0, 0, i}; - set_cursor_pos(cp); - } - - // Set active page 0 - set_active_page(0x00); - - // Write the fonts in memory - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) { - call16_vgaint(0x1104, 0); - call16_vgaint(0x1103, 0); - } - // Set the ints 0x1F and 0x43 - SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8])); - - switch (cheight) { - case 8: - SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8)); - break; - case 14: - SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14)); - break; - case 16: - SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16)); - break; - } -} - -static void -handle_1001(struct bregs *regs) -{ - set_cursor_shape(regs->ch, regs->cl); -} - -static void -handle_1002(struct bregs *regs) -{ - struct cursorpos cp = {regs->dl, regs->dh, regs->bh}; - set_cursor_pos(cp); -} - -static void -handle_1003(struct bregs *regs) -{ - regs->cx = get_cursor_shape(regs->bh); - struct cursorpos cp = get_cursor_pos(regs->bh); - regs->dl = cp.x; - regs->dh = cp.y; -} - -// Read light pen pos (unimplemented) -static void -handle_1004(struct bregs *regs) -{ - debug_stub(regs); - regs->ax = regs->bx = regs->cx = regs->dx = 0; -} - -static void -handle_1005(struct bregs *regs) -{ - set_active_page(regs->al); -} - -static void -verify_scroll(struct bregs *regs, int dir) -{ - u8 page = GET_BDA(video_page); - struct cursorpos ul = {regs->cl, regs->ch, page}; - struct cursorpos lr = {regs->dl, regs->dh, page}; - - u16 nbrows = GET_BDA(video_rows) + 1; - if (lr.y >= nbrows) - lr.y = nbrows - 1; - u16 nbcols = GET_BDA(video_cols); - if (lr.x >= nbcols) - lr.x = nbcols - 1; - - if (ul.x > lr.x || ul.y > lr.y) - return; - - u16 nblines = regs->al; - if (!nblines || nblines > lr.y - ul.y + 1) - nblines = lr.y - ul.y + 1; - - vgafb_scroll(dir * nblines, regs->bh, ul, lr); -} - -static void -handle_1006(struct bregs *regs) -{ - verify_scroll(regs, 1); -} - -static void -handle_1007(struct bregs *regs) -{ - verify_scroll(regs, -1); -} - -static void -handle_1008(struct bregs *regs) -{ - struct carattr ca = vgafb_read_char(get_cursor_pos(regs->bh)); - regs->al = ca.car; - regs->ah = ca.attr; -} - -static void noinline -write_chars(u8 page, struct carattr ca, u16 count) -{ - struct cursorpos cp = get_cursor_pos(page); - while (count--) { - vgafb_write_char(cp, ca); - cp.x++; - } -} - -static void -handle_1009(struct bregs *regs) -{ - struct carattr ca = {regs->al, regs->bl, 1}; - write_chars(regs->bh, ca, regs->cx); -} - -static void -handle_100a(struct bregs *regs) -{ - struct carattr ca = {regs->al, regs->bl, 0}; - write_chars(regs->bh, ca, regs->cx); -} - - -static void -handle_100b00(struct bregs *regs) -{ - vgahw_set_border_color(regs->bl); -} - -static void -handle_100b01(struct bregs *regs) -{ - vgahw_set_palette(regs->bl); -} - -static void -handle_100bXX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_100b(struct bregs *regs) -{ - switch (regs->bh) { - case 0x00: handle_100b00(regs); break; - case 0x01: handle_100b01(regs); break; - default: handle_100bXX(regs); break; - } -} - - -static void -handle_100c(struct bregs *regs) -{ - // XXX - page (regs->bh) is unused - vgafb_write_pixel(regs->al, regs->cx, regs->dx); -} - -static void -handle_100d(struct bregs *regs) -{ - // XXX - page (regs->bh) is unused - regs->al = vgafb_read_pixel(regs->cx, regs->dx); -} - -static void noinline -handle_100e(struct bregs *regs) -{ - // Ralf Brown Interrupt list is WRONG on bh(page) - // We do output only on the current page ! - struct carattr ca = {regs->al, regs->bl, 0}; - struct cursorpos cp = get_cursor_pos(0xff); - write_teletype(&cp, ca); - set_cursor_pos(cp); -} - -static void -handle_100f(struct bregs *regs) -{ - regs->bh = GET_BDA(video_page); - regs->al = GET_BDA(video_mode) | (GET_BDA(video_ctl) & 0x80); - regs->ah = GET_BDA(video_cols); -} - - -static void -handle_101000(struct bregs *regs) -{ - if (regs->bl > 0x14) - return; - vgahw_set_single_palette_reg(regs->bl, regs->bh); -} - -static void -handle_101001(struct bregs *regs) -{ - vgahw_set_overscan_border_color(regs->bh); -} - -static void -handle_101002(struct bregs *regs) -{ - vgahw_set_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); -} - -static void -handle_101003(struct bregs *regs) -{ - vgahw_toggle_intensity(regs->bl); -} - -static void -handle_101007(struct bregs *regs) -{ - if (regs->bl > 0x14) - return; - regs->bh = vgahw_get_single_palette_reg(regs->bl); -} - -static void -handle_101008(struct bregs *regs) -{ - regs->bh = vgahw_get_overscan_border_color(); -} - -static void -handle_101009(struct bregs *regs) -{ - vgahw_get_all_palette_reg(regs->es, (u8*)(regs->dx + 0)); -} - -static void noinline -handle_101010(struct bregs *regs) -{ - u8 rgb[3] = {regs->dh, regs->ch, regs->cl}; - vgahw_set_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); -} - -static void -handle_101012(struct bregs *regs) -{ - vgahw_set_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); -} - -static void -handle_101013(struct bregs *regs) -{ - vgahw_select_video_dac_color_page(regs->bl, regs->bh); -} - -static void noinline -handle_101015(struct bregs *regs) -{ - u8 rgb[3]; - vgahw_get_dac_regs(GET_SEG(SS), rgb, regs->bx, 1); - regs->dh = rgb[0]; - regs->ch = rgb[1]; - regs->cl = rgb[2]; -} - -static void -handle_101017(struct bregs *regs) -{ - vgahw_get_dac_regs(regs->es, (u8*)(regs->dx + 0), regs->bx, regs->cx); -} - -static void -handle_101018(struct bregs *regs) -{ - vgahw_set_pel_mask(regs->bl); -} - -static void -handle_101019(struct bregs *regs) -{ - regs->bl = vgahw_get_pel_mask(); -} - -static void -handle_10101a(struct bregs *regs) -{ - vgahw_read_video_dac_state(®s->bl, ®s->bh); -} - -static void -handle_10101b(struct bregs *regs) -{ - perform_gray_scale_summing(regs->bx, regs->cx); -} - -static void -handle_1010XX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_1010(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101000(regs); break; - case 0x01: handle_101001(regs); break; - case 0x02: handle_101002(regs); break; - case 0x03: handle_101003(regs); break; - case 0x07: handle_101007(regs); break; - case 0x08: handle_101008(regs); break; - case 0x09: handle_101009(regs); break; - case 0x10: handle_101010(regs); break; - case 0x12: handle_101012(regs); break; - case 0x13: handle_101013(regs); break; - case 0x15: handle_101015(regs); break; - case 0x17: handle_101017(regs); break; - case 0x18: handle_101018(regs); break; - case 0x19: handle_101019(regs); break; - case 0x1a: handle_10101a(regs); break; - case 0x1b: handle_10101b(regs); break; - default: handle_1010XX(regs); break; - } -} - - -static void -handle_101100(struct bregs *regs) -{ - vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx - , regs->dx, regs->bl, regs->bh); -} - -static void -handle_101101(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); -} - -static void -handle_101102(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); -} - -static void -handle_101103(struct bregs *regs) -{ - vgahw_set_text_block_specifier(regs->bl); -} - -static void -handle_101104(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); -} - -static void -handle_101110(struct bregs *regs) -{ - vgafb_load_font(regs->es, (void*)(regs->bp+0), regs->cx - , regs->dx, regs->bl, regs->bh); - set_scan_lines(regs->bh); -} - -static void -handle_101111(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont14, 0x100, 0, regs->bl, 14); - set_scan_lines(14); -} - -static void -handle_101112(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont8, 0x100, 0, regs->bl, 8); - set_scan_lines(8); -} - -static void -handle_101114(struct bregs *regs) -{ - vgafb_load_font(get_global_seg(), vgafont16, 0x100, 0, regs->bl, 16); - set_scan_lines(16); -} - -static void -handle_101130(struct bregs *regs) -{ - switch (regs->bh) { - case 0x00: { - struct segoff_s so = GET_IVT(0x1f); - regs->es = so.seg; - regs->bp = so.offset; - break; - } - case 0x01: { - struct segoff_s so = GET_IVT(0x43); - regs->es = so.seg; - regs->bp = so.offset; - break; - } - case 0x02: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont14; - break; - case 0x03: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont8; - break; - case 0x04: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont8 + 128 * 8; - break; - case 0x05: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont14alt; - break; - case 0x06: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont16; - break; - case 0x07: - regs->es = get_global_seg(); - regs->bp = (u32)vgafont16alt; - break; - default: - dprintf(1, "Get font info BH(%02x) was discarded\n", regs->bh); - return; - } - // Set byte/char of on screen font - regs->cx = GET_BDA(char_height) & 0xff; - - // Set Highest char row - regs->dx = GET_BDA(video_rows); -} - -static void -handle_1011XX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_1011(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101100(regs); break; - case 0x01: handle_101101(regs); break; - case 0x02: handle_101102(regs); break; - case 0x03: handle_101103(regs); break; - case 0x04: handle_101104(regs); break; - case 0x10: handle_101110(regs); break; - case 0x11: handle_101111(regs); break; - case 0x12: handle_101112(regs); break; - case 0x14: handle_101114(regs); break; - case 0x30: handle_101130(regs); break; - default: handle_1011XX(regs); break; - } -} - - -static void -handle_101210(struct bregs *regs) -{ - u16 crtc_addr = GET_BDA(crtc_address); - if (crtc_addr == VGAREG_MDA_CRTC_ADDRESS) - regs->bx = 0x0103; - else - regs->bx = 0x0003; - regs->cx = GET_BDA(video_switches) & 0x0f; -} - -static void -handle_101230(struct bregs *regs) -{ - u8 mctl = GET_BDA(modeset_ctl); - u8 vswt = GET_BDA(video_switches); - switch (regs->al) { - case 0x00: - // 200 lines - mctl = (mctl & ~0x10) | 0x80; - vswt = (vswt & ~0x0f) | 0x08; - break; - case 0x01: - // 350 lines - mctl &= ~0x90; - vswt = (vswt & ~0x0f) | 0x09; - break; - case 0x02: - // 400 lines - mctl = (mctl & ~0x80) | 0x10; - vswt = (vswt & ~0x0f) | 0x09; - break; - default: - dprintf(1, "Select vert res (%02x) was discarded\n", regs->al); - break; - } - SET_BDA(modeset_ctl, mctl); - SET_BDA(video_switches, vswt); - regs->al = 0x12; -} - -static void -handle_101231(struct bregs *regs) -{ - u8 v = (regs->al & 0x01) << 3; - u8 mctl = GET_BDA(video_ctl) & ~0x08; - SET_BDA(video_ctl, mctl | v); - regs->al = 0x12; -} - -static void -handle_101232(struct bregs *regs) -{ - vgahw_enable_video_addressing(regs->al); - regs->al = 0x12; -} - -static void -handle_101233(struct bregs *regs) -{ - u8 v = ((regs->al << 1) & 0x02) ^ 0x02; - u8 v2 = GET_BDA(modeset_ctl) & ~0x02; - SET_BDA(modeset_ctl, v | v2); - regs->al = 0x12; -} - -static void -handle_101234(struct bregs *regs) -{ - u8 v = (regs->al & 0x01) ^ 0x01; - u8 v2 = GET_BDA(modeset_ctl) & ~0x01; - SET_BDA(modeset_ctl, v | v2); - regs->al = 0x12; -} - -static void -handle_101235(struct bregs *regs) -{ - debug_stub(regs); - regs->al = 0x12; -} - -static void -handle_101236(struct bregs *regs) -{ - debug_stub(regs); - regs->al = 0x12; -} - -static void -handle_1012XX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_1012(struct bregs *regs) -{ - switch (regs->bl) { - case 0x10: handle_101210(regs); break; - case 0x30: handle_101230(regs); break; - case 0x31: handle_101231(regs); break; - case 0x32: handle_101232(regs); break; - case 0x33: handle_101233(regs); break; - case 0x34: handle_101234(regs); break; - case 0x35: handle_101235(regs); break; - case 0x36: handle_101236(regs); break; - default: handle_1012XX(regs); break; - } - - // XXX - cirrus has 1280, 1281, 1282, 1285, 129a, 12a0, 12a1, 12a2, 12ae -} - - -// Write string -static void noinline -handle_1013(struct bregs *regs) -{ - struct cursorpos cp = {regs->dl, regs->dh, regs->bh}; - // if row=0xff special case : use current cursor position - if (cp.y == 0xff) - cp = get_cursor_pos(cp.page); - u8 flag = regs->al; - if (flag & 2) - write_attr_string(&cp, regs->cx, regs->es, (void*)(regs->bp + 0)); - else - write_string(&cp, regs->bl, regs->cx, regs->es, (void*)(regs->bp + 0)); - - if (flag & 1) - set_cursor_pos(cp); -} - - -static void -handle_101a00(struct bregs *regs) -{ - regs->bx = GET_BDA(dcc_index); - regs->al = 0x1a; -} - -static void -handle_101a01(struct bregs *regs) -{ - SET_BDA(dcc_index, regs->bl); - dprintf(1, "Alternate Display code (%02x) was discarded\n", regs->bh); - regs->al = 0x1a; -} - -static void -handle_101aXX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_101a(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101a00(regs); break; - case 0x01: handle_101a01(regs); break; - default: handle_101aXX(regs); break; - } -} - - -struct funcInfo { - u16 static_functionality_off; - u16 static_functionality_seg; - u8 bda_0x49[30]; - u8 bda_0x84[3]; - u8 dcc_index; - u8 dcc_alt; - u16 colors; - u8 pages; - u8 scan_lines; - u8 primary_char; - u8 secondar_char; - u8 misc; - u8 non_vga_mode; - u8 reserved_2f[2]; - u8 video_mem; - u8 save_flags; - u8 disp_info; - u8 reserved_34[12]; -}; - -static void -handle_101b(struct bregs *regs) -{ - u16 seg = regs->es; - struct funcInfo *info = (void*)(regs->di+0); - memset_far(seg, info, 0, sizeof(*info)); - // Address of static functionality table - SET_FARVAR(seg, info->static_functionality_off, (u32)static_functionality); - SET_FARVAR(seg, info->static_functionality_seg, get_global_seg()); - - // Hard coded copy from BIOS area. Should it be cleaner ? - memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49 - , sizeof(info->bda_0x49)); - memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84 - , sizeof(info->bda_0x84)); - - SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index)); - SET_FARVAR(seg, info->colors, 16); - SET_FARVAR(seg, info->pages, 8); - SET_FARVAR(seg, info->scan_lines, 2); - SET_FARVAR(seg, info->video_mem, 3); - regs->al = 0x1B; -} - - -static void -handle_101c00(struct bregs *regs) -{ - u16 flags = regs->cx; - u16 size = 0; - if (flags & 1) - size += sizeof(struct saveVideoHardware); - if (flags & 2) - size += sizeof(struct saveBDAstate); - if (flags & 4) - size += sizeof(struct saveDACcolors); - regs->bx = size; - regs->al = 0x1c; -} - -static void -handle_101c01(struct bregs *regs) -{ - u16 flags = regs->cx; - u16 seg = regs->es; - void *data = (void*)(regs->bx+0); - if (flags & 1) { - vgahw_save_state(seg, data); - data += sizeof(struct saveVideoHardware); - } - if (flags & 2) { - save_bda_state(seg, data); - data += sizeof(struct saveBDAstate); - } - if (flags & 4) - vgahw_save_dac_state(seg, data); - regs->al = 0x1c; -} - -static void -handle_101c02(struct bregs *regs) -{ - u16 flags = regs->cx; - u16 seg = regs->es; - void *data = (void*)(regs->bx+0); - if (flags & 1) { - vgahw_restore_state(seg, data); - data += sizeof(struct saveVideoHardware); - } - if (flags & 2) { - restore_bda_state(seg, data); - data += sizeof(struct saveBDAstate); - } - if (flags & 4) - vgahw_restore_dac_state(seg, data); - regs->al = 0x1c; -} - -static void -handle_101cXX(struct bregs *regs) -{ - debug_stub(regs); -} - -static void -handle_101c(struct bregs *regs) -{ - switch (regs->al) { - case 0x00: handle_101c00(regs); break; - case 0x01: handle_101c01(regs); break; - case 0x02: handle_101c02(regs); break; - default: handle_101cXX(regs); break; - } -} - - -static void -handle_104f00(struct bregs *regs) -{ - // XXX - vbe_biosfn_return_controller_information(&AX,ES,DI); - // XXX - OR cirrus_vesa_00h -} - -static void -handle_104f01(struct bregs *regs) -{ - // XXX - vbe_biosfn_return_mode_information(&AX,CX,ES,DI); - // XXX - OR cirrus_vesa_01h -} - -static void -handle_104f02(struct bregs *regs) -{ - // XXX - vbe_biosfn_set_mode(&AX,BX,ES,DI); - // XXX - OR cirrus_vesa_02h -} - -static void -handle_104f03(struct bregs *regs) -{ - // XXX - vbe_biosfn_return_current_mode - // XXX - OR cirrus_vesa_03h -} - -static void -handle_104f04(struct bregs *regs) -{ - // XXX - vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX); -} - -static void -handle_104f05(struct bregs *regs) -{ - // XXX - vbe_biosfn_display_window_control - // XXX - OR cirrus_vesa_05h -} - -static void -handle_104f06(struct bregs *regs) -{ - // XXX - vbe_biosfn_set_get_logical_scan_line_length - // XXX - OR cirrus_vesa_06h -} - -static void -handle_104f07(struct bregs *regs) -{ - // XXX - vbe_biosfn_set_get_display_start - // XXX - OR cirrus_vesa_07h -} - -static void -handle_104f08(struct bregs *regs) -{ - // XXX - vbe_biosfn_set_get_dac_palette_format -} - -static void -handle_104f0a(struct bregs *regs) -{ - // XXX - vbe_biosfn_return_protected_mode_interface -} - -static void -handle_104fXX(struct bregs *regs) -{ - debug_stub(regs); - regs->ax = 0x0100; -} - -static void -handle_104f(struct bregs *regs) -{ - if (! CONFIG_VBE || !vbe_has_vbe_display()) { - handle_104fXX(regs); - return; - } - - switch (regs->al) { - case 0x00: handle_104f00(regs); break; - case 0x01: handle_104f01(regs); break; - case 0x02: handle_104f02(regs); break; - case 0x03: handle_104f03(regs); break; - case 0x04: handle_104f04(regs); break; - case 0x05: handle_104f05(regs); break; - case 0x06: handle_104f06(regs); break; - case 0x07: handle_104f07(regs); break; - case 0x08: handle_104f08(regs); break; - case 0x0a: handle_104f0a(regs); break; - default: handle_104fXX(regs); break; - } -} - - -static void -handle_10XX(struct bregs *regs) -{ - debug_stub(regs); -} - -// INT 10h Video Support Service Entry Point -void VISIBLE16 -handle_10(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_10); - switch (regs->ah) { - case 0x00: handle_1000(regs); break; - case 0x01: handle_1001(regs); break; - case 0x02: handle_1002(regs); break; - case 0x03: handle_1003(regs); break; - case 0x04: handle_1004(regs); break; - case 0x05: handle_1005(regs); break; - case 0x06: handle_1006(regs); break; - case 0x07: handle_1007(regs); break; - case 0x08: handle_1008(regs); break; - case 0x09: handle_1009(regs); break; - case 0x0a: handle_100a(regs); break; - case 0x0b: handle_100b(regs); break; - case 0x0c: handle_100c(regs); break; - case 0x0d: handle_100d(regs); break; - case 0x0e: handle_100e(regs); break; - case 0x0f: handle_100f(regs); break; - case 0x10: handle_1010(regs); break; - case 0x11: handle_1011(regs); break; - case 0x12: handle_1012(regs); break; - case 0x13: handle_1013(regs); break; - case 0x1a: handle_101a(regs); break; - case 0x1b: handle_101b(regs); break; - case 0x1c: handle_101c(regs); break; - case 0x4f: handle_104f(regs); break; - default: handle_10XX(regs); break; - } -} - - -/**************************************************************** - * VGA post - ****************************************************************/ - -static void -init_bios_area(void) -{ - // init detected hardware BIOS Area - // set 80x25 color (not clear from RBIL but usual) - u16 eqf = GET_BDA(equipment_list_flags); - SET_BDA(equipment_list_flags, (eqf & 0xffcf) | 0x20); - - // Just for the first int10 find its children - - // the default char height - SET_BDA(char_height, 0x10); - - // Clear the screen - SET_BDA(video_ctl, 0x60); - - // Set the basic screen we have - SET_BDA(video_switches, 0xf9); - - // Set the basic modeset options - SET_BDA(modeset_ctl, 0x51); - - // Set the default MSR - SET_BDA(video_msr, 0x09); -} - -void VISIBLE16 -vga_post(struct bregs *regs) -{ - debug_enter(regs, DEBUG_VGA_POST); - - vgahw_init(); - - init_bios_area(); - - if (CONFIG_VBE) - vbe_init(); - - extern void entry_10(void); - SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10)); - - if (CONFIG_CIRRUS) - cirrus_init(); - - // XXX - clear screen and display info - - // XXX: fill it - SET_VGA(video_save_pointer_table[0], (u32)video_param_table); - SET_VGA(video_save_pointer_table[1], get_global_seg()); - - // Fixup checksum - extern u8 _rom_header_size, _rom_header_checksum; - SET_VGA(_rom_header_checksum, 0); - u8 sum = -checksum_far(get_global_seg(), 0, _rom_header_size * 512); - SET_VGA(_rom_header_checksum, sum); -} diff --git a/roms/seabios/vgasrc/vgaentry.S b/roms/seabios/vgasrc/vgaentry.S deleted file mode 100644 index b99cf6f..0000000 --- a/roms/seabios/vgasrc/vgaentry.S +++ /dev/null @@ -1,48 +0,0 @@ -// Rom layout and bios assembler to C interface. -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - - -/**************************************************************** - * Include of 16bit C code - ****************************************************************/ - - .code16gcc -.include "out/vgaccode.16.s" - -#include "entryfuncs.S" // ENTRY_* - - -/**************************************************************** - * Rom Header - ****************************************************************/ - - .section .rom.header - .global _rom_header, _rom_header_size, _rom_header_checksum -_rom_header: - .word 0xaa55 -_rom_header_size: - .byte 0 -_rom_header_entry: - jmp _optionrom_entry -_rom_header_checksum: - .byte 0 -_rom_header_other: - .space 21 - - -/**************************************************************** - * Entry points - ****************************************************************/ - - DECLFUNC _optionrom_entry -_optionrom_entry: - ENTRY_ARG vga_post - lretw - - DECLFUNC entry_10 -entry_10: - ENTRY_ARG handle_10 - iretw diff --git a/roms/seabios/vgasrc/vgafb.c b/roms/seabios/vgasrc/vgafb.c deleted file mode 100644 index 866f7f8..0000000 --- a/roms/seabios/vgasrc/vgafb.c +++ /dev/null @@ -1,512 +0,0 @@ -// Code for manipulating VGA framebuffers. -// -// Copyright (C) 2009 Kevin O'Connor -// Copyright (C) 2001-2008 the LGPL VGABios developers Team -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "biosvar.h" // GET_BDA -#include "util.h" // memset_far -#include "vgatables.h" // find_vga_entry - - -/**************************************************************** - * Screen scrolling - ****************************************************************/ - -static inline void * -memcpy_stride(u16 seg, void *dst, void *src, int copylen, int stride, int lines) -{ - for (; lines; lines--, dst+=stride, src+=stride) - memcpy_far(seg, dst, seg, src, copylen); - return dst; -} - -static inline void -memset_stride(u16 seg, void *dst, u8 val, int setlen, int stride, int lines) -{ - for (; lines; lines--, dst+=stride) - memset_far(seg, dst, val, setlen); -} - -static inline void -memset16_stride(u16 seg, void *dst, u16 val, int setlen, int stride, int lines) -{ - for (; lines; lines--, dst+=stride) - memset16_far(seg, dst, val, setlen); -} - -static void -scroll_pl4(struct vgamode_s *vmode_g, int nblines, int attr - , struct cursorpos ul, struct cursorpos lr) -{ - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - u8 cheight = GET_GLOBAL(vparam_g->cheight); - int stride = GET_BDA(video_cols); - void *src_far, *dest_far; - if (nblines >= 0) { - dest_far = (void*)(ul.y * cheight * stride + ul.x); - src_far = dest_far + nblines * cheight * stride; - } else { - // Scroll down - nblines = -nblines; - dest_far = (void*)(lr.y * cheight * stride + ul.x); - src_far = dest_far - nblines * cheight * stride; - stride = -stride; - } - int cols = lr.x - ul.x + 1; - int rows = lr.y - ul.y + 1; - if (nblines < rows) { - vgahw_grdc_write(0x05, 0x01); - dest_far = memcpy_stride(SEG_GRAPH, dest_far, src_far, cols, stride - , (rows - nblines) * cheight); - } - if (attr < 0) - attr = 0; - vgahw_grdc_write(0x05, 0x02); - memset_stride(SEG_GRAPH, dest_far, attr, cols, stride, nblines * cheight); - vgahw_grdc_write(0x05, 0x00); -} - -static void -scroll_cga(struct vgamode_s *vmode_g, int nblines, int attr - , struct cursorpos ul, struct cursorpos lr) -{ - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - u8 cheight = GET_GLOBAL(vparam_g->cheight); - u8 bpp = GET_GLOBAL(vmode_g->pixbits); - int stride = GET_BDA(video_cols) * bpp; - void *src_far, *dest_far; - if (nblines >= 0) { - dest_far = (void*)(ul.y * cheight * stride + ul.x * bpp); - src_far = dest_far + nblines * cheight * stride; - } else { - // Scroll down - nblines = -nblines; - dest_far = (void*)(lr.y * cheight * stride + ul.x * bpp); - src_far = dest_far - nblines * cheight * stride; - stride = -stride; - } - int cols = (lr.x - ul.x + 1) * bpp; - int rows = lr.y - ul.y + 1; - if (nblines < rows) { - memcpy_stride(SEG_CTEXT, dest_far + 0x2000, src_far + 0x2000, cols - , stride, (rows - nblines) * cheight / 2); - dest_far = memcpy_stride(SEG_CTEXT, dest_far, src_far, cols - , stride, (rows - nblines) * cheight / 2); - } - if (attr < 0) - attr = 0; - memset_stride(SEG_CTEXT, dest_far + 0x2000, attr, cols - , stride, nblines * cheight / 2); - memset_stride(SEG_CTEXT, dest_far, attr, cols - , stride, nblines * cheight / 2); -} - -static void -scroll_text(struct vgamode_s *vmode_g, int nblines, int attr - , struct cursorpos ul, struct cursorpos lr) -{ - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - void *src_far, *dest_far = (void*)SCREEN_MEM_START(nbcols, nbrows, ul.page); - int stride = nbcols * 2; - if (nblines >= 0) { - dest_far += ul.y * stride + ul.x * 2; - src_far = dest_far + nblines * stride; - } else { - // Scroll down - nblines = -nblines; - dest_far += lr.y * stride + ul.x * 2; - src_far = dest_far - nblines * stride; - stride = -stride; - } - int cols = (lr.x - ul.x + 1) * 2; - int rows = lr.y - ul.y + 1; - u16 seg = GET_GLOBAL(vmode_g->sstart); - if (nblines < rows) - dest_far = memcpy_stride(seg, dest_far, src_far, cols, stride - , (rows - nblines)); - if (attr < 0) - attr = 0x07; - attr = (attr << 8) | ' '; - memset16_stride(seg, dest_far, attr, cols, stride, nblines); -} - -void -vgafb_scroll(int nblines, int attr, struct cursorpos ul, struct cursorpos lr) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // FIXME gfx mode not complete - switch (GET_GLOBAL(vmode_g->memmodel)) { - case CTEXT: - case MTEXT: - scroll_text(vmode_g, nblines, attr, ul, lr); - break; - case PLANAR4: - case PLANAR1: - scroll_pl4(vmode_g, nblines, attr, ul, lr); - break; - case CGA: - scroll_cga(vmode_g, nblines, attr, ul, lr); - break; - default: - dprintf(1, "Scroll in graphics mode\n"); - } -} - -void -clear_screen(struct vgamode_s *vmode_g) -{ - switch (GET_GLOBAL(vmode_g->memmodel)) { - case CTEXT: - case MTEXT: - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0720, 32*1024); - break; - case CGA: - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 32*1024); - break; - default: - // XXX - old code gets/sets/restores sequ register 2 to 0xf - - // but it should always be 0xf anyway. - memset16_far(GET_GLOBAL(vmode_g->sstart), 0, 0x0000, 64*1024); - } -} - - -/**************************************************************** - * Read/write characters to screen - ****************************************************************/ - -static void -write_gfx_char_pl4(struct vgamode_s *vmode_g - , struct cursorpos cp, struct carattr ca) -{ - u16 nbcols = GET_BDA(video_cols); - if (cp.x >= nbcols) - return; - - struct VideoParam_s *vparam_g = GET_GLOBAL(vmode_g->vparam); - u8 cheight = GET_GLOBAL(vparam_g->cheight); - u8 *fdata_g; - switch (cheight) { - case 14: - fdata_g = vgafont14; - break; - case 16: - fdata_g = vgafont16; - break; - default: - fdata_g = vgafont8; - } - u16 addr = cp.x + cp.y * cheight * nbcols; - u16 src = ca.car * cheight; - vgahw_sequ_write(0x02, 0x0f); - vgahw_grdc_write(0x05, 0x02); - if (ca.attr & 0x80) - vgahw_grdc_write(0x03, 0x18); - else - vgahw_grdc_write(0x03, 0x00); - u8 i; - for (i = 0; i < cheight; i++) { - u8 *dest_far = (void*)(addr + i * nbcols); - u8 j; - for (j = 0; j < 8; j++) { - u8 mask = 0x80 >> j; - vgahw_grdc_write(0x08, mask); - GET_FARVAR(SEG_GRAPH, *dest_far); - if (GET_GLOBAL(fdata_g[src + i]) & mask) - SET_FARVAR(SEG_GRAPH, *dest_far, ca.attr & 0x0f); - else - SET_FARVAR(SEG_GRAPH, *dest_far, 0x00); - } - } - vgahw_grdc_write(0x08, 0xff); - vgahw_grdc_write(0x05, 0x00); - vgahw_grdc_write(0x03, 0x00); -} - -static void -write_gfx_char_cga(struct vgamode_s *vmode_g - , struct cursorpos cp, struct carattr ca) -{ - u16 nbcols = GET_BDA(video_cols); - if (cp.x >= nbcols) - return; - - u8 *fdata_g = vgafont8; - u8 bpp = GET_GLOBAL(vmode_g->pixbits); - u16 addr = (cp.x * bpp) + cp.y * 320; - u16 src = ca.car * 8; - u8 i; - for (i = 0; i < 8; i++) { - u8 *dest_far = (void*)(addr + (i >> 1) * 80); - if (i & 1) - dest_far += 0x2000; - u8 mask = 0x80; - if (bpp == 1) { - u8 data = 0; - if (ca.attr & 0x80) - data = GET_FARVAR(SEG_CTEXT, *dest_far); - u8 j; - for (j = 0; j < 8; j++) { - if (GET_GLOBAL(fdata_g[src + i]) & mask) { - if (ca.attr & 0x80) - data ^= (ca.attr & 0x01) << (7 - j); - else - data |= (ca.attr & 0x01) << (7 - j); - } - mask >>= 1; - } - SET_FARVAR(SEG_CTEXT, *dest_far, data); - } else { - while (mask > 0) { - u8 data = 0; - if (ca.attr & 0x80) - data = GET_FARVAR(SEG_CTEXT, *dest_far); - u8 j; - for (j = 0; j < 4; j++) { - if (GET_GLOBAL(fdata_g[src + i]) & mask) { - if (ca.attr & 0x80) - data ^= (ca.attr & 0x03) << ((3 - j) * 2); - else - data |= (ca.attr & 0x03) << ((3 - j) * 2); - } - mask >>= 1; - } - SET_FARVAR(SEG_CTEXT, *dest_far, data); - dest_far += 1; - } - } - } -} - -static void -write_gfx_char_lin(struct vgamode_s *vmode_g - , struct cursorpos cp, struct carattr ca) -{ - // Get the dimensions - u16 nbcols = GET_BDA(video_cols); - if (cp.x >= nbcols) - return; - - u8 *fdata_g = vgafont8; - u16 addr = cp.x * 8 + cp.y * nbcols * 64; - u16 src = ca.car * 8; - u8 i; - for (i = 0; i < 8; i++) { - u8 *dest_far = (void*)(addr + i * nbcols * 8); - u8 mask = 0x80; - u8 j; - for (j = 0; j < 8; j++) { - u8 data = 0x00; - if (GET_GLOBAL(fdata_g[src + i]) & mask) - data = ca.attr; - SET_FARVAR(SEG_GRAPH, dest_far[j], data); - mask >>= 1; - } - } -} - -static void -write_text_char(struct vgamode_s *vmode_g - , struct cursorpos cp, struct carattr ca) -{ - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - // Compute the address - void *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page) - + (cp.x + cp.y * nbcols) * 2); - - if (ca.use_attr) { - u16 dummy = (ca.attr << 8) | ca.car; - SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u16*)address_far, dummy); - } else { - SET_FARVAR(GET_GLOBAL(vmode_g->sstart), *(u8*)address_far, ca.car); - } -} - -void -vgafb_write_char(struct cursorpos cp, struct carattr ca) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - - // FIXME gfx mode not complete - switch (GET_GLOBAL(vmode_g->memmodel)) { - case CTEXT: - case MTEXT: - write_text_char(vmode_g, cp, ca); - break; - case PLANAR4: - case PLANAR1: - write_gfx_char_pl4(vmode_g, cp, ca); - break; - case CGA: - write_gfx_char_cga(vmode_g, cp, ca); - break; - case LINEAR8: - write_gfx_char_lin(vmode_g, cp, ca); - break; - } -} - -struct carattr -vgafb_read_char(struct cursorpos cp) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - goto fail; - - if (!(GET_GLOBAL(vmode_g->memmodel) & TEXT)) { - // FIXME gfx mode - dprintf(1, "Read char in graphics mode\n"); - goto fail; - } - - // Get the dimensions - u16 nbrows = GET_BDA(video_rows) + 1; - u16 nbcols = GET_BDA(video_cols); - - // Compute the address - u16 *address_far = (void*)(SCREEN_MEM_START(nbcols, nbrows, cp.page) - + (cp.x + cp.y * nbcols) * 2); - u16 v = GET_FARVAR(GET_GLOBAL(vmode_g->sstart), *address_far); - struct carattr ca = {v, v>>8, 0}; - return ca; - -fail: ; - struct carattr ca2 = {0, 0, 0}; - return ca2; -} - - -/**************************************************************** - * Read/write pixels - ****************************************************************/ - -void -vgafb_write_pixel(u8 color, u16 x, u16 y) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return; - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - return; - - u8 *addr_far, mask, attr, data; - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - addr_far = (void*)(x / 8 + y * GET_BDA(video_cols)); - mask = 0x80 >> (x & 0x07); - vgahw_grdc_write(0x08, mask); - vgahw_grdc_write(0x05, 0x02); - data = GET_FARVAR(SEG_GRAPH, *addr_far); - if (color & 0x80) - vgahw_grdc_write(0x03, 0x18); - SET_FARVAR(SEG_GRAPH, *addr_far, color); - vgahw_grdc_write(0x08, 0xff); - vgahw_grdc_write(0x05, 0x00); - vgahw_grdc_write(0x03, 0x00); - break; - case CGA: - if (GET_GLOBAL(vmode_g->pixbits) == 2) - addr_far = (void*)((x >> 2) + (y >> 1) * 80); - else - addr_far = (void*)((x >> 3) + (y >> 1) * 80); - if (y & 1) - addr_far += 0x2000; - data = GET_FARVAR(SEG_CTEXT, *addr_far); - if (GET_GLOBAL(vmode_g->pixbits) == 2) { - attr = (color & 0x03) << ((3 - (x & 0x03)) * 2); - mask = 0x03 << ((3 - (x & 0x03)) * 2); - } else { - attr = (color & 0x01) << (7 - (x & 0x07)); - mask = 0x01 << (7 - (x & 0x07)); - } - if (color & 0x80) { - data ^= attr; - } else { - data &= ~mask; - data |= attr; - } - SET_FARVAR(SEG_CTEXT, *addr_far, data); - break; - case LINEAR8: - addr_far = (void*)(x + y * (GET_BDA(video_cols) * 8)); - SET_FARVAR(SEG_GRAPH, *addr_far, color); - break; - } -} - -u8 -vgafb_read_pixel(u16 x, u16 y) -{ - // Get the mode - struct vgamode_s *vmode_g = find_vga_entry(GET_BDA(video_mode)); - if (!vmode_g) - return 0; - if (GET_GLOBAL(vmode_g->memmodel) & TEXT) - return 0; - - u8 *addr_far, mask, attr=0, data, i; - switch (GET_GLOBAL(vmode_g->memmodel)) { - case PLANAR4: - case PLANAR1: - addr_far = (void*)(x / 8 + y * GET_BDA(video_cols)); - mask = 0x80 >> (x & 0x07); - attr = 0x00; - for (i = 0; i < 4; i++) { - vgahw_grdc_write(0x04, i); - data = GET_FARVAR(SEG_GRAPH, *addr_far) & mask; - if (data > 0) - attr |= (0x01 << i); - } - break; - case CGA: - addr_far = (void*)((x >> 2) + (y >> 1) * 80); - if (y & 1) - addr_far += 0x2000; - data = GET_FARVAR(SEG_CTEXT, *addr_far); - if (GET_GLOBAL(vmode_g->pixbits) == 2) - attr = (data >> ((3 - (x & 0x03)) * 2)) & 0x03; - else - attr = (data >> (7 - (x & 0x07))) & 0x01; - break; - case LINEAR8: - addr_far = (void*)(x + y * (GET_BDA(video_cols) * 8)); - attr = GET_FARVAR(SEG_GRAPH, *addr_far); - break; - } - return attr; -} - - -/**************************************************************** - * Font loading - ****************************************************************/ - -void -vgafb_load_font(u16 seg, void *src_far, u16 count - , u16 start, u8 destflags, u8 fontsize) -{ - get_font_access(); - u16 blockaddr = ((destflags & 0x03) << 14) + ((destflags & 0x04) << 11); - void *dest_far = (void*)(blockaddr + start*32); - u16 i; - for (i = 0; i < count; i++) - memcpy_far(SEG_GRAPH, dest_far + i*32 - , seg, src_far + i*fontsize, fontsize); - release_font_access(); -} diff --git a/roms/seabios/vgasrc/vgafonts.c b/roms/seabios/vgasrc/vgafonts.c deleted file mode 100644 index 8c1752c..0000000 --- a/roms/seabios/vgasrc/vgafonts.c +++ /dev/null @@ -1,785 +0,0 @@ -#include "vgatables.h" // vgafont8 - -/* - * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip - * The package is (c) by Joseph Gil - * The individual fonts are public domain - */ -u8 vgafont8[256 * 8] VAR16 = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, - 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, - 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, - 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, - 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, - 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, - 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, - 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, - 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, - 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, - 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, - 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, - 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, - 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, - 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, - 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, - 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, - 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, - 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, - 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, - 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, - 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, - 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, - 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, - 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, - 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, - 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, - 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, - 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, - 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, - 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, - 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, - 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, - 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, - 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, - 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, - 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, - 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, - 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, - 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, - 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, - 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, - 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, - 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, - 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, - 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, - 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, - 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, - 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, - 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, - 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, - 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, - 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, - 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, - 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, - 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, - 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, - 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, - 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, - 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, - 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, - 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, - 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, - 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, - 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, - 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, - 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, - 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, - 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, - 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, - 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, - 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, - 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, - 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, - 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, - 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, - 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, - 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, - 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, - 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, - 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, - 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, - 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, - 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, - 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, - 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, - 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, - 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, - 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, - 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, - 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, - 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, - 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, - 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, - 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, - 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -u8 vgafont14[256 * 14] VAR16 = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, - 0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, - 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -u8 vgafont16[256 * 16] VAR16 = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, - 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -u8 vgafont14alt[1] VAR16; -u8 vgafont16alt[1] VAR16; diff --git a/roms/seabios/vgasrc/vgaio.c b/roms/seabios/vgasrc/vgaio.c deleted file mode 100644 index ffded34..0000000 --- a/roms/seabios/vgasrc/vgaio.c +++ /dev/null @@ -1,555 +0,0 @@ -// VGA io port access -// -// Copyright (C) 2009 Kevin O'Connor -// Copyright (C) 2001-2008 the LGPL VGABios developers Team -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "ioport.h" // outb -#include "farptr.h" // SET_FARVAR -#include "biosvar.h" // GET_BDA -#include "vgatables.h" // VGAREG_* - -// TODO -// * replace direct in/out calls with wrapper functions - - -/**************************************************************** - * Attribute control - ****************************************************************/ - -void -vgahw_screen_disable(void) -{ - inb(VGAREG_ACTL_RESET); - outb(0x00, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_screen_enable(void) -{ - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_set_border_color(u8 color) -{ - inb(VGAREG_ACTL_RESET); - outb(0x00, VGAREG_ACTL_ADDRESS); - u8 v1 = color & 0x0f; - if (v1 & 0x08) - v1 += 0x08; - outb(v1, VGAREG_ACTL_WRITE_DATA); - - u8 v2 = color & 0x10; - int i; - for (i = 1; i < 4; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - - u8 cur = inb(VGAREG_ACTL_READ_DATA); - cur &= 0xef; - cur |= v2; - outb(cur, VGAREG_ACTL_WRITE_DATA); - } - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_set_overscan_border_color(u8 color) -{ - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - outb(color, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -u8 -vgahw_get_overscan_border_color(void) -{ - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - u8 v = inb(VGAREG_ACTL_READ_DATA); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - return v; -} - -void -vgahw_set_palette(u8 palid) -{ - inb(VGAREG_ACTL_RESET); - palid &= 0x01; - int i; - for (i = 1; i < 4; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - - u8 v = inb(VGAREG_ACTL_READ_DATA); - v &= 0xfe; - v |= palid; - outb(v, VGAREG_ACTL_WRITE_DATA); - } - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_set_single_palette_reg(u8 reg, u8 val) -{ - inb(VGAREG_ACTL_RESET); - outb(reg, VGAREG_ACTL_ADDRESS); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -u8 -vgahw_get_single_palette_reg(u8 reg) -{ - inb(VGAREG_ACTL_RESET); - outb(reg, VGAREG_ACTL_ADDRESS); - u8 v = inb(VGAREG_ACTL_READ_DATA); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - return v; -} - -void -vgahw_set_all_palette_reg(u16 seg, u8 *data_far) -{ - inb(VGAREG_ACTL_RESET); - int i; - for (i = 0; i < 0x10; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - u8 val = GET_FARVAR(seg, *data_far); - outb(val, VGAREG_ACTL_WRITE_DATA); - data_far++; - } - outb(0x11, VGAREG_ACTL_ADDRESS); - outb(GET_FARVAR(seg, *data_far), VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_get_all_palette_reg(u16 seg, u8 *data_far) -{ - int i; - for (i = 0; i < 0x10; i++) { - inb(VGAREG_ACTL_RESET); - outb(i, VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA)); - data_far++; - } - inb(VGAREG_ACTL_RESET); - outb(0x11, VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, *data_far, inb(VGAREG_ACTL_READ_DATA)); - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_toggle_intensity(u8 flag) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val = (inb(VGAREG_ACTL_READ_DATA) & 0xf7) | ((flag & 0x01) << 3); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_select_video_dac_color_page(u8 flag, u8 data) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val = inb(VGAREG_ACTL_READ_DATA); - if (!(flag & 0x01)) { - // select paging mode - val = (val & 0x7f) | (data << 7); - outb(val, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); - return; - } - // select page - inb(VGAREG_ACTL_RESET); - outb(0x14, VGAREG_ACTL_ADDRESS); - if (!(val & 0x80)) - data <<= 2; - data &= 0x0f; - outb(data, VGAREG_ACTL_WRITE_DATA); - outb(0x20, VGAREG_ACTL_ADDRESS); -} - -void -vgahw_read_video_dac_state(u8 *pmode, u8 *curpage) -{ - inb(VGAREG_ACTL_RESET); - outb(0x10, VGAREG_ACTL_ADDRESS); - u8 val1 = inb(VGAREG_ACTL_READ_DATA) >> 7; - - inb(VGAREG_ACTL_RESET); - outb(0x14, VGAREG_ACTL_ADDRESS); - u8 val2 = inb(VGAREG_ACTL_READ_DATA) & 0x0f; - if (!(val1 & 0x01)) - val2 >>= 2; - - inb(VGAREG_ACTL_RESET); - outb(0x20, VGAREG_ACTL_ADDRESS); - - *pmode = val1; - *curpage = val2; -} - - -/**************************************************************** - * DAC control - ****************************************************************/ - -void -vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count) -{ - outb(start, VGAREG_DAC_WRITE_ADDRESS); - while (count) { - outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); - data_far++; - outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); - data_far++; - outb(GET_FARVAR(seg, *data_far), VGAREG_DAC_DATA); - data_far++; - count--; - } -} - -void -vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count) -{ - outb(start, VGAREG_DAC_READ_ADDRESS); - while (count) { - SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - SET_FARVAR(seg, *data_far, inb(VGAREG_DAC_DATA)); - data_far++; - count--; - } -} - -void -vgahw_set_pel_mask(u8 val) -{ - outb(val, VGAREG_PEL_MASK); -} - -u8 -vgahw_get_pel_mask(void) -{ - return inb(VGAREG_PEL_MASK); -} - -void -vgahw_save_dac_state(u16 seg, struct saveDACcolors *info) -{ - /* XXX: check this */ - SET_FARVAR(seg, info->rwmode, inb(VGAREG_DAC_STATE)); - SET_FARVAR(seg, info->peladdr, inb(VGAREG_DAC_WRITE_ADDRESS)); - SET_FARVAR(seg, info->pelmask, inb(VGAREG_PEL_MASK)); - vgahw_get_dac_regs(seg, info->dac, 0, 256); - SET_FARVAR(seg, info->color_select, 0); -} - -void -vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info) -{ - outb(GET_FARVAR(seg, info->pelmask), VGAREG_PEL_MASK); - vgahw_set_dac_regs(seg, info->dac, 0, 256); - outb(GET_FARVAR(seg, info->peladdr), VGAREG_DAC_WRITE_ADDRESS); -} - - -/**************************************************************** - * Memory control - ****************************************************************/ - -void -vgahw_sequ_write(u8 index, u8 value) -{ - outw((value<<8) | index, VGAREG_SEQU_ADDRESS); -} - -void -vgahw_grdc_write(u8 index, u8 value) -{ - outw((value<<8) | index, VGAREG_GRDC_ADDRESS); -} - -void -vgahw_set_text_block_specifier(u8 spec) -{ - outw((spec << 8) | 0x03, VGAREG_SEQU_ADDRESS); -} - -void -get_font_access(void) -{ - outw(0x0100, VGAREG_SEQU_ADDRESS); - outw(0x0402, VGAREG_SEQU_ADDRESS); - outw(0x0704, VGAREG_SEQU_ADDRESS); - outw(0x0300, VGAREG_SEQU_ADDRESS); - outw(0x0204, VGAREG_GRDC_ADDRESS); - outw(0x0005, VGAREG_GRDC_ADDRESS); - outw(0x0406, VGAREG_GRDC_ADDRESS); -} - -void -release_font_access(void) -{ - outw(0x0100, VGAREG_SEQU_ADDRESS); - outw(0x0302, VGAREG_SEQU_ADDRESS); - outw(0x0304, VGAREG_SEQU_ADDRESS); - outw(0x0300, VGAREG_SEQU_ADDRESS); - u16 v = (inw(VGAREG_READ_MISC_OUTPUT) & 0x01) ? 0x0e : 0x0a; - outw((v << 8) | 0x06, VGAREG_GRDC_ADDRESS); - outw(0x0004, VGAREG_GRDC_ADDRESS); - outw(0x1005, VGAREG_GRDC_ADDRESS); -} - - -/**************************************************************** - * CRTC registers - ****************************************************************/ - -static u16 -get_crtc(void) -{ - return GET_BDA(crtc_address); -} - -void -vgahw_set_cursor_shape(u8 start, u8 end) -{ - u16 crtc_addr = get_crtc(); - outb(0x0a, crtc_addr); - outb(start, crtc_addr + 1); - outb(0x0b, crtc_addr); - outb(end, crtc_addr + 1); -} - -void -vgahw_set_active_page(u16 address) -{ - u16 crtc_addr = get_crtc(); - outb(0x0c, crtc_addr); - outb((address & 0xff00) >> 8, crtc_addr + 1); - outb(0x0d, crtc_addr); - outb(address & 0x00ff, crtc_addr + 1); -} - -void -vgahw_set_cursor_pos(u16 address) -{ - u16 crtc_addr = get_crtc(); - outb(0x0e, crtc_addr); - outb((address & 0xff00) >> 8, crtc_addr + 1); - outb(0x0f, crtc_addr); - outb(address & 0x00ff, crtc_addr + 1); -} - -void -vgahw_set_scan_lines(u8 lines) -{ - u16 crtc_addr = get_crtc(); - outb(0x09, crtc_addr); - u8 crtc_r9 = inb(crtc_addr + 1); - crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); - outb(crtc_r9, crtc_addr + 1); -} - -// Get vertical display end -u16 -vgahw_get_vde(void) -{ - u16 crtc_addr = get_crtc(); - outb(0x12, crtc_addr); - u16 vde = inb(crtc_addr + 1); - outb(0x07, crtc_addr); - u8 ovl = inb(crtc_addr + 1); - vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1); - return vde; -} - - -/**************************************************************** - * Save/Restore/Set state - ****************************************************************/ - -void -vgahw_save_state(u16 seg, struct saveVideoHardware *info) -{ - u16 crtc_addr = get_crtc(); - SET_FARVAR(seg, info->sequ_index, inb(VGAREG_SEQU_ADDRESS)); - SET_FARVAR(seg, info->crtc_index, inb(crtc_addr)); - SET_FARVAR(seg, info->grdc_index, inb(VGAREG_GRDC_ADDRESS)); - inb(VGAREG_ACTL_RESET); - u16 ar_index = inb(VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, info->actl_index, ar_index); - SET_FARVAR(seg, info->feature, inb(VGAREG_READ_FEATURE_CTL)); - - u16 i; - for (i=0; i<4; i++) { - outb(i+1, VGAREG_SEQU_ADDRESS); - SET_FARVAR(seg, info->sequ_regs[i], inb(VGAREG_SEQU_DATA)); - } - outb(0, VGAREG_SEQU_ADDRESS); - SET_FARVAR(seg, info->sequ0, inb(VGAREG_SEQU_DATA)); - - for (i=0; i<25; i++) { - outb(i, crtc_addr); - SET_FARVAR(seg, info->crtc_regs[i], inb(crtc_addr + 1)); - } - - for (i=0; i<20; i++) { - inb(VGAREG_ACTL_RESET); - outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS); - SET_FARVAR(seg, info->actl_regs[i], inb(VGAREG_ACTL_READ_DATA)); - } - inb(VGAREG_ACTL_RESET); - - for (i=0; i<9; i++) { - outb(i, VGAREG_GRDC_ADDRESS); - SET_FARVAR(seg, info->grdc_regs[i], inb(VGAREG_GRDC_DATA)); - } - - SET_FARVAR(seg, info->crtc_addr, crtc_addr); - - /* XXX: read plane latches */ - for (i=0; i<4; i++) - SET_FARVAR(seg, info->plane_latch[i], 0); -} - -void -vgahw_restore_state(u16 seg, struct saveVideoHardware *info) -{ - // Reset Attribute Ctl flip-flop - inb(VGAREG_ACTL_RESET); - - u16 crtc_addr = GET_FARVAR(seg, info->crtc_addr); - - u16 i; - for (i=0; i<4; i++) { - outb(i+1, VGAREG_SEQU_ADDRESS); - outb(GET_FARVAR(seg, info->sequ_regs[i]), VGAREG_SEQU_DATA); - } - outb(0, VGAREG_SEQU_ADDRESS); - outb(GET_FARVAR(seg, info->sequ0), VGAREG_SEQU_DATA); - - // Disable CRTC write protection - outw(0x0011, crtc_addr); - // Set CRTC regs - for (i=0; i<25; i++) - if (i != 0x11) { - outb(i, crtc_addr); - outb(GET_FARVAR(seg, info->crtc_regs[i]), crtc_addr + 1); - } - // select crtc base address - u16 v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; - if (crtc_addr == VGAREG_VGA_CRTC_ADDRESS) - v |= 0x01; - outb(v, VGAREG_WRITE_MISC_OUTPUT); - - // enable write protection if needed - outb(0x11, crtc_addr); - outb(GET_FARVAR(seg, info->crtc_regs[0x11]), crtc_addr + 1); - - // Set Attribute Ctl - u16 ar_index = GET_FARVAR(seg, info->actl_index); - inb(VGAREG_ACTL_RESET); - for (i=0; i<20; i++) { - outb(i | (ar_index & 0x20), VGAREG_ACTL_ADDRESS); - outb(GET_FARVAR(seg, info->actl_regs[i]), VGAREG_ACTL_WRITE_DATA); - } - outb(ar_index, VGAREG_ACTL_ADDRESS); - inb(VGAREG_ACTL_RESET); - - for (i=0; i<9; i++) { - outb(i, VGAREG_GRDC_ADDRESS); - outb(GET_FARVAR(seg, info->grdc_regs[i]), VGAREG_GRDC_DATA); - } - - outb(GET_FARVAR(seg, info->sequ_index), VGAREG_SEQU_ADDRESS); - outb(GET_FARVAR(seg, info->crtc_index), crtc_addr); - outb(GET_FARVAR(seg, info->grdc_index), VGAREG_GRDC_ADDRESS); - outb(GET_FARVAR(seg, info->feature), crtc_addr - 0x4 + 0xa); -} - -void -vgahw_set_mode(struct VideoParam_s *vparam_g) -{ - // Reset Attribute Ctl flip-flop - inb(VGAREG_ACTL_RESET); - - // Set Attribute Ctl - u16 i; - for (i = 0; i <= 0x13; i++) { - outb(i, VGAREG_ACTL_ADDRESS); - outb(GET_GLOBAL(vparam_g->actl_regs[i]), VGAREG_ACTL_WRITE_DATA); - } - outb(0x14, VGAREG_ACTL_ADDRESS); - outb(0x00, VGAREG_ACTL_WRITE_DATA); - - // Set Sequencer Ctl - outb(0, VGAREG_SEQU_ADDRESS); - outb(0x03, VGAREG_SEQU_DATA); - for (i = 1; i <= 4; i++) { - outb(i, VGAREG_SEQU_ADDRESS); - outb(GET_GLOBAL(vparam_g->sequ_regs[i - 1]), VGAREG_SEQU_DATA); - } - - // Set Grafx Ctl - for (i = 0; i <= 8; i++) { - outb(i, VGAREG_GRDC_ADDRESS); - outb(GET_GLOBAL(vparam_g->grdc_regs[i]), VGAREG_GRDC_DATA); - } - - // Set CRTC address VGA or MDA - u8 miscreg = GET_GLOBAL(vparam_g->miscreg); - u16 crtc_addr = VGAREG_VGA_CRTC_ADDRESS; - if (!(miscreg & 1)) - crtc_addr = VGAREG_MDA_CRTC_ADDRESS; - - // Disable CRTC write protection - outw(0x0011, crtc_addr); - // Set CRTC regs - for (i = 0; i <= 0x18; i++) { - outb(i, crtc_addr); - outb(GET_GLOBAL(vparam_g->crtc_regs[i]), crtc_addr + 1); - } - - // Set the misc register - outb(miscreg, VGAREG_WRITE_MISC_OUTPUT); - - // Enable video - outb(0x20, VGAREG_ACTL_ADDRESS); - inb(VGAREG_ACTL_RESET); -} - - -/**************************************************************** - * Misc - ****************************************************************/ - -void -vgahw_enable_video_addressing(u8 disable) -{ - u8 v = (disable & 1) ? 0x00 : 0x02; - u8 v2 = inb(VGAREG_READ_MISC_OUTPUT) & ~0x02; - outb(v | v2, VGAREG_WRITE_MISC_OUTPUT); -} - -void -vgahw_init(void) -{ - // switch to color mode and enable CPU access 480 lines - outb(0xc3, VGAREG_WRITE_MISC_OUTPUT); - // more than 64k 3C4/04 - outb(0x04, VGAREG_SEQU_ADDRESS); - outb(0x02, VGAREG_SEQU_DATA); -} diff --git a/roms/seabios/vgasrc/vgalayout.lds.S b/roms/seabios/vgasrc/vgalayout.lds.S deleted file mode 100644 index 08a5f32..0000000 --- a/roms/seabios/vgasrc/vgalayout.lds.S +++ /dev/null @@ -1,24 +0,0 @@ -// Linker definitions for an option rom -// -// Copyright (C) 2009 Kevin O'Connor -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH("i386") -ENTRY(_optionrom_entry) -SECTIONS -{ - .text 0 : { - KEEP(*(.rom.header)) - *(.text.*) - _rodata = . ; - *(.rodata.__func__.*) - *(.rodata.str1.1) - *(.data16.*) - } - - // Discard regular data sections to force a link error if - // 16bit code attempts to access data not marked with VAR16. - /DISCARD/ : { *(.text*) *(.rodata*) *(.data*) *(.bss*) *(COMMON) } -} diff --git a/roms/seabios/vgasrc/vgatables.c b/roms/seabios/vgasrc/vgatables.c deleted file mode 100644 index 0587e65..0000000 --- a/roms/seabios/vgasrc/vgatables.c +++ /dev/null @@ -1,438 +0,0 @@ -// Tables used by VGA bios -// -// Copyright (C) 2009 Kevin O'Connor -// Copyright (C) 2001-2008 the LGPL VGABios developers Team -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "vgatables.h" // struct VideoParamTableEntry_s -#include "biosvar.h" // GET_GLOBAL - - -/**************************************************************** - * Video parameter table - ****************************************************************/ - -struct VideoParam_s video_param_table[] VAR16 = { - // index=0x00 no mode defined - {}, - // index=0x01 no mode defined - {}, - // index=0x02 no mode defined - {}, - // index=0x03 no mode defined - {}, - // index=0x04 vga mode 0x04 - { 40, 24, 8, 0x0800, /* tw, th-1, ch, slength */ - { 0x09, 0x03, 0x00, 0x02 }, /* sequ_regs */ - 0x63, /* miscreg */ - { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff }, /* crtc_regs */ - { 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x05 vga mode 0x05 */ - { 40, 24, 8, 0x0800, /* tw, th-1, ch, slength */ - { 0x09, 0x03, 0x00, 0x02 }, /* sequ_regs */ - 0x63, /* miscreg */ - { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff }, /* crtc_regs */ - { 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x06 vga mode 0x06 */ - { 80, 24, 8, 0x1000, /* tw, th-1, ch, slength */ - { 0x01, 0x01, 0x00, 0x06 }, /* sequ_regs */ - 0x63, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, - 0xff }, /* crtc_regs */ - { 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x01, 0x00, 0x01, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x07 vga mode 0x07 */ - { 80, 24, 16, 0x1000, /* tw, th-1, ch, slength */ - { 0x00, 0x03, 0x00, 0x02 }, /* sequ_regs */ - 0x66, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, - 0xff }, /* crtc_regs */ - { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x08 no mode defined */ - {}, - /* index=0x09 no mode defined */ - {}, - /* index=0x0a no mode defined */ - {}, - /* index=0x0b no mode defined */ - {}, - /* index=0x0c no mode defined */ - {}, - /* index=0x0d vga mode 0x0d */ - { 40, 24, 8, 0x2000, /* tw, th-1, ch, slength */ - { 0x09, 0x0f, 0x00, 0x06 }, /* sequ_regs */ - 0x63, /* miscreg */ - { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x0e vga mode 0x0e */ - { 80, 24, 8, 0x4000, /* tw, th-1, ch, slength */ - { 0x01, 0x0f, 0x00, 0x06 }, /* sequ_regs */ - 0x63, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x0f no mode defined */ - {}, - /* index=0x10 no mode defined */ - {}, - /* index=0x11 vga mode 0x0f */ - { 80, 24, 14, 0x8000, /* tw, th-1, ch, slength */ - { 0x01, 0x0f, 0x00, 0x06 }, /* sequ_regs */ - 0xa3, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff }, /* crtc_regs */ - { 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x12 vga mode 0x10 */ - { 80, 24, 14, 0x8000, /* tw, th-1, ch, slength */ - { 0x01, 0x0f, 0x00, 0x06 }, /* sequ_regs */ - 0xa3, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x13 no mode defined */ - {}, - /* index=0x14 no mode defined */ - {}, - /* index=0x15 no mode defined */ - {}, - /* index=0x16 no mode defined */ - {}, - /* index=0x17 vga mode 0x01 */ - { 40, 24, 16, 0x0800, /* tw, th-1, ch, slength */ - { 0x08, 0x03, 0x00, 0x02 }, /* sequ_regs */ - 0x67, /* miscreg */ - { 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x18 vga mode 0x03 */ - { 80, 24, 16, 0x1000, /* tw, th-1, ch, slength */ - { 0x00, 0x03, 0x00, 0x02 }, /* sequ_regs */ - 0x67, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x19 vga mode 0x07 */ - { 80, 24, 16, 0x1000, /* tw, th-1, ch, slength */ - { 0x00, 0x03, 0x00, 0x02 }, /* sequ_regs */ - 0x66, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, - 0xff }, /* crtc_regs */ - { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x1a vga mode 0x11 */ - { 80, 29, 16, 0x0000, /* tw, th-1, ch, slength */ - { 0x01, 0x0f, 0x00, 0x06 }, /* sequ_regs */ - 0xe3, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff }, /* crtc_regs */ - { 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, - 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, - 0x01, 0x00, 0x0f, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x1b vga mode 0x12 */ - { 80, 29, 16, 0x0000, /* tw, th-1, ch, slength */ - { 0x01, 0x0f, 0x00, 0x06 }, /* sequ_regs */ - 0xe3, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x1c vga mode 0x13 */ - { 40, 24, 8, 0x0000, /* tw, th-1, ch, slength */ - { 0x01, 0x0f, 0x00, 0x0e }, /* sequ_regs */ - 0x63, /* miscreg */ - { 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x41, 0x00, 0x0f, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, - /* index=0x1d vga mode 0x6a */ - { 100, 36, 16, 0x0000, /* tw, th-1, ch, slength */ - { 0x01, 0x0f, 0x00, 0x06 }, /* sequ_regs */ - 0xe3, /* miscreg */ - { 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0, - 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3, - 0xff }, /* crtc_regs */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00 }, /* actl_regs */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff }, /* grdc_regs */ - }, -}; - - -/**************************************************************** - * Palette definitions - ****************************************************************/ - -/* Mono */ -static u8 palette0[] VAR16 = { - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f -}; - -static u8 palette1[] VAR16 = { - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, - 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, - 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, - 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, - 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, - 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, - 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, - 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, - 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f -}; - -static u8 palette2[] VAR16 = { - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, - 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, - 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, - 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, - 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, - 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, - 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, - 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, - 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, - 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, - 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, - 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, - 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, - 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, - 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f -}; - -static u8 palette3[] VAR16 = { - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, - 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, - 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, - 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, - 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, - 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, - 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, - 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, - 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, - 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, - 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, - 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, - 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, - 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, - - 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, - 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, - 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, - 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, - 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, - 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, - 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, - 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, - 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, - 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, - 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, - 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, - 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, - 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, - 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, - 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, - - 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, - 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, - 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, - 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, - 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, - 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, - 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, - 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, - 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, - 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, - 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, - 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, - 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, - 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, - 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, - 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, - - 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, - 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, - 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, - 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, - 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, - 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, - 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, - 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, - 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, - 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, - 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, - 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, - 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, - 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 -}; - - -/**************************************************************** - * Video mode list - ****************************************************************/ - -#define PAL(x) x, sizeof(x) -#define VPARAM(x) &video_param_table[x] - -static struct vgamode_s vga_modes[] VAR16 = { - //mode vparam model bits sstart pelm dac - {0x00, VPARAM(0x17), CTEXT, 4, SEG_CTEXT, 0xFF, PAL(palette2)}, - {0x01, VPARAM(0x17), CTEXT, 4, SEG_CTEXT, 0xFF, PAL(palette2)}, - {0x02, VPARAM(0x18), CTEXT, 4, SEG_CTEXT, 0xFF, PAL(palette2)}, - {0x03, VPARAM(0x18), CTEXT, 4, SEG_CTEXT, 0xFF, PAL(palette2)}, - {0x04, VPARAM(0x04), CGA, 2, SEG_CTEXT, 0xFF, PAL(palette1)}, - {0x05, VPARAM(0x05), CGA, 2, SEG_CTEXT, 0xFF, PAL(palette1)}, - {0x06, VPARAM(0x06), CGA, 1, SEG_CTEXT, 0xFF, PAL(palette1)}, - {0x07, VPARAM(0x07), MTEXT, 4, SEG_MTEXT, 0xFF, PAL(palette0)}, - {0x0D, VPARAM(0x0d), PLANAR4, 4, SEG_GRAPH, 0xFF, PAL(palette1)}, - {0x0E, VPARAM(0x0e), PLANAR4, 4, SEG_GRAPH, 0xFF, PAL(palette1)}, - {0x0F, VPARAM(0x11), PLANAR1, 1, SEG_GRAPH, 0xFF, PAL(palette0)}, - {0x10, VPARAM(0x12), PLANAR4, 4, SEG_GRAPH, 0xFF, PAL(palette2)}, - {0x11, VPARAM(0x1a), PLANAR1, 1, SEG_GRAPH, 0xFF, PAL(palette2)}, - {0x12, VPARAM(0x1b), PLANAR4, 4, SEG_GRAPH, 0xFF, PAL(palette2)}, - {0x13, VPARAM(0x1c), LINEAR8, 8, SEG_GRAPH, 0xFF, PAL(palette3)}, - {0x6A, VPARAM(0x1d), PLANAR4, 4, SEG_GRAPH, 0xFF, PAL(palette2)}, -}; - -struct vgamode_s * -find_vga_entry(u8 mode) -{ - int i; - for (i = 0; i < ARRAY_SIZE(vga_modes); i++) { - struct vgamode_s *vmode_g = &vga_modes[i]; - if (GET_GLOBAL(vmode_g->svgamode) == mode) - return vmode_g; - } - return NULL; -} - -u16 video_save_pointer_table[14] VAR16; - - -/**************************************************************** - * Static functionality table - ****************************************************************/ - -u8 static_functionality[0x10] VAR16 = { - /* 0 */ 0xff, // All modes supported #1 - /* 1 */ 0xe0, // All modes supported #2 - /* 2 */ 0x0f, // All modes supported #3 - /* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved - /* 7 */ 0x07, // 200, 350, 400 scan lines - /* 8 */ 0x02, // mamimum number of visible charsets in text mode - /* 9 */ 0x08, // total number of charset blocks in text mode - /* a */ 0xe7, // Change to add new functions - /* b */ 0x0c, // Change to add new functions - /* c */ 0x00, // reserved - /* d */ 0x00, // reserved - /* e */ 0x00, // Change to add new functions - /* f */ 0x00 // reserved -}; diff --git a/roms/seabios/vgasrc/vgatables.h b/roms/seabios/vgasrc/vgatables.h deleted file mode 100644 index 1e76b3a..0000000 --- a/roms/seabios/vgasrc/vgatables.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef __VGATABLES_H -#define __VGATABLES_H - -#include "types.h" // u8 -#include "farptr.h" // struct segoff_s - -/* - * - * VGA registers - * - */ -#define VGAREG_ACTL_ADDRESS 0x3c0 -#define VGAREG_ACTL_WRITE_DATA 0x3c0 -#define VGAREG_ACTL_READ_DATA 0x3c1 - -#define VGAREG_INPUT_STATUS 0x3c2 -#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 -#define VGAREG_VIDEO_ENABLE 0x3c3 -#define VGAREG_SEQU_ADDRESS 0x3c4 -#define VGAREG_SEQU_DATA 0x3c5 - -#define VGAREG_PEL_MASK 0x3c6 -#define VGAREG_DAC_STATE 0x3c7 -#define VGAREG_DAC_READ_ADDRESS 0x3c7 -#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 -#define VGAREG_DAC_DATA 0x3c9 - -#define VGAREG_READ_FEATURE_CTL 0x3ca -#define VGAREG_READ_MISC_OUTPUT 0x3cc - -#define VGAREG_GRDC_ADDRESS 0x3ce -#define VGAREG_GRDC_DATA 0x3cf - -#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 -#define VGAREG_MDA_CRTC_DATA 0x3b5 -#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 -#define VGAREG_VGA_CRTC_DATA 0x3d5 - -#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba -#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da -#define VGAREG_ACTL_RESET 0x3da - -#define VGAREG_MDA_MODECTL 0x3b8 -#define VGAREG_CGA_MODECTL 0x3d8 -#define VGAREG_CGA_PALETTE 0x3d9 - -/* Video memory */ -#define SEG_GRAPH 0xA000 -#define SEG_CTEXT 0xB800 -#define SEG_MTEXT 0xB000 - -/* - * Tables of default values for each mode - */ -#define TEXT 0x80 - -#define CTEXT (0x00 | TEXT) -#define MTEXT (0x01 | TEXT) -#define CGA 0x02 -#define PLANAR1 0x03 -#define PLANAR4 0x04 -#define LINEAR8 0x05 - -// for SVGA -#define LINEAR15 0x10 -#define LINEAR16 0x11 -#define LINEAR24 0x12 -#define LINEAR32 0x13 - -#define SCREEN_IO_START(x,y,p) (((((x)*(y)) | 0x00ff) + 1) * (p)) -#define SCREEN_MEM_START(x,y,p) SCREEN_IO_START(((x)*2),(y),(p)) - -/* standard BIOS Video Parameter Table */ -struct VideoParam_s { - u8 twidth; - u8 theightm1; - u8 cheight; - u16 slength; - u8 sequ_regs[4]; - u8 miscreg; - u8 crtc_regs[25]; - u8 actl_regs[20]; - u8 grdc_regs[9]; -} PACKED; - -struct vgamode_s { - u8 svgamode; - struct VideoParam_s *vparam; - u8 memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ - u8 pixbits; - u16 sstart; - u8 pelmask; - u8 *dac; - u16 dacsize; -}; - -struct saveVideoHardware { - u8 sequ_index; - u8 crtc_index; - u8 grdc_index; - u8 actl_index; - u8 feature; - u8 sequ_regs[4]; - u8 sequ0; - u8 crtc_regs[25]; - u8 actl_regs[20]; - u8 grdc_regs[9]; - u16 crtc_addr; - u8 plane_latch[4]; -}; - -struct saveBDAstate { - u8 video_mode; - u16 video_cols; - u16 video_pagesize; - u16 crtc_address; - u8 video_rows; - u16 char_height; - u8 video_ctl; - u8 video_switches; - u8 modeset_ctl; - u16 cursor_type; - u16 cursor_pos[8]; - u16 video_pagestart; - u8 video_page; - /* current font */ - struct segoff_s font0; - struct segoff_s font1; -}; - -struct saveDACcolors { - u8 rwmode; - u8 peladdr; - u8 pelmask; - u8 dac[768]; - u8 color_select; -}; - -// vgatables.c -struct vgamode_s *find_vga_entry(u8 mode); -extern u16 video_save_pointer_table[]; -extern struct VideoParam_s video_param_table[]; -extern u8 static_functionality[]; - -// vgafonts.c -extern u8 vgafont8[]; -extern u8 vgafont14[]; -extern u8 vgafont16[]; -extern u8 vgafont14alt[]; -extern u8 vgafont16alt[]; - -// vga.c -struct carattr { - u8 car, attr, use_attr; -}; -struct cursorpos { - u8 x, y, page; -}; - -// vgafb.c -void clear_screen(struct vgamode_s *vmode_g); -void vgafb_scroll(int nblines, int attr - , struct cursorpos ul, struct cursorpos lr); -void vgafb_write_char(struct cursorpos cp, struct carattr ca); -struct carattr vgafb_read_char(struct cursorpos cp); -void vgafb_write_pixel(u8 color, u16 x, u16 y); -u8 vgafb_read_pixel(u16 x, u16 y); -void vgafb_load_font(u16 seg, void *src_far, u16 count - , u16 start, u8 destflags, u8 fontsize); - -// vgaio.c -void vgahw_screen_disable(void); -void vgahw_screen_enable(void); -void vgahw_set_border_color(u8 color); -void vgahw_set_overscan_border_color(u8 color); -u8 vgahw_get_overscan_border_color(void); -void vgahw_set_palette(u8 palid); -void vgahw_set_single_palette_reg(u8 reg, u8 val); -u8 vgahw_get_single_palette_reg(u8 reg); -void vgahw_set_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_get_all_palette_reg(u16 seg, u8 *data_far); -void vgahw_toggle_intensity(u8 flag); -void vgahw_select_video_dac_color_page(u8 flag, u8 data); -void vgahw_read_video_dac_state(u8 *pmode, u8 *curpage); -void vgahw_set_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_get_dac_regs(u16 seg, u8 *data_far, u8 start, int count); -void vgahw_set_pel_mask(u8 val); -u8 vgahw_get_pel_mask(void); -void vgahw_save_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_restore_dac_state(u16 seg, struct saveDACcolors *info); -void vgahw_sequ_write(u8 index, u8 value); -void vgahw_grdc_write(u8 index, u8 value); -void vgahw_set_text_block_specifier(u8 spec); -void get_font_access(void); -void release_font_access(void); -void vgahw_set_cursor_shape(u8 start, u8 end); -void vgahw_set_active_page(u16 address); -void vgahw_set_cursor_pos(u16 address); -void vgahw_set_scan_lines(u8 lines); -u16 vgahw_get_vde(void); -void vgahw_save_state(u16 seg, struct saveVideoHardware *info); -void vgahw_restore_state(u16 seg, struct saveVideoHardware *info); -void vgahw_set_mode(struct VideoParam_s *vparam_g); -void vgahw_enable_video_addressing(u8 disable); -void vgahw_init(void); - -// clext.c -void cirrus_set_video_mode(u8 mode); -void cirrus_init(void); - -// vbe.c -- not implemented yet. -#define VBE_DISPI_DISABLED 0x00 -void dispi_set_enable(int enable); -void vbe_init(void); -int vbe_has_vbe_display(void); - -#endif // vgatables.h diff --git a/roms/vgabios/.cvsignore b/roms/vgabios/.cvsignore deleted file mode 100644 index 1df04b7..0000000 --- a/roms/vgabios/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -vbetables.h diff --git a/roms/vgabios/BUGS b/roms/vgabios/BUGS deleted file mode 100644 index 785f4dc..0000000 --- a/roms/vgabios/BUGS +++ /dev/null @@ -1,3 +0,0 @@ -Not all the functions have been implemented yet. - -Please report any bugs to diff --git a/roms/vgabios/COPYING b/roms/vgabios/COPYING deleted file mode 100644 index 223ede7..0000000 --- a/roms/vgabios/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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/roms/vgabios/ChangeLog b/roms/vgabios/ChangeLog deleted file mode 100644 index dbaed5d..0000000 --- a/roms/vgabios/ChangeLog +++ /dev/null @@ -1,1311 +0,0 @@ -2009-04-07 20:18 vruppert - - * vgabios.c (1.69): - - - biosfn_write_teletype: fixed attribute when scrolling in text mode - -2009-04-06 20:17 vruppert - - * ChangeLog (1.28), README (1.17): - - - preparing for release 0.6c - -2009-01-25 16:46 vruppert - - * vbe.c (1.62), vbe.h (1.28), vbetables-gen.c (1.5): - - - added support for a lot more non-standard VBE modes (e.g. widescreen modes) - - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, VRAM size - in 64k pages stored in VBE register) - - check if VBE mode is supported with current VRAM size - -2009-01-24 11:02 vruppert - - * clext.c (1.14), vbe.c (1.61), vgabios.c (1.68): - - - use VBE LFB address from PCI base address if present (rewrite of the cirrus - specific function in main vgabios code) - - removed unnecessary spaces - -2008-12-14 09:29 vruppert - - * clext.c (1.13): - - - added DPMS support to cirrus vgabios (patch from Gleb Natapov) - -2008-05-30 17:28 vruppert - - * README (1.16): - - - updated for release 0.6b - -2008-05-22 12:55 vruppert - - * ChangeLog (1.27), README (1.15): - - - preparations for release 0.6b - -2008-05-11 08:40 vruppert - - * biossums.c (1.6): - - - fixed a warning - -2008-03-02 08:47 vruppert - - * vbe.c (1.60): - - - added debug message for unsupported VBE modes - -2008-02-24 09:18 vruppert - - * vbe.c (1.59): - - - in LFB modes the number of banks must be set to 1 - -2008-01-27 10:44 vruppert - - * Makefile (1.21), biossums.c (1.5), vgabios.c (1.67): - - - added PCI data structure for the Cirrus VGABIOS images - - added support for the PCI data structure in biossums - - updated year in copyright - -2008-01-26 11:46 vruppert - - * BUGS (1.4), Makefile (1.20), README (1.14), TODO (1.13), vbe_display_api.txt (1.14): - - - whitespace cleanup - -2006-11-26 10:43 vruppert - - * Makefile (1.19): - - - disable the generation of linemarkers by the preprocessor, since the latest - versions of bcc don't like them - -2006-09-02 13:15 vruppert - - * biossums.c (1.4): - - - the biossums utility no longer modifies VGABIOS images with proper checksum - and size - -2006-08-19 14:28 vruppert - - * Changelog (1.26), README (1.13), TODO (1.12): - - - updates for 0.6a release - -2006-08-19 09:39 vruppert - - * vbe.c (1.58): - - - improved VGA compatible setup for VBE modes (disable CGA and Hercules - compatible memory layout) - -2006-08-18 20:39 vruppert - - * vbe.c (1.57): - - - improved VGA compatible setup for >=8bpp VBE modes (CRTC doubleword mode and - GRDC shift register setting added) - - now using symbolic name for CRTC address register - -2006-08-15 20:42 vruppert - - * vbe.c (1.56), vbetables-gen.c (1.4): - - - init 4bpp VBE modes by a temporary switch to VGA mode 0x6A - - all 4bpp VBE modes now enabled - -2006-08-14 20:24 vruppert - - * vbe.c (1.55): - - - VGA compatible setup for VBE modes improved (Bochs hack can be removed now) - -2006-08-12 07:51 vruppert - - * .cvsignore (1.1): - - - .cvsignore added for auto-generated file - -2006-08-12 07:47 vruppert - - * vbe.c (1.54), vbe.h (1.27), vbe_display_api.txt (1.13), vbetables-gen.c (1.3): - - - cleaned up VBE memory size definitions (removed duplicate defines, main - definition now in vbetables-gen.c) - -2006-08-09 21:28 vruppert - - * vbetables.h (1.30): - - - removed auto-generated file - -2006-08-09 21:26 vruppert - - * vbe.c (1.53), vbe.h (1.26), vbe_display_api.txt (1.12), vbetables-gen.c (1.2), - vbetables.h (1.29): - - - VBE video memory increased to 8 MB - - VBE dispi ID changed to B0C4 - - documentation update - -2006-07-11 08:03 vruppert - - * Makefile (1.18), vbetables-gen.c (1.1), vbetables.h (1.28): - - - generate vbetables.h dynamicly - * initial patch from the qemu project by Fabrice Bellard - * only add modes that fit in video memory (still 4 MB) - * several other fixes (e.g. 4 bpp specific stuff, number of pages) - -2006-07-10 07:47 vruppert - - * vgabios.c (1.66): - - - biosfn_scroll(): check variable 'i' for underflowing when scrolling downwards - to avoid screen corruption - -2006-07-10 07:47 vruppert - - * vbe.c (1.52): - - - VBE set bank functions failure handling added - - VBE get/set logical scan line length fixes for the 4bpp mode - -2006-07-08 13:27 vruppert - - * vbe.c (1.51), vbetables.h (1.27): - - - added special case for the 4 bpp when setting VBE display start - - VBE mode table fixes - -2006-07-07 13:30 vruppert - - * clext.c (1.12): - - - bank pointer must be set to 0 after a mode set - -2006-06-21 16:58 vruppert - - * vbe.c (1.50), vbetables.h (1.26): - - - improved VBE display capabilities check (X resulution checked now) - - removed obsolete defines (LFB always available, always generate dynamic list) - - CR/LF to LF fixes - -2006-06-18 15:22 vruppert - - * clext.c (1.11), vbe.c (1.49), vbe.h (1.25), vbetables.h (1.25), vgabios.c - (1.65): - - - applied patch from the qemu project (Fabrice Bellard) - * Cirrus SVGA now supports the "no clear" bit when switching to Cirrus or - VESA mode - * Bochs VBE protected mode interface improved - * save/restore video state support for Bochs VBE and standard VGA added - * Bochs VBE prepared for more modi - -2006-03-25 10:19 vruppert - - * clext.c (1.10), vgabios.c (1.64), vgatables.h (1.10): - - - applied patch from Fabrice Bellard - * added minimal support for the video parameter table (VPT) - * added Cirrus SVGA mode 0x7b (1600x1200x8) - -2005-12-26 19:50 vruppert - - * vbe.c (1.48), vgabios.c (1.63): - - - Bochs VBE protected mode interface added (based on a patch by malc@pulsesoft.com) - -2005-12-26 19:50 vruppert - - * biossums.c (1.3): - - - biossums utility now supports VGABIOS sizes up to 64 kBytes - -2005-09-21 18:45 vruppert - - * vgatables.h (1.9): - - - mode 0x11: all color planes must be enabled in this 2-color VGA mode - -2005-08-30 18:41 vruppert - - * biossums.c (1.2): - - - missing license text added in biossums.c - -2005-07-02 18:39 vruppert - - * vgabios.c (1.62): - - - BIOS configuration word usually reports initial mode 80x25 color text - - vgabios function 0x0e (write teletype): linefeed (0x0a) only increments the - cursor row value - -2005-05-24 16:50 vruppert - - * vbe.c (1.47), vgabios.c (1.61): - - - output to the vgabios info port can be disabled now. It is still enabled by - default and always possible in debug mode. (based on a patch from Alex Beregszaszi) - -2005-05-20 16:06 vruppert - - * vbe.c (1.46), vgabios.c (1.60): - - - fixed return value for the default case in the VBE section (non-debug mode) - - removed unused macros HALT and PANIC_PORT - -2005-03-07 20:39 vruppert - - * README (1.9): - - - updates for 0.5a release - -2005-03-06 13:06 vruppert - - * Makefile (1.17): - - - vgabios files with cirrus support added to release target - -2005-03-06 12:24 vruppert - - * Makefile (1.16): - - - cross compilation support added (patch from Alex Beregszaszi) - -2005-03-05 13:03 vruppert - - * BUGS (1.3), README (1.8), TODO (1.11): - - - documentation updates - -2004-12-04 15:26 vruppert - - * VGABIOS-lgpl-latest.bin (1.61), VGABIOS-lgpl-latest.cirrus.bin - (1.13), VGABIOS-lgpl-latest.cirrus.debug.bin (1.13), - VGABIOS-lgpl-latest.debug.bin (1.61), clext.c (1.9): - - - Cirrus extension: support for 1280x1024x15 and 1280x1024x16 modes added (patch - from Fabrice Bellard) - -2004-08-08 16:53 vruppert - - * VGABIOS-lgpl-latest.bin (1.60), VGABIOS-lgpl-latest.cirrus.bin (1.12), - VGABIOS-lgpl-latest.cirrus.debug.bin (1.12), - VGABIOS-lgpl-latest.debug.bin (1.60), clext.c (1.8): - - - use single bank mode for VBE - - enable 16k granularity for VBE only - -2004-07-30 19:33 vruppert - - * VGABIOS-lgpl-latest.bin (1.59), VGABIOS-lgpl-latest.cirrus.bin (1.11), - VGABIOS-lgpl-latest.cirrus.debug.bin (1.11), - VGABIOS-lgpl-latest.debug.bin (1.59), clext.c (1.7): - - - cirrus init: set standard vga mode and reset bitblt - -2004-07-22 18:38 vruppert - - * VGABIOS-lgpl-latest.bin (1.58), VGABIOS-lgpl-latest.cirrus.bin (1.10), - VGABIOS-lgpl-latest.cirrus.debug.bin (1.10), - VGABIOS-lgpl-latest.debug.bin (1.58), clext.c (1.6), vbe.c (1.45), - vbetables.h (1.24): - - - cirrus extension: tables for mode 1280x1024x8 added - - vbe: dispi_set_xres() and dispi_set_virt_width() now modify vga compatible - registers - - vbe: mode list entry for mode 800x600x4 fixed - -2004-07-18 20:23 vruppert - - * VGABIOS-lgpl-latest.bin (1.57), VGABIOS-lgpl-latest.cirrus.bin (1.9), - VGABIOS-lgpl-latest.cirrus.debug.bin (1.9), - VGABIOS-lgpl-latest.debug.bin (1.57), vgabios.c (1.59), vgatables.h (1.8): - - - disable CRTC write protection before setting new values - - CRTC line for mode 0x6a fixed - -2004-07-07 16:08 vruppert - - * Makefile (1.15), VGABIOS-lgpl-latest.bin (1.56), - VGABIOS-lgpl-latest.cirrus.bin (1.8), VGABIOS-lgpl-latest.cirrus.debug.bin (1.8), - VGABIOS-lgpl-latest.debug.bin (1.56), biossums.c (1.1), clext.c (1.5): - - - biossums utility for the Bochs BIOS adapted for the LGPL'd VGABIOS - - VESA3 PMINFO checksum calculated in the source - - 24 bpp mode entries fixed (patch from Fabrice Bellard) - -2004-06-25 18:28 vruppert - - * VGABIOS-lgpl-latest.cirrus.bin (1.7), VGABIOS-lgpl-latest.cirrus.debug.bin (1.7), - clext.c (1.4): - - - 4MB memory probe added (patch from Fabrice Bellard) - -2004-06-25 17:31 vruppert - - * VGABIOS-lgpl-latest.bin (1.55), VGABIOS-lgpl-latest.cirrus.bin (1.6), - VGABIOS-lgpl-latest.cirrus.debug.bin (1.6), - VGABIOS-lgpl-latest.debug.bin (1.55), clext.c (1.3): - - - fixed value of sequencer reset register in cirrus mode table - - fixed possible overflow error if cirrus start address is >256k - -2004-06-23 21:11 vruppert - - * VGABIOS-lgpl-latest.bin (1.54), VGABIOS-lgpl-latest.cirrus.bin (1.5), - VGABIOS-lgpl-latest.cirrus.debug.bin (1.5), - VGABIOS-lgpl-latest.debug.bin (1.54), clext.c (1.2): - - - applied new patch for the cirrus extension from suzu - * enable VESA LFB support if a Cirrus PCI adapter is detected - * prepared VBE3 protected mode info block (test case required) - - added VBE functions 4F06h and 4F07h - - some bugfixes - -2004-06-17 18:57 vruppert - - * Makefile (1.14), VGABIOS-lgpl-latest.bin (1.53), - VGABIOS-lgpl-latest.cirrus.bin (1.2), VGABIOS-lgpl-latest.cirrus.debug.bin (1.2), - VGABIOS-lgpl-latest.debug.bin (1.53): - - - fixed makefile targets for the binaries with cirrus extension - -2004-06-16 21:11 vruppert - - * Makefile (1.13), VGABIOS-lgpl-latest.bin (1.52), - VGABIOS-lgpl-latest.cirrus.bin (1.1), VGABIOS-lgpl-latest.cirrus.debug.bin (1.1), - VGABIOS-lgpl-latest.debug.bin (1.52), clext.c (1.1), vgabios.c (1.58): - - - applied suzu's cirrus extension patch. Cirrus SVGA detection, most of the - cirrus-specific modes and some basic VBE features are present now. - -2004-05-31 21:15 vruppert - - * VGABIOS-lgpl-latest.bin (1.51), VGABIOS-lgpl-latest.debug.bin (1.51), - vgabios.c (1.57): - - - write character in planar graphics modes: sequencer map mask must be 0x0f and - bit operation must be 'replace' if bit 7 of attribute is clear - - read/write pixel in planar graphics modes: bit mask setup simplified - -2004-05-11 18:08 vruppert - - * VGABIOS-lgpl-latest.bin (1.50), VGABIOS-lgpl-latest.debug.bin (1.50), - vgabios.c (1.56): - - - biosfn_select_vert_res rewritten in assembler - - scroll text in planar graphics modes: attribute for blank line fixed - - write character in planar graphics modes: graphics controller values fixed - -2004-05-09 20:32 vruppert - - * VGABIOS-lgpl-latest.bin (1.49), VGABIOS-lgpl-latest.debug.bin (1.49), - vbe.c (1.44), vbe.h (1.24), vgabios.c (1.55): - - - VBE init code and some dispi ioport functions rewritten in assembler - - text scroll functions for CGA graphics modes added - - scroll text in graphics modes: attribute for blank line fixed - -2004-05-08 16:06 vruppert - - * BUGS (1.2), README (1.7), TODO (1.10), VGABIOS-lgpl-latest.bin (1.48), - VGABIOS-lgpl-latest.debug.bin (1.48), vbe.c (1.43), vbe.h (1.23), - vbe_display_api.txt (1.11), vgabios.c (1.54): - - - VBE internal functions dispi_set_enable and dispi_set_bank now called both from C - and asm code - - VBE function 0x03 rewritten in assembler - - VBE function 0x08 cleaned up - - text output and scroll functions for graphics modes rewritten using case - structures - - documentation and comments updated - -2004-05-06 21:18 vruppert - - * VGABIOS-lgpl-latest.bin (1.47), VGABIOS-lgpl-latest.debug.bin (1.47), - vbe.c (1.42), vbe.h (1.22), vgabios.c (1.53): - - - VBE functions 0x05, 0x06, 0x07 and some dispi ioport functions rewritten in - assembler - - VBE functions 0x06 and 0x07: get functions now supported, 15 bpp bug fixed - -2004-05-05 19:24 vruppert - - * VGABIOS-lgpl-latest.bin (1.46), VGABIOS-lgpl-latest.debug.bin (1.46), - vbe.c (1.41), vbe.h (1.21), vbe_display_api.txt (1.10), vgabios.c (1.52): - - - 8 bit DAC capability flag set - - vbe_biosfn_set_get_dac_palette_format implemented - - VBE api description updated - - C definitions from header files now used assembler code - -2004-05-02 17:27 vruppert - - * VGABIOS-lgpl-latest.bin (1.45), VGABIOS-lgpl-latest.debug.bin (1.45), - vgabios.c (1.51): - - - text scroll functions for PLANAR1/PLANAR4 graphics modes added - - function biosfn_get_ega_info rewritten in assembler - - read/write graphics pixel functions rewritten using a case structure - -2004-05-01 16:03 vruppert - - * VGABIOS-lgpl-latest.bin (1.44), VGABIOS-lgpl-latest.debug.bin (1.44), - vgabios.c (1.50): - - - biosfn_enable_cursor_emulation rewritten in assembler - - remap of the cursor shape depends on modeset control bit 0 - - text output in PLANAR4 modes now supports attribute bit 7 (XOR with background) - -2004-04-25 20:13 vruppert - - * VGABIOS-lgpl-latest.bin (1.43), VGABIOS-lgpl-latest.debug.bin (1.43), - vgabios.c (1.49), vgatables.h (1.7): - - - table entries for vga mode 0x0f fixed (PLANAR2 exists on EGA only) - - function release_font_access now supports the monochrome text mode - - PLANAR1 modes now supported in text output functions and read/write pixel - - function AH=0x12/BL=0x32 rewritten in assembler - -2004-04-25 08:45 vruppert - - * VGABIOS-lgpl-latest.bin (1.42), VGABIOS-lgpl-latest.debug.bin (1.42), - vgabios.c (1.48): - - - block address calculation in font functions fixed - - functions AX=0x1103, AH=0x12/BL=0x31 and AH=0x12/BL=0x33 rewritten in assembler - -2004-04-24 09:59 vruppert - - * VGABIOS-lgpl-latest.bin (1.41), VGABIOS-lgpl-latest.debug.bin (1.41), - vgabios.c (1.47): - - - read/write graphics pixel for PLANAR4 modes added - - CGA specific functions (group AH = 0x0B) implemented - -2004-04-23 14:34 vruppert - - * VGABIOS-lgpl-latest.bin (1.40), VGABIOS-lgpl-latest.debug.bin (1.40), - vgabios.c (1.46): - - - remaining palette and dac read/write functions (except gray scale summing) - rewritten in assembler - -2004-04-18 13:43 vruppert - - * VGABIOS-lgpl-latest.bin (1.39), VGABIOS-lgpl-latest.debug.bin (1.39), - vgabios.c (1.45): - - - some palette and dac read/write functions rewritten in assembler - - main int10 debug message now works with assembler functions, too - -2004-04-18 09:15 japj - - * vbe.c (1.40): - - updated my email address + put vgabios url in the bios copyright string - (instead of my old email address) - -2004-04-17 07:18 vruppert - - * VGABIOS-lgpl-latest.bin (1.38), VGABIOS-lgpl-latest.debug.bin (1.38), - vgabios.c (1.44): - - - biosfn_set_video_mode: don't load DAC registers if default palette loading is - disabled. Perform gray scale summing if enabled. - - biosfn_perform_gray_scale_summing: switch between DAC read and write mode is - required to make this function work. Maximum DAC value always set to 0x3f. - -2004-04-08 17:50 vruppert - - * VGABIOS-lgpl-latest.bin (1.37), VGABIOS-lgpl-latest.debug.bin (1.37), - vgabios.c (1.43): - - - write character function for the LINEAR8 mode - - get_font_access() and release_font_access() rewritten in assembler - - fixed wrong variable name in the init code - -2004-04-06 19:31 vruppert - - * VGABIOS-lgpl-latest.bin (1.36), VGABIOS-lgpl-latest.debug.bin (1.36), - vgabios.c (1.42): - - - init functions rewitten in assembler - - function biosfn_set_display_code rewritten in assembler - -2004-04-05 19:40 vruppert - - * VGABIOS-lgpl-latest.bin (1.35), VGABIOS-lgpl-latest.debug.bin (1.35), - vgabios.c (1.41): - - - functions biosfn_get_video_mode() and biosfn_read_display_code() rewritten - in assembler - -2004-04-04 18:20 vruppert - - * VGABIOS-lgpl-latest.bin (1.34), VGABIOS-lgpl-latest.debug.bin (1.34), - vgabios.c (1.40): - - - write character function for CGA modes added - - read/write graphics pixel for CGA and LINEAR8 modes added - -2004-02-23 21:08 vruppert - - * VGABIOS-lgpl-latest.bin (1.33), VGABIOS-lgpl-latest.debug.bin (1.33), - vbe.c (1.39): - - - dispi_get_max_bpp(): restore the original value of the vbe enable register - -2004-02-22 14:17 vruppert - - * README (1.6), vbe.c (1.38), vbe.h (1.20), vbe_display_api.txt (1.9), - VGABIOS-lgpl-latest.bin (1.32), VGABIOS-lgpl-latest.debug.bin (1.32): - - - new function dispi_get_max_bpp() returns the bpp capabilities of the Bochs gui - - create the mode list depending on the supported bpp capability - - unused stuff removed - - documentation updated - -2004-02-21 18:20 vruppert - - * vbe.c (1.37), vbe.h (1.19), vbetables.h (1.23), - VGABIOS-lgpl-latest.bin (1.31), VGABIOS-lgpl-latest.debug.bin (1.31): - - - dynamicly genarated vbe mode_info list works now - -2003-11-17 21:04 vruppert - - * vbe.c (1.36), vbetables.h (1.22), vgabios.c (1.39), vgatables.h (1.6), - VGABIOS-lgpl-latest.bin (1.30), VGABIOS-lgpl-latest.debug.bin (1.30): - - - new VBE presence flag stored at unused BDA address 0xB9 - - VBE init code rewritten - - added BIOS TTY flag for VBE mode 0x0102 (TODO: scrolling) - - vgabios_init_func: load and activate text font already done by set_video_mode - - function biosfn_get_all_palette_reg() fixed - -2003-11-06 00:26 cbothamy - - * README (1.5): - - - add changes for 0.4c release - -2003-11-06 00:22 cbothamy - - * VGABIOS-lgpl-latest.bin (1.29), VGABIOS-lgpl-latest.debug.bin - (1.29): - - - compile vgabios.c rev1.38 - -2003-11-06 00:21 cbothamy - - * vgabios.c (1.38): - - - activate char table after loading it when setting a text video - mode - -2003-11-06 00:19 cbothamy - - * Makefile (1.12): - - - when making a release, remove unwanted files first, and exclude - CVS from the tarball - -2003-11-04 22:50 cbothamy - - * ChangeLog (1.20, v0_4b): - - - update ChangeLog for 0.4b release - -2003-11-04 22:49 cbothamy - - * README (1.4, v0_4b): - - - update Changes for 0.4b release - -2003-11-04 20:26 vruppert - - * vgabios.c (1.37), VGABIOS-lgpl-latest.bin (1.28), - VGABIOS-lgpl-latest.debug.bin (1.28) (utags: v0_4b): - - - biosfn_get_font_info(): character height must be returned in CX - -2003-11-03 21:57 vruppert - - * vbe.c (1.35, v0_4b), vgabios.c (1.36), VGABIOS-lgpl-latest.bin - (1.27), VGABIOS-lgpl-latest.debug.bin (1.27): - - - the 'noclearmem' flag is not stored in the 'current video mode' - register (0040h:0049h) - VBE also stores the 'noclear' flag in - the 'video control' register (0040h:0087h) - -2003-10-05 10:06 vruppert - - * vbe.h (1.18, v0_4b), vbe_display_api.txt (1.8, v0_4b), - VGABIOS-lgpl-latest.bin (1.26), VGABIOS-lgpl-latest.debug.bin - (1.26): - - - changed VBE i/o registers to 0x01CE/CF (suggestion from Daniel - Gimpelevich) - -2003-08-18 18:38 vruppert - - * VGABIOS-lgpl-latest.bin (1.25), VGABIOS-lgpl-latest.debug.bin - (1.25), vgabios.c (1.35): - - - wrong offsets to the character tables (INT 0x1F/0x43) fixed - (underscore added) - functions accessing the CRT controller - optimized using a local variable 'crtc_addr' - -2003-08-17 15:46 cbothamy - - * ChangeLog (1.19, v0_4a): - - - ChangeLog is now automatically generated by running "cvs2cl -r - -t -P -S" - update ChangeLog for 0.4a release - -2003-08-17 15:44 cbothamy - - * README (1.3, v0_4a): - - - added the old ChangeLog in the HOSTORY section of the README - file - update History for 0.4a release, with a summary of Changes - -2003-08-17 15:24 cbothamy - - * Makefile (1.11, v0_4b, v0_4a): - - - fix Makefile for "release" target - -2003-08-16 01:49 cbothamy - - * Makefile (1.10), README (1.2), VGABIOS-lgpl-latest.bin (1.24, - v0_4a), VGABIOS-lgpl-latest.debug.bin (1.24, v0_4a), vgabios.c - (1.34, v0_4a): - - - update the Makefile for releases - remove references to old - plex86 website - update the Makefile so it build - VGABIOS-lgpl-latest.bin and VGABIOS-lgpl-latest.debug.bin - -2003-08-07 18:17 vruppert - - * VGABIOS-lgpl-latest.bin (1.23), VGABIOS-lgpl-latest.debug.bin - (1.23): - - - current VBE mode now stored in BDA (unused address 0xBA) - -2003-08-07 17:54 vruppert - - * vbe.c (1.34), vgatables.h (1.5, v0_4b) (utags: v0_4a): - - - current VBE mode now stored in BDA (unused address 0xBA) - -2003-07-20 18:05 vruppert - - * vgabios.c (1.33), VGABIOS-lgpl-latest.bin (1.22), - VGABIOS-lgpl-latest.debug.bin (1.22): - - - fixed a few functions accessing the attribute controller - -2003-07-19 09:33 vruppert - - * vgabios.c (1.32), VGABIOS-lgpl-latest.bin (1.21), - VGABIOS-lgpl-latest.debug.bin (1.21): - - - re-enable video after programming the attribute controller - - biosfn_set_all_palette_reg(): number of palette registers fixed - -2003-07-16 22:32 vruppert - - * ChangeLog (1.18), vbe.c (1.33), vbe.h (1.17, v0_4a), - vbe_display_api.txt (1.7, v0_4a), vgabios.c (1.31), - VGABIOS-lgpl-latest.bin (1.20), VGABIOS-lgpl-latest.debug.bin - (1.20): - - - LFB flag now stored in the register VBE_DISPI_INDEX_ENABLE - - release date in Changelog fixed - release date of VBE BIOS 0.6 - was the same as VGA BIOS 0.3b - year changed in copyright - messages - -2003-07-15 12:40 vruppert - - * VGABIOS-lgpl-latest.bin (1.19), VGABIOS-lgpl-latest.debug.bin - (1.19): - - - new function dispi_get_bpp() - function - vbe_biosfn_set_get_logical_scan_line_length() fixed for >8bpp - - number of image pages of all VBE modes fixed - -2003-07-15 12:35 vruppert - - * vbe.c (1.32), vbetables.h (1.21, v0_4b, v0_4a): - - - new function dispi_get_bpp() - function - vbe_biosfn_set_get_logical_scan_line_length() fixed for >8bpp - - number of image pages of all VBE modes fixed - -2003-07-14 19:45 vruppert - - * vbe_display_api.txt (1.6): - - - description of VBE_DISPI_ interface 0xb0c2 added - -2003-07-10 19:07 vruppert - - * vbe.c (1.31), vbetables.h (1.20), VGABIOS-lgpl-latest.bin (1.18), - VGABIOS-lgpl-latest.debug.bin (1.18): - - - 15 bpp VBE modes added - "Bochs own" mode 0x142 (640x480x32bpp) - added - -2003-07-01 19:00 vruppert - - * vbe.c (1.30), vbe.h (1.16), vbetables.h (1.19), - VGABIOS-lgpl-latest.bin (1.17), VGABIOS-lgpl-latest.debug.bin - (1.17): - - - VBE preserve display memory feature implemented - VBE mode - entries 0x117 and 0x118 added - -2003-06-30 21:27 vruppert - - * vbe.c (1.29), vbe.h (1.15), vbetables.h (1.18), - VGABIOS-lgpl-latest.bin (1.16), VGABIOS-lgpl-latest.debug.bin - (1.16): - - - VBE mode info blocks of modes with >8bpp enabled - VBE modes - with 24 bpp: bytes per scanline fixed - vbe_biosfn_set_mode() now - supports >8bpp - VBE will be enabled with new VBE_DISPI_ID2 - (0xB0C2) - -2003-06-29 12:53 vruppert - - * vbetables.h (1.17), VGABIOS-lgpl-latest.bin (1.15), - VGABIOS-lgpl-latest.debug.bin (1.15): - - - duplicate lines with VBE_MODE_ATTRIBUTE_GRAPHICS_MODE removed - - VBE mode info items of currently unsupported modes fixed - -2003-06-15 21:19 vruppert - - * vgabios.c (1.30), VGABIOS-lgpl-latest.bin (1.14), - VGABIOS-lgpl-latest.debug.bin (1.14): - - - function write_gfx_char() rewritten - -2003-04-26 09:27 vruppert - - * VGABIOS-lgpl-latest.debug.bin (1.13): - - - added missing VBE function dispi_get_bank() - added missing - return codes for VBE function 4F05h - memory size is always - reported in VBE function 4F00h - fixed scan line length for VBE - mode 0102h - fixed function set_active_page() for graphics modes - - fixed the page sizes of some VGA modes - -2003-04-26 09:22 vruppert - - * vbe.c (1.28), vbetables.h (1.16), vgabios.c (1.29), vgatables.h - (1.4), VGABIOS-lgpl-latest.bin (1.13): - - - added missing VBE function dispi_get_bank() - added missing - return codes for VBE function 4F05h - memory size is always - reported in VBE function 4F00h - fixed scan line length for VBE - mode 0102h - fixed function set_active_page() for graphics modes - - fixed the page sizes of some VGA modes - -2003-04-20 09:51 vruppert - - * vgabios.c (1.28), vgatables.h (1.3), VGABIOS-lgpl-latest.bin - (1.12), VGABIOS-lgpl-latest.debug.bin (1.12): - - - function write_gfx_char() now supports different font sizes - - some entries of the static functionality table fixed - -2003-04-18 09:23 vruppert - - * vbe.c (1.27), vbe.h (1.14), vbetables.h (1.15): - - - applied patch #1331 * new function dispi_set_bank_farcall() - * VBE mode info item WinFuncPtr points to the new function if the - flag VBE_WINDOW_ATTRIBUTE_RELOCATABLE is set * flag - VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE added - -2003-02-11 20:17 vruppert - - * VGABIOS-lgpl-latest.bin (1.11), VGABIOS-lgpl-latest.debug.bin - (1.11), vbe.c (1.26), vbetables.h (1.14): - - - VBE mode search rewritten * improved function - mode_info_find_mode() is now used by the VBE functions 0x4F01 - and 0x4F02 * removed all mode list entries with the LFB bit - set. LFB detection is now present in the function - mode_info_find_mode() - -2003-02-09 20:59 vruppert - - * VGABIOS-lgpl-latest.bin (1.10), VGABIOS-lgpl-latest.debug.bin - (1.10), vgabios.c (1.27): - - - function write_gfx_char(): memory address now calculated in - this function; background color is always black - function - biosfn_write_char_attr(): the count parameter is now used in - graphics modes too - function biosfn_write_char_only() works - the same way as function biosfn_write_char_attr() in graphics - mode - copying charmap data optimized using memcpyb() - -2003-02-09 11:36 vruppert - - * VGABIOS-lgpl-latest.bin (1.9), VGABIOS-lgpl-latest.debug.bin - (1.9): - - - VESA mode 0x102 added (uses existing SVGA mode 0x6a) - all VESA - modes with the LFB flag set removed from the list (Linux doesn't - like mode numbers > 0x07ff) - -2003-02-09 11:02 vruppert - - * vbe.c (1.25), vbe.h (1.13), vbetables.h (1.13): - - - VESA mode 0x102 added (uses existing SVGA mode 0x6a) - all VESA - modes with the LFB flag set removed from the list (Linux doesn't - like mode numbers > 0x07ff) - -2003-02-08 13:04 vruppert - - * vbe.c (1.24), vgabios.c (1.26): - - - vbe_biosfn_return_current_mode() now returns the active - standard VGA mode TODO: return VESA mode if enabled - - biosfn_set_video_mode() now clears the screen in CGA mode - correctly - write character functions are now working in all - PLANAR4 graphics modes - added stubs for unimplemented features - in graphics modes - -2003-02-04 22:19 vruppert - - * VGABIOS-lgpl-latest.bin (1.8), VGABIOS-lgpl-latest.debug.bin - (1.8): - - - set video mode: clear vga memory in graphics mode - set video - mode: load default font in text mode - write character - implemented for graphics mode 0x12 - -2003-02-04 22:06 vruppert - - * vgabios.c (1.25): - - - set video mode: clear vga memory in graphics mode - set video - mode: load default font in text mode - write character - implemented for graphics mode 0x12 - -2003-01-21 19:30 vruppert - - * vgabios.c (1.24): - - - remap the cursor size if the char height is > 8 and the new - values are < 8 - -2003-01-20 18:24 cbothamy - - * Makefile (1.9): - - - fix so make -j2 does not overwrite temp files - -2003-01-19 12:35 vruppert - - * vgabios.c (1.23): - - - function set_scan_lines() recalculates the number of rows and - the page size - new values for char height, text rows and page - size are stored in the BIOS data segment - asm helper function - idiv_u added - -2003-01-15 18:49 cbothamy - - * VGABIOS-lgpl-latest.bin (1.7), VGABIOS-lgpl-latest.debug.bin - (1.7): - - - compile vgabios rev 1.22 - -2003-01-15 18:49 cbothamy - - * vgabios.c (1.22): - - - fix bug found by ams : a 8bits index value was compared to - 0x100 in some cases in biosfn_set_all_dac_reg, - biosfn_read_all_dac_reg, biosfn_perform_gray_scale_summing - -2003-01-15 17:34 cbothamy - - * Makefile (1.8): - - - fix symbol table file names, discovered by ams - -2003-01-04 21:20 vruppert - - * VGABIOS-lgpl-latest.bin (1.6), VGABIOS-lgpl-latest.debug.bin - (1.6), vgabios.c (1.21): - - - biosfn_set_video_mode(): reset attribute controller flip-flop - before setting up the controller's registers (bug found with - amidiag) - -2003-01-04 09:50 vruppert - - * vbe.c (1.23): - - - VBE function 0x00 returns VBE 1.x compatible information if no - VBE signature is present - -2003-01-01 12:44 vruppert - - * VGABIOS-lgpl-latest.bin (1.5), VGABIOS-lgpl-latest.debug.bin - (1.5): - - - SVGA mode 0x6A (800x600x4) added to the list of graphics modes - -2002-12-31 18:07 vruppert - - * vgatables.h (1.2): - - - SVGA mode 0x6A (800x600x4) added to the list of graphics modes - -2002-11-23 10:38 cbothamy - - * ChangeLog (1.17, v0_3b): - - - fix changelog for 0.3b release - -2002-10-20 17:12 vruppert - - * VGABIOS-lgpl-latest.bin (1.4), VGABIOS-lgpl-latest.debug.bin - (1.4), vgabios.c (1.20) (utags: v0_3b): - - - new function set_scan_lines() for the font size change (patch - from Hartmut Birr) - cursor shape start and end must be updated - in set_scan_lines() - set_scan_lines() is called by the functions - 0x1110, 0x1111, 0x1112 and 0x1114 after copying the font data - -2002-10-04 08:20 vruppert - - * VGABIOS-lgpl-latest.bin (1.3), VGABIOS-lgpl-latest.debug.bin - (1.3), vgabios.c (1.19): - - - biosfn_set_single_dac_reg(): the red value is stored in DH - -2002-09-19 19:05 cbothamy - - * VGABIOS-lgpl-latest.bin (1.2), VGABIOS-lgpl-latest.debug.bin - (1.2): - - - updated with latest changes - -2002-09-19 19:03 cbothamy - - * ChangeLog (1.16), Makefile (1.7, v0_3b), vbe.c (1.22, v0_3b), - vgabios.c (1.18), vgabios.h (1.3, v0_4b, v0_4a, v0_3b): - - - updated the Makefile - removed display of copyrights. - - changed the Copyright string to "LGPL VGABios developers" - -2002-09-08 21:14 vruppert - - * vgabios.c (1.17): - - - set the cursor shape depending on the current font height - - clear BL before calling int 0x10 function 0x1103 in - vgabios_init_func - -2002-08-23 22:58 cbothamy - - * vbe.c (1.21), vbetables.h (1.12, v0_3b): - - - added lfb-mode numbers (patch from mathis) - -2002-07-21 21:57 japj - - * vbe.c (1.20), vgabios.c (1.16): - - gcc2/3 preprocessing fix - -2002-05-18 16:55 cbothamy - - * vgabios.c (1.15): - - - include patch from Volker that adds some text font functions - -2002-05-01 23:13 japj - - * VGABIOS-lgpl-latest.bin (1.1), VGABIOS-lgpl-latest.debug.bin - (1.1): - - adding latest bin & debug bin of the vgabios - -2002-04-29 14:50 japj - - * ChangeLog (1.15), vbe.c (1.19), vbe.h (1.12, v0_3b), vbetables.h - (1.11), vgabios.c (1.14): - - - applying hw scrolling/multibuffering patch - -2002-04-25 21:59 japj - - * Makefile (1.6), vbe.c (1.18), vgabios.c (1.13): - - - reverting #asm/##asm & endasm patch (does not work with with - cygwin) - -2002-04-19 19:38 japj - - * Makefile (1.5), vbe.c (1.17), vgabios.c (1.12): - - - fixing preprocessing of vgabios with latest gcc (from Mandrake - 8.2) - -2002-04-08 23:44 japj - - * ChangeLog (1.14), vbe_display_api.txt (1.5, v0_3b): - - - preparing docs for new DISPI interface (for hardware scrolling) - -2002-04-03 19:06 japj - - * ChangeLog (1.13), TODO (1.9, v0_4b, v0_4a, v0_3b), vbe.c (1.16): - - - defaulting LFB on + updated changelog & todo - -2002-04-03 00:38 cbothamy - - * vbe.c (1.15), vgabios.c (1.11): - - - changed the logging ports to 0x500 -> 0x502 - -2002-03-14 17:54 japj - - * vbe.c (1.14): - - - vbetables.h is dependant upon some defines (VBE_HAVE_LFB), so - put the include *after* the define - -2002-03-13 21:47 japj - - * ChangeLog (1.12), TODO (1.8), vbe.c (1.13), vbetables.h (1.10), - vgabios.c (1.10): - - - made LFB dependant upon define - not implement vbe functions - return failure - updated todo & docs for things after bochs 1.4 - -2002-03-13 19:46 japj - - * vbe.h (1.11), vbe_display_api.txt (1.4): - - - added max video memory + documented what is in the 0xb0c0 - interface - -2002-03-12 02:33 cbothamy - - * ChangeLog (1.11), Makefile (1.4): - - - updated for 0.3a. Merged vgabios.bin and vbebios.bin - -2002-03-10 21:36 japj - - * ChangeLog (1.10), vbetables.h (1.9): - - - added LFB modes for testing with vbe-lfb patch in Bochs - -2002-03-10 17:42 japj - - * vbe.c (1.12, v0_3a): - - - show people when they do NOT have VBE support available - -2002-03-10 17:36 japj - - * TODO (1.7, v0_3a), vbe.c (1.11), vbe.h (1.10, v0_3a), vgabios.c - (1.9, v0_3a): - - - cleanup of vbe internal functions (set 8bpp mode is now - dependant on ModeInfo content instead of hardcoded functions) - -2002-03-10 17:20 cbothamy - - * ChangeLog (1.9, v0_3a), TODO (1.6): - - - updated for 0.3a - -2002-03-10 17:19 cbothamy - - * vbe.c (1.10), vbe.h (1.9): - - - added vbe_has_vbe_display function that detects an attached vbe - display - -2002-03-10 17:12 cbothamy - - * vgabios.c (1.8): - - - vbe calls are done only if a vbe display is detected - -2002-03-10 11:25 japj - - * vbe.h (1.8), vbe_display_api.txt (1.3, v0_3a): - - - preparing for LFB support - -2002-03-09 14:25 japj - - * vgabios.c (1.7): - - - fixing initial cursor shape to _ instead of - - -2002-03-08 23:08 japj - - * ChangeLog (1.8), TODO (1.5), vbe.c (1.9), vbe.h (1.7), vgabios.c - (1.6): - - - updating vbe code to new API - -2002-03-08 21:48 japj - - * vbe.c (1.8), vbe.h (1.6), vbetables.h (1.8, v0_3a): - - - updating vbe code with #defines from API - -2002-03-08 21:31 japj - - * vbe_display_api.txt (1.2): - - - adding some text about how banks work - -2002-03-08 21:09 japj - - * ChangeLog (1.7), vbe_display_api.txt (1.1): - - - adding vbe_display_api documentation - -2002-03-07 21:36 japj - - * ChangeLog (1.6), vbe.c (1.7), vbetables.h (1.7): - - - added 1024x768xbpp support - some more cleanups/comments - -2002-03-06 21:55 japj - - * ChangeLog (1.5), TODO (1.4), vbe.c (1.6), vbetables.h (1.6), - vgabios.c (1.5): - - - updated changelog with new modi - added 640x480x8 (Mandrake - Installer can use this!) - added pre VBE2 compatible 'detection' - - fixed problem when normal vga set mode wouldn't disable vbe - mode - -2002-03-06 20:59 japj - - * TODO (1.3), vbe.c (1.5), vbe.h (1.5), vbetables.h (1.5), - vgabios.c (1.4): - - - adding 640x400x8 and 800x600x8 vbe support (this depends - HEAVILY on my bochs vga code patch - japj) - -2002-03-06 18:00 japj - - * vbe.c (1.4), vbe.h (1.4), vbetables.h (1.4): - - - implemented banked & lfb support for 320x200x8bpp (some fixes - for vbetest program not displaying anything) - -2002-03-05 20:25 japj - - * Makefile (1.3, v0_3a): - - for vbe debug bios: - print debugging information in assembly - output - print source code in assembly output - -2002-03-01 19:39 japj - - * ChangeLog (1.4), TODO (1.2), vbe.c (1.3), vbe.h (1.3), - vbetables.h (1.3): - - - added vbe support for 320x200x8 using the standard vgamode - (0x13) - -2002-02-19 00:29 japj - - * ChangeLog (1.3): - - - updating ChangeLog with lfbprof - -2002-02-18 23:26 japj - - * tests/lfbprof/: lfbprof.c (1.2), lfbprof.h (1.2) (utags: v0_3a, - v0_3b, v0_4a, v0_4b): - - - fixed unsigned short for mode list (-1 != 0xffff otherwise) - - fixed LfbMapRealPointer macro mask problem (some modes were - skipped) - added some extra 'debugging' printf's - -2002-02-18 23:07 japj - - * tests/lfbprof/: Makefile (1.1, v0_4b, v0_4a, v0_3b, v0_3a), - lfbprof.c (1.1), lfbprof.h (1.1): - - - Adding lfbprof testprogram (for vbe testing purposes) It - needs to be compiled with the Watcom C Compiler - -2002-02-18 18:48 japj - - * vbe.c (1.2), vbe.h (1.2): - - - cosmetic updates to vbe.c/h + added bunch of FIXMEs for work - that needs to be done - -2002-02-18 18:34 japj - - * vbetables.h (1.2): - - - cosmetic updates in vbetables.h - -2002-02-18 18:32 japj - - * ChangeLog (1.2): - - updated changelog with merge of vbebios 0.2 - -2002-02-18 18:07 japj - - * vgabios.c (1.3): - - - small cosmetic cleanup in vgabios vbe code + added FIXMEs - -2002-02-18 17:55 japj - - * Makefile (1.2), dataseghack (1.2, v0_4b, v0_4a, v0_3b, v0_3a), - vbe.c (1.1), vbe.h (1.1), vbetables.h (1.1), vgabios.c (1.2), - vgabios.h (1.2, v0_3a): - - - merging with vbebios 0.2 release - -2002-02-18 11:31 cbothamy - - * BUGS (1.1, v0_4b, v0_4a, v0_3b, v0_3a), COPYING (1.1, v0_4b, - v0_4a, v0_3b, v0_3a), ChangeLog (1.1), Makefile (1.1), Notes - (1.1, v0_4b, v0_4a, v0_3b, v0_3a), README (1.1, v0_3b, v0_3a), - TODO (1.1), dataseghack (1.1), vgabios.c (1.1), vgabios.h (1.1), - vgafonts.h (1.1, v0_4b, v0_4a, v0_3b, v0_3a), vgatables.h (1.1, - v0_3b, v0_3a), tests/testbios.c (1.1, v0_4b, v0_4a, v0_3b, - v0_3a): - - - initial import - diff --git a/roms/vgabios/Makefile b/roms/vgabios/Makefile deleted file mode 100644 index 578721a..0000000 --- a/roms/vgabios/Makefile +++ /dev/null @@ -1,103 +0,0 @@ -SHELL = /bin/sh - -CC = gcc -CFLAGS = -g -O2 -Wall -Wstrict-prototypes -LDFLAGS = - -GCC = gcc -BCC = bcc -AS86 = as86 - -RELEASE = `pwd | sed "s-.*/--"` -RELDATE = `date '+%d %b %Y'` -RELVERS = `pwd | sed "s-.*/--" | sed "s/vgabios//" | sed "s/-//"` - -VGABIOS_DATE = "-DVGABIOS_DATE=\"$(RELDATE)\"" - -all: bios cirrus-bios stdvga-bios vmware-bios qxl-bios - -bios: vgabios.bin vgabios.debug.bin - -cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin - -stdvga-bios: vgabios-stdvga.bin vgabios-stdvga.debug.bin - -vmware-bios: vgabios-vmware.bin vgabios-vmware.debug.bin - -qxl-bios: vgabios-qxl.bin vgabios-qxl.debug.bin - -clean: - /bin/rm -f biossums vbetables-gen vbetables.h *.o *.s *.ld86 \ - temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak - -dist-clean: clean - -# source files -VGA_FILES := vgabios.c vgabios.h vgafonts.h vgatables.h -VBE_FILES := vbe.h vbe.c vbetables.h - -# build flags -vgabios.bin : VGAFLAGS := -DVBE -DPCI_VID=0x1234 -vgabios.debug.bin : VGAFLAGS := -DVBE -DPCI_VID=0x1234 -DDEBUG -vgabios-cirrus.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS -vgabios-cirrus.debug.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS -DCIRRUS_DEBUG -vgabios-stdvga.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1234 -DPCI_DID=0x1111 -vgabios-stdvga.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1234 -DPCI_DID=0x1111 -DDEBUG -vgabios-vmware.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x15ad -DPCI_DID=0x0405 -vgabios-vmware.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x15ad -DPCI_DID=0x0405 -DDEBUG -vgabios-qxl.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1b36 -DPCI_DID=0x0100 -vgabios-qxl.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1b36 -DPCI_DID=0x0100 -DDEBUG - -# dist names -vgabios.bin : DISTNAME := VGABIOS-lgpl-latest.bin -vgabios.debug.bin : DISTNAME := VGABIOS-lgpl-latest.debug.bin -vgabios-cirrus.bin : DISTNAME := VGABIOS-lgpl-latest.cirrus.bin -vgabios-cirrus.debug.bin : DISTNAME := VGABIOS-lgpl-latest.cirrus.debug.bin -vgabios-stdvga.bin : DISTNAME := VGABIOS-lgpl-latest.stdvga.bin -vgabios-stdvga.debug.bin : DISTNAME := VGABIOS-lgpl-latest.stdvga.debug.bin -vgabios-vmware.bin : DISTNAME := VGABIOS-lgpl-latest.vmware.bin -vgabios-vmware.debug.bin : DISTNAME := VGABIOS-lgpl-latest.vmware.debug.bin -vgabios-qxl.bin : DISTNAME := VGABIOS-lgpl-latest.qxl.bin -vgabios-qxl.debug.bin : DISTNAME := VGABIOS-lgpl-latest.qxl.debug.bin - -# dependencies -vgabios.bin : $(VGA_FILES) $(VBE_FILES) biossums -vgabios.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums -vgabios-cirrus.bin : $(VGA_FILES) clext.c biossums -vgabios-cirrus.debug.bin : $(VGA_FILES) clext.c biossums -vgabios-stdvga.bin : $(VGA_FILES) $(VBE_FILES) biossums -vgabios-stdvga.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums -vgabios-vmware.bin : $(VGA_FILES) $(VBE_FILES) biossums -vgabios-vmware.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums -vgabios-qxl.bin : $(VGA_FILES) $(VBE_FILES) biossums -vgabios-qxl.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums - -# build rule -%.bin: - $(GCC) -E -P vgabios.c $(VGABIOS_VERS) $(VGAFLAGS) $(VGABIOS_DATE) > _$*_.c - $(BCC) -o $*.s -C-c -D__i86__ -S -0 _$*_.c - sed -e 's/^\.text//' -e 's/^\.data//' $*.s > _$*_.s - $(AS86) _$*_.s -b $*.bin -u -w- -g -0 -j -O -l $*.txt - rm -f _$*_.s _$*_.c $*.s - mv $*.bin $(DISTNAME) - ./biossums $(DISTNAME) - ls -l $(DISTNAME) - -release: - VGABIOS_VERS=\"-DVGABIOS_VERS=\\\"$(RELVERS)\\\"\" make bios cirrus-bios - /bin/rm -f *.o *.s *.ld86 \ - temp.awk.* vgabios.*.orig _vgabios_.*.c core *.bak .#* - cp VGABIOS-lgpl-latest.bin ../$(RELEASE).bin - cp VGABIOS-lgpl-latest.debug.bin ../$(RELEASE).debug.bin - cp VGABIOS-lgpl-latest.cirrus.bin ../$(RELEASE).cirrus.bin - cp VGABIOS-lgpl-latest.cirrus.debug.bin ../$(RELEASE).cirrus.debug.bin - tar czvf ../$(RELEASE).tgz --exclude CVS -C .. $(RELEASE)/ - -biossums: biossums.c - $(CC) -o biossums biossums.c - -vbetables-gen: vbetables-gen.c - $(CC) -o vbetables-gen vbetables-gen.c - -vbetables.h: vbetables-gen - ./vbetables-gen > $@ diff --git a/roms/vgabios/Notes b/roms/vgabios/Notes deleted file mode 100644 index d5b708d..0000000 --- a/roms/vgabios/Notes +++ /dev/null @@ -1,11 +0,0 @@ -Development notes ------------------ - -- need to split video init function - 1. set bios variables - 2. do the real init with io based on bios variables - -- characters format switching will set the bios - variables and call function #2 above - -- need to rework the tables as explained in Interrupt list diff --git a/roms/vgabios/README b/roms/vgabios/README deleted file mode 100644 index c68b573..0000000 --- a/roms/vgabios/README +++ /dev/null @@ -1,226 +0,0 @@ -Plex86/Bochs VGABios --------------------- - -The goal of this project is to have a LGPL'd Video Bios in plex86, -Bochs and qemu. -This VGA Bios is very specific to the emulated VGA card. -It is NOT meant to drive a physical vga card. - - -Cirrus SVGA extension ---------------------- - -The Cirrus SVGA extension is designed for the Cirrus emulation in Bochs and -qemu. The initial patch for the Cirrus extension has been written by Makoto -Suzuki (suzu). - - -Install -------- -To compile the VGA Bios you will need : -- gcc -- bcc -- as86 -- ld86 - -Untar the archive, and type make. You should get a "VGABIOS-lgpl-latest.bin" -file. Alternatively, you can use the binary file "VGABIOS-lgpl-latest.bin", -i have compiled for you. - -Edit your plex86/bochs conf file, and modify the load-rom command in the -VGA BIOS section, to point to the new vgabios image file. - - -Debugging ---------- -You can get a very basic debugging system: messages printed by the vgabios. -You have to register the "unmapped" device driver in plex86 or bochs, and make -sure it grabs port 0xfff0. - -Comment the #undef DEBUG at the beginning of vgabios.c. -You can then use the "printf" function in the bios. - - -Testing -------- -Look at the "testvga.c" file in the archive. This is a minimal Turbo C 2.0 -source file that calls a few int10 functions. Feel free to modify it to suit -your needs. - - -Copyright and License ---------------------- -This program has been written by Christophe Bothamy -It is protected by the GNU Lesser Public License, which you should -have received a copy of along with this package. - - -Reverse Engineering -------------------- -The VGA Bios has been written without reverse-engineering any existing Bios. - - -Acknowledgment --------------- -The source code contains code ripped from rombios.c of plex86, written -by Kevin Lawton - -The source code contains fonts from fntcol16.zip (c) by Joseph Gil avalable at : -ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip -These fonts are public domain - -The source code is based on information taken from : -- Kevin Lawton's vga card emulation for bochs/plex86 -- Ralf Brown's interrupts list avalaible at - http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html -- Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ -- Michael Abrash's Graphics Programming Black Book -- Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" - edited by sybex -- DOSEMU 1.0.1 source code for several tables values and formulas - - -Feedback --------- -Please report any bugs, comments, patches for this VGA Bios to info@vruppert.de -You can find the latest release at : http://www.nongnu.org/vgabios/ -For any information on bochs, visit the website http://bochs.sourceforge.net/ -For any information on qemu, visit the website http://fabrice.bellard.free.fr/qemu/ - - -History -------- -vgabios-0.6c : Apr 08 2009 - - Volker - . added DPMS support to cirrus vgabios (patch from Gleb Natapov) - . use VBE LFB address from PCI base address if present - . added support for a lot more non-standard VBE modes (e.g. widescreen modes) - . minor bugfixes - -vgabios-0.6b : May 30 2008 - - Volker - . added PCI data structure for the Cirrus VGABIOS images - . minor bugfixes in biossums utility, VBE support and makefile - -vgabios-0.6a : Aug 19 2006 - - Volker - . added minimal support for the video parameter table (VPT) - . Cirrus SVGA now supports the "no clear" bit in Cirrus and VESA mode - . Bochs VBE protected mode interface improved - . save/restore video state support for Bochs VBE and standard VGA added - . generate vbetables.h dynamicly - . VBE video memory increased to 8 MB (VBE dispi ID changed to B0C4) - . lots of 4bpp VBE fixes (all 4bpp VBE modes now enabled) - . VGA compatible setup for VBE modes added - -vgabios-0.5d : Dec 29 2005 - - Volker - . Bochs VBE protected mode interface added (based on a patch by malc@pulsesoft.com) - . biossums utility now supports VGABIOS sizes up to 64 kBytes - . VGA mode 0x11: all color planes must be enabled in this 2-color VGA mode - -vgabios-0.5c : Jul 07 2005 - - Volker - . BIOS configuration word usually reports initial mode 80x25 color text - . vgabios function 0x0e (write teletype): linefeed (0x0a) only increments the - cursor row value - -vgabios-0.5b : May 24 2005 - - Volker - . fixed return value for the default case in the VBE section (non-debug mode) - . removed unused stuff - -vgabios-0.5a : Mar 07 2005 - - Volker - . Cirrus SVGA extension (initial patches from Makoto Suzuki, improvements - from Fabrice Bellard) - . vgabios image size is now exactly 32k with a checksum - . a lot of vgabios and vbe functions rewritten in assembler - . dynamicly generated VBE mode info list - . write character function for CGA and LINEAR8 modes - . read/write graphics pixel for some graphics modes - . text scroll feature for some graphics modes - . VBE 8-bit DAC support - -vgabios-0.4c : Nov 06 2003 - - Christophe - . fix font problem on initial screen of NT4 Loader - -vgabios-0.4b : Nov 04 2003 - - Volker - . fix offset of character tables - . optimizations of CRT controller accesses - . VBE i/o registers changed to 0x01CE/CF - (suggestion from Daniel Gimpelevich) - . "noclear" flag stored in BIOS area - . fix character height returned by get_font_info function - -vgabios-0.4a : Aug 17 2003 - - Volker - . VBE mode search rewritten (VBE modes with LFB bit removed) - . many bugfixes and optimizations - . write character function implemented for graphics modes - . support for 15bpp, 16bpp, 24bpp and 32bpp VBE modes added - . SVGA mode 0x6A added - . VBE modes 0x102, 0x117, 0x118 and 0x142 (Bochs specific) - -vgabios-0.3b : Nov 23 2002 - - Christophe - . added lfb-mode numbers (patch from mathis) - . updated the Makefile - . removed display of copyrights. - . changed the Copyright string to "LGPL VGABios developers" - - Volker - . set the cursor shape depending on the current font height - . clear BL before calling int 0x10 function 0x1103 in vgabios_init_func - . added some text font functions - - Jeroen - . Forced to new DISPI (0xb0c1) interface (requires latest bochs vbe code) - . Added multibuffering support - . Added new DISPI interface for: virt width, height, x offset, y offset - . Added LFB modes (to be used with the vbe-lfb patch in bochs) - see VBE_HAVE_LFB in vbe.c (currently default enabled) - . updated TODO & docs for changes after bochs 1.4 - -vgabios-0.3a : Mar 10 2002 - - Christophe - . Fixed bug in function ah=13 - - Jeroen - . updated vbebios implementation to new api - . added vbe_display_api documentation - . added 640x400x8, 640x480x8, 800x600x8, 1024x768 - (>640x480 needs a special bochs patch atm) - . added 320x200x8 vbe support (uses the standard 320x200x8 vga mode to - display, this allows for testing & having something on screen as well, - at least until bochs host side display is up & running) - . adding lfbprof (vbe) testprogram (+some small fixes to it) - . merging with vbebios 0.2 - -vgabios-0.2b : Nov 19 2001 - - Christophe - . Fixed bug in function ah=13 - -vgabios-0.2a : Nov 09 2001 - - Christophe - . Included bugfix from techt@pikeonline.net about grayscale summing - . Added the "IBM" string at org 0x1e as Bart Oldeman suggested - . Fixed DS and ES that where inverted in the int10 parameters list! - . The following have been implemented : - - function ax=1a00, ax=1a01, ah=1b - - function ax=1130 - . Added debug messages for unimplemented/unknown functions - Must be compiled with DEBUG defined. The output is trapped - by the unknown-ioport driver of plex/bochs (port 0xfff0 is used) - -vgabios-0.1a : May 8 2001 - - Christophe - . First release. The work has been focused only on text mode. - . The following have been implemented : - - inits - - int 10 handler - - functions ah=00, ah=01, ah=02, ah=03, ah=05, ah=06, ah=07, ah=08 - ah=09, ah=0a, ah=0e, ah=0f, ax=1000, ax=1001, ax=1002, ax=1003 - ax=1007, ax=1008, ax=1009, ax=1010, ax=1012, ax=1013, ax=1015 - ax=1017, ax=1018, ax=1019, ax=101a, ax=101b, ah=12 bl=10, - ah=12 bl=30, ah=12 bl=31, ah=12 bl=32, ah=12 bl=33, ah=12 bl=34 - ah=13 diff --git a/roms/vgabios/TODO b/roms/vgabios/TODO deleted file mode 100644 index b08ee4b..0000000 --- a/roms/vgabios/TODO +++ /dev/null @@ -1,26 +0,0 @@ -Short term : ------------- - -General - - Fix init mode (ah=00). Should use more BIOS variables - - Add new functionalities and modify static functionality table - - Performance : 16 bits IO - -v0.7 - - Implement the remaining functions (don't know if all are needed): - - chargen ax=1120, ax=1121, ax=1122, ax=1123, ax=1124 - - display switch interface ah=12 bl=35 - - video refresh control ah=12 bl=36 - - Graphic modes - -v1.0 - - Bugfixes - - -================================================================================================= -VBE: ----- -Long term: -- have plex86 host side display interface -- have text io functions in vbe mode - diff --git a/roms/vgabios/biossums.c b/roms/vgabios/biossums.c deleted file mode 100644 index d5816f4..0000000 --- a/roms/vgabios/biossums.c +++ /dev/null @@ -1,282 +0,0 @@ -/* biossums.c --- written by Eike W. for the Bochs BIOS */ -/* adapted for the LGPL'd VGABIOS by vruppert */ - -/* 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 - -typedef unsigned char byte; - -void check( int value, char* message ); - -#define MAX_BIOS_DATA 0x10000 - -long chksum_bios_get_offset( byte* data, long offset ); -byte chksum_bios_calc_value( byte* data, long offset ); -byte chksum_bios_get_value( byte* data, long offset ); -void chksum_bios_set_value( byte* data, long offset, byte value ); - -#define PMID_LEN 20 -#define PMID_CHKSUM 19 - -long chksum_pmid_get_offset( byte* data, long offset ); -byte chksum_pmid_calc_value( byte* data, long offset ); -byte chksum_pmid_get_value( byte* data, long offset ); -void chksum_pmid_set_value( byte* data, long offset, byte value ); - -#define PCIR_LEN 24 - -long chksum_pcir_get_offset( byte* data, long offset ); - - -byte bios_data[MAX_BIOS_DATA]; -long bios_len; - - -int main(int argc, char* argv[]) -{ - FILE* stream; - long offset, tmp_offset, pcir_offset; - byte bios_len_byte, cur_val = 0, new_val = 0; - int hits, modified; - - if (argc != 2) { - printf( "Error. Need a file-name as an argument.\n" ); - exit( EXIT_FAILURE ); - } - - if ((stream = fopen(argv[1], "rb")) == NULL) { - printf("Error opening %s for reading.\n", argv[1]); - exit(EXIT_FAILURE); - } - memset(bios_data, 0, MAX_BIOS_DATA); - bios_len = fread(bios_data, 1, MAX_BIOS_DATA, stream); - if (bios_len > MAX_BIOS_DATA) { - printf("Error reading max. 65536 Bytes from %s.\n", argv[1]); - fclose(stream); - exit(EXIT_FAILURE); - } - fclose(stream); - modified = 0; - if (bios_len < 0x8000) { - bios_len = 0x8000; - modified = 1; - } else if ((bios_len & 0x1FF) != 0) { - bios_len = (bios_len + 0x200) & ~0x1FF; - modified = 1; - } - bios_len_byte = (byte)(bios_len / 512); - if (bios_len_byte != bios_data[2]) { - if (modified == 0) { - bios_len += 0x200; - } - bios_data[2] = (byte)(bios_len / 512); - modified = 1; - } - - hits = 0; - offset = 0L; - while( (tmp_offset = chksum_pmid_get_offset( bios_data, offset )) != -1L ) { - offset = tmp_offset; - cur_val = chksum_pmid_get_value( bios_data, offset ); - new_val = chksum_pmid_calc_value( bios_data, offset ); - printf( "\nPMID entry at: 0x%4lX\n", offset ); - printf( "Current checksum: 0x%02X\n", cur_val ); - printf( "Calculated checksum: 0x%02X ", new_val ); - hits++; - } - if ((hits == 1) && (cur_val != new_val)) { - printf("Setting checksum."); - chksum_pmid_set_value( bios_data, offset, new_val ); - if (modified == 0) { - bios_len += 0x200; - bios_data[2]++; - } - modified = 1; - } - if (hits >= 2) { - printf( "Multiple PMID entries! No checksum set." ); - } - if (hits) { - printf("\n"); - } - - offset = 0L; - pcir_offset = chksum_pcir_get_offset( bios_data, offset ); - if (pcir_offset != -1L) { - if (bios_data[pcir_offset + 16] != bios_data[2]) { - bios_data[pcir_offset + 16] = bios_data[2]; - if (modified == 0) { - bios_len += 0x200; - bios_data[2]++; - bios_data[pcir_offset + 16]++; - } - modified = 1; - } - } - - offset = 0L; - do { - offset = chksum_bios_get_offset(bios_data, offset); - cur_val = chksum_bios_get_value(bios_data, offset); - new_val = chksum_bios_calc_value(bios_data, offset); - if ((cur_val != new_val) && (modified == 0)) { - bios_len += 0x200; - bios_data[2]++; - if (pcir_offset != -1L) { - bios_data[pcir_offset + 16]++; - } - modified = 1; - } else { - printf("\nBios checksum at: 0x%4lX\n", offset); - printf("Current checksum: 0x%02X\n", cur_val); - printf("Calculated checksum: 0x%02X ", new_val); - if (cur_val != new_val) { - printf("Setting checksum."); - chksum_bios_set_value(bios_data, offset, new_val); - cur_val = new_val; - modified = 1; - } - printf( "\n" ); - } - } while (cur_val != new_val); - - if (modified == 1) { - if ((stream = fopen( argv[1], "wb")) == NULL) { - printf("Error opening %s for writing.\n", argv[1]); - exit(EXIT_FAILURE); - } - if (fwrite(bios_data, 1, bios_len, stream) < bios_len) { - printf("Error writing %d KBytes to %s.\n", bios_len / 1024, argv[1]); - fclose(stream); - exit(EXIT_FAILURE); - } - fclose(stream); - } - - return (EXIT_SUCCESS); -} - - -void check( int okay, char* message ) { - - if( !okay ) { - printf( "\n\nError. %s.\n", message ); - exit( EXIT_FAILURE ); - } -} - - -long chksum_bios_get_offset( byte* data, long offset ) { - - return (bios_len - 1); -} - - -byte chksum_bios_calc_value( byte* data, long offset ) { - - int i; - byte sum; - - sum = 0; - for( i = 0; i < offset; i++ ) { - sum = sum + *( data + i ); - } - sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ - return( sum ); -} - - -byte chksum_bios_get_value( byte* data, long offset ) { - - return( *( data + offset ) ); -} - - -void chksum_bios_set_value( byte* data, long offset, byte value ) { - - *( data + offset ) = value; -} - - -byte chksum_pmid_calc_value( byte* data, long offset ) { - - int i; - int len; - byte sum; - - len = PMID_LEN; - check((offset + len) <= (bios_len - 1), "PMID entry length out of bounds" ); - sum = 0; - for( i = 0; i < len; i++ ) { - if( i != PMID_CHKSUM ) { - sum = sum + *( data + offset + i ); - } - } - sum = -sum; - return( sum ); -} - - -long chksum_pmid_get_offset( byte* data, long offset ) { - - long result = -1L; - - while ((offset + PMID_LEN) < (bios_len - 1)) { - offset = offset + 1; - if( *( data + offset + 0 ) == 'P' && \ - *( data + offset + 1 ) == 'M' && \ - *( data + offset + 2 ) == 'I' && \ - *( data + offset + 3 ) == 'D' ) { - result = offset; - break; - } - } - return( result ); -} - - -byte chksum_pmid_get_value( byte* data, long offset ) { - - check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); - return( *( data + offset + PMID_CHKSUM ) ); -} - - -void chksum_pmid_set_value( byte* data, long offset, byte value ) { - - check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); - *( data + offset + PMID_CHKSUM ) = value; -} - - -long chksum_pcir_get_offset( byte* data, long offset ) { - - long result = -1L; - - while ((offset + PCIR_LEN) < (bios_len - 1)) { - offset = offset + 1; - if( *( data + offset + 0 ) == 'P' && \ - *( data + offset + 1 ) == 'C' && \ - *( data + offset + 2 ) == 'I' && \ - *( data + offset + 3 ) == 'R' ) { - result = offset; - break; - } - } - return( result ); -} diff --git a/roms/vgabios/clext.c b/roms/vgabios/clext.c deleted file mode 100644 index b0b6834..0000000 --- a/roms/vgabios/clext.c +++ /dev/null @@ -1,1641 +0,0 @@ -// -// QEMU Cirrus CLGD 54xx VGABIOS Extension. -// -// Copyright (c) 2004 Makoto Suzuki (suzu) -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// - -//#define CIRRUS_VESA3_PMINFO -#ifdef VBE -#undef CIRRUS_VESA3_PMINFO -#endif - -#define PM_BIOSMEM_CURRENT_MODE 0x449 -#define PM_BIOSMEM_CRTC_ADDRESS 0x463 -#define PM_BIOSMEM_VBE_MODE 0x4BA - -typedef struct -{ - /* + 0 */ - unsigned short mode; - unsigned short width; - unsigned short height; - unsigned short depth; - /* + 8 */ - unsigned short hidden_dac; /* 0x3c6 */ - unsigned short *seq; /* 0x3c4 */ - unsigned short *graph; /* 0x3ce */ - unsigned short *crtc; /* 0x3d4 */ - /* +16 */ - unsigned char bitsperpixel; - unsigned char vesacolortype; - unsigned char vesaredmask; - unsigned char vesaredpos; - unsigned char vesagreenmask; - unsigned char vesagreenpos; - unsigned char vesabluemask; - unsigned char vesabluepos; - /* +24 */ - unsigned char vesareservedmask; - unsigned char vesareservedpos; -} cirrus_mode_t; -#define CIRRUS_MODE_SIZE 26 - - -/* For VESA BIOS 3.0 */ -#define CIRRUS_PM16INFO_SIZE 20 - -/* VGA */ -unsigned short cseq_vga[] = {0x0007,0xffff}; -unsigned short cgraph_vga[] = {0x0009,0x000a,0x000b,0xffff}; -unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff}; - -/* extensions */ -unsigned short cgraph_svgacolor[] = { -0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08, -0x0009,0x000a,0x000b, -0xffff -}; -/* 640x480x8 */ -unsigned short cseq_640x480x8[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, -0x580b,0x580c,0x580d,0x580e, -0x0412,0x0013,0x2017, -0x331b,0x331c,0x331d,0x331e, -0xffff -}; -unsigned short ccrtc_640x480x8[] = { -0x2c11, -0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, -0x4009,0x000c,0x000d, -0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18, -0x001a,0x221b,0x001d, -0xffff -}; -/* 640x480x16 */ -unsigned short cseq_640x480x16[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, -0x580b,0x580c,0x580d,0x580e, -0x0412,0x0013,0x2017, -0x331b,0x331c,0x331d,0x331e, -0xffff -}; -unsigned short ccrtc_640x480x16[] = { -0x2c11, -0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, -0x4009,0x000c,0x000d, -0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18, -0x001a,0x221b,0x001d, -0xffff -}; -/* 640x480x24 */ -unsigned short cseq_640x480x24[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, -0x580b,0x580c,0x580d,0x580e, -0x0412,0x0013,0x2017, -0x331b,0x331c,0x331d,0x331e, -0xffff -}; -unsigned short ccrtc_640x480x24[] = { -0x2c11, -0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, -0x4009,0x000c,0x000d, -0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18, -0x001a,0x321b,0x001d, -0xffff -}; -/* 800x600x8 */ -unsigned short cseq_800x600x8[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, -0x230b,0x230c,0x230d,0x230e, -0x0412,0x0013,0x2017, -0x141b,0x141c,0x141d,0x141e, -0xffff -}; -unsigned short ccrtc_800x600x8[] = { -0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, -0x6009,0x000c,0x000d, -0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18, -0x001a,0x221b,0x001d, -0xffff -}; -/* 800x600x16 */ -unsigned short cseq_800x600x16[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, -0x230b,0x230c,0x230d,0x230e, -0x0412,0x0013,0x2017, -0x141b,0x141c,0x141d,0x141e, -0xffff -}; -unsigned short ccrtc_800x600x16[] = { -0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, -0x6009,0x000c,0x000d, -0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18, -0x001a,0x221b,0x001d, -0xffff -}; -/* 800x600x24 */ -unsigned short cseq_800x600x24[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, -0x230b,0x230c,0x230d,0x230e, -0x0412,0x0013,0x2017, -0x141b,0x141c,0x141d,0x141e, -0xffff -}; -unsigned short ccrtc_800x600x24[] = { -0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, -0x6009,0x000c,0x000d, -0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18, -0x001a,0x321b,0x001d, -0xffff -}; -/* 1024x768x8 */ -unsigned short cseq_1024x768x8[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, -0x760b,0x760c,0x760d,0x760e, -0x0412,0x0013,0x2017, -0x341b,0x341c,0x341d,0x341e, -0xffff -}; -unsigned short ccrtc_1024x768x8[] = { -0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, -0x6009,0x000c,0x000d, -0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, -0x001a,0x221b,0x001d, -0xffff -}; -/* 1024x768x16 */ -unsigned short cseq_1024x768x16[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, -0x760b,0x760c,0x760d,0x760e, -0x0412,0x0013,0x2017, -0x341b,0x341c,0x341d,0x341e, -0xffff -}; -unsigned short ccrtc_1024x768x16[] = { -0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, -0x6009,0x000c,0x000d, -0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18, -0x001a,0x321b,0x001d, -0xffff -}; -/* 1024x768x24 */ -unsigned short cseq_1024x768x24[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, -0x760b,0x760c,0x760d,0x760e, -0x0412,0x0013,0x2017, -0x341b,0x341c,0x341d,0x341e, -0xffff -}; -unsigned short ccrtc_1024x768x24[] = { -0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, -0x6009,0x000c,0x000d, -0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, -0x001a,0x321b,0x001d, -0xffff -}; -/* 1280x1024x8 */ -unsigned short cseq_1280x1024x8[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, -0x760b,0x760c,0x760d,0x760e, -0x0412,0x0013,0x2017, -0x341b,0x341c,0x341d,0x341e, -0xffff -}; -unsigned short ccrtc_1280x1024x8[] = { -0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, -0x6009,0x000c,0x000d, -0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, -0x001a,0x221b,0x001d, -0xffff -}; -/* 1280x1024x16 */ -unsigned short cseq_1280x1024x16[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, -0x760b,0x760c,0x760d,0x760e, -0x0412,0x0013,0x2017, -0x341b,0x341c,0x341d,0x341e, -0xffff -}; -unsigned short ccrtc_1280x1024x16[] = { -0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, -0x6009,0x000c,0x000d, -0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18, -0x001a,0x321b,0x001d, -0xffff -}; - -/* 1600x1200x8 */ -unsigned short cseq_1600x1200x8[] = { -0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, -0x760b,0x760c,0x760d,0x760e, -0x0412,0x0013,0x2017, -0x341b,0x341c,0x341d,0x341e, -0xffff -}; -unsigned short ccrtc_1600x1200x8[] = { -0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, -0x6009,0x000c,0x000d, -0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, -0x001a,0x221b,0x001d, -0xffff -}; - -cirrus_mode_t cirrus_modes[] = -{ - {0x5f,640,480,8,0x00, - cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x64,640,480,16,0xe1, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x66,640,480,15,0xf0, - cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, - 6,5,10,5,5,5,0,1,15}, - {0x71,640,480,24,0xe5, - cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, - 6,8,16,8,8,8,0,0,0}, - - {0x5c,800,600,8,0x00, - cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x65,800,600,16,0xe1, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x67,800,600,15,0xf0, - cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, - 6,5,10,5,5,5,0,1,15}, - - {0x60,1024,768,8,0x00, - cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x74,1024,768,16,0xe1, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 6,5,11,6,5,5,0,0,0}, - {0x68,1024,768,15,0xf0, - cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, - 6,5,10,5,5,5,0,1,15}, - - {0x78,800,600,24,0xe5, - cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, - 6,8,16,8,8,8,0,0,0}, - {0x79,1024,768,24,0xe5, - cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, - 6,8,16,8,8,8,0,0,0}, - - {0x6d,1280,1024,8,0x00, - cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, - 4,0,0,0,0,0,0,0,0}, - {0x69,1280,1024,15,0xf0, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 6,5,10,5,5,5,0,1,15}, - {0x75,1280,1024,16,0xe1, - cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, - 6,5,11,6,5,5,0,0,0}, - - {0x7b,1600,1200,8,0x00, - cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, - 4,0,0,0,0,0,0,0,0}, - - {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, - 0xff,0,0,0,0,0,0,0,0}, - {0xff,0,0,0,0,0,0,0,0, - 0xff,0,0,0,0,0,0,0,0}, -}; - -unsigned char cirrus_id_table[] = { - // 5430 - 0xA0, 0x32, - // 5446 - 0xB8, 0x39, - - 0xff, 0xff -}; - - -unsigned short cirrus_vesa_modelist[] = { -// 640x480x8 - 0x101, 0x5f, -// 640x480x15 - 0x110, 0x66, -// 640x480x16 - 0x111, 0x64, -// 640x480x24 - 0x112, 0x71, -// 800x600x8 - 0x103, 0x5c, -// 800x600x15 - 0x113, 0x67, -// 800x600x16 - 0x114, 0x65, -// 800x600x24 - 0x115, 0x78, -// 1024x768x8 - 0x105, 0x60, -// 1024x768x15 - 0x116, 0x68, -// 1024x768x16 - 0x117, 0x74, -// 1024x768x24 - 0x118, 0x79, -// 1280x1024x8 - 0x107, 0x6d, -// 1280x1024x15 - 0x119, 0x69, -// 1280x1024x16 - 0x11a, 0x75, -// invalid - 0xffff,0xffff -}; - - -ASM_START - -cirrus_installed: -.ascii "cirrus-compatible VGA is detected" -.byte 0x0d,0x0a -.byte 0x0d,0x0a,0x00 - -cirrus_not_installed: -.ascii "cirrus-compatible VGA is not detected" -.byte 0x0d,0x0a -.byte 0x0d,0x0a,0x00 - -cirrus_vesa_vendorname: -cirrus_vesa_productname: -cirrus_vesa_oemname: -.ascii "VGABIOS Cirrus extension" -.byte 0 -cirrus_vesa_productrevision: -.ascii "1.0" -.byte 0 - -cirrus_init: - call cirrus_check - jnz no_cirrus - SET_INT_VECTOR(0x10, #0xC000, #cirrus_int10_handler) - mov al, #0x0f ; memory setup - mov dx, #0x3C4 - out dx, al - inc dx - in al, dx - and al, #0x18 - mov ah, al - mov al, #0x0a - dec dx - out dx, ax - mov ax, #0x0007 ; set vga mode - out dx, ax - mov ax, #0x0431 ; reset bitblt - mov dx, #0x3CE - out dx, ax - mov ax, #0x0031 - out dx, ax -no_cirrus: - ret - -cirrus_display_info: - push ds - push si - push cs - pop ds - call cirrus_check - mov si, #cirrus_not_installed - jnz cirrus_msgnotinstalled - mov si, #cirrus_installed - -cirrus_msgnotinstalled: - call _display_string - pop si - pop ds - ret - -cirrus_check: - push ax - push dx - mov ax, #0x9206 - mov dx, #0x3C4 - out dx, ax - inc dx - in al, dx - cmp al, #0x12 - pop dx - pop ax - ret - - -cirrus_int10_handler: - pushf - push bp - cmp ah, #0x00 ;; set video mode - jz cirrus_set_video_mode - cmp ah, #0x12 ;; cirrus extension - jz cirrus_extbios - cmp ah, #0x4F ;; VESA extension - jz cirrus_vesa - -cirrus_unhandled: - pop bp - popf - jmp vgabios_int10_handler - -cirrus_return: -#ifdef CIRRUS_DEBUG - call cirrus_debug_dump -#endif - pop bp - popf - iret - -cirrus_set_video_mode: -#ifdef CIRRUS_DEBUG - call cirrus_debug_dump -#endif - push si - push ax - push bx - push ds -#ifdef CIRRUS_VESA3_PMINFO - db 0x2e ;; cs: - mov si, [cirrus_vesa_sel0000_data] -#else - xor si, si -#endif - mov ds, si - xor bx, bx - mov [PM_BIOSMEM_VBE_MODE], bx - pop ds - pop bx - call cirrus_get_modeentry - jnc cirrus_set_video_mode_extended - mov al, #0xfe - call cirrus_get_modeentry_nomask - call cirrus_switch_mode - pop ax - pop si - jmp cirrus_unhandled - -cirrus_extbios: -#ifdef CIRRUS_DEBUG - call cirrus_debug_dump -#endif - cmp bl, #0x80 - jb cirrus_unhandled - cmp bl, #0xAF - ja cirrus_unhandled - push bx - and bx, #0x7F - shl bx, 1 - db 0x2e ;; cs: - mov bp, cirrus_extbios_handlers[bx] - pop bx - push #cirrus_return - push bp - ret - -cirrus_vesa: -#ifdef CIRRUS_DEBUG - call cirrus_debug_dump -#endif - cmp al, #0x10 - ja cirrus_vesa_not_handled - push bx - xor bx, bx - mov bl, al - shl bx, 1 - db 0x2e ;; cs: - mov bp, cirrus_vesa_handlers[bx] - pop bx - push #cirrus_return - push bp - ret - -cirrus_vesa_not_handled: - mov ax, #0x014F ;; not implemented - jmp cirrus_return - -#ifdef CIRRUS_DEBUG -cirrus_debug_dump: - push es - push ds - pusha - push cs - pop ds - call _cirrus_debugmsg - popa - pop ds - pop es - ret -#endif - -cirrus_set_video_mode_extended: - call cirrus_switch_mode - pop ax ;; mode - test al, #0x80 - jnz cirrus_set_video_mode_extended_1 - push ax - mov ax, #0xffff ; set to 0xff to keep win 2K happy - call cirrus_clear_vram - pop ax -cirrus_set_video_mode_extended_1: - and al, #0x7f - - push ds -#ifdef CIRRUS_VESA3_PMINFO - db 0x2e ;; cs: - mov si, [cirrus_vesa_sel0000_data] -#else - xor si, si -#endif - mov ds, si - mov [PM_BIOSMEM_CURRENT_MODE], al - pop ds - - mov al, #0x20 - - pop si - jmp cirrus_return - -cirrus_vesa_pmbios_init: - retf -cirrus_vesa_pmbios_entry: - pushf - push bp - cmp ah, #0x4F - jnz cirrus_vesa_pmbios_unimplemented - cmp al, #0x0F - ja cirrus_vesa_pmbios_unimplemented - push bx - xor bx, bx - mov bl, al - shl bx, 1 - db 0x2e ;; cs: - mov bp, cirrus_vesa_handlers[bx] - pop bx - push #cirrus_vesa_pmbios_return - push bp - ret -cirrus_vesa_pmbios_unimplemented: - mov ax, #0x014F -cirrus_vesa_pmbios_return: - pop bp - popf - retf - -; in si:mode table -cirrus_switch_mode: - push ds - push bx - push dx - push cs - pop ds - - mov bx, [si+10] ;; seq - mov dx, #0x3c4 - mov ax, #0x1206 - out dx, ax ;; Unlock cirrus special - call cirrus_switch_mode_setregs - - mov bx, [si+12] ;; graph - mov dx, #0x3ce - call cirrus_switch_mode_setregs - - mov bx, [si+14] ;; crtc - call cirrus_get_crtc - call cirrus_switch_mode_setregs - - mov dx, #0x3c6 - mov al, #0x00 - out dx, al - in al, dx - in al, dx - in al, dx - in al, dx - mov al, [si+8] ;; hidden dac - out dx, al - mov al, #0xff - out dx, al - - mov al, #0x00 - mov bl, [si+17] ;; memory model - or bl, bl - jz is_text_mode - mov al, #0x01 - cmp bl, #0x03 - jnz is_text_mode - or al, #0x40 -is_text_mode: - mov bl, #0x10 - call biosfn_get_single_palette_reg - and bh, #0xfe - or bh, al - call biosfn_set_single_palette_reg - - pop dx - pop bx - pop ds - ret - -cirrus_enable_16k_granularity: - push ax - push dx - mov dx, #0x3ce - mov al, #0x0b - out dx, al - inc dx - in al, dx - or al, #0x20 ;; enable 16k - out dx, al - pop dx - pop ax - ret - -cirrus_switch_mode_setregs: -csms_1: - mov ax, [bx] - cmp ax, #0xffff - jz csms_2 - out dx, ax - add bx, #0x2 - jmp csms_1 -csms_2: - ret - -cirrus_extbios_80h: - push dx - call cirrus_get_crtc - mov al, #0x27 - out dx, al - inc dx - in al, dx - mov bx, #_cirrus_id_table -c80h_1: - db 0x2e ;; cs: - mov ah, [bx] - cmp ah, al - jz c80h_2 - cmp ah, #0xff - jz c80h_2 - inc bx - inc bx - jmp c80h_1 -c80h_2: - db 0x2e ;; cs: - mov al, 0x1[bx] - pop dx - mov ah, #0x00 - xor bx, bx - ret - -cirrus_extbios_81h: - mov ax, #0x100 ;; XXX - ret -cirrus_extbios_82h: - push dx - call cirrus_get_crtc - xor ax, ax - mov al, #0x27 - out dx, al - inc dx - in al, dx - and al, #0x03 - mov ah, #0xAF - pop dx - ret - -cirrus_extbios_85h: - push cx - push dx - mov dx, #0x3C4 - mov al, #0x0f ;; get DRAM band width - out dx, al - inc dx - in al, dx - ;; al = 4 << bandwidth - mov cl, al - shr cl, #0x03 - and cl, #0x03 - cmp cl, #0x03 - je c85h2 - mov al, #0x04 - shl al, cl - jmp c85h3 -c85h2: -;; 4MB or 2MB - and al, #0x80 - mov al, #0x20 ;; 2 MB - je c85h3 - mov al, #0x40 ;; 4 MB -c85h3: - pop dx - pop cx - ret - -cirrus_extbios_9Ah: - mov ax, #0x4060 - mov cx, #0x1132 - ret - -cirrus_extbios_A0h: - call cirrus_get_modeentry - mov ah, #0x01 - sbb ah, #0x00 - mov bx, cirrus_extbios_A0h_callback - mov si, #0xffff - mov di, bx - mov ds, bx - mov es, bx - ret - -cirrus_extbios_A0h_callback: - ;; fatal: not implemented yet - cli - hlt - retf - -cirrus_extbios_A1h: - mov bx, #0x0E00 ;; IBM 8512/8513, color - ret - -cirrus_extbios_A2h: - mov al, #0x07 ;; HSync 31.5 - 64.0 kHz - ret - -cirrus_extbios_AEh: - mov al, #0x01 ;; High Refresh 75Hz - ret - -cirrus_extbios_unimplemented: - ret - -cirrus_vesa_00h: - push ds - push si - mov bp, di - push es - pop ds - cld - mov ax, [di] - cmp ax, #0x4256 ;; VB - jnz cv00_1 - mov ax, [di+2] - cmp ax, #0x3245 ;; E2 - jnz cv00_1 - ;; VBE2 - lea di, 0x14[bp] - mov ax, #0x0100 ;; soft ver. - stosw - mov ax, # cirrus_vesa_vendorname - stosw - mov ax, cs - stosw - mov ax, # cirrus_vesa_productname - stosw - mov ax, cs - stosw - mov ax, # cirrus_vesa_productrevision - stosw - mov ax, cs - stosw -cv00_1: - mov di, bp - mov ax, #0x4556 ;; VE - stosw - mov ax, #0x4153 ;; SA - stosw - mov ax, #0x0200 ;; v2.00 - stosw - mov ax, # cirrus_vesa_oemname - stosw - mov ax, cs - stosw - xor ax, ax ;; caps - stosw - stosw - lea ax, 0x40[bp] - stosw - mov ax, es - stosw - call cirrus_extbios_85h ;; vram in 64k - mov ah, #0x00 - stosw - - push cs - pop ds - lea di, 0x40[bp] - mov si, #_cirrus_vesa_modelist -cv00_2: - lodsw - stosw - add si, #2 - cmp ax, #0xffff - jnz cv00_2 - - mov ax, #0x004F - mov di, bp - pop si - pop ds - ret - -cirrus_vesa_01h: - mov ax, cx - and ax, #0x3fff - call cirrus_vesamode_to_mode - cmp ax, #0xffff - jnz cirrus_vesa_01h_1 - jmp cirrus_vesa_unimplemented -cirrus_vesa_01h_1: - push ds - push si - push cx - push dx - push bx - mov bp, di - cld - push cs - pop ds - call cirrus_get_modeentry_nomask - - push di - xor ax, ax - mov cx, #0x80 - rep - stosw ;; clear buffer - pop di - - mov ax, #0x003b ;; mode - stosw - mov ax, #0x0007 ;; attr - stosw - mov ax, #0x0010 ;; granularity =16K - stosw - mov ax, #0x0040 ;; size =64K - stosw - mov ax, #0xA000 ;; segment A - stosw - xor ax, ax ;; no segment B - stosw - mov ax, #cirrus_vesa_05h_farentry - stosw - mov ax, cs - stosw - call cirrus_get_line_offset_entry - stosw ;; bytes per scan line - mov ax, [si+2] ;; width - stosw - mov ax, [si+4] ;; height - stosw - mov ax, #0x08 - stosb - mov ax, #0x10 - stosb - mov al, #1 ;; count of planes - stosb - mov al, [si+6] ;; bpp - stosb - mov al, #0x1 ;; XXX number of banks - stosb - mov al, [si+17] - stosb ;; memory model - mov al, #0x0 ;; XXX size of bank in K - stosb - call cirrus_get_line_offset_entry - mov bx, [si+4] - mul bx ;; dx:ax=vramdisp - or ax, ax - jz cirrus_vesa_01h_3 - inc dx -cirrus_vesa_01h_3: - call cirrus_extbios_85h ;; al=vram in 64k - mov ah, #0x00 - mov cx, dx - xor dx, dx - div cx - dec ax - stosb ;; number of image pages = vramtotal/vramdisp-1 - mov al, #0x00 - stosb - - ;; v1.2+ stuffs - push si - add si, #18 - movsw - movsw - movsw - movsw - pop si - - mov ah, [si+16] - mov al, #0x0 - sub ah, #9 - rcl al, #1 ; bit 0=palette flag - stosb ;; direct screen mode info - - ;; v2.0+ stuffs - ;; 32-bit LFB address - xor ax, ax - stosw - mov ax, #0x1013 ;; vendor Cirrus - call _pci_get_lfb_addr - stosw - or ax, ax - jz cirrus_vesa_01h_4 - push di - mov di, bp - db 0x26 ;; es: - mov ax, [di] - or ax, #0x0080 ;; mode bit 7:LFB - stosw - pop di -cirrus_vesa_01h_4: - - xor ax, ax - stosw ; reserved - stosw ; reserved - stosw ; reserved - - mov ax, #0x004F - mov di, bp - pop bx - pop dx - pop cx - pop si - pop ds - - test cx, #0x4000 ;; LFB flag - jz cirrus_vesa_01h_5 - push cx - db 0x26 ;; es: - mov cx, [di] - cmp cx, #0x0080 ;; is LFB supported? - jnz cirrus_vesa_01h_6 - mov ax, #0x014F ;; error - no LFB -cirrus_vesa_01h_6: - pop cx -cirrus_vesa_01h_5: - ret - -cirrus_vesa_02h: - ;; XXX support CRTC registers - test bx, #0x3e00 - jnz cirrus_vesa_02h_2 ;; unknown flags - mov ax, bx - and ax, #0x1ff ;; bit 8-0 mode - cmp ax, #0x100 ;; legacy VGA mode - jb cirrus_vesa_02h_legacy - call cirrus_vesamode_to_mode - cmp ax, #0xffff - jnz cirrus_vesa_02h_1 -cirrus_vesa_02h_2: - jmp cirrus_vesa_unimplemented -cirrus_vesa_02h_legacy: -#ifdef CIRRUS_VESA3_PMINFO - db 0x2e ;; cs: - cmp byte ptr [cirrus_vesa_is_protected_mode], #0 - jnz cirrus_vesa_02h_2 -#endif // CIRRUS_VESA3_PMINFO - int #0x10 - mov ax, #0x004F - ret -cirrus_vesa_02h_1: - push si - push ax - call cirrus_get_modeentry_nomask - call cirrus_switch_mode - test bx, #0x4000 ;; LFB - jnz cirrus_vesa_02h_3 - call cirrus_enable_16k_granularity -cirrus_vesa_02h_3: - test bx, #0x8000 ;; no clear - jnz cirrus_vesa_02h_4 - push ax - xor ax,ax - call cirrus_clear_vram - pop ax -cirrus_vesa_02h_4: - pop ax - push ds -#ifdef CIRRUS_VESA3_PMINFO - db 0x2e ;; cs: - mov si, [cirrus_vesa_sel0000_data] -#else - xor si, si -#endif - mov ds, si - mov [PM_BIOSMEM_CURRENT_MODE], al - mov [PM_BIOSMEM_VBE_MODE], bx - pop ds - pop si - mov ax, #0x004F - ret - -cirrus_vesa_03h: - push ds -#ifdef CIRRUS_VESA3_PMINFO - db 0x2e ;; cs: - mov ax, [cirrus_vesa_sel0000_data] -#else - xor ax, ax -#endif - mov ds, ax - mov bx, # PM_BIOSMEM_VBE_MODE - mov ax, [bx] - mov bx, ax - test bx, bx - jnz cirrus_vesa_03h_1 - mov bx, # PM_BIOSMEM_CURRENT_MODE - mov al, [bx] - mov bl, al - xor bh, bh -cirrus_vesa_03h_1: - mov ax, #0x004f - pop ds - ret - -cirrus_vesa_05h_farentry: - call cirrus_vesa_05h - retf - -cirrus_vesa_05h: - cmp bl, #0x01 - ja cirrus_vesa_05h_1 - cmp bh, #0x00 - jz cirrus_vesa_05h_setmempage - cmp bh, #0x01 - jz cirrus_vesa_05h_getmempage -cirrus_vesa_05h_1: - jmp cirrus_vesa_unimplemented -cirrus_vesa_05h_setmempage: - or dh, dh ; address must be < 0x100 - jnz cirrus_vesa_05h_1 - push dx - mov al, bl ;; bl=bank number - add al, #0x09 - mov ah, dl ;; dx=window address in granularity - mov dx, #0x3ce - out dx, ax - pop dx - mov ax, #0x004F - ret -cirrus_vesa_05h_getmempage: - mov al, bl ;; bl=bank number - add al, #0x09 - mov dx, #0x3ce - out dx, al - inc dx - in al, dx - xor dx, dx - mov dl, al ;; dx=window address in granularity - mov ax, #0x004F - ret - -cirrus_vesa_06h: - mov ax, cx - cmp bl, #0x01 - je cirrus_vesa_06h_3 - cmp bl, #0x02 - je cirrus_vesa_06h_2 - jb cirrus_vesa_06h_1 - mov ax, #0x0100 - ret -cirrus_vesa_06h_1: - call cirrus_get_bpp_bytes - mov bl, al - xor bh, bh - mov ax, cx - mul bx -cirrus_vesa_06h_2: - call cirrus_set_line_offset -cirrus_vesa_06h_3: - call cirrus_get_bpp_bytes - mov bl, al - xor bh, bh - xor dx, dx - call cirrus_get_line_offset - push ax - div bx - mov cx, ax - pop bx - call cirrus_extbios_85h ;; al=vram in 64k - xor dx, dx - mov dl, al - xor ax, ax - div bx - mov dx, ax - mov ax, #0x004f - ret - -cirrus_vesa_07h: - cmp bl, #0x80 - je cirrus_vesa_07h_1 - cmp bl, #0x01 - je cirrus_vesa_07h_2 - jb cirrus_vesa_07h_1 - mov ax, #0x0100 - ret -cirrus_vesa_07h_1: - push dx - call cirrus_get_bpp_bytes - mov bl, al - xor bh, bh - mov ax, cx - mul bx - pop bx - push ax - call cirrus_get_line_offset - mul bx - pop bx - add ax, bx - jnc cirrus_vesa_07h_3 - inc dx -cirrus_vesa_07h_3: - push dx - and dx, #0x0003 - mov bx, #0x04 - div bx - pop dx - shr dx, #2 - call cirrus_set_start_addr - mov ax, #0x004f - ret -cirrus_vesa_07h_2: - call cirrus_get_start_addr - shl dx, #2 - push dx - mov bx, #0x04 - mul bx - pop bx - or dx, bx - push ax - call cirrus_get_line_offset - mov bx, ax - pop ax - div bx - push ax - push dx - call cirrus_get_bpp_bytes - mov bl, al - xor bh, bh - pop ax - xor dx, dx - div bx - mov cx, ax - pop dx - mov ax, #0x004f - ret - -cirrus_vesa_10h: - cmp bl, #0x00 - jne cirrus_vesa_10h_01 - mov bx, #0x0f30 - mov ax, #0x004f - ret -cirrus_vesa_10h_01: - cmp bl, #0x01 - jne cirrus_vesa_10h_02 - push dx - push ds - mov dx, #0x40 - mov ds, dx - mov [0xb9], bh - pop ds - pop dx - mov ax, #0x004f - ret -cirrus_vesa_10h_02: - cmp bl, #0x02 - jne cirrus_vesa_unimplemented - push dx - push ds - mov dx, #0x40 - mov ds, dx - mov bh, [0xb9] - pop ds - pop dx - mov ax, #0x004f - ret - -cirrus_vesa_unimplemented: - mov ax, #0x014F ;; not implemented - ret - - -;; in ax:vesamode, out ax:cirrusmode -cirrus_vesamode_to_mode: - push ds - push cx - push si - push cs - pop ds - mov cx, #0xffff - mov si, #_cirrus_vesa_modelist -cvtm_1: - cmp [si],ax - jz cvtm_2 - cmp [si],cx - jz cvtm_2 - add si, #4 - jmp cvtm_1 -cvtm_2: - mov ax,[si+2] - pop si - pop cx - pop ds - ret - - ; cirrus_get_crtc - ;; NOTE - may be called in protected mode -cirrus_get_crtc: - push ds - push ax - mov dx, #0x3cc - in al, dx - and al, #0x01 - shl al, #5 - mov dx, #0x3b4 - add dl, al - pop ax - pop ds - ret - -;; in - al:mode, out - cflag:result, si:table, ax:destroyed -cirrus_get_modeentry: - and al, #0x7f -cirrus_get_modeentry_nomask: - mov si, #_cirrus_modes -cgm_1: - db 0x2e ;; cs: - mov ah, [si] - cmp al, ah - jz cgm_2 - cmp ah, #0xff - jz cgm_4 - add si, # CIRRUS_MODE_SIZE - jmp cgm_1 -cgm_4: - xor si, si - stc ;; video mode is not supported - jmp cgm_3 -cgm_2: - clc ;; video mode is supported -cgm_3: - ret - -;; out - al:bytes per pixel -cirrus_get_bpp_bytes: - push dx - mov dx, #0x03c4 - mov al, #0x07 - out dx, al - inc dx - in al, dx - and al, #0x0e - cmp al, #0x06 - jne cirrus_get_bpp_bytes_1 - and al, #0x02 -cirrus_get_bpp_bytes_1: - shr al, #1 - cmp al, #0x04 - je cirrus_get_bpp_bytes_2 - inc al -cirrus_get_bpp_bytes_2: - pop dx - ret - -;; in - ax: new line offset -cirrus_set_line_offset: - shr ax, #3 - push ax - call cirrus_get_crtc - mov al, #0x13 - out dx, al - inc dx - pop ax - out dx, al - dec dx - mov al, #0x1b - out dx, al - inc dx - shl ah, #4 - in al, dx - and al, #ef - or al, ah - out dx, al - ret - -;; out - ax: active line offset -cirrus_get_line_offset: - push dx - push bx - call cirrus_get_crtc - mov al, #0x13 - out dx, al - inc dx - in al, dx - mov bl, al - dec dx - mov al, #0x1b - out dx, al - inc dx - in al, dx - mov ah, al - shr ah, #4 - and ah, #0x01 - mov al, bl - shl ax, #3 - pop bx - pop dx - ret - -;; in - si: table -;; out - ax: line offset for mode -cirrus_get_line_offset_entry: - push bx - mov bx, [si+14] ;; crtc table - push bx -offset_loop1: - mov ax, [bx] - cmp al, #0x13 - je offset_found1 - inc bx - inc bx - jnz offset_loop1 -offset_found1: - xor al, al - shr ax, #5 - pop bx - push ax -offset_loop2: - mov ax, [bx] - cmp al, #0x1b - je offset_found2 - inc bx - inc bx - jnz offset_loop2 -offset_found2: - pop bx - and ax, #0x1000 - shr ax, #1 - or ax, bx - pop bx - ret - -;; in - new address in DX:AX -cirrus_set_start_addr: - push bx - push dx - push ax - call cirrus_get_crtc - mov al, #0x0d - out dx, al - inc dx - pop ax - out dx, al - dec dx - mov al, #0x0c - out dx, al - inc dx - mov al, ah - out dx, al - dec dx - mov al, #0x1d - out dx, al - inc dx - in al, dx - and al, #0x7f - pop bx - mov ah, bl - shl bl, #4 - and bl, #0x80 - or al, bl - out dx, al - dec dx - mov bl, ah - and ah, #0x01 - shl bl, #1 - and bl, #0x0c - or ah, bl - mov al, #0x1b - out dx, al - inc dx - in al, dx - and al, #0xf2 - or al, ah - out dx, al - pop bx - ret - -;; out - current address in DX:AX -cirrus_get_start_addr: - push bx - call cirrus_get_crtc - mov al, #0x0c - out dx, al - inc dx - in al, dx - mov ah, al - dec dx - mov al, #0x0d - out dx, al - inc dx - in al, dx - push ax - dec dx - mov al, #0x1b - out dx, al - inc dx - in al, dx - dec dx - mov bl, al - and al, #0x01 - and bl, #0x0c - shr bl, #1 - or bl, al - mov al, #0x1d - out dx, al - inc dx - in al, dx - and al, #0x80 - shr al, #4 - or bl, al - mov dl, bl - xor dh, dh - pop ax - pop bx - ret - -cirrus_clear_vram: - pusha - push es - mov si, ax - - call cirrus_enable_16k_granularity - call cirrus_extbios_85h - shl al, #2 - mov bl, al - xor ah,ah -cirrus_clear_vram_1: - mov al, #0x09 - mov dx, #0x3ce - out dx, ax - push ax - mov cx, #0xa000 - mov es, cx - xor di, di - mov ax, si - mov cx, #8192 - cld - rep - stosw - pop ax - inc ah - cmp ah, bl - jne cirrus_clear_vram_1 - - xor ah,ah - mov dx, #0x3ce - out dx, ax - - pop es - popa - ret - -cirrus_extbios_handlers: - ;; 80h - dw cirrus_extbios_80h - dw cirrus_extbios_81h - dw cirrus_extbios_82h - dw cirrus_extbios_unimplemented - ;; 84h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_85h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; 88h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; 8Ch - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; 90h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; 94h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; 98h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_9Ah - dw cirrus_extbios_unimplemented - ;; 9Ch - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; A0h - dw cirrus_extbios_A0h - dw cirrus_extbios_A1h - dw cirrus_extbios_A2h - dw cirrus_extbios_unimplemented - ;; A4h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; A8h - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - ;; ACh - dw cirrus_extbios_unimplemented - dw cirrus_extbios_unimplemented - dw cirrus_extbios_AEh - dw cirrus_extbios_unimplemented - -cirrus_vesa_handlers: - ;; 00h - dw cirrus_vesa_00h - dw cirrus_vesa_01h - dw cirrus_vesa_02h - dw cirrus_vesa_03h - ;; 04h - dw cirrus_vesa_unimplemented - dw cirrus_vesa_05h - dw cirrus_vesa_06h - dw cirrus_vesa_07h - ;; 08h - dw cirrus_vesa_unimplemented - dw cirrus_vesa_unimplemented - dw cirrus_vesa_unimplemented - dw cirrus_vesa_unimplemented - ;; 0Ch - dw cirrus_vesa_unimplemented - dw cirrus_vesa_unimplemented - dw cirrus_vesa_unimplemented - dw cirrus_vesa_unimplemented - ;; 10h - dw cirrus_vesa_10h - - -ASM_END - -#ifdef CIRRUS_VESA3_PMINFO -ASM_START -cirrus_vesa_pminfo: - /* + 0 */ - .byte 0x50,0x4d,0x49,0x44 ;; signature[4] - /* + 4 */ - dw cirrus_vesa_pmbios_entry ;; entry_bios - dw cirrus_vesa_pmbios_init ;; entry_init - /* + 8 */ -cirrus_vesa_sel0000_data: - dw 0x0000 ;; sel_00000 -cirrus_vesa_selA000_data: - dw 0xA000 ;; sel_A0000 - /* +12 */ -cirrus_vesa_selB000_data: - dw 0xB000 ;; sel_B0000 -cirrus_vesa_selB800_data: - dw 0xB800 ;; sel_B8000 - /* +16 */ -cirrus_vesa_selC000_data: - dw 0xC000 ;; sel_C0000 -cirrus_vesa_is_protected_mode: - ;; protected mode flag and checksum - dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \ - + (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01 -ASM_END -#endif // CIRRUS_VESA3_PMINFO - - -#ifdef CIRRUS_DEBUG -static void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) - Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; -{ - if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05)) - printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); -} -#endif diff --git a/roms/vgabios/dataseghack b/roms/vgabios/dataseghack deleted file mode 100644 index 02a2d4c..0000000 --- a/roms/vgabios/dataseghack +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -awk \ - 'BEGIN { }\ - /^\.text/,/DATA_SEG_DEFS_HERE/ { print }\ - END { }'\ - $1 > temp.awk.1 - -awk \ - 'BEGIN { i = 0; last = "hello" }\ - /BLOCK_STRINGS_BEGIN/,/^\.bss/ { if ( i > 1 ) { print last } last = $0; i = i + 1 }\ - END { }'\ - $1 > temp.awk.2 - -awk \ - 'BEGIN { }\ - /DATA_SEG_DEFS_HERE/,/BLOCK_STRINGS_BEGIN/ { print }\ - END { }'\ - $1 > temp.awk.3 - -cp $1 $1.orig -cat temp.awk.1 temp.awk.2 temp.awk.3 | sed -e 's/^\.data//' -e 's/^\.bss//' -e 's/^\.text//' > $1 -/bin/rm -f temp.awk.1 temp.awk.2 temp.awk.3 $1.orig diff --git a/roms/vgabios/tests/lfbprof/Makefile b/roms/vgabios/tests/lfbprof/Makefile deleted file mode 100644 index 7c42e38..0000000 --- a/roms/vgabios/tests/lfbprof/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# Very simple makefile for LFBPROF.C using Watcom C++ 10.0a with DOS4GW - -lfbprof.exe: lfbprof.c lfbprof.h - wcl386 -zq -s -d2 lfbprof.c - diff --git a/roms/vgabios/tests/lfbprof/lfbprof.c b/roms/vgabios/tests/lfbprof/lfbprof.c deleted file mode 100644 index df37452..0000000 --- a/roms/vgabios/tests/lfbprof/lfbprof.c +++ /dev/null @@ -1,594 +0,0 @@ -/**************************************************************************** -* -* VBE 2.0 Linear Framebuffer Profiler -* By Kendall Bennett and Brian Hook -* -* Filename: LFBPROF.C -* Language: ANSI C -* Environment: Watcom C/C++ 10.0a with DOS4GW -* -* Description: Simple program to profile the speed of screen clearing -* and full screen BitBlt operations using a VESA VBE 2.0 -* linear framebuffer from 32 bit protected mode. -* -* For simplicity, this program only supports 256 color -* SuperVGA video modes that support a linear framebuffer. -* -* -* 2002/02/18: Jeroen Janssen -* - fixed unsigned short for mode list (-1 != 0xffff otherwise) -* - fixed LfbMapRealPointer macro mask problem (some modes were skipped) -* -****************************************************************************/ - -#include -#include -#include -#include -#include -#include "lfbprof.h" - -/*---------------------------- Global Variables ---------------------------*/ - -int VESABuf_len = 1024; /* Length of VESABuf */ -int VESABuf_sel = 0; /* Selector for VESABuf */ -int VESABuf_rseg; /* Real mode segment of VESABuf */ -unsigned short modeList[50]; /* List of available VBE modes */ -float clearsPerSec; /* Number of clears per second */ -float clearsMbPerSec; /* Memory transfer for clears */ -float bitBltsPerSec; /* Number of BitBlt's per second */ -float bitBltsMbPerSec; /* Memory transfer for bitblt's */ -int xres,yres; /* Video mode resolution */ -int bytesperline; /* Bytes per scanline for mode */ -long imageSize; /* Length of the video image */ -char *LFBPtr; /* Pointer to linear framebuffer */ - -/*------------------------- DPMI interface routines -----------------------*/ - -void DPMI_allocRealSeg(int size,int *sel,int *r_seg) -/**************************************************************************** -* -* Function: DPMI_allocRealSeg -* Parameters: size - Size of memory block to allocate -* sel - Place to return protected mode selector -* r_seg - Place to return real mode segment -* -* Description: Allocates a block of real mode memory using DPMI services. -* This routine returns both a protected mode selector and -* real mode segment for accessing the memory block. -* -****************************************************************************/ -{ - union REGS r; - - r.w.ax = 0x100; /* DPMI allocate DOS memory */ - r.w.bx = (size + 0xF) >> 4; /* number of paragraphs */ - int386(0x31, &r, &r); - if (r.w.cflag) - FatalError("DPMI_allocRealSeg failed!"); - *sel = r.w.dx; /* Protected mode selector */ - *r_seg = r.w.ax; /* Real mode segment */ -} - -void DPMI_freeRealSeg(unsigned sel) -/**************************************************************************** -* -* Function: DPMI_allocRealSeg -* Parameters: sel - Protected mode selector of block to free -* -* Description: Frees a block of real mode memory. -* -****************************************************************************/ -{ - union REGS r; - - r.w.ax = 0x101; /* DPMI free DOS memory */ - r.w.dx = sel; /* DX := selector from 0x100 */ - int386(0x31, &r, &r); -} - -typedef struct { - long edi; - long esi; - long ebp; - long reserved; - long ebx; - long edx; - long ecx; - long eax; - short flags; - short es,ds,fs,gs,ip,cs,sp,ss; - } _RMREGS; - -#define IN(reg) rmregs.e##reg = in->x.reg -#define OUT(reg) out->x.reg = rmregs.e##reg - -int DPMI_int86(int intno, RMREGS *in, RMREGS *out) -/**************************************************************************** -* -* Function: DPMI_int86 -* Parameters: intno - Interrupt number to issue -* in - Pointer to structure for input registers -* out - Pointer to structure for output registers -* Returns: Value returned by interrupt in AX -* -* Description: Issues a real mode interrupt using DPMI services. -* -****************************************************************************/ -{ - _RMREGS rmregs; - union REGS r; - struct SREGS sr; - - memset(&rmregs, 0, sizeof(rmregs)); - IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); - - segread(&sr); - r.w.ax = 0x300; /* DPMI issue real interrupt */ - r.h.bl = intno; - r.h.bh = 0; - r.w.cx = 0; - sr.es = sr.ds; - r.x.edi = (unsigned)&rmregs; - int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ - - OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); - out->x.cflag = rmregs.flags & 0x1; - return out->x.ax; -} - -int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs) -/**************************************************************************** -* -* Function: DPMI_int86 -* Parameters: intno - Interrupt number to issue -* in - Pointer to structure for input registers -* out - Pointer to structure for output registers -* sregs - Values to load into segment registers -* Returns: Value returned by interrupt in AX -* -* Description: Issues a real mode interrupt using DPMI services. -* -****************************************************************************/ -{ - _RMREGS rmregs; - union REGS r; - struct SREGS sr; - - memset(&rmregs, 0, sizeof(rmregs)); - IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); - rmregs.es = sregs->es; - rmregs.ds = sregs->ds; - - segread(&sr); - r.w.ax = 0x300; /* DPMI issue real interrupt */ - r.h.bl = intno; - r.h.bh = 0; - r.w.cx = 0; - sr.es = sr.ds; - r.x.edi = (unsigned)&rmregs; - int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ - - OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); - sregs->es = rmregs.es; - sregs->cs = rmregs.cs; - sregs->ss = rmregs.ss; - sregs->ds = rmregs.ds; - out->x.cflag = rmregs.flags & 0x1; - return out->x.ax; -} - -int DPMI_allocSelector(void) -/**************************************************************************** -* -* Function: DPMI_allocSelector -* Returns: Newly allocated protected mode selector -* -* Description: Allocates a new protected mode selector using DPMI -* services. This selector has a base address and limit of 0. -* -****************************************************************************/ -{ - int sel; - union REGS r; - - r.w.ax = 0; /* DPMI allocate selector */ - r.w.cx = 1; /* Allocate a single selector */ - int386(0x31, &r, &r); - if (r.x.cflag) - FatalError("DPMI_allocSelector() failed!"); - sel = r.w.ax; - - r.w.ax = 9; /* DPMI set access rights */ - r.w.bx = sel; - r.w.cx = 0x8092; /* 32 bit page granular */ - int386(0x31, &r, &r); - return sel; -} - -long DPMI_mapPhysicalToLinear(long physAddr,long limit) -/**************************************************************************** -* -* Function: DPMI_mapPhysicalToLinear -* Parameters: physAddr - Physical memory address to map -* limit - Length-1 of physical memory region to map -* Returns: Starting linear address for mapped memory -* -* Description: Maps a section of physical memory into the linear address -* space of a process using DPMI calls. Note that this linear -* address cannot be used directly, but must be used as the -* base address for a selector. -* -****************************************************************************/ -{ - union REGS r; - - r.w.ax = 0x800; /* DPMI map physical to linear */ - r.w.bx = physAddr >> 16; - r.w.cx = physAddr & 0xFFFF; - r.w.si = limit >> 16; - r.w.di = limit & 0xFFFF; - int386(0x31, &r, &r); - if (r.x.cflag) - FatalError("DPMI_mapPhysicalToLinear() failed!"); - return ((long)r.w.bx << 16) + r.w.cx; -} - -void DPMI_setSelectorBase(int sel,long linAddr) -/**************************************************************************** -* -* Function: DPMI_setSelectorBase -* Parameters: sel - Selector to change base address for -* linAddr - Linear address used for new base address -* -* Description: Sets the base address for the specified selector. -* -****************************************************************************/ -{ - union REGS r; - - r.w.ax = 7; /* DPMI set selector base address */ - r.w.bx = sel; - r.w.cx = linAddr >> 16; - r.w.dx = linAddr & 0xFFFF; - int386(0x31, &r, &r); - if (r.x.cflag) - FatalError("DPMI_setSelectorBase() failed!"); -} - -void DPMI_setSelectorLimit(int sel,long limit) -/**************************************************************************** -* -* Function: DPMI_setSelectorLimit -* Parameters: sel - Selector to change limit for -* limit - Limit-1 for the selector -* -* Description: Sets the memory limit for the specified selector. -* -****************************************************************************/ -{ - union REGS r; - - r.w.ax = 8; /* DPMI set selector limit */ - r.w.bx = sel; - r.w.cx = limit >> 16; - r.w.dx = limit & 0xFFFF; - int386(0x31, &r, &r); - if (r.x.cflag) - FatalError("DPMI_setSelectorLimit() failed!"); -} - -/*-------------------------- VBE Interface routines -----------------------*/ - -void FatalError(char *msg) -{ - fprintf(stderr,"%s\n", msg); - exit(1); -} - -static void ExitVBEBuf(void) -{ - DPMI_freeRealSeg(VESABuf_sel); -} - -void VBE_initRMBuf(void) -/**************************************************************************** -* -* Function: VBE_initRMBuf -* Description: Initialises the VBE transfer buffer in real mode memory. -* This routine is called by the VESAVBE module every time -* it needs to use the transfer buffer, so we simply allocate -* it once and then return. -* -****************************************************************************/ -{ - if (!VESABuf_sel) { - DPMI_allocRealSeg(VESABuf_len, &VESABuf_sel, &VESABuf_rseg); - atexit(ExitVBEBuf); - } -} - -void VBE_callESDI(RMREGS *regs, void *buffer, int size) -/**************************************************************************** -* -* Function: VBE_callESDI -* Parameters: regs - Registers to load when calling VBE -* buffer - Buffer to copy VBE info block to -* size - Size of buffer to fill -* -* Description: Calls the VESA VBE and passes in a buffer for the VBE to -* store information in, which is then copied into the users -* buffer space. This works in protected mode as the buffer -* passed to the VESA VBE is allocated in conventional -* memory, and is then copied into the users memory block. -* -****************************************************************************/ -{ - RMSREGS sregs; - - VBE_initRMBuf(); - sregs.es = VESABuf_rseg; - regs->x.di = 0; - _fmemcpy(MK_FP(VESABuf_sel,0),buffer,size); - DPMI_int86x(0x10, regs, regs, &sregs); - _fmemcpy(buffer,MK_FP(VESABuf_sel,0),size); -} - -int VBE_detect(void) -/**************************************************************************** -* -* Function: VBE_detect -* Parameters: vgaInfo - Place to store the VGA information block -* Returns: VBE version number, or 0 if not detected. -* -* Description: Detects if a VESA VBE is out there and functioning -* correctly. If we detect a VBE interface we return the -* VGAInfoBlock returned by the VBE and the VBE version number. -* -****************************************************************************/ -{ - RMREGS regs; - unsigned short *p1,*p2; - VBE_vgaInfo vgaInfo; - - /* Put 'VBE2' into the signature area so that the VBE 2.0 BIOS knows - * that we have passed a 512 byte extended block to it, and wish - * the extended information to be filled in. - */ - strncpy(vgaInfo.VESASignature,"VBE2",4); - - /* Get the SuperVGA Information block */ - regs.x.ax = 0x4F00; - VBE_callESDI(®s, &vgaInfo, sizeof(VBE_vgaInfo)); - if (regs.x.ax != 0x004F) - return 0; - if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0) - return 0; - - /* Now that we have detected a VBE interface, copy the list of available - * video modes into our local buffer. We *must* copy this mode list, - * since the VBE will build the mode list in the VBE_vgaInfo buffer - * that we have passed, so the next call to the VBE will trash the - * list of modes. - */ - printf("videomodeptr %x\n",vgaInfo.VideoModePtr); - p1 = LfbMapRealPointer(vgaInfo.VideoModePtr); - p2 = modeList; - while (*p1 != -1) - { - printf("found mode %x\n",*p1); - *p2++ = *p1++; - } - *p2 = -1; - return vgaInfo.VESAVersion; -} - -int VBE_getModeInfo(int mode,VBE_modeInfo *modeInfo) -/**************************************************************************** -* -* Function: VBE_getModeInfo -* Parameters: mode - VBE mode to get information for -* modeInfo - Place to store VBE mode information -* Returns: 1 on success, 0 if function failed. -* -* Description: Obtains information about a specific video mode from the -* VBE. You should use this function to find the video mode -* you wish to set, as the new VBE 2.0 mode numbers may be -* completely arbitrary. -* -****************************************************************************/ -{ - RMREGS regs; - - regs.x.ax = 0x4F01; /* Get mode information */ - regs.x.cx = mode; - VBE_callESDI(®s, modeInfo, sizeof(VBE_modeInfo)); - if (regs.x.ax != 0x004F) - return 0; - if ((modeInfo->ModeAttributes & vbeMdAvailable) == 0) - return 0; - return 1; -} - -void VBE_setVideoMode(int mode) -/**************************************************************************** -* -* Function: VBE_setVideoMode -* Parameters: mode - VBE mode number to initialise -* -****************************************************************************/ -{ - RMREGS regs; - regs.x.ax = 0x4F02; - regs.x.bx = mode; - DPMI_int86(0x10,®s,®s); -} - -/*-------------------- Application specific routines ----------------------*/ - -void *GetPtrToLFB(long physAddr) -/**************************************************************************** -* -* Function: GetPtrToLFB -* Parameters: physAddr - Physical memory address of linear framebuffer -* Returns: Far pointer to the linear framebuffer memory -* -****************************************************************************/ -{ - int sel; - long linAddr,limit = (4096 * 1024) - 1; - -// sel = DPMI_allocSelector(); - linAddr = DPMI_mapPhysicalToLinear(physAddr,limit); -// DPMI_setSelectorBase(sel,linAddr); -// DPMI_setSelectorLimit(sel,limit); -// return MK_FP(sel,0); - return (void*)linAddr; -} - -void AvailableModes(void) -/**************************************************************************** -* -* Function: AvailableModes -* -* Description: Display a list of available LFB mode resolutions. -* -****************************************************************************/ -{ - unsigned short *p; - VBE_modeInfo modeInfo; - - printf("Usage: LFBPROF \n\n"); - printf("Available 256 color video modes:\n"); - for (p = modeList; *p != -1; p++) { - if (VBE_getModeInfo(*p, &modeInfo)) { - /* Filter out only 8 bit linear framebuffer modes */ - if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) - continue; - if (modeInfo.MemoryModel != vbeMemPK - || modeInfo.BitsPerPixel != 8 - || modeInfo.NumberOfPlanes != 1) - continue; - printf(" %4d x %4d %d bits per pixel\n", - modeInfo.XResolution, modeInfo.YResolution, - modeInfo.BitsPerPixel); - } - } - exit(1); -} - -void InitGraphics(int x,int y) -/**************************************************************************** -* -* Function: InitGraphics -* Parameters: x,y - Requested video mode resolution -* -* Description: Initialise the specified video mode. We search through -* the list of available video modes for one that matches -* the resolution and color depth are are looking for. -* -****************************************************************************/ -{ - unsigned short *p; - VBE_modeInfo modeInfo; - printf("InitGraphics\n"); - - for (p = modeList; *p != -1; p++) { - if (VBE_getModeInfo(*p, &modeInfo)) { - /* Filter out only 8 bit linear framebuffer modes */ - if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) - continue; - if (modeInfo.MemoryModel != vbeMemPK - || modeInfo.BitsPerPixel != 8 - || modeInfo.NumberOfPlanes != 1) - continue; - if (modeInfo.XResolution != x || modeInfo.YResolution != y) - continue; - xres = x; - yres = y; - bytesperline = modeInfo.BytesPerScanLine; - imageSize = bytesperline * yres; - VBE_setVideoMode(*p | vbeUseLFB); - LFBPtr = GetPtrToLFB(modeInfo.PhysBasePtr); - return; - } - } - printf("Valid video mode not found\n"); - exit(1); -} - -void EndGraphics(void) -/**************************************************************************** -* -* Function: EndGraphics -* -* Description: Restores text mode. -* -****************************************************************************/ -{ - RMREGS regs; - printf("EndGraphics\n"); - regs.x.ax = 0x3; - DPMI_int86(0x10, ®s, ®s); -} - -void ProfileMode(void) -/**************************************************************************** -* -* Function: ProfileMode -* -* Description: Profiles framebuffer performance for simple screen clearing -* and for copying from system memory to video memory (BitBlt). -* This routine thrashes the CPU cache by cycling through -* enough system memory buffers to invalidate the entire -* CPU external cache before re-using the first memory buffer -* again. -* -****************************************************************************/ -{ - int i,numClears,numBlts,maxImages; - long startTicks,endTicks; - void *image[10],*dst; - printf("ProfileMode\n"); - - /* Profile screen clearing operation */ - startTicks = LfbGetTicks(); - numClears = 0; - while ((LfbGetTicks() - startTicks) < 182) - LfbMemset(LFBPtr,numClears++,imageSize); - endTicks = LfbGetTicks(); - clearsPerSec = numClears / ((endTicks - startTicks) * 0.054925); - clearsMbPerSec = (clearsPerSec * imageSize) / 1048576.0; - - /* Profile system memory to video memory copies */ - maxImages = ((512 * 1024U) / imageSize) + 2; - for (i = 0; i < maxImages; i++) { - image[i] = malloc(imageSize); - if (image[i] == NULL) - FatalError("Not enough memory to profile BitBlt!"); - memset(image[i],i+1,imageSize); - } - startTicks = LfbGetTicks(); - numBlts = 0; - while ((LfbGetTicks() - startTicks) < 182) - LfbMemcpy(LFBPtr,image[numBlts++ % maxImages],imageSize); - endTicks = LfbGetTicks(); - bitBltsPerSec = numBlts / ((endTicks - startTicks) * 0.054925); - bitBltsMbPerSec = (bitBltsPerSec * imageSize) / 1048576.0; -} - -void main(int argc, char *argv[]) -{ - if (VBE_detect() < 0x200) - FatalError("This program requires VBE 2.0; Please install UniVBE 5.1."); - if (argc != 3) - AvailableModes(); /* Display available modes */ - - InitGraphics(atoi(argv[1]),atoi(argv[2])); /* Start graphics */ - ProfileMode(); /* Profile the video mode */ - EndGraphics(); /* Restore text mode */ - - printf("Profiling results for %dx%d 8 bits per pixel.\n",xres,yres); - printf("%3.2f clears/s, %2.2f Mb/s\n", clearsPerSec, clearsMbPerSec); - printf("%3.2f bitBlt/s, %2.2f Mb/s\n", bitBltsPerSec, bitBltsMbPerSec); -} diff --git a/roms/vgabios/tests/lfbprof/lfbprof.h b/roms/vgabios/tests/lfbprof/lfbprof.h deleted file mode 100644 index bae0e09..0000000 --- a/roms/vgabios/tests/lfbprof/lfbprof.h +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -* -* VBE 2.0 Linear Framebuffer Profiler -* By Kendall Bennett and Brian Hook -* -* Filename: LFBPROF.H -* Language: ANSI C -* Environment: Watcom C/C++ 10.0a with DOS4GW -* -* Description: Header file for the LFBPROF.C progam. -* -****************************************************************************/ - -#ifndef __LFBPROF_H -#define __LFBPROF_H - -/*---------------------- Macros and type definitions ----------------------*/ - -#pragma pack(1) - -/* SuperVGA information block */ - -typedef struct { - char VESASignature[4]; /* 'VESA' 4 byte signature */ - short VESAVersion; /* VBE version number */ - long OemStringPtr; /* Pointer to OEM string */ - long Capabilities; /* Capabilities of video card */ - long VideoModePtr; /* Pointer to supported modes */ - short TotalMemory; /* Number of 64kb memory blocks */ - - /* VBE 2.0 extensions */ - - short OemSoftwareRev; /* OEM Software revision number */ - long OemVendorNamePtr; /* Pointer to Vendor Name string */ - long OemProductNamePtr; /* Pointer to Product Name string */ - long OemProductRevPtr; /* Pointer to Product Revision str */ - char reserved[222]; /* Pad to 256 byte block size */ - char OemDATA[256]; /* Scratch pad for OEM data */ - } VBE_vgaInfo; - -/* SuperVGA mode information block */ - -typedef struct { - short ModeAttributes; /* Mode attributes */ - char WinAAttributes; /* Window A attributes */ - char WinBAttributes; /* Window B attributes */ - short WinGranularity; /* Window granularity in k */ - short WinSize; /* Window size in k */ - short WinASegment; /* Window A segment */ - short WinBSegment; /* Window B segment */ - long WinFuncPtr; /* Pointer to window function */ - short BytesPerScanLine; /* Bytes per scanline */ - short XResolution; /* Horizontal resolution */ - short YResolution; /* Vertical resolution */ - char XCharSize; /* Character cell width */ - char YCharSize; /* Character cell height */ - char NumberOfPlanes; /* Number of memory planes */ - char BitsPerPixel; /* Bits per pixel */ - char NumberOfBanks; /* Number of CGA style banks */ - char MemoryModel; /* Memory model type */ - char BankSize; /* Size of CGA style banks */ - char NumberOfImagePages; /* Number of images pages */ - char res1; /* Reserved */ - char RedMaskSize; /* Size of direct color red mask */ - char RedFieldPosition; /* Bit posn of lsb of red mask */ - char GreenMaskSize; /* Size of direct color green mask */ - char GreenFieldPosition; /* Bit posn of lsb of green mask */ - char BlueMaskSize; /* Size of direct color blue mask */ - char BlueFieldPosition; /* Bit posn of lsb of blue mask */ - char RsvdMaskSize; /* Size of direct color res mask */ - char RsvdFieldPosition; /* Bit posn of lsb of res mask */ - char DirectColorModeInfo; /* Direct color mode attributes */ - - /* VBE 2.0 extensions */ - - long PhysBasePtr; /* Physical address for linear buf */ - long OffScreenMemOffset; /* Pointer to start of offscreen mem*/ - short OffScreenMemSize; /* Amount of offscreen mem in 1K's */ - char res2[206]; /* Pad to 256 byte block size */ - } VBE_modeInfo; - -#define vbeMemPK 4 /* Packed Pixel memory model */ -#define vbeUseLFB 0x4000 /* Enable linear framebuffer mode */ - -/* Flags for the mode attributes returned by VBE_getModeInfo. If - * vbeMdNonBanked is set to 1 and vbeMdLinear is also set to 1, then only - * the linear framebuffer mode is available. - */ - -#define vbeMdAvailable 0x0001 /* Video mode is available */ -#define vbeMdColorMode 0x0008 /* Mode is a color video mode */ -#define vbeMdGraphMode 0x0010 /* Mode is a graphics mode */ -#define vbeMdNonBanked 0x0040 /* Banked mode is not supported */ -#define vbeMdLinear 0x0080 /* Linear mode supported */ - -/* Structures for issuing real mode interrupts with DPMI */ - -struct _RMWORDREGS { - unsigned short ax, bx, cx, dx, si, di, cflag; - }; - -struct _RMBYTEREGS { - unsigned char al, ah, bl, bh, cl, ch, dl, dh; - }; - -typedef union { - struct _RMWORDREGS x; - struct _RMBYTEREGS h; - } RMREGS; - -typedef struct { - unsigned short es; - unsigned short cs; - unsigned short ss; - unsigned short ds; - } RMSREGS; - -/* Inline assembler block fill/move routines */ - -void LfbMemset(void *p,int c,int n); -#pragma aux LfbMemset = \ - "shr ecx,2" \ - "xor eax,eax" \ - "mov al,bl" \ - "shl ebx,8" \ - "or ax,bx" \ - "mov ebx,eax" \ - "shl ebx,16" \ - "or eax,ebx" \ - "rep stosd" \ - parm [edi] [ebx] [ecx]; - -void LfbMemcpy(void *dst,void *src,int n); -#pragma aux LfbMemcpy = \ - "shr ecx,2" \ - "rep movsd" \ - parm [edi] [esi] [ecx]; - -/* Map a real mode pointer into address space */ - -#define LfbMapRealPointer(p) (void*)(((unsigned)((p) & 0xFFFF0000) >> 12) + ((p) & 0xFFFF)) - -/* Get the current timer tick count */ - -#define LfbGetTicks() *((long*)0x46C) - -#pragma pack() - -#endif /* __LFBPROF_H */ diff --git a/roms/vgabios/tests/testbios.c b/roms/vgabios/tests/testbios.c deleted file mode 100644 index 99da5a6..0000000 --- a/roms/vgabios/tests/testbios.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - This is a little turbo C program that executes - several int10, and let you inspect the content - of the vgabios area - - It is used to test the behavior of the vgabios -*/ - -#include -#include -#include - - -typedef unsigned char Bit8u; -typedef unsigned short Bit16u; - -typedef struct -{Bit8u initial; - Bit8u current; - Bit16u nbcols; - Bit16u regen; - Bit16u start; - Bit16u curpos[8]; - Bit8u curtyp; - Bit8u curpage; - Bit16u crtc; - Bit16u msr; - Bit16u cgapal; - Bit8u nbrows; - Bit16u cheight; - Bit8u ctl; - Bit8u switches; - Bit8u modeset; - Bit8u dcc; - Bit16u vsseg; - Bit16u vsoffset; -} BIOSAREA; - -void int10ax0003(struct REGPACK *regs) -{ - regs->r_ax=0x0003; - intr(0x10,regs); -} - -void int10ax02(struct REGPACK *regs) -{ - regs->r_ax=0x0200; - regs->r_bx=0x0000; - regs->r_dx=0x1710; - intr(0x10,regs); - printf("We are now at 24/17"); -} - -void int10ax03(struct REGPACK *regs) -{ - regs->r_ax=0x0300; - regs->r_bx=0x0000; - intr(0x10,regs); - printf("\nCursor is ax%04x cx%04x dx%04x\n",regs->r_ax,regs->r_cx,regs->r_dx); -} - -void int10ax0501(struct REGPACK *regs) -{ - regs->r_ax=0x0501; - intr(0x10,regs); - regs->r_ax=0x0e61; - regs->r_bx=0x0000; - intr(0x10,regs); - printf("We are now on page 2"); -} - -void int10ax0602(struct REGPACK *regs) -{ - regs->r_ax=0x0602; - regs->r_bx=0x0700; - regs->r_cx=0x0101; - regs->r_dx=0x0a0a; - intr(0x10,regs); - printf("Scrolled 2 up"); -} - -void int10ax0702(struct REGPACK *regs) -{ - regs->r_ax=0x0702; - regs->r_bx=0x0700; - regs->r_cx=0x0101; - regs->r_dx=0x0a0a; - intr(0x10,regs); - printf("Scrolled 2 down"); -} - -void int10ax08(struct REGPACK *regs) -{ - regs->r_ax=0x0800; - regs->r_bx=0x0000; - intr(0x10,regs); -} - -void int10ax09(struct REGPACK *regs) -{ - char attr; - regs->r_ax=0x0501; - intr(0x10,regs); - for(attr=0;attr<16;attr++) - {printf("%02x ",attr); - regs->r_ax=0x0961+attr; - regs->r_bx=0x0100+attr; - regs->r_cx=0x0016; - intr(0x10,regs); - printf("\n"); - } -} - -void int10ax0a(struct REGPACK *regs) -{ - regs->r_ax=0x0501; - intr(0x10,regs); - regs->r_ax=0x0a62; - regs->r_bx=0x0101; - regs->r_cx=0x0016; - intr(0x10,regs); -} - -void int10ax0f(struct REGPACK *regs) -{ - regs->r_ax=0x0501; - intr(0x10,regs); - regs->r_ax=0x0f00; - intr(0x10,regs); -} - -void int10ax1b(struct REGPACK *regs) -{unsigned char table[64]; - unsigned char far *ptable; - int i; - - regs->r_ax=0x0501; - intr(0x10,regs); - regs->r_ax=0x1b00; - regs->r_bx=0x0000; - ptable=&table; - regs->r_es=FP_SEG(ptable); - regs->r_di=FP_OFF(ptable); - printf("Read state info in %04x:%04x\n",regs->r_es,regs->r_di); - intr(0x10,regs); - - for(i=0;i<64;i++) - {if(i%16==0)printf("\n%02x ",i); - printf("%02x ",table[i]); - } - printf("\n"); -} - -static unsigned char var[64]; - -void int10ax13(struct REGPACK *regs) -{unsigned char far *pvar; - - pvar=&var; - - regs->r_ax=0x1300; - regs->r_bx=0x000b; - regs->r_dx=0x1010; - regs->r_cx=0x0002; - regs->r_es=FP_SEG(pvar); - regs->r_bp=FP_OFF(pvar); - pokeb(regs->r_es,regs->r_bp,'t'); - pokeb(regs->r_es,regs->r_bp+1,'b'); - printf("Writing from %04x:%04x\n",regs->r_es,regs->r_bp); - intr(0x10,regs); - -} - -void switch_50(struct REGPACK *regs) -{ - regs->r_ax=0x1202; - regs->r_bx=0x3000; - intr(0x10,regs); - regs->r_ax=0x0003; - intr(0x10,regs); - regs->r_ax=0x1112; - regs->r_bx=0x0000; - intr(0x10,regs); -} - -char exec_function(struct REGPACK *regs) -{char c; - - printf("--- Functions --------------------\n"); - printf("a. int10 ax0003\t"); - printf("b. int10 ax02\t"); - printf("c. int10 ax03\t"); - printf("d. int10 ax0501\n"); - printf("e. int10 ax0602\t"); - printf("f. int10 ax0702\t"); - printf("g. int10 ax08\t"); - printf("h. int10 ax09\t"); - printf("i. int10 ax0a\n"); - printf("j. int10 ax0f\t"); - printf("k. int10 ax1b\t"); - printf("l. int10 ax13\n"); - printf("q. Quit\t"); - printf("r. switch to 50 lines\n"); - c=getche(); - - switch(c) - {case 'a': - int10ax0003(regs); - break; - case 'b': - int10ax02(regs); - break; - case 'c': - int10ax03(regs); - break; - case 'd': - int10ax0501(regs); - break; - case 'e': - int10ax0602(regs); - break; - case 'f': - int10ax0702(regs); - break; - case 'g': - int10ax08(regs); - break; - case 'h': - int10ax09(regs); - break; - case 'i': - int10ax0a(regs); - break; - case 'j': - int10ax0f(regs); - break; - case 'k': - int10ax1b(regs); - break; - case 'l': - int10ax13(regs); - break; - case 'q': - break; - case 'r': - switch_50(regs); - break; - default: - printf("No such function!\n"); - } - - if(c=='q')return 1; - while(kbhit()==0); - c=getch(); - - return 0; -} - -void read_bios_area(BIOSAREA *biosarea) -{ - biosarea->initial=peekb(0x40,0x10); - biosarea->current=peekb(0x40,0x49); - biosarea->nbcols=peek(0x40,0x4a); - biosarea->regen=peek(0x40,0x4c); - biosarea->start=peek(0x40,0x4e); - biosarea->curpos[0]=peek(0x40,0x50); - biosarea->curpos[1]=peek(0x40,0x52); - biosarea->curpos[2]=peek(0x40,0x54); - biosarea->curpos[3]=peek(0x40,0x56); - biosarea->curpos[4]=peek(0x40,0x58); - biosarea->curpos[5]=peek(0x40,0x5a); - biosarea->curpos[6]=peek(0x40,0x5c); - biosarea->curpos[7]=peek(0x40,0x5e); - biosarea->curtyp=peek(0x40,0x60); - biosarea->curpage=peekb(0x40,0x62); - biosarea->crtc=peek(0x40,0x63); - biosarea->msr=peekb(0x40,0x65); - biosarea->cgapal=peekb(0x40,0x66); - biosarea->nbrows=peekb(0x40,0x84); - biosarea->cheight=peek(0x40,0x85); - biosarea->ctl=peekb(0x40,0x87); - biosarea->switches=peekb(0x40,0x88); - biosarea->modeset=peekb(0x40,0x89); - biosarea->dcc=peekb(0x40,0x8a); - biosarea->vsseg=peek(0x40,0xa8); - biosarea->vsoffset=peek(0x40,0xaa); -} - -void show_bios_area(BIOSAREA *biosarea) -{ - printf("--- BIOS area --------------------\n"); - printf("initial : %02x\t",biosarea->initial); - printf("current : %02x\t",biosarea->current); - printf("nbcols : %04x\t",biosarea->nbcols); - printf("regen : %04x\t",biosarea->regen); - printf("start : %04x\n",biosarea->start); - printf("curpos : %04x %04x %04x %04x %04x %04x %04x %04x\n", - biosarea->curpos[0], biosarea->curpos[1], biosarea->curpos[2], biosarea->curpos[3], - biosarea->curpos[4], biosarea->curpos[5], biosarea->curpos[6], biosarea->curpos[7]); - printf("curtyp : %04x\t",biosarea->curtyp); - printf("curpage : %02x\t",biosarea->curpage); - printf("crtc : %04x\t",biosarea->crtc); - printf("msr : %04x\n",biosarea->msr); - printf("cgapal : %04x\t",biosarea->cgapal); - printf("nbrows-1: %02x\t",biosarea->nbrows); - printf("cheight : %04x\t",biosarea->cheight); - printf("ctl : %02x\n",biosarea->ctl); - printf("switches: %02x\t",biosarea->switches); - printf("modeset : %02x\t",biosarea->modeset); - printf("dcc : %02x\t",biosarea->dcc); - printf("vs : %04x:%04x\n",biosarea->vsseg,biosarea->vsoffset); -} - -void show_regs(struct REGPACK *regs) -{ - printf("--- Registers --------------------\n"); - printf("ax %04x\t",regs->r_ax); - printf("bx %04x\t",regs->r_bx); - printf("cx %04x\t",regs->r_cx); - printf("dx %04x\t",regs->r_dx); - printf("ds %04x\t",regs->r_ds); - printf("si %04x\t",regs->r_si); - printf("es %04x\t",regs->r_es); - printf("di %04x\n",regs->r_di); -} - -void reset_videomode() -{ - struct REGPACK regs; - - regs.r_ax=0x0003; - intr(0x10,®s); -} - -void main() -{ - - BIOSAREA biosarea; - struct REGPACK regs; - - directvideo=0; - - while(1) - { - read_bios_area(&biosarea); - - reset_videomode(); - show_bios_area(&biosarea); - show_regs(®s); - - if(exec_function(®s)!=0)break; - } -} diff --git a/roms/vgabios/vbe.c b/roms/vgabios/vbe.c deleted file mode 100644 index 1fab2f9..0000000 --- a/roms/vgabios/vbe.c +++ /dev/null @@ -1,1456 +0,0 @@ -// ============================================================================================ -// -// Copyright (C) 2002 Jeroen Janssen -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// ============================================================================================ -// -// This VBE is part of the VGA Bios specific to the plex86/bochs Emulated VGA card. -// You can NOT drive any physical vga card with it. -// -// ============================================================================================ -// -// This VBE Bios is based on information taken from : -// - VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0 located at www.vesa.org -// -// ============================================================================================ - - -// defines available - -// disable VESA/VBE2 check in vbe info -//#define VBE2_NO_VESA_CHECK - - -#include "vbe.h" -#include "vbetables.h" - -// The current OEM Software Revision of this VBE Bios -#define VBE_OEM_SOFTWARE_REV 0x0002; - -extern char vbebios_copyright; -extern char vbebios_vendor_name; -extern char vbebios_product_name; -extern char vbebios_product_revision; - -ASM_START -// FIXME: 'merge' these (c) etc strings with the vgabios.c strings? -_vbebios_copyright: -.ascii "Bochs/Plex86 VBE(C) 2003 http://savannah.nongnu.org/projects/vgabios/" -.byte 0x00 - -_vbebios_vendor_name: -.ascii "Bochs/Plex86 Developers" -.byte 0x00 - -_vbebios_product_name: -.ascii "Bochs/Plex86 VBE Adapter" -.byte 0x00 - -_vbebios_product_revision: -.ascii "$Id$" -.byte 0x00 - -_vbebios_info_string: -.ascii "Bochs VBE Display Adapter enabled" -.byte 0x0a,0x0d -.byte 0x0a,0x0d -.byte 0x00 - -_no_vbebios_info_string: -.ascii "NO Bochs VBE Support available!" -.byte 0x0a,0x0d -.byte 0x0a,0x0d -.byte 0x00 - -#if defined(USE_BX_INFO) || defined(DEBUG) -msg_vbe_init: -.ascii "VBE Bios $Id$" -.byte 0x0a,0x0d, 0x00 -#endif - - .align 2 -vesa_pm_start: - dw vesa_pm_set_window - vesa_pm_start - dw vesa_pm_set_display_start - vesa_pm_start - dw vesa_pm_unimplemented - vesa_pm_start - dw vesa_pm_io_ports_table - vesa_pm_start -vesa_pm_io_ports_table: - dw VBE_DISPI_IOPORT_INDEX - dw VBE_DISPI_IOPORT_INDEX + 1 - dw VBE_DISPI_IOPORT_DATA - dw VBE_DISPI_IOPORT_DATA + 1 - dw 0xffff - dw 0xffff - - USE32 -vesa_pm_set_window: - cmp bx, #0x00 - je vesa_pm_set_display_window1 - mov ax, #0x0100 - ret -vesa_pm_set_display_window1: - mov ax, dx - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_BANK - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - in ax, dx - pop dx - cmp dx, ax - jne illegal_window - mov ax, #0x004f - ret -illegal_window: - mov ax, #0x014f - ret - -vesa_pm_set_display_start: - cmp bl, #0x80 - je vesa_pm_set_display_start1 - cmp bl, #0x00 - je vesa_pm_set_display_start1 - mov ax, #0x0100 - ret -vesa_pm_set_display_start1: -; convert offset to (X, Y) coordinate -; (would be simpler to change Bochs VBE API...) - push eax - push ecx - push edx - push esi - push edi - shl edx, #16 - and ecx, #0xffff - or ecx, edx - shl ecx, #2 - mov eax, ecx - - push eax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - movzx ecx, ax - - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_BPP - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - movzx esi, ax - pop eax - - cmp esi, #4 - jz bpp4_mode - add esi, #7 - shr esi, #3 - imul ecx, esi - xor edx, edx - div ecx - mov edi, eax - mov eax, edx - xor edx, edx - div esi - jmp set_xy_regs - -bpp4_mode: - shr ecx, #1 - xor edx, edx - div ecx - mov edi, eax - mov eax, edx - shl eax, #1 - -set_xy_regs: - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_X_OFFSET - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - - mov ax, di - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_Y_OFFSET - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - - pop edi - pop esi - pop edx - pop ecx - pop eax - mov ax, #0x004f - ret - -vesa_pm_unimplemented: - mov ax, #0x014f - ret - USE16 -vesa_pm_end: - -; DISPI ioport functions - -dispi_get_id: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_ID - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - pop dx - ret - -dispi_set_id: - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_ID - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - ret -ASM_END - -static void dispi_set_xres(xres) - Bit16u xres; -{ -ASM_START - push bp - mov bp, sp - push ax - push dx - - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_XRES - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - mov ax, 4[bp] ; xres - out dx, ax - - pop dx - pop ax - pop bp -ASM_END -} - -static void dispi_set_yres(yres) - Bit16u yres; -{ - outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_YRES); - outw(VBE_DISPI_IOPORT_DATA,yres); -} - -static void dispi_set_bpp(bpp) - Bit16u bpp; -{ - outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_BPP); - outw(VBE_DISPI_IOPORT_DATA,bpp); -} - -ASM_START -; AL = bits per pixel / AH = bytes per pixel -dispi_get_bpp: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_BPP - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - mov ah, al - shr ah, 3 - test al, #0x07 - jz get_bpp_noinc - inc ah -get_bpp_noinc: - pop dx - ret - -; get display capabilities - -_dispi_get_max_xres: - push dx - push bx - call dispi_get_enable - mov bx, ax - or ax, # VBE_DISPI_GETCAPS - call _dispi_set_enable - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_XRES - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - push ax - mov ax, bx - call _dispi_set_enable - pop ax - pop bx - pop dx - ret - -_dispi_get_max_bpp: - push dx - push bx - call dispi_get_enable - mov bx, ax - or ax, # VBE_DISPI_GETCAPS - call _dispi_set_enable - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_BPP - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - push ax - mov ax, bx - call _dispi_set_enable - pop ax - pop bx - pop dx - ret - -_dispi_set_enable: - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_ENABLE - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - ret - -dispi_get_enable: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_ENABLE - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - pop dx - ret - -_dispi_set_bank: - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_BANK - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - ret - -dispi_get_bank: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_BANK - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - pop dx - ret -ASM_END - -static void dispi_set_bank_farcall() -{ -ASM_START - cmp bx,#0x0100 - je dispi_set_bank_farcall_get - or bx,bx - jnz dispi_set_bank_farcall_error - mov ax,dx - push dx - push ax - mov ax,# VBE_DISPI_INDEX_BANK - mov dx,# VBE_DISPI_IOPORT_INDEX - out dx,ax - pop ax - mov dx,# VBE_DISPI_IOPORT_DATA - out dx,ax - in ax,dx - pop dx - cmp dx,ax - jne dispi_set_bank_farcall_error - mov ax, #0x004f - retf -dispi_set_bank_farcall_get: - mov ax,# VBE_DISPI_INDEX_BANK - mov dx,# VBE_DISPI_IOPORT_INDEX - out dx,ax - mov dx,# VBE_DISPI_IOPORT_DATA - in ax,dx - mov dx,ax - retf -dispi_set_bank_farcall_error: - mov ax,#0x014F - retf -ASM_END -} - -ASM_START -dispi_set_x_offset: - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_X_OFFSET - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - ret - -dispi_get_x_offset: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_X_OFFSET - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - pop dx - ret - -dispi_set_y_offset: - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_Y_OFFSET - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - ret - -dispi_get_y_offset: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_Y_OFFSET - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - pop dx - ret - -vga_set_virt_width: - push ax - push bx - push dx - mov bx, ax - call dispi_get_bpp - cmp al, #0x04 - ja set_width_svga - shr bx, #1 -set_width_svga: - shr bx, #3 - mov dx, # VGAREG_VGA_CRTC_ADDRESS - mov ah, bl - mov al, #0x13 - out dx, ax - pop dx - pop bx - pop ax - ret - -dispi_set_virt_width: - call vga_set_virt_width - push dx - push ax - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH - out dx, ax - pop ax - mov dx, # VBE_DISPI_IOPORT_DATA - out dx, ax - pop dx - ret - -dispi_get_virt_width: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - pop dx - ret - -dispi_get_virt_height: - push dx - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_VIRT_HEIGHT - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - pop dx - ret - -_vga_compat_setup: - push ax - push dx - - ; set CRT X resolution - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_XRES - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - push ax - mov dx, # VGAREG_VGA_CRTC_ADDRESS - mov ax, #0x0011 - out dx, ax - pop ax - push ax - shr ax, #3 - dec ax - mov ah, al - mov al, #0x01 - out dx, ax - pop ax - call vga_set_virt_width - - ; set CRT Y resolution - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_YRES - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - dec ax - push ax - mov dx, # VGAREG_VGA_CRTC_ADDRESS - mov ah, al - mov al, #0x12 - out dx, ax - pop ax - mov al, #0x07 - out dx, al - inc dx - in al, dx - and al, #0xbd - test ah, #0x01 - jz bit8_clear - or al, #0x02 -bit8_clear: - test ah, #0x02 - jz bit9_clear - or al, #0x40 -bit9_clear: - out dx, al - - ; other settings - mov dx, # VGAREG_VGA_CRTC_ADDRESS - mov ax, #0x0009 - out dx, ax - mov al, #0x17 - out dx, al - mov dx, # VGAREG_VGA_CRTC_DATA - in al, dx - or al, #0x03 - out dx, al - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x10 - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - or al, #0x01 - mov dx, # VGAREG_ACTL_ADDRESS - out dx, al - mov al, #0x20 - out dx, al - mov dx, # VGAREG_GRDC_ADDRESS - mov ax, #0x0506 - out dx, ax - mov dx, # VGAREG_SEQU_ADDRESS - mov ax, #0x0f02 - out dx, ax - - ; settings for >= 8bpp - mov dx, # VBE_DISPI_IOPORT_INDEX - mov ax, # VBE_DISPI_INDEX_BPP - out dx, ax - mov dx, # VBE_DISPI_IOPORT_DATA - in ax, dx - cmp al, #0x08 - jb vga_compat_end - mov dx, # VGAREG_VGA_CRTC_ADDRESS - mov al, #0x14 - out dx, al - mov dx, # VGAREG_VGA_CRTC_DATA - in al, dx - or al, #0x40 - out dx, al - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x10 - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - or al, #0x40 - mov dx, # VGAREG_ACTL_ADDRESS - out dx, al - mov al, #0x20 - out dx, al - mov dx, # VGAREG_SEQU_ADDRESS - mov al, #0x04 - out dx, al - mov dx, # VGAREG_SEQU_DATA - in al, dx - or al, #0x08 - out dx, al - mov dx, # VGAREG_GRDC_ADDRESS - mov al, #0x05 - out dx, al - mov dx, # VGAREG_GRDC_DATA - in al, dx - and al, #0x9f - or al, #0x40 - out dx, al - -vga_compat_end: - pop dx - pop ax -ASM_END - - -// ModeInfo helper function -static ModeInfoListItem* mode_info_find_mode(mode, using_lfb) - Bit16u mode; Boolean using_lfb; -{ - ModeInfoListItem *cur_info=&mode_info_list; - - while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST) - { - if (cur_info->mode == mode) - { - if (!using_lfb) - { - return cur_info; - } - else if (cur_info->info.ModeAttributes & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE) - { - return cur_info; - } - else - { - cur_info++; - } - } - else - { - cur_info++; - } - } - - return 0; -} - -ASM_START - -; Has VBE display - Returns true if VBE display detected - -_vbe_has_vbe_display: - push ds - push bx - mov ax, # BIOSMEM_SEG - mov ds, ax - mov bx, # BIOSMEM_VBE_FLAG - mov al, [bx] - and al, #0x01 - xor ah, ah - pop bx - pop ds - ret - -; VBE Init - Initialise the Vesa Bios Extension Code -; This function does a sanity check on the host side display code interface. - -vbe_init: - mov ax, # VBE_DISPI_ID0 - call dispi_set_id - call dispi_get_id - cmp ax, # VBE_DISPI_ID0 - jne no_vbe_interface - push ds - push bx - mov ax, # BIOSMEM_SEG - mov ds, ax - mov bx, # BIOSMEM_VBE_FLAG - mov al, #0x01 - mov [bx], al - pop bx - pop ds - mov ax, # VBE_DISPI_ID5 - call dispi_set_id -no_vbe_interface: -#if defined(USE_BX_INFO) || defined(DEBUG) - mov bx, #msg_vbe_init - push bx - call _printf - inc sp - inc sp -#endif - ret - -; VBE Display Info - Display information on screen about the VBE - -vbe_display_info: - call _vbe_has_vbe_display - test ax, ax - jz no_vbe_flag - mov ax, #0xc000 - mov ds, ax - mov si, #_vbebios_info_string - jmp _display_string -no_vbe_flag: - mov ax, #0xc000 - mov ds, ax - mov si, #_no_vbebios_info_string - jmp _display_string - -; helper function for memory size calculation - -lmulul: - and eax, #0x0000FFFF - shl ebx, #16 - or eax, ebx - SEG SS - mul eax, dword ptr [di] - mov ebx, eax - shr ebx, #16 - ret -ASM_END - -/** Function 00h - Return VBE Controller Information - * - * Input: - * AX = 4F00h - * ES:DI = Pointer to buffer in which to place VbeInfoBlock structure - * (VbeSignature should be VBE2 when VBE 2.0 information is desired and - * the info block is 512 bytes in size) - * Output: - * AX = VBE Return Status - * - */ -void vbe_biosfn_return_controller_information(AX, ES, DI) -Bit16u *AX;Bit16u ES;Bit16u DI; -{ - Bit16u ss=get_SS(); - VbeInfoBlock vbe_info_block; - Bit16u status; - Bit16u result; - Bit16u vbe2_info; - Bit16u cur_mode=0; - Bit16u cur_ptr=34; - Bit16u size_64k; - ModeInfoListItem *cur_info=&mode_info_list; - - status = read_word(ss, AX); - -#ifdef DEBUG - printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status); -#endif - - vbe2_info = 0; -#ifdef VBE2_NO_VESA_CHECK -#else - // get vbe_info_block into local variable - memcpyb(ss, &vbe_info_block, ES, DI, sizeof(vbe_info_block)); - - // check for VBE2 signature - if (((vbe_info_block.VbeSignature[0] == 'V') && - (vbe_info_block.VbeSignature[1] == 'B') && - (vbe_info_block.VbeSignature[2] == 'E') && - (vbe_info_block.VbeSignature[3] == '2')) || - - ((vbe_info_block.VbeSignature[0] == 'V') && - (vbe_info_block.VbeSignature[1] == 'E') && - (vbe_info_block.VbeSignature[2] == 'S') && - (vbe_info_block.VbeSignature[3] == 'A')) ) - { - vbe2_info = 1; -#ifdef DEBUG - printf("VBE correct VESA/VBE2 signature found\n"); -#endif - } -#endif - - // VBE Signature - vbe_info_block.VbeSignature[0] = 'V'; - vbe_info_block.VbeSignature[1] = 'E'; - vbe_info_block.VbeSignature[2] = 'S'; - vbe_info_block.VbeSignature[3] = 'A'; - - // VBE Version supported - vbe_info_block.VbeVersion = 0x0200; - - // OEM String - vbe_info_block.OemStringPtr_Seg = 0xc000; - vbe_info_block.OemStringPtr_Off = &vbebios_copyright; - - // Capabilities - vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC; - vbe_info_block.Capabilities[1] = 0; - vbe_info_block.Capabilities[2] = 0; - vbe_info_block.Capabilities[3] = 0; - - // VBE Video Mode Pointer (dynamicly generated from the mode_info_list) - vbe_info_block.VideoModePtr_Seg= ES ; - vbe_info_block.VideoModePtr_Off= DI + 34; - - // VBE Total Memory (in 64k blocks) - outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); - vbe_info_block.TotalMemory = inw(VBE_DISPI_IOPORT_DATA); - - if (vbe2_info) - { - // OEM Stuff - vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV; - vbe_info_block.OemVendorNamePtr_Seg = 0xc000; - vbe_info_block.OemVendorNamePtr_Off = &vbebios_vendor_name; - vbe_info_block.OemProductNamePtr_Seg = 0xc000; - vbe_info_block.OemProductNamePtr_Off = &vbebios_product_name; - vbe_info_block.OemProductRevPtr_Seg = 0xc000; - vbe_info_block.OemProductRevPtr_Off = &vbebios_product_revision; - - // copy updates in vbe_info_block back - memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block)); - } - else - { - // copy updates in vbe_info_block back (VBE 1.x compatibility) - memcpyb(ES, DI, ss, &vbe_info_block, 256); - } - - do - { - size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; - - if ((cur_info->info.XResolution <= dispi_get_max_xres()) && - (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && - (size_64k <= vbe_info_block.TotalMemory)) { -#ifdef DEBUG - printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); -#endif - write_word(ES, DI + cur_ptr, cur_info->mode); - cur_mode++; - cur_ptr+=2; - } else { -#ifdef DEBUG - printf("VBE mode %x (xres=%x / bpp=%02x) not supported \n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel); -#endif - } - cur_info++; - } while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST); - - // Add vesa mode list terminator - write_word(ES, DI + cur_ptr, cur_info->mode); - - result = 0x4f; - - write_word(ss, AX, result); -} - - -/** Function 01h - Return VBE Mode Information - * - * Input: - * AX = 4F01h - * CX = Mode Number - * ES:DI = Pointer to buffer in which to place ModeInfoBlock structure - * Output: - * AX = VBE Return Status - * - */ -void vbe_biosfn_return_mode_information(AX, CX, ES, DI) -Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; -{ - Bit16u result=0x0100; - Bit16u ss=get_SS(); - ModeInfoBlock info; - ModeInfoListItem *cur_info; - Boolean using_lfb; - Bit16u lfb_addr; - -#ifdef DEBUG - printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX); -#endif - - using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); - - CX = (CX & 0x1ff); - - cur_info = mode_info_find_mode(CX, using_lfb, &cur_info); - - if (cur_info != 0) - { -#ifdef DEBUG - printf("VBE found mode %x\n",CX); -#endif - memsetb(ss, &info, 0, sizeof(ModeInfoBlock)); - memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact)); - if (using_lfb) { - info.NumberOfBanks = 1; - } -#ifdef PCI_VID - lfb_addr = pci_get_lfb_addr(PCI_VID); -#else - lfb_addr = 0; -#endif - if (lfb_addr > 0) { - info.PhysBasePtr = ((Bit32u)lfb_addr << 16); - } - if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) { - info.WinFuncPtr = 0xC0000000UL; - *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall); - } - - result = 0x4f; - } - else - { -#ifdef DEBUG - printf("VBE *NOT* found mode %x\n",CX); -#endif - result = 0x100; - } - - if (result == 0x4f) - { - // copy updates in mode_info_block back - memcpyb(ES, DI, ss, &info, sizeof(info)); - } - - write_word(ss, AX, result); -} - -/** Function 02h - Set VBE Mode - * - * Input: - * AX = 4F02h - * BX = Desired Mode to set - * ES:DI = Pointer to CRTCInfoBlock structure - * Output: - * AX = VBE Return Status - * - */ -void vbe_biosfn_set_mode(AX, BX, ES, DI) -Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI; -{ - Bit16u ss = get_SS(); - Bit16u result; - ModeInfoListItem *cur_info; - Boolean using_lfb; - Bit8u no_clear; - Bit8u lfb_flag; - - using_lfb=((BX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); - lfb_flag=using_lfb?VBE_DISPI_LFB_ENABLED:0; - no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0; - - BX = (BX & 0x1ff); - - //result=read_word(ss,AX); - - // check for non vesa mode - if (BXinfo.XResolution, - cur_info->info.YResolution, - cur_info->info.BitsPerPixel); -#endif - - // first disable current mode (when switching between vesa modi) - dispi_set_enable(VBE_DISPI_DISABLED); - - if (cur_info->info.BitsPerPixel == 4) - { - biosfn_set_video_mode(0x6a); - } - - dispi_set_bpp(cur_info->info.BitsPerPixel); - dispi_set_xres(cur_info->info.XResolution); - dispi_set_yres(cur_info->info.YResolution); - dispi_set_bank(0); - dispi_set_enable(VBE_DISPI_ENABLED | no_clear | lfb_flag); - vga_compat_setup(); - - write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX); - write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear)); - - result = 0x4f; - } - else - { -#ifdef DEBUG - printf("VBE *NOT* found mode %x\n" , BX); -#endif - result = 0x100; - - // FIXME: redirect non VBE modi to normal VGA bios operation - // (switch back to VGA mode - if (BX == 3) - result = 0x4f; - } - - write_word(ss, AX, result); -} - -/** Function 03h - Return Current VBE Mode - * - * Input: - * AX = 4F03h - * Output: - * AX = VBE Return Status - * BX = Current VBE Mode - * - */ -ASM_START -vbe_biosfn_return_current_mode: - push ds - mov ax, # BIOSMEM_SEG - mov ds, ax - call dispi_get_enable - and ax, # VBE_DISPI_ENABLED - jz no_vbe_mode - mov bx, # BIOSMEM_VBE_MODE - mov ax, [bx] - mov bx, ax - jnz vbe_03_ok -no_vbe_mode: - mov bx, # BIOSMEM_CURRENT_MODE - mov al, [bx] - mov bl, al - xor bh, bh -vbe_03_ok: - mov ax, #0x004f - pop ds - ret -ASM_END - - -Bit16u vbe_biosfn_read_video_state_size() -{ - return 9 * 2; -} - -void vbe_biosfn_save_video_state(ES, BX) - Bit16u ES; Bit16u BX; -{ - Bit16u enable, i; - - outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); - enable = inw(VBE_DISPI_IOPORT_DATA); - write_word(ES, BX, enable); - BX += 2; - if (!(enable & VBE_DISPI_ENABLED)) - return; - for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { - if (i != VBE_DISPI_INDEX_ENABLE) { - outw(VBE_DISPI_IOPORT_INDEX, i); - write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA)); - BX += 2; - } - } -} - - -void vbe_biosfn_restore_video_state(ES, BX) - Bit16u ES; Bit16u BX; -{ - Bit16u enable, i; - - enable = read_word(ES, BX); - BX += 2; - - if (!(enable & VBE_DISPI_ENABLED)) { - outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); - outw(VBE_DISPI_IOPORT_DATA, enable); - } else { - outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES); - outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); - BX += 2; - outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES); - outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); - BX += 2; - outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP); - outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); - BX += 2; - outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); - outw(VBE_DISPI_IOPORT_DATA, enable); - - for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { - outw(VBE_DISPI_IOPORT_INDEX, i); - outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); - BX += 2; - } - } -} - -/** Function 04h - Save/Restore State - * - * Input: - * AX = 4F04h - * DL = 00h Return Save/Restore State buffer size - * 01h Save State - * 02h Restore State - * CX = Requested states - * ES:BX = Pointer to buffer (if DL <> 00h) - * Output: - * AX = VBE Return Status - * BX = Number of 64-byte blocks to hold the state buffer (if DL=00h) - * - */ -void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX) -Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX; -{ - Bit16u ss=get_SS(); - Bit16u result, val; - - result = 0x4f; - switch(GET_DL()) { - case 0x00: - val = biosfn_read_video_state_size2(CX); -#ifdef DEBUG - printf("VGA state size=%x\n", val); -#endif - if (CX & 8) - val += vbe_biosfn_read_video_state_size(); - write_word(ss, BX, val); - break; - case 0x01: - val = read_word(ss, BX); - val = biosfn_save_video_state(CX, ES, val); -#ifdef DEBUG - printf("VGA save_state offset=%x\n", val); -#endif - if (CX & 8) - vbe_biosfn_save_video_state(ES, val); - break; - case 0x02: - val = read_word(ss, BX); - val = biosfn_restore_video_state(CX, ES, val); -#ifdef DEBUG - printf("VGA restore_state offset=%x\n", val); -#endif - if (CX & 8) - vbe_biosfn_restore_video_state(ES, val); - break; - default: - // function failed - result = 0x100; - break; - } - write_word(ss, AX, result); -} - -/** Function 05h - Display Window Control - * - * Input: - * AX = 4F05h - * (16-bit) BH = 00h Set memory window - * = 01h Get memory window - * BL = Window number - * = 00h Window A - * = 01h Window B - * DX = Window number in video memory in window - * granularity units (Set Memory Window only) - * Note: - * If this function is called while in a linear frame buffer mode, - * this function must fail with completion code AH=03h - * - * Output: - * AX = VBE Return Status - * DX = Window number in window granularity units - * (Get Memory Window only) - */ -ASM_START -vbe_biosfn_display_window_control: - cmp bl, #0x00 - jne vbe_05_failed - cmp bh, #0x01 - je get_display_window - jb set_display_window - mov ax, #0x0100 - ret -set_display_window: - mov ax, dx - call _dispi_set_bank - call dispi_get_bank - cmp ax, dx - jne vbe_05_failed - mov ax, #0x004f - ret -get_display_window: - call dispi_get_bank - mov dx, ax - mov ax, #0x004f - ret -vbe_05_failed: - mov ax, #0x014f - ret -ASM_END - - -/** Function 06h - Set/Get Logical Scan Line Length - * - * Input: - * AX = 4F06h - * BL = 00h Set Scan Line Length in Pixels - * = 01h Get Scan Line Length - * = 02h Set Scan Line Length in Bytes - * = 03h Get Maximum Scan Line Length - * CX = If BL=00h Desired Width in Pixels - * If BL=02h Desired Width in Bytes - * (Ignored for Get Functions) - * - * Output: - * AX = VBE Return Status - * BX = Bytes Per Scan Line - * CX = Actual Pixels Per Scan Line - * (truncated to nearest complete pixel) - * DX = Maximum Number of Scan Lines - */ -ASM_START -vbe_biosfn_set_get_logical_scan_line_length: - mov ax, cx - cmp bl, #0x01 - je get_logical_scan_line_length - cmp bl, #0x02 - je set_logical_scan_line_bytes - jb set_logical_scan_line_pixels - mov ax, #0x0100 - ret -set_logical_scan_line_bytes: - push ax - call dispi_get_bpp - xor bh, bh - mov bl, ah - or bl, bl - jnz no_4bpp_1 - shl ax, #3 - mov bl, #1 -no_4bpp_1: - xor dx, dx - pop ax - div bx -set_logical_scan_line_pixels: - call dispi_set_virt_width -get_logical_scan_line_length: - call dispi_get_bpp - xor bh, bh - mov bl, ah - call dispi_get_virt_width - mov cx, ax - or bl, bl - jnz no_4bpp_2 - shr ax, #3 - mov bl, #1 -no_4bpp_2: - mul bx - mov bx, ax - call dispi_get_virt_height - mov dx, ax - mov ax, #0x004f - ret -ASM_END - - -/** Function 07h - Set/Get Display Start - * - * Input(16-bit): - * AX = 4F07h - * BH = 00h Reserved and must be 00h - * BL = 00h Set Display Start - * = 01h Get Display Start - * = 02h Schedule Display Start (Alternate) - * = 03h Schedule Stereoscopic Display Start - * = 04h Get Scheduled Display Start Status - * = 05h Enable Stereoscopic Mode - * = 06h Disable Stereoscopic Mode - * = 80h Set Display Start during Vertical Retrace - * = 82h Set Display Start during Vertical Retrace (Alternate) - * = 83h Set Stereoscopic Display Start during Vertical Retrace - * ECX = If BL=02h/82h Display Start Address in bytes - * If BL=03h/83h Left Image Start Address in bytes - * EDX = If BL=03h/83h Right Image Start Address in bytes - * CX = If BL=00h/80h First Displayed Pixel In Scan Line - * DX = If BL=00h/80h First Displayed Scan Line - * - * Output: - * AX = VBE Return Status - * BH = If BL=01h Reserved and will be 0 - * CX = If BL=01h First Displayed Pixel In Scan Line - * If BL=04h 0 if flip has not occurred, not 0 if it has - * DX = If BL=01h First Displayed Scan Line - * - * Input(32-bit): - * BH = 00h Reserved and must be 00h - * BL = 00h Set Display Start - * = 80h Set Display Start during Vertical Retrace - * CX = Bits 0-15 of display start address - * DX = Bits 16-31 of display start address - * ES = Selector for memory mapped registers - */ -ASM_START -vbe_biosfn_set_get_display_start: - cmp bl, #0x80 - je set_display_start - cmp bl, #0x01 - je get_display_start - jb set_display_start - mov ax, #0x0100 - ret -set_display_start: - mov ax, cx - call dispi_set_x_offset - mov ax, dx - call dispi_set_y_offset - mov ax, #0x004f - ret -get_display_start: - call dispi_get_x_offset - mov cx, ax - call dispi_get_y_offset - mov dx, ax - xor bh, bh - mov ax, #0x004f - ret -ASM_END - - -/** Function 08h - Set/Get Dac Palette Format - * - * Input: - * AX = 4F08h - * BL = 00h set DAC palette width - * = 01h get DAC palette width - * BH = If BL=00h: desired number of bits per primary color - * Output: - * AX = VBE Return Status - * BH = current number of bits per primary color (06h = standard VGA) - */ -ASM_START -vbe_biosfn_set_get_dac_palette_format: - cmp bl, #0x01 - je get_dac_palette_format - jb set_dac_palette_format - mov ax, #0x0100 - ret -set_dac_palette_format: - call dispi_get_enable - cmp bh, #0x06 - je set_normal_dac - cmp bh, #0x08 - jne vbe_08_unsupported - or ax, # VBE_DISPI_8BIT_DAC - jnz set_dac_mode -set_normal_dac: - and ax, #~ VBE_DISPI_8BIT_DAC -set_dac_mode: - call _dispi_set_enable -get_dac_palette_format: - mov bh, #0x06 - call dispi_get_enable - and ax, # VBE_DISPI_8BIT_DAC - jz vbe_08_ok - mov bh, #0x08 -vbe_08_ok: - mov ax, #0x004f - ret -vbe_08_unsupported: - mov ax, #0x014f - ret -ASM_END - - -/** Function 09h - Set/Get Palette Data - * - * Input: - * AX = 4F09h - * Output: - * AX = VBE Return Status - * - * FIXME: incomplete API description, Input & Output - */ -void vbe_biosfn_set_get_palette_data(AX) -{ -} - -/** Function 0Ah - Return VBE Protected Mode Interface - * Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface - * BL = 00h Return protected mode table - * - * - * Output: AX = Status - * ES = Real Mode Segment of Table - * DI = Offset of Table - * CX = Length of Table including protected mode code - * (for copying purposes) - */ -ASM_START -vbe_biosfn_return_protected_mode_interface: - test bl, bl - jnz _fail - mov di, #0xc000 - mov es, di - mov di, # vesa_pm_start - mov cx, # vesa_pm_end - sub cx, di - mov ax, #0x004f - ret -_fail: - mov ax, #0x014f - ret -ASM_END diff --git a/roms/vgabios/vbe.h b/roms/vgabios/vbe.h deleted file mode 100644 index 72cb045..0000000 --- a/roms/vgabios/vbe.h +++ /dev/null @@ -1,315 +0,0 @@ -#ifndef vbe_h_included -#define vbe_h_included - -#include "vgabios.h" - -// DISPI helper function -void dispi_set_enable(enable); - -/** VBE int10 API - * - * See the function descriptions in vbe.c for more information - */ -Boolean vbe_has_vbe_display(); -void vbe_biosfn_return_controller_information(AX, ES, DI); -void vbe_biosfn_return_mode_information(AX, CX, ES, DI); -void vbe_biosfn_set_mode(AX, BX, ES, DI); -void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX); -void vbe_biosfn_set_get_palette_data(AX); -void vbe_biosfn_return_protected_mode_interface(AX); - -// The official VBE Information Block -typedef struct VbeInfoBlock -{ - Bit8u VbeSignature[4]; - Bit16u VbeVersion; - Bit16u OemStringPtr_Off; - Bit16u OemStringPtr_Seg; - Bit8u Capabilities[4]; - Bit16u VideoModePtr_Off; - Bit16u VideoModePtr_Seg; - Bit16u TotalMemory; - Bit16u OemSoftwareRev; - Bit16u OemVendorNamePtr_Off; - Bit16u OemVendorNamePtr_Seg; - Bit16u OemProductNamePtr_Off; - Bit16u OemProductNamePtr_Seg; - Bit16u OemProductRevPtr_Off; - Bit16u OemProductRevPtr_Seg; - Bit16u Reserved[111]; // used for dynamicly generated mode list - Bit8u OemData[256]; -} VbeInfoBlock; - - -// This one is for compactly storing a static list of mode info blocks -// this saves us 189 bytes per block -typedef struct ModeInfoBlockCompact -{ -// Mandatory information for all VBE revisions - Bit16u ModeAttributes; - Bit8u WinAAttributes; - Bit8u WinBAttributes; - Bit16u WinGranularity; - Bit16u WinSize; - Bit16u WinASegment; - Bit16u WinBSegment; - Bit32u WinFuncPtr; - Bit16u BytesPerScanLine; -// Mandatory information for VBE 1.2 and above - Bit16u XResolution; - Bit16u YResolution; - Bit8u XCharSize; - Bit8u YCharSize; - Bit8u NumberOfPlanes; - Bit8u BitsPerPixel; - Bit8u NumberOfBanks; - Bit8u MemoryModel; - Bit8u BankSize; - Bit8u NumberOfImagePages; - Bit8u Reserved_page; -// Direct Color fields (required for direct/6 and YUV/7 memory models) - Bit8u RedMaskSize; - Bit8u RedFieldPosition; - Bit8u GreenMaskSize; - Bit8u GreenFieldPosition; - Bit8u BlueMaskSize; - Bit8u BlueFieldPosition; - Bit8u RsvdMaskSize; - Bit8u RsvdFieldPosition; - Bit8u DirectColorModeInfo; -// Mandatory information for VBE 2.0 and above - Bit32u PhysBasePtr; - Bit32u OffScreenMemOffset; - Bit16u OffScreenMemSize; -// Mandatory information for VBE 3.0 and above - Bit16u LinBytesPerScanLine; - Bit8u BnkNumberOfPages; - Bit8u LinNumberOfPages; - Bit8u LinRedMaskSize; - Bit8u LinRedFieldPosition; - Bit8u LinGreenMaskSize; - Bit8u LinGreenFieldPosition; - Bit8u LinBlueMaskSize; - Bit8u LinBlueFieldPosition; - Bit8u LinRsvdMaskSize; - Bit8u LinRsvdFieldPosition; - Bit32u MaxPixelClock; -// Bit8u Reserved[189]; // DO NOT PUT THIS IN HERE because of Compact Mode Info storage in bios -} ModeInfoBlockCompact; - -typedef struct ModeInfoBlock -{ -// Mandatory information for all VBE revisions - Bit16u ModeAttributes; - Bit8u WinAAttributes; - Bit8u WinBAttributes; - Bit16u WinGranularity; - Bit16u WinSize; - Bit16u WinASegment; - Bit16u WinBSegment; - Bit32u WinFuncPtr; - Bit16u BytesPerScanLine; -// Mandatory information for VBE 1.2 and above - Bit16u XResolution; - Bit16u YResolution; - Bit8u XCharSize; - Bit8u YCharSize; - Bit8u NumberOfPlanes; - Bit8u BitsPerPixel; - Bit8u NumberOfBanks; - Bit8u MemoryModel; - Bit8u BankSize; - Bit8u NumberOfImagePages; - Bit8u Reserved_page; -// Direct Color fields (required for direct/6 and YUV/7 memory models) - Bit8u RedMaskSize; - Bit8u RedFieldPosition; - Bit8u GreenMaskSize; - Bit8u GreenFieldPosition; - Bit8u BlueMaskSize; - Bit8u BlueFieldPosition; - Bit8u RsvdMaskSize; - Bit8u RsvdFieldPosition; - Bit8u DirectColorModeInfo; -// Mandatory information for VBE 2.0 and above - Bit32u PhysBasePtr; - Bit32u OffScreenMemOffset; - Bit16u OffScreenMemSize; -// Mandatory information for VBE 3.0 and above - Bit16u LinBytesPerScanLine; - Bit8u BnkNumberOfPages; - Bit8u LinNumberOfPages; - Bit8u LinRedMaskSize; - Bit8u LinRedFieldPosition; - Bit8u LinGreenMaskSize; - Bit8u LinGreenFieldPosition; - Bit8u LinBlueMaskSize; - Bit8u LinBlueFieldPosition; - Bit8u LinRsvdMaskSize; - Bit8u LinRsvdFieldPosition; - Bit32u MaxPixelClock; - Bit8u Reserved[189]; -} ModeInfoBlock; - -typedef struct ModeInfoListItem -{ - Bit16u mode; - ModeInfoBlockCompact info; -} ModeInfoListItem; - -// VBE Return Status Info -// AL -#define VBE_RETURN_STATUS_SUPPORTED 0x4F -#define VBE_RETURN_STATUS_UNSUPPORTED 0x00 -// AH -#define VBE_RETURN_STATUS_SUCCESSFULL 0x00 -#define VBE_RETURN_STATUS_FAILED 0x01 -#define VBE_RETURN_STATUS_NOT_SUPPORTED 0x02 -#define VBE_RETURN_STATUS_INVALID 0x03 - -// VBE Mode Numbers - -#define VBE_MODE_VESA_DEFINED 0x0100 -#define VBE_MODE_REFRESH_RATE_USE_CRTC 0x0800 -#define VBE_MODE_LINEAR_FRAME_BUFFER 0x4000 -#define VBE_MODE_PRESERVE_DISPLAY_MEMORY 0x8000 - -// VBE GFX Mode Number - -#define VBE_VESA_MODE_640X400X8 0x100 -#define VBE_VESA_MODE_640X480X8 0x101 -#define VBE_VESA_MODE_800X600X4 0x102 -#define VBE_VESA_MODE_800X600X8 0x103 -#define VBE_VESA_MODE_1024X768X4 0x104 -#define VBE_VESA_MODE_1024X768X8 0x105 -#define VBE_VESA_MODE_1280X1024X4 0x106 -#define VBE_VESA_MODE_1280X1024X8 0x107 -#define VBE_VESA_MODE_320X200X1555 0x10D -#define VBE_VESA_MODE_320X200X565 0x10E -#define VBE_VESA_MODE_320X200X888 0x10F -#define VBE_VESA_MODE_640X480X1555 0x110 -#define VBE_VESA_MODE_640X480X565 0x111 -#define VBE_VESA_MODE_640X480X888 0x112 -#define VBE_VESA_MODE_800X600X1555 0x113 -#define VBE_VESA_MODE_800X600X565 0x114 -#define VBE_VESA_MODE_800X600X888 0x115 -#define VBE_VESA_MODE_1024X768X1555 0x116 -#define VBE_VESA_MODE_1024X768X565 0x117 -#define VBE_VESA_MODE_1024X768X888 0x118 -#define VBE_VESA_MODE_1280X1024X1555 0x119 -#define VBE_VESA_MODE_1280X1024X565 0x11A -#define VBE_VESA_MODE_1280X1024X888 0x11B -#define VBE_VESA_MODE_1600X1200X8 0x11C -#define VBE_VESA_MODE_1600X1200X1555 0x11D -#define VBE_VESA_MODE_1600X1200X565 0x11E -#define VBE_VESA_MODE_1600X1200X888 0x11F - -// BOCHS/PLEX86 'own' mode numbers -#define VBE_OWN_MODE_320X200X8888 0x140 -#define VBE_OWN_MODE_640X400X8888 0x141 -#define VBE_OWN_MODE_640X480X8888 0x142 -#define VBE_OWN_MODE_800X600X8888 0x143 -#define VBE_OWN_MODE_1024X768X8888 0x144 -#define VBE_OWN_MODE_1280X1024X8888 0x145 -#define VBE_OWN_MODE_320X200X8 0x146 -#define VBE_OWN_MODE_1600X1200X8888 0x147 -#define VBE_OWN_MODE_1152X864X8 0x148 -#define VBE_OWN_MODE_1152X864X1555 0x149 -#define VBE_OWN_MODE_1152X864X565 0x14a -#define VBE_OWN_MODE_1152X864X888 0x14b -#define VBE_OWN_MODE_1152X864X8888 0x14c - -#define VBE_VESA_MODE_END_OF_LIST 0xFFFF - -// Capabilities - -#define VBE_CAPABILITY_8BIT_DAC 0x0001 -#define VBE_CAPABILITY_NOT_VGA_COMPATIBLE 0x0002 -#define VBE_CAPABILITY_RAMDAC_USE_BLANK_BIT 0x0004 -#define VBE_CAPABILITY_STEREOSCOPIC_SUPPORT 0x0008 -#define VBE_CAPABILITY_STEREO_VIA_VESA_EVC 0x0010 - -// Mode Attributes - -#define VBE_MODE_ATTRIBUTE_SUPPORTED 0x0001 -#define VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE 0x0002 -#define VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT 0x0004 -#define VBE_MODE_ATTRIBUTE_COLOR_MODE 0x0008 -#define VBE_MODE_ATTRIBUTE_GRAPHICS_MODE 0x0010 -#define VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE 0x0020 -#define VBE_MODE_ATTRIBUTE_NO_VGA_COMPATIBLE_WINDOW 0x0040 -#define VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE 0x0080 -#define VBE_MODE_ATTRIBUTE_DOUBLE_SCAN_MODE 0x0100 -#define VBE_MODE_ATTRIBUTE_INTERLACE_MODE 0x0200 -#define VBE_MODE_ATTRIBUTE_HARDWARE_TRIPLE_BUFFER 0x0400 -#define VBE_MODE_ATTRIBUTE_HARDWARE_STEREOSCOPIC_DISPLAY 0x0800 -#define VBE_MODE_ATTRIBUTE_DUAL_DISPLAY_START_ADDRESS 0x1000 - -#define VBE_MODE_ATTTRIBUTE_LFB_ONLY ( VBE_MODE_ATTRIBUTE_NO_VGA_COMPATIBLE_WINDOW | VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE ) - -// Window attributes - -#define VBE_WINDOW_ATTRIBUTE_RELOCATABLE 0x01 -#define VBE_WINDOW_ATTRIBUTE_READABLE 0x02 -#define VBE_WINDOW_ATTRIBUTE_WRITEABLE 0x04 - -// Memory model - -#define VBE_MEMORYMODEL_TEXT_MODE 0x00 -#define VBE_MEMORYMODEL_CGA_GRAPHICS 0x01 -#define VBE_MEMORYMODEL_HERCULES_GRAPHICS 0x02 -#define VBE_MEMORYMODEL_PLANAR 0x03 -#define VBE_MEMORYMODEL_PACKED_PIXEL 0x04 -#define VBE_MEMORYMODEL_NON_CHAIN_4_256 0x05 -#define VBE_MEMORYMODEL_DIRECT_COLOR 0x06 -#define VBE_MEMORYMODEL_YUV 0x07 - -// DirectColorModeInfo - -#define VBE_DIRECTCOLOR_COLOR_RAMP_PROGRAMMABLE 0x01 -#define VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE 0x02 - -// GUEST <-> HOST Communication API - -// FIXME: either dynamicly ask host for this or put somewhere high in physical memory -// like 0xE0000000 - - - #define VBE_DISPI_BANK_ADDRESS 0xA0000 - #define VBE_DISPI_BANK_SIZE_KB 64 - - #define VBE_DISPI_MAX_XRES 2560 - #define VBE_DISPI_MAX_YRES 1600 - - #define VBE_DISPI_IOPORT_INDEX 0x01CE - #define VBE_DISPI_IOPORT_DATA 0x01CF - - #define VBE_DISPI_INDEX_ID 0x0 - #define VBE_DISPI_INDEX_XRES 0x1 - #define VBE_DISPI_INDEX_YRES 0x2 - #define VBE_DISPI_INDEX_BPP 0x3 - #define VBE_DISPI_INDEX_ENABLE 0x4 - #define VBE_DISPI_INDEX_BANK 0x5 - #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 - #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 - #define VBE_DISPI_INDEX_X_OFFSET 0x8 - #define VBE_DISPI_INDEX_Y_OFFSET 0x9 - #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa - - #define VBE_DISPI_ID0 0xB0C0 - #define VBE_DISPI_ID1 0xB0C1 - #define VBE_DISPI_ID2 0xB0C2 - #define VBE_DISPI_ID3 0xB0C3 - #define VBE_DISPI_ID4 0xB0C4 - #define VBE_DISPI_ID5 0xB0C5 - - #define VBE_DISPI_DISABLED 0x00 - #define VBE_DISPI_ENABLED 0x01 - #define VBE_DISPI_GETCAPS 0x02 - #define VBE_DISPI_8BIT_DAC 0x20 - #define VBE_DISPI_LFB_ENABLED 0x40 - #define VBE_DISPI_NOCLEARMEM 0x80 - - #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 - -#endif diff --git a/roms/vgabios/vbe_display_api.txt b/roms/vgabios/vbe_display_api.txt deleted file mode 100644 index fddb78b..0000000 --- a/roms/vgabios/vbe_display_api.txt +++ /dev/null @@ -1,237 +0,0 @@ -VBE Display API -------------------------------------------------------------------------------------------------------------- - This document is part of the Bochs/VBEBios documentation, - it specifies the bochs host <-> vbebios client communication. - - That means, the display code implementation and the vbebios code depend - very heavily on each other. As such, this documents needs be synchronised - between bochs CVS and the vgabios CVS. - - This document does not describe how the VBEBios implements the VBE2/3 spec. - This document does not describe how the Bochs display code will display gfx based upon this spec. - - -API History ------------ -0xb0c0 supports the following VBE_DISPI_ interfaces (present in Bochs 1.4): - VBE_DISPI_INDEX_ID - VBE_DISPI_INDEX_XRES - VBE_DISPI_INDEX_YRES - VBE_DISPI_INDEX_BPP - VBE_DISPI_INDEX_ENABLE - VBE_DISPI_INDEX_BANK - - Bpp format supported is: - VBE_DISPI_BPP_8 - -0xb0c1 supports 0xb0c0 VBE_DISPI_ interfaces, additional interfaces (present in Bochs 2.0): - VBE_DISPI_INDEX_VIRT_WIDTH - VBE_DISPI_INDEX_VIRT_HEIGHT - VBE_DISPI_INDEX_X_OFFSET - VBE_DISPI_INDEX_Y_OFFSET - -0xb0c2 supports 0xb0c1 VBE_DISPI_ interfaces, interfaces updated for - additional features (present in Bochs 2.1): - VBE_DISPI_INDEX_BPP supports >8bpp color depth (value = bits) - VBE_DISPI_INDEX_ENABLE supports new flags VBE_DISPI_NOCLEARMEM and VBE_DISPI_LFB_ENABLED - VBE i/o registers changed from 0xFF80/81 to 0x01CE/CF - -0xb0c3 supports 0xb0c2 VBE_DISPI_ interfaces, interfaces updated for - additional features: - VBE_DISPI_INDEX_ENABLE supports new flags VBE_DISPI_GETCAPS and VBE_DISPI_8BIT_DAC - -0xb0c4 VBE video memory increased to 8 MB - - -History -------- - Version 0.6 2002 Nov 23 Jeroen Janssen - - Added LFB support - - Added Virt width, height and x,y offset - - Version 0.5 2002 March 08 Jeroen Janssen - - Added documentation about panic behaviour / current limits of the data values. - - Changed BPP API (in order to include future (A)RGB formats) - - Initial version (based upon extended display text of the vbe bochs display patch) - - -Todo ----- - Version 0.6+ [random order] - - Add lots of different (A)RGB formats - -References ----------- - [VBE3] VBE 3 Specification at - http://www.vesa.org/vbe3.pdf - - [BOCHS] Bochs Open Source IA-32 Emulator at - http://bochs.sourceforge.net - - [VBEBIOS] VBE Bios for Bochs at - http://savannah.gnu.org/projects/vgabios/ - - [Screenshots] Screenshots of programs using the VBE Bios at - http://japj.org/projects/bochs_plex86/screenshots.html - -Abbreviations -------------- - VBE Vesa Bios Extension - DISPI (Bochs) Display Interface - BPP Bits Per Pixel - LFB Linear Frame Buffer - - -#defines --------- -vbetables-gen.c - #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 8 - -vbe.h - #define VBE_DISPI_BANK_ADDRESS 0xA0000 - #define VBE_DISPI_BANK_SIZE_KB 64 - - #define VBE_DISPI_MAX_XRES 1024 - #define VBE_DISPI_MAX_YRES 768 - - #define VBE_DISPI_IOPORT_INDEX 0x01CE - #define VBE_DISPI_IOPORT_DATA 0x01CF - - #define VBE_DISPI_INDEX_ID 0x0 - #define VBE_DISPI_INDEX_XRES 0x1 - #define VBE_DISPI_INDEX_YRES 0x2 - #define VBE_DISPI_INDEX_BPP 0x3 - #define VBE_DISPI_INDEX_ENABLE 0x4 - #define VBE_DISPI_INDEX_BANK 0x5 - #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 - #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 - #define VBE_DISPI_INDEX_X_OFFSET 0x8 - #define VBE_DISPI_INDEX_Y_OFFSET 0x9 - - #define VBE_DISPI_ID0 0xB0C0 - #define VBE_DISPI_ID1 0xB0C1 - #define VBE_DISPI_ID2 0xB0C2 - #define VBE_DISPI_ID3 0xB0C3 - #define VBE_DISPI_ID4 0xB0C4 - - #define VBE_DISPI_DISABLED 0x00 - #define VBE_DISPI_ENABLED 0x01 - #define VBE_DISPI_VBE_ENABLED 0x40 - #define VBE_DISPI_NOCLEARMEM 0x80 - - #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 - -API ---- - The display api works by using a index (VBE_DISPI_IOPORT_INDEX) and - data (VBE_DISPI_IOPORT_DATA) ioport. One writes the index of the parameter to the index port. - Next, the parameter value can be read or written. - -[0xb0c0] - * VBE_DISPI_INDEX_ID : WORD {R,W} - This parameter can be used to detect the current display API (both bochs & vbebios). - The bios writes VBE_DISPI_ID0 to the dataport and reads it back again. - This way, the display code knows the vbebios 'ID' and the vbebios can check if the correct - display code is present. - As a result, a PANIC can be generated if an incompatible vbebios/display code combination is detected. - This panic can be generated from the bochs display code (NOT the bios, see Notes). - - Example values: VBE_DISPI_ID0 - - * VBE_DISPI_INDEX_XRES : WORD {R,W} - This parameter can be used to read/write the vbe display X resolution (in pixels). - It's illegal to set the XRES when the VBE is enabled (display code should generate PANIC). - - If the value written exceeds VBE_DISPI_MAX_XRES, the display code needs to generate a PANIC. - - Example values: 320,640,800,1024 - - * VBE_DISPI_INDEX_YRES : WORD {R,W} - This parameter can be used to read/write the vbe display Y resolution (in pixels). - It's illegal to set the YRES when the VBE is enabled (display code should generate PANIC). - - If the value written exceeds VBE_DISPI_MAX_YRES, the display code needs to generate a PANIC. - - Example values: 200,400,480,600,768 - - * VBE_DISPI_INDEX_BPP : WORD {R,W} - This parameter can be used to read/write the vbe display BPP. - It's illegal to set the BPP when the VBE is enabled (display code should generate PANIC). - - If the value written is an incompatible BPP, the display code needs to generate a PANIC. - - Example values: VBE_DISPI_BPP_8 - - * VBE_DISPI_INDEX_ENABLE : WORD {R,W} - This parameter can be used to read/write the vbe ENABLED state. - If the bios writes VBE_DISPI_ENABLED then the display code will setup a hostside display mode - with the current XRES, YRES and BPP settings. - If the bios write VBE_DISPI_DISABLED then the display code will switch back to normal vga mode behaviour. - - Example values: VBE_DISPI_ENABLED, VBE_DISPI_DISABLED - - * VBE_DISPI_INDEX_BANK : WORD {R,W} - This parameter can be used to read/write the current selected BANK (at 0xA0000). - This can be used for switching banks in banked mode. - -[0xb0c1] - * VBE_DISPI_INDEX_VIRT_WIDTH : WORD {R,W} - This parameter can be used to read/write the current virtual width. - Upon enabling a mode, this will be set to the current xres - Setting this field during enabled mode will result in the virtual width to be changed. - Value will be adjusted if current setting is not possible. - - * VBE_DISPI_INDEX_VIRT_HEIGHT : WORD {R} - This parameter can be read in order to obtain the current virtual height. - This setting will be adjusted after setting a virtual width in order to stay within limit of video memory. - - * VBE_DISPI_INDEX_X_OFFSET : WORD {R,W} - The current X offset (in pixels!) of the visible screen part. - Writing a new offset will also result in a complete screen refresh. - - * VBE_DISPI_INDEX_Y_OFFSET : WORD {R,W} - The current Y offset (in pixels!) of the visible screen part. - Writing a new offset will also result in a complete screen refresh. - - -[0xb0c2] - * VBE_DISPI_INDEX_BPP : WORD {R,W} - The value written is now the number of bits per pixel. A value of 0 is treated - the same as 8 for backward compatibilty. These values are supported: 8, 15, - 16, 24 and 32. The value of 4 is not yet handled in the VBE code. - * VBE_DISPI_INDEX_ENABLE : WORD {R,W} - The new flag VBE_DISPI_NOCLEARMEM allows to preserve the VBE video memory. - The new flag VBE_DISPI_LFB_ENABLED indicates the usage of the LFB. - -[0xb0c3] - * VBE_DISPI_INDEX_ENABLE : WORD {R,W} - If the new flag VBE_DISPI_GETCAPS is enabled, the xres, yres and bpp registers - return the gui capabilities. - The new flag VBE_DISPI_8BIT_DAC switches the DAC to 8 bit mode. - -[0xb0c4] - * VBE_DISPI_TOTAL_VIDEO_MEMORY_MB set to 8 (moved to auto-generated vbetables.h) - -Displaying GFX (banked mode) --------------- - What happens is that the total screen is devided in banks of 'VBE_DISPI_BANK_SIZE_KB' KiloByte in size. - If you want to set a pixel you can calculate its bank by doing: - - offset = pixel_x + pixel_y * resolution_x; - bank = offset / 64 Kb (rounded 1.9999 -> 1) - - bank_pixel_pos = offset - bank * 64Kb - - Now you can set the current bank and put the pixel at VBE_DISPI_BANK_ADDRESS + bank_pixel_pos - -Displaying GFX (linear frame buffer mode) --------------- - NOT WRITTEN YET - -Notes ------ - * Since the XRES/YRES/BPP may not be written when VBE is enabled, if you want to switch from one VBE mode - to another, you will need to disable VBE first. - - * Note when the bios doesn't find a valid DISPI_ID, it can disable the VBE functions. This allows people to - use the same bios for both vbe enabled and disabled bochs executables. diff --git a/roms/vgabios/vbetables-gen.c b/roms/vgabios/vbetables-gen.c deleted file mode 100644 index 550935a..0000000 --- a/roms/vgabios/vbetables-gen.c +++ /dev/null @@ -1,261 +0,0 @@ -/* Generate the VGABIOS VBE Tables */ -#include -#include - -#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 16 - -typedef struct { - int width; - int height; - int depth; - int mode; -} ModeInfo; - -ModeInfo modes[] = { - /* standard VESA modes */ -{ 640, 400, 8 , 0x100}, -{ 640, 480, 8 , 0x101}, -{ 800, 600, 4 , 0x102}, -{ 800, 600, 8 , 0x103}, -{ 1024, 768, 4 , 0x104}, -{ 1024, 768, 8 , 0x105}, -{ 1280, 1024, 4 , 0x106}, -{ 1280, 1024, 8 , 0x107}, -{ 320, 200, 15 , 0x10D}, -{ 320, 200, 16 , 0x10E}, -{ 320, 200, 24 , 0x10F}, -{ 640, 480, 15 , 0x110}, -{ 640, 480, 16 , 0x111}, -{ 640, 480, 24 , 0x112}, -{ 800, 600, 15 , 0x113}, -{ 800, 600, 16 , 0x114}, -{ 800, 600, 24 , 0x115}, -{ 1024, 768, 15 , 0x116}, -{ 1024, 768, 16 , 0x117}, -{ 1024, 768, 24 , 0x118}, -{ 1280, 1024, 15 , 0x119}, -{ 1280, 1024, 16 , 0x11A}, -{ 1280, 1024, 24 , 0x11B}, -{ 1600, 1200, 8 , 0x11C}, -{ 1600, 1200, 15 , 0x11D}, -{ 1600, 1200, 16 , 0x11E}, -{ 1600, 1200, 24 , 0x11F}, - - /* BOCHS/PLEX86 'own' mode numbers */ -{ 320, 200, 32 , 0x140}, -{ 640, 400, 32 , 0x141}, -{ 640, 480, 32 , 0x142}, -{ 800, 600, 32 , 0x143}, -{ 1024, 768, 32 , 0x144}, -{ 1280, 1024, 32 , 0x145}, -{ 320, 200, 8 , 0x146}, -{ 1600, 1200, 32 , 0x147}, -{ 1152, 864, 8 , 0x148}, -{ 1152, 864, 15 , 0x149}, -{ 1152, 864, 16 , 0x14a}, -{ 1152, 864, 24 , 0x14b}, -{ 1152, 864, 32 , 0x14c}, -{ 1280, 800, 16 , 0x178}, -{ 1280, 800, 24 , 0x179}, -{ 1280, 800, 32 , 0x17a}, -{ 1280, 960, 16 , 0x17b}, -{ 1280, 960, 24 , 0x17c}, -{ 1280, 960, 32 , 0x17d}, -{ 1440, 900, 16 , 0x17e}, -{ 1440, 900, 24 , 0x17f}, -{ 1440, 900, 32 , 0x180}, -{ 1400, 1050, 16 , 0x181}, -{ 1400, 1050, 24 , 0x182}, -{ 1400, 1050, 32 , 0x183}, -{ 1680, 1050, 16 , 0x184}, -{ 1680, 1050, 24 , 0x185}, -{ 1680, 1050, 32 , 0x186}, -{ 1920, 1200, 16 , 0x187}, -{ 1920, 1200, 24 , 0x188}, -{ 1920, 1200, 32 , 0x189}, -{ 2560, 1600, 16 , 0x18a}, -{ 2560, 1600, 24 , 0x18b}, -{ 2560, 1600, 32 , 0x18c}, -{ 0, }, -}; - -int main(int argc, char **argv) -{ - const ModeInfo *pm; - int pages, pitch; - int r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; - const char *str; - long vram_size = VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024 * 1024; - - printf("/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); - printf("#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB %d\n\n", VBE_DISPI_TOTAL_VIDEO_MEMORY_MB); - printf("static ModeInfoListItem mode_info_list[]=\n"); - printf("{\n"); - for (pm = modes; pm->mode != 0; pm++) { - if (pm->depth == 4) - pitch = (pm->width + 7) / 8; - else - pitch = pm->width * ((pm->depth + 7) / 8); - pages = vram_size / (pm->height * pitch); - if (pages > 0) { - printf("{ 0x%04x, /* %dx%dx%d */\n", - pm->mode, pm->width, pm->height, pm->depth); - if (pm->depth == 4) - printf("{ /*Bit16u ModeAttributes*/ %s,\n", - "VBE_MODE_ATTRIBUTE_SUPPORTED | " - "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | " - "VBE_MODE_ATTRIBUTE_COLOR_MODE | " - "VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT | " - "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE"); - else - printf("{ /*Bit16u ModeAttributes*/ %s,\n", - "VBE_MODE_ATTRIBUTE_SUPPORTED | " - "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | " - "VBE_MODE_ATTRIBUTE_COLOR_MODE | " - "VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE | " - "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE"); - printf("/*Bit8u WinAAttributes*/ %s,\n", - "VBE_WINDOW_ATTRIBUTE_RELOCATABLE | " - "VBE_WINDOW_ATTRIBUTE_READABLE | " - "VBE_WINDOW_ATTRIBUTE_WRITEABLE"); - - printf("/*Bit8u WinBAttributes*/ %d,\n", 0); - - printf("/*Bit16u WinGranularity*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); - - printf("/*Bit16u WinSize*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); - - printf("/*Bit16u WinASegment*/ %s,\n", "VGAMEM_GRAPH"); - - printf("/*Bit16u WinBSegment*/ 0x%04x,\n", 0); - - printf("/*Bit32u WinFuncPtr*/ %d,\n", 0); - - printf("/*Bit16u BytesPerScanLine*/ %d,\n", pitch); - - // Mandatory information for VBE 1.2 and above - printf("/*Bit16u XResolution*/ %d,\n", pm->width); - printf("/*Bit16u YResolution*/ %d,\n", pm->height); - printf("/*Bit8u XCharSize*/ %d,\n", 8); - printf("/*Bit8u YCharSize*/ %d,\n", 16); - if (pm->depth == 4) { - printf("/*Bit8u NumberOfPlanes*/ %d,\n", 4); - } else { - printf("/*Bit8u NumberOfPlanes*/ %d,\n", 1); - } - printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth); - printf("/*Bit8u NumberOfBanks*/ %d,\n", - (pm->height * pitch + 65535) / 65536); - - if (pm->depth == 4) - str = "VBE_MEMORYMODEL_PLANAR"; - else if (pm->depth == 8) - str = "VBE_MEMORYMODEL_PACKED_PIXEL"; - else - str = "VBE_MEMORYMODEL_DIRECT_COLOR"; - printf("/*Bit8u MemoryModel*/ %s,\n", str); - printf("/*Bit8u BankSize*/ %d,\n", 0); - if (pm->depth == 4) - printf("/*Bit8u NumberOfImagePages*/ %d,\n", (pages / 4) - 1); - else - printf("/*Bit8u NumberOfImagePages*/ %d,\n", pages - 1); - printf("/*Bit8u Reserved_page*/ %d,\n", 0); - - // Direct Color fields (required for direct/6 and YUV/7 memory models) - switch(pm->depth) { - case 15: - r_size = 5; - r_pos = 10; - g_size = 5; - g_pos = 5; - b_size = 5; - b_pos = 0; - a_size = 1; - a_pos = 15; - break; - case 16: - r_size = 5; - r_pos = 11; - g_size = 6; - g_pos = 5; - b_size = 5; - b_pos = 0; - a_size = 0; - a_pos = 0; - break; - case 24: - r_size = 8; - r_pos = 16; - g_size = 8; - g_pos = 8; - b_size = 8; - b_pos = 0; - a_size = 0; - a_pos = 0; - break; - case 32: - r_size = 8; - r_pos = 16; - g_size = 8; - g_pos = 8; - b_size = 8; - b_pos = 0; - a_size = 8; - a_pos = 24; - break; - default: - r_size = 0; - r_pos = 0; - g_size = 0; - g_pos = 0; - b_size = 0; - b_pos = 0; - a_size = 0; - a_pos = 0; - break; - } - - printf("/*Bit8u RedMaskSize*/ %d,\n", r_size); - printf("/*Bit8u RedFieldPosition*/ %d,\n", r_pos); - printf("/*Bit8u GreenMaskSize*/ %d,\n", g_size); - printf("/*Bit8u GreenFieldPosition*/ %d,\n", g_pos); - printf("/*Bit8u BlueMaskSize*/ %d,\n", b_size); - printf("/*Bit8u BlueFieldPosition*/ %d,\n", b_pos); - printf("/*Bit8u RsvdMaskSize*/ %d,\n", a_size); - printf("/*Bit8u RsvdFieldPosition*/ %d,\n", a_pos); - if (pm->depth == 32) - printf("/*Bit8u DirectColorModeInfo*/ %s,\n", - "VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE"); - else - printf("/*Bit8u DirectColorModeInfo*/ %s,\n", "0"); - -// Mandatory information for VBE 2.0 and above - if (pm->depth > 4) - printf("/*Bit32u PhysBasePtr*/ %s,\n", - "VBE_DISPI_LFB_PHYSICAL_ADDRESS"); - else - printf("/*Bit32u PhysBasePtr*/ %s,\n", "0"); - printf("/*Bit32u OffScreenMemOffset*/ %d,\n", 0); - printf("/*Bit16u OffScreenMemSize*/ %d,\n", 0); - // Mandatory information for VBE 3.0 and above - printf("/*Bit16u LinBytesPerScanLine*/ %d,\n", pitch); - printf("/*Bit8u BnkNumberOfPages*/ %d,\n", 0); - printf("/*Bit8u LinNumberOfPages*/ %d,\n", 0); - printf("/*Bit8u LinRedMaskSize*/ %d,\n", r_size); - printf("/*Bit8u LinRedFieldPosition*/ %d,\n", r_pos); - printf("/*Bit8u LinGreenMaskSize*/ %d,\n", g_size); - printf("/*Bit8u LinGreenFieldPosition*/ %d,\n", g_pos); - printf("/*Bit8u LinBlueMaskSize*/ %d,\n", b_size); - printf("/*Bit8u LinBlueFieldPosition*/ %d,\n", b_pos); - printf("/*Bit8u LinRsvdMaskSize*/ %d,\n", a_size); - printf("/*Bit8u LinRsvdFieldPosition*/ %d,\n", a_pos); - printf("/*Bit32u MaxPixelClock*/ %d,\n", 0); - printf("} },\n"); - } - } - printf("{ VBE_VESA_MODE_END_OF_LIST,\n"); - printf("{ 0,\n"); - printf("} },\n"); - printf("};\n"); - return 0; -} diff --git a/roms/vgabios/vgabios.c b/roms/vgabios/vgabios.c deleted file mode 100644 index c1e312b..0000000 --- a/roms/vgabios/vgabios.c +++ /dev/null @@ -1,3923 +0,0 @@ -// ============================================================================================ -/* - * vgabios.c - */ -// ============================================================================================ -// -// Copyright (C) 2001-2008 the LGPL VGABios developers Team -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// ============================================================================================ -// -// This VGA Bios is specific to the plex86/bochs Emulated VGA card. -// You can NOT drive any physical vga card with it. -// -// ============================================================================================ -// -// This file contains code ripped from : -// - rombios.c of plex86 -// -// This VGA Bios contains fonts from : -// - fntcol16.zip (c) by Joseph Gil avalable at : -// ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip -// These fonts are public domain -// -// This VGA Bios is based on information taken from : -// - Kevin Lawton's vga card emulation for bochs/plex86 -// - Ralf Brown's interrupts list available at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html -// - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ -// - Michael Abrash's Graphics Programming Black Book -// - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex -// - DOSEMU 1.0.1 source code for several tables values and formulas -// -// Thanks for patches, comments and ideas to : -// - techt@pikeonline.net -// -// ============================================================================================ - -#include "vgabios.h" - -#ifdef VBE -#include "vbe.h" -#endif - -#define USE_BX_INFO - -/* Declares */ -static Bit8u read_byte(); -static Bit16u read_word(); -static void write_byte(); -static void write_word(); -static Bit8u inb(); -static Bit16u inw(); -static void outb(); -static void outw(); - -static Bit16u get_SS(); - -// Output -static void printf(); -static void unimplemented(); -static void unknown(); - -static Bit8u find_vga_entry(); - -static void memsetb(); -static void memsetw(); -static void memcpyb(); -static void memcpyw(); - -static void biosfn_set_video_mode(); -static void biosfn_set_cursor_shape(); -static void biosfn_set_cursor_pos(); -static void biosfn_get_cursor_pos(); -static void biosfn_set_active_page(); -static void biosfn_scroll(); -static void biosfn_read_char_attr(); -static void biosfn_write_char_attr(); -static void biosfn_write_char_only(); -static void biosfn_write_pixel(); -static void biosfn_read_pixel(); -static void biosfn_write_teletype(); -static void biosfn_perform_gray_scale_summing(); -static void biosfn_load_text_user_pat(); -static void biosfn_load_text_8_14_pat(); -static void biosfn_load_text_8_8_pat(); -static void biosfn_load_text_8_16_pat(); -static void biosfn_load_gfx_8_8_chars(); -static void biosfn_load_gfx_user_chars(); -static void biosfn_load_gfx_8_14_chars(); -static void biosfn_load_gfx_8_8_dd_chars(); -static void biosfn_load_gfx_8_16_chars(); -static void biosfn_get_font_info(); -static void biosfn_alternate_prtsc(); -static void biosfn_switch_video_interface(); -static void biosfn_enable_video_refresh_control(); -static void biosfn_write_string(); -static void biosfn_read_state_info(); -static void biosfn_read_video_state_size(); -static Bit16u biosfn_save_video_state(); -static Bit16u biosfn_restore_video_state(); -extern Bit8u video_save_pointer_table[]; - -// This is for compiling with gcc2 and gcc3 -#define ASM_START #asm -#define ASM_END #endasm - -ASM_START - -MACRO SET_INT_VECTOR - push ds - xor ax, ax - mov ds, ax - mov ax, ?3 - mov ?1*4, ax - mov ax, ?2 - mov ?1*4+2, ax - pop ds -MEND - -ASM_END - -ASM_START -.text -.rom -.org 0 - -use16 386 - -vgabios_start: -.byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */ - -.byte 0x40 /* BIOS extension length in units of 512 bytes */ - - -vgabios_entry_point: - - jmp vgabios_init_func - -#ifdef PCIBIOS -.org 0x18 -.word vgabios_pci_data -#endif - -// Info from Bart Oldeman -.org 0x1e -.ascii "IBM" -.byte 0x00 - -vgabios_name: -.ascii "Plex86/Bochs VGABios" -#ifdef PCIBIOS -.ascii " (PCI)" -#endif -.ascii " " -.byte 0x00 - -vgabios_version: -#ifndef VGABIOS_VERS -.ascii "current-cvs" -#else -.ascii VGABIOS_VERS -#endif -.ascii " " - -vgabios_date: -.ascii VGABIOS_DATE -.byte 0x0a,0x0d -.byte 0x00 - -vgabios_copyright: -.ascii "(C) 2008 the LGPL VGABios developers Team" -.byte 0x0a,0x0d -.byte 0x00 - -vgabios_license: -.ascii "This VGA/VBE Bios is released under the GNU LGPL" -.byte 0x0a,0x0d -.byte 0x0a,0x0d -.byte 0x00 - -vgabios_website: -.ascii "Please visit :" -.byte 0x0a,0x0d -;;.ascii " . http://www.plex86.org" -;;.byte 0x0a,0x0d -.ascii " . http://bochs.sourceforge.net" -.byte 0x0a,0x0d -.ascii " . http://www.nongnu.org/vgabios" -.byte 0x0a,0x0d -.byte 0x0a,0x0d -.byte 0x00 - -#ifdef PCIBIOS -vgabios_pci_data: -.ascii "PCIR" -#ifdef CIRRUS -.word 0x1013 -.word 0x00b8 // CLGD5446 -#else -#ifdef PCI_VID -.word PCI_VID -.word PCI_DID -#else -#error "Unknown PCI vendor and device id" -#endif -#endif -.word 0 // reserved -.word 0x18 // dlen -.byte 0 // revision -.byte 0x0 // class,hi: vga display -.word 0x300 // class,lo: vga display -.word 0x40 // bios size -.word 1 // revision -.byte 0 // intel x86 data -.byte 0x80 // last image -.word 0 // reserved -#endif - - -;; ============================================================================================ -;; -;; Init Entry point -;; -;; ============================================================================================ -vgabios_init_func: - -;; init vga card - call init_vga_card - -;; init basic bios vars - call init_bios_area - -#ifdef VBE -;; init vbe functions - call vbe_init -#endif - -;; set int10 vect - SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler) - -#ifdef CIRRUS - call cirrus_init -#endif - -;; display splash screen - call _display_splash_screen - -;; init video mode and clear the screen - mov ax,#0x0003 - int #0x10 - -;; show info - call _display_info - -#ifdef VBE -;; show vbe info - call vbe_display_info -#endif - -#ifdef CIRRUS -;; show cirrus info - call cirrus_display_info -#endif - - retf -ASM_END - -/* - * int10 handled here - */ -ASM_START -vgabios_int10_handler: - pushf -#ifdef DEBUG - push es - push ds - pusha - mov bx, #0xc000 - mov ds, bx - call _int10_debugmsg - popa - pop ds - pop es -#endif - cmp ah, #0x0f - jne int10_test_1A - call biosfn_get_video_mode - jmp int10_end -int10_test_1A: - cmp ah, #0x1a - jne int10_test_0B - call biosfn_group_1A - jmp int10_end -int10_test_0B: - cmp ah, #0x0b - jne int10_test_1103 - call biosfn_group_0B - jmp int10_end -int10_test_1103: - cmp ax, #0x1103 - jne int10_test_12 - call biosfn_set_text_block_specifier - jmp int10_end -int10_test_12: - cmp ah, #0x12 - jne int10_test_101B - cmp bl, #0x10 - jne int10_test_BL30 - call biosfn_get_ega_info - jmp int10_end -int10_test_BL30: - cmp bl, #0x30 - jne int10_test_BL31 - call biosfn_select_vert_res - jmp int10_end -int10_test_BL31: - cmp bl, #0x31 - jne int10_test_BL32 - call biosfn_enable_default_palette_loading - jmp int10_end -int10_test_BL32: - cmp bl, #0x32 - jne int10_test_BL33 - call biosfn_enable_video_addressing - jmp int10_end -int10_test_BL33: - cmp bl, #0x33 - jne int10_test_BL34 - call biosfn_enable_grayscale_summing - jmp int10_end -int10_test_BL34: - cmp bl, #0x34 - jne int10_normal - call biosfn_enable_cursor_emulation - jmp int10_end -int10_test_101B: - cmp ax, #0x101b - je int10_normal - cmp ah, #0x10 -#ifndef VBE - jne int10_normal -#else - jne int10_test_4F -#endif - call biosfn_group_10 - jmp int10_end -#ifdef VBE -int10_test_4F: - cmp ah, #0x4f - jne int10_normal - cmp al, #0x03 - jne int10_test_vbe_05 - call vbe_biosfn_return_current_mode - jmp int10_end -int10_test_vbe_05: - cmp al, #0x05 - jne int10_test_vbe_06 - call vbe_biosfn_display_window_control - jmp int10_end -int10_test_vbe_06: - cmp al, #0x06 - jne int10_test_vbe_07 - call vbe_biosfn_set_get_logical_scan_line_length - jmp int10_end -int10_test_vbe_07: - cmp al, #0x07 - jne int10_test_vbe_08 - call vbe_biosfn_set_get_display_start - jmp int10_end -int10_test_vbe_08: - cmp al, #0x08 - jne int10_test_vbe_0A - call vbe_biosfn_set_get_dac_palette_format - jmp int10_end -int10_test_vbe_0A: - cmp al, #0x0A - jne int10_normal - call vbe_biosfn_return_protected_mode_interface - jmp int10_end -#endif - -int10_normal: - push es - push ds - pusha - -;; We have to set ds to access the right data segment - mov bx, #0xc000 - mov ds, bx - call _int10_func - - popa - pop ds - pop es -int10_end: - popf - iret -ASM_END - -#include "vgatables.h" -#include "vgafonts.h" - -/* - * Boot time harware inits - */ -ASM_START -init_vga_card: -;; switch to color mode and enable CPU access 480 lines - mov dx, #0x3C2 - mov al, #0xC3 - outb dx,al - -;; more than 64k 3C4/04 - mov dx, #0x3C4 - mov al, #0x04 - outb dx,al - mov dx, #0x3C5 - mov al, #0x02 - outb dx,al - -#if defined(USE_BX_INFO) || defined(DEBUG) - mov bx, #msg_vga_init - push bx - call _printf -#endif - inc sp - inc sp - ret - -#if defined(USE_BX_INFO) || defined(DEBUG) -msg_vga_init: -.ascii "VGABios $Id$" -.byte 0x0d,0x0a,0x00 -#endif -ASM_END - -// -------------------------------------------------------------------------------------------- -/* - * Boot time bios area inits - */ -ASM_START -init_bios_area: - push ds - mov ax, # BIOSMEM_SEG - mov ds, ax - -;; init detected hardware BIOS Area - mov bx, # BIOSMEM_INITIAL_MODE - mov ax, [bx] - and ax, #0xffcf -;; set 80x25 color (not clear from RBIL but usual) - or ax, #0x0020 - mov [bx], ax - -;; Just for the first int10 find its children - -;; the default char height - mov bx, # BIOSMEM_CHAR_HEIGHT - mov al, #0x10 - mov [bx], al - -;; Clear the screen - mov bx, # BIOSMEM_VIDEO_CTL - mov al, #0x60 - mov [bx], al - -;; Set the basic screen we have - mov bx, # BIOSMEM_SWITCHES - mov al, #0xf9 - mov [bx], al - -;; Set the basic modeset options - mov bx, # BIOSMEM_MODESET_CTL - mov al, #0x51 - mov [bx], al - -;; Set the default MSR - mov bx, # BIOSMEM_CURRENT_MSR - mov al, #0x09 - mov [bx], al - - pop ds - ret - -_video_save_pointer_table: - .word _video_param_table - .word 0xc000 - - .word 0 /* XXX: fill it */ - .word 0 - - .word 0 /* XXX: fill it */ - .word 0 - - .word 0 /* XXX: fill it */ - .word 0 - - .word 0 /* XXX: fill it */ - .word 0 - - .word 0 /* XXX: fill it */ - .word 0 - - .word 0 /* XXX: fill it */ - .word 0 - -ASM_END - -// -------------------------------------------------------------------------------------------- -/* - * Boot time Splash screen - */ -static void display_splash_screen() -{ -} - -// -------------------------------------------------------------------------------------------- -/* - * Tell who we are - */ - -static void display_info() -{ -ASM_START - mov ax,#0xc000 - mov ds,ax - mov si,#vgabios_name - call _display_string - mov si,#vgabios_version - call _display_string - - ;;mov si,#vgabios_copyright - ;;call _display_string - ;;mov si,#crlf - ;;call _display_string - - mov si,#vgabios_license - call _display_string - mov si,#vgabios_website - call _display_string -ASM_END -} - -static void display_string() -{ - // Get length of string -ASM_START - mov ax,ds - mov es,ax - mov di,si - xor cx,cx - not cx - xor al,al - cld - repne - scasb - not cx - dec cx - push cx - - mov ax,#0x0300 - mov bx,#0x0000 - int #0x10 - - pop cx - mov ax,#0x1301 - mov bx,#0x000b - mov bp,si - int #0x10 -ASM_END -} - -// -------------------------------------------------------------------------------------------- -#ifdef DEBUG -static void int10_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) - Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; -{ - // 0E is write char... - if(GET_AH()!=0x0E) - printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); -} -#endif - -// -------------------------------------------------------------------------------------------- -/* - * int10 main dispatcher - */ -static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) - Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; -{ - - // BIOS functions - switch(GET_AH()) - { - case 0x00: - biosfn_set_video_mode(GET_AL()); - switch(GET_AL()&0x7F) - {case 6: - SET_AL(0x3F); - break; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 7: - SET_AL(0x30); - break; - default: - SET_AL(0x20); - } - break; - case 0x01: - biosfn_set_cursor_shape(GET_CH(),GET_CL()); - break; - case 0x02: - biosfn_set_cursor_pos(GET_BH(),DX); - break; - case 0x03: - biosfn_get_cursor_pos(GET_BH(),&CX,&DX); - break; - case 0x04: - // Read light pen pos (unimplemented) -#ifdef DEBUG - unimplemented(); -#endif - AX=0x00; - BX=0x00; - CX=0x00; - DX=0x00; - break; - case 0x05: - biosfn_set_active_page(GET_AL()); - break; - case 0x06: - biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP); - break; - case 0x07: - biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN); - break; - case 0x08: - biosfn_read_char_attr(GET_BH(),&AX); - break; - case 0x09: - biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX); - break; - case 0x0A: - biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX); - break; - case 0x0C: - biosfn_write_pixel(GET_BH(),GET_AL(),CX,DX); - break; - case 0x0D: - biosfn_read_pixel(GET_BH(),CX,DX,&AX); - break; - case 0x0E: - // Ralf Brown Interrupt list is WRONG on bh(page) - // We do output only on the current page ! - biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR); - break; - case 0x10: - // All other functions of group AH=0x10 rewritten in assembler - biosfn_perform_gray_scale_summing(BX,CX); - break; - case 0x11: - switch(GET_AL()) - { - case 0x00: - case 0x10: - biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH()); - break; - case 0x01: - case 0x11: - biosfn_load_text_8_14_pat(GET_AL(),GET_BL()); - break; - case 0x02: - case 0x12: - biosfn_load_text_8_8_pat(GET_AL(),GET_BL()); - break; - case 0x04: - case 0x14: - biosfn_load_text_8_16_pat(GET_AL(),GET_BL()); - break; - case 0x20: - biosfn_load_gfx_8_8_chars(ES,BP); - break; - case 0x21: - biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL()); - break; - case 0x22: - biosfn_load_gfx_8_14_chars(GET_BL()); - break; - case 0x23: - biosfn_load_gfx_8_8_dd_chars(GET_BL()); - break; - case 0x24: - biosfn_load_gfx_8_16_chars(GET_BL()); - break; - case 0x30: - biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX); - break; -#ifdef DEBUG - default: - unknown(); -#endif - } - - break; - case 0x12: - switch(GET_BL()) - { - case 0x20: - biosfn_alternate_prtsc(); - break; - case 0x35: - biosfn_switch_video_interface(GET_AL(),ES,DX); - SET_AL(0x12); - break; - case 0x36: - biosfn_enable_video_refresh_control(GET_AL()); - SET_AL(0x12); - break; -#ifdef DEBUG - default: - unknown(); -#endif - } - break; - case 0x13: - biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP); - break; - case 0x1B: - biosfn_read_state_info(BX,ES,DI); - SET_AL(0x1B); - break; - case 0x1C: - switch(GET_AL()) - { - case 0x00: - biosfn_read_video_state_size(CX,&BX); - break; - case 0x01: - biosfn_save_video_state(CX,ES,BX); - break; - case 0x02: - biosfn_restore_video_state(CX,ES,BX); - break; -#ifdef DEBUG - default: - unknown(); -#endif - } - SET_AL(0x1C); - break; - -#ifdef VBE - case 0x4f: - if (vbe_has_vbe_display()) { - switch(GET_AL()) - { - case 0x00: - vbe_biosfn_return_controller_information(&AX,ES,DI); - break; - case 0x01: - vbe_biosfn_return_mode_information(&AX,CX,ES,DI); - break; - case 0x02: - vbe_biosfn_set_mode(&AX,BX,ES,DI); - break; - case 0x04: - vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX); - break; - case 0x09: - //FIXME -#ifdef DEBUG - unimplemented(); -#endif - // function failed - AX=0x100; - break; - case 0x0A: - //FIXME -#ifdef DEBUG - unimplemented(); -#endif - // function failed - AX=0x100; - break; - default: -#ifdef DEBUG - unknown(); -#endif - // function failed - AX=0x100; - } - } - else { - // No VBE display - AX=0x0100; - } - break; -#endif - -#ifdef DEBUG - default: - unknown(); -#endif - } -} - -// ============================================================================================ -// -// BIOS functions -// -// ============================================================================================ - -static void biosfn_set_video_mode(mode) Bit8u mode; -{// mode: Bit 7 is 1 if no clear screen - - // Should we clear the screen ? - Bit8u noclearmem=mode&0x80; - Bit8u line,mmask,*palette,vpti; - Bit16u i,twidth,theightm1,cheight; - Bit8u modeset_ctl,video_ctl,vga_switches; - Bit16u crtc_addr; - -#ifdef VBE - if (vbe_has_vbe_display()) { - dispi_set_enable(VBE_DISPI_DISABLED); - } -#endif // def VBE - - // The real mode - mode=mode&0x7f; - - // find the entry in the video modes - line=find_vga_entry(mode); - -#ifdef DEBUG - printf("mode search %02x found line %02x\n",mode,line); -#endif - - if(line==0xFF) - return; - - vpti=line_to_vpti[line]; - twidth=video_param_table[vpti].twidth; - theightm1=video_param_table[vpti].theightm1; - cheight=video_param_table[vpti].cheight; - - // Read the bios vga control - video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); - - // Read the bios vga switches - vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES); - - // Read the bios mode set control - modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); - - // Then we know the number of lines -// FIXME - - // if palette loading (bit 3 of modeset ctl = 0) - if((modeset_ctl&0x08)==0) - {// Set the PEL mask - outb(VGAREG_PEL_MASK,vga_modes[line].pelmask); - - // Set the whole dac always, from 0 - outb(VGAREG_DAC_WRITE_ADDRESS,0x00); - - // From which palette - switch(vga_modes[line].dacmodel) - {case 0: - palette=&palette0; - break; - case 1: - palette=&palette1; - break; - case 2: - palette=&palette2; - break; - case 3: - palette=&palette3; - break; - } - // Always 256*3 values - for(i=0;i<0x0100;i++) - {if(i<=dac_regs[vga_modes[line].dacmodel]) - {outb(VGAREG_DAC_DATA,palette[(i*3)+0]); - outb(VGAREG_DAC_DATA,palette[(i*3)+1]); - outb(VGAREG_DAC_DATA,palette[(i*3)+2]); - } - else - {outb(VGAREG_DAC_DATA,0); - outb(VGAREG_DAC_DATA,0); - outb(VGAREG_DAC_DATA,0); - } - } - if((modeset_ctl&0x02)==0x02) - { - biosfn_perform_gray_scale_summing(0x00, 0x100); - } - } - - // Reset Attribute Ctl flip-flop - inb(VGAREG_ACTL_RESET); - - // Set Attribute Ctl - for(i=0;i<=0x13;i++) - {outb(VGAREG_ACTL_ADDRESS,i); - outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]); - } - outb(VGAREG_ACTL_ADDRESS,0x14); - outb(VGAREG_ACTL_WRITE_DATA,0x00); - - // Set Sequencer Ctl - outb(VGAREG_SEQU_ADDRESS,0); - outb(VGAREG_SEQU_DATA,0x03); - for(i=1;i<=4;i++) - {outb(VGAREG_SEQU_ADDRESS,i); - outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]); - } - - // Set Grafx Ctl - for(i=0;i<=8;i++) - {outb(VGAREG_GRDC_ADDRESS,i); - outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]); - } - - // Set CRTC address VGA or MDA - crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; - - // Disable CRTC write protection - outw(crtc_addr,0x0011); - // Set CRTC regs - for(i=0;i<=0x18;i++) - {outb(crtc_addr,i); - outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]); - } - - // Set the misc register - outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg); - - // Enable video - outb(VGAREG_ACTL_ADDRESS,0x20); - inb(VGAREG_ACTL_RESET); - - if(noclearmem==0x00) - { - if(vga_modes[line].class==TEXT) - { - memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k - } - else - { - if(mode<0x0d) - { - memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k - } - else - { - outb( VGAREG_SEQU_ADDRESS, 0x02 ); - mmask = inb( VGAREG_SEQU_DATA ); - outb( VGAREG_SEQU_DATA, 0x0f ); // all planes - memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k - outb( VGAREG_SEQU_DATA, mmask ); - } - } - } - - // Set the BIOS mem - write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); - write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); - write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l); - write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); - write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1); - write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); - write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem)); - write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); - write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); - - // FIXME We nearly have the good tables. to be reworked - write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now - write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table); - write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000); - - // FIXME - write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... - write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... - - // Set cursor shape - if(vga_modes[line].class==TEXT) - { - biosfn_set_cursor_shape(0x06,0x07); - } - - // Set cursor pos for page 0..7 - for(i=0;i<8;i++) - biosfn_set_cursor_pos(i,0x0000); - - // Set active page 0 - biosfn_set_active_page(0x00); - - // Write the fonts in memory - if(vga_modes[line].class==TEXT) - { -ASM_START - ;; copy and activate 8x16 font - mov ax, #0x1104 - mov bl, #0x00 - int #0x10 - mov ax, #0x1103 - mov bl, #0x00 - int #0x10 -ASM_END - } - - // Set the ints 0x1F and 0x43 -ASM_START - SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8) -ASM_END - - switch(cheight) - {case 8: -ASM_START - SET_INT_VECTOR(0x43, #0xC000, #_vgafont8) -ASM_END - break; - case 14: -ASM_START - SET_INT_VECTOR(0x43, #0xC000, #_vgafont14) -ASM_END - break; - case 16: -ASM_START - SET_INT_VECTOR(0x43, #0xC000, #_vgafont16) -ASM_END - break; - } -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_set_cursor_shape (CH,CL) -Bit8u CH;Bit8u CL; -{Bit16u cheight,curs,crtc_addr; - Bit8u modeset_ctl; - - CH&=0x3f; - CL&=0x1f; - - curs=(CH<<8)+CL; - write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs); - - modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); - cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); - if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20)) - { - if(CL!=(CH+1)) - { - CH = ((CH+1) * cheight / 8) -1; - } - else - { - CH = ((CL+1) * cheight / 8) - 2; - } - CL = ((CL+1) * cheight / 8) - 1; - } - - // CTRC regs 0x0a and 0x0b - crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); - outb(crtc_addr,0x0a); - outb(crtc_addr+1,CH); - outb(crtc_addr,0x0b); - outb(crtc_addr+1,CL); -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_set_cursor_pos (page, cursor) -Bit8u page;Bit16u cursor; -{ - Bit8u xcurs,ycurs,current; - Bit16u nbcols,nbrows,address,crtc_addr; - - // Should not happen... - if(page>7)return; - - // Bios cursor pos - write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor); - - // Set the hardware cursor - current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - if(page==current) - { - // Get the dimensions - nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; - - xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; - - // Calculate the address knowing nbcols nbrows and page num - address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols; - - // CRTC regs 0x0e and 0x0f - crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); - outb(crtc_addr,0x0e); - outb(crtc_addr+1,(address&0xff00)>>8); - outb(crtc_addr,0x0f); - outb(crtc_addr+1,address&0x00ff); - } -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_get_cursor_pos (page,shape, pos) -Bit8u page;Bit16u *shape;Bit16u *pos; -{ - Bit16u ss=get_SS(); - - // Default - write_word(ss, shape, 0); - write_word(ss, pos, 0); - - if(page>7)return; - // FIXME should handle VGA 14/16 lines - write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); - write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2)); -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_set_active_page (page) -Bit8u page; -{ - Bit16u cursor,dummy,crtc_addr; - Bit16u nbcols,nbrows,address; - Bit8u mode,line; - - if(page>7)return; - - // Get the mode - mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); - line=find_vga_entry(mode); - if(line==0xFF)return; - - // Get pos curs pos for the right page - biosfn_get_cursor_pos(page,&dummy,&cursor); - - if(vga_modes[line].class==TEXT) - { - // Get the dimensions - nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; - - // Calculate the address knowing nbcols nbrows and page num - address=SCREEN_MEM_START(nbcols,nbrows,page); - write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START,address); - - // Start address - address=SCREEN_IO_START(nbcols,nbrows,page); - } - else - { - address = page * (*(Bit16u *)&video_param_table[line_to_vpti[line]].slength_l); - } - - // CRTC regs 0x0c and 0x0d - crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); - outb(crtc_addr,0x0c); - outb(crtc_addr+1,(address&0xff00)>>8); - outb(crtc_addr,0x0d); - outb(crtc_addr+1,address&0x00ff); - - // And change the BIOS page - write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); - -#ifdef DEBUG - printf("Set active page %02x address %04x\n",page,address); -#endif - - // Display the cursor, now the page is active - biosfn_set_cursor_pos(page,cursor); -} - -// -------------------------------------------------------------------------------------------- -static void vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight) -Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight; -{ - Bit16u src,dest; - Bit8u i; - - src=ysrc*cheight*nbcols+xstart; - dest=ydest*cheight*nbcols+xstart; - outw(VGAREG_GRDC_ADDRESS, 0x0105); - for(i=0;i>1)+xstart; - dest=((ydest*cheight*nbcols)>>1)+xstart; - for(i=0;i>1)*nbcols,0xb800,0x2000+src+(i>>1)*nbcols,cols); - else - memcpyb(0xb800,dest+(i>>1)*nbcols,0xb800,src+(i>>1)*nbcols,cols); - } -} - -// -------------------------------------------------------------------------------------------- -static void vgamem_fill_cga(xstart,ystart,cols,nbcols,cheight,attr) -Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr; -{ - Bit16u dest; - Bit8u i; - - dest=((ystart*cheight*nbcols)>>1)+xstart; - for(i=0;i>1)*nbcols,attr,cols); - else - memsetb(0xb800,dest+(i>>1)*nbcols,attr,cols); - } -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir) -Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir; -{ - // page == 0xFF if current - - Bit8u mode,line,cheight,bpp,cols; - Bit16u nbcols,nbrows,i; - Bit16u address; - - if(rul>rlr)return; - if(cul>clr)return; - - // Get the mode - mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); - line=find_vga_entry(mode); - if(line==0xFF)return; - - // Get the dimensions - nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; - nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - - // Get the current page - if(page==0xFF) - page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - - if(rlr>=nbrows)rlr=nbrows-1; - if(clr>=nbcols)clr=nbcols-1; - if(nblines>nbrows)nblines=0; - cols=clr-cul+1; - - if(vga_modes[line].class==TEXT) - { - // Compute the address - address=SCREEN_MEM_START(nbcols,nbrows,page); -#ifdef DEBUG - printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page); -#endif - - if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) - { - memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols); - } - else - {// if Scroll up - if(dir==SCROLL_UP) - {for(i=rul;i<=rlr;i++) - { - if((i+nblines>rlr)||(nblines==0)) - memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols); - else - memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols); - } - } - else - {for(i=rlr;i>=rul;i--) - { - if((irlr) break; - } - } - } - } - else - { - // FIXME gfx mode not complete - cheight=video_param_table[line_to_vpti[line]].cheight; - switch(vga_modes[line].memmodel) - { - case PLANAR4: - case PLANAR1: - if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) - { - outw(VGAREG_GRDC_ADDRESS, 0x0205); - memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight); - outw(VGAREG_GRDC_ADDRESS, 0x0005); - } - else - {// if Scroll up - if(dir==SCROLL_UP) - {for(i=rul;i<=rlr;i++) - { - if((i+nblines>rlr)||(nblines==0)) - vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr); - else - vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight); - } - } - else - {for(i=rlr;i>=rul;i--) - { - if((irlr) break; - } - } - } - break; - case CGA: - bpp=vga_modes[line].pixbits; - if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) - { - memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight*bpp); - } - else - { - if(bpp==2) - { - cul<<=1; - cols<<=1; - nbcols<<=1; - } - // if Scroll up - if(dir==SCROLL_UP) - {for(i=rul;i<=rlr;i++) - { - if((i+nblines>rlr)||(nblines==0)) - vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr); - else - vgamem_copy_cga(cul,i+nblines,i,cols,nbcols,cheight); - } - } - else - {for(i=rlr;i>=rul;i--) - { - if((irlr) break; - } - } - } - break; -#ifdef DEBUG - default: - printf("Scroll in graphics mode "); - unimplemented(); -#endif - } - } -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_read_char_attr (page,car) -Bit8u page;Bit16u *car; -{Bit16u ss=get_SS(); - Bit8u xcurs,ycurs,mode,line; - Bit16u nbcols,nbrows,address; - Bit16u cursor,dummy; - - // Get the mode - mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); - line=find_vga_entry(mode); - if(line==0xFF)return; - - // Get the cursor pos for the page - biosfn_get_cursor_pos(page,&dummy,&cursor); - xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; - - // Get the dimensions - nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; - nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - - if(vga_modes[line].class==TEXT) - { - // Compute the address - address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; - - write_word(ss,car,read_word(vga_modes[line].sstart,address)); - } - else - { - // FIXME gfx mode -#ifdef DEBUG - unimplemented(); -#endif - } -} - -// -------------------------------------------------------------------------------------------- -static void write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight) -Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u cheight; -{ - Bit8u i,j,mask; - Bit8u *fdata; - Bit16u addr,dest,src; - - switch(cheight) - {case 14: - fdata = &vgafont14; - break; - case 16: - fdata = &vgafont16; - break; - default: - fdata = &vgafont8; - } - addr=xcurs+ycurs*cheight*nbcols; - src = car * cheight; - outw(VGAREG_SEQU_ADDRESS, 0x0f02); - outw(VGAREG_GRDC_ADDRESS, 0x0205); - if(attr&0x80) - { - outw(VGAREG_GRDC_ADDRESS, 0x1803); - } - else - { - outw(VGAREG_GRDC_ADDRESS, 0x0003); - } - for(i=0;i>j; - outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); - read_byte(0xa000,dest); - if(fdata[src+i]&mask) - { - write_byte(0xa000,dest,attr&0x0f); - } - else - { - write_byte(0xa000,dest,0x00); - } - } - } -ASM_START - mov dx, # VGAREG_GRDC_ADDRESS - mov ax, #0xff08 - out dx, ax - mov ax, #0x0005 - out dx, ax - mov ax, #0x0003 - out dx, ax -ASM_END -} - -// -------------------------------------------------------------------------------------------- -static void write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp) -Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u bpp; -{ - Bit8u i,j,mask,data; - Bit8u *fdata; - Bit16u addr,dest,src; - - fdata = &vgafont8; - addr=(xcurs*bpp)+ycurs*320; - src = car * 8; - for(i=0;i<8;i++) - { - dest=addr+(i>>1)*80; - if (i & 1) dest += 0x2000; - mask = 0x80; - if (bpp == 1) - { - if (attr & 0x80) - { - data = read_byte(0xb800,dest); - } - else - { - data = 0x00; - } - for(j=0;j<8;j++) - { - if (fdata[src+i] & mask) - { - if (attr & 0x80) - { - data ^= (attr & 0x01) << (7-j); - } - else - { - data |= (attr & 0x01) << (7-j); - } - } - mask >>= 1; - } - write_byte(0xb800,dest,data); - } - else - { - while (mask > 0) - { - if (attr & 0x80) - { - data = read_byte(0xb800,dest); - } - else - { - data = 0x00; - } - for(j=0;j<4;j++) - { - if (fdata[src+i] & mask) - { - if (attr & 0x80) - { - data ^= (attr & 0x03) << ((3-j)*2); - } - else - { - data |= (attr & 0x03) << ((3-j)*2); - } - } - mask >>= 1; - } - write_byte(0xb800,dest,data); - dest += 1; - } - } - } -} - -// -------------------------------------------------------------------------------------------- -static void write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols) -Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols; -{ - Bit8u i,j,mask,data; - Bit8u *fdata; - Bit16u addr,dest,src; - - fdata = &vgafont8; - addr=xcurs*8+ycurs*nbcols*64; - src = car * 8; - for(i=0;i<8;i++) - { - dest=addr+i*nbcols*8; - mask = 0x80; - for(j=0;j<8;j++) - { - data = 0x00; - if (fdata[src+i] & mask) - { - data = attr; - } - write_byte(0xa000,dest+j,data); - mask >>= 1; - } - } -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_write_char_attr (car,page,attr,count) -Bit8u car;Bit8u page;Bit8u attr;Bit16u count; -{ - Bit8u cheight,xcurs,ycurs,mode,line,bpp; - Bit16u nbcols,nbrows,address; - Bit16u cursor,dummy; - - // Get the mode - mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); - line=find_vga_entry(mode); - if(line==0xFF)return; - - // Get the cursor pos for the page - biosfn_get_cursor_pos(page,&dummy,&cursor); - xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; - - // Get the dimensions - nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; - nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - - if(vga_modes[line].class==TEXT) - { - // Compute the address - address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; - - dummy=((Bit16u)attr<<8)+car; - memsetw(vga_modes[line].sstart,address,dummy,count); - } - else - { - // FIXME gfx mode not complete - cheight=video_param_table[line_to_vpti[line]].cheight; - bpp=vga_modes[line].pixbits; - while((count-->0) && (xcurs>8; - - // Get the dimensions - nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; - nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - - if(vga_modes[line].class==TEXT) - { - // Compute the address - address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; - - while(count-->0) - {write_byte(vga_modes[line].sstart,address,car); - address+=2; - } - } - else - { - // FIXME gfx mode not complete - cheight=video_param_table[line_to_vpti[line]].cheight; - bpp=vga_modes[line].pixbits; - while((count-->0) && (xcurs> (CX & 0x07); - outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); - outw(VGAREG_GRDC_ADDRESS, 0x0205); - data = read_byte(0xa000,addr); - if (AL & 0x80) - { - outw(VGAREG_GRDC_ADDRESS, 0x1803); - } - write_byte(0xa000,addr,AL); -ASM_START - mov dx, # VGAREG_GRDC_ADDRESS - mov ax, #0xff08 - out dx, ax - mov ax, #0x0005 - out dx, ax - mov ax, #0x0003 - out dx, ax -ASM_END - break; - case CGA: - if(vga_modes[line].pixbits==2) - { - addr=(CX>>2)+(DX>>1)*80; - } - else - { - addr=(CX>>3)+(DX>>1)*80; - } - if (DX & 1) addr += 0x2000; - data = read_byte(0xb800,addr); - if(vga_modes[line].pixbits==2) - { - attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2); - mask = 0x03 << ((3 - (CX & 0x03)) * 2); - } - else - { - attr = (AL & 0x01) << (7 - (CX & 0x07)); - mask = 0x01 << (7 - (CX & 0x07)); - } - if (AL & 0x80) - { - data ^= attr; - } - else - { - data &= ~mask; - data |= attr; - } - write_byte(0xb800,addr,data); - break; - case LINEAR8: - addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); - write_byte(0xa000,addr,AL); - break; -#ifdef DEBUG - default: - unimplemented(); -#endif - } -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_read_pixel (BH,CX,DX,AX) Bit8u BH;Bit16u CX;Bit16u DX;Bit16u *AX; -{ - Bit8u mode,line,mask,attr,data,i; - Bit16u addr; - Bit16u ss=get_SS(); - - // Get the mode - mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); - line=find_vga_entry(mode); - if(line==0xFF)return; - if(vga_modes[line].class==TEXT)return; - - switch(vga_modes[line].memmodel) - { - case PLANAR4: - case PLANAR1: - addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - mask = 0x80 >> (CX & 0x07); - attr = 0x00; - for(i=0;i<4;i++) - { - outw(VGAREG_GRDC_ADDRESS, (i << 8) | 0x04); - data = read_byte(0xa000,addr) & mask; - if (data > 0) attr |= (0x01 << i); - } - break; - case CGA: - addr=(CX>>2)+(DX>>1)*80; - if (DX & 1) addr += 0x2000; - data = read_byte(0xb800,addr); - if(vga_modes[line].pixbits==2) - { - attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03; - } - else - { - attr = (data >> (7 - (CX & 0x07))) & 0x01; - } - break; - case LINEAR8: - addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); - attr=read_byte(0xa000,addr); - break; - default: -#ifdef DEBUG - unimplemented(); -#endif - attr = 0; - } - write_word(ss,AX,(read_word(ss,AX) & 0xff00) | attr); -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_write_teletype (car, page, attr, flag) -Bit8u car;Bit8u page;Bit8u attr;Bit8u flag; -{// flag = WITH_ATTR / NO_ATTR - - Bit8u cheight,xcurs,ycurs,mode,line,bpp; - Bit16u nbcols,nbrows,address; - Bit16u cursor,dummy; - - // special case if page is 0xff, use current page - if(page==0xff) - page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); - - // Get the mode - mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); - line=find_vga_entry(mode); - if(line==0xFF)return; - - // Get the cursor pos for the page - biosfn_get_cursor_pos(page,&dummy,&cursor); - xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; - - // Get the dimensions - nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; - nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - - switch(car) - { - case 7: - //FIXME should beep - break; - - case 8: - if(xcurs>0)xcurs--; - break; - - case '\r': - xcurs=0; - break; - - case '\n': - ycurs++; - break; - - case '\t': - do - { - biosfn_write_teletype(' ',page,attr,flag); - biosfn_get_cursor_pos(page,&dummy,&cursor); - xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; - }while(xcurs%8==0); - break; - - default: - - if(vga_modes[line].class==TEXT) - { - // Compute the address - address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; - - // Write the char - write_byte(vga_modes[line].sstart,address,car); - - if(flag==WITH_ATTR) - write_byte(vga_modes[line].sstart,address+1,attr); - } - else - { - // FIXME gfx mode not complete - cheight=video_param_table[line_to_vpti[line]].cheight; - bpp=vga_modes[line].pixbits; - switch(vga_modes[line].memmodel) - { - case PLANAR4: - case PLANAR1: - write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); - break; - case CGA: - write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); - break; - case LINEAR8: - write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); - break; -#ifdef DEBUG - default: - unimplemented(); -#endif - } - } - xcurs++; - } - - // Do we need to wrap ? - if(xcurs==nbcols) - {xcurs=0; - ycurs++; - } - - // Do we need to scroll ? - if(ycurs==nbrows) - { - if(vga_modes[line].class==TEXT) - { - address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+(ycurs-1)*nbcols)*2; - attr=read_byte(vga_modes[line].sstart,address+1); - biosfn_scroll(0x01,attr,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); - } - else - { - biosfn_scroll(0x01,0x00,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); - } - ycurs-=1; - } - - // Set the cursor for the page - cursor=ycurs; cursor<<=8; cursor+=xcurs; - biosfn_set_cursor_pos(page,cursor); -} - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_get_video_mode: - push ds - mov ax, # BIOSMEM_SEG - mov ds, ax - push bx - mov bx, # BIOSMEM_CURRENT_PAGE - mov al, [bx] - pop bx - mov bh, al - push bx - mov bx, # BIOSMEM_VIDEO_CTL - mov ah, [bx] - and ah, #0x80 - mov bx, # BIOSMEM_CURRENT_MODE - mov al, [bx] - or al, ah - mov bx, # BIOSMEM_NB_COLS - mov ah, [bx] - pop bx - pop ds - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_group_10: - cmp al, #0x00 - jne int10_test_1001 - jmp biosfn_set_single_palette_reg -int10_test_1001: - cmp al, #0x01 - jne int10_test_1002 - jmp biosfn_set_overscan_border_color -int10_test_1002: - cmp al, #0x02 - jne int10_test_1003 - jmp biosfn_set_all_palette_reg -int10_test_1003: - cmp al, #0x03 - jne int10_test_1007 - jmp biosfn_toggle_intensity -int10_test_1007: - cmp al, #0x07 - jne int10_test_1008 - jmp biosfn_get_single_palette_reg -int10_test_1008: - cmp al, #0x08 - jne int10_test_1009 - jmp biosfn_read_overscan_border_color -int10_test_1009: - cmp al, #0x09 - jne int10_test_1010 - jmp biosfn_get_all_palette_reg -int10_test_1010: - cmp al, #0x10 - jne int10_test_1012 - jmp biosfn_set_single_dac_reg -int10_test_1012: - cmp al, #0x12 - jne int10_test_1013 - jmp biosfn_set_all_dac_reg -int10_test_1013: - cmp al, #0x13 - jne int10_test_1015 - jmp biosfn_select_video_dac_color_page -int10_test_1015: - cmp al, #0x15 - jne int10_test_1017 - jmp biosfn_read_single_dac_reg -int10_test_1017: - cmp al, #0x17 - jne int10_test_1018 - jmp biosfn_read_all_dac_reg -int10_test_1018: - cmp al, #0x18 - jne int10_test_1019 - jmp biosfn_set_pel_mask -int10_test_1019: - cmp al, #0x19 - jne int10_test_101A - jmp biosfn_read_pel_mask -int10_test_101A: - cmp al, #0x1a - jne int10_group_10_unknown - jmp biosfn_read_video_dac_state -int10_group_10_unknown: -#ifdef DEBUG - call _unknown -#endif - ret - -biosfn_set_single_palette_reg: - cmp bl, #0x14 - ja no_actl_reg1 - push ax - push dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, bl - out dx, al - mov al, bh - out dx, al - mov al, #0x20 - out dx, al - pop dx - pop ax -no_actl_reg1: - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_set_overscan_border_color: - push bx - mov bl, #0x11 - call biosfn_set_single_palette_reg - pop bx - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_set_all_palette_reg: - push ax - push bx - push cx - push dx - mov bx, dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov cl, #0x00 - mov dx, # VGAREG_ACTL_ADDRESS -set_palette_loop: - mov al, cl - out dx, al - seg es - mov al, [bx] - out dx, al - inc bx - inc cl - cmp cl, #0x10 - jne set_palette_loop - mov al, #0x11 - out dx, al - seg es - mov al, [bx] - out dx, al - mov al, #0x20 - out dx, al - pop dx - pop cx - pop bx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_toggle_intensity: - push ax - push bx - push dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x10 - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - and al, #0xf7 - and bl, #0x01 - shl bl, 3 - or al, bl - mov dx, # VGAREG_ACTL_ADDRESS - out dx, al - mov al, #0x20 - out dx, al - pop dx - pop bx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_get_single_palette_reg: - cmp bl, #0x14 - ja no_actl_reg2 - push ax - push dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, bl - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - mov bh, al - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x20 - out dx, al - pop dx - pop ax -no_actl_reg2: - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_read_overscan_border_color: - push ax - push bx - mov bl, #0x11 - call biosfn_get_single_palette_reg - mov al, bh - pop bx - mov bh, al - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_get_all_palette_reg: - push ax - push bx - push cx - push dx - mov bx, dx - mov cl, #0x00 -get_palette_loop: - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, cl - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - seg es - mov [bx], al - inc bx - inc cl - cmp cl, #0x10 - jne get_palette_loop - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x11 - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - seg es - mov [bx], al - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x20 - out dx, al - pop dx - pop cx - pop bx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_set_single_dac_reg: - push ax - push dx - mov dx, # VGAREG_DAC_WRITE_ADDRESS - mov al, bl - out dx, al - mov dx, # VGAREG_DAC_DATA - pop ax - push ax - mov al, ah - out dx, al - mov al, ch - out dx, al - mov al, cl - out dx, al - pop dx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_set_all_dac_reg: - push ax - push bx - push cx - push dx - mov dx, # VGAREG_DAC_WRITE_ADDRESS - mov al, bl - out dx, al - pop dx - push dx - mov bx, dx - mov dx, # VGAREG_DAC_DATA -set_dac_loop: - seg es - mov al, [bx] - out dx, al - inc bx - seg es - mov al, [bx] - out dx, al - inc bx - seg es - mov al, [bx] - out dx, al - inc bx - dec cx - jnz set_dac_loop - pop dx - pop cx - pop bx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_select_video_dac_color_page: - push ax - push bx - push dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x10 - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - and bl, #0x01 - jnz set_dac_page - and al, #0x7f - shl bh, 7 - or al, bh - mov dx, # VGAREG_ACTL_ADDRESS - out dx, al - jmp set_actl_normal -set_dac_page: - push ax - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x14 - out dx, al - pop ax - and al, #0x80 - jnz set_dac_16_page - shl bh, 2 -set_dac_16_page: - and bh, #0x0f - mov al, bh - out dx, al -set_actl_normal: - mov al, #0x20 - out dx, al - pop dx - pop bx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_read_single_dac_reg: - push ax - push dx - mov dx, # VGAREG_DAC_READ_ADDRESS - mov al, bl - out dx, al - pop ax - mov ah, al - mov dx, # VGAREG_DAC_DATA - in al, dx - xchg al, ah - push ax - in al, dx - mov ch, al - in al, dx - mov cl, al - pop dx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_read_all_dac_reg: - push ax - push bx - push cx - push dx - mov dx, # VGAREG_DAC_READ_ADDRESS - mov al, bl - out dx, al - pop dx - push dx - mov bx, dx - mov dx, # VGAREG_DAC_DATA -read_dac_loop: - in al, dx - seg es - mov [bx], al - inc bx - in al, dx - seg es - mov [bx], al - inc bx - in al, dx - seg es - mov [bx], al - inc bx - dec cx - jnz read_dac_loop - pop dx - pop cx - pop bx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_set_pel_mask: - push ax - push dx - mov dx, # VGAREG_PEL_MASK - mov al, bl - out dx, al - pop dx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_read_pel_mask: - push ax - push dx - mov dx, # VGAREG_PEL_MASK - in al, dx - mov bl, al - pop dx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_read_video_dac_state: - push ax - push dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x10 - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - mov bl, al - shr bl, 7 - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x14 - out dx, al - mov dx, # VGAREG_ACTL_READ_DATA - in al, dx - mov bh, al - and bh, #0x0f - test bl, #0x01 - jnz get_dac_16_page - shr bh, 2 -get_dac_16_page: - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x20 - out dx, al - pop dx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -static void biosfn_perform_gray_scale_summing (start,count) -Bit16u start;Bit16u count; -{Bit8u r,g,b; - Bit16u i; - Bit16u index; - - inb(VGAREG_ACTL_RESET); - outb(VGAREG_ACTL_ADDRESS,0x00); - - for( index = 0; index < count; index++ ) - { - // set read address and switch to read mode - outb(VGAREG_DAC_READ_ADDRESS,start); - // get 6-bit wide RGB data values - r=inb( VGAREG_DAC_DATA ); - g=inb( VGAREG_DAC_DATA ); - b=inb( VGAREG_DAC_DATA ); - - // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue ) - i = ( ( 77*r + 151*g + 28*b ) + 0x80 ) >> 8; - - if(i>0x3f)i=0x3f; - - // set write address and switch to write mode - outb(VGAREG_DAC_WRITE_ADDRESS,start); - // write new intensity value - outb( VGAREG_DAC_DATA, i&0xff ); - outb( VGAREG_DAC_DATA, i&0xff ); - outb( VGAREG_DAC_DATA, i&0xff ); - start++; - } - inb(VGAREG_ACTL_RESET); - outb(VGAREG_ACTL_ADDRESS,0x20); -} - -// -------------------------------------------------------------------------------------------- -static void get_font_access() -{ -ASM_START - mov dx, # VGAREG_SEQU_ADDRESS - mov ax, #0x0100 - out dx, ax - mov ax, #0x0402 - out dx, ax - mov ax, #0x0704 - out dx, ax - mov ax, #0x0300 - out dx, ax - mov dx, # VGAREG_GRDC_ADDRESS - mov ax, #0x0204 - out dx, ax - mov ax, #0x0005 - out dx, ax - mov ax, #0x0406 - out dx, ax -ASM_END -} - -static void release_font_access() -{ -ASM_START - mov dx, # VGAREG_SEQU_ADDRESS - mov ax, #0x0100 - out dx, ax - mov ax, #0x0302 - out dx, ax - mov ax, #0x0304 - out dx, ax - mov ax, #0x0300 - out dx, ax - mov dx, # VGAREG_READ_MISC_OUTPUT - in al, dx - and al, #0x01 - shl al, 2 - or al, #0x0a - mov ah, al - mov al, #0x06 - mov dx, # VGAREG_GRDC_ADDRESS - out dx, ax - mov ax, #0x0004 - out dx, ax - mov ax, #0x1005 - out dx, ax -ASM_END -} - -ASM_START -idiv_u: - xor dx,dx - div bx - ret -ASM_END - -static void set_scan_lines(lines) Bit8u lines; -{ - Bit16u crtc_addr,cols,page,vde; - Bit8u crtc_r9,ovl,rows; - - crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); - outb(crtc_addr, 0x09); - crtc_r9 = inb(crtc_addr+1); - crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); - outb(crtc_addr+1, crtc_r9); - if(lines==8) - { - biosfn_set_cursor_shape(0x06,0x07); - } - else - { - biosfn_set_cursor_shape(lines-4,lines-3); - } - write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines); - outb(crtc_addr, 0x12); - vde = inb(crtc_addr+1); - outb(crtc_addr, 0x07); - ovl = inb(crtc_addr+1); - vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1); - rows = vde / lines; - write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1); - cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); - write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2); -} - -static void biosfn_load_text_user_pat (AL,ES,BP,CX,DX,BL,BH) Bit8u AL;Bit16u ES;Bit16u BP;Bit16u CX;Bit16u DX;Bit8u BL;Bit8u BH; -{ - Bit16u blockaddr,dest,i,src; - - get_font_access(); - blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - for(i=0;i=0x10) - { - set_scan_lines(BH); - } -} - -static void biosfn_load_text_8_14_pat (AL,BL) Bit8u AL;Bit8u BL; -{ - Bit16u blockaddr,dest,i,src; - - get_font_access(); - blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - for(i=0;i<0x100;i++) - { - src = i * 14; - dest = blockaddr + i * 32; - memcpyb(0xA000, dest, 0xC000, vgafont14+src, 14); - } - release_font_access(); - if(AL>=0x10) - { - set_scan_lines(14); - } -} - -static void biosfn_load_text_8_8_pat (AL,BL) Bit8u AL;Bit8u BL; -{ - Bit16u blockaddr,dest,i,src; - - get_font_access(); - blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - for(i=0;i<0x100;i++) - { - src = i * 8; - dest = blockaddr + i * 32; - memcpyb(0xA000, dest, 0xC000, vgafont8+src, 8); - } - release_font_access(); - if(AL>=0x10) - { - set_scan_lines(8); - } -} - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_set_text_block_specifier: - push ax - push dx - mov dx, # VGAREG_SEQU_ADDRESS - mov ah, bl - mov al, #0x03 - out dx, ax - pop dx - pop ax - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL; -{ - Bit16u blockaddr,dest,i,src; - - get_font_access(); - blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); - for(i=0;i<0x100;i++) - { - src = i * 16; - dest = blockaddr + i * 32; - memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16); - } - release_font_access(); - if(AL>=0x10) - { - set_scan_lines(16); - } -} - -static void biosfn_load_gfx_8_8_chars (ES,BP) Bit16u ES;Bit16u BP; -{ -#ifdef DEBUG - unimplemented(); -#endif -} -static void biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL) Bit16u ES;Bit16u BP;Bit16u CX;Bit8u BL;Bit8u DL; -{ -#ifdef DEBUG - unimplemented(); -#endif -} -static void biosfn_load_gfx_8_14_chars (BL) Bit8u BL; -{ -#ifdef DEBUG - unimplemented(); -#endif -} -static void biosfn_load_gfx_8_8_dd_chars (BL) Bit8u BL; -{ -#ifdef DEBUG - unimplemented(); -#endif -} -static void biosfn_load_gfx_8_16_chars (BL) Bit8u BL; -{ -#ifdef DEBUG - unimplemented(); -#endif -} -// -------------------------------------------------------------------------------------------- -static void biosfn_get_font_info (BH,ES,BP,CX,DX) -Bit8u BH;Bit16u *ES;Bit16u *BP;Bit16u *CX;Bit16u *DX; -{Bit16u ss=get_SS(); - - switch(BH) - {case 0x00: - write_word(ss,ES,read_word(0x00,0x1f*4)); - write_word(ss,BP,read_word(0x00,(0x1f*4)+2)); - break; - case 0x01: - write_word(ss,ES,read_word(0x00,0x43*4)); - write_word(ss,BP,read_word(0x00,(0x43*4)+2)); - break; - case 0x02: - write_word(ss,ES,0xC000); - write_word(ss,BP,vgafont14); - break; - case 0x03: - write_word(ss,ES,0xC000); - write_word(ss,BP,vgafont8); - break; - case 0x04: - write_word(ss,ES,0xC000); - write_word(ss,BP,vgafont8+128*8); - break; - case 0x05: - write_word(ss,ES,0xC000); - write_word(ss,BP,vgafont14alt); - break; - case 0x06: - write_word(ss,ES,0xC000); - write_word(ss,BP,vgafont16); - break; - case 0x07: - write_word(ss,ES,0xC000); - write_word(ss,BP,vgafont16alt); - break; - default: - #ifdef DEBUG - printf("Get font info BH(%02x) was discarded\n",BH); - #endif - return; - } - // Set byte/char of on screen font - write_word(ss,CX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); - - // Set Highest char row - write_word(ss,DX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); -} - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_get_ega_info: - push ds - push ax - mov ax, # BIOSMEM_SEG - mov ds, ax - xor ch, ch - mov bx, # BIOSMEM_SWITCHES - mov cl, [bx] - and cl, #0x0f - mov bx, # BIOSMEM_CRTC_ADDRESS - mov ax, [bx] - mov bx, #0x0003 - cmp ax, # VGAREG_MDA_CRTC_ADDRESS - jne mode_ega_color - mov bh, #0x01 -mode_ega_color: - pop ax - pop ds - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -static void biosfn_alternate_prtsc() -{ -#ifdef DEBUG - unimplemented(); -#endif -} - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_select_vert_res: - -; res : 00 200 lines, 01 350 lines, 02 400 lines - - push ds - push bx - push dx - mov dl, al - mov ax, # BIOSMEM_SEG - mov ds, ax - mov bx, # BIOSMEM_MODESET_CTL - mov al, [bx] - mov bx, # BIOSMEM_SWITCHES - mov ah, [bx] - cmp dl, #0x01 - je vert_res_350 - jb vert_res_200 - cmp dl, #0x02 - je vert_res_400 -#ifdef DEBUG - mov al, dl - xor ah, ah - push ax - mov bx, #msg_vert_res - push bx - call _printf - add sp, #4 -#endif - jmp set_retcode -vert_res_400: - - ; reset modeset ctl bit 7 and set bit 4 - ; set switches bit 3-0 to 0x09 - - and al, #0x7f - or al, #0x10 - and ah, #0xf0 - or ah, #0x09 - jnz set_vert_res -vert_res_350: - - ; reset modeset ctl bit 7 and bit 4 - ; set switches bit 3-0 to 0x09 - - and al, #0x6f - and ah, #0xf0 - or ah, #0x09 - jnz set_vert_res -vert_res_200: - - ; set modeset ctl bit 7 and reset bit 4 - ; set switches bit 3-0 to 0x08 - - and al, #0xef - or al, #0x80 - and ah, #0xf0 - or ah, #0x08 -set_vert_res: - mov bx, # BIOSMEM_MODESET_CTL - mov [bx], al - mov bx, # BIOSMEM_SWITCHES - mov [bx], ah -set_retcode: - mov ax, #0x1212 - pop dx - pop bx - pop ds - ret - -#ifdef DEBUG -msg_vert_res: -.ascii "Select vert res (%02x) was discarded" -.byte 0x0d,0x0a,0x00 -#endif - - -biosfn_enable_default_palette_loading: - push ds - push bx - push dx - mov dl, al - and dl, #0x01 - shl dl, 3 - mov ax, # BIOSMEM_SEG - mov ds, ax - mov bx, # BIOSMEM_MODESET_CTL - mov al, [bx] - and al, #0xf7 - or al, dl - mov [bx], al - mov ax, #0x1212 - pop dx - pop bx - pop ds - ret - - -biosfn_enable_video_addressing: - push bx - push dx - mov bl, al - and bl, #0x01 - xor bl, #0x01 - shl bl, 1 - mov dx, # VGAREG_READ_MISC_OUTPUT - in al, dx - and al, #0xfd - or al, bl - mov dx, # VGAREG_WRITE_MISC_OUTPUT - out dx, al - mov ax, #0x1212 - pop dx - pop bx - ret - - -biosfn_enable_grayscale_summing: - push ds - push bx - push dx - mov dl, al - and dl, #0x01 - xor dl, #0x01 - shl dl, 1 - mov ax, # BIOSMEM_SEG - mov ds, ax - mov bx, # BIOSMEM_MODESET_CTL - mov al, [bx] - and al, #0xfd - or al, dl - mov [bx], al - mov ax, #0x1212 - pop dx - pop bx - pop ds - ret - - -biosfn_enable_cursor_emulation: - push ds - push bx - push dx - mov dl, al - and dl, #0x01 - xor dl, #0x01 - mov ax, # BIOSMEM_SEG - mov ds, ax - mov bx, # BIOSMEM_MODESET_CTL - mov al, [bx] - and al, #0xfe - or al, dl - mov [bx], al - mov ax, #0x1212 - pop dx - pop bx - pop ds - ret -ASM_END - -// -------------------------------------------------------------------------------------------- -static void biosfn_switch_video_interface (AL,ES,DX) Bit8u AL;Bit16u ES;Bit16u DX; -{ -#ifdef DEBUG - unimplemented(); -#endif -} -static void biosfn_enable_video_refresh_control (AL) Bit8u AL; -{ -#ifdef DEBUG - unimplemented(); -#endif -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset) -Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset; -{ - Bit16u newcurs,oldcurs,dummy; - Bit8u car,carattr; - - // Read curs info for the page - biosfn_get_cursor_pos(page,&dummy,&oldcurs); - - // if row=0xff special case : use current cursor position - if(row==0xff) - {col=oldcurs&0x00ff; - row=(oldcurs&0xff00)>>8; - } - - newcurs=row; newcurs<<=8; newcurs+=col; - biosfn_set_cursor_pos(page,newcurs); - - while(count--!=0) - { - car=read_byte(seg,offset++); - if((flag&0x02)!=0) - attr=read_byte(seg,offset++); - - biosfn_write_teletype(car,page,attr,WITH_ATTR); - } - - // Set back curs pos - if((flag&0x01)==0) - biosfn_set_cursor_pos(page,oldcurs); -} - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_group_1A: - cmp al, #0x00 - je biosfn_read_display_code - cmp al, #0x01 - je biosfn_set_display_code -#ifdef DEBUG - call _unknown -#endif - ret -biosfn_read_display_code: - push ds - push ax - mov ax, # BIOSMEM_SEG - mov ds, ax - mov bx, # BIOSMEM_DCC_INDEX - mov al, [bx] - mov bl, al - xor bh, bh - pop ax - mov al, ah - pop ds - ret -biosfn_set_display_code: - push ds - push ax - push bx - mov ax, # BIOSMEM_SEG - mov ds, ax - mov ax, bx - mov bx, # BIOSMEM_DCC_INDEX - mov [bx], al -#ifdef DEBUG - mov al, ah - xor ah, ah - push ax - mov bx, #msg_alt_dcc - push bx - call _printf - add sp, #4 -#endif - pop bx - pop ax - mov al, ah - pop ds - ret - -#ifdef DEBUG -msg_alt_dcc: -.ascii "Alternate Display code (%02x) was discarded" -.byte 0x0d,0x0a,0x00 -#endif -ASM_END - -// -------------------------------------------------------------------------------------------- -static void biosfn_read_state_info (BX,ES,DI) -Bit16u BX;Bit16u ES;Bit16u DI; -{ - // Address of static functionality table - write_word(ES,DI+0x00,&static_functionality); - write_word(ES,DI+0x02,0xC000); - - // Hard coded copy from BIOS area. Should it be cleaner ? - memcpyb(ES,DI+0x04,BIOSMEM_SEG,0x49,30); - memcpyb(ES,DI+0x22,BIOSMEM_SEG,0x84,3); - - write_byte(ES,DI+0x25,read_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); - write_byte(ES,DI+0x26,0); - write_byte(ES,DI+0x27,16); - write_byte(ES,DI+0x28,0); - write_byte(ES,DI+0x29,8); - write_byte(ES,DI+0x2a,2); - write_byte(ES,DI+0x2b,0); - write_byte(ES,DI+0x2c,0); - write_byte(ES,DI+0x31,3); - write_byte(ES,DI+0x32,0); - - memsetb(ES,DI+0x33,0,13); -} - -// -------------------------------------------------------------------------------------------- -// -------------------------------------------------------------------------------------------- -static Bit16u biosfn_read_video_state_size2 (CX) - Bit16u CX; -{ - Bit16u size; - size = 0; - if (CX & 1) { - size += 0x46; - } - if (CX & 2) { - size += (5 + 8 + 5) * 2 + 6; - } - if (CX & 4) { - size += 3 + 256 * 3 + 1; -} - return size; -} - -static void biosfn_read_video_state_size (CX, BX) - Bit16u CX; Bit16u *BX; -{ - Bit16u ss=get_SS(); - write_word(ss, BX, biosfn_read_video_state_size2(CX)); -} - -static Bit16u biosfn_save_video_state (CX,ES,BX) - Bit16u CX;Bit16u ES;Bit16u BX; -{ - Bit16u i, v, crtc_addr, ar_index; - - crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS); - if (CX & 1) { - write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++; - write_byte(ES, BX, inb(crtc_addr)); BX++; - write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++; - inb(VGAREG_ACTL_RESET); - ar_index = inb(VGAREG_ACTL_ADDRESS); - write_byte(ES, BX, ar_index); BX++; - write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++; - - for(i=1;i<=4;i++){ - outb(VGAREG_SEQU_ADDRESS, i); - write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; - } - outb(VGAREG_SEQU_ADDRESS, 0); - write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; - - for(i=0;i<=0x18;i++) { - outb(crtc_addr,i); - write_byte(ES, BX, inb(crtc_addr+1)); BX++; - } - - for(i=0;i<=0x13;i++) { - inb(VGAREG_ACTL_RESET); - outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); - write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++; - } - inb(VGAREG_ACTL_RESET); - - for(i=0;i<=8;i++) { - outb(VGAREG_GRDC_ADDRESS,i); - write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++; - } - - write_word(ES, BX, crtc_addr); BX+= 2; - - /* XXX: read plane latches */ - write_byte(ES, BX, 0); BX++; - write_byte(ES, BX, 0); BX++; - write_byte(ES, BX, 0); BX++; - write_byte(ES, BX, 0); BX++; - } - if (CX & 2) { - write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++; - write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2; - write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2; - write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2; - write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++; - write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2; - write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++; - write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++; - write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++; - write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2; - for(i=0;i<8;i++) { - write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i)); - BX += 2; - } - write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2; - write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++; - /* current font */ - write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2; - write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2; - write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2; - write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2; - } - if (CX & 4) { - /* XXX: check this */ - write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */ - write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */ - write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++; - // Set the whole dac always, from 0 - outb(VGAREG_DAC_WRITE_ADDRESS,0x00); - for(i=0;i<256*3;i++) { - write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++; - } - write_byte(ES, BX, 0); BX++; /* color select register */ - } - return BX; -} - -static Bit16u biosfn_restore_video_state (CX,ES,BX) - Bit16u CX;Bit16u ES;Bit16u BX; -{ - Bit16u i, crtc_addr, v, addr1, ar_index; - - if (CX & 1) { - // Reset Attribute Ctl flip-flop - inb(VGAREG_ACTL_RESET); - - crtc_addr = read_word(ES, BX + 0x40); - addr1 = BX; - BX += 5; - - for(i=1;i<=4;i++){ - outb(VGAREG_SEQU_ADDRESS, i); - outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; - } - outb(VGAREG_SEQU_ADDRESS, 0); - outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; - - // Disable CRTC write protection - outw(crtc_addr,0x0011); - // Set CRTC regs - for(i=0;i<=0x18;i++) { - if (i != 0x11) { - outb(crtc_addr,i); - outb(crtc_addr+1, read_byte(ES, BX)); - } - BX++; - } - // select crtc base address - v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; - if (crtc_addr = 0x3d4) - v |= 0x01; - outb(VGAREG_WRITE_MISC_OUTPUT, v); - - // enable write protection if needed - outb(crtc_addr, 0x11); - outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11)); - - // Set Attribute Ctl - ar_index = read_byte(ES, addr1 + 0x03); - inb(VGAREG_ACTL_RESET); - for(i=0;i<=0x13;i++) { - outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); - outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++; - } - outb(VGAREG_ACTL_ADDRESS, ar_index); - inb(VGAREG_ACTL_RESET); - - for(i=0;i<=8;i++) { - outb(VGAREG_GRDC_ADDRESS,i); - outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++; - } - BX += 2; /* crtc_addr */ - BX += 4; /* plane latches */ - - outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++; - outb(crtc_addr, read_byte(ES, addr1)); addr1++; - outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++; - addr1++; - outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++; - } - if (CX & 2) { - write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++; - write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2; - write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2; - write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2; - write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++; - write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2; - write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++; - write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++; - write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++; - write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2; - for(i=0;i<8;i++) { - write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX)); - BX += 2; - } - write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2; - write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++; - /* current font */ - write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2; - write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2; - write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2; - write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2; - } - if (CX & 4) { - BX++; - v = read_byte(ES, BX); BX++; - outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++; - // Set the whole dac always, from 0 - outb(VGAREG_DAC_WRITE_ADDRESS,0x00); - for(i=0;i<256*3;i++) { - outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++; - } - BX++; - outb(VGAREG_DAC_WRITE_ADDRESS, v); - } - return BX; -} - -// ============================================================================================ -// -// Video Utils -// -// ============================================================================================ - -// -------------------------------------------------------------------------------------------- -static Bit8u find_vga_entry(mode) -Bit8u mode; -{ - Bit8u i,line=0xFF; - for(i=0;i<=MODE_MAX;i++) - if(vga_modes[i].svgamode==mode) - {line=i; - break; - } - return line; -} - -/* =========================================================== */ -/* - * Misc Utils -*/ -/* =========================================================== */ - -// -------------------------------------------------------------------------------------------- -static void memsetb(seg,offset,value,count) - Bit16u seg; - Bit16u offset; - Bit16u value; - Bit16u count; -{ -ASM_START - push bp - mov bp, sp - - push ax - push cx - push es - push di - - mov cx, 10[bp] ; count - cmp cx, #0x00 - je memsetb_end - mov ax, 4[bp] ; segment - mov es, ax - mov ax, 6[bp] ; offset - mov di, ax - mov al, 8[bp] ; value - cld - rep - stosb - -memsetb_end: - pop di - pop es - pop cx - pop ax - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- -static void memsetw(seg,offset,value,count) - Bit16u seg; - Bit16u offset; - Bit16u value; - Bit16u count; -{ -ASM_START - push bp - mov bp, sp - - push ax - push cx - push es - push di - - mov cx, 10[bp] ; count - cmp cx, #0x00 - je memsetw_end - mov ax, 4[bp] ; segment - mov es, ax - mov ax, 6[bp] ; offset - mov di, ax - mov ax, 8[bp] ; value - cld - rep - stosw - -memsetw_end: - pop di - pop es - pop cx - pop ax - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- -static void memcpyb(dseg,doffset,sseg,soffset,count) - Bit16u dseg; - Bit16u doffset; - Bit16u sseg; - Bit16u soffset; - Bit16u count; -{ -ASM_START - push bp - mov bp, sp - - push ax - push cx - push es - push di - push ds - push si - - mov cx, 12[bp] ; count - cmp cx, #0x0000 - je memcpyb_end - mov ax, 4[bp] ; dsegment - mov es, ax - mov ax, 6[bp] ; doffset - mov di, ax - mov ax, 8[bp] ; ssegment - mov ds, ax - mov ax, 10[bp] ; soffset - mov si, ax - cld - rep - movsb - -memcpyb_end: - pop si - pop ds - pop di - pop es - pop cx - pop ax - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- -static void memcpyw(dseg,doffset,sseg,soffset,count) - Bit16u dseg; - Bit16u doffset; - Bit16u sseg; - Bit16u soffset; - Bit16u count; -{ -ASM_START - push bp - mov bp, sp - - push ax - push cx - push es - push di - push ds - push si - - mov cx, 12[bp] ; count - cmp cx, #0x0000 - je memcpyw_end - mov ax, 4[bp] ; dsegment - mov es, ax - mov ax, 6[bp] ; doffset - mov di, ax - mov ax, 8[bp] ; ssegment - mov ds, ax - mov ax, 10[bp] ; soffset - mov si, ax - cld - rep - movsw - -memcpyw_end: - pop si - pop ds - pop di - pop es - pop cx - pop ax - - pop bp -ASM_END -} - -/* =========================================================== */ -/* - * These functions where ripped from Kevin's rombios.c -*/ -/* =========================================================== */ - -// -------------------------------------------------------------------------------------------- -static Bit8u -read_byte(seg, offset) - Bit16u seg; - Bit16u offset; -{ -ASM_START - push bp - mov bp, sp - - push bx - push ds - mov ax, 4[bp] ; segment - mov ds, ax - mov bx, 6[bp] ; offset - mov al, [bx] - ;; al = return value (byte) - pop ds - pop bx - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- -static Bit16u -read_word(seg, offset) - Bit16u seg; - Bit16u offset; -{ -ASM_START - push bp - mov bp, sp - - push bx - push ds - mov ax, 4[bp] ; segment - mov ds, ax - mov bx, 6[bp] ; offset - mov ax, [bx] - ;; ax = return value (word) - pop ds - pop bx - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- -static void -write_byte(seg, offset, data) - Bit16u seg; - Bit16u offset; - Bit8u data; -{ -ASM_START - push bp - mov bp, sp - - push ax - push bx - push ds - mov ax, 4[bp] ; segment - mov ds, ax - mov bx, 6[bp] ; offset - mov al, 8[bp] ; data byte - mov [bx], al ; write data byte - pop ds - pop bx - pop ax - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- -static void -write_word(seg, offset, data) - Bit16u seg; - Bit16u offset; - Bit16u data; -{ -ASM_START - push bp - mov bp, sp - - push ax - push bx - push ds - mov ax, 4[bp] ; segment - mov ds, ax - mov bx, 6[bp] ; offset - mov ax, 8[bp] ; data word - mov [bx], ax ; write data word - pop ds - pop bx - pop ax - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- - Bit8u -inb(port) - Bit16u port; -{ -ASM_START - push bp - mov bp, sp - - push dx - mov dx, 4[bp] - in al, dx - pop dx - - pop bp -ASM_END -} - - Bit16u -inw(port) - Bit16u port; -{ -ASM_START - push bp - mov bp, sp - - push dx - mov dx, 4[bp] - in ax, dx - pop dx - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- - void -outb(port, val) - Bit16u port; - Bit8u val; -{ -ASM_START - push bp - mov bp, sp - - push ax - push dx - mov dx, 4[bp] - mov al, 6[bp] - out dx, al - pop dx - pop ax - - pop bp -ASM_END -} - -// -------------------------------------------------------------------------------------------- - void -outw(port, val) - Bit16u port; - Bit16u val; -{ -ASM_START - push bp - mov bp, sp - - push ax - push dx - mov dx, 4[bp] - mov ax, 6[bp] - out dx, ax - pop dx - pop ax - - pop bp -ASM_END -} - -Bit16u get_SS() -{ -ASM_START - mov ax, ss -ASM_END -} - -#ifdef DEBUG -void unimplemented() -{ - printf("--> Unimplemented\n"); -} - -void unknown() -{ - printf("--> Unknown int10\n"); -} -#endif - -// -------------------------------------------------------------------------------------------- -#if defined(USE_BX_INFO) || defined(DEBUG) || defined(CIRRUS_DEBUG) -void printf(s) - Bit8u *s; -{ - Bit8u c, format_char; - Boolean in_format; - unsigned format_width, i; - Bit16u *arg_ptr; - Bit16u arg_seg, arg, digit, nibble, shift_count; - - arg_ptr = &s; - arg_seg = get_SS(); - - in_format = 0; - format_width = 0; - - while (c = read_byte(0xc000, s)) { - if ( c == '%' ) { - in_format = 1; - format_width = 0; - } - else if (in_format) { - if ( (c>='0') && (c<='9') ) { - format_width = (format_width * 10) + (c - '0'); - } - else if (c == 'x') { - arg_ptr++; // increment to next arg - arg = read_word(arg_seg, arg_ptr); - if (format_width == 0) - format_width = 4; - i = 0; - digit = format_width - 1; - for (i=0; i> (4 * digit)) & 0x000f; - if (nibble <= 9) - outb(0x0500, nibble + '0'); - else - outb(0x0500, (nibble - 10) + 'A'); - digit--; - } - in_format = 0; - } - //else if (c == 'd') { - // in_format = 0; - // } - } - else { - outb(0x0500, c); - } - s ++; - } -} -#endif - -ASM_START - ; get LFB address from PCI - ; in - ax: PCI device vendor - ; out - ax: LFB address (high 16 bit) - ;; NOTE - may be called in protected mode -_pci_get_lfb_addr: - push bx - push cx - push dx - push eax - mov bx, ax - xor cx, cx - mov dl, #0x00 - call pci_read_reg - cmp ax, #0xffff - jz pci_get_lfb_addr_fail - pci_get_lfb_addr_next_dev: - mov dl, #0x00 - call pci_read_reg - cmp ax, bx ;; check vendor - jz pci_get_lfb_addr_found - add cx, #0x8 - cmp cx, #0x200 ;; search bus #0 and #1 - jb pci_get_lfb_addr_next_dev - pci_get_lfb_addr_fail: - xor dx, dx ;; no LFB - jmp pci_get_lfb_addr_return - pci_get_lfb_addr_found: - mov dl, #0x10 ;; I/O space #0 - call pci_read_reg - test ax, #0xfff1 - jz pci_get_lfb_addr_success - mov dl, #0x14 ;; I/O space #1 - call pci_read_reg - test ax, #0xfff1 - jnz pci_get_lfb_addr_fail - pci_get_lfb_addr_success: - shr eax, #16 - mov dx, ax ;; LFB address - pci_get_lfb_addr_return: - pop eax - mov ax, dx - pop dx - pop cx - pop bx - ret - - ; read PCI register - ; in - cx: device/function - ; in - dl: register - ; out - eax: value -pci_read_reg: - mov eax, #0x00800000 - mov ax, cx - shl eax, #8 - mov al, dl - mov dx, #0xcf8 - out dx, eax - add dl, #4 - in eax, dx - ret -ASM_END - -#ifdef VBE -#include "vbe.c" -#endif - -#ifdef CIRRUS -#include "clext.c" -#endif - -// -------------------------------------------------------------------------------------------- - -ASM_START -;; DATA_SEG_DEFS_HERE -ASM_END - -ASM_START -.ascii "vgabios ends here" -.byte 0x00 -vgabios_end: -.byte 0xCB -;; BLOCK_STRINGS_BEGIN -ASM_END diff --git a/roms/vgabios/vgabios.h b/roms/vgabios/vgabios.h deleted file mode 100644 index 3ad4bae..0000000 --- a/roms/vgabios/vgabios.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef vgabios_h_included -#define vgabios_h_included - -/* Types */ -typedef unsigned char Bit8u; -typedef unsigned short Bit16u; -typedef unsigned long Bit32u; -typedef unsigned short Boolean; - -/* Defines */ - -#define SET_AL(val8) AX = ((AX & 0xff00) | (val8)) -#define SET_BL(val8) BX = ((BX & 0xff00) | (val8)) -#define SET_CL(val8) CX = ((CX & 0xff00) | (val8)) -#define SET_DL(val8) DX = ((DX & 0xff00) | (val8)) -#define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8)) -#define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8)) -#define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8)) -#define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8)) - -#define GET_AL() ( AX & 0x00ff ) -#define GET_BL() ( BX & 0x00ff ) -#define GET_CL() ( CX & 0x00ff ) -#define GET_DL() ( DX & 0x00ff ) -#define GET_AH() ( AX >> 8 ) -#define GET_BH() ( BX >> 8 ) -#define GET_CH() ( CX >> 8 ) -#define GET_DH() ( DX >> 8 ) - -#define SET_CF() FLAGS |= 0x0001 -#define CLEAR_CF() FLAGS &= 0xfffe -#define GET_CF() (FLAGS & 0x0001) - -#define SET_ZF() FLAGS |= 0x0040 -#define CLEAR_ZF() FLAGS &= 0xffbf -#define GET_ZF() (FLAGS & 0x0040) - -#define SCROLL_DOWN 0 -#define SCROLL_UP 1 -#define NO_ATTR 2 -#define WITH_ATTR 3 - -#define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) -#define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) -#define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) - -#endif diff --git a/roms/vgabios/vgafonts.h b/roms/vgabios/vgafonts.h deleted file mode 100644 index 0c213e6..0000000 --- a/roms/vgabios/vgafonts.h +++ /dev/null @@ -1,784 +0,0 @@ -/* - * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip - * The package is (c) by Joseph Gil - * The individual fonts are public domain - */ -static Bit8u vgafont8[256*8]= -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, - 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, - 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, - 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, - 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, - 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, - 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, - 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, - 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, - 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, - 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, - 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, - 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, - 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, - 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, - 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, - 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, - 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, - 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, - 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, - 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, - 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, - 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, - 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, - 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, - 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, - 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, - 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, - 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, - 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, - 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, - 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, - 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, - 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, - 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, - 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, - 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, - 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, - 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, - 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, - 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, - 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, - 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, - 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, - 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, - 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, - 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, - 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, - 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, - 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, - 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, - 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, - 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, - 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, - 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, - 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, - 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, - 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, - 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, - 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, - 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, - 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, - 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, - 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, - 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, - 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, - 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, - 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, - 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, - 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, - 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, - 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, - 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, - 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, - 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, - 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, - 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, - 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, - 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, - 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, - 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, - 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, - 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, - 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, - 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, - 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, - 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, - 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, - 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, - 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, - 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, - 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, - 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, - 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, - 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, - 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, - 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, - 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, - 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, - 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, - 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, - 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, - 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, - 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, - 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, - 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, - 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, - 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static Bit8u vgafont14[256*14]= -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, - 0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, - 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static Bit8u vgafont16[256*16]= -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, - 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static Bit8u vgafont14alt[1]={0x00}; -static Bit8u vgafont16alt[1]={0x00}; diff --git a/roms/vgabios/vgatables.h b/roms/vgabios/vgatables.h deleted file mode 100644 index 3ac96bb..0000000 --- a/roms/vgabios/vgatables.h +++ /dev/null @@ -1,622 +0,0 @@ -/* - * - * BIOS Memory - * - */ -#define BIOSMEM_SEG 0x40 - -#define BIOSMEM_INITIAL_MODE 0x10 -#define BIOSMEM_CURRENT_MODE 0x49 -#define BIOSMEM_NB_COLS 0x4A -#define BIOSMEM_PAGE_SIZE 0x4C -#define BIOSMEM_CURRENT_START 0x4E -#define BIOSMEM_CURSOR_POS 0x50 -#define BIOSMEM_CURSOR_TYPE 0x60 -#define BIOSMEM_CURRENT_PAGE 0x62 -#define BIOSMEM_CRTC_ADDRESS 0x63 -#define BIOSMEM_CURRENT_MSR 0x65 -#define BIOSMEM_CURRENT_PAL 0x66 -#define BIOSMEM_NB_ROWS 0x84 -#define BIOSMEM_CHAR_HEIGHT 0x85 -#define BIOSMEM_VIDEO_CTL 0x87 -#define BIOSMEM_SWITCHES 0x88 -#define BIOSMEM_MODESET_CTL 0x89 -#define BIOSMEM_DCC_INDEX 0x8A -#define BIOSMEM_VS_POINTER 0xA8 -#define BIOSMEM_VBE_FLAG 0xB9 -#define BIOSMEM_VBE_MODE 0xBA - - -/* - * - * VGA registers - * - */ -#define VGAREG_ACTL_ADDRESS 0x3c0 -#define VGAREG_ACTL_WRITE_DATA 0x3c0 -#define VGAREG_ACTL_READ_DATA 0x3c1 - -#define VGAREG_INPUT_STATUS 0x3c2 -#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 -#define VGAREG_VIDEO_ENABLE 0x3c3 -#define VGAREG_SEQU_ADDRESS 0x3c4 -#define VGAREG_SEQU_DATA 0x3c5 - -#define VGAREG_PEL_MASK 0x3c6 -#define VGAREG_DAC_STATE 0x3c7 -#define VGAREG_DAC_READ_ADDRESS 0x3c7 -#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 -#define VGAREG_DAC_DATA 0x3c9 - -#define VGAREG_READ_FEATURE_CTL 0x3ca -#define VGAREG_READ_MISC_OUTPUT 0x3cc - -#define VGAREG_GRDC_ADDRESS 0x3ce -#define VGAREG_GRDC_DATA 0x3cf - -#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 -#define VGAREG_MDA_CRTC_DATA 0x3b5 -#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 -#define VGAREG_VGA_CRTC_DATA 0x3d5 - -#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba -#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da -#define VGAREG_ACTL_RESET 0x3da - -#define VGAREG_MDA_MODECTL 0x3b8 -#define VGAREG_CGA_MODECTL 0x3d8 -#define VGAREG_CGA_PALETTE 0x3d9 - -/* Video memory */ -#define VGAMEM_GRAPH 0xA000 -#define VGAMEM_CTEXT 0xB800 -#define VGAMEM_MTEXT 0xB000 - -/* - * - * Tables of default values for each mode - * - */ -#define MODE_MAX 15 -#define TEXT 0x00 -#define GRAPH 0x01 - -#define CTEXT 0x00 -#define MTEXT 0x01 -#define CGA 0x02 -#define PLANAR1 0x03 -#define PLANAR4 0x04 -#define LINEAR8 0x05 - -// for SVGA -#define LINEAR15 0x10 -#define LINEAR16 0x11 -#define LINEAR24 0x12 -#define LINEAR32 0x13 - -typedef struct -{Bit8u svgamode; - Bit8u class; /* TEXT, GRAPH */ - Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ - Bit8u pixbits; - Bit16u sstart; - Bit8u pelmask; - Bit8u dacmodel; /* 0 1 2 3 */ -} VGAMODES; - -static VGAMODES vga_modes[MODE_MAX+1]= -{//mode class model bits sstart pelm dac - {0x00, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, - {0x01, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, - {0x02, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, - {0x03, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, - {0x04, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, - {0x05, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, - {0x06, GRAPH, CGA, 1, 0xB800, 0xFF, 0x01}, - {0x07, TEXT, MTEXT, 4, 0xB000, 0xFF, 0x00}, - {0x0D, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, - {0x0E, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, - {0x0F, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x00}, - {0x10, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, - {0x11, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x02}, - {0x12, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, - {0x13, GRAPH, LINEAR8, 8, 0xA000, 0xFF, 0x03}, - {0x6A, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02} -}; - -/* convert index in vga_modes[] to index in video_param_table[] */ -static Bit8u line_to_vpti[MODE_MAX+1]={ - 0x17, 0x17, 0x18, 0x18, 0x04, 0x05, 0x06, 0x07, - 0x0d, 0x0e, 0x11, 0x12, 0x1a, 0x1b, 0x1c, 0x1d, -}; - -/* Default Palette */ -#define DAC_MAX_MODEL 3 - -static Bit8u dac_regs[DAC_MAX_MODEL+1]= -{0x3f,0x3f,0x3f,0xff}; - -/* standard BIOS Video Parameter Table */ -typedef struct { - Bit8u twidth; - Bit8u theightm1; - Bit8u cheight; - Bit8u slength_l; - Bit8u slength_h; - Bit8u sequ_regs[4]; - Bit8u miscreg; - Bit8u crtc_regs[25]; - Bit8u actl_regs[20]; - Bit8u grdc_regs[9]; -} VideoParamTableEntry; - -static VideoParamTableEntry video_param_table[30] = { -{ - /* index=0x00 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x01 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x02 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x03 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x04 vga mode 0x04 */ - 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ - 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ - 0x63, /* miscreg */ - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff, /* crtc_regs */ - 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x05 vga mode 0x05 */ - 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ - 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ - 0x63, /* miscreg */ - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff, /* crtc_regs */ - 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x06 vga mode 0x06 */ - 80, 24, 8, 0x00, 0x10, /* tw, th-1, ch, slength */ - 0x01, 0x01, 0x00, 0x06, /* sequ_regs */ - 0x63, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, - 0xff, /* crtc_regs */ - 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x01, 0x00, 0x01, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x07 vga mode 0x07 */ - 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ - 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ - 0x66, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, - 0xff, /* crtc_regs */ - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x08 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x09 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x0a no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x0b no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x0c no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x0d vga mode 0x0d */ - 40, 24, 8, 0x00, 0x20, /* tw, th-1, ch, slength */ - 0x09, 0x0f, 0x00, 0x06, /* sequ_regs */ - 0x63, /* miscreg */ - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x0e vga mode 0x0e */ - 80, 24, 8, 0x00, 0x40, /* tw, th-1, ch, slength */ - 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ - 0x63, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x0f no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x10 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x11 vga mode 0x0f */ - 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ - 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ - 0xa3, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff, /* crtc_regs */ - 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x12 vga mode 0x10 */ - 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ - 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ - 0xa3, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x13 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x14 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x15 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x16 no mode defined */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}, -{ - /* index=0x17 vga mode 0x01 */ - 40, 24, 16, 0x00, 0x08, /* tw, th-1, ch, slength */ - 0x08, 0x03, 0x00, 0x02, /* sequ_regs */ - 0x67, /* miscreg */ - 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x18 vga mode 0x03 */ - 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ - 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ - 0x67, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x19 vga mode 0x07 */ - 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ - 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ - 0x66, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, - 0xff, /* crtc_regs */ - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x1a vga mode 0x11 */ - 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ - 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ - 0xe3, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff, /* crtc_regs */ - 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, - 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, - 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x1b vga mode 0x12 */ - 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ - 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ - 0xe3, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x1c vga mode 0x13 */ - 40, 24, 8, 0x00, 0x00, /* tw, th-1, ch, slength */ - 0x01, 0x0f, 0x00, 0x0e, /* sequ_regs */ - 0x63, /* miscreg */ - 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, - 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x41, 0x00, 0x0f, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -{ - /* index=0x1d vga mode 0x6a */ - 100, 36, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ - 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ - 0xe3, /* miscreg */ - 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0, - 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3, - 0xff, /* crtc_regs */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ -}, -}; - -/* Mono */ -static Bit8u palette0[63+1][3]= -{ - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, - 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f -}; - -static Bit8u palette1[63+1][3]= -{ - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f -}; - -static Bit8u palette2[63+1][3]= -{ - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, - 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, - 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, - 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, - 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, - 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, - 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f -}; - -static Bit8u palette3[256][3]= -{ - 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, - 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, - 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, - 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, - 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, - 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, - 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, - 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, - - 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, - 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, - 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, - 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, - 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, - 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, - 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, - 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, - - 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, - 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, - 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, - 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, - 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, - 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, - 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, - 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, - - 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, - 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, - 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, - 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, - 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, - 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, - 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, - 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 -}; - -static Bit8u static_functionality[0x10]= -{ - /* 0 */ 0xff, // All modes supported #1 - /* 1 */ 0xe0, // All modes supported #2 - /* 2 */ 0x0f, // All modes supported #3 - /* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved - /* 7 */ 0x07, // 200, 350, 400 scan lines - /* 8 */ 0x02, // mamimum number of visible charsets in text mode - /* 9 */ 0x08, // total number of charset blocks in text mode - /* a */ 0xe7, // Change to add new functions - /* b */ 0x0c, // Change to add new functions - /* c */ 0x00, // reserved - /* d */ 0x00, // reserved - /* e */ 0x00, // Change to add new functions - /* f */ 0x00 // reserved -}; diff --git a/rules.mak b/rules.mak index ed59c9e..04a9198 100644 --- a/rules.mak +++ b/rules.mak @@ -15,15 +15,23 @@ MAKEFLAGS += -rR QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d %.o: %.c - $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," CC $(TARGET_DIR)$@") + $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," CC $(TARGET_DIR)$@") + +ifeq ($(LIBTOOL),) +%.lo: %.c + @echo "missing libtool. please install and rerun configure"; exit 1 +else +%.lo: %.c + $(call quiet-command,$(LIBTOOL) --mode=compile --quiet --tag=CC $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," lt CC $@") +endif %.o: %.S - $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," AS $(TARGET_DIR)$@") + $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," AS $(TARGET_DIR)$@") %.o: %.m - $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," OBJC $(TARGET_DIR)$@") + $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," OBJC $(TARGET_DIR)$@") -LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(LIBS)," LINK $(TARGET_DIR)$@") +LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(sort $(1)) $(LIBS)," LINK $(TARGET_DIR)$@") %$(EXESUF): %.o $(call LINK,$^) diff --git a/rwhandler.c b/rwhandler.c deleted file mode 100644 index bb2238f..0000000 --- a/rwhandler.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "rwhandler.h" -#include "ioport.h" -#include "cpu-all.h" - -#define RWHANDLER_WRITE(name, len, type) \ -static void name(void *opaque, type addr, uint32_t value) \ -{\ - struct ReadWriteHandler *handler = opaque;\ - handler->write(handler, addr, value, len);\ -} - -#define RWHANDLER_READ(name, len, type) \ -static uint32_t name(void *opaque, type addr) \ -{ \ - struct ReadWriteHandler *handler = opaque; \ - return handler->read(handler, addr, len); \ -} - -RWHANDLER_WRITE(cpu_io_memory_simple_writeb, 1, target_phys_addr_t); -RWHANDLER_READ(cpu_io_memory_simple_readb, 1, target_phys_addr_t); -RWHANDLER_WRITE(cpu_io_memory_simple_writew, 2, target_phys_addr_t); -RWHANDLER_READ(cpu_io_memory_simple_readw, 2, target_phys_addr_t); -RWHANDLER_WRITE(cpu_io_memory_simple_writel, 4, target_phys_addr_t); -RWHANDLER_READ(cpu_io_memory_simple_readl, 4, target_phys_addr_t); - -static CPUWriteMemoryFunc * const cpu_io_memory_simple_write[] = { - &cpu_io_memory_simple_writeb, - &cpu_io_memory_simple_writew, - &cpu_io_memory_simple_writel, -}; - -static CPUReadMemoryFunc * const cpu_io_memory_simple_read[] = { - &cpu_io_memory_simple_readb, - &cpu_io_memory_simple_readw, - &cpu_io_memory_simple_readl, -}; - -int cpu_register_io_memory_simple(struct ReadWriteHandler *handler, int endian) -{ - if (!handler->read || !handler->write) { - return -1; - } - return cpu_register_io_memory(cpu_io_memory_simple_read, - cpu_io_memory_simple_write, - handler, endian); -} - -RWHANDLER_WRITE(ioport_simple_writeb, 1, uint32_t); -RWHANDLER_READ(ioport_simple_readb, 1, uint32_t); -RWHANDLER_WRITE(ioport_simple_writew, 2, uint32_t); -RWHANDLER_READ(ioport_simple_readw, 2, uint32_t); -RWHANDLER_WRITE(ioport_simple_writel, 4, uint32_t); -RWHANDLER_READ(ioport_simple_readl, 4, uint32_t); - -int register_ioport_simple(ReadWriteHandler* handler, - pio_addr_t start, int length, int size) -{ - IOPortWriteFunc *write; - IOPortReadFunc *read; - int r; - switch (size) { - case 1: - write = ioport_simple_writeb; - read = ioport_simple_readb; - break; - case 2: - write = ioport_simple_writew; - read = ioport_simple_readw; - break; - default: - write = ioport_simple_writel; - read = ioport_simple_readl; - } - if (handler->write) { - r = register_ioport_write(start, length, size, write, handler); - if (r < 0) { - return r; - } - } - if (handler->read) { - r = register_ioport_read(start, length, size, read, handler); - if (r < 0) { - return r; - } - } - return 0; -} diff --git a/rwhandler.h b/rwhandler.h deleted file mode 100644 index b2a5790..0000000 --- a/rwhandler.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef READ_WRITE_HANDLER_H -#define READ_WRITE_HANDLER_H - -#include "qemu-common.h" -#include "ioport.h" - -typedef struct ReadWriteHandler ReadWriteHandler; - -/* len is guaranteed to be one of 1, 2 or 4, addr is guaranteed to fit in an - * appropriate type (io/memory/etc). They do not need to be range checked. */ -typedef void WriteHandlerFunc(ReadWriteHandler *, pcibus_t addr, - uint32_t value, int len); -typedef uint32_t ReadHandlerFunc(ReadWriteHandler *, pcibus_t addr, int len); - -struct ReadWriteHandler { - WriteHandlerFunc *write; - ReadHandlerFunc *read; -}; - -/* Helpers for when we want to use a single routine with length. */ -/* CPU memory handler: both read and write must be present. */ -int cpu_register_io_memory_simple(ReadWriteHandler *, int endian); -/* io port handler: can supply only read or write handlers. */ -int register_ioport_simple(ReadWriteHandler *, - pio_addr_t start, int length, int size); - -#endif diff --git a/savevm.c b/savevm.c index 3d51974..f53cd4c 100644 --- a/savevm.c +++ b/savevm.c @@ -23,7 +23,6 @@ */ #include #include -#include #include #include #include @@ -82,6 +81,8 @@ #include "migration.h" #include "qemu_socket.h" #include "qemu-queue.h" +#include "qemu-timer.h" +#include "cpus.h" #define SELF_ANNOUNCE_ROUNDS 5 @@ -137,7 +138,7 @@ static void qemu_announce_self_once(void *opaque) if (--count) { /* delay 50ms, 150ms, 250ms, ... */ - qemu_mod_timer(timer, qemu_get_clock(rt_clock) + + qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) + 50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100); } else { qemu_del_timer(timer); @@ -148,7 +149,7 @@ static void qemu_announce_self_once(void *opaque) void qemu_announce_self(void) { static QEMUTimer *timer; - timer = qemu_new_timer(rt_clock, qemu_announce_self_once, &timer); + timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer); qemu_announce_self_once(&timer); } @@ -173,7 +174,7 @@ struct QEMUFile { int buf_size; /* 0 when writing */ uint8_t buf[IO_BUF_SIZE]; - int has_error; + int last_error; }; typedef struct QEMUFileStdio @@ -194,7 +195,7 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) ssize_t len; do { - len = recv(s->fd, (void *)buf, size, 0); + len = qemu_recv(s->fd, buf, size, 0); } while (len == -1 && socket_error() == EINTR); if (len == -1) @@ -206,7 +207,7 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) static int socket_close(void *opaque) { QEMUFileSocket *s = opaque; - qemu_free(s); + g_free(s); return 0; } @@ -234,7 +235,7 @@ static int stdio_pclose(void *opaque) QEMUFileStdio *s = opaque; int ret; ret = pclose(s->stdio_file); - qemu_free(s); + g_free(s); return ret; } @@ -242,7 +243,7 @@ static int stdio_fclose(void *opaque) { QEMUFileStdio *s = opaque; fclose(s->stdio_file); - qemu_free(s); + g_free(s); return 0; } @@ -255,7 +256,7 @@ QEMUFile *qemu_popen(FILE *stdio_file, const char *mode) return NULL; } - s = qemu_mallocz(sizeof(QEMUFileStdio)); + s = g_malloc0(sizeof(QEMUFileStdio)); s->stdio_file = stdio_file; @@ -303,7 +304,7 @@ QEMUFile *qemu_fdopen(int fd, const char *mode) return NULL; } - s = qemu_mallocz(sizeof(QEMUFileStdio)); + s = g_malloc0(sizeof(QEMUFileStdio)); s->stdio_file = fdopen(fd, mode); if (!s->stdio_file) goto fail; @@ -318,13 +319,13 @@ QEMUFile *qemu_fdopen(int fd, const char *mode) return s->file; fail: - qemu_free(s); + g_free(s); return NULL; } QEMUFile *qemu_fopen_socket(int fd) { - QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket)); + QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket)); s->fd = fd; s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, @@ -358,7 +359,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode) return NULL; } - s = qemu_mallocz(sizeof(QEMUFileStdio)); + s = g_malloc0(sizeof(QEMUFileStdio)); s->stdio_file = fopen(filename, mode); if (!s->stdio_file) @@ -373,7 +374,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode) } return s->file; fail: - qemu_free(s); + g_free(s); return NULL; } @@ -411,7 +412,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, { QEMUFile *f; - f = qemu_mallocz(sizeof(QEMUFile)); + f = g_malloc0(sizeof(QEMUFile)); f->opaque = opaque; f->put_buffer = put_buffer; @@ -425,14 +426,14 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, return f; } -int qemu_file_has_error(QEMUFile *f) +int qemu_file_get_error(QEMUFile *f) { - return f->has_error; + return f->last_error; } -void qemu_file_set_error(QEMUFile *f) +void qemu_file_set_error(QEMUFile *f, int ret) { - f->has_error = 1; + f->last_error = ret; } void qemu_fflush(QEMUFile *f) @@ -447,7 +448,7 @@ void qemu_fflush(QEMUFile *f) if (len > 0) f->buf_offset += f->buf_index; else - f->has_error = 1; + f->last_error = -EINVAL; f->buf_index = 0; } } @@ -455,6 +456,7 @@ void qemu_fflush(QEMUFile *f) static void qemu_fill_buffer(QEMUFile *f) { int len; + int pending; if (!f->get_buffer) return; @@ -462,13 +464,22 @@ static void qemu_fill_buffer(QEMUFile *f) if (f->is_write) abort(); - len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE); + pending = f->buf_size - f->buf_index; + if (pending > 0) { + memmove(f->buf, f->buf + f->buf_index, pending); + } + f->buf_index = 0; + f->buf_size = pending; + + len = f->get_buffer(f->opaque, f->buf + pending, f->buf_offset, + IO_BUF_SIZE - pending); if (len > 0) { - f->buf_index = 0; - f->buf_size = len; + f->buf_size += len; f->buf_offset += len; + } else if (len == 0) { + f->last_error = -EIO; } else if (len != -EAGAIN) - f->has_error = 1; + f->last_error = len; } int qemu_fclose(QEMUFile *f) @@ -477,7 +488,7 @@ int qemu_fclose(QEMUFile *f) qemu_fflush(f); if (f->close) ret = f->close(f->opaque); - qemu_free(f); + g_free(f); return ret; } @@ -490,13 +501,13 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) { int l; - if (!f->has_error && f->is_write == 0 && f->buf_index > 0) { + if (!f->last_error && f->is_write == 0 && f->buf_index > 0) { fprintf(stderr, "Attempted to write to buffer while read buffer is not empty\n"); abort(); } - while (!f->has_error && size > 0) { + while (!f->last_error && size > 0) { l = IO_BUF_SIZE - f->buf_index; if (l > size) l = size; @@ -512,7 +523,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) void qemu_put_byte(QEMUFile *f, int v) { - if (!f->has_error && f->is_write == 0 && f->buf_index > 0) { + if (!f->last_error && f->is_write == 0 && f->buf_index > 0) { fprintf(stderr, "Attempted to write to buffer while read buffer is not empty\n"); abort(); @@ -524,56 +535,86 @@ void qemu_put_byte(QEMUFile *f, int v) qemu_fflush(f); } -int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) +static void qemu_file_skip(QEMUFile *f, int size) { - int size, l; + if (f->buf_index + size <= f->buf_size) { + f->buf_index += size; + } +} - if (f->is_write) +static int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset) +{ + int pending; + int index; + + if (f->is_write) { abort(); + } - size = size1; - while (size > 0) { - l = f->buf_size - f->buf_index; - if (l == 0) { - qemu_fill_buffer(f); - l = f->buf_size - f->buf_index; - if (l == 0) - break; + index = f->buf_index + offset; + pending = f->buf_size - index; + if (pending < size) { + qemu_fill_buffer(f); + index = f->buf_index + offset; + pending = f->buf_size - index; + } + + if (pending <= 0) { + return 0; + } + if (size > pending) { + size = pending; + } + + memcpy(buf, f->buf + index, size); + return size; +} + +int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size) +{ + int pending = size; + int done = 0; + + while (pending > 0) { + int res; + + res = qemu_peek_buffer(f, buf, pending, 0); + if (res == 0) { + return done; } - if (l > size) - l = size; - memcpy(buf, f->buf + f->buf_index, l); - f->buf_index += l; - buf += l; - size -= l; + qemu_file_skip(f, res); + buf += res; + pending -= res; + done += res; } - return size1 - size; + return done; } -static int qemu_peek_byte(QEMUFile *f) +static int qemu_peek_byte(QEMUFile *f, int offset) { - if (f->is_write) + int index = f->buf_index + offset; + + if (f->is_write) { abort(); + } - if (f->buf_index >= f->buf_size) { + if (index >= f->buf_size) { qemu_fill_buffer(f); - if (f->buf_index >= f->buf_size) + index = f->buf_index + offset; + if (index >= f->buf_size) { return 0; + } } - return f->buf[f->buf_index]; + return f->buf[index]; } int qemu_get_byte(QEMUFile *f) { - if (f->is_write) - abort(); + int result; - if (f->buf_index >= f->buf_size) { - qemu_fill_buffer(f); - if (f->buf_index >= f->buf_size) - return 0; - } - return f->buf[f->buf_index++]; + result = qemu_peek_byte(f, 0); + qemu_file_skip(f, 1); + return result; } int64_t qemu_ftell(QEMUFile *f) @@ -674,6 +715,30 @@ uint64_t qemu_get_be64(QEMUFile *f) return v; } + +/* timer */ + +void qemu_put_timer(QEMUFile *f, QEMUTimer *ts) +{ + uint64_t expire_time; + + expire_time = qemu_timer_expire_time_ns(ts); + qemu_put_be64(f, expire_time); +} + +void qemu_get_timer(QEMUFile *f, QEMUTimer *ts) +{ + uint64_t expire_time; + + expire_time = qemu_get_be64(f); + if (expire_time != -1) { + qemu_mod_timer_ns(ts, expire_time); + } else { + qemu_del_timer(ts); + } +} + + /* bool */ static int get_bool(QEMUFile *f, void *pv, size_t size) @@ -882,6 +947,27 @@ const VMStateInfo vmstate_info_uint32 = { .put = put_uint32, }; +/* 32 bit uint. See that the received value is the same than the one + in the field */ + +static int get_uint32_equal(QEMUFile *f, void *pv, size_t size) +{ + uint32_t *v = pv; + uint32_t v2; + qemu_get_be32s(f, &v2); + + if (*v == v2) { + return 0; + } + return -EINVAL; +} + +const VMStateInfo vmstate_info_uint32_equal = { + .name = "uint32 equal", + .get = get_uint32_equal, + .put = put_uint32, +}; + /* 64 bit unsigned int */ static int get_uint64(QEMUFile *f, void *pv, size_t size) @@ -986,7 +1072,7 @@ const VMStateInfo vmstate_info_buffer = { }; /* unused buffers: space that was used for some fields that are - not usefull anymore */ + not useful anymore */ static int get_unused_buffer(QEMUFile *f, void *pv, size_t size) { @@ -1093,7 +1179,7 @@ int register_savevm_live(DeviceState *dev, { SaveStateEntry *se; - se = qemu_mallocz(sizeof(SaveStateEntry)); + se = g_malloc0(sizeof(SaveStateEntry)); se->version_id = version_id; se->section_id = global_section_id++; se->set_params = set_params; @@ -1109,9 +1195,9 @@ int register_savevm_live(DeviceState *dev, if (id) { pstrcpy(se->idstr, sizeof(se->idstr), id); pstrcat(se->idstr, sizeof(se->idstr), "/"); - qemu_free(id); + g_free(id); - se->compat = qemu_mallocz(sizeof(CompatEntry)); + se->compat = g_malloc0(sizeof(CompatEntry)); pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr); se->compat->instance_id = instance_id == -1 ? calculate_compat_instance_id(idstr) : instance_id; @@ -1153,7 +1239,7 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque) if (path) { pstrcpy(id, sizeof(id), path); pstrcat(id, sizeof(id), "/"); - qemu_free(path); + g_free(path); } } pstrcat(id, sizeof(id), idstr); @@ -1162,34 +1248,9 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque) if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) { QTAILQ_REMOVE(&savevm_handlers, se, entry); if (se->compat) { - qemu_free(se->compat); + g_free(se->compat); } - qemu_free(se); - } - } -} - -/* mark a device as not to be migrated, that is the device should be - unplugged before migration */ -void register_device_unmigratable(DeviceState *dev, const char *idstr, - void *opaque) -{ - SaveStateEntry *se; - char id[256] = ""; - - if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) { - char *path = dev->parent_bus->info->get_dev_path(dev); - if (path) { - pstrcpy(id, sizeof(id), path); - pstrcat(id, sizeof(id), "/"); - qemu_free(path); - } - } - pstrcat(id, sizeof(id), idstr); - - QTAILQ_FOREACH(se, &savevm_handlers, entry) { - if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) { - se->no_migrate = 1; + g_free(se); } } } @@ -1204,7 +1265,7 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, /* If this triggers, alias support can be dropped for the vmsd. */ assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id); - se = qemu_mallocz(sizeof(SaveStateEntry)); + se = g_malloc0(sizeof(SaveStateEntry)); se->version_id = vmsd->version_id; se->section_id = global_section_id++; se->save_live_state = NULL; @@ -1213,15 +1274,16 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, se->opaque = opaque; se->vmsd = vmsd; se->alias_id = alias_id; + se->no_migrate = vmsd->unmigratable; if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) { char *id = dev->parent_bus->info->get_dev_path(dev); if (id) { pstrcpy(se->idstr, sizeof(se->idstr), id); pstrcat(se->idstr, sizeof(se->idstr), "/"); - qemu_free(id); + g_free(id); - se->compat = qemu_mallocz(sizeof(CompatEntry)); + se->compat = g_malloc0(sizeof(CompatEntry)); pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name); se->compat->instance_id = instance_id == -1 ? calculate_compat_instance_id(vmsd->name) : instance_id; @@ -1257,9 +1319,9 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, if (se->vmsd == vmsd && se->opaque == opaque) { QTAILQ_REMOVE(&savevm_handlers, se, entry); if (se->compat) { - qemu_free(se->compat); + g_free(se->compat); } - qemu_free(se); + g_free(se); } } } @@ -1308,8 +1370,12 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, n_elems = field->num; } else if (field->flags & VMS_VARRAY_INT32) { n_elems = *(int32_t *)(opaque+field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT32) { + n_elems = *(uint32_t *)(opaque+field->num_offset); } else if (field->flags & VMS_VARRAY_UINT16) { n_elems = *(uint16_t *)(opaque+field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT8) { + n_elems = *(uint8_t *)(opaque+field->num_offset); } if (field->flags & VMS_POINTER) { base_addr = *(void **)base_addr + field->start; @@ -1370,6 +1436,8 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, n_elems = *(int32_t *)(opaque+field->num_offset); } else if (field->flags & VMS_VARRAY_UINT16) { n_elems = *(uint16_t *)(opaque+field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT8) { + n_elems = *(uint8_t *)(opaque+field->num_offset); } if (field->flags & VMS_POINTER) { base_addr = *(void **)base_addr + field->start; @@ -1400,15 +1468,13 @@ static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id) return vmstate_load_state(f, se->vmsd, se->opaque, version_id); } -static int vmstate_save(QEMUFile *f, SaveStateEntry *se) +static void vmstate_save(QEMUFile *f, SaveStateEntry *se) { if (!se->vmsd) { /* Old style */ se->save_state(f, se->opaque); - return 0; + return; } vmstate_save_state(f,se->vmsd, se->opaque); - - return 0; } #define QEMU_VM_FILE_MAGIC 0x5145564d @@ -1440,13 +1506,7 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, int shared) { SaveStateEntry *se; - int dev = 0; - QTAILQ_FOREACH(se, &savevm_handlers, entry) { - if (se->save_live_state || se->vmsd) { - dev++; - } - } - monitor_printf(mon, "Device_Count=%d\n", dev); + int ret; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if(se->set_params == NULL) { @@ -1458,7 +1518,6 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, qemu_put_be32(f, QEMU_VM_FILE_MAGIC); qemu_put_be32(f, QEMU_VM_FILE_VERSION); - dev = 0; QTAILQ_FOREACH(se, &savevm_handlers, entry) { int len; @@ -1476,23 +1535,32 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, qemu_put_be32(f, se->instance_id); qemu_put_be32(f, se->version_id); - - dev++; - se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque); - } - if (qemu_file_has_error(f)) { + ret = se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque); + if (ret < 0) { + qemu_savevm_state_cancel(mon, f); + return ret; + } + } + ret = qemu_file_get_error(f); + if (ret != 0) { qemu_savevm_state_cancel(mon, f); - return -EIO; } - return 0; + return ret; + } +/* + * this funtion has three return values: + * negative: there was one error, and we have -errno. + * 0 : We haven't finished, caller have to go again + * 1 : We have finished, we can go to complete phase + */ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) { SaveStateEntry *se; - int ret = 1, dev = 0; + int ret = 1; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if (se->save_live_state == NULL) @@ -1501,10 +1569,9 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) /* Section type */ qemu_put_byte(f, QEMU_VM_SECTION_PART); qemu_put_be32(f, se->section_id); - - dev++; + ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque); - if (!ret) { + if (ret <= 0) { /* Do not proceed to the next vmstate before this one reported completion of the current stage. This serializes the migration and reduces the probability that a faster changing state is @@ -1512,23 +1579,21 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) break; } } - - if (ret) - return 1; - - if (qemu_file_has_error(f)) { + if (ret != 0) { + return ret; + } + ret = qemu_file_get_error(f); + if (ret != 0) { qemu_savevm_state_cancel(mon, f); - return -EIO; } - - return 0; + return ret; } int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) { SaveStateEntry *se; - int r; - int dev = 0; + int ret; + cpu_synchronize_all_states(); QTAILQ_FOREACH(se, &savevm_handlers, entry) { @@ -1538,12 +1603,13 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) /* Section type */ qemu_put_byte(f, QEMU_VM_SECTION_END); qemu_put_be32(f, se->section_id); - - dev++; - se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque); + + ret = se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque); + if (ret < 0) { + return ret; + } } - dev = 0; QTAILQ_FOREACH(se, &savevm_handlers, entry) { int len; @@ -1561,24 +1627,13 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) qemu_put_be32(f, se->instance_id); qemu_put_be32(f, se->version_id); - - dev++; - r = vmstate_save(f, se); - if (r < 0) { - monitor_printf(mon, "cannot migrate with device '%s'\n", se->idstr); - return r; - } - monitor_printf(mon, "Device_Completed:%d:name:%s\n", dev, se->idstr); - } - - monitor_printf(mon, "SaveVM Complete\n"); - - qemu_put_byte(f, QEMU_VM_EOF); - if (qemu_file_has_error(f)) - return -EIO; + vmstate_save(f, se); + } - return 0; + qemu_put_byte(f, QEMU_VM_EOF); + + return qemu_file_get_error(f); } void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f) @@ -1594,12 +1649,8 @@ void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f) static int qemu_savevm_state(Monitor *mon, QEMUFile *f) { - int saved_vm_running; int ret; - saved_vm_running = vm_running; - vm_stop(0); - if (qemu_savevm_state_blocked(mon)) { ret = -EINVAL; goto out; @@ -1618,11 +1669,9 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f) ret = qemu_savevm_state_complete(mon, f); out: - if (qemu_file_has_error(f)) - ret = -EIO; - - if (!ret && saved_vm_running) - vm_start(); + if (ret == 0) { + ret = qemu_file_get_error(f); + } return ret; } @@ -1661,29 +1710,36 @@ static const VMStateDescription *vmstate_get_subsection(const VMStateSubsection static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, void *opaque) { - const VMStateSubsection *sub = vmsd->subsections; - - if (!sub || !sub->needed) { - return 0; - } - - while (qemu_peek_byte(f) == QEMU_VM_SUBSECTION) { + while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) { char idstr[256]; int ret; - uint8_t version_id, len; + uint8_t version_id, len, size; const VMStateDescription *sub_vmsd; - qemu_get_byte(f); /* subsection */ - len = qemu_get_byte(f); - qemu_get_buffer(f, (uint8_t *)idstr, len); - idstr[len] = 0; - version_id = qemu_get_be32(f); + len = qemu_peek_byte(f, 1); + if (len < strlen(vmsd->name) + 1) { + /* subsection name has be be "section_name/a" */ + return 0; + } + size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2); + if (size != len) { + return 0; + } + idstr[size] = 0; - sub_vmsd = vmstate_get_subsection(sub, idstr); + if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) { + /* it don't have a valid subsection name */ + return 0; + } + sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr); if (sub_vmsd == NULL) { return -ENOENT; } - assert(!sub_vmsd->subsections); + qemu_file_skip(f, 1); /* subsection */ + qemu_file_skip(f, 1); /* len */ + qemu_file_skip(f, len); /* idstr */ + version_id = qemu_get_be32(f); + ret = vmstate_load_state(f, sub_vmsd, opaque, version_id); if (ret) { return ret; @@ -1707,7 +1763,6 @@ static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, qemu_put_byte(f, len); qemu_put_buffer(f, (uint8_t *)vmsd->name, len); qemu_put_be32(f, vmsd->version_id); - assert(!vmsd->subsections); vmstate_save_state(f, vmsd, opaque); } sub++; @@ -1780,7 +1835,7 @@ int qemu_loadvm_state(QEMUFile *f) } /* Add entry */ - le = qemu_mallocz(sizeof(*le)); + le = g_malloc0(sizeof(*le)); le->se = se; le->section_id = section_id; @@ -1830,11 +1885,12 @@ int qemu_loadvm_state(QEMUFile *f) out: QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) { QLIST_REMOVE(le, entry); - qemu_free(le); + g_free(le); } - if (qemu_file_has_error(f)) - ret = -EIO; + if (ret == 0) { + ret = qemu_file_get_error(f); + } return ret; } @@ -1857,7 +1913,7 @@ static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, break; } } - qemu_free(sn_tab); + g_free(sn_tab); return ret; } @@ -1909,7 +1965,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) bs = NULL; while ((bs = bdrv_next(bs))) { - if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) { + if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { continue; } @@ -1926,8 +1982,8 @@ void do_savevm(Monitor *mon, const QDict *qdict) return; } - saved_vm_running = vm_running; - vm_stop(0); + saved_vm_running = runstate_is_running(); + vm_stop(RUN_STATE_SAVE_VM); memset(sn, 0, sizeof(*sn)); @@ -1941,7 +1997,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) sn->date_sec = tv.tv_sec; sn->date_nsec = tv.tv_usec * 1000; #endif - sn->vm_clock_nsec = qemu_get_clock(vm_clock); + sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock); if (name) { ret = bdrv_snapshot_find(bs, old_sn, name); @@ -2019,6 +2075,8 @@ int load_vmstate(const char *name) if (ret < 0) { return ret; } else if (sn.vm_state_size == 0) { + error_report("This is a disk-only snapshot. Revert to it offline " + "using qemu-img."); return -EINVAL; } @@ -2027,7 +2085,7 @@ int load_vmstate(const char *name) bs = NULL; while ((bs = bdrv_next(bs))) { - if (bdrv_is_removable(bs) || bdrv_is_read_only(bs)) { + if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { continue; } @@ -2067,6 +2125,7 @@ int load_vmstate(const char *name) return -EINVAL; } + qemu_system_reset(VMRESET_SILENT); ret = qemu_loadvm_state(f); qemu_fclose(f); @@ -2133,7 +2192,7 @@ void do_info_snapshots(Monitor *mon) return; } - available_snapshots = qemu_mallocz(sizeof(int) * nb_sns); + available_snapshots = g_malloc0(sizeof(int) * nb_sns); total = 0; for (i = 0; i < nb_sns; i++) { sn = &sn_tab[i]; @@ -2166,7 +2225,7 @@ void do_info_snapshots(Monitor *mon) monitor_printf(mon, "There is no suitable snapshot available\n"); } - qemu_free(sn_tab); - qemu_free(available_snapshots); + g_free(sn_tab); + g_free(available_snapshots); } diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl old mode 100644 new mode 100755 index 4fa06c0..04ab990 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -859,7 +859,7 @@ sub annotate_values { $av_preprocessor = 0; } - } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) { + } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { print "CAST($1)\n" if ($dbg_values > 1); push(@av_paren_type, $type); $type = 'C'; @@ -1495,7 +1495,7 @@ sub process { next if ($realfile !~ /\.(h|c|pl)$/); # in QEMU, no tabs are allowed - if ($rawline =~ /\t/) { + if ($rawline =~ /^\+.*\t/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; ERROR("code indent should never use tabs\n" . $herevet); $rpt_cleaners = 1; @@ -2068,8 +2068,10 @@ sub process { } # , must have a space on the right. + # not required when having a single },{ on one line } elsif ($op eq ',') { - if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { + if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ && + ($elements[$n] . $elements[$n + 2]) !~ " *}{") { ERROR("space required after that '$op' $at\n" . $hereptr); } @@ -2204,12 +2206,6 @@ sub process { ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr); } -#goto labels aren't indented, allow a single space however - if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and - !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { - WARN("labels should not be indented\n" . $herecurr); - } - # Return is not a function. if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { my $spacing = $1; @@ -2530,13 +2526,14 @@ sub process { $allowed = 1; } } - if (!$seen) { + if ($seen != ($#chunks + 1)) { WARN("braces {} are necessary for all arms of this statement\n" . $herectx); } } } if (!defined $suppress_ifbraces{$linenr - 1} && $line =~ /\b(if|while|for|else)\b/ && + $line !~ /\#\s*if/ && $line !~ /\#\s*else/) { my $allowed = 0; diff --git a/scripts/create_config b/scripts/create_config old mode 100644 new mode 100755 diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh index c50beb7..83a44d8 100644 --- a/scripts/qemu-binfmt-conf.sh +++ b/scripts/qemu-binfmt-conf.sh @@ -1,5 +1,5 @@ #!/bin/sh -# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC program execution by the kernel +# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel # load the binfmt_misc module if [ ! -d /proc/sys/fs/binfmt_misc ]; then @@ -63,4 +63,6 @@ fi if [ $cpu != "sh" ] ; then echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register +if [ $cpu != "s390x" ] ; then + echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register fi diff --git a/scripts/signrom.sh b/scripts/signrom.sh old mode 100644 new mode 100755 diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py old mode 100644 new mode 100755 index 553a727..f55e5e6 --- a/scripts/simpletrace.py +++ b/scripts/simpletrace.py @@ -9,30 +9,27 @@ # # For help see docs/tracing.txt -import sys import struct import re +import inspect header_event_id = 0xffffffffffffffff header_magic = 0xf2b177cb0aa429b4 header_version = 0 +dropped_event_id = 0xfffffffffffffffe trace_fmt = '=QQQQQQQQ' trace_len = struct.calcsize(trace_fmt) event_re = re.compile(r'(disable\s+)?([a-zA-Z0-9_]+)\(([^)]*)\).*') -def err(msg): - sys.stderr.write(msg + '\n') - sys.exit(1) - def parse_events(fobj): - """Parse a trace-events file.""" + """Parse a trace-events file into {event_num: (name, arg1, ...)}.""" def get_argnames(args): """Extract argument names from a parameter list.""" return tuple(arg.split()[-1].lstrip('*') for arg in args.split(',')) - events = {} + events = {dropped_event_id: ('dropped', 'count')} event_num = 0 for line in fobj: m = event_re.match(line.strip()) @@ -45,20 +42,20 @@ def parse_events(fobj): return events def read_record(fobj): - """Deserialize a trace record from a file.""" + """Deserialize a trace record from a file into a tuple (event_num, timestamp, arg1, ..., arg6).""" s = fobj.read(trace_len) if len(s) != trace_len: return None return struct.unpack(trace_fmt, s) def read_trace_file(fobj): - """Deserialize trace records from a file.""" + """Deserialize trace records from a file, yielding record tuples (event_num, timestamp, arg1, ..., arg6).""" header = read_record(fobj) if header is None or \ header[0] != header_event_id or \ header[1] != header_magic or \ header[2] != header_version: - err('not a trace file or incompatible version') + raise ValueError('not a trace file or incompatible version') while True: rec = read_record(fobj) @@ -67,27 +64,88 @@ def read_trace_file(fobj): yield rec -class Formatter(object): - def __init__(self, events): - self.events = events - self.last_timestamp = None - - def format_record(self, rec): - if self.last_timestamp is None: - self.last_timestamp = rec[1] - delta_ns = rec[1] - self.last_timestamp - self.last_timestamp = rec[1] - - event = self.events[rec[0]] - fields = [event[0], '%0.3f' % (delta_ns / 1000.0)] - for i in xrange(1, len(event)): - fields.append('%s=0x%x' % (event[i], rec[i + 1])) - return ' '.join(fields) - -if len(sys.argv) != 3: - err('usage: %s ' % sys.argv[0]) - -events = parse_events(open(sys.argv[1], 'r')) -formatter = Formatter(events) -for rec in read_trace_file(open(sys.argv[2], 'rb')): - print formatter.format_record(rec) +class Analyzer(object): + """A trace file analyzer which processes trace records. + + An analyzer can be passed to run() or process(). The begin() method is + invoked, then each trace record is processed, and finally the end() method + is invoked. + + If a method matching a trace event name exists, it is invoked to process + that trace record. Otherwise the catchall() method is invoked.""" + + def begin(self): + """Called at the start of the trace.""" + pass + + def catchall(self, event, rec): + """Called if no specific method for processing a trace event has been found.""" + pass + + def end(self): + """Called at the end of the trace.""" + pass + +def process(events, log, analyzer): + """Invoke an analyzer on each event in a log.""" + if isinstance(events, str): + events = parse_events(open(events, 'r')) + if isinstance(log, str): + log = open(log, 'rb') + + def build_fn(analyzer, event): + fn = getattr(analyzer, event[0], None) + if fn is None: + return analyzer.catchall + + event_argcount = len(event) - 1 + fn_argcount = len(inspect.getargspec(fn)[0]) - 1 + if fn_argcount == event_argcount + 1: + # Include timestamp as first argument + return lambda _, rec: fn(*rec[1:2 + event_argcount]) + else: + # Just arguments, no timestamp + return lambda _, rec: fn(*rec[2:2 + event_argcount]) + + analyzer.begin() + fn_cache = {} + for rec in read_trace_file(log): + event_num = rec[0] + event = events[event_num] + if event_num not in fn_cache: + fn_cache[event_num] = build_fn(analyzer, event) + fn_cache[event_num](event, rec) + analyzer.end() + +def run(analyzer): + """Execute an analyzer on a trace file given on the command-line. + + This function is useful as a driver for simple analysis scripts. More + advanced scripts will want to call process() instead.""" + import sys + + if len(sys.argv) != 3: + sys.stderr.write('usage: %s \n' % sys.argv[0]) + sys.exit(1) + + events = parse_events(open(sys.argv[1], 'r')) + process(events, sys.argv[2], analyzer) + +if __name__ == '__main__': + class Formatter(Analyzer): + def __init__(self): + self.last_timestamp = None + + def catchall(self, event, rec): + timestamp = rec[1] + if self.last_timestamp is None: + self.last_timestamp = timestamp + delta_ns = timestamp - self.last_timestamp + self.last_timestamp = timestamp + + fields = [event[0], '%0.3f' % (delta_ns / 1000.0)] + for i in xrange(1, len(event)): + fields.append('%s=0x%x' % (event[i], rec[i + 1])) + print ' '.join(fields) + + run(Formatter()) diff --git a/scripts/texi2pod.pl b/scripts/texi2pod.pl old mode 100644 new mode 100755 diff --git a/scripts/tracetool b/scripts/tracetool old mode 100644 new mode 100755 index e046683..4c9951d --- a/scripts/tracetool +++ b/scripts/tracetool @@ -30,18 +30,48 @@ Output formats: --stap Generate .stp file (DTrace with SystemTAP only) Options: - --binary [path] Full path to QEMU binary - --target-arch [arch] QEMU emulator target arch - --target-type [type] QEMU emulator target type ('system' or 'user') + --binary [path] Full path to QEMU binary + --target-arch [arch] QEMU emulator target arch + --target-type [type] QEMU emulator target type ('system' or 'user') + --probe-prefix [prefix] Prefix for dtrace probe names + (default: qemu-\$targettype-\$targetarch) EOF exit 1 } +# Print a line without interpreting backslash escapes +# +# The built-in echo command may interpret backslash escapes without an option +# to disable this behavior. +puts() +{ + printf "%s\n" "$1" +} + # Get the name of a trace event get_name() { - echo ${1%%\(*} + local name + name=${1%%\(*} + echo "${name##* }" +} + +# Get the given property of a trace event +# 1: trace-events line +# 2: property name +# -> return 0 if property is present, or 1 otherwise +has_property() +{ + local props prop + props=${1%%\(*} + props=${props% *} + for prop in $props; do + if [ "$prop" = "$2" ]; then + return 0 + fi + done + return 1 } # Get the argument list of a trace event, including types and names @@ -49,7 +79,7 @@ get_args() { local args args=${1#*\(} - args=${args%\)*} + args=${args%%\)*} echo "$args" } @@ -90,27 +120,10 @@ get_argc() echo $argc } -# Get the format string for a trace event +# Get the format string including double quotes for a trace event get_fmt() { - local fmt - fmt=${1#*\"} - fmt=${fmt%\"*} - echo "$fmt" -} - -# Get the state of a trace event -get_state() -{ - local str disable state - str=$(get_name "$1") - disable=${str##disable } - if [ "$disable" = "$str" ] ; then - state=1 - else - state=0 - fi - echo "$state" + puts "${1#*)}" } linetoh_begin_nop() @@ -156,7 +169,7 @@ linetoc_end_nop() linetoh_begin_simple() { cat < +#include "trace/stderr.h" + +extern TraceEvent trace_list[]; EOF + + stderr_event_num=0 } linetoh_stderr() @@ -261,29 +271,47 @@ linetoh_stderr() cat < -#include -#include -#else /* !_WIN32 */ -#include -#include -#include -#include -#include -#endif /* !_WIN32 */ - -#include "net/slirp.h" -#include "qemu_socket.h" -#include "sdb.h" -#include "nbd.h" -#include "tizen/src/debug_ch.h" - -//DEFAULT_DEBUG_CHANNEL(qemu); -MULTI_DEBUG_CHANNEL(qemu, sdb); - -/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty - * easily in QEMU since we use SIGALRM to implement periodic timers - */ - -#ifdef _WIN32 -# define QSOCKET_CALL(_ret,_cmd) \ - do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR ) -#else -# define QSOCKET_CALL(_ret,_cmd) \ - do { \ - errno = 0; \ - do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \ - } while (0); -#endif - -#ifdef _WIN32 - -#include - -static int winsock_error; - -#define WINSOCK_ERRORS_LIST \ - EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \ -EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \ -EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \ -EE(WSAEINTR,EINTR,"interrupted function call") \ -EE(WSAEALREADY,EALREADY,"operation already in progress") \ -EE(WSAEBADF,EBADF,"bad file descriptor") \ -EE(WSAEACCES,EACCES,"permission denied") \ -EE(WSAEFAULT,EFAULT,"bad address") \ -EE(WSAEINVAL,EINVAL,"invalid argument") \ -EE(WSAEMFILE,EMFILE,"too many opened files") \ -EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \ -EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \ -EE(WSAEALREADY,EAGAIN,"operation already in progress") \ -EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \ -EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \ -EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \ -EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \ -EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \ -EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \ -EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \ -EE(WSAENETDOWN,ENETDOWN,"network is down") \ -EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \ -EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \ -EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \ -EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \ -EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \ -EE(WSAEISCONN,EISCONN,"socket is already connected") \ -EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \ -EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \ -EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \ -EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \ -EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \ -EE(WSAELOOP,ELOOP,"cannot translate name") \ -EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \ -EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \ -EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \ - -typedef struct { - int winsock; - int unix; - const char* string; -} WinsockError; - -static const WinsockError _winsock_errors[] = { -#define EE(w,u,s) { w, u, s }, - WINSOCK_ERRORS_LIST -#undef EE - { -1, -1, NULL } -}; - -/* this function reads the latest winsock error code and updates - * errno to a matching value. It also returns the new value of - * errno. - */ -static int _fix_errno( void ) -{ - const WinsockError* werr = _winsock_errors; - int unix = EINVAL; /* generic error code */ - - winsock_error = WSAGetLastError(); - - for ( ; werr->string != NULL; werr++ ) { - if (werr->winsock == winsock_error) { - unix = werr->unix; - break; - } - } - errno = unix; - return -1; -} - -#else -static int _fix_errno( void ) -{ - return -1; -} - -#endif - -#define SOCKET_CALL(cmd) \ - int ret; \ -QSOCKET_CALL(ret, (cmd)); \ -if (ret < 0) \ -return _fix_errno(); \ -return ret; \ - -int socket_send(int fd, const void* buf, int buflen) -{ - SOCKET_CALL(send(fd, buf, buflen, 0)) -} - -#ifdef _WIN32 - - static void -socket_close_handler( void* _fd ) -{ - int fd = (int)_fd; - int ret; - char buff[64]; - - /* we want to drain the read side of the socket before closing it */ - do { - ret = recv( fd, buff, sizeof(buff), 0 ); - } while (ret < 0 && WSAGetLastError() == WSAEINTR); - - if (ret < 0 && WSAGetLastError() == EWOULDBLOCK) - return; - - qemu_set_fd_handler( fd, NULL, NULL, NULL ); - closesocket( fd ); -} - - void -socket_close( int fd ) -{ - int old_errno = errno; - - shutdown( fd, SD_BOTH ); - /* we want to drain the socket before closing it */ - qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd ); - - errno = old_errno; -} - -#else /* !_WIN32 */ - -#include - - void -socket_close( int fd ) -{ - int old_errno = errno; - - shutdown( fd, SHUT_RDWR ); - close( fd ); - - errno = old_errno; -} - -#endif /* !_WIN32 */ - -int inet_strtoip(const char* str, uint32_t *ip) -{ - int comp[4]; - - if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4) - return -1; - - if ((unsigned)comp[0] >= 256 || - (unsigned)comp[1] >= 256 || - (unsigned)comp[2] >= 256 || - (unsigned)comp[3] >= 256) - return -1; - - *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) | - (comp[2] << 8) | comp[3]); - return 0; -} - -static int check_port_bind_listen(u_int port) -{ - struct sockaddr_in addr; - int s, opt = 1; - int ret = -1; - socklen_t addrlen = sizeof(addr); - memset(&addr, 0, addrlen); - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(port); - - if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) || - (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || - (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || - (listen(s,1) < 0)) { - - /* fail */ - ret = -1; - ERR( "port(%d) listen fail \n", port); - }else{ - /*fsucess*/ - ret = 1; - INFO( "port(%d) listen ok \n", port); - } - -#ifdef _WIN32 - closesocket(s); -#else - close(s); -#endif - - return ret; -} - -int get_sdb_base_port(void) -{ - int tries = 10; - int success = 0; - u_int port = 26100; - - if(tizen_base_port == 0){ - - for ( ; tries > 0; tries--, port += 10 ) { - if(check_port_bind_listen(port+1) < 0 ) - continue; - - success = 1; - break; - } - - if (!success) { - ERR( "it seems too many emulator instances are running on this machine. Aborting\n" ); - exit(1); - } - - tizen_base_port = port; - INFO( "sdb port is %d \n", tizen_base_port); - } - - return tizen_base_port; -} - -void sdb_setup(void) -{ - int tries = 10; - const char *base_port = "26100"; - int success = 0; - int s; - int port; - uint32_t guest_ip; - const char *p; - char buf[64] = {0,}; - - inet_strtoip("10.0.2.16", &guest_ip); - - port = strtol(base_port, (char **)&p, 0); - - for ( ; tries > 0; tries--, port += 10 ) { - // redir form [tcp:26100:10.0.2.16:26101] - sprintf(buf, "tcp:%d:10.0.2.16:26101", port+1); - if(net_slirp_redir((char*)buf) < 0) - continue; - - // fprintf(stdout,"SDBD established on port %d\n", port+1); - success = 1; - break; - } - - INFO("redirect [%s] success\n", buf); - if (!success) { - ERR( "it seems too many emulator instances are running on this machine. Aborting\n" ); - exit(1); - } - - if( tizen_base_port != port ){ - ERR( "sdb port is miss match. Aborting\n" ); - exit(1); - } - - /* Save base port. */ - tizen_base_port = port; - INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1); - - /* for sensort */ - sprintf(buf, "tcp:%d:10.0.2.16:3577", get_sdb_base_port() + SDB_TCP_EMULD_INDEX ); - if(net_slirp_redir((char*)buf) < 0){ - ERR( "redirect [%s] fail \n", buf); - }else{ - INFO("redirect [%s] success\n", buf); - } - - /* send a simple message to the SDB host server to tell it we just started. - * it should be listening on port 26099. if we can't reach it, don't bother - */ - do - { - char tmp[32] = {0}; - - s = tcp_socket_outgoing("127.0.0.1", SDB_HOST_PORT); - if (s < 0) { - INFO("can't create socket to talk to the SDB server \n"); - INFO("This emulator will be scaned by the SDB server \n"); - break; - } - - /* length is hex: 0x13 = 19 */ - sprintf(tmp,"0013host:emulator:%d",port+1); - socket_send(s, tmp, 30); - - } - while (0); - - if (s >= 0) - socket_close(s); -} diff --git a/sdb.h b/sdb.h deleted file mode 100644 index c4ec1fb..0000000 --- a/sdb.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) 2006-2010 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** 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. -*/ - -#include -#include -#include - -#define SDB_HOST_PORT 26099 - -#ifdef _WIN32 -# ifndef EINTR -# define EINTR 10004 -# endif -# ifndef EAGAIN -# define EAGAIN 10035 -# endif -# ifndef EWOULDBLOCK -# define EWOULDBLOCK EAGAIN -# endif -# ifndef EINPROGRESS -# define EINPROGRESS 10036 -# endif -# ifndef EALREADY -# define EALREADY 10037 -# endif -# ifndef EDESTADDRREQ -# define EDESTADDRREQ 10039 -# endif -# ifndef EMSGSIZE -# define EMSGSIZE 10040 -# endif -# ifndef EPROTOTYPE -# define EPROTOTYPE 10041 -# endif -# ifndef ENOPROTOOPT -# define ENOPROTOOPT 10042 -# endif -# ifndef EAFNOSUPPORT -# define EAFNOSUPPORT 10047 -# endif -# ifndef EADDRINUSE -# define EADDRINUSE 10048 -# endif -# ifndef EADDRNOTAVAIL -# define EADDRNOTAVAIL 10049 -# endif -# ifndef ENETDOWN -# define ENETDOWN 10050 -# endif -# ifndef ENETUNREACH -# define ENETUNREACH 10051 -# endif -# ifndef ENETRESET -# define ENETRESET 10052 -# endif -# ifndef ECONNABORTED -# define ECONNABORTED 10053 -# endif -# ifndef ECONNRESET -# define ECONNRESET 10054 -# endif -# ifndef ENOBUFS -# define ENOBUFS 10055 -# endif -# ifndef EISCONN -# define EISCONN 10056 -# endif -# ifndef ENOTCONN -# define ENOTCONN 10057 -# endif -# ifndef ESHUTDOWN -# define ESHUTDOWN 10058 -# endif -# ifndef ETOOMANYREFS -# define ETOOMANYREFS 10059 -# endif -# ifndef ETIMEDOUT -# define ETIMEDOUT 10060 -# endif -# ifndef ECONNREFUSED -# define ECONNREFUSED 10061 -# endif -# ifndef ELOOP -# define ELOOP 10062 -# endif -# ifndef EHOSTDOWN -# define EHOSTDOWN 10064 -# endif -# ifndef EHOSTUNREACH -# define EHOSTUNREACH 10065 -# endif -#endif /* _WIN32 */ - -#define SDB_TCP_EMULD_INDEX 3 /* emulator daemon port */ -#define SDB_TCP_OPENGL_INDEX 4 /* opengl server port */ - -#define SDB_UDP_SENSOR_INDEX 3 /* sensor server port */ -extern int tizen_base_port; -void sdb_setup(void); -int get_sdb_base_port(void); -int inet_strtoip(const char* str, uint32_t *ip); -int socket_send(int fd, const void* buf, int buflen); -void socket_close(int fd); diff --git a/simpletrace.c b/simpletrace.c deleted file mode 100644 index 9ea0d1f..0000000 --- a/simpletrace.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Simple trace backend - * - * Copyright IBM, Corp. 2010 - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include -#include -#include -#include -#include "qemu-timer.h" -#include "trace.h" - -/** Trace file header event ID */ -#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */ - -/** Trace file magic number */ -#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL - -/** Trace file version number, bump if format changes */ -#define HEADER_VERSION 0 - -/** Trace buffer entry */ -typedef struct { - uint64_t event; - uint64_t timestamp_ns; - uint64_t x1; - uint64_t x2; - uint64_t x3; - uint64_t x4; - uint64_t x5; - uint64_t x6; -} TraceRecord; - -enum { - TRACE_BUF_LEN = 64 * 1024 / sizeof(TraceRecord), -}; - -static TraceRecord trace_buf[TRACE_BUF_LEN]; -static unsigned int trace_idx; -static FILE *trace_fp; -static char *trace_file_name = NULL; -static bool trace_file_enabled = false; - -void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) -{ - stream_printf(stream, "Trace file \"%s\" %s.\n", - trace_file_name, trace_file_enabled ? "on" : "off"); -} - -static bool write_header(FILE *fp) -{ - static const TraceRecord header = { - .event = HEADER_EVENT_ID, - .timestamp_ns = HEADER_MAGIC, - .x1 = HEADER_VERSION, - }; - - return fwrite(&header, sizeof header, 1, fp) == 1; -} - -/** - * set_trace_file : To set the name of a trace file. - * @file : pointer to the name to be set. - * If NULL, set to the default name- set at config time. - */ -bool st_set_trace_file(const char *file) -{ - st_set_trace_file_enabled(false); - - free(trace_file_name); - - if (!file) { - if (asprintf(&trace_file_name, CONFIG_TRACE_FILE, getpid()) < 0) { - trace_file_name = NULL; - return false; - } - } else { - if (asprintf(&trace_file_name, "%s", file) < 0) { - trace_file_name = NULL; - return false; - } - } - - st_set_trace_file_enabled(true); - return true; -} - -static void flush_trace_file(void) -{ - /* If the trace file is not open yet, open it now */ - if (!trace_fp) { - trace_fp = fopen(trace_file_name, "w"); - if (!trace_fp) { - /* Avoid repeatedly trying to open file on failure */ - trace_file_enabled = false; - return; - } - write_header(trace_fp); - } - - if (trace_fp) { - size_t unused; /* for when fwrite(3) is declared warn_unused_result */ - unused = fwrite(trace_buf, trace_idx * sizeof(trace_buf[0]), 1, trace_fp); - } -} - -void st_flush_trace_buffer(void) -{ - if (trace_file_enabled) { - flush_trace_file(); - } - - /* Discard written trace records */ - trace_idx = 0; -} - -void st_set_trace_file_enabled(bool enable) -{ - if (enable == trace_file_enabled) { - return; /* no change */ - } - - /* Flush/discard trace buffer */ - st_flush_trace_buffer(); - - /* To disable, close trace file */ - if (!enable) { - fclose(trace_fp); - trace_fp = NULL; - } - - trace_file_enabled = enable; -} - -static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, - uint64_t x4, uint64_t x5, uint64_t x6) -{ - TraceRecord *rec = &trace_buf[trace_idx]; - - if (!trace_list[event].state) { - return; - } - - rec->event = event; - rec->timestamp_ns = get_clock(); - rec->x1 = x1; - rec->x2 = x2; - rec->x3 = x3; - rec->x4 = x4; - rec->x5 = x5; - rec->x6 = x6; - - if (++trace_idx == TRACE_BUF_LEN) { - st_flush_trace_buffer(); - } -} - -void trace0(TraceEventID event) -{ - trace(event, 0, 0, 0, 0, 0, 0); -} - -void trace1(TraceEventID event, uint64_t x1) -{ - trace(event, x1, 0, 0, 0, 0, 0); -} - -void trace2(TraceEventID event, uint64_t x1, uint64_t x2) -{ - trace(event, x1, x2, 0, 0, 0, 0); -} - -void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3) -{ - trace(event, x1, x2, x3, 0, 0, 0); -} - -void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4) -{ - trace(event, x1, x2, x3, x4, 0, 0); -} - -void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5) -{ - trace(event, x1, x2, x3, x4, x5, 0); -} - -void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6) -{ - trace(event, x1, x2, x3, x4, x5, x6); -} - -/** - * Flush the trace buffer on exit - */ -static void __attribute__((constructor)) st_init(void) -{ - atexit(st_flush_trace_buffer); -} - -void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) -{ - unsigned int i; - - for (i = 0; i < trace_idx; i++) { - stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64 - " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n", - trace_buf[i].event, trace_buf[i].x1, trace_buf[i].x2, - trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5, - trace_buf[i].x6); - } -} - -void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) -{ - unsigned int i; - - for (i = 0; i < NR_TRACE_EVENTS; i++) { - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_list[i].tp_name, i, trace_list[i].state); - } -} - -static TraceEvent* find_trace_event_by_name(const char *tname) -{ - unsigned int i; - - if (!tname) { - return NULL; - } - - for (i = 0; i < NR_TRACE_EVENTS; i++) { - if (!strcmp(trace_list[i].tp_name, tname)) { - return &trace_list[i]; - } - } - return NULL; /* indicates end of list reached without a match */ -} - -bool st_change_trace_event_state(const char *tname, bool tstate) -{ - TraceEvent *tp; - - tp = find_trace_event_by_name(tname); - if (tp) { - tp->state = tstate; - return true; - } - return false; -} diff --git a/simpletrace.h b/simpletrace.h deleted file mode 100644 index 2f44ed3..0000000 --- a/simpletrace.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Simple trace backend - * - * Copyright IBM, Corp. 2010 - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#ifndef SIMPLETRACE_H -#define SIMPLETRACE_H - -#include -#include -#include - -typedef uint64_t TraceEventID; - -typedef struct { - const char *tp_name; - bool state; -} TraceEvent; - -void trace0(TraceEventID event); -void trace1(TraceEventID event, uint64_t x1); -void trace2(TraceEventID event, uint64_t x1, uint64_t x2); -void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3); -void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4); -void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5); -void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6); -void st_print_trace(FILE *stream, fprintf_function stream_printf); -void st_print_trace_events(FILE *stream, fprintf_function stream_printf); -bool st_change_trace_event_state(const char *tname, bool tstate); -void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf); -void st_set_trace_file_enabled(bool enable); -bool st_set_trace_file(const char *file); -void st_flush_trace_buffer(void); - -#endif /* SIMPLETRACE_H */ diff --git a/slirp/bootp.c b/slirp/bootp.c index 0905c6d..efd1fe7 100644 --- a/slirp/bootp.c +++ b/slirp/bootp.c @@ -149,6 +149,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) struct in_addr preq_addr; int dhcp_msg_type, val; uint8_t *q; + uint8_t client_ethaddr[ETH_ALEN]; /* extract exact DHCP msg type */ dhcp_decode(bp, &dhcp_msg_type, &preq_addr); @@ -164,8 +165,9 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) if (dhcp_msg_type != DHCPDISCOVER && dhcp_msg_type != DHCPREQUEST) return; - /* XXX: this is a hack to get the client mac address */ - memcpy(slirp->client_ethaddr, bp->bp_hwaddr, 6); + + /* Get client's hardware address from bootp request */ + memcpy(client_ethaddr, bp->bp_hwaddr, ETH_ALEN); m = m_get(slirp); if (!m) { @@ -178,25 +180,25 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) if (dhcp_msg_type == DHCPDISCOVER) { if (preq_addr.s_addr != htonl(0L)) { - bc = request_addr(slirp, &preq_addr, slirp->client_ethaddr); + bc = request_addr(slirp, &preq_addr, client_ethaddr); if (bc) { daddr.sin_addr = preq_addr; } } if (!bc) { new_addr: - bc = get_new_addr(slirp, &daddr.sin_addr, slirp->client_ethaddr); + bc = get_new_addr(slirp, &daddr.sin_addr, client_ethaddr); if (!bc) { DPRINTF("no address left\n"); return; } } - memcpy(bc->macaddr, slirp->client_ethaddr, 6); + memcpy(bc->macaddr, client_ethaddr, ETH_ALEN); } else if (preq_addr.s_addr != htonl(0L)) { - bc = request_addr(slirp, &preq_addr, slirp->client_ethaddr); + bc = request_addr(slirp, &preq_addr, client_ethaddr); if (bc) { daddr.sin_addr = preq_addr; - memcpy(bc->macaddr, slirp->client_ethaddr, 6); + memcpy(bc->macaddr, client_ethaddr, ETH_ALEN); } else { daddr.sin_addr.s_addr = 0; } @@ -209,6 +211,9 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) } } + /* Update ARP table for this IP address */ + arp_table_add(slirp, daddr.sin_addr.s_addr, client_ethaddr); + saddr.sin_addr = slirp->vhost_addr; saddr.sin_port = htons(BOOTP_SERVER); @@ -218,7 +223,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) rbp->bp_xid = bp->bp_xid; rbp->bp_htype = 1; rbp->bp_hlen = 6; - memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); + memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, ETH_ALEN); rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ @@ -284,7 +289,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) } else { static const char nak_msg[] = "requested address not available"; - DPRINTF("nak'ed addr=%08x\n", ntohl(preq_addr->s_addr)); + DPRINTF("nak'ed addr=%08x\n", ntohl(preq_addr.s_addr)); *q++ = RFC2132_MSG_TYPE; *q++ = 1; diff --git a/slirp/if.c b/slirp/if.c index 0f04e13..2852396 100644 --- a/slirp/if.c +++ b/slirp/if.c @@ -6,6 +6,7 @@ */ #include +#include "qemu-timer.h" #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) @@ -153,6 +154,8 @@ diddit: void if_start(Slirp *slirp) { + uint64_t now = qemu_get_clock_ns(rt_clock); + int requeued = 0; struct mbuf *ifm, *ifqt; DEBUG_CALL("if_start"); @@ -199,11 +202,22 @@ if_start(Slirp *slirp) ifm->ifq_so->so_nqueued = 0; } - /* Encapsulate the packet for sending */ - if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len); - - m_free(ifm); + if (ifm->expiration_date < now) { + /* Expired */ + m_free(ifm); + } else { + /* Encapsulate the packet for sending */ + if (if_encap(slirp, ifm)) { + m_free(ifm); + } else { + /* re-queue */ + insque(ifm, ifqt); + requeued++; + } + } if (slirp->if_queued) goto again; + + slirp->if_queued = requeued; } diff --git a/slirp/ip.h b/slirp/ip.h index 48ea38e..88c903f 100644 --- a/slirp/ip.h +++ b/slirp/ip.h @@ -74,10 +74,10 @@ typedef uint32_t n_long; /* long as received from the net */ */ struct ip { #ifdef HOST_WORDS_BIGENDIAN - u_int ip_v:4, /* version */ + uint8_t ip_v:4, /* version */ ip_hl:4; /* header length */ #else - u_int ip_hl:4, /* header length */ + uint8_t ip_hl:4, /* header length */ ip_v:4; /* version */ #endif uint8_t ip_tos; /* type of service */ @@ -91,7 +91,7 @@ struct ip { uint8_t ip_p; /* protocol */ uint16_t ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ -} __attribute__((packed)); +} QEMU_PACKED; #define IP_MAXPACKET 65535 /* maximum packet size */ @@ -140,10 +140,10 @@ struct ip_timestamp { uint8_t ipt_len; /* size of structure (variable) */ uint8_t ipt_ptr; /* index of current entry */ #ifdef HOST_WORDS_BIGENDIAN - u_int ipt_oflw:4, /* overflow counter */ + uint8_t ipt_oflw:4, /* overflow counter */ ipt_flg:4; /* flags, see below */ #else - u_int ipt_flg:4, /* flags, see below */ + uint8_t ipt_flg:4, /* flags, see below */ ipt_oflw:4; /* overflow counter */ #endif union ipt_timestamp { @@ -153,7 +153,7 @@ struct ip_timestamp { n_long ipt_time; } ipt_ta[1]; } ipt_timestamp; -} __attribute__((packed)); +} QEMU_PACKED; /* flag bits for ipt_flg */ #define IPOPT_TS_TSONLY 0 /* timestamps only */ @@ -183,11 +183,11 @@ struct ip_timestamp { struct mbuf_ptr { struct mbuf *mptr; uint32_t dummy; -} __attribute__((packed)); +} QEMU_PACKED; #else struct mbuf_ptr { struct mbuf *mptr; -} __attribute__((packed)); +} QEMU_PACKED; #endif struct qlink { void *next, *prev; @@ -203,7 +203,7 @@ struct ipovly { uint16_t ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ -} __attribute__((packed)); +} QEMU_PACKED; /* * Ip reassembly queue structure. Each fragment @@ -219,7 +219,7 @@ struct ipq { uint8_t ipq_p; /* protocol of this fragment */ uint16_t ipq_id; /* sequence id for reassembly */ struct in_addr ipq_src,ipq_dst; -} __attribute__((packed)); +} QEMU_PACKED; /* * Ip header, when holding a fragment. @@ -229,7 +229,7 @@ struct ipq { struct ipasfrag { struct qlink ipf_link; struct ip ipf_ip; -} __attribute__((packed)); +} QEMU_PACKED; #define ipf_off ipf_ip.ip_off #define ipf_tos ipf_ip.ip_tos @@ -248,6 +248,6 @@ struct ipasfrag { struct ipoption { struct in_addr ipopt_dst; /* first-hop dst if source routed */ int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */ -} __attribute__((packed)); +} QEMU_PACKED; #endif diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c index 154884e..4b43994 100644 --- a/slirp/ip_icmp.c +++ b/slirp/ip_icmp.c @@ -60,59 +60,51 @@ static const int icmp_flush[19] = { /* ADDR MASK REPLY (18) */ 0 }; -int icmp_attach(struct socket *so); -void icmp_detach(struct socket *so); -int icmp_cksum(u_short *p, int n); - -int -icmp_attach(struct socket *so) +void icmp_init(Slirp *slirp) { - /* same as udp_attach except socket creation */ - if((so->s = qemu_socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) != -1) { - so->so_expire = curtime + SO_EXPIRE; - insque(so, &so->slirp->udb); - } - return(so->s); + slirp->icmp.so_next = slirp->icmp.so_prev = &slirp->icmp; + slirp->icmp_last_so = &slirp->icmp; } -void -icmp_detach(struct socket *so) +static int icmp_send(struct socket *so, struct mbuf *m, int hlen) { - /* same as udp_detach */ - closesocket(so->s); - sofree(so); + struct ip *ip = mtod(m, struct ip *); + struct sockaddr_in addr; + + so->s = qemu_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); + if (so->s == -1) { + return -1; + } + + so->so_m = m; + so->so_faddr = ip->ip_dst; + so->so_laddr = ip->ip_src; + so->so_iptos = ip->ip_tos; + so->so_type = IPPROTO_ICMP; + so->so_state = SS_ISFCONNECTED; + so->so_expire = curtime + SO_EXPIRE; + + addr.sin_family = AF_INET; + addr.sin_addr = so->so_faddr; + + insque(so, &so->slirp->icmp); + + if (sendto(so->s, m->m_data + hlen, m->m_len - hlen, 0, + (struct sockaddr *)&addr, sizeof(addr)) == -1) { + DEBUG_MISC((dfd, "icmp_input icmp sendto tx errno = %d-%s\n", + errno, strerror(errno))); + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); + icmp_detach(so); + } + + return 0; } -int -icmp_cksum(u_short *p, int n) +void icmp_detach(struct socket *so) { - register u_short answer; - register long sum = 0; - u_short odd_byte = 0; - - while( n > 1 ) - { - sum += *p++; - n -= 2; - - }/* WHILE */ - - - /* mop up an odd byte, if necessary */ - if( n == 1 ) - { - *( u_char* )( &odd_byte ) = *( u_char* )p; - sum += odd_byte; - - }/* IF */ - - sum = ( sum >> 16 ) + ( sum & 0xffff ); /* add hi 16 to low 16 */ - sum += ( sum >> 16 ); /* add carry */ - answer = ~sum; /* ones-complement, truncate*/ - - return ( answer ); - -} /* in_cksum() */ + closesocket(so->s); + sofree(so); +} /* * Process a received ICMP message. @@ -135,7 +127,7 @@ icmp_input(struct mbuf *m, int hlen) */ if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */ freeit: - m_freem(m); + m_free(m); goto end_error; } @@ -151,30 +143,19 @@ icmp_input(struct mbuf *m, int hlen) DEBUG_ARG("icmp_type = %d", icp->icmp_type); switch (icp->icmp_type) { case ICMP_ECHO: - icp->icmp_type = ICMP_ECHOREPLY; ip->ip_len += hlen; /* since ip_input subtracts this */ if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) { icmp_reflect(m); -#ifndef _WIN32 - } else if( getuid() != 0 ) { - char commands[64]; - int code; - - sprintf( commands, "ping -c 1 %s", inet_ntoa(ip->ip_dst) ); - code = system( commands ); - - if( WIFEXITED(code) && WEXITSTATUS(code) == 0 ) - icmp_reflect(m); - else - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, "ping failed"); -#endif + } else if (slirp->restricted) { + goto freeit; } else { - char icmp_buf[128] ; - struct icmp *picmp = (struct icmp *)icmp_buf; struct socket *so; struct sockaddr_in addr; if ((so = socreate(slirp)) == NULL) goto freeit; - if(icmp_attach(so) == -1) { + if (icmp_send(so, m, hlen) == 0) { + return; + } + if(udp_attach(so) == -1) { DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n", errno,strerror(errno))); sofree(so); @@ -205,21 +186,12 @@ icmp_input(struct mbuf *m, int hlen) addr.sin_addr = so->so_faddr; } addr.sin_port = so->so_fport; - - picmp->icmp_type = ICMP_ECHO; - picmp->icmp_code = 0; - picmp->icmp_cksum = 0; - picmp->icmp_id = icp->icmp_id; - picmp->icmp_seq = icp->icmp_seq; - strcpy(icmp_buf+8, icmp_ping_msg); - picmp->icmp_cksum = icmp_cksum((u_short *)picmp, sizeof(icmp_ping_msg)+8); - - if(sendto(so->s, picmp, sizeof(icmp_ping_msg)+8, 0, + if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0, (struct sockaddr *)&addr, sizeof(addr)) == -1) { DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n", errno,strerror(errno))); icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); - icmp_detach(so); + udp_detach(so); } } /* if ip->ip_dst.s_addr == alias_addr.s_addr */ break; @@ -231,11 +203,11 @@ icmp_input(struct mbuf *m, int hlen) case ICMP_TSTAMP: case ICMP_MASKREQ: case ICMP_REDIRECT: - m_freem(m); + m_free(m); break; default: - m_freem(m); + m_free(m); } /* swith */ end_error: @@ -397,6 +369,7 @@ icmp_reflect(struct mbuf *m) m->m_len -= hlen; icp = mtod(m, struct icmp *); + icp->icmp_type = ICMP_ECHOREPLY; icp->icmp_cksum = 0; icp->icmp_cksum = cksum(m, ip->ip_len - hlen); @@ -427,3 +400,39 @@ icmp_reflect(struct mbuf *m) (void ) ip_output((struct socket *)NULL, m); } + +void icmp_receive(struct socket *so) +{ + struct mbuf *m = so->so_m; + struct ip *ip = mtod(m, struct ip *); + int hlen = ip->ip_hl << 2; + u_char error_code; + struct icmp *icp; + int id, len; + + m->m_data += hlen; + m->m_len -= hlen; + icp = mtod(m, struct icmp *); + + id = icp->icmp_id; + len = qemu_recv(so->s, icp, m->m_len, 0); + icp->icmp_id = id; + + m->m_data -= hlen; + m->m_len += hlen; + + if (len == -1 || len == 0) { + if (errno == ENETUNREACH) { + error_code = ICMP_UNREACH_NET; + } else { + error_code = ICMP_UNREACH_HOST; + } + DEBUG_MISC((dfd, " udp icmp rx errno = %d-%s\n", errno, + strerror(errno))); + icmp_error(so->so_m, ICMP_UNREACH, error_code, 0, strerror(errno)); + } else { + icmp_reflect(so->so_m); + so->so_m = NULL; /* Don't m_free() it again! */ + } + icmp_detach(so); +} diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h index 2692822..b3da1f2 100644 --- a/slirp/ip_icmp.h +++ b/slirp/ip_icmp.h @@ -153,9 +153,12 @@ struct icmp { (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) +void icmp_init(Slirp *slirp); void icmp_input(struct mbuf *, int); void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, const char *message); void icmp_reflect(struct mbuf *); +void icmp_receive(struct socket *so); +void icmp_detach(struct socket *so); #endif diff --git a/slirp/ip_input.c b/slirp/ip_input.c index 768ab0c..c7b3eb4 100644 --- a/slirp/ip_input.c +++ b/slirp/ip_input.c @@ -58,6 +58,7 @@ ip_init(Slirp *slirp) slirp->ipq.ip_link.next = slirp->ipq.ip_link.prev = &slirp->ipq.ip_link; udp_init(slirp); tcp_init(slirp); + icmp_init(slirp); } /* @@ -118,27 +119,6 @@ ip_input(struct mbuf *m) goto bad; } - if (slirp->restricted) { - if ((ip->ip_dst.s_addr & slirp->vnetwork_mask.s_addr) == - slirp->vnetwork_addr.s_addr) { - if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP) - goto bad; - } else { - uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr; - struct ex_list *ex_ptr; - - if ((ip->ip_dst.s_addr & inv_mask) == inv_mask) { - goto bad; - } - for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) - if (ex_ptr->ex_addr.s_addr == ip->ip_dst.s_addr) - break; - - if (!ex_ptr) - goto bad; - } - } - /* Should drop packet if mbuf too long? hmmm... */ if (m->m_len > ip->ip_len) m_adj(m, ip->ip_len - m->m_len); @@ -225,7 +205,7 @@ ip_input(struct mbuf *m) } return; bad: - m_freem(m); + m_free(m); return; } @@ -318,7 +298,7 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp) break; } q = q->ipf_next; - m_freem(dtom(slirp, q->ipf_prev)); + m_free(dtom(slirp, q->ipf_prev)); ip_deq(q->ipf_prev); } @@ -384,7 +364,7 @@ insert: return ip; dropfrag: - m_freem(m); + m_free(m); return NULL; } @@ -400,7 +380,7 @@ ip_freef(Slirp *slirp, struct ipq *fp) for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) { p = q->ipf_next; ip_deq(q); - m_freem(dtom(slirp, q)); + m_free(dtom(slirp, q)); } remque(&fp->ip_link); (void) m_free(dtom(slirp, fp)); @@ -531,7 +511,7 @@ typedef uint32_t n_time; */ break; } - off--; / * 0 origin * / + off--; /* 0 origin */ if (off > optlen - sizeof(struct in_addr)) { /* * End of source route. Should be for us. @@ -574,7 +554,7 @@ typedef uint32_t n_time; /* * If no space remains, ignore. */ - off--; * 0 origin * + off--; /* 0 origin */ if (off > optlen - sizeof(struct in_addr)) break; bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr, diff --git a/slirp/ip_output.c b/slirp/ip_output.c index 542f318..c82830f 100644 --- a/slirp/ip_output.c +++ b/slirp/ip_output.c @@ -159,7 +159,7 @@ sendorfree: if (error == 0) if_output(so, m); else - m_freem(m); + m_free(m); } } @@ -167,6 +167,6 @@ done: return (error); bad: - m_freem(m0); + m_free(m0); goto done; } diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 67c70e3..890fd86 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -1,9 +1,7 @@ #ifndef _LIBSLIRP_H #define _LIBSLIRP_H -#include - -#ifdef CONFIG_SLIRP +#include "qemu-common.h" struct Slirp; typedef struct Slirp Slirp; @@ -44,13 +42,4 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port); -#else /* !CONFIG_SLIRP */ - -static inline void slirp_select_fill(int *pnfds, fd_set *readfds, - fd_set *writefds, fd_set *xfds) { } - -static inline void slirp_select_poll(fd_set *readfds, fd_set *writefds, - fd_set *xfds, int select_error) { } -#endif /* !CONFIG_SLIRP */ - #endif diff --git a/slirp/main.h b/slirp/main.h index 0dd8d81..028df4b 100644 --- a/slirp/main.h +++ b/slirp/main.h @@ -42,5 +42,5 @@ extern int tcp_keepintvl; #define PROTO_PPP 0x2 #endif -void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len); +int if_encap(Slirp *slirp, struct mbuf *ifm); ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags); diff --git a/slirp/mbuf.c b/slirp/mbuf.c index ce2eb84..c699c75 100644 --- a/slirp/mbuf.c +++ b/slirp/mbuf.c @@ -70,6 +70,8 @@ m_get(Slirp *slirp) m->m_len = 0; m->m_nextpkt = NULL; m->m_prevpkt = NULL; + m->arp_requested = false; + m->expiration_date = (uint64_t)-1; end_error: DEBUG_ARG("m = %lx", (long )m); return m; diff --git a/slirp/mbuf.h b/slirp/mbuf.h index 97729e2..0708840 100644 --- a/slirp/mbuf.h +++ b/slirp/mbuf.h @@ -33,9 +33,6 @@ #ifndef _MBUF_H_ #define _MBUF_H_ -#define m_freem m_free - - #define MINCSIZE 4096 /* Amount to increase mbuf if too small */ /* @@ -85,6 +82,9 @@ struct m_hdr { struct mbuf { struct m_hdr m_hdr; Slirp *slirp; + bool arp_requested; + uint64_t expiration_date; + /* start of dynamic buffer area, must be last element */ union M_dat { char m_dat_[1]; /* ANSI don't like 0 sized arrays */ char *m_ext_; diff --git a/slirp/misc.c b/slirp/misc.c index 19dbec4..6c80e69 100644 --- a/slirp/misc.c +++ b/slirp/misc.c @@ -119,6 +119,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) char *bptr; const char *curarg; int c, i, ret; + pid_t pid; DEBUG_CALL("fork_exec"); DEBUG_ARG("so = %lx", (long)so); @@ -142,7 +143,8 @@ fork_exec(struct socket *so, const char *ex, int do_pty) } } - switch(fork()) { + pid = fork(); + switch(pid) { case -1: lprint("Error: fork failed: %s\n", strerror(errno)); close(s); @@ -151,11 +153,12 @@ fork_exec(struct socket *so, const char *ex, int do_pty) return 0; case 0: + setsid(); + /* Set the DISPLAY */ if (do_pty == 2) { (void) close(master); #ifdef TIOCSCTTY /* XXXXX */ - (void) setsid(); ioctl(s, TIOCSCTTY, (char *)NULL); #endif } else { @@ -179,7 +182,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) close(s); i = 0; - bptr = qemu_strdup(ex); /* No need to free() this */ + bptr = g_strdup(ex); /* No need to free() this */ if (do_pty == 1) { /* Setup "slirp.telnetd -x" */ argv[i++] = "slirp.telnetd"; @@ -206,6 +209,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) exit(1); default: + qemu_add_child_watch(pid); if (do_pty == 2) { close(s); so->s = master; @@ -403,4 +407,17 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon) inet_ntoa(dst_addr), ntohs(dst_port), so->so_rcv.sb_cc, so->so_snd.sb_cc); } + + for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) { + n = snprintf(buf, sizeof(buf), " ICMP[%d sec]", + (so->so_expire - curtime) / 1000); + src.sin_addr = so->so_laddr; + dst_addr = so->so_faddr; + memset(&buf[n], ' ', 19 - n); + buf[19] = 0; + monitor_printf(mon, "%s %3d %15s - ", buf, so->s, + src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*"); + monitor_printf(mon, "%15s - %5d %5d\n", inet_ntoa(dst_addr), + so->so_rcv.sb_cc, so->so_snd.sb_cc); + } } diff --git a/slirp/slirp.c b/slirp/slirp.c index 332d83b..19d69eb 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -31,11 +31,11 @@ struct in_addr loopback_addr; /* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */ -static const uint8_t special_ethaddr[6] = { +static const uint8_t special_ethaddr[ETH_ALEN] = { 0x52, 0x55, 0x00, 0x00, 0x00, 0x00 }; -static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 }; +static const uint8_t zero_ethaddr[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; /* XXX: suppress those select globals */ fd_set *global_readfds, *global_writefds, *global_xfds; @@ -202,7 +202,7 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, const char *bootfile, struct in_addr vdhcp_start, struct in_addr vnameserver, void *opaque) { - Slirp *slirp = qemu_mallocz(sizeof(Slirp)); + Slirp *slirp = g_malloc0(sizeof(Slirp)); slirp_init_once(); @@ -222,10 +222,10 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, vhostname); } if (tftp_path) { - slirp->tftp_prefix = qemu_strdup(tftp_path); + slirp->tftp_prefix = g_strdup(tftp_path); } if (bootfile) { - slirp->bootp_filename = qemu_strdup(bootfile); + slirp->bootp_filename = g_strdup(bootfile); } slirp->vdhcp_startaddr = vdhcp_start; slirp->vnameserver_addr = vnameserver; @@ -246,9 +246,9 @@ void slirp_cleanup(Slirp *slirp) unregister_savevm(NULL, "slirp", slirp); - qemu_free(slirp->tftp_prefix); - qemu_free(slirp->bootp_filename); - qemu_free(slirp); + g_free(slirp->tftp_prefix); + g_free(slirp->bootp_filename); + g_free(slirp); } #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) @@ -373,6 +373,31 @@ void slirp_select_fill(int *pnfds, UPD_NFDS(so->s); } } + + /* + * ICMP sockets + */ + for (so = slirp->icmp.so_next; so != &slirp->icmp; + so = so_next) { + so_next = so->so_next; + + /* + * See if it's timed out + */ + if (so->so_expire) { + if (so->so_expire <= curtime) { + icmp_detach(so); + continue; + } else { + do_slowtimo = 1; /* Let socket expire */ + } + } + + if (so->so_state & SS_ISFCONNECTED) { + FD_SET(so->s, readfds); + UPD_NFDS(so->s); + } + } } *pnfds = nfds; @@ -393,7 +418,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, global_writefds = writefds; global_xfds = xfds; - curtime = qemu_get_clock(rt_clock); + curtime = qemu_get_clock_ms(rt_clock); QTAILQ_FOREACH(slirp, &slirp_instances, entry) { /* @@ -497,7 +522,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, */ #ifdef PROBE_CONN if (so->so_state & SS_ISFCONNECTING) { - ret = recv(so->s, (char *)&ret, 0,0); + ret = qemu_recv(so->s, &ret, 0,0); if (ret < 0) { /* XXX */ @@ -542,6 +567,18 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, sorecvfrom(so); } } + + /* + * Check incoming ICMP relies. + */ + for (so = slirp->icmp.so_next; so != &slirp->icmp; + so = so_next) { + so_next = so->so_next; + + if (so->s != -1 && FD_ISSET(so->s, readfds)) { + icmp_receive(so); + } + } } /* @@ -562,42 +599,8 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, global_xfds = NULL; } -#define ETH_ALEN 6 -#define ETH_HLEN 14 - -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ - -#define ARPOP_REQUEST 1 /* ARP request */ -#define ARPOP_REPLY 2 /* ARP reply */ - -struct ethhdr -{ - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ -}; - -struct arphdr -{ - unsigned short ar_hrd; /* format of hardware address */ - unsigned short ar_pro; /* format of protocol address */ - unsigned char ar_hln; /* length of hardware address */ - unsigned char ar_pln; /* length of protocol address */ - unsigned short ar_op; /* ARP opcode (command) */ - - /* - * Ethernet looks like this : This bit is variable sized however... - */ - unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ - uint32_t ar_sip; /* sender IP address */ - unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ - uint32_t ar_tip ; /* target IP address */ -} __attribute__((packed)); - static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) { - struct ethhdr *eh = (struct ethhdr *)pkt; struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN); uint8_t arp_reply[max(ETH_HLEN + sizeof(struct arphdr), 64)]; struct ethhdr *reh = (struct ethhdr *)arp_reply; @@ -608,6 +611,12 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) ar_op = ntohs(ah->ar_op); switch(ar_op) { case ARPOP_REQUEST: + if (ah->ar_tip == ah->ar_sip) { + /* Gratuitous ARP */ + arp_table_add(slirp, ah->ar_sip, ah->ar_sha); + return; + } + if ((ah->ar_tip & slirp->vnetwork_mask.s_addr) == slirp->vnetwork_addr.s_addr) { if (ah->ar_tip == slirp->vnameserver_addr.s_addr || @@ -620,8 +629,8 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) return; arp_ok: memset(arp_reply, 0, sizeof(arp_reply)); - /* XXX: make an ARP request to have the client address */ - memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN); + + arp_table_add(slirp, ah->ar_sip, ah->ar_sha); /* ARP request for alias/dns mac address */ memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); @@ -642,11 +651,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) } break; case ARPOP_REPLY: - /* reply to request of client mac address ? */ - if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN) && - ah->ar_sip == slirp->client_ipaddr.s_addr) { - memcpy(slirp->client_ethaddr, ah->ar_sha, ETH_ALEN); - } + arp_table_add(slirp, ah->ar_sip, ah->ar_sha); break; default: break; @@ -687,54 +692,66 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) } } -/* output the IP packet to the ethernet device */ -void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len) +/* Output the IP packet to the ethernet device. Returns 0 if the packet must be + * re-queued. + */ +int if_encap(Slirp *slirp, struct mbuf *ifm) { uint8_t buf[1600]; struct ethhdr *eh = (struct ethhdr *)buf; + uint8_t ethaddr[ETH_ALEN]; + const struct ip *iph = (const struct ip *)ifm->m_data; - if (ip_data_len + ETH_HLEN > sizeof(buf)) - return; - - if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) { + if (ifm->m_len + ETH_HLEN > sizeof(buf)) { + return 1; + } + + if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) { uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)]; struct ethhdr *reh = (struct ethhdr *)arp_req; struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN); - const struct ip *iph = (const struct ip *)ip_data; - - /* If the client addr is not known, there is no point in - sending the packet to it. Normally the sender should have - done an ARP request to get its MAC address. Here we do it - in place of sending the packet and we hope that the sender - will retry sending its packet. */ - memset(reh->h_dest, 0xff, ETH_ALEN); - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4); - memcpy(&reh->h_source[2], &slirp->vhost_addr, 4); - reh->h_proto = htons(ETH_P_ARP); - rah->ar_hrd = htons(1); - rah->ar_pro = htons(ETH_P_IP); - rah->ar_hln = ETH_ALEN; - rah->ar_pln = 4; - rah->ar_op = htons(ARPOP_REQUEST); - /* source hw addr */ - memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4); - memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4); - /* source IP */ - rah->ar_sip = slirp->vhost_addr.s_addr; - /* target hw addr (none) */ - memset(rah->ar_tha, 0, ETH_ALEN); - /* target IP */ - rah->ar_tip = iph->ip_dst.s_addr; - slirp->client_ipaddr = iph->ip_dst; - slirp_output(slirp->opaque, arp_req, sizeof(arp_req)); + + if (!ifm->arp_requested) { + /* If the client addr is not known, send an ARP request */ + memset(reh->h_dest, 0xff, ETH_ALEN); + memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4); + memcpy(&reh->h_source[2], &slirp->vhost_addr, 4); + reh->h_proto = htons(ETH_P_ARP); + rah->ar_hrd = htons(1); + rah->ar_pro = htons(ETH_P_IP); + rah->ar_hln = ETH_ALEN; + rah->ar_pln = 4; + rah->ar_op = htons(ARPOP_REQUEST); + + /* source hw addr */ + memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4); + memcpy(&rah->ar_sha[2], &slirp->vhost_addr, 4); + + /* source IP */ + rah->ar_sip = slirp->vhost_addr.s_addr; + + /* target hw addr (none) */ + memset(rah->ar_tha, 0, ETH_ALEN); + + /* target IP */ + rah->ar_tip = iph->ip_dst.s_addr; + slirp->client_ipaddr = iph->ip_dst; + slirp_output(slirp->opaque, arp_req, sizeof(arp_req)); + ifm->arp_requested = true; + + /* Expire request and drop outgoing packet after 1 second */ + ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL; + } + return 0; } else { - memcpy(eh->h_dest, slirp->client_ethaddr, ETH_ALEN); + memcpy(eh->h_dest, ethaddr, ETH_ALEN); memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4); /* XXX: not correct */ memcpy(&eh->h_source[2], &slirp->vhost_addr, 4); eh->h_proto = htons(ETH_P_IP); - memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); - slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN); + memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len); + slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN); + return 1; } } @@ -801,7 +818,7 @@ int slirp_add_exec(Slirp *slirp, int do_pty, const void *args, ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags) { if (so->s == -1 && so->extra) { - qemu_chr_write(so->extra, buf, len); + qemu_chr_fe_write(so->extra, buf, len); return len; } diff --git a/slirp/slirp.h b/slirp/slirp.h index 954289a..28a5c03 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -152,6 +152,7 @@ int inet_aton(const char *cp, struct in_addr *ia); #include "tcp_var.h" #include "tcpip.h" #include "udp.h" +#include "ip_icmp.h" #include "mbuf.h" #include "sbuf.h" #include "socket.h" @@ -169,6 +170,48 @@ int inet_aton(const char *cp, struct in_addr *ia); /* osdep.c */ int qemu_socket(int domain, int type, int protocol); +#define ETH_ALEN 6 +#define ETH_HLEN 14 + +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_ARP 0x0806 /* Address Resolution packet */ + +#define ARPOP_REQUEST 1 /* ARP request */ +#define ARPOP_REPLY 2 /* ARP reply */ + +struct ethhdr { + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ +}; + +struct arphdr { + unsigned short ar_hrd; /* format of hardware address */ + unsigned short ar_pro; /* format of protocol address */ + unsigned char ar_hln; /* length of hardware address */ + unsigned char ar_pln; /* length of protocol address */ + unsigned short ar_op; /* ARP opcode (command) */ + + /* + * Ethernet looks like this : This bit is variable sized however... + */ + unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ + uint32_t ar_sip; /* sender IP address */ + unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ + uint32_t ar_tip; /* target IP address */ +} QEMU_PACKED; + +#define ARP_TABLE_SIZE 16 + +typedef struct ArpTable { + struct arphdr table[ARP_TABLE_SIZE]; + int next_victim; +} ArpTable; + +void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN]); + +bool arp_table_search(Slirp *slirp, uint32_t ip_addr, + uint8_t out_ethaddr[ETH_ALEN]); struct Slirp { QTAILQ_ENTRY(Slirp) entry; @@ -180,9 +223,6 @@ struct Slirp { struct in_addr vdhcp_startaddr; struct in_addr vnameserver_addr; - /* ARP cache for the guest IP addresses (XXX: allow many entries) */ - uint8_t client_ethaddr[6]; - struct in_addr client_ipaddr; char client_hostname[33]; @@ -218,10 +258,16 @@ struct Slirp { struct socket udb; struct socket *udp_last_so; + /* icmp states */ + struct socket icmp; + struct socket *icmp_last_so; + /* tftp states */ char *tftp_prefix; struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; + ArpTable arp_table; + void *opaque; }; diff --git a/slirp/socket.c b/slirp/socket.c index c97691c..77b0c98 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -71,6 +71,8 @@ sofree(struct socket *so) slirp->tcp_last_so = &slirp->tcb; } else if (so == slirp->udp_last_so) { slirp->udp_last_so = &slirp->udb; + } else if (so == slirp->icmp_last_so) { + slirp->icmp_last_so = &slirp->icmp; } m_free(so->so_m); @@ -164,7 +166,7 @@ soread(struct socket *so) nn = readv(so->s, (struct iovec *)iov, n); DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); #else - nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); + nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0); #endif if (nn <= 0) { if (nn < 0 && (errno == EINTR || errno == EAGAIN)) @@ -189,7 +191,7 @@ soread(struct socket *so) */ if (n == 2 && nn == iov[0].iov_len) { int ret; - ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0); + ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0); if (ret > 0) nn += ret; } @@ -624,8 +626,8 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr, addr.sin_port = hport; if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) || - (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || + (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || (listen(s,1) < 0)) { int tmperrno = errno; /* Don't clobber the real reason we failed */ diff --git a/slirp/tcp.h b/slirp/tcp.h index 9d06836..b3817cb 100644 --- a/slirp/tcp.h +++ b/slirp/tcp.h @@ -51,10 +51,10 @@ struct tcphdr { tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ #ifdef HOST_WORDS_BIGENDIAN - u_int th_off:4, /* data offset */ + uint8_t th_off:4, /* data offset */ th_x2:4; /* (unused) */ #else - u_int th_x2:4, /* (unused) */ + uint8_t th_x2:4, /* (unused) */ th_off:4; /* data offset */ #endif uint8_t th_flags; diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index e4a7731..942aaf4 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -136,7 +136,7 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, i = q->ti_seq + q->ti_len - ti->ti_seq; if (i > 0) { if (i >= ti->ti_len) { - m_freem(m); + m_free(m); /* * Try to present any queued data * at the left window edge to the user. @@ -170,7 +170,7 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti, q = tcpiphdr_next(q); m = tcpiphdr_prev(q)->ti_mbuf; remque(tcpiphdr2qlink(tcpiphdr_prev(q))); - m_freem(m); + m_free(m); } /* @@ -197,7 +197,7 @@ present: m = ti->ti_mbuf; ti = tcpiphdr_next(ti); if (so->so_state & SS_FCANTSENDMORE) - m_freem(m); + m_free(m); else { if (so->so_emu) { if (tcp_emu(so,m)) sbappend(so, m); @@ -231,7 +231,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso) Slirp *slirp; DEBUG_CALL("tcp_input"); - DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", + DEBUG_ARGS((dfd, " m = %8lx iphlen = %2d inso = %lx\n", (long )m, iphlen, (long )inso )); /* @@ -451,7 +451,7 @@ findso: acked = ti->ti_ack - tp->snd_una; sbdrop(&so->so_snd, acked); tp->snd_una = ti->ti_ack; - m_freem(m); + m_free(m); /* * If all outstanding data are acked, stop @@ -580,7 +580,7 @@ findso: if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { u_char code=ICMP_UNREACH_NET; - DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", + DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n", errno,strerror(errno))); if(errno == ECONNREFUSED) { /* ACK the SYN, send RST to refuse the connection */ @@ -610,6 +610,7 @@ findso: so->so_ti = ti; tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; tp->t_state = TCPS_SYN_RECEIVED; + tcp_template(tp); } return; @@ -910,7 +911,7 @@ trimthenstep6: if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { - DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n", + DEBUG_MISC((dfd, " dup ack m = %lx so = %lx\n", (long )m, (long )so)); /* * If we have outstanding data (other than @@ -1156,6 +1157,16 @@ step6: dodata: /* + * If this is a small packet, then ACK now - with Nagel + * congestion avoidance sender won't send more until + * he gets an ACK. + */ + if (ti->ti_len && (unsigned)ti->ti_len <= 5 && + ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { + tp->t_flags |= TF_ACKNOW; + } + + /* * Process the segment text, merging it into the TCP sequencing queue, * and arranging for acknowledgment of receipt if necessary. * This process logically involves adjusting tp->rcv_wnd as data @@ -1234,18 +1245,6 @@ dodata: } /* - * If this is a small packet, then ACK now - with Nagel - * congestion avoidance sender won't send more until - * he gets an ACK. - * - * See above. - */ - if (ti->ti_len && (unsigned)ti->ti_len <= 5 && - ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { - tp->t_flags |= TF_ACKNOW; - } - - /* * Return any desired output. */ if (needoutput || (tp->t_flags & TF_ACKNOW)) { @@ -1260,7 +1259,7 @@ dropafterack: */ if (tiflags & TH_RST) goto drop; - m_freem(m); + m_free(m); tp->t_flags |= TF_ACKNOW; (void) tcp_output(tp); return; @@ -1293,7 +1292,7 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) int opt, optlen; DEBUG_CALL("tcp_dooptions"); - DEBUG_ARGS((dfd," tp = %lx cnt=%i \n", (long )tp, cnt)); + DEBUG_ARGS((dfd, " tp = %lx cnt=%i\n", (long)tp, cnt)); for (; cnt > 0; cnt -= optlen, cp += optlen) { opt = cp[0]; diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index b661d26..143a238 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -250,7 +250,7 @@ tcp_close(struct tcpcb *tp) t = tcpiphdr_next(t); m = tcpiphdr_prev(t)->ti_mbuf; remque(tcpiphdr2qlink(tcpiphdr_prev(t))); - m_freem(m); + m_free(m); } free(tp); so->so_tcpcb = NULL; @@ -902,7 +902,7 @@ int tcp_ctl(struct socket *so) return 1; } do_pty = ex_ptr->ex_pty; - DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); + DEBUG_MISC((dfd, " executing %s\n", ex_ptr->ex_exec)); return fork_exec(so, ex_ptr->ex_exec, do_pty); } } diff --git a/slirp/tftp.c b/slirp/tftp.c index 1821648..b78765f 100644 --- a/slirp/tftp.c +++ b/slirp/tftp.c @@ -37,7 +37,7 @@ static inline void tftp_session_update(struct tftp_session *spt) static void tftp_session_terminate(struct tftp_session *spt) { - qemu_free(spt->filename); + g_free(spt->filename); spt->slirp = NULL; } @@ -54,7 +54,7 @@ static int tftp_session_allocate(Slirp *slirp, struct tftp_t *tp) /* sessions time out after 5 inactive seconds */ if ((int)(curtime - spt->timestamp) > 5000) { - qemu_free(spt->filename); + g_free(spt->filename); goto found; } } @@ -136,9 +136,9 @@ static int tftp_send_oack(struct tftp_session *spt, m->m_data += sizeof(struct udpiphdr); tp->tp_op = htons(TFTP_OACK); - n += snprintf((char *)tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", + n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s", key) + 1; - n += snprintf((char *)tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u", + n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u", value) + 1; saddr.sin_addr = recv_tp->ip.ip_dst; @@ -283,11 +283,11 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) /* skip header fields */ k = 0; - pktlen -= ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp); + pktlen -= offsetof(struct tftp_t, x.tp_buf); /* prepend tftp_prefix */ prefix_len = strlen(slirp->tftp_prefix); - spt->filename = qemu_malloc(prefix_len + TFTP_FILENAME_MAX + 2); + spt->filename = g_malloc(prefix_len + TFTP_FILENAME_MAX + 2); memcpy(spt->filename, slirp->tftp_prefix, prefix_len); spt->filename[prefix_len] = '/'; @@ -299,7 +299,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) tftp_send_error(spt, 2, "Access violation", tp); return; } - req_fname[k] = (char)tp->x.tp_buf[k]; + req_fname[k] = tp->x.tp_buf[k]; if (req_fname[k++] == '\0') { break; } @@ -311,7 +311,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) return; } - if (strcasecmp((const char *)&tp->x.tp_buf[k], "octet") != 0) { + if (strcasecmp(&tp->x.tp_buf[k], "octet") != 0) { tftp_send_error(spt, 4, "Unsupported transfer mode", tp); return; } @@ -340,7 +340,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) while (k < pktlen) { const char *key, *value; - key = (const char *)&tp->x.tp_buf[k]; + key = &tp->x.tp_buf[k]; k += strlen(key) + 1; if (k >= pktlen) { @@ -348,7 +348,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen) return; } - value = (const char *)&tp->x.tp_buf[k]; + value = &tp->x.tp_buf[k]; k += strlen(value) + 1; if (strcasecmp(key, "tsize") == 0) { diff --git a/slirp/tftp.h b/slirp/tftp.h index b9f0847..72e5e91 100644 --- a/slirp/tftp.h +++ b/slirp/tftp.h @@ -26,7 +26,7 @@ struct tftp_t { uint16_t tp_error_code; uint8_t tp_msg[512]; } tp_error; - uint8_t tp_buf[512 + 2]; + char tp_buf[512 + 2]; } x; }; diff --git a/slirp/udp.c b/slirp/udp.c index 02b3793..5b060f3 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -120,23 +120,26 @@ udp_input(register struct mbuf *m, int iphlen) /* * handle DHCP/BOOTP */ - if (ntohs(uh->uh_dport) == BOOTP_SERVER) { - bootp_input(m); - goto bad; - } - - if (slirp->restricted) { - goto bad; - } + if (ntohs(uh->uh_dport) == BOOTP_SERVER && + (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr || + ip->ip_dst.s_addr == 0xffffffff)) { + bootp_input(m); + goto bad; + } /* * handle TFTP */ - if (ntohs(uh->uh_dport) == TFTP_SERVER) { + if (ntohs(uh->uh_dport) == TFTP_SERVER && + ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) { tftp_input(m); goto bad; } + if (slirp->restricted) { + goto bad; + } + /* * Locate pcb for datagram. */ @@ -219,7 +222,7 @@ udp_input(register struct mbuf *m, int iphlen) return; bad: - m_freem(m); + m_free(m); return; } diff --git a/softmmu-semi.h b/softmmu-semi.h index 79278cc..86a9f8a 100644 --- a/softmmu-semi.h +++ b/softmmu-semi.h @@ -4,7 +4,7 @@ * * Copyright (c) 2007 CodeSourcery. * - * This code is licenced under the GPL + * This code is licensed under the GPL */ static inline uint32_t softmmu_tget32(CPUState *env, uint32_t addr) diff --git a/softmmu_defs.h b/softmmu_defs.h index e38bb75..c5a2bcd 100644 --- a/softmmu_defs.h +++ b/softmmu_defs.h @@ -1,3 +1,11 @@ +/* + * Software MMU support + * + * Declare helpers used by TCG for qemu_ld/st ops. + * + * Used by softmmu_exec.h, TCG targets and exec-all.h. + * + */ #ifndef SOFTMMU_DEFS_H #define SOFTMMU_DEFS_H diff --git a/softmmu_exec.h b/softmmu_exec.h index 28d1d53..8c73985 100644 --- a/softmmu_exec.h +++ b/softmmu_exec.h @@ -1,4 +1,14 @@ -/* Common softmmu definitions and inline routines. */ +/* + * Software MMU support + * + * Generate inline load/store functions for all MMU modes (typically + * at least _user and _kernel) as well as _data versions, for all data + * sizes. + * + * Used by target op helpers. + * + * MMU mode suffixes are defined in target cpu.h. + */ /* XXX: find something cleaner. * Furthermore, this is false for 64 bits targets diff --git a/softmmu_header.h b/softmmu_header.h index 2f95c33..818d7b6 100644 --- a/softmmu_header.h +++ b/softmmu_header.h @@ -1,6 +1,15 @@ /* * Software MMU support * + * Generate inline load/store functions for one MMU mode and data + * size. + * + * Generate a store function as well as signed and unsigned loads. For + * 32 and 64 bit cases, also generate floating point functions with + * the same size. + * + * Not used directly but included from softmmu_exec.h and exec-all.h. + * * Copyright (c) 2003 Fabrice Bellard * * This library is free software; you can redistribute it and/or diff --git a/softmmu_template.h b/softmmu_template.h index 73136ae..71360c1 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -1,6 +1,11 @@ /* * Software MMU support * + * Generate helpers used by TCG for qemu_ld/st ops and code load + * functions. + * + * Included from target op helpers and exec.c. + * * Copyright (c) 2003 Fabrice Bellard * * This library is free software; you can redistribute it and/or @@ -131,30 +136,23 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, if ((addr & (DATA_SIZE - 1)) != 0) do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); #endif - tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); goto redo; } return res; } -#if defined(CONFIG_TCG_TARGET_X86_OPT) && !defined(SOFTMMU_CODE_ACCESS) -/* - * extended versions of MMU helpers for x86 TCG target optimization - * !defined(SOFTMMU_CODE_ACCESS) suppress warnings from exec.c - */ -DATA_TYPE REGPARM glue(glue(__ldext, SUFFIX), MMUSUFFIX)(target_ulong addr, - int mmu_idx, - void *ra) +/* handle all unaligned cases */ +static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, + int mmu_idx, + void *retaddr) { - DATA_TYPE res; - int index; - target_ulong tlb_addr; + DATA_TYPE res, res1, res2; + int index, shift; target_phys_addr_t ioaddr; unsigned long addend; - void *retaddr; + target_ulong tlb_addr, addr1, addr2; - /* test if there is match for unaligned or IO access */ - /* XXX: could done more in memory macro in a non portable way */ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; @@ -163,54 +161,55 @@ DATA_TYPE REGPARM glue(glue(__ldext, SUFFIX), MMUSUFFIX)(target_ulong addr, /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; - retaddr = ra; ioaddr = env->iotlb[mmu_idx][index]; res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - /* slow unaligned access (it spans two pages or IO) */ do_unaligned_access: - retaddr = ra; -#ifdef ALIGNED_ONLY - do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + /* slow unaligned access (it spans two pages) */ + addr1 = addr & ~(DATA_SIZE - 1); + addr2 = addr1 + DATA_SIZE; + res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1, + mmu_idx, retaddr); + res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2, + mmu_idx, retaddr); + shift = (addr & (DATA_SIZE - 1)) * 8; +#ifdef TARGET_WORDS_BIGENDIAN + res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); +#else + res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift)); #endif - res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr, - mmu_idx, retaddr); + res = (DATA_TYPE)res; } else { /* unaligned/aligned access in the same page */ -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { - retaddr = ra; - do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); - } -#endif addend = env->tlb_table[mmu_idx][index].addend; res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); } } else { /* the page is not in the TLB : fill it */ - retaddr = ra; -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) - do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); -#endif - tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); goto redo; } return res; } -#endif /* CONFIG_TCG_TARGET_X86_OPT */ -/* handle all unaligned cases */ -static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - int mmu_idx, - void *retaddr) +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && !defined(SOFTMMU_CODE_ACCESS) +/* Extended versions of MMU helpers for qemu_ld IR optimization. + They get return address arguments because the caller PCs are not where helpers return to. + !defined(SOFTMMU_CODE_ACCESS) suppress warnings from exec.c */ +#if defined(__i386__) || defined(__x86_64__) +DATA_TYPE REGPARM glue(glue(__ldext, SUFFIX), MMUSUFFIX)(target_ulong addr, + int mmu_idx, + void *ra) { - DATA_TYPE res, res1, res2; - int index, shift; + DATA_TYPE res; + int index; + target_ulong tlb_addr; target_phys_addr_t ioaddr; unsigned long addend; - target_ulong tlb_addr, addr1, addr2; + void *retaddr; + /* test if there is match for unaligned or IO access */ + /* XXX: could done more in memory macro in a non portable way */ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; @@ -219,36 +218,43 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; + retaddr = ra; ioaddr = env->iotlb[mmu_idx][index]; res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { + /* slow unaligned access (it spans two pages or IO) */ do_unaligned_access: - /* slow unaligned access (it spans two pages) */ - addr1 = addr & ~(DATA_SIZE - 1); - addr2 = addr1 + DATA_SIZE; - res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1, - mmu_idx, retaddr); - res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2, - mmu_idx, retaddr); - shift = (addr & (DATA_SIZE - 1)) * 8; -#ifdef TARGET_WORDS_BIGENDIAN - res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); -#else - res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift)); + retaddr = ra; +#ifdef ALIGNED_ONLY + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); #endif - res = (DATA_TYPE)res; + res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr, + mmu_idx, retaddr); } else { /* unaligned/aligned access in the same page */ +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) { + retaddr = ra; + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + } +#endif addend = env->tlb_table[mmu_idx][index].addend; res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); } } else { /* the page is not in the TLB : fill it */ - tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + retaddr = ra; +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); +#endif + tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); goto redo; } return res; } +#endif /* defined(__i386__) || defined(__x86_64__) */ +#endif /* defined(CONFIG_QEMU_LDST_OPTIMIZATION) */ #ifndef SOFTMMU_CODE_ACCESS @@ -332,26 +338,21 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, if ((addr & (DATA_SIZE - 1)) != 0) do_unaligned_access(addr, 1, mmu_idx, retaddr); #endif - tlb_fill(addr, 1, mmu_idx, retaddr); + tlb_fill(env, addr, 1, mmu_idx, retaddr); goto redo; } } -#if defined(CONFIG_TCG_TARGET_X86_OPT) -/* - * extended versions of MMU helpers for x86 TCG target optimization - * !defined(SOFTMMU_CODE_ACCESS) suppress warnings from exec.c - */ -void REGPARM glue(glue(__stext, SUFFIX), MMUSUFFIX)(target_ulong addr, - DATA_TYPE val, - int mmu_idx, - void *ra) +/* handles all unaligned cases */ +static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, + DATA_TYPE val, + int mmu_idx, + void *retaddr) { target_phys_addr_t ioaddr; unsigned long addend; target_ulong tlb_addr; - void *retaddr; - int index; + int index, i; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: @@ -361,51 +362,48 @@ void REGPARM glue(glue(__stext, SUFFIX), MMUSUFFIX)(target_ulong addr, /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; - retaddr = ra; ioaddr = env->iotlb[mmu_idx][index]; glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { do_unaligned_access: - retaddr = ra; -#ifdef ALIGNED_ONLY - do_unaligned_access(addr, 1, mmu_idx, retaddr); + /* XXX: not efficient, but simple */ + /* Note: relies on the fact that tlb_fill() does not remove the + * previous page from the TLB cache. */ + for(i = DATA_SIZE - 1; i >= 0; i--) { +#ifdef TARGET_WORDS_BIGENDIAN + glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), + mmu_idx, retaddr); +#else + glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8), + mmu_idx, retaddr); #endif - glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val, - mmu_idx, retaddr); + } } else { /* aligned/unaligned access in the same page */ -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) { - retaddr = ra; - do_unaligned_access(addr, 1, mmu_idx, retaddr); - } -#endif addend = env->tlb_table[mmu_idx][index].addend; glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); } } else { /* the page is not in the TLB : fill it */ - retaddr = ra; -#ifdef ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) - do_unaligned_access(addr, 1, mmu_idx, retaddr); -#endif - tlb_fill(addr, 1, mmu_idx, retaddr); + tlb_fill(env, addr, 1, mmu_idx, retaddr); goto redo; } } -#endif /* CONFIG_TCG_TARGET_X86_OPT */ -/* handles all unaligned cases */ -static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, - DATA_TYPE val, - int mmu_idx, - void *retaddr) +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) +#if defined(__i386__) || defined(__x86_64__) +/* Extended versions of MMU helpers for qemu_st IR optimization. + They get return address arguments because the caller PCs are not where helpers return to. */ +void REGPARM glue(glue(__stext, SUFFIX), MMUSUFFIX)(target_ulong addr, + DATA_TYPE val, + int mmu_idx, + void *ra) { target_phys_addr_t ioaddr; unsigned long addend; target_ulong tlb_addr; - int index, i; + void *retaddr; + int index; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: @@ -415,33 +413,41 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; + retaddr = ra; ioaddr = env->iotlb[mmu_idx][index]; glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { do_unaligned_access: - /* XXX: not efficient, but simple */ - /* Note: relies on the fact that tlb_fill() does not remove the - * previous page from the TLB cache. */ - for(i = DATA_SIZE - 1; i >= 0; i--) { -#ifdef TARGET_WORDS_BIGENDIAN - glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), - mmu_idx, retaddr); -#else - glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8), - mmu_idx, retaddr); + retaddr = ra; +#ifdef ALIGNED_ONLY + do_unaligned_access(addr, 1, mmu_idx, retaddr); #endif - } + glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val, + mmu_idx, retaddr); } else { /* aligned/unaligned access in the same page */ +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) { + retaddr = ra; + do_unaligned_access(addr, 1, mmu_idx, retaddr); + } +#endif addend = env->tlb_table[mmu_idx][index].addend; glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); } } else { /* the page is not in the TLB : fill it */ - tlb_fill(addr, 1, mmu_idx, retaddr); + retaddr = ra; +#ifdef ALIGNED_ONLY + if ((addr & (DATA_SIZE - 1)) != 0) + do_unaligned_access(addr, 1, mmu_idx, retaddr); +#endif + tlb_fill(env, addr, 1, mmu_idx, retaddr); goto redo; } } +#endif /* defined(__i386__) || defined(__x86_64__) */ +#endif /* defined(CONFIG_QEMU_LDST_OPTIMIZATION) */ #endif /* !defined(SOFTMMU_CODE_ACCESS) */ diff --git a/sparc.ld b/sparc.ld index 31321be..56efe34 100644 --- a/sparc.ld +++ b/sparc.ld @@ -67,23 +67,23 @@ SECTIONS .tbss : { *(.tbss) } .preinit_array : { - PROVIDE_HIDDEN (__preinit_array_start = .); + PROVIDE (__preinit_array_start = .); KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); + PROVIDE (__preinit_array_end = .); } .init_array : { - PROVIDE_HIDDEN (__init_array_start = .); + PROVIDE (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE (__init_array_end = .); } .fini_array : { - PROVIDE_HIDDEN (__fini_array_start = .); + PROVIDE (__fini_array_start = .); KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE (__fini_array_end = .); } .ctors : { diff --git a/spice-qemu-char.c b/spice-qemu-char.c index 517f337..7e8eaa9 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -36,17 +36,16 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) while (len > 0) { last_out = MIN(len, VMC_MAX_HOST_WRITE); - qemu_chr_read(scd->chr, p, last_out); - if (last_out > 0) { - out += last_out; - len -= last_out; - p += last_out; - } else { + if (qemu_chr_be_can_write(scd->chr) < last_out) { break; } + qemu_chr_be_write(scd->chr, p, last_out); + out += last_out; + len -= last_out; + p += last_out; } - dprintf(scd, 3, "%s: %lu/%zd\n", __func__, out, len + out); + dprintf(scd, 3, "%s: %zu/%zd\n", __func__, out, len + out); trace_spice_vmc_write(out, len + out); return out; } @@ -70,11 +69,40 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) return bytes; } +static void vmc_state(SpiceCharDeviceInstance *sin, int connected) +{ + SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); + +#if SPICE_SERVER_VERSION < 0x000901 + /* + * spice-server calls the state callback for the agent channel when the + * spice client connects / disconnects. Given that not the client but + * the server is doing the parsing of the messages this is wrong as the + * server is still listening. Worse, this causes the parser in the server + * to go out of sync, so we ignore state calls for subtype vdagent + * spicevmc chardevs. For the full story see: + * http://lists.freedesktop.org/archives/spice-devel/2011-July/004837.html + */ + if (strcmp(sin->subtype, "vdagent") == 0) { + return; + } +#endif + + if ((scd->chr->opened && connected) || + (!scd->chr->opened && !connected)) { + return; + } + + qemu_chr_be_event(scd->chr, + connected ? CHR_EVENT_OPENED : CHR_EVENT_CLOSED); +} + static SpiceCharDeviceInterface vmc_interface = { .base.type = SPICE_INTERFACE_CHAR_DEVICE, .base.description = "spice virtual channel char device", .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR, .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR, + .state = vmc_state, .write = vmc_write, .read = vmc_read, }; @@ -113,7 +141,7 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) assert(s->datalen == 0); if (s->bufsize < len) { s->bufsize = len; - s->buffer = qemu_realloc(s->buffer, s->bufsize); + s->buffer = g_realloc(s->buffer, s->bufsize); } memcpy(s->buffer, buf, len); s->datapos = s->buffer; @@ -128,7 +156,19 @@ static void spice_chr_close(struct CharDriverState *chr) printf("%s\n", __func__); vmc_unregister_interface(s); - qemu_free(s); + g_free(s); +} + +static void spice_chr_guest_open(struct CharDriverState *chr) +{ + SpiceCharDriver *s = chr->opaque; + vmc_register_interface(s); +} + +static void spice_chr_guest_close(struct CharDriverState *chr) +{ + SpiceCharDriver *s = chr->opaque; + vmc_unregister_interface(s); } static void print_allowed_subtypes(void) @@ -148,7 +188,7 @@ static void print_allowed_subtypes(void) fprintf(stderr, "\n"); } -CharDriverState *qemu_chr_open_spice(QemuOpts *opts) +int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; SpiceCharDriver *s; @@ -160,7 +200,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts) if (name == NULL) { fprintf(stderr, "spice-qemu-char: missing name parameter\n"); print_allowed_subtypes(); - return NULL; + return -EINVAL; } for(;*psubtype != NULL; ++psubtype) { if (strcmp(name, *psubtype) == 0) { @@ -171,11 +211,11 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts) if (subtype == NULL) { fprintf(stderr, "spice-qemu-char: unsupported name\n"); print_allowed_subtypes(); - return NULL; + return -EINVAL; } - chr = qemu_mallocz(sizeof(CharDriverState)); - s = qemu_mallocz(sizeof(SpiceCharDriver)); + chr = g_malloc0(sizeof(CharDriverState)); + s = g_malloc0(sizeof(SpiceCharDriver)); s->chr = chr; s->debug = debug; s->active = false; @@ -183,8 +223,16 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts) chr->opaque = s; chr->chr_write = spice_chr_write; chr->chr_close = spice_chr_close; + chr->chr_guest_open = spice_chr_guest_open; + chr->chr_guest_close = spice_chr_guest_close; - qemu_chr_generic_open(chr); +#if SPICE_SERVER_VERSION < 0x000901 + /* See comment in vmc_state() */ + if (strcmp(subtype, "vdagent") == 0) { + qemu_chr_generic_open(chr); + } +#endif - return chr; + *_chr = chr; + return 0; } diff --git a/sysemu.h b/sysemu.h index b1529c7..338a073 100644 --- a/sysemu.h +++ b/sysemu.h @@ -6,56 +6,52 @@ #include "qemu-option.h" #include "qemu-queue.h" #include "qemu-timer.h" +#include "qapi-types.h" #include "notify.h" - -#ifdef _WIN32 -#include -#include "qemu-os-win32.h" -#endif - -#ifdef CONFIG_POSIX -#include "qemu-os-posix.h" -#endif +#include "main-loop.h" /* vl.c */ -extern const char *bios_name; -#define QEMU_FILE_TYPE_BIOS 0 -#define QEMU_FILE_TYPE_KEYMAP 1 -char *qemu_find_file(int type, const char *name); +extern const char *bios_name; -extern int vm_running; extern const char *qemu_name; extern uint8_t qemu_uuid[]; int qemu_uuid_parse(const char *str, uint8_t *uuid); #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void runstate_init(void); +bool runstate_check(RunState state); +void runstate_set(RunState new_state); +int runstate_is_running(void); typedef struct vm_change_state_entry VMChangeStateEntry; -typedef void VMChangeStateHandler(void *opaque, int running, int reason); +typedef void VMChangeStateHandler(void *opaque, int running, RunState state); VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb, void *opaque); void qemu_del_vm_change_state_handler(VMChangeStateEntry *e); +void vm_state_notify(int running, RunState state); -void vm_start(void); -void vm_stop(int reason); - -uint64_t ram_bytes_remaining(void); -uint64_t ram_bytes_transferred(void); -uint64_t ram_bytes_total(void); +#define VMRESET_SILENT false +#define VMRESET_REPORT true -int64_t cpu_get_ticks(void); -void cpu_enable_ticks(void); -void cpu_disable_ticks(void); +void vm_start(void); +void vm_stop(RunState state); +void vm_stop_force_state(RunState state); void qemu_system_reset_request(void); void qemu_system_shutdown_request(void); void qemu_system_powerdown_request(void); +void qemu_system_debug_request(void); +void qemu_system_vmstop_request(RunState reason); +int qemu_shutdown_requested_get(void); +int qemu_reset_requested_get(void); int qemu_shutdown_requested(void); int qemu_reset_requested(void); int qemu_powerdown_requested(void); +void qemu_system_killed(int signal, pid_t pid); +void qemu_kill_report(void); extern qemu_irq qemu_system_powerdown; -void qemu_system_reset(void); +void qemu_system_reset(bool report); void qemu_add_exit_notifier(Notifier *notify); void qemu_remove_exit_notifier(Notifier *notify); @@ -67,14 +63,8 @@ int load_vmstate(const char *name); void do_delvm(Monitor *mon, const QDict *qdict); void do_info_snapshots(Monitor *mon); -void cpu_synchronize_all_states(void); -void cpu_synchronize_all_post_reset(void); -void cpu_synchronize_all_post_init(void); - void qemu_announce_self(void); -void main_loop_wait(int nonblocking); - bool qemu_savevm_state_blocked(Monitor *mon); int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, int shared); @@ -86,28 +76,26 @@ int qemu_loadvm_state(QEMUFile *f); /* SLIRP */ void do_info_slirp(Monitor *mon); -/* OS specific functions */ -void os_setup_early_signal_handling(void); -char *os_find_datadir(const char *argv0); -void os_parse_cmd_args(int index, const char *optarg); -void os_pidfile_error(void); - typedef enum DisplayType { DT_DEFAULT, DT_CURSES, DT_SDL, DT_NOGRAPHIC, +#ifdef CONFIG_MARU + DT_MARU, +#endif + DT_NONE, } DisplayType; extern int autostart; -extern int incoming_expected; extern int bios_size; typedef enum { VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL, -// by caramis... - VGA_TIZEN +#ifdef CONFIG_MARU + VGA_MARU, +#endif } VGAInterfaceType; extern int vga_interface_type; @@ -116,9 +104,9 @@ extern int vga_interface_type; #define xenfb_enabled (vga_interface_type == VGA_XENFB) #define vmsvga_enabled (vga_interface_type == VGA_VMWARE) #define qxl_enabled (vga_interface_type == VGA_QXL) -// by caramis... -#define tizen_vga_enabled (vga_interface_type == VGA_TIZEN) - +#ifdef CONFIG_MARU +#define maru_vga_enabled (vga_interface_type == VGA_MARU) +#endif extern int graphic_width; extern int graphic_height; extern int graphic_depth; @@ -139,6 +127,9 @@ extern int no_shutdown; extern int semihosting_enabled; extern int old_param; extern int boot_menu; +extern uint8_t *boot_splash_filedata; +extern int boot_splash_filedata_size; +extern uint8_t qemu_extra_params_fw[2]; extern QEMUClock *rtc_clock; #define MAX_NODES 64 @@ -180,8 +171,6 @@ extern CharDriverState *serial_hds[MAX_SERIAL_PORTS]; extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; -#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) - void do_usb_add(Monitor *mon, const QDict *qdict); void do_usb_del(Monitor *mon, const QDict *qdict); void usb_info(Monitor *mon); diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 686fb4a..9d61d45 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -28,8 +28,6 @@ #include "cpu-defs.h" -#include - #include "softfloat.h" #define TARGET_HAS_ICE 1 @@ -192,171 +190,39 @@ enum { #define SWCR_MASK (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK) -/* Internal processor registers */ -/* XXX: TOFIX: most of those registers are implementation dependant */ -enum { -#if defined(CONFIG_USER_ONLY) - IPR_EXC_ADDR, - IPR_EXC_SUM, - IPR_EXC_MASK, -#else - /* Ebox IPRs */ - IPR_CC = 0xC0, /* 21264 */ - IPR_CC_CTL = 0xC1, /* 21264 */ -#define IPR_CC_CTL_ENA_SHIFT 32 -#define IPR_CC_CTL_COUNTER_MASK 0xfffffff0UL - IPR_VA = 0xC2, /* 21264 */ - IPR_VA_CTL = 0xC4, /* 21264 */ -#define IPR_VA_CTL_VA_48_SHIFT 1 -#define IPR_VA_CTL_VPTB_SHIFT 30 - IPR_VA_FORM = 0xC3, /* 21264 */ - /* Ibox IPRs */ - IPR_ITB_TAG = 0x00, /* 21264 */ - IPR_ITB_PTE = 0x01, /* 21264 */ - IPR_ITB_IAP = 0x02, - IPR_ITB_IA = 0x03, /* 21264 */ - IPR_ITB_IS = 0x04, /* 21264 */ - IPR_PMPC = 0x05, - IPR_EXC_ADDR = 0x06, /* 21264 */ - IPR_IVA_FORM = 0x07, /* 21264 */ - IPR_CM = 0x09, /* 21264 */ -#define IPR_CM_SHIFT 3 -#define IPR_CM_MASK (3ULL << IPR_CM_SHIFT) /* 21264 */ - IPR_IER = 0x0A, /* 21264 */ -#define IPR_IER_MASK 0x0000007fffffe000ULL - IPR_IER_CM = 0x0B, /* 21264: = CM | IER */ - IPR_SIRR = 0x0C, /* 21264 */ -#define IPR_SIRR_SHIFT 14 -#define IPR_SIRR_MASK 0x7fff - IPR_ISUM = 0x0D, /* 21264 */ - IPR_HW_INT_CLR = 0x0E, /* 21264 */ - IPR_EXC_SUM = 0x0F, - IPR_PAL_BASE = 0x10, - IPR_I_CTL = 0x11, -#define IPR_I_CTL_CHIP_ID_SHIFT 24 /* 21264 */ -#define IPR_I_CTL_BIST_FAIL (1 << 23) /* 21264 */ -#define IPR_I_CTL_IC_EN_SHIFT 2 /* 21264 */ -#define IPR_I_CTL_SDE1_SHIFT 7 /* 21264 */ -#define IPR_I_CTL_HWE_SHIFT 12 /* 21264 */ -#define IPR_I_CTL_VA_48_SHIFT 15 /* 21264 */ -#define IPR_I_CTL_SPE_SHIFT 3 /* 21264 */ -#define IPR_I_CTL_CALL_PAL_R23_SHIFT 20 /* 21264 */ - IPR_I_STAT = 0x16, /* 21264 */ - IPR_IC_FLUSH = 0x13, /* 21264 */ - IPR_IC_FLUSH_ASM = 0x12, /* 21264 */ - IPR_CLR_MAP = 0x15, - IPR_SLEEP = 0x17, - IPR_PCTX = 0x40, - IPR_PCTX_ASN = 0x01, /* field */ -#define IPR_PCTX_ASN_SHIFT 39 - IPR_PCTX_ASTER = 0x02, /* field */ -#define IPR_PCTX_ASTER_SHIFT 5 - IPR_PCTX_ASTRR = 0x04, /* field */ -#define IPR_PCTX_ASTRR_SHIFT 9 - IPR_PCTX_PPCE = 0x08, /* field */ -#define IPR_PCTX_PPCE_SHIFT 1 - IPR_PCTX_FPE = 0x10, /* field */ -#define IPR_PCTX_FPE_SHIFT 2 - IPR_PCTX_ALL = 0x5f, /* all fields */ - IPR_PCTR_CTL = 0x14, /* 21264 */ - /* Mbox IPRs */ - IPR_DTB_TAG0 = 0x20, /* 21264 */ - IPR_DTB_TAG1 = 0xA0, /* 21264 */ - IPR_DTB_PTE0 = 0x21, /* 21264 */ - IPR_DTB_PTE1 = 0xA1, /* 21264 */ - IPR_DTB_ALTMODE = 0xA6, - IPR_DTB_ALTMODE0 = 0x26, /* 21264 */ -#define IPR_DTB_ALTMODE_MASK 3 - IPR_DTB_IAP = 0xA2, - IPR_DTB_IA = 0xA3, /* 21264 */ - IPR_DTB_IS0 = 0x24, - IPR_DTB_IS1 = 0xA4, - IPR_DTB_ASN0 = 0x25, /* 21264 */ - IPR_DTB_ASN1 = 0xA5, /* 21264 */ -#define IPR_DTB_ASN_SHIFT 56 - IPR_MM_STAT = 0x27, /* 21264 */ - IPR_M_CTL = 0x28, /* 21264 */ -#define IPR_M_CTL_SPE_SHIFT 1 -#define IPR_M_CTL_SPE_MASK 7 - IPR_DC_CTL = 0x29, /* 21264 */ - IPR_DC_STAT = 0x2A, /* 21264 */ - /* Cbox IPRs */ - IPR_C_DATA = 0x2B, - IPR_C_SHIFT = 0x2C, - - IPR_ASN, - IPR_ASTEN, - IPR_ASTSR, - IPR_DATFX, - IPR_ESP, - IPR_FEN, - IPR_IPIR, - IPR_IPL, - IPR_KSP, - IPR_MCES, - IPR_PERFMON, - IPR_PCBB, - IPR_PRBR, - IPR_PTBR, - IPR_SCBB, - IPR_SISR, - IPR_SSP, - IPR_SYSPTBR, - IPR_TBCHK, - IPR_TBIA, - IPR_TBIAP, - IPR_TBIS, - IPR_TBISD, - IPR_TBISI, - IPR_USP, - IPR_VIRBND, - IPR_VPTB, - IPR_WHAMI, - IPR_ALT_MODE, -#endif - IPR_LAST, -}; +/* MMU modes definitions */ -typedef struct CPUAlphaState CPUAlphaState; +/* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user. + The Unix PALcode only exposes the kernel and user modes; presumably + executive and supervisor are used by VMS. -typedef struct pal_handler_t pal_handler_t; -struct pal_handler_t { - /* Reset */ - void (*reset)(CPUAlphaState *env); - /* Uncorrectable hardware error */ - void (*machine_check)(CPUAlphaState *env); - /* Arithmetic exception */ - void (*arithmetic)(CPUAlphaState *env); - /* Interrupt / correctable hardware error */ - void (*interrupt)(CPUAlphaState *env); - /* Data fault */ - void (*dfault)(CPUAlphaState *env); - /* DTB miss pal */ - void (*dtb_miss_pal)(CPUAlphaState *env); - /* DTB miss native */ - void (*dtb_miss_native)(CPUAlphaState *env); - /* Unaligned access */ - void (*unalign)(CPUAlphaState *env); - /* ITB miss */ - void (*itb_miss)(CPUAlphaState *env); - /* Instruction stream access violation */ - void (*itb_acv)(CPUAlphaState *env); - /* Reserved or privileged opcode */ - void (*opcdec)(CPUAlphaState *env); - /* Floating point exception */ - void (*fen)(CPUAlphaState *env); - /* Call pal instruction */ - void (*call_pal)(CPUAlphaState *env, uint32_t palcode); -}; + PALcode itself uses physical mode for code and kernel mode for data; + there are PALmode instructions that can access data via physical mode + or via an os-installed "alternate mode", which is one of the 4 above. -#define NB_MMU_MODES 4 + QEMU does not currently properly distinguish between code/data when + looking up addresses. To avoid having to address this issue, our + emulated PALcode will cheat and use the KSEG mapping for its code+data + rather than physical addresses. + + Moreover, we're only emulating Unix PALcode, and not attempting VMS. + + All of which allows us to drop all but kernel and user modes. + Elide the unused MMU modes to save space. */ + +#define NB_MMU_MODES 2 + +#define MMU_MODE0_SUFFIX _kernel +#define MMU_MODE1_SUFFIX _user +#define MMU_KERNEL_IDX 0 +#define MMU_USER_IDX 1 + +typedef struct CPUAlphaState CPUAlphaState; struct CPUAlphaState { uint64_t ir[31]; float64 fir[31]; uint64_t pc; - uint64_t ipr[IPR_LAST]; - uint64_t ps; uint64_t unique; uint64_t lock_addr; uint64_t lock_st_addr; @@ -371,10 +237,37 @@ struct CPUAlphaState { uint8_t fpcr_dnod; uint8_t fpcr_undz; - /* Used for HW_LD / HW_ST */ - uint8_t saved_mode; - /* For RC and RS */ + /* The Internal Processor Registers. Some of these we assume always + exist for use in user-mode. */ + uint8_t ps; uint8_t intr_flag; + uint8_t pal_mode; + uint8_t fen; + + uint32_t pcc_ofs; + + /* These pass data from the exception logic in the translator and + helpers to the OS entry point. This is used for both system + emulation and user-mode. */ + uint64_t trap_arg0; + uint64_t trap_arg1; + uint64_t trap_arg2; + +#if !defined(CONFIG_USER_ONLY) + /* The internal data required by our emulation of the Unix PALcode. */ + uint64_t exc_addr; + uint64_t palbr; + uint64_t ptbr; + uint64_t vptptr; + uint64_t sysval; + uint64_t usp; + uint64_t shadow[8]; + uint64_t scratch[24]; +#endif + + /* This alarm doesn't exist in real hardware; we wish it did. */ + struct QEMUTimer *alarm_timer; + uint64_t alarm_expire; #if TARGET_LONG_BITS > HOST_LONG_BITS /* temporary fixed-point registers @@ -386,14 +279,11 @@ struct CPUAlphaState { /* Those resources are used only in Qemu core */ CPU_COMMON - uint32_t hflags; - int error_code; uint32_t features; uint32_t amask; int implver; - pal_handler_t *pal_handler; }; #define cpu_init cpu_alpha_init @@ -401,17 +291,6 @@ struct CPUAlphaState { #define cpu_gen_code cpu_alpha_gen_code #define cpu_signal_handler cpu_alpha_signal_handler -/* MMU modes definitions */ -#define MMU_MODE0_SUFFIX _kernel -#define MMU_MODE1_SUFFIX _executive -#define MMU_MODE2_SUFFIX _supervisor -#define MMU_MODE3_SUFFIX _user -#define MMU_USER_IDX 3 -static inline int cpu_mmu_index (CPUState *env) -{ - return (env->ps >> 3) & 3; -} - #include "cpu-all.h" enum { @@ -422,36 +301,89 @@ enum { }; enum { - EXCP_RESET = 0x0000, - EXCP_MCHK = 0x0020, - EXCP_ARITH = 0x0060, - EXCP_HW_INTERRUPT = 0x00E0, - EXCP_DFAULT = 0x01E0, - EXCP_DTB_MISS_PAL = 0x09E0, - EXCP_ITB_MISS = 0x03E0, - EXCP_ITB_ACV = 0x07E0, - EXCP_DTB_MISS_NATIVE = 0x08E0, - EXCP_UNALIGN = 0x11E0, - EXCP_OPCDEC = 0x13E0, - EXCP_FEN = 0x17E0, - EXCP_CALL_PAL = 0x2000, - EXCP_CALL_PALP = 0x3000, - EXCP_CALL_PALE = 0x4000, - /* Pseudo exception for console */ - EXCP_CONSOLE_DISPATCH = 0x4001, - EXCP_CONSOLE_FIXUP = 0x4002, - EXCP_STL_C = 0x4003, - EXCP_STQ_C = 0x4004, + EXCP_RESET, + EXCP_MCHK, + EXCP_SMP_INTERRUPT, + EXCP_CLK_INTERRUPT, + EXCP_DEV_INTERRUPT, + EXCP_MMFAULT, + EXCP_UNALIGN, + EXCP_OPCDEC, + EXCP_ARITH, + EXCP_FEN, + EXCP_CALL_PAL, + /* For Usermode emulation. */ + EXCP_STL_C, + EXCP_STQ_C, +}; + +/* Alpha-specific interrupt pending bits. */ +#define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_EXT_0 +#define CPU_INTERRUPT_SMP CPU_INTERRUPT_TGT_EXT_1 +#define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2 + +/* OSF/1 Page table bits. */ +enum { + PTE_VALID = 0x0001, + PTE_FOR = 0x0002, /* used for page protection (fault on read) */ + PTE_FOW = 0x0004, /* used for page protection (fault on write) */ + PTE_FOE = 0x0008, /* used for page protection (fault on exec) */ + PTE_ASM = 0x0010, + PTE_KRE = 0x0100, + PTE_URE = 0x0200, + PTE_KWE = 0x1000, + PTE_UWE = 0x2000 +}; + +/* Hardware interrupt (entInt) constants. */ +enum { + INT_K_IP, + INT_K_CLK, + INT_K_MCHK, + INT_K_DEV, + INT_K_PERF, +}; + +/* Memory management (entMM) constants. */ +enum { + MM_K_TNV, + MM_K_ACV, + MM_K_FOR, + MM_K_FOE, + MM_K_FOW }; -/* Arithmetic exception */ -#define EXC_M_IOV (1<<16) /* Integer Overflow */ -#define EXC_M_INE (1<<15) /* Inexact result */ -#define EXC_M_UNF (1<<14) /* Underflow */ -#define EXC_M_FOV (1<<13) /* Overflow */ -#define EXC_M_DZE (1<<12) /* Division by zero */ -#define EXC_M_INV (1<<11) /* Invalid operation */ -#define EXC_M_SWC (1<<10) /* Software completion */ +/* Arithmetic exception (entArith) constants. */ +enum { + EXC_M_SWC = 1, /* Software completion */ + EXC_M_INV = 2, /* Invalid operation */ + EXC_M_DZE = 4, /* Division by zero */ + EXC_M_FOV = 8, /* Overflow */ + EXC_M_UNF = 16, /* Underflow */ + EXC_M_INE = 32, /* Inexact result */ + EXC_M_IOV = 64 /* Integer Overflow */ +}; + +/* Processor status constants. */ +enum { + /* Low 3 bits are interrupt mask level. */ + PS_INT_MASK = 7, + + /* Bits 4 and 5 are the mmu mode. The VMS PALcode uses all 4 modes; + The Unix PALcode only uses bit 4. */ + PS_USER_MODE = 8 +}; + +static inline int cpu_mmu_index(CPUState *env) +{ + if (env->pal_mode) { + return MMU_KERNEL_IDX; + } else if (env->ps & PS_USER_MODE) { + return MMU_USER_IDX; + } else { + return MMU_KERNEL_IDX; + } +} enum { IR_V0 = 0, @@ -498,25 +430,53 @@ int cpu_alpha_exec(CPUAlphaState *s); int cpu_alpha_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault void do_interrupt (CPUState *env); uint64_t cpu_alpha_load_fpcr (CPUState *env); void cpu_alpha_store_fpcr (CPUState *env, uint64_t val); -int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp); -int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp); -#if !defined (CONFIG_USER_ONLY) -void pal_init (CPUState *env); -void call_pal (CPUState *env); +#ifndef CONFIG_USER_ONLY +void swap_shadow_regs(CPUState *env); +QEMU_NORETURN void cpu_unassigned_access(CPUState *env1, + target_phys_addr_t addr, int is_write, + int is_exec, int unused, int size); #endif +/* Bits in TB->FLAGS that control how translation is processed. */ +enum { + TB_FLAGS_PAL_MODE = 1, + TB_FLAGS_FEN = 2, + TB_FLAGS_USER_MODE = 8, + + TB_FLAGS_AMASK_SHIFT = 4, + TB_FLAGS_AMASK_BWX = AMASK_BWX << TB_FLAGS_AMASK_SHIFT, + TB_FLAGS_AMASK_FIX = AMASK_FIX << TB_FLAGS_AMASK_SHIFT, + TB_FLAGS_AMASK_CIX = AMASK_CIX << TB_FLAGS_AMASK_SHIFT, + TB_FLAGS_AMASK_MVI = AMASK_MVI << TB_FLAGS_AMASK_SHIFT, + TB_FLAGS_AMASK_TRAP = AMASK_TRAP << TB_FLAGS_AMASK_SHIFT, + TB_FLAGS_AMASK_PREFETCH = AMASK_PREFETCH << TB_FLAGS_AMASK_SHIFT, +}; + static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, - target_ulong *cs_base, int *flags) + target_ulong *cs_base, int *pflags) { + int flags = 0; + *pc = env->pc; *cs_base = 0; - *flags = env->ps; + + if (env->pal_mode) { + flags = TB_FLAGS_PAL_MODE; + } else { + flags = env->ps & PS_USER_MODE; + } + if (env->fen) { + flags |= TB_FLAGS_FEN; + } + flags |= env->amask << TB_FLAGS_AMASK_SHIFT; + + *pflags = flags; } #if defined(CONFIG_USER_ONLY) @@ -535,4 +495,26 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls) } #endif +static inline bool cpu_has_work(CPUState *env) +{ + /* Here we are checking to see if the CPU should wake up from HALT. + We will have gotten into this state only for WTINT from PALmode. */ + /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU + asleep even if (some) interrupts have been asserted. For now, + assume that if a CPU really wants to stay asleep, it will mask + interrupts at the chipset level, which will prevent these bits + from being set in the first place. */ + return env->interrupt_request & (CPU_INTERRUPT_HARD + | CPU_INTERRUPT_TIMER + | CPU_INTERRUPT_SMP + | CPU_INTERRUPT_MCHK); +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->pc = tb->pc; +} + #endif /* !defined (__CPU_ALPHA_H__) */ diff --git a/target-alpha/exec.h b/target-alpha/exec.h deleted file mode 100644 index a8a38d2..0000000 --- a/target-alpha/exec.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Alpha emulation cpu run-time definitions for qemu. - * - * Copyright (c) 2007 Jocelyn Mayer - * - * 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, see . - */ - -#if !defined (__ALPHA_EXEC_H__) -#define __ALPHA_EXEC_H__ - -#include "config.h" - -#include "dyngen-exec.h" - -#define TARGET_LONG_BITS 64 - -register struct CPUAlphaState *env asm(AREG0); - -#define FP_STATUS (env->fp_status) - -#include "cpu.h" -#include "exec-all.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - -static inline int cpu_has_work(CPUState *env) -{ - return (env->interrupt_request & CPU_INTERRUPT_HARD); -} - -static inline int cpu_halted(CPUState *env) -{ - if (!env->halted) - return 0; - if (cpu_has_work(env)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - -#endif /* !defined (__ALPHA_EXEC_H__) */ diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 3ba4478..06d2565 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -22,7 +22,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "softfloat.h" uint64_t cpu_alpha_load_fpcr (CPUState *env) @@ -160,382 +159,299 @@ void cpu_alpha_store_fpcr (CPUState *env, uint64_t val) } #if defined(CONFIG_USER_ONLY) - int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { - if (rw == 2) - env->exception_index = EXCP_ITB_MISS; - else - env->exception_index = EXCP_DFAULT; - env->ipr[IPR_EXC_ADDR] = address; - + env->exception_index = EXCP_MMFAULT; + env->trap_arg0 = address; return 1; } - -void do_interrupt (CPUState *env) +#else +void swap_shadow_regs(CPUState *env) { - env->exception_index = -1; + uint64_t i0, i1, i2, i3, i4, i5, i6, i7; + + i0 = env->ir[8]; + i1 = env->ir[9]; + i2 = env->ir[10]; + i3 = env->ir[11]; + i4 = env->ir[12]; + i5 = env->ir[13]; + i6 = env->ir[14]; + i7 = env->ir[25]; + + env->ir[8] = env->shadow[0]; + env->ir[9] = env->shadow[1]; + env->ir[10] = env->shadow[2]; + env->ir[11] = env->shadow[3]; + env->ir[12] = env->shadow[4]; + env->ir[13] = env->shadow[5]; + env->ir[14] = env->shadow[6]; + env->ir[25] = env->shadow[7]; + + env->shadow[0] = i0; + env->shadow[1] = i1; + env->shadow[2] = i2; + env->shadow[3] = i3; + env->shadow[4] = i4; + env->shadow[5] = i5; + env->shadow[6] = i6; + env->shadow[7] = i7; } -#else +/* Returns the OSF/1 entMM failure indication, or -1 on success. */ +static int get_physical_address(CPUState *env, target_ulong addr, + int prot_need, int mmu_idx, + target_ulong *pphys, int *pprot) +{ + target_long saddr = addr; + target_ulong phys = 0; + target_ulong L1pte, L2pte, L3pte; + target_ulong pt, index; + int prot = 0; + int ret = MM_K_ACV; + + /* Ensure that the virtual address is properly sign-extended from + the last implemented virtual address bit. */ + if (saddr >> TARGET_VIRT_ADDR_SPACE_BITS != saddr >> 63) { + goto exit; + } + + /* Translate the superpage. */ + /* ??? When we do more than emulate Unix PALcode, we'll need to + determine which KSEG is actually active. */ + if (saddr < 0 && ((saddr >> 41) & 3) == 2) { + /* User-space cannot access KSEG addresses. */ + if (mmu_idx != MMU_KERNEL_IDX) { + goto exit; + } + + /* For the benefit of the Typhoon chipset, move bit 40 to bit 43. + We would not do this if the 48-bit KSEG is enabled. */ + phys = saddr & ((1ull << 40) - 1); + phys |= (saddr & (1ull << 40)) << 3; + + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + ret = -1; + goto exit; + } + + /* Interpret the page table exactly like PALcode does. */ -target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) + pt = env->ptbr; + + /* L1 page table read. */ + index = (addr >> (TARGET_PAGE_BITS + 20)) & 0x3ff; + L1pte = ldq_phys(pt + index*8); + + if (unlikely((L1pte & PTE_VALID) == 0)) { + ret = MM_K_TNV; + goto exit; + } + if (unlikely((L1pte & PTE_KRE) == 0)) { + goto exit; + } + pt = L1pte >> 32 << TARGET_PAGE_BITS; + + /* L2 page table read. */ + index = (addr >> (TARGET_PAGE_BITS + 10)) & 0x3ff; + L2pte = ldq_phys(pt + index*8); + + if (unlikely((L2pte & PTE_VALID) == 0)) { + ret = MM_K_TNV; + goto exit; + } + if (unlikely((L2pte & PTE_KRE) == 0)) { + goto exit; + } + pt = L2pte >> 32 << TARGET_PAGE_BITS; + + /* L3 page table read. */ + index = (addr >> TARGET_PAGE_BITS) & 0x3ff; + L3pte = ldq_phys(pt + index*8); + + phys = L3pte >> 32 << TARGET_PAGE_BITS; + if (unlikely((L3pte & PTE_VALID) == 0)) { + ret = MM_K_TNV; + goto exit; + } + +#if PAGE_READ != 1 || PAGE_WRITE != 2 || PAGE_EXEC != 4 +# error page bits out of date +#endif + + /* Check access violations. */ + if (L3pte & (PTE_KRE << mmu_idx)) { + prot |= PAGE_READ | PAGE_EXEC; + } + if (L3pte & (PTE_KWE << mmu_idx)) { + prot |= PAGE_WRITE; + } + if (unlikely((prot & prot_need) == 0 && prot_need)) { + goto exit; + } + + /* Check fault-on-operation violations. */ + prot &= ~(L3pte >> 1); + ret = -1; + if (unlikely((prot & prot_need) == 0)) { + ret = (prot_need & PAGE_EXEC ? MM_K_FOE : + prot_need & PAGE_WRITE ? MM_K_FOW : + prot_need & PAGE_READ ? MM_K_FOR : -1); + } + + exit: + *pphys = phys; + *pprot = prot; + return ret; +} + +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) { - return -1; + target_ulong phys; + int prot, fail; + + fail = get_physical_address(env, addr, 0, 0, &phys, &prot); + return (fail >= 0 ? -1 : phys); } -int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) +int cpu_alpha_handle_mmu_fault(CPUState *env, target_ulong addr, int rw, + int mmu_idx) { - uint32_t opc; - - if (rw == 2) { - /* Instruction translation buffer miss */ - env->exception_index = EXCP_ITB_MISS; - } else { - if (env->ipr[IPR_EXC_ADDR] & 1) - env->exception_index = EXCP_DTB_MISS_PAL; - else - env->exception_index = EXCP_DTB_MISS_NATIVE; - opc = (ldl_code(env->pc) >> 21) << 4; - if (rw) { - opc |= 0x9; - } else { - opc |= 0x4; - } - env->ipr[IPR_MM_STAT] = opc; + target_ulong phys; + int prot, fail; + + fail = get_physical_address(env, addr, 1 << rw, mmu_idx, &phys, &prot); + if (unlikely(fail >= 0)) { + env->exception_index = EXCP_MMFAULT; + env->trap_arg0 = addr; + env->trap_arg1 = fail; + env->trap_arg2 = (rw == 2 ? -1 : rw); + return 1; } - return 1; + tlb_set_page(env, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK, + prot, mmu_idx, TARGET_PAGE_SIZE); + return 0; } +#endif /* USER_ONLY */ -int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp) +void do_interrupt (CPUState *env) { - uint64_t hwpcb; - int ret = 0; - - hwpcb = env->ipr[IPR_PCBB]; - switch (iprn) { - case IPR_ASN: - if (env->features & FEATURE_ASN) - *valp = env->ipr[IPR_ASN]; - else - *valp = 0; - break; - case IPR_ASTEN: - *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60; - break; - case IPR_ASTSR: - *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60; - break; - case IPR_DATFX: - /* Write only */ - ret = -1; - break; - case IPR_ESP: - if (env->features & FEATURE_SPS) - *valp = env->ipr[IPR_ESP]; - else - *valp = ldq_raw(hwpcb + 8); - break; - case IPR_FEN: - *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63; - break; - case IPR_IPIR: - /* Write-only */ - ret = -1; - break; - case IPR_IPL: - *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59; - break; - case IPR_KSP: - if (!(env->ipr[IPR_EXC_ADDR] & 1)) { - ret = -1; - } else { - if (env->features & FEATURE_SPS) - *valp = env->ipr[IPR_KSP]; - else - *valp = ldq_raw(hwpcb + 0); + int i = env->exception_index; + + if (qemu_loglevel_mask(CPU_LOG_INT)) { + static int count; + const char *name = ""; + + switch (i) { + case EXCP_RESET: + name = "reset"; + break; + case EXCP_MCHK: + name = "mchk"; + break; + case EXCP_SMP_INTERRUPT: + name = "smp_interrupt"; + break; + case EXCP_CLK_INTERRUPT: + name = "clk_interrupt"; + break; + case EXCP_DEV_INTERRUPT: + name = "dev_interrupt"; + break; + case EXCP_MMFAULT: + name = "mmfault"; + break; + case EXCP_UNALIGN: + name = "unalign"; + break; + case EXCP_OPCDEC: + name = "opcdec"; + break; + case EXCP_ARITH: + name = "arith"; + break; + case EXCP_FEN: + name = "fen"; + break; + case EXCP_CALL_PAL: + name = "call_pal"; + break; + case EXCP_STL_C: + name = "stl_c"; + break; + case EXCP_STQ_C: + name = "stq_c"; + break; } - break; - case IPR_MCES: - *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59; - break; - case IPR_PERFMON: - /* Implementation specific */ - *valp = 0; - break; - case IPR_PCBB: - *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16; - break; - case IPR_PRBR: - *valp = env->ipr[IPR_PRBR]; - break; - case IPR_PTBR: - *valp = env->ipr[IPR_PTBR]; - break; - case IPR_SCBB: - *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]); - break; - case IPR_SIRR: - /* Write-only */ - ret = -1; - break; - case IPR_SISR: - *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]); - case IPR_SSP: - if (env->features & FEATURE_SPS) - *valp = env->ipr[IPR_SSP]; - else - *valp = ldq_raw(hwpcb + 16); - break; - case IPR_SYSPTBR: - if (env->features & FEATURE_VIRBND) - *valp = env->ipr[IPR_SYSPTBR]; - else - ret = -1; - break; - case IPR_TBCHK: - if ((env->features & FEATURE_TBCHK)) { - /* XXX: TODO */ - *valp = 0; - ret = -1; - } else { - ret = -1; - } - break; - case IPR_TBIA: - /* Write-only */ - ret = -1; - break; - case IPR_TBIAP: - /* Write-only */ - ret = -1; - break; - case IPR_TBIS: - /* Write-only */ - ret = -1; - break; - case IPR_TBISD: - /* Write-only */ - ret = -1; - break; - case IPR_TBISI: - /* Write-only */ - ret = -1; - break; - case IPR_USP: - if (env->features & FEATURE_SPS) - *valp = env->ipr[IPR_USP]; - else - *valp = ldq_raw(hwpcb + 24); - break; - case IPR_VIRBND: - if (env->features & FEATURE_VIRBND) - *valp = env->ipr[IPR_VIRBND]; - else - ret = -1; - break; - case IPR_VPTB: - *valp = env->ipr[IPR_VPTB]; - break; - case IPR_WHAMI: - *valp = env->ipr[IPR_WHAMI]; - break; - default: - /* Invalid */ - ret = -1; - break; + qemu_log("INT %6d: %s(%#x) pc=%016" PRIx64 " sp=%016" PRIx64 "\n", + ++count, name, env->error_code, env->pc, env->ir[IR_SP]); } - return ret; -} + env->exception_index = -1; -int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp) -{ - uint64_t hwpcb, tmp64; - uint8_t tmp8; - int ret = 0; - - hwpcb = env->ipr[IPR_PCBB]; - switch (iprn) { - case IPR_ASN: - /* Read-only */ - ret = -1; - break; - case IPR_ASTEN: - tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4; - *oldvalp = tmp8; - tmp8 &= val & 0xF; - tmp8 |= (val >> 4) & 0xF; - env->ipr[IPR_ASTEN] &= ~0xF; - env->ipr[IPR_ASTEN] |= tmp8; - ret = 1; - break; - case IPR_ASTSR: - tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4; - *oldvalp = tmp8; - tmp8 &= val & 0xF; - tmp8 |= (val >> 4) & 0xF; - env->ipr[IPR_ASTSR] &= ~0xF; - env->ipr[IPR_ASTSR] |= tmp8; - ret = 1; - case IPR_DATFX: - env->ipr[IPR_DATFX] &= ~0x1; - env->ipr[IPR_DATFX] |= val & 1; - tmp64 = ldq_raw(hwpcb + 56); - tmp64 &= ~0x8000000000000000ULL; - tmp64 |= (val & 1) << 63; - stq_raw(hwpcb + 56, tmp64); +#if !defined(CONFIG_USER_ONLY) + switch (i) { + case EXCP_RESET: + i = 0x0000; break; - case IPR_ESP: - if (env->features & FEATURE_SPS) - env->ipr[IPR_ESP] = val; - else - stq_raw(hwpcb + 8, val); + case EXCP_MCHK: + i = 0x0080; break; - case IPR_FEN: - env->ipr[IPR_FEN] = val & 1; - tmp64 = ldq_raw(hwpcb + 56); - tmp64 &= ~1; - tmp64 |= val & 1; - stq_raw(hwpcb + 56, tmp64); + case EXCP_SMP_INTERRUPT: + i = 0x0100; break; - case IPR_IPIR: - /* XXX: TODO: Send IRQ to CPU #ir[16] */ + case EXCP_CLK_INTERRUPT: + i = 0x0180; break; - case IPR_IPL: - *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59; - env->ipr[IPR_IPL] &= ~0x1F; - env->ipr[IPR_IPL] |= val & 0x1F; - /* XXX: may issue an interrupt or ASR _now_ */ - ret = 1; + case EXCP_DEV_INTERRUPT: + i = 0x0200; break; - case IPR_KSP: - if (!(env->ipr[IPR_EXC_ADDR] & 1)) { - ret = -1; - } else { - if (env->features & FEATURE_SPS) - env->ipr[IPR_KSP] = val; - else - stq_raw(hwpcb + 0, val); - } - break; - case IPR_MCES: - env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18); - env->ipr[IPR_MCES] |= val & 0x18; - break; - case IPR_PERFMON: - /* Implementation specific */ - *oldvalp = 0; - ret = 1; + case EXCP_MMFAULT: + i = 0x0280; break; - case IPR_PCBB: - /* Read-only */ - ret = -1; + case EXCP_UNALIGN: + i = 0x0300; break; - case IPR_PRBR: - env->ipr[IPR_PRBR] = val; + case EXCP_OPCDEC: + i = 0x0380; break; - case IPR_PTBR: - /* Read-only */ - ret = -1; + case EXCP_ARITH: + i = 0x0400; break; - case IPR_SCBB: - env->ipr[IPR_SCBB] = (uint32_t)val; + case EXCP_FEN: + i = 0x0480; break; - case IPR_SIRR: - if (val & 0xF) { - env->ipr[IPR_SISR] |= 1 << (val & 0xF); - /* XXX: request a software interrupt _now_ */ + case EXCP_CALL_PAL: + i = env->error_code; + /* There are 64 entry points for both privileged and unprivileged, + with bit 0x80 indicating unprivileged. Each entry point gets + 64 bytes to do its job. */ + if (i & 0x80) { + i = 0x2000 + (i - 0x80) * 64; + } else { + i = 0x1000 + i * 64; } break; - case IPR_SISR: - /* Read-only */ - ret = -1; - break; - case IPR_SSP: - if (env->features & FEATURE_SPS) - env->ipr[IPR_SSP] = val; - else - stq_raw(hwpcb + 16, val); - break; - case IPR_SYSPTBR: - if (env->features & FEATURE_VIRBND) - env->ipr[IPR_SYSPTBR] = val; - else - ret = -1; - break; - case IPR_TBCHK: - /* Read-only */ - ret = -1; - break; - case IPR_TBIA: - tlb_flush(env, 1); - break; - case IPR_TBIAP: - tlb_flush(env, 1); - break; - case IPR_TBIS: - tlb_flush_page(env, val); - break; - case IPR_TBISD: - tlb_flush_page(env, val); - break; - case IPR_TBISI: - tlb_flush_page(env, val); - break; - case IPR_USP: - if (env->features & FEATURE_SPS) - env->ipr[IPR_USP] = val; - else - stq_raw(hwpcb + 24, val); - break; - case IPR_VIRBND: - if (env->features & FEATURE_VIRBND) - env->ipr[IPR_VIRBND] = val; - else - ret = -1; - break; - case IPR_VPTB: - env->ipr[IPR_VPTB] = val; - break; - case IPR_WHAMI: - /* Read-only */ - ret = -1; - break; default: - /* Invalid */ - ret = -1; - break; + cpu_abort(env, "Unhandled CPU exception"); } - return ret; -} + /* Remember where the exception happened. Emulate real hardware in + that the low bit of the PC indicates PALmode. */ + env->exc_addr = env->pc | env->pal_mode; -void do_interrupt (CPUState *env) -{ - int excp; + /* Continue execution at the PALcode entry point. */ + env->pc = env->palbr + i; - env->ipr[IPR_EXC_ADDR] = env->pc | 1; - excp = env->exception_index; - env->exception_index = -1; - env->error_code = 0; - /* XXX: disable interrupts and memory mapping */ - if (env->ipr[IPR_PAL_BASE] != -1ULL) { - /* We use native PALcode */ - env->pc = env->ipr[IPR_PAL_BASE] + excp; - } else { - /* We use emulated PALcode */ - call_pal(env); - /* Emulate REI */ - env->pc = env->ipr[IPR_EXC_ADDR] & ~7; - env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1; - /* XXX: re-enable interrupts and memory mapping */ + /* Switch to PALmode. */ + if (!env->pal_mode) { + env->pal_mode = 1; + swap_shadow_regs(env); } +#endif /* !USER_ONLY */ } -#endif void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf, int flags) @@ -548,7 +464,7 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf, }; int i; - cpu_fprintf(f, " PC " TARGET_FMT_lx " PS " TARGET_FMT_lx "\n", + cpu_fprintf(f, " PC " TARGET_FMT_lx " PS %02x\n", env->pc, env->ps); for (i = 0; i < 31; i++) { cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i, diff --git a/target-alpha/helper.h b/target-alpha/helper.h index ccf6a2a..b693cee 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -100,27 +100,24 @@ DEF_HELPER_1(ieee_input_cmp, i64, i64) DEF_HELPER_1(ieee_input_s, i64, i64) #if !defined (CONFIG_USER_ONLY) -DEF_HELPER_0(hw_rei, void) DEF_HELPER_1(hw_ret, void, i64) -DEF_HELPER_2(mfpr, i64, int, i64) -DEF_HELPER_2(mtpr, void, int, i64) -DEF_HELPER_0(set_alt_mode, void) -DEF_HELPER_0(restore_mode, void) - -DEF_HELPER_1(ld_virt_to_phys, i64, i64) -DEF_HELPER_1(st_virt_to_phys, i64, i64) -DEF_HELPER_2(ldl_raw, void, i64, i64) -DEF_HELPER_2(ldq_raw, void, i64, i64) -DEF_HELPER_2(ldl_l_raw, void, i64, i64) -DEF_HELPER_2(ldq_l_raw, void, i64, i64) -DEF_HELPER_2(ldl_kernel, void, i64, i64) -DEF_HELPER_2(ldq_kernel, void, i64, i64) -DEF_HELPER_2(ldl_data, void, i64, i64) -DEF_HELPER_2(ldq_data, void, i64, i64) -DEF_HELPER_2(stl_raw, void, i64, i64) -DEF_HELPER_2(stq_raw, void, i64, i64) -DEF_HELPER_2(stl_c_raw, i64, i64, i64) -DEF_HELPER_2(stq_c_raw, i64, i64, i64) + +DEF_HELPER_1(ldl_phys, i64, i64) +DEF_HELPER_1(ldq_phys, i64, i64) +DEF_HELPER_1(ldl_l_phys, i64, i64) +DEF_HELPER_1(ldq_l_phys, i64, i64) +DEF_HELPER_2(stl_phys, void, i64, i64) +DEF_HELPER_2(stq_phys, void, i64, i64) +DEF_HELPER_2(stl_c_phys, i64, i64, i64) +DEF_HELPER_2(stq_c_phys, i64, i64, i64) + +DEF_HELPER_FLAGS_0(tbia, TCG_CALL_CONST, void) +DEF_HELPER_FLAGS_1(tbis, TCG_CALL_CONST, void, i64) + +DEF_HELPER_1(halt, void, i64); + +DEF_HELPER_FLAGS_0(get_time, TCG_CALL_CONST, i64) +DEF_HELPER_FLAGS_1(set_alarm, TCG_CALL_CONST, void, i64) #endif #include "def-helper.h" diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index 6c2ae20..cc102db 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -17,25 +17,69 @@ * License along with this library; if not, see . */ -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "host-utils.h" #include "softfloat.h" #include "helper.h" +#include "sysemu.h" #include "qemu-timer.h" +#define FP_STATUS (env->fp_status) + /*****************************************************************************/ /* Exceptions processing helpers */ -void QEMU_NORETURN helper_excp (int excp, int error) + +/* This should only be called from translate, via gen_excp. + We expect that ENV->PC has already been updated. */ +void QEMU_NORETURN helper_excp(int excp, int error) +{ + env->exception_index = excp; + env->error_code = error; + cpu_loop_exit(env); +} + +static void do_restore_state(void *retaddr) +{ + unsigned long pc = (unsigned long)retaddr; + + if (pc) { + TranslationBlock *tb = tb_find_pc(pc); + if (tb) { + cpu_restore_state(tb, env, pc); + } + } +} + +/* This may be called from any of the helpers to set up EXCEPTION_INDEX. */ +static void QEMU_NORETURN dynamic_excp(int excp, int error) { env->exception_index = excp; env->error_code = error; - cpu_loop_exit(); + do_restore_state(GETPC()); + cpu_loop_exit(env); +} + +static void QEMU_NORETURN arith_excp(int exc, uint64_t mask) +{ + env->trap_arg0 = exc; + env->trap_arg1 = mask; + dynamic_excp(EXCP_ARITH, 0); } uint64_t helper_load_pcc (void) { - /* ??? This isn't a timer for which we have any rate info. */ +#ifndef CONFIG_USER_ONLY + /* In system mode we have access to a decent high-resolution clock. + In order to make OS-level time accounting work with the RPCC, + present it with a well-timed clock fixed at 250MHz. */ + return (((uint64_t)env->pcc_ofs << 32) + | (uint32_t)(qemu_get_clock_ns(vm_clock) >> 2)); +#else + /* In user-mode, vm_clock doesn't exist. Just pass through the host cpu + clock ticks. Also, don't bother taking PCC_OFS into account. */ return (uint32_t)cpu_get_real_ticks(); +#endif } uint64_t helper_load_fpcr (void) @@ -53,7 +97,7 @@ uint64_t helper_addqv (uint64_t op1, uint64_t op2) uint64_t tmp = op1; op1 += op2; if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) { - helper_excp(EXCP_ARITH, EXC_M_IOV); + arith_excp(EXC_M_IOV, 0); } return op1; } @@ -63,7 +107,7 @@ uint64_t helper_addlv (uint64_t op1, uint64_t op2) uint64_t tmp = op1; op1 = (uint32_t)(op1 + op2); if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) { - helper_excp(EXCP_ARITH, EXC_M_IOV); + arith_excp(EXC_M_IOV, 0); } return op1; } @@ -73,7 +117,7 @@ uint64_t helper_subqv (uint64_t op1, uint64_t op2) uint64_t res; res = op1 - op2; if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) { - helper_excp(EXCP_ARITH, EXC_M_IOV); + arith_excp(EXC_M_IOV, 0); } return res; } @@ -83,7 +127,7 @@ uint64_t helper_sublv (uint64_t op1, uint64_t op2) uint32_t res; res = op1 - op2; if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) { - helper_excp(EXCP_ARITH, EXC_M_IOV); + arith_excp(EXC_M_IOV, 0); } return res; } @@ -93,7 +137,7 @@ uint64_t helper_mullv (uint64_t op1, uint64_t op2) int64_t res = (int64_t)op1 * (int64_t)op2; if (unlikely((int32_t)res != res)) { - helper_excp(EXCP_ARITH, EXC_M_IOV); + arith_excp(EXC_M_IOV, 0); } return (int64_t)((int32_t)res); } @@ -105,7 +149,7 @@ uint64_t helper_mulqv (uint64_t op1, uint64_t op2) muls64(&tl, &th, op1, op2); /* If th != 0 && th != -1, then we had an overflow */ if (unlikely((th + 1) > 1)) { - helper_excp(EXCP_ARITH, EXC_M_IOV); + arith_excp(EXC_M_IOV, 0); } return tl; } @@ -373,8 +417,6 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno) if (exc) { uint32_t hw_exc = 0; - env->ipr[IPR_EXC_MASK] |= 1ull << regno; - if (exc & float_flag_invalid) { hw_exc |= EXC_M_INV; } @@ -390,7 +432,8 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno) if (exc & float_flag_inexact) { hw_exc |= EXC_M_INE; } - helper_excp(EXCP_ARITH, hw_exc); + + arith_excp(hw_exc, 1ull << regno); } } @@ -420,7 +463,7 @@ uint64_t helper_ieee_input(uint64_t val) if (env->fpcr_dnz) { val &= 1ull << 63; } else { - helper_excp(EXCP_ARITH, EXC_M_UNF); + arith_excp(EXC_M_UNF, 0); } } } else if (exp == 0x7ff) { @@ -428,7 +471,7 @@ uint64_t helper_ieee_input(uint64_t val) /* ??? I'm not sure these exception bit flags are correct. I do know that the Linux kernel, at least, doesn't rely on them and just emulates the insn to figure out what exception to use. */ - helper_excp(EXCP_ARITH, frac ? EXC_M_INV : EXC_M_FOV); + arith_excp(frac ? EXC_M_INV : EXC_M_FOV, 0); } return val; } @@ -445,12 +488,12 @@ uint64_t helper_ieee_input_cmp(uint64_t val) if (env->fpcr_dnz) { val &= 1ull << 63; } else { - helper_excp(EXCP_ARITH, EXC_M_UNF); + arith_excp(EXC_M_UNF, 0); } } } else if (exp == 0x7ff && frac) { /* NaN. */ - helper_excp(EXCP_ARITH, EXC_M_INV); + arith_excp(EXC_M_INV, 0); } return val; } @@ -513,7 +556,7 @@ static inline float32 f_to_float32(uint64_t a) if (unlikely(!exp && mant_sig)) { /* Reserved operands / Dirty zero */ - helper_excp(EXCP_OPCDEC, 0); + dynamic_excp(EXCP_OPCDEC, 0); } if (exp < 3) { @@ -643,7 +686,7 @@ static inline float64 g_to_float64(uint64_t a) if (!exp && mant_sig) { /* Reserved operands / Dirty zero */ - helper_excp(EXCP_OPCDEC, 0); + dynamic_excp(EXCP_OPCDEC, 0); } if (exp < 3) { @@ -904,10 +947,11 @@ uint64_t helper_cmptun (uint64_t a, uint64_t b) fa = t_to_float64(a); fb = t_to_float64(b); - if (float64_is_quiet_nan(fa) || float64_is_quiet_nan(fb)) + if (float64_unordered_quiet(fa, fb, &FP_STATUS)) { return 0x4000000000000000ULL; - else + } else { return 0; + } } uint64_t helper_cmpteq(uint64_t a, uint64_t b) @@ -917,7 +961,7 @@ uint64_t helper_cmpteq(uint64_t a, uint64_t b) fa = t_to_float64(a); fb = t_to_float64(b); - if (float64_eq(fa, fb, &FP_STATUS)) + if (float64_eq_quiet(fa, fb, &FP_STATUS)) return 0x4000000000000000ULL; else return 0; @@ -956,7 +1000,7 @@ uint64_t helper_cmpgeq(uint64_t a, uint64_t b) fa = g_to_float64(a); fb = g_to_float64(b); - if (float64_eq(fa, fb, &FP_STATUS)) + if (float64_eq_quiet(fa, fb, &FP_STATUS)) return 0x4000000000000000ULL; else return 0; @@ -1155,187 +1199,150 @@ uint64_t helper_cvtqg (uint64_t a) /* PALcode support special instructions */ #if !defined (CONFIG_USER_ONLY) -void helper_hw_rei (void) -{ - env->pc = env->ipr[IPR_EXC_ADDR] & ~3; - env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1; - env->intr_flag = 0; - env->lock_addr = -1; - /* XXX: re-enable interrupts and memory mapping */ -} - void helper_hw_ret (uint64_t a) { env->pc = a & ~3; - env->ipr[IPR_EXC_ADDR] = a & 1; env->intr_flag = 0; env->lock_addr = -1; - /* XXX: re-enable interrupts and memory mapping */ + if ((a & 1) == 0) { + env->pal_mode = 0; + swap_shadow_regs(env); + } } -uint64_t helper_mfpr (int iprn, uint64_t val) +void helper_tbia(void) { - uint64_t tmp; - - if (cpu_alpha_mfpr(env, iprn, &tmp) == 0) - val = tmp; - - return val; + tlb_flush(env, 1); } -void helper_mtpr (int iprn, uint64_t val) +void helper_tbis(uint64_t p) { - cpu_alpha_mtpr(env, iprn, val, NULL); + tlb_flush_page(env, p); } -void helper_set_alt_mode (void) +void helper_halt(uint64_t restart) { - env->saved_mode = env->ps & 0xC; - env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC); + if (restart) { + qemu_system_reset_request(); + } else { + qemu_system_shutdown_request(); + } } -void helper_restore_mode (void) +uint64_t helper_get_time(void) { - env->ps = (env->ps & ~0xC) | env->saved_mode; + return qemu_get_clock_ns(rtc_clock); } +void helper_set_alarm(uint64_t expire) +{ + if (expire) { + env->alarm_expire = expire; + qemu_mod_timer(env->alarm_timer, expire); + } else { + qemu_del_timer(env->alarm_timer); + } +} #endif /*****************************************************************************/ /* Softmmu support */ #if !defined (CONFIG_USER_ONLY) - -/* XXX: the two following helpers are pure hacks. - * Hopefully, we emulate the PALcode, then we should never see - * HW_LD / HW_ST instructions. - */ -uint64_t helper_ld_virt_to_phys (uint64_t virtaddr) -{ - uint64_t tlb_addr, physaddr; - int index, mmu_idx; - void *retaddr; - - mmu_idx = cpu_mmu_index(env); - index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - redo: - tlb_addr = env->tlb_table[mmu_idx][index].addr_read; - if ((virtaddr & TARGET_PAGE_MASK) == - (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; - } else { - /* the page is not in the TLB : fill it */ - retaddr = GETPC(); - tlb_fill(virtaddr, 0, mmu_idx, retaddr); - goto redo; - } - return physaddr; -} - -uint64_t helper_st_virt_to_phys (uint64_t virtaddr) +uint64_t helper_ldl_phys(uint64_t p) { - uint64_t tlb_addr, physaddr; - int index, mmu_idx; - void *retaddr; - - mmu_idx = cpu_mmu_index(env); - index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - redo: - tlb_addr = env->tlb_table[mmu_idx][index].addr_write; - if ((virtaddr & TARGET_PAGE_MASK) == - (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend; - } else { - /* the page is not in the TLB : fill it */ - retaddr = GETPC(); - tlb_fill(virtaddr, 1, mmu_idx, retaddr); - goto redo; - } - return physaddr; + return (int32_t)ldl_phys(p); } -void helper_ldl_raw(uint64_t t0, uint64_t t1) +uint64_t helper_ldq_phys(uint64_t p) { - ldl_raw(t1, t0); + return ldq_phys(p); } -void helper_ldq_raw(uint64_t t0, uint64_t t1) +uint64_t helper_ldl_l_phys(uint64_t p) { - ldq_raw(t1, t0); + env->lock_addr = p; + return env->lock_value = (int32_t)ldl_phys(p); } -void helper_ldl_l_raw(uint64_t t0, uint64_t t1) +uint64_t helper_ldq_l_phys(uint64_t p) { - env->lock = t1; - ldl_raw(t1, t0); + env->lock_addr = p; + return env->lock_value = ldl_phys(p); } -void helper_ldq_l_raw(uint64_t t0, uint64_t t1) +void helper_stl_phys(uint64_t p, uint64_t v) { - env->lock = t1; - ldl_raw(t1, t0); + stl_phys(p, v); } -void helper_ldl_kernel(uint64_t t0, uint64_t t1) +void helper_stq_phys(uint64_t p, uint64_t v) { - ldl_kernel(t1, t0); + stq_phys(p, v); } -void helper_ldq_kernel(uint64_t t0, uint64_t t1) +uint64_t helper_stl_c_phys(uint64_t p, uint64_t v) { - ldq_kernel(t1, t0); -} + uint64_t ret = 0; -void helper_ldl_data(uint64_t t0, uint64_t t1) -{ - ldl_data(t1, t0); -} + if (p == env->lock_addr) { + int32_t old = ldl_phys(p); + if (old == (int32_t)env->lock_value) { + stl_phys(p, v); + ret = 1; + } + } + env->lock_addr = -1; -void helper_ldq_data(uint64_t t0, uint64_t t1) -{ - ldq_data(t1, t0); + return ret; } -void helper_stl_raw(uint64_t t0, uint64_t t1) +uint64_t helper_stq_c_phys(uint64_t p, uint64_t v) { - stl_raw(t1, t0); -} + uint64_t ret = 0; -void helper_stq_raw(uint64_t t0, uint64_t t1) -{ - stq_raw(t1, t0); + if (p == env->lock_addr) { + uint64_t old = ldq_phys(p); + if (old == env->lock_value) { + stq_phys(p, v); + ret = 1; + } + } + env->lock_addr = -1; + + return ret; } -uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1) +static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write, + int is_user, void *retaddr) { - uint64_t ret; + uint64_t pc; + uint32_t insn; - if (t1 == env->lock) { - stl_raw(t1, t0); - ret = 0; - } else - ret = 1; + do_restore_state(retaddr); - env->lock = 1; + pc = env->pc; + insn = ldl_code(pc); - return ret; + env->trap_arg0 = addr; + env->trap_arg1 = insn >> 26; /* opcode */ + env->trap_arg2 = (insn >> 21) & 31; /* dest regno */ + helper_excp(EXCP_UNALIGN, 0); } -uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1) +void QEMU_NORETURN cpu_unassigned_access(CPUState *env1, + target_phys_addr_t addr, int is_write, + int is_exec, int unused, int size) { - uint64_t ret; - - if (t1 == env->lock) { - stq_raw(t1, t0); - ret = 0; - } else - ret = 1; - - env->lock = 1; - - return ret; + env = env1; + env->trap_arg0 = addr; + env->trap_arg1 = is_write; + dynamic_excp(EXCP_MCHK, 0); } +#include "softmmu_exec.h" + #define MMUSUFFIX _mmu +#define ALIGNED_ONLY #define SHIFT 0 #include "softmmu_template.h" @@ -1353,33 +1360,20 @@ uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1) NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { - TranslationBlock *tb; CPUState *saved_env; - unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; - ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); - if (!likely(ret == 0)) { - if (likely(retaddr)) { - /* now we have a real cpu fault */ - pc = (unsigned long)retaddr; - tb = tb_find_pc(pc); - if (likely(tb)) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); - } - } + env = env1; + ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx); + if (unlikely(ret != 0)) { + do_restore_state(retaddr); /* Exception index and error code are already set */ - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } - #endif diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 3a1c625..a961159 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -22,7 +22,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "host-utils.h" #include "tcg-op.h" @@ -47,10 +46,6 @@ struct DisasContext { CPUAlphaState *env; uint64_t pc; int mem_idx; -#if !defined (CONFIG_USER_ONLY) - int pal_mode; -#endif - uint32_t amask; /* Current rounding mode for this TB. */ int tb_rm; @@ -89,8 +84,10 @@ static TCGv cpu_pc; static TCGv cpu_lock_addr; static TCGv cpu_lock_st_addr; static TCGv cpu_lock_value; -#ifdef CONFIG_USER_ONLY -static TCGv cpu_uniq; +static TCGv cpu_unique; +#ifndef CONFIG_USER_ONLY +static TCGv cpu_sysval; +static TCGv cpu_usp; #endif /* register names */ @@ -135,9 +132,13 @@ static void alpha_translate_init(void) offsetof(CPUState, lock_value), "lock_value"); -#ifdef CONFIG_USER_ONLY - cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUState, unique), "uniq"); + cpu_unique = tcg_global_mem_new_i64(TCG_AREG0, + offsetof(CPUState, unique), "unique"); +#ifndef CONFIG_USER_ONLY + cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0, + offsetof(CPUState, sysval), "sysval"); + cpu_usp = tcg_global_mem_new_i64(TCG_AREG0, + offsetof(CPUState, usp), "usp"); #endif /* register helpers */ @@ -147,17 +148,21 @@ static void alpha_translate_init(void) done_init = 1; } -static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code) +static void gen_excp_1(int exception, int error_code) { TCGv_i32 tmp1, tmp2; - tcg_gen_movi_i64(cpu_pc, ctx->pc); tmp1 = tcg_const_i32(exception); tmp2 = tcg_const_i32(error_code); gen_helper_excp(tmp1, tmp2); tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp1); +} +static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code) +{ + tcg_gen_movi_i64(cpu_pc, ctx->pc); + gen_excp_1(exception, error_code); return EXIT_NORETURN; } @@ -322,7 +327,7 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb, #if defined(CONFIG_USER_ONLY) addr = cpu_lock_st_addr; #else - addr = tcg_local_new(); + addr = tcg_temp_local_new(); #endif if (rb != 31) { @@ -345,7 +350,7 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb, lab_fail = gen_new_label(); lab_done = gen_new_label(); - tcg_gen_brcond(TCG_COND_NE, addr, cpu_lock_addr, lab_fail); + tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail); val = tcg_temp_new(); if (quad) { @@ -353,7 +358,7 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb, } else { tcg_gen_qemu_ld32s(val, addr, ctx->mem_idx); } - tcg_gen_brcond(TCG_COND_NE, val, cpu_lock_value, lab_fail); + tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail); if (quad) { tcg_gen_qemu_st64(cpu_ir[ra], addr, ctx->mem_idx); @@ -398,7 +403,7 @@ static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp) } else if (use_goto_tb(ctx, dest)) { tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_exit_tb((long)ctx->tb); + tcg_gen_exit_tb((tcg_target_long)ctx->tb); return EXIT_GOTO_TB; } else { tcg_gen_movi_i64(cpu_pc, dest); @@ -417,12 +422,12 @@ static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond, tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, ctx->pc); - tcg_gen_exit_tb((long)ctx->tb); + tcg_gen_exit_tb((tcg_target_long)ctx->tb); gen_set_label(lab_true); tcg_gen_goto_tb(1); tcg_gen_movi_i64(cpu_pc, dest); - tcg_gen_exit_tb((long)ctx->tb + 1); + tcg_gen_exit_tb((tcg_target_long)ctx->tb + 1); return EXIT_GOTO_TB; } else { @@ -1464,12 +1469,242 @@ static void gen_rx(int ra, int set) tcg_temp_free_i32(tmp); } +static ExitStatus gen_call_pal(DisasContext *ctx, int palcode) +{ + /* We're emulating OSF/1 PALcode. Many of these are trivial access + to internal cpu registers. */ + + /* Unprivileged PAL call */ + if (palcode >= 0x80 && palcode < 0xC0) { + switch (palcode) { + case 0x86: + /* IMB */ + /* No-op inside QEMU. */ + break; + case 0x9E: + /* RDUNIQUE */ + tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique); + break; + case 0x9F: + /* WRUNIQUE */ + tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]); + break; + default: + return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf); + } + return NO_EXIT; + } + +#ifndef CONFIG_USER_ONLY + /* Privileged PAL code */ + if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) { + switch (palcode) { + case 0x01: + /* CFLUSH */ + /* No-op inside QEMU. */ + break; + case 0x02: + /* DRAINA */ + /* No-op inside QEMU. */ + break; + case 0x2D: + /* WRVPTPTR */ + tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUState, vptptr)); + break; + case 0x31: + /* WRVAL */ + tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]); + break; + case 0x32: + /* RDVAL */ + tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval); + break; + + case 0x35: { + /* SWPIPL */ + TCGv tmp; + + /* Note that we already know we're in kernel mode, so we know + that PS only contains the 3 IPL bits. */ + tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps)); + + /* But make sure and store only the 3 IPL bits from the user. */ + tmp = tcg_temp_new(); + tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK); + tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUState, ps)); + tcg_temp_free(tmp); + break; + } + + case 0x36: + /* RDPS */ + tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps)); + break; + case 0x38: + /* WRUSP */ + tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]); + break; + case 0x3A: + /* RDUSP */ + tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp); + break; + case 0x3C: + /* WHAMI */ + tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env, + offsetof(CPUState, cpu_index)); + break; + + default: + return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f); + } + return NO_EXIT; + } +#endif + + return gen_invalid(ctx); +} + +#ifndef CONFIG_USER_ONLY + +#define PR_BYTE 0x100000 +#define PR_LONG 0x200000 + +static int cpu_pr_data(int pr) +{ + switch (pr) { + case 0: return offsetof(CPUAlphaState, ps) | PR_BYTE; + case 1: return offsetof(CPUAlphaState, fen) | PR_BYTE; + case 2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG; + case 3: return offsetof(CPUAlphaState, trap_arg0); + case 4: return offsetof(CPUAlphaState, trap_arg1); + case 5: return offsetof(CPUAlphaState, trap_arg2); + case 6: return offsetof(CPUAlphaState, exc_addr); + case 7: return offsetof(CPUAlphaState, palbr); + case 8: return offsetof(CPUAlphaState, ptbr); + case 9: return offsetof(CPUAlphaState, vptptr); + case 10: return offsetof(CPUAlphaState, unique); + case 11: return offsetof(CPUAlphaState, sysval); + case 12: return offsetof(CPUAlphaState, usp); + + case 32 ... 39: + return offsetof(CPUAlphaState, shadow[pr - 32]); + case 40 ... 63: + return offsetof(CPUAlphaState, scratch[pr - 40]); + + case 251: + return offsetof(CPUAlphaState, alarm_expire); + } + return 0; +} + +static ExitStatus gen_mfpr(int ra, int regno) +{ + int data = cpu_pr_data(regno); + + /* In our emulated PALcode, these processor registers have no + side effects from reading. */ + if (ra == 31) { + return NO_EXIT; + } + + if (regno == 250) { + /* WALL_TIME */ + if (use_icount) { + gen_io_start(); + gen_helper_get_time(cpu_ir[ra]); + gen_io_end(); + return EXIT_PC_STALE; + } else { + gen_helper_get_time(cpu_ir[ra]); + return NO_EXIT; + } + } + + /* The basic registers are data only, and unknown registers + are read-zero, write-ignore. */ + if (data == 0) { + tcg_gen_movi_i64(cpu_ir[ra], 0); + } else if (data & PR_BYTE) { + tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, data & ~PR_BYTE); + } else if (data & PR_LONG) { + tcg_gen_ld32s_i64(cpu_ir[ra], cpu_env, data & ~PR_LONG); + } else { + tcg_gen_ld_i64(cpu_ir[ra], cpu_env, data); + } + return NO_EXIT; +} + +static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno) +{ + TCGv tmp; + int data; + + if (rb == 31) { + tmp = tcg_const_i64(0); + } else { + tmp = cpu_ir[rb]; + } + + switch (regno) { + case 255: + /* TBIA */ + gen_helper_tbia(); + break; + + case 254: + /* TBIS */ + gen_helper_tbis(tmp); + break; + + case 253: + /* WAIT */ + tmp = tcg_const_i64(1); + tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUState, halted)); + return gen_excp(ctx, EXCP_HLT, 0); + + case 252: + /* HALT */ + gen_helper_halt(tmp); + return EXIT_PC_STALE; + + case 251: + /* ALARM */ + gen_helper_set_alarm(tmp); + break; + + default: + /* The basic registers are data only, and unknown registers + are read-zero, write-ignore. */ + data = cpu_pr_data(regno); + if (data != 0) { + if (data & PR_BYTE) { + tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE); + } else if (data & PR_LONG) { + tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG); + } else { + tcg_gen_st_i64(tmp, cpu_env, data); + } + } + break; + } + + if (rb == 31) { + tcg_temp_free(tmp); + } + + return NO_EXIT; +} +#endif /* !USER_ONLY*/ + static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) { uint32_t palcode; - int32_t disp21, disp16, disp12; + int32_t disp21, disp16; +#ifndef CONFIG_USER_ONLY + int32_t disp12; +#endif uint16_t fn11; - uint8_t opc, ra, rb, rc, fpfn, fn7, fn2, islit, real_islit; + uint8_t opc, ra, rb, rc, fpfn, fn7, islit, real_islit; uint8_t lit; ExitStatus ret; @@ -1487,11 +1722,12 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) palcode = insn & 0x03FFFFFF; disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11; disp16 = (int16_t)(insn & 0x0000FFFF); +#ifndef CONFIG_USER_ONLY disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20; +#endif fn11 = (insn >> 5) & 0x000007FF; fpfn = fn11 & 0x3F; fn7 = (insn >> 5) & 0x0000007F; - fn2 = (insn >> 5) & 0x00000003; LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n", opc, ra, rb, rc, disp16); @@ -1499,32 +1735,8 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch (opc) { case 0x00: /* CALL_PAL */ -#ifdef CONFIG_USER_ONLY - if (palcode == 0x9E) { - /* RDUNIQUE */ - tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq); - break; - } else if (palcode == 0x9F) { - /* WRUNIQUE */ - tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]); - break; - } -#endif - if (palcode >= 0x80 && palcode < 0xC0) { - /* Unprivileged PAL call */ - ret = gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0); - break; - } -#ifndef CONFIG_USER_ONLY - if (palcode < 0x40) { - /* Privileged PAL code */ - if (ctx->mem_idx & 1) - goto invalid_opc; - ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0); - } -#endif - /* Invalid PAL call */ - goto invalid_opc; + ret = gen_call_pal(ctx, palcode); + break; case 0x01: /* OPC01 */ goto invalid_opc; @@ -1566,20 +1778,22 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x0A: /* LDBU */ - if (!(ctx->amask & AMASK_BWX)) - goto invalid_opc; - gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) { + gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0); + break; + } + goto invalid_opc; case 0x0B: /* LDQ_U */ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1); break; case 0x0C: /* LDWU */ - if (!(ctx->amask & AMASK_BWX)) - goto invalid_opc; - gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) { + gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0); + break; + } + goto invalid_opc; case 0x0D: /* STW */ gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0); @@ -1983,20 +2197,12 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x61: /* AMASK */ if (likely(rc != 31)) { - if (islit) - tcg_gen_movi_i64(cpu_ir[rc], lit); - else - tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]); - switch (ctx->env->implver) { - case IMPLVER_2106x: - /* EV4, EV45, LCA, LCA45 & EV5 */ - break; - case IMPLVER_21164: - case IMPLVER_21264: - case IMPLVER_21364: - tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rc], - ~(uint64_t)ctx->amask); - break; + uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT; + + if (islit) { + tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask); + } else { + tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask); } } break; @@ -2210,8 +2416,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch (fpfn) { /* fn11 & 0x3F */ case 0x04: /* ITOFS */ - if (!(ctx->amask & AMASK_FIX)) + if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) { goto invalid_opc; + } if (likely(rc != 31)) { if (ra != 31) { TCGv_i32 tmp = tcg_temp_new_i32(); @@ -2224,20 +2431,23 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x0A: /* SQRTF */ - if (!(ctx->amask & AMASK_FIX)) - goto invalid_opc; - gen_fsqrtf(rb, rc); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) { + gen_fsqrtf(rb, rc); + break; + } + goto invalid_opc; case 0x0B: /* SQRTS */ - if (!(ctx->amask & AMASK_FIX)) - goto invalid_opc; - gen_fsqrts(ctx, rb, rc, fn11); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) { + gen_fsqrts(ctx, rb, rc, fn11); + break; + } + goto invalid_opc; case 0x14: /* ITOFF */ - if (!(ctx->amask & AMASK_FIX)) + if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) { goto invalid_opc; + } if (likely(rc != 31)) { if (ra != 31) { TCGv_i32 tmp = tcg_temp_new_i32(); @@ -2250,8 +2460,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x24: /* ITOFT */ - if (!(ctx->amask & AMASK_FIX)) + if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) { goto invalid_opc; + } if (likely(rc != 31)) { if (ra != 31) tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]); @@ -2261,16 +2472,18 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x2A: /* SQRTG */ - if (!(ctx->amask & AMASK_FIX)) - goto invalid_opc; - gen_fsqrtg(rb, rc); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) { + gen_fsqrtg(rb, rc); + break; + } + goto invalid_opc; case 0x02B: /* SQRTT */ - if (!(ctx->amask & AMASK_FIX)) - goto invalid_opc; - gen_fsqrtt(ctx, rb, rc, fn11); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) { + gen_fsqrtt(ctx, rb, rc, fn11); + break; + } + goto invalid_opc; default: goto invalid_opc; } @@ -2547,8 +2760,16 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0xC000: /* RPCC */ - if (ra != 31) - gen_helper_load_pcc(cpu_ir[ra]); + if (ra != 31) { + if (use_icount) { + gen_io_start(); + gen_helper_load_pcc(cpu_ir[ra]); + gen_io_end(); + ret = EXIT_PC_STALE; + } else { + gen_helper_load_pcc(cpu_ir[ra]); + } + } break; case 0xE000: /* RC */ @@ -2571,18 +2792,12 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x19: /* HW_MFPR (PALcode) */ -#if defined (CONFIG_USER_ONLY) - goto invalid_opc; -#else - if (!ctx->pal_mode) - goto invalid_opc; - if (ra != 31) { - TCGv tmp = tcg_const_i32(insn & 0xFF); - gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]); - tcg_temp_free(tmp); +#ifndef CONFIG_USER_ONLY + if (ctx->tb->flags & TB_FLAGS_PAL_MODE) { + return gen_mfpr(ra, insn & 0xffff); } - break; #endif + goto invalid_opc; case 0x1A: /* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch prediction stack action, which of course we don't implement. */ @@ -2598,13 +2813,15 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x1B: /* HW_LD (PALcode) */ -#if defined (CONFIG_USER_ONLY) - goto invalid_opc; -#else - if (!ctx->pal_mode) - goto invalid_opc; - if (ra != 31) { - TCGv addr = tcg_temp_new(); +#ifndef CONFIG_USER_ONLY + if (ctx->tb->flags & TB_FLAGS_PAL_MODE) { + TCGv addr; + + if (ra == 31) { + break; + } + + addr = tcg_temp_new(); if (rb != 31) tcg_gen_addi_i64(addr, cpu_ir[rb], disp12); else @@ -2612,27 +2829,26 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access (hw_ldl/p) */ - gen_helper_ldl_raw(cpu_ir[ra], addr); + gen_helper_ldl_phys(cpu_ir[ra], addr); break; case 0x1: /* Quadword physical access (hw_ldq/p) */ - gen_helper_ldq_raw(cpu_ir[ra], addr); + gen_helper_ldq_phys(cpu_ir[ra], addr); break; case 0x2: /* Longword physical access with lock (hw_ldl_l/p) */ - gen_helper_ldl_l_raw(cpu_ir[ra], addr); + gen_helper_ldl_l_phys(cpu_ir[ra], addr); break; case 0x3: /* Quadword physical access with lock (hw_ldq_l/p) */ - gen_helper_ldq_l_raw(cpu_ir[ra], addr); + gen_helper_ldq_l_phys(cpu_ir[ra], addr); break; case 0x4: /* Longword virtual PTE fetch (hw_ldl/v) */ - tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0); - break; + goto invalid_opc; case 0x5: /* Quadword virtual PTE fetch (hw_ldq/v) */ - tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0); + goto invalid_opc; break; case 0x6: /* Incpu_ir[ra]id */ @@ -2642,63 +2858,47 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) goto invalid_opc; case 0x8: /* Longword virtual access (hw_ldl) */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldl_raw(cpu_ir[ra], addr); - break; + goto invalid_opc; case 0x9: /* Quadword virtual access (hw_ldq) */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldq_raw(cpu_ir[ra], addr); - break; + goto invalid_opc; case 0xA: /* Longword virtual access with protection check (hw_ldl/w) */ - tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0); + tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_KERNEL_IDX); break; case 0xB: /* Quadword virtual access with protection check (hw_ldq/w) */ - tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0); + tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_KERNEL_IDX); break; case 0xC: /* Longword virtual access with alt access mode (hw_ldl/a)*/ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldl_raw(cpu_ir[ra], addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xD: /* Quadword virtual access with alt access mode (hw_ldq/a) */ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_ldq_raw(cpu_ir[ra], addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xE: /* Longword virtual access with alternate access mode and - * protection checks (hw_ldl/wa) - */ - gen_helper_set_alt_mode(); - gen_helper_ldl_data(cpu_ir[ra], addr); - gen_helper_restore_mode(); + protection checks (hw_ldl/wa) */ + tcg_gen_qemu_ld32s(cpu_ir[ra], addr, MMU_USER_IDX); break; case 0xF: /* Quadword virtual access with alternate access mode and - * protection checks (hw_ldq/wa) - */ - gen_helper_set_alt_mode(); - gen_helper_ldq_data(cpu_ir[ra], addr); - gen_helper_restore_mode(); + protection checks (hw_ldq/wa) */ + tcg_gen_qemu_ld64(cpu_ir[ra], addr, MMU_USER_IDX); break; } tcg_temp_free(addr); + break; } - break; #endif + goto invalid_opc; case 0x1C: switch (fn7) { case 0x00: /* SEXTB */ - if (!(ctx->amask & AMASK_BWX)) + if ((ctx->tb->flags & TB_FLAGS_AMASK_BWX) == 0) { goto invalid_opc; + } if (likely(rc != 31)) { if (islit) tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit)); @@ -2708,138 +2908,164 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x01: /* SEXTW */ - if (!(ctx->amask & AMASK_BWX)) - goto invalid_opc; - if (likely(rc != 31)) { - if (islit) - tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit)); - else - tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]); + if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) { + if (likely(rc != 31)) { + if (islit) { + tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit)); + } else { + tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]); + } + } + break; } - break; + goto invalid_opc; case 0x30: /* CTPOP */ - if (!(ctx->amask & AMASK_CIX)) - goto invalid_opc; - if (likely(rc != 31)) { - if (islit) - tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit)); - else - gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]); + if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) { + if (likely(rc != 31)) { + if (islit) { + tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit)); + } else { + gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]); + } + } + break; } - break; + goto invalid_opc; case 0x31: /* PERR */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_perr(ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_perr(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x32: /* CTLZ */ - if (!(ctx->amask & AMASK_CIX)) - goto invalid_opc; - if (likely(rc != 31)) { - if (islit) - tcg_gen_movi_i64(cpu_ir[rc], clz64(lit)); - else - gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]); + if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) { + if (likely(rc != 31)) { + if (islit) { + tcg_gen_movi_i64(cpu_ir[rc], clz64(lit)); + } else { + gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]); + } + } + break; } - break; + goto invalid_opc; case 0x33: /* CTTZ */ - if (!(ctx->amask & AMASK_CIX)) - goto invalid_opc; - if (likely(rc != 31)) { - if (islit) - tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit)); - else - gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]); + if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) { + if (likely(rc != 31)) { + if (islit) { + tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit)); + } else { + gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]); + } + } + break; } - break; + goto invalid_opc; case 0x34: /* UNPKBW */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - if (real_islit || ra != 31) - goto invalid_opc; - gen_unpkbw (rb, rc); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + if (real_islit || ra != 31) { + goto invalid_opc; + } + gen_unpkbw(rb, rc); + break; + } + goto invalid_opc; case 0x35: /* UNPKBL */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - if (real_islit || ra != 31) - goto invalid_opc; - gen_unpkbl (rb, rc); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + if (real_islit || ra != 31) { + goto invalid_opc; + } + gen_unpkbl(rb, rc); + break; + } + goto invalid_opc; case 0x36: /* PKWB */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - if (real_islit || ra != 31) - goto invalid_opc; - gen_pkwb (rb, rc); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + if (real_islit || ra != 31) { + goto invalid_opc; + } + gen_pkwb(rb, rc); + break; + } + goto invalid_opc; case 0x37: /* PKLB */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - if (real_islit || ra != 31) - goto invalid_opc; - gen_pklb (rb, rc); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + if (real_islit || ra != 31) { + goto invalid_opc; + } + gen_pklb(rb, rc); + break; + } + goto invalid_opc; case 0x38: /* MINSB8 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_minsb8 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_minsb8(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x39: /* MINSW4 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_minsw4 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_minsw4(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x3A: /* MINUB8 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_minub8 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_minub8(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x3B: /* MINUW4 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_minuw4 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_minuw4(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x3C: /* MAXUB8 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_maxub8 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_maxub8(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x3D: /* MAXUW4 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_maxuw4 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_maxuw4(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x3E: /* MAXSB8 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_maxsb8 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_maxsb8(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x3F: /* MAXSW4 */ - if (!(ctx->amask & AMASK_MVI)) - goto invalid_opc; - gen_maxsw4 (ra, rb, rc, islit, lit); - break; + if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) { + gen_maxsw4(ra, rb, rc, islit, lit); + break; + } + goto invalid_opc; case 0x70: /* FTOIT */ - if (!(ctx->amask & AMASK_FIX)) + if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) { goto invalid_opc; + } if (likely(rc != 31)) { if (ra != 31) tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]); @@ -2849,8 +3075,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x78: /* FTOIS */ - if (!(ctx->amask & AMASK_FIX)) + if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) { goto invalid_opc; + } if (rc != 31) { TCGv_i32 tmp1 = tcg_temp_new_i32(); if (ra != 31) @@ -2870,57 +3097,36 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x1D: /* HW_MTPR (PALcode) */ -#if defined (CONFIG_USER_ONLY) - goto invalid_opc; -#else - if (!ctx->pal_mode) - goto invalid_opc; - else { - TCGv tmp1 = tcg_const_i32(insn & 0xFF); - if (ra != 31) - gen_helper_mtpr(tmp1, cpu_ir[ra]); - else { - TCGv tmp2 = tcg_const_i64(0); - gen_helper_mtpr(tmp1, tmp2); - tcg_temp_free(tmp2); - } - tcg_temp_free(tmp1); - ret = EXIT_PC_STALE; +#ifndef CONFIG_USER_ONLY + if (ctx->tb->flags & TB_FLAGS_PAL_MODE) { + return gen_mtpr(ctx, rb, insn & 0xffff); } - break; #endif - case 0x1E: - /* HW_REI (PALcode) */ -#if defined (CONFIG_USER_ONLY) goto invalid_opc; -#else - if (!ctx->pal_mode) - goto invalid_opc; - if (rb == 31) { - /* "Old" alpha */ - gen_helper_hw_rei(); - } else { - TCGv tmp; - - if (ra != 31) { - tmp = tcg_temp_new(); - tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51)); - } else - tmp = tcg_const_i64(((int64_t)insn << 51) >> 51); - gen_helper_hw_ret(tmp); - tcg_temp_free(tmp); + case 0x1E: + /* HW_RET (PALcode) */ +#ifndef CONFIG_USER_ONLY + if (ctx->tb->flags & TB_FLAGS_PAL_MODE) { + if (rb == 31) { + /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return + address from EXC_ADDR. This turns out to be useful for our + emulation PALcode, so continue to accept it. */ + TCGv tmp = tcg_temp_new(); + tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUState, exc_addr)); + gen_helper_hw_ret(tmp); + tcg_temp_free(tmp); + } else { + gen_helper_hw_ret(cpu_ir[rb]); + } + ret = EXIT_PC_UPDATED; + break; } - ret = EXIT_PC_UPDATED; - break; #endif + goto invalid_opc; case 0x1F: /* HW_ST (PALcode) */ -#if defined (CONFIG_USER_ONLY) - goto invalid_opc; -#else - if (!ctx->pal_mode) - goto invalid_opc; - else { +#ifndef CONFIG_USER_ONLY + if (ctx->tb->flags & TB_FLAGS_PAL_MODE) { TCGv addr, val; addr = tcg_temp_new(); if (rb != 31) @@ -2936,30 +3142,26 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch ((insn >> 12) & 0xF) { case 0x0: /* Longword physical access */ - gen_helper_stl_raw(val, addr); + gen_helper_stl_phys(addr, val); break; case 0x1: /* Quadword physical access */ - gen_helper_stq_raw(val, addr); + gen_helper_stq_phys(addr, val); break; case 0x2: /* Longword physical access with lock */ - gen_helper_stl_c_raw(val, val, addr); + gen_helper_stl_c_phys(val, addr, val); break; case 0x3: /* Quadword physical access with lock */ - gen_helper_stq_c_raw(val, val, addr); + gen_helper_stq_c_phys(val, addr, val); break; case 0x4: /* Longword virtual access */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stl_raw(val, addr); - break; + goto invalid_opc; case 0x5: /* Quadword virtual access */ - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stq_raw(val, addr); - break; + goto invalid_opc; case 0x6: /* Invalid */ goto invalid_opc; @@ -2980,18 +3182,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) goto invalid_opc; case 0xC: /* Longword virtual access with alternate access mode */ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stl_raw(val, addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xD: /* Quadword virtual access with alternate access mode */ - gen_helper_set_alt_mode(); - gen_helper_st_virt_to_phys(addr, addr); - gen_helper_stl_raw(val, addr); - gen_helper_restore_mode(); - break; + goto invalid_opc; case 0xE: /* Invalid */ goto invalid_opc; @@ -3002,9 +3196,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) if (ra == 31) tcg_temp_free(val); tcg_temp_free(addr); + break; } - break; #endif + goto invalid_opc; case 0x20: /* LDF */ gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0); @@ -3155,13 +3350,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, ctx.tb = tb; ctx.env = env; ctx.pc = pc_start; - ctx.amask = env->amask; -#if defined (CONFIG_USER_ONLY) - ctx.mem_idx = 0; -#else - ctx.mem_idx = ((env->ps >> 3) & 3); - ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1; -#endif + ctx.mem_idx = cpu_mmu_index(env); /* ??? Every TB begins with unset rounding mode, to be initialized on the first fp insn of the TB. Alternately we could define a proper @@ -3211,18 +3400,15 @@ static inline void gen_intermediate_code_internal(CPUState *env, ctx.pc += 4; ret = translate_one(ctxp, insn); - if (ret == NO_EXIT) { - /* If we reach a page boundary, are single stepping, - or exhaust instruction count, stop generation. */ - if (env->singlestep_enabled) { - gen_excp(&ctx, EXCP_DEBUG, 0); - ret = EXIT_PC_UPDATED; - } else if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 - || gen_opc_ptr >= gen_opc_end - || num_insns >= max_insns - || singlestep) { - ret = EXIT_PC_STALE; - } + /* If we reach a page boundary, are single stepping, + or exhaust instruction count, stop generation. */ + if (ret == NO_EXIT + && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 + || gen_opc_ptr >= gen_opc_end + || num_insns >= max_insns + || singlestep + || env->singlestep_enabled)) { + ret = EXIT_PC_STALE; } } while (ret == NO_EXIT); @@ -3238,7 +3424,11 @@ static inline void gen_intermediate_code_internal(CPUState *env, tcg_gen_movi_i64(cpu_pc, ctx.pc); /* FALLTHRU */ case EXIT_PC_UPDATED: - tcg_gen_exit_tb(0); + if (env->singlestep_enabled) { + gen_excp_1(EXCP_DEBUG, 0); + } else { + tcg_gen_exit_tb(0); + } break; default: abort(); @@ -3304,7 +3494,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) CPUAlphaState *env; int implver, amask, i, max; - env = qemu_mallocz(sizeof(CPUAlphaState)); + env = g_malloc0(sizeof(CPUAlphaState)); cpu_exec_init(env); alpha_translate_init(); tlb_flush(env, 1); @@ -3325,50 +3515,19 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) env->implver = implver; env->amask = amask; - env->ps = 0x1F00; #if defined (CONFIG_USER_ONLY) - env->ps |= 1 << 3; + env->ps = PS_USER_MODE; cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD | FPCR_UNFD | FPCR_INED | FPCR_DNOD)); -#else - pal_init(env); #endif env->lock_addr = -1; - - /* Initialize IPR */ -#if defined (CONFIG_USER_ONLY) - env->ipr[IPR_EXC_ADDR] = 0; - env->ipr[IPR_EXC_SUM] = 0; - env->ipr[IPR_EXC_MASK] = 0; -#else - { - // uint64_t hwpcb; - // hwpcb = env->ipr[IPR_PCBB]; - env->ipr[IPR_ASN] = 0; - env->ipr[IPR_ASTEN] = 0; - env->ipr[IPR_ASTSR] = 0; - env->ipr[IPR_DATFX] = 0; - /* XXX: fix this */ - // env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8); - // env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0); - // env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16); - // env->ipr[IPR_USP] = ldq_raw(hwpcb + 24); - env->ipr[IPR_FEN] = 0; - env->ipr[IPR_IPL] = 31; - env->ipr[IPR_MCES] = 0; - env->ipr[IPR_PERFMON] = 0; /* Implementation specific */ - // env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32); - env->ipr[IPR_SISR] = 0; - env->ipr[IPR_VIRBND] = -1ULL; - } -#endif + env->fen = 1; qemu_init_vcpu(env); return env; } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->pc = gen_opc_pc[pc_pos]; } diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 5bcd53a..c4d742f 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -55,6 +55,10 @@ #define ARMV7M_EXCP_PENDSV 14 #define ARMV7M_EXCP_SYSTICK 15 +/* ARM-specific interrupt pending bits. */ +#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1 + + typedef void ARMWriteCPFunc(void *opaque, int cp_info, int srcreg, int operand, uint32_t value); typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info, @@ -126,8 +130,15 @@ typedef struct CPUARMState { uint32_t c6_region[8]; /* MPU base/size registers. */ uint32_t c6_insn; /* Fault address registers. */ uint32_t c6_data; + uint32_t c7_par; /* Translation result. */ uint32_t c9_insn; /* Cache lockdown registers. */ uint32_t c9_data; + uint32_t c9_pmcr; /* performance monitor control register */ + uint32_t c9_pmcnten; /* perf monitor counter enables */ + uint32_t c9_pmovsr; /* perf monitor overflow status */ + uint32_t c9_pmxevtyper; /* perf monitor event type */ + uint32_t c9_pmuserenr; /* perf monitor user enable */ + uint32_t c9_pminten; /* perf monitor interrupt enables */ uint32_t c13_fcse; /* FCSE PID. */ uint32_t c13_context; /* Context ID. */ uint32_t c13_tls1; /* User RW Thread register. */ @@ -157,10 +168,6 @@ typedef struct CPUARMState { /* Internal CPU feature flags. */ uint32_t features; - /* Callback for vectored interrupt controller. */ - int (*get_irq_vector)(struct CPUARMState *); - void *irq_opaque; - /* VFP coprocessor state. */ struct { float64 regs[32]; @@ -220,7 +227,7 @@ typedef struct CPUARMState { void *opaque; } cp[15]; void *nvic; - struct arm_boot_info *boot_info; + const struct arm_boot_info *boot_info; } CPUARMState; CPUARMState *cpu_arm_init(const char *cpu_model); @@ -237,7 +244,7 @@ uint32_t do_arm_semihosting(CPUARMState *env); int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw, - int mmu_idx, int is_softmuu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls) @@ -359,10 +366,17 @@ enum arm_features { ARM_FEATURE_VFP3, ARM_FEATURE_VFP_FP16, ARM_FEATURE_NEON, - ARM_FEATURE_DIV, + ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */ ARM_FEATURE_M, /* Microcontroller profile. */ ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */ - ARM_FEATURE_THUMB2EE + ARM_FEATURE_THUMB2EE, + ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */ + ARM_FEATURE_V4T, + ARM_FEATURE_V5, + ARM_FEATURE_STRONGARM, + ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */ + ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */ + ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */ }; static inline int arm_feature(CPUARMState *env, int feature) @@ -393,6 +407,8 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, #define ARM_CPUID_ARM946 0x41059461 #define ARM_CPUID_TI915T 0x54029152 #define ARM_CPUID_TI925T 0x54029252 +#define ARM_CPUID_SA1100 0x4401A11B +#define ARM_CPUID_SA1110 0x6901B119 #define ARM_CPUID_PXA250 0x69052100 #define ARM_CPUID_PXA255 0x69052d00 #define ARM_CPUID_PXA260 0x69052903 @@ -407,6 +423,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, #define ARM_CPUID_PXA270_C5 0x69054117 #define ARM_CPUID_ARM1136 0x4117b363 #define ARM_CPUID_ARM1136_R2 0x4107b362 +#define ARM_CPUID_ARM1176 0x410fb767 #define ARM_CPUID_ARM11MPCORE 0x410fb022 #define ARM_CPUID_CORTEXA8 0x410fc080 #define ARM_CPUID_CORTEXA9 0x410fc090 @@ -431,7 +448,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, #define cpu_signal_handler cpu_arm_signal_handler #define cpu_list arm_cpu_list -#define CPU_SAVE_VERSION 2 +#define CPU_SAVE_VERSION 4 /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel @@ -505,4 +522,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, } } +static inline bool cpu_has_work(CPUState *env) +{ + return env->interrupt_request & + (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB); +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->regs[15] = tb->pc; +} + #endif diff --git a/target-arm/exec.h b/target-arm/exec.h deleted file mode 100644 index e4c35a3..0000000 --- a/target-arm/exec.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ARM execution defines - * - * Copyright (c) 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, see . - */ -#include "config.h" -#include "dyngen-exec.h" - -register struct CPUARMState *env asm(AREG0); - -#define M0 env->iwmmxt.val - -#include "cpu.h" -#include "exec-all.h" - -static inline int cpu_has_work(CPUState *env) -{ - return (env->interrupt_request & - (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)); -} - -static inline int cpu_halted(CPUState *env) { - if (!env->halted) - return 0; - /* An interrupt wakes the CPU even if the I and F CPSR bits are - set. We use EXITTB to silently wake CPU without causing an - actual interrupt. */ - if (cpu_has_work(env)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif - -void raise_exception(int); - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->regs[15] = tb->pc; -} - diff --git a/target-arm/helper.c b/target-arm/helper.c index b562767..97af4d0 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -3,9 +3,8 @@ #include #include "cpu.h" -#include "exec-all.h" #include "gdbstub.h" -#include "helpers.h" +#include "helper.h" #include "qemu-common.h" #include "host-utils.h" #if !defined(CONFIG_USER_ONLY) @@ -36,6 +35,12 @@ static uint32_t arm1136_cp15_c0_c1[8] = static uint32_t arm1136_cp15_c0_c2[8] = { 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 }; +static uint32_t arm1176_cp15_c0_c1[8] = +{ 0x111, 0x11, 0x33, 0, 0x01130003, 0x10030302, 0x01222100, 0 }; + +static uint32_t arm1176_cp15_c0_c2[8] = +{ 0x0140011, 0x12002111, 0x11231121, 0x01102131, 0x01141, 0, 0, 0 }; + static uint32_t cpu_arm_find_by_name(const char *name); static inline void set_feature(CPUARMState *env, int feature) @@ -48,28 +53,47 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_cpuid = id; switch (id) { case ARM_CPUID_ARM926: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_VFP); env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; case ARM_CPUID_ARM946: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_MPU); env->cp15.c0_cachetype = 0x0f004006; env->cp15.c1_sys = 0x00000078; break; case ARM_CPUID_ARM1026: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_AUXCR); env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00090078; break; - case ARM_CPUID_ARM1136_R2: case ARM_CPUID_ARM1136: + /* This is the 1136 r1, which is a v6K core */ + set_feature(env, ARM_FEATURE_V6K); + /* Fall through */ + case ARM_CPUID_ARM1136_R2: + /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an + * older core than plain "arm1136". In particular this does not + * have the v6K features. + */ + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_AUXCR); + /* These ID register values are correct for 1136 but may be wrong + * for 1136_r2 (in particular r0p2 does not actually implement most + * of the ID registers). + */ env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; @@ -78,11 +102,30 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_cachetype = 0x1dd20d2; env->cp15.c1_sys = 0x00050078; break; + case ARM_CPUID_ARM1176: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); + set_feature(env, ARM_FEATURE_V6); + set_feature(env, ARM_FEATURE_V6K); + set_feature(env, ARM_FEATURE_VFP); + set_feature(env, ARM_FEATURE_AUXCR); + set_feature(env, ARM_FEATURE_VAPA); + env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b5; + env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; + env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; + memcpy(env->cp15.c0_c1, arm1176_cp15_c0_c1, 8 * sizeof(uint32_t)); + memcpy(env->cp15.c0_c2, arm1176_cp15_c0_c2, 8 * sizeof(uint32_t)); + env->cp15.c0_cachetype = 0x1dd20d2; + env->cp15.c1_sys = 0x00050078; + break; case ARM_CPUID_ARM11MPCORE: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_AUXCR); + set_feature(env, ARM_FEATURE_VAPA); env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; @@ -91,6 +134,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_cachetype = 0x1dd20d2; break; case ARM_CPUID_CORTEXA8: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); set_feature(env, ARM_FEATURE_V7); @@ -113,6 +158,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXA9: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); set_feature(env, ARM_FEATURE_V7); @@ -123,6 +170,11 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) set_feature(env, ARM_FEATURE_VFP_FP16); set_feature(env, ARM_FEATURE_NEON); set_feature(env, ARM_FEATURE_THUMB2EE); + /* Note that A9 supports the MP extensions even for + * A9UP and single-core A9MP (which are both different + * and valid configurations; we don't model A9UP). + */ + set_feature(env, ARM_FEATURE_V7MP); env->vfp.xregs[ARM_VFP_FPSID] = 0x41034000; /* Guess */ env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; env->vfp.xregs[ARM_VFP_MVFR1] = 0x01111111; @@ -135,26 +187,33 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c1_sys = 0x00c50078; break; case ARM_CPUID_CORTEXM3: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_THUMB2); set_feature(env, ARM_FEATURE_V7); set_feature(env, ARM_FEATURE_M); - set_feature(env, ARM_FEATURE_DIV); + set_feature(env, ARM_FEATURE_THUMB_DIV); break; case ARM_CPUID_ANY: /* For userspace emulation. */ + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_V6); set_feature(env, ARM_FEATURE_V6K); set_feature(env, ARM_FEATURE_V7); set_feature(env, ARM_FEATURE_THUMB2); set_feature(env, ARM_FEATURE_VFP); set_feature(env, ARM_FEATURE_VFP3); + set_feature(env, ARM_FEATURE_VFP4); set_feature(env, ARM_FEATURE_VFP_FP16); set_feature(env, ARM_FEATURE_NEON); set_feature(env, ARM_FEATURE_THUMB2EE); - set_feature(env, ARM_FEATURE_DIV); + set_feature(env, ARM_FEATURE_ARM_DIV); + set_feature(env, ARM_FEATURE_V7MP); break; case ARM_CPUID_TI915T: case ARM_CPUID_TI925T: + set_feature(env, ARM_FEATURE_V4T); set_feature(env, ARM_FEATURE_OMAPCP); env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring. */ env->cp15.c0_cachetype = 0x5109149; @@ -167,6 +226,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA260: case ARM_CPUID_PXA261: case ARM_CPUID_PXA262: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_XSCALE); /* JTAG_ID is ((id << 28) | 0x09265013) */ env->cp15.c0_cachetype = 0xd172172; @@ -178,6 +239,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) case ARM_CPUID_PXA270_B1: case ARM_CPUID_PXA270_C0: case ARM_CPUID_PXA270_C5: + set_feature(env, ARM_FEATURE_V4T); + set_feature(env, ARM_FEATURE_V5); set_feature(env, ARM_FEATURE_XSCALE); /* JTAG_ID is ((id << 28) | 0x09265013) */ set_feature(env, ARM_FEATURE_IWMMXT); @@ -185,10 +248,23 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) env->cp15.c0_cachetype = 0xd172172; env->cp15.c1_sys = 0x00000078; break; + case ARM_CPUID_SA1100: + case ARM_CPUID_SA1110: + set_feature(env, ARM_FEATURE_STRONGARM); + env->cp15.c1_sys = 0x00000070; + break; default: cpu_abort(env, "Bad CPU ID: %x\n", id); break; } + + /* Some features automatically imply others: */ + if (arm_feature(env, ARM_FEATURE_V7)) { + set_feature(env, ARM_FEATURE_VAPA); + } + if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { + set_feature(env, ARM_FEATURE_THUMB_DIV); + } } void cpu_reset(CPUARMState *env) @@ -226,7 +302,7 @@ void cpu_reset(CPUARMState *env) if (rom) { /* We should really use ldl_phys here, in case the guest modified flash and reset itself. However images - loaded via -kenrel have not been copied yet, so load the + loaded via -kernel have not been copied yet, so load the values directly from there. */ env->regs[13] = ldl_p(rom); pc = ldl_p(rom + 4); @@ -236,10 +312,18 @@ void cpu_reset(CPUARMState *env) } env->vfp.xregs[ARM_VFP_FPEXC] = 0; env->cp15.c2_base_mask = 0xffffc000u; + /* v7 performance monitor control register: same implementor + * field as main ID register, and we implement no event counters. + */ + env->cp15.c9_pmcr = (id & 0xff000000); #endif set_flush_to_zero(1, &env->vfp.standard_fp_status); set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.fp_status); + set_float_detect_tininess(float_tininess_before_rounding, + &env->vfp.standard_fp_status); tlb_flush(env, 1); } @@ -304,7 +388,7 @@ CPUARMState *cpu_arm_init(const char *cpu_model) id = cpu_arm_find_by_name(cpu_model); if (id == 0) return NULL; - env = qemu_mallocz(sizeof(CPUARMState)); + env = g_malloc0(sizeof(CPUARMState)); cpu_exec_init(env); if (!inited) { inited = 1; @@ -339,12 +423,15 @@ static const struct arm_cpu_t arm_cpu_names[] = { { ARM_CPUID_ARM1026, "arm1026"}, { ARM_CPUID_ARM1136, "arm1136"}, { ARM_CPUID_ARM1136_R2, "arm1136-r2"}, + { ARM_CPUID_ARM1176, "arm1176"}, { ARM_CPUID_ARM11MPCORE, "arm11mpcore"}, { ARM_CPUID_CORTEXM3, "cortex-m3"}, { ARM_CPUID_CORTEXA8, "cortex-a8"}, { ARM_CPUID_CORTEXA9, "cortex-a9"}, { ARM_CPUID_TI925T, "ti925t" }, { ARM_CPUID_PXA250, "pxa250" }, + { ARM_CPUID_SA1100, "sa1100" }, + { ARM_CPUID_SA1110, "sa1110" }, { ARM_CPUID_PXA255, "pxa255" }, { ARM_CPUID_PXA260, "pxa260" }, { ARM_CPUID_PXA261, "pxa261" }, @@ -388,7 +475,7 @@ static uint32_t cpu_arm_find_by_name(const char *name) void cpu_arm_close(CPUARMState *env) { - free(env); + g_free(env); } uint32_t cpsr_read(CPUARMState *env) @@ -499,7 +586,7 @@ void do_interrupt (CPUState *env) } int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { if (rw == 2) { env->exception_index = EXCP_PREFETCH_ABORT; @@ -808,6 +895,7 @@ void do_interrupt(CPUARMState *env) return; } } + env->cp15.c5_insn = 2; /* Fall through to prefetch abort. */ case EXCP_PREFETCH_ABORT: new_mode = ARM_CPU_MODE_ABT; @@ -850,7 +938,11 @@ void do_interrupt(CPUARMState *env) /* Switch to the new mode, and to the correct instruction set. */ env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; env->uncached_cpsr |= mask; - env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0; + /* this is a lie, as the was no c1_sys on V4T/V5, but who cares + * and we should just guard the thumb mode on V4 */ + if (arm_feature(env, ARM_FEATURE_V4T)) { + env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0; + } env->regs[14] = env->regs[15] + offset; env->regs[15] = addr; env->interrupt_request |= CPU_INTERRUPT_EXITTB; @@ -900,7 +992,7 @@ static inline int check_ap(CPUState *env, int ap, int domain, int access_type, case 6: return prot_ro; case 7: - if (!arm_feature (env, ARM_FEATURE_V7)) + if (!arm_feature (env, ARM_FEATURE_V6K)) return 0; return prot_ro; default: @@ -1206,7 +1298,7 @@ static inline int get_phys_addr(CPUState *env, uint32_t address, } int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, - int access_type, int mmu_idx, int is_softmmu) + int access_type, int mmu_idx) { uint32_t phys_addr; target_ulong page_size; @@ -1341,7 +1433,7 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) /* This may enable/disable the MMU, so do a TLB flush. */ tlb_flush(env, 1); break; - case 1: /* Auxiliary cotrol register. */ + case 1: /* Auxiliary control register. */ if (arm_feature(env, ARM_FEATURE_XSCALE)) { env->cp15.c1_xscaleauxcr = val; break; @@ -1450,8 +1542,49 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) case 7: /* Cache control. */ env->cp15.c15_i_max = 0x000; env->cp15.c15_i_min = 0xff0; - /* No cache, so nothing to do. */ - /* ??? MPCore has VA to PA translation functions. */ + if (op1 != 0) { + goto bad_reg; + } + /* No cache, so nothing to do except VA->PA translations. */ + if (arm_feature(env, ARM_FEATURE_VAPA)) { + switch (crm) { + case 4: + if (arm_feature(env, ARM_FEATURE_V7)) { + env->cp15.c7_par = val & 0xfffff6ff; + } else { + env->cp15.c7_par = val & 0xfffff1ff; + } + break; + case 8: { + uint32_t phys_addr; + target_ulong page_size; + int prot; + int ret, is_user = op2 & 2; + int access_type = op2 & 1; + + if (op2 & 4) { + /* Other states are only available with TrustZone */ + goto bad_reg; + } + ret = get_phys_addr(env, val, access_type, is_user, + &phys_addr, &prot, &page_size); + if (ret == 0) { + /* We do not set any attribute bits in the PAR */ + if (page_size == (1 << 24) + && arm_feature(env, ARM_FEATURE_V7)) { + env->cp15.c7_par = (phys_addr & 0xff000000) | 1 << 1; + } else { + env->cp15.c7_par = phys_addr & 0xfffff000; + } + } else { + env->cp15.c7_par = ((ret & (10 << 1)) >> 5) | + ((ret & (12 << 1)) >> 6) | + ((ret & 0xf) << 1) | 1; + } + break; + } + } + } break; case 8: /* MMU TLB control. */ switch (op2) { @@ -1475,6 +1608,8 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) case 9: if (arm_feature(env, ARM_FEATURE_OMAPCP)) break; + if (arm_feature(env, ARM_FEATURE_STRONGARM)) + break; /* Ignore ReadBuffer access */ switch (crm) { case 0: /* Cache lockdown. */ switch (op1) { @@ -1500,6 +1635,81 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) case 1: /* TCM memory region registers. */ /* Not implemented. */ goto bad_reg; + case 12: /* Performance monitor control */ + /* Performance monitors are implementation defined in v7, + * but with an ARM recommended set of registers, which we + * follow (although we don't actually implement any counters) + */ + if (!arm_feature(env, ARM_FEATURE_V7)) { + goto bad_reg; + } + switch (op2) { + case 0: /* performance monitor control register */ + /* only the DP, X, D and E bits are writable */ + env->cp15.c9_pmcr &= ~0x39; + env->cp15.c9_pmcr |= (val & 0x39); + break; + case 1: /* Count enable set register */ + val &= (1 << 31); + env->cp15.c9_pmcnten |= val; + break; + case 2: /* Count enable clear */ + val &= (1 << 31); + env->cp15.c9_pmcnten &= ~val; + break; + case 3: /* Overflow flag status */ + env->cp15.c9_pmovsr &= ~val; + break; + case 4: /* Software increment */ + /* RAZ/WI since we don't implement the software-count event */ + break; + case 5: /* Event counter selection register */ + /* Since we don't implement any events, writing to this register + * is actually UNPREDICTABLE. So we choose to RAZ/WI. + */ + break; + default: + goto bad_reg; + } + break; + case 13: /* Performance counters */ + if (!arm_feature(env, ARM_FEATURE_V7)) { + goto bad_reg; + } + switch (op2) { + case 0: /* Cycle count register: not implemented, so RAZ/WI */ + break; + case 1: /* Event type select */ + env->cp15.c9_pmxevtyper = val & 0xff; + break; + case 2: /* Event count register */ + /* Unimplemented (we have no events), RAZ/WI */ + break; + default: + goto bad_reg; + } + break; + case 14: /* Performance monitor control */ + if (!arm_feature(env, ARM_FEATURE_V7)) { + goto bad_reg; + } + switch (op2) { + case 0: /* user enable */ + env->cp15.c9_pmuserenr = val & 1; + /* changes access rights for cp registers, so flush tbs */ + tb_flush(env); + break; + case 1: /* interrupt enable set */ + /* We have no event counters so only the C bit can be changed */ + val &= (1 << 31); + env->cp15.c9_pminten |= val; + break; + case 2: /* interrupt enable clear */ + val &= (1 << 31); + env->cp15.c9_pminten &= ~val; + break; + } + break; default: goto bad_reg; } @@ -1602,12 +1812,28 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) return 0; case 3: /* TLB type register. */ return 0; /* No lockable TLB entries. */ - case 5: /* CPU ID */ - if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) { - return env->cpu_index | 0x80000900; - } else { - return env->cpu_index; + case 5: /* MPIDR */ + /* The MPIDR was standardised in v7; prior to + * this it was implemented only in the 11MPCore. + * For all other pre-v7 cores it does not exist. + */ + if (arm_feature(env, ARM_FEATURE_V7) || + ARM_CPUID(env) == ARM_CPUID_ARM11MPCORE) { + int mpidr = env->cpu_index; + /* We don't support setting cluster ID ([8..11]) + * so these bits always RAZ. + */ + if (arm_feature(env, ARM_FEATURE_V7MP)) { + mpidr |= (1 << 31); + /* Cores which are uniprocessor (non-coherent) + * but still implement the MP extensions set + * bit 30. (For instance, A9UP.) However we do + * not currently model any of those cores. + */ + } + return mpidr; } + /* otherwise fall through to the unimplemented-reg case */ default: goto bad_reg; } @@ -1666,6 +1892,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) return 1; case ARM_CPUID_ARM1136: case ARM_CPUID_ARM1136_R2: + case ARM_CPUID_ARM1176: return 7; case ARM_CPUID_ARM11MPCORE: return 1; @@ -1767,32 +1994,89 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) } } case 7: /* Cache control. */ + if (crm == 4 && op1 == 0 && op2 == 0) { + return env->cp15.c7_par; + } /* FIXME: Should only clear Z flag if destination is r15. */ env->ZF = 0; return 0; case 8: /* MMU TLB control. */ goto bad_reg; - case 9: /* Cache lockdown. */ - switch (op1) { - case 0: /* L1 cache. */ - if (arm_feature(env, ARM_FEATURE_OMAPCP)) - return 0; + case 9: + switch (crm) { + case 0: /* Cache lockdown */ + switch (op1) { + case 0: /* L1 cache. */ + if (arm_feature(env, ARM_FEATURE_OMAPCP)) { + return 0; + } + switch (op2) { + case 0: + return env->cp15.c9_data; + case 1: + return env->cp15.c9_insn; + default: + goto bad_reg; + } + case 1: /* L2 cache */ + if (crm != 0) { + goto bad_reg; + } + /* L2 Lockdown and Auxiliary control. */ + return 0; + default: + goto bad_reg; + } + break; + case 12: /* Performance monitor control */ + if (!arm_feature(env, ARM_FEATURE_V7)) { + goto bad_reg; + } switch (op2) { - case 0: - return env->cp15.c9_data; - case 1: - return env->cp15.c9_insn; + case 0: /* performance monitor control register */ + return env->cp15.c9_pmcr; + case 1: /* count enable set */ + case 2: /* count enable clear */ + return env->cp15.c9_pmcnten; + case 3: /* overflow flag status */ + return env->cp15.c9_pmovsr; + case 4: /* software increment */ + case 5: /* event counter selection register */ + return 0; /* Unimplemented, RAZ/WI */ default: goto bad_reg; } - case 1: /* L2 cache */ - if (crm != 0) + case 13: /* Performance counters */ + if (!arm_feature(env, ARM_FEATURE_V7)) { + goto bad_reg; + } + switch (op2) { + case 1: /* Event type select */ + return env->cp15.c9_pmxevtyper; + case 0: /* Cycle count register */ + case 2: /* Event count register */ + /* Unimplemented, so RAZ/WI */ + return 0; + default: + goto bad_reg; + } + case 14: /* Performance monitor control */ + if (!arm_feature(env, ARM_FEATURE_V7)) { + goto bad_reg; + } + switch (op2) { + case 0: /* user enable */ + return env->cp15.c9_pmuserenr; + case 1: /* interrupt enable set */ + case 2: /* interrupt enable clear */ + return env->cp15.c9_pminten; + default: goto bad_reg; - /* L2 Lockdown and Auxiliary control. */ - return 0; + } default: goto bad_reg; } + break; case 10: /* MMU TLB lockdown. */ /* ??? TLB lockdown not implemented. */ return 0; @@ -1888,11 +2172,11 @@ uint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg) return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ return (env->uncached_cpsr & CPSR_I) != 0; - case 17: /* FAULTMASK */ - return (env->uncached_cpsr & CPSR_F) != 0; - case 18: /* BASEPRI */ - case 19: /* BASEPRI_MAX */ + case 17: /* BASEPRI */ + case 18: /* BASEPRI_MAX */ return env->v7m.basepri; + case 19: /* FAULTMASK */ + return (env->uncached_cpsr & CPSR_F) != 0; case 20: /* CONTROL */ return env->v7m.control; default: @@ -1944,20 +2228,20 @@ void HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val) else env->uncached_cpsr &= ~CPSR_I; break; - case 17: /* FAULTMASK */ - if (val & 1) - env->uncached_cpsr |= CPSR_F; - else - env->uncached_cpsr &= ~CPSR_F; - break; - case 18: /* BASEPRI */ + case 17: /* BASEPRI */ env->v7m.basepri = val & 0xff; break; - case 19: /* BASEPRI_MAX */ + case 18: /* BASEPRI_MAX */ val &= 0xff; if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) env->v7m.basepri = val; break; + case 19: /* FAULTMASK */ + if (val & 1) + env->uncached_cpsr |= CPSR_F; + else + env->uncached_cpsr &= ~CPSR_F; + break; case 20: /* CONTROL */ env->v7m.control = val & 3; switch_v7m_sp(env, (val & 2) != 0); @@ -2105,7 +2389,7 @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b) /* Signed modulo arithmetic. */ #define SARITH16(a, b, n, op) do { \ int32_t sum; \ - sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \ + sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \ RESULT(sum, n, 16); \ if (sum >= 0) \ ge |= 3 << (n * 2); \ @@ -2113,7 +2397,7 @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b) #define SARITH8(a, b, n, op) do { \ int32_t sum; \ - sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \ + sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \ RESULT(sum, n, 8); \ if (sum >= 0) \ ge |= 1 << n; \ @@ -2249,7 +2533,7 @@ static inline int vfp_exceptbits_from_host(int host_bits) target_bits |= 2; if (host_bits & float_flag_overflow) target_bits |= 4; - if (host_bits & float_flag_underflow) + if (host_bits & (float_flag_underflow | float_flag_output_denormal)) target_bits |= 8; if (host_bits & float_flag_inexact) target_bits |= 0x10; @@ -2346,13 +2630,15 @@ void vfp_set_fpscr(CPUState *env, uint32_t val) #define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p)) #define VFP_BINOP(name) \ -float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \ +float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \ { \ - return float32_ ## name (a, b, &env->vfp.fp_status); \ + float_status *fpst = fpstp; \ + return float32_ ## name(a, b, fpst); \ } \ -float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \ +float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \ { \ - return float64_ ## name (a, b, &env->vfp.fp_status); \ + float_status *fpst = fpstp; \ + return float64_ ## name(a, b, fpst); \ } VFP_BINOP(add) VFP_BINOP(sub) @@ -2420,136 +2706,39 @@ DO_VFP_cmp(s, float32) DO_VFP_cmp(d, float64) #undef DO_VFP_cmp -/* Helper routines to perform bitwise copies between float and int. */ -static inline float32 vfp_itos(uint32_t i) -{ - union { - uint32_t i; - float32 s; - } v; - - v.i = i; - return v.s; -} - -static inline uint32_t vfp_stoi(float32 s) -{ - union { - uint32_t i; - float32 s; - } v; - - v.s = s; - return v.i; -} - -static inline float64 vfp_itod(uint64_t i) -{ - union { - uint64_t i; - float64 d; - } v; - - v.i = i; - return v.d; -} - -static inline uint64_t vfp_dtoi(float64 d) -{ - union { - uint64_t i; - float64 d; - } v; - - v.d = d; - return v.i; -} - -/* Integer to float conversion. */ -float32 VFP_HELPER(uito, s)(float32 x, CPUState *env) -{ - return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status); -} - -float64 VFP_HELPER(uito, d)(float32 x, CPUState *env) -{ - return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status); -} - -float32 VFP_HELPER(sito, s)(float32 x, CPUState *env) -{ - return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status); -} - -float64 VFP_HELPER(sito, d)(float32 x, CPUState *env) -{ - return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status); -} - -/* Float to integer conversion. */ -float32 VFP_HELPER(toui, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status)); -} - -float32 VFP_HELPER(toui, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status)); -} - -float32 VFP_HELPER(tosi, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float32_to_int32(x, &env->vfp.fp_status)); -} +/* Integer to float and float to integer conversions */ -float32 VFP_HELPER(tosi, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float64_to_int32(x, &env->vfp.fp_status)); +#define CONV_ITOF(name, fsz, sign) \ + float##fsz HELPER(name)(uint32_t x, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + return sign##int32_to_##float##fsz(x, fpst); \ } -float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status)); +#define CONV_FTOI(name, fsz, sign, round) \ +uint32_t HELPER(name)(float##fsz x, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + if (float##fsz##_is_any_nan(x)) { \ + float_raise(float_flag_invalid, fpst); \ + return 0; \ + } \ + return float##fsz##_to_##sign##int32##round(x, fpst); \ } -float32 VFP_HELPER(touiz, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status)); -} +#define FLOAT_CONVS(name, p, fsz, sign) \ +CONV_ITOF(vfp_##name##to##p, fsz, sign) \ +CONV_FTOI(vfp_to##name##p, fsz, sign, ) \ +CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero) -float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status)); -} +FLOAT_CONVS(si, s, 32, ) +FLOAT_CONVS(si, d, 64, ) +FLOAT_CONVS(ui, s, 32, u) +FLOAT_CONVS(ui, d, 64, u) -float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - return float32_zero; - } - return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status)); -} +#undef CONV_ITOF +#undef CONV_FTOI +#undef FLOAT_CONVS /* floating point conversion */ float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env) @@ -2571,110 +2760,342 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env) } /* VFP3 fixed point conversion. */ -#define VFP_CONV_FIX(name, p, ftype, itype, sign) \ -ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \ +#define VFP_CONV_FIX(name, p, fsz, itype, sign) \ +float##fsz HELPER(vfp_##name##to##p)(uint##fsz##_t x, uint32_t shift, \ + void *fpstp) \ { \ - ftype tmp; \ - tmp = sign##int32_to_##ftype ((itype##_t)vfp_##p##toi(x), \ - &env->vfp.fp_status); \ - return ftype##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \ + float_status *fpst = fpstp; \ + float##fsz tmp; \ + tmp = sign##int32_to_##float##fsz((itype##_t)x, fpst); \ + return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ } \ -ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \ +uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \ + void *fpstp) \ { \ - ftype tmp; \ - if (ftype##_is_any_nan(x)) { \ - return ftype##_zero; \ + float_status *fpst = fpstp; \ + float##fsz tmp; \ + if (float##fsz##_is_any_nan(x)) { \ + float_raise(float_flag_invalid, fpst); \ + return 0; \ } \ - tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \ - return vfp_ito##p(ftype##_to_##itype##_round_to_zero(tmp, \ - &env->vfp.fp_status)); \ -} - -VFP_CONV_FIX(sh, d, float64, int16, ) -VFP_CONV_FIX(sl, d, float64, int32, ) -VFP_CONV_FIX(uh, d, float64, uint16, u) -VFP_CONV_FIX(ul, d, float64, uint32, u) -VFP_CONV_FIX(sh, s, float32, int16, ) -VFP_CONV_FIX(sl, s, float32, int32, ) -VFP_CONV_FIX(uh, s, float32, uint16, u) -VFP_CONV_FIX(ul, s, float32, uint32, u) + tmp = float##fsz##_scalbn(x, shift, fpst); \ + return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \ +} + +VFP_CONV_FIX(sh, d, 64, int16, ) +VFP_CONV_FIX(sl, d, 64, int32, ) +VFP_CONV_FIX(uh, d, 64, uint16, u) +VFP_CONV_FIX(ul, d, 64, uint32, u) +VFP_CONV_FIX(sh, s, 32, int16, ) +VFP_CONV_FIX(sl, s, 32, int32, ) +VFP_CONV_FIX(uh, s, 32, uint16, u) +VFP_CONV_FIX(ul, s, 32, uint32, u) #undef VFP_CONV_FIX /* Half precision conversions. */ -float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUState *env) +static float32 do_fcvt_f16_to_f32(uint32_t a, CPUState *env, float_status *s) { - float_status *s = &env->vfp.fp_status; int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - return float16_to_float32(a, ieee, s); + float32 r = float16_to_float32(make_float16(a), ieee, s); + if (ieee) { + return float32_maybe_silence_nan(r); + } + return r; } -uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUState *env) +static uint32_t do_fcvt_f32_to_f16(float32 a, CPUState *env, float_status *s) { - float_status *s = &env->vfp.fp_status; int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0; - return float32_to_float16(a, ieee, s); + float16 r = float32_to_float16(a, ieee, s); + if (ieee) { + r = float16_maybe_silence_nan(r); + } + return float16_val(r); } +float32 HELPER(neon_fcvt_f16_to_f32)(uint32_t a, CPUState *env) +{ + return do_fcvt_f16_to_f32(a, env, &env->vfp.standard_fp_status); +} + +uint32_t HELPER(neon_fcvt_f32_to_f16)(float32 a, CPUState *env) +{ + return do_fcvt_f32_to_f16(a, env, &env->vfp.standard_fp_status); +} + +float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUState *env) +{ + return do_fcvt_f16_to_f32(a, env, &env->vfp.fp_status); +} + +uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUState *env) +{ + return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status); +} + +#define float32_two make_float32(0x40000000) +#define float32_three make_float32(0x40400000) +#define float32_one_point_five make_float32(0x3fc00000) + float32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env) { - float_status *s = &env->vfp.fp_status; - float32 two = int32_to_float32(2, s); - return float32_sub(two, float32_mul(a, b, s), s); + float_status *s = &env->vfp.standard_fp_status; + if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) || + (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) { + if (!(float32_is_zero(a) || float32_is_zero(b))) { + float_raise(float_flag_input_denormal, s); + } + return float32_two; + } + return float32_sub(float32_two, float32_mul(a, b, s), s); } float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env) { float_status *s = &env->vfp.standard_fp_status; - float32 two = int32_to_float32(2, s); - float32 three = int32_to_float32(3, s); float32 product; if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) || (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) { - product = float32_zero; - } else { - product = float32_mul(a, b, s); + if (!(float32_is_zero(a) || float32_is_zero(b))) { + float_raise(float_flag_input_denormal, s); + } + return float32_one_point_five; } - return float32_div(float32_sub(three, product, s), two, s); + product = float32_mul(a, b, s); + return float32_div(float32_sub(float32_three, product, s), float32_two, s); } /* NEON helpers. */ -/* TODO: The architecture specifies the value that the estimate functions - should return. We return the exact reciprocal/root instead. */ +/* Constants 256 and 512 are used in some helpers; we avoid relying on + * int->float conversions at run-time. */ +#define float64_256 make_float64(0x4070000000000000LL) +#define float64_512 make_float64(0x4080000000000000LL) + +/* The algorithm that must be used to calculate the estimate + * is specified by the ARM ARM. + */ +static float64 recip_estimate(float64 a, CPUState *env) +{ + /* These calculations mustn't set any fp exception flags, + * so we use a local copy of the fp_status. + */ + float_status dummy_status = env->vfp.standard_fp_status; + float_status *s = &dummy_status; + /* q = (int)(a * 512.0) */ + float64 q = float64_mul(float64_512, a, s); + int64_t q_int = float64_to_int64_round_to_zero(q, s); + + /* r = 1.0 / (((double)q + 0.5) / 512.0) */ + q = int64_to_float64(q_int, s); + q = float64_add(q, float64_half, s); + q = float64_div(q, float64_512, s); + q = float64_div(float64_one, q, s); + + /* s = (int)(256.0 * r + 0.5) */ + q = float64_mul(q, float64_256, s); + q = float64_add(q, float64_half, s); + q_int = float64_to_int64_round_to_zero(q, s); + + /* return (double)s / 256.0 */ + return float64_div(int64_to_float64(q_int, s), float64_256, s); +} + float32 HELPER(recpe_f32)(float32 a, CPUState *env) { - float_status *s = &env->vfp.fp_status; - float32 one = int32_to_float32(1, s); - return float32_div(one, a, s); + float_status *s = &env->vfp.standard_fp_status; + float64 f64; + uint32_t val32 = float32_val(a); + + int result_exp; + int a_exp = (val32 & 0x7f800000) >> 23; + int sign = val32 & 0x80000000; + + if (float32_is_any_nan(a)) { + if (float32_is_signaling_nan(a)) { + float_raise(float_flag_invalid, s); + } + return float32_default_nan; + } else if (float32_is_infinity(a)) { + return float32_set_sign(float32_zero, float32_is_neg(a)); + } else if (float32_is_zero_or_denormal(a)) { + if (!float32_is_zero(a)) { + float_raise(float_flag_input_denormal, s); + } + float_raise(float_flag_divbyzero, s); + return float32_set_sign(float32_infinity, float32_is_neg(a)); + } else if (a_exp >= 253) { + float_raise(float_flag_underflow, s); + return float32_set_sign(float32_zero, float32_is_neg(a)); + } + + f64 = make_float64((0x3feULL << 52) + | ((int64_t)(val32 & 0x7fffff) << 29)); + + result_exp = 253 - a_exp; + + f64 = recip_estimate(f64, env); + + val32 = sign + | ((result_exp & 0xff) << 23) + | ((float64_val(f64) >> 29) & 0x7fffff); + return make_float32(val32); +} + +/* The algorithm that must be used to calculate the estimate + * is specified by the ARM ARM. + */ +static float64 recip_sqrt_estimate(float64 a, CPUState *env) +{ + /* These calculations mustn't set any fp exception flags, + * so we use a local copy of the fp_status. + */ + float_status dummy_status = env->vfp.standard_fp_status; + float_status *s = &dummy_status; + float64 q; + int64_t q_int; + + if (float64_lt(a, float64_half, s)) { + /* range 0.25 <= a < 0.5 */ + + /* a in units of 1/512 rounded down */ + /* q0 = (int)(a * 512.0); */ + q = float64_mul(float64_512, a, s); + q_int = float64_to_int64_round_to_zero(q, s); + + /* reciprocal root r */ + /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0); */ + q = int64_to_float64(q_int, s); + q = float64_add(q, float64_half, s); + q = float64_div(q, float64_512, s); + q = float64_sqrt(q, s); + q = float64_div(float64_one, q, s); + } else { + /* range 0.5 <= a < 1.0 */ + + /* a in units of 1/256 rounded down */ + /* q1 = (int)(a * 256.0); */ + q = float64_mul(float64_256, a, s); + int64_t q_int = float64_to_int64_round_to_zero(q, s); + + /* reciprocal root r */ + /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */ + q = int64_to_float64(q_int, s); + q = float64_add(q, float64_half, s); + q = float64_div(q, float64_256, s); + q = float64_sqrt(q, s); + q = float64_div(float64_one, q, s); + } + /* r in units of 1/256 rounded to nearest */ + /* s = (int)(256.0 * r + 0.5); */ + + q = float64_mul(q, float64_256,s ); + q = float64_add(q, float64_half, s); + q_int = float64_to_int64_round_to_zero(q, s); + + /* return (double)s / 256.0;*/ + return float64_div(int64_to_float64(q_int, s), float64_256, s); } float32 HELPER(rsqrte_f32)(float32 a, CPUState *env) { - float_status *s = &env->vfp.fp_status; - float32 one = int32_to_float32(1, s); - return float32_div(one, float32_sqrt(a, s), s); + float_status *s = &env->vfp.standard_fp_status; + int result_exp; + float64 f64; + uint32_t val; + uint64_t val64; + + val = float32_val(a); + + if (float32_is_any_nan(a)) { + if (float32_is_signaling_nan(a)) { + float_raise(float_flag_invalid, s); + } + return float32_default_nan; + } else if (float32_is_zero_or_denormal(a)) { + if (!float32_is_zero(a)) { + float_raise(float_flag_input_denormal, s); + } + float_raise(float_flag_divbyzero, s); + return float32_set_sign(float32_infinity, float32_is_neg(a)); + } else if (float32_is_neg(a)) { + float_raise(float_flag_invalid, s); + return float32_default_nan; + } else if (float32_is_infinity(a)) { + return float32_zero; + } + + /* Normalize to a double-precision value between 0.25 and 1.0, + * preserving the parity of the exponent. */ + if ((val & 0x800000) == 0) { + f64 = make_float64(((uint64_t)(val & 0x80000000) << 32) + | (0x3feULL << 52) + | ((uint64_t)(val & 0x7fffff) << 29)); + } else { + f64 = make_float64(((uint64_t)(val & 0x80000000) << 32) + | (0x3fdULL << 52) + | ((uint64_t)(val & 0x7fffff) << 29)); + } + + result_exp = (380 - ((val & 0x7f800000) >> 23)) / 2; + + f64 = recip_sqrt_estimate(f64, env); + + val64 = float64_val(f64); + + val = ((result_exp & 0xff) << 23) + | ((val64 >> 29) & 0x7fffff); + return make_float32(val); } uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env) { - float_status *s = &env->vfp.fp_status; - float32 tmp; - tmp = int32_to_float32(a, s); - tmp = float32_scalbn(tmp, -32, s); - tmp = helper_recpe_f32(tmp, env); - tmp = float32_scalbn(tmp, 31, s); - return float32_to_int32(tmp, s); + float64 f64; + + if ((a & 0x80000000) == 0) { + return 0xffffffff; + } + + f64 = make_float64((0x3feULL << 52) + | ((int64_t)(a & 0x7fffffff) << 21)); + + f64 = recip_estimate (f64, env); + + return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff); } uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env) { - float_status *s = &env->vfp.fp_status; - float32 tmp; - tmp = int32_to_float32(a, s); - tmp = float32_scalbn(tmp, -32, s); - tmp = helper_rsqrte_f32(tmp, env); - tmp = float32_scalbn(tmp, 31, s); - return float32_to_int32(tmp, s); + float64 f64; + + if ((a & 0xc0000000) == 0) { + return 0xffffffff; + } + + if (a & 0x80000000) { + f64 = make_float64((0x3feULL << 52) + | ((uint64_t)(a & 0x7fffffff) << 21)); + } else { /* bits 31-30 == '01' */ + f64 = make_float64((0x3fdULL << 52) + | ((uint64_t)(a & 0x3fffffff) << 22)); + } + + f64 = recip_sqrt_estimate(f64, env); + + return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff); +} + +/* VFPv4 fused multiply-accumulate */ +float32 VFP_HELPER(muladd, s)(float32 a, float32 b, float32 c, void *fpstp) +{ + float_status *fpst = fpstp; + return float32_muladd(a, b, c, 0, fpst); +} + +float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp) +{ + float_status *fpst = fpstp; + return float64_muladd(a, b, c, 0, fpst); } void HELPER(set_teecr)(CPUState *env, uint32_t val) diff --git a/target-arm/helper_gpi_dummy.c b/target-arm/helper_gpi_dummy.c deleted file mode 100644 index 26991d8..0000000 --- a/target-arm/helper_gpi_dummy.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "debug_ch.h" -MULTI_DEBUG_CHANNEL(qemu, arm_dummy); - -int call_gpi(int pid, int call_num, char *in_args, int args_len, char *r_buffer, int r_length); - -int call_gpi(int pid, int call_num, char *in_args, int args_len, char *r_buffer, int r_length){ - ERR("virtio -> call_gpi(arm_dummy) called!!!\n"); - return 0; -} diff --git a/target-arm/helpers.h b/target-arm/helpers.h deleted file mode 100644 index 8a2564e..0000000 --- a/target-arm/helpers.h +++ /dev/null @@ -1,458 +0,0 @@ -#include "def-helper.h" - -DEF_HELPER_1(clz, i32, i32) -DEF_HELPER_1(sxtb16, i32, i32) -DEF_HELPER_1(uxtb16, i32, i32) - -DEF_HELPER_2(add_setq, i32, i32, i32) -DEF_HELPER_2(add_saturate, i32, i32, i32) -DEF_HELPER_2(sub_saturate, i32, i32, i32) -DEF_HELPER_2(add_usaturate, i32, i32, i32) -DEF_HELPER_2(sub_usaturate, i32, i32, i32) -DEF_HELPER_1(double_saturate, i32, s32) -DEF_HELPER_2(sdiv, s32, s32, s32) -DEF_HELPER_2(udiv, i32, i32, i32) -DEF_HELPER_1(rbit, i32, i32) -DEF_HELPER_1(abs, i32, i32) - -#define PAS_OP(pfx) \ - DEF_HELPER_3(pfx ## add8, i32, i32, i32, ptr) \ - DEF_HELPER_3(pfx ## sub8, i32, i32, i32, ptr) \ - DEF_HELPER_3(pfx ## sub16, i32, i32, i32, ptr) \ - DEF_HELPER_3(pfx ## add16, i32, i32, i32, ptr) \ - DEF_HELPER_3(pfx ## addsubx, i32, i32, i32, ptr) \ - DEF_HELPER_3(pfx ## subaddx, i32, i32, i32, ptr) - -PAS_OP(s) -PAS_OP(u) -#undef PAS_OP - -#define PAS_OP(pfx) \ - DEF_HELPER_2(pfx ## add8, i32, i32, i32) \ - DEF_HELPER_2(pfx ## sub8, i32, i32, i32) \ - DEF_HELPER_2(pfx ## sub16, i32, i32, i32) \ - DEF_HELPER_2(pfx ## add16, i32, i32, i32) \ - DEF_HELPER_2(pfx ## addsubx, i32, i32, i32) \ - DEF_HELPER_2(pfx ## subaddx, i32, i32, i32) -PAS_OP(q) -PAS_OP(sh) -PAS_OP(uq) -PAS_OP(uh) -#undef PAS_OP - -DEF_HELPER_2(ssat, i32, i32, i32) -DEF_HELPER_2(usat, i32, i32, i32) -DEF_HELPER_2(ssat16, i32, i32, i32) -DEF_HELPER_2(usat16, i32, i32, i32) - -DEF_HELPER_2(usad8, i32, i32, i32) - -DEF_HELPER_1(logicq_cc, i32, i64) - -DEF_HELPER_3(sel_flags, i32, i32, i32, i32) -DEF_HELPER_1(exception, void, i32) -DEF_HELPER_0(wfi, void) - -DEF_HELPER_2(cpsr_write, void, i32, i32) -DEF_HELPER_0(cpsr_read, i32) - -DEF_HELPER_3(v7m_msr, void, env, i32, i32) -DEF_HELPER_2(v7m_mrs, i32, env, i32) - -DEF_HELPER_3(set_cp15, void, env, i32, i32) -DEF_HELPER_2(get_cp15, i32, env, i32) - -DEF_HELPER_3(set_cp, void, env, i32, i32) -DEF_HELPER_2(get_cp, i32, env, i32) - -DEF_HELPER_2(get_r13_banked, i32, env, i32) -DEF_HELPER_3(set_r13_banked, void, env, i32, i32) - -DEF_HELPER_1(get_user_reg, i32, i32) -DEF_HELPER_2(set_user_reg, void, i32, i32) - -DEF_HELPER_1(vfp_get_fpscr, i32, env) -DEF_HELPER_2(vfp_set_fpscr, void, env, i32) - -DEF_HELPER_3(vfp_adds, f32, f32, f32, env) -DEF_HELPER_3(vfp_addd, f64, f64, f64, env) -DEF_HELPER_3(vfp_subs, f32, f32, f32, env) -DEF_HELPER_3(vfp_subd, f64, f64, f64, env) -DEF_HELPER_3(vfp_muls, f32, f32, f32, env) -DEF_HELPER_3(vfp_muld, f64, f64, f64, env) -DEF_HELPER_3(vfp_divs, f32, f32, f32, env) -DEF_HELPER_3(vfp_divd, f64, f64, f64, env) -DEF_HELPER_1(vfp_negs, f32, f32) -DEF_HELPER_1(vfp_negd, f64, f64) -DEF_HELPER_1(vfp_abss, f32, f32) -DEF_HELPER_1(vfp_absd, f64, f64) -DEF_HELPER_2(vfp_sqrts, f32, f32, env) -DEF_HELPER_2(vfp_sqrtd, f64, f64, env) -DEF_HELPER_3(vfp_cmps, void, f32, f32, env) -DEF_HELPER_3(vfp_cmpd, void, f64, f64, env) -DEF_HELPER_3(vfp_cmpes, void, f32, f32, env) -DEF_HELPER_3(vfp_cmped, void, f64, f64, env) - -DEF_HELPER_2(vfp_fcvtds, f64, f32, env) -DEF_HELPER_2(vfp_fcvtsd, f32, f64, env) - -DEF_HELPER_2(vfp_uitos, f32, f32, env) -DEF_HELPER_2(vfp_uitod, f64, f32, env) -DEF_HELPER_2(vfp_sitos, f32, f32, env) -DEF_HELPER_2(vfp_sitod, f64, f32, env) - -DEF_HELPER_2(vfp_touis, f32, f32, env) -DEF_HELPER_2(vfp_touid, f32, f64, env) -DEF_HELPER_2(vfp_touizs, f32, f32, env) -DEF_HELPER_2(vfp_touizd, f32, f64, env) -DEF_HELPER_2(vfp_tosis, f32, f32, env) -DEF_HELPER_2(vfp_tosid, f32, f64, env) -DEF_HELPER_2(vfp_tosizs, f32, f32, env) -DEF_HELPER_2(vfp_tosizd, f32, f64, env) - -DEF_HELPER_3(vfp_toshs, f32, f32, i32, env) -DEF_HELPER_3(vfp_tosls, f32, f32, i32, env) -DEF_HELPER_3(vfp_touhs, f32, f32, i32, env) -DEF_HELPER_3(vfp_touls, f32, f32, i32, env) -DEF_HELPER_3(vfp_toshd, f64, f64, i32, env) -DEF_HELPER_3(vfp_tosld, f64, f64, i32, env) -DEF_HELPER_3(vfp_touhd, f64, f64, i32, env) -DEF_HELPER_3(vfp_tould, f64, f64, i32, env) -DEF_HELPER_3(vfp_shtos, f32, f32, i32, env) -DEF_HELPER_3(vfp_sltos, f32, f32, i32, env) -DEF_HELPER_3(vfp_uhtos, f32, f32, i32, env) -DEF_HELPER_3(vfp_ultos, f32, f32, i32, env) -DEF_HELPER_3(vfp_shtod, f64, f64, i32, env) -DEF_HELPER_3(vfp_sltod, f64, f64, i32, env) -DEF_HELPER_3(vfp_uhtod, f64, f64, i32, env) -DEF_HELPER_3(vfp_ultod, f64, f64, i32, env) - -DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env) -DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env) - -DEF_HELPER_3(recps_f32, f32, f32, f32, env) -DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env) -DEF_HELPER_2(recpe_f32, f32, f32, env) -DEF_HELPER_2(rsqrte_f32, f32, f32, env) -DEF_HELPER_2(recpe_u32, i32, i32, env) -DEF_HELPER_2(rsqrte_u32, i32, i32, env) -DEF_HELPER_4(neon_tbl, i32, i32, i32, i32, i32) - -DEF_HELPER_2(add_cc, i32, i32, i32) -DEF_HELPER_2(adc_cc, i32, i32, i32) -DEF_HELPER_2(sub_cc, i32, i32, i32) -DEF_HELPER_2(sbc_cc, i32, i32, i32) - -DEF_HELPER_2(shl, i32, i32, i32) -DEF_HELPER_2(shr, i32, i32, i32) -DEF_HELPER_2(sar, i32, i32, i32) -DEF_HELPER_2(shl_cc, i32, i32, i32) -DEF_HELPER_2(shr_cc, i32, i32, i32) -DEF_HELPER_2(sar_cc, i32, i32, i32) -DEF_HELPER_2(ror_cc, i32, i32, i32) - -/* neon_helper.c */ -DEF_HELPER_3(neon_qadd_u8, i32, env, i32, i32) -DEF_HELPER_3(neon_qadd_s8, i32, env, i32, i32) -DEF_HELPER_3(neon_qadd_u16, i32, env, i32, i32) -DEF_HELPER_3(neon_qadd_s16, i32, env, i32, i32) -DEF_HELPER_3(neon_qadd_u32, i32, env, i32, i32) -DEF_HELPER_3(neon_qadd_s32, i32, env, i32, i32) -DEF_HELPER_3(neon_qsub_u8, i32, env, i32, i32) -DEF_HELPER_3(neon_qsub_s8, i32, env, i32, i32) -DEF_HELPER_3(neon_qsub_u16, i32, env, i32, i32) -DEF_HELPER_3(neon_qsub_s16, i32, env, i32, i32) -DEF_HELPER_3(neon_qsub_u32, i32, env, i32, i32) -DEF_HELPER_3(neon_qsub_s32, i32, env, i32, i32) -DEF_HELPER_3(neon_qadd_u64, i64, env, i64, i64) -DEF_HELPER_3(neon_qadd_s64, i64, env, i64, i64) -DEF_HELPER_3(neon_qsub_u64, i64, env, i64, i64) -DEF_HELPER_3(neon_qsub_s64, i64, env, i64, i64) - -DEF_HELPER_2(neon_hadd_s8, i32, i32, i32) -DEF_HELPER_2(neon_hadd_u8, i32, i32, i32) -DEF_HELPER_2(neon_hadd_s16, i32, i32, i32) -DEF_HELPER_2(neon_hadd_u16, i32, i32, i32) -DEF_HELPER_2(neon_hadd_s32, s32, s32, s32) -DEF_HELPER_2(neon_hadd_u32, i32, i32, i32) -DEF_HELPER_2(neon_rhadd_s8, i32, i32, i32) -DEF_HELPER_2(neon_rhadd_u8, i32, i32, i32) -DEF_HELPER_2(neon_rhadd_s16, i32, i32, i32) -DEF_HELPER_2(neon_rhadd_u16, i32, i32, i32) -DEF_HELPER_2(neon_rhadd_s32, s32, s32, s32) -DEF_HELPER_2(neon_rhadd_u32, i32, i32, i32) -DEF_HELPER_2(neon_hsub_s8, i32, i32, i32) -DEF_HELPER_2(neon_hsub_u8, i32, i32, i32) -DEF_HELPER_2(neon_hsub_s16, i32, i32, i32) -DEF_HELPER_2(neon_hsub_u16, i32, i32, i32) -DEF_HELPER_2(neon_hsub_s32, s32, s32, s32) -DEF_HELPER_2(neon_hsub_u32, i32, i32, i32) - -DEF_HELPER_2(neon_cgt_u8, i32, i32, i32) -DEF_HELPER_2(neon_cgt_s8, i32, i32, i32) -DEF_HELPER_2(neon_cgt_u16, i32, i32, i32) -DEF_HELPER_2(neon_cgt_s16, i32, i32, i32) -DEF_HELPER_2(neon_cgt_u32, i32, i32, i32) -DEF_HELPER_2(neon_cgt_s32, i32, i32, i32) -DEF_HELPER_2(neon_cge_u8, i32, i32, i32) -DEF_HELPER_2(neon_cge_s8, i32, i32, i32) -DEF_HELPER_2(neon_cge_u16, i32, i32, i32) -DEF_HELPER_2(neon_cge_s16, i32, i32, i32) -DEF_HELPER_2(neon_cge_u32, i32, i32, i32) -DEF_HELPER_2(neon_cge_s32, i32, i32, i32) - -DEF_HELPER_2(neon_min_u8, i32, i32, i32) -DEF_HELPER_2(neon_min_s8, i32, i32, i32) -DEF_HELPER_2(neon_min_u16, i32, i32, i32) -DEF_HELPER_2(neon_min_s16, i32, i32, i32) -DEF_HELPER_2(neon_min_u32, i32, i32, i32) -DEF_HELPER_2(neon_min_s32, i32, i32, i32) -DEF_HELPER_2(neon_max_u8, i32, i32, i32) -DEF_HELPER_2(neon_max_s8, i32, i32, i32) -DEF_HELPER_2(neon_max_u16, i32, i32, i32) -DEF_HELPER_2(neon_max_s16, i32, i32, i32) -DEF_HELPER_2(neon_max_u32, i32, i32, i32) -DEF_HELPER_2(neon_max_s32, i32, i32, i32) -DEF_HELPER_2(neon_pmin_u8, i32, i32, i32) -DEF_HELPER_2(neon_pmin_s8, i32, i32, i32) -DEF_HELPER_2(neon_pmin_u16, i32, i32, i32) -DEF_HELPER_2(neon_pmin_s16, i32, i32, i32) -DEF_HELPER_2(neon_pmax_u8, i32, i32, i32) -DEF_HELPER_2(neon_pmax_s8, i32, i32, i32) -DEF_HELPER_2(neon_pmax_u16, i32, i32, i32) -DEF_HELPER_2(neon_pmax_s16, i32, i32, i32) - -DEF_HELPER_2(neon_abd_u8, i32, i32, i32) -DEF_HELPER_2(neon_abd_s8, i32, i32, i32) -DEF_HELPER_2(neon_abd_u16, i32, i32, i32) -DEF_HELPER_2(neon_abd_s16, i32, i32, i32) -DEF_HELPER_2(neon_abd_u32, i32, i32, i32) -DEF_HELPER_2(neon_abd_s32, i32, i32, i32) - -DEF_HELPER_2(neon_shl_u8, i32, i32, i32) -DEF_HELPER_2(neon_shl_s8, i32, i32, i32) -DEF_HELPER_2(neon_shl_u16, i32, i32, i32) -DEF_HELPER_2(neon_shl_s16, i32, i32, i32) -DEF_HELPER_2(neon_shl_u32, i32, i32, i32) -DEF_HELPER_2(neon_shl_s32, i32, i32, i32) -DEF_HELPER_2(neon_shl_u64, i64, i64, i64) -DEF_HELPER_2(neon_shl_s64, i64, i64, i64) -DEF_HELPER_2(neon_rshl_u8, i32, i32, i32) -DEF_HELPER_2(neon_rshl_s8, i32, i32, i32) -DEF_HELPER_2(neon_rshl_u16, i32, i32, i32) -DEF_HELPER_2(neon_rshl_s16, i32, i32, i32) -DEF_HELPER_2(neon_rshl_u32, i32, i32, i32) -DEF_HELPER_2(neon_rshl_s32, i32, i32, i32) -DEF_HELPER_2(neon_rshl_u64, i64, i64, i64) -DEF_HELPER_2(neon_rshl_s64, i64, i64, i64) -DEF_HELPER_3(neon_qshl_u8, i32, env, i32, i32) -DEF_HELPER_3(neon_qshl_s8, i32, env, i32, i32) -DEF_HELPER_3(neon_qshl_u16, i32, env, i32, i32) -DEF_HELPER_3(neon_qshl_s16, i32, env, i32, i32) -DEF_HELPER_3(neon_qshl_u32, i32, env, i32, i32) -DEF_HELPER_3(neon_qshl_s32, i32, env, i32, i32) -DEF_HELPER_3(neon_qshl_u64, i64, env, i64, i64) -DEF_HELPER_3(neon_qshl_s64, i64, env, i64, i64) -DEF_HELPER_3(neon_qshlu_s8, i32, env, i32, i32); -DEF_HELPER_3(neon_qshlu_s16, i32, env, i32, i32); -DEF_HELPER_3(neon_qshlu_s32, i32, env, i32, i32); -DEF_HELPER_3(neon_qshlu_s64, i64, env, i64, i64); -DEF_HELPER_3(neon_qrshl_u8, i32, env, i32, i32) -DEF_HELPER_3(neon_qrshl_s8, i32, env, i32, i32) -DEF_HELPER_3(neon_qrshl_u16, i32, env, i32, i32) -DEF_HELPER_3(neon_qrshl_s16, i32, env, i32, i32) -DEF_HELPER_3(neon_qrshl_u32, i32, env, i32, i32) -DEF_HELPER_3(neon_qrshl_s32, i32, env, i32, i32) -DEF_HELPER_3(neon_qrshl_u64, i64, env, i64, i64) -DEF_HELPER_3(neon_qrshl_s64, i64, env, i64, i64) - -DEF_HELPER_2(neon_add_u8, i32, i32, i32) -DEF_HELPER_2(neon_add_u16, i32, i32, i32) -DEF_HELPER_2(neon_padd_u8, i32, i32, i32) -DEF_HELPER_2(neon_padd_u16, i32, i32, i32) -DEF_HELPER_2(neon_sub_u8, i32, i32, i32) -DEF_HELPER_2(neon_sub_u16, i32, i32, i32) -DEF_HELPER_2(neon_mul_u8, i32, i32, i32) -DEF_HELPER_2(neon_mul_u16, i32, i32, i32) -DEF_HELPER_2(neon_mul_p8, i32, i32, i32) - -DEF_HELPER_2(neon_tst_u8, i32, i32, i32) -DEF_HELPER_2(neon_tst_u16, i32, i32, i32) -DEF_HELPER_2(neon_tst_u32, i32, i32, i32) -DEF_HELPER_2(neon_ceq_u8, i32, i32, i32) -DEF_HELPER_2(neon_ceq_u16, i32, i32, i32) -DEF_HELPER_2(neon_ceq_u32, i32, i32, i32) - -DEF_HELPER_1(neon_abs_s8, i32, i32) -DEF_HELPER_1(neon_abs_s16, i32, i32) -DEF_HELPER_1(neon_clz_u8, i32, i32) -DEF_HELPER_1(neon_clz_u16, i32, i32) -DEF_HELPER_1(neon_cls_s8, i32, i32) -DEF_HELPER_1(neon_cls_s16, i32, i32) -DEF_HELPER_1(neon_cls_s32, i32, i32) -DEF_HELPER_1(neon_cnt_u8, i32, i32) - -DEF_HELPER_3(neon_qdmulh_s16, i32, env, i32, i32) -DEF_HELPER_3(neon_qrdmulh_s16, i32, env, i32, i32) -DEF_HELPER_3(neon_qdmulh_s32, i32, env, i32, i32) -DEF_HELPER_3(neon_qrdmulh_s32, i32, env, i32, i32) - -DEF_HELPER_1(neon_narrow_u8, i32, i64) -DEF_HELPER_1(neon_narrow_u16, i32, i64) -DEF_HELPER_2(neon_narrow_sat_u8, i32, env, i64) -DEF_HELPER_2(neon_narrow_sat_s8, i32, env, i64) -DEF_HELPER_2(neon_narrow_sat_u16, i32, env, i64) -DEF_HELPER_2(neon_narrow_sat_s16, i32, env, i64) -DEF_HELPER_2(neon_narrow_sat_u32, i32, env, i64) -DEF_HELPER_2(neon_narrow_sat_s32, i32, env, i64) -DEF_HELPER_1(neon_narrow_high_u8, i32, i64) -DEF_HELPER_1(neon_narrow_high_u16, i32, i64) -DEF_HELPER_1(neon_narrow_round_high_u8, i32, i64) -DEF_HELPER_1(neon_narrow_round_high_u16, i32, i64) -DEF_HELPER_1(neon_widen_u8, i64, i32) -DEF_HELPER_1(neon_widen_s8, i64, i32) -DEF_HELPER_1(neon_widen_u16, i64, i32) -DEF_HELPER_1(neon_widen_s16, i64, i32) - -DEF_HELPER_2(neon_addl_u16, i64, i64, i64) -DEF_HELPER_2(neon_addl_u32, i64, i64, i64) -DEF_HELPER_2(neon_paddl_u16, i64, i64, i64) -DEF_HELPER_2(neon_paddl_u32, i64, i64, i64) -DEF_HELPER_2(neon_subl_u16, i64, i64, i64) -DEF_HELPER_2(neon_subl_u32, i64, i64, i64) -DEF_HELPER_3(neon_addl_saturate_s32, i64, env, i64, i64) -DEF_HELPER_3(neon_addl_saturate_s64, i64, env, i64, i64) -DEF_HELPER_2(neon_abdl_u16, i64, i32, i32) -DEF_HELPER_2(neon_abdl_s16, i64, i32, i32) -DEF_HELPER_2(neon_abdl_u32, i64, i32, i32) -DEF_HELPER_2(neon_abdl_s32, i64, i32, i32) -DEF_HELPER_2(neon_abdl_u64, i64, i32, i32) -DEF_HELPER_2(neon_abdl_s64, i64, i32, i32) -DEF_HELPER_2(neon_mull_u8, i64, i32, i32) -DEF_HELPER_2(neon_mull_s8, i64, i32, i32) -DEF_HELPER_2(neon_mull_u16, i64, i32, i32) -DEF_HELPER_2(neon_mull_s16, i64, i32, i32) - -DEF_HELPER_1(neon_negl_u16, i64, i64) -DEF_HELPER_1(neon_negl_u32, i64, i64) -DEF_HELPER_1(neon_negl_u64, i64, i64) - -DEF_HELPER_2(neon_qabs_s8, i32, env, i32) -DEF_HELPER_2(neon_qabs_s16, i32, env, i32) -DEF_HELPER_2(neon_qabs_s32, i32, env, i32) -DEF_HELPER_2(neon_qneg_s8, i32, env, i32) -DEF_HELPER_2(neon_qneg_s16, i32, env, i32) -DEF_HELPER_2(neon_qneg_s32, i32, env, i32) - -DEF_HELPER_2(neon_min_f32, i32, i32, i32) -DEF_HELPER_2(neon_max_f32, i32, i32, i32) -DEF_HELPER_2(neon_abd_f32, i32, i32, i32) -DEF_HELPER_2(neon_add_f32, i32, i32, i32) -DEF_HELPER_2(neon_sub_f32, i32, i32, i32) -DEF_HELPER_2(neon_mul_f32, i32, i32, i32) -DEF_HELPER_2(neon_ceq_f32, i32, i32, i32) -DEF_HELPER_2(neon_cge_f32, i32, i32, i32) -DEF_HELPER_2(neon_cgt_f32, i32, i32, i32) -DEF_HELPER_2(neon_acge_f32, i32, i32, i32) -DEF_HELPER_2(neon_acgt_f32, i32, i32, i32) - -/* iwmmxt_helper.c */ -DEF_HELPER_2(iwmmxt_maddsq, i64, i64, i64) -DEF_HELPER_2(iwmmxt_madduq, i64, i64, i64) -DEF_HELPER_2(iwmmxt_sadb, i64, i64, i64) -DEF_HELPER_2(iwmmxt_sadw, i64, i64, i64) -DEF_HELPER_2(iwmmxt_mulslw, i64, i64, i64) -DEF_HELPER_2(iwmmxt_mulshw, i64, i64, i64) -DEF_HELPER_2(iwmmxt_mululw, i64, i64, i64) -DEF_HELPER_2(iwmmxt_muluhw, i64, i64, i64) -DEF_HELPER_2(iwmmxt_macsw, i64, i64, i64) -DEF_HELPER_2(iwmmxt_macuw, i64, i64, i64) -DEF_HELPER_1(iwmmxt_setpsr_nz, i32, i64) - -#define DEF_IWMMXT_HELPER_SIZE_ENV(name) \ -DEF_HELPER_3(iwmmxt_##name##b, i64, env, i64, i64) \ -DEF_HELPER_3(iwmmxt_##name##w, i64, env, i64, i64) \ -DEF_HELPER_3(iwmmxt_##name##l, i64, env, i64, i64) \ - -DEF_IWMMXT_HELPER_SIZE_ENV(unpackl) -DEF_IWMMXT_HELPER_SIZE_ENV(unpackh) - -DEF_HELPER_2(iwmmxt_unpacklub, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpackluw, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpacklul, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpackhub, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpackhuw, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpackhul, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpacklsb, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpacklsw, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpacklsl, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpackhsb, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpackhsw, i64, env, i64) -DEF_HELPER_2(iwmmxt_unpackhsl, i64, env, i64) - -DEF_IWMMXT_HELPER_SIZE_ENV(cmpeq) -DEF_IWMMXT_HELPER_SIZE_ENV(cmpgtu) -DEF_IWMMXT_HELPER_SIZE_ENV(cmpgts) - -DEF_IWMMXT_HELPER_SIZE_ENV(mins) -DEF_IWMMXT_HELPER_SIZE_ENV(minu) -DEF_IWMMXT_HELPER_SIZE_ENV(maxs) -DEF_IWMMXT_HELPER_SIZE_ENV(maxu) - -DEF_IWMMXT_HELPER_SIZE_ENV(subn) -DEF_IWMMXT_HELPER_SIZE_ENV(addn) -DEF_IWMMXT_HELPER_SIZE_ENV(subu) -DEF_IWMMXT_HELPER_SIZE_ENV(addu) -DEF_IWMMXT_HELPER_SIZE_ENV(subs) -DEF_IWMMXT_HELPER_SIZE_ENV(adds) - -DEF_HELPER_3(iwmmxt_avgb0, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_avgb1, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_avgw0, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_avgw1, i64, env, i64, i64) - -DEF_HELPER_2(iwmmxt_msadb, i64, i64, i64) - -DEF_HELPER_3(iwmmxt_align, i64, i64, i64, i32) -DEF_HELPER_4(iwmmxt_insr, i64, i64, i32, i32, i32) - -DEF_HELPER_1(iwmmxt_bcstb, i64, i32) -DEF_HELPER_1(iwmmxt_bcstw, i64, i32) -DEF_HELPER_1(iwmmxt_bcstl, i64, i32) - -DEF_HELPER_1(iwmmxt_addcb, i64, i64) -DEF_HELPER_1(iwmmxt_addcw, i64, i64) -DEF_HELPER_1(iwmmxt_addcl, i64, i64) - -DEF_HELPER_1(iwmmxt_msbb, i32, i64) -DEF_HELPER_1(iwmmxt_msbw, i32, i64) -DEF_HELPER_1(iwmmxt_msbl, i32, i64) - -DEF_HELPER_3(iwmmxt_srlw, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_srll, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_srlq, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_sllw, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_slll, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_sllq, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_sraw, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_sral, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_sraq, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_rorw, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_rorl, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_rorq, i64, env, i64, i32) -DEF_HELPER_3(iwmmxt_shufh, i64, env, i64, i32) - -DEF_HELPER_3(iwmmxt_packuw, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_packul, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_packuq, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_packsw, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_packsl, i64, env, i64, i64) -DEF_HELPER_3(iwmmxt_packsq, i64, env, i64, i64) - -DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32) -DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32) -DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32) - -DEF_HELPER_2(set_teecr, void, env, i32) - -#include "def-helper.h" diff --git a/target-arm/iwmmxt_helper.c b/target-arm/iwmmxt_helper.c index 3332f70..843994d 100644 --- a/target-arm/iwmmxt_helper.c +++ b/target-arm/iwmmxt_helper.c @@ -24,7 +24,7 @@ #include "cpu.h" #include "exec-all.h" -#include "helpers.h" +#include "helper.h" /* iwMMXt macros extracted from GNU gdb. */ diff --git a/target-arm/machine.c b/target-arm/machine.c index 3925d3a..aaee9b9 100644 --- a/target-arm/machine.c +++ b/target-arm/machine.c @@ -41,8 +41,15 @@ void cpu_save(QEMUFile *f, void *opaque) } qemu_put_be32(f, env->cp15.c6_insn); qemu_put_be32(f, env->cp15.c6_data); + qemu_put_be32(f, env->cp15.c7_par); qemu_put_be32(f, env->cp15.c9_insn); qemu_put_be32(f, env->cp15.c9_data); + qemu_put_be32(f, env->cp15.c9_pmcr); + qemu_put_be32(f, env->cp15.c9_pmcnten); + qemu_put_be32(f, env->cp15.c9_pmovsr); + qemu_put_be32(f, env->cp15.c9_pmxevtyper); + qemu_put_be32(f, env->cp15.c9_pmuserenr); + qemu_put_be32(f, env->cp15.c9_pminten); qemu_put_be32(f, env->cp15.c13_fcse); qemu_put_be32(f, env->cp15.c13_context); qemu_put_be32(f, env->cp15.c13_tls1); @@ -148,8 +155,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) } env->cp15.c6_insn = qemu_get_be32(f); env->cp15.c6_data = qemu_get_be32(f); + env->cp15.c7_par = qemu_get_be32(f); env->cp15.c9_insn = qemu_get_be32(f); env->cp15.c9_data = qemu_get_be32(f); + env->cp15.c9_pmcr = qemu_get_be32(f); + env->cp15.c9_pmcnten = qemu_get_be32(f); + env->cp15.c9_pmovsr = qemu_get_be32(f); + env->cp15.c9_pmxevtyper = qemu_get_be32(f); + env->cp15.c9_pmuserenr = qemu_get_be32(f); + env->cp15.c9_pminten = qemu_get_be32(f); env->cp15.c13_fcse = qemu_get_be32(f); env->cp15.c13_context = qemu_get_be32(f); env->cp15.c13_tls1 = qemu_get_be32(f); @@ -175,7 +189,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) env->vfp.vec_stride = qemu_get_be32(f); if (arm_feature(env, ARM_FEATURE_VFP3)) { - for (i = 0; i < 16; i++) { + for (i = 16; i < 32; i++) { CPU_DoubleU u; u.l.upper = qemu_get_be32(f); u.l.lower = qemu_get_be32(f); diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c index 268af33..b51e35a 100644 --- a/target-arm/neon_helper.c +++ b/target-arm/neon_helper.c @@ -4,46 +4,20 @@ * Copyright (c) 2007, 2008 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GNU GPL v2. + * This code is licensed under the GNU GPL v2. */ #include #include #include "cpu.h" #include "exec-all.h" -#include "helpers.h" +#include "helper.h" #define SIGNBIT (uint32_t)0x80000000 #define SIGNBIT64 ((uint64_t)1 << 63) #define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] = CPSR_Q -static float_status neon_float_status; -#define NFS &neon_float_status - -/* Helper routines to perform bitwise copies between float and int. */ -static inline float32 vfp_itos(uint32_t i) -{ - union { - uint32_t i; - float32 s; - } v; - - v.i = i; - return v.s; -} - -static inline uint32_t vfp_stoi(float32 s) -{ - union { - uint32_t i; - float32 s; - } v; - - v.s = s; - return v.i; -} - #define NEON_TYPE1(name, type) \ typedef struct \ { \ @@ -543,14 +517,9 @@ uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop) #define NEON_FN(dest, src1, src2) do { \ int8_t tmp; \ tmp = (int8_t)src2; \ - if (tmp >= (ssize_t)sizeof(src1) * 8) { \ + if ((tmp >= (ssize_t)sizeof(src1) * 8) \ + || (tmp <= -(ssize_t)sizeof(src1) * 8)) { \ dest = 0; \ - } else if (tmp < -(ssize_t)sizeof(src1) * 8) { \ - dest = src1 >> (sizeof(src1) * 8 - 1); \ - } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \ - dest = src1 >> (tmp - 1); \ - dest++; \ - dest >>= 1; \ } else if (tmp < 0) { \ dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \ } else { \ @@ -558,23 +527,45 @@ uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop) }} while (0) NEON_VOP(rshl_s8, neon_s8, 4) NEON_VOP(rshl_s16, neon_s16, 2) -NEON_VOP(rshl_s32, neon_s32, 1) #undef NEON_FN +/* The addition of the rounding constant may overflow, so we use an + * intermediate 64 bits accumulator. */ +uint32_t HELPER(neon_rshl_s32)(uint32_t valop, uint32_t shiftop) +{ + int32_t dest; + int32_t val = (int32_t)valop; + int8_t shift = (int8_t)shiftop; + if ((shift >= 32) || (shift <= -32)) { + dest = 0; + } else if (shift < 0) { + int64_t big_dest = ((int64_t)val + (1 << (-1 - shift))); + dest = big_dest >> -shift; + } else { + dest = val << shift; + } + return dest; +} + +/* Handling addition overflow with 64 bits inputs values is more + * tricky than with 32 bits values. */ uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop) { int8_t shift = (int8_t)shiftop; int64_t val = valop; - if (shift >= 64) { + if ((shift >= 64) || (shift <= -64)) { val = 0; - } else if (shift < -64) { - val >>= 63; - } else if (shift == -63) { - val >>= 63; - val++; - val >>= 1; } else if (shift < 0) { - val = (val + ((int64_t)1 << (-1 - shift))) >> -shift; + val >>= (-shift - 1); + if (val == INT64_MAX) { + /* In this case, it means that the rounding constant is 1, + * and the addition would overflow. Return the actual + * result directly. */ + val = 0x4000000000000000LL; + } else { + val++; + val >>= 1; + } } else { val <<= shift; } @@ -588,7 +579,7 @@ uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop) tmp < -(ssize_t)sizeof(src1) * 8) { \ dest = 0; \ } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \ - dest = src1 >> (tmp - 1); \ + dest = src1 >> (-tmp - 1); \ } else if (tmp < 0) { \ dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \ } else { \ @@ -596,20 +587,48 @@ uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop) }} while (0) NEON_VOP(rshl_u8, neon_u8, 4) NEON_VOP(rshl_u16, neon_u16, 2) -NEON_VOP(rshl_u32, neon_u32, 1) #undef NEON_FN +/* The addition of the rounding constant may overflow, so we use an + * intermediate 64 bits accumulator. */ +uint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shiftop) +{ + uint32_t dest; + int8_t shift = (int8_t)shiftop; + if (shift >= 32 || shift < -32) { + dest = 0; + } else if (shift == -32) { + dest = val >> 31; + } else if (shift < 0) { + uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift))); + dest = big_dest >> -shift; + } else { + dest = val << shift; + } + return dest; +} + +/* Handling addition overflow with 64 bits inputs values is more + * tricky than with 32 bits values. */ uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop) { int8_t shift = (uint8_t)shiftop; - if (shift >= 64 || shift < 64) { + if (shift >= 64 || shift < -64) { val = 0; } else if (shift == -64) { /* Rounding a 1-bit result just preserves that bit. */ val >>= 63; - } if (shift < 0) { - val = (val + ((uint64_t)1 << (-1 - shift))) >> -shift; - val >>= -shift; + } else if (shift < 0) { + val >>= (-shift - 1); + if (val == UINT64_MAX) { + /* In this case, it means that the rounding constant is 1, + * and the addition would overflow. Return the actual + * result directly. */ + val = 0x8000000000000000ULL; + } else { + val++; + val >>= 1; + } } else { val <<= shift; } @@ -773,7 +792,18 @@ uint64_t HELPER(neon_qshlu_s64)(CPUState *env, uint64_t valop, uint64_t shiftop) #define NEON_FN(dest, src1, src2) do { \ int8_t tmp; \ tmp = (int8_t)src2; \ - if (tmp < 0) { \ + if (tmp >= (ssize_t)sizeof(src1) * 8) { \ + if (src1) { \ + SET_QC(); \ + dest = ~0; \ + } else { \ + dest = 0; \ + } \ + } else if (tmp < -(ssize_t)sizeof(src1) * 8) { \ + dest = 0; \ + } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \ + dest = src1 >> (sizeof(src1) * 8 - 1); \ + } else if (tmp < 0) { \ dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \ } else { \ dest = src1 << tmp; \ @@ -784,14 +814,63 @@ uint64_t HELPER(neon_qshlu_s64)(CPUState *env, uint64_t valop, uint64_t shiftop) }} while (0) NEON_VOP_ENV(qrshl_u8, neon_u8, 4) NEON_VOP_ENV(qrshl_u16, neon_u16, 2) -NEON_VOP_ENV(qrshl_u32, neon_u32, 1) #undef NEON_FN +/* The addition of the rounding constant may overflow, so we use an + * intermediate 64 bits accumulator. */ +uint32_t HELPER(neon_qrshl_u32)(CPUState *env, uint32_t val, uint32_t shiftop) +{ + uint32_t dest; + int8_t shift = (int8_t)shiftop; + if (shift >= 32) { + if (val) { + SET_QC(); + dest = ~0; + } else { + dest = 0; + } + } else if (shift < -32) { + dest = 0; + } else if (shift == -32) { + dest = val >> 31; + } else if (shift < 0) { + uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift))); + dest = big_dest >> -shift; + } else { + dest = val << shift; + if ((dest >> shift) != val) { + SET_QC(); + dest = ~0; + } + } + return dest; +} + +/* Handling addition overflow with 64 bits inputs values is more + * tricky than with 32 bits values. */ uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop) { int8_t shift = (int8_t)shiftop; - if (shift < 0) { - val = (val + (1 << (-1 - shift))) >> -shift; + if (shift >= 64) { + if (val) { + SET_QC(); + val = ~0; + } + } else if (shift < -64) { + val = 0; + } else if (shift == -64) { + val >>= 63; + } else if (shift < 0) { + val >>= (-shift - 1); + if (val == UINT64_MAX) { + /* In this case, it means that the rounding constant is 1, + * and the addition would overflow. Return the actual + * result directly. */ + val = 0x8000000000000000ULL; + } else { + val++; + val >>= 1; + } } else { \ uint64_t tmp = val; val <<= shift; @@ -806,33 +885,94 @@ uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop) #define NEON_FN(dest, src1, src2) do { \ int8_t tmp; \ tmp = (int8_t)src2; \ - if (tmp < 0) { \ + if (tmp >= (ssize_t)sizeof(src1) * 8) { \ + if (src1) { \ + SET_QC(); \ + dest = (1 << (sizeof(src1) * 8 - 1)); \ + if (src1 > 0) { \ + dest--; \ + } \ + } else { \ + dest = 0; \ + } \ + } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \ + dest = 0; \ + } else if (tmp < 0) { \ dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \ } else { \ dest = src1 << tmp; \ if ((dest >> tmp) != src1) { \ SET_QC(); \ - dest = src1 >> 31; \ + dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \ + if (src1 > 0) { \ + dest--; \ + } \ } \ }} while (0) NEON_VOP_ENV(qrshl_s8, neon_s8, 4) NEON_VOP_ENV(qrshl_s16, neon_s16, 2) -NEON_VOP_ENV(qrshl_s32, neon_s32, 1) #undef NEON_FN +/* The addition of the rounding constant may overflow, so we use an + * intermediate 64 bits accumulator. */ +uint32_t HELPER(neon_qrshl_s32)(CPUState *env, uint32_t valop, uint32_t shiftop) +{ + int32_t dest; + int32_t val = (int32_t)valop; + int8_t shift = (int8_t)shiftop; + if (shift >= 32) { + if (val) { + SET_QC(); + dest = (val >> 31) ^ ~SIGNBIT; + } else { + dest = 0; + } + } else if (shift <= -32) { + dest = 0; + } else if (shift < 0) { + int64_t big_dest = ((int64_t)val + (1 << (-1 - shift))); + dest = big_dest >> -shift; + } else { + dest = val << shift; + if ((dest >> shift) != val) { + SET_QC(); + dest = (val >> 31) ^ ~SIGNBIT; + } + } + return dest; +} + +/* Handling addition overflow with 64 bits inputs values is more + * tricky than with 32 bits values. */ uint64_t HELPER(neon_qrshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop) { int8_t shift = (uint8_t)shiftop; int64_t val = valop; - if (shift < 0) { - val = (val + (1 << (-1 - shift))) >> -shift; + if (shift >= 64) { + if (val) { + SET_QC(); + val = (val >> 63) ^ ~SIGNBIT64; + } + } else if (shift <= -64) { + val = 0; + } else if (shift < 0) { + val >>= (-shift - 1); + if (val == INT64_MAX) { + /* In this case, it means that the rounding constant is 1, + * and the addition would overflow. Return the actual + * result directly. */ + val = 0x4000000000000000ULL; + } else { + val++; + val >>= 1; + } } else { - int64_t tmp = val;; + int64_t tmp = val; val <<= shift; if ((val >> shift) != tmp) { SET_QC(); - val = tmp >> 31; + val = (tmp >> 63) ^ ~SIGNBIT64; } } return val; @@ -895,6 +1035,36 @@ uint32_t HELPER(neon_mul_p8)(uint32_t op1, uint32_t op2) return result; } +uint64_t HELPER(neon_mull_p8)(uint32_t op1, uint32_t op2) +{ + uint64_t result = 0; + uint64_t mask; + uint64_t op2ex = op2; + op2ex = (op2ex & 0xff) | + ((op2ex & 0xff00) << 8) | + ((op2ex & 0xff0000) << 16) | + ((op2ex & 0xff000000) << 24); + while (op1) { + mask = 0; + if (op1 & 1) { + mask |= 0xffff; + } + if (op1 & (1 << 8)) { + mask |= (0xffffU << 16); + } + if (op1 & (1 << 16)) { + mask |= (0xffffULL << 32); + } + if (op1 & (1 << 24)) { + mask |= (0xffffULL << 48); + } + result ^= op2ex & mask; + op1 = (op1 >> 1) & 0x7f7f7f7f; + op2ex <<= 1; + } + return result; +} + #define NEON_FN(dest, src1, src2) dest = (src1 & src2) ? -1 : 0 NEON_VOP(tst_u8, neon_u8, 4) NEON_VOP(tst_u16, neon_u16, 2) @@ -1053,6 +1223,33 @@ uint32_t HELPER(neon_narrow_round_high_u16)(uint64_t x) return ((x >> 16) & 0xffff) | ((x >> 32) & 0xffff0000); } +uint32_t HELPER(neon_unarrow_sat8)(CPUState *env, uint64_t x) +{ + uint16_t s; + uint8_t d; + uint32_t res = 0; +#define SAT8(n) \ + s = x >> n; \ + if (s & 0x8000) { \ + SET_QC(); \ + } else { \ + if (s > 0xff) { \ + d = 0xff; \ + SET_QC(); \ + } else { \ + d = s; \ + } \ + res |= (uint32_t)d << (n / 2); \ + } + + SAT8(0); + SAT8(16); + SAT8(32); + SAT8(48); +#undef SAT8 + return res; +} + uint32_t HELPER(neon_narrow_sat_u8)(CPUState *env, uint64_t x) { uint16_t s; @@ -1099,6 +1296,29 @@ uint32_t HELPER(neon_narrow_sat_s8)(CPUState *env, uint64_t x) return res; } +uint32_t HELPER(neon_unarrow_sat16)(CPUState *env, uint64_t x) +{ + uint32_t high; + uint32_t low; + low = x; + if (low & 0x80000000) { + low = 0; + SET_QC(); + } else if (low > 0xffff) { + low = 0xffff; + SET_QC(); + } + high = x >> 32; + if (high & 0x80000000) { + high = 0; + SET_QC(); + } else if (high > 0xffff) { + high = 0xffff; + SET_QC(); + } + return low | (high << 16); +} + uint32_t HELPER(neon_narrow_sat_u16)(CPUState *env, uint64_t x) { uint32_t high; @@ -1133,6 +1353,19 @@ uint32_t HELPER(neon_narrow_sat_s16)(CPUState *env, uint64_t x) return (uint16_t)low | (high << 16); } +uint32_t HELPER(neon_unarrow_sat32)(CPUState *env, uint64_t x) +{ + if (x & 0x8000000000000000ull) { + SET_QC(); + return 0; + } + if (x > 0xffffffffu) { + SET_QC(); + return 0xffffffffu; + } + return x; +} + uint32_t HELPER(neon_narrow_sat_u32)(CPUState *env, uint64_t x) { if (x > 0xffffffffu) { @@ -1146,7 +1379,7 @@ uint32_t HELPER(neon_narrow_sat_s32)(CPUState *env, uint64_t x) { if ((int64_t)x != (int32_t)x) { SET_QC(); - return (x >> 63) ^ 0x7fffffff; + return ((int64_t)x >> 63) ^ 0x7fffffff; } return x; } @@ -1283,9 +1516,13 @@ uint64_t HELPER(neon_addl_saturate_s64)(CPUState *env, uint64_t a, uint64_t b) return result; } -#define DO_ABD(dest, x, y, type) do { \ - type tmp_x = x; \ - type tmp_y = y; \ +/* We have to do the arithmetic in a larger type than + * the input type, because for example with a signed 32 bit + * op the absolute difference can overflow a signed 32 bit value. + */ +#define DO_ABD(dest, x, y, intype, arithtype) do { \ + arithtype tmp_x = (intype)(x); \ + arithtype tmp_y = (intype)(y); \ dest = ((tmp_x > tmp_y) ? tmp_x - tmp_y : tmp_y - tmp_x); \ } while(0) @@ -1293,12 +1530,12 @@ uint64_t HELPER(neon_abdl_u16)(uint32_t a, uint32_t b) { uint64_t tmp; uint64_t result; - DO_ABD(result, a, b, uint8_t); - DO_ABD(tmp, a >> 8, b >> 8, uint8_t); + DO_ABD(result, a, b, uint8_t, uint32_t); + DO_ABD(tmp, a >> 8, b >> 8, uint8_t, uint32_t); result |= tmp << 16; - DO_ABD(tmp, a >> 16, b >> 16, uint8_t); + DO_ABD(tmp, a >> 16, b >> 16, uint8_t, uint32_t); result |= tmp << 32; - DO_ABD(tmp, a >> 24, b >> 24, uint8_t); + DO_ABD(tmp, a >> 24, b >> 24, uint8_t, uint32_t); result |= tmp << 48; return result; } @@ -1307,12 +1544,12 @@ uint64_t HELPER(neon_abdl_s16)(uint32_t a, uint32_t b) { uint64_t tmp; uint64_t result; - DO_ABD(result, a, b, int8_t); - DO_ABD(tmp, a >> 8, b >> 8, int8_t); + DO_ABD(result, a, b, int8_t, int32_t); + DO_ABD(tmp, a >> 8, b >> 8, int8_t, int32_t); result |= tmp << 16; - DO_ABD(tmp, a >> 16, b >> 16, int8_t); + DO_ABD(tmp, a >> 16, b >> 16, int8_t, int32_t); result |= tmp << 32; - DO_ABD(tmp, a >> 24, b >> 24, int8_t); + DO_ABD(tmp, a >> 24, b >> 24, int8_t, int32_t); result |= tmp << 48; return result; } @@ -1321,8 +1558,8 @@ uint64_t HELPER(neon_abdl_u32)(uint32_t a, uint32_t b) { uint64_t tmp; uint64_t result; - DO_ABD(result, a, b, uint16_t); - DO_ABD(tmp, a >> 16, b >> 16, uint16_t); + DO_ABD(result, a, b, uint16_t, uint32_t); + DO_ABD(tmp, a >> 16, b >> 16, uint16_t, uint32_t); return result | (tmp << 32); } @@ -1330,22 +1567,22 @@ uint64_t HELPER(neon_abdl_s32)(uint32_t a, uint32_t b) { uint64_t tmp; uint64_t result; - DO_ABD(result, a, b, int16_t); - DO_ABD(tmp, a >> 16, b >> 16, int16_t); + DO_ABD(result, a, b, int16_t, int32_t); + DO_ABD(tmp, a >> 16, b >> 16, int16_t, int32_t); return result | (tmp << 32); } uint64_t HELPER(neon_abdl_u64)(uint32_t a, uint32_t b) { uint64_t result; - DO_ABD(result, a, b, uint32_t); + DO_ABD(result, a, b, uint32_t, uint64_t); return result; } uint64_t HELPER(neon_abdl_s64)(uint32_t a, uint32_t b) { uint64_t result; - DO_ABD(result, a, b, int32_t); + DO_ABD(result, a, b, int32_t, int64_t); return result; } #undef DO_ABD @@ -1421,7 +1658,6 @@ uint64_t HELPER(neon_negl_u16)(uint64_t x) return result; } -#include uint64_t HELPER(neon_negl_u32)(uint64_t x) { uint32_t low = -x; @@ -1536,68 +1772,246 @@ uint32_t HELPER(neon_qneg_s32)(CPUState *env, uint32_t x) } /* NEON Float helpers. */ -uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b) -{ - float32 f0 = vfp_itos(a); - float32 f1 = vfp_itos(b); - return (float32_compare_quiet(f0, f1, NFS) == -1) ? a : b; -} - -uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b) -{ - float32 f0 = vfp_itos(a); - float32 f1 = vfp_itos(b); - return (float32_compare_quiet(f0, f1, NFS) == 1) ? a : b; -} - -uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b) +uint32_t HELPER(neon_min_f32)(uint32_t a, uint32_t b, void *fpstp) { - float32 f0 = vfp_itos(a); - float32 f1 = vfp_itos(b); - return vfp_stoi((float32_compare_quiet(f0, f1, NFS) == 1) - ? float32_sub(f0, f1, NFS) - : float32_sub(f1, f0, NFS)); + float_status *fpst = fpstp; + return float32_val(float32_min(make_float32(a), make_float32(b), fpst)); } -uint32_t HELPER(neon_add_f32)(uint32_t a, uint32_t b) +uint32_t HELPER(neon_max_f32)(uint32_t a, uint32_t b, void *fpstp) { - return vfp_stoi(float32_add(vfp_itos(a), vfp_itos(b), NFS)); + float_status *fpst = fpstp; + return float32_val(float32_max(make_float32(a), make_float32(b), fpst)); } -uint32_t HELPER(neon_sub_f32)(uint32_t a, uint32_t b) +uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b, void *fpstp) { - return vfp_stoi(float32_sub(vfp_itos(a), vfp_itos(b), NFS)); + float_status *fpst = fpstp; + float32 f0 = make_float32(a); + float32 f1 = make_float32(b); + return float32_val(float32_abs(float32_sub(f0, f1, fpst))); } -uint32_t HELPER(neon_mul_f32)(uint32_t a, uint32_t b) +/* Floating point comparisons produce an integer result. + * Note that EQ doesn't signal InvalidOp for QNaNs but GE and GT do. + * Softfloat routines return 0/1, which we convert to the 0/-1 Neon requires. + */ +uint32_t HELPER(neon_ceq_f32)(uint32_t a, uint32_t b, void *fpstp) { - return vfp_stoi(float32_mul(vfp_itos(a), vfp_itos(b), NFS)); -} - -/* Floating point comparisons produce an integer result. */ -#define NEON_VOP_FCMP(name, cmp) \ -uint32_t HELPER(neon_##name)(uint32_t a, uint32_t b) \ -{ \ - if (float32_compare_quiet(vfp_itos(a), vfp_itos(b), NFS) cmp 0) \ - return ~0; \ - else \ - return 0; \ + float_status *fpst = fpstp; + return -float32_eq_quiet(make_float32(a), make_float32(b), fpst); } -NEON_VOP_FCMP(ceq_f32, ==) -NEON_VOP_FCMP(cge_f32, >=) -NEON_VOP_FCMP(cgt_f32, >) - -uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b) -{ - float32 f0 = float32_abs(vfp_itos(a)); - float32 f1 = float32_abs(vfp_itos(b)); - return (float32_compare_quiet(f0, f1,NFS) >= 0) ? ~0 : 0; -} +uint32_t HELPER(neon_cge_f32)(uint32_t a, uint32_t b, void *fpstp) +{ + float_status *fpst = fpstp; + return -float32_le(make_float32(b), make_float32(a), fpst); +} + +uint32_t HELPER(neon_cgt_f32)(uint32_t a, uint32_t b, void *fpstp) +{ + float_status *fpst = fpstp; + return -float32_lt(make_float32(b), make_float32(a), fpst); +} -uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b) -{ - float32 f0 = float32_abs(vfp_itos(a)); - float32 f1 = float32_abs(vfp_itos(b)); - return (float32_compare_quiet(f0, f1, NFS) > 0) ? ~0 : 0; +uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b, void *fpstp) +{ + float_status *fpst = fpstp; + float32 f0 = float32_abs(make_float32(a)); + float32 f1 = float32_abs(make_float32(b)); + return -float32_le(f1, f0, fpst); +} + +uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b, void *fpstp) +{ + float_status *fpst = fpstp; + float32 f0 = float32_abs(make_float32(a)); + float32 f1 = float32_abs(make_float32(b)); + return -float32_lt(f1, f0, fpst); +} + +#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1)) + +void HELPER(neon_qunzip8)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm0 = float64_val(env->vfp.regs[rm]); + uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]); + uint64_t zd0 = float64_val(env->vfp.regs[rd]); + uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]); + uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zd0, 2, 8) << 8) + | (ELEM(zd0, 4, 8) << 16) | (ELEM(zd0, 6, 8) << 24) + | (ELEM(zd1, 0, 8) << 32) | (ELEM(zd1, 2, 8) << 40) + | (ELEM(zd1, 4, 8) << 48) | (ELEM(zd1, 6, 8) << 56); + uint64_t d1 = ELEM(zm0, 0, 8) | (ELEM(zm0, 2, 8) << 8) + | (ELEM(zm0, 4, 8) << 16) | (ELEM(zm0, 6, 8) << 24) + | (ELEM(zm1, 0, 8) << 32) | (ELEM(zm1, 2, 8) << 40) + | (ELEM(zm1, 4, 8) << 48) | (ELEM(zm1, 6, 8) << 56); + uint64_t m0 = ELEM(zd0, 1, 8) | (ELEM(zd0, 3, 8) << 8) + | (ELEM(zd0, 5, 8) << 16) | (ELEM(zd0, 7, 8) << 24) + | (ELEM(zd1, 1, 8) << 32) | (ELEM(zd1, 3, 8) << 40) + | (ELEM(zd1, 5, 8) << 48) | (ELEM(zd1, 7, 8) << 56); + uint64_t m1 = ELEM(zm0, 1, 8) | (ELEM(zm0, 3, 8) << 8) + | (ELEM(zm0, 5, 8) << 16) | (ELEM(zm0, 7, 8) << 24) + | (ELEM(zm1, 1, 8) << 32) | (ELEM(zm1, 3, 8) << 40) + | (ELEM(zm1, 5, 8) << 48) | (ELEM(zm1, 7, 8) << 56); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rm + 1] = make_float64(m1); + env->vfp.regs[rd] = make_float64(d0); + env->vfp.regs[rd + 1] = make_float64(d1); +} + +void HELPER(neon_qunzip16)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm0 = float64_val(env->vfp.regs[rm]); + uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]); + uint64_t zd0 = float64_val(env->vfp.regs[rd]); + uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]); + uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zd0, 2, 16) << 16) + | (ELEM(zd1, 0, 16) << 32) | (ELEM(zd1, 2, 16) << 48); + uint64_t d1 = ELEM(zm0, 0, 16) | (ELEM(zm0, 2, 16) << 16) + | (ELEM(zm1, 0, 16) << 32) | (ELEM(zm1, 2, 16) << 48); + uint64_t m0 = ELEM(zd0, 1, 16) | (ELEM(zd0, 3, 16) << 16) + | (ELEM(zd1, 1, 16) << 32) | (ELEM(zd1, 3, 16) << 48); + uint64_t m1 = ELEM(zm0, 1, 16) | (ELEM(zm0, 3, 16) << 16) + | (ELEM(zm1, 1, 16) << 32) | (ELEM(zm1, 3, 16) << 48); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rm + 1] = make_float64(m1); + env->vfp.regs[rd] = make_float64(d0); + env->vfp.regs[rd + 1] = make_float64(d1); +} + +void HELPER(neon_qunzip32)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm0 = float64_val(env->vfp.regs[rm]); + uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]); + uint64_t zd0 = float64_val(env->vfp.regs[rd]); + uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]); + uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zd1, 0, 32) << 32); + uint64_t d1 = ELEM(zm0, 0, 32) | (ELEM(zm1, 0, 32) << 32); + uint64_t m0 = ELEM(zd0, 1, 32) | (ELEM(zd1, 1, 32) << 32); + uint64_t m1 = ELEM(zm0, 1, 32) | (ELEM(zm1, 1, 32) << 32); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rm + 1] = make_float64(m1); + env->vfp.regs[rd] = make_float64(d0); + env->vfp.regs[rd + 1] = make_float64(d1); +} + +void HELPER(neon_unzip8)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm = float64_val(env->vfp.regs[rm]); + uint64_t zd = float64_val(env->vfp.regs[rd]); + uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zd, 2, 8) << 8) + | (ELEM(zd, 4, 8) << 16) | (ELEM(zd, 6, 8) << 24) + | (ELEM(zm, 0, 8) << 32) | (ELEM(zm, 2, 8) << 40) + | (ELEM(zm, 4, 8) << 48) | (ELEM(zm, 6, 8) << 56); + uint64_t m0 = ELEM(zd, 1, 8) | (ELEM(zd, 3, 8) << 8) + | (ELEM(zd, 5, 8) << 16) | (ELEM(zd, 7, 8) << 24) + | (ELEM(zm, 1, 8) << 32) | (ELEM(zm, 3, 8) << 40) + | (ELEM(zm, 5, 8) << 48) | (ELEM(zm, 7, 8) << 56); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rd] = make_float64(d0); +} + +void HELPER(neon_unzip16)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm = float64_val(env->vfp.regs[rm]); + uint64_t zd = float64_val(env->vfp.regs[rd]); + uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zd, 2, 16) << 16) + | (ELEM(zm, 0, 16) << 32) | (ELEM(zm, 2, 16) << 48); + uint64_t m0 = ELEM(zd, 1, 16) | (ELEM(zd, 3, 16) << 16) + | (ELEM(zm, 1, 16) << 32) | (ELEM(zm, 3, 16) << 48); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rd] = make_float64(d0); +} + +void HELPER(neon_qzip8)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm0 = float64_val(env->vfp.regs[rm]); + uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]); + uint64_t zd0 = float64_val(env->vfp.regs[rd]); + uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]); + uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zm0, 0, 8) << 8) + | (ELEM(zd0, 1, 8) << 16) | (ELEM(zm0, 1, 8) << 24) + | (ELEM(zd0, 2, 8) << 32) | (ELEM(zm0, 2, 8) << 40) + | (ELEM(zd0, 3, 8) << 48) | (ELEM(zm0, 3, 8) << 56); + uint64_t d1 = ELEM(zd0, 4, 8) | (ELEM(zm0, 4, 8) << 8) + | (ELEM(zd0, 5, 8) << 16) | (ELEM(zm0, 5, 8) << 24) + | (ELEM(zd0, 6, 8) << 32) | (ELEM(zm0, 6, 8) << 40) + | (ELEM(zd0, 7, 8) << 48) | (ELEM(zm0, 7, 8) << 56); + uint64_t m0 = ELEM(zd1, 0, 8) | (ELEM(zm1, 0, 8) << 8) + | (ELEM(zd1, 1, 8) << 16) | (ELEM(zm1, 1, 8) << 24) + | (ELEM(zd1, 2, 8) << 32) | (ELEM(zm1, 2, 8) << 40) + | (ELEM(zd1, 3, 8) << 48) | (ELEM(zm1, 3, 8) << 56); + uint64_t m1 = ELEM(zd1, 4, 8) | (ELEM(zm1, 4, 8) << 8) + | (ELEM(zd1, 5, 8) << 16) | (ELEM(zm1, 5, 8) << 24) + | (ELEM(zd1, 6, 8) << 32) | (ELEM(zm1, 6, 8) << 40) + | (ELEM(zd1, 7, 8) << 48) | (ELEM(zm1, 7, 8) << 56); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rm + 1] = make_float64(m1); + env->vfp.regs[rd] = make_float64(d0); + env->vfp.regs[rd + 1] = make_float64(d1); +} + +void HELPER(neon_qzip16)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm0 = float64_val(env->vfp.regs[rm]); + uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]); + uint64_t zd0 = float64_val(env->vfp.regs[rd]); + uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]); + uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zm0, 0, 16) << 16) + | (ELEM(zd0, 1, 16) << 32) | (ELEM(zm0, 1, 16) << 48); + uint64_t d1 = ELEM(zd0, 2, 16) | (ELEM(zm0, 2, 16) << 16) + | (ELEM(zd0, 3, 16) << 32) | (ELEM(zm0, 3, 16) << 48); + uint64_t m0 = ELEM(zd1, 0, 16) | (ELEM(zm1, 0, 16) << 16) + | (ELEM(zd1, 1, 16) << 32) | (ELEM(zm1, 1, 16) << 48); + uint64_t m1 = ELEM(zd1, 2, 16) | (ELEM(zm1, 2, 16) << 16) + | (ELEM(zd1, 3, 16) << 32) | (ELEM(zm1, 3, 16) << 48); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rm + 1] = make_float64(m1); + env->vfp.regs[rd] = make_float64(d0); + env->vfp.regs[rd + 1] = make_float64(d1); +} + +void HELPER(neon_qzip32)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm0 = float64_val(env->vfp.regs[rm]); + uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]); + uint64_t zd0 = float64_val(env->vfp.regs[rd]); + uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]); + uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zm0, 0, 32) << 32); + uint64_t d1 = ELEM(zd0, 1, 32) | (ELEM(zm0, 1, 32) << 32); + uint64_t m0 = ELEM(zd1, 0, 32) | (ELEM(zm1, 0, 32) << 32); + uint64_t m1 = ELEM(zd1, 1, 32) | (ELEM(zm1, 1, 32) << 32); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rm + 1] = make_float64(m1); + env->vfp.regs[rd] = make_float64(d0); + env->vfp.regs[rd + 1] = make_float64(d1); +} + +void HELPER(neon_zip8)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm = float64_val(env->vfp.regs[rm]); + uint64_t zd = float64_val(env->vfp.regs[rd]); + uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zm, 0, 8) << 8) + | (ELEM(zd, 1, 8) << 16) | (ELEM(zm, 1, 8) << 24) + | (ELEM(zd, 2, 8) << 32) | (ELEM(zm, 2, 8) << 40) + | (ELEM(zd, 3, 8) << 48) | (ELEM(zm, 3, 8) << 56); + uint64_t m0 = ELEM(zd, 4, 8) | (ELEM(zm, 4, 8) << 8) + | (ELEM(zd, 5, 8) << 16) | (ELEM(zm, 5, 8) << 24) + | (ELEM(zd, 6, 8) << 32) | (ELEM(zm, 6, 8) << 40) + | (ELEM(zd, 7, 8) << 48) | (ELEM(zm, 7, 8) << 56); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rd] = make_float64(d0); +} + +void HELPER(neon_zip16)(CPUState *env, uint32_t rd, uint32_t rm) +{ + uint64_t zm = float64_val(env->vfp.regs[rm]); + uint64_t zd = float64_val(env->vfp.regs[rd]); + uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zm, 0, 16) << 16) + | (ELEM(zd, 1, 16) << 32) | (ELEM(zm, 1, 16) << 48); + uint64_t m0 = ELEM(zd, 2, 16) | (ELEM(zm, 2, 16) << 16) + | (ELEM(zd, 3, 16) << 32) | (ELEM(zm, 3, 16) << 48); + env->vfp.regs[rm] = make_float64(m0); + env->vfp.regs[rd] = make_float64(d0); } diff --git a/target-arm/op_addsub.h b/target-arm/op_addsub.h index c02c92a..ca4a189 100644 --- a/target-arm/op_addsub.h +++ b/target-arm/op_addsub.h @@ -4,7 +4,7 @@ * Copyright (c) 2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #ifdef ARITH_GE diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 3de2610..1892b35 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -16,17 +16,20 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ -#include "exec.h" -#include "helpers.h" +#include "cpu.h" +#include "dyngen-exec.h" +#include "helper.h" #define SIGNBIT (uint32_t)0x80000000 #define SIGNBIT64 ((uint64_t)1 << 63) -void raise_exception(int tt) +#if !defined(CONFIG_USER_ONLY) +static void raise_exception(int tt) { env->exception_index = tt; - cpu_loop_exit(); + cpu_loop_exit(env); } +#endif uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, uint32_t rn, uint32_t maxindex) @@ -52,6 +55,8 @@ uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, #if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" + #define MMUSUFFIX _mmu #define SHIFT 0 @@ -70,18 +75,17 @@ uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { TranslationBlock *tb; CPUState *saved_env; unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; - ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + env = env1; + ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ @@ -90,7 +94,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } raise_exception(env->exception_index); @@ -234,13 +238,13 @@ void HELPER(wfi)(void) { env->exception_index = EXCP_HLT; env->halted = 1; - cpu_loop_exit(); + cpu_loop_exit(env); } void HELPER(exception)(uint32_t excp) { env->exception_index = excp; - cpu_loop_exit(); + cpu_loop_exit(env); } uint32_t HELPER(cpsr_read)(void) diff --git a/target-arm/opengl_dummy.c b/target-arm/opengl_dummy.c deleted file mode 100644 index 57e4336..0000000 --- a/target-arm/opengl_dummy.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include "debug_ch.h" - -MULTI_DEBUG_CHANNEL(qemu, arm_dummy); - -void *init_opengl_server(void *arg); - -void *init_opengl_server(void *arg){ - ERR("init_open_gl_server(arm_dummy) called!!!\n"); - return 0; -} - -#ifndef _WIN32 -#include -#include -void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window); -void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window) -{ - ERR("opengl_exec_set_parent_window(arm_dummy) called!!!\n"); -} -#endif diff --git a/target-arm/translate.c b/target-arm/translate.c index 5149543..0f35b60 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -25,15 +25,18 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "qemu-log.h" -#include "helpers.h" +#include "helper.h" #define GEN_HELPER 1 -#include "helpers.h" +#include "helper.h" +#define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T) +#define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5) +/* currently all emulated v5 cores are also v5TE, so don't bother */ +#define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5) #define ENABLE_ARCH_5J 0 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6) #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K) @@ -125,28 +128,12 @@ void arm_translate_init(void) #endif #define GEN_HELPER 2 -#include "helpers.h" -} - -static int num_temps; - -/* Allocate a temporary variable. */ -static TCGv_i32 new_tmp(void) -{ - num_temps++; - return tcg_temp_new_i32(); -} - -/* Release a temporary variable. */ -static void dead_tmp(TCGv tmp) -{ - tcg_temp_free(tmp); - num_temps--; +#include "helper.h" } static inline TCGv load_cpu_offset(int offset) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp, cpu_env, offset); return tmp; } @@ -156,7 +143,7 @@ static inline TCGv load_cpu_offset(int offset) static inline void store_cpu_offset(TCGv var, int offset) { tcg_gen_st_i32(var, cpu_env, offset); - dead_tmp(var); + tcg_temp_free_i32(var); } #define store_cpu_field(var, name) \ @@ -181,7 +168,7 @@ static void load_reg_var(DisasContext *s, TCGv var, int reg) /* Create a new temporary and set it to the value of a CPU register. */ static inline TCGv load_reg(DisasContext *s, int reg) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); load_reg_var(s, tmp, reg); return tmp; } @@ -195,7 +182,7 @@ static void store_reg(DisasContext *s, int reg, TCGv var) s->is_jmp = DISAS_JUMP; } tcg_gen_mov_i32(cpu_R[reg], var); - dead_tmp(var); + tcg_temp_free_i32(var); } /* Value extensions. */ @@ -219,37 +206,37 @@ static inline void gen_set_cpsr(TCGv var, uint32_t mask) static void gen_exception(int excp) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, excp); gen_helper_exception(tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } static void gen_smul_dual(TCGv a, TCGv b) { - TCGv tmp1 = new_tmp(); - TCGv tmp2 = new_tmp(); + TCGv tmp1 = tcg_temp_new_i32(); + TCGv tmp2 = tcg_temp_new_i32(); tcg_gen_ext16s_i32(tmp1, a); tcg_gen_ext16s_i32(tmp2, b); tcg_gen_mul_i32(tmp1, tmp1, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_sari_i32(a, a, 16); tcg_gen_sari_i32(b, b, 16); tcg_gen_mul_i32(b, b, a); tcg_gen_mov_i32(a, tmp1); - dead_tmp(tmp1); + tcg_temp_free_i32(tmp1); } /* Byteswap each halfword. */ static void gen_rev16(TCGv var) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_shri_i32(tmp, var, 8); tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff); tcg_gen_shli_i32(var, var, 8); tcg_gen_andi_i32(var, var, 0xff00ff00); tcg_gen_or_i32(var, var, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* Byteswap low halfword and sign extend. */ @@ -298,7 +285,7 @@ static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b) TCGv_i64 tmp64 = tcg_temp_new_i64(); tcg_gen_extu_i32_i64(tmp64, b); - dead_tmp(b); + tcg_temp_free_i32(b); tcg_gen_shli_i64(tmp64, tmp64, 32); tcg_gen_add_i64(a, tmp64, a); @@ -312,7 +299,7 @@ static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b) TCGv_i64 tmp64 = tcg_temp_new_i64(); tcg_gen_extu_i32_i64(tmp64, b); - dead_tmp(b); + tcg_temp_free_i32(b); tcg_gen_shli_i64(tmp64, tmp64, 32); tcg_gen_sub_i64(a, tmp64, a); @@ -329,9 +316,9 @@ static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b) TCGv_i64 tmp2 = tcg_temp_new_i64(); tcg_gen_extu_i32_i64(tmp1, a); - dead_tmp(a); + tcg_temp_free_i32(a); tcg_gen_extu_i32_i64(tmp2, b); - dead_tmp(b); + tcg_temp_free_i32(b); tcg_gen_mul_i64(tmp1, tmp1, tmp2); tcg_temp_free_i64(tmp2); return tmp1; @@ -343,9 +330,9 @@ static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b) TCGv_i64 tmp2 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp1, a); - dead_tmp(a); + tcg_temp_free_i32(a); tcg_gen_ext_i32_i64(tmp2, b); - dead_tmp(b); + tcg_temp_free_i32(b); tcg_gen_mul_i64(tmp1, tmp1, tmp2); tcg_temp_free_i64(tmp2); return tmp1; @@ -354,11 +341,11 @@ static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b) /* Swap low and high halfwords. */ static void gen_swap_half(TCGv var) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_shri_i32(tmp, var, 16); tcg_gen_shli_i32(var, var, 16); tcg_gen_or_i32(var, var, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead. @@ -370,15 +357,15 @@ static void gen_swap_half(TCGv var) static void gen_add16(TCGv t0, TCGv t1) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_xor_i32(tmp, t0, t1); tcg_gen_andi_i32(tmp, tmp, 0x8000); tcg_gen_andi_i32(t0, t0, ~0x8000); tcg_gen_andi_i32(t1, t1, ~0x8000); tcg_gen_add_i32(t0, t0, t1); tcg_gen_xor_i32(t0, t0, tmp); - dead_tmp(tmp); - dead_tmp(t1); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(t1); } #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF)) @@ -386,10 +373,10 @@ static void gen_add16(TCGv t0, TCGv t1) /* Set CF to the top bit of var. */ static void gen_set_CF_bit31(TCGv var) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_shri_i32(tmp, var, 31); gen_set_CF(tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* Set N and Z flags from var. */ @@ -406,7 +393,7 @@ static void gen_adc(TCGv t0, TCGv t1) tcg_gen_add_i32(t0, t0, t1); tmp = load_cpu_field(CF); tcg_gen_add_i32(t0, t0, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* dest = T0 + T1 + CF. */ @@ -416,7 +403,7 @@ static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1) tcg_gen_add_i32(dest, t0, t1); tmp = load_cpu_field(CF); tcg_gen_add_i32(dest, dest, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* dest = T0 - T1 + CF - 1. */ @@ -427,7 +414,7 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) tmp = load_cpu_field(CF); tcg_gen_add_i32(dest, dest, tmp); tcg_gen_subi_i32(dest, dest, 1); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* FIXME: Implement this natively. */ @@ -435,7 +422,7 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) static void shifter_out_im(TCGv var, int shift) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); if (shift == 0) { tcg_gen_andi_i32(tmp, var, 1); } else { @@ -444,7 +431,7 @@ static void shifter_out_im(TCGv var, int shift) tcg_gen_andi_i32(tmp, tmp, 1); } gen_set_CF(tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* Shift by immediate. Includes special handling for shift == 0. */ @@ -492,7 +479,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) tcg_gen_shri_i32(var, var, 1); tcg_gen_shli_i32(tmp, tmp, 31); tcg_gen_or_i32(var, var, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } } }; @@ -516,7 +503,7 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop, tcg_gen_rotr_i32(var, var, shift); break; } } - dead_tmp(shift); + tcg_temp_free_i32(shift); } #define PAS_OP(pfx) \ @@ -655,7 +642,7 @@ static void gen_test_cc(int cc, int label) inv = gen_new_label(); tmp = load_cpu_field(CF); tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tmp = load_cpu_field(ZF); tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label); gen_set_label(inv); @@ -663,7 +650,7 @@ static void gen_test_cc(int cc, int label) case 9: /* ls: !C || Z */ tmp = load_cpu_field(CF); tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tmp = load_cpu_field(ZF); tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); break; @@ -671,43 +658,43 @@ static void gen_test_cc(int cc, int label) tmp = load_cpu_field(VF); tmp2 = load_cpu_field(NF); tcg_gen_xor_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); break; case 11: /* lt: N != V -> N ^ V != 0 */ tmp = load_cpu_field(VF); tmp2 = load_cpu_field(NF); tcg_gen_xor_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); break; case 12: /* gt: !Z && N == V */ inv = gen_new_label(); tmp = load_cpu_field(ZF); tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tmp = load_cpu_field(VF); tmp2 = load_cpu_field(NF); tcg_gen_xor_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label); gen_set_label(inv); break; case 13: /* le: Z || N != V */ tmp = load_cpu_field(ZF); tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tmp = load_cpu_field(VF); tmp2 = load_cpu_field(NF); tcg_gen_xor_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label); break; default: fprintf(stderr, "Bad condition code 0x%x\n", cc); abort(); } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } static const uint8_t table_logic_cc[16] = { @@ -736,10 +723,10 @@ static inline void gen_bx_im(DisasContext *s, uint32_t addr) s->is_jmp = DISAS_UPDATE; if (s->thumb != (addr & 1)) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, addr & 1); tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb)); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } tcg_gen_movi_i32(cpu_R[15], addr & ~1); } @@ -766,33 +753,47 @@ static inline void store_reg_bx(CPUState *env, DisasContext *s, } } +/* Variant of store_reg which uses branch&exchange logic when storing + * to r15 in ARM architecture v5T and above. This is used for storing + * the results of a LDR/LDM/POP into r15, and corresponds to the cases + * in the ARM ARM which use the LoadWritePC() pseudocode function. */ +static inline void store_reg_from_load(CPUState *env, DisasContext *s, + int reg, TCGv var) +{ + if (reg == 15 && ENABLE_ARCH_5) { + gen_bx(s, var); + } else { + store_reg(s, reg, var); + } +} + static inline TCGv gen_ld8s(TCGv addr, int index) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld8s(tmp, addr, index); return tmp; } static inline TCGv gen_ld8u(TCGv addr, int index) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld8u(tmp, addr, index); return tmp; } static inline TCGv gen_ld16s(TCGv addr, int index) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld16s(tmp, addr, index); return tmp; } static inline TCGv gen_ld16u(TCGv addr, int index) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld16u(tmp, addr, index); return tmp; } static inline TCGv gen_ld32(TCGv addr, int index) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, index); return tmp; } @@ -805,17 +806,17 @@ static inline TCGv_i64 gen_ld64(TCGv addr, int index) static inline void gen_st8(TCGv val, TCGv addr, int index) { tcg_gen_qemu_st8(val, addr, index); - dead_tmp(val); + tcg_temp_free_i32(val); } static inline void gen_st16(TCGv val, TCGv addr, int index) { tcg_gen_qemu_st16(val, addr, index); - dead_tmp(val); + tcg_temp_free_i32(val); } static inline void gen_st32(TCGv val, TCGv addr, int index) { tcg_gen_qemu_st32(val, addr, index); - dead_tmp(val); + tcg_temp_free_i32(val); } static inline void gen_st64(TCGv_i64 val, TCGv addr, int index) { @@ -859,7 +860,7 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn, tcg_gen_sub_i32(var, var, offset); else tcg_gen_add_i32(var, var, offset); - dead_tmp(offset); + tcg_temp_free_i32(offset); } } @@ -887,17 +888,33 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn, tcg_gen_sub_i32(var, var, offset); else tcg_gen_add_i32(var, var, offset); - dead_tmp(offset); + tcg_temp_free_i32(offset); + } +} + +static TCGv_ptr get_fpstatus_ptr(int neon) +{ + TCGv_ptr statusptr = tcg_temp_new_ptr(); + int offset; + if (neon) { + offset = offsetof(CPUState, vfp.standard_fp_status); + } else { + offset = offsetof(CPUState, vfp.fp_status); } + tcg_gen_addi_ptr(statusptr, cpu_env, offset); + return statusptr; } #define VFP_OP2(name) \ static inline void gen_vfp_##name(int dp) \ { \ - if (dp) \ - gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \ - else \ - gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \ + TCGv_ptr fpst = get_fpstatus_ptr(0); \ + if (dp) { \ + gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \ + } else { \ + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \ + } \ + tcg_temp_free_ptr(fpst); \ } VFP_OP2(add) @@ -907,6 +924,28 @@ VFP_OP2(div) #undef VFP_OP2 +static inline void gen_vfp_F1_mul(int dp) +{ + /* Like gen_vfp_mul() but put result in F1 */ + TCGv_ptr fpst = get_fpstatus_ptr(0); + if (dp) { + gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst); + } else { + gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst); + } + tcg_temp_free_ptr(fpst); +} + +static inline void gen_vfp_F1_neg(int dp) +{ + /* Like gen_vfp_neg() but put result in F1 */ + if (dp) { + gen_helper_vfp_negd(cpu_F1d, cpu_F0d); + } else { + gen_helper_vfp_negs(cpu_F1s, cpu_F0s); + } +} + static inline void gen_vfp_abs(int dp) { if (dp) @@ -955,63 +994,52 @@ static inline void gen_vfp_F1_ld0(int dp) tcg_gen_movi_i32(cpu_F1s, 0); } -static inline void gen_vfp_uito(int dp) -{ - if (dp) - gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env); - else - gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env); -} - -static inline void gen_vfp_sito(int dp) -{ - if (dp) - gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env); - else - gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env); -} - -static inline void gen_vfp_toui(int dp) -{ - if (dp) - gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env); - else - gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env); +#define VFP_GEN_ITOF(name) \ +static inline void gen_vfp_##name(int dp, int neon) \ +{ \ + TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ + if (dp) { \ + gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \ + } else { \ + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ + } \ + tcg_temp_free_ptr(statusptr); \ } -static inline void gen_vfp_touiz(int dp) -{ - if (dp) - gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env); - else - gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env); -} +VFP_GEN_ITOF(uito) +VFP_GEN_ITOF(sito) +#undef VFP_GEN_ITOF -static inline void gen_vfp_tosi(int dp) -{ - if (dp) - gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env); - else - gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env); +#define VFP_GEN_FTOI(name) \ +static inline void gen_vfp_##name(int dp, int neon) \ +{ \ + TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ + if (dp) { \ + gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \ + } else { \ + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \ + } \ + tcg_temp_free_ptr(statusptr); \ } -static inline void gen_vfp_tosiz(int dp) -{ - if (dp) - gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env); - else - gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env); -} +VFP_GEN_FTOI(toui) +VFP_GEN_FTOI(touiz) +VFP_GEN_FTOI(tosi) +VFP_GEN_FTOI(tosiz) +#undef VFP_GEN_FTOI #define VFP_GEN_FIX(name) \ -static inline void gen_vfp_##name(int dp, int shift) \ +static inline void gen_vfp_##name(int dp, int shift, int neon) \ { \ TCGv tmp_shift = tcg_const_i32(shift); \ - if (dp) \ - gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, cpu_env);\ - else \ - gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, cpu_env);\ + TCGv_ptr statusptr = get_fpstatus_ptr(neon); \ + if (dp) { \ + gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \ + } else { \ + gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \ + } \ tcg_temp_free_i32(tmp_shift); \ + tcg_temp_free_ptr(statusptr); \ } VFP_GEN_FIX(tosh) VFP_GEN_FIX(tosl) @@ -1065,7 +1093,7 @@ neon_reg_offset (int reg, int n) static TCGv neon_load_reg(int reg, int pass) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass)); return tmp; } @@ -1073,7 +1101,7 @@ static TCGv neon_load_reg(int reg, int pass) static void neon_store_reg(int reg, int pass, TCGv var) { tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass)); - dead_tmp(var); + tcg_temp_free_i32(var); } static inline void neon_load_reg64(TCGv_i64 var, int reg) @@ -1129,7 +1157,7 @@ static inline void iwmmxt_store_reg(TCGv_i64 var, int reg) static inline TCGv iwmmxt_load_creg(int reg) { - TCGv var = new_tmp(); + TCGv var = tcg_temp_new_i32(); tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg])); return var; } @@ -1137,7 +1165,7 @@ static inline TCGv iwmmxt_load_creg(int reg) static inline void iwmmxt_store_creg(int reg, TCGv var) { tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg])); - dead_tmp(var); + tcg_temp_free_i32(var); } static inline void gen_op_iwmmxt_movq_wRn_M0(int rn) @@ -1268,7 +1296,7 @@ static void gen_op_iwmmxt_set_cup(void) static void gen_op_iwmmxt_setpsr_nz(void) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0); store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]); } @@ -1300,7 +1328,7 @@ static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest) if (insn & (1 << 21)) store_reg(s, rd, tmp); else - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else if (insn & (1 << 21)) { /* Post indexed */ tcg_gen_mov_i32(dest, tmp); @@ -1326,17 +1354,17 @@ static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest) tmp = iwmmxt_load_creg(rd); } } else { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); iwmmxt_load_reg(cpu_V0, rd); tcg_gen_trunc_i64_i32(tmp, cpu_V0); } tcg_gen_andi_i32(tmp, tmp, mask); tcg_gen_mov_i32(dest, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 0; } -/* Disassemble an iwMMXt instruction. Returns nonzero if an error occured +/* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred (ie. an undefined instruction). */ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) { @@ -1364,14 +1392,14 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) } wrd = (insn >> 12) & 0xf; - addr = new_tmp(); + addr = tcg_temp_new_i32(); if (gen_iwmmxt_address(s, insn, addr)) { - dead_tmp(addr); + tcg_temp_free_i32(addr); return 1; } if (insn & ARM_CP_RW_BIT) { if ((insn >> 28) == 0xf) { /* WLDRW wCx */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); iwmmxt_store_creg(wrd, tmp); } else { @@ -1392,7 +1420,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) } if (i) { tcg_gen_extu_i32_i64(cpu_M0, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } gen_op_iwmmxt_movq_wRn_M0(wrd); } @@ -1402,10 +1430,10 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_st32(tmp, addr, IS_USER(s)); } else { gen_op_iwmmxt_movq_M0_wRn(wrd); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (insn & (1 << 8)) { if (insn & (1 << 22)) { /* WSTRD */ - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s)); } else { /* WSTRW wRd */ tcg_gen_trunc_i64_i32(tmp, cpu_M0); @@ -1422,7 +1450,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) } } } - dead_tmp(addr); + tcg_temp_free_i32(addr); return 0; } @@ -1457,7 +1485,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) tmp = iwmmxt_load_creg(wrd); tmp2 = load_reg(s, rd); tcg_gen_andc_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); iwmmxt_store_creg(wrd, tmp); break; case ARM_IWMMXT_wCGR0: @@ -1670,7 +1698,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) tcg_gen_andi_i32(tmp, tmp, 7); iwmmxt_load_reg(cpu_V1, rd1); gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; @@ -1701,7 +1729,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3); tcg_temp_free(tmp3); tcg_temp_free(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; @@ -1711,7 +1739,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) if (rd == 15 || ((insn >> 22) & 3) == 3) return 1; gen_op_iwmmxt_movq_M0_wRn(wrd); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); switch ((insn >> 22) & 3) { case 0: tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3); @@ -1755,7 +1783,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) } tcg_gen_shli_i32(tmp, tmp, 28); gen_set_nzcv(tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */ if (((insn >> 6) & 3) == 3) @@ -1774,7 +1802,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_helper_iwmmxt_bcstl(cpu_M0, tmp); break; } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; @@ -1782,7 +1810,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) return 1; tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp2, tmp); switch ((insn >> 22) & 3) { case 0: @@ -1803,8 +1831,8 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) break; } gen_set_nzcv(tmp); - dead_tmp(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); break; case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */ wrd = (insn >> 12) & 0xf; @@ -1830,7 +1858,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) return 1; tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp2, tmp); switch ((insn >> 22) & 3) { case 0: @@ -1851,8 +1879,8 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) break; } gen_set_nzcv(tmp); - dead_tmp(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); break; case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */ rd = (insn >> 12) & 0xf; @@ -1860,7 +1888,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3) return 1; gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); switch ((insn >> 22) & 3) { case 0: gen_helper_iwmmxt_msbb(tmp, cpu_M0); @@ -1975,9 +2003,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (gen_iwmmxt_shift(insn, 0xff, tmp)) { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 1; } switch ((insn >> 22) & 3) { @@ -1991,7 +2019,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp); break; } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); @@ -2003,9 +2031,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (gen_iwmmxt_shift(insn, 0xff, tmp)) { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 1; } switch ((insn >> 22) & 3) { @@ -2019,7 +2047,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp); break; } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); @@ -2031,9 +2059,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (gen_iwmmxt_shift(insn, 0xff, tmp)) { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 1; } switch ((insn >> 22) & 3) { @@ -2047,7 +2075,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp); break; } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); @@ -2059,31 +2087,31 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); switch ((insn >> 22) & 3) { case 1: if (gen_iwmmxt_shift(insn, 0xf, tmp)) { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 1; } gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp); break; case 2: if (gen_iwmmxt_shift(insn, 0x1f, tmp)) { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 1; } gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp); break; case 3: if (gen_iwmmxt_shift(insn, 0x3f, tmp)) { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 1; } gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp); break; } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); @@ -2324,12 +2352,12 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); break; default: - dead_tmp(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); return 1; } - dead_tmp(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; @@ -2340,7 +2368,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) return 0; } -/* Disassemble an XScale DSP instruction. Returns nonzero if an error occured +/* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred (ie. an undefined instruction). */ static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn) { @@ -2378,8 +2406,8 @@ static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn) default: return 1; } - dead_tmp(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); gen_op_iwmmxt_movq_wRn_M0(acc); return 0; @@ -2425,7 +2453,7 @@ static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn) if (!env->cp[cp].cp_read) return 1; gen_set_pc_im(s->pc); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tmp2 = tcg_const_i32(insn); gen_helper_get_cp(tmp, cpu_env, tmp2); tcg_temp_free(tmp2); @@ -2438,28 +2466,38 @@ static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn) tmp2 = tcg_const_i32(insn); gen_helper_set_cp(cpu_env, tmp2, tmp); tcg_temp_free(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } return 0; } -static int cp15_user_ok(uint32_t insn) +static int cp15_user_ok(CPUState *env, uint32_t insn) { int cpn = (insn >> 16) & 0xf; int cpm = insn & 0xf; int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38); + if (arm_feature(env, ARM_FEATURE_V7) && cpn == 9) { + /* Performance monitor registers fall into three categories: + * (a) always UNDEF in usermode + * (b) UNDEF only if PMUSERENR.EN is 0 + * (c) always read OK and UNDEF on write (PMUSERENR only) + */ + if ((cpm == 12 && (op < 6)) || + (cpm == 13 && (op < 3))) { + return env->cp15.c9_pmuserenr; + } else if (cpm == 14 && op == 0 && (insn & ARM_CP_RW_BIT)) { + /* PMUSERENR, read only */ + return 1; + } + return 0; + } + if (cpn == 13 && cpm == 0) { /* TLS register. */ if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT))) return 1; } - if (cpn == 7) { - /* ISB, DSB, DMB. */ - if ((cpm == 5 && op == 4) - || (cpm == 10 && (op == 4 || op == 5))) - return 1; - } return 0; } @@ -2505,7 +2543,7 @@ static int cp15_tls_load_store(CPUState *env, DisasContext *s, uint32_t insn, ui store_cpu_field(tmp, cp15.c13_tls3); break; default: - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 0; } } @@ -2535,16 +2573,62 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) /* cdp */ return 1; } - if (IS_USER(s) && !cp15_user_ok(insn)) { - return 1; - } - if ((insn & 0x0fff0fff) == 0x0e070f90 - || (insn & 0x0fff0fff) == 0x0e070f58) { - /* Wait for interrupt. */ - gen_set_pc_im(s->pc); - s->is_jmp = DISAS_WFI; + /* We special case a number of cp15 instructions which were used + * for things which are real instructions in ARMv7. This allows + * them to work in linux-user mode which doesn't provide functional + * get_cp15/set_cp15 helpers, and is more efficient anyway. + */ + switch ((insn & 0x0fff0fff)) { + case 0x0e070f90: + /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores). + * In v7, this must NOP. + */ + if (IS_USER(s)) { + return 1; + } + if (!arm_feature(env, ARM_FEATURE_V7)) { + /* Wait for interrupt. */ + gen_set_pc_im(s->pc); + s->is_jmp = DISAS_WFI; + } return 0; + case 0x0e070f58: + /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI, + * so this is slightly over-broad. + */ + if (!IS_USER(s) && !arm_feature(env, ARM_FEATURE_V6)) { + /* Wait for interrupt. */ + gen_set_pc_im(s->pc); + s->is_jmp = DISAS_WFI; + return 0; + } + /* Otherwise continue to handle via helper function. + * In particular, on v7 and some v6 cores this is one of + * the VA-PA registers. + */ + break; + case 0x0e070f3d: + /* 0,c7,c13,1: prefetch-by-MVA in v6, NOP in v7 */ + if (arm_feature(env, ARM_FEATURE_V6)) { + return IS_USER(s) ? 1 : 0; + } + break; + case 0x0e070f95: /* 0,c7,c5,4 : ISB */ + case 0x0e070f9a: /* 0,c7,c10,4: DSB */ + case 0x0e070fba: /* 0,c7,c10,5: DMB */ + /* Barriers in both v6 and v7 */ + if (arm_feature(env, ARM_FEATURE_V6)) { + return 0; + } + break; + default: + break; } + + if (IS_USER(s) && !cp15_user_ok(env, insn)) { + return 1; + } + rd = (insn >> 12) & 0xf; if (cp15_tls_load_store(env, s, insn, rd)) @@ -2552,17 +2636,17 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) tmp2 = tcg_const_i32(insn); if (insn & ARM_CP_RW_BIT) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); gen_helper_get_cp15(tmp, cpu_env, tmp2); /* If the destination register is r15 then sets condition codes. */ if (rd != 15) store_reg(s, rd, tmp); else - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else { tmp = load_reg(s, rd); gen_helper_set_cp15(cpu_env, tmp2, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); /* Normally we would always end the TB here, but Linux * arch/arm/mach-pxa/sleep.S expects two instructions following * an MMU enable to execute from cache. Imitate this behaviour. */ @@ -2597,7 +2681,7 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) /* Move between integer and VFP cores. */ static TCGv gen_vfp_mrs(void) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp, cpu_F0s); return tmp; } @@ -2605,12 +2689,12 @@ static TCGv gen_vfp_mrs(void) static void gen_vfp_msr(TCGv tmp) { tcg_gen_mov_i32(cpu_F0s, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } static void gen_neon_dup_u8(TCGv var, int shift) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); if (shift) tcg_gen_shri_i32(var, var, shift); tcg_gen_ext8u_i32(var, var); @@ -2618,28 +2702,50 @@ static void gen_neon_dup_u8(TCGv var, int shift) tcg_gen_or_i32(var, var, tmp); tcg_gen_shli_i32(tmp, var, 16); tcg_gen_or_i32(var, var, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } static void gen_neon_dup_low16(TCGv var) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_ext16u_i32(var, var); tcg_gen_shli_i32(tmp, var, 16); tcg_gen_or_i32(var, var, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } static void gen_neon_dup_high16(TCGv var) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_andi_i32(var, var, 0xffff0000); tcg_gen_shri_i32(tmp, var, 16); tcg_gen_or_i32(var, var, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); +} + +static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size) +{ + /* Load a single Neon element and replicate into a 32 bit TCG reg */ + TCGv tmp; + switch (size) { + case 0: + tmp = gen_ld8u(addr, IS_USER(s)); + gen_neon_dup_u8(tmp, 0); + break; + case 1: + tmp = gen_ld16u(addr, IS_USER(s)); + gen_neon_dup_low16(tmp); + break; + case 2: + tmp = gen_ld32(addr, IS_USER(s)); + break; + default: /* Avoid compiler warnings. */ + abort(); + } + return tmp; } -/* Disassemble a VFP instruction. Returns nonzero if an error occured +/* Disassemble a VFP instruction. Returns nonzero if an error occurred (ie. an undefined instruction). */ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) { @@ -2731,7 +2837,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_neon_dup_low16(tmp); } for (n = 0; n <= pass * 2; n++) { - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp2, tmp); neon_store_reg(rn, n, tmp2); } @@ -2742,12 +2848,12 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) case 0: tmp2 = neon_load_reg(rn, pass); gen_bfi(tmp, tmp2, tmp, offset, 0xff); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); break; case 1: tmp2 = neon_load_reg(rn, pass); gen_bfi(tmp, tmp2, tmp, offset, 0xffff); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); break; case 2: break; @@ -2793,7 +2899,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); tcg_gen_andi_i32(tmp, tmp, 0xf0000000); } else { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); gen_helper_vfp_get_fpscr(tmp, cpu_env); } break; @@ -2814,7 +2920,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) if (rd == 15) { /* Set the 4 flag bits in the CPSR. */ gen_set_nzcv(tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else { store_reg(s, rd, tmp); } @@ -2832,7 +2938,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) break; case ARM_VFP_FPSCR: gen_helper_vfp_set_fpscr(cpu_env, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_lookup_tb(s); break; case ARM_VFP_FPEXC: @@ -2965,6 +3071,17 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) /* Source and destination the same. */ gen_mov_F0_vreg(dp, rd); break; + case 4: + case 5: + case 6: + case 7: + /* VCVTB, VCVTT: only present with the halfprec extension, + * UNPREDICTABLE if bit 8 is set (we choose to UNDEF) + */ + if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) { + return 1; + } + /* Otherwise fall through */ default: /* One source operand. */ gen_mov_F0_vreg(dp, rm); @@ -2979,27 +3096,34 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) for (;;) { /* Perform the calculation. */ switch (op) { - case 0: /* mac: fd + (fn * fm) */ - gen_vfp_mul(dp); - gen_mov_F1_vreg(dp, rd); + case 0: /* VMLA: fd + (fn * fm) */ + /* Note that order of inputs to the add matters for NaNs */ + gen_vfp_F1_mul(dp); + gen_mov_F0_vreg(dp, rd); gen_vfp_add(dp); break; - case 1: /* nmac: fd - (fn * fm) */ + case 1: /* VMLS: fd + -(fn * fm) */ gen_vfp_mul(dp); - gen_vfp_neg(dp); - gen_mov_F1_vreg(dp, rd); + gen_vfp_F1_neg(dp); + gen_mov_F0_vreg(dp, rd); gen_vfp_add(dp); break; - case 2: /* msc: -fd + (fn * fm) */ - gen_vfp_mul(dp); - gen_mov_F1_vreg(dp, rd); - gen_vfp_sub(dp); + case 2: /* VNMLS: -fd + (fn * fm) */ + /* Note that it isn't valid to replace (-A + B) with (B - A) + * or similar plausible looking simplifications + * because this will give wrong results for NaNs. + */ + gen_vfp_F1_mul(dp); + gen_mov_F0_vreg(dp, rd); + gen_vfp_neg(dp); + gen_vfp_add(dp); break; - case 3: /* nmsc: -fd - (fn * fm) */ + case 3: /* VNMLA: -fd + -(fn * fm) */ gen_vfp_mul(dp); + gen_vfp_F1_neg(dp); + gen_mov_F0_vreg(dp, rd); gen_vfp_neg(dp); - gen_mov_F1_vreg(dp, rd); - gen_vfp_sub(dp); + gen_vfp_add(dp); break; case 4: /* mul: fn * fm */ gen_vfp_mul(dp); @@ -3017,6 +3141,57 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) case 8: /* div: fn / fm */ gen_vfp_div(dp); break; + case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */ + case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */ + case 12: /* VFMA : fd = muladd( fd, fn, fm) */ + case 13: /* VFMS : fd = muladd( fd, -fn, fm) */ + /* These are fused multiply-add, and must be done as one + * floating point operation with no rounding between the + * multiplication and addition steps. + * NB that doing the negations here as separate steps is + * correct : an input NaN should come out with its sign bit + * flipped if it is a negated-input. + */ + if (!arm_feature(env, ARM_FEATURE_VFP4)) { + return 1; + } + if (dp) { + TCGv_ptr fpst; + TCGv_i64 frd; + if (op & 1) { + /* VFNMS, VFMS */ + gen_helper_vfp_negd(cpu_F0d, cpu_F0d); + } + frd = tcg_temp_new_i64(); + tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd)); + if (op & 2) { + /* VFNMA, VFNMS */ + gen_helper_vfp_negd(frd, frd); + } + fpst = get_fpstatus_ptr(0); + gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d, + cpu_F1d, frd, fpst); + tcg_temp_free_ptr(fpst); + tcg_temp_free_i64(frd); + } else { + TCGv_ptr fpst; + TCGv_i32 frd; + if (op & 1) { + /* VFNMS, VFMS */ + gen_helper_vfp_negs(cpu_F0s, cpu_F0s); + } + frd = tcg_temp_new_i32(); + tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd)); + if (op & 2) { + gen_helper_vfp_negs(frd, frd); + } + fpst = get_fpstatus_ptr(0); + gen_helper_vfp_muladds(cpu_F0s, cpu_F0s, + cpu_F1s, frd, fpst); + tcg_temp_free_ptr(fpst); + tcg_temp_free_i32(frd); + } + break; case 14: /* fconst */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; @@ -3054,44 +3229,36 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_vfp_sqrt(dp); break; case 4: /* vcvtb.f32.f16 */ - if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) - return 1; tmp = gen_vfp_mrs(); tcg_gen_ext16u_i32(tmp, tmp); gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; case 5: /* vcvtt.f32.f16 */ - if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) - return 1; tmp = gen_vfp_mrs(); tcg_gen_shri_i32(tmp, tmp, 16); gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; case 6: /* vcvtb.f16.f32 */ - if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) - return 1; - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); gen_mov_F0_vreg(0, rd); tmp2 = gen_vfp_mrs(); tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); tcg_gen_or_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); gen_vfp_msr(tmp); break; case 7: /* vcvtt.f16.f32 */ - if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) - return 1; - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); tcg_gen_shli_i32(tmp, tmp, 16); gen_mov_F0_vreg(0, rd); tmp2 = gen_vfp_mrs(); tcg_gen_ext16u_i32(tmp2, tmp2); tcg_gen_or_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); gen_vfp_msr(tmp); break; case 8: /* cmp */ @@ -3114,70 +3281,68 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env); break; case 16: /* fuito */ - gen_vfp_uito(dp); + gen_vfp_uito(dp, 0); break; case 17: /* fsito */ - gen_vfp_sito(dp); + gen_vfp_sito(dp, 0); break; case 20: /* fshto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_shto(dp, 16 - rm); + gen_vfp_shto(dp, 16 - rm, 0); break; case 21: /* fslto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_slto(dp, 32 - rm); + gen_vfp_slto(dp, 32 - rm, 0); break; case 22: /* fuhto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_uhto(dp, 16 - rm); + gen_vfp_uhto(dp, 16 - rm, 0); break; case 23: /* fulto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_ulto(dp, 32 - rm); + gen_vfp_ulto(dp, 32 - rm, 0); break; case 24: /* ftoui */ - gen_vfp_toui(dp); + gen_vfp_toui(dp, 0); break; case 25: /* ftouiz */ - gen_vfp_touiz(dp); + gen_vfp_touiz(dp, 0); break; case 26: /* ftosi */ - gen_vfp_tosi(dp); + gen_vfp_tosi(dp, 0); break; case 27: /* ftosiz */ - gen_vfp_tosiz(dp); + gen_vfp_tosiz(dp, 0); break; case 28: /* ftosh */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_tosh(dp, 16 - rm); + gen_vfp_tosh(dp, 16 - rm, 0); break; case 29: /* ftosl */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_tosl(dp, 32 - rm); + gen_vfp_tosl(dp, 32 - rm, 0); break; case 30: /* ftouh */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_touh(dp, 16 - rm); + gen_vfp_touh(dp, 16 - rm, 0); break; case 31: /* ftoul */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; - gen_vfp_toul(dp, 32 - rm); + gen_vfp_toul(dp, 32 - rm, 0); break; default: /* undefined */ - printf ("rn:%d\n", rn); return 1; } break; default: /* undefined */ - printf ("op:%d\n", op); return 1; } @@ -3232,7 +3397,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) break; case 0xc: case 0xd: - if (dp && (insn & 0x03e00000) == 0x00400000) { + if ((insn & 0x03e00000) == 0x00400000) { /* two-register transfer */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; @@ -3254,10 +3419,10 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) } else { gen_mov_F0_vreg(0, rm); tmp = gen_vfp_mrs(); - store_reg(s, rn, tmp); + store_reg(s, rd, tmp); gen_mov_F0_vreg(0, rm + 1); tmp = gen_vfp_mrs(); - store_reg(s, rd, tmp); + store_reg(s, rn, tmp); } } else { /* arm->vfp */ @@ -3269,10 +3434,10 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm * 2 + 1); } else { - tmp = load_reg(s, rn); + tmp = load_reg(s, rd); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm); - tmp = load_reg(s, rd); + tmp = load_reg(s, rn); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm + 1); } @@ -3284,17 +3449,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) VFP_DREG_D(rd, insn); else rd = VFP_SREG_D(insn); - if (s->thumb && rn == 15) { - addr = new_tmp(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, rn); - } if ((insn & 0x01200000) == 0x01000000) { /* Single load/store */ offset = (insn & 0xff) << 2; if ((insn & (1 << 23)) == 0) offset = -offset; + if (s->thumb && rn == 15) { + /* This is actually UNPREDICTABLE */ + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc & ~2); + } else { + addr = load_reg(s, rn); + } tcg_gen_addi_i32(addr, addr, offset); if (insn & (1 << 20)) { gen_vfp_ld(s, dp, addr); @@ -3303,14 +3469,37 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_mov_F0_vreg(dp, rd); gen_vfp_st(s, dp, addr); } - dead_tmp(addr); + tcg_temp_free_i32(addr); } else { /* load/store multiple */ + int w = insn & (1 << 21); if (dp) n = (insn >> 1) & 0x7f; else n = insn & 0xff; + if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) { + /* P == U , W == 1 => UNDEF */ + return 1; + } + if (n == 0 || (rd + n) > 32 || (dp && n > 16)) { + /* UNPREDICTABLE cases for bad immediates: we choose to + * UNDEF to avoid generating huge numbers of TCG ops + */ + return 1; + } + if (rn == 15 && w) { + /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */ + return 1; + } + + if (s->thumb && rn == 15) { + /* This is actually UNPREDICTABLE */ + addr = tcg_temp_new_i32(); + tcg_gen_movi_i32(addr, s->pc & ~2); + } else { + addr = load_reg(s, rn); + } if (insn & (1 << 24)) /* pre-decrement */ tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2)); @@ -3330,7 +3519,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) } tcg_gen_addi_i32(addr, addr, offset); } - if (insn & (1 << 21)) { + if (w) { /* writeback */ if (insn & (1 << 24)) offset = -offset * n; @@ -3343,7 +3532,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_gen_addi_i32(addr, addr, offset); store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } } } @@ -3363,7 +3552,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); gen_set_pc_im(dest); - tcg_gen_exit_tb((long)tb + n); + tcg_gen_exit_tb((tcg_target_long)tb + n); } else { gen_set_pc_im(dest); tcg_gen_exit_tb(0); @@ -3412,6 +3601,10 @@ static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) { /* Mask out undefined bits. */ mask &= ~CPSR_RESERVED; + if (!arm_feature(env, ARM_FEATURE_V4T)) + mask &= ~CPSR_T; + if (!arm_feature(env, ARM_FEATURE_V5)) + mask &= ~CPSR_Q; /* V5TE in reality*/ if (!arm_feature(env, ARM_FEATURE_V6)) mask &= ~(CPSR_E | CPSR_GE); if (!arm_feature(env, ARM_FEATURE_THUMB2)) @@ -3442,7 +3635,7 @@ static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0) } else { gen_set_cpsr(t0, mask); } - dead_tmp(t0); + tcg_temp_free_i32(t0); gen_lookup_tb(s); return 0; } @@ -3451,7 +3644,7 @@ static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0) static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val) { TCGv tmp; - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); return gen_set_psr(s, mask, spsr, tmp); } @@ -3463,7 +3656,7 @@ static void gen_exception_return(DisasContext *s, TCGv pc) store_reg(s, 15, pc); tmp = load_cpu_field(spsr); gen_set_cpsr(tmp, 0xffffffff); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); s->is_jmp = DISAS_UPDATE; } @@ -3471,7 +3664,7 @@ static void gen_exception_return(DisasContext *s, TCGv pc) static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr) { gen_set_cpsr(cpsr, 0xffffffff); - dead_tmp(cpsr); + tcg_temp_free_i32(cpsr); store_reg(s, 15, pc); s->is_jmp = DISAS_UPDATE; } @@ -3481,7 +3674,7 @@ gen_set_condexec (DisasContext *s) { if (s->condexec_mask) { uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1); - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); store_cpu_field(tmp, condexec_bits); } @@ -3512,15 +3705,14 @@ static void gen_nop_hint(DisasContext *s, int val) #define CPU_V001 cpu_V0, cpu_V0, cpu_V1 -static inline int gen_neon_add(int size, TCGv t0, TCGv t1) +static inline void gen_neon_add(int size, TCGv t0, TCGv t1) { switch (size) { case 0: gen_helper_neon_add_u8(t0, t0, t1); break; case 1: gen_helper_neon_add_u16(t0, t0, t1); break; case 2: tcg_gen_add_i32(t0, t0, t1); break; - default: return 1; + default: abort(); } - return 0; } static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1) @@ -3587,7 +3779,7 @@ static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1) static TCGv neon_load_scratch(int scratch) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); return tmp; } @@ -3595,7 +3787,7 @@ static TCGv neon_load_scratch(int scratch) static void neon_store_scratch(int scratch, TCGv var) { tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); - dead_tmp(var); + tcg_temp_free_i32(var); } static inline TCGv neon_get_scalar(int size, int reg) @@ -3614,144 +3806,112 @@ static inline TCGv neon_get_scalar(int size, int reg) return tmp; } -static void gen_neon_unzip_u8(TCGv t0, TCGv t1) -{ - TCGv rd, rm, tmp; - - rd = new_tmp(); - rm = new_tmp(); - tmp = new_tmp(); - - tcg_gen_andi_i32(rd, t0, 0xff); - tcg_gen_shri_i32(tmp, t0, 8); - tcg_gen_andi_i32(tmp, tmp, 0xff00); - tcg_gen_or_i32(rd, rd, tmp); - tcg_gen_shli_i32(tmp, t1, 16); - tcg_gen_andi_i32(tmp, tmp, 0xff0000); - tcg_gen_or_i32(rd, rd, tmp); - tcg_gen_shli_i32(tmp, t1, 8); - tcg_gen_andi_i32(tmp, tmp, 0xff000000); - tcg_gen_or_i32(rd, rd, tmp); - - tcg_gen_shri_i32(rm, t0, 8); - tcg_gen_andi_i32(rm, rm, 0xff); - tcg_gen_shri_i32(tmp, t0, 16); - tcg_gen_andi_i32(tmp, tmp, 0xff00); - tcg_gen_or_i32(rm, rm, tmp); - tcg_gen_shli_i32(tmp, t1, 8); - tcg_gen_andi_i32(tmp, tmp, 0xff0000); - tcg_gen_or_i32(rm, rm, tmp); - tcg_gen_andi_i32(tmp, t1, 0xff000000); - tcg_gen_or_i32(t1, rm, tmp); - tcg_gen_mov_i32(t0, rd); - - dead_tmp(tmp); - dead_tmp(rm); - dead_tmp(rd); -} - -static void gen_neon_zip_u8(TCGv t0, TCGv t1) -{ - TCGv rd, rm, tmp; - - rd = new_tmp(); - rm = new_tmp(); - tmp = new_tmp(); - - tcg_gen_andi_i32(rd, t0, 0xff); - tcg_gen_shli_i32(tmp, t1, 8); - tcg_gen_andi_i32(tmp, tmp, 0xff00); - tcg_gen_or_i32(rd, rd, tmp); - tcg_gen_shli_i32(tmp, t0, 16); - tcg_gen_andi_i32(tmp, tmp, 0xff0000); - tcg_gen_or_i32(rd, rd, tmp); - tcg_gen_shli_i32(tmp, t1, 24); - tcg_gen_andi_i32(tmp, tmp, 0xff000000); - tcg_gen_or_i32(rd, rd, tmp); - - tcg_gen_andi_i32(rm, t1, 0xff000000); - tcg_gen_shri_i32(tmp, t0, 8); - tcg_gen_andi_i32(tmp, tmp, 0xff0000); - tcg_gen_or_i32(rm, rm, tmp); - tcg_gen_shri_i32(tmp, t1, 8); - tcg_gen_andi_i32(tmp, tmp, 0xff00); - tcg_gen_or_i32(rm, rm, tmp); - tcg_gen_shri_i32(tmp, t0, 16); - tcg_gen_andi_i32(tmp, tmp, 0xff); - tcg_gen_or_i32(t1, rm, tmp); - tcg_gen_mov_i32(t0, rd); - - dead_tmp(tmp); - dead_tmp(rm); - dead_tmp(rd); -} - -static void gen_neon_zip_u16(TCGv t0, TCGv t1) +static int gen_neon_unzip(int rd, int rm, int size, int q) { TCGv tmp, tmp2; - - tmp = new_tmp(); - tmp2 = new_tmp(); - - tcg_gen_andi_i32(tmp, t0, 0xffff); - tcg_gen_shli_i32(tmp2, t1, 16); - tcg_gen_or_i32(tmp, tmp, tmp2); - tcg_gen_andi_i32(t1, t1, 0xffff0000); - tcg_gen_shri_i32(tmp2, t0, 16); - tcg_gen_or_i32(t1, t1, tmp2); - tcg_gen_mov_i32(t0, tmp); - - dead_tmp(tmp2); - dead_tmp(tmp); -} - -static void gen_neon_unzip(int reg, int q, int tmp, int size) -{ - int n; - TCGv t0, t1; - - for (n = 0; n < q + 1; n += 2) { - t0 = neon_load_reg(reg, n); - t1 = neon_load_reg(reg, n + 1); + if (!q && size == 2) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rm); + if (q) { switch (size) { - case 0: gen_neon_unzip_u8(t0, t1); break; - case 1: gen_neon_zip_u16(t0, t1); break; /* zip and unzip are the same. */ - case 2: /* no-op */; break; - default: abort(); + case 0: + gen_helper_neon_qunzip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_qunzip16(cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qunzip32(cpu_env, tmp, tmp2); + break; + default: + abort(); + } + } else { + switch (size) { + case 0: + gen_helper_neon_unzip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_unzip16(cpu_env, tmp, tmp2); + break; + default: + abort(); } - neon_store_scratch(tmp + n, t0); - neon_store_scratch(tmp + n + 1, t1); } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + return 0; } -static void gen_neon_trn_u8(TCGv t0, TCGv t1) +static int gen_neon_zip(int rd, int rm, int size, int q) { - TCGv rd, tmp; - - rd = new_tmp(); - tmp = new_tmp(); - - tcg_gen_shli_i32(rd, t0, 8); - tcg_gen_andi_i32(rd, rd, 0xff00ff00); - tcg_gen_andi_i32(tmp, t1, 0x00ff00ff); - tcg_gen_or_i32(rd, rd, tmp); - - tcg_gen_shri_i32(t1, t1, 8); - tcg_gen_andi_i32(t1, t1, 0x00ff00ff); - tcg_gen_andi_i32(tmp, t0, 0xff00ff00); + TCGv tmp, tmp2; + if (!q && size == 2) { + return 1; + } + tmp = tcg_const_i32(rd); + tmp2 = tcg_const_i32(rm); + if (q) { + switch (size) { + case 0: + gen_helper_neon_qzip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_qzip16(cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qzip32(cpu_env, tmp, tmp2); + break; + default: + abort(); + } + } else { + switch (size) { + case 0: + gen_helper_neon_zip8(cpu_env, tmp, tmp2); + break; + case 1: + gen_helper_neon_zip16(cpu_env, tmp, tmp2); + break; + default: + abort(); + } + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + return 0; +} + +static void gen_neon_trn_u8(TCGv t0, TCGv t1) +{ + TCGv rd, tmp; + + rd = tcg_temp_new_i32(); + tmp = tcg_temp_new_i32(); + + tcg_gen_shli_i32(rd, t0, 8); + tcg_gen_andi_i32(rd, rd, 0xff00ff00); + tcg_gen_andi_i32(tmp, t1, 0x00ff00ff); + tcg_gen_or_i32(rd, rd, tmp); + + tcg_gen_shri_i32(t1, t1, 8); + tcg_gen_andi_i32(t1, t1, 0x00ff00ff); + tcg_gen_andi_i32(tmp, t0, 0xff00ff00); tcg_gen_or_i32(t1, t1, tmp); tcg_gen_mov_i32(t0, rd); - dead_tmp(tmp); - dead_tmp(rd); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(rd); } static void gen_neon_trn_u16(TCGv t0, TCGv t1) { TCGv rd, tmp; - rd = new_tmp(); - tmp = new_tmp(); + rd = tcg_temp_new_i32(); + tmp = tcg_temp_new_i32(); tcg_gen_shli_i32(rd, t0, 16); tcg_gen_andi_i32(tmp, t1, 0xffff); @@ -3761,8 +3921,8 @@ static void gen_neon_trn_u16(TCGv t0, TCGv t1) tcg_gen_or_i32(t1, t1, tmp); tcg_gen_mov_i32(t0, rd); - dead_tmp(tmp); - dead_tmp(rd); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(rd); } @@ -3811,18 +3971,33 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) rn = (insn >> 16) & 0xf; rm = insn & 0xf; load = (insn & (1 << 21)) != 0; - addr = new_tmp(); if ((insn & (1 << 23)) == 0) { /* Load store all elements. */ op = (insn >> 8) & 0xf; size = (insn >> 6) & 3; if (op > 10) return 1; + /* Catch UNDEF cases for bad values of align field */ + switch (op & 0xc) { + case 4: + if (((insn >> 5) & 1) == 1) { + return 1; + } + break; + case 8: + if (((insn >> 4) & 3) == 3) { + return 1; + } + break; + default: + break; + } nregs = neon_ls_element_type[op].nregs; interleave = neon_ls_element_type[op].interleave; spacing = neon_ls_element_type[op].spacing; if (size == 3 && (interleave | spacing) != 1) return 1; + addr = tcg_temp_new_i32(); load_reg_var(s, addr, rn); stride = (1 << size) * interleave; for (reg = 0; reg < nregs; reg++) { @@ -3863,11 +4038,11 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_gen_addi_i32(addr, addr, stride); tcg_gen_shli_i32(tmp2, tmp2, 16); tcg_gen_or_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); neon_store_reg(rd, pass, tmp); } else { tmp = neon_load_reg(rd, pass); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_shri_i32(tmp2, tmp, 16); gen_st16(tmp, addr, IS_USER(s)); tcg_gen_addi_i32(addr, addr, stride); @@ -3885,14 +4060,14 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) } else { tcg_gen_shli_i32(tmp, tmp, n * 8); tcg_gen_or_i32(tmp2, tmp2, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } } neon_store_reg(rd, pass, tmp2); } else { tmp2 = neon_load_reg(rd, pass); for (n = 0; n < 4; n++) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (n == 0) { tcg_gen_mov_i32(tmp, tmp2); } else { @@ -3901,52 +4076,68 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_st8(tmp, addr, IS_USER(s)); tcg_gen_addi_i32(addr, addr, stride); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } } } } rd += spacing; } + tcg_temp_free_i32(addr); stride = nregs * 8; } else { size = (insn >> 10) & 3; if (size == 3) { /* Load single element to all lanes. */ - if (!load) + int a = (insn >> 4) & 1; + if (!load) { return 1; + } size = (insn >> 6) & 3; nregs = ((insn >> 8) & 3) + 1; - stride = (insn & (1 << 5)) ? 2 : 1; - load_reg_var(s, addr, rn); - for (reg = 0; reg < nregs; reg++) { - switch (size) { - case 0: - tmp = gen_ld8u(addr, IS_USER(s)); - gen_neon_dup_u8(tmp, 0); - break; - case 1: - tmp = gen_ld16u(addr, IS_USER(s)); - gen_neon_dup_low16(tmp); - break; - case 2: - tmp = gen_ld32(addr, IS_USER(s)); - break; - case 3: + + if (size == 3) { + if (nregs != 4 || a == 0) { return 1; - default: /* Avoid compiler warnings. */ - abort(); } - tcg_gen_addi_i32(addr, addr, 1 << size); - tmp2 = new_tmp(); - tcg_gen_mov_i32(tmp2, tmp); - neon_store_reg(rd, 0, tmp2); - neon_store_reg(rd, 1, tmp); - rd += stride; + /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */ + size = 2; + } + if (nregs == 1 && a == 1 && size == 0) { + return 1; + } + if (nregs == 3 && a == 1) { + return 1; + } + addr = tcg_temp_new_i32(); + load_reg_var(s, addr, rn); + if (nregs == 1) { + /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */ + tmp = gen_load_and_replicate(s, addr, size); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); + if (insn & (1 << 5)) { + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0)); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1)); + } + tcg_temp_free_i32(tmp); + } else { + /* VLD2/3/4 to all lanes: bit 5 indicates register stride */ + stride = (insn & (1 << 5)) ? 2 : 1; + for (reg = 0; reg < nregs; reg++) { + tmp = gen_load_and_replicate(s, addr, size); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0)); + tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1)); + tcg_temp_free_i32(tmp); + tcg_gen_addi_i32(addr, addr, 1 << size); + rd += stride; + } } + tcg_temp_free_i32(addr); stride = (1 << size) * nregs; } else { /* Single element. */ + int idx = (insn >> 4) & 0xf; pass = (insn >> 7) & 1; switch (size) { case 0: @@ -3965,6 +4156,40 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) abort(); } nregs = ((insn >> 8) & 3) + 1; + /* Catch the UNDEF cases. This is unavoidably a bit messy. */ + switch (nregs) { + case 1: + if (((idx & (1 << size)) != 0) || + (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) { + return 1; + } + break; + case 3: + if ((idx & 1) != 0) { + return 1; + } + /* fall through */ + case 2: + if (size == 2 && (idx & 2) != 0) { + return 1; + } + break; + case 4: + if ((size == 2) && ((idx & 3) == 3)) { + return 1; + } + break; + default: + abort(); + } + if ((rd + stride * (nregs - 1)) > 31) { + /* Attempts to write off the end of the register file + * are UNPREDICTABLE; we choose to UNDEF because otherwise + * the neon_load_reg() would write off the end of the array. + */ + return 1; + } + addr = tcg_temp_new_i32(); load_reg_var(s, addr, rn); for (reg = 0; reg < nregs; reg++) { if (load) { @@ -3984,7 +4209,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) if (size != 2) { tmp2 = neon_load_reg(rd, pass); gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } neon_store_reg(rd, pass, tmp); } else { /* Store */ @@ -4006,10 +4231,10 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) rd += stride; tcg_gen_addi_i32(addr, addr, 1 << size); } + tcg_temp_free_i32(addr); stride = nregs * (1 << size); } } - dead_tmp(addr); if (rm != 15) { TCGv base; @@ -4020,7 +4245,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) TCGv index; index = load_reg(s, rm); tcg_gen_add_i32(base, base, index); - dead_tmp(index); + tcg_temp_free_i32(index); } store_reg(s, rn, base); } @@ -4065,6 +4290,16 @@ static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src) } } +static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src) +{ + switch (size) { + case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break; + case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break; + case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break; + default: abort(); + } +} + static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift, int q, int u) { @@ -4085,8 +4320,8 @@ static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift, } else { if (u) { switch (size) { - case 1: gen_helper_neon_rshl_u16(var, var, shift); break; - case 2: gen_helper_neon_rshl_u32(var, var, shift); break; + case 1: gen_helper_neon_shl_u16(var, var, shift); break; + case 2: gen_helper_neon_shl_u32(var, var, shift); break; default: abort(); } } else { @@ -4116,7 +4351,7 @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u) default: abort(); } } - dead_tmp(src); + tcg_temp_free_i32(src); } static inline void gen_neon_addl(int size) @@ -4170,10 +4405,12 @@ static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u) case 4: tmp = gen_muls_i64_i32(a, b); tcg_gen_mov_i64(dest, tmp); + tcg_temp_free_i64(tmp); break; case 5: tmp = gen_mulu_i64_i32(a, b); tcg_gen_mov_i64(dest, tmp); + tcg_temp_free_i64(tmp); break; default: abort(); } @@ -4181,11 +4418,205 @@ static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u) /* gen_helper_neon_mull_[su]{8|16} do not free their parameters. Don't forget to clean them now. */ if (size < 2) { - dead_tmp(a); - dead_tmp(b); + tcg_temp_free_i32(a); + tcg_temp_free_i32(b); + } +} + +static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src) +{ + if (op) { + if (u) { + gen_neon_unarrow_sats(size, dest, src); + } else { + gen_neon_narrow(size, dest, src); + } + } else { + if (u) { + gen_neon_narrow_satu(size, dest, src); + } else { + gen_neon_narrow_sats(size, dest, src); + } } } +/* Symbolic constants for op fields for Neon 3-register same-length. + * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B + * table A7-9. + */ +#define NEON_3R_VHADD 0 +#define NEON_3R_VQADD 1 +#define NEON_3R_VRHADD 2 +#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */ +#define NEON_3R_VHSUB 4 +#define NEON_3R_VQSUB 5 +#define NEON_3R_VCGT 6 +#define NEON_3R_VCGE 7 +#define NEON_3R_VSHL 8 +#define NEON_3R_VQSHL 9 +#define NEON_3R_VRSHL 10 +#define NEON_3R_VQRSHL 11 +#define NEON_3R_VMAX 12 +#define NEON_3R_VMIN 13 +#define NEON_3R_VABD 14 +#define NEON_3R_VABA 15 +#define NEON_3R_VADD_VSUB 16 +#define NEON_3R_VTST_VCEQ 17 +#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */ +#define NEON_3R_VMUL 19 +#define NEON_3R_VPMAX 20 +#define NEON_3R_VPMIN 21 +#define NEON_3R_VQDMULH_VQRDMULH 22 +#define NEON_3R_VPADD 23 +#define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */ +#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */ +#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */ +#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */ +#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */ +#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */ +#define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */ + +static const uint8_t neon_3r_sizes[] = { + [NEON_3R_VHADD] = 0x7, + [NEON_3R_VQADD] = 0xf, + [NEON_3R_VRHADD] = 0x7, + [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */ + [NEON_3R_VHSUB] = 0x7, + [NEON_3R_VQSUB] = 0xf, + [NEON_3R_VCGT] = 0x7, + [NEON_3R_VCGE] = 0x7, + [NEON_3R_VSHL] = 0xf, + [NEON_3R_VQSHL] = 0xf, + [NEON_3R_VRSHL] = 0xf, + [NEON_3R_VQRSHL] = 0xf, + [NEON_3R_VMAX] = 0x7, + [NEON_3R_VMIN] = 0x7, + [NEON_3R_VABD] = 0x7, + [NEON_3R_VABA] = 0x7, + [NEON_3R_VADD_VSUB] = 0xf, + [NEON_3R_VTST_VCEQ] = 0x7, + [NEON_3R_VML] = 0x7, + [NEON_3R_VMUL] = 0x7, + [NEON_3R_VPMAX] = 0x7, + [NEON_3R_VPMIN] = 0x7, + [NEON_3R_VQDMULH_VQRDMULH] = 0x6, + [NEON_3R_VPADD] = 0x7, + [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */ + [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */ +}; + +/* Symbolic constants for op fields for Neon 2-register miscellaneous. + * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B + * table A7-13. + */ +#define NEON_2RM_VREV64 0 +#define NEON_2RM_VREV32 1 +#define NEON_2RM_VREV16 2 +#define NEON_2RM_VPADDL 4 +#define NEON_2RM_VPADDL_U 5 +#define NEON_2RM_VCLS 8 +#define NEON_2RM_VCLZ 9 +#define NEON_2RM_VCNT 10 +#define NEON_2RM_VMVN 11 +#define NEON_2RM_VPADAL 12 +#define NEON_2RM_VPADAL_U 13 +#define NEON_2RM_VQABS 14 +#define NEON_2RM_VQNEG 15 +#define NEON_2RM_VCGT0 16 +#define NEON_2RM_VCGE0 17 +#define NEON_2RM_VCEQ0 18 +#define NEON_2RM_VCLE0 19 +#define NEON_2RM_VCLT0 20 +#define NEON_2RM_VABS 22 +#define NEON_2RM_VNEG 23 +#define NEON_2RM_VCGT0_F 24 +#define NEON_2RM_VCGE0_F 25 +#define NEON_2RM_VCEQ0_F 26 +#define NEON_2RM_VCLE0_F 27 +#define NEON_2RM_VCLT0_F 28 +#define NEON_2RM_VABS_F 30 +#define NEON_2RM_VNEG_F 31 +#define NEON_2RM_VSWP 32 +#define NEON_2RM_VTRN 33 +#define NEON_2RM_VUZP 34 +#define NEON_2RM_VZIP 35 +#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */ +#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */ +#define NEON_2RM_VSHLL 38 +#define NEON_2RM_VCVT_F16_F32 44 +#define NEON_2RM_VCVT_F32_F16 46 +#define NEON_2RM_VRECPE 56 +#define NEON_2RM_VRSQRTE 57 +#define NEON_2RM_VRECPE_F 58 +#define NEON_2RM_VRSQRTE_F 59 +#define NEON_2RM_VCVT_FS 60 +#define NEON_2RM_VCVT_FU 61 +#define NEON_2RM_VCVT_SF 62 +#define NEON_2RM_VCVT_UF 63 + +static int neon_2rm_is_float_op(int op) +{ + /* Return true if this neon 2reg-misc op is float-to-float */ + return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F || + op >= NEON_2RM_VRECPE_F); +} + +/* Each entry in this array has bit n set if the insn allows + * size value n (otherwise it will UNDEF). Since unallocated + * op values will have no bits set they always UNDEF. + */ +static const uint8_t neon_2rm_sizes[] = { + [NEON_2RM_VREV64] = 0x7, + [NEON_2RM_VREV32] = 0x3, + [NEON_2RM_VREV16] = 0x1, + [NEON_2RM_VPADDL] = 0x7, + [NEON_2RM_VPADDL_U] = 0x7, + [NEON_2RM_VCLS] = 0x7, + [NEON_2RM_VCLZ] = 0x7, + [NEON_2RM_VCNT] = 0x1, + [NEON_2RM_VMVN] = 0x1, + [NEON_2RM_VPADAL] = 0x7, + [NEON_2RM_VPADAL_U] = 0x7, + [NEON_2RM_VQABS] = 0x7, + [NEON_2RM_VQNEG] = 0x7, + [NEON_2RM_VCGT0] = 0x7, + [NEON_2RM_VCGE0] = 0x7, + [NEON_2RM_VCEQ0] = 0x7, + [NEON_2RM_VCLE0] = 0x7, + [NEON_2RM_VCLT0] = 0x7, + [NEON_2RM_VABS] = 0x7, + [NEON_2RM_VNEG] = 0x7, + [NEON_2RM_VCGT0_F] = 0x4, + [NEON_2RM_VCGE0_F] = 0x4, + [NEON_2RM_VCEQ0_F] = 0x4, + [NEON_2RM_VCLE0_F] = 0x4, + [NEON_2RM_VCLT0_F] = 0x4, + [NEON_2RM_VABS_F] = 0x4, + [NEON_2RM_VNEG_F] = 0x4, + [NEON_2RM_VSWP] = 0x1, + [NEON_2RM_VTRN] = 0x7, + [NEON_2RM_VUZP] = 0x7, + [NEON_2RM_VZIP] = 0x7, + [NEON_2RM_VMOVN] = 0x7, + [NEON_2RM_VQMOVN] = 0x7, + [NEON_2RM_VSHLL] = 0x7, + [NEON_2RM_VCVT_F16_F32] = 0x2, + [NEON_2RM_VCVT_F32_F16] = 0x2, + [NEON_2RM_VRECPE] = 0x4, + [NEON_2RM_VRSQRTE] = 0x4, + [NEON_2RM_VRECPE_F] = 0x4, + [NEON_2RM_VRSQRTE_F] = 0x4, + [NEON_2RM_VCVT_FS] = 0x4, + [NEON_2RM_VCVT_FU] = 0x4, + [NEON_2RM_VCVT_SF] = 0x4, + [NEON_2RM_VCVT_UF] = 0x4, +}; + /* Translate a NEON data processing instruction. Return nonzero if the instruction is invalid. We process data in a mixture of 32-bit and 64-bit chunks. @@ -4202,7 +4633,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) int count; int pairwise; int u; - int n; uint32_t imm, mask; TCGv tmp, tmp2, tmp3, tmp4, tmp5; TCGv_i64 tmp64; @@ -4218,14 +4648,23 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) if ((insn & (1 << 23)) == 0) { /* Three register same length. */ op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1); - if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9 - || op == 10 || op == 11 || op == 16)) { - /* 64-bit element instructions. */ + /* Catch invalid op and bad size combinations: UNDEF */ + if ((neon_3r_sizes[op] & (1 << size)) == 0) { + return 1; + } + /* All insns of this form UNDEF for either this condition or the + * superset of cases "Q==1"; we catch the latter later. + */ + if (q && ((rd | rn | rm) & 1)) { + return 1; + } + if (size == 3 && op != NEON_3R_LOGIC) { + /* 64-bit element instructions. */ for (pass = 0; pass < (q ? 2 : 1); pass++) { neon_load_reg64(cpu_V0, rn + pass); neon_load_reg64(cpu_V1, rm + pass); switch (op) { - case 1: /* VQADD */ + case NEON_3R_VQADD: if (u) { gen_helper_neon_qadd_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1); @@ -4234,7 +4673,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) cpu_V0, cpu_V1); } break; - case 5: /* VQSUB */ + case NEON_3R_VQSUB: if (u) { gen_helper_neon_qsub_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1); @@ -4243,14 +4682,14 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) cpu_V0, cpu_V1); } break; - case 8: /* VSHL */ + case NEON_3R_VSHL: if (u) { gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0); } else { gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0); } break; - case 9: /* VQSHL */ + case NEON_3R_VQSHL: if (u) { gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V1, cpu_V0); @@ -4259,14 +4698,14 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) cpu_V1, cpu_V0); } break; - case 10: /* VRSHL */ + case NEON_3R_VRSHL: if (u) { gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0); } else { gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0); } break; - case 11: /* VQRSHL */ + case NEON_3R_VQRSHL: if (u) { gen_helper_neon_qrshl_u64(cpu_V0, cpu_env, cpu_V1, cpu_V0); @@ -4275,7 +4714,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) cpu_V1, cpu_V0); } break; - case 16: + case NEON_3R_VADD_VSUB: if (u) { tcg_gen_sub_i64(CPU_V001); } else { @@ -4289,50 +4728,81 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } return 0; } + pairwise = 0; switch (op) { - case 8: /* VSHL */ - case 9: /* VQSHL */ - case 10: /* VRSHL */ - case 11: /* VQRSHL */ + case NEON_3R_VSHL: + case NEON_3R_VQSHL: + case NEON_3R_VRSHL: + case NEON_3R_VQRSHL: { int rtmp; /* Shift instruction operands are reversed. */ rtmp = rn; rn = rm; rm = rtmp; - pairwise = 0; } break; - case 20: /* VPMAX */ - case 21: /* VPMIN */ - case 23: /* VPADD */ + case NEON_3R_VPADD: + if (u) { + return 1; + } + /* Fall through */ + case NEON_3R_VPMAX: + case NEON_3R_VPMIN: pairwise = 1; break; - case 26: /* VPADD (float) */ - pairwise = (u && size < 2); + case NEON_3R_FLOAT_ARITH: + pairwise = (u && size < 2); /* if VPADD (float) */ + break; + case NEON_3R_FLOAT_MINMAX: + pairwise = u; /* if VPMIN/VPMAX (float) */ + break; + case NEON_3R_FLOAT_CMP: + if (!u && size) { + /* no encoding for U=0 C=1x */ + return 1; + } + break; + case NEON_3R_FLOAT_ACMP: + if (!u) { + return 1; + } break; - case 30: /* VPMIN/VPMAX (float) */ - pairwise = u; + case NEON_3R_VRECPS_VRSQRTS: + if (u) { + return 1; + } + break; + case NEON_3R_VMUL: + if (u && (size != 0)) { + /* UNDEF on invalid size for polynomial subcase */ + return 1; + } + break; + case NEON_3R_VFM: + if (!arm_feature(env, ARM_FEATURE_VFP4) || u) { + return 1; + } break; default: - pairwise = 0; break; } + if (pairwise && q) { + /* All the pairwise insns UNDEF if Q is set */ + return 1; + } + for (pass = 0; pass < (q ? 4 : 2); pass++) { if (pairwise) { /* Pairwise. */ - if (q) - n = (pass & 1) * 2; - else - n = 0; - if (pass < q + 1) { - tmp = neon_load_reg(rn, n); - tmp2 = neon_load_reg(rn, n + 1); + if (pass < 1) { + tmp = neon_load_reg(rn, 0); + tmp2 = neon_load_reg(rn, 1); } else { - tmp = neon_load_reg(rm, n); - tmp2 = neon_load_reg(rm, n + 1); + tmp = neon_load_reg(rm, 0); + tmp2 = neon_load_reg(rm, 1); } } else { /* Elementwise. */ @@ -4340,16 +4810,16 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tmp2 = neon_load_reg(rm, pass); } switch (op) { - case 0: /* VHADD */ + case NEON_3R_VHADD: GEN_NEON_INTEGER_OP(hadd); break; - case 1: /* VQADD */ + case NEON_3R_VQADD: GEN_NEON_INTEGER_OP_ENV(qadd); break; - case 2: /* VRHADD */ + case NEON_3R_VRHADD: GEN_NEON_INTEGER_OP(rhadd); break; - case 3: /* Logic ops. */ + case NEON_3R_LOGIC: /* Logic ops. */ switch ((u << 2) | size) { case 0: /* VAND */ tcg_gen_and_i32(tmp, tmp, tmp2); @@ -4369,97 +4839,96 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) case 5: /* VBSL */ tmp3 = neon_load_reg(rd, pass); gen_neon_bsl(tmp, tmp, tmp2, tmp3); - dead_tmp(tmp3); + tcg_temp_free_i32(tmp3); break; case 6: /* VBIT */ tmp3 = neon_load_reg(rd, pass); gen_neon_bsl(tmp, tmp, tmp3, tmp2); - dead_tmp(tmp3); + tcg_temp_free_i32(tmp3); break; case 7: /* VBIF */ tmp3 = neon_load_reg(rd, pass); gen_neon_bsl(tmp, tmp3, tmp, tmp2); - dead_tmp(tmp3); + tcg_temp_free_i32(tmp3); break; } break; - case 4: /* VHSUB */ + case NEON_3R_VHSUB: GEN_NEON_INTEGER_OP(hsub); break; - case 5: /* VQSUB */ + case NEON_3R_VQSUB: GEN_NEON_INTEGER_OP_ENV(qsub); break; - case 6: /* VCGT */ + case NEON_3R_VCGT: GEN_NEON_INTEGER_OP(cgt); break; - case 7: /* VCGE */ + case NEON_3R_VCGE: GEN_NEON_INTEGER_OP(cge); break; - case 8: /* VSHL */ + case NEON_3R_VSHL: GEN_NEON_INTEGER_OP(shl); break; - case 9: /* VQSHL */ + case NEON_3R_VQSHL: GEN_NEON_INTEGER_OP_ENV(qshl); break; - case 10: /* VRSHL */ + case NEON_3R_VRSHL: GEN_NEON_INTEGER_OP(rshl); break; - case 11: /* VQRSHL */ + case NEON_3R_VQRSHL: GEN_NEON_INTEGER_OP_ENV(qrshl); break; - case 12: /* VMAX */ + case NEON_3R_VMAX: GEN_NEON_INTEGER_OP(max); break; - case 13: /* VMIN */ + case NEON_3R_VMIN: GEN_NEON_INTEGER_OP(min); break; - case 14: /* VABD */ + case NEON_3R_VABD: GEN_NEON_INTEGER_OP(abd); break; - case 15: /* VABA */ + case NEON_3R_VABA: GEN_NEON_INTEGER_OP(abd); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tmp2 = neon_load_reg(rd, pass); gen_neon_add(size, tmp, tmp2); break; - case 16: + case NEON_3R_VADD_VSUB: if (!u) { /* VADD */ - if (gen_neon_add(size, tmp, tmp2)) - return 1; + gen_neon_add(size, tmp, tmp2); } else { /* VSUB */ switch (size) { case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } } break; - case 17: + case NEON_3R_VTST_VCEQ: if (!u) { /* VTST */ switch (size) { case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } } else { /* VCEQ */ switch (size) { case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } } break; - case 18: /* Multiply. */ + case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */ switch (size) { case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tmp2 = neon_load_reg(rd, pass); if (u) { /* VMLS */ gen_neon_rsb(size, tmp, tmp2); @@ -4467,7 +4936,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_neon_add(size, tmp, tmp2); } break; - case 19: /* VMUL */ + case NEON_3R_VMUL: if (u) { /* polynomial */ gen_helper_neon_mul_p8(tmp, tmp, tmp2); } else { /* Integer */ @@ -4475,105 +4944,144 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } } break; - case 20: /* VPMAX */ + case NEON_3R_VPMAX: GEN_NEON_INTEGER_OP(pmax); break; - case 21: /* VPMIN */ + case NEON_3R_VPMIN: GEN_NEON_INTEGER_OP(pmin); break; - case 22: /* Hultiply high. */ + case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */ if (!u) { /* VQDMULH */ switch (size) { - case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break; - case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break; - default: return 1; + case 1: + gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); + break; + default: abort(); } - } else { /* VQRDHMUL */ + } else { /* VQRDMULH */ switch (size) { - case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break; - case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break; - default: return 1; + case 1: + gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); + break; + case 2: + gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); + break; + default: abort(); } } break; - case 23: /* VPADD */ - if (u) - return 1; + case NEON_3R_VPADD: switch (size) { case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } break; - case 26: /* Floating point arithnetic. */ + case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */ + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); switch ((u << 2) | size) { case 0: /* VADD */ - gen_helper_neon_add_f32(tmp, tmp, tmp2); + case 4: /* VPADD */ + gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); break; case 2: /* VSUB */ - gen_helper_neon_sub_f32(tmp, tmp, tmp2); - break; - case 4: /* VPADD */ - gen_helper_neon_add_f32(tmp, tmp, tmp2); + gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus); break; case 6: /* VABD */ - gen_helper_neon_abd_f32(tmp, tmp, tmp2); + gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus); break; default: - return 1; + abort(); } + tcg_temp_free_ptr(fpstatus); break; - case 27: /* Float multiply. */ - gen_helper_neon_mul_f32(tmp, tmp, tmp2); + } + case NEON_3R_FLOAT_MULTIPLY: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus); if (!u) { - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tmp2 = neon_load_reg(rd, pass); if (size == 0) { - gen_helper_neon_add_f32(tmp, tmp, tmp2); + gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); } else { - gen_helper_neon_sub_f32(tmp, tmp2, tmp); + gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus); } } + tcg_temp_free_ptr(fpstatus); break; - case 28: /* Float compare. */ + } + case NEON_3R_FLOAT_CMP: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); if (!u) { - gen_helper_neon_ceq_f32(tmp, tmp, tmp2); + gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus); } else { - if (size == 0) - gen_helper_neon_cge_f32(tmp, tmp, tmp2); - else - gen_helper_neon_cgt_f32(tmp, tmp, tmp2); + if (size == 0) { + gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus); + } } + tcg_temp_free_ptr(fpstatus); break; - case 29: /* Float compare absolute. */ - if (!u) - return 1; - if (size == 0) - gen_helper_neon_acge_f32(tmp, tmp, tmp2); - else - gen_helper_neon_acgt_f32(tmp, tmp, tmp2); + } + case NEON_3R_FLOAT_ACMP: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + if (size == 0) { + gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus); + } + tcg_temp_free_ptr(fpstatus); break; - case 30: /* Float min/max. */ - if (size == 0) - gen_helper_neon_max_f32(tmp, tmp, tmp2); - else - gen_helper_neon_min_f32(tmp, tmp, tmp2); + } + case NEON_3R_FLOAT_MINMAX: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + if (size == 0) { + gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus); + } else { + gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus); + } + tcg_temp_free_ptr(fpstatus); break; - case 31: + } + case NEON_3R_VRECPS_VRSQRTS: if (size == 0) gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env); else gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env); break; + case NEON_3R_VFM: + { + /* VFMA, VFMS: fused multiply-add */ + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + TCGv_i32 tmp3 = neon_load_reg(rd, pass); + if (size) { + /* VFMS */ + gen_helper_vfp_negs(tmp, tmp); + } + gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus); + tcg_temp_free_i32(tmp3); + tcg_temp_free_ptr(fpstatus); + break; + } default: abort(); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); /* Save the result. For elementwise operations we can put it straight into the destination register. For pairwise operations @@ -4597,7 +5105,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) /* Two registers and shift. */ op = (insn >> 8) & 0xf; if (insn & (1 << 7)) { - /* 64-bit shift. */ + /* 64-bit shift. */ + if (op > 7) { + return 1; + } size = 3; } else { size = 2; @@ -4610,6 +5121,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) if (op < 8) { /* Shift by immediate: VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */ + if (q && ((rd | rm) & 1)) { + return 1; + } + if (!u && (op == 4 || op == 6)) { + return 1; + } /* Right shifts are encoded as N - shift, where N is the element size in bits. */ if (op <= 4) @@ -4657,20 +5174,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1); break; case 4: /* VSRI */ - if (!u) - return 1; - gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); - break; case 5: /* VSHL, VSLI */ gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1); break; case 6: /* VQSHLU */ - if (u) { - gen_helper_neon_qshlu_s64(cpu_V0, cpu_env, - cpu_V0, cpu_V1); - } else { - return 1; - } + gen_helper_neon_qshlu_s64(cpu_V0, cpu_env, + cpu_V0, cpu_V1); break; case 7: /* VQSHL */ if (u) { @@ -4688,13 +5197,25 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1); } else if (op == 4 || (op == 5 && u)) { /* Insert */ - cpu_abort(env, "VS[LR]I.64 not implemented"); + neon_load_reg64(cpu_V1, rd + pass); + uint64_t mask; + if (shift < -63 || shift > 63) { + mask = 0; + } else { + if (op == 4) { + mask = 0xffffffffffffffffull >> -shift; + } else { + mask = 0xffffffffffffffffull << shift; + } + } + tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask); + tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1); } neon_store_reg64(cpu_V0, rd + pass); } else { /* size < 3 */ /* Operands in T0 and T1. */ tmp = neon_load_reg(rm, pass); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, imm); switch (op) { case 0: /* VSHR */ @@ -4706,22 +5227,15 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) GEN_NEON_INTEGER_OP(rshl); break; case 4: /* VSRI */ - if (!u) - return 1; - GEN_NEON_INTEGER_OP(shl); - break; case 5: /* VSHL, VSLI */ switch (size) { case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } break; case 6: /* VQSHLU */ - if (!u) { - return 1; - } switch (size) { case 0: gen_helper_neon_qshlu_s8(tmp, cpu_env, @@ -4736,20 +5250,20 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tmp, tmp2); break; default: - return 1; + abort(); } break; case 7: /* VQSHL */ GEN_NEON_INTEGER_OP_ENV(qshl); break; } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (op == 1 || op == 3) { /* Accumulate. */ tmp2 = neon_load_reg(rd, pass); gen_neon_add(size, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } else if (op == 4 || (op == 5 && u)) { /* Insert */ switch (size) { @@ -4785,7 +5299,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_gen_andi_i32(tmp, tmp, mask); tcg_gen_andi_i32(tmp2, tmp2, ~mask); tcg_gen_or_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } neon_store_reg(rd, pass, tmp); } @@ -4793,71 +5307,81 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } else if (op < 10) { /* Shift by immediate and narrow: VSHRN, VRSHRN, VQSHRN, VQRSHRN. */ + int input_unsigned = (op == 8) ? !u : u; + if (rm & 1) { + return 1; + } shift = shift - (1 << (size + 3)); size++; - switch (size) { - case 1: - imm = (uint16_t)shift; - imm |= imm << 16; - tmp2 = tcg_const_i32(imm); - TCGV_UNUSED_I64(tmp64); - break; - case 2: - imm = (uint32_t)shift; - tmp2 = tcg_const_i32(imm); - TCGV_UNUSED_I64(tmp64); - break; - case 3: + if (size == 3) { tmp64 = tcg_const_i64(shift); - TCGV_UNUSED(tmp2); - break; - default: - abort(); - } - - for (pass = 0; pass < 2; pass++) { - if (size == 3) { - neon_load_reg64(cpu_V0, rm + pass); + neon_load_reg64(cpu_V0, rm); + neon_load_reg64(cpu_V1, rm + 1); + for (pass = 0; pass < 2; pass++) { + TCGv_i64 in; + if (pass == 0) { + in = cpu_V0; + } else { + in = cpu_V1; + } if (q) { - if (u) - gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64); - else - gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64); + if (input_unsigned) { + gen_helper_neon_rshl_u64(cpu_V0, in, tmp64); + } else { + gen_helper_neon_rshl_s64(cpu_V0, in, tmp64); + } } else { - if (u) - gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64); - else - gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64); + if (input_unsigned) { + gen_helper_neon_shl_u64(cpu_V0, in, tmp64); + } else { + gen_helper_neon_shl_s64(cpu_V0, in, tmp64); + } } - } else { - tmp = neon_load_reg(rm + pass, 0); - gen_neon_shift_narrow(size, tmp, tmp2, q, u); - tmp3 = neon_load_reg(rm + pass, 1); - gen_neon_shift_narrow(size, tmp3, tmp2, q, u); - tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); - dead_tmp(tmp); - dead_tmp(tmp3); - } - tmp = new_tmp(); - if (op == 8 && !u) { - gen_neon_narrow(size - 1, tmp, cpu_V0); - } else { - if (op == 8) - gen_neon_narrow_sats(size - 1, tmp, cpu_V0); - else - gen_neon_narrow_satu(size - 1, tmp, cpu_V0); - } - neon_store_reg(rd, pass, tmp); - } /* for pass */ - if (size == 3) { + tmp = tcg_temp_new_i32(); + gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); + neon_store_reg(rd, pass, tmp); + } /* for pass */ tcg_temp_free_i64(tmp64); } else { + if (size == 1) { + imm = (uint16_t)shift; + imm |= imm << 16; + } else { + /* size == 2 */ + imm = (uint32_t)shift; + } + tmp2 = tcg_const_i32(imm); + tmp4 = neon_load_reg(rm + 1, 0); + tmp5 = neon_load_reg(rm + 1, 1); + for (pass = 0; pass < 2; pass++) { + if (pass == 0) { + tmp = neon_load_reg(rm, 0); + } else { + tmp = tmp4; + } + gen_neon_shift_narrow(size, tmp, tmp2, q, + input_unsigned); + if (pass == 0) { + tmp3 = neon_load_reg(rm, 1); + } else { + tmp3 = tmp5; + } + gen_neon_shift_narrow(size, tmp3, tmp2, q, + input_unsigned); + tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp3); + tmp = tcg_temp_new_i32(); + gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0); + neon_store_reg(rd, pass, tmp); + } /* for pass */ tcg_temp_free_i32(tmp2); } } else if (op == 10) { - /* VSHLL */ - if (q || size == 3) + /* VSHLL, VMOVL */ + if (q || (rd & 1)) { return 1; + } tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); for (pass = 0; pass < 2; pass++) { @@ -4870,22 +5394,37 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) /* The shift is less than the width of the source type, so we can just shift the whole register. */ tcg_gen_shli_i64(cpu_V0, cpu_V0, shift); + /* Widen the result of shift: we need to clear + * the potential overflow bits resulting from + * left bits of the narrow input appearing as + * right bits of left the neighbour narrow + * input. */ if (size < 2 || !u) { uint64_t imm64; if (size == 0) { imm = (0xffu >> (8 - shift)); imm |= imm << 16; - } else { + } else if (size == 1) { imm = 0xffff >> (16 - shift); + } else { + /* size == 2 */ + imm = 0xffffffff >> (32 - shift); + } + if (size < 2) { + imm64 = imm | (((uint64_t)imm) << 32); + } else { + imm64 = imm; } - imm64 = imm | (((uint64_t)imm) << 32); - tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64); + tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64); } } neon_store_reg64(cpu_V0, rd + pass); } } else if (op >= 14) { /* VCVT fixed-point. */ + if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) { + return 1; + } /* We have already masked out the must-be-1 top bit of imm6, * hence this 32-shift where the ARM ARM has 64-imm6. */ @@ -4894,14 +5433,14 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); if (!(op & 1)) { if (u) - gen_vfp_ulto(0, shift); + gen_vfp_ulto(0, shift, 1); else - gen_vfp_slto(0, shift); + gen_vfp_slto(0, shift, 1); } else { if (u) - gen_vfp_toul(0, shift); + gen_vfp_toul(0, shift, 1); else - gen_vfp_tosl(0, shift); + gen_vfp_tosl(0, shift, 1); } tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); } @@ -4910,11 +5449,18 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } } else { /* (insn & 0x00380080) == 0 */ int invert; + if (q && (rd & 1)) { + return 1; + } op = (insn >> 8) & 0xf; /* One register and immediate. */ imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf); invert = (insn & (1 << 5)) != 0; + /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE. + * We choose to not special-case this and will behave as if a + * valid constant encoding of 0 had been given. + */ switch (op) { case 0: case 1: /* no-op */ @@ -4946,6 +5492,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) imm = ~imm; break; case 15: + if (invert) { + return 1; + } imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19) | ((imm & 0x40) ? (0x1f << 25) : (1 << 30)); break; @@ -4965,8 +5514,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } } else { /* VMOV, VMVN. */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (op == 14 && invert) { + int n; uint32_t val; val = 0; for (n = 0; n < 4; n++) { @@ -4989,31 +5539,47 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) int src1_wide; int src2_wide; int prewiden; - /* prewiden, src1_wide, src2_wide */ - static const int neon_3reg_wide[16][3] = { - {1, 0, 0}, /* VADDL */ - {1, 1, 0}, /* VADDW */ - {1, 0, 0}, /* VSUBL */ - {1, 1, 0}, /* VSUBW */ - {0, 1, 1}, /* VADDHN */ - {0, 0, 0}, /* VABAL */ - {0, 1, 1}, /* VSUBHN */ - {0, 0, 0}, /* VABDL */ - {0, 0, 0}, /* VMLAL */ - {0, 0, 0}, /* VQDMLAL */ - {0, 0, 0}, /* VMLSL */ - {0, 0, 0}, /* VQDMLSL */ - {0, 0, 0}, /* Integer VMULL */ - {0, 0, 0}, /* VQDMULL */ - {0, 0, 0} /* Polynomial VMULL */ + /* undefreq: bit 0 : UNDEF if size != 0 + * bit 1 : UNDEF if size == 0 + * bit 2 : UNDEF if U == 1 + * Note that [1:0] set implies 'always UNDEF' + */ + int undefreq; + /* prewiden, src1_wide, src2_wide, undefreq */ + static const int neon_3reg_wide[16][4] = { + {1, 0, 0, 0}, /* VADDL */ + {1, 1, 0, 0}, /* VADDW */ + {1, 0, 0, 0}, /* VSUBL */ + {1, 1, 0, 0}, /* VSUBW */ + {0, 1, 1, 0}, /* VADDHN */ + {0, 0, 0, 0}, /* VABAL */ + {0, 1, 1, 0}, /* VSUBHN */ + {0, 0, 0, 0}, /* VABDL */ + {0, 0, 0, 0}, /* VMLAL */ + {0, 0, 0, 6}, /* VQDMLAL */ + {0, 0, 0, 0}, /* VMLSL */ + {0, 0, 0, 6}, /* VQDMLSL */ + {0, 0, 0, 0}, /* Integer VMULL */ + {0, 0, 0, 2}, /* VQDMULL */ + {0, 0, 0, 5}, /* Polynomial VMULL */ + {0, 0, 0, 3}, /* Reserved: always UNDEF */ }; prewiden = neon_3reg_wide[op][0]; src1_wide = neon_3reg_wide[op][1]; src2_wide = neon_3reg_wide[op][2]; + undefreq = neon_3reg_wide[op][3]; - if (size == 0 && (op == 9 || op == 11 || op == 13)) + if (((undefreq & 1) && (size != 0)) || + ((undefreq & 2) && (size == 0)) || + ((undefreq & 4) && u)) { return 1; + } + if ((src1_wide && (rn & 1)) || + (src2_wide && (rm & 1)) || + (!src2_wide && (rd & 1))) { + return 1; + } /* Avoid overlapping operands. Wide source operands are always aligned so will never overlap with wide @@ -5082,48 +5648,49 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) break; default: abort(); } - dead_tmp(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); break; case 8: case 9: case 10: case 11: case 12: case 13: /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */ gen_neon_mull(cpu_V0, tmp, tmp2, size, u); break; case 14: /* Polynomial VMULL */ - cpu_abort(env, "Polynomial VMULL not implemented"); - - default: /* 15 is RESERVED. */ - return 1; + gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + break; + default: /* 15 is RESERVED: caught earlier */ + abort(); } - if (op == 5 || op == 13 || (op >= 8 && op <= 11)) { + if (op == 13) { + /* VQDMULL */ + gen_neon_addl_saturate(cpu_V0, cpu_V0, size); + neon_store_reg64(cpu_V0, rd + pass); + } else if (op == 5 || (op >= 8 && op <= 11)) { /* Accumulate. */ - if (op == 10 || op == 11) { - gen_neon_negl(cpu_V0, size); - } - - if (op != 13) { - neon_load_reg64(cpu_V1, rd + pass); - } - + neon_load_reg64(cpu_V1, rd + pass); switch (op) { - case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */ + case 10: /* VMLSL */ + gen_neon_negl(cpu_V0, size); + /* Fall through */ + case 5: case 8: /* VABAL, VMLAL */ gen_neon_addl(size); break; case 9: case 11: /* VQDMLAL, VQDMLSL */ gen_neon_addl_saturate(cpu_V0, cpu_V0, size); + if (op == 11) { + gen_neon_negl(cpu_V0, size); + } gen_neon_addl_saturate(cpu_V0, cpu_V1, size); break; - /* Fall through. */ - case 13: /* VQDMULL */ - gen_neon_addl_saturate(cpu_V0, cpu_V0, size); - break; default: abort(); } neon_store_reg64(cpu_V0, rd + pass); } else if (op == 4 || op == 6) { /* Narrowing operation. */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (!u) { switch (size) { case 0: @@ -5166,16 +5733,29 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } } } else { - /* Two registers and a scalar. */ + /* Two registers and a scalar. NB that for ops of this form + * the ARM ARM labels bit 24 as Q, but it is in our variable + * 'u', not 'q'. + */ + if (size == 0) { + return 1; + } switch (op) { - case 0: /* Integer VMLA scalar */ case 1: /* Float VMLA scalar */ - case 4: /* Integer VMLS scalar */ case 5: /* Floating point VMLS scalar */ - case 8: /* Integer VMUL scalar */ case 9: /* Floating point VMUL scalar */ + if (size == 1) { + return 1; + } + /* fall through */ + case 0: /* Integer VMLA scalar */ + case 4: /* Integer VMLS scalar */ + case 8: /* Integer VMUL scalar */ case 12: /* VQDMULH scalar */ case 13: /* VQRDMULH scalar */ + if (u && ((rd | rn) & 1)) { + return 1; + } tmp = neon_get_scalar(size, rm); neon_store_scratch(0, tmp); for (pass = 0; pass < (u ? 4 : 2); pass++) { @@ -5194,16 +5774,18 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); } } else if (op & 1) { - gen_helper_neon_mul_f32(tmp, tmp, tmp2); + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus); + tcg_temp_free_ptr(fpstatus); } else { switch (size) { case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break; case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (op < 8) { /* Accumulate. */ tmp2 = neon_load_reg(rd, pass); @@ -5212,35 +5794,47 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_neon_add(size, tmp, tmp2); break; case 1: - gen_helper_neon_add_f32(tmp, tmp, tmp2); + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus); + tcg_temp_free_ptr(fpstatus); break; + } case 4: gen_neon_rsb(size, tmp, tmp2); break; case 5: - gen_helper_neon_sub_f32(tmp, tmp2, tmp); + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus); + tcg_temp_free_ptr(fpstatus); break; + } default: abort(); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } neon_store_reg(rd, pass, tmp); } - break; + break; + case 3: /* VQDMLAL scalar */ + case 7: /* VQDMLSL scalar */ + case 11: /* VQDMULL scalar */ + if (u == 1) { + return 1; + } + /* fall through */ case 2: /* VMLAL sclar */ - case 3: /* VQDMLAL scalar */ case 6: /* VMLSL scalar */ - case 7: /* VQDMLSL scalar */ case 10: /* VMULL scalar */ - case 11: /* VQDMULL scalar */ - if (size == 0 && (op == 3 || op == 7 || op == 11)) + if (rd & 1) { return 1; - + } tmp2 = neon_get_scalar(size, rm); /* We need a copy of tmp2 because gen_neon_mull * deletes it during pass 0. */ - tmp4 = new_tmp(); + tmp4 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp4, tmp2); tmp3 = neon_load_reg(rn, 1); @@ -5252,18 +5846,21 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tmp2 = tmp4; } gen_neon_mull(cpu_V0, tmp, tmp2, size, u); - if (op == 6 || op == 7) { - gen_neon_negl(cpu_V0, size); - } if (op != 11) { neon_load_reg64(cpu_V1, rd + pass); } switch (op) { - case 2: case 6: + case 6: + gen_neon_negl(cpu_V0, size); + /* Fall through */ + case 2: gen_neon_addl(size); break; case 3: case 7: gen_neon_addl_saturate(cpu_V0, cpu_V0, size); + if (op == 7) { + gen_neon_negl(cpu_V0, size); + } gen_neon_addl_saturate(cpu_V0, cpu_V1, size); break; case 10: @@ -5292,6 +5889,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) if (imm > 7 && !q) return 1; + if (q && ((rd | rn | rm) & 1)) { + return 1; + } + if (imm == 0) { neon_load_reg64(cpu_V0, rn); if (q) { @@ -5340,10 +5941,16 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) /* Two register misc. */ op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf); size = (insn >> 18) & 3; + /* UNDEF for unknown op values and bad op-size combinations */ + if ((neon_2rm_sizes[op] & (1 << size)) == 0) { + return 1; + } + if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) && + q && ((rm | rd) & 1)) { + return 1; + } switch (op) { - case 0: /* VREV64 */ - if (size == 3) - return 1; + case NEON_2RM_VREV64: for (pass = 0; pass < (q ? 2 : 1); pass++) { tmp = neon_load_reg(rm, pass * 2); tmp2 = neon_load_reg(rm, pass * 2 + 1); @@ -5366,10 +5973,8 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } } break; - case 4: case 5: /* VPADDL */ - case 12: case 13: /* VPADAL */ - if (size == 3) - return 1; + case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U: + case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U: for (pass = 0; pass < q + 1; pass++) { tmp = neon_load_reg(rm, pass * 2); gen_neon_widen(cpu_V0, tmp, size, op & 1); @@ -5381,7 +5986,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) case 2: tcg_gen_add_i64(CPU_V001); break; default: abort(); } - if (op >= 12) { + if (op >= NEON_2RM_VPADAL) { /* Accumulate. */ neon_load_reg64(cpu_V1, rd + pass); gen_neon_addl(size); @@ -5389,8 +5994,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) neon_store_reg64(cpu_V0, rd + pass); } break; - case 33: /* VTRN */ + case NEON_2RM_VTRN: if (size == 2) { + int n; for (n = 0; n < (q ? 4 : 2); n += 2) { tmp = neon_load_reg(rm, n); tmp2 = neon_load_reg(rd, n + 1); @@ -5401,73 +6007,27 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) goto elementwise; } break; - case 34: /* VUZP */ - /* Reg Before After - Rd A3 A2 A1 A0 B2 B0 A2 A0 - Rm B3 B2 B1 B0 B3 B1 A3 A1 - */ - if (size == 3) + case NEON_2RM_VUZP: + if (gen_neon_unzip(rd, rm, size, q)) { return 1; - gen_neon_unzip(rd, q, 0, size); - gen_neon_unzip(rm, q, 4, size); - if (q) { - static int unzip_order_q[8] = - {0, 2, 4, 6, 1, 3, 5, 7}; - for (n = 0; n < 8; n++) { - int reg = (n < 4) ? rd : rm; - tmp = neon_load_scratch(unzip_order_q[n]); - neon_store_reg(reg, n % 4, tmp); - } - } else { - static int unzip_order[4] = - {0, 4, 1, 5}; - for (n = 0; n < 4; n++) { - int reg = (n < 2) ? rd : rm; - tmp = neon_load_scratch(unzip_order[n]); - neon_store_reg(reg, n % 2, tmp); - } } break; - case 35: /* VZIP */ - /* Reg Before After - Rd A3 A2 A1 A0 B1 A1 B0 A0 - Rm B3 B2 B1 B0 B3 A3 B2 A2 - */ - if (size == 3) + case NEON_2RM_VZIP: + if (gen_neon_zip(rd, rm, size, q)) { return 1; - count = (q ? 4 : 2); - for (n = 0; n < count; n++) { - tmp = neon_load_reg(rd, n); - tmp2 = neon_load_reg(rd, n); - switch (size) { - case 0: gen_neon_zip_u8(tmp, tmp2); break; - case 1: gen_neon_zip_u16(tmp, tmp2); break; - case 2: /* no-op */; break; - default: abort(); - } - neon_store_scratch(n * 2, tmp); - neon_store_scratch(n * 2 + 1, tmp2); - } - for (n = 0; n < count * 2; n++) { - int reg = (n < count) ? rd : rm; - tmp = neon_load_scratch(n); - neon_store_reg(reg, n % count, tmp); } break; - case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */ - if (size == 3) + case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN: + /* also VQMOVUN; op field and mnemonics don't line up */ + if (rm & 1) { return 1; + } TCGV_UNUSED(tmp2); for (pass = 0; pass < 2; pass++) { neon_load_reg64(cpu_V0, rm + pass); - tmp = new_tmp(); - if (op == 36 && q == 0) { - gen_neon_narrow(size, tmp, cpu_V0); - } else if (q) { - gen_neon_narrow_satu(size, tmp, cpu_V0); - } else { - gen_neon_narrow_sats(size, tmp, cpu_V0); - } + tmp = tcg_temp_new_i32(); + gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size, + tmp, cpu_V0); if (pass == 0) { tmp2 = tmp; } else { @@ -5476,9 +6036,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } } break; - case 38: /* VSHLL */ - if (q || size == 3) + case NEON_2RM_VSHLL: + if (q || (rd & 1)) { return 1; + } tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); for (pass = 0; pass < 2; pass++) { @@ -5489,54 +6050,58 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) neon_store_reg64(cpu_V0, rd + pass); } break; - case 44: /* VCVT.F16.F32 */ - if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) - return 1; - tmp = new_tmp(); - tmp2 = new_tmp(); + case NEON_2RM_VCVT_F16_F32: + if (!arm_feature(env, ARM_FEATURE_VFP_FP16) || + q || (rm & 1)) { + return 1; + } + tmp = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i32(); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0)); - gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); + gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1)); - gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); + gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); tcg_gen_shli_i32(tmp2, tmp2, 16); tcg_gen_or_i32(tmp2, tmp2, tmp); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2)); - gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); + gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3)); neon_store_reg(rd, 0, tmp2); - tmp2 = new_tmp(); - gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); + tmp2 = tcg_temp_new_i32(); + gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env); tcg_gen_shli_i32(tmp2, tmp2, 16); tcg_gen_or_i32(tmp2, tmp2, tmp); neon_store_reg(rd, 1, tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; - case 46: /* VCVT.F32.F16 */ - if (!arm_feature(env, ARM_FEATURE_VFP_FP16)) - return 1; - tmp3 = new_tmp(); + case NEON_2RM_VCVT_F32_F16: + if (!arm_feature(env, ARM_FEATURE_VFP_FP16) || + q || (rd & 1)) { + return 1; + } + tmp3 = tcg_temp_new_i32(); tmp = neon_load_reg(rm, 0); tmp2 = neon_load_reg(rm, 1); tcg_gen_ext16u_i32(tmp3, tmp); - gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0)); tcg_gen_shri_i32(tmp3, tmp, 16); - gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1)); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tcg_gen_ext16u_i32(tmp3, tmp2); - gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2)); tcg_gen_shri_i32(tmp3, tmp2, 16); - gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); + gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env); tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3)); - dead_tmp(tmp2); - dead_tmp(tmp3); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp3); break; default: elementwise: for (pass = 0; pass < (q ? 4 : 2); pass++) { - if (op == 30 || op == 31 || op >= 58) { + if (neon_2rm_is_float_op(op)) { tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass)); TCGV_UNUSED(tmp); @@ -5544,177 +6109,210 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tmp = neon_load_reg(rm, pass); } switch (op) { - case 1: /* VREV32 */ + case NEON_2RM_VREV32: switch (size) { case 0: tcg_gen_bswap32_i32(tmp, tmp); break; case 1: gen_swap_half(tmp); break; - default: return 1; + default: abort(); } break; - case 2: /* VREV16 */ - if (size != 0) - return 1; + case NEON_2RM_VREV16: gen_rev16(tmp); break; - case 8: /* CLS */ + case NEON_2RM_VCLS: switch (size) { case 0: gen_helper_neon_cls_s8(tmp, tmp); break; case 1: gen_helper_neon_cls_s16(tmp, tmp); break; case 2: gen_helper_neon_cls_s32(tmp, tmp); break; - default: return 1; + default: abort(); } break; - case 9: /* CLZ */ + case NEON_2RM_VCLZ: switch (size) { case 0: gen_helper_neon_clz_u8(tmp, tmp); break; case 1: gen_helper_neon_clz_u16(tmp, tmp); break; case 2: gen_helper_clz(tmp, tmp); break; - default: return 1; + default: abort(); } break; - case 10: /* CNT */ - if (size != 0) - return 1; + case NEON_2RM_VCNT: gen_helper_neon_cnt_u8(tmp, tmp); break; - case 11: /* VNOT */ - if (size != 0) - return 1; + case NEON_2RM_VMVN: tcg_gen_not_i32(tmp, tmp); break; - case 14: /* VQABS */ + case NEON_2RM_VQABS: switch (size) { - case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break; - case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break; - case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break; - default: return 1; + case 0: + gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); + break; + case 1: + gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); + break; + case 2: + gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); + break; + default: abort(); } break; - case 15: /* VQNEG */ + case NEON_2RM_VQNEG: switch (size) { - case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break; - case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break; - case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break; - default: return 1; + case 0: + gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); + break; + case 1: + gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); + break; + case 2: + gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); + break; + default: abort(); } break; - case 16: case 19: /* VCGT #0, VCLE #0 */ + case NEON_2RM_VCGT0: case NEON_2RM_VCLE0: tmp2 = tcg_const_i32(0); switch(size) { case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } tcg_temp_free(tmp2); - if (op == 19) + if (op == NEON_2RM_VCLE0) { tcg_gen_not_i32(tmp, tmp); + } break; - case 17: case 20: /* VCGE #0, VCLT #0 */ + case NEON_2RM_VCGE0: case NEON_2RM_VCLT0: tmp2 = tcg_const_i32(0); switch(size) { case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } tcg_temp_free(tmp2); - if (op == 20) + if (op == NEON_2RM_VCLT0) { tcg_gen_not_i32(tmp, tmp); + } break; - case 18: /* VCEQ #0 */ + case NEON_2RM_VCEQ0: tmp2 = tcg_const_i32(0); switch(size) { case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break; case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break; case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break; - default: return 1; + default: abort(); } tcg_temp_free(tmp2); break; - case 22: /* VABS */ + case NEON_2RM_VABS: switch(size) { case 0: gen_helper_neon_abs_s8(tmp, tmp); break; case 1: gen_helper_neon_abs_s16(tmp, tmp); break; case 2: tcg_gen_abs_i32(tmp, tmp); break; - default: return 1; + default: abort(); } break; - case 23: /* VNEG */ - if (size == 3) - return 1; + case NEON_2RM_VNEG: tmp2 = tcg_const_i32(0); gen_neon_rsb(size, tmp, tmp2); tcg_temp_free(tmp2); break; - case 24: case 27: /* Float VCGT #0, Float VCLE #0 */ + case NEON_2RM_VCGT0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); tmp2 = tcg_const_i32(0); - gen_helper_neon_cgt_f32(tmp, tmp, tmp2); + gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus); tcg_temp_free(tmp2); - if (op == 27) - tcg_gen_not_i32(tmp, tmp); + tcg_temp_free_ptr(fpstatus); break; - case 25: case 28: /* Float VCGE #0, Float VCLT #0 */ + } + case NEON_2RM_VCGE0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); tmp2 = tcg_const_i32(0); - gen_helper_neon_cge_f32(tmp, tmp, tmp2); + gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus); tcg_temp_free(tmp2); - if (op == 28) - tcg_gen_not_i32(tmp, tmp); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCEQ0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + tmp2 = tcg_const_i32(0); + gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus); + tcg_temp_free(tmp2); + tcg_temp_free_ptr(fpstatus); + break; + } + case NEON_2RM_VCLE0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); + tmp2 = tcg_const_i32(0); + gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus); + tcg_temp_free(tmp2); + tcg_temp_free_ptr(fpstatus); break; - case 26: /* Float VCEQ #0 */ + } + case NEON_2RM_VCLT0_F: + { + TCGv_ptr fpstatus = get_fpstatus_ptr(1); tmp2 = tcg_const_i32(0); - gen_helper_neon_ceq_f32(tmp, tmp, tmp2); + gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus); tcg_temp_free(tmp2); + tcg_temp_free_ptr(fpstatus); break; - case 30: /* Float VABS */ + } + case NEON_2RM_VABS_F: gen_vfp_abs(0); break; - case 31: /* Float VNEG */ + case NEON_2RM_VNEG_F: gen_vfp_neg(0); break; - case 32: /* VSWP */ + case NEON_2RM_VSWP: tmp2 = neon_load_reg(rd, pass); neon_store_reg(rm, pass, tmp2); break; - case 33: /* VTRN */ + case NEON_2RM_VTRN: tmp2 = neon_load_reg(rd, pass); switch (size) { case 0: gen_neon_trn_u8(tmp, tmp2); break; case 1: gen_neon_trn_u16(tmp, tmp2); break; - case 2: abort(); - default: return 1; + default: abort(); } neon_store_reg(rm, pass, tmp2); break; - case 56: /* Integer VRECPE */ + case NEON_2RM_VRECPE: gen_helper_recpe_u32(tmp, tmp, cpu_env); break; - case 57: /* Integer VRSQRTE */ + case NEON_2RM_VRSQRTE: gen_helper_rsqrte_u32(tmp, tmp, cpu_env); break; - case 58: /* Float VRECPE */ + case NEON_2RM_VRECPE_F: gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env); break; - case 59: /* Float VRSQRTE */ + case NEON_2RM_VRSQRTE_F: gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env); break; - case 60: /* VCVT.F32.S32 */ - gen_vfp_sito(0); + case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */ + gen_vfp_sito(0, 1); break; - case 61: /* VCVT.F32.U32 */ - gen_vfp_uito(0); + case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */ + gen_vfp_uito(0, 1); break; - case 62: /* VCVT.S32.F32 */ - gen_vfp_tosiz(0); + case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */ + gen_vfp_tosiz(0, 1); break; - case 63: /* VCVT.U32.F32 */ - gen_vfp_touiz(0); + case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */ + gen_vfp_touiz(0, 1); break; default: - /* Reserved: 21, 29, 39-56 */ - return 1; + /* Reserved op values were caught by the + * neon_2rm_sizes[] check earlier. + */ + abort(); } - if (op == 30 || op == 31 || op >= 58) { + if (neon_2rm_is_float_op(op)) { tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass)); } else { @@ -5725,22 +6323,29 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) } } else if ((insn & (1 << 10)) == 0) { /* VTBL, VTBX. */ - n = ((insn >> 5) & 0x18) + 8; + int n = ((insn >> 8) & 3) + 1; + if ((rn + n) > 32) { + /* This is UNPREDICTABLE; we choose to UNDEF to avoid the + * helper function running off the end of the register file. + */ + return 1; + } + n <<= 3; if (insn & (1 << 6)) { tmp = neon_load_reg(rd, 0); } else { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } tmp2 = neon_load_reg(rm, 0); tmp4 = tcg_const_i32(rn); tmp5 = tcg_const_i32(n); gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); if (insn & (1 << 6)) { tmp = neon_load_reg(rd, 1); } else { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } tmp3 = neon_load_reg(rm, 1); @@ -5749,9 +6354,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_temp_free_i32(tmp4); neon_store_reg(rd, 0, tmp2); neon_store_reg(rd, 1, tmp3); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else if ((insn & 0x380) == 0) { /* VDUP */ + if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) { + return 1; + } if (insn & (1 << 19)) { tmp = neon_load_reg(rm, 1); } else { @@ -5766,11 +6374,11 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_neon_dup_low16(tmp); } for (pass = 0; pass < (q ? 4 : 2); pass++) { - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_mov_i32(tmp2, tmp); neon_store_reg(rd, pass, tmp2); } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else { return 1; } @@ -5788,6 +6396,34 @@ static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn) int rt = (insn >> 12) & 0xf; TCGv tmp; + /* Minimal set of debug registers, since we don't support debug */ + if (op1 == 0 && crn == 0 && op2 == 0) { + switch (crm) { + case 0: + /* DBGDIDR: just RAZ. In particular this means the + * "debug architecture version" bits will read as + * a reserved value, which should cause Linux to + * not try to use the debug hardware. + */ + tmp = tcg_const_i32(0); + store_reg(s, rt, tmp); + return 0; + case 1: + case 2: + /* DBGDRAR and DBGDSAR: v7 only. Always RAZ since we + * don't implement memory mapped debug components + */ + if (ENABLE_ARCH_7) { + tmp = tcg_const_i32(0); + store_reg(s, rt, tmp); + return 0; + } + break; + default: + break; + } + } + if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) { /* TEECR */ @@ -5806,8 +6442,6 @@ static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn) return 0; } } - fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n", - op1, crn, crm, op2); return 1; } @@ -5827,7 +6461,7 @@ static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn) return 1; tmp = load_reg(s, rt); gen_helper_set_teecr(cpu_env, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); return 0; } if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) { @@ -5839,8 +6473,6 @@ static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn) return 0; } } - fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n", - op1, crn, crm, op2); return 1; } @@ -5888,10 +6520,10 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn) static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val) { TCGv tmp; - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, val); store_reg(s, rlow, tmp); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_shri_i64(val, val, 32); tcg_gen_trunc_i64_i32(tmp, val); store_reg(s, rhigh, tmp); @@ -5907,7 +6539,7 @@ static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow) tmp = tcg_temp_new_i64(); tmp2 = load_reg(s, rlow); tcg_gen_extu_i32_i64(tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_add_i64(val, val, tmp); tcg_temp_free_i64(tmp); } @@ -5924,8 +6556,8 @@ static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh) tmph = load_reg(s, rhigh); tmp = tcg_temp_new_i64(); tcg_gen_concat_i32_i64(tmp, tmpl, tmph); - dead_tmp(tmpl); - dead_tmp(tmph); + tcg_temp_free_i32(tmpl); + tcg_temp_free_i32(tmph); tcg_gen_add_i64(val, val, tmp); tcg_temp_free_i64(tmp); } @@ -5933,10 +6565,10 @@ static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh) /* Set N and Z flags from a 64-bit value. */ static void gen_logicq_cc(TCGv_i64 val) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); gen_helper_logicq_cc(tmp, val); gen_logic_CC(tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } /* Load/Store exclusive instructions are implemented by remembering @@ -5970,10 +6602,10 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2, tcg_gen_mov_i32(cpu_exclusive_val, tmp); store_reg(s, rt, tmp); if (size == 3) { - TCGv tmp2 = new_tmp(); + TCGv tmp2 = tcg_temp_new_i32(); tcg_gen_addi_i32(tmp2, addr, 4); tmp = gen_ld32(tmp2, IS_USER(s)); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_mov_i32(cpu_exclusive_high, tmp); store_reg(s, rt2, tmp); } @@ -6026,14 +6658,14 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, abort(); } tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); if (size == 3) { - TCGv tmp2 = new_tmp(); + TCGv tmp2 = tcg_temp_new_i32(); tcg_gen_addi_i32(tmp2, addr, 4); tmp = gen_ld32(tmp2, IS_USER(s)); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } tmp = load_reg(s, rt); switch (size) { @@ -6081,6 +6713,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) goto illegal_op; cond = insn >> 28; if (cond == 0xf){ + /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we + * choose to UNDEF. In ARMv5 and above the space is used + * for miscellaneous unconditional instructions. + */ + ARCH(5); + /* Unconditional instructions. */ if (((insn >> 25) & 7) == 1) { /* NEON Data processing. */ @@ -6100,9 +6738,32 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) goto illegal_op; return; } - if ((insn & 0x0d70f000) == 0x0550f000) - return; /* PLD */ - else if ((insn & 0x0ffffdff) == 0x01010000) { + if (((insn & 0x0f30f000) == 0x0510f000) || + ((insn & 0x0f30f010) == 0x0710f000)) { + if ((insn & (1 << 22)) == 0) { + /* PLDW; v7MP */ + if (!arm_feature(env, ARM_FEATURE_V7MP)) { + goto illegal_op; + } + } + /* Otherwise PLD; v5TE+ */ + ARCH(5TE); + return; + } + if (((insn & 0x0f70f000) == 0x0450f000) || + ((insn & 0x0f70f010) == 0x0650f000)) { + ARCH(7); + return; /* PLI; V7 */ + } + if (((insn & 0x0f700000) == 0x04100000) || + ((insn & 0x0f700010) == 0x06100000)) { + if (!arm_feature(env, ARM_FEATURE_V7MP)) { + goto illegal_op; + } + return; /* v7MP: Unallocated memory hint: must NOP */ + } + + if ((insn & 0x0ffffdff) == 0x01010000) { ARCH(6); /* setend */ if (insn & (1 << 9)) { @@ -6132,7 +6793,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) goto illegal_op; ARCH(6); op1 = (insn & 0x1f); - addr = new_tmp(); + addr = tcg_temp_new_i32(); tmp = tcg_const_i32(op1); gen_helper_get_r13_banked(addr, cpu_env, tmp); tcg_temp_free_i32(tmp); @@ -6165,9 +6826,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tmp = tcg_const_i32(op1); gen_helper_set_r13_banked(cpu_env, tmp, addr); tcg_temp_free_i32(tmp); - dead_tmp(addr); + tcg_temp_free_i32(addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } return; } else if ((insn & 0x0e50ffe0) == 0x08100a00) { @@ -6205,7 +6866,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tcg_gen_addi_i32(addr, addr, offset); store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } gen_rfe(s, tmp, tmp2); return; @@ -6214,7 +6875,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) int32_t offset; val = (uint32_t)s->pc; - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); store_reg(s, 14, tmp); /* Sign-extend the 24-bit offset */ @@ -6223,6 +6884,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) val += (offset << 2) | ((insn >> 23) & 2) | 1; /* pipeline offset */ val += 4; + /* protected by ARCH(5); above, near the start of uncond block */ gen_bx_im(s, val); return; } else if ((insn & 0x0e000f00) == 0x0c000100) { @@ -6234,6 +6896,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } } else if ((insn & 0x0fe00000) == 0x0c400000) { /* Coprocessor double register transfer. */ + ARCH(5TE); } else if ((insn & 0x0f000010) == 0x0e000010) { /* Additional coprocessor register transfer. */ } else if ((insn & 0x0ff10020) == 0x01000000) { @@ -6278,7 +6941,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) val = ((insn >> 4) & 0xf000) | (insn & 0xfff); if ((insn & (1 << 22)) == 0) { /* MOVW */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); } else { /* MOVT */ @@ -6325,7 +6988,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) goto illegal_op; tmp = load_cpu_field(spsr); } else { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); gen_helper_cpsr_read(tmp); } store_reg(s, rd, tmp); @@ -6334,10 +6997,12 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) case 0x1: if (op1 == 1) { /* branch/exchange thumb (bx). */ + ARCH(4T); tmp = load_reg(s, rm); gen_bx(s, tmp); } else if (op1 == 3) { /* clz */ + ARCH(5); rd = (insn >> 12) & 0xf; tmp = load_reg(s, rm); gen_helper_clz(tmp, tmp); @@ -6360,14 +7025,16 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) if (op1 != 1) goto illegal_op; + ARCH(5); /* branch link/exchange thumb (blx) */ tmp = load_reg(s, rm); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc); store_reg(s, 14, tmp2); gen_bx(s, tmp); break; case 0x5: /* saturating add/subtract */ + ARCH(5TE); rd = (insn >> 12) & 0xf; rn = (insn >> 16) & 0xf; tmp = load_reg(s, rm); @@ -6378,7 +7045,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) gen_helper_sub_saturate(tmp, tmp, tmp2); else gen_helper_add_saturate(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 7: @@ -6389,12 +7056,14 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) goto illegal_op; } /* bkpt */ + ARCH(5); gen_exception_insn(s, 4, EXCP_BKPT); break; case 0x8: /* signed multiply */ case 0xa: case 0xc: case 0xe: + ARCH(5TE); rs = (insn >> 8) & 0xf; rn = (insn >> 12) & 0xf; rd = (insn >> 16) & 0xf; @@ -6408,13 +7077,13 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) gen_sxth(tmp2); tmp64 = gen_muls_i64_i32(tmp, tmp2); tcg_gen_shri_i64(tmp64, tmp64, 16); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); if ((sh & 2) == 0) { tmp2 = load_reg(s, rn); gen_helper_add_setq(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); } else { @@ -6422,11 +7091,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); gen_mulxy(tmp, tmp2, sh & 2, sh & 4); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (op1 == 2) { tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rn, rd); gen_storeq_reg(s, rn, rd, tmp64); tcg_temp_free_i64(tmp64); @@ -6434,7 +7103,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) if (op1 == 0) { tmp2 = load_reg(s, rn); gen_helper_add_setq(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); } @@ -6460,7 +7129,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) if (shift) { val = (val >> shift) | (val << (32 - shift)); } - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, val); if (logic_cc && shift) { gen_set_CF_bit31(tmp2); @@ -6563,26 +7232,26 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tcg_gen_and_i32(tmp, tmp, tmp2); gen_logic_CC(tmp); } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; case 0x09: if (set_cc) { tcg_gen_xor_i32(tmp, tmp, tmp2); gen_logic_CC(tmp); } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; case 0x0a: if (set_cc) { gen_helper_sub_cc(tmp, tmp, tmp2); } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; case 0x0b: if (set_cc) { gen_helper_add_cc(tmp, tmp, tmp2); } - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; case 0x0c: tcg_gen_or_i32(tmp, tmp, tmp2); @@ -6622,7 +7291,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) break; } if (op1 != 0x0f && op1 != 0x0d) { - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } } else { /* other instructions */ @@ -6645,18 +7314,18 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tmp = load_reg(s, rs); tmp2 = load_reg(s, rm); tcg_gen_mul_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (insn & (1 << 22)) { /* Subtract (mls) */ ARCH(6T2); tmp2 = load_reg(s, rn); tcg_gen_sub_i32(tmp, tmp2, tmp); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } else if (insn & (1 << 21)) { /* Add */ tmp2 = load_reg(s, rn); tcg_gen_add_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } if (insn & (1 << 20)) gen_logic_CC(tmp); @@ -6760,7 +7429,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tmp2 = gen_ld32(addr, IS_USER(s)); gen_st32(tmp, addr, IS_USER(s)); } - dead_tmp(addr); + tcg_temp_free_i32(addr); store_reg(s, rd, tmp2); } } @@ -6790,6 +7459,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } load = 1; } else if (sh & 2) { + ARCH(5TE); /* doubleword */ if (sh & 1) { /* store */ @@ -6827,7 +7497,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tcg_gen_addi_i32(addr, addr, address_offset); store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } if (load) { /* Complete the load. */ @@ -6856,7 +7526,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) if ((op1 & 3) == 0 || sh == 5 || sh == 6) goto illegal_op; gen_arm_parallel_addsub(op1, sh, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 1: @@ -6880,7 +7550,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); } tcg_gen_or_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x00200020) == 0x00200000) { /* [us]sat */ @@ -6916,16 +7586,16 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) /* Select bytes. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); - tmp3 = new_tmp(); + tmp3 = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); - dead_tmp(tmp3); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp3); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x000003e0) == 0x00000060) { tmp = load_reg(s, rm); shift = (insn >> 10) & 3; - /* ??? In many cases it's not neccessary to do a + /* ??? In many cases it's not necessary to do a rotate, a shift is sufficient. */ if (shift != 0) tcg_gen_rotri_i32(tmp, tmp, shift * 8); @@ -6945,7 +7615,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) gen_add16(tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } } store_reg(s, rd, tmp); @@ -6971,11 +7641,16 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } break; case 2: /* Multiplies (Type 3). */ - tmp = load_reg(s, rm); - tmp2 = load_reg(s, rs); - if (insn & (1 << 20)) { + switch ((insn >> 20) & 0x7) { + case 5: + if (((insn >> 6) ^ (insn >> 7)) & 1) { + /* op2 not 00x or 11x : UNDEF */ + goto illegal_op; + } /* Signed multiply most significant [accumulate]. (SMMUL, SMMLA, SMMLS) */ + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); tmp64 = gen_muls_i64_i32(tmp, tmp2); if (rd != 15) { @@ -6990,26 +7665,38 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); } tcg_gen_shri_i64(tmp64, tmp64, 32); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); store_reg(s, rn, tmp); - } else { + break; + case 0: + case 4: + /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */ + if (insn & (1 << 7)) { + goto illegal_op; + } + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); if (insn & (1 << 5)) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); - /* This addition cannot overflow. */ if (insn & (1 << 6)) { + /* This subtraction cannot overflow. */ tcg_gen_sub_i32(tmp, tmp, tmp2); } else { - tcg_gen_add_i32(tmp, tmp, tmp2); + /* This addition cannot overflow 32 bits; + * however it may overflow considered as a signed + * operation, in which case we must set the Q flag. + */ + gen_helper_add_setq(tmp, tmp, tmp2); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (insn & (1 << 22)) { /* smlald, smlsld */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rd, rn); gen_storeq_reg(s, rd, rn, tmp64); tcg_temp_free_i64(tmp64); @@ -7019,10 +7706,32 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) { tmp2 = load_reg(s, rd); gen_helper_add_setq(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } store_reg(s, rn, tmp); } + break; + case 1: + case 3: + /* SDIV, UDIV */ + if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) { + goto illegal_op; + } + if (((insn >> 5) & 7) || (rd != 15)) { + goto illegal_op; + } + tmp = load_reg(s, rm); + tmp2 = load_reg(s, rs); + if (insn & (1 << 21)) { + gen_helper_udiv(tmp, tmp, tmp2); + } else { + gen_helper_sdiv(tmp, tmp, tmp2); + } + tcg_temp_free_i32(tmp2); + store_reg(s, rn, tmp); + break; + default: + goto illegal_op; } break; case 3: @@ -7033,11 +7742,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); gen_helper_usad8(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (rd != 15) { tmp2 = load_reg(s, rd); tcg_gen_add_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } store_reg(s, rn, tmp); break; @@ -7048,7 +7757,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) i = (insn >> 16) & 0x1f; i = i + 1 - shift; if (rm == 15) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rm); @@ -7056,7 +7765,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) if (i != 32) { tmp2 = load_reg(s, rd); gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); break; @@ -7122,14 +7831,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } else if (insn & (1 << 21)) { store_reg(s, rn, tmp2); } else { - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } if (insn & (1 << 20)) { /* Complete the load. */ - if (rd == 15) - gen_bx(s, tmp); - else - store_reg(s, rd, tmp); + store_reg_from_load(env, s, rd, tmp); } break; case 0x08: @@ -7182,28 +7888,26 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) if (insn & (1 << 20)) { /* load */ tmp = gen_ld32(addr, IS_USER(s)); - if (i == 15) { - gen_bx(s, tmp); - } else if (user) { + if (user) { tmp2 = tcg_const_i32(i); gen_helper_set_user_reg(tmp2, tmp); tcg_temp_free_i32(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else if (i == rn) { loaded_var = tmp; loaded_base = 1; } else { - store_reg(s, i, tmp); + store_reg_from_load(env, s, i, tmp); } } else { /* store */ if (i == 15) { /* special case: r15 = PC + 8 */ val = (long)s->pc + 4; - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); } else if (user) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tmp2 = tcg_const_i32(i); gen_helper_get_user_reg(tmp, tmp2); tcg_temp_free_i32(tmp2); @@ -7239,7 +7943,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } if (loaded_base) { store_reg(s, rn, loaded_var); @@ -7248,7 +7952,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) /* Restore CPSR from SPSR. */ tmp = load_cpu_field(spsr); gen_set_cpsr(tmp, 0xffffffff); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); s->is_jmp = DISAS_UPDATE; } } @@ -7261,7 +7965,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) /* branch (and link) */ val = (int32_t)s->pc; if (insn & (1 << 24)) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); store_reg(s, 14, tmp); } @@ -7323,8 +8027,7 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG logic_cc = conds; break; case 3: /* orn */ - tcg_gen_not_i32(t1, t1); - tcg_gen_or_i32(t0, t0, t1); + tcg_gen_orc_i32(t0, t0, t1); logic_cc = conds; break; case 4: /* eor */ @@ -7394,13 +8097,14 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) 16-bit instructions to get correct prefetch abort behavior. */ insn = insn_hw1; if ((insn & (1 << 12)) == 0) { + ARCH(5); /* Second half of blx. */ offset = ((insn & 0x7ff) << 1); tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); @@ -7412,7 +8116,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); @@ -7451,7 +8155,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) if (insn & 0x01200000) { /* Load/store doubleword. */ if (rn == 15) { - addr = new_tmp(); + addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc & ~3); } else { addr = load_reg(s, rn); @@ -7485,7 +8189,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tcg_gen_addi_i32(addr, addr, offset - 4); store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } } else if ((insn & (1 << 23)) == 0) { /* Load/store exclusive word. */ @@ -7501,7 +8205,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) } else if ((insn & (1 << 6)) == 0) { /* Table Branch. */ if (rn == 15) { - addr = new_tmp(); + addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, s->pc); } else { addr = load_reg(s, rn); @@ -7511,13 +8215,13 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) if (insn & (1 << 4)) { /* tbh */ tcg_gen_add_i32(addr, addr, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tmp = gen_ld16u(addr, IS_USER(s)); } else { /* tbb */ - dead_tmp(tmp); + tcg_temp_free_i32(tmp); tmp = gen_ld8u(addr, IS_USER(s)); } - dead_tmp(addr); + tcg_temp_free_i32(addr); tcg_gen_shli_i32(tmp, tmp, 1); tcg_gen_addi_i32(tmp, tmp, s->pc); store_reg(s, 15, tmp); @@ -7561,13 +8265,13 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) } store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } gen_rfe(s, tmp, tmp2); } else { /* srs */ op = (insn & 0x1f); - addr = new_tmp(); + addr = tcg_temp_new_i32(); tmp = tcg_const_i32(op); gen_helper_get_r13_banked(addr, cpu_env, tmp); tcg_temp_free_i32(tmp); @@ -7577,7 +8281,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tmp = load_reg(s, 14); gen_st32(tmp, addr, 0); tcg_gen_addi_i32(addr, addr, 4); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); gen_helper_cpsr_read(tmp); gen_st32(tmp, addr, 0); if (insn & (1 << 21)) { @@ -7590,11 +8294,12 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) gen_helper_set_r13_banked(cpu_env, tmp, addr); tcg_temp_free_i32(tmp); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } } } else { - int i; + int i, loaded_base = 0; + TCGv loaded_var; /* Load/store multiple. */ addr = load_reg(s, rn); offset = 0; @@ -7606,6 +8311,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tcg_gen_addi_i32(addr, addr, -offset); } + TCGV_UNUSED(loaded_var); for (i = 0; i < 16; i++) { if ((insn & (1 << i)) == 0) continue; @@ -7614,6 +8320,9 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tmp = gen_ld32(addr, IS_USER(s)); if (i == 15) { gen_bx(s, tmp); + } else if (i == rn) { + loaded_var = tmp; + loaded_base = 1; } else { store_reg(s, i, tmp); } @@ -7624,6 +8333,9 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) } tcg_gen_addi_i32(addr, addr, 4); } + if (loaded_base) { + store_reg(s, rn, loaded_var); + } if (insn & (1 << 21)) { /* Base register writeback. */ if (insn & (1 << 24)) { @@ -7634,7 +8346,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) goto illegal_op; store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } } } @@ -7662,12 +8374,12 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); } tcg_gen_or_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else { /* Data processing register constant shift. */ if (rn == 15) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); @@ -7681,11 +8393,11 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) goto illegal_op; - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (rd != 15) { store_reg(s, rd, tmp); } else { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } } break; @@ -7709,7 +8421,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) case 1: /* Sign/zero extend. */ tmp = load_reg(s, rm); shift = (insn >> 4) & 3; - /* ??? In many cases it's not neccessary to do a + /* ??? In many cases it's not necessary to do a rotate, a shift is sufficient. */ if (shift != 0) tcg_gen_rotri_i32(tmp, tmp, shift * 8); @@ -7729,7 +8441,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) gen_add16(tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } } store_reg(s, rd, tmp); @@ -7742,7 +8454,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); gen_thumb2_parallel_addsub(op, shift, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 3: /* Other data processing. */ @@ -7757,7 +8469,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) gen_helper_sub_saturate(tmp, tmp2, tmp); else gen_helper_add_saturate(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } else { tmp = load_reg(s, rn); switch (op) { @@ -7775,11 +8487,11 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) break; case 0x10: /* sel */ tmp2 = load_reg(s, rm); - tmp3 = new_tmp(); + tmp3 = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); - dead_tmp(tmp3); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp3); + tcg_temp_free_i32(tmp2); break; case 0x18: /* clz */ gen_helper_clz(tmp, tmp); @@ -7797,23 +8509,23 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) switch ((insn >> 20) & 7) { case 0: /* 32 x 32 -> 32 */ tcg_gen_mul_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); if (op) tcg_gen_sub_i32(tmp, tmp2, tmp); else tcg_gen_add_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } break; case 1: /* 16 x 16 -> 32 */ gen_mulxy(tmp, tmp2, op & 2, op & 1); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } break; case 2: /* Dual multiply add. */ @@ -7821,18 +8533,22 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) if (op) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); - /* This addition cannot overflow. */ if (insn & (1 << 22)) { + /* This subtraction cannot overflow. */ tcg_gen_sub_i32(tmp, tmp, tmp2); } else { - tcg_gen_add_i32(tmp, tmp, tmp2); + /* This addition cannot overflow 32 bits; + * however it may overflow considered as a signed + * operation, in which case we must set the Q flag. + */ + gen_helper_add_setq(tmp, tmp, tmp2); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } break; case 3: /* 32 * 16 -> 32msb */ @@ -7842,14 +8558,14 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) gen_sxth(tmp2); tmp64 = gen_muls_i64_i32(tmp, tmp2); tcg_gen_shri_i64(tmp64, tmp64, 16); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } break; case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ @@ -7866,17 +8582,17 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); } tcg_gen_shri_i64(tmp64, tmp64, 32); - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); break; case 7: /* Unsigned sum of absolute differences. */ gen_helper_usad8(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); tcg_gen_add_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } break; } @@ -7888,13 +8604,14 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tmp2 = load_reg(s, rm); if ((op & 0x50) == 0x10) { /* sdiv, udiv */ - if (!arm_feature(env, ARM_FEATURE_DIV)) + if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) { goto illegal_op; + } if (op & 0x20) gen_helper_udiv(tmp, tmp, tmp2); else gen_helper_sdiv(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((op & 0xe) == 0xc) { /* Dual multiply accumulate long. */ @@ -7906,11 +8623,11 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) } else { tcg_gen_add_i32(tmp, tmp, tmp2); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); /* BUGFIX */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rs, rd); gen_storeq_reg(s, rs, rd, tmp64); tcg_temp_free_i64(tmp64); @@ -7922,10 +8639,10 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) if (op & 8) { /* smlalxy */ gen_mulxy(tmp, tmp2, op & 2, op & 1); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else { /* Signed 64-bit multiply */ tmp64 = gen_muls_i64_i32(tmp, tmp2); @@ -7949,7 +8666,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) /* Coprocessor. */ if (((insn >> 24) & 3) == 3) { /* Translate into the equivalent ARM encoding. */ - insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4); + insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28); if (disas_neon_data_insn(env, s, insn)) goto illegal_op; } else { @@ -7986,6 +8703,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) } else { /* blx */ offset &= ~(uint32_t)2; + /* thumb2 bx, no need to check */ gen_bx_im(s, offset); } } else if (((insn >> 23) & 7) == 7) { @@ -8005,7 +8723,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_msr(cpu_env, addr, tmp); tcg_temp_free_i32(addr); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); gen_lookup_tb(s); break; } @@ -8079,7 +8797,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) gen_exception_return(s, tmp); break; case 6: /* mrs cpsr. */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); if (IS_M(env)) { addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_mrs(tmp, cpu_env, addr); @@ -8131,7 +8849,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) imm = insn & 0x1f; shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); if (rn == 15) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); @@ -8158,7 +8876,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) if (imm != 32) { tmp2 = load_reg(s, rd); gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } break; case 7: @@ -8201,7 +8919,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) tcg_gen_ori_i32(tmp, tmp, imm << 16); } else { /* movw */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, imm); } } else { @@ -8212,7 +8930,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) offset -= imm; else offset += imm; - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, offset); } else { tmp = load_reg(s, rn); @@ -8251,11 +8969,11 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) shifter_out = 1; break; } - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, imm); rn = (insn >> 16) & 0xf; if (rn == 15) { - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); @@ -8264,12 +8982,12 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, shifter_out, tmp, tmp2)) goto illegal_op; - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); rd = (insn >> 8) & 0xf; if (rd != 15) { store_reg(s, rd, tmp); } else { - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } } } @@ -8284,9 +9002,45 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) goto illegal_op; break; } + op = ((insn >> 21) & 3) | ((insn >> 22) & 4); + if (rs == 15) { + if (!(insn & (1 << 20))) { + goto illegal_op; + } + if (op != 2) { + /* Byte or halfword load space with dest == r15 : memory hints. + * Catch them early so we don't emit pointless addressing code. + * This space is a mix of: + * PLD/PLDW/PLI, which we implement as NOPs (note that unlike + * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP + * cores) + * unallocated hints, which must be treated as NOPs + * UNPREDICTABLE space, which we NOP or UNDEF depending on + * which is easiest for the decoding logic + * Some space which must UNDEF + */ + int op1 = (insn >> 23) & 3; + int op2 = (insn >> 6) & 0x3f; + if (op & 2) { + goto illegal_op; + } + if (rn == 15) { + /* UNPREDICTABLE or unallocated hint */ + return 0; + } + if (op1 & 1) { + return 0; /* PLD* or unallocated hint */ + } + if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) { + return 0; /* PLD* or unallocated hint */ + } + /* UNDEF space, or an UNPREDICTABLE */ + return 1; + } + } user = IS_USER(s); if (rn == 15) { - addr = new_tmp(); + addr = tcg_temp_new_i32(); /* PC relative. */ /* s->pc has already been incremented by 4. */ imm = s->pc & 0xfffffffc; @@ -8302,77 +9056,74 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) imm = insn & 0xfff; tcg_gen_addi_i32(addr, addr, imm); } else { - op = (insn >> 8) & 7; imm = insn & 0xff; - switch (op) { - case 0: case 8: /* Shifted Register. */ + switch ((insn >> 8) & 0xf) { + case 0x0: /* Shifted Register. */ shift = (insn >> 4) & 0xf; - if (shift > 3) + if (shift > 3) { + tcg_temp_free_i32(addr); goto illegal_op; + } tmp = load_reg(s, rm); if (shift) tcg_gen_shli_i32(tmp, tmp, shift); tcg_gen_add_i32(addr, addr, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); break; - case 4: /* Negative offset. */ + case 0xc: /* Negative offset. */ tcg_gen_addi_i32(addr, addr, -imm); break; - case 6: /* User privilege. */ + case 0xe: /* User privilege. */ tcg_gen_addi_i32(addr, addr, imm); user = 1; break; - case 1: /* Post-decrement. */ + case 0x9: /* Post-decrement. */ imm = -imm; /* Fall through. */ - case 3: /* Post-increment. */ + case 0xb: /* Post-increment. */ postinc = 1; writeback = 1; break; - case 5: /* Pre-decrement. */ + case 0xd: /* Pre-decrement. */ imm = -imm; /* Fall through. */ - case 7: /* Pre-increment. */ + case 0xf: /* Pre-increment. */ tcg_gen_addi_i32(addr, addr, imm); writeback = 1; break; default: + tcg_temp_free_i32(addr); goto illegal_op; } } } - op = ((insn >> 21) & 3) | ((insn >> 22) & 4); if (insn & (1 << 20)) { /* Load. */ - if (rs == 15 && op != 2) { - if (op & 2) - goto illegal_op; - /* Memory hint. Implemented as NOP. */ + switch (op) { + case 0: tmp = gen_ld8u(addr, user); break; + case 4: tmp = gen_ld8s(addr, user); break; + case 1: tmp = gen_ld16u(addr, user); break; + case 5: tmp = gen_ld16s(addr, user); break; + case 2: tmp = gen_ld32(addr, user); break; + default: + tcg_temp_free_i32(addr); + goto illegal_op; + } + if (rs == 15) { + gen_bx(s, tmp); } else { - switch (op) { - case 0: tmp = gen_ld8u(addr, user); break; - case 4: tmp = gen_ld8s(addr, user); break; - case 1: tmp = gen_ld16u(addr, user); break; - case 5: tmp = gen_ld16s(addr, user); break; - case 2: tmp = gen_ld32(addr, user); break; - default: goto illegal_op; - } - if (rs == 15) { - gen_bx(s, tmp); - } else { - store_reg(s, rs, tmp); - } + store_reg(s, rs, tmp); } } else { /* Store. */ - if (rs == 15) - goto illegal_op; tmp = load_reg(s, rs); switch (op) { case 0: gen_st8(tmp, addr, user); break; case 1: gen_st16(tmp, addr, user); break; case 2: gen_st32(tmp, addr, user); break; - default: goto illegal_op; + default: + tcg_temp_free_i32(addr); + goto illegal_op; } } if (postinc) @@ -8380,7 +9131,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) if (writeback) { store_reg(s, rn, addr); } else { - dead_tmp(addr); + tcg_temp_free_i32(addr); } } break; @@ -8424,7 +9175,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tmp = load_reg(s, rn); if (insn & (1 << 10)) { /* immediate */ - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, (insn >> 6) & 7); } else { /* reg */ @@ -8442,7 +9193,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) else gen_helper_add_cc(tmp, tmp, tmp2); } - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else { /* shift immediate */ @@ -8460,27 +9211,27 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) op = (insn >> 11) & 3; rd = (insn >> 8) & 0x7; if (op == 0) { /* mov */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, insn & 0xff); if (!s->condexec_mask) gen_logic_CC(tmp); store_reg(s, rd, tmp); } else { tmp = load_reg(s, rd); - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, insn & 0xff); switch (op) { case 1: /* cmp */ gen_helper_sub_cc(tmp, tmp, tmp2); - dead_tmp(tmp); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); break; case 2: /* add */ if (s->condexec_mask) tcg_gen_add_i32(tmp, tmp, tmp2); else gen_helper_add_cc(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 3: /* sub */ @@ -8488,7 +9239,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tcg_gen_sub_i32(tmp, tmp, tmp2); else gen_helper_sub_cc(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; } @@ -8500,10 +9251,10 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) /* load pc-relative. Bit 1 of PC is ignored. */ val = s->pc + 2 + ((insn & 0xff) * 4); val &= ~(uint32_t)2; - addr = new_tmp(); + addr = tcg_temp_new_i32(); tcg_gen_movi_i32(addr, val); tmp = gen_ld32(addr, IS_USER(s)); - dead_tmp(addr); + tcg_temp_free_i32(addr); store_reg(s, rd, tmp); break; } @@ -8517,15 +9268,15 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tmp = load_reg(s, rd); tmp2 = load_reg(s, rm); tcg_gen_add_i32(tmp, tmp, tmp2); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 1: /* cmp */ tmp = load_reg(s, rd); tmp2 = load_reg(s, rm); gen_helper_sub_cc(tmp, tmp, tmp2); - dead_tmp(tmp2); - dead_tmp(tmp); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); break; case 2: /* mov/cpy */ tmp = load_reg(s, rm); @@ -8534,11 +9285,13 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) case 3:/* branch [and link] exchange thumb register */ tmp = load_reg(s, rm); if (insn & (1 << 7)) { + ARCH(5); val = (uint32_t)s->pc | 1; - tmp2 = new_tmp(); + tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, val); store_reg(s, 14, tmp2); } + /* already thumb, no need to check */ gen_bx(s, tmp); break; } @@ -8560,7 +9313,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) } if (op == 9) { /* neg */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else if (op != 0xf) { /* mvn doesn't read its first operand */ tmp = load_reg(s, rd); @@ -8671,14 +9424,14 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) if (val) { store_reg(s, rm, tmp2); if (op != 0xf) - dead_tmp(tmp); + tcg_temp_free_i32(tmp); } else { store_reg(s, rd, tmp); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp2); } } else { - dead_tmp(tmp); - dead_tmp(tmp2); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); } break; @@ -8691,7 +9444,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) addr = load_reg(s, rn); tmp = load_reg(s, rm); tcg_gen_add_i32(addr, addr, tmp); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); if (op < 3) /* store */ tmp = load_reg(s, rd); @@ -8724,7 +9477,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) } if (op >= 3) /* load */ store_reg(s, rd, tmp); - dead_tmp(addr); + tcg_temp_free_i32(addr); break; case 6: @@ -8744,7 +9497,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tmp = load_reg(s, rd); gen_st32(tmp, addr, IS_USER(s)); } - dead_tmp(addr); + tcg_temp_free_i32(addr); break; case 7: @@ -8764,7 +9517,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tmp = load_reg(s, rd); gen_st8(tmp, addr, IS_USER(s)); } - dead_tmp(addr); + tcg_temp_free_i32(addr); break; case 8: @@ -8784,7 +9537,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tmp = load_reg(s, rd); gen_st16(tmp, addr, IS_USER(s)); } - dead_tmp(addr); + tcg_temp_free_i32(addr); break; case 9: @@ -8803,7 +9556,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tmp = load_reg(s, rd); gen_st32(tmp, addr, IS_USER(s)); } - dead_tmp(addr); + tcg_temp_free_i32(addr); break; case 10: @@ -8814,7 +9567,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tmp = load_reg(s, 13); } else { /* PC. bit 1 is ignored. */ - tmp = new_tmp(); + tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2); } val = (insn & 0xff) * 4; @@ -8898,8 +9651,9 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) /* write back the new stack pointer */ store_reg(s, 13, addr); /* set the new PC value */ - if ((insn & 0x0900) == 0x0900) - gen_bx(s, tmp); + if ((insn & 0x0900) == 0x0900) { + store_reg_from_load(env, s, 15, tmp); + } break; case 1: case 3: case 9: case 11: /* czb */ @@ -8911,7 +9665,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel); else tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel); - dead_tmp(tmp); + tcg_temp_free_i32(tmp); offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3; val = (uint32_t)s->pc + 2; val += offset; @@ -8930,6 +9684,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) break; case 0xe: /* bkpt */ + ARCH(5); gen_exception_insn(s, 2, EXCP_BKPT); break; @@ -8982,7 +9737,10 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) break; case 12: + { /* load/store multiple */ + TCGv loaded_var; + TCGV_UNUSED(loaded_var); rn = (insn >> 8) & 0x7; addr = load_reg(s, rn); for (i = 0; i < 8; i++) { @@ -8990,7 +9748,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) if (insn & (1 << 11)) { /* load */ tmp = gen_ld32(addr, IS_USER(s)); - store_reg(s, i, tmp); + if (i == rn) { + loaded_var = tmp; + } else { + store_reg(s, i, tmp); + } } else { /* store */ tmp = load_reg(s, i); @@ -9000,14 +9762,18 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) tcg_gen_addi_i32(addr, addr, 4); } } - /* Base register writeback. */ if ((insn & (1 << rn)) == 0) { + /* base reg not in list: base register writeback */ store_reg(s, rn, addr); } else { - dead_tmp(addr); + /* base reg in list: if load, complete it now */ + if (insn & (1 << 11)) { + store_reg(s, rn, loaded_var); + } + tcg_temp_free_i32(addr); } break; - + } case 13: /* conditional branch or swi */ cond = (insn >> 8) & 0xf; @@ -9076,8 +9842,6 @@ static inline void gen_intermediate_code_internal(CPUState *env, int max_insns; /* generate intermediate code */ - num_temps = 0; - pc_start = tb->pc; dc->tb = tb; @@ -9114,6 +9878,8 @@ static inline void gen_intermediate_code_internal(CPUState *env, gen_icount_start(); + tcg_clear_temp_count(); + /* A note on handling of the condexec (IT) bits: * * We want to avoid the overhead of having to write the updated condexec @@ -9136,8 +9902,8 @@ static inline void gen_intermediate_code_internal(CPUState *env, * This is handled in the same way as restoration of the * PC in these situations: we will be called again with search_pc=1 * and generate a mapping of the condexec bits for each PC in - * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore - * the condexec bits. + * gen_opc_condexec_bits[]. restore_state_to_opc() then uses + * this to restore the condexec bits. * * Note that there are no instructions which can read the condexec * bits, and none which can write non-static values to them, so @@ -9149,7 +9915,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, complications trying to do it at the end of the block. */ if (dc->condexec_mask || dc->condexec_cond) { - TCGv tmp = new_tmp(); + TCGv tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); store_cpu_field(tmp, condexec_bits); } @@ -9218,15 +9984,16 @@ static inline void gen_intermediate_code_internal(CPUState *env, } else { disas_arm_insn(env, dc); } - if (num_temps) { - fprintf(stderr, "Internal resource leak before %08x\n", dc->pc); - num_temps = 0; - } if (dc->condjmp && !dc->is_jmp) { gen_set_label(dc->condlabel); dc->condjmp = 0; } + + if (tcg_check_temp_count()) { + fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc); + } + /* Translation stops when a conditional branch is encountered. * Otherwise the subsequent code could get translated several times. * Also stop translation when a page boundary is reached. This @@ -9401,8 +10168,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, #endif } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->regs[15] = gen_opc_pc[pc_pos]; env->condexec_bits = gen_opc_condexec_bits[pc_pos]; diff --git a/target-cris/cpu.h b/target-cris/cpu.h index d908775..453afbb 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -36,6 +36,9 @@ #define EXCP_IRQ 4 #define EXCP_BREAK 5 +/* CRIS-specific interrupt pending bits. */ +#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3 + /* Register aliases. R0 - R15 */ #define R_FP 8 #define R_SP 14 @@ -64,6 +67,8 @@ #define Q_FLAG 0x80000000 #define M_FLAG 0x40000000 #define PFIX_FLAG 0x800 /* CRISv10 Only. */ +#define F_FLAG_V10 0x400 +#define P_FLAG_V10 0x200 #define S_FLAG 0x200 #define R_FLAG 0x100 #define P_FLAG 0x80 @@ -101,7 +106,7 @@ typedef struct CPUCRISState { /* P0 - P15 are referred to as special registers in the docs. */ uint32_t pregs[16]; - /* Pseudo register for the PC. Not directly accessable on CRIS. */ + /* Pseudo register for the PC. Not directly accessible on CRIS. */ uint32_t pc; /* Pseudo register for the kernel stack. */ @@ -223,7 +228,7 @@ static inline int cpu_mmu_index (CPUState *env) } int cpu_cris_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault #if defined(CONFIG_USER_ONLY) @@ -265,4 +270,15 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, #define cpu_list cris_cpu_list void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf); +static inline bool cpu_has_work(CPUState *env) +{ + return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->pc = tb->pc; +} #endif diff --git a/target-cris/exec.h b/target-cris/exec.h deleted file mode 100644 index 93ce768..0000000 --- a/target-cris/exec.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * CRIS execution defines - * - * Copyright (c) 2007 AXIS Communications AB - * Written by Edgar E. Iglesias - * - * 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 - * 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, see . - */ -#include "dyngen-exec.h" - -register struct CPUCRISState *env asm(AREG0); - -#include "cpu.h" -#include "exec-all.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif - -static inline int cpu_has_work(CPUState *env) -{ - return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)); -} - -static inline int cpu_halted(CPUState *env) { - if (!env->halted) - return 0; - - /* IRQ, NMI and GURU execeptions wakes us up. */ - if (env->interrupt_request - & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - diff --git a/target-cris/helper.c b/target-cris/helper.c index 2a4403b..5bc6d81 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -24,7 +24,6 @@ #include "config.h" #include "cpu.h" #include "mmu.h" -#include "exec-all.h" #include "host-utils.h" @@ -48,7 +47,7 @@ void do_interrupt (CPUState *env) } int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = 0xaa; env->pregs[PR_EDA] = address; @@ -69,7 +68,7 @@ static void cris_shift_ccs(CPUState *env) } int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { struct cris_mmu_result res; int prot, miss; @@ -105,10 +104,9 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, r = 0; } if (r > 0) - D_LOG("%s returns %d irqreq=%x addr=%x" - " phy=%x ismmu=%d vec=%x pc=%x\n", - __func__, r, env->interrupt_request, - address, res.phy, is_softmmu, res.bf_vec, env->pc); + D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n", + __func__, r, env->interrupt_request, address, res.phy, + res.bf_vec, env->pc); return r; } @@ -159,6 +157,7 @@ static void do_interruptv10(CPUState *env) /* Now that we are in kernel mode, load the handlers address. */ env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4); env->locked_irq = 1; + env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */ qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", __func__, env->pc, ex_vec, diff --git a/target-cris/mmu.c b/target-cris/mmu.c index 1243745..d481e39 100644 --- a/target-cris/mmu.c +++ b/target-cris/mmu.c @@ -27,7 +27,6 @@ #include "config.h" #include "cpu.h" #include "mmu.h" -#include "exec-all.h" #ifdef DEBUG #define D(x) x diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c index be9eb06..1eacc5f 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c @@ -18,7 +18,8 @@ * License along with this library; if not, see . */ -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "mmu.h" #include "helper.h" #include "host-utils.h" @@ -35,6 +36,7 @@ #endif #if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" #define MMUSUFFIX _mmu @@ -54,21 +56,20 @@ NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { TranslationBlock *tb; CPUState *saved_env; unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; + env = env1; D_LOG("%s pc=%x tpc=%x ra=%x\n", __func__, env->pc, env->debug1, retaddr); - ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ @@ -77,13 +78,13 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); /* Evaluate flags after retranslation. */ helper_top_evaluate_flags(); } } - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } @@ -93,7 +94,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) void helper_raise_exception(uint32_t index) { env->exception_index = index; - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_tlb_flush_pid(uint32_t pid) diff --git a/target-cris/opcode-cris.h b/target-cris/opcode-cris.h index 8d4749d..779d4aa 100644 --- a/target-cris/opcode-cris.h +++ b/target-cris/opcode-cris.h @@ -29,8 +29,8 @@ along with this program; if not, see . */ /* Registers. */ #define MAX_REG (15) -#define REG_SP (14) -#define REG_PC (15) +#define CRIS_REG_SP (14) +#define CRIS_REG_PC (15) /* CPU version control of disassembly and assembly of instructions. May affect how the instruction is assembled, at least the size of @@ -138,7 +138,7 @@ extern const struct cris_cond15 cris_conds15[]; #define BDAP_INDIR_OPCODE (BDAP_INDIR_HIGH * 0x0100 + BDAP_INDIR_LOW) #define BDAP_INDIR_Z_BITS (BDAP_INDIR_HIGH_Z * 0x100 + BDAP_INDIR_LOW_Z) -#define BDAP_PC_LOW (BDAP_INDIR_LOW + REG_PC) +#define BDAP_PC_LOW (BDAP_INDIR_LOW + CRIS_REG_PC) #define BDAP_INCR_HIGH (BDAP_INDIR_HIGH + AUTOINCR_BIT) /* No prefix must have this code for its "match" bits in the @@ -192,16 +192,16 @@ extern const char *const cris_cc_strings[]; #define JUMP_INDIR_OPCODE (0x0930) #define JUMP_INDIR_Z_BITS (0xf2c0) #define JUMP_PC_INCR_OPCODE \ - (JUMP_INDIR_OPCODE + AUTOINCR_BIT * 0x0100 + REG_PC) + (JUMP_INDIR_OPCODE + AUTOINCR_BIT * 0x0100 + CRIS_REG_PC) #define MOVE_M_TO_PREG_OPCODE 0x0a30 #define MOVE_M_TO_PREG_ZBITS 0x01c0 /* BDAP.D N,PC. */ #define MOVE_PC_INCR_OPCODE_PREFIX \ - (((BDAP_INCR_HIGH | (REG_PC << 4)) << 8) | BDAP_PC_LOW | (2 << 4)) + (((BDAP_INCR_HIGH | (CRIS_REG_PC << 4)) << 8) | BDAP_PC_LOW | (2 << 4)) #define MOVE_PC_INCR_OPCODE_SUFFIX \ - (MOVE_M_TO_PREG_OPCODE | REG_PC | (AUTOINCR_BIT << 8)) + (MOVE_M_TO_PREG_OPCODE | CRIS_REG_PC | (AUTOINCR_BIT << 8)) #define JUMP_PC_INCR_OPCODE_V32 (0x0DBF) diff --git a/target-cris/translate.c b/target-cris/translate.c index b4648a0..70abf8a 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -30,7 +30,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "helper.h" @@ -596,7 +595,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(env_pc, dest); - tcg_gen_exit_tb((long)tb + n); + tcg_gen_exit_tb((tcg_target_long)tb + n); } else { tcg_gen_movi_tl(env_pc, dest); tcg_gen_exit_tb(0); @@ -3517,7 +3516,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) static int tcg_initialized = 0; int i; - env = qemu_mallocz(sizeof(CPUCRISState)); + env = g_malloc0(sizeof(CPUCRISState)); env->pregs[PR_VR] = vr_by_name(cpu_model); cpu_exec_init(env); @@ -3604,8 +3603,7 @@ void cpu_reset (CPUCRISState *env) #endif } -void gen_pc_load(CPUState *env, struct TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->pc = gen_opc_pc[pc_pos]; } diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c index 41db158..95053b6 100644 --- a/target-cris/translate_v10.c +++ b/target-cris/translate_v10.c @@ -62,6 +62,65 @@ static inline void cris_illegal_insn(DisasContext *dc) t_gen_raise_exception(EXCP_BREAK); } +static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val, + unsigned int size, int mem_index) +{ + int l1 = gen_new_label(); + TCGv taddr = tcg_temp_local_new(); + TCGv tval = tcg_temp_local_new(); + TCGv t1 = tcg_temp_local_new(); + dc->postinc = 0; + cris_evaluate_flags(dc); + + tcg_gen_mov_tl(taddr, addr); + tcg_gen_mov_tl(tval, val); + + /* Store only if F flag isn't set */ + tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + if (size == 1) { + tcg_gen_qemu_st8(tval, taddr, mem_index); + } else if (size == 2) { + tcg_gen_qemu_st16(tval, taddr, mem_index); + } else { + tcg_gen_qemu_st32(tval, taddr, mem_index); + } + gen_set_label(l1); + tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */ + tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/ + tcg_temp_free(t1); + tcg_temp_free(tval); + tcg_temp_free(taddr); +} + +static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val, + unsigned int size) +{ + int mem_index = cpu_mmu_index(dc->env); + + /* If we get a fault on a delayslot we must keep the jmp state in + the cpu-state to be able to re-execute the jmp. */ + if (dc->delayed_branch == 1) { + cris_store_direct_jmp(dc); + } + + /* Conditional writes. We only support the kind were X is known + at translation time. */ + if (dc->flagx_known && dc->flags_x) { + gen_store_v10_conditional(dc, addr, val, size, mem_index); + return; + } + + if (size == 1) { + tcg_gen_qemu_st8(val, addr, mem_index); + } else if (size == 2) { + tcg_gen_qemu_st16(val, addr, mem_index); + } else { + tcg_gen_qemu_st32(val, addr, mem_index); + } +} + + /* Prefix flag and register are used to handle the more complex addressing modes. */ static void cris_set_prefix(DisasContext *dc) @@ -262,9 +321,6 @@ static unsigned int dec10_quick_imm(DisasContext *dc) break; case CRISV10_QIMM_BCC_R0: - if (!dc->ir) { - cpu_abort(dc->env, "opcode zero\n"); - } case CRISV10_QIMM_BCC_R1: case CRISV10_QIMM_BCC_R2: case CRISV10_QIMM_BCC_R3: @@ -316,7 +372,8 @@ static unsigned int dec10_setclrf(DisasContext *dc) if (set) { tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags); } else { - tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags); + tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], + ~(flags|F_FLAG_V10|P_FLAG_V10)); } dc->flags_uptodate = 1; @@ -726,7 +783,7 @@ static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size) LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst); addr = tcg_temp_new(); crisv10_prepare_memaddr(dc, addr, size); - gen_store(dc, addr, cpu_R[dc->dst], size); + gen_store_v10(dc, addr, cpu_R[dc->dst], size); insn_len += crisv10_post_memaddr(dc, size); return insn_len; @@ -770,10 +827,10 @@ static unsigned int dec10_ind_move_pr_m(DisasContext *dc) t0 = tcg_temp_new(); cris_evaluate_flags(dc); tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG); - gen_store(dc, addr, t0, size); + gen_store_v10(dc, addr, t0, size); tcg_temp_free(t0); } else { - gen_store(dc, addr, cpu_PR[dc->dst], size); + gen_store_v10(dc, addr, cpu_PR[dc->dst], size); } t0 = tcg_temp_new(); insn_len += crisv10_post_memaddr(dc, size); @@ -796,9 +853,9 @@ static void dec10_movem_r_m(DisasContext *dc) tcg_gen_mov_tl(t0, addr); for (i = dc->dst; i >= 0; i--) { if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) { - gen_store(dc, addr, t0, 4); + gen_store_v10(dc, addr, t0, 4); } else { - gen_store(dc, addr, cpu_R[i], 4); + gen_store_v10(dc, addr, cpu_R[i], 4); } tcg_gen_addi_tl(addr, addr, 4); } @@ -956,7 +1013,7 @@ static int dec10_bdap_m(DisasContext *dc, int size) return insn_len; } #endif - /* Now the rest of the modes are truely indirect. */ + /* Now the rest of the modes are truly indirect. */ insn_len += dec10_prep_move_m(dc, 1, size, cpu_PR[PR_PREFIX]); tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]); cris_set_prefix(dc); diff --git a/target-i386/TODO b/target-i386/TODO index c8ada07..a8d69cf 100644 --- a/target-i386/TODO +++ b/target-i386/TODO @@ -15,7 +15,6 @@ Correctness issues: - DRx register support - CR0.AC emulation - SSE alignment checks -- fix SSE min/max with nans Optimizations/Features: diff --git a/target-i386/cpu.h b/target-i386/cpu.h index af701a4..a08ce9d 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -283,6 +283,7 @@ #define MSR_IA32_APICBASE_BSP (1<<8) #define MSR_IA32_APICBASE_ENABLE (1<<11) #define MSR_IA32_APICBASE_BASE (0xfffff<<12) +#define MSR_IA32_TSCDEADLINE 0x6e0 #define MSR_MTRRcap 0xfe #define MSR_MTRRcap_VCNT 8 @@ -299,6 +300,10 @@ #define MSR_IA32_PERF_STATUS 0x198 +#define MSR_IA32_MISC_ENABLE 0x1a0 +/* Indicates good rep/movs microcode on some processors: */ +#define MSR_IA32_MISC_ENABLE_DEFAULT 1 + #define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg)) #define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1) @@ -438,9 +443,13 @@ #define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */ #define CPUID_VENDOR_AMD_1 0x68747541 /* "Auth" */ -#define CPUID_VENDOR_AMD_2 0x69746e65 /* "enti" */ +#define CPUID_VENDOR_AMD_2 0x69746e65 /* "enti" */ #define CPUID_VENDOR_AMD_3 0x444d4163 /* "cAMD" */ +#define CPUID_VENDOR_VIA_1 0x746e6543 /* "Cent" */ +#define CPUID_VENDOR_VIA_2 0x48727561 /* "aurH" */ +#define CPUID_VENDOR_VIA_3 0x736c7561 /* "auls" */ + #define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */ #define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */ @@ -466,6 +475,15 @@ #define EXCP_SYSCALL 0x100 /* only happens in user only emulation for syscall instruction */ +/* i386-specific interrupt pending bits. */ +#define CPU_INTERRUPT_SMI CPU_INTERRUPT_TGT_EXT_2 +#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3 +#define CPU_INTERRUPT_MCE CPU_INTERRUPT_TGT_EXT_4 +#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_INT_0 +#define CPU_INTERRUPT_INIT CPU_INTERRUPT_TGT_INT_1 +#define CPU_INTERRUPT_SIPI CPU_INTERRUPT_TGT_INT_2 + + enum { CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */ CC_OP_EFLAGS, /* all cc are explicitly computed, CC_SRC = flags */ @@ -523,16 +541,6 @@ enum { CC_OP_NB, }; -#ifdef FLOATX80 -#define USE_X86LDOUBLE -#endif - -#ifdef USE_X86LDOUBLE -typedef floatx80 CPU86_LDouble; -#else -typedef float64 CPU86_LDouble; -#endif - typedef struct SegmentCache { uint32_t selector; target_ulong base; @@ -585,11 +593,7 @@ typedef union { #define MMX_Q(n) q typedef union { -#ifdef USE_X86LDOUBLE - CPU86_LDouble d __attribute__((aligned(16))); -#else - CPU86_LDouble d; -#endif + floatx80 d __attribute__((aligned(16))); MMXReg mmx; } FPReg; @@ -642,10 +646,14 @@ typedef struct CPUX86State { uint16_t fpuc; uint8_t fptags[8]; /* 0 = valid, 1 = empty */ FPReg fpregs[8]; + /* KVM-only so far */ + uint16_t fpop; + uint64_t fpip; + uint64_t fpdp; /* emulator internal variables */ float_status fp_status; - CPU86_LDouble ft0; + floatx80 ft0; float_status mmx_status; /* for 3DNow! float ops */ float_status sse_status; @@ -684,8 +692,10 @@ typedef struct CPUX86State { uint64_t async_pf_en_msr; uint64_t tsc; + uint64_t tsc_deadline; - uint64_t pat; + uint64_t mcg_status; + uint64_t msr_ia32_misc_enable; /* exception/interrupt handling */ int error_code; @@ -705,6 +715,8 @@ typedef struct CPUX86State { CPU_COMMON + uint64_t pat; + /* processor features (e.g. for CPUID insn) */ uint32_t cpuid_level; uint32_t cpuid_vendor1; @@ -719,6 +731,9 @@ typedef struct CPUX86State { uint32_t cpuid_ext3_features; uint32_t cpuid_apic_id; int cpuid_vendor_override; + /* Store the results of Centaur's CPUID instructions */ + uint32_t cpuid_xlevel2; + uint32_t cpuid_ext4_features; /* MTRRs */ uint64_t mtrr_fixed[11]; @@ -734,13 +749,14 @@ typedef struct CPUX86State { uint32_t sipi_vector; uint32_t cpuid_kvm_features; uint32_t cpuid_svm_features; + bool tsc_valid; + int tsc_khz; /* in order to simplify APIC support, we leave this pointer to the user */ struct DeviceState *apic_state; uint64_t mcg_cap; - uint64_t mcg_status; uint64_t mcg_ctl; uint64_t mce_banks[MCE_BANKS_DEF*4]; @@ -854,8 +870,8 @@ static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl) /* op_helper.c */ /* used for debug or cpu save/restore */ -void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f); -CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper); +void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f); +floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper); /* cpu-exec.c */ /* the following helpers are only usable in user mode simulation as @@ -881,7 +897,7 @@ void host_cpuid(uint32_t function, uint32_t count, /* helper.c */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write, int mmu_idx, int is_softmmu); + int is_write, int mmu_idx); #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault void cpu_x86_set_a20(CPUX86State *env, int a20_state); @@ -949,14 +965,39 @@ static inline int cpu_mmu_index (CPUState *env) return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0; } +#undef EAX +#define EAX (env->regs[R_EAX]) +#undef ECX +#define ECX (env->regs[R_ECX]) +#undef EDX +#define EDX (env->regs[R_EDX]) +#undef EBX +#define EBX (env->regs[R_EBX]) +#undef ESP +#define ESP (env->regs[R_ESP]) +#undef EBP +#define EBP (env->regs[R_EBP]) +#undef ESI +#define ESI (env->regs[R_ESI]) +#undef EDI +#define EDI (env->regs[R_EDI]) +#undef EIP +#define EIP (env->eip) +#define DF (env->df) + +#define CC_SRC (env->cc_src) +#define CC_DST (env->cc_dst) +#define CC_OP (env->cc_op) + +/* float macros */ +#define FT0 (env->ft0) +#define ST0 (env->fpregs[env->fpstt].d) +#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d) +#define ST1 ST(1) + /* translate.c */ void optimize_flags_init(void); -typedef struct CCTable { - int (*compute_all)(void); /* return all the flags */ - int (*compute_c)(void); /* return the C flag */ -} CCTable; - #if defined(CONFIG_USER_ONLY) static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) { @@ -973,6 +1014,23 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) #include "hw/apic.h" #endif +static inline bool cpu_has_work(CPUState *env) +{ + return ((env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK)) || + (env->interrupt_request & (CPU_INTERRUPT_NMI | + CPU_INTERRUPT_INIT | + CPU_INTERRUPT_SIPI | + CPU_INTERRUPT_MCE)); +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->eip = tb->pc - tb->cs_base; +} + static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { @@ -984,4 +1042,25 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, void do_cpu_init(CPUState *env); void do_cpu_sipi(CPUState *env); + +#define MCE_INJECT_BROADCAST 1 +#define MCE_INJECT_UNCOND_AO 2 + +void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank, + uint64_t status, uint64_t mcg_status, uint64_t addr, + uint64_t misc, int flags); + +/* op_helper.c */ +void do_interrupt(CPUState *env); +void do_interrupt_x86_hardirq(CPUState *env, int intno, int is_hw); +void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv); +void QEMU_NORETURN raise_exception_err_env(CPUState *nenv, int exception_index, + int error_code); + +void do_smm_enter(CPUState *env1); + +void svm_check_intercept(CPUState *env1, uint32_t type); + +uint32_t cpu_cc_compute_all(CPUState *env1, int op); + #endif /* CPU_I386_H */ diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c index 5382a28..0b3af90 100644 --- a/target-i386/cpuid.c +++ b/target-i386/cpuid.c @@ -73,7 +73,7 @@ static const char *ext3_feature_name[] = { }; static const char *kvm_feature_name[] = { - "kvmclock", "kvm_nopiodelay", "kvm_mmu", NULL, "kvm_asyncpf", NULL, NULL, NULL, + "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -182,20 +182,22 @@ static int altcmp(const char *s, const char *e, const char *altstr) } /* search featureset for flag *[s..e), if found set corresponding bit in - * *pval and return success, otherwise return zero + * *pval and return true, otherwise return false */ -static int lookup_feature(uint32_t *pval, const char *s, const char *e, - const char **featureset) +static bool lookup_feature(uint32_t *pval, const char *s, const char *e, + const char **featureset) { uint32_t mask; const char **ppc; + bool found = false; - for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) + for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) { if (*ppc && !altcmp(s, e, *ppc)) { *pval |= mask; - break; + found = true; } - return (mask ? 1 : 0); + } + return found; } static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features, @@ -222,12 +224,16 @@ typedef struct x86_def_t { int family; int model; int stepping; + int tsc_khz; uint32_t features, ext_features, ext2_features, ext3_features; uint32_t kvm_features, svm_features; uint32_t xlevel; char model_id[48]; int vendor_override; uint32_t flags; + /* Store the results of Centaur's CPUID instructions */ + uint32_t ext4_features; + uint32_t xlevel2; } x86_def_t; #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) @@ -520,6 +526,18 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def) cpu_x86_fill_model_id(x86_cpu_def->model_id); x86_cpu_def->vendor_override = 0; + /* Call Centaur's CPUID instruction. */ + if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 && + x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 && + x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) { + host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx); + if (eax >= 0xC0000001) { + /* Support VIA max extended level */ + x86_cpu_def->xlevel2 = eax; + host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx); + x86_cpu_def->ext4_features = edx; + } + } /* * Every SVM feature requires emulation support in KVM - so we can't just @@ -582,7 +600,7 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) unsigned int i; x86_def_t *def; - char *s = strdup(cpu_model); + char *s = g_strdup(cpu_model); char *featurestr, *name = strtok(s, ","); /* Features to be added*/ uint32_t plus_features = 0, plus_ext_features = 0; @@ -595,9 +613,9 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) uint32_t numvalue; for (def = x86_defs; def; def = def->next) - if (!strcmp(name, def->name)) + if (name && !strcmp(name, def->name)) break; - if (kvm_enabled() && strcmp(name, "host") == 0) { + if (kvm_enabled() && name && strcmp(name, "host") == 0) { cpu_x86_fill_host(x86_cpu_def); } else if (!def) { goto error; @@ -687,6 +705,17 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) } else if (!strcmp(featurestr, "model_id")) { pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id), val); + } else if (!strcmp(featurestr, "tsc_freq")) { + int64_t tsc_freq; + char *err; + + tsc_freq = strtosz_suffix_unit(val, &err, + STRTOSZ_DEFSUFFIX_B, 1000); + if (tsc_freq < 0 || *err) { + fprintf(stderr, "bad numerical value %s\n", val); + goto error; + } + x86_cpu_def->tsc_khz = tsc_freq / 1000; } else { fprintf(stderr, "unrecognized feature %s\n", featurestr); goto error; @@ -717,11 +746,11 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) if (check_features_against_host(x86_cpu_def) && enforce_cpuid) goto error; } - free(s); + g_free(s); return 0; error: - free(s); + g_free(s); return -1; } @@ -847,13 +876,15 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model) env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16); env->cpuid_version |= def->stepping; env->cpuid_features = def->features; - env->pat = 0x0007040600070406ULL; env->cpuid_ext_features = def->ext_features; env->cpuid_ext2_features = def->ext2_features; env->cpuid_ext3_features = def->ext3_features; env->cpuid_xlevel = def->xlevel; env->cpuid_kvm_features = def->kvm_features; env->cpuid_svm_features = def->svm_features; + env->cpuid_ext4_features = def->ext4_features; + env->cpuid_xlevel2 = def->xlevel2; + env->tsc_khz = def->tsc_khz; if (!kvm_enabled()) { env->cpuid_features &= TCG_FEATURES; env->cpuid_ext_features &= TCG_EXT_FEATURES; @@ -938,7 +969,8 @@ static int cpudef_setfield(const char *name, const char *str, void *opaque) int err = 0; if (!strcmp(name, "name")) { - def->name = strdup(str); + g_free((void *)def->name); + def->name = g_strdup(str); } else if (!strcmp(name, "model_id")) { strncpy(def->model_id, str, sizeof (def->model_id)); } else if (!strcmp(name, "level")) { @@ -978,7 +1010,7 @@ static int cpudef_setfield(const char *name, const char *str, void *opaque) */ static int cpudef_register(QemuOpts *opts, void *opaque) { - x86_def_t *def = qemu_mallocz(sizeof (x86_def_t)); + x86_def_t *def = g_malloc0(sizeof (x86_def_t)); qemu_opt_foreach(opts, cpudef_setfield, def, 1); def->next = x86_defs; @@ -1034,8 +1066,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, { /* test if maximum index reached */ if (index & 0x80000000) { - if (index > env->cpuid_xlevel) - index = env->cpuid_level; + if (index > env->cpuid_xlevel) { + if (env->cpuid_xlevel2 > 0) { + /* Handle the Centaur's CPUID instruction. */ + if (index > env->cpuid_xlevel2) { + index = env->cpuid_xlevel2; + } else if (index < 0xC0000000) { + index = env->cpuid_xlevel; + } + } else { + index = env->cpuid_xlevel; + } + } } else { if (index > env->cpuid_level) index = env->cpuid_level; @@ -1114,6 +1156,21 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0; *edx = 0; break; + case 7: + if (kvm_enabled()) { + KVMState *s = env->kvm_state; + + *eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX); + *ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX); + *ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX); + *edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX); + } else { + *eax = 0; + *ebx = 0; + *ecx = 0; + *edx = 0; + } + break; case 9: /* Direct Cache Access Information Leaf */ *eax = 0; /* Bits 0-31 in DCA_CAP MSR */ @@ -1138,10 +1195,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; } if (kvm_enabled()) { - *eax = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EAX); - *ebx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EBX); - *ecx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_ECX); - *edx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EDX); + KVMState *s = env->kvm_state; + + *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX); + *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX); + *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX); + *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX); } else { *eax = 0; *ebx = 0; @@ -1230,6 +1289,28 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *edx = 0; } break; + case 0xC0000000: + *eax = env->cpuid_xlevel2; + *ebx = 0; + *ecx = 0; + *edx = 0; + break; + case 0xC0000001: + /* Support for VIA CPU's CPUID instruction */ + *eax = env->cpuid_version; + *ebx = 0; + *ecx = 0; + *edx = env->cpuid_ext4_features; + break; + case 0xC0000002: + case 0xC0000003: + case 0xC0000004: + /* Reserved for the future, and now filled with zero */ + *eax = 0; + *ebx = 0; + *ecx = 0; + *edx = 0; + break; default: /* reserved values: zero */ *eax = 0; diff --git a/target-i386/exec.h b/target-i386/exec.h deleted file mode 100644 index 6465c24..0000000 --- a/target-i386/exec.h +++ /dev/null @@ -1,391 +0,0 @@ -/* - * i386 execution defines - * - * Copyright (c) 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, see . - */ -#include "config.h" -#include "dyngen-exec.h" - -/* XXX: factorize this mess */ -#ifdef TARGET_X86_64 -#define TARGET_LONG_BITS 64 -#else -#define TARGET_LONG_BITS 32 -#endif - -#include "cpu-defs.h" - -register struct CPUX86State *env asm(AREG0); - -#include "qemu-common.h" -#include "qemu-log.h" - -#undef EAX -#define EAX (env->regs[R_EAX]) -#undef ECX -#define ECX (env->regs[R_ECX]) -#undef EDX -#define EDX (env->regs[R_EDX]) -#undef EBX -#define EBX (env->regs[R_EBX]) -#undef ESP -#define ESP (env->regs[R_ESP]) -#undef EBP -#define EBP (env->regs[R_EBP]) -#undef ESI -#define ESI (env->regs[R_ESI]) -#undef EDI -#define EDI (env->regs[R_EDI]) -#undef EIP -#define EIP (env->eip) -#define DF (env->df) - -#define CC_SRC (env->cc_src) -#define CC_DST (env->cc_dst) -#define CC_OP (env->cc_op) - -/* float macros */ -#define FT0 (env->ft0) -#define ST0 (env->fpregs[env->fpstt].d) -#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d) -#define ST1 ST(1) - -#include "cpu.h" -#include "exec-all.h" - -/* op_helper.c */ -void do_interrupt(int intno, int is_int, int error_code, - target_ulong next_eip, int is_hw); -void do_interrupt_user(int intno, int is_int, int error_code, - target_ulong next_eip); -void QEMU_NORETURN raise_exception_err(int exception_index, int error_code); -void QEMU_NORETURN raise_exception(int exception_index); -void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv); -void do_smm_enter(void); - -/* n must be a constant to be efficient */ -static inline target_long lshift(target_long x, int n) -{ - if (n >= 0) - return x << n; - else - return x >> (-n); -} - -#include "helper.h" - -static inline void svm_check_intercept(uint32_t type) -{ - helper_svm_check_intercept_param(type, 0); -} - -#if !defined(CONFIG_USER_ONLY) - -#include "softmmu_exec.h" - -#endif /* !defined(CONFIG_USER_ONLY) */ - -#ifdef USE_X86LDOUBLE -/* use long double functions */ -#define floatx_to_int32 floatx80_to_int32 -#define floatx_to_int64 floatx80_to_int64 -#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero -#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero -#define int32_to_floatx int32_to_floatx80 -#define int64_to_floatx int64_to_floatx80 -#define float32_to_floatx float32_to_floatx80 -#define float64_to_floatx float64_to_floatx80 -#define floatx_to_float32 floatx80_to_float32 -#define floatx_to_float64 floatx80_to_float64 -#define floatx_abs floatx80_abs -#define floatx_chs floatx80_chs -#define floatx_round_to_int floatx80_round_to_int -#define floatx_compare floatx80_compare -#define floatx_compare_quiet floatx80_compare_quiet -#else -#define floatx_to_int32 float64_to_int32 -#define floatx_to_int64 float64_to_int64 -#define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero -#define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero -#define int32_to_floatx int32_to_float64 -#define int64_to_floatx int64_to_float64 -#define float32_to_floatx float32_to_float64 -#define float64_to_floatx(x, e) (x) -#define floatx_to_float32 float64_to_float32 -#define floatx_to_float64(x, e) (x) -#define floatx_abs float64_abs -#define floatx_chs float64_chs -#define floatx_round_to_int float64_round_to_int -#define floatx_compare float64_compare -#define floatx_compare_quiet float64_compare_quiet -#endif - -#define RC_MASK 0xc00 -#define RC_NEAR 0x000 -#define RC_DOWN 0x400 -#define RC_UP 0x800 -#define RC_CHOP 0xc00 - -#define MAXTAN 9223372036854775808.0 - -#ifdef USE_X86LDOUBLE - -/* only for x86 */ -typedef union { - long double d; - struct { - unsigned long long lower; - unsigned short upper; - } l; -} CPU86_LDoubleU; - -/* the following deal with x86 long double-precision numbers */ -#define MAXEXPD 0x7fff -#define EXPBIAS 16383 -#define EXPD(fp) (fp.l.upper & 0x7fff) -#define SIGND(fp) ((fp.l.upper) & 0x8000) -#define MANTD(fp) (fp.l.lower) -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS - -#else - -/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ -typedef union { - double d; -#if !defined(HOST_WORDS_BIGENDIAN) && !defined(__arm__) - struct { - uint32_t lower; - int32_t upper; - } l; -#else - struct { - int32_t upper; - uint32_t lower; - } l; -#endif -#ifndef __arm__ - int64_t ll; -#endif -} CPU86_LDoubleU; - -/* the following deal with IEEE double-precision numbers */ -#define MAXEXPD 0x7ff -#define EXPBIAS 1023 -#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) -#define SIGND(fp) ((fp.l.upper) & 0x80000000) -#ifdef __arm__ -#define MANTD(fp) (fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32)) -#else -#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) -#endif -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) -#endif - -static inline void fpush(void) -{ - env->fpstt = (env->fpstt - 1) & 7; - env->fptags[env->fpstt] = 0; /* validate stack entry */ -} - -static inline void fpop(void) -{ - env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ - env->fpstt = (env->fpstt + 1) & 7; -} - -#ifndef USE_X86LDOUBLE -static inline CPU86_LDouble helper_fldt(target_ulong ptr) -{ - CPU86_LDoubleU temp; - int upper, e; - uint64_t ll; - - /* mantissa */ - upper = lduw(ptr + 8); - /* XXX: handle overflow ? */ - e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ - e |= (upper >> 4) & 0x800; /* sign */ - ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1); -#ifdef __arm__ - temp.l.upper = (e << 20) | (ll >> 32); - temp.l.lower = ll; -#else - temp.ll = ll | ((uint64_t)e << 52); -#endif - return temp.d; -} - -static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) -{ - CPU86_LDoubleU temp; - int e; - - temp.d = f; - /* mantissa */ - stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); - /* exponent + sign */ - e = EXPD(temp) - EXPBIAS + 16383; - e |= SIGND(temp) >> 16; - stw(ptr + 8, e); -} -#else - -/* we use memory access macros */ - -static inline CPU86_LDouble helper_fldt(target_ulong ptr) -{ - CPU86_LDoubleU temp; - - temp.l.lower = ldq(ptr); - temp.l.upper = lduw(ptr + 8); - return temp.d; -} - -static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) -{ - CPU86_LDoubleU temp; - - temp.d = f; - stq(ptr, temp.l.lower); - stw(ptr + 8, temp.l.upper); -} - -#endif /* USE_X86LDOUBLE */ - -#define FPUS_IE (1 << 0) -#define FPUS_DE (1 << 1) -#define FPUS_ZE (1 << 2) -#define FPUS_OE (1 << 3) -#define FPUS_UE (1 << 4) -#define FPUS_PE (1 << 5) -#define FPUS_SF (1 << 6) -#define FPUS_SE (1 << 7) -#define FPUS_B (1 << 15) - -#define FPUC_EM 0x3f - -static inline uint32_t compute_eflags(void) -{ - return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); -} - -/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */ -static inline void load_eflags(int eflags, int update_mask) -{ - CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((eflags >> 10) & 1)); - env->eflags = (env->eflags & ~update_mask) | - (eflags & update_mask) | 0x2; -} - -static inline void env_to_regs(void) -{ -#ifdef reg_EAX - EAX = env->regs[R_EAX]; -#endif -#ifdef reg_ECX - ECX = env->regs[R_ECX]; -#endif -#ifdef reg_EDX - EDX = env->regs[R_EDX]; -#endif -#ifdef reg_EBX - EBX = env->regs[R_EBX]; -#endif -#ifdef reg_ESP - ESP = env->regs[R_ESP]; -#endif -#ifdef reg_EBP - EBP = env->regs[R_EBP]; -#endif -#ifdef reg_ESI - ESI = env->regs[R_ESI]; -#endif -#ifdef reg_EDI - EDI = env->regs[R_EDI]; -#endif -} - -static inline void regs_to_env(void) -{ -#ifdef reg_EAX - env->regs[R_EAX] = EAX; -#endif -#ifdef reg_ECX - env->regs[R_ECX] = ECX; -#endif -#ifdef reg_EDX - env->regs[R_EDX] = EDX; -#endif -#ifdef reg_EBX - env->regs[R_EBX] = EBX; -#endif -#ifdef reg_ESP - env->regs[R_ESP] = ESP; -#endif -#ifdef reg_EBP - env->regs[R_EBP] = EBP; -#endif -#ifdef reg_ESI - env->regs[R_ESI] = ESI; -#endif -#ifdef reg_EDI - env->regs[R_EDI] = EDI; -#endif -} - -static inline int cpu_has_work(CPUState *env) -{ - int work; - - work = (env->interrupt_request & CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK); - work |= env->interrupt_request & CPU_INTERRUPT_NMI; - work |= env->interrupt_request & CPU_INTERRUPT_INIT; - work |= env->interrupt_request & CPU_INTERRUPT_SIPI; - - return work; -} - -static inline int cpu_halted(CPUState *env) { - /* handle exit of HALTED state */ - if (!env->halted) - return 0; - /* disable halt condition */ - if (cpu_has_work(env)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -/* load efer and update the corresponding hflags. XXX: do consistency - checks with cpuid bits ? */ -static inline void cpu_load_efer(CPUState *env, uint64_t val) -{ - env->efer = val; - env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); - if (env->efer & MSR_EFER_LMA) - env->hflags |= HF_LMA_MASK; - if (env->efer & MSR_EFER_SVME) - env->hflags |= HF_SVME_MASK; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->eip = tb->pc - tb->cs_base; -} - diff --git a/target-i386/gl_func_perso.h b/target-i386/gl_func_perso.h deleted file mode 100644 index 205ba6d..0000000 --- a/target-i386/gl_func_perso.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Hand-implemented GL/GLX API - * - * Copyright (c) 2006,2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - -MAGIC_MACRO(_init), -MAGIC_MACRO(_synchronize), -MAGIC_MACRO(_serialized_calls), -MAGIC_MACRO(_exit_process), -MAGIC_MACRO(_moveResizeWindow), -MAGIC_MACRO(_changeWindowState), -MAGIC_MACRO(_send_cursor), - -/* When you add a glX call here, you HAVE TO update IS_GLX_CALL */ -MAGIC_MACRO(glXChooseVisual), -MAGIC_MACRO(glXQueryExtensionsString), -MAGIC_MACRO(glXQueryServerString), -MAGIC_MACRO(glXCreateContext), -MAGIC_MACRO(glXCopyContext), -MAGIC_MACRO(glXDestroyContext), -MAGIC_MACRO(glXGetClientString), -MAGIC_MACRO(glXQueryVersion), -MAGIC_MACRO(glXMakeCurrent), -MAGIC_MACRO(glXGetConfig), -MAGIC_MACRO(glXGetConfig_extended), -MAGIC_MACRO(glXWaitGL), -MAGIC_MACRO(glXWaitX), -MAGIC_MACRO(glXGetFBConfigAttrib_extended), -MAGIC_MACRO(glXChooseFBConfig), -MAGIC_MACRO(glXChooseFBConfigSGIX), -MAGIC_MACRO(glXGetFBConfigs), -MAGIC_MACRO(glXDestroyWindow), -MAGIC_MACRO(glXCreatePbuffer), -MAGIC_MACRO(glXCreateGLXPbufferSGIX), -MAGIC_MACRO(glXDestroyPbuffer), -MAGIC_MACRO(glXDestroyGLXPbufferSGIX), -MAGIC_MACRO(glXCreateNewContext), -MAGIC_MACRO(glXCreateContextWithConfigSGIX), -MAGIC_MACRO(glXGetVisualFromFBConfig), -MAGIC_MACRO(glXGetFBConfigAttrib), -MAGIC_MACRO(glXGetFBConfigAttribSGIX), -MAGIC_MACRO(glXQueryContext), -MAGIC_MACRO(glXQueryDrawable), -MAGIC_MACRO(glXQueryGLXPbufferSGIX), -MAGIC_MACRO(glXUseXFont), -MAGIC_MACRO(glXIsDirect), -MAGIC_MACRO(glXGetProcAddress_fake), -MAGIC_MACRO(glXGetProcAddress_global_fake), -MAGIC_MACRO(glXSwapBuffers), -MAGIC_MACRO(glXQueryExtension), -MAGIC_MACRO(glXGetScreenDriver), -MAGIC_MACRO(glXGetDriverConfig), -MAGIC_MACRO(glXSwapIntervalSGI), -MAGIC_MACRO(glXBindTexImageATI), -MAGIC_MACRO(glXReleaseTexImageATI), -MAGIC_MACRO(glXBindTexImageARB), -MAGIC_MACRO(glXReleaseTexImageARB), - -MAGIC_MACRO(glGetString), - -MAGIC_MACRO(glShaderSourceARB_fake), -MAGIC_MACRO(glShaderSource_fake), -MAGIC_MACRO(glVertexPointer_fake), -MAGIC_MACRO(glNormalPointer_fake), -MAGIC_MACRO(glColorPointer_fake), -MAGIC_MACRO(glSecondaryColorPointer_fake), -MAGIC_MACRO(glIndexPointer_fake), -MAGIC_MACRO(glTexCoordPointer_fake), -MAGIC_MACRO(glEdgeFlagPointer_fake), -MAGIC_MACRO(glVertexAttribPointerARB_fake), -MAGIC_MACRO(glVertexAttribPointerNV_fake), -MAGIC_MACRO(glWeightPointerARB_fake), -MAGIC_MACRO(glMatrixIndexPointerARB_fake), -MAGIC_MACRO(glFogCoordPointer_fake), -MAGIC_MACRO(glVariantPointerEXT_fake), -MAGIC_MACRO(glInterleavedArrays_fake), -MAGIC_MACRO(glElementPointerATI_fake), -MAGIC_MACRO(glTuxRacerDrawElements_fake), -MAGIC_MACRO(glVertexAndNormalPointer_fake), -MAGIC_MACRO(glTexCoordPointer01_fake), -MAGIC_MACRO(glTexCoordPointer012_fake), -MAGIC_MACRO(glVertexNormalPointerInterlaced_fake), -MAGIC_MACRO(glVertexNormalColorPointerInterlaced_fake), -MAGIC_MACRO(glVertexColorTexCoord0PointerInterlaced_fake), -MAGIC_MACRO(glVertexNormalTexCoord0PointerInterlaced_fake), -MAGIC_MACRO(glVertexNormalTexCoord01PointerInterlaced_fake), -MAGIC_MACRO(glVertexNormalTexCoord012PointerInterlaced_fake), -MAGIC_MACRO(glVertexNormalColorTexCoord0PointerInterlaced_fake), -MAGIC_MACRO(glVertexNormalColorTexCoord01PointerInterlaced_fake), -MAGIC_MACRO(glVertexNormalColorTexCoord012PointerInterlaced_fake), -MAGIC_MACRO(glGenTextures_fake), -MAGIC_MACRO(glGenBuffersARB_fake), -MAGIC_MACRO(glGenLists_fake), -MAGIC_MACRO(_glDrawElements_buffer), -MAGIC_MACRO(_glDrawRangeElements_buffer), -MAGIC_MACRO(_glMultiDrawElements_buffer), -MAGIC_MACRO(_glVertexPointer_buffer), -MAGIC_MACRO(_glNormalPointer_buffer), -MAGIC_MACRO(_glColorPointer_buffer), -MAGIC_MACRO(_glSecondaryColorPointer_buffer), -MAGIC_MACRO(_glIndexPointer_buffer), -MAGIC_MACRO(_glTexCoordPointer_buffer), -MAGIC_MACRO(_glEdgeFlagPointer_buffer), -MAGIC_MACRO(_glVertexAttribPointerARB_buffer), -MAGIC_MACRO(_glWeightPointerARB_buffer), -MAGIC_MACRO(_glMatrixIndexPointerARB_buffer), -MAGIC_MACRO(_glFogCoordPointer_buffer), -MAGIC_MACRO(_glVariantPointerEXT_buffer), -MAGIC_MACRO(_glGetError_fake), -MAGIC_MACRO(_glReadPixels_pbo), -MAGIC_MACRO(_glDrawPixels_pbo), -MAGIC_MACRO(_glMapBufferARB_fake), -MAGIC_MACRO(_glSelectBuffer_fake), -MAGIC_MACRO(_glGetSelectBuffer_fake), -MAGIC_MACRO(_glFeedbackBuffer_fake), -MAGIC_MACRO(_glGetFeedbackBuffer_fake), diff --git a/target-i386/glgetv_cst.h b/target-i386/glgetv_cst.h deleted file mode 100644 index 0d7820e..0000000 --- a/target-i386/glgetv_cst.h +++ /dev/null @@ -1,468 +0,0 @@ -/* This is a generated file. Do not edit !*/ -typedef struct { - GLuint count; - GLenum token; - const char *name; -} GlGetConstant ; -static const GlGetConstant gl_get_constants[] = { - { 4, 0x0B00, "GL_CURRENT_COLOR" }, - { 1, 0x0B01, "GL_CURRENT_INDEX" }, - { 3, 0x0B02, "GL_CURRENT_NORMAL" }, - { 4, 0x0B03, "GL_CURRENT_TEXTURE_COORDS" }, - { 4, 0x0B04, "GL_CURRENT_RASTER_COLOR" }, - { 1, 0x0B05, "GL_CURRENT_RASTER_INDEX" }, - { 4, 0x0B06, "GL_CURRENT_RASTER_TEXTURE_COORDS" }, - { 4, 0x0B07, "GL_CURRENT_RASTER_POSITION" }, - { 1, 0x0B08, "GL_CURRENT_RASTER_POSITION_VALID" }, - { 1, 0x0B09, "GL_CURRENT_RASTER_DISTANCE" }, - { 1, 0x0B10, "GL_POINT_SMOOTH" }, - { 1, 0x0B11, "GL_POINT_SIZE" }, - { 2, 0x0B12, "GL_POINT_SIZE_RANGE" }, - { 1, 0x0B13, "GL_POINT_SIZE_GRANULARITY" }, - { 1, 0x0B20, "GL_LINE_SMOOTH" }, - { 1, 0x0B21, "GL_LINE_WIDTH" }, - { 2, 0x0B22, "GL_LINE_WIDTH_RANGE" }, - { 1, 0x0B23, "GL_LINE_WIDTH_GRANULARITY" }, - { 1, 0x0B24, "GL_LINE_STIPPLE" }, - { 1, 0x0B25, "GL_LINE_STIPPLE_PATTERN" }, - { 1, 0x0B26, "GL_LINE_STIPPLE_REPEAT" }, - { 1, 0x0B30, "GL_LIST_MODE" }, - { 1, 0x0B31, "GL_MAX_LIST_NESTING" }, - { 1, 0x0B32, "GL_LIST_BASE" }, - { 1, 0x0B33, "GL_LIST_INDEX" }, - { 2, 0x0B40, "GL_POLYGON_MODE" }, - { 1, 0x0B41, "GL_POLYGON_SMOOTH" }, - { 1, 0x0B42, "GL_POLYGON_STIPPLE" }, - { 1, 0x0B43, "GL_EDGE_FLAG" }, - { 1, 0x0B44, "GL_CULL_FACE" }, - { 1, 0x0B45, "GL_CULL_FACE_MODE" }, - { 1, 0x0B46, "GL_FRONT_FACE" }, - { 1, 0x0B50, "GL_LIGHTING" }, - { 1, 0x0B51, "GL_LIGHT_MODEL_LOCAL_VIEWER" }, - { 1, 0x0B52, "GL_LIGHT_MODEL_TWO_SIDE" }, - { 4, 0x0B53, "GL_LIGHT_MODEL_AMBIENT" }, - { 1, 0x0B54, "GL_SHADE_MODEL" }, - { 1, 0x0B55, "GL_COLOR_MATERIAL_FACE" }, - { 1, 0x0B56, "GL_COLOR_MATERIAL_PARAMETER" }, - { 1, 0x0B57, "GL_COLOR_MATERIAL" }, - { 1, 0x0B60, "GL_FOG" }, - { 1, 0x0B61, "GL_FOG_INDEX" }, - { 1, 0x0B62, "GL_FOG_DENSITY" }, - { 1, 0x0B63, "GL_FOG_START" }, - { 1, 0x0B64, "GL_FOG_END" }, - { 1, 0x0B65, "GL_FOG_MODE" }, - { 4, 0x0B66, "GL_FOG_COLOR" }, - { 2, 0x0B70, "GL_DEPTH_RANGE" }, - { 1, 0x0B71, "GL_DEPTH_TEST" }, - { 1, 0x0B72, "GL_DEPTH_WRITEMASK" }, - { 1, 0x0B73, "GL_DEPTH_CLEAR_VALUE" }, - { 1, 0x0B74, "GL_DEPTH_FUNC" }, - { 4, 0x0B80, "GL_ACCUM_CLEAR_VALUE" }, - { 1, 0x0B90, "GL_STENCIL_TEST" }, - { 1, 0x0B91, "GL_STENCIL_CLEAR_VALUE" }, - { 1, 0x0B92, "GL_STENCIL_FUNC" }, - { 1, 0x0B93, "GL_STENCIL_VALUE_MASK" }, - { 1, 0x0B94, "GL_STENCIL_FAIL" }, - { 1, 0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL" }, - { 1, 0x0B96, "GL_STENCIL_PASS_DEPTH_PASS" }, - { 1, 0x0B97, "GL_STENCIL_REF" }, - { 1, 0x0B98, "GL_STENCIL_WRITEMASK" }, - { 1, 0x0BA0, "GL_MATRIX_MODE" }, - { 1, 0x0BA1, "GL_NORMALIZE" }, - { 4, 0x0BA2, "GL_VIEWPORT" }, - { 1, 0x0BA3, "GL_MODELVIEW_STACK_DEPTH" }, - { 1, 0x0BA4, "GL_PROJECTION_STACK_DEPTH" }, - { 1, 0x0BA5, "GL_TEXTURE_STACK_DEPTH" }, - { 16, 0x0BA6, "GL_MODELVIEW_MATRIX" }, - { 16, 0x0BA7, "GL_PROJECTION_MATRIX" }, - { 16, 0x0BA8, "GL_TEXTURE_MATRIX" }, - { 1, 0x0BB0, "GL_ATTRIB_STACK_DEPTH" }, - { 1, 0x0BB1, "GL_CLIENT_ATTRIB_STACK_DEPTH" }, - { 1, 0x0BC0, "GL_ALPHA_TEST" }, - { 1, 0x0BC1, "GL_ALPHA_TEST_FUNC" }, - { 1, 0x0BC2, "GL_ALPHA_TEST_REF" }, - { 1, 0x0BD0, "GL_DITHER" }, - { 1, 0x0BE0, "GL_BLEND_DST" }, - { 1, 0x0BE1, "GL_BLEND_SRC" }, - { 1, 0x0BE2, "GL_BLEND" }, - { 1, 0x0BF0, "GL_LOGIC_OP_MODE" }, - { 1, 0x0BF1, "GL_INDEX_LOGIC_OP" }, - { 1, 0x0BF2, "GL_COLOR_LOGIC_OP" }, - { 1, 0x0C00, "GL_AUX_BUFFERS" }, - { 1, 0x0C01, "GL_DRAW_BUFFER" }, - { 1, 0x0C02, "GL_READ_BUFFER" }, - { 4, 0x0C10, "GL_SCISSOR_BOX" }, - { 1, 0x0C11, "GL_SCISSOR_TEST" }, - { 1, 0x0C20, "GL_INDEX_CLEAR_VALUE" }, - { 1, 0x0C21, "GL_INDEX_WRITEMASK" }, - { 4, 0x0C22, "GL_COLOR_CLEAR_VALUE" }, - { 4, 0x0C23, "GL_COLOR_WRITEMASK" }, - { 1, 0x0C30, "GL_INDEX_MODE" }, - { 1, 0x0C31, "GL_RGBA_MODE" }, - { 1, 0x0C32, "GL_DOUBLEBUFFER" }, - { 1, 0x0C33, "GL_STEREO" }, - { 1, 0x0C40, "GL_RENDER_MODE" }, - { 1, 0x0C50, "GL_PERSPECTIVE_CORRECTION_HINT" }, - { 1, 0x0C51, "GL_POINT_SMOOTH_HINT" }, - { 1, 0x0C52, "GL_LINE_SMOOTH_HINT" }, - { 1, 0x0C53, "GL_POLYGON_SMOOTH_HINT" }, - { 1, 0x0C54, "GL_FOG_HINT" }, - { 1, 0x0C60, "GL_TEXTURE_GEN_S" }, - { 1, 0x0C61, "GL_TEXTURE_GEN_T" }, - { 1, 0x0C62, "GL_TEXTURE_GEN_R" }, - { 1, 0x0C63, "GL_TEXTURE_GEN_Q" }, - { 1, 0x0CB0, "GL_PIXEL_MAP_I_TO_I_SIZE" }, - { 1, 0x0CB1, "GL_PIXEL_MAP_S_TO_S_SIZE" }, - { 1, 0x0CB2, "GL_PIXEL_MAP_I_TO_R_SIZE" }, - { 1, 0x0CB3, "GL_PIXEL_MAP_I_TO_G_SIZE" }, - { 1, 0x0CB4, "GL_PIXEL_MAP_I_TO_B_SIZE" }, - { 1, 0x0CB5, "GL_PIXEL_MAP_I_TO_A_SIZE" }, - { 1, 0x0CB6, "GL_PIXEL_MAP_R_TO_R_SIZE" }, - { 1, 0x0CB7, "GL_PIXEL_MAP_G_TO_G_SIZE" }, - { 1, 0x0CB8, "GL_PIXEL_MAP_B_TO_B_SIZE" }, - { 1, 0x0CB9, "GL_PIXEL_MAP_A_TO_A_SIZE" }, - { 1, 0x0CF0, "GL_UNPACK_SWAP_BYTES" }, - { 1, 0x0CF1, "GL_UNPACK_LSB_FIRST" }, - { 1, 0x0CF2, "GL_UNPACK_ROW_LENGTH" }, - { 1, 0x0CF3, "GL_UNPACK_SKIP_ROWS" }, - { 1, 0x0CF4, "GL_UNPACK_SKIP_PIXELS" }, - { 1, 0x0CF5, "GL_UNPACK_ALIGNMENT" }, - { 1, 0x0D00, "GL_PACK_SWAP_BYTES" }, - { 1, 0x0D01, "GL_PACK_LSB_FIRST" }, - { 1, 0x0D02, "GL_PACK_ROW_LENGTH" }, - { 1, 0x0D03, "GL_PACK_SKIP_ROWS" }, - { 1, 0x0D04, "GL_PACK_SKIP_PIXELS" }, - { 1, 0x0D05, "GL_PACK_ALIGNMENT" }, - { 1, 0x0D10, "GL_MAP_COLOR" }, - { 1, 0x0D11, "GL_MAP_STENCIL" }, - { 1, 0x0D12, "GL_INDEX_SHIFT" }, - { 1, 0x0D13, "GL_INDEX_OFFSET" }, - { 1, 0x0D14, "GL_RED_SCALE" }, - { 1, 0x0D15, "GL_RED_BIAS" }, - { 1, 0x0D16, "GL_ZOOM_X" }, - { 1, 0x0D17, "GL_ZOOM_Y" }, - { 1, 0x0D18, "GL_GREEN_SCALE" }, - { 1, 0x0D19, "GL_GREEN_BIAS" }, - { 1, 0x0D1A, "GL_BLUE_SCALE" }, - { 1, 0x0D1B, "GL_BLUE_BIAS" }, - { 1, 0x0D1C, "GL_ALPHA_SCALE" }, - { 1, 0x0D1D, "GL_ALPHA_BIAS" }, - { 1, 0x0D1E, "GL_DEPTH_SCALE" }, - { 1, 0x0D1F, "GL_DEPTH_BIAS" }, - { 1, 0x0D30, "GL_MAX_EVAL_ORDER" }, - { 1, 0x0D31, "GL_MAX_LIGHTS" }, - { 1, 0x0D32, "GL_MAX_CLIP_PLANES" }, - { 1, 0x0D33, "GL_MAX_TEXTURE_SIZE" }, - { 1, 0x0D34, "GL_MAX_PIXEL_MAP_TABLE" }, - { 1, 0x0D35, "GL_MAX_ATTRIB_STACK_DEPTH" }, - { 1, 0x0D36, "GL_MAX_MODELVIEW_STACK_DEPTH" }, - { 1, 0x0D37, "GL_MAX_NAME_STACK_DEPTH" }, - { 1, 0x0D38, "GL_MAX_PROJECTION_STACK_DEPTH" }, - { 1, 0x0D39, "GL_MAX_TEXTURE_STACK_DEPTH" }, - { 2, 0x0D3A, "GL_MAX_VIEWPORT_DIMS" }, - { 1, 0x0D3B, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH" }, - { 1, 0x0D50, "GL_SUBPIXEL_BITS" }, - { 1, 0x0D51, "GL_INDEX_BITS" }, - { 1, 0x0D52, "GL_RED_BITS" }, - { 1, 0x0D53, "GL_GREEN_BITS" }, - { 1, 0x0D54, "GL_BLUE_BITS" }, - { 1, 0x0D55, "GL_ALPHA_BITS" }, - { 1, 0x0D56, "GL_DEPTH_BITS" }, - { 1, 0x0D57, "GL_STENCIL_BITS" }, - { 1, 0x0D58, "GL_ACCUM_RED_BITS" }, - { 1, 0x0D59, "GL_ACCUM_GREEN_BITS" }, - { 1, 0x0D5A, "GL_ACCUM_BLUE_BITS" }, - { 1, 0x0D5B, "GL_ACCUM_ALPHA_BITS" }, - { 1, 0x0D70, "GL_NAME_STACK_DEPTH" }, - { 1, 0x0D80, "GL_AUTO_NORMAL" }, - { 1, 0x0D90, "GL_MAP1_COLOR_4" }, - { 1, 0x0D91, "GL_MAP1_INDEX" }, - { 1, 0x0D92, "GL_MAP1_NORMAL" }, - { 1, 0x0D93, "GL_MAP1_TEXTURE_COORD_1" }, - { 1, 0x0D94, "GL_MAP1_TEXTURE_COORD_2" }, - { 1, 0x0D95, "GL_MAP1_TEXTURE_COORD_3" }, - { 1, 0x0D96, "GL_MAP1_TEXTURE_COORD_4" }, - { 1, 0x0D97, "GL_MAP1_VERTEX_3" }, - { 1, 0x0D98, "GL_MAP1_VERTEX_4" }, - { 1, 0x0DB0, "GL_MAP2_COLOR_4" }, - { 1, 0x0DB1, "GL_MAP2_INDEX" }, - { 1, 0x0DB2, "GL_MAP2_NORMAL" }, - { 1, 0x0DB3, "GL_MAP2_TEXTURE_COORD_1" }, - { 1, 0x0DB4, "GL_MAP2_TEXTURE_COORD_2" }, - { 1, 0x0DB5, "GL_MAP2_TEXTURE_COORD_3" }, - { 1, 0x0DB6, "GL_MAP2_TEXTURE_COORD_4" }, - { 1, 0x0DB7, "GL_MAP2_VERTEX_3" }, - { 1, 0x0DB8, "GL_MAP2_VERTEX_4" }, - { 2, 0x0DD0, "GL_MAP1_GRID_DOMAIN" }, - { 1, 0x0DD1, "GL_MAP1_GRID_SEGMENTS" }, - { 4, 0x0DD2, "GL_MAP2_GRID_DOMAIN" }, - { 2, 0x0DD3, "GL_MAP2_GRID_SEGMENTS" }, - { 1, 0x0DE0, "GL_TEXTURE_1D" }, - { 1, 0x0DE1, "GL_TEXTURE_2D" }, - { 1, 0x0DF1, "GL_FEEDBACK_BUFFER_SIZE" }, - { 1, 0x0DF2, "GL_FEEDBACK_BUFFER_TYPE" }, - { 1, 0x0DF4, "GL_SELECTION_BUFFER_SIZE" }, - { 1, 0x2200, "GL_TEXTURE_ENV_MODE" }, - { 4, 0x2201, "GL_TEXTURE_ENV_COLOR" }, - { 1, 0x2A00, "GL_POLYGON_OFFSET_UNITS" }, - { 1, 0x3000, "GL_CLIP_PLANE0" }, - { 1, 0x3001, "GL_CLIP_PLANE1" }, - { 1, 0x3002, "GL_CLIP_PLANE2" }, - { 1, 0x3003, "GL_CLIP_PLANE3" }, - { 1, 0x3004, "GL_CLIP_PLANE4" }, - { 1, 0x3005, "GL_CLIP_PLANE5" }, - { 1, 0x4000, "GL_LIGHT0" }, - { 1, 0x4001, "GL_LIGHT1" }, - { 1, 0x4002, "GL_LIGHT2" }, - { 1, 0x4003, "GL_LIGHT3" }, - { 1, 0x4004, "GL_LIGHT4" }, - { 1, 0x4005, "GL_LIGHT5" }, - { 1, 0x4006, "GL_LIGHT6" }, - { 1, 0x4007, "GL_LIGHT7" }, - { 4, 0x8005, "GL_BLEND_COLOR_EXT" }, - { 1, 0x8009, "GL_BLEND_EQUATION" }, - { 1, 0x8010, "GL_CONVOLUTION_1D_EXT" }, - { 1, 0x8011, "GL_CONVOLUTION_2D_EXT" }, - { 1, 0x8012, "GL_SEPARABLE_2D_EXT" }, - { 1, 0x801C, "GL_POST_CONVOLUTION_RED_SCALE_EXT" }, - { 1, 0x801D, "GL_POST_CONVOLUTION_GREEN_SCALE_EXT" }, - { 1, 0x801E, "GL_POST_CONVOLUTION_BLUE_SCALE_EXT" }, - { 1, 0x801F, "GL_POST_CONVOLUTION_ALPHA_SCALE_EXT" }, - { 1, 0x8020, "GL_POST_CONVOLUTION_RED_BIAS_EXT" }, - { 1, 0x8021, "GL_POST_CONVOLUTION_GREEN_BIAS_EXT" }, - { 1, 0x8022, "GL_POST_CONVOLUTION_BLUE_BIAS_EXT" }, - { 1, 0x8023, "GL_POST_CONVOLUTION_ALPHA_BIAS_EXT" }, - { 1, 0x8024, "GL_HISTOGRAM" }, - { 1, 0x802E, "GL_MINMAX" }, - { 1, 0x8038, "GL_POLYGON_OFFSET_FACTOR" }, - { 1, 0x8039, "GL_POLYGON_OFFSET_BIAS_EXT" }, - { 1, 0x803A, "GL_RESCALE_NORMAL" }, - { 1, 0x8068, "GL_TEXTURE_BINDING_1D" }, - { 1, 0x8069, "GL_TEXTURE_BINDING_2D" }, - { 1, 0x806A, "GL_TEXTURE_BINDING_3D" }, - { 1, 0x806B, "GL_PACK_SKIP_IMAGES_EXT" }, - { 1, 0x806C, "GL_PACK_IMAGE_HEIGHT_EXT" }, - { 1, 0x806D, "GL_UNPACK_SKIP_IMAGES_EXT" }, - { 1, 0x806E, "GL_UNPACK_IMAGE_HEIGHT_EXT" }, - { 1, 0x806F, "GL_TEXTURE_3D" }, - { 1, 0x8073, "GL_MAX_3D_TEXTURE_SIZE" }, - { 1, 0x8074, "GL_VERTEX_ARRAY" }, - { 1, 0x8075, "GL_NORMAL_ARRAY" }, - { 1, 0x8076, "GL_COLOR_ARRAY" }, - { 1, 0x8077, "GL_INDEX_ARRAY" }, - { 1, 0x8078, "GL_TEXTURE_COORD_ARRAY" }, - { 1, 0x8079, "GL_EDGE_FLAG_ARRAY" }, - { 1, 0x807A, "GL_VERTEX_ARRAY_SIZE" }, - { 1, 0x807B, "GL_VERTEX_ARRAY_TYPE" }, - { 1, 0x807C, "GL_VERTEX_ARRAY_STRIDE" }, - { 1, 0x807D, "GL_VERTEX_ARRAY_COUNT_EXT" }, - { 1, 0x807E, "GL_NORMAL_ARRAY_TYPE" }, - { 1, 0x807F, "GL_NORMAL_ARRAY_STRIDE" }, - { 1, 0x8080, "GL_NORMAL_ARRAY_COUNT_EXT" }, - { 1, 0x8081, "GL_COLOR_ARRAY_SIZE" }, - { 1, 0x8082, "GL_COLOR_ARRAY_TYPE" }, - { 1, 0x8083, "GL_COLOR_ARRAY_STRIDE" }, - { 1, 0x8084, "GL_COLOR_ARRAY_COUNT_EXT" }, - { 1, 0x8085, "GL_INDEX_ARRAY_TYPE" }, - { 1, 0x8086, "GL_INDEX_ARRAY_STRIDE" }, - { 1, 0x8087, "GL_INDEX_ARRAY_COUNT_EXT" }, - { 1, 0x8088, "GL_TEXTURE_COORD_ARRAY_SIZE" }, - { 1, 0x8089, "GL_TEXTURE_COORD_ARRAY_TYPE" }, - { 1, 0x808A, "GL_TEXTURE_COORD_ARRAY_STRIDE" }, - { 1, 0x808B, "GL_TEXTURE_COORD_ARRAY_COUNT_EXT" }, - { 1, 0x808C, "GL_EDGE_FLAG_ARRAY_STRIDE" }, - { 1, 0x808D, "GL_EDGE_FLAG_ARRAY_COUNT_EXT" }, - { 1, 0x809D, "GL_MULTISAMPLE_ARB" }, - { 1, 0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE_ARB" }, - { 1, 0x809F, "GL_SAMPLE_ALPHA_TO_ONE_ARB" }, - { 1, 0x80A0, "GL_SAMPLE_COVERAGE_ARB" }, - { 1, 0x80A8, "GL_SAMPLE_BUFFERS_ARB" }, - { 1, 0x80A9, "GL_SAMPLES_ARB" }, - { 1, 0x80AA, "GL_SAMPLE_COVERAGE_VALUE_ARB" }, - { 1, 0x80AB, "GL_SAMPLE_COVERAGE_INVERT_ARB" }, - { 16, 0x80B1, "GL_COLOR_MATRIX_SGI" }, - { 1, 0x80B2, "GL_COLOR_MATRIX_STACK_DEPTH_SGI" }, - { 1, 0x80B3, "GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI" }, - { 1, 0x80B4, "GL_POST_COLOR_MATRIX_RED_SCALE_SGI" }, - { 1, 0x80B5, "GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI" }, - { 1, 0x80B6, "GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI" }, - { 1, 0x80B7, "GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI" }, - { 1, 0x80B8, "GL_POST_COLOR_MATRIX_RED_BIAS_SGI" }, - { 1, 0x80B9, "GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI" }, - { 1, 0x80BA, "GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI" }, - { 1, 0x80BB, "GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI" }, - { 1, 0x80BC, "GL_TEXTURE_COLOR_TABLE_SGI" }, - { 1, 0x80C8, "GL_BLEND_DST_RGB_EXT" }, - { 1, 0x80C9, "GL_BLEND_SRC_RGB_EXT" }, - { 1, 0x80CA, "GL_BLEND_DST_ALPHA_EXT" }, - { 1, 0x80CB, "GL_BLEND_SRC_ALPHA_EXT" }, - { 1, 0x80D0, "GL_COLOR_TABLE_SGI" }, - { 1, 0x80D1, "GL_POST_CONVOLUTION_COLOR_TABLE_SGI" }, - { 1, 0x80D2, "GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI" }, - { 1, 0x80E8, "GL_MAX_ELEMENTS_VERTICES" }, - { 1, 0x80E9, "GL_MAX_ELEMENTS_INDICES" }, - { 1, 0x8126, "GL_POINT_SIZE_MIN_EXT" }, - { 1, 0x8127, "GL_POINT_SIZE_MAX_EXT" }, - { 1, 0x8128, "GL_POINT_FADE_THRESHOLD_SIZE_EXT" }, - { 3, 0x8129, "GL_DISTANCE_ATTENUATION_EXT" }, - { 1, 0x8149, "GL_SPRITE_MODE_SGIX" }, - { 3, 0x814A, "GL_SPRITE_AXIS_SGIX " }, - { 3, 0x814B, "GL_SPRITE_TRANSLATION_SGIX" }, - { 4, 0x817E, "GL_REFERENCE_PLANE_EQUATION_SGIX" }, - { 1, 0x8192, "GL_GENERATE_MIPMAP_HINT_SGIS" }, - { 1, 0x81A8, "GL_ARRAY_ELEMENT_LOCK_FIRST_EXT" }, - { 1, 0x81A9, "GL_ARRAY_ELEMENT_LOCK_COUNT_EXT" }, - { 1, 0x81F8, "GL_LIGHT_MODEL_COLOR_CONTROL" }, - { 1, 0x81FB, "GL_SHARED_TEXTURE_PALETTE_EXT" }, - { 1, 0x8450, "GL_FOG_COORDINATE_SOURCE_EXT" }, - { 1, 0x8453, "GL_CURRENT_FOG_COORDINATE_EXT" }, - { 1, 0x8454, "GL_FOG_COORDINATE_ARRAY_TYPE_EXT" }, - { 1, 0x8455, "GL_FOG_COORDINATE_ARRAY_STRIDE_EXT" }, - { 1, 0x8457, "GL_FOG_COORDINATE_ARRAY_EXT" }, - { 1, 0x8458, "GL_COLOR_SUM_EXT" }, - { 4, 0x8459, "GL_CURRENT_SECONDARY_COLOR_EXT" }, - { 1, 0x845A, "GL_SECONDARY_COLOR_ARRAY_SIZE_EXT" }, - { 1, 0x845B, "GL_SECONDARY_COLOR_ARRAY_TYPE_EXT" }, - { 1, 0x845C, "GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT" }, - { 1, 0x845E, "GL_SECONDARY_COLOR_ARRAY_EXT" }, - { 4, 0x845F, "GL_CURRENT_RASTER_SECONDARY_COLOR" }, - { 2, 0x846D, "GL_ALIASED_POINT_SIZE_RANGE" }, - { 2, 0x846E, "GL_ALIASED_LINE_WIDTH_RANGE" }, - { 1, 0x84E0, "GL_ACTIVE_TEXTURE_ARB" }, - { 1, 0x84E1, "GL_CLIENT_ACTIVE_TEXTURE_ARB" }, - { 1, 0x84E2, "GL_MAX_TEXTURE_UNITS_ARB" }, - { 16, 0x84E3, "GL_TRANSPOSE_MODELVIEW_MATRIX_ARB" }, - { 16, 0x84E4, "GL_TRANSPOSE_PROJECTION_MATRIX_ARB" }, - { 16, 0x84E5, "GL_TRANSPOSE_TEXTURE_MATRIX_ARB" }, - { 16, 0x84E6, "GL_TRANSPOSE_COLOR_MATRIX_ARB" }, - { 1, 0x84E8, "GL_MAX_RENDERBUFFER_SIZE_EXT" }, - { 1, 0x84EF, "GL_TEXTURE_COMPRESSION_HINT_ARB" }, - { 1, 0x84F5, "GL_TEXTURE_RECTANGLE_NV" }, - { 1, 0x84F6, "GL_TEXTURE_BINDING_RECTANGLE_NV" }, - { 1, 0x84F8, "GL_MAX_RECTANGLE_TEXTURE_SIZE_NV" }, - { 1, 0x84FD, "GL_MAX_TEXTURE_LOD_BIAS_EXT" }, - { 1, 0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT" }, - { 1, 0x8504, "GL_MAX_SHININESS_NV" }, - { 1, 0x8505, "GL_MAX_SPOT_EXPONENT_NV" }, - { 1, 0x8513, "GL_TEXTURE_CUBE_MAP_ARB" }, - { 1, 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP_ARB" }, - { 1, 0x851C, "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB" }, - { 1, 0x854D, "GL_MAX_GENERAL_COMBINERS_NV" }, - { 1, 0x85B2, "GL_UNPACK_CLIENT_STORAGE_APPLE" }, - { 1, 0x8620, "GL_VERTEX_PROGRAM_ARB" }, - { 1, 0x862E, "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB" }, - { 1, 0x862F, "GL_MAX_PROGRAM_MATRICES_ARB" }, - { 1, 0x8640, "GL_CURRENT_MATRIX_STACK_DEPTH_ARB" }, - { 16, 0x8641, "GL_CURRENT_MATRIX_ARB" }, - { 1, 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE_ARB" }, - { 1, 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE_ARB" }, - { 1, 0x864A, "GL_VERTEX_PROGRAM_BINDING_NV" }, - { 1, 0x864B, "GL_PROGRAM_ERROR_POSITION_ARB" }, - { 1, 0x8650, "GL_VERTEX_ATTRIB_ARRAY0_NV" }, - { 1, 0x8651, "GL_VERTEX_ATTRIB_ARRAY1_NV" }, - { 1, 0x8652, "GL_VERTEX_ATTRIB_ARRAY2_NV" }, - { 1, 0x8653, "GL_VERTEX_ATTRIB_ARRAY3_NV" }, - { 1, 0x8654, "GL_VERTEX_ATTRIB_ARRAY4_NV" }, - { 1, 0x8655, "GL_VERTEX_ATTRIB_ARRAY5_NV" }, - { 1, 0x8656, "GL_VERTEX_ATTRIB_ARRAY6_NV" }, - { 1, 0x8657, "GL_VERTEX_ATTRIB_ARRAY7_NV" }, - { 1, 0x8658, "GL_VERTEX_ATTRIB_ARRAY8_NV" }, - { 1, 0x8659, "GL_VERTEX_ATTRIB_ARRAY9_NV" }, - { 1, 0x865A, "GL_VERTEX_ATTRIB_ARRAY10_NV" }, - { 1, 0x865B, "GL_VERTEX_ATTRIB_ARRAY11_NV" }, - { 1, 0x865C, "GL_VERTEX_ATTRIB_ARRAY12_NV" }, - { 1, 0x865D, "GL_VERTEX_ATTRIB_ARRAY13_NV" }, - { 1, 0x865E, "GL_VERTEX_ATTRIB_ARRAY14_NV" }, - { 1, 0x865F, "GL_VERTEX_ATTRIB_ARRAY15_NV" }, - { 1, 0x8660, "GL_MAP1_VERTEX_ATTRIB0_4_NV" }, - { 1, 0x8661, "GL_MAP1_VERTEX_ATTRIB1_4_NV" }, - { 1, 0x8662, "GL_MAP1_VERTEX_ATTRIB2_4_NV" }, - { 1, 0x8663, "GL_MAP1_VERTEX_ATTRIB3_4_NV" }, - { 1, 0x8664, "GL_MAP1_VERTEX_ATTRIB4_4_NV" }, - { 1, 0x8665, "GL_MAP1_VERTEX_ATTRIB5_4_NV" }, - { 1, 0x8666, "GL_MAP1_VERTEX_ATTRIB6_4_NV" }, - { 1, 0x8667, "GL_MAP1_VERTEX_ATTRIB7_4_NV" }, - { 1, 0x8668, "GL_MAP1_VERTEX_ATTRIB8_4_NV" }, - { 1, 0x8669, "GL_MAP1_VERTEX_ATTRIB9_4_NV" }, - { 1, 0x866A, "GL_MAP1_VERTEX_ATTRIB10_4_NV" }, - { 1, 0x866B, "GL_MAP1_VERTEX_ATTRIB11_4_NV" }, - { 1, 0x866C, "GL_MAP1_VERTEX_ATTRIB12_4_NV" }, - { 1, 0x866D, "GL_MAP1_VERTEX_ATTRIB13_4_NV" }, - { 1, 0x866E, "GL_MAP1_VERTEX_ATTRIB14_4_NV" }, - { 1, 0x866F, "GL_MAP1_VERTEX_ATTRIB15_4_NV" }, - { 1, 0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB" }, - { 1, 0x8758, "GL_PACK_INVERT_MESA" }, - { 1, 0x87C5, "GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT" }, - { 1, 0x87C6, "GL_MAX_VERTEX_SHADER_VARIANTS_EXT" }, - { 1, 0x87C7, "GL_MAX_VERTEX_SHADER_INVARIANTS_EXT" }, - { 1, 0x87C8, "GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, - { 1, 0x87C9, "GL_MAX_VERTEX_SHADER_LOCALS_EXT" }, - { 1, 0x87CA, "GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT" }, - { 1, 0x87CB, "GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT" }, - { 1, 0x87CC, "GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, - { 1, 0x87CC, "GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, - { 1, 0x87CD, "GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT" }, - { 1, 0x8800, "GL_STENCIL_BACK_FUNC" }, - { 1, 0x8801, "GL_STENCIL_BACK_FAIL" }, - { 1, 0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL" }, - { 1, 0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS" }, - { 1, 0x8804, "GL_FRAGMENT_PROGRAM_ARB" }, - { 1, 0x8824, "GL_MAX_DRAW_BUFFERS_ARB" }, - { 1, 0x8825, "GL_DRAW_BUFFER0_ARB" }, - { 1, 0x8826, "GL_DRAW_BUFFER1_ARB" }, - { 1, 0x8827, "GL_DRAW_BUFFER2_ARB" }, - { 1, 0x8828, "GL_DRAW_BUFFER3_ARB" }, - { 1, 0x883D, "GL_BLEND_EQUATION_ALPHA_EXT" }, - { 1, 0x8861, "GL_POINT_SPRITE_NV" }, - { 1, 0x8863, "GL_POINT_SPRITE_R_MODE_NV" }, - { 1, 0x8868, "GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV" }, - { 1, 0x8869, "GL_MAX_VERTEX_ATTRIBS_ARB" }, - { 1, 0x8870, "GL_FRAGMENT_PROGRAM_NV" }, - { 1, 0x8871, "GL_MAX_TEXTURE_COORDS_ARB" }, - { 1, 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" }, - { 1, 0x8873, "GL_FRAGMENT_PROGRAM_BINDING_NV" }, - { 1, 0x8890, "GL_DEPTH_BOUNDS_TEST_EXT" }, - { 2, 0x8891, "GL_DEPTH_BOUNDS_EXT" }, - { 1, 0x8894, "GL_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x8896, "GL_VERTEX_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x8897, "GL_NORMAL_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x8898, "GL_COLOR_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x8899, "GL_INDEX_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x889A, "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x889B, "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x889C, "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB" }, - { 1, 0x889D, "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB" }, - { 16, 0x88B7, "GL_TRANSPOSE_CURRENT_MATRIX_ARB" }, - { 1, 0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING_EXT" }, - { 1, 0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING_EXT" }, - { 1, 0x8910, "GL_STENCIL_TEST_TWO_SIDE_EXT" }, - { 1, 0x8911, "GL_ACTIVE_STENCIL_FACE_EXT" }, - { 1, 0x896E, "GL_NUM_FRAGMENT_REGISTERS_ATI" }, - { 1, 0x896F, "GL_NUM_FRAGMENT_CONSTANTS_ATI" }, - { 1, 0x8970, "GL_NUM_PASSES_ATI" }, - { 1, 0x8971, "GL_NUM_INSTRUCTIONS_PER_PASS_ATI" }, - { 1, 0x8972, "GL_NUM_INSTRUCTIONS_TOTAL_ATI" }, - { 1, 0x8973, "GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI" }, - { 1, 0x8974, "GL_NUM_LOOPBACK_COMPONENTS_ATI" }, - { 1, 0x8975, "GL_COLOR_ALPHA_PAIRING_ATI" }, - { 1, 0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB" }, - { 1, 0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB" }, - { 1, 0x8B4B, "GL_MAX_VARYING_FLOATS_ARB" }, - { 1, 0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB" }, - { 1, 0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB" }, - { 1, 0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB" }, - { 1, 0x8B9A, "GL_IMPLEMENTATION_COLOR_READ_TYPE_OES" }, - { 1, 0x8B9B, "GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES" }, - { 1, 0x8BB0, "GL_FRAGMENT_PROGRAM_POSITION_MESA" }, - { 1, 0x8BB1, "GL_FRAGMENT_PROGRAM_CALLBACK_MESA" }, - { 1, 0x8BB4, "GL_VERTEX_PROGRAM_POSITION_MESA" }, - { 1, 0x8BB5, "GL_VERTEX_PROGRAM_CALLBACK_MESA" }, - { 1, 0x8CA0, "GL_POINT_SPRITE_COORD_ORIGIN" }, - { 1, 0x8CA3, "GL_STENCIL_BACK_REF" }, - { 1, 0x8CA4, "GL_STENCIL_BACK_VALUE_MASK" }, - { 1, 0x8CA6, "GL_FRAMEBUFFER_BINDING_EXT" }, - { 1, 0x8CA7, "GL_RENDERBUFFER_BINDING_EXT" }, - { 1, 0x8CDF, "GL_MAX_COLOR_ATTACHMENTS_EXT" }, - { 1, 0x19262, "GL_RASTER_POSITION_UNCLIPPED_IBM" }, -}; diff --git a/target-i386/helper.c b/target-i386/helper.c index f0c546d..2586aff 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -21,13 +21,14 @@ #include #include #include -#include #include "cpu.h" -#include "exec-all.h" #include "qemu-common.h" #include "kvm.h" -#include "kvm_x86.h" +#ifndef CONFIG_USER_ONLY +#include "sysemu.h" +#include "monitor.h" +#endif //#define DEBUG_MMU @@ -96,18 +97,19 @@ void cpu_reset(CPUX86State *env) env->mxcsr = 0x1f80; + env->pat = 0x0007040600070406ULL; + env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT; + memset(env->dr, 0, sizeof(env->dr)); env->dr[6] = DR6_FIXED_1; env->dr[7] = DR7_FIXED_1; cpu_breakpoint_remove_all(env, BP_CPU); cpu_watchpoint_remove_all(env, BP_CPU); - - env->mcg_status = 0; } void cpu_x86_close(CPUX86State *env) { - qemu_free(env); + g_free(env); } static void cpu_x86_version(CPUState *env, int *family, int *model) @@ -400,21 +402,10 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, fptag, env->mxcsr); for(i=0;i<8;i++) { -#if defined(USE_X86LDOUBLE) - union { - long double d; - struct { - uint64_t lower; - uint16_t upper; - } l; - } tmp; - tmp.d = env->fpregs[i].d; + CPU_LDoubleU u; + u.d = env->fpregs[i].d; cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x", - i, tmp.l.lower, tmp.l.upper); -#else - cpu_fprintf(f, "FPR%d=%016" PRIx64, - i, env->fpregs[i].mmx.q); -#endif + i, u.l.lower, u.l.upper); if ((i & 1) == 1) cpu_fprintf(f, "\n"); else @@ -556,7 +547,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) #if defined(CONFIG_USER_ONLY) int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write, int mmu_idx, int is_softmmu) + int is_write, int mmu_idx) { /* user mode only emulation */ is_write &= 1; @@ -583,7 +574,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 1 = generate PF fault */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write1, int mmu_idx, int is_softmmu) + int is_write1, int mmu_idx) { uint64_t ptep, pte; target_ulong pde_addr, pte_addr; @@ -1037,8 +1028,6 @@ int check_hw_breakpoints(CPUState *env, int force_dr6_update) static CPUDebugExcpHandler *prev_debug_excp_handler; -void raise_exception_env(int exception_index, CPUState *env); - static void breakpoint_handler(CPUState *env) { CPUBreakpoint *bp; @@ -1065,91 +1054,138 @@ static void breakpoint_handler(CPUState *env) prev_debug_excp_handler(env); } -/* This should come from sysemu.h - if we could include it here... */ -void qemu_system_reset_request(void); - -static void qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, - uint64_t mcg_status, uint64_t addr, uint64_t misc) +typedef struct MCEInjectionParams { + Monitor *mon; + CPUState *env; + int bank; + uint64_t status; + uint64_t mcg_status; + uint64_t addr; + uint64_t misc; + int flags; +} MCEInjectionParams; + +static void do_inject_x86_mce(void *data) { - uint64_t mcg_cap = cenv->mcg_cap; - uint64_t *banks = cenv->mce_banks; + MCEInjectionParams *params = data; + CPUState *cenv = params->env; + uint64_t *banks = cenv->mce_banks + 4 * params->bank; + + cpu_synchronize_state(cenv); /* - * if MSR_MCG_CTL is not all 1s, the uncorrected error - * reporting is disabled - */ - if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) && - cenv->mcg_ctl != ~(uint64_t)0) - return; - banks += 4 * bank; - /* - * if MSR_MCi_CTL is not all 1s, the uncorrected error - * reporting is disabled for the bank + * If there is an MCE exception being processed, ignore this SRAO MCE + * unless unconditional injection was requested. */ - if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0) + if (!(params->flags & MCE_INJECT_UNCOND_AO) + && !(params->status & MCI_STATUS_AR) + && (cenv->mcg_status & MCG_STATUS_MCIP)) { return; - if (status & MCI_STATUS_UC) { + } + + if (params->status & MCI_STATUS_UC) { + /* + * if MSR_MCG_CTL is not all 1s, the uncorrected error + * reporting is disabled + */ + if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) { + monitor_printf(params->mon, + "CPU %d: Uncorrected error reporting disabled\n", + cenv->cpu_index); + return; + } + + /* + * if MSR_MCi_CTL is not all 1s, the uncorrected error + * reporting is disabled for the bank + */ + if (banks[0] != ~(uint64_t)0) { + monitor_printf(params->mon, + "CPU %d: Uncorrected error reporting disabled for" + " bank %d\n", + cenv->cpu_index, params->bank); + return; + } + if ((cenv->mcg_status & MCG_STATUS_MCIP) || !(cenv->cr[4] & CR4_MCE_MASK)) { - fprintf(stderr, "injects mce exception while previous " - "one is in progress!\n"); + monitor_printf(params->mon, + "CPU %d: Previous MCE still in progress, raising" + " triple fault\n", + cenv->cpu_index); qemu_log_mask(CPU_LOG_RESET, "Triple fault\n"); qemu_system_reset_request(); return; } - if (banks[1] & MCI_STATUS_VAL) - status |= MCI_STATUS_OVER; - banks[2] = addr; - banks[3] = misc; - cenv->mcg_status = mcg_status; - banks[1] = status; + if (banks[1] & MCI_STATUS_VAL) { + params->status |= MCI_STATUS_OVER; + } + banks[2] = params->addr; + banks[3] = params->misc; + cenv->mcg_status = params->mcg_status; + banks[1] = params->status; cpu_interrupt(cenv, CPU_INTERRUPT_MCE); } else if (!(banks[1] & MCI_STATUS_VAL) || !(banks[1] & MCI_STATUS_UC)) { - if (banks[1] & MCI_STATUS_VAL) - status |= MCI_STATUS_OVER; - banks[2] = addr; - banks[3] = misc; - banks[1] = status; - } else + if (banks[1] & MCI_STATUS_VAL) { + params->status |= MCI_STATUS_OVER; + } + banks[2] = params->addr; + banks[3] = params->misc; + banks[1] = params->status; + } else { banks[1] |= MCI_STATUS_OVER; + } } -void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, - uint64_t mcg_status, uint64_t addr, uint64_t misc, - int broadcast) +void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank, + uint64_t status, uint64_t mcg_status, uint64_t addr, + uint64_t misc, int flags) { + MCEInjectionParams params = { + .mon = mon, + .env = cenv, + .bank = bank, + .status = status, + .mcg_status = mcg_status, + .addr = addr, + .misc = misc, + .flags = flags, + }; unsigned bank_num = cenv->mcg_cap & 0xff; CPUState *env; - int flag = 0; - if (bank >= bank_num || !(status & MCI_STATUS_VAL)) { + if (!cenv->mcg_cap) { + monitor_printf(mon, "MCE injection not supported\n"); return; } - - if (broadcast) { - if (!cpu_x86_support_mca_broadcast(cenv)) { - fprintf(stderr, "Current CPU does not support broadcast\n"); - return; - } + if (bank >= bank_num) { + monitor_printf(mon, "Invalid MCE bank number\n"); + return; + } + if (!(status & MCI_STATUS_VAL)) { + monitor_printf(mon, "Invalid MCE status code\n"); + return; + } + if ((flags & MCE_INJECT_BROADCAST) + && !cpu_x86_support_mca_broadcast(cenv)) { + monitor_printf(mon, "Guest CPU does not support MCA broadcast\n"); + return; } - if (kvm_enabled()) { - if (broadcast) { - flag |= MCE_BROADCAST; - } - - kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag); - } else { - qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc); - if (broadcast) { - for (env = first_cpu; env != NULL; env = env->next_cpu) { - if (cenv == env) { - continue; - } - qemu_inject_x86_mce(env, 1, MCI_STATUS_VAL | MCI_STATUS_UC, - MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0); + run_on_cpu(cenv, do_inject_x86_mce, ¶ms); + if (flags & MCE_INJECT_BROADCAST) { + params.bank = 1; + params.status = MCI_STATUS_VAL | MCI_STATUS_UC; + params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV; + params.addr = 0; + params.misc = 0; + for (env = first_cpu; env != NULL; env = env->next_cpu) { + if (cenv == env) { + continue; } + params.env = env; + run_on_cpu(cenv, do_inject_x86_mce, ¶ms); } } } @@ -1157,15 +1193,16 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, static void mce_init(CPUX86State *cenv) { - unsigned int bank, bank_num; + unsigned int bank; - if (((cenv->cpuid_version >> 8)&0xf) >= 6 - && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) { + if (((cenv->cpuid_version >> 8) & 0xf) >= 6 + && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) == + (CPUID_MCE | CPUID_MCA)) { cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF; cenv->mcg_ctl = ~(uint64_t)0; - bank_num = MCE_BANKS_DEF; - for (bank = 0; bank < bank_num; bank++) - cenv->mce_banks[bank*4] = ~(uint64_t)0; + for (bank = 0; bank < MCE_BANKS_DEF; bank++) { + cenv->mce_banks[bank * 4] = ~(uint64_t)0; + } } } @@ -1203,12 +1240,12 @@ CPUX86State *cpu_x86_init(const char *cpu_model) CPUX86State *env; static int inited; - env = qemu_mallocz(sizeof(CPUX86State)); + env = g_malloc0(sizeof(CPUX86State)); cpu_exec_init(env); env->cpu_model_str = cpu_model; - /* init various static tables */ - if (!inited) { + /* init various static tables used in TCG mode */ + if (tcg_enabled() && !inited) { inited = 1; optimize_flags_init(); #ifndef CONFIG_USER_ONLY @@ -1220,6 +1257,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model) cpu_x86_close(env); return NULL; } + env->cpuid_apic_id = env->cpu_index; mce_init(env); qemu_init_vcpu(env); @@ -1231,8 +1269,11 @@ CPUX86State *cpu_x86_init(const char *cpu_model) void do_cpu_init(CPUState *env) { int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI; + uint64_t pat = env->pat; + cpu_reset(env); env->interrupt_request = sipi; + env->pat = pat; apic_init_reset(env->apic_state); env->halted = !cpu_is_bsp(env); } diff --git a/target-i386/helper.h b/target-i386/helper.h index e3a2f56..761954e 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -85,9 +85,6 @@ DEF_HELPER_0(rdpmc, void) DEF_HELPER_0(rdmsr, void) DEF_HELPER_0(wrmsr, void) -/* opengl support by okdear */ -DEF_HELPER_0(opengl99, void) - DEF_HELPER_1(check_iob, void, i32) DEF_HELPER_1(check_iow, void, i32) DEF_HELPER_1(check_iol, void, i32) @@ -200,6 +197,7 @@ DEF_HELPER_2(lzcnt, tl, tl, int) /* MMX/SSE */ +DEF_HELPER_1(ldmxcsr, void, i32) DEF_HELPER_0(enter_mmx, void) DEF_HELPER_0(emms, void) DEF_HELPER_2(movq, void, ptr, ptr) diff --git a/target-i386/helper_gpi.c b/target-i386/helper_gpi.c deleted file mode 100644 index 83b47b1..0000000 --- a/target-i386/helper_gpi.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Virtio general purpose interface - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: - * YeongKyoon Lee - * DongKyun Yun - * - * 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. - * - * Contributors: - * - S-Core Co., Ltd - * - */ - -#define _XOPEN_SOURCE 600 - -#include -#include -#include -#include - -#include "qemu-common.h" -#include "qemu-log.h" -#include "helper_gpi.h" - -#include "sdb.h" -#include "tizen/src/debug_ch.h" -MULTI_DEBUG_CHANNEL(qemu, gpi); - -/** - * Global variables - * - */ -static struct object_ops *call_ops = NULL; - -/* do_call_gpi() - * - */ -static int sync_sdb_port(char *args_in, int args_len, char *r_buffer, int r_len) -{ - char tmp[32] = {0}; - - snprintf(tmp, sizeof(tmp)-1, "%d", get_sdb_base_port()); - - if( r_len < strlen(tmp) ){ - ERR("short return buffer length [%d < %d(%s)] \n", r_len, strlen(tmp), tmp); - return 0; - } - - memcpy(r_buffer, tmp, strlen(tmp)); - TRACE("sdb-port: => return [%s]\n", r_buffer); - - return 1; -} - -static int dummy_function(char *args_in, int args_len, char *r_buffer, int r_len) -{ - ERR("Need the specific operation \n"); - - return 1; -} - -static void do_call_init(void) -{ - int i; - - call_ops = qemu_mallocz(CAll_HANDLE_MAX*sizeof(object_ops_t) ); - - /* set dummy function */ - for( i = 0; i < CAll_HANDLE_MAX ; i++ ) { - call_ops[i].ftn = &dummy_function; - } - - /* init function */ - call_ops[FTN_SYNC_SDB_PORT].ftn = &sync_sdb_port; - - return; -} - - -int call_gpi(int pid, int ftn_num, char *in_args, int args_len, char *r_buffer, int r_len) -{ - static int init = 0; - int ret; - - TRACE("ftn_num(%d) args_len(%d) r_len(%d) \n", ftn_num, args_len, r_len); - - if( init == 0 ){ - do_call_init(); - init = 1; - } - - ret = call_ops[ftn_num].ftn(in_args, args_len, r_buffer, r_len); - TRACE("return [%s]\n", r_buffer); - - if(!ret){ - /* error */ - } - - return ret; -} diff --git a/target-i386/helper_gpi.h b/target-i386/helper_gpi.h deleted file mode 100644 index fea5463..0000000 --- a/target-i386/helper_gpi.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Virtio general purpose interface - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: - * YeongKyoon Lee - * DongKyun Yun - * - * 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. - * - * Contributors: - * - S-Core Co., Ltd - * - */ - -#ifndef GPI_H -#define GPI_H - -#define CAll_HANDLE_MAX 128 -#define FTN_SYNC_SDB_PORT 1 - -/* operations valid on all objects */ -typedef struct object_ops object_ops_t; -struct object_ops { - int (*ftn)(char *args_in, int args_len, char *r_buffer, int r_len); -}; - -int call_gpi(int pid, int ftn_num, char *in_args, int args_len, char *r_buffer, int r_len); - -#endif diff --git a/target-i386/helper_gpi_test.c b/target-i386/helper_gpi_test.c deleted file mode 100644 index bb5f19e..0000000 --- a/target-i386/helper_gpi_test.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include - -#define SIZE_OUT_HEADER (4*4) - -static inline int call_gpi(int fd, int args_len, int ret_len, int ftn_num, char *args_buf) -{ - int ret = 0; - //volatile int *i = (volatile int*)args_buf; - int *i = (int*)args_buf; - - /* i[0] = pid; ...is filled in by the kernel module for virtio GL */ - i[1] = args_len; - i[2] = ret_len; - i[3] = ftn_num; - - fprintf(stdout, "args_len(%d), ret_len(%d), ftn_num(%d) \n", i[1], i[2], i[3]); - - ret = write(fd, args_buf, args_len); - if( ret != args_len) { - perror("write fail"); - exit(0); - } - - return ret; -} - -int main(int argc, char** argv) -{ - - int fd; - int ftn_num; - char write_buf[4096] = {0}; - char read_buf[4096] = {0}; - - - if((fd = open("/dev/virt_gpi", O_RDWR)) == -1) { - perror("open"); - exit(0); - } - - if( argc >= 1 && argv[1] != NULL ){ - ftn_num = atoi(argv[1]); - }else{ - exit(0); - } - - if( argc >= 2 && argv[2] != NULL ){ - strcpy(write_buf, argv[2]); - } - - if(call_gpi(fd, SIZE_OUT_HEADER + strlen(write_buf), sizeof(read_buf), ftn_num, write_buf) <= 0) { - perror("call_gpi"); - exit(0); - } - - if(read(fd, read_buf, sizeof(read_buf)) <= 0){ - perror("read"); - exit(0); - } - - fprintf(stdout, "read_buf[%s] \n", read_buf); - - close(fd); - return 0; -} - - diff --git a/target-i386/helper_opengl.c b/target-i386/helper_opengl.c deleted file mode 100755 index 24400fc..0000000 --- a/target-i386/helper_opengl.c +++ /dev/null @@ -1,1434 +0,0 @@ -/* - * Host-side implementation of GL/GLX API - * - * Copyright (c) 2006,2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - -#ifdef _WIN32 -#ifndef _GNU_SOURCE - #define _GNU_SOURCE -#endif -#endif - -#define _XOPEN_SOURCE 600 - - -#include -#include -#include -#include -#include "exec.h" - -#ifndef _WIN32 -#include -#include -#else -#include - -typedef HDC GLDisplay; -HWND displayHWND; -#endif - -//## remove GCC warning -//#include "qemu-common.h" -//#include "opengl_func.h" -#include "helper_opengl.h" - -#define ENABLE_GL_LOG - -//#ifdef _WIN32 -//extern int do_function_call(Display dpy, int func_number, int pid, int* args, char* ret_string); -//#else -//extern int do_function_call(Display* dpy, int func_number, int pid, int* args, char* ret_string); -//#endif -extern int last_process_id; - -#ifndef _WIN32 -extern void sdl_set_opengl_window(int x, int y, int width, int height); -#endif - -#ifdef _WIN32 -static GLDisplay CreateDisplay(void) -{ - HWND hWnd; - WNDCLASS wc; - LPCSTR ClassName ="DISPLAY"; - HINSTANCE hInstance = 0; - - /* only register the window class once - use hInstance as a flag. */ - hInstance = GetModuleHandle(NULL); - wc.style = CS_OWNDC; - wc.lpfnWndProc = (WNDPROC)DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = ClassName; - - RegisterClass(&wc); - - displayHWND = CreateWindow(ClassName, ClassName, (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU ), - 0, 0, 10, 10, NULL, (HMENU)NULL, hInstance, NULL); - - - ShowWindow(hWnd, SW_HIDE); - - return GetDC(displayHWND); -} -#endif - -static int must_save = 0; - -static inline void* get_phys_mem_addr(const CPUState *env, target_ulong addr) -{ -#if 1 - void *ret; - ret = qemu_get_ram_ptr(addr); - - return ret; -#endif -#if 0 - int is_user, index; - index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - is_user = ((env->hflags & HF_CPL_MASK) == 3); - if (is_user == 0) - { - fprintf(stderr, "not in userland !!!\n"); - return NULL; - } - if (__builtin_expect(env->tlb_table[is_user][index].addr_code != - (addr & TARGET_PAGE_MASK), 0)) - { - target_ulong ret = cpu_get_phys_page_debug((CPUState *)env, addr); - if (ret == -1) - { - fprintf(stderr, "cpu_get_phys_page_debug(env, %x) == %x\n", addr, ret); - fprintf(stderr, "not in phys mem %x (%x %x)\n", addr, env->tlb_table[is_user][index].addr_code, addr & TARGET_PAGE_MASK); - fprintf(stderr, "cpu_x86_handle_mmu_fault = %d\n", - cpu_x86_handle_mmu_fault((CPUState*)env, addr, 0, 1, 1)); - return NULL; - } - else - { - if (ret + TARGET_PAGE_SIZE <= ldl_phys(0)) - { - //return phys_ram_base + ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1)); - //return qemu_get_buffer(ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1))); - //return ldl_phys(0) + ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1)); - return qemu_get_ram_ptr(ret + (((target_ulong)addr) & (TARGET_PAGE_SIZE - 1))); - } - else - { - fprintf(stderr, "cpu_get_phys_page_debug(env, %x) == %xp\n", addr, ret); - //fprintf(stderr, "ret=%x phys_ram_size=%x\n", ret, phys_ram_size); - fprintf(stderr, "ret=%x ldl_phys(0)=%x\n", ret, ldl_phys(0)); - return NULL; - } - } - } - else - { - return (void*)(addr + env->tlb_table[is_user][index].addend); - } -#endif -} -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -enum -{ - NOT_MAPPED, - MAPPED_CONTIGUOUS, - MAPPED_NOT_CONTIGUOUS -}; - -#define TARGET_ADDR_LOW_ALIGN(x) ((target_ulong)(x) & ~(TARGET_PAGE_SIZE - 1)) - -/* Return NOT_MAPPED if a page is not mapped into target physical memory */ -/* MAPPED_CONTIGUOUS if all pages are mapped into target physical memory and contiguous */ -/* MAPPED_NOT_CONTIGUOUS if all pages are mapped into target physical memory but not contiguous */ -static int get_target_mem_state(const CPUState *env, target_ulong target_addr, int len) -{ - target_ulong aligned_target_addr = TARGET_ADDR_LOW_ALIGN(target_addr); - int to_end_page = (long)aligned_target_addr + TARGET_PAGE_SIZE - (long)target_addr; - int ret = MAPPED_CONTIGUOUS; - - if (aligned_target_addr != target_addr) - { - void* phys_addr = get_phys_mem_addr(env, aligned_target_addr); - void* last_phys_addr = phys_addr; - if (phys_addr == 0) - { - return NOT_MAPPED; - } - if (len > to_end_page) - { - len -= to_end_page; - aligned_target_addr += TARGET_PAGE_SIZE; - int i; - for(i=0;i -#include - -static void (*anticrash_handler)(void*) = NULL; -static void (*show_stack_from_signal_handler)(int, int, int) = NULL; - -static void my_anticrash_sigsegv_handler(int signum, siginfo_t* info, void* ptr) -{ - static int counter = 0; - counter++; - - printf("oops\n"); - - /*if (show_stack_from_signal_handler && counter == 1) - { - struct ucontext* ctxt = (struct ucontext*)ptr; - show_stack_from_signal_handler(10, ctxt->uc_mcontext.gregs[REG_EBP], ctxt->uc_mcontext.gregs[REG_ESP]); - }*/ - anticrash_handler(ptr); - - counter--; -} -#endif - -#ifdef _WIN32 - -static int decode_call_int(CPUState *env, int func_number, int pid, target_ulong target_ret_string, - target_ulong in_args, target_ulong in_args_size) -{ - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int ret_type = signature->ret_type; - //int has_out_parameters = signature->has_out_parameters; - int nb_args = signature->nb_args; - int* args_type = signature->args_type; - int i; - int ret; - int* args_size = NULL; - target_ulong saved_out_ptr[50]; - static char* ret_string = NULL; - static target_ulong args[50]; - static GLDisplay dpy = 0; - - if (last_func_number == _exit_process_func && func_number == _exit_process_func) - { - last_func_number = -1; - return 0; - } - -#if 0 - if (last_process_id == 0) - { - last_process_id = pid; - } - else if (last_process_id != pid) - { - fprintf(stderr, "damnit. I don't support (yet) opengl calls coming from // processes... Sorry !\n"); - return 0; - } -#else - last_process_id = pid; -#endif - - if (dpy == NULL) - { - dpy = CreateDisplay(); - //init_process_tab(); - create_process_tab(NULL); - - ret_string = malloc(32768); - my_strlen = strlen; - } - - reset_host_offset(); - - if (nb_args) - { - if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * nb_args) == 0) - { - fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); - fprintf(stderr, "cannot get call parameters\n"); - last_process_id = 0; - return 0; - } - - args_size = (int*)get_host_read_pointer(env, in_args_size, sizeof(int) * nb_args); - if (args_size == NULL) - { - fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); - fprintf(stderr, "cannot get call parameters size\n"); - last_process_id = 0; - return 0; - } - } - - if (func_number == _serialized_calls_func) - { - int command_buffer_size = args_size[0]; - const void* command_buffer = get_host_read_pointer(env, args[0], command_buffer_size); - int commmand_buffer_offset = 0; - args_size = NULL; -#ifdef ENABLE_GL_LOG - if (must_save) write_gl_debug_cmd_short(_serialized_calls_func); -#endif - - while(commmand_buffer_offset < command_buffer_size) - { - func_number = *(short*)(command_buffer + commmand_buffer_offset); - if( ! (func_number >= 0 && func_number < GL_N_CALLS) ) - { - fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed at " - "commmand_buffer_offset=%d (command_buffer_size=%d)\n", - commmand_buffer_offset, command_buffer_size); - return 0; - } - commmand_buffer_offset += sizeof(short); -#ifdef ENABLE_GL_LOG - if (must_save) write_gl_debug_cmd_short(func_number); -#endif - - signature = (Signature*)tab_opengl_calls[func_number]; - ret_type = signature->ret_type; - assert(ret_type == TYPE_NONE); - nb_args = signature->nb_args; - args_type = signature->args_type; - - for(i=0;ikqemu_enabled) - *(int*)args[1] = 2; - else -#endif -#endif - *(int*)args[1] = 1; - ret = 0; - } - else - { - ret = do_function_call(dpy, func_number, pid, args, ret_string); - } -#ifdef ENABLE_GL_LOG - if (must_save && func_number == glXGetVisualFromFBConfig_func) - { - write_gl_debug_cmd_int(ret); - } -#endif - for(i=0;iret_type; - //int has_out_parameters = signature->has_out_parameters; - int nb_args = signature->nb_args; - int* args_type = signature->args_type; - int i; - int ret; - int* args_size = NULL; - target_ulong saved_out_ptr[50]; - static char* ret_string = NULL; - static target_ulong args[50]; - static Display* dpy = NULL; - - if (last_func_number == _exit_process_func && func_number == _exit_process_func) - { - last_func_number = -1; - return 0; - } - - #if 0 - if (last_process_id == 0) - { - last_process_id = pid; - } - else if (last_process_id != pid) - { - fprintf(stderr, "damnit. I don't support (yet) opengl calls coming from // processes... Sorry !\n"); - return 0; - } - #else - last_process_id = pid; - #endif - - if (dpy == NULL) - { - void *handle = dlopen("libanticrash.so", RTLD_LAZY); - if (handle) - { - anticrash_handler = dlsym(handle, "anticrash_handler"); - if (anticrash_handler) - { - fprintf(stderr, "anticrash handler enabled\n"); - struct sigaction sigsegv_action; - struct sigaction old_sigsegv_action; - - sigsegv_action.sa_sigaction = my_anticrash_sigsegv_handler; - sigemptyset(&(sigsegv_action.sa_mask)); - sigsegv_action.sa_flags = SA_SIGINFO | SA_NOMASK; - sigaction(SIGSEGV, &sigsegv_action, &old_sigsegv_action); - } - } - handle = dlopen("libgetstack.so", RTLD_LAZY); - if (handle) - { - show_stack_from_signal_handler = dlsym(handle, "show_stack_from_signal_handler"); - } - - dpy = XOpenDisplay(NULL); - /*init_process_tab();*/ - create_process_tab(NULL); - - ret_string = malloc(32768); - my_strlen = strlen; - } - - reset_host_offset(); - - if (nb_args) - { - if (memcpy_target_to_host(env, args, in_args, sizeof(target_ulong) * nb_args) == 0) - { - fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); - fprintf(stderr, "cannot get call parameters\n"); - last_process_id = 0; - return 0; - } - - args_size = (int*)get_host_read_pointer(env, in_args_size, sizeof(int) * nb_args); - if (args_size == NULL) - { - fprintf(stderr, "call %s pid=%d\n", tab_opengl_calls_name[func_number], pid); - fprintf(stderr, "cannot get call parameters size\n"); - last_process_id = 0; - return 0; - } - } - if (func_number == _serialized_calls_func) - { - int command_buffer_size = args_size[0]; - const void* command_buffer = get_host_read_pointer(env, args[0], command_buffer_size); - int commmand_buffer_offset = 0; - args_size = NULL; -#ifdef ENABLE_GL_LOG - if (must_save) write_gl_debug_cmd_short(_serialized_calls_func); -#endif - - while(commmand_buffer_offset < command_buffer_size) - { - func_number = *(short*)(command_buffer + commmand_buffer_offset); - if( ! (func_number >= 0 && func_number < GL_N_CALLS) ) - { - fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed at " - "commmand_buffer_offset=%d (command_buffer_size=%d)\n", - commmand_buffer_offset, command_buffer_size); - return 0; - } - commmand_buffer_offset += sizeof(short); -#ifdef ENABLE_GL_LOG - if (must_save) write_gl_debug_cmd_short(func_number); -#endif - - signature = (Signature*)tab_opengl_calls[func_number]; - ret_type = signature->ret_type; - assert(ret_type == TYPE_NONE); - nb_args = signature->nb_args; - args_type = signature->args_type; - for(i=0;ikqemu_enabled) - *(int*)args[1] = 2; - else -#endif -#endif - *(int*)args[1] = 1; - ret = 0; - } - else - { - - ret = do_function_call(dpy, func_number, pid, (void*)args, ret_string); - } -#ifdef ENABLE_GL_LOG - if (must_save && func_number == glXGetVisualFromFBConfig_func) - { - write_gl_debug_cmd_int(ret); - } -#endif - for(i=0;icr[3]); - if( ! (func_number >= 0 && func_number < GL_N_CALLS) ) - { - fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed(%d)\n", func_number); - return 0; - } - ret = decode_call_int(env, func_number, pid, target_ret_string, in_args, in_args_size); - if (func_number == glXCreateContext_func) - { - fprintf(stderr, "ret of glXCreateContext_func = %d\n", ret); - } - return ret; -} - -//void helper_opengl() -void helper_opengl(CPUState *env) -{ - doing_opengl = 1; - - env->regs[R_EAX] = decode_call(env, - env->regs[R_EAX], - env->regs[R_EBX], - env->regs[R_ECX], - env->regs[R_EDX], - env->regs[R_ESI]); - - doing_opengl = 0; -} diff --git a/target-i386/helper_opengl.h b/target-i386/helper_opengl.h deleted file mode 100644 index ed599cb..0000000 --- a/target-i386/helper_opengl.h +++ /dev/null @@ -1,5 +0,0 @@ -#include "qemu-common.h" -#include "opengl_func.h" - -extern int decode_call(CPUState *env, int func_number, int pid, target_ulong target_ret_string, target_ulong in_args, target_ulong in_args_size); -extern void helper_opengl(CPUState *env); diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 05010bb..5bfc21f 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -18,6 +18,7 @@ #include #include +#include #include "qemu-common.h" #include "sysemu.h" @@ -28,12 +29,7 @@ #include "hw/pc.h" #include "hw/apic.h" #include "ioport.h" -#include "kvm_x86.h" -#ifdef CONFIG_KVM_PARA -#include -#endif -// //#define DEBUG_KVM #ifdef DEBUG_KVM @@ -63,9 +59,9 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { static bool has_msr_star; static bool has_msr_hsave_pa; -#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) +static bool has_msr_tsc_deadline; static bool has_msr_async_pf_en; -#endif +static bool has_msr_misc_enable; static int lm_capable_kernel; static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) @@ -74,7 +70,7 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) int r, size; size = sizeof(*cpuid) + max * sizeof(*cpuid->entries); - cpuid = (struct kvm_cpuid2 *)qemu_mallocz(size); + cpuid = (struct kvm_cpuid2 *)g_malloc0(size); cpuid->nent = max; r = kvm_ioctl(s, KVM_GET_SUPPORTED_CPUID, cpuid); if (r == 0 && cpuid->nent >= max) { @@ -82,7 +78,7 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) } if (r < 0) { if (r == -E2BIG) { - qemu_free(cpuid); + g_free(cpuid); return NULL; } else { fprintf(stderr, "KVM_GET_SUPPORTED_CPUID failed: %s\n", @@ -93,22 +89,51 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) return cpuid; } -uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, +struct kvm_para_features { + int cap; + int feature; +} para_features[] = { + { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE }, + { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY }, + { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, + { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF }, + { -1, -1 } +}; + +static int get_para_features(KVMState *s) +{ + int i, features = 0; + + for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) { + if (kvm_check_extension(s, para_features[i].cap)) { + features |= (1 << para_features[i].feature); + } + } + + return features; +} + + +uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, uint32_t index, int reg) { struct kvm_cpuid2 *cpuid; int i, max; uint32_t ret = 0; uint32_t cpuid_1_edx; + int has_kvm_features = 0; max = 1; - while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) { + while ((cpuid = try_get_cpuid(s, max)) == NULL) { max *= 2; } for (i = 0; i < cpuid->nent; ++i) { if (cpuid->entries[i].function == function && cpuid->entries[i].index == index) { + if (cpuid->entries[i].function == KVM_CPUID_FEATURES) { + has_kvm_features = 1; + } switch (reg) { case R_EAX: ret = cpuid->entries[i].eax; @@ -130,7 +155,7 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, /* On Intel, kvm returns cpuid according to the Intel spec, * so add missing bits according to the AMD spec: */ - cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, 0, R_EDX); + cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX); ret |= cpuid_1_edx & 0x183f7ff; break; } @@ -139,42 +164,49 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, } } - qemu_free(cpuid); + g_free(cpuid); + + /* fallback for older kernels */ + if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) { + ret = get_para_features(s); + } return ret; } -#ifdef CONFIG_KVM_PARA -struct kvm_para_features { - int cap; - int feature; -} para_features[] = { - { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE }, - { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY }, - { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, -#ifdef KVM_CAP_ASYNC_PF - { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF }, -#endif - { -1, -1 } -}; +typedef struct HWPoisonPage { + ram_addr_t ram_addr; + QLIST_ENTRY(HWPoisonPage) list; +} HWPoisonPage; + +static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list = + QLIST_HEAD_INITIALIZER(hwpoison_page_list); -static int get_para_features(CPUState *env) +static void kvm_unpoison_all(void *param) { - int i, features = 0; + HWPoisonPage *page, *next_page; - for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) { - if (kvm_check_extension(env->kvm_state, para_features[i].cap)) { - features |= (1 << para_features[i].feature); + QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) { + QLIST_REMOVE(page, list); + qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE); + g_free(page); + } +} + +static void kvm_hwpoison_page_add(ram_addr_t ram_addr) +{ + HWPoisonPage *page; + + QLIST_FOREACH(page, &hwpoison_page_list, list) { + if (page->ram_addr == ram_addr) { + return; } } -#ifdef KVM_CAP_ASYNC_PF - has_msr_async_pf_en = features & (1 << KVM_FEATURE_ASYNC_PF); -#endif - return features; + page = g_malloc(sizeof(HWPoisonPage)); + page->ram_addr = ram_addr; + QLIST_INSERT_HEAD(&hwpoison_page_list, page, list); } -#endif -#ifdef KVM_CAP_MCE static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap, int *max_banks) { @@ -188,117 +220,129 @@ static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap, return -ENOSYS; } -static int kvm_setup_mce(CPUState *env, uint64_t *mcg_cap) +static void kvm_mce_inject(CPUState *env, target_phys_addr_t paddr, int code) { - return kvm_vcpu_ioctl(env, KVM_X86_SETUP_MCE, mcg_cap); -} + uint64_t status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN | + MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S; + uint64_t mcg_status = MCG_STATUS_MCIP; -static int kvm_set_mce(CPUState *env, struct kvm_x86_mce *m) -{ - return kvm_vcpu_ioctl(env, KVM_X86_SET_MCE, m); + if (code == BUS_MCEERR_AR) { + status |= MCI_STATUS_AR | 0x134; + mcg_status |= MCG_STATUS_EIPV; + } else { + status |= 0xc0; + mcg_status |= MCG_STATUS_RIPV; + } + cpu_x86_inject_mce(NULL, env, 9, status, mcg_status, paddr, + (MCM_ADDR_PHYS << 6) | 0xc, + cpu_x86_support_mca_broadcast(env) ? + MCE_INJECT_BROADCAST : 0); } -static int kvm_get_msr(CPUState *env, struct kvm_msr_entry *msrs, int n) +static void hardware_memory_error(void) { - struct kvm_msrs *kmsrs = qemu_malloc(sizeof *kmsrs + n * sizeof *msrs); - int r; - - kmsrs->nmsrs = n; - memcpy(kmsrs->entries, msrs, n * sizeof *msrs); - r = kvm_vcpu_ioctl(env, KVM_GET_MSRS, kmsrs); - memcpy(msrs, kmsrs->entries, n * sizeof *msrs); - free(kmsrs); - return r; + fprintf(stderr, "Hardware memory error!\n"); + exit(1); } -/* FIXME: kill this and kvm_get_msr, use env->mcg_status instead */ -static int kvm_mce_in_progress(CPUState *env) +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr) { - struct kvm_msr_entry msr_mcg_status = { - .index = MSR_MCG_STATUS, - }; - int r; + ram_addr_t ram_addr; + target_phys_addr_t paddr; - r = kvm_get_msr(env, &msr_mcg_status, 1); - if (r == -1 || r == 0) { - fprintf(stderr, "Failed to get MCE status\n"); - return 0; + if ((env->mcg_cap & MCG_SER_P) && addr + && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) { + if (qemu_ram_addr_from_host(addr, &ram_addr) || + !kvm_physical_memory_addr_from_ram(env->kvm_state, ram_addr, + &paddr)) { + fprintf(stderr, "Hardware memory error for memory used by " + "QEMU itself instead of guest system!\n"); + /* Hope we are lucky for AO MCE */ + if (code == BUS_MCEERR_AO) { + return 0; + } else { + hardware_memory_error(); + } + } + kvm_hwpoison_page_add(ram_addr); + kvm_mce_inject(env, paddr, code); + } else { + if (code == BUS_MCEERR_AO) { + return 0; + } else if (code == BUS_MCEERR_AR) { + hardware_memory_error(); + } else { + return 1; + } } - return !!(msr_mcg_status.data & MCG_STATUS_MCIP); + return 0; } -struct kvm_x86_mce_data -{ - CPUState *env; - struct kvm_x86_mce *mce; - int abort_on_error; -}; - -static void kvm_do_inject_x86_mce(void *_data) +int kvm_arch_on_sigbus(int code, void *addr) { - struct kvm_x86_mce_data *data = _data; - int r; + if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) { + ram_addr_t ram_addr; + target_phys_addr_t paddr; - /* If there is an MCE exception being processed, ignore this SRAO MCE */ - if ((data->env->mcg_cap & MCG_SER_P) && - !(data->mce->status & MCI_STATUS_AR)) { - if (kvm_mce_in_progress(data->env)) { - return; + /* Hope we are lucky for AO MCE */ + if (qemu_ram_addr_from_host(addr, &ram_addr) || + !kvm_physical_memory_addr_from_ram(first_cpu->kvm_state, ram_addr, + &paddr)) { + fprintf(stderr, "Hardware memory error for memory used by " + "QEMU itself instead of guest system!: %p\n", addr); + return 0; } - } - - r = kvm_set_mce(data->env, data->mce); - if (r < 0) { - perror("kvm_set_mce FAILED"); - if (data->abort_on_error) { - abort(); + kvm_hwpoison_page_add(ram_addr); + kvm_mce_inject(first_cpu, paddr, code); + } else { + if (code == BUS_MCEERR_AO) { + return 0; + } else if (code == BUS_MCEERR_AR) { + hardware_memory_error(); + } else { + return 1; } } + return 0; } -static void kvm_inject_x86_mce_on(CPUState *env, struct kvm_x86_mce *mce, - int flag) +static int kvm_inject_mce_oldstyle(CPUState *env) { - struct kvm_x86_mce_data data = { - .env = env, - .mce = mce, - .abort_on_error = (flag & ABORT_ON_ERROR), - }; - - if (!env->mcg_cap) { - fprintf(stderr, "MCE support is not enabled!\n"); - return; - } + if (!kvm_has_vcpu_events() && env->exception_injected == EXCP12_MCHK) { + unsigned int bank, bank_num = env->mcg_cap & 0xff; + struct kvm_x86_mce mce; - run_on_cpu(env, kvm_do_inject_x86_mce, &data); -} + env->exception_injected = -1; -static void kvm_mce_broadcast_rest(CPUState *env); -#endif + /* + * There must be at least one bank in use if an MCE is pending. + * Find it and use its values for the event injection. + */ + for (bank = 0; bank < bank_num; bank++) { + if (env->mce_banks[bank * 4 + 1] & MCI_STATUS_VAL) { + break; + } + } + assert(bank < bank_num); -void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, - uint64_t mcg_status, uint64_t addr, uint64_t misc, - int flag) -{ -#ifdef KVM_CAP_MCE - struct kvm_x86_mce mce = { - .bank = bank, - .status = status, - .mcg_status = mcg_status, - .addr = addr, - .misc = misc, - }; + mce.bank = bank; + mce.status = env->mce_banks[bank * 4 + 1]; + mce.mcg_status = env->mcg_status; + mce.addr = env->mce_banks[bank * 4 + 2]; + mce.misc = env->mce_banks[bank * 4 + 3]; - if (flag & MCE_BROADCAST) { - kvm_mce_broadcast_rest(cenv); + return kvm_vcpu_ioctl(env, KVM_X86_SET_MCE, &mce); } + return 0; +} - kvm_inject_x86_mce_on(cenv, &mce, flag); -#else - if (flag & ABORT_ON_ERROR) { - abort(); +static void cpu_update_state(void *opaque, int running, RunState state) +{ + CPUState *env = opaque; + + if (running) { + env->tsc_valid = false; } -#endif } int kvm_arch_init_vcpu(CPUState *env) @@ -306,31 +350,29 @@ int kvm_arch_init_vcpu(CPUState *env) struct { struct kvm_cpuid2 cpuid; struct kvm_cpuid_entry2 entries[100]; - } __attribute__((packed)) cpuid_data; + } QEMU_PACKED cpuid_data; + KVMState *s = env->kvm_state; uint32_t limit, i, j, cpuid_i; uint32_t unused; struct kvm_cpuid_entry2 *c; -#ifdef CONFIG_KVM_PARA uint32_t signature[3]; -#endif + int r; - env->cpuid_features &= kvm_arch_get_supported_cpuid(env, 1, 0, R_EDX); + env->cpuid_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX); i = env->cpuid_ext_features & CPUID_EXT_HYPERVISOR; - env->cpuid_ext_features &= kvm_arch_get_supported_cpuid(env, 1, 0, R_ECX); + env->cpuid_ext_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX); env->cpuid_ext_features |= i; - env->cpuid_ext2_features &= kvm_arch_get_supported_cpuid(env, 0x80000001, + env->cpuid_ext2_features &= kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX); - env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(env, 0x80000001, + env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX); - env->cpuid_svm_features &= kvm_arch_get_supported_cpuid(env, 0x8000000A, + env->cpuid_svm_features &= kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX); - cpuid_i = 0; -#ifdef CONFIG_KVM_PARA /* Paravirtualization CPUIDs */ memcpy(signature, "KVMKVMKVM\0\0\0", 12); c = &cpuid_data.entries[cpuid_i++]; @@ -344,8 +386,10 @@ int kvm_arch_init_vcpu(CPUState *env) c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_FEATURES; - c->eax = env->cpuid_kvm_features & get_para_features(env); -#endif + c->eax = env->cpuid_kvm_features & + kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX); + + has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF); cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); @@ -375,6 +419,9 @@ int kvm_arch_init_vcpu(CPUState *env) case 0xb: case 0xd: for (j = 0; ; j++) { + if (i == 0xd && j == 64) { + break; + } c->function = i; c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX; c->index = j; @@ -387,7 +434,7 @@ int kvm_arch_init_vcpu(CPUState *env) break; } if (i == 0xd && c->eax == 0) { - break; + continue; } c = &cpuid_data.entries[cpuid_i++]; } @@ -409,32 +456,67 @@ int kvm_arch_init_vcpu(CPUState *env) cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); } + /* Call Centaur's CPUID instructions they are supported. */ + if (env->cpuid_xlevel2 > 0) { + env->cpuid_ext4_features &= + kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX); + cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused); + + for (i = 0xC0000000; i <= limit; i++) { + c = &cpuid_data.entries[cpuid_i++]; + + c->function = i; + c->flags = 0; + cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + } + } + cpuid_data.cpuid.nent = cpuid_i; -#ifdef KVM_CAP_MCE if (((env->cpuid_version >> 8)&0xF) >= 6 && (env->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA) && kvm_check_extension(env->kvm_state, KVM_CAP_MCE) > 0) { uint64_t mcg_cap; int banks; + int ret; - if (kvm_get_mce_cap_supported(env->kvm_state, &mcg_cap, &banks)) { - perror("kvm_get_mce_cap_supported FAILED"); - } else { - if (banks > MCE_BANKS_DEF) - banks = MCE_BANKS_DEF; - mcg_cap &= MCE_CAP_DEF; - mcg_cap |= banks; - if (kvm_setup_mce(env, &mcg_cap)) { - perror("kvm_setup_mce FAILED"); - } else { - env->mcg_cap = mcg_cap; - } + ret = kvm_get_mce_cap_supported(env->kvm_state, &mcg_cap, &banks); + if (ret < 0) { + fprintf(stderr, "kvm_get_mce_cap_supported: %s", strerror(-ret)); + return ret; + } + + if (banks > MCE_BANKS_DEF) { + banks = MCE_BANKS_DEF; } + mcg_cap &= MCE_CAP_DEF; + mcg_cap |= banks; + ret = kvm_vcpu_ioctl(env, KVM_X86_SETUP_MCE, &mcg_cap); + if (ret < 0) { + fprintf(stderr, "KVM_X86_SETUP_MCE: %s", strerror(-ret)); + return ret; + } + + env->mcg_cap = mcg_cap; } -#endif - return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data); + qemu_add_vm_change_state_handler(cpu_update_state, env); + + r = kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data); + if (r) { + return r; + } + + r = kvm_check_extension(env->kvm_state, KVM_CAP_TSC_CONTROL); + if (r && env->tsc_khz) { + r = kvm_vcpu_ioctl(env, KVM_SET_TSC_KHZ, env->tsc_khz); + if (r < 0) { + fprintf(stderr, "KVM_SET_TSC_KHZ failed\n"); + return r; + } + } + + return 0; } void kvm_arch_reset_vcpu(CPUState *env) @@ -470,7 +552,7 @@ static int kvm_get_supported_msrs(KVMState *s) } /* Old kernel modules had a bug and could write beyond the provided memory. Allocate at least a safe amount of 1K. */ - kvm_msr_list = qemu_mallocz(MAX(1024, sizeof(msr_list) + + kvm_msr_list = g_malloc0(MAX(1024, sizeof(msr_list) + msr_list.nmsrs * sizeof(msr_list.indices[0]))); @@ -488,10 +570,18 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_hsave_pa = true; continue; } + if (kvm_msr_list->indices[i] == MSR_IA32_TSCDEADLINE) { + has_msr_tsc_deadline = true; + continue; + } + if (kvm_msr_list->indices[i] == MSR_IA32_MISC_ENABLE) { + has_msr_misc_enable = true; + continue; + } } } - free(kvm_msr_list); + g_free(kvm_msr_list); } return ret; @@ -522,7 +612,6 @@ int kvm_arch_init(KVMState *s) * that case we need to stick with the default, i.e. a 256K maximum BIOS * size. */ -#ifdef KVM_CAP_SET_IDENTITY_MAP_ADDR if (kvm_check_extension(s, KVM_CAP_SET_IDENTITY_MAP_ADDR)) { /* Allows up to 16M BIOSes. */ identity_base = 0xfeffc000; @@ -532,7 +621,7 @@ int kvm_arch_init(KVMState *s) return ret; } } -#endif + /* Set TSS base one page after EPT identity map. */ ret = kvm_vm_ioctl(s, KVM_SET_TSS_ADDR, identity_base + 0x1000); if (ret < 0) { @@ -545,6 +634,7 @@ int kvm_arch_init(KVMState *s) fprintf(stderr, "e820_add_entry() table is full\n"); return ret; } + qemu_register_reset(kvm_unpoison_all, NULL); return 0; } @@ -656,6 +746,9 @@ static int kvm_put_fpu(CPUState *env) fpu.fsw = env->fpus & ~(7 << 11); fpu.fsw |= (env->fpstt & 7) << 11; fpu.fcw = env->fpuc; + fpu.last_opcode = env->fpop; + fpu.last_ip = env->fpip; + fpu.last_dp = env->fpdp; for (i = 0; i < 8; ++i) { fpu.ftwx |= (!env->fptags[i]) << i; } @@ -666,7 +759,6 @@ static int kvm_put_fpu(CPUState *env) return kvm_vcpu_ioctl(env, KVM_SET_FPU, &fpu); } -#ifdef KVM_CAP_XSAVE #define XSAVE_CWD_RIP 2 #define XSAVE_CWD_RDP 4 #define XSAVE_MXCSR 6 @@ -674,14 +766,12 @@ static int kvm_put_fpu(CPUState *env) #define XSAVE_XMM_SPACE 40 #define XSAVE_XSTATE_BV 128 #define XSAVE_YMMH_SPACE 144 -#endif static int kvm_put_xsave(CPUState *env) { -#ifdef KVM_CAP_XSAVE int i, r; struct kvm_xsave* xsave; - uint16_t cwd, swd, twd, fop; + uint16_t cwd, swd, twd; if (!kvm_has_xsave()) { return kvm_put_fpu(env); @@ -689,7 +779,7 @@ static int kvm_put_xsave(CPUState *env) xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); memset(xsave, 0, sizeof(struct kvm_xsave)); - cwd = swd = twd = fop = 0; + twd = 0; swd = env->fpus & ~(7 << 11); swd |= (env->fpstt & 7) << 11; cwd = env->fpuc; @@ -697,7 +787,9 @@ static int kvm_put_xsave(CPUState *env) twd |= (!env->fptags[i]) << i; } xsave->region[0] = (uint32_t)(swd << 16) + cwd; - xsave->region[1] = (uint32_t)(fop << 16) + twd; + xsave->region[1] = (uint32_t)(env->fpop << 16) + twd; + memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip)); + memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp)); memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs, sizeof env->fpregs); memcpy(&xsave->region[XSAVE_XMM_SPACE], env->xmm_regs, @@ -707,16 +799,12 @@ static int kvm_put_xsave(CPUState *env) memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs, sizeof env->ymmh_regs); r = kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave); - qemu_free(xsave); + g_free(xsave); return r; -#else - return kvm_put_fpu(env); -#endif } static int kvm_put_xcrs(CPUState *env) { -#ifdef KVM_CAP_XCRS struct kvm_xcrs xcrs; if (!kvm_has_xcrs()) { @@ -728,9 +816,6 @@ static int kvm_put_xcrs(CPUState *env) xcrs.xcrs[0].xcr = 0; xcrs.xcrs[0].value = env->xcr0; return kvm_vcpu_ioctl(env, KVM_SET_XCRS, &xcrs); -#else - return 0; -#endif } static int kvm_put_sregs(CPUState *env) @@ -799,12 +884,20 @@ static int kvm_put_msrs(CPUState *env, int level) kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs); kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp); kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip); + kvm_msr_entry_set(&msrs[n++], MSR_PAT, env->pat); if (has_msr_star) { kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star); } if (has_msr_hsave_pa) { kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave); } + if (has_msr_tsc_deadline) { + kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSCDEADLINE, env->tsc_deadline); + } + if (has_msr_misc_enable) { + kvm_msr_entry_set(&msrs[n++], MSR_IA32_MISC_ENABLE, + env->msr_ia32_misc_enable); + } #ifdef TARGET_X86_64 if (lm_capable_kernel) { kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar); @@ -833,28 +926,20 @@ static int kvm_put_msrs(CPUState *env, int level) kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, env->system_time_msr); kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr); -#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) if (has_msr_async_pf_en) { kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN, env->async_pf_en_msr); } -#endif } -#ifdef KVM_CAP_MCE if (env->mcg_cap) { int i; - if (level == KVM_PUT_RESET_STATE) { - kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status); - } else if (level == KVM_PUT_FULL_STATE) { - kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status); - kvm_msr_entry_set(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl); - for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) { - kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]); - } + kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status); + kvm_msr_entry_set(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl); + for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) { + kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]); } } -#endif msr_data.info.nmsrs = n; @@ -876,6 +961,9 @@ static int kvm_get_fpu(CPUState *env) env->fpstt = (fpu.fsw >> 11) & 7; env->fpus = fpu.fsw; env->fpuc = fpu.fcw; + env->fpop = fpu.last_opcode; + env->fpip = fpu.last_ip; + env->fpdp = fpu.last_dp; for (i = 0; i < 8; ++i) { env->fptags[i] = !((fpu.ftwx >> i) & 1); } @@ -888,10 +976,9 @@ static int kvm_get_fpu(CPUState *env) static int kvm_get_xsave(CPUState *env) { -#ifdef KVM_CAP_XSAVE struct kvm_xsave* xsave; int ret, i; - uint16_t cwd, swd, twd, fop; + uint16_t cwd, swd, twd; if (!kvm_has_xsave()) { return kvm_get_fpu(env); @@ -900,20 +987,22 @@ static int kvm_get_xsave(CPUState *env) xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); ret = kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave); if (ret < 0) { - qemu_free(xsave); + g_free(xsave); return ret; } cwd = (uint16_t)xsave->region[0]; swd = (uint16_t)(xsave->region[0] >> 16); twd = (uint16_t)xsave->region[1]; - fop = (uint16_t)(xsave->region[1] >> 16); + env->fpop = (uint16_t)(xsave->region[1] >> 16); env->fpstt = (swd >> 11) & 7; env->fpus = swd; env->fpuc = cwd; for (i = 0; i < 8; ++i) { env->fptags[i] = !((twd >> i) & 1); } + memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip)); + memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp)); env->mxcsr = xsave->region[XSAVE_MXCSR]; memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE], sizeof env->fpregs); @@ -922,16 +1011,12 @@ static int kvm_get_xsave(CPUState *env) env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE], sizeof env->ymmh_regs); - qemu_free(xsave); + g_free(xsave); return 0; -#else - return kvm_get_fpu(env); -#endif } static int kvm_get_xcrs(CPUState *env) { -#ifdef KVM_CAP_XCRS int i, ret; struct kvm_xcrs xcrs; @@ -952,9 +1037,6 @@ static int kvm_get_xcrs(CPUState *env) } } return 0; -#else - return 0; -#endif } static int kvm_get_sregs(CPUState *env) @@ -1055,13 +1137,25 @@ static int kvm_get_msrs(CPUState *env) msrs[n++].index = MSR_IA32_SYSENTER_CS; msrs[n++].index = MSR_IA32_SYSENTER_ESP; msrs[n++].index = MSR_IA32_SYSENTER_EIP; + msrs[n++].index = MSR_PAT; if (has_msr_star) { msrs[n++].index = MSR_STAR; } if (has_msr_hsave_pa) { msrs[n++].index = MSR_VM_HSAVE_PA; } - msrs[n++].index = MSR_IA32_TSC; + if (has_msr_tsc_deadline) { + msrs[n++].index = MSR_IA32_TSCDEADLINE; + } + if (has_msr_misc_enable) { + msrs[n++].index = MSR_IA32_MISC_ENABLE; + } + + if (!env->tsc_valid) { + msrs[n++].index = MSR_IA32_TSC; + env->tsc_valid = !runstate_is_running(); + } + #ifdef TARGET_X86_64 if (lm_capable_kernel) { msrs[n++].index = MSR_CSTAR; @@ -1072,13 +1166,10 @@ static int kvm_get_msrs(CPUState *env) #endif msrs[n++].index = MSR_KVM_SYSTEM_TIME; msrs[n++].index = MSR_KVM_WALL_CLOCK; -#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) if (has_msr_async_pf_en) { msrs[n++].index = MSR_KVM_ASYNC_PF_EN; } -#endif -#ifdef KVM_CAP_MCE if (env->mcg_cap) { msrs[n++].index = MSR_MCG_STATUS; msrs[n++].index = MSR_MCG_CTL; @@ -1086,7 +1177,6 @@ static int kvm_get_msrs(CPUState *env) msrs[n++].index = MSR_MC0_CTL + i; } } -#endif msr_data.info.nmsrs = n; ret = kvm_vcpu_ioctl(env, KVM_GET_MSRS, &msr_data); @@ -1105,6 +1195,9 @@ static int kvm_get_msrs(CPUState *env) case MSR_IA32_SYSENTER_EIP: env->sysenter_eip = msrs[i].data; break; + case MSR_PAT: + env->pat = msrs[i].data; + break; case MSR_STAR: env->star = msrs[i].data; break; @@ -1125,6 +1218,9 @@ static int kvm_get_msrs(CPUState *env) case MSR_IA32_TSC: env->tsc = msrs[i].data; break; + case MSR_IA32_TSCDEADLINE: + env->tsc_deadline = msrs[i].data; + break; case MSR_VM_HSAVE_PA: env->vm_hsave = msrs[i].data; break; @@ -1134,27 +1230,24 @@ static int kvm_get_msrs(CPUState *env) case MSR_KVM_WALL_CLOCK: env->wall_clock_msr = msrs[i].data; break; -#ifdef KVM_CAP_MCE case MSR_MCG_STATUS: env->mcg_status = msrs[i].data; break; case MSR_MCG_CTL: env->mcg_ctl = msrs[i].data; break; -#endif + case MSR_IA32_MISC_ENABLE: + env->msr_ia32_misc_enable = msrs[i].data; + break; default: -#ifdef KVM_CAP_MCE if (msrs[i].index >= MSR_MC0_CTL && msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) { env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data; } -#endif break; -#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) case MSR_KVM_ASYNC_PF_EN: env->async_pf_en_msr = msrs[i].data; break; -#endif } } @@ -1186,7 +1279,6 @@ static int kvm_get_mp_state(CPUState *env) static int kvm_put_vcpu_events(CPUState *env, int level) { -#ifdef KVM_CAP_VCPU_EVENTS struct kvm_vcpu_events events; if (!kvm_has_vcpu_events()) { @@ -1215,14 +1307,10 @@ static int kvm_put_vcpu_events(CPUState *env, int level) } return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, &events); -#else - return 0; -#endif } static int kvm_get_vcpu_events(CPUState *env) { -#ifdef KVM_CAP_VCPU_EVENTS struct kvm_vcpu_events events; int ret; @@ -1252,7 +1340,6 @@ static int kvm_get_vcpu_events(CPUState *env) } env->sipi_vector = events.sipi_vector; -#endif return 0; } @@ -1260,7 +1347,6 @@ static int kvm_get_vcpu_events(CPUState *env) static int kvm_guest_debug_workarounds(CPUState *env) { int ret = 0; -#ifdef KVM_CAP_SET_GUEST_DEBUG unsigned long reinject_trap = 0; if (!kvm_has_vcpu_events()) { @@ -1284,13 +1370,11 @@ static int kvm_guest_debug_workarounds(CPUState *env) (!kvm_has_robust_singlestep() && env->singlestep_enabled)) { ret = kvm_update_guest_debug(env, reinject_trap); } -#endif /* KVM_CAP_SET_GUEST_DEBUG */ return ret; } static int kvm_put_debugregs(CPUState *env) { -#ifdef KVM_CAP_DEBUGREGS struct kvm_debugregs dbgregs; int i; @@ -1306,14 +1390,10 @@ static int kvm_put_debugregs(CPUState *env) dbgregs.flags = 0; return kvm_vcpu_ioctl(env, KVM_SET_DEBUGREGS, &dbgregs); -#else - return 0; -#endif } static int kvm_get_debugregs(CPUState *env) { -#ifdef KVM_CAP_DEBUGREGS struct kvm_debugregs dbgregs; int i, ret; @@ -1330,7 +1410,6 @@ static int kvm_get_debugregs(CPUState *env) } env->dr[4] = env->dr[6] = dbgregs.dr6; env->dr[5] = env->dr[7] = dbgregs.dr7; -#endif return 0; } @@ -1339,7 +1418,7 @@ int kvm_arch_put_registers(CPUState *env, int level) { int ret; - assert(cpu_is_stopped(env) || qemu_cpu_self(env)); + assert(cpu_is_stopped(env) || qemu_cpu_is_self(env)); ret = kvm_getput_regs(env, 1); if (ret < 0) { @@ -1357,6 +1436,11 @@ int kvm_arch_put_registers(CPUState *env, int level) if (ret < 0) { return ret; } + /* must be before kvm_put_msrs */ + ret = kvm_inject_mce_oldstyle(env); + if (ret < 0) { + return ret; + } ret = kvm_put_msrs(env, level); if (ret < 0) { return ret; @@ -1387,7 +1471,7 @@ int kvm_arch_get_registers(CPUState *env) { int ret; - assert(cpu_is_stopped(env) || qemu_cpu_self(env)); + assert(cpu_is_stopped(env) || qemu_cpu_is_self(env)); ret = kvm_getput_regs(env, 0); if (ret < 0) { @@ -1424,49 +1508,65 @@ int kvm_arch_get_registers(CPUState *env) return 0; } -int kvm_arch_pre_run(CPUState *env, struct kvm_run *run) +void kvm_arch_pre_run(CPUState *env, struct kvm_run *run) { + int ret; + /* Inject NMI */ if (env->interrupt_request & CPU_INTERRUPT_NMI) { env->interrupt_request &= ~CPU_INTERRUPT_NMI; DPRINTF("injected NMI\n"); - kvm_vcpu_ioctl(env, KVM_NMI); - } - - /* Try to inject an interrupt if the guest can accept it */ - if (run->ready_for_interrupt_injection && - (env->interrupt_request & CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK)) { - int irq; - - env->interrupt_request &= ~CPU_INTERRUPT_HARD; - irq = cpu_get_pic_interrupt(env); - if (irq >= 0) { - struct kvm_interrupt intr; - intr.irq = irq; - /* FIXME: errors */ - DPRINTF("injected interrupt %d\n", irq); - kvm_vcpu_ioctl(env, KVM_INTERRUPT, &intr); + ret = kvm_vcpu_ioctl(env, KVM_NMI); + if (ret < 0) { + fprintf(stderr, "KVM: injection failed, NMI lost (%s)\n", + strerror(-ret)); } } - /* If we have an interrupt but the guest is not ready to receive an - * interrupt, request an interrupt window exit. This will - * cause a return to userspace as soon as the guest is ready to - * receive interrupts. */ - if ((env->interrupt_request & CPU_INTERRUPT_HARD)) { - run->request_interrupt_window = 1; - } else { - run->request_interrupt_window = 0; - } + if (!kvm_irqchip_in_kernel()) { + /* Force the VCPU out of its inner loop to process the INIT request */ + if (env->interrupt_request & CPU_INTERRUPT_INIT) { + env->exit_request = 1; + } + + /* Try to inject an interrupt if the guest can accept it */ + if (run->ready_for_interrupt_injection && + (env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK)) { + int irq; + + env->interrupt_request &= ~CPU_INTERRUPT_HARD; + irq = cpu_get_pic_interrupt(env); + if (irq >= 0) { + struct kvm_interrupt intr; + + intr.irq = irq; + DPRINTF("injected interrupt %d\n", irq); + ret = kvm_vcpu_ioctl(env, KVM_INTERRUPT, &intr); + if (ret < 0) { + fprintf(stderr, + "KVM: injection failed, interrupt lost (%s)\n", + strerror(-ret)); + } + } + } - DPRINTF("setting tpr\n"); - run->cr8 = cpu_get_apic_tpr(env->apic_state); + /* If we have an interrupt but the guest is not ready to receive an + * interrupt, request an interrupt window exit. This will + * cause a return to userspace as soon as the guest is ready to + * receive interrupts. */ + if ((env->interrupt_request & CPU_INTERRUPT_HARD)) { + run->request_interrupt_window = 1; + } else { + run->request_interrupt_window = 0; + } - return 0; + DPRINTF("setting tpr\n"); + run->cr8 = cpu_get_apic_tpr(env->apic_state); + } } -int kvm_arch_post_run(CPUState *env, struct kvm_run *run) +void kvm_arch_post_run(CPUState *env, struct kvm_run *run) { if (run->if_flag) { env->eflags |= IF_MASK; @@ -1475,18 +1575,46 @@ int kvm_arch_post_run(CPUState *env, struct kvm_run *run) } cpu_set_apic_tpr(env->apic_state, run->cr8); cpu_set_apic_base(env->apic_state, run->apic_base); - - return 0; } -int kvm_arch_process_irqchip_events(CPUState *env) +int kvm_arch_process_async_events(CPUState *env) { + if (env->interrupt_request & CPU_INTERRUPT_MCE) { + /* We must not raise CPU_INTERRUPT_MCE if it's not supported. */ + assert(env->mcg_cap); + + env->interrupt_request &= ~CPU_INTERRUPT_MCE; + + kvm_cpu_synchronize_state(env); + + if (env->exception_injected == EXCP08_DBLE) { + /* this means triple fault */ + qemu_system_reset_request(); + env->exit_request = 1; + return 0; + } + env->exception_injected = EXCP12_MCHK; + env->has_error_code = 0; + + env->halted = 0; + if (kvm_irqchip_in_kernel() && env->mp_state == KVM_MP_STATE_HALTED) { + env->mp_state = KVM_MP_STATE_RUNNABLE; + } + } + + if (kvm_irqchip_in_kernel()) { + return 0; + } + + if (((env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK)) || + (env->interrupt_request & CPU_INTERRUPT_NMI)) { + env->halted = 0; + } if (env->interrupt_request & CPU_INTERRUPT_INIT) { kvm_cpu_synchronize_state(env); do_cpu_init(env); - env->exception_index = EXCP_HALTED; } - if (env->interrupt_request & CPU_INTERRUPT_SIPI) { kvm_cpu_synchronize_state(env); do_cpu_sipi(env); @@ -1501,68 +1629,12 @@ static int kvm_handle_halt(CPUState *env) (env->eflags & IF_MASK)) && !(env->interrupt_request & CPU_INTERRUPT_NMI)) { env->halted = 1; - env->exception_index = EXCP_HLT; - return 0; + return EXCP_HLT; } - return 1; -} - -static bool host_supports_vmx(void) -{ - uint32_t ecx, unused; - - host_cpuid(1, 0, &unused, &unused, &ecx, &unused); - return ecx & CPUID_EXT_VMX; -} - -#define VMX_INVALID_GUEST_STATE 0x80000021 - -int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run) -{ - uint64_t code; - int ret = 0; - - switch (run->exit_reason) { - case KVM_EXIT_HLT: - DPRINTF("handle_hlt\n"); - ret = kvm_handle_halt(env); - break; - case KVM_EXIT_SET_TPR: - ret = 1; - break; - case KVM_EXIT_FAIL_ENTRY: - code = run->fail_entry.hardware_entry_failure_reason; - fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n", - code); - if (host_supports_vmx() && code == VMX_INVALID_GUEST_STATE) { - fprintf(stderr, - "\nIf you're runnning a guest on an Intel machine without " - "unrestricted mode\n" - "support, the failure can be most likely due to the guest " - "entering an invalid\n" - "state for Intel VT. For example, the guest maybe running " - "in big real mode\n" - "which is not supported on less recent Intel processors." - "\n\n"); - } - ret = -1; - break; - case KVM_EXIT_EXCEPTION: - fprintf(stderr, "KVM: exception %d exit (error code 0x%x)\n", - run->ex.exception, run->ex.error_code); - ret = -1; - break; - default: - fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); - ret = -1; - break; - } - - return ret; + return 0; } -#ifdef KVM_CAP_SET_GUEST_DEBUG int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp) { static const uint8_t int3 = 0xcc; @@ -1669,31 +1741,31 @@ void kvm_arch_remove_all_hw_breakpoints(void) static CPUWatchpoint hw_watchpoint; -int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info) +static int kvm_handle_debug(struct kvm_debug_exit_arch *arch_info) { - int handle = 0; + int ret = 0; int n; if (arch_info->exception == 1) { if (arch_info->dr6 & (1 << 14)) { if (cpu_single_env->singlestep_enabled) { - handle = 1; + ret = EXCP_DEBUG; } } else { for (n = 0; n < 4; n++) { if (arch_info->dr6 & (1 << n)) { switch ((arch_info->dr7 >> (16 + n*4)) & 0x3) { case 0x0: - handle = 1; + ret = EXCP_DEBUG; break; case 0x1: - handle = 1; + ret = EXCP_DEBUG; cpu_single_env->watchpoint_hit = &hw_watchpoint; hw_watchpoint.vaddr = hw_breakpoint[n].addr; hw_watchpoint.flags = BP_MEM_WRITE; break; case 0x3: - handle = 1; + ret = EXCP_DEBUG; cpu_single_env->watchpoint_hit = &hw_watchpoint; hw_watchpoint.vaddr = hw_breakpoint[n].addr; hw_watchpoint.flags = BP_MEM_ACCESS; @@ -1703,17 +1775,18 @@ int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info) } } } else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc)) { - handle = 1; + ret = EXCP_DEBUG; } - if (!handle) { + if (ret == 0) { cpu_synchronize_state(cpu_single_env); assert(cpu_single_env->exception_injected == -1); + /* pass to guest */ cpu_single_env->exception_injected = arch_info->exception; cpu_single_env->has_error_code = 0; } - return handle; + return ret; } void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg) @@ -1742,180 +1815,67 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg) } } } -#endif /* KVM_CAP_SET_GUEST_DEBUG */ - -bool kvm_arch_stop_on_emulation_error(CPUState *env) -{ - return !(env->cr[0] & CR0_PE_MASK) || - ((env->segs[R_CS].selector & 3) != 3); -} - -static void hardware_memory_error(void) -{ - fprintf(stderr, "Hardware memory error!\n"); - exit(1); -} - -#ifdef KVM_CAP_MCE -static void kvm_mce_broadcast_rest(CPUState *env) -{ - struct kvm_x86_mce mce = { - .bank = 1, - .status = MCI_STATUS_VAL | MCI_STATUS_UC, - .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV, - .addr = 0, - .misc = 0, - }; - CPUState *cenv; - - /* Broadcast MCA signal for processor version 06H_EH and above */ - if (cpu_x86_support_mca_broadcast(env)) { - for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) { - if (cenv == env) { - continue; - } - kvm_inject_x86_mce_on(cenv, &mce, ABORT_ON_ERROR); - } - } -} - -static void kvm_mce_inj_srar_dataload(CPUState *env, target_phys_addr_t paddr) -{ - struct kvm_x86_mce mce = { - .bank = 9, - .status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN - | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S - | MCI_STATUS_AR | 0x134, - .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV, - .addr = paddr, - .misc = (MCM_ADDR_PHYS << 6) | 0xc, - }; - int r; - - r = kvm_set_mce(env, &mce); - if (r < 0) { - fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno)); - abort(); - } - kvm_mce_broadcast_rest(env); -} -static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr) -{ - struct kvm_x86_mce mce = { - .bank = 9, - .status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN - | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S - | 0xc0, - .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV, - .addr = paddr, - .misc = (MCM_ADDR_PHYS << 6) | 0xc, - }; - int r; - - r = kvm_set_mce(env, &mce); - if (r < 0) { - fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno)); - abort(); - } - kvm_mce_broadcast_rest(env); -} - -static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr) +static bool host_supports_vmx(void) { - struct kvm_x86_mce mce = { - .bank = 9, - .status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN - | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S - | 0xc0, - .mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV, - .addr = paddr, - .misc = (MCM_ADDR_PHYS << 6) | 0xc, - }; + uint32_t ecx, unused; - kvm_inject_x86_mce_on(env, &mce, ABORT_ON_ERROR); - kvm_mce_broadcast_rest(env); + host_cpuid(1, 0, &unused, &unused, &ecx, &unused); + return ecx & CPUID_EXT_VMX; } -#endif +#define VMX_INVALID_GUEST_STATE 0x80000021 -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) +int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run) { -#if defined(KVM_CAP_MCE) - void *vaddr; - ram_addr_t ram_addr; - target_phys_addr_t paddr; - - if ((env->mcg_cap & MCG_SER_P) && addr - && (code == BUS_MCEERR_AR - || code == BUS_MCEERR_AO)) { - vaddr = (void *)addr; - if (qemu_ram_addr_from_host(vaddr, &ram_addr) || - !kvm_physical_memory_addr_from_ram(env->kvm_state, ram_addr, &paddr)) { - fprintf(stderr, "Hardware memory error for memory used by " - "QEMU itself instead of guest system!\n"); - /* Hope we are lucky for AO MCE */ - if (code == BUS_MCEERR_AO) { - return 0; - } else { - hardware_memory_error(); - } - } + uint64_t code; + int ret; - if (code == BUS_MCEERR_AR) { - /* Fake an Intel architectural Data Load SRAR UCR */ - kvm_mce_inj_srar_dataload(env, paddr); - } else { - /* - * If there is an MCE excpetion being processed, ignore - * this SRAO MCE - */ - if (!kvm_mce_in_progress(env)) { - /* Fake an Intel architectural Memory scrubbing UCR */ - kvm_mce_inj_srao_memscrub(env, paddr); - } - } - } else -#endif - { - if (code == BUS_MCEERR_AO) { - return 0; - } else if (code == BUS_MCEERR_AR) { - hardware_memory_error(); - } else { - return 1; + switch (run->exit_reason) { + case KVM_EXIT_HLT: + DPRINTF("handle_hlt\n"); + ret = kvm_handle_halt(env); + break; + case KVM_EXIT_SET_TPR: + ret = 0; + break; + case KVM_EXIT_FAIL_ENTRY: + code = run->fail_entry.hardware_entry_failure_reason; + fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n", + code); + if (host_supports_vmx() && code == VMX_INVALID_GUEST_STATE) { + fprintf(stderr, + "\nIf you're running a guest on an Intel machine without " + "unrestricted mode\n" + "support, the failure can be most likely due to the guest " + "entering an invalid\n" + "state for Intel VT. For example, the guest maybe running " + "in big real mode\n" + "which is not supported on less recent Intel processors." + "\n\n"); } + ret = -1; + break; + case KVM_EXIT_EXCEPTION: + fprintf(stderr, "KVM: exception %d exit (error code 0x%x)\n", + run->ex.exception, run->ex.error_code); + ret = -1; + break; + case KVM_EXIT_DEBUG: + DPRINTF("kvm_exit_debug\n"); + ret = kvm_handle_debug(&run->debug.arch); + break; + default: + fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); + ret = -1; + break; } - return 0; + + return ret; } -int kvm_on_sigbus(int code, void *addr) +bool kvm_arch_stop_on_emulation_error(CPUState *env) { -#if defined(KVM_CAP_MCE) - if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) { - void *vaddr; - ram_addr_t ram_addr; - target_phys_addr_t paddr; - - /* Hope we are lucky for AO MCE */ - vaddr = addr; - if (qemu_ram_addr_from_host(vaddr, &ram_addr) || - !kvm_physical_memory_addr_from_ram(first_cpu->kvm_state, ram_addr, &paddr)) { - fprintf(stderr, "Hardware memory error for memory used by " - "QEMU itself instead of guest system!: %p\n", addr); - return 0; - } - kvm_mce_inj_srao_memscrub2(first_cpu, paddr); - } else -#endif - { - if (code == BUS_MCEERR_AO) { - return 0; - } else if (code == BUS_MCEERR_AR) { - hardware_memory_error(); - } else { - return 1; - } - } - return 0; + return !(env->cr[0] & CR0_PE_MASK) || + ((env->segs[R_CS].selector & 3) != 3); } diff --git a/target-i386/kvm_x86.h b/target-i386/kvm_x86.h deleted file mode 100644 index 9d7b584..0000000 --- a/target-i386/kvm_x86.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * QEMU KVM support - * - * Copyright (C) 2009 Red Hat Inc. - * Copyright IBM, Corp. 2008 - * - * Authors: - * Anthony Liguori - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ - -#ifndef __KVM_X86_H__ -#define __KVM_X86_H__ - -#define ABORT_ON_ERROR 0x01 -#define MCE_BROADCAST 0x02 - -void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, - uint64_t mcg_status, uint64_t addr, uint64_t misc, - int flag); - -#endif diff --git a/target-i386/machine.c b/target-i386/machine.c index 1b75b1c..d6e98ff 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -3,24 +3,9 @@ #include "hw/pc.h" #include "hw/isa.h" -#include "exec-all.h" +#include "cpu.h" #include "kvm.h" -//int sensor_update(int x, int y, int z); -int compass_update(int x, int y, int z, int temp); -/* -int sensor_update(int x, int y, int z) -{ - return 0; -} -*/ -/* -int compass_update(int x, int y, int z, int temp) -{ - return 0; -} -*/ - static const VMStateDescription vmstate_segment = { .name = "segment", .version_id = 1, @@ -99,7 +84,6 @@ static void put_fpreg_error(QEMUFile *f, void *opaque, size_t size) exit(0); } -#ifdef USE_X86LDOUBLE /* XXX: add that in a FPU generic layer */ union x86_longdouble { uint64_t mant; @@ -217,102 +201,6 @@ static bool fpregs_is_1_no_mmx(void *opaque, int version_id) VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_mmx, vmstate_fpreg_1_mmx, FPReg), \ VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_no_mmx, vmstate_fpreg_1_no_mmx, FPReg) -#else -static int get_fpreg(QEMUFile *f, void *opaque, size_t size) -{ - FPReg *fp_reg = opaque; - - qemu_get_be64s(f, &fp_reg->mmx.MMX_Q(0)); - return 0; -} - -static void put_fpreg(QEMUFile *f, void *opaque, size_t size) -{ - FPReg *fp_reg = opaque; - /* if we use doubles for float emulation, we save the doubles to - avoid losing information in case of MMX usage. It can give - problems if the image is restored on a CPU where long - doubles are used instead. */ - qemu_put_be64s(f, &fp_reg->mmx.MMX_Q(0)); -} - -const VMStateInfo vmstate_fpreg = { - .name = "fpreg", - .get = get_fpreg, - .put = put_fpreg, -}; - -static int get_fpreg_0_mmx(QEMUFile *f, void *opaque, size_t size) -{ - FPReg *fp_reg = opaque; - uint64_t mant; - uint16_t exp; - - qemu_get_be64s(f, &mant); - qemu_get_be16s(f, &exp); - fp_reg->mmx.MMX_Q(0) = mant; - return 0; -} - -const VMStateInfo vmstate_fpreg_0_mmx = { - .name = "fpreg_0_mmx", - .get = get_fpreg_0_mmx, - .put = put_fpreg_error, -}; - -static int get_fpreg_0_no_mmx(QEMUFile *f, void *opaque, size_t size) -{ - FPReg *fp_reg = opaque; - uint64_t mant; - uint16_t exp; - - qemu_get_be64s(f, &mant); - qemu_get_be16s(f, &exp); - - fp_reg->d = cpu_set_fp80(mant, exp); - return 0; -} - -const VMStateInfo vmstate_fpreg_0_no_mmx = { - .name = "fpreg_0_no_mmx", - .get = get_fpreg_0_no_mmx, - .put = put_fpreg_error, -}; - -static bool fpregs_is_1(void *opaque, int version_id) -{ - CPUState *env = opaque; - - return env->fpregs_format_vmstate == 1; -} - -static bool fpregs_is_0_mmx(void *opaque, int version_id) -{ - CPUState *env = opaque; - int guess_mmx; - - guess_mmx = ((env->fptag_vmstate == 0xff) && - (env->fpus_vmstate & 0x3800) == 0); - return guess_mmx && env->fpregs_format_vmstate == 0; -} - -static bool fpregs_is_0_no_mmx(void *opaque, int version_id) -{ - CPUState *env = opaque; - int guess_mmx; - - guess_mmx = ((env->fptag_vmstate == 0xff) && - (env->fpus_vmstate & 0x3800) == 0); - return !guess_mmx && env->fpregs_format_vmstate == 0; -} - -#define VMSTATE_FP_REGS(_field, _state, _n) \ - VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1, vmstate_fpreg, FPReg), \ - VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_0_mmx, vmstate_fpreg_0_mmx, FPReg), \ - VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_0_no_mmx, vmstate_fpreg_0_no_mmx, FPReg) - -#endif /* USE_X86LDOUBLE */ - static bool version_is_5(void *opaque, int version_id) { return version_id == 5; @@ -359,11 +247,7 @@ static void cpu_pre_save(void *opaque) env->fptag_vmstate |= ((!env->fptags[i]) << i); } -#ifdef USE_X86LDOUBLE env->fpregs_format_vmstate = 0; -#else - env->fpregs_format_vmstate = 1; -#endif } static int cpu_post_load(void *opaque, int version_id) @@ -388,6 +272,80 @@ static int cpu_post_load(void *opaque, int version_id) return 0; } +static bool async_pf_msr_needed(void *opaque) +{ + CPUState *cpu = opaque; + + return cpu->async_pf_en_msr != 0; +} + +static const VMStateDescription vmstate_async_pf_msr = { + .name = "cpu/async_pf_msr", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(async_pf_en_msr, CPUState), + VMSTATE_END_OF_LIST() + } +}; + +static bool fpop_ip_dp_needed(void *opaque) +{ + CPUState *env = opaque; + + return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0; +} + +static const VMStateDescription vmstate_fpop_ip_dp = { + .name = "cpu/fpop_ip_dp", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT16(fpop, CPUState), + VMSTATE_UINT64(fpip, CPUState), + VMSTATE_UINT64(fpdp, CPUState), + VMSTATE_END_OF_LIST() + } +}; + +static bool tscdeadline_needed(void *opaque) +{ + CPUState *env = opaque; + + return env->tsc_deadline != 0; +} + +static const VMStateDescription vmstate_msr_tscdeadline = { + .name = "cpu/msr_tscdeadline", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(tsc_deadline, CPUState), + VMSTATE_END_OF_LIST() + } +}; + +static bool misc_enable_needed(void *opaque) +{ + CPUState *env = opaque; + + return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT; +} + +static const VMStateDescription vmstate_msr_ia32_misc_enable = { + .name = "cpu/msr_ia32_misc_enable", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(msr_ia32_misc_enable, CPUState), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_cpu = { .name = "cpu", .version_id = CPU_SAVE_VERSION, @@ -490,6 +448,23 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_YMMH_REGS_VARS(ymmh_regs, CPUState, CPU_NB_REGS, 12), VMSTATE_END_OF_LIST() /* The above list is not sorted /wrt version numbers, watch out! */ + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_async_pf_msr, + .needed = async_pf_msr_needed, + } , { + .vmsd = &vmstate_fpop_ip_dp, + .needed = fpop_ip_dp_needed, + }, { + .vmsd = &vmstate_msr_tscdeadline, + .needed = tscdeadline_needed, + }, { + .vmsd = &vmstate_msr_ia32_misc_enable, + .needed = misc_enable_needed, + } , { + /* empty */ + } } }; diff --git a/target-i386/mesa_enums.c b/target-i386/mesa_enums.c deleted file mode 100644 index d5019ae..0000000 --- a/target-i386/mesa_enums.c +++ /dev/null @@ -1,4890 +0,0 @@ -/* DO NOT EDIT - This file generated automatically by gl_enums.py (from Mesa) script */ - -/* - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * All Rights Reserved. - * - * 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, sub license, - * 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 (including the next - * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL, - * AND/OR THEIR SUPPLIERS 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. - */ - -#include "glheader.h" -#include "enums.h" -#include "imports.h" - -typedef struct { - size_t offset; - int n; -} enum_elt; - -LONGSTRING static const char enum_string_table[] = - "GL_2D\0" - "GL_2_BYTES\0" - "GL_3D\0" - "GL_3D_COLOR\0" - "GL_3D_COLOR_TEXTURE\0" - "GL_3_BYTES\0" - "GL_4D_COLOR_TEXTURE\0" - "GL_4_BYTES\0" - "GL_ACCUM\0" - "GL_ACCUM_ALPHA_BITS\0" - "GL_ACCUM_BLUE_BITS\0" - "GL_ACCUM_BUFFER_BIT\0" - "GL_ACCUM_CLEAR_VALUE\0" - "GL_ACCUM_GREEN_BITS\0" - "GL_ACCUM_RED_BITS\0" - "GL_ACTIVE_ATTRIBUTES\0" - "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH\0" - "GL_ACTIVE_STENCIL_FACE_EXT\0" - "GL_ACTIVE_TEXTURE\0" - "GL_ACTIVE_TEXTURE_ARB\0" - "GL_ACTIVE_UNIFORMS\0" - "GL_ACTIVE_UNIFORM_MAX_LENGTH\0" - "GL_ACTIVE_VERTEX_UNITS_ARB\0" - "GL_ADD\0" - "GL_ADD_SIGNED\0" - "GL_ADD_SIGNED_ARB\0" - "GL_ADD_SIGNED_EXT\0" - "GL_ALIASED_LINE_WIDTH_RANGE\0" - "GL_ALIASED_POINT_SIZE_RANGE\0" - "GL_ALL_ATTRIB_BITS\0" - "GL_ALL_CLIENT_ATTRIB_BITS\0" - "GL_ALPHA\0" - "GL_ALPHA12\0" - "GL_ALPHA12_EXT\0" - "GL_ALPHA16\0" - "GL_ALPHA16_EXT\0" - "GL_ALPHA4\0" - "GL_ALPHA4_EXT\0" - "GL_ALPHA8\0" - "GL_ALPHA8_EXT\0" - "GL_ALPHA_BIAS\0" - "GL_ALPHA_BITS\0" - "GL_ALPHA_SCALE\0" - "GL_ALPHA_TEST\0" - "GL_ALPHA_TEST_FUNC\0" - "GL_ALPHA_TEST_REF\0" - "GL_ALWAYS\0" - "GL_AMBIENT\0" - "GL_AMBIENT_AND_DIFFUSE\0" - "GL_AND\0" - "GL_AND_INVERTED\0" - "GL_AND_REVERSE\0" - "GL_ARRAY_BUFFER\0" - "GL_ARRAY_BUFFER_ARB\0" - "GL_ARRAY_BUFFER_BINDING\0" - "GL_ARRAY_BUFFER_BINDING_ARB\0" - "GL_ATTACHED_SHADERS\0" - "GL_ATTRIB_ARRAY_POINTER_NV\0" - "GL_ATTRIB_ARRAY_SIZE_NV\0" - "GL_ATTRIB_ARRAY_STRIDE_NV\0" - "GL_ATTRIB_ARRAY_TYPE_NV\0" - "GL_ATTRIB_STACK_DEPTH\0" - "GL_AUTO_NORMAL\0" - "GL_AUX0\0" - "GL_AUX1\0" - "GL_AUX2\0" - "GL_AUX3\0" - "GL_AUX_BUFFERS\0" - "GL_BACK\0" - "GL_BACK_LEFT\0" - "GL_BACK_RIGHT\0" - "GL_BGR\0" - "GL_BGRA\0" - "GL_BITMAP\0" - "GL_BITMAP_TOKEN\0" - "GL_BLEND\0" - "GL_BLEND_COLOR\0" - "GL_BLEND_COLOR_EXT\0" - "GL_BLEND_DST\0" - "GL_BLEND_DST_ALPHA\0" - "GL_BLEND_DST_RGB\0" - "GL_BLEND_EQUATION\0" - "GL_BLEND_EQUATION_ALPHA\0" - "GL_BLEND_EQUATION_ALPHA_EXT\0" - "GL_BLEND_EQUATION_EXT\0" - "GL_BLEND_EQUATION_RGB_EXT\0" - "GL_BLEND_SRC\0" - "GL_BLEND_SRC_ALPHA\0" - "GL_BLEND_SRC_RGB\0" - "GL_BLUE\0" - "GL_BLUE_BIAS\0" - "GL_BLUE_BITS\0" - "GL_BLUE_SCALE\0" - "GL_BOOL\0" - "GL_BOOL_ARB\0" - "GL_BOOL_VEC2\0" - "GL_BOOL_VEC2_ARB\0" - "GL_BOOL_VEC3\0" - "GL_BOOL_VEC3_ARB\0" - "GL_BOOL_VEC4\0" - "GL_BOOL_VEC4_ARB\0" - "GL_BUFFER_ACCESS\0" - "GL_BUFFER_ACCESS_ARB\0" - "GL_BUFFER_MAPPED\0" - "GL_BUFFER_MAPPED_ARB\0" - "GL_BUFFER_MAP_POINTER\0" - "GL_BUFFER_MAP_POINTER_ARB\0" - "GL_BUFFER_SIZE\0" - "GL_BUFFER_SIZE_ARB\0" - "GL_BUFFER_USAGE\0" - "GL_BUFFER_USAGE_ARB\0" - "GL_BYTE\0" - "GL_C3F_V3F\0" - "GL_C4F_N3F_V3F\0" - "GL_C4UB_V2F\0" - "GL_C4UB_V3F\0" - "GL_CCW\0" - "GL_CLAMP\0" - "GL_CLAMP_TO_BORDER\0" - "GL_CLAMP_TO_BORDER_ARB\0" - "GL_CLAMP_TO_BORDER_SGIS\0" - "GL_CLAMP_TO_EDGE\0" - "GL_CLAMP_TO_EDGE_SGIS\0" - "GL_CLEAR\0" - "GL_CLIENT_ACTIVE_TEXTURE\0" - "GL_CLIENT_ACTIVE_TEXTURE_ARB\0" - "GL_CLIENT_ALL_ATTRIB_BITS\0" - "GL_CLIENT_ATTRIB_STACK_DEPTH\0" - "GL_CLIENT_PIXEL_STORE_BIT\0" - "GL_CLIENT_VERTEX_ARRAY_BIT\0" - "GL_CLIP_PLANE0\0" - "GL_CLIP_PLANE1\0" - "GL_CLIP_PLANE2\0" - "GL_CLIP_PLANE3\0" - "GL_CLIP_PLANE4\0" - "GL_CLIP_PLANE5\0" - "GL_CLIP_VOLUME_CLIPPING_HINT_EXT\0" - "GL_COEFF\0" - "GL_COLOR\0" - "GL_COLOR_ARRAY\0" - "GL_COLOR_ARRAY_BUFFER_BINDING\0" - "GL_COLOR_ARRAY_BUFFER_BINDING_ARB\0" - "GL_COLOR_ARRAY_POINTER\0" - "GL_COLOR_ARRAY_SIZE\0" - "GL_COLOR_ARRAY_STRIDE\0" - "GL_COLOR_ARRAY_TYPE\0" - "GL_COLOR_ATTACHMENT0_EXT\0" - "GL_COLOR_ATTACHMENT10_EXT\0" - "GL_COLOR_ATTACHMENT11_EXT\0" - "GL_COLOR_ATTACHMENT12_EXT\0" - "GL_COLOR_ATTACHMENT13_EXT\0" - "GL_COLOR_ATTACHMENT14_EXT\0" - "GL_COLOR_ATTACHMENT15_EXT\0" - "GL_COLOR_ATTACHMENT1_EXT\0" - "GL_COLOR_ATTACHMENT2_EXT\0" - "GL_COLOR_ATTACHMENT3_EXT\0" - "GL_COLOR_ATTACHMENT4_EXT\0" - "GL_COLOR_ATTACHMENT5_EXT\0" - "GL_COLOR_ATTACHMENT6_EXT\0" - "GL_COLOR_ATTACHMENT7_EXT\0" - "GL_COLOR_ATTACHMENT8_EXT\0" - "GL_COLOR_ATTACHMENT9_EXT\0" - "GL_COLOR_BUFFER_BIT\0" - "GL_COLOR_CLEAR_VALUE\0" - "GL_COLOR_INDEX\0" - "GL_COLOR_INDEXES\0" - "GL_COLOR_LOGIC_OP\0" - "GL_COLOR_MATERIAL\0" - "GL_COLOR_MATERIAL_FACE\0" - "GL_COLOR_MATERIAL_PARAMETER\0" - "GL_COLOR_MATRIX\0" - "GL_COLOR_MATRIX_SGI\0" - "GL_COLOR_MATRIX_STACK_DEPTH\0" - "GL_COLOR_MATRIX_STACK_DEPTH_SGI\0" - "GL_COLOR_SUM\0" - "GL_COLOR_SUM_ARB\0" - "GL_COLOR_TABLE\0" - "GL_COLOR_TABLE_ALPHA_SIZE\0" - "GL_COLOR_TABLE_ALPHA_SIZE_EXT\0" - "GL_COLOR_TABLE_ALPHA_SIZE_SGI\0" - "GL_COLOR_TABLE_BIAS\0" - "GL_COLOR_TABLE_BIAS_SGI\0" - "GL_COLOR_TABLE_BLUE_SIZE\0" - "GL_COLOR_TABLE_BLUE_SIZE_EXT\0" - "GL_COLOR_TABLE_BLUE_SIZE_SGI\0" - "GL_COLOR_TABLE_FORMAT\0" - "GL_COLOR_TABLE_FORMAT_EXT\0" - "GL_COLOR_TABLE_FORMAT_SGI\0" - "GL_COLOR_TABLE_GREEN_SIZE\0" - "GL_COLOR_TABLE_GREEN_SIZE_EXT\0" - "GL_COLOR_TABLE_GREEN_SIZE_SGI\0" - "GL_COLOR_TABLE_INTENSITY_SIZE\0" - "GL_COLOR_TABLE_INTENSITY_SIZE_EXT\0" - "GL_COLOR_TABLE_INTENSITY_SIZE_SGI\0" - "GL_COLOR_TABLE_LUMINANCE_SIZE\0" - "GL_COLOR_TABLE_LUMINANCE_SIZE_EXT\0" - "GL_COLOR_TABLE_LUMINANCE_SIZE_SGI\0" - "GL_COLOR_TABLE_RED_SIZE\0" - "GL_COLOR_TABLE_RED_SIZE_EXT\0" - "GL_COLOR_TABLE_RED_SIZE_SGI\0" - "GL_COLOR_TABLE_SCALE\0" - "GL_COLOR_TABLE_SCALE_SGI\0" - "GL_COLOR_TABLE_WIDTH\0" - "GL_COLOR_TABLE_WIDTH_EXT\0" - "GL_COLOR_TABLE_WIDTH_SGI\0" - "GL_COLOR_WRITEMASK\0" - "GL_COMBINE\0" - "GL_COMBINE4\0" - "GL_COMBINE_ALPHA\0" - "GL_COMBINE_ALPHA_ARB\0" - "GL_COMBINE_ALPHA_EXT\0" - "GL_COMBINE_ARB\0" - "GL_COMBINE_EXT\0" - "GL_COMBINE_RGB\0" - "GL_COMBINE_RGB_ARB\0" - "GL_COMBINE_RGB_EXT\0" - "GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT\0" - "GL_COMPARE_R_TO_TEXTURE\0" - "GL_COMPARE_R_TO_TEXTURE_ARB\0" - "GL_COMPILE\0" - "GL_COMPILE_AND_EXECUTE\0" - "GL_COMPILE_STATUS\0" - "GL_COMPRESSED_ALPHA\0" - "GL_COMPRESSED_ALPHA_ARB\0" - "GL_COMPRESSED_INTENSITY\0" - "GL_COMPRESSED_INTENSITY_ARB\0" - "GL_COMPRESSED_LUMINANCE\0" - "GL_COMPRESSED_LUMINANCE_ALPHA\0" - "GL_COMPRESSED_LUMINANCE_ALPHA_ARB\0" - "GL_COMPRESSED_LUMINANCE_ARB\0" - "GL_COMPRESSED_RGB\0" - "GL_COMPRESSED_RGBA\0" - "GL_COMPRESSED_RGBA_ARB\0" - "GL_COMPRESSED_RGBA_FXT1_3DFX\0" - "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT\0" - "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT\0" - "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT\0" - "GL_COMPRESSED_RGB_ARB\0" - "GL_COMPRESSED_RGB_FXT1_3DFX\0" - "GL_COMPRESSED_RGB_S3TC_DXT1_EXT\0" - "GL_COMPRESSED_TEXTURE_FORMATS\0" - "GL_CONSTANT\0" - "GL_CONSTANT_ALPHA\0" - "GL_CONSTANT_ALPHA_EXT\0" - "GL_CONSTANT_ARB\0" - "GL_CONSTANT_ATTENUATION\0" - "GL_CONSTANT_BORDER_HP\0" - "GL_CONSTANT_COLOR\0" - "GL_CONSTANT_COLOR_EXT\0" - "GL_CONSTANT_EXT\0" - "GL_CONVOLUTION_1D\0" - "GL_CONVOLUTION_2D\0" - "GL_CONVOLUTION_BORDER_COLOR\0" - "GL_CONVOLUTION_BORDER_COLOR_HP\0" - "GL_CONVOLUTION_BORDER_MODE\0" - "GL_CONVOLUTION_BORDER_MODE_EXT\0" - "GL_CONVOLUTION_FILTER_BIAS\0" - "GL_CONVOLUTION_FILTER_BIAS_EXT\0" - "GL_CONVOLUTION_FILTER_SCALE\0" - "GL_CONVOLUTION_FILTER_SCALE_EXT\0" - "GL_CONVOLUTION_FORMAT\0" - "GL_CONVOLUTION_FORMAT_EXT\0" - "GL_CONVOLUTION_HEIGHT\0" - "GL_CONVOLUTION_HEIGHT_EXT\0" - "GL_CONVOLUTION_WIDTH\0" - "GL_CONVOLUTION_WIDTH_EXT\0" - "GL_COORD_REPLACE\0" - "GL_COORD_REPLACE_ARB\0" - "GL_COORD_REPLACE_NV\0" - "GL_COPY\0" - "GL_COPY_INVERTED\0" - "GL_COPY_PIXEL_TOKEN\0" - "GL_CULL_FACE\0" - "GL_CULL_FACE_MODE\0" - "GL_CULL_VERTEX_EXT\0" - "GL_CULL_VERTEX_EYE_POSITION_EXT\0" - "GL_CULL_VERTEX_OBJECT_POSITION_EXT\0" - "GL_CURRENT_ATTRIB_NV\0" - "GL_CURRENT_BIT\0" - "GL_CURRENT_COLOR\0" - "GL_CURRENT_FOG_COORD\0" - "GL_CURRENT_FOG_COORDINATE\0" - "GL_CURRENT_INDEX\0" - "GL_CURRENT_MATRIX_ARB\0" - "GL_CURRENT_MATRIX_INDEX_ARB\0" - "GL_CURRENT_MATRIX_NV\0" - "GL_CURRENT_MATRIX_STACK_DEPTH_ARB\0" - "GL_CURRENT_MATRIX_STACK_DEPTH_NV\0" - "GL_CURRENT_NORMAL\0" - "GL_CURRENT_PALETTE_MATRIX_ARB\0" - "GL_CURRENT_PROGRAM\0" - "GL_CURRENT_QUERY\0" - "GL_CURRENT_QUERY_ARB\0" - "GL_CURRENT_RASTER_COLOR\0" - "GL_CURRENT_RASTER_DISTANCE\0" - "GL_CURRENT_RASTER_INDEX\0" - "GL_CURRENT_RASTER_POSITION\0" - "GL_CURRENT_RASTER_POSITION_VALID\0" - "GL_CURRENT_RASTER_TEXTURE_COORDS\0" - "GL_CURRENT_SECONDARY_COLOR\0" - "GL_CURRENT_TEXTURE_COORDS\0" - "GL_CURRENT_VERTEX_ATTRIB\0" - "GL_CURRENT_VERTEX_ATTRIB_ARB\0" - "GL_CURRENT_WEIGHT_ARB\0" - "GL_CW\0" - "GL_DEBUG_ASSERT_MESA\0" - "GL_DEBUG_OBJECT_MESA\0" - "GL_DEBUG_PRINT_MESA\0" - "GL_DECAL\0" - "GL_DECR\0" - "GL_DECR_WRAP\0" - "GL_DECR_WRAP_EXT\0" - "GL_DELETE_STATUS\0" - "GL_DEPTH\0" - "GL_DEPTH_ATTACHMENT_EXT\0" - "GL_DEPTH_BIAS\0" - "GL_DEPTH_BITS\0" - "GL_DEPTH_BOUNDS_EXT\0" - "GL_DEPTH_BOUNDS_TEST_EXT\0" - "GL_DEPTH_BUFFER_BIT\0" - "GL_DEPTH_CLAMP_NV\0" - "GL_DEPTH_CLEAR_VALUE\0" - "GL_DEPTH_COMPONENT\0" - "GL_DEPTH_COMPONENT16\0" - "GL_DEPTH_COMPONENT16_ARB\0" - "GL_DEPTH_COMPONENT16_SGIX\0" - "GL_DEPTH_COMPONENT24\0" - "GL_DEPTH_COMPONENT24_ARB\0" - "GL_DEPTH_COMPONENT24_SGIX\0" - "GL_DEPTH_COMPONENT32\0" - "GL_DEPTH_COMPONENT32_ARB\0" - "GL_DEPTH_COMPONENT32_SGIX\0" - "GL_DEPTH_FUNC\0" - "GL_DEPTH_RANGE\0" - "GL_DEPTH_SCALE\0" - "GL_DEPTH_STENCIL_NV\0" - "GL_DEPTH_STENCIL_TO_BGRA_NV\0" - "GL_DEPTH_STENCIL_TO_RGBA_NV\0" - "GL_DEPTH_TEST\0" - "GL_DEPTH_TEXTURE_MODE\0" - "GL_DEPTH_TEXTURE_MODE_ARB\0" - "GL_DEPTH_WRITEMASK\0" - "GL_DIFFUSE\0" - "GL_DITHER\0" - "GL_DOMAIN\0" - "GL_DONT_CARE\0" - "GL_DOT3_RGB\0" - "GL_DOT3_RGBA\0" - "GL_DOT3_RGBA_ARB\0" - "GL_DOT3_RGBA_EXT\0" - "GL_DOT3_RGB_ARB\0" - "GL_DOT3_RGB_EXT\0" - "GL_DOUBLE\0" - "GL_DOUBLEBUFFER\0" - "GL_DRAW_BUFFER\0" - "GL_DRAW_BUFFER0\0" - "GL_DRAW_BUFFER0_ARB\0" - "GL_DRAW_BUFFER0_ATI\0" - "GL_DRAW_BUFFER1\0" - "GL_DRAW_BUFFER10\0" - "GL_DRAW_BUFFER10_ARB\0" - "GL_DRAW_BUFFER10_ATI\0" - "GL_DRAW_BUFFER11\0" - "GL_DRAW_BUFFER11_ARB\0" - "GL_DRAW_BUFFER11_ATI\0" - "GL_DRAW_BUFFER12\0" - "GL_DRAW_BUFFER12_ARB\0" - "GL_DRAW_BUFFER12_ATI\0" - "GL_DRAW_BUFFER13\0" - "GL_DRAW_BUFFER13_ARB\0" - "GL_DRAW_BUFFER13_ATI\0" - "GL_DRAW_BUFFER14\0" - "GL_DRAW_BUFFER14_ARB\0" - "GL_DRAW_BUFFER14_ATI\0" - "GL_DRAW_BUFFER15\0" - "GL_DRAW_BUFFER15_ARB\0" - "GL_DRAW_BUFFER15_ATI\0" - "GL_DRAW_BUFFER1_ARB\0" - "GL_DRAW_BUFFER1_ATI\0" - "GL_DRAW_BUFFER2\0" - "GL_DRAW_BUFFER2_ARB\0" - "GL_DRAW_BUFFER2_ATI\0" - "GL_DRAW_BUFFER3\0" - "GL_DRAW_BUFFER3_ARB\0" - "GL_DRAW_BUFFER3_ATI\0" - "GL_DRAW_BUFFER4\0" - "GL_DRAW_BUFFER4_ARB\0" - "GL_DRAW_BUFFER4_ATI\0" - "GL_DRAW_BUFFER5\0" - "GL_DRAW_BUFFER5_ARB\0" - "GL_DRAW_BUFFER5_ATI\0" - "GL_DRAW_BUFFER6\0" - "GL_DRAW_BUFFER6_ARB\0" - "GL_DRAW_BUFFER6_ATI\0" - "GL_DRAW_BUFFER7\0" - "GL_DRAW_BUFFER7_ARB\0" - "GL_DRAW_BUFFER7_ATI\0" - "GL_DRAW_BUFFER8\0" - "GL_DRAW_BUFFER8_ARB\0" - "GL_DRAW_BUFFER8_ATI\0" - "GL_DRAW_BUFFER9\0" - "GL_DRAW_BUFFER9_ARB\0" - "GL_DRAW_BUFFER9_ATI\0" - "GL_DRAW_FRAMEBUFFER_BINDING_EXT\0" - "GL_DRAW_FRAMEBUFFER_EXT\0" - "GL_DRAW_PIXEL_TOKEN\0" - "GL_DST_ALPHA\0" - "GL_DST_COLOR\0" - "GL_DYNAMIC_COPY\0" - "GL_DYNAMIC_COPY_ARB\0" - "GL_DYNAMIC_DRAW\0" - "GL_DYNAMIC_DRAW_ARB\0" - "GL_DYNAMIC_READ\0" - "GL_DYNAMIC_READ_ARB\0" - "GL_EDGE_FLAG\0" - "GL_EDGE_FLAG_ARRAY\0" - "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING\0" - "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB\0" - "GL_EDGE_FLAG_ARRAY_POINTER\0" - "GL_EDGE_FLAG_ARRAY_STRIDE\0" - "GL_ELEMENT_ARRAY_BUFFER\0" - "GL_ELEMENT_ARRAY_BUFFER_ARB\0" - "GL_ELEMENT_ARRAY_BUFFER_BINDING\0" - "GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB\0" - "GL_EMISSION\0" - "GL_ENABLE_BIT\0" - "GL_EQUAL\0" - "GL_EQUIV\0" - "GL_EVAL_BIT\0" - "GL_EXP\0" - "GL_EXP2\0" - "GL_EXTENSIONS\0" - "GL_EYE_LINEAR\0" - "GL_EYE_PLANE\0" - "GL_EYE_PLANE_ABSOLUTE_NV\0" - "GL_EYE_RADIAL_NV\0" - "GL_FALSE\0" - "GL_FASTEST\0" - "GL_FEEDBACK\0" - "GL_FEEDBACK_BUFFER_POINTER\0" - "GL_FEEDBACK_BUFFER_SIZE\0" - "GL_FEEDBACK_BUFFER_TYPE\0" - "GL_FILL\0" - "GL_FLAT\0" - "GL_FLOAT\0" - "GL_FLOAT_MAT2\0" - "GL_FLOAT_MAT2_ARB\0" - "GL_FLOAT_MAT3\0" - "GL_FLOAT_MAT3_ARB\0" - "GL_FLOAT_MAT4\0" - "GL_FLOAT_MAT4_ARB\0" - "GL_FLOAT_VEC2\0" - "GL_FLOAT_VEC2_ARB\0" - "GL_FLOAT_VEC3\0" - "GL_FLOAT_VEC3_ARB\0" - "GL_FLOAT_VEC4\0" - "GL_FLOAT_VEC4_ARB\0" - "GL_FOG\0" - "GL_FOG_BIT\0" - "GL_FOG_COLOR\0" - "GL_FOG_COORD\0" - "GL_FOG_COORDINATE\0" - "GL_FOG_COORDINATE_ARRAY\0" - "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING\0" - "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB\0" - "GL_FOG_COORDINATE_ARRAY_POINTER\0" - "GL_FOG_COORDINATE_ARRAY_STRIDE\0" - "GL_FOG_COORDINATE_ARRAY_TYPE\0" - "GL_FOG_COORDINATE_SOURCE\0" - "GL_FOG_COORD_ARRAY\0" - "GL_FOG_COORD_ARRAY_BUFFER_BINDING\0" - "GL_FOG_COORD_ARRAY_POINTER\0" - "GL_FOG_COORD_ARRAY_STRIDE\0" - "GL_FOG_COORD_ARRAY_TYPE\0" - "GL_FOG_COORD_SRC\0" - "GL_FOG_DENSITY\0" - "GL_FOG_DISTANCE_MODE_NV\0" - "GL_FOG_END\0" - "GL_FOG_HINT\0" - "GL_FOG_INDEX\0" - "GL_FOG_MODE\0" - "GL_FOG_OFFSET_SGIX\0" - "GL_FOG_OFFSET_VALUE_SGIX\0" - "GL_FOG_START\0" - "GL_FRAGMENT_DEPTH\0" - "GL_FRAGMENT_PROGRAM_ARB\0" - "GL_FRAGMENT_SHADER\0" - "GL_FRAGMENT_SHADER_ARB\0" - "GL_FRAGMENT_SHADER_DERIVATIVE_HINT\0" - "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT\0" - "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT\0" - "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT\0" - "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT\0" - "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT\0" - "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT\0" - "GL_FRAMEBUFFER_BINDING_EXT\0" - "GL_FRAMEBUFFER_COMPLETE_EXT\0" - "GL_FRAMEBUFFER_EXT\0" - "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\0" - "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\0" - "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\0" - "GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT\0" - "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\0" - "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\0" - "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\0" - "GL_FRAMEBUFFER_STATUS_ERROR_EXT\0" - "GL_FRAMEBUFFER_UNSUPPORTED_EXT\0" - "GL_FRONT\0" - "GL_FRONT_AND_BACK\0" - "GL_FRONT_FACE\0" - "GL_FRONT_LEFT\0" - "GL_FRONT_RIGHT\0" - "GL_FUNC_ADD\0" - "GL_FUNC_ADD_EXT\0" - "GL_FUNC_REVERSE_SUBTRACT\0" - "GL_FUNC_REVERSE_SUBTRACT_EXT\0" - "GL_FUNC_SUBTRACT\0" - "GL_FUNC_SUBTRACT_EXT\0" - "GL_GENERATE_MIPMAP\0" - "GL_GENERATE_MIPMAP_HINT\0" - "GL_GENERATE_MIPMAP_HINT_SGIS\0" - "GL_GENERATE_MIPMAP_SGIS\0" - "GL_GEQUAL\0" - "GL_GL_BLEND_EQUATION_RGB\0" - "GL_GL_COMPRESSED_SLUMINANCE\0" - "GL_GL_COMPRESSED_SLUMINANCE_ALPHA\0" - "GL_GL_COMPRESSED_SRGB\0" - "GL_GL_COMPRESSED_SRGB_ALPHA\0" - "GL_GL_CURRENT_RASTER_SECONDARY_COLOR\0" - "GL_GL_FLOAT_MAT2x3\0" - "GL_GL_FLOAT_MAT2x4\0" - "GL_GL_FLOAT_MAT3x2\0" - "GL_GL_FLOAT_MAT3x4\0" - "GL_GL_FLOAT_MAT4x2\0" - "GL_GL_FLOAT_MAT4x3\0" - "GL_GL_PIXEL_PACK_BUFFER\0" - "GL_GL_PIXEL_PACK_BUFFER_BINDING\0" - "GL_GL_PIXEL_UNPACK_BUFFER\0" - "GL_GL_PIXEL_UNPACK_BUFFER_BINDING\0" - "GL_GL_SLUMINANCE\0" - "GL_GL_SLUMINANCE8\0" - "GL_GL_SLUMINANCE8_ALPHA8\0" - "GL_GL_SLUMINANCE_ALPHA\0" - "GL_GL_SRGB\0" - "GL_GL_SRGB8\0" - "GL_GL_SRGB8_ALPHA8\0" - "GL_GL_SRGB_ALPHA\0" - "GL_GREATER\0" - "GL_GREEN\0" - "GL_GREEN_BIAS\0" - "GL_GREEN_BITS\0" - "GL_GREEN_SCALE\0" - "GL_HINT_BIT\0" - "GL_HISTOGRAM\0" - "GL_HISTOGRAM_ALPHA_SIZE\0" - "GL_HISTOGRAM_ALPHA_SIZE_EXT\0" - "GL_HISTOGRAM_BLUE_SIZE\0" - "GL_HISTOGRAM_BLUE_SIZE_EXT\0" - "GL_HISTOGRAM_EXT\0" - "GL_HISTOGRAM_FORMAT\0" - "GL_HISTOGRAM_FORMAT_EXT\0" - "GL_HISTOGRAM_GREEN_SIZE\0" - "GL_HISTOGRAM_GREEN_SIZE_EXT\0" - "GL_HISTOGRAM_LUMINANCE_SIZE\0" - "GL_HISTOGRAM_LUMINANCE_SIZE_EXT\0" - "GL_HISTOGRAM_RED_SIZE\0" - "GL_HISTOGRAM_RED_SIZE_EXT\0" - "GL_HISTOGRAM_SINK\0" - "GL_HISTOGRAM_SINK_EXT\0" - "GL_HISTOGRAM_WIDTH\0" - "GL_HISTOGRAM_WIDTH_EXT\0" - "GL_IDENTITY_NV\0" - "GL_IGNORE_BORDER_HP\0" - "GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES\0" - "GL_IMPLEMENTATION_COLOR_READ_TYPE_OES\0" - "GL_INCR\0" - "GL_INCR_WRAP\0" - "GL_INCR_WRAP_EXT\0" - "GL_INDEX_ARRAY\0" - "GL_INDEX_ARRAY_BUFFER_BINDING\0" - "GL_INDEX_ARRAY_BUFFER_BINDING_ARB\0" - "GL_INDEX_ARRAY_POINTER\0" - "GL_INDEX_ARRAY_STRIDE\0" - "GL_INDEX_ARRAY_TYPE\0" - "GL_INDEX_BITS\0" - "GL_INDEX_CLEAR_VALUE\0" - "GL_INDEX_LOGIC_OP\0" - "GL_INDEX_MODE\0" - "GL_INDEX_OFFSET\0" - "GL_INDEX_SHIFT\0" - "GL_INDEX_WRITEMASK\0" - "GL_INFO_LOG_LENGTH\0" - "GL_INT\0" - "GL_INTENSITY\0" - "GL_INTENSITY12\0" - "GL_INTENSITY12_EXT\0" - "GL_INTENSITY16\0" - "GL_INTENSITY16_EXT\0" - "GL_INTENSITY4\0" - "GL_INTENSITY4_EXT\0" - "GL_INTENSITY8\0" - "GL_INTENSITY8_EXT\0" - "GL_INTENSITY_EXT\0" - "GL_INTERPOLATE\0" - "GL_INTERPOLATE_ARB\0" - "GL_INTERPOLATE_EXT\0" - "GL_INT_VEC2\0" - "GL_INT_VEC2_ARB\0" - "GL_INT_VEC3\0" - "GL_INT_VEC3_ARB\0" - "GL_INT_VEC4\0" - "GL_INT_VEC4_ARB\0" - "GL_INVALID_ENUM\0" - "GL_INVALID_FRAMEBUFFER_OPERATION_EXT\0" - "GL_INVALID_OPERATION\0" - "GL_INVALID_VALUE\0" - "GL_INVERSE_NV\0" - "GL_INVERSE_TRANSPOSE_NV\0" - "GL_INVERT\0" - "GL_KEEP\0" - "GL_LEFT\0" - "GL_LEQUAL\0" - "GL_LESS\0" - "GL_LIGHT0\0" - "GL_LIGHT1\0" - "GL_LIGHT2\0" - "GL_LIGHT3\0" - "GL_LIGHT4\0" - "GL_LIGHT5\0" - "GL_LIGHT6\0" - "GL_LIGHT7\0" - "GL_LIGHTING\0" - "GL_LIGHTING_BIT\0" - "GL_LIGHT_MODEL_AMBIENT\0" - "GL_LIGHT_MODEL_COLOR_CONTROL\0" - "GL_LIGHT_MODEL_COLOR_CONTROL_EXT\0" - "GL_LIGHT_MODEL_LOCAL_VIEWER\0" - "GL_LIGHT_MODEL_TWO_SIDE\0" - "GL_LINE\0" - "GL_LINEAR\0" - "GL_LINEAR_ATTENUATION\0" - "GL_LINEAR_CLIPMAP_LINEAR_SGIX\0" - "GL_LINEAR_CLIPMAP_NEAREST_SGIX\0" - "GL_LINEAR_MIPMAP_LINEAR\0" - "GL_LINEAR_MIPMAP_NEAREST\0" - "GL_LINES\0" - "GL_LINE_BIT\0" - "GL_LINE_LOOP\0" - "GL_LINE_RESET_TOKEN\0" - "GL_LINE_SMOOTH\0" - "GL_LINE_SMOOTH_HINT\0" - "GL_LINE_STIPPLE\0" - "GL_LINE_STIPPLE_PATTERN\0" - "GL_LINE_STIPPLE_REPEAT\0" - "GL_LINE_STRIP\0" - "GL_LINE_TOKEN\0" - "GL_LINE_WIDTH\0" - "GL_LINE_WIDTH_GRANULARITY\0" - "GL_LINE_WIDTH_RANGE\0" - "GL_LINK_STATUS\0" - "GL_LIST_BASE\0" - "GL_LIST_BIT\0" - "GL_LIST_INDEX\0" - "GL_LIST_MODE\0" - "GL_LOAD\0" - "GL_LOGIC_OP\0" - "GL_LOGIC_OP_MODE\0" - "GL_LOWER_LEFT\0" - "GL_LUMINANCE\0" - "GL_LUMINANCE12\0" - "GL_LUMINANCE12_ALPHA12\0" - "GL_LUMINANCE12_ALPHA12_EXT\0" - "GL_LUMINANCE12_ALPHA4\0" - "GL_LUMINANCE12_ALPHA4_EXT\0" - "GL_LUMINANCE12_EXT\0" - "GL_LUMINANCE16\0" - "GL_LUMINANCE16_ALPHA16\0" - "GL_LUMINANCE16_ALPHA16_EXT\0" - "GL_LUMINANCE16_EXT\0" - "GL_LUMINANCE4\0" - "GL_LUMINANCE4_ALPHA4\0" - "GL_LUMINANCE4_ALPHA4_EXT\0" - "GL_LUMINANCE4_EXT\0" - "GL_LUMINANCE6_ALPHA2\0" - "GL_LUMINANCE6_ALPHA2_EXT\0" - "GL_LUMINANCE8\0" - "GL_LUMINANCE8_ALPHA8\0" - "GL_LUMINANCE8_ALPHA8_EXT\0" - "GL_LUMINANCE8_EXT\0" - "GL_LUMINANCE_ALPHA\0" - "GL_MAP1_COLOR_4\0" - "GL_MAP1_GRID_DOMAIN\0" - "GL_MAP1_GRID_SEGMENTS\0" - "GL_MAP1_INDEX\0" - "GL_MAP1_NORMAL\0" - "GL_MAP1_TEXTURE_COORD_1\0" - "GL_MAP1_TEXTURE_COORD_2\0" - "GL_MAP1_TEXTURE_COORD_3\0" - "GL_MAP1_TEXTURE_COORD_4\0" - "GL_MAP1_VERTEX_3\0" - "GL_MAP1_VERTEX_4\0" - "GL_MAP1_VERTEX_ATTRIB0_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB10_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB11_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB12_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB13_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB14_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB15_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB1_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB2_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB3_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB4_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB5_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB6_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB7_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB8_4_NV\0" - "GL_MAP1_VERTEX_ATTRIB9_4_NV\0" - "GL_MAP2_COLOR_4\0" - "GL_MAP2_GRID_DOMAIN\0" - "GL_MAP2_GRID_SEGMENTS\0" - "GL_MAP2_INDEX\0" - "GL_MAP2_NORMAL\0" - "GL_MAP2_TEXTURE_COORD_1\0" - "GL_MAP2_TEXTURE_COORD_2\0" - "GL_MAP2_TEXTURE_COORD_3\0" - "GL_MAP2_TEXTURE_COORD_4\0" - "GL_MAP2_VERTEX_3\0" - "GL_MAP2_VERTEX_4\0" - "GL_MAP2_VERTEX_ATTRIB0_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB10_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB11_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB12_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB13_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB14_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB15_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB1_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB2_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB3_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB4_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB5_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB6_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB7_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB8_4_NV\0" - "GL_MAP2_VERTEX_ATTRIB9_4_NV\0" - "GL_MAP_COLOR\0" - "GL_MAP_STENCIL\0" - "GL_MATRIX0_ARB\0" - "GL_MATRIX0_NV\0" - "GL_MATRIX10_ARB\0" - "GL_MATRIX11_ARB\0" - "GL_MATRIX12_ARB\0" - "GL_MATRIX13_ARB\0" - "GL_MATRIX14_ARB\0" - "GL_MATRIX15_ARB\0" - "GL_MATRIX16_ARB\0" - "GL_MATRIX17_ARB\0" - "GL_MATRIX18_ARB\0" - "GL_MATRIX19_ARB\0" - "GL_MATRIX1_ARB\0" - "GL_MATRIX1_NV\0" - "GL_MATRIX20_ARB\0" - "GL_MATRIX21_ARB\0" - "GL_MATRIX22_ARB\0" - "GL_MATRIX23_ARB\0" - "GL_MATRIX24_ARB\0" - "GL_MATRIX25_ARB\0" - "GL_MATRIX26_ARB\0" - "GL_MATRIX27_ARB\0" - "GL_MATRIX28_ARB\0" - "GL_MATRIX29_ARB\0" - "GL_MATRIX2_ARB\0" - "GL_MATRIX2_NV\0" - "GL_MATRIX30_ARB\0" - "GL_MATRIX31_ARB\0" - "GL_MATRIX3_ARB\0" - "GL_MATRIX3_NV\0" - "GL_MATRIX4_ARB\0" - "GL_MATRIX4_NV\0" - "GL_MATRIX5_ARB\0" - "GL_MATRIX5_NV\0" - "GL_MATRIX6_ARB\0" - "GL_MATRIX6_NV\0" - "GL_MATRIX7_ARB\0" - "GL_MATRIX7_NV\0" - "GL_MATRIX8_ARB\0" - "GL_MATRIX9_ARB\0" - "GL_MATRIX_INDEX_ARRAY_ARB\0" - "GL_MATRIX_INDEX_ARRAY_POINTER_ARB\0" - "GL_MATRIX_INDEX_ARRAY_SIZE_ARB\0" - "GL_MATRIX_INDEX_ARRAY_STRIDE_ARB\0" - "GL_MATRIX_INDEX_ARRAY_TYPE_ARB\0" - "GL_MATRIX_MODE\0" - "GL_MATRIX_PALETTE_ARB\0" - "GL_MAX\0" - "GL_MAX_3D_TEXTURE_SIZE\0" - "GL_MAX_ARRAY_TEXTURE_LAYERS_EXT\0" - "GL_MAX_ATTRIB_STACK_DEPTH\0" - "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH\0" - "GL_MAX_CLIPMAP_DEPTH_SGIX\0" - "GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX\0" - "GL_MAX_CLIP_PLANES\0" - "GL_MAX_COLOR_ATTACHMENTS_EXT\0" - "GL_MAX_COLOR_MATRIX_STACK_DEPTH\0" - "GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI\0" - "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS\0" - "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB\0" - "GL_MAX_CONVOLUTION_HEIGHT\0" - "GL_MAX_CONVOLUTION_HEIGHT_EXT\0" - "GL_MAX_CONVOLUTION_WIDTH\0" - "GL_MAX_CONVOLUTION_WIDTH_EXT\0" - "GL_MAX_CUBE_MAP_TEXTURE_SIZE\0" - "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB\0" - "GL_MAX_DRAW_BUFFERS\0" - "GL_MAX_DRAW_BUFFERS_ARB\0" - "GL_MAX_DRAW_BUFFERS_ATI\0" - "GL_MAX_ELEMENTS_INDICES\0" - "GL_MAX_ELEMENTS_VERTICES\0" - "GL_MAX_EVAL_ORDER\0" - "GL_MAX_EXT\0" - "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS\0" - "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB\0" - "GL_MAX_LIGHTS\0" - "GL_MAX_LIST_NESTING\0" - "GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB\0" - "GL_MAX_MODELVIEW_STACK_DEPTH\0" - "GL_MAX_NAME_STACK_DEPTH\0" - "GL_MAX_PALETTE_MATRICES_ARB\0" - "GL_MAX_PIXEL_MAP_TABLE\0" - "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB\0" - "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB\0" - "GL_MAX_PROGRAM_ATTRIBS_ARB\0" - "GL_MAX_PROGRAM_CALL_DEPTH_NV\0" - "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB\0" - "GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV\0" - "GL_MAX_PROGRAM_IF_DEPTH_NV\0" - "GL_MAX_PROGRAM_INSTRUCTIONS_ARB\0" - "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB\0" - "GL_MAX_PROGRAM_LOOP_COUNT_NV\0" - "GL_MAX_PROGRAM_LOOP_DEPTH_NV\0" - "GL_MAX_PROGRAM_MATRICES_ARB\0" - "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB\0" - "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB\0" - "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB\0" - "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB\0" - "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB\0" - "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB\0" - "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB\0" - "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB\0" - "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB\0" - "GL_MAX_PROGRAM_PARAMETERS_ARB\0" - "GL_MAX_PROGRAM_TEMPORARIES_ARB\0" - "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB\0" - "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB\0" - "GL_MAX_PROJECTION_STACK_DEPTH\0" - "GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB\0" - "GL_MAX_RECTANGLE_TEXTURE_SIZE_NV\0" - "GL_MAX_RENDERBUFFER_SIZE_EXT\0" - "GL_MAX_SHININESS_NV\0" - "GL_MAX_SPOT_EXPONENT_NV\0" - "GL_MAX_TEXTURE_COORDS\0" - "GL_MAX_TEXTURE_COORDS_ARB\0" - "GL_MAX_TEXTURE_IMAGE_UNITS\0" - "GL_MAX_TEXTURE_IMAGE_UNITS_ARB\0" - "GL_MAX_TEXTURE_LOD_BIAS\0" - "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT\0" - "GL_MAX_TEXTURE_SIZE\0" - "GL_MAX_TEXTURE_STACK_DEPTH\0" - "GL_MAX_TEXTURE_UNITS\0" - "GL_MAX_TEXTURE_UNITS_ARB\0" - "GL_MAX_TRACK_MATRICES_NV\0" - "GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV\0" - "GL_MAX_VARYING_FLOATS\0" - "GL_MAX_VARYING_FLOATS_ARB\0" - "GL_MAX_VERTEX_ATTRIBS\0" - "GL_MAX_VERTEX_ATTRIBS_ARB\0" - "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS\0" - "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB\0" - "GL_MAX_VERTEX_UNIFORM_COMPONENTS\0" - "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB\0" - "GL_MAX_VERTEX_UNITS_ARB\0" - "GL_MAX_VIEWPORT_DIMS\0" - "GL_MIN\0" - "GL_MINMAX\0" - "GL_MINMAX_EXT\0" - "GL_MINMAX_FORMAT\0" - "GL_MINMAX_FORMAT_EXT\0" - "GL_MINMAX_SINK\0" - "GL_MINMAX_SINK_EXT\0" - "GL_MIN_EXT\0" - "GL_MIRRORED_REPEAT\0" - "GL_MIRRORED_REPEAT_ARB\0" - "GL_MIRRORED_REPEAT_IBM\0" - "GL_MIRROR_CLAMP_ATI\0" - "GL_MIRROR_CLAMP_EXT\0" - "GL_MIRROR_CLAMP_TO_BORDER_EXT\0" - "GL_MIRROR_CLAMP_TO_EDGE_ATI\0" - "GL_MIRROR_CLAMP_TO_EDGE_EXT\0" - "GL_MODELVIEW\0" - "GL_MODELVIEW0_ARB\0" - "GL_MODELVIEW10_ARB\0" - "GL_MODELVIEW11_ARB\0" - "GL_MODELVIEW12_ARB\0" - "GL_MODELVIEW13_ARB\0" - "GL_MODELVIEW14_ARB\0" - "GL_MODELVIEW15_ARB\0" - "GL_MODELVIEW16_ARB\0" - "GL_MODELVIEW17_ARB\0" - "GL_MODELVIEW18_ARB\0" - "GL_MODELVIEW19_ARB\0" - "GL_MODELVIEW1_ARB\0" - "GL_MODELVIEW20_ARB\0" - "GL_MODELVIEW21_ARB\0" - "GL_MODELVIEW22_ARB\0" - "GL_MODELVIEW23_ARB\0" - "GL_MODELVIEW24_ARB\0" - "GL_MODELVIEW25_ARB\0" - "GL_MODELVIEW26_ARB\0" - "GL_MODELVIEW27_ARB\0" - "GL_MODELVIEW28_ARB\0" - "GL_MODELVIEW29_ARB\0" - "GL_MODELVIEW2_ARB\0" - "GL_MODELVIEW30_ARB\0" - "GL_MODELVIEW31_ARB\0" - "GL_MODELVIEW3_ARB\0" - "GL_MODELVIEW4_ARB\0" - "GL_MODELVIEW5_ARB\0" - "GL_MODELVIEW6_ARB\0" - "GL_MODELVIEW7_ARB\0" - "GL_MODELVIEW8_ARB\0" - "GL_MODELVIEW9_ARB\0" - "GL_MODELVIEW_MATRIX\0" - "GL_MODELVIEW_PROJECTION_NV\0" - "GL_MODELVIEW_STACK_DEPTH\0" - "GL_MODULATE\0" - "GL_MODULATE_ADD_ATI\0" - "GL_MODULATE_SIGNED_ADD_ATI\0" - "GL_MODULATE_SUBTRACT_ATI\0" - "GL_MULT\0" - "GL_MULTISAMPLE\0" - "GL_MULTISAMPLE_3DFX\0" - "GL_MULTISAMPLE_ARB\0" - "GL_MULTISAMPLE_BIT\0" - "GL_MULTISAMPLE_BIT_3DFX\0" - "GL_MULTISAMPLE_BIT_ARB\0" - "GL_MULTISAMPLE_FILTER_HINT_NV\0" - "GL_N3F_V3F\0" - "GL_NAME_STACK_DEPTH\0" - "GL_NAND\0" - "GL_NEAREST\0" - "GL_NEAREST_CLIPMAP_LINEAR_SGIX\0" - "GL_NEAREST_CLIPMAP_NEAREST_SGIX\0" - "GL_NEAREST_MIPMAP_LINEAR\0" - "GL_NEAREST_MIPMAP_NEAREST\0" - "GL_NEVER\0" - "GL_NICEST\0" - "GL_NONE\0" - "GL_NOOP\0" - "GL_NOR\0" - "GL_NORMALIZE\0" - "GL_NORMAL_ARRAY\0" - "GL_NORMAL_ARRAY_BUFFER_BINDING\0" - "GL_NORMAL_ARRAY_BUFFER_BINDING_ARB\0" - "GL_NORMAL_ARRAY_POINTER\0" - "GL_NORMAL_ARRAY_STRIDE\0" - "GL_NORMAL_ARRAY_TYPE\0" - "GL_NORMAL_MAP\0" - "GL_NORMAL_MAP_ARB\0" - "GL_NORMAL_MAP_NV\0" - "GL_NOTEQUAL\0" - "GL_NO_ERROR\0" - "GL_NUM_COMPRESSED_TEXTURE_FORMATS\0" - "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB\0" - "GL_OBJECT_ACTIVE_ATTRIBUTES_ARB\0" - "GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB\0" - "GL_OBJECT_ACTIVE_UNIFORMS_ARB\0" - "GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB\0" - "GL_OBJECT_ATTACHED_OBJECTS_ARB\0" - "GL_OBJECT_COMPILE_STATUS_ARB\0" - "GL_OBJECT_DELETE_STATUS_ARB\0" - "GL_OBJECT_INFO_LOG_LENGTH_ARB\0" - "GL_OBJECT_LINEAR\0" - "GL_OBJECT_LINK_STATUS_ARB\0" - "GL_OBJECT_PLANE\0" - "GL_OBJECT_SHADER_SOURCE_LENGTH_ARB\0" - "GL_OBJECT_SUBTYPE_ARB\0" - "GL_OBJECT_TYPE_ARB\0" - "GL_OBJECT_VALIDATE_STATUS_ARB\0" - "GL_OCCLUSION_TEST_HP\0" - "GL_OCCLUSION_TEST_RESULT_HP\0" - "GL_ONE\0" - "GL_ONE_MINUS_CONSTANT_ALPHA\0" - "GL_ONE_MINUS_CONSTANT_ALPHA_EXT\0" - "GL_ONE_MINUS_CONSTANT_COLOR\0" - "GL_ONE_MINUS_CONSTANT_COLOR_EXT\0" - "GL_ONE_MINUS_DST_ALPHA\0" - "GL_ONE_MINUS_DST_COLOR\0" - "GL_ONE_MINUS_SRC_ALPHA\0" - "GL_ONE_MINUS_SRC_COLOR\0" - "GL_OPERAND0_ALPHA\0" - "GL_OPERAND0_ALPHA_ARB\0" - "GL_OPERAND0_ALPHA_EXT\0" - "GL_OPERAND0_RGB\0" - "GL_OPERAND0_RGB_ARB\0" - "GL_OPERAND0_RGB_EXT\0" - "GL_OPERAND1_ALPHA\0" - "GL_OPERAND1_ALPHA_ARB\0" - "GL_OPERAND1_ALPHA_EXT\0" - "GL_OPERAND1_RGB\0" - "GL_OPERAND1_RGB_ARB\0" - "GL_OPERAND1_RGB_EXT\0" - "GL_OPERAND2_ALPHA\0" - "GL_OPERAND2_ALPHA_ARB\0" - "GL_OPERAND2_ALPHA_EXT\0" - "GL_OPERAND2_RGB\0" - "GL_OPERAND2_RGB_ARB\0" - "GL_OPERAND2_RGB_EXT\0" - "GL_OPERAND3_ALPHA_NV\0" - "GL_OPERAND3_RGB_NV\0" - "GL_OR\0" - "GL_ORDER\0" - "GL_OR_INVERTED\0" - "GL_OR_REVERSE\0" - "GL_OUT_OF_MEMORY\0" - "GL_PACK_ALIGNMENT\0" - "GL_PACK_IMAGE_HEIGHT\0" - "GL_PACK_INVERT_MESA\0" - "GL_PACK_LSB_FIRST\0" - "GL_PACK_ROW_LENGTH\0" - "GL_PACK_SKIP_IMAGES\0" - "GL_PACK_SKIP_PIXELS\0" - "GL_PACK_SKIP_ROWS\0" - "GL_PACK_SWAP_BYTES\0" - "GL_PALETTE4_R5_G6_B5_OES\0" - "GL_PALETTE4_RGB5_A1_OES\0" - "GL_PALETTE4_RGB8_OES\0" - "GL_PALETTE4_RGBA4_OES\0" - "GL_PALETTE4_RGBA8_OES\0" - "GL_PALETTE8_R5_G6_B5_OES\0" - "GL_PALETTE8_RGB5_A1_OES\0" - "GL_PALETTE8_RGB8_OES\0" - "GL_PALETTE8_RGBA4_OES\0" - "GL_PALETTE8_RGBA8_OES\0" - "GL_PASS_THROUGH_TOKEN\0" - "GL_PERSPECTIVE_CORRECTION_HINT\0" - "GL_PIXEL_MAP_A_TO_A\0" - "GL_PIXEL_MAP_A_TO_A_SIZE\0" - "GL_PIXEL_MAP_B_TO_B\0" - "GL_PIXEL_MAP_B_TO_B_SIZE\0" - "GL_PIXEL_MAP_G_TO_G\0" - "GL_PIXEL_MAP_G_TO_G_SIZE\0" - "GL_PIXEL_MAP_I_TO_A\0" - "GL_PIXEL_MAP_I_TO_A_SIZE\0" - "GL_PIXEL_MAP_I_TO_B\0" - "GL_PIXEL_MAP_I_TO_B_SIZE\0" - "GL_PIXEL_MAP_I_TO_G\0" - "GL_PIXEL_MAP_I_TO_G_SIZE\0" - "GL_PIXEL_MAP_I_TO_I\0" - "GL_PIXEL_MAP_I_TO_I_SIZE\0" - "GL_PIXEL_MAP_I_TO_R\0" - "GL_PIXEL_MAP_I_TO_R_SIZE\0" - "GL_PIXEL_MAP_R_TO_R\0" - "GL_PIXEL_MAP_R_TO_R_SIZE\0" - "GL_PIXEL_MAP_S_TO_S\0" - "GL_PIXEL_MAP_S_TO_S_SIZE\0" - "GL_PIXEL_MODE_BIT\0" - "GL_PIXEL_PACK_BUFFER_BINDING_EXT\0" - "GL_PIXEL_PACK_BUFFER_EXT\0" - "GL_PIXEL_UNPACK_BUFFER_BINDING_EXT\0" - "GL_PIXEL_UNPACK_BUFFER_EXT\0" - "GL_POINT\0" - "GL_POINTS\0" - "GL_POINT_BIT\0" - "GL_POINT_DISTANCE_ATTENUATION\0" - "GL_POINT_DISTANCE_ATTENUATION_ARB\0" - "GL_POINT_DISTANCE_ATTENUATION_EXT\0" - "GL_POINT_DISTANCE_ATTENUATION_SGIS\0" - "GL_POINT_FADE_THRESHOLD_SIZE\0" - "GL_POINT_FADE_THRESHOLD_SIZE_ARB\0" - "GL_POINT_FADE_THRESHOLD_SIZE_EXT\0" - "GL_POINT_FADE_THRESHOLD_SIZE_SGIS\0" - "GL_POINT_SIZE\0" - "GL_POINT_SIZE_GRANULARITY\0" - "GL_POINT_SIZE_MAX\0" - "GL_POINT_SIZE_MAX_ARB\0" - "GL_POINT_SIZE_MAX_EXT\0" - "GL_POINT_SIZE_MAX_SGIS\0" - "GL_POINT_SIZE_MIN\0" - "GL_POINT_SIZE_MIN_ARB\0" - "GL_POINT_SIZE_MIN_EXT\0" - "GL_POINT_SIZE_MIN_SGIS\0" - "GL_POINT_SIZE_RANGE\0" - "GL_POINT_SMOOTH\0" - "GL_POINT_SMOOTH_HINT\0" - "GL_POINT_SPRITE\0" - "GL_POINT_SPRITE_ARB\0" - "GL_POINT_SPRITE_COORD_ORIGIN\0" - "GL_POINT_SPRITE_NV\0" - "GL_POINT_SPRITE_R_MODE_NV\0" - "GL_POINT_TOKEN\0" - "GL_POLYGON\0" - "GL_POLYGON_BIT\0" - "GL_POLYGON_MODE\0" - "GL_POLYGON_OFFSET_BIAS\0" - "GL_POLYGON_OFFSET_FACTOR\0" - "GL_POLYGON_OFFSET_FILL\0" - "GL_POLYGON_OFFSET_LINE\0" - "GL_POLYGON_OFFSET_POINT\0" - "GL_POLYGON_OFFSET_UNITS\0" - "GL_POLYGON_SMOOTH\0" - "GL_POLYGON_SMOOTH_HINT\0" - "GL_POLYGON_STIPPLE\0" - "GL_POLYGON_STIPPLE_BIT\0" - "GL_POLYGON_TOKEN\0" - "GL_POSITION\0" - "GL_POST_COLOR_MATRIX_ALPHA_BIAS\0" - "GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI\0" - "GL_POST_COLOR_MATRIX_ALPHA_SCALE\0" - "GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI\0" - "GL_POST_COLOR_MATRIX_BLUE_BIAS\0" - "GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI\0" - "GL_POST_COLOR_MATRIX_BLUE_SCALE\0" - "GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI\0" - "GL_POST_COLOR_MATRIX_COLOR_TABLE\0" - "GL_POST_COLOR_MATRIX_GREEN_BIAS\0" - "GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI\0" - "GL_POST_COLOR_MATRIX_GREEN_SCALE\0" - "GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI\0" - "GL_POST_COLOR_MATRIX_RED_BIAS\0" - "GL_POST_COLOR_MATRIX_RED_BIAS_SGI\0" - "GL_POST_COLOR_MATRIX_RED_SCALE\0" - "GL_POST_COLOR_MATRIX_RED_SCALE_SGI\0" - "GL_POST_CONVOLUTION_ALPHA_BIAS\0" - "GL_POST_CONVOLUTION_ALPHA_BIAS_EXT\0" - "GL_POST_CONVOLUTION_ALPHA_SCALE\0" - "GL_POST_CONVOLUTION_ALPHA_SCALE_EXT\0" - "GL_POST_CONVOLUTION_BLUE_BIAS\0" - "GL_POST_CONVOLUTION_BLUE_BIAS_EXT\0" - "GL_POST_CONVOLUTION_BLUE_SCALE\0" - "GL_POST_CONVOLUTION_BLUE_SCALE_EXT\0" - "GL_POST_CONVOLUTION_COLOR_TABLE\0" - "GL_POST_CONVOLUTION_GREEN_BIAS\0" - "GL_POST_CONVOLUTION_GREEN_BIAS_EXT\0" - "GL_POST_CONVOLUTION_GREEN_SCALE\0" - "GL_POST_CONVOLUTION_GREEN_SCALE_EXT\0" - "GL_POST_CONVOLUTION_RED_BIAS\0" - "GL_POST_CONVOLUTION_RED_BIAS_EXT\0" - "GL_POST_CONVOLUTION_RED_SCALE\0" - "GL_POST_CONVOLUTION_RED_SCALE_EXT\0" - "GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX\0" - "GL_POST_TEXTURE_FILTER_BIAS_SGIX\0" - "GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX\0" - "GL_POST_TEXTURE_FILTER_SCALE_SGIX\0" - "GL_PREVIOUS\0" - "GL_PREVIOUS_ARB\0" - "GL_PREVIOUS_EXT\0" - "GL_PRIMARY_COLOR\0" - "GL_PRIMARY_COLOR_ARB\0" - "GL_PRIMARY_COLOR_EXT\0" - "GL_PROGRAM_ADDRESS_REGISTERS_ARB\0" - "GL_PROGRAM_ALU_INSTRUCTIONS_ARB\0" - "GL_PROGRAM_ATTRIBS_ARB\0" - "GL_PROGRAM_BINDING_ARB\0" - "GL_PROGRAM_ERROR_POSITION_ARB\0" - "GL_PROGRAM_ERROR_POSITION_NV\0" - "GL_PROGRAM_ERROR_STRING_ARB\0" - "GL_PROGRAM_FORMAT_ARB\0" - "GL_PROGRAM_FORMAT_ASCII_ARB\0" - "GL_PROGRAM_INSTRUCTIONS_ARB\0" - "GL_PROGRAM_LENGTH_ARB\0" - "GL_PROGRAM_LENGTH_NV\0" - "GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB\0" - "GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB\0" - "GL_PROGRAM_NATIVE_ATTRIBS_ARB\0" - "GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB\0" - "GL_PROGRAM_NATIVE_PARAMETERS_ARB\0" - "GL_PROGRAM_NATIVE_TEMPORARIES_ARB\0" - "GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB\0" - "GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB\0" - "GL_PROGRAM_OBJECT_ARB\0" - "GL_PROGRAM_PARAMETERS_ARB\0" - "GL_PROGRAM_PARAMETER_NV\0" - "GL_PROGRAM_RESIDENT_NV\0" - "GL_PROGRAM_STRING_ARB\0" - "GL_PROGRAM_STRING_NV\0" - "GL_PROGRAM_TARGET_NV\0" - "GL_PROGRAM_TEMPORARIES_ARB\0" - "GL_PROGRAM_TEX_INDIRECTIONS_ARB\0" - "GL_PROGRAM_TEX_INSTRUCTIONS_ARB\0" - "GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB\0" - "GL_PROJECTION\0" - "GL_PROJECTION_MATRIX\0" - "GL_PROJECTION_STACK_DEPTH\0" - "GL_PROXY_COLOR_TABLE\0" - "GL_PROXY_HISTOGRAM\0" - "GL_PROXY_HISTOGRAM_EXT\0" - "GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE\0" - "GL_PROXY_POST_CONVOLUTION_COLOR_TABLE\0" - "GL_PROXY_TEXTURE_1D\0" - "GL_PROXY_TEXTURE_1D_ARRAY_EXT\0" - "GL_PROXY_TEXTURE_1D_EXT\0" - "GL_PROXY_TEXTURE_2D\0" - "GL_PROXY_TEXTURE_2D_ARRAY_EXT\0" - "GL_PROXY_TEXTURE_2D_EXT\0" - "GL_PROXY_TEXTURE_3D\0" - "GL_PROXY_TEXTURE_COLOR_TABLE_SGI\0" - "GL_PROXY_TEXTURE_CUBE_MAP\0" - "GL_PROXY_TEXTURE_CUBE_MAP_ARB\0" - "GL_PROXY_TEXTURE_RECTANGLE_ARB\0" - "GL_PROXY_TEXTURE_RECTANGLE_NV\0" - "GL_Q\0" - "GL_QUADRATIC_ATTENUATION\0" - "GL_QUADS\0" - "GL_QUAD_MESH_SUN\0" - "GL_QUAD_STRIP\0" - "GL_QUERY_COUNTER_BITS\0" - "GL_QUERY_COUNTER_BITS_ARB\0" - "GL_QUERY_RESULT\0" - "GL_QUERY_RESULT_ARB\0" - "GL_QUERY_RESULT_AVAILABLE\0" - "GL_QUERY_RESULT_AVAILABLE_ARB\0" - "GL_R\0" - "GL_R3_G3_B2\0" - "GL_RASTER_POSITION_UNCLIPPED_IBM\0" - "GL_READ_BUFFER\0" - "GL_READ_FRAMEBUFFER_BINDING_EXT\0" - "GL_READ_FRAMEBUFFER_EXT\0" - "GL_READ_ONLY\0" - "GL_READ_ONLY_ARB\0" - "GL_READ_WRITE\0" - "GL_READ_WRITE_ARB\0" - "GL_RED\0" - "GL_REDUCE\0" - "GL_REDUCE_EXT\0" - "GL_RED_BIAS\0" - "GL_RED_BITS\0" - "GL_RED_SCALE\0" - "GL_REFLECTION_MAP\0" - "GL_REFLECTION_MAP_ARB\0" - "GL_REFLECTION_MAP_NV\0" - "GL_RENDER\0" - "GL_RENDERBUFFER_BINDING_EXT\0" - "GL_RENDERBUFFER_EXT\0" - "GL_RENDERBUFFER_HEIGHT_EXT\0" - "GL_RENDERBUFFER_INTERNAL_FORMAT_EXT\0" - "GL_RENDERBUFFER_WIDTH_EXT\0" - "GL_RENDERER\0" - "GL_RENDER_MODE\0" - "GL_REPEAT\0" - "GL_REPLACE\0" - "GL_REPLACE_EXT\0" - "GL_REPLICATE_BORDER_HP\0" - "GL_RESCALE_NORMAL\0" - "GL_RESCALE_NORMAL_EXT\0" - "GL_RETURN\0" - "GL_RGB\0" - "GL_RGB10\0" - "GL_RGB10_A2\0" - "GL_RGB10_A2_EXT\0" - "GL_RGB10_EXT\0" - "GL_RGB12\0" - "GL_RGB12_EXT\0" - "GL_RGB16\0" - "GL_RGB16_EXT\0" - "GL_RGB2_EXT\0" - "GL_RGB4\0" - "GL_RGB4_EXT\0" - "GL_RGB4_S3TC\0" - "GL_RGB5\0" - "GL_RGB5_A1\0" - "GL_RGB5_A1_EXT\0" - "GL_RGB5_EXT\0" - "GL_RGB8\0" - "GL_RGB8_EXT\0" - "GL_RGBA\0" - "GL_RGBA12\0" - "GL_RGBA12_EXT\0" - "GL_RGBA16\0" - "GL_RGBA16_EXT\0" - "GL_RGBA2\0" - "GL_RGBA2_EXT\0" - "GL_RGBA4\0" - "GL_RGBA4_DXT5_S3TC\0" - "GL_RGBA4_EXT\0" - "GL_RGBA4_S3TC\0" - "GL_RGBA8\0" - "GL_RGBA8_EXT\0" - "GL_RGBA_DXT5_S3TC\0" - "GL_RGBA_MODE\0" - "GL_RGBA_S3TC\0" - "GL_RGB_S3TC\0" - "GL_RGB_SCALE\0" - "GL_RGB_SCALE_ARB\0" - "GL_RGB_SCALE_EXT\0" - "GL_RIGHT\0" - "GL_S\0" - "GL_SAMPLER_1D\0" - "GL_SAMPLER_1D_SHADOW\0" - "GL_SAMPLER_2D\0" - "GL_SAMPLER_2D_SHADOW\0" - "GL_SAMPLER_3D\0" - "GL_SAMPLER_CUBE\0" - "GL_SAMPLES\0" - "GL_SAMPLES_3DFX\0" - "GL_SAMPLES_ARB\0" - "GL_SAMPLES_PASSED\0" - "GL_SAMPLES_PASSED_ARB\0" - "GL_SAMPLE_ALPHA_TO_COVERAGE\0" - "GL_SAMPLE_ALPHA_TO_COVERAGE_ARB\0" - "GL_SAMPLE_ALPHA_TO_ONE\0" - "GL_SAMPLE_ALPHA_TO_ONE_ARB\0" - "GL_SAMPLE_BUFFERS\0" - "GL_SAMPLE_BUFFERS_3DFX\0" - "GL_SAMPLE_BUFFERS_ARB\0" - "GL_SAMPLE_COVERAGE\0" - "GL_SAMPLE_COVERAGE_ARB\0" - "GL_SAMPLE_COVERAGE_INVERT\0" - "GL_SAMPLE_COVERAGE_INVERT_ARB\0" - "GL_SAMPLE_COVERAGE_VALUE\0" - "GL_SAMPLE_COVERAGE_VALUE_ARB\0" - "GL_SCISSOR_BIT\0" - "GL_SCISSOR_BOX\0" - "GL_SCISSOR_TEST\0" - "GL_SECONDARY_COLOR_ARRAY\0" - "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING\0" - "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB\0" - "GL_SECONDARY_COLOR_ARRAY_POINTER\0" - "GL_SECONDARY_COLOR_ARRAY_SIZE\0" - "GL_SECONDARY_COLOR_ARRAY_STRIDE\0" - "GL_SECONDARY_COLOR_ARRAY_TYPE\0" - "GL_SELECT\0" - "GL_SELECTION_BUFFER_POINTER\0" - "GL_SELECTION_BUFFER_SIZE\0" - "GL_SEPARABLE_2D\0" - "GL_SEPARATE_SPECULAR_COLOR\0" - "GL_SEPARATE_SPECULAR_COLOR_EXT\0" - "GL_SET\0" - "GL_SHADER_OBJECT_ARB\0" - "GL_SHADER_SOURCE_LENGTH\0" - "GL_SHADER_TYPE\0" - "GL_SHADE_MODEL\0" - "GL_SHADING_LANGUAGE_VERSION\0" - "GL_SHADOW_AMBIENT_SGIX\0" - "GL_SHARED_TEXTURE_PALETTE_EXT\0" - "GL_SHININESS\0" - "GL_SHORT\0" - "GL_SINGLE_COLOR\0" - "GL_SINGLE_COLOR_EXT\0" - "GL_SLICE_ACCUM_SUN\0" - "GL_SMOOTH\0" - "GL_SMOOTH_LINE_WIDTH_GRANULARITY\0" - "GL_SMOOTH_LINE_WIDTH_RANGE\0" - "GL_SMOOTH_POINT_SIZE_GRANULARITY\0" - "GL_SMOOTH_POINT_SIZE_RANGE\0" - "GL_SOURCE0_ALPHA\0" - "GL_SOURCE0_ALPHA_ARB\0" - "GL_SOURCE0_ALPHA_EXT\0" - "GL_SOURCE0_RGB\0" - "GL_SOURCE0_RGB_ARB\0" - "GL_SOURCE0_RGB_EXT\0" - "GL_SOURCE1_ALPHA\0" - "GL_SOURCE1_ALPHA_ARB\0" - "GL_SOURCE1_ALPHA_EXT\0" - "GL_SOURCE1_RGB\0" - "GL_SOURCE1_RGB_ARB\0" - "GL_SOURCE1_RGB_EXT\0" - "GL_SOURCE2_ALPHA\0" - "GL_SOURCE2_ALPHA_ARB\0" - "GL_SOURCE2_ALPHA_EXT\0" - "GL_SOURCE2_RGB\0" - "GL_SOURCE2_RGB_ARB\0" - "GL_SOURCE2_RGB_EXT\0" - "GL_SOURCE3_ALPHA_NV\0" - "GL_SOURCE3_RGB_NV\0" - "GL_SPECULAR\0" - "GL_SPHERE_MAP\0" - "GL_SPOT_CUTOFF\0" - "GL_SPOT_DIRECTION\0" - "GL_SPOT_EXPONENT\0" - "GL_SRC0_ALPHA\0" - "GL_SRC0_RGB\0" - "GL_SRC1_ALPHA\0" - "GL_SRC1_RGB\0" - "GL_SRC2_ALPHA\0" - "GL_SRC2_RGB\0" - "GL_SRC_ALPHA\0" - "GL_SRC_ALPHA_SATURATE\0" - "GL_SRC_COLOR\0" - "GL_STACK_OVERFLOW\0" - "GL_STACK_UNDERFLOW\0" - "GL_STATIC_COPY\0" - "GL_STATIC_COPY_ARB\0" - "GL_STATIC_DRAW\0" - "GL_STATIC_DRAW_ARB\0" - "GL_STATIC_READ\0" - "GL_STATIC_READ_ARB\0" - "GL_STENCIL\0" - "GL_STENCIL_ATTACHMENT_EXT\0" - "GL_STENCIL_BACK_FAIL\0" - "GL_STENCIL_BACK_FUNC\0" - "GL_STENCIL_BACK_PASS_DEPTH_FAIL\0" - "GL_STENCIL_BACK_PASS_DEPTH_PASS\0" - "GL_STENCIL_BACK_REF\0" - "GL_STENCIL_BACK_VALUE_MASK\0" - "GL_STENCIL_BACK_WRITEMASK\0" - "GL_STENCIL_BITS\0" - "GL_STENCIL_BUFFER_BIT\0" - "GL_STENCIL_CLEAR_VALUE\0" - "GL_STENCIL_FAIL\0" - "GL_STENCIL_FUNC\0" - "GL_STENCIL_INDEX\0" - "GL_STENCIL_INDEX16_EXT\0" - "GL_STENCIL_INDEX1_EXT\0" - "GL_STENCIL_INDEX4_EXT\0" - "GL_STENCIL_INDEX8_EXT\0" - "GL_STENCIL_INDEX_EXT\0" - "GL_STENCIL_PASS_DEPTH_FAIL\0" - "GL_STENCIL_PASS_DEPTH_PASS\0" - "GL_STENCIL_REF\0" - "GL_STENCIL_TEST\0" - "GL_STENCIL_TEST_TWO_SIDE_EXT\0" - "GL_STENCIL_VALUE_MASK\0" - "GL_STENCIL_WRITEMASK\0" - "GL_STEREO\0" - "GL_STREAM_COPY\0" - "GL_STREAM_COPY_ARB\0" - "GL_STREAM_DRAW\0" - "GL_STREAM_DRAW_ARB\0" - "GL_STREAM_READ\0" - "GL_STREAM_READ_ARB\0" - "GL_SUBPIXEL_BITS\0" - "GL_SUBTRACT\0" - "GL_SUBTRACT_ARB\0" - "GL_T\0" - "GL_T2F_C3F_V3F\0" - "GL_T2F_C4F_N3F_V3F\0" - "GL_T2F_C4UB_V3F\0" - "GL_T2F_N3F_V3F\0" - "GL_T2F_V3F\0" - "GL_T4F_C4F_N3F_V4F\0" - "GL_T4F_V4F\0" - "GL_TABLE_TOO_LARGE_EXT\0" - "GL_TEXTURE\0" - "GL_TEXTURE0\0" - "GL_TEXTURE0_ARB\0" - "GL_TEXTURE1\0" - "GL_TEXTURE10\0" - "GL_TEXTURE10_ARB\0" - "GL_TEXTURE11\0" - "GL_TEXTURE11_ARB\0" - "GL_TEXTURE12\0" - "GL_TEXTURE12_ARB\0" - "GL_TEXTURE13\0" - "GL_TEXTURE13_ARB\0" - "GL_TEXTURE14\0" - "GL_TEXTURE14_ARB\0" - "GL_TEXTURE15\0" - "GL_TEXTURE15_ARB\0" - "GL_TEXTURE16\0" - "GL_TEXTURE16_ARB\0" - "GL_TEXTURE17\0" - "GL_TEXTURE17_ARB\0" - "GL_TEXTURE18\0" - "GL_TEXTURE18_ARB\0" - "GL_TEXTURE19\0" - "GL_TEXTURE19_ARB\0" - "GL_TEXTURE1_ARB\0" - "GL_TEXTURE2\0" - "GL_TEXTURE20\0" - "GL_TEXTURE20_ARB\0" - "GL_TEXTURE21\0" - "GL_TEXTURE21_ARB\0" - "GL_TEXTURE22\0" - "GL_TEXTURE22_ARB\0" - "GL_TEXTURE23\0" - "GL_TEXTURE23_ARB\0" - "GL_TEXTURE24\0" - "GL_TEXTURE24_ARB\0" - "GL_TEXTURE25\0" - "GL_TEXTURE25_ARB\0" - "GL_TEXTURE26\0" - "GL_TEXTURE26_ARB\0" - "GL_TEXTURE27\0" - "GL_TEXTURE27_ARB\0" - "GL_TEXTURE28\0" - "GL_TEXTURE28_ARB\0" - "GL_TEXTURE29\0" - "GL_TEXTURE29_ARB\0" - "GL_TEXTURE2_ARB\0" - "GL_TEXTURE3\0" - "GL_TEXTURE30\0" - "GL_TEXTURE30_ARB\0" - "GL_TEXTURE31\0" - "GL_TEXTURE31_ARB\0" - "GL_TEXTURE3_ARB\0" - "GL_TEXTURE4\0" - "GL_TEXTURE4_ARB\0" - "GL_TEXTURE5\0" - "GL_TEXTURE5_ARB\0" - "GL_TEXTURE6\0" - "GL_TEXTURE6_ARB\0" - "GL_TEXTURE7\0" - "GL_TEXTURE7_ARB\0" - "GL_TEXTURE8\0" - "GL_TEXTURE8_ARB\0" - "GL_TEXTURE9\0" - "GL_TEXTURE9_ARB\0" - "GL_TEXTURE_1D\0" - "GL_TEXTURE_1D_ARRAY_EXT\0" - "GL_TEXTURE_2D\0" - "GL_TEXTURE_2D_ARRAY_EXT\0" - "GL_TEXTURE_3D\0" - "GL_TEXTURE_ALPHA_SIZE\0" - "GL_TEXTURE_ALPHA_SIZE_EXT\0" - "GL_TEXTURE_BASE_LEVEL\0" - "GL_TEXTURE_BINDING_1D\0" - "GL_TEXTURE_BINDING_1D_ARRAY_EXT\0" - "GL_TEXTURE_BINDING_2D\0" - "GL_TEXTURE_BINDING_2D_ARRAY_EXT\0" - "GL_TEXTURE_BINDING_3D\0" - "GL_TEXTURE_BINDING_CUBE_MAP\0" - "GL_TEXTURE_BINDING_CUBE_MAP_ARB\0" - "GL_TEXTURE_BINDING_RECTANGLE_ARB\0" - "GL_TEXTURE_BINDING_RECTANGLE_NV\0" - "GL_TEXTURE_BIT\0" - "GL_TEXTURE_BLUE_SIZE\0" - "GL_TEXTURE_BLUE_SIZE_EXT\0" - "GL_TEXTURE_BORDER\0" - "GL_TEXTURE_BORDER_COLOR\0" - "GL_TEXTURE_CLIPMAP_CENTER_SGIX\0" - "GL_TEXTURE_CLIPMAP_DEPTH_SGIX\0" - "GL_TEXTURE_CLIPMAP_FRAME_SGIX\0" - "GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX\0" - "GL_TEXTURE_CLIPMAP_OFFSET_SGIX\0" - "GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX\0" - "GL_TEXTURE_COLOR_TABLE_SGI\0" - "GL_TEXTURE_COLOR_WRITEMASK_SGIS\0" - "GL_TEXTURE_COMPARE_FAIL_VALUE_ARB\0" - "GL_TEXTURE_COMPARE_FUNC\0" - "GL_TEXTURE_COMPARE_FUNC_ARB\0" - "GL_TEXTURE_COMPARE_MODE\0" - "GL_TEXTURE_COMPARE_MODE_ARB\0" - "GL_TEXTURE_COMPARE_OPERATOR_SGIX\0" - "GL_TEXTURE_COMPARE_SGIX\0" - "GL_TEXTURE_COMPONENTS\0" - "GL_TEXTURE_COMPRESSED\0" - "GL_TEXTURE_COMPRESSED_ARB\0" - "GL_TEXTURE_COMPRESSED_FORMATS_ARB\0" - "GL_TEXTURE_COMPRESSED_IMAGE_SIZE\0" - "GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB\0" - "GL_TEXTURE_COMPRESSION_HINT\0" - "GL_TEXTURE_COMPRESSION_HINT_ARB\0" - "GL_TEXTURE_COORD_ARRAY\0" - "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING\0" - "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB\0" - "GL_TEXTURE_COORD_ARRAY_POINTER\0" - "GL_TEXTURE_COORD_ARRAY_SIZE\0" - "GL_TEXTURE_COORD_ARRAY_STRIDE\0" - "GL_TEXTURE_COORD_ARRAY_TYPE\0" - "GL_TEXTURE_CUBE_MAP\0" - "GL_TEXTURE_CUBE_MAP_ARB\0" - "GL_TEXTURE_CUBE_MAP_NEGATIVE_X\0" - "GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB\0" - "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y\0" - "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB\0" - "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z\0" - "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB\0" - "GL_TEXTURE_CUBE_MAP_POSITIVE_X\0" - "GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB\0" - "GL_TEXTURE_CUBE_MAP_POSITIVE_Y\0" - "GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\0" - "GL_TEXTURE_CUBE_MAP_POSITIVE_Z\0" - "GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\0" - "GL_TEXTURE_DEPTH\0" - "GL_TEXTURE_DEPTH_SIZE\0" - "GL_TEXTURE_DEPTH_SIZE_ARB\0" - "GL_TEXTURE_ENV\0" - "GL_TEXTURE_ENV_COLOR\0" - "GL_TEXTURE_ENV_MODE\0" - "GL_TEXTURE_FILTER_CONTROL\0" - "GL_TEXTURE_GEN_MODE\0" - "GL_TEXTURE_GEN_Q\0" - "GL_TEXTURE_GEN_R\0" - "GL_TEXTURE_GEN_S\0" - "GL_TEXTURE_GEN_T\0" - "GL_TEXTURE_GEQUAL_R_SGIX\0" - "GL_TEXTURE_GREEN_SIZE\0" - "GL_TEXTURE_GREEN_SIZE_EXT\0" - "GL_TEXTURE_HEIGHT\0" - "GL_TEXTURE_INDEX_SIZE_EXT\0" - "GL_TEXTURE_INTENSITY_SIZE\0" - "GL_TEXTURE_INTENSITY_SIZE_EXT\0" - "GL_TEXTURE_INTERNAL_FORMAT\0" - "GL_TEXTURE_LEQUAL_R_SGIX\0" - "GL_TEXTURE_LOD_BIAS\0" - "GL_TEXTURE_LOD_BIAS_EXT\0" - "GL_TEXTURE_LOD_BIAS_R_SGIX\0" - "GL_TEXTURE_LOD_BIAS_S_SGIX\0" - "GL_TEXTURE_LOD_BIAS_T_SGIX\0" - "GL_TEXTURE_LUMINANCE_SIZE\0" - "GL_TEXTURE_LUMINANCE_SIZE_EXT\0" - "GL_TEXTURE_MAG_FILTER\0" - "GL_TEXTURE_MATRIX\0" - "GL_TEXTURE_MAX_ANISOTROPY_EXT\0" - "GL_TEXTURE_MAX_CLAMP_R_SGIX\0" - "GL_TEXTURE_MAX_CLAMP_S_SGIX\0" - "GL_TEXTURE_MAX_CLAMP_T_SGIX\0" - "GL_TEXTURE_MAX_LEVEL\0" - "GL_TEXTURE_MAX_LOD\0" - "GL_TEXTURE_MIN_FILTER\0" - "GL_TEXTURE_MIN_LOD\0" - "GL_TEXTURE_PRIORITY\0" - "GL_TEXTURE_RECTANGLE_ARB\0" - "GL_TEXTURE_RECTANGLE_NV\0" - "GL_TEXTURE_RED_SIZE\0" - "GL_TEXTURE_RED_SIZE_EXT\0" - "GL_TEXTURE_RESIDENT\0" - "GL_TEXTURE_STACK_DEPTH\0" - "GL_TEXTURE_TOO_LARGE_EXT\0" - "GL_TEXTURE_UNSIGNED_REMAP_MODE_NV\0" - "GL_TEXTURE_WIDTH\0" - "GL_TEXTURE_WRAP_R\0" - "GL_TEXTURE_WRAP_S\0" - "GL_TEXTURE_WRAP_T\0" - "GL_TIME_ELAPSED_EXT\0" - "GL_TRACK_MATRIX_NV\0" - "GL_TRACK_MATRIX_TRANSFORM_NV\0" - "GL_TRANSFORM_BIT\0" - "GL_TRANSPOSE_COLOR_MATRIX\0" - "GL_TRANSPOSE_COLOR_MATRIX_ARB\0" - "GL_TRANSPOSE_CURRENT_MATRIX_ARB\0" - "GL_TRANSPOSE_MODELVIEW_MATRIX\0" - "GL_TRANSPOSE_MODELVIEW_MATRIX_ARB\0" - "GL_TRANSPOSE_NV\0" - "GL_TRANSPOSE_PROJECTION_MATRIX\0" - "GL_TRANSPOSE_PROJECTION_MATRIX_ARB\0" - "GL_TRANSPOSE_TEXTURE_MATRIX\0" - "GL_TRANSPOSE_TEXTURE_MATRIX_ARB\0" - "GL_TRIANGLES\0" - "GL_TRIANGLE_FAN\0" - "GL_TRIANGLE_MESH_SUN\0" - "GL_TRIANGLE_STRIP\0" - "GL_TRUE\0" - "GL_UNPACK_ALIGNMENT\0" - "GL_UNPACK_IMAGE_HEIGHT\0" - "GL_UNPACK_LSB_FIRST\0" - "GL_UNPACK_ROW_LENGTH\0" - "GL_UNPACK_SKIP_IMAGES\0" - "GL_UNPACK_SKIP_PIXELS\0" - "GL_UNPACK_SKIP_ROWS\0" - "GL_UNPACK_SWAP_BYTES\0" - "GL_UNSIGNED_BYTE\0" - "GL_UNSIGNED_BYTE_2_3_3_REV\0" - "GL_UNSIGNED_BYTE_3_3_2\0" - "GL_UNSIGNED_INT\0" - "GL_UNSIGNED_INT_10_10_10_2\0" - "GL_UNSIGNED_INT_24_8_NV\0" - "GL_UNSIGNED_INT_2_10_10_10_REV\0" - "GL_UNSIGNED_INT_8_8_8_8\0" - "GL_UNSIGNED_INT_8_8_8_8_REV\0" - "GL_UNSIGNED_SHORT\0" - "GL_UNSIGNED_SHORT_1_5_5_5_REV\0" - "GL_UNSIGNED_SHORT_4_4_4_4\0" - "GL_UNSIGNED_SHORT_4_4_4_4_REV\0" - "GL_UNSIGNED_SHORT_5_5_5_1\0" - "GL_UNSIGNED_SHORT_5_6_5\0" - "GL_UNSIGNED_SHORT_5_6_5_REV\0" - "GL_UNSIGNED_SHORT_8_8_APPLE\0" - "GL_UNSIGNED_SHORT_8_8_MESA\0" - "GL_UNSIGNED_SHORT_8_8_REV_APPLE\0" - "GL_UNSIGNED_SHORT_8_8_REV_MESA\0" - "GL_UPPER_LEFT\0" - "GL_V2F\0" - "GL_V3F\0" - "GL_VALIDATE_STATUS\0" - "GL_VENDOR\0" - "GL_VERSION\0" - "GL_VERTEX_ARRAY\0" - "GL_VERTEX_ARRAY_BINDING_APPLE\0" - "GL_VERTEX_ARRAY_BUFFER_BINDING\0" - "GL_VERTEX_ARRAY_BUFFER_BINDING_ARB\0" - "GL_VERTEX_ARRAY_POINTER\0" - "GL_VERTEX_ARRAY_SIZE\0" - "GL_VERTEX_ARRAY_STRIDE\0" - "GL_VERTEX_ARRAY_TYPE\0" - "GL_VERTEX_ATTRIB_ARRAY0_NV\0" - "GL_VERTEX_ATTRIB_ARRAY10_NV\0" - "GL_VERTEX_ATTRIB_ARRAY11_NV\0" - "GL_VERTEX_ATTRIB_ARRAY12_NV\0" - "GL_VERTEX_ATTRIB_ARRAY13_NV\0" - "GL_VERTEX_ATTRIB_ARRAY14_NV\0" - "GL_VERTEX_ATTRIB_ARRAY15_NV\0" - "GL_VERTEX_ATTRIB_ARRAY1_NV\0" - "GL_VERTEX_ATTRIB_ARRAY2_NV\0" - "GL_VERTEX_ATTRIB_ARRAY3_NV\0" - "GL_VERTEX_ATTRIB_ARRAY4_NV\0" - "GL_VERTEX_ATTRIB_ARRAY5_NV\0" - "GL_VERTEX_ATTRIB_ARRAY6_NV\0" - "GL_VERTEX_ATTRIB_ARRAY7_NV\0" - "GL_VERTEX_ATTRIB_ARRAY8_NV\0" - "GL_VERTEX_ATTRIB_ARRAY9_NV\0" - "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING\0" - "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB\0" - "GL_VERTEX_ATTRIB_ARRAY_ENABLED\0" - "GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB\0" - "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED\0" - "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB\0" - "GL_VERTEX_ATTRIB_ARRAY_POINTER\0" - "GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB\0" - "GL_VERTEX_ATTRIB_ARRAY_SIZE\0" - "GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB\0" - "GL_VERTEX_ATTRIB_ARRAY_STRIDE\0" - "GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB\0" - "GL_VERTEX_ATTRIB_ARRAY_TYPE\0" - "GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB\0" - "GL_VERTEX_BLEND_ARB\0" - "GL_VERTEX_PROGRAM_ARB\0" - "GL_VERTEX_PROGRAM_BINDING_NV\0" - "GL_VERTEX_PROGRAM_NV\0" - "GL_VERTEX_PROGRAM_POINT_SIZE\0" - "GL_VERTEX_PROGRAM_POINT_SIZE_ARB\0" - "GL_VERTEX_PROGRAM_POINT_SIZE_NV\0" - "GL_VERTEX_PROGRAM_TWO_SIDE\0" - "GL_VERTEX_PROGRAM_TWO_SIDE_ARB\0" - "GL_VERTEX_PROGRAM_TWO_SIDE_NV\0" - "GL_VERTEX_SHADER\0" - "GL_VERTEX_SHADER_ARB\0" - "GL_VERTEX_STATE_PROGRAM_NV\0" - "GL_VIEWPORT\0" - "GL_VIEWPORT_BIT\0" - "GL_WEIGHT_ARRAY_ARB\0" - "GL_WEIGHT_ARRAY_BUFFER_BINDING\0" - "GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB\0" - "GL_WEIGHT_ARRAY_POINTER_ARB\0" - "GL_WEIGHT_ARRAY_SIZE_ARB\0" - "GL_WEIGHT_ARRAY_STRIDE_ARB\0" - "GL_WEIGHT_ARRAY_TYPE_ARB\0" - "GL_WEIGHT_SUM_UNITY_ARB\0" - "GL_WRAP_BORDER_SUN\0" - "GL_WRITE_ONLY\0" - "GL_WRITE_ONLY_ARB\0" - "GL_XOR\0" - "GL_YCBCR_422_APPLE\0" - "GL_YCBCR_MESA\0" - "GL_ZERO\0" - "GL_ZOOM_X\0" - "GL_ZOOM_Y\0" - ; - -static const enum_elt all_enums[1746] = -{ - { 0, 0x00000600 }, /* GL_2D */ - { 6, 0x00001407 }, /* GL_2_BYTES */ - { 17, 0x00000601 }, /* GL_3D */ - { 23, 0x00000602 }, /* GL_3D_COLOR */ - { 35, 0x00000603 }, /* GL_3D_COLOR_TEXTURE */ - { 55, 0x00001408 }, /* GL_3_BYTES */ - { 66, 0x00000604 }, /* GL_4D_COLOR_TEXTURE */ - { 86, 0x00001409 }, /* GL_4_BYTES */ - { 97, 0x00000100 }, /* GL_ACCUM */ - { 106, 0x00000D5B }, /* GL_ACCUM_ALPHA_BITS */ - { 126, 0x00000D5A }, /* GL_ACCUM_BLUE_BITS */ - { 145, 0x00000200 }, /* GL_ACCUM_BUFFER_BIT */ - { 165, 0x00000B80 }, /* GL_ACCUM_CLEAR_VALUE */ - { 186, 0x00000D59 }, /* GL_ACCUM_GREEN_BITS */ - { 206, 0x00000D58 }, /* GL_ACCUM_RED_BITS */ - { 224, 0x00008B89 }, /* GL_ACTIVE_ATTRIBUTES */ - { 245, 0x00008B8A }, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */ - { 276, 0x00008911 }, /* GL_ACTIVE_STENCIL_FACE_EXT */ - { 303, 0x000084E0 }, /* GL_ACTIVE_TEXTURE */ - { 321, 0x000084E0 }, /* GL_ACTIVE_TEXTURE_ARB */ - { 343, 0x00008B86 }, /* GL_ACTIVE_UNIFORMS */ - { 362, 0x00008B87 }, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */ - { 391, 0x000086A5 }, /* GL_ACTIVE_VERTEX_UNITS_ARB */ - { 418, 0x00000104 }, /* GL_ADD */ - { 425, 0x00008574 }, /* GL_ADD_SIGNED */ - { 439, 0x00008574 }, /* GL_ADD_SIGNED_ARB */ - { 457, 0x00008574 }, /* GL_ADD_SIGNED_EXT */ - { 475, 0x0000846E }, /* GL_ALIASED_LINE_WIDTH_RANGE */ - { 503, 0x0000846D }, /* GL_ALIASED_POINT_SIZE_RANGE */ - { 531, 0x000FFFFF }, /* GL_ALL_ATTRIB_BITS */ - { 550, 0xFFFFFFFF }, /* GL_ALL_CLIENT_ATTRIB_BITS */ - { 576, 0x00001906 }, /* GL_ALPHA */ - { 585, 0x0000803D }, /* GL_ALPHA12 */ - { 596, 0x0000803D }, /* GL_ALPHA12_EXT */ - { 611, 0x0000803E }, /* GL_ALPHA16 */ - { 622, 0x0000803E }, /* GL_ALPHA16_EXT */ - { 637, 0x0000803B }, /* GL_ALPHA4 */ - { 647, 0x0000803B }, /* GL_ALPHA4_EXT */ - { 661, 0x0000803C }, /* GL_ALPHA8 */ - { 671, 0x0000803C }, /* GL_ALPHA8_EXT */ - { 685, 0x00000D1D }, /* GL_ALPHA_BIAS */ - { 699, 0x00000D55 }, /* GL_ALPHA_BITS */ - { 713, 0x00000D1C }, /* GL_ALPHA_SCALE */ - { 728, 0x00000BC0 }, /* GL_ALPHA_TEST */ - { 742, 0x00000BC1 }, /* GL_ALPHA_TEST_FUNC */ - { 761, 0x00000BC2 }, /* GL_ALPHA_TEST_REF */ - { 779, 0x00000207 }, /* GL_ALWAYS */ - { 789, 0x00001200 }, /* GL_AMBIENT */ - { 800, 0x00001602 }, /* GL_AMBIENT_AND_DIFFUSE */ - { 823, 0x00001501 }, /* GL_AND */ - { 830, 0x00001504 }, /* GL_AND_INVERTED */ - { 846, 0x00001502 }, /* GL_AND_REVERSE */ - { 861, 0x00008892 }, /* GL_ARRAY_BUFFER */ - { 877, 0x00008892 }, /* GL_ARRAY_BUFFER_ARB */ - { 897, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING */ - { 921, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING_ARB */ - { 949, 0x00008B85 }, /* GL_ATTACHED_SHADERS */ - { 969, 0x00008645 }, /* GL_ATTRIB_ARRAY_POINTER_NV */ - { 996, 0x00008623 }, /* GL_ATTRIB_ARRAY_SIZE_NV */ - { 1020, 0x00008624 }, /* GL_ATTRIB_ARRAY_STRIDE_NV */ - { 1046, 0x00008625 }, /* GL_ATTRIB_ARRAY_TYPE_NV */ - { 1070, 0x00000BB0 }, /* GL_ATTRIB_STACK_DEPTH */ - { 1092, 0x00000D80 }, /* GL_AUTO_NORMAL */ - { 1107, 0x00000409 }, /* GL_AUX0 */ - { 1115, 0x0000040A }, /* GL_AUX1 */ - { 1123, 0x0000040B }, /* GL_AUX2 */ - { 1131, 0x0000040C }, /* GL_AUX3 */ - { 1139, 0x00000C00 }, /* GL_AUX_BUFFERS */ - { 1154, 0x00000405 }, /* GL_BACK */ - { 1162, 0x00000402 }, /* GL_BACK_LEFT */ - { 1175, 0x00000403 }, /* GL_BACK_RIGHT */ - { 1189, 0x000080E0 }, /* GL_BGR */ - { 1196, 0x000080E1 }, /* GL_BGRA */ - { 1204, 0x00001A00 }, /* GL_BITMAP */ - { 1214, 0x00000704 }, /* GL_BITMAP_TOKEN */ - { 1230, 0x00000BE2 }, /* GL_BLEND */ - { 1239, 0x00008005 }, /* GL_BLEND_COLOR */ - { 1254, 0x00008005 }, /* GL_BLEND_COLOR_EXT */ - { 1273, 0x00000BE0 }, /* GL_BLEND_DST */ - { 1286, 0x000080CA }, /* GL_BLEND_DST_ALPHA */ - { 1305, 0x000080C8 }, /* GL_BLEND_DST_RGB */ - { 1322, 0x00008009 }, /* GL_BLEND_EQUATION */ - { 1340, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA */ - { 1364, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA_EXT */ - { 1392, 0x00008009 }, /* GL_BLEND_EQUATION_EXT */ - { 1414, 0x00008009 }, /* GL_BLEND_EQUATION_RGB_EXT */ - { 1440, 0x00000BE1 }, /* GL_BLEND_SRC */ - { 1453, 0x000080CB }, /* GL_BLEND_SRC_ALPHA */ - { 1472, 0x000080C9 }, /* GL_BLEND_SRC_RGB */ - { 1489, 0x00001905 }, /* GL_BLUE */ - { 1497, 0x00000D1B }, /* GL_BLUE_BIAS */ - { 1510, 0x00000D54 }, /* GL_BLUE_BITS */ - { 1523, 0x00000D1A }, /* GL_BLUE_SCALE */ - { 1537, 0x00008B56 }, /* GL_BOOL */ - { 1545, 0x00008B56 }, /* GL_BOOL_ARB */ - { 1557, 0x00008B57 }, /* GL_BOOL_VEC2 */ - { 1570, 0x00008B57 }, /* GL_BOOL_VEC2_ARB */ - { 1587, 0x00008B58 }, /* GL_BOOL_VEC3 */ - { 1600, 0x00008B58 }, /* GL_BOOL_VEC3_ARB */ - { 1617, 0x00008B59 }, /* GL_BOOL_VEC4 */ - { 1630, 0x00008B59 }, /* GL_BOOL_VEC4_ARB */ - { 1647, 0x000088BB }, /* GL_BUFFER_ACCESS */ - { 1664, 0x000088BB }, /* GL_BUFFER_ACCESS_ARB */ - { 1685, 0x000088BC }, /* GL_BUFFER_MAPPED */ - { 1702, 0x000088BC }, /* GL_BUFFER_MAPPED_ARB */ - { 1723, 0x000088BD }, /* GL_BUFFER_MAP_POINTER */ - { 1745, 0x000088BD }, /* GL_BUFFER_MAP_POINTER_ARB */ - { 1771, 0x00008764 }, /* GL_BUFFER_SIZE */ - { 1786, 0x00008764 }, /* GL_BUFFER_SIZE_ARB */ - { 1805, 0x00008765 }, /* GL_BUFFER_USAGE */ - { 1821, 0x00008765 }, /* GL_BUFFER_USAGE_ARB */ - { 1841, 0x00001400 }, /* GL_BYTE */ - { 1849, 0x00002A24 }, /* GL_C3F_V3F */ - { 1860, 0x00002A26 }, /* GL_C4F_N3F_V3F */ - { 1875, 0x00002A22 }, /* GL_C4UB_V2F */ - { 1887, 0x00002A23 }, /* GL_C4UB_V3F */ - { 1899, 0x00000901 }, /* GL_CCW */ - { 1906, 0x00002900 }, /* GL_CLAMP */ - { 1915, 0x0000812D }, /* GL_CLAMP_TO_BORDER */ - { 1934, 0x0000812D }, /* GL_CLAMP_TO_BORDER_ARB */ - { 1957, 0x0000812D }, /* GL_CLAMP_TO_BORDER_SGIS */ - { 1981, 0x0000812F }, /* GL_CLAMP_TO_EDGE */ - { 1998, 0x0000812F }, /* GL_CLAMP_TO_EDGE_SGIS */ - { 2020, 0x00001500 }, /* GL_CLEAR */ - { 2029, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE */ - { 2054, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE_ARB */ - { 2083, 0xFFFFFFFF }, /* GL_CLIENT_ALL_ATTRIB_BITS */ - { 2109, 0x00000BB1 }, /* GL_CLIENT_ATTRIB_STACK_DEPTH */ - { 2138, 0x00000001 }, /* GL_CLIENT_PIXEL_STORE_BIT */ - { 2164, 0x00000002 }, /* GL_CLIENT_VERTEX_ARRAY_BIT */ - { 2191, 0x00003000 }, /* GL_CLIP_PLANE0 */ - { 2206, 0x00003001 }, /* GL_CLIP_PLANE1 */ - { 2221, 0x00003002 }, /* GL_CLIP_PLANE2 */ - { 2236, 0x00003003 }, /* GL_CLIP_PLANE3 */ - { 2251, 0x00003004 }, /* GL_CLIP_PLANE4 */ - { 2266, 0x00003005 }, /* GL_CLIP_PLANE5 */ - { 2281, 0x000080F0 }, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */ - { 2314, 0x00000A00 }, /* GL_COEFF */ - { 2323, 0x00001800 }, /* GL_COLOR */ - { 2332, 0x00008076 }, /* GL_COLOR_ARRAY */ - { 2347, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING */ - { 2377, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING_ARB */ - { 2411, 0x00008090 }, /* GL_COLOR_ARRAY_POINTER */ - { 2434, 0x00008081 }, /* GL_COLOR_ARRAY_SIZE */ - { 2454, 0x00008083 }, /* GL_COLOR_ARRAY_STRIDE */ - { 2476, 0x00008082 }, /* GL_COLOR_ARRAY_TYPE */ - { 2496, 0x00008CE0 }, /* GL_COLOR_ATTACHMENT0_EXT */ - { 2521, 0x00008CEA }, /* GL_COLOR_ATTACHMENT10_EXT */ - { 2547, 0x00008CEB }, /* GL_COLOR_ATTACHMENT11_EXT */ - { 2573, 0x00008CEC }, /* GL_COLOR_ATTACHMENT12_EXT */ - { 2599, 0x00008CED }, /* GL_COLOR_ATTACHMENT13_EXT */ - { 2625, 0x00008CEE }, /* GL_COLOR_ATTACHMENT14_EXT */ - { 2651, 0x00008CEF }, /* GL_COLOR_ATTACHMENT15_EXT */ - { 2677, 0x00008CE1 }, /* GL_COLOR_ATTACHMENT1_EXT */ - { 2702, 0x00008CE2 }, /* GL_COLOR_ATTACHMENT2_EXT */ - { 2727, 0x00008CE3 }, /* GL_COLOR_ATTACHMENT3_EXT */ - { 2752, 0x00008CE4 }, /* GL_COLOR_ATTACHMENT4_EXT */ - { 2777, 0x00008CE5 }, /* GL_COLOR_ATTACHMENT5_EXT */ - { 2802, 0x00008CE6 }, /* GL_COLOR_ATTACHMENT6_EXT */ - { 2827, 0x00008CE7 }, /* GL_COLOR_ATTACHMENT7_EXT */ - { 2852, 0x00008CE8 }, /* GL_COLOR_ATTACHMENT8_EXT */ - { 2877, 0x00008CE9 }, /* GL_COLOR_ATTACHMENT9_EXT */ - { 2902, 0x00004000 }, /* GL_COLOR_BUFFER_BIT */ - { 2922, 0x00000C22 }, /* GL_COLOR_CLEAR_VALUE */ - { 2943, 0x00001900 }, /* GL_COLOR_INDEX */ - { 2958, 0x00001603 }, /* GL_COLOR_INDEXES */ - { 2975, 0x00000BF2 }, /* GL_COLOR_LOGIC_OP */ - { 2993, 0x00000B57 }, /* GL_COLOR_MATERIAL */ - { 3011, 0x00000B55 }, /* GL_COLOR_MATERIAL_FACE */ - { 3034, 0x00000B56 }, /* GL_COLOR_MATERIAL_PARAMETER */ - { 3062, 0x000080B1 }, /* GL_COLOR_MATRIX */ - { 3078, 0x000080B1 }, /* GL_COLOR_MATRIX_SGI */ - { 3098, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH */ - { 3126, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH_SGI */ - { 3158, 0x00008458 }, /* GL_COLOR_SUM */ - { 3171, 0x00008458 }, /* GL_COLOR_SUM_ARB */ - { 3188, 0x000080D0 }, /* GL_COLOR_TABLE */ - { 3203, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE */ - { 3229, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE_EXT */ - { 3259, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE_SGI */ - { 3289, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS */ - { 3309, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS_SGI */ - { 3333, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE */ - { 3358, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE_EXT */ - { 3387, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE_SGI */ - { 3416, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT */ - { 3438, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT_EXT */ - { 3464, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT_SGI */ - { 3490, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE */ - { 3516, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE_EXT */ - { 3546, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE_SGI */ - { 3576, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE */ - { 3606, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE_EXT */ - { 3640, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE_SGI */ - { 3674, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE */ - { 3704, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE_EXT */ - { 3738, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE_SGI */ - { 3772, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE */ - { 3796, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE_EXT */ - { 3824, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE_SGI */ - { 3852, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE */ - { 3873, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE_SGI */ - { 3898, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH */ - { 3919, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH_EXT */ - { 3944, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH_SGI */ - { 3969, 0x00000C23 }, /* GL_COLOR_WRITEMASK */ - { 3988, 0x00008570 }, /* GL_COMBINE */ - { 3999, 0x00008503 }, /* GL_COMBINE4 */ - { 4011, 0x00008572 }, /* GL_COMBINE_ALPHA */ - { 4028, 0x00008572 }, /* GL_COMBINE_ALPHA_ARB */ - { 4049, 0x00008572 }, /* GL_COMBINE_ALPHA_EXT */ - { 4070, 0x00008570 }, /* GL_COMBINE_ARB */ - { 4085, 0x00008570 }, /* GL_COMBINE_EXT */ - { 4100, 0x00008571 }, /* GL_COMBINE_RGB */ - { 4115, 0x00008571 }, /* GL_COMBINE_RGB_ARB */ - { 4134, 0x00008571 }, /* GL_COMBINE_RGB_EXT */ - { 4153, 0x0000884E }, /* GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT */ - { 4189, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE */ - { 4213, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE_ARB */ - { 4241, 0x00001300 }, /* GL_COMPILE */ - { 4252, 0x00001301 }, /* GL_COMPILE_AND_EXECUTE */ - { 4275, 0x00008B81 }, /* GL_COMPILE_STATUS */ - { 4293, 0x000084E9 }, /* GL_COMPRESSED_ALPHA */ - { 4313, 0x000084E9 }, /* GL_COMPRESSED_ALPHA_ARB */ - { 4337, 0x000084EC }, /* GL_COMPRESSED_INTENSITY */ - { 4361, 0x000084EC }, /* GL_COMPRESSED_INTENSITY_ARB */ - { 4389, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE */ - { 4413, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA */ - { 4443, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA_ARB */ - { 4477, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE_ARB */ - { 4505, 0x000084ED }, /* GL_COMPRESSED_RGB */ - { 4523, 0x000084EE }, /* GL_COMPRESSED_RGBA */ - { 4542, 0x000084EE }, /* GL_COMPRESSED_RGBA_ARB */ - { 4565, 0x000086B1 }, /* GL_COMPRESSED_RGBA_FXT1_3DFX */ - { 4594, 0x000083F1 }, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */ - { 4627, 0x000083F2 }, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */ - { 4660, 0x000083F3 }, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */ - { 4693, 0x000084ED }, /* GL_COMPRESSED_RGB_ARB */ - { 4715, 0x000086B0 }, /* GL_COMPRESSED_RGB_FXT1_3DFX */ - { 4743, 0x000083F0 }, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */ - { 4775, 0x000086A3 }, /* GL_COMPRESSED_TEXTURE_FORMATS */ - { 4805, 0x00008576 }, /* GL_CONSTANT */ - { 4817, 0x00008003 }, /* GL_CONSTANT_ALPHA */ - { 4835, 0x00008003 }, /* GL_CONSTANT_ALPHA_EXT */ - { 4857, 0x00008576 }, /* GL_CONSTANT_ARB */ - { 4873, 0x00001207 }, /* GL_CONSTANT_ATTENUATION */ - { 4897, 0x00008151 }, /* GL_CONSTANT_BORDER_HP */ - { 4919, 0x00008001 }, /* GL_CONSTANT_COLOR */ - { 4937, 0x00008001 }, /* GL_CONSTANT_COLOR_EXT */ - { 4959, 0x00008576 }, /* GL_CONSTANT_EXT */ - { 4975, 0x00008010 }, /* GL_CONVOLUTION_1D */ - { 4993, 0x00008011 }, /* GL_CONVOLUTION_2D */ - { 5011, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR */ - { 5039, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR_HP */ - { 5070, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE */ - { 5097, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE_EXT */ - { 5128, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS */ - { 5155, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS_EXT */ - { 5186, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE */ - { 5214, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE_EXT */ - { 5246, 0x00008017 }, /* GL_CONVOLUTION_FORMAT */ - { 5268, 0x00008017 }, /* GL_CONVOLUTION_FORMAT_EXT */ - { 5294, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT */ - { 5316, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT_EXT */ - { 5342, 0x00008018 }, /* GL_CONVOLUTION_WIDTH */ - { 5363, 0x00008018 }, /* GL_CONVOLUTION_WIDTH_EXT */ - { 5388, 0x00008862 }, /* GL_COORD_REPLACE */ - { 5405, 0x00008862 }, /* GL_COORD_REPLACE_ARB */ - { 5426, 0x00008862 }, /* GL_COORD_REPLACE_NV */ - { 5446, 0x00001503 }, /* GL_COPY */ - { 5454, 0x0000150C }, /* GL_COPY_INVERTED */ - { 5471, 0x00000706 }, /* GL_COPY_PIXEL_TOKEN */ - { 5491, 0x00000B44 }, /* GL_CULL_FACE */ - { 5504, 0x00000B45 }, /* GL_CULL_FACE_MODE */ - { 5522, 0x000081AA }, /* GL_CULL_VERTEX_EXT */ - { 5541, 0x000081AC }, /* GL_CULL_VERTEX_EYE_POSITION_EXT */ - { 5573, 0x000081AB }, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */ - { 5608, 0x00008626 }, /* GL_CURRENT_ATTRIB_NV */ - { 5629, 0x00000001 }, /* GL_CURRENT_BIT */ - { 5644, 0x00000B00 }, /* GL_CURRENT_COLOR */ - { 5661, 0x00008453 }, /* GL_CURRENT_FOG_COORD */ - { 5682, 0x00008453 }, /* GL_CURRENT_FOG_COORDINATE */ - { 5708, 0x00000B01 }, /* GL_CURRENT_INDEX */ - { 5725, 0x00008641 }, /* GL_CURRENT_MATRIX_ARB */ - { 5747, 0x00008845 }, /* GL_CURRENT_MATRIX_INDEX_ARB */ - { 5775, 0x00008641 }, /* GL_CURRENT_MATRIX_NV */ - { 5796, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */ - { 5830, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_NV */ - { 5863, 0x00000B02 }, /* GL_CURRENT_NORMAL */ - { 5881, 0x00008843 }, /* GL_CURRENT_PALETTE_MATRIX_ARB */ - { 5911, 0x00008B8D }, /* GL_CURRENT_PROGRAM */ - { 5930, 0x00008865 }, /* GL_CURRENT_QUERY */ - { 5947, 0x00008865 }, /* GL_CURRENT_QUERY_ARB */ - { 5968, 0x00000B04 }, /* GL_CURRENT_RASTER_COLOR */ - { 5992, 0x00000B09 }, /* GL_CURRENT_RASTER_DISTANCE */ - { 6019, 0x00000B05 }, /* GL_CURRENT_RASTER_INDEX */ - { 6043, 0x00000B07 }, /* GL_CURRENT_RASTER_POSITION */ - { 6070, 0x00000B08 }, /* GL_CURRENT_RASTER_POSITION_VALID */ - { 6103, 0x00000B06 }, /* GL_CURRENT_RASTER_TEXTURE_COORDS */ - { 6136, 0x00008459 }, /* GL_CURRENT_SECONDARY_COLOR */ - { 6163, 0x00000B03 }, /* GL_CURRENT_TEXTURE_COORDS */ - { 6189, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB */ - { 6214, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB_ARB */ - { 6243, 0x000086A8 }, /* GL_CURRENT_WEIGHT_ARB */ - { 6265, 0x00000900 }, /* GL_CW */ - { 6271, 0x0000875B }, /* GL_DEBUG_ASSERT_MESA */ - { 6292, 0x00008759 }, /* GL_DEBUG_OBJECT_MESA */ - { 6313, 0x0000875A }, /* GL_DEBUG_PRINT_MESA */ - { 6333, 0x00002101 }, /* GL_DECAL */ - { 6342, 0x00001E03 }, /* GL_DECR */ - { 6350, 0x00008508 }, /* GL_DECR_WRAP */ - { 6363, 0x00008508 }, /* GL_DECR_WRAP_EXT */ - { 6380, 0x00008B80 }, /* GL_DELETE_STATUS */ - { 6397, 0x00001801 }, /* GL_DEPTH */ - { 6406, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT_EXT */ - { 6430, 0x00000D1F }, /* GL_DEPTH_BIAS */ - { 6444, 0x00000D56 }, /* GL_DEPTH_BITS */ - { 6458, 0x00008891 }, /* GL_DEPTH_BOUNDS_EXT */ - { 6478, 0x00008890 }, /* GL_DEPTH_BOUNDS_TEST_EXT */ - { 6503, 0x00000100 }, /* GL_DEPTH_BUFFER_BIT */ - { 6523, 0x0000864F }, /* GL_DEPTH_CLAMP_NV */ - { 6541, 0x00000B73 }, /* GL_DEPTH_CLEAR_VALUE */ - { 6562, 0x00001902 }, /* GL_DEPTH_COMPONENT */ - { 6581, 0x000081A5 }, /* GL_DEPTH_COMPONENT16 */ - { 6602, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_ARB */ - { 6627, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_SGIX */ - { 6653, 0x000081A6 }, /* GL_DEPTH_COMPONENT24 */ - { 6674, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_ARB */ - { 6699, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_SGIX */ - { 6725, 0x000081A7 }, /* GL_DEPTH_COMPONENT32 */ - { 6746, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_ARB */ - { 6771, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_SGIX */ - { 6797, 0x00000B74 }, /* GL_DEPTH_FUNC */ - { 6811, 0x00000B70 }, /* GL_DEPTH_RANGE */ - { 6826, 0x00000D1E }, /* GL_DEPTH_SCALE */ - { 6841, 0x000084F9 }, /* GL_DEPTH_STENCIL_NV */ - { 6861, 0x0000886F }, /* GL_DEPTH_STENCIL_TO_BGRA_NV */ - { 6889, 0x0000886E }, /* GL_DEPTH_STENCIL_TO_RGBA_NV */ - { 6917, 0x00000B71 }, /* GL_DEPTH_TEST */ - { 6931, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE */ - { 6953, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE_ARB */ - { 6979, 0x00000B72 }, /* GL_DEPTH_WRITEMASK */ - { 6998, 0x00001201 }, /* GL_DIFFUSE */ - { 7009, 0x00000BD0 }, /* GL_DITHER */ - { 7019, 0x00000A02 }, /* GL_DOMAIN */ - { 7029, 0x00001100 }, /* GL_DONT_CARE */ - { 7042, 0x000086AE }, /* GL_DOT3_RGB */ - { 7054, 0x000086AF }, /* GL_DOT3_RGBA */ - { 7067, 0x000086AF }, /* GL_DOT3_RGBA_ARB */ - { 7084, 0x00008741 }, /* GL_DOT3_RGBA_EXT */ - { 7101, 0x000086AE }, /* GL_DOT3_RGB_ARB */ - { 7117, 0x00008740 }, /* GL_DOT3_RGB_EXT */ - { 7133, 0x0000140A }, /* GL_DOUBLE */ - { 7143, 0x00000C32 }, /* GL_DOUBLEBUFFER */ - { 7159, 0x00000C01 }, /* GL_DRAW_BUFFER */ - { 7174, 0x00008825 }, /* GL_DRAW_BUFFER0 */ - { 7190, 0x00008825 }, /* GL_DRAW_BUFFER0_ARB */ - { 7210, 0x00008825 }, /* GL_DRAW_BUFFER0_ATI */ - { 7230, 0x00008826 }, /* GL_DRAW_BUFFER1 */ - { 7246, 0x0000882F }, /* GL_DRAW_BUFFER10 */ - { 7263, 0x0000882F }, /* GL_DRAW_BUFFER10_ARB */ - { 7284, 0x0000882F }, /* GL_DRAW_BUFFER10_ATI */ - { 7305, 0x00008830 }, /* GL_DRAW_BUFFER11 */ - { 7322, 0x00008830 }, /* GL_DRAW_BUFFER11_ARB */ - { 7343, 0x00008830 }, /* GL_DRAW_BUFFER11_ATI */ - { 7364, 0x00008831 }, /* GL_DRAW_BUFFER12 */ - { 7381, 0x00008831 }, /* GL_DRAW_BUFFER12_ARB */ - { 7402, 0x00008831 }, /* GL_DRAW_BUFFER12_ATI */ - { 7423, 0x00008832 }, /* GL_DRAW_BUFFER13 */ - { 7440, 0x00008832 }, /* GL_DRAW_BUFFER13_ARB */ - { 7461, 0x00008832 }, /* GL_DRAW_BUFFER13_ATI */ - { 7482, 0x00008833 }, /* GL_DRAW_BUFFER14 */ - { 7499, 0x00008833 }, /* GL_DRAW_BUFFER14_ARB */ - { 7520, 0x00008833 }, /* GL_DRAW_BUFFER14_ATI */ - { 7541, 0x00008834 }, /* GL_DRAW_BUFFER15 */ - { 7558, 0x00008834 }, /* GL_DRAW_BUFFER15_ARB */ - { 7579, 0x00008834 }, /* GL_DRAW_BUFFER15_ATI */ - { 7600, 0x00008826 }, /* GL_DRAW_BUFFER1_ARB */ - { 7620, 0x00008826 }, /* GL_DRAW_BUFFER1_ATI */ - { 7640, 0x00008827 }, /* GL_DRAW_BUFFER2 */ - { 7656, 0x00008827 }, /* GL_DRAW_BUFFER2_ARB */ - { 7676, 0x00008827 }, /* GL_DRAW_BUFFER2_ATI */ - { 7696, 0x00008828 }, /* GL_DRAW_BUFFER3 */ - { 7712, 0x00008828 }, /* GL_DRAW_BUFFER3_ARB */ - { 7732, 0x00008828 }, /* GL_DRAW_BUFFER3_ATI */ - { 7752, 0x00008829 }, /* GL_DRAW_BUFFER4 */ - { 7768, 0x00008829 }, /* GL_DRAW_BUFFER4_ARB */ - { 7788, 0x00008829 }, /* GL_DRAW_BUFFER4_ATI */ - { 7808, 0x0000882A }, /* GL_DRAW_BUFFER5 */ - { 7824, 0x0000882A }, /* GL_DRAW_BUFFER5_ARB */ - { 7844, 0x0000882A }, /* GL_DRAW_BUFFER5_ATI */ - { 7864, 0x0000882B }, /* GL_DRAW_BUFFER6 */ - { 7880, 0x0000882B }, /* GL_DRAW_BUFFER6_ARB */ - { 7900, 0x0000882B }, /* GL_DRAW_BUFFER6_ATI */ - { 7920, 0x0000882C }, /* GL_DRAW_BUFFER7 */ - { 7936, 0x0000882C }, /* GL_DRAW_BUFFER7_ARB */ - { 7956, 0x0000882C }, /* GL_DRAW_BUFFER7_ATI */ - { 7976, 0x0000882D }, /* GL_DRAW_BUFFER8 */ - { 7992, 0x0000882D }, /* GL_DRAW_BUFFER8_ARB */ - { 8012, 0x0000882D }, /* GL_DRAW_BUFFER8_ATI */ - { 8032, 0x0000882E }, /* GL_DRAW_BUFFER9 */ - { 8048, 0x0000882E }, /* GL_DRAW_BUFFER9_ARB */ - { 8068, 0x0000882E }, /* GL_DRAW_BUFFER9_ATI */ - { 8088, 0x00008CA6 }, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */ - { 8120, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER_EXT */ - { 8144, 0x00000705 }, /* GL_DRAW_PIXEL_TOKEN */ - { 8164, 0x00000304 }, /* GL_DST_ALPHA */ - { 8177, 0x00000306 }, /* GL_DST_COLOR */ - { 8190, 0x000088EA }, /* GL_DYNAMIC_COPY */ - { 8206, 0x000088EA }, /* GL_DYNAMIC_COPY_ARB */ - { 8226, 0x000088E8 }, /* GL_DYNAMIC_DRAW */ - { 8242, 0x000088E8 }, /* GL_DYNAMIC_DRAW_ARB */ - { 8262, 0x000088E9 }, /* GL_DYNAMIC_READ */ - { 8278, 0x000088E9 }, /* GL_DYNAMIC_READ_ARB */ - { 8298, 0x00000B43 }, /* GL_EDGE_FLAG */ - { 8311, 0x00008079 }, /* GL_EDGE_FLAG_ARRAY */ - { 8330, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */ - { 8364, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB */ - { 8402, 0x00008093 }, /* GL_EDGE_FLAG_ARRAY_POINTER */ - { 8429, 0x0000808C }, /* GL_EDGE_FLAG_ARRAY_STRIDE */ - { 8455, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER */ - { 8479, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER_ARB */ - { 8507, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */ - { 8539, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB */ - { 8575, 0x00001600 }, /* GL_EMISSION */ - { 8587, 0x00002000 }, /* GL_ENABLE_BIT */ - { 8601, 0x00000202 }, /* GL_EQUAL */ - { 8610, 0x00001509 }, /* GL_EQUIV */ - { 8619, 0x00010000 }, /* GL_EVAL_BIT */ - { 8631, 0x00000800 }, /* GL_EXP */ - { 8638, 0x00000801 }, /* GL_EXP2 */ - { 8646, 0x00001F03 }, /* GL_EXTENSIONS */ - { 8660, 0x00002400 }, /* GL_EYE_LINEAR */ - { 8674, 0x00002502 }, /* GL_EYE_PLANE */ - { 8687, 0x0000855C }, /* GL_EYE_PLANE_ABSOLUTE_NV */ - { 8712, 0x0000855B }, /* GL_EYE_RADIAL_NV */ - { 8729, 0x00000000 }, /* GL_FALSE */ - { 8738, 0x00001101 }, /* GL_FASTEST */ - { 8749, 0x00001C01 }, /* GL_FEEDBACK */ - { 8761, 0x00000DF0 }, /* GL_FEEDBACK_BUFFER_POINTER */ - { 8788, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */ - { 8812, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */ - { 8836, 0x00001B02 }, /* GL_FILL */ - { 8844, 0x00001D00 }, /* GL_FLAT */ - { 8852, 0x00001406 }, /* GL_FLOAT */ - { 8861, 0x00008B5A }, /* GL_FLOAT_MAT2 */ - { 8875, 0x00008B5A }, /* GL_FLOAT_MAT2_ARB */ - { 8893, 0x00008B5B }, /* GL_FLOAT_MAT3 */ - { 8907, 0x00008B5B }, /* GL_FLOAT_MAT3_ARB */ - { 8925, 0x00008B5C }, /* GL_FLOAT_MAT4 */ - { 8939, 0x00008B5C }, /* GL_FLOAT_MAT4_ARB */ - { 8957, 0x00008B50 }, /* GL_FLOAT_VEC2 */ - { 8971, 0x00008B50 }, /* GL_FLOAT_VEC2_ARB */ - { 8989, 0x00008B51 }, /* GL_FLOAT_VEC3 */ - { 9003, 0x00008B51 }, /* GL_FLOAT_VEC3_ARB */ - { 9021, 0x00008B52 }, /* GL_FLOAT_VEC4 */ - { 9035, 0x00008B52 }, /* GL_FLOAT_VEC4_ARB */ - { 9053, 0x00000B60 }, /* GL_FOG */ - { 9060, 0x00000080 }, /* GL_FOG_BIT */ - { 9071, 0x00000B66 }, /* GL_FOG_COLOR */ - { 9084, 0x00008451 }, /* GL_FOG_COORD */ - { 9097, 0x00008451 }, /* GL_FOG_COORDINATE */ - { 9115, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */ - { 9139, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */ - { 9178, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB */ - { 9221, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */ - { 9253, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */ - { 9284, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */ - { 9313, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */ - { 9338, 0x00008457 }, /* GL_FOG_COORD_ARRAY */ - { 9357, 0x0000889D }, /* GL_FOG_COORD_ARRAY_BUFFER_BINDING */ - { 9391, 0x00008456 }, /* GL_FOG_COORD_ARRAY_POINTER */ - { 9418, 0x00008455 }, /* GL_FOG_COORD_ARRAY_STRIDE */ - { 9444, 0x00008454 }, /* GL_FOG_COORD_ARRAY_TYPE */ - { 9468, 0x00008450 }, /* GL_FOG_COORD_SRC */ - { 9485, 0x00000B62 }, /* GL_FOG_DENSITY */ - { 9500, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */ - { 9524, 0x00000B64 }, /* GL_FOG_END */ - { 9535, 0x00000C54 }, /* GL_FOG_HINT */ - { 9547, 0x00000B61 }, /* GL_FOG_INDEX */ - { 9560, 0x00000B65 }, /* GL_FOG_MODE */ - { 9572, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */ - { 9591, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */ - { 9616, 0x00000B63 }, /* GL_FOG_START */ - { 9629, 0x00008452 }, /* GL_FRAGMENT_DEPTH */ - { 9647, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */ - { 9671, 0x00008B30 }, /* GL_FRAGMENT_SHADER */ - { 9690, 0x00008B30 }, /* GL_FRAGMENT_SHADER_ARB */ - { 9713, 0x00008B8B }, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */ - { 9748, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */ - { 9790, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */ - { 9832, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */ - { 9881, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */ - { 9933, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ - { 9977, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */ - { 10021, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */ - { 10048, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */ - { 10076, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */ - { 10095, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */ - { 10136, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */ - { 10177, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */ - { 10219, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */ - { 10270, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */ - { 10308, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */ - { 10357, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */ - { 10399, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */ - { 10431, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */ - { 10462, 0x00000404 }, /* GL_FRONT */ - { 10471, 0x00000408 }, /* GL_FRONT_AND_BACK */ - { 10489, 0x00000B46 }, /* GL_FRONT_FACE */ - { 10503, 0x00000400 }, /* GL_FRONT_LEFT */ - { 10517, 0x00000401 }, /* GL_FRONT_RIGHT */ - { 10532, 0x00008006 }, /* GL_FUNC_ADD */ - { 10544, 0x00008006 }, /* GL_FUNC_ADD_EXT */ - { 10560, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */ - { 10585, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */ - { 10614, 0x0000800A }, /* GL_FUNC_SUBTRACT */ - { 10631, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */ - { 10652, 0x00008191 }, /* GL_GENERATE_MIPMAP */ - { 10671, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */ - { 10695, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */ - { 10724, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */ - { 10748, 0x00000206 }, /* GL_GEQUAL */ - { 10758, 0x00008009 }, /* GL_GL_BLEND_EQUATION_RGB */ - { 10783, 0x00008C4A }, /* GL_GL_COMPRESSED_SLUMINANCE */ - { 10811, 0x00008C4B }, /* GL_GL_COMPRESSED_SLUMINANCE_ALPHA */ - { 10845, 0x00008C48 }, /* GL_GL_COMPRESSED_SRGB */ - { 10867, 0x00008C49 }, /* GL_GL_COMPRESSED_SRGB_ALPHA */ - { 10895, 0x0000845F }, /* GL_GL_CURRENT_RASTER_SECONDARY_COLOR */ - { 10932, 0x00008B65 }, /* GL_GL_FLOAT_MAT2x3 */ - { 10951, 0x00008B66 }, /* GL_GL_FLOAT_MAT2x4 */ - { 10970, 0x00008B67 }, /* GL_GL_FLOAT_MAT3x2 */ - { 10989, 0x00008B68 }, /* GL_GL_FLOAT_MAT3x4 */ - { 11008, 0x00008B69 }, /* GL_GL_FLOAT_MAT4x2 */ - { 11027, 0x00008B6A }, /* GL_GL_FLOAT_MAT4x3 */ - { 11046, 0x000088EB }, /* GL_GL_PIXEL_PACK_BUFFER */ - { 11070, 0x000088ED }, /* GL_GL_PIXEL_PACK_BUFFER_BINDING */ - { 11102, 0x000088EC }, /* GL_GL_PIXEL_UNPACK_BUFFER */ - { 11128, 0x000088EF }, /* GL_GL_PIXEL_UNPACK_BUFFER_BINDING */ - { 11162, 0x00008C46 }, /* GL_GL_SLUMINANCE */ - { 11179, 0x00008C47 }, /* GL_GL_SLUMINANCE8 */ - { 11197, 0x00008C45 }, /* GL_GL_SLUMINANCE8_ALPHA8 */ - { 11222, 0x00008C44 }, /* GL_GL_SLUMINANCE_ALPHA */ - { 11245, 0x00008C40 }, /* GL_GL_SRGB */ - { 11256, 0x00008C41 }, /* GL_GL_SRGB8 */ - { 11268, 0x00008C43 }, /* GL_GL_SRGB8_ALPHA8 */ - { 11287, 0x00008C42 }, /* GL_GL_SRGB_ALPHA */ - { 11304, 0x00000204 }, /* GL_GREATER */ - { 11315, 0x00001904 }, /* GL_GREEN */ - { 11324, 0x00000D19 }, /* GL_GREEN_BIAS */ - { 11338, 0x00000D53 }, /* GL_GREEN_BITS */ - { 11352, 0x00000D18 }, /* GL_GREEN_SCALE */ - { 11367, 0x00008000 }, /* GL_HINT_BIT */ - { 11379, 0x00008024 }, /* GL_HISTOGRAM */ - { 11392, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */ - { 11416, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */ - { 11444, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */ - { 11467, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */ - { 11494, 0x00008024 }, /* GL_HISTOGRAM_EXT */ - { 11511, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */ - { 11531, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */ - { 11555, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */ - { 11579, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */ - { 11607, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */ - { 11635, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */ - { 11667, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */ - { 11689, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */ - { 11715, 0x0000802D }, /* GL_HISTOGRAM_SINK */ - { 11733, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */ - { 11755, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */ - { 11774, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */ - { 11797, 0x0000862A }, /* GL_IDENTITY_NV */ - { 11812, 0x00008150 }, /* GL_IGNORE_BORDER_HP */ - { 11832, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */ - { 11872, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */ - { 11910, 0x00001E02 }, /* GL_INCR */ - { 11918, 0x00008507 }, /* GL_INCR_WRAP */ - { 11931, 0x00008507 }, /* GL_INCR_WRAP_EXT */ - { 11948, 0x00008077 }, /* GL_INDEX_ARRAY */ - { 11963, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */ - { 11993, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */ - { 12027, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */ - { 12050, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */ - { 12072, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */ - { 12092, 0x00000D51 }, /* GL_INDEX_BITS */ - { 12106, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */ - { 12127, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */ - { 12145, 0x00000C30 }, /* GL_INDEX_MODE */ - { 12159, 0x00000D13 }, /* GL_INDEX_OFFSET */ - { 12175, 0x00000D12 }, /* GL_INDEX_SHIFT */ - { 12190, 0x00000C21 }, /* GL_INDEX_WRITEMASK */ - { 12209, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */ - { 12228, 0x00001404 }, /* GL_INT */ - { 12235, 0x00008049 }, /* GL_INTENSITY */ - { 12248, 0x0000804C }, /* GL_INTENSITY12 */ - { 12263, 0x0000804C }, /* GL_INTENSITY12_EXT */ - { 12282, 0x0000804D }, /* GL_INTENSITY16 */ - { 12297, 0x0000804D }, /* GL_INTENSITY16_EXT */ - { 12316, 0x0000804A }, /* GL_INTENSITY4 */ - { 12330, 0x0000804A }, /* GL_INTENSITY4_EXT */ - { 12348, 0x0000804B }, /* GL_INTENSITY8 */ - { 12362, 0x0000804B }, /* GL_INTENSITY8_EXT */ - { 12380, 0x00008049 }, /* GL_INTENSITY_EXT */ - { 12397, 0x00008575 }, /* GL_INTERPOLATE */ - { 12412, 0x00008575 }, /* GL_INTERPOLATE_ARB */ - { 12431, 0x00008575 }, /* GL_INTERPOLATE_EXT */ - { 12450, 0x00008B53 }, /* GL_INT_VEC2 */ - { 12462, 0x00008B53 }, /* GL_INT_VEC2_ARB */ - { 12478, 0x00008B54 }, /* GL_INT_VEC3 */ - { 12490, 0x00008B54 }, /* GL_INT_VEC3_ARB */ - { 12506, 0x00008B55 }, /* GL_INT_VEC4 */ - { 12518, 0x00008B55 }, /* GL_INT_VEC4_ARB */ - { 12534, 0x00000500 }, /* GL_INVALID_ENUM */ - { 12550, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */ - { 12587, 0x00000502 }, /* GL_INVALID_OPERATION */ - { 12608, 0x00000501 }, /* GL_INVALID_VALUE */ - { 12625, 0x0000862B }, /* GL_INVERSE_NV */ - { 12639, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */ - { 12663, 0x0000150A }, /* GL_INVERT */ - { 12673, 0x00001E00 }, /* GL_KEEP */ - { 12681, 0x00000406 }, /* GL_LEFT */ - { 12689, 0x00000203 }, /* GL_LEQUAL */ - { 12699, 0x00000201 }, /* GL_LESS */ - { 12707, 0x00004000 }, /* GL_LIGHT0 */ - { 12717, 0x00004001 }, /* GL_LIGHT1 */ - { 12727, 0x00004002 }, /* GL_LIGHT2 */ - { 12737, 0x00004003 }, /* GL_LIGHT3 */ - { 12747, 0x00004004 }, /* GL_LIGHT4 */ - { 12757, 0x00004005 }, /* GL_LIGHT5 */ - { 12767, 0x00004006 }, /* GL_LIGHT6 */ - { 12777, 0x00004007 }, /* GL_LIGHT7 */ - { 12787, 0x00000B50 }, /* GL_LIGHTING */ - { 12799, 0x00000040 }, /* GL_LIGHTING_BIT */ - { 12815, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */ - { 12838, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */ - { 12867, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */ - { 12900, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */ - { 12928, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */ - { 12952, 0x00001B01 }, /* GL_LINE */ - { 12960, 0x00002601 }, /* GL_LINEAR */ - { 12970, 0x00001208 }, /* GL_LINEAR_ATTENUATION */ - { 12992, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */ - { 13022, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */ - { 13053, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */ - { 13077, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */ - { 13102, 0x00000001 }, /* GL_LINES */ - { 13111, 0x00000004 }, /* GL_LINE_BIT */ - { 13123, 0x00000002 }, /* GL_LINE_LOOP */ - { 13136, 0x00000707 }, /* GL_LINE_RESET_TOKEN */ - { 13156, 0x00000B20 }, /* GL_LINE_SMOOTH */ - { 13171, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */ - { 13191, 0x00000B24 }, /* GL_LINE_STIPPLE */ - { 13207, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */ - { 13231, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */ - { 13254, 0x00000003 }, /* GL_LINE_STRIP */ - { 13268, 0x00000702 }, /* GL_LINE_TOKEN */ - { 13282, 0x00000B21 }, /* GL_LINE_WIDTH */ - { 13296, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */ - { 13322, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */ - { 13342, 0x00008B82 }, /* GL_LINK_STATUS */ - { 13357, 0x00000B32 }, /* GL_LIST_BASE */ - { 13370, 0x00020000 }, /* GL_LIST_BIT */ - { 13382, 0x00000B33 }, /* GL_LIST_INDEX */ - { 13396, 0x00000B30 }, /* GL_LIST_MODE */ - { 13409, 0x00000101 }, /* GL_LOAD */ - { 13417, 0x00000BF1 }, /* GL_LOGIC_OP */ - { 13429, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */ - { 13446, 0x00008CA1 }, /* GL_LOWER_LEFT */ - { 13460, 0x00001909 }, /* GL_LUMINANCE */ - { 13473, 0x00008041 }, /* GL_LUMINANCE12 */ - { 13488, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */ - { 13511, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */ - { 13538, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */ - { 13560, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */ - { 13586, 0x00008041 }, /* GL_LUMINANCE12_EXT */ - { 13605, 0x00008042 }, /* GL_LUMINANCE16 */ - { 13620, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */ - { 13643, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */ - { 13670, 0x00008042 }, /* GL_LUMINANCE16_EXT */ - { 13689, 0x0000803F }, /* GL_LUMINANCE4 */ - { 13703, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */ - { 13724, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */ - { 13749, 0x0000803F }, /* GL_LUMINANCE4_EXT */ - { 13767, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */ - { 13788, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */ - { 13813, 0x00008040 }, /* GL_LUMINANCE8 */ - { 13827, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */ - { 13848, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */ - { 13873, 0x00008040 }, /* GL_LUMINANCE8_EXT */ - { 13891, 0x0000190A }, /* GL_LUMINANCE_ALPHA */ - { 13910, 0x00000D90 }, /* GL_MAP1_COLOR_4 */ - { 13926, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */ - { 13946, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */ - { 13968, 0x00000D91 }, /* GL_MAP1_INDEX */ - { 13982, 0x00000D92 }, /* GL_MAP1_NORMAL */ - { 13997, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */ - { 14021, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */ - { 14045, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */ - { 14069, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */ - { 14093, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */ - { 14110, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */ - { 14127, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */ - { 14155, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */ - { 14184, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */ - { 14213, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */ - { 14242, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */ - { 14271, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */ - { 14300, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */ - { 14329, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */ - { 14357, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */ - { 14385, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */ - { 14413, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */ - { 14441, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */ - { 14469, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */ - { 14497, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */ - { 14525, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */ - { 14553, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */ - { 14581, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */ - { 14597, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */ - { 14617, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */ - { 14639, 0x00000DB1 }, /* GL_MAP2_INDEX */ - { 14653, 0x00000DB2 }, /* GL_MAP2_NORMAL */ - { 14668, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */ - { 14692, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */ - { 14716, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */ - { 14740, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */ - { 14764, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */ - { 14781, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */ - { 14798, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */ - { 14826, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */ - { 14855, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */ - { 14884, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */ - { 14913, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */ - { 14942, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */ - { 14971, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */ - { 15000, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */ - { 15028, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */ - { 15056, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */ - { 15084, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */ - { 15112, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */ - { 15140, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */ - { 15168, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */ - { 15196, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */ - { 15224, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */ - { 15252, 0x00000D10 }, /* GL_MAP_COLOR */ - { 15265, 0x00000D11 }, /* GL_MAP_STENCIL */ - { 15280, 0x000088C0 }, /* GL_MATRIX0_ARB */ - { 15295, 0x00008630 }, /* GL_MATRIX0_NV */ - { 15309, 0x000088CA }, /* GL_MATRIX10_ARB */ - { 15325, 0x000088CB }, /* GL_MATRIX11_ARB */ - { 15341, 0x000088CC }, /* GL_MATRIX12_ARB */ - { 15357, 0x000088CD }, /* GL_MATRIX13_ARB */ - { 15373, 0x000088CE }, /* GL_MATRIX14_ARB */ - { 15389, 0x000088CF }, /* GL_MATRIX15_ARB */ - { 15405, 0x000088D0 }, /* GL_MATRIX16_ARB */ - { 15421, 0x000088D1 }, /* GL_MATRIX17_ARB */ - { 15437, 0x000088D2 }, /* GL_MATRIX18_ARB */ - { 15453, 0x000088D3 }, /* GL_MATRIX19_ARB */ - { 15469, 0x000088C1 }, /* GL_MATRIX1_ARB */ - { 15484, 0x00008631 }, /* GL_MATRIX1_NV */ - { 15498, 0x000088D4 }, /* GL_MATRIX20_ARB */ - { 15514, 0x000088D5 }, /* GL_MATRIX21_ARB */ - { 15530, 0x000088D6 }, /* GL_MATRIX22_ARB */ - { 15546, 0x000088D7 }, /* GL_MATRIX23_ARB */ - { 15562, 0x000088D8 }, /* GL_MATRIX24_ARB */ - { 15578, 0x000088D9 }, /* GL_MATRIX25_ARB */ - { 15594, 0x000088DA }, /* GL_MATRIX26_ARB */ - { 15610, 0x000088DB }, /* GL_MATRIX27_ARB */ - { 15626, 0x000088DC }, /* GL_MATRIX28_ARB */ - { 15642, 0x000088DD }, /* GL_MATRIX29_ARB */ - { 15658, 0x000088C2 }, /* GL_MATRIX2_ARB */ - { 15673, 0x00008632 }, /* GL_MATRIX2_NV */ - { 15687, 0x000088DE }, /* GL_MATRIX30_ARB */ - { 15703, 0x000088DF }, /* GL_MATRIX31_ARB */ - { 15719, 0x000088C3 }, /* GL_MATRIX3_ARB */ - { 15734, 0x00008633 }, /* GL_MATRIX3_NV */ - { 15748, 0x000088C4 }, /* GL_MATRIX4_ARB */ - { 15763, 0x00008634 }, /* GL_MATRIX4_NV */ - { 15777, 0x000088C5 }, /* GL_MATRIX5_ARB */ - { 15792, 0x00008635 }, /* GL_MATRIX5_NV */ - { 15806, 0x000088C6 }, /* GL_MATRIX6_ARB */ - { 15821, 0x00008636 }, /* GL_MATRIX6_NV */ - { 15835, 0x000088C7 }, /* GL_MATRIX7_ARB */ - { 15850, 0x00008637 }, /* GL_MATRIX7_NV */ - { 15864, 0x000088C8 }, /* GL_MATRIX8_ARB */ - { 15879, 0x000088C9 }, /* GL_MATRIX9_ARB */ - { 15894, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */ - { 15920, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */ - { 15954, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */ - { 15985, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */ - { 16018, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */ - { 16049, 0x00000BA0 }, /* GL_MATRIX_MODE */ - { 16064, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */ - { 16086, 0x00008008 }, /* GL_MAX */ - { 16093, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */ - { 16116, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */ - { 16148, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */ - { 16174, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */ - { 16207, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */ - { 16233, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - { 16267, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */ - { 16286, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */ - { 16315, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ - { 16347, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */ - { 16383, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ - { 16419, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */ - { 16459, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */ - { 16485, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */ - { 16515, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */ - { 16540, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */ - { 16569, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ - { 16598, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */ - { 16631, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */ - { 16651, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */ - { 16675, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */ - { 16699, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */ - { 16723, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */ - { 16748, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */ - { 16766, 0x00008008 }, /* GL_MAX_EXT */ - { 16777, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */ - { 16812, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */ - { 16851, 0x00000D31 }, /* GL_MAX_LIGHTS */ - { 16865, 0x00000B31 }, /* GL_MAX_LIST_NESTING */ - { 16885, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */ - { 16923, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */ - { 16952, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */ - { 16976, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */ - { 17004, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */ - { 17027, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */ - { 17064, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */ - { 17100, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */ - { 17127, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */ - { 17156, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */ - { 17190, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ - { 17226, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */ - { 17253, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */ - { 17285, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */ - { 17321, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */ - { 17350, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */ - { 17379, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */ - { 17407, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */ - { 17445, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - { 17489, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - { 17532, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */ - { 17566, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - { 17605, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */ - { 17642, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */ - { 17680, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - { 17723, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - { 17766, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */ - { 17796, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ - { 17827, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */ - { 17863, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */ - { 17899, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */ - { 17929, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */ - { 17963, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */ - { 17996, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */ - { 18025, 0x00008504 }, /* GL_MAX_SHININESS_NV */ - { 18045, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */ - { 18069, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */ - { 18091, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */ - { 18117, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */ - { 18144, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */ - { 18175, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */ - { 18199, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ - { 18233, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */ - { 18253, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */ - { 18280, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */ - { 18301, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */ - { 18326, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */ - { 18351, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */ - { 18386, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */ - { 18408, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */ - { 18434, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */ - { 18456, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */ - { 18482, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */ - { 18516, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ - { 18554, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */ - { 18587, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */ - { 18624, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */ - { 18648, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */ - { 18669, 0x00008007 }, /* GL_MIN */ - { 18676, 0x0000802E }, /* GL_MINMAX */ - { 18686, 0x0000802E }, /* GL_MINMAX_EXT */ - { 18700, 0x0000802F }, /* GL_MINMAX_FORMAT */ - { 18717, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */ - { 18738, 0x00008030 }, /* GL_MINMAX_SINK */ - { 18753, 0x00008030 }, /* GL_MINMAX_SINK_EXT */ - { 18772, 0x00008007 }, /* GL_MIN_EXT */ - { 18783, 0x00008370 }, /* GL_MIRRORED_REPEAT */ - { 18802, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */ - { 18825, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */ - { 18848, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */ - { 18868, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */ - { 18888, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */ - { 18918, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */ - { 18946, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */ - { 18974, 0x00001700 }, /* GL_MODELVIEW */ - { 18987, 0x00001700 }, /* GL_MODELVIEW0_ARB */ - { 19005, 0x0000872A }, /* GL_MODELVIEW10_ARB */ - { 19024, 0x0000872B }, /* GL_MODELVIEW11_ARB */ - { 19043, 0x0000872C }, /* GL_MODELVIEW12_ARB */ - { 19062, 0x0000872D }, /* GL_MODELVIEW13_ARB */ - { 19081, 0x0000872E }, /* GL_MODELVIEW14_ARB */ - { 19100, 0x0000872F }, /* GL_MODELVIEW15_ARB */ - { 19119, 0x00008730 }, /* GL_MODELVIEW16_ARB */ - { 19138, 0x00008731 }, /* GL_MODELVIEW17_ARB */ - { 19157, 0x00008732 }, /* GL_MODELVIEW18_ARB */ - { 19176, 0x00008733 }, /* GL_MODELVIEW19_ARB */ - { 19195, 0x0000850A }, /* GL_MODELVIEW1_ARB */ - { 19213, 0x00008734 }, /* GL_MODELVIEW20_ARB */ - { 19232, 0x00008735 }, /* GL_MODELVIEW21_ARB */ - { 19251, 0x00008736 }, /* GL_MODELVIEW22_ARB */ - { 19270, 0x00008737 }, /* GL_MODELVIEW23_ARB */ - { 19289, 0x00008738 }, /* GL_MODELVIEW24_ARB */ - { 19308, 0x00008739 }, /* GL_MODELVIEW25_ARB */ - { 19327, 0x0000873A }, /* GL_MODELVIEW26_ARB */ - { 19346, 0x0000873B }, /* GL_MODELVIEW27_ARB */ - { 19365, 0x0000873C }, /* GL_MODELVIEW28_ARB */ - { 19384, 0x0000873D }, /* GL_MODELVIEW29_ARB */ - { 19403, 0x00008722 }, /* GL_MODELVIEW2_ARB */ - { 19421, 0x0000873E }, /* GL_MODELVIEW30_ARB */ - { 19440, 0x0000873F }, /* GL_MODELVIEW31_ARB */ - { 19459, 0x00008723 }, /* GL_MODELVIEW3_ARB */ - { 19477, 0x00008724 }, /* GL_MODELVIEW4_ARB */ - { 19495, 0x00008725 }, /* GL_MODELVIEW5_ARB */ - { 19513, 0x00008726 }, /* GL_MODELVIEW6_ARB */ - { 19531, 0x00008727 }, /* GL_MODELVIEW7_ARB */ - { 19549, 0x00008728 }, /* GL_MODELVIEW8_ARB */ - { 19567, 0x00008729 }, /* GL_MODELVIEW9_ARB */ - { 19585, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */ - { 19605, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */ - { 19632, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */ - { 19657, 0x00002100 }, /* GL_MODULATE */ - { 19669, 0x00008744 }, /* GL_MODULATE_ADD_ATI */ - { 19689, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */ - { 19716, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */ - { 19741, 0x00000103 }, /* GL_MULT */ - { 19749, 0x0000809D }, /* GL_MULTISAMPLE */ - { 19764, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */ - { 19784, 0x0000809D }, /* GL_MULTISAMPLE_ARB */ - { 19803, 0x20000000 }, /* GL_MULTISAMPLE_BIT */ - { 19822, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */ - { 19846, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */ - { 19869, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */ - { 19899, 0x00002A25 }, /* GL_N3F_V3F */ - { 19910, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */ - { 19930, 0x0000150E }, /* GL_NAND */ - { 19938, 0x00002600 }, /* GL_NEAREST */ - { 19949, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */ - { 19980, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */ - { 20012, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */ - { 20037, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */ - { 20063, 0x00000200 }, /* GL_NEVER */ - { 20072, 0x00001102 }, /* GL_NICEST */ - { 20082, 0x00000000 }, /* GL_NONE */ - { 20090, 0x00001505 }, /* GL_NOOP */ - { 20098, 0x00001508 }, /* GL_NOR */ - { 20105, 0x00000BA1 }, /* GL_NORMALIZE */ - { 20118, 0x00008075 }, /* GL_NORMAL_ARRAY */ - { 20134, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */ - { 20165, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */ - { 20200, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */ - { 20224, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */ - { 20247, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */ - { 20268, 0x00008511 }, /* GL_NORMAL_MAP */ - { 20282, 0x00008511 }, /* GL_NORMAL_MAP_ARB */ - { 20300, 0x00008511 }, /* GL_NORMAL_MAP_NV */ - { 20317, 0x00000205 }, /* GL_NOTEQUAL */ - { 20329, 0x00000000 }, /* GL_NO_ERROR */ - { 20341, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */ - { 20375, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */ - { 20413, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */ - { 20445, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */ - { 20487, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */ - { 20517, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */ - { 20557, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */ - { 20588, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */ - { 20617, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */ - { 20645, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */ - { 20675, 0x00002401 }, /* GL_OBJECT_LINEAR */ - { 20692, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */ - { 20718, 0x00002501 }, /* GL_OBJECT_PLANE */ - { 20734, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */ - { 20769, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */ - { 20791, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */ - { 20810, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */ - { 20840, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */ - { 20861, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */ - { 20889, 0x00000001 }, /* GL_ONE */ - { 20896, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */ - { 20924, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */ - { 20956, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */ - { 20984, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */ - { 21016, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */ - { 21039, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */ - { 21062, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */ - { 21085, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */ - { 21108, 0x00008598 }, /* GL_OPERAND0_ALPHA */ - { 21126, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */ - { 21148, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */ - { 21170, 0x00008590 }, /* GL_OPERAND0_RGB */ - { 21186, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */ - { 21206, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */ - { 21226, 0x00008599 }, /* GL_OPERAND1_ALPHA */ - { 21244, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */ - { 21266, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */ - { 21288, 0x00008591 }, /* GL_OPERAND1_RGB */ - { 21304, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */ - { 21324, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */ - { 21344, 0x0000859A }, /* GL_OPERAND2_ALPHA */ - { 21362, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */ - { 21384, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */ - { 21406, 0x00008592 }, /* GL_OPERAND2_RGB */ - { 21422, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */ - { 21442, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */ - { 21462, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */ - { 21483, 0x00008593 }, /* GL_OPERAND3_RGB_NV */ - { 21502, 0x00001507 }, /* GL_OR */ - { 21508, 0x00000A01 }, /* GL_ORDER */ - { 21517, 0x0000150D }, /* GL_OR_INVERTED */ - { 21532, 0x0000150B }, /* GL_OR_REVERSE */ - { 21546, 0x00000505 }, /* GL_OUT_OF_MEMORY */ - { 21563, 0x00000D05 }, /* GL_PACK_ALIGNMENT */ - { 21581, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */ - { 21602, 0x00008758 }, /* GL_PACK_INVERT_MESA */ - { 21622, 0x00000D01 }, /* GL_PACK_LSB_FIRST */ - { 21640, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */ - { 21659, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */ - { 21679, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */ - { 21699, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */ - { 21717, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */ - { 21736, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */ - { 21761, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */ - { 21785, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */ - { 21806, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */ - { 21828, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */ - { 21850, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */ - { 21875, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */ - { 21899, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */ - { 21920, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */ - { 21942, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */ - { 21964, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */ - { 21986, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */ - { 22017, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */ - { 22037, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */ - { 22062, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */ - { 22082, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */ - { 22107, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */ - { 22127, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */ - { 22152, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */ - { 22172, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */ - { 22197, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */ - { 22217, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */ - { 22242, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */ - { 22262, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */ - { 22287, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */ - { 22307, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */ - { 22332, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */ - { 22352, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */ - { 22377, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */ - { 22397, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */ - { 22422, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */ - { 22442, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */ - { 22467, 0x00000020 }, /* GL_PIXEL_MODE_BIT */ - { 22485, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */ - { 22518, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */ - { 22543, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */ - { 22578, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */ - { 22605, 0x00001B00 }, /* GL_POINT */ - { 22614, 0x00000000 }, /* GL_POINTS */ - { 22624, 0x00000002 }, /* GL_POINT_BIT */ - { 22637, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */ - { 22667, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */ - { 22701, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */ - { 22735, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */ - { 22770, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */ - { 22799, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */ - { 22832, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */ - { 22865, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */ - { 22899, 0x00000B11 }, /* GL_POINT_SIZE */ - { 22913, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */ - { 22939, 0x00008127 }, /* GL_POINT_SIZE_MAX */ - { 22957, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */ - { 22979, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */ - { 23001, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */ - { 23024, 0x00008126 }, /* GL_POINT_SIZE_MIN */ - { 23042, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */ - { 23064, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */ - { 23086, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */ - { 23109, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */ - { 23129, 0x00000B10 }, /* GL_POINT_SMOOTH */ - { 23145, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */ - { 23166, 0x00008861 }, /* GL_POINT_SPRITE */ - { 23182, 0x00008861 }, /* GL_POINT_SPRITE_ARB */ - { 23202, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */ - { 23231, 0x00008861 }, /* GL_POINT_SPRITE_NV */ - { 23250, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */ - { 23276, 0x00000701 }, /* GL_POINT_TOKEN */ - { 23291, 0x00000009 }, /* GL_POLYGON */ - { 23302, 0x00000008 }, /* GL_POLYGON_BIT */ - { 23317, 0x00000B40 }, /* GL_POLYGON_MODE */ - { 23333, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */ - { 23356, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */ - { 23381, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */ - { 23404, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */ - { 23427, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */ - { 23451, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */ - { 23475, 0x00000B41 }, /* GL_POLYGON_SMOOTH */ - { 23493, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */ - { 23516, 0x00000B42 }, /* GL_POLYGON_STIPPLE */ - { 23535, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */ - { 23558, 0x00000703 }, /* GL_POLYGON_TOKEN */ - { 23575, 0x00001203 }, /* GL_POSITION */ - { 23587, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ - { 23619, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */ - { 23655, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ - { 23688, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */ - { 23725, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ - { 23756, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */ - { 23791, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ - { 23823, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */ - { 23859, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ - { 23892, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ - { 23924, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */ - { 23960, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ - { 23993, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */ - { 24030, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */ - { 24060, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */ - { 24094, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */ - { 24125, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */ - { 24160, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */ - { 24191, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */ - { 24226, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */ - { 24258, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */ - { 24294, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */ - { 24324, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */ - { 24358, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */ - { 24389, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */ - { 24424, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */ - { 24456, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */ - { 24487, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */ - { 24522, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */ - { 24554, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */ - { 24590, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */ - { 24619, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */ - { 24652, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */ - { 24682, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */ - { 24716, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */ - { 24755, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */ - { 24788, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */ - { 24828, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */ - { 24862, 0x00008578 }, /* GL_PREVIOUS */ - { 24874, 0x00008578 }, /* GL_PREVIOUS_ARB */ - { 24890, 0x00008578 }, /* GL_PREVIOUS_EXT */ - { 24906, 0x00008577 }, /* GL_PRIMARY_COLOR */ - { 24923, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */ - { 24944, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */ - { 24965, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */ - { 24998, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */ - { 25030, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */ - { 25053, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */ - { 25076, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */ - { 25106, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */ - { 25135, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */ - { 25163, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */ - { 25185, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */ - { 25213, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */ - { 25241, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */ - { 25263, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */ - { 25284, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - { 25324, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - { 25363, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */ - { 25393, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - { 25428, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */ - { 25461, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */ - { 25495, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - { 25534, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - { 25573, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */ - { 25595, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */ - { 25621, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */ - { 25645, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */ - { 25668, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */ - { 25690, 0x00008628 }, /* GL_PROGRAM_STRING_NV */ - { 25711, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */ - { 25732, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */ - { 25759, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */ - { 25791, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */ - { 25823, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */ - { 25858, 0x00001701 }, /* GL_PROJECTION */ - { 25872, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */ - { 25893, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */ - { 25919, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */ - { 25940, 0x00008025 }, /* GL_PROXY_HISTOGRAM */ - { 25959, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */ - { 25982, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ - { 26021, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ - { 26059, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */ - { 26079, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */ - { 26109, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */ - { 26133, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */ - { 26153, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */ - { 26183, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */ - { 26207, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */ - { 26227, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */ - { 26260, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */ - { 26286, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */ - { 26316, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */ - { 26347, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */ - { 26377, 0x00002003 }, /* GL_Q */ - { 26382, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */ - { 26407, 0x00000007 }, /* GL_QUADS */ - { 26416, 0x00008614 }, /* GL_QUAD_MESH_SUN */ - { 26433, 0x00000008 }, /* GL_QUAD_STRIP */ - { 26447, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */ - { 26469, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */ - { 26495, 0x00008866 }, /* GL_QUERY_RESULT */ - { 26511, 0x00008866 }, /* GL_QUERY_RESULT_ARB */ - { 26531, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */ - { 26557, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */ - { 26587, 0x00002002 }, /* GL_R */ - { 26592, 0x00002A10 }, /* GL_R3_G3_B2 */ - { 26604, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */ - { 26637, 0x00000C02 }, /* GL_READ_BUFFER */ - { 26652, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */ - { 26684, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */ - { 26708, 0x000088B8 }, /* GL_READ_ONLY */ - { 26721, 0x000088B8 }, /* GL_READ_ONLY_ARB */ - { 26738, 0x000088BA }, /* GL_READ_WRITE */ - { 26752, 0x000088BA }, /* GL_READ_WRITE_ARB */ - { 26770, 0x00001903 }, /* GL_RED */ - { 26777, 0x00008016 }, /* GL_REDUCE */ - { 26787, 0x00008016 }, /* GL_REDUCE_EXT */ - { 26801, 0x00000D15 }, /* GL_RED_BIAS */ - { 26813, 0x00000D52 }, /* GL_RED_BITS */ - { 26825, 0x00000D14 }, /* GL_RED_SCALE */ - { 26838, 0x00008512 }, /* GL_REFLECTION_MAP */ - { 26856, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */ - { 26878, 0x00008512 }, /* GL_REFLECTION_MAP_NV */ - { 26899, 0x00001C00 }, /* GL_RENDER */ - { 26909, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */ - { 26937, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */ - { 26957, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */ - { 26984, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */ - { 27020, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */ - { 27046, 0x00001F01 }, /* GL_RENDERER */ - { 27058, 0x00000C40 }, /* GL_RENDER_MODE */ - { 27073, 0x00002901 }, /* GL_REPEAT */ - { 27083, 0x00001E01 }, /* GL_REPLACE */ - { 27094, 0x00008062 }, /* GL_REPLACE_EXT */ - { 27109, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */ - { 27132, 0x0000803A }, /* GL_RESCALE_NORMAL */ - { 27150, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */ - { 27172, 0x00000102 }, /* GL_RETURN */ - { 27182, 0x00001907 }, /* GL_RGB */ - { 27189, 0x00008052 }, /* GL_RGB10 */ - { 27198, 0x00008059 }, /* GL_RGB10_A2 */ - { 27210, 0x00008059 }, /* GL_RGB10_A2_EXT */ - { 27226, 0x00008052 }, /* GL_RGB10_EXT */ - { 27239, 0x00008053 }, /* GL_RGB12 */ - { 27248, 0x00008053 }, /* GL_RGB12_EXT */ - { 27261, 0x00008054 }, /* GL_RGB16 */ - { 27270, 0x00008054 }, /* GL_RGB16_EXT */ - { 27283, 0x0000804E }, /* GL_RGB2_EXT */ - { 27295, 0x0000804F }, /* GL_RGB4 */ - { 27303, 0x0000804F }, /* GL_RGB4_EXT */ - { 27315, 0x000083A1 }, /* GL_RGB4_S3TC */ - { 27328, 0x00008050 }, /* GL_RGB5 */ - { 27336, 0x00008057 }, /* GL_RGB5_A1 */ - { 27347, 0x00008057 }, /* GL_RGB5_A1_EXT */ - { 27362, 0x00008050 }, /* GL_RGB5_EXT */ - { 27374, 0x00008051 }, /* GL_RGB8 */ - { 27382, 0x00008051 }, /* GL_RGB8_EXT */ - { 27394, 0x00001908 }, /* GL_RGBA */ - { 27402, 0x0000805A }, /* GL_RGBA12 */ - { 27412, 0x0000805A }, /* GL_RGBA12_EXT */ - { 27426, 0x0000805B }, /* GL_RGBA16 */ - { 27436, 0x0000805B }, /* GL_RGBA16_EXT */ - { 27450, 0x00008055 }, /* GL_RGBA2 */ - { 27459, 0x00008055 }, /* GL_RGBA2_EXT */ - { 27472, 0x00008056 }, /* GL_RGBA4 */ - { 27481, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */ - { 27500, 0x00008056 }, /* GL_RGBA4_EXT */ - { 27513, 0x000083A3 }, /* GL_RGBA4_S3TC */ - { 27527, 0x00008058 }, /* GL_RGBA8 */ - { 27536, 0x00008058 }, /* GL_RGBA8_EXT */ - { 27549, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */ - { 27567, 0x00000C31 }, /* GL_RGBA_MODE */ - { 27580, 0x000083A2 }, /* GL_RGBA_S3TC */ - { 27593, 0x000083A0 }, /* GL_RGB_S3TC */ - { 27605, 0x00008573 }, /* GL_RGB_SCALE */ - { 27618, 0x00008573 }, /* GL_RGB_SCALE_ARB */ - { 27635, 0x00008573 }, /* GL_RGB_SCALE_EXT */ - { 27652, 0x00000407 }, /* GL_RIGHT */ - { 27661, 0x00002000 }, /* GL_S */ - { 27666, 0x00008B5D }, /* GL_SAMPLER_1D */ - { 27680, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */ - { 27701, 0x00008B5E }, /* GL_SAMPLER_2D */ - { 27715, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */ - { 27736, 0x00008B5F }, /* GL_SAMPLER_3D */ - { 27750, 0x00008B60 }, /* GL_SAMPLER_CUBE */ - { 27766, 0x000080A9 }, /* GL_SAMPLES */ - { 27777, 0x000086B4 }, /* GL_SAMPLES_3DFX */ - { 27793, 0x000080A9 }, /* GL_SAMPLES_ARB */ - { 27808, 0x00008914 }, /* GL_SAMPLES_PASSED */ - { 27826, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */ - { 27848, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */ - { 27876, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */ - { 27908, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */ - { 27931, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */ - { 27958, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */ - { 27976, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */ - { 27999, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */ - { 28021, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */ - { 28040, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */ - { 28063, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */ - { 28089, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */ - { 28119, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */ - { 28144, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */ - { 28173, 0x00080000 }, /* GL_SCISSOR_BIT */ - { 28188, 0x00000C10 }, /* GL_SCISSOR_BOX */ - { 28203, 0x00000C11 }, /* GL_SCISSOR_TEST */ - { 28219, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */ - { 28244, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */ - { 28284, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */ - { 28328, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */ - { 28361, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */ - { 28391, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */ - { 28423, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */ - { 28453, 0x00001C02 }, /* GL_SELECT */ - { 28463, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */ - { 28491, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */ - { 28516, 0x00008012 }, /* GL_SEPARABLE_2D */ - { 28532, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */ - { 28559, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */ - { 28590, 0x0000150F }, /* GL_SET */ - { 28597, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */ - { 28618, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */ - { 28642, 0x00008B4F }, /* GL_SHADER_TYPE */ - { 28657, 0x00000B54 }, /* GL_SHADE_MODEL */ - { 28672, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */ - { 28700, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */ - { 28723, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */ - { 28753, 0x00001601 }, /* GL_SHININESS */ - { 28766, 0x00001402 }, /* GL_SHORT */ - { 28775, 0x000081F9 }, /* GL_SINGLE_COLOR */ - { 28791, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */ - { 28811, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */ - { 28830, 0x00001D01 }, /* GL_SMOOTH */ - { 28840, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */ - { 28873, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */ - { 28900, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */ - { 28933, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */ - { 28960, 0x00008588 }, /* GL_SOURCE0_ALPHA */ - { 28977, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */ - { 28998, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */ - { 29019, 0x00008580 }, /* GL_SOURCE0_RGB */ - { 29034, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */ - { 29053, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */ - { 29072, 0x00008589 }, /* GL_SOURCE1_ALPHA */ - { 29089, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */ - { 29110, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */ - { 29131, 0x00008581 }, /* GL_SOURCE1_RGB */ - { 29146, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */ - { 29165, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */ - { 29184, 0x0000858A }, /* GL_SOURCE2_ALPHA */ - { 29201, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */ - { 29222, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */ - { 29243, 0x00008582 }, /* GL_SOURCE2_RGB */ - { 29258, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */ - { 29277, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */ - { 29296, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */ - { 29316, 0x00008583 }, /* GL_SOURCE3_RGB_NV */ - { 29334, 0x00001202 }, /* GL_SPECULAR */ - { 29346, 0x00002402 }, /* GL_SPHERE_MAP */ - { 29360, 0x00001206 }, /* GL_SPOT_CUTOFF */ - { 29375, 0x00001204 }, /* GL_SPOT_DIRECTION */ - { 29393, 0x00001205 }, /* GL_SPOT_EXPONENT */ - { 29410, 0x00008588 }, /* GL_SRC0_ALPHA */ - { 29424, 0x00008580 }, /* GL_SRC0_RGB */ - { 29436, 0x00008589 }, /* GL_SRC1_ALPHA */ - { 29450, 0x00008581 }, /* GL_SRC1_RGB */ - { 29462, 0x0000858A }, /* GL_SRC2_ALPHA */ - { 29476, 0x00008582 }, /* GL_SRC2_RGB */ - { 29488, 0x00000302 }, /* GL_SRC_ALPHA */ - { 29501, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */ - { 29523, 0x00000300 }, /* GL_SRC_COLOR */ - { 29536, 0x00000503 }, /* GL_STACK_OVERFLOW */ - { 29554, 0x00000504 }, /* GL_STACK_UNDERFLOW */ - { 29573, 0x000088E6 }, /* GL_STATIC_COPY */ - { 29588, 0x000088E6 }, /* GL_STATIC_COPY_ARB */ - { 29607, 0x000088E4 }, /* GL_STATIC_DRAW */ - { 29622, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */ - { 29641, 0x000088E5 }, /* GL_STATIC_READ */ - { 29656, 0x000088E5 }, /* GL_STATIC_READ_ARB */ - { 29675, 0x00001802 }, /* GL_STENCIL */ - { 29686, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */ - { 29712, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */ - { 29733, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */ - { 29754, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */ - { 29786, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */ - { 29818, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */ - { 29838, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */ - { 29865, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */ - { 29891, 0x00000D57 }, /* GL_STENCIL_BITS */ - { 29907, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */ - { 29929, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */ - { 29952, 0x00000B94 }, /* GL_STENCIL_FAIL */ - { 29968, 0x00000B92 }, /* GL_STENCIL_FUNC */ - { 29984, 0x00001901 }, /* GL_STENCIL_INDEX */ - { 30001, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */ - { 30024, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */ - { 30046, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */ - { 30068, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */ - { 30090, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */ - { 30111, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */ - { 30138, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */ - { 30165, 0x00000B97 }, /* GL_STENCIL_REF */ - { 30180, 0x00000B90 }, /* GL_STENCIL_TEST */ - { 30196, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */ - { 30225, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */ - { 30247, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */ - { 30268, 0x00000C33 }, /* GL_STEREO */ - { 30278, 0x000088E2 }, /* GL_STREAM_COPY */ - { 30293, 0x000088E2 }, /* GL_STREAM_COPY_ARB */ - { 30312, 0x000088E0 }, /* GL_STREAM_DRAW */ - { 30327, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */ - { 30346, 0x000088E1 }, /* GL_STREAM_READ */ - { 30361, 0x000088E1 }, /* GL_STREAM_READ_ARB */ - { 30380, 0x00000D50 }, /* GL_SUBPIXEL_BITS */ - { 30397, 0x000084E7 }, /* GL_SUBTRACT */ - { 30409, 0x000084E7 }, /* GL_SUBTRACT_ARB */ - { 30425, 0x00002001 }, /* GL_T */ - { 30430, 0x00002A2A }, /* GL_T2F_C3F_V3F */ - { 30445, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */ - { 30464, 0x00002A29 }, /* GL_T2F_C4UB_V3F */ - { 30480, 0x00002A2B }, /* GL_T2F_N3F_V3F */ - { 30495, 0x00002A27 }, /* GL_T2F_V3F */ - { 30506, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */ - { 30525, 0x00002A28 }, /* GL_T4F_V4F */ - { 30536, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */ - { 30559, 0x00001702 }, /* GL_TEXTURE */ - { 30570, 0x000084C0 }, /* GL_TEXTURE0 */ - { 30582, 0x000084C0 }, /* GL_TEXTURE0_ARB */ - { 30598, 0x000084C1 }, /* GL_TEXTURE1 */ - { 30610, 0x000084CA }, /* GL_TEXTURE10 */ - { 30623, 0x000084CA }, /* GL_TEXTURE10_ARB */ - { 30640, 0x000084CB }, /* GL_TEXTURE11 */ - { 30653, 0x000084CB }, /* GL_TEXTURE11_ARB */ - { 30670, 0x000084CC }, /* GL_TEXTURE12 */ - { 30683, 0x000084CC }, /* GL_TEXTURE12_ARB */ - { 30700, 0x000084CD }, /* GL_TEXTURE13 */ - { 30713, 0x000084CD }, /* GL_TEXTURE13_ARB */ - { 30730, 0x000084CE }, /* GL_TEXTURE14 */ - { 30743, 0x000084CE }, /* GL_TEXTURE14_ARB */ - { 30760, 0x000084CF }, /* GL_TEXTURE15 */ - { 30773, 0x000084CF }, /* GL_TEXTURE15_ARB */ - { 30790, 0x000084D0 }, /* GL_TEXTURE16 */ - { 30803, 0x000084D0 }, /* GL_TEXTURE16_ARB */ - { 30820, 0x000084D1 }, /* GL_TEXTURE17 */ - { 30833, 0x000084D1 }, /* GL_TEXTURE17_ARB */ - { 30850, 0x000084D2 }, /* GL_TEXTURE18 */ - { 30863, 0x000084D2 }, /* GL_TEXTURE18_ARB */ - { 30880, 0x000084D3 }, /* GL_TEXTURE19 */ - { 30893, 0x000084D3 }, /* GL_TEXTURE19_ARB */ - { 30910, 0x000084C1 }, /* GL_TEXTURE1_ARB */ - { 30926, 0x000084C2 }, /* GL_TEXTURE2 */ - { 30938, 0x000084D4 }, /* GL_TEXTURE20 */ - { 30951, 0x000084D4 }, /* GL_TEXTURE20_ARB */ - { 30968, 0x000084D5 }, /* GL_TEXTURE21 */ - { 30981, 0x000084D5 }, /* GL_TEXTURE21_ARB */ - { 30998, 0x000084D6 }, /* GL_TEXTURE22 */ - { 31011, 0x000084D6 }, /* GL_TEXTURE22_ARB */ - { 31028, 0x000084D7 }, /* GL_TEXTURE23 */ - { 31041, 0x000084D7 }, /* GL_TEXTURE23_ARB */ - { 31058, 0x000084D8 }, /* GL_TEXTURE24 */ - { 31071, 0x000084D8 }, /* GL_TEXTURE24_ARB */ - { 31088, 0x000084D9 }, /* GL_TEXTURE25 */ - { 31101, 0x000084D9 }, /* GL_TEXTURE25_ARB */ - { 31118, 0x000084DA }, /* GL_TEXTURE26 */ - { 31131, 0x000084DA }, /* GL_TEXTURE26_ARB */ - { 31148, 0x000084DB }, /* GL_TEXTURE27 */ - { 31161, 0x000084DB }, /* GL_TEXTURE27_ARB */ - { 31178, 0x000084DC }, /* GL_TEXTURE28 */ - { 31191, 0x000084DC }, /* GL_TEXTURE28_ARB */ - { 31208, 0x000084DD }, /* GL_TEXTURE29 */ - { 31221, 0x000084DD }, /* GL_TEXTURE29_ARB */ - { 31238, 0x000084C2 }, /* GL_TEXTURE2_ARB */ - { 31254, 0x000084C3 }, /* GL_TEXTURE3 */ - { 31266, 0x000084DE }, /* GL_TEXTURE30 */ - { 31279, 0x000084DE }, /* GL_TEXTURE30_ARB */ - { 31296, 0x000084DF }, /* GL_TEXTURE31 */ - { 31309, 0x000084DF }, /* GL_TEXTURE31_ARB */ - { 31326, 0x000084C3 }, /* GL_TEXTURE3_ARB */ - { 31342, 0x000084C4 }, /* GL_TEXTURE4 */ - { 31354, 0x000084C4 }, /* GL_TEXTURE4_ARB */ - { 31370, 0x000084C5 }, /* GL_TEXTURE5 */ - { 31382, 0x000084C5 }, /* GL_TEXTURE5_ARB */ - { 31398, 0x000084C6 }, /* GL_TEXTURE6 */ - { 31410, 0x000084C6 }, /* GL_TEXTURE6_ARB */ - { 31426, 0x000084C7 }, /* GL_TEXTURE7 */ - { 31438, 0x000084C7 }, /* GL_TEXTURE7_ARB */ - { 31454, 0x000084C8 }, /* GL_TEXTURE8 */ - { 31466, 0x000084C8 }, /* GL_TEXTURE8_ARB */ - { 31482, 0x000084C9 }, /* GL_TEXTURE9 */ - { 31494, 0x000084C9 }, /* GL_TEXTURE9_ARB */ - { 31510, 0x00000DE0 }, /* GL_TEXTURE_1D */ - { 31524, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */ - { 31548, 0x00000DE1 }, /* GL_TEXTURE_2D */ - { 31562, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */ - { 31586, 0x0000806F }, /* GL_TEXTURE_3D */ - { 31600, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */ - { 31622, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */ - { 31648, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */ - { 31670, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */ - { 31692, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */ - { 31724, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */ - { 31746, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */ - { 31778, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */ - { 31800, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */ - { 31828, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */ - { 31860, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */ - { 31893, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */ - { 31925, 0x00040000 }, /* GL_TEXTURE_BIT */ - { 31940, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */ - { 31961, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */ - { 31986, 0x00001005 }, /* GL_TEXTURE_BORDER */ - { 32004, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */ - { 32028, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */ - { 32059, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */ - { 32089, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */ - { 32119, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */ - { 32154, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */ - { 32185, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - { 32223, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */ - { 32250, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */ - { 32282, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ - { 32316, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */ - { 32340, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */ - { 32368, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */ - { 32392, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */ - { 32420, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */ - { 32453, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */ - { 32477, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */ - { 32499, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */ - { 32521, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */ - { 32547, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */ - { 32581, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */ - { 32614, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */ - { 32651, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */ - { 32679, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */ - { 32711, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */ - { 32734, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */ - { 32772, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */ - { 32814, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */ - { 32845, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */ - { 32873, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */ - { 32903, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */ - { 32931, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */ - { 32951, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */ - { 32975, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */ - { 33006, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */ - { 33041, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */ - { 33072, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */ - { 33107, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */ - { 33138, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */ - { 33173, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */ - { 33204, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */ - { 33239, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */ - { 33270, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */ - { 33305, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */ - { 33336, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */ - { 33371, 0x00008071 }, /* GL_TEXTURE_DEPTH */ - { 33388, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */ - { 33410, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */ - { 33436, 0x00002300 }, /* GL_TEXTURE_ENV */ - { 33451, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */ - { 33472, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */ - { 33492, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */ - { 33518, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */ - { 33538, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */ - { 33555, 0x00000C62 }, /* GL_TEXTURE_GEN_R */ - { 33572, 0x00000C60 }, /* GL_TEXTURE_GEN_S */ - { 33589, 0x00000C61 }, /* GL_TEXTURE_GEN_T */ - { 33606, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */ - { 33631, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */ - { 33653, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */ - { 33679, 0x00001001 }, /* GL_TEXTURE_HEIGHT */ - { 33697, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */ - { 33723, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */ - { 33749, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */ - { 33779, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */ - { 33806, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */ - { 33831, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */ - { 33851, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */ - { 33875, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */ - { 33902, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */ - { 33929, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */ - { 33956, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */ - { 33982, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */ - { 34012, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */ - { 34034, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */ - { 34052, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */ - { 34082, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */ - { 34110, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */ - { 34138, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */ - { 34166, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */ - { 34187, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */ - { 34206, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */ - { 34228, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */ - { 34247, 0x00008066 }, /* GL_TEXTURE_PRIORITY */ - { 34267, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */ - { 34292, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */ - { 34316, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */ - { 34336, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */ - { 34360, 0x00008067 }, /* GL_TEXTURE_RESIDENT */ - { 34380, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */ - { 34403, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */ - { 34428, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */ - { 34462, 0x00001000 }, /* GL_TEXTURE_WIDTH */ - { 34479, 0x00008072 }, /* GL_TEXTURE_WRAP_R */ - { 34497, 0x00002802 }, /* GL_TEXTURE_WRAP_S */ - { 34515, 0x00002803 }, /* GL_TEXTURE_WRAP_T */ - { 34533, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */ - { 34553, 0x00008648 }, /* GL_TRACK_MATRIX_NV */ - { 34572, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */ - { 34601, 0x00001000 }, /* GL_TRANSFORM_BIT */ - { 34618, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */ - { 34644, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */ - { 34674, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */ - { 34706, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */ - { 34736, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */ - { 34770, 0x0000862C }, /* GL_TRANSPOSE_NV */ - { 34786, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */ - { 34817, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */ - { 34852, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */ - { 34880, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */ - { 34912, 0x00000004 }, /* GL_TRIANGLES */ - { 34925, 0x00000006 }, /* GL_TRIANGLE_FAN */ - { 34941, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */ - { 34962, 0x00000005 }, /* GL_TRIANGLE_STRIP */ - { 34980, 0x00000001 }, /* GL_TRUE */ - { 34988, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */ - { 35008, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */ - { 35031, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */ - { 35051, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */ - { 35072, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */ - { 35094, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */ - { 35116, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */ - { 35136, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */ - { 35157, 0x00001401 }, /* GL_UNSIGNED_BYTE */ - { 35174, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */ - { 35201, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */ - { 35224, 0x00001405 }, /* GL_UNSIGNED_INT */ - { 35240, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */ - { 35267, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */ - { 35291, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */ - { 35322, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */ - { 35346, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */ - { 35374, 0x00001403 }, /* GL_UNSIGNED_SHORT */ - { 35392, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */ - { 35422, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */ - { 35448, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */ - { 35478, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */ - { 35504, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */ - { 35528, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */ - { 35556, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */ - { 35584, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */ - { 35611, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */ - { 35643, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */ - { 35674, 0x00008CA2 }, /* GL_UPPER_LEFT */ - { 35688, 0x00002A20 }, /* GL_V2F */ - { 35695, 0x00002A21 }, /* GL_V3F */ - { 35702, 0x00008B83 }, /* GL_VALIDATE_STATUS */ - { 35721, 0x00001F00 }, /* GL_VENDOR */ - { 35731, 0x00001F02 }, /* GL_VERSION */ - { 35742, 0x00008074 }, /* GL_VERTEX_ARRAY */ - { 35758, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */ - { 35788, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */ - { 35819, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */ - { 35854, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */ - { 35878, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */ - { 35899, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */ - { 35922, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */ - { 35943, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */ - { 35970, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */ - { 35998, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */ - { 36026, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */ - { 36054, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */ - { 36082, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */ - { 36110, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */ - { 36138, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */ - { 36165, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */ - { 36192, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */ - { 36219, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */ - { 36246, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */ - { 36273, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */ - { 36300, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */ - { 36327, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */ - { 36354, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */ - { 36381, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */ - { 36419, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */ - { 36461, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */ - { 36492, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */ - { 36527, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */ - { 36561, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */ - { 36599, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */ - { 36630, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */ - { 36665, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */ - { 36693, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */ - { 36725, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */ - { 36755, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */ - { 36789, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */ - { 36817, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */ - { 36849, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */ - { 36869, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */ - { 36891, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */ - { 36920, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */ - { 36941, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */ - { 36970, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */ - { 37003, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */ - { 37035, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */ - { 37062, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */ - { 37093, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */ - { 37123, 0x00008B31 }, /* GL_VERTEX_SHADER */ - { 37140, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */ - { 37161, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */ - { 37188, 0x00000BA2 }, /* GL_VIEWPORT */ - { 37200, 0x00000800 }, /* GL_VIEWPORT_BIT */ - { 37216, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */ - { 37236, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */ - { 37267, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */ - { 37302, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */ - { 37330, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */ - { 37355, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */ - { 37382, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */ - { 37407, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */ - { 37431, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */ - { 37450, 0x000088B9 }, /* GL_WRITE_ONLY */ - { 37464, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */ - { 37482, 0x00001506 }, /* GL_XOR */ - { 37489, 0x000085B9 }, /* GL_YCBCR_422_APPLE */ - { 37508, 0x00008757 }, /* GL_YCBCR_MESA */ - { 37522, 0x00000000 }, /* GL_ZERO */ - { 37530, 0x00000D16 }, /* GL_ZOOM_X */ - { 37540, 0x00000D17 }, /* GL_ZOOM_Y */ -}; - -static const unsigned reduced_enums[1284] = -{ - 436, /* GL_FALSE */ - 645, /* GL_LINES */ - 647, /* GL_LINE_LOOP */ - 654, /* GL_LINE_STRIP */ - 1637, /* GL_TRIANGLES */ - 1640, /* GL_TRIANGLE_STRIP */ - 1638, /* GL_TRIANGLE_FAN */ - 1211, /* GL_QUADS */ - 1213, /* GL_QUAD_STRIP */ - 1099, /* GL_POLYGON */ - 1111, /* GL_POLYGON_STIPPLE_BIT */ - 1064, /* GL_PIXEL_MODE_BIT */ - 632, /* GL_LIGHTING_BIT */ - 458, /* GL_FOG_BIT */ - 8, /* GL_ACCUM */ - 664, /* GL_LOAD */ - 1253, /* GL_RETURN */ - 937, /* GL_MULT */ - 23, /* GL_ADD */ - 953, /* GL_NEVER */ - 622, /* GL_LESS */ - 426, /* GL_EQUAL */ - 621, /* GL_LEQUAL */ - 547, /* GL_GREATER */ - 968, /* GL_NOTEQUAL */ - 522, /* GL_GEQUAL */ - 46, /* GL_ALWAYS */ - 1386, /* GL_SRC_COLOR */ - 997, /* GL_ONE_MINUS_SRC_COLOR */ - 1384, /* GL_SRC_ALPHA */ - 996, /* GL_ONE_MINUS_SRC_ALPHA */ - 406, /* GL_DST_ALPHA */ - 994, /* GL_ONE_MINUS_DST_ALPHA */ - 407, /* GL_DST_COLOR */ - 995, /* GL_ONE_MINUS_DST_COLOR */ - 1385, /* GL_SRC_ALPHA_SATURATE */ - 510, /* GL_FRONT_LEFT */ - 511, /* GL_FRONT_RIGHT */ - 69, /* GL_BACK_LEFT */ - 70, /* GL_BACK_RIGHT */ - 507, /* GL_FRONT */ - 68, /* GL_BACK */ - 620, /* GL_LEFT */ - 1293, /* GL_RIGHT */ - 508, /* GL_FRONT_AND_BACK */ - 63, /* GL_AUX0 */ - 64, /* GL_AUX1 */ - 65, /* GL_AUX2 */ - 66, /* GL_AUX3 */ - 612, /* GL_INVALID_ENUM */ - 615, /* GL_INVALID_VALUE */ - 614, /* GL_INVALID_OPERATION */ - 1387, /* GL_STACK_OVERFLOW */ - 1388, /* GL_STACK_UNDERFLOW */ - 1022, /* GL_OUT_OF_MEMORY */ - 613, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */ - 0, /* GL_2D */ - 2, /* GL_3D */ - 3, /* GL_3D_COLOR */ - 4, /* GL_3D_COLOR_TEXTURE */ - 6, /* GL_4D_COLOR_TEXTURE */ - 1042, /* GL_PASS_THROUGH_TOKEN */ - 1098, /* GL_POINT_TOKEN */ - 655, /* GL_LINE_TOKEN */ - 1112, /* GL_POLYGON_TOKEN */ - 74, /* GL_BITMAP_TOKEN */ - 405, /* GL_DRAW_PIXEL_TOKEN */ - 271, /* GL_COPY_PIXEL_TOKEN */ - 648, /* GL_LINE_RESET_TOKEN */ - 429, /* GL_EXP */ - 430, /* GL_EXP2 */ - 304, /* GL_CW */ - 116, /* GL_CCW */ - 137, /* GL_COEFF */ - 1019, /* GL_ORDER */ - 344, /* GL_DOMAIN */ - 279, /* GL_CURRENT_COLOR */ - 282, /* GL_CURRENT_INDEX */ - 288, /* GL_CURRENT_NORMAL */ - 300, /* GL_CURRENT_TEXTURE_COORDS */ - 293, /* GL_CURRENT_RASTER_COLOR */ - 295, /* GL_CURRENT_RASTER_INDEX */ - 298, /* GL_CURRENT_RASTER_TEXTURE_COORDS */ - 296, /* GL_CURRENT_RASTER_POSITION */ - 297, /* GL_CURRENT_RASTER_POSITION_VALID */ - 294, /* GL_CURRENT_RASTER_DISTANCE */ - 1091, /* GL_POINT_SMOOTH */ - 1080, /* GL_POINT_SIZE */ - 1090, /* GL_POINT_SIZE_RANGE */ - 1081, /* GL_POINT_SIZE_GRANULARITY */ - 649, /* GL_LINE_SMOOTH */ - 656, /* GL_LINE_WIDTH */ - 658, /* GL_LINE_WIDTH_RANGE */ - 657, /* GL_LINE_WIDTH_GRANULARITY */ - 651, /* GL_LINE_STIPPLE */ - 652, /* GL_LINE_STIPPLE_PATTERN */ - 653, /* GL_LINE_STIPPLE_REPEAT */ - 663, /* GL_LIST_MODE */ - 822, /* GL_MAX_LIST_NESTING */ - 660, /* GL_LIST_BASE */ - 662, /* GL_LIST_INDEX */ - 1101, /* GL_POLYGON_MODE */ - 1108, /* GL_POLYGON_SMOOTH */ - 1110, /* GL_POLYGON_STIPPLE */ - 414, /* GL_EDGE_FLAG */ - 272, /* GL_CULL_FACE */ - 273, /* GL_CULL_FACE_MODE */ - 509, /* GL_FRONT_FACE */ - 631, /* GL_LIGHTING */ - 636, /* GL_LIGHT_MODEL_LOCAL_VIEWER */ - 637, /* GL_LIGHT_MODEL_TWO_SIDE */ - 633, /* GL_LIGHT_MODEL_AMBIENT */ - 1339, /* GL_SHADE_MODEL */ - 168, /* GL_COLOR_MATERIAL_FACE */ - 169, /* GL_COLOR_MATERIAL_PARAMETER */ - 167, /* GL_COLOR_MATERIAL */ - 457, /* GL_FOG */ - 479, /* GL_FOG_INDEX */ - 475, /* GL_FOG_DENSITY */ - 483, /* GL_FOG_START */ - 477, /* GL_FOG_END */ - 480, /* GL_FOG_MODE */ - 459, /* GL_FOG_COLOR */ - 333, /* GL_DEPTH_RANGE */ - 338, /* GL_DEPTH_TEST */ - 341, /* GL_DEPTH_WRITEMASK */ - 321, /* GL_DEPTH_CLEAR_VALUE */ - 332, /* GL_DEPTH_FUNC */ - 12, /* GL_ACCUM_CLEAR_VALUE */ - 1418, /* GL_STENCIL_TEST */ - 1406, /* GL_STENCIL_CLEAR_VALUE */ - 1408, /* GL_STENCIL_FUNC */ - 1420, /* GL_STENCIL_VALUE_MASK */ - 1407, /* GL_STENCIL_FAIL */ - 1415, /* GL_STENCIL_PASS_DEPTH_FAIL */ - 1416, /* GL_STENCIL_PASS_DEPTH_PASS */ - 1417, /* GL_STENCIL_REF */ - 1421, /* GL_STENCIL_WRITEMASK */ - 791, /* GL_MATRIX_MODE */ - 958, /* GL_NORMALIZE */ - 1727, /* GL_VIEWPORT */ - 932, /* GL_MODELVIEW_STACK_DEPTH */ - 1191, /* GL_PROJECTION_STACK_DEPTH */ - 1616, /* GL_TEXTURE_STACK_DEPTH */ - 930, /* GL_MODELVIEW_MATRIX */ - 1190, /* GL_PROJECTION_MATRIX */ - 1601, /* GL_TEXTURE_MATRIX */ - 61, /* GL_ATTRIB_STACK_DEPTH */ - 127, /* GL_CLIENT_ATTRIB_STACK_DEPTH */ - 43, /* GL_ALPHA_TEST */ - 44, /* GL_ALPHA_TEST_FUNC */ - 45, /* GL_ALPHA_TEST_REF */ - 343, /* GL_DITHER */ - 78, /* GL_BLEND_DST */ - 86, /* GL_BLEND_SRC */ - 75, /* GL_BLEND */ - 666, /* GL_LOGIC_OP_MODE */ - 586, /* GL_INDEX_LOGIC_OP */ - 166, /* GL_COLOR_LOGIC_OP */ - 67, /* GL_AUX_BUFFERS */ - 354, /* GL_DRAW_BUFFER */ - 1223, /* GL_READ_BUFFER */ - 1320, /* GL_SCISSOR_BOX */ - 1321, /* GL_SCISSOR_TEST */ - 585, /* GL_INDEX_CLEAR_VALUE */ - 590, /* GL_INDEX_WRITEMASK */ - 163, /* GL_COLOR_CLEAR_VALUE */ - 205, /* GL_COLOR_WRITEMASK */ - 587, /* GL_INDEX_MODE */ - 1287, /* GL_RGBA_MODE */ - 353, /* GL_DOUBLEBUFFER */ - 1422, /* GL_STEREO */ - 1246, /* GL_RENDER_MODE */ - 1043, /* GL_PERSPECTIVE_CORRECTION_HINT */ - 1092, /* GL_POINT_SMOOTH_HINT */ - 650, /* GL_LINE_SMOOTH_HINT */ - 1109, /* GL_POLYGON_SMOOTH_HINT */ - 478, /* GL_FOG_HINT */ - 1582, /* GL_TEXTURE_GEN_S */ - 1583, /* GL_TEXTURE_GEN_T */ - 1581, /* GL_TEXTURE_GEN_R */ - 1580, /* GL_TEXTURE_GEN_Q */ - 1056, /* GL_PIXEL_MAP_I_TO_I */ - 1062, /* GL_PIXEL_MAP_S_TO_S */ - 1058, /* GL_PIXEL_MAP_I_TO_R */ - 1054, /* GL_PIXEL_MAP_I_TO_G */ - 1052, /* GL_PIXEL_MAP_I_TO_B */ - 1050, /* GL_PIXEL_MAP_I_TO_A */ - 1060, /* GL_PIXEL_MAP_R_TO_R */ - 1048, /* GL_PIXEL_MAP_G_TO_G */ - 1046, /* GL_PIXEL_MAP_B_TO_B */ - 1044, /* GL_PIXEL_MAP_A_TO_A */ - 1057, /* GL_PIXEL_MAP_I_TO_I_SIZE */ - 1063, /* GL_PIXEL_MAP_S_TO_S_SIZE */ - 1059, /* GL_PIXEL_MAP_I_TO_R_SIZE */ - 1055, /* GL_PIXEL_MAP_I_TO_G_SIZE */ - 1053, /* GL_PIXEL_MAP_I_TO_B_SIZE */ - 1051, /* GL_PIXEL_MAP_I_TO_A_SIZE */ - 1061, /* GL_PIXEL_MAP_R_TO_R_SIZE */ - 1049, /* GL_PIXEL_MAP_G_TO_G_SIZE */ - 1047, /* GL_PIXEL_MAP_B_TO_B_SIZE */ - 1045, /* GL_PIXEL_MAP_A_TO_A_SIZE */ - 1649, /* GL_UNPACK_SWAP_BYTES */ - 1644, /* GL_UNPACK_LSB_FIRST */ - 1645, /* GL_UNPACK_ROW_LENGTH */ - 1648, /* GL_UNPACK_SKIP_ROWS */ - 1647, /* GL_UNPACK_SKIP_PIXELS */ - 1642, /* GL_UNPACK_ALIGNMENT */ - 1031, /* GL_PACK_SWAP_BYTES */ - 1026, /* GL_PACK_LSB_FIRST */ - 1027, /* GL_PACK_ROW_LENGTH */ - 1030, /* GL_PACK_SKIP_ROWS */ - 1029, /* GL_PACK_SKIP_PIXELS */ - 1023, /* GL_PACK_ALIGNMENT */ - 744, /* GL_MAP_COLOR */ - 745, /* GL_MAP_STENCIL */ - 589, /* GL_INDEX_SHIFT */ - 588, /* GL_INDEX_OFFSET */ - 1235, /* GL_RED_SCALE */ - 1233, /* GL_RED_BIAS */ - 1744, /* GL_ZOOM_X */ - 1745, /* GL_ZOOM_Y */ - 551, /* GL_GREEN_SCALE */ - 549, /* GL_GREEN_BIAS */ - 92, /* GL_BLUE_SCALE */ - 90, /* GL_BLUE_BIAS */ - 42, /* GL_ALPHA_SCALE */ - 40, /* GL_ALPHA_BIAS */ - 334, /* GL_DEPTH_SCALE */ - 315, /* GL_DEPTH_BIAS */ - 817, /* GL_MAX_EVAL_ORDER */ - 821, /* GL_MAX_LIGHTS */ - 800, /* GL_MAX_CLIP_PLANES */ - 865, /* GL_MAX_TEXTURE_SIZE */ - 827, /* GL_MAX_PIXEL_MAP_TABLE */ - 796, /* GL_MAX_ATTRIB_STACK_DEPTH */ - 824, /* GL_MAX_MODELVIEW_STACK_DEPTH */ - 825, /* GL_MAX_NAME_STACK_DEPTH */ - 853, /* GL_MAX_PROJECTION_STACK_DEPTH */ - 866, /* GL_MAX_TEXTURE_STACK_DEPTH */ - 880, /* GL_MAX_VIEWPORT_DIMS */ - 797, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */ - 1429, /* GL_SUBPIXEL_BITS */ - 584, /* GL_INDEX_BITS */ - 1234, /* GL_RED_BITS */ - 550, /* GL_GREEN_BITS */ - 91, /* GL_BLUE_BITS */ - 41, /* GL_ALPHA_BITS */ - 316, /* GL_DEPTH_BITS */ - 1404, /* GL_STENCIL_BITS */ - 14, /* GL_ACCUM_RED_BITS */ - 13, /* GL_ACCUM_GREEN_BITS */ - 10, /* GL_ACCUM_BLUE_BITS */ - 9, /* GL_ACCUM_ALPHA_BITS */ - 946, /* GL_NAME_STACK_DEPTH */ - 62, /* GL_AUTO_NORMAL */ - 690, /* GL_MAP1_COLOR_4 */ - 693, /* GL_MAP1_INDEX */ - 694, /* GL_MAP1_NORMAL */ - 695, /* GL_MAP1_TEXTURE_COORD_1 */ - 696, /* GL_MAP1_TEXTURE_COORD_2 */ - 697, /* GL_MAP1_TEXTURE_COORD_3 */ - 698, /* GL_MAP1_TEXTURE_COORD_4 */ - 699, /* GL_MAP1_VERTEX_3 */ - 700, /* GL_MAP1_VERTEX_4 */ - 717, /* GL_MAP2_COLOR_4 */ - 720, /* GL_MAP2_INDEX */ - 721, /* GL_MAP2_NORMAL */ - 722, /* GL_MAP2_TEXTURE_COORD_1 */ - 723, /* GL_MAP2_TEXTURE_COORD_2 */ - 724, /* GL_MAP2_TEXTURE_COORD_3 */ - 725, /* GL_MAP2_TEXTURE_COORD_4 */ - 726, /* GL_MAP2_VERTEX_3 */ - 727, /* GL_MAP2_VERTEX_4 */ - 691, /* GL_MAP1_GRID_DOMAIN */ - 692, /* GL_MAP1_GRID_SEGMENTS */ - 718, /* GL_MAP2_GRID_DOMAIN */ - 719, /* GL_MAP2_GRID_SEGMENTS */ - 1506, /* GL_TEXTURE_1D */ - 1508, /* GL_TEXTURE_2D */ - 439, /* GL_FEEDBACK_BUFFER_POINTER */ - 440, /* GL_FEEDBACK_BUFFER_SIZE */ - 441, /* GL_FEEDBACK_BUFFER_TYPE */ - 1330, /* GL_SELECTION_BUFFER_POINTER */ - 1331, /* GL_SELECTION_BUFFER_SIZE */ - 1619, /* GL_TEXTURE_WIDTH */ - 1587, /* GL_TEXTURE_HEIGHT */ - 1543, /* GL_TEXTURE_COMPONENTS */ - 1527, /* GL_TEXTURE_BORDER_COLOR */ - 1526, /* GL_TEXTURE_BORDER */ - 345, /* GL_DONT_CARE */ - 437, /* GL_FASTEST */ - 954, /* GL_NICEST */ - 47, /* GL_AMBIENT */ - 342, /* GL_DIFFUSE */ - 1373, /* GL_SPECULAR */ - 1113, /* GL_POSITION */ - 1376, /* GL_SPOT_DIRECTION */ - 1377, /* GL_SPOT_EXPONENT */ - 1375, /* GL_SPOT_CUTOFF */ - 245, /* GL_CONSTANT_ATTENUATION */ - 640, /* GL_LINEAR_ATTENUATION */ - 1210, /* GL_QUADRATIC_ATTENUATION */ - 219, /* GL_COMPILE */ - 220, /* GL_COMPILE_AND_EXECUTE */ - 111, /* GL_BYTE */ - 1650, /* GL_UNSIGNED_BYTE */ - 1344, /* GL_SHORT */ - 1659, /* GL_UNSIGNED_SHORT */ - 592, /* GL_INT */ - 1653, /* GL_UNSIGNED_INT */ - 444, /* GL_FLOAT */ - 1, /* GL_2_BYTES */ - 5, /* GL_3_BYTES */ - 7, /* GL_4_BYTES */ - 352, /* GL_DOUBLE */ - 123, /* GL_CLEAR */ - 49, /* GL_AND */ - 51, /* GL_AND_REVERSE */ - 269, /* GL_COPY */ - 50, /* GL_AND_INVERTED */ - 956, /* GL_NOOP */ - 1740, /* GL_XOR */ - 1018, /* GL_OR */ - 957, /* GL_NOR */ - 427, /* GL_EQUIV */ - 618, /* GL_INVERT */ - 1021, /* GL_OR_REVERSE */ - 270, /* GL_COPY_INVERTED */ - 1020, /* GL_OR_INVERTED */ - 947, /* GL_NAND */ - 1335, /* GL_SET */ - 424, /* GL_EMISSION */ - 1343, /* GL_SHININESS */ - 48, /* GL_AMBIENT_AND_DIFFUSE */ - 165, /* GL_COLOR_INDEXES */ - 897, /* GL_MODELVIEW */ - 1189, /* GL_PROJECTION */ - 1441, /* GL_TEXTURE */ - 138, /* GL_COLOR */ - 313, /* GL_DEPTH */ - 1395, /* GL_STENCIL */ - 164, /* GL_COLOR_INDEX */ - 1409, /* GL_STENCIL_INDEX */ - 322, /* GL_DEPTH_COMPONENT */ - 1230, /* GL_RED */ - 548, /* GL_GREEN */ - 89, /* GL_BLUE */ - 31, /* GL_ALPHA */ - 1254, /* GL_RGB */ - 1273, /* GL_RGBA */ - 668, /* GL_LUMINANCE */ - 689, /* GL_LUMINANCE_ALPHA */ - 73, /* GL_BITMAP */ - 1069, /* GL_POINT */ - 638, /* GL_LINE */ - 442, /* GL_FILL */ - 1239, /* GL_RENDER */ - 438, /* GL_FEEDBACK */ - 1329, /* GL_SELECT */ - 443, /* GL_FLAT */ - 1348, /* GL_SMOOTH */ - 619, /* GL_KEEP */ - 1248, /* GL_REPLACE */ - 575, /* GL_INCR */ - 309, /* GL_DECR */ - 1674, /* GL_VENDOR */ - 1245, /* GL_RENDERER */ - 1675, /* GL_VERSION */ - 431, /* GL_EXTENSIONS */ - 1294, /* GL_S */ - 1432, /* GL_T */ - 1220, /* GL_R */ - 1209, /* GL_Q */ - 933, /* GL_MODULATE */ - 308, /* GL_DECAL */ - 1577, /* GL_TEXTURE_ENV_MODE */ - 1576, /* GL_TEXTURE_ENV_COLOR */ - 1575, /* GL_TEXTURE_ENV */ - 432, /* GL_EYE_LINEAR */ - 980, /* GL_OBJECT_LINEAR */ - 1374, /* GL_SPHERE_MAP */ - 1579, /* GL_TEXTURE_GEN_MODE */ - 982, /* GL_OBJECT_PLANE */ - 433, /* GL_EYE_PLANE */ - 948, /* GL_NEAREST */ - 639, /* GL_LINEAR */ - 952, /* GL_NEAREST_MIPMAP_NEAREST */ - 644, /* GL_LINEAR_MIPMAP_NEAREST */ - 951, /* GL_NEAREST_MIPMAP_LINEAR */ - 643, /* GL_LINEAR_MIPMAP_LINEAR */ - 1600, /* GL_TEXTURE_MAG_FILTER */ - 1608, /* GL_TEXTURE_MIN_FILTER */ - 1621, /* GL_TEXTURE_WRAP_S */ - 1622, /* GL_TEXTURE_WRAP_T */ - 117, /* GL_CLAMP */ - 1247, /* GL_REPEAT */ - 1107, /* GL_POLYGON_OFFSET_UNITS */ - 1106, /* GL_POLYGON_OFFSET_POINT */ - 1105, /* GL_POLYGON_OFFSET_LINE */ - 1221, /* GL_R3_G3_B2 */ - 1671, /* GL_V2F */ - 1672, /* GL_V3F */ - 114, /* GL_C4UB_V2F */ - 115, /* GL_C4UB_V3F */ - 112, /* GL_C3F_V3F */ - 945, /* GL_N3F_V3F */ - 113, /* GL_C4F_N3F_V3F */ - 1437, /* GL_T2F_V3F */ - 1439, /* GL_T4F_V4F */ - 1435, /* GL_T2F_C4UB_V3F */ - 1433, /* GL_T2F_C3F_V3F */ - 1436, /* GL_T2F_N3F_V3F */ - 1434, /* GL_T2F_C4F_N3F_V3F */ - 1438, /* GL_T4F_C4F_N3F_V4F */ - 130, /* GL_CLIP_PLANE0 */ - 131, /* GL_CLIP_PLANE1 */ - 132, /* GL_CLIP_PLANE2 */ - 133, /* GL_CLIP_PLANE3 */ - 134, /* GL_CLIP_PLANE4 */ - 135, /* GL_CLIP_PLANE5 */ - 623, /* GL_LIGHT0 */ - 624, /* GL_LIGHT1 */ - 625, /* GL_LIGHT2 */ - 626, /* GL_LIGHT3 */ - 627, /* GL_LIGHT4 */ - 628, /* GL_LIGHT5 */ - 629, /* GL_LIGHT6 */ - 630, /* GL_LIGHT7 */ - 552, /* GL_HINT_BIT */ - 247, /* GL_CONSTANT_COLOR */ - 992, /* GL_ONE_MINUS_CONSTANT_COLOR */ - 242, /* GL_CONSTANT_ALPHA */ - 990, /* GL_ONE_MINUS_CONSTANT_ALPHA */ - 76, /* GL_BLEND_COLOR */ - 512, /* GL_FUNC_ADD */ - 881, /* GL_MIN */ - 793, /* GL_MAX */ - 81, /* GL_BLEND_EQUATION */ - 516, /* GL_FUNC_SUBTRACT */ - 514, /* GL_FUNC_REVERSE_SUBTRACT */ - 250, /* GL_CONVOLUTION_1D */ - 251, /* GL_CONVOLUTION_2D */ - 1332, /* GL_SEPARABLE_2D */ - 254, /* GL_CONVOLUTION_BORDER_MODE */ - 258, /* GL_CONVOLUTION_FILTER_SCALE */ - 256, /* GL_CONVOLUTION_FILTER_BIAS */ - 1231, /* GL_REDUCE */ - 260, /* GL_CONVOLUTION_FORMAT */ - 264, /* GL_CONVOLUTION_WIDTH */ - 262, /* GL_CONVOLUTION_HEIGHT */ - 808, /* GL_MAX_CONVOLUTION_WIDTH */ - 806, /* GL_MAX_CONVOLUTION_HEIGHT */ - 1146, /* GL_POST_CONVOLUTION_RED_SCALE */ - 1142, /* GL_POST_CONVOLUTION_GREEN_SCALE */ - 1137, /* GL_POST_CONVOLUTION_BLUE_SCALE */ - 1133, /* GL_POST_CONVOLUTION_ALPHA_SCALE */ - 1144, /* GL_POST_CONVOLUTION_RED_BIAS */ - 1140, /* GL_POST_CONVOLUTION_GREEN_BIAS */ - 1135, /* GL_POST_CONVOLUTION_BLUE_BIAS */ - 1131, /* GL_POST_CONVOLUTION_ALPHA_BIAS */ - 553, /* GL_HISTOGRAM */ - 1193, /* GL_PROXY_HISTOGRAM */ - 569, /* GL_HISTOGRAM_WIDTH */ - 559, /* GL_HISTOGRAM_FORMAT */ - 565, /* GL_HISTOGRAM_RED_SIZE */ - 561, /* GL_HISTOGRAM_GREEN_SIZE */ - 556, /* GL_HISTOGRAM_BLUE_SIZE */ - 554, /* GL_HISTOGRAM_ALPHA_SIZE */ - 563, /* GL_HISTOGRAM_LUMINANCE_SIZE */ - 567, /* GL_HISTOGRAM_SINK */ - 882, /* GL_MINMAX */ - 884, /* GL_MINMAX_FORMAT */ - 886, /* GL_MINMAX_SINK */ - 1440, /* GL_TABLE_TOO_LARGE_EXT */ - 1652, /* GL_UNSIGNED_BYTE_3_3_2 */ - 1661, /* GL_UNSIGNED_SHORT_4_4_4_4 */ - 1663, /* GL_UNSIGNED_SHORT_5_5_5_1 */ - 1657, /* GL_UNSIGNED_INT_8_8_8_8 */ - 1654, /* GL_UNSIGNED_INT_10_10_10_2 */ - 1104, /* GL_POLYGON_OFFSET_FILL */ - 1103, /* GL_POLYGON_OFFSET_FACTOR */ - 1102, /* GL_POLYGON_OFFSET_BIAS */ - 1251, /* GL_RESCALE_NORMAL */ - 36, /* GL_ALPHA4 */ - 38, /* GL_ALPHA8 */ - 32, /* GL_ALPHA12 */ - 34, /* GL_ALPHA16 */ - 679, /* GL_LUMINANCE4 */ - 685, /* GL_LUMINANCE8 */ - 669, /* GL_LUMINANCE12 */ - 675, /* GL_LUMINANCE16 */ - 680, /* GL_LUMINANCE4_ALPHA4 */ - 683, /* GL_LUMINANCE6_ALPHA2 */ - 686, /* GL_LUMINANCE8_ALPHA8 */ - 672, /* GL_LUMINANCE12_ALPHA4 */ - 670, /* GL_LUMINANCE12_ALPHA12 */ - 676, /* GL_LUMINANCE16_ALPHA16 */ - 593, /* GL_INTENSITY */ - 598, /* GL_INTENSITY4 */ - 600, /* GL_INTENSITY8 */ - 594, /* GL_INTENSITY12 */ - 596, /* GL_INTENSITY16 */ - 1263, /* GL_RGB2_EXT */ - 1264, /* GL_RGB4 */ - 1267, /* GL_RGB5 */ - 1271, /* GL_RGB8 */ - 1255, /* GL_RGB10 */ - 1259, /* GL_RGB12 */ - 1261, /* GL_RGB16 */ - 1278, /* GL_RGBA2 */ - 1280, /* GL_RGBA4 */ - 1268, /* GL_RGB5_A1 */ - 1284, /* GL_RGBA8 */ - 1256, /* GL_RGB10_A2 */ - 1274, /* GL_RGBA12 */ - 1276, /* GL_RGBA16 */ - 1613, /* GL_TEXTURE_RED_SIZE */ - 1585, /* GL_TEXTURE_GREEN_SIZE */ - 1524, /* GL_TEXTURE_BLUE_SIZE */ - 1511, /* GL_TEXTURE_ALPHA_SIZE */ - 1598, /* GL_TEXTURE_LUMINANCE_SIZE */ - 1589, /* GL_TEXTURE_INTENSITY_SIZE */ - 1249, /* GL_REPLACE_EXT */ - 1197, /* GL_PROXY_TEXTURE_1D */ - 1200, /* GL_PROXY_TEXTURE_2D */ - 1617, /* GL_TEXTURE_TOO_LARGE_EXT */ - 1610, /* GL_TEXTURE_PRIORITY */ - 1615, /* GL_TEXTURE_RESIDENT */ - 1514, /* GL_TEXTURE_BINDING_1D */ - 1516, /* GL_TEXTURE_BINDING_2D */ - 1518, /* GL_TEXTURE_BINDING_3D */ - 1028, /* GL_PACK_SKIP_IMAGES */ - 1024, /* GL_PACK_IMAGE_HEIGHT */ - 1646, /* GL_UNPACK_SKIP_IMAGES */ - 1643, /* GL_UNPACK_IMAGE_HEIGHT */ - 1510, /* GL_TEXTURE_3D */ - 1203, /* GL_PROXY_TEXTURE_3D */ - 1572, /* GL_TEXTURE_DEPTH */ - 1620, /* GL_TEXTURE_WRAP_R */ - 794, /* GL_MAX_3D_TEXTURE_SIZE */ - 1676, /* GL_VERTEX_ARRAY */ - 959, /* GL_NORMAL_ARRAY */ - 139, /* GL_COLOR_ARRAY */ - 578, /* GL_INDEX_ARRAY */ - 1551, /* GL_TEXTURE_COORD_ARRAY */ - 415, /* GL_EDGE_FLAG_ARRAY */ - 1681, /* GL_VERTEX_ARRAY_SIZE */ - 1683, /* GL_VERTEX_ARRAY_TYPE */ - 1682, /* GL_VERTEX_ARRAY_STRIDE */ - 964, /* GL_NORMAL_ARRAY_TYPE */ - 963, /* GL_NORMAL_ARRAY_STRIDE */ - 143, /* GL_COLOR_ARRAY_SIZE */ - 145, /* GL_COLOR_ARRAY_TYPE */ - 144, /* GL_COLOR_ARRAY_STRIDE */ - 583, /* GL_INDEX_ARRAY_TYPE */ - 582, /* GL_INDEX_ARRAY_STRIDE */ - 1555, /* GL_TEXTURE_COORD_ARRAY_SIZE */ - 1557, /* GL_TEXTURE_COORD_ARRAY_TYPE */ - 1556, /* GL_TEXTURE_COORD_ARRAY_STRIDE */ - 419, /* GL_EDGE_FLAG_ARRAY_STRIDE */ - 1680, /* GL_VERTEX_ARRAY_POINTER */ - 962, /* GL_NORMAL_ARRAY_POINTER */ - 142, /* GL_COLOR_ARRAY_POINTER */ - 581, /* GL_INDEX_ARRAY_POINTER */ - 1554, /* GL_TEXTURE_COORD_ARRAY_POINTER */ - 418, /* GL_EDGE_FLAG_ARRAY_POINTER */ - 938, /* GL_MULTISAMPLE */ - 1306, /* GL_SAMPLE_ALPHA_TO_COVERAGE */ - 1308, /* GL_SAMPLE_ALPHA_TO_ONE */ - 1313, /* GL_SAMPLE_COVERAGE */ - 1310, /* GL_SAMPLE_BUFFERS */ - 1301, /* GL_SAMPLES */ - 1317, /* GL_SAMPLE_COVERAGE_VALUE */ - 1315, /* GL_SAMPLE_COVERAGE_INVERT */ - 170, /* GL_COLOR_MATRIX */ - 172, /* GL_COLOR_MATRIX_STACK_DEPTH */ - 802, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ - 1129, /* GL_POST_COLOR_MATRIX_RED_SCALE */ - 1125, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ - 1120, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ - 1116, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ - 1127, /* GL_POST_COLOR_MATRIX_RED_BIAS */ - 1123, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ - 1118, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ - 1114, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ - 1534, /* GL_TEXTURE_COLOR_TABLE_SGI */ - 1204, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */ - 1536, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ - 80, /* GL_BLEND_DST_RGB */ - 88, /* GL_BLEND_SRC_RGB */ - 79, /* GL_BLEND_DST_ALPHA */ - 87, /* GL_BLEND_SRC_ALPHA */ - 176, /* GL_COLOR_TABLE */ - 1139, /* GL_POST_CONVOLUTION_COLOR_TABLE */ - 1122, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ - 1192, /* GL_PROXY_COLOR_TABLE */ - 1196, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ - 1195, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ - 200, /* GL_COLOR_TABLE_SCALE */ - 180, /* GL_COLOR_TABLE_BIAS */ - 185, /* GL_COLOR_TABLE_FORMAT */ - 202, /* GL_COLOR_TABLE_WIDTH */ - 197, /* GL_COLOR_TABLE_RED_SIZE */ - 188, /* GL_COLOR_TABLE_GREEN_SIZE */ - 182, /* GL_COLOR_TABLE_BLUE_SIZE */ - 177, /* GL_COLOR_TABLE_ALPHA_SIZE */ - 194, /* GL_COLOR_TABLE_LUMINANCE_SIZE */ - 191, /* GL_COLOR_TABLE_INTENSITY_SIZE */ - 71, /* GL_BGR */ - 72, /* GL_BGRA */ - 816, /* GL_MAX_ELEMENTS_VERTICES */ - 815, /* GL_MAX_ELEMENTS_INDICES */ - 1588, /* GL_TEXTURE_INDEX_SIZE_EXT */ - 136, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */ - 1086, /* GL_POINT_SIZE_MIN */ - 1082, /* GL_POINT_SIZE_MAX */ - 1076, /* GL_POINT_FADE_THRESHOLD_SIZE */ - 1072, /* GL_POINT_DISTANCE_ATTENUATION */ - 118, /* GL_CLAMP_TO_BORDER */ - 121, /* GL_CLAMP_TO_EDGE */ - 1609, /* GL_TEXTURE_MIN_LOD */ - 1607, /* GL_TEXTURE_MAX_LOD */ - 1513, /* GL_TEXTURE_BASE_LEVEL */ - 1606, /* GL_TEXTURE_MAX_LEVEL */ - 572, /* GL_IGNORE_BORDER_HP */ - 246, /* GL_CONSTANT_BORDER_HP */ - 1250, /* GL_REPLICATE_BORDER_HP */ - 252, /* GL_CONVOLUTION_BORDER_COLOR */ - 987, /* GL_OCCLUSION_TEST_HP */ - 988, /* GL_OCCLUSION_TEST_RESULT_HP */ - 641, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */ - 1528, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */ - 1530, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */ - 1532, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */ - 1533, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - 1531, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */ - 1529, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */ - 798, /* GL_MAX_CLIPMAP_DEPTH_SGIX */ - 799, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - 1149, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */ - 1151, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */ - 1148, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */ - 1150, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */ - 1596, /* GL_TEXTURE_LOD_BIAS_S_SGIX */ - 1597, /* GL_TEXTURE_LOD_BIAS_T_SGIX */ - 1595, /* GL_TEXTURE_LOD_BIAS_R_SGIX */ - 518, /* GL_GENERATE_MIPMAP */ - 519, /* GL_GENERATE_MIPMAP_HINT */ - 481, /* GL_FOG_OFFSET_SGIX */ - 482, /* GL_FOG_OFFSET_VALUE_SGIX */ - 1542, /* GL_TEXTURE_COMPARE_SGIX */ - 1541, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */ - 1592, /* GL_TEXTURE_LEQUAL_R_SGIX */ - 1584, /* GL_TEXTURE_GEQUAL_R_SGIX */ - 323, /* GL_DEPTH_COMPONENT16 */ - 326, /* GL_DEPTH_COMPONENT24 */ - 329, /* GL_DEPTH_COMPONENT32 */ - 274, /* GL_CULL_VERTEX_EXT */ - 276, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */ - 275, /* GL_CULL_VERTEX_EYE_POSITION_EXT */ - 1737, /* GL_WRAP_BORDER_SUN */ - 1535, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */ - 634, /* GL_LIGHT_MODEL_COLOR_CONTROL */ - 1345, /* GL_SINGLE_COLOR */ - 1333, /* GL_SEPARATE_SPECULAR_COLOR */ - 1342, /* GL_SHARED_TEXTURE_PALETTE_EXT */ - 1651, /* GL_UNSIGNED_BYTE_2_3_3_REV */ - 1664, /* GL_UNSIGNED_SHORT_5_6_5 */ - 1665, /* GL_UNSIGNED_SHORT_5_6_5_REV */ - 1662, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */ - 1660, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */ - 1658, /* GL_UNSIGNED_INT_8_8_8_8_REV */ - 1656, /* GL_UNSIGNED_INT_2_10_10_10_REV */ - 1604, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */ - 1605, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */ - 1603, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */ - 889, /* GL_MIRRORED_REPEAT */ - 1289, /* GL_RGB_S3TC */ - 1266, /* GL_RGB4_S3TC */ - 1288, /* GL_RGBA_S3TC */ - 1283, /* GL_RGBA4_S3TC */ - 1286, /* GL_RGBA_DXT5_S3TC */ - 1281, /* GL_RGBA4_DXT5_S3TC */ - 239, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */ - 234, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */ - 235, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */ - 236, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */ - 950, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */ - 949, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */ - 642, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */ - 468, /* GL_FOG_COORDINATE_SOURCE */ - 460, /* GL_FOG_COORD */ - 484, /* GL_FRAGMENT_DEPTH */ - 280, /* GL_CURRENT_FOG_COORD */ - 467, /* GL_FOG_COORDINATE_ARRAY_TYPE */ - 466, /* GL_FOG_COORDINATE_ARRAY_STRIDE */ - 465, /* GL_FOG_COORDINATE_ARRAY_POINTER */ - 462, /* GL_FOG_COORDINATE_ARRAY */ - 174, /* GL_COLOR_SUM */ - 299, /* GL_CURRENT_SECONDARY_COLOR */ - 1326, /* GL_SECONDARY_COLOR_ARRAY_SIZE */ - 1328, /* GL_SECONDARY_COLOR_ARRAY_TYPE */ - 1327, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */ - 1325, /* GL_SECONDARY_COLOR_ARRAY_POINTER */ - 1322, /* GL_SECONDARY_COLOR_ARRAY */ - 528, /* GL_GL_CURRENT_RASTER_SECONDARY_COLOR */ - 28, /* GL_ALIASED_POINT_SIZE_RANGE */ - 27, /* GL_ALIASED_LINE_WIDTH_RANGE */ - 1442, /* GL_TEXTURE0 */ - 1444, /* GL_TEXTURE1 */ - 1466, /* GL_TEXTURE2 */ - 1488, /* GL_TEXTURE3 */ - 1494, /* GL_TEXTURE4 */ - 1496, /* GL_TEXTURE5 */ - 1498, /* GL_TEXTURE6 */ - 1500, /* GL_TEXTURE7 */ - 1502, /* GL_TEXTURE8 */ - 1504, /* GL_TEXTURE9 */ - 1445, /* GL_TEXTURE10 */ - 1447, /* GL_TEXTURE11 */ - 1449, /* GL_TEXTURE12 */ - 1451, /* GL_TEXTURE13 */ - 1453, /* GL_TEXTURE14 */ - 1455, /* GL_TEXTURE15 */ - 1457, /* GL_TEXTURE16 */ - 1459, /* GL_TEXTURE17 */ - 1461, /* GL_TEXTURE18 */ - 1463, /* GL_TEXTURE19 */ - 1467, /* GL_TEXTURE20 */ - 1469, /* GL_TEXTURE21 */ - 1471, /* GL_TEXTURE22 */ - 1473, /* GL_TEXTURE23 */ - 1475, /* GL_TEXTURE24 */ - 1477, /* GL_TEXTURE25 */ - 1479, /* GL_TEXTURE26 */ - 1481, /* GL_TEXTURE27 */ - 1483, /* GL_TEXTURE28 */ - 1485, /* GL_TEXTURE29 */ - 1489, /* GL_TEXTURE30 */ - 1491, /* GL_TEXTURE31 */ - 18, /* GL_ACTIVE_TEXTURE */ - 124, /* GL_CLIENT_ACTIVE_TEXTURE */ - 867, /* GL_MAX_TEXTURE_UNITS */ - 1630, /* GL_TRANSPOSE_MODELVIEW_MATRIX */ - 1633, /* GL_TRANSPOSE_PROJECTION_MATRIX */ - 1635, /* GL_TRANSPOSE_TEXTURE_MATRIX */ - 1627, /* GL_TRANSPOSE_COLOR_MATRIX */ - 1430, /* GL_SUBTRACT */ - 856, /* GL_MAX_RENDERBUFFER_SIZE_EXT */ - 222, /* GL_COMPRESSED_ALPHA */ - 226, /* GL_COMPRESSED_LUMINANCE */ - 227, /* GL_COMPRESSED_LUMINANCE_ALPHA */ - 224, /* GL_COMPRESSED_INTENSITY */ - 230, /* GL_COMPRESSED_RGB */ - 231, /* GL_COMPRESSED_RGBA */ - 1549, /* GL_TEXTURE_COMPRESSION_HINT */ - 1611, /* GL_TEXTURE_RECTANGLE_ARB */ - 1521, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */ - 1207, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */ - 854, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */ - 335, /* GL_DEPTH_STENCIL_NV */ - 1655, /* GL_UNSIGNED_INT_24_8_NV */ - 863, /* GL_MAX_TEXTURE_LOD_BIAS */ - 1602, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */ - 864, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ - 1578, /* GL_TEXTURE_FILTER_CONTROL */ - 1593, /* GL_TEXTURE_LOD_BIAS */ - 207, /* GL_COMBINE4 */ - 857, /* GL_MAX_SHININESS_NV */ - 858, /* GL_MAX_SPOT_EXPONENT_NV */ - 576, /* GL_INCR_WRAP */ - 310, /* GL_DECR_WRAP */ - 909, /* GL_MODELVIEW1_ARB */ - 965, /* GL_NORMAL_MAP */ - 1236, /* GL_REFLECTION_MAP */ - 1558, /* GL_TEXTURE_CUBE_MAP */ - 1519, /* GL_TEXTURE_BINDING_CUBE_MAP */ - 1566, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */ - 1560, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */ - 1568, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */ - 1562, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */ - 1570, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */ - 1564, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */ - 1205, /* GL_PROXY_TEXTURE_CUBE_MAP */ - 810, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ - 944, /* GL_MULTISAMPLE_FILTER_HINT_NV */ - 476, /* GL_FOG_DISTANCE_MODE_NV */ - 435, /* GL_EYE_RADIAL_NV */ - 434, /* GL_EYE_PLANE_ABSOLUTE_NV */ - 206, /* GL_COMBINE */ - 213, /* GL_COMBINE_RGB */ - 208, /* GL_COMBINE_ALPHA */ - 1290, /* GL_RGB_SCALE */ - 24, /* GL_ADD_SIGNED */ - 603, /* GL_INTERPOLATE */ - 241, /* GL_CONSTANT */ - 1155, /* GL_PRIMARY_COLOR */ - 1152, /* GL_PREVIOUS */ - 1356, /* GL_SOURCE0_RGB */ - 1362, /* GL_SOURCE1_RGB */ - 1368, /* GL_SOURCE2_RGB */ - 1372, /* GL_SOURCE3_RGB_NV */ - 1353, /* GL_SOURCE0_ALPHA */ - 1359, /* GL_SOURCE1_ALPHA */ - 1365, /* GL_SOURCE2_ALPHA */ - 1371, /* GL_SOURCE3_ALPHA_NV */ - 1001, /* GL_OPERAND0_RGB */ - 1007, /* GL_OPERAND1_RGB */ - 1013, /* GL_OPERAND2_RGB */ - 1017, /* GL_OPERAND3_RGB_NV */ - 998, /* GL_OPERAND0_ALPHA */ - 1004, /* GL_OPERAND1_ALPHA */ - 1010, /* GL_OPERAND2_ALPHA */ - 1016, /* GL_OPERAND3_ALPHA_NV */ - 1677, /* GL_VERTEX_ARRAY_BINDING_APPLE */ - 1741, /* GL_YCBCR_422_APPLE */ - 1666, /* GL_UNSIGNED_SHORT_8_8_APPLE */ - 1668, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */ - 1347, /* GL_SLICE_ACCUM_SUN */ - 1212, /* GL_QUAD_MESH_SUN */ - 1639, /* GL_TRIANGLE_MESH_SUN */ - 1715, /* GL_VERTEX_PROGRAM_ARB */ - 1726, /* GL_VERTEX_STATE_PROGRAM_NV */ - 1702, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */ - 1708, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */ - 1710, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */ - 1712, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */ - 301, /* GL_CURRENT_VERTEX_ATTRIB */ - 1168, /* GL_PROGRAM_LENGTH_ARB */ - 1182, /* GL_PROGRAM_STRING_ARB */ - 931, /* GL_MODELVIEW_PROJECTION_NV */ - 571, /* GL_IDENTITY_NV */ - 616, /* GL_INVERSE_NV */ - 1632, /* GL_TRANSPOSE_NV */ - 617, /* GL_INVERSE_TRANSPOSE_NV */ - 840, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */ - 839, /* GL_MAX_PROGRAM_MATRICES_ARB */ - 747, /* GL_MATRIX0_NV */ - 759, /* GL_MATRIX1_NV */ - 771, /* GL_MATRIX2_NV */ - 775, /* GL_MATRIX3_NV */ - 777, /* GL_MATRIX4_NV */ - 779, /* GL_MATRIX5_NV */ - 781, /* GL_MATRIX6_NV */ - 783, /* GL_MATRIX7_NV */ - 286, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */ - 283, /* GL_CURRENT_MATRIX_ARB */ - 1718, /* GL_VERTEX_PROGRAM_POINT_SIZE */ - 1721, /* GL_VERTEX_PROGRAM_TWO_SIDE */ - 1180, /* GL_PROGRAM_PARAMETER_NV */ - 1706, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */ - 1184, /* GL_PROGRAM_TARGET_NV */ - 1181, /* GL_PROGRAM_RESIDENT_NV */ - 1624, /* GL_TRACK_MATRIX_NV */ - 1625, /* GL_TRACK_MATRIX_TRANSFORM_NV */ - 1716, /* GL_VERTEX_PROGRAM_BINDING_NV */ - 1162, /* GL_PROGRAM_ERROR_POSITION_ARB */ - 320, /* GL_DEPTH_CLAMP_NV */ - 1684, /* GL_VERTEX_ATTRIB_ARRAY0_NV */ - 1691, /* GL_VERTEX_ATTRIB_ARRAY1_NV */ - 1692, /* GL_VERTEX_ATTRIB_ARRAY2_NV */ - 1693, /* GL_VERTEX_ATTRIB_ARRAY3_NV */ - 1694, /* GL_VERTEX_ATTRIB_ARRAY4_NV */ - 1695, /* GL_VERTEX_ATTRIB_ARRAY5_NV */ - 1696, /* GL_VERTEX_ATTRIB_ARRAY6_NV */ - 1697, /* GL_VERTEX_ATTRIB_ARRAY7_NV */ - 1698, /* GL_VERTEX_ATTRIB_ARRAY8_NV */ - 1699, /* GL_VERTEX_ATTRIB_ARRAY9_NV */ - 1685, /* GL_VERTEX_ATTRIB_ARRAY10_NV */ - 1686, /* GL_VERTEX_ATTRIB_ARRAY11_NV */ - 1687, /* GL_VERTEX_ATTRIB_ARRAY12_NV */ - 1688, /* GL_VERTEX_ATTRIB_ARRAY13_NV */ - 1689, /* GL_VERTEX_ATTRIB_ARRAY14_NV */ - 1690, /* GL_VERTEX_ATTRIB_ARRAY15_NV */ - 701, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */ - 708, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */ - 709, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */ - 710, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */ - 711, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */ - 712, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */ - 713, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */ - 714, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */ - 715, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */ - 716, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */ - 702, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */ - 703, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */ - 704, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */ - 705, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */ - 706, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */ - 707, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */ - 728, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */ - 735, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */ - 736, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */ - 737, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */ - 738, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */ - 739, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */ - 740, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */ - 1161, /* GL_PROGRAM_BINDING_ARB */ - 742, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */ - 743, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */ - 729, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */ - 730, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */ - 731, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */ - 732, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */ - 733, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */ - 734, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */ - 1547, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */ - 1544, /* GL_TEXTURE_COMPRESSED */ - 970, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */ - 240, /* GL_COMPRESSED_TEXTURE_FORMATS */ - 879, /* GL_MAX_VERTEX_UNITS_ARB */ - 22, /* GL_ACTIVE_VERTEX_UNITS_ARB */ - 1736, /* GL_WEIGHT_SUM_UNITY_ARB */ - 1714, /* GL_VERTEX_BLEND_ARB */ - 303, /* GL_CURRENT_WEIGHT_ARB */ - 1735, /* GL_WEIGHT_ARRAY_TYPE_ARB */ - 1734, /* GL_WEIGHT_ARRAY_STRIDE_ARB */ - 1733, /* GL_WEIGHT_ARRAY_SIZE_ARB */ - 1732, /* GL_WEIGHT_ARRAY_POINTER_ARB */ - 1729, /* GL_WEIGHT_ARRAY_ARB */ - 346, /* GL_DOT3_RGB */ - 347, /* GL_DOT3_RGBA */ - 238, /* GL_COMPRESSED_RGB_FXT1_3DFX */ - 233, /* GL_COMPRESSED_RGBA_FXT1_3DFX */ - 939, /* GL_MULTISAMPLE_3DFX */ - 1311, /* GL_SAMPLE_BUFFERS_3DFX */ - 1302, /* GL_SAMPLES_3DFX */ - 920, /* GL_MODELVIEW2_ARB */ - 923, /* GL_MODELVIEW3_ARB */ - 924, /* GL_MODELVIEW4_ARB */ - 925, /* GL_MODELVIEW5_ARB */ - 926, /* GL_MODELVIEW6_ARB */ - 927, /* GL_MODELVIEW7_ARB */ - 928, /* GL_MODELVIEW8_ARB */ - 929, /* GL_MODELVIEW9_ARB */ - 899, /* GL_MODELVIEW10_ARB */ - 900, /* GL_MODELVIEW11_ARB */ - 901, /* GL_MODELVIEW12_ARB */ - 902, /* GL_MODELVIEW13_ARB */ - 903, /* GL_MODELVIEW14_ARB */ - 904, /* GL_MODELVIEW15_ARB */ - 905, /* GL_MODELVIEW16_ARB */ - 906, /* GL_MODELVIEW17_ARB */ - 907, /* GL_MODELVIEW18_ARB */ - 908, /* GL_MODELVIEW19_ARB */ - 910, /* GL_MODELVIEW20_ARB */ - 911, /* GL_MODELVIEW21_ARB */ - 912, /* GL_MODELVIEW22_ARB */ - 913, /* GL_MODELVIEW23_ARB */ - 914, /* GL_MODELVIEW24_ARB */ - 915, /* GL_MODELVIEW25_ARB */ - 916, /* GL_MODELVIEW26_ARB */ - 917, /* GL_MODELVIEW27_ARB */ - 918, /* GL_MODELVIEW28_ARB */ - 919, /* GL_MODELVIEW29_ARB */ - 921, /* GL_MODELVIEW30_ARB */ - 922, /* GL_MODELVIEW31_ARB */ - 351, /* GL_DOT3_RGB_EXT */ - 349, /* GL_DOT3_RGBA_EXT */ - 893, /* GL_MIRROR_CLAMP_EXT */ - 896, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */ - 934, /* GL_MODULATE_ADD_ATI */ - 935, /* GL_MODULATE_SIGNED_ADD_ATI */ - 936, /* GL_MODULATE_SUBTRACT_ATI */ - 1742, /* GL_YCBCR_MESA */ - 1025, /* GL_PACK_INVERT_MESA */ - 306, /* GL_DEBUG_OBJECT_MESA */ - 307, /* GL_DEBUG_PRINT_MESA */ - 305, /* GL_DEBUG_ASSERT_MESA */ - 107, /* GL_BUFFER_SIZE */ - 109, /* GL_BUFFER_USAGE */ - 1398, /* GL_STENCIL_BACK_FUNC */ - 1397, /* GL_STENCIL_BACK_FAIL */ - 1399, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */ - 1400, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */ - 485, /* GL_FRAGMENT_PROGRAM_ARB */ - 1159, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */ - 1187, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */ - 1186, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */ - 1171, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - 1177, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - 1176, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - 829, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */ - 852, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */ - 851, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */ - 842, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - 848, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - 847, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - 812, /* GL_MAX_DRAW_BUFFERS */ - 355, /* GL_DRAW_BUFFER0 */ - 358, /* GL_DRAW_BUFFER1 */ - 379, /* GL_DRAW_BUFFER2 */ - 382, /* GL_DRAW_BUFFER3 */ - 385, /* GL_DRAW_BUFFER4 */ - 388, /* GL_DRAW_BUFFER5 */ - 391, /* GL_DRAW_BUFFER6 */ - 394, /* GL_DRAW_BUFFER7 */ - 397, /* GL_DRAW_BUFFER8 */ - 400, /* GL_DRAW_BUFFER9 */ - 359, /* GL_DRAW_BUFFER10 */ - 362, /* GL_DRAW_BUFFER11 */ - 365, /* GL_DRAW_BUFFER12 */ - 368, /* GL_DRAW_BUFFER13 */ - 371, /* GL_DRAW_BUFFER14 */ - 374, /* GL_DRAW_BUFFER15 */ - 82, /* GL_BLEND_EQUATION_ALPHA */ - 792, /* GL_MATRIX_PALETTE_ARB */ - 823, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */ - 826, /* GL_MAX_PALETTE_MATRICES_ARB */ - 289, /* GL_CURRENT_PALETTE_MATRIX_ARB */ - 786, /* GL_MATRIX_INDEX_ARRAY_ARB */ - 284, /* GL_CURRENT_MATRIX_INDEX_ARB */ - 788, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */ - 790, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */ - 789, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */ - 787, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */ - 1573, /* GL_TEXTURE_DEPTH_SIZE */ - 339, /* GL_DEPTH_TEXTURE_MODE */ - 1539, /* GL_TEXTURE_COMPARE_MODE */ - 1537, /* GL_TEXTURE_COMPARE_FUNC */ - 217, /* GL_COMPARE_R_TO_TEXTURE */ - 1093, /* GL_POINT_SPRITE */ - 266, /* GL_COORD_REPLACE */ - 1097, /* GL_POINT_SPRITE_R_MODE_NV */ - 1214, /* GL_QUERY_COUNTER_BITS */ - 291, /* GL_CURRENT_QUERY */ - 1216, /* GL_QUERY_RESULT */ - 1218, /* GL_QUERY_RESULT_AVAILABLE */ - 873, /* GL_MAX_VERTEX_ATTRIBS */ - 1704, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */ - 337, /* GL_DEPTH_STENCIL_TO_RGBA_NV */ - 336, /* GL_DEPTH_STENCIL_TO_BGRA_NV */ - 859, /* GL_MAX_TEXTURE_COORDS */ - 861, /* GL_MAX_TEXTURE_IMAGE_UNITS */ - 1164, /* GL_PROGRAM_ERROR_STRING_ARB */ - 1166, /* GL_PROGRAM_FORMAT_ASCII_ARB */ - 1165, /* GL_PROGRAM_FORMAT_ARB */ - 1618, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */ - 318, /* GL_DEPTH_BOUNDS_TEST_EXT */ - 317, /* GL_DEPTH_BOUNDS_EXT */ - 52, /* GL_ARRAY_BUFFER */ - 420, /* GL_ELEMENT_ARRAY_BUFFER */ - 54, /* GL_ARRAY_BUFFER_BINDING */ - 422, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */ - 1678, /* GL_VERTEX_ARRAY_BUFFER_BINDING */ - 960, /* GL_NORMAL_ARRAY_BUFFER_BINDING */ - 140, /* GL_COLOR_ARRAY_BUFFER_BINDING */ - 579, /* GL_INDEX_ARRAY_BUFFER_BINDING */ - 1552, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */ - 416, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */ - 1323, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */ - 463, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */ - 1730, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */ - 1700, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */ - 1167, /* GL_PROGRAM_INSTRUCTIONS_ARB */ - 835, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */ - 1173, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - 844, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - 1185, /* GL_PROGRAM_TEMPORARIES_ARB */ - 850, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ - 1175, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */ - 846, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */ - 1179, /* GL_PROGRAM_PARAMETERS_ARB */ - 849, /* GL_MAX_PROGRAM_PARAMETERS_ARB */ - 1174, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */ - 845, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */ - 1160, /* GL_PROGRAM_ATTRIBS_ARB */ - 830, /* GL_MAX_PROGRAM_ATTRIBS_ARB */ - 1172, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */ - 843, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */ - 1158, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */ - 828, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */ - 1170, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - 841, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - 836, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */ - 832, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */ - 1188, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */ - 1629, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */ - 1226, /* GL_READ_ONLY */ - 1738, /* GL_WRITE_ONLY */ - 1228, /* GL_READ_WRITE */ - 101, /* GL_BUFFER_ACCESS */ - 103, /* GL_BUFFER_MAPPED */ - 105, /* GL_BUFFER_MAP_POINTER */ - 1623, /* GL_TIME_ELAPSED_EXT */ - 746, /* GL_MATRIX0_ARB */ - 758, /* GL_MATRIX1_ARB */ - 770, /* GL_MATRIX2_ARB */ - 774, /* GL_MATRIX3_ARB */ - 776, /* GL_MATRIX4_ARB */ - 778, /* GL_MATRIX5_ARB */ - 780, /* GL_MATRIX6_ARB */ - 782, /* GL_MATRIX7_ARB */ - 784, /* GL_MATRIX8_ARB */ - 785, /* GL_MATRIX9_ARB */ - 748, /* GL_MATRIX10_ARB */ - 749, /* GL_MATRIX11_ARB */ - 750, /* GL_MATRIX12_ARB */ - 751, /* GL_MATRIX13_ARB */ - 752, /* GL_MATRIX14_ARB */ - 753, /* GL_MATRIX15_ARB */ - 754, /* GL_MATRIX16_ARB */ - 755, /* GL_MATRIX17_ARB */ - 756, /* GL_MATRIX18_ARB */ - 757, /* GL_MATRIX19_ARB */ - 760, /* GL_MATRIX20_ARB */ - 761, /* GL_MATRIX21_ARB */ - 762, /* GL_MATRIX22_ARB */ - 763, /* GL_MATRIX23_ARB */ - 764, /* GL_MATRIX24_ARB */ - 765, /* GL_MATRIX25_ARB */ - 766, /* GL_MATRIX26_ARB */ - 767, /* GL_MATRIX27_ARB */ - 768, /* GL_MATRIX28_ARB */ - 769, /* GL_MATRIX29_ARB */ - 772, /* GL_MATRIX30_ARB */ - 773, /* GL_MATRIX31_ARB */ - 1425, /* GL_STREAM_DRAW */ - 1427, /* GL_STREAM_READ */ - 1423, /* GL_STREAM_COPY */ - 1391, /* GL_STATIC_DRAW */ - 1393, /* GL_STATIC_READ */ - 1389, /* GL_STATIC_COPY */ - 410, /* GL_DYNAMIC_DRAW */ - 412, /* GL_DYNAMIC_READ */ - 408, /* GL_DYNAMIC_COPY */ - 535, /* GL_GL_PIXEL_PACK_BUFFER */ - 537, /* GL_GL_PIXEL_UNPACK_BUFFER */ - 536, /* GL_GL_PIXEL_PACK_BUFFER_BINDING */ - 538, /* GL_GL_PIXEL_UNPACK_BUFFER_BINDING */ - 833, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ - 831, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */ - 834, /* GL_MAX_PROGRAM_IF_DEPTH_NV */ - 838, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */ - 837, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */ - 795, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */ - 1419, /* GL_STENCIL_TEST_TWO_SIDE_EXT */ - 17, /* GL_ACTIVE_STENCIL_FACE_EXT */ - 894, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */ - 1304, /* GL_SAMPLES_PASSED */ - 486, /* GL_FRAGMENT_SHADER */ - 1724, /* GL_VERTEX_SHADER */ - 1178, /* GL_PROGRAM_OBJECT_ARB */ - 1336, /* GL_SHADER_OBJECT_ARB */ - 819, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */ - 877, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */ - 871, /* GL_MAX_VARYING_FLOATS */ - 875, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */ - 804, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ - 985, /* GL_OBJECT_TYPE_ARB */ - 1338, /* GL_SHADER_TYPE */ - 451, /* GL_FLOAT_VEC2 */ - 453, /* GL_FLOAT_VEC3 */ - 455, /* GL_FLOAT_VEC4 */ - 606, /* GL_INT_VEC2 */ - 608, /* GL_INT_VEC3 */ - 610, /* GL_INT_VEC4 */ - 93, /* GL_BOOL */ - 95, /* GL_BOOL_VEC2 */ - 97, /* GL_BOOL_VEC3 */ - 99, /* GL_BOOL_VEC4 */ - 445, /* GL_FLOAT_MAT2 */ - 447, /* GL_FLOAT_MAT3 */ - 449, /* GL_FLOAT_MAT4 */ - 1295, /* GL_SAMPLER_1D */ - 1297, /* GL_SAMPLER_2D */ - 1299, /* GL_SAMPLER_3D */ - 1300, /* GL_SAMPLER_CUBE */ - 1296, /* GL_SAMPLER_1D_SHADOW */ - 1298, /* GL_SAMPLER_2D_SHADOW */ - 529, /* GL_GL_FLOAT_MAT2x3 */ - 530, /* GL_GL_FLOAT_MAT2x4 */ - 531, /* GL_GL_FLOAT_MAT3x2 */ - 532, /* GL_GL_FLOAT_MAT3x4 */ - 533, /* GL_GL_FLOAT_MAT4x2 */ - 534, /* GL_GL_FLOAT_MAT4x3 */ - 312, /* GL_DELETE_STATUS */ - 221, /* GL_COMPILE_STATUS */ - 659, /* GL_LINK_STATUS */ - 1673, /* GL_VALIDATE_STATUS */ - 591, /* GL_INFO_LOG_LENGTH */ - 56, /* GL_ATTACHED_SHADERS */ - 20, /* GL_ACTIVE_UNIFORMS */ - 21, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */ - 1337, /* GL_SHADER_SOURCE_LENGTH */ - 15, /* GL_ACTIVE_ATTRIBUTES */ - 16, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */ - 488, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */ - 1340, /* GL_SHADING_LANGUAGE_VERSION */ - 290, /* GL_CURRENT_PROGRAM */ - 1034, /* GL_PALETTE4_RGB8_OES */ - 1036, /* GL_PALETTE4_RGBA8_OES */ - 1032, /* GL_PALETTE4_R5_G6_B5_OES */ - 1035, /* GL_PALETTE4_RGBA4_OES */ - 1033, /* GL_PALETTE4_RGB5_A1_OES */ - 1039, /* GL_PALETTE8_RGB8_OES */ - 1041, /* GL_PALETTE8_RGBA8_OES */ - 1037, /* GL_PALETTE8_R5_G6_B5_OES */ - 1040, /* GL_PALETTE8_RGBA4_OES */ - 1038, /* GL_PALETTE8_RGB5_A1_OES */ - 574, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */ - 573, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */ - 1507, /* GL_TEXTURE_1D_ARRAY_EXT */ - 1198, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */ - 1509, /* GL_TEXTURE_2D_ARRAY_EXT */ - 1201, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */ - 1515, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */ - 1517, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */ - 543, /* GL_GL_SRGB */ - 544, /* GL_GL_SRGB8 */ - 546, /* GL_GL_SRGB_ALPHA */ - 545, /* GL_GL_SRGB8_ALPHA8 */ - 542, /* GL_GL_SLUMINANCE_ALPHA */ - 541, /* GL_GL_SLUMINANCE8_ALPHA8 */ - 539, /* GL_GL_SLUMINANCE */ - 540, /* GL_GL_SLUMINANCE8 */ - 526, /* GL_GL_COMPRESSED_SRGB */ - 527, /* GL_GL_COMPRESSED_SRGB_ALPHA */ - 524, /* GL_GL_COMPRESSED_SLUMINANCE */ - 525, /* GL_GL_COMPRESSED_SLUMINANCE_ALPHA */ - 1095, /* GL_POINT_SPRITE_COORD_ORIGIN */ - 667, /* GL_LOWER_LEFT */ - 1670, /* GL_UPPER_LEFT */ - 1401, /* GL_STENCIL_BACK_REF */ - 1402, /* GL_STENCIL_BACK_VALUE_MASK */ - 1403, /* GL_STENCIL_BACK_WRITEMASK */ - 403, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */ - 1240, /* GL_RENDERBUFFER_BINDING_EXT */ - 1225, /* GL_READ_FRAMEBUFFER_EXT */ - 404, /* GL_DRAW_FRAMEBUFFER_EXT */ - 1224, /* GL_READ_FRAMEBUFFER_BINDING_EXT */ - 490, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */ - 489, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */ - 494, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */ - 492, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */ - 491, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */ - 496, /* GL_FRAMEBUFFER_COMPLETE_EXT */ - 498, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */ - 503, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */ - 501, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */ - 499, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */ - 502, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */ - 500, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */ - 504, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */ - 506, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */ - 505, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */ - 801, /* GL_MAX_COLOR_ATTACHMENTS_EXT */ - 146, /* GL_COLOR_ATTACHMENT0_EXT */ - 153, /* GL_COLOR_ATTACHMENT1_EXT */ - 154, /* GL_COLOR_ATTACHMENT2_EXT */ - 155, /* GL_COLOR_ATTACHMENT3_EXT */ - 156, /* GL_COLOR_ATTACHMENT4_EXT */ - 157, /* GL_COLOR_ATTACHMENT5_EXT */ - 158, /* GL_COLOR_ATTACHMENT6_EXT */ - 159, /* GL_COLOR_ATTACHMENT7_EXT */ - 160, /* GL_COLOR_ATTACHMENT8_EXT */ - 161, /* GL_COLOR_ATTACHMENT9_EXT */ - 147, /* GL_COLOR_ATTACHMENT10_EXT */ - 148, /* GL_COLOR_ATTACHMENT11_EXT */ - 149, /* GL_COLOR_ATTACHMENT12_EXT */ - 150, /* GL_COLOR_ATTACHMENT13_EXT */ - 151, /* GL_COLOR_ATTACHMENT14_EXT */ - 152, /* GL_COLOR_ATTACHMENT15_EXT */ - 314, /* GL_DEPTH_ATTACHMENT_EXT */ - 1396, /* GL_STENCIL_ATTACHMENT_EXT */ - 497, /* GL_FRAMEBUFFER_EXT */ - 1241, /* GL_RENDERBUFFER_EXT */ - 1244, /* GL_RENDERBUFFER_WIDTH_EXT */ - 1242, /* GL_RENDERBUFFER_HEIGHT_EXT */ - 1243, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */ - 1414, /* GL_STENCIL_INDEX_EXT */ - 1411, /* GL_STENCIL_INDEX1_EXT */ - 1412, /* GL_STENCIL_INDEX4_EXT */ - 1413, /* GL_STENCIL_INDEX8_EXT */ - 1410, /* GL_STENCIL_INDEX16_EXT */ - 428, /* GL_EVAL_BIT */ - 1222, /* GL_RASTER_POSITION_UNCLIPPED_IBM */ - 661, /* GL_LIST_BIT */ - 1523, /* GL_TEXTURE_BIT */ - 1319, /* GL_SCISSOR_BIT */ - 29, /* GL_ALL_ATTRIB_BITS */ - 941, /* GL_MULTISAMPLE_BIT */ - 30, /* GL_ALL_CLIENT_ATTRIB_BITS */ -}; - -#define Elements(x) sizeof(x)/sizeof(*x) - -typedef int (*cfunc)(const void *, const void *); - -/** - * Compare a key name to an element in the \c all_enums array. - * - * \c bsearch always passes the key as the first parameter and the pointer - * to the array element as the second parameter. We can elimiate some - * extra work by taking advantage of that fact. - * - * \param a Pointer to the desired enum name. - * \param b Pointer to an element of the \c all_enums array. - */ -static int compar_name( const char *a, const enum_elt *b ) -{ - return _mesa_strcmp( a, & enum_string_table[ b->offset ] ); -} - -/** - * Compare a key enum value to an element in the \c all_enums array. - * - * \c bsearch always passes the key as the first parameter and the pointer - * to the array element as the second parameter. We can elimiate some - * extra work by taking advantage of that fact. - * - * \param a Pointer to the desired enum name. - * \param b Pointer to an index into the \c all_enums array. - */ -static int compar_nr( const int *a, const unsigned *b ) -{ - return a[0] - all_enums[*b].n; -} - - -static char token_tmp[20]; - -const char *_mesa_lookup_enum_by_nr( int nr ) -{ - unsigned * i; - - i = (unsigned *)bsearch( & nr, reduced_enums, Elements(reduced_enums), - sizeof(reduced_enums[0]), (cfunc) compar_nr ); - - if ( i != NULL ) { - return & enum_string_table[ all_enums[ *i ].offset ]; - } - else { - /* this is not re-entrant safe, no big deal here */ - _mesa_sprintf(token_tmp, "0x%x", nr); - return token_tmp; - } -} - -int _mesa_lookup_enum_by_name( const char *symbol ) -{ - enum_elt * f = NULL; - - if ( symbol != NULL ) { - f = (enum_elt *)bsearch( symbol, all_enums, Elements(all_enums), - sizeof( enum_elt ), (cfunc) compar_name ); - } - - return (f != NULL) ? f->n : -1; -} - - diff --git a/target-i386/mesa_get.c b/target-i386/mesa_get.c deleted file mode 100644 index 0867859..0000000 --- a/target-i386/mesa_get.c +++ /dev/null @@ -1,5563 +0,0 @@ - -/*** - *** NOTE!!! DO NOT EDIT THIS FILE!!! IT IS GENERATED BY get_gen.py - ***/ - -#include "glheader.h" -#include "context.h" -#include "enable.h" -#include "extensions.h" -#include "fbobject.h" -#include "get.h" -#include "macros.h" -#include "mtypes.h" -#include "state.h" -#include "texcompress.h" - - -#define FLOAT_TO_BOOLEAN(X) ( (X) ? GL_TRUE : GL_FALSE ) - -#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE ) - -#define ENUM_TO_BOOLEAN(E) ( (E) ? GL_TRUE : GL_FALSE ) -#define ENUM_TO_INT(E) ( (GLint) (E) ) -#define ENUM_TO_FLOAT(E) ( (GLfloat) (E) ) - -#define BOOLEAN_TO_INT(B) ( (GLint) (B) ) -#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F ) - - -/* - * Check if named extension is enabled, if not generate error and return. - */ -#define CHECK_EXT1(EXT1, FUNC) \ - if (!ctx->Extensions.EXT1) { \ - _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \ - return; \ - } - -/* - * Check if either of two extensions is enabled. - */ -#define CHECK_EXT2(EXT1, EXT2, FUNC) \ - if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \ - _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \ - return; \ - } - -/* - * Check if either of three extensions is enabled. - */ -#define CHECK_EXT3(EXT1, EXT2, EXT3, FUNC) \ - if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \ - !ctx->Extensions.EXT3) { \ - _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \ - return; \ - } - -/* - * Check if either of four extensions is enabled. - */ -#define CHECK_EXT4(EXT1, EXT2, EXT3, EXT4, FUNC) \ - if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \ - !ctx->Extensions.EXT3 && !ctx->Extensions.EXT4) { \ - _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \ - return; \ - } - - -void GLAPIENTRY -_mesa_GetBooleanv( GLenum pname, GLboolean *params ) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (!params) - return; - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (ctx->Driver.GetBooleanv && - ctx->Driver.GetBooleanv(ctx, pname, params)) - return; - - switch (pname) { - case GL_ACCUM_RED_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumRedBits); - break; - case GL_ACCUM_GREEN_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumGreenBits); - break; - case GL_ACCUM_BLUE_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumBlueBits); - break; - case GL_ACCUM_ALPHA_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumAlphaBits); - break; - case GL_ACCUM_CLEAR_VALUE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[3]); - break; - case GL_ALPHA_BIAS: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaBias); - break; - case GL_ALPHA_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.alphaBits); - break; - case GL_ALPHA_SCALE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaScale); - break; - case GL_ALPHA_TEST: - params[0] = ctx->Color.AlphaEnabled; - break; - case GL_ALPHA_TEST_FUNC: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.AlphaFunc); - break; - case GL_ALPHA_TEST_REF: - params[0] = FLOAT_TO_BOOLEAN(ctx->Color.AlphaRef); - break; - case GL_ATTRIB_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(ctx->AttribStackDepth); - break; - case GL_AUTO_NORMAL: - params[0] = ctx->Eval.AutoNormal; - break; - case GL_AUX_BUFFERS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.numAuxBuffers); - break; - case GL_BLEND: - params[0] = ctx->Color.BlendEnabled; - break; - case GL_BLEND_DST: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstRGB); - break; - case GL_BLEND_SRC: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendSrcRGB); - break; - case GL_BLEND_SRC_RGB_EXT: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendSrcRGB); - break; - case GL_BLEND_DST_RGB_EXT: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstRGB); - break; - case GL_BLEND_SRC_ALPHA_EXT: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendSrcA); - break; - case GL_BLEND_DST_ALPHA_EXT: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstA); - break; - case GL_BLEND_EQUATION: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendEquationRGB ); - break; - case GL_BLEND_EQUATION_ALPHA_EXT: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendEquationA ); - break; - case GL_BLEND_COLOR_EXT: - params[0] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Color.BlendColor[3]); - break; - case GL_BLUE_BIAS: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueBias); - break; - case GL_BLUE_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.blueBits); - break; - case GL_BLUE_SCALE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueScale); - break; - case GL_CLIENT_ATTRIB_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(ctx->ClientAttribStackDepth); - break; - case GL_CLIP_PLANE0: - params[0] = (ctx->Transform.ClipPlanesEnabled >> 0) & 1; - break; - case GL_CLIP_PLANE1: - params[0] = (ctx->Transform.ClipPlanesEnabled >> 1) & 1; - break; - case GL_CLIP_PLANE2: - params[0] = (ctx->Transform.ClipPlanesEnabled >> 2) & 1; - break; - case GL_CLIP_PLANE3: - params[0] = (ctx->Transform.ClipPlanesEnabled >> 3) & 1; - break; - case GL_CLIP_PLANE4: - params[0] = (ctx->Transform.ClipPlanesEnabled >> 4) & 1; - break; - case GL_CLIP_PLANE5: - params[0] = (ctx->Transform.ClipPlanesEnabled >> 5) & 1; - break; - case GL_COLOR_CLEAR_VALUE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Color.ClearColor[3]); - break; - case GL_COLOR_MATERIAL: - params[0] = ctx->Light.ColorMaterialEnabled; - break; - case GL_COLOR_MATERIAL_FACE: - params[0] = ENUM_TO_BOOLEAN(ctx->Light.ColorMaterialFace); - break; - case GL_COLOR_MATERIAL_PARAMETER: - params[0] = ENUM_TO_BOOLEAN(ctx->Light.ColorMaterialMode); - break; - case GL_COLOR_WRITEMASK: - params[0] = INT_TO_BOOLEAN(ctx->Color.ColorMask[RCOMP] ? 1 : 0); - params[1] = INT_TO_BOOLEAN(ctx->Color.ColorMask[GCOMP] ? 1 : 0); - params[2] = INT_TO_BOOLEAN(ctx->Color.ColorMask[BCOMP] ? 1 : 0); - params[3] = INT_TO_BOOLEAN(ctx->Color.ColorMask[ACOMP] ? 1 : 0); - break; - case GL_CULL_FACE: - params[0] = ctx->Polygon.CullFlag; - break; - case GL_CULL_FACE_MODE: - params[0] = ENUM_TO_BOOLEAN(ctx->Polygon.CullFaceMode); - break; - case GL_CURRENT_COLOR: - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]); - } - break; - case GL_CURRENT_INDEX: - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]); - } - break; - case GL_CURRENT_NORMAL: - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]); - } - break; - case GL_CURRENT_RASTER_COLOR: - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterColor[3]); - break; - case GL_CURRENT_RASTER_DISTANCE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterDistance); - break; - case GL_CURRENT_RASTER_INDEX: - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterIndex); - break; - case GL_CURRENT_RASTER_POSITION: - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterPos[3]); - break; - case GL_CURRENT_RASTER_SECONDARY_COLOR: - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterSecondaryColor[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterSecondaryColor[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterSecondaryColor[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterSecondaryColor[3]); - break; - case GL_CURRENT_RASTER_TEXTURE_COORDS: - { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][3]); - } - break; - case GL_CURRENT_RASTER_POSITION_VALID: - params[0] = ctx->Current.RasterPosValid; - break; - case GL_CURRENT_TEXTURE_COORDS: - { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]); - } - break; - case GL_DEPTH_BIAS: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.DepthBias); - break; - case GL_DEPTH_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.depthBits); - break; - case GL_DEPTH_CLEAR_VALUE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Depth.Clear); - break; - case GL_DEPTH_FUNC: - params[0] = ENUM_TO_BOOLEAN(ctx->Depth.Func); - break; - case GL_DEPTH_RANGE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Viewport.Near); - params[1] = FLOAT_TO_BOOLEAN(ctx->Viewport.Far); - break; - case GL_DEPTH_SCALE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.DepthScale); - break; - case GL_DEPTH_TEST: - params[0] = ctx->Depth.Test; - break; - case GL_DEPTH_WRITEMASK: - params[0] = ctx->Depth.Mask; - break; - case GL_DITHER: - params[0] = ctx->Color.DitherFlag; - break; - case GL_DOUBLEBUFFER: - params[0] = ctx->DrawBuffer->Visual.doubleBufferMode; - break; - case GL_DRAW_BUFFER: - params[0] = ENUM_TO_BOOLEAN(ctx->DrawBuffer->ColorDrawBuffer[0]); - break; - case GL_EDGE_FLAG: - { - FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.EdgeFlag; - } - break; - case GL_FEEDBACK_BUFFER_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Feedback.BufferSize); - break; - case GL_FEEDBACK_BUFFER_TYPE: - params[0] = ENUM_TO_BOOLEAN(ctx->Feedback.Type); - break; - case GL_FOG: - params[0] = ctx->Fog.Enabled; - break; - case GL_FOG_COLOR: - params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Fog.Color[3]); - break; - case GL_FOG_DENSITY: - params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Density); - break; - case GL_FOG_END: - params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.End); - break; - case GL_FOG_HINT: - params[0] = ENUM_TO_BOOLEAN(ctx->Hint.Fog); - break; - case GL_FOG_INDEX: - params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Index); - break; - case GL_FOG_MODE: - params[0] = ENUM_TO_BOOLEAN(ctx->Fog.Mode); - break; - case GL_FOG_START: - params[0] = FLOAT_TO_BOOLEAN(ctx->Fog.Start); - break; - case GL_FRONT_FACE: - params[0] = ENUM_TO_BOOLEAN(ctx->Polygon.FrontFace); - break; - case GL_GREEN_BIAS: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenBias); - break; - case GL_GREEN_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.greenBits); - break; - case GL_GREEN_SCALE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenScale); - break; - case GL_INDEX_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.indexBits); - break; - case GL_INDEX_CLEAR_VALUE: - params[0] = INT_TO_BOOLEAN(ctx->Color.ClearIndex); - break; - case GL_INDEX_MODE: - params[0] = !ctx->DrawBuffer->Visual.rgbMode; - break; - case GL_INDEX_OFFSET: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.IndexOffset); - break; - case GL_INDEX_SHIFT: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.IndexShift); - break; - case GL_INDEX_WRITEMASK: - params[0] = INT_TO_BOOLEAN(ctx->Color.IndexMask); - break; - case GL_LIGHT0: - params[0] = ctx->Light.Light[0].Enabled; - break; - case GL_LIGHT1: - params[0] = ctx->Light.Light[1].Enabled; - break; - case GL_LIGHT2: - params[0] = ctx->Light.Light[2].Enabled; - break; - case GL_LIGHT3: - params[0] = ctx->Light.Light[3].Enabled; - break; - case GL_LIGHT4: - params[0] = ctx->Light.Light[4].Enabled; - break; - case GL_LIGHT5: - params[0] = ctx->Light.Light[5].Enabled; - break; - case GL_LIGHT6: - params[0] = ctx->Light.Light[6].Enabled; - break; - case GL_LIGHT7: - params[0] = ctx->Light.Light[7].Enabled; - break; - case GL_LIGHTING: - params[0] = ctx->Light.Enabled; - break; - case GL_LIGHT_MODEL_AMBIENT: - params[0] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Light.Model.Ambient[3]); - break; - case GL_LIGHT_MODEL_COLOR_CONTROL: - params[0] = ENUM_TO_BOOLEAN(ctx->Light.Model.ColorControl); - break; - case GL_LIGHT_MODEL_LOCAL_VIEWER: - params[0] = ctx->Light.Model.LocalViewer; - break; - case GL_LIGHT_MODEL_TWO_SIDE: - params[0] = ctx->Light.Model.TwoSide; - break; - case GL_LINE_SMOOTH: - params[0] = ctx->Line.SmoothFlag; - break; - case GL_LINE_SMOOTH_HINT: - params[0] = ENUM_TO_BOOLEAN(ctx->Hint.LineSmooth); - break; - case GL_LINE_STIPPLE: - params[0] = ctx->Line.StippleFlag; - break; - case GL_LINE_STIPPLE_PATTERN: - params[0] = INT_TO_BOOLEAN(ctx->Line.StipplePattern); - break; - case GL_LINE_STIPPLE_REPEAT: - params[0] = INT_TO_BOOLEAN(ctx->Line.StippleFactor); - break; - case GL_LINE_WIDTH: - params[0] = FLOAT_TO_BOOLEAN(ctx->Line.Width); - break; - case GL_LINE_WIDTH_GRANULARITY: - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.LineWidthGranularity); - break; - case GL_LINE_WIDTH_RANGE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinLineWidthAA); - params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxLineWidthAA); - break; - case GL_ALIASED_LINE_WIDTH_RANGE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinLineWidth); - params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxLineWidth); - break; - case GL_LIST_BASE: - params[0] = INT_TO_BOOLEAN(ctx->List.ListBase); - break; - case GL_LIST_INDEX: - params[0] = INT_TO_BOOLEAN(ctx->ListState.CurrentListNum); - break; - case GL_LIST_MODE: - { - GLenum mode; - if (!ctx->CompileFlag) - mode = 0; - else if (ctx->ExecuteFlag) - mode = GL_COMPILE_AND_EXECUTE; - else - mode = GL_COMPILE; - params[0] = ENUM_TO_BOOLEAN(mode); - } - break; - case GL_INDEX_LOGIC_OP: - params[0] = ctx->Color.IndexLogicOpEnabled; - break; - case GL_COLOR_LOGIC_OP: - params[0] = ctx->Color.ColorLogicOpEnabled; - break; - case GL_LOGIC_OP_MODE: - params[0] = ENUM_TO_BOOLEAN(ctx->Color.LogicOp); - break; - case GL_MAP1_COLOR_4: - params[0] = ctx->Eval.Map1Color4; - break; - case GL_MAP1_GRID_DOMAIN: - params[0] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid1u1); - params[1] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid1u2); - break; - case GL_MAP1_GRID_SEGMENTS: - params[0] = INT_TO_BOOLEAN(ctx->Eval.MapGrid1un); - break; - case GL_MAP1_INDEX: - params[0] = ctx->Eval.Map1Index; - break; - case GL_MAP1_NORMAL: - params[0] = ctx->Eval.Map1Normal; - break; - case GL_MAP1_TEXTURE_COORD_1: - params[0] = ctx->Eval.Map1TextureCoord1; - break; - case GL_MAP1_TEXTURE_COORD_2: - params[0] = ctx->Eval.Map1TextureCoord2; - break; - case GL_MAP1_TEXTURE_COORD_3: - params[0] = ctx->Eval.Map1TextureCoord3; - break; - case GL_MAP1_TEXTURE_COORD_4: - params[0] = ctx->Eval.Map1TextureCoord4; - break; - case GL_MAP1_VERTEX_3: - params[0] = ctx->Eval.Map1Vertex3; - break; - case GL_MAP1_VERTEX_4: - params[0] = ctx->Eval.Map1Vertex4; - break; - case GL_MAP2_COLOR_4: - params[0] = ctx->Eval.Map2Color4; - break; - case GL_MAP2_GRID_DOMAIN: - params[0] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2u1); - params[1] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2u2); - params[2] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2v1); - params[3] = FLOAT_TO_BOOLEAN(ctx->Eval.MapGrid2v2); - break; - case GL_MAP2_GRID_SEGMENTS: - params[0] = INT_TO_BOOLEAN(ctx->Eval.MapGrid2un); - params[1] = INT_TO_BOOLEAN(ctx->Eval.MapGrid2vn); - break; - case GL_MAP2_INDEX: - params[0] = ctx->Eval.Map2Index; - break; - case GL_MAP2_NORMAL: - params[0] = ctx->Eval.Map2Normal; - break; - case GL_MAP2_TEXTURE_COORD_1: - params[0] = ctx->Eval.Map2TextureCoord1; - break; - case GL_MAP2_TEXTURE_COORD_2: - params[0] = ctx->Eval.Map2TextureCoord2; - break; - case GL_MAP2_TEXTURE_COORD_3: - params[0] = ctx->Eval.Map2TextureCoord3; - break; - case GL_MAP2_TEXTURE_COORD_4: - params[0] = ctx->Eval.Map2TextureCoord4; - break; - case GL_MAP2_VERTEX_3: - params[0] = ctx->Eval.Map2Vertex3; - break; - case GL_MAP2_VERTEX_4: - params[0] = ctx->Eval.Map2Vertex4; - break; - case GL_MAP_COLOR: - params[0] = ctx->Pixel.MapColorFlag; - break; - case GL_MAP_STENCIL: - params[0] = ctx->Pixel.MapStencilFlag; - break; - case GL_MATRIX_MODE: - params[0] = ENUM_TO_BOOLEAN(ctx->Transform.MatrixMode); - break; - case GL_MAX_ATTRIB_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(MAX_ATTRIB_STACK_DEPTH); - break; - case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(MAX_CLIENT_ATTRIB_STACK_DEPTH); - break; - case GL_MAX_CLIP_PLANES: - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxClipPlanes); - break; - case GL_MAX_ELEMENTS_VERTICES: - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxArrayLockSize); - break; - case GL_MAX_ELEMENTS_INDICES: - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxArrayLockSize); - break; - case GL_MAX_EVAL_ORDER: - params[0] = INT_TO_BOOLEAN(MAX_EVAL_ORDER); - break; - case GL_MAX_LIGHTS: - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxLights); - break; - case GL_MAX_LIST_NESTING: - params[0] = INT_TO_BOOLEAN(MAX_LIST_NESTING); - break; - case GL_MAX_MODELVIEW_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(MAX_MODELVIEW_STACK_DEPTH); - break; - case GL_MAX_NAME_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(MAX_NAME_STACK_DEPTH); - break; - case GL_MAX_PIXEL_MAP_TABLE: - params[0] = INT_TO_BOOLEAN(MAX_PIXEL_MAP_TABLE); - break; - case GL_MAX_PROJECTION_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(MAX_PROJECTION_STACK_DEPTH); - break; - case GL_MAX_TEXTURE_SIZE: - params[0] = INT_TO_BOOLEAN(1 << (ctx->Const.MaxTextureLevels - 1)); - break; - case GL_MAX_3D_TEXTURE_SIZE: - params[0] = INT_TO_BOOLEAN(1 << (ctx->Const.Max3DTextureLevels - 1)); - break; - case GL_MAX_TEXTURE_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(MAX_TEXTURE_STACK_DEPTH); - break; - case GL_MAX_VIEWPORT_DIMS: - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxViewportWidth); - params[1] = INT_TO_BOOLEAN(ctx->Const.MaxViewportHeight); - break; - case GL_MODELVIEW_MATRIX: - { - const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[1]); - params[2] = FLOAT_TO_BOOLEAN(matrix[2]); - params[3] = FLOAT_TO_BOOLEAN(matrix[3]); - params[4] = FLOAT_TO_BOOLEAN(matrix[4]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[6]); - params[7] = FLOAT_TO_BOOLEAN(matrix[7]); - params[8] = FLOAT_TO_BOOLEAN(matrix[8]); - params[9] = FLOAT_TO_BOOLEAN(matrix[9]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[11]); - params[12] = FLOAT_TO_BOOLEAN(matrix[12]); - params[13] = FLOAT_TO_BOOLEAN(matrix[13]); - params[14] = FLOAT_TO_BOOLEAN(matrix[14]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_MODELVIEW_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(ctx->ModelviewMatrixStack.Depth + 1); - break; - case GL_NAME_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(ctx->Select.NameStackDepth); - break; - case GL_NORMALIZE: - params[0] = ctx->Transform.Normalize; - break; - case GL_PACK_ALIGNMENT: - params[0] = INT_TO_BOOLEAN(ctx->Pack.Alignment); - break; - case GL_PACK_LSB_FIRST: - params[0] = ctx->Pack.LsbFirst; - break; - case GL_PACK_ROW_LENGTH: - params[0] = INT_TO_BOOLEAN(ctx->Pack.RowLength); - break; - case GL_PACK_SKIP_PIXELS: - params[0] = INT_TO_BOOLEAN(ctx->Pack.SkipPixels); - break; - case GL_PACK_SKIP_ROWS: - params[0] = INT_TO_BOOLEAN(ctx->Pack.SkipRows); - break; - case GL_PACK_SWAP_BYTES: - params[0] = ctx->Pack.SwapBytes; - break; - case GL_PACK_SKIP_IMAGES_EXT: - params[0] = INT_TO_BOOLEAN(ctx->Pack.SkipImages); - break; - case GL_PACK_IMAGE_HEIGHT_EXT: - params[0] = INT_TO_BOOLEAN(ctx->Pack.ImageHeight); - break; - case GL_PACK_INVERT_MESA: - params[0] = ctx->Pack.Invert; - break; - case GL_PERSPECTIVE_CORRECTION_HINT: - params[0] = ENUM_TO_BOOLEAN(ctx->Hint.PerspectiveCorrection); - break; - case GL_PIXEL_MAP_A_TO_A_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapAtoAsize); - break; - case GL_PIXEL_MAP_B_TO_B_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapBtoBsize); - break; - case GL_PIXEL_MAP_G_TO_G_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapGtoGsize); - break; - case GL_PIXEL_MAP_I_TO_A_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoAsize); - break; - case GL_PIXEL_MAP_I_TO_B_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoBsize); - break; - case GL_PIXEL_MAP_I_TO_G_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoGsize); - break; - case GL_PIXEL_MAP_I_TO_I_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoIsize); - break; - case GL_PIXEL_MAP_I_TO_R_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapItoRsize); - break; - case GL_PIXEL_MAP_R_TO_R_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapRtoRsize); - break; - case GL_PIXEL_MAP_S_TO_S_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Pixel.MapStoSsize); - break; - case GL_POINT_SIZE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Point.Size); - break; - case GL_POINT_SIZE_GRANULARITY: - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.PointSizeGranularity); - break; - case GL_POINT_SIZE_RANGE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinPointSizeAA); - params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxPointSizeAA); - break; - case GL_ALIASED_POINT_SIZE_RANGE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MinPointSize); - params[1] = FLOAT_TO_BOOLEAN(ctx->Const.MaxPointSize); - break; - case GL_POINT_SMOOTH: - params[0] = ctx->Point.SmoothFlag; - break; - case GL_POINT_SMOOTH_HINT: - params[0] = ENUM_TO_BOOLEAN(ctx->Hint.PointSmooth); - break; - case GL_POINT_SIZE_MIN_EXT: - params[0] = FLOAT_TO_BOOLEAN(ctx->Point.MinSize); - break; - case GL_POINT_SIZE_MAX_EXT: - params[0] = FLOAT_TO_BOOLEAN(ctx->Point.MaxSize); - break; - case GL_POINT_FADE_THRESHOLD_SIZE_EXT: - params[0] = FLOAT_TO_BOOLEAN(ctx->Point.Threshold); - break; - case GL_DISTANCE_ATTENUATION_EXT: - params[0] = FLOAT_TO_BOOLEAN(ctx->Point.Params[0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Point.Params[1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Point.Params[2]); - break; - case GL_POLYGON_MODE: - params[0] = ENUM_TO_BOOLEAN(ctx->Polygon.FrontMode); - params[1] = ENUM_TO_BOOLEAN(ctx->Polygon.BackMode); - break; - case GL_POLYGON_OFFSET_BIAS_EXT: - params[0] = FLOAT_TO_BOOLEAN(ctx->Polygon.OffsetUnits); - break; - case GL_POLYGON_OFFSET_FACTOR: - params[0] = FLOAT_TO_BOOLEAN(ctx->Polygon.OffsetFactor ); - break; - case GL_POLYGON_OFFSET_UNITS: - params[0] = FLOAT_TO_BOOLEAN(ctx->Polygon.OffsetUnits ); - break; - case GL_POLYGON_SMOOTH: - params[0] = ctx->Polygon.SmoothFlag; - break; - case GL_POLYGON_SMOOTH_HINT: - params[0] = ENUM_TO_BOOLEAN(ctx->Hint.PolygonSmooth); - break; - case GL_POLYGON_STIPPLE: - params[0] = ctx->Polygon.StippleFlag; - break; - case GL_PROJECTION_MATRIX: - { - const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[1]); - params[2] = FLOAT_TO_BOOLEAN(matrix[2]); - params[3] = FLOAT_TO_BOOLEAN(matrix[3]); - params[4] = FLOAT_TO_BOOLEAN(matrix[4]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[6]); - params[7] = FLOAT_TO_BOOLEAN(matrix[7]); - params[8] = FLOAT_TO_BOOLEAN(matrix[8]); - params[9] = FLOAT_TO_BOOLEAN(matrix[9]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[11]); - params[12] = FLOAT_TO_BOOLEAN(matrix[12]); - params[13] = FLOAT_TO_BOOLEAN(matrix[13]); - params[14] = FLOAT_TO_BOOLEAN(matrix[14]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_PROJECTION_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(ctx->ProjectionMatrixStack.Depth + 1); - break; - case GL_READ_BUFFER: - params[0] = ENUM_TO_BOOLEAN(ctx->ReadBuffer->ColorReadBuffer); - break; - case GL_RED_BIAS: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedBias); - break; - case GL_RED_BITS: - params[0] = INT_TO_BOOLEAN( ctx->DrawBuffer->Visual.redBits ); - break; - case GL_RED_SCALE: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedScale); - break; - case GL_RENDER_MODE: - params[0] = ENUM_TO_BOOLEAN(ctx->RenderMode); - break; - case GL_RESCALE_NORMAL: - params[0] = ctx->Transform.RescaleNormals; - break; - case GL_RGBA_MODE: - params[0] = ctx->DrawBuffer->Visual.rgbMode; - break; - case GL_SCISSOR_BOX: - params[0] = INT_TO_BOOLEAN(ctx->Scissor.X); - params[1] = INT_TO_BOOLEAN(ctx->Scissor.Y); - params[2] = INT_TO_BOOLEAN(ctx->Scissor.Width); - params[3] = INT_TO_BOOLEAN(ctx->Scissor.Height); - break; - case GL_SCISSOR_TEST: - params[0] = ctx->Scissor.Enabled; - break; - case GL_SELECTION_BUFFER_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Select.BufferSize); - break; - case GL_SHADE_MODEL: - params[0] = ENUM_TO_BOOLEAN(ctx->Light.ShadeModel); - break; - case GL_SHARED_TEXTURE_PALETTE_EXT: - params[0] = ctx->Texture.SharedPalette; - break; - case GL_STENCIL_BITS: - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.stencilBits); - break; - case GL_STENCIL_CLEAR_VALUE: - params[0] = INT_TO_BOOLEAN(ctx->Stencil.Clear); - break; - case GL_STENCIL_FAIL: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_FUNC: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_PASS_DEPTH_FAIL: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_PASS_DEPTH_PASS: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_REF: - params[0] = INT_TO_BOOLEAN(ctx->Stencil.Ref[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_TEST: - params[0] = ctx->Stencil.Enabled; - break; - case GL_STENCIL_VALUE_MASK: - params[0] = INT_TO_BOOLEAN(ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_WRITEMASK: - params[0] = INT_TO_BOOLEAN(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]); - break; - case GL_STEREO: - params[0] = ctx->DrawBuffer->Visual.stereoMode; - break; - case GL_SUBPIXEL_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Const.SubPixelBits); - break; - case GL_TEXTURE_1D: - params[0] = _mesa_IsEnabled(GL_TEXTURE_1D); - break; - case GL_TEXTURE_2D: - params[0] = _mesa_IsEnabled(GL_TEXTURE_2D); - break; - case GL_TEXTURE_3D: - params[0] = _mesa_IsEnabled(GL_TEXTURE_3D); - break; - case GL_TEXTURE_BINDING_1D: - params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name); - break; - case GL_TEXTURE_BINDING_2D: - params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2D->Name); - break; - case GL_TEXTURE_BINDING_3D: - params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name); - break; - case GL_TEXTURE_ENV_COLOR: - { - const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor; - params[0] = FLOAT_TO_BOOLEAN(color[0]); - params[1] = FLOAT_TO_BOOLEAN(color[1]); - params[2] = FLOAT_TO_BOOLEAN(color[2]); - params[3] = FLOAT_TO_BOOLEAN(color[3]); - } - break; - case GL_TEXTURE_ENV_MODE: - params[0] = ENUM_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvMode); - break; - case GL_TEXTURE_GEN_S: - params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0); - break; - case GL_TEXTURE_GEN_T: - params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0); - break; - case GL_TEXTURE_GEN_R: - params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0); - break; - case GL_TEXTURE_GEN_Q: - params[0] = ((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0); - break; - case GL_TEXTURE_MATRIX: - { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[1]); - params[2] = FLOAT_TO_BOOLEAN(matrix[2]); - params[3] = FLOAT_TO_BOOLEAN(matrix[3]); - params[4] = FLOAT_TO_BOOLEAN(matrix[4]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[6]); - params[7] = FLOAT_TO_BOOLEAN(matrix[7]); - params[8] = FLOAT_TO_BOOLEAN(matrix[8]); - params[9] = FLOAT_TO_BOOLEAN(matrix[9]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[11]); - params[12] = FLOAT_TO_BOOLEAN(matrix[12]); - params[13] = FLOAT_TO_BOOLEAN(matrix[13]); - params[14] = FLOAT_TO_BOOLEAN(matrix[14]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_TEXTURE_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1); - break; - case GL_UNPACK_ALIGNMENT: - params[0] = INT_TO_BOOLEAN(ctx->Unpack.Alignment); - break; - case GL_UNPACK_LSB_FIRST: - params[0] = ctx->Unpack.LsbFirst; - break; - case GL_UNPACK_ROW_LENGTH: - params[0] = INT_TO_BOOLEAN(ctx->Unpack.RowLength); - break; - case GL_UNPACK_SKIP_PIXELS: - params[0] = INT_TO_BOOLEAN(ctx->Unpack.SkipPixels); - break; - case GL_UNPACK_SKIP_ROWS: - params[0] = INT_TO_BOOLEAN(ctx->Unpack.SkipRows); - break; - case GL_UNPACK_SWAP_BYTES: - params[0] = ctx->Unpack.SwapBytes; - break; - case GL_UNPACK_SKIP_IMAGES_EXT: - params[0] = INT_TO_BOOLEAN(ctx->Unpack.SkipImages); - break; - case GL_UNPACK_IMAGE_HEIGHT_EXT: - params[0] = INT_TO_BOOLEAN(ctx->Unpack.ImageHeight); - break; - case GL_UNPACK_CLIENT_STORAGE_APPLE: - params[0] = ctx->Unpack.ClientStorage; - break; - case GL_VIEWPORT: - params[0] = INT_TO_BOOLEAN(ctx->Viewport.X); - params[1] = INT_TO_BOOLEAN(ctx->Viewport.Y); - params[2] = INT_TO_BOOLEAN(ctx->Viewport.Width); - params[3] = INT_TO_BOOLEAN(ctx->Viewport.Height); - break; - case GL_ZOOM_X: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.ZoomX); - break; - case GL_ZOOM_Y: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.ZoomY); - break; - case GL_VERTEX_ARRAY: - params[0] = ctx->Array.ArrayObj->Vertex.Enabled; - break; - case GL_VERTEX_ARRAY_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Vertex.Size); - break; - case GL_VERTEX_ARRAY_TYPE: - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->Vertex.Type); - break; - case GL_VERTEX_ARRAY_STRIDE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Vertex.Stride); - break; - case GL_VERTEX_ARRAY_COUNT_EXT: - params[0] = INT_TO_BOOLEAN(0); - break; - case GL_NORMAL_ARRAY: - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->Normal.Enabled); - break; - case GL_NORMAL_ARRAY_TYPE: - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->Normal.Type); - break; - case GL_NORMAL_ARRAY_STRIDE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Normal.Stride); - break; - case GL_NORMAL_ARRAY_COUNT_EXT: - params[0] = INT_TO_BOOLEAN(0); - break; - case GL_COLOR_ARRAY: - params[0] = ctx->Array.ArrayObj->Color.Enabled; - break; - case GL_COLOR_ARRAY_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Color.Size); - break; - case GL_COLOR_ARRAY_TYPE: - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->Color.Type); - break; - case GL_COLOR_ARRAY_STRIDE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Color.Stride); - break; - case GL_COLOR_ARRAY_COUNT_EXT: - params[0] = INT_TO_BOOLEAN(0); - break; - case GL_INDEX_ARRAY: - params[0] = ctx->Array.ArrayObj->Index.Enabled; - break; - case GL_INDEX_ARRAY_TYPE: - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->Index.Type); - break; - case GL_INDEX_ARRAY_STRIDE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Index.Stride); - break; - case GL_INDEX_ARRAY_COUNT_EXT: - params[0] = INT_TO_BOOLEAN(0); - break; - case GL_TEXTURE_COORD_ARRAY: - params[0] = ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled; - break; - case GL_TEXTURE_COORD_ARRAY_SIZE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Size); - break; - case GL_TEXTURE_COORD_ARRAY_TYPE: - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Type); - break; - case GL_TEXTURE_COORD_ARRAY_STRIDE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Stride); - break; - case GL_TEXTURE_COORD_ARRAY_COUNT_EXT: - params[0] = INT_TO_BOOLEAN(0); - break; - case GL_EDGE_FLAG_ARRAY: - params[0] = ctx->Array.ArrayObj->EdgeFlag.Enabled; - break; - case GL_EDGE_FLAG_ARRAY_STRIDE: - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->EdgeFlag.Stride); - break; - case GL_EDGE_FLAG_ARRAY_COUNT_EXT: - params[0] = INT_TO_BOOLEAN(0); - break; - case GL_MAX_TEXTURE_UNITS_ARB: - CHECK_EXT1(ARB_multitexture, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxTextureUnits); - break; - case GL_ACTIVE_TEXTURE_ARB: - CHECK_EXT1(ARB_multitexture, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit); - break; - case GL_CLIENT_ACTIVE_TEXTURE_ARB: - CHECK_EXT1(ARB_multitexture, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(GL_TEXTURE0_ARB + ctx->Array.ActiveTexture); - break; - case GL_TEXTURE_CUBE_MAP_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetBooleanv"); - params[0] = _mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB); - break; - case GL_TEXTURE_BINDING_CUBE_MAP_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap->Name); - break; - case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN((1 << (ctx->Const.MaxCubeTextureLevels - 1))); - break; - case GL_TEXTURE_COMPRESSION_HINT_ARB: - CHECK_EXT1(ARB_texture_compression, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Hint.TextureCompression); - break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: - CHECK_EXT1(ARB_texture_compression, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(_mesa_get_compressed_formats(ctx, NULL, GL_FALSE)); - break; - case GL_COMPRESSED_TEXTURE_FORMATS_ARB: - CHECK_EXT1(ARB_texture_compression, "GetBooleanv"); - { - GLint formats[100]; - GLuint i, n = _mesa_get_compressed_formats(ctx, formats, GL_FALSE); - ASSERT(n <= 100); - for (i = 0; i < n; i++) - params[i] = ENUM_TO_INT(formats[i]); - } - break; - case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT: - CHECK_EXT1(EXT_compiled_vertex_array, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.LockFirst); - break; - case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT: - CHECK_EXT1(EXT_compiled_vertex_array, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.LockCount); - break; - case GL_TRANSPOSE_COLOR_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ColorMatrixStack.Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[4]); - params[2] = FLOAT_TO_BOOLEAN(matrix[8]); - params[3] = FLOAT_TO_BOOLEAN(matrix[12]); - params[4] = FLOAT_TO_BOOLEAN(matrix[1]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[9]); - params[7] = FLOAT_TO_BOOLEAN(matrix[13]); - params[8] = FLOAT_TO_BOOLEAN(matrix[2]); - params[9] = FLOAT_TO_BOOLEAN(matrix[6]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[14]); - params[12] = FLOAT_TO_BOOLEAN(matrix[3]); - params[13] = FLOAT_TO_BOOLEAN(matrix[7]); - params[14] = FLOAT_TO_BOOLEAN(matrix[11]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[4]); - params[2] = FLOAT_TO_BOOLEAN(matrix[8]); - params[3] = FLOAT_TO_BOOLEAN(matrix[12]); - params[4] = FLOAT_TO_BOOLEAN(matrix[1]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[9]); - params[7] = FLOAT_TO_BOOLEAN(matrix[13]); - params[8] = FLOAT_TO_BOOLEAN(matrix[2]); - params[9] = FLOAT_TO_BOOLEAN(matrix[6]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[14]); - params[12] = FLOAT_TO_BOOLEAN(matrix[3]); - params[13] = FLOAT_TO_BOOLEAN(matrix[7]); - params[14] = FLOAT_TO_BOOLEAN(matrix[11]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[4]); - params[2] = FLOAT_TO_BOOLEAN(matrix[8]); - params[3] = FLOAT_TO_BOOLEAN(matrix[12]); - params[4] = FLOAT_TO_BOOLEAN(matrix[1]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[9]); - params[7] = FLOAT_TO_BOOLEAN(matrix[13]); - params[8] = FLOAT_TO_BOOLEAN(matrix[2]); - params[9] = FLOAT_TO_BOOLEAN(matrix[6]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[14]); - params[12] = FLOAT_TO_BOOLEAN(matrix[3]); - params[13] = FLOAT_TO_BOOLEAN(matrix[7]); - params[14] = FLOAT_TO_BOOLEAN(matrix[11]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: - { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[4]); - params[2] = FLOAT_TO_BOOLEAN(matrix[8]); - params[3] = FLOAT_TO_BOOLEAN(matrix[12]); - params[4] = FLOAT_TO_BOOLEAN(matrix[1]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[9]); - params[7] = FLOAT_TO_BOOLEAN(matrix[13]); - params[8] = FLOAT_TO_BOOLEAN(matrix[2]); - params[9] = FLOAT_TO_BOOLEAN(matrix[6]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[14]); - params[12] = FLOAT_TO_BOOLEAN(matrix[3]); - params[13] = FLOAT_TO_BOOLEAN(matrix[7]); - params[14] = FLOAT_TO_BOOLEAN(matrix[11]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_COLOR_MATRIX_SGI: - { - const GLfloat *matrix = ctx->ColorMatrixStack.Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[1]); - params[2] = FLOAT_TO_BOOLEAN(matrix[2]); - params[3] = FLOAT_TO_BOOLEAN(matrix[3]); - params[4] = FLOAT_TO_BOOLEAN(matrix[4]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[6]); - params[7] = FLOAT_TO_BOOLEAN(matrix[7]); - params[8] = FLOAT_TO_BOOLEAN(matrix[8]); - params[9] = FLOAT_TO_BOOLEAN(matrix[9]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[11]); - params[12] = FLOAT_TO_BOOLEAN(matrix[12]); - params[13] = FLOAT_TO_BOOLEAN(matrix[13]); - params[14] = FLOAT_TO_BOOLEAN(matrix[14]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_COLOR_MATRIX_STACK_DEPTH_SGI: - params[0] = INT_TO_BOOLEAN(ctx->ColorMatrixStack.Depth + 1); - break; - case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI: - params[0] = INT_TO_BOOLEAN(MAX_COLOR_STACK_DEPTH); - break; - case GL_POST_COLOR_MATRIX_RED_SCALE_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[0]); - break; - case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[1]); - break; - case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[2]); - break; - case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixScale[3]); - break; - case GL_POST_COLOR_MATRIX_RED_BIAS_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[0]); - break; - case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[1]); - break; - case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[2]); - break; - case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI: - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostColorMatrixBias[3]); - break; - case GL_CONVOLUTION_1D_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = ctx->Pixel.Convolution1DEnabled; - break; - case GL_CONVOLUTION_2D_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = ctx->Pixel.Convolution2DEnabled; - break; - case GL_SEPARABLE_2D_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = ctx->Pixel.Separable2DEnabled; - break; - case GL_POST_CONVOLUTION_RED_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[0]); - break; - case GL_POST_CONVOLUTION_GREEN_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[1]); - break; - case GL_POST_CONVOLUTION_BLUE_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[2]); - break; - case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionScale[3]); - break; - case GL_POST_CONVOLUTION_RED_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[0]); - break; - case GL_POST_CONVOLUTION_GREEN_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[1]); - break; - case GL_POST_CONVOLUTION_BLUE_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[2]); - break; - case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.PostConvolutionBias[3]); - break; - case GL_HISTOGRAM: - CHECK_EXT1(EXT_histogram, "GetBooleanv"); - params[0] = ctx->Pixel.HistogramEnabled; - break; - case GL_MINMAX: - CHECK_EXT1(EXT_histogram, "GetBooleanv"); - params[0] = ctx->Pixel.MinMaxEnabled; - break; - case GL_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetBooleanv"); - params[0] = ctx->Pixel.ColorTableEnabled; - break; - case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetBooleanv"); - params[0] = ctx->Pixel.PostConvolutionColorTableEnabled; - break; - case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetBooleanv"); - params[0] = ctx->Pixel.PostColorMatrixColorTableEnabled; - break; - case GL_TEXTURE_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_texture_color_table, "GetBooleanv"); - params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled; - break; - case GL_COLOR_SUM_EXT: - CHECK_EXT2(EXT_secondary_color, ARB_vertex_program, "GetBooleanv"); - params[0] = ctx->Fog.ColorSumEnabled; - break; - case GL_CURRENT_SECONDARY_COLOR_EXT: - CHECK_EXT1(EXT_secondary_color, "GetBooleanv"); - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3]); - } - break; - case GL_SECONDARY_COLOR_ARRAY_EXT: - CHECK_EXT1(EXT_secondary_color, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->SecondaryColor.Enabled; - break; - case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->SecondaryColor.Type); - break; - case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->SecondaryColor.Stride); - break; - case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->SecondaryColor.Size); - break; - case GL_CURRENT_FOG_COORDINATE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetBooleanv"); - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]); - } - break; - case GL_FOG_COORDINATE_ARRAY_EXT: - CHECK_EXT1(EXT_fog_coord, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->FogCoord.Enabled; - break; - case GL_FOG_COORDINATE_ARRAY_TYPE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Array.ArrayObj->FogCoord.Type); - break; - case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->FogCoord.Stride); - break; - case GL_FOG_COORDINATE_SOURCE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Fog.FogCoordinateSource); - break; - case GL_MAX_TEXTURE_LOD_BIAS_EXT: - CHECK_EXT1(EXT_texture_lod_bias, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxTextureLodBias); - break; - case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: - CHECK_EXT1(EXT_texture_filter_anisotropic, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxTextureMaxAnisotropy); - break; - case GL_MULTISAMPLE_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = ctx->Multisample.Enabled; - break; - case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = ctx->Multisample.SampleAlphaToCoverage; - break; - case GL_SAMPLE_ALPHA_TO_ONE_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = ctx->Multisample.SampleAlphaToOne; - break; - case GL_SAMPLE_COVERAGE_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = ctx->Multisample.SampleCoverage; - break; - case GL_SAMPLE_COVERAGE_VALUE_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Multisample.SampleCoverageValue); - break; - case GL_SAMPLE_COVERAGE_INVERT_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = ctx->Multisample.SampleCoverageInvert; - break; - case GL_SAMPLE_BUFFERS_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.sampleBuffers); - break; - case GL_SAMPLES_ARB: - CHECK_EXT1(ARB_multisample, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.samples); - break; - case GL_RASTER_POSITION_UNCLIPPED_IBM: - CHECK_EXT1(IBM_rasterpos_clip, "GetBooleanv"); - params[0] = ctx->Transform.RasterPositionUnclipped; - break; - case GL_POINT_SPRITE_NV: - CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetBooleanv"); - params[0] = ctx->Point.PointSprite; - break; - case GL_POINT_SPRITE_R_MODE_NV: - CHECK_EXT1(NV_point_sprite, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Point.SpriteRMode); - break; - case GL_POINT_SPRITE_COORD_ORIGIN: - CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Point.SpriteOrigin); - break; - case GL_GENERATE_MIPMAP_HINT_SGIS: - CHECK_EXT1(SGIS_generate_mipmap, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Hint.GenerateMipmap); - break; - case GL_VERTEX_PROGRAM_BINDING_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN((ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0)); - break; - case GL_VERTEX_ATTRIB_ARRAY0_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[0].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY1_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[1].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY2_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[2].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY3_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[3].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[4].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY5_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[5].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY6_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[6].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY7_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[7].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY8_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[8].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY9_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[9].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY10_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[10].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY11_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[11].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY12_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[12].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY13_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[13].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY14_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[14].Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY15_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Array.ArrayObj->VertexAttrib[15].Enabled; - break; - case GL_MAP1_VERTEX_ATTRIB0_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[0]; - break; - case GL_MAP1_VERTEX_ATTRIB1_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[1]; - break; - case GL_MAP1_VERTEX_ATTRIB2_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[2]; - break; - case GL_MAP1_VERTEX_ATTRIB3_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[3]; - break; - case GL_MAP1_VERTEX_ATTRIB4_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[4]; - break; - case GL_MAP1_VERTEX_ATTRIB5_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[5]; - break; - case GL_MAP1_VERTEX_ATTRIB6_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[6]; - break; - case GL_MAP1_VERTEX_ATTRIB7_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[7]; - break; - case GL_MAP1_VERTEX_ATTRIB8_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[8]; - break; - case GL_MAP1_VERTEX_ATTRIB9_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[9]; - break; - case GL_MAP1_VERTEX_ATTRIB10_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[10]; - break; - case GL_MAP1_VERTEX_ATTRIB11_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[11]; - break; - case GL_MAP1_VERTEX_ATTRIB12_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[12]; - break; - case GL_MAP1_VERTEX_ATTRIB13_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[13]; - break; - case GL_MAP1_VERTEX_ATTRIB14_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[14]; - break; - case GL_MAP1_VERTEX_ATTRIB15_4_NV: - CHECK_EXT1(NV_vertex_program, "GetBooleanv"); - params[0] = ctx->Eval.Map1Attrib[15]; - break; - case GL_FRAGMENT_PROGRAM_NV: - CHECK_EXT1(NV_fragment_program, "GetBooleanv"); - params[0] = ctx->FragmentProgram.Enabled; - break; - case GL_FRAGMENT_PROGRAM_BINDING_NV: - CHECK_EXT1(NV_fragment_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0); - break; - case GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV: - CHECK_EXT1(NV_fragment_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_NV_FRAGMENT_PROGRAM_PARAMS); - break; - case GL_TEXTURE_RECTANGLE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetBooleanv"); - params[0] = _mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV); - break; - case GL_TEXTURE_BINDING_RECTANGLE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentRect->Name); - break; - case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxTextureRectSize); - break; - case GL_STENCIL_TEST_TWO_SIDE_EXT: - CHECK_EXT1(EXT_stencil_two_side, "GetBooleanv"); - params[0] = ctx->Stencil.TestTwoSide; - break; - case GL_ACTIVE_STENCIL_FACE_EXT: - CHECK_EXT1(EXT_stencil_two_side, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT); - break; - case GL_MAX_SHININESS_NV: - CHECK_EXT1(NV_light_max_exponent, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxShininess); - break; - case GL_MAX_SPOT_EXPONENT_NV: - CHECK_EXT1(NV_light_max_exponent, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Const.MaxSpotExponent); - break; - case GL_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayBufferObj->Name); - break; - case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Vertex.BufferObj->Name); - break; - case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Normal.BufferObj->Name); - break; - case GL_COLOR_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Color.BufferObj->Name); - break; - case GL_INDEX_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Index.BufferObj->Name); - break; - case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name); - break; - case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->EdgeFlag.BufferObj->Name); - break; - case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->SecondaryColor.BufferObj->Name); - break; - case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->FogCoord.BufferObj->Name); - break; - case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Array.ElementArrayBufferObj->Name); - break; - case GL_PIXEL_PACK_BUFFER_BINDING_EXT: - CHECK_EXT1(EXT_pixel_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Pack.BufferObj->Name); - break; - case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT: - CHECK_EXT1(EXT_pixel_buffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Unpack.BufferObj->Name); - break; - case GL_VERTEX_PROGRAM_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetBooleanv"); - params[0] = ctx->VertexProgram.Enabled; - break; - case GL_VERTEX_PROGRAM_POINT_SIZE_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetBooleanv"); - params[0] = ctx->VertexProgram.PointSizeEnabled; - break; - case GL_VERTEX_PROGRAM_TWO_SIDE_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetBooleanv"); - params[0] = ctx->VertexProgram.TwoSideEnabled; - break; - case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxProgramMatrixStackDepth); - break; - case GL_MAX_PROGRAM_MATRICES_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxProgramMatrices); - break; - case GL_CURRENT_MATRIX_STACK_DEPTH_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetBooleanv"); - params[0] = ctx->CurrentStack->Depth + 1; - break; - case GL_CURRENT_MATRIX_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_fragment_program, "GetBooleanv"); - { - const GLfloat *matrix = ctx->CurrentStack->Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[1]); - params[2] = FLOAT_TO_BOOLEAN(matrix[2]); - params[3] = FLOAT_TO_BOOLEAN(matrix[3]); - params[4] = FLOAT_TO_BOOLEAN(matrix[4]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[6]); - params[7] = FLOAT_TO_BOOLEAN(matrix[7]); - params[8] = FLOAT_TO_BOOLEAN(matrix[8]); - params[9] = FLOAT_TO_BOOLEAN(matrix[9]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[11]); - params[12] = FLOAT_TO_BOOLEAN(matrix[12]); - params[13] = FLOAT_TO_BOOLEAN(matrix[13]); - params[14] = FLOAT_TO_BOOLEAN(matrix[14]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_TRANSPOSE_CURRENT_MATRIX_ARB: - CHECK_EXT2(ARB_vertex_program, ARB_fragment_program, "GetBooleanv"); - { - const GLfloat *matrix = ctx->CurrentStack->Top->m; - params[0] = FLOAT_TO_BOOLEAN(matrix[0]); - params[1] = FLOAT_TO_BOOLEAN(matrix[4]); - params[2] = FLOAT_TO_BOOLEAN(matrix[8]); - params[3] = FLOAT_TO_BOOLEAN(matrix[12]); - params[4] = FLOAT_TO_BOOLEAN(matrix[1]); - params[5] = FLOAT_TO_BOOLEAN(matrix[5]); - params[6] = FLOAT_TO_BOOLEAN(matrix[9]); - params[7] = FLOAT_TO_BOOLEAN(matrix[13]); - params[8] = FLOAT_TO_BOOLEAN(matrix[2]); - params[9] = FLOAT_TO_BOOLEAN(matrix[6]); - params[10] = FLOAT_TO_BOOLEAN(matrix[10]); - params[11] = FLOAT_TO_BOOLEAN(matrix[14]); - params[12] = FLOAT_TO_BOOLEAN(matrix[3]); - params[13] = FLOAT_TO_BOOLEAN(matrix[7]); - params[14] = FLOAT_TO_BOOLEAN(matrix[11]); - params[15] = FLOAT_TO_BOOLEAN(matrix[15]); - } - break; - case GL_MAX_VERTEX_ATTRIBS_ARB: - CHECK_EXT1(ARB_vertex_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.VertexProgram.MaxAttribs); - break; - case GL_PROGRAM_ERROR_POSITION_ARB: - CHECK_EXT4(NV_vertex_program, ARB_vertex_program, NV_fragment_program, ARB_fragment_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Program.ErrorPos); - break; - case GL_FRAGMENT_PROGRAM_ARB: - CHECK_EXT1(ARB_fragment_program, "GetBooleanv"); - params[0] = ctx->FragmentProgram.Enabled; - break; - case GL_MAX_TEXTURE_COORDS_ARB: - CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxTextureCoordUnits); - break; - case GL_MAX_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxTextureImageUnits); - break; - case GL_DEPTH_BOUNDS_TEST_EXT: - CHECK_EXT1(EXT_depth_bounds_test, "GetBooleanv"); - params[0] = ctx->Depth.BoundsTest; - break; - case GL_DEPTH_BOUNDS_EXT: - CHECK_EXT1(EXT_depth_bounds_test, "GetBooleanv"); - params[0] = FLOAT_TO_BOOLEAN(ctx->Depth.BoundsMin); - params[1] = FLOAT_TO_BOOLEAN(ctx->Depth.BoundsMax); - break; - case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: - CHECK_EXT1(MESA_program_debug, "GetBooleanv"); - params[0] = ctx->FragmentProgram.CallbackEnabled; - break; - case GL_VERTEX_PROGRAM_CALLBACK_MESA: - CHECK_EXT1(MESA_program_debug, "GetBooleanv"); - params[0] = ctx->VertexProgram.CallbackEnabled; - break; - case GL_FRAGMENT_PROGRAM_POSITION_MESA: - CHECK_EXT1(MESA_program_debug, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->FragmentProgram.CurrentPosition); - break; - case GL_VERTEX_PROGRAM_POSITION_MESA: - CHECK_EXT1(MESA_program_debug, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->VertexProgram.CurrentPosition); - break; - case GL_MAX_DRAW_BUFFERS_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxDrawBuffers); - break; - case GL_DRAW_BUFFER0_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->DrawBuffer->ColorDrawBuffer[0]); - break; - case GL_DRAW_BUFFER1_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetBooleanv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[1]; - params[0] = ENUM_TO_BOOLEAN(buffer); - } - break; - case GL_DRAW_BUFFER2_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetBooleanv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[2]; - params[0] = ENUM_TO_BOOLEAN(buffer); - } - break; - case GL_DRAW_BUFFER3_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetBooleanv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[3]; - params[0] = ENUM_TO_BOOLEAN(buffer); - } - break; - case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: - CHECK_EXT1(OES_read_format, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.ColorReadType); - break; - case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: - CHECK_EXT1(OES_read_format, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.ColorReadFormat); - break; - case GL_NUM_FRAGMENT_REGISTERS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(6); - break; - case GL_NUM_FRAGMENT_CONSTANTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(8); - break; - case GL_NUM_PASSES_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(2); - break; - case GL_NUM_INSTRUCTIONS_PER_PASS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(8); - break; - case GL_NUM_INSTRUCTIONS_TOTAL_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(16); - break; - case GL_COLOR_ALPHA_PAIRING_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = GL_TRUE; - break; - case GL_NUM_LOOPBACK_COMPONENTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(3); - break; - case GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(3); - break; - case GL_STENCIL_BACK_FUNC: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.Function[1]); - break; - case GL_STENCIL_BACK_VALUE_MASK: - params[0] = INT_TO_BOOLEAN(ctx->Stencil.ValueMask[1]); - break; - case GL_STENCIL_BACK_REF: - params[0] = INT_TO_BOOLEAN(ctx->Stencil.Ref[1]); - break; - case GL_STENCIL_BACK_FAIL: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.FailFunc[1]); - break; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZFailFunc[1]); - break; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - params[0] = ENUM_TO_BOOLEAN(ctx->Stencil.ZPassFunc[1]); - break; - case GL_FRAMEBUFFER_BINDING_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Name); - break; - case GL_RENDERBUFFER_BINDING_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0); - break; - case GL_MAX_COLOR_ATTACHMENTS_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxColorAttachments); - break; - case GL_MAX_RENDERBUFFER_SIZE_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxRenderbufferSize); - break; - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: - CHECK_EXT1(ARB_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_FRAGMENT_UNIFORM_COMPONENTS); - break; - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: - CHECK_EXT1(ARB_fragment_shader, "GetBooleanv"); - params[0] = ENUM_TO_BOOLEAN(ctx->Hint.FragmentShaderDerivative); - break; - case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VERTEX_UNIFORM_COMPONENTS); - break; - case GL_MAX_VARYING_FLOATS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VARYING_FLOATS); - break; - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VERTEX_TEXTURE_IMAGE_UNITS); - break; - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_COMBINED_TEXTURE_IMAGE_UNITS); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname); - } -} - -void GLAPIENTRY -_mesa_GetFloatv( GLenum pname, GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (!params) - return; - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (ctx->Driver.GetFloatv && - ctx->Driver.GetFloatv(ctx, pname, params)) - return; - - switch (pname) { - case GL_ACCUM_RED_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumRedBits); - break; - case GL_ACCUM_GREEN_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumGreenBits); - break; - case GL_ACCUM_BLUE_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumBlueBits); - break; - case GL_ACCUM_ALPHA_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumAlphaBits); - break; - case GL_ACCUM_CLEAR_VALUE: - params[0] = ctx->Accum.ClearColor[0]; - params[1] = ctx->Accum.ClearColor[1]; - params[2] = ctx->Accum.ClearColor[2]; - params[3] = ctx->Accum.ClearColor[3]; - break; - case GL_ALPHA_BIAS: - params[0] = ctx->Pixel.AlphaBias; - break; - case GL_ALPHA_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.alphaBits); - break; - case GL_ALPHA_SCALE: - params[0] = ctx->Pixel.AlphaScale; - break; - case GL_ALPHA_TEST: - params[0] = BOOLEAN_TO_FLOAT(ctx->Color.AlphaEnabled); - break; - case GL_ALPHA_TEST_FUNC: - params[0] = ENUM_TO_FLOAT(ctx->Color.AlphaFunc); - break; - case GL_ALPHA_TEST_REF: - params[0] = ctx->Color.AlphaRef; - break; - case GL_ATTRIB_STACK_DEPTH: - params[0] = (GLfloat)(ctx->AttribStackDepth); - break; - case GL_AUTO_NORMAL: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.AutoNormal); - break; - case GL_AUX_BUFFERS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.numAuxBuffers); - break; - case GL_BLEND: - params[0] = BOOLEAN_TO_FLOAT(ctx->Color.BlendEnabled); - break; - case GL_BLEND_DST: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB); - break; - case GL_BLEND_SRC: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB); - break; - case GL_BLEND_SRC_RGB_EXT: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB); - break; - case GL_BLEND_DST_RGB_EXT: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB); - break; - case GL_BLEND_SRC_ALPHA_EXT: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendSrcA); - break; - case GL_BLEND_DST_ALPHA_EXT: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstA); - break; - case GL_BLEND_EQUATION: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendEquationRGB ); - break; - case GL_BLEND_EQUATION_ALPHA_EXT: - params[0] = ENUM_TO_FLOAT(ctx->Color.BlendEquationA ); - break; - case GL_BLEND_COLOR_EXT: - params[0] = ctx->Color.BlendColor[0]; - params[1] = ctx->Color.BlendColor[1]; - params[2] = ctx->Color.BlendColor[2]; - params[3] = ctx->Color.BlendColor[3]; - break; - case GL_BLUE_BIAS: - params[0] = ctx->Pixel.BlueBias; - break; - case GL_BLUE_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.blueBits); - break; - case GL_BLUE_SCALE: - params[0] = ctx->Pixel.BlueScale; - break; - case GL_CLIENT_ATTRIB_STACK_DEPTH: - params[0] = (GLfloat)(ctx->ClientAttribStackDepth); - break; - case GL_CLIP_PLANE0: - params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 0) & 1); - break; - case GL_CLIP_PLANE1: - params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 1) & 1); - break; - case GL_CLIP_PLANE2: - params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 2) & 1); - break; - case GL_CLIP_PLANE3: - params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 3) & 1); - break; - case GL_CLIP_PLANE4: - params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 4) & 1); - break; - case GL_CLIP_PLANE5: - params[0] = BOOLEAN_TO_FLOAT((ctx->Transform.ClipPlanesEnabled >> 5) & 1); - break; - case GL_COLOR_CLEAR_VALUE: - params[0] = ctx->Color.ClearColor[0]; - params[1] = ctx->Color.ClearColor[1]; - params[2] = ctx->Color.ClearColor[2]; - params[3] = ctx->Color.ClearColor[3]; - break; - case GL_COLOR_MATERIAL: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.ColorMaterialEnabled); - break; - case GL_COLOR_MATERIAL_FACE: - params[0] = ENUM_TO_FLOAT(ctx->Light.ColorMaterialFace); - break; - case GL_COLOR_MATERIAL_PARAMETER: - params[0] = ENUM_TO_FLOAT(ctx->Light.ColorMaterialMode); - break; - case GL_COLOR_WRITEMASK: - params[0] = (GLfloat)(ctx->Color.ColorMask[RCOMP] ? 1 : 0); - params[1] = (GLfloat)(ctx->Color.ColorMask[GCOMP] ? 1 : 0); - params[2] = (GLfloat)(ctx->Color.ColorMask[BCOMP] ? 1 : 0); - params[3] = (GLfloat)(ctx->Color.ColorMask[ACOMP] ? 1 : 0); - break; - case GL_CULL_FACE: - params[0] = BOOLEAN_TO_FLOAT(ctx->Polygon.CullFlag); - break; - case GL_CULL_FACE_MODE: - params[0] = ENUM_TO_FLOAT(ctx->Polygon.CullFaceMode); - break; - case GL_CURRENT_COLOR: - { - FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - params[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - params[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - params[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - } - break; - case GL_CURRENT_INDEX: - { - FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]; - } - break; - case GL_CURRENT_NORMAL: - { - FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; - params[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; - params[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; - } - break; - case GL_CURRENT_RASTER_COLOR: - params[0] = ctx->Current.RasterColor[0]; - params[1] = ctx->Current.RasterColor[1]; - params[2] = ctx->Current.RasterColor[2]; - params[3] = ctx->Current.RasterColor[3]; - break; - case GL_CURRENT_RASTER_DISTANCE: - params[0] = ctx->Current.RasterDistance; - break; - case GL_CURRENT_RASTER_INDEX: - params[0] = ctx->Current.RasterIndex; - break; - case GL_CURRENT_RASTER_POSITION: - params[0] = ctx->Current.RasterPos[0]; - params[1] = ctx->Current.RasterPos[1]; - params[2] = ctx->Current.RasterPos[2]; - params[3] = ctx->Current.RasterPos[3]; - break; - case GL_CURRENT_RASTER_SECONDARY_COLOR: - params[0] = ctx->Current.RasterSecondaryColor[0]; - params[1] = ctx->Current.RasterSecondaryColor[1]; - params[2] = ctx->Current.RasterSecondaryColor[2]; - params[3] = ctx->Current.RasterSecondaryColor[3]; - break; - case GL_CURRENT_RASTER_TEXTURE_COORDS: - { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = ctx->Current.RasterTexCoords[texUnit][0]; - params[1] = ctx->Current.RasterTexCoords[texUnit][1]; - params[2] = ctx->Current.RasterTexCoords[texUnit][2]; - params[3] = ctx->Current.RasterTexCoords[texUnit][3]; - } - break; - case GL_CURRENT_RASTER_POSITION_VALID: - params[0] = BOOLEAN_TO_FLOAT(ctx->Current.RasterPosValid); - break; - case GL_CURRENT_TEXTURE_COORDS: - { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]; - params[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]; - params[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]; - params[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]; - } - break; - case GL_DEPTH_BIAS: - params[0] = ctx->Pixel.DepthBias; - break; - case GL_DEPTH_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.depthBits); - break; - case GL_DEPTH_CLEAR_VALUE: - params[0] = ctx->Depth.Clear; - break; - case GL_DEPTH_FUNC: - params[0] = ENUM_TO_FLOAT(ctx->Depth.Func); - break; - case GL_DEPTH_RANGE: - params[0] = ctx->Viewport.Near; - params[1] = ctx->Viewport.Far; - break; - case GL_DEPTH_SCALE: - params[0] = ctx->Pixel.DepthScale; - break; - case GL_DEPTH_TEST: - params[0] = BOOLEAN_TO_FLOAT(ctx->Depth.Test); - break; - case GL_DEPTH_WRITEMASK: - params[0] = BOOLEAN_TO_FLOAT(ctx->Depth.Mask); - break; - case GL_DITHER: - params[0] = BOOLEAN_TO_FLOAT(ctx->Color.DitherFlag); - break; - case GL_DOUBLEBUFFER: - params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.doubleBufferMode); - break; - case GL_DRAW_BUFFER: - params[0] = ENUM_TO_FLOAT(ctx->DrawBuffer->ColorDrawBuffer[0]); - break; - case GL_EDGE_FLAG: - { - FLUSH_CURRENT(ctx, 0); - params[0] = BOOLEAN_TO_FLOAT(ctx->Current.EdgeFlag); - } - break; - case GL_FEEDBACK_BUFFER_SIZE: - params[0] = (GLfloat)(ctx->Feedback.BufferSize); - break; - case GL_FEEDBACK_BUFFER_TYPE: - params[0] = ENUM_TO_FLOAT(ctx->Feedback.Type); - break; - case GL_FOG: - params[0] = BOOLEAN_TO_FLOAT(ctx->Fog.Enabled); - break; - case GL_FOG_COLOR: - params[0] = ctx->Fog.Color[0]; - params[1] = ctx->Fog.Color[1]; - params[2] = ctx->Fog.Color[2]; - params[3] = ctx->Fog.Color[3]; - break; - case GL_FOG_DENSITY: - params[0] = ctx->Fog.Density; - break; - case GL_FOG_END: - params[0] = ctx->Fog.End; - break; - case GL_FOG_HINT: - params[0] = ENUM_TO_FLOAT(ctx->Hint.Fog); - break; - case GL_FOG_INDEX: - params[0] = ctx->Fog.Index; - break; - case GL_FOG_MODE: - params[0] = ENUM_TO_FLOAT(ctx->Fog.Mode); - break; - case GL_FOG_START: - params[0] = ctx->Fog.Start; - break; - case GL_FRONT_FACE: - params[0] = ENUM_TO_FLOAT(ctx->Polygon.FrontFace); - break; - case GL_GREEN_BIAS: - params[0] = ctx->Pixel.GreenBias; - break; - case GL_GREEN_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.greenBits); - break; - case GL_GREEN_SCALE: - params[0] = ctx->Pixel.GreenScale; - break; - case GL_INDEX_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.indexBits); - break; - case GL_INDEX_CLEAR_VALUE: - params[0] = (GLfloat)(ctx->Color.ClearIndex); - break; - case GL_INDEX_MODE: - params[0] = BOOLEAN_TO_FLOAT(!ctx->DrawBuffer->Visual.rgbMode); - break; - case GL_INDEX_OFFSET: - params[0] = (GLfloat)(ctx->Pixel.IndexOffset); - break; - case GL_INDEX_SHIFT: - params[0] = (GLfloat)(ctx->Pixel.IndexShift); - break; - case GL_INDEX_WRITEMASK: - params[0] = (GLfloat)(ctx->Color.IndexMask); - break; - case GL_LIGHT0: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[0].Enabled); - break; - case GL_LIGHT1: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[1].Enabled); - break; - case GL_LIGHT2: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[2].Enabled); - break; - case GL_LIGHT3: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[3].Enabled); - break; - case GL_LIGHT4: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[4].Enabled); - break; - case GL_LIGHT5: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[5].Enabled); - break; - case GL_LIGHT6: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[6].Enabled); - break; - case GL_LIGHT7: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Light[7].Enabled); - break; - case GL_LIGHTING: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Enabled); - break; - case GL_LIGHT_MODEL_AMBIENT: - params[0] = ctx->Light.Model.Ambient[0]; - params[1] = ctx->Light.Model.Ambient[1]; - params[2] = ctx->Light.Model.Ambient[2]; - params[3] = ctx->Light.Model.Ambient[3]; - break; - case GL_LIGHT_MODEL_COLOR_CONTROL: - params[0] = ENUM_TO_FLOAT(ctx->Light.Model.ColorControl); - break; - case GL_LIGHT_MODEL_LOCAL_VIEWER: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Model.LocalViewer); - break; - case GL_LIGHT_MODEL_TWO_SIDE: - params[0] = BOOLEAN_TO_FLOAT(ctx->Light.Model.TwoSide); - break; - case GL_LINE_SMOOTH: - params[0] = BOOLEAN_TO_FLOAT(ctx->Line.SmoothFlag); - break; - case GL_LINE_SMOOTH_HINT: - params[0] = ENUM_TO_FLOAT(ctx->Hint.LineSmooth); - break; - case GL_LINE_STIPPLE: - params[0] = BOOLEAN_TO_FLOAT(ctx->Line.StippleFlag); - break; - case GL_LINE_STIPPLE_PATTERN: - params[0] = (GLfloat)(ctx->Line.StipplePattern); - break; - case GL_LINE_STIPPLE_REPEAT: - params[0] = (GLfloat)(ctx->Line.StippleFactor); - break; - case GL_LINE_WIDTH: - params[0] = ctx->Line.Width; - break; - case GL_LINE_WIDTH_GRANULARITY: - params[0] = ctx->Const.LineWidthGranularity; - break; - case GL_LINE_WIDTH_RANGE: - params[0] = ctx->Const.MinLineWidthAA; - params[1] = ctx->Const.MaxLineWidthAA; - break; - case GL_ALIASED_LINE_WIDTH_RANGE: - params[0] = ctx->Const.MinLineWidth; - params[1] = ctx->Const.MaxLineWidth; - break; - case GL_LIST_BASE: - params[0] = (GLfloat)(ctx->List.ListBase); - break; - case GL_LIST_INDEX: - params[0] = (GLfloat)(ctx->ListState.CurrentListNum); - break; - case GL_LIST_MODE: - { - GLenum mode; - if (!ctx->CompileFlag) - mode = 0; - else if (ctx->ExecuteFlag) - mode = GL_COMPILE_AND_EXECUTE; - else - mode = GL_COMPILE; - params[0] = ENUM_TO_FLOAT(mode); - } - break; - case GL_INDEX_LOGIC_OP: - params[0] = BOOLEAN_TO_FLOAT(ctx->Color.IndexLogicOpEnabled); - break; - case GL_COLOR_LOGIC_OP: - params[0] = BOOLEAN_TO_FLOAT(ctx->Color.ColorLogicOpEnabled); - break; - case GL_LOGIC_OP_MODE: - params[0] = ENUM_TO_FLOAT(ctx->Color.LogicOp); - break; - case GL_MAP1_COLOR_4: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Color4); - break; - case GL_MAP1_GRID_DOMAIN: - params[0] = ctx->Eval.MapGrid1u1; - params[1] = ctx->Eval.MapGrid1u2; - break; - case GL_MAP1_GRID_SEGMENTS: - params[0] = (GLfloat)(ctx->Eval.MapGrid1un); - break; - case GL_MAP1_INDEX: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Index); - break; - case GL_MAP1_NORMAL: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Normal); - break; - case GL_MAP1_TEXTURE_COORD_1: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord1); - break; - case GL_MAP1_TEXTURE_COORD_2: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord2); - break; - case GL_MAP1_TEXTURE_COORD_3: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord3); - break; - case GL_MAP1_TEXTURE_COORD_4: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1TextureCoord4); - break; - case GL_MAP1_VERTEX_3: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Vertex3); - break; - case GL_MAP1_VERTEX_4: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Vertex4); - break; - case GL_MAP2_COLOR_4: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Color4); - break; - case GL_MAP2_GRID_DOMAIN: - params[0] = ctx->Eval.MapGrid2u1; - params[1] = ctx->Eval.MapGrid2u2; - params[2] = ctx->Eval.MapGrid2v1; - params[3] = ctx->Eval.MapGrid2v2; - break; - case GL_MAP2_GRID_SEGMENTS: - params[0] = (GLfloat)(ctx->Eval.MapGrid2un); - params[1] = (GLfloat)(ctx->Eval.MapGrid2vn); - break; - case GL_MAP2_INDEX: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Index); - break; - case GL_MAP2_NORMAL: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Normal); - break; - case GL_MAP2_TEXTURE_COORD_1: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord1); - break; - case GL_MAP2_TEXTURE_COORD_2: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord2); - break; - case GL_MAP2_TEXTURE_COORD_3: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord3); - break; - case GL_MAP2_TEXTURE_COORD_4: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2TextureCoord4); - break; - case GL_MAP2_VERTEX_3: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Vertex3); - break; - case GL_MAP2_VERTEX_4: - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map2Vertex4); - break; - case GL_MAP_COLOR: - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.MapColorFlag); - break; - case GL_MAP_STENCIL: - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.MapStencilFlag); - break; - case GL_MATRIX_MODE: - params[0] = ENUM_TO_FLOAT(ctx->Transform.MatrixMode); - break; - case GL_MAX_ATTRIB_STACK_DEPTH: - params[0] = (GLfloat)(MAX_ATTRIB_STACK_DEPTH); - break; - case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: - params[0] = (GLfloat)(MAX_CLIENT_ATTRIB_STACK_DEPTH); - break; - case GL_MAX_CLIP_PLANES: - params[0] = (GLfloat)(ctx->Const.MaxClipPlanes); - break; - case GL_MAX_ELEMENTS_VERTICES: - params[0] = (GLfloat)(ctx->Const.MaxArrayLockSize); - break; - case GL_MAX_ELEMENTS_INDICES: - params[0] = (GLfloat)(ctx->Const.MaxArrayLockSize); - break; - case GL_MAX_EVAL_ORDER: - params[0] = (GLfloat)(MAX_EVAL_ORDER); - break; - case GL_MAX_LIGHTS: - params[0] = (GLfloat)(ctx->Const.MaxLights); - break; - case GL_MAX_LIST_NESTING: - params[0] = (GLfloat)(MAX_LIST_NESTING); - break; - case GL_MAX_MODELVIEW_STACK_DEPTH: - params[0] = (GLfloat)(MAX_MODELVIEW_STACK_DEPTH); - break; - case GL_MAX_NAME_STACK_DEPTH: - params[0] = (GLfloat)(MAX_NAME_STACK_DEPTH); - break; - case GL_MAX_PIXEL_MAP_TABLE: - params[0] = (GLfloat)(MAX_PIXEL_MAP_TABLE); - break; - case GL_MAX_PROJECTION_STACK_DEPTH: - params[0] = (GLfloat)(MAX_PROJECTION_STACK_DEPTH); - break; - case GL_MAX_TEXTURE_SIZE: - params[0] = (GLfloat)(1 << (ctx->Const.MaxTextureLevels - 1)); - break; - case GL_MAX_3D_TEXTURE_SIZE: - params[0] = (GLfloat)(1 << (ctx->Const.Max3DTextureLevels - 1)); - break; - case GL_MAX_TEXTURE_STACK_DEPTH: - params[0] = (GLfloat)(MAX_TEXTURE_STACK_DEPTH); - break; - case GL_MAX_VIEWPORT_DIMS: - params[0] = (GLfloat)(ctx->Const.MaxViewportWidth); - params[1] = (GLfloat)(ctx->Const.MaxViewportHeight); - break; - case GL_MODELVIEW_MATRIX: - { - const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m; - params[0] = matrix[0]; - params[1] = matrix[1]; - params[2] = matrix[2]; - params[3] = matrix[3]; - params[4] = matrix[4]; - params[5] = matrix[5]; - params[6] = matrix[6]; - params[7] = matrix[7]; - params[8] = matrix[8]; - params[9] = matrix[9]; - params[10] = matrix[10]; - params[11] = matrix[11]; - params[12] = matrix[12]; - params[13] = matrix[13]; - params[14] = matrix[14]; - params[15] = matrix[15]; - } - break; - case GL_MODELVIEW_STACK_DEPTH: - params[0] = (GLfloat)(ctx->ModelviewMatrixStack.Depth + 1); - break; - case GL_NAME_STACK_DEPTH: - params[0] = (GLfloat)(ctx->Select.NameStackDepth); - break; - case GL_NORMALIZE: - params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.Normalize); - break; - case GL_PACK_ALIGNMENT: - params[0] = (GLfloat)(ctx->Pack.Alignment); - break; - case GL_PACK_LSB_FIRST: - params[0] = BOOLEAN_TO_FLOAT(ctx->Pack.LsbFirst); - break; - case GL_PACK_ROW_LENGTH: - params[0] = (GLfloat)(ctx->Pack.RowLength); - break; - case GL_PACK_SKIP_PIXELS: - params[0] = (GLfloat)(ctx->Pack.SkipPixels); - break; - case GL_PACK_SKIP_ROWS: - params[0] = (GLfloat)(ctx->Pack.SkipRows); - break; - case GL_PACK_SWAP_BYTES: - params[0] = BOOLEAN_TO_FLOAT(ctx->Pack.SwapBytes); - break; - case GL_PACK_SKIP_IMAGES_EXT: - params[0] = (GLfloat)(ctx->Pack.SkipImages); - break; - case GL_PACK_IMAGE_HEIGHT_EXT: - params[0] = (GLfloat)(ctx->Pack.ImageHeight); - break; - case GL_PACK_INVERT_MESA: - params[0] = BOOLEAN_TO_FLOAT(ctx->Pack.Invert); - break; - case GL_PERSPECTIVE_CORRECTION_HINT: - params[0] = ENUM_TO_FLOAT(ctx->Hint.PerspectiveCorrection); - break; - case GL_PIXEL_MAP_A_TO_A_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapAtoAsize); - break; - case GL_PIXEL_MAP_B_TO_B_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapBtoBsize); - break; - case GL_PIXEL_MAP_G_TO_G_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapGtoGsize); - break; - case GL_PIXEL_MAP_I_TO_A_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapItoAsize); - break; - case GL_PIXEL_MAP_I_TO_B_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapItoBsize); - break; - case GL_PIXEL_MAP_I_TO_G_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapItoGsize); - break; - case GL_PIXEL_MAP_I_TO_I_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapItoIsize); - break; - case GL_PIXEL_MAP_I_TO_R_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapItoRsize); - break; - case GL_PIXEL_MAP_R_TO_R_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapRtoRsize); - break; - case GL_PIXEL_MAP_S_TO_S_SIZE: - params[0] = (GLfloat)(ctx->Pixel.MapStoSsize); - break; - case GL_POINT_SIZE: - params[0] = ctx->Point.Size; - break; - case GL_POINT_SIZE_GRANULARITY: - params[0] = ctx->Const.PointSizeGranularity; - break; - case GL_POINT_SIZE_RANGE: - params[0] = ctx->Const.MinPointSizeAA; - params[1] = ctx->Const.MaxPointSizeAA; - break; - case GL_ALIASED_POINT_SIZE_RANGE: - params[0] = ctx->Const.MinPointSize; - params[1] = ctx->Const.MaxPointSize; - break; - case GL_POINT_SMOOTH: - params[0] = BOOLEAN_TO_FLOAT(ctx->Point.SmoothFlag); - break; - case GL_POINT_SMOOTH_HINT: - params[0] = ENUM_TO_FLOAT(ctx->Hint.PointSmooth); - break; - case GL_POINT_SIZE_MIN_EXT: - params[0] = ctx->Point.MinSize; - break; - case GL_POINT_SIZE_MAX_EXT: - params[0] = ctx->Point.MaxSize; - break; - case GL_POINT_FADE_THRESHOLD_SIZE_EXT: - params[0] = ctx->Point.Threshold; - break; - case GL_DISTANCE_ATTENUATION_EXT: - params[0] = ctx->Point.Params[0]; - params[1] = ctx->Point.Params[1]; - params[2] = ctx->Point.Params[2]; - break; - case GL_POLYGON_MODE: - params[0] = ENUM_TO_FLOAT(ctx->Polygon.FrontMode); - params[1] = ENUM_TO_FLOAT(ctx->Polygon.BackMode); - break; - case GL_POLYGON_OFFSET_BIAS_EXT: - params[0] = ctx->Polygon.OffsetUnits; - break; - case GL_POLYGON_OFFSET_FACTOR: - params[0] = ctx->Polygon.OffsetFactor ; - break; - case GL_POLYGON_OFFSET_UNITS: - params[0] = ctx->Polygon.OffsetUnits ; - break; - case GL_POLYGON_SMOOTH: - params[0] = BOOLEAN_TO_FLOAT(ctx->Polygon.SmoothFlag); - break; - case GL_POLYGON_SMOOTH_HINT: - params[0] = ENUM_TO_FLOAT(ctx->Hint.PolygonSmooth); - break; - case GL_POLYGON_STIPPLE: - params[0] = BOOLEAN_TO_FLOAT(ctx->Polygon.StippleFlag); - break; - case GL_PROJECTION_MATRIX: - { - const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m; - params[0] = matrix[0]; - params[1] = matrix[1]; - params[2] = matrix[2]; - params[3] = matrix[3]; - params[4] = matrix[4]; - params[5] = matrix[5]; - params[6] = matrix[6]; - params[7] = matrix[7]; - params[8] = matrix[8]; - params[9] = matrix[9]; - params[10] = matrix[10]; - params[11] = matrix[11]; - params[12] = matrix[12]; - params[13] = matrix[13]; - params[14] = matrix[14]; - params[15] = matrix[15]; - } - break; - case GL_PROJECTION_STACK_DEPTH: - params[0] = (GLfloat)(ctx->ProjectionMatrixStack.Depth + 1); - break; - case GL_READ_BUFFER: - params[0] = ENUM_TO_FLOAT(ctx->ReadBuffer->ColorReadBuffer); - break; - case GL_RED_BIAS: - params[0] = ctx->Pixel.RedBias; - break; - case GL_RED_BITS: - params[0] = (GLfloat)( ctx->DrawBuffer->Visual.redBits ); - break; - case GL_RED_SCALE: - params[0] = ctx->Pixel.RedScale; - break; - case GL_RENDER_MODE: - params[0] = ENUM_TO_FLOAT(ctx->RenderMode); - break; - case GL_RESCALE_NORMAL: - params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.RescaleNormals); - break; - case GL_RGBA_MODE: - params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.rgbMode); - break; - case GL_SCISSOR_BOX: - params[0] = (GLfloat)(ctx->Scissor.X); - params[1] = (GLfloat)(ctx->Scissor.Y); - params[2] = (GLfloat)(ctx->Scissor.Width); - params[3] = (GLfloat)(ctx->Scissor.Height); - break; - case GL_SCISSOR_TEST: - params[0] = BOOLEAN_TO_FLOAT(ctx->Scissor.Enabled); - break; - case GL_SELECTION_BUFFER_SIZE: - params[0] = (GLfloat)(ctx->Select.BufferSize); - break; - case GL_SHADE_MODEL: - params[0] = ENUM_TO_FLOAT(ctx->Light.ShadeModel); - break; - case GL_SHARED_TEXTURE_PALETTE_EXT: - params[0] = BOOLEAN_TO_FLOAT(ctx->Texture.SharedPalette); - break; - case GL_STENCIL_BITS: - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.stencilBits); - break; - case GL_STENCIL_CLEAR_VALUE: - params[0] = (GLfloat)(ctx->Stencil.Clear); - break; - case GL_STENCIL_FAIL: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_FUNC: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_PASS_DEPTH_FAIL: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_PASS_DEPTH_PASS: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_REF: - params[0] = (GLfloat)(ctx->Stencil.Ref[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_TEST: - params[0] = BOOLEAN_TO_FLOAT(ctx->Stencil.Enabled); - break; - case GL_STENCIL_VALUE_MASK: - params[0] = (GLfloat)(ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_WRITEMASK: - params[0] = (GLfloat)(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]); - break; - case GL_STEREO: - params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.stereoMode); - break; - case GL_SUBPIXEL_BITS: - params[0] = (GLfloat)(ctx->Const.SubPixelBits); - break; - case GL_TEXTURE_1D: - params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_1D)); - break; - case GL_TEXTURE_2D: - params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_2D)); - break; - case GL_TEXTURE_3D: - params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_3D)); - break; - case GL_TEXTURE_BINDING_1D: - params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name); - break; - case GL_TEXTURE_BINDING_2D: - params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2D->Name); - break; - case GL_TEXTURE_BINDING_3D: - params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name); - break; - case GL_TEXTURE_ENV_COLOR: - { - const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor; - params[0] = color[0]; - params[1] = color[1]; - params[2] = color[2]; - params[3] = color[3]; - } - break; - case GL_TEXTURE_ENV_MODE: - params[0] = ENUM_TO_FLOAT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvMode); - break; - case GL_TEXTURE_GEN_S: - params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_GEN_T: - params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_GEN_R: - params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_GEN_Q: - params[0] = BOOLEAN_TO_FLOAT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_MATRIX: - { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; - params[0] = matrix[0]; - params[1] = matrix[1]; - params[2] = matrix[2]; - params[3] = matrix[3]; - params[4] = matrix[4]; - params[5] = matrix[5]; - params[6] = matrix[6]; - params[7] = matrix[7]; - params[8] = matrix[8]; - params[9] = matrix[9]; - params[10] = matrix[10]; - params[11] = matrix[11]; - params[12] = matrix[12]; - params[13] = matrix[13]; - params[14] = matrix[14]; - params[15] = matrix[15]; - } - break; - case GL_TEXTURE_STACK_DEPTH: - params[0] = (GLfloat)(ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1); - break; - case GL_UNPACK_ALIGNMENT: - params[0] = (GLfloat)(ctx->Unpack.Alignment); - break; - case GL_UNPACK_LSB_FIRST: - params[0] = BOOLEAN_TO_FLOAT(ctx->Unpack.LsbFirst); - break; - case GL_UNPACK_ROW_LENGTH: - params[0] = (GLfloat)(ctx->Unpack.RowLength); - break; - case GL_UNPACK_SKIP_PIXELS: - params[0] = (GLfloat)(ctx->Unpack.SkipPixels); - break; - case GL_UNPACK_SKIP_ROWS: - params[0] = (GLfloat)(ctx->Unpack.SkipRows); - break; - case GL_UNPACK_SWAP_BYTES: - params[0] = BOOLEAN_TO_FLOAT(ctx->Unpack.SwapBytes); - break; - case GL_UNPACK_SKIP_IMAGES_EXT: - params[0] = (GLfloat)(ctx->Unpack.SkipImages); - break; - case GL_UNPACK_IMAGE_HEIGHT_EXT: - params[0] = (GLfloat)(ctx->Unpack.ImageHeight); - break; - case GL_UNPACK_CLIENT_STORAGE_APPLE: - params[0] = BOOLEAN_TO_FLOAT(ctx->Unpack.ClientStorage); - break; - case GL_VIEWPORT: - params[0] = (GLfloat)(ctx->Viewport.X); - params[1] = (GLfloat)(ctx->Viewport.Y); - params[2] = (GLfloat)(ctx->Viewport.Width); - params[3] = (GLfloat)(ctx->Viewport.Height); - break; - case GL_ZOOM_X: - params[0] = ctx->Pixel.ZoomX; - break; - case GL_ZOOM_Y: - params[0] = ctx->Pixel.ZoomY; - break; - case GL_VERTEX_ARRAY: - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->Vertex.Enabled); - break; - case GL_VERTEX_ARRAY_SIZE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->Vertex.Size); - break; - case GL_VERTEX_ARRAY_TYPE: - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->Vertex.Type); - break; - case GL_VERTEX_ARRAY_STRIDE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->Vertex.Stride); - break; - case GL_VERTEX_ARRAY_COUNT_EXT: - params[0] = (GLfloat)(0); - break; - case GL_NORMAL_ARRAY: - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->Normal.Enabled); - break; - case GL_NORMAL_ARRAY_TYPE: - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->Normal.Type); - break; - case GL_NORMAL_ARRAY_STRIDE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->Normal.Stride); - break; - case GL_NORMAL_ARRAY_COUNT_EXT: - params[0] = (GLfloat)(0); - break; - case GL_COLOR_ARRAY: - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->Color.Enabled); - break; - case GL_COLOR_ARRAY_SIZE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->Color.Size); - break; - case GL_COLOR_ARRAY_TYPE: - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->Color.Type); - break; - case GL_COLOR_ARRAY_STRIDE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->Color.Stride); - break; - case GL_COLOR_ARRAY_COUNT_EXT: - params[0] = (GLfloat)(0); - break; - case GL_INDEX_ARRAY: - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->Index.Enabled); - break; - case GL_INDEX_ARRAY_TYPE: - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->Index.Type); - break; - case GL_INDEX_ARRAY_STRIDE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->Index.Stride); - break; - case GL_INDEX_ARRAY_COUNT_EXT: - params[0] = (GLfloat)(0); - break; - case GL_TEXTURE_COORD_ARRAY: - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled); - break; - case GL_TEXTURE_COORD_ARRAY_SIZE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Size); - break; - case GL_TEXTURE_COORD_ARRAY_TYPE: - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Type); - break; - case GL_TEXTURE_COORD_ARRAY_STRIDE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Stride); - break; - case GL_TEXTURE_COORD_ARRAY_COUNT_EXT: - params[0] = (GLfloat)(0); - break; - case GL_EDGE_FLAG_ARRAY: - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->EdgeFlag.Enabled); - break; - case GL_EDGE_FLAG_ARRAY_STRIDE: - params[0] = (GLfloat)(ctx->Array.ArrayObj->EdgeFlag.Stride); - break; - case GL_EDGE_FLAG_ARRAY_COUNT_EXT: - params[0] = (GLfloat)(0); - break; - case GL_MAX_TEXTURE_UNITS_ARB: - CHECK_EXT1(ARB_multitexture, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxTextureUnits); - break; - case GL_ACTIVE_TEXTURE_ARB: - CHECK_EXT1(ARB_multitexture, "GetFloatv"); - params[0] = (GLfloat)(GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit); - break; - case GL_CLIENT_ACTIVE_TEXTURE_ARB: - CHECK_EXT1(ARB_multitexture, "GetFloatv"); - params[0] = (GLfloat)(GL_TEXTURE0_ARB + ctx->Array.ActiveTexture); - break; - case GL_TEXTURE_CUBE_MAP_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB)); - break; - case GL_TEXTURE_BINDING_CUBE_MAP_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetFloatv"); - params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap->Name); - break; - case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetFloatv"); - params[0] = (GLfloat)((1 << (ctx->Const.MaxCubeTextureLevels - 1))); - break; - case GL_TEXTURE_COMPRESSION_HINT_ARB: - CHECK_EXT1(ARB_texture_compression, "GetFloatv"); - params[0] = (GLfloat)(ctx->Hint.TextureCompression); - break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: - CHECK_EXT1(ARB_texture_compression, "GetFloatv"); - params[0] = (GLfloat)(_mesa_get_compressed_formats(ctx, NULL, GL_FALSE)); - break; - case GL_COMPRESSED_TEXTURE_FORMATS_ARB: - CHECK_EXT1(ARB_texture_compression, "GetFloatv"); - { - GLint formats[100]; - GLuint i, n = _mesa_get_compressed_formats(ctx, formats, GL_FALSE); - ASSERT(n <= 100); - for (i = 0; i < n; i++) - params[i] = ENUM_TO_INT(formats[i]); - } - break; - case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT: - CHECK_EXT1(EXT_compiled_vertex_array, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.LockFirst); - break; - case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT: - CHECK_EXT1(EXT_compiled_vertex_array, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.LockCount); - break; - case GL_TRANSPOSE_COLOR_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ColorMatrixStack.Top->m; - params[0] = matrix[0]; - params[1] = matrix[4]; - params[2] = matrix[8]; - params[3] = matrix[12]; - params[4] = matrix[1]; - params[5] = matrix[5]; - params[6] = matrix[9]; - params[7] = matrix[13]; - params[8] = matrix[2]; - params[9] = matrix[6]; - params[10] = matrix[10]; - params[11] = matrix[14]; - params[12] = matrix[3]; - params[13] = matrix[7]; - params[14] = matrix[11]; - params[15] = matrix[15]; - } - break; - case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m; - params[0] = matrix[0]; - params[1] = matrix[4]; - params[2] = matrix[8]; - params[3] = matrix[12]; - params[4] = matrix[1]; - params[5] = matrix[5]; - params[6] = matrix[9]; - params[7] = matrix[13]; - params[8] = matrix[2]; - params[9] = matrix[6]; - params[10] = matrix[10]; - params[11] = matrix[14]; - params[12] = matrix[3]; - params[13] = matrix[7]; - params[14] = matrix[11]; - params[15] = matrix[15]; - } - break; - case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m; - params[0] = matrix[0]; - params[1] = matrix[4]; - params[2] = matrix[8]; - params[3] = matrix[12]; - params[4] = matrix[1]; - params[5] = matrix[5]; - params[6] = matrix[9]; - params[7] = matrix[13]; - params[8] = matrix[2]; - params[9] = matrix[6]; - params[10] = matrix[10]; - params[11] = matrix[14]; - params[12] = matrix[3]; - params[13] = matrix[7]; - params[14] = matrix[11]; - params[15] = matrix[15]; - } - break; - case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: - { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; - params[0] = matrix[0]; - params[1] = matrix[4]; - params[2] = matrix[8]; - params[3] = matrix[12]; - params[4] = matrix[1]; - params[5] = matrix[5]; - params[6] = matrix[9]; - params[7] = matrix[13]; - params[8] = matrix[2]; - params[9] = matrix[6]; - params[10] = matrix[10]; - params[11] = matrix[14]; - params[12] = matrix[3]; - params[13] = matrix[7]; - params[14] = matrix[11]; - params[15] = matrix[15]; - } - break; - case GL_COLOR_MATRIX_SGI: - { - const GLfloat *matrix = ctx->ColorMatrixStack.Top->m; - params[0] = matrix[0]; - params[1] = matrix[1]; - params[2] = matrix[2]; - params[3] = matrix[3]; - params[4] = matrix[4]; - params[5] = matrix[5]; - params[6] = matrix[6]; - params[7] = matrix[7]; - params[8] = matrix[8]; - params[9] = matrix[9]; - params[10] = matrix[10]; - params[11] = matrix[11]; - params[12] = matrix[12]; - params[13] = matrix[13]; - params[14] = matrix[14]; - params[15] = matrix[15]; - } - break; - case GL_COLOR_MATRIX_STACK_DEPTH_SGI: - params[0] = (GLfloat)(ctx->ColorMatrixStack.Depth + 1); - break; - case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI: - params[0] = (GLfloat)(MAX_COLOR_STACK_DEPTH); - break; - case GL_POST_COLOR_MATRIX_RED_SCALE_SGI: - params[0] = ctx->Pixel.PostColorMatrixScale[0]; - break; - case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI: - params[0] = ctx->Pixel.PostColorMatrixScale[1]; - break; - case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI: - params[0] = ctx->Pixel.PostColorMatrixScale[2]; - break; - case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI: - params[0] = ctx->Pixel.PostColorMatrixScale[3]; - break; - case GL_POST_COLOR_MATRIX_RED_BIAS_SGI: - params[0] = ctx->Pixel.PostColorMatrixBias[0]; - break; - case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI: - params[0] = ctx->Pixel.PostColorMatrixBias[1]; - break; - case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI: - params[0] = ctx->Pixel.PostColorMatrixBias[2]; - break; - case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI: - params[0] = ctx->Pixel.PostColorMatrixBias[3]; - break; - case GL_CONVOLUTION_1D_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.Convolution1DEnabled); - break; - case GL_CONVOLUTION_2D_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.Convolution2DEnabled); - break; - case GL_SEPARABLE_2D_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.Separable2DEnabled); - break; - case GL_POST_CONVOLUTION_RED_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionScale[0]; - break; - case GL_POST_CONVOLUTION_GREEN_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionScale[1]; - break; - case GL_POST_CONVOLUTION_BLUE_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionScale[2]; - break; - case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionScale[3]; - break; - case GL_POST_CONVOLUTION_RED_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionBias[0]; - break; - case GL_POST_CONVOLUTION_GREEN_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionBias[1]; - break; - case GL_POST_CONVOLUTION_BLUE_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionBias[2]; - break; - case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetFloatv"); - params[0] = ctx->Pixel.PostConvolutionBias[3]; - break; - case GL_HISTOGRAM: - CHECK_EXT1(EXT_histogram, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.HistogramEnabled); - break; - case GL_MINMAX: - CHECK_EXT1(EXT_histogram, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.MinMaxEnabled); - break; - case GL_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.ColorTableEnabled); - break; - case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.PostConvolutionColorTableEnabled); - break; - case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Pixel.PostColorMatrixColorTableEnabled); - break; - case GL_TEXTURE_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_texture_color_table, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled); - break; - case GL_COLOR_SUM_EXT: - CHECK_EXT2(EXT_secondary_color, ARB_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Fog.ColorSumEnabled); - break; - case GL_CURRENT_SECONDARY_COLOR_EXT: - CHECK_EXT1(EXT_secondary_color, "GetFloatv"); - { - FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0]; - params[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1]; - params[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2]; - params[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3]; - } - break; - case GL_SECONDARY_COLOR_ARRAY_EXT: - CHECK_EXT1(EXT_secondary_color, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->SecondaryColor.Enabled); - break; - case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->SecondaryColor.Type); - break; - case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->SecondaryColor.Stride); - break; - case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->SecondaryColor.Size); - break; - case GL_CURRENT_FOG_COORDINATE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetFloatv"); - { - FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; - } - break; - case GL_FOG_COORDINATE_ARRAY_EXT: - CHECK_EXT1(EXT_fog_coord, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->FogCoord.Enabled); - break; - case GL_FOG_COORDINATE_ARRAY_TYPE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Array.ArrayObj->FogCoord.Type); - break; - case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->FogCoord.Stride); - break; - case GL_FOG_COORDINATE_SOURCE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Fog.FogCoordinateSource); - break; - case GL_MAX_TEXTURE_LOD_BIAS_EXT: - CHECK_EXT1(EXT_texture_lod_bias, "GetFloatv"); - params[0] = ctx->Const.MaxTextureLodBias; - break; - case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: - CHECK_EXT1(EXT_texture_filter_anisotropic, "GetFloatv"); - params[0] = ctx->Const.MaxTextureMaxAnisotropy; - break; - case GL_MULTISAMPLE_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.Enabled); - break; - case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleAlphaToCoverage); - break; - case GL_SAMPLE_ALPHA_TO_ONE_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleAlphaToOne); - break; - case GL_SAMPLE_COVERAGE_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleCoverage); - break; - case GL_SAMPLE_COVERAGE_VALUE_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = ctx->Multisample.SampleCoverageValue; - break; - case GL_SAMPLE_COVERAGE_INVERT_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Multisample.SampleCoverageInvert); - break; - case GL_SAMPLE_BUFFERS_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.sampleBuffers); - break; - case GL_SAMPLES_ARB: - CHECK_EXT1(ARB_multisample, "GetFloatv"); - params[0] = (GLfloat)(ctx->DrawBuffer->Visual.samples); - break; - case GL_RASTER_POSITION_UNCLIPPED_IBM: - CHECK_EXT1(IBM_rasterpos_clip, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.RasterPositionUnclipped); - break; - case GL_POINT_SPRITE_NV: - CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Point.PointSprite); - break; - case GL_POINT_SPRITE_R_MODE_NV: - CHECK_EXT1(NV_point_sprite, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Point.SpriteRMode); - break; - case GL_POINT_SPRITE_COORD_ORIGIN: - CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Point.SpriteOrigin); - break; - case GL_GENERATE_MIPMAP_HINT_SGIS: - CHECK_EXT1(SGIS_generate_mipmap, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Hint.GenerateMipmap); - break; - case GL_VERTEX_PROGRAM_BINDING_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = (GLfloat)((ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0)); - break; - case GL_VERTEX_ATTRIB_ARRAY0_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[0].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY1_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[1].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY2_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[2].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY3_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[3].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[4].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY5_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[5].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY6_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[6].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY7_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[7].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY8_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[8].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY9_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[9].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY10_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[10].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY11_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[11].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY12_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[12].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY13_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[13].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY14_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[14].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY15_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Array.ArrayObj->VertexAttrib[15].Enabled); - break; - case GL_MAP1_VERTEX_ATTRIB0_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[0]); - break; - case GL_MAP1_VERTEX_ATTRIB1_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[1]); - break; - case GL_MAP1_VERTEX_ATTRIB2_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[2]); - break; - case GL_MAP1_VERTEX_ATTRIB3_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[3]); - break; - case GL_MAP1_VERTEX_ATTRIB4_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[4]); - break; - case GL_MAP1_VERTEX_ATTRIB5_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[5]); - break; - case GL_MAP1_VERTEX_ATTRIB6_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[6]); - break; - case GL_MAP1_VERTEX_ATTRIB7_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[7]); - break; - case GL_MAP1_VERTEX_ATTRIB8_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[8]); - break; - case GL_MAP1_VERTEX_ATTRIB9_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[9]); - break; - case GL_MAP1_VERTEX_ATTRIB10_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[10]); - break; - case GL_MAP1_VERTEX_ATTRIB11_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[11]); - break; - case GL_MAP1_VERTEX_ATTRIB12_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[12]); - break; - case GL_MAP1_VERTEX_ATTRIB13_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[13]); - break; - case GL_MAP1_VERTEX_ATTRIB14_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[14]); - break; - case GL_MAP1_VERTEX_ATTRIB15_4_NV: - CHECK_EXT1(NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.Map1Attrib[15]); - break; - case GL_FRAGMENT_PROGRAM_NV: - CHECK_EXT1(NV_fragment_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->FragmentProgram.Enabled); - break; - case GL_FRAGMENT_PROGRAM_BINDING_NV: - CHECK_EXT1(NV_fragment_program, "GetFloatv"); - params[0] = (GLfloat)(ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0); - break; - case GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV: - CHECK_EXT1(NV_fragment_program, "GetFloatv"); - params[0] = (GLfloat)(MAX_NV_FRAGMENT_PROGRAM_PARAMS); - break; - case GL_TEXTURE_RECTANGLE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(_mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV)); - break; - case GL_TEXTURE_BINDING_RECTANGLE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetFloatv"); - params[0] = (GLfloat)(ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentRect->Name); - break; - case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxTextureRectSize); - break; - case GL_STENCIL_TEST_TWO_SIDE_EXT: - CHECK_EXT1(EXT_stencil_two_side, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Stencil.TestTwoSide); - break; - case GL_ACTIVE_STENCIL_FACE_EXT: - CHECK_EXT1(EXT_stencil_two_side, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT); - break; - case GL_MAX_SHININESS_NV: - CHECK_EXT1(NV_light_max_exponent, "GetFloatv"); - params[0] = ctx->Const.MaxShininess; - break; - case GL_MAX_SPOT_EXPONENT_NV: - CHECK_EXT1(NV_light_max_exponent, "GetFloatv"); - params[0] = ctx->Const.MaxSpotExponent; - break; - case GL_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayBufferObj->Name); - break; - case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->Vertex.BufferObj->Name); - break; - case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->Normal.BufferObj->Name); - break; - case GL_COLOR_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->Color.BufferObj->Name); - break; - case GL_INDEX_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->Index.BufferObj->Name); - break; - case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name); - break; - case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->EdgeFlag.BufferObj->Name); - break; - case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->SecondaryColor.BufferObj->Name); - break; - case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ArrayObj->FogCoord.BufferObj->Name); - break; - case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Array.ElementArrayBufferObj->Name); - break; - case GL_PIXEL_PACK_BUFFER_BINDING_EXT: - CHECK_EXT1(EXT_pixel_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Pack.BufferObj->Name); - break; - case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT: - CHECK_EXT1(EXT_pixel_buffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Unpack.BufferObj->Name); - break; - case GL_VERTEX_PROGRAM_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.Enabled); - break; - case GL_VERTEX_PROGRAM_POINT_SIZE_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.PointSizeEnabled); - break; - case GL_VERTEX_PROGRAM_TWO_SIDE_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.TwoSideEnabled); - break; - case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxProgramMatrixStackDepth); - break; - case GL_MAX_PROGRAM_MATRICES_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxProgramMatrices); - break; - case GL_CURRENT_MATRIX_STACK_DEPTH_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->CurrentStack->Depth + 1); - break; - case GL_CURRENT_MATRIX_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_fragment_program, "GetFloatv"); - { - const GLfloat *matrix = ctx->CurrentStack->Top->m; - params[0] = matrix[0]; - params[1] = matrix[1]; - params[2] = matrix[2]; - params[3] = matrix[3]; - params[4] = matrix[4]; - params[5] = matrix[5]; - params[6] = matrix[6]; - params[7] = matrix[7]; - params[8] = matrix[8]; - params[9] = matrix[9]; - params[10] = matrix[10]; - params[11] = matrix[11]; - params[12] = matrix[12]; - params[13] = matrix[13]; - params[14] = matrix[14]; - params[15] = matrix[15]; - } - break; - case GL_TRANSPOSE_CURRENT_MATRIX_ARB: - CHECK_EXT2(ARB_vertex_program, ARB_fragment_program, "GetFloatv"); - { - const GLfloat *matrix = ctx->CurrentStack->Top->m; - params[0] = matrix[0]; - params[1] = matrix[4]; - params[2] = matrix[8]; - params[3] = matrix[12]; - params[4] = matrix[1]; - params[5] = matrix[5]; - params[6] = matrix[9]; - params[7] = matrix[13]; - params[8] = matrix[2]; - params[9] = matrix[6]; - params[10] = matrix[10]; - params[11] = matrix[14]; - params[12] = matrix[3]; - params[13] = matrix[7]; - params[14] = matrix[11]; - params[15] = matrix[15]; - } - break; - case GL_MAX_VERTEX_ATTRIBS_ARB: - CHECK_EXT1(ARB_vertex_program, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.VertexProgram.MaxAttribs); - break; - case GL_PROGRAM_ERROR_POSITION_ARB: - CHECK_EXT4(NV_vertex_program, ARB_vertex_program, NV_fragment_program, ARB_fragment_program, "GetFloatv"); - params[0] = (GLfloat)(ctx->Program.ErrorPos); - break; - case GL_FRAGMENT_PROGRAM_ARB: - CHECK_EXT1(ARB_fragment_program, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->FragmentProgram.Enabled); - break; - case GL_MAX_TEXTURE_COORDS_ARB: - CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxTextureCoordUnits); - break; - case GL_MAX_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxTextureImageUnits); - break; - case GL_DEPTH_BOUNDS_TEST_EXT: - CHECK_EXT1(EXT_depth_bounds_test, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->Depth.BoundsTest); - break; - case GL_DEPTH_BOUNDS_EXT: - CHECK_EXT1(EXT_depth_bounds_test, "GetFloatv"); - params[0] = ctx->Depth.BoundsMin; - params[1] = ctx->Depth.BoundsMax; - break; - case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: - CHECK_EXT1(MESA_program_debug, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->FragmentProgram.CallbackEnabled); - break; - case GL_VERTEX_PROGRAM_CALLBACK_MESA: - CHECK_EXT1(MESA_program_debug, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(ctx->VertexProgram.CallbackEnabled); - break; - case GL_FRAGMENT_PROGRAM_POSITION_MESA: - CHECK_EXT1(MESA_program_debug, "GetFloatv"); - params[0] = (GLfloat)(ctx->FragmentProgram.CurrentPosition); - break; - case GL_VERTEX_PROGRAM_POSITION_MESA: - CHECK_EXT1(MESA_program_debug, "GetFloatv"); - params[0] = (GLfloat)(ctx->VertexProgram.CurrentPosition); - break; - case GL_MAX_DRAW_BUFFERS_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxDrawBuffers); - break; - case GL_DRAW_BUFFER0_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->DrawBuffer->ColorDrawBuffer[0]); - break; - case GL_DRAW_BUFFER1_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetFloatv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[1]; - params[0] = ENUM_TO_FLOAT(buffer); - } - break; - case GL_DRAW_BUFFER2_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetFloatv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[2]; - params[0] = ENUM_TO_FLOAT(buffer); - } - break; - case GL_DRAW_BUFFER3_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetFloatv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[3]; - params[0] = ENUM_TO_FLOAT(buffer); - } - break; - case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: - CHECK_EXT1(OES_read_format, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.ColorReadType); - break; - case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: - CHECK_EXT1(OES_read_format, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.ColorReadFormat); - break; - case GL_NUM_FRAGMENT_REGISTERS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(6); - break; - case GL_NUM_FRAGMENT_CONSTANTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(8); - break; - case GL_NUM_PASSES_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(2); - break; - case GL_NUM_INSTRUCTIONS_PER_PASS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(8); - break; - case GL_NUM_INSTRUCTIONS_TOTAL_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(16); - break; - case GL_COLOR_ALPHA_PAIRING_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = BOOLEAN_TO_FLOAT(GL_TRUE); - break; - case GL_NUM_LOOPBACK_COMPONENTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(3); - break; - case GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(3); - break; - case GL_STENCIL_BACK_FUNC: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.Function[1]); - break; - case GL_STENCIL_BACK_VALUE_MASK: - params[0] = (GLfloat)(ctx->Stencil.ValueMask[1]); - break; - case GL_STENCIL_BACK_REF: - params[0] = (GLfloat)(ctx->Stencil.Ref[1]); - break; - case GL_STENCIL_BACK_FAIL: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.FailFunc[1]); - break; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc[1]); - break; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - params[0] = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc[1]); - break; - case GL_FRAMEBUFFER_BINDING_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->DrawBuffer->Name); - break; - case GL_RENDERBUFFER_BINDING_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0); - break; - case GL_MAX_COLOR_ATTACHMENTS_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxColorAttachments); - break; - case GL_MAX_RENDERBUFFER_SIZE_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxRenderbufferSize); - break; - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: - CHECK_EXT1(ARB_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_FRAGMENT_UNIFORM_COMPONENTS); - break; - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: - CHECK_EXT1(ARB_fragment_shader, "GetFloatv"); - params[0] = ENUM_TO_FLOAT(ctx->Hint.FragmentShaderDerivative); - break; - case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VERTEX_UNIFORM_COMPONENTS); - break; - case GL_MAX_VARYING_FLOATS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VARYING_FLOATS); - break; - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VERTEX_TEXTURE_IMAGE_UNITS); - break; - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_COMBINED_TEXTURE_IMAGE_UNITS); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(pname=0x%x)", pname); - } -} - -void GLAPIENTRY -_mesa_GetIntegerv( GLenum pname, GLint *params ) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (!params) - return; - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (ctx->Driver.GetIntegerv && - ctx->Driver.GetIntegerv(ctx, pname, params)) - return; - - switch (pname) { - case GL_ACCUM_RED_BITS: - params[0] = ctx->DrawBuffer->Visual.accumRedBits; - break; - case GL_ACCUM_GREEN_BITS: - params[0] = ctx->DrawBuffer->Visual.accumGreenBits; - break; - case GL_ACCUM_BLUE_BITS: - params[0] = ctx->DrawBuffer->Visual.accumBlueBits; - break; - case GL_ACCUM_ALPHA_BITS: - params[0] = ctx->DrawBuffer->Visual.accumAlphaBits; - break; - case GL_ACCUM_CLEAR_VALUE: - params[0] = FLOAT_TO_INT(ctx->Accum.ClearColor[0]); - params[1] = FLOAT_TO_INT(ctx->Accum.ClearColor[1]); - params[2] = FLOAT_TO_INT(ctx->Accum.ClearColor[2]); - params[3] = FLOAT_TO_INT(ctx->Accum.ClearColor[3]); - break; - case GL_ALPHA_BIAS: - params[0] = IROUND(ctx->Pixel.AlphaBias); - break; - case GL_ALPHA_BITS: - params[0] = ctx->DrawBuffer->Visual.alphaBits; - break; - case GL_ALPHA_SCALE: - params[0] = IROUND(ctx->Pixel.AlphaScale); - break; - case GL_ALPHA_TEST: - params[0] = BOOLEAN_TO_INT(ctx->Color.AlphaEnabled); - break; - case GL_ALPHA_TEST_FUNC: - params[0] = ENUM_TO_INT(ctx->Color.AlphaFunc); - break; - case GL_ALPHA_TEST_REF: - params[0] = FLOAT_TO_INT(ctx->Color.AlphaRef); - break; - case GL_ATTRIB_STACK_DEPTH: - params[0] = ctx->AttribStackDepth; - break; - case GL_AUTO_NORMAL: - params[0] = BOOLEAN_TO_INT(ctx->Eval.AutoNormal); - break; - case GL_AUX_BUFFERS: - params[0] = ctx->DrawBuffer->Visual.numAuxBuffers; - break; - case GL_BLEND: - params[0] = BOOLEAN_TO_INT(ctx->Color.BlendEnabled); - break; - case GL_BLEND_DST: - params[0] = ENUM_TO_INT(ctx->Color.BlendDstRGB); - break; - case GL_BLEND_SRC: - params[0] = ENUM_TO_INT(ctx->Color.BlendSrcRGB); - break; - case GL_BLEND_SRC_RGB_EXT: - params[0] = ENUM_TO_INT(ctx->Color.BlendSrcRGB); - break; - case GL_BLEND_DST_RGB_EXT: - params[0] = ENUM_TO_INT(ctx->Color.BlendDstRGB); - break; - case GL_BLEND_SRC_ALPHA_EXT: - params[0] = ENUM_TO_INT(ctx->Color.BlendSrcA); - break; - case GL_BLEND_DST_ALPHA_EXT: - params[0] = ENUM_TO_INT(ctx->Color.BlendDstA); - break; - case GL_BLEND_EQUATION: - params[0] = ENUM_TO_INT(ctx->Color.BlendEquationRGB ); - break; - case GL_BLEND_EQUATION_ALPHA_EXT: - params[0] = ENUM_TO_INT(ctx->Color.BlendEquationA ); - break; - case GL_BLEND_COLOR_EXT: - params[0] = FLOAT_TO_INT(ctx->Color.BlendColor[0]); - params[1] = FLOAT_TO_INT(ctx->Color.BlendColor[1]); - params[2] = FLOAT_TO_INT(ctx->Color.BlendColor[2]); - params[3] = FLOAT_TO_INT(ctx->Color.BlendColor[3]); - break; - case GL_BLUE_BIAS: - params[0] = IROUND(ctx->Pixel.BlueBias); - break; - case GL_BLUE_BITS: - params[0] = ctx->DrawBuffer->Visual.blueBits; - break; - case GL_BLUE_SCALE: - params[0] = IROUND(ctx->Pixel.BlueScale); - break; - case GL_CLIENT_ATTRIB_STACK_DEPTH: - params[0] = ctx->ClientAttribStackDepth; - break; - case GL_CLIP_PLANE0: - params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 0) & 1); - break; - case GL_CLIP_PLANE1: - params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 1) & 1); - break; - case GL_CLIP_PLANE2: - params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 2) & 1); - break; - case GL_CLIP_PLANE3: - params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 3) & 1); - break; - case GL_CLIP_PLANE4: - params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 4) & 1); - break; - case GL_CLIP_PLANE5: - params[0] = BOOLEAN_TO_INT((ctx->Transform.ClipPlanesEnabled >> 5) & 1); - break; - case GL_COLOR_CLEAR_VALUE: - params[0] = FLOAT_TO_INT(ctx->Color.ClearColor[0]); - params[1] = FLOAT_TO_INT(ctx->Color.ClearColor[1]); - params[2] = FLOAT_TO_INT(ctx->Color.ClearColor[2]); - params[3] = FLOAT_TO_INT(ctx->Color.ClearColor[3]); - break; - case GL_COLOR_MATERIAL: - params[0] = BOOLEAN_TO_INT(ctx->Light.ColorMaterialEnabled); - break; - case GL_COLOR_MATERIAL_FACE: - params[0] = ENUM_TO_INT(ctx->Light.ColorMaterialFace); - break; - case GL_COLOR_MATERIAL_PARAMETER: - params[0] = ENUM_TO_INT(ctx->Light.ColorMaterialMode); - break; - case GL_COLOR_WRITEMASK: - params[0] = ctx->Color.ColorMask[RCOMP] ? 1 : 0; - params[1] = ctx->Color.ColorMask[GCOMP] ? 1 : 0; - params[2] = ctx->Color.ColorMask[BCOMP] ? 1 : 0; - params[3] = ctx->Color.ColorMask[ACOMP] ? 1 : 0; - break; - case GL_CULL_FACE: - params[0] = BOOLEAN_TO_INT(ctx->Polygon.CullFlag); - break; - case GL_CULL_FACE_MODE: - params[0] = ENUM_TO_INT(ctx->Polygon.CullFaceMode); - break; - case GL_CURRENT_COLOR: - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]); - params[1] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]); - params[2] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]); - params[3] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]); - } - break; - case GL_CURRENT_INDEX: - { - FLUSH_CURRENT(ctx, 0); - params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]); - } - break; - case GL_CURRENT_NORMAL: - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]); - params[1] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]); - params[2] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]); - } - break; - case GL_CURRENT_RASTER_COLOR: - params[0] = FLOAT_TO_INT(ctx->Current.RasterColor[0]); - params[1] = FLOAT_TO_INT(ctx->Current.RasterColor[1]); - params[2] = FLOAT_TO_INT(ctx->Current.RasterColor[2]); - params[3] = FLOAT_TO_INT(ctx->Current.RasterColor[3]); - break; - case GL_CURRENT_RASTER_DISTANCE: - params[0] = IROUND(ctx->Current.RasterDistance); - break; - case GL_CURRENT_RASTER_INDEX: - params[0] = IROUND(ctx->Current.RasterIndex); - break; - case GL_CURRENT_RASTER_POSITION: - params[0] = IROUND(ctx->Current.RasterPos[0]); - params[1] = IROUND(ctx->Current.RasterPos[1]); - params[2] = IROUND(ctx->Current.RasterPos[2]); - params[3] = IROUND(ctx->Current.RasterPos[3]); - break; - case GL_CURRENT_RASTER_SECONDARY_COLOR: - params[0] = FLOAT_TO_INT(ctx->Current.RasterSecondaryColor[0]); - params[1] = FLOAT_TO_INT(ctx->Current.RasterSecondaryColor[1]); - params[2] = FLOAT_TO_INT(ctx->Current.RasterSecondaryColor[2]); - params[3] = FLOAT_TO_INT(ctx->Current.RasterSecondaryColor[3]); - break; - case GL_CURRENT_RASTER_TEXTURE_COORDS: - { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = IROUND(ctx->Current.RasterTexCoords[texUnit][0]); - params[1] = IROUND(ctx->Current.RasterTexCoords[texUnit][1]); - params[2] = IROUND(ctx->Current.RasterTexCoords[texUnit][2]); - params[3] = IROUND(ctx->Current.RasterTexCoords[texUnit][3]); - } - break; - case GL_CURRENT_RASTER_POSITION_VALID: - params[0] = BOOLEAN_TO_INT(ctx->Current.RasterPosValid); - break; - case GL_CURRENT_TEXTURE_COORDS: - { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]); - params[1] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]); - params[2] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]); - params[3] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]); - } - break; - case GL_DEPTH_BIAS: - params[0] = IROUND(ctx->Pixel.DepthBias); - break; - case GL_DEPTH_BITS: - params[0] = ctx->DrawBuffer->Visual.depthBits; - break; - case GL_DEPTH_CLEAR_VALUE: - params[0] = IROUND(ctx->Depth.Clear); - break; - case GL_DEPTH_FUNC: - params[0] = ENUM_TO_INT(ctx->Depth.Func); - break; - case GL_DEPTH_RANGE: - params[0] = FLOAT_TO_INT(ctx->Viewport.Near); - params[1] = FLOAT_TO_INT(ctx->Viewport.Far); - break; - case GL_DEPTH_SCALE: - params[0] = IROUND(ctx->Pixel.DepthScale); - break; - case GL_DEPTH_TEST: - params[0] = BOOLEAN_TO_INT(ctx->Depth.Test); - break; - case GL_DEPTH_WRITEMASK: - params[0] = BOOLEAN_TO_INT(ctx->Depth.Mask); - break; - case GL_DITHER: - params[0] = BOOLEAN_TO_INT(ctx->Color.DitherFlag); - break; - case GL_DOUBLEBUFFER: - params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.doubleBufferMode); - break; - case GL_DRAW_BUFFER: - params[0] = ENUM_TO_INT(ctx->DrawBuffer->ColorDrawBuffer[0]); - break; - case GL_EDGE_FLAG: - { - FLUSH_CURRENT(ctx, 0); - params[0] = BOOLEAN_TO_INT(ctx->Current.EdgeFlag); - } - break; - case GL_FEEDBACK_BUFFER_SIZE: - params[0] = ctx->Feedback.BufferSize; - break; - case GL_FEEDBACK_BUFFER_TYPE: - params[0] = ENUM_TO_INT(ctx->Feedback.Type); - break; - case GL_FOG: - params[0] = BOOLEAN_TO_INT(ctx->Fog.Enabled); - break; - case GL_FOG_COLOR: - params[0] = FLOAT_TO_INT(ctx->Fog.Color[0]); - params[1] = FLOAT_TO_INT(ctx->Fog.Color[1]); - params[2] = FLOAT_TO_INT(ctx->Fog.Color[2]); - params[3] = FLOAT_TO_INT(ctx->Fog.Color[3]); - break; - case GL_FOG_DENSITY: - params[0] = IROUND(ctx->Fog.Density); - break; - case GL_FOG_END: - params[0] = IROUND(ctx->Fog.End); - break; - case GL_FOG_HINT: - params[0] = ENUM_TO_INT(ctx->Hint.Fog); - break; - case GL_FOG_INDEX: - params[0] = IROUND(ctx->Fog.Index); - break; - case GL_FOG_MODE: - params[0] = ENUM_TO_INT(ctx->Fog.Mode); - break; - case GL_FOG_START: - params[0] = IROUND(ctx->Fog.Start); - break; - case GL_FRONT_FACE: - params[0] = ENUM_TO_INT(ctx->Polygon.FrontFace); - break; - case GL_GREEN_BIAS: - params[0] = IROUND(ctx->Pixel.GreenBias); - break; - case GL_GREEN_BITS: - params[0] = ctx->DrawBuffer->Visual.greenBits; - break; - case GL_GREEN_SCALE: - params[0] = IROUND(ctx->Pixel.GreenScale); - break; - case GL_INDEX_BITS: - params[0] = ctx->DrawBuffer->Visual.indexBits; - break; - case GL_INDEX_CLEAR_VALUE: - params[0] = ctx->Color.ClearIndex; - break; - case GL_INDEX_MODE: - params[0] = BOOLEAN_TO_INT(!ctx->DrawBuffer->Visual.rgbMode); - break; - case GL_INDEX_OFFSET: - params[0] = ctx->Pixel.IndexOffset; - break; - case GL_INDEX_SHIFT: - params[0] = ctx->Pixel.IndexShift; - break; - case GL_INDEX_WRITEMASK: - params[0] = ctx->Color.IndexMask; - break; - case GL_LIGHT0: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[0].Enabled); - break; - case GL_LIGHT1: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[1].Enabled); - break; - case GL_LIGHT2: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[2].Enabled); - break; - case GL_LIGHT3: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[3].Enabled); - break; - case GL_LIGHT4: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[4].Enabled); - break; - case GL_LIGHT5: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[5].Enabled); - break; - case GL_LIGHT6: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[6].Enabled); - break; - case GL_LIGHT7: - params[0] = BOOLEAN_TO_INT(ctx->Light.Light[7].Enabled); - break; - case GL_LIGHTING: - params[0] = BOOLEAN_TO_INT(ctx->Light.Enabled); - break; - case GL_LIGHT_MODEL_AMBIENT: - params[0] = FLOAT_TO_INT(ctx->Light.Model.Ambient[0]); - params[1] = FLOAT_TO_INT(ctx->Light.Model.Ambient[1]); - params[2] = FLOAT_TO_INT(ctx->Light.Model.Ambient[2]); - params[3] = FLOAT_TO_INT(ctx->Light.Model.Ambient[3]); - break; - case GL_LIGHT_MODEL_COLOR_CONTROL: - params[0] = ENUM_TO_INT(ctx->Light.Model.ColorControl); - break; - case GL_LIGHT_MODEL_LOCAL_VIEWER: - params[0] = BOOLEAN_TO_INT(ctx->Light.Model.LocalViewer); - break; - case GL_LIGHT_MODEL_TWO_SIDE: - params[0] = BOOLEAN_TO_INT(ctx->Light.Model.TwoSide); - break; - case GL_LINE_SMOOTH: - params[0] = BOOLEAN_TO_INT(ctx->Line.SmoothFlag); - break; - case GL_LINE_SMOOTH_HINT: - params[0] = ENUM_TO_INT(ctx->Hint.LineSmooth); - break; - case GL_LINE_STIPPLE: - params[0] = BOOLEAN_TO_INT(ctx->Line.StippleFlag); - break; - case GL_LINE_STIPPLE_PATTERN: - params[0] = ctx->Line.StipplePattern; - break; - case GL_LINE_STIPPLE_REPEAT: - params[0] = ctx->Line.StippleFactor; - break; - case GL_LINE_WIDTH: - params[0] = IROUND(ctx->Line.Width); - break; - case GL_LINE_WIDTH_GRANULARITY: - params[0] = IROUND(ctx->Const.LineWidthGranularity); - break; - case GL_LINE_WIDTH_RANGE: - params[0] = IROUND(ctx->Const.MinLineWidthAA); - params[1] = IROUND(ctx->Const.MaxLineWidthAA); - break; - case GL_ALIASED_LINE_WIDTH_RANGE: - params[0] = IROUND(ctx->Const.MinLineWidth); - params[1] = IROUND(ctx->Const.MaxLineWidth); - break; - case GL_LIST_BASE: - params[0] = ctx->List.ListBase; - break; - case GL_LIST_INDEX: - params[0] = ctx->ListState.CurrentListNum; - break; - case GL_LIST_MODE: - { - GLenum mode; - if (!ctx->CompileFlag) - mode = 0; - else if (ctx->ExecuteFlag) - mode = GL_COMPILE_AND_EXECUTE; - else - mode = GL_COMPILE; - params[0] = ENUM_TO_INT(mode); - } - break; - case GL_INDEX_LOGIC_OP: - params[0] = BOOLEAN_TO_INT(ctx->Color.IndexLogicOpEnabled); - break; - case GL_COLOR_LOGIC_OP: - params[0] = BOOLEAN_TO_INT(ctx->Color.ColorLogicOpEnabled); - break; - case GL_LOGIC_OP_MODE: - params[0] = ENUM_TO_INT(ctx->Color.LogicOp); - break; - case GL_MAP1_COLOR_4: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Color4); - break; - case GL_MAP1_GRID_DOMAIN: - params[0] = IROUND(ctx->Eval.MapGrid1u1); - params[1] = IROUND(ctx->Eval.MapGrid1u2); - break; - case GL_MAP1_GRID_SEGMENTS: - params[0] = ctx->Eval.MapGrid1un; - break; - case GL_MAP1_INDEX: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Index); - break; - case GL_MAP1_NORMAL: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Normal); - break; - case GL_MAP1_TEXTURE_COORD_1: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord1); - break; - case GL_MAP1_TEXTURE_COORD_2: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord2); - break; - case GL_MAP1_TEXTURE_COORD_3: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord3); - break; - case GL_MAP1_TEXTURE_COORD_4: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1TextureCoord4); - break; - case GL_MAP1_VERTEX_3: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Vertex3); - break; - case GL_MAP1_VERTEX_4: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Vertex4); - break; - case GL_MAP2_COLOR_4: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Color4); - break; - case GL_MAP2_GRID_DOMAIN: - params[0] = IROUND(ctx->Eval.MapGrid2u1); - params[1] = IROUND(ctx->Eval.MapGrid2u2); - params[2] = IROUND(ctx->Eval.MapGrid2v1); - params[3] = IROUND(ctx->Eval.MapGrid2v2); - break; - case GL_MAP2_GRID_SEGMENTS: - params[0] = ctx->Eval.MapGrid2un; - params[1] = ctx->Eval.MapGrid2vn; - break; - case GL_MAP2_INDEX: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Index); - break; - case GL_MAP2_NORMAL: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Normal); - break; - case GL_MAP2_TEXTURE_COORD_1: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord1); - break; - case GL_MAP2_TEXTURE_COORD_2: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord2); - break; - case GL_MAP2_TEXTURE_COORD_3: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord3); - break; - case GL_MAP2_TEXTURE_COORD_4: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2TextureCoord4); - break; - case GL_MAP2_VERTEX_3: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Vertex3); - break; - case GL_MAP2_VERTEX_4: - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map2Vertex4); - break; - case GL_MAP_COLOR: - params[0] = BOOLEAN_TO_INT(ctx->Pixel.MapColorFlag); - break; - case GL_MAP_STENCIL: - params[0] = BOOLEAN_TO_INT(ctx->Pixel.MapStencilFlag); - break; - case GL_MATRIX_MODE: - params[0] = ENUM_TO_INT(ctx->Transform.MatrixMode); - break; - case GL_MAX_ATTRIB_STACK_DEPTH: - params[0] = MAX_ATTRIB_STACK_DEPTH; - break; - case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: - params[0] = MAX_CLIENT_ATTRIB_STACK_DEPTH; - break; - case GL_MAX_CLIP_PLANES: - params[0] = ctx->Const.MaxClipPlanes; - break; - case GL_MAX_ELEMENTS_VERTICES: - params[0] = ctx->Const.MaxArrayLockSize; - break; - case GL_MAX_ELEMENTS_INDICES: - params[0] = ctx->Const.MaxArrayLockSize; - break; - case GL_MAX_EVAL_ORDER: - params[0] = MAX_EVAL_ORDER; - break; - case GL_MAX_LIGHTS: - params[0] = ctx->Const.MaxLights; - break; - case GL_MAX_LIST_NESTING: - params[0] = MAX_LIST_NESTING; - break; - case GL_MAX_MODELVIEW_STACK_DEPTH: - params[0] = MAX_MODELVIEW_STACK_DEPTH; - break; - case GL_MAX_NAME_STACK_DEPTH: - params[0] = MAX_NAME_STACK_DEPTH; - break; - case GL_MAX_PIXEL_MAP_TABLE: - params[0] = MAX_PIXEL_MAP_TABLE; - break; - case GL_MAX_PROJECTION_STACK_DEPTH: - params[0] = MAX_PROJECTION_STACK_DEPTH; - break; - case GL_MAX_TEXTURE_SIZE: - params[0] = 1 << (ctx->Const.MaxTextureLevels - 1); - break; - case GL_MAX_3D_TEXTURE_SIZE: - params[0] = 1 << (ctx->Const.Max3DTextureLevels - 1); - break; - case GL_MAX_TEXTURE_STACK_DEPTH: - params[0] = MAX_TEXTURE_STACK_DEPTH; - break; - case GL_MAX_VIEWPORT_DIMS: - params[0] = ctx->Const.MaxViewportWidth; - params[1] = ctx->Const.MaxViewportHeight; - break; - case GL_MODELVIEW_MATRIX: - { - const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[1]); - params[2] = IROUND(matrix[2]); - params[3] = IROUND(matrix[3]); - params[4] = IROUND(matrix[4]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[6]); - params[7] = IROUND(matrix[7]); - params[8] = IROUND(matrix[8]); - params[9] = IROUND(matrix[9]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[11]); - params[12] = IROUND(matrix[12]); - params[13] = IROUND(matrix[13]); - params[14] = IROUND(matrix[14]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_MODELVIEW_STACK_DEPTH: - params[0] = ctx->ModelviewMatrixStack.Depth + 1; - break; - case GL_NAME_STACK_DEPTH: - params[0] = ctx->Select.NameStackDepth; - break; - case GL_NORMALIZE: - params[0] = BOOLEAN_TO_INT(ctx->Transform.Normalize); - break; - case GL_PACK_ALIGNMENT: - params[0] = ctx->Pack.Alignment; - break; - case GL_PACK_LSB_FIRST: - params[0] = BOOLEAN_TO_INT(ctx->Pack.LsbFirst); - break; - case GL_PACK_ROW_LENGTH: - params[0] = ctx->Pack.RowLength; - break; - case GL_PACK_SKIP_PIXELS: - params[0] = ctx->Pack.SkipPixels; - break; - case GL_PACK_SKIP_ROWS: - params[0] = ctx->Pack.SkipRows; - break; - case GL_PACK_SWAP_BYTES: - params[0] = BOOLEAN_TO_INT(ctx->Pack.SwapBytes); - break; - case GL_PACK_SKIP_IMAGES_EXT: - params[0] = ctx->Pack.SkipImages; - break; - case GL_PACK_IMAGE_HEIGHT_EXT: - params[0] = ctx->Pack.ImageHeight; - break; - case GL_PACK_INVERT_MESA: - params[0] = BOOLEAN_TO_INT(ctx->Pack.Invert); - break; - case GL_PERSPECTIVE_CORRECTION_HINT: - params[0] = ENUM_TO_INT(ctx->Hint.PerspectiveCorrection); - break; - case GL_PIXEL_MAP_A_TO_A_SIZE: - params[0] = ctx->Pixel.MapAtoAsize; - break; - case GL_PIXEL_MAP_B_TO_B_SIZE: - params[0] = ctx->Pixel.MapBtoBsize; - break; - case GL_PIXEL_MAP_G_TO_G_SIZE: - params[0] = ctx->Pixel.MapGtoGsize; - break; - case GL_PIXEL_MAP_I_TO_A_SIZE: - params[0] = ctx->Pixel.MapItoAsize; - break; - case GL_PIXEL_MAP_I_TO_B_SIZE: - params[0] = ctx->Pixel.MapItoBsize; - break; - case GL_PIXEL_MAP_I_TO_G_SIZE: - params[0] = ctx->Pixel.MapItoGsize; - break; - case GL_PIXEL_MAP_I_TO_I_SIZE: - params[0] = ctx->Pixel.MapItoIsize; - break; - case GL_PIXEL_MAP_I_TO_R_SIZE: - params[0] = ctx->Pixel.MapItoRsize; - break; - case GL_PIXEL_MAP_R_TO_R_SIZE: - params[0] = ctx->Pixel.MapRtoRsize; - break; - case GL_PIXEL_MAP_S_TO_S_SIZE: - params[0] = ctx->Pixel.MapStoSsize; - break; - case GL_POINT_SIZE: - params[0] = IROUND(ctx->Point.Size); - break; - case GL_POINT_SIZE_GRANULARITY: - params[0] = IROUND(ctx->Const.PointSizeGranularity); - break; - case GL_POINT_SIZE_RANGE: - params[0] = IROUND(ctx->Const.MinPointSizeAA); - params[1] = IROUND(ctx->Const.MaxPointSizeAA); - break; - case GL_ALIASED_POINT_SIZE_RANGE: - params[0] = IROUND(ctx->Const.MinPointSize); - params[1] = IROUND(ctx->Const.MaxPointSize); - break; - case GL_POINT_SMOOTH: - params[0] = BOOLEAN_TO_INT(ctx->Point.SmoothFlag); - break; - case GL_POINT_SMOOTH_HINT: - params[0] = ENUM_TO_INT(ctx->Hint.PointSmooth); - break; - case GL_POINT_SIZE_MIN_EXT: - params[0] = IROUND(ctx->Point.MinSize); - break; - case GL_POINT_SIZE_MAX_EXT: - params[0] = IROUND(ctx->Point.MaxSize); - break; - case GL_POINT_FADE_THRESHOLD_SIZE_EXT: - params[0] = IROUND(ctx->Point.Threshold); - break; - case GL_DISTANCE_ATTENUATION_EXT: - params[0] = IROUND(ctx->Point.Params[0]); - params[1] = IROUND(ctx->Point.Params[1]); - params[2] = IROUND(ctx->Point.Params[2]); - break; - case GL_POLYGON_MODE: - params[0] = ENUM_TO_INT(ctx->Polygon.FrontMode); - params[1] = ENUM_TO_INT(ctx->Polygon.BackMode); - break; - case GL_POLYGON_OFFSET_BIAS_EXT: - params[0] = IROUND(ctx->Polygon.OffsetUnits); - break; - case GL_POLYGON_OFFSET_FACTOR: - params[0] = IROUND(ctx->Polygon.OffsetFactor ); - break; - case GL_POLYGON_OFFSET_UNITS: - params[0] = IROUND(ctx->Polygon.OffsetUnits ); - break; - case GL_POLYGON_SMOOTH: - params[0] = BOOLEAN_TO_INT(ctx->Polygon.SmoothFlag); - break; - case GL_POLYGON_SMOOTH_HINT: - params[0] = ENUM_TO_INT(ctx->Hint.PolygonSmooth); - break; - case GL_POLYGON_STIPPLE: - params[0] = BOOLEAN_TO_INT(ctx->Polygon.StippleFlag); - break; - case GL_PROJECTION_MATRIX: - { - const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[1]); - params[2] = IROUND(matrix[2]); - params[3] = IROUND(matrix[3]); - params[4] = IROUND(matrix[4]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[6]); - params[7] = IROUND(matrix[7]); - params[8] = IROUND(matrix[8]); - params[9] = IROUND(matrix[9]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[11]); - params[12] = IROUND(matrix[12]); - params[13] = IROUND(matrix[13]); - params[14] = IROUND(matrix[14]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_PROJECTION_STACK_DEPTH: - params[0] = ctx->ProjectionMatrixStack.Depth + 1; - break; - case GL_READ_BUFFER: - params[0] = ENUM_TO_INT(ctx->ReadBuffer->ColorReadBuffer); - break; - case GL_RED_BIAS: - params[0] = IROUND(ctx->Pixel.RedBias); - break; - case GL_RED_BITS: - params[0] = ctx->DrawBuffer->Visual.redBits ; - break; - case GL_RED_SCALE: - params[0] = IROUND(ctx->Pixel.RedScale); - break; - case GL_RENDER_MODE: - params[0] = ENUM_TO_INT(ctx->RenderMode); - break; - case GL_RESCALE_NORMAL: - params[0] = BOOLEAN_TO_INT(ctx->Transform.RescaleNormals); - break; - case GL_RGBA_MODE: - params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.rgbMode); - break; - case GL_SCISSOR_BOX: - params[0] = ctx->Scissor.X; - params[1] = ctx->Scissor.Y; - params[2] = ctx->Scissor.Width; - params[3] = ctx->Scissor.Height; - break; - case GL_SCISSOR_TEST: - params[0] = BOOLEAN_TO_INT(ctx->Scissor.Enabled); - break; - case GL_SELECTION_BUFFER_SIZE: - params[0] = ctx->Select.BufferSize; - break; - case GL_SHADE_MODEL: - params[0] = ENUM_TO_INT(ctx->Light.ShadeModel); - break; - case GL_SHARED_TEXTURE_PALETTE_EXT: - params[0] = BOOLEAN_TO_INT(ctx->Texture.SharedPalette); - break; - case GL_STENCIL_BITS: - params[0] = ctx->DrawBuffer->Visual.stencilBits; - break; - case GL_STENCIL_CLEAR_VALUE: - params[0] = ctx->Stencil.Clear; - break; - case GL_STENCIL_FAIL: - params[0] = ENUM_TO_INT(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_FUNC: - params[0] = ENUM_TO_INT(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_PASS_DEPTH_FAIL: - params[0] = ENUM_TO_INT(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_PASS_DEPTH_PASS: - params[0] = ENUM_TO_INT(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); - break; - case GL_STENCIL_REF: - params[0] = ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; - break; - case GL_STENCIL_TEST: - params[0] = BOOLEAN_TO_INT(ctx->Stencil.Enabled); - break; - case GL_STENCIL_VALUE_MASK: - params[0] = ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; - break; - case GL_STENCIL_WRITEMASK: - params[0] = ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; - break; - case GL_STEREO: - params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.stereoMode); - break; - case GL_SUBPIXEL_BITS: - params[0] = ctx->Const.SubPixelBits; - break; - case GL_TEXTURE_1D: - params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_1D)); - break; - case GL_TEXTURE_2D: - params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_2D)); - break; - case GL_TEXTURE_3D: - params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_3D)); - break; - case GL_TEXTURE_BINDING_1D: - params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current1D->Name; - break; - case GL_TEXTURE_BINDING_2D: - params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current2D->Name; - break; - case GL_TEXTURE_BINDING_3D: - params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Current3D->Name; - break; - case GL_TEXTURE_ENV_COLOR: - { - const GLfloat *color = ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvColor; - params[0] = FLOAT_TO_INT(color[0]); - params[1] = FLOAT_TO_INT(color[1]); - params[2] = FLOAT_TO_INT(color[2]); - params[3] = FLOAT_TO_INT(color[3]); - } - break; - case GL_TEXTURE_ENV_MODE: - params[0] = ENUM_TO_INT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].EnvMode); - break; - case GL_TEXTURE_GEN_S: - params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_GEN_T: - params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_GEN_R: - params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_GEN_Q: - params[0] = BOOLEAN_TO_INT(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0)); - break; - case GL_TEXTURE_MATRIX: - { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[1]); - params[2] = IROUND(matrix[2]); - params[3] = IROUND(matrix[3]); - params[4] = IROUND(matrix[4]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[6]); - params[7] = IROUND(matrix[7]); - params[8] = IROUND(matrix[8]); - params[9] = IROUND(matrix[9]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[11]); - params[12] = IROUND(matrix[12]); - params[13] = IROUND(matrix[13]); - params[14] = IROUND(matrix[14]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_TEXTURE_STACK_DEPTH: - params[0] = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1; - break; - case GL_UNPACK_ALIGNMENT: - params[0] = ctx->Unpack.Alignment; - break; - case GL_UNPACK_LSB_FIRST: - params[0] = BOOLEAN_TO_INT(ctx->Unpack.LsbFirst); - break; - case GL_UNPACK_ROW_LENGTH: - params[0] = ctx->Unpack.RowLength; - break; - case GL_UNPACK_SKIP_PIXELS: - params[0] = ctx->Unpack.SkipPixels; - break; - case GL_UNPACK_SKIP_ROWS: - params[0] = ctx->Unpack.SkipRows; - break; - case GL_UNPACK_SWAP_BYTES: - params[0] = BOOLEAN_TO_INT(ctx->Unpack.SwapBytes); - break; - case GL_UNPACK_SKIP_IMAGES_EXT: - params[0] = ctx->Unpack.SkipImages; - break; - case GL_UNPACK_IMAGE_HEIGHT_EXT: - params[0] = ctx->Unpack.ImageHeight; - break; - case GL_UNPACK_CLIENT_STORAGE_APPLE: - params[0] = BOOLEAN_TO_INT(ctx->Unpack.ClientStorage); - break; - case GL_VIEWPORT: - params[0] = ctx->Viewport.X; - params[1] = ctx->Viewport.Y; - params[2] = ctx->Viewport.Width; - params[3] = ctx->Viewport.Height; - break; - case GL_ZOOM_X: - params[0] = IROUND(ctx->Pixel.ZoomX); - break; - case GL_ZOOM_Y: - params[0] = IROUND(ctx->Pixel.ZoomY); - break; - case GL_VERTEX_ARRAY: - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->Vertex.Enabled); - break; - case GL_VERTEX_ARRAY_SIZE: - params[0] = ctx->Array.ArrayObj->Vertex.Size; - break; - case GL_VERTEX_ARRAY_TYPE: - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->Vertex.Type); - break; - case GL_VERTEX_ARRAY_STRIDE: - params[0] = ctx->Array.ArrayObj->Vertex.Stride; - break; - case GL_VERTEX_ARRAY_COUNT_EXT: - params[0] = 0; - break; - case GL_NORMAL_ARRAY: - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->Normal.Enabled); - break; - case GL_NORMAL_ARRAY_TYPE: - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->Normal.Type); - break; - case GL_NORMAL_ARRAY_STRIDE: - params[0] = ctx->Array.ArrayObj->Normal.Stride; - break; - case GL_NORMAL_ARRAY_COUNT_EXT: - params[0] = 0; - break; - case GL_COLOR_ARRAY: - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->Color.Enabled); - break; - case GL_COLOR_ARRAY_SIZE: - params[0] = ctx->Array.ArrayObj->Color.Size; - break; - case GL_COLOR_ARRAY_TYPE: - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->Color.Type); - break; - case GL_COLOR_ARRAY_STRIDE: - params[0] = ctx->Array.ArrayObj->Color.Stride; - break; - case GL_COLOR_ARRAY_COUNT_EXT: - params[0] = 0; - break; - case GL_INDEX_ARRAY: - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->Index.Enabled); - break; - case GL_INDEX_ARRAY_TYPE: - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->Index.Type); - break; - case GL_INDEX_ARRAY_STRIDE: - params[0] = ctx->Array.ArrayObj->Index.Stride; - break; - case GL_INDEX_ARRAY_COUNT_EXT: - params[0] = 0; - break; - case GL_TEXTURE_COORD_ARRAY: - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled); - break; - case GL_TEXTURE_COORD_ARRAY_SIZE: - params[0] = ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Size; - break; - case GL_TEXTURE_COORD_ARRAY_TYPE: - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Type); - break; - case GL_TEXTURE_COORD_ARRAY_STRIDE: - params[0] = ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Stride; - break; - case GL_TEXTURE_COORD_ARRAY_COUNT_EXT: - params[0] = 0; - break; - case GL_EDGE_FLAG_ARRAY: - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->EdgeFlag.Enabled); - break; - case GL_EDGE_FLAG_ARRAY_STRIDE: - params[0] = ctx->Array.ArrayObj->EdgeFlag.Stride; - break; - case GL_EDGE_FLAG_ARRAY_COUNT_EXT: - params[0] = 0; - break; - case GL_MAX_TEXTURE_UNITS_ARB: - CHECK_EXT1(ARB_multitexture, "GetIntegerv"); - params[0] = ctx->Const.MaxTextureUnits; - break; - case GL_ACTIVE_TEXTURE_ARB: - CHECK_EXT1(ARB_multitexture, "GetIntegerv"); - params[0] = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit; - break; - case GL_CLIENT_ACTIVE_TEXTURE_ARB: - CHECK_EXT1(ARB_multitexture, "GetIntegerv"); - params[0] = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB)); - break; - case GL_TEXTURE_BINDING_CUBE_MAP_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetIntegerv"); - params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentCubeMap->Name; - break; - case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: - CHECK_EXT1(ARB_texture_cube_map, "GetIntegerv"); - params[0] = (1 << (ctx->Const.MaxCubeTextureLevels - 1)); - break; - case GL_TEXTURE_COMPRESSION_HINT_ARB: - CHECK_EXT1(ARB_texture_compression, "GetIntegerv"); - params[0] = ctx->Hint.TextureCompression; - break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: - CHECK_EXT1(ARB_texture_compression, "GetIntegerv"); - params[0] = _mesa_get_compressed_formats(ctx, NULL, GL_FALSE); - break; - case GL_COMPRESSED_TEXTURE_FORMATS_ARB: - CHECK_EXT1(ARB_texture_compression, "GetIntegerv"); - { - GLint formats[100]; - GLuint i, n = _mesa_get_compressed_formats(ctx, formats, GL_FALSE); - ASSERT(n <= 100); - for (i = 0; i < n; i++) - params[i] = ENUM_TO_INT(formats[i]); - } - break; - case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT: - CHECK_EXT1(EXT_compiled_vertex_array, "GetIntegerv"); - params[0] = ctx->Array.LockFirst; - break; - case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT: - CHECK_EXT1(EXT_compiled_vertex_array, "GetIntegerv"); - params[0] = ctx->Array.LockCount; - break; - case GL_TRANSPOSE_COLOR_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ColorMatrixStack.Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[4]); - params[2] = IROUND(matrix[8]); - params[3] = IROUND(matrix[12]); - params[4] = IROUND(matrix[1]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[9]); - params[7] = IROUND(matrix[13]); - params[8] = IROUND(matrix[2]); - params[9] = IROUND(matrix[6]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[14]); - params[12] = IROUND(matrix[3]); - params[13] = IROUND(matrix[7]); - params[14] = IROUND(matrix[11]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[4]); - params[2] = IROUND(matrix[8]); - params[3] = IROUND(matrix[12]); - params[4] = IROUND(matrix[1]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[9]); - params[7] = IROUND(matrix[13]); - params[8] = IROUND(matrix[2]); - params[9] = IROUND(matrix[6]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[14]); - params[12] = IROUND(matrix[3]); - params[13] = IROUND(matrix[7]); - params[14] = IROUND(matrix[11]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: - { - const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[4]); - params[2] = IROUND(matrix[8]); - params[3] = IROUND(matrix[12]); - params[4] = IROUND(matrix[1]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[9]); - params[7] = IROUND(matrix[13]); - params[8] = IROUND(matrix[2]); - params[9] = IROUND(matrix[6]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[14]); - params[12] = IROUND(matrix[3]); - params[13] = IROUND(matrix[7]); - params[14] = IROUND(matrix[11]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: - { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[4]); - params[2] = IROUND(matrix[8]); - params[3] = IROUND(matrix[12]); - params[4] = IROUND(matrix[1]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[9]); - params[7] = IROUND(matrix[13]); - params[8] = IROUND(matrix[2]); - params[9] = IROUND(matrix[6]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[14]); - params[12] = IROUND(matrix[3]); - params[13] = IROUND(matrix[7]); - params[14] = IROUND(matrix[11]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_COLOR_MATRIX_SGI: - { - const GLfloat *matrix = ctx->ColorMatrixStack.Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[1]); - params[2] = IROUND(matrix[2]); - params[3] = IROUND(matrix[3]); - params[4] = IROUND(matrix[4]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[6]); - params[7] = IROUND(matrix[7]); - params[8] = IROUND(matrix[8]); - params[9] = IROUND(matrix[9]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[11]); - params[12] = IROUND(matrix[12]); - params[13] = IROUND(matrix[13]); - params[14] = IROUND(matrix[14]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_COLOR_MATRIX_STACK_DEPTH_SGI: - params[0] = ctx->ColorMatrixStack.Depth + 1; - break; - case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI: - params[0] = MAX_COLOR_STACK_DEPTH; - break; - case GL_POST_COLOR_MATRIX_RED_SCALE_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[0]); - break; - case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[1]); - break; - case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[2]); - break; - case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixScale[3]); - break; - case GL_POST_COLOR_MATRIX_RED_BIAS_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[0]); - break; - case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[1]); - break; - case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[2]); - break; - case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI: - params[0] = IROUND(ctx->Pixel.PostColorMatrixBias[3]); - break; - case GL_CONVOLUTION_1D_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.Convolution1DEnabled); - break; - case GL_CONVOLUTION_2D_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.Convolution2DEnabled); - break; - case GL_SEPARABLE_2D_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.Separable2DEnabled); - break; - case GL_POST_CONVOLUTION_RED_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionScale[0]); - break; - case GL_POST_CONVOLUTION_GREEN_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionScale[1]); - break; - case GL_POST_CONVOLUTION_BLUE_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionScale[2]); - break; - case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionScale[3]); - break; - case GL_POST_CONVOLUTION_RED_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionBias[0]); - break; - case GL_POST_CONVOLUTION_GREEN_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionBias[1]); - break; - case GL_POST_CONVOLUTION_BLUE_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionBias[2]); - break; - case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT: - CHECK_EXT1(EXT_convolution, "GetIntegerv"); - params[0] = IROUND(ctx->Pixel.PostConvolutionBias[3]); - break; - case GL_HISTOGRAM: - CHECK_EXT1(EXT_histogram, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.HistogramEnabled); - break; - case GL_MINMAX: - CHECK_EXT1(EXT_histogram, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.MinMaxEnabled); - break; - case GL_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.ColorTableEnabled); - break; - case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.PostConvolutionColorTableEnabled); - break; - case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_color_table, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Pixel.PostColorMatrixColorTableEnabled); - break; - case GL_TEXTURE_COLOR_TABLE_SGI: - CHECK_EXT1(SGI_texture_color_table, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled); - break; - case GL_COLOR_SUM_EXT: - CHECK_EXT2(EXT_secondary_color, ARB_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Fog.ColorSumEnabled); - break; - case GL_CURRENT_SECONDARY_COLOR_EXT: - CHECK_EXT1(EXT_secondary_color, "GetIntegerv"); - { - FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0]); - params[1] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1]); - params[2] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2]); - params[3] = FLOAT_TO_INT(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3]); - } - break; - case GL_SECONDARY_COLOR_ARRAY_EXT: - CHECK_EXT1(EXT_secondary_color, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->SecondaryColor.Enabled); - break; - case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->SecondaryColor.Type); - break; - case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->SecondaryColor.Stride; - break; - case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT: - CHECK_EXT1(EXT_secondary_color, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->SecondaryColor.Size; - break; - case GL_CURRENT_FOG_COORDINATE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetIntegerv"); - { - FLUSH_CURRENT(ctx, 0); - params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]); - } - break; - case GL_FOG_COORDINATE_ARRAY_EXT: - CHECK_EXT1(EXT_fog_coord, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->FogCoord.Enabled); - break; - case GL_FOG_COORDINATE_ARRAY_TYPE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Array.ArrayObj->FogCoord.Type); - break; - case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->FogCoord.Stride; - break; - case GL_FOG_COORDINATE_SOURCE_EXT: - CHECK_EXT1(EXT_fog_coord, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Fog.FogCoordinateSource); - break; - case GL_MAX_TEXTURE_LOD_BIAS_EXT: - CHECK_EXT1(EXT_texture_lod_bias, "GetIntegerv"); - params[0] = IROUND(ctx->Const.MaxTextureLodBias); - break; - case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: - CHECK_EXT1(EXT_texture_filter_anisotropic, "GetIntegerv"); - params[0] = IROUND(ctx->Const.MaxTextureMaxAnisotropy); - break; - case GL_MULTISAMPLE_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Multisample.Enabled); - break; - case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleAlphaToCoverage); - break; - case GL_SAMPLE_ALPHA_TO_ONE_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleAlphaToOne); - break; - case GL_SAMPLE_COVERAGE_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleCoverage); - break; - case GL_SAMPLE_COVERAGE_VALUE_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = IROUND(ctx->Multisample.SampleCoverageValue); - break; - case GL_SAMPLE_COVERAGE_INVERT_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Multisample.SampleCoverageInvert); - break; - case GL_SAMPLE_BUFFERS_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = ctx->DrawBuffer->Visual.sampleBuffers; - break; - case GL_SAMPLES_ARB: - CHECK_EXT1(ARB_multisample, "GetIntegerv"); - params[0] = ctx->DrawBuffer->Visual.samples; - break; - case GL_RASTER_POSITION_UNCLIPPED_IBM: - CHECK_EXT1(IBM_rasterpos_clip, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Transform.RasterPositionUnclipped); - break; - case GL_POINT_SPRITE_NV: - CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Point.PointSprite); - break; - case GL_POINT_SPRITE_R_MODE_NV: - CHECK_EXT1(NV_point_sprite, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Point.SpriteRMode); - break; - case GL_POINT_SPRITE_COORD_ORIGIN: - CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Point.SpriteOrigin); - break; - case GL_GENERATE_MIPMAP_HINT_SGIS: - CHECK_EXT1(SGIS_generate_mipmap, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Hint.GenerateMipmap); - break; - case GL_VERTEX_PROGRAM_BINDING_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = (ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0); - break; - case GL_VERTEX_ATTRIB_ARRAY0_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[0].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY1_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[1].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY2_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[2].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY3_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[3].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[4].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY5_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[5].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY6_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[6].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY7_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[7].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY8_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[8].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY9_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[9].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY10_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[10].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY11_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[11].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY12_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[12].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY13_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[13].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY14_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[14].Enabled); - break; - case GL_VERTEX_ATTRIB_ARRAY15_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Array.ArrayObj->VertexAttrib[15].Enabled); - break; - case GL_MAP1_VERTEX_ATTRIB0_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[0]); - break; - case GL_MAP1_VERTEX_ATTRIB1_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[1]); - break; - case GL_MAP1_VERTEX_ATTRIB2_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[2]); - break; - case GL_MAP1_VERTEX_ATTRIB3_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[3]); - break; - case GL_MAP1_VERTEX_ATTRIB4_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[4]); - break; - case GL_MAP1_VERTEX_ATTRIB5_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[5]); - break; - case GL_MAP1_VERTEX_ATTRIB6_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[6]); - break; - case GL_MAP1_VERTEX_ATTRIB7_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[7]); - break; - case GL_MAP1_VERTEX_ATTRIB8_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[8]); - break; - case GL_MAP1_VERTEX_ATTRIB9_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[9]); - break; - case GL_MAP1_VERTEX_ATTRIB10_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[10]); - break; - case GL_MAP1_VERTEX_ATTRIB11_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[11]); - break; - case GL_MAP1_VERTEX_ATTRIB12_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[12]); - break; - case GL_MAP1_VERTEX_ATTRIB13_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[13]); - break; - case GL_MAP1_VERTEX_ATTRIB14_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[14]); - break; - case GL_MAP1_VERTEX_ATTRIB15_4_NV: - CHECK_EXT1(NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Eval.Map1Attrib[15]); - break; - case GL_FRAGMENT_PROGRAM_NV: - CHECK_EXT1(NV_fragment_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->FragmentProgram.Enabled); - break; - case GL_FRAGMENT_PROGRAM_BINDING_NV: - CHECK_EXT1(NV_fragment_program, "GetIntegerv"); - params[0] = ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0; - break; - case GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV: - CHECK_EXT1(NV_fragment_program, "GetIntegerv"); - params[0] = MAX_NV_FRAGMENT_PROGRAM_PARAMS; - break; - case GL_TEXTURE_RECTANGLE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(_mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV)); - break; - case GL_TEXTURE_BINDING_RECTANGLE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetIntegerv"); - params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentRect->Name; - break; - case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV: - CHECK_EXT1(NV_texture_rectangle, "GetIntegerv"); - params[0] = ctx->Const.MaxTextureRectSize; - break; - case GL_STENCIL_TEST_TWO_SIDE_EXT: - CHECK_EXT1(EXT_stencil_two_side, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Stencil.TestTwoSide); - break; - case GL_ACTIVE_STENCIL_FACE_EXT: - CHECK_EXT1(EXT_stencil_two_side, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT); - break; - case GL_MAX_SHININESS_NV: - CHECK_EXT1(NV_light_max_exponent, "GetIntegerv"); - params[0] = IROUND(ctx->Const.MaxShininess); - break; - case GL_MAX_SPOT_EXPONENT_NV: - CHECK_EXT1(NV_light_max_exponent, "GetIntegerv"); - params[0] = IROUND(ctx->Const.MaxSpotExponent); - break; - case GL_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayBufferObj->Name; - break; - case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->Vertex.BufferObj->Name; - break; - case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->Normal.BufferObj->Name; - break; - case GL_COLOR_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->Color.BufferObj->Name; - break; - case GL_INDEX_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->Index.BufferObj->Name; - break; - case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name; - break; - case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->EdgeFlag.BufferObj->Name; - break; - case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->SecondaryColor.BufferObj->Name; - break; - case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ArrayObj->FogCoord.BufferObj->Name; - break; - case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB: - CHECK_EXT1(ARB_vertex_buffer_object, "GetIntegerv"); - params[0] = ctx->Array.ElementArrayBufferObj->Name; - break; - case GL_PIXEL_PACK_BUFFER_BINDING_EXT: - CHECK_EXT1(EXT_pixel_buffer_object, "GetIntegerv"); - params[0] = ctx->Pack.BufferObj->Name; - break; - case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT: - CHECK_EXT1(EXT_pixel_buffer_object, "GetIntegerv"); - params[0] = ctx->Unpack.BufferObj->Name; - break; - case GL_VERTEX_PROGRAM_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.Enabled); - break; - case GL_VERTEX_PROGRAM_POINT_SIZE_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.PointSizeEnabled); - break; - case GL_VERTEX_PROGRAM_TWO_SIDE_ARB: - CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.TwoSideEnabled); - break; - case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetIntegerv"); - params[0] = ctx->Const.MaxProgramMatrixStackDepth; - break; - case GL_MAX_PROGRAM_MATRICES_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetIntegerv"); - params[0] = ctx->Const.MaxProgramMatrices; - break; - case GL_CURRENT_MATRIX_STACK_DEPTH_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->CurrentStack->Depth + 1); - break; - case GL_CURRENT_MATRIX_ARB: - CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_fragment_program, "GetIntegerv"); - { - const GLfloat *matrix = ctx->CurrentStack->Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[1]); - params[2] = IROUND(matrix[2]); - params[3] = IROUND(matrix[3]); - params[4] = IROUND(matrix[4]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[6]); - params[7] = IROUND(matrix[7]); - params[8] = IROUND(matrix[8]); - params[9] = IROUND(matrix[9]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[11]); - params[12] = IROUND(matrix[12]); - params[13] = IROUND(matrix[13]); - params[14] = IROUND(matrix[14]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_TRANSPOSE_CURRENT_MATRIX_ARB: - CHECK_EXT2(ARB_vertex_program, ARB_fragment_program, "GetIntegerv"); - { - const GLfloat *matrix = ctx->CurrentStack->Top->m; - params[0] = IROUND(matrix[0]); - params[1] = IROUND(matrix[4]); - params[2] = IROUND(matrix[8]); - params[3] = IROUND(matrix[12]); - params[4] = IROUND(matrix[1]); - params[5] = IROUND(matrix[5]); - params[6] = IROUND(matrix[9]); - params[7] = IROUND(matrix[13]); - params[8] = IROUND(matrix[2]); - params[9] = IROUND(matrix[6]); - params[10] = IROUND(matrix[10]); - params[11] = IROUND(matrix[14]); - params[12] = IROUND(matrix[3]); - params[13] = IROUND(matrix[7]); - params[14] = IROUND(matrix[11]); - params[15] = IROUND(matrix[15]); - } - break; - case GL_MAX_VERTEX_ATTRIBS_ARB: - CHECK_EXT1(ARB_vertex_program, "GetIntegerv"); - params[0] = ctx->Const.VertexProgram.MaxAttribs; - break; - case GL_PROGRAM_ERROR_POSITION_ARB: - CHECK_EXT4(NV_vertex_program, ARB_vertex_program, NV_fragment_program, ARB_fragment_program, "GetIntegerv"); - params[0] = ctx->Program.ErrorPos; - break; - case GL_FRAGMENT_PROGRAM_ARB: - CHECK_EXT1(ARB_fragment_program, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->FragmentProgram.Enabled); - break; - case GL_MAX_TEXTURE_COORDS_ARB: - CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetIntegerv"); - params[0] = ctx->Const.MaxTextureCoordUnits; - break; - case GL_MAX_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetIntegerv"); - params[0] = ctx->Const.MaxTextureImageUnits; - break; - case GL_DEPTH_BOUNDS_TEST_EXT: - CHECK_EXT1(EXT_depth_bounds_test, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->Depth.BoundsTest); - break; - case GL_DEPTH_BOUNDS_EXT: - CHECK_EXT1(EXT_depth_bounds_test, "GetIntegerv"); - params[0] = IROUND(ctx->Depth.BoundsMin); - params[1] = IROUND(ctx->Depth.BoundsMax); - break; - case GL_FRAGMENT_PROGRAM_CALLBACK_MESA: - CHECK_EXT1(MESA_program_debug, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->FragmentProgram.CallbackEnabled); - break; - case GL_VERTEX_PROGRAM_CALLBACK_MESA: - CHECK_EXT1(MESA_program_debug, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(ctx->VertexProgram.CallbackEnabled); - break; - case GL_FRAGMENT_PROGRAM_POSITION_MESA: - CHECK_EXT1(MESA_program_debug, "GetIntegerv"); - params[0] = ctx->FragmentProgram.CurrentPosition; - break; - case GL_VERTEX_PROGRAM_POSITION_MESA: - CHECK_EXT1(MESA_program_debug, "GetIntegerv"); - params[0] = ctx->VertexProgram.CurrentPosition; - break; - case GL_MAX_DRAW_BUFFERS_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetIntegerv"); - params[0] = ctx->Const.MaxDrawBuffers; - break; - case GL_DRAW_BUFFER0_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->DrawBuffer->ColorDrawBuffer[0]); - break; - case GL_DRAW_BUFFER1_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetIntegerv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[1]; - params[0] = ENUM_TO_INT(buffer); - } - break; - case GL_DRAW_BUFFER2_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetIntegerv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[2]; - params[0] = ENUM_TO_INT(buffer); - } - break; - case GL_DRAW_BUFFER3_ARB: - CHECK_EXT1(ARB_draw_buffers, "GetIntegerv"); - { - GLenum buffer; - if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)"); - return; - } - buffer = ctx->DrawBuffer->ColorDrawBuffer[3]; - params[0] = ENUM_TO_INT(buffer); - } - break; - case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: - CHECK_EXT1(OES_read_format, "GetIntegerv"); - params[0] = ctx->Const.ColorReadType; - break; - case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: - CHECK_EXT1(OES_read_format, "GetIntegerv"); - params[0] = ctx->Const.ColorReadFormat; - break; - case GL_NUM_FRAGMENT_REGISTERS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = 6; - break; - case GL_NUM_FRAGMENT_CONSTANTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = 8; - break; - case GL_NUM_PASSES_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = 2; - break; - case GL_NUM_INSTRUCTIONS_PER_PASS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = 8; - break; - case GL_NUM_INSTRUCTIONS_TOTAL_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = 16; - break; - case GL_COLOR_ALPHA_PAIRING_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = BOOLEAN_TO_INT(GL_TRUE); - break; - case GL_NUM_LOOPBACK_COMPONENTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = 3; - break; - case GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI: - CHECK_EXT1(ATI_fragment_shader, "GetIntegerv"); - params[0] = 3; - break; - case GL_STENCIL_BACK_FUNC: - params[0] = ENUM_TO_INT(ctx->Stencil.Function[1]); - break; - case GL_STENCIL_BACK_VALUE_MASK: - params[0] = ctx->Stencil.ValueMask[1]; - break; - case GL_STENCIL_BACK_REF: - params[0] = ctx->Stencil.Ref[1]; - break; - case GL_STENCIL_BACK_FAIL: - params[0] = ENUM_TO_INT(ctx->Stencil.FailFunc[1]); - break; - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - params[0] = ENUM_TO_INT(ctx->Stencil.ZFailFunc[1]); - break; - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - params[0] = ENUM_TO_INT(ctx->Stencil.ZPassFunc[1]); - break; - case GL_FRAMEBUFFER_BINDING_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv"); - params[0] = ctx->DrawBuffer->Name; - break; - case GL_RENDERBUFFER_BINDING_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv"); - params[0] = ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0; - break; - case GL_MAX_COLOR_ATTACHMENTS_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv"); - params[0] = ctx->Const.MaxColorAttachments; - break; - case GL_MAX_RENDERBUFFER_SIZE_EXT: - CHECK_EXT1(EXT_framebuffer_object, "GetIntegerv"); - params[0] = ctx->Const.MaxRenderbufferSize; - break; - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: - CHECK_EXT1(ARB_fragment_shader, "GetIntegerv"); - params[0] = MAX_FRAGMENT_UNIFORM_COMPONENTS; - break; - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: - CHECK_EXT1(ARB_fragment_shader, "GetIntegerv"); - params[0] = ENUM_TO_INT(ctx->Hint.FragmentShaderDerivative); - break; - case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VERTEX_UNIFORM_COMPONENTS; - break; - case GL_MAX_VARYING_FLOATS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VARYING_FLOATS; - break; - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VERTEX_TEXTURE_IMAGE_UNITS; - break; - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: - CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname); - } -} - - -void GLAPIENTRY -_mesa_GetDoublev( GLenum pname, GLdouble *params ) -{ - const GLfloat magic = -1234.5F; - GLfloat values[16]; - GLuint i; - - if (!params) - return; - - /* Init temp array to magic numbers so we can figure out how many values - * are returned by the GetFloatv() call. - */ - for (i = 0; i < 16; i++) - values[i] = magic; - - _mesa_GetFloatv(pname, values); - - for (i = 0; i < 16 && values[i] != magic; i++) - params[i] = (GLdouble) values[i]; -} - diff --git a/target-i386/mesa_gl.h b/target-i386/mesa_gl.h deleted file mode 100644 index f1ddb5b..0000000 --- a/target-i386/mesa_gl.h +++ /dev/null @@ -1,2267 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * 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 - * BRIAN PAUL 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. - */ - - -#ifndef __gl_h_ -#define __gl_h_ - -#if defined(USE_MGL_NAMESPACE) -#include "gl_mangle.h" -#endif - - -/********************************************************************** - * Begin system-specific stuff. Do not do any of this when building - * for SciTech SNAP, as this is all done before this header file is - * included. - */ -#if !defined(__SCITECH_SNAP__) - -#if defined(__BEOS__) -#include /* to get some BeOS-isms */ -#endif - -#if !defined(OPENSTEP) && (defined(NeXT) || defined(NeXT_PDO)) -#define OPENSTEP -#endif - -#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) -#define __WIN32__ -#endif - -/* GLAPI, part 1 (use WINGDIAPI, if defined) */ -#if defined(__WIN32__) && defined(WINGDIAPI) -# define GLAPI WINGDIAPI -#endif - - -#if !defined(GLAPI) -#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__)) -# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GL32) /* tag specify we're building mesa as a DLL */ -# define GLAPI __declspec(dllexport) -# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ -# define GLAPI __declspec(dllimport) -# else /* for use with static link lib build of Win32 edition only */ -# define GLAPI extern -# endif /* _STATIC_MESA support */ -# define GLAPIENTRY __stdcall -#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ -# define GLAPI extern -# define GLAPIENTRY __stdcall -#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 -# define GLAPI __attribute__((visibility("default"))) -# define GLAPIENTRY -#endif /* WIN32 && !CYGWIN */ -#else -#if !defined(GLAPIENTRY) -# if defined(__WIN32__) -# define GLAPIENTRY __stdcall -# else -# define GLAPIENTRY -# endif -#endif -#endif - -#if (defined(__BEOS__) && defined(__POWERPC__)) || defined(__QUICKDRAW__) -# define PRAGMA_EXPORT_SUPPORTED 1 -#endif - -/* - * WINDOWS: Include windows.h here to define APIENTRY. - * It is also useful when applications include this file by - * including only glut.h, since glut.h depends on windows.h. - * Applications needing to include windows.h with parms other - * than "WIN32_LEAN_AND_MEAN" may include windows.h before - * glut.h or gl.h. - */ -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP) && !defined(__CYGWIN__) -#include -#endif - -#if defined(macintosh) && PRAGMA_IMPORT_SUPPORTED -#pragma import on -#endif - -#ifndef GLAPI -#define GLAPI extern -#endif - -#ifndef GLAPIENTRY -#define GLAPIENTRY -#endif - -#ifndef APIENTRY -#define APIENTRY GLAPIENTRY -#endif - -/* "P" suffix to be used for a pointer to a function */ -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif - -#ifndef GLAPIENTRYP -#define GLAPIENTRYP GLAPIENTRY * -#endif - -#ifdef CENTERLINE_CLPP -#define signed -#endif - -#if defined(PRAGMA_EXPORT_SUPPORTED) -#pragma export on -#endif - -#endif /* !__SCITECH_SNAP__ */ -/* - * End system-specific stuff. - **********************************************************************/ - - - -#ifdef __cplusplus -extern "C" { -#endif - - - -#define GL_VERSION_1_1 1 -#define GL_VERSION_1_2 1 -#define GL_VERSION_1_3 1 -#define GL_ARB_imaging 1 - - -/* - * Datatypes - */ -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef void GLvoid; -typedef signed char GLbyte; /* 1-byte signed */ -typedef short GLshort; /* 2-byte signed */ -typedef int GLint; /* 4-byte signed */ -typedef unsigned char GLubyte; /* 1-byte unsigned */ -typedef unsigned short GLushort; /* 2-byte unsigned */ -typedef unsigned int GLuint; /* 4-byte unsigned */ -typedef int GLsizei; /* 4-byte signed */ -typedef float GLfloat; /* single precision float */ -typedef float GLclampf; /* single precision float in [0,1] */ -typedef double GLdouble; /* double precision float */ -typedef double GLclampd; /* double precision float in [0,1] */ - - - -/* - * Constants - */ - -/* Boolean values */ -#define GL_FALSE 0x0 -#define GL_TRUE 0x1 - -/* Data types */ -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_2_BYTES 0x1407 -#define GL_3_BYTES 0x1408 -#define GL_4_BYTES 0x1409 -#define GL_DOUBLE 0x140A - -/* Primitives */ -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_QUADS 0x0007 -#define GL_QUAD_STRIP 0x0008 -#define GL_POLYGON 0x0009 - -/* Vertex Arrays */ -#define GL_VERTEX_ARRAY 0x8074 -#define GL_NORMAL_ARRAY 0x8075 -#define GL_COLOR_ARRAY 0x8076 -#define GL_INDEX_ARRAY 0x8077 -#define GL_TEXTURE_COORD_ARRAY 0x8078 -#define GL_EDGE_FLAG_ARRAY 0x8079 -#define GL_VERTEX_ARRAY_SIZE 0x807A -#define GL_VERTEX_ARRAY_TYPE 0x807B -#define GL_VERTEX_ARRAY_STRIDE 0x807C -#define GL_NORMAL_ARRAY_TYPE 0x807E -#define GL_NORMAL_ARRAY_STRIDE 0x807F -#define GL_COLOR_ARRAY_SIZE 0x8081 -#define GL_COLOR_ARRAY_TYPE 0x8082 -#define GL_COLOR_ARRAY_STRIDE 0x8083 -#define GL_INDEX_ARRAY_TYPE 0x8085 -#define GL_INDEX_ARRAY_STRIDE 0x8086 -#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A -#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C -#define GL_VERTEX_ARRAY_POINTER 0x808E -#define GL_NORMAL_ARRAY_POINTER 0x808F -#define GL_COLOR_ARRAY_POINTER 0x8090 -#define GL_INDEX_ARRAY_POINTER 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 -#define GL_V2F 0x2A20 -#define GL_V3F 0x2A21 -#define GL_C4UB_V2F 0x2A22 -#define GL_C4UB_V3F 0x2A23 -#define GL_C3F_V3F 0x2A24 -#define GL_N3F_V3F 0x2A25 -#define GL_C4F_N3F_V3F 0x2A26 -#define GL_T2F_V3F 0x2A27 -#define GL_T4F_V4F 0x2A28 -#define GL_T2F_C4UB_V3F 0x2A29 -#define GL_T2F_C3F_V3F 0x2A2A -#define GL_T2F_N3F_V3F 0x2A2B -#define GL_T2F_C4F_N3F_V3F 0x2A2C -#define GL_T4F_C4F_N3F_V4F 0x2A2D - -/* Matrix Mode */ -#define GL_MATRIX_MODE 0x0BA0 -#define GL_MODELVIEW 0x1700 -#define GL_PROJECTION 0x1701 -#define GL_TEXTURE 0x1702 - -/* Points */ -#define GL_POINT_SMOOTH 0x0B10 -#define GL_POINT_SIZE 0x0B11 -#define GL_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_POINT_SIZE_RANGE 0x0B12 - -/* Lines */ -#define GL_LINE_SMOOTH 0x0B20 -#define GL_LINE_STIPPLE 0x0B24 -#define GL_LINE_STIPPLE_PATTERN 0x0B25 -#define GL_LINE_STIPPLE_REPEAT 0x0B26 -#define GL_LINE_WIDTH 0x0B21 -#define GL_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_LINE_WIDTH_RANGE 0x0B22 - -/* Polygons */ -#define GL_POINT 0x1B00 -#define GL_LINE 0x1B01 -#define GL_FILL 0x1B02 -#define GL_CW 0x0900 -#define GL_CCW 0x0901 -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_POLYGON_MODE 0x0B40 -#define GL_POLYGON_SMOOTH 0x0B41 -#define GL_POLYGON_STIPPLE 0x0B42 -#define GL_EDGE_FLAG 0x0B43 -#define GL_CULL_FACE 0x0B44 -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_OFFSET_POINT 0x2A01 -#define GL_POLYGON_OFFSET_LINE 0x2A02 -#define GL_POLYGON_OFFSET_FILL 0x8037 - -/* Display Lists */ -#define GL_COMPILE 0x1300 -#define GL_COMPILE_AND_EXECUTE 0x1301 -#define GL_LIST_BASE 0x0B32 -#define GL_LIST_INDEX 0x0B33 -#define GL_LIST_MODE 0x0B30 - -/* Depth buffer */ -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 -#define GL_DEPTH_TEST 0x0B71 -#define GL_DEPTH_BITS 0x0D56 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_COMPONENT 0x1902 - -/* Lighting */ -#define GL_LIGHTING 0x0B50 -#define GL_LIGHT0 0x4000 -#define GL_LIGHT1 0x4001 -#define GL_LIGHT2 0x4002 -#define GL_LIGHT3 0x4003 -#define GL_LIGHT4 0x4004 -#define GL_LIGHT5 0x4005 -#define GL_LIGHT6 0x4006 -#define GL_LIGHT7 0x4007 -#define GL_SPOT_EXPONENT 0x1205 -#define GL_SPOT_CUTOFF 0x1206 -#define GL_CONSTANT_ATTENUATION 0x1207 -#define GL_LINEAR_ATTENUATION 0x1208 -#define GL_QUADRATIC_ATTENUATION 0x1209 -#define GL_AMBIENT 0x1200 -#define GL_DIFFUSE 0x1201 -#define GL_SPECULAR 0x1202 -#define GL_SHININESS 0x1601 -#define GL_EMISSION 0x1600 -#define GL_POSITION 0x1203 -#define GL_SPOT_DIRECTION 0x1204 -#define GL_AMBIENT_AND_DIFFUSE 0x1602 -#define GL_COLOR_INDEXES 0x1603 -#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 -#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 -#define GL_LIGHT_MODEL_AMBIENT 0x0B53 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_SHADE_MODEL 0x0B54 -#define GL_FLAT 0x1D00 -#define GL_SMOOTH 0x1D01 -#define GL_COLOR_MATERIAL 0x0B57 -#define GL_COLOR_MATERIAL_FACE 0x0B55 -#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 -#define GL_NORMALIZE 0x0BA1 - -/* User clipping planes */ -#define GL_CLIP_PLANE0 0x3000 -#define GL_CLIP_PLANE1 0x3001 -#define GL_CLIP_PLANE2 0x3002 -#define GL_CLIP_PLANE3 0x3003 -#define GL_CLIP_PLANE4 0x3004 -#define GL_CLIP_PLANE5 0x3005 - -/* Accumulation buffer */ -#define GL_ACCUM_RED_BITS 0x0D58 -#define GL_ACCUM_GREEN_BITS 0x0D59 -#define GL_ACCUM_BLUE_BITS 0x0D5A -#define GL_ACCUM_ALPHA_BITS 0x0D5B -#define GL_ACCUM_CLEAR_VALUE 0x0B80 -#define GL_ACCUM 0x0100 -#define GL_ADD 0x0104 -#define GL_LOAD 0x0101 -#define GL_MULT 0x0103 -#define GL_RETURN 0x0102 - -/* Alpha testing */ -#define GL_ALPHA_TEST 0x0BC0 -#define GL_ALPHA_TEST_REF 0x0BC2 -#define GL_ALPHA_TEST_FUNC 0x0BC1 - -/* Blending */ -#define GL_BLEND 0x0BE2 -#define GL_BLEND_SRC 0x0BE1 -#define GL_BLEND_DST 0x0BE0 -#define GL_ZERO 0x0 -#define GL_ONE 0x1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 - -/* Render Mode */ -#define GL_FEEDBACK 0x1C01 -#define GL_RENDER 0x1C00 -#define GL_SELECT 0x1C02 - -/* Feedback */ -#define GL_2D 0x0600 -#define GL_3D 0x0601 -#define GL_3D_COLOR 0x0602 -#define GL_3D_COLOR_TEXTURE 0x0603 -#define GL_4D_COLOR_TEXTURE 0x0604 -#define GL_POINT_TOKEN 0x0701 -#define GL_LINE_TOKEN 0x0702 -#define GL_LINE_RESET_TOKEN 0x0707 -#define GL_POLYGON_TOKEN 0x0703 -#define GL_BITMAP_TOKEN 0x0704 -#define GL_DRAW_PIXEL_TOKEN 0x0705 -#define GL_COPY_PIXEL_TOKEN 0x0706 -#define GL_PASS_THROUGH_TOKEN 0x0700 -#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 -#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 -#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 - -/* Selection */ -#define GL_SELECTION_BUFFER_POINTER 0x0DF3 -#define GL_SELECTION_BUFFER_SIZE 0x0DF4 - -/* Fog */ -#define GL_FOG 0x0B60 -#define GL_FOG_MODE 0x0B65 -#define GL_FOG_DENSITY 0x0B62 -#define GL_FOG_COLOR 0x0B66 -#define GL_FOG_INDEX 0x0B61 -#define GL_FOG_START 0x0B63 -#define GL_FOG_END 0x0B64 -#define GL_LINEAR 0x2601 -#define GL_EXP 0x0800 -#define GL_EXP2 0x0801 - -/* Logic Ops */ -#define GL_LOGIC_OP 0x0BF1 -#define GL_INDEX_LOGIC_OP 0x0BF1 -#define GL_COLOR_LOGIC_OP 0x0BF2 -#define GL_LOGIC_OP_MODE 0x0BF0 -#define GL_CLEAR 0x1500 -#define GL_SET 0x150F -#define GL_COPY 0x1503 -#define GL_COPY_INVERTED 0x150C -#define GL_NOOP 0x1505 -#define GL_INVERT 0x150A -#define GL_AND 0x1501 -#define GL_NAND 0x150E -#define GL_OR 0x1507 -#define GL_NOR 0x1508 -#define GL_XOR 0x1506 -#define GL_EQUIV 0x1509 -#define GL_AND_REVERSE 0x1502 -#define GL_AND_INVERTED 0x1504 -#define GL_OR_REVERSE 0x150B -#define GL_OR_INVERTED 0x150D - -/* Stencil */ -#define GL_STENCIL_BITS 0x0D57 -#define GL_STENCIL_TEST 0x0B90 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STENCIL_INDEX 0x1901 -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 - -/* Buffers, Pixel Drawing/Reading */ -#define GL_NONE 0x0 -#define GL_LEFT 0x0406 -#define GL_RIGHT 0x0407 -/*GL_FRONT 0x0404 */ -/*GL_BACK 0x0405 */ -/*GL_FRONT_AND_BACK 0x0408 */ -#define GL_FRONT_LEFT 0x0400 -#define GL_FRONT_RIGHT 0x0401 -#define GL_BACK_LEFT 0x0402 -#define GL_BACK_RIGHT 0x0403 -#define GL_AUX0 0x0409 -#define GL_AUX1 0x040A -#define GL_AUX2 0x040B -#define GL_AUX3 0x040C -#define GL_COLOR_INDEX 0x1900 -#define GL_RED 0x1903 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_ALPHA 0x1906 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#define GL_ALPHA_BITS 0x0D55 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_INDEX_BITS 0x0D51 -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_AUX_BUFFERS 0x0C00 -#define GL_READ_BUFFER 0x0C02 -#define GL_DRAW_BUFFER 0x0C01 -#define GL_DOUBLEBUFFER 0x0C32 -#define GL_STEREO 0x0C33 -#define GL_BITMAP 0x1A00 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_DITHER 0x0BD0 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 - -/* Implementation limits */ -#define GL_MAX_LIST_NESTING 0x0B31 -#define GL_MAX_EVAL_ORDER 0x0D30 -#define GL_MAX_LIGHTS 0x0D31 -#define GL_MAX_CLIP_PLANES 0x0D32 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 -#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 -#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 -#define GL_MAX_NAME_STACK_DEPTH 0x0D37 -#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 -#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B - -/* Gets */ -#define GL_ATTRIB_STACK_DEPTH 0x0BB0 -#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_CURRENT_INDEX 0x0B01 -#define GL_CURRENT_COLOR 0x0B00 -#define GL_CURRENT_NORMAL 0x0B02 -#define GL_CURRENT_RASTER_COLOR 0x0B04 -#define GL_CURRENT_RASTER_DISTANCE 0x0B09 -#define GL_CURRENT_RASTER_INDEX 0x0B05 -#define GL_CURRENT_RASTER_POSITION 0x0B07 -#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 -#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 -#define GL_CURRENT_TEXTURE_COORDS 0x0B03 -#define GL_INDEX_CLEAR_VALUE 0x0C20 -#define GL_INDEX_MODE 0x0C30 -#define GL_INDEX_WRITEMASK 0x0C21 -#define GL_MODELVIEW_MATRIX 0x0BA6 -#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 -#define GL_NAME_STACK_DEPTH 0x0D70 -#define GL_PROJECTION_MATRIX 0x0BA7 -#define GL_PROJECTION_STACK_DEPTH 0x0BA4 -#define GL_RENDER_MODE 0x0C40 -#define GL_RGBA_MODE 0x0C31 -#define GL_TEXTURE_MATRIX 0x0BA8 -#define GL_TEXTURE_STACK_DEPTH 0x0BA5 -#define GL_VIEWPORT 0x0BA2 - -/* Evaluators */ -#define GL_AUTO_NORMAL 0x0D80 -#define GL_MAP1_COLOR_4 0x0D90 -#define GL_MAP1_INDEX 0x0D91 -#define GL_MAP1_NORMAL 0x0D92 -#define GL_MAP1_TEXTURE_COORD_1 0x0D93 -#define GL_MAP1_TEXTURE_COORD_2 0x0D94 -#define GL_MAP1_TEXTURE_COORD_3 0x0D95 -#define GL_MAP1_TEXTURE_COORD_4 0x0D96 -#define GL_MAP1_VERTEX_3 0x0D97 -#define GL_MAP1_VERTEX_4 0x0D98 -#define GL_MAP2_COLOR_4 0x0DB0 -#define GL_MAP2_INDEX 0x0DB1 -#define GL_MAP2_NORMAL 0x0DB2 -#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 -#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 -#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 -#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 -#define GL_MAP2_VERTEX_3 0x0DB7 -#define GL_MAP2_VERTEX_4 0x0DB8 -#define GL_MAP1_GRID_DOMAIN 0x0DD0 -#define GL_MAP1_GRID_SEGMENTS 0x0DD1 -#define GL_MAP2_GRID_DOMAIN 0x0DD2 -#define GL_MAP2_GRID_SEGMENTS 0x0DD3 -#define GL_COEFF 0x0A00 -#define GL_ORDER 0x0A01 -#define GL_DOMAIN 0x0A02 - -/* Hints */ -#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 -#define GL_POINT_SMOOTH_HINT 0x0C51 -#define GL_LINE_SMOOTH_HINT 0x0C52 -#define GL_POLYGON_SMOOTH_HINT 0x0C53 -#define GL_FOG_HINT 0x0C54 -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 - -/* Scissor box */ -#define GL_SCISSOR_BOX 0x0C10 -#define GL_SCISSOR_TEST 0x0C11 - -/* Pixel Mode / Transfer */ -#define GL_MAP_COLOR 0x0D10 -#define GL_MAP_STENCIL 0x0D11 -#define GL_INDEX_SHIFT 0x0D12 -#define GL_INDEX_OFFSET 0x0D13 -#define GL_RED_SCALE 0x0D14 -#define GL_RED_BIAS 0x0D15 -#define GL_GREEN_SCALE 0x0D18 -#define GL_GREEN_BIAS 0x0D19 -#define GL_BLUE_SCALE 0x0D1A -#define GL_BLUE_BIAS 0x0D1B -#define GL_ALPHA_SCALE 0x0D1C -#define GL_ALPHA_BIAS 0x0D1D -#define GL_DEPTH_SCALE 0x0D1E -#define GL_DEPTH_BIAS 0x0D1F -#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 -#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 -#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 -#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 -#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 -#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 -#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 -#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 -#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 -#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 -#define GL_PIXEL_MAP_S_TO_S 0x0C71 -#define GL_PIXEL_MAP_I_TO_I 0x0C70 -#define GL_PIXEL_MAP_I_TO_R 0x0C72 -#define GL_PIXEL_MAP_I_TO_G 0x0C73 -#define GL_PIXEL_MAP_I_TO_B 0x0C74 -#define GL_PIXEL_MAP_I_TO_A 0x0C75 -#define GL_PIXEL_MAP_R_TO_R 0x0C76 -#define GL_PIXEL_MAP_G_TO_G 0x0C77 -#define GL_PIXEL_MAP_B_TO_B 0x0C78 -#define GL_PIXEL_MAP_A_TO_A 0x0C79 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_PACK_LSB_FIRST 0x0D01 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SWAP_BYTES 0x0D00 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_UNPACK_LSB_FIRST 0x0CF1 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SWAP_BYTES 0x0CF0 -#define GL_ZOOM_X 0x0D16 -#define GL_ZOOM_Y 0x0D17 - -/* Texture mapping */ -#define GL_TEXTURE_ENV 0x2300 -#define GL_TEXTURE_ENV_MODE 0x2200 -#define GL_TEXTURE_1D 0x0DE0 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_ENV_COLOR 0x2201 -#define GL_TEXTURE_GEN_S 0x0C60 -#define GL_TEXTURE_GEN_T 0x0C61 -#define GL_TEXTURE_GEN_MODE 0x2500 -#define GL_TEXTURE_BORDER_COLOR 0x1004 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_BORDER 0x1005 -#define GL_TEXTURE_COMPONENTS 0x1003 -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE 0x8061 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_OBJECT_LINEAR 0x2401 -#define GL_OBJECT_PLANE 0x2501 -#define GL_EYE_LINEAR 0x2400 -#define GL_EYE_PLANE 0x2502 -#define GL_SPHERE_MAP 0x2402 -#define GL_DECAL 0x2101 -#define GL_MODULATE 0x2100 -#define GL_NEAREST 0x2600 -#define GL_REPEAT 0x2901 -#define GL_CLAMP 0x2900 -#define GL_S 0x2000 -#define GL_T 0x2001 -#define GL_R 0x2002 -#define GL_Q 0x2003 -#define GL_TEXTURE_GEN_R 0x0C62 -#define GL_TEXTURE_GEN_Q 0x0C63 - -/* Utility */ -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 - -/* Errors */ -#define GL_NO_ERROR 0x0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_OUT_OF_MEMORY 0x0505 - -/* glPush/PopAttrib bits */ -#define GL_CURRENT_BIT 0x00000001 -#define GL_POINT_BIT 0x00000002 -#define GL_LINE_BIT 0x00000004 -#define GL_POLYGON_BIT 0x00000008 -#define GL_POLYGON_STIPPLE_BIT 0x00000010 -#define GL_PIXEL_MODE_BIT 0x00000020 -#define GL_LIGHTING_BIT 0x00000040 -#define GL_FOG_BIT 0x00000080 -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_ACCUM_BUFFER_BIT 0x00000200 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_VIEWPORT_BIT 0x00000800 -#define GL_TRANSFORM_BIT 0x00001000 -#define GL_ENABLE_BIT 0x00002000 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_HINT_BIT 0x00008000 -#define GL_EVAL_BIT 0x00010000 -#define GL_LIST_BIT 0x00020000 -#define GL_TEXTURE_BIT 0x00040000 -#define GL_SCISSOR_BIT 0x00080000 -#define GL_ALL_ATTRIB_BITS 0x000FFFFF - - -/* OpenGL 1.1 */ -#define GL_PROXY_TEXTURE_1D 0x8063 -#define GL_PROXY_TEXTURE_2D 0x8064 -#define GL_TEXTURE_PRIORITY 0x8066 -#define GL_TEXTURE_RESIDENT 0x8067 -#define GL_TEXTURE_BINDING_1D 0x8068 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_ALPHA4 0x803B -#define GL_ALPHA8 0x803C -#define GL_ALPHA12 0x803D -#define GL_ALPHA16 0x803E -#define GL_LUMINANCE4 0x803F -#define GL_LUMINANCE8 0x8040 -#define GL_LUMINANCE12 0x8041 -#define GL_LUMINANCE16 0x8042 -#define GL_LUMINANCE4_ALPHA4 0x8043 -#define GL_LUMINANCE6_ALPHA2 0x8044 -#define GL_LUMINANCE8_ALPHA8 0x8045 -#define GL_LUMINANCE12_ALPHA4 0x8046 -#define GL_LUMINANCE12_ALPHA12 0x8047 -#define GL_LUMINANCE16_ALPHA16 0x8048 -#define GL_INTENSITY 0x8049 -#define GL_INTENSITY4 0x804A -#define GL_INTENSITY8 0x804B -#define GL_INTENSITY12 0x804C -#define GL_INTENSITY16 0x804D -#define GL_R3_G3_B2 0x2A10 -#define GL_RGB4 0x804F -#define GL_RGB5 0x8050 -#define GL_RGB8 0x8051 -#define GL_RGB10 0x8052 -#define GL_RGB12 0x8053 -#define GL_RGB16 0x8054 -#define GL_RGBA2 0x8055 -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_RGBA12 0x805A -#define GL_RGBA16 0x805B -#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 -#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 -#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF -#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF - - - -/* - * Miscellaneous - */ - -GLAPI void GLAPIENTRY glClearIndex( GLfloat c ); - -GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); - -GLAPI void GLAPIENTRY glClear( GLbitfield mask ); - -GLAPI void GLAPIENTRY glIndexMask( GLuint mask ); - -GLAPI void GLAPIENTRY glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); - -GLAPI void GLAPIENTRY glAlphaFunc( GLenum func, GLclampf ref ); - -GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ); - -GLAPI void GLAPIENTRY glLogicOp( GLenum opcode ); - -GLAPI void GLAPIENTRY glCullFace( GLenum mode ); - -GLAPI void GLAPIENTRY glFrontFace( GLenum mode ); - -GLAPI void GLAPIENTRY glPointSize( GLfloat size ); - -GLAPI void GLAPIENTRY glLineWidth( GLfloat width ); - -GLAPI void GLAPIENTRY glLineStipple( GLint factor, GLushort pattern ); - -GLAPI void GLAPIENTRY glPolygonMode( GLenum face, GLenum mode ); - -GLAPI void GLAPIENTRY glPolygonOffset( GLfloat factor, GLfloat units ); - -GLAPI void GLAPIENTRY glPolygonStipple( const GLubyte *mask ); - -GLAPI void GLAPIENTRY glGetPolygonStipple( GLubyte *mask ); - -GLAPI void GLAPIENTRY glEdgeFlag( GLboolean flag ); - -GLAPI void GLAPIENTRY glEdgeFlagv( const GLboolean *flag ); - -GLAPI void GLAPIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height); - -GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation ); - -GLAPI void GLAPIENTRY glGetClipPlane( GLenum plane, GLdouble *equation ); - -GLAPI void GLAPIENTRY glDrawBuffer( GLenum mode ); - -GLAPI void GLAPIENTRY glReadBuffer( GLenum mode ); - -GLAPI void GLAPIENTRY glEnable( GLenum cap ); - -GLAPI void GLAPIENTRY glDisable( GLenum cap ); - -GLAPI GLboolean GLAPIENTRY glIsEnabled( GLenum cap ); - - -GLAPI void GLAPIENTRY glEnableClientState( GLenum cap ); /* 1.1 */ - -GLAPI void GLAPIENTRY glDisableClientState( GLenum cap ); /* 1.1 */ - - -GLAPI void GLAPIENTRY glGetBooleanv( GLenum pname, GLboolean *params ); - -GLAPI void GLAPIENTRY glGetDoublev( GLenum pname, GLdouble *params ); - -GLAPI void GLAPIENTRY glGetFloatv( GLenum pname, GLfloat *params ); - -GLAPI void GLAPIENTRY glGetIntegerv( GLenum pname, GLint *params ); - - -GLAPI void GLAPIENTRY glPushAttrib( GLbitfield mask ); - -GLAPI void GLAPIENTRY glPopAttrib( void ); - - -GLAPI void GLAPIENTRY glPushClientAttrib( GLbitfield mask ); /* 1.1 */ - -GLAPI void GLAPIENTRY glPopClientAttrib( void ); /* 1.1 */ - - -GLAPI GLint GLAPIENTRY glRenderMode( GLenum mode ); - -GLAPI GLenum GLAPIENTRY glGetError( void ); - -GLAPI const GLubyte * GLAPIENTRY glGetString( GLenum name ); - -GLAPI void GLAPIENTRY glFinish( void ); - -GLAPI void GLAPIENTRY glFlush( void ); - -GLAPI void GLAPIENTRY glHint( GLenum target, GLenum mode ); - - -/* - * Depth Buffer - */ - -GLAPI void GLAPIENTRY glClearDepth( GLclampd depth ); - -GLAPI void GLAPIENTRY glDepthFunc( GLenum func ); - -GLAPI void GLAPIENTRY glDepthMask( GLboolean flag ); - -GLAPI void GLAPIENTRY glDepthRange( GLclampd near_val, GLclampd far_val ); - - -/* - * Accumulation Buffer - */ - -GLAPI void GLAPIENTRY glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); - -GLAPI void GLAPIENTRY glAccum( GLenum op, GLfloat value ); - - -/* - * Transformation - */ - -GLAPI void GLAPIENTRY glMatrixMode( GLenum mode ); - -GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right, - GLdouble bottom, GLdouble top, - GLdouble near_val, GLdouble far_val ); - -GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right, - GLdouble bottom, GLdouble top, - GLdouble near_val, GLdouble far_val ); - -GLAPI void GLAPIENTRY glViewport( GLint x, GLint y, - GLsizei width, GLsizei height ); - -GLAPI void GLAPIENTRY glPushMatrix( void ); - -GLAPI void GLAPIENTRY glPopMatrix( void ); - -GLAPI void GLAPIENTRY glLoadIdentity( void ); - -GLAPI void GLAPIENTRY glLoadMatrixd( const GLdouble *m ); -GLAPI void GLAPIENTRY glLoadMatrixf( const GLfloat *m ); - -GLAPI void GLAPIENTRY glMultMatrixd( const GLdouble *m ); -GLAPI void GLAPIENTRY glMultMatrixf( const GLfloat *m ); - -GLAPI void GLAPIENTRY glRotated( GLdouble angle, - GLdouble x, GLdouble y, GLdouble z ); -GLAPI void GLAPIENTRY glRotatef( GLfloat angle, - GLfloat x, GLfloat y, GLfloat z ); - -GLAPI void GLAPIENTRY glScaled( GLdouble x, GLdouble y, GLdouble z ); -GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z ); - -GLAPI void GLAPIENTRY glTranslated( GLdouble x, GLdouble y, GLdouble z ); -GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z ); - - -/* - * Display Lists - */ - -GLAPI GLboolean GLAPIENTRY glIsList( GLuint list ); - -GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range ); - -GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range ); - -GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode ); - -GLAPI void GLAPIENTRY glEndList( void ); - -GLAPI void GLAPIENTRY glCallList( GLuint list ); - -GLAPI void GLAPIENTRY glCallLists( GLsizei n, GLenum type, - const GLvoid *lists ); - -GLAPI void GLAPIENTRY glListBase( GLuint base ); - - -/* - * Drawing Functions - */ - -GLAPI void GLAPIENTRY glBegin( GLenum mode ); - -GLAPI void GLAPIENTRY glEnd( void ); - - -GLAPI void GLAPIENTRY glVertex2d( GLdouble x, GLdouble y ); -GLAPI void GLAPIENTRY glVertex2f( GLfloat x, GLfloat y ); -GLAPI void GLAPIENTRY glVertex2i( GLint x, GLint y ); -GLAPI void GLAPIENTRY glVertex2s( GLshort x, GLshort y ); - -GLAPI void GLAPIENTRY glVertex3d( GLdouble x, GLdouble y, GLdouble z ); -GLAPI void GLAPIENTRY glVertex3f( GLfloat x, GLfloat y, GLfloat z ); -GLAPI void GLAPIENTRY glVertex3i( GLint x, GLint y, GLint z ); -GLAPI void GLAPIENTRY glVertex3s( GLshort x, GLshort y, GLshort z ); - -GLAPI void GLAPIENTRY glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); -GLAPI void GLAPIENTRY glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); -GLAPI void GLAPIENTRY glVertex4i( GLint x, GLint y, GLint z, GLint w ); -GLAPI void GLAPIENTRY glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w ); - -GLAPI void GLAPIENTRY glVertex2dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glVertex2fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glVertex2iv( const GLint *v ); -GLAPI void GLAPIENTRY glVertex2sv( const GLshort *v ); - -GLAPI void GLAPIENTRY glVertex3dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glVertex3fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glVertex3iv( const GLint *v ); -GLAPI void GLAPIENTRY glVertex3sv( const GLshort *v ); - -GLAPI void GLAPIENTRY glVertex4dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glVertex4fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glVertex4iv( const GLint *v ); -GLAPI void GLAPIENTRY glVertex4sv( const GLshort *v ); - - -GLAPI void GLAPIENTRY glNormal3b( GLbyte nx, GLbyte ny, GLbyte nz ); -GLAPI void GLAPIENTRY glNormal3d( GLdouble nx, GLdouble ny, GLdouble nz ); -GLAPI void GLAPIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz ); -GLAPI void GLAPIENTRY glNormal3i( GLint nx, GLint ny, GLint nz ); -GLAPI void GLAPIENTRY glNormal3s( GLshort nx, GLshort ny, GLshort nz ); - -GLAPI void GLAPIENTRY glNormal3bv( const GLbyte *v ); -GLAPI void GLAPIENTRY glNormal3dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glNormal3fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glNormal3iv( const GLint *v ); -GLAPI void GLAPIENTRY glNormal3sv( const GLshort *v ); - - -GLAPI void GLAPIENTRY glIndexd( GLdouble c ); -GLAPI void GLAPIENTRY glIndexf( GLfloat c ); -GLAPI void GLAPIENTRY glIndexi( GLint c ); -GLAPI void GLAPIENTRY glIndexs( GLshort c ); -GLAPI void GLAPIENTRY glIndexub( GLubyte c ); /* 1.1 */ - -GLAPI void GLAPIENTRY glIndexdv( const GLdouble *c ); -GLAPI void GLAPIENTRY glIndexfv( const GLfloat *c ); -GLAPI void GLAPIENTRY glIndexiv( const GLint *c ); -GLAPI void GLAPIENTRY glIndexsv( const GLshort *c ); -GLAPI void GLAPIENTRY glIndexubv( const GLubyte *c ); /* 1.1 */ - -GLAPI void GLAPIENTRY glColor3b( GLbyte red, GLbyte green, GLbyte blue ); -GLAPI void GLAPIENTRY glColor3d( GLdouble red, GLdouble green, GLdouble blue ); -GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue ); -GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue ); -GLAPI void GLAPIENTRY glColor3s( GLshort red, GLshort green, GLshort blue ); -GLAPI void GLAPIENTRY glColor3ub( GLubyte red, GLubyte green, GLubyte blue ); -GLAPI void GLAPIENTRY glColor3ui( GLuint red, GLuint green, GLuint blue ); -GLAPI void GLAPIENTRY glColor3us( GLushort red, GLushort green, GLushort blue ); - -GLAPI void GLAPIENTRY glColor4b( GLbyte red, GLbyte green, - GLbyte blue, GLbyte alpha ); -GLAPI void GLAPIENTRY glColor4d( GLdouble red, GLdouble green, - GLdouble blue, GLdouble alpha ); -GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green, - GLfloat blue, GLfloat alpha ); -GLAPI void GLAPIENTRY glColor4i( GLint red, GLint green, - GLint blue, GLint alpha ); -GLAPI void GLAPIENTRY glColor4s( GLshort red, GLshort green, - GLshort blue, GLshort alpha ); -GLAPI void GLAPIENTRY glColor4ub( GLubyte red, GLubyte green, - GLubyte blue, GLubyte alpha ); -GLAPI void GLAPIENTRY glColor4ui( GLuint red, GLuint green, - GLuint blue, GLuint alpha ); -GLAPI void GLAPIENTRY glColor4us( GLushort red, GLushort green, - GLushort blue, GLushort alpha ); - - -GLAPI void GLAPIENTRY glColor3bv( const GLbyte *v ); -GLAPI void GLAPIENTRY glColor3dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glColor3fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glColor3iv( const GLint *v ); -GLAPI void GLAPIENTRY glColor3sv( const GLshort *v ); -GLAPI void GLAPIENTRY glColor3ubv( const GLubyte *v ); -GLAPI void GLAPIENTRY glColor3uiv( const GLuint *v ); -GLAPI void GLAPIENTRY glColor3usv( const GLushort *v ); - -GLAPI void GLAPIENTRY glColor4bv( const GLbyte *v ); -GLAPI void GLAPIENTRY glColor4dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glColor4iv( const GLint *v ); -GLAPI void GLAPIENTRY glColor4sv( const GLshort *v ); -GLAPI void GLAPIENTRY glColor4ubv( const GLubyte *v ); -GLAPI void GLAPIENTRY glColor4uiv( const GLuint *v ); -GLAPI void GLAPIENTRY glColor4usv( const GLushort *v ); - - -GLAPI void GLAPIENTRY glTexCoord1d( GLdouble s ); -GLAPI void GLAPIENTRY glTexCoord1f( GLfloat s ); -GLAPI void GLAPIENTRY glTexCoord1i( GLint s ); -GLAPI void GLAPIENTRY glTexCoord1s( GLshort s ); - -GLAPI void GLAPIENTRY glTexCoord2d( GLdouble s, GLdouble t ); -GLAPI void GLAPIENTRY glTexCoord2f( GLfloat s, GLfloat t ); -GLAPI void GLAPIENTRY glTexCoord2i( GLint s, GLint t ); -GLAPI void GLAPIENTRY glTexCoord2s( GLshort s, GLshort t ); - -GLAPI void GLAPIENTRY glTexCoord3d( GLdouble s, GLdouble t, GLdouble r ); -GLAPI void GLAPIENTRY glTexCoord3f( GLfloat s, GLfloat t, GLfloat r ); -GLAPI void GLAPIENTRY glTexCoord3i( GLint s, GLint t, GLint r ); -GLAPI void GLAPIENTRY glTexCoord3s( GLshort s, GLshort t, GLshort r ); - -GLAPI void GLAPIENTRY glTexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q ); -GLAPI void GLAPIENTRY glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ); -GLAPI void GLAPIENTRY glTexCoord4i( GLint s, GLint t, GLint r, GLint q ); -GLAPI void GLAPIENTRY glTexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q ); - -GLAPI void GLAPIENTRY glTexCoord1dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glTexCoord1fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glTexCoord1iv( const GLint *v ); -GLAPI void GLAPIENTRY glTexCoord1sv( const GLshort *v ); - -GLAPI void GLAPIENTRY glTexCoord2dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glTexCoord2fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glTexCoord2iv( const GLint *v ); -GLAPI void GLAPIENTRY glTexCoord2sv( const GLshort *v ); - -GLAPI void GLAPIENTRY glTexCoord3dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glTexCoord3fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glTexCoord3iv( const GLint *v ); -GLAPI void GLAPIENTRY glTexCoord3sv( const GLshort *v ); - -GLAPI void GLAPIENTRY glTexCoord4dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glTexCoord4fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glTexCoord4iv( const GLint *v ); -GLAPI void GLAPIENTRY glTexCoord4sv( const GLshort *v ); - - -GLAPI void GLAPIENTRY glRasterPos2d( GLdouble x, GLdouble y ); -GLAPI void GLAPIENTRY glRasterPos2f( GLfloat x, GLfloat y ); -GLAPI void GLAPIENTRY glRasterPos2i( GLint x, GLint y ); -GLAPI void GLAPIENTRY glRasterPos2s( GLshort x, GLshort y ); - -GLAPI void GLAPIENTRY glRasterPos3d( GLdouble x, GLdouble y, GLdouble z ); -GLAPI void GLAPIENTRY glRasterPos3f( GLfloat x, GLfloat y, GLfloat z ); -GLAPI void GLAPIENTRY glRasterPos3i( GLint x, GLint y, GLint z ); -GLAPI void GLAPIENTRY glRasterPos3s( GLshort x, GLshort y, GLshort z ); - -GLAPI void GLAPIENTRY glRasterPos4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); -GLAPI void GLAPIENTRY glRasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ); -GLAPI void GLAPIENTRY glRasterPos4i( GLint x, GLint y, GLint z, GLint w ); -GLAPI void GLAPIENTRY glRasterPos4s( GLshort x, GLshort y, GLshort z, GLshort w ); - -GLAPI void GLAPIENTRY glRasterPos2dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glRasterPos2fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glRasterPos2iv( const GLint *v ); -GLAPI void GLAPIENTRY glRasterPos2sv( const GLshort *v ); - -GLAPI void GLAPIENTRY glRasterPos3dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glRasterPos3fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glRasterPos3iv( const GLint *v ); -GLAPI void GLAPIENTRY glRasterPos3sv( const GLshort *v ); - -GLAPI void GLAPIENTRY glRasterPos4dv( const GLdouble *v ); -GLAPI void GLAPIENTRY glRasterPos4fv( const GLfloat *v ); -GLAPI void GLAPIENTRY glRasterPos4iv( const GLint *v ); -GLAPI void GLAPIENTRY glRasterPos4sv( const GLshort *v ); - - -GLAPI void GLAPIENTRY glRectd( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ); -GLAPI void GLAPIENTRY glRectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); -GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 ); -GLAPI void GLAPIENTRY glRects( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ); - - -GLAPI void GLAPIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 ); -GLAPI void GLAPIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 ); -GLAPI void GLAPIENTRY glRectiv( const GLint *v1, const GLint *v2 ); -GLAPI void GLAPIENTRY glRectsv( const GLshort *v1, const GLshort *v2 ); - - -/* - * Vertex Arrays (1.1) - */ - -GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr ); - -GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride, - const GLvoid *ptr ); - -GLAPI void GLAPIENTRY glColorPointer( GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr ); - -GLAPI void GLAPIENTRY glIndexPointer( GLenum type, GLsizei stride, - const GLvoid *ptr ); - -GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr ); - -GLAPI void GLAPIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr ); - -GLAPI void GLAPIENTRY glGetPointerv( GLenum pname, GLvoid **params ); - -GLAPI void GLAPIENTRY glArrayElement( GLint i ); - -GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ); - -GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count, - GLenum type, const GLvoid *indices ); - -GLAPI void GLAPIENTRY glInterleavedArrays( GLenum format, GLsizei stride, - const GLvoid *pointer ); - -/* - * Lighting - */ - -GLAPI void GLAPIENTRY glShadeModel( GLenum mode ); - -GLAPI void GLAPIENTRY glLightf( GLenum light, GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glLighti( GLenum light, GLenum pname, GLint param ); -GLAPI void GLAPIENTRY glLightfv( GLenum light, GLenum pname, - const GLfloat *params ); -GLAPI void GLAPIENTRY glLightiv( GLenum light, GLenum pname, - const GLint *params ); - -GLAPI void GLAPIENTRY glGetLightfv( GLenum light, GLenum pname, - GLfloat *params ); -GLAPI void GLAPIENTRY glGetLightiv( GLenum light, GLenum pname, - GLint *params ); - -GLAPI void GLAPIENTRY glLightModelf( GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glLightModeli( GLenum pname, GLint param ); -GLAPI void GLAPIENTRY glLightModelfv( GLenum pname, const GLfloat *params ); -GLAPI void GLAPIENTRY glLightModeliv( GLenum pname, const GLint *params ); - -GLAPI void GLAPIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glMateriali( GLenum face, GLenum pname, GLint param ); -GLAPI void GLAPIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params ); -GLAPI void GLAPIENTRY glMaterialiv( GLenum face, GLenum pname, const GLint *params ); - -GLAPI void GLAPIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params ); -GLAPI void GLAPIENTRY glGetMaterialiv( GLenum face, GLenum pname, GLint *params ); - -GLAPI void GLAPIENTRY glColorMaterial( GLenum face, GLenum mode ); - - -/* - * Raster functions - */ - -GLAPI void GLAPIENTRY glPixelZoom( GLfloat xfactor, GLfloat yfactor ); - -GLAPI void GLAPIENTRY glPixelStoref( GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glPixelStorei( GLenum pname, GLint param ); - -GLAPI void GLAPIENTRY glPixelTransferf( GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glPixelTransferi( GLenum pname, GLint param ); - -GLAPI void GLAPIENTRY glPixelMapfv( GLenum map, GLsizei mapsize, - const GLfloat *values ); -GLAPI void GLAPIENTRY glPixelMapuiv( GLenum map, GLsizei mapsize, - const GLuint *values ); -GLAPI void GLAPIENTRY glPixelMapusv( GLenum map, GLsizei mapsize, - const GLushort *values ); - -GLAPI void GLAPIENTRY glGetPixelMapfv( GLenum map, GLfloat *values ); -GLAPI void GLAPIENTRY glGetPixelMapuiv( GLenum map, GLuint *values ); -GLAPI void GLAPIENTRY glGetPixelMapusv( GLenum map, GLushort *values ); - -GLAPI void GLAPIENTRY glBitmap( GLsizei width, GLsizei height, - GLfloat xorig, GLfloat yorig, - GLfloat xmove, GLfloat ymove, - const GLubyte *bitmap ); - -GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels ); - -GLAPI void GLAPIENTRY glDrawPixels( GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels ); - -GLAPI void GLAPIENTRY glCopyPixels( GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type ); - -/* - * Stenciling - */ - -GLAPI void GLAPIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask ); - -GLAPI void GLAPIENTRY glStencilMask( GLuint mask ); - -GLAPI void GLAPIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass ); - -GLAPI void GLAPIENTRY glClearStencil( GLint s ); - - - -/* - * Texture mapping - */ - -GLAPI void GLAPIENTRY glTexGend( GLenum coord, GLenum pname, GLdouble param ); -GLAPI void GLAPIENTRY glTexGenf( GLenum coord, GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glTexGeni( GLenum coord, GLenum pname, GLint param ); - -GLAPI void GLAPIENTRY glTexGendv( GLenum coord, GLenum pname, const GLdouble *params ); -GLAPI void GLAPIENTRY glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); -GLAPI void GLAPIENTRY glTexGeniv( GLenum coord, GLenum pname, const GLint *params ); - -GLAPI void GLAPIENTRY glGetTexGendv( GLenum coord, GLenum pname, GLdouble *params ); -GLAPI void GLAPIENTRY glGetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); -GLAPI void GLAPIENTRY glGetTexGeniv( GLenum coord, GLenum pname, GLint *params ); - - -GLAPI void GLAPIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param ); - -GLAPI void GLAPIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params ); -GLAPI void GLAPIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params ); - -GLAPI void GLAPIENTRY glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ); -GLAPI void GLAPIENTRY glGetTexEnviv( GLenum target, GLenum pname, GLint *params ); - - -GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param ); -GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ); - -GLAPI void GLAPIENTRY glTexParameterfv( GLenum target, GLenum pname, - const GLfloat *params ); -GLAPI void GLAPIENTRY glTexParameteriv( GLenum target, GLenum pname, - const GLint *params ); - -GLAPI void GLAPIENTRY glGetTexParameterfv( GLenum target, - GLenum pname, GLfloat *params); -GLAPI void GLAPIENTRY glGetTexParameteriv( GLenum target, - GLenum pname, GLint *params ); - -GLAPI void GLAPIENTRY glGetTexLevelParameterfv( GLenum target, GLint level, - GLenum pname, GLfloat *params ); -GLAPI void GLAPIENTRY glGetTexLevelParameteriv( GLenum target, GLint level, - GLenum pname, GLint *params ); - - -GLAPI void GLAPIENTRY glTexImage1D( GLenum target, GLint level, - GLint internalFormat, - GLsizei width, GLint border, - GLenum format, GLenum type, - const GLvoid *pixels ); - -GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level, - GLint internalFormat, - GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, - const GLvoid *pixels ); - -GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level, - GLenum format, GLenum type, - GLvoid *pixels ); - - -/* 1.1 functions */ - -GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures ); - -GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures); - -GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture ); - -GLAPI void GLAPIENTRY glPrioritizeTextures( GLsizei n, - const GLuint *textures, - const GLclampf *priorities ); - -GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n, - const GLuint *textures, - GLboolean *residences ); - -GLAPI GLboolean GLAPIENTRY glIsTexture( GLuint texture ); - - -GLAPI void GLAPIENTRY glTexSubImage1D( GLenum target, GLint level, - GLint xoffset, - GLsizei width, GLenum format, - GLenum type, const GLvoid *pixels ); - - -GLAPI void GLAPIENTRY glTexSubImage2D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels ); - - -GLAPI void GLAPIENTRY glCopyTexImage1D( GLenum target, GLint level, - GLenum internalformat, - GLint x, GLint y, - GLsizei width, GLint border ); - - -GLAPI void GLAPIENTRY glCopyTexImage2D( GLenum target, GLint level, - GLenum internalformat, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLint border ); - - -GLAPI void GLAPIENTRY glCopyTexSubImage1D( GLenum target, GLint level, - GLint xoffset, GLint x, GLint y, - GLsizei width ); - - -GLAPI void GLAPIENTRY glCopyTexSubImage2D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, - GLsizei width, GLsizei height ); - - -/* - * Evaluators - */ - -GLAPI void GLAPIENTRY glMap1d( GLenum target, GLdouble u1, GLdouble u2, - GLint stride, - GLint order, const GLdouble *points ); -GLAPI void GLAPIENTRY glMap1f( GLenum target, GLfloat u1, GLfloat u2, - GLint stride, - GLint order, const GLfloat *points ); - -GLAPI void GLAPIENTRY glMap2d( GLenum target, - GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, - GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, - const GLdouble *points ); -GLAPI void GLAPIENTRY glMap2f( GLenum target, - GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, - GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, - const GLfloat *points ); - -GLAPI void GLAPIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v ); -GLAPI void GLAPIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v ); -GLAPI void GLAPIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v ); - -GLAPI void GLAPIENTRY glEvalCoord1d( GLdouble u ); -GLAPI void GLAPIENTRY glEvalCoord1f( GLfloat u ); - -GLAPI void GLAPIENTRY glEvalCoord1dv( const GLdouble *u ); -GLAPI void GLAPIENTRY glEvalCoord1fv( const GLfloat *u ); - -GLAPI void GLAPIENTRY glEvalCoord2d( GLdouble u, GLdouble v ); -GLAPI void GLAPIENTRY glEvalCoord2f( GLfloat u, GLfloat v ); - -GLAPI void GLAPIENTRY glEvalCoord2dv( const GLdouble *u ); -GLAPI void GLAPIENTRY glEvalCoord2fv( const GLfloat *u ); - -GLAPI void GLAPIENTRY glMapGrid1d( GLint un, GLdouble u1, GLdouble u2 ); -GLAPI void GLAPIENTRY glMapGrid1f( GLint un, GLfloat u1, GLfloat u2 ); - -GLAPI void GLAPIENTRY glMapGrid2d( GLint un, GLdouble u1, GLdouble u2, - GLint vn, GLdouble v1, GLdouble v2 ); -GLAPI void GLAPIENTRY glMapGrid2f( GLint un, GLfloat u1, GLfloat u2, - GLint vn, GLfloat v1, GLfloat v2 ); - -GLAPI void GLAPIENTRY glEvalPoint1( GLint i ); - -GLAPI void GLAPIENTRY glEvalPoint2( GLint i, GLint j ); - -GLAPI void GLAPIENTRY glEvalMesh1( GLenum mode, GLint i1, GLint i2 ); - -GLAPI void GLAPIENTRY glEvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); - - -/* - * Fog - */ - -GLAPI void GLAPIENTRY glFogf( GLenum pname, GLfloat param ); - -GLAPI void GLAPIENTRY glFogi( GLenum pname, GLint param ); - -GLAPI void GLAPIENTRY glFogfv( GLenum pname, const GLfloat *params ); - -GLAPI void GLAPIENTRY glFogiv( GLenum pname, const GLint *params ); - - -/* - * Selection and Feedback - */ - -GLAPI void GLAPIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ); - -GLAPI void GLAPIENTRY glPassThrough( GLfloat token ); - -GLAPI void GLAPIENTRY glSelectBuffer( GLsizei size, GLuint *buffer ); - -GLAPI void GLAPIENTRY glInitNames( void ); - -GLAPI void GLAPIENTRY glLoadName( GLuint name ); - -GLAPI void GLAPIENTRY glPushName( GLuint name ); - -GLAPI void GLAPIENTRY glPopName( void ); - - - -/* - * OpenGL 1.2 - */ - -#define GL_RESCALE_NORMAL 0x803A -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_TEXTURE_BINDING_3D 0x806A - -GLAPI void GLAPIENTRY glDrawRangeElements( GLenum mode, GLuint start, - GLuint end, GLsizei count, GLenum type, const GLvoid *indices ); - -GLAPI void GLAPIENTRY glTexImage3D( GLenum target, GLint level, - GLint internalFormat, - GLsizei width, GLsizei height, - GLsizei depth, GLint border, - GLenum format, GLenum type, - const GLvoid *pixels ); - -GLAPI void GLAPIENTRY glTexSubImage3D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, - GLenum format, - GLenum type, const GLvoid *pixels); - -GLAPI void GLAPIENTRY glCopyTexSubImage3D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint zoffset, GLint x, - GLint y, GLsizei width, - GLsizei height ); - -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - - -/* - * GL_ARB_imaging - */ - -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_CONSTANT_BORDER 0x8151 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_BLEND_EQUATION 0x8009 -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_BLEND_COLOR 0x8005 - - -GLAPI void GLAPIENTRY glColorTable( GLenum target, GLenum internalformat, - GLsizei width, GLenum format, - GLenum type, const GLvoid *table ); - -GLAPI void GLAPIENTRY glColorSubTable( GLenum target, - GLsizei start, GLsizei count, - GLenum format, GLenum type, - const GLvoid *data ); - -GLAPI void GLAPIENTRY glColorTableParameteriv(GLenum target, GLenum pname, - const GLint *params); - -GLAPI void GLAPIENTRY glColorTableParameterfv(GLenum target, GLenum pname, - const GLfloat *params); - -GLAPI void GLAPIENTRY glCopyColorSubTable( GLenum target, GLsizei start, - GLint x, GLint y, GLsizei width ); - -GLAPI void GLAPIENTRY glCopyColorTable( GLenum target, GLenum internalformat, - GLint x, GLint y, GLsizei width ); - -GLAPI void GLAPIENTRY glGetColorTable( GLenum target, GLenum format, - GLenum type, GLvoid *table ); - -GLAPI void GLAPIENTRY glGetColorTableParameterfv( GLenum target, GLenum pname, - GLfloat *params ); - -GLAPI void GLAPIENTRY glGetColorTableParameteriv( GLenum target, GLenum pname, - GLint *params ); - -GLAPI void GLAPIENTRY glBlendEquation( GLenum mode ); - -GLAPI void GLAPIENTRY glBlendColor( GLclampf red, GLclampf green, - GLclampf blue, GLclampf alpha ); - -GLAPI void GLAPIENTRY glHistogram( GLenum target, GLsizei width, - GLenum internalformat, GLboolean sink ); - -GLAPI void GLAPIENTRY glResetHistogram( GLenum target ); - -GLAPI void GLAPIENTRY glGetHistogram( GLenum target, GLboolean reset, - GLenum format, GLenum type, - GLvoid *values ); - -GLAPI void GLAPIENTRY glGetHistogramParameterfv( GLenum target, GLenum pname, - GLfloat *params ); - -GLAPI void GLAPIENTRY glGetHistogramParameteriv( GLenum target, GLenum pname, - GLint *params ); - -GLAPI void GLAPIENTRY glMinmax( GLenum target, GLenum internalformat, - GLboolean sink ); - -GLAPI void GLAPIENTRY glResetMinmax( GLenum target ); - -GLAPI void GLAPIENTRY glGetMinmax( GLenum target, GLboolean reset, - GLenum format, GLenum types, - GLvoid *values ); - -GLAPI void GLAPIENTRY glGetMinmaxParameterfv( GLenum target, GLenum pname, - GLfloat *params ); - -GLAPI void GLAPIENTRY glGetMinmaxParameteriv( GLenum target, GLenum pname, - GLint *params ); - -GLAPI void GLAPIENTRY glConvolutionFilter1D( GLenum target, - GLenum internalformat, GLsizei width, GLenum format, GLenum type, - const GLvoid *image ); - -GLAPI void GLAPIENTRY glConvolutionFilter2D( GLenum target, - GLenum internalformat, GLsizei width, GLsizei height, GLenum format, - GLenum type, const GLvoid *image ); - -GLAPI void GLAPIENTRY glConvolutionParameterf( GLenum target, GLenum pname, - GLfloat params ); - -GLAPI void GLAPIENTRY glConvolutionParameterfv( GLenum target, GLenum pname, - const GLfloat *params ); - -GLAPI void GLAPIENTRY glConvolutionParameteri( GLenum target, GLenum pname, - GLint params ); - -GLAPI void GLAPIENTRY glConvolutionParameteriv( GLenum target, GLenum pname, - const GLint *params ); - -GLAPI void GLAPIENTRY glCopyConvolutionFilter1D( GLenum target, - GLenum internalformat, GLint x, GLint y, GLsizei width ); - -GLAPI void GLAPIENTRY glCopyConvolutionFilter2D( GLenum target, - GLenum internalformat, GLint x, GLint y, GLsizei width, - GLsizei height); - -GLAPI void GLAPIENTRY glGetConvolutionFilter( GLenum target, GLenum format, - GLenum type, GLvoid *image ); - -GLAPI void GLAPIENTRY glGetConvolutionParameterfv( GLenum target, GLenum pname, - GLfloat *params ); - -GLAPI void GLAPIENTRY glGetConvolutionParameteriv( GLenum target, GLenum pname, - GLint *params ); - -GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target, - GLenum internalformat, GLsizei width, GLsizei height, GLenum format, - GLenum type, const GLvoid *row, const GLvoid *column ); - -GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format, - GLenum type, GLvoid *row, GLvoid *column, GLvoid *span ); - -typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); - - - -/* - * OpenGL 1.3 - */ - -/* multitexture */ -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -/* texture_cube_map */ -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -/* texture_compression */ -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -/* multisample */ -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_MULTISAMPLE_BIT 0x20000000 -/* transpose_matrix */ -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -/* texture_env_combine */ -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -/* texture_env_dot3 */ -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -/* texture_border_clamp */ -#define GL_CLAMP_TO_BORDER 0x812D - -GLAPI void GLAPIENTRY glActiveTexture( GLenum texture ); - -GLAPI void GLAPIENTRY glClientActiveTexture( GLenum texture ); - -GLAPI void GLAPIENTRY glCompressedTexImage1D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data ); - -GLAPI void GLAPIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data ); - -GLAPI void GLAPIENTRY glCompressedTexImage3D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data ); - -GLAPI void GLAPIENTRY glCompressedTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data ); - -GLAPI void GLAPIENTRY glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data ); - -GLAPI void GLAPIENTRY glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ); - -GLAPI void GLAPIENTRY glGetCompressedTexImage( GLenum target, GLint lod, GLvoid *img ); - -GLAPI void GLAPIENTRY glMultiTexCoord1d( GLenum target, GLdouble s ); - -GLAPI void GLAPIENTRY glMultiTexCoord1dv( GLenum target, const GLdouble *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord1f( GLenum target, GLfloat s ); - -GLAPI void GLAPIENTRY glMultiTexCoord1fv( GLenum target, const GLfloat *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord1i( GLenum target, GLint s ); - -GLAPI void GLAPIENTRY glMultiTexCoord1iv( GLenum target, const GLint *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord1s( GLenum target, GLshort s ); - -GLAPI void GLAPIENTRY glMultiTexCoord1sv( GLenum target, const GLshort *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord2d( GLenum target, GLdouble s, GLdouble t ); - -GLAPI void GLAPIENTRY glMultiTexCoord2dv( GLenum target, const GLdouble *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord2f( GLenum target, GLfloat s, GLfloat t ); - -GLAPI void GLAPIENTRY glMultiTexCoord2fv( GLenum target, const GLfloat *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord2i( GLenum target, GLint s, GLint t ); - -GLAPI void GLAPIENTRY glMultiTexCoord2iv( GLenum target, const GLint *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord2s( GLenum target, GLshort s, GLshort t ); - -GLAPI void GLAPIENTRY glMultiTexCoord2sv( GLenum target, const GLshort *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord3d( GLenum target, GLdouble s, GLdouble t, GLdouble r ); - -GLAPI void GLAPIENTRY glMultiTexCoord3dv( GLenum target, const GLdouble *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord3f( GLenum target, GLfloat s, GLfloat t, GLfloat r ); - -GLAPI void GLAPIENTRY glMultiTexCoord3fv( GLenum target, const GLfloat *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord3i( GLenum target, GLint s, GLint t, GLint r ); - -GLAPI void GLAPIENTRY glMultiTexCoord3iv( GLenum target, const GLint *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord3s( GLenum target, GLshort s, GLshort t, GLshort r ); - -GLAPI void GLAPIENTRY glMultiTexCoord3sv( GLenum target, const GLshort *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord4d( GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q ); - -GLAPI void GLAPIENTRY glMultiTexCoord4dv( GLenum target, const GLdouble *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q ); - -GLAPI void GLAPIENTRY glMultiTexCoord4fv( GLenum target, const GLfloat *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord4i( GLenum target, GLint s, GLint t, GLint r, GLint q ); - -GLAPI void GLAPIENTRY glMultiTexCoord4iv( GLenum target, const GLint *v ); - -GLAPI void GLAPIENTRY glMultiTexCoord4s( GLenum target, GLshort s, GLshort t, GLshort r, GLshort q ); - -GLAPI void GLAPIENTRY glMultiTexCoord4sv( GLenum target, const GLshort *v ); - - -GLAPI void GLAPIENTRY glLoadTransposeMatrixd( const GLdouble m[16] ); - -GLAPI void GLAPIENTRY glLoadTransposeMatrixf( const GLfloat m[16] ); - -GLAPI void GLAPIENTRY glMultTransposeMatrixd( const GLdouble m[16] ); - -GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] ); - -GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert ); - -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img); - - -/* - * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) - */ -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 - -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 - -GLAPI void GLAPIENTRY glActiveTextureARB(GLenum texture); -GLAPI void GLAPIENTRY glClientActiveTextureARB(GLenum texture); -GLAPI void GLAPIENTRY glMultiTexCoord1dARB(GLenum target, GLdouble s); -GLAPI void GLAPIENTRY glMultiTexCoord1dvARB(GLenum target, const GLdouble *v); -GLAPI void GLAPIENTRY glMultiTexCoord1fARB(GLenum target, GLfloat s); -GLAPI void GLAPIENTRY glMultiTexCoord1fvARB(GLenum target, const GLfloat *v); -GLAPI void GLAPIENTRY glMultiTexCoord1iARB(GLenum target, GLint s); -GLAPI void GLAPIENTRY glMultiTexCoord1ivARB(GLenum target, const GLint *v); -GLAPI void GLAPIENTRY glMultiTexCoord1sARB(GLenum target, GLshort s); -GLAPI void GLAPIENTRY glMultiTexCoord1svARB(GLenum target, const GLshort *v); -GLAPI void GLAPIENTRY glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t); -GLAPI void GLAPIENTRY glMultiTexCoord2dvARB(GLenum target, const GLdouble *v); -GLAPI void GLAPIENTRY glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t); -GLAPI void GLAPIENTRY glMultiTexCoord2fvARB(GLenum target, const GLfloat *v); -GLAPI void GLAPIENTRY glMultiTexCoord2iARB(GLenum target, GLint s, GLint t); -GLAPI void GLAPIENTRY glMultiTexCoord2ivARB(GLenum target, const GLint *v); -GLAPI void GLAPIENTRY glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t); -GLAPI void GLAPIENTRY glMultiTexCoord2svARB(GLenum target, const GLshort *v); -GLAPI void GLAPIENTRY glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI void GLAPIENTRY glMultiTexCoord3dvARB(GLenum target, const GLdouble *v); -GLAPI void GLAPIENTRY glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI void GLAPIENTRY glMultiTexCoord3fvARB(GLenum target, const GLfloat *v); -GLAPI void GLAPIENTRY glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r); -GLAPI void GLAPIENTRY glMultiTexCoord3ivARB(GLenum target, const GLint *v); -GLAPI void GLAPIENTRY glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI void GLAPIENTRY glMultiTexCoord3svARB(GLenum target, const GLshort *v); -GLAPI void GLAPIENTRY glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void GLAPIENTRY glMultiTexCoord4dvARB(GLenum target, const GLdouble *v); -GLAPI void GLAPIENTRY glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void GLAPIENTRY glMultiTexCoord4fvARB(GLenum target, const GLfloat *v); -GLAPI void GLAPIENTRY glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI void GLAPIENTRY glMultiTexCoord4ivARB(GLenum target, const GLint *v); -GLAPI void GLAPIENTRY glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void GLAPIENTRY glMultiTexCoord4svARB(GLenum target, const GLshort *v); - -typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); - -#endif /* GL_ARB_multitexture */ - - - -/* - * Define this token if you want "old-style" header file behaviour (extensions - * defined in gl.h). Otherwise, extensions will be included from glext.h. - */ -#if defined(GL_GLEXT_LEGACY) - -/* All extensions that used to be here are now found in glext.h */ - -#else /* GL_GLEXT_LEGACY */ - -#include - -#endif /* GL_GLEXT_LEGACY */ - - - -#if GL_ARB_shader_objects - -#ifndef GL_MESA_shader_debug -#define GL_MESA_shader_debug 1 - -#define GL_DEBUG_OBJECT_MESA 0x8759 -#define GL_DEBUG_PRINT_MESA 0x875A -#define GL_DEBUG_ASSERT_MESA 0x875B - -GLAPI GLhandleARB APIENTRY glCreateDebugObjectMESA (void); -GLAPI void APIENTRY glClearDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType); -GLAPI void APIENTRY glGetDebugLogMESA (GLhandleARB obj, GLenum logType, GLenum shaderType, GLsizei maxLength, - GLsizei *length, GLcharARB *debugLog); -GLAPI GLsizei APIENTRY glGetDebugLogLengthMESA (GLhandleARB obj, GLenum logType, GLenum shaderType); - -#endif /* GL_MESA_shader_debug */ - -#endif /* GL_ARB_shader_objects */ - - -/* - * ???. GL_MESA_packed_depth_stencil - * XXX obsolete - */ -#ifndef GL_MESA_packed_depth_stencil -#define GL_MESA_packed_depth_stencil 1 - -#define GL_DEPTH_STENCIL_MESA 0x8750 -#define GL_UNSIGNED_INT_24_8_MESA 0x8751 -#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 -#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 -#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 - -#endif /* GL_MESA_packed_depth_stencil */ - - -#ifndef GL_MESA_program_debug -#define GL_MESA_program_debug 1 - -#define GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8bb0 -#define GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8bb1 -#define GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8bb2 -#define GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8bb3 -#define GL_VERTEX_PROGRAM_POSITION_MESA 0x8bb4 -#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8bb5 -#define GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8bb6 -#define GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8bb7 - -typedef void (*GLprogramcallbackMESA)(GLenum target, GLvoid *data); - -GLAPI void GLAPIENTRY glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, GLvoid *data); - -GLAPI void GLAPIENTRY glGetProgramRegisterfvMESA(GLenum target, GLsizei len, const GLubyte *name, GLfloat *v); - -#endif /* GL_MESA_program_debug */ - - -#ifndef GL_ATI_blend_equation_separate -#define GL_ATI_blend_equation_separate 1 - -#define GL_ALPHA_BLEND_EQUATION_ATI 0x883D - -GLAPI void GLAPIENTRY glBlendEquationSeparateATI( GLenum modeRGB, GLenum modeA ); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLenum modeA); - -#endif /* GL_ATI_blend_equation_separate */ - - - -/** - ** NOTE!!!!! If you add new functions to this file, or update - ** glext.h be sure to regenerate the gl_mangle.h file. See comments - ** in that file for details. - **/ - - - -/********************************************************************** - * Begin system-specific stuff - */ -#if defined(PRAGMA_EXPORT_SUPPORTED) -#pragma export off -#endif - -#if defined(macintosh) && PRAGMA_IMPORT_SUPPORTED -#pragma import off -#endif -/* - * End system-specific stuff - **********************************************************************/ - - -#ifdef __cplusplus -} -#endif - -#endif /* __gl_h_ */ diff --git a/target-i386/mesa_glext.h b/target-i386/mesa_glext.h deleted file mode 100644 index 969d297..0000000 --- a/target-i386/mesa_glext.h +++ /dev/null @@ -1,7278 +0,0 @@ -#ifndef __glext_h_ -#define __glext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are 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 Materials. -** -** THE MATERIALS ARE 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 AUTHORS OR 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -/* Header file version number, required by OpenGL ABI for Linux */ -/* glext.h last updated 2007/02/12 */ -/* Current version at http://www.opengl.org/registry/ */ -#define GL_GLEXT_VERSION 39 - -#ifndef GL_VERSION_1_2 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_RESCALE_NORMAL 0x803A -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#endif - -#ifndef GL_ARB_imaging -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 -#define GL_FUNC_ADD 0x8006 -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_BLEND_EQUATION 0x8009 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_CONSTANT_BORDER 0x8151 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 -#endif - -#ifndef GL_VERSION_1_3 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CLAMP_TO_BORDER 0x812D -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#endif - -#ifndef GL_VERSION_1_4 -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#endif - -#ifndef GL_VERSION_1_5 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 -#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE -#define GL_FOG_COORD GL_FOG_COORDINATE -#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE -#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE -#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE -#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER -#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -#define GL_SRC0_RGB GL_SOURCE0_RGB -#define GL_SRC1_RGB GL_SOURCE1_RGB -#define GL_SRC2_RGB GL_SOURCE2_RGB -#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA -#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA -#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA -#endif - -#ifndef GL_VERSION_2_0 -#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_COORDS 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#endif - -#ifndef GL_VERSION_2_1 -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -#endif - -#ifndef GL_ARB_multitexture -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 -#endif - -#ifndef GL_ARB_transpose_matrix -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 -#endif - -#ifndef GL_ARB_multisample -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 -#endif - -#ifndef GL_ARB_texture_env_add -#endif - -#ifndef GL_ARB_texture_cube_map -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#endif - -#ifndef GL_ARB_texture_compression -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -#endif - -#ifndef GL_ARB_texture_border_clamp -#define GL_CLAMP_TO_BORDER_ARB 0x812D -#endif - -#ifndef GL_ARB_point_parameters -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 -#endif - -#ifndef GL_ARB_vertex_blend -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F -#endif - -#ifndef GL_ARB_matrix_palette -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 -#endif - -#ifndef GL_ARB_texture_env_combine -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 -#endif - -#ifndef GL_ARB_texture_env_crossbar -#endif - -#ifndef GL_ARB_texture_env_dot3 -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGBA_ARB 0x86AF -#endif - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_MIRRORED_REPEAT_ARB 0x8370 -#endif - -#ifndef GL_ARB_depth_texture -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B -#endif - -#ifndef GL_ARB_shadow -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E -#endif - -#ifndef GL_ARB_shadow_ambient -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF -#endif - -#ifndef GL_ARB_window_pos -#endif - -#ifndef GL_ARB_vertex_program -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF -#endif - -#ifndef GL_ARB_fragment_program -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 -#endif - -#ifndef GL_ARB_vertex_buffer_object -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA -#endif - -#ifndef GL_ARB_occlusion_query -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_SAMPLES_PASSED_ARB 0x8914 -#endif - -#ifndef GL_ARB_shader_objects -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 -#endif - -#ifndef GL_ARB_vertex_shader -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A -#endif - -#ifndef GL_ARB_fragment_shader -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B -#endif - -#ifndef GL_ARB_shading_language_100 -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C -#endif - -#ifndef GL_ARB_texture_non_power_of_two -#endif - -#ifndef GL_ARB_point_sprite -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_COORD_REPLACE_ARB 0x8862 -#endif - -#ifndef GL_ARB_fragment_program_shadow -#endif - -#ifndef GL_ARB_draw_buffers -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER15_ARB 0x8834 -#endif - -#ifndef GL_ARB_texture_rectangle -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#endif - -#ifndef GL_ARB_color_buffer_float -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_FIXED_ONLY_ARB 0x891D -#endif - -#ifndef GL_ARB_half_float_pixel -#define GL_HALF_FLOAT_ARB 0x140B -#endif - -#ifndef GL_ARB_texture_float -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#endif - -#ifndef GL_ARB_pixel_buffer_object -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF -#endif - -#ifndef GL_EXT_abgr -#define GL_ABGR_EXT 0x8000 -#endif - -#ifndef GL_EXT_blend_color -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_BLEND_COLOR_EXT 0x8005 -#endif - -#ifndef GL_EXT_polygon_offset -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 -#endif - -#ifndef GL_EXT_texture -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16_EXT 0x803E -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16_EXT 0x804D -#define GL_RGB2_EXT 0x804E -#define GL_RGB4_EXT 0x804F -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8_EXT 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGBA8_EXT 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16_EXT 0x805B -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_REPLACE_EXT 0x8062 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 -#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 -#endif - -#ifndef GL_EXT_texture3D -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 -#endif - -#ifndef GL_SGIS_texture_filter4 -#define GL_FILTER4_SGIS 0x8146 -#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 -#endif - -#ifndef GL_EXT_subtexture -#endif - -#ifndef GL_EXT_copy_texture -#endif - -#ifndef GL_EXT_histogram -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK_EXT 0x8030 -#define GL_TABLE_TOO_LARGE_EXT 0x8031 -#endif - -#ifndef GL_EXT_convolution -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_REDUCE_EXT 0x8016 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 -#endif - -#ifndef GL_SGI_color_matrix -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB -#endif - -#ifndef GL_SGI_color_table -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF -#endif - -#ifndef GL_SGIS_pixel_texture -#define GL_PIXEL_TEXTURE_SGIS 0x8353 -#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 -#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 -#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 -#endif - -#ifndef GL_SGIX_pixel_texture -#define GL_PIXEL_TEX_GEN_SGIX 0x8139 -#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B -#endif - -#ifndef GL_SGIS_texture4D -#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 -#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 -#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 -#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 -#define GL_TEXTURE_4D_SGIS 0x8134 -#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 -#define GL_TEXTURE_4DSIZE_SGIS 0x8136 -#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 -#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 -#define GL_TEXTURE_4D_BINDING_SGIS 0x814F -#endif - -#ifndef GL_SGI_texture_color_table -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD -#endif - -#ifndef GL_EXT_cmyka -#define GL_CMYK_EXT 0x800C -#define GL_CMYKA_EXT 0x800D -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_UNPACK_CMYK_HINT_EXT 0x800F -#endif - -#ifndef GL_EXT_texture_object -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_3D_BINDING_EXT 0x806A -#endif - -#ifndef GL_SGIS_detail_texture -#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 -#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 -#define GL_LINEAR_DETAIL_SGIS 0x8097 -#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 -#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 -#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A -#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B -#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C -#endif - -#ifndef GL_SGIS_sharpen_texture -#define GL_LINEAR_SHARPEN_SGIS 0x80AD -#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE -#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF -#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 -#endif - -#ifndef GL_EXT_packed_pixels -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 -#endif - -#ifndef GL_SGIS_texture_lod -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D -#endif - -#ifndef GL_SGIS_multisample -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_PATTERN_SGIS 0x80AC -#endif - -#ifndef GL_EXT_rescale_normal -#define GL_RESCALE_NORMAL_EXT 0x803A -#endif - -#ifndef GL_EXT_vertex_array -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 -#endif - -#ifndef GL_EXT_misc_attribute -#endif - -#ifndef GL_SGIS_generate_mipmap -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif - -#ifndef GL_SGIX_clipmap -#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 -#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 -#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 -#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 -#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 -#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 -#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 -#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 -#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 -#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D -#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E -#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F -#endif - -#ifndef GL_SGIX_shadow -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D -#endif - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_CLAMP_TO_EDGE_SGIS 0x812F -#endif - -#ifndef GL_SGIS_texture_border_clamp -#define GL_CLAMP_TO_BORDER_SGIS 0x812D -#endif - -#ifndef GL_EXT_blend_minmax -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#define GL_BLEND_EQUATION_EXT 0x8009 -#endif - -#ifndef GL_EXT_blend_subtract -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B -#endif - -#ifndef GL_EXT_blend_logic_op -#endif - -#ifndef GL_SGIX_interlace -#define GL_INTERLACE_SGIX 0x8094 -#endif - -#ifndef GL_SGIX_pixel_tiles -#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E -#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F -#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 -#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 -#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 -#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 -#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 -#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 -#endif - -#ifndef GL_SGIS_texture_select -#define GL_DUAL_ALPHA4_SGIS 0x8110 -#define GL_DUAL_ALPHA8_SGIS 0x8111 -#define GL_DUAL_ALPHA12_SGIS 0x8112 -#define GL_DUAL_ALPHA16_SGIS 0x8113 -#define GL_DUAL_LUMINANCE4_SGIS 0x8114 -#define GL_DUAL_LUMINANCE8_SGIS 0x8115 -#define GL_DUAL_LUMINANCE12_SGIS 0x8116 -#define GL_DUAL_LUMINANCE16_SGIS 0x8117 -#define GL_DUAL_INTENSITY4_SGIS 0x8118 -#define GL_DUAL_INTENSITY8_SGIS 0x8119 -#define GL_DUAL_INTENSITY12_SGIS 0x811A -#define GL_DUAL_INTENSITY16_SGIS 0x811B -#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C -#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D -#define GL_QUAD_ALPHA4_SGIS 0x811E -#define GL_QUAD_ALPHA8_SGIS 0x811F -#define GL_QUAD_LUMINANCE4_SGIS 0x8120 -#define GL_QUAD_LUMINANCE8_SGIS 0x8121 -#define GL_QUAD_INTENSITY4_SGIS 0x8122 -#define GL_QUAD_INTENSITY8_SGIS 0x8123 -#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 -#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 -#endif - -#ifndef GL_SGIX_sprite -#define GL_SPRITE_SGIX 0x8148 -#define GL_SPRITE_MODE_SGIX 0x8149 -#define GL_SPRITE_AXIS_SGIX 0x814A -#define GL_SPRITE_TRANSLATION_SGIX 0x814B -#define GL_SPRITE_AXIAL_SGIX 0x814C -#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D -#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E -#endif - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E -#endif - -#ifndef GL_EXT_point_parameters -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 -#endif - -#ifndef GL_SGIS_point_parameters -#define GL_POINT_SIZE_MIN_SGIS 0x8126 -#define GL_POINT_SIZE_MAX_SGIS 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 -#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 -#endif - -#ifndef GL_SGIX_instruments -#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 -#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 -#endif - -#ifndef GL_SGIX_texture_scale_bias -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C -#endif - -#ifndef GL_SGIX_framezoom -#define GL_FRAMEZOOM_SGIX 0x818B -#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C -#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D -#endif - -#ifndef GL_SGIX_tag_sample_buffer -#endif - -#ifndef GL_FfdMaskSGIX -#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 -#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 -#endif - -#ifndef GL_SGIX_polynomial_ffd -#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 -#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 -#define GL_DEFORMATIONS_MASK_SGIX 0x8196 -#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 -#endif - -#ifndef GL_SGIX_reference_plane -#define GL_REFERENCE_PLANE_SGIX 0x817D -#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E -#endif - -#ifndef GL_SGIX_flush_raster -#endif - -#ifndef GL_SGIX_depth_texture -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 -#endif - -#ifndef GL_SGIS_fog_function -#define GL_FOG_FUNC_SGIS 0x812A -#define GL_FOG_FUNC_POINTS_SGIS 0x812B -#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C -#endif - -#ifndef GL_SGIX_fog_offset -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 -#endif - -#ifndef GL_HP_image_transform -#define GL_IMAGE_SCALE_X_HP 0x8155 -#define GL_IMAGE_SCALE_Y_HP 0x8156 -#define GL_IMAGE_TRANSLATE_X_HP 0x8157 -#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 -#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 -#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A -#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B -#define GL_IMAGE_MAG_FILTER_HP 0x815C -#define GL_IMAGE_MIN_FILTER_HP 0x815D -#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E -#define GL_CUBIC_HP 0x815F -#define GL_AVERAGE_HP 0x8160 -#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 -#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 -#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 -#endif - -#ifndef GL_HP_convolution_border_modes -#define GL_IGNORE_BORDER_HP 0x8150 -#define GL_CONSTANT_BORDER_HP 0x8151 -#define GL_REPLICATE_BORDER_HP 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 -#endif - -#ifndef GL_INGR_palette_buffer -#endif - -#ifndef GL_SGIX_texture_add_env -#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE -#endif - -#ifndef GL_EXT_color_subtable -#endif - -#ifndef GL_PGI_vertex_hints -#define GL_VERTEX_DATA_HINT_PGI 0x1A22A -#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B -#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C -#define GL_MAX_VERTEX_HINT_PGI 0x1A22D -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#endif - -#ifndef GL_PGI_misc_hints -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 -#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD -#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 -#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C -#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E -#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F -#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 -#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 -#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 -#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 -#define GL_CLIP_NEAR_HINT_PGI 0x1A220 -#define GL_CLIP_FAR_HINT_PGI 0x1A221 -#define GL_WIDE_LINE_HINT_PGI 0x1A222 -#define GL_BACK_NORMALS_HINT_PGI 0x1A223 -#endif - -#ifndef GL_EXT_paletted_texture -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -#endif - -#ifndef GL_EXT_clip_volume_hint -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 -#endif - -#ifndef GL_SGIX_list_priority -#define GL_LIST_PRIORITY_SGIX 0x8182 -#endif - -#ifndef GL_SGIX_ir_instrument1 -#define GL_IR_INSTRUMENT1_SGIX 0x817F -#endif - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 -#endif - -#ifndef GL_SGIX_texture_lod_bias -#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E -#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F -#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 -#endif - -#ifndef GL_SGIX_shadow_ambient -#define GL_SHADOW_AMBIENT_SGIX 0x80BF -#endif - -#ifndef GL_EXT_index_texture -#endif - -#ifndef GL_EXT_index_material -#define GL_INDEX_MATERIAL_EXT 0x81B8 -#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 -#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA -#endif - -#ifndef GL_EXT_index_func -#define GL_INDEX_TEST_EXT 0x81B5 -#define GL_INDEX_TEST_FUNC_EXT 0x81B6 -#define GL_INDEX_TEST_REF_EXT 0x81B7 -#endif - -#ifndef GL_EXT_index_array_formats -#define GL_IUI_V2F_EXT 0x81AD -#define GL_IUI_V3F_EXT 0x81AE -#define GL_IUI_N3F_V2F_EXT 0x81AF -#define GL_IUI_N3F_V3F_EXT 0x81B0 -#define GL_T2F_IUI_V2F_EXT 0x81B1 -#define GL_T2F_IUI_V3F_EXT 0x81B2 -#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 -#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 -#endif - -#ifndef GL_EXT_compiled_vertex_array -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 -#endif - -#ifndef GL_EXT_cull_vertex -#define GL_CULL_VERTEX_EXT 0x81AA -#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB -#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC -#endif - -#ifndef GL_SGIX_ycrcb -#define GL_YCRCB_422_SGIX 0x81BB -#define GL_YCRCB_444_SGIX 0x81BC -#endif - -#ifndef GL_SGIX_fragment_lighting -#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 -#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 -#define GL_LIGHT_ENV_MODE_SGIX 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B -#define GL_FRAGMENT_LIGHT0_SGIX 0x840C -#define GL_FRAGMENT_LIGHT1_SGIX 0x840D -#define GL_FRAGMENT_LIGHT2_SGIX 0x840E -#define GL_FRAGMENT_LIGHT3_SGIX 0x840F -#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 -#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 -#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 -#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 -#endif - -#ifndef GL_IBM_rasterpos_clip -#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 -#endif - -#ifndef GL_HP_texture_lighting -#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 -#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 -#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 -#endif - -#ifndef GL_EXT_draw_range_elements -#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 -#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 -#endif - -#ifndef GL_WIN_phong_shading -#define GL_PHONG_WIN 0x80EA -#define GL_PHONG_HINT_WIN 0x80EB -#endif - -#ifndef GL_WIN_specular_fog -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC -#endif - -#ifndef GL_EXT_light_texture -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_ATTENUATION_EXT 0x834D -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 -/* reuse GL_FRAGMENT_DEPTH_EXT */ -#endif - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_MAX_SGIX 0x8321 -#endif - -#ifndef GL_SGIX_impact_pixel_texture -#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 -#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 -#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 -#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 -#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 -#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 -#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A -#endif - -#ifndef GL_EXT_bgra -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 -#endif - -#ifndef GL_SGIX_async -#define GL_ASYNC_MARKER_SGIX 0x8329 -#endif - -#ifndef GL_SGIX_async_pixel -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 -#endif - -#ifndef GL_SGIX_async_histogram -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D -#endif - -#ifndef GL_INTEL_texture_scissor -#endif - -#ifndef GL_INTEL_parallel_arrays -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 -#endif - -#ifndef GL_HP_occlusion_test -#define GL_OCCLUSION_TEST_HP 0x8165 -#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 -#endif - -#ifndef GL_EXT_pixel_transform -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_CUBIC_EXT 0x8334 -#define GL_AVERAGE_EXT 0x8335 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 -#endif - -#ifndef GL_EXT_pixel_transform_color_table -#endif - -#ifndef GL_EXT_shared_texture_palette -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB -#endif - -#ifndef GL_EXT_separate_specular_color -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#endif - -#ifndef GL_EXT_secondary_color -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E -#endif - -#ifndef GL_EXT_texture_perturb_normal -#define GL_PERTURB_EXT 0x85AE -#define GL_TEXTURE_NORMAL_EXT 0x85AF -#endif - -#ifndef GL_EXT_multi_draw_arrays -#endif - -#ifndef GL_EXT_fog_coord -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 -#endif - -#ifndef GL_REND_screen_coordinates -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_INVERTED_SCREEN_W_REND 0x8491 -#endif - -#ifndef GL_EXT_coordinate_frame -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP2_BINORMAL_EXT 0x8447 -#endif - -#ifndef GL_EXT_texture_env_combine -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_CONSTANT_EXT 0x8576 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND2_ALPHA_EXT 0x859A -#endif - -#ifndef GL_APPLE_specular_vector -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 -#endif - -#ifndef GL_APPLE_transform_hint -#define GL_TRANSFORM_HINT_APPLE 0x85B1 -#endif - -#ifndef GL_SGIX_fog_scale -#define GL_FOG_SCALE_SGIX 0x81FC -#define GL_FOG_SCALE_VALUE_SGIX 0x81FD -#endif - -#ifndef GL_SUNX_constant_data -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 -#endif - -#ifndef GL_SUN_global_alpha -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA -#endif - -#ifndef GL_SUN_triangle_list -#define GL_RESTART_SUN 0x0001 -#define GL_REPLACE_MIDDLE_SUN 0x0002 -#define GL_REPLACE_OLDEST_SUN 0x0003 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB -#endif - -#ifndef GL_SUN_vertex -#endif - -#ifndef GL_EXT_blend_func_separate -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB -#endif - -#ifndef GL_INGR_color_clamp -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 -#endif - -#ifndef GL_INGR_interlace_read -#define GL_INTERLACE_READ_INGR 0x8568 -#endif - -#ifndef GL_EXT_stencil_wrap -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_DECR_WRAP_EXT 0x8508 -#endif - -#ifndef GL_EXT_422_pixels -#define GL_422_EXT 0x80CC -#define GL_422_REV_EXT 0x80CD -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_REV_AVERAGE_EXT 0x80CF -#endif - -#ifndef GL_NV_texgen_reflection -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_REFLECTION_MAP_NV 0x8512 -#endif - -#ifndef GL_EXT_texture_cube_map -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C -#endif - -#ifndef GL_SUN_convolution_border_modes -#define GL_WRAP_BORDER_SUN 0x81D4 -#endif - -#ifndef GL_EXT_texture_env_add -#endif - -#ifndef GL_EXT_texture_lod_bias -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 -#endif - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif - -#ifndef GL_EXT_vertex_weighting -#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_MODELVIEW0_EXT GL_MODELVIEW -#define GL_MODELVIEW1_EXT 0x850A -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 -#endif - -#ifndef GL_NV_light_max_exponent -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 -#endif - -#ifndef GL_NV_vertex_array_range -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 -#endif - -#ifndef GL_NV_register_combiners -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_SPARE0_NV 0x852E -#define GL_SPARE1_NV 0x852F -#define GL_DISCARD_NV 0x8530 -#define GL_E_TIMES_F_NV 0x8531 -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 -/* reuse GL_TEXTURE0_ARB */ -/* reuse GL_TEXTURE1_ARB */ -/* reuse GL_ZERO */ -/* reuse GL_NONE */ -/* reuse GL_FOG */ -#endif - -#ifndef GL_NV_fog_distance -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_EYE_RADIAL_NV 0x855B -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C -/* reuse GL_EYE_PLANE */ -#endif - -#ifndef GL_NV_texgen_emboss -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_MAP_NV 0x855F -#endif - -#ifndef GL_NV_blend_square -#endif - -#ifndef GL_NV_texture_env_combine4 -#define GL_COMBINE4_NV 0x8503 -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OPERAND3_ALPHA_NV 0x859B -#endif - -#ifndef GL_MESA_resize_buffers -#endif - -#ifndef GL_MESA_window_pos -#endif - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif - -#ifndef GL_IBM_cull_vertex -#define GL_CULL_VERTEX_IBM 103050 -#endif - -#ifndef GL_IBM_multimode_draw_arrays -#endif - -#ifndef GL_IBM_vertex_array_lists -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 -#endif - -#ifndef GL_SGIX_subsample -#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 -#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 -#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 -#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 -#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 -#endif - -#ifndef GL_SGIX_ycrcb_subsample -#endif - -#ifndef GL_SGIX_ycrcba -#define GL_YCRCB_SGIX 0x8318 -#define GL_YCRCBA_SGIX 0x8319 -#endif - -#ifndef GL_SGI_depth_pass_instrument -#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 -#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 -#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 -#endif - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 -#endif - -#ifndef GL_3DFX_multisample -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 -#endif - -#ifndef GL_3DFX_tbuffer -#endif - -#ifndef GL_EXT_multisample -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_1PASS_EXT 0x80A1 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 -#endif - -#ifndef GL_SGIX_vertex_preclip -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF -#endif - -#ifndef GL_SGIX_convolution_accuracy -#define GL_CONVOLUTION_HINT_SGIX 0x8316 -#endif - -#ifndef GL_SGIX_resample -#define GL_PACK_RESAMPLE_SGIX 0x842C -#define GL_UNPACK_RESAMPLE_SGIX 0x842D -#define GL_RESAMPLE_REPLICATE_SGIX 0x842E -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#endif - -#ifndef GL_SGIS_point_line_texgen -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_OBJECT_LINE_SGIS 0x81F7 -#endif - -#ifndef GL_SGIS_texture_color_mask -#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF -#endif - -#ifndef GL_EXT_texture_env_dot3 -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT3_RGBA_EXT 0x8741 -#endif - -#ifndef GL_ATI_texture_mirror_once -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 -#endif - -#ifndef GL_NV_fence -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -#endif - -#ifndef GL_IBM_texture_mirrored_repeat -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#endif - -#ifndef GL_NV_evaluators -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 -#endif - -#ifndef GL_NV_packed_depth_stencil -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA -#endif - -#ifndef GL_NV_register_combiners2 -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 -#endif - -#ifndef GL_NV_texture_compression_vtc -#endif - -#ifndef GL_NV_texture_rectangle -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 -#endif - -#ifndef GL_NV_texture_shader -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_CULL_MODES_NV 0x86E0 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV -#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV -#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_HI_SCALE_NV 0x870E -#define GL_LO_SCALE_NV 0x870F -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_SCALE_NV 0x8711 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_HI_BIAS_NV 0x8714 -#define GL_LO_BIAS_NV 0x8715 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DT_BIAS_NV 0x8717 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_MAG_SIZE_NV 0x871F -#endif - -#ifndef GL_NV_texture_shader2 -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#endif - -#ifndef GL_NV_vertex_array_range2 -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 -#endif - -#ifndef GL_NV_vertex_program -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F -#endif - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B -#endif - -#ifndef GL_SGIX_scalebias_hint -#define GL_SCALEBIAS_HINT_SGIX 0x8322 -#endif - -#ifndef GL_OML_interlace -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_OML 0x8981 -#endif - -#ifndef GL_OML_subsample -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 -#endif - -#ifndef GL_OML_resample -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 -#endif - -#ifndef GL_NV_copy_depth_to_color -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F -#endif - -#ifndef GL_ATI_envmap_bumpmap -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_DUDV_ATI 0x8779 -#define GL_DU8DV8_ATI 0x877A -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_TARGET_ATI 0x877C -#endif - -#ifndef GL_ATI_fragment_shader -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_2_ATI 0x8923 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_REG_6_ATI 0x8927 -#define GL_REG_7_ATI 0x8928 -#define GL_REG_8_ATI 0x8929 -#define GL_REG_9_ATI 0x892A -#define GL_REG_10_ATI 0x892B -#define GL_REG_11_ATI 0x892C -#define GL_REG_12_ATI 0x892D -#define GL_REG_13_ATI 0x892E -#define GL_REG_14_ATI 0x892F -#define GL_REG_15_ATI 0x8930 -#define GL_REG_16_ATI 0x8931 -#define GL_REG_17_ATI 0x8932 -#define GL_REG_18_ATI 0x8933 -#define GL_REG_19_ATI 0x8934 -#define GL_REG_20_ATI 0x8935 -#define GL_REG_21_ATI 0x8936 -#define GL_REG_22_ATI 0x8937 -#define GL_REG_23_ATI 0x8938 -#define GL_REG_24_ATI 0x8939 -#define GL_REG_25_ATI 0x893A -#define GL_REG_26_ATI 0x893B -#define GL_REG_27_ATI 0x893C -#define GL_REG_28_ATI 0x893D -#define GL_REG_29_ATI 0x893E -#define GL_REG_30_ATI 0x893F -#define GL_REG_31_ATI 0x8940 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_2_ATI 0x8943 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_CON_8_ATI 0x8949 -#define GL_CON_9_ATI 0x894A -#define GL_CON_10_ATI 0x894B -#define GL_CON_11_ATI 0x894C -#define GL_CON_12_ATI 0x894D -#define GL_CON_13_ATI 0x894E -#define GL_CON_14_ATI 0x894F -#define GL_CON_15_ATI 0x8950 -#define GL_CON_16_ATI 0x8951 -#define GL_CON_17_ATI 0x8952 -#define GL_CON_18_ATI 0x8953 -#define GL_CON_19_ATI 0x8954 -#define GL_CON_20_ATI 0x8955 -#define GL_CON_21_ATI 0x8956 -#define GL_CON_22_ATI 0x8957 -#define GL_CON_23_ATI 0x8958 -#define GL_CON_24_ATI 0x8959 -#define GL_CON_25_ATI 0x895A -#define GL_CON_26_ATI 0x895B -#define GL_CON_27_ATI 0x895C -#define GL_CON_28_ATI 0x895D -#define GL_CON_29_ATI 0x895E -#define GL_CON_30_ATI 0x895F -#define GL_CON_31_ATI 0x8960 -#define GL_MOV_ATI 0x8961 -#define GL_ADD_ATI 0x8963 -#define GL_MUL_ATI 0x8964 -#define GL_SUB_ATI 0x8965 -#define GL_DOT3_ATI 0x8966 -#define GL_DOT4_ATI 0x8967 -#define GL_MAD_ATI 0x8968 -#define GL_LERP_ATI 0x8969 -#define GL_CND_ATI 0x896A -#define GL_CND0_ATI 0x896B -#define GL_DOT2_ADD_ATI 0x896C -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B -#define GL_RED_BIT_ATI 0x00000001 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_2X_BIT_ATI 0x00000001 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_BIAS_BIT_ATI 0x00000008 -#endif - -#ifndef GL_ATI_pn_triangles -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 -#endif - -#ifndef GL_ATI_vertex_array_object -#define GL_STATIC_ATI 0x8760 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_PRESERVE_ATI 0x8762 -#define GL_DISCARD_ATI 0x8763 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 -#endif - -#ifndef GL_EXT_vertex_shader -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_SUB_EXT 0x8796 -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MOV_EXT 0x8799 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_SCALAR_EXT 0x87BE -#define GL_VECTOR_EXT 0x87BF -#define GL_MATRIX_EXT 0x87C0 -#define GL_VARIANT_EXT 0x87C1 -#define GL_INVARIANT_EXT 0x87C2 -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_EXT 0x87C4 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_X_EXT 0x87D5 -#define GL_Y_EXT 0x87D6 -#define GL_Z_EXT 0x87D7 -#define GL_W_EXT 0x87D8 -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_ZERO_EXT 0x87DD -#define GL_ONE_EXT 0x87DE -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED -#endif - -#ifndef GL_ATI_vertex_streams -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_VERTEX_STREAM0_ATI 0x876C -#define GL_VERTEX_STREAM1_ATI 0x876D -#define GL_VERTEX_STREAM2_ATI 0x876E -#define GL_VERTEX_STREAM3_ATI 0x876F -#define GL_VERTEX_STREAM4_ATI 0x8770 -#define GL_VERTEX_STREAM5_ATI 0x8771 -#define GL_VERTEX_STREAM6_ATI 0x8772 -#define GL_VERTEX_STREAM7_ATI 0x8773 -#define GL_VERTEX_SOURCE_ATI 0x8774 -#endif - -#ifndef GL_ATI_element_array -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A -#endif - -#ifndef GL_SUN_mesh_array -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_TRIANGLE_MESH_SUN 0x8615 -#endif - -#ifndef GL_SUN_slice_accum -#define GL_SLICE_ACCUM_SUN 0x85CC -#endif - -#ifndef GL_NV_multisample_filter_hint -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 -#endif - -#ifndef GL_NV_depth_clamp -#define GL_DEPTH_CLAMP_NV 0x864F -#endif - -#ifndef GL_NV_occlusion_query -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 -#endif - -#ifndef GL_NV_point_sprite -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 -#endif - -#ifndef GL_NV_texture_shader3 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_HILO8_NV 0x885E -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 -#endif - -#ifndef GL_NV_vertex_program1_1 -#endif - -#ifndef GL_EXT_shadow_funcs -#endif - -#ifndef GL_EXT_stencil_two_side -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 -#endif - -#ifndef GL_ATI_text_fragment_shader -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 -#endif - -#ifndef GL_APPLE_client_storage -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 -#endif - -#ifndef GL_APPLE_element_array -#define GL_ELEMENT_ARRAY_APPLE 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A -#endif - -#ifndef GL_APPLE_fence -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x8A0B -#endif - -#ifndef GL_APPLE_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 -#endif - -#ifndef GL_APPLE_vertex_array_range -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF -#endif - -#ifndef GL_APPLE_ycbcr_422 -#define GL_YCBCR_422_APPLE 0x85B9 -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#endif - -#ifndef GL_S3_s3tc -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA4_S3TC 0x83A3 -#endif - -#ifndef GL_ATI_draw_buffers -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER15_ATI 0x8834 -#endif - -#ifndef GL_ATI_pixel_format_float -#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 -#endif - -#ifndef GL_ATI_texture_env_combine3 -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 -#endif - -#ifndef GL_ATI_texture_float -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F -#endif - -#ifndef GL_NV_float_buffer -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_RGBA_MODE_NV 0x888E -#endif - -#ifndef GL_NV_fragment_program -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 -#endif - -#ifndef GL_NV_half_float -#define GL_HALF_FLOAT_NV 0x140B -#endif - -#ifndef GL_NV_pixel_data_range -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D -#endif - -#ifndef GL_NV_primitive_restart -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 -#endif - -#ifndef GL_NV_texture_expand_normal -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F -#endif - -#ifndef GL_NV_vertex_program2 -#endif - -#ifndef GL_ATI_map_object_buffer -#endif - -#ifndef GL_ATI_separate_stencil -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 -#endif - -#ifndef GL_ATI_vertex_attrib_array_object -#endif - -#ifndef GL_OES_read_format -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B -#endif - -#ifndef GL_EXT_depth_bounds_test -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BOUNDS_EXT 0x8891 -#endif - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 -#endif - -#ifndef GL_EXT_blend_equation_separate -#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D -#endif - -#ifndef GL_MESA_pack_invert -#define GL_PACK_INVERT_MESA 0x8758 -#endif - -#ifndef GL_MESA_ycbcr_texture -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_YCBCR_MESA 0x8757 -#endif - -#ifndef GL_EXT_pixel_buffer_object -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF -#endif - -#ifndef GL_NV_fragment_program_option -#endif - -#ifndef GL_NV_fragment_program2 -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 -#endif - -#ifndef GL_NV_vertex_program2_option -/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ -/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ -#endif - -#ifndef GL_NV_vertex_program3 -/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ -#endif - -#ifndef GL_EXT_framebuffer_object -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -#endif - -#ifndef GL_GREMEDY_string_marker -#endif - -#ifndef GL_EXT_packed_depth_stencil -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 -#endif - -#ifndef GL_EXT_stencil_clear_tag -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 -#endif - -#ifndef GL_EXT_texture_sRGB -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F -#endif - -#ifndef GL_EXT_framebuffer_blit -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CAA -#endif - -#ifndef GL_EXT_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#endif - -#ifndef GL_MESAX_texture_stack -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E -#endif - -#ifndef GL_EXT_timer_query -#define GL_TIME_ELAPSED_EXT 0x88BF -#endif - -#ifndef GL_EXT_gpu_program_parameters -#endif - -#ifndef GL_APPLE_flush_buffer_range -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 -#endif - -#ifndef GL_NV_gpu_program4 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 -#endif - -#ifndef GL_NV_geometry_program4 -#define GL_LINES_ADJACENCY_EXT 0x000A -#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B -#define GL_TRIANGLES_ADJACENCY_EXT 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#endif - -#ifndef GL_EXT_geometry_shader4 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */ -/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */ -/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */ -/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -/* reuse GL_LINES_ADJACENCY_EXT */ -/* reuse GL_LINE_STRIP_ADJACENCY_EXT */ -/* reuse GL_TRIANGLES_ADJACENCY_EXT */ -/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ -/* reuse GL_PROGRAM_POINT_SIZE_EXT */ -#endif - -#ifndef GL_NV_vertex_program4 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD -#endif - -#ifndef GL_EXT_gpu_shader4 -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 -#endif - -#ifndef GL_EXT_draw_instanced -#endif - -#ifndef GL_EXT_packed_float -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C -#endif - -#ifndef GL_EXT_texture_array -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ -#endif - -#ifndef GL_EXT_texture_buffer_object -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E -#endif - -#ifndef GL_EXT_texture_compression_latc -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 -#endif - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE -#endif - -#ifndef GL_EXT_texture_shared_exponent -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F -#endif - -#ifndef GL_NV_depth_buffer_float -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF -#endif - -#ifndef GL_NV_fragment_program4 -#endif - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 -#endif - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA -#endif - -#ifndef GL_NV_geometry_shader4 -#endif - -#ifndef GL_NV_parameter_buffer_object -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 -#endif - -#ifndef GL_EXT_draw_buffers2 -#endif - -#ifndef GL_NV_transform_feedback -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F -#endif - -#ifndef GL_EXT_bindable_uniform -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF -#endif - -#ifndef GL_EXT_texture_integer -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGB8UI_EXT 0x8D7D -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGB32I_EXT 0x8D83 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGB16I_EXT 0x8D89 -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGB8I_EXT 0x8D8F -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E -#endif - - -/*************************************************************/ - -#include -#ifndef GL_VERSION_2_0 -/* GL type for program/shader text */ -typedef char GLchar; /* native character */ -#endif - -#ifndef GL_VERSION_1_5 -/* GL types for handling large vertex buffer objects */ -typedef ptrdiff_t GLintptr; -typedef ptrdiff_t GLsizeiptr; -#endif - -#ifndef GL_ARB_vertex_buffer_object -/* GL types for handling large vertex buffer objects */ -typedef ptrdiff_t GLintptrARB; -typedef ptrdiff_t GLsizeiptrARB; -#endif - -#ifndef GL_ARB_shader_objects -/* GL types for handling shader object handles and program/shader text */ -typedef char GLcharARB; /* native character */ -typedef unsigned int GLhandleARB; /* shader object handle */ -#endif - -/* GL types for "half" precision (s10e5) float data in host memory */ -#ifndef GL_ARB_half_float_pixel -typedef unsigned short GLhalfARB; -#endif - -#ifndef GL_NV_half_float -typedef unsigned short GLhalfNV; -#endif - -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GL_EXT_timer_query extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) -#include -#if defined(__STDC__) -#if defined(__arch64__) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -#include /* Fallback option */ -#endif -#endif - -#ifndef GL_EXT_timer_query -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -#endif - -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); -GLAPI void APIENTRY glBlendEquation (GLenum); -GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); -GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); -GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); -GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); -GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); -GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); -GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean); -GLAPI void APIENTRY glResetHistogram (GLenum); -GLAPI void APIENTRY glResetMinmax (GLenum); -GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif - -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTexture (GLenum); -GLAPI void APIENTRY glClientActiveTexture (GLenum); -GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble); -GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat); -GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint); -GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort); -GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *); -GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *); -GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *); -GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *); -GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *); -GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean); -GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); -#endif - -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glFogCoordf (GLfloat); -GLAPI void APIENTRY glFogCoordfv (const GLfloat *); -GLAPI void APIENTRY glFogCoordd (GLdouble); -GLAPI void APIENTRY glFogCoorddv (const GLdouble *); -GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); -GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); -GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *); -GLAPI void APIENTRY glPointParameteri (GLenum, GLint); -GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *); -GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *); -GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *); -GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *); -GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint); -GLAPI void APIENTRY glSecondaryColor3iv (const GLint *); -GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *); -GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *); -GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *); -GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort); -GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *); -GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos2dv (const GLdouble *); -GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos2fv (const GLfloat *); -GLAPI void APIENTRY glWindowPos2i (GLint, GLint); -GLAPI void APIENTRY glWindowPos2iv (const GLint *); -GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort); -GLAPI void APIENTRY glWindowPos2sv (const GLshort *); -GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos3dv (const GLdouble *); -GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos3fv (const GLfloat *); -GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos3iv (const GLint *); -GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos3sv (const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); -#endif - -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueries (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteQueries (GLsizei, const GLuint *); -GLAPI GLboolean APIENTRY glIsQuery (GLuint); -GLAPI void APIENTRY glBeginQuery (GLenum, GLuint); -GLAPI void APIENTRY glEndQuery (GLenum); -GLAPI void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *); -GLAPI void APIENTRY glBindBuffer (GLenum, GLuint); -GLAPI void APIENTRY glDeleteBuffers (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenBuffers (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsBuffer (GLuint); -GLAPI void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); -GLAPI void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); -GLAPI void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); -GLAPI GLvoid* APIENTRY glMapBuffer (GLenum, GLenum); -GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum); -GLAPI void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); -#endif - -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparate (GLenum, GLenum); -GLAPI void APIENTRY glDrawBuffers (GLsizei, const GLenum *); -GLAPI void APIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); -GLAPI void APIENTRY glStencilMaskSeparate (GLenum, GLuint); -GLAPI void APIENTRY glAttachShader (GLuint, GLuint); -GLAPI void APIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *); -GLAPI void APIENTRY glCompileShader (GLuint); -GLAPI GLuint APIENTRY glCreateProgram (void); -GLAPI GLuint APIENTRY glCreateShader (GLenum); -GLAPI void APIENTRY glDeleteProgram (GLuint); -GLAPI void APIENTRY glDeleteShader (GLuint); -GLAPI void APIENTRY glDetachShader (GLuint, GLuint); -GLAPI void APIENTRY glDisableVertexAttribArray (GLuint); -GLAPI void APIENTRY glEnableVertexAttribArray (GLuint); -GLAPI void APIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); -GLAPI void APIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); -GLAPI void APIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); -GLAPI GLint APIENTRY glGetAttribLocation (GLuint, const GLchar *); -GLAPI void APIENTRY glGetProgramiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); -GLAPI void APIENTRY glGetShaderiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); -GLAPI void APIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); -GLAPI GLint APIENTRY glGetUniformLocation (GLuint, const GLchar *); -GLAPI void APIENTRY glGetUniformfv (GLuint, GLint, GLfloat *); -GLAPI void APIENTRY glGetUniformiv (GLuint, GLint, GLint *); -GLAPI void APIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); -GLAPI GLboolean APIENTRY glIsProgram (GLuint); -GLAPI GLboolean APIENTRY glIsShader (GLuint); -GLAPI void APIENTRY glLinkProgram (GLuint); -GLAPI void APIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); -GLAPI void APIENTRY glUseProgram (GLuint); -GLAPI void APIENTRY glUniform1f (GLint, GLfloat); -GLAPI void APIENTRY glUniform2f (GLint, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform1i (GLint, GLint); -GLAPI void APIENTRY glUniform2i (GLint, GLint, GLint); -GLAPI void APIENTRY glUniform3i (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform1iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform2iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform3iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform4iv (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glValidateProgram (GLuint); -GLAPI void APIENTRY glVertexAttrib1d (GLuint, GLdouble); -GLAPI void APIENTRY glVertexAttrib1dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib1f (GLuint, GLfloat); -GLAPI void APIENTRY glVertexAttrib1fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib1s (GLuint, GLshort); -GLAPI void APIENTRY glVertexAttrib1sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib2dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib2fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib2sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib3dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib3fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib3sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4Niv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttrib4bv (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib4dv (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib4fv (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib4iv (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib4sv (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4uiv (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4usv (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); -typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformMatrix2x3fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3x2fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix2x4fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4x2fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3x4fv (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4x3fv (GLint, GLsizei, GLboolean, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#endif - -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTextureARB (GLenum); -GLAPI void APIENTRY glClientActiveTextureARB (GLenum); -GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); -GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); -GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); -GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); -GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); -GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); -GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); -GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); -GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); -#endif - -#ifndef GL_ARB_transpose_matrix -#define GL_ARB_transpose_matrix 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); -GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); -GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); -GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -#endif - -#ifndef GL_ARB_multisample -#define GL_ARB_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); -#endif - -#ifndef GL_ARB_texture_env_add -#define GL_ARB_texture_env_add 1 -#endif - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 -#endif - -#ifndef GL_ARB_texture_compression -#define GL_ARB_texture_compression 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); -#endif - -#ifndef GL_ARB_texture_border_clamp -#define GL_ARB_texture_border_clamp 1 -#endif - -#ifndef GL_ARB_point_parameters -#define GL_ARB_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_ARB_vertex_blend -#define GL_ARB_vertex_blend 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *); -GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *); -GLAPI void APIENTRY glWeightivARB (GLint, const GLint *); -GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *); -GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *); -GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *); -GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *); -GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *); -GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glVertexBlendARB (GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); -typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); -typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); -typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); -typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); -typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); -typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); -#endif - -#ifndef GL_ARB_matrix_palette -#define GL_ARB_matrix_palette 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint); -GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *); -GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *); -GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *); -GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); -typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_ARB_texture_env_combine -#define GL_ARB_texture_env_combine 1 -#endif - -#ifndef GL_ARB_texture_env_crossbar -#define GL_ARB_texture_env_crossbar 1 -#endif - -#ifndef GL_ARB_texture_env_dot3 -#define GL_ARB_texture_env_dot3 1 -#endif - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_ARB_texture_mirrored_repeat 1 -#endif - -#ifndef GL_ARB_depth_texture -#define GL_ARB_depth_texture 1 -#endif - -#ifndef GL_ARB_shadow -#define GL_ARB_shadow 1 -#endif - -#ifndef GL_ARB_shadow_ambient -#define GL_ARB_shadow_ambient 1 -#endif - -#ifndef GL_ARB_window_pos -#define GL_ARB_window_pos 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *); -GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *); -GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint); -GLAPI void APIENTRY glWindowPos2ivARB (const GLint *); -GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort); -GLAPI void APIENTRY glWindowPos2svARB (const GLshort *); -GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *); -GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *); -GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos3ivARB (const GLint *); -GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos3svARB (const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); -#endif - -#ifndef GL_ARB_vertex_program -#define GL_ARB_vertex_program 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble); -GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat); -GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort); -GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); -GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint); -GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint); -GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint); -GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *); -GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); -GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); -GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); -GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); -GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); -GLAPI GLboolean APIENTRY glIsProgramARB (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); -typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); -#endif - -#ifndef GL_ARB_fragment_program -#define GL_ARB_fragment_program 1 -/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ -#endif - -#ifndef GL_ARB_vertex_buffer_object -#define GL_ARB_vertex_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint); -GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsBufferARB (GLuint); -GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); -GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); -GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); -GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum); -GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum); -GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); -#endif - -#ifndef GL_ARB_occlusion_query -#define GL_ARB_occlusion_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueriesARB (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *); -GLAPI GLboolean APIENTRY glIsQueryARB (GLuint); -GLAPI void APIENTRY glBeginQueryARB (GLenum, GLuint); -GLAPI void APIENTRY glEndQueryARB (GLenum); -GLAPI void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); -#endif - -#ifndef GL_ARB_shader_objects -#define GL_ARB_shader_objects 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB); -GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum); -GLAPI void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB); -GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum); -GLAPI void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); -GLAPI void APIENTRY glCompileShaderARB (GLhandleARB); -GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); -GLAPI void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB); -GLAPI void APIENTRY glLinkProgramARB (GLhandleARB); -GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB); -GLAPI void APIENTRY glValidateProgramARB (GLhandleARB); -GLAPI void APIENTRY glUniform1fARB (GLint, GLfloat); -GLAPI void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glUniform1iARB (GLint, GLint); -GLAPI void APIENTRY glUniform2iARB (GLint, GLint, GLint); -GLAPI void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *); -GLAPI void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); -GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); -GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); -GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); -GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); -GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *); -GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); -GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *); -GLAPI void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *); -GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); -typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); -typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); -typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#endif - -#ifndef GL_ARB_vertex_shader -#define GL_ARB_vertex_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); -GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); -GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -#endif - -#ifndef GL_ARB_fragment_shader -#define GL_ARB_fragment_shader 1 -#endif - -#ifndef GL_ARB_shading_language_100 -#define GL_ARB_shading_language_100 1 -#endif - -#ifndef GL_ARB_texture_non_power_of_two -#define GL_ARB_texture_non_power_of_two 1 -#endif - -#ifndef GL_ARB_point_sprite -#define GL_ARB_point_sprite 1 -#endif - -#ifndef GL_ARB_fragment_program_shadow -#define GL_ARB_fragment_program_shadow 1 -#endif - -#ifndef GL_ARB_draw_buffers -#define GL_ARB_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersARB (GLsizei, const GLenum *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); -#endif - -#ifndef GL_ARB_texture_rectangle -#define GL_ARB_texture_rectangle 1 -#endif - -#ifndef GL_ARB_color_buffer_float -#define GL_ARB_color_buffer_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClampColorARB (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); -#endif - -#ifndef GL_ARB_half_float_pixel -#define GL_ARB_half_float_pixel 1 -#endif - -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 -#endif - -#ifndef GL_ARB_pixel_buffer_object -#define GL_ARB_pixel_buffer_object 1 -#endif - -#ifndef GL_EXT_abgr -#define GL_EXT_abgr 1 -#endif - -#ifndef GL_EXT_blend_color -#define GL_EXT_blend_color 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -#endif - -#ifndef GL_EXT_polygon_offset -#define GL_EXT_polygon_offset 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); -#endif - -#ifndef GL_EXT_texture -#define GL_EXT_texture 1 -#endif - -#ifndef GL_EXT_texture3D -#define GL_EXT_texture3D 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_SGIS_texture_filter4 -#define GL_SGIS_texture_filter4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); -typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#endif - -#ifndef GL_EXT_subtexture -#define GL_EXT_subtexture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_EXT_copy_texture -#define GL_EXT_copy_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); -GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); -GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif - -#ifndef GL_EXT_histogram -#define GL_EXT_histogram 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); -GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); -GLAPI void APIENTRY glResetHistogramEXT (GLenum); -GLAPI void APIENTRY glResetMinmaxEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); -#endif - -#ifndef GL_EXT_convolution -#define GL_EXT_convolution 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); -GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); -GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -#endif - -#ifndef GL_SGI_color_matrix -#define GL_SGI_color_matrix 1 -#endif - -#ifndef GL_SGI_color_table -#define GL_SGI_color_table 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); -GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); -#endif - -#ifndef GL_SGIX_pixel_texture -#define GL_SGIX_pixel_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenSGIX (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); -#endif - -#ifndef GL_SGIS_pixel_texture -#define GL_SGIS_pixel_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); -GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); -GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); -GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); -GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); -GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); -#endif - -#ifndef GL_SGIS_texture4D -#define GL_SGIS_texture4D 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_SGI_texture_color_table -#define GL_SGI_texture_color_table 1 -#endif - -#ifndef GL_EXT_cmyka -#define GL_EXT_cmyka 1 -#endif - -#ifndef GL_EXT_texture_object -#define GL_EXT_texture_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); -GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint); -GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint); -GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); -typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#endif - -#ifndef GL_SGIS_detail_texture -#define GL_SGIS_detail_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); -GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#endif - -#ifndef GL_SGIS_sharpen_texture -#define GL_SGIS_sharpen_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); -GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#endif - -#ifndef GL_EXT_packed_pixels -#define GL_EXT_packed_pixels 1 -#endif - -#ifndef GL_SGIS_texture_lod -#define GL_SGIS_texture_lod 1 -#endif - -#ifndef GL_SGIS_multisample -#define GL_SGIS_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); -GLAPI void APIENTRY glSamplePatternSGIS (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); -#endif - -#ifndef GL_EXT_rescale_normal -#define GL_EXT_rescale_normal 1 -#endif - -#ifndef GL_EXT_vertex_array -#define GL_EXT_vertex_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glArrayElementEXT (GLint); -GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); -GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); -GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); -GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); -GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); -typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); -typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); -typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_misc_attribute -#define GL_EXT_misc_attribute 1 -#endif - -#ifndef GL_SGIS_generate_mipmap -#define GL_SGIS_generate_mipmap 1 -#endif - -#ifndef GL_SGIX_clipmap -#define GL_SGIX_clipmap 1 -#endif - -#ifndef GL_SGIX_shadow -#define GL_SGIX_shadow 1 -#endif - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_SGIS_texture_edge_clamp 1 -#endif - -#ifndef GL_SGIS_texture_border_clamp -#define GL_SGIS_texture_border_clamp 1 -#endif - -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_blend_subtract -#define GL_EXT_blend_subtract 1 -#endif - -#ifndef GL_EXT_blend_logic_op -#define GL_EXT_blend_logic_op 1 -#endif - -#ifndef GL_SGIX_interlace -#define GL_SGIX_interlace 1 -#endif - -#ifndef GL_SGIX_pixel_tiles -#define GL_SGIX_pixel_tiles 1 -#endif - -#ifndef GL_SGIX_texture_select -#define GL_SGIX_texture_select 1 -#endif - -#ifndef GL_SGIX_sprite -#define GL_SGIX_sprite 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); -GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); -GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); -GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); -#endif - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_SGIX_texture_multi_buffer 1 -#endif - -#ifndef GL_EXT_point_parameters -#define GL_EXT_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); -/* ERO Begin */ -GLAPI void APIENTRY glPointParameteriEXT (GLenum, GLint); -GLAPI void APIENTRY glPointParameterivEXT (GLenum, const GLint *); -/* ERO end */ -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_SGIS_point_parameters -#define GL_SGIS_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); -GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_SGIX_instruments -#define GL_SGIX_instruments 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); -GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); -GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *); -GLAPI void APIENTRY glReadInstrumentsSGIX (GLint); -GLAPI void APIENTRY glStartInstrumentsSGIX (void); -GLAPI void APIENTRY glStopInstrumentsSGIX (GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); -typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); -typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); -typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); -#endif - -#ifndef GL_SGIX_texture_scale_bias -#define GL_SGIX_texture_scale_bias 1 -#endif - -#ifndef GL_SGIX_framezoom -#define GL_SGIX_framezoom 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameZoomSGIX (GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); -#endif - -#ifndef GL_SGIX_tag_sample_buffer -#define GL_SGIX_tag_sample_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTagSampleBufferSGIX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); -#endif - -#ifndef GL_SGIX_polynomial_ffd -#define GL_SGIX_polynomial_ffd 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); -GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); -GLAPI void APIENTRY glDeformSGIX (GLbitfield); -GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); -#endif - -#ifndef GL_SGIX_reference_plane -#define GL_SGIX_reference_plane 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); -#endif - -#ifndef GL_SGIX_flush_raster -#define GL_SGIX_flush_raster 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushRasterSGIX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); -#endif - -#ifndef GL_SGIX_depth_texture -#define GL_SGIX_depth_texture 1 -#endif - -#ifndef GL_SGIS_fog_function -#define GL_SGIS_fog_function 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); -GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); -#endif - -#ifndef GL_SGIX_fog_offset -#define GL_SGIX_fog_offset 1 -#endif - -#ifndef GL_HP_image_transform -#define GL_HP_image_transform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); -GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_HP_convolution_border_modes -#define GL_HP_convolution_border_modes 1 -#endif - -#ifndef GL_SGIX_texture_add_env -#define GL_SGIX_texture_add_env 1 -#endif - -#ifndef GL_EXT_color_subtable -#define GL_EXT_color_subtable 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#endif - -#ifndef GL_PGI_vertex_hints -#define GL_PGI_vertex_hints 1 -#endif - -#ifndef GL_PGI_misc_hints -#define GL_PGI_misc_hints 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glHintPGI (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); -#endif - -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); -GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); -GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_EXT_clip_volume_hint -#define GL_EXT_clip_volume_hint 1 -#endif - -#ifndef GL_SGIX_list_priority -#define GL_SGIX_list_priority 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); -GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); -GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); -GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); -#endif - -#ifndef GL_SGIX_ir_instrument1 -#define GL_SGIX_ir_instrument1 1 -#endif - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_SGIX_calligraphic_fragment 1 -#endif - -#ifndef GL_SGIX_texture_lod_bias -#define GL_SGIX_texture_lod_bias 1 -#endif - -#ifndef GL_SGIX_shadow_ambient -#define GL_SGIX_shadow_ambient 1 -#endif - -#ifndef GL_EXT_index_texture -#define GL_EXT_index_texture 1 -#endif - -#ifndef GL_EXT_index_material -#define GL_EXT_index_material 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); -#endif - -#ifndef GL_EXT_index_func -#define GL_EXT_index_func 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); -#endif - -#ifndef GL_EXT_index_array_formats -#define GL_EXT_index_array_formats 1 -#endif - -#ifndef GL_EXT_compiled_vertex_array -#define GL_EXT_compiled_vertex_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei); -GLAPI void APIENTRY glUnlockArraysEXT (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); -#endif - -#ifndef GL_EXT_cull_vertex -#define GL_EXT_cull_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); -GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); -#endif - -#ifndef GL_SGIX_ycrcb -#define GL_SGIX_ycrcb 1 -#endif - -#ifndef GL_SGIX_fragment_lighting -#define GL_SGIX_fragment_lighting 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); -GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); -GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); -GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); -GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); -GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); -GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); -GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); -#endif - -#ifndef GL_IBM_rasterpos_clip -#define GL_IBM_rasterpos_clip 1 -#endif - -#ifndef GL_HP_texture_lighting -#define GL_HP_texture_lighting 1 -#endif - -#ifndef GL_EXT_draw_range_elements -#define GL_EXT_draw_range_elements 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -#endif - -#ifndef GL_WIN_phong_shading -#define GL_WIN_phong_shading 1 -#endif - -#ifndef GL_WIN_specular_fog -#define GL_WIN_specular_fog 1 -#endif - -#ifndef GL_EXT_light_texture -#define GL_EXT_light_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glApplyTextureEXT (GLenum); -GLAPI void APIENTRY glTextureLightEXT (GLenum); -GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); -#endif - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_SGIX_blend_alpha_minmax 1 -#endif - -#ifndef GL_EXT_bgra -#define GL_EXT_bgra 1 -#endif - -#ifndef GL_SGIX_async -#define GL_SGIX_async 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint); -GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *); -GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *); -GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); -GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); -GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); -typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); -typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); -typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); -typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); -typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); -#endif - -#ifndef GL_SGIX_async_pixel -#define GL_SGIX_async_pixel 1 -#endif - -#ifndef GL_SGIX_async_histogram -#define GL_SGIX_async_histogram 1 -#endif - -#ifndef GL_INTEL_parallel_arrays -#define GL_INTEL_parallel_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); -GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); -GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); -GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -#endif - -#ifndef GL_HP_occlusion_test -#define GL_HP_occlusion_test 1 -#endif - -#ifndef GL_EXT_pixel_transform -#define GL_EXT_pixel_transform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); -GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); -GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); -/* ERO Begin */ -GLAPI void APIENTRY glGetPixelTransformParameterivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetPixelTransformParameterfvEXT (GLenum, GLenum, GLfloat *); -/* ERO End */ -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -/* ERO Begin */ -typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -/* ERO End */ -#endif - -#ifndef GL_EXT_pixel_transform_color_table -#define GL_EXT_pixel_transform_color_table 1 -#endif - -#ifndef GL_EXT_shared_texture_palette -#define GL_EXT_shared_texture_palette 1 -#endif - -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 -#endif - -#ifndef GL_EXT_secondary_color -#define GL_EXT_secondary_color 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); -GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); -GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); -GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); -GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *); -GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *); -GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); -GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *); -GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); -GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *); -GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_texture_perturb_normal -#define GL_EXT_texture_perturb_normal 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureNormalEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); -GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -#endif - -#ifndef GL_EXT_fog_coord -#define GL_EXT_fog_coord 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogCoordfEXT (GLfloat); -GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *); -GLAPI void APIENTRY glFogCoorddEXT (GLdouble); -GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *); -GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_REND_screen_coordinates -#define GL_REND_screen_coordinates 1 -#endif - -#ifndef GL_EXT_coordinate_frame -#define GL_EXT_coordinate_frame 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *); -GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *); -GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *); -GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint); -GLAPI void APIENTRY glTangent3ivEXT (const GLint *); -GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glTangent3svEXT (const GLshort *); -GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *); -GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *); -GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *); -GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); -GLAPI void APIENTRY glBinormal3ivEXT (const GLint *); -GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glBinormal3svEXT (const GLshort *); -GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); -typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); -typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); -typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); -typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); -typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); -typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); -typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); -typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); -typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); -typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_texture_env_combine -#define GL_EXT_texture_env_combine 1 -#endif - -#ifndef GL_APPLE_specular_vector -#define GL_APPLE_specular_vector 1 -#endif - -#ifndef GL_APPLE_transform_hint -#define GL_APPLE_transform_hint 1 -#endif - -#ifndef GL_SGIX_fog_scale -#define GL_SGIX_fog_scale 1 -#endif - -#ifndef GL_SUNX_constant_data -#define GL_SUNX_constant_data 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFinishTextureSUNX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); -#endif - -#ifndef GL_SUN_global_alpha -#define GL_SUN_global_alpha 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); -GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort); -GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint); -GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); -GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble); -GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); -GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort); -GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); -#endif - -#ifndef GL_SUN_triangle_list -#define GL_SUN_triangle_list 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint); -GLAPI void APIENTRY glReplacementCodeusSUN (GLushort); -GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte); -GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *); -GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *); -GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *); -GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); -#endif - -#ifndef GL_SUN_vertex -#define GL_SUN_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); -GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#endif - -#ifndef GL_EXT_blend_func_separate -#define GL_EXT_blend_func_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif - -#ifndef GL_INGR_blend_func_separate -#define GL_INGR_blend_func_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif - -#ifndef GL_INGR_color_clamp -#define GL_INGR_color_clamp 1 -#endif - -#ifndef GL_INGR_interlace_read -#define GL_INGR_interlace_read 1 -#endif - -#ifndef GL_EXT_stencil_wrap -#define GL_EXT_stencil_wrap 1 -#endif - -#ifndef GL_EXT_422_pixels -#define GL_EXT_422_pixels 1 -#endif - -#ifndef GL_NV_texgen_reflection -#define GL_NV_texgen_reflection 1 -#endif - -#ifndef GL_SUN_convolution_border_modes -#define GL_SUN_convolution_border_modes 1 -#endif - -#ifndef GL_EXT_texture_env_add -#define GL_EXT_texture_env_add 1 -#endif - -#ifndef GL_EXT_texture_lod_bias -#define GL_EXT_texture_lod_bias 1 -#endif - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 -#endif - -#ifndef GL_EXT_vertex_weighting -#define GL_EXT_vertex_weighting 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexWeightfEXT (GLfloat); -GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *); -GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_NV_light_max_exponent -#define GL_NV_light_max_exponent 1 -#endif - -#ifndef GL_NV_vertex_array_range -#define GL_NV_vertex_array_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); -GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); -#endif - -#ifndef GL_NV_register_combiners -#define GL_NV_register_combiners 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); -GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); -GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); -GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint); -GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); -GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); -#endif - -#ifndef GL_NV_fog_distance -#define GL_NV_fog_distance 1 -#endif - -#ifndef GL_NV_texgen_emboss -#define GL_NV_texgen_emboss 1 -#endif - -#ifndef GL_NV_blend_square -#define GL_NV_blend_square 1 -#endif - -#ifndef GL_NV_texture_env_combine4 -#define GL_NV_texture_env_combine4 1 -#endif - -#ifndef GL_MESA_resize_buffers -#define GL_MESA_resize_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glResizeBuffersMESA (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); -#endif - -#ifndef GL_MESA_window_pos -#define GL_MESA_window_pos 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *); -GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *); -GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint); -GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *); -GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort); -GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *); -GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *); -GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *); -GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *); -GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *); -GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *); -GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *); -GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *); -GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); -#endif - -#ifndef GL_IBM_cull_vertex -#define GL_IBM_cull_vertex 1 -#endif - -#ifndef GL_IBM_multimode_draw_arrays -#define GL_IBM_multimode_draw_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); -GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); -#endif - -#ifndef GL_IBM_vertex_array_lists -#define GL_IBM_vertex_array_lists 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); -GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -#endif - -#ifndef GL_SGIX_subsample -#define GL_SGIX_subsample 1 -#endif - -#ifndef GL_SGIX_ycrcba -#define GL_SGIX_ycrcba 1 -#endif - -#ifndef GL_SGIX_ycrcb_subsample -#define GL_SGIX_ycrcb_subsample 1 -#endif - -#ifndef GL_SGIX_depth_pass_instrument -#define GL_SGIX_depth_pass_instrument 1 -#endif - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_3DFX_texture_compression_FXT1 1 -#endif - -#ifndef GL_3DFX_multisample -#define GL_3DFX_multisample 1 -#endif - -#ifndef GL_3DFX_tbuffer -#define GL_3DFX_tbuffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTbufferMask3DFX (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); -#endif - -#ifndef GL_EXT_multisample -#define GL_EXT_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); -GLAPI void APIENTRY glSamplePatternEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); -#endif - -#ifndef GL_SGIX_vertex_preclip -#define GL_SGIX_vertex_preclip 1 -#endif - -#ifndef GL_SGIX_convolution_accuracy -#define GL_SGIX_convolution_accuracy 1 -#endif - -#ifndef GL_SGIX_resample -#define GL_SGIX_resample 1 -#endif - -#ifndef GL_SGIS_point_line_texgen -#define GL_SGIS_point_line_texgen 1 -#endif - -#ifndef GL_SGIS_texture_color_mask -#define GL_SGIS_texture_color_mask 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#endif - -#ifndef GL_SGIX_igloo_interface -#define GL_SGIX_igloo_interface 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); -#endif - -#ifndef GL_EXT_texture_env_dot3 -#define GL_EXT_texture_env_dot3 1 -#endif - -#ifndef GL_ATI_texture_mirror_once -#define GL_ATI_texture_mirror_once 1 -#endif - -#ifndef GL_NV_fence -#define GL_NV_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsFenceNV (GLuint); -GLAPI GLboolean APIENTRY glTestFenceNV (GLuint); -GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glFinishFenceNV (GLuint); -GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); -typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -#endif - -#ifndef GL_NV_evaluators -#define GL_NV_evaluators 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); -GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); -GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); -typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); -#endif - -#ifndef GL_NV_packed_depth_stencil -#define GL_NV_packed_depth_stencil 1 -#endif - -#ifndef GL_NV_register_combiners2 -#define GL_NV_register_combiners2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); -GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_NV_texture_compression_vtc -#define GL_NV_texture_compression_vtc 1 -#endif - -#ifndef GL_NV_texture_rectangle -#define GL_NV_texture_rectangle 1 -#endif - -#ifndef GL_NV_texture_shader -#define GL_NV_texture_shader 1 -#endif - -#ifndef GL_NV_texture_shader2 -#define GL_NV_texture_shader2 1 -#endif - -#ifndef GL_NV_vertex_array_range2 -#define GL_NV_vertex_array_range2 1 -#endif - -#ifndef GL_NV_vertex_program -#define GL_NV_vertex_program 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); -GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint); -GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *); -GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *); -GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *); -GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); -GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); -GLAPI GLboolean APIENTRY glIsProgramNV (GLuint); -GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); -GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); -GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); -GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); -GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *); -GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); -GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble); -GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat); -GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort); -GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *); -GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *); -GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); -GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); -GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); -GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); -typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); -typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); -typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); -#endif - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_SGIX_texture_coordinate_clamp 1 -#endif - -#ifndef GL_SGIX_scalebias_hint -#define GL_SGIX_scalebias_hint 1 -#endif - -#ifndef GL_OML_interlace -#define GL_OML_interlace 1 -#endif - -#ifndef GL_OML_subsample -#define GL_OML_subsample 1 -#endif - -#ifndef GL_OML_resample -#define GL_OML_resample 1 -#endif - -#ifndef GL_NV_copy_depth_to_color -#define GL_NV_copy_depth_to_color 1 -#endif - -#ifndef GL_ATI_envmap_bumpmap -#define GL_ATI_envmap_bumpmap 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *); -GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *); -GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -#endif - -#ifndef GL_ATI_fragment_shader -#define GL_ATI_fragment_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint); -GLAPI void APIENTRY glBindFragmentShaderATI (GLuint); -GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint); -GLAPI void APIENTRY glBeginFragmentShaderATI (void); -GLAPI void APIENTRY glEndFragmentShaderATI (void); -GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum); -GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum); -GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); -typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); -typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); -#endif - -#ifndef GL_ATI_pn_triangles -#define GL_ATI_pn_triangles 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint); -GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); -#endif - -#ifndef GL_ATI_vertex_array_object -#define GL_ATI_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); -GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint); -GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); -GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glFreeObjectBufferATI (GLuint); -/* ERO Begin */ -GLAPI void APIENTRY glDeleteObjectBufferATI (GLuint); -/* ERO End */ -GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); -GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); -GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); -GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); -typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); -#endif - -#ifndef GL_EXT_vertex_shader -#define GL_EXT_vertex_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVertexShaderEXT (void); -GLAPI void APIENTRY glEndVertexShaderEXT (void); -GLAPI void APIENTRY glBindVertexShaderEXT (GLuint); -GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint); -GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint); -GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint); -GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint); -GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *); -GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); -GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *); -GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *); -GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *); -GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *); -GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *); -GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *); -GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); -GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint); -GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint); -GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum); -GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum); -GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum); -GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum); -GLAPI GLuint APIENTRY glBindParameterEXT (GLenum); -GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum); -GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); -GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); -GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); -GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); -GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); -typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); -typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); -typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); -typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); -typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); -typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); -typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); -typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); -typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); -typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); -typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); -typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); -typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); -typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); -typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); -typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -#endif - -#ifndef GL_ATI_vertex_streams -#define GL_ATI_vertex_streams 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort); -GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint); -GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat); -GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble); -GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort); -GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint); -GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); -GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *); -GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); -GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *); -GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint); -GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *); -GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *); -GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *); -GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum); -GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint); -GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); -#endif - -#ifndef GL_ATI_element_array -#define GL_ATI_element_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *); -GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei); -GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); -#endif - -#ifndef GL_SUN_mesh_array -#define GL_SUN_mesh_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); -#endif - -#ifndef GL_SUN_slice_accum -#define GL_SUN_slice_accum 1 -#endif - -#ifndef GL_NV_multisample_filter_hint -#define GL_NV_multisample_filter_hint 1 -#endif - -#ifndef GL_NV_depth_clamp -#define GL_NV_depth_clamp 1 -#endif - -#ifndef GL_NV_occlusion_query -#define GL_NV_occlusion_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *); -GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint); -GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint); -GLAPI void APIENTRY glEndOcclusionQueryNV (void); -GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); -#endif - -#ifndef GL_NV_point_sprite -#define GL_NV_point_sprite 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint); -GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -#endif - -#ifndef GL_NV_texture_shader3 -#define GL_NV_texture_shader3 1 -#endif - -#ifndef GL_NV_vertex_program1_1 -#define GL_NV_vertex_program1_1 1 -#endif - -#ifndef GL_EXT_shadow_funcs -#define GL_EXT_shadow_funcs 1 -#endif - -#ifndef GL_EXT_stencil_two_side -#define GL_EXT_stencil_two_side 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); -#endif - -#ifndef GL_ATI_text_fragment_shader -#define GL_ATI_text_fragment_shader 1 -#endif - -#ifndef GL_APPLE_client_storage -#define GL_APPLE_client_storage 1 -#endif - -#ifndef GL_APPLE_element_array -#define GL_APPLE_element_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *); -GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei); -GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); -GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); -GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#endif - -#ifndef GL_APPLE_fence -#define GL_APPLE_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *); -GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *); -GLAPI void APIENTRY glSetFenceAPPLE (GLuint); -GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint); -GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint); -GLAPI void APIENTRY glFinishFenceAPPLE (GLuint); -GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint); -GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); -typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); -typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); -#endif - -#ifndef GL_APPLE_vertex_array_object -#define GL_APPLE_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint); -GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, GLuint *); -GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); -#endif - -#ifndef GL_APPLE_vertex_array_range -#define GL_APPLE_vertex_array_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *); -GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); -GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); -#endif - -#ifndef GL_APPLE_ycbcr_422 -#define GL_APPLE_ycbcr_422 1 -#endif - -#ifndef GL_S3_s3tc -#define GL_S3_s3tc 1 -#endif - -#ifndef GL_ATI_draw_buffers -#define GL_ATI_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); -#endif - -#ifndef GL_ATI_pixel_format_float -#define GL_ATI_pixel_format_float 1 -/* This is really a WGL extension, but defines some associated GL enums. - * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. - */ -#endif - -#ifndef GL_ATI_texture_env_combine3 -#define GL_ATI_texture_env_combine3 1 -#endif - -#ifndef GL_ATI_texture_float -#define GL_ATI_texture_float 1 -#endif - -#ifndef GL_NV_float_buffer -#define GL_NV_float_buffer 1 -#endif - -#ifndef GL_NV_fragment_program -#define GL_NV_fragment_program 1 -/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); -GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); -GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); -GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); -GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#endif - -#ifndef GL_NV_half_float -#define GL_NV_half_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *); -GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV); -GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *); -GLAPI void APIENTRY glFogCoordhNV (GLhalfNV); -GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *); -GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV); -GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); -GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); -GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); -typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); -typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -#endif - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *); -GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -#endif - -#ifndef GL_NV_primitive_restart -#define GL_NV_primitive_restart 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPrimitiveRestartNV (void); -GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); -#endif - -#ifndef GL_NV_texture_expand_normal -#define GL_NV_texture_expand_normal 1 -#endif - -#ifndef GL_NV_vertex_program2 -#define GL_NV_vertex_program2 1 -#endif - -#ifndef GL_ATI_map_object_buffer -#define GL_ATI_map_object_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint); -GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); -#endif - -#ifndef GL_ATI_separate_stencil -#define GL_ATI_separate_stencil 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); -GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#endif - -#ifndef GL_ATI_vertex_attrib_array_object -#define GL_ATI_vertex_attrib_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); -GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); -GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); -#endif - -#ifndef GL_OES_read_format -#define GL_OES_read_format 1 -#endif - -#ifndef GL_EXT_depth_bounds_test -#define GL_EXT_depth_bounds_test 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); -#endif - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_EXT_texture_mirror_clamp 1 -#endif - -#ifndef GL_EXT_blend_equation_separate -#define GL_EXT_blend_equation_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); -#endif - -#ifndef GL_MESA_pack_invert -#define GL_MESA_pack_invert 1 -#endif - -#ifndef GL_MESA_ycbcr_texture -#define GL_MESA_ycbcr_texture 1 -#endif - -#ifndef GL_EXT_pixel_buffer_object -#define GL_EXT_pixel_buffer_object 1 -#endif - -#ifndef GL_NV_fragment_program_option -#define GL_NV_fragment_program_option 1 -#endif - -#ifndef GL_NV_fragment_program2 -#define GL_NV_fragment_program2 1 -#endif - -#ifndef GL_NV_vertex_program2_option -#define GL_NV_vertex_program2_option 1 -#endif - -#ifndef GL_NV_vertex_program3 -#define GL_NV_vertex_program3 1 -#endif - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint); -GLAPI void APIENTRY glBindRenderbufferEXT (GLenum, GLuint); -GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *); -GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); -GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); -GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint); -GLAPI void APIENTRY glBindFramebufferEXT (GLenum, GLuint); -GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *); -GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *); -GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum); -GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); -GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGenerateMipmapEXT (GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); -#endif - -#ifndef GL_GREMEDY_string_marker -#define GL_GREMEDY_string_marker 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); -#endif - -#ifndef GL_EXT_packed_depth_stencil -#define GL_EXT_packed_depth_stencil 1 -#endif - -#ifndef GL_EXT_stencil_clear_tag -#define GL_EXT_stencil_clear_tag 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilClearTagEXT (GLsizei, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); -#endif - -#ifndef GL_EXT_texture_sRGB -#define GL_EXT_texture_sRGB 1 -#endif - -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlitFramebufferEXT (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif - -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif - -#ifndef GL_MESAX_texture_stack -#define GL_MESAX_texture_stack 1 -#endif - -#ifndef GL_EXT_timer_query -#define GL_EXT_timer_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint, GLenum, GLint64EXT *); -GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint, GLenum, GLuint64EXT *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); -#endif - -#ifndef GL_EXT_gpu_program_parameters -#define GL_EXT_gpu_program_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#endif - -#ifndef GL_APPLE_flush_buffer_range -#define GL_APPLE_flush_buffer_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum, GLenum, GLint); -GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum, GLintptr, GLsizeiptr); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); -#endif - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum, GLuint, const GLint *); -GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum, GLuint, const GLuint *); -GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); -GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum, GLuint, const GLint *); -GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum, GLuint, const GLuint *); -GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); -GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum, GLuint, GLint *); -GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum, GLuint, GLuint *); -GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum, GLuint, GLint *); -GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum, GLuint, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -#endif - -#ifndef GL_NV_geometry_program4 -#define GL_NV_geometry_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramVertexLimitNV (GLenum, GLint); -GLAPI void APIENTRY glFramebufferTextureEXT (GLenum, GLenum, GLuint, GLint); -GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum, GLenum, GLuint, GLint, GLint); -GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum, GLenum, GLuint, GLint, GLenum); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriEXT (GLuint, GLenum, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); -#endif - -#ifndef GL_NV_vertex_program4 -#define GL_NV_vertex_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint, GLint); -GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint, GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint, const GLint *); -GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint, const GLuint *); -GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint, const GLbyte *); -GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint, const GLshort *); -GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint, const GLubyte *); -GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint, const GLushort *); -GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint, GLint, GLenum, GLsizei, const GLvoid *); -GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint, GLenum, GLint *); -GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint, GLenum, GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -#endif - -#ifndef GL_EXT_gpu_shader4 -#define GL_EXT_gpu_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetUniformuivEXT (GLuint, GLint, GLuint *); -GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint, GLuint, const GLchar *); -GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint, const GLchar *); -GLAPI void APIENTRY glUniform1uiEXT (GLint, GLuint); -GLAPI void APIENTRY glUniform2uiEXT (GLint, GLuint, GLuint); -GLAPI void APIENTRY glUniform3uiEXT (GLint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glUniform4uiEXT (GLint, GLuint, GLuint, GLuint, GLuint); -GLAPI void APIENTRY glUniform1uivEXT (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform2uivEXT (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform3uivEXT (GLint, GLsizei, const GLuint *); -GLAPI void APIENTRY glUniform4uivEXT (GLint, GLsizei, const GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -#endif - -#ifndef GL_EXT_draw_instanced -#define GL_EXT_draw_instanced 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum, GLint, GLsizei, GLsizei); -GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif - -#ifndef GL_EXT_packed_float -#define GL_EXT_packed_float 1 -#endif - -#ifndef GL_EXT_texture_array -#define GL_EXT_texture_array 1 -#endif - -#ifndef GL_EXT_texture_buffer_object -#define GL_EXT_texture_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferEXT (GLenum, GLenum, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#endif - -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc 1 -#endif - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_EXT_texture_compression_rgtc 1 -#endif - -#ifndef GL_EXT_texture_shared_exponent -#define GL_EXT_texture_shared_exponent 1 -#endif - -#ifndef GL_NV_depth_buffer_float -#define GL_NV_depth_buffer_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthRangedNV (GLdouble, GLdouble); -GLAPI void APIENTRY glClearDepthdNV (GLdouble); -GLAPI void APIENTRY glDepthBoundsdNV (GLdouble, GLdouble); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); -typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); -#endif - -#ifndef GL_NV_fragment_program4 -#define GL_NV_fragment_program4 1 -#endif - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_NV_framebuffer_multisample_coverage 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#endif - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_EXT_framebuffer_sRGB 1 -#endif - -#ifndef GL_NV_geometry_shader4 -#define GL_NV_geometry_shader4 1 -#endif - -#ifndef GL_NV_parameter_buffer_object -#define GL_NV_parameter_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum, GLuint, GLuint, GLsizei, const GLfloat *); -GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum, GLuint, GLuint, GLsizei, const GLint *); -GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum, GLuint, GLuint, GLsizei, const GLuint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); -#endif - -#ifndef GL_EXT_draw_buffers2 -#define GL_EXT_draw_buffers2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); -GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum, GLuint, GLboolean *); -GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum, GLuint, GLint *); -GLAPI void APIENTRY glEnableIndexedEXT (GLenum, GLuint); -GLAPI void APIENTRY glDisableIndexedEXT (GLenum, GLuint); -GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); -#endif - -#ifndef GL_NV_transform_feedback -#define GL_NV_transform_feedback 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum); -GLAPI void APIENTRY glEndTransformFeedbackNV (void); -GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint, const GLint *, GLenum); -GLAPI void APIENTRY glBindBufferRangeNV (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); -GLAPI void APIENTRY glBindBufferOffsetNV (GLenum, GLuint, GLuint, GLintptr); -GLAPI void APIENTRY glBindBufferBaseNV (GLenum, GLuint, GLuint); -GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLint *, GLenum); -GLAPI void APIENTRY glActiveVaryingNV (GLuint, const GLchar *); -GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint, const GLchar *); -GLAPI void APIENTRY glGetActiveVaryingNV (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); -GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint, GLuint, GLint *); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); -#endif - -#ifndef GL_EXT_bindable_uniform -#define GL_EXT_bindable_uniform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformBufferEXT (GLuint, GLint, GLuint); -GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint, GLint); -GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint, GLint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); -typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); -typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); -#endif - -#ifndef GL_EXT_texture_integer -#define GL_EXT_texture_integer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexParameterIivEXT (GLenum, GLenum, const GLint *); -GLAPI void APIENTRY glTexParameterIuivEXT (GLenum, GLenum, const GLuint *); -GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum, GLenum, GLint *); -GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum, GLenum, GLuint *); -GLAPI void APIENTRY glClearColorIiEXT (GLint, GLint, GLint, GLint); -GLAPI void APIENTRY glClearColorIuiEXT (GLuint, GLuint, GLuint, GLuint); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); -typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#endif - -/* ERO */ -GLAPI void GLAPIENTRY fake_gluBuild2DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/target-i386/mesa_glu.h b/target-i386/mesa_glu.h deleted file mode 100644 index 98740dd..0000000 --- a/target-i386/mesa_glu.h +++ /dev/null @@ -1,366 +0,0 @@ -/* -** License Applicability. Except to the extent portions of this file are -** made subject to an alternative license as permitted in the SGI Free -** Software License B, Version 1.1 (the "License"), the contents of this -** file are subject only to the provisions of the License. You may not use -** this file except in compliance with the License. You may obtain a copy -** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 -** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** -** http://oss.sgi.com/projects/FreeB -** -** Note that, as provided in the License, the Software is distributed on an -** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS -** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND -** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A -** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** -** Original Code. The Original Code is: OpenGL Sample Implementation, -** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, -** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. -** Copyright in any portions created by third parties is as indicated -** elsewhere herein. All Rights Reserved. -** -** Additional Notice Provisions: This software was created using the -** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has -** not been independently verified as being compliant with the OpenGL(R) -** version 1.2.1 Specification. -*/ - -#ifndef __glu_h__ -#define __glu_h__ - -#if defined(USE_MGL_NAMESPACE) -#include "glu_mangle.h" -#endif - -//#include -#include "mesa_gl.h" - -#ifndef GLAPIENTRY -#define GLAPIENTRY -#endif - -#ifndef GLAPIENTRYP -#define GLAPIENTRYP GLAPIENTRY * -#endif - -#ifdef GLAPI -#undef GLAPI -#endif - -/* __WIN32__ */ -#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__)) -# define __WIN32__ -#endif - -/* GLAPI, part 1 (use WINGDIAPI, if defined) */ -#if defined(__WIN32__) && defined(WINGDIAPI) -# define GLAPI WINGDIAPI -#endif - -#if !defined(GLAPI) -# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GLU32) -# define GLAPI __declspec(dllexport) -# elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL) /* tag specifying we're building for DLL runtime support */ -# define GLAPI __declspec(dllimport) -# else /* for use with static link lib build of Win32 edition only */ -# define GLAPI extern -# endif /* _STATIC_MESA support */ - -#endif - -#ifndef GLAPI -#define GLAPI -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*************************************************************/ - -/* Extensions */ -#define GLU_EXT_object_space_tess 1 -#define GLU_EXT_nurbs_tessellator 1 - -/* Boolean */ -#define GLU_FALSE 0 -#define GLU_TRUE 1 - -/* Version */ -#define GLU_VERSION_1_1 1 -#define GLU_VERSION_1_2 1 -#define GLU_VERSION_1_3 1 - -/* StringName */ -#define GLU_VERSION 100800 -#define GLU_EXTENSIONS 100801 - -/* ErrorCode */ -#define GLU_INVALID_ENUM 100900 -#define GLU_INVALID_VALUE 100901 -#define GLU_OUT_OF_MEMORY 100902 -#define GLU_INCOMPATIBLE_GL_VERSION 100903 -#define GLU_INVALID_OPERATION 100904 - -/* NurbsDisplay */ -/* GLU_FILL */ -#define GLU_OUTLINE_POLYGON 100240 -#define GLU_OUTLINE_PATCH 100241 - -/* NurbsCallback */ -#define GLU_NURBS_ERROR 100103 -#define GLU_ERROR 100103 -#define GLU_NURBS_BEGIN 100164 -#define GLU_NURBS_BEGIN_EXT 100164 -#define GLU_NURBS_VERTEX 100165 -#define GLU_NURBS_VERTEX_EXT 100165 -#define GLU_NURBS_NORMAL 100166 -#define GLU_NURBS_NORMAL_EXT 100166 -#define GLU_NURBS_COLOR 100167 -#define GLU_NURBS_COLOR_EXT 100167 -#define GLU_NURBS_TEXTURE_COORD 100168 -#define GLU_NURBS_TEX_COORD_EXT 100168 -#define GLU_NURBS_END 100169 -#define GLU_NURBS_END_EXT 100169 -#define GLU_NURBS_BEGIN_DATA 100170 -#define GLU_NURBS_BEGIN_DATA_EXT 100170 -#define GLU_NURBS_VERTEX_DATA 100171 -#define GLU_NURBS_VERTEX_DATA_EXT 100171 -#define GLU_NURBS_NORMAL_DATA 100172 -#define GLU_NURBS_NORMAL_DATA_EXT 100172 -#define GLU_NURBS_COLOR_DATA 100173 -#define GLU_NURBS_COLOR_DATA_EXT 100173 -#define GLU_NURBS_TEXTURE_COORD_DATA 100174 -#define GLU_NURBS_TEX_COORD_DATA_EXT 100174 -#define GLU_NURBS_END_DATA 100175 -#define GLU_NURBS_END_DATA_EXT 100175 - -/* NurbsError */ -#define GLU_NURBS_ERROR1 100251 -#define GLU_NURBS_ERROR2 100252 -#define GLU_NURBS_ERROR3 100253 -#define GLU_NURBS_ERROR4 100254 -#define GLU_NURBS_ERROR5 100255 -#define GLU_NURBS_ERROR6 100256 -#define GLU_NURBS_ERROR7 100257 -#define GLU_NURBS_ERROR8 100258 -#define GLU_NURBS_ERROR9 100259 -#define GLU_NURBS_ERROR10 100260 -#define GLU_NURBS_ERROR11 100261 -#define GLU_NURBS_ERROR12 100262 -#define GLU_NURBS_ERROR13 100263 -#define GLU_NURBS_ERROR14 100264 -#define GLU_NURBS_ERROR15 100265 -#define GLU_NURBS_ERROR16 100266 -#define GLU_NURBS_ERROR17 100267 -#define GLU_NURBS_ERROR18 100268 -#define GLU_NURBS_ERROR19 100269 -#define GLU_NURBS_ERROR20 100270 -#define GLU_NURBS_ERROR21 100271 -#define GLU_NURBS_ERROR22 100272 -#define GLU_NURBS_ERROR23 100273 -#define GLU_NURBS_ERROR24 100274 -#define GLU_NURBS_ERROR25 100275 -#define GLU_NURBS_ERROR26 100276 -#define GLU_NURBS_ERROR27 100277 -#define GLU_NURBS_ERROR28 100278 -#define GLU_NURBS_ERROR29 100279 -#define GLU_NURBS_ERROR30 100280 -#define GLU_NURBS_ERROR31 100281 -#define GLU_NURBS_ERROR32 100282 -#define GLU_NURBS_ERROR33 100283 -#define GLU_NURBS_ERROR34 100284 -#define GLU_NURBS_ERROR35 100285 -#define GLU_NURBS_ERROR36 100286 -#define GLU_NURBS_ERROR37 100287 - -/* NurbsProperty */ -#define GLU_AUTO_LOAD_MATRIX 100200 -#define GLU_CULLING 100201 -#define GLU_SAMPLING_TOLERANCE 100203 -#define GLU_DISPLAY_MODE 100204 -#define GLU_PARAMETRIC_TOLERANCE 100202 -#define GLU_SAMPLING_METHOD 100205 -#define GLU_U_STEP 100206 -#define GLU_V_STEP 100207 -#define GLU_NURBS_MODE 100160 -#define GLU_NURBS_MODE_EXT 100160 -#define GLU_NURBS_TESSELLATOR 100161 -#define GLU_NURBS_TESSELLATOR_EXT 100161 -#define GLU_NURBS_RENDERER 100162 -#define GLU_NURBS_RENDERER_EXT 100162 - -/* NurbsSampling */ -#define GLU_OBJECT_PARAMETRIC_ERROR 100208 -#define GLU_OBJECT_PARAMETRIC_ERROR_EXT 100208 -#define GLU_OBJECT_PATH_LENGTH 100209 -#define GLU_OBJECT_PATH_LENGTH_EXT 100209 -#define GLU_PATH_LENGTH 100215 -#define GLU_PARAMETRIC_ERROR 100216 -#define GLU_DOMAIN_DISTANCE 100217 - -/* NurbsTrim */ -#define GLU_MAP1_TRIM_2 100210 -#define GLU_MAP1_TRIM_3 100211 - -/* QuadricDrawStyle */ -#define GLU_POINT 100010 -#define GLU_LINE 100011 -#define GLU_FILL 100012 -#define GLU_SILHOUETTE 100013 - -/* QuadricCallback */ -/* GLU_ERROR */ - -/* QuadricNormal */ -#define GLU_SMOOTH 100000 -#define GLU_FLAT 100001 -#define GLU_NONE 100002 - -/* QuadricOrientation */ -#define GLU_OUTSIDE 100020 -#define GLU_INSIDE 100021 - -/* TessCallback */ -#define GLU_TESS_BEGIN 100100 -#define GLU_BEGIN 100100 -#define GLU_TESS_VERTEX 100101 -#define GLU_VERTEX 100101 -#define GLU_TESS_END 100102 -#define GLU_END 100102 -#define GLU_TESS_ERROR 100103 -#define GLU_TESS_EDGE_FLAG 100104 -#define GLU_EDGE_FLAG 100104 -#define GLU_TESS_COMBINE 100105 -#define GLU_TESS_BEGIN_DATA 100106 -#define GLU_TESS_VERTEX_DATA 100107 -#define GLU_TESS_END_DATA 100108 -#define GLU_TESS_ERROR_DATA 100109 -#define GLU_TESS_EDGE_FLAG_DATA 100110 -#define GLU_TESS_COMBINE_DATA 100111 - -/* TessContour */ -#define GLU_CW 100120 -#define GLU_CCW 100121 -#define GLU_INTERIOR 100122 -#define GLU_EXTERIOR 100123 -#define GLU_UNKNOWN 100124 - -/* TessProperty */ -#define GLU_TESS_WINDING_RULE 100140 -#define GLU_TESS_BOUNDARY_ONLY 100141 -#define GLU_TESS_TOLERANCE 100142 - -/* TessError */ -#define GLU_TESS_ERROR1 100151 -#define GLU_TESS_ERROR2 100152 -#define GLU_TESS_ERROR3 100153 -#define GLU_TESS_ERROR4 100154 -#define GLU_TESS_ERROR5 100155 -#define GLU_TESS_ERROR6 100156 -#define GLU_TESS_ERROR7 100157 -#define GLU_TESS_ERROR8 100158 -#define GLU_TESS_MISSING_BEGIN_POLYGON 100151 -#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152 -#define GLU_TESS_MISSING_END_POLYGON 100153 -#define GLU_TESS_MISSING_END_CONTOUR 100154 -#define GLU_TESS_COORD_TOO_LARGE 100155 -#define GLU_TESS_NEED_COMBINE_CALLBACK 100156 - -/* TessWinding */ -#define GLU_TESS_WINDING_ODD 100130 -#define GLU_TESS_WINDING_NONZERO 100131 -#define GLU_TESS_WINDING_POSITIVE 100132 -#define GLU_TESS_WINDING_NEGATIVE 100133 -#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134 - -/*************************************************************/ - - -#ifdef __cplusplus -class GLUnurbs; -class GLUquadric; -class GLUtesselator; -#else -typedef struct GLUnurbs GLUnurbs; -typedef struct GLUquadric GLUquadric; -typedef struct GLUtesselator GLUtesselator; -#endif - -typedef GLUnurbs GLUnurbsObj; -typedef GLUquadric GLUquadricObj; -typedef GLUtesselator GLUtesselatorObj; -typedef GLUtesselator GLUtriangulatorObj; - -#define GLU_TESS_MAX_COORD 1.0e150 - -/* Internal convenience typedefs */ -typedef void (GLAPIENTRYP _GLUfuncptr)(void); - -GLAPI void GLAPIENTRY gluBeginCurve (GLUnurbs* nurb); -GLAPI void GLAPIENTRY gluBeginPolygon (GLUtesselator* tess); -GLAPI void GLAPIENTRY gluBeginSurface (GLUnurbs* nurb); -GLAPI void GLAPIENTRY gluBeginTrim (GLUnurbs* nurb); -GLAPI GLint GLAPIENTRY gluBuild1DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data); -GLAPI GLint GLAPIENTRY gluBuild1DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, const void *data); -GLAPI GLint GLAPIENTRY gluBuild2DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data); -GLAPI GLint GLAPIENTRY gluBuild2DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); -GLAPI GLint GLAPIENTRY gluBuild3DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data); -GLAPI GLint GLAPIENTRY gluBuild3DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); -GLAPI GLboolean GLAPIENTRY gluCheckExtension (const GLubyte *extName, const GLubyte *extString); -GLAPI void GLAPIENTRY gluCylinder (GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks); -GLAPI void GLAPIENTRY gluDeleteNurbsRenderer (GLUnurbs* nurb); -GLAPI void GLAPIENTRY gluDeleteQuadric (GLUquadric* quad); -GLAPI void GLAPIENTRY gluDeleteTess (GLUtesselator* tess); -GLAPI void GLAPIENTRY gluDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops); -GLAPI void GLAPIENTRY gluEndCurve (GLUnurbs* nurb); -GLAPI void GLAPIENTRY gluEndPolygon (GLUtesselator* tess); -GLAPI void GLAPIENTRY gluEndSurface (GLUnurbs* nurb); -GLAPI void GLAPIENTRY gluEndTrim (GLUnurbs* nurb); -GLAPI const GLubyte * GLAPIENTRY gluErrorString (GLenum error); -GLAPI void GLAPIENTRY gluGetNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat* data); -GLAPI const GLubyte * GLAPIENTRY gluGetString (GLenum name); -GLAPI void GLAPIENTRY gluGetTessProperty (GLUtesselator* tess, GLenum which, GLdouble* data); -GLAPI void GLAPIENTRY gluLoadSamplingMatrices (GLUnurbs* nurb, const GLfloat *model, const GLfloat *perspective, const GLint *view); -GLAPI void GLAPIENTRY gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ); -GLAPI GLUnurbs* GLAPIENTRY gluNewNurbsRenderer (void); -GLAPI GLUquadric* GLAPIENTRY gluNewQuadric (void); -GLAPI GLUtesselator* GLAPIENTRY gluNewTess (void); -GLAPI void GLAPIENTRY gluNextContour (GLUtesselator* tess, GLenum type); -GLAPI void GLAPIENTRY gluNurbsCallback (GLUnurbs* nurb, GLenum which, _GLUfuncptr CallBackFunc); -GLAPI void GLAPIENTRY gluNurbsCallbackData (GLUnurbs* nurb, GLvoid* userData); -GLAPI void GLAPIENTRY gluNurbsCallbackDataEXT (GLUnurbs* nurb, GLvoid* userData); -GLAPI void GLAPIENTRY gluNurbsCurve (GLUnurbs* nurb, GLint knotCount, GLfloat *knots, GLint stride, GLfloat *control, GLint order, GLenum type); -GLAPI void GLAPIENTRY gluNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat value); -GLAPI void GLAPIENTRY gluNurbsSurface (GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type); -GLAPI void GLAPIENTRY gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top); -GLAPI void GLAPIENTRY gluPartialDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops, GLdouble start, GLdouble sweep); -GLAPI void GLAPIENTRY gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); -GLAPI void GLAPIENTRY gluPickMatrix (GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint *viewport); -GLAPI GLint GLAPIENTRY gluProject (GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ); -GLAPI void GLAPIENTRY gluPwlCurve (GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type); -GLAPI void GLAPIENTRY gluQuadricCallback (GLUquadric* quad, GLenum which, _GLUfuncptr CallBackFunc); -GLAPI void GLAPIENTRY gluQuadricDrawStyle (GLUquadric* quad, GLenum draw); -GLAPI void GLAPIENTRY gluQuadricNormals (GLUquadric* quad, GLenum normal); -GLAPI void GLAPIENTRY gluQuadricOrientation (GLUquadric* quad, GLenum orientation); -GLAPI void GLAPIENTRY gluQuadricTexture (GLUquadric* quad, GLboolean texture); -GLAPI GLint GLAPIENTRY gluScaleImage (GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut); -GLAPI void GLAPIENTRY gluSphere (GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks); -GLAPI void GLAPIENTRY gluTessBeginContour (GLUtesselator* tess); -GLAPI void GLAPIENTRY gluTessBeginPolygon (GLUtesselator* tess, GLvoid* data); -GLAPI void GLAPIENTRY gluTessCallback (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc); -GLAPI void GLAPIENTRY gluTessEndContour (GLUtesselator* tess); -GLAPI void GLAPIENTRY gluTessEndPolygon (GLUtesselator* tess); -GLAPI void GLAPIENTRY gluTessNormal (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ); -GLAPI void GLAPIENTRY gluTessProperty (GLUtesselator* tess, GLenum which, GLdouble data); -GLAPI void GLAPIENTRY gluTessVertex (GLUtesselator* tess, GLdouble *location, GLvoid* data); -GLAPI GLint GLAPIENTRY gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ); -GLAPI GLint GLAPIENTRY gluUnProject4 (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW); - -#ifdef __cplusplus -} -#endif - -#endif /* __glu_h__ */ diff --git a/target-i386/mesa_glx.h b/target-i386/mesa_glx.h deleted file mode 100644 index 02654c4..0000000 --- a/target-i386/mesa_glx.h +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * 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 - * BRIAN PAUL 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. - */ - - -#ifndef GLX_H -#define GLX_H - - -#if defined( _WIN32 ) /* by 13.Nov.2009 */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Tokens for glXChooseVisual and glXGetConfig: - */ -#define GLX_USE_GL 1 -#define GLX_BUFFER_SIZE 2 -#define GLX_LEVEL 3 -#define GLX_RGBA 4 -#define GLX_DOUBLEBUFFER 5 -#define GLX_STEREO 6 -#define GLX_AUX_BUFFERS 7 -#define GLX_RED_SIZE 8 -#define GLX_GREEN_SIZE 9 -#define GLX_BLUE_SIZE 10 -#define GLX_ALPHA_SIZE 11 -#define GLX_DEPTH_SIZE 12 -#define GLX_STENCIL_SIZE 13 -#define GLX_ACCUM_RED_SIZE 14 -#define GLX_ACCUM_GREEN_SIZE 15 -#define GLX_ACCUM_BLUE_SIZE 16 -#define GLX_ACCUM_ALPHA_SIZE 17 - - -/* - * Error codes returned by glXGetConfig: - */ -#define GLX_BAD_SCREEN 1 -#define GLX_BAD_ATTRIBUTE 2 -#define GLX_NO_EXTENSION 3 -#define GLX_BAD_VISUAL 4 -#define GLX_BAD_CONTEXT 5 -#define GLX_BAD_VALUE 6 -#define GLX_BAD_ENUM 7 - - -/* - * GLX 1.1 and later: - */ -#define GLX_VENDOR 1 -#define GLX_VERSION 2 -#define GLX_EXTENSIONS 3 - - -/* - * GLX 1.3 and later: - */ -#define GLX_CONFIG_CAVEAT 0x20 -#define GLX_DONT_CARE 0xFFFFFFFF -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_VISUAL_ID 0x800B -#define GLX_SCREEN 0x800C -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 -#define GLX_PBUFFER_HEIGHT 0x8040 -#define GLX_PBUFFER_WIDTH 0x8041 -#define GLX_RGBA_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 - - -/* - * GLX 1.4 and later: - */ -#define GLX_SAMPLE_BUFFERS 0x186a0 /*100000*/ -#define GLX_SAMPLES 0x186a1 /*100001*/ - -#ifdef __cplusplus -} -#endif - -#else -#ifdef __VMS -#include -# ifdef __cplusplus -/* VMS Xlib.h gives problems with C++. - * this avoids a bunch of trivial warnings */ -#pragma message disable nosimpint -#endif -#endif -#include -#include -#ifdef __VMS -# ifdef __cplusplus -#pragma message enable nosimpint -#endif -#endif -#include - - -#if defined(USE_MGL_NAMESPACE) -#include "glx_mangle.h" -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define GLX_VERSION_1_1 1 -#define GLX_VERSION_1_2 1 -#define GLX_VERSION_1_3 1 -#define GLX_VERSION_1_4 1 - -#define GLX_EXTENSION_NAME "GLX" - - - -/* - * Tokens for glXChooseVisual and glXGetConfig: - */ -#define GLX_USE_GL 1 -#define GLX_BUFFER_SIZE 2 -#define GLX_LEVEL 3 -#define GLX_RGBA 4 -#define GLX_DOUBLEBUFFER 5 -#define GLX_STEREO 6 -#define GLX_AUX_BUFFERS 7 -#define GLX_RED_SIZE 8 -#define GLX_GREEN_SIZE 9 -#define GLX_BLUE_SIZE 10 -#define GLX_ALPHA_SIZE 11 -#define GLX_DEPTH_SIZE 12 -#define GLX_STENCIL_SIZE 13 -#define GLX_ACCUM_RED_SIZE 14 -#define GLX_ACCUM_GREEN_SIZE 15 -#define GLX_ACCUM_BLUE_SIZE 16 -#define GLX_ACCUM_ALPHA_SIZE 17 - - -/* - * Error codes returned by glXGetConfig: - */ -#define GLX_BAD_SCREEN 1 -#define GLX_BAD_ATTRIBUTE 2 -#define GLX_NO_EXTENSION 3 -#define GLX_BAD_VISUAL 4 -#define GLX_BAD_CONTEXT 5 -#define GLX_BAD_VALUE 6 -#define GLX_BAD_ENUM 7 - - -/* - * GLX 1.1 and later: - */ -#define GLX_VENDOR 1 -#define GLX_VERSION 2 -#define GLX_EXTENSIONS 3 - - -/* - * GLX 1.3 and later: - */ -#define GLX_CONFIG_CAVEAT 0x20 -#define GLX_DONT_CARE 0xFFFFFFFF -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_VISUAL_ID 0x800B -#define GLX_SCREEN 0x800C -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 -#define GLX_PBUFFER_HEIGHT 0x8040 -#define GLX_PBUFFER_WIDTH 0x8041 -#define GLX_RGBA_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 - - -/* - * GLX 1.4 and later: - */ -#define GLX_SAMPLE_BUFFERS 0x186a0 /*100000*/ -#define GLX_SAMPLES 0x186a1 /*100001*/ - - - -typedef struct __GLXcontextRec *GLXContext; -typedef XID GLXPixmap; -typedef XID GLXDrawable; -/* GLX 1.3 and later */ -typedef struct __GLXFBConfigRec *GLXFBConfig; -typedef XID GLXFBConfigID; -typedef XID GLXContextID; -typedef XID GLXWindow; -typedef XID GLXPbuffer; - - - -extern XVisualInfo* glXChooseVisual( Display *dpy, int screen, - int *attribList ); - -extern GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, - GLXContext shareList, Bool direct ); - -extern void glXDestroyContext( Display *dpy, GLXContext ctx ); - -extern Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, - GLXContext ctx); - -extern void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, - unsigned long mask ); - -extern void glXSwapBuffers( Display *dpy, GLXDrawable drawable ); - -extern GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visual, - Pixmap pixmap ); - -extern void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ); - -extern Bool glXQueryExtension( Display *dpy, int *errorb, int *event ); - -extern Bool glXQueryVersion( Display *dpy, int *maj, int *min ); - -extern Bool glXIsDirect( Display *dpy, GLXContext ctx ); - -extern int glXGetConfig( Display *dpy, XVisualInfo *visual, - int attrib, int *value ); - -extern GLXContext glXGetCurrentContext( void ); - -extern GLXDrawable glXGetCurrentDrawable( void ); - -extern void glXWaitGL( void ); - -extern void glXWaitX( void ); - -extern void glXUseXFont( Font font, int first, int count, int list ); - - - -/* GLX 1.1 and later */ -extern const char *glXQueryExtensionsString( Display *dpy, int screen ); - -extern const char *glXQueryServerString( Display *dpy, int screen, int name ); - -extern const char *glXGetClientString( Display *dpy, int name ); - - -/* GLX 1.2 and later */ -extern Display *glXGetCurrentDisplay( void ); - - -/* GLX 1.3 and later */ -extern GLXFBConfig *glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ); - -extern int glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, - int attribute, int *value ); - -extern GLXFBConfig *glXGetFBConfigs( Display *dpy, int screen, - int *nelements ); - -extern XVisualInfo *glXGetVisualFromFBConfig( Display *dpy, - GLXFBConfig config ); - -extern GLXWindow glXCreateWindow( Display *dpy, GLXFBConfig config, - Window win, const int *attribList ); - -extern void glXDestroyWindow( Display *dpy, GLXWindow window ); - -extern GLXPixmap glXCreatePixmap( Display *dpy, GLXFBConfig config, - Pixmap pixmap, const int *attribList ); - -extern void glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ); - -extern GLXPbuffer glXCreatePbuffer( Display *dpy, GLXFBConfig config, - const int *attribList ); - -extern void glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ); - -extern void glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, - unsigned int *value ); - -extern GLXContext glXCreateNewContext( Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, - Bool direct ); - -extern Bool glXMakeContextCurrent( Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx ); - -extern GLXDrawable glXGetCurrentReadDrawable( void ); - -extern int glXQueryContext( Display *dpy, GLXContext ctx, int attribute, - int *value ); - -extern void glXSelectEvent( Display *dpy, GLXDrawable drawable, - unsigned long mask ); - -extern void glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, - unsigned long *mask ); - - -/* GLX 1.4 and later */ -extern void (*glXGetProcAddress(const GLubyte *procname))( void ); - - -#ifndef GLX_GLXEXT_LEGACY - -#include - -#else - - - -/* - * ARB 2. GLX_ARB_get_proc_address - */ -#ifndef GLX_ARB_get_proc_address -#define GLX_ARB_get_proc_address 1 - -typedef void (*__GLXextFuncPtr)(void); -extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *); - -#endif /* GLX_ARB_get_proc_address */ - - - -#endif /* GLX_GLXEXT_LEGACY */ - - -/** - ** The following aren't in glxext.h yet. - **/ - - -/* - * ???. GLX_NV_vertex_array_range - */ -#ifndef GLX_NV_vertex_array_range -#define GLX_NV_vertex_array_range - -extern void *glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -extern void glXFreeMemoryNV(GLvoid *pointer); -typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void ( * PFNGLXFREEMEMORYNVPROC) (GLvoid *pointer); - -#endif /* GLX_NV_vertex_array_range */ - - -/* - * ???. GLX_MESA_allocate_memory - */ -#ifndef GLX_MESA_allocate_memory -#define GLX_MESA_allocate_memory 1 - -extern void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority); -extern void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer); -extern GLuint glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer); -typedef void * ( * PFNGLXALLOCATEMEMORYMESAPROC) (Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority); -typedef void ( * PFNGLXFREEMEMORYMESAPROC) (Display *dpy, int scrn, void *pointer); -typedef GLuint (* PFNGLXGETMEMORYOFFSETMESAPROC) (Display *dpy, int scrn, const void *pointer); - -#endif /* GLX_MESA_allocate_memory */ - - -/* - * ARB ?. GLX_ARB_render_texture - * XXX This was never finalized! - */ -#ifndef GLX_ARB_render_texture -#define GLX_ARB_render_texture 1 - -extern Bool glXBindTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer); -extern Bool glXReleaseTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer); -extern Bool glXDrawableAttribARB(Display *dpy, GLXDrawable draw, const int *attribList); - -#endif /* GLX_ARB_render_texture */ - - -#ifndef GLX_ATI_render_texture -#define GLX_ATI_render_texture 1 - -extern void glXBindTexImageATI(Display *dpy, GLXPbuffer pbuffer, int buffer); -extern void glXReleaseTexImageATI(Display *dpy, GLXPbuffer pbuffer, int buffer); -extern void glXDrawableAttribATI(Display *dpy, GLXDrawable draw, const int *attribList); - -#endif /* GLX_ATI_render_texture */ - - -/* - * Remove this when glxext.h is updated. - */ -#ifndef GLX_NV_float_buffer -#define GLX_NV_float_buffer 1 - -#define GLX_FLOAT_COMPONENTS_NV 0x20B0 - -#endif /* GLX_NV_float_buffer */ - - - -/* - * #?. GLX_MESA_swap_frame_usage - */ -#ifndef GLX_MESA_swap_frame_usage -#define GLX_MESA_swap_frame_usage 1 - -extern int glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable, float *usage); -extern int glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable); -extern int glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable); -extern int glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable, int64_t *swapCount, int64_t *missedFrames, float *lastMissedUsage); - -typedef int (*PFNGLXGETFRAMEUSAGEMESAPROC) (Display *dpy, GLXDrawable drawable, float *usage); -typedef int (*PFNGLXBEGINFRAMETRACKINGMESAPROC)(Display *dpy, GLXDrawable drawable); -typedef int (*PFNGLXENDFRAMETRACKINGMESAPROC)(Display *dpy, GLXDrawable drawable); -typedef int (*PFNGLXQUERYFRAMETRACKINGMESAPROC)(Display *dpy, GLXDrawable drawable, int64_t *swapCount, int64_t *missedFrames, float *lastMissedUsage); - -#endif /* GLX_MESA_swap_frame_usage */ - - - -/* - * #?. GLX_MESA_swap_control - */ -#ifndef GLX_MESA_swap_control -#define GLX_MESA_swap_control 1 - -extern int glXSwapIntervalMESA(unsigned int interval); -extern int glXGetSwapIntervalMESA(void); - -typedef int (*PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval); -typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void); - -#endif /* GLX_MESA_swap_control */ - - - -/* - * #?. GLX_EXT_texture_from_pixmap - * XXX not finished? - */ -#ifndef GLX_EXT_texture_from_pixmap -#define GLX_EXT_texture_from_pixmap 1 - -#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 -#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 -#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 -#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 -#define GLX_Y_INVERTED_EXT 0x20D4 - -#define GLX_TEXTURE_FORMAT_EXT 0x20D5 -#define GLX_TEXTURE_TARGET_EXT 0x20D6 -#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 - -#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 -#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 -#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA - -#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 -#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 -#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 - -#define GLX_TEXTURE_1D_EXT 0x20DB -#define GLX_TEXTURE_2D_EXT 0x20DC -#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD - -#define GLX_FRONT_LEFT_EXT 0x20DE -#define GLX_FRONT_RIGHT_EXT 0x20DF -#define GLX_BACK_LEFT_EXT 0x20E0 -#define GLX_BACK_RIGHT_EXT 0x20E1 -#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT -#define GLX_BACK_EXT GLX_BACK_LEFT_EXT -#define GLX_AUX0_EXT 0x20E2 -#define GLX_AUX1_EXT 0x20E3 -#define GLX_AUX2_EXT 0x20E4 -#define GLX_AUX3_EXT 0x20E5 -#define GLX_AUX4_EXT 0x20E6 -#define GLX_AUX5_EXT 0x20E7 -#define GLX_AUX6_EXT 0x20E8 -#define GLX_AUX7_EXT 0x20E9 -#define GLX_AUX8_EXT 0x20EA -#define GLX_AUX9_EXT 0x20EB - -extern void glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); -extern void glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer); - -#endif /* GLX_EXT_texture_from_pixmap */ - - - - -/*** Should these go here, or in another header? */ -/* -** GLX Events -*/ -typedef struct { - int event_type; /* GLX_DAMAGED or GLX_SAVED */ - int draw_type; /* GLX_WINDOW or GLX_PBUFFER */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came for SendEvent request */ - Display *display; /* display the event was read from */ - GLXDrawable drawable; /* XID of Drawable */ - unsigned int buffer_mask; /* mask indicating which buffers are affected */ - unsigned int aux_buffer; /* which aux buffer was affected */ - int x, y; - int width, height; - int count; /* if nonzero, at least this many more */ -} GLXPbufferClobberEvent; - -typedef union __GLXEvent { - GLXPbufferClobberEvent glxpbufferclobber; - long pad[24]; -} GLXEvent; - -#ifdef __cplusplus -} -#endif -#endif - -#endif diff --git a/target-i386/mesa_glxext.h b/target-i386/mesa_glxext.h deleted file mode 100644 index 91b6581..0000000 --- a/target-i386/mesa_glxext.h +++ /dev/null @@ -1,1137 +0,0 @@ -#ifndef __glxext_h_ -#define __glxext_h_ - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are 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 Materials. -** -** THE MATERIALS ARE 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 AUTHORS OR 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -#if defined( _WIN32 ) /* by 16.Nov.2009 */ -#ifdef __cplusplus -extern "C" { -#endif - - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -/* Header file version number, required by OpenGL ABI for Linux */ -/* glxext.h last updated 2007/04/21 */ -/* Current version at http://www.opengl.org/registry/ */ -#define GLX_GLXEXT_VERSION 19 - -#ifndef GLX_VERSION_1_3 -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_RGBA_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 -#define GLX_CONFIG_CAVEAT 0x20 -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_DONT_CARE 0xFFFFFFFF -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_VISUAL_ID 0x800B -#define GLX_SCREEN 0x800C -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 -#define GLX_PBUFFER_HEIGHT 0x8040 -#define GLX_PBUFFER_WIDTH 0x8041 -#endif - -#ifndef GLX_VERSION_1_4 -#define GLX_SAMPLE_BUFFERS 100000 -#define GLX_SAMPLES 100001 -#endif - -#ifndef GLX_ARB_get_proc_address -#endif - -#ifndef GLX_ARB_multisample -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 -#endif - -#ifndef GLX_ARB_fbconfig_float -#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 -#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 -#endif - -#ifndef GLX_SGIS_multisample -#define GLX_SAMPLE_BUFFERS_SGIS 100000 -#define GLX_SAMPLES_SGIS 100001 -#endif - -#ifndef GLX_EXT_visual_info -#define GLX_X_VISUAL_TYPE_EXT 0x22 -#define GLX_TRANSPARENT_TYPE_EXT 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 -#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 -#define GLX_NONE_EXT 0x8000 -#define GLX_TRUE_COLOR_EXT 0x8002 -#define GLX_DIRECT_COLOR_EXT 0x8003 -#define GLX_PSEUDO_COLOR_EXT 0x8004 -#define GLX_STATIC_COLOR_EXT 0x8005 -#define GLX_GRAY_SCALE_EXT 0x8006 -#define GLX_STATIC_GRAY_EXT 0x8007 -#define GLX_TRANSPARENT_RGB_EXT 0x8008 -#define GLX_TRANSPARENT_INDEX_EXT 0x8009 -#endif - -#ifndef GLX_SGI_swap_control -#endif - -#ifndef GLX_SGI_video_sync -#endif - -#ifndef GLX_SGI_make_current_read -#endif - -#ifndef GLX_SGIX_video_source -#endif - -#ifndef GLX_EXT_visual_rating -#define GLX_VISUAL_CAVEAT_EXT 0x20 -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D -/* reuse GLX_NONE_EXT */ -#endif - -#ifndef GLX_EXT_import_context -#define GLX_SHARE_CONTEXT_EXT 0x800A -#define GLX_VISUAL_ID_EXT 0x800B -#define GLX_SCREEN_EXT 0x800C -#endif - -#ifndef GLX_SGIX_fbconfig -#define GLX_WINDOW_BIT_SGIX 0x00000001 -#define GLX_PIXMAP_BIT_SGIX 0x00000002 -#define GLX_RGBA_BIT_SGIX 0x00000001 -#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 -#define GLX_DRAWABLE_TYPE_SGIX 0x8010 -#define GLX_RENDER_TYPE_SGIX 0x8011 -#define GLX_X_RENDERABLE_SGIX 0x8012 -#define GLX_FBCONFIG_ID_SGIX 0x8013 -#define GLX_RGBA_TYPE_SGIX 0x8014 -#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 -/* reuse GLX_SCREEN_EXT */ -#endif - -#ifndef GLX_SGIX_pbuffer -#define GLX_PBUFFER_BIT_SGIX 0x00000004 -#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 -#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 -#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 -#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 -#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 -#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 -#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 -#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 -#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 -#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 -#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A -#define GLX_PRESERVED_CONTENTS_SGIX 0x801B -#define GLX_LARGEST_PBUFFER_SGIX 0x801C -#define GLX_WIDTH_SGIX 0x801D -#define GLX_HEIGHT_SGIX 0x801E -#define GLX_EVENT_MASK_SGIX 0x801F -#define GLX_DAMAGED_SGIX 0x8020 -#define GLX_SAVED_SGIX 0x8021 -#define GLX_WINDOW_SGIX 0x8022 -#define GLX_PBUFFER_SGIX 0x8023 -#endif - -#ifndef GLX_SGI_cushion -#endif - -#ifndef GLX_SGIX_video_resize -#define GLX_SYNC_FRAME_SGIX 0x00000000 -#define GLX_SYNC_SWAP_SGIX 0x00000001 -#endif - -#ifndef GLX_SGIX_dmbuffer -#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 -#endif - -#ifndef GLX_SGIX_swap_group -#endif - -#ifndef GLX_SGIX_swap_barrier -#endif - -#ifndef GLX_SGIS_blended_overlay -#define GLX_BLENDED_RGBA_SGIS 0x8025 -#endif - -#ifndef GLX_SGIS_shared_multisample -#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 -#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 -#endif - -#ifndef GLX_SUN_get_transparent_index -#endif - -#ifndef GLX_3DFX_multisample -#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 -#define GLX_SAMPLES_3DFX 0x8051 -#endif - -#ifndef GLX_MESA_copy_sub_buffer -#endif - -#ifndef GLX_MESA_pixmap_colormap -#endif - -#ifndef GLX_MESA_release_buffers -#endif - -#ifndef GLX_MESA_set_3dfx_mode -#define GLX_3DFX_WINDOW_MODE_MESA 0x1 -#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 -#endif - -#ifndef GLX_SGIX_visual_select_group -#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 -#endif - -#ifndef GLX_OML_swap_method -#define GLX_SWAP_METHOD_OML 0x8060 -#define GLX_SWAP_EXCHANGE_OML 0x8061 -#define GLX_SWAP_COPY_OML 0x8062 -#define GLX_SWAP_UNDEFINED_OML 0x8063 -#endif - -#ifndef GLX_OML_sync_control -#endif - -#ifndef GLX_NV_float_buffer -#define GLX_FLOAT_COMPONENTS_NV 0x20B0 -#endif - -#ifndef GLX_SGIX_hyperpipe -#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 -#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 -#define GLX_BAD_HYPERPIPE_SGIX 92 -#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 -#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 -#define GLX_PIPE_RECT_SGIX 0x00000001 -#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 -#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 -#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 -#define GLX_HYPERPIPE_ID_SGIX 0x8030 -#endif - -#ifndef GLX_MESA_agp_offset -#endif - -#ifndef GLX_EXT_fbconfig_packed_float -#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 -#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 -#endif - -#ifndef GLX_EXT_framebuffer_sRGB -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 -#endif - -#ifndef GLX_EXT_texture_from_pixmap -#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 -#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 -#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 -#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 -#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 -#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 -#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 -#define GLX_Y_INVERTED_EXT 0x20D4 -#define GLX_TEXTURE_FORMAT_EXT 0x20D5 -#define GLX_TEXTURE_TARGET_EXT 0x20D6 -#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 -#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 -#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 -#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA -#define GLX_TEXTURE_1D_EXT 0x20DB -#define GLX_TEXTURE_2D_EXT 0x20DC -#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD -#define GLX_FRONT_LEFT_EXT 0x20DE -#define GLX_FRONT_RIGHT_EXT 0x20DF -#define GLX_BACK_LEFT_EXT 0x20E0 -#define GLX_BACK_RIGHT_EXT 0x20E1 -#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT -#define GLX_BACK_EXT GLX_BACK_LEFT_EXT -#define GLX_AUX0_EXT 0x20E2 -#define GLX_AUX1_EXT 0x20E3 -#define GLX_AUX2_EXT 0x20E4 -#define GLX_AUX3_EXT 0x20E5 -#define GLX_AUX4_EXT 0x20E6 -#define GLX_AUX5_EXT 0x20E7 -#define GLX_AUX6_EXT 0x20E8 -#define GLX_AUX7_EXT 0x20E9 -#define GLX_AUX8_EXT 0x20EA -#define GLX_AUX9_EXT 0x20EB -#endif - -#ifdef __cplusplus -} -#endif -#else -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2007 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are 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 Materials. -** -** THE MATERIALS ARE 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 AUTHORS OR 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 -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -/* Header file version number, required by OpenGL ABI for Linux */ -/* glxext.h last updated 2007/04/21 */ -/* Current version at http://www.opengl.org/registry/ */ -#define GLX_GLXEXT_VERSION 19 - -#ifndef GLX_VERSION_1_3 -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 -#define GLX_RGBA_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 -#define GLX_CONFIG_CAVEAT 0x20 -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_DONT_CARE 0xFFFFFFFF -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 -#define GLX_VISUAL_ID 0x800B -#define GLX_SCREEN 0x800C -#define GLX_NON_CONFORMANT_CONFIG 0x800D -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 -#define GLX_PBUFFER_HEIGHT 0x8040 -#define GLX_PBUFFER_WIDTH 0x8041 -#endif - -#ifndef GLX_VERSION_1_4 -#define GLX_SAMPLE_BUFFERS 100000 -#define GLX_SAMPLES 100001 -#endif - -#ifndef GLX_ARB_get_proc_address -#endif - -#ifndef GLX_ARB_multisample -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 -#endif - -#ifndef GLX_ARB_fbconfig_float -#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 -#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 -#endif - -#ifndef GLX_SGIS_multisample -#define GLX_SAMPLE_BUFFERS_SGIS 100000 -#define GLX_SAMPLES_SGIS 100001 -#endif - -#ifndef GLX_EXT_visual_info -#define GLX_X_VISUAL_TYPE_EXT 0x22 -#define GLX_TRANSPARENT_TYPE_EXT 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 -#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 -#define GLX_NONE_EXT 0x8000 -#define GLX_TRUE_COLOR_EXT 0x8002 -#define GLX_DIRECT_COLOR_EXT 0x8003 -#define GLX_PSEUDO_COLOR_EXT 0x8004 -#define GLX_STATIC_COLOR_EXT 0x8005 -#define GLX_GRAY_SCALE_EXT 0x8006 -#define GLX_STATIC_GRAY_EXT 0x8007 -#define GLX_TRANSPARENT_RGB_EXT 0x8008 -#define GLX_TRANSPARENT_INDEX_EXT 0x8009 -#endif - -#ifndef GLX_SGI_swap_control -#endif - -#ifndef GLX_SGI_video_sync -#endif - -#ifndef GLX_SGI_make_current_read -#endif - -#ifndef GLX_SGIX_video_source -#endif - -#ifndef GLX_EXT_visual_rating -#define GLX_VISUAL_CAVEAT_EXT 0x20 -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D -/* reuse GLX_NONE_EXT */ -#endif - -#ifndef GLX_EXT_import_context -#define GLX_SHARE_CONTEXT_EXT 0x800A -#define GLX_VISUAL_ID_EXT 0x800B -#define GLX_SCREEN_EXT 0x800C -#endif - -#ifndef GLX_SGIX_fbconfig -#define GLX_WINDOW_BIT_SGIX 0x00000001 -#define GLX_PIXMAP_BIT_SGIX 0x00000002 -#define GLX_RGBA_BIT_SGIX 0x00000001 -#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002 -#define GLX_DRAWABLE_TYPE_SGIX 0x8010 -#define GLX_RENDER_TYPE_SGIX 0x8011 -#define GLX_X_RENDERABLE_SGIX 0x8012 -#define GLX_FBCONFIG_ID_SGIX 0x8013 -#define GLX_RGBA_TYPE_SGIX 0x8014 -#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015 -/* reuse GLX_SCREEN_EXT */ -#endif - -#ifndef GLX_SGIX_pbuffer -#define GLX_PBUFFER_BIT_SGIX 0x00000004 -#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000 -#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008 -#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010 -#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020 -#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040 -#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080 -#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100 -#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017 -#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018 -#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019 -#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A -#define GLX_PRESERVED_CONTENTS_SGIX 0x801B -#define GLX_LARGEST_PBUFFER_SGIX 0x801C -#define GLX_WIDTH_SGIX 0x801D -#define GLX_HEIGHT_SGIX 0x801E -#define GLX_EVENT_MASK_SGIX 0x801F -#define GLX_DAMAGED_SGIX 0x8020 -#define GLX_SAVED_SGIX 0x8021 -#define GLX_WINDOW_SGIX 0x8022 -#define GLX_PBUFFER_SGIX 0x8023 -#endif - -#ifndef GLX_SGI_cushion -#endif - -#ifndef GLX_SGIX_video_resize -#define GLX_SYNC_FRAME_SGIX 0x00000000 -#define GLX_SYNC_SWAP_SGIX 0x00000001 -#endif - -#ifndef GLX_SGIX_dmbuffer -#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024 -#endif - -#ifndef GLX_SGIX_swap_group -#endif - -#ifndef GLX_SGIX_swap_barrier -#endif - -#ifndef GLX_SGIS_blended_overlay -#define GLX_BLENDED_RGBA_SGIS 0x8025 -#endif - -#ifndef GLX_SGIS_shared_multisample -#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026 -#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027 -#endif - -#ifndef GLX_SUN_get_transparent_index -#endif - -#ifndef GLX_3DFX_multisample -#define GLX_SAMPLE_BUFFERS_3DFX 0x8050 -#define GLX_SAMPLES_3DFX 0x8051 -#endif - -#ifndef GLX_MESA_copy_sub_buffer -#endif - -#ifndef GLX_MESA_pixmap_colormap -#endif - -#ifndef GLX_MESA_release_buffers -#endif - -#ifndef GLX_MESA_set_3dfx_mode -#define GLX_3DFX_WINDOW_MODE_MESA 0x1 -#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2 -#endif - -#ifndef GLX_SGIX_visual_select_group -#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028 -#endif - -#ifndef GLX_OML_swap_method -#define GLX_SWAP_METHOD_OML 0x8060 -#define GLX_SWAP_EXCHANGE_OML 0x8061 -#define GLX_SWAP_COPY_OML 0x8062 -#define GLX_SWAP_UNDEFINED_OML 0x8063 -#endif - -#ifndef GLX_OML_sync_control -#endif - -#ifndef GLX_NV_float_buffer -#define GLX_FLOAT_COMPONENTS_NV 0x20B0 -#endif - -#ifndef GLX_SGIX_hyperpipe -#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80 -#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91 -#define GLX_BAD_HYPERPIPE_SGIX 92 -#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001 -#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002 -#define GLX_PIPE_RECT_SGIX 0x00000001 -#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002 -#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003 -#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004 -#define GLX_HYPERPIPE_ID_SGIX 0x8030 -#endif - -#ifndef GLX_MESA_agp_offset -#endif - -#ifndef GLX_EXT_fbconfig_packed_float -#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1 -#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008 -#endif - -#ifndef GLX_EXT_framebuffer_sRGB -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2 -#endif - -#ifndef GLX_EXT_texture_from_pixmap -#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 -#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 -#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 -#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 -#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 -#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 -#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 -#define GLX_Y_INVERTED_EXT 0x20D4 -#define GLX_TEXTURE_FORMAT_EXT 0x20D5 -#define GLX_TEXTURE_TARGET_EXT 0x20D6 -#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 -#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 -#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 -#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA -#define GLX_TEXTURE_1D_EXT 0x20DB -#define GLX_TEXTURE_2D_EXT 0x20DC -#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD -#define GLX_FRONT_LEFT_EXT 0x20DE -#define GLX_FRONT_RIGHT_EXT 0x20DF -#define GLX_BACK_LEFT_EXT 0x20E0 -#define GLX_BACK_RIGHT_EXT 0x20E1 -#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT -#define GLX_BACK_EXT GLX_BACK_LEFT_EXT -#define GLX_AUX0_EXT 0x20E2 -#define GLX_AUX1_EXT 0x20E3 -#define GLX_AUX2_EXT 0x20E4 -#define GLX_AUX3_EXT 0x20E5 -#define GLX_AUX4_EXT 0x20E6 -#define GLX_AUX5_EXT 0x20E7 -#define GLX_AUX6_EXT 0x20E8 -#define GLX_AUX7_EXT 0x20E9 -#define GLX_AUX8_EXT 0x20EA -#define GLX_AUX9_EXT 0x20EB -#endif - - -/*************************************************************/ - -#ifndef GLX_ARB_get_proc_address -typedef void (*__GLXextFuncPtr)(void); -#endif - -#ifndef GLX_SGIX_video_source -typedef XID GLXVideoSourceSGIX; -#endif - -#ifndef GLX_SGIX_fbconfig -typedef XID GLXFBConfigIDSGIX; -typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; -#endif - -#ifndef GLX_SGIX_pbuffer -typedef XID GLXPbufferSGIX; -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came for SendEvent request */ - Display *display; /* display the event was read from */ - GLXDrawable drawable; /* i.d. of Drawable */ - int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ - int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ - unsigned int mask; /* mask indicating which buffers are affected*/ - int x, y; - int width, height; - int count; /* if nonzero, at least this many more */ -} GLXBufferClobberEventSGIX; -#endif - -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glxext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GLX_OML_sync_control extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -#include /* Fallback option */ -#endif -#endif - -#ifndef GLX_VERSION_1_3 -#define GLX_VERSION_1_3 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern GLXFBConfig * glXGetFBConfigs (Display *, int, int *); -extern GLXFBConfig * glXChooseFBConfig (Display *, int, const int *, int *); -extern int glXGetFBConfigAttrib (Display *, GLXFBConfig, int, int *); -extern XVisualInfo * glXGetVisualFromFBConfig (Display *, GLXFBConfig); -extern GLXWindow glXCreateWindow (Display *, GLXFBConfig, Window, const int *); -extern void glXDestroyWindow (Display *, GLXWindow); -extern GLXPixmap glXCreatePixmap (Display *, GLXFBConfig, Pixmap, const int *); -extern void glXDestroyPixmap (Display *, GLXPixmap); -extern GLXPbuffer glXCreatePbuffer (Display *, GLXFBConfig, const int *); -extern void glXDestroyPbuffer (Display *, GLXPbuffer); -extern void glXQueryDrawable (Display *, GLXDrawable, int, unsigned int *); -extern GLXContext glXCreateNewContext (Display *, GLXFBConfig, int, GLXContext, Bool); -extern Bool glXMakeContextCurrent (Display *, GLXDrawable, GLXDrawable, GLXContext); -extern GLXDrawable glXGetCurrentReadDrawable (void); -extern Display * glXGetCurrentDisplay (void); -extern int glXQueryContext (Display *, GLXContext, int, int *); -extern void glXSelectEvent (Display *, GLXDrawable, unsigned long); -extern void glXGetSelectedEvent (Display *, GLXDrawable, unsigned long *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef GLXFBConfig * ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements); -typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); -typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value); -typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); -typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); -typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win); -typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); -typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); -typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list); -typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf); -typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); -typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); -typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void); -typedef Display * ( * PFNGLXGETCURRENTDISPLAYPROC) (void); -typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value); -typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask); -typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask); -#endif - -#ifndef GLX_VERSION_1_4 -#define GLX_VERSION_1_4 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern __GLXextFuncPtr glXGetProcAddress (const GLubyte *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName); -#endif - -#ifndef GLX_ARB_get_proc_address -#define GLX_ARB_get_proc_address 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName); -#endif - -#ifndef GLX_ARB_multisample -#define GLX_ARB_multisample 1 -#endif - -#ifndef GLX_ARB_fbconfig_float -#define GLX_ARB_fbconfig_float 1 -#endif - -#ifndef GLX_SGIS_multisample -#define GLX_SGIS_multisample 1 -#endif - -#ifndef GLX_EXT_visual_info -#define GLX_EXT_visual_info 1 -#endif - -#ifndef GLX_SGI_swap_control -#define GLX_SGI_swap_control 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern int glXSwapIntervalSGI (int); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); -#endif - -#ifndef GLX_SGI_video_sync -#define GLX_SGI_video_sync 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern int glXGetVideoSyncSGI (unsigned int *); -extern int glXWaitVideoSyncSGI (int, int, unsigned int *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count); -typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count); -#endif - -#ifndef GLX_SGI_make_current_read -#define GLX_SGI_make_current_read 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern Bool glXMakeCurrentReadSGI (Display *, GLXDrawable, GLXDrawable, GLXContext); -extern GLXDrawable glXGetCurrentReadDrawableSGI (void); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void); -#endif - -#ifndef GLX_SGIX_video_source -#define GLX_SGIX_video_source 1 -#ifdef _VL_H -#ifdef GLX_GLXEXT_PROTOTYPES -extern GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *, int, VLServer, VLPath, int, VLNode); -extern void glXDestroyGLXVideoSourceSGIX (Display *, GLXVideoSourceSGIX); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef GLXVideoSourceSGIX ( * PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); -typedef void ( * PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource); -#endif /* _VL_H */ -#endif - -#ifndef GLX_EXT_visual_rating -#define GLX_EXT_visual_rating 1 -#endif - -#ifndef GLX_EXT_import_context -#define GLX_EXT_import_context 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern Display * glXGetCurrentDisplayEXT (void); -extern int glXQueryContextInfoEXT (Display *, GLXContext, int, int *); -extern GLXContextID glXGetContextIDEXT (const GLXContext); -extern GLXContext glXImportContextEXT (Display *, GLXContextID); -extern void glXFreeContextEXT (Display *, GLXContext); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef Display * ( * PFNGLXGETCURRENTDISPLAYEXTPROC) (void); -typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value); -typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context); -typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID); -typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context); -#endif - -#ifndef GLX_SGIX_fbconfig -#define GLX_SGIX_fbconfig 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern int glXGetFBConfigAttribSGIX (Display *, GLXFBConfigSGIX, int, int *); -extern GLXFBConfigSGIX * glXChooseFBConfigSGIX (Display *, int, int *, int *); -extern GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *, GLXFBConfigSGIX, Pixmap); -extern GLXContext glXCreateContextWithConfigSGIX (Display *, GLXFBConfigSGIX, int, GLXContext, Bool); -extern XVisualInfo * glXGetVisualFromFBConfigSGIX (Display *, GLXFBConfigSGIX); -extern GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *, XVisualInfo *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); -typedef GLXFBConfigSGIX * ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements); -typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); -typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); -typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config); -typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis); -#endif - -#ifndef GLX_SGIX_pbuffer -#define GLX_SGIX_pbuffer 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); -extern void glXDestroyGLXPbufferSGIX (Display *, GLXPbufferSGIX); -extern int glXQueryGLXPbufferSGIX (Display *, GLXPbufferSGIX, int, unsigned int *); -extern void glXSelectEventSGIX (Display *, GLXDrawable, unsigned long); -extern void glXGetSelectedEventSGIX (Display *, GLXDrawable, unsigned long *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef GLXPbufferSGIX ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); -typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf); -typedef int ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); -typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask); -typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask); -#endif - -#ifndef GLX_SGI_cushion -#define GLX_SGI_cushion 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern void glXCushionSGI (Display *, Window, float); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef void ( * PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion); -#endif - -#ifndef GLX_SGIX_video_resize -#define GLX_SGIX_video_resize 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern int glXBindChannelToWindowSGIX (Display *, int, int, Window); -extern int glXChannelRectSGIX (Display *, int, int, int, int, int, int); -extern int glXQueryChannelRectSGIX (Display *, int, int, int *, int *, int *, int *); -extern int glXQueryChannelDeltasSGIX (Display *, int, int, int *, int *, int *, int *); -extern int glXChannelRectSyncSGIX (Display *, int, int, GLenum); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window); -typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h); -typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); -typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h); -typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype); -#endif - -#ifndef GLX_SGIX_dmbuffer -#define GLX_SGIX_dmbuffer 1 -#ifdef _DM_BUFFER_H_ -#ifdef GLX_GLXEXT_PROTOTYPES -extern Bool glXAssociateDMPbufferSGIX (Display *, GLXPbufferSGIX, DMparams *, DMbuffer); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef Bool ( * PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); -#endif /* _DM_BUFFER_H_ */ -#endif - -#ifndef GLX_SGIX_swap_group -#define GLX_SGIX_swap_group 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern void glXJoinSwapGroupSGIX (Display *, GLXDrawable, GLXDrawable); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); -#endif - -#ifndef GLX_SGIX_swap_barrier -#define GLX_SGIX_swap_barrier 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern void glXBindSwapBarrierSGIX (Display *, GLXDrawable, int); -extern Bool glXQueryMaxSwapBarriersSGIX (Display *, int, int *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier); -typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max); -#endif - -#ifndef GLX_SUN_get_transparent_index -#define GLX_SUN_get_transparent_index 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern Status glXGetTransparentIndexSUN (Display *, Window, Window, long *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); -#endif - -#ifndef GLX_MESA_copy_sub_buffer -#define GLX_MESA_copy_sub_buffer 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern void glXCopySubBufferMESA (Display *, GLXDrawable, int, int, int, int); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); -#endif - -#ifndef GLX_MESA_pixmap_colormap -#define GLX_MESA_pixmap_colormap 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern GLXPixmap glXCreateGLXPixmapMESA (Display *, XVisualInfo *, Pixmap, Colormap); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); -#endif - -#ifndef GLX_MESA_release_buffers -#define GLX_MESA_release_buffers 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern Bool glXReleaseBuffersMESA (Display *, GLXDrawable); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable); -#endif - -#ifndef GLX_MESA_set_3dfx_mode -#define GLX_MESA_set_3dfx_mode 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern Bool glXSet3DfxModeMESA (int); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef Bool ( * PFNGLXSET3DFXMODEMESAPROC) (int mode); -#endif - -#ifndef GLX_SGIX_visual_select_group -#define GLX_SGIX_visual_select_group 1 -#endif - -#ifndef GLX_OML_swap_method -#define GLX_OML_swap_method 1 -#endif - -#ifndef GLX_OML_sync_control -#define GLX_OML_sync_control 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern Bool glXGetSyncValuesOML (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *); -extern Bool glXGetMscRateOML (Display *, GLXDrawable, int32_t *, int32_t *); -extern int64_t glXSwapBuffersMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t); -extern Bool glXWaitForMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *); -extern Bool glXWaitForSbcOML (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); -typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); -typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); -typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); -typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); -#endif - -#ifndef GLX_NV_float_buffer -#define GLX_NV_float_buffer 1 -#endif - -#ifndef GLX_SGIX_hyperpipe -#define GLX_SGIX_hyperpipe 1 - -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int networkId; -} GLXHyperpipeNetworkSGIX; - -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int channel; - unsigned int - participationType; - int timeSlice; -} GLXHyperpipeConfigSGIX; - -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int srcXOrigin, srcYOrigin, srcWidth, srcHeight; - int destXOrigin, destYOrigin, destWidth, destHeight; -} GLXPipeRect; - -typedef struct { - char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]; - int XOrigin, YOrigin, maxHeight, maxWidth; -} GLXPipeRectLimits; - -#ifdef GLX_GLXEXT_PROTOTYPES -extern GLXHyperpipeNetworkSGIX * glXQueryHyperpipeNetworkSGIX (Display *, int *); -extern int glXHyperpipeConfigSGIX (Display *, int, int, GLXHyperpipeConfigSGIX *, int *); -extern GLXHyperpipeConfigSGIX * glXQueryHyperpipeConfigSGIX (Display *, int, int *); -extern int glXDestroyHyperpipeConfigSGIX (Display *, int); -extern int glXBindHyperpipeSGIX (Display *, int); -extern int glXQueryHyperpipeBestAttribSGIX (Display *, int, int, int, void *, void *); -extern int glXHyperpipeAttribSGIX (Display *, int, int, int, void *); -extern int glXQueryHyperpipeAttribSGIX (Display *, int, int, int, void *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes); -typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); -typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes); -typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId); -typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId); -typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); -typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList); -typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); -#endif - -#ifndef GLX_MESA_agp_offset -#define GLX_MESA_agp_offset 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern unsigned int glXGetAGPOffsetMESA (const void *); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer); -#endif - -#ifndef GLX_EXT_fbconfig_packed_float -#define GLX_EXT_fbconfig_packed_float 1 -#endif - -#ifndef GLX_EXT_framebuffer_sRGB -#define GLX_EXT_framebuffer_sRGB 1 -#endif - -#ifndef GLX_EXT_texture_from_pixmap -#define GLX_EXT_texture_from_pixmap 1 -#ifdef GLX_GLXEXT_PROTOTYPES -extern void glXBindTexImageEXT (Display *, GLXDrawable, int, const int *); -extern void glXReleaseTexImageEXT (Display *, GLXDrawable, int); -#endif /* GLX_GLXEXT_PROTOTYPES */ -typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); -typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif - -#endif diff --git a/target-i386/mesa_mipmap.c b/target-i386/mesa_mipmap.c deleted file mode 100644 index d951de7..0000000 --- a/target-i386/mesa_mipmap.c +++ /dev/null @@ -1,828 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 3.4 - * Copyright (C) 1995-2000 Brian Paul - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -#ifdef PC_HEADER -#include "all.h" -#else -#include -#include -#include -#include -//#include "gluP.h" -#endif - - -/* - * Compute ceiling of integer quotient of A divided by B: - */ -#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) - - - -#ifdef EPSILON -#undef EPSILON -#endif -#define EPSILON 0.001 - - -/* To work around optimizer bug in MSVC4.1 */ -#if defined(__WIN32__) && !defined(OPENSTEP) -void dummy(GLuint j, GLuint k); -void dummy(GLuint j, GLuint k) -{ -} -#else -#define dummy(J, K) -#endif - - -static GLint GLAPIENTRY -mesa_gluScaleImage(GLenum format, - GLsizei widthin, GLsizei heightin, - GLenum typein, const void *datain, - GLsizei widthout, GLsizei heightout, - GLenum typeout, void *dataout) -{ - GLint components, i, j, k; - GLfloat *tempin, *tempout; - GLfloat sx, sy; - GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels; - GLint packrowlength, packalignment, packskiprows, packskippixels; - GLint sizein, sizeout; - GLint rowstride, rowlen; - - - /* Determine number of components per pixel */ - switch (format) { - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - case GL_DEPTH_COMPONENT: - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - components = 1; - break; - case GL_LUMINANCE_ALPHA: - components = 2; - break; - case GL_RGB: - case GL_BGR: - components = 3; - break; - case GL_RGBA: - case GL_BGRA: -#ifdef GL_EXT_abgr - case GL_ABGR_EXT: -#endif - components = 4; - break; - default: - return GLU_INVALID_ENUM; - } - - /* Determine bytes per input datum */ - switch (typein) { - case GL_UNSIGNED_BYTE: - sizein = sizeof(GLubyte); - break; - case GL_BYTE: - sizein = sizeof(GLbyte); - break; - case GL_UNSIGNED_SHORT: - sizein = sizeof(GLushort); - break; - case GL_SHORT: - sizein = sizeof(GLshort); - break; - case GL_UNSIGNED_INT: - sizein = sizeof(GLuint); - break; - case GL_INT: - sizein = sizeof(GLint); - break; - case GL_FLOAT: - sizein = sizeof(GLfloat); - break; - case GL_BITMAP: - /* not implemented yet */ - default: - return GL_INVALID_ENUM; - } - - /* Determine bytes per output datum */ - switch (typeout) { - case GL_UNSIGNED_BYTE: - sizeout = sizeof(GLubyte); - break; - case GL_BYTE: - sizeout = sizeof(GLbyte); - break; - case GL_UNSIGNED_SHORT: - sizeout = sizeof(GLushort); - break; - case GL_SHORT: - sizeout = sizeof(GLshort); - break; - case GL_UNSIGNED_INT: - sizeout = sizeof(GLuint); - break; - case GL_INT: - sizeout = sizeof(GLint); - break; - case GL_FLOAT: - sizeout = sizeof(GLfloat); - break; - case GL_BITMAP: - /* not implemented yet */ - default: - return GL_INVALID_ENUM; - } - - /* Get glPixelStore state */ - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment); - glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows); - glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels); - glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength); - glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment); - glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows); - glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels); - - /* Allocate storage for intermediate images */ - tempin = (GLfloat *) malloc(widthin * heightin - * components * sizeof(GLfloat)); - if (!tempin) { - return GLU_OUT_OF_MEMORY; - } - tempout = (GLfloat *) malloc(widthout * heightout - * components * sizeof(GLfloat)); - if (!tempout) { - free(tempin); - return GLU_OUT_OF_MEMORY; - } - - - /* - * Unpack the pixel data and convert to floating point - */ - - if (unpackrowlength > 0) { - rowlen = unpackrowlength; - } - else { - rowlen = widthin; - } - if (sizein >= unpackalignment) { - rowstride = components * rowlen; - } - else { - rowstride = unpackalignment / sizein - * CEILING(components * rowlen * sizein, unpackalignment); - } - - switch (typein) { - case GL_UNSIGNED_BYTE: - k = 0; - for (i = 0; i < heightin; i++) { - GLubyte *ubptr = (GLubyte *) datain - + i * rowstride - + unpackskiprows * rowstride + unpackskippixels * components; - for (j = 0; j < widthin * components; j++) { - dummy(j, k); - tempin[k++] = (GLfloat) * ubptr++; - } - } - break; - case GL_BYTE: - k = 0; - for (i = 0; i < heightin; i++) { - GLbyte *bptr = (GLbyte *) datain - + i * rowstride - + unpackskiprows * rowstride + unpackskippixels * components; - for (j = 0; j < widthin * components; j++) { - dummy(j, k); - tempin[k++] = (GLfloat) * bptr++; - } - } - break; - case GL_UNSIGNED_SHORT: - k = 0; - for (i = 0; i < heightin; i++) { - GLushort *usptr = (GLushort *) datain - + i * rowstride - + unpackskiprows * rowstride + unpackskippixels * components; - for (j = 0; j < widthin * components; j++) { - dummy(j, k); - tempin[k++] = (GLfloat) * usptr++; - } - } - break; - case GL_SHORT: - k = 0; - for (i = 0; i < heightin; i++) { - GLshort *sptr = (GLshort *) datain - + i * rowstride - + unpackskiprows * rowstride + unpackskippixels * components; - for (j = 0; j < widthin * components; j++) { - dummy(j, k); - tempin[k++] = (GLfloat) * sptr++; - } - } - break; - case GL_UNSIGNED_INT: - k = 0; - for (i = 0; i < heightin; i++) { - GLuint *uiptr = (GLuint *) datain - + i * rowstride - + unpackskiprows * rowstride + unpackskippixels * components; - for (j = 0; j < widthin * components; j++) { - dummy(j, k); - tempin[k++] = (GLfloat) * uiptr++; - } - } - break; - case GL_INT: - k = 0; - for (i = 0; i < heightin; i++) { - GLint *iptr = (GLint *) datain - + i * rowstride - + unpackskiprows * rowstride + unpackskippixels * components; - for (j = 0; j < widthin * components; j++) { - dummy(j, k); - tempin[k++] = (GLfloat) * iptr++; - } - } - break; - case GL_FLOAT: - k = 0; - for (i = 0; i < heightin; i++) { - GLfloat *fptr = (GLfloat *) datain - + i * rowstride - + unpackskiprows * rowstride + unpackskippixels * components; - for (j = 0; j < widthin * components; j++) { - dummy(j, k); - tempin[k++] = *fptr++; - } - } - break; - default: - return GLU_INVALID_ENUM; - } - - - /* - * Scale the image! - */ - - if (widthout > 1) - sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1); - else - sx = (GLfloat) (widthin - 1); - if (heightout > 1) - sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1); - else - sy = (GLfloat) (heightin - 1); - -/*#define POINT_SAMPLE*/ -#ifdef POINT_SAMPLE - for (i = 0; i < heightout; i++) { - GLint ii = i * sy; - for (j = 0; j < widthout; j++) { - GLint jj = j * sx; - - GLfloat *src = tempin + (ii * widthin + jj) * components; - GLfloat *dst = tempout + (i * widthout + j) * components; - - for (k = 0; k < components; k++) { - *dst++ = *src++; - } - } - } -#else - if (sx < 1.0 && sy < 1.0) { - /* magnify both width and height: use weighted sample of 4 pixels */ - GLint i0, i1, j0, j1; - GLfloat alpha, beta; - GLfloat *src00, *src01, *src10, *src11; - GLfloat s1, s2; - GLfloat *dst; - - for (i = 0; i < heightout; i++) { - i0 = i * sy; - i1 = i0 + 1; - if (i1 >= heightin) - i1 = heightin - 1; -/* i1 = (i+1) * sy - EPSILON;*/ - alpha = i * sy - i0; - for (j = 0; j < widthout; j++) { - j0 = j * sx; - j1 = j0 + 1; - if (j1 >= widthin) - j1 = widthin - 1; -/* j1 = (j+1) * sx - EPSILON; */ - beta = j * sx - j0; - - /* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */ - src00 = tempin + (i0 * widthin + j0) * components; - src01 = tempin + (i0 * widthin + j1) * components; - src10 = tempin + (i1 * widthin + j0) * components; - src11 = tempin + (i1 * widthin + j1) * components; - - dst = tempout + (i * widthout + j) * components; - - for (k = 0; k < components; k++) { - s1 = *src00++ * (1.0 - beta) + *src01++ * beta; - s2 = *src10++ * (1.0 - beta) + *src11++ * beta; - *dst++ = s1 * (1.0 - alpha) + s2 * alpha; - } - } - } - } - else { - /* shrink width and/or height: use an unweighted box filter */ - GLint i0, i1; - GLint j0, j1; - GLint ii, jj; - GLfloat sum, *dst; - - for (i = 0; i < heightout; i++) { - i0 = i * sy; - i1 = i0 + 1; - if (i1 >= heightin) - i1 = heightin - 1; -/* i1 = (i+1) * sy - EPSILON; */ - for (j = 0; j < widthout; j++) { - j0 = j * sx; - j1 = j0 + 1; - if (j1 >= widthin) - j1 = widthin - 1; -/* j1 = (j+1) * sx - EPSILON; */ - - dst = tempout + (i * widthout + j) * components; - - /* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */ - for (k = 0; k < components; k++) { - sum = 0.0; - for (ii = i0; ii <= i1; ii++) { - for (jj = j0; jj <= j1; jj++) { - sum += *(tempin + (ii * widthin + jj) * components + k); - } - } - sum /= (j1 - j0 + 1) * (i1 - i0 + 1); - *dst++ = sum; - } - } - } - } -#endif - - - /* - * Return output image - */ - - if (packrowlength > 0) { - rowlen = packrowlength; - } - else { - rowlen = widthout; - } - if (sizeout >= packalignment) { - rowstride = components * rowlen; - } - else { - rowstride = packalignment / sizeout - * CEILING(components * rowlen * sizeout, packalignment); - } - - switch (typeout) { - case GL_UNSIGNED_BYTE: - k = 0; - for (i = 0; i < heightout; i++) { - GLubyte *ubptr = (GLubyte *) dataout - + i * rowstride - + packskiprows * rowstride + packskippixels * components; - for (j = 0; j < widthout * components; j++) { - dummy(j, k + i); - *ubptr++ = (GLubyte) tempout[k++]; - } - } - break; - case GL_BYTE: - k = 0; - for (i = 0; i < heightout; i++) { - GLbyte *bptr = (GLbyte *) dataout - + i * rowstride - + packskiprows * rowstride + packskippixels * components; - for (j = 0; j < widthout * components; j++) { - dummy(j, k + i); - *bptr++ = (GLbyte) tempout[k++]; - } - } - break; - case GL_UNSIGNED_SHORT: - k = 0; - for (i = 0; i < heightout; i++) { - GLushort *usptr = (GLushort *) dataout - + i * rowstride - + packskiprows * rowstride + packskippixels * components; - for (j = 0; j < widthout * components; j++) { - dummy(j, k + i); - *usptr++ = (GLushort) tempout[k++]; - } - } - break; - case GL_SHORT: - k = 0; - for (i = 0; i < heightout; i++) { - GLshort *sptr = (GLshort *) dataout - + i * rowstride - + packskiprows * rowstride + packskippixels * components; - for (j = 0; j < widthout * components; j++) { - dummy(j, k + i); - *sptr++ = (GLshort) tempout[k++]; - } - } - break; - case GL_UNSIGNED_INT: - k = 0; - for (i = 0; i < heightout; i++) { - GLuint *uiptr = (GLuint *) dataout - + i * rowstride - + packskiprows * rowstride + packskippixels * components; - for (j = 0; j < widthout * components; j++) { - dummy(j, k + i); - *uiptr++ = (GLuint) tempout[k++]; - } - } - break; - case GL_INT: - k = 0; - for (i = 0; i < heightout; i++) { - GLint *iptr = (GLint *) dataout - + i * rowstride - + packskiprows * rowstride + packskippixels * components; - for (j = 0; j < widthout * components; j++) { - dummy(j, k + i); - *iptr++ = (GLint) tempout[k++]; - } - } - break; - case GL_FLOAT: - k = 0; - for (i = 0; i < heightout; i++) { - GLfloat *fptr = (GLfloat *) dataout - + i * rowstride - + packskiprows * rowstride + packskippixels * components; - for (j = 0; j < widthout * components; j++) { - dummy(j, k + i); - *fptr++ = tempout[k++]; - } - } - break; - default: - return GLU_INVALID_ENUM; - } - - - /* free temporary image storage */ - free(tempin); - free(tempout); - - return 0; -} - - - -#if 0 -/* - * Return the largest k such that 2^k <= n. - */ -static GLint -ilog2(GLint n) -{ - GLint k; - - if (n <= 0) - return 0; - for (k = 0; n >>= 1; k++); - return k; -} -#endif - - - -/* - * Find the value nearest to n which is also a power of two. - */ -static GLint -round2(GLint n) -{ - GLint m; - - for (m = 1; m < n; m *= 2); - - /* m>=n */ - if (m - n <= n - m / 2) { - return m; - } - else { - return m / 2; - } -} - - -/* - * Given an pixel format and datatype, return the number of bytes to - * store one pixel. - */ -static GLint -bytes_per_pixel(GLenum format, GLenum type) -{ - GLint n, m; - - switch (format) { - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - case GL_DEPTH_COMPONENT: - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - n = 1; - break; - case GL_LUMINANCE_ALPHA: - n = 2; - break; - case GL_RGB: - case GL_BGR: - n = 3; - break; - case GL_RGBA: - case GL_BGRA: -#ifdef GL_EXT_abgr - case GL_ABGR_EXT: -#endif - n = 4; - break; - default: - n = 0; - } - - switch (type) { - case GL_UNSIGNED_BYTE: - m = sizeof(GLubyte); - break; - case GL_BYTE: - m = sizeof(GLbyte); - break; - case GL_BITMAP: - m = 1; - break; - case GL_UNSIGNED_SHORT: - m = sizeof(GLushort); - break; - case GL_SHORT: - m = sizeof(GLshort); - break; - case GL_UNSIGNED_INT: - m = sizeof(GLuint); - break; - case GL_INT: - m = sizeof(GLint); - break; - case GL_FLOAT: - m = sizeof(GLfloat); - break; - default: - m = 0; - } - - return n * m; -} - - - -#if 0 -/* - * WARNING: This function isn't finished and has never been tested!!!! - */ -GLint GLAPIENTRY -mesa_gluBuild1DMipmaps(GLenum target, GLint components, - GLsizei width, GLenum format, GLenum type, const void *data) -{ - GLubyte *texture; - GLint levels, max_levels; - GLint new_width, max_width; - GLint i, j, k, l; - - if (width < 1) - return GLU_INVALID_VALUE; - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_width); - max_levels = ilog2(max_width) + 1; - - /* Compute how many mipmap images to make */ - levels = ilog2(width) + 1; - if (levels > max_levels) { - levels = max_levels; - } - - new_width = 1 << (levels - 1); - - texture = (GLubyte *) malloc(new_width * components); - if (!texture) { - return GLU_OUT_OF_MEMORY; - } - - if (width != new_width) { - /* initial rescaling */ - switch (type) { - case GL_UNSIGNED_BYTE: - { - GLubyte *ub_data = (GLubyte *) data; - for (i = 0; i < new_width; i++) { - j = i * width / new_width; - for (k = 0; k < components; k++) { - texture[i * components + k] = ub_data[j * components + k]; - } - } - } - break; - default: - /* Not implemented */ - return GLU_ERROR; - } - } - - /* generate and load mipmap images */ - for (l = 0; l < levels; l++) { - glTexImage1D(GL_TEXTURE_1D, l, components, new_width, 0, - format, GL_UNSIGNED_BYTE, texture); - - /* Scale image down to 1/2 size */ - new_width = new_width / 2; - for (i = 0; i < new_width; i++) { - for (k = 0; k < components; k++) { - GLint sample1, sample2; - sample1 = (GLint) texture[i * 2 * components + k]; - sample2 = (GLint) texture[(i * 2 + 1) * components + k]; - texture[i * components + k] = (GLubyte) ((sample1 + sample2) / 2); - } - } - } - - free(texture); - - return 0; -} -#endif - - - -static GLint GLAPIENTRY -mesa_gluBuild2DMipmaps(GLenum target, GLint components, - GLsizei width, GLsizei height, GLenum format, - GLenum type, const void *data) -{ - GLint w, h, maxsize; - void *image, *newimage; - GLint neww, newh, level, bpp; - int error; - GLboolean done; - GLint retval = 0; - GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels; - GLint packrowlength, packalignment, packskiprows, packskippixels; - - if (width < 1 || height < 1) - return GLU_INVALID_VALUE; - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); - - w = round2(width); - if (w > maxsize) { - w = maxsize; - } - h = round2(height); - if (h > maxsize) { - h = maxsize; - } - - bpp = bytes_per_pixel(format, type); - if (bpp == 0) { - /* probably a bad format or type enum */ - return GLU_INVALID_ENUM; - } - - /* Get current glPixelStore values */ - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment); - glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows); - glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels); - glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength); - glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment); - glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows); - glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels); - - /* set pixel packing */ - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_SKIP_ROWS, 0); - glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - - done = GL_FALSE; - - if (w != width || h != height) { - /* must rescale image to get "top" mipmap texture image */ - image = malloc((w + 4) * h * bpp); - if (!image) { - return GLU_OUT_OF_MEMORY; - } - error = mesa_gluScaleImage(format, width, height, type, data, - w, h, type, image); - if (error) { - retval = error; - done = GL_TRUE; - } - } - else { - image = (void *) data; - } - - level = 0; - while (!done) { - if (image != data) { - /* set pixel unpacking */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - } - - glTexImage2D(target, level, components, w, h, 0, format, type, image); - - if (w == 1 && h == 1) - break; - - neww = (w < 2) ? 1 : w / 2; - newh = (h < 2) ? 1 : h / 2; - newimage = malloc((neww + 4) * newh * bpp); - if (!newimage) { - return GLU_OUT_OF_MEMORY; - } - - error = mesa_gluScaleImage(format, w, h, type, image, - neww, newh, type, newimage); - if (error) { - retval = error; - done = GL_TRUE; - } - - if (image != data) { - free(image); - } - image = newimage; - - w = neww; - h = newh; - level++; - } - - if (image != data) { - free(image); - } - - /* Restore original glPixelStore state */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength); - glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment); - glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels); - glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength); - glPixelStorei(GL_PACK_ALIGNMENT, packalignment); - glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows); - glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels); - - return retval; -} diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c deleted file mode 100644 index 9470d9e..0000000 --- a/target-i386/op_helper.c +++ /dev/null @@ -1,5675 +0,0 @@ -/* - * i386 helpers - * - * Copyright (c) 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, see . - */ - -#include "exec.h" -#include "exec-all.h" -#include "host-utils.h" -#include "ioport.h" - -//#define DEBUG_PCALL - - -#ifdef DEBUG_PCALL -# define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__) -# define LOG_PCALL_STATE(env) \ - log_cpu_state_mask(CPU_LOG_PCALL, (env), X86_DUMP_CCOP) -#else -# define LOG_PCALL(...) do { } while (0) -# define LOG_PCALL_STATE(env) do { } while (0) -#endif - - -#if 0 -#define raise_exception_err(a, b)\ -do {\ - qemu_log("raise_exception line=%d\n", __LINE__);\ - (raise_exception_err)(a, b);\ -} while (0) -#endif - -static const uint8_t parity_table[256] = { - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, -}; - -/* modulo 17 table */ -static const uint8_t rclw_table[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9,10,11,12,13,14,15, - 16, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9,10,11,12,13,14, -}; - -/* modulo 9 table */ -static const uint8_t rclb_table[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 0, 1, 2, 3, 4, 5, - 6, 7, 8, 0, 1, 2, 3, 4, -}; - -static const CPU86_LDouble f15rk[7] = -{ - 0.00000000000000000000L, - 1.00000000000000000000L, - 3.14159265358979323851L, /*pi*/ - 0.30102999566398119523L, /*lg2*/ - 0.69314718055994530943L, /*ln2*/ - 1.44269504088896340739L, /*l2e*/ - 3.32192809488736234781L, /*l2t*/ -}; - -/* broken thread support */ - -static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; - -void helper_lock(void) -{ - spin_lock(&global_cpu_lock); -} - -void helper_unlock(void) -{ - spin_unlock(&global_cpu_lock); -} - -void helper_write_eflags(target_ulong t0, uint32_t update_mask) -{ - load_eflags(t0, update_mask); -} - -target_ulong helper_read_eflags(void) -{ - uint32_t eflags; - eflags = helper_cc_compute_all(CC_OP); - eflags |= (DF & DF_MASK); - eflags |= env->eflags & ~(VM_MASK | RF_MASK); - return eflags; -} - -/* return non zero if error */ -static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, - int selector) -{ - SegmentCache *dt; - int index; - target_ulong ptr; - - if (selector & 0x4) - dt = &env->ldt; - else - dt = &env->gdt; - index = selector & ~7; - if ((index + 7) > dt->limit) - return -1; - ptr = dt->base + index; - *e1_ptr = ldl_kernel(ptr); - *e2_ptr = ldl_kernel(ptr + 4); - return 0; -} - -static inline unsigned int get_seg_limit(uint32_t e1, uint32_t e2) -{ - unsigned int limit; - limit = (e1 & 0xffff) | (e2 & 0x000f0000); - if (e2 & DESC_G_MASK) - limit = (limit << 12) | 0xfff; - return limit; -} - -static inline uint32_t get_seg_base(uint32_t e1, uint32_t e2) -{ - return ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); -} - -static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t e2) -{ - sc->base = get_seg_base(e1, e2); - sc->limit = get_seg_limit(e1, e2); - sc->flags = e2; -} - -/* init the segment cache in vm86 mode. */ -static inline void load_seg_vm(int seg, int selector) -{ - selector &= 0xffff; - cpu_x86_load_seg_cache(env, seg, selector, - (selector << 4), 0xffff, 0); -} - -static inline void get_ss_esp_from_tss(uint32_t *ss_ptr, - uint32_t *esp_ptr, int dpl) -{ - int type, index, shift; - -#if 0 - { - int i; - printf("TR: base=%p limit=%x\n", env->tr.base, env->tr.limit); - for(i=0;itr.limit;i++) { - printf("%02x ", env->tr.base[i]); - if ((i & 7) == 7) printf("\n"); - } - printf("\n"); - } -#endif - - if (!(env->tr.flags & DESC_P_MASK)) - cpu_abort(env, "invalid tss"); - type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; - if ((type & 7) != 1) - cpu_abort(env, "invalid tss type"); - shift = type >> 3; - index = (dpl * 4 + 2) << shift; - if (index + (4 << shift) - 1 > env->tr.limit) - raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc); - if (shift == 0) { - *esp_ptr = lduw_kernel(env->tr.base + index); - *ss_ptr = lduw_kernel(env->tr.base + index + 2); - } else { - *esp_ptr = ldl_kernel(env->tr.base + index); - *ss_ptr = lduw_kernel(env->tr.base + index + 4); - } -} - -/* XXX: merge with load_seg() */ -static void tss_load_seg(int seg_reg, int selector) -{ - uint32_t e1, e2; - int rpl, dpl, cpl; - - if ((selector & 0xfffc) != 0) { - if (load_segment(&e1, &e2, selector) != 0) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - if (!(e2 & DESC_S_MASK)) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (seg_reg == R_CS) { - if (!(e2 & DESC_CS_MASK)) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - /* XXX: is it correct ? */ - if (dpl != rpl) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - if ((e2 & DESC_C_MASK) && dpl > rpl) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - } else if (seg_reg == R_SS) { - /* SS must be writable data */ - if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - if (dpl != cpl || dpl != rpl) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - } else { - /* not readable code */ - if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK)) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - /* if data or non conforming code, checks the rights */ - if (((e2 >> DESC_TYPE_SHIFT) & 0xf) < 12) { - if (dpl < cpl || dpl < rpl) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - } - } - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); - cpu_x86_load_seg_cache(env, seg_reg, selector, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), - e2); - } else { - if (seg_reg == R_SS || seg_reg == R_CS) - raise_exception_err(EXCP0A_TSS, selector & 0xfffc); - } -} - -#define SWITCH_TSS_JMP 0 -#define SWITCH_TSS_IRET 1 -#define SWITCH_TSS_CALL 2 - -/* XXX: restore CPU state in registers (PowerPC case) */ -static void switch_tss(int tss_selector, - uint32_t e1, uint32_t e2, int source, - uint32_t next_eip) -{ - int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, v1, v2, i; - target_ulong tss_base; - uint32_t new_regs[8], new_segs[6]; - uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap; - uint32_t old_eflags, eflags_mask; - SegmentCache *dt; - int index; - target_ulong ptr; - - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, source); - - /* if task gate, we read the TSS segment and we load it */ - if (type == 5) { - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc); - tss_selector = e1 >> 16; - if (tss_selector & 4) - raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); - if (load_segment(&e1, &e2, tss_selector) != 0) - raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc); - if (e2 & DESC_S_MASK) - raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc); - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - if ((type & 7) != 1) - raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc); - } - - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc); - - if (type & 8) - tss_limit_max = 103; - else - tss_limit_max = 43; - tss_limit = get_seg_limit(e1, e2); - tss_base = get_seg_base(e1, e2); - if ((tss_selector & 4) != 0 || - tss_limit < tss_limit_max) - raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); - old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; - if (old_type & 8) - old_tss_limit_max = 103; - else - old_tss_limit_max = 43; - - /* read all the registers from the new TSS */ - if (type & 8) { - /* 32 bit */ - new_cr3 = ldl_kernel(tss_base + 0x1c); - new_eip = ldl_kernel(tss_base + 0x20); - new_eflags = ldl_kernel(tss_base + 0x24); - for(i = 0; i < 8; i++) - new_regs[i] = ldl_kernel(tss_base + (0x28 + i * 4)); - for(i = 0; i < 6; i++) - new_segs[i] = lduw_kernel(tss_base + (0x48 + i * 4)); - new_ldt = lduw_kernel(tss_base + 0x60); - new_trap = ldl_kernel(tss_base + 0x64); - } else { - /* 16 bit */ - new_cr3 = 0; - new_eip = lduw_kernel(tss_base + 0x0e); - new_eflags = lduw_kernel(tss_base + 0x10); - for(i = 0; i < 8; i++) - new_regs[i] = lduw_kernel(tss_base + (0x12 + i * 2)) | 0xffff0000; - for(i = 0; i < 4; i++) - new_segs[i] = lduw_kernel(tss_base + (0x22 + i * 4)); - new_ldt = lduw_kernel(tss_base + 0x2a); - new_segs[R_FS] = 0; - new_segs[R_GS] = 0; - new_trap = 0; - } - - /* NOTE: we must avoid memory exceptions during the task switch, - so we make dummy accesses before */ - /* XXX: it can still fail in some cases, so a bigger hack is - necessary to valid the TLB after having done the accesses */ - - v1 = ldub_kernel(env->tr.base); - v2 = ldub_kernel(env->tr.base + old_tss_limit_max); - stb_kernel(env->tr.base, v1); - stb_kernel(env->tr.base + old_tss_limit_max, v2); - - /* clear busy bit (it is restartable) */ - if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) { - target_ulong ptr; - uint32_t e2; - ptr = env->gdt.base + (env->tr.selector & ~7); - e2 = ldl_kernel(ptr + 4); - e2 &= ~DESC_TSS_BUSY_MASK; - stl_kernel(ptr + 4, e2); - } - old_eflags = compute_eflags(); - if (source == SWITCH_TSS_IRET) - old_eflags &= ~NT_MASK; - - /* save the current state in the old TSS */ - if (type & 8) { - /* 32 bit */ - stl_kernel(env->tr.base + 0x20, next_eip); - stl_kernel(env->tr.base + 0x24, old_eflags); - stl_kernel(env->tr.base + (0x28 + 0 * 4), EAX); - stl_kernel(env->tr.base + (0x28 + 1 * 4), ECX); - stl_kernel(env->tr.base + (0x28 + 2 * 4), EDX); - stl_kernel(env->tr.base + (0x28 + 3 * 4), EBX); - stl_kernel(env->tr.base + (0x28 + 4 * 4), ESP); - stl_kernel(env->tr.base + (0x28 + 5 * 4), EBP); - stl_kernel(env->tr.base + (0x28 + 6 * 4), ESI); - stl_kernel(env->tr.base + (0x28 + 7 * 4), EDI); - for(i = 0; i < 6; i++) - stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector); - } else { - /* 16 bit */ - stw_kernel(env->tr.base + 0x0e, next_eip); - stw_kernel(env->tr.base + 0x10, old_eflags); - stw_kernel(env->tr.base + (0x12 + 0 * 2), EAX); - stw_kernel(env->tr.base + (0x12 + 1 * 2), ECX); - stw_kernel(env->tr.base + (0x12 + 2 * 2), EDX); - stw_kernel(env->tr.base + (0x12 + 3 * 2), EBX); - stw_kernel(env->tr.base + (0x12 + 4 * 2), ESP); - stw_kernel(env->tr.base + (0x12 + 5 * 2), EBP); - stw_kernel(env->tr.base + (0x12 + 6 * 2), ESI); - stw_kernel(env->tr.base + (0x12 + 7 * 2), EDI); - for(i = 0; i < 4; i++) - stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector); - } - - /* now if an exception occurs, it will occurs in the next task - context */ - - if (source == SWITCH_TSS_CALL) { - stw_kernel(tss_base, env->tr.selector); - new_eflags |= NT_MASK; - } - - /* set busy bit */ - if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_CALL) { - target_ulong ptr; - uint32_t e2; - ptr = env->gdt.base + (tss_selector & ~7); - e2 = ldl_kernel(ptr + 4); - e2 |= DESC_TSS_BUSY_MASK; - stl_kernel(ptr + 4, e2); - } - - /* set the new CPU state */ - /* from this point, any exception which occurs can give problems */ - env->cr[0] |= CR0_TS_MASK; - env->hflags |= HF_TS_MASK; - env->tr.selector = tss_selector; - env->tr.base = tss_base; - env->tr.limit = tss_limit; - env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK; - - if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) { - cpu_x86_update_cr3(env, new_cr3); - } - - /* load all registers without an exception, then reload them with - possible exception */ - env->eip = new_eip; - eflags_mask = TF_MASK | AC_MASK | ID_MASK | - IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK; - if (!(type & 8)) - eflags_mask &= 0xffff; - load_eflags(new_eflags, eflags_mask); - /* XXX: what to do in 16 bit case ? */ - EAX = new_regs[0]; - ECX = new_regs[1]; - EDX = new_regs[2]; - EBX = new_regs[3]; - ESP = new_regs[4]; - EBP = new_regs[5]; - ESI = new_regs[6]; - EDI = new_regs[7]; - if (new_eflags & VM_MASK) { - for(i = 0; i < 6; i++) - load_seg_vm(i, new_segs[i]); - /* in vm86, CPL is always 3 */ - cpu_x86_set_cpl(env, 3); - } else { - /* CPL is set the RPL of CS */ - cpu_x86_set_cpl(env, new_segs[R_CS] & 3); - /* first just selectors as the rest may trigger exceptions */ - for(i = 0; i < 6; i++) - cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0); - } - - env->ldt.selector = new_ldt & ~4; - env->ldt.base = 0; - env->ldt.limit = 0; - env->ldt.flags = 0; - - /* load the LDT */ - if (new_ldt & 4) - raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); - - if ((new_ldt & 0xfffc) != 0) { - dt = &env->gdt; - index = new_ldt & ~7; - if ((index + 7) > dt->limit) - raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); - ptr = dt->base + index; - e1 = ldl_kernel(ptr); - e2 = ldl_kernel(ptr + 4); - if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) - raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc); - load_seg_cache_raw_dt(&env->ldt, e1, e2); - } - - /* load the segments */ - if (!(new_eflags & VM_MASK)) { - tss_load_seg(R_CS, new_segs[R_CS]); - tss_load_seg(R_SS, new_segs[R_SS]); - tss_load_seg(R_ES, new_segs[R_ES]); - tss_load_seg(R_DS, new_segs[R_DS]); - tss_load_seg(R_FS, new_segs[R_FS]); - tss_load_seg(R_GS, new_segs[R_GS]); - } - - /* check that EIP is in the CS segment limits */ - if (new_eip > env->segs[R_CS].limit) { - /* XXX: different exception if CALL ? */ - raise_exception_err(EXCP0D_GPF, 0); - } - -#ifndef CONFIG_USER_ONLY - /* reset local breakpoints */ - if (env->dr[7] & 0x55) { - for (i = 0; i < 4; i++) { - if (hw_breakpoint_enabled(env->dr[7], i) == 0x1) - hw_breakpoint_remove(env, i); - } - env->dr[7] &= ~0x55; - } -#endif -} - -/* check if Port I/O is allowed in TSS */ -static inline void check_io(int addr, int size) -{ - int io_offset, val, mask; - - /* TSS must be a valid 32 bit one */ - if (!(env->tr.flags & DESC_P_MASK) || - ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 || - env->tr.limit < 103) - goto fail; - io_offset = lduw_kernel(env->tr.base + 0x66); - io_offset += (addr >> 3); - /* Note: the check needs two bytes */ - if ((io_offset + 1) > env->tr.limit) - goto fail; - val = lduw_kernel(env->tr.base + io_offset); - val >>= (addr & 7); - mask = (1 << size) - 1; - /* all bits must be zero to allow the I/O */ - if ((val & mask) != 0) { - fail: - raise_exception_err(EXCP0D_GPF, 0); - } -} - -void helper_check_iob(uint32_t t0) -{ - check_io(t0, 1); -} - -void helper_check_iow(uint32_t t0) -{ - check_io(t0, 2); -} - -void helper_check_iol(uint32_t t0) -{ - check_io(t0, 4); -} - -void helper_outb(uint32_t port, uint32_t data) -{ - cpu_outb(port, data & 0xff); -} - -target_ulong helper_inb(uint32_t port) -{ - return cpu_inb(port); -} - -void helper_outw(uint32_t port, uint32_t data) -{ - cpu_outw(port, data & 0xffff); -} - -target_ulong helper_inw(uint32_t port) -{ - return cpu_inw(port); -} - -void helper_outl(uint32_t port, uint32_t data) -{ - cpu_outl(port, data); -} - -target_ulong helper_inl(uint32_t port) -{ - return cpu_inl(port); -} - -static inline unsigned int get_sp_mask(unsigned int e2) -{ - if (e2 & DESC_B_MASK) - return 0xffffffff; - else - return 0xffff; -} - -static int exeption_has_error_code(int intno) -{ - switch(intno) { - case 8: - case 10: - case 11: - case 12: - case 13: - case 14: - case 17: - return 1; - } - return 0; -} - -#ifdef TARGET_X86_64 -#define SET_ESP(val, sp_mask)\ -do {\ - if ((sp_mask) == 0xffff)\ - ESP = (ESP & ~0xffff) | ((val) & 0xffff);\ - else if ((sp_mask) == 0xffffffffLL)\ - ESP = (uint32_t)(val);\ - else\ - ESP = (val);\ -} while (0) -#else -#define SET_ESP(val, sp_mask) ESP = (ESP & ~(sp_mask)) | ((val) & (sp_mask)) -#endif - -/* in 64-bit machines, this can overflow. So this segment addition macro - * can be used to trim the value to 32-bit whenever needed */ -#define SEG_ADDL(ssp, sp, sp_mask) ((uint32_t)((ssp) + (sp & (sp_mask)))) - -/* XXX: add a is_user flag to have proper security support */ -#define PUSHW(ssp, sp, sp_mask, val)\ -{\ - sp -= 2;\ - stw_kernel((ssp) + (sp & (sp_mask)), (val));\ -} - -#define PUSHL(ssp, sp, sp_mask, val)\ -{\ - sp -= 4;\ - stl_kernel(SEG_ADDL(ssp, sp, sp_mask), (uint32_t)(val));\ -} - -#define POPW(ssp, sp, sp_mask, val)\ -{\ - val = lduw_kernel((ssp) + (sp & (sp_mask)));\ - sp += 2;\ -} - -#define POPL(ssp, sp, sp_mask, val)\ -{\ - val = (uint32_t)ldl_kernel(SEG_ADDL(ssp, sp, sp_mask));\ - sp += 4;\ -} - -/* protected mode interrupt */ -static void do_interrupt_protected(int intno, int is_int, int error_code, - unsigned int next_eip, int is_hw) -{ - SegmentCache *dt; - target_ulong ptr, ssp; - int type, dpl, selector, ss_dpl, cpl; - int has_error_code, new_stack, shift; - uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0; - uint32_t old_eip, sp_mask; - - has_error_code = 0; - if (!is_int && !is_hw) - has_error_code = exeption_has_error_code(intno); - if (is_int) - old_eip = next_eip; - else - old_eip = env->eip; - - dt = &env->idt; - if (intno * 8 + 7 > dt->limit) - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); - ptr = dt->base + intno * 8; - e1 = ldl_kernel(ptr); - e2 = ldl_kernel(ptr + 4); - /* check gate type */ - type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; - switch(type) { - case 5: /* task gate */ - /* must do that check here to return the correct error code */ - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2); - switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip); - if (has_error_code) { - int type; - uint32_t mask; - /* push the error code */ - type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf; - shift = type >> 3; - if (env->segs[R_SS].flags & DESC_B_MASK) - mask = 0xffffffff; - else - mask = 0xffff; - esp = (ESP - (2 << shift)) & mask; - ssp = env->segs[R_SS].base + esp; - if (shift) - stl_kernel(ssp, error_code); - else - stw_kernel(ssp, error_code); - SET_ESP(esp, mask); - } - return; - case 6: /* 286 interrupt gate */ - case 7: /* 286 trap gate */ - case 14: /* 386 interrupt gate */ - case 15: /* 386 trap gate */ - break; - default: - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); - break; - } - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - /* check privilege if software int */ - if (is_int && dpl < cpl) - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); - /* check valid bit */ - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2); - selector = e1 >> 16; - offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); - if ((selector & 0xfffc) == 0) - raise_exception_err(EXCP0D_GPF, 0); - - if (load_segment(&e1, &e2, selector) != 0) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (dpl > cpl) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); - if (!(e2 & DESC_C_MASK) && dpl < cpl) { - /* to inner privilege */ - get_ss_esp_from_tss(&ss, &esp, dpl); - if ((ss & 0xfffc) == 0) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if ((ss & 3) != dpl) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if (load_segment(&ss_e1, &ss_e2, ss) != 0) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; - if (ss_dpl != dpl) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if (!(ss_e2 & DESC_S_MASK) || - (ss_e2 & DESC_CS_MASK) || - !(ss_e2 & DESC_W_MASK)) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if (!(ss_e2 & DESC_P_MASK)) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - new_stack = 1; - sp_mask = get_sp_mask(ss_e2); - ssp = get_seg_base(ss_e1, ss_e2); - } else if ((e2 & DESC_C_MASK) || dpl == cpl) { - /* to same privilege */ - if (env->eflags & VM_MASK) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - new_stack = 0; - sp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; - esp = ESP; - dpl = cpl; - } else { - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - new_stack = 0; /* avoid warning */ - sp_mask = 0; /* avoid warning */ - ssp = 0; /* avoid warning */ - esp = 0; /* avoid warning */ - } - - shift = type >> 3; - -#if 0 - /* XXX: check that enough room is available */ - push_size = 6 + (new_stack << 2) + (has_error_code << 1); - if (env->eflags & VM_MASK) - push_size += 8; - push_size <<= shift; -#endif - if (shift == 1) { - if (new_stack) { - if (env->eflags & VM_MASK) { - PUSHL(ssp, esp, sp_mask, env->segs[R_GS].selector); - PUSHL(ssp, esp, sp_mask, env->segs[R_FS].selector); - PUSHL(ssp, esp, sp_mask, env->segs[R_DS].selector); - PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector); - } - PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector); - PUSHL(ssp, esp, sp_mask, ESP); - } - PUSHL(ssp, esp, sp_mask, compute_eflags()); - PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector); - PUSHL(ssp, esp, sp_mask, old_eip); - if (has_error_code) { - PUSHL(ssp, esp, sp_mask, error_code); - } - } else { - if (new_stack) { - if (env->eflags & VM_MASK) { - PUSHW(ssp, esp, sp_mask, env->segs[R_GS].selector); - PUSHW(ssp, esp, sp_mask, env->segs[R_FS].selector); - PUSHW(ssp, esp, sp_mask, env->segs[R_DS].selector); - PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector); - } - PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector); - PUSHW(ssp, esp, sp_mask, ESP); - } - PUSHW(ssp, esp, sp_mask, compute_eflags()); - PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector); - PUSHW(ssp, esp, sp_mask, old_eip); - if (has_error_code) { - PUSHW(ssp, esp, sp_mask, error_code); - } - } - - if (new_stack) { - if (env->eflags & VM_MASK) { - cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0); - cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0, 0); - cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0, 0); - cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0); - } - ss = (ss & ~3) | dpl; - cpu_x86_load_seg_cache(env, R_SS, ss, - ssp, get_seg_limit(ss_e1, ss_e2), ss_e2); - } - SET_ESP(esp, sp_mask); - - selector = (selector & ~3) | dpl; - cpu_x86_load_seg_cache(env, R_CS, selector, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), - e2); - cpu_x86_set_cpl(env, dpl); - env->eip = offset; - - /* interrupt gate clear IF mask */ - if ((type & 1) == 0) { - env->eflags &= ~IF_MASK; - } - env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK); -} - -#ifdef TARGET_X86_64 - -#define PUSHQ(sp, val)\ -{\ - sp -= 8;\ - stq_kernel(sp, (val));\ -} - -#define POPQ(sp, val)\ -{\ - val = ldq_kernel(sp);\ - sp += 8;\ -} - -static inline target_ulong get_rsp_from_tss(int level) -{ - int index; - -#if 0 - printf("TR: base=" TARGET_FMT_lx " limit=%x\n", - env->tr.base, env->tr.limit); -#endif - - if (!(env->tr.flags & DESC_P_MASK)) - cpu_abort(env, "invalid tss"); - index = 8 * level + 4; - if ((index + 7) > env->tr.limit) - raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc); - return ldq_kernel(env->tr.base + index); -} - -/* 64 bit interrupt */ -static void do_interrupt64(int intno, int is_int, int error_code, - target_ulong next_eip, int is_hw) -{ - SegmentCache *dt; - target_ulong ptr; - int type, dpl, selector, cpl, ist; - int has_error_code, new_stack; - uint32_t e1, e2, e3, ss; - target_ulong old_eip, esp, offset; - - has_error_code = 0; - if (!is_int && !is_hw) - has_error_code = exeption_has_error_code(intno); - if (is_int) - old_eip = next_eip; - else - old_eip = env->eip; - - dt = &env->idt; - if (intno * 16 + 15 > dt->limit) - raise_exception_err(EXCP0D_GPF, intno * 16 + 2); - ptr = dt->base + intno * 16; - e1 = ldl_kernel(ptr); - e2 = ldl_kernel(ptr + 4); - e3 = ldl_kernel(ptr + 8); - /* check gate type */ - type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; - switch(type) { - case 14: /* 386 interrupt gate */ - case 15: /* 386 trap gate */ - break; - default: - raise_exception_err(EXCP0D_GPF, intno * 16 + 2); - break; - } - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - /* check privilege if software int */ - if (is_int && dpl < cpl) - raise_exception_err(EXCP0D_GPF, intno * 16 + 2); - /* check valid bit */ - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, intno * 16 + 2); - selector = e1 >> 16; - offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff); - ist = e2 & 7; - if ((selector & 0xfffc) == 0) - raise_exception_err(EXCP0D_GPF, 0); - - if (load_segment(&e1, &e2, selector) != 0) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (dpl > cpl) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); - if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) { - /* to inner privilege */ - if (ist != 0) - esp = get_rsp_from_tss(ist + 3); - else - esp = get_rsp_from_tss(dpl); - esp &= ~0xfLL; /* align stack */ - ss = 0; - new_stack = 1; - } else if ((e2 & DESC_C_MASK) || dpl == cpl) { - /* to same privilege */ - if (env->eflags & VM_MASK) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - new_stack = 0; - if (ist != 0) - esp = get_rsp_from_tss(ist + 3); - else - esp = ESP; - esp &= ~0xfLL; /* align stack */ - dpl = cpl; - } else { - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - new_stack = 0; /* avoid warning */ - esp = 0; /* avoid warning */ - } - - PUSHQ(esp, env->segs[R_SS].selector); - PUSHQ(esp, ESP); - PUSHQ(esp, compute_eflags()); - PUSHQ(esp, env->segs[R_CS].selector); - PUSHQ(esp, old_eip); - if (has_error_code) { - PUSHQ(esp, error_code); - } - - if (new_stack) { - ss = 0 | dpl; - cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0); - } - ESP = esp; - - selector = (selector & ~3) | dpl; - cpu_x86_load_seg_cache(env, R_CS, selector, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), - e2); - cpu_x86_set_cpl(env, dpl); - env->eip = offset; - - /* interrupt gate clear IF mask */ - if ((type & 1) == 0) { - env->eflags &= ~IF_MASK; - } - env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK); -} -#endif - -#ifdef TARGET_X86_64 -#if defined(CONFIG_USER_ONLY) -void helper_syscall(int next_eip_addend) -{ - env->exception_index = EXCP_SYSCALL; - env->exception_next_eip = env->eip + next_eip_addend; - cpu_loop_exit(); -} -#else -void helper_syscall(int next_eip_addend) -{ - int selector; - - if (!(env->efer & MSR_EFER_SCE)) { - raise_exception_err(EXCP06_ILLOP, 0); - } - selector = (env->star >> 32) & 0xffff; - if (env->hflags & HF_LMA_MASK) { - int code64; - - ECX = env->eip + next_eip_addend; - env->regs[11] = compute_eflags(); - - code64 = env->hflags & HF_CS64_MASK; - - cpu_x86_set_cpl(env, 0); - cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); - cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_W_MASK | DESC_A_MASK); - env->eflags &= ~env->fmask; - load_eflags(env->eflags, 0); - if (code64) - env->eip = env->lstar; - else - env->eip = env->cstar; - } else { - ECX = (uint32_t)(env->eip + next_eip_addend); - - cpu_x86_set_cpl(env, 0); - cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_W_MASK | DESC_A_MASK); - env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK); - env->eip = (uint32_t)env->star; - } -} -#endif -#endif - -#ifdef TARGET_X86_64 -void helper_sysret(int dflag) -{ - int cpl, selector; - - if (!(env->efer & MSR_EFER_SCE)) { - raise_exception_err(EXCP06_ILLOP, 0); - } - cpl = env->hflags & HF_CPL_MASK; - if (!(env->cr[0] & CR0_PE_MASK) || cpl != 0) { - raise_exception_err(EXCP0D_GPF, 0); - } - selector = (env->star >> 48) & 0xffff; - if (env->hflags & HF_LMA_MASK) { - if (dflag == 2) { - cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3, - 0, 0xffffffff, - DESC_G_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | - DESC_L_MASK); - env->eip = ECX; - } else { - cpu_x86_load_seg_cache(env, R_CS, selector | 3, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - env->eip = (uint32_t)ECX; - } - cpu_x86_load_seg_cache(env, R_SS, selector + 8, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_W_MASK | DESC_A_MASK); - load_eflags((uint32_t)(env->regs[11]), TF_MASK | AC_MASK | ID_MASK | - IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK); - cpu_x86_set_cpl(env, 3); - } else { - cpu_x86_load_seg_cache(env, R_CS, selector | 3, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - env->eip = (uint32_t)ECX; - cpu_x86_load_seg_cache(env, R_SS, selector + 8, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_W_MASK | DESC_A_MASK); - env->eflags |= IF_MASK; - cpu_x86_set_cpl(env, 3); - } -} -#endif - -/* real mode interrupt */ -static void do_interrupt_real(int intno, int is_int, int error_code, - unsigned int next_eip) -{ - SegmentCache *dt; - target_ulong ptr, ssp; - int selector; - uint32_t offset, esp; - uint32_t old_cs, old_eip; - - /* real mode (simpler !) */ - dt = &env->idt; - if (intno * 4 + 3 > dt->limit) - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); - ptr = dt->base + intno * 4; - offset = lduw_kernel(ptr); - selector = lduw_kernel(ptr + 2); - esp = ESP; - ssp = env->segs[R_SS].base; - if (is_int) - old_eip = next_eip; - else - old_eip = env->eip; - old_cs = env->segs[R_CS].selector; - /* XXX: use SS segment size ? */ - PUSHW(ssp, esp, 0xffff, compute_eflags()); - PUSHW(ssp, esp, 0xffff, old_cs); - PUSHW(ssp, esp, 0xffff, old_eip); - - /* update processor state */ - ESP = (ESP & ~0xffff) | (esp & 0xffff); - env->eip = offset; - env->segs[R_CS].selector = selector; - env->segs[R_CS].base = (selector << 4); - env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK); -} - -/* fake user mode interrupt */ -void do_interrupt_user(int intno, int is_int, int error_code, - target_ulong next_eip) -{ - SegmentCache *dt; - target_ulong ptr; - int dpl, cpl, shift; - uint32_t e2; - - dt = &env->idt; - if (env->hflags & HF_LMA_MASK) { - shift = 4; - } else { - shift = 3; - } - ptr = dt->base + (intno << shift); - e2 = ldl_kernel(ptr + 4); - - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - /* check privilege if software int */ - if (is_int && dpl < cpl) - raise_exception_err(EXCP0D_GPF, (intno << shift) + 2); - - /* Since we emulate only user space, we cannot do more than - exiting the emulation with the suitable exception and error - code */ - if (is_int) - EIP = next_eip; -} - -#if !defined(CONFIG_USER_ONLY) -static void handle_even_inj(int intno, int is_int, int error_code, - int is_hw, int rm) -{ - uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); - if (!(event_inj & SVM_EVTINJ_VALID)) { - int type; - if (is_int) - type = SVM_EVTINJ_TYPE_SOFT; - else - type = SVM_EVTINJ_TYPE_EXEPT; - event_inj = intno | type | SVM_EVTINJ_VALID; - if (!rm && exeption_has_error_code(intno)) { - event_inj |= SVM_EVTINJ_VALID_ERR; - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err), error_code); - } - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj); - } -} -#endif - -/* - * Begin execution of an interruption. is_int is TRUE if coming from - * the int instruction. next_eip is the EIP value AFTER the interrupt - * instruction. It is only relevant if is_int is TRUE. - */ -void do_interrupt(int intno, int is_int, int error_code, - target_ulong next_eip, int is_hw) -{ - if (qemu_loglevel_mask(CPU_LOG_INT)) { - if ((env->cr[0] & CR0_PE_MASK)) { - static int count; - qemu_log("%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:" TARGET_FMT_lx " pc=" TARGET_FMT_lx " SP=%04x:" TARGET_FMT_lx, - count, intno, error_code, is_int, - env->hflags & HF_CPL_MASK, - env->segs[R_CS].selector, EIP, - (int)env->segs[R_CS].base + EIP, - env->segs[R_SS].selector, ESP); - if (intno == 0x0e) { - qemu_log(" CR2=" TARGET_FMT_lx, env->cr[2]); - } else { - qemu_log(" EAX=" TARGET_FMT_lx, EAX); - } - qemu_log("\n"); - log_cpu_state(env, X86_DUMP_CCOP); -#if 0 - { - int i; - target_ulong ptr; - qemu_log(" code="); - ptr = env->segs[R_CS].base + env->eip; - for(i = 0; i < 16; i++) { - qemu_log(" %02x", ldub(ptr + i)); - } - qemu_log("\n"); - } -#endif - count++; - } - } - if (env->cr[0] & CR0_PE_MASK) { -#if !defined(CONFIG_USER_ONLY) - if (env->hflags & HF_SVMI_MASK) - handle_even_inj(intno, is_int, error_code, is_hw, 0); -#endif -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { - do_interrupt64(intno, is_int, error_code, next_eip, is_hw); - } else -#endif - { - do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw); - } - } else { -#if !defined(CONFIG_USER_ONLY) - if (env->hflags & HF_SVMI_MASK) - handle_even_inj(intno, is_int, error_code, is_hw, 1); -#endif - do_interrupt_real(intno, is_int, error_code, next_eip); - } - -#if !defined(CONFIG_USER_ONLY) - if (env->hflags & HF_SVMI_MASK) { - uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID); - } -#endif -} - -/* This should come from sysemu.h - if we could include it here... */ -void qemu_system_reset_request(void); - -/* - * Check nested exceptions and change to double or triple fault if - * needed. It should only be called, if this is not an interrupt. - * Returns the new exception number. - */ -static int check_exception(int intno, int *error_code) -{ - int first_contributory = env->old_exception == 0 || - (env->old_exception >= 10 && - env->old_exception <= 13); - int second_contributory = intno == 0 || - (intno >= 10 && intno <= 13); - - qemu_log_mask(CPU_LOG_INT, "check_exception old: 0x%x new 0x%x\n", - env->old_exception, intno); - -#if !defined(CONFIG_USER_ONLY) - if (env->old_exception == EXCP08_DBLE) { - if (env->hflags & HF_SVMI_MASK) - helper_vmexit(SVM_EXIT_SHUTDOWN, 0); /* does not return */ - - qemu_log_mask(CPU_LOG_RESET, "Triple fault\n"); - - qemu_system_reset_request(); - return EXCP_HLT; - } -#endif - - if ((first_contributory && second_contributory) - || (env->old_exception == EXCP0E_PAGE && - (second_contributory || (intno == EXCP0E_PAGE)))) { - intno = EXCP08_DBLE; - *error_code = 0; - } - - if (second_contributory || (intno == EXCP0E_PAGE) || - (intno == EXCP08_DBLE)) - env->old_exception = intno; - - return intno; -} - -/* - * Signal an interruption. It is executed in the main CPU loop. - * is_int is TRUE if coming from the int instruction. next_eip is the - * EIP value AFTER the interrupt instruction. It is only relevant if - * is_int is TRUE. - */ -static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code, - int next_eip_addend) -{ - if (!is_int) { - helper_svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno, error_code); - intno = check_exception(intno, &error_code); - } else { - helper_svm_check_intercept_param(SVM_EXIT_SWINT, 0); - } - - env->exception_index = intno; - env->error_code = error_code; - env->exception_is_int = is_int; - env->exception_next_eip = env->eip + next_eip_addend; - cpu_loop_exit(); -} - -/* shortcuts to generate exceptions */ - -void raise_exception_err(int exception_index, int error_code) -{ - raise_interrupt(exception_index, 0, error_code, 0); -} - -void raise_exception(int exception_index) -{ - raise_interrupt(exception_index, 0, 0, 0); -} - -void raise_exception_env(int exception_index, CPUState *nenv) -{ - env = nenv; - raise_exception(exception_index); -} -/* SMM support */ - -#if defined(CONFIG_USER_ONLY) - -void do_smm_enter(void) -{ -} - -void helper_rsm(void) -{ -} - -#else - -#ifdef TARGET_X86_64 -#define SMM_REVISION_ID 0x00020064 -#else -#define SMM_REVISION_ID 0x00020000 -#endif - -void do_smm_enter(void) -{ - target_ulong sm_state; - SegmentCache *dt; - int i, offset; - - qemu_log_mask(CPU_LOG_INT, "SMM: enter\n"); - log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP); - - env->hflags |= HF_SMM_MASK; - cpu_smm_update(env); - - sm_state = env->smbase + 0x8000; - -#ifdef TARGET_X86_64 - for(i = 0; i < 6; i++) { - dt = &env->segs[i]; - offset = 0x7e00 + i * 16; - stw_phys(sm_state + offset, dt->selector); - stw_phys(sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff); - stl_phys(sm_state + offset + 4, dt->limit); - stq_phys(sm_state + offset + 8, dt->base); - } - - stq_phys(sm_state + 0x7e68, env->gdt.base); - stl_phys(sm_state + 0x7e64, env->gdt.limit); - - stw_phys(sm_state + 0x7e70, env->ldt.selector); - stq_phys(sm_state + 0x7e78, env->ldt.base); - stl_phys(sm_state + 0x7e74, env->ldt.limit); - stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff); - - stq_phys(sm_state + 0x7e88, env->idt.base); - stl_phys(sm_state + 0x7e84, env->idt.limit); - - stw_phys(sm_state + 0x7e90, env->tr.selector); - stq_phys(sm_state + 0x7e98, env->tr.base); - stl_phys(sm_state + 0x7e94, env->tr.limit); - stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff); - - stq_phys(sm_state + 0x7ed0, env->efer); - - stq_phys(sm_state + 0x7ff8, EAX); - stq_phys(sm_state + 0x7ff0, ECX); - stq_phys(sm_state + 0x7fe8, EDX); - stq_phys(sm_state + 0x7fe0, EBX); - stq_phys(sm_state + 0x7fd8, ESP); - stq_phys(sm_state + 0x7fd0, EBP); - stq_phys(sm_state + 0x7fc8, ESI); - stq_phys(sm_state + 0x7fc0, EDI); - for(i = 8; i < 16; i++) - stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]); - stq_phys(sm_state + 0x7f78, env->eip); - stl_phys(sm_state + 0x7f70, compute_eflags()); - stl_phys(sm_state + 0x7f68, env->dr[6]); - stl_phys(sm_state + 0x7f60, env->dr[7]); - - stl_phys(sm_state + 0x7f48, env->cr[4]); - stl_phys(sm_state + 0x7f50, env->cr[3]); - stl_phys(sm_state + 0x7f58, env->cr[0]); - - stl_phys(sm_state + 0x7efc, SMM_REVISION_ID); - stl_phys(sm_state + 0x7f00, env->smbase); -#else - stl_phys(sm_state + 0x7ffc, env->cr[0]); - stl_phys(sm_state + 0x7ff8, env->cr[3]); - stl_phys(sm_state + 0x7ff4, compute_eflags()); - stl_phys(sm_state + 0x7ff0, env->eip); - stl_phys(sm_state + 0x7fec, EDI); - stl_phys(sm_state + 0x7fe8, ESI); - stl_phys(sm_state + 0x7fe4, EBP); - stl_phys(sm_state + 0x7fe0, ESP); - stl_phys(sm_state + 0x7fdc, EBX); - stl_phys(sm_state + 0x7fd8, EDX); - stl_phys(sm_state + 0x7fd4, ECX); - stl_phys(sm_state + 0x7fd0, EAX); - stl_phys(sm_state + 0x7fcc, env->dr[6]); - stl_phys(sm_state + 0x7fc8, env->dr[7]); - - stl_phys(sm_state + 0x7fc4, env->tr.selector); - stl_phys(sm_state + 0x7f64, env->tr.base); - stl_phys(sm_state + 0x7f60, env->tr.limit); - stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff); - - stl_phys(sm_state + 0x7fc0, env->ldt.selector); - stl_phys(sm_state + 0x7f80, env->ldt.base); - stl_phys(sm_state + 0x7f7c, env->ldt.limit); - stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff); - - stl_phys(sm_state + 0x7f74, env->gdt.base); - stl_phys(sm_state + 0x7f70, env->gdt.limit); - - stl_phys(sm_state + 0x7f58, env->idt.base); - stl_phys(sm_state + 0x7f54, env->idt.limit); - - for(i = 0; i < 6; i++) { - dt = &env->segs[i]; - if (i < 3) - offset = 0x7f84 + i * 12; - else - offset = 0x7f2c + (i - 3) * 12; - stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector); - stl_phys(sm_state + offset + 8, dt->base); - stl_phys(sm_state + offset + 4, dt->limit); - stl_phys(sm_state + offset, (dt->flags >> 8) & 0xf0ff); - } - stl_phys(sm_state + 0x7f14, env->cr[4]); - - stl_phys(sm_state + 0x7efc, SMM_REVISION_ID); - stl_phys(sm_state + 0x7ef8, env->smbase); -#endif - /* init SMM cpu state */ - -#ifdef TARGET_X86_64 - cpu_load_efer(env, 0); -#endif - load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); - env->eip = 0x00008000; - cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase, - 0xffffffff, 0); - cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0); - cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0); - cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0); - cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0); - cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0); - - cpu_x86_update_cr0(env, - env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK)); - cpu_x86_update_cr4(env, 0); - env->dr[7] = 0x00000400; - CC_OP = CC_OP_EFLAGS; -} - -void helper_rsm(void) -{ - target_ulong sm_state; - int i, offset; - uint32_t val; - - sm_state = env->smbase + 0x8000; -#ifdef TARGET_X86_64 - cpu_load_efer(env, ldq_phys(sm_state + 0x7ed0)); - - for(i = 0; i < 6; i++) { - offset = 0x7e00 + i * 16; - cpu_x86_load_seg_cache(env, i, - lduw_phys(sm_state + offset), - ldq_phys(sm_state + offset + 8), - ldl_phys(sm_state + offset + 4), - (lduw_phys(sm_state + offset + 2) & 0xf0ff) << 8); - } - - env->gdt.base = ldq_phys(sm_state + 0x7e68); - env->gdt.limit = ldl_phys(sm_state + 0x7e64); - - env->ldt.selector = lduw_phys(sm_state + 0x7e70); - env->ldt.base = ldq_phys(sm_state + 0x7e78); - env->ldt.limit = ldl_phys(sm_state + 0x7e74); - env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8; - - env->idt.base = ldq_phys(sm_state + 0x7e88); - env->idt.limit = ldl_phys(sm_state + 0x7e84); - - env->tr.selector = lduw_phys(sm_state + 0x7e90); - env->tr.base = ldq_phys(sm_state + 0x7e98); - env->tr.limit = ldl_phys(sm_state + 0x7e94); - env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8; - - EAX = ldq_phys(sm_state + 0x7ff8); - ECX = ldq_phys(sm_state + 0x7ff0); - EDX = ldq_phys(sm_state + 0x7fe8); - EBX = ldq_phys(sm_state + 0x7fe0); - ESP = ldq_phys(sm_state + 0x7fd8); - EBP = ldq_phys(sm_state + 0x7fd0); - ESI = ldq_phys(sm_state + 0x7fc8); - EDI = ldq_phys(sm_state + 0x7fc0); - for(i = 8; i < 16; i++) - env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8); - env->eip = ldq_phys(sm_state + 0x7f78); - load_eflags(ldl_phys(sm_state + 0x7f70), - ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); - env->dr[6] = ldl_phys(sm_state + 0x7f68); - env->dr[7] = ldl_phys(sm_state + 0x7f60); - - cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f48)); - cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7f50)); - cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7f58)); - - val = ldl_phys(sm_state + 0x7efc); /* revision ID */ - if (val & 0x20000) { - env->smbase = ldl_phys(sm_state + 0x7f00) & ~0x7fff; - } -#else - cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc)); - cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8)); - load_eflags(ldl_phys(sm_state + 0x7ff4), - ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); - env->eip = ldl_phys(sm_state + 0x7ff0); - EDI = ldl_phys(sm_state + 0x7fec); - ESI = ldl_phys(sm_state + 0x7fe8); - EBP = ldl_phys(sm_state + 0x7fe4); - ESP = ldl_phys(sm_state + 0x7fe0); - EBX = ldl_phys(sm_state + 0x7fdc); - EDX = ldl_phys(sm_state + 0x7fd8); - ECX = ldl_phys(sm_state + 0x7fd4); - EAX = ldl_phys(sm_state + 0x7fd0); - env->dr[6] = ldl_phys(sm_state + 0x7fcc); - env->dr[7] = ldl_phys(sm_state + 0x7fc8); - - env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff; - env->tr.base = ldl_phys(sm_state + 0x7f64); - env->tr.limit = ldl_phys(sm_state + 0x7f60); - env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8; - - env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff; - env->ldt.base = ldl_phys(sm_state + 0x7f80); - env->ldt.limit = ldl_phys(sm_state + 0x7f7c); - env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8; - - env->gdt.base = ldl_phys(sm_state + 0x7f74); - env->gdt.limit = ldl_phys(sm_state + 0x7f70); - - env->idt.base = ldl_phys(sm_state + 0x7f58); - env->idt.limit = ldl_phys(sm_state + 0x7f54); - - for(i = 0; i < 6; i++) { - if (i < 3) - offset = 0x7f84 + i * 12; - else - offset = 0x7f2c + (i - 3) * 12; - cpu_x86_load_seg_cache(env, i, - ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff, - ldl_phys(sm_state + offset + 8), - ldl_phys(sm_state + offset + 4), - (ldl_phys(sm_state + offset) & 0xf0ff) << 8); - } - cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f14)); - - val = ldl_phys(sm_state + 0x7efc); /* revision ID */ - if (val & 0x20000) { - env->smbase = ldl_phys(sm_state + 0x7ef8) & ~0x7fff; - } -#endif - CC_OP = CC_OP_EFLAGS; - env->hflags &= ~HF_SMM_MASK; - cpu_smm_update(env); - - qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n"); - log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP); -} - -#endif /* !CONFIG_USER_ONLY */ - - -/* division, flags are undefined */ - -void helper_divb_AL(target_ulong t0) -{ - unsigned int num, den, q, r; - - num = (EAX & 0xffff); - den = (t0 & 0xff); - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q > 0xff) - raise_exception(EXCP00_DIVZ); - q &= 0xff; - r = (num % den) & 0xff; - EAX = (EAX & ~0xffff) | (r << 8) | q; -} - -void helper_idivb_AL(target_ulong t0) -{ - int num, den, q, r; - - num = (int16_t)EAX; - den = (int8_t)t0; - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q != (int8_t)q) - raise_exception(EXCP00_DIVZ); - q &= 0xff; - r = (num % den) & 0xff; - EAX = (EAX & ~0xffff) | (r << 8) | q; -} - -void helper_divw_AX(target_ulong t0) -{ - unsigned int num, den, q, r; - - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); - den = (t0 & 0xffff); - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q > 0xffff) - raise_exception(EXCP00_DIVZ); - q &= 0xffff; - r = (num % den) & 0xffff; - EAX = (EAX & ~0xffff) | q; - EDX = (EDX & ~0xffff) | r; -} - -void helper_idivw_AX(target_ulong t0) -{ - int num, den, q, r; - - num = (EAX & 0xffff) | ((EDX & 0xffff) << 16); - den = (int16_t)t0; - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - if (q != (int16_t)q) - raise_exception(EXCP00_DIVZ); - q &= 0xffff; - r = (num % den) & 0xffff; - EAX = (EAX & ~0xffff) | q; - EDX = (EDX & ~0xffff) | r; -} - -void helper_divl_EAX(target_ulong t0) -{ - unsigned int den, r; - uint64_t num, q; - - num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); - den = t0; - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - r = (num % den); - if (q > 0xffffffff) - raise_exception(EXCP00_DIVZ); - EAX = (uint32_t)q; - EDX = (uint32_t)r; -} - -void helper_idivl_EAX(target_ulong t0) -{ - int den, r; - int64_t num, q; - - num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); - den = t0; - if (den == 0) { - raise_exception(EXCP00_DIVZ); - } - q = (num / den); - r = (num % den); - if (q != (int32_t)q) - raise_exception(EXCP00_DIVZ); - EAX = (uint32_t)q; - EDX = (uint32_t)r; -} - -/* bcd */ - -/* XXX: exception */ -void helper_aam(int base) -{ - int al, ah; - al = EAX & 0xff; - ah = al / base; - al = al % base; - EAX = (EAX & ~0xffff) | al | (ah << 8); - CC_DST = al; -} - -void helper_aad(int base) -{ - int al, ah; - al = EAX & 0xff; - ah = (EAX >> 8) & 0xff; - al = ((ah * base) + al) & 0xff; - EAX = (EAX & ~0xffff) | al; - CC_DST = al; -} - -void helper_aaa(void) -{ - int icarry; - int al, ah, af; - int eflags; - - eflags = helper_cc_compute_all(CC_OP); - af = eflags & CC_A; - al = EAX & 0xff; - ah = (EAX >> 8) & 0xff; - - icarry = (al > 0xf9); - if (((al & 0x0f) > 9 ) || af) { - al = (al + 6) & 0x0f; - ah = (ah + 1 + icarry) & 0xff; - eflags |= CC_C | CC_A; - } else { - eflags &= ~(CC_C | CC_A); - al &= 0x0f; - } - EAX = (EAX & ~0xffff) | al | (ah << 8); - CC_SRC = eflags; -} - -void helper_aas(void) -{ - int icarry; - int al, ah, af; - int eflags; - - eflags = helper_cc_compute_all(CC_OP); - af = eflags & CC_A; - al = EAX & 0xff; - ah = (EAX >> 8) & 0xff; - - icarry = (al < 6); - if (((al & 0x0f) > 9 ) || af) { - al = (al - 6) & 0x0f; - ah = (ah - 1 - icarry) & 0xff; - eflags |= CC_C | CC_A; - } else { - eflags &= ~(CC_C | CC_A); - al &= 0x0f; - } - EAX = (EAX & ~0xffff) | al | (ah << 8); - CC_SRC = eflags; -} - -void helper_daa(void) -{ - int al, af, cf; - int eflags; - - eflags = helper_cc_compute_all(CC_OP); - cf = eflags & CC_C; - af = eflags & CC_A; - al = EAX & 0xff; - - eflags = 0; - if (((al & 0x0f) > 9 ) || af) { - al = (al + 6) & 0xff; - eflags |= CC_A; - } - if ((al > 0x9f) || cf) { - al = (al + 0x60) & 0xff; - eflags |= CC_C; - } - EAX = (EAX & ~0xff) | al; - /* well, speed is not an issue here, so we compute the flags by hand */ - eflags |= (al == 0) << 6; /* zf */ - eflags |= parity_table[al]; /* pf */ - eflags |= (al & 0x80); /* sf */ - CC_SRC = eflags; -} - -void helper_das(void) -{ - int al, al1, af, cf; - int eflags; - - eflags = helper_cc_compute_all(CC_OP); - cf = eflags & CC_C; - af = eflags & CC_A; - al = EAX & 0xff; - - eflags = 0; - al1 = al; - if (((al & 0x0f) > 9 ) || af) { - eflags |= CC_A; - if (al < 6 || cf) - eflags |= CC_C; - al = (al - 6) & 0xff; - } - if ((al1 > 0x99) || cf) { - al = (al - 0x60) & 0xff; - eflags |= CC_C; - } - EAX = (EAX & ~0xff) | al; - /* well, speed is not an issue here, so we compute the flags by hand */ - eflags |= (al == 0) << 6; /* zf */ - eflags |= parity_table[al]; /* pf */ - eflags |= (al & 0x80); /* sf */ - CC_SRC = eflags; -} - -void helper_into(int next_eip_addend) -{ - int eflags; - eflags = helper_cc_compute_all(CC_OP); - if (eflags & CC_O) { - raise_interrupt(EXCP04_INTO, 1, 0, next_eip_addend); - } -} - -void helper_cmpxchg8b(target_ulong a0) -{ - uint64_t d; - int eflags; - - eflags = helper_cc_compute_all(CC_OP); - d = ldq(a0); - if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) { - stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX); - eflags |= CC_Z; - } else { - /* always do the store */ - stq(a0, d); - EDX = (uint32_t)(d >> 32); - EAX = (uint32_t)d; - eflags &= ~CC_Z; - } - CC_SRC = eflags; -} - -#ifdef TARGET_X86_64 -void helper_cmpxchg16b(target_ulong a0) -{ - uint64_t d0, d1; - int eflags; - - if ((a0 & 0xf) != 0) - raise_exception(EXCP0D_GPF); - eflags = helper_cc_compute_all(CC_OP); - d0 = ldq(a0); - d1 = ldq(a0 + 8); - if (d0 == EAX && d1 == EDX) { - stq(a0, EBX); - stq(a0 + 8, ECX); - eflags |= CC_Z; - } else { - /* always do the store */ - stq(a0, d0); - stq(a0 + 8, d1); - EDX = d1; - EAX = d0; - eflags &= ~CC_Z; - } - CC_SRC = eflags; -} -#endif - -void helper_single_step(void) -{ -#ifndef CONFIG_USER_ONLY - check_hw_breakpoints(env, 1); - env->dr[6] |= DR6_BS; -#endif - raise_exception(EXCP01_DB); -} - -void helper_cpuid(void) -{ - uint32_t eax, ebx, ecx, edx; - - helper_svm_check_intercept_param(SVM_EXIT_CPUID, 0); - - cpu_x86_cpuid(env, (uint32_t)EAX, (uint32_t)ECX, &eax, &ebx, &ecx, &edx); - EAX = eax; - EBX = ebx; - ECX = ecx; - EDX = edx; -} - -void helper_enter_level(int level, int data32, target_ulong t1) -{ - target_ulong ssp; - uint32_t esp_mask, esp, ebp; - - esp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; - ebp = EBP; - esp = ESP; - if (data32) { - /* 32 bit */ - esp -= 4; - while (--level) { - esp -= 4; - ebp -= 4; - stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask))); - } - esp -= 4; - stl(ssp + (esp & esp_mask), t1); - } else { - /* 16 bit */ - esp -= 2; - while (--level) { - esp -= 2; - ebp -= 2; - stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask))); - } - esp -= 2; - stw(ssp + (esp & esp_mask), t1); - } -} - -#ifdef TARGET_X86_64 -void helper_enter64_level(int level, int data64, target_ulong t1) -{ - target_ulong esp, ebp; - ebp = EBP; - esp = ESP; - - if (data64) { - /* 64 bit */ - esp -= 8; - while (--level) { - esp -= 8; - ebp -= 8; - stq(esp, ldq(ebp)); - } - esp -= 8; - stq(esp, t1); - } else { - /* 16 bit */ - esp -= 2; - while (--level) { - esp -= 2; - ebp -= 2; - stw(esp, lduw(ebp)); - } - esp -= 2; - stw(esp, t1); - } -} -#endif - -void helper_lldt(int selector) -{ - SegmentCache *dt; - uint32_t e1, e2; - int index, entry_limit; - target_ulong ptr; - - selector &= 0xffff; - if ((selector & 0xfffc) == 0) { - /* XXX: NULL selector case: invalid LDT */ - env->ldt.base = 0; - env->ldt.limit = 0; - } else { - if (selector & 0x4) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - dt = &env->gdt; - index = selector & ~7; -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) - entry_limit = 15; - else -#endif - entry_limit = 7; - if ((index + entry_limit) > dt->limit) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - ptr = dt->base + index; - e1 = ldl_kernel(ptr); - e2 = ldl_kernel(ptr + 4); - if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { - uint32_t e3; - e3 = ldl_kernel(ptr + 8); - load_seg_cache_raw_dt(&env->ldt, e1, e2); - env->ldt.base |= (target_ulong)e3 << 32; - } else -#endif - { - load_seg_cache_raw_dt(&env->ldt, e1, e2); - } - } - env->ldt.selector = selector; -} - -void helper_ltr(int selector) -{ - SegmentCache *dt; - uint32_t e1, e2; - int index, type, entry_limit; - target_ulong ptr; - - selector &= 0xffff; - if ((selector & 0xfffc) == 0) { - /* NULL selector case: invalid TR */ - env->tr.base = 0; - env->tr.limit = 0; - env->tr.flags = 0; - } else { - if (selector & 0x4) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - dt = &env->gdt; - index = selector & ~7; -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) - entry_limit = 15; - else -#endif - entry_limit = 7; - if ((index + entry_limit) > dt->limit) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - ptr = dt->base + index; - e1 = ldl_kernel(ptr); - e2 = ldl_kernel(ptr + 4); - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - if ((e2 & DESC_S_MASK) || - (type != 1 && type != 9)) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { - uint32_t e3, e4; - e3 = ldl_kernel(ptr + 8); - e4 = ldl_kernel(ptr + 12); - if ((e4 >> DESC_TYPE_SHIFT) & 0xf) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - load_seg_cache_raw_dt(&env->tr, e1, e2); - env->tr.base |= (target_ulong)e3 << 32; - } else -#endif - { - load_seg_cache_raw_dt(&env->tr, e1, e2); - } - e2 |= DESC_TSS_BUSY_MASK; - stl_kernel(ptr + 4, e2); - } - env->tr.selector = selector; -} - -/* only works if protected mode and not VM86. seg_reg must be != R_CS */ -void helper_load_seg(int seg_reg, int selector) -{ - uint32_t e1, e2; - int cpl, dpl, rpl; - SegmentCache *dt; - int index; - target_ulong ptr; - - selector &= 0xffff; - cpl = env->hflags & HF_CPL_MASK; - if ((selector & 0xfffc) == 0) { - /* null selector case */ - if (seg_reg == R_SS -#ifdef TARGET_X86_64 - && (!(env->hflags & HF_CS64_MASK) || cpl == 3) -#endif - ) - raise_exception_err(EXCP0D_GPF, 0); - cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0); - } else { - - if (selector & 0x4) - dt = &env->ldt; - else - dt = &env->gdt; - index = selector & ~7; - if ((index + 7) > dt->limit) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - ptr = dt->base + index; - e1 = ldl_kernel(ptr); - e2 = ldl_kernel(ptr + 4); - - if (!(e2 & DESC_S_MASK)) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (seg_reg == R_SS) { - /* must be writable segment */ - if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (rpl != cpl || dpl != cpl) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - } else { - /* must be readable segment */ - if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - - if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) { - /* if not conforming code, test rights */ - if (dpl < cpl || dpl < rpl) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - } - } - - if (!(e2 & DESC_P_MASK)) { - if (seg_reg == R_SS) - raise_exception_err(EXCP0C_STACK, selector & 0xfffc); - else - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); - } - - /* set the access bit if not already set */ - if (!(e2 & DESC_A_MASK)) { - e2 |= DESC_A_MASK; - stl_kernel(ptr + 4, e2); - } - - cpu_x86_load_seg_cache(env, seg_reg, selector, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), - e2); -#if 0 - qemu_log("load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx flags=%08x\n", - selector, (unsigned long)sc->base, sc->limit, sc->flags); -#endif - } -} - -/* protected mode jump */ -void helper_ljmp_protected(int new_cs, target_ulong new_eip, - int next_eip_addend) -{ - int gate_cs, type; - uint32_t e1, e2, cpl, dpl, rpl, limit; - target_ulong next_eip; - - if ((new_cs & 0xfffc) == 0) - raise_exception_err(EXCP0D_GPF, 0); - if (load_segment(&e1, &e2, new_cs) != 0) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_S_MASK) { - if (!(e2 & DESC_CS_MASK)) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (e2 & DESC_C_MASK) { - /* conforming code segment */ - if (dpl > cpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - } else { - /* non conforming code segment */ - rpl = new_cs & 3; - if (rpl > cpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - if (dpl != cpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - } - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); - limit = get_seg_limit(e1, e2); - if (new_eip > limit && - !(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK)) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, - get_seg_base(e1, e2), limit, e2); - EIP = new_eip; - } else { - /* jump to call or task gate */ - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - rpl = new_cs & 3; - cpl = env->hflags & HF_CPL_MASK; - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - switch(type) { - case 1: /* 286 TSS */ - case 9: /* 386 TSS */ - case 5: /* task gate */ - if (dpl < cpl || dpl < rpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - next_eip = env->eip + next_eip_addend; - switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip); - CC_OP = CC_OP_EFLAGS; - break; - case 4: /* 286 call gate */ - case 12: /* 386 call gate */ - if ((dpl < cpl) || (dpl < rpl)) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); - gate_cs = e1 >> 16; - new_eip = (e1 & 0xffff); - if (type == 12) - new_eip |= (e2 & 0xffff0000); - if (load_segment(&e1, &e2, gate_cs) != 0) - raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc); - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - /* must be code segment */ - if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) != - (DESC_S_MASK | DESC_CS_MASK))) - raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc); - if (((e2 & DESC_C_MASK) && (dpl > cpl)) || - (!(e2 & DESC_C_MASK) && (dpl != cpl))) - raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc); - limit = get_seg_limit(e1, e2); - if (new_eip > limit) - raise_exception_err(EXCP0D_GPF, 0); - cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl, - get_seg_base(e1, e2), limit, e2); - EIP = new_eip; - break; - default: - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - break; - } - } -} - -/* real mode call */ -void helper_lcall_real(int new_cs, target_ulong new_eip1, - int shift, int next_eip) -{ - int new_eip; - uint32_t esp, esp_mask; - target_ulong ssp; - - new_eip = new_eip1; - esp = ESP; - esp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; - if (shift) { - PUSHL(ssp, esp, esp_mask, env->segs[R_CS].selector); - PUSHL(ssp, esp, esp_mask, next_eip); - } else { - PUSHW(ssp, esp, esp_mask, env->segs[R_CS].selector); - PUSHW(ssp, esp, esp_mask, next_eip); - } - - SET_ESP(esp, esp_mask); - env->eip = new_eip; - env->segs[R_CS].selector = new_cs; - env->segs[R_CS].base = (new_cs << 4); -} - -/* protected mode call */ -void helper_lcall_protected(int new_cs, target_ulong new_eip, - int shift, int next_eip_addend) -{ - int new_stack, i; - uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count; - uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, sp, type, ss_dpl, sp_mask; - uint32_t val, limit, old_sp_mask; - target_ulong ssp, old_ssp, next_eip; - - next_eip = env->eip + next_eip_addend; - LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift); - LOG_PCALL_STATE(env); - if ((new_cs & 0xfffc) == 0) - raise_exception_err(EXCP0D_GPF, 0); - if (load_segment(&e1, &e2, new_cs) != 0) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - cpl = env->hflags & HF_CPL_MASK; - LOG_PCALL("desc=%08x:%08x\n", e1, e2); - if (e2 & DESC_S_MASK) { - if (!(e2 & DESC_CS_MASK)) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (e2 & DESC_C_MASK) { - /* conforming code segment */ - if (dpl > cpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - } else { - /* non conforming code segment */ - rpl = new_cs & 3; - if (rpl > cpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - if (dpl != cpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - } - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); - -#ifdef TARGET_X86_64 - /* XXX: check 16/32 bit cases in long mode */ - if (shift == 2) { - target_ulong rsp; - /* 64 bit case */ - rsp = ESP; - PUSHQ(rsp, env->segs[R_CS].selector); - PUSHQ(rsp, next_eip); - /* from this point, not restartable */ - ESP = rsp; - cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), e2); - EIP = new_eip; - } else -#endif - { - sp = ESP; - sp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; - if (shift) { - PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector); - PUSHL(ssp, sp, sp_mask, next_eip); - } else { - PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector); - PUSHW(ssp, sp, sp_mask, next_eip); - } - - limit = get_seg_limit(e1, e2); - if (new_eip > limit) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - /* from this point, not restartable */ - SET_ESP(sp, sp_mask); - cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, - get_seg_base(e1, e2), limit, e2); - EIP = new_eip; - } - } else { - /* check gate type */ - type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - rpl = new_cs & 3; - switch(type) { - case 1: /* available 286 TSS */ - case 9: /* available 386 TSS */ - case 5: /* task gate */ - if (dpl < cpl || dpl < rpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - switch_tss(new_cs, e1, e2, SWITCH_TSS_CALL, next_eip); - CC_OP = CC_OP_EFLAGS; - return; - case 4: /* 286 call gate */ - case 12: /* 386 call gate */ - break; - default: - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - break; - } - shift = type >> 3; - - if (dpl < cpl || dpl < rpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - /* check valid bit */ - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); - selector = e1 >> 16; - offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff); - param_count = e2 & 0x1f; - if ((selector & 0xfffc) == 0) - raise_exception_err(EXCP0D_GPF, 0); - - if (load_segment(&e1, &e2, selector) != 0) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (dpl > cpl) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); - - if (!(e2 & DESC_C_MASK) && dpl < cpl) { - /* to inner privilege */ - get_ss_esp_from_tss(&ss, &sp, dpl); - LOG_PCALL("new ss:esp=%04x:%08x param_count=%d ESP=" TARGET_FMT_lx "\n", - ss, sp, param_count, ESP); - if ((ss & 0xfffc) == 0) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if ((ss & 3) != dpl) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if (load_segment(&ss_e1, &ss_e2, ss) != 0) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; - if (ss_dpl != dpl) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if (!(ss_e2 & DESC_S_MASK) || - (ss_e2 & DESC_CS_MASK) || - !(ss_e2 & DESC_W_MASK)) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - if (!(ss_e2 & DESC_P_MASK)) - raise_exception_err(EXCP0A_TSS, ss & 0xfffc); - - // push_size = ((param_count * 2) + 8) << shift; - - old_sp_mask = get_sp_mask(env->segs[R_SS].flags); - old_ssp = env->segs[R_SS].base; - - sp_mask = get_sp_mask(ss_e2); - ssp = get_seg_base(ss_e1, ss_e2); - if (shift) { - PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector); - PUSHL(ssp, sp, sp_mask, ESP); - for(i = param_count - 1; i >= 0; i--) { - val = ldl_kernel(old_ssp + ((ESP + i * 4) & old_sp_mask)); - PUSHL(ssp, sp, sp_mask, val); - } - } else { - PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector); - PUSHW(ssp, sp, sp_mask, ESP); - for(i = param_count - 1; i >= 0; i--) { - val = lduw_kernel(old_ssp + ((ESP + i * 2) & old_sp_mask)); - PUSHW(ssp, sp, sp_mask, val); - } - } - new_stack = 1; - } else { - /* to same privilege */ - sp = ESP; - sp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; - // push_size = (4 << shift); - new_stack = 0; - } - - if (shift) { - PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector); - PUSHL(ssp, sp, sp_mask, next_eip); - } else { - PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector); - PUSHW(ssp, sp, sp_mask, next_eip); - } - - /* from this point, not restartable */ - - if (new_stack) { - ss = (ss & ~3) | dpl; - cpu_x86_load_seg_cache(env, R_SS, ss, - ssp, - get_seg_limit(ss_e1, ss_e2), - ss_e2); - } - - selector = (selector & ~3) | dpl; - cpu_x86_load_seg_cache(env, R_CS, selector, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), - e2); - cpu_x86_set_cpl(env, dpl); - SET_ESP(sp, sp_mask); - EIP = offset; - } -} - -/* real and vm86 mode iret */ -void helper_iret_real(int shift) -{ - uint32_t sp, new_cs, new_eip, new_eflags, sp_mask; - target_ulong ssp; - int eflags_mask; - - sp_mask = 0xffff; /* XXXX: use SS segment size ? */ - sp = ESP; - ssp = env->segs[R_SS].base; - if (shift == 1) { - /* 32 bits */ - POPL(ssp, sp, sp_mask, new_eip); - POPL(ssp, sp, sp_mask, new_cs); - new_cs &= 0xffff; - POPL(ssp, sp, sp_mask, new_eflags); - } else { - /* 16 bits */ - POPW(ssp, sp, sp_mask, new_eip); - POPW(ssp, sp, sp_mask, new_cs); - POPW(ssp, sp, sp_mask, new_eflags); - } - ESP = (ESP & ~sp_mask) | (sp & sp_mask); - env->segs[R_CS].selector = new_cs; - env->segs[R_CS].base = (new_cs << 4); - env->eip = new_eip; - if (env->eflags & VM_MASK) - eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | RF_MASK | NT_MASK; - else - eflags_mask = TF_MASK | AC_MASK | ID_MASK | IF_MASK | IOPL_MASK | RF_MASK | NT_MASK; - if (shift == 0) - eflags_mask &= 0xffff; - load_eflags(new_eflags, eflags_mask); - env->hflags2 &= ~HF2_NMI_MASK; -} - -static inline void validate_seg(int seg_reg, int cpl) -{ - int dpl; - uint32_t e2; - - /* XXX: on x86_64, we do not want to nullify FS and GS because - they may still contain a valid base. I would be interested to - know how a real x86_64 CPU behaves */ - if ((seg_reg == R_FS || seg_reg == R_GS) && - (env->segs[seg_reg].selector & 0xfffc) == 0) - return; - - e2 = env->segs[seg_reg].flags; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) { - /* data or non conforming code segment */ - if (dpl < cpl) { - cpu_x86_load_seg_cache(env, seg_reg, 0, 0, 0, 0); - } - } -} - -/* protected mode iret */ -static inline void helper_ret_protected(int shift, int is_iret, int addend) -{ - uint32_t new_cs, new_eflags, new_ss; - uint32_t new_es, new_ds, new_fs, new_gs; - uint32_t e1, e2, ss_e1, ss_e2; - int cpl, dpl, rpl, eflags_mask, iopl; - target_ulong ssp, sp, new_eip, new_esp, sp_mask; - -#ifdef TARGET_X86_64 - if (shift == 2) - sp_mask = -1; - else -#endif - sp_mask = get_sp_mask(env->segs[R_SS].flags); - sp = ESP; - ssp = env->segs[R_SS].base; - new_eflags = 0; /* avoid warning */ -#ifdef TARGET_X86_64 - if (shift == 2) { - POPQ(sp, new_eip); - POPQ(sp, new_cs); - new_cs &= 0xffff; - if (is_iret) { - POPQ(sp, new_eflags); - } - } else -#endif - if (shift == 1) { - /* 32 bits */ - POPL(ssp, sp, sp_mask, new_eip); - POPL(ssp, sp, sp_mask, new_cs); - new_cs &= 0xffff; - if (is_iret) { - POPL(ssp, sp, sp_mask, new_eflags); - if (new_eflags & VM_MASK) - goto return_to_vm86; - } - } else { - /* 16 bits */ - POPW(ssp, sp, sp_mask, new_eip); - POPW(ssp, sp, sp_mask, new_cs); - if (is_iret) - POPW(ssp, sp, sp_mask, new_eflags); - } - LOG_PCALL("lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n", - new_cs, new_eip, shift, addend); - LOG_PCALL_STATE(env); - if ((new_cs & 0xfffc) == 0) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - if (load_segment(&e1, &e2, new_cs) != 0) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - if (!(e2 & DESC_S_MASK) || - !(e2 & DESC_CS_MASK)) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - cpl = env->hflags & HF_CPL_MASK; - rpl = new_cs & 3; - if (rpl < cpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - if (e2 & DESC_C_MASK) { - if (dpl > rpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - } else { - if (dpl != rpl) - raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - } - if (!(e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); - - sp += addend; - if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) || - ((env->hflags & HF_CS64_MASK) && !is_iret))) { - /* return to same privilege level */ - cpu_x86_load_seg_cache(env, R_CS, new_cs, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), - e2); - } else { - /* return to different privilege level */ -#ifdef TARGET_X86_64 - if (shift == 2) { - POPQ(sp, new_esp); - POPQ(sp, new_ss); - new_ss &= 0xffff; - } else -#endif - if (shift == 1) { - /* 32 bits */ - POPL(ssp, sp, sp_mask, new_esp); - POPL(ssp, sp, sp_mask, new_ss); - new_ss &= 0xffff; - } else { - /* 16 bits */ - POPW(ssp, sp, sp_mask, new_esp); - POPW(ssp, sp, sp_mask, new_ss); - } - LOG_PCALL("new ss:esp=%04x:" TARGET_FMT_lx "\n", - new_ss, new_esp); - if ((new_ss & 0xfffc) == 0) { -#ifdef TARGET_X86_64 - /* NULL ss is allowed in long mode if cpl != 3*/ - /* XXX: test CS64 ? */ - if ((env->hflags & HF_LMA_MASK) && rpl != 3) { - cpu_x86_load_seg_cache(env, R_SS, new_ss, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (rpl << DESC_DPL_SHIFT) | - DESC_W_MASK | DESC_A_MASK); - ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */ - } else -#endif - { - raise_exception_err(EXCP0D_GPF, 0); - } - } else { - if ((new_ss & 3) != rpl) - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); - if (load_segment(&ss_e1, &ss_e2, new_ss) != 0) - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); - if (!(ss_e2 & DESC_S_MASK) || - (ss_e2 & DESC_CS_MASK) || - !(ss_e2 & DESC_W_MASK)) - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); - dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; - if (dpl != rpl) - raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); - if (!(ss_e2 & DESC_P_MASK)) - raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc); - cpu_x86_load_seg_cache(env, R_SS, new_ss, - get_seg_base(ss_e1, ss_e2), - get_seg_limit(ss_e1, ss_e2), - ss_e2); - } - - cpu_x86_load_seg_cache(env, R_CS, new_cs, - get_seg_base(e1, e2), - get_seg_limit(e1, e2), - e2); - cpu_x86_set_cpl(env, rpl); - sp = new_esp; -#ifdef TARGET_X86_64 - if (env->hflags & HF_CS64_MASK) - sp_mask = -1; - else -#endif - sp_mask = get_sp_mask(ss_e2); - - /* validate data segments */ - validate_seg(R_ES, rpl); - validate_seg(R_DS, rpl); - validate_seg(R_FS, rpl); - validate_seg(R_GS, rpl); - - sp += addend; - } - SET_ESP(sp, sp_mask); - env->eip = new_eip; - if (is_iret) { - /* NOTE: 'cpl' is the _old_ CPL */ - eflags_mask = TF_MASK | AC_MASK | ID_MASK | RF_MASK | NT_MASK; - if (cpl == 0) - eflags_mask |= IOPL_MASK; - iopl = (env->eflags >> IOPL_SHIFT) & 3; - if (cpl <= iopl) - eflags_mask |= IF_MASK; - if (shift == 0) - eflags_mask &= 0xffff; - load_eflags(new_eflags, eflags_mask); - } - return; - - return_to_vm86: - POPL(ssp, sp, sp_mask, new_esp); - POPL(ssp, sp, sp_mask, new_ss); - POPL(ssp, sp, sp_mask, new_es); - POPL(ssp, sp, sp_mask, new_ds); - POPL(ssp, sp, sp_mask, new_fs); - POPL(ssp, sp, sp_mask, new_gs); - - /* modify processor state */ - load_eflags(new_eflags, TF_MASK | AC_MASK | ID_MASK | - IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK | VIP_MASK); - load_seg_vm(R_CS, new_cs & 0xffff); - cpu_x86_set_cpl(env, 3); - load_seg_vm(R_SS, new_ss & 0xffff); - load_seg_vm(R_ES, new_es & 0xffff); - load_seg_vm(R_DS, new_ds & 0xffff); - load_seg_vm(R_FS, new_fs & 0xffff); - load_seg_vm(R_GS, new_gs & 0xffff); - - env->eip = new_eip & 0xffff; - ESP = new_esp; -} - -void helper_iret_protected(int shift, int next_eip) -{ - int tss_selector, type; - uint32_t e1, e2; - - /* specific case for TSS */ - if (env->eflags & NT_MASK) { -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) - raise_exception_err(EXCP0D_GPF, 0); -#endif - tss_selector = lduw_kernel(env->tr.base + 0); - if (tss_selector & 4) - raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); - if (load_segment(&e1, &e2, tss_selector) != 0) - raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); - type = (e2 >> DESC_TYPE_SHIFT) & 0x17; - /* NOTE: we check both segment and busy TSS */ - if (type != 3) - raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); - switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip); - } else { - helper_ret_protected(shift, 1, 0); - } - env->hflags2 &= ~HF2_NMI_MASK; -} - -void helper_lret_protected(int shift, int addend) -{ - helper_ret_protected(shift, 0, addend); -} - -void helper_sysenter(void) -{ - if (env->sysenter_cs == 0) { - raise_exception_err(EXCP0D_GPF, 0); - } - env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK); - cpu_x86_set_cpl(env, 0); - -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { - cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); - } else -#endif - { - cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - } - cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_W_MASK | DESC_A_MASK); - ESP = env->sysenter_esp; - EIP = env->sysenter_eip; -} - -void helper_sysexit(int dflag) -{ - int cpl; - - cpl = env->hflags & HF_CPL_MASK; - if (env->sysenter_cs == 0 || cpl != 0) { - raise_exception_err(EXCP0D_GPF, 0); - } - cpu_x86_set_cpl(env, 3); -#ifdef TARGET_X86_64 - if (dflag == 2) { - cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 32) & 0xfffc) | 3, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK); - cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 40) & 0xfffc) | 3, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_W_MASK | DESC_A_MASK); - } else -#endif - { - cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | (3 << DESC_DPL_SHIFT) | - DESC_W_MASK | DESC_A_MASK); - } - ESP = ECX; - EIP = EDX; -} - -#if defined(CONFIG_USER_ONLY) -target_ulong helper_read_crN(int reg) -{ - return 0; -} - -void helper_write_crN(int reg, target_ulong t0) -{ -} - -void helper_movl_drN_T0(int reg, target_ulong t0) -{ -} -#else -target_ulong helper_read_crN(int reg) -{ - target_ulong val; - - helper_svm_check_intercept_param(SVM_EXIT_READ_CR0 + reg, 0); - switch(reg) { - default: - val = env->cr[reg]; - break; - case 8: - if (!(env->hflags2 & HF2_VINTR_MASK)) { - val = cpu_get_apic_tpr(env->apic_state); - } else { - val = env->v_tpr; - } - break; - } - return val; -} - -void helper_write_crN(int reg, target_ulong t0) -{ - helper_svm_check_intercept_param(SVM_EXIT_WRITE_CR0 + reg, 0); - switch(reg) { - case 0: - cpu_x86_update_cr0(env, t0); - break; - case 3: - cpu_x86_update_cr3(env, t0); - break; - case 4: - cpu_x86_update_cr4(env, t0); - break; - case 8: - if (!(env->hflags2 & HF2_VINTR_MASK)) { - cpu_set_apic_tpr(env->apic_state, t0); - } - env->v_tpr = t0 & 0x0f; - break; - default: - env->cr[reg] = t0; - break; - } -} - -void helper_movl_drN_T0(int reg, target_ulong t0) -{ - int i; - - if (reg < 4) { - hw_breakpoint_remove(env, reg); - env->dr[reg] = t0; - hw_breakpoint_insert(env, reg); - } else if (reg == 7) { - for (i = 0; i < 4; i++) - hw_breakpoint_remove(env, i); - env->dr[7] = t0; - for (i = 0; i < 4; i++) - hw_breakpoint_insert(env, i); - } else - env->dr[reg] = t0; -} -#endif - -void helper_lmsw(target_ulong t0) -{ - /* only 4 lower bits of CR0 are modified. PE cannot be set to zero - if already set to one. */ - t0 = (env->cr[0] & ~0xe) | (t0 & 0xf); - helper_write_crN(0, t0); -} - -void helper_clts(void) -{ - env->cr[0] &= ~CR0_TS_MASK; - env->hflags &= ~HF_TS_MASK; -} - -void helper_invlpg(target_ulong addr) -{ - helper_svm_check_intercept_param(SVM_EXIT_INVLPG, 0); - tlb_flush_page(env, addr); -} - -void helper_rdtsc(void) -{ - uint64_t val; - - if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { - raise_exception(EXCP0D_GPF); - } - helper_svm_check_intercept_param(SVM_EXIT_RDTSC, 0); - - val = cpu_get_tsc(env) + env->tsc_offset; - EAX = (uint32_t)(val); - EDX = (uint32_t)(val >> 32); -} - -void helper_rdtscp(void) -{ - helper_rdtsc(); - ECX = (uint32_t)(env->tsc_aux); -} - -void helper_rdpmc(void) -{ - if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { - raise_exception(EXCP0D_GPF); - } - helper_svm_check_intercept_param(SVM_EXIT_RDPMC, 0); - - /* currently unimplemented */ - raise_exception_err(EXCP06_ILLOP, 0); -} - -#if defined(CONFIG_USER_ONLY) -void helper_wrmsr(void) -{ -} - -void helper_rdmsr(void) -{ -} -#else -void helper_wrmsr(void) -{ - uint64_t val; - - helper_svm_check_intercept_param(SVM_EXIT_MSR, 1); - - val = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32); - - switch((uint32_t)ECX) { - case MSR_IA32_SYSENTER_CS: - env->sysenter_cs = val & 0xffff; - break; - case MSR_IA32_SYSENTER_ESP: - env->sysenter_esp = val; - break; - case MSR_IA32_SYSENTER_EIP: - env->sysenter_eip = val; - break; - case MSR_IA32_APICBASE: - cpu_set_apic_base(env->apic_state, val); - break; - case MSR_EFER: - { - uint64_t update_mask; - update_mask = 0; - if (env->cpuid_ext2_features & CPUID_EXT2_SYSCALL) - update_mask |= MSR_EFER_SCE; - if (env->cpuid_ext2_features & CPUID_EXT2_LM) - update_mask |= MSR_EFER_LME; - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) - update_mask |= MSR_EFER_FFXSR; - if (env->cpuid_ext2_features & CPUID_EXT2_NX) - update_mask |= MSR_EFER_NXE; - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) - update_mask |= MSR_EFER_SVME; - if (env->cpuid_ext2_features & CPUID_EXT2_FFXSR) - update_mask |= MSR_EFER_FFXSR; - cpu_load_efer(env, (env->efer & ~update_mask) | - (val & update_mask)); - } - break; - case MSR_STAR: - env->star = val; - break; - case MSR_PAT: - env->pat = val; - break; - case MSR_VM_HSAVE_PA: - env->vm_hsave = val; - break; -#ifdef TARGET_X86_64 - case MSR_LSTAR: - env->lstar = val; - break; - case MSR_CSTAR: - env->cstar = val; - break; - case MSR_FMASK: - env->fmask = val; - break; - case MSR_FSBASE: - env->segs[R_FS].base = val; - break; - case MSR_GSBASE: - env->segs[R_GS].base = val; - break; - case MSR_KERNELGSBASE: - env->kernelgsbase = val; - break; -#endif - case MSR_MTRRphysBase(0): - case MSR_MTRRphysBase(1): - case MSR_MTRRphysBase(2): - case MSR_MTRRphysBase(3): - case MSR_MTRRphysBase(4): - case MSR_MTRRphysBase(5): - case MSR_MTRRphysBase(6): - case MSR_MTRRphysBase(7): - env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base = val; - break; - case MSR_MTRRphysMask(0): - case MSR_MTRRphysMask(1): - case MSR_MTRRphysMask(2): - case MSR_MTRRphysMask(3): - case MSR_MTRRphysMask(4): - case MSR_MTRRphysMask(5): - case MSR_MTRRphysMask(6): - case MSR_MTRRphysMask(7): - env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask = val; - break; - case MSR_MTRRfix64K_00000: - env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix64K_00000] = val; - break; - case MSR_MTRRfix16K_80000: - case MSR_MTRRfix16K_A0000: - env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1] = val; - break; - case MSR_MTRRfix4K_C0000: - case MSR_MTRRfix4K_C8000: - case MSR_MTRRfix4K_D0000: - case MSR_MTRRfix4K_D8000: - case MSR_MTRRfix4K_E0000: - case MSR_MTRRfix4K_E8000: - case MSR_MTRRfix4K_F0000: - case MSR_MTRRfix4K_F8000: - env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3] = val; - break; - case MSR_MTRRdefType: - env->mtrr_deftype = val; - break; - case MSR_MCG_STATUS: - env->mcg_status = val; - break; - case MSR_MCG_CTL: - if ((env->mcg_cap & MCG_CTL_P) - && (val == 0 || val == ~(uint64_t)0)) - env->mcg_ctl = val; - break; - case MSR_TSC_AUX: - env->tsc_aux = val; - break; - default: - if ((uint32_t)ECX >= MSR_MC0_CTL - && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) { - uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL; - if ((offset & 0x3) != 0 - || (val == 0 || val == ~(uint64_t)0)) - env->mce_banks[offset] = val; - break; - } - /* XXX: exception ? */ - break; - } -} - -void helper_rdmsr(void) -{ - uint64_t val; - - helper_svm_check_intercept_param(SVM_EXIT_MSR, 0); - - switch((uint32_t)ECX) { - case MSR_IA32_SYSENTER_CS: - val = env->sysenter_cs; - break; - case MSR_IA32_SYSENTER_ESP: - val = env->sysenter_esp; - break; - case MSR_IA32_SYSENTER_EIP: - val = env->sysenter_eip; - break; - case MSR_IA32_APICBASE: - val = cpu_get_apic_base(env->apic_state); - break; - case MSR_EFER: - val = env->efer; - break; - case MSR_STAR: - val = env->star; - break; - case MSR_PAT: - val = env->pat; - break; - case MSR_VM_HSAVE_PA: - val = env->vm_hsave; - break; - case MSR_IA32_PERF_STATUS: - /* tsc_increment_by_tick */ - val = 1000ULL; - /* CPU multiplier */ - val |= (((uint64_t)4ULL) << 40); - break; -#ifdef TARGET_X86_64 - case MSR_LSTAR: - val = env->lstar; - break; - case MSR_CSTAR: - val = env->cstar; - break; - case MSR_FMASK: - val = env->fmask; - break; - case MSR_FSBASE: - val = env->segs[R_FS].base; - break; - case MSR_GSBASE: - val = env->segs[R_GS].base; - break; - case MSR_KERNELGSBASE: - val = env->kernelgsbase; - break; - case MSR_TSC_AUX: - val = env->tsc_aux; - break; -#endif - case MSR_MTRRphysBase(0): - case MSR_MTRRphysBase(1): - case MSR_MTRRphysBase(2): - case MSR_MTRRphysBase(3): - case MSR_MTRRphysBase(4): - case MSR_MTRRphysBase(5): - case MSR_MTRRphysBase(6): - case MSR_MTRRphysBase(7): - val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysBase(0)) / 2].base; - break; - case MSR_MTRRphysMask(0): - case MSR_MTRRphysMask(1): - case MSR_MTRRphysMask(2): - case MSR_MTRRphysMask(3): - case MSR_MTRRphysMask(4): - case MSR_MTRRphysMask(5): - case MSR_MTRRphysMask(6): - case MSR_MTRRphysMask(7): - val = env->mtrr_var[((uint32_t)ECX - MSR_MTRRphysMask(0)) / 2].mask; - break; - case MSR_MTRRfix64K_00000: - val = env->mtrr_fixed[0]; - break; - case MSR_MTRRfix16K_80000: - case MSR_MTRRfix16K_A0000: - val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix16K_80000 + 1]; - break; - case MSR_MTRRfix4K_C0000: - case MSR_MTRRfix4K_C8000: - case MSR_MTRRfix4K_D0000: - case MSR_MTRRfix4K_D8000: - case MSR_MTRRfix4K_E0000: - case MSR_MTRRfix4K_E8000: - case MSR_MTRRfix4K_F0000: - case MSR_MTRRfix4K_F8000: - val = env->mtrr_fixed[(uint32_t)ECX - MSR_MTRRfix4K_C0000 + 3]; - break; - case MSR_MTRRdefType: - val = env->mtrr_deftype; - break; - case MSR_MTRRcap: - if (env->cpuid_features & CPUID_MTRR) - val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | MSR_MTRRcap_WC_SUPPORTED; - else - /* XXX: exception ? */ - val = 0; - break; - case MSR_MCG_CAP: - val = env->mcg_cap; - break; - case MSR_MCG_CTL: - if (env->mcg_cap & MCG_CTL_P) - val = env->mcg_ctl; - else - val = 0; - break; - case MSR_MCG_STATUS: - val = env->mcg_status; - break; - default: - if ((uint32_t)ECX >= MSR_MC0_CTL - && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) { - uint32_t offset = (uint32_t)ECX - MSR_MC0_CTL; - val = env->mce_banks[offset]; - break; - } - /* XXX: exception ? */ - val = 0; - break; - } - EAX = (uint32_t)(val); - EDX = (uint32_t)(val >> 32); -} -#endif - -target_ulong helper_lsl(target_ulong selector1) -{ - unsigned int limit; - uint32_t e1, e2, eflags, selector; - int rpl, dpl, cpl, type; - - selector = selector1 & 0xffff; - eflags = helper_cc_compute_all(CC_OP); - if ((selector & 0xfffc) == 0) - goto fail; - if (load_segment(&e1, &e2, selector) != 0) - goto fail; - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_S_MASK) { - if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { - /* conforming */ - } else { - if (dpl < cpl || dpl < rpl) - goto fail; - } - } else { - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - switch(type) { - case 1: - case 2: - case 3: - case 9: - case 11: - break; - default: - goto fail; - } - if (dpl < cpl || dpl < rpl) { - fail: - CC_SRC = eflags & ~CC_Z; - return 0; - } - } - limit = get_seg_limit(e1, e2); - CC_SRC = eflags | CC_Z; - return limit; -} - -target_ulong helper_lar(target_ulong selector1) -{ - uint32_t e1, e2, eflags, selector; - int rpl, dpl, cpl, type; - - selector = selector1 & 0xffff; - eflags = helper_cc_compute_all(CC_OP); - if ((selector & 0xfffc) == 0) - goto fail; - if (load_segment(&e1, &e2, selector) != 0) - goto fail; - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_S_MASK) { - if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { - /* conforming */ - } else { - if (dpl < cpl || dpl < rpl) - goto fail; - } - } else { - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - switch(type) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 9: - case 11: - case 12: - break; - default: - goto fail; - } - if (dpl < cpl || dpl < rpl) { - fail: - CC_SRC = eflags & ~CC_Z; - return 0; - } - } - CC_SRC = eflags | CC_Z; - return e2 & 0x00f0ff00; -} - -void helper_verr(target_ulong selector1) -{ - uint32_t e1, e2, eflags, selector; - int rpl, dpl, cpl; - - selector = selector1 & 0xffff; - eflags = helper_cc_compute_all(CC_OP); - if ((selector & 0xfffc) == 0) - goto fail; - if (load_segment(&e1, &e2, selector) != 0) - goto fail; - if (!(e2 & DESC_S_MASK)) - goto fail; - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_CS_MASK) { - if (!(e2 & DESC_R_MASK)) - goto fail; - if (!(e2 & DESC_C_MASK)) { - if (dpl < cpl || dpl < rpl) - goto fail; - } - } else { - if (dpl < cpl || dpl < rpl) { - fail: - CC_SRC = eflags & ~CC_Z; - return; - } - } - CC_SRC = eflags | CC_Z; -} - -void helper_verw(target_ulong selector1) -{ - uint32_t e1, e2, eflags, selector; - int rpl, dpl, cpl; - - selector = selector1 & 0xffff; - eflags = helper_cc_compute_all(CC_OP); - if ((selector & 0xfffc) == 0) - goto fail; - if (load_segment(&e1, &e2, selector) != 0) - goto fail; - if (!(e2 & DESC_S_MASK)) - goto fail; - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_CS_MASK) { - goto fail; - } else { - if (dpl < cpl || dpl < rpl) - goto fail; - if (!(e2 & DESC_W_MASK)) { - fail: - CC_SRC = eflags & ~CC_Z; - return; - } - } - CC_SRC = eflags | CC_Z; -} - -/* x87 FPU helpers */ - -static void fpu_set_exception(int mask) -{ - env->fpus |= mask; - if (env->fpus & (~env->fpuc & FPUC_EM)) - env->fpus |= FPUS_SE | FPUS_B; -} - -static inline CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b) -{ - if (b == 0.0) - fpu_set_exception(FPUS_ZE); - return a / b; -} - -static void fpu_raise_exception(void) -{ - if (env->cr[0] & CR0_NE_MASK) { - raise_exception(EXCP10_COPR); - } -#if !defined(CONFIG_USER_ONLY) - else { - cpu_set_ferr(env); - } -#endif -} - -void helper_flds_FT0(uint32_t val) -{ - union { - float32 f; - uint32_t i; - } u; - u.i = val; - FT0 = float32_to_floatx(u.f, &env->fp_status); -} - -void helper_fldl_FT0(uint64_t val) -{ - union { - float64 f; - uint64_t i; - } u; - u.i = val; - FT0 = float64_to_floatx(u.f, &env->fp_status); -} - -void helper_fildl_FT0(int32_t val) -{ - FT0 = int32_to_floatx(val, &env->fp_status); -} - -void helper_flds_ST0(uint32_t val) -{ - int new_fpstt; - union { - float32 f; - uint32_t i; - } u; - new_fpstt = (env->fpstt - 1) & 7; - u.i = val; - env->fpregs[new_fpstt].d = float32_to_floatx(u.f, &env->fp_status); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void helper_fldl_ST0(uint64_t val) -{ - int new_fpstt; - union { - float64 f; - uint64_t i; - } u; - new_fpstt = (env->fpstt - 1) & 7; - u.i = val; - env->fpregs[new_fpstt].d = float64_to_floatx(u.f, &env->fp_status); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void helper_fildl_ST0(int32_t val) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; - env->fpregs[new_fpstt].d = int32_to_floatx(val, &env->fp_status); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void helper_fildll_ST0(int64_t val) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; - env->fpregs[new_fpstt].d = int64_to_floatx(val, &env->fp_status); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -uint32_t helper_fsts_ST0(void) -{ - union { - float32 f; - uint32_t i; - } u; - u.f = floatx_to_float32(ST0, &env->fp_status); - return u.i; -} - -uint64_t helper_fstl_ST0(void) -{ - union { - float64 f; - uint64_t i; - } u; - u.f = floatx_to_float64(ST0, &env->fp_status); - return u.i; -} - -int32_t helper_fist_ST0(void) -{ - int32_t val; - val = floatx_to_int32(ST0, &env->fp_status); - if (val != (int16_t)val) - val = -32768; - return val; -} - -int32_t helper_fistl_ST0(void) -{ - int32_t val; - val = floatx_to_int32(ST0, &env->fp_status); - return val; -} - -int64_t helper_fistll_ST0(void) -{ - int64_t val; - val = floatx_to_int64(ST0, &env->fp_status); - return val; -} - -int32_t helper_fistt_ST0(void) -{ - int32_t val; - val = floatx_to_int32_round_to_zero(ST0, &env->fp_status); - if (val != (int16_t)val) - val = -32768; - return val; -} - -int32_t helper_fisttl_ST0(void) -{ - int32_t val; - val = floatx_to_int32_round_to_zero(ST0, &env->fp_status); - return val; -} - -int64_t helper_fisttll_ST0(void) -{ - int64_t val; - val = floatx_to_int64_round_to_zero(ST0, &env->fp_status); - return val; -} - -void helper_fldt_ST0(target_ulong ptr) -{ - int new_fpstt; - new_fpstt = (env->fpstt - 1) & 7; - env->fpregs[new_fpstt].d = helper_fldt(ptr); - env->fpstt = new_fpstt; - env->fptags[new_fpstt] = 0; /* validate stack entry */ -} - -void helper_fstt_ST0(target_ulong ptr) -{ - helper_fstt(ST0, ptr); -} - -void helper_fpush(void) -{ - fpush(); -} - -void helper_fpop(void) -{ - fpop(); -} - -void helper_fdecstp(void) -{ - env->fpstt = (env->fpstt - 1) & 7; - env->fpus &= (~0x4700); -} - -void helper_fincstp(void) -{ - env->fpstt = (env->fpstt + 1) & 7; - env->fpus &= (~0x4700); -} - -/* FPU move */ - -void helper_ffree_STN(int st_index) -{ - env->fptags[(env->fpstt + st_index) & 7] = 1; -} - -void helper_fmov_ST0_FT0(void) -{ - ST0 = FT0; -} - -void helper_fmov_FT0_STN(int st_index) -{ - FT0 = ST(st_index); -} - -void helper_fmov_ST0_STN(int st_index) -{ - ST0 = ST(st_index); -} - -void helper_fmov_STN_ST0(int st_index) -{ - ST(st_index) = ST0; -} - -void helper_fxchg_ST0_STN(int st_index) -{ - CPU86_LDouble tmp; - tmp = ST(st_index); - ST(st_index) = ST0; - ST0 = tmp; -} - -/* FPU operations */ - -static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; - -void helper_fcom_ST0_FT0(void) -{ - int ret; - - ret = floatx_compare(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; -} - -void helper_fucom_ST0_FT0(void) -{ - int ret; - - ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; -} - -static const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; - -void helper_fcomi_ST0_FT0(void) -{ - int eflags; - int ret; - - ret = floatx_compare(ST0, FT0, &env->fp_status); - eflags = helper_cc_compute_all(CC_OP); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; - CC_SRC = eflags; -} - -void helper_fucomi_ST0_FT0(void) -{ - int eflags; - int ret; - - ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); - eflags = helper_cc_compute_all(CC_OP); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; - CC_SRC = eflags; -} - -void helper_fadd_ST0_FT0(void) -{ - ST0 += FT0; -} - -void helper_fmul_ST0_FT0(void) -{ - ST0 *= FT0; -} - -void helper_fsub_ST0_FT0(void) -{ - ST0 -= FT0; -} - -void helper_fsubr_ST0_FT0(void) -{ - ST0 = FT0 - ST0; -} - -void helper_fdiv_ST0_FT0(void) -{ - ST0 = helper_fdiv(ST0, FT0); -} - -void helper_fdivr_ST0_FT0(void) -{ - ST0 = helper_fdiv(FT0, ST0); -} - -/* fp operations between STN and ST0 */ - -void helper_fadd_STN_ST0(int st_index) -{ - ST(st_index) += ST0; -} - -void helper_fmul_STN_ST0(int st_index) -{ - ST(st_index) *= ST0; -} - -void helper_fsub_STN_ST0(int st_index) -{ - ST(st_index) -= ST0; -} - -void helper_fsubr_STN_ST0(int st_index) -{ - CPU86_LDouble *p; - p = &ST(st_index); - *p = ST0 - *p; -} - -void helper_fdiv_STN_ST0(int st_index) -{ - CPU86_LDouble *p; - p = &ST(st_index); - *p = helper_fdiv(*p, ST0); -} - -void helper_fdivr_STN_ST0(int st_index) -{ - CPU86_LDouble *p; - p = &ST(st_index); - *p = helper_fdiv(ST0, *p); -} - -/* misc FPU operations */ -void helper_fchs_ST0(void) -{ - ST0 = floatx_chs(ST0); -} - -void helper_fabs_ST0(void) -{ - ST0 = floatx_abs(ST0); -} - -void helper_fld1_ST0(void) -{ - ST0 = f15rk[1]; -} - -void helper_fldl2t_ST0(void) -{ - ST0 = f15rk[6]; -} - -void helper_fldl2e_ST0(void) -{ - ST0 = f15rk[5]; -} - -void helper_fldpi_ST0(void) -{ - ST0 = f15rk[2]; -} - -void helper_fldlg2_ST0(void) -{ - ST0 = f15rk[3]; -} - -void helper_fldln2_ST0(void) -{ - ST0 = f15rk[4]; -} - -void helper_fldz_ST0(void) -{ - ST0 = f15rk[0]; -} - -void helper_fldz_FT0(void) -{ - FT0 = f15rk[0]; -} - -uint32_t helper_fnstsw(void) -{ - return (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; -} - -uint32_t helper_fnstcw(void) -{ - return env->fpuc; -} - -static void update_fp_status(void) -{ - int rnd_type; - - /* set rounding mode */ - switch(env->fpuc & RC_MASK) { - default: - case RC_NEAR: - rnd_type = float_round_nearest_even; - break; - case RC_DOWN: - rnd_type = float_round_down; - break; - case RC_UP: - rnd_type = float_round_up; - break; - case RC_CHOP: - rnd_type = float_round_to_zero; - break; - } - set_float_rounding_mode(rnd_type, &env->fp_status); -#ifdef FLOATX80 - switch((env->fpuc >> 8) & 3) { - case 0: - rnd_type = 32; - break; - case 2: - rnd_type = 64; - break; - case 3: - default: - rnd_type = 80; - break; - } - set_floatx80_rounding_precision(rnd_type, &env->fp_status); -#endif -} - -void helper_fldcw(uint32_t val) -{ - env->fpuc = val; - update_fp_status(); -} - -void helper_fclex(void) -{ - env->fpus &= 0x7f00; -} - -void helper_fwait(void) -{ - if (env->fpus & FPUS_SE) - fpu_raise_exception(); -} - -void helper_fninit(void) -{ - env->fpus = 0; - env->fpstt = 0; - env->fpuc = 0x37f; - env->fptags[0] = 1; - env->fptags[1] = 1; - env->fptags[2] = 1; - env->fptags[3] = 1; - env->fptags[4] = 1; - env->fptags[5] = 1; - env->fptags[6] = 1; - env->fptags[7] = 1; -} - -/* BCD ops */ - -void helper_fbld_ST0(target_ulong ptr) -{ - CPU86_LDouble tmp; - uint64_t val; - unsigned int v; - int i; - - val = 0; - for(i = 8; i >= 0; i--) { - v = ldub(ptr + i); - val = (val * 100) + ((v >> 4) * 10) + (v & 0xf); - } - tmp = val; - if (ldub(ptr + 9) & 0x80) - tmp = -tmp; - fpush(); - ST0 = tmp; -} - -void helper_fbst_ST0(target_ulong ptr) -{ - int v; - target_ulong mem_ref, mem_end; - int64_t val; - - val = floatx_to_int64(ST0, &env->fp_status); - mem_ref = ptr; - mem_end = mem_ref + 9; - if (val < 0) { - stb(mem_end, 0x80); - val = -val; - } else { - stb(mem_end, 0x00); - } - while (mem_ref < mem_end) { - if (val == 0) - break; - v = val % 100; - val = val / 100; - v = ((v / 10) << 4) | (v % 10); - stb(mem_ref++, v); - } - while (mem_ref < mem_end) { - stb(mem_ref++, 0); - } -} - -void helper_f2xm1(void) -{ - ST0 = pow(2.0,ST0) - 1.0; -} - -void helper_fyl2x(void) -{ - CPU86_LDouble fptemp; - - fptemp = ST0; - if (fptemp>0.0){ - fptemp = log(fptemp)/log(2.0); /* log2(ST) */ - ST1 *= fptemp; - fpop(); - } else { - env->fpus &= (~0x4700); - env->fpus |= 0x400; - } -} - -void helper_fptan(void) -{ - CPU86_LDouble fptemp; - - fptemp = ST0; - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { - env->fpus |= 0x400; - } else { - ST0 = tan(fptemp); - fpush(); - ST0 = 1.0; - env->fpus &= (~0x400); /* C2 <-- 0 */ - /* the above code is for |arg| < 2**52 only */ - } -} - -void helper_fpatan(void) -{ - CPU86_LDouble fptemp, fpsrcop; - - fpsrcop = ST1; - fptemp = ST0; - ST1 = atan2(fpsrcop,fptemp); - fpop(); -} - -void helper_fxtract(void) -{ - CPU86_LDoubleU temp; - unsigned int expdif; - - temp.d = ST0; - expdif = EXPD(temp) - EXPBIAS; - /*DP exponent bias*/ - ST0 = expdif; - fpush(); - BIASEXPONENT(temp); - ST0 = temp.d; -} - -void helper_fprem1(void) -{ - CPU86_LDouble dblq, fpsrcop, fptemp; - CPU86_LDoubleU fpsrcop1, fptemp1; - int expdif; - signed long long int q; - - if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) { - ST0 = 0.0 / 0.0; /* NaN */ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - return; - } - - fpsrcop = ST0; - fptemp = ST1; - fpsrcop1.d = fpsrcop; - fptemp1.d = fptemp; - expdif = EXPD(fpsrcop1) - EXPD(fptemp1); - - if (expdif < 0) { - /* optimisation? taken from the AMD docs */ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - /* ST0 is unchanged */ - return; - } - - if (expdif < 53) { - dblq = fpsrcop / fptemp; - /* round dblq towards nearest integer */ - dblq = rint(dblq); - ST0 = fpsrcop - fptemp * dblq; - - /* convert dblq to q by truncating towards zero */ - if (dblq < 0.0) - q = (signed long long int)(-dblq); - else - q = (signed long long int)dblq; - - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - /* (C0,C3,C1) <-- (q2,q1,q0) */ - env->fpus |= (q & 0x4) << (8 - 2); /* (C0) <-- q2 */ - env->fpus |= (q & 0x2) << (14 - 1); /* (C3) <-- q1 */ - env->fpus |= (q & 0x1) << (9 - 0); /* (C1) <-- q0 */ - } else { - env->fpus |= 0x400; /* C2 <-- 1 */ - fptemp = pow(2.0, expdif - 50); - fpsrcop = (ST0 / ST1) / fptemp; - /* fpsrcop = integer obtained by chopping */ - fpsrcop = (fpsrcop < 0.0) ? - -(floor(fabs(fpsrcop))) : floor(fpsrcop); - ST0 -= (ST1 * fpsrcop * fptemp); - } -} - -void helper_fprem(void) -{ - CPU86_LDouble dblq, fpsrcop, fptemp; - CPU86_LDoubleU fpsrcop1, fptemp1; - int expdif; - signed long long int q; - - if (isinf(ST0) || isnan(ST0) || isnan(ST1) || (ST1 == 0.0)) { - ST0 = 0.0 / 0.0; /* NaN */ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - return; - } - - fpsrcop = (CPU86_LDouble)ST0; - fptemp = (CPU86_LDouble)ST1; - fpsrcop1.d = fpsrcop; - fptemp1.d = fptemp; - expdif = EXPD(fpsrcop1) - EXPD(fptemp1); - - if (expdif < 0) { - /* optimisation? taken from the AMD docs */ - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - /* ST0 is unchanged */ - return; - } - - if ( expdif < 53 ) { - dblq = fpsrcop/*ST0*/ / fptemp/*ST1*/; - /* round dblq towards zero */ - dblq = (dblq < 0.0) ? ceil(dblq) : floor(dblq); - ST0 = fpsrcop/*ST0*/ - fptemp * dblq; - - /* convert dblq to q by truncating towards zero */ - if (dblq < 0.0) - q = (signed long long int)(-dblq); - else - q = (signed long long int)dblq; - - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - /* (C0,C3,C1) <-- (q2,q1,q0) */ - env->fpus |= (q & 0x4) << (8 - 2); /* (C0) <-- q2 */ - env->fpus |= (q & 0x2) << (14 - 1); /* (C3) <-- q1 */ - env->fpus |= (q & 0x1) << (9 - 0); /* (C1) <-- q0 */ - } else { - int N = 32 + (expdif % 32); /* as per AMD docs */ - env->fpus |= 0x400; /* C2 <-- 1 */ - fptemp = pow(2.0, (double)(expdif - N)); - fpsrcop = (ST0 / ST1) / fptemp; - /* fpsrcop = integer obtained by chopping */ - fpsrcop = (fpsrcop < 0.0) ? - -(floor(fabs(fpsrcop))) : floor(fpsrcop); - ST0 -= (ST1 * fpsrcop * fptemp); - } -} - -void helper_fyl2xp1(void) -{ - CPU86_LDouble fptemp; - - fptemp = ST0; - if ((fptemp+1.0)>0.0) { - fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */ - ST1 *= fptemp; - fpop(); - } else { - env->fpus &= (~0x4700); - env->fpus |= 0x400; - } -} - -void helper_fsqrt(void) -{ - CPU86_LDouble fptemp; - - fptemp = ST0; - if (fptemp<0.0) { - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - env->fpus |= 0x400; - } - ST0 = sqrt(fptemp); -} - -void helper_fsincos(void) -{ - CPU86_LDouble fptemp; - - fptemp = ST0; - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { - env->fpus |= 0x400; - } else { - ST0 = sin(fptemp); - fpush(); - ST0 = cos(fptemp); - env->fpus &= (~0x400); /* C2 <-- 0 */ - /* the above code is for |arg| < 2**63 only */ - } -} - -void helper_frndint(void) -{ - ST0 = floatx_round_to_int(ST0, &env->fp_status); -} - -void helper_fscale(void) -{ - ST0 = ldexp (ST0, (int)(ST1)); -} - -void helper_fsin(void) -{ - CPU86_LDouble fptemp; - - fptemp = ST0; - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { - env->fpus |= 0x400; - } else { - ST0 = sin(fptemp); - env->fpus &= (~0x400); /* C2 <-- 0 */ - /* the above code is for |arg| < 2**53 only */ - } -} - -void helper_fcos(void) -{ - CPU86_LDouble fptemp; - - fptemp = ST0; - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { - env->fpus |= 0x400; - } else { - ST0 = cos(fptemp); - env->fpus &= (~0x400); /* C2 <-- 0 */ - /* the above code is for |arg5 < 2**63 only */ - } -} - -void helper_fxam_ST0(void) -{ - CPU86_LDoubleU temp; - int expdif; - - temp.d = ST0; - - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ - if (SIGND(temp)) - env->fpus |= 0x200; /* C1 <-- 1 */ - - /* XXX: test fptags too */ - expdif = EXPD(temp); - if (expdif == MAXEXPD) { -#ifdef USE_X86LDOUBLE - if (MANTD(temp) == 0x8000000000000000ULL) -#else - if (MANTD(temp) == 0) -#endif - env->fpus |= 0x500 /*Infinity*/; - else - env->fpus |= 0x100 /*NaN*/; - } else if (expdif == 0) { - if (MANTD(temp) == 0) - env->fpus |= 0x4000 /*Zero*/; - else - env->fpus |= 0x4400 /*Denormal*/; - } else { - env->fpus |= 0x400; - } -} - -void helper_fstenv(target_ulong ptr, int data32) -{ - int fpus, fptag, exp, i; - uint64_t mant; - CPU86_LDoubleU tmp; - - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; - fptag = 0; - for (i=7; i>=0; i--) { - fptag <<= 2; - if (env->fptags[i]) { - fptag |= 3; - } else { - tmp.d = env->fpregs[i].d; - exp = EXPD(tmp); - mant = MANTD(tmp); - if (exp == 0 && mant == 0) { - /* zero */ - fptag |= 1; - } else if (exp == 0 || exp == MAXEXPD -#ifdef USE_X86LDOUBLE - || (mant & (1LL << 63)) == 0 -#endif - ) { - /* NaNs, infinity, denormal */ - fptag |= 2; - } - } - } - if (data32) { - /* 32 bit */ - stl(ptr, env->fpuc); - stl(ptr + 4, fpus); - stl(ptr + 8, fptag); - stl(ptr + 12, 0); /* fpip */ - stl(ptr + 16, 0); /* fpcs */ - stl(ptr + 20, 0); /* fpoo */ - stl(ptr + 24, 0); /* fpos */ - } else { - /* 16 bit */ - stw(ptr, env->fpuc); - stw(ptr + 2, fpus); - stw(ptr + 4, fptag); - stw(ptr + 6, 0); - stw(ptr + 8, 0); - stw(ptr + 10, 0); - stw(ptr + 12, 0); - } -} - -void helper_fldenv(target_ulong ptr, int data32) -{ - int i, fpus, fptag; - - if (data32) { - env->fpuc = lduw(ptr); - fpus = lduw(ptr + 4); - fptag = lduw(ptr + 8); - } - else { - env->fpuc = lduw(ptr); - fpus = lduw(ptr + 2); - fptag = lduw(ptr + 4); - } - env->fpstt = (fpus >> 11) & 7; - env->fpus = fpus & ~0x3800; - for(i = 0;i < 8; i++) { - env->fptags[i] = ((fptag & 3) == 3); - fptag >>= 2; - } -} - -void helper_fsave(target_ulong ptr, int data32) -{ - CPU86_LDouble tmp; - int i; - - helper_fstenv(ptr, data32); - - ptr += (14 << data32); - for(i = 0;i < 8; i++) { - tmp = ST(i); - helper_fstt(tmp, ptr); - ptr += 10; - } - - /* fninit */ - env->fpus = 0; - env->fpstt = 0; - env->fpuc = 0x37f; - env->fptags[0] = 1; - env->fptags[1] = 1; - env->fptags[2] = 1; - env->fptags[3] = 1; - env->fptags[4] = 1; - env->fptags[5] = 1; - env->fptags[6] = 1; - env->fptags[7] = 1; -} - -void helper_frstor(target_ulong ptr, int data32) -{ - CPU86_LDouble tmp; - int i; - - helper_fldenv(ptr, data32); - ptr += (14 << data32); - - for(i = 0;i < 8; i++) { - tmp = helper_fldt(ptr); - ST(i) = tmp; - ptr += 10; - } -} - -void helper_fxsave(target_ulong ptr, int data64) -{ - int fpus, fptag, i, nb_xmm_regs; - CPU86_LDouble tmp; - target_ulong addr; - - /* The operand must be 16 byte aligned */ - if (ptr & 0xf) { - raise_exception(EXCP0D_GPF); - } - - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; - fptag = 0; - for(i = 0; i < 8; i++) { - fptag |= (env->fptags[i] << i); - } - stw(ptr, env->fpuc); - stw(ptr + 2, fpus); - stw(ptr + 4, fptag ^ 0xff); -#ifdef TARGET_X86_64 - if (data64) { - stq(ptr + 0x08, 0); /* rip */ - stq(ptr + 0x10, 0); /* rdp */ - } else -#endif - { - stl(ptr + 0x08, 0); /* eip */ - stl(ptr + 0x0c, 0); /* sel */ - stl(ptr + 0x10, 0); /* dp */ - stl(ptr + 0x14, 0); /* sel */ - } - - addr = ptr + 0x20; - for(i = 0;i < 8; i++) { - tmp = ST(i); - helper_fstt(tmp, addr); - addr += 16; - } - - if (env->cr[4] & CR4_OSFXSR_MASK) { - /* XXX: finish it */ - stl(ptr + 0x18, env->mxcsr); /* mxcsr */ - stl(ptr + 0x1c, 0x0000ffff); /* mxcsr_mask */ - if (env->hflags & HF_CS64_MASK) - nb_xmm_regs = 16; - else - nb_xmm_regs = 8; - addr = ptr + 0xa0; - /* Fast FXSAVE leaves out the XMM registers */ - if (!(env->efer & MSR_EFER_FFXSR) - || (env->hflags & HF_CPL_MASK) - || !(env->hflags & HF_LMA_MASK)) { - for(i = 0; i < nb_xmm_regs; i++) { - stq(addr, env->xmm_regs[i].XMM_Q(0)); - stq(addr + 8, env->xmm_regs[i].XMM_Q(1)); - addr += 16; - } - } - } -} - -void helper_fxrstor(target_ulong ptr, int data64) -{ - int i, fpus, fptag, nb_xmm_regs; - CPU86_LDouble tmp; - target_ulong addr; - - /* The operand must be 16 byte aligned */ - if (ptr & 0xf) { - raise_exception(EXCP0D_GPF); - } - - env->fpuc = lduw(ptr); - fpus = lduw(ptr + 2); - fptag = lduw(ptr + 4); - env->fpstt = (fpus >> 11) & 7; - env->fpus = fpus & ~0x3800; - fptag ^= 0xff; - for(i = 0;i < 8; i++) { - env->fptags[i] = ((fptag >> i) & 1); - } - - addr = ptr + 0x20; - for(i = 0;i < 8; i++) { - tmp = helper_fldt(addr); - ST(i) = tmp; - addr += 16; - } - - if (env->cr[4] & CR4_OSFXSR_MASK) { - /* XXX: finish it */ - env->mxcsr = ldl(ptr + 0x18); - //ldl(ptr + 0x1c); - if (env->hflags & HF_CS64_MASK) - nb_xmm_regs = 16; - else - nb_xmm_regs = 8; - addr = ptr + 0xa0; - /* Fast FXRESTORE leaves out the XMM registers */ - if (!(env->efer & MSR_EFER_FFXSR) - || (env->hflags & HF_CPL_MASK) - || !(env->hflags & HF_LMA_MASK)) { - for(i = 0; i < nb_xmm_regs; i++) { - env->xmm_regs[i].XMM_Q(0) = ldq(addr); - env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8); - addr += 16; - } - } - } -} - -#ifndef USE_X86LDOUBLE - -void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f) -{ - CPU86_LDoubleU temp; - int e; - - temp.d = f; - /* mantissa */ - *pmant = (MANTD(temp) << 11) | (1LL << 63); - /* exponent + sign */ - e = EXPD(temp) - EXPBIAS + 16383; - e |= SIGND(temp) >> 16; - *pexp = e; -} - -CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper) -{ - CPU86_LDoubleU temp; - int e; - uint64_t ll; - - /* XXX: handle overflow ? */ - e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ - e |= (upper >> 4) & 0x800; /* sign */ - ll = (mant >> 11) & ((1LL << 52) - 1); -#ifdef __arm__ - temp.l.upper = (e << 20) | (ll >> 32); - temp.l.lower = ll; -#else - temp.ll = ll | ((uint64_t)e << 52); -#endif - return temp.d; -} - -#else - -void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f) -{ - CPU86_LDoubleU temp; - - temp.d = f; - *pmant = temp.l.lower; - *pexp = temp.l.upper; -} - -CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper) -{ - CPU86_LDoubleU temp; - - temp.l.upper = upper; - temp.l.lower = mant; - return temp.d; -} -#endif - -#ifdef TARGET_X86_64 - -//#define DEBUG_MULDIV - -static void add128(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) -{ - *plow += a; - /* carry test */ - if (*plow < a) - (*phigh)++; - *phigh += b; -} - -static void neg128(uint64_t *plow, uint64_t *phigh) -{ - *plow = ~ *plow; - *phigh = ~ *phigh; - add128(plow, phigh, 1, 0); -} - -/* return TRUE if overflow */ -static int div64(uint64_t *plow, uint64_t *phigh, uint64_t b) -{ - uint64_t q, r, a1, a0; - int i, qb, ab; - - a0 = *plow; - a1 = *phigh; - if (a1 == 0) { - q = a0 / b; - r = a0 % b; - *plow = q; - *phigh = r; - } else { - if (a1 >= b) - return 1; - /* XXX: use a better algorithm */ - for(i = 0; i < 64; i++) { - ab = a1 >> 63; - a1 = (a1 << 1) | (a0 >> 63); - if (ab || a1 >= b) { - a1 -= b; - qb = 1; - } else { - qb = 0; - } - a0 = (a0 << 1) | qb; - } -#if defined(DEBUG_MULDIV) - printf("div: 0x%016" PRIx64 "%016" PRIx64 " / 0x%016" PRIx64 ": q=0x%016" PRIx64 " r=0x%016" PRIx64 "\n", - *phigh, *plow, b, a0, a1); -#endif - *plow = a0; - *phigh = a1; - } - return 0; -} - -/* return TRUE if overflow */ -static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b) -{ - int sa, sb; - sa = ((int64_t)*phigh < 0); - if (sa) - neg128(plow, phigh); - sb = (b < 0); - if (sb) - b = -b; - if (div64(plow, phigh, b) != 0) - return 1; - if (sa ^ sb) { - if (*plow > (1ULL << 63)) - return 1; - *plow = - *plow; - } else { - if (*plow >= (1ULL << 63)) - return 1; - } - if (sa) - *phigh = - *phigh; - return 0; -} - -void helper_mulq_EAX_T0(target_ulong t0) -{ - uint64_t r0, r1; - - mulu64(&r0, &r1, EAX, t0); - EAX = r0; - EDX = r1; - CC_DST = r0; - CC_SRC = r1; -} - -void helper_imulq_EAX_T0(target_ulong t0) -{ - uint64_t r0, r1; - - muls64(&r0, &r1, EAX, t0); - EAX = r0; - EDX = r1; - CC_DST = r0; - CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); -} - -target_ulong helper_imulq_T0_T1(target_ulong t0, target_ulong t1) -{ - uint64_t r0, r1; - - muls64(&r0, &r1, t0, t1); - CC_DST = r0; - CC_SRC = ((int64_t)r1 != ((int64_t)r0 >> 63)); - return r0; -} - -void helper_divq_EAX(target_ulong t0) -{ - uint64_t r0, r1; - if (t0 == 0) { - raise_exception(EXCP00_DIVZ); - } - r0 = EAX; - r1 = EDX; - if (div64(&r0, &r1, t0)) - raise_exception(EXCP00_DIVZ); - EAX = r0; - EDX = r1; -} - -void helper_idivq_EAX(target_ulong t0) -{ - uint64_t r0, r1; - if (t0 == 0) { - raise_exception(EXCP00_DIVZ); - } - r0 = EAX; - r1 = EDX; - if (idiv64(&r0, &r1, t0)) - raise_exception(EXCP00_DIVZ); - EAX = r0; - EDX = r1; -} -#endif - -static void do_hlt(void) -{ - env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ - env->halted = 1; - env->exception_index = EXCP_HLT; - cpu_loop_exit(); -} - -void helper_hlt(int next_eip_addend) -{ - helper_svm_check_intercept_param(SVM_EXIT_HLT, 0); - EIP += next_eip_addend; - - do_hlt(); -} - -void helper_monitor(target_ulong ptr) -{ - if ((uint32_t)ECX != 0) - raise_exception(EXCP0D_GPF); - /* XXX: store address ? */ - helper_svm_check_intercept_param(SVM_EXIT_MONITOR, 0); -} - -void helper_mwait(int next_eip_addend) -{ - if ((uint32_t)ECX != 0) - raise_exception(EXCP0D_GPF); - helper_svm_check_intercept_param(SVM_EXIT_MWAIT, 0); - EIP += next_eip_addend; - - /* XXX: not complete but not completely erroneous */ - if (env->cpu_index != 0 || env->next_cpu != NULL) { - /* more than one CPU: do not sleep because another CPU may - wake this one */ - } else { - do_hlt(); - } -} - -void helper_debug(void) -{ - env->exception_index = EXCP_DEBUG; - cpu_loop_exit(); -} - -void helper_reset_rf(void) -{ - env->eflags &= ~RF_MASK; -} - -void helper_raise_interrupt(int intno, int next_eip_addend) -{ - raise_interrupt(intno, 1, 0, next_eip_addend); -} - -void helper_raise_exception(int exception_index) -{ - raise_exception(exception_index); -} - -void helper_cli(void) -{ - env->eflags &= ~IF_MASK; -} - -void helper_sti(void) -{ - env->eflags |= IF_MASK; -} - -#if 0 -/* vm86plus instructions */ -void helper_cli_vm(void) -{ - env->eflags &= ~VIF_MASK; -} - -void helper_sti_vm(void) -{ - env->eflags |= VIF_MASK; - if (env->eflags & VIP_MASK) { - raise_exception(EXCP0D_GPF); - } -} -#endif - -void helper_set_inhibit_irq(void) -{ - env->hflags |= HF_INHIBIT_IRQ_MASK; -} - -void helper_reset_inhibit_irq(void) -{ - env->hflags &= ~HF_INHIBIT_IRQ_MASK; -} - -void helper_boundw(target_ulong a0, int v) -{ - int low, high; - low = ldsw(a0); - high = ldsw(a0 + 2); - v = (int16_t)v; - if (v < low || v > high) { - raise_exception(EXCP05_BOUND); - } -} - -void helper_boundl(target_ulong a0, int v) -{ - int low, high; - low = ldl(a0); - high = ldl(a0 + 4); - if (v < low || v > high) { - raise_exception(EXCP05_BOUND); - } -} - -static float approx_rsqrt(float a) -{ - return 1.0 / sqrt(a); -} - -static float approx_rcp(float a) -{ - return 1.0 / a; -} - -#if !defined(CONFIG_USER_ONLY) - -#define MMUSUFFIX _mmu - -#define SHIFT 0 -#include "softmmu_template.h" - -#define SHIFT 1 -#include "softmmu_template.h" - -#define SHIFT 2 -#include "softmmu_template.h" - -#define SHIFT 3 -#include "softmmu_template.h" - -#endif - -void helper_int99(void); -void helper_int99(void) -{ - regs_to_env(); -#ifndef _WIN32 - //helper_opengl(env); -#endif - env_to_regs(); -} - -#if !defined(CONFIG_USER_ONLY) -/* try to fill the TLB and return an exception if error. If retaddr is - NULL, it means that the function was called in C code (i.e. not - from generated code or from helper.c) */ -/* XXX: fix it to restore all registers */ -void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) -{ - TranslationBlock *tb; - int ret; - unsigned long pc; - CPUX86State *saved_env; - - /* XXX: hack to restore env in all cases, even if not called from - generated code */ - saved_env = env; - env = cpu_single_env; - - ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); - if (ret) { - if (retaddr) { - /* now we have a real cpu fault */ - pc = (unsigned long)retaddr; - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); - } - } - raise_exception_err(env->exception_index, env->error_code); - } - env = saved_env; -} -#endif - -/* Secure Virtual Machine helpers */ - -#if defined(CONFIG_USER_ONLY) - -void helper_vmrun(int aflag, int next_eip_addend) -{ -} -void helper_vmmcall(void) -{ -} -void helper_vmload(int aflag) -{ -} -void helper_vmsave(int aflag) -{ -} -void helper_stgi(void) -{ -} -void helper_clgi(void) -{ -} -void helper_skinit(void) -{ -} -void helper_invlpga(int aflag) -{ -} -void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) -{ -} -void helper_svm_check_intercept_param(uint32_t type, uint64_t param) -{ -} - -void helper_svm_check_io(uint32_t port, uint32_t param, - uint32_t next_eip_addend) -{ -} -#else - -static inline void svm_save_seg(target_phys_addr_t addr, - const SegmentCache *sc) -{ - stw_phys(addr + offsetof(struct vmcb_seg, selector), - sc->selector); - stq_phys(addr + offsetof(struct vmcb_seg, base), - sc->base); - stl_phys(addr + offsetof(struct vmcb_seg, limit), - sc->limit); - stw_phys(addr + offsetof(struct vmcb_seg, attrib), - ((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00)); -} - -static inline void svm_load_seg(target_phys_addr_t addr, SegmentCache *sc) -{ - unsigned int flags; - - sc->selector = lduw_phys(addr + offsetof(struct vmcb_seg, selector)); - sc->base = ldq_phys(addr + offsetof(struct vmcb_seg, base)); - sc->limit = ldl_phys(addr + offsetof(struct vmcb_seg, limit)); - flags = lduw_phys(addr + offsetof(struct vmcb_seg, attrib)); - sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12); -} - -static inline void svm_load_seg_cache(target_phys_addr_t addr, - CPUState *env, int seg_reg) -{ - SegmentCache sc1, *sc = &sc1; - svm_load_seg(addr, sc); - cpu_x86_load_seg_cache(env, seg_reg, sc->selector, - sc->base, sc->limit, sc->flags); -} - -void helper_vmrun(int aflag, int next_eip_addend) -{ - target_ulong addr; - uint32_t event_inj; - uint32_t int_ctl; - - helper_svm_check_intercept_param(SVM_EXIT_VMRUN, 0); - - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; - - qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr); - - env->vm_vmcb = addr; - - /* save the current CPU state in the hsave page */ - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base); - stl_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit), env->gdt.limit); - - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.base), env->idt.base); - stl_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.limit), env->idt.limit); - - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0), env->cr[0]); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]); - - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer), env->efer); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags), compute_eflags()); - - svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.es), - &env->segs[R_ES]); - svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.cs), - &env->segs[R_CS]); - svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ss), - &env->segs[R_SS]); - svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ds), - &env->segs[R_DS]); - - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip), - EIP + next_eip_addend); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP); - stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX); - - /* load the interception bitmaps so we do not need to access the - vmcb in svm mode */ - env->intercept = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept)); - env->intercept_cr_read = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_cr_read)); - env->intercept_cr_write = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_cr_write)); - env->intercept_dr_read = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_dr_read)); - env->intercept_dr_write = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_dr_write)); - env->intercept_exceptions = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_exceptions)); - - /* enable intercepts */ - env->hflags |= HF_SVMI_MASK; - - env->tsc_offset = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.tsc_offset)); - - env->gdt.base = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base)); - env->gdt.limit = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit)); - - env->idt.base = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.base)); - env->idt.limit = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit)); - - /* clear exit_info_2 so we behave like the real hardware */ - stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0); - - cpu_x86_update_cr0(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr0))); - cpu_x86_update_cr4(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4))); - cpu_x86_update_cr3(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3))); - env->cr[2] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2)); - int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); - env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK); - if (int_ctl & V_INTR_MASKING_MASK) { - env->v_tpr = int_ctl & V_TPR_MASK; - env->hflags2 |= HF2_VINTR_MASK; - if (env->eflags & IF_MASK) - env->hflags2 |= HF2_HIF_MASK; - } - - cpu_load_efer(env, - ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer))); - env->eflags = 0; - load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)), - ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); - CC_OP = CC_OP_EFLAGS; - - svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.es), - env, R_ES); - svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.cs), - env, R_CS); - svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.ss), - env, R_SS); - svm_load_seg_cache(env->vm_vmcb + offsetof(struct vmcb, save.ds), - env, R_DS); - - EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip)); - env->eip = EIP; - ESP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp)); - EAX = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax)); - env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7)); - env->dr[6] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6)); - cpu_x86_set_cpl(env, ldub_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl))); - - /* FIXME: guest state consistency checks */ - - switch(ldub_phys(env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) { - case TLB_CONTROL_DO_NOTHING: - break; - case TLB_CONTROL_FLUSH_ALL_ASID: - /* FIXME: this is not 100% correct but should work for now */ - tlb_flush(env, 1); - break; - } - - env->hflags2 |= HF2_GIF_MASK; - - if (int_ctl & V_IRQ_MASK) { - env->interrupt_request |= CPU_INTERRUPT_VIRQ; - } - - /* maybe we need to inject an event */ - event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); - if (event_inj & SVM_EVTINJ_VALID) { - uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK; - uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR; - uint32_t event_inj_err = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err)); - - qemu_log_mask(CPU_LOG_TB_IN_ASM, "Injecting(%#hx): ", valid_err); - /* FIXME: need to implement valid_err */ - switch (event_inj & SVM_EVTINJ_TYPE_MASK) { - case SVM_EVTINJ_TYPE_INTR: - env->exception_index = vector; - env->error_code = event_inj_err; - env->exception_is_int = 0; - env->exception_next_eip = -1; - qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR"); - /* XXX: is it always correct ? */ - do_interrupt(vector, 0, 0, 0, 1); - break; - case SVM_EVTINJ_TYPE_NMI: - env->exception_index = EXCP02_NMI; - env->error_code = event_inj_err; - env->exception_is_int = 0; - env->exception_next_eip = EIP; - qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI"); - cpu_loop_exit(); - break; - case SVM_EVTINJ_TYPE_EXEPT: - env->exception_index = vector; - env->error_code = event_inj_err; - env->exception_is_int = 0; - env->exception_next_eip = -1; - qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT"); - cpu_loop_exit(); - break; - case SVM_EVTINJ_TYPE_SOFT: - env->exception_index = vector; - env->error_code = event_inj_err; - env->exception_is_int = 1; - env->exception_next_eip = EIP; - qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT"); - cpu_loop_exit(); - break; - } - qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index, env->error_code); - } -} - -void helper_vmmcall(void) -{ - helper_svm_check_intercept_param(SVM_EXIT_VMMCALL, 0); - raise_exception(EXCP06_ILLOP); -} - -void helper_vmload(int aflag) -{ - target_ulong addr; - helper_svm_check_intercept_param(SVM_EXIT_VMLOAD, 0); - - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; - - qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", - addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), - env->segs[R_FS].base); - - svm_load_seg_cache(addr + offsetof(struct vmcb, save.fs), - env, R_FS); - svm_load_seg_cache(addr + offsetof(struct vmcb, save.gs), - env, R_GS); - svm_load_seg(addr + offsetof(struct vmcb, save.tr), - &env->tr); - svm_load_seg(addr + offsetof(struct vmcb, save.ldtr), - &env->ldt); - -#ifdef TARGET_X86_64 - env->kernelgsbase = ldq_phys(addr + offsetof(struct vmcb, save.kernel_gs_base)); - env->lstar = ldq_phys(addr + offsetof(struct vmcb, save.lstar)); - env->cstar = ldq_phys(addr + offsetof(struct vmcb, save.cstar)); - env->fmask = ldq_phys(addr + offsetof(struct vmcb, save.sfmask)); -#endif - env->star = ldq_phys(addr + offsetof(struct vmcb, save.star)); - env->sysenter_cs = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_cs)); - env->sysenter_esp = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_esp)); - env->sysenter_eip = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_eip)); -} - -void helper_vmsave(int aflag) -{ - target_ulong addr; - helper_svm_check_intercept_param(SVM_EXIT_VMSAVE, 0); - - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; - - qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", - addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), - env->segs[R_FS].base); - - svm_save_seg(addr + offsetof(struct vmcb, save.fs), - &env->segs[R_FS]); - svm_save_seg(addr + offsetof(struct vmcb, save.gs), - &env->segs[R_GS]); - svm_save_seg(addr + offsetof(struct vmcb, save.tr), - &env->tr); - svm_save_seg(addr + offsetof(struct vmcb, save.ldtr), - &env->ldt); - -#ifdef TARGET_X86_64 - stq_phys(addr + offsetof(struct vmcb, save.kernel_gs_base), env->kernelgsbase); - stq_phys(addr + offsetof(struct vmcb, save.lstar), env->lstar); - stq_phys(addr + offsetof(struct vmcb, save.cstar), env->cstar); - stq_phys(addr + offsetof(struct vmcb, save.sfmask), env->fmask); -#endif - stq_phys(addr + offsetof(struct vmcb, save.star), env->star); - stq_phys(addr + offsetof(struct vmcb, save.sysenter_cs), env->sysenter_cs); - stq_phys(addr + offsetof(struct vmcb, save.sysenter_esp), env->sysenter_esp); - stq_phys(addr + offsetof(struct vmcb, save.sysenter_eip), env->sysenter_eip); -} - -void helper_stgi(void) -{ - helper_svm_check_intercept_param(SVM_EXIT_STGI, 0); - env->hflags2 |= HF2_GIF_MASK; -} - -void helper_clgi(void) -{ - helper_svm_check_intercept_param(SVM_EXIT_CLGI, 0); - env->hflags2 &= ~HF2_GIF_MASK; -} - -void helper_skinit(void) -{ - helper_svm_check_intercept_param(SVM_EXIT_SKINIT, 0); - /* XXX: not implemented */ - raise_exception(EXCP06_ILLOP); -} - -void helper_invlpga(int aflag) -{ - target_ulong addr; - helper_svm_check_intercept_param(SVM_EXIT_INVLPGA, 0); - - if (aflag == 2) - addr = EAX; - else - addr = (uint32_t)EAX; - - /* XXX: could use the ASID to see if it is needed to do the - flush */ - tlb_flush_page(env, addr); -} - -void helper_svm_check_intercept_param(uint32_t type, uint64_t param) -{ - if (likely(!(env->hflags & HF_SVMI_MASK))) - return; - switch(type) { - case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8: - if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) { - helper_vmexit(type, param); - } - break; - case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8: - if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) { - helper_vmexit(type, param); - } - break; - case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7: - if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) { - helper_vmexit(type, param); - } - break; - case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7: - if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) { - helper_vmexit(type, param); - } - break; - case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31: - if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) { - helper_vmexit(type, param); - } - break; - case SVM_EXIT_MSR: - if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) { - /* FIXME: this should be read in at vmrun (faster this way?) */ - uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.msrpm_base_pa)); - uint32_t t0, t1; - switch((uint32_t)ECX) { - case 0 ... 0x1fff: - t0 = (ECX * 2) % 8; - t1 = ECX / 8; - break; - case 0xc0000000 ... 0xc0001fff: - t0 = (8192 + ECX - 0xc0000000) * 2; - t1 = (t0 / 8); - t0 %= 8; - break; - case 0xc0010000 ... 0xc0011fff: - t0 = (16384 + ECX - 0xc0010000) * 2; - t1 = (t0 / 8); - t0 %= 8; - break; - default: - helper_vmexit(type, param); - t0 = 0; - t1 = 0; - break; - } - if (ldub_phys(addr + t1) & ((1 << param) << t0)) - helper_vmexit(type, param); - } - break; - default: - if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) { - helper_vmexit(type, param); - } - break; - } -} - -void helper_svm_check_io(uint32_t port, uint32_t param, - uint32_t next_eip_addend) -{ - if (env->intercept & (1ULL << (SVM_EXIT_IOIO - SVM_EXIT_INTR))) { - /* FIXME: this should be read in at vmrun (faster this way?) */ - uint64_t addr = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa)); - uint16_t mask = (1 << ((param >> 4) & 7)) - 1; - if(lduw_phys(addr + port / 8) & (mask << (port & 7))) { - /* next EIP */ - stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), - env->eip + next_eip_addend); - helper_vmexit(SVM_EXIT_IOIO, param | (port << 16)); - } - } -} - -/* Note: currently only 32 bits of exit_code are used */ -void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) -{ - uint32_t int_ctl; - - qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n", - exit_code, exit_info_1, - ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2)), - EIP); - - if(env->hflags & HF_INHIBIT_IRQ_MASK) { - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), SVM_INTERRUPT_SHADOW_MASK); - env->hflags &= ~HF_INHIBIT_IRQ_MASK; - } else { - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_state), 0); - } - - /* Save the VM state in the vmcb */ - svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.es), - &env->segs[R_ES]); - svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.cs), - &env->segs[R_CS]); - svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.ss), - &env->segs[R_SS]); - svm_save_seg(env->vm_vmcb + offsetof(struct vmcb, save.ds), - &env->segs[R_DS]); - - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base), env->gdt.base); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit), env->gdt.limit); - - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.base), env->idt.base); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit), env->idt.limit); - - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer), env->efer); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr0), env->cr[0]); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2), env->cr[2]); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]); - - int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); - int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK); - int_ctl |= env->v_tpr & V_TPR_MASK; - if (env->interrupt_request & CPU_INTERRUPT_VIRQ) - int_ctl |= V_IRQ_MASK; - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl); - - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags), compute_eflags()); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip), env->eip); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp), ESP); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax), EAX); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7), env->dr[7]); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6), env->dr[6]); - stb_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl), env->hflags & HF_CPL_MASK); - - /* Reload the host state from vm_hsave */ - env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK); - env->hflags &= ~HF_SVMI_MASK; - env->intercept = 0; - env->intercept_exceptions = 0; - env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; - env->tsc_offset = 0; - - env->gdt.base = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base)); - env->gdt.limit = ldl_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit)); - - env->idt.base = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.base)); - env->idt.limit = ldl_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.limit)); - - cpu_x86_update_cr0(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0)) | CR0_PE_MASK); - cpu_x86_update_cr4(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4))); - cpu_x86_update_cr3(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3))); - /* we need to set the efer after the crs so the hidden flags get - set properly */ - cpu_load_efer(env, - ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer))); - env->eflags = 0; - load_eflags(ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags)), - ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); - CC_OP = CC_OP_EFLAGS; - - svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.es), - env, R_ES); - svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.cs), - env, R_CS); - svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.ss), - env, R_SS); - svm_load_seg_cache(env->vm_hsave + offsetof(struct vmcb, save.ds), - env, R_DS); - - EIP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip)); - ESP = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp)); - EAX = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax)); - - env->dr[6] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6)); - env->dr[7] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7)); - - /* other setups */ - cpu_x86_set_cpl(env, 0); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code); - stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1); - - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info), - ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj))); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err), - ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err))); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0); - - env->hflags2 &= ~HF2_GIF_MASK; - /* FIXME: Resets the current ASID register to zero (host ASID). */ - - /* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */ - - /* Clears the TSC_OFFSET inside the processor. */ - - /* If the host is in PAE mode, the processor reloads the host's PDPEs - from the page table indicated the host's CR3. If the PDPEs contain - illegal state, the processor causes a shutdown. */ - - /* Forces CR0.PE = 1, RFLAGS.VM = 0. */ - env->cr[0] |= CR0_PE_MASK; - env->eflags &= ~VM_MASK; - - /* Disables all breakpoints in the host DR7 register. */ - - /* Checks the reloaded host state for consistency. */ - - /* If the host's rIP reloaded by #VMEXIT is outside the limit of the - host's code segment or non-canonical (in the case of long mode), a - #GP fault is delivered inside the host.) */ - - /* remove any pending exception */ - env->exception_index = -1; - env->error_code = 0; - env->old_exception = -1; - - cpu_loop_exit(); -} - -#endif - -/* MMX/SSE */ -/* XXX: optimize by storing fptt and fptags in the static cpu state */ -void helper_enter_mmx(void) -{ - env->fpstt = 0; - *(uint32_t *)(env->fptags) = 0; - *(uint32_t *)(env->fptags + 4) = 0; -} - -void helper_emms(void) -{ - /* set to empty state */ - *(uint32_t *)(env->fptags) = 0x01010101; - *(uint32_t *)(env->fptags + 4) = 0x01010101; -} - -/* XXX: suppress */ -void helper_movq(void *d, void *s) -{ - *(uint64_t *)d = *(uint64_t *)s; -} - -#define SHIFT 0 -#include "ops_sse.h" - -#define SHIFT 1 -#include "ops_sse.h" - -#define SHIFT 0 -#include "helper_template.h" -#undef SHIFT - -#define SHIFT 1 -#include "helper_template.h" -#undef SHIFT - -#define SHIFT 2 -#include "helper_template.h" -#undef SHIFT - -#ifdef TARGET_X86_64 - -#define SHIFT 3 -#include "helper_template.h" -#undef SHIFT - -#endif - -/* bit operations */ -target_ulong helper_bsf(target_ulong t0) -{ - int count; - target_ulong res; - - res = t0; - count = 0; - while ((res & 1) == 0) { - count++; - res >>= 1; - } - return count; -} - -target_ulong helper_lzcnt(target_ulong t0, int wordsize) -{ - int count; - target_ulong res, mask; - - if (wordsize > 0 && t0 == 0) { - return wordsize; - } - res = t0; - count = TARGET_LONG_BITS - 1; - mask = (target_ulong)1 << (TARGET_LONG_BITS - 1); - while ((res & mask) == 0) { - count--; - res <<= 1; - } - if (wordsize > 0) { - return wordsize - 1 - count; - } - return count; -} - -target_ulong helper_bsr(target_ulong t0) -{ - return helper_lzcnt(t0, 0); -} - -static int compute_all_eflags(void) -{ - return CC_SRC; -} - -static int compute_c_eflags(void) -{ - return CC_SRC & CC_C; -} - -uint32_t helper_cc_compute_all(int op) -{ - switch (op) { - default: /* should never happen */ return 0; - - case CC_OP_EFLAGS: return compute_all_eflags(); - - case CC_OP_MULB: return compute_all_mulb(); - case CC_OP_MULW: return compute_all_mulw(); - case CC_OP_MULL: return compute_all_mull(); - - case CC_OP_ADDB: return compute_all_addb(); - case CC_OP_ADDW: return compute_all_addw(); - case CC_OP_ADDL: return compute_all_addl(); - - case CC_OP_ADCB: return compute_all_adcb(); - case CC_OP_ADCW: return compute_all_adcw(); - case CC_OP_ADCL: return compute_all_adcl(); - - case CC_OP_SUBB: return compute_all_subb(); - case CC_OP_SUBW: return compute_all_subw(); - case CC_OP_SUBL: return compute_all_subl(); - - case CC_OP_SBBB: return compute_all_sbbb(); - case CC_OP_SBBW: return compute_all_sbbw(); - case CC_OP_SBBL: return compute_all_sbbl(); - - case CC_OP_LOGICB: return compute_all_logicb(); - case CC_OP_LOGICW: return compute_all_logicw(); - case CC_OP_LOGICL: return compute_all_logicl(); - - case CC_OP_INCB: return compute_all_incb(); - case CC_OP_INCW: return compute_all_incw(); - case CC_OP_INCL: return compute_all_incl(); - - case CC_OP_DECB: return compute_all_decb(); - case CC_OP_DECW: return compute_all_decw(); - case CC_OP_DECL: return compute_all_decl(); - - case CC_OP_SHLB: return compute_all_shlb(); - case CC_OP_SHLW: return compute_all_shlw(); - case CC_OP_SHLL: return compute_all_shll(); - - case CC_OP_SARB: return compute_all_sarb(); - case CC_OP_SARW: return compute_all_sarw(); - case CC_OP_SARL: return compute_all_sarl(); - -#ifdef TARGET_X86_64 - case CC_OP_MULQ: return compute_all_mulq(); - - case CC_OP_ADDQ: return compute_all_addq(); - - case CC_OP_ADCQ: return compute_all_adcq(); - - case CC_OP_SUBQ: return compute_all_subq(); - - case CC_OP_SBBQ: return compute_all_sbbq(); - - case CC_OP_LOGICQ: return compute_all_logicq(); - - case CC_OP_INCQ: return compute_all_incq(); - - case CC_OP_DECQ: return compute_all_decq(); - - case CC_OP_SHLQ: return compute_all_shlq(); - - case CC_OP_SARQ: return compute_all_sarq(); -#endif - } -} - -uint32_t helper_cc_compute_c(int op) -{ - switch (op) { - default: /* should never happen */ return 0; - - case CC_OP_EFLAGS: return compute_c_eflags(); - - case CC_OP_MULB: return compute_c_mull(); - case CC_OP_MULW: return compute_c_mull(); - case CC_OP_MULL: return compute_c_mull(); - - case CC_OP_ADDB: return compute_c_addb(); - case CC_OP_ADDW: return compute_c_addw(); - case CC_OP_ADDL: return compute_c_addl(); - - case CC_OP_ADCB: return compute_c_adcb(); - case CC_OP_ADCW: return compute_c_adcw(); - case CC_OP_ADCL: return compute_c_adcl(); - - case CC_OP_SUBB: return compute_c_subb(); - case CC_OP_SUBW: return compute_c_subw(); - case CC_OP_SUBL: return compute_c_subl(); - - case CC_OP_SBBB: return compute_c_sbbb(); - case CC_OP_SBBW: return compute_c_sbbw(); - case CC_OP_SBBL: return compute_c_sbbl(); - - case CC_OP_LOGICB: return compute_c_logicb(); - case CC_OP_LOGICW: return compute_c_logicw(); - case CC_OP_LOGICL: return compute_c_logicl(); - - case CC_OP_INCB: return compute_c_incl(); - case CC_OP_INCW: return compute_c_incl(); - case CC_OP_INCL: return compute_c_incl(); - - case CC_OP_DECB: return compute_c_incl(); - case CC_OP_DECW: return compute_c_incl(); - case CC_OP_DECL: return compute_c_incl(); - - case CC_OP_SHLB: return compute_c_shlb(); - case CC_OP_SHLW: return compute_c_shlw(); - case CC_OP_SHLL: return compute_c_shll(); - - case CC_OP_SARB: return compute_c_sarl(); - case CC_OP_SARW: return compute_c_sarl(); - case CC_OP_SARL: return compute_c_sarl(); - -#ifdef TARGET_X86_64 - case CC_OP_MULQ: return compute_c_mull(); - - case CC_OP_ADDQ: return compute_c_addq(); - - case CC_OP_ADCQ: return compute_c_adcq(); - - case CC_OP_SUBQ: return compute_c_subq(); - - case CC_OP_SBBQ: return compute_c_sbbq(); - - case CC_OP_LOGICQ: return compute_c_logicq(); - - case CC_OP_INCQ: return compute_c_incl(); - - case CC_OP_DECQ: return compute_c_incl(); - - case CC_OP_SHLQ: return compute_c_shlq(); - - case CC_OP_SARQ: return compute_c_sarl(); -#endif - } -} diff --git a/target-i386/opengl32.def b/target-i386/opengl32.def deleted file mode 100755 index 531c2d4..0000000 --- a/target-i386/opengl32.def +++ /dev/null @@ -1,991 +0,0 @@ -DESCRIPTION 'OpenGL for QEMU for Win32' -VERSION 1.0 -; -; Module definition file for Mesa (OPENGL32.DLL) -; -; Note: The OpenGL functions use the STDCALL -; function calling convention. Microsoft's -; OPENGL32 uses this convention and so must the -; Mesa OPENGL32 so that the Mesa DLL can be used -; as a drop-in replacement. -; -; The linker exports STDCALL entry points with -; 'decorated' names; e.g., _glBegin@0, where the -; trailing number is the number of bytes of -; parameter data pushed onto the stack. The -; callee is responsible for popping this data -; off the stack, usually via a RETF n instruction. -; -; However, the Microsoft OPENGL32.DLL does not export -; the decorated names, even though the calling convention -; is STDCALL. So, this module definition file is -; needed to force the Mesa OPENGL32.DLL to export the -; symbols in the same manner as the Microsoft DLL. -; Were it not for this problem, this file would not -; be needed (for the gl* functions) since the entry -; points are compiled with dllexport declspec. -; -; However, this file is still needed to export "internal" -; Mesa symbols for the benefit of the OSMESA32.DLL. -; -EXPORTS -glAccum -glActiveStencilFaceEXT -glActiveTexture -glActiveTextureARB -glAlphaFragmentOp1ATI -glAlphaFragmentOp2ATI -glAlphaFragmentOp3ATI -glAlphaFunc -glApplyTextureEXT -glAreTexturesResident -glArrayElement -glArrayElementEXT -glArrayObjectATI -glAsyncMarkerSGIX -glAttachObjectARB -glBegin -glBeginFragmentShaderATI -glBeginOcclusionQueryNV -glBeginQueryARB -glBeginVertexShaderEXT -glBindAttribLocationARB -glBindBuffer -glBindBufferARB -glBindFragmentShaderATI -glBindFramebufferEXT -glBindLightParameterEXT -glBindMaterialParameterEXT -glBindParameterEXT -glBindProgramARB -glBindProgramNV -glBindRenderbufferEXT -glBindTexGenParameterEXT -glBindTexture -glBindTextureEXT -glBindTextureUnitParameterEXT -glBindVertexShaderEXT -glBinormal3bEXT -glBinormal3bvEXT -glBinormal3dEXT -glBinormal3dvEXT -glBinormal3fEXT -glBinormal3fvEXT -glBinormal3iEXT -glBinormal3ivEXT -glBinormal3sEXT -glBinormal3svEXT -glBitmap -glBlendColor -glBlendColorEXT -glBlendEquation -glBlendEquationEXT -glBlendEquationSeparateEXT -glBlendFunc -glBlendFuncSeparateEXT -glBlitFramebufferEXT -glBufferDataARB -glBufferSubDataARB -glCallList -glCallLists -glCheckFramebufferStatusEXT -glClampColorARB -glClear -glClearAccum -glClearColor -glClearDepth -glClearIndex -glClearStencil -glClientActiveTexture -glClientActiveTextureARB -glClientActiveVertexStreamATI -glClipPlane -glColor3b -glColor3bv -glColor3d -glColor3dv -glColor3f -glColor3fv -glColor3hNV -glColor3i -glColor3iv -glColor3s -glColor3sv -glColor3ub -glColor3ubv -glColor3ui -glColor3uiv -glColor3us -glColor3usv -glColor4b -glColor4bv -glColor4d -glColor4dv -glColor4f -glColor4fv -glColor4hNV -glColor4i -glColor4iv -glColor4s -glColor4sv -glColor4ub -glColor4ubv -glColor4ui -glColor4uiv -glColor4us -glColor4usv -glColorFragmentOp1ATI -glColorFragmentOp2ATI -glColorFragmentOp3ATI -glColorMask -glColorMaterial -glColorPointer -glCombinerInputNV -glCombinerOutputNV -glCombinerParameterfNV -glCombinerParameterfvNV -glCombinerParameteriNV -glCombinerParameterivNV -glCompileShaderARB -glCompressedTexImage1DARB -glCompressedTexImage2DARB -glCompressedTexImage3DARB -glCompressedTexSubImage1DARB -glCompressedTexSubImage2DARB -glCompressedTexSubImage3DARB -glConvolutionParameterf -glConvolutionParameterfEXT -glConvolutionParameteri -glConvolutionParameteriEXT -glCopyColorSubTable -glCopyColorSubTableEXT -glCopyColorTable -glCopyColorTableSGI -glCopyConvolutionFilter1D -glCopyConvolutionFilter1DEXT -glCopyConvolutionFilter2D -glCopyConvolutionFilter2DEXT -glCopyPixels -glCopyTexImage1D -glCopyTexImage1DEXT -glCopyTexImage2D -glCopyTexImage2DEXT -glCopyTexSubImage1D -glCopyTexSubImage1DEXT -glCopyTexSubImage2D -glCopyTexSubImage2DEXT -glCopyTexSubImage3D -glCopyTexSubImage3DEXT -glCreateProgramObjectARB -glCreateShaderObjectARB -glCullFace -glCurrentPaletteMatrixARB -glDeformSGIX -glDeleteAsyncMarkersSGIX -glDeleteBuffersARB -glDeleteFragmentShaderATI -glDeleteFramebuffersEXT -glDeleteLists -glDeleteObjectARB -glDeleteOcclusionQueriesNV -glDeleteProgramsARB -glDeleteRenderbuffersEXT -glDeleteTextures -glDeleteVertexShaderEXT -glDepthBoundsEXT -glDepthFunc -glDepthMask -glDepthRange -glDetachObjectARB -glDisable -glDisableClientState -glDisableVariantClientStateEXT -glDisableVertexAttribArrayARB -glDrawArrays -glDrawArraysEXT -glDrawBuffer -glDrawElementArrayATI -glDrawElements -glDrawPixels -glDrawRangeElementArrayATI -glDrawRangeElements -glEdgeFlag -glEdgeFlagPointer -glEdgeFlagv -glEnable -glEnableClientState -glEnableVariantClientStateEXT -glEnableVertexAttribArrayARB -glEnd -glEndFragmentShaderATI -glEndList -glEndOcclusionQueryNV -glEndQueryARB -glEndVertexShaderEXT -glEvalCoord1d -glEvalCoord1dv -glEvalCoord1f -glEvalCoord1fv -glEvalCoord2d -glEvalCoord2dv -glEvalCoord2f -glEvalCoord2fv -glEvalMapsNV -glEvalMesh1 -glEvalMesh2 -glEvalPoint1 -glEvalPoint2 -glExtractComponentEXT -glFeedbackBuffer -glFinalCombinerInputNV -glFinish -glFinishFenceNV -glFlush -glFlushPixelDataRangeNV -glFlushRasterSGIX -glFlushVertexArrayRangeNV -glFogCoorddEXT -glFogCoordfEXT -glFogCoordhNV -glFogf -glFogfv -glFogi -glFogiv -glFragmentColorMaterialSGIX -glFragmentLightfSGIX -glFragmentLightiSGIX -glFragmentLightModelfSGIX -glFragmentLightModeliSGIX -glFragmentMaterialfSGIX -glFragmentMaterialiSGIX -glFramebufferRenderbufferEXT -glFramebufferTexture1DEXT -glFramebufferTexture2DEXT -glFramebufferTexture3DEXT -glFrameZoomSGIX -glFreeObjectBufferATI -glFrontFace -glFrustum -glGenAsyncMarkersSGIX -glGenBuffersARB -glGenerateMipmapEXT -glGenFragmentShadersATI -glGenFramebuffersEXT -glGenLists -glGenOcclusionQueriesNV -glGenProgramsARB -glGenQueriesARB -glGenRenderbuffersEXT -glGenSymbolsEXT -glGenTextures -glGenVertexShadersEXT -glGetActiveAttribARB -glGetActiveUniformARB -glGetAttachedObjectsARB -glGetAttribLocationARB -glGetBooleanv -glGetBufferParameterivARB -glGetBufferPointervARB -glGetBufferSubDataARB -glGetClipPlane -glGetCombinerInputParameterfvNV -glGetCombinerInputParameterivNV -glGetCombinerOutputParameterfvNV -glGetCombinerOutputParameterivNV -glGetCompressedTexImageARB -glGetConvolutionParameteriv -glGetDoublev -glGetError -glGetFinalCombinerInputParameterfvNV -glGetFinalCombinerInputParameterivNV -glGetFloatv -glGetHandleARB -glGetInfoLogARB -glGetInstrumentsSGIX -glGetIntegerv -glGetLightfv -glGetLightiv -glGetMapdv -glGetMapfv -glGetMapiv -glGetMaterialfv -glGetMaterialiv -glGetObjectParameterfvARB -glGetObjectParameterivARB -glGetOcclusionQueryivNV -glGetOcclusionQueryuivNV -glGetPixelMapfv -glGetPixelMapuiv -glGetPixelMapusv -glGetPointerv -glGetPolygonStipple -glGetProgramEnvParameterdvARB -glGetProgramEnvParameterfvARB -glGetProgramivARB -glGetProgramLocalParameterdvARB -glGetProgramLocalParameterfvARB -glGetProgramStringARB -glGetQueryivARB -glGetQueryObjectivARB -glGetQueryObjectuivARB -glGetShaderSourceARB -glGetString -glGetTexEnvfv -glGetTexEnviv -glGetTexGendv -glGetTexGenfv -glGetTexGeniv -glGetTexImage -glGetTexLevelParameterfv -glGetTexLevelParameteriv -glGetTexParameterfv -glGetTexParameteriv -glGetUniformfvARB -glGetUniformivARB -glGetUniformLocationARB -glGetVertexAttribdvARB -glGetVertexAttribfvARB -glGetVertexAttribivARB -glGetVertexAttribPointervARB -glHint -glHistogram -glHistogramEXT -glIndexd -glIndexdv -glIndexf -glIndexFuncEXT -glIndexfv -glIndexi -glIndexiv -glIndexMask -glIndexMaterialEXT -glIndexPointer -glIndexs -glIndexsv -glIndexub -glIndexubv -glInitNames -glInsertComponentEXT -glInterleavedArrays -glIsAsyncMarkerSGIX -glIsBufferARB -glIsEnabled -glIsFenceNV -glIsFramebufferEXT -glIsList -glIsObjectBufferATI -glIsOcclusionQueryNV -glIsProgramARB -glIsProgramNV -glIsQueryARB -glIsRenderbufferEXT -glIsTexture -glIsTextureEXT -glIsVariantEnabledEXT -glLightEnviSGIX -glLightf -glLightfv -glLighti -glLightiv -glLightModelf -glLightModelfv -glLightModeli -glLightModeliv -glLineStipple -glLineWidth -glLinkProgramARB -glListBase -glListParameterfSGIX -glListParameteriSGIX -glLoadIdentity -glLoadIdentityDeformationMapSGIX -glLoadMatrixd -glLoadMatrixf -glLoadName -glLoadTransposeMatrixd -glLoadTransposeMatrixdARB -glLoadTransposeMatrixf -glLoadTransposeMatrixfARB -glLockArraysEXT -glLogicOp -glMap1d -glMap1f -glMap2d -glMap2f -glMapBufferARB -glMapGrid1d -glMapGrid1f -glMapGrid2d -glMapGrid2f -glMaterialf -glMaterialfv -glMateriali -glMaterialiv -glMatrixMode -glMinmax -glMinmaxEXT -glMultiTexCoord1d -glMultiTexCoord1dARB -glMultiTexCoord1dv -glMultiTexCoord1dvARB -glMultiTexCoord1f -glMultiTexCoord1fARB -glMultiTexCoord1fv -glMultiTexCoord1fvARB -glMultiTexCoord1hNV -glMultiTexCoord1i -glMultiTexCoord1iARB -glMultiTexCoord1iv -glMultiTexCoord1ivARB -glMultiTexCoord1s -glMultiTexCoord1sARB -glMultiTexCoord1sv -glMultiTexCoord1svARB -glMultiTexCoord2d -glMultiTexCoord2dARB -glMultiTexCoord2dv -glMultiTexCoord2dvARB -glMultiTexCoord2f -glMultiTexCoord2fARB -glMultiTexCoord2fv -glMultiTexCoord2fvARB -glMultiTexCoord2hNV -glMultiTexCoord2i -glMultiTexCoord2iARB -glMultiTexCoord2iv -glMultiTexCoord2ivARB -glMultiTexCoord2s -glMultiTexCoord2sARB -glMultiTexCoord2sv -glMultiTexCoord2svARB -glMultiTexCoord3d -glMultiTexCoord3dARB -glMultiTexCoord3dv -glMultiTexCoord3dvARB -glMultiTexCoord3f -glMultiTexCoord3fARB -glMultiTexCoord3fv -glMultiTexCoord3fvARB -glMultiTexCoord3hNV -glMultiTexCoord3i -glMultiTexCoord3iARB -glMultiTexCoord3iv -glMultiTexCoord3ivARB -glMultiTexCoord3s -glMultiTexCoord3sARB -glMultiTexCoord3sv -glMultiTexCoord3svARB -glMultiTexCoord4d -glMultiTexCoord4dARB -glMultiTexCoord4dv -glMultiTexCoord4dvARB -glMultiTexCoord4f -glMultiTexCoord4fARB -glMultiTexCoord4fv -glMultiTexCoord4fvARB -glMultiTexCoord4hNV -glMultiTexCoord4i -glMultiTexCoord4iARB -glMultiTexCoord4iv -glMultiTexCoord4ivARB -glMultiTexCoord4s -glMultiTexCoord4sARB -glMultiTexCoord4sv -glMultiTexCoord4svARB -glMultMatrixd -glMultMatrixf -glMultTransposeMatrixd -glMultTransposeMatrixdARB -glMultTransposeMatrixf -glMultTransposeMatrixfARB -glNewList -glNormal3b -glNormal3bv -glNormal3d -glNormal3dv -glNormal3f -glNormal3fv -glNormal3hNV -glNormal3i -glNormal3iv -glNormal3s -glNormal3sv -glNormalPointer -glNormalStream3bATI -glNormalStream3bvATI -glNormalStream3dATI -glNormalStream3dvATI -glNormalStream3fATI -glNormalStream3fvATI -glNormalStream3iATI -glNormalStream3ivATI -glNormalStream3sATI -glNormalStream3svATI -glOrtho -glPassTexCoordATI -glPassThrough -glPixelMapfv -glPixelMapuiv -glPixelMapusv -glPixelStoref -glPixelStorei -glPixelTexGenParameterfSGIS -glPixelTexGenParameteriSGIS -glPixelTexGenSGIX -glPixelTransferf -glPixelTransferi -glPixelTransformParameterfEXT -glPixelTransformParameteriEXT -glPixelZoom -glPNTrianglesfATI -glPNTrianglesiATI -glPointParameterfARB -glPointParameterfEXT -glPointParameterfSGIS -glPointParameterfvARB -glPointParameteriNV -glPointSize -glPolygonMode -glPolygonOffset -glPolygonOffsetEXT -glPolygonStipple -glPopAttrib -glPopClientAttrib -glPopMatrix -glPopName -glPrimitiveRestartIndexNV -glPrimitiveRestartNV -glPrioritizeTextures -glProgramEnvParameter4dARB -glProgramEnvParameter4dvARB -glProgramEnvParameter4fARB -glProgramEnvParameter4fvARB -glProgramEnvParameters4fvEXT -glProgramLocalParameter4dARB -glProgramLocalParameter4dvARB -glProgramLocalParameter4fARB -glProgramLocalParameter4fvARB -glProgramLocalParameters4fvEXT -glProgramParameter4dNV -glProgramParameter4dvNV -glProgramParameter4fNV -glProgramParameter4fvNV -glProgramParameters4dvNV -glProgramParameters4fvNV -glProgramStringARB -glPushAttrib -glPushClientAttrib -glPushMatrix -glPushName -glRasterPos2d -glRasterPos2dv -glRasterPos2f -glRasterPos2fv -glRasterPos2i -glRasterPos2iv -glRasterPos2s -glRasterPos2sv -glRasterPos3d -glRasterPos3dv -glRasterPos3f -glRasterPos3fv -glRasterPos3i -glRasterPos3iv -glRasterPos3s -glRasterPos3sv -glRasterPos4d -glRasterPos4dv -glRasterPos4f -glRasterPos4fv -glRasterPos4i -glRasterPos4iv -glRasterPos4s -glRasterPos4sv -glReadBuffer -glReadInstrumentsSGIX -glReadPixels -glRectd -glRectdv -glRectf -glRectfv -glRecti -glRectiv -glRects -glRectsv -glRenderbufferStorageEXT -glRenderbufferStorageMultisampleEXT -glRenderMode -glResetHistogram -glResetHistogramEXT -glResetMinmax -glResetMinmaxEXT -glResizeBuffersMESA -glRotated -glRotatef -glSampleCoverage -glSampleCoverageARB -glSampleMapATI -glSampleMaskEXT -glSampleMaskSGIS -glSamplePatternEXT -glSamplePatternSGIS -glScaled -glScalef -glScissor -glSecondaryColor3bEXT -glSecondaryColor3bvEXT -glSecondaryColor3dEXT -glSecondaryColor3dvEXT -glSecondaryColor3fEXT -glSecondaryColor3fvEXT -glSecondaryColor3hNV -glSecondaryColor3iEXT -glSecondaryColor3ivEXT -glSecondaryColor3sEXT -glSecondaryColor3svEXT -glSecondaryColor3ubEXT -glSecondaryColor3ubvEXT -glSecondaryColor3uiEXT -glSecondaryColor3uivEXT -glSecondaryColor3usEXT -glSecondaryColor3usvEXT -glSelectBuffer -glSetFenceNV -glSetFragmentShaderConstantATI -glShadeModel -glShaderOp1EXT -glShaderOp2EXT -glShaderOp3EXT -glShaderSourceARB -glSpriteParameterfSGIX -glSpriteParameteriSGIX -glStartInstrumentsSGIX -glStencilClearTagEXT -glStencilFunc -glStencilFuncSeparateATI -glStencilMask -glStencilOp -glStencilOpSeparateATI -glStopInstrumentsSGIX -glSwizzleEXT -glTagSampleBufferSGIX -glTangent3bEXT -glTangent3bvEXT -glTangent3dEXT -glTangent3dvEXT -glTangent3fEXT -glTangent3fvEXT -glTangent3iEXT -glTangent3ivEXT -glTangent3sEXT -glTangent3svEXT -glTestFenceNV -glTexCoord1d -glTexCoord1dv -glTexCoord1f -glTexCoord1fv -glTexCoord1hNV -glTexCoord1i -glTexCoord1iv -glTexCoord1s -glTexCoord1sv -glTexCoord2d -glTexCoord2dv -glTexCoord2f -glTexCoord2fv -glTexCoord2hNV -glTexCoord2i -glTexCoord2iv -glTexCoord2s -glTexCoord2sv -glTexCoord3d -glTexCoord3dv -glTexCoord3f -glTexCoord3fv -glTexCoord3hNV -glTexCoord3i -glTexCoord3iv -glTexCoord3s -glTexCoord3sv -glTexCoord4d -glTexCoord4dv -glTexCoord4f -glTexCoord4fv -glTexCoord4hNV -glTexCoord4i -glTexCoord4iv -glTexCoord4s -glTexCoord4sv -glTexCoordPointer -glTexEnvf -glTexEnvfv -glTexEnvi -glTexEnviv -glTexGend -glTexGendv -glTexGenf -glTexGenfv -glTexGeni -glTexGeniv -glTexImage1D -glTexImage1DEXT -glTexImage2D -glTexImage2DEXT -glTexImage3D -glTexImage3DEXT -glTexParameterf -glTexParameterfv -glTexParameteri -glTexParameteriv -glTexSubImage1D -glTexSubImage1DEXT -glTexSubImage2D -glTexSubImage2DEXT -glTexSubImage3D -glTexSubImage3DEXT -glTextureColorMaskSGIS -glTextureLightEXT -glTextureMaterialEXT -glTextureNormalEXT -glTrackMatrixNV -glTranslated -glTranslatef -glUniform1fARB -glUniform1fvARB -glUniform1iARB -glUniform1ivARB -glUniform2fARB -glUniform2fvARB -glUniform2iARB -glUniform2ivARB -glUniform3fARB -glUniform3fvARB -glUniform3iARB -glUniform3ivARB -glUniform4fARB -glUniform4fvARB -glUniform4iARB -glUniform4ivARB -glUniformMatrix2fvARB -glUniformMatrix3fvARB -glUniformMatrix4fvARB -glUnlockArraysEXT -glUnmapBufferARB -glUnmapObjectBufferATI -glUseProgramObjectARB -glValidateProgramARB -glVariantArrayObjectATI -glVertex2d -glVertex2dv -glVertex2f -glVertex2fv -glVertex2hNV -glVertex2i -glVertex2iv -glVertex2s -glVertex2sv -glVertex3d -glVertex3dv -glVertex3f -glVertex3fv -glVertex3hNV -glVertex3i -glVertex3iv -glVertex3s -glVertex3sv -glVertex4d -glVertex4dv -glVertex4f -glVertex4fv -glVertex4hNV -glVertex4i -glVertex4iv -glVertex4s -glVertex4sv -glVertexAttrib1dARB -glVertexAttrib1dNV -glVertexAttrib1dvARB -glVertexAttrib1dvNV -glVertexAttrib1fARB -glVertexAttrib1fNV -glVertexAttrib1fvARB -glVertexAttrib1fvNV -glVertexAttrib1hNV -glVertexAttrib1sARB -glVertexAttrib1sNV -glVertexAttrib1svARB -glVertexAttrib1svNV -glVertexAttrib2dARB -glVertexAttrib2dNV -glVertexAttrib2dvARB -glVertexAttrib2dvNV -glVertexAttrib2fARB -glVertexAttrib2fNV -glVertexAttrib2fvARB -glVertexAttrib2fvNV -glVertexAttrib2hNV -glVertexAttrib2sARB -glVertexAttrib2sNV -glVertexAttrib2svARB -glVertexAttrib2svNV -glVertexAttrib3dARB -glVertexAttrib3dNV -glVertexAttrib3dvARB -glVertexAttrib3dvNV -glVertexAttrib3fARB -glVertexAttrib3fNV -glVertexAttrib3fvARB -glVertexAttrib3fvNV -glVertexAttrib3hNV -glVertexAttrib3sARB -glVertexAttrib3sNV -glVertexAttrib3svARB -glVertexAttrib3svNV -glVertexAttrib4bvARB -glVertexAttrib4dARB -glVertexAttrib4dNV -glVertexAttrib4dvARB -glVertexAttrib4dvNV -glVertexAttrib4fARB -glVertexAttrib4fNV -glVertexAttrib4fvARB -glVertexAttrib4fvNV -glVertexAttrib4hNV -glVertexAttrib4ivARB -glVertexAttrib4NbvARB -glVertexAttrib4NivARB -glVertexAttrib4NsvARB -glVertexAttrib4NubARB -glVertexAttrib4NubvARB -glVertexAttrib4NuivARB -glVertexAttrib4NusvARB -glVertexAttrib4sARB -glVertexAttrib4sNV -glVertexAttrib4svARB -glVertexAttrib4svNV -glVertexAttrib4ubNV -glVertexAttrib4ubvARB -glVertexAttrib4ubvNV -glVertexAttrib4uivARB -glVertexAttrib4usvARB -glVertexAttribArrayObjectATI -glVertexAttribPointerARB -glVertexAttribs1dvNV -glVertexAttribs1fvNV -glVertexAttribs1svNV -glVertexAttribs2dvNV -glVertexAttribs2fvNV -glVertexAttribs2svNV -glVertexAttribs3dvNV -glVertexAttribs3fvNV -glVertexAttribs3svNV -glVertexAttribs4dvNV -glVertexAttribs4fvNV -glVertexAttribs4svNV -glVertexAttribs4ubvNV -glVertexBlendARB -glVertexBlendEnvfATI -glVertexBlendEnviATI -glVertexPointer -glVertexStream1dATI -glVertexStream1dvATI -glVertexStream1fATI -glVertexStream1fvATI -glVertexStream1iATI -glVertexStream1ivATI -glVertexStream1sATI -glVertexStream1svATI -glVertexStream2dATI -glVertexStream2dvATI -glVertexStream2fATI -glVertexStream2fvATI -glVertexStream2iATI -glVertexStream2ivATI -glVertexStream2sATI -glVertexStream2svATI -glVertexStream3dATI -glVertexStream3dvATI -glVertexStream3fATI -glVertexStream3fvATI -glVertexStream3iATI -glVertexStream3ivATI -glVertexStream3sATI -glVertexStream3svATI -glVertexStream4dATI -glVertexStream4dvATI -glVertexStream4fATI -glVertexStream4fvATI -glVertexStream4iATI -glVertexStream4ivATI -glVertexStream4sATI -glVertexStream4svATI -glVertexWeightfEXT -glVertexWeighthNV -glViewport -glWindowPos2dARB -glWindowPos2dMESA -glWindowPos2dvARB -glWindowPos2dvMESA -glWindowPos2fARB -glWindowPos2fMESA -glWindowPos2fvARB -glWindowPos2fvMESA -glWindowPos2iARB -glWindowPos2iMESA -glWindowPos2ivARB -glWindowPos2ivMESA -glWindowPos2sARB -glWindowPos2sMESA -glWindowPos2svARB -glWindowPos2svMESA -glWindowPos3dARB -glWindowPos3dMESA -glWindowPos3dvARB -glWindowPos3dvMESA -glWindowPos3fARB -glWindowPos3fMESA -glWindowPos3fvARB -glWindowPos3fvMESA -glWindowPos3iARB -glWindowPos3iMESA -glWindowPos3ivARB -glWindowPos3ivMESA -glWindowPos3sARB -glWindowPos3sMESA -glWindowPos3svARB -glWindowPos3svMESA -glWindowPos4dMESA -glWindowPos4dvMESA -glWindowPos4fMESA -glWindowPos4fvMESA -glWindowPos4iMESA -glWindowPos4ivMESA -glWindowPos4sMESA -glWindowPos4svMESA -glWriteMaskEXT -; -; WGL API - wglChoosePixelFormat - wglCopyContext - wglCreateContext - wglCreateLayerContext - wglDeleteContext - wglDescribeLayerPlane - wglDescribePixelFormat - wglGetCurrentContext - wglGetCurrentDC - wglGetLayerPaletteEntries - wglGetPixelFormat - wglGetProcAddress - wglMakeCurrent - wglRealizeLayerPalette - wglSetLayerPaletteEntries - wglSetPixelFormat - wglShareLists - wglSwapBuffers - wglSwapLayerBuffers - wglUseFontBitmapsA - wglUseFontBitmapsW - wglUseFontOutlinesA - wglUseFontOutlinesW -; wglGetExtensionsStringARB diff --git a/target-i386/opengl_client.c b/target-i386/opengl_client.c deleted file mode 100755 index beab16f..0000000 --- a/target-i386/opengl_client.c +++ /dev/null @@ -1,12382 +0,0 @@ -/* - * Guest-side implementation of GL/GLX API. Replacement of standard libGL.so - * - * Copyright (c) 2006,2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - -/* This library can also be used independly of qemu as a TCP/IP client with the opengl_server TCP/IP server */ - -/* gcc -Wall -g -O2 opengl_client.c -shared -o libGL.so.1 */ - -/* Windows compilations instructions */ -/* After building qemu, cd to target-i386 */ -/* i586-mingw32msvc-gcc -O2 -Wall opengl_client.c -c -I../i386-softmmu -I. -DBUILD_GL32 */ -/* i586-mingw32msvc-dllwrap -o opengl32.dll --def opengl32.def -Wl,-enable-stdcall-fixup opengl_client.o -lws2_32 - */ - - -/* objdump -T ../i386-softmmu/libGL.so | grep Base | awk '{print $7}' | grep gl | sort > opengl32_temp.def */ - - -/* HACK_XGL=true USE_TCP_COMMUNICATION=1 LD_LIBRARY_PATH=/home/even/qemu/cvs280207/qemu/i386-softmmu:/home/even/cairo/glitz-0.5.6/src/glx/.libs/:/home/even/cairo/glitz-0.5.6/src/.libsvalgrind Xgl -screen 800x600 :10 -ac */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#define _XOPEN_SOURCE 600 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GL_GLEXT_LEGACY -#include "mesa_gl.h" -#include "mesa_glext.h" - -#ifndef WIN32 -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#else -#include -#include -WINGDIAPI const char* WINAPI wglGetExtensionsStringARB(HDC hdc); -#endif - -#define ENABLE_THREAD_SAFETY - -/* Opengl character device */ -#define DEV_NAME "/dev/opengl" -int fd; /* file description */ - -/*void *pthread_getspecific(pthread_key_t key); - int pthread_setspecific(pthread_key_t key, const void *value);*/ - -#define CHECK_ARGS(x, y) (1 / ((sizeof(x)/sizeof(x[0])) == (sizeof(y)/sizeof(y[0])) ? 1 : 0)) ? x : x, y - -#ifndef _WIN32 - -#define TCP_COMMUNICATION_SUPPORT -#define USE_TCP_METHOD -//#define USE_DEVICE_METHOD -//#define USE_SWI_METHOD -#endif -//#define PROVIDE_STUB_IMPLEMENTATION - -#define NOT_IMPLEMENTED(x) log_gl(#x " not implemented !\n") - -static void log_gl(const char* format, ...); - -static const char* interestingEnvVars[] = -{ - "USE_TCP_COMMUNICATION", /* default : not set */ - "GET_IMG_FROM_SERVER", /* default : not set */ /* unsupported for Win32 guest */ - "GL_SERVER", /* default is localhost */ - "GL_SERVER_PORT", /* */ - "GL_ERR_FILE", /* default is stderr */ - "HACK_XGL", /* default : not set */ /* unsupported for Win32 guest */ - "DEBUG_GL", /* default : not set */ - "DEBUG_ARRAY_PTR", /* default : not set */ - "DISABLE_OPTIM", /* default : not set */ - "LIMIT_FPS", /* default : not set */ /* unsupported for Win32 guest */ - "ENABLE_GL_BUFFERING", /* default : set if TCP/IP communication or KQEMU detected */ - "NO_MOVE", /* default : set if TCP/IP communication */ -}; - - -#ifdef WIN32 - -typedef struct -{ - char* name; - char* value; -} EnvVarStruct; - -static int nbEnvVar = 0; -static EnvVarStruct* envVar = NULL; - -const char* my_getenv(const char* name) -{ - int i; - for(i=0;i (b)) ? (a) : (b)) -#endif - -static FILE* get_err_file() -{ - static FILE* err_file = NULL; - if (err_file == NULL) - { - err_file = getenv("GL_ERR_FILE") ? fopen(getenv("GL_ERR_FILE"), "wt") : NULL; - if (err_file == NULL) - err_file = stderr; - } - return err_file; -} - -#include "opengl_func.h" - -#include "glgetv_cst.h" - -typedef struct -{ - int size; - int type; - int stride; - const void* ptr; - - int index; - int normalized; - - int enabled; - int vbo_name; - - unsigned int last_crc; -} ClientArray; - -typedef struct { - GLboolean swapEndian; - GLboolean lsbFirst; - GLuint rowLength; - GLuint imageHeight; - GLuint skipRows; - GLuint skipPixels; - GLuint skipImages; - GLuint alignment; -} PixelStoreMode; - -typedef struct -{ - int format; - int stride; - const void* ptr; -} InterleavedArrays; - -typedef struct { - ClientArray vertexArray; - ClientArray normalArray; - ClientArray colorArray; - ClientArray secondaryColorArray; - ClientArray indexArray; - ClientArray edgeFlagArray; - ClientArray weightArray; - ClientArray matrixIndexArray; - ClientArray fogCoordArray; - ClientArray texCoordArray[NB_MAX_TEXTURES]; - ClientArray vertexAttribArray[MY_GL_MAX_VERTEX_ATTRIBS_ARB]; - ClientArray vertexAttribArrayNV[MY_GL_MAX_VERTEX_ATTRIBS_NV]; - ClientArray variantPointer[MY_GL_MAX_VARIANT_POINTER_EXT]; - ClientArray elementArrayATI; - InterleavedArrays interleavedArrays; -} ClientArrays; - - - - -typedef struct -{ - GLbitfield mask; - PixelStoreMode pack; - PixelStoreMode unpack; - ClientArrays arrays; - int clientActiveTexture; - int selectBufferSize; - void* selectBufferPtr; - int feedbackBufferSize; - void* feedbackBufferPtr; -} ClientState; - - -typedef struct -{ - int texture; - int level; - - int width; - int height; -} Texture2DDim; - -typedef struct -{ - float mode; - float density; - float start; - float end; - float index; - float color[4]; -} Fog; - -#define N_CLIP_PLANES 8 -typedef struct -{ - GLbitfield mask; - int matrixMode; - int bindTexture2D; /* optimization for openquartz */ - int bindTextureRectangle; - int linesmoothEnabled; /* optimization for googleearth */ - int lightingEnabled; - int texture2DEnabled; - int blendEnabled; - int scissorTestEnabled; - int vertexProgramEnabled; - int fogEnabled; - int depthFunc; - Fog fog; - - Texture2DDim* texture2DCache; - int texture2DCacheDim; - Texture2DDim* textureProxy2DCache; - int textureProxy2DCacheDim; - Texture2DDim* textureRectangleCache; - int textureRectangleCacheDim; - Texture2DDim* textureProxyRectangleCache; - int textureProxyRectangleCacheDim; - - double clipPlanes[N_CLIP_PLANES][4]; -} ServerState; - -typedef struct -{ - int size; - void* ptr; - int mapped; - int usage; - int access; -} Buffer; - -typedef struct -{ - int start; - int length; -} IntRange; - -typedef struct -{ - IntRange* ranges; - int nb; - int maxNb; -} IntSetRanges; - -typedef struct -{ - int bufferid; - int size; - void* ptr; - void* ptrMapped; - IntSetRanges updatedRangesAfterMapping; - void* ptrUpdatedWhileMapped; -} ObjectBufferATI; - -typedef struct -{ - GLuint program; - char* txt; - int location; -} UniformLocation; - - -#include "opengl_utils.h" - -/**/ -#define MAX_MATRIX_STACK_SIZE 64 -#define NB_GL_MATRIX (3+NB_MAX_TEXTURES+31) -typedef struct -{ - double val[16]; -} Matrixd; - -typedef struct -{ - Matrixd stack[MAX_MATRIX_STACK_SIZE]; - Matrixd current; - int sp; -} GLMatrix; - -typedef struct -{ - int x; - int y; - int width; - int height; -} ViewportStruct; - -typedef struct -{ - int x; - int y; - int width; - int height; - int map_state; -} WindowPosStruct; - - -typedef struct -{ - int id; - int datatype; - int components; -} Symbol; - -typedef struct -{ - Symbol* tab; - int count; -} Symbols; - -#define MAX_CLIENT_STATE_STACK_SIZE 16 -#define MAX_SERVER_STATE_STACK_SIZE 16 - -typedef struct -{ - int ref; -#ifndef WIN32 - Display* display; - GLXContext context; - GLXDrawable current_drawable; - GLXDrawable current_read_drawable; - struct timeval last_swap_buffer_time; - GLXContext shareList; - XFixesCursorImage last_cursor; - GLXPbuffer pbuffer; -#endif - int isAssociatedToFBConfigVisual; - - ClientState client_state_stack[MAX_CLIENT_STATE_STACK_SIZE]; - ClientState client_state; - int client_state_sp; - - ServerState server_stack[MAX_SERVER_STATE_STACK_SIZE]; - ServerState current_server_state; - int server_sp; - - int arrayBuffer; /* optimization for ww2d */ - int elementArrayBuffer; - int pixelUnpackBuffer; - int pixelPackBuffer; - - Buffer arrayBuffers[32768]; - Buffer elementArrayBuffers[32768]; - Buffer pixelUnpackBuffers[32768]; - Buffer pixelPackBuffers[32768]; - - RangeAllocator ownTextureAllocator; - RangeAllocator* textureAllocator; - RangeAllocator ownBufferAllocator; - RangeAllocator* bufferAllocator; - RangeAllocator ownListAllocator; - RangeAllocator* listAllocator; - - Symbols symbols; - - ObjectBufferATI objectBuffersATI[32768]; - - UniformLocation* uniformLocations; - int countUniformLocations; - - WindowPosStruct oldPos; - ViewportStruct viewport; - ViewportStruct scissorbox; - int drawable_width; - int drawable_height; - - int currentRasterPosKnown; - float currentRasterPos[4]; - - char* tuxRacerBuffer; - - int activeTexture; - - int isBetweenBegin; - - int lastGlError; - - int isBetweenLockArrays; - int locked_first; - int locked_count; - - GLMatrix matrix[NB_GL_MATRIX]; -} GLState; - -static GLState* new_gl_state() -{ - int i, j; - GLState* state; - - state = malloc(sizeof(GLState)); - memset(state, 0, sizeof(GLState)); - state->activeTexture = GL_TEXTURE0_ARB; - state->client_state.pack.alignment = 4; - state->client_state.unpack.alignment = 4; - state->current_server_state.matrixMode = GL_MODELVIEW; - state->current_server_state.depthFunc = GL_LESS; - state->current_server_state.fog.mode = GL_EXP; - state->current_server_state.fog.density = 1; - state->current_server_state.fog.start = 0; - state->current_server_state.fog.end = 1; - state->current_server_state.fog.index = 0; - state->textureAllocator = &state->ownTextureAllocator; - state->bufferAllocator = &state->ownBufferAllocator; - state->listAllocator = &state->ownListAllocator; - state->currentRasterPosKnown = 1; - state->currentRasterPos[0] = 0; - state->currentRasterPos[1] = 0; - state->currentRasterPos[2] = 0; - state->currentRasterPos[3] = 1; - for(i=0;imatrix[i].sp = 0; - for(j=0;j<16;j++) - { - state->matrix[i].current.val[j] = (j == 0 || j == 5 || j == 10 || j == 15); - } - } - return state; -} - -/* The access to the following global variables shoud be done under the global lock */ -static GLState* default_gl_state = NULL; -static int nbGLStates = 0; -static GLState** glstates = NULL; - -#define IS_GLX_CALL(x) (x >= glXChooseVisual_func && x <= glXReleaseTexImageARB_func) - -#ifdef ENABLE_THREAD_SAFETY - -/* Posix threading */ -/* The concepts used here are coming directly from http://www.mesa3d.org/dispatch.html */ - -#ifndef WIN32 -static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_key_t key_current_gl_state; -#define GET_CURRENT_THREAD() pthread_self() - -static pthread_t last_current_thread = 0; -static GLState* _mono_threaded_current_gl_state = NULL; -#ifdef TEST_IF_LOCK_USE_IS_CORRECT_INTO_MONO_THREADED_CASE -static int lock_count = 0; -#define LOCK(func_number) int __lock__ = 0; assert(lock_count == 0); lock_count++; pthread_mutex_lock( &global_mutex ); -#define UNLOCK(func_number) assert(lock_count + __lock__ == 1); lock_count--; pthread_mutex_unlock( &global_mutex ); -#define IS_MT() 2 -static int _is_mt = 2; -#else -static int _is_mt = 0; -static inline int is_mt() -{ - if (_is_mt) return 1; - pthread_t current_thread = GET_CURRENT_THREAD(); - if (last_current_thread == 0) - last_current_thread = current_thread; - if (current_thread != last_current_thread) - { - _is_mt = 1; - log_gl("-------- Two threads at least are doing OpenGL ---------\n"); - pthread_key_create(&key_current_gl_state, NULL); - } - return _is_mt; -} -#define IS_MT() is_mt() - -/* The idea here is that the first GL/GLX call made in each thread is necessary a GLX call */ -/* So in the case where it's a GLX call we always take the lock and check if we're in MT case */ -/* otherwise (regular GL call), we have to take the lock only in the MT case */ -#define LOCK(func_number) do { if (IS_GLX_CALL(func_number)) { pthread_mutex_lock( &global_mutex ); IS_MT(); } else if (_is_mt) { pthread_mutex_lock( &global_mutex ); } } while(0) -#define UNLOCK(func_number) do { if (IS_GLX_CALL(func_number) || _is_mt) pthread_mutex_unlock( &global_mutex ); } while(0) -#endif -static void set_current_state(GLState* current_gl_state) -{ - if (_is_mt) - pthread_setspecific(key_current_gl_state, current_gl_state); - else - _mono_threaded_current_gl_state = current_gl_state; -} -static inline GLState* get_current_state() -{ - GLState* current_gl_state; - if (_is_mt == 1 && - last_current_thread == GET_CURRENT_THREAD()) - { - _is_mt = 2; - set_current_state(_mono_threaded_current_gl_state); - _mono_threaded_current_gl_state = NULL; - } - current_gl_state = (_is_mt) ? pthread_getspecific(key_current_gl_state) : _mono_threaded_current_gl_state; - if (current_gl_state == NULL) - { - if (default_gl_state == NULL) - { - default_gl_state = new_gl_state(); - } - current_gl_state = default_gl_state; - set_current_state(current_gl_state); - } - return current_gl_state; -} -#define SET_CURRENT_STATE(_x) set_current_state(_x) - -/* Win32 threading : TODO !*/ - -#else -#define LOCK(func_number) -#define UNLOCK(func_number) -#define GET_CURRENT_THREAD() 0 -#define IS_MT() 0 -static GLState* current_gl_state = NULL; -static inline GLState* get_current_state() -{ - if (current_gl_state == NULL) - { - if (default_gl_state == NULL) - { - default_gl_state = new_gl_state(); - } - return default_gl_state; - } - return current_gl_state; -} -#define SET_CURRENT_STATE(_x) current_gl_state = _x -#endif - -/* No support for threading */ -#else -#define LOCK(func_number) -#define UNLOCK(func_number) -#define GET_CURRENT_THREAD() 0 -#define IS_MT() 0 -static GLState* current_gl_state = NULL; -static inline GLState* get_current_state() -{ - if (current_gl_state == NULL) - { - if (default_gl_state == NULL) - { - default_gl_state = new_gl_state(); - } - return default_gl_state; - } - return current_gl_state; -} -#define SET_CURRENT_STATE(_x) current_gl_state = _x -#endif - - -#define GET_CURRENT_STATE() GLState* state = get_current_state() - -static void log_gl(const char* format, ...) -{ -#if 0 - va_list list; - va_start(list, format); -#ifdef ENABLE_THREAD_SAFETY - if (IS_MT()) - fprintf(get_err_file(), "[thread %p] : ", (void*)GET_CURRENT_THREAD()); -#endif - vfprintf(get_err_file(), format, list); - va_end(list); -#endif -} - - -/**/ - -#ifndef WIN32 -typedef struct -{ - int attrib; - int value; - int ret; -} _glXGetConfigAttribs; - -typedef struct -{ - int val; - char* name; -} glXAttrib; - -#define VAL_AND_NAME(x) { x, #x } - -static const glXAttrib tabRequestedAttribsPair[] = -{ - VAL_AND_NAME(GLX_USE_GL), - VAL_AND_NAME(GLX_BUFFER_SIZE), - VAL_AND_NAME(GLX_LEVEL), - VAL_AND_NAME(GLX_RGBA), - VAL_AND_NAME(GLX_DOUBLEBUFFER), - VAL_AND_NAME(GLX_STEREO), - VAL_AND_NAME(GLX_AUX_BUFFERS), - VAL_AND_NAME(GLX_RED_SIZE), - VAL_AND_NAME(GLX_GREEN_SIZE), - VAL_AND_NAME(GLX_BLUE_SIZE), - VAL_AND_NAME(GLX_ALPHA_SIZE), - VAL_AND_NAME(GLX_DEPTH_SIZE), - VAL_AND_NAME(GLX_STENCIL_SIZE), - VAL_AND_NAME(GLX_ACCUM_RED_SIZE), - VAL_AND_NAME(GLX_ACCUM_GREEN_SIZE), - VAL_AND_NAME(GLX_ACCUM_BLUE_SIZE), - VAL_AND_NAME(GLX_ACCUM_ALPHA_SIZE), - VAL_AND_NAME(GLX_CONFIG_CAVEAT), - VAL_AND_NAME(GLX_X_VISUAL_TYPE), - VAL_AND_NAME(GLX_TRANSPARENT_TYPE), - VAL_AND_NAME(GLX_TRANSPARENT_INDEX_VALUE), - VAL_AND_NAME(GLX_TRANSPARENT_RED_VALUE), - VAL_AND_NAME(GLX_TRANSPARENT_GREEN_VALUE), - VAL_AND_NAME(GLX_TRANSPARENT_BLUE_VALUE), - VAL_AND_NAME(GLX_TRANSPARENT_ALPHA_VALUE), - VAL_AND_NAME(GLX_SLOW_CONFIG), - VAL_AND_NAME(GLX_TRUE_COLOR), - VAL_AND_NAME(GLX_DIRECT_COLOR), - VAL_AND_NAME(GLX_PSEUDO_COLOR), - VAL_AND_NAME(GLX_STATIC_COLOR), - VAL_AND_NAME(GLX_GRAY_SCALE), - VAL_AND_NAME(GLX_STATIC_GRAY), - VAL_AND_NAME(GLX_TRANSPARENT_RGB), - VAL_AND_NAME(GLX_TRANSPARENT_INDEX), - VAL_AND_NAME(GLX_VISUAL_ID), - VAL_AND_NAME(GLX_DRAWABLE_TYPE), - VAL_AND_NAME(GLX_RENDER_TYPE), - VAL_AND_NAME(GLX_X_RENDERABLE), - VAL_AND_NAME(GLX_FBCONFIG_ID), - VAL_AND_NAME(GLX_RGBA_TYPE), - VAL_AND_NAME(GLX_COLOR_INDEX_TYPE), - VAL_AND_NAME(GLX_MAX_PBUFFER_WIDTH), - VAL_AND_NAME(GLX_MAX_PBUFFER_HEIGHT), - VAL_AND_NAME(GLX_MAX_PBUFFER_PIXELS), - VAL_AND_NAME(GLX_PRESERVED_CONTENTS), - VAL_AND_NAME(GLX_FLOAT_COMPONENTS_NV), - VAL_AND_NAME(GLX_SAMPLE_BUFFERS), - VAL_AND_NAME(GLX_SAMPLES) -}; -#define N_REQUESTED_ATTRIBS (sizeof(tabRequestedAttribsPair)/sizeof(tabRequestedAttribsPair[0])) - -static int* getTabRequestedAttribsInt() -{ - static int tabRequestedAttribsInt[N_REQUESTED_ATTRIBS] = { 0 }; - if (tabRequestedAttribsInt[0] == 0) - { - int i; - for(i=0;i -#include -#include - -static void glReadPixels_no_lock ( GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels ); - -#define MAX_IMAGES 100 - -typedef struct { - Window win; - GC win_gc; - int width; - int height ; - unsigned int bytes_per_pixel; - unsigned int bytes_per_line; - char *rData; - - char *imageData; - XImage *xImage; - XShmSegmentInfo *shminfo; -} WindowImage; - -WindowImage wImage[MAX_IMAGES]; - -static Bool _create_image(Display *dpy, Window win, WindowImage *image) -{ - XWindowAttributes XWinAttribs; - XShmSegmentInfo *shmseginfo; - - XGetWindowAttributes( dpy, win, &XWinAttribs ); - shmseginfo = (XShmSegmentInfo *)malloc(sizeof(XShmSegmentInfo)); - if(!shmseginfo) - { - return False; - } - image->xImage = XShmCreateImage(dpy, XWinAttribs.visual, XWinAttribs.depth, ZPixmap, NULL, shmseginfo, XWinAttribs.width, XWinAttribs.height); - if( image->xImage == NULL ) - { - free( shmseginfo ); - return False; - } - - image->width = XWinAttribs.width; - image->height = XWinAttribs.height; - image->bytes_per_pixel = image->xImage->bits_per_pixel / 8; - image->bytes_per_line = image->width * image->bytes_per_pixel; - - - shmseginfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777); - if(shmseginfo->shmid < 0 ) - { - printf("shmget Err --------- \n"); - XDestroyImage(image->xImage); - free( shmseginfo ); - return False; - } - - shmseginfo->shmaddr = shmat(shmseginfo->shmid, NULL, 0); - if(!shmseginfo->shmaddr) - { - printf("shmat Err --------- \n"); - XDestroyImage(image->xImage); - shmctl(shmseginfo->shmid, IPC_RMID, NULL); - free( shmseginfo ); - return False; - - } - shmseginfo->readOnly = False; - - image->imageData = (char *) shmseginfo->shmaddr; - image->rData = malloc(XWinAttribs.width * XWinAttribs.height * image->bytes_per_pixel); - - if(image->rData == NULL || !XShmAttach(dpy, shmseginfo)) - { - XShmDetach(dpy, shmseginfo); - XDestroyImage(image->xImage); - shmdt(shmseginfo->shmaddr); - shmctl(shmseginfo->shmid, IPC_RMID, NULL); - free( shmseginfo ); - return False; - } - - image->xImage->data = image->imageData; - image->win = win; - image->shminfo = shmseginfo; - - return True; -} - -static void _destroy_image(Display *dpy, WindowImage *image) -{ - XShmDetach(dpy, image->shminfo); - XDestroyImage(image->xImage); - image->imageData = NULL; - image->win = 0; - - shmdt(image->shminfo->shmaddr); - shmctl(image->shminfo->shmid, IPC_RMID, NULL); - free( image->shminfo ); - image->shminfo = NULL; - - free(image->rData); - image->rData = NULL; -} - -static void _draw_image(Display *dpy, Window win, WindowImage *image) -{ - int r, s; - XWindowAttributes XWinAttribs; - - XGetWindowAttributes( dpy, win, &XWinAttribs ); - if( image->width != XWinAttribs.width || image->height != XWinAttribs.height ) - { - _destroy_image( dpy, image); - if( _create_image(dpy, win, image) == False ) - { - XFreeGC(dpy, image->win_gc); - image->win_gc = NULL; - return; - } - } - LOCK(glReadPixels_func); - glReadPixels_no_lock(0, 0, image->width, image->height, GL_BGRA, GL_UNSIGNED_BYTE, image->rData); - UNLOCK(glReadPixels_func); - - for(s = 0, r = image->height - 1; s < image->height; s++, r--) - { - memcpy(&image->imageData[image->bytes_per_line * s], &image->rData[image->bytes_per_line * r], image->bytes_per_line); - } - - XShmPutImage(dpy, image->win, image->win_gc, image->xImage, 0, 0, 0, 0, image->width, image->height, False); - XFlush(dpy); - - return; -} -#endif /*__CLIENT_WINDOW__*/ -#endif - - -static int pagesize = 0; - -static int debug_gl = 0; -static int debug_array_ptr = 0; -static int disable_optim = 0; -static int limit_fps = 0; - -#ifndef WIN32 -static struct sigaction old_action; - -static void sigsegv_handler(int signum, siginfo_t* info, void* ptr) -{ - struct ucontext* context = (struct ucontext*)ptr; -#if defined(__i386__) - unsigned char* eip_ptr = (unsigned char*)context->uc_mcontext.gregs[REG_EIP]; -#elif defined(__x86_64__) - unsigned char* eip_ptr = (unsigned char*)context->uc_mcontext.gregs[REG_RIP]; -#else -#error "unsupported architecture" -#endif - if (eip_ptr[0] == 0xCD && eip_ptr[1] == 0x99) - { -#if defined(__i386__) - context->uc_mcontext.gregs[REG_EIP] += 2; -#elif defined(__x86_64__) - context->uc_mcontext.gregs[REG_RIP] += 2; -#else -#error "unsupported architecture" -#endif - } - else - { - log_gl("unhandled SIGSEGV\n"); - exit(-1); // FIXME - if (old_action.sa_flags & SA_SIGINFO) - { - old_action.sa_sigaction(signum, info, ptr); - } - else - { - old_action.sa_handler(signum); - } - } -} -#endif - -#ifdef TCP_COMMUNICATION_SUPPORT - -#include -#include -#include - -#ifndef WIN32 -#include -#include -#include -#include -#include -static int sock; -#else -#include -#include -#include -#include -SOCKET sock; -#endif - - -static void init_sockaddr (struct sockaddr_in *name, - const char *hostname, - uint16_t port) -{ - struct hostent *hostinfo; - name->sin_family = AF_INET; - name->sin_port = htons (port); - name->sin_addr.s_addr = inet_addr(hostname); - if (name->sin_addr.s_addr != INADDR_NONE) - return; - hostinfo = gethostbyname (hostname); - if (hostinfo == NULL) - { - log_gl("Unknown host %s.\n", hostname); -#ifdef WIN32 - char msg[512]; - sprintf(msg, "Unknown host %s", hostname); - MessageBox(NULL, msg, "Unknown host", 0); -#endif - exit (EXIT_FAILURE); - } - name->sin_addr = *(struct in_addr *) hostinfo->h_addr; -} - -static int total_written = 0; -static void write_sock_data(void* data, int len) -{ - if (len && data) - { - int offset = 0; - //if (debug_gl) log_gl("to write : %d\n", len); - while(offset < len) - { -#ifndef WIN32 - int nwritten = write(sock, data + offset, len - offset); - if (nwritten == -1) -#else - int nwritten = send(sock, data + offset, len - offset, 0); - if (nwritten == SOCKET_ERROR) -#endif - { - if (errno == EINTR) - continue; - perror("write"); - assert(nwritten != -1); - } - offset += nwritten; - total_written += nwritten; - /*if (debug_gl) - log_gl("total written : %d\n", total_written); - if (debug_gl && offset < len) log_gl("remaining to write : %d\n", len - offset);*/ - } - } -} - -static void inline write_sock_int(int my_int) -{ - write_sock_data(&my_int, sizeof(int)); -} - -static void inline write_sock_short(short my_int) -{ - write_sock_data(&my_int, sizeof(short)); -} - -static void read_sock_data(void* data, int len) -{ - if (len && data) - { - int offset = 0; - while(offset < len) - { -#ifndef WIN32 - int nread = read(sock, data + offset, len - offset); - if (nread == -1) -#else - int nread = recv(sock, data + offset, len - offset, 0); - if (nread == SOCKET_ERROR) -#endif - { - if (errno == EINTR) - continue; - perror("read"); - assert(nread != -1); - } - offset += nread; - } - } -} - -static int inline read_sock_int() -{ - int ret; - read_sock_data(&ret, sizeof(int)); - return ret; -} - -static int call_opengl_tcp(int func_number, int pid, void* ret_string, void* _args, void* _args_size) -{ - int ret; - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int nb_args = signature->nb_args; - int i; - long* args = (long*)_args; - int* args_size = (int*)_args_size; - int* args_type = signature->args_type; - - - write_sock_short(func_number); - for(i=0;ihas_out_parameters) - { - for(i=0;iret_type == TYPE_CONST_CHAR) - { - int len = read_sock_int(); - read_sock_data(ret_string, len); - ret = 0; - } - else if (signature->ret_type != TYPE_NONE) - { - ret = read_sock_int(); - } - else - { - ret = 0; - } - - return ret; -} -#endif - -#ifdef WIN32 -static EXCEPTION_DISPOSITION win32_sigsegv_handler(struct _EXCEPTION_RECORD *exception_record, - void * EstablisherFrame, - struct _CONTEXT *ContextRecord, - void * DispatcherContext) -{ - /* If the exception is an access violation */ - if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && - exception_record->NumberParameters >= 2) - { - //int accessMode = (int)exception_record->ExceptionInformation[0]; - //void* adr = (void *)exception_record->ExceptionInformation[1]; - - unsigned char* eip_ptr = (unsigned char*)ContextRecord->Eip; - if (eip_ptr[0] == 0xCD && eip_ptr[1] == 0x99) - { - ContextRecord->Eip += 2; - return ExceptionContinueExecution; - } - else - { - log_gl("not handled exception : %X\n", (int)exception_record->ExceptionCode); - fflush(get_err_file()); - return ExceptionContinueSearch; - } - } - else - { - log_gl("not handled exception : %X\n", (int)exception_record->ExceptionCode); - fflush(get_err_file()); - return ExceptionContinueSearch; - } -} -#endif - -static int call_opengl_chardev(int func_number, int pid, void* ret_string, void *args, void* args_size) -{ - if( ! (func_number >= 0 && func_number < GL_N_CALLS) ) - { - log_gl("func_number >= 0 && func_number < GL_N_CALLS failed\n"); - return 0; - } - - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int nb_args = signature->nb_args; - - int ret; - struct accel { - int func_number; - int pid; - void *ret_string; - void *args; - void *args_size; - }; - struct accel accelMode; - - accelMode.func_number = func_number; - accelMode.pid = pid; - accelMode.ret_string = ret_string; - accelMode.args = args; - accelMode.args_size = args_size; - - write(fd, &accelMode, nb_args); - - ret = read(fd, NULL, 1); - - return ret; -} - -static int call_opengl_qemu(int func_number, int pid, void* ret_string, void* args, void* args_size) -{ -#if defined(__i386__) - int ret; -#ifdef WIN32 - __asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (win32_sigsegv_handler)); -#endif - __asm__ ("push %ebx"); - __asm__ ("push %ecx"); - __asm__ ("push %edx"); - __asm__ ("push %esi"); - __asm__ ("mov %0, %%eax"::"m"(func_number)); - __asm__ ("mov %0, %%ebx"::"m"(pid)); - __asm__ ("mov %0, %%ecx"::"m"(ret_string)); - __asm__ ("mov %0, %%edx"::"m"(args)); - __asm__ ("mov %0, %%esi"::"m"(args_size)); - __asm__ ("int $0x99"); - __asm__ ("pop %esi"); - __asm__ ("pop %edx"); - __asm__ ("pop %ecx"); - __asm__ ("pop %ebx"); - __asm__ ("mov %%eax, %0"::"m"(ret)); -#ifdef WIN32 - __asm__ ("movl (%%esp),%%ecx;movl %%ecx,%%fs:0;addl $8,%%esp;" : : : "%ecx"); -#endif - return ret; -#elif defined(__x86_64__) - int ret; - __asm__ ("push %rbx"); - __asm__ ("push %rcx"); - __asm__ ("push %rdx"); - __asm__ ("push %rsi"); - __asm__ ("mov %0, %%eax"::"m"(func_number)); - __asm__ ("mov %0, %%ebx"::"m"(pid)); - __asm__ ("mov %0, %%rcx"::"m"(ret_string)); - __asm__ ("mov %0, %%rdx"::"m"(args)); - __asm__ ("mov %0, %%rsi"::"m"(args_size)); - __asm__ ("int $0x99"); - __asm__ ("pop %rsi"); - __asm__ ("pop %rdx"); - __asm__ ("pop %rcx"); - __asm__ ("pop %rbx"); - __asm__ ("mov %%eax, %0"::"m"(ret)); - return ret; -#else - fprintf(stderr, "unsupported architecture!\n"); - return 0; -#endif -} - - -#ifdef TCP_COMMUNICATION_SUPPORT -static int use_tcp_communication = 0; -static int call_opengl(int func_number, int pid, void* ret_string, void* args, void* args_size) -{ - if (!use_tcp_communication) - return call_opengl_chardev(func_number, pid, ret_string, args, args_size); - else - return call_opengl_tcp(func_number, pid, ret_string, args, args_size); -} -#else -static int call_opengl(int func_number, int pid, void* ret_string, void* args, void* args_size) -{ - return call_opengl_qemu(func_number, pid, ret_string, args, args_size); -} -#endif - - -static void do_init() -{ -#ifdef TCP_COMMUNICATION_SUPPORT - if (use_tcp_communication) - { - struct sockaddr_in servername; -#ifdef WIN32 - WORD wVersionRequested; - WSADATA WSAData; /* Structure WSADATA d�finie dans winsock.h */ - int err; - - wVersionRequested = MAKEWORD(2, 0); /* 1.1 Version voulut de Winsock */ - err = WSAStartup(wVersionRequested, &WSAData); /* Appel de notre fonction */ - if (err != 0) - { - MessageBox(NULL, "WSAStartup failed", "WSAStartup failed", 0); - exit(EXIT_FAILURE); - } -#endif - /* Create the socket. */ - sock = socket (AF_INET, SOCK_STREAM, -#ifndef WIN32 - IPPROTO_TCP -#else - 0 -#endif - ); - if (sock < 0) - { -#ifdef WIN32 - MessageBox(NULL, "socket (client)", "socket (client)", 0); -#endif - perror ("socket (client)"); - exit (EXIT_FAILURE); - } - - /* Connect to the server. */ - int port; - if (getenv("GL_SERVER_PORT")) - port = atoi(getenv("GL_SERVER_PORT")); - - /* Get fixed host IP address and connect to server */ -#ifdef USE_TCP_METHOD - //char fixed_host_ip[] = "10.0.2.2"; /* HOST_QEMU_ADDRESS */ - //init_sockaddr (&servername, getenv("GL_SERVER") ? getenv("GL_SERVER") : &fixed_host_ip[0], port); - - FILE *fp; - char port_buffer[32] = {0}; - char ip_buffer[32] = "10.0.2.2"; - - /* - fp = fopen("/opt/home/opengl_ip.txt", "rt"); - if( fp== NULL ) { - fprintf(stderr, "/opt/home/opengl_ip.txt file open error\n"); - exit(EXIT_FAILURE); - } - fgets(ip_buffer, 32, fp); - fclose(fp); - */ - - fp = fopen("/opt/home/sdb_port.txt", "rt"); - if( fp== NULL ) { - fprintf(stderr, "/opt/home/sdb_port.txt file open error\n"); - exit(EXIT_FAILURE); - } - fgets(port_buffer, 32, fp); - fclose(fp); - - port = atoi(port_buffer) + 4; - init_sockaddr(&servername, getenv("GL_SERVER") ? getenv("GL_SERVER") : ip_buffer, port);; - -#else - init_sockaddr (&servername, getenv("GL_SERVER") ? getenv("GL_SERVER") : "localhost", port); -#endif - - int flag = 1; - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,(char *)&flag, sizeof(int)) != 0) - { -#ifdef WIN32 - MessageBox(NULL, "setsockopt TCP_NODELAY", "setsockopt TCP_NODELAY", 0); -#endif - perror("setsockopt TCP_NODELAY"); - } - if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,(char *)&flag, sizeof(int)) != 0) - { -#ifdef WIN32 - MessageBox(NULL, "setsockopt SO_KEEPALIVE", "setsockopt SO_KEEPALIVE", 0); -#endif - perror("setsockopt SO_KEEPALIVE"); - } - - if (0 > connect (sock, - (struct sockaddr *) &servername, - sizeof (servername))) - { -#ifdef WIN32 - MessageBox(NULL, "impossible to connect to server", "impossible to connect to server", 0); -#endif - perror ("impossible to connect to server"); - exit (EXIT_FAILURE); - } - - setenv("ENABLE_GL_BUFFERING", "1", 1); - setenv("NO_MOVE", "1", 1); - } - else -#endif - { -#ifndef WIN32 - struct sigaction action; - action.sa_sigaction = sigsegv_handler; - sigemptyset(&(action.sa_mask)); - action.sa_flags = SA_SIGINFO; - sigaction(SIGSEGV, &action, &old_action); - - int parent_pid = getpid(); - int pid_fork = fork(); - if (pid_fork == 0) - { - /* Sorry. This is really ugly, not portable, etc... - This is the quickest way I've found - to make sure that someone notices that the main program has stopped - running and can warn the server */ - if (fork() != 0) exit(0); - setsid(); - if (fork() != 0) exit(0); - fcloseall(); - chdir("/"); - - char processname[512]; - sprintf(processname, "/proc/%d", parent_pid); - while(1) - { - struct stat buf; - if (lstat(processname, &buf) < 0) - { - call_opengl(_exit_process_func, parent_pid, NULL, NULL, NULL); - close(fd); - exit(0); - } - sleep(1); - } - } - else if (pid_fork > 0) - { - log_gl("go on...\n"); - } - else - { - log_gl("fork failed\n"); - exit(-1); - } -#endif - } - /* -#ifndef _WIN32 - if((fd = open(DEV_NAME, O_RDWR|O_NDELAY)) < 0) -#else - if((fd = open(DEV_NAME, O_RDWR)) < 0 ) -#endif - { - fprintf(stderr, "Device Open Error\n"); - return -1; - } - */ -} - -static int try_to_put_into_phys_memory(void* addr, int len) -{ - if (addr == NULL || len == 0) return 0; - int i; - void* aligned_addr = (void*)((long)addr & (~(pagesize - 1))); - int to_end_page = (long)aligned_addr + pagesize - (long)addr; - char c = 0; - if (aligned_addr != addr) - { - c += ((char*)addr)[0]; - if (len <= to_end_page) - { - return c; - } - len -= to_end_page; - addr = aligned_addr + pagesize; - } - for(i=0;i= 0 && func_number < GL_N_CALLS) ) - { - log_gl("func_number >= 0 && func_number < GL_N_CALLS failed\n"); - goto end_do_opengl_call; - } - - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int nb_args = signature->nb_args; - int* args_type = signature->args_type; - int args_size[100] = {0,}; - int ret_int = 0; - int i; - - static char* command_buffer = NULL; - static int command_buffer_size = 0; - static int last_command_buffer_size = -1; - static char* ret_string = NULL; - static int enable_gl_buffering = 0; - static int last_current_thread = -1; - static int exists_on_server_side[GL_N_CALLS]; - - int current_thread = GET_CURRENT_THREAD(); - - if (ret_string == NULL) - { - /* Sanity checks */ - assert(tab_args_type_length[TYPE_OUT_128UCHAR] == 128 * sizeof(char)); - assert(tab_args_type_length[TYPE_OUT_ARRAY_DOUBLE_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS] == sizeof(double)); - - assert(sizeof(tab_args_type_length)/sizeof(tab_args_type_length[0]) == TYPE_LAST); - - memset(exists_on_server_side, 255, sizeof(exists_on_server_side)); - exists_on_server_side[glXGetProcAddress_fake_func] = 1; - exists_on_server_side[glXGetProcAddress_global_fake_func] = 1; - - FILE* f = fopen("/tmp/.opengl_client", "rb"); - if (!f) - f = fopen("opengl_client.txt", "rb"); - if (f) - { - char buffer[80]; - while (fgets(buffer, 80, f)) - { - for(i=0;idisplay, state->current_drawable, state->context); -#else - // FIXME -#endif - } -#endif - -#ifndef WIN32 - if (func_number == glFlush_func && getenv("HACK_XGL")) - { - glXSwapBuffers_no_lock(state->display, state->current_drawable); - goto end_do_opengl_call; - } - else if ((func_number == glDrawBuffer_func || func_number == glReadBuffer_func) && getenv("HACK_XGL")) - { - goto end_do_opengl_call; - } -#endif - - if ((func_number >= glRasterPos2d_func && func_number <= glRasterPos4sv_func) || - (func_number >= glWindowPos2d_func && func_number <= glWindowPos3sv_func) || - (func_number >= glWindowPos2dARB_func && func_number <= glWindowPos3svARB_func) || - (func_number >= glWindowPos2dMESA_func && func_number <= glWindowPos4svMESA_func)) - - { - state->currentRasterPosKnown = 0; - } - - int this_func_parameter_size = sizeof(short); /* func_number */ - - /* Compress consecutive glEnableClientState calls */ - if (!disable_optim && - last_command_buffer_size != -1 && - func_number == glClientActiveTexture_func && - *(short*)(command_buffer + last_command_buffer_size) == glClientActiveTexture_func) - { - *(int*)(command_buffer + last_command_buffer_size + sizeof(short)) = args[0]; - goto end_do_opengl_call; - } - for(i=0;iret_type == TYPE_NONE && signature->has_out_parameters == 0 && - func_number != _exit_process_func && !(func_number == glXSwapBuffers_func || func_number == glXDestroyWindow_func || func_number == glFlush_func || func_number == glFinish_func)) - { - assert(ret_ptr == NULL); - if (this_func_parameter_size + command_buffer_size >= SIZE_BUFFER_COMMAND) - { - if (debug_gl) - log_gl("flush pending opengl calls...\n"); - try_to_put_into_phys_memory(command_buffer, command_buffer_size); - call_opengl(_serialized_calls_func, getpid(), NULL, &command_buffer, &command_buffer_size); - command_buffer_size = 0; - last_command_buffer_size = -1; - } - - if (this_func_parameter_size + command_buffer_size < SIZE_BUFFER_COMMAND) - { - /*if (debug_gl) - log_gl("serializable opengl call.\n");*/ - last_command_buffer_size = command_buffer_size; - *(short*)(command_buffer + command_buffer_size) = func_number; - command_buffer_size += sizeof(short); - - for(i=0;iret_type == TYPE_CONST_CHAR) - { - try_to_put_into_phys_memory(ret_string, RET_STRING_SIZE); - } - -#ifndef WIN32 - if (getenv("GET_IMG_FROM_SERVER") != NULL && func_number == glXSwapBuffers_func) - { - } - else -#endif - ret_int = call_opengl(func_number, getpid(), (signature->ret_type == TYPE_CONST_CHAR) ? ret_string : NULL, args, args_size); - if (func_number == glXCreateContext_func) - { - if (debug_gl) - log_gl("ret_int = %d\n", ret_int); - } - else if (func_number == glXSwapBuffers_func || func_number == glXDestroyWindow_func || func_number == glFinish_func || func_number == glFlush_func) - { -#ifndef WIN32 - if (getenv("GET_IMG_FROM_SERVER")) - { - XWindowAttributes window_attributes_return; - XGetWindowAttributes(state->display, state->current_drawable, &window_attributes_return); - state->drawable_width = window_attributes_return.width; - state->drawable_height = window_attributes_return.height; - - char* buf = malloc(4 * state->drawable_width * state->drawable_height); - char* bufGL = malloc(4 * state->drawable_width * state->drawable_height); - XImage* img = XCreateImage(state->display, 0, 24, ZPixmap, 0, buf, state->drawable_width, state->drawable_height, 8, 0); - disable_warning_for_gl_read_pixels = 1; - - int pack_row_length, pack_alignment, pack_skip_rows, pack_skip_pixels; - int pack_pbo = state->pixelPackBuffer; - glGetIntegerv_no_lock(GL_PACK_ROW_LENGTH, &pack_row_length); - glGetIntegerv_no_lock(GL_PACK_ALIGNMENT, &pack_alignment); - glGetIntegerv_no_lock(GL_PACK_SKIP_ROWS, &pack_skip_rows); - glGetIntegerv_no_lock(GL_PACK_SKIP_PIXELS, &pack_skip_pixels); - glPixelStorei_no_lock(GL_PACK_ROW_LENGTH, 0); - glPixelStorei_no_lock(GL_PACK_ALIGNMENT, 4); - glPixelStorei_no_lock(GL_PACK_SKIP_ROWS, 0); - glPixelStorei_no_lock(GL_PACK_SKIP_PIXELS, 0); - if (pack_pbo) - glBindBufferARB_no_lock(GL_PIXEL_PACK_BUFFER_EXT, 0); - glReadPixels_no_lock(0, 0, state->drawable_width, state->drawable_height, GL_BGRA, GL_UNSIGNED_BYTE, bufGL); - glPixelStorei_no_lock(GL_PACK_ROW_LENGTH, pack_row_length); - glPixelStorei_no_lock(GL_PACK_ALIGNMENT, pack_alignment); - glPixelStorei_no_lock(GL_PACK_SKIP_ROWS, pack_skip_rows); - glPixelStorei_no_lock(GL_PACK_SKIP_PIXELS, pack_skip_pixels); - if (pack_pbo) - glBindBufferARB_no_lock(GL_PIXEL_PACK_BUFFER_EXT, pack_pbo); - disable_warning_for_gl_read_pixels = 0; - for(i=0;idrawable_height;i++) - { - memcpy(buf + i * 4 * state->drawable_width, - bufGL + (state->drawable_height-1-i) * 4 * state->drawable_width, - 4 * state->drawable_width); - } - free(bufGL); - GC gc = DefaultGC(state->display, DefaultScreen(state->display)); - XPutImage(state->display, state->current_drawable, gc, img, 0, 0, 0, 0, state->drawable_width, state->drawable_height); - XDestroyImage(img); - } - else -#endif - call_opengl(_synchronize_func, getpid(), NULL, NULL, NULL); - } - if (signature->ret_type == TYPE_UNSIGNED_INT || - signature->ret_type == TYPE_INT) - { - *(int*)ret_ptr = ret_int; - } - else if (signature->ret_type == TYPE_UNSIGNED_CHAR || - signature->ret_type == TYPE_CHAR) - { - *(char*)ret_ptr = ret_int; - } - else if (signature->ret_type == TYPE_CONST_CHAR) - { - *(char**)(ret_ptr) = ret_string; - } - } - -end_do_opengl_call: - (void)0; -} - -static inline void do_opengl_call(int func_number, void* ret_ptr, long* args, int* args_size_opt) -{ - LOCK(func_number); - do_opengl_call_no_lock(func_number, ret_ptr, args, args_size_opt); - UNLOCK(func_number); -} - -#include "client_stub.c" - -GLAPI void APIENTRY glPushAttrib(GLbitfield mask) -{ - GET_CURRENT_STATE(); - long args[] = { UNSIGNED_INT_TO_ARG(mask)}; - if (state->server_sp < MAX_SERVER_STATE_STACK_SIZE) - { - state->server_stack[state->server_sp].mask = mask; - if (mask & GL_ENABLE_BIT) - { - state->server_stack[state->server_sp].linesmoothEnabled = state->current_server_state.linesmoothEnabled; - state->server_stack[state->server_sp].lightingEnabled = state->current_server_state.lightingEnabled; - state->server_stack[state->server_sp].texture2DEnabled = state->current_server_state.texture2DEnabled; - state->server_stack[state->server_sp].blendEnabled = state->current_server_state.blendEnabled; - } - if (mask & GL_TRANSFORM_BIT) - { - state->server_stack[state->server_sp].matrixMode = state->current_server_state.matrixMode; - } - if (mask & GL_DEPTH_BUFFER_BIT) - { - state->server_stack[state->server_sp].depthFunc = state->current_server_state.depthFunc; - } - if (mask & GL_TEXTURE_BIT) - { - state->server_stack[state->server_sp].bindTexture2D = state->current_server_state.bindTexture2D; - state->server_stack[state->server_sp].bindTextureRectangle = state->current_server_state.bindTextureRectangle; - } - if (mask & GL_FOG_BIT) - { - state->server_stack[state->server_sp].fog = state->current_server_state.fog; - } - state->server_sp++; - } - else - { - log_gl("server_sp > MAX_SERVER_STATE_STACK_SIZE\n"); - } - do_opengl_call(glPushAttrib_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glPopAttrib() -{ - GET_CURRENT_STATE(); - if (state->server_sp > 0) - { - state->server_sp--; - if (state->server_stack[state->server_sp].mask & GL_ENABLE_BIT) - { - state->current_server_state.linesmoothEnabled = state->server_stack[state->server_sp].linesmoothEnabled; - state->current_server_state.lightingEnabled = state->server_stack[state->server_sp].lightingEnabled; - state->current_server_state.texture2DEnabled = state->server_stack[state->server_sp].texture2DEnabled; - state->current_server_state.blendEnabled = state->server_stack[state->server_sp].blendEnabled; - } - if (state->server_stack[state->server_sp].mask & GL_TRANSFORM_BIT) - { - state->current_server_state.matrixMode = state->server_stack[state->server_sp].matrixMode; - } - if (state->server_stack[state->server_sp].mask & GL_DEPTH_BUFFER_BIT) - { - state->current_server_state.depthFunc = state->server_stack[state->server_sp].depthFunc; - } - if (state->server_stack[state->server_sp].mask & GL_TEXTURE_BIT) - { - state->current_server_state.bindTexture2D = state->server_stack[state->server_sp].bindTexture2D; - state->current_server_state.bindTextureRectangle = state->server_stack[state->server_sp].bindTextureRectangle; - } - if (state->server_stack[state->server_sp].mask & GL_FOG_BIT) - { - state->current_server_state.fog = state->server_stack[state->server_sp].fog; - } - } - else - { - log_gl("server_sp <= 0\n"); - } - do_opengl_call(glPopAttrib_func, NULL, NULL, NULL); -} - -/* 'glIsEnabled'�� ���� static function �� */ -static GLboolean APIENTRY _glIsEnabled( GLenum cap ) -{ - GLboolean ret = 0; - GET_CURRENT_STATE(); - if (!disable_optim) - { - if (cap == GL_LINE_SMOOTH) - { - return state->current_server_state.linesmoothEnabled; - } - else if (cap == GL_LIGHTING) - { - return state->current_server_state.lightingEnabled; - } - else if (cap == GL_TEXTURE_2D) - { - return state->current_server_state.texture2DEnabled; - } - else if (cap == GL_BLEND) - { - return state->current_server_state.blendEnabled; - } - else if (cap == GL_SCISSOR_TEST) - { - return state->current_server_state.scissorTestEnabled; - } - else if (cap == GL_VERTEX_PROGRAM_NV) - { - return state->current_server_state.vertexProgramEnabled; - } - else if (cap == GL_FOG) - { - return state->current_server_state.fogEnabled; - } - } - long args[] = { INT_TO_ARG(cap) }; - do_opengl_call(glIsEnabled_func, &ret, args, NULL); - return ret; -} - -GLAPI GLboolean APIENTRY glIsEnabled( GLenum cap ) -{ - GLboolean ret = 0; - - if (debug_gl) log_gl("glIsEnabled(0x%X)\n", cap); - - ret = _glIsEnabled(cap); - - if (debug_gl) log_gl("glIsEnabled(0x%X) = %d\n", cap, ret); - return ret; -} - -static ClientArray* _getArray(GLenum cap, int verbose) -{ - GET_CURRENT_STATE(); - switch(cap) - { - case GL_VERTEX_ARRAY: return &state->client_state.arrays.vertexArray; - case GL_COLOR_ARRAY: return &state->client_state.arrays.colorArray; - case GL_SECONDARY_COLOR_ARRAY: return &state->client_state.arrays.secondaryColorArray; - case GL_NORMAL_ARRAY: return &state->client_state.arrays.normalArray; - case GL_INDEX_ARRAY: return &state->client_state.arrays.indexArray; - case GL_TEXTURE_COORD_ARRAY: - return &state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture]; - case GL_EDGE_FLAG_ARRAY: return &state->client_state.arrays.edgeFlagArray; - case GL_WEIGHT_ARRAY_ARB: return &state->client_state.arrays.weightArray; - case GL_MATRIX_INDEX_ARRAY_POINTER_ARB: return &state->client_state.arrays.matrixIndexArray; - case GL_FOG_COORD_ARRAY: return &state->client_state.arrays.fogCoordArray; - case GL_ELEMENT_ARRAY_ATI: return &state->client_state.arrays.elementArrayATI; - default: - if (cap >= GL_VERTEX_ATTRIB_ARRAY0_NV && cap < GL_VERTEX_ATTRIB_ARRAY0_NV + MY_GL_MAX_VERTEX_ATTRIBS_NV) - return &state->client_state.arrays.vertexAttribArrayNV[cap - GL_VERTEX_ATTRIB_ARRAY0_NV]; - if (verbose) log_gl("unhandled cap : %d\n", cap); return NULL; - } -} - - -GLAPI void APIENTRY glEnable(GLenum cap) -{ - GET_CURRENT_STATE(); - /* Strange but some programs use glEnable(GL_VERTEX_ARRAY) - instead of glEnableClientState(GL_VERTEX_ARRAY) ... - I've discovered that while trying to make the spheres demo of chromium running - and mesa confirms it too */ - if (_getArray(cap, 0)) - { - glEnableClientState(cap); - return; - } - - if (cap == GL_LINE_SMOOTH) - { - state->current_server_state.linesmoothEnabled = 1; - } - else if (cap == GL_LIGHTING) - { - state->current_server_state.lightingEnabled = 1; - } - else if (cap == GL_TEXTURE_2D) - { - state->current_server_state.texture2DEnabled = 1; - } - else if (cap == GL_BLEND) - { - state->current_server_state.blendEnabled = 1; - } - else if (cap == GL_SCISSOR_TEST) - { - state->current_server_state.scissorTestEnabled = 1; - } - else if (cap == GL_VERTEX_PROGRAM_NV) - { - state->current_server_state.vertexProgramEnabled = 1; - } - else if (cap == GL_FOG) - { - state->current_server_state.fogEnabled = 1; - } - long args[] = { INT_TO_ARG(cap)}; - do_opengl_call(glEnable_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glDisable(GLenum cap) -{ - GET_CURRENT_STATE(); - if (_getArray(cap, 0)) - { - glDisableClientState(cap); - return; - } - - if (cap == GL_LINE_SMOOTH) - { - state->current_server_state.linesmoothEnabled = 0; - } - else if (cap == GL_LIGHTING) - { - state->current_server_state.lightingEnabled = 0; - } - else if (cap == GL_TEXTURE_2D) - { - state->current_server_state.texture2DEnabled = 0; - } - else if (cap == GL_BLEND) - { - state->current_server_state.blendEnabled = 0; - } - else if (cap == GL_SCISSOR_TEST) - { - state->current_server_state.scissorTestEnabled = 0; - } - else if (cap == GL_VERTEX_PROGRAM_NV) - { - state->current_server_state.vertexProgramEnabled = 0; - } - else if (cap == GL_FOG) - { - state->current_server_state.fogEnabled = 0; - } - long args[] = { INT_TO_ARG(cap)}; - do_opengl_call(glDisable_func, NULL, args, NULL); -} - -#define GET_CAP_NAME(x) case x: return #x; -static const char* _getArrayName(GLenum cap) -{ - switch (cap) - { - GET_CAP_NAME(GL_VERTEX_ARRAY); - GET_CAP_NAME(GL_COLOR_ARRAY); - GET_CAP_NAME(GL_SECONDARY_COLOR_ARRAY); - GET_CAP_NAME(GL_NORMAL_ARRAY); - GET_CAP_NAME(GL_INDEX_ARRAY); - GET_CAP_NAME(GL_TEXTURE_COORD_ARRAY); - GET_CAP_NAME(GL_EDGE_FLAG_ARRAY); - GET_CAP_NAME(GL_WEIGHT_ARRAY_ARB); - GET_CAP_NAME(GL_MATRIX_INDEX_ARRAY_ARB); - GET_CAP_NAME(GL_FOG_COORD_ARRAY); - GET_CAP_NAME(GL_ELEMENT_ARRAY_ATI); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY0_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY1_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY2_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY3_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY4_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY5_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY6_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY7_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY8_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY9_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY10_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY11_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY12_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY13_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY14_NV); - GET_CAP_NAME(GL_VERTEX_ATTRIB_ARRAY15_NV); - } - return "unknown"; -} - -GLAPI void APIENTRY EXT_FUNC(glEnableVertexAttribArrayARB)(GLuint index) -{ - CHECK_PROC(glEnableVertexAttribArrayARB); - GET_CURRENT_STATE(); - long args[] = { index }; - do_opengl_call(glEnableVertexAttribArrayARB_func, NULL, args, NULL); - - if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB) - { - state->client_state.arrays.vertexAttribArray[index].enabled = 1; - } - else - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB\n"); - } -} - -GLAPI void APIENTRY EXT_FUNC(glEnableVertexAttribArray)(GLuint index) -{ - CHECK_PROC(glEnableVertexAttribArray); - GET_CURRENT_STATE(); - long args[] = { index }; - do_opengl_call(glEnableVertexAttribArray_func, NULL, args, NULL); - - if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB) - { - state->client_state.arrays.vertexAttribArray[index].enabled = 1; - } - else - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB\n"); - } -} - - -GLAPI void APIENTRY EXT_FUNC(glDisableVertexAttribArrayARB)(GLuint index) -{ - CHECK_PROC(glDisableVertexAttribArrayARB); - GET_CURRENT_STATE(); - long args[] = { index }; - do_opengl_call(glDisableVertexAttribArrayARB_func, NULL, args, NULL); - - if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB) - { - state->client_state.arrays.vertexAttribArray[index].enabled = 0; - } - else - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB\n"); - } -} - -GLAPI void APIENTRY EXT_FUNC(glDisableVertexAttribArray)(GLuint index) -{ - CHECK_PROC(glDisableVertexAttribArray); - GET_CURRENT_STATE(); - long args[] = { index }; - do_opengl_call(glDisableVertexAttribArray_func, NULL, args, NULL); - - if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB) - { - state->client_state.arrays.vertexAttribArray[index].enabled = 0; - } - else - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB\n"); - } -} - -GLAPI void APIENTRY glEnableClientState(GLenum cap) -{ - if (cap == GL_VERTEX_ARRAY_RANGE_NV || - cap == GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV) return; /* FIXME */ - GET_CURRENT_STATE(); - ClientArray* array = _getArray(cap, 1); - if (array == NULL) return; - if (debug_array_ptr) - { - if (cap == GL_TEXTURE_COORD_ARRAY) - log_gl("enable texture %d\n", state->client_state.clientActiveTexture); - else - log_gl("enable feature %s\n", _getArrayName(cap)); - } - if ((!disable_optim) && array->enabled) - { - //log_gl("discard useless command\n"); - return; - } - array->enabled = 1; - /*if ((!disable_optim) && cap == GL_TEXTURE_COORD_ARRAY) - { - long args[] = { UNSIGNED_INT_TO_ARG(state->client_state.clientActiveTexture + GL_TEXTURE0_ARB)}; - do_opengl_call(glClientActiveTexture_func, NULL, args, NULL); - }*/ - long args[] = { UNSIGNED_INT_TO_ARG(cap)}; - do_opengl_call(glEnableClientState_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glDisableClientState(GLenum cap) -{ - if (cap == GL_VERTEX_ARRAY_RANGE_NV || - cap == GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV) return; /* FIXME */ - GET_CURRENT_STATE(); - ClientArray* array = _getArray(cap, 1); - if (array == NULL) return; - if (debug_array_ptr) - { - if (cap == GL_TEXTURE_COORD_ARRAY) - log_gl("disable texture %d\n", state->client_state.clientActiveTexture); - else - log_gl("disable feature %s\n", _getArrayName(cap)); - } - - if ((!disable_optim) && array->enabled == 0) - { - //log_gl("discard useless command\n"); - return; - } - array->enabled = 0; - /*if ((!disable_optim) && cap == GL_TEXTURE_COORD_ARRAY) - { - long args[] = { UNSIGNED_INT_TO_ARG(state->client_state.clientActiveTexture + GL_TEXTURE0_ARB)}; - do_opengl_call(glClientActiveTexture_func, NULL, args, NULL); - }*/ - long args[] = { UNSIGNED_INT_TO_ARG(cap)}; - do_opengl_call(glDisableClientState_func, NULL, args, NULL); -} - - -GLAPI void APIENTRY glClientActiveTexture(GLenum texture) -{ - GET_CURRENT_STATE(); - - if (disable_optim || state->client_state.clientActiveTexture != (int)texture - GL_TEXTURE0_ARB) - { - long args[] = { UNSIGNED_INT_TO_ARG(texture)}; - do_opengl_call(glClientActiveTexture_func, NULL, args, NULL); - } - - state->client_state.clientActiveTexture = (int)texture - GL_TEXTURE0_ARB; - - assert(state->client_state.clientActiveTexture >= 0 && - state->client_state.clientActiveTexture < NB_MAX_TEXTURES); -} - -GLAPI void APIENTRY glClientActiveTextureARB(GLenum texture) -{ - glClientActiveTexture(texture); -} - -GLAPI void APIENTRY glActiveTextureARB(GLenum texture) -{ - GET_CURRENT_STATE(); - if (disable_optim || state->activeTexture != texture) - { - state->activeTexture = texture; - - long args[] = { INT_TO_ARG(texture) }; - do_opengl_call(glActiveTextureARB_func, NULL, args, NULL); - } -} - -GLAPI void APIENTRY glPushClientAttrib(GLbitfield mask) -{ - GET_CURRENT_STATE(); - long args[] = { UNSIGNED_INT_TO_ARG(mask)}; - if (state->client_state_sp < MAX_CLIENT_STATE_STACK_SIZE) - { - state->client_state_stack[state->client_state_sp].mask = mask; - if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) - { - state->client_state_stack[state->client_state_sp].arrays = state->client_state.arrays; - } - if (mask & GL_CLIENT_PIXEL_STORE_BIT) - { - state->client_state_stack[state->client_state_sp].pack = state->client_state.pack; - state->client_state_stack[state->client_state_sp].unpack = state->client_state.unpack; - } - state->client_state_sp++; - } - else - { - log_gl("state->client_state_sp > MAX_CLIENT_STATE_STACK_SIZE\n"); - } - do_opengl_call(glPushClientAttrib_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glPopClientAttrib() -{ - GET_CURRENT_STATE(); - if (state->client_state_sp > 0) - { - state->client_state_sp--; - if (state->client_state_stack[state->client_state_sp].mask & GL_CLIENT_VERTEX_ARRAY_BIT) - { - state->client_state.arrays = state->client_state_stack[state->client_state_sp].arrays; - } - if (state->client_state_stack[state->client_state_sp].mask & GL_CLIENT_PIXEL_STORE_BIT) - { - state->client_state.pack = state->client_state_stack[state->client_state_sp].pack; - state->client_state.unpack = state->client_state_stack[state->client_state_sp].unpack; - } - } - else - { - log_gl("state->client_state_sp <= 0\n"); - } - do_opengl_call(glPopClientAttrib_func, NULL, NULL, NULL); -} - -static void _glPixelStore(GLenum pname, GLint param) -{ - GET_CURRENT_STATE(); - switch (pname) - { - case GL_PACK_SWAP_BYTES: state->client_state.pack.swapEndian = param != 0; break; - case GL_PACK_LSB_FIRST: state->client_state.pack.lsbFirst = param != 0; break; - case GL_PACK_ROW_LENGTH: if (param >= 0) state->client_state.pack.rowLength = param; break; - case GL_PACK_IMAGE_HEIGHT: if (param >= 0) state->client_state.pack.imageHeight = param; break; - case GL_PACK_SKIP_ROWS: if (param >= 0) state->client_state.pack.skipRows = param; break; - case GL_PACK_SKIP_PIXELS: if (param >= 0) state->client_state.pack.skipPixels = param; break; - case GL_PACK_SKIP_IMAGES: if (param >= 0) state->client_state.pack.skipImages = param; break; - case GL_PACK_ALIGNMENT: if (param == 1 || param == 2 || param == 4 || param == 8) - state->client_state.pack.alignment = param; break; - case GL_UNPACK_SWAP_BYTES: state->client_state.unpack.swapEndian = param != 0; break; - case GL_UNPACK_LSB_FIRST: state->client_state.unpack.lsbFirst = param != 0; break; - case GL_UNPACK_ROW_LENGTH: if (param >= 0) state->client_state.unpack.rowLength = param; break; - case GL_UNPACK_IMAGE_HEIGHT: if (param >= 0) state->client_state.unpack.imageHeight = param; break; - case GL_UNPACK_SKIP_ROWS: if (param >= 0) state->client_state.unpack.skipRows = param; break; - case GL_UNPACK_SKIP_PIXELS: if (param >= 0) state->client_state.unpack.skipPixels = param; break; - case GL_UNPACK_SKIP_IMAGES: if (param >= 0) state->client_state.unpack.skipImages = param; break; - case GL_UNPACK_ALIGNMENT: if (param == 1 || param == 2 || param == 4 || param == 8) - state->client_state.unpack.alignment = param; break; - default: log_gl("unhandled pname %d\n", pname); break; - } -} - -GLAPI void APIENTRY glPixelStoref(GLenum pname, GLfloat param) -{ - long args[] = { UNSIGNED_INT_TO_ARG(pname), FLOAT_TO_ARG(param)}; - if (!(pname == GL_PACK_SKIP_PIXELS || pname == GL_PACK_SKIP_PIXELS || pname == GL_PACK_SKIP_IMAGES || - pname == GL_UNPACK_SKIP_PIXELS || pname == GL_UNPACK_SKIP_PIXELS || pname == GL_UNPACK_SKIP_IMAGES)) - { - _glPixelStore(pname, (GLint)(param + 0.5)); - do_opengl_call(glPixelStoref_func, NULL, args, NULL); - } -} - -static void glPixelStorei_no_lock(GLenum pname, GLint param) -{ - _glPixelStore(pname, param); - if (!(pname == GL_PACK_SKIP_PIXELS || pname == GL_PACK_SKIP_ROWS || pname == GL_PACK_SKIP_IMAGES || - pname == GL_UNPACK_SKIP_PIXELS || pname == GL_UNPACK_SKIP_ROWS || pname == GL_UNPACK_SKIP_IMAGES)) - { - long args[] = { UNSIGNED_INT_TO_ARG(pname), INT_TO_ARG(param)}; - do_opengl_call_no_lock(glPixelStorei_func, NULL, args, NULL); - } -} - -GLAPI void APIENTRY glPixelStorei(GLenum pname, GLint param) -{ - LOCK(glPixelStorei_func); - glPixelStorei_no_lock(pname, param); - UNLOCK(glPixelStorei_func); -} - -static int get_nb_composants_of_gl_get_constant_compare(const void* a, const void* b) -{ - GlGetConstant* constantA = (GlGetConstant*)a; - GlGetConstant* constantB = (GlGetConstant*)b; - return constantA->token - constantB->token; -} - -static int get_size_get_boolean_integer_float_double_v(int func_number, int pname) -{ - GlGetConstant constant; - GlGetConstant* found; - constant.token = pname; - found = bsearch(&constant, gl_get_constants, - sizeof(gl_get_constants) / sizeof(GlGetConstant), sizeof(GlGetConstant), - get_nb_composants_of_gl_get_constant_compare); - if (found) - return found->count; - else - { - log_gl("unknown name for %s : %d\n", tab_opengl_calls_name[func_number], pname); - log_gl("hoping that size is 1...\n"); - return 1; - } -} - - -#define AFFECT_N(x, y, N) do { int _i; for(_i=0;_i= GL_MODELVIEW && mode <= GL_TEXTURE) || \ - (mode == GL_MATRIX_PALETTE_ARB) || \ - (mode == GL_MODELVIEW1_ARB) || \ - (mode >= GL_MODELVIEW2_ARB && mode <= GL_MODELVIEW31_ARB)) - -#define MATRIX_MODE_TO_MATRIX_INDEX(mode) \ - ((mode == GL_MODELVIEW) ? 0 : \ - (mode == GL_PROJECTION) ? 1 : \ - (mode == GL_TEXTURE) ? 2 + state->activeTexture - GL_TEXTURE0_ARB: \ - (mode == GL_MATRIX_PALETTE_ARB) ? 2 + NB_MAX_TEXTURES : \ - (mode == GL_MODELVIEW1_ARB) ? 3 + NB_MAX_TEXTURES : \ - (mode >= GL_MODELVIEW2_ARB && mode <= GL_MODELVIEW31_ARB) ? 4 + NB_MAX_TEXTURES + mode - GL_MODELVIEW2_ARB : -1) - -static int maxTextureSize = -1; /* optimization for ppracer */ -static int maxTextureUnits = -1; - -static int _glGetIntegerv(GLenum pname) -{ - int ret; - long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(&ret) }; - int args_size[] = { 0, sizeof(int) }; - do_opengl_call_no_lock(glGetIntegerv_func, NULL, CHECK_ARGS(args, args_size)); - return ret; -} - -#define glGetf(funcName, funcNumber, cType, typeBase) \ - static void CONCAT(funcName,_no_lock)( GLenum pname, cType *params ) \ -{ \ - GET_CURRENT_STATE(); \ - switch (pname) \ - { \ - case GL_VERTEX_ARRAY: *params = state->client_state.arrays.vertexArray.enabled; break; \ - case GL_NORMAL_ARRAY: *params = state->client_state.arrays.normalArray.enabled; break; \ - case GL_COLOR_ARRAY: *params = state->client_state.arrays.colorArray.enabled; break; \ - case GL_INDEX_ARRAY: *params = state->client_state.arrays.indexArray.enabled; break; \ - case GL_TEXTURE_COORD_ARRAY: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].enabled; break; \ - case GL_EDGE_FLAG_ARRAY: *params = state->client_state.arrays.edgeFlagArray.enabled; break; \ - case GL_SECONDARY_COLOR_ARRAY: *params = state->client_state.arrays.secondaryColorArray.enabled; break; \ - case GL_FOG_COORDINATE_ARRAY: *params = state->client_state.arrays.fogCoordArray.enabled; break; \ - case GL_WEIGHT_ARRAY_ARB: *params = state->client_state.arrays.weightArray.enabled; break; \ - case GL_VERTEX_ARRAY_SIZE: *params = state->client_state.arrays.vertexArray.size; break; \ - case GL_VERTEX_ARRAY_TYPE: *params = state->client_state.arrays.vertexArray.type; break; \ - case GL_VERTEX_ARRAY_STRIDE: *params = state->client_state.arrays.vertexArray.stride; break; \ - case GL_NORMAL_ARRAY_TYPE: *params = state->client_state.arrays.normalArray.type; break; \ - case GL_NORMAL_ARRAY_STRIDE: *params = state->client_state.arrays.normalArray.stride; break; \ - case GL_COLOR_ARRAY_SIZE: *params = state->client_state.arrays.colorArray.size; break; \ - case GL_COLOR_ARRAY_TYPE: *params = state->client_state.arrays.colorArray.type; break; \ - case GL_COLOR_ARRAY_STRIDE: *params = state->client_state.arrays.colorArray.stride; break; \ - case GL_INDEX_ARRAY_TYPE: *params = state->client_state.arrays.indexArray.type; break; \ - case GL_INDEX_ARRAY_STRIDE: *params = state->client_state.arrays.indexArray.stride; break; \ - case GL_TEXTURE_COORD_ARRAY_SIZE: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].size; break; \ - case GL_TEXTURE_COORD_ARRAY_TYPE: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].type; break; \ - case GL_TEXTURE_COORD_ARRAY_STRIDE: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].stride; break; \ - case GL_EDGE_FLAG_ARRAY_STRIDE: *params = state->client_state.arrays.edgeFlagArray.stride; break; \ - case GL_SECONDARY_COLOR_ARRAY_SIZE: *params = state->client_state.arrays.secondaryColorArray.size; break; \ - case GL_SECONDARY_COLOR_ARRAY_TYPE: *params = state->client_state.arrays.secondaryColorArray.type; break; \ - case GL_SECONDARY_COLOR_ARRAY_STRIDE: *params = state->client_state.arrays.secondaryColorArray.stride; break; \ - case GL_FOG_COORDINATE_ARRAY_TYPE: *params = state->client_state.arrays.fogCoordArray.type; break; \ - case GL_FOG_COORDINATE_ARRAY_POINTER: *params = state->client_state.arrays.fogCoordArray.stride; break; \ - case GL_WEIGHT_ARRAY_SIZE_ARB: *params = state->client_state.arrays.weightArray.size; break; \ - case GL_WEIGHT_ARRAY_TYPE_ARB: *params = state->client_state.arrays.weightArray.type; break; \ - case GL_WEIGHT_ARRAY_STRIDE_ARB: *params = state->client_state.arrays.weightArray.stride; break; \ - case GL_MATRIX_INDEX_ARRAY_SIZE_ARB: *params = state->client_state.arrays.matrixIndexArray.size; break; \ - case GL_MATRIX_INDEX_ARRAY_TYPE_ARB: *params = state->client_state.arrays.matrixIndexArray.type; break; \ - case GL_MATRIX_INDEX_ARRAY_STRIDE_ARB: *params = state->client_state.arrays.matrixIndexArray.stride; break; \ - case GL_VERTEX_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.vertexArray.vbo_name; break; \ - case GL_NORMAL_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.normalArray.vbo_name; break; \ - case GL_COLOR_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.colorArray.vbo_name; break; \ - case GL_INDEX_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.indexArray.vbo_name; break; \ - case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].vbo_name; break; \ - case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.edgeFlagArray.vbo_name; break; \ - case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.secondaryColorArray.vbo_name; break; \ - case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.fogCoordArray.vbo_name; break; \ - case GL_WEIGHT_ARRAY_BUFFER_BINDING: *params = state->client_state.arrays.weightArray.vbo_name; break; \ - case GL_PACK_SWAP_BYTES: *params = state->client_state.pack.swapEndian; break; \ - case GL_PACK_LSB_FIRST: *params = state->client_state.pack.lsbFirst; break; \ - case GL_PACK_ROW_LENGTH: *params = state->client_state.pack.rowLength; break; \ - case GL_PACK_IMAGE_HEIGHT: *params = state->client_state.pack.imageHeight; break; \ - case GL_PACK_SKIP_ROWS: *params = state->client_state.pack.skipRows; break; \ - case GL_PACK_SKIP_PIXELS: *params = state->client_state.pack.skipPixels; break; \ - case GL_PACK_SKIP_IMAGES: *params = state->client_state.pack.skipImages; break; \ - case GL_PACK_ALIGNMENT: *params = state->client_state.pack.alignment; break; \ - case GL_UNPACK_SWAP_BYTES: *params = state->client_state.unpack.swapEndian; break; \ - case GL_UNPACK_LSB_FIRST: *params = state->client_state.unpack.lsbFirst; break; \ - case GL_UNPACK_ROW_LENGTH: *params = state->client_state.unpack.rowLength; break; \ - case GL_UNPACK_IMAGE_HEIGHT: *params = state->client_state.unpack.imageHeight; break; \ - case GL_UNPACK_SKIP_ROWS: *params = state->client_state.unpack.skipRows; break; \ - case GL_UNPACK_SKIP_PIXELS: *params = state->client_state.unpack.skipPixels; break; \ - case GL_UNPACK_SKIP_IMAGES: *params = state->client_state.unpack.skipImages; break; \ - case GL_UNPACK_ALIGNMENT: *params = state->client_state.unpack.alignment; break; \ - case GL_TEXTURE_2D_BINDING_EXT: *params = state->current_server_state.bindTexture2D; break; \ - case GL_TEXTURE_BINDING_RECTANGLE_ARB: *params = state->current_server_state.bindTextureRectangle; break; \ - case GL_VIEWPORT: params[0] = state->viewport.x; params[1] = state->viewport.y; params[2] = state->viewport.width; params[3] = state->viewport.height; break; \ - case GL_SCISSOR_BOX: params[0] = state->scissorbox.x; params[1] = state->scissorbox.y; params[2] = state->scissorbox.width; params[3] = state->scissorbox.height; break; \ - case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: *params = 16; break;\ - case GL_MATRIX_MODE: *params = state->current_server_state.matrixMode; break; \ - case GL_DEPTH_FUNC: *params = state->current_server_state.depthFunc; break; \ - case GL_FOG_MODE: *params = state->current_server_state.fog.mode; break; \ - case GL_FOG_DENSITY: *params = state->current_server_state.fog.density; break; \ - case GL_FOG_START: *params = state->current_server_state.fog.start; break; \ - case GL_FOG_END: *params = state->current_server_state.fog.end; break; \ - case GL_FOG_INDEX: *params = state->current_server_state.fog.index; break; \ - case GL_FOG_COLOR: AFFECT_N(params, state->current_server_state.fog.color, 4); break; \ - case GL_COMPRESSED_TEXTURE_FORMATS_ARB: \ - { \ - long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) }; \ - int args_size[] = { 0, 0 }; \ - int nb_compressed_texture_formats = 0; \ - glGetIntegerv_no_lock(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &nb_compressed_texture_formats); \ - args_size[1] = tab_args_type_length[typeBase] * nb_compressed_texture_formats; \ - do_opengl_call_no_lock(funcNumber, NULL, CHECK_ARGS(args, args_size)); \ - break; \ - } \ - case GL_ARRAY_BUFFER_BINDING: *params = state->arrayBuffer; break; \ - case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB: *params = state->elementArrayBuffer; break; \ - case GL_MAX_TEXTURE_SIZE: if (maxTextureSize == -1) maxTextureSize = _glGetIntegerv(pname); *params = maxTextureSize; break; \ - case GL_MAX_TEXTURE_UNITS_ARB: if (maxTextureUnits == -1) maxTextureUnits = _glGetIntegerv(pname); *params = maxTextureUnits; break; \ - case GL_MODELVIEW_MATRIX: \ - case GL_PROJECTION_MATRIX: \ - case GL_TEXTURE_MATRIX: AFFECT_N(params, state->matrix[pname - GL_MODELVIEW_MATRIX].current.val, 16); break; \ - case GL_CURRENT_RASTER_POSITION: \ - { \ - if (!state->currentRasterPosKnown) \ - { \ - long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(state->currentRasterPos) }; \ - int args_size[] = { 0, 4 * sizeof(float) }; \ - log_gl("getting value 0x%X\n", pname); \ - do_opengl_call_no_lock(glGetFloatv_func, NULL, CHECK_ARGS(args, args_size)); \ - state->currentRasterPosKnown = 1; \ - } \ - AFFECT_N(params, state->currentRasterPos, 4); \ - break; \ - } \ - default: \ - { \ - long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) }; \ - int args_size[] = { 0, 0 }; \ - args_size[1] = tab_args_type_length[typeBase] * get_size_get_boolean_integer_float_double_v(funcNumber, pname); \ - log_gl("getting value 0x%X\n", pname); \ - do_opengl_call_no_lock(funcNumber, NULL, CHECK_ARGS(args, args_size)); \ - if (typeBase == TYPE_INT) log_gl("val=%d\n", (int)*params); \ - else if (typeBase == TYPE_FLOAT) log_gl("val=%f\n", (float)*params); \ - } \ - } \ -} \ -GLAPI void APIENTRY funcName( GLenum pname, cType *params ) \ -{ \ - LOCK(funcNumber); \ - CONCAT(funcName,_no_lock)(pname, params); \ - UNLOCK(funcNumber); \ -} - -glGetf(glGetBooleanv, glGetBooleanv_func, GLboolean, TYPE_CHAR); -glGetf(glGetIntegerv, glGetIntegerv_func, GLint, TYPE_INT); -glGetf(glGetFloatv, glGetFloatv_func, GLfloat, TYPE_FLOAT); -glGetf(glGetDoublev, glGetDoublev_func, GLdouble, TYPE_DOUBLE); - -GLAPI void APIENTRY glDepthFunc(GLenum func) -{ - long args[] = { UNSIGNED_INT_TO_ARG(func)}; - GET_CURRENT_STATE(); - state->current_server_state.depthFunc = func; - do_opengl_call(glDepthFunc_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glClipPlane(GLenum plane, const GLdouble * equation) -{ - GET_CURRENT_STATE(); - if (plane >= GL_CLIP_PLANE0 && plane < GL_CLIP_PLANE0 + N_CLIP_PLANES) - memcpy(state->current_server_state.clipPlanes[plane-GL_CLIP_PLANE0], equation, 4 * sizeof(double)); - long args[] = { UNSIGNED_INT_TO_ARG(plane), POINTER_TO_ARG(equation)}; - do_opengl_call(glClipPlane_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glGetClipPlane(GLenum plane, GLdouble * equation) -{ - GET_CURRENT_STATE(); - if (plane >= GL_CLIP_PLANE0 && plane < GL_CLIP_PLANE0 + N_CLIP_PLANES) - { - memcpy(equation, state->current_server_state.clipPlanes[plane-GL_CLIP_PLANE0], 4 * sizeof(double)); - return; - } - long args[] = { UNSIGNED_INT_TO_ARG(plane), POINTER_TO_ARG(equation)}; - do_opengl_call(glGetClipPlane_func, NULL, args, NULL); -} - - -GLAPI void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) -{ - GET_CURRENT_STATE(); - long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height)}; - state->viewport.x = x; - state->viewport.y = y; - state->viewport.width = width; - state->viewport.height = height; - if (debug_gl) log_gl("viewport %d,%d,%d,%d\n", x, y, width, height); - do_opengl_call(glViewport_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) -{ - GET_CURRENT_STATE(); - long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height)}; - state->scissorbox.x = x; - state->scissorbox.y = y; - state->scissorbox.width = width; - state->scissorbox.height = height; - do_opengl_call(glScissor_func, NULL, args, NULL); -} - - -/* Matrix optimization : openquartz */ -#if 1 -GLAPI void APIENTRY glMatrixMode(GLenum mode) -{ - GET_CURRENT_STATE(); - long args[] = { UNSIGNED_INT_TO_ARG(mode)}; - if (IS_VALID_MATRIX_MODE(mode)) - state->current_server_state.matrixMode = mode; - do_opengl_call(glMatrixMode_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glPushMatrix() -{ - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - if (state->matrix[index_mode].sp < MAX_MATRIX_STACK_SIZE) - { - memcpy(state->matrix[index_mode].stack[state->matrix[index_mode].sp].val, - state->matrix[index_mode].current.val, - 16 * sizeof(double)); - state->matrix[index_mode].sp++; - } - else - { - log_gl("matrix[mode].sp >= MAX_MATRIX_STACK_SIZE\n"); - } - } - - do_opengl_call(glPushMatrix_func, NULL, NULL, NULL); -} - -GLAPI void APIENTRY glPopMatrix() -{ - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - if (state->matrix[index_mode].sp > 0) - { - state->matrix[index_mode].sp--; - memcpy(state->matrix[index_mode].current.val, - state->matrix[index_mode].stack[state->matrix[index_mode].sp].val, - 16 * sizeof(double)); - } - else - { - log_gl("matrix[mode].sp <= 0\n"); - } - } - - do_opengl_call(glPopMatrix_func, NULL, NULL, NULL); -} - -GLAPI void APIENTRY glLoadIdentity() -{ - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - int j; - if (index_mode >= 0) - { - for(j=0;j<16;j++) - { - state->matrix[index_mode].current.val[j] = (j == 0 || j == 5 || j == 10 || j == 15); - } - } - do_opengl_call(glLoadIdentity_func, NULL, NULL, NULL); -} - -static void _internal_glLoadMatrixd(const GLdouble matrix[16]) -{ - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - memcpy(state->matrix[index_mode].current.val, matrix, 16 * sizeof(double)); -} - -static void _internal_glLoadMatrixf(const GLfloat matrix[16]) -{ - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - int i; - for(i=0;i<16;i++) - state->matrix[index_mode].current.val[i] = matrix[i]; - } -} - -GLAPI void APIENTRY glLoadMatrixd(const GLdouble matrix[16]) -{ - _internal_glLoadMatrixd(matrix); - long args[] = { POINTER_TO_ARG(matrix)}; - do_opengl_call(glLoadMatrixd_func, NULL, args, NULL); -} - -static void matrixfToMatrixd(const GLfloat matrixf[16], GLdouble matrix[16]) -{ - int i; - for(i=0;i<16;i++) - { - matrix[i] = matrixf[i]; - } -} - -GLAPI void APIENTRY glLoadMatrixf(const GLfloat matrix[16]) -{ - _internal_glLoadMatrixf(matrix); - - long args[] = { POINTER_TO_ARG(matrix)}; - do_opengl_call(glLoadMatrixf_func, NULL, args, NULL); -} - -static void _internal_glMultMatrixd(const GLdouble matrix[16]) -{ - GET_CURRENT_STATE(); - GLdouble destMatrix[16]; - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - GLdouble* oriMatrix = state->matrix[index_mode].current.val; - - /* t(C)=t(A.B)=t(B).t(A) */ - - destMatrix[0*4+0] = matrix[0*4+0] * oriMatrix[0*4+0] + - matrix[0*4+1] * oriMatrix[1*4+0] + - matrix[0*4+2] * oriMatrix[2*4+0] + - matrix[0*4+3] * oriMatrix[3*4+0]; - destMatrix[0*4+1] = matrix[0*4+0] * oriMatrix[0*4+1] + - matrix[0*4+1] * oriMatrix[1*4+1] + - matrix[0*4+2] * oriMatrix[2*4+1] + - matrix[0*4+3] * oriMatrix[3*4+1]; - destMatrix[0*4+2] = matrix[0*4+0] * oriMatrix[0*4+2] + - matrix[0*4+1] * oriMatrix[1*4+2] + - matrix[0*4+2] * oriMatrix[2*4+2] + - matrix[0*4+3] * oriMatrix[3*4+2]; - destMatrix[0*4+3] = matrix[0*4+0] * oriMatrix[0*4+3] + - matrix[0*4+1] * oriMatrix[1*4+3] + - matrix[0*4+2] * oriMatrix[2*4+3] + - matrix[0*4+3] * oriMatrix[3*4+3]; - - destMatrix[1*4+0] = matrix[1*4+0] * oriMatrix[0*4+0] + - matrix[1*4+1] * oriMatrix[1*4+0] + - matrix[1*4+2] * oriMatrix[2*4+0] + - matrix[1*4+3] * oriMatrix[3*4+0]; - destMatrix[1*4+1] = matrix[1*4+0] * oriMatrix[0*4+1] + - matrix[1*4+1] * oriMatrix[1*4+1] + - matrix[1*4+2] * oriMatrix[2*4+1] + - matrix[1*4+3] * oriMatrix[3*4+1]; - destMatrix[1*4+2] = matrix[1*4+0] * oriMatrix[0*4+2] + - matrix[1*4+1] * oriMatrix[1*4+2] + - matrix[1*4+2] * oriMatrix[2*4+2] + - matrix[1*4+3] * oriMatrix[3*4+2]; - destMatrix[1*4+3] = matrix[1*4+0] * oriMatrix[0*4+3] + - matrix[1*4+1] * oriMatrix[1*4+3] + - matrix[1*4+2] * oriMatrix[2*4+3] + - matrix[1*4+3] * oriMatrix[3*4+3]; - - destMatrix[2*4+0] = matrix[2*4+0] * oriMatrix[0*4+0] + - matrix[2*4+1] * oriMatrix[1*4+0] + - matrix[2*4+2] * oriMatrix[2*4+0] + - matrix[2*4+3] * oriMatrix[3*4+0]; - destMatrix[2*4+1] = matrix[2*4+0] * oriMatrix[0*4+1] + - matrix[2*4+1] * oriMatrix[1*4+1] + - matrix[2*4+2] * oriMatrix[2*4+1] + - matrix[2*4+3] * oriMatrix[3*4+1]; - destMatrix[2*4+2] = matrix[2*4+0] * oriMatrix[0*4+2] + - matrix[2*4+1] * oriMatrix[1*4+2] + - matrix[2*4+2] * oriMatrix[2*4+2] + - matrix[2*4+3] * oriMatrix[3*4+2]; - destMatrix[2*4+3] = matrix[2*4+0] * oriMatrix[0*4+3] + - matrix[2*4+1] * oriMatrix[1*4+3] + - matrix[2*4+2] * oriMatrix[2*4+3] + - matrix[2*4+3] * oriMatrix[3*4+3]; - - destMatrix[3*4+0] = matrix[3*4+0] * oriMatrix[0*4+0] + - matrix[3*4+1] * oriMatrix[1*4+0] + - matrix[3*4+2] * oriMatrix[2*4+0] + - matrix[3*4+3] * oriMatrix[3*4+0]; - destMatrix[3*4+1] = matrix[3*4+0] * oriMatrix[0*4+1] + - matrix[3*4+1] * oriMatrix[1*4+1] + - matrix[3*4+2] * oriMatrix[2*4+1] + - matrix[3*4+3] * oriMatrix[3*4+1]; - destMatrix[3*4+2] = matrix[3*4+0] * oriMatrix[0*4+2] + - matrix[3*4+1] * oriMatrix[1*4+2] + - matrix[3*4+2] * oriMatrix[2*4+2] + - matrix[3*4+3] * oriMatrix[3*4+2]; - destMatrix[3*4+3] = matrix[3*4+0] * oriMatrix[0*4+3] + - matrix[3*4+1] * oriMatrix[1*4+3] + - matrix[3*4+2] * oriMatrix[2*4+3] + - matrix[3*4+3] * oriMatrix[3*4+3]; - - memcpy(oriMatrix, destMatrix, 16 * sizeof(double)); - } -} - -GLAPI void APIENTRY glMultMatrixd(const GLdouble matrix[16]) -{ - _internal_glMultMatrixd(matrix); - - long args[] = { POINTER_TO_ARG(matrix)}; - do_opengl_call(glMultMatrixd_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glMultMatrixf(const GLfloat matrix[16]) -{ - GLdouble matrixd[16]; - matrixfToMatrixd(matrix, matrixd); - _internal_glMultMatrixd(matrixd); - - long args[] = { POINTER_TO_ARG(matrix)}; - do_opengl_call(glMultMatrixf_func, NULL, args, NULL); -} - -/** - * Transpose a GLfloat matrix. - * - * \param to destination array. - * \param from source array. - */ - static void -_math_transposef( GLfloat to[16], const GLfloat from[16] ) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - - -/** - * Transpose a GLdouble matrix. - * - * \param to destination array. - * \param from source array. - */ - static void -_math_transposed( GLdouble to[16], const GLdouble from[16] ) -{ - to[0] = from[0]; - to[1] = from[4]; - to[2] = from[8]; - to[3] = from[12]; - to[4] = from[1]; - to[5] = from[5]; - to[6] = from[9]; - to[7] = from[13]; - to[8] = from[2]; - to[9] = from[6]; - to[10] = from[10]; - to[11] = from[14]; - to[12] = from[3]; - to[13] = from[7]; - to[14] = from[11]; - to[15] = from[15]; -} - -GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat m[16]) -{ - GLfloat dest[16]; - _math_transposef(dest, m); - glLoadMatrixf(dest); -} - -GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble m[16]) -{ - GLdouble dest[16]; - _math_transposed(dest, m); - glLoadMatrixd(dest); -} - -GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat m[16]) -{ - GLfloat dest[16]; - _math_transposef(dest, m); - glMultMatrixf(dest); -} - -GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble m[16]) -{ - GLdouble dest[16]; - _math_transposed(dest, m); - glMultMatrixd(dest); -} - -GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat* m) -{ - GLfloat dest[16]; - _math_transposef(dest, m); - glLoadMatrixf(dest); -} - -GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble* m) -{ - GLdouble dest[16]; - _math_transposed(dest, m); - glLoadMatrixd(dest); -} - -GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat* m) -{ - GLfloat dest[16]; - _math_transposef(dest, m); - glMultMatrixf(dest); -} - -GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble* m) -{ - GLdouble dest[16]; - _math_transposed(dest, m); - glMultMatrixd(dest); -} - -GLAPI void APIENTRY glOrtho( GLdouble left, - GLdouble right, - GLdouble bottom, - GLdouble top, - GLdouble near_val, - GLdouble far_val) -{ - double tx, ty, tz; - tx = -(right + left) / (right - left); - ty = -(top + bottom) / (top - bottom); - tz = -(far_val + near_val) / (far_val - near_val); - double matrix[16] = { 2/(right - left), 0, 0, 0, - 0, 2/(top-bottom), 0, 0, - 0, 0, -2/(far_val - near_val), 0, - tx, ty, tz, 1 }; - _internal_glMultMatrixd(matrix); - - long args[] = { DOUBLE_TO_ARG(left), DOUBLE_TO_ARG(right), DOUBLE_TO_ARG(bottom), DOUBLE_TO_ARG(top), DOUBLE_TO_ARG(near_val), DOUBLE_TO_ARG(far_val)}; - do_opengl_call(glOrtho_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glFrustum( GLdouble left, - GLdouble right, - GLdouble bottom, - GLdouble top, - GLdouble near_val, - GLdouble far_val) -{ - double V1, V2, A, B, C, D; - V1 = 2 * near_val / (right - left); - V2 = 2 * near_val / (top - bottom); - A = (right + left) / (right - left); - B = (top + bottom) / (top - bottom); - C = -(far_val + near_val) / (far_val - near_val); - D = -2 * far_val * near_val / (far_val - near_val); - double matrix[16] = { V1, 0, 0, 0, - 0, V2, 0, 0, - A, B, C, -1, - 0, 0, D, 0}; - _internal_glMultMatrixd(matrix); - - long args[] = { DOUBLE_TO_ARG(left), DOUBLE_TO_ARG(right), DOUBLE_TO_ARG(bottom), DOUBLE_TO_ARG(top), DOUBLE_TO_ARG(near_val), DOUBLE_TO_ARG(far_val)}; - do_opengl_call(glFrustum_func, NULL, args, NULL); - -} - -static void _glRotate_internal(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) -{ - double c = cos(angle / 180. * M_PI); - double s = sin(angle / 180. * M_PI); - if (x == 1 && y == 0 && z == 0) - { - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - GLdouble* matrix = state->matrix[index_mode].current.val; - double t, u; - - t = matrix[1*4+0]; - u = matrix[2*4+0]; - matrix[1*4+0] = c * t + s * u; - matrix[2*4+0] = c * u - s * t; - - t = matrix[1*4+1]; - u = matrix[2*4+1]; - matrix[1*4+1] = c * t + s * u; - matrix[2*4+1] = c * u - s * t; - - t = matrix[1*4+2]; - u = matrix[2*4+2]; - matrix[1*4+2] = c * t + s * u; - matrix[2*4+2] = c * u - s * t; - - t = matrix[1*4+3]; - u = matrix[2*4+3]; - matrix[1*4+3] = c * t + s * u; - matrix[2*4+3] = c * u - s * t; - } - } - else if (x == 0 && y == 1 && z == 0) - { - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - GLdouble* matrix = state->matrix[index_mode].current.val; - double t, u; - - t = matrix[0*4+0]; - u = matrix[2*4+0]; - matrix[0*4+0] = c * t - s * u; - matrix[2*4+0] = s * t + c * u; - - t = matrix[0*4+1]; - u = matrix[2*4+1]; - matrix[0*4+1] = c * t - s * u; - matrix[2*4+1] = s * t + c * u; - - t = matrix[0*4+2]; - u = matrix[2*4+2]; - matrix[0*4+2] = c * t - s * u; - matrix[2*4+2] = s * t + c * u; - - t = matrix[0*4+3]; - u = matrix[2*4+3]; - matrix[0*4+3] = c * t - s * u; - matrix[2*4+3] = s * t + c * u; - } - } - else if (x == 0 && y == 0 && z == 1) - { - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - GLdouble* matrix = state->matrix[index_mode].current.val; - double t, u; - - t = matrix[0*4+0]; - u = matrix[1*4+0]; - matrix[0*4+0] = c * t + s * u; - matrix[1*4+0] = c * u - s * t; - - t = matrix[0*4+1]; - u = matrix[1*4+1]; - matrix[0*4+1] = c * t + s * u; - matrix[1*4+1] = c * u - s * t; - - t = matrix[0*4+2]; - u = matrix[1*4+2]; - matrix[0*4+2] = c * t + s * u; - matrix[1*4+2] = c * u - s * t; - - t = matrix[0*4+3]; - u = matrix[1*4+3]; - matrix[0*4+3] = c * t + s * u; - matrix[1*4+3] = c * u - s * t; - } - } - else - { - double sqrt_sum_sqr = sqrt(x*x+y*y+z*z); - if (sqrt_sum_sqr < 1e-4) return; - x /= sqrt_sum_sqr; - y /= sqrt_sum_sqr; - z /= sqrt_sum_sqr; - double matrix[16] = { x*x*(1-c)+c, y*x*(1-c)+z*s, x*z*(1-c)-y*s, 0, - x*y*(1-c)-z*s, y*y*(1-c)+c, y*z*(1-c)+x*s, 0, - x*z*(1-c)+y*s, y*z*(1-c)-x*s, z*z*(1-c)+c, 0, - 0, 0, 0, 1}; - _internal_glMultMatrixd(matrix); - } -} - -GLAPI void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) -{ - _glRotate_internal(angle, x, y, z); - - long args[] = { DOUBLE_TO_ARG(angle), DOUBLE_TO_ARG(x), DOUBLE_TO_ARG(y), DOUBLE_TO_ARG(z)}; - do_opengl_call(glRotated_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) -{ - _glRotate_internal(angle, x, y, z); - - long args[] = { FLOAT_TO_ARG(angle), FLOAT_TO_ARG(x), FLOAT_TO_ARG(y), FLOAT_TO_ARG(z)}; - do_opengl_call(glRotatef_func, NULL, args, NULL); -} - -static void _glScale_internal(double a, double b, double c) -{ - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - GLdouble* matrix = state->matrix[index_mode].current.val; - matrix[0*4+0] *= a; - matrix[0*4+1] *= a; - matrix[0*4+2] *= a; - matrix[0*4+3] *= a; - matrix[1*4+0] *= b; - matrix[1*4+1] *= b; - matrix[1*4+2] *= b; - matrix[1*4+3] *= b; - matrix[2*4+0] *= c; - matrix[2*4+1] *= c; - matrix[2*4+2] *= c; - matrix[2*4+3] *= c; - } -} - -GLAPI void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z) -{ - _glScale_internal(x, y, z); - - long args[] = { DOUBLE_TO_ARG(x), DOUBLE_TO_ARG(y), DOUBLE_TO_ARG(z)}; - do_opengl_call(glScaled_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) -{ - _glScale_internal(x, y, z); - - long args[] = { FLOAT_TO_ARG(x), FLOAT_TO_ARG(y), FLOAT_TO_ARG(z)}; - do_opengl_call(glScalef_func, NULL, args, NULL); -} - -static void _glTranslate_internal(double a, double b, double c) -{ - GET_CURRENT_STATE(); - int index_mode = MATRIX_MODE_TO_MATRIX_INDEX(state->current_server_state.matrixMode); - if (index_mode >= 0) - { - GLdouble* matrix = state->matrix[index_mode].current.val; - - matrix[3*4+0] += a * matrix[0*4+0] + b * matrix[1*4+0] + c * matrix[2*4+0]; - matrix[3*4+1] += a * matrix[0*4+1] + b * matrix[1*4+1] + c * matrix[2*4+1]; - matrix[3*4+2] += a * matrix[0*4+2] + b * matrix[1*4+2] + c * matrix[2*4+2]; - matrix[3*4+3] += a * matrix[0*4+3] + b * matrix[1*4+3] + c * matrix[2*4+3]; - } -} - -GLAPI void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z) -{ - _glTranslate_internal(x, y, z); - - long args[] = { DOUBLE_TO_ARG(x), DOUBLE_TO_ARG(y), DOUBLE_TO_ARG(z)}; - do_opengl_call(glTranslated_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) -{ - _glTranslate_internal(x, y, z); - - long args[] = { FLOAT_TO_ARG(x), FLOAT_TO_ARG(y), FLOAT_TO_ARG(z)}; - do_opengl_call(glTranslatef_func, NULL, args, NULL); -} -#endif -/* End of matrix optimization */ - -static void glBindBufferARB_no_lock(GLenum target, GLuint buffer) -{ - CHECK_PROC(glBindBufferARB); - GET_CURRENT_STATE(); - if (buffer >= 32768) - { - log_gl("buffer >= 32768\n"); - return; - } - long args[] = {INT_TO_ARG(target), INT_TO_ARG(buffer)}; - if (target == GL_ARRAY_BUFFER_ARB) - { - //log_gl("glBindBufferARB(GL_ARRAY_BUFFER,%d)\n", buffer); - state->arrayBuffer = buffer; - } - else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) - { - //log_gl("glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,%d)\n", buffer); - state->elementArrayBuffer = buffer; - } - else if (target == GL_PIXEL_UNPACK_BUFFER_EXT) - { - //log_gl("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT,%d)\n", buffer); - state->pixelUnpackBuffer = buffer; - } - else if (target == GL_PIXEL_PACK_BUFFER_EXT) - { - //log_gl("glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT,%d)\n", buffer); - state->pixelPackBuffer = buffer; - } - do_opengl_call_no_lock(glBindBufferARB_func, NULL, args, NULL); -} - -GLAPI void APIENTRY EXT_FUNC(glBindBufferARB) (GLenum target, GLuint buffer) -{ - LOCK(glBindBufferARB_func); - glBindBufferARB_no_lock(target, buffer); - UNLOCK(glBindBufferARB_func); -} - -GLAPI void APIENTRY EXT_FUNC(glBindBuffer) (GLenum target, GLuint buffer) -{ - glBindBufferARB(target, buffer); -} - -GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint * tab) -{ - CHECK_PROC(glGenBuffersARB); - GET_CURRENT_STATE(); - if (n <= 0) { log_gl("n <= 0\n"); return; } - alloc_range(state->bufferAllocator, n, tab); - long args[] = { INT_TO_ARG(n) }; - do_opengl_call(glGenBuffersARB_fake_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint * tab) -{ - glGenBuffersARB(n, tab); -} - -GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint * tab) -{ - CHECK_PROC(glDeleteBuffersARB); - GET_CURRENT_STATE(); - if (n <= 0) { log_gl("n <= 0\n"); return; } - delete_range(state->bufferAllocator, n, tab); - long args[] = { INT_TO_ARG(n), POINTER_TO_ARG(tab) }; - do_opengl_call(glDeleteBuffersARB_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glDeleteBuffers(GLsizei n, const GLuint * tab) -{ - glDeleteBuffersARB(n, tab); -} - -static Buffer* _get_buffer(GLenum target) -{ - GET_CURRENT_STATE(); - if (target == GL_ARRAY_BUFFER_ARB) - { - if (state->arrayBuffer) - return &state->arrayBuffers[state->arrayBuffer]; - else - return NULL; - } - else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) - { - if (state->elementArrayBuffer) - return &state->elementArrayBuffers[state->elementArrayBuffer]; - else - return NULL; - } - else if (target == GL_PIXEL_UNPACK_BUFFER_EXT) - { - if (state->pixelUnpackBuffer) - return &state->pixelUnpackBuffers[state->pixelUnpackBuffer]; - else - return NULL; - } - else if (target == GL_PIXEL_PACK_BUFFER_EXT) - { - if (state->pixelPackBuffer) - return &state->pixelPackBuffers[state->pixelPackBuffer]; - else - return NULL; - } - else - { - return NULL; - } -} - -GLAPI GLenum APIENTRY glGetError() -{ - int ret = 0; - if (disable_optim) - { - do_opengl_call(glGetError_func, &ret, NULL, NULL); - log_gl("glGetError() = %d\n", ret); - } - else - do_opengl_call(_glGetError_fake_func, NULL, NULL, NULL); - return ret; -} - -GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) -{ - CHECK_PROC(glBufferDataARB); - - Buffer* buffer = _get_buffer(target); - if (buffer) - { - buffer->usage = usage; - buffer->size = size; - buffer->ptr = realloc(buffer->ptr, size); - if (data) memcpy(buffer->ptr, data, size); - } - else - { - fprintf(stderr, "unknown buffer/buffer target : %d\n", target); - } - long args[] = { INT_TO_ARG(target), INT_TO_ARG(size), POINTER_TO_ARG(data), INT_TO_ARG(usage) }; - int args_size[] = { 0, 0, (data) ? size : 0, 0 }; - do_opengl_call(glBufferDataARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) -{ - glBufferDataARB(target, size, data, usage); -} - -GLAPI void APIENTRY glBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) -{ - CHECK_PROC(glBufferSubDataARB); - - //log_gl("glBufferSubDataARB %d %d\n", offset, size); - - Buffer* buffer = _get_buffer(target); - if (buffer) - { - assert(offset + size <= buffer->size); - assert(buffer->ptr); - memcpy(buffer->ptr + offset, data, size); - } - else - { - fprintf(stderr, "unknown buffer/buffer target : %d\n", target); - } - long args[] = { INT_TO_ARG(target), INT_TO_ARG(offset), INT_TO_ARG(size), POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, size }; - do_opengl_call(glBufferSubDataARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) -{ - glBufferSubDataARB(target, offset, size, data); -} - -GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) -{ - CHECK_PROC(glGetBufferSubDataARB); - - Buffer* buffer = _get_buffer(target); - if (!buffer) return; - - assert(offset + size <= buffer->size); - assert(buffer->ptr); - - memcpy(data, buffer->ptr + offset, size); -} - -GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) -{ - glGetBufferSubDataARB(target, offset, size, data); -} - -GLvoid* glMapBufferARB (GLenum target, GLenum access) -{ - CHECK_PROC_WITH_RET(glMapBufferARB); - - Buffer* buffer = _get_buffer(target); - if (!buffer) return NULL; - if (target == GL_PIXEL_PACK_BUFFER_EXT && (access == GL_READ_ONLY || access == GL_READ_WRITE)) - { - int ret_int = 0; - long args[] = { INT_TO_ARG(target), INT_TO_ARG(buffer->size), POINTER_TO_ARG(buffer->ptr) }; - int args_size[] = { 0, 0, buffer->size }; - do_opengl_call(_glMapBufferARB_fake_func, &ret_int, CHECK_ARGS(args, args_size)); - if (ret_int == 0) - return NULL; - } - buffer->access = access; - buffer->mapped = 1; - return buffer->ptr; -} - -GLvoid* glMapBuffer(GLenum target, GLenum access) -{ - return glMapBufferARB(target, access); -} - -GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params) -{ - CHECK_PROC(glGetBufferParameterivARB); - - Buffer* buffer = _get_buffer(target); - if (!buffer) return; - - switch (pname) - { - case GL_BUFFER_SIZE_ARB: *params = buffer->size; break; - case GL_BUFFER_USAGE_ARB: *params = buffer->usage; break; - case GL_BUFFER_ACCESS_ARB: *params = buffer->access; break; - case GL_BUFFER_MAPPED_ARB: *params = buffer->mapped; break; - default: - log_gl("unknown pname = 0x%X\n", pname); - } -} - -GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) -{ - glGetBufferParameterivARB(target, pname, params); -} - -GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params) -{ - CHECK_PROC(glGetBufferPointervARB); - if (pname != GL_BUFFER_MAP_POINTER_ARB) - { - log_gl("glGetBufferPointervARB : unknown buffer data pname : %x\n", pname); - return; - } - Buffer* buffer = _get_buffer(target); - if (!buffer) return; - if (buffer->mapped) *params = buffer->ptr; else *params = NULL; -} - -GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) -{ - glGetBufferPointervARB(target, pname, params); -} - -GLAPI GLboolean APIENTRY glUnmapBufferARB(GLenum target) -{ - CHECK_PROC_WITH_RET(glUnmapBufferARB); - Buffer* buffer = _get_buffer(target); - if (!buffer) return 0; - if (!buffer->mapped) - { - log_gl("unmapped buffer"); - return 0; - } - buffer->mapped = 0; - if (buffer->access != GL_READ_ONLY) - { - glBufferSubDataARB(target, 0, buffer->size, buffer->ptr); - } - buffer->access = 0; - return 1; -} - -GLAPI GLboolean APIENTRY glUnmapBuffer(GLenum target) -{ - return glUnmapBufferARB(target); -} - -GLAPI void GLAPIENTRY glNewList( GLuint list, GLenum mode ) -{ - long args[] = { INT_TO_ARG(list), INT_TO_ARG(mode) }; - GET_CURRENT_STATE(); - alloc_value(state->listAllocator, list); - do_opengl_call(glNewList_func, NULL, args, NULL); -} - -GLAPI void GLAPIENTRY glDeleteLists( GLuint list, GLsizei range ) -{ - long args[] = { INT_TO_ARG(list), INT_TO_ARG(range) }; - GET_CURRENT_STATE(); - delete_consecutive_values(state->listAllocator, list, range); - do_opengl_call(glDeleteLists_func, NULL, args, NULL); -} - -GLAPI GLuint GLAPIENTRY glGenLists( GLsizei range ) -{ - GET_CURRENT_STATE(); - unsigned int firstValue = alloc_range(state->listAllocator, range, NULL); - long args[] = { INT_TO_ARG(range) }; - do_opengl_call(glGenLists_fake_func, NULL, args, NULL); - return firstValue; -} - -GLAPI void APIENTRY glCallLists( GLsizei n, - GLenum type, - const GLvoid *lists ) -{ - long args[] = { INT_TO_ARG(n), INT_TO_ARG(type), POINTER_TO_ARG(lists) }; - int args_size[] = { 0, 0, 0 }; - int size = n; - if (n <= 0) { log_gl("n <= 0\n"); return; } - switch(type) - { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - break; - - case GL_SHORT: - case GL_UNSIGNED_SHORT: - case GL_2_BYTES: - size *= 2; - break; - - case GL_3_BYTES: - size *= 3; - break; - - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - case GL_4_BYTES: - size *= 4; - break; - - default: - log_gl("unsupported type = %d\n", type); - return; - } - args_size[2] = size; - do_opengl_call(glCallLists_func, NULL, CHECK_ARGS(args, args_size)); -} - - - -static void removeUnwantedExtensions(char* ret) -{ - char* toBeRemoved = getenv("GL_REMOVE_EXTENSIONS"); - if (toBeRemoved == NULL) return; - toBeRemoved = strdup(toBeRemoved); - char* iterToBeRemoved = toBeRemoved; - while(*iterToBeRemoved) - { - char* cSpace = strchr(iterToBeRemoved, ' '); - char* cComma = strchr(iterToBeRemoved, ','); - char* c = (cSpace && cComma) ? MIN(cSpace, cComma) : (cSpace) ? cSpace : (cComma) ? cComma : NULL; - if (c != NULL) - { - *c = 0; - } - if (!(*iterToBeRemoved == ' ' || *iterToBeRemoved == ',' || *iterToBeRemoved == 0)) - { - log_gl("Trying to remove : %s (%d)\n", iterToBeRemoved, *iterToBeRemoved); - char* c2 = strstr(ret, iterToBeRemoved); - while (c2) - { - memset(c2, 'X', strlen(iterToBeRemoved)); - c2 = strstr(c2 + strlen(iterToBeRemoved), iterToBeRemoved); - } - } - if (c == NULL) - break; - iterToBeRemoved = c + 1; - } - free(toBeRemoved); -} - -#ifndef WIN32 -const char *glXQueryExtensionsString( Display *dpy, int screen ) -{ - LOCK(glXQueryExtensionsString_func); - static char* ret = NULL; - if (ret == NULL) - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(screen) }; - do_opengl_call_no_lock(glXQueryExtensionsString_func, &ret, args, NULL); - ret = strdup(ret); - removeUnwantedExtensions(ret); - } - UNLOCK(glXQueryExtensionsString_func); - return ret; -} - - -typedef struct -{ - XVisualInfo* vis; - int visualid; - GLXFBConfig fbconfig; -} AssocVisualInfoVisualId; - -#define MAX_SIZE_TAB_ASSOC_VISUALINFO_VISUALID 100 -AssocVisualInfoVisualId tabAssocVisualInfoVisualId[MAX_SIZE_TAB_ASSOC_VISUALINFO_VISUALID]; -int nEltTabAssocVisualInfoVisualId = 0; - -static const char* _getAttribNameFromValue(int val) -{ - int i; - static char buffer[80]; - for(i=0;iclass; - temp.visualid = DefaultVisual(dpy,screen)->visualid; - - vis = XGetVisualInfo( dpy, mask, &temp, &n ); - if (vis == NULL) - log_gl("cannot get visual from client side\n"); - - assert (nEltTabAssocVisualInfoVisualId < MAX_SIZE_TAB_ASSOC_VISUALINFO_VISUALID); - for(i=0;i= 0 && name < 100); - if (glXQueryServerString_ret[name] == NULL) - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(screen), INT_TO_ARG(name) }; - do_opengl_call_no_lock(glXQueryServerString_func, &glXQueryServerString_ret[name], args, NULL); - glXQueryServerString_ret[name] = strdup(glXQueryServerString_ret[name]); - if (name == GLX_EXTENSIONS) - { - removeUnwantedExtensions(glXQueryServerString_ret[name]); - } - } - UNLOCK(glXQueryServerString_func); - return glXQueryServerString_ret[name]; -} - -const char *glXGetClientString( Display *dpy, int name ) -{ - LOCK(glXGetClientString_func); - static char* glXGetClientString_ret[100] = {NULL}; - assert(name >= 0 && name < 100); - if (glXGetClientString_ret[name] == NULL) - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(name) }; - do_opengl_call_no_lock(glXGetClientString_func, &glXGetClientString_ret[name], args, NULL); - if (getenv("GLX_VENDOR") && name == GLX_VENDOR) - { - glXGetClientString_ret[name] = getenv("GLX_VENDOR"); - } - else - glXGetClientString_ret[name] = strdup(glXGetClientString_ret[name]); - if (name == GLX_EXTENSIONS) - { - removeUnwantedExtensions(glXGetClientString_ret[name]); - } - } - UNLOCK(glXGetClientString_func); - return glXGetClientString_ret[name]; -} - -static void _create_context(GLXContext context, GLXContext shareList) -{ - int i; - glstates = realloc(glstates, (nbGLStates+1) * sizeof(GLState*)); - glstates[nbGLStates] = new_gl_state(); - glstates[nbGLStates]->ref = 1; - glstates[nbGLStates]->context = context; - glstates[nbGLStates]->shareList = shareList; - glstates[nbGLStates]->pbuffer = 0; - glstates[nbGLStates]->viewport.width = 0; - if (shareList) - { - for(i=0; icontext == shareList) - { - glstates[i]->ref++; - glstates[nbGLStates]->textureAllocator = glstates[i]->textureAllocator; - glstates[nbGLStates]->bufferAllocator = glstates[i]->bufferAllocator; - glstates[nbGLStates]->listAllocator = glstates[i]->listAllocator; - break; - } - } - if (i == nbGLStates) - { - log_gl("unknown shareList %p\n", (void*)shareList); - } - } - nbGLStates++; -} - -static GLXFBConfig* glXChooseFBConfig_no_lock( Display *dpy, int screen, - const int *attribList, int *nitems ); -static XVisualInfo* glXGetVisualFromFBConfig_no_lock( Display *dpy, GLXFBConfig config ); -static GLXPbuffer glXCreatePbuffer_no_lock(Display *dpy, - GLXFBConfig config, - const int *attribList); - -GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, - GLXContext shareList, Bool direct ) -{ - LOCK(glXCreateContext_func); - int isFbConfigVisual = 0; - int i; - int visualid = 0; - - for(i=0;ivisualid), INT_TO_ARG(shareList), INT_TO_ARG(direct) }; - do_opengl_call_no_lock(glXCreateContext_func, &ctxt, args, NULL); - - XFree(visinfo); - - if (ctxt) - { - _create_context(ctxt, shareList); - - int pbufAttrib[] = { - GLX_PBUFFER_WIDTH, 1024, - GLX_PBUFFER_HEIGHT, 1024, - GLX_LARGEST_PBUFFER, GL_TRUE, - None - }; - - glstates[nbGLStates-1]->isAssociatedToFBConfigVisual = isFbConfigVisual; - glstates[nbGLStates-1]->pbuffer = glXCreatePbuffer_no_lock(dpy, fbconfig[0], pbufAttrib); - assert(glstates[nbGLStates-1]->pbuffer); - } - - XFree(fbconfig); - - goto end_of_create_context; - } - } - - GLXContext ctxt = NULL; - if (i == nEltTabAssocVisualInfoVisualId) - { - visualid = vis->visualid; - if (debug_gl) log_gl("not found vis %p in table, visualid=%d\n", vis, visualid); - } - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(visualid), INT_TO_ARG(shareList), INT_TO_ARG(direct) }; - do_opengl_call_no_lock(glXCreateContext_func, &ctxt, args, NULL); - - if (ctxt) - { - _create_context(ctxt, shareList); - glstates[nbGLStates-1]->isAssociatedToFBConfigVisual = isFbConfigVisual; - } -end_of_create_context: - UNLOCK(glXCreateContext_func); - return ctxt; -} - -GLXContext glXGetCurrentContext (void) -{ - GET_CURRENT_STATE(); - if (debug_gl) log_gl("glXGetCurrentContext() -> %p\n", state->context); - return state->context; -} - -GLXDrawable glXGetCurrentDrawable (void) -{ - GET_CURRENT_STATE(); - if (debug_gl) log_gl("glXGetCurrentDrawable() -> %p\n", (void*)state->current_drawable); - return state->current_drawable; -} - -static void _free_context(Display* dpy, int i, GLState* state) -{ - if (state->pbuffer) glXDestroyPbuffer(dpy, state->pbuffer); - free(state->last_cursor.pixels); - free(state->ownTextureAllocator.values); - free(state->ownBufferAllocator.values); - free(state->ownListAllocator.values); - free(state); - memmove(&state, &glstates[i+1], (nbGLStates-i-1) * sizeof(GLState*)); - nbGLStates--; -} - -GLAPI void APIENTRY glXDestroyContext( Display *dpy, GLXContext ctx ) -{ - int i; - LOCK(glXDestroyContext_func); - GET_CURRENT_STATE(); - for(i=0;icontext == ctx) - { - long args[] = { POINTER_TO_ARG(dpy), POINTER_TO_ARG(ctx) }; - do_opengl_call_no_lock(glXDestroyContext_func, NULL, args, NULL); - if (ctx == state->context) - { - SET_CURRENT_STATE(NULL); - } - - GLXContext shareList = glstates[i]->shareList; - - glstates[i]->ref --; - if (glstates[i]->ref == 0) - { - _free_context(dpy, i, glstates[i]); - } - - if (shareList) - { - for(i=0; icontext == shareList) - { - glstates[i]->ref--; - if (glstates[i]->ref == 0) - { - _free_context(dpy, i, glstates[i]); - } - break; - } - } - } - break; - } - } - UNLOCK(glXDestroyContext_func); -} - -Bool glXQueryVersion( Display *dpy, int *maj, int *min ) -{ - LOCK(glXQueryVersion_func); - static Bool ret = -1; - static int l_maj, l_min; - if (ret == -1) - { - long args[] = { POINTER_TO_ARG(dpy), POINTER_TO_ARG(&l_maj), POINTER_TO_ARG(&l_min) }; - do_opengl_call_no_lock(glXQueryVersion_func, &ret, args, NULL); - } - if (maj) *maj = l_maj; - if (min) *min = l_min; - UNLOCK(glXQueryVersion_func); - return ret; -} - - -static void _get_window_pos(Display *dpy, Window win, WindowPosStruct* pos) -{ - XWindowAttributes window_attributes_return; - Window child; - int x, y; - Window root = DefaultRootWindow(dpy); - XGetWindowAttributes(dpy, win, &window_attributes_return); - XTranslateCoordinates(dpy, win, root, 0, 0, &x, &y, &child); - /*printf("%d %d %d %d\n", x, y, window_attributes_return.width, window_attributes_return.height);*/ - pos->x = x; - pos->y = y; - pos->width = window_attributes_return.width; - pos->height = window_attributes_return.height; - pos->map_state = window_attributes_return.map_state; -} - -#define MAX_PBUFFERS 100 - -/* Doit être appelé avec le lock */ -static void _move_win_if_necessary(Display *dpy, Window win) -{ - GET_CURRENT_STATE(); - if ((int)win < MAX_PBUFFERS) /* FIXME */ - { - return; - } - - WindowPosStruct pos; - _get_window_pos(dpy, win, &pos); - if (memcmp(&pos, &state->oldPos, sizeof(state->oldPos)) != 0) - { - /* Host Window�� ��Ÿ���� �ʴ´�. if (pos.map_state != state->oldPos.map_state) - { - long args[] = { INT_TO_ARG(win), INT_TO_ARG(pos.map_state) }; - do_opengl_call_no_lock(_changeWindowState_func, NULL, args, NULL); - }*/ - memcpy(&state->oldPos, &pos, sizeof(state->oldPos)); - long args[] = { INT_TO_ARG(win), POINTER_TO_ARG(&pos) }; - if (getenv("NO_MOVE")) - { - pos.x = 0; - pos.y = 0; - } - do_opengl_call_no_lock(_moveResizeWindow_func, NULL, args, NULL); - } -} - -static Bool glXMakeCurrent_no_lock( Display *dpy, GLXDrawable drawable, GLXContext ctx) -{ - Bool ret = False; - int i; -#if 0 - if (drawable == 0 && ctx == 0) - return True; - if (current_drawable == drawable && current_context == ctx) /* optimization */ - return True; -#endif - GET_CURRENT_STATE(); - - if (!(drawable < MAX_PBUFFERS)) /* FIXME */ - { - for(i=0; icontext == ctx && glstates[i]->viewport.width == 0) - { - XWindowAttributes window_attributes_return; - XGetWindowAttributes(dpy, drawable, &window_attributes_return); - glstates[i]->viewport.width = window_attributes_return.width; - glstates[i]->viewport.height = window_attributes_return.height; - if (debug_gl) - log_gl("drawable 0x%X dim : %d x %d\n", (int)drawable, window_attributes_return.width, - window_attributes_return.height); - break; - } - } - } - - if (getenv("GET_IMG_FROM_SERVER") && ctx != NULL) - { - for(i=0; icontext == ctx) - { - if (glstates[i]->pbuffer) - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(glstates[i]->pbuffer), INT_TO_ARG(ctx) }; - do_opengl_call_no_lock(glXMakeCurrent_func, NULL /*&ret*/, args, NULL); - ret = True; - } - else - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(drawable), INT_TO_ARG(ctx) }; - do_opengl_call_no_lock(glXMakeCurrent_func, NULL /*&ret*/, args, NULL); - ret = True; - _move_win_if_necessary(dpy, drawable); - } - break; - } - } - if (i == nbGLStates) - { - log_gl("unknown context %p\n", ctx); - } - } - else - { - //log_gl("glXMakeCurrent %d %d\n", drawable, ctx); - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(drawable), INT_TO_ARG(ctx) }; - do_opengl_call_no_lock(glXMakeCurrent_func, NULL /*&ret*/, args, NULL); - ret = True; - _move_win_if_necessary(dpy, drawable); - } - - if (ret) - { - int i; - if (ctx == 0) - { - state->context = NULL; - } - else - { - for(i=0; icontext == ctx) - { - state = glstates[i]; - SET_CURRENT_STATE(state); - break; - } - } - if (i == nbGLStates) - { - log_gl("cannot set current_gl_state\n"); - } - } - - state->display = dpy; - state->context = ctx; - state->current_drawable = drawable; - state->current_read_drawable = drawable; - } - return ret; -} - -GLAPI Bool APIENTRY glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx) -{ - Bool ret; - LOCK(glXMakeCurrent_func); - ret = glXMakeCurrent_no_lock(dpy, drawable, ctx); - UNLOCK(glXMakeCurrent_func); - return ret; -} - -GLAPI void APIENTRY glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, unsigned long mask ) -{ - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(src), INT_TO_ARG(dst), INT_TO_ARG(mask) }; - do_opengl_call(glXCopyContext_func, NULL, args, NULL); -} - -GLAPI Bool APIENTRY glXIsDirect( Display *dpy, GLXContext ctx ) -{ - Bool ret = False; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(ctx) }; - do_opengl_call(glXIsDirect_func, &ret, args, NULL); - return ret; -} - -GLAPI int APIENTRY glXGetConfig( Display *dpy, XVisualInfo *vis, - int attrib, int *value ) -{ - int ret = 0; - int i, j; - if (vis == NULL || value == NULL) return 0; - LOCK(glXGetConfig_func); - - int visualid = 0; - for(i=0;ivisualid; - } - - /* Optimization */ - for(i=0;i %d\n", vis, attrib, *value); - if (configs[i].nbAttribs < N_MAX_ATTRIBS) - { - configs[i].attribs[configs[i].nbAttribs].attrib = attrib; - configs[i].attribs[configs[i].nbAttribs].value = *value; - configs[i].attribs[configs[i].nbAttribs].ret = ret; - configs[i].nbAttribs++; - } - } - } - else - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(visualid), INT_TO_ARG(attrib), POINTER_TO_ARG(value) }; - do_opengl_call_no_lock(glXGetConfig_func, &ret, args, NULL); - if (debug_gl) log_gl("glXGetConfig visual=%p, attrib=%d -> %d\n", vis, attrib, *value); - } -end_of_glx_get_config: - UNLOCK(glXGetConfig_func); - return ret; -} - -#ifndef __CLIENT_WINDOW__ -/* Doit être appelé avec le lock */ -static void _send_cursor(Display* dpy, Window win) -{ - GET_CURRENT_STATE(); - XFixesCursorImage* cursor = XFixesGetCursorImage(dpy); - Window child_return, root_return; - int root_x_return, root_y_return, win_x_return, win_y_return; - unsigned int mask_return; - XQueryPointer(dpy, win, &root_return, &child_return, &root_x_return, &root_y_return, - &win_x_return, &win_y_return, &mask_return); - cursor->x = win_x_return; - cursor->y = win_y_return; - - - if (cursor->width == state->last_cursor.width && - cursor->height == state->last_cursor.height && - cursor->xhot == state->last_cursor.xhot && - cursor->yhot == state->last_cursor.yhot && - memcmp(cursor->pixels, state->last_cursor.pixels, sizeof(long) * cursor->width * cursor->height) == 0) - { - if (!(cursor->x == state->last_cursor.x && - cursor->y == state->last_cursor.y)) - { - long args[] = { INT_TO_ARG(cursor->x), INT_TO_ARG(cursor->y), - INT_TO_ARG(cursor->width), INT_TO_ARG(cursor->height), - INT_TO_ARG(cursor->xhot), INT_TO_ARG(cursor->yhot), - 0 }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0 }; - do_opengl_call_no_lock(_send_cursor_func, NULL, CHECK_ARGS(args, args_size)); - - state->last_cursor.x = cursor->x; - state->last_cursor.y = cursor->y; - } - XFree(cursor); - return; - } - int* data; - - /* Fun stuff about the 'pixels' field of XFixesCursorImage. It's a long instead of an int */ - /* The interface chosen for serialization is an array of int */ - if (sizeof(long) != sizeof(int)) - { - data = malloc(sizeof(int) * cursor->width * cursor->height); - int i; - for(i=0;iwidth*cursor->height;i++) - { - data[i] = (int)cursor->pixels[i]; - } - } - else - { - data = (int*)cursor->pixels; - } - - long args[] = { INT_TO_ARG(cursor->x), INT_TO_ARG(cursor->y), - INT_TO_ARG(cursor->width), INT_TO_ARG(cursor->height), - INT_TO_ARG(cursor->xhot), INT_TO_ARG(cursor->yhot), - POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, sizeof(int) * cursor->width * cursor->height }; - do_opengl_call_no_lock(_send_cursor_func, NULL, CHECK_ARGS(args, args_size)); - - void* prev_ptr = state->last_cursor.pixels; - memcpy(&state->last_cursor, cursor, sizeof(XFixesCursorImage)); - state->last_cursor.pixels = realloc(prev_ptr, sizeof(long) * cursor->width * cursor->height); - memcpy(state->last_cursor.pixels, cursor->pixels, sizeof(long) * cursor->width * cursor->height); - - if (sizeof(long) != sizeof(int)) - { - free(data); - } - XFree(cursor); -} -#endif - -static void glXSwapBuffers_no_lock( Display *dpy, GLXDrawable drawable ) -{ - //log_gl("glXSwapBuffers %d\n", drawable); - int i; -#ifdef __CLIENT_WINDOW__ - WindowImage *image = NULL; -#else - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(drawable) }; - GET_CURRENT_STATE(); -#endif - -#ifndef __CLIENT_WINDOW__ /*Host window�� draw���� �ʴ´�.*/ - do_opengl_call_no_lock(glXSwapBuffers_func, NULL, args, NULL); -#endif - - if (getenv("GET_IMG_FROM_SERVER") == NULL) - { - _move_win_if_necessary(dpy, drawable); - } - -#ifndef __CLIENT_WINDOW__ - _send_cursor(dpy, drawable); - - if (limit_fps > 0) - { - if (state->last_swap_buffer_time.tv_sec != 0) - { - struct timeval current_time; - gettimeofday(¤t_time, NULL); - int diff_time = (current_time.tv_sec - state->last_swap_buffer_time.tv_sec) * 1000 + (current_time.tv_usec - state->last_swap_buffer_time.tv_usec) / 1000; - - if (diff_time < 1000 / limit_fps) - { - usleep( (1000 / limit_fps - diff_time) * 900); - } - } - gettimeofday(&state->last_swap_buffer_time, NULL); - } -#endif - -#ifdef __CLIENT_WINDOW__ - for(i = 0; i < MAX_IMAGES; i++) - { - if( wImage[i].win == (Window)drawable ) - { - image = &wImage[i]; - break; - } - } - - if( image && image->win ) - _draw_image(dpy, image->win, image); -#endif - -} - -GLAPI void APIENTRY glXSwapBuffers( Display *dpy, GLXDrawable drawable ) -{ - LOCK(glXSwapBuffers_func); - glXSwapBuffers_no_lock(dpy, drawable); - UNLOCK(glXSwapBuffers_func); -} - -GLAPI Bool APIENTRY glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) -{ - Bool ret; - LOCK(glXQueryExtension_func); - int fake_int; - if (errorBase == NULL) errorBase = &fake_int; - if (eventBase == NULL) eventBase = &fake_int; - long args[] = { POINTER_TO_ARG(dpy), POINTER_TO_ARG(errorBase), POINTER_TO_ARG(eventBase) }; - do_opengl_call_no_lock(glXQueryExtension_func, &ret, args, NULL); - UNLOCK(glXQueryExtension_func); - return ret; -} - -GLAPI void APIENTRY glXWaitGL (void) -{ - int ret; - do_opengl_call(glXWaitGL_func, &ret, NULL, NULL); -} - -GLAPI void APIENTRY glXWaitX (void) -{ - int ret; - do_opengl_call(glXWaitX_func, &ret, NULL, NULL); -} - -GLAPI Display* APIENTRY glXGetCurrentDisplay( void ) -{ - GET_CURRENT_STATE(); - return state->display; -} - -static GLXFBConfig* glXChooseFBConfig_no_lock( Display *dpy, int screen, - const int *attribList, int *nitems ) -{ - CHECK_PROC_WITH_RET(glXChooseFBConfig); - GLXFBConfig* fbConfig = NULL; - if (debug_gl) log_gl("glXChooseFBConfig\n"); - int i=0; - int ret = 0; - int emptyAttribList = None; - if (attribList == NULL) attribList = &emptyAttribList; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(screen), POINTER_TO_ARG(attribList), POINTER_TO_ARG(nitems) }; - int args_size[] = { 0, 0, sizeof(int) * _compute_length_of_attrib_list_including_zero(attribList, 1), 0 }; - do_opengl_call_no_lock(glXChooseFBConfig_func, &ret, args, args_size); - if (debug_gl) log_gl("nitems = %d\n", *nitems); - if (*nitems == 0) - return NULL; - fbConfig = malloc(sizeof(GLXFBConfig) * (*nitems)); - for(i=0;i<*nitems;i++) - { - fbConfig[i] = (GLXFBConfig)(long)(ret + i); - if (debug_gl && (i == 0 || i == *nitems-1)) log_gl("config %d = %d\n", i, ret+i); - } - return fbConfig; -} - -GLAPI GLXFBConfig* APIENTRY glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ) -{ - GLXFBConfig* fbconfig; - LOCK(glXChooseFBConfig_func); - fbconfig = glXChooseFBConfig_no_lock(dpy, screen, attribList, nitems); - UNLOCK(glXChooseFBConfig_func); - return fbconfig; -} - -GLAPI GLXFBConfigSGIX* APIENTRY glXChooseFBConfigSGIX( Display *dpy, int screen, - const int *attribList, int *nitems ) -{ - CHECK_PROC_WITH_RET(glXChooseFBConfigSGIX); - GLXFBConfigSGIX* fbConfig = NULL; - if (debug_gl) log_gl("glXChooseFBConfigSGIX\n"); - int i = 0; - int ret = 0; - int emptyAttribList = None; - if (attribList == NULL) attribList = &emptyAttribList; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(screen), POINTER_TO_ARG(attribList), POINTER_TO_ARG(nitems) }; - int args_size[] = { 0, 0, sizeof(int) * _compute_length_of_attrib_list_including_zero(attribList, 1), 0 }; - do_opengl_call(glXChooseFBConfigSGIX_func, &ret, args, args_size); - if (debug_gl) log_gl("nitems = %d\n", *nitems); - fbConfig = malloc(sizeof(GLXFBConfigSGIX) * (*nitems)); - for(i=0;i<*nitems;i++) - { - fbConfig[i] = (GLXFBConfig)(long)(ret + i); - if (debug_gl && (i == 0 || i == *nitems-1)) log_gl("config %d = %d\n", i, ret+i); - } - return fbConfig; -} - -GLAPI GLXFBConfig* APIENTRY glXGetFBConfigs( Display *dpy, int screen, int *nitems ) -{ - CHECK_PROC_WITH_RET(glXGetFBConfigs); - if (debug_gl) log_gl("glXGetFBConfigs\n"); - int i = 0; - GLXFBConfig* fbConfig; - int ret = 0; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(screen), POINTER_TO_ARG(nitems) }; - do_opengl_call(glXGetFBConfigs_func, &ret, args, NULL); - if (debug_gl) log_gl("nitems = %d\n", *nitems); - fbConfig = malloc(sizeof(GLXFBConfig) * (*nitems)); - for(i=0;i<*nitems;i++) - { - fbConfig[i] = (GLXFBConfig)(long)(ret + i); - if (debug_gl && (i == 0 || i == *nitems-1)) log_gl("config %d = %d\n", i, ret+i); - } - return fbConfig; -} - - -GLAPI int APIENTRY glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attrib, int *value) -{ - CHECK_PROC_WITH_RET(glXGetFBConfigAttrib); - LOCK(glXGetFBConfigAttrib_func); - int ret = 0; - int i, j; - - /* Optimization */ - for(i=0;i %d\n", config, attrib, *value); - if (fbconfigs[i].nbAttribs < N_MAX_ATTRIBS) - { - fbconfigs[i].attribs[fbconfigs[i].nbAttribs].attrib = attrib; - fbconfigs[i].attribs[fbconfigs[i].nbAttribs].value = *value; - fbconfigs[i].attribs[fbconfigs[i].nbAttribs].ret = ret; - fbconfigs[i].nbAttribs++; - } - } - } - else - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(config), INT_TO_ARG(attrib), POINTER_TO_ARG(value) }; - do_opengl_call_no_lock(glXGetFBConfigAttrib_func, &ret, args, NULL); - if (debug_gl) log_gl("glXGetFBConfigAttrib config=%p, attrib=%d -> %d\n", config, attrib, *value); - } -end_of_glx_get_fb_config_attrib: - UNLOCK(glXGetFBConfigAttrib_func); - return ret; -} - -GLAPI int APIENTRY glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) -{ - CHECK_PROC_WITH_RET(glXGetFBConfigAttribSGIX); - int ret = 0; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(config), INT_TO_ARG(attribute), POINTER_TO_ARG(value) }; - do_opengl_call(glXGetFBConfigAttribSGIX_func, &ret, args, NULL); - if (debug_gl) - { - if (attribute < 0x20) - log_gl("glXGetFBConfigAttribSGIX %p %d = %d\n", (void*)config, attribute, *value); - else - log_gl("glXGetFBConfigAttribSGIX %p 0x%X = %d\n", (void*)config, attribute, *value); - } - return ret; -} - -GLAPI int APIENTRY glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) -{ - CHECK_PROC_WITH_RET(glXQueryContext); - int ret = 0; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(ctx), INT_TO_ARG(attribute), POINTER_TO_ARG(value) }; - do_opengl_call(glXQueryContext_func, &ret, args, NULL); - return ret; -} - -GLAPI void APIENTRY glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, unsigned int *value ) -{ - CHECK_PROC(glXQueryDrawable); - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(draw), INT_TO_ARG(attribute), POINTER_TO_ARG(value) }; - do_opengl_call(glXQueryDrawable_func, NULL, args, NULL); -} - -GLAPI int APIENTRY glXQueryGLXPbufferSGIX( Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value ) -{ - CHECK_PROC_WITH_RET(glXQueryGLXPbufferSGIX); - int ret = 0; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(pbuf), INT_TO_ARG(attribute), POINTER_TO_ARG(value) }; - do_opengl_call(glXQueryGLXPbufferSGIX_func, &ret, args, NULL); - return ret; -} - -static GLXPbuffer glXCreatePbuffer_no_lock(Display *dpy, - GLXFBConfig config, - const int *attribList) -{ - CHECK_PROC_WITH_RET(glXCreatePbuffer); - if (debug_gl) log_gl("glXCreatePbuffer %p\n", (void*)config); - - GLXPbuffer pbuffer; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(config), POINTER_TO_ARG(attribList) }; - int args_size[] = { 0, 0, sizeof(int) * _compute_length_of_attrib_list_including_zero(attribList, 1)}; - do_opengl_call_no_lock(glXCreatePbuffer_func, &pbuffer, args, args_size); - - return pbuffer; -} - -GLAPI GLXPbuffer APIENTRY glXCreatePbuffer(Display *dpy, - GLXFBConfig config, - const int *attribList) -{ - GLXPbuffer pbuffer; - LOCK(glXCreatePbuffer_func); - pbuffer = glXCreatePbuffer_no_lock(dpy, config, attribList); - UNLOCK(glXCreatePbuffer_func); - return pbuffer; -} - -GLAPI GLXPbufferSGIX APIENTRY glXCreateGLXPbufferSGIX( Display *dpy, - GLXFBConfigSGIX config, - unsigned int width, - unsigned int height, - int *attribList ) -{ - CHECK_PROC_WITH_RET(glXCreateGLXPbufferSGIX); - if (debug_gl) log_gl("glXCreateGLXPbufferSGIX %p\n", (void*)config); - - GLXPbufferSGIX pbuffer; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(config), INT_TO_ARG(width), INT_TO_ARG(height), POINTER_TO_ARG(attribList) }; - int args_size[] = { 0, 0, 0, 0, sizeof(int) * _compute_length_of_attrib_list_including_zero(attribList, 1)}; - do_opengl_call(glXCreateGLXPbufferSGIX_func, &pbuffer, args, args_size); - - return pbuffer; -} - -void glXBindTexImageATI(Display *dpy, GLXPbuffer pbuffer, int buffer) -{ - CHECK_PROC(glXBindTexImageATI); - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(pbuffer), INT_TO_ARG(buffer) }; - do_opengl_call(glXBindTexImageATI_func, NULL, args, NULL); -} - -void glXReleaseTexImageATI(Display *dpy, GLXPbuffer pbuffer, int buffer) -{ - CHECK_PROC(glXReleaseTexImageATI); - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(pbuffer), INT_TO_ARG(buffer) }; - do_opengl_call(glXReleaseTexImageATI_func, NULL, args, NULL); -} - -Bool glXBindTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer) -{ - Bool ret = 0; - CHECK_PROC_WITH_RET(glXBindTexImageARB); - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(pbuffer), INT_TO_ARG(buffer) }; - do_opengl_call(glXBindTexImageARB_func, &ret, args, NULL); - return ret; -} - -Bool glXReleaseTexImageARB(Display *dpy, GLXPbuffer pbuffer, int buffer) -{ - Bool ret = 0; - CHECK_PROC_WITH_RET(glXReleaseTexImageARB); - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(pbuffer), INT_TO_ARG(buffer) }; - do_opengl_call(glXReleaseTexImageARB_func, &ret, args, NULL); - return ret; -} - -GLAPI void APIENTRY glXDestroyPbuffer(Display* dpy, GLXPbuffer pbuffer) -{ - CHECK_PROC(glXDestroyPbuffer); - if (debug_gl) log_gl("glXDestroyPbuffer %d\n", (int)pbuffer); - - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(pbuffer) }; - do_opengl_call(glXDestroyPbuffer_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glXDestroyGLXPbufferSGIX(Display* dpy, GLXPbufferSGIX pbuffer) -{ - CHECK_PROC(glXDestroyGLXPbufferSGIX); - if (debug_gl) log_gl("glXDestroyGLXPbufferSGIX %d\n", (int)pbuffer); - - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(pbuffer) }; - do_opengl_call(glXDestroyGLXPbufferSGIX_func, NULL, args, NULL); -} - -static XVisualInfo* glXGetVisualFromFBConfig_no_lock( Display *dpy, GLXFBConfig config ) -{ - CHECK_PROC_WITH_RET(glXGetVisualFromFBConfig); - int screen = 0; - - if (debug_gl) log_gl("glXGetVisualFromFBConfig %p\n", (void*)config); - - XVisualInfo temp, *vis; - long mask; - int n; - int i; - - mask = VisualScreenMask | VisualDepthMask | VisualClassMask; - temp.screen = screen; - temp.depth = DefaultDepth(dpy,screen); - temp.class = DefaultVisual(dpy,screen)->class; - temp.visualid = DefaultVisual(dpy,screen)->visualid; - mask |= VisualIDMask; - - vis = XGetVisualInfo( dpy, mask, &temp, &n ); - - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(config)}; - int visualid; - do_opengl_call_no_lock(glXGetVisualFromFBConfig_func, &visualid, args, NULL); - - /*host vid�� tabAssocVisualInfoVisualId[]�� �����Ͽ� ��������� guest vi�� ����� �ʿ� ����*/ - /*vis->visualid = visualid;*/ - - assert (nEltTabAssocVisualInfoVisualId < MAX_SIZE_TAB_ASSOC_VISUALINFO_VISUALID); - for(i=0;ipbuffer = glXCreatePbuffer(dpy, fbconfig, pbufAttrib); - assert(glstates[nbGLStates-1]->pbuffer); - } - } - UNLOCK(glXCreateNewContext_func); - return ctxt; -} - -GLAPI Bool APIENTRY glXMakeContextCurrent( Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx ) -{ - Bool ret; - GET_CURRENT_STATE(); - if (draw != read) - { - static int first_time = 1; - if (first_time) - { - first_time = 0; - log_gl("using glXMakeCurrent instead of real glXMakeContextCurrent... may help some program work...\n"); - } - } - ret = glXMakeCurrent(dpy, draw, ctx); - if (ret) - state->current_read_drawable = read; - return ret; -} - -GLAPI GLXContext APIENTRY glXCreateContextWithConfigSGIX( Display *dpy, - GLXFBConfigSGIX config, - int renderType, - GLXContext shareList, - Bool direct ) -{ - CHECK_PROC_WITH_RET(glXCreateContextWithConfigSGIX); - if (debug_gl) log_gl("glXCreateContextWithConfigSGIX %p\n", (void*)config); - - GLXContext ctxt; - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(config), INT_TO_ARG(renderType), INT_TO_ARG(shareList), - INT_TO_ARG(direct) }; - do_opengl_call(glXCreateContextWithConfigSGIX_func, &ctxt, args, NULL); - return ctxt; -} - -GLAPI GLXWindow APIENTRY glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, const int *attribList ) -{ - CHECK_PROC_WITH_RET(glXCreateWindow); - /* do nothing. Not sure about this implementation. FIXME */ - -#ifdef __CLIENT_WINDOW__ - int i; - WindowImage *image = NULL; - - for(i = 0; i < MAX_IMAGES; i++) - { - if( wImage[i].win == 0 && image == NULL ) - { - image = &wImage[i]; - break; - } - else if( wImage[i].win == win ) - { - image = &wImage[i]; - return (GLXWindow)win; - } - } - - if( image ) - { - image->win_gc = XCreateGC(dpy, win, 0, NULL); - if( image->win_gc == NULL ) - { - log_gl("Winodow GC Create Fail \n"); - return (GLXWindow)win; - } - - if( _create_image(dpy, win, image) == False ) - { - XFreeGC(dpy, image->win_gc); - image->win_gc = NULL; - log_gl("Window Image Create Fail \n"); - return (GLXWindow)win; - } - } -#endif - - return (GLXWindow)win; -} - -GLAPI void APIENTRY glXDestroyWindow( Display *dpy, GLXWindow window ) -{ - CHECK_PROC(glXDestroyWindow); - /* Destroy Sub-Window of Host OS */ - -#ifdef __CLIENT_WINDOW__ - int i; - WindowImage *image = NULL; - - if (debug_gl) log_gl("glXDestroyWindow %d\n", (int)window); - - for(i = 0; i < MAX_IMAGES; i++) - { - if( wImage[i].win == (Window)window ) - { - image = &wImage[i]; - break; - } - } - - if( image && image->win) - { - _destroy_image(dpy, image); - - XFreeGC(dpy, image->win_gc); - image->win_gc = NULL; - } -#endif - - if ( window ) { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(window) }; - do_opengl_call(glXDestroyWindow_func, NULL, args, NULL); - } -} - -GLAPI GLXPixmap APIENTRY glXCreateGLXPixmap( Display *dpy, - XVisualInfo *vis, - Pixmap pixmap ) -{ - CHECK_PROC_WITH_RET(glXCreateGLXPixmap); - /* FIXME */ - log_gl("glXCreateGLXPixmap : sorry, unsupported call and I don't really see how I could implement it..."); - return 0; -} - -GLAPI void APIENTRY glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) -{ - CHECK_PROC(glXDestroyGLXPixmap); - /* FIXME */ - log_gl("glXDestroyGLXPixmap : sorry, unsupported call and I don't really see how I could implement it..."); -} - -GLAPI GLXPixmap APIENTRY glXCreatePixmap( Display *dpy, GLXFBConfig config, - Pixmap pixmap, const int *attribList ) -{ - CHECK_PROC_WITH_RET(glXCreatePixmap); - /* FIXME */ - log_gl("glXCreatePixmap : sorry, unsupported call and I don't really see how I could implement it..."); - return 0; -} - -GLAPI void APIENTRY glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) -{ - CHECK_PROC(glXDestroyPixmap); - /* FIXME */ - log_gl("glXDestroyPixmap : sorry, unsupported call and I don't really see how I could implement it..."); -} - -GLAPI GLXDrawable APIENTRY glXGetCurrentReadDrawable( void ) -{ - CHECK_PROC_WITH_RET(glXGetCurrentReadDrawable); - GET_CURRENT_STATE(); - return state->current_read_drawable; -} - -GLAPI void APIENTRY glXSelectEvent( Display *dpy, GLXDrawable drawable, - unsigned long mask ) -{ - CHECK_PROC(glXSelectEvent); - log_gl("glXSelectEvent : sorry, unsupported call"); -} - -GLAPI void APIENTRY glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, - unsigned long *mask ) -{ - CHECK_PROC(glXGetSelectedEvent); - log_gl("glXGetSelectedEvent : sorry, unsupported call"); -} - - -#include "opengl_client_xfonts.c" - -GLAPI const char * APIENTRY EXT_FUNC(glXGetScreenDriver) (Display *dpy, int screen) -{ - static const char* ret = NULL; - LOCK(glXGetScreenDriver_func); - CHECK_PROC_WITH_RET(glXGetScreenDriver); - if (ret == NULL) - { - long args[] = { POINTER_TO_ARG(dpy), INT_TO_ARG(screen) }; - do_opengl_call_no_lock(glXGetScreenDriver_func, &ret, args, NULL); - ret = strdup(ret); - } - UNLOCK(glXGetScreenDriver_func); - return ret; -} - -GLAPI const char * APIENTRY EXT_FUNC(glXGetDriverConfig) (const char *drivername) -{ - static const char* ret = NULL; - CHECK_PROC_WITH_RET(glXGetDriverConfig); - long args[] = { POINTER_TO_ARG(drivername) }; - if (ret) free((void*)ret); - do_opengl_call(glXGetDriverConfig_func, &ret, args, NULL); - ret = strdup(ret); - return ret; -} - -/* For googleearth */ -static int counterSync = 0; - -GLAPI int APIENTRY EXT_FUNC(glXWaitVideoSyncSGI) ( int divisor, int remainder, unsigned int *count ) -{ - CHECK_PROC_WITH_RET(glXWaitVideoSyncSGI); - //log_gl("glXWaitVideoSyncSGI %d %d\n", divisor, remainder); - *count = counterSync++; // FIXME ? - return 0; -} - -GLAPI int APIENTRY EXT_FUNC(glXGetVideoSyncSGI)( unsigned int *count ) -{ - CHECK_PROC_WITH_RET(glXGetVideoSyncSGI); - //log_gl("glXGetVideoSyncSGI\n"); - *count = counterSync++; // FIXME ? - return 0; -} - -GLAPI int APIENTRY EXT_FUNC(glXSwapIntervalSGI) ( int interval ) -{ - CHECK_PROC_WITH_RET(glXSwapIntervalSGI); - long args[] = { INT_TO_ARG(interval) }; - int ret = 0; - do_opengl_call(glXSwapIntervalSGI_func, &ret, args, NULL); - //log_gl("glXSwapIntervalSGI(%d) = %d\n", interval, ret); - return ret; -} - -#endif - -GLAPI const GLubyte * APIENTRY glGetString( GLenum name ) -{ - int i; - static GLubyte* glStrings[6] = {NULL}; - static const char* glGetStringsName[] = { - "GL_VENDOR", - "GL_RENDERER", - "GL_VERSION", - "GL_EXTENSIONS", - "GL_SHADING_LANGUAGE_VERSION", - }; - - if (name >= GL_VENDOR && name <= GL_EXTENSIONS) - i = name - GL_VENDOR; - else if (name == GL_SHADING_LANGUAGE_VERSION) - i = 4; - else if (name == GL_PROGRAM_ERROR_STRING_NV) - i = 5; - else - { - log_gl("assert(name >= GL_VENDOR && name <= GL_EXTENSIONS || name == GL_SHADING_LANGUAGE_VERSION || name == GL_PROGRAM_ERROR_STRING_NV)\n"); - return NULL; - } - LOCK(glGetString_func); - if (glStrings[i] == NULL) - { - if (i <= 4 && getenv(glGetStringsName[i])) - { - glStrings[i] = getenv(glGetStringsName[i]); - } - else - { - long args[] = { INT_TO_ARG(name) }; - do_opengl_call_no_lock(glGetString_func, &glStrings[i], args, NULL); - } - - log_gl("glGetString(0x%X) = %s\n", name, glStrings[i]); - glStrings[name - GL_VENDOR] = strdup((char*)glStrings[i]); - if (name == GL_EXTENSIONS) - { - removeUnwantedExtensions(glStrings[i]); - } - } - UNLOCK(glGetString_func); - return glStrings[i]; -} - -#define CASE_GL_PIXEL_MAP(x) case GL_PIXEL_MAP_##x: glGetIntegerv_no_lock(CONCAT(GL_PIXEL_MAP_##x,_SIZE), &value); return value; - -static int get_glgetpixelmapv_size(int map) -{ - int value; - switch (map) - { - LOCK(glGetIntegerv_func); - CASE_GL_PIXEL_MAP(I_TO_I); - CASE_GL_PIXEL_MAP(S_TO_S); - CASE_GL_PIXEL_MAP(I_TO_R); - CASE_GL_PIXEL_MAP(I_TO_G); - CASE_GL_PIXEL_MAP(I_TO_B); - CASE_GL_PIXEL_MAP(I_TO_A); - CASE_GL_PIXEL_MAP(R_TO_R); - CASE_GL_PIXEL_MAP(G_TO_G); - CASE_GL_PIXEL_MAP(B_TO_B); - CASE_GL_PIXEL_MAP(A_TO_A); - UNLOCK(glGetIntegerv_func); - default : - { - log_gl("unhandled map = %d\n", map); - return 0; - } - } -} - -GLAPI void APIENTRY glGetPixelMapfv( GLenum map, GLfloat *values ) -{ - long args[] = { INT_TO_ARG(map), POINTER_TO_ARG(values) }; - int args_size[] = { 0, get_glgetpixelmapv_size(map) * sizeof(float) }; - if (args_size[1] == 0) return; - do_opengl_call(glGetPixelMapfv_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY glGetPixelMapuiv( GLenum map, GLuint *values ) -{ - long args[] = { INT_TO_ARG(map), POINTER_TO_ARG(values) }; - int args_size[] = { 0, get_glgetpixelmapv_size(map) * sizeof(int) }; - if (args_size[1] == 0) return; - do_opengl_call(glGetPixelMapuiv_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY glGetPixelMapusv( GLenum map, GLushort *values ) -{ - long args[] = { INT_TO_ARG(map), POINTER_TO_ARG(values) }; - int args_size[] = { 0, get_glgetpixelmapv_size(map) * sizeof(short) }; - if (args_size[1] == 0) return; - do_opengl_call(glGetPixelMapusv_func, NULL, CHECK_ARGS(args, args_size)); -} - -static int glMap1_get_multiplier(GLenum target) -{ - switch (target) - { - case GL_MAP1_VERTEX_3: - case GL_MAP1_NORMAL: - case GL_MAP1_TEXTURE_COORD_3: - return 3; - break; - - case GL_MAP1_VERTEX_4: - case GL_MAP1_COLOR_4: - case GL_MAP1_TEXTURE_COORD_4: - return 4; - break; - - case GL_MAP1_INDEX: - case GL_MAP1_TEXTURE_COORD_1: - return 1; - break; - - case GL_MAP1_TEXTURE_COORD_2: - return 2; - break; - - default: - if (target >= GL_MAP1_VERTEX_ATTRIB0_4_NV && target <= GL_MAP1_VERTEX_ATTRIB15_4_NV) - return 4; - log_gl("unhandled target = %d\n", target); - return 0; - } -} - - -static int glMap2_get_multiplier(GLenum target) -{ - switch (target) - { - case GL_MAP2_VERTEX_3: - case GL_MAP2_NORMAL: - case GL_MAP2_TEXTURE_COORD_3: - return 3; - break; - - case GL_MAP2_VERTEX_4: - case GL_MAP2_COLOR_4: - case GL_MAP2_TEXTURE_COORD_4: - return 4; - break; - - case GL_MAP2_INDEX: - case GL_MAP2_TEXTURE_COORD_1: - return 1; - break; - - case GL_MAP2_TEXTURE_COORD_2: - return 2; - break; - - default: - if (target >= GL_MAP2_VERTEX_ATTRIB0_4_NV && target <= GL_MAP2_VERTEX_ATTRIB15_4_NV) - return 4; - log_gl("unhandled target = %d\n", target); - return 0; - } -} - -static int get_dimensionnal_evaluator(GLenum target) -{ - switch(target) - { - case GL_MAP1_COLOR_4: - case GL_MAP1_INDEX: - case GL_MAP1_NORMAL: - case GL_MAP1_TEXTURE_COORD_1: - case GL_MAP1_TEXTURE_COORD_2: - case GL_MAP1_TEXTURE_COORD_3: - case GL_MAP1_TEXTURE_COORD_4: - case GL_MAP1_VERTEX_3: - case GL_MAP1_VERTEX_4: - return 1; - - case GL_MAP2_COLOR_4: - case GL_MAP2_INDEX: - case GL_MAP2_NORMAL: - case GL_MAP2_TEXTURE_COORD_1: - case GL_MAP2_TEXTURE_COORD_2: - case GL_MAP2_TEXTURE_COORD_3: - case GL_MAP2_TEXTURE_COORD_4: - case GL_MAP2_VERTEX_3: - case GL_MAP2_VERTEX_4: - return 2; - - default: - log_gl("unhandled target %d\n", target); - return 0; - } -} - -GLAPI void APIENTRY glMap1f( GLenum target, - GLfloat u1, - GLfloat u2, - GLint stride, - GLint order, - const GLfloat *points ) -{ - long args[] = { INT_TO_ARG(target), FLOAT_TO_ARG(u1), FLOAT_TO_ARG(u2), - INT_TO_ARG(stride), INT_TO_ARG(order), POINTER_TO_ARG(points) }; - int args_size[] = { 0, 0, 0, 0, 0, 0 }; - int num_points = order; - int multiplier = glMap1_get_multiplier(target); - if (multiplier) - { - num_points *= multiplier; - args_size[5] = num_points * sizeof(float); - do_opengl_call(glMap1f_func, NULL, CHECK_ARGS(args, args_size)); - } -} - -GLAPI void APIENTRY glMap1d( GLenum target, - GLdouble u1, - GLdouble u2, - GLint stride, - GLint order, - const GLdouble *points ) -{ - long args[] = { INT_TO_ARG(target), DOUBLE_TO_ARG(u1), DOUBLE_TO_ARG(u2), - INT_TO_ARG(stride), INT_TO_ARG(order), POINTER_TO_ARG(points) }; - int args_size[] = { 0, 0, 0, 0, 0, 0 }; - int num_points = order; - int multiplier = glMap1_get_multiplier(target); - if (multiplier) - { - num_points *= multiplier; - args_size[5] = num_points * sizeof(double); - do_opengl_call(glMap1d_func, NULL, CHECK_ARGS(args, args_size)); - } -} - -GLAPI void APIENTRY glMap2f( GLenum target, - GLfloat u1, - GLfloat u2, - GLint ustride, - GLint uorder, - GLfloat v1, - GLfloat v2, - GLint vstride, - GLint vorder, - const GLfloat *points ) -{ - long args[] = { INT_TO_ARG(target), - FLOAT_TO_ARG(u1), FLOAT_TO_ARG(u2), - INT_TO_ARG(ustride), INT_TO_ARG(uorder), - FLOAT_TO_ARG(v1), FLOAT_TO_ARG(v2), - INT_TO_ARG(vstride), INT_TO_ARG(vorder), - POINTER_TO_ARG(points) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int num_points = uorder * vorder; - int multiplier = glMap2_get_multiplier(target); - if (multiplier) - { - num_points *= multiplier; - args_size[9] = num_points * sizeof(float); - do_opengl_call(glMap2f_func, NULL, CHECK_ARGS(args, args_size)); - } -} - - -GLAPI void APIENTRY glMap2d( GLenum target, - GLdouble u1, - GLdouble u2, - GLint ustride, - GLint uorder, - GLdouble v1, - GLdouble v2, - GLint vstride, - GLint vorder, - const GLdouble *points ) -{ - long args[] = { INT_TO_ARG(target), - DOUBLE_TO_ARG(u1), DOUBLE_TO_ARG(u2), - INT_TO_ARG(ustride), INT_TO_ARG(uorder), - DOUBLE_TO_ARG(v1), DOUBLE_TO_ARG(v2), - INT_TO_ARG(vstride), INT_TO_ARG(vorder), - POINTER_TO_ARG(points) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - int num_points = uorder * vorder; - int multiplier = glMap2_get_multiplier(target); - if (multiplier) - { - num_points *= multiplier; - args_size[9] = num_points * sizeof(double); - do_opengl_call(glMap2d_func, NULL, CHECK_ARGS(args, args_size)); - } -} - -static int _glGetMapv_get_n_components( GLenum target, GLenum query) -{ - int dim = get_dimensionnal_evaluator(target); - if (query == GL_COEFF) - { - int orders[2] = { 1, 1 }; - glGetMapiv(target, GL_ORDER, orders); - return orders[0] * orders[1] * ((dim == 1) ? glMap1_get_multiplier(target) : glMap2_get_multiplier(target)); - } - else if (query == GL_ORDER) - { - return dim; - } - else if (query == GL_DOMAIN) - { - return 2 * dim; - } - else - return 0; -} - - -GLAPI void APIENTRY glGetMapdv( GLenum target, GLenum query, GLdouble *v ) -{ - int dim = get_dimensionnal_evaluator(target); - if (dim == 0) return; - long args[] = { INT_TO_ARG(target), INT_TO_ARG(query), POINTER_TO_ARG(v) }; - int args_size[] = { 0, 0, _glGetMapv_get_n_components(target, query) * sizeof(double) }; - do_opengl_call(glGetMapdv_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY glGetMapfv( GLenum target, GLenum query, GLfloat *v ) -{ - int dim = get_dimensionnal_evaluator(target); - if (dim == 0) return; - long args[] = { INT_TO_ARG(target), INT_TO_ARG(query), POINTER_TO_ARG(v) }; - int args_size[] = { 0, 0, _glGetMapv_get_n_components(target, query) * sizeof(float) }; - do_opengl_call(glGetMapfv_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY glGetMapiv( GLenum target, GLenum query, GLint *v ) -{ - int dim = get_dimensionnal_evaluator(target); - if (dim == 0) return; - long args[] = { INT_TO_ARG(target), INT_TO_ARG(query), POINTER_TO_ARG(v) }; - int args_size[] = { 0, 0, _glGetMapv_get_n_components(target, query) * sizeof(int) }; - do_opengl_call(glGetMapiv_func, NULL, CHECK_ARGS(args, args_size)); -} - - - -GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture) -{ - CHECK_PROC(glBindTexture); - GET_CURRENT_STATE(); - alloc_value(state->textureAllocator, texture); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(texture) }; - if (target == GL_TEXTURE_2D) - { - state->current_server_state.bindTexture2D = texture; - } - else if (target == GL_TEXTURE_RECTANGLE_ARB) - { - state->current_server_state.bindTextureRectangle = texture; - } - do_opengl_call(glBindTexture_func, NULL, args, NULL); -} - -GLAPI void APIENTRY EXT_FUNC(glBindTextureEXT) (GLenum target, GLuint texture) -{ - glBindTexture(target, texture); -} - - -GLAPI void APIENTRY glGenTextures( GLsizei n, GLuint *textures ) -{ - CHECK_PROC(glGenTextures); - GET_CURRENT_STATE(); - if (n <= 0) { log_gl("n <= 0\n"); return; } - alloc_range(state->textureAllocator, n, textures); - long args[] = { n }; - do_opengl_call(glGenTextures_fake_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glGenTexturesEXT( GLsizei n, GLuint *textures ) -{ - glGenTextures(n, textures); -} - -GLAPI void APIENTRY glDeleteTextures ( GLsizei n, const GLuint *textures ) -{ - CHECK_PROC(glDeleteTextures); - GET_CURRENT_STATE(); - if (n <= 0) { log_gl("n <= 0\n"); return; } - delete_range(state->textureAllocator, n, textures); - long args[] = { INT_TO_ARG(n), POINTER_TO_ARG(textures) }; - do_opengl_call(glDeleteTextures_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glDeleteTexturesEXT ( GLsizei n, const GLuint *textures ) -{ - glDeleteTextures(n, textures); -} - -static int getTexImageTypeSizeSimple(int format, int type) -{ - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_BYTE: - return 1; - - case GL_UNSIGNED_SHORT: - case GL_SHORT: - return 2; - - case GL_UNSIGNED_INT: - case GL_INT: - case GL_UNSIGNED_INT_24_8_EXT: - case GL_FLOAT: - return 4; - - default: - log_gl("unknown texture type %d for texture format %d\n", type, format); - return 0; - } -} - -static int getTexImageFactorFromFormatAndType(int format, int type) -{ - switch (format) - { - case GL_COLOR_INDEX: - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_DEPTH_COMPONENT: - case GL_STENCIL_INDEX: - case GL_DEPTH_STENCIL_EXT: - return 1 * getTexImageTypeSizeSimple(format, type); - break; - - case GL_LUMINANCE_ALPHA: - return 2 * getTexImageTypeSizeSimple(format, type); - break; - - case GL_YCBCR_MESA: - { - switch (type) - { - case GL_UNSIGNED_SHORT_8_8_MESA: - case GL_UNSIGNED_SHORT_8_8_REV_MESA: - return 2; - - default: - log_gl("unknown texture type %d for texture format %d\n", type, format); - return 0; - } - } - - case GL_RGB: - case GL_BGR: - { - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_BYTE: - return 1 * 3; - - case GL_UNSIGNED_SHORT: - case GL_SHORT: - return 2 * 3; - - case GL_UNSIGNED_INT: - case GL_INT: - case GL_FLOAT: - return 4 * 3; - - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - return 1; - - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_8_8_MESA: - case GL_UNSIGNED_SHORT_8_8_REV_MESA: - return 2; - - default: - log_gl("unknown texture type %d for texture format %d\n", type, format); - return 0; - } - } - - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - { - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_BYTE: - return 1 * 4; - - case GL_UNSIGNED_SHORT: - case GL_SHORT: - return 2 * 4; - - case GL_UNSIGNED_INT: - case GL_INT: - case GL_FLOAT: - return 4 * 4; - - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return 2; - - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - return 4; - - default: - log_gl("unknown texture type %d for texture format %d\n", type, format); - return 0; - } - } - - default: - log_gl("unknown texture format : %d\n", format); - return 0; - } -} - -static void* _calcReadSize(int width, int height, int depth, GLenum format, GLenum type, void* pixels, int* p_size) -{ - int pack_row_length, pack_alignment, pack_skip_rows, pack_skip_pixels; - - LOCK(glGetIntegerv_func); - glGetIntegerv_no_lock(GL_PACK_ROW_LENGTH, &pack_row_length); - glGetIntegerv_no_lock(GL_PACK_ALIGNMENT, &pack_alignment); - glGetIntegerv_no_lock(GL_PACK_SKIP_ROWS, &pack_skip_rows); - glGetIntegerv_no_lock(GL_PACK_SKIP_PIXELS, &pack_skip_pixels); - UNLOCK(glGetIntegerv_func); - - int w = (pack_row_length == 0) ? width : pack_row_length; - int size = ((width * getTexImageFactorFromFormatAndType(format, type) + pack_alignment - 1) & (~(pack_alignment-1))) * depth; - if (height >= 1) - size += ((w * getTexImageFactorFromFormatAndType(format, type) + pack_alignment - 1) & (~(pack_alignment-1)))* (height-1) * depth ; - *p_size = size; - - pixels += (pack_skip_pixels + pack_skip_rows * w) * getTexImageFactorFromFormatAndType(format, type); - - return pixels; -} - -static const void* _calcWriteSize(int width, int height, int depth, GLenum format, GLenum type, const void* pixels, int* p_size) -{ - int unpack_row_length, unpack_alignment, unpack_skip_rows, unpack_skip_pixels; - - LOCK(glGetIntegerv_func); - glGetIntegerv_no_lock(GL_UNPACK_ROW_LENGTH, &unpack_row_length); - glGetIntegerv_no_lock(GL_UNPACK_ALIGNMENT, &unpack_alignment); - glGetIntegerv_no_lock(GL_UNPACK_SKIP_ROWS, &unpack_skip_rows); - glGetIntegerv_no_lock(GL_UNPACK_SKIP_PIXELS, &unpack_skip_pixels); - UNLOCK(glGetIntegerv_func); - - int w = (unpack_row_length == 0) ? width : unpack_row_length; - int size = ((width * getTexImageFactorFromFormatAndType(format, type) + unpack_alignment - 1) & (~(unpack_alignment-1))) * depth; - if (height >= 1) - size += ((w * getTexImageFactorFromFormatAndType(format, type) + unpack_alignment - 1) & (~(unpack_alignment-1))) * (height-1) * depth; - *p_size = size; - - pixels += (unpack_skip_pixels + unpack_skip_rows * w) * getTexImageFactorFromFormatAndType(format, type); - - return pixels; -} - -GLAPI void APIENTRY glTexImage1D(GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLint border, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - int size = 0; - if (pixels) - pixels = _calcWriteSize(width, 1, 1, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat), - INT_TO_ARG(width), INT_TO_ARG(border), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, (pixels == NULL) ? 0 : size }; - do_opengl_call(glTexImage1D_func, NULL, CHECK_ARGS(args, args_size)); - -} - -GLAPI void APIENTRY glTexImage1DEXT(GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLint border, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - glTexImage1D(target, level, internalFormat, width, border, format, type, pixels); -} - -GLAPI GLint GLAPIENTRY gluBuild2DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) -{ - int size = 0; - pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(internalFormat), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, size }; - do_opengl_call(fake_gluBuild2DMipmaps_func, NULL, CHECK_ARGS(args, args_size)); - return 0; -} - -GLAPI void APIENTRY glTexImage2D( GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLsizei height, - GLint border, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - GET_CURRENT_STATE(); - int i; - int size = 0; - if (pixels) - pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size); - - if (target == GL_TEXTURE_2D) - { - for(i=0;icurrent_server_state.texture2DCacheDim;i++) - { - if (state->current_server_state.texture2DCache[i].texture == state->current_server_state.bindTexture2D && - state->current_server_state.texture2DCache[i].level == level) - { - state->current_server_state.texture2DCache[i].width = width; - state->current_server_state.texture2DCache[i].height = height; - break; - } - } - if (i == state->current_server_state.texture2DCacheDim) - { - state->current_server_state.texture2DCache = - realloc(state->current_server_state.texture2DCache, sizeof(Texture2DDim) * - (state->current_server_state.texture2DCacheDim + 1)); - i = state->current_server_state.texture2DCacheDim; - state->current_server_state.texture2DCache[i].texture = state->current_server_state.bindTexture2D; - state->current_server_state.texture2DCache[i].level = level; - state->current_server_state.texture2DCache[i].width = width; - state->current_server_state.texture2DCache[i].height = height; - state->current_server_state.texture2DCacheDim++; - } - } - else if (target == GL_PROXY_TEXTURE_2D_EXT) - { - for(i=0;icurrent_server_state.textureProxy2DCacheDim;i++) - { - if (state->current_server_state.textureProxy2DCache[i].level == level) - { - state->current_server_state.textureProxy2DCache[i].width = width; - state->current_server_state.textureProxy2DCache[i].height = height; - break; - } - } - if (i == state->current_server_state.textureProxy2DCacheDim) - { - state->current_server_state.textureProxy2DCache = - realloc(state->current_server_state.textureProxy2DCache, sizeof(Texture2DDim) * - (state->current_server_state.textureProxy2DCacheDim + 1)); - i = state->current_server_state.textureProxy2DCacheDim; - state->current_server_state.textureProxy2DCache[i].level = level; - state->current_server_state.textureProxy2DCache[i].width = width; - state->current_server_state.textureProxy2DCache[i].height = height; - state->current_server_state.textureProxy2DCacheDim++; - } - } - else if (target == GL_TEXTURE_RECTANGLE_ARB) - { - for(i=0;icurrent_server_state.textureRectangleCacheDim;i++) - { - if (state->current_server_state.textureRectangleCache[i].texture == state->current_server_state.bindTextureRectangle && - state->current_server_state.textureRectangleCache[i].level == level) - { - state->current_server_state.textureRectangleCache[i].width = width; - state->current_server_state.textureRectangleCache[i].height = height; - break; - } - } - if (i == state->current_server_state.textureRectangleCacheDim) - { - state->current_server_state.textureRectangleCache = - realloc(state->current_server_state.textureRectangleCache, sizeof(Texture2DDim) * - (state->current_server_state.textureRectangleCacheDim + 1)); - i = state->current_server_state.textureRectangleCacheDim; - state->current_server_state.textureRectangleCache[i].texture = state->current_server_state.bindTextureRectangle; - state->current_server_state.textureRectangleCache[i].level = level; - state->current_server_state.textureRectangleCache[i].width = width; - state->current_server_state.textureRectangleCache[i].height = height; - state->current_server_state.textureRectangleCacheDim++; - } - } - else if (target == GL_PROXY_TEXTURE_RECTANGLE_ARB) - { - for(i=0;icurrent_server_state.textureProxyRectangleCacheDim;i++) - { - if (state->current_server_state.textureProxyRectangleCache[i].level == level) - { - state->current_server_state.textureProxyRectangleCache[i].width = width; - state->current_server_state.textureProxyRectangleCache[i].height = height; - break; - } - } - if (i == state->current_server_state.textureProxyRectangleCacheDim) - { - state->current_server_state.textureProxyRectangleCache = - realloc(state->current_server_state.textureProxyRectangleCache, sizeof(Texture2DDim) * - (state->current_server_state.textureProxyRectangleCacheDim + 1)); - i = state->current_server_state.textureProxyRectangleCacheDim; - state->current_server_state.textureProxyRectangleCache[i].level = level; - state->current_server_state.textureProxyRectangleCache[i].width = width; - state->current_server_state.textureProxyRectangleCache[i].height = height; - state->current_server_state.textureProxyRectangleCacheDim++; - } - } - - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(border), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, (pixels == NULL) ? 0 : size }; - do_opengl_call(glTexImage2D_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY glTexImage2DEXT(GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLsizei height, - GLint border, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels); -} - -GLAPI void APIENTRY glTexImage3D( GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLint border, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - int size = 0; - if (pixels) - pixels = _calcWriteSize(width, height, depth, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(border), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, (pixels == NULL) ? 0 : size }; - do_opengl_call(glTexImage3D_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glTexImage3DEXT)(GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLint border, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - CHECK_PROC(glTexImage3DEXT); - glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels); -} - -GLAPI void APIENTRY glTexSubImage1D( GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - int size = 0; - if (pixels) - pixels = _calcWriteSize(width, 1, 1, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), - INT_TO_ARG(width), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, size }; - do_opengl_call(glTexSubImage1D_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glTexSubImage1DEXT)( GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - CHECK_PROC(glTexSubImage1DEXT); - glTexSubImage1D(target, level, xoffset, width, format, type, pixels); -} - -GLAPI void APIENTRY glTexSubImage2D( GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - int size = 0; - if (pixels) - pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, size }; - do_opengl_call(glTexSubImage2D_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glTexSubImage2DEXT)( GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - CHECK_PROC(glTexSubImage2DEXT); - glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); -} - -GLAPI void APIENTRY glTexSubImage3D( GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint zoffset, - GLsizei width, - GLsizei height, - GLsizei depth, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - int size = 0; - if (pixels) - pixels = _calcWriteSize(width, height, depth, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset), INT_TO_ARG(zoffset), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(format), INT_TO_ARG(type), - POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, size }; - do_opengl_call(glTexSubImage3D_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glTexSubImage3DEXT)( GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint zoffset, - GLsizei width, - GLsizei height, - GLsizei depth, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - CHECK_PROC(glTexSubImage3DEXT); - glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); -} -GLAPI void APIENTRY glSelectBuffer( GLsizei size, GLuint *buffer ) -{ - if (size <= 0) return; - GET_CURRENT_STATE(); - state->client_state.selectBufferSize = size; - state->client_state.selectBufferPtr = buffer; - long args[] = { INT_TO_ARG(size) }; - do_opengl_call(_glSelectBuffer_fake_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glFeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) -{ - if (size <= 0) return; - GET_CURRENT_STATE(); - state->client_state.feedbackBufferSize = size; - state->client_state.feedbackBufferPtr = buffer; - long args[] = { INT_TO_ARG(size), INT_TO_ARG(type) }; - do_opengl_call(_glFeedbackBuffer_fake_func, NULL, args, NULL); -} - -GLAPI GLint APIENTRY glRenderMode(GLenum mode) -{ - GLint ret; - GET_CURRENT_STATE(); - long args[] = { UNSIGNED_INT_TO_ARG(mode)}; - do_opengl_call(glRenderMode_func, &ret, args, NULL); - if (mode == GL_SELECT && state->client_state.selectBufferPtr) - { - long args[] = { POINTER_TO_ARG(state->client_state.selectBufferPtr) }; - int args_size[] = { state->client_state.selectBufferSize * 4 }; - do_opengl_call(_glGetSelectBuffer_fake_func, NULL, CHECK_ARGS(args, args_size)); - } - else if (mode == GL_FEEDBACK && state->client_state.selectBufferPtr) - { - long args[] = { POINTER_TO_ARG(state->client_state.feedbackBufferPtr) }; - int args_size[] = { state->client_state.feedbackBufferSize * 4 }; - do_opengl_call(_glGetFeedbackBuffer_fake_func, NULL, CHECK_ARGS(args, args_size)); - } - return ret; -} - - -GLAPI void APIENTRY EXT_FUNC(glGetCompressedTexImageARB)(GLenum target, GLint level, GLvoid *img) -{ - CHECK_PROC(glGetCompressedTexImageARB); - - int imageSize = 0; - glGetTexLevelParameteriv(target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &imageSize); - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), POINTER_TO_ARG(img) }; - int args_size[] = { 0, 0, imageSize }; - do_opengl_call(glGetCompressedTexImageARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glGetCompressedTexImage)(GLenum target, GLint level, GLvoid *img) -{ - glGetCompressedTexImageARB(target, level, img); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage1DARB)(GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLint border, - GLsizei imageSize, - const GLvoid * data) -{ - CHECK_PROC(glCompressedTexImage1DARB); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat), - INT_TO_ARG(width), INT_TO_ARG(border), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, imageSize }; - do_opengl_call(glCompressedTexImage1DARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage1D)(GLenum target, - GLint level, - GLenum internalFormat, - GLsizei width, - GLint border, - GLsizei imageSize, - const GLvoid * data) -{ - glCompressedTexImage1DARB(target, level, internalFormat, width, border, imageSize, data); -} - - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage2DARB)(GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLsizei height, - GLint border, - GLsizei imageSize, - const GLvoid * data) -{ - CHECK_PROC(glCompressedTexImage2DARB); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(border), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, imageSize }; - do_opengl_call(glCompressedTexImage2DARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage2D)(GLenum target, - GLint level, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLint border, - GLsizei imageSize, - const GLvoid * data) -{ - glCompressedTexImage2DARB(target, level, internalFormat, width, height, border, imageSize, data); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage3DARB)(GLenum target, - GLint level, - GLint internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLint border, - GLsizei imageSize, - const GLvoid * data) -{ - CHECK_PROC(glCompressedTexImage3DARB); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(internalFormat), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(border), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, imageSize }; - do_opengl_call(glCompressedTexImage3DARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexImage3D)(GLenum target, - GLint level, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLint border, - GLsizei imageSize, - const GLvoid * data) -{ - glCompressedTexImage3DARB(target, level, internalFormat, width, height, depth, border, imageSize, data); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage1DARB)(GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, - GLsizei imageSize, - const GLvoid * data) -{ - CHECK_PROC(glCompressedTexSubImage1DARB); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), - INT_TO_ARG(width), INT_TO_ARG(format), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, imageSize }; - do_opengl_call(glCompressedTexSubImage1DARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage1D)(GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, - GLsizei imageSize, - const GLvoid * data) -{ - glCompressedTexSubImage1DARB(target, level, xoffset, width, format, imageSize, data); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage2DARB)(GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLsizei width, - GLsizei height, - GLenum format, - GLsizei imageSize, - const GLvoid * data) -{ - CHECK_PROC(glCompressedTexSubImage2DARB); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(format), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, imageSize }; - do_opengl_call(glCompressedTexSubImage2DARB_func, NULL, CHECK_ARGS(args, args_size)); -} - - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage2D)(GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLsizei width, - GLsizei height, - GLenum format, - GLsizei imageSize, - const GLvoid * data) -{ - glCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage3DARB)(GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint zoffset, - GLsizei width, - GLsizei height, - GLsizei depth, - GLenum format, - GLsizei imageSize, - const GLvoid * data) -{ - CHECK_PROC(glCompressedTexSubImage3DARB); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(xoffset), INT_TO_ARG(yoffset), INT_TO_ARG(zoffset), - INT_TO_ARG(width), INT_TO_ARG(height), INT_TO_ARG(depth), INT_TO_ARG(format), INT_TO_ARG(imageSize), POINTER_TO_ARG(data) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, imageSize }; - do_opengl_call(glCompressedTexSubImage3DARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glCompressedTexSubImage3D)(GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint zoffset, - GLsizei width, - GLsizei height, - GLsizei depth, - GLenum format, - GLsizei imageSize, - const GLvoid * data) -{ - glCompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); -} - - -GLAPI void APIENTRY glGetTexLevelParameteriv( GLenum target, - GLint level, - GLenum pname, - GLint *params ) -{ - int i; - GET_CURRENT_STATE(); - - if (target == GL_TEXTURE_2D && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT)) - { - for(i=0;icurrent_server_state.texture2DCacheDim;i++) - { - if (state->current_server_state.texture2DCache[i].texture == state->current_server_state.bindTexture2D && - state->current_server_state.texture2DCache[i].level == level) - { - if (pname == GL_TEXTURE_WIDTH) - { - *params = state->current_server_state.texture2DCache[i].width; - return; - } - if (pname == GL_TEXTURE_HEIGHT) - { - *params = state->current_server_state.texture2DCache[i].height; - return; - } - } - } - } - else if (target == GL_PROXY_TEXTURE_2D_EXT && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT)) - { - for(i=0;icurrent_server_state.textureProxy2DCacheDim;i++) - { - if (state->current_server_state.textureProxy2DCache[i].level == level) - { - if (pname == GL_TEXTURE_WIDTH) - { - *params = state->current_server_state.textureProxy2DCache[i].width; - return; - } - if (pname == GL_TEXTURE_HEIGHT) - { - *params = state->current_server_state.textureProxy2DCache[i].height; - return; - } - } - } - } - else if (target == GL_TEXTURE_RECTANGLE_ARB && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT)) - { - for(i=0;icurrent_server_state.textureRectangleCacheDim;i++) - { - if (state->current_server_state.textureRectangleCache[i].texture == state->current_server_state.bindTextureRectangle && - state->current_server_state.textureRectangleCache[i].level == level) - { - if (pname == GL_TEXTURE_WIDTH) - { - *params = state->current_server_state.textureRectangleCache[i].width; - return; - } - if (pname == GL_TEXTURE_HEIGHT) - { - *params = state->current_server_state.textureRectangleCache[i].height; - return; - } - } - } - } - else if (target == GL_PROXY_TEXTURE_RECTANGLE_ARB && (pname == GL_TEXTURE_WIDTH || pname == GL_TEXTURE_HEIGHT)) - { - for(i=0;icurrent_server_state.textureProxyRectangleCacheDim;i++) - { - if (state->current_server_state.textureProxyRectangleCache[i].level == level) - { - if (pname == GL_TEXTURE_WIDTH) - { - *params = state->current_server_state.textureProxyRectangleCache[i].width; - return; - } - if (pname == GL_TEXTURE_HEIGHT) - { - *params = state->current_server_state.textureProxyRectangleCache[i].height; - return; - } - } - } - } - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(pname), POINTER_TO_ARG(params) }; - do_opengl_call(glGetTexLevelParameteriv_func, NULL, args, NULL); - -} - - -GLAPI void APIENTRY glGetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) -{ - if (pname == GL_TEXTURE_MAX_ANISOTROPY_EXT) - *params = 1; - else - { - int size = __glTexParameter_size(get_err_file(), pname); - long args[] = { INT_TO_ARG(target), INT_TO_ARG(pname), POINTER_TO_ARG(params) }; - int args_size[] = { 0, 0, size * sizeof(GLfloat) }; - do_opengl_call(glGetTexParameterfv_func, NULL, CHECK_ARGS(args, args_size)); - } -} - -GLAPI void APIENTRY glFogf(GLenum pname, GLfloat param) -{ - GET_CURRENT_STATE(); - if (pname == GL_FOG_MODE) - state->current_server_state.fog.mode = param; - else if (pname == GL_FOG_DENSITY) - state->current_server_state.fog.density = param; - else if (pname == GL_FOG_START) - state->current_server_state.fog.start = param; - else if (pname == GL_FOG_END) - state->current_server_state.fog.end = param; - else if (pname == GL_FOG_INDEX) - state->current_server_state.fog.index = param; - long args[] = { UNSIGNED_INT_TO_ARG(pname), FLOAT_TO_ARG(param)}; - do_opengl_call(glFogf_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glFogi(GLenum pname, GLint param) -{ - GET_CURRENT_STATE(); - if (pname == GL_FOG_MODE) - state->current_server_state.fog.mode = param; - else if (pname == GL_FOG_DENSITY) - state->current_server_state.fog.density = param; - else if (pname == GL_FOG_START) - state->current_server_state.fog.start = param; - else if (pname == GL_FOG_END) - state->current_server_state.fog.end = param; - else if (pname == GL_FOG_INDEX) - state->current_server_state.fog.index = param; - long args[] = { UNSIGNED_INT_TO_ARG(pname), INT_TO_ARG(param)}; - do_opengl_call(glFogi_func, NULL, args, NULL); -} - - -GLAPI void APIENTRY glFogfv( GLenum pname, const GLfloat *params ) -{ - if (pname != GL_FOG_COLOR) - { - glFogf(pname, *params); - return; - } - GET_CURRENT_STATE(); - long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) }; - memcpy(state->current_server_state.fog.color, params, 4 * sizeof(float)); - do_opengl_call(glFogfv_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glFogiv( GLenum pname, const GLint *params ) -{ - if (pname != GL_FOG_COLOR) - { - glFogi(pname, *params); - return; - } - long args[] = { INT_TO_ARG(pname), POINTER_TO_ARG(params) }; - do_opengl_call(glFogiv_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glRectdv( const GLdouble *v1, const GLdouble *v2 ) -{ - glRectd(v1[0], v1[1], v2[0], v2[1]); -} -GLAPI void APIENTRY glRectfv( const GLfloat *v1, const GLfloat *v2 ) -{ - glRectf(v1[0], v1[1], v2[0], v2[1]); -} -GLAPI void APIENTRY glRectiv( const GLint *v1, const GLint *v2 ) -{ - glRecti(v1[0], v1[1], v2[0], v2[1]); -} -GLAPI void APIENTRY glRectsv( const GLshort *v1, const GLshort *v2 ) -{ - glRects(v1[0], v1[1], v2[0], v2[1]); -} - - -GLAPI void APIENTRY glBitmap(GLsizei width, - GLsizei height, - GLfloat xorig, - GLfloat yorig, - GLfloat xmove, - GLfloat ymove, - const GLubyte *bitmap ) -{ - GET_CURRENT_STATE(); - int unpack_alignment, unpack_row_length; - LOCK(glGetIntegerv_func); - glGetIntegerv_no_lock(GL_UNPACK_ROW_LENGTH, &unpack_row_length); - glGetIntegerv_no_lock(GL_UNPACK_ALIGNMENT, &unpack_alignment); - UNLOCK(glGetIntegerv_func); - int w = (unpack_row_length == 0) ? width : unpack_row_length; - int size = ((w + unpack_alignment - 1) & (~(unpack_alignment-1))) * height; - long args[] = { INT_TO_ARG(width), INT_TO_ARG(height), FLOAT_TO_ARG(xorig), FLOAT_TO_ARG(yorig), - FLOAT_TO_ARG(xmove), FLOAT_TO_ARG(ymove), POINTER_TO_ARG(bitmap) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, size }; - do_opengl_call(glBitmap_func, NULL, CHECK_ARGS(args, args_size)); - - state->currentRasterPos[0] += xmove; - state->currentRasterPos[1] += ymove; -} - - -GLAPI void APIENTRY glGetTexImage( GLenum target, - GLint level, - GLenum format, - GLenum type, - GLvoid *pixels ) -{ - int size = 0, width, height = 1, depth = 1; - if (target == GL_PROXY_TEXTURE_1D || target == GL_PROXY_TEXTURE_2D || target == GL_PROXY_TEXTURE_3D) - { - log_gl("unhandled target : %d\n", target); - return; - } - glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); - if (target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB || target == GL_TEXTURE_3D) - glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); - if (target == GL_TEXTURE_3D) - glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth); - - pixels = _calcReadSize(width, height, depth, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(target), INT_TO_ARG(level), INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, size }; - do_opengl_call(glGetTexImage_func, NULL, CHECK_ARGS(args, args_size)); -} - - -static void glReadPixels_no_lock(GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - GLvoid *pixels ) -{ - GET_CURRENT_STATE(); - if (state->pixelPackBuffer) - { - int fake_ret; - long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height), - INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - /* Make it synchronous, otherwise it floods server */ - do_opengl_call_no_lock(_glReadPixels_pbo_func, &fake_ret, args, NULL); - } - else - { - int size = 0; - - pixels = _calcReadSize(width, height, 1, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(x), INT_TO_ARG(y), INT_TO_ARG(width), INT_TO_ARG(height), - INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, size }; - - do_opengl_call_no_lock(glReadPixels_func, NULL, CHECK_ARGS(args, args_size)); - } -} -GLAPI void APIENTRY glReadPixels(GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - GLvoid *pixels ) -{ - LOCK(glReadPixels_func); - glReadPixels_no_lock(x, y, width, height, format, type, pixels); - UNLOCK(glReadPixels_func); -} - -GLAPI void APIENTRY glDrawPixels(GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - const GLvoid *pixels ) -{ - GET_CURRENT_STATE(); - if (state->pixelUnpackBuffer) - { - long args[] = { INT_TO_ARG(width), INT_TO_ARG(height), - INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - do_opengl_call(_glDrawPixels_pbo_func, NULL, args, NULL); - } - else - { - int size = 0; - - pixels = _calcWriteSize(width, height, 1, format, type, pixels, &size); - - long args[] = { INT_TO_ARG(width), INT_TO_ARG(height), - INT_TO_ARG(format), INT_TO_ARG(type), POINTER_TO_ARG(pixels) }; - int args_size[] = { 0, 0, 0, 0, size }; - do_opengl_call(glDrawPixels_func, NULL, CHECK_ARGS(args, args_size)); - } -} - -GLAPI void APIENTRY glInterleavedArrays( GLenum format, - GLsizei stride, - const GLvoid *ptr ) -{ - CHECK_PROC(glInterleavedArrays); - GET_CURRENT_STATE(); - if (debug_array_ptr) - log_gl("glInterleavedArrays format=%d stride=%d ptr=%p\n", format, stride, ptr); - state->client_state.arrays.interleavedArrays.format = format; - state->client_state.arrays.interleavedArrays.stride = stride; - state->client_state.arrays.interleavedArrays.ptr = ptr; -} - -GLAPI void APIENTRY glVertexPointer( GLint size, - GLenum type, - GLsizei stride, - const GLvoid *ptr ) -{ - CHECK_PROC(glVertexPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.vertexArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.vertexArray.vbo_name) - { - long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glVertexPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.vertexArray.size == size && - state->client_state.arrays.vertexArray.type == type && - state->client_state.arrays.vertexArray.stride == stride && - state->client_state.arrays.vertexArray.ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("glVertexPointer size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr); - state->client_state.arrays.vertexArray.size = size; - state->client_state.arrays.vertexArray.type = type; - state->client_state.arrays.vertexArray.stride = stride; - state->client_state.arrays.vertexArray.ptr = ptr; - } -} - -DEFINE_EXT(glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr)); - -GLAPI void APIENTRY glNormalPointer( GLenum type, - GLsizei stride, - const GLvoid *ptr ) -{ - CHECK_PROC(glNormalPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.normalArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.normalArray.vbo_name) - { - long args[] = { INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glNormalPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.normalArray.type == type && - state->client_state.arrays.normalArray.stride == stride && - state->client_state.arrays.normalArray.ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("glNormalPointer type=%d stride=%d ptr=%p\n", type, stride, ptr); - state->client_state.arrays.normalArray.size = 3; - state->client_state.arrays.normalArray.type = type; - state->client_state.arrays.normalArray.stride = stride; - state->client_state.arrays.normalArray.ptr = ptr; - } -} - -DEFINE_EXT(glNormalPointer, (GLenum type, GLsizei stride, const GLvoid *ptr), (type, stride, ptr)); - -GLAPI void APIENTRY glIndexPointer( GLenum type, - GLsizei stride, - const GLvoid *ptr ) -{ - CHECK_PROC(glIndexPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.indexArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.indexArray.vbo_name) - { - long args[] = { INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glIndexPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.indexArray.type == type && - state->client_state.arrays.indexArray.stride == stride && - state->client_state.arrays.indexArray.ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("glIndexPointer type=%d stride=%d ptr=%p\n", type, stride, ptr); - state->client_state.arrays.indexArray.size = 1; - state->client_state.arrays.indexArray.type = type; - state->client_state.arrays.indexArray.stride = stride; - state->client_state.arrays.indexArray.ptr = ptr; - } -} - -DEFINE_EXT(glIndexPointer, (GLenum type, GLsizei stride, const GLvoid *ptr), (type, stride, ptr)); - -GLAPI void APIENTRY glColorPointer( GLint size, - GLenum type, - GLsizei stride, - const GLvoid *ptr ) -{ - CHECK_PROC(glColorPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.colorArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.colorArray.vbo_name) - { - long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glColorPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.colorArray.size == size && - state->client_state.arrays.colorArray.type == type && - state->client_state.arrays.colorArray.stride == stride && - state->client_state.arrays.colorArray.ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("glColorPointer size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr); - state->client_state.arrays.colorArray.size = size; - state->client_state.arrays.colorArray.type = type; - state->client_state.arrays.colorArray.stride = stride; - state->client_state.arrays.colorArray.ptr = ptr; - } -} - -DEFINE_EXT(glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr)); - -GLAPI void APIENTRY glSecondaryColorPointer( GLint size, - GLenum type, - GLsizei stride, - const GLvoid *ptr ) -{ - CHECK_PROC(glSecondaryColorPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.secondaryColorArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.secondaryColorArray.vbo_name) - { - long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glSecondaryColorPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.secondaryColorArray.size == size && - state->client_state.arrays.secondaryColorArray.type == type && - state->client_state.arrays.secondaryColorArray.stride == stride && - state->client_state.arrays.secondaryColorArray.ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("glSecondaryColorPointer size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr); - state->client_state.arrays.secondaryColorArray.size = size; - state->client_state.arrays.secondaryColorArray.type = type; - state->client_state.arrays.secondaryColorArray.stride = stride; - state->client_state.arrays.secondaryColorArray.ptr = ptr; - } -} - -DEFINE_EXT(glSecondaryColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr)); - -GLAPI void APIENTRY glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) -{ - CHECK_PROC(glTexCoordPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].vbo_name = state->arrayBuffer; - if (state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].vbo_name) - { - long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glTexCoordPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].size == size && - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].type == type && - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].stride == stride && - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("glTexCoordPointer[%d] size=%d type=%d stride=%d ptr=%p\n", - state->client_state.clientActiveTexture, size, type, stride, ptr); - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].index = - state->client_state.clientActiveTexture; - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].size = size; - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].type = type; - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].stride = stride; - state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].ptr = ptr; - } -} - -DEFINE_EXT(glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), (size, type, stride, ptr)); - -GLAPI void APIENTRY glEdgeFlagPointer( GLsizei stride, const GLvoid *ptr ) -{ - CHECK_PROC(glEdgeFlagPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.edgeFlagArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.edgeFlagArray.vbo_name) - { - long args[] = { INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glEdgeFlagPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.edgeFlagArray.stride == stride && - state->client_state.arrays.edgeFlagArray.ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("edgeFlagArray stride=%d ptr=%p\n", stride, ptr); - state->client_state.arrays.edgeFlagArray.size = 1; - state->client_state.arrays.edgeFlagArray.type = GL_BYTE; - state->client_state.arrays.edgeFlagArray.stride = stride; - state->client_state.arrays.edgeFlagArray.ptr = ptr; - } -} - -DEFINE_EXT(glEdgeFlagPointer, (GLsizei stride, const GLvoid *ptr), (stride, ptr)); - -GLAPI void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) -{ - CHECK_PROC(glFogCoordPointer); - GET_CURRENT_STATE(); - - state->client_state.arrays.fogCoordArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.fogCoordArray.vbo_name) - { - long args[] = { INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glFogCoordPointer_buffer_func, NULL, args, NULL); - return; - } - - if (state->client_state.arrays.fogCoordArray.type == type && - state->client_state.arrays.fogCoordArray.stride == stride && - state->client_state.arrays.fogCoordArray.ptr == ptr) - { - } - else - { - if (debug_array_ptr) - log_gl("glFogCoordPointer type=%d stride=%d ptr=%p\n", type, stride, ptr); - state->client_state.arrays.fogCoordArray.size = 1; - state->client_state.arrays.fogCoordArray.type = type; - state->client_state.arrays.fogCoordArray.stride = stride; - state->client_state.arrays.fogCoordArray.ptr = ptr; - } -} - -DEFINE_EXT(glFogCoordPointer, (GLenum type, GLsizei stride, const GLvoid *ptr), (type, stride, ptr)); - - -GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) -{ - CHECK_PROC(glWeightPointerARB); - GET_CURRENT_STATE(); - - state->client_state.arrays.weightArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.weightArray.vbo_name) - { - long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glWeightPointerARB_buffer_func, NULL, args, NULL); - return; - } - - log_gl("glWeightPointerARB\n"); - fflush(get_err_file()); - if (debug_array_ptr) - log_gl("weightArray size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr); - state->client_state.arrays.weightArray.size = size; - state->client_state.arrays.weightArray.type = type; - state->client_state.arrays.weightArray.stride = stride; - state->client_state.arrays.weightArray.ptr = ptr; -} - - -GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) -{ - CHECK_PROC(glMatrixIndexPointerARB); - GET_CURRENT_STATE(); - - state->client_state.arrays.matrixIndexArray.vbo_name = state->arrayBuffer; - if (state->client_state.arrays.matrixIndexArray.vbo_name) - { - long args[] = { INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glMatrixIndexPointerARB_buffer_func, NULL, args, NULL); - return; - } - - log_gl("glMatrixIndexPointerARB\n"); - fflush(get_err_file()); - if (debug_array_ptr) - log_gl("matrixIndexArray size=%d type=%d stride=%d ptr=%p\n", size, type, stride, ptr); - state->client_state.arrays.matrixIndexArray.size = size; - state->client_state.arrays.matrixIndexArray.type = type; - state->client_state.arrays.matrixIndexArray.stride = stride; - state->client_state.arrays.matrixIndexArray.ptr = ptr; -} - -#define glMatrixIndexvARB(name, type) \ - GLAPI void APIENTRY name (GLint size, const type *indices) \ -{ \ - CHECK_PROC(name); \ - long args[] = { INT_TO_ARG(size), POINTER_TO_ARG(indices) }; \ - int args_size[] = { 0, size * sizeof(type) }; \ - do_opengl_call(CONCAT(name, _func), NULL, CHECK_ARGS(args, args_size)); \ -} - -glMatrixIndexvARB(glMatrixIndexubvARB, GLubyte); -glMatrixIndexvARB(glMatrixIndexusvARB, GLushort); -glMatrixIndexvARB(glMatrixIndexuivARB, GLuint); - - -GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight) -{ - log_gl("glVertexWeightfEXT : deprecated API. unimplemented\n"); -} - -GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight) -{ - log_gl("glVertexWeightfvEXT : deprecated API. unimplemented\n"); -} - -GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer) -{ - log_gl("glVertexWeightPointerEXT : deprecated API. unimplemented\n"); -} - - - -GLAPI void APIENTRY EXT_FUNC(glVertexAttribPointerARB)(GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *ptr) -{ - CHECK_PROC(glVertexAttribPointerARB); - - GET_CURRENT_STATE(); - if (index < MY_GL_MAX_VERTEX_ATTRIBS_ARB) - { - state->client_state.arrays.vertexAttribArray[index].vbo_name = state->arrayBuffer; - if (state->client_state.arrays.vertexAttribArray[index].vbo_name) - { - long args[] = { INT_TO_ARG(index), INT_TO_ARG(size), INT_TO_ARG(type), INT_TO_ARG(normalized), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glVertexAttribPointerARB_buffer_func, NULL, args, NULL); - return; - } - - if (debug_array_ptr) - log_gl("glVertexAttribPointerARB[%d] size=%d type=%d normalized=%d stride=%d ptr=%p\n", - index, size, type, normalized, stride, ptr); - state->client_state.arrays.vertexAttribArray[index].index = index; - state->client_state.arrays.vertexAttribArray[index].size = size; - state->client_state.arrays.vertexAttribArray[index].type = type; - state->client_state.arrays.vertexAttribArray[index].normalized = normalized; - state->client_state.arrays.vertexAttribArray[index].stride = stride; - state->client_state.arrays.vertexAttribArray[index].ptr = ptr; - } - else - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB\n"); - } -} - -GLAPI void APIENTRY EXT_FUNC(glVertexAttribPointer)(GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *ptr) -{ - glVertexAttribPointerARB(index, size, type, normalized, stride, ptr); -} - -GLAPI void APIENTRY EXT_FUNC(glVertexAttribPointerNV)(GLuint index, - GLint size, - GLenum type, - GLsizei stride, - const GLvoid *ptr) -{ - CHECK_PROC(glVertexAttribPointerNV); - - GET_CURRENT_STATE(); - if (index < MY_GL_MAX_VERTEX_ATTRIBS_NV) - { - if (debug_array_ptr) - log_gl("glVertexAttribPointerNV[%d] size=%d type=%d stride=%d ptr=%p\n", - index, size, type, stride, ptr); - state->client_state.arrays.vertexAttribArrayNV[index].index = index; - state->client_state.arrays.vertexAttribArrayNV[index].size = size; - state->client_state.arrays.vertexAttribArrayNV[index].type = type; - state->client_state.arrays.vertexAttribArrayNV[index].stride = stride; - state->client_state.arrays.vertexAttribArrayNV[index].ptr = ptr; - } - else - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_NV\n"); - } -} - -GLAPI void APIENTRY EXT_FUNC(glElementPointerATI) (GLenum type, const GLvoid * ptr) -{ - CHECK_PROC(glElementPointerATI); - GET_CURRENT_STATE(); - state->client_state.arrays.elementArrayATI.size = 1; - state->client_state.arrays.elementArrayATI.type = type; - state->client_state.arrays.elementArrayATI.stride = 0; - state->client_state.arrays.elementArrayATI.ptr = ptr; -} - -GLAPI void APIENTRY glGetPointerv( GLenum pname, void **params ) -{ - GET_CURRENT_STATE(); - switch (pname) - { - case GL_COLOR_ARRAY_POINTER: *params = (void*)state->client_state.arrays.colorArray.ptr; break; - case GL_SECONDARY_COLOR_ARRAY_POINTER: *params = (void*)state->client_state.arrays.secondaryColorArray.ptr; break; - case GL_NORMAL_ARRAY_POINTER: *params = (void*)state->client_state.arrays.normalArray.ptr; break; - case GL_INDEX_ARRAY_POINTER: *params = (void*)state->client_state.arrays.indexArray.ptr; break; - case GL_TEXTURE_COORD_ARRAY_POINTER: *params = (void*)state->client_state.arrays.texCoordArray[state->client_state.clientActiveTexture].ptr; break; - case GL_VERTEX_ARRAY_POINTER: *params = (void*)state->client_state.arrays.vertexArray.ptr; break; - case GL_EDGE_FLAG_ARRAY_POINTER: *params = (void*)state->client_state.arrays.edgeFlagArray.ptr; break; - case GL_WEIGHT_ARRAY_POINTER_ARB: *params = (void*)state->client_state.arrays.weightArray.ptr; break; - case GL_MATRIX_INDEX_ARRAY_POINTER_ARB: *params = (void*)state->client_state.arrays.matrixIndexArray.ptr; break; - case GL_FOG_COORD_ARRAY_POINTER: *params = (void*)state->client_state.arrays.fogCoordArray.ptr; break; - case GL_ELEMENT_ARRAY_POINTER_ATI: *params = (void*)state->client_state.arrays.elementArrayATI.ptr; break; - case GL_SELECTION_BUFFER_POINTER: *params = (void*)state->client_state.selectBufferPtr; break; - case GL_FEEDBACK_BUFFER_POINTER: *params = (void*)state->client_state.feedbackBufferPtr; break; - default: - { - log_gl("not yet handled pname %d\n", pname); - *params = NULL; - } - } -} - -GLAPI void APIENTRY glGetPointervEXT( GLenum pname, void **params ) -{ - glGetPointerv(pname, params); -} - -GLAPI void APIENTRY EXT_FUNC(glGetVertexAttribPointervARB)(GLuint index, - GLenum pname, - GLvoid **pointer) -{ - GET_CURRENT_STATE(); - - if (index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB) - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB\n"); - return; - } - - switch (pname) - { - case GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB: - { - *pointer = (void*)state->client_state.arrays.vertexAttribArray[index].ptr; - break; - } - default: - log_gl("glGetVertexAttribPointervARB : bad pname=0x%X", pname); - break; - } -} - -GLAPI void APIENTRY EXT_FUNC(glGetVertexAttribPointerv)(GLuint index, - GLenum pname, - GLvoid **pointer) -{ - glGetVertexAttribPointervARB(index, pname, pointer); -} - -GLAPI void APIENTRY EXT_FUNC(_glGetVertexAttribiv)(int func_number, GLuint index, GLenum pname, GLint *params) -{ - if (index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB) - { - log_gl("%s: index >= MY_GL_MAX_VERTEX_ATTRIBS_ARB\n", tab_opengl_calls_name[func_number]); - return; - } - - GET_CURRENT_STATE(); - switch (pname) - { - case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: - *params = state->client_state.arrays.vertexAttribArray[index].enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: - *params = state->client_state.arrays.vertexAttribArray[index].size; - break; - case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: - *params = state->client_state.arrays.vertexAttribArray[index].stride; - break; - case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: - *params = state->client_state.arrays.vertexAttribArray[index].type; - break; - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: - *params = state->client_state.arrays.vertexAttribArray[index].normalized; - break; - case GL_CURRENT_VERTEX_ATTRIB_ARB: - *params = state->client_state.arrays.vertexAttribArray[index].vbo_name; - break; - default: - log_gl("%s : bad pname=0x%X", tab_opengl_calls_name[func_number], pname); - break; - } -} - -#define DEFINE_glGetVertexAttribv(funcName, type) \ - GLAPI void APIENTRY EXT_FUNC(funcName)(GLuint index, GLenum pname, type *params) \ -{ \ - CHECK_PROC(funcName); \ - if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) \ - { \ - long args[] = { UNSIGNED_INT_TO_ARG(index), UNSIGNED_INT_TO_ARG(pname), POINTER_TO_ARG(params)}; \ - do_opengl_call(CONCAT(funcName,_func), NULL, args, NULL); \ - return; \ - } \ - int i_params; \ - _glGetVertexAttribiv(CONCAT(funcName,_func), index, pname, &i_params); \ - *params = i_params; \ -} - -DEFINE_glGetVertexAttribv(glGetVertexAttribivARB, GLint); -DEFINE_glGetVertexAttribv(glGetVertexAttribiv, GLint); -DEFINE_glGetVertexAttribv(glGetVertexAttribfvARB, GLfloat); -DEFINE_glGetVertexAttribv(glGetVertexAttribfv, GLfloat); -DEFINE_glGetVertexAttribv(glGetVertexAttribdvARB, GLdouble); -DEFINE_glGetVertexAttribv(glGetVertexAttribdv, GLdouble); - - -GLAPI void APIENTRY EXT_FUNC(glGetVertexAttribPointervNV)(GLuint index, - GLenum pname, - GLvoid **pointer) -{ - CHECK_PROC(glGetVertexAttribPointervNV); - GET_CURRENT_STATE(); - if (index >= MY_GL_MAX_VERTEX_ATTRIBS_NV) - { - log_gl("index >= MY_GL_MAX_VERTEX_ATTRIBS_NV\n"); - return; - } - switch (pname) - { - case GL_ATTRIB_ARRAY_POINTER_NV: - { - *pointer = (void*)state->client_state.arrays.vertexAttribArrayNV[index].ptr; - break; - } - default: - log_gl("glGetVertexAttribPointervNV : bad pname=0x%X", pname); - break; - } -} - -static int getGlTypeByteSize(int type) -{ - switch(type) - { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return 1; - break; - - case GL_SHORT: - case GL_UNSIGNED_SHORT: - return 2; - break; - - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - return 4; - break; - - case GL_DOUBLE: - return 8; - break; - - default: - log_gl("unsupported type = %d\n", type); - return 0; - } -} - -static int getMulFactorFromPointerArray(ClientArray* array) -{ - if (array->stride) - return array->stride; - - return getGlTypeByteSize(array->type) * array->size; -} - -static void _glArraySend(GLState* state, const char* func_name, int func, ClientArray* array, int first, int last) -{ - if (array->ptr == NULL || array->vbo_name || array->enabled == 0) return; - int offset = first * getMulFactorFromPointerArray(array); - int size = (last - first + 1) * getMulFactorFromPointerArray(array); - if (size == 0) return; - -#if 0 - unsigned int crc = calc_checksum(array->ptr + offset, size, 0xFFFFFFFF); - crc = calc_checksum(&offset, sizeof(int), crc); - crc = calc_checksum(&size, sizeof(int), crc); - crc = calc_checksum(&array->size, sizeof(int), crc); - crc = calc_checksum(&array->type, sizeof(int), crc); - - if (crc == 0) - { - /*int i; - unsigned char* ptr = (unsigned char*)(array->ptr + offset); - for(i=0;ilast_crc) - { - if (debug_array_ptr) - { - log_gl("%s : same crc. Saving %d bytes\n", func_name, size); - } - return; - } - - array->last_crc = crc; -#endif - - if (debug_array_ptr) - { - unsigned int crc = calc_checksum(array->ptr + offset, size, 0xFFFFFFFF); - crc = calc_checksum(&offset, sizeof(int), crc); - crc = calc_checksum(&size, sizeof(int), crc); - crc = calc_checksum(&array->size, sizeof(int), crc); - crc = calc_checksum(&array->type, sizeof(int), crc); - - log_gl("%s sending %d bytes from %d : crc = %d\n", func_name, size, offset, crc); - } - - int currentArrayBuffer = state->arrayBuffer; - if (currentArrayBuffer) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - } - - switch(func) - { - case glEdgeFlagPointer_fake_func: - { - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(array->stride), - INT_TO_ARG(size), - POINTER_TO_ARG(array->ptr + offset) }; - int args_size[] = { 0, 0, 0, size}; - do_opengl_call(func, NULL, CHECK_ARGS(args, args_size)); - break; - } - - case glNormalPointer_fake_func: - case glIndexPointer_fake_func: - case glFogCoordPointer_fake_func: - { - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(array->type), - INT_TO_ARG(array->stride), - INT_TO_ARG(size), - POINTER_TO_ARG(array->ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, size}; - do_opengl_call(func, NULL, CHECK_ARGS(args, args_size)); - break; - } - - case glVertexPointer_fake_func: - case glColorPointer_fake_func: - case glSecondaryColorPointer_fake_func: - case glWeightPointerARB_fake_func: - case glMatrixIndexPointerARB_fake_func: - { - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(array->size), - INT_TO_ARG(array->type), - INT_TO_ARG(array->stride), - INT_TO_ARG(size), - POINTER_TO_ARG(array->ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, size}; - do_opengl_call(func, NULL, CHECK_ARGS(args, args_size)); - break; - } - - case glTexCoordPointer_fake_func: - case glVertexAttribPointerNV_fake_func: - { - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(array->index), - INT_TO_ARG(array->size), - INT_TO_ARG(array->type), - INT_TO_ARG(array->stride), - INT_TO_ARG(size), - POINTER_TO_ARG(array->ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, size}; - do_opengl_call(func, NULL, CHECK_ARGS(args, args_size)); - break; - } - - case glVertexAttribPointerARB_fake_func: - { - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(array->index), - INT_TO_ARG(array->size), - INT_TO_ARG(array->type), - INT_TO_ARG(array->normalized), - INT_TO_ARG(array->stride), - INT_TO_ARG(size), - POINTER_TO_ARG(array->ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, size}; - do_opengl_call(func, NULL, CHECK_ARGS(args, args_size)); - break; - } - - case glVariantPointerEXT_fake_func: - { - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(array->index), - INT_TO_ARG(array->type), - INT_TO_ARG(array->stride), - INT_TO_ARG(size), - POINTER_TO_ARG(array->ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, size}; - do_opengl_call(func, NULL, CHECK_ARGS(args, args_size)); - break; - } - - default: - log_gl("shoudln't reach that point\n"); - break; - } - - if (currentArrayBuffer) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, currentArrayBuffer); - } -} - - -#define ARRAY_SEND_FUNC(x) #x, CONCAT(x,_fake_func) - -static int _calc_interleaved_arrays_stride(GLenum format) -{ - switch(format) - { - case GL_V2F: return 2 * sizeof(float); break; - case GL_V3F: return 3 * sizeof(float); break; - case GL_C4UB_V2F: return 4 * sizeof(char) + 2 * sizeof(float); break; - case GL_C4UB_V3F: return 4 * sizeof(char) + 3 * sizeof(float); break; - case GL_C3F_V3F: return 3 * sizeof(float) + 3 * sizeof(float); break; - case GL_N3F_V3F: return 3 * sizeof(float) + 3 * sizeof(float); break; - case GL_C4F_N3F_V3F: return 4 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break; - case GL_T2F_V3F: return 2 * sizeof(float) + 3 * sizeof(float); break; - case GL_T4F_V4F: return 4 * sizeof(float) + 4 * sizeof(float); break; - case GL_T2F_C4UB_V3F: return 2 * sizeof(float) + 4 * sizeof(char) + 3 * sizeof(float); break; - case GL_T2F_C3F_V3F: return 2 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break; - case GL_T2F_N3F_V3F: return 2 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break; - case GL_T2F_C4F_N3F_V3F: return 2 * sizeof(float) + 4 * sizeof(float) + 3 * sizeof(float) + 3 * sizeof(float); break; - case GL_T4F_C4F_N3F_V4F: return 4 * sizeof(float) + 4 * sizeof(float) + 3 * sizeof(float) + 4 * sizeof(float); break; - default: log_gl("unknown interleaved array format : %d\n", format); return 0; - } -} - - -enum -{ - TEXCOORD_FUNC, - COLOR_FUNC, - NORMAL_FUNC, - INDEX_FUNC, - VERTEX_FUNC -}; - -typedef void (*vector_func_type)(const void*); - -typedef struct -{ - int type; - int size; - int typeFunc; - vector_func_type vector_func; -} VectorFuncStruct; - -VectorFuncStruct vectorFuncArray[] = -{ - { GL_DOUBLE, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1dv }, - { GL_DOUBLE, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2dv }, - { GL_DOUBLE, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3dv }, - { GL_DOUBLE, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4dv }, - { GL_FLOAT, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1fv }, - { GL_FLOAT, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2fv }, - { GL_FLOAT, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3fv }, - { GL_FLOAT, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4fv }, - { GL_INT, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1iv }, - { GL_INT, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2iv }, - { GL_INT, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3iv }, - { GL_INT, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4iv }, - { GL_SHORT, 1, TEXCOORD_FUNC, (vector_func_type)glTexCoord1sv }, - { GL_SHORT, 2, TEXCOORD_FUNC, (vector_func_type)glTexCoord2sv }, - { GL_SHORT, 3, TEXCOORD_FUNC, (vector_func_type)glTexCoord3sv }, - { GL_SHORT, 4, TEXCOORD_FUNC, (vector_func_type)glTexCoord4sv }, - - { GL_BYTE, 3, COLOR_FUNC, (vector_func_type)glColor3bv }, - { GL_DOUBLE, 3, COLOR_FUNC, (vector_func_type)glColor3dv }, - { GL_FLOAT, 3, COLOR_FUNC, (vector_func_type)glColor3fv }, - { GL_INT, 3, COLOR_FUNC, (vector_func_type)glColor3iv }, - { GL_SHORT, 3, COLOR_FUNC, (vector_func_type)glColor3sv }, - { GL_UNSIGNED_BYTE, 3, COLOR_FUNC, (vector_func_type)glColor3ubv }, - { GL_UNSIGNED_INT, 3, COLOR_FUNC, (vector_func_type)glColor3uiv }, - { GL_UNSIGNED_SHORT, 3, COLOR_FUNC, (vector_func_type)glColor3usv }, - { GL_BYTE, 4, COLOR_FUNC, (vector_func_type)glColor4bv }, - { GL_DOUBLE, 4, COLOR_FUNC, (vector_func_type)glColor4dv }, - { GL_FLOAT, 4, COLOR_FUNC, (vector_func_type)glColor4fv }, - { GL_INT, 4, COLOR_FUNC, (vector_func_type)glColor4iv }, - { GL_SHORT, 4, COLOR_FUNC, (vector_func_type)glColor4sv }, - { GL_UNSIGNED_BYTE, 4, COLOR_FUNC, (vector_func_type)glColor4ubv }, - { GL_UNSIGNED_INT, 4, COLOR_FUNC, (vector_func_type)glColor4uiv }, - { GL_UNSIGNED_SHORT, 4, COLOR_FUNC, (vector_func_type)glColor4usv }, - - { GL_BYTE, 3, NORMAL_FUNC, (vector_func_type)glNormal3bv }, - { GL_DOUBLE, 3, NORMAL_FUNC, (vector_func_type)glNormal3dv }, - { GL_FLOAT, 3, NORMAL_FUNC, (vector_func_type)glNormal3fv }, - { GL_INT, 3, NORMAL_FUNC, (vector_func_type)glNormal3iv }, - { GL_SHORT, 3, NORMAL_FUNC, (vector_func_type)glNormal3sv }, - - { GL_DOUBLE, 1, INDEX_FUNC, (vector_func_type)glIndexdv }, - { GL_FLOAT, 1, INDEX_FUNC, (vector_func_type)glIndexfv }, - { GL_INT, 1, INDEX_FUNC, (vector_func_type)glIndexiv }, - { GL_SHORT, 1, INDEX_FUNC, (vector_func_type)glIndexsv }, - { GL_UNSIGNED_BYTE, 1, INDEX_FUNC, (vector_func_type)glIndexubv }, - - { GL_DOUBLE, 2, VERTEX_FUNC, (vector_func_type)glVertex2dv }, - { GL_FLOAT, 2, VERTEX_FUNC, (vector_func_type)glVertex2fv }, - { GL_INT, 2, VERTEX_FUNC, (vector_func_type)glVertex2iv }, - { GL_SHORT, 2, VERTEX_FUNC, (vector_func_type)glVertex2sv }, - { GL_DOUBLE, 3, VERTEX_FUNC, (vector_func_type)glVertex3dv }, - { GL_FLOAT, 3, VERTEX_FUNC, (vector_func_type)glVertex3fv }, - { GL_INT, 3, VERTEX_FUNC, (vector_func_type)glVertex3iv }, - { GL_SHORT, 4, VERTEX_FUNC, (vector_func_type)glVertex4sv }, - { GL_DOUBLE, 4, VERTEX_FUNC, (vector_func_type)glVertex4dv }, - { GL_FLOAT, 4, VERTEX_FUNC, (vector_func_type)glVertex4fv }, - { GL_INT, 4, VERTEX_FUNC, (vector_func_type)glVertex4iv }, - { GL_SHORT, 4, VERTEX_FUNC, (vector_func_type)glVertex4sv }, -}; - -static vector_func_type _get_vector_func(int type, int size, int typeFunc) -{ - int i; - for(i=0;ienabled) - { - vector_func_type vector_func = - _get_vector_func(array->type, array->size, typeFunc); - if (vector_func) - { - vector_func(array->ptr + getMulFactorFromPointerArray(array) * indice); - } - } -} - -static void _glElementArrayImmediate(int indice) -{ - GET_CURRENT_STATE(); - - if (state->client_state.arrays.interleavedArrays.ptr != NULL && - state->client_state.arrays.vertexArray.ptr == NULL) - { - GLboolean tflag, cflag, nflag; /* enable/disable flags */ - GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ - GLenum ctype = 0; /* color type */ - GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ - const GLint toffset = 0; /* always zero */ - GLint defstride; /* default stride */ - GLint c, f; - - int stride = state->client_state.arrays.interleavedArrays.stride; - - f = sizeof(GLfloat); - c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); - - switch (state->client_state.arrays.interleavedArrays.format) { - case GL_V2F: - tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; - tcomps = 0; ccomps = 0; vcomps = 2; - voffset = 0; - defstride = 2*f; - break; - case GL_V3F: - tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; - tcomps = 0; ccomps = 0; vcomps = 3; - voffset = 0; - defstride = 3*f; - break; - case GL_C4UB_V2F: - tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; - tcomps = 0; ccomps = 4; vcomps = 2; - ctype = GL_UNSIGNED_BYTE; - coffset = 0; - voffset = c; - defstride = c + 2*f; - break; - case GL_C4UB_V3F: - tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; - tcomps = 0; ccomps = 4; vcomps = 3; - ctype = GL_UNSIGNED_BYTE; - coffset = 0; - voffset = c; - defstride = c + 3*f; - break; - case GL_C3F_V3F: - tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; - tcomps = 0; ccomps = 3; vcomps = 3; - ctype = GL_FLOAT; - coffset = 0; - voffset = 3*f; - defstride = 6*f; - break; - case GL_N3F_V3F: - tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; - tcomps = 0; ccomps = 0; vcomps = 3; - noffset = 0; - voffset = 3*f; - defstride = 6*f; - break; - case GL_C4F_N3F_V3F: - tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; - tcomps = 0; ccomps = 4; vcomps = 3; - ctype = GL_FLOAT; - coffset = 0; - noffset = 4*f; - voffset = 7*f; - defstride = 10*f; - break; - case GL_T2F_V3F: - tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; - tcomps = 2; ccomps = 0; vcomps = 3; - voffset = 2*f; - defstride = 5*f; - break; - case GL_T4F_V4F: - tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; - tcomps = 4; ccomps = 0; vcomps = 4; - voffset = 4*f; - defstride = 8*f; - break; - case GL_T2F_C4UB_V3F: - tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; - tcomps = 2; ccomps = 4; vcomps = 3; - ctype = GL_UNSIGNED_BYTE; - coffset = 2*f; - voffset = c+2*f; - defstride = c+5*f; - break; - case GL_T2F_C3F_V3F: - tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; - tcomps = 2; ccomps = 3; vcomps = 3; - ctype = GL_FLOAT; - coffset = 2*f; - voffset = 5*f; - defstride = 8*f; - break; - case GL_T2F_N3F_V3F: - tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; - tcomps = 2; ccomps = 0; vcomps = 3; - noffset = 2*f; - voffset = 5*f; - defstride = 8*f; - break; - case GL_T2F_C4F_N3F_V3F: - tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; - tcomps = 2; ccomps = 4; vcomps = 3; - ctype = GL_FLOAT; - coffset = 2*f; - noffset = 6*f; - voffset = 9*f; - defstride = 12*f; - break; - case GL_T4F_C4F_N3F_V4F: - tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; - tcomps = 4; ccomps = 4; vcomps = 4; - ctype = GL_FLOAT; - coffset = 4*f; - noffset = 8*f; - voffset = 11*f; - defstride = 15*f; - break; - default: - log_gl("unknown interleaved array format : %d\n", state->client_state.arrays.interleavedArrays.format); - return; - } - - if (stride==0) { - stride = defstride; - } - - const void* ptr = state->client_state.arrays.interleavedArrays.ptr + indice * stride; - - if (tflag) - { - if (tcomps == 2) - glTexCoord2fv(ptr + toffset); - else if (tcomps == 4) - glTexCoord4fv(ptr + toffset); - else - assert(0); - } - - if (cflag) - { - if (ctype == GL_FLOAT) - { - if (ccomps == 3) - glColor3fv(ptr + coffset); - else if (ccomps == 4) - glColor4fv(ptr + coffset); - else - assert(0); - } - else if (ctype == GL_UNSIGNED_BYTE) - { - if (ccomps == 4) - glColor4ubv(ptr + coffset); - else - assert(0); - } - else - assert(0); - } - - if (nflag) - glNormal3fv(ptr + noffset); - - if (vcomps == 2) - glVertex2fv(ptr + voffset); - else if (vcomps == 3) - glVertex3fv(ptr + voffset); - else if (vcomps == 4) - glVertex4fv(ptr + voffset); - else - assert(0); - - return; - } - - int i; - - int prevActiveTexture = state->activeTexture; - for(i=0;iclient_state.arrays.texCoordArray[i].enabled) - { - if (i != 0 || state->activeTexture != GL_TEXTURE0_ARB) - glActiveTextureARB(GL_TEXTURE0_ARB + i); - _glElementArrayImmediate_one(&state->client_state.arrays.texCoordArray[i], indice, TEXCOORD_FUNC); - } - } - glActiveTextureARB(prevActiveTexture); - - _glElementArrayImmediate_one(&state->client_state.arrays.normalArray, indice, NORMAL_FUNC); - _glElementArrayImmediate_one(&state->client_state.arrays.colorArray, indice, COLOR_FUNC); - _glElementArrayImmediate_one(&state->client_state.arrays.indexArray, indice, INDEX_FUNC); - _glElementArrayImmediate_one(&state->client_state.arrays.vertexArray, indice, VERTEX_FUNC); -} - -static void _glArraysSend(int first, int last) -{ - GET_CURRENT_STATE(); - if (debug_array_ptr) - { - log_gl("_glArraysSend from %d to %d\n", first, last); - } - - - int startIndiceTextureToDealtWith = 0; - int i; - int nbElts = 1 + last; - - if (_glIsEnabled(GL_VERTEX_PROGRAM_NV)) - { - int vertexProgramNV = 0; - for(i=0;iclient_state.arrays.vertexAttribArrayNV[i]; - if (!(array->ptr == NULL || array->enabled == 0)) - { - _glArraySend(state, ARRAY_SEND_FUNC(glVertexAttribPointerNV), array, first, last); - vertexProgramNV = 1; - } - } - if (vertexProgramNV) - return; - } - - if (state->client_state.arrays.interleavedArrays.ptr != NULL && - state->client_state.arrays.vertexArray.ptr == NULL) - { - int stride; - if (state->client_state.arrays.interleavedArrays.stride) - stride = state->client_state.arrays.interleavedArrays.stride; - else - stride = _calc_interleaved_arrays_stride(state->client_state.arrays.interleavedArrays.format); - if (stride == 0) return; - int offset = stride * first; - int size = (last - first + 1) * stride; - long args[] = { offset, - state->client_state.arrays.interleavedArrays.format, - state->client_state.arrays.interleavedArrays.stride, - size, - POINTER_TO_ARG(state->client_state.arrays.interleavedArrays.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, size }; - do_opengl_call(glInterleavedArrays_fake_func, NULL, CHECK_ARGS(args, args_size)); - return; - } - - int normalArrayOffset = (long)state->client_state.arrays.normalArray.ptr - - (long)state->client_state.arrays.vertexArray.ptr; - int colorArrayOffset = (long)state->client_state.arrays.colorArray.ptr - - (long)state->client_state.arrays.vertexArray.ptr; - int texCoord0PointerOffset = (long)state->client_state.arrays.texCoordArray[0].ptr - - (long)state->client_state.arrays.vertexArray.ptr; - int texCoord1PointerOffset = (long)state->client_state.arrays.texCoordArray[1].ptr - - (long)state->client_state.arrays.vertexArray.ptr; - int texCoord2PointerOffset = (long)state->client_state.arrays.texCoordArray[2].ptr - - (long)state->client_state.arrays.vertexArray.ptr; - - if (state->client_state.arrays.vertexArray.vbo_name || - state->client_state.arrays.colorArray.vbo_name || - state->client_state.arrays.normalArray.vbo_name || - state->client_state.arrays.texCoordArray[0].vbo_name || - state->client_state.arrays.texCoordArray[1].vbo_name || - state->client_state.arrays.texCoordArray[2].vbo_name) - { - _glArraySend(state, ARRAY_SEND_FUNC(glVertexPointer), &state->client_state.arrays.vertexArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glNormalPointer), &state->client_state.arrays.normalArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glColorPointer), &state->client_state.arrays.colorArray, first, last); - } - else - if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled == 0 && - state->client_state.arrays.colorArray.enabled && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.colorArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride && - colorArrayOffset >= 0 && - colorArrayOffset < state->client_state.arrays.vertexArray.stride && - texCoord0PointerOffset >= 0 && - texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexColorTexCoord0PointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(colorArrayOffset), - INT_TO_ARG(state->client_state.arrays.colorArray.size), - INT_TO_ARG(state->client_state.arrays.colorArray.type), - INT_TO_ARG(texCoord0PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexColorTexCoord0PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 1; - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.colorArray.enabled && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.texCoordArray[1].enabled && - state->client_state.arrays.texCoordArray[2].enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[2].stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride && - colorArrayOffset >= 0 && - colorArrayOffset < state->client_state.arrays.vertexArray.stride && - texCoord0PointerOffset >= 0 && - texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride && - texCoord1PointerOffset >= 0 && - texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride && - texCoord2PointerOffset >= 0 && - texCoord2PointerOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 4 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalColorTexCoord012PointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(colorArrayOffset), - INT_TO_ARG(state->client_state.arrays.colorArray.size), - INT_TO_ARG(state->client_state.arrays.colorArray.type), - INT_TO_ARG(texCoord0PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(texCoord1PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type), - INT_TO_ARG(texCoord2PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[2].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[2].type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexNormalColorTexCoord012PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 3; - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.colorArray.enabled && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.texCoordArray[1].enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride && - colorArrayOffset >= 0 && - colorArrayOffset < state->client_state.arrays.vertexArray.stride && - texCoord0PointerOffset >= 0 && - texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride && - texCoord1PointerOffset >= 0 && - texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalColorTexCoord01PointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(colorArrayOffset), - INT_TO_ARG(state->client_state.arrays.colorArray.size), - INT_TO_ARG(state->client_state.arrays.colorArray.type), - INT_TO_ARG(texCoord0PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(texCoord1PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexNormalColorTexCoord01PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 2; - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.colorArray.enabled == 0 && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.texCoordArray[1].enabled && - state->client_state.arrays.texCoordArray[2].enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[2].stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride && - texCoord0PointerOffset >= 0 && - texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride && - texCoord1PointerOffset >= 0 && - texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride && - texCoord2PointerOffset >= 0 && - texCoord2PointerOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalTexCoord012PointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(texCoord0PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(texCoord1PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type), - INT_TO_ARG(texCoord2PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[2].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[2].type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexNormalTexCoord012PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 3; - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.colorArray.enabled == 0 && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.texCoordArray[1].enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[1].stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride && - texCoord0PointerOffset >= 0 && - texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride && - texCoord1PointerOffset >= 0 && - texCoord1PointerOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalTexCoord01PointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(texCoord0PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(texCoord1PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[1].type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexNormalTexCoord01PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 2; - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.colorArray.enabled == 0 && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride && - texCoord0PointerOffset >= 0 && - texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalTexCoord0PointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(texCoord0PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexNormalTexCoord0PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 1; - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.colorArray.enabled && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.colorArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.texCoordArray[0].stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride && - colorArrayOffset >= 0 && - colorArrayOffset < state->client_state.arrays.vertexArray.stride && - texCoord0PointerOffset >= 0 && - texCoord0PointerOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalColorTexCoord0PointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(colorArrayOffset), - INT_TO_ARG(state->client_state.arrays.colorArray.size), - INT_TO_ARG(state->client_state.arrays.colorArray.type), - INT_TO_ARG(texCoord0PointerOffset), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexNormalColorTexCoord0PointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 1; - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - getMulFactorFromPointerArray(&state->client_state.arrays.vertexArray) == - getMulFactorFromPointerArray(&state->client_state.arrays.normalArray) && - state->client_state.arrays.vertexArray.ptr == state->client_state.arrays.normalArray.ptr) - { - /* Special optimization for earth3d */ - int data_size = nbElts * getMulFactorFromPointerArray(&state->client_state.arrays.vertexArray); - - if (debug_array_ptr) - { - log_gl("glVertexAndNormalPointer_fake_func sending %d bytes from %d\n", - data_size, - 0); - } - - long args[] = { INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(state->client_state.arrays.normalArray.stride), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, data_size }; - do_opengl_call(glVertexAndNormalPointer_fake_func, NULL, CHECK_ARGS(args, args_size)); - } - - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - /*state->client_state.arrays.colorArray.enabled && */ - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.colorArray.stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride && - colorArrayOffset >= 0 && - colorArrayOffset < state->client_state.arrays.vertexArray.stride) - { - /* Special optimization for tuxracer */ - /* - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer( 3, GL_FLOAT, STRIDE_GL_ARRAY, vnc_array ); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer( GL_FLOAT, STRIDE_GL_ARRAY, - vnc_array + 4*sizeof(GLfloat) ); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer( 4, GL_UNSIGNED_BYTE, STRIDE_GL_ARRAY, - vnc_array + 8*sizeof(GLfloat) ); - */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalColorPointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(colorArrayOffset), - INT_TO_ARG(state->client_state.arrays.colorArray.size), - INT_TO_ARG(state->client_state.arrays.colorArray.type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - data_size}; - do_opengl_call(glVertexNormalColorPointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - } - else if (state->client_state.arrays.vertexArray.enabled && - state->client_state.arrays.normalArray.enabled && - state->client_state.arrays.vertexArray.ptr != NULL && - state->client_state.arrays.vertexArray.stride != 0 && - state->client_state.arrays.vertexArray.stride == state->client_state.arrays.normalArray.stride && - normalArrayOffset >= 0 && - normalArrayOffset < state->client_state.arrays.vertexArray.stride) - { - /* For unreal tournament 3 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int offset = first * state->client_state.arrays.vertexArray.stride; - int data_size = (last - first + 1) * state->client_state.arrays.vertexArray.stride; - - if (debug_array_ptr) - { - log_gl("glVertexNormalPointerInterlaced_fake_func sending %d bytes from %d\n", - data_size, - offset); - } - long args[] = { INT_TO_ARG(offset), - INT_TO_ARG(state->client_state.arrays.vertexArray.size), - INT_TO_ARG(state->client_state.arrays.vertexArray.type), - INT_TO_ARG(state->client_state.arrays.vertexArray.stride), - INT_TO_ARG(normalArrayOffset), - INT_TO_ARG(state->client_state.arrays.normalArray.type), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.vertexArray.ptr + offset) }; - int args_size[] = { 0, 0, 0, 0, 0, 0, 0, data_size}; - do_opengl_call(glVertexNormalPointerInterlaced_fake_func, NULL, CHECK_ARGS(args, args_size)); - - _glArraySend(state, ARRAY_SEND_FUNC(glColorPointer), &state->client_state.arrays.colorArray, first, last); - } - else - { - _glArraySend(state, ARRAY_SEND_FUNC(glVertexPointer), &state->client_state.arrays.vertexArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glNormalPointer), &state->client_state.arrays.normalArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glColorPointer), &state->client_state.arrays.colorArray, first, last); - } - - _glArraySend(state, ARRAY_SEND_FUNC(glSecondaryColorPointer), &state->client_state.arrays.secondaryColorArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glEdgeFlagPointer), &state->client_state.arrays.edgeFlagArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glIndexPointer), &state->client_state.arrays.indexArray, first, last); - - for(i=0;iclient_state.arrays.vertexAttribArray[i], first, last); - } - for(i=0;iclient_state.arrays.variantPointer[i], first, last); - } - - if (startIndiceTextureToDealtWith == 0 && - state->client_state.arrays.texCoordArray[0].vbo_name == 0 && - state->client_state.arrays.texCoordArray[1].vbo_name == 0 && - state->client_state.arrays.texCoordArray[2].vbo_name == 0 && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.texCoordArray[1].enabled && - state->client_state.arrays.texCoordArray[2].enabled && - state->client_state.arrays.texCoordArray[0].ptr && - state->client_state.arrays.texCoordArray[0].ptr == state->client_state.arrays.texCoordArray[1].ptr && - state->client_state.arrays.texCoordArray[0].size == state->client_state.arrays.texCoordArray[1].size && - state->client_state.arrays.texCoordArray[0].type == state->client_state.arrays.texCoordArray[1].type && - state->client_state.arrays.texCoordArray[0].stride == state->client_state.arrays.texCoordArray[1].stride && - state->client_state.arrays.texCoordArray[0].ptr == state->client_state.arrays.texCoordArray[2].ptr && - state->client_state.arrays.texCoordArray[0].size == state->client_state.arrays.texCoordArray[2].size && - state->client_state.arrays.texCoordArray[0].type == state->client_state.arrays.texCoordArray[2].type && - state->client_state.arrays.texCoordArray[0].stride == state->client_state.arrays.texCoordArray[2].stride) - { - /* For unreal tournament 4 with GL_EXTENSIONS="GL_EXT_bgra GL_EXT_texture_compression_s3tc" */ - int data_size = nbElts * getMulFactorFromPointerArray(&state->client_state.arrays.texCoordArray[0]); - if (debug_array_ptr) - { - log_gl("glTexCoordPointer012_fake_func sending %d bytes from %d\n", - data_size, - 0); - } - - long args[] = { INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].stride), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.texCoordArray[0].ptr) }; - int args_size[] = { 0, 0, 0, 0, data_size }; - do_opengl_call(glTexCoordPointer012_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 3; - } - else - if (startIndiceTextureToDealtWith == 0 && - state->client_state.arrays.texCoordArray[0].vbo_name == 0 && - state->client_state.arrays.texCoordArray[1].vbo_name == 0 && - state->client_state.arrays.texCoordArray[0].enabled && - state->client_state.arrays.texCoordArray[1].enabled && - state->client_state.arrays.texCoordArray[0].ptr && - state->client_state.arrays.texCoordArray[0].ptr == state->client_state.arrays.texCoordArray[1].ptr && - state->client_state.arrays.texCoordArray[0].size == state->client_state.arrays.texCoordArray[1].size && - state->client_state.arrays.texCoordArray[0].type == state->client_state.arrays.texCoordArray[1].type && - state->client_state.arrays.texCoordArray[0].stride == state->client_state.arrays.texCoordArray[1].stride) - { - /* Special optimization for earth3d */ - int data_size = nbElts * getMulFactorFromPointerArray(&state->client_state.arrays.texCoordArray[0]); - if (debug_array_ptr) - { - log_gl("glTexCoordPointer01_fake_func sending %d bytes from %d\n", - data_size, - 0); - } - - long args[] = { INT_TO_ARG(state->client_state.arrays.texCoordArray[0].size), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].type), - INT_TO_ARG(state->client_state.arrays.texCoordArray[0].stride), - INT_TO_ARG(data_size), - POINTER_TO_ARG(state->client_state.arrays.texCoordArray[0].ptr) }; - int args_size[] = { 0, 0, 0, 0, data_size }; - do_opengl_call(glTexCoordPointer01_fake_func, NULL, CHECK_ARGS(args, args_size)); - - startIndiceTextureToDealtWith = 2; - } - - for(i=startIndiceTextureToDealtWith;iclient_state.arrays.texCoordArray[i], first, last); - } - - _glArraySend(state, ARRAY_SEND_FUNC(glWeightPointerARB), &state->client_state.arrays.weightArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glMatrixIndexPointerARB), &state->client_state.arrays.matrixIndexArray, first, last); - _glArraySend(state, ARRAY_SEND_FUNC(glFogCoordPointer), &state->client_state.arrays.fogCoordArray, first, last); -} - -#define ASSERT_COND(cond, val) do { if (!(val)) { state->lastGlError = val; return; } } while(0) -#define CLEAR_ERROR_STATE() do { state->lastGlError = 0; } while(0) - - -GLAPI void APIENTRY EXT_FUNC(glLockArraysEXT) (GLint first, GLsizei count) -{ - /* Quite difficult to be correctly implemented IMHO for a doubtful performance gain */ - /* You need to send data for enabled arrays at this moment, but then for */ - /* the glDrawArrays, glDrawElements, etc... you need to check if enough data has been sent */ - /* For ex consider the following code : - glVertexPointer(.....); - glColorPointer(......); - glNormalPointer(.....); - glEnableClientState(GL_VERTEX_ARRAY); - glLockArraysEXT(0, 16); (1) - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glDrawArrays(GL_TRIANGLE, 0, 20); (2) - glUnlockArraysEXT(); - */ - /* At (1), you need to send 16 vertices, but at (2) you need to send the */ - /* 4 following ones, or either the whole 20... */ - CHECK_PROC(glLockArraysEXT); - GET_CURRENT_STATE(); - ASSERT_COND(first >= 0, GL_INVALID_VALUE); - ASSERT_COND(count > 0, GL_INVALID_VALUE); - ASSERT_COND(state->isBetweenLockArrays == 0, GL_INVALID_OPERATION); - ASSERT_COND(state->isBetweenBegin == 0, GL_INVALID_OPERATION); - - if (debug_array_ptr) - { - log_gl("glLockArraysEXT(%d,%d)\n", first, count); - } - - state->isBetweenLockArrays = 1; - - state->locked_first = first; - state->locked_count = count; - - CLEAR_ERROR_STATE(); -} - -GLAPI void APIENTRY EXT_FUNC(glUnlockArraysEXT) () -{ - CHECK_PROC(glUnlockArraysEXT); - GET_CURRENT_STATE(); - ASSERT_COND(state->isBetweenLockArrays == 1, GL_INVALID_OPERATION); - ASSERT_COND(state->isBetweenBegin == 0, GL_INVALID_OPERATION); - - if (debug_array_ptr) - { - log_gl("glUnlockArraysEXT()\n"); - } - - state->isBetweenLockArrays = 0; - - CLEAR_ERROR_STATE(); -} - -GLAPI void APIENTRY glArrayElement( GLint i ) -{ - Buffer* buffer = _get_buffer(GL_ARRAY_BUFFER_ARB); - if (buffer) - { - long args[] = { INT_TO_ARG(i) }; - do_opengl_call(glArrayElement_func, NULL, args, NULL); - } - else - { - _glElementArrayImmediate(i); - } -} - -GLAPI void APIENTRY glDrawArrays( GLenum mode, - GLint first, - GLsizei count ) -{ - if (debug_array_ptr) log_gl("glDrawArrays(%d,%d,%d)\n", mode, first, count); - - _glArraysSend(first, first + count - 1); - - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(first), INT_TO_ARG(count) }; - do_opengl_call(glDrawArrays_func, NULL, args, NULL); -} - -static int _isTuxRacer(GLState* state) -{ - int i; - ClientArrays* arrays = &state->client_state.arrays; - if (arrays->vertexArray.vbo_name || - arrays->normalArray.vbo_name || - arrays->colorArray.vbo_name || - arrays->vertexArray.enabled == 0 || - arrays->normalArray.enabled == 0) - return 0; - - int normalArrayOffset = (long)arrays->normalArray.ptr - (long)arrays->vertexArray.ptr; - int colorArrayOffset = (long)arrays->colorArray.ptr - (long)arrays->vertexArray.ptr; - - if (!(arrays->vertexArray.ptr != NULL && - arrays->vertexArray.stride != 0 && - arrays->vertexArray.stride == arrays->normalArray.stride && - arrays->vertexArray.stride == arrays->colorArray.stride && - normalArrayOffset >= 0 && - normalArrayOffset < arrays->vertexArray.stride && - colorArrayOffset >= 0 && - colorArrayOffset < arrays->vertexArray.stride)) - return 0; - - if (!(arrays->vertexArray.type == GL_FLOAT && arrays->vertexArray.size == 3 && - arrays->normalArray.type == GL_FLOAT && - arrays->colorArray.type == GL_UNSIGNED_BYTE && arrays->colorArray.size == 4)) - return 0; - - if (arrays->secondaryColorArray.enabled || - arrays->indexArray.enabled || - arrays->edgeFlagArray.enabled || - arrays->weightArray.enabled || - arrays->matrixIndexArray.enabled || - arrays->fogCoordArray.enabled) - return 0; - - for(i=0;itexCoordArray[i].enabled) - return 0; - } - for(i=0;ivertexAttribArray[i].enabled) - return 0; - } - return 1; -} - -static int _check_if_enabled_non_vbo_array() -{ - int i; - GET_CURRENT_STATE(); - ClientArrays* arrays = &state->client_state.arrays; - - if (arrays->vertexArray.vbo_name == 0 && arrays->vertexArray.enabled) - return 1; - if (arrays->normalArray.vbo_name == 0 && arrays->normalArray.enabled) - return 1; - if (arrays->colorArray.vbo_name == 0 && arrays->colorArray.enabled) - return 1; - if (arrays->secondaryColorArray.vbo_name == 0 && arrays->secondaryColorArray.enabled) - return 1; - if (arrays->indexArray.vbo_name == 0 && arrays->indexArray.enabled) - return 1; - if (arrays->edgeFlagArray.vbo_name == 0 && arrays->edgeFlagArray.enabled) - return 1; - if (arrays->weightArray.vbo_name == 0 && arrays->weightArray.enabled) - return 1; - if (arrays->matrixIndexArray.vbo_name == 0 && arrays->matrixIndexArray.enabled) - return 1; - if (arrays->fogCoordArray.vbo_name == 0 && arrays->fogCoordArray.enabled) - return 1; - for(i=0;itexCoordArray[i].vbo_name == 0 && arrays->texCoordArray[i].enabled) - return 1; - } - for(i=0;ivertexAttribArray[i].vbo_name == 0 && arrays->vertexAttribArray[i].enabled) - return 1; - } - for(i=0;ivariantPointer[i].vbo_name == 0 && arrays->variantPointer[i].enabled) - return 1; - } - - return 0; -} - -GLAPI void APIENTRY glDrawElements( GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices ) -{ - CHECK_PROC(glDrawElements); - int i; - int size = count; - //Buffer* bufferArray; - Buffer* bufferElement; - - if (debug_array_ptr) log_gl("glDrawElements(%d,%d,%d,%p)\n", mode, count, type, indices); - - if (count == 0) return; - - //bufferArray = _get_buffer(GL_ARRAY_BUFFER_ARB); - bufferElement = _get_buffer(GL_ELEMENT_ARRAY_BUFFER_ARB); - if (bufferElement) - { - if (_check_if_enabled_non_vbo_array()) - { - log_gl("sorry : unsupported : glDrawElements in EBO with a non VBO array enabled\n"); - return; - } - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) }; - do_opengl_call(_glDrawElements_buffer_func, NULL, args, NULL); - return; - } - - - int minIndice = 0; - int maxIndice = -1; - - switch(type) - { - case GL_UNSIGNED_BYTE: - { - //if (!bufferArray) - { - unsigned char* tab_indices = (unsigned char*)indices; - minIndice = tab_indices[0]; - maxIndice = tab_indices[0]; - for(i=1;i maxIndice) maxIndice = tab_indices[i]; - } - } - break; - } - - case GL_UNSIGNED_SHORT: - { - size *= 2; - //if (!bufferArray) - { - unsigned short* tab_indices = (unsigned short*)indices; - minIndice = tab_indices[0]; - maxIndice = tab_indices[0]; - for(i=1;i maxIndice) maxIndice = tab_indices[i]; - } - } - break; - } - - case GL_UNSIGNED_INT: - { - size *= 4; - //if (!bufferArray) - { - unsigned int* tab_indices = (unsigned int*)indices; - minIndice = tab_indices[0]; - maxIndice = tab_indices[0]; - for(i=1;i maxIndice) maxIndice = tab_indices[i]; - } - //log_gl("maxIndice = %d\n", maxIndice); - if (maxIndice > 100 * 1024 * 1024) - { - log_gl("too big indice : %d\n",maxIndice); - return; - } - } - break; - } - - default: - log_gl("unsupported type = %d\n", type); - return; - } - - GET_CURRENT_STATE(); - if (_isTuxRacer(state) && type == GL_UNSIGNED_INT) - { - /* Special optimization for tuxracer */ - /* - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer( 3, GL_FLOAT, STRIDE_GL_ARRAY, vnc_array ); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer( GL_FLOAT, STRIDE_GL_ARRAY, - vnc_array + 4*sizeof(GLfloat) ); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer( 4, GL_UNSIGNED_BYTE, STRIDE_GL_ARRAY, - vnc_array + 8*sizeof(GLfloat) ); - */ - ClientArrays* arrays = &state->client_state.arrays; - int stride = arrays->vertexArray.stride; - int bufferSize = (maxIndice - minIndice + 1) * stride + sizeof(int) * count; - int eltSize = 6 * sizeof(float) + ((arrays->colorArray.enabled) ? 4 * sizeof(unsigned char) : 0); - int singleCommandSize = count * eltSize; - if (count < bufferSize) - { - unsigned int* tab_indices = (unsigned int*)indices; - const char* vertexArray = (const char*)arrays->vertexArray.ptr; - int normalArrayOffset = (long)arrays->normalArray.ptr - (long)arrays->vertexArray.ptr; - int colorArrayOffset = (long)arrays->colorArray.ptr - (long)arrays->vertexArray.ptr; - state->tuxRacerBuffer = realloc(state->tuxRacerBuffer, singleCommandSize); - - for(i=0;ituxRacerBuffer[i * eltSize], &vertexArray[ind * stride], 3 * sizeof(float)); - memcpy(&state->tuxRacerBuffer[i * eltSize + 3 * sizeof(float)], - &vertexArray[ind * stride + normalArrayOffset], 3 * sizeof(float)); - if (arrays->colorArray.enabled) - memcpy(&state->tuxRacerBuffer[i * eltSize + 6 * sizeof(float)], - &vertexArray[ind * stride + colorArrayOffset], 4 * sizeof(unsigned char)); - } - - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count), INT_TO_ARG(arrays->colorArray.enabled), POINTER_TO_ARG(state->tuxRacerBuffer) }; - int args_size[] = { 0, 0, 0, singleCommandSize} ; - do_opengl_call(glTuxRacerDrawElements_fake_func, NULL, CHECK_ARGS(args, args_size)); - return; - } - } - _glArraysSend(minIndice, maxIndice); - - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) }; - int args_size[] = { 0, 0, 0, (indices) ? size : 0 } ; - do_opengl_call(glDrawElements_func, NULL, CHECK_ARGS(args, args_size)); -} - - -GLAPI void APIENTRY glDrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices ) -{ - CHECK_PROC(glDrawRangeElements); - int size = count; - Buffer* bufferElement; - - if (debug_array_ptr) log_gl("glDrawRangeElements(0x%X, %d, %d, %d, %d, %p)\n", mode, start, end, count, type, indices); - - if (count == 0) return; - - /* Yes : try to send regular arrays even if GL_ELEMENT_ARRAY_BUFFER_ARB is enabled. - This is necessary for nexuiz 2.3 where in GL_ELEMENT_ARRAY_BUFFER_ARB some arrays are regular array pointers, - and some others are stored in VBO... */ - _glArraysSend(start, end); - - bufferElement = _get_buffer(GL_ELEMENT_ARRAY_BUFFER_ARB); - if (bufferElement) - { - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(start), INT_TO_ARG(end), INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) }; - do_opengl_call(_glDrawRangeElements_buffer_func, NULL, args, NULL); - return; - } -#if 0 - int i; - switch(type) - { - case GL_UNSIGNED_BYTE: - { - unsigned char* tab_indices = (unsigned char*)indices; - for(i=0;i end) - { - log_gl("indice out of bounds at offset %d\n", i); - } - } - break; - } - - case GL_UNSIGNED_SHORT: - { - size *= 2; - unsigned short* tab_indices = (unsigned short*)indices; - for(i=0;i end) - { - log_gl("indice out of bounds at offset %d\n", i); - } - } - break; - } - - case GL_UNSIGNED_INT: - { - size *= 4; - unsigned int* tab_indices = (unsigned int*)indices; - for(i=0;i end) - { - log_gl("indice out of bounds at offset %d\n", i); - } - } - break; - } - - default: - log_gl("unsupported type = %d\n", type); - return; - } -#else - switch(type) - { - case GL_UNSIGNED_BYTE: - { - } - - case GL_UNSIGNED_SHORT: - { - size *= 2; - break; - } - - case GL_UNSIGNED_INT: - { - size *= 4; - break; - } - - default: - log_gl("unsupported type = %d\n", type); - return; - } -#endif - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(start), INT_TO_ARG(end), - INT_TO_ARG(count), INT_TO_ARG(type), POINTER_TO_ARG(indices) }; - int args_size[] = { 0, 0, 0, 0, 0, size } ; - do_opengl_call(glDrawRangeElements_func, NULL, CHECK_ARGS(args, args_size)); - -} - -DEFINE_EXT(glDrawRangeElements, ( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices ), - (mode, start, end, count, type, indices) ) - - -GLAPI void APIENTRY glMultiDrawArrays( GLenum mode, GLint *first, - GLsizei *count, GLsizei primcount ) -{ - GLint i; - - for (i = 0; i < primcount; i++) { - if (count[i] > 0) { - glDrawArrays(mode, first[i], count[i]); - } - } -} - -DEFINE_EXT(glMultiDrawArrays, ( GLenum mode, GLint *first, - GLsizei *count, GLsizei primcount ), - (mode, first, count, primcount) ) - -GLAPI void APIENTRY glMultiDrawElements( GLenum mode, const GLsizei *count, GLenum type, - const GLvoid **indices, GLsizei primcount ) -{ - GLint i; - CHECK_PROC(glMultiDrawElements); - - Buffer* bufferElement = _get_buffer(GL_ELEMENT_ARRAY_BUFFER_ARB); - if (bufferElement && primcount > 1) - { - if (_check_if_enabled_non_vbo_array()) - { - log_gl("sorry : unsupported : glMultiDrawElements in EBO with a non VBO array enabled\n"); - return; - } - long args[] = { INT_TO_ARG(mode), POINTER_TO_ARG(count), INT_TO_ARG(type), - POINTER_TO_ARG(indices), INT_TO_ARG(primcount) }; - int args_size[] = { 0, primcount * sizeof(int), 0, primcount * sizeof(void*), 0 }; - do_opengl_call(_glMultiDrawElements_buffer_func, NULL, args, args_size); - return; - } - - for (i = 0; i < primcount; i++) { - if (count[i] > 0) { - glDrawElements(mode, count[i], type, indices[i]); - } - } -} - -DEFINE_EXT(glMultiDrawElements, ( GLenum mode, const GLsizei *count, GLenum type, - const GLvoid **indices, GLsizei primcount ), - (mode, count, type, indices, primcount) ) - - -#if 0 -GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset) -{ - CHECK_PROC(glArrayObjectATI); - //log_gl("glArrayObjectATI(array=%p, size=%d, type=%p, stride=%d, buffer=%d, offset=%d)\n", array, size, type, stride, buffer, offset); - long args[] = { UNSIGNED_INT_TO_ARG(array), INT_TO_ARG(size), UNSIGNED_INT_TO_ARG(type), INT_TO_ARG(stride), UNSIGNED_INT_TO_ARG(buffer), UNSIGNED_INT_TO_ARG(offset)}; - do_opengl_call(glArrayObjectATI_func, NULL, args, NULL); -} -#endif - -GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count) -{ - CHECK_PROC(glDrawElementArrayATI); - GET_CURRENT_STATE(); - - if (state->client_state.arrays.elementArrayATI.enabled && - state->client_state.arrays.elementArrayATI.ptr != NULL) - { - int size = count * getMulFactorFromPointerArray(&state->client_state.arrays.elementArrayATI); - long args[] = { INT_TO_ARG(state->client_state.arrays.elementArrayATI.type), - INT_TO_ARG(size), - INT_TO_ARG(state->client_state.arrays.elementArrayATI.ptr) }; - int args_size[] = {0, 0, size}; - do_opengl_call(glElementPointerATI_fake_func, NULL, CHECK_ARGS(args, args_size)); - } - - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(count) }; - do_opengl_call(glDrawElementArrayATI_func, NULL, args, NULL); -} - -GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count) -{ - CHECK_PROC(glDrawRangeElementArrayATI); - GET_CURRENT_STATE(); - - if (state->client_state.arrays.elementArrayATI.enabled && - state->client_state.arrays.elementArrayATI.ptr != NULL) - { - int size = count * getMulFactorFromPointerArray(&state->client_state.arrays.elementArrayATI); - long args[] = { INT_TO_ARG(state->client_state.arrays.elementArrayATI.type), - INT_TO_ARG(size), - INT_TO_ARG(state->client_state.arrays.elementArrayATI.ptr) }; - int args_size[] = {0, 0, size}; - do_opengl_call(glElementPointerATI_fake_func, NULL, CHECK_ARGS(args, args_size)); - } - - long args[] = { INT_TO_ARG(mode), INT_TO_ARG(start), INT_TO_ARG(end), INT_TO_ARG(count) }; - do_opengl_call(glDrawRangeElementArrayATI_func, NULL, args, NULL); -} - -GLAPI GLuint APIENTRY glGenSymbolsEXT(GLenum datatype, GLenum storagetype, GLenum range, GLuint components) -{ - GLuint id = 0; - CHECK_PROC_WITH_RET(glGenSymbolsEXT); - GET_CURRENT_STATE(); - long args[] = { datatype, storagetype, range, components }; - do_opengl_call(glGenSymbolsEXT_func, &id, args, NULL); - if (id != 0) - { - state->symbols.tab = realloc(state->symbols.tab, (state->symbols.count+1) * sizeof(Symbol)); - state->symbols.tab[state->symbols.count].id = id; - state->symbols.tab[state->symbols.count].datatype = datatype; - state->symbols.tab[state->symbols.count].components = components; - state->symbols.count++; - } - return id; -} - -static int get_vertex_shader_var_nb_composants(GLuint id) -{ - GET_CURRENT_STATE(); - int i; - for(i=0;isymbols.count;i++) - { - if (id >= state->symbols.tab[i].id && id < state->symbols.tab[i].id + state->symbols.tab[i].components) - { - int size = 0; - - if (state->symbols.tab[i].datatype == GL_SCALAR_EXT) - size = 1; - else if (state->symbols.tab[i].datatype == GL_VECTOR_EXT) - size = 4; - else if (state->symbols.tab[i].datatype == GL_MATRIX_EXT) - size = 16; - else - { - log_gl("unknown datatype %d\n", state->symbols.tab[i].datatype); - return 0; - } - - return size; - } - } - log_gl("unknown id %d\n", id); - return 0; -} - -GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr) -{ - CHECK_PROC(glSetLocalConstantEXT); - int size = get_vertex_shader_var_nb_composants(id) * getGlTypeByteSize(type); - if (size) - { - long args[] = { id, type, POINTER_TO_ARG(addr) }; - int args_size[] = { 0, 0, size }; - - do_opengl_call(glSetLocalConstantEXT_func, NULL, CHECK_ARGS(args, args_size)); - } -} - -GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr) -{ - CHECK_PROC(glSetInvariantEXT); - int size = get_vertex_shader_var_nb_composants(id) * getGlTypeByteSize(type); - if (size) - { - long args[] = { id, type, POINTER_TO_ARG(addr) }; - int args_size[] = { 0, 0, size }; - - do_opengl_call(glSetInvariantEXT_func, NULL, CHECK_ARGS(args, args_size)); - } -} - -#define glVariantGeneric(func_name, gltype) \ - GLAPI void APIENTRY func_name (GLuint id, const gltype * addr)\ -{\ - CHECK_PROC(func_name); \ - int size = get_vertex_shader_var_nb_composants(id) * sizeof(gltype); \ - if (size) \ - { \ - long args[] = { id, POINTER_TO_ARG(addr) }; \ - int args_size[] = { 0, size }; \ - do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \ - } \ -} - -glVariantGeneric(glVariantbvEXT, GLbyte); -glVariantGeneric(glVariantsvEXT, GLshort); -glVariantGeneric(glVariantivEXT, GLint); -glVariantGeneric(glVariantfvEXT, GLfloat); -glVariantGeneric(glVariantdvEXT, GLdouble); -glVariantGeneric(glVariantubvEXT, GLubyte); -glVariantGeneric(glVariantusvEXT, GLushort); -glVariantGeneric(glVariantuivEXT, GLuint); - -GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id) -{ - CHECK_PROC(glEnableVariantClientStateEXT); - long args[] = { id }; - do_opengl_call(glEnableVariantClientStateEXT_func, NULL, args, NULL); - if (id < MY_GL_MAX_VARIANT_POINTER_EXT) - { - GET_CURRENT_STATE(); - state->client_state.arrays.variantPointer[id].enabled = 1; - } -} - -GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id) -{ - CHECK_PROC(glDisableVariantClientStateEXT); - long args[] = { id }; - do_opengl_call(glDisableVariantClientStateEXT_func, NULL, args, NULL); - if (id < MY_GL_MAX_VARIANT_POINTER_EXT) - { - GET_CURRENT_STATE(); - state->client_state.arrays.variantPointer[id].enabled = 0; - } -} - -GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *ptr) -{ - CHECK_PROC(glVariantPointerEXT); - - GET_CURRENT_STATE(); - if (id < MY_GL_MAX_VARIANT_POINTER_EXT) - { - state->client_state.arrays.variantPointer[id].vbo_name = state->arrayBuffer; - if (state->client_state.arrays.variantPointer[id].vbo_name) - { - long args[] = { INT_TO_ARG(id), INT_TO_ARG(type), INT_TO_ARG(stride), POINTER_TO_ARG(ptr) }; - do_opengl_call(_glVariantPointerEXT_buffer_func, NULL, args, NULL); - return; - } - - if (debug_array_ptr) - log_gl("glVariantPointerEXT[%d] type=%dstride=%d ptr=%p\n", - id, type, stride, ptr); - state->client_state.arrays.variantPointer[id].index = id; - state->client_state.arrays.variantPointer[id].size = 4; - state->client_state.arrays.variantPointer[id].type = type; - state->client_state.arrays.variantPointer[id].stride = stride; - state->client_state.arrays.variantPointer[id].ptr = ptr; - } - else - { - log_gl("id >= MY_GL_MAX_VARIANT_POINTER_EXT\n"); - } -} - -#define glGetVariantGeneric(func_name, gltype) \ - GLAPI void APIENTRY func_name (GLuint id, GLenum name, gltype* addr)\ -{\ - CHECK_PROC(func_name); \ - int size = (name == GL_VARIANT_VALUE_EXT) ? get_vertex_shader_var_nb_composants(id) * sizeof(gltype) : sizeof(gltype); \ - if (size) \ - { \ - long args[] = { id, name, POINTER_TO_ARG(addr) }; \ - int args_size[] = { 0, 0, size }; \ - do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \ - } \ -} - -glGetVariantGeneric(glGetVariantBooleanvEXT, GLboolean); -glGetVariantGeneric(glGetVariantIntegervEXT, GLint); -glGetVariantGeneric(glGetVariantFloatvEXT, GLfloat); - -GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum name, GLvoid* *addr) -{ - CHECK_PROC(glGetVariantPointervEXT); - - GET_CURRENT_STATE(); - if (id < MY_GL_MAX_VARIANT_POINTER_EXT) - { - if (name == GL_VARIANT_ARRAY_POINTER_EXT) - *addr = (void*)state->client_state.arrays.variantPointer[id].ptr; - } - else - { - log_gl("id >= MY_GL_MAX_VARIANT_POINTER_EXT\n"); - } -} - -#define glGetInvariantGeneric(func_name, gltype) \ - GLAPI void APIENTRY func_name (GLuint id, GLenum name, gltype* addr)\ -{\ - CHECK_PROC(func_name); \ - int size = (name == GL_INVARIANT_VALUE_EXT) ? get_vertex_shader_var_nb_composants(id) * sizeof(gltype) : sizeof(gltype); \ - if (size) \ - { \ - long args[] = { id, name, POINTER_TO_ARG(addr) }; \ - int args_size[] = { 0, 0, size }; \ - do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \ - } \ -} - -glGetInvariantGeneric(glGetInvariantBooleanvEXT, GLboolean); -glGetInvariantGeneric(glGetInvariantIntegervEXT, GLint); -glGetInvariantGeneric(glGetInvariantFloatvEXT, GLfloat); - -#define glGetLocalConstantGeneric(func_name, gltype) \ - GLAPI void APIENTRY func_name (GLuint id, GLenum name, gltype* addr)\ -{\ - CHECK_PROC(func_name); \ - int size = (name == GL_LOCAL_CONSTANT_VALUE_EXT) ? get_vertex_shader_var_nb_composants(id) * sizeof(gltype) : sizeof(gltype); \ - if (size) \ - { \ - long args[] = { id, name, POINTER_TO_ARG(addr) }; \ - int args_size[] = { 0, 0, size }; \ - do_opengl_call(CONCAT(func_name,_func), NULL, CHECK_ARGS(args, args_size)); \ - } \ -} - -glGetLocalConstantGeneric(glGetLocalConstantBooleanvEXT, GLboolean); -glGetLocalConstantGeneric(glGetLocalConstantIntegervEXT, GLint); -glGetLocalConstantGeneric(glGetLocalConstantFloatvEXT, GLfloat); - - -static void _glShaderSource(int func_number, GLhandleARB handle, GLsizei size, const GLcharARB** tab_prog, const GLint* tab_length) -{ - int i; - int* my_tab_length; - int total_length = 0; - int acc_length = 0; - GLcharARB* all_progs; - - if (size <= 0 || tab_prog == NULL) - { - log_gl("size <= 0 || tab_prog == NULL\n"); - return; - } - my_tab_length = malloc(sizeof(int) * size); - for(i=0;icountUniformLocations;i++) - { - if (state->uniformLocations[i].program == program && - strcmp(state->uniformLocations[i].txt, txt) == 0) - { - return state->uniformLocations[i].location; - } - } - - CHECK_PROC_WITH_RET(glGetUniformLocationARB); - long args[] = { INT_TO_ARG(program), POINTER_TO_ARG(txt) } ; - do_opengl_call(glGetUniformLocationARB_func, &ret, args, NULL); - - state->uniformLocations = realloc(state->uniformLocations, sizeof(UniformLocation) * (state->countUniformLocations+1)); - state->uniformLocations[state->countUniformLocations].program = program; - state->uniformLocations[state->countUniformLocations].txt = strdup(txt); - state->uniformLocations[state->countUniformLocations].location = ret; - state->countUniformLocations++; - - return ret; -} - -GLAPI GLint EXT_FUNC(glGetUniformLocation) (GLuint program, const GLcharARB *txt) -{ - int i; - int ret = -1; - GET_CURRENT_STATE(); - for(i=0;icountUniformLocations;i++) - { - if (state->uniformLocations[i].program == program && - strcmp(state->uniformLocations[i].txt, txt) == 0) - { - return state->uniformLocations[i].location; - } - } - - CHECK_PROC_WITH_RET(glGetUniformLocation); - long args[] = { INT_TO_ARG(program), POINTER_TO_ARG(txt) } ; - do_opengl_call(glGetUniformLocation_func, &ret, args, NULL); - - state->uniformLocations = realloc(state->uniformLocations, sizeof(UniformLocation) * (state->countUniformLocations+1)); - state->uniformLocations[state->countUniformLocations].program = program; - state->uniformLocations[state->countUniformLocations].txt = strdup(txt); - state->uniformLocations[state->countUniformLocations].location = ret; - state->countUniformLocations++; - - return ret; -} - - -GLAPI void APIENTRY EXT_FUNC(glGetActiveUniformARB)(GLuint program, - GLuint index, - GLsizei maxLength, - GLsizei *length, - GLint *size, - GLenum *type, - GLcharARB *name) -{ - CHECK_PROC(glGetActiveUniformARB); - int fake_length; - if (length == NULL) length = &fake_length; - long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) }; - int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), maxLength }; - do_opengl_call(glGetActiveUniformARB_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glGetActiveUniform)(GLuint program, - GLuint index, - GLsizei maxLength, - GLsizei *length, - GLint *size, - GLenum *type, - GLcharARB *name) -{ - CHECK_PROC(glGetActiveUniform); - int fake_length; - if (length == NULL) length = &fake_length; - long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(maxLength), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) }; - int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), maxLength }; - do_opengl_call(glGetActiveUniform_func, NULL, CHECK_ARGS(args, args_size)); -} - -GLAPI void APIENTRY EXT_FUNC(glGetActiveVaryingNV)(GLuint program, - GLuint index, - GLsizei bufSize, - GLsizei *length, - GLsizei *size, - GLenum *type, - GLchar *name) -{ - CHECK_PROC(glGetActiveVaryingNV); - int fake_length; - if (length == NULL) length = &fake_length; - long args[] = { INT_TO_ARG(program), INT_TO_ARG(index), INT_TO_ARG(bufSize), POINTER_TO_ARG(length), POINTER_TO_ARG(size), POINTER_TO_ARG(type), POINTER_TO_ARG(name) }; - int args_size[] = { 0, 0, 0, sizeof(int), sizeof(int), sizeof(int), bufSize }; - do_opengl_call(glGetActiveVaryingNV_func, NULL, CHECK_ARGS(args, args_size)); -} - -static int _get_size_of_gl_uniform_variables(GLenum type) -{ - switch(type) - { - case GL_FLOAT: return sizeof(float); - case GL_FLOAT_VEC2: return 2*sizeof(float); - case GL_FLOAT_VEC3: return 3*sizeof(float); - case GL_FLOAT_VEC4: return 4*sizeof(float); - case GL_INT: return sizeof(int); - case GL_INT_VEC2: return 2*sizeof(int); - case GL_INT_VEC3: return 3*sizeof(int); - case GL_INT_VEC4: return 4*sizeof(int); - case GL_BOOL: return sizeof(int); - case GL_BOOL_VEC2: return 2*sizeof(int); - case GL_BOOL_VEC3: return 3*sizeof(int); - case GL_BOOL_VEC4: return 4*sizeof(int); - case GL_FLOAT_MAT2: return 2*2*sizeof(float); - case GL_FLOAT_MAT3: return 3*3*sizeof(float); - case GL_FLOAT_MAT4: return 4*4*sizeof(float); - case GL_FLOAT_MAT2x3:return 2*3*sizeof(float); - case GL_FLOAT_MAT2x4:return 2*4*sizeof(float); - case GL_FLOAT_MAT3x2:return 3*2*sizeof(float); - case GL_FLOAT_MAT3x4:return 3*4*sizeof(float); - case GL_FLOAT_MAT4x2:return 4*2*sizeof(float); - case GL_FLOAT_MAT4x3:return 4*3*sizeof(float); - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - return sizeof(int); - - default: - log_gl("unknown type for a uniform variable : %X\n", type); - return 0; - } -} - -static void _gl_get_uniform(PFNGLGETPROGRAMIVPROC getProgramiv, - PFNGLGETACTIVEUNIFORMPROC getActiveUniform, - int func_number, - GLuint program, - GLint location, - void* params) -{ - GET_CURRENT_STATE(); - int nActiveUniforms = 0; - int nameMaxLength = 0; - int i; - - getProgramiv(program, GL_ACTIVE_UNIFORMS, &nActiveUniforms); - getProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &nameMaxLength); - - char* name = malloc(nameMaxLength+1); - char* uniformName = NULL; - for(i=0;icountUniformLocations;i++) - { - if (state->uniformLocations[i].program == program && - state->uniformLocations[i].location == location) - { - uniformName = state->uniformLocations[i].txt; - break; - } - } - if (uniformName == NULL) - { - log_gl("unknown uniform location : %d\n", location); - return; - } - char* uniformName2 = NULL; - if (strchr(uniformName, '[') == 0) - { - uniformName2 = malloc(strlen(uniformName) + 3 + 1); - strcpy(uniformName2, uniformName); - strcat(uniformName2, "[0]"); - } - /*log_gl("nActiveUniforms=%d\n", nActiveUniforms);*/ - for(i=0;iobjectBuffersATI[i].bufferid == 0) - { - memset(&state->objectBuffersATI[i], 0, sizeof(ObjectBufferATI)); - return &state->objectBuffersATI[i]; - } - } - return NULL; -} - -static ObjectBufferATI* _find_object_buffer_ATI_from_id(GLuint buffer) -{ - GET_CURRENT_STATE(); - int i; - for(i=0;i<32768;i++) - { - if (state->objectBuffersATI[i].bufferid == buffer) - { - return &state->objectBuffersATI[i]; - } - } - return NULL; -} - -static void _free_object_buffer_ATI(ObjectBufferATI* objectBufferATI) -{ - if (objectBufferATI == NULL) return; - - if (objectBufferATI->ptr) - free(objectBufferATI->ptr); - objectBufferATI->ptr = NULL; - if (objectBufferATI->ptrMapped) - free(objectBufferATI->ptrMapped); - objectBufferATI->ptrMapped = NULL; - if (objectBufferATI->ptrUpdatedWhileMapped) - free(objectBufferATI->ptrUpdatedWhileMapped); - objectBufferATI->ptrUpdatedWhileMapped = NULL; - if (objectBufferATI->updatedRangesAfterMapping.ranges) - free(objectBufferATI->updatedRangesAfterMapping.ranges); - objectBufferATI->updatedRangesAfterMapping.ranges = NULL; - objectBufferATI->updatedRangesAfterMapping.nb = 0; - objectBufferATI->bufferid = 0; - objectBufferATI->size = 0; -} - -GLAPI GLuint APIENTRY EXT_FUNC(glNewObjectBufferATI) (GLsizei size, const GLvoid *pointer, GLenum usage) -{ - int buffer = 0; - CHECK_PROC_WITH_RET(glNewObjectBufferATI); - long args[] = { INT_TO_ARG(size), POINTER_TO_ARG(pointer), INT_TO_ARG(usage) }; - int args_size[] = { 0, (pointer) ? size : 0, 0 }; - do_opengl_call(glNewObjectBufferATI_func, &buffer, CHECK_ARGS(args, args_size)); - //log_gl("glNewObjectBufferATI(%d,%p) --> %d\n", size, pointer, buffer); - - if (buffer != 0) - { - ObjectBufferATI* objectBufferATI = _new_object_buffer_ATI(); - if (objectBufferATI) - { - objectBufferATI->bufferid = buffer; - objectBufferATI->size = size; - objectBufferATI->ptr = malloc(size); - objectBufferATI->ptrMapped = NULL; - if (pointer) - memcpy(objectBufferATI->ptr, pointer, size); - } - } - - return buffer; -} - -GLAPI void APIENTRY EXT_FUNC(glFreeObjectBufferATI) (GLuint buffer) -{ - CHECK_PROC(glFreeObjectBufferATI); - long args[] = { UNSIGNED_INT_TO_ARG(buffer)}; - do_opengl_call(glFreeObjectBufferATI_func, NULL, args, NULL); - _free_object_buffer_ATI(_find_object_buffer_ATI_from_id(buffer)); -} - -static void _add_int_range_to_ranges(IntSetRanges* ranges, int start, int length) -{ - int i,j; - for(i=0;inb;i++) - { - IntRange* range = &ranges->ranges[i]; - if (start <= range->start) - { - if (start + length < range->start) - { - if (ranges->nb == ranges->maxNb) - ranges->ranges = realloc(ranges->ranges, sizeof(IntRange) * (ranges->nb+1)); - memmove(&ranges->ranges[i+1], &ranges->ranges[i], sizeof(IntRange) * (ranges->nb - i)); - ranges->nb++; - if (ranges->nb > ranges->maxNb) - ranges->maxNb = ranges->nb; - ranges->ranges[i].start = start; - ranges->ranges[i].length = length; - return; - } - else if (start + length <= range->start + range->length) - { - range->length = range->start + range->length - start; - range->start = start; - return; - } - else - { - j = i + 1; - range->start = start; - range->length = start + length - range->start; - while(j < ranges->nb && start + length >= ranges->ranges[j].start) - { - if (start + length <= ranges->ranges[j].start + ranges->ranges[j].length) - { - range->length = ranges->ranges[j].start + ranges->ranges[j].length - range->start; - j++; - break; - } - j++; - } - if (i+1nb) - memmove(&ranges->ranges[i+1], &ranges->ranges[j], sizeof(IntRange) * (j - (i + 1))); - ranges->nb -= j - (i+1); - return; - } - } - else - { - if (start > range->start + range->length) - { - continue; - } - else if (start + length <= range->start + range->length) - { - return; - } - else - { - j = i + 1; - range->length = start + length - range->start; - while(j < ranges->nb && start + length >= ranges->ranges[j].start) - { - if (start + length <= ranges->ranges[j].start + ranges->ranges[j].length) - { - range->length = ranges->ranges[j].start + ranges->ranges[j].length - range->start; - j++; - break; - } - j++; - } - if (i+1nb) - memmove(&ranges->ranges[i+1], &ranges->ranges[j], sizeof(IntRange) * (j - (i + 1))); - ranges->nb -= j - (i+1); - return; - } - } - } - if (ranges->nb == ranges->maxNb) - ranges->ranges = realloc(ranges->ranges, sizeof(IntRange) * (ranges->nb+1)); - ranges->ranges[ranges->nb].start = start; - ranges->ranges[ranges->nb].length = length; - ranges->nb++; - if (ranges->nb > ranges->maxNb) - ranges->maxNb = ranges->nb; - return; -} - -static IntSetRanges _get_empty_ranges(IntSetRanges* inRanges, int start, int length) -{ - IntSetRanges outRanges = {0}; - int i; - int end = start+length; - int last_end = 0x80000000; - for(i=0;i<=inRanges->nb;i++) - { - int cur_start, cur_end; - if (i == inRanges->nb) - { - cur_start = cur_end = 0x7FFFFFFF; - } - else - { - IntRange* range = &inRanges->ranges[i]; - cur_start = range->start; - cur_end = range->start + range->length; - } - - /* [last_end,cur_start[ inter [start,end[ */ - if ((last_end >= start && last_end < end) || (start >= last_end && start < cur_start)) - { - outRanges.ranges = realloc(outRanges.ranges, sizeof(IntRange) * (outRanges.nb+1)); - outRanges.ranges[outRanges.nb].start = MAX(start,last_end); - outRanges.ranges[outRanges.nb].length = MIN(end,cur_start) - outRanges.ranges[outRanges.nb].start; - outRanges.nb++; - } - - last_end = cur_end; - } - return outRanges; -} - -GLAPI void APIENTRY EXT_FUNC(glUpdateObjectBufferATI) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve) -{ - CHECK_PROC(glUpdateObjectBufferATI); - //log_gl("glUpdateObjectBufferATI(%d, %d, %d)\n", buffer, offset, size); - long args[] = { INT_TO_ARG(buffer), INT_TO_ARG(offset), INT_TO_ARG(size), POINTER_TO_ARG(pointer), INT_TO_ARG(preserve) }; - int args_size[] = { 0, 0, 0, size, 0 }; - do_opengl_call(glUpdateObjectBufferATI_func, NULL, CHECK_ARGS(args, args_size)); - ObjectBufferATI* objectBufferATI = _find_object_buffer_ATI_from_id(buffer); - if (objectBufferATI) - { - if (offset >= 0 && offset + size <= objectBufferATI->size) - { - if (objectBufferATI->ptrMapped) - { - log_gl("you shouldn't call glUpdateObjectBufferATI after glMapObjectBufferATI. we're emulating ATI fglrx (strange) behaviour\n"); - objectBufferATI->updatedRangesAfterMapping.nb = 0; - _add_int_range_to_ranges(&objectBufferATI->updatedRangesAfterMapping, offset, size); - objectBufferATI->ptrUpdatedWhileMapped = realloc(objectBufferATI->ptrUpdatedWhileMapped, size); - memcpy(objectBufferATI->ptrUpdatedWhileMapped, pointer, size); - } - else - { - memcpy(objectBufferATI->ptr + offset, pointer, size); - } - } - else - { - log_gl("offset >= 0 && offset + size <= state->objectBuffersATI[i].size failed\n"); - } - } -} - -GLAPI GLvoid* APIENTRY EXT_FUNC(glMapObjectBufferATI) (GLuint buffer) -{ - CHECK_PROC_WITH_RET(glMapObjectBufferATI); - //log_gl("glMapObjectBufferATI(%d)\n", buffer); - ObjectBufferATI* objectBufferATI = _find_object_buffer_ATI_from_id(buffer); - if (objectBufferATI) - { - if (objectBufferATI->ptrMapped == NULL) - { - objectBufferATI->ptrMapped = malloc(objectBufferATI->size); - memcpy(objectBufferATI->ptrMapped, - objectBufferATI->ptr, - objectBufferATI->size); - return objectBufferATI->ptrMapped; - } - else - return NULL; - } - else - return NULL; -} - -GLAPI void APIENTRY EXT_FUNC(glUnmapObjectBufferATI) (GLuint buffer) -{ - CHECK_PROC(glUnmapObjectBufferATI); - //log_gl("glUnmapObjectBufferATI(%d)\n", buffer); - ObjectBufferATI* objectBufferATI = _find_object_buffer_ATI_from_id(buffer); - if (objectBufferATI) - { - if (objectBufferATI->ptrMapped) - { - IntSetRanges outRanges = _get_empty_ranges(&objectBufferATI->updatedRangesAfterMapping, 0, objectBufferATI->size); - int i; - void* ptrMapped = objectBufferATI->ptrMapped; - if (objectBufferATI->ptrUpdatedWhileMapped) - { - assert(objectBufferATI->updatedRangesAfterMapping.nb == 1); - memcpy(objectBufferATI->ptr + objectBufferATI->updatedRangesAfterMapping.ranges[0].start, - objectBufferATI->ptrUpdatedWhileMapped, - objectBufferATI->updatedRangesAfterMapping.ranges[0].length); - free(objectBufferATI->ptrUpdatedWhileMapped); - objectBufferATI->ptrUpdatedWhileMapped = NULL; - } - objectBufferATI->updatedRangesAfterMapping.nb = 0; - objectBufferATI->ptrMapped = NULL; - for(i=0;i> 8) & 0xff; - char2b.byte2 = (c & 0xff); - - XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); - - image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); - if (image) { - /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ - for (y = 0; y < height; y++) - for (x = 0; x < 8 * width; x++) - if (XGetPixel(image, x, y)) - bitmap[width * (height - y - 1) + x / 8] |= - (1 << (7 - (x % 8))); - XDestroyImage(image); - } - - XFreePixmap(dpy, pixmap); -} - -/* - * determine if a given glyph is valid and return the - * corresponding XCharStruct. - */ -static XCharStruct * -isvalid(XFontStruct * fs, unsigned int which) -{ - unsigned int rows, pages; - unsigned int byte1 = 0, byte2 = 0; - int i, valid = 1; - - rows = fs->max_byte1 - fs->min_byte1 + 1; - pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; - - if (rows == 1) { - /* "linear" fonts */ - if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) - valid = 0; - } - else { - /* "matrix" fonts */ - byte2 = which & 0xff; - byte1 = which >> 8; - if ((fs->min_char_or_byte2 > byte2) || - (fs->max_char_or_byte2 < byte2) || - (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) - valid = 0; - } - - if (valid) { - if (fs->per_char) { - if (rows == 1) { - /* "linear" fonts */ - return (fs->per_char + (which - fs->min_char_or_byte2)); - } - else { - /* "matrix" fonts */ - i = ((byte1 - fs->min_byte1) * pages) + - (byte2 - fs->min_char_or_byte2); - return (fs->per_char + i); - } - } - else { - return (&fs->min_bounds); - } - } - return (NULL); -} - - -GLAPI void APIENTRY glXUseXFont( Font font, int first, int count, int listbase ) -{ - Display *dpy; - Window win; - Pixmap pixmap; - GC gc; - XGCValues values; - unsigned long valuemask; - XFontStruct *fs; - GLint swapbytes, lsbfirst, rowlength; - GLint skiprows, skippixels, alignment; - unsigned int max_width, max_height, max_bm_width, max_bm_height; - GLubyte *bm; - int i; - - dpy = glXGetCurrentDisplay(); - if (!dpy) - return; /* I guess glXMakeCurrent wasn't called */ - win = RootWindow(dpy, DefaultScreen(dpy)); - - fs = XQueryFont(dpy, font); - if (!fs) { - /*_mesa_error(NULL, GL_INVALID_VALUE, - "Couldn't get font structure information");*/ - return; - } - - /* Allocate a bitmap that can fit all characters. */ - max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; - max_height = fs->max_bounds.ascent + fs->max_bounds.descent; - max_bm_width = (max_width + 7) / 8; - max_bm_height = max_height; - - bm = (GLubyte *) malloc((max_bm_width * max_bm_height) * sizeof(GLubyte)); - if (!bm) { - XFreeFontInfo(NULL, fs, 1); - /*_mesa_error(NULL, GL_OUT_OF_MEMORY, - "Couldn't allocate bitmap in glXUseXFont()");*/ - return; - } - -#if 0 - /* get the page info */ - pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; - firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; - lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; - rows = fs->max_byte1 - fs->min_byte1 + 1; - unsigned int first_char, last_char, pages, rows; -#endif - - /* Save the current packing mode for bitmaps. */ - glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); - glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); - glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); - glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); - - /* Enforce a standard packing mode which is compatible with - fill_bitmap() from above. This is actually the default mode, - except for the (non)alignment. */ - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - pixmap = XCreatePixmap(dpy, win, 10, 10, 1); - values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); - values.background = WhitePixel(dpy, DefaultScreen(dpy)); - values.font = fs->fid; - valuemask = GCForeground | GCBackground | GCFont; - gc = XCreateGC(dpy, pixmap, valuemask, &values); - XFreePixmap(dpy, pixmap); - -#ifdef DEBUG - if (debug_xfonts) - dump_font_struct(fs); -#endif - - for (i = 0; i < count; i++) { - unsigned int width, height, bm_width, bm_height; - GLfloat x0, y0, dx, dy; - XCharStruct *ch; - int x, y; - unsigned int c = first + i; - int list = listbase + i; - int valid; - - /* check on index validity and get the bounds */ - ch = isvalid(fs, c); - if (!ch) { - ch = &fs->max_bounds; - valid = 0; - } - else { - valid = 1; - } - -#ifdef DEBUG - if (debug_xfonts) { - char s[7]; - sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); - dump_char_struct(ch, s); - } -#endif - - /* glBitmap()' parameters: - straight from the glXUseXFont(3) manpage. */ - width = ch->rbearing - ch->lbearing; - height = ch->ascent + ch->descent; - x0 = -ch->lbearing; - y0 = ch->descent - 0; /* XXX used to subtract 1 here */ - /* but that caused a conformace failure */ - dx = ch->width; - dy = 0; - - /* X11's starting point. */ - x = -ch->lbearing; - y = ch->ascent; - - /* Round the width to a multiple of eight. We will use this also - for the pixmap for capturing the X11 font. This is slightly - inefficient, but it makes the OpenGL part real easy. */ - bm_width = (width + 7) / 8; - bm_height = height; - - glNewList(list, GL_COMPILE); - if (valid && (bm_width > 0) && (bm_height > 0)) { - - memset(bm, '\0', bm_width * bm_height); - fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); - - glBitmap(width, height, x0, y0, dx, dy, bm); -#ifdef DEBUG - if (debug_xfonts) { - printf("width/height = %u/%u\n", width, height); - printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); - dump_bitmap(bm_width, bm_height, bm); - } -#endif - } - else { - glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); - } - glEndList(); - } - - free(bm); - XFreeFontInfo(NULL, fs, 1); - XFreeGC(dpy, gc); - - /* Restore saved packing modes. */ - glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); - glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); - glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); - glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); - glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); -} diff --git a/target-i386/opengl_exec.c b/target-i386/opengl_exec.c deleted file mode 100755 index 3930dfd..0000000 --- a/target-i386/opengl_exec.c +++ /dev/null @@ -1,7230 +0,0 @@ -/* - * Host-side implementation of GL/GLX API - * - * Copyright (c) 2006,2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - - -#include -#include -#include -#include - -void init_process_tab(void); - -#ifdef _WIN32 - -#include - -//#define _MK_DBG_ - -#define IsViewable 2 -#define False 0 -#define True 1 - - -#define GL_GLEXT_PROTOTYPES -#include "opengl_func.h" -#include "opengl_utils.h" -#include "mesa_glx.h" -#include "mesa_glxext.h" -#include "mesa_glu.h" -#include "mesa_mipmap.c" - -typedef struct -{ - HGLRC context; - void *backBuffer; - int width; - int height; - int colorFormat; - unsigned int colorBits; -} PbufferInfo; - -typedef struct -{ - void* key; - void* value; - void* hWnd; /* Surface?? ˤ?? Window Handle*/ - void* cDC; /*Context?? ˤ?? Dummy Window Handle*/ -} Assoc; - -#define MAX_HANDLED_PROCESS 100 -#define MAX_ASSOC_SIZE 100 -#define MAX_FBCONFIG 10 -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -typedef struct -{ - int x; - int y; - int width; - int height; - int map_state; -} WindowPosStruct; - -typedef struct -{ - GLbitfield mask; - int activeTextureIndex; -} ClientState; - -#define MAX_CLIENT_STATE_STACK_SIZE 16 -#define NB_MAX_TEXTURES 16 -#define MY_GL_MAX_VERTEX_ATTRIBS_ARB 16 -#define MY_GL_MAX_VERTEX_ATTRIBS_NV 16 -#define MY_GL_MAX_VARIANT_POINTER_EXT 16 - -typedef struct -{ - int ref; - int fake_ctxt; - int fake_shareList; - HGLRC context; - HDC drawable; - - void* vertexPointer; - void* normalPointer; - void* colorPointer; - void* secondaryColorPointer; - void* indexPointer; - void* texCoordPointer[NB_MAX_TEXTURES]; - void* edgeFlagPointer; - void* vertexAttribPointer[MY_GL_MAX_VERTEX_ATTRIBS_ARB]; - void* vertexAttribPointerNV[MY_GL_MAX_VERTEX_ATTRIBS_NV]; - void* weightPointer; - void* matrixIndexPointer; - void* fogCoordPointer; - void* variantPointerEXT[MY_GL_MAX_VARIANT_POINTER_EXT]; - void* interleavedArrays; - void* elementPointerATI; - - int vertexPointerSize; - int normalPointerSize; - int colorPointerSize; - int secondaryColorPointerSize; - int indexPointerSize; - int texCoordPointerSize[NB_MAX_TEXTURES]; - int edgeFlagPointerSize; - int vertexAttribPointerSize[MY_GL_MAX_VERTEX_ATTRIBS_ARB]; - int vertexAttribPointerNVSize[MY_GL_MAX_VERTEX_ATTRIBS_NV]; - int weightPointerSize; - int matrixIndexPointerSize; - int fogCoordPointerSize; - int variantPointerEXTSize[MY_GL_MAX_VARIANT_POINTER_EXT]; - int interleavedArraysSize; - int elementPointerATISize; - - int selectBufferSize; - void* selectBufferPtr; - int feedbackBufferSize; - void* feedbackBufferPtr; - - ClientState clientStateStack[MAX_CLIENT_STATE_STACK_SIZE]; - int clientStateSp; - int activeTextureIndex; - - unsigned int ownTabTextures[32768]; - unsigned int* tabTextures; - RangeAllocator ownTextureAllocator; - RangeAllocator* textureAllocator; - - unsigned int ownTabBuffers[32768]; - unsigned int* tabBuffers; - RangeAllocator ownBufferAllocator; - RangeAllocator* bufferAllocator; - - unsigned int ownTabLists[32768]; - unsigned int* tabLists; - RangeAllocator ownListAllocator; - RangeAllocator* listAllocator; - -#ifdef SYSTEMATIC_ERROR_CHECK - int last_error; -#endif -} GLState; - -typedef struct -{ - PIXELFORMATDESCRIPTOR pfd; - unsigned int visualID; -} WGLFBConfig; - -typedef struct -{ - int internal_num; - int process_id; - int instr_counter; - - int x, y, width, height; - WindowPosStruct currentDrawablePos; - - int next_available_context_number; - int next_available_pbuffer_number; - - int nbGLStates; - GLState default_state; - GLState** glstates; - GLState* current_state; - - int nfbconfig; - WGLFBConfig* fbconfigs[MAX_FBCONFIG]; - int fbconfigs_max[MAX_FBCONFIG]; - int nfbconfig_total; - - Assoc association_fakecontext_glxcontext[MAX_ASSOC_SIZE]; - Assoc association_fakepbuffer_pbuffer[MAX_ASSOC_SIZE]; - Assoc association_clientdrawable_serverdrawable[MAX_ASSOC_SIZE]; - Assoc association_fakecontext_visual[MAX_ASSOC_SIZE]; -} ProcessStruct; - -int last_process_id = 0; - - -typedef struct -{ - int attribListLength; - int* attribList; - unsigned int visualID; - /*PIXELFORMATDESCRIPTOR* visInfo;*/ -} AssocAttribListVisual; - -#define ARG_TO_CHAR(x) (char)(x) -#define ARG_TO_UNSIGNED_CHAR(x) (unsigned char)(x) -#define ARG_TO_SHORT(x) (short)(x) -#define ARG_TO_UNSIGNED_SHORT(x) (unsigned short)(x) -#define ARG_TO_INT(x) (int)(x) -#define ARG_TO_UNSIGNED_INT(x) (unsigned int)(x) -#define ARG_TO_FLOAT(x) (*(float*)&(x)) -#define ARG_TO_DOUBLE(x) (*(double*)(x)) - -#define GET_EXT_PTR(type, funcname, args_decl) \ - static int detect_##funcname = 0; \ -static type(*ptr_func_##funcname)args_decl = NULL; \ -if (detect_##funcname == 0) \ -{ \ - detect_##funcname = 1; \ - ptr_func_##funcname = (type(*)args_decl)wglGetProcAddress((const GLubyte*)#funcname); \ - assert (ptr_func_##funcname); \ -} - -#define GET_EXT_PTR_NO_FAIL(type, funcname, args_decl) \ - static int detect_##funcname = 0; \ -static type(*ptr_func_##funcname)args_decl = NULL; \ -if (detect_##funcname == 0) \ -{ \ - detect_##funcname = 1; \ - ptr_func_##funcname = (type(*)args_decl)wglGetProcAddress((const GLubyte*)#funcname); \ -} - - -#include "server_stub.c" - -static void* get_glu_ptr(const char* name) -{ - static void* handle = (void*)-1; - if (handle == (void*)-1) - { -#ifndef WIN32 - handle = dlopen("libGLU.so" ,RTLD_LAZY); - if (!handle) { - fprintf (stderr, "can't load libGLU.so : %s\n", dlerror()); - } -#else - handle = (void *)LoadLibrary("glu32.dll"); - if (!handle) { - fprintf (stderr, "can't load glu32.dll\n"); - } -#endif - } - if (handle) - { -#ifndef WIN32 - return dlsym(handle, name); -#else - return GetProcAddress(handle, name); -#endif - } - return NULL; -} - - - -#define GET_GLU_PTR(type, funcname, args_decl) \ - static int detect_##funcname = 0; \ -static type(*ptr_func_##funcname)args_decl = NULL; \ -if (detect_##funcname == 0) \ -{ \ - detect_##funcname = 1; \ - ptr_func_##funcname = (type(*)args_decl)get_glu_ptr(#funcname); \ -} - - -static void _get_window_pos(HWND hWnd, WindowPosStruct* pos) -{ - RECT rcWindow; - - GetWindowRect(hWnd, &rcWindow); - - pos->x = rcWindow.left; - pos->y = rcWindow.top; - - pos->width = rcWindow.right - rcWindow.left; - pos->height = rcWindow.bottom - rcWindow.top; - - pos->map_state = IsViewable; -} - - -int display_function_call = 0; - -static void init_gl_state(GLState* state) -{ - state->textureAllocator = &state->ownTextureAllocator; - state->tabTextures = state->ownTabTextures; - state->bufferAllocator = &state->ownBufferAllocator; - state->tabBuffers = state->ownTabBuffers; - state->listAllocator = &state->ownListAllocator; - state->tabLists = state->ownTabLists; -} - - -static void destroy_gl_state(GLState* state) -{ - int i; - if (state->vertexPointer) free(state->vertexPointer); - if (state->normalPointer) free(state->normalPointer); - if (state->indexPointer) free(state->indexPointer); - if (state->colorPointer) free(state->colorPointer); - if (state->secondaryColorPointer) free(state->secondaryColorPointer); - for(i=0;itexCoordPointer[i]) free(state->texCoordPointer[i]); - } - for(i=0;ivertexAttribPointer[i]) free(state->vertexAttribPointer[i]); - } - for(i=0;ivertexAttribPointerNV[i]) free(state->vertexAttribPointerNV[i]); - } - if (state->weightPointer) free(state->weightPointer); - if (state->matrixIndexPointer) free(state->matrixIndexPointer); - if (state->fogCoordPointer) free(state->fogCoordPointer); - for(i=0;ivariantPointerEXT[i]) free(state->variantPointerEXT[i]); - } - if (state->interleavedArrays) free(state->interleavedArrays); - if (state->elementPointerATI) free(state->elementPointerATI); -} - -static void _create_context(ProcessStruct* process, HGLRC ctxt, int fake_ctxt, HGLRC shareList, int fake_shareList) -{ - process->glstates = realloc(process->glstates, (process->nbGLStates+1)*sizeof(GLState*)); - process->glstates[process->nbGLStates] = malloc(sizeof(GLState)); - memset(process->glstates[process->nbGLStates], 0, sizeof(GLState)); - process->glstates[process->nbGLStates]->ref = 1; - process->glstates[process->nbGLStates]->context = ctxt; - process->glstates[process->nbGLStates]->fake_ctxt = fake_ctxt; - process->glstates[process->nbGLStates]->fake_shareList = fake_shareList; - init_gl_state(process->glstates[process->nbGLStates]); - if (shareList && fake_shareList) - { - int i; - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_shareList) - { - process->glstates[i]->ref ++; - process->glstates[process->nbGLStates]->textureAllocator = - process->glstates[i]->textureAllocator; - process->glstates[process->nbGLStates]->tabTextures = - process->glstates[i]->tabTextures; - process->glstates[process->nbGLStates]->bufferAllocator = - process->glstates[i]->bufferAllocator; - process->glstates[process->nbGLStates]->tabBuffers = - process->glstates[i]->tabBuffers; - process->glstates[process->nbGLStates]->listAllocator = - process->glstates[i]->listAllocator; - process->glstates[process->nbGLStates]->tabLists = - process->glstates[i]->tabLists; - break; - } - } - } - process->nbGLStates++; -} - -WGLFBConfig* get_pfDescriptor(ProcessStruct* process, int client_pfd) -{ - int i; - int nbtotal = 0; - for(i=0;infbconfig;i++) - { - assert(client_pfd >= 1 + nbtotal); - if (client_pfd <= nbtotal + process->fbconfigs_max[i]) - { - return (WGLFBConfig*) (&process->fbconfigs[i][client_pfd-1 - nbtotal]); - } - nbtotal += process->fbconfigs_max[i]; - } - return 0; -} - -int get_pfdAttrib(PIXELFORMATDESCRIPTOR *ppfd, int attrib, int *value) -{ - int answer = 0; - - switch(attrib) - { - case GLX_FBCONFIG_ID: - answer = (int) ppfd; - break; - - case GLX_AUX_BUFFERS: - answer = ppfd->cAuxBuffers; - break; - - case GLX_STEREO: - answer = (int)False; - break; - - case GLX_ACCUM_RED_SIZE: - answer = ppfd->cAccumRedBits; - break; - - case GLX_ACCUM_GREEN_SIZE: - answer = ppfd->cAccumGreenBits; - break; - - case GLX_ACCUM_BLUE_SIZE: - answer = ppfd->cAccumBlueBits; - break; - - case GLX_ACCUM_ALPHA_SIZE: - answer = ppfd->cAccumAlphaBits; - break; - - case GLX_RENDER_TYPE: - answer = (ppfd->iPixelType == PFD_TYPE_RGBA) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - break; - - case GLX_RGBA: - case GLX_RGBA_TYPE: - answer = (ppfd->iPixelType == PFD_TYPE_RGBA) ? (int)True : (int)False; - break; - - case GLX_COLOR_INDEX_TYPE: - answer = (ppfd->iPixelType == PFD_TYPE_COLORINDEX) ? (int)True : (int)False; - break; - - case GLX_USE_GL: - answer = ((ppfd->dwFlags & PFD_SUPPORT_OPENGL) != 0) ? (int)True : (int)False; - break; - - case GLX_DOUBLEBUFFER: - answer = ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != 0) ? (int)True : (int)False; - break; - - case GLX_DRAWABLE_TYPE: - answer = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; - break; - -#ifdef GLX_CONFIG_CAVEAT - case GLX_CONFIG_CAVEAT: - answer = GLX_NONE; - break; - - case GLX_SLOW_CONFIG: - case GLX_NON_CONFORMANT_CONFIG: - answer = (int)False; - break; -#endif /*GLX_CONFIG_CAVEAT not support*/ - - case GLX_X_RENDERABLE: - answer = 1; - break; - - case GLX_BUFFER_SIZE: - answer = ppfd->cColorBits; - break; - - case GLX_RED_SIZE: - answer = ppfd->cRedBits; - break; - - case GLX_GREEN_SIZE: - answer = ppfd->cGreenBits; - break; - - case GLX_BLUE_SIZE: - answer = ppfd->cBlueBits; - break; - - case GLX_ALPHA_SIZE: - answer = ppfd->cAlphaBits; - break; - - case GLX_DEPTH_SIZE: - answer = ppfd->cDepthBits; - break; - - case GLX_STENCIL_SIZE: - answer = ppfd->cStencilBits; - break; - - case GLX_LEVEL: - answer = 0; - break; - - case GLX_MAX_PBUFFER_WIDTH: - answer = 480; - break; - - case GLX_MAX_PBUFFER_HEIGHT: - answer = 800; - break; - - case GLX_MAX_PBUFFER_PIXELS: - answer = 384000; - break; - - case GLX_VISUAL_ID: - answer = 0; - break; - -#ifdef GLX_X_VISUAL_TYPE - case GLX_X_VISUAL_TYPE: - answer = GLX_NONE; - break; - - case GLX_TRUE_COLOR: - case GLX_DIRECT_COLOR: - case GLX_PSEUDO_COLOR: - case GLX_STATIC_COLOR: - case GLX_GRAY_SCALE: - case GLX_STATIC_GRAY: - answer = False; - break; -#endif /*GLX_X_VISUAL_TYPE not support*/ - - case GLX_SAMPLE_BUFFERS: - case GLX_SAMPLES: - answer = 0; - break; - -#ifdef GLX_TRANSPARENT_TYPE - case GLX_TRANSPARENT_TYPE: - answer = GLX_NONE; - break; - - case GLX_TRANSPARENT_INDEX_VALUE: - case GLX_TRANSPARENT_RED_VALUE: - case GLX_TRANSPARENT_GREEN_VALUE: - case GLX_TRANSPARENT_ALPHA_VALUE: - case GLX_TRANSPARENT_BLUE_VALUE: - answer = GLX_DONT_CARE; - break; - - case GLX_TRANSPARENT_RGB: - case GLX_TRANSPARENT_INDEX: - answer = (int)False; - break; -#endif /*GLX_X_VISUAL_TYPE not support*/ - - case GLX_FLOAT_COMPONENTS_NV: - case GLX_PRESERVED_CONTENTS: - answer = (int)False; - break; - - default: - answer = GLX_BAD_ATTRIBUTE; - - } - - *value = answer; - - return 0; -} - -void* get_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - return process->association_fakecontext_glxcontext[i].value; - } - return NULL; -} - -void set_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext, void* glxcontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakecontext_glxcontext[i].key = fakecontext; - process->association_fakecontext_glxcontext[i].value = glxcontext; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -void get_association_fakecontext_glxwnd(ProcessStruct* process, void* fakecontext, HWND rWnd, HDC rDC) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - { - rWnd = (HWND)process->association_fakecontext_glxcontext[i].hWnd; - rDC = (HDC)process->association_fakecontext_glxcontext[i].cDC; - return; - } - } - - rWnd = NULL; - rDC = NULL; -} - -void set_association_fakecontext_glxwnd(ProcessStruct* process, void* fakecontext, void* glxwnd, void *glxhdc) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakecontext_glxcontext[i].key = fakecontext; - process->association_fakecontext_glxcontext[i].hWnd = glxwnd; - process->association_fakecontext_glxcontext[i].cDC = glxhdc; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -void unset_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - { - memmove(&process->association_fakecontext_glxcontext[i], - &process->association_fakecontext_glxcontext[i+1], - sizeof(Assoc) * (MAX_ASSOC_SIZE - 1 - i)); - return; - } - } -} - -unsigned int get_association_fakecontext_visualid(ProcessStruct* process, void* fakecontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_visual[i].key != NULL;i++) - { - if (process->association_fakecontext_visual[i].key == fakecontext) - return (unsigned int)process->association_fakecontext_visual[i].value; - } - return 0; -} - -void set_association_fakecontext_visualid(ProcessStruct* process, void* fakecontext, unsigned int visualid) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_visual[i].key != NULL;i++) - { - if (process->association_fakecontext_visual[i].key == fakecontext) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakecontext_visual[i].key = fakecontext; - process->association_fakecontext_visual[i].value = (void *)(long)visualid; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -void unset_association_fakecontext_visualid(ProcessStruct* process, void* fakecontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_visual[i].key != NULL;i++) - { - if (process->association_fakecontext_visual[i].key == fakecontext) - { - memmove(&process->association_fakecontext_visual[i], - &process->association_fakecontext_visual[i+1], - sizeof(Assoc) * (MAX_ASSOC_SIZE - 1 - i)); - return; - } - } -} - -HWND get_association_clientdrawable_serverwnd(ProcessStruct* process, HDC clientdrawable) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL; i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == (void*)clientdrawable) - return (HWND)process->association_clientdrawable_serverdrawable[i].hWnd; - } - return (HWND)0; -} - -HDC get_association_clientdrawable_serverdrawable(ProcessStruct* process, HDC clientdrawable) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == (void*)clientdrawable) - return (HDC)process->association_clientdrawable_serverdrawable[i].value; - } - return (HDC)0; -} - -void set_association_clientdrawable_serverwnd(ProcessStruct* process, void* clientdrawable, void* serverwnd) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == clientdrawable) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_clientdrawable_serverdrawable[i].key = clientdrawable; - process->association_clientdrawable_serverdrawable[i].hWnd = serverwnd; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -void set_association_clientdrawable_serverdrawable(ProcessStruct* process, void* clientdrawable, void* serverdrawable) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == clientdrawable) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_clientdrawable_serverdrawable[i].key = clientdrawable; - process->association_clientdrawable_serverdrawable[i].value = serverdrawable; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -void unset_association_clientdrawable_serverdrawable(ProcessStruct* process, void* clientdrawable) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == clientdrawable) - { - memmove(&process->association_clientdrawable_serverdrawable[i], - &process->association_clientdrawable_serverdrawable[i+1], - sizeof(Assoc) * (MAX_ASSOC_SIZE - 1 - i)); - return; - } - } -} - -HWND get_association_fakepbuffer_pbufferwnd(ProcessStruct* process, void* fakepbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL; i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - return (HWND)process->association_fakepbuffer_pbuffer[i].hWnd; - } - return (HWND)0; -} - -void set_association_fakepbuffer_pbufferwnd(ProcessStruct* process, void* fakepbuffer, void* pbufferwnd) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakepbuffer_pbuffer[i].key = fakepbuffer; - process->association_fakepbuffer_pbuffer[i].hWnd = pbufferwnd; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -PbufferInfo *get_association_fakepbuffer_pbinfo(ProcessStruct* process, void* fakepbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL; i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - return (PbufferInfo *)process->association_fakepbuffer_pbuffer[i].cDC; - } - return (PbufferInfo *)0; -} - -void set_association_fakepbuffer_pbinfo(ProcessStruct* process, void* fakepbuffer, void* pbuffer_info) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakepbuffer_pbuffer[i].key = fakepbuffer; - process->association_fakepbuffer_pbuffer[i].cDC= pbuffer_info; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -HDC get_association_fakepbuffer_pbuffer(ProcessStruct* process, void* fakepbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - return (HDC)process->association_fakepbuffer_pbuffer[i].value; - } - return (HDC)NULL; -} - -void set_association_fakepbuffer_pbuffer(ProcessStruct* process, void* fakepbuffer, void* pbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakepbuffer_pbuffer[i].key = fakepbuffer; - process->association_fakepbuffer_pbuffer[i].value = pbuffer; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -void unset_association_fakepbuffer_pbuffer(ProcessStruct* process, void* fakepbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - { - memmove(&process->association_fakepbuffer_pbuffer[i], - &process->association_fakepbuffer_pbuffer[i+1], - sizeof(Assoc) * (MAX_ASSOC_SIZE - 1 - i)); - return; - } - } -} - -static int get_visual_info_from_visual_id( OGLS_Conn *pConn, int visualid, PIXELFORMATDESCRIPTOR* rpfd) -{ - int i; - if( 0 < visualid ) - { - AssocAttribListVisual *tabAssocAttribListVisual = (AssocAttribListVisual *)pConn->tabAssocAttribListVisual ; - for(i=0;inTabAssocAttribListVisual;i++) - { - if ( tabAssocAttribListVisual[i].visualID == visualid) - { - DescribePixelFormat((HDC)pConn->Display, (visualid -1), sizeof( PIXELFORMATDESCRIPTOR), rpfd); - return 1; - } - } - } - - return 0; -} - -static int get_default_visual(Display dpy, PIXELFORMATDESCRIPTOR* rpfd) -{ - HDC hdc; - hdc = (HDC)dpy; - int n; - - if ((n = DescribePixelFormat(hdc, 0, 0, NULL)) > 0) - { - int i; - for (i = 0; i < n; i++) - { - DescribePixelFormat(hdc, i, sizeof( PIXELFORMATDESCRIPTOR), rpfd); - if (!(rpfd->dwFlags & PFD_SUPPORT_OPENGL)) continue; - if (!(rpfd->dwFlags & PFD_DRAW_TO_WINDOW)) continue; - if (!(rpfd->dwFlags & PFD_DOUBLEBUFFER)) continue; - if (rpfd->iPixelType != PFD_TYPE_RGBA) continue; - if (rpfd->cRedBits < 8) continue; - if (rpfd->cGreenBits < 8) continue; - if (rpfd->cBlueBits < 8) continue; - if (rpfd->cAlphaBits < 8) continue; - if (rpfd->cDepthBits < 16) continue; - if (rpfd->cStencilBits < 8) continue; - - break; - } - - if( i < n ) return i + 1; - } - - return 0; -} - -/* Surface?? 위?? Window ????*/ -static HDC create_swindow(OGLS_Conn *pConn, HDC clientdrawable, ProcessStruct* process, int x, int y, int width, int height) -{ - RECT rect; - HWND hWnd; - HDC hDC; - WNDCLASS wc; - LPSTR lpszClassWindowSurface ="WindowSurface"; - - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = lpszClassWindowSurface; - - RegisterClass(&wc); - - rect.left = x; - rect.top = y; - rect.right = width; - rect.bottom = height; - AdjustWindowRect(&rect, (WS_OVERLAPPED |WS_POPUP |WS_SYSMENU), False); - - hWnd = CreateWindow(lpszClassWindowSurface, lpszClassWindowSurface, - (WS_OVERLAPPED |WS_POPUP |WS_SYSMENU ), - rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, - NULL, (HMENU)NULL, NULL, NULL); - - hDC = GetDC(hWnd); - if(hDC) - { - pConn->active_win = hDC; - ShowWindow(hWnd,SW_HIDE); - set_association_clientdrawable_serverwnd(process, (void *) clientdrawable, (void *) hWnd); - } - - return hDC; -} - -/* pbuffer?? 위?? Window ????*/ -static HDC create_pbwindow(void *fakepbuffer, ProcessStruct* process, int x, int y, int width, int height) -{ - RECT rect; - HWND hWnd; - HDC hDC; - WNDCLASS wc; - LPSTR lpszClassWindowSurface ="PBuffer"; - - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = lpszClassWindowSurface; - - RegisterClass(&wc); - - rect.left = x; - rect.top = y; - rect.right = width; - rect.bottom = height; - AdjustWindowRect(&rect, (WS_OVERLAPPED |WS_POPUP |WS_SYSMENU), False); - - hWnd = CreateWindow(lpszClassWindowSurface, lpszClassWindowSurface, - (WS_OVERLAPPED |WS_POPUP |WS_SYSMENU ), - rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, - NULL, (HMENU)NULL, NULL, NULL); - - hDC = GetDC(hWnd); - if(hDC) - { - ShowWindow(hWnd,SW_HIDE); - set_association_fakepbuffer_pbufferwnd(process, fakepbuffer, (void *) hWnd); - } - - return hDC; -} - -/* context?? ˤ?? Dummy Window ????*/ -static HDC create_cwindow(int fake_ctx, ProcessStruct* process, int x, int y, int width, int height) -{ - RECT rect; - HWND hWnd; - HDC hDC; - WNDCLASS wc; - LPSTR lpszClassWindowSurface ="Context"; - - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = lpszClassWindowSurface; - - RegisterClass(&wc); - - rect.left = x; - rect.top = y; - rect.right = width; - rect.bottom = height; - AdjustWindowRect(&rect, (WS_OVERLAPPED |WS_POPUP |WS_SYSMENU), False); - - hWnd = CreateWindow(lpszClassWindowSurface, lpszClassWindowSurface, - (WS_OVERLAPPED |WS_POPUP |WS_SYSMENU ), - rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, - NULL, (HMENU)NULL, NULL, NULL); - - hDC = GetDC(hWnd); - if(hDC) - { - ShowWindow(hWnd,SW_HIDE); - set_association_fakecontext_glxwnd(process, (void *) (long)fake_ctx, (void *)hWnd, (void *)hDC); - } - - return hDC; -} - -static void destroy_glwindow(OGLS_Conn *pConn, HWND hWnd, HDC hDC ) -{ - ReleaseDC( hWnd, hDC ); - DestroyWindow(hWnd); - - /*PostQuitMessage(0);*/ - - if( pConn->active_win == hDC) - pConn->active_win = 0; -} - -static int get_server_texture(ProcessStruct* process, unsigned int client_texture) -{ - unsigned int server_texture = 0; - if (client_texture < 32768) - { - server_texture = process->current_state->tabTextures[client_texture]; - } - else - { - fprintf(stderr, "invalid texture name %d\n", client_texture); - } - return server_texture; -} - -static int get_server_list(ProcessStruct* process, unsigned int client_list) -{ - unsigned int server_list = 0; - if (client_list < 32768) - { - server_list = process->current_state->tabLists[client_list]; - } - else - { - fprintf(stderr, "invalid list name %d\n", client_list); - } - return server_list; -} - -static int get_server_buffer(ProcessStruct* process, unsigned int client_buffer) -{ - unsigned int server_buffer = 0; - if (client_buffer < 32768) - { - server_buffer = process->current_state->tabBuffers[client_buffer]; - } - else - { - fprintf(stderr, "invalid buffer name %d\n", client_buffer); - } - return server_buffer; -} - - -static void do_glClientActiveTextureARB(int texture) -{ - GET_EXT_PTR_NO_FAIL(void, glClientActiveTextureARB, (int)); - if (ptr_func_glClientActiveTextureARB) - { - ptr_func_glClientActiveTextureARB(texture); - } -} - - -/* - * Translate the nth element of list from type to GLuint. - */ - static GLuint -translate_id(GLsizei n, GLenum type, const GLvoid * list) -{ - GLbyte *bptr; - GLubyte *ubptr; - GLshort *sptr; - GLushort *usptr; - GLint *iptr; - GLuint *uiptr; - GLfloat *fptr; - - switch (type) { - case GL_BYTE: - bptr = (GLbyte *) list; - return (GLuint) *(bptr + n); - case GL_UNSIGNED_BYTE: - ubptr = (GLubyte *) list; - return (GLuint) *(ubptr + n); - case GL_SHORT: - sptr = (GLshort *) list; - return (GLuint) *(sptr + n); - case GL_UNSIGNED_SHORT: - usptr = (GLushort *) list; - return (GLuint) *(usptr + n); - case GL_INT: - iptr = (GLint *) list; - return (GLuint) *(iptr + n); - case GL_UNSIGNED_INT: - uiptr = (GLuint *) list; - return (GLuint) *(uiptr + n); - case GL_FLOAT: - fptr = (GLfloat *) list; - return (GLuint) *(fptr + n); - case GL_2_BYTES: - ubptr = ((GLubyte *) list) + 2 * n; - return (GLuint) *ubptr * 256 + (GLuint) * (ubptr + 1); - case GL_3_BYTES: - ubptr = ((GLubyte *) list) + 3 * n; - return (GLuint) * ubptr * 65536 - + (GLuint) *(ubptr + 1) * 256 + (GLuint) * (ubptr + 2); - case GL_4_BYTES: - ubptr = ((GLubyte *) list) + 4 * n; - return (GLuint) *ubptr * 16777216 - + (GLuint) *(ubptr + 1) * 65536 - + (GLuint) *(ubptr + 2) * 256 + (GLuint) * (ubptr + 3); - default: - return 0; - } -} - - -static const char *opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) -{ - char *start; - char *ret; - char *p; - int retlen; - static const char *delim = " \t\n\r/"; - - if (prevbuf) - free(prevbuf); - - if (s) { - *saveptr = s; - } else { - if (!(*saveptr) || !(*n)) - return NULL; - s = *saveptr; - } - - for (; *n && strchr(delim, *s); s++, (*n)--) { - if (*s == '/' && *n > 1) { - if (s[1] == '/') { - do { - s++, (*n)--; - } while (*n > 1 && s[1] != '\n' && s[1] != '\r'); - } else if (s[1] == '*') { - do { - s++, (*n)--; - } while (*n > 2 && (s[1] != '*' || s[2] != '/')); - s++, (*n)--; - } - } - } - - start = s; - for (; *n && *s && !strchr(delim, *s); s++, (*n)--); - if (*n > 0) - s++, (*n)--; - - *saveptr = s; - - retlen = s - start; - ret = malloc(retlen + 1); - p = ret; - - while (retlen > 0) { - if (*start == '/' && retlen > 1) { - if (start[1] == '/') { - do { - start++, retlen--; - } while (retlen > 1 && start[1] != '\n' && start[1] != '\r'); - start++, retlen--; - continue; - } else if (start[1] == '*') { - do { - start++, retlen--; - } while (retlen > 2 && (start[1] != '*' || start[2] != '/')); - start += 3, retlen -= 3; - continue; - } - } - *(p++) = *(start++), retlen--; - } - - *p = 0; - return ret; -} - -static char *do_eglShaderPatch(const char *source, int length, int *patched_len) -{ - char *saveptr = NULL; - char *sp; - char *p = NULL; - - if (!length) - length = strlen(source); - - *patched_len = 0; - int patched_size = length; - char *patched = malloc(patched_size + 1); - - if (!patched) - return NULL; - - p = opengl_strtok(source, &length, &saveptr, NULL); - for (; p; p = opengl_strtok(0, &length, &saveptr, p)) { - if (!strncmp(p, "lowp", 4) || !strncmp(p, "mediump", 7) || !strncmp(p, "highp", 5)) { - continue; - } else if (!strncmp(p, "precision", 9)) { - while ((p = opengl_strtok(0, &length, &saveptr, p)) && !strchr(p, ';')); - } else { - if (!strncmp(p, "gl_MaxVertexUniformVectors", 26)) { - p = "(gl_MaxVertexUniformComponents / 4)"; - } else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28)) { - p = "(gl_MaxFragmentUniformComponents / 4)"; - } else if (!strncmp(p, "gl_MaxVaryingVectors", 20)) { - p = "(gl_MaxVaryingFloats / 4)"; - } - - int new_len = strlen(p); - if (*patched_len + new_len > patched_size) { - patched_size *= 2; - patched = realloc(patched, patched_size + 1); - - if (!patched) - return NULL; - } - - memcpy(patched + *patched_len, p, new_len); - *patched_len += new_len; - } - } - - patched[*patched_len] = 0; - /* check that we don't leave dummy preprocessor lines */ - for (sp = patched; *sp;) { - for (; *sp == ' ' || *sp == '\t'; sp++); - if (!strncmp(sp, "#define", 7)) { - for (p = sp + 7; *p == ' ' || *p == '\t'; p++); - if (*p == '\n' || *p == '\r' || *p == '/') { - memset(sp, 0x20, 7); - } - } - for (; *sp && *sp != '\n' && *sp != '\r'; sp++); - for (; *sp == '\n' || *sp == '\r'; sp++); - } - return patched; -} - -static int -shadersrc_gles_to_gl(GLsizei count, const char** string, char **s, const GLint* length, GLint *l) -{ - int i; - - for(i = 0; i < count; ++i) { - GLint len; - if(length) { - len = length[i]; - if (len < 0) - len = string[i] ? strlen(string[i]) : 0; - } else - len = string[i] ? strlen(string[i]) : 0; - - if(string[i]) { - s[i] = do_eglShaderPatch(string[i], len, &l[i]); - if(!s[i]) { - while(i) - free(s[--i]); - - free(l); - free(s); - return -1; - } - } else { - s[i] = NULL; - l[i] = 0; - } - } - - return 0; -} - - -int do_function_call(OGLS_Conn *pConn, int func_number, int pid, long* args, char* ret_string) -{ - char ret_char = 0; - int ret_int = 0; - const char* ret_str = NULL; - int iProcess; - ProcessStruct* process = NULL; - ProcessStruct *processTab = (ProcessStruct *) pConn->processTab; - - for(iProcess=0;iProcessprocessTab; - if (processTab[iProcess].process_id == pid) - { - process = &processTab[iProcess]; - break; - } - else if (processTab[iProcess].process_id == 0) - { - process = &processTab[iProcess]; - memset(process, 0, sizeof(ProcessStruct)); - process->process_id = pid; - process->internal_num = pConn->last_assigned_internal_num++; - init_gl_state(&process->default_state); - process->current_state = &process->default_state; - break; - } - } - if (process == NULL) - { - fprintf(stderr, "Too many processes !\n"); - return 0; - } - - if (process->internal_num != pConn->last_active_internal_num) - { - wglMakeCurrent(process->current_state->drawable, process->current_state->context); - pConn->last_active_internal_num = process->internal_num; - } - - process->instr_counter++; - if (display_function_call) fprintf(stderr, "[%d]> %s\n", process->instr_counter, tab_opengl_calls_name[func_number]); - -#if defined( _MK_DBG_ ) - //printf(" %s Function(%d) \n", tab_opengl_calls_name[func_number], func_number); -#endif - - switch (func_number) - { - case _init_func: - { - *(int*)args[1] = 1; - break; - } - - case _synchronize_func: - { - ret_int = 1; - break; - } - - case _exit_process_func: - { - int i; - HWND hWnd; - HDC hDC; - HGLRC hRC; - PbufferInfo *pb_info; - - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - hRC = process->association_fakecontext_glxcontext[i].value; - hWnd = (HWND) process->association_fakecontext_glxcontext[i].hWnd; - hDC = (HDC) process->association_fakecontext_glxcontext[i].cDC; - - fprintf(stderr, "Destroy context corresponding to fake_context = %ld\n", - (long)process->association_fakecontext_glxcontext[i].key); - - wglDeleteContext(hRC); - ReleaseDC(hWnd, hDC); - DestroyWindow(hWnd); - } - - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - hWnd = (HWND) process->association_fakepbuffer_pbuffer[i].hWnd; - hDC = (HDC)process->association_fakepbuffer_pbuffer[i].value; - pb_info = (PbufferInfo *) process->association_fakepbuffer_pbuffer[i].cDC; - - fprintf(stderr, "Destroy pbuffer corresponding to client_drawable = %p\n", - process->association_fakepbuffer_pbuffer[i].key); - - free(pb_info->backBuffer); - free(pb_info); - - ReleaseDC(hWnd, hDC); - DestroyWindow(hWnd); - } - - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL; i++) - { - hWnd = (HWND) process->association_clientdrawable_serverdrawable[i].hWnd; - hDC = (HDC)process->association_clientdrawable_serverdrawable[i].value; - - fprintf(stderr, "Destroy window corresponding to client_drawable = %p\n", - process->association_clientdrawable_serverdrawable[i].key); - - ReleaseDC(hWnd, hDC); - DestroyWindow(hWnd); - } - - for(i=0;infbconfig;i++) - { - free(process->fbconfigs[i]); - } - - for(i=0;inbGLStates;i++) - { - destroy_gl_state(process->glstates[i]); - free(process->glstates[i]); - } - - destroy_gl_state(&process->default_state); - free(process->glstates); - - pConn->active_win = 0; - - memmove(&processTab[iProcess], &processTab[iProcess+1], (MAX_HANDLED_PROCESS - 1 - iProcess) * sizeof(ProcessStruct)); - - last_process_id = 0; - - break; - } - - case _changeWindowState_func: - { - HDC client_drawable = (HDC) args[0]; - if (display_function_call) fprintf(stderr, "client_drawable=%p\n", (void*)client_drawable); - - HWND hWnd = get_association_clientdrawable_serverwnd(process, client_drawable); - if (hWnd && (args[1] == IsViewable)) - { - ShowWindow(hWnd, SW_SHOW); - } - - break; - } - - case _moveResizeWindow_func: - { - int* params = (int*)args[1]; - HDC client_drawable = (HDC)args[0]; - if (display_function_call) fprintf(stderr, "client_drawable=%p\n", (void*)client_drawable); - - HWND hWnd = get_association_clientdrawable_serverwnd(process, client_drawable); - if (hWnd) - { - WindowPosStruct pos; - _get_window_pos(hWnd, &pos); - if (!(params[0] == pos.x && params[1] == pos.y && params[2] == pos.width && params[3] == pos.height)) - { - int redim = !(params[2] == pos.width && params[3] == pos.height); - pConn->active_win_x = params[0]; - pConn->active_win_y = params[1]; - - //fprintf(stderr, "old x=%d y=%d width=%d height=%d\n", pos.x, pos.y, pos.width, pos.height); - //fprintf(stderr, "new x=%d y=%d width=%d height=%d\n", params[0], params[1], params[2], params[3]); - - if (redim) - { - MoveWindow(hWnd, params[0], params[1], params[2], params[3], False); - _get_window_pos(hWnd, &pos); - process->currentDrawablePos = pos; - - glViewport(0, 0, pos.width, pos.height); - } - } - } - break; - } - - case _send_cursor_func: - { - fprintf(stderr, "_send_cursor_func not support \n"); - break; - } - - case glXWaitGL_func: - { - ret_int = 0; - break; - } - - case glXWaitX_func: - { - ret_int = 0; - break; - } - - case glXGetFBConfigs_func: - { - ret_int = 0; - - fprintf(stderr, "glXGetFBConfigs not support \n"); - - /*TODO*/ - /*TODO*/ - break; - } - - - case glXChooseFBConfig_func: - case glXChooseFBConfigSGIX_func: - { - HDC hdc; - WGLFBConfig *fbConfigs, *c; - int n; - - if (process->nfbconfig == MAX_FBCONFIG) - { - *(int*)args[3] = 0; - ret_int = 0; - } - else - { - hdc = (HDC) pConn->Display; - - if ((n = DescribePixelFormat(hdc, 0, 0, NULL)) > 0) - { - int i, j; - PIXELFORMATDESCRIPTOR pfd; - for (j = i = 0; i < n; i++) - { - DescribePixelFormat(hdc, i, sizeof pfd, &pfd); - if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue; - if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW)) continue; - if (!(pfd.dwFlags & PFD_DOUBLEBUFFER)) continue; - if (pfd.iPixelType != PFD_TYPE_RGBA) continue; - j++; - } - - c = fbConfigs = (WGLFBConfig *)malloc(sizeof(WGLFBConfig) * j); - - for (i = 0; i < n; i++) { - DescribePixelFormat(hdc, i, sizeof pfd, &pfd); - if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue; - if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW)) continue; - if (!(pfd.dwFlags & PFD_DOUBLEBUFFER)) continue; - if (pfd.iPixelType != PFD_TYPE_RGBA) continue; - - c->visualID = i + 1; - memcpy(&c->pfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR)); -#if defined( _MK_DBG_ ) /* by 19.Nov.2009 */ - printf("Choose Config:0x%p VisualID : %d\n ",c, c->visualID); -#endif - c++; - } - - *(int*)args[3] = j; - - if (fbConfigs) - { - process->fbconfigs[process->nfbconfig] = fbConfigs; - process->fbconfigs_max[process->nfbconfig] = *(int*)args[3]; - process->nfbconfig++; - ret_int = 1 + process->nfbconfig_total; - process->nfbconfig_total += process->fbconfigs_max[process->nfbconfig]; - -#if defined( _MK_DBG_ ) - printf(" DescribePixelFormat Num : %d \n", j); -#endif - } - else - { - ret_int = 0; - *(int*)args[3] = 0; - } - } - else - { - ret_int = 0; - *(int*)args[3] = 0; - printf(" DescribePixelFormat - NULL \n"); - } - - } - - break; - } - - case glXGetFBConfigAttrib_func: - case glXGetFBConfigAttribSGIX_func: - { - int client_pfd = args[1]; - WGLFBConfig *fbConfig = get_pfDescriptor(process, client_pfd); - - ret_int = 0; - - if (fbConfig) - ret_int = get_pfdAttrib(&fbConfig->pfd, args[2], (int*)args[3]); - - break; - } - - case glXGetFBConfigAttrib_extended_func: - { - int client_pfd = args[1]; - int n = args[2]; - int i; - int* attribs = (int*)args[3]; - int* values = (int*)args[4]; - int* res = (int*)args[5]; - WGLFBConfig *fbConfig = get_pfDescriptor(process, client_pfd); - - for(i=0;ipfd, attribs[i], &values[i]); - } - else - { - res[i] = 0; - } - } - break; - } - - case glXGetVisualFromFBConfig_func: - { - int client_pfd = args[1]; - int i; - unsigned int visualid; - WGLFBConfig *fbConfig = get_pfDescriptor(process, client_pfd); - - ret_int = 0; - - if (fbConfig) - { - visualid = fbConfig->visualID; - ret_int = visualid; - - AssocAttribListVisual *tabAssocAttribListVisual = (AssocAttribListVisual *)pConn->tabAssocAttribListVisual ; - for( i = 0; i < pConn->nTabAssocAttribListVisual && (tabAssocAttribListVisual[i].visualID != visualid); i++ ); - - if( i >= pConn->nTabAssocAttribListVisual ) - { - pConn->tabAssocAttribListVisual = tabAssocAttribListVisual = - realloc(tabAssocAttribListVisual, sizeof(AssocAttribListVisual) * (pConn->nTabAssocAttribListVisual+1)); - - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribListLength = 0; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribList = NULL; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].visualID = visualid; - pConn->nTabAssocAttribListVisual++; - } - - if (display_function_call) fprintf(stderr, "visualid = %d\n", ret_int); - } - - break; - } - - case glXCreateNewContext_func: - { - int client_pfd = args[1]; - WGLFBConfig *fbConfig = get_pfDescriptor(process, client_pfd); - ret_int = 0; - -#if defined( _MK_DBG_ ) - printf(" Config 0x%p - client_pfd %d \n", fbConfig, client_pfd); -#endif - - if (fbConfig) - { - int fake_shareList = args[3]; - HGLRC ctxt; - HGLRC shareList = get_association_fakecontext_glxcontext(process, (void*)(long)fake_shareList); - int fake_ctxt = process->next_available_context_number + 1; - HDC hdc = create_cwindow(fake_ctxt, process, 0, 0, 10, 10); - - if(SetPixelFormat(hdc, fbConfig->visualID - 1, NULL)) - { - ctxt = wglCreateContext (hdc); -#if defined( _MK_DBG_ ) - printf("HGLRC 0x%p = wglCreateNewContext(HDC 0x%p) visualID:%d fake_ctx:%d\n", ctxt, hdc, fbConfig->visualID, fake_ctxt); -#endif - - if(ctxt) - { - process->next_available_context_number ++; - set_association_fakecontext_visualid(process, (void*)(long)fake_ctxt, fbConfig->visualID); - set_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt, ctxt); - _create_context(process, ctxt, fake_ctxt, shareList, fake_shareList); - ret_int = fake_ctxt; - } - } - - if( 0 == ret_int ) - { - int i; - - for(i=0; i < MAX_ASSOC_SIZE; i++) - { - if (process->association_fakecontext_glxcontext[i].key == (void *) (long)fake_ctxt) - { - process->association_fakecontext_glxcontext[i].key = NULL; - process->association_fakecontext_glxcontext[i].value = NULL; - process->association_fakecontext_glxcontext[i].hWnd = NULL; - process->association_fakecontext_glxcontext[i].cDC= NULL; - break; - } - } - printf("wglCreateContext Fail - HDC: 0x%p, visual ID: %d, Error : %d \n", hdc, fbConfig->visualID, (unsigned int)GetLastError()); - } - } - - break; - } - - case glXCreateContext_func: - { - int visualid = (int)args[1]; - int fake_shareList = (int)args[2]; - PIXELFORMATDESCRIPTOR pfd; - HGLRC shareList = get_association_fakecontext_glxcontext(process, (void*)(long)fake_shareList); - HGLRC ctxt = 0; - int fake_ctxt = process->next_available_context_number + 1; - HDC hdc = create_cwindow(fake_ctxt, process, 0, 0, 10, 10); - - ret_int = 0; - - if (1 || display_function_call) fprintf(stderr, "visualid=%d, fake_shareList=%d\n", visualid, fake_shareList); - - if(get_visual_info_from_visual_id(pConn, visualid, &pfd)) - { - SetPixelFormat(hdc, visualid - 1, &pfd); - ctxt = wglCreateContext (hdc); - } - else - { - if((visualid = get_default_visual(pConn->Display, &pfd))) - { - SetPixelFormat(hdc, visualid - 1, &pfd); - ctxt = wglCreateContext (hdc); - } - } - - printf("HGLRC 0x%p = wglCreateContext(HDC 0x%p) visualID:%d \n", ctxt, hdc, visualid); - - if (ctxt) - { - process->next_available_context_number ++; - set_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt, ctxt); - set_association_fakecontext_visualid(process, (void*)(long)fake_ctxt, visualid); - _create_context(process, ctxt, fake_ctxt, shareList, fake_shareList); - ret_int = fake_ctxt; - } - - if( 0 == ret_int ) - { - int i; - - for(i=0; i < MAX_ASSOC_SIZE; i++) - { - if (process->association_fakecontext_glxcontext[i].key == (void *) (long)fake_ctxt) - { - process->association_fakecontext_glxcontext[i].key = NULL; - process->association_fakecontext_glxcontext[i].value = NULL; - process->association_fakecontext_glxcontext[i].hWnd = NULL; - process->association_fakecontext_glxcontext[i].cDC= NULL; - break; - } - } - printf("wglCreateContext Fail - HDC: 0x%p, visual ID: %d, Error : %d \n", hdc, visualid, (unsigned int)GetLastError()); - } - - break; - } - - case glXMakeCurrent_func: - { - int i; - HDC client_drawable = (HDC)args[1]; - HDC drawable = 0; - PIXELFORMATDESCRIPTOR pfd; - int fake_ctxt = args[2]; - unsigned int visualid = 0; - - if (display_function_call) fprintf(stderr, "client_drawable=%p fake_ctx=%d\n", (void*)client_drawable, fake_ctxt); - - if (client_drawable == 0 && fake_ctxt == 0) - { - ret_int = wglMakeCurrent(NULL, NULL); - ret_int = 1; - process->current_state = &process->default_state; - } - else if ((drawable = (HDC)get_association_fakepbuffer_pbuffer(process, (void*)client_drawable))) - { - HGLRC ctxt = (HGLRC)get_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - PbufferInfo *pb_info = get_association_fakepbuffer_pbinfo(process, (void*)client_drawable); - - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%d) (*)!\n", fake_ctxt); - ret_int = 0; - } - else - { - if( pb_info ) - { - pb_info->context = ctxt; - } - - visualid = get_association_fakecontext_visualid(process, (void*)(long)fake_ctxt); - if(visualid) - { - /*DescribePixelFormat((HDC)dpy, (visualid -1), sizeof( PIXELFORMATDESCRIPTOR), &pfd);*/ - - if(SetPixelFormat(drawable, visualid - 1, &pfd)) - { - ret_int = wglMakeCurrent(drawable, ctxt); -#if defined( _MK_DBG_ ) - printf("%d = wglMakeCurrentPBuffer(HDC 0x%p, HGLRC 0x%p) - visualID:%d client_drawable:0x%p\n", ret_int, drawable, ctxt, visualid, client_drawable); -#endif - } - else - { - fprintf(stderr, "SetPixelFormat Error......\n"); - ret_int = 0; - } - - } - else - { - ret_int = 0; - } - } - } - else - { - HGLRC ctxt = (HGLRC)get_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%d)!\n", fake_ctxt); - ret_int = 0; - } - else - { - visualid = get_association_fakecontext_visualid(process, (void*)(long)fake_ctxt); - - if( visualid == 0 ) - { - visualid = get_default_visual(pConn->Display, &pfd); - } - - drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - if (drawable == 0) - { - - drawable = create_swindow(pConn, client_drawable, process, 0, 0, 480, 800); - set_association_clientdrawable_serverdrawable(process, (void*)client_drawable, (void*)drawable); - } - - /*DescribePixelFormat((HDC)dpy, (visualid -1), sizeof( PIXELFORMATDESCRIPTOR), &pfd);*/ - if(SetPixelFormat(drawable, visualid - 1, &pfd)) - { - ret_int = wglMakeCurrent(drawable, ctxt); -#if defined( _MK_DBG_ ) - printf("%d = wglMakeCurrent(HDC 0x%p, HGLRC 0x%p) - visualID:%d client_drawable:0x%p\n", ret_int, drawable, ctxt, visualid, client_drawable); -#endif - } - else - { - fprintf(stderr, "SetPixelFormat Error......\n"); - ret_int = 0; - } - } - } - - if (ret_int) - { - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_ctxt) - { - process->current_state = process->glstates[i]; /* HACK !!! REMOVE */ - process->current_state->drawable = drawable; - break; - } - } - } - break; - } - - case glXGetConfig_func: - { - int visualid = args[1]; - PIXELFORMATDESCRIPTOR pfd; - - if (visualid) - { - if( get_visual_info_from_visual_id(pConn, visualid, &pfd)) - { - ret_int = get_pfdAttrib(&pfd, args[2], (int*)args[3]); - } - else - { - if( get_default_visual(pConn->Display, &pfd)) - ret_int = get_pfdAttrib(&pfd, args[2], (int*)args[3]); - else - ret_int = GLX_BAD_VISUAL; - } - } - else - { - if( get_default_visual(pConn->Display, &pfd)) - ret_int = get_pfdAttrib(&pfd, args[2], (int*)args[3]); - else - ret_int = GLX_BAD_VISUAL; - } - - break; - } - - case glXChooseVisual_func: - { - PIXELFORMATDESCRIPTOR pfd; - unsigned int visualid = 0; - AssocAttribListVisual *tabAssocAttribListVisual = (AssocAttribListVisual *)pConn->tabAssocAttribListVisual ; - - int i; - - if ((int*)args[2] == NULL) - ret_int = 0; - - visualid = get_default_visual(pConn->Display, &pfd); - - for( i = 0; i < pConn->nTabAssocAttribListVisual && (tabAssocAttribListVisual[i].visualID != visualid); i++ ); - - if( i >= pConn->nTabAssocAttribListVisual ) { - pConn->tabAssocAttribListVisual = tabAssocAttribListVisual = - realloc(tabAssocAttribListVisual, sizeof(AssocAttribListVisual) * (pConn->nTabAssocAttribListVisual+1)); - - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribListLength = 0; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribList = NULL; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].visualID = i; - pConn->nTabAssocAttribListVisual++; - } - - ret_int = visualid; - break; - } - - case glXDestroyWindow_func: - { - int i; - HDC client_drawable = (HDC)args[1]; - HDC drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - HWND hWnd = get_association_clientdrawable_serverwnd( process, client_drawable); - - if (display_function_call) fprintf(stderr, "client_drawable=%p\n", (void*)client_drawable); - - if( drawable && hWnd ) - { - destroy_glwindow(pConn, hWnd, drawable); - -#if defined( _MK_DBG_ ) - printf("DestoryWindw( HWND 0x%p, HDC 0x%p) Client Drawable 0x%p\n", hWnd, drawable, client_drawable); -#endif - - unset_association_clientdrawable_serverdrawable(process, (void *) (long)client_drawable); - - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->drawable == drawable) - { - process->glstates[i]->drawable = 0; - } - } - - if( process->current_state->drawable == drawable ) - process->current_state = &process->default_state; - } - - break; - } - - - case glXDestroyContext_func: - { - int fake_ctxt = (int)args[1]; - HWND hWnd = NULL; - HDC hdc = NULL; - HGLRC ctxt = (HGLRC)get_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - - if (display_function_call) fprintf(stderr, "fake_ctxt=%d\n", fake_ctxt); - - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%p) !\n", (void*)(long)fake_ctxt); - } - else - { - int i; - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_ctxt) - { - if (ctxt == process->current_state->context) - process->current_state = &process->default_state; - - int fake_shareList = process->glstates[i]->fake_shareList; - process->glstates[i]->ref --; - if (process->glstates[i]->ref == 0) - { - fprintf(stderr, "destroy_gl_state fake_ctxt = %d\n", process->glstates[i]->fake_ctxt); - destroy_gl_state(process->glstates[i]); - free(process->glstates[i]); - memmove(&process->glstates[i], &process->glstates[i+1], (process->nbGLStates-i-1) * sizeof(GLState*)); - process->nbGLStates--; - } - - if (fake_shareList) - { - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_shareList) - { - process->glstates[i]->ref --; - if (process->glstates[i]->ref == 0) - { - fprintf(stderr, "destroy_gl_state fake_ctxt = %d\n", process->glstates[i]->fake_ctxt); - destroy_gl_state(process->glstates[i]); - free(process->glstates[i]); - memmove(&process->glstates[i], &process->glstates[i+1], (process->nbGLStates-i-1) * sizeof(GLState*)); - process->nbGLStates--; - } - break; - } - } - } - - wglDeleteContext(ctxt); - - get_association_fakecontext_glxwnd(process, (void*)(long)fake_ctxt, hWnd, hdc); - destroy_glwindow(pConn, hWnd, hdc); - - unset_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - unset_association_fakecontext_visualid(process, (void*)(long)fake_ctxt); - -#if defined( _MK_DBG_ ) - printf("Destory Context Window ( WHND 0x%p, HRC 0x%p)", hWnd, hdc); - printf("wglDestroyContext(HGLRC 0x%p) - fake context : %d\n", ctxt, fake_ctxt); -#endif - break; - } - } - } - break; - } - - case glXGetProcAddress_fake_func: - { - char *fun_name = (char*)args[0]; - if (display_function_call) fprintf(stderr, "%s\n", fun_name); - - ret_int = 1; - break; - } - - case glXGetProcAddress_global_fake_func: - { - int nbElts = args[0]; - char* huge_buffer = (char*)args[1]; - char* result = (char*)args[2]; - int i; - for(i=0;i> 8; - *pMinorVersion = rVersion & 0x000000FF; - - -#if defined( _MK_DBG_ ) /* by 20.Nov.2009 */ - printf(" Major Version : %d - Minor Version : %d \n",*pMajorVersion, *pMinorVersion); -#endif - break; - } - - case glXQueryExtensionsString_func: - { - - fprintf(stderr, "glXQueryExtensionsString not support (Current WIN32 System)\n"); - ret_str = NULL; - break; - } - - case glXGetClientString_func: - { - static char *ventor = "support WGL of Microsoft Corporation"; - ret_str = ventor;//glXGetClientString(dpy, args[1]); - break; - } - - case glXQueryServerString_func: - { - static char *ventor = "support WGL of Microsoft Corporation"; - ret_str = ventor; //glXQueryServerString(dpy, 0, args[2]); - break; - } - - case glXGetScreenDriver_func: - { - fprintf(stderr, "glXGetScreenDriver not support (Current WIN32 System)\n"); - ret_str = NULL; - break; - } - - case glXGetDriverConfig_func: - { - fprintf(stderr, "glXGetDriverConfig not support (Current WIN32 System)\n"); - ret_str = NULL; - break; - } - - case glXCreatePbuffer_func: - { - int client_fbconfig = args[1]; - int pb_width = 0, pb_height = 0; - int *attrib_list = (int*)args[2]; - int fake_pbuffer = process->next_available_pbuffer_number + 1; - HDC pbuffer; - WGLFBConfig *fbconfig = get_pfDescriptor(process, client_fbconfig); - - ret_int = 0; - - while (attrib_list && *attrib_list != GLX_NONE) { - switch (*attrib_list++) { - case GLX_WIDTH: - pb_width = *attrib_list++; - break; - - case GLX_HEIGHT: - pb_height = *attrib_list++; - break; - - default: - break; - } - } - - if(fbconfig) - { - pbuffer = create_pbwindow((void *) ( fake_pbuffer), process, 0, 0, pb_width, pb_height); - -#if defined( _MK_DBG_ ) - printf(" pbuffer 0x%p = Create_pbwindow( fakebuffer : %d , width : %d, height : %d\n", pbuffer, fake_pbuffer, pb_width, pb_height); -#endif - - if (pbuffer) - { - PbufferInfo *pb_info = (PbufferInfo *)malloc( sizeof(PbufferInfo) ); - memset((void *) pb_info, 0, sizeof(PbufferInfo)); - - process->next_available_pbuffer_number ++; - set_association_fakepbuffer_pbuffer(process, (void*)(long)fake_pbuffer, (void*)pbuffer); - ret_int = fake_pbuffer; - - pb_info->width = pb_width; - pb_info->height = pb_height; - pb_info->colorFormat = GLX_RGBA; - get_pfdAttrib(&fbconfig->pfd, GLX_BUFFER_SIZE, &pb_info->colorBits); - - pb_info->backBuffer = malloc( pb_width * pb_height * sizeof(int)); - set_association_fakepbuffer_pbinfo( process, (void *)(long)fake_pbuffer, (void *) pb_info ); - } - } - - break; - } - - case glXCreateGLXPbufferSGIX_func: - { - int client_fbconfig = args[1]; - int pb_width = 0, pb_height = 0; - int fake_pbuffer = process->next_available_pbuffer_number + 1; - HDC pbuffer; - WGLFBConfig *fbconfig = get_pfDescriptor(process, client_fbconfig); - - ret_int = 0; - - pb_width = args[2]; - pb_height = args[3]; - - if(fbconfig) - { - pbuffer = create_pbwindow((void *) ( fake_pbuffer), process, 0, 0, pb_width, pb_height); -#if defined( _MK_DBG_ ) - printf(" pbuffer 0x%p = Create_pbwindow( fakebuffer : %d , width : %d, height : %d\n", pbuffer, fake_pbuffer, pb_width, pb_height); -#endif - if (pbuffer) - { - PbufferInfo *pb_info = (PbufferInfo *)malloc( sizeof(PbufferInfo) ); - memset((void *) pb_info, 0, sizeof(PbufferInfo)); - - process->next_available_pbuffer_number ++; - set_association_fakepbuffer_pbuffer(process, (void*)(long)fake_pbuffer, (void*)pbuffer); - ret_int = fake_pbuffer; - - pb_info->width = pb_width; - pb_info->height = pb_height; - pb_info->colorFormat = GLX_RGBA; - get_pfdAttrib(&fbconfig->pfd, GLX_BUFFER_SIZE, &pb_info->colorBits); - - pb_info->backBuffer = malloc( pb_width * pb_height * sizeof(int)); - set_association_fakepbuffer_pbinfo( process, (void *)(long)fake_pbuffer, (void *) pb_info ); - } - } - - break; - } - - case glXDestroyPbuffer_func: - case glXDestroyGLXPbufferSGIX_func: - { - HDC fakepbuffer = (HDC)args[1]; - HDC pbuffer = get_association_fakepbuffer_pbuffer(process, (void *)fakepbuffer); - HWND hWnd = get_association_fakepbuffer_pbufferwnd( process, (void *)fakepbuffer); - PbufferInfo *pb_info = get_association_fakepbuffer_pbinfo(process, (void *) fakepbuffer); - - if( pbuffer && hWnd ) - { - if(pb_info) - { - free(pb_info->backBuffer); - free(pb_info); - } - - destroy_glwindow(pConn, hWnd, pbuffer); - -#if defined( _MK_DBG_ ) - printf("DestoryPbuffer( HWND 0x%p, HDC 0x%p) fake pbuffer 0x%p\n", hWnd, pbuffer, fakepbuffer); -#endif - - unset_association_fakepbuffer_pbuffer(process, (void *) (long)fakepbuffer); - } - - break; - } - - case glXBindTexImageARB_func: - case glXBindTexImageATI_func: - { - HGLRC pb_context, cur_context; - HDC pb_drawable, cur_drawable; - int fake_pbuffer = (int)args[1]; - PbufferInfo *pb_info = get_association_fakepbuffer_pbinfo(process, (void *) (long) fake_pbuffer); - - ret_int = 0; - - if( pb_info ) - { - - pb_context = pb_info->context; - pb_drawable =get_association_fakepbuffer_pbuffer(process, (void *) (long) fake_pbuffer); - - if( pb_context && pb_drawable ) - { - cur_context = wglGetCurrentContext( ); - cur_drawable = wglGetCurrentDC( ); - - wglMakeCurrent(pb_drawable, pb_context); - glReadPixels(0, 0, pb_info->width, pb_info->height, pb_info->colorFormat, GL_UNSIGNED_BYTE, pb_info->backBuffer); - wglMakeCurrent(cur_drawable, cur_context); - - glTexImage2D(GL_TEXTURE_2D, 0, pb_info->colorFormat, pb_info->width, pb_info->height, - 0, pb_info->colorFormat, GL_UNSIGNED_BYTE, pb_info->backBuffer); - ret_int = 1; - } - else - { - fprintf(stderr, "glXBindTexImage Error - pbuffer Null...\n"); - } - - } - else - { - fprintf(stderr, "glXBindTexImage Error - pbuffer information Null...\n"); - } - - - /*TODO*/ - /*TODO*/ - break; - } - - case glXReleaseTexImageARB_func: - case glXReleaseTexImageATI_func: - { - int fake_pbuffer = (int)args[1]; - HDC pbuffer = get_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - PbufferInfo *pb_info = get_association_fakepbuffer_pbinfo(process, (void*)fake_pbuffer); - - ret_int = 0; - - if ( pbuffer ) - { - if(pb_info) - { - glTexImage2D(GL_TEXTURE_2D, 0, pb_info->colorFormat, pb_info->width, pb_info->height, 0, pb_info->colorFormat, GL_UNSIGNED_BYTE, NULL); - ret_int = 1; - } - else - { - fprintf(stderr, "glXReleaseTexImageARB : invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - } - } - else - { - fprintf(stderr, "glXReleaseTexImageARB : invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - } - - break; - } - - case glXQueryContext_func: - { - ret_int = 0; - fprintf(stderr, "glXCreateGLXPbufferSGIX not support (Current WIN32 System)\n"); - break; - } - - case glXQueryDrawable_func: - { - fprintf(stderr, "glXQueryDrawable not support \n"); - - /*TODO*/ - /*TODO*/ - break; - } - - case glXQueryGLXPbufferSGIX_func: - { - ret_int = 0; - - fprintf(stderr, "glXCreateGLXPbufferSGIX not support (Current WIN32 System)\n"); - break; - } - - case glXCreateContextWithConfigSGIX_func: - { - ret_int = 0; - - fprintf(stderr, "glXCreateContextWithConfigSGIX not support (Current WIN32 System)\n"); - break; - } - - case glXSwapIntervalSGI_func: - { - ret_int = 0; - - fprintf(stderr, "glXSwapIntervalSGI not support (Current WIN32 System)\n"); - break; - } - - case glXCopyContext_func: - { - HGLRC fake_src_ctxt = (HGLRC)args[1]; - HGLRC fake_dst_ctxt = (HGLRC)args[2]; - - if (display_function_call) fprintf(stderr, "fake_src_ctxt=%p, fake_dst_ctxt=%p\n", fake_src_ctxt, fake_dst_ctxt); - - fprintf(stderr, "glXCopyContext not support (Current WIN32 System)\n"); - break; - } - - case glXIsDirect_func: - { - ret_char = False; - fprintf(stderr, "glXCopyContext not support (Current WIN32 System)\n"); - break; - } - - case glGetString_func: - { - ret_str = (char*)glGetString(args[0]); - break; - } - - /* Begin of texture stuff */ - case glBindTexture_func: - case glBindTextureEXT_func: - { - int target = args[0]; - unsigned int client_texture = args[1]; - unsigned int server_texture; - - if (client_texture == 0) - { - glBindTexture(target, 0); - } - else - { - alloc_value(process->current_state->textureAllocator, client_texture); - server_texture = process->current_state->tabTextures[client_texture]; - if (server_texture == 0) - { - glGenTextures(1, &server_texture); - process->current_state->tabTextures[client_texture] = server_texture; - } - glBindTexture(target, server_texture); - } - break; - } - - case glGenTextures_fake_func: - { - //GET_EXT_PTR(void, glGenTextures, (GLsizei n, GLuint *textures)); - int i; - int n = args[0]; - unsigned int* clientTabTextures = malloc(n * sizeof(int)); - unsigned int* serverTabTextures = malloc(n * sizeof(int)); - - alloc_range(process->current_state->textureAllocator, n, clientTabTextures); - - glGenTextures(n, serverTabTextures); - for(i=0;icurrent_state->tabTextures[clientTabTextures[i]] = serverTabTextures[i]; - } - - free(clientTabTextures); - free(serverTabTextures); - break; - } - - case glDeleteTextures_func: - { - //GET_EXT_PTR(void, glDeleteTextures, (GLsizei n, const GLuint *textures)); - int i; - int n = args[0]; - unsigned int* clientTabTextures = (unsigned int*)args[1]; - - delete_range(process->current_state->textureAllocator, n, clientTabTextures); - - unsigned int* serverTabTextures = malloc(n * sizeof(int)); - for(i=0;icurrent_state->tabTextures[clientTabTextures[i]] = 0; - } - free(serverTabTextures); - break; - } - - case glPrioritizeTextures_func: - { - GET_EXT_PTR(void, glPrioritizeTextures, (GLsizei n, const GLuint *textures, const GLclampf *priorities)); - - int i; - int n = args[0]; - unsigned int* textures = (unsigned int*)args[1]; - for(i=0;icurrent_state->tabLists[first_client + i] = 0; - } - delete_consecutive_values(process->current_state->listAllocator, first_client, n); - break; - } - - case glGenLists_fake_func: - { - int i; - int n = args[0]; - unsigned int server_first = glGenLists(n); - if (server_first) - { - unsigned int client_first = alloc_range(process->current_state->listAllocator, n, NULL); - for(i=0;icurrent_state->tabLists[client_first + i] = server_first + i; - } - } - break; - } - - case glNewList_func: - { - unsigned int client_list = args[0]; - int mode = args[1]; - alloc_value(process->current_state->listAllocator, client_list); - unsigned int server_list = get_server_list(process, client_list); - if (server_list == 0) - { - server_list = glGenLists(1); - process->current_state->tabLists[client_list] = server_list; - } - glNewList(server_list, mode); - break; - } - - case glCallList_func: - { - unsigned int client_list = args[0]; - unsigned int server_list = get_server_list(process, client_list); - glCallList(server_list); - break; - } - - case glCallLists_func: - { - int i; - int n = args[0]; - int type = args[1]; - const GLvoid* lists = (const GLvoid*)args[2]; - int* new_lists = malloc(sizeof(int) * n); - for(i=0;icurrent_state->bufferAllocator, n, clientTabBuffers); - - ptr_func_glGenBuffersARB(n, serverTabBuffers); - for(i=0;icurrent_state->tabBuffers[clientTabBuffers[i]] = serverTabBuffers[i]; - } - - free(clientTabBuffers); - free(serverTabBuffers); - break; - } - - - case glDeleteBuffersARB_func: - { - GET_EXT_PTR(void, glDeleteBuffersARB, (int,int*)); - int i; - int n = args[0]; - unsigned int* clientTabBuffers = (unsigned int*)args[1]; - - delete_range(process->current_state->bufferAllocator, n, clientTabBuffers); - - int* serverTabBuffers = malloc(n * sizeof(int)); - for(i=0;icurrent_state->tabBuffers[clientTabBuffers[i]] = 0; - } - free(serverTabBuffers); - break; - } - - case glIsBufferARB_func: - { - GET_EXT_PTR(int, glIsBufferARB, (int)); - unsigned int client_buffer = args[0]; - unsigned int server_buffer = get_server_buffer(process, client_buffer); - if (server_buffer) - ret_int = ptr_func_glIsBufferARB(server_buffer); - else - ret_int = 0; - break; - } - /* Endo of buffer stuff */ - - case glShaderSourceARB_fake_func: - { - GET_EXT_PTR(void, glShaderSourceARB, (int,int,char**,void*)); - int size = args[1]; - int i; - int acc_length = 0; - GLcharARB** tab_prog = malloc(size * sizeof(GLcharARB*)); - int* tab_length = (int*)args[3]; - for(i=0;icurrent_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, (void*)args[5], bytes_size); - /*fprintf(stderr, "glVertexPointer_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - glVertexPointer(size, type, stride, process->current_state->vertexPointer); - break; - } - - case glNormalPointer_fake_func: - { - int offset = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->normalPointerSize = MAX(process->current_state->normalPointerSize, offset + bytes_size); - process->current_state->normalPointer = realloc(process->current_state->normalPointer, process->current_state->normalPointerSize); - memcpy(process->current_state->normalPointer + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glNormalPointer_fake_func type=%d, stride=%d, byte_size=%d\n", type, stride, bytes_size); - glNormalPointer(type, stride, process->current_state->normalPointer); - break; - } - - case glIndexPointer_fake_func: - { - int offset = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->indexPointerSize = MAX(process->current_state->indexPointerSize, offset + bytes_size); - process->current_state->indexPointer = realloc(process->current_state->indexPointer, process->current_state->indexPointerSize); - memcpy(process->current_state->indexPointer + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glIndexPointer_fake_func type=%d, stride=%d, byte_size=%d\n", type, stride, bytes_size); - glIndexPointer(type, stride, process->current_state->indexPointer); - break; - } - - case glEdgeFlagPointer_fake_func: - { - int offset = args[0]; - int stride = args[1]; - int bytes_size = args[2]; - process->current_state->edgeFlagPointerSize = MAX(process->current_state->edgeFlagPointerSize, offset + bytes_size); - process->current_state->edgeFlagPointer = realloc(process->current_state->edgeFlagPointer, process->current_state->edgeFlagPointerSize); - memcpy(process->current_state->edgeFlagPointer + offset, (void*)args[3], bytes_size ); - //fprintf(stderr, "glEdgeFlagPointer_fake_func stride = %d, bytes_size=%d\n", stride, bytes_size); - glEdgeFlagPointer(stride, process->current_state->edgeFlagPointer); - break; - } - - case glVertexAttribPointerARB_fake_func: - { - GET_EXT_PTR(void, glVertexAttribPointerARB, (int,int,int,int,int,void*)); - int offset = args[0]; - int index = args[1]; - int size = args[2]; - int type = args[3]; - int normalized = args[4]; - int stride = args[5]; - int bytes_size = args[6]; - process->current_state->vertexAttribPointerSize[index] = MAX(process->current_state->vertexAttribPointerSize[index], offset + bytes_size); - process->current_state->vertexAttribPointer[index] = realloc(process->current_state->vertexAttribPointer[index], - process->current_state->vertexAttribPointerSize[index]); - memcpy(process->current_state->vertexAttribPointer[index] + offset, (void*)args[7], bytes_size); - ptr_func_glVertexAttribPointerARB(index, size, type, normalized, stride, - process->current_state->vertexAttribPointer[index]); - break; - } - - case glVertexAttribPointerNV_fake_func: - { - GET_EXT_PTR(void, glVertexAttribPointerNV, (int,int,int,int,void*)); - int offset = args[0]; - int index = args[1]; - int size = args[2]; - int type = args[3]; - int stride = args[4]; - int bytes_size = args[5]; - process->current_state->vertexAttribPointerNVSize[index] = MAX(process->current_state->vertexAttribPointerNVSize[index], offset + bytes_size); - process->current_state->vertexAttribPointerNV[index] = realloc(process->current_state->vertexAttribPointerNV[index], - process->current_state->vertexAttribPointerNVSize[index]); - memcpy(process->current_state->vertexAttribPointerNV[index] + offset, (void*)args[6], bytes_size); - ptr_func_glVertexAttribPointerNV(index, size, type, stride, - process->current_state->vertexAttribPointerNV[index]); - break; - } - - case glColorPointer_fake_func: - { - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->colorPointerSize = MAX(process->current_state->colorPointerSize, offset + bytes_size); - process->current_state->colorPointer = realloc(process->current_state->colorPointer, process->current_state->colorPointerSize); - memcpy(process->current_state->colorPointer + offset, (void*)args[5], bytes_size); - //fprintf(stderr, "glColorPointer_fake_func bytes_size = %d\n", bytes_size); - glColorPointer(size, type, stride, process->current_state->colorPointer); - - break; - } - - case glSecondaryColorPointer_fake_func: - { - GET_EXT_PTR(void, glSecondaryColorPointer, (int,int,int,void*)); - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->secondaryColorPointerSize = MAX(process->current_state->secondaryColorPointerSize, offset + bytes_size); - process->current_state->secondaryColorPointer = realloc(process->current_state->secondaryColorPointer, process->current_state->secondaryColorPointerSize); - memcpy(process->current_state->secondaryColorPointer + offset, (void*)args[5], bytes_size); - //fprintf(stderr, "glSecondaryColorPointer_fake_func bytes_size = %d\n", bytes_size); - ptr_func_glSecondaryColorPointer(size, type, stride, process->current_state->secondaryColorPointer); - - break; - } - - case glPushClientAttrib_func: - { - int mask = args[0]; - if (process->current_state->clientStateSp < MAX_CLIENT_STATE_STACK_SIZE) - { - process->current_state->clientStateStack[process->current_state->clientStateSp].mask = mask; - if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) - { - process->current_state->clientStateStack[process->current_state->clientStateSp].activeTextureIndex = - process->current_state->activeTextureIndex; - } - process->current_state->clientStateSp++; - } - glPushClientAttrib(mask); - break; - } - - case glPopClientAttrib_func: - { - if (process->current_state->clientStateSp > 0) - { - process->current_state->clientStateSp--; - if (process->current_state->clientStateStack[process->current_state->clientStateSp].mask & GL_CLIENT_VERTEX_ARRAY_BIT) - { - process->current_state->activeTextureIndex = - process->current_state->clientStateStack[process->current_state->clientStateSp].activeTextureIndex; - } - } - glPopClientAttrib(); - break; - } - - case glClientActiveTexture_func: - case glClientActiveTextureARB_func: - { - int activeTexture = args[0]; - process->current_state->activeTextureIndex = activeTexture - GL_TEXTURE0_ARB; - do_glClientActiveTextureARB(activeTexture); - break; - } - - case glTexCoordPointer_fake_func: - { - int offset = args[0]; - int index = args[1]; - int size = args[2]; - int type = args[3]; - int stride = args[4]; - int bytes_size = args[5]; - process->current_state->texCoordPointerSize[index] = MAX(process->current_state->texCoordPointerSize[index], offset + bytes_size); - process->current_state->texCoordPointer[index] = realloc(process->current_state->texCoordPointer[index], process->current_state->texCoordPointerSize[index]); - memcpy(process->current_state->texCoordPointer[index] + offset, (void*)args[6], bytes_size); - /*fprintf(stderr, "glTexCoordPointer_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + index); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[index]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glWeightPointerARB_fake_func: - { - GET_EXT_PTR(void, glWeightPointerARB, (int,int,int,void*)); - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->weightPointerSize = MAX(process->current_state->weightPointerSize, offset + bytes_size); - process->current_state->weightPointer = realloc(process->current_state->weightPointer, process->current_state->weightPointerSize); - memcpy(process->current_state->weightPointer + offset, (void*)args[5], bytes_size); - /*fprintf(stderr, "glWeightPointerARB_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - ptr_func_glWeightPointerARB(size, type, stride, process->current_state->weightPointer); - break; - } - - case glMatrixIndexPointerARB_fake_func: - { - GET_EXT_PTR(void, glMatrixIndexPointerARB, (int,int,int,void*)); - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->matrixIndexPointerSize = MAX(process->current_state->matrixIndexPointerSize, offset + bytes_size); - process->current_state->matrixIndexPointer = realloc(process->current_state->matrixIndexPointer, process->current_state->matrixIndexPointerSize); - memcpy(process->current_state->matrixIndexPointer + offset, (void*)args[5], bytes_size); - /*fprintf(stderr, "glMatrixIndexPointerARB_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - ptr_func_glMatrixIndexPointerARB(size, type, stride, process->current_state->matrixIndexPointer); - break; - } - - case glFogCoordPointer_fake_func: - { - GET_EXT_PTR(void, glFogCoordPointer, (int,int,void*)); - int offset = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->fogCoordPointerSize = MAX(process->current_state->fogCoordPointerSize, offset + bytes_size); - process->current_state->fogCoordPointer = realloc(process->current_state->fogCoordPointer, process->current_state->fogCoordPointerSize); - memcpy(process->current_state->fogCoordPointer + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glFogCoordPointer_fake_func type=%d, stride=%d, byte_size=%d\n", type, stride, bytes_size); - ptr_func_glFogCoordPointer(type, stride, process->current_state->fogCoordPointer); - break; - } - - case glVariantPointerEXT_fake_func: - { - GET_EXT_PTR(void, glVariantPointerEXT, (int,int,int,void*)); - int offset = args[0]; - int id = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->variantPointerEXTSize[id] = MAX(process->current_state->variantPointerEXTSize[id], offset + bytes_size); - process->current_state->variantPointerEXT[id] = realloc(process->current_state->variantPointerEXT[id], process->current_state->variantPointerEXTSize[id]); - memcpy(process->current_state->variantPointerEXT[id] + offset, (void*)args[5], bytes_size); - //fprintf(stderr, "glVariantPointerEXT_fake_func[%d] type=%d, stride=%d, byte_size=%d\n", id, type, stride, bytes_size); - ptr_func_glVariantPointerEXT(id, type, stride, process->current_state->variantPointerEXT[id]); - break; - } - - case glInterleavedArrays_fake_func: - { - GET_EXT_PTR(void, glInterleavedArrays, (int,int,void*)); - int offset = args[0]; - int format = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->interleavedArraysSize = MAX(process->current_state->interleavedArraysSize, offset + bytes_size); - process->current_state->interleavedArrays = realloc(process->current_state->interleavedArrays, process->current_state->interleavedArraysSize); - memcpy(process->current_state->interleavedArrays + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glInterleavedArrays_fake_func format=%d, stride=%d, byte_size=%d\n", format, stride, bytes_size); - ptr_func_glInterleavedArrays(format, stride, process->current_state->interleavedArrays); - break; - } - - case glElementPointerATI_fake_func: - { - GET_EXT_PTR(void, glElementPointerATI, (int,void*)); - int type = args[0]; - int bytes_size = args[1]; - process->current_state->elementPointerATISize = bytes_size; - process->current_state->elementPointerATI = realloc(process->current_state->elementPointerATI, process->current_state->elementPointerATISize); - memcpy(process->current_state->elementPointerATI, (void*)args[2], bytes_size); - //fprintf(stderr, "glElementPointerATI_fake_func type=%d, byte_size=%d\n", type, bytes_size); - ptr_func_glElementPointerATI(type, process->current_state->elementPointerATI); - break; - } - - case glTexCoordPointer01_fake_func: - { - int size = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->texCoordPointerSize[0] = bytes_size; - process->current_state->texCoordPointer[0] = realloc(process->current_state->texCoordPointer[0], bytes_size); - memcpy(process->current_state->texCoordPointer[0], (void*)args[4], bytes_size); - /*fprintf(stderr, "glTexCoordPointer01_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glTexCoordPointer012_fake_func: - { - int size = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->texCoordPointerSize[0] = bytes_size; - process->current_state->texCoordPointer[0] = realloc(process->current_state->texCoordPointer[0], bytes_size); - memcpy(process->current_state->texCoordPointer[0], (void*)args[4], bytes_size); - /*fprintf(stderr, "glTexCoordPointer012_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexAndNormalPointer_fake_func: - { - int vertexPointerSize = args[0]; - int vertexPointerType = args[1]; - int vertexPointerStride = args[2]; - int normalPointerType = args[3]; - int normalPointerStride = args[4]; - int bytes_size = args[5]; - void* ptr = (void*)args[6]; - process->current_state->vertexPointerSize = bytes_size; - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, bytes_size); - memcpy(process->current_state->vertexPointer, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, vertexPointerStride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, normalPointerStride, process->current_state->vertexPointer); - break; - } - - case glVertexNormalPointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset= args[i++]; - int normalPointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - break; - } - - case glTuxRacerDrawElements_fake_func: - { - int mode = args[0]; - int count = args[1]; - int isColorEnabled = args[2]; - void* ptr = (void*)args[3]; - int stride = 6 * sizeof(float) + ((isColorEnabled) ? 4 * sizeof(unsigned char) : 0); - glVertexPointer( 3, GL_FLOAT, stride, ptr); - glNormalPointer( GL_FLOAT, stride, ptr + 3 * sizeof(float)); - if (isColorEnabled) - glColorPointer( 4, GL_UNSIGNED_BYTE, stride, ptr + 6 * sizeof(float)); - glDrawArrays(mode, 0, count); - break; - } - - case glVertexNormalColorPointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset= args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - break; - } - - case glVertexColorTexCoord0PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalTexCoord0PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalTexCoord01PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalTexCoord012PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int texCoord2PointerOffset = args[i++]; - int texCoord2PointerSize = args[i++]; - int texCoord2PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2); - glTexCoordPointer(texCoord2PointerSize, texCoord2PointerType, stride, process->current_state->vertexPointer + texCoord2PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalColorTexCoord0PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalColorTexCoord01PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalColorTexCoord012PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int texCoord2PointerOffset = args[i++]; - int texCoord2PointerSize = args[i++]; - int texCoord2PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2); - glTexCoordPointer(texCoord2PointerSize, texCoord2PointerType, stride, process->current_state->vertexPointer + texCoord2PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case _glVertexPointer_buffer_func: - { - glVertexPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glNormalPointer_buffer_func: - { - glNormalPointer(args[0],args[1],(void*)args[2]); - break; - } - - case _glColorPointer_buffer_func: - { - glColorPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glSecondaryColorPointer_buffer_func: - { - GET_EXT_PTR(void, glSecondaryColorPointer, (int,int,int,void*)); - ptr_func_glSecondaryColorPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glIndexPointer_buffer_func: - { - glIndexPointer(args[0],args[1],(void*)args[2]); - break; - } - - case _glTexCoordPointer_buffer_func: - { - glTexCoordPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glEdgeFlagPointer_buffer_func: - { - glEdgeFlagPointer(args[0],(void*)args[1]); - break; - } - - case _glVertexAttribPointerARB_buffer_func: - { - GET_EXT_PTR(void, glVertexAttribPointerARB, (int,int,int,int,int,void*)); - ptr_func_glVertexAttribPointerARB(args[0], args[1], args[2], args[3], args[4], (void*)args[5]); - break; - } - - case _glWeightPointerARB_buffer_func: - { - GET_EXT_PTR(void, glWeightPointerARB, (int,int,int,void*)); - ptr_func_glWeightPointerARB(args[0], args[1], args[2], (void*)args[3]); - break; - } - - case _glMatrixIndexPointerARB_buffer_func: - { - GET_EXT_PTR(void, glMatrixIndexPointerARB, (int,int,int,void*)); - ptr_func_glMatrixIndexPointerARB(args[0], args[1], args[2], (void*)args[3]); - break; - } - - case _glFogCoordPointer_buffer_func: - { - GET_EXT_PTR(void, glFogCoordPointer, (int,int,void*)); - ptr_func_glFogCoordPointer(args[0], args[1], (void*)args[2]); - break; - } - - case _glVariantPointerEXT_buffer_func: - { - GET_EXT_PTR(void, glVariantPointerEXT, (int, int,int,void*)); - ptr_func_glVariantPointerEXT(args[0], args[1], args[2], (void*)args[3]); - break; - } - - case _glDrawElements_buffer_func: - { - glDrawElements(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glDrawRangeElements_buffer_func: - { - GET_EXT_PTR(void, glDrawRangeElements, ( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices )); - ptr_func_glDrawRangeElements(args[0],args[1],args[2],args[3],args[4],(void*)args[5]); - break; - } - - case _glMultiDrawElements_buffer_func: - { - GET_EXT_PTR(void, glMultiDrawElements, (int,int*,int,void**, int)); - ptr_func_glMultiDrawElements(args[0],(int*)args[1],args[2],(void**)args[3],args[4]); - break; - } - - case _glGetError_fake_func: - { - break; - } - - case glGetIntegerv_func: - { - glGetIntegerv(args[0], (int*)args[1]); - break; - } - - case _glReadPixels_pbo_func: - { - glReadPixels(ARG_TO_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_INT(args[2]), ARG_TO_INT(args[3]), ARG_TO_UNSIGNED_INT(args[4]), ARG_TO_UNSIGNED_INT(args[5]), (void*)(args[6])); - break; - } - - case _glDrawPixels_pbo_func: - { - glDrawPixels(ARG_TO_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_UNSIGNED_INT(args[2]), ARG_TO_UNSIGNED_INT(args[3]), (const void*)(args[4])); - break; - } - - case _glMapBufferARB_fake_func: - { - GET_EXT_PTR(GLvoid*, glMapBufferARB, (GLenum, GLenum)); - GET_EXT_PTR(GLboolean, glUnmapBufferARB, (GLenum)); - int target = args[0]; - int size = args[1]; - void* dst_ptr = (void*)args[2]; - void* src_ptr = ptr_func_glMapBufferARB(target, GL_READ_ONLY); - if (src_ptr) - { - memcpy(dst_ptr, src_ptr, size); - ret_int = ptr_func_glUnmapBufferARB(target); - } - else - { - ret_int = 0; - } - break; - } - - case fake_gluBuild2DMipmaps_func: - { - GET_GLU_PTR(GLint, gluBuild2DMipmaps, (GLenum arg_0, GLint arg_1, GLsizei arg_2, GLsizei arg_3, GLenum arg_4, GLenum arg_5, const GLvoid * arg_6)); - if (ptr_func_gluBuild2DMipmaps == NULL) - ptr_func_gluBuild2DMipmaps = mesa_gluBuild2DMipmaps; - ptr_func_gluBuild2DMipmaps(ARG_TO_UNSIGNED_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_INT(args[2]), ARG_TO_INT(args[3]), ARG_TO_UNSIGNED_INT(args[4]), ARG_TO_UNSIGNED_INT(args[5]), (const void*)(args[6])); - break; - } - - case _glSelectBuffer_fake_func: - { - process->current_state->selectBufferSize = args[0] * 4; - process->current_state->selectBufferPtr = realloc(process->current_state->selectBufferPtr, process->current_state->selectBufferSize); - glSelectBuffer(args[0], process->current_state->selectBufferPtr); - break; - } - - case _glGetSelectBuffer_fake_func: - { - void* ptr = (void*)args[0]; - memcpy(ptr, process->current_state->selectBufferPtr, process->current_state->selectBufferSize); - break; - } - - case _glFeedbackBuffer_fake_func: - { - process->current_state->feedbackBufferSize = args[0] * 4; - process->current_state->feedbackBufferPtr = realloc(process->current_state->feedbackBufferPtr, process->current_state->feedbackBufferSize); - glFeedbackBuffer(args[0], args[1], process->current_state->feedbackBufferPtr); - break; - } - - case _glGetFeedbackBuffer_fake_func: - { - void* ptr = (void*)args[0]; - memcpy(ptr, process->current_state->feedbackBufferPtr, process->current_state->feedbackBufferSize); - break; - } - - case glGetError_func: - { - ret_int = glGetError(); - break; - } - - case glNewObjectBufferATI_func: - { - GET_EXT_PTR(int, glNewObjectBufferATI, (int,void*, int)); - ret_int = ptr_func_glNewObjectBufferATI(args[0], (void*)args[1], args[2]); - break; - } - - default: - execute_func(func_number, args, &ret_int, &ret_char); - break; - } - - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int ret_type = signature->ret_type; - switch(ret_type) - { - case TYPE_NONE: - break; - - case TYPE_CHAR: - case TYPE_UNSIGNED_CHAR: - ret_int = ret_char; - break; - - case TYPE_INT: - case TYPE_UNSIGNED_INT: - break; - - case TYPE_CONST_CHAR: - { - strncpy(ret_string, (ret_str) ? ret_str : "", 32768); - break; - } - - default: - fprintf(stderr, "unexpected ret type : %d\n", ret_type); - exit(-1); - break; - } - - return ret_int; -} - -#else - -#include -#include -#include - -#define GL_GLEXT_PROTOTYPES -#define GLX_GLXEXT_PROTOTYPES - -#include "opengl_func.h" -#include "opengl_utils.h" -#include "mesa_gl.h" -#include "mesa_glx.h" -#include "mesa_glu.h" -#include "mesa_mipmap.c" - -//#define SYSTEMATIC_ERROR_CHECK - -#define GET_EXT_PTR(type, funcname, args_decl) \ - static int detect_##funcname = 0; \ -static type(*ptr_func_##funcname)args_decl = NULL; \ -if (detect_##funcname == 0) \ -{ \ - detect_##funcname = 1; \ - ptr_func_##funcname = (type(*)args_decl)glXGetProcAddressARB((const GLubyte*)#funcname); \ - assert (ptr_func_##funcname); \ -} - -#define GET_EXT_PTR_NO_FAIL(type, funcname, args_decl) \ - static int detect_##funcname = 0; \ -static type(*ptr_func_##funcname)args_decl = NULL; \ -if (detect_##funcname == 0) \ -{ \ - detect_##funcname = 1; \ - ptr_func_##funcname = (type(*)args_decl)glXGetProcAddressARB((const GLubyte*)#funcname); \ -} - -#ifndef WIN32 -#include -#endif - -static void* get_glu_ptr(const char* name) -{ - static void* handle = (void*)-1; - if (handle == (void*)-1) - { -#ifndef WIN32 - handle = dlopen("libGLU.so" ,RTLD_LAZY); - if (!handle) { - fprintf (stderr, "can't load libGLU.so : %s\n", dlerror()); - } -#else - handle = (void *)LoadLibrary("glu32.dll"); - if (!handle) { - fprintf (stderr, "can't load glu32.dll\n"); - } -#endif - } - if (handle) - { -#ifndef WIN32 - return dlsym(handle, name); -#else - return GetProcAddress(handle, name); -#endif - } - return NULL; -} - -#define GET_GLU_PTR(type, funcname, args_decl) \ - static int detect_##funcname = 0; \ -static type(*ptr_func_##funcname)args_decl = NULL; \ -if (detect_##funcname == 0) \ -{ \ - detect_##funcname = 1; \ - ptr_func_##funcname = (type(*)args_decl)get_glu_ptr(#funcname); \ -} - -int display_function_call = 0; - -static const int defaultAttribList[] = { - GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_DOUBLEBUFFER, - None -}; - -static XVisualInfo* get_default_visual(Display* dpy) -{ - fprintf(stderr, "get_default_visual\n"); - static XVisualInfo* vis = NULL; - XVisualInfo theTemplate; - int numVisuals; - if (vis) return vis; - /*if (vis == NULL) - vis = glXChooseVisual(dpy, 0, (int*)defaultAttribList);*/ - theTemplate.screen = 0; - vis = XGetVisualInfo(dpy, VisualScreenMask, &theTemplate, &numVisuals); - return vis; -} - -void opengl_exec_set_parent_window(OGLS_Conn *pConn, Window _parent_window) -{ - pConn->parent_dpy = pConn->Display; - pConn->qemu_parent_window = _parent_window; - if (pConn->active_win) - { - XReparentWindow(pConn->Display, pConn->active_win, _parent_window, pConn->active_win_x, pConn->active_win_y); - } -} - -static Window create_window(OGLS_Conn *pConn, Window local_parent_window, XVisualInfo* vis, const char *name, - int x, int y, int width, int height) -{ - int scrnum; - XSetWindowAttributes attr = {0}; - unsigned long mask; - Window root; - Window win; - - scrnum = DefaultScreen( pConn->Display ); - root = RootWindow( pConn->Display, scrnum ); - - /* window attributes */ - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap( pConn->Display, root, vis->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask /*| KeyPressMask*/; - attr.save_under = True; - //if (local_parent_window == NULL && qemu_parent_window == NULL) - attr.override_redirect = False; - //else - // attr.override_redirect = True; - attr.cursor = None; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect | CWSaveUnder ; - - if (local_parent_window) - { - win = XCreateWindow( pConn->Display, local_parent_window, 0, 0, width, height, - 0, vis->depth, InputOutput, - vis->visual, mask, &attr ); - } - else if (pConn->qemu_parent_window) - { - win = XCreateWindow( pConn->Display, pConn->qemu_parent_window, 0, 0, width, height, - 0, vis->depth, InputOutput, - vis->visual, mask, &attr ); - } - else - { - win = XCreateWindow( pConn->Display, root, 0, 0, width, height, - 0, vis->depth, InputOutput, - vis->visual, mask, &attr ); - } - - /* set hints and properties */ - { - XSizeHints sizehints; - sizehints.x = x; - sizehints.y = y; - sizehints.width = width; - sizehints.height = height; - sizehints.flags = USSize | USPosition; - XSetWMNormalHints(pConn->Display, win, &sizehints); - XSetStandardProperties(pConn->Display, win, name, name, - None, (char **)NULL, 0, &sizehints); - } - - /* Host Window?? ?琉??? ?苛쨈?. if( win ) - XMapWindow(pConn->Display, win);*/ - - XSync(pConn->Display, 0); - - /* - int loop = 1; - while (loop) { - while (XPending(pConn->Display) > 0) { - XEvent event; - XNextEvent(pConn->Display, &event); - switch (event.type) { - case CreateNotify: - { - if (((XCreateWindowEvent*)&event)->window == win) - { - loop = 0; - } - break; - } - } - } - }*/ - - pConn->active_win = win; - - return win; -} - -static void destroy_window(OGLS_Conn *pConn, Window win ) -{ - /*int i;*/ - - XDestroyWindow(pConn->Display, win); - - XSync(pConn->Display, 0); - /*int loop = 1; - while (loop) { - while (XPending(pConn->Display) > 0) { - XEvent event; - XNextEvent(pConn->Display, &event); - switch (event.type) { - case DestroyNotify: - { - if (((XDestroyWindowEvent*)&event)->window == win) - { - loop = 0; - } - break; - } - } - } - }*/ - - if( pConn->active_win == win) - pConn->active_win = 0; - -} - - -typedef struct -{ - void* key; - void* value; -} Assoc; - - -#define MAX_HANDLED_PROCESS 100 -#define MAX_ASSOC_SIZE 100 - -#define MAX_FBCONFIG 10 - - -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - - -typedef struct -{ - int x; - int y; - int width; - int height; - int map_state; -} WindowPosStruct; - -typedef struct -{ - GLbitfield mask; - int activeTextureIndex; -} ClientState; - -#define MAX_CLIENT_STATE_STACK_SIZE 16 - -typedef struct -{ - int ref; - int fake_ctxt; - int fake_shareList; - GLXContext context; - GLXDrawable drawable; - - void* vertexPointer; - void* normalPointer; - void* colorPointer; - void* secondaryColorPointer; - void* indexPointer; - void* texCoordPointer[NB_MAX_TEXTURES]; - void* edgeFlagPointer; - void* vertexAttribPointer[MY_GL_MAX_VERTEX_ATTRIBS_ARB]; - void* vertexAttribPointerNV[MY_GL_MAX_VERTEX_ATTRIBS_NV]; - void* weightPointer; - void* matrixIndexPointer; - void* fogCoordPointer; - void* variantPointerEXT[MY_GL_MAX_VARIANT_POINTER_EXT]; - void* interleavedArrays; - void* elementPointerATI; - - int vertexPointerSize; - int normalPointerSize; - int colorPointerSize; - int secondaryColorPointerSize; - int indexPointerSize; - int texCoordPointerSize[NB_MAX_TEXTURES]; - int edgeFlagPointerSize; - int vertexAttribPointerSize[MY_GL_MAX_VERTEX_ATTRIBS_ARB]; - int vertexAttribPointerNVSize[MY_GL_MAX_VERTEX_ATTRIBS_NV]; - int weightPointerSize; - int matrixIndexPointerSize; - int fogCoordPointerSize; - int variantPointerEXTSize[MY_GL_MAX_VARIANT_POINTER_EXT]; - int interleavedArraysSize; - int elementPointerATISize; - - int selectBufferSize; - void* selectBufferPtr; - int feedbackBufferSize; - void* feedbackBufferPtr; - - ClientState clientStateStack[MAX_CLIENT_STATE_STACK_SIZE]; - int clientStateSp; - int activeTextureIndex; - - unsigned int ownTabTextures[32768]; - unsigned int* tabTextures; - RangeAllocator ownTextureAllocator; - RangeAllocator* textureAllocator; - - unsigned int ownTabBuffers[32768]; - unsigned int* tabBuffers; - RangeAllocator ownBufferAllocator; - RangeAllocator* bufferAllocator; - - unsigned int ownTabLists[32768]; - unsigned int* tabLists; - RangeAllocator ownListAllocator; - RangeAllocator* listAllocator; - -#ifdef SYSTEMATIC_ERROR_CHECK - int last_error; -#endif -} GLState; - -typedef struct -{ - int internal_num; - int process_id; - int instr_counter; - - int x, y, width, height; - WindowPosStruct currentDrawablePos; - - int next_available_context_number; - int next_available_pbuffer_number; - - int nbGLStates; - GLState default_state; - GLState** glstates; - GLState* current_state; - - int nfbconfig; - GLXFBConfig* fbconfigs[MAX_FBCONFIG]; - int fbconfigs_max[MAX_FBCONFIG]; - int nfbconfig_total; - - Assoc association_fakecontext_glxcontext[MAX_ASSOC_SIZE]; - Assoc association_fakepbuffer_pbuffer[MAX_ASSOC_SIZE]; - Assoc association_clientdrawable_serverdrawable[MAX_ASSOC_SIZE]; - Assoc association_fakecontext_visual[MAX_ASSOC_SIZE]; -} ProcessStruct; - -int last_process_id = 0; - - -#define ARG_TO_CHAR(x) (char)(x) -#define ARG_TO_UNSIGNED_CHAR(x) (unsigned char)(x) -#define ARG_TO_SHORT(x) (short)(x) -#define ARG_TO_UNSIGNED_SHORT(x) (unsigned short)(x) -#define ARG_TO_INT(x) (int)(x) -#define ARG_TO_UNSIGNED_INT(x) (unsigned int)(x) -#define ARG_TO_FLOAT(x) (*(float*)&(x)) -#define ARG_TO_DOUBLE(x) (*(double*)(x)) - -#include "server_stub.c" - -/* ---- */ - -static void* get_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - return process->association_fakecontext_glxcontext[i].value; - } - return NULL; -} - -static void set_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext, void* glxcontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakecontext_glxcontext[i].key = fakecontext; - process->association_fakecontext_glxcontext[i].value = glxcontext; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -static void unset_association_fakecontext_glxcontext(ProcessStruct* process, void* fakecontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - if (process->association_fakecontext_glxcontext[i].key == fakecontext) - { - memmove(&process->association_fakecontext_glxcontext[i], - &process->association_fakecontext_glxcontext[i+1], - sizeof(Assoc) * (MAX_ASSOC_SIZE - 1 - i)); - return; - } - } -} - -/* ---- */ - -static void* get_association_fakecontext_visual(ProcessStruct* process, void* fakecontext) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_visual[i].key != NULL;i++) - { - if (process->association_fakecontext_visual[i].key == fakecontext) - return process->association_fakecontext_visual[i].value; - } - return NULL; -} - -static void set_association_fakecontext_visual(ProcessStruct* process, void* fakecontext, void* visual) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_visual[i].key != NULL;i++) - { - if (process->association_fakecontext_visual[i].key == fakecontext) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakecontext_visual[i].key = fakecontext; - process->association_fakecontext_visual[i].value = visual; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -/* ---- */ - -static void* get_association_fakepbuffer_pbuffer(ProcessStruct* process, void* fakepbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - return process->association_fakepbuffer_pbuffer[i].value; - } - return NULL; -} -static void set_association_fakepbuffer_pbuffer(ProcessStruct* process, void* fakepbuffer, void* pbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_fakepbuffer_pbuffer[i].key = fakepbuffer; - process->association_fakepbuffer_pbuffer[i].value = pbuffer; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} -static void unset_association_fakepbuffer_pbuffer(ProcessStruct* process, void* fakepbuffer) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - if (process->association_fakepbuffer_pbuffer[i].key == fakepbuffer) - { - memmove(&process->association_fakepbuffer_pbuffer[i], - &process->association_fakepbuffer_pbuffer[i+1], - sizeof(Assoc) * (MAX_ASSOC_SIZE - 1 - i)); - return; - } - } -} - -/* ---- */ - - -static GLXDrawable get_association_clientdrawable_serverdrawable(ProcessStruct* process, GLXDrawable clientdrawable) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == (void*)clientdrawable) - return (GLXDrawable)process->association_clientdrawable_serverdrawable[i].value; - } - return (GLXDrawable)0; -} - -#if 0 -static void* get_association_serverdrawable_clientdrawable(ProcessStruct* process, GLXDrawable serverdrawable) -{ - int i; - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if ((GLXDrawable)process->association_clientdrawable_serverdrawable[i].value == serverdrawable) - return process->association_clientdrawable_serverdrawable[i].key; - } - return NULL; -} -#endif - -static void set_association_clientdrawable_serverdrawable(ProcessStruct* process, void* clientdrawable, void* serverdrawable) -{ - int i; - for(i=0;process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == clientdrawable) - { - break; - } - } - if (i < MAX_ASSOC_SIZE) - { - process->association_clientdrawable_serverdrawable[i].key = clientdrawable; - process->association_clientdrawable_serverdrawable[i].value = serverdrawable; - } - else - { - fprintf(stderr, "MAX_ASSOC_SIZE reached\n"); - } -} - -static void _get_window_pos(Display *dpy, Window win, WindowPosStruct* pos) -{ - XWindowAttributes window_attributes_return; - Window child; - int x, y; - Window root = DefaultRootWindow(dpy); - XGetWindowAttributes(dpy, win, &window_attributes_return); - XTranslateCoordinates(dpy, win, root, 0, 0, &x, &y, &child); - /*printf("%d %d %d %d\n", x, y, - window_attributes_return.width, window_attributes_return.height);*/ - pos->x = x; - pos->y = y; - pos->width = window_attributes_return.width; - pos->height = window_attributes_return.height; - pos->map_state = window_attributes_return.map_state; -} - -static int is_gl_vendor_ati(Display* dpy) -{ - static int is_gl_vendor_ati_flag = 0; - static int has_init = 0; - if (has_init == 0) - { - has_init = 1; - is_gl_vendor_ati_flag = (strncmp(glXGetClientString(dpy, GLX_VENDOR), "ATI", 3) == 0); - } - return is_gl_vendor_ati_flag; -} - -static int get_server_texture(ProcessStruct* process, unsigned int client_texture) -{ - unsigned int server_texture = 0; - if (client_texture < 32768) - { - server_texture = process->current_state->tabTextures[client_texture]; - } - else - { - fprintf(stderr, "invalid texture name %d\n", client_texture); - } - return server_texture; -} - -static int get_server_buffer(ProcessStruct* process, unsigned int client_buffer) -{ - unsigned int server_buffer = 0; - if (client_buffer < 32768) - { - server_buffer = process->current_state->tabBuffers[client_buffer]; - } - else - { - fprintf(stderr, "invalid buffer name %d\n", client_buffer); - } - return server_buffer; -} - - -static int get_server_list(ProcessStruct* process, unsigned int client_list) -{ - unsigned int server_list = 0; - if (client_list < 32768) - { - server_list = process->current_state->tabLists[client_list]; - } - else - { - fprintf(stderr, "invalid list name %d\n", client_list); - } - return server_list; -} - -static GLXFBConfig get_fbconfig(ProcessStruct* process, int client_fbconfig) -{ - int i; - int nbtotal = 0; - for(i=0;infbconfig;i++) - { - assert(client_fbconfig >= 1 + nbtotal); - if (client_fbconfig <= nbtotal + process->fbconfigs_max[i]) - { - return process->fbconfigs[i][client_fbconfig-1 - nbtotal]; - } - nbtotal += process->fbconfigs_max[i]; - } - return 0; -} - -typedef struct -{ - int attribListLength; - int* attribList; - XVisualInfo* visInfo; -} AssocAttribListVisual; - -static int _compute_length_of_attrib_list_including_zero(const int* attribList, int booleanMustHaveValue) -{ - int i = 0; - while(attribList[i]) - { - if (booleanMustHaveValue || - !(attribList[i] == GLX_USE_GL || - attribList[i] == GLX_RGBA || - attribList[i] == GLX_DOUBLEBUFFER || - attribList[i] == GLX_STEREO)) - { - i+=2; - } - else - { - i++; - } - } - return i + 1; -} - -static int glXChooseVisualFunc( OGLS_Conn *pConn, const int* _attribList) -{ - AssocAttribListVisual *tabAssocAttribListVisual = (AssocAttribListVisual *)pConn->tabAssocAttribListVisual ; - - if (_attribList == NULL) - return 0; - int attribListLength = _compute_length_of_attrib_list_including_zero(_attribList, 0); - int i; - - int* attribList = malloc(sizeof(int) * attribListLength); - memcpy(attribList, _attribList, sizeof(int) * attribListLength); - - i = 0; - while(attribList[i]) - { - if (!(attribList[i] == GLX_USE_GL || - attribList[i] == GLX_RGBA || - attribList[i] == GLX_DOUBLEBUFFER || - attribList[i] == GLX_STEREO)) - { - if (attribList[i] == GLX_SAMPLE_BUFFERS && attribList[i+1] != 0 && getenv("DISABLE_SAMPLE_BUFFERS")) - { - fprintf(stderr, "Disabling GLX_SAMPLE_BUFFERS\n"); - attribList[i+1] = 0; - } - i+=2; - } - else - { - i++; - } - } - - for(i=0;inTabAssocAttribListVisual;i++) - { - if (tabAssocAttribListVisual[i].attribListLength == attribListLength && - memcmp(tabAssocAttribListVisual[i].attribList, attribList, attribListLength * sizeof(int)) == 0) - { - free(attribList); - return (tabAssocAttribListVisual[i].visInfo) ? tabAssocAttribListVisual[i].visInfo->visualid : 0; - } - } - XVisualInfo* visInfo = glXChooseVisual(pConn->Display, 0, attribList); - pConn->tabAssocAttribListVisual = tabAssocAttribListVisual = - realloc(tabAssocAttribListVisual, sizeof(AssocAttribListVisual) * (pConn->nTabAssocAttribListVisual+1)); - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribListLength = attribListLength; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribList = (int*)malloc(sizeof(int) * attribListLength); - memcpy(tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribList, attribList, sizeof(int) * attribListLength); - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].visInfo = visInfo; - pConn->nTabAssocAttribListVisual++; - free(attribList); - return (visInfo) ? visInfo->visualid : 0; -} - -static XVisualInfo* get_visual_info_from_visual_id( OGLS_Conn *pConn, int visualid) -{ - int i, n; - XVisualInfo template; - XVisualInfo* visInfo; - - AssocAttribListVisual *tabAssocAttribListVisual = (AssocAttribListVisual *)pConn->tabAssocAttribListVisual ; - - for(i=0;inTabAssocAttribListVisual;i++) - { - if (tabAssocAttribListVisual[i].visInfo && - tabAssocAttribListVisual[i].visInfo->visualid == visualid) - { - return tabAssocAttribListVisual[i].visInfo; - } - } - template.visualid = visualid; - visInfo = XGetVisualInfo(pConn->Display, VisualIDMask, &template, &n); - pConn->tabAssocAttribListVisual = tabAssocAttribListVisual = - realloc(tabAssocAttribListVisual, sizeof(AssocAttribListVisual) * (pConn->nTabAssocAttribListVisual+1)); - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribListLength = 0; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribList = NULL; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].visInfo = visInfo; - pConn->nTabAssocAttribListVisual++; - return visInfo; -} - -typedef struct -{ - int x; - int y; - int width; - int height; - int xhot; - int yhot; - int* pixels; -} ClientCursor; - -static ClientCursor client_cursor = { 0 }; - -static void do_glClientActiveTextureARB(int texture) -{ - GET_EXT_PTR_NO_FAIL(void, glClientActiveTextureARB, (int)); - if (ptr_func_glClientActiveTextureARB) - { - ptr_func_glClientActiveTextureARB(texture); - } -} - -static void do_glActiveTextureARB(int texture) -{ - GET_EXT_PTR_NO_FAIL(void, glActiveTextureARB, (int)); - if (ptr_func_glActiveTextureARB) - { - ptr_func_glActiveTextureARB(texture); - } -} - -static void do_glUseProgramObjectARB(GLhandleARB programObj) -{ - GET_EXT_PTR_NO_FAIL(void, glUseProgramObjectARB, (GLhandleARB)); - if (ptr_func_glUseProgramObjectARB) - { - ptr_func_glUseProgramObjectARB(programObj); - } -} - -static void destroy_gl_state(GLState* state) -{ - int i; - if (state->vertexPointer) free(state->vertexPointer); - if (state->normalPointer) free(state->normalPointer); - if (state->indexPointer) free(state->indexPointer); - if (state->colorPointer) free(state->colorPointer); - if (state->secondaryColorPointer) free(state->secondaryColorPointer); - for(i=0;itexCoordPointer[i]) free(state->texCoordPointer[i]); - } - for(i=0;ivertexAttribPointer[i]) free(state->vertexAttribPointer[i]); - } - for(i=0;ivertexAttribPointerNV[i]) free(state->vertexAttribPointerNV[i]); - } - if (state->weightPointer) free(state->weightPointer); - if (state->matrixIndexPointer) free(state->matrixIndexPointer); - if (state->fogCoordPointer) free(state->fogCoordPointer); - for(i=0;ivariantPointerEXT[i]) free(state->variantPointerEXT[i]); - } - if (state->interleavedArrays) free(state->interleavedArrays); - if (state->elementPointerATI) free(state->elementPointerATI); -} - -static void init_gl_state(GLState* state) -{ - state->textureAllocator = &state->ownTextureAllocator; - state->tabTextures = state->ownTabTextures; - state->bufferAllocator = &state->ownBufferAllocator; - state->tabBuffers = state->ownTabBuffers; - state->listAllocator = &state->ownListAllocator; - state->tabLists = state->ownTabLists; -} - -/* - * Translate the nth element of list from type to GLuint. - */ - static GLuint -translate_id(GLsizei n, GLenum type, const GLvoid * list) -{ - GLbyte *bptr; - GLubyte *ubptr; - GLshort *sptr; - GLushort *usptr; - GLint *iptr; - GLuint *uiptr; - GLfloat *fptr; - - switch (type) { - case GL_BYTE: - bptr = (GLbyte *) list; - return (GLuint) *(bptr + n); - case GL_UNSIGNED_BYTE: - ubptr = (GLubyte *) list; - return (GLuint) *(ubptr + n); - case GL_SHORT: - sptr = (GLshort *) list; - return (GLuint) *(sptr + n); - case GL_UNSIGNED_SHORT: - usptr = (GLushort *) list; - return (GLuint) *(usptr + n); - case GL_INT: - iptr = (GLint *) list; - return (GLuint) *(iptr + n); - case GL_UNSIGNED_INT: - uiptr = (GLuint *) list; - return (GLuint) *(uiptr + n); - case GL_FLOAT: - fptr = (GLfloat *) list; - return (GLuint) *(fptr + n); - case GL_2_BYTES: - ubptr = ((GLubyte *) list) + 2 * n; - return (GLuint) *ubptr * 256 + (GLuint) * (ubptr + 1); - case GL_3_BYTES: - ubptr = ((GLubyte *) list) + 3 * n; - return (GLuint) * ubptr * 65536 - + (GLuint) *(ubptr + 1) * 256 + (GLuint) * (ubptr + 2); - case GL_4_BYTES: - ubptr = ((GLubyte *) list) + 4 * n; - return (GLuint) *ubptr * 16777216 - + (GLuint) *(ubptr + 1) * 65536 - + (GLuint) *(ubptr + 2) * 256 + (GLuint) * (ubptr + 3); - default: - return 0; - } -} - -static void _create_context(ProcessStruct* process, GLXContext ctxt, int fake_ctxt, GLXContext shareList, int fake_shareList) -{ - process->glstates = realloc(process->glstates, (process->nbGLStates+1)*sizeof(GLState*)); - process->glstates[process->nbGLStates] = malloc(sizeof(GLState)); - memset(process->glstates[process->nbGLStates], 0, sizeof(GLState)); - process->glstates[process->nbGLStates]->ref = 1; - process->glstates[process->nbGLStates]->context = ctxt; - process->glstates[process->nbGLStates]->fake_ctxt = fake_ctxt; - process->glstates[process->nbGLStates]->fake_shareList = fake_shareList; - init_gl_state(process->glstates[process->nbGLStates]); - if (shareList && fake_shareList) - { - int i; - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_shareList) - { - process->glstates[i]->ref ++; - process->glstates[process->nbGLStates]->textureAllocator = - process->glstates[i]->textureAllocator; - process->glstates[process->nbGLStates]->tabTextures = - process->glstates[i]->tabTextures; - process->glstates[process->nbGLStates]->bufferAllocator = - process->glstates[i]->bufferAllocator; - process->glstates[process->nbGLStates]->tabBuffers = - process->glstates[i]->tabBuffers; - process->glstates[process->nbGLStates]->listAllocator = - process->glstates[i]->listAllocator; - process->glstates[process->nbGLStates]->tabLists = - process->glstates[i]->tabLists; - break; - } - } - } - process->nbGLStates++; -} - -static const char *opengl_strtok(const char *s, int *n, char **saveptr, char *prevbuf) -{ - char *start; - char *ret; - char *p; - int retlen; - static const char *delim = " \t\n\r/"; - - if (prevbuf) - free(prevbuf); - - if (s) { - *saveptr = s; - } else { - if (!(*saveptr) || !(*n)) - return NULL; - s = *saveptr; - } - - for (; *n && strchr(delim, *s); s++, (*n)--) { - if (*s == '/' && *n > 1) { - if (s[1] == '/') { - do { - s++, (*n)--; - } while (*n > 1 && s[1] != '\n' && s[1] != '\r'); - } else if (s[1] == '*') { - do { - s++, (*n)--; - } while (*n > 2 && (s[1] != '*' || s[2] != '/')); - s++, (*n)--; - } - } - } - - start = s; - for (; *n && *s && !strchr(delim, *s); s++, (*n)--); - if (*n > 0) - s++, (*n)--; - - *saveptr = s; - - retlen = s - start; - ret = malloc(retlen + 1); - p = ret; - - while (retlen > 0) { - if (*start == '/' && retlen > 1) { - if (start[1] == '/') { - do { - start++, retlen--; - } while (retlen > 1 && start[1] != '\n' && start[1] != '\r'); - start++, retlen--; - continue; - } else if (start[1] == '*') { - do { - start++, retlen--; - } while (retlen > 2 && (start[1] != '*' || start[2] != '/')); - start += 3, retlen -= 3; - continue; - } - } - *(p++) = *(start++), retlen--; - } - - *p = 0; - return ret; -} - -static char *do_eglShaderPatch(const char *source, int length, int *patched_len) -{ - char *saveptr = NULL; - char *sp; - char *p = NULL; - - if (!length) - length = strlen(source); - - *patched_len = 0; - int patched_size = length; - char *patched = malloc(patched_size + 1); - - if (!patched) - return NULL; - - p = opengl_strtok(source, &length, &saveptr, NULL); - for (; p; p = opengl_strtok(0, &length, &saveptr, p)) { - if (!strncmp(p, "lowp", 4) || !strncmp(p, "mediump", 7) || !strncmp(p, "highp", 5)) { - continue; - } else if (!strncmp(p, "precision", 9)) { - while ((p = opengl_strtok(0, &length, &saveptr, p)) && !strchr(p, ';')); - } else { - if (!strncmp(p, "gl_MaxVertexUniformVectors", 26)) { - p = "(gl_MaxVertexUniformComponents / 4)"; - } else if (!strncmp(p, "gl_MaxFragmentUniformVectors", 28)) { - p = "(gl_MaxFragmentUniformComponents / 4)"; - } else if (!strncmp(p, "gl_MaxVaryingVectors", 20)) { - p = "(gl_MaxVaryingFloats / 4)"; - } - - int new_len = strlen(p); - if (*patched_len + new_len > patched_size) { - patched_size *= 2; - patched = realloc(patched, patched_size + 1); - - if (!patched) - return NULL; - } - - memcpy(patched + *patched_len, p, new_len); - *patched_len += new_len; - } - } - - patched[*patched_len] = 0; - /* check that we don't leave dummy preprocessor lines */ - for (sp = patched; *sp;) { - for (; *sp == ' ' || *sp == '\t'; sp++); - if (!strncmp(sp, "#define", 7)) { - for (p = sp + 7; *p == ' ' || *p == '\t'; p++); - if (*p == '\n' || *p == '\r' || *p == '/') { - memset(sp, 0x20, 7); - } - } - for (; *sp && *sp != '\n' && *sp != '\r'; sp++); - for (; *sp == '\n' || *sp == '\r'; sp++); - } - return patched; -} - -static int -shadersrc_gles_to_gl(GLsizei count, const char** string, char **s, const GLint* length, GLint *l) -{ - int i; - - for(i = 0; i < count; ++i) { - GLint len; - if(length) { - len = length[i]; - if (len < 0) - len = string[i] ? strlen(string[i]) : 0; - } else - len = string[i] ? strlen(string[i]) : 0; - - if(string[i]) { - s[i] = do_eglShaderPatch(string[i], len, &l[i]); - if(!s[i]) { - while(i) - free(s[--i]); - - free(l); - free(s); - return -1; - } - } else { - s[i] = NULL; - l[i] = 0; - } - } - - return 0; -} - -int do_function_call(OGLS_Conn *pConn, int func_number, int pid, long* args, char* ret_string) -{ - char ret_char = 0; - int ret_int = 0; - const char* ret_str = NULL; - int iProcess; - ProcessStruct* process = NULL; - ProcessStruct *processTab = (ProcessStruct *) pConn->processTab; - - if (pConn->parent_dpy) - { - pConn->Display = pConn->parent_dpy; - } - - for(iProcess=0;iProcessprocessTab; - if (processTab[iProcess].process_id == pid) - { - process = &processTab[iProcess]; - break; - } - else if (processTab[iProcess].process_id == 0) - { - process = &processTab[iProcess]; - memset(process, 0, sizeof(ProcessStruct)); - process->process_id = pid; - process->internal_num = pConn->last_assigned_internal_num++; - init_gl_state(&process->default_state); - process->current_state = &process->default_state; - break; - } - } - if (process == NULL) - { - fprintf(stderr, "Too many processes !\n"); - return 0; - } - if (process->internal_num != pConn->last_active_internal_num) - { - glXMakeCurrent(pConn->Display, process->current_state->drawable, process->current_state->context); - pConn->last_active_internal_num = process->internal_num; - } - - process->instr_counter++; - - if (display_function_call) fprintf(stderr, "[%d]> %s\n", process->instr_counter, tab_opengl_calls_name[func_number]); - //fprintf(stderr, "[%d]> %s\n", process->instr_counter, tab_opengl_calls_name[func_number]); - - switch (func_number) - { - case _init_func: - { - *(int*)args[1] = 1; - break; - } - - case _synchronize_func: - { - ret_int = 1; - break; - } - - case _exit_process_func: - { - int i; - - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakecontext_glxcontext[i].key != NULL;i++) - { - GLXContext ctxt = process->association_fakecontext_glxcontext[i].value; - //fprintf(stderr, "Destroy context corresponding to fake_context = %ld\n", - // (long)process->association_fakecontext_glxcontext[i].key); - glXDestroyContext(pConn->Display, ctxt); - } - - GET_EXT_PTR(void, glXDestroyPbuffer, (Display*, GLXPbuffer)); - for(i=0;i < MAX_ASSOC_SIZE && process->association_fakepbuffer_pbuffer[i].key != NULL;i++) - { - GLXPbuffer pbuffer = (GLXPbuffer)process->association_fakepbuffer_pbuffer[i].value; - fprintf(stderr, "Destroy pbuffer corresponding to fake_pbuffer = %ld\n", - (long)process->association_fakepbuffer_pbuffer[i].key); - if (!is_gl_vendor_ati(pConn->Display)) - ptr_func_glXDestroyPbuffer(pConn->Display, pbuffer); - } - - for(i=0;i < MAX_ASSOC_SIZE && process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - //fprintf(stderr, "Destroy window corresponding to client_drawable = %p\n", - // process->association_clientdrawable_serverdrawable[i].key); - - Window win = (Window)process->association_clientdrawable_serverdrawable[i].value; - XDestroyWindow(pConn->Display, win); - - int loop = 1; - while (loop) { - while (XPending(pConn->Display) > 0) { - XEvent event; - XNextEvent(pConn->Display, &event); - switch (event.type) { - case DestroyNotify: - { - if (((XDestroyWindowEvent*)&event)->window == win) - { - loop = 0; - } - break; - } - } - } - } - } - - for(i=0;inbGLStates;i++) - { - destroy_gl_state(process->glstates[i]); - free(process->glstates[i]); - } - destroy_gl_state(&process->default_state); - free(process->glstates); - - pConn->active_win = 0; - - memmove(&processTab[iProcess], &processTab[iProcess+1], (MAX_HANDLED_PROCESS - 1 - iProcess) * sizeof(ProcessStruct)); - - last_process_id = 0; - - break; - } - - case _changeWindowState_func: - { - GLXDrawable client_drawable = args[0]; - if (display_function_call) fprintf(stderr, "client_drawable=%p\n", (void*)client_drawable); - - GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - if (drawable) - { - if (args[1] == IsViewable) - { - WindowPosStruct pos; - _get_window_pos(pConn->Display, drawable, &pos); - if (pos.map_state != args[1]) - { - XMapWindow(pConn->Display, drawable); - - int loop = 0; //1; - while (loop) { - while (XPending(pConn->Display) > 0) { - XEvent event; - XNextEvent(pConn->Display, &event); - switch (event.type) { - case ConfigureNotify: - { - if (((XConfigureEvent*)&event)->window == drawable) - { - loop = 0; - } - break; - } - } - } - } - } - } - } - - break; - } - - case _moveResizeWindow_func: - { - int* params = (int*)args[1]; - GLXDrawable client_drawable = args[0]; - if (display_function_call) fprintf(stderr, "client_drawable=%p\n", (void*)client_drawable); - - GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - if (drawable) - { - WindowPosStruct pos; - _get_window_pos(pConn->Display, drawable, &pos); - if (!(params[0] == pos.x && params[1] == pos.y && params[2] == pos.width && params[3] == pos.height)) - { - int redim = !(params[2] == pos.width && params[3] == pos.height); - pConn->active_win_x = params[0]; - pConn->active_win_y = params[1]; - - /* - fprintf(stderr, "old x=%d y=%d width=%d height=%d\n", pos.x, pos.y, pos.width, pos.height); - fprintf(stderr, "new x=%d y=%d width=%d height=%d\n", params[0], params[1], params[2], params[3]); - */ - - XMoveResizeWindow(pConn->Display, drawable, params[0], params[1], params[2], params[3]); - _get_window_pos(pConn->Display, drawable, &pos); - process->currentDrawablePos = pos; - //if (getenv("FORCE_GL_VIEWPORT")) - if (redim) - glViewport(0, 0, params[2], params[3]); - int loop = 0; //1; - while (loop) { - while (XPending(pConn->Display) > 0) { - XEvent event; - XNextEvent(pConn->Display, &event); - switch (event.type) { - case ConfigureNotify: - { - if (((XConfigureEvent*)&event)->window == drawable) - { - loop = 0; - } - break; - } - } - } - } - } - } - break; - } - - case _send_cursor_func: - { - int x = args[0]; - int y = args[1]; - int width = args[2]; - int height = args[3]; - int xhot = args[4]; - int yhot = args[5]; - int* pixels = (int*)args[6]; - client_cursor.x = x; - client_cursor.y = y; - client_cursor.width = width; - client_cursor.height = height; - client_cursor.xhot = xhot; - client_cursor.yhot = yhot; - if (pixels) - { - client_cursor.pixels = realloc(client_cursor.pixels, client_cursor.width * client_cursor.height * sizeof(int)); - memcpy(client_cursor.pixels, pixels, client_cursor.width * client_cursor.height * sizeof(int)); - } - //int in_window = (x >= 0 && y >= 0 && - //x < process->currentDrawablePos.width && - //y < process->currentDrawablePos.height); - //fprintf(stderr, "cursor at %d %d (%s)\n", x, y, (in_window) ? "in window" : "not in window"); - break; - } - - case glXWaitGL_func: - { - glXWaitGL(); - ret_int = 0; - break; - } - - case glXWaitX_func: - { - glXWaitX(); - ret_int = 0; - break; - } - - case glXChooseVisual_func: - { - ret_int = glXChooseVisualFunc(pConn, (int*)args[2]); - break; - } - - case glXQueryExtensionsString_func: - { - ret_str = glXQueryExtensionsString(pConn->Display, 0); - break; - } - - case glXQueryServerString_func: - { - ret_str = glXQueryServerString(pConn->Display, 0, args[2]); - break; - } - - case glXGetClientString_func: - { - ret_str = glXGetClientString(pConn->Display, args[1]); - break; - } - - case glXGetScreenDriver_func: - { - GET_EXT_PTR(const char*, glXGetScreenDriver, (Display* , int )); - ret_str = ptr_func_glXGetScreenDriver(pConn->Display, 0); - break; - } - - case glXGetDriverConfig_func: - { - GET_EXT_PTR(const char*, glXGetDriverConfig, (const char* )); - ret_str = ptr_func_glXGetDriverConfig((const char*)args[0]); - break; - } - - case glXCreateContext_func: - { - int visualid = (int)args[1]; - int fake_shareList = (int)args[2]; - if (1 || display_function_call) fprintf(stderr, "visualid=%d, fake_shareList=%d\n", visualid, fake_shareList); - - GLXContext shareList = get_association_fakecontext_glxcontext(process, (void*)(long)fake_shareList); - XVisualInfo* vis = get_visual_info_from_visual_id(pConn, visualid); - GLXContext ctxt; - if (vis) - { - ctxt = glXCreateContext(pConn->Display, vis, shareList, args[3]); - } - else - { - vis = get_default_visual(pConn->Display); - int saved_visualid = vis->visualid; - vis->visualid = (visualid) ? visualid : saved_visualid; - ctxt = glXCreateContext(pConn->Display, vis, shareList, args[3]); - vis->visualid = saved_visualid; - } - - if (ctxt) - { - process->next_available_context_number ++; - int fake_ctxt = process->next_available_context_number; - set_association_fakecontext_visual(process, (void*)(long)fake_ctxt, vis); - set_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt, ctxt); - ret_int = fake_ctxt; - - _create_context(process, ctxt, fake_ctxt, shareList, fake_shareList); - } - else - { - ret_int = 0; - } - - break; - } - - - case glXCreateNewContext_func: - { - GET_EXT_PTR(GLXContext, glXCreateNewContext, (Display*, GLXFBConfig, int, GLXContext, int)); - GET_EXT_PTR(XVisualInfo*, glXGetVisualFromFBConfig, (Display*, GLXFBConfig)); - int client_fbconfig = args[1]; - XVisualInfo* vis = NULL; - - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - { - int fake_shareList = args[3]; - GLXContext shareList = get_association_fakecontext_glxcontext(process, (void*)(long)fake_shareList); - process->next_available_context_number ++; - int fake_ctxt = process->next_available_context_number; - GLXContext ctxt = ptr_func_glXCreateNewContext(pConn->Display, fbconfig, args[2], shareList, args[4]); - set_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt, ctxt); - - vis = ptr_func_glXGetVisualFromFBConfig(pConn->Display, fbconfig); /* visual info ????*/ - set_association_fakecontext_visual(process, (void *)(long)fake_ctxt, vis); - - ret_int = fake_ctxt; - - _create_context(process, ctxt, fake_ctxt, shareList, fake_shareList); - } - break; - } - - case glXCopyContext_func: - { - GLXContext fake_src_ctxt = (GLXContext)args[1]; - GLXContext fake_dst_ctxt = (GLXContext)args[2]; - GLXContext src_ctxt; - GLXContext dst_ctxt; - if (display_function_call) fprintf(stderr, "fake_src_ctxt=%p, fake_dst_ctxt=%p\n", fake_src_ctxt, fake_dst_ctxt); - - if ((src_ctxt = get_association_fakecontext_glxcontext(process, fake_src_ctxt)) == NULL) - { - fprintf(stderr, "invalid fake_src_ctxt (%p) !\n", fake_src_ctxt); - } - else if ((dst_ctxt = get_association_fakecontext_glxcontext(process, fake_dst_ctxt)) == NULL) - { - fprintf(stderr, "invalid fake_dst_ctxt (%p) !\n", fake_dst_ctxt); - } - else - { - glXCopyContext(pConn->Display, src_ctxt, dst_ctxt, args[3]); - } - break; - } - - case glXDestroyContext_func: - { - int fake_ctxt = (int)args[1]; - if (display_function_call) fprintf(stderr, "fake_ctxt=%d\n", fake_ctxt); - - GLXContext ctxt = get_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%p) !\n", (void*)(long)fake_ctxt); - } - else - { - int i; - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_ctxt) - { - if (ctxt == process->current_state->context) - process->current_state = &process->default_state; - - int fake_shareList = process->glstates[i]->fake_shareList; - process->glstates[i]->ref --; - if (process->glstates[i]->ref == 0) - { - fprintf(stderr, "destroy_gl_state fake_ctxt = %d\n", process->glstates[i]->fake_ctxt); - destroy_gl_state(process->glstates[i]); - free(process->glstates[i]); - memmove(&process->glstates[i], &process->glstates[i+1], (process->nbGLStates-i-1) * sizeof(GLState*)); - process->nbGLStates--; - } - - if (fake_shareList) - { - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_shareList) - { - process->glstates[i]->ref --; - if (process->glstates[i]->ref == 0) - { - fprintf(stderr, "destroy_gl_state fake_ctxt = %d\n", process->glstates[i]->fake_ctxt); - destroy_gl_state(process->glstates[i]); - free(process->glstates[i]); - memmove(&process->glstates[i], &process->glstates[i+1], (process->nbGLStates-i-1) * sizeof(GLState*)); - process->nbGLStates--; - } - break; - } - } - } - - glXDestroyContext(pConn->Display, ctxt); - unset_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - - break; - } - } - } - break; - } - - case glXQueryVersion_func: - { - ret_int = glXQueryVersion(pConn->Display, (int*)args[1], (int*)args[2]); - break; - } - - case glGetString_func: - { - ret_str = (char*)glGetString(args[0]); - break; - } - - case glXMakeCurrent_func: - { - int i; - GLXDrawable client_drawable = (GLXDrawable)args[1]; - GLXDrawable drawable = 0; - int fake_ctxt = args[2]; - if (display_function_call) fprintf(stderr, "client_drawable=%p fake_ctx=%d\n", (void*)client_drawable, fake_ctxt); - - if (client_drawable == 0 && fake_ctxt == 0) - { - ret_int = glXMakeCurrent(pConn->Display, 0, NULL); - process->current_state = &process->default_state; - } - else if ((drawable = (GLXDrawable)get_association_fakepbuffer_pbuffer(process, (void*)client_drawable))) - { - GLXContext ctxt = get_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%d) (*)!\n", fake_ctxt); - ret_int = 0; - } - else - { - ret_int = glXMakeCurrent(pConn->Display, drawable, ctxt); - } - } - else - { - GLXContext ctxt = get_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt); - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%d)!\n", fake_ctxt); - ret_int = 0; - } - else - { - drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - if (drawable == 0) - { - XVisualInfo* vis = (XVisualInfo*)get_association_fakecontext_visual(process, (void*)(long)fake_ctxt); - if (vis == NULL) - vis = get_default_visual(pConn->Display); - /*if (pConn->local_connection) - drawable = client_drawable; - else*/ - { - if (/*pConn->local_connection &&*/ client_drawable == RootWindow(pConn->Display, 0)) - { - drawable = client_drawable; - } - else - { - drawable = create_window(pConn, (pConn->local_connection) ? (Window)client_drawable : 0, vis, "", 0, 0, 480, 800);/* Default Window 크?綬�Simulator 크???? ?????磯?.*/ - } - //fprintf(stderr, "creating window\n"); - } - set_association_clientdrawable_serverdrawable(process, (void*)client_drawable, (void*)drawable); - } - - ret_int = glXMakeCurrent(pConn->Display, drawable, ctxt); - } - } - - if (ret_int) - { - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->fake_ctxt == fake_ctxt) - { - process->current_state = process->glstates[i]; /* HACK !!! REMOVE */ - process->current_state->drawable = drawable; - break; - } - } - } - break; - } - - case glXSwapBuffers_func: - { - GLXDrawable client_drawable = args[1]; - if (display_function_call) fprintf(stderr, "client_drawable=%p\n", (void*)client_drawable); - - GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - if (drawable == 0) - { - fprintf(stderr, "unknown client_drawable (%p) !\n", (void*)client_drawable); - } - else - { - if (client_cursor.pixels && pConn->local_connection == 0) - { - glPushAttrib(GL_ALL_ATTRIB_BITS); - glPushClientAttrib(GL_ALL_ATTRIB_BITS); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0,process->currentDrawablePos.width,process->currentDrawablePos.height,0,-1,1); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glPixelZoom(1,-1); - - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); - glPixelStorei(GL_UNPACK_LSB_FIRST, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glShadeModel(GL_SMOOTH); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - int i,numUnits; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &numUnits); - for(i=0;iDisplay, drawable); - } - break; - } - - case glXIsDirect_func: - { - GLXContext fake_ctxt = (GLXContext)args[1]; - if (display_function_call) fprintf(stderr, "fake_ctx=%p\n", fake_ctxt); - GLXContext ctxt = get_association_fakecontext_glxcontext(process, fake_ctxt); - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); - ret_char = False; - } - else - { - ret_char = glXIsDirect(pConn->Display, ctxt); - } - break; - } - - case glXGetConfig_func: - { - int visualid = args[1]; - XVisualInfo* vis = NULL; - if (visualid) - vis = get_visual_info_from_visual_id(pConn, visualid); - if (vis == NULL) - vis = get_default_visual(pConn->Display); - ret_int = glXGetConfig(pConn->Display, vis, args[2], (int*)args[3]); - break; - } - - case glXGetConfig_extended_func: - { - int visualid = args[1]; - int n = args[2]; - int i; - XVisualInfo* vis = NULL; - int* attribs = (int*)args[3]; - int* values = (int*)args[4]; - int* res = (int*)args[5]; - - if (visualid) - vis = get_visual_info_from_visual_id(pConn, visualid); - if (vis == NULL) - vis = get_default_visual(pConn->Display); - - for(i=0;iDisplay, vis, attribs[i], &values[i]); - } - break; - } - - case glXUseXFont_func: - { - /* implementation is client-side only :-) */ - break; - } - - - case glXQueryExtension_func: - { - ret_int = glXQueryExtension(pConn->Display, (int*)args[1], (int*)args[2]); - break; - } - - case glXChooseFBConfig_func: - { - GET_EXT_PTR(GLXFBConfig*, glXChooseFBConfig, (Display*, int, int*, int*)); - if (process->nfbconfig == MAX_FBCONFIG) - { - *(int*)args[3] = 0; - ret_int = 0; - } - else - { - GLXFBConfig* fbconfigs = ptr_func_glXChooseFBConfig(pConn->Display, args[1], (int*)args[2], (int*)args[3]); - if (fbconfigs) - { - process->fbconfigs[process->nfbconfig] = fbconfigs; - process->fbconfigs_max[process->nfbconfig] = *(int*)args[3]; - process->nfbconfig++; - ret_int = 1 + process->nfbconfig_total; - process->nfbconfig_total += process->fbconfigs_max[process->nfbconfig]; - } - else - { - ret_int = 0; - } - } - break; - } - - case glXChooseFBConfigSGIX_func: - { - GET_EXT_PTR(GLXFBConfigSGIX*, glXChooseFBConfigSGIX, (Display*, int, int*, int*)); - if (process->nfbconfig == MAX_FBCONFIG) - { - *(int*)args[3] = 0; - ret_int = 0; - } - else - { - GLXFBConfigSGIX* fbconfigs = ptr_func_glXChooseFBConfigSGIX(pConn->Display, args[1], (int*)args[2], (int*)args[3]); - if (fbconfigs) - { - process->fbconfigs[process->nfbconfig] = fbconfigs; - process->fbconfigs_max[process->nfbconfig] = *(int*)args[3]; - process->nfbconfig++; - ret_int = 1 + process->nfbconfig_total; - process->nfbconfig_total += process->fbconfigs_max[process->nfbconfig]; - } - else - { - ret_int = 0; - } - } - break; - } - - case glXGetFBConfigs_func: - { - GET_EXT_PTR(GLXFBConfig*, glXGetFBConfigs, (Display*, int, int*)); - if (process->nfbconfig == MAX_FBCONFIG) - { - *(int*)args[2] = 0; - ret_int = 0; - } - else - { - GLXFBConfig* fbconfigs = ptr_func_glXGetFBConfigs(pConn->Display, args[1], (int*)args[2]); - if (fbconfigs) - { - process->fbconfigs[process->nfbconfig] = fbconfigs; - process->fbconfigs_max[process->nfbconfig] = *(int*)args[2]; - process->nfbconfig++; - ret_int = 1 + process->nfbconfig_total; - process->nfbconfig_total += process->fbconfigs_max[process->nfbconfig]; - } - else - { - ret_int = 0; - } - } - break; - } - - case glXDestroyWindow_func: - { - GLXDrawable client_drawable = args[1]; - if (display_function_call) fprintf(stderr, "client_drawable=%p\n", (void*)client_drawable); - - GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - - destroy_window(pConn, (Window)drawable); - - int i; - for(i=0;process->association_clientdrawable_serverdrawable[i].key != NULL;i++) - { - if (process->association_clientdrawable_serverdrawable[i].key == (void *) client_drawable) - { - process->association_clientdrawable_serverdrawable[i].key = NULL; - process->association_clientdrawable_serverdrawable[i].value = NULL; - } - } - - for(i=0;inbGLStates;i++) - { - if (process->glstates[i]->drawable == drawable) - { - process->glstates[i]->drawable = 0; - } - } - - if( process->current_state->drawable == drawable ) - process->current_state = &process->default_state; - - break; - } - - - case glXCreatePbuffer_func: - { - GET_EXT_PTR(GLXPbuffer, glXCreatePbuffer, (Display*, GLXFBConfig, int*)); - int client_fbconfig = args[1]; - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - { - GLXPbuffer pbuffer = ptr_func_glXCreatePbuffer(pConn->Display, fbconfig, (int*)args[2]); - fprintf(stderr, "glXCreatePbuffer --> %X\n", (int)pbuffer); - if (pbuffer) - { - process->next_available_pbuffer_number ++; - int fake_pbuffer = process->next_available_pbuffer_number; - set_association_fakepbuffer_pbuffer(process, (void*)(long)fake_pbuffer, (void*)pbuffer); - fprintf(stderr, "set_association_fakepbuffer_pbuffer(%d, %X)\n", fake_pbuffer, (int)pbuffer); - ret_int = fake_pbuffer; - } - } - break; - } - - case glXCreateGLXPbufferSGIX_func: - { - GET_EXT_PTR(GLXPbufferSGIX, glXCreateGLXPbufferSGIX, (Display*, GLXFBConfig, int, int, int*)); - int client_fbconfig = args[1]; - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - { - GLXPbufferSGIX pbuffer = ptr_func_glXCreateGLXPbufferSGIX(pConn->Display, fbconfig, args[2], args[3], (int*)args[4]); - if (pbuffer) - { - process->next_available_pbuffer_number ++; - int fake_pbuffer = process->next_available_pbuffer_number; - set_association_fakepbuffer_pbuffer(process, (void*)(long)fake_pbuffer, (void*)pbuffer); - ret_int = fake_pbuffer; - } - } - break; - } - - case glXDestroyPbuffer_func: - { - GET_EXT_PTR(void, glXDestroyPbuffer, (Display*, GLXPbuffer)); - GLXPbuffer fake_pbuffer = (GLXPbuffer)args[1]; - if (display_function_call) fprintf(stderr, "fake_pbuffer=%d\n", (int)fake_pbuffer); - - GLXPbuffer pbuffer = (GLXPbuffer)get_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - if (pbuffer == 0) - { - fprintf(stderr, "invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - } - else - { - if (!is_gl_vendor_ati(pConn->Display)) - ptr_func_glXDestroyPbuffer(pConn->Display, pbuffer); - unset_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - } - break; - } - - case glXDestroyGLXPbufferSGIX_func: - { - GET_EXT_PTR(void, glXDestroyGLXPbufferSGIX, (Display*, GLXPbuffer)); - GLXPbuffer fake_pbuffer = (GLXPbuffer)args[1]; - if (display_function_call) fprintf(stderr, "fake_pbuffer=%d\n", (int)fake_pbuffer); - - GLXPbuffer pbuffer = (GLXPbuffer)get_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - if (pbuffer == 0) - { - fprintf(stderr, "invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - } - else - { - if (!is_gl_vendor_ati(pConn->Display)) - ptr_func_glXDestroyGLXPbufferSGIX(pConn->Display, pbuffer); - unset_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - } - break; - } - - case glXBindTexImageATI_func: - { - GET_EXT_PTR(void, glXBindTexImageATI, (Display*, GLXPbuffer, int)); - GLXPbuffer fake_pbuffer = (GLXPbuffer)args[1]; - if (display_function_call) fprintf(stderr, "fake_pbuffer=%d\n", (int)fake_pbuffer); - - GLXPbuffer pbuffer = (GLXPbuffer)get_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - if (pbuffer == 0) - { - fprintf(stderr, "glXBindTexImageATI : invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - } - else - { - ptr_func_glXBindTexImageATI(pConn->Display, pbuffer, args[2]); - } - break; - } - - case glXReleaseTexImageATI_func: - { - GET_EXT_PTR(void, glXReleaseTexImageATI, (Display*, GLXPbuffer, int)); - GLXPbuffer fake_pbuffer = (GLXPbuffer)args[1]; - if (display_function_call) fprintf(stderr, "fake_pbuffer=%d\n", (int)fake_pbuffer); - - GLXPbuffer pbuffer = (GLXPbuffer)get_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - if (pbuffer == 0) - { - fprintf(stderr, "glXReleaseTexImageATI : invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - } - else - { - ptr_func_glXReleaseTexImageATI(pConn->Display, pbuffer, args[2]); - } - break; - } - - case glXBindTexImageARB_func: - { - GET_EXT_PTR(Bool, glXBindTexImageARB, (Display*, GLXPbuffer, int)); - GLXPbuffer fake_pbuffer = (GLXPbuffer)args[1]; - if (display_function_call) fprintf(stderr, "fake_pbuffer=%d\n", (int)fake_pbuffer); - - GLXPbuffer pbuffer = (GLXPbuffer)get_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - if (pbuffer == 0) - { - fprintf(stderr, "glXBindTexImageARB : invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - ret_int = 0; - } - else - { - ret_int = ptr_func_glXBindTexImageARB(pConn->Display, pbuffer, args[2]); - } - break; - } - - case glXReleaseTexImageARB_func: - { - GET_EXT_PTR(Bool, glXReleaseTexImageARB, (Display*, GLXPbuffer, int)); - GLXPbuffer fake_pbuffer = (GLXPbuffer)args[1]; - if (display_function_call) fprintf(stderr, "fake_pbuffer=%d\n", (int)fake_pbuffer); - - GLXPbuffer pbuffer = (GLXPbuffer)get_association_fakepbuffer_pbuffer(process, (void*)fake_pbuffer); - if (pbuffer == 0) - { - fprintf(stderr, "glXReleaseTexImageARB : invalid fake_pbuffer (%d) !\n", (int)fake_pbuffer); - ret_int = 0; - } - else - { - ret_int = ptr_func_glXReleaseTexImageARB(pConn->Display, pbuffer, args[2]); - } - break; - } - - case glXGetFBConfigAttrib_func: - { - GET_EXT_PTR(int, glXGetFBConfigAttrib, (Display*, GLXFBConfig, int, int*)); - int client_fbconfig = args[1]; - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - ret_int = ptr_func_glXGetFBConfigAttrib(pConn->Display, fbconfig, args[2], (int*)args[3]); - break; - } - - case glXGetFBConfigAttrib_extended_func: - { - GET_EXT_PTR(int, glXGetFBConfigAttrib, (Display*, GLXFBConfig, int, int*)); - int client_fbconfig = args[1]; - int n = args[2]; - int i; - int* attribs = (int*)args[3]; - int* values = (int*)args[4]; - int* res = (int*)args[5]; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - - for(i=0;iDisplay, fbconfig, attribs[i], &values[i]); - } - else - { - res[i] = 0; - } - } - break; - } - - case glXGetFBConfigAttribSGIX_func: - { - GET_EXT_PTR(int, glXGetFBConfigAttribSGIX, (Display*, GLXFBConfigSGIX, int, int*)); - int client_fbconfig = args[1]; - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - ret_int = ptr_func_glXGetFBConfigAttribSGIX(pConn->Display, (GLXFBConfigSGIX)fbconfig, args[2], (int*)args[3]); - break; - } - - case glXQueryContext_func: - { - GET_EXT_PTR(int, glXQueryContext, (Display*, GLXContext, int, int*)); - GLXContext fake_ctxt = (GLXContext)args[1]; - if (display_function_call) fprintf(stderr, "fake_ctx=%p\n", fake_ctxt); - GLXContext ctxt = get_association_fakecontext_glxcontext(process, fake_ctxt); - if (ctxt == NULL) - { - fprintf(stderr, "invalid fake_ctxt (%p) !\n", fake_ctxt); - ret_int = 0; - } - else - { - ret_int = ptr_func_glXQueryContext(pConn->Display, ctxt, args[2], (int*)args[3]); - } - break; - } - - case glXQueryDrawable_func: - { - GET_EXT_PTR(void, glXQueryDrawable, (Display*, GLXDrawable, int, int*)); - GLXDrawable client_drawable = (GLXDrawable)args[1]; - GLXDrawable drawable = get_association_clientdrawable_serverdrawable(process, client_drawable); - if (display_function_call) fprintf(stderr, "client_drawable=%d\n", (int)client_drawable); - if (drawable == 0) - { - fprintf(stderr, "invalid client_drawable (%d) !\n", (int)client_drawable); - } - else - { - ptr_func_glXQueryDrawable(pConn->Display, drawable, args[2], (int*)args[3]); - } - break; - } - - case glXQueryGLXPbufferSGIX_func: - { - GET_EXT_PTR(int, glXQueryGLXPbufferSGIX, (Display*, GLXFBConfigSGIX, int, int*)); - int client_fbconfig = args[1]; - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - ret_int = ptr_func_glXQueryGLXPbufferSGIX(pConn->Display, (GLXFBConfigSGIX)fbconfig, args[2], (int*)args[3]); - break; - } - - case glXCreateContextWithConfigSGIX_func: - { - GET_EXT_PTR(GLXContext, glXCreateContextWithConfigSGIX, (Display*, GLXFBConfigSGIX, int, GLXContext, int)); - int client_fbconfig = args[1]; - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - { - GLXContext shareList = get_association_fakecontext_glxcontext(process, (void*)args[3]); - process->next_available_context_number ++; - int fake_ctxt = process->next_available_context_number; - GLXContext ctxt = ptr_func_glXCreateContextWithConfigSGIX(pConn->Display, (GLXFBConfigSGIX)fbconfig, args[2], shareList, args[4]); - set_association_fakecontext_glxcontext(process, (void*)(long)fake_ctxt, ctxt); - ret_int = fake_ctxt; - } - break; - } - - case glXGetVisualFromFBConfig_func: - { - GET_EXT_PTR(XVisualInfo*, glXGetVisualFromFBConfig, (Display*, GLXFBConfig)); - int client_fbconfig = args[1]; - ret_int = 0; - GLXFBConfig fbconfig = get_fbconfig(process, client_fbconfig); - if (fbconfig) - { - AssocAttribListVisual *tabAssocAttribListVisual = (AssocAttribListVisual *)pConn->tabAssocAttribListVisual ; - XVisualInfo* vis = ptr_func_glXGetVisualFromFBConfig(pConn->Display, fbconfig); - ret_int = (vis) ? vis->visualid : 0; - if (vis) - { - pConn->tabAssocAttribListVisual = tabAssocAttribListVisual = - realloc(tabAssocAttribListVisual, sizeof(AssocAttribListVisual) * (pConn->nTabAssocAttribListVisual+1)); - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribListLength = 0; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].attribList = NULL; - tabAssocAttribListVisual[pConn->nTabAssocAttribListVisual].visInfo = vis; - pConn->nTabAssocAttribListVisual++; - pConn->tabAssocAttribListVisual = tabAssocAttribListVisual; - } - if (display_function_call) fprintf(stderr, "visualid = %d\n", ret_int); - } - break; - } - - case glXSwapIntervalSGI_func: - { - GET_EXT_PTR(int, glXSwapIntervalSGI, (int)); - ret_int = ptr_func_glXSwapIntervalSGI(args[0]); - break; - } - - case glXGetProcAddress_fake_func: - { - if (display_function_call) fprintf(stderr, "%s\n", (char*)args[0]); - ret_int = glXGetProcAddressARB((const GLubyte*)args[0]) != NULL; - break; - } - - case glXGetProcAddress_global_fake_func: - { - int nbElts = args[0]; - char* huge_buffer = (char*)args[1]; - char* result = (char*)args[2]; - int i; - - for(i=0;icurrent_state->textureAllocator, client_texture); - server_texture = process->current_state->tabTextures[client_texture]; - if (server_texture == 0) - { - glGenTextures(1, &server_texture); - process->current_state->tabTextures[client_texture] = server_texture; - } - glBindTexture(target, server_texture); - } - break; - } - - case glGenTextures_fake_func: - { - GET_EXT_PTR(void, glGenTextures, (GLsizei n, GLuint *textures)); - int i; - int n = args[0]; - unsigned int* clientTabTextures = malloc(n * sizeof(int)); - unsigned int* serverTabTextures = malloc(n * sizeof(int)); - - alloc_range(process->current_state->textureAllocator, n, clientTabTextures); - - ptr_func_glGenTextures(n, serverTabTextures); - for(i=0;icurrent_state->tabTextures[clientTabTextures[i]] = serverTabTextures[i]; - } - - free(clientTabTextures); - free(serverTabTextures); - break; - } - - - case glDeleteTextures_func: - { - GET_EXT_PTR(void, glDeleteTextures, (GLsizei n, const GLuint *textures)); - int i; - int n = args[0]; - unsigned int* clientTabTextures = (unsigned int*)args[1]; - - delete_range(process->current_state->textureAllocator, n, clientTabTextures); - - unsigned int* serverTabTextures = malloc(n * sizeof(int)); - for(i=0;icurrent_state->tabTextures[clientTabTextures[i]] = 0; - } - free(serverTabTextures); - break; - } - - case glPrioritizeTextures_func: - { - GET_EXT_PTR(void, glPrioritizeTextures, (GLsizei n, const GLuint *textures, const GLclampf *priorities)); - - int i; - int n = args[0]; - unsigned int* textures = (unsigned int*)args[1]; - for(i=0;icurrent_state->tabLists[first_client + i] = 0; - } - delete_consecutive_values(process->current_state->listAllocator, first_client, n); - break; - } - - case glGenLists_fake_func: - { - int i; - int n = args[0]; - unsigned int server_first = glGenLists(n); - if (server_first) - { - unsigned int client_first = alloc_range(process->current_state->listAllocator, n, NULL); - for(i=0;icurrent_state->tabLists[client_first + i] = server_first + i; - } - } - break; - } - - case glNewList_func: - { - unsigned int client_list = args[0]; - int mode = args[1]; - alloc_value(process->current_state->listAllocator, client_list); - unsigned int server_list = get_server_list(process, client_list); - if (server_list == 0) - { - server_list = glGenLists(1); - process->current_state->tabLists[client_list] = server_list; - } - glNewList(server_list, mode); - break; - } - - case glCallList_func: - { - unsigned int client_list = args[0]; - unsigned int server_list = get_server_list(process, client_list); - glCallList(server_list); - break; - } - - case glCallLists_func: - { - int i; - int n = args[0]; - int type = args[1]; - const GLvoid* lists = (const GLvoid*)args[2]; - int* new_lists = malloc(sizeof(int) * n); - for(i=0;icurrent_state->bufferAllocator, n, clientTabBuffers); - - ptr_func_glGenBuffersARB(n, serverTabBuffers); - for(i=0;icurrent_state->tabBuffers[clientTabBuffers[i]] = serverTabBuffers[i]; - } - - free(clientTabBuffers); - free(serverTabBuffers); - break; - } - - - case glDeleteBuffersARB_func: - { - GET_EXT_PTR(void, glDeleteBuffersARB, (int,int*)); - int i; - int n = args[0]; - unsigned int* clientTabBuffers = (unsigned int*)args[1]; - - delete_range(process->current_state->bufferAllocator, n, clientTabBuffers); - - int* serverTabBuffers = malloc(n * sizeof(int)); - for(i=0;icurrent_state->tabBuffers[clientTabBuffers[i]] = 0; - } - free(serverTabBuffers); - break; - } - - case glIsBufferARB_func: - { - GET_EXT_PTR(int, glIsBufferARB, (int)); - unsigned int client_buffer = args[0]; - unsigned int server_buffer = get_server_buffer(process, client_buffer); - if (server_buffer) - ret_int = ptr_func_glIsBufferARB(server_buffer); - else - ret_int = 0; - break; - } - - /* Endo of buffer stuff */ - - case glShaderSourceARB_fake_func: - { - GET_EXT_PTR(void, glShaderSourceARB, (int,int,char**,void*)); - int size = args[1]; - int i; - int acc_length = 0; - GLcharARB** tab_prog = malloc(size * sizeof(GLcharARB*)); - int* tab_length = (int*)args[3]; - for(i=0;icurrent_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, (void*)args[5], bytes_size); - /*fprintf(stderr, "glVertexPointer_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - glVertexPointer(size, type, stride, process->current_state->vertexPointer); - break; - } - - case glNormalPointer_fake_func: - { - int offset = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->normalPointerSize = MAX(process->current_state->normalPointerSize, offset + bytes_size); - process->current_state->normalPointer = realloc(process->current_state->normalPointer, process->current_state->normalPointerSize); - memcpy(process->current_state->normalPointer + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glNormalPointer_fake_func type=%d, stride=%d, byte_size=%d\n", type, stride, bytes_size); - glNormalPointer(type, stride, process->current_state->normalPointer); - break; - } - - case glIndexPointer_fake_func: - { - int offset = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->indexPointerSize = MAX(process->current_state->indexPointerSize, offset + bytes_size); - process->current_state->indexPointer = realloc(process->current_state->indexPointer, process->current_state->indexPointerSize); - memcpy(process->current_state->indexPointer + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glIndexPointer_fake_func type=%d, stride=%d, byte_size=%d\n", type, stride, bytes_size); - glIndexPointer(type, stride, process->current_state->indexPointer); - break; - } - - case glEdgeFlagPointer_fake_func: - { - int offset = args[0]; - int stride = args[1]; - int bytes_size = args[2]; - process->current_state->edgeFlagPointerSize = MAX(process->current_state->edgeFlagPointerSize, offset + bytes_size); - process->current_state->edgeFlagPointer = realloc(process->current_state->edgeFlagPointer, process->current_state->edgeFlagPointerSize); - memcpy(process->current_state->edgeFlagPointer + offset, (void*)args[3], bytes_size ); - //fprintf(stderr, "glEdgeFlagPointer_fake_func stride = %d, bytes_size=%d\n", stride, bytes_size); - glEdgeFlagPointer(stride, process->current_state->edgeFlagPointer); - break; - } - - case glVertexAttribPointerARB_fake_func: - { - GET_EXT_PTR(void, glVertexAttribPointerARB, (int,int,int,int,int,void*)); - int offset = args[0]; - int index = args[1]; - int size = args[2]; - int type = args[3]; - int normalized = args[4]; - int stride = args[5]; - int bytes_size = args[6]; - process->current_state->vertexAttribPointerSize[index] = MAX(process->current_state->vertexAttribPointerSize[index], offset + bytes_size); - process->current_state->vertexAttribPointer[index] = realloc(process->current_state->vertexAttribPointer[index], - process->current_state->vertexAttribPointerSize[index]); - memcpy(process->current_state->vertexAttribPointer[index] + offset, (void*)args[7], bytes_size); - ptr_func_glVertexAttribPointerARB(index, size, type, normalized, stride, - process->current_state->vertexAttribPointer[index]); - break; - } - - case glVertexAttribPointerNV_fake_func: - { - GET_EXT_PTR(void, glVertexAttribPointerNV, (int,int,int,int,void*)); - int offset = args[0]; - int index = args[1]; - int size = args[2]; - int type = args[3]; - int stride = args[4]; - int bytes_size = args[5]; - process->current_state->vertexAttribPointerNVSize[index] = MAX(process->current_state->vertexAttribPointerNVSize[index], offset + bytes_size); - process->current_state->vertexAttribPointerNV[index] = realloc(process->current_state->vertexAttribPointerNV[index], - process->current_state->vertexAttribPointerNVSize[index]); - memcpy(process->current_state->vertexAttribPointerNV[index] + offset, (void*)args[6], bytes_size); - ptr_func_glVertexAttribPointerNV(index, size, type, stride, - process->current_state->vertexAttribPointerNV[index]); - break; - } - - case glColorPointer_fake_func: - { - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->colorPointerSize = MAX(process->current_state->colorPointerSize, offset + bytes_size); - process->current_state->colorPointer = realloc(process->current_state->colorPointer, process->current_state->colorPointerSize); - memcpy(process->current_state->colorPointer + offset, (void*)args[5], bytes_size); - //fprintf(stderr, "glColorPointer_fake_func bytes_size = %d\n", bytes_size); - glColorPointer(size, type, stride, process->current_state->colorPointer); - - break; - } - - case glSecondaryColorPointer_fake_func: - { - GET_EXT_PTR(void, glSecondaryColorPointer, (int,int,int,void*)); - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->secondaryColorPointerSize = MAX(process->current_state->secondaryColorPointerSize, offset + bytes_size); - process->current_state->secondaryColorPointer = realloc(process->current_state->secondaryColorPointer, process->current_state->secondaryColorPointerSize); - memcpy(process->current_state->secondaryColorPointer + offset, (void*)args[5], bytes_size); - //fprintf(stderr, "glSecondaryColorPointer_fake_func bytes_size = %d\n", bytes_size); - ptr_func_glSecondaryColorPointer(size, type, stride, process->current_state->secondaryColorPointer); - - break; - } - - case glPushClientAttrib_func: - { - int mask = args[0]; - if (process->current_state->clientStateSp < MAX_CLIENT_STATE_STACK_SIZE) - { - process->current_state->clientStateStack[process->current_state->clientStateSp].mask = mask; - if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) - { - process->current_state->clientStateStack[process->current_state->clientStateSp].activeTextureIndex = - process->current_state->activeTextureIndex; - } - process->current_state->clientStateSp++; - } - glPushClientAttrib(mask); - break; - } - - case glPopClientAttrib_func: - { - if (process->current_state->clientStateSp > 0) - { - process->current_state->clientStateSp--; - if (process->current_state->clientStateStack[process->current_state->clientStateSp].mask & GL_CLIENT_VERTEX_ARRAY_BIT) - { - process->current_state->activeTextureIndex = - process->current_state->clientStateStack[process->current_state->clientStateSp].activeTextureIndex; - } - } - glPopClientAttrib(); - break; - } - - case glClientActiveTexture_func: - case glClientActiveTextureARB_func: - { - int activeTexture = args[0]; - process->current_state->activeTextureIndex = activeTexture - GL_TEXTURE0_ARB; - do_glClientActiveTextureARB(activeTexture); - break; - } - - case glTexCoordPointer_fake_func: - { - int offset = args[0]; - int index = args[1]; - int size = args[2]; - int type = args[3]; - int stride = args[4]; - int bytes_size = args[5]; - process->current_state->texCoordPointerSize[index] = MAX(process->current_state->texCoordPointerSize[index], offset + bytes_size); - process->current_state->texCoordPointer[index] = realloc(process->current_state->texCoordPointer[index], process->current_state->texCoordPointerSize[index]); - memcpy(process->current_state->texCoordPointer[index] + offset, (void*)args[6], bytes_size); - /*fprintf(stderr, "glTexCoordPointer_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + index); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[index]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glWeightPointerARB_fake_func: - { - GET_EXT_PTR(void, glWeightPointerARB, (int,int,int,void*)); - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->weightPointerSize = MAX(process->current_state->weightPointerSize, offset + bytes_size); - process->current_state->weightPointer = realloc(process->current_state->weightPointer, process->current_state->weightPointerSize); - memcpy(process->current_state->weightPointer + offset, (void*)args[5], bytes_size); - /*fprintf(stderr, "glWeightPointerARB_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - ptr_func_glWeightPointerARB(size, type, stride, process->current_state->weightPointer); - break; - } - - case glMatrixIndexPointerARB_fake_func: - { - GET_EXT_PTR(void, glMatrixIndexPointerARB, (int,int,int,void*)); - int offset = args[0]; - int size = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->matrixIndexPointerSize = MAX(process->current_state->matrixIndexPointerSize, offset + bytes_size); - process->current_state->matrixIndexPointer = realloc(process->current_state->matrixIndexPointer, process->current_state->matrixIndexPointerSize); - memcpy(process->current_state->matrixIndexPointer + offset, (void*)args[5], bytes_size); - /*fprintf(stderr, "glMatrixIndexPointerARB_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - ptr_func_glMatrixIndexPointerARB(size, type, stride, process->current_state->matrixIndexPointer); - break; - } - - case glFogCoordPointer_fake_func: - { - GET_EXT_PTR(void, glFogCoordPointer, (int,int,void*)); - int offset = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->fogCoordPointerSize = MAX(process->current_state->fogCoordPointerSize, offset + bytes_size); - process->current_state->fogCoordPointer = realloc(process->current_state->fogCoordPointer, process->current_state->fogCoordPointerSize); - memcpy(process->current_state->fogCoordPointer + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glFogCoordPointer_fake_func type=%d, stride=%d, byte_size=%d\n", type, stride, bytes_size); - ptr_func_glFogCoordPointer(type, stride, process->current_state->fogCoordPointer); - break; - } - - case glVariantPointerEXT_fake_func: - { - GET_EXT_PTR(void, glVariantPointerEXT, (int,int,int,void*)); - int offset = args[0]; - int id = args[1]; - int type = args[2]; - int stride = args[3]; - int bytes_size = args[4]; - process->current_state->variantPointerEXTSize[id] = MAX(process->current_state->variantPointerEXTSize[id], offset + bytes_size); - process->current_state->variantPointerEXT[id] = realloc(process->current_state->variantPointerEXT[id], process->current_state->variantPointerEXTSize[id]); - memcpy(process->current_state->variantPointerEXT[id] + offset, (void*)args[5], bytes_size); - //fprintf(stderr, "glVariantPointerEXT_fake_func[%d] type=%d, stride=%d, byte_size=%d\n", id, type, stride, bytes_size); - ptr_func_glVariantPointerEXT(id, type, stride, process->current_state->variantPointerEXT[id]); - break; - } - - case glInterleavedArrays_fake_func: - { - GET_EXT_PTR(void, glInterleavedArrays, (int,int,void*)); - int offset = args[0]; - int format = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->interleavedArraysSize = MAX(process->current_state->interleavedArraysSize, offset + bytes_size); - process->current_state->interleavedArrays = realloc(process->current_state->interleavedArrays, process->current_state->interleavedArraysSize); - memcpy(process->current_state->interleavedArrays + offset, (void*)args[4], bytes_size); - //fprintf(stderr, "glInterleavedArrays_fake_func format=%d, stride=%d, byte_size=%d\n", format, stride, bytes_size); - ptr_func_glInterleavedArrays(format, stride, process->current_state->interleavedArrays); - break; - } - - case glElementPointerATI_fake_func: - { - GET_EXT_PTR(void, glElementPointerATI, (int,void*)); - int type = args[0]; - int bytes_size = args[1]; - process->current_state->elementPointerATISize = bytes_size; - process->current_state->elementPointerATI = realloc(process->current_state->elementPointerATI, process->current_state->elementPointerATISize); - memcpy(process->current_state->elementPointerATI, (void*)args[2], bytes_size); - //fprintf(stderr, "glElementPointerATI_fake_func type=%d, byte_size=%d\n", type, bytes_size); - ptr_func_glElementPointerATI(type, process->current_state->elementPointerATI); - break; - } - - case glTexCoordPointer01_fake_func: - { - int size = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->texCoordPointerSize[0] = bytes_size; - process->current_state->texCoordPointer[0] = realloc(process->current_state->texCoordPointer[0], bytes_size); - memcpy(process->current_state->texCoordPointer[0], (void*)args[4], bytes_size); - /*fprintf(stderr, "glTexCoordPointer01_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glTexCoordPointer012_fake_func: - { - int size = args[0]; - int type = args[1]; - int stride = args[2]; - int bytes_size = args[3]; - process->current_state->texCoordPointerSize[0] = bytes_size; - process->current_state->texCoordPointer[0] = realloc(process->current_state->texCoordPointer[0], bytes_size); - memcpy(process->current_state->texCoordPointer[0], (void*)args[4], bytes_size); - /*fprintf(stderr, "glTexCoordPointer012_fake_func size=%d, type=%d, stride=%d, byte_size=%d\n", - size, type, stride, bytes_size);*/ - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2); - glTexCoordPointer(size, type, stride, process->current_state->texCoordPointer[0]); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - - case glVertexAndNormalPointer_fake_func: - { - int vertexPointerSize = args[0]; - int vertexPointerType = args[1]; - int vertexPointerStride = args[2]; - int normalPointerType = args[3]; - int normalPointerStride = args[4]; - int bytes_size = args[5]; - void* ptr = (void*)args[6]; - process->current_state->vertexPointerSize = bytes_size; - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, bytes_size); - memcpy(process->current_state->vertexPointer, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, vertexPointerStride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, normalPointerStride, process->current_state->vertexPointer); - break; - } - - case glVertexNormalPointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset= args[i++]; - int normalPointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - break; - } - - case glTuxRacerDrawElements_fake_func: - { - int mode = args[0]; - int count = args[1]; - int isColorEnabled = args[2]; - void* ptr = (void*)args[3]; - int stride = 6 * sizeof(float) + ((isColorEnabled) ? 4 * sizeof(unsigned char) : 0); - glVertexPointer( 3, GL_FLOAT, stride, ptr); - glNormalPointer( GL_FLOAT, stride, ptr + 3 * sizeof(float)); - if (isColorEnabled) - glColorPointer( 4, GL_UNSIGNED_BYTE, stride, ptr + 6 * sizeof(float)); - glDrawArrays(mode, 0, count); - break; - } - - case glVertexNormalColorPointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset= args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - break; - } - - case glVertexColorTexCoord0PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalTexCoord0PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalTexCoord01PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalTexCoord012PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int texCoord2PointerOffset = args[i++]; - int texCoord2PointerSize = args[i++]; - int texCoord2PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2); - glTexCoordPointer(texCoord2PointerSize, texCoord2PointerType, stride, process->current_state->vertexPointer + texCoord2PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalColorTexCoord0PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalColorTexCoord01PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case glVertexNormalColorTexCoord012PointerInterlaced_fake_func: - { - int i = 0; - int offset = args[i++]; - int vertexPointerSize = args[i++]; - int vertexPointerType = args[i++]; - int stride = args[i++]; - int normalPointerOffset = args[i++]; - int normalPointerType = args[i++]; - int colorPointerOffset = args[i++]; - int colorPointerSize = args[i++]; - int colorPointerType = args[i++]; - int texCoord0PointerOffset = args[i++]; - int texCoord0PointerSize = args[i++]; - int texCoord0PointerType = args[i++]; - int texCoord1PointerOffset = args[i++]; - int texCoord1PointerSize = args[i++]; - int texCoord1PointerType = args[i++]; - int texCoord2PointerOffset = args[i++]; - int texCoord2PointerSize = args[i++]; - int texCoord2PointerType = args[i++]; - int bytes_size = args[i++]; - void* ptr = (void*)args[i++]; - process->current_state->vertexPointerSize = MAX(process->current_state->vertexPointerSize, offset + bytes_size); - process->current_state->vertexPointer = realloc(process->current_state->vertexPointer, process->current_state->vertexPointerSize); - memcpy(process->current_state->vertexPointer + offset, ptr, bytes_size); - glVertexPointer(vertexPointerSize, vertexPointerType, stride, process->current_state->vertexPointer); - glNormalPointer(normalPointerType, stride, process->current_state->vertexPointer + normalPointerOffset); - glColorPointer(colorPointerSize, colorPointerType, stride, process->current_state->vertexPointer + colorPointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 0); - glTexCoordPointer(texCoord0PointerSize, texCoord0PointerType, stride, process->current_state->vertexPointer + texCoord0PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 1); - glTexCoordPointer(texCoord1PointerSize, texCoord1PointerType, stride, process->current_state->vertexPointer + texCoord1PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + 2); - glTexCoordPointer(texCoord2PointerSize, texCoord2PointerType, stride, process->current_state->vertexPointer + texCoord2PointerOffset); - do_glClientActiveTextureARB(GL_TEXTURE0_ARB + process->current_state->activeTextureIndex); - break; - } - - case _glVertexPointer_buffer_func: - { - glVertexPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glNormalPointer_buffer_func: - { - glNormalPointer(args[0],args[1],(void*)args[2]); - break; - } - - case _glColorPointer_buffer_func: - { - glColorPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glSecondaryColorPointer_buffer_func: - { - GET_EXT_PTR(void, glSecondaryColorPointer, (int,int,int,void*)); - ptr_func_glSecondaryColorPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glIndexPointer_buffer_func: - { - glIndexPointer(args[0],args[1],(void*)args[2]); - break; - } - - case _glTexCoordPointer_buffer_func: - { - glTexCoordPointer(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glEdgeFlagPointer_buffer_func: - { - glEdgeFlagPointer(args[0],(void*)args[1]); - break; - } - - case _glVertexAttribPointerARB_buffer_func: - { - GET_EXT_PTR(void, glVertexAttribPointerARB, (int,int,int,int,int,void*)); - ptr_func_glVertexAttribPointerARB(args[0], args[1], args[2], args[3], args[4], (void*)args[5]); - break; - } - - case _glWeightPointerARB_buffer_func: - { - GET_EXT_PTR(void, glWeightPointerARB, (int,int,int,void*)); - ptr_func_glWeightPointerARB(args[0], args[1], args[2], (void*)args[3]); - break; - } - - case _glMatrixIndexPointerARB_buffer_func: - { - GET_EXT_PTR(void, glMatrixIndexPointerARB, (int,int,int,void*)); - ptr_func_glMatrixIndexPointerARB(args[0], args[1], args[2], (void*)args[3]); - break; - } - - case _glFogCoordPointer_buffer_func: - { - GET_EXT_PTR(void, glFogCoordPointer, (int,int,void*)); - ptr_func_glFogCoordPointer(args[0], args[1], (void*)args[2]); - break; - } - - case _glVariantPointerEXT_buffer_func: - { - GET_EXT_PTR(void, glVariantPointerEXT, (int, int,int,void*)); - ptr_func_glVariantPointerEXT(args[0], args[1], args[2], (void*)args[3]); - break; - } - - case _glDrawElements_buffer_func: - { - glDrawElements(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case _glDrawRangeElements_buffer_func: - { - glDrawRangeElements(args[0],args[1],args[2],args[3],args[4],(void*)args[5]); - break; - } - - case _glMultiDrawElements_buffer_func: - { - GET_EXT_PTR(void, glMultiDrawElements, (int,int*,int,void**, int)); - ptr_func_glMultiDrawElements(args[0],(int*)args[1],args[2],(void**)args[3],args[4]); - break; - } - - case _glGetError_fake_func: - { - break; - } - - case glGetIntegerv_func: - { - glGetIntegerv(args[0], (int*)args[1]); - //fprintf(stderr,"glGetIntegerv(%X)=%d\n", (int)args[0], *(int*)args[1]); - break; - } - - case _glReadPixels_pbo_func: - { - glReadPixels(ARG_TO_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_INT(args[2]), ARG_TO_INT(args[3]), ARG_TO_UNSIGNED_INT(args[4]), ARG_TO_UNSIGNED_INT(args[5]), (void*)(args[6])); - break; - } - - case _glDrawPixels_pbo_func: - { - glDrawPixels(ARG_TO_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_UNSIGNED_INT(args[2]), ARG_TO_UNSIGNED_INT(args[3]), (const void*)(args[4])); - break; - } - - case _glMapBufferARB_fake_func: - { - GET_EXT_PTR(GLvoid*, glMapBufferARB, (GLenum, GLenum)); - GET_EXT_PTR(GLboolean, glUnmapBufferARB, (GLenum)); - int target = args[0]; - int size = args[1]; - void* dst_ptr = (void*)args[2]; - void* src_ptr = ptr_func_glMapBufferARB(target, GL_READ_ONLY); - if (src_ptr) - { - memcpy(dst_ptr, src_ptr, size); - ret_int = ptr_func_glUnmapBufferARB(target); - } - else - { - ret_int = 0; - } - break; - } - - case fake_gluBuild2DMipmaps_func: - { - GET_GLU_PTR(GLint, gluBuild2DMipmaps, (GLenum arg_0, GLint arg_1, GLsizei arg_2, GLsizei arg_3, GLenum arg_4, GLenum arg_5, const GLvoid * arg_6)); - if (ptr_func_gluBuild2DMipmaps == NULL) - ptr_func_gluBuild2DMipmaps = mesa_gluBuild2DMipmaps; - ptr_func_gluBuild2DMipmaps(ARG_TO_UNSIGNED_INT(args[0]), ARG_TO_INT(args[1]), ARG_TO_INT(args[2]), ARG_TO_INT(args[3]), ARG_TO_UNSIGNED_INT(args[4]), ARG_TO_UNSIGNED_INT(args[5]), (const void*)(args[6])); - break; - } - - case _glSelectBuffer_fake_func: - { - process->current_state->selectBufferSize = args[0] * 4; - process->current_state->selectBufferPtr = realloc(process->current_state->selectBufferPtr, process->current_state->selectBufferSize); - glSelectBuffer(args[0], process->current_state->selectBufferPtr); - break; - } - - case _glGetSelectBuffer_fake_func: - { - void* ptr = (void*)args[0]; - memcpy(ptr, process->current_state->selectBufferPtr, process->current_state->selectBufferSize); - break; - } - - case _glFeedbackBuffer_fake_func: - { - process->current_state->feedbackBufferSize = args[0] * 4; - process->current_state->feedbackBufferPtr = realloc(process->current_state->feedbackBufferPtr, process->current_state->feedbackBufferSize); - glFeedbackBuffer(args[0], args[1], process->current_state->feedbackBufferPtr); - break; - } - - case _glGetFeedbackBuffer_fake_func: - { - void* ptr = (void*)args[0]; - memcpy(ptr, process->current_state->feedbackBufferPtr, process->current_state->feedbackBufferSize); - break; - } - - /* - case glEnableClientState_func: - { - if (display_function_call) fprintf(stderr, "cap : %s\n", nameArrays[args[0] - GL_VERTEX_ARRAY]); - glEnableClientState(args[0]); - break; - } - - case glDisableClientState_func: - { - if (display_function_call) fprintf(stderr, "cap : %s\n", nameArrays[args[0] - GL_VERTEX_ARRAY]); - glDisableClientState(args[0]); - break; - } - - case glClientActiveTexture_func: - case glClientActiveTextureARB_func: - { - if (display_function_call) fprintf(stderr, "client activeTexture %d\n", args[0] - GL_TEXTURE0_ARB); - glClientActiveTextureARB(args[0]); - break; - } - - case glActiveTextureARB_func: - { - if (display_function_call) fprintf(stderr, "server activeTexture %d\n", args[0] - GL_TEXTURE0_ARB); - glActiveTextureARB(args[0]); - break; - } - - case glLockArraysEXT_func: - break; - - case glUnlockArraysEXT_func: - break; - - case glArrayElement_func: - { - glArrayElement(args[0]); - break; - } - - case glDrawArrays_func: - { - glDrawArrays(args[0],args[1],args[2]); - break; - } - - case glDrawElements_func: - { - glDrawElements(args[0],args[1],args[2],(void*)args[3]); - break; - } - - case glDrawRangeElements_func: - { - glDrawRangeElements(args[0],args[1],args[2],args[3],args[4],(void*)args[5]); - break; - } - */ - - case glGetError_func: - { -#ifdef SYSTEMATIC_ERROR_CHECK - ret_int = process->current_state->last_error; -#else - ret_int = glGetError(); -#endif - break; - } - - case glNewObjectBufferATI_func: - { - GET_EXT_PTR(int, glNewObjectBufferATI, (int,void*, int)); - ret_int = ptr_func_glNewObjectBufferATI(args[0], (void*)args[1], args[2]); - break; - } - - default: - execute_func(func_number, args, &ret_int, &ret_char); - break; - } - -#ifdef SYSTEMATIC_ERROR_CHECK - if (func_number == glGetError_func) - { - process->current_state->last_error = 0; - } - else - { - process->current_state->last_error = glGetError(); - if (process->current_state->last_error != 0) - { - printf("error %s 0x%X\n", tab_opengl_calls_name[func_number], process->current_state->last_error); - } - } -#endif - - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int ret_type = signature->ret_type; - //int nb_args = signature->nb_args; - switch(ret_type) - { - case TYPE_NONE: - break; - - case TYPE_CHAR: - case TYPE_UNSIGNED_CHAR: - ret_int = ret_char; - break; - - case TYPE_INT: - case TYPE_UNSIGNED_INT: - break; - - case TYPE_CONST_CHAR: - { - strncpy(ret_string, (ret_str) ? ret_str : "", 32768); - break; - } - - default: - fprintf(stderr, "unexpected ret type : %d\n", ret_type); - exit(-1); - break; - } - - if (display_function_call) fprintf(stderr, "[%d]< %s\n", process->instr_counter, tab_opengl_calls_name[func_number]); - - return ret_int; -} -#endif - -void create_process_tab( OGLS_Conn *pConn ) -{ - if (pConn == NULL) { - fprintf(stderr, "create_process_tab: pConn is NULL.\n"); - return; - } - pConn->processTab = malloc( sizeof(ProcessStruct)*MAX_HANDLED_PROCESS ); - if( !pConn->processTab ) - { - perror( "init_process_tab" ); - return ; - } - - memset(pConn->processTab, 0, sizeof(ProcessStruct)*MAX_HANDLED_PROCESS ); -} - -void remove_process_tab( OGLS_Conn *pConn ) -{ - if( !pConn->processTab ) return ; - free( pConn->processTab ); - pConn->processTab = NULL; -} diff --git a/target-i386/opengl_func.h b/target-i386/opengl_func.h deleted file mode 100644 index fbd0a3e..0000000 --- a/target-i386/opengl_func.h +++ /dev/null @@ -1,922 +0,0 @@ -/* - * Main header for both host and guest sides - * - * Copyright (c) 2006,2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - -#include "mesa_gl.h" -#include "mesa_glext.h" -#include "opengl_server.h" - -/* To remove GCC warnings */ -//extern void opengl_exec_set_parent_window(Display* _dpy, Window _parent_window); -extern void opengl_exec_set_parent_window(OGLS_Conn *pConn, Window _parent_window); -extern void opengl_exec_set_local_connection(void); - -//#ifdef _WIN32 -//extern int do_function_call(Display dpy, int func_number, int pid, int* args, char* ret_string); -//#else -//extern int do_function_call(Display* dpy, int func_number, int pid, long* args, char* ret_string); -//#endif - -extern int do_function_call(OGLS_Conn *, int, int, long*, char*); -extern void execute_func(int func_number, long* args, int* pret_int, char* pret_char); -extern void create_process_tab( OGLS_Conn *pConn ); -extern void remove_process_tab( OGLS_Conn *pConn ); - -enum -{ - TYPE_NONE, - TYPE_CHAR, - TYPE_UNSIGNED_CHAR, - TYPE_SHORT, - TYPE_UNSIGNED_SHORT, - TYPE_INT, - TYPE_UNSIGNED_INT, - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_1CHAR, - TYPE_2CHAR, - TYPE_3CHAR, - TYPE_4CHAR, - TYPE_128UCHAR, - TYPE_1SHORT, - TYPE_2SHORT, - TYPE_3SHORT, - TYPE_4SHORT, - TYPE_1INT, - TYPE_2INT, - TYPE_3INT, - TYPE_4INT, - TYPE_1FLOAT, - TYPE_2FLOAT, - TYPE_3FLOAT, - TYPE_4FLOAT, - TYPE_16FLOAT, - TYPE_1DOUBLE, - TYPE_2DOUBLE, - TYPE_3DOUBLE, - TYPE_4DOUBLE, - TYPE_16DOUBLE, - TYPE_OUT_1INT, - TYPE_OUT_1FLOAT, - TYPE_OUT_4CHAR, - TYPE_OUT_4INT, - TYPE_OUT_4FLOAT, - TYPE_OUT_4DOUBLE, - TYPE_OUT_128UCHAR, - TYPE_CONST_CHAR, - TYPE_ARRAY_CHAR, - TYPE_ARRAY_SHORT, - TYPE_ARRAY_INT, - TYPE_ARRAY_FLOAT, - TYPE_ARRAY_DOUBLE, - TYPE_IN_IGNORED_POINTER, - TYPE_OUT_ARRAY_CHAR, - TYPE_OUT_ARRAY_SHORT, - TYPE_OUT_ARRAY_INT, - TYPE_OUT_ARRAY_FLOAT, - TYPE_OUT_ARRAY_DOUBLE, - TYPE_NULL_TERMINATED_STRING, - - TYPE_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_FLOAT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_DOUBLE_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_FLOAT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_DOUBLE_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - /* .... */ - TYPE_LAST, - /* .... */ - TYPE_1UCHAR = TYPE_CHAR, - TYPE_1USHORT = TYPE_1SHORT, - TYPE_1UINT = TYPE_1INT, - TYPE_OUT_1UINT = TYPE_OUT_1INT, - TYPE_OUT_4UCHAR = TYPE_OUT_4CHAR, - TYPE_ARRAY_VOID = TYPE_ARRAY_CHAR, - TYPE_ARRAY_SIGNED_CHAR = TYPE_ARRAY_CHAR, - TYPE_ARRAY_UNSIGNED_CHAR = TYPE_ARRAY_CHAR, - TYPE_ARRAY_UNSIGNED_SHORT = TYPE_ARRAY_SHORT, - TYPE_ARRAY_UNSIGNED_INT = TYPE_ARRAY_INT, - TYPE_OUT_ARRAY_VOID = TYPE_OUT_ARRAY_CHAR, - TYPE_OUT_ARRAY_SIGNED_CHAR = TYPE_OUT_ARRAY_CHAR, - TYPE_OUT_ARRAY_UNSIGNED_CHAR = TYPE_OUT_ARRAY_CHAR, - TYPE_OUT_ARRAY_UNSIGNED_SHORT = TYPE_OUT_ARRAY_SHORT, - TYPE_OUT_ARRAY_UNSIGNED_INT = TYPE_OUT_ARRAY_INT, - TYPE_ARRAY_VOID_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_SIGNED_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_UNSIGNED_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_UNSIGNED_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_ARRAY_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_ARRAY_UNSIGNED_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_ARRAY_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_VOID_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_OUT_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_SIGNED_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_OUT_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_UNSIGNED_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_OUT_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_UNSIGNED_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_OUT_ARRAY_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, - TYPE_OUT_ARRAY_UNSIGNED_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS = TYPE_OUT_ARRAY_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS, -}; - -#define CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS \ - case TYPE_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_ARRAY_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_ARRAY_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_ARRAY_FLOAT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_ARRAY_DOUBLE_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS - -#define CASE_OUT_LENGTH_DEPENDING_ON_PREVIOUS_ARGS \ - case TYPE_OUT_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_OUT_ARRAY_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_OUT_ARRAY_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_OUT_ARRAY_FLOAT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: \ -case TYPE_OUT_ARRAY_DOUBLE_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS - -#define CASE_IN_UNKNOWN_SIZE_POINTERS \ - case TYPE_ARRAY_CHAR: \ -case TYPE_ARRAY_SHORT: \ -case TYPE_ARRAY_INT: \ -case TYPE_ARRAY_FLOAT: \ -case TYPE_ARRAY_DOUBLE - -#define CASE_IN_KNOWN_SIZE_POINTERS \ - case TYPE_1CHAR:\ -case TYPE_2CHAR:\ -case TYPE_3CHAR:\ -case TYPE_4CHAR:\ -case TYPE_128UCHAR:\ -case TYPE_1SHORT:\ -case TYPE_2SHORT:\ -case TYPE_3SHORT:\ -case TYPE_4SHORT:\ -case TYPE_1INT:\ -case TYPE_2INT:\ -case TYPE_3INT:\ -case TYPE_4INT:\ -case TYPE_1FLOAT:\ -case TYPE_2FLOAT:\ -case TYPE_3FLOAT:\ -case TYPE_4FLOAT:\ -case TYPE_16FLOAT:\ -case TYPE_1DOUBLE:\ -case TYPE_2DOUBLE:\ -case TYPE_3DOUBLE:\ -case TYPE_4DOUBLE:\ -case TYPE_16DOUBLE - -#define CASE_OUT_UNKNOWN_SIZE_POINTERS \ - case TYPE_OUT_ARRAY_CHAR: \ -case TYPE_OUT_ARRAY_SHORT: \ -case TYPE_OUT_ARRAY_INT: \ -case TYPE_OUT_ARRAY_FLOAT: \ -case TYPE_OUT_ARRAY_DOUBLE - -#define CASE_OUT_KNOWN_SIZE_POINTERS \ - case TYPE_OUT_1INT: \ -case TYPE_OUT_1FLOAT: \ -case TYPE_OUT_4CHAR: \ -case TYPE_OUT_4INT: \ -case TYPE_OUT_4FLOAT: \ -case TYPE_OUT_4DOUBLE: \ -case TYPE_OUT_128UCHAR \ - -#define CASE_IN_POINTERS CASE_IN_UNKNOWN_SIZE_POINTERS: CASE_IN_KNOWN_SIZE_POINTERS: CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS -#define CASE_OUT_POINTERS CASE_OUT_UNKNOWN_SIZE_POINTERS: CASE_OUT_KNOWN_SIZE_POINTERS: CASE_OUT_LENGTH_DEPENDING_ON_PREVIOUS_ARGS - -#define CASE_POINTERS CASE_IN_POINTERS: CASE_OUT_POINTERS -#define CASE_KNOWN_SIZE_POINTERS CASE_IN_KNOWN_SIZE_POINTERS: CASE_OUT_KNOWN_SIZE_POINTERS - - -#define IS_ARRAY_CHAR(type) (type == TYPE_ARRAY_CHAR || type == TYPE_1CHAR || type == TYPE_2CHAR || type == TYPE_3CHAR || type == TYPE_4CHAR || type == TYPE_ARRAY_CHAR_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS) -#define IS_ARRAY_SHORT(type) (type == TYPE_ARRAY_SHORT || type == TYPE_1SHORT || type == TYPE_2SHORT || type == TYPE_3SHORT || type == TYPE_4SHORT || type == TYPE_ARRAY_SHORT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS) -#define IS_ARRAY_INT(type) (type == TYPE_ARRAY_INT || type == TYPE_1INT || type == TYPE_2INT || type == TYPE_3INT || type == TYPE_4INT || type == TYPE_ARRAY_INT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS) -#define IS_ARRAY_FLOAT(type) (type == TYPE_ARRAY_FLOAT || type == TYPE_1FLOAT || type == TYPE_2FLOAT || type == TYPE_3FLOAT || type == TYPE_4FLOAT || type == TYPE_16FLOAT || type == TYPE_ARRAY_FLOAT_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS) -#define IS_ARRAY_DOUBLE(type) (type == TYPE_ARRAY_DOUBLE || type == TYPE_1DOUBLE || type == TYPE_2DOUBLE || type == TYPE_3DOUBLE || type == TYPE_4DOUBLE || type == TYPE_16DOUBLE || type == TYPE_ARRAY_DOUBLE_OF_LENGTH_DEPENDING_ON_PREVIOUS_ARGS) - -#define NB_MAX_TEXTURES 16 -#define MY_GL_MAX_VERTEX_ATTRIBS_ARB 16 -#define MY_GL_MAX_VERTEX_ATTRIBS_NV 16 -#define MY_GL_MAX_VARIANT_POINTER_EXT 16 - -static int tab_args_type_length[] = -{ - 0, - sizeof(char), - sizeof(unsigned char), - sizeof(short), - sizeof(unsigned short), - sizeof(int), - sizeof(unsigned int), - sizeof(float), - sizeof(double), - 1 * sizeof(char), - 2 * sizeof(char), - 3 * sizeof(char), - 4 * sizeof(char), - 128 * sizeof(char), - 1 * sizeof(short), - 2 * sizeof(short), - 3 * sizeof(short), - 4 * sizeof(short), - 1 * sizeof(int), - 2 * sizeof(int), - 3 * sizeof(int), - 4 * sizeof(int), - 1 * sizeof(float), - 2 * sizeof(float), - 3 * sizeof(float), - 4 * sizeof(float), - 16 * sizeof(float), - 1 * sizeof(double), - 2 * sizeof(double), - 3 * sizeof(double), - 4 * sizeof(double), - 16 * sizeof(double), - sizeof(int), - sizeof(float), - 4 * sizeof(char), - 4 * sizeof(int), - 4 * sizeof(float), - 4 * sizeof(double), - 128 * sizeof(char), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - /* the following sizes are the size of 1 element of the array */ - sizeof(char), - sizeof(short), - sizeof(int), - sizeof(float), - sizeof(double), - sizeof(char), - sizeof(short), - sizeof(int), - sizeof(float), - sizeof(double), -}; - -typedef struct -{ - int ret_type; - int has_out_parameters; - int nb_args; - int args_type[0]; -} Signature; - -static const int _init_signature[] = { TYPE_NONE, 1, 2, TYPE_INT, TYPE_OUT_1INT}; - -static const int _synchronize_signature[] = { TYPE_INT, 0, 0 }; - -static const int _serialized_calls_signature[] = { TYPE_NONE, 0, 1, TYPE_ARRAY_CHAR }; - -static const int _exit_process_signature[] = {TYPE_NONE, 0, 0}; - -static const int _changeWindowState_signature[] = {TYPE_NONE, 0, 2, TYPE_INT, TYPE_INT}; - -static const int _moveResizeWindow_signature[] = {TYPE_NONE, 0, 2, TYPE_INT, TYPE_4INT}; - -static const int _send_cursor_signature[] = {TYPE_NONE, 0, 7, TYPE_INT, TYPE_INT, - TYPE_INT, TYPE_INT, - TYPE_INT, TYPE_INT, - TYPE_ARRAY_INT }; - -/* XVisualInfo* glXChooseVisual( Display *dpy, int screen, int *attribList ) */ -static const int glXChooseVisual_signature[] = {TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_ARRAY_INT }; - -/*GLXContext glXCreateContext( Display *dpy, XVisualInfo *vis, - GLXContext shareList, Bool direct )*/ -static const int glXCreateContext_signature[] = {TYPE_INT, 0, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_INT}; - -static const int glXCopyContext_signature[] = {TYPE_NONE, 0, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_INT}; - -/* void glXDestroyContext( Display *dpy, GLXContext ctx ) */ -static const int glXDestroyContext_signature[] = {TYPE_NONE, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; - -/* Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx) */ -//static const int glXMakeCurrent_signature[] = {TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT}; -/* making it asynchronous */ -static const int glXMakeCurrent_signature[] = {TYPE_NONE, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT}; - -/*int glXGetConfig( Display *dpy, XVisualInfo *visual, - int attrib, int *value )*/ -static const int glXGetConfig_signature[] = {TYPE_INT, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_OUT_1INT}; - -/* "glXGetConfig_extended"(dpy, visual_id, int n, int* attribs, int* values, int* rets) */ -static const int glXGetConfig_extended_signature[] = {TYPE_NONE, 1, 6, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_ARRAY_INT, TYPE_OUT_ARRAY_INT, TYPE_OUT_ARRAY_INT}; - -/* void glXSwapBuffers( Display *dpy, GLXDrawable drawable ); */ -static const int glXSwapBuffers_signature[] = {TYPE_NONE, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; - -/* Bool glXQueryVersion( Display *dpy, int *maj, int *min ) */ -static const int glXQueryVersion_signature[] = {TYPE_INT, 1, 3, TYPE_IN_IGNORED_POINTER, TYPE_OUT_1INT, TYPE_OUT_1INT}; - -/* Bool glXQueryExtension( Display *dpy, int *errorBase, int *eventBase ) */ -static const int glXQueryExtension_signature[] = {TYPE_INT, 1, 3, TYPE_IN_IGNORED_POINTER, TYPE_OUT_1INT, TYPE_OUT_1INT}; - -static const int glXWaitGL_signature[] = { TYPE_INT, 0, 0 }; -static const int glXWaitX_signature[] = { TYPE_INT, 0, 0 }; - -/* GLX 1.1 and later */ - -/* const char *glXGetClientString( Display *dpy, int name ) */ -static const int glXGetClientString_signature[] = {TYPE_CONST_CHAR, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; - -/*const char *glXQueryExtensionsString( Display *dpy, int screen ) */ -static const int glXQueryExtensionsString_signature[] = {TYPE_CONST_CHAR, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; - -/* const char *glXQueryServerString( Display *dpy, int screen, int name ) */ -static const int glXQueryServerString_signature[] = {TYPE_CONST_CHAR, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT}; - - -static const int glXGetProcAddress_fake_signature[] = {TYPE_INT, 0, 1, TYPE_NULL_TERMINATED_STRING}; - -static const int glXGetProcAddress_global_fake_signature[] = {TYPE_NONE, 1, 3, TYPE_INT, TYPE_ARRAY_CHAR, TYPE_OUT_ARRAY_CHAR}; - - -/* GLX 1.3 and later */ - -/* - GLXFBConfig *glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ); */ -static const int glXChooseFBConfig_signature[] = {TYPE_INT, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_ARRAY_INT, TYPE_OUT_1INT}; - -static const int glXChooseFBConfigSGIX_signature[] = {TYPE_INT, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_ARRAY_INT, TYPE_OUT_1INT}; - -static const int glXGetFBConfigs_signature[] = {TYPE_INT, 1, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_OUT_1INT}; - -/* "glXGetFBConfigAttrib_extended"(dpy, fbconfig, int n, int* attribs, int* values, int* rets) */ -static const int glXGetFBConfigAttrib_extended_signature[] = {TYPE_NONE, 1, 6, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_ARRAY_INT, TYPE_OUT_ARRAY_INT, TYPE_OUT_ARRAY_INT}; - -static const int glXDestroyWindow_signature[] = {TYPE_NONE, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; // mkjung - - -/* GLXPbuffer glXCreatePbuffer( Display *dpy, GLXFBConfig config, - const int *attribList ) */ -static const int glXCreatePbuffer_signature[] = {TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_ARRAY_INT}; - -static const int glXCreateGLXPbufferSGIX_signature[] = {TYPE_INT, 0, 5, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_INT}; - -static const int glXDestroyPbuffer_signature[] = {TYPE_NONE, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; - -static const int glXDestroyGLXPbufferSGIX_signature[] = {TYPE_NONE, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; - -/* GLXContext glXCreateNewContext(Display * dpy - GLXFBConfig config - int renderType - GLXContext ShareList - Bool Direct) */ -static const int glXCreateNewContext_signature[] = {TYPE_INT, 0, 5, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; - -static const int glXCreateContextWithConfigSGIX_signature[] = {TYPE_INT, 0, 5, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; - -/*XVisualInfo *glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) */ -static const int glXGetVisualFromFBConfig_signature[] = {TYPE_INT, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT}; - -/*int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value)*/ -static const int glXGetFBConfigAttrib_signature[] = {TYPE_INT, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_OUT_1INT}; - -static const int glXGetFBConfigAttribSGIX_signature[] = {TYPE_INT, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_OUT_1INT}; - -static const int glXQueryContext_signature[] = {TYPE_INT, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_OUT_1INT}; - -static const int glXQueryGLXPbufferSGIX_signature[] = {TYPE_INT, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_OUT_1INT}; - -static const int glXQueryDrawable_signature[] = {TYPE_NONE, 1, 4, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT, TYPE_OUT_1INT}; - -/* void glXUseXFont( Font font, int first, int count, int list ) */ -static const int glXUseXFont_signature[] = {TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; - -/* Bool glXIsDirect( Display *dpy, GLXContext ctx ) */ -static const int glXIsDirect_signature[] = {TYPE_CHAR, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT }; - -static const int glXGetScreenDriver_signature[] = { TYPE_CONST_CHAR, 0, 2, TYPE_IN_IGNORED_POINTER, TYPE_INT }; - -static const int glXGetDriverConfig_signature[] = { TYPE_CONST_CHAR, 0, 1, TYPE_NULL_TERMINATED_STRING }; - - -static const int glXWaitVideoSyncSGI_signature[] = { TYPE_INT, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_1INT }; - -static const int glXGetVideoSyncSGI_signature[] = { TYPE_INT, 1, 1, TYPE_OUT_1INT }; - -static const int glXSwapIntervalSGI_signature[] = { TYPE_INT, 0, 1, TYPE_INT }; - -static const int glXBindTexImageATI_signature[] = { TYPE_NONE, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; -static const int glXReleaseTexImageATI_signature[] = { TYPE_NONE, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; -static const int glXBindTexImageARB_signature[] = { TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; -static const int glXReleaseTexImageARB_signature[] = { TYPE_INT, 0, 3, TYPE_IN_IGNORED_POINTER, TYPE_INT, TYPE_INT }; - -/* const GLubyte * glGetString( GLenum name ) */ -static const int glGetString_signature[] = {TYPE_CONST_CHAR, 0, 1, TYPE_INT}; - -/* void glShaderSourceARB (GLhandleARB handle , GLsizei size, const GLcharARB* *p_tab_prog, const GLint * tab_length) */ -/* --> void glShaderSourceARB (GLhandleARB handle , GLsizei size, const GLcharARB* all_progs, const GLint * tab_length) */ -static const int glShaderSourceARB_fake_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR, TYPE_ARRAY_INT}; -static const int glShaderSource_fake_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR, TYPE_ARRAY_INT}; - -static const int glVertexPointer_fake_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glNormalPointer_fake_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glColorPointer_fake_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glSecondaryColorPointer_fake_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glIndexPointer_fake_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glTexCoordPointer_fake_signature[] = { TYPE_NONE, 0, 7, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glEdgeFlagPointer_fake_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexAttribPointerARB_fake_signature[] = { TYPE_NONE, 0, 8, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexAttribPointerNV_fake_signature[] = { TYPE_NONE, 0, 7, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glWeightPointerARB_fake_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glMatrixIndexPointerARB_fake_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glFogCoordPointer_fake_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glInterleavedArrays_fake_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glElementPointerATI_fake_signature[] = { TYPE_NONE, 0, 3, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVariantPointerEXT_fake_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glTuxRacerDrawElements_fake_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexAndNormalPointer_fake_signature[] = { TYPE_NONE, 0, 7, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glTexCoordPointer01_fake_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glTexCoordPointer012_fake_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalPointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 8, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalColorPointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 11, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexColorTexCoord0PointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 12, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalTexCoord0PointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 11, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalTexCoord01PointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 14, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalTexCoord012PointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 17, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalColorTexCoord0PointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 14, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalColorTexCoord01PointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 17, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; -static const int glVertexNormalColorTexCoord012PointerInterlaced_fake_signature[] = {TYPE_NONE, 0, 20, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_ARRAY_CHAR }; - -static const int glGenTextures_fake_signature[] = { TYPE_NONE, 0, 1, TYPE_INT}; -static const int glGenBuffersARB_fake_signature[] = { TYPE_NONE, 0, 1, TYPE_INT}; -static const int glGenLists_fake_signature[] = { TYPE_NONE, 0, 1, TYPE_INT}; - -static const int _glDrawElements_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glDrawRangeElements_buffer_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glMultiDrawElements_buffer_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_ARRAY_INT, TYPE_INT, TYPE_ARRAY_INT, TYPE_INT }; - -static const int _glVertexPointer_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glNormalPointer_buffer_signature[] = { TYPE_NONE, 0, 3, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glColorPointer_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glSecondaryColorPointer_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glIndexPointer_buffer_signature[] = { TYPE_NONE, 0, 3, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glTexCoordPointer_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glEdgeFlagPointer_buffer_signature[] = { TYPE_NONE, 0, 2, TYPE_INT, TYPE_INT}; -static const int _glVertexAttribPointerARB_buffer_signature[] = { TYPE_NONE, 0, 6, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glWeightPointerARB_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glMatrixIndexPointerARB_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glFogCoordPointer_buffer_signature[] = { TYPE_NONE, 0, 3, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glVariantPointerEXT_buffer_signature[] = { TYPE_NONE, 0, 4, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; - -static const int _glReadPixels_pbo_signature[] = { TYPE_INT, 0, 7, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glDrawPixels_pbo_signature[] = { TYPE_NONE, 0, 5, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT}; -static const int _glMapBufferARB_fake_signature[] = { TYPE_INT, 1, 3, TYPE_INT, TYPE_INT, TYPE_OUT_ARRAY_CHAR }; - -static const int _glSelectBuffer_fake_signature[] = { TYPE_NONE, 0, 1, TYPE_INT }; -static const int _glGetSelectBuffer_fake_signature[] = { TYPE_NONE, 1, 1, TYPE_ARRAY_CHAR }; -static const int _glFeedbackBuffer_fake_signature[] = { TYPE_NONE, 0, 2, TYPE_INT, TYPE_INT }; -static const int _glGetFeedbackBuffer_fake_signature[] = { TYPE_NONE, 1, 1, TYPE_ARRAY_CHAR }; - -static const int _glGetError_fake_signature[] = { TYPE_NONE, 0, 0 }; - -#define timesynchro_func -1 -#define memorize_array_func -2 -#define reuse_array_func -3 - -#include "gl_func.h" - - -static GLint __glTexParameter_size(FILE* err_file, GLenum pname) -{ - switch (pname) { - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - case GL_TEXTURE_PRIORITY: - case GL_TEXTURE_WRAP_R: - case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: - /* case GL_SHADOW_AMBIENT_SGIX:*/ - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_CLIPMAP_FRAME_SGIX: - case GL_TEXTURE_LOD_BIAS_S_SGIX: - case GL_TEXTURE_LOD_BIAS_T_SGIX: - case GL_TEXTURE_LOD_BIAS_R_SGIX: - case GL_GENERATE_MIPMAP: - /* case GL_GENERATE_MIPMAP_SGIS:*/ - case GL_TEXTURE_COMPARE_SGIX: - case GL_TEXTURE_COMPARE_OPERATOR_SGIX: - case GL_TEXTURE_MAX_CLAMP_S_SGIX: - case GL_TEXTURE_MAX_CLAMP_T_SGIX: - case GL_TEXTURE_MAX_CLAMP_R_SGIX: - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - case GL_TEXTURE_LOD_BIAS: - /* case GL_TEXTURE_LOD_BIAS_EXT:*/ - case GL_DEPTH_TEXTURE_MODE: - /* case GL_DEPTH_TEXTURE_MODE_ARB:*/ - case GL_TEXTURE_COMPARE_MODE: - /* case GL_TEXTURE_COMPARE_MODE_ARB:*/ - case GL_TEXTURE_COMPARE_FUNC: - /* case GL_TEXTURE_COMPARE_FUNC_ARB:*/ - case GL_TEXTURE_UNSIGNED_REMAP_MODE_NV: - return 1; - case GL_TEXTURE_CLIPMAP_CENTER_SGIX: - case GL_TEXTURE_CLIPMAP_OFFSET_SGIX: - return 2; - case GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX: - return 3; - case GL_TEXTURE_BORDER_COLOR: - case GL_POST_TEXTURE_FILTER_BIAS_SGIX: - case GL_POST_TEXTURE_FILTER_SCALE_SGIX: - return 4; - default: - fprintf(err_file, "unhandled pname = %d\n", pname); - return 0; - } -} - -static int __glLight_size(FILE* err_file, GLenum pname) -{ - switch(pname) - { - case GL_AMBIENT: - case GL_DIFFUSE: - case GL_SPECULAR: - case GL_POSITION: - return 4; - break; - - case GL_SPOT_DIRECTION: - return 3; - break; - - case GL_SPOT_EXPONENT: - case GL_SPOT_CUTOFF: - case GL_CONSTANT_ATTENUATION: - case GL_LINEAR_ATTENUATION: - case GL_QUADRATIC_ATTENUATION: - return 1; - break; - - default: - fprintf(err_file, "unhandled pname = %d\n", pname); - return 0; - } -} - -static int __glMaterial_size(FILE* err_file, GLenum pname) -{ - switch(pname) - { - case GL_AMBIENT: - case GL_DIFFUSE: - case GL_SPECULAR: - case GL_EMISSION: - case GL_AMBIENT_AND_DIFFUSE: - return 4; - break; - - case GL_SHININESS: - return 1; - break; - - case GL_COLOR_INDEXES: - return 3; - break; - - default: - fprintf(err_file, "unhandled pname = %d\n", pname); - return 0; - } -} - - -static inline int compute_arg_length(FILE* err_file, int func_number, int arg_i, long* args) -{ - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int* args_type = signature->args_type; - - switch (func_number) - { - case glProgramNamedParameter4fNV_func: - case glProgramNamedParameter4dNV_func: - case glProgramNamedParameter4fvNV_func: - case glProgramNamedParameter4dvNV_func: - case glGetProgramNamedParameterfvNV_func: - case glGetProgramNamedParameterdvNV_func: - if (arg_i == 2) - return 1 * args[arg_i-1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glProgramStringARB_func: - case glLoadProgramNV_func: - case glGenProgramsNV_func: - case glDeleteProgramsNV_func: - case glGenProgramsARB_func: - case glDeleteProgramsARB_func: - case glRequestResidentProgramsNV_func: - case glDrawBuffers_func: - case glDrawBuffersARB_func: - case glDrawBuffersATI_func: - case glDeleteBuffers_func: - case glDeleteBuffersARB_func: - case glDeleteTextures_func: - case glDeleteTexturesEXT_func: - case glGenFramebuffersEXT_func: - case glDeleteFramebuffersEXT_func: - case glGenRenderbuffersEXT_func: - case glDeleteRenderbuffersEXT_func: - case glGenQueries_func: - case glGenQueriesARB_func: - case glDeleteQueries_func: - case glDeleteQueriesARB_func: - case glGenOcclusionQueriesNV_func: - case glDeleteOcclusionQueriesNV_func: - case glGenFencesNV_func: - case glDeleteFencesNV_func: - case glUniform1fv_func: - case glUniform1iv_func: - case glUniform1fvARB_func: - case glUniform1ivARB_func: - case glUniform1uivEXT_func: - case glVertexAttribs1dvNV_func: - case glVertexAttribs1fvNV_func: - case glVertexAttribs1svNV_func: - case glVertexAttribs1hvNV_func: - case glWeightbvARB_func: - case glWeightsvARB_func: - case glWeightivARB_func: - case glWeightfvARB_func: - case glWeightdvARB_func: - case glWeightubvARB_func: - case glWeightusvARB_func: - case glWeightuivARB_func: - case glPixelMapfv_func: - case glPixelMapuiv_func: - case glPixelMapusv_func: - case glProgramBufferParametersfvNV_func: - case glProgramBufferParametersIivNV_func: - case glProgramBufferParametersIuivNV_func: - case glTransformFeedbackAttribsNV_func: - case glTransformFeedbackVaryingsNV_func: - if (arg_i == signature->nb_args - 1) - return 1 * args[arg_i-1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniform2fv_func: - case glUniform2iv_func: - case glUniform2fvARB_func: - case glUniform2ivARB_func: - case glUniform2uivEXT_func: - case glVertexAttribs2dvNV_func: - case glVertexAttribs2fvNV_func: - case glVertexAttribs2svNV_func: - case glVertexAttribs2hvNV_func: - case glDetailTexFuncSGIS_func: - case glSharpenTexFuncSGIS_func: - if (arg_i == signature->nb_args - 1) - return 2 * args[arg_i-1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniform3fv_func: - case glUniform3iv_func: - case glUniform3fvARB_func: - case glUniform3ivARB_func: - case glUniform3uivEXT_func: - case glVertexAttribs3dvNV_func: - case glVertexAttribs3fvNV_func: - case glVertexAttribs3svNV_func: - case glVertexAttribs3hvNV_func: - if (arg_i == signature->nb_args - 1) - return 3 * args[arg_i-1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniform4fv_func: - case glUniform4iv_func: - case glUniform4fvARB_func: - case glUniform4ivARB_func: - case glUniform4uivEXT_func: - case glVertexAttribs4dvNV_func: - case glVertexAttribs4fvNV_func: - case glVertexAttribs4svNV_func: - case glVertexAttribs4hvNV_func: - case glVertexAttribs4ubvNV_func: - case glProgramParameters4fvNV_func: - case glProgramParameters4dvNV_func: - case glProgramLocalParameters4fvEXT_func: - case glProgramEnvParameters4fvEXT_func: - case glProgramLocalParametersI4ivNV_func: - case glProgramLocalParametersI4uivNV_func: - case glProgramEnvParametersI4ivNV_func: - case glProgramEnvParametersI4uivNV_func: - if (arg_i == signature->nb_args - 1) - return 4 * args[arg_i-1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glPrioritizeTextures_func: - case glPrioritizeTexturesEXT_func: - case glAreProgramsResidentNV_func: - case glAreTexturesResident_func: - case glAreTexturesResidentEXT_func: - if (arg_i == 1 || arg_i == 2) - return args[0] * tab_args_type_length[args_type[arg_i]]; - break; - - case glLightfv_func: - case glLightiv_func: - case glGetLightfv_func: - case glGetLightiv_func: - case glFragmentLightfvSGIX_func: - case glFragmentLightivSGIX_func: - case glGetFragmentLightfvSGIX_func: - case glGetFragmentLightivSGIX_func: - if (arg_i == signature->nb_args - 1) - return __glLight_size(err_file, args[arg_i-1]) * tab_args_type_length[args_type[arg_i]]; - break; - - case glLightModelfv_func: - case glLightModeliv_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_LIGHT_MODEL_AMBIENT) ? 4 : 1) * tab_args_type_length[args_type[arg_i]]; - break; - - case glFragmentLightModelfvSGIX_func: - case glFragmentLightModelivSGIX_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX) ? 4 : 1) * tab_args_type_length[args_type[arg_i]]; - break; - - case glMaterialfv_func: - case glMaterialiv_func: - case glGetMaterialfv_func: - case glGetMaterialiv_func: - case glFragmentMaterialfvSGIX_func: - case glFragmentMaterialivSGIX_func: - case glGetFragmentMaterialfvSGIX_func: - case glGetFragmentMaterialivSGIX_func: - if (arg_i == signature->nb_args - 1) - return __glMaterial_size(err_file, args[arg_i-1]) * tab_args_type_length[args_type[arg_i]]; - break; - - case glTexParameterfv_func: - case glTexParameteriv_func: - case glGetTexParameterfv_func: - case glGetTexParameteriv_func: - case glTexParameterIivEXT_func: - case glTexParameterIuivEXT_func: - case glGetTexParameterIivEXT_func: - case glGetTexParameterIuivEXT_func: - if (arg_i == signature->nb_args - 1) - return __glTexParameter_size(err_file, args[arg_i-1]) * tab_args_type_length[args_type[arg_i]]; - break; - - case glFogiv_func: - case glFogfv_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_FOG_COLOR) ? 4 : 1) * tab_args_type_length[args_type[arg_i]]; - break; - - case glTexGendv_func: - case glTexGenfv_func: - case glTexGeniv_func: - case glGetTexGendv_func: - case glGetTexGenfv_func: - case glGetTexGeniv_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_TEXTURE_GEN_MODE) ? 1 : 4) * tab_args_type_length[args_type[arg_i]]; - break; - - case glTexEnvfv_func: - case glTexEnviv_func: - case glGetTexEnvfv_func: - case glGetTexEnviv_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_TEXTURE_ENV_MODE) ? 1 : 4) * tab_args_type_length[args_type[arg_i]]; - break; - - case glConvolutionParameterfv_func: - case glConvolutionParameteriv_func: - case glGetConvolutionParameterfv_func: - case glGetConvolutionParameteriv_func: - case glConvolutionParameterfvEXT_func: - case glConvolutionParameterivEXT_func: - case glGetConvolutionParameterfvEXT_func: - case glGetConvolutionParameterivEXT_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_CONVOLUTION_BORDER_COLOR || - args[arg_i-1] == GL_CONVOLUTION_FILTER_SCALE || - args[arg_i-1] == GL_CONVOLUTION_FILTER_BIAS) ? 4 : 1) * tab_args_type_length[args_type[arg_i]]; - break; - - case glGetVertexAttribfvARB_func: - case glGetVertexAttribfvNV_func: - case glGetVertexAttribfv_func: - case glGetVertexAttribdvARB_func: - case glGetVertexAttribdvNV_func: - case glGetVertexAttribdv_func: - case glGetVertexAttribivARB_func: - case glGetVertexAttribivNV_func: - case glGetVertexAttribiv_func: - case glGetVertexAttribIivEXT_func: - case glGetVertexAttribIuivEXT_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_CURRENT_VERTEX_ATTRIB_ARB) ? 4 : 1) * tab_args_type_length[args_type[arg_i]]; - break; - - - case glPointParameterfv_func: - case glPointParameterfvEXT_func: - case glPointParameterfvARB_func: - case glPointParameterfvSGIS_func: - case glPointParameteriv_func: - case glPointParameterivEXT_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_POINT_DISTANCE_ATTENUATION) ? 3 : 1) * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniformMatrix2fv_func: - case glUniformMatrix2fvARB_func: - if (arg_i == signature->nb_args - 1) - return 2 * 2 * args[1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniformMatrix3fv_func: - case glUniformMatrix3fvARB_func: - if (arg_i == signature->nb_args - 1) - return 3 * 3 * args[1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniformMatrix4fv_func: - case glUniformMatrix4fvARB_func: - if (arg_i == signature->nb_args - 1) - return 4 * 4 * args[1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniformMatrix2x3fv_func: - case glUniformMatrix3x2fv_func: - if (arg_i == signature->nb_args - 1) - return 2 * 3 * args[1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniformMatrix2x4fv_func: - case glUniformMatrix4x2fv_func: - if (arg_i == signature->nb_args - 1) - return 2 * 4 * args[1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glUniformMatrix3x4fv_func: - case glUniformMatrix4x3fv_func: - if (arg_i == signature->nb_args - 1) - return 3 * 4 * args[1] * tab_args_type_length[args_type[arg_i]]; - break; - - case glSpriteParameterivSGIX_func: - case glSpriteParameterfvSGIX_func: - if (arg_i == signature->nb_args - 1) - return ((args[arg_i-1] == GL_SPRITE_MODE_SGIX) ? 1 : 3) * tab_args_type_length[args_type[arg_i]]; - break; - - default: - break; - } - - fprintf(err_file, "invalid combination for compute_arg_length : func_number=%d, arg_i=%d\n", func_number, arg_i); - return 0; -} - -#define IS_NULL_POINTER_OK_FOR_FUNC(func_number) \ - (func_number == glBitmap_func || \ - func_number == _send_cursor_func || \ - func_number == glTexImage1D_func || \ - func_number == glTexImage2D_func || \ - func_number == glTexImage3D_func || \ - func_number == glBufferDataARB_func || \ - func_number == glNewObjectBufferATI_func) diff --git a/target-i386/opengl_player.c b/target-i386/opengl_player.c deleted file mode 100644 index a7e5111..0000000 --- a/target-i386/opengl_player.c +++ /dev/null @@ -1,1489 +0,0 @@ -/* - * Plays a sequence of OpenGL calls recorded either under qemu or with opengl_server - * - * Copyright (c) 2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - -/* gcc -O2 -g -Wall opengl_player.c opengl_exec.c -o opengl_player -I../i386-softmmu -I. -I.. -lGL */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "opengl_func.h" -#include "opengl_utils.h" - -//#include "ffmpeg/avcodec.h" - -extern int last_process_id; -extern void init_process_tab(void); -extern int do_function_call(Display*, int, int, int*, char*); - -typedef struct -{ - int n_used; - unsigned int crc; - int size; - long long last_use; -} RecordBufferedArray; - -typedef struct -{ - int size; - long file_offset; -} ReplayBufferedArray; - -#define N_BUFFERED_ARRAYS 1024 -RecordBufferedArray recordBufferedArrays[N_BUFFERED_ARRAYS]; - -#define INSTR_WINDOW_SIZE 65536 -short instrWindow[INSTR_WINDOW_SIZE]; -int instrWindowCount = 0; -int instrWindowPtr = 0; -int instrWindowBeginPtr = 0; - -#include "ghash.c" - -#define PRIME 131 - -typedef struct -{ - int iFirstOccur; - int nbOccur; - int hash; -} SeqDesc; - -typedef struct -{ - int hash; - int offset; -} HashElt; - -int sort_hash_N; -short* sort_hash_tab; -int count_compar; -int collision_detected; - -static int sort_hash(const void* ptrA, const void* ptrB) -{ - const HashElt* a = (const HashElt*)ptrA; - const HashElt* b = (const HashElt*)ptrB; - count_compar++; - if (a->hash == b->hash) - { - int j; - for(j=0;joffset + j] != sort_hash_tab[b->offset + j]) - { - collision_detected = 1; - //fprintf(stderr, "collision de hash !\n"); - return sort_hash_tab[a->offset + j] < sort_hash_tab[b->offset + j] ? -1 : 1; - } - } - return a->offset - b->offset; - } - else if (a->hash < b->hash) - return -1; - else - return 1; -} - -static int sort_seq_desc_by_occur(const void* ptrA, const void* ptrB) -{ - const SeqDesc* a = (const SeqDesc*)ptrA; - const SeqDesc* b = (const SeqDesc*)ptrB; - return b->nbOccur - a->nbOccur; -} - -static int sort_seq_desc_by_offset(const void* ptrA, const void* ptrB) -{ - const SeqDesc* a = (const SeqDesc*)ptrA; - const SeqDesc* b = (const SeqDesc*)ptrB; - return a->iFirstOccur - b->iFirstOccur; -} - -void find_repeated_seq(short* tab, int iStart, int length) -{ - //SimpleHashTable* tableHash = simple_hash_table_new(free); - int N = 10; - int i; - int hash = 0; - int primeN = 1; - HashElt* tabHash = malloc(sizeof(HashElt) * (length - N + 1)); - - short* new_tab = malloc(sizeof(short) * length); - memcpy(&new_tab[0], &tab[iStart], sizeof(short) * (length - iStart)); - memcpy(&new_tab[length-iStart], &tab[0], sizeof(short) * iStart); - tab = new_tab; - - sort_hash_N = N; - sort_hash_tab = tab; - - fprintf(stderr, "(start) iStart = %d\n", iStart); - for(i=0;i= N) - { - hash -= tab[i - N] * primeN; - } - if (i >= N - 1) - { - tabHash[i - (N - 1)].offset = i - (N - 1); - tabHash[i - (N - 1)].hash = /*(i == 100) ? tabHash[0].hash :*/ hash; -#if 0 - void** p_n_occurences = simple_hash_table_lookup_pointer(tableHash, hash); - if (p_n_occurences == NULL) - { - SeqDesc* seqDesc = malloc(sizeof(SeqDesc)); - seqDesc->iFirstOccur = i - (N - 1); - seqDesc->nbOccur = 1; - simple_hash_table_insert(tableHash, hash, seqDesc); - } - else - { - SeqDesc* seqDesc = (SeqDesc*)(*p_n_occurences); - int j; - for(j=0;jiFirstOccur + j) % length] != tab[(iStart + i - (N - 1) + j) % length]) - break; - } - if (j != N) - fprintf(stderr, "arg\n"); - seqDesc->nbOccur ++; - //fprintf(stderr, "iStart = %d, i = %d, iFirstOccur = %d, nbOccur = %d\n", iStart, i, seqDesc->iFirstOccur, seqDesc->nbOccur); - } -#endif - } - } - collision_detected = 0; - count_compar = 0; - qsort(tabHash, length - N + 1, sizeof(HashElt), sort_hash); - if (! collision_detected) - { - SeqDesc* tabSeqDesc = (SeqDesc*)malloc(sizeof(SeqDesc) * length); - int nbSeqDesc = 0; - int lastI = 0; - int prevHash = tabHash[0].hash; - for(i=1;i tabSeqDesc[maxI].nbOccur) - { - maxI = i; - } - } - else - { - tabSeqDesc[j].iFirstOccur = tabSeqDesc[maxI].iFirstOccur; - tabSeqDesc[j].nbOccur = tabSeqDesc[maxI].nbOccur; - j++; -#define MAX(a,b) (((a)>(b)) ? (a) : (b)) - lastI = tabSeqDesc[maxI].iFirstOccur; - while(i < nbSeqDesc && tabSeqDesc[i].iFirstOccur - lastI <= N) i++; - if (i == nbSeqDesc) break; - maxI = i; - } - } - nbSeqDesc = j; - qsort(tabSeqDesc, nbSeqDesc, sizeof(SeqDesc), sort_seq_desc_by_occur); - for(i=0;i= nMaxContiguous) - { - nMaxContiguous = nContiguous; - jMax = j; - } - } - fprintf(stderr, "iStart = %d, i = %d, j = %d, nContiguous = %d\n", iStart, i, i + jMax, nMaxContiguous); - } -#endif -} - -#define MAX_SERVER_STATE_STACK_SIZE 16 - -typedef struct -{ - GLbitfield mask; - int matrixMode; - int lastMatrixOp; -} ServerState; - -typedef struct -{ - ServerState stackAttrib[MAX_SERVER_STATE_STACK_SIZE]; - int stackAttribPtr; - int matrixMode; - int lastMatrixOp; -} GLState; - -#define NB_STATES 100 -GLState states[NB_STATES]; - -void usage() -{ - printf("Usage : opengl_player [OPTION] filename\n\n"); - printf("filename is the file where to read the OpenGL flow ('/tmp/debug_gl.bin' by default)\n"); - printf("'-' is supported and stands for standard input\n\n"); - printf("The following options are available :\n"); - printf("--debug : output debugging trace on stderr\n"); - printf("--disable-real-time-play-back : play as fast as possible\n"); - printf("--show-hard-disk-bandwidth : displays regularly the data bandwidth\n"); - printf("--h or --help : display this help\n"); -} - -int main(int argc, char* argv[]) -{ - static int args_size[50]; - int i; - int visualid_fbconfig_read = -1; - int visualid_fbconfig_real = 0; - char* filename = "/tmp/debug_gl.bin"; - int slowdown = 0; - int debug = 0; - char* ret_string; - int args[50]; - Display* dpy = NULL; - struct timeval start_time, last_time, current_time; - int noplay = 0; - int count_last_time = 0, count_current = 0; - int refresh_rate = 500; - int disable_real_time_play_back = 0; - int show_hard_disk_bandwith = 0; - int last_offset = 0; - int resize = 0; - int window_width = 0, window_height = 0; - int orig_window_width = 0; - int show_offset = 0; - int show_diff_offset = 0; - int last_cmd_offset = 0; - FILE* compressed_file = NULL; - int sizeBufferedArraysPlay = 0; - ReplayBufferedArray* replayBufferedArrays = NULL; - int currentState = 0; - - memset(recordBufferedArrays, 0, sizeof(recordBufferedArrays)); - memset(states, 0, sizeof(states)); - for(i=0;i= INSTR_WINDOW_SIZE) - { - if ((instrWindowCount % (INSTR_WINDOW_SIZE / 2)) == 0) - find_repeated_seq(instrWindow, instrWindowBeginPtr, INSTR_WINDOW_SIZE); - instrWindowBeginPtr++; - if (instrWindowBeginPtr == INSTR_WINDOW_SIZE) - instrWindowBeginPtr = 0; - }*/ - - /* -1 is special code that indicates time synchro */ - if (func_number == timesynchro_func) - { - long long ts_file; - fread(&ts_file, sizeof(long long), 1, f); - - if (compressed_file) - { - WRITE_SHORT(timesynchro_func); - WRITE_LONGLONG(ts_file); - } - - if (!disable_real_time_play_back) - { - gettimeofday(¤t_time, NULL); - long long ts_real= (current_time.tv_sec - start_time.tv_sec) * (long long)1000000 + current_time.tv_usec - start_time.tv_usec; - //fprintf(stderr, "%d %d\n", (int)ts_real, (int)ts_file); - if (ts_real < ts_file /*&& ts_file - ts_real > 100 * 1000*/) /* we're playing too fast */ - { - //fprintf(stderr, "waiting %d usec\n", (int)(ts_file - ts_real)); - usleep((int)(ts_file - ts_real)); - } - } - continue; - } - else if (func_number == memorize_array_func) - { - fread(&memorize_array_play, sizeof(short), 1, f); - goto begin; - } - else if (func_number == reuse_array_func) - { - fread(&reuse_array_play, sizeof(short), 1, f); - goto begin; - } - - assert(func_number >= 0); - - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int nb_args = signature->nb_args; - int* args_type = signature->args_type; - - for(i=0;i= 0) - { - long current_pos = ftell(f); - args_size[i] = replayBufferedArrays[reuse_array_play].size; - args[i] = (long)malloc(args_size[i]); - fseek(f, replayBufferedArrays[reuse_array_play].file_offset, SEEK_SET); - fread((void*)args[i], args_size[i], 1, f); - fseek(f, current_pos, SEEK_SET); - } - if (memorize_array_play >= 0) - { - assert (memorize_array_play <= sizeBufferedArraysPlay); - if (memorize_array_play == sizeBufferedArraysPlay) - { - sizeBufferedArraysPlay++; - replayBufferedArrays = realloc(replayBufferedArrays, sizeBufferedArraysPlay * sizeof(ReplayBufferedArray)); - replayBufferedArrays[sizeBufferedArraysPlay-1].file_offset = 0; - } - replayBufferedArrays[memorize_array_play].file_offset = ftell(f) - args_size[i]; - replayBufferedArrays[memorize_array_play].size = args_size[i]; - } - break; - - CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: - { - args_size[i] = compute_arg_length(stderr, func_number, i, args); - args[i] = (args_size[i]) ? (long)malloc(args_size[i]) : 0; - fread((void*)args[i], args_size[i], 1, f); - break; - } - - CASE_OUT_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: - { - args_size[i] = compute_arg_length(stderr, func_number, i, args); - args[i] = (long)malloc(args_size[i]); - break; - } - - CASE_OUT_UNKNOWN_SIZE_POINTERS: - { - fread(&args_size[i], sizeof(int), 1, f); - if (args_size[i]) - { - args[i] = (long)malloc(args_size[i]); - } - else - { - if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number)) - { - fprintf(stderr, "call %s arg %d\n", tab_opengl_calls_name[func_number], i); - } - args[i] = 0; - } - break; - } - - CASE_OUT_KNOWN_SIZE_POINTERS: - { - args_size[i] = tab_args_type_length[args_type[i]]; - assert(args_size[i]); - args[i] = (long)malloc(args_size[i]); - break; - } - - case TYPE_DOUBLE: - CASE_IN_KNOWN_SIZE_POINTERS: - args_size[i] = tab_args_type_length[args_type[i]]; - args[i] = (long)malloc(args_size[i]); - fread((void*)args[i], args_size[i], 1, f); - break; - - case TYPE_IN_IGNORED_POINTER: - args[i] = 0; - break; - - default: - fprintf(stderr, "shouldn't happen : call %s arg %d\n", tab_opengl_calls_name[func_number], i); - last_process_id = 0; - return 0; - break; - } - } - if (debug) display_gl_call(stderr, func_number, args, args_size); - - if (debug && reuse_array_play != -1) fprintf(stderr, "reuse_array_play %d\n", reuse_array_play); - if (debug && memorize_array_play != -1) fprintf(stderr, "memorize_array_play %d\n", memorize_array_play); - - if (compressed_file) - { - int reuse_array = -1; - int memorize_array = -1; - void* ptr = NULL; - int bytes_size = 0; - int do_default = 1; - - switch (func_number) - { - case glXMakeCurrent_func: - { - currentState = args[2]; - assert(currentState >= 0 && currentState < NB_STATES); - break; - } - - case glMatrixMode_func: - { - if (states[currentState].matrixMode == args[0]) - { - do_default = 0; - } - else - { - states[currentState].matrixMode = args[0]; - } - break; - } - - case glLoadIdentity_func: - case glLoadMatrixd_func: - case glLoadMatrixf_func: - case glMultMatrixd_func: - case glMultMatrixf_func: - case glOrtho_func: - case glFrustum_func: - case glRotated_func: - case glRotatef_func: - case glScaled_func: - case glScalef_func: - case glTranslated_func: - case glTranslatef_func: - case glPushMatrix_func: - case glPopMatrix_func: - { - if (states[currentState].matrixMode == 5890) - { - if (states[currentState].lastMatrixOp == glLoadIdentity_func && - func_number == glLoadIdentity_func) - { - do_default = 0; - } - states[currentState].lastMatrixOp = func_number; - } - break; - } - - case glPushAttrib_func: - { - if (states[currentState].stackAttribPtr < MAX_SERVER_STATE_STACK_SIZE) - { - int mask = args[0]; - states[currentState].stackAttrib[states[currentState].stackAttribPtr].mask = mask; - if (mask & GL_TRANSFORM_BIT) - { - states[currentState].stackAttrib[states[currentState].stackAttribPtr].matrixMode = - states[currentState].matrixMode; - states[currentState].stackAttrib[states[currentState].stackAttribPtr].lastMatrixOp = - states[currentState].lastMatrixOp; - } - states[currentState].stackAttribPtr++; - } - break; - } - - case glPopAttrib_func: - { - if (states[currentState].stackAttribPtr > 0) - { - --states[currentState].stackAttribPtr; - if (states[currentState].stackAttrib[states[currentState].stackAttribPtr].mask & GL_TRANSFORM_BIT) - { - states[currentState].matrixMode = - states[currentState].stackAttrib[states[currentState].stackAttribPtr].matrixMode; - states[currentState].lastMatrixOp = - states[currentState].stackAttrib[states[currentState].stackAttribPtr].lastMatrixOp; - } - } - break; - } - - case glBufferDataARB_func: - { - ptr = args[2]; - bytes_size = args_size[2]; - break; - } - - case glVertexPointer_fake_func: - case glTexCoordPointer_fake_func: - case glTexCoordPointer01_fake_func: - case glDrawElements_func: - { - ptr = (void*)args[nb_args - 1]; - bytes_size = args_size[nb_args - 1]; - break; - } - - default: - break; - } - - if (ptr) - { - unsigned int crc = calc_checksum(ptr, bytes_size, 0xFFFFFFFF); - long long minInterest = 0x7FFFFFFFFFFFFFFFLL; - int iMinUsed = -1; - - instr_count++; - - for(i=0;i= -32768 && (x) < 32768) - - case glRasterPos2i_func: - { - if (IS_SHORT(args[0]) && IS_SHORT(args[1])) - { - WRITE_SHORT(glRasterPos2s_func); - WRITE_SHORT(args[0]); - WRITE_SHORT(args[1]); - do_default = 0; - } - break; - } - - case glVertex2i_func: - { - if (IS_SHORT(args[0]) && IS_SHORT(args[1])) - { - WRITE_SHORT(glVertex2s_func); - WRITE_SHORT(args[0]); - WRITE_SHORT(args[1]); - do_default = 0; - } - break; - } - - case glTexCoord2i_func: - { - if (IS_SHORT(args[0]) && IS_SHORT(args[1])) - { - WRITE_SHORT(glTexCoord2s_func); - WRITE_SHORT(args[0]); - WRITE_SHORT(args[1]); - do_default = 0; - } - break; - } - - case glTexCoord2fv_func: - { - float* ptr = (float*)args[0]; - float u = ptr[0]; - float v = ptr[1]; - if (fabs(u - (int)u) < 1e-7 && fabs(v - (int)v) < 1e-7) - { - int ui = (int)u; - int vi = (int)v; - if (IS_SHORT(ui) && IS_SHORT(vi)) - { - WRITE_SHORT(glTexCoord2s_func); - WRITE_SHORT(ui); - WRITE_SHORT(vi); - do_default = 0; - } - } - break; - } - - case glTexCoord2f_func: - { - float u = *(float*)&args[0]; - float v = *(float*)&args[1]; - if (fabs(u - (int)u) < 1e-7 && fabs(v - (int)v) < 1e-7) - { - int ui = (int)u; - int vi = (int)v; - if (IS_SHORT(ui) && IS_SHORT(vi)) - { - WRITE_SHORT(glTexCoord2s_func); - WRITE_SHORT(ui); - WRITE_SHORT(vi); - do_default = 0; - } - } - break; - } - - case glColor3f_func: - { - WRITE_SHORT(glColor3ub_func); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[0]); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[1]); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[2]); - do_default = 0; - break; - } - - case glColor4f_func: - { - if (*(float*)&args[3] == 1) - { - WRITE_SHORT(glColor3ub_func); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[0]); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[1]); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[2]); - } - else - { - WRITE_SHORT(glColor4ub_func); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[0]); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[1]); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[2]); - WRITE_UNSIGNED_CHAR(255 * *(float*)&args[3]); - } - do_default = 0; - break; - } - - case glColor4fv_func: - { - float* ptr = (float*)args[0]; - if (ptr[3] == 1) - { - WRITE_SHORT(glColor3ub_func); - WRITE_UNSIGNED_CHAR(255 * ptr[0]); - WRITE_UNSIGNED_CHAR(255 * ptr[1]); - WRITE_UNSIGNED_CHAR(255 * ptr[2]); - } - else - { - WRITE_SHORT(glColor4ub_func); - WRITE_UNSIGNED_CHAR(255 * ptr[0]); - WRITE_UNSIGNED_CHAR(255 * ptr[1]); - WRITE_UNSIGNED_CHAR(255 * ptr[2]); - WRITE_UNSIGNED_CHAR(255 * ptr[3]); - } - do_default = 0; - break; - } - - case glColor3d_func: - { - WRITE_SHORT(glColor3ub_func); - WRITE_UNSIGNED_CHAR(255 * *(double*)args[0]); - WRITE_UNSIGNED_CHAR(255 * *(double*)args[1]); - WRITE_UNSIGNED_CHAR(255 * *(double*)args[2]); - do_default = 0; - break; - } - - case glVertex3f_func: - { - if (*(float*)&args[2] == 0) - { - WRITE_SHORT(glVertex2f_func); - WRITE_FLOAT(*(float*)&args[0]); - WRITE_FLOAT(*(float*)&args[1]); - do_default = 0; - } - break; - } - - case glVertex3d_func: - { - WRITE_SHORT(glVertex3f_func); - WRITE_FLOAT(*(double*)args[0]); - WRITE_FLOAT(*(double*)args[1]); - WRITE_FLOAT(*(double*)args[2]); - do_default = 0; - break; - } - - case glNormal3fv_func: - { - float* ptr = (float*)args[0]; - float u = ptr[0]; - float v = ptr[1]; - float w = ptr[2]; - if (fabs(u - (int)u) < 1e-7 && fabs(v - (int)v) < 1e-7 && fabs(w - (int)w) < 1e-7) - { - int ui = (int)u; - int vi = (int)v; - int wi = (int)w; - if (IS_SHORT(ui) && IS_SHORT(vi) && IS_SHORT(wi)) - { - WRITE_SHORT(glNormal3sv_func); - WRITE_SHORT(ui); - WRITE_SHORT(vi); - WRITE_SHORT(wi); - do_default = 0; - } - } - break; - } - - case glNormal3d_func: - { - WRITE_SHORT(glNormal3f_func); - WRITE_FLOAT(*(double*)args[0]); - WRITE_FLOAT(*(double*)args[1]); - WRITE_FLOAT(*(double*)args[2]); - do_default = 0; - break; - } - - case glDrawElements_func: - { - int mode = args[0]; - int count = args[1]; - int type = args[2]; - if (type == GL_UNSIGNED_INT) - { - int j; - unsigned int* ptr = (unsigned int*)args[3]; - for(j=0;j> 16) != 0) - break; - } - if (j == count) - { - WRITE_SHORT(func_number); - WRITE_INT(mode); - WRITE_INT(count); - WRITE_INT(GL_UNSIGNED_SHORT); - if (reuse_array != -1) - { - WRITE_INT(0); - } - else - { - WRITE_INT(count * sizeof(short)); - for(j=0;j= show_diff_offset)) - { - fprintf(stderr, "offset = %d, diff=%d\n", new_offset, new_offset - last_cmd_offset); - } - last_cmd_offset = new_offset; - - if (func_number == glXCreateContext_func && args[1] == visualid_fbconfig_read) - { - args[1] = visualid_fbconfig_real; - } - if (debug) - { - if (func_number == glBindProgramARB_func) - { - fprintf(stderr, "glBindProgramARB_func(y, x) : x = %d\n", args[1]); - } - else if (func_number == glXGetProcAddress_fake_func) - { - fprintf(stderr, "glXGetProcAddress_fake(%s)\n", (char*)args[0]); - } - } - - if (debug && func_number == glEnable_func) - { - fprintf(stderr, "enable(0x%X)\n", args[0]); - } - else if (debug && func_number == glDisable_func) - { - fprintf(stderr, "disable(0x%X)\n", args[0]); - } - - if (resize) - { - if (func_number == _moveResizeWindow_func) - { - int* params = (int*)args[1]; - orig_window_width = params[2]; - window_height = params[3] = params[3] * window_width / params[2]; - params[2] = window_width; - //buffer = malloc(4 * window_width * window_height); - } - else if (func_number == glViewport_func || func_number == glScissor_func) - { - args[0] = args[0] * window_width / orig_window_width; - args[1] = args[1] * window_width / orig_window_width; - args[2] = args[2] * window_width / orig_window_width; - args[3] = args[3] * window_width / orig_window_width; - } - } - else if (func_number == _moveResizeWindow_func) - { - int* params = (int*)args[1]; - window_width = params[2]; - window_height = params[3]; - //buffer = malloc(4 * window_width * window_height); - } - - int ret = (noplay) ? 0 : do_function_call(dpy, func_number, 1, args, ret_string); - - if (func_number == glXSwapBuffers_func) - { - /*glReadPixels(0, 0, window_width, window_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - fwrite(buffer, 4 * window_width * window_height, 1, fout);*/ - - int diff_time; - count_current++; - gettimeofday(¤t_time, NULL); - diff_time = (current_time.tv_sec - last_time.tv_sec) * 1000 + (current_time.tv_usec - last_time.tv_usec) / 1000; - if (diff_time > refresh_rate) - { - printf("%d frames in %.1f seconds = %.3f FPS\n", - count_current - count_last_time, - diff_time / 1000., - (count_current - count_last_time) * 1000. / diff_time); - if (show_hard_disk_bandwith) - { - int current_offset = ftell(f); - printf("bandwidth : %.1f MB/s\n", (current_offset - last_offset) * 1e-6); - last_offset = current_offset; - } - last_time.tv_sec = current_time.tv_sec; - last_time.tv_usec = current_time.tv_usec; - count_last_time = count_current; - } - usleep(slowdown * 50000); - } - if (debug && func_number == glGenProgramsARB_func && args[0] == 1) - { - fprintf(stderr, "glGenProgramsARB_func(1, &x) : x = %d\n", *(int*)args[1]); - } - - if (func_number == glXGetVisualFromFBConfig_func) - { - fread(&visualid_fbconfig_read, sizeof(int), 1, f); - visualid_fbconfig_real = ret; - } - - for(i=0;i -#include -#include -#include -#include - -#ifdef _WIN32 // or __MINGW32__ - #include - #include -#else // _WIN32 -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -#endif // _WIN32 - -#define ENABLE_GL_LOG - -#include "opengl_func.h" -#include "opengl_utils.h" -#include "opengl_server.h" -#include "sdb.h" - -#include "../tizen/src/debug_ch.h" - -MULTI_DEBUG_CHANNEL(qemu,opengl_server); - - -extern int display_function_call; - -#ifdef _WIN32 -HWND displayHWND; -static Display CreateDisplay(void) -{ - HWND hWnd; - WNDCLASS wc; - LPSTR ClassName ="DISPLAY"; - HINSTANCE hInstance = 0; - - /* only register the window class once - use hInstance as a flag. */ - hInstance = GetModuleHandle(NULL); - wc.style = CS_OWNDC; - wc.lpfnWndProc = (WNDPROC)DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = ClassName; - - RegisterClass(&wc); - - displayHWND = CreateWindow(ClassName, ClassName, (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU ), - 0, 0, 10, 10, NULL, (HMENU)NULL, hInstance, NULL); - - - ShowWindow(hWnd, SW_HIDE); - - return GetDC(displayHWND); -} -#endif // _WIN32 - -#ifdef ENABLE_GL_LOG -static FILE* f = NULL; - -static const char* filename = "/tmp/debug_gl.bin"; - -#define write_gl_debug_init() do { if (f == NULL) f = fopen(filename, "wb"); } while(0) - -inline static void write_gl_debug_cmd_char(char my_int) -{ - write_gl_debug_init(); - fwrite(&my_int, sizeof(my_int), 1, f); -} - -inline static void write_gl_debug_cmd_short(short my_int) -{ - write_gl_debug_init(); - fwrite(&my_int, sizeof(my_int), 1, f); -} - -inline static void write_gl_debug_cmd_int(int my_int) -{ - write_gl_debug_init(); - fwrite(&my_int, sizeof(my_int), 1, f); -} - -inline static void write_gl_debug_cmd_longlong(long long my_longlong) -{ - write_gl_debug_init(); - fwrite(&my_longlong, sizeof(my_longlong), 1, f); -} - -inline static void write_gl_debug_cmd_buffer_with_size(int size, void* buffer) -{ - write_gl_debug_init(); - fwrite(&size, sizeof(int), 1, f); - if (size) - fwrite(buffer, size, 1, f); -} - -inline static void write_gl_debug_cmd_buffer_without_size(int size, void* buffer) -{ - write_gl_debug_init(); - if (size) - fwrite(buffer, size, 1, f); -} - -inline static void write_gl_debug_end(void) -{ - write_gl_debug_init(); - fclose(f); - f = NULL; -} - -#endif - -static int write_sock_data(int sock, void* data, int len) -{ - int offset = 0; - - if (len && data) - { - while(offset < len) - { - int nwritten = send(sock, data + offset, len - offset, 0); - if (nwritten == -1) - { -#ifndef _WIN32 - if (errno == EINTR) - continue; -#endif - ERR("write error : %s(%d)\n", strerror(errno), errno); - //assert(nwritten != -1); - return -1; - } - offset += nwritten; - } - } - - return offset; -} - -inline static int write_sock_int(int sock, int my_int) -{ - return write_sock_data(sock, &my_int, sizeof(int)); -} - -static int total_read = 0; -static void read_sock_data(int sock, void* data, int len) -{ - if (len) - { - int offset = 0; - while(offset < len) - { - int nread = recv(sock, data + offset, len - offset, 0); - if (nread == -1) - { -#ifndef _WIN32 - if (errno == EINTR) - continue; -#endif - ERR("read(%d) error : %s(%d)\n", sock, strerror(errno), errno); - //assert(nread != -1); - } - if (nread == 0) - { - //fprintf(stderr, "nread = 0\n"); - } - //assert(nread > 0); - if (nread > 0) - { - offset += nread; - total_read += nread; - } - } - } -} - -inline static int read_sock_int(int sock) -{ - int ret; - read_sock_data(sock, &ret, sizeof(int)); - return ret; -} - -inline static short read_sock_short(int sock) -{ - short ret; - read_sock_data(sock, &ret, sizeof(short)); - return ret; -} - -static int OGLS_readConn( OGLS_Conn *pConn ) -{ - int sock = pConn->sock; - long args[50]; - int args_size[50]; - char ret_string[32768]; - char command_buffer[65536*16]; - - if( pConn->Display == NULL ) - { - create_process_tab(pConn); -#ifdef _WIN32 - pConn->Display = CreateDisplay(); -#else - pConn->Display = XOpenDisplay(NULL); - if (pConn->pOption->parent_xid != -1) - { - opengl_exec_set_parent_window(pConn, pConn->pOption->parent_xid); - } -#endif // _WIN32 - } - - int i; - int func_number = read_sock_short(sock); - - TRACE("OGLS_readConn (%s)\n", tab_opengl_calls_name[func_number]); - - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int ret_type = signature->ret_type; - int nb_args = signature->nb_args; - int* args_type = signature->args_type; - int pid = 0; - - if (func_number == _serialized_calls_func) - { - int command_buffer_size = read_sock_int(sock); - int commmand_buffer_offset = 0; - read_sock_data(sock, command_buffer, command_buffer_size); - -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_short(_serialized_calls_func); -#endif - - while(commmand_buffer_offset < command_buffer_size) - { - func_number = *(short*)(command_buffer + commmand_buffer_offset); - if( ! (func_number >= 0 && func_number < GL_N_CALLS) ) - { - fprintf(stderr, "func_number >= 0 && func_number < GL_N_CALLS failed at " - "commmand_buffer_offset=%d (command_buffer_size=%d)\n", - commmand_buffer_offset, command_buffer_size); - //exit(-1); - return -1; - } - -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_short(func_number); -#endif - TRACE("serialized call is %s\n", tab_opengl_calls_name[func_number]); - - commmand_buffer_offset += sizeof(short); - - - signature = (Signature*)tab_opengl_calls[func_number]; - ret_type = signature->ret_type; - assert(ret_type == TYPE_NONE); - nb_args = signature->nb_args; - args_type = signature->args_type; - - for(i=0;ipOption->must_save) write_gl_debug_cmd_char(args[i]); -#endif - commmand_buffer_offset += sizeof(int); - break; - } - - case TYPE_UNSIGNED_SHORT: - case TYPE_SHORT: - { - args[i] = *(int*)(command_buffer + commmand_buffer_offset); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_short(args[i]); -#endif - commmand_buffer_offset += sizeof(int); - break; - } - - case TYPE_UNSIGNED_INT: - case TYPE_INT: - case TYPE_FLOAT: - { - args[i] = *(int*)(command_buffer + commmand_buffer_offset); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_int(args[i]); -#endif - commmand_buffer_offset += sizeof(int); - break; - } - - case TYPE_NULL_TERMINATED_STRING: -CASE_IN_UNKNOWN_SIZE_POINTERS: - { - args_size[i] = *(int*)(command_buffer + commmand_buffer_offset); - commmand_buffer_offset += sizeof(int); - - if (args_size[i] == 0) - { - args[i] = 0; - } - else - { - args[i] = (long)(command_buffer + commmand_buffer_offset); - } - - if (args[i] == 0) - { - if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number)) - { - fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid); - return 0; - } - } -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_buffer_with_size(args_size[i], (void*)args[i]); -#endif - commmand_buffer_offset += args_size[i]; - - break; - } - -CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: - { - args_size[i] = compute_arg_length(stderr, func_number, i, args); - args[i] = (args_size[i]) ? (long)(command_buffer + commmand_buffer_offset) : 0; -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_buffer_without_size(args_size[i], (void*)args[i]); -#endif - commmand_buffer_offset += args_size[i]; - break; - } - -CASE_OUT_POINTERS: - { - fprintf(stderr, "shouldn't happen TYPE_OUT_xxxx : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid); - return 0; - break; - } - - case TYPE_DOUBLE: -CASE_IN_KNOWN_SIZE_POINTERS: - args[i] = (long)(command_buffer + commmand_buffer_offset); - args_size[i] = tab_args_type_length[args_type[i]]; -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]); -#endif - commmand_buffer_offset += tab_args_type_length[args_type[i]]; - break; - - case TYPE_IN_IGNORED_POINTER: - args[i] = 0; - break; - - default: - fprintf(stderr, "shouldn't happen : call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid); - return 0; - break; - } - } - - if (display_function_call) display_gl_call(stderr, func_number, args, args_size); - do_function_call(pConn, func_number, 1, args, ret_string); - } - } - else - { -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save && func_number != _synchronize_func) write_gl_debug_cmd_short(func_number); -#endif - - for(i=0;ipOption->must_save) write_gl_debug_cmd_char(args[i]); -#endif - break; - - case TYPE_UNSIGNED_SHORT: - case TYPE_SHORT: - args[i] = read_sock_int(sock); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_short(args[i]); -#endif - break; - - case TYPE_UNSIGNED_INT: - case TYPE_INT: - case TYPE_FLOAT: - args[i] = read_sock_int(sock); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_int(args[i]); -#endif - break; - - case TYPE_NULL_TERMINATED_STRING: -CASE_IN_UNKNOWN_SIZE_POINTERS: - { - args_size[i] = read_sock_int(sock); - if (args_size[i]) - { - args[i] = (long)malloc(args_size[i]); - read_sock_data(sock, (void*)args[i], args_size[i]); - } - else - { - args[i] = 0; - if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number)) - { - fprintf(stderr, "call %s arg %d\n", tab_opengl_calls_name[func_number], i); - return 0; - } - } -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_buffer_with_size(args_size[i], (void*)args[i]); -#endif - break; - } - -CASE_IN_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: - { - args_size[i] = compute_arg_length(stderr, func_number, i, args); - args[i] = (args_size[i]) ? (long)malloc(args_size[i]) : 0; - read_sock_data(sock, (void*)args[i], args_size[i]); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_buffer_without_size(args_size[i], (void*)args[i]); -#endif - break; - } - -CASE_OUT_LENGTH_DEPENDING_ON_PREVIOUS_ARGS: - { - args_size[i] = compute_arg_length(stderr, func_number, i, args); - args[i] = (long)malloc(args_size[i]); - break; - } - -CASE_OUT_UNKNOWN_SIZE_POINTERS: - { - args_size[i] = read_sock_int(sock); - if (func_number == glGetProgramLocalParameterdvARB_func) - { - fprintf(stderr, "size = %d\n", args_size[i]); - } - if (args_size[i]) - { - args[i] = (long)malloc(args_size[i]); - } - else - { - if (!IS_NULL_POINTER_OK_FOR_FUNC(func_number)) - { - fprintf(stderr, "call %s arg %d pid=%d\n", tab_opengl_calls_name[func_number], i, pid); - return 0; - }; - args[i] = 0; - } - //fprintf(stderr, "%p %d\n", (void*)args[i], args_size[i]); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_int(args_size[i]); -#endif - break; - } - -CASE_OUT_KNOWN_SIZE_POINTERS: - { - args_size[i] = tab_args_type_length[args_type[i]]; - assert(args_size[i]); - args[i] = (long)malloc(args_size[i]); - //fprintf(stderr, "%p %d\n", (void*)args[i], args_size[i]); - break; - } - - case TYPE_DOUBLE: -CASE_IN_KNOWN_SIZE_POINTERS: - args_size[i] = tab_args_type_length[args_type[i]]; - args[i] = (long)malloc(args_size[i]); - read_sock_data(sock, (void*)args[i], args_size[i]); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save) write_gl_debug_cmd_buffer_without_size(tab_args_type_length[args_type[i]], (void*)args[i]); -#endif - break; - - case TYPE_IN_IGNORED_POINTER: - args[i] = 0; - break; - - default: - fprintf(stderr, "shouldn't happen : call %s arg %d\n", tab_opengl_calls_name[func_number], i); - return 0; - break; - } - } - - if (display_function_call) display_gl_call(stderr, func_number, args, args_size); - - if (getenv("ALWAYS_FLUSH")) fflush(f); - - int ret = do_function_call(pConn, func_number, 1, args, ret_string); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save && func_number == glXGetVisualFromFBConfig_func) - { - write_gl_debug_cmd_int(ret); - } -#endif - - for(i=0;i write_sock_data(sock, (void*)args[i], args_size[i]) ) - { - perror( "write_sock_data" ) ; - return -1 ; - } - - if (display_function_call) - { - if (args_type[i] == TYPE_OUT_1INT) - { - fprintf(stderr, "out[%d] : %d\n", i, *(int*)args[i]); - } - else if (args_type[i] == TYPE_OUT_1FLOAT) - { - fprintf(stderr, "out[%d] : %f\n", i, *(float*)args[i]); - } - } - if (args[i]) free((void*)args[i]); - break; - - case TYPE_IN_IGNORED_POINTER: - args[i] = 0; - break; - - default: - fprintf(stderr, "shouldn't happen : call %s arg %d\n", tab_opengl_calls_name[func_number], i); - return 0; - break; - } - } - - if (signature->ret_type == TYPE_CONST_CHAR) - { - if( 0 > write_sock_int(sock, strlen(ret_string) + 1) ) - { - perror( "write_sock_int" ) ; - return -1 ; - } - if( 0 > write_sock_data(sock, ret_string, strlen(ret_string) + 1) ) - { - perror( "write_sock_data" ) ; - return -1 ; - } - } - else if (signature->ret_type != TYPE_NONE) - { - if( 0 > write_sock_int(sock, ret) ) - { - perror( "write_sock_int" ) ; - return -1 ; - } - } - -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save && func_number == _exit_process_func) - { - write_gl_debug_end(); - } -#endif - if (func_number == _exit_process_func) - { - return -1; - } - else if (func_number == glXSwapBuffers_func) - { - int diff_time; - pConn->count_current++; - gettimeofday(&pConn->current_time, NULL); -#ifdef ENABLE_GL_LOG - if (pConn->pOption->must_save && pConn->pOption->timestamp) - { - long long ts = (pConn->current_time.tv_sec - pConn->time_stamp_start.tv_sec) * (long long)1000000 + pConn->current_time.tv_usec - pConn->time_stamp_start.tv_usec; - /* -1 is special code that indicates time synchro */ - write_gl_debug_cmd_short(timesynchro_func); - write_gl_debug_cmd_longlong(ts); - } -#endif - diff_time = (pConn->current_time.tv_sec - pConn->last_time.tv_sec) * 1000 + (pConn->current_time.tv_usec - pConn->last_time.tv_usec) / 1000; - if (diff_time > pConn->pOption->refresh_rate) - { -#ifdef ENABLE_GL_LOG - fflush(f); -#endif - printf("%d frames in %.1f seconds = %.3f FPS\n", - pConn->count_current - pConn->count_last_time, - diff_time / 1000., - (pConn->count_current - pConn->count_last_time) * 1000. / diff_time); - pConn->last_time.tv_sec = pConn->current_time.tv_sec; - pConn->last_time.tv_usec = pConn->current_time.tv_usec; - pConn->count_last_time = pConn->count_current; - } - } - } - return 0; -} - -static int OGLS_createListenSocket (uint16_t port) -{ - int sock; - struct sockaddr_in name; - - /* Create the socket. */ - sock = socket (PF_INET, SOCK_STREAM, 0); - if (sock < 0) - { - ERR("socket error : %s(%d)\n", strerror(errno), errno); - //exit (EXIT_FAILURE); - return -1; - } - - int flag = 1; - if (setsockopt(sock, IPPROTO_IP, SO_REUSEADDR,(char *)&flag, sizeof(int)) != 0) - { - ERR("setsockopt error(SO_REUSEADDR) : %s(%d)\n", strerror(errno), errno); - } - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,(char *)&flag, sizeof(int)) != 0) - { - ERR("setsockopt error(TCP_NODELAY) : %s(%d)\n", strerror(errno), errno); - } - - /* Give the socket a name. */ - name.sin_family = AF_INET; - name.sin_port = htons (port); - name.sin_addr.s_addr = htonl (INADDR_ANY); - if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) - { - fprintf(stderr, "bind(INADDR_ANY:%d): errorno = %d(%s)\n", port, errno, strerror(errno)); - ERR("bind error : %s(%d)\n", strerror(errno), errno); - //exit (EXIT_FAILURE); - //exit (EXIT_FAILURE); - return -1; - } - - //fprintf(stderr, "Port(%d/tcp) listen for opengl \n", port); - - return sock; -} - -static OGLS_Conn * OGLS_createConn( OGLS_Opts *pOption ) -{ - OGLS_Conn *pConn = malloc(sizeof(OGLS_Conn)); - if( !pConn ) - { - return NULL ; - } - - memset( pConn, 0, sizeof(*pConn) ); - pConn->pOption = pOption; - return pConn; -} - -static void OGLS_removeConn( OGLS_Conn *pConn ) -{ - if( !pConn ) return ; - - if( pConn->sock > 0 ) - { - closesocket(pConn->sock); - pConn->sock = 0 ; - } - - if( pConn->Display ) - { -#ifdef _WIN32 - // ReleaseDC(pConn->Display); -#else - XCloseDisplay( pConn->Display ); - pConn->Display = NULL; -#endif // _WIN32 - } - - remove_process_tab(pConn); - - free( pConn ); -} - -static void OGLS_loop( OGLS_Conn *pConn ) -{ - //fprintf (stderr, "Server: connect from host %s, port %hd.\n", - // inet_ntoa (pConn->clientname.sin_addr), - // ntohs (pConn->clientname.sin_port)); - - gettimeofday(&pConn->last_time, NULL); - gettimeofday(&pConn->last_read_time, NULL); - -#ifndef _WIN32 - if (strcmp(inet_ntoa(pConn->clientname.sin_addr), "127.0.0.1") == 0 && - pConn->pOption->different_windows == 0) - { - pConn->local_connection = 1; - } -#endif // _WIN32 - - if( pConn->pOption->timestamp ) - { - gettimeofday(&pConn->time_stamp_start, NULL); - } - - while( OGLS_readConn(pConn) >= 0 ); - - do_function_call(pConn, _exit_process_func, 1, NULL, NULL); - - //fprintf (stderr, "Server: disconnect from host %s, port %hd.\n", - // inet_ntoa (pConn->clientname.sin_addr), - // ntohs (pConn->clientname.sin_port)); - - OGLS_removeConn( pConn ); -} - -#ifndef _WIN32 -int has_x_error = 0; -static int OGLS_x_error_handler(Display *display, XErrorEvent *error) -{ - char buf[64]; - XGetErrorText(display, error->error_code, buf, 63); - fprintf (stderr, "The program received an X Window System error.\n" - "This probably reflects a bug in the program.\n" - "The error was '%s'.\n" - " (Details: serial %ld error_code %d request_code %d minor_code %d)\n", - buf, - error->serial, - error->error_code, - error->request_code, - error->minor_code); - has_x_error = 1; - return 0; -} -#endif // _WIN32 - -static void OGLS_main( OGLS_Opts *pOption ) -{ - int sock; - fd_set active_fd_set, read_fd_set; - - socklen_t size; - -#ifndef _WIN32 - XSetErrorHandler(OGLS_x_error_handler); -#endif // _WIN32 - - /* Create the socket and set it up to accept connections. */ - sock = OGLS_createListenSocket( pOption->port ); - if (sock < 0) - return; - - if (listen (sock, 1) < 0) - { - ERR("listen error : %s(%d)\n", strerror(errno), errno); - //exit (EXIT_FAILURE); - return; - } - - FD_ZERO (&active_fd_set); - FD_SET (sock, &active_fd_set); - - while(1) - { - OGLS_Conn *pConn = NULL; - pthread_t taskid; - - read_fd_set = active_fd_set; - if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) - { -#ifndef _WIN32 - if (errno == EINTR) { - continue; - } -#endif - ERR("select error : %s(%d)\n", strerror(errno), errno); - //exit (EXIT_FAILURE); - break; - } - - pConn = OGLS_createConn( pOption ); - if( !pConn ) - { - perror( "OGLS_createConn" ); - continue; - } - - size = sizeof(pConn->clientname); - pConn->sock = accept (sock, (struct sockaddr *) &pConn->clientname, &size); - if (pConn->sock < 0) - { - ERR("accept error : %s(%d)\n", strerror(errno), errno); - OGLS_removeConn( pConn ); - continue; - } - - if( pthread_create( (pthread_t *)&taskid, NULL, (void *(*)(void *))OGLS_loop, (void *)pConn ) ) - { - ERR("pthread_create error : %s(%d)\n", strerror(errno), errno); - OGLS_removeConn( pConn ); - continue; - } - } - - closesocket( sock ); -} - -#if 0 -static void usage(void) -{ - printf("Usage : opengl_server [OPTION]\n\n"); - printf("The following options are available :\n"); - printf("--port=XXXX : set XXX as the port number for the TCP/IP server \n"); - printf("--debug : output debugging trace on stderr\n"); - printf("--save : dump the serialialized OpenGL flow in a file (default : /tmp/debug_gl.bin)\n"); - printf("--filename=X : the file where to write the serailized OpenGL flow\n"); - printf("--different-windows : even if the client is on 127.0.0.1, display OpenGL on a new X window\n"); - printf("--parent-xid=XXX : use XXX as the XID of the parent X window where to display the OpenGL flow\n"); - printf(" This is useful if you want to run accelerated OpenGL inside a non-patched QEMU\n"); - printf(" or from another emulator, through TCP/IP\n"); - printf("--h or --help : display this help\n"); -} -#endif - -//int main (int argc, char* argv[]) -void *init_opengl_server(void *arg) -{ - OGLS_Opts option; - - memset( &option, 0, sizeof(option) ); - - // set default values - option.port = get_sdb_base_port() + SDB_TCP_OPENGL_INDEX; - option.parent_xid = -1; - option.refresh_rate = 1000; - option.timestamp = 1; /* only valid if must_save == 1. include timestamps in the save file to enable real-time playback */ - -#if 0 - for(i=1;i -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 - #include - #include - #include - #include - #include - #include - #include -#else - #include - #include -#endif /* _WIN32 */ - -#ifdef _WIN32 -#define socklen_t int -typedef HDC Display; -typedef unsigned long Window; -#else -#define closesocket close -#endif - -typedef struct { - int port; - int different_windows; - int display_function_call; - int must_save; - int parent_xid; - int refresh_rate; - int timestamp; /* only valid if must_save == 1. include timestamps in the save file to enable real-time playback */ -} OGLS_Opts; - -typedef struct { - int sock; - int count_last_time, count_current; - struct timeval last_time, current_time, time_stamp_start; - struct timeval last_read_time, current_read_time; - - struct sockaddr_in clientname; -#ifdef _WIN32 - Display Display; - HDC active_win; /* FIXME */ -#else - Display* parent_dpy; - Window qemu_parent_window; - - Display* Display; - Window active_win; /* FIXME */ -#endif - int active_win_x; - int active_win_y; - - int local_connection; - - int last_assigned_internal_num; - int last_active_internal_num; - - int nTabAssocAttribListVisual ; - void* tabAssocAttribListVisual ; - void * processTab; - - OGLS_Opts *pOption; -} OGLS_Conn ; - -/* opengl_server main function */ -void *init_opengl_server(void *arg); - -#endif /* OPENGL_SERVER_H_ */ diff --git a/target-i386/opengl_utils.h b/target-i386/opengl_utils.h deleted file mode 100644 index 1b0a2b5..0000000 --- a/target-i386/opengl_utils.h +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Functions used by host & client sides - * - * Copyright (c) 2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - - -#ifndef _OPENGL_UTILS -#define _OPENGL_UTILS - -typedef struct -{ - unsigned int* values; - int nbValues; -} RangeAllocator; - -/* - static void print_range(RangeAllocator* range) - { - int i; - printf("%s", "table : "); - for(i=0;inbValues;i++) - { - printf("%d ", range->values[i]); - } - printf("\n"); - } - */ - -static void alloc_value(RangeAllocator* range, unsigned int value) -{ - if (value == 0) return; - if (range->nbValues >= 1) - { - int lower = 0; - int upper = range->nbValues-1; - while(1) - { - int mid = (lower + upper) / 2; - if (range->values[mid] > value) - upper = mid; - else if (range->values[mid] < value) - lower = mid; - else - break; - if (upper - lower <= 1) - { - if (value < range->values[lower]) - { - range->values = realloc(range->values, (range->nbValues+1) * sizeof(int)); - memmove(&range->values[lower+1], &range->values[lower], (range->nbValues - lower) * sizeof(int)); - range->values[lower] = value; - range->nbValues++; - } - else if (value == range->values[lower]) - { - } - else if (value < range->values[upper]) - { - range->values = realloc(range->values, (range->nbValues+1) * sizeof(int)); - memmove(&range->values[upper+1], &range->values[upper], (range->nbValues - upper) * sizeof(int)); - range->values[upper] = value; - range->nbValues++; - } - else if (value == range->values[upper]) - { - } - else - { - upper++; - - range->values = realloc(range->values, (range->nbValues+1) * sizeof(int)); - memmove(&range->values[upper+1], &range->values[upper], (range->nbValues - upper) * sizeof(int)); - range->values[upper] = value; - range->nbValues++; - } - break; - } - } - } - else - { - range->values = malloc(sizeof(int)); - range->values[0] = value; - range->nbValues = 1; - } -} - -/* return first value */ -static unsigned int alloc_range(RangeAllocator* range, int n, unsigned int* values) -{ - int i, j; - if (range->nbValues == 0) - { - range->nbValues = n; - range->values = malloc(n * sizeof(int)); - for(i=0;ivalues[i] = i+1; - if (values) - values[i] = range->values[i]; - } - return 1; - } - else - { - int lastValue = 1; - for(i=0;inbValues;i++) - { - if ((int)range->values[i] - (int)lastValue - 1 >= n) - { - range->values = realloc(range->values, (range->nbValues+n) * sizeof(int)); - memmove(&range->values[i+n], &range->values[i], (range->nbValues - i) * sizeof(int)); - for(j=0;jvalues[i+j] = lastValue + 1 + j; - if (values) - values[j] = range->values[i+j]; - } - range->nbValues += n; - break; - } - else - lastValue = range->values[i]; - } - if (i == range->nbValues) - { - range->values = realloc(range->values, (range->nbValues+n) * sizeof(int)); - for(j=0;jvalues[i+j] = lastValue + 1 + j; - if (values) - values[j] = range->values[i+j]; - } - range->nbValues += n; - } - return lastValue + 1; - } -} - -static void delete_value(RangeAllocator* range, unsigned int value) -{ - if (value == 0) - return; - if (range->nbValues >= 1) - { - int lower = 0; - int upper = range->nbValues-1; - while(1) - { - int mid = (lower + upper) / 2; - if (range->values[mid] > value) - upper = mid; - else if (range->values[mid] < value) - lower = mid; - else - { - lower = upper = mid; - } - if (upper - lower <= 1) - { - if (value == range->values[lower]) - { - memmove(&range->values[lower], &range->values[lower+1], (range->nbValues - lower-1) * sizeof(int)); - range->nbValues--; - } - else if (value == range->values[upper]) - { - memmove(&range->values[upper], &range->values[upper+1], (range->nbValues - upper-1) * sizeof(int)); - range->nbValues--; - } - break; - } - } - } -} - -static void delete_range(RangeAllocator* range, int n, const unsigned int* values) -{ - int i; - for(i=0;i> 8); - } - return crc; -} - - -#ifdef _WIN32 -static void display_gl_call(FILE* f, int func_number, long* args, int* args_size) -#else -static inline void display_gl_call(FILE* f, int func_number, long* args, int* args_size) -#endif -{ - int i; - if (func_number < 0) - { - fprintf(f, "unknown call : %d\n", func_number); - return; - } - Signature* signature = (Signature*)tab_opengl_calls[func_number]; - int nb_args = signature->nb_args; - int* args_type = signature->args_type; - - //fprintf(f, "%s(", tab_opengl_calls_name[func_number]); - - for(i=0;isse_status) #define FPU_MUL(size, a, b) float ## size ## _mul(a, b, &env->sse_status) #define FPU_DIV(size, a, b) float ## size ## _div(a, b, &env->sse_status) -#define FPU_MIN(size, a, b) (a) < (b) ? (a) : (b) -#define FPU_MAX(size, a, b) (a) > (b) ? (a) : (b) #define FPU_SQRT(size, a, b) float ## size ## _sqrt(b, &env->sse_status) +/* Note that the choice of comparison op here is important to get the + * special cases right: for min and max Intel specifies that (-0,0), + * (NaN, anything) and (anything, NaN) return the second argument. + */ +#define FPU_MIN(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? (a) : (b) +#define FPU_MAX(size, a, b) float ## size ## _lt(b, a, &env->sse_status) ? (a) : (b) + SSE_HELPER_S(add, FPU_ADD) SSE_HELPER_S(sub, FPU_SUB) SSE_HELPER_S(mul, FPU_MUL) @@ -778,28 +783,38 @@ int64_t helper_cvttsd2sq(XMMReg *s) void helper_rsqrtps(XMMReg *d, XMMReg *s) { - d->XMM_S(0) = approx_rsqrt(s->XMM_S(0)); - d->XMM_S(1) = approx_rsqrt(s->XMM_S(1)); - d->XMM_S(2) = approx_rsqrt(s->XMM_S(2)); - d->XMM_S(3) = approx_rsqrt(s->XMM_S(3)); + d->XMM_S(0) = float32_div(float32_one, + float32_sqrt(s->XMM_S(0), &env->sse_status), + &env->sse_status); + d->XMM_S(1) = float32_div(float32_one, + float32_sqrt(s->XMM_S(1), &env->sse_status), + &env->sse_status); + d->XMM_S(2) = float32_div(float32_one, + float32_sqrt(s->XMM_S(2), &env->sse_status), + &env->sse_status); + d->XMM_S(3) = float32_div(float32_one, + float32_sqrt(s->XMM_S(3), &env->sse_status), + &env->sse_status); } void helper_rsqrtss(XMMReg *d, XMMReg *s) { - d->XMM_S(0) = approx_rsqrt(s->XMM_S(0)); + d->XMM_S(0) = float32_div(float32_one, + float32_sqrt(s->XMM_S(0), &env->sse_status), + &env->sse_status); } void helper_rcpps(XMMReg *d, XMMReg *s) { - d->XMM_S(0) = approx_rcp(s->XMM_S(0)); - d->XMM_S(1) = approx_rcp(s->XMM_S(1)); - d->XMM_S(2) = approx_rcp(s->XMM_S(2)); - d->XMM_S(3) = approx_rcp(s->XMM_S(3)); + d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status); + d->XMM_S(1) = float32_div(float32_one, s->XMM_S(1), &env->sse_status); + d->XMM_S(2) = float32_div(float32_one, s->XMM_S(2), &env->sse_status); + d->XMM_S(3) = float32_div(float32_one, s->XMM_S(3), &env->sse_status); } void helper_rcpss(XMMReg *d, XMMReg *s) { - d->XMM_S(0) = approx_rcp(s->XMM_S(0)); + d->XMM_S(0) = float32_div(float32_one, s->XMM_S(0), &env->sse_status); } static inline uint64_t helper_extrq(uint64_t src, int shift, int len) @@ -849,51 +864,51 @@ void helper_insertq_i(XMMReg *d, int index, int length) void helper_haddps(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_S(0) = d->XMM_S(0) + d->XMM_S(1); - r.XMM_S(1) = d->XMM_S(2) + d->XMM_S(3); - r.XMM_S(2) = s->XMM_S(0) + s->XMM_S(1); - r.XMM_S(3) = s->XMM_S(2) + s->XMM_S(3); + r.XMM_S(0) = float32_add(d->XMM_S(0), d->XMM_S(1), &env->sse_status); + r.XMM_S(1) = float32_add(d->XMM_S(2), d->XMM_S(3), &env->sse_status); + r.XMM_S(2) = float32_add(s->XMM_S(0), s->XMM_S(1), &env->sse_status); + r.XMM_S(3) = float32_add(s->XMM_S(2), s->XMM_S(3), &env->sse_status); *d = r; } void helper_haddpd(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_D(0) = d->XMM_D(0) + d->XMM_D(1); - r.XMM_D(1) = s->XMM_D(0) + s->XMM_D(1); + r.XMM_D(0) = float64_add(d->XMM_D(0), d->XMM_D(1), &env->sse_status); + r.XMM_D(1) = float64_add(s->XMM_D(0), s->XMM_D(1), &env->sse_status); *d = r; } void helper_hsubps(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_S(0) = d->XMM_S(0) - d->XMM_S(1); - r.XMM_S(1) = d->XMM_S(2) - d->XMM_S(3); - r.XMM_S(2) = s->XMM_S(0) - s->XMM_S(1); - r.XMM_S(3) = s->XMM_S(2) - s->XMM_S(3); + r.XMM_S(0) = float32_sub(d->XMM_S(0), d->XMM_S(1), &env->sse_status); + r.XMM_S(1) = float32_sub(d->XMM_S(2), d->XMM_S(3), &env->sse_status); + r.XMM_S(2) = float32_sub(s->XMM_S(0), s->XMM_S(1), &env->sse_status); + r.XMM_S(3) = float32_sub(s->XMM_S(2), s->XMM_S(3), &env->sse_status); *d = r; } void helper_hsubpd(XMMReg *d, XMMReg *s) { XMMReg r; - r.XMM_D(0) = d->XMM_D(0) - d->XMM_D(1); - r.XMM_D(1) = s->XMM_D(0) - s->XMM_D(1); + r.XMM_D(0) = float64_sub(d->XMM_D(0), d->XMM_D(1), &env->sse_status); + r.XMM_D(1) = float64_sub(s->XMM_D(0), s->XMM_D(1), &env->sse_status); *d = r; } void helper_addsubps(XMMReg *d, XMMReg *s) { - d->XMM_S(0) = d->XMM_S(0) - s->XMM_S(0); - d->XMM_S(1) = d->XMM_S(1) + s->XMM_S(1); - d->XMM_S(2) = d->XMM_S(2) - s->XMM_S(2); - d->XMM_S(3) = d->XMM_S(3) + s->XMM_S(3); + d->XMM_S(0) = float32_sub(d->XMM_S(0), s->XMM_S(0), &env->sse_status); + d->XMM_S(1) = float32_add(d->XMM_S(1), s->XMM_S(1), &env->sse_status); + d->XMM_S(2) = float32_sub(d->XMM_S(2), s->XMM_S(2), &env->sse_status); + d->XMM_S(3) = float32_add(d->XMM_S(3), s->XMM_S(3), &env->sse_status); } void helper_addsubpd(XMMReg *d, XMMReg *s) { - d->XMM_D(0) = d->XMM_D(0) - s->XMM_D(0); - d->XMM_D(1) = d->XMM_D(1) + s->XMM_D(1); + d->XMM_D(0) = float64_sub(d->XMM_D(0), s->XMM_D(0), &env->sse_status); + d->XMM_D(1) = float64_add(d->XMM_D(1), s->XMM_D(1), &env->sse_status); } /* XXX: unordered */ @@ -921,14 +936,14 @@ void helper_ ## name ## sd (Reg *d, Reg *s)\ d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\ } -#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0 +#define FPU_CMPEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? -1 : 0 #define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0 #define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0 -#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0 -#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1 +#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? - 1 : 0 +#define FPU_CMPNEQ(size, a, b) float ## size ## _eq_quiet(a, b, &env->sse_status) ? 0 : -1 #define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1 #define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1 -#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1 +#define FPU_CMPORD(size, a, b) float ## size ## _unordered_quiet(a, b, &env->sse_status) ? 0 : -1 SSE_HELPER_CMP(cmpeq, FPU_CMPEQ) SSE_HELPER_CMP(cmplt, FPU_CMPLT) @@ -1216,8 +1231,8 @@ void helper_pfadd(MMXReg *d, MMXReg *s) void helper_pfcmpeq(MMXReg *d, MMXReg *s) { - d->MMX_L(0) = float32_eq(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0; - d->MMX_L(1) = float32_eq(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0; + d->MMX_L(0) = float32_eq_quiet(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0; + d->MMX_L(1) = float32_eq_quiet(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0; } void helper_pfcmpge(MMXReg *d, MMXReg *s) @@ -1272,14 +1287,16 @@ void helper_pfpnacc(MMXReg *d, MMXReg *s) void helper_pfrcp(MMXReg *d, MMXReg *s) { - d->MMX_S(0) = approx_rcp(s->MMX_S(0)); + d->MMX_S(0) = float32_div(float32_one, s->MMX_S(0), &env->mmx_status); d->MMX_S(1) = d->MMX_S(0); } void helper_pfrsqrt(MMXReg *d, MMXReg *s) { d->MMX_L(1) = s->MMX_L(0) & 0x7fffffff; - d->MMX_S(1) = approx_rsqrt(d->MMX_S(1)); + d->MMX_S(1) = float32_div(float32_one, + float32_sqrt(d->MMX_S(1), &env->mmx_status), + &env->mmx_status); d->MMX_L(1) |= s->MMX_L(0) & 0x80000000; d->MMX_L(0) = d->MMX_L(1); } @@ -1636,10 +1653,10 @@ void glue(helper_roundps, SUFFIX) (Reg *d, Reg *s, uint32_t mode) break; } - d->L(0) = float64_round_to_int(s->L(0), &env->sse_status); - d->L(1) = float64_round_to_int(s->L(1), &env->sse_status); - d->L(2) = float64_round_to_int(s->L(2), &env->sse_status); - d->L(3) = float64_round_to_int(s->L(3), &env->sse_status); + d->XMM_S(0) = float32_round_to_int(s->XMM_S(0), &env->sse_status); + d->XMM_S(1) = float32_round_to_int(s->XMM_S(1), &env->sse_status); + d->XMM_S(2) = float32_round_to_int(s->XMM_S(2), &env->sse_status); + d->XMM_S(3) = float32_round_to_int(s->XMM_S(3), &env->sse_status); #if 0 /* TODO */ if (mode & (1 << 3)) @@ -1672,8 +1689,8 @@ void glue(helper_roundpd, SUFFIX) (Reg *d, Reg *s, uint32_t mode) break; } - d->Q(0) = float64_round_to_int(s->Q(0), &env->sse_status); - d->Q(1) = float64_round_to_int(s->Q(1), &env->sse_status); + d->XMM_D(0) = float64_round_to_int(s->XMM_D(0), &env->sse_status); + d->XMM_D(1) = float64_round_to_int(s->XMM_D(1), &env->sse_status); #if 0 /* TODO */ if (mode & (1 << 3)) @@ -1706,7 +1723,7 @@ void glue(helper_roundss, SUFFIX) (Reg *d, Reg *s, uint32_t mode) break; } - d->L(0) = float64_round_to_int(s->L(0), &env->sse_status); + d->XMM_S(0) = float32_round_to_int(s->XMM_S(0), &env->sse_status); #if 0 /* TODO */ if (mode & (1 << 3)) @@ -1739,7 +1756,7 @@ void glue(helper_roundsd, SUFFIX) (Reg *d, Reg *s, uint32_t mode) break; } - d->Q(0) = float64_round_to_int(s->Q(0), &env->sse_status); + d->XMM_D(0) = float64_round_to_int(s->XMM_D(0), &env->sse_status); #if 0 /* TODO */ if (mode & (1 << 3)) @@ -1758,44 +1775,44 @@ SSE_HELPER_I(helper_pblendw, W, 8, FBLENDP) void glue(helper_dpps, SUFFIX) (Reg *d, Reg *s, uint32_t mask) { - float32 iresult = 0 /*float32_zero*/; + float32 iresult = float32_zero; if (mask & (1 << 4)) iresult = float32_add(iresult, - float32_mul(d->L(0), s->L(0), &env->sse_status), + float32_mul(d->XMM_S(0), s->XMM_S(0), &env->sse_status), &env->sse_status); if (mask & (1 << 5)) iresult = float32_add(iresult, - float32_mul(d->L(1), s->L(1), &env->sse_status), + float32_mul(d->XMM_S(1), s->XMM_S(1), &env->sse_status), &env->sse_status); if (mask & (1 << 6)) iresult = float32_add(iresult, - float32_mul(d->L(2), s->L(2), &env->sse_status), + float32_mul(d->XMM_S(2), s->XMM_S(2), &env->sse_status), &env->sse_status); if (mask & (1 << 7)) iresult = float32_add(iresult, - float32_mul(d->L(3), s->L(3), &env->sse_status), + float32_mul(d->XMM_S(3), s->XMM_S(3), &env->sse_status), &env->sse_status); - d->L(0) = (mask & (1 << 0)) ? iresult : 0 /*float32_zero*/; - d->L(1) = (mask & (1 << 1)) ? iresult : 0 /*float32_zero*/; - d->L(2) = (mask & (1 << 2)) ? iresult : 0 /*float32_zero*/; - d->L(3) = (mask & (1 << 3)) ? iresult : 0 /*float32_zero*/; + d->XMM_S(0) = (mask & (1 << 0)) ? iresult : float32_zero; + d->XMM_S(1) = (mask & (1 << 1)) ? iresult : float32_zero; + d->XMM_S(2) = (mask & (1 << 2)) ? iresult : float32_zero; + d->XMM_S(3) = (mask & (1 << 3)) ? iresult : float32_zero; } void glue(helper_dppd, SUFFIX) (Reg *d, Reg *s, uint32_t mask) { - float64 iresult = 0 /*float64_zero*/; + float64 iresult = float64_zero; if (mask & (1 << 4)) iresult = float64_add(iresult, - float64_mul(d->Q(0), s->Q(0), &env->sse_status), + float64_mul(d->XMM_D(0), s->XMM_D(0), &env->sse_status), &env->sse_status); if (mask & (1 << 5)) iresult = float64_add(iresult, - float64_mul(d->Q(1), s->Q(1), &env->sse_status), + float64_mul(d->XMM_D(1), s->XMM_D(1), &env->sse_status), &env->sse_status); - d->Q(0) = (mask & (1 << 0)) ? iresult : 0 /*float64_zero*/; - d->Q(1) = (mask & (1 << 1)) ? iresult : 0 /*float64_zero*/; + d->XMM_D(0) = (mask & (1 << 0)) ? iresult : float64_zero; + d->XMM_D(1) = (mask & (1 << 1)) ? iresult : float64_zero; } void glue(helper_mpsadbw, SUFFIX) (Reg *d, Reg *s, uint32_t offset) @@ -1984,11 +2001,13 @@ void glue(helper_pcmpestrm, SUFFIX) (Reg *d, Reg *s, uint32_t ctrl) if ((ctrl >> 6) & 1) { if (ctrl & 1) - for (i = 0; i <= 8; i--, res >>= 1) + for (i = 0; i < 8; i++, res >>= 1) { d->W(i) = (res & 1) ? ~0 : 0; + } else - for (i = 0; i <= 16; i--, res >>= 1) + for (i = 0; i < 16; i++, res >>= 1) { d->B(i) = (res & 1) ? ~0 : 0; + } } else { d->Q(1) = 0; d->Q(0) = res; @@ -2016,11 +2035,13 @@ void glue(helper_pcmpistrm, SUFFIX) (Reg *d, Reg *s, uint32_t ctrl) if ((ctrl >> 6) & 1) { if (ctrl & 1) - for (i = 0; i <= 8; i--, res >>= 1) + for (i = 0; i < 8; i++, res >>= 1) { d->W(i) = (res & 1) ? ~0 : 0; + } else - for (i = 0; i <= 16; i--, res >>= 1) + for (i = 0; i < 16; i++, res >>= 1) { d->B(i) = (res & 1) ? ~0 : 0; + } } else { d->Q(1) = 0; d->Q(0) = res; diff --git a/target-i386/parse_gl_h.c b/target-i386/parse_gl_h.c deleted file mode 100644 index 6c091ba..0000000 --- a/target-i386/parse_gl_h.c +++ /dev/null @@ -1,1501 +0,0 @@ -/* - * Parse gl.h et glx.h to auto-generate source code - * - * Copyright (c) 2006,2007 Even Rouault - * - * 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 AUTHORS OR 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. - */ - -/* gcc -g parse_gl_h.c -o parse_gl_h && ./parse_gl_h */ -#include -#include -#include -#include - -int isExtByName(const char* name) -{ - return (strstr(name, "ARB") != NULL) || - (strstr(name, "IBM") != NULL) || - (strstr(name, "EXT") != NULL) || - (strstr(name, "ATI") != NULL) || - (strstr(name, "NV") != NULL) || - (strstr(name, "MESA") != NULL) || - (strstr(name, "APPLE") != NULL) || - (strstr(name, "SUN") != NULL) || - (strstr(name, "SGI") != NULL); -} - -char* get_arg_type(char* s) -{ - while(*s == ' ' || *s == '\t') s++; - char* n = s; - char* c = strstr(n, "const"); - if (c) - n += 6; - - char* t = strstr(n, " "); - if (t) - { - if (t[1] == '*') - t += 2; - t[0] = 0; - char* ori = t; - t = strstr(t+1, "["); - if (t) - { - memmove(ori, t, strlen(t)); - strstr(ori, "]")[1] = 0; - } - } - return strdup(s); -} - -typedef struct -{ - char* type; - char* name; - int nargs; - char** args; - int ok; - int just_for_server_side; - int has_out_parameters; - int isExt; -} FuncDesc; - -int isExt(FuncDesc* func) -{ - return func->isExt; -} - -char* get_type_string(char* type) -{ - if (strstr(type, "[16]")) - { - if (strstr(type, "float")) - return ("TYPE_16FLOAT"); - else if (strstr(type, "double")) - return ("TYPE_16DOUBLE"); - else - { - printf("inconnu %s\n", type); - exit(-1); - } - } - else if (strstr(type, "[128]") && strstr(type, "GLubyte")) - return strstr(type, "const") ? "TYPE_128UCHAR" : "TYPE_OUT_128UCHAR"; - else if (strstr(type, "const GLvoid *")) - return "TYPE_ARRAY_VOID"; - else if (strstr(type, "const GLchar *") || - strstr(type, "const GLcharARB *")) - return "TYPE_NULL_TERMINATED_STRING"; - else if (strstr(type, "const GLbyte *")) - return "TYPE_ARRAY_SIGNED_CHAR"; - else if (strstr(type, "const GLubyte *")) - return "TYPE_ARRAY_UNSIGNED_CHAR"; - else if (strstr(type, "const GLshort *")) - return "TYPE_ARRAY_SHORT"; - else if (strstr(type, "const GLushort *") || - strstr(type, "const GLhalfNV *")) - return "TYPE_ARRAY_UNSIGNED_SHORT"; - else if (strstr(type, "const GLint *")) - return "TYPE_ARRAY_INT"; - else if (strstr(type, "const GLuint *") || - strstr(type, "const GLenum *")) - return "TYPE_ARRAY_UNSIGNED_INT"; - else if (strstr(type, "const GLfloat *") || - strstr(type, "const GLclampf *")) - return "TYPE_ARRAY_FLOAT"; - else if (strstr(type, "const GLdouble *")) - return "TYPE_ARRAY_DOUBLE"; - else if (strstr(type, "GLvoid *")) - return "TYPE_OUT_ARRAY_VOID"; - else if (strstr(type, "GLboolean *") || - strstr(type, "GLubyte *")) - return "TYPE_OUT_ARRAY_UNSIGNED_CHAR"; - else if (strstr(type, "GLcharARB *") || - strstr(type, "GLchar *")) - return "TYPE_OUT_ARRAY_CHAR"; - else if (strstr(type, "GLshort *")) - return "TYPE_OUT_ARRAY_SHORT"; - else if (strstr(type, "GLushort *")) - return "TYPE_OUT_ARRAY_UNSIGNED_SHORT"; - else if (strstr(type, "GLint *")|| - strstr(type, "GLsizei *")) - return "TYPE_OUT_ARRAY_INT"; - else if (strstr(type, "GLuint *") || - strstr(type, "GLenum *") || - strstr(type, "GLhandleARB *")) - return "TYPE_OUT_ARRAY_UNSIGNED_INT"; - else if (strstr(type, "GLfloat *")) - return "TYPE_OUT_ARRAY_FLOAT"; - else if (strstr(type, "GLdouble *")) - return "TYPE_OUT_ARRAY_DOUBLE"; - else if (strcmp(type, "void") == 0) - return("TYPE_NONE"); - else if (strcmp(type, "GLbyte") == 0) - return("TYPE_CHAR"); - else if (strcmp(type, "GLubyte") == 0 || - strcmp(type, "GLboolean") == 0) - return("TYPE_UNSIGNED_CHAR"); - else if (strcmp(type, "GLshort") == 0) - return("TYPE_SHORT"); - else if (strcmp(type, "GLushort") == 0 || - strcmp(type, "GLhalfNV") == 0) - return("TYPE_UNSIGNED_SHORT"); - else if (strcmp(type, "GLint") == 0 || - strcmp(type, "GLsizei") == 0 || - strcmp(type, "GLintptr") == 0 || - strcmp(type, "GLsizeiptr") == 0 || - strcmp(type, "GLintptrARB") == 0 || - strcmp(type, "GLsizeiptrARB") == 0) - return("TYPE_INT"); - else if (strcmp(type, "GLenum") == 0 || - strcmp(type, "GLuint") == 0 || - strcmp(type, "GLhandleARB") == 0 || - strcmp(type, "GLbitfield") == 0) - return("TYPE_UNSIGNED_INT"); - else if (strcmp(type, "GLfloat") == 0 || - strcmp(type, "GLclampf") == 0) - return("TYPE_FLOAT"); - else if (strcmp(type, "GLdouble") == 0 || - strcmp(type, "GLclampd") == 0) - return("TYPE_DOUBLE"); - else - { - printf("inconnu %s\n", type); - exit(-1); - } -} - -typedef struct -{ - char* letter; - char* signature_type_name; - char* gl_c_type_name; - char* c_type_name; -} ForIsKnownArgVector; - -#define N_ELEMENTS(x) (sizeof(x)/sizeof(x[0])) -#define N_FIELDS_IN_ARG_VECTOR 4 - - -typedef struct -{ - char* func_name; - char* signature_type_name; -} KnownLastArgFunc; - -static KnownLastArgFunc knownLastArgFuncs[] = -{ -{"glFogCoordfv", "TYPE_1FLOAT"}, -{"glFogCoorddv", "TYPE_1DOUBLE"}, -{"glFogCoordfvEXT", "TYPE_1FLOAT"}, -{"glFogCoorddvEXT", "TYPE_1DOUBLE"}, -{"glFogCoordhvNV", "TYPE_1USHORT"}, - -{"glGetFenceivNV", "TYPE_OUT_1INT"}, - -{"glGetTexLevelParameteriv", "TYPE_OUT_1INT" }, -{"glGetTexLevelParameterfv", "TYPE_OUT_1FLOAT" }, - -{"glGetRenderbufferParameterivEXT", "TYPE_OUT_1INT"}, -{"glGetFramebufferAttachmentParameterivEXT", "TYPE_OUT_1INT"}, -{"glGetFinalCombinerInputParameterivNV", "TYPE_OUT_1INT"}, -{"glGetCombinerOutputParameterivNV", "TYPE_OUT_1INT"}, -{"glGetCombinerInputParameterivNV", "TYPE_OUT_1INT"}, -{"glGetOcclusionQueryivNV", "TYPE_OUT_1INT"}, -{"glGetOcclusionQueryuivNV", "TYPE_OUT_1UINT"}, -{"glGetObjectParameterivARB", "TYPE_OUT_1INT"}, -{"glGetQueryivARB", "TYPE_OUT_1INT"}, -{"glGetQueryiv", "TYPE_OUT_1INT"}, -{"glGetQueryObjectivARB", "TYPE_OUT_1INT"}, -{"glGetQueryObjectiv", "TYPE_OUT_1INT"}, -{"glGetQueryObjectuivARB", "TYPE_OUT_1UINT"}, -{"glGetQueryObjectuiv", "TYPE_OUT_1UINT"}, -{"glGetProgramivARB", "TYPE_OUT_1INT"}, -{"glGetProgramiv", "TYPE_OUT_1INT"}, -{"glGetProgramivNV", "TYPE_OUT_1INT"}, -{"glGetShaderiv", "TYPE_OUT_1INT"}, - -{"glCombinerParameterfvNV", "TYPE_1FLOAT"}, -{"glCombinerParameterivNV", "TYPE_1INT"}, - -{"glGetFinalCombinerInputParameterfvNV", "TYPE_OUT_1FLOAT"}, -{"glGetCombinerOutputParameterfvNV", "TYPE_OUT_1FLOAT"}, -{"glGetCombinerInputParameterfvNV", "TYPE_OUT_1FLOAT"}, -{"glGetObjectParameterfvARB", "TYPE_OUT_1FLOAT"}, - -{"glCombinerStageParameterfvNV", "TYPE_4FLOAT"}, -{"glGetCombinerStageParameterfvNV", "TYPE_OUT_4FLOAT"}, - -{"glTexBumpParameterivATI", "TYPE_1INT"}, -{"glTexBumpParameterfvATI", "TYPE_1FLOAT"}, -{"glGetTexBumpParameterivATI", "TYPE_OUT_1INT"}, -{"glGetTexBumpParameterfvATI", "TYPE_OUT_1FLOAT"}, - -{"glGetProgramLocalParameterfvARB", "TYPE_OUT_4FLOAT"}, -{"glGetProgramLocalParameterdvARB", "TYPE_OUT_4DOUBLE"}, -{"glGetProgramEnvParameterfvARB", "TYPE_OUT_4FLOAT"}, -{"glGetProgramEnvParameterdvARB", "TYPE_OUT_4DOUBLE"}, -{"glGetProgramLocalParameterIivNV", "TYPE_OUT_1INT"}, -{"glGetProgramLocalParameterIuivNV", "TYPE_OUT_1UINT"}, -{"glGetProgramEnvParameterIivNV", "TYPE_OUT_1INT"}, -{"glGetProgramEnvParameterIuivNV", "TYPE_OUT_1UINT"}, - -{"glGetProgramParameterfvNV", "TYPE_OUT_4FLOAT"}, -{"glGetProgramParameterdvNV", "TYPE_OUT_4DOUBLE"}, -{"glGetProgramNamedParameterfvNV", "TYPE_OUT_4FLOAT"}, -{"glGetProgramNamedParameterdvNV", "TYPE_OUT_4DOUBLE"}, - -{"glCullParameterfvEXT", "TYPE_4FLOAT"}, -{"glCullParameterdvEXT", "TYPE_4DOUBLE"}, - -{"glGetTrackMatrixivNV", "TYPE_OUT_1INT"}, -{"glExecuteProgramNV", "TYPE_4FLOAT"}, - -{"glEdgeFlagv", "TYPE_1UCHAR"}, - -{"glClipPlane", "TYPE_4DOUBLE"}, -{"glGetClipPlane", "TYPE_OUT_4DOUBLE"}, - -{"glSetFragmentShaderConstantATI", "TYPE_4FLOAT"}, - -{"glGetObjectBufferfvATI", "TYPE_OUT_1FLOAT"}, -{"glGetObjectBufferivATI", "TYPE_OUT_1INT"}, -{"glGetArrayObjectfvATI", "TYPE_OUT_1FLOAT"}, -{"glGetArrayObjectivATI", "TYPE_OUT_1INT"}, -{"glGetVariantArrayObjectfvATI", "TYPE_OUT_1FLOAT"}, -{"glGetVariantArrayObjectivATI", "TYPE_OUT_1INT"}, -{"glGetVertexAttribArrayObjectfvATI", "TYPE_OUT_1FLOAT"}, -{"glGetVertexAttribArrayObjectivATI", "TYPE_OUT_1INT"}, - -{"glPixelTransformParameterivEXT", "TYPE_1INT"}, -{"glPixelTransformParameterfvEXT", "TYPE_1FLOAT"}, -{"glGetPixelTransformParameterivEXT", "TYPE_OUT_1INT"}, -{"glGetPixelTransformParameterfvEXT", "TYPE_OUT_1FLOAT"}, - -{"glColorTableParameterfv", "TYPE_4FLOAT"}, -{"glColorTableParameteriv", "TYPE_4INT"}, -{"glGetColorTableParameterfv", "TYPE_OUT_4FLOAT"}, -{"glGetColorTableParameteriv", "TYPE_OUT_4INT"}, -{"glColorTableParameterfvEXT", "TYPE_4FLOAT"}, -{"glColorTableParameterivEXT", "TYPE_4INT"}, -{"glGetColorTableParameterfvEXT", "TYPE_OUT_4FLOAT"}, -{"glGetColorTableParameterivEXT", "TYPE_OUT_4INT"}, - -{"glGetMinmaxParameterfv", "TYPE_OUT_1FLOAT"}, -{"glGetMinmaxParameteriv", "TYPE_OUT_1INT"}, -{"glGetHistogramParameterfv", "TYPE_OUT_1FLOAT"}, -{"glGetHistogramParameteriv", "TYPE_OUT_1INT"}, -{"glGetMinmaxParameterfvEXT", "TYPE_OUT_1FLOAT"}, -{"glGetMinmaxParameterivEXT", "TYPE_OUT_1INT"}, -{"glGetHistogramParameterfvEXT", "TYPE_OUT_1FLOAT"}, -{"glGetHistogramParameterivEXT", "TYPE_OUT_1INT"}, - -/* Not sure at all for the 2 followingo ones ! */ -{"glGetBooleanIndexedvEXT", "TYPE_OUT_4UCHAR"}, -{"glGetIntegerIndexedvEXT", "TYPE_OUT_4INT"}, - -{"glReferencePlaneSGIX", "TYPE_4DOUBLE"}, - -{"glGetTransformFeedbackVaryingNV", "TYPE_OUT_1INT"}, - -}; - -int is_known_arg_vector(FuncDesc* desc, char** p_signature_type_name, char** p_c_type_name) -{ - static ForIsKnownArgVector my_tab[] = - { - { "b", "CHAR", "GLbyte", "signed char" }, - { "Boolean", "CHAR", "GLboolean", "unsigned char" }, - { "s", "SHORT", "GLshort", "short" }, - { "i", "INT", "GLint", "int" }, - { "Integer", "INT", "GLint", "int" }, - { "ub", "CHAR", "GLubyte", "unsigned char" }, - { "h", "SHORT", "GLhalf", "unsigned short" }, - { "us", "SHORT", "GLushort", "unsigned short" }, - { "ui", "INT", "GLuint", "unsigned int" }, - { "Nb", "CHAR", "GLbyte", "signed char" }, - { "Ns", "SHORT", "GLshort", "short" }, - { "Ni", "INT", "GLint", "int" }, - { "Nub", "CHAR", "GLubyte", "unsigned char" }, - { "Nus", "SHORT", "GLushort", "unsigned short" }, - { "Nui", "INT", "GLuint", "unsigned int" }, - - { "f", "FLOAT", "GLfloat", "float" }, - { "Float", "FLOAT", "GLfloat", "float" }, - { "d", "DOUBLE", "GLdouble", "double" }, - }; - - if (desc->nargs == 0) - return 0; - - int i , j; - - if (strstr(desc->name, "glVertexAttribs") || - strstr(desc->name, "glProgramParameters") || - strstr(desc->name, "glProgramEnvParameters") || - strstr(desc->name, "glProgramLocalParameters") || - (strstr(desc->name, "glUniform") && (strstr(desc->name, "iv") || strstr(desc->name, "fv")))) - return 0; - - static char signatures[N_ELEMENTS(my_tab)][N_FIELDS_IN_ARG_VECTOR][20] = {0}; - char signature[10]; - - for(i=0;iname, knownLastArgFuncs[i].func_name) == 0) - { - if (p_signature_type_name) - { - *p_signature_type_name = knownLastArgFuncs[i].signature_type_name; - } - if (p_c_type_name) - { - if (strstr(knownLastArgFuncs[i].signature_type_name, "FLOAT")) - *p_c_type_name = "float"; - else if (strstr(knownLastArgFuncs[i].signature_type_name, "DOUBLE")) - *p_c_type_name = "double"; - else if (strstr(knownLastArgFuncs[i].signature_type_name, "UINT")) - *p_c_type_name = "unsigned int"; - else if (strstr(knownLastArgFuncs[i].signature_type_name, "INT")) - *p_c_type_name = "int"; - else if (strstr(knownLastArgFuncs[i].signature_type_name, "USHORT")) - *p_c_type_name = "unsigned short"; - else if (strstr(knownLastArgFuncs[i].signature_type_name, "SHORT")) - *p_c_type_name = "short"; - else if (strstr(knownLastArgFuncs[i].signature_type_name, "UCHAR")) - *p_c_type_name = "unsigned char"; - else if (strstr(knownLastArgFuncs[i].signature_type_name, "CHAR")) - *p_c_type_name = "char"; - else - assert(0); - } - return 1; - } - } - - for(i=0;iname, "glIndex") && strstr(desc->name, "v")) - sprintf(signature, "%sv", my_tab[i].letter); - else - sprintf(signature, "%d%sv", j, my_tab[i].letter); - if (strstr(desc->name, signature) && - strstr(desc->args[desc->nargs - 1], my_tab[i].gl_c_type_name) && - strstr(desc->args[desc->nargs - 1], "*")) - { - if (p_signature_type_name) - { - if (signatures[i][j-1][0] == 0) - sprintf(signatures[i][j-1], "TYPE_%d%s", j, my_tab[i].signature_type_name); - *p_signature_type_name = signatures[i][j-1]; - } - if (p_c_type_name) *p_c_type_name = my_tab[i].c_type_name; - return 1; - } - } - } - return 0; -} - -static void print_server_side_argument(FILE* server_stub, int j, char* glType) -{ - const char* symbolic_type = get_type_string(glType); - if (strcmp(symbolic_type, "TYPE_CHAR") == 0) - fprintf(server_stub, "ARG_TO_CHAR(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_UNSIGNED_CHAR") == 0) - fprintf(server_stub, "ARG_TO_UNSIGNED_CHAR(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_SHORT") == 0) - fprintf(server_stub, "ARG_TO_SHORT(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_UNSIGNED_SHORT") == 0) - fprintf(server_stub, "ARG_TO_UNSIGNED_SHORT(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_INT") == 0) - fprintf(server_stub, "ARG_TO_INT(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_UNSIGNED_INT") == 0) - fprintf(server_stub, "ARG_TO_UNSIGNED_INT(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_FLOAT") == 0) - fprintf(server_stub, "ARG_TO_FLOAT(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_16FLOAT") == 0) - fprintf(server_stub, "(const float*)(args[%d])", j); - else if (strcmp(symbolic_type, "TYPE_DOUBLE") == 0) - fprintf(server_stub, "ARG_TO_DOUBLE(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_16DOUBLE") == 0) - fprintf(server_stub, "(const double*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_128UCHAR") == 0) - fprintf(server_stub, "(unsigned char*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_128UCHAR") == 0) - fprintf(server_stub, "(const unsigned char*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_NULL_TERMINATED_STRING") == 0) - fprintf(server_stub, "(const char*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_SHORT") == 0) - fprintf(server_stub, "(const short*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_UNSIGNED_SHORT") == 0) - fprintf(server_stub, "(const unsigned short*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_INT") == 0) - fprintf(server_stub, "(const int*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_UNSIGNED_INT") == 0) - fprintf(server_stub, "(const unsigned int*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_FLOAT") == 0) - fprintf(server_stub, "(const float*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_DOUBLE") == 0) - fprintf(server_stub, "(const double*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_CHAR") == 0) - fprintf(server_stub, "(const char*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_SIGNED_CHAR") == 0) - fprintf(server_stub, "(const signed char*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_VOID") == 0) - fprintf(server_stub, "(const void*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_ARRAY_UNSIGNED_CHAR") == 0) - fprintf(server_stub, "(const unsigned char*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_SHORT") == 0) - fprintf(server_stub, "(short*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_UNSIGNED_SHORT") == 0) - fprintf(server_stub, "(unsigned short*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_INT") == 0) - fprintf(server_stub, "(int*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_UNSIGNED_INT") == 0) - fprintf(server_stub, "(unsigned int*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_FLOAT") == 0) - fprintf(server_stub, "(float*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_DOUBLE") == 0) - fprintf(server_stub, "(double*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_VOID") == 0) - fprintf(server_stub, "(void*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_CHAR") == 0) - fprintf(server_stub, "(char*)(args[%d])", j); - else if ( strcmp(symbolic_type, "TYPE_OUT_ARRAY_UNSIGNED_CHAR") == 0) - fprintf(server_stub, "(unsigned char*)(args[%d])", j); - - else - { - fprintf(stderr, "Unknown : %s\n", symbolic_type); - assert(0); - } -} - -static const char* func_dealt_by_hand[500] = { NULL }; - - -static const char* ignore_func[] = -{ - "glGetPointerv", - "glRectdv", - "glRectfv", - "glRectiv", - "glRectsv", - "glMultiDrawArrays", - "glMultiDrawArraysEXT", - "glMultiDrawElements", - "glMultiDrawElementsEXT", - "glUnmapBuffer", - "glUnmapBufferARB", - "glLoadTransposeMatrixf", - "glLoadTransposeMatrixd", - "glMultTransposeMatrixf", - "glMultTransposeMatrixd", - "glLoadTransposeMatrixfARB", - "glLoadTransposeMatrixdARB", - "glMultTransposeMatrixfARB", - "glMultTransposeMatrixdARB", - - "glPixelDataRangeNV", - "glFlushPixelDataRangeNV", - "glVertexArrayRangeNV", - "glFlushVertexArrayRangeNV", - "glVertexWeightfEXT", - - "glGetBufferPointerv", - "glGetBufferPointervARB", - "glGetVertexAttribPointerv", - "glGetVertexAttribPointervARB", - "glVertexAttribPointer", - "glVertexAttribPointerARB", - "glGetVariantPointervEXT", - NULL, -}; - -void get_func_dealt_by_hand() -{ - FILE* f = fopen("../target-i386/gl_func_perso.h", "r"); - char buffer[256]; - int i = 0; - char* c; - while(fgets(buffer, 256, f)) - { - if (strstr(buffer, "MAGIC_MACRO(")) - { - func_dealt_by_hand[i] = strdup(strstr(buffer, "MAGIC_MACRO(") + strlen("MAGIC_MACRO(")); - * strstr(func_dealt_by_hand[i], ")") = 0; - c = strstr(func_dealt_by_hand[i], "_"); - if (c && c != func_dealt_by_hand[i]) *c = 0; - i ++; - } - } - fclose(f); - - int j = 0; - while(ignore_func[j]) - { - func_dealt_by_hand[i] = ignore_func[j]; - i++; - j++; - } -} - -static const char* just_for_server_side_list[] = -{ - "glEnableClientState", - "glDisableClientState", - "glPushClientAttrib", - "glPopClientAttrib", - "glPixelStorei", - "glPixelStoref", - "glClientActiveTexture", - "glClientActiveTextureARB", - "glEnableVertexAttribArray", - "glEnableVertexAttribArrayARB", - "glDisableVertexAttribArray", - "glDisableVertexAttribArrayARB", - "glDrawElementArrayATI", - "glDrawRangeElementArrayATI", - "glGenSymbolsEXT", - "glFreeObjectBufferATI", - "glUnmapObjectBufferATI", - "glLockArraysEXT", - "glUnlockArraysEXT", - "glDepthFunc", - "glFogf", - "glFogi", - "glClipPlane", - "glGetClipPlane", - -/* begin of openquartz optimization */ -#if 1 - "glMatrixMode", - "glOrtho", - "glFrustum", - "glPushMatrix", - "glPopMatrix", - "glLoadIdentity", - "glLoadMatrixd", - "glLoadMatrixf", - "glMultMatrixd", - "glMultMatrixf", - "glRotated", - "glRotatef", - "glScaled", - "glScalef", - "glTranslated", - "glTranslatef", -#endif -/* end of openquartz optimization */ - - "glGetError", - "glActiveTextureARB", - - "glViewport", - "glScissor", - - "glBindBufferARB", - "glDeleteBuffersARB", - "glGenBuffersARB", - "glBufferDataARB", - "glBufferSubDataARB", - "glGetBufferSubDataARB", - "glGetBufferParameterivARB", - "glBindBuffer", - "glDeleteBuffers", - "glGenBuffers", - "glBufferData", - "glBufferSubData", - "glGetBufferSubData", - "glGetBufferParameteriv", - - "glPushAttrib", - "glPopAttrib", - "glEnable", - "glDisable", - "glIsEnabled", - "glBindTexture", - "glBindTextureEXT", - "glFogfv", - "glFogiv", - "glBitmap", - "glGetTexImage", - "glReadPixels", - "glDrawPixels", - "glSelectBuffer", - "glFeedbackBuffer", - - "glTexImage1D", - "glTexImage2D", - "glTexImage3D", - "glTexSubImage1D", - "glTexSubImage2D", - "glTexSubImage3D", - - "glTexImage3DEXT", - "glTexSubImage1DEXT", - "glTexSubImage2DEXT", - "glTexSubImage3DEXT", - - "glGetCompressedTexImage", - "glCompressedTexImage1D", - "glCompressedTexImage2D", - "glCompressedTexImage3D", - "glCompressedTexSubImage1D", - "glCompressedTexSubImage2D", - "glCompressedTexSubImage3D", - - "glGetCompressedTexImageARB", - "glCompressedTexImage1DARB", - "glCompressedTexImage2DARB", - "glCompressedTexImage3DARB", - "glCompressedTexSubImage1DARB", - "glCompressedTexSubImage2DARB", - "glCompressedTexSubImage3DARB", - - "glCallLists", - "glNewList", - "glDeleteLists", - "glGenLists", - - "glGenTextures", - "glDeleteTextures", - "glDeleteTexturesEXT", - "glMap1f", - "glMap1d", - "glMap2f", - "glMap2d", - "glGetMapdv", - "glGetMapfv", - "glGetMapiv", - "glGetBooleanv", - "glGetIntegerv", - "glGetFloatv", - "glGetDoublev", - - "glGetPixelMapfv", - "glGetPixelMapuiv", - "glGetPixelMapusv", - "glGetProgramStringARB", - "glGetProgramStringNV", - "glArrayElement", - "glDrawArrays", - "glDrawElements", - "glDrawRangeElements", - "glDrawRangeElementsEXT", - "glGetProgramInfoLog", - "glGetTexLevelParameteriv", - "glGetInfoLogARB", - "glGetShaderInfoLog", - "glGetAttachedObjectsARB", - "glGetAttachedShaders", - "glGetActiveUniformARB", - "glGetActiveUniform", - "glGetUniformLocationARB", - "glGetUniformLocation", - "glGetUniformfvARB", - "glGetUniformfv", - "glGetUniformivARB", - "glGetUniformiv", - "glGetUniformuivEXT", - "glGetShaderSourceARB", - "glGetShaderSource", - "glGetActiveAttribARB", - "glGetActiveAttrib", - "glGetAttribLocationARB", - "glGetAttribLocation", - - "glNewObjectBufferATI", - "glUpdateObjectBufferATI", - - "glSetLocalConstantEXT", - "glSetInvariantEXT", - "glVariantbvEXT", - "glVariantsvEXT", - "glVariantivEXT", - "glVariantfvEXT", - "glVariantdvEXT", - "glVariantubvEXT", - "glVariantusvEXT", - "glVariantuivEXT", - "glGetVariantBooleanvEXT", - "glGetVariantIntegervEXT", - "glGetVariantFloatvEXT", - "glGetInvariantBooleanvEXT", - "glGetInvariantIntegervEXT", - "glGetInvariantFloatvEXT", - "glGetLocalConstantBooleanvEXT", - "glGetLocalConstantIntegervEXT", - "glGetLocalConstantFloatvEXT", - - "glMatrixIndexubvARB", - "glMatrixIndexusvARB", - "glMatrixIndexuivARB", - - "glColorTable", - "glColorSubTable", - "glGetColorTable", - "glConvolutionFilter1D", - "glConvolutionFilter2D", - "glGetConvolutionFilter", - "glSeparableFilter2D", - "glGetSeparableFilter", - "glGetHistogram", - "glGetMinmax", - "glColorTableEXT", - "glColorSubTableEXT", - "glGetColorTableEXT", - "glConvolutionFilter1DEXT", - "glConvolutionFilter2DEXT", - "glGetConvolutionFilterEXT", - "glSeparableFilter2DEXT", - "glGetSeparableFilterEXT", - "glGetHistogramEXT", - "glGetMinmaxEXT", - - "glGetTexParameterfv", - - "glGetVertexAttribivARB", - "glGetVertexAttribfvARB", - "glGetVertexAttribdvARB", - "glGetVertexAttribiv", - "glGetVertexAttribfv", - "glGetVertexAttribdv", - - "glGetDetailTexFuncSGIS", - "glGetSharpenTexFuncSGIS", - - "fake_gluBuild2DMipmaps", - - "glRenderMode", - - "glEnableVariantClientStateEXT", - "glDisableVariantClientStateEXT", - - "glGetActiveVaryingNV", - - NULL, -}; - -static int just_for_server_side_func(char* funcname) -{ - int i; - for(i=0;just_for_server_side_list[i];i++) - { - if (strcmp(just_for_server_side_list[i], funcname) == 0) - return 1; - } - return 0; -} - -int parse(FILE* f, FuncDesc* funcDesc, int funcDescCount, int ignoreEXT) -{ - char buffer[256]; - while(fgets(buffer, 256, f)) - { - - if (strncmp(buffer, "GLAPI", 5) == 0 && strstr(buffer, "APIENTRY") && strstr(buffer, "(")) - { - int i = 0; - int skip = 0; - if (func_dealt_by_hand[0] == 0) - { - get_func_dealt_by_hand(); - } - while (func_dealt_by_hand[i]) - { - if (strstr(buffer, func_dealt_by_hand[i])) - { - skip = 1; - break; - } - i++; - } - if (skip) - continue; - - char** args = malloc(15 * sizeof(char*)); - int narg = 0; - char* type = buffer + 6; - char* n = strstr(type, "GLAPIENTRY") ? strstr(type, "GLAPIENTRY") : strstr(type, "APIENTRY"); - int skip_length = strstr(type, "GLAPIENTRY") ? 11 : 9; - n[-1] = 0; - type = strdup(type); - n += skip_length; - char* fonc = n; - n = strstr(n, "("); - if (n[-1] == ' ') n[-1] = 0; - n[0] = 0; - fonc = strdup(fonc); - /*if (strstr(fonc, "glLockArraysEXT") || strstr(fonc, "glUnlockArraysEXT")) - { - } - else*/ - - - if (ignoreEXT == 1 && isExtByName(fonc)) - { - free(type); - free(fonc); - continue; - } - n++; - while(1) - { - char* virg = strstr(n, ","); - if (virg) - { - args[narg] = n; - virg[0] = 0; - args[narg] = get_arg_type(args[narg]); - narg++; - n = virg+1; - } - else - break; - } - while (strstr(n, ")") == 0) - { - fgets(buffer, 256, f); - n = buffer; - while(1) - { - char* virg = strstr(n, ","); - if (virg) - { - args[narg] = n; - virg[0] = 0; - args[narg] = get_arg_type(args[narg]); - narg++; - n = virg+1; - } - else - break; - } - } - char* par = strstr(n, ")"); - args[narg] = n; - par[0] = 0; - args[narg] = get_arg_type(args[narg]); - narg++; - - - /*printf("%s %s (", type, fonc); - for(i=0;iargs[j], "*") == NULL) - return 0; - for(i=0;i< N_ELEMENTS(argDependingOnPreviousArgTab); i++) - { - if (strstr(funcDesc->name, argDependingOnPreviousArgTab[i].str) && j == argDependingOnPreviousArgTab[i].i) - return 1; - } - return 0; -} - -static void fprintf_prototype_args(FILE* f, FuncDesc* funcDesc) -{ - int j; - if (!funcDesc->nargs) - { - fprintf(f, "void"); - return; - } - for(j=0;jnargs;j++) - { - if (j != 0) fprintf(f,", "); - if (strstr(funcDesc->args[j], "[16]")) - { - if (strstr(funcDesc->args[j], "float")) - { - fprintf(f, "const GLfloat arg_%d[16]", j); - } - else if (strstr(funcDesc->args[j], "double")) - { - fprintf(f, "const GLdouble arg_%d[16]", j); - } - else - { - exit(-1); - } - } - else if (strstr(funcDesc->args[j], "[128]") && strstr(funcDesc->args[j], "GLubyte")) - fprintf(f, (strstr(funcDesc->args[j], "const")) ? "const GLubyte* arg_%d" : "GLubyte* arg_%d", j); - else - fprintf(f, "%s arg_%d", funcDesc->args[j], j); - } -} - -int main(int argc, char* argv[]) -{ - FuncDesc funcDesc[3000]; - int funcDescCount = 0; - FILE* f; - - f = fopen("../target-i386/mesa_gl.h", "r"); - assert(f); - /*if (!f) - f = fopen("/usr/include/GL/gl.h", "r");*/ - funcDescCount = parse(f, funcDesc, 0, 1); - fclose(f); - - f = fopen("../target-i386/mesa_glext.h", "r"); - assert(f); - /*if (!f) - f = fopen("/usr/include/GL/glext.h", "r");*/ - funcDescCount = parse(f, funcDesc, funcDescCount, 0); - fclose(f); - - FILE* header = fopen("gl_func.h", "w"); - FILE* client_stub = fopen("client_stub.c", "w"); - FILE* server_stub = fopen("server_stub.c", "w"); - - fprintf(header, "/* This is a generated file. DO NOT EDIT ! */\n\n"); - fprintf(header, "#define COMPOSE(x,y) x##y\n"); - fprintf(header, "#define MAGIC_MACRO(x) COMPOSE(x,_func)\n"); - fprintf(header, "enum {\n" - "#include \"gl_func_perso.h\"\n"); - - fprintf(client_stub, "/* This is a generated file. DO NOT EDIT ! */\n\n"); - - fprintf(server_stub, "/* This is a generated file. DO NOT EDIT ! */\n\n"); - - int i; - for(i=0;i= 0) - { - j = funcDesc[i].nargs-1; - if (!is_arg_of_length_depending_on_previous_args(&funcDesc[i], j) && - strstr(funcDesc[i].args[j], "const GLchar") == NULL && - strstr(funcDesc[i].args[j], "[16]") == NULL) - { - pointer_of_unknown_size |= strstr(funcDesc[i].args[j], "*") != NULL; - pointer_of_unknown_size |= strstr(funcDesc[i].args[j], "[") != NULL; - } - } - } - } - if (pointer_of_unknown_size && funcDesc[i].nargs == 1) - { - if (strstr(funcDesc[i].name, "Matrixf") || strstr(funcDesc[i].name, "Matrixd")) - { - free(funcDesc[i].args[0]); - if (strstr(funcDesc[i].name, "Matrixf")) - funcDesc[i].args[0] = strdup("GLfloat m[16]"); - else - funcDesc[i].args[0] = strdup("GLdouble m[16]"); - pointer_of_unknown_size = 0; - } - else if (strcmp(funcDesc[i].name, "glPolygonStipple") == 0) - { - free(funcDesc[i].args[0]); - funcDesc[i].args[0] = strdup("const GLubyte mask[128]"); - pointer_of_unknown_size = 0; - } - else if (strcmp(funcDesc[i].name, "glGetPolygonStipple") == 0) - { - free(funcDesc[i].args[0]); - funcDesc[i].args[0] = strdup("GLubyte mask[128]"); - funcDesc[i].has_out_parameters = 1; - pointer_of_unknown_size = 0; - } - } - if (just_for_server_side_func(name) || pointer_of_unknown_size == 0) - { - fprintf(header, " %s_func,\n", funcDesc[i].name); - funcDesc[i].ok = 1; - if (just_for_server_side_func(name)) - funcDesc[i].just_for_server_side = 1; - for(j=0;j 0) fprintf(client_stub, ", "); - if (strstr(funcDesc[i].args[j], "*")) - { - fprintf(client_stub, "POINTER_TO_ARG(arg_%d)", j); - } - else - { - const char* symbolic_type = get_type_string(funcDesc[i].args[j]); - if (strcmp(symbolic_type, "TYPE_CHAR") == 0) - fprintf(client_stub, "CHAR_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_UNSIGNED_CHAR") == 0) - fprintf(client_stub, "UNSIGNED_CHAR_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_SHORT") == 0) - fprintf(client_stub, "SHORT_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_UNSIGNED_SHORT") == 0) - fprintf(client_stub, "UNSIGNED_SHORT_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_INT") == 0) - fprintf(client_stub, "INT_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_UNSIGNED_INT") == 0) - fprintf(client_stub, "UNSIGNED_INT_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_FLOAT") == 0) - fprintf(client_stub, "FLOAT_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_16FLOAT") == 0) - fprintf(client_stub, "POINTER_TO_ARG"); - else if (strcmp(symbolic_type, "TYPE_DOUBLE") == 0) - fprintf(client_stub, "DOUBLE_TO_ARG"); - else if ( strcmp(symbolic_type, "TYPE_16DOUBLE") == 0) - fprintf(client_stub, "POINTER_TO_ARG"); - else if ( strcmp(symbolic_type, "TYPE_128UCHAR") == 0 || strcmp(symbolic_type, "TYPE_OUT_128UCHAR") == 0) - fprintf(client_stub, "POINTER_TO_ARG"); - else - { - fprintf(stderr, "Unknown : %s\n", symbolic_type); - assert(0); - } - fprintf(client_stub, "(arg_%d)", j); - } - } - fprintf(client_stub, "};\n"); - } - - fprintf(client_stub, " do_opengl_call(%s_func, %s, %s, NULL);\n", - funcDesc[i].name, (strcmp(funcDesc[i].type, "void") == 0) ? "NULL" : "&ret", - (funcDesc[i].nargs) ? "args" : "NULL"); - - if (strcmp(funcDesc[i].type, "void") != 0) - { - fprintf(client_stub, " return ret;\n"); - } - fprintf(client_stub, "}\n\n"); - } - - fprintf(server_stub, " case %s_func:\n", funcDesc[i].name); - fprintf(server_stub, " {\n"); - - if (isExt(&funcDesc[i])) - { - fprintf(server_stub, " GET_EXT_PTR(%s, %s, (", funcDesc[i].type, funcDesc[i].name); - fprintf_prototype_args(server_stub, &funcDesc[i]); - fprintf(server_stub, "));\n"); - } - - fprintf(server_stub, " "); - - if (strcmp(funcDesc[i].type, "void") == 0) - ; - else if (strcmp(get_type_string(funcDesc[i].type), "TYPE_INT") == 0 || - strcmp(get_type_string(funcDesc[i].type), "TYPE_UNSIGNED_INT") == 0) - fprintf(server_stub, "*pret_int = "); - else if (strcmp(get_type_string(funcDesc[i].type), "TYPE_CHAR") == 0 || - strcmp(get_type_string(funcDesc[i].type), "TYPE_UNSIGNED_CHAR") == 0) - fprintf(server_stub, "*pret_char = "); - else - { - fprintf(stderr, "unknown ret type = %s\n", get_type_string(funcDesc[i].type)); - exit(-1); - } - /*if (strstr(funcDesc[i].name, "EXT")) - { - char* dup = strdup(funcDesc[i].name); - *strstr(dup, "EXT") = 0; - fprintf(server_stub, "%s(", dup); - free(dup); - } - else*/ - { - if (isExt(&funcDesc[i])) - fprintf(server_stub, "ptr_func_%s(", funcDesc[i].name); - else - fprintf(server_stub, "%s(", funcDesc[i].name); - } - char* c_type_name; - if (is_known_arg_vector(&funcDesc[i], NULL, &c_type_name)) - { - for(j=0;j -#include -#include -#include - -#include "mesa_gl.h" -#include "mesa_glext.h" - -/* #include "mesa_enums.c" */ - -int gl_lookup_enum_by_name(const char* name) -{ - FILE* f; - char buffer[256]; - char template1[256]; - char template2[256]; - int i; - sprintf(template1, "#define %s\t", name); - sprintf(template2, "#define %s ", name); - for(i=0;i<2;i++) - { - if (i == 0) - f = fopen("mesa_gl.h", "r"); - else - f = fopen("mesa_glext.h", "r"); - while(fgets(buffer, 256, f)) - { - if (strstr(buffer, template1) || strstr(buffer, template2)) - { - char* c = strstr(buffer, "0x"); - assert(c); - int ret; - ret = strtol(c, NULL, 16); - return ret; - } - } - fclose(f); - } - - return -1; -} - -typedef struct -{ - int value; - char* name; - int nb_elts; -} Token; - -int compare_func(Token* a, Token* b) -{ - return a->value - b->value; -} - -typedef struct -{ - int i; - char* str; -} Cpl; -#define CPL(x) {x, #x} - -Cpl constantsOneVal[] = -{ - CPL(GL_MAX_GENERAL_COMBINERS_NV), - CPL(GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT), - CPL(GL_MAX_VERTEX_SHADER_VARIANTS_EXT), - CPL(GL_MAX_VERTEX_SHADER_INVARIANTS_EXT), - CPL(GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT), - CPL(GL_MAX_VERTEX_SHADER_LOCALS_EXT), - CPL(GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT), - CPL(GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT), - CPL(GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT), - CPL(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT), - CPL(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT), -}; -#define NB_CONSTANTS_ONE_VAL 11 - -int main(int argc, char* argv[]) -{ - FILE* f = fopen("mesa_get.c", "r"); - char buffer[256]; - int state = 0; - char name[256]; - int count = 0; - char template[256]; - Token tokens[1000]; - int ntoken = 0; - int i; - FILE* outf = fopen("glgetv_cst.h", "w"); - - fprintf(outf, "/* This is a generated file. Do not edit !*/\n"); - fprintf(outf, "typedef struct {\n"); - fprintf(outf, " GLuint count;\n"); - fprintf(outf, " GLenum token;\n"); - fprintf(outf, " const char *name;\n"); - fprintf(outf, "} GlGetConstant ;\n"); - fprintf(outf, "static const GlGetConstant gl_get_constants[] = {\n"); - - while(fgets(buffer, 256, f)) - { - if (strstr(buffer, "_mesa_GetBooleanv")) - { - state = 1; - } - else if (state == 1) - { - if (strstr(buffer, "_mesa_GetFloatv")) - { - break; - } - else if (strstr(buffer, "case GL_")) - { - strcpy(name, strstr(buffer, "case GL_") + 5); - *strstr(name, ":") = 0; - count = 0; - strcpy(template, "params[0]"); - } - else if (strstr(buffer, template)) - { - count ++; - sprintf(template, "params[%d]", count); - } - else if (strstr(buffer, "break")) - { - if (count > 0) - { - int gl_lookup = gl_lookup_enum_by_name(name); - /* - int mesa_lookup = _mesa_lookup_enum_by_name(name); - if (mesa_lookup != -1) - { - if(mesa_lookup != gl_lookup) - { - fprintf(stderr, "wrong : %s %d %d !\n", name, mesa_lookup, gl_lookup); - exit(-1); - } - }*/ - if (gl_lookup == -1) - { - fprintf(stderr, "not found in includes : %s\n", name); - //fprintf(outf, "/* { %d, unknown value, \"%s\" },*/\n", count, name); - } - else - { - //fprintf(outf, " { %d, 0x%04X, \"%s\" },\n", count, gl_lookup, name); - tokens[ntoken].value = gl_lookup; - tokens[ntoken].nb_elts = count; - tokens[ntoken].name = strdup(name); - ntoken++; - } - /*fprintf(outf, "#ifdef %s\n", name); - fprintf(outf, " { %d, MAKE_TOKEN_NAME(%s) },\n", count, name); - fprintf(outf, "#endif\n");*/ - } - else - fprintf(stderr, "not recognized : %s\n", name); - } - } - } - - for(i=0;i #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "helper.h" #define GEN_HELPER 1 #include "helper.h" +#include "hax.h" #define PREFIX_REPZ 0x01 #define PREFIX_REPNZ 0x02 @@ -274,28 +274,16 @@ static inline void gen_op_andl_A0_ffff(void) static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0) { - TCGv tmp; - switch(ot) { case OT_BYTE: - tmp = tcg_temp_new(); - tcg_gen_ext8u_tl(tmp, t0); if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) { - tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xff); - tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp); + tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8); } else { - tcg_gen_shli_tl(tmp, tmp, 8); - tcg_gen_andi_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], ~0xff00); - tcg_gen_or_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], tmp); + tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8); } - tcg_temp_free(tmp); break; case OT_WORD: - tmp = tcg_temp_new(); - tcg_gen_ext16u_tl(tmp, t0); - tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); - tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp); - tcg_temp_free(tmp); + tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16); break; default: /* XXX this shouldn't be reached; abort? */ case OT_LONG: @@ -323,15 +311,9 @@ static inline void gen_op_mov_reg_T1(int ot, int reg) static inline void gen_op_mov_reg_A0(int size, int reg) { - TCGv tmp; - switch(size) { case 0: - tmp = tcg_temp_new(); - tcg_gen_ext16u_tl(tmp, cpu_A0); - tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); - tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp); - tcg_temp_free(tmp); + tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16); break; default: /* XXX this shouldn't be reached; abort? */ case 1: @@ -389,7 +371,7 @@ static inline void gen_op_addq_A0_im(int64_t val) tcg_gen_addi_tl(cpu_A0, cpu_A0, val); } #endif - + static void gen_add_A0_im(DisasContext *s, int val) { #ifdef TARGET_X86_64 @@ -415,9 +397,7 @@ static inline void gen_op_add_reg_im(int size, int reg, int32_t val) switch(size) { case 0: tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val); - tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0); - tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); - tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0); + tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16); break; case 1: tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val); @@ -439,9 +419,7 @@ static inline void gen_op_add_reg_T0(int size, int reg) switch(size) { case 0: tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]); - tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0); - tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); - tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0); + tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16); break; case 1: tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]); @@ -665,7 +643,7 @@ static inline void gen_string_movl_A0_EDI(DisasContext *s) } } -static inline void gen_op_movl_T0_Dshift(int ot) +static inline void gen_op_movl_T0_Dshift(int ot) { tcg_gen_ld32s_tl(cpu_T[0], cpu_env, offsetof(CPUState, df)); tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot); @@ -791,12 +769,6 @@ static inline void gen_update_cc_op(DisasContext *s) } } -extern void helper_int99(void); -void helper_opengl99(void) -{ - helper_int99(); -} - static void gen_op_update1_cc(void) { tcg_gen_discard_tl(cpu_cc_src); @@ -962,7 +934,7 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) case CC_OP_SUBW: case CC_OP_SUBL: case CC_OP_SUBQ: - + size = cc_op - CC_OP_SUBB; switch(jcc_op) { case JCC_Z: @@ -993,28 +965,28 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) switch(size) { case 0: tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80); - tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, + tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 0, l1); break; case 1: tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000); - tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, + tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 0, l1); break; #ifdef TARGET_X86_64 case 2: tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000); - tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, + tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 0, l1); break; #endif default: - tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst, + tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst, 0, l1); break; } break; - + case JCC_B: cond = inv ? TCG_COND_GEU : TCG_COND_LTU; goto fast_jcc_b; @@ -1046,7 +1018,7 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) } tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1); break; - + case JCC_L: cond = inv ? TCG_COND_GE : TCG_COND_LT; goto fast_jcc_l; @@ -1078,48 +1050,48 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) } tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1); break; - + default: goto slow_jcc; } break; - + /* some jumps are easy to compute */ case CC_OP_ADDB: case CC_OP_ADDW: case CC_OP_ADDL: case CC_OP_ADDQ: - + case CC_OP_ADCB: case CC_OP_ADCW: case CC_OP_ADCL: case CC_OP_ADCQ: - + case CC_OP_SBBB: case CC_OP_SBBW: case CC_OP_SBBL: case CC_OP_SBBQ: - + case CC_OP_LOGICB: case CC_OP_LOGICW: case CC_OP_LOGICL: case CC_OP_LOGICQ: - + case CC_OP_INCB: case CC_OP_INCW: case CC_OP_INCL: case CC_OP_INCQ: - + case CC_OP_DECB: case CC_OP_DECW: case CC_OP_DECL: case CC_OP_DECQ: - + case CC_OP_SHLB: case CC_OP_SHLW: case CC_OP_SHLL: case CC_OP_SHLQ: - + case CC_OP_SARB: case CC_OP_SARW: case CC_OP_SARL: @@ -1138,7 +1110,7 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1) default: slow_jcc: gen_setcc_slow_T0(s, jcc_op); - tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, + tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_T[0], 0, l1); break; } @@ -1430,82 +1402,96 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c) tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); } -static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, +static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, int is_right, int is_arith) { target_ulong mask; int shift_label; - TCGv t0, t1; + TCGv t0, t1, t2; - if (ot == OT_QUAD) + if (ot == OT_QUAD) { mask = 0x3f; - else + } else { mask = 0x1f; + } /* load */ - if (op1 == OR_TMP0) + if (op1 == OR_TMP0) { gen_op_ld_T0_A0(ot + s->mem_index); - else + } else { gen_op_mov_TN_reg(ot, 0, op1); + } - tcg_gen_andi_tl(cpu_T[1], cpu_T[1], mask); + t0 = tcg_temp_local_new(); + t1 = tcg_temp_local_new(); + t2 = tcg_temp_local_new(); - tcg_gen_addi_tl(cpu_tmp5, cpu_T[1], -1); + tcg_gen_andi_tl(t2, cpu_T[1], mask); if (is_right) { if (is_arith) { gen_exts(ot, cpu_T[0]); - tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5); - tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, cpu_T[0]); + tcg_gen_sar_tl(cpu_T[0], cpu_T[0], t2); } else { gen_extu(ot, cpu_T[0]); - tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5); - tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, cpu_T[0]); + tcg_gen_shr_tl(cpu_T[0], cpu_T[0], t2); } } else { - tcg_gen_shl_tl(cpu_T3, cpu_T[0], cpu_tmp5); - tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, cpu_T[0]); + tcg_gen_shl_tl(cpu_T[0], cpu_T[0], t2); } /* store */ - if (op1 == OR_TMP0) + if (op1 == OR_TMP0) { gen_op_st_T0_A0(ot + s->mem_index); - else + } else { gen_op_mov_reg_T0(ot, op1); + } /* update eflags if non zero shift */ - if (s->cc_op != CC_OP_DYNAMIC) + if (s->cc_op != CC_OP_DYNAMIC) { gen_op_set_cc_op(s->cc_op); + } - /* XXX: inefficient */ - t0 = tcg_temp_local_new(); - t1 = tcg_temp_local_new(); - - tcg_gen_mov_tl(t0, cpu_T[0]); - tcg_gen_mov_tl(t1, cpu_T3); + tcg_gen_mov_tl(t1, cpu_T[0]); shift_label = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, shift_label); + tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, shift_label); - tcg_gen_mov_tl(cpu_cc_src, t1); - tcg_gen_mov_tl(cpu_cc_dst, t0); - if (is_right) + tcg_gen_addi_tl(t2, t2, -1); + tcg_gen_mov_tl(cpu_cc_dst, t1); + + if (is_right) { + if (is_arith) { + tcg_gen_sar_tl(cpu_cc_src, t0, t2); + } else { + tcg_gen_shr_tl(cpu_cc_src, t0, t2); + } + } else { + tcg_gen_shl_tl(cpu_cc_src, t0, t2); + } + + if (is_right) { tcg_gen_movi_i32(cpu_cc_op, CC_OP_SARB + ot); - else + } else { tcg_gen_movi_i32(cpu_cc_op, CC_OP_SHLB + ot); + } gen_set_label(shift_label); s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ tcg_temp_free(t0); tcg_temp_free(t1); + tcg_temp_free(t2); } static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2, int is_right, int is_arith) { int mask; - + if (ot == OT_QUAD) mask = 0x3f; else @@ -1540,7 +1526,7 @@ static void gen_shift_rm_im(DisasContext *s, int ot, int op1, int op2, gen_op_st_T0_A0(ot + s->mem_index); else gen_op_mov_reg_T0(ot, op1); - + /* update eflags if non zero shift */ if (op2 != 0) { tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4); @@ -1560,7 +1546,7 @@ static inline void tcg_gen_lshift(TCGv ret, TCGv arg1, target_long arg2) tcg_gen_shri_tl(ret, arg1, -arg2); } -static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, +static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, int is_right) { target_ulong mask; @@ -1594,12 +1580,12 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, shifts. */ label1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, label1); - + if (ot <= OT_WORD) tcg_gen_andi_tl(cpu_tmp0, t1, (1 << (3 + ot)) - 1); else tcg_gen_mov_tl(cpu_tmp0, t1); - + gen_extu(ot, t0); tcg_gen_mov_tl(t2, t0); @@ -1624,7 +1610,7 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, } else { gen_op_mov_reg_v(ot, op1, t0); } - + /* update eflags */ if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); @@ -1643,10 +1629,10 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, } tcg_gen_andi_tl(t0, t0, CC_C); tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0); - + tcg_gen_discard_tl(cpu_cc_dst); tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS); - + gen_set_label(label2); s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ @@ -1734,7 +1720,7 @@ static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2, } /* XXX: add faster immediate = 1 case */ -static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, +static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, int is_right) { int label1; @@ -1747,7 +1733,7 @@ static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, gen_op_ld_T0_A0(ot + s->mem_index); else gen_op_mov_TN_reg(ot, 0, op1); - + if (is_right) { switch (ot) { case 0: gen_helper_rcrb(cpu_T[0], cpu_T[0], cpu_T[1]); break; @@ -1780,13 +1766,13 @@ static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp); tcg_gen_discard_tl(cpu_cc_dst); tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS); - + gen_set_label(label1); s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */ } /* XXX: add faster immediate case */ -static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, +static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, int is_right) { int label1, label2, data_bits; @@ -1820,7 +1806,7 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, shifts. */ label1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1); - + tcg_gen_addi_tl(cpu_tmp5, t2, -1); if (ot == OT_WORD) { /* Note: we implement the Intel behaviour for shift count > 16 */ @@ -1831,7 +1817,7 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, tcg_gen_ext32u_tl(t0, t0); tcg_gen_shr_tl(cpu_tmp4, t0, cpu_tmp5); - + /* only needed if count > 16, but a test would complicate */ tcg_gen_subfi_tl(cpu_tmp5, 32, t2); tcg_gen_shl_tl(cpu_tmp0, t0, cpu_tmp5); @@ -1845,7 +1831,7 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, tcg_gen_shli_tl(t1, t1, 16); tcg_gen_or_tl(t1, t1, t0); tcg_gen_ext32u_tl(t1, t1); - + tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5); tcg_gen_subfi_tl(cpu_tmp0, 32, cpu_tmp5); tcg_gen_shr_tl(cpu_tmp5, t1, cpu_tmp0); @@ -1868,13 +1854,13 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2); tcg_gen_shl_tl(t1, t1, cpu_tmp5); tcg_gen_or_tl(t0, t0, t1); - + } else { if (ot == OT_LONG) tcg_gen_ext32u_tl(t1, t1); tcg_gen_shl_tl(cpu_tmp4, t0, cpu_tmp5); - + tcg_gen_shl_tl(t0, t0, t2); tcg_gen_subfi_tl(cpu_tmp5, data_bits, t2); tcg_gen_shr_tl(t1, t1, cpu_tmp5); @@ -1890,7 +1876,7 @@ static void gen_shiftd_rm_T1_T3(DisasContext *s, int ot, int op1, } else { gen_op_mov_reg_v(ot, op1, t0); } - + /* update eflags */ if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); @@ -2289,21 +2275,6 @@ static inline int insn_const_size(unsigned int ot) return 4; } -#ifdef CONFIG_EXEC_PROFILE -/* generation of TB execution profiling */ -static inline void gen_prof_tbexec(DisasContext *s, int tb_num) -{ - tcg_gen_movi_tl(cpu_T[0], (target_ulong)((void *)s->tb + - offsetof(TranslationBlock, tbexec_count) + - sizeof (uint32_t) * (tb_num & 0x1))); - tcg_gen_ld32s_tl(cpu_T[1], cpu_T[0], 0); - tcg_gen_addi_i32(cpu_T[1], cpu_T[1], 1); - tcg_gen_st32_tl(cpu_T[1], cpu_T[0], 0); -} -#else -# define gen_prof_tbexec(s, tb_num) -#endif /* CONFIG_EXEC_PROFILE */ - static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) { TranslationBlock *tb; @@ -2314,12 +2285,10 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) /* NOTE: we handle the case where the TB spans two pages here */ if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { - /* profile TB execution, yklee 20111112 */ - gen_prof_tbexec(s, tb_num); /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); gen_jmp_im(eip); - tcg_gen_exit_tb((long)tb + tb_num); + tcg_gen_exit_tb((tcg_target_long)tb + tb_num); } else { /* jump to another page: currently not optimized */ gen_jmp_im(eip); @@ -2337,7 +2306,7 @@ static inline void gen_jcc(DisasContext *s, int b, if (s->jmp_opt) { l1 = gen_new_label(); gen_jcc1(s, cc_op, b, l1); - + gen_goto_tb(s, 0, next_eip); gen_set_label(l1); @@ -2390,17 +2359,17 @@ static void gen_setcc(DisasContext *s, int b) static inline void gen_op_movl_T0_seg(int seg_reg) { - tcg_gen_ld32u_tl(cpu_T[0], cpu_env, + tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[seg_reg].selector)); } static inline void gen_op_movl_seg_T0_vm(int seg_reg) { tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff); - tcg_gen_st32_tl(cpu_T[0], cpu_env, + tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[seg_reg].selector)); tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4); - tcg_gen_st_tl(cpu_T[0], cpu_env, + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[seg_reg].base)); } @@ -2695,37 +2664,17 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip) s->is_jmp = DISAS_TB_JUMP; } -extern int enable_gl; /* an interrupt is different from an exception because of the privilege checks */ static void gen_interrupt(DisasContext *s, int intno, target_ulong cur_eip, target_ulong next_eip) { - /* opengl patch by okdear.park */ - if (enable_gl && intno == 0x99) - { - if (s->cc_op != CC_OP_DYNAMIC) - gen_op_set_cc_op(s->cc_op); - gen_jmp_im(cur_eip); - - gen_helper_opengl99(); - //gen_helper_cpuid(); - - //gen_op_int99(); -- okdearpjs - } - /* opengl patch end */ - else { - - if (s->cc_op != CC_OP_DYNAMIC) - gen_op_set_cc_op(s->cc_op); - gen_jmp_im(cur_eip); - //gen_heler_test_interrupt(); - gen_helper_raise_interrupt(tcg_const_i32(intno), - tcg_const_i32(next_eip - cur_eip)); - s->is_jmp = DISAS_TB_JUMP; - } - - + if (s->cc_op != CC_OP_DYNAMIC) + gen_op_set_cc_op(s->cc_op); + gen_jmp_im(cur_eip); + gen_helper_raise_interrupt(tcg_const_i32(intno), + tcg_const_i32(next_eip - cur_eip)); + s->is_jmp = DISAS_TB_JUMP; } static void gen_debug(DisasContext *s, target_ulong cur_eip) @@ -2754,7 +2703,6 @@ static void gen_eob(DisasContext *s) } else if (s->tf) { gen_helper_single_step(); } else { - gen_prof_tbexec(s, 0); tcg_gen_exit_tb(0); } s->is_jmp = DISAS_TB_JUMP; @@ -3236,7 +3184,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) #endif { gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0); - tcg_gen_addi_ptr(cpu_ptr0, cpu_env, + tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32); @@ -3246,14 +3194,14 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) #ifdef TARGET_X86_64 if (s->dflag == 2) { gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0); - tcg_gen_addi_ptr(cpu_ptr0, cpu_env, + tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T[0]); } else #endif { gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0); - tcg_gen_addi_ptr(cpu_ptr0, cpu_env, + tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32); @@ -3404,13 +3352,13 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) case 0x7e: /* movd ea, mm */ #ifdef TARGET_X86_64 if (s->dflag == 2) { - tcg_gen_ld_i64(cpu_T[0], cpu_env, + tcg_gen_ld_i64(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1); } else #endif { - tcg_gen_ld32u_tl(cpu_T[0], cpu_env, + tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0))); gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1); } @@ -3418,13 +3366,13 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) case 0x17e: /* movd ea, xmm */ #ifdef TARGET_X86_64 if (s->dflag == 2) { - tcg_gen_ld_i64(cpu_T[0], cpu_env, + tcg_gen_ld_i64(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0))); gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1); } else #endif { - tcg_gen_ld32u_tl(cpu_T[0], cpu_env, + tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0))); gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1); } @@ -3543,7 +3491,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) break; case 0x050: /* movmskps */ rm = (modrm & 7) | REX_B(s); - tcg_gen_addi_ptr(cpu_ptr0, cpu_env, + tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); gen_helper_movmskps(cpu_tmp2_i32, cpu_ptr0); tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); @@ -3551,7 +3499,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) break; case 0x150: /* movmskpd */ rm = (modrm & 7) | REX_B(s); - tcg_gen_addi_ptr(cpu_ptr0, cpu_env, + tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); gen_helper_movmskpd(cpu_tmp2_i32, cpu_ptr0); tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32); @@ -4692,12 +4640,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_lcall_protected(cpu_tmp2_i32, cpu_T[1], - tcg_const_i32(dflag), + tcg_const_i32(dflag), tcg_const_i32(s->pc - pc_start)); } else { tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); gen_helper_lcall_real(cpu_tmp2_i32, cpu_T[1], - tcg_const_i32(dflag), + tcg_const_i32(dflag), tcg_const_i32(s->pc - s->cs_base)); } gen_eob(s); @@ -4923,20 +4871,23 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0); gen_extu(ot, t2); tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1); + label2 = gen_new_label(); if (mod == 3) { - label2 = gen_new_label(); gen_op_mov_reg_v(ot, R_EAX, t0); tcg_gen_br(label2); gen_set_label(label1); gen_op_mov_reg_v(ot, rm, t1); - gen_set_label(label2); } else { - tcg_gen_mov_tl(t1, t0); + /* perform no-op store cycle like physical cpu; must be + before changing accumulator to ensure idempotency if + the store faults and the instruction is restarted */ + gen_op_st_v(ot + s->mem_index, t0, a0); gen_op_mov_reg_v(ot, R_EAX, t0); + tcg_gen_br(label2); gen_set_label(label1); - /* always store */ gen_op_st_v(ot + s->mem_index, t1, a0); } + gen_set_label(label2); tcg_gen_mov_tl(cpu_cc_src, t0); tcg_gen_mov_tl(cpu_cc_dst, t2); s->cc_op = CC_OP_SUBB + ot; @@ -4961,7 +4912,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_lea_modrm(s, modrm, ®_addr, &offset_addr); gen_helper_cmpxchg16b(cpu_A0); } else -#endif +#endif { if (!(s->cpuid_features & CPUID_CX8)) goto illegal_op; @@ -5537,7 +5488,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_helper_fildl_FT0(cpu_tmp2_i32); break; case 2: - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, + tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, (s->mem_index >> 2) - 1); gen_helper_fldl_FT0(cpu_tmp1_i64); break; @@ -5576,7 +5527,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_helper_fildl_ST0(cpu_tmp2_i32); break; case 2: - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, + tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, (s->mem_index >> 2) - 1); gen_helper_fldl_ST0(cpu_tmp1_i64); break; @@ -5598,7 +5549,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; case 2: gen_helper_fisttll_ST0(cpu_tmp1_i64); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, + tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, (s->mem_index >> 2) - 1); break; case 3: @@ -5624,7 +5575,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; case 2: gen_helper_fstl_ST0(cpu_tmp1_i64); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, + tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, (s->mem_index >> 2) - 1); break; case 3: @@ -5706,13 +5657,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_helper_fpop(); break; case 0x3d: /* fildll */ - tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, + tcg_gen_qemu_ld64(cpu_tmp1_i64, cpu_A0, (s->mem_index >> 2) - 1); gen_helper_fildll_ST0(cpu_tmp1_i64); break; case 0x3f: /* fistpll */ gen_helper_fistll_ST0(cpu_tmp1_i64); - tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, + tcg_gen_qemu_st64(cpu_tmp1_i64, cpu_A0, (s->mem_index >> 2) - 1); gen_helper_fpop(); break; @@ -6100,7 +6051,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) ot = dflag ? OT_LONG : OT_WORD; gen_op_mov_TN_reg(OT_WORD, 0, R_EDX); gen_op_andl_T0_ffff(); - gen_check_io(s, ot, pc_start - s->cs_base, + gen_check_io(s, ot, pc_start - s->cs_base, SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4); if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) { gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base); @@ -6169,7 +6120,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (use_icount) gen_io_start(); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); - tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]); gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32); if (use_icount) { @@ -6212,7 +6162,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (use_icount) gen_io_start(); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); - tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]); gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32); if (use_icount) { @@ -6291,7 +6240,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_jmp_im(pc_start - s->cs_base); - gen_helper_iret_protected(tcg_const_i32(s->dflag), + gen_helper_iret_protected(tcg_const_i32(s->dflag), tcg_const_i32(s->pc - s->cs_base)); s->cc_op = CC_OP_EFLAGS; } @@ -7178,7 +7127,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; case 4: /* STGI */ if ((!(s->flags & HF_SVME_MASK) && - !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || + !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || !s->pe) goto illegal_op; if (s->cpl != 0) { @@ -7199,8 +7148,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) } break; case 6: /* SKINIT */ - if ((!(s->flags & HF_SVME_MASK) && - !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || + if ((!(s->flags & HF_SVME_MASK) && + !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT)) || !s->pe) goto illegal_op; gen_helper_skinit(); @@ -7596,7 +7545,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_lea_modrm(s, modrm, ®_addr, &offset_addr); if (op == 2) { gen_op_ld_T0_A0(OT_LONG + s->mem_index); - tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr)); + gen_helper_ldmxcsr(cpu_T[0]); } else { tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, mxcsr)); gen_op_st_T0_A0(OT_LONG + s->mem_index); @@ -7604,7 +7553,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; case 5: /* lfence */ case 6: /* mfence */ - if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE)) + if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2)) goto illegal_op; break; case 7: /* sfence / clflush */ @@ -7694,11 +7643,6 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) void optimize_flags_init(void) { -#if TCG_TARGET_REG_BITS == 32 - assert(sizeof(CCTable) == (1 << 3)); -#else - assert(sizeof(CCTable) == (1 << 4)); -#endif cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op), "cc_op"); @@ -7884,6 +7828,14 @@ static inline void gen_intermediate_code_internal(CPUState *env, pc_ptr = disas_insn(dc, pc_ptr); num_insns++; +#ifdef CONFIG_HAX + if (hax_enabled() && hax_stop_translate(env)) + { + gen_jmp_im(pc_ptr - dc->cs_base); + gen_eob(dc); + break; + } +#endif /* stop translation if indicated */ if (dc->is_jmp) break; @@ -7956,8 +7908,7 @@ void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb) gen_intermediate_code_internal(env, tb, 1); } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { int cc_op; #ifdef DEBUG_DISAS @@ -7969,8 +7920,8 @@ void gen_pc_load(CPUState *env, TranslationBlock *tb, qemu_log("0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]); } } - qemu_log("spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n", - searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base, + qemu_log("pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n", + pc_pos, gen_opc_pc[pc_pos] - tb->cs_base, (uint32_t)tb->cs_base); } #endif diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index b025b66..0667f82 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -119,7 +119,8 @@ void m68k_tcg_init(void); CPUM68KState *cpu_m68k_init(const char *cpu_model); int cpu_m68k_exec(CPUM68KState *s); void cpu_m68k_close(CPUM68KState *s); -void do_interrupt(int is_hw); +void do_interrupt(CPUState *env1); +void do_interrupt_m68k_hardirq(CPUState *env1); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ @@ -230,7 +231,7 @@ static inline int cpu_mmu_index (CPUState *env) } int cpu_m68k_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault #if defined(CONFIG_USER_ONLY) @@ -254,4 +255,16 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */ } +static inline bool cpu_has_work(CPUState *env) +{ + return env->interrupt_request & CPU_INTERRUPT_HARD; +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->pc = tb->pc; +} + #endif diff --git a/target-m68k/exec.h b/target-m68k/exec.h deleted file mode 100644 index f31e06e..0000000 --- a/target-m68k/exec.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * m68k execution defines - * - * Copyright (c) 2005-2006 CodeSourcery - * Written by Paul Brook - * - * 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 - * 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, see . - */ -#include "dyngen-exec.h" - -register struct CPUM68KState *env asm(AREG0); - -#include "cpu.h" -#include "exec-all.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif - -static inline int cpu_has_work(CPUState *env) -{ - return (env->interrupt_request & (CPU_INTERRUPT_HARD)); -} - -static inline int cpu_halted(CPUState *env) { - if (!env->halted) - return 0; - if (cpu_has_work(env)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; -} - diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 514b039..674c8e6 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -23,7 +23,6 @@ #include "config.h" #include "cpu.h" -#include "exec-all.h" #include "qemu-common.h" #include "gdbstub.h" @@ -173,7 +172,7 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) CPUM68KState *env; static int inited; - env = qemu_mallocz(sizeof(CPUM68KState)); + env = g_malloc0(sizeof(CPUM68KState)); cpu_exec_init(env); if (!inited) { inited = 1; @@ -194,7 +193,7 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model) void cpu_m68k_close(CPUM68KState *env) { - qemu_free(env); + g_free(env); } void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) @@ -345,7 +344,7 @@ void m68k_switch_sp(CPUM68KState *env) #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = EXCP_ACCESS; env->mmu.ar = address; @@ -363,7 +362,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) } int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { int prot; @@ -714,7 +713,7 @@ void HELPER(macsats)(CPUState *env, uint32_t acc) if (env->macsr & MACSR_V) { env->macsr |= MACSR_PAV0 << acc; if (env->macsr & MACSR_OMC) { - /* The result is saturated to 32 bits, despite overflow occuring + /* The result is saturated to 32 bits, despite overflow occurring at 48 bits. Seems weird, but that's what the hardware docs say. */ result = (result >> 63) ^ 0x7fffffff; diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index 0711107..2f7fe6b 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -16,20 +16,27 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "helpers.h" #if defined(CONFIG_USER_ONLY) -void do_interrupt(int is_hw) +void do_interrupt(CPUState *env1) +{ + env1->exception_index = -1; +} + +void do_interrupt_m68k_hardirq(CPUState *env1) { - env->exception_index = -1; } #else extern int semihosting_enabled; +#include "softmmu_exec.h" + #define MMUSUFFIX _mmu #define SHIFT 0 @@ -48,18 +55,17 @@ extern int semihosting_enabled; NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { TranslationBlock *tb; CPUState *saved_env; unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; - ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + env = env1; + ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ @@ -68,10 +74,10 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } @@ -90,7 +96,7 @@ static void do_rte(void) env->aregs[7] = sp + 8; } -void do_interrupt(int is_hw) +static void do_interrupt_all(int is_hw) { uint32_t sp; uint32_t fmt; @@ -118,7 +124,7 @@ void do_interrupt(int is_hw) } env->halted = 1; env->exception_index = EXCP_HLT; - cpu_loop_exit(); + cpu_loop_exit(env); return; } if (env->exception_index >= EXCP_TRAP0 @@ -155,12 +161,31 @@ void do_interrupt(int is_hw) env->pc = ldl_kernel(env->vbr + vector); } +void do_interrupt(CPUState *env1) +{ + CPUState *saved_env; + + saved_env = env; + env = env1; + do_interrupt_all(0); + env = saved_env; +} + +void do_interrupt_m68k_hardirq(CPUState *env1) +{ + CPUState *saved_env; + + saved_env = env; + env = env1; + do_interrupt_all(1); + env = saved_env; +} #endif static void raise_exception(int tt) { env->exception_index = tt; - cpu_loop_exit(); + cpu_loop_exit(env); } void HELPER(raise_exception)(uint32_t tt) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 6f72a2b..0e7f1fe 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -25,7 +25,6 @@ #include "config.h" #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "qemu-log.h" @@ -171,9 +170,6 @@ typedef void (*disas_proc)(DisasContext *, uint16_t); static void disas_##name (DisasContext *s, uint16_t insn) #endif -/* FIXME: Remove this. */ -#define gen_im32(val) tcg_const_i32(val) - /* Generate a load from the specified address. Narrow values are sign extended to full register width. */ static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign) @@ -339,7 +335,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base) if ((ext & 0x80) == 0) { /* base not suppressed */ if (IS_NULL_QREG(base)) { - base = gen_im32(offset + bd); + base = tcg_const_i32(offset + bd); bd = 0; } if (!IS_NULL_QREG(add)) { @@ -355,7 +351,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base) add = tmp; } } else { - add = gen_im32(bd); + add = tcg_const_i32(bd); } if ((ext & 3) != 0) { /* memory indirect */ @@ -536,15 +532,15 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize) case 0: /* Absolute short. */ offset = ldsw_code(s->pc); s->pc += 2; - return gen_im32(offset); + return tcg_const_i32(offset); case 1: /* Absolute long. */ offset = read_im32(s); - return gen_im32(offset); + return tcg_const_i32(offset); case 2: /* pc displacement */ offset = s->pc; offset += ldsw_code(s->pc); s->pc += 2; - return gen_im32(offset); + return tcg_const_i32(offset); case 3: /* pc index+displacement. */ return gen_lea_indexed(s, opsize, NULL_QREG); case 4: /* Immediate. */ @@ -861,7 +857,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest) (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(QREG_PC, dest); - tcg_gen_exit_tb((long)tb + n); + tcg_gen_exit_tb((tcg_target_long)tb + n); } else { gen_jmp_im(s, dest); tcg_gen_exit_tb(0); @@ -1209,16 +1205,16 @@ DISAS_INSN(arith_im) break; case 2: /* subi */ tcg_gen_mov_i32(dest, src1); - gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im)); + gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im)); tcg_gen_subi_i32(dest, dest, im); - gen_update_cc_add(dest, gen_im32(im)); + gen_update_cc_add(dest, tcg_const_i32(im)); s->cc_op = CC_OP_SUB; break; case 3: /* addi */ tcg_gen_mov_i32(dest, src1); tcg_gen_addi_i32(dest, dest, im); - gen_update_cc_add(dest, gen_im32(im)); - gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im)); + gen_update_cc_add(dest, tcg_const_i32(im)); + gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im)); s->cc_op = CC_OP_ADD; break; case 5: /* eori */ @@ -1228,7 +1224,7 @@ DISAS_INSN(arith_im) case 6: /* cmpi */ tcg_gen_mov_i32(dest, src1); tcg_gen_subi_i32(dest, dest, im); - gen_update_cc_add(dest, gen_im32(im)); + gen_update_cc_add(dest, tcg_const_i32(im)); s->cc_op = CC_OP_SUB; break; default: @@ -1324,8 +1320,8 @@ DISAS_INSN(clr) default: abort(); } - DEST_EA(insn, opsize, gen_im32(0), NULL); - gen_logic_cc(s, gen_im32(0)); + DEST_EA(insn, opsize, tcg_const_i32(0), NULL); + gen_logic_cc(s, tcg_const_i32(0)); } static TCGv gen_get_ccr(DisasContext *s) @@ -1589,7 +1585,7 @@ DISAS_INSN(jump) } if ((insn & 0x40) == 0) { /* jsr */ - gen_push(s, gen_im32(s->pc)); + gen_push(s, tcg_const_i32(s->pc)); } gen_jmp(s, tmp); } @@ -1617,7 +1613,7 @@ DISAS_INSN(addsubq) tcg_gen_addi_i32(dest, dest, val); } } else { - src2 = gen_im32(val); + src2 = tcg_const_i32(val); if (insn & 0x0100) { gen_helper_xflag_lt(QREG_CC_X, dest, src2); tcg_gen_subi_i32(dest, dest, val); @@ -1666,7 +1662,7 @@ DISAS_INSN(branch) } if (op == 1) { /* bsr */ - gen_push(s, gen_im32(s->pc)); + gen_push(s, tcg_const_i32(s->pc)); } gen_flush_cc_op(s); if (op > 1) { @@ -1757,7 +1753,7 @@ DISAS_INSN(mov3q) val = (insn >> 9) & 7; if (val == 0) val = -1; - src = gen_im32(val); + src = tcg_const_i32(val); gen_logic_cc(s, src); DEST_EA(insn, OS_LONG, src, NULL); } @@ -1883,7 +1879,7 @@ DISAS_INSN(shift_im) tmp = (insn >> 9) & 7; if (tmp == 0) tmp = 8; - shift = gen_im32(tmp); + shift = tcg_const_i32(tmp); /* No need to flush flags becuse we know we will set C flag. */ if (insn & 0x100) { gen_helper_shl_cc(reg, cpu_env, reg, shift); @@ -2191,7 +2187,7 @@ DISAS_INSN(fpu) switch ((ext >> 10) & 7) { case 4: /* FPCR */ /* Not implemented. Always return zero. */ - tmp32 = gen_im32(0); + tmp32 = tcg_const_i32(0); break; case 1: /* FPIAR */ case 2: /* FPSR */ @@ -2592,7 +2588,7 @@ DISAS_INSN(mac) /* Skip the accumulate if the value is already saturated. */ l1 = gen_new_label(); tmp = tcg_temp_new(); - gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc)); + gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc)); gen_op_jmp_nz32(tmp, l1); } #endif @@ -2626,7 +2622,7 @@ DISAS_INSN(mac) /* Skip the accumulate if the value is already saturated. */ l1 = gen_new_label(); tmp = tcg_temp_new(); - gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc)); + gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc)); gen_op_jmp_nz32(tmp, l1); } #endif @@ -3113,8 +3109,7 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result); } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->pc = gen_opc_pc[pc_pos]; } diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index 3aa28bf..3530286 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -41,6 +41,9 @@ struct CPUMBState; #define EXCP_HW_BREAK 5 #define EXCP_HW_EXCP 6 +/* MicroBlaze-specific interrupt pending bits. */ +#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3 + /* Register aliases. R0 - R15 */ #define R_SP 1 #define SR_PC 0 @@ -62,6 +65,7 @@ struct CPUMBState; #define MSR_DCE (1<<7) /* 0x080 */ #define MSR_EE (1<<8) /* 0x100 */ #define MSR_EIP (1<<9) /* 0x200 */ +#define MSR_PVR (1<<10) /* 0x400 */ #define MSR_CC (1<<31) /* Machine State Register (MSR) Fields */ @@ -79,6 +83,8 @@ struct CPUMBState; #define ESR_DIZ (1<<11) /* Zone Protection */ #define ESR_S (1<<10) /* Store instruction */ +#define ESR_ESS_FSL_OFFSET 5 + #define ESR_EC_FSL 0 #define ESR_EC_UNALIGNED_DATA 1 #define ESR_EC_ILLEGAL_OP 2 @@ -91,6 +97,7 @@ struct CPUMBState; #define ESR_EC_INSN_STORAGE 9 #define ESR_EC_DATA_TLB 10 #define ESR_EC_INSN_TLB 11 +#define ESR_EC_MASK 31 /* Floating Point Status Register (FSR) Bits */ #define FSR_IO (1<<4) /* Invalid operation */ @@ -110,6 +117,9 @@ struct CPUMBState; #define PVR0_USE_ICACHE_MASK 0x02000000 #define PVR0_USE_DCACHE_MASK 0x01000000 #define PVR0_USE_MMU 0x00800000 /* new */ +#define PVR0_USE_BTC 0x00400000 +#define PVR0_ENDI 0x00200000 +#define PVR0_FAULT 0x00100000 #define PVR0_VERSION_MASK 0x0000FF00 #define PVR0_USER1_MASK 0x000000FF @@ -169,6 +179,7 @@ struct CPUMBState; #define PVR5_DCACHE_ALLOW_WR_MASK 0x01000000 #define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000 #define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000 +#define PVR5_DCACHE_WRITEBACK_MASK 0x00004000 /* ICache base address PVR mask */ #define PVR6_ICACHE_BASEADDR_MASK 0xFFFFFFFF @@ -190,7 +201,7 @@ struct CPUMBState; #define PVR11_MMU_ITLB_SIZE 0x38000000 #define PVR11_MMU_DTLB_SIZE 0x07000000 #define PVR11_MMU_TLB_ACCESS 0x00C00000 -#define PVR11_MMU_ZONES 0x003C0000 +#define PVR11_MMU_ZONES 0x003E0000 /* MSR Reset value PVR mask */ #define PVR11_MSR_RESET_VALUE_MASK 0x000007FF @@ -207,6 +218,13 @@ struct CPUMBState; #define CC_EQ 0 #define NB_MMU_MODES 3 + +#define STREAM_EXCEPTION (1 << 0) +#define STREAM_ATOMIC (1 << 1) +#define STREAM_TEST (1 << 2) +#define STREAM_CONTROL (1 << 3) +#define STREAM_NONBLOCK (1 << 4) + typedef struct CPUMBState { uint32_t debug; uint32_t btaken; @@ -292,7 +310,7 @@ static inline int cpu_mmu_index (CPUState *env) } int cpu_mb_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault #if defined(CONFIG_USER_ONLY) @@ -330,7 +348,20 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, } #if !defined(CONFIG_USER_ONLY) -void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, - int is_asi, int size); +void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr, + int is_write, int is_exec, int is_asi, int size); #endif + +static inline bool cpu_has_work(CPUState *env) +{ + return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->sregs[SR_PC] = tb->pc; +} + #endif diff --git a/target-microblaze/exec.h b/target-microblaze/exec.h deleted file mode 100644 index 87b2494..0000000 --- a/target-microblaze/exec.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Microblaze execution defines - * - * Copyright (c) 2009 Edgar E. Iglesias - * - * 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 - * 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, see . - */ -#include "dyngen-exec.h" - -register struct CPUMBState *env asm(AREG0); - -#include "cpu.h" -#include "exec-all.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif - -static inline int cpu_has_work(CPUState *env) -{ - return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)); -} - -static inline int cpu_halted(CPUState *env) { - if (!env->halted) - return 0; - - /* IRQ, NMI and GURU execeptions wakes us up. */ - if (env->interrupt_request - & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->sregs[SR_PC] = tb->pc; -} - diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c index 5230b52..2cf2802 100644 --- a/target-microblaze/helper.c +++ b/target-microblaze/helper.c @@ -23,7 +23,6 @@ #include "config.h" #include "cpu.h" -#include "exec-all.h" #include "host-utils.h" #define D(x) @@ -38,7 +37,7 @@ void do_interrupt (CPUState *env) } int cpu_mb_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->exception_index = 0xaa; cpu_dump_state(env, stderr, fprintf, 0); @@ -48,7 +47,7 @@ int cpu_mb_handle_mmu_fault(CPUState * env, target_ulong address, int rw, #else /* !CONFIG_USER_ONLY */ int cpu_mb_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { unsigned int hit; unsigned int mmu_available; @@ -117,7 +116,7 @@ void do_interrupt(CPUState *env) { uint32_t t; - /* IMM flag cannot propagate accross a branch and into the dslot. */ + /* IMM flag cannot propagate across a branch and into the dslot. */ assert(!((env->iflags & D_FLAG) && (env->iflags & IMM_FLAG))); assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG))); /* assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions. */ diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h index 1696b88..b92aa34 100644 --- a/target-microblaze/helper.h +++ b/target-microblaze/helper.h @@ -33,4 +33,7 @@ DEF_HELPER_2(mmu_write, void, i32, i32) DEF_HELPER_4(memalign, void, i32, i32, i32, i32) +DEF_HELPER_2(get, i32, i32, i32) +DEF_HELPER_3(put, void, i32, i32, i32) + #include "def-helper.h" diff --git a/target-microblaze/microblaze-decode.h b/target-microblaze/microblaze-decode.h index 4a27476..401319e 100644 --- a/target-microblaze/microblaze-decode.h +++ b/target-microblaze/microblaze-decode.h @@ -50,3 +50,6 @@ #define DEC_BR {B8(00100110), B8(00110111)} #define DEC_BCC {B8(00100111), B8(00110111)} #define DEC_RTS {B8(00101101), B8(00111111)} + +#define DEC_STREAM {B8(00010011), B8(00110111)} + diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c index b38f7d9..281fc8d 100644 --- a/target-microblaze/mmu.c +++ b/target-microblaze/mmu.c @@ -22,7 +22,6 @@ #include "config.h" #include "cpu.h" -#include "exec-all.h" #define D(x) diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c index d75a53c..7433cec 100644 --- a/target-microblaze/op_helper.c +++ b/target-microblaze/op_helper.c @@ -18,13 +18,16 @@ */ #include -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "helper.h" #include "host-utils.h" #define D(x) #if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" + #define MMUSUFFIX _mmu #define SHIFT 0 #include "softmmu_template.h" @@ -39,19 +42,18 @@ NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { TranslationBlock *tb; CPUState *saved_env; unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; + env = env1; - ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ @@ -60,19 +62,54 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } #endif +void helper_put(uint32_t id, uint32_t ctrl, uint32_t data) +{ + int test = ctrl & STREAM_TEST; + int atomic = ctrl & STREAM_ATOMIC; + int control = ctrl & STREAM_CONTROL; + int nonblock = ctrl & STREAM_NONBLOCK; + int exception = ctrl & STREAM_EXCEPTION; + + qemu_log("Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n", + id, data, + test ? "t" : "", + nonblock ? "n" : "", + exception ? "e" : "", + control ? "c" : "", + atomic ? "a" : ""); +} + +uint32_t helper_get(uint32_t id, uint32_t ctrl) +{ + int test = ctrl & STREAM_TEST; + int atomic = ctrl & STREAM_ATOMIC; + int control = ctrl & STREAM_CONTROL; + int nonblock = ctrl & STREAM_NONBLOCK; + int exception = ctrl & STREAM_EXCEPTION; + + qemu_log("Unhandled stream get from stream-id=%d %s%s%s%s%s\n", + id, + test ? "t" : "", + nonblock ? "n" : "", + exception ? "e" : "", + control ? "c" : "", + atomic ? "a" : ""); + return 0xdead0000 | id; +} + void helper_raise_exception(uint32_t index) { env->exception_index = index; - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_debug(void) @@ -303,7 +340,7 @@ uint32_t helper_fcmp_eq(uint32_t a, uint32_t b) set_float_exception_flags(0, &env->fp_status); fa.l = a; fb.l = b; - r = float32_eq(fa.f, fb.f, &env->fp_status); + r = float32_eq_quiet(fa.f, fb.f, &env->fp_status); flags = get_float_exception_flags(&env->fp_status); update_fpu_flags(flags & float_flag_invalid); @@ -349,7 +386,7 @@ uint32_t helper_fcmp_ne(uint32_t a, uint32_t b) fa.l = a; fb.l = b; set_float_exception_flags(0, &env->fp_status); - r = !float32_eq(fa.f, fb.f, &env->fp_status); + r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status); flags = get_float_exception_flags(&env->fp_status); update_fpu_flags(flags & float_flag_invalid); @@ -453,20 +490,14 @@ void helper_mmu_write(uint32_t rn, uint32_t v) mmu_write(env, rn, v); } -void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, - int is_asi, int size) +void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr, + int is_write, int is_exec, int is_asi, int size) { CPUState *saved_env; - if (!cpu_single_env) { - /* XXX: ??? */ - return; - } - - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; + env = env1; + qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n", addr, is_write, is_exec); if (!(env->sregs[SR_MSR] & MSR_EE)) { diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 2207431..366fd3e 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -25,7 +25,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "helper.h" @@ -146,7 +145,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_SR[SR_PC], dest); - tcg_gen_exit_tb((long)tb + n); + tcg_gen_exit_tb((tcg_target_long)tb + n); } else { tcg_gen_movi_tl(cpu_SR[SR_PC], dest); tcg_gen_exit_tb(0); @@ -425,10 +424,15 @@ static inline void msr_read(DisasContext *dc, TCGv d) static inline void msr_write(DisasContext *dc, TCGv v) { + TCGv t; + + t = tcg_temp_new(); dc->cpustate_changed = 1; - tcg_gen_mov_tl(cpu_SR[SR_MSR], v); - /* PVR, we have a processor version register. */ - tcg_gen_ori_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10)); + /* PVR bit is not writable. */ + tcg_gen_andi_tl(t, v, ~MSR_PVR); + tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR); + tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], v); + tcg_temp_free(t); } static void dec_msr(DisasContext *dc) @@ -923,7 +927,7 @@ static void dec_load(DisasContext *dc) /* * When doing reverse accesses we need to do two things. * - * 1. Reverse the address wrt endianess. + * 1. Reverse the address wrt endianness. * 2. Byteswap the data lanes on the way back into the CPU core. */ if (rev && size != 4) { @@ -1476,6 +1480,42 @@ static void dec_null(DisasContext *dc) dc->abort_at_next_insn = 1; } +/* Insns connected to FSL or AXI stream attached devices. */ +static void dec_stream(DisasContext *dc) +{ + int mem_index = cpu_mmu_index(dc->env); + TCGv_i32 t_id, t_ctrl; + int ctrl; + + LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put", + dc->type_b ? "" : "d", dc->imm); + + if ((dc->tb_flags & MSR_EE_FLAG) && (mem_index == MMU_USER_IDX)) { + tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); + t_gen_raise_exception(dc, EXCP_HW_EXCP); + return; + } + + t_id = tcg_temp_new(); + if (dc->type_b) { + tcg_gen_movi_tl(t_id, dc->imm & 0xf); + ctrl = dc->imm >> 10; + } else { + tcg_gen_andi_tl(t_id, cpu_R[dc->rb], 0xf); + ctrl = dc->imm >> 5; + } + + t_ctrl = tcg_const_tl(ctrl); + + if (dc->rd == 0) { + gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]); + } else { + gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl); + } + tcg_temp_free(t_id); + tcg_temp_free(t_ctrl); +} + static struct decoder_info { struct { uint32_t bits; @@ -1500,6 +1540,7 @@ static struct decoder_info { {DEC_MUL, dec_mul}, {DEC_DIV, dec_div}, {DEC_MSR, dec_msr}, + {DEC_STREAM, dec_stream}, {{0, 0}, dec_null} }; @@ -1715,9 +1756,13 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, t_sync_flags(dc); if (unlikely(env->singlestep_enabled)) { - t_gen_raise_exception(dc, EXCP_DEBUG); - if (dc->is_jmp == DISAS_NEXT) + TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG); + + if (dc->is_jmp != DISAS_JUMP) { tcg_gen_movi_tl(cpu_SR[SR_PC], npc); + } + gen_helper_raise_exception(tmp); + tcg_temp_free_i32(tmp); } else { switch(dc->is_jmp) { case DISAS_NEXT: @@ -1806,10 +1851,11 @@ CPUState *cpu_mb_init (const char *cpu_model) static int tcg_initialized = 0; int i; - env = qemu_mallocz(sizeof(CPUState)); + env = g_malloc0(sizeof(CPUState)); cpu_exec_init(env); cpu_reset(env); + qemu_init_vcpu(env); set_float_rounding_mode(float_round_nearest_even, &env->fp_status); if (tcg_initialized) @@ -1899,8 +1945,7 @@ void cpu_reset (CPUState *env) #endif } -void gen_pc_load(CPUState *env, struct TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->sregs[SR_PC] = gen_opc_pc[pc_pos]; } diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 2419aa9..79e2558 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -1,6 +1,8 @@ #if !defined (__MIPS_CPU_H__) #define __MIPS_CPU_H__ +//#define DEBUG_OP + #define TARGET_HAS_ICE 1 #define ELF_MACHINE EM_MIPS @@ -63,7 +65,7 @@ union fpr_t { uint32_t w[2]; /* binary single fixed-point */ }; /* define FP_ENDIAN_IDX to access the same location - * in the fpr_t union regardless of the host endianess + * in the fpr_t union regardless of the host endianness */ #if defined(HOST_WORDS_BIGENDIAN) # define FP_ENDIAN_IDX 1 @@ -493,8 +495,8 @@ void r4k_helper_tlbwr (void); void r4k_helper_tlbp (void); void r4k_helper_tlbr (void); -void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, - int unused, int size); +void cpu_unassigned_access(CPUState *env, target_phys_addr_t addr, + int is_write, int is_exec, int unused, int size); #endif void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf); @@ -535,6 +537,10 @@ static inline int cpu_mips_hw_interrupts_pending(CPUState *env) if (!(env->CP0_Status & (1 << CP0St_IE)) || (env->CP0_Status & (1 << CP0St_EXL)) || (env->CP0_Status & (1 << CP0St_ERL)) || + /* Note that the TCStatus IXMT field is initialized to zero, + and only MT capable cores can set it to one. So we don't + need to check for MT capabilities here. */ + (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) || (env->hflags & MIPS_HFLAG_DM)) { /* Interrupts are disabled */ return 0; @@ -616,6 +622,14 @@ enum { /* Dummy exception for conditional stores. */ #define EXCP_SC 0x100 +/* + * This is an interrnally generated WAKE request line. + * It is driven by the CPU itself. Raised when the MT + * block wants to wake a VPE from an inactive state and + * cleared when VPE goes from active to inactive. + */ +#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 + int cpu_mips_exec(CPUMIPSState *s); CPUMIPSState *cpu_mips_init(const char *cpu_model); //~ uint32_t cpu_mips_get_clock (void); @@ -634,7 +648,7 @@ void cpu_mips_soft_irq(CPUState *env, int irq, int level); /* helper.c */ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault void do_interrupt (CPUState *env); #if !defined(CONFIG_USER_ONLY) @@ -656,4 +670,71 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls) env->tls_value = newtls; } +static inline int mips_vpe_active(CPUState *env) +{ + int active = 1; + + /* Check that the VPE is enabled. */ + if (!(env->mvp->CP0_MVPControl & (1 << CP0MVPCo_EVP))) { + active = 0; + } + /* Check that the VPE is actived. */ + if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))) { + active = 0; + } + + /* Now verify that there are active thread contexts in the VPE. + + This assumes the CPU model will internally reschedule threads + if the active one goes to sleep. If there are no threads available + the active one will be in a sleeping state, and we can turn off + the entire VPE. */ + if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) { + /* TC is not activated. */ + active = 0; + } + if (env->active_tc.CP0_TCHalt & 1) { + /* TC is in halt state. */ + active = 0; + } + + return active; +} + +static inline int cpu_has_work(CPUState *env) +{ + int has_work = 0; + + /* It is implementation dependent if non-enabled interrupts + wake-up the CPU, however most of the implementations only + check for interrupts that can be taken. */ + if ((env->interrupt_request & CPU_INTERRUPT_HARD) && + cpu_mips_hw_interrupts_pending(env)) { + has_work = 1; + } + + /* MIPS-MT has the ability to halt the CPU. */ + if (env->CP0_Config3 & (1 << CP0C3_MT)) { + /* The QEMU model will issue an _WAKE request whenever the CPUs + should be woken up. */ + if (env->interrupt_request & CPU_INTERRUPT_WAKE) { + has_work = 1; + } + + if (!mips_vpe_active(env)) { + has_work = 0; + } + } + return has_work; +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->active_tc.PC = tb->pc; + env->hflags &= ~MIPS_HFLAG_BMASK; + env->hflags |= tb->flags & MIPS_HFLAG_BMASK; +} + #endif /* !defined (__MIPS_CPU_H__) */ diff --git a/target-mips/exec.h b/target-mips/exec.h deleted file mode 100644 index 1273654..0000000 --- a/target-mips/exec.h +++ /dev/null @@ -1,98 +0,0 @@ -#if !defined(__QEMU_MIPS_EXEC_H__) -#define __QEMU_MIPS_EXEC_H__ - -//#define DEBUG_OP - -#include "config.h" -#include "mips-defs.h" -#include "dyngen-exec.h" -#include "cpu-defs.h" - -register struct CPUMIPSState *env asm(AREG0); - -#include "cpu.h" -#include "exec-all.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - -static inline int cpu_has_work(CPUState *env) -{ - int has_work = 0; - - /* It is implementation dependent if non-enabled interrupts - wake-up the CPU, however most of the implementations only - check for interrupts that can be taken. */ - if ((env->interrupt_request & CPU_INTERRUPT_HARD) && - cpu_mips_hw_interrupts_pending(env)) { - has_work = 1; - } - - if (env->interrupt_request & CPU_INTERRUPT_TIMER) { - has_work = 1; - } - - return has_work; -} - -static inline int cpu_halted(CPUState *env) -{ - if (!env->halted) - return 0; - if (cpu_has_work(env)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void compute_hflags(CPUState *env) -{ - env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | - MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | - MIPS_HFLAG_UX); - if (!(env->CP0_Status & (1 << CP0St_EXL)) && - !(env->CP0_Status & (1 << CP0St_ERL)) && - !(env->hflags & MIPS_HFLAG_DM)) { - env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU; - } -#if defined(TARGET_MIPS64) - if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) || - (env->CP0_Status & (1 << CP0St_PX)) || - (env->CP0_Status & (1 << CP0St_UX))) - env->hflags |= MIPS_HFLAG_64; - if (env->CP0_Status & (1 << CP0St_UX)) - env->hflags |= MIPS_HFLAG_UX; -#endif - if ((env->CP0_Status & (1 << CP0St_CU0)) || - !(env->hflags & MIPS_HFLAG_KSU)) - env->hflags |= MIPS_HFLAG_CP0; - if (env->CP0_Status & (1 << CP0St_CU1)) - env->hflags |= MIPS_HFLAG_FPU; - if (env->CP0_Status & (1 << CP0St_FR)) - env->hflags |= MIPS_HFLAG_F64; - if (env->insn_flags & ISA_MIPS32R2) { - if (env->active_fpu.fcr0 & (1 << FCR0_F64)) - env->hflags |= MIPS_HFLAG_COP1X; - } else if (env->insn_flags & ISA_MIPS32) { - if (env->hflags & MIPS_HFLAG_64) - env->hflags |= MIPS_HFLAG_COP1X; - } else if (env->insn_flags & ISA_MIPS4) { - /* All supported MIPS IV CPUs use the XX (CU3) to enable - and disable the MIPS IV extensions to the MIPS III ISA. - Some other MIPS IV CPUs ignore the bit, so the check here - would be too restrictive for them. */ - if (env->CP0_Status & (1 << CP0St_CU3)) - env->hflags |= MIPS_HFLAG_COP1X; - } -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->active_tc.PC = tb->pc; - env->hflags &= ~MIPS_HFLAG_BMASK; - env->hflags |= tb->flags & MIPS_HFLAG_BMASK; -} - -#endif /* !defined(__QEMU_MIPS_EXEC_H__) */ diff --git a/target-mips/helper.c b/target-mips/helper.c index bdc1e53..1c58e0c 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -24,7 +24,6 @@ #include #include "cpu.h" -#include "exec-all.h" enum { TLBRET_DIRTY = -4, @@ -267,39 +266,37 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) #endif int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { #if !defined(CONFIG_USER_ONLY) target_phys_addr_t physical; int prot; -#endif int access_type; +#endif int ret = 0; #if 0 log_cpu_state(env, 0); #endif - qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n", - __func__, env->active_tc.PC, address, rw, mmu_idx, is_softmmu); + qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n", + __func__, env->active_tc.PC, address, rw, mmu_idx); rw &= 1; /* data access */ +#if !defined(CONFIG_USER_ONLY) /* XXX: put correct access by using cpu_restore_state() correctly */ access_type = ACCESS_INT; -#if defined(CONFIG_USER_ONLY) - ret = TLBRET_NOMATCH; -#else ret = get_physical_address(env, &physical, &prot, address, rw, access_type); qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx " prot %d\n", __func__, address, ret, physical, prot); if (ret == TLBRET_MATCH) { - tlb_set_page(env, address & TARGET_PAGE_MASK, - physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, - mmu_idx, TARGET_PAGE_SIZE); - ret = 0; + tlb_set_page(env, address & TARGET_PAGE_MASK, + physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, + mmu_idx, TARGET_PAGE_SIZE); + ret = 0; } else if (ret < 0) #endif { @@ -485,18 +482,18 @@ void do_interrupt (CPUState *env) unsigned int vector; unsigned int pending = (env->CP0_Cause & CP0Ca_IP_mask) >> 8; + pending &= env->CP0_Status >> 8; /* Compute the Vector Spacing. */ spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & ((1 << 6) - 1); spacing <<= 5; if (env->CP0_Config3 & (1 << CP0C3_VInt)) { /* For VInt mode, the MIPS computes the vector internally. */ - for (vector = 0; vector < 8; vector++) { - if (pending & 1) { + for (vector = 7; vector > 0; vector--) { + if (pending & (1 << vector)) { /* Found it. */ break; } - pending >>= 1; } } else { /* For VEIC mode, the external interrupt controller feeds the diff --git a/target-mips/helper.h b/target-mips/helper.h index 297ab64..442f684 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -52,6 +52,8 @@ DEF_HELPER_2(msachiu, tl, tl, tl) DEF_HELPER_0(mfc0_mvpcontrol, tl) DEF_HELPER_0(mfc0_mvpconf0, tl) DEF_HELPER_0(mfc0_mvpconf1, tl) +DEF_HELPER_0(mftc0_vpecontrol, tl) +DEF_HELPER_0(mftc0_vpeconf0, tl) DEF_HELPER_0(mfc0_random, tl) DEF_HELPER_0(mfc0_tcstatus, tl) DEF_HELPER_0(mftc0_tcstatus, tl) @@ -70,6 +72,10 @@ DEF_HELPER_0(mftc0_tcschefback, tl) DEF_HELPER_0(mfc0_count, tl) DEF_HELPER_0(mftc0_entryhi, tl) DEF_HELPER_0(mftc0_status, tl) +DEF_HELPER_0(mftc0_cause, tl) +DEF_HELPER_0(mftc0_epc, tl) +DEF_HELPER_0(mftc0_ebase, tl) +DEF_HELPER_1(mftc0_configx, tl, tl) DEF_HELPER_0(mfc0_lladdr, tl) DEF_HELPER_1(mfc0_watchlo, tl, i32) DEF_HELPER_1(mfc0_watchhi, tl, i32) @@ -88,7 +94,9 @@ DEF_HELPER_1(dmfc0_watchlo, tl, i32) DEF_HELPER_1(mtc0_index, void, tl) DEF_HELPER_1(mtc0_mvpcontrol, void, tl) DEF_HELPER_1(mtc0_vpecontrol, void, tl) +DEF_HELPER_1(mttc0_vpecontrol, void, tl) DEF_HELPER_1(mtc0_vpeconf0, void, tl) +DEF_HELPER_1(mttc0_vpeconf0, void, tl) DEF_HELPER_1(mtc0_vpeconf1, void, tl) DEF_HELPER_1(mtc0_yqmask, void, tl) DEF_HELPER_1(mtc0_vpeopt, void, tl) @@ -127,7 +135,9 @@ DEF_HELPER_1(mttc0_status, void, tl) DEF_HELPER_1(mtc0_intctl, void, tl) DEF_HELPER_1(mtc0_srsctl, void, tl) DEF_HELPER_1(mtc0_cause, void, tl) +DEF_HELPER_1(mttc0_cause, void, tl) DEF_HELPER_1(mtc0_ebase, void, tl) +DEF_HELPER_1(mttc0_ebase, void, tl) DEF_HELPER_1(mtc0_config0, void, tl) DEF_HELPER_1(mtc0_config2, void, tl) DEF_HELPER_1(mtc0_lladdr, void, tl) diff --git a/target-mips/machine.c b/target-mips/machine.c index 9ffac71..be72b36 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -1,7 +1,7 @@ #include "hw/hw.h" #include "hw/boards.h" -#include "exec-all.h" +#include "cpu.h" static void save_tc(QEMUFile *f, TCState *tc) { diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 669faf1..c51b9cb 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -17,16 +17,70 @@ * License along with this library; if not, see . */ #include -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "host-utils.h" #include "helper.h" +#if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" +#endif /* !defined(CONFIG_USER_ONLY) */ + #ifndef CONFIG_USER_ONLY static inline void cpu_mips_tlb_flush (CPUState *env, int flush_global); #endif +static inline void compute_hflags(CPUState *env) +{ + env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | + MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | + MIPS_HFLAG_UX); + if (!(env->CP0_Status & (1 << CP0St_EXL)) && + !(env->CP0_Status & (1 << CP0St_ERL)) && + !(env->hflags & MIPS_HFLAG_DM)) { + env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU; + } +#if defined(TARGET_MIPS64) + if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) || + (env->CP0_Status & (1 << CP0St_PX)) || + (env->CP0_Status & (1 << CP0St_UX))) { + env->hflags |= MIPS_HFLAG_64; + } + if (env->CP0_Status & (1 << CP0St_UX)) { + env->hflags |= MIPS_HFLAG_UX; + } +#endif + if ((env->CP0_Status & (1 << CP0St_CU0)) || + !(env->hflags & MIPS_HFLAG_KSU)) { + env->hflags |= MIPS_HFLAG_CP0; + } + if (env->CP0_Status & (1 << CP0St_CU1)) { + env->hflags |= MIPS_HFLAG_FPU; + } + if (env->CP0_Status & (1 << CP0St_FR)) { + env->hflags |= MIPS_HFLAG_F64; + } + if (env->insn_flags & ISA_MIPS32R2) { + if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { + env->hflags |= MIPS_HFLAG_COP1X; + } + } else if (env->insn_flags & ISA_MIPS32) { + if (env->hflags & MIPS_HFLAG_64) { + env->hflags |= MIPS_HFLAG_COP1X; + } + } else if (env->insn_flags & ISA_MIPS4) { + /* All supported MIPS IV CPUs use the XX (CU3) to enable + and disable the MIPS IV extensions to the MIPS III ISA. + Some other MIPS IV CPUs ignore the bit, so the check here + would be too restrictive for them. */ + if (env->CP0_Status & (1 << CP0St_CU3)) { + env->hflags |= MIPS_HFLAG_COP1X; + } + } +} + /*****************************************************************************/ /* Exceptions processing helpers */ @@ -38,7 +92,7 @@ void helper_raise_exception_err (uint32_t exception, int error_code) #endif env->exception_index = exception; env->error_code = error_code; - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_raise_exception (uint32_t exception) @@ -54,7 +108,7 @@ static void do_restore_state (void *pc_ptr) tb = tb_find_pc (pc); if (tb) { - cpu_restore_state (tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } #endif @@ -277,7 +331,7 @@ static inline target_phys_addr_t do_translate_address(target_ulong address, int lladdr = cpu_mips_translate_address(env, address, rw); if (lladdr == -1LL) { - cpu_loop_exit(); + cpu_loop_exit(env); } else { return lladdr; } @@ -695,6 +749,163 @@ void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx) #endif #ifndef CONFIG_USER_ONLY +/* SMP helpers. */ +static int mips_vpe_is_wfi(CPUState *c) +{ + /* If the VPE is halted but otherwise active, it means it's waiting for + an interrupt. */ + return c->halted && mips_vpe_active(c); +} + +static inline void mips_vpe_wake(CPUState *c) +{ + /* Dont set ->halted = 0 directly, let it be done via cpu_has_work + because there might be other conditions that state that c should + be sleeping. */ + cpu_interrupt(c, CPU_INTERRUPT_WAKE); +} + +static inline void mips_vpe_sleep(CPUState *c) +{ + /* The VPE was shut off, really go to bed. + Reset any old _WAKE requests. */ + c->halted = 1; + cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE); +} + +static inline void mips_tc_wake(CPUState *c, int tc) +{ + /* FIXME: TC reschedule. */ + if (mips_vpe_active(c) && !mips_vpe_is_wfi(c)) { + mips_vpe_wake(c); + } +} + +static inline void mips_tc_sleep(CPUState *c, int tc) +{ + /* FIXME: TC reschedule. */ + if (!mips_vpe_active(c)) { + mips_vpe_sleep(c); + } +} + +/* tc should point to an int with the value of the global TC index. + This function will transform it into a local index within the + returned CPUState. + + FIXME: This code assumes that all VPEs have the same number of TCs, + which depends on runtime setup. Can probably be fixed by + walking the list of CPUStates. */ +static CPUState *mips_cpu_map_tc(int *tc) +{ + CPUState *other; + int vpe_idx, nr_threads = env->nr_threads; + int tc_idx = *tc; + + if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) { + /* Not allowed to address other CPUs. */ + *tc = env->current_tc; + return env; + } + + vpe_idx = tc_idx / nr_threads; + *tc = tc_idx % nr_threads; + other = qemu_get_cpu(vpe_idx); + return other ? other : env; +} + +/* The per VPE CP0_Status register shares some fields with the per TC + CP0_TCStatus registers. These fields are wired to the same registers, + so changes to either of them should be reflected on both registers. + + Also, EntryHi shares the bottom 8 bit ASID with TCStauts. + + These helper call synchronizes the regs for a given cpu. */ + +/* Called for updates to CP0_Status. */ +static void sync_c0_status(CPUState *cpu, int tc) +{ + int32_t tcstatus, *tcst; + uint32_t v = cpu->CP0_Status; + uint32_t cu, mx, asid, ksu; + uint32_t mask = ((1 << CP0TCSt_TCU3) + | (1 << CP0TCSt_TCU2) + | (1 << CP0TCSt_TCU1) + | (1 << CP0TCSt_TCU0) + | (1 << CP0TCSt_TMX) + | (3 << CP0TCSt_TKSU) + | (0xff << CP0TCSt_TASID)); + + cu = (v >> CP0St_CU0) & 0xf; + mx = (v >> CP0St_MX) & 0x1; + ksu = (v >> CP0St_KSU) & 0x3; + asid = env->CP0_EntryHi & 0xff; + + tcstatus = cu << CP0TCSt_TCU0; + tcstatus |= mx << CP0TCSt_TMX; + tcstatus |= ksu << CP0TCSt_TKSU; + tcstatus |= asid; + + if (tc == cpu->current_tc) { + tcst = &cpu->active_tc.CP0_TCStatus; + } else { + tcst = &cpu->tcs[tc].CP0_TCStatus; + } + + *tcst &= ~mask; + *tcst |= tcstatus; + compute_hflags(cpu); +} + +/* Called for updates to CP0_TCStatus. */ +static void sync_c0_tcstatus(CPUState *cpu, int tc, target_ulong v) +{ + uint32_t status; + uint32_t tcu, tmx, tasid, tksu; + uint32_t mask = ((1 << CP0St_CU3) + | (1 << CP0St_CU2) + | (1 << CP0St_CU1) + | (1 << CP0St_CU0) + | (1 << CP0St_MX) + | (3 << CP0St_KSU)); + + tcu = (v >> CP0TCSt_TCU0) & 0xf; + tmx = (v >> CP0TCSt_TMX) & 0x1; + tasid = v & 0xff; + tksu = (v >> CP0TCSt_TKSU) & 0x3; + + status = tcu << CP0St_CU0; + status |= tmx << CP0St_MX; + status |= tksu << CP0St_KSU; + + cpu->CP0_Status &= ~mask; + cpu->CP0_Status |= status; + + /* Sync the TASID with EntryHi. */ + cpu->CP0_EntryHi &= ~0xff; + cpu->CP0_EntryHi = tasid; + + compute_hflags(cpu); +} + +/* Called for updates to CP0_EntryHi. */ +static void sync_c0_entryhi(CPUState *cpu, int tc) +{ + int32_t *tcst; + uint32_t asid, v = cpu->CP0_EntryHi; + + asid = v & 0xff; + + if (tc == cpu->current_tc) { + tcst = &cpu->active_tc.CP0_TCStatus; + } else { + tcst = &cpu->tcs[tc].CP0_TCStatus; + } + + *tcst &= ~0xff; + *tcst |= asid; +} + /* CP0 helpers */ target_ulong helper_mfc0_mvpcontrol (void) { @@ -724,11 +935,12 @@ target_ulong helper_mfc0_tcstatus (void) target_ulong helper_mftc0_tcstatus(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.CP0_TCStatus; + if (other_tc == other->current_tc) + return other->active_tc.CP0_TCStatus; else - return env->tcs[other_tc].CP0_TCStatus; + return other->tcs[other_tc].CP0_TCStatus; } target_ulong helper_mfc0_tcbind (void) @@ -739,11 +951,12 @@ target_ulong helper_mfc0_tcbind (void) target_ulong helper_mftc0_tcbind(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.CP0_TCBind; + if (other_tc == other->current_tc) + return other->active_tc.CP0_TCBind; else - return env->tcs[other_tc].CP0_TCBind; + return other->tcs[other_tc].CP0_TCBind; } target_ulong helper_mfc0_tcrestart (void) @@ -754,11 +967,12 @@ target_ulong helper_mfc0_tcrestart (void) target_ulong helper_mftc0_tcrestart(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.PC; + if (other_tc == other->current_tc) + return other->active_tc.PC; else - return env->tcs[other_tc].PC; + return other->tcs[other_tc].PC; } target_ulong helper_mfc0_tchalt (void) @@ -769,11 +983,12 @@ target_ulong helper_mfc0_tchalt (void) target_ulong helper_mftc0_tchalt(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.CP0_TCHalt; + if (other_tc == other->current_tc) + return other->active_tc.CP0_TCHalt; else - return env->tcs[other_tc].CP0_TCHalt; + return other->tcs[other_tc].CP0_TCHalt; } target_ulong helper_mfc0_tccontext (void) @@ -784,11 +999,12 @@ target_ulong helper_mfc0_tccontext (void) target_ulong helper_mftc0_tccontext(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.CP0_TCContext; + if (other_tc == other->current_tc) + return other->active_tc.CP0_TCContext; else - return env->tcs[other_tc].CP0_TCContext; + return other->tcs[other_tc].CP0_TCContext; } target_ulong helper_mfc0_tcschedule (void) @@ -799,11 +1015,12 @@ target_ulong helper_mfc0_tcschedule (void) target_ulong helper_mftc0_tcschedule(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.CP0_TCSchedule; + if (other_tc == other->current_tc) + return other->active_tc.CP0_TCSchedule; else - return env->tcs[other_tc].CP0_TCSchedule; + return other->tcs[other_tc].CP0_TCSchedule; } target_ulong helper_mfc0_tcschefback (void) @@ -814,11 +1031,12 @@ target_ulong helper_mfc0_tcschefback (void) target_ulong helper_mftc0_tcschefback(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.CP0_TCScheFBack; + if (other_tc == other->current_tc) + return other->active_tc.CP0_TCScheFBack; else - return env->tcs[other_tc].CP0_TCScheFBack; + return other->tcs[other_tc].CP0_TCScheFBack; } target_ulong helper_mfc0_count (void) @@ -829,33 +1047,32 @@ target_ulong helper_mfc0_count (void) target_ulong helper_mftc0_entryhi(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - int32_t tcstatus; + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - tcstatus = env->active_tc.CP0_TCStatus; - else - tcstatus = env->tcs[other_tc].CP0_TCStatus; - - return (env->CP0_EntryHi & ~0xff) | (tcstatus & 0xff); + return other->CP0_EntryHi; } -target_ulong helper_mftc0_status(void) +target_ulong helper_mftc0_cause(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - target_ulong t0; - int32_t tcstatus; + int32_t tccause; + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - tcstatus = env->active_tc.CP0_TCStatus; - else - tcstatus = env->tcs[other_tc].CP0_TCStatus; + if (other_tc == other->current_tc) { + tccause = other->CP0_Cause; + } else { + tccause = other->CP0_Cause; + } - t0 = env->CP0_Status & ~0xf1000018; - t0 |= tcstatus & (0xf << CP0TCSt_TCU0); - t0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX); - t0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU); + return tccause; +} - return t0; +target_ulong helper_mftc0_status(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + + return other->CP0_Status; } target_ulong helper_mfc0_lladdr (void) @@ -886,14 +1103,15 @@ target_ulong helper_mftc0_debug(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); int32_t tcstatus; + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - tcstatus = env->active_tc.CP0_Debug_tcstatus; + if (other_tc == other->current_tc) + tcstatus = other->active_tc.CP0_Debug_tcstatus; else - tcstatus = env->tcs[other_tc].CP0_Debug_tcstatus; + tcstatus = other->tcs[other_tc].CP0_Debug_tcstatus; /* XXX: Might be wrong, check with EJTAG spec. */ - return (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | + return (other->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); } @@ -980,6 +1198,38 @@ void helper_mtc0_vpecontrol (target_ulong arg1) env->CP0_VPEControl = newval; } +void helper_mttc0_vpecontrol(target_ulong arg1) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + uint32_t mask; + uint32_t newval; + + mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) | + (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC); + newval = (other->CP0_VPEControl & ~mask) | (arg1 & mask); + + /* TODO: Enable/disable TCs. */ + + other->CP0_VPEControl = newval; +} + +target_ulong helper_mftc0_vpecontrol(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + /* FIXME: Mask away return zero on read bits. */ + return other->CP0_VPEControl; +} + +target_ulong helper_mftc0_vpeconf0(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + + return other->CP0_VPEConf0; +} + void helper_mtc0_vpeconf0 (target_ulong arg1) { uint32_t mask = 0; @@ -997,6 +1247,20 @@ void helper_mtc0_vpeconf0 (target_ulong arg1) env->CP0_VPEConf0 = newval; } +void helper_mttc0_vpeconf0(target_ulong arg1) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + uint32_t mask = 0; + uint32_t newval; + + mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); + newval = (other->CP0_VPEConf0 & ~mask) | (arg1 & mask); + + /* TODO: TC exclusive handling due to ERL/EXL. */ + other->CP0_VPEConf0 = newval; +} + void helper_mtc0_vpeconf1 (target_ulong arg1) { uint32_t mask = 0; @@ -1040,21 +1304,20 @@ void helper_mtc0_tcstatus (target_ulong arg1) newval = (env->active_tc.CP0_TCStatus & ~mask) | (arg1 & mask); - // TODO: Sync with CP0_Status. - env->active_tc.CP0_TCStatus = newval; + sync_c0_tcstatus(env, env->current_tc, newval); } void helper_mttc0_tcstatus (target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - // TODO: Sync with CP0_Status. - - if (other_tc == env->current_tc) - env->active_tc.CP0_TCStatus = arg1; + if (other_tc == other->current_tc) + other->active_tc.CP0_TCStatus = arg1; else - env->tcs[other_tc].CP0_TCStatus = arg1; + other->tcs[other_tc].CP0_TCStatus = arg1; + sync_c0_tcstatus(other, other_tc, arg1); } void helper_mtc0_tcbind (target_ulong arg1) @@ -1073,15 +1336,16 @@ void helper_mttc0_tcbind (target_ulong arg1) int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); uint32_t mask = (1 << CP0TCBd_TBE); uint32_t newval; + CPUState *other = mips_cpu_map_tc(&other_tc); - if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) + if (other->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) mask |= (1 << CP0TCBd_CurVPE); - if (other_tc == env->current_tc) { - newval = (env->active_tc.CP0_TCBind & ~mask) | (arg1 & mask); - env->active_tc.CP0_TCBind = newval; + if (other_tc == other->current_tc) { + newval = (other->active_tc.CP0_TCBind & ~mask) | (arg1 & mask); + other->active_tc.CP0_TCBind = newval; } else { - newval = (env->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask); - env->tcs[other_tc].CP0_TCBind = newval; + newval = (other->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask); + other->tcs[other_tc].CP0_TCBind = newval; } } @@ -1096,16 +1360,17 @@ void helper_mtc0_tcrestart (target_ulong arg1) void helper_mttc0_tcrestart (target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) { - env->active_tc.PC = arg1; - env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS); - env->lladdr = 0ULL; + if (other_tc == other->current_tc) { + other->active_tc.PC = arg1; + other->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS); + other->lladdr = 0ULL; /* MIPS16 not implemented. */ } else { - env->tcs[other_tc].PC = arg1; - env->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS); - env->lladdr = 0ULL; + other->tcs[other_tc].PC = arg1; + other->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS); + other->lladdr = 0ULL; /* MIPS16 not implemented. */ } } @@ -1115,18 +1380,30 @@ void helper_mtc0_tchalt (target_ulong arg1) env->active_tc.CP0_TCHalt = arg1 & 0x1; // TODO: Halt TC / Restart (if allocated+active) TC. + if (env->active_tc.CP0_TCHalt & 1) { + mips_tc_sleep(env, env->current_tc); + } else { + mips_tc_wake(env, env->current_tc); + } } void helper_mttc0_tchalt (target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); // TODO: Halt TC / Restart (if allocated+active) TC. - if (other_tc == env->current_tc) - env->active_tc.CP0_TCHalt = arg1; + if (other_tc == other->current_tc) + other->active_tc.CP0_TCHalt = arg1; else - env->tcs[other_tc].CP0_TCHalt = arg1; + other->tcs[other_tc].CP0_TCHalt = arg1; + + if (arg1 & 1) { + mips_tc_sleep(other, other_tc); + } else { + mips_tc_wake(other, other_tc); + } } void helper_mtc0_tccontext (target_ulong arg1) @@ -1137,11 +1414,12 @@ void helper_mtc0_tccontext (target_ulong arg1) void helper_mttc0_tccontext (target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.CP0_TCContext = arg1; + if (other_tc == other->current_tc) + other->active_tc.CP0_TCContext = arg1; else - env->tcs[other_tc].CP0_TCContext = arg1; + other->tcs[other_tc].CP0_TCContext = arg1; } void helper_mtc0_tcschedule (target_ulong arg1) @@ -1152,11 +1430,12 @@ void helper_mtc0_tcschedule (target_ulong arg1) void helper_mttc0_tcschedule (target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.CP0_TCSchedule = arg1; + if (other_tc == other->current_tc) + other->active_tc.CP0_TCSchedule = arg1; else - env->tcs[other_tc].CP0_TCSchedule = arg1; + other->tcs[other_tc].CP0_TCSchedule = arg1; } void helper_mtc0_tcschefback (target_ulong arg1) @@ -1167,11 +1446,12 @@ void helper_mtc0_tcschefback (target_ulong arg1) void helper_mttc0_tcschefback (target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.CP0_TCScheFBack = arg1; + if (other_tc == other->current_tc) + other->active_tc.CP0_TCScheFBack = arg1; else - env->tcs[other_tc].CP0_TCScheFBack = arg1; + other->tcs[other_tc].CP0_TCScheFBack = arg1; } void helper_mtc0_entrylo1 (target_ulong arg1) @@ -1252,8 +1532,7 @@ void helper_mtc0_entryhi (target_ulong arg1) old = env->CP0_EntryHi; env->CP0_EntryHi = val; if (env->CP0_Config3 & (1 << CP0C3_MT)) { - uint32_t tcst = env->active_tc.CP0_TCStatus & ~0xff; - env->active_tc.CP0_TCStatus = tcst | (val & 0xff); + sync_c0_entryhi(env, env->current_tc); } /* If the ASID changes, flush qemu's TLB. */ if ((old & 0xFF) != (val & 0xFF)) @@ -1263,16 +1542,10 @@ void helper_mtc0_entryhi (target_ulong arg1) void helper_mttc0_entryhi(target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - int32_t tcstatus; + CPUState *other = mips_cpu_map_tc(&other_tc); - env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (arg1 & ~0xff); - if (other_tc == env->current_tc) { - tcstatus = (env->active_tc.CP0_TCStatus & ~0xff) | (arg1 & 0xff); - env->active_tc.CP0_TCStatus = tcstatus; - } else { - tcstatus = (env->tcs[other_tc].CP0_TCStatus & ~0xff) | (arg1 & 0xff); - env->tcs[other_tc].CP0_TCStatus = tcstatus; - } + other->CP0_EntryHi = arg1; + sync_c0_entryhi(other, other_tc); } void helper_mtc0_compare (target_ulong arg1) @@ -1288,7 +1561,12 @@ void helper_mtc0_status (target_ulong arg1) val = arg1 & mask; old = env->CP0_Status; env->CP0_Status = (env->CP0_Status & ~mask) | val; - compute_hflags(env); + if (env->CP0_Config3 & (1 << CP0C3_MT)) { + sync_c0_status(env, env->current_tc); + } else { + compute_hflags(env); + } + if (qemu_loglevel_mask(CPU_LOG_EXEC)) { qemu_log("Status %08x (%08x) => %08x (%08x) Cause %08x", old, old & env->CP0_Cause & CP0Ca_IP_mask, @@ -1306,22 +1584,16 @@ void helper_mtc0_status (target_ulong arg1) void helper_mttc0_status(target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - int32_t tcstatus = env->tcs[other_tc].CP0_TCStatus; - - env->CP0_Status = arg1 & ~0xf1000018; - tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (arg1 & (0xf << CP0St_CU0)); - tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((arg1 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); - tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((arg1 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); - if (other_tc == env->current_tc) - env->active_tc.CP0_TCStatus = tcstatus; - else - env->tcs[other_tc].CP0_TCStatus = tcstatus; + CPUState *other = mips_cpu_map_tc(&other_tc); + + other->CP0_Status = arg1 & ~0xf1000018; + sync_c0_status(other, other_tc); } void helper_mtc0_intctl (target_ulong arg1) { /* vectored interrupts not implemented, no performance counters. */ - env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (arg1 & 0x000002e0); + env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0); } void helper_mtc0_srsctl (target_ulong arg1) @@ -1330,38 +1602,95 @@ void helper_mtc0_srsctl (target_ulong arg1) env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (arg1 & mask); } -void helper_mtc0_cause (target_ulong arg1) +static void mtc0_cause(CPUState *cpu, target_ulong arg1) { uint32_t mask = 0x00C00300; - uint32_t old = env->CP0_Cause; + uint32_t old = cpu->CP0_Cause; int i; - if (env->insn_flags & ISA_MIPS32R2) + if (cpu->insn_flags & ISA_MIPS32R2) { mask |= 1 << CP0Ca_DC; + } - env->CP0_Cause = (env->CP0_Cause & ~mask) | (arg1 & mask); + cpu->CP0_Cause = (cpu->CP0_Cause & ~mask) | (arg1 & mask); - if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) { - if (env->CP0_Cause & (1 << CP0Ca_DC)) - cpu_mips_stop_count(env); - else - cpu_mips_start_count(env); + if ((old ^ cpu->CP0_Cause) & (1 << CP0Ca_DC)) { + if (cpu->CP0_Cause & (1 << CP0Ca_DC)) { + cpu_mips_stop_count(cpu); + } else { + cpu_mips_start_count(cpu); + } } /* Set/reset software interrupts */ for (i = 0 ; i < 2 ; i++) { - if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) { - cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i))); + if ((old ^ cpu->CP0_Cause) & (1 << (CP0Ca_IP + i))) { + cpu_mips_soft_irq(cpu, i, cpu->CP0_Cause & (1 << (CP0Ca_IP + i))); } } } +void helper_mtc0_cause(target_ulong arg1) +{ + mtc0_cause(env, arg1); +} + +void helper_mttc0_cause(target_ulong arg1) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + + mtc0_cause(other, arg1); +} + +target_ulong helper_mftc0_epc(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + + return other->CP0_EPC; +} + +target_ulong helper_mftc0_ebase(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + + return other->CP0_EBase; +} + void helper_mtc0_ebase (target_ulong arg1) { /* vectored interrupts not implemented */ env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000); } +void helper_mttc0_ebase(target_ulong arg1) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + other->CP0_EBase = (other->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000); +} + +target_ulong helper_mftc0_configx(target_ulong idx) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); + + switch (idx) { + case 0: return other->CP0_Config0; + case 1: return other->CP0_Config1; + case 2: return other->CP0_Config2; + case 3: return other->CP0_Config3; + /* 4 and 5 are reserved. */ + case 6: return other->CP0_Config6; + case 7: return other->CP0_Config7; + default: + break; + } + return 0; +} + void helper_mtc0_config0 (target_ulong arg1) { env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (arg1 & 0x00000007); @@ -1417,13 +1746,15 @@ void helper_mttc0_debug(target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); uint32_t val = arg1 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); + CPUState *other = mips_cpu_map_tc(&other_tc); /* XXX: Might be wrong, check with EJTAG spec. */ - if (other_tc == env->current_tc) - env->active_tc.CP0_Debug_tcstatus = val; + if (other_tc == other->current_tc) + other->active_tc.CP0_Debug_tcstatus = val; else - env->tcs[other_tc].CP0_Debug_tcstatus = val; - env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | + other->tcs[other_tc].CP0_Debug_tcstatus = val; + other->CP0_Debug = (other->CP0_Debug & + ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | (arg1 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); } @@ -1456,101 +1787,111 @@ void helper_mtc0_datahi (target_ulong arg1) target_ulong helper_mftgpr(uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.gpr[sel]; + if (other_tc == other->current_tc) + return other->active_tc.gpr[sel]; else - return env->tcs[other_tc].gpr[sel]; + return other->tcs[other_tc].gpr[sel]; } target_ulong helper_mftlo(uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.LO[sel]; + if (other_tc == other->current_tc) + return other->active_tc.LO[sel]; else - return env->tcs[other_tc].LO[sel]; + return other->tcs[other_tc].LO[sel]; } target_ulong helper_mfthi(uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.HI[sel]; + if (other_tc == other->current_tc) + return other->active_tc.HI[sel]; else - return env->tcs[other_tc].HI[sel]; + return other->tcs[other_tc].HI[sel]; } target_ulong helper_mftacx(uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.ACX[sel]; + if (other_tc == other->current_tc) + return other->active_tc.ACX[sel]; else - return env->tcs[other_tc].ACX[sel]; + return other->tcs[other_tc].ACX[sel]; } target_ulong helper_mftdsp(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - return env->active_tc.DSPControl; + if (other_tc == other->current_tc) + return other->active_tc.DSPControl; else - return env->tcs[other_tc].DSPControl; + return other->tcs[other_tc].DSPControl; } void helper_mttgpr(target_ulong arg1, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.gpr[sel] = arg1; + if (other_tc == other->current_tc) + other->active_tc.gpr[sel] = arg1; else - env->tcs[other_tc].gpr[sel] = arg1; + other->tcs[other_tc].gpr[sel] = arg1; } void helper_mttlo(target_ulong arg1, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.LO[sel] = arg1; + if (other_tc == other->current_tc) + other->active_tc.LO[sel] = arg1; else - env->tcs[other_tc].LO[sel] = arg1; + other->tcs[other_tc].LO[sel] = arg1; } void helper_mtthi(target_ulong arg1, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.HI[sel] = arg1; + if (other_tc == other->current_tc) + other->active_tc.HI[sel] = arg1; else - env->tcs[other_tc].HI[sel] = arg1; + other->tcs[other_tc].HI[sel] = arg1; } void helper_mttacx(target_ulong arg1, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.ACX[sel] = arg1; + if (other_tc == other->current_tc) + other->active_tc.ACX[sel] = arg1; else - env->tcs[other_tc].ACX[sel] = arg1; + other->tcs[other_tc].ACX[sel] = arg1; } void helper_mttdsp(target_ulong arg1) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + CPUState *other = mips_cpu_map_tc(&other_tc); - if (other_tc == env->current_tc) - env->active_tc.DSPControl = arg1; + if (other_tc == other->current_tc) + other->active_tc.DSPControl = arg1; else - env->tcs[other_tc].DSPControl = arg1; + other->tcs[other_tc].DSPControl = arg1; } /* MIPS MT functions */ @@ -1568,14 +1909,36 @@ target_ulong helper_emt(void) target_ulong helper_dvpe(void) { - // TODO - return 0; + CPUState *other_cpu = first_cpu; + target_ulong prev = env->mvp->CP0_MVPControl; + + do { + /* Turn off all VPEs except the one executing the dvpe. */ + if (other_cpu != env) { + other_cpu->mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP); + mips_vpe_sleep(other_cpu); + } + other_cpu = other_cpu->next_cpu; + } while (other_cpu); + return prev; } target_ulong helper_evpe(void) { - // TODO - return 0; + CPUState *other_cpu = first_cpu; + target_ulong prev = env->mvp->CP0_MVPControl; + + do { + if (other_cpu != env + /* If the VPE is WFI, dont distrub it's sleep. */ + && !mips_vpe_is_wfi(other_cpu)) { + /* Enable the VPE. */ + other_cpu->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); + mips_vpe_wake(other_cpu); /* And wake it up. */ + } + other_cpu = other_cpu->next_cpu; + } while (other_cpu); + return prev; } #endif /* !CONFIG_USER_ONLY */ @@ -1923,6 +2286,7 @@ void helper_pmon (int function) void helper_wait (void) { env->halted = 1; + cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE); helper_raise_exception(EXCP_HLT); } @@ -1952,18 +2316,17 @@ static void do_unaligned_access (target_ulong addr, int is_write, int is_user, v helper_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL); } -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { TranslationBlock *tb; CPUState *saved_env; unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; - ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + env = env1; + ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx); if (ret) { if (retaddr) { /* now we have a real cpu fault */ @@ -1972,7 +2335,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } helper_raise_exception_err(env->exception_index, env->error_code); @@ -1980,9 +2343,11 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) env = saved_env; } -void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, - int unused, int size) +void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr, + int is_write, int is_exec, int unused, int size) { + env = env1; + if (is_exec) helper_raise_exception(EXCP_IBE); else @@ -2077,22 +2442,27 @@ void helper_ctc1 (target_ulong arg1, uint32_t reg) helper_raise_exception(EXCP_FPE); } -static inline char ieee_ex_to_mips(char xcpt) +static inline int ieee_ex_to_mips(int xcpt) { - return (xcpt & float_flag_inexact) >> 5 | - (xcpt & float_flag_underflow) >> 3 | - (xcpt & float_flag_overflow) >> 1 | - (xcpt & float_flag_divbyzero) << 1 | - (xcpt & float_flag_invalid) << 4; -} - -static inline char mips_ex_to_ieee(char xcpt) -{ - return (xcpt & FP_INEXACT) << 5 | - (xcpt & FP_UNDERFLOW) << 3 | - (xcpt & FP_OVERFLOW) << 1 | - (xcpt & FP_DIV0) >> 1 | - (xcpt & FP_INVALID) >> 4; + int ret = 0; + if (xcpt) { + if (xcpt & float_flag_invalid) { + ret |= FP_INVALID; + } + if (xcpt & float_flag_overflow) { + ret |= FP_OVERFLOW; + } + if (xcpt & float_flag_underflow) { + ret |= FP_UNDERFLOW; + } + if (xcpt & float_flag_divbyzero) { + ret |= FP_DIV0; + } + if (xcpt & float_flag_inexact) { + ret |= FP_INEXACT; + } + } + return ret; } static inline void update_fcr31(void) @@ -2282,6 +2652,7 @@ uint64_t helper_float_roundl_d(uint64_t fdt0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status); dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2295,6 +2666,7 @@ uint64_t helper_float_roundl_s(uint32_t fst0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status); dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2308,6 +2680,7 @@ uint32_t helper_float_roundw_d(uint64_t fdt0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status); wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2321,6 +2694,7 @@ uint32_t helper_float_roundw_s(uint32_t fst0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status); wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2334,6 +2708,7 @@ uint64_t helper_float_truncl_d(uint64_t fdt0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status); update_fcr31(); if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID)) @@ -2345,6 +2720,7 @@ uint64_t helper_float_truncl_s(uint32_t fst0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); update_fcr31(); if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID)) @@ -2356,6 +2732,7 @@ uint32_t helper_float_truncw_d(uint64_t fdt0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); update_fcr31(); if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID)) @@ -2367,6 +2744,7 @@ uint32_t helper_float_truncw_s(uint32_t fst0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); update_fcr31(); if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID)) @@ -2378,6 +2756,7 @@ uint64_t helper_float_ceill_d(uint64_t fdt0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2391,6 +2770,7 @@ uint64_t helper_float_ceill_s(uint32_t fst0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2404,6 +2784,7 @@ uint32_t helper_float_ceilw_d(uint64_t fdt0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2417,6 +2798,7 @@ uint32_t helper_float_ceilw_s(uint32_t fst0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2430,6 +2812,7 @@ uint64_t helper_float_floorl_d(uint64_t fdt0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2443,6 +2826,7 @@ uint64_t helper_float_floorl_s(uint32_t fst0) { uint64_t dt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2456,6 +2840,7 @@ uint32_t helper_float_floorw_d(uint64_t fdt0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2469,6 +2854,7 @@ uint32_t helper_float_floorw_s(uint32_t fst0) { uint32_t wt2; + set_float_exception_flags(0, &env->active_fpu.fp_status); set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); RESTORE_ROUNDING_MODE; @@ -2853,7 +3239,9 @@ uint64_t helper_float_mulr_ps(uint64_t fdt0, uint64_t fdt1) #define FOP_COND_D(op, cond) \ void helper_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ { \ - int c = cond; \ + int c; \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ + c = cond; \ update_fcr31(); \ if (c) \ SET_FP_COND(cc, env->active_fpu); \ @@ -2863,6 +3251,7 @@ void helper_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ { \ int c; \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ fdt0 = float64_abs(fdt0); \ fdt1 = float64_abs(fdt1); \ c = cond; \ @@ -2873,45 +3262,33 @@ void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ CLEAR_FP_COND(cc, env->active_fpu); \ } -static int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM) -{ - if (float64_is_signaling_nan(a) || - float64_is_signaling_nan(b) || - (sig && (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)))) { - float_raise(float_flag_invalid, status); - return 1; - } else if (float64_is_quiet_nan(a) || float64_is_quiet_nan(b)) { - return 1; - } else { - return 0; - } -} - /* NOTE: the comma operator will make "cond" to eval to false, - * but float*_is_unordered() is still called. */ -FOP_COND_D(f, (float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status), 0)) -FOP_COND_D(un, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)) -FOP_COND_D(eq, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) || float64_le(fdt0, fdt1, &env->active_fpu.fp_status)) + * but float64_unordered_quiet() is still called. */ +FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), 0)) +FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status)) +FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status)) /* NOTE: the comma operator will make "cond" to eval to false, - * but float*_is_unordered() is still called. */ -FOP_COND_D(sf, (float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status), 0)) -FOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)) -FOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(lt, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(le, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status)) -FOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) || float64_le(fdt0, fdt1, &env->active_fpu.fp_status)) + * but float64_unordered() is still called. */ +FOP_COND_D(sf, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0)) +FOP_COND_D(ngle,float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)) +FOP_COND_D(seq, float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(lt, float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(nge, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(le, float64_le(fdt0, fdt1, &env->active_fpu.fp_status)) +FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || float64_le(fdt0, fdt1, &env->active_fpu.fp_status)) #define FOP_COND_S(op, cond) \ void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \ { \ - int c = cond; \ + int c; \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ + c = cond; \ update_fcr31(); \ if (c) \ SET_FP_COND(cc, env->active_fpu); \ @@ -2921,6 +3298,7 @@ void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \ { \ int c; \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ fst0 = float32_abs(fst0); \ fst1 = float32_abs(fst1); \ c = cond; \ @@ -2931,51 +3309,39 @@ void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \ CLEAR_FP_COND(cc, env->active_fpu); \ } -static flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM) -{ - if (float32_is_signaling_nan(a) || - float32_is_signaling_nan(b) || - (sig && (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)))) { - float_raise(float_flag_invalid, status); - return 1; - } else if (float32_is_quiet_nan(a) || float32_is_quiet_nan(b)) { - return 1; - } else { - return 0; - } -} - /* NOTE: the comma operator will make "cond" to eval to false, - * but float*_is_unordered() is still called. */ -FOP_COND_S(f, (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0)) -FOP_COND_S(un, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)) -FOP_COND_S(eq, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status)) + * but float32_unordered_quiet() is still called. */ +FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0)) +FOP_COND_S(un, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status)) +FOP_COND_S(eq, float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status)) /* NOTE: the comma operator will make "cond" to eval to false, - * but float*_is_unordered() is still called. */ -FOP_COND_S(sf, (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0)) -FOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)) -FOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(lt, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(le, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status)) -FOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status)) + * but float32_unordered() is still called. */ +FOP_COND_S(sf, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0)) +FOP_COND_S(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status)) +FOP_COND_S(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(lt, float32_lt(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(le, float32_le(fst0, fst1, &env->active_fpu.fp_status)) +FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status)) #define FOP_COND_PS(op, condl, condh) \ void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ { \ - uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \ - uint32_t fsth0 = float32_abs(fdt0 >> 32); \ - uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \ - uint32_t fsth1 = float32_abs(fdt1 >> 32); \ - int cl = condl; \ - int ch = condh; \ - \ + uint32_t fst0, fsth0, fst1, fsth1; \ + int ch, cl; \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ + fst0 = fdt0 & 0XFFFFFFFF; \ + fsth0 = fdt0 >> 32; \ + fst1 = fdt1 & 0XFFFFFFFF; \ + fsth1 = fdt1 >> 32; \ + cl = condl; \ + ch = condh; \ update_fcr31(); \ if (cl) \ SET_FP_COND(cc, env->active_fpu); \ @@ -2988,13 +3354,14 @@ void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ } \ void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ { \ - uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \ - uint32_t fsth0 = float32_abs(fdt0 >> 32); \ - uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \ - uint32_t fsth1 = float32_abs(fdt1 >> 32); \ - int cl = condl; \ - int ch = condh; \ - \ + uint32_t fst0, fsth0, fst1, fsth1; \ + int ch, cl; \ + fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \ + fsth0 = float32_abs(fdt0 >> 32); \ + fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \ + fsth1 = float32_abs(fdt1 >> 32); \ + cl = condl; \ + ch = condh; \ update_fcr31(); \ if (cl) \ SET_FP_COND(cc, env->active_fpu); \ @@ -3007,38 +3374,38 @@ void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \ } /* NOTE: the comma operator will make "cond" to eval to false, - * but float*_is_unordered() is still called. */ -FOP_COND_PS(f, (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0), - (float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status), 0)) -FOP_COND_PS(un, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), - float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)) -FOP_COND_PS(eq, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status), - !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status), - float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status), - !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status), - float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status), - !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status), - float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) + * but float32_unordered_quiet() is still called. */ +FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), 0), + (float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status), 0)) +FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), + float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status)) +FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status), + float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status), + float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq_quiet(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status), + float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status), + float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt_quiet(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(ole, float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status), + float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status), + float32_unordered_quiet(fsth1, fsth0, &env->active_fpu.fp_status) || float32_le_quiet(fsth0, fsth1, &env->active_fpu.fp_status)) /* NOTE: the comma operator will make "cond" to eval to false, - * but float*_is_unordered() is still called. */ -FOP_COND_PS(sf, (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0), - (float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status), 0)) -FOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), - float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)) -FOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status), - !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status), - float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(lt, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status), - !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status), - float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(le, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status), - !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) -FOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status), - float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) + * but float32_unordered() is still called. */ +FOP_COND_PS(sf, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0), + (float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status), 0)) +FOP_COND_PS(ngle,float32_unordered(fst1, fst0, &env->active_fpu.fp_status), + float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status)) +FOP_COND_PS(seq, float32_eq(fst0, fst1, &env->active_fpu.fp_status), + float32_eq(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(ngl, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_eq(fst0, fst1, &env->active_fpu.fp_status), + float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(lt, float32_lt(fst0, fst1, &env->active_fpu.fp_status), + float32_lt(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(nge, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_lt(fst0, fst1, &env->active_fpu.fp_status), + float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(le, float32_le(fst0, fst1, &env->active_fpu.fp_status), + float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) +FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status), + float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) diff --git a/target-mips/translate.c b/target-mips/translate.c index 0f93e2a..d5b1c76 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -27,7 +27,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "qemu-common.h" @@ -2686,7 +2685,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) likely(!ctx->singlestep_enabled)) { tcg_gen_goto_tb(n); gen_save_pc(dest); - tcg_gen_exit_tb((long)tb + n); + tcg_gen_exit_tb((tcg_target_long)tb + n); } else { gen_save_pc(dest); if (ctx->singlestep_enabled) { @@ -5538,6 +5537,19 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, tcg_gen_movi_tl(t0, -1); else if (u == 0) { switch (rt) { + case 1: + switch (sel) { + case 1: + gen_helper_mftc0_vpecontrol(t0); + break; + case 2: + gen_helper_mftc0_vpeconf0(t0); + break; + default: + goto die; + break; + } + break; case 2: switch (sel) { case 1: @@ -5584,6 +5596,46 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, gen_mfc0(env, ctx, t0, rt, sel); break; } + case 13: + switch (sel) { + case 0: + gen_helper_mftc0_cause(t0); + break; + default: + goto die; + break; + } + break; + case 14: + switch (sel) { + case 0: + gen_helper_mftc0_epc(t0); + break; + default: + goto die; + break; + } + break; + case 15: + switch (sel) { + case 1: + gen_helper_mftc0_ebase(t0); + break; + default: + goto die; + break; + } + break; + case 16: + switch (sel) { + case 0 ... 7: + gen_helper_mftc0_configx(t0, tcg_const_tl(sel)); + break; + default: + goto die; + break; + } + break; case 23: switch (sel) { case 0: @@ -5703,6 +5755,19 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, /* NOP */ ; else if (u == 0) { switch (rd) { + case 1: + switch (sel) { + case 1: + gen_helper_mttc0_vpecontrol(t0); + break; + case 2: + gen_helper_mttc0_vpeconf0(t0); + break; + default: + goto die; + break; + } + break; case 2: switch (sel) { case 1: @@ -5749,6 +5814,26 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, gen_mtc0(env, ctx, t0, rd, sel); break; } + case 13: + switch (sel) { + case 0: + gen_helper_mttc0_cause(t0); + break; + default: + goto die; + break; + } + break; + case 15: + switch (sel) { + case 1: + gen_helper_mttc0_ebase(t0); + break; + default: + goto die; + break; + } + break; case 23: switch (sel) { case 0: @@ -12619,7 +12704,7 @@ CPUMIPSState *cpu_mips_init (const char *cpu_model) def = cpu_mips_find_by_name(cpu_model); if (!def) return NULL; - env = qemu_mallocz(sizeof(CPUMIPSState)); + env = g_malloc0(sizeof(CPUMIPSState)); env->cpu_model = def; env->cpu_model_str = cpu_model; @@ -12728,6 +12813,32 @@ void cpu_reset (CPUMIPSState *env) /* Count register increments in debug mode, EJTAG version 1 */ env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); env->hflags = MIPS_HFLAG_CP0; + + if (env->CP0_Config3 & (1 << CP0C3_MT)) { + int i; + + /* Only TC0 on VPE 0 starts as active. */ + for (i = 0; i < ARRAY_SIZE(env->tcs); i++) { + env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE; + env->tcs[i].CP0_TCHalt = 1; + } + env->active_tc.CP0_TCHalt = 1; + env->halted = 1; + + if (!env->cpu_index) { + /* VPE0 starts up enabled. */ + env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); + env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); + + /* TC0 starts up unhalted. */ + env->halted = 0; + env->active_tc.CP0_TCHalt = 0; + env->tcs[0].CP0_TCHalt = 0; + /* With thread 0 active. */ + env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A); + env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A); + } + } #endif #if defined(TARGET_MIPS64) if (env->cpu_model->insn_flags & ISA_MIPS3) { @@ -12737,8 +12848,7 @@ void cpu_reset (CPUMIPSState *env) env->exception_index = EXCP_NONE; } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->active_tc.PC = gen_opc_pc[pc_pos]; env->hflags &= ~MIPS_HFLAG_BMASK; diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index 590e092..c39138f 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -38,7 +38,7 @@ ((1 << CP0C2_M)) /* No config4, no DSP ASE, no large physaddr (PABITS), - no external interrupt controller, no vectored interupts, + no external interrupt controller, no vectored interrupts, no 1kb pages, no SmartMIPS ASE, no trace logic */ #define MIPS_CONFIG3 \ ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ @@ -274,7 +274,7 @@ static const mips_def_t mips_defs[] = (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | (1 << CP0C1_CA), .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT), + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT), .CP0_LLAddr_rw_bitmask = 0, .CP0_LLAddr_shift = 0, .SYNCI_Step = 32, @@ -477,7 +477,7 @@ static const mips_def_t mips_defs[] = .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), .SYNCI_Step = 16, .CCRes = 2, - .CP0_Status_rw_bitmask = 0xF5D0FF1F, /*bit5:7 not writeable*/ + .CP0_Status_rw_bitmask = 0xF5D0FF1F, /*bit5:7 not writable*/ .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV), .SEGBITS = 40, .PABITS = 40, @@ -535,7 +535,7 @@ static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def) static void mmu_init (CPUMIPSState *env, const mips_def_t *def) { - env->tlb = qemu_mallocz(sizeof(CPUMIPSTLBContext)); + env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext)); switch (def->mmu_type) { case MMU_TYPE_NONE: @@ -568,7 +568,7 @@ static void fpu_init (CPUMIPSState *env, const mips_def_t *def) static void mvp_init (CPUMIPSState *env, const mips_def_t *def) { - env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext)); + env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext)); /* MVPConf1 implemented, TLB sharable, no gating storage support, programmable cache partitioning implemented, number of allocatable @@ -580,7 +580,7 @@ static void mvp_init (CPUMIPSState *env, const mips_def_t *def) // (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) | // (0x04 << CP0MVPC0_PTC); (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) | - (0x04 << CP0MVPC0_PTC); + (0x00 << CP0MVPC0_PTC); #if !defined(CONFIG_USER_ONLY) /* Usermode has no TLB support */ env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE); diff --git a/target-ppc/STATUS b/target-ppc/STATUS index 32e7ffa..c8e9018 100644 --- a/target-ppc/STATUS +++ b/target-ppc/STATUS @@ -11,7 +11,7 @@ INSN: instruction set. SPR: special purpose registers set OK => all SPR registered (but some may be fake) KO => some SPR are missing or should be removed - ? => uncheked + ? => unchecked MSR: MSR bits definitions OK => all MSR bits properly defined KO => MSR definition is incorrect diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index deb8d7c..e84108c 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -43,6 +43,8 @@ # define TARGET_VIRT_ADDR_SPACE_BITS 64 #endif +#define TARGET_PAGE_BITS_16M 24 + #else /* defined (TARGET_PPC64) */ /* PowerPC 32 definitions */ #define TARGET_LONG_BITS 32 @@ -64,7 +66,7 @@ #define TARGET_PAGE_BITS 12 #endif /* defined(TARGET_PPCEMB) */ -#define TARGET_PHYS_ADDR_SPACE_BITS 32 +#define TARGET_PHYS_ADDR_SPACE_BITS 36 #define TARGET_VIRT_ADDR_SPACE_BITS 32 #endif /* defined (TARGET_PPC64) */ @@ -73,8 +75,6 @@ #include "cpu-defs.h" -#include - #include "softfloat.h" #define TARGET_HAS_ICE 1 @@ -106,16 +106,19 @@ enum powerpc_mmu_t { POWERPC_MMU_MPC8xx = 0x00000007, /* BookE MMU model */ POWERPC_MMU_BOOKE = 0x00000008, - /* BookE FSL MMU model */ - POWERPC_MMU_BOOKE_FSL = 0x00000009, + /* BookE 2.06 MMU model */ + POWERPC_MMU_BOOKE206 = 0x00000009, /* PowerPC 601 MMU model (specific BATs format) */ POWERPC_MMU_601 = 0x0000000A, #if defined(TARGET_PPC64) #define POWERPC_MMU_64 0x00010000 +#define POWERPC_MMU_1TSEG 0x00020000 /* 64 bits PowerPC MMU */ POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001, /* 620 variant (no segment exceptions) */ POWERPC_MMU_620 = POWERPC_MMU_64 | 0x00000002, + /* Architecture 2.06 variant */ + POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG | 0x00000003, #endif /* defined(TARGET_PPC64) */ }; @@ -151,6 +154,8 @@ enum powerpc_excp_t { #if defined(TARGET_PPC64) /* PowerPC 970 exception model */ POWERPC_EXCP_970, + /* POWER7 exception model */ + POWERPC_EXCP_POWER7, #endif /* defined(TARGET_PPC64) */ }; @@ -218,7 +223,7 @@ enum { /* 970FX specific exceptions */ POWERPC_EXCP_SOFTP = 88, /* Soft patch exception */ POWERPC_EXCP_MAINT = 89, /* Maintenance exception */ - /* Freescale embeded cores specific exceptions */ + /* Freescale embedded cores specific exceptions */ POWERPC_EXCP_MEXTBR = 90, /* Maskable external breakpoint */ POWERPC_EXCP_NMEXTBR = 91, /* Non maskable external breakpoint */ POWERPC_EXCP_ITLBE = 92, /* Instruction TLB error */ @@ -286,6 +291,8 @@ enum powerpc_input_t { PPC_FLAGS_INPUT_405, /* PowerPC 970 bus */ PPC_FLAGS_INPUT_970, + /* PowerPC POWER7 bus */ + PPC_FLAGS_INPUT_POWER7, /* PowerPC 401 bus */ PPC_FLAGS_INPUT_401, /* Freescale RCPU bus */ @@ -351,18 +358,71 @@ struct ppcemb_tlb_t { uint32_t attr; /* Storage attributes */ }; +typedef struct ppcmas_tlb_t { + uint32_t mas8; + uint32_t mas1; + uint64_t mas2; + uint64_t mas7_3; +} ppcmas_tlb_t; + union ppc_tlb_t { - ppc6xx_tlb_t tlb6; - ppcemb_tlb_t tlbe; + ppc6xx_tlb_t *tlb6; + ppcemb_tlb_t *tlbe; + ppcmas_tlb_t *tlbm; }; + +/* possible TLB variants */ +#define TLB_NONE 0 +#define TLB_6XX 1 +#define TLB_EMB 2 +#define TLB_MAS 3 #endif +#define SDR_32_HTABORG 0xFFFF0000UL +#define SDR_32_HTABMASK 0x000001FFUL + +#if defined(TARGET_PPC64) +#define SDR_64_HTABORG 0xFFFFFFFFFFFC0000ULL +#define SDR_64_HTABSIZE 0x000000000000001FULL +#endif /* defined(TARGET_PPC64 */ + +#define HASH_PTE_SIZE_32 8 +#define HASH_PTE_SIZE_64 16 + typedef struct ppc_slb_t ppc_slb_t; struct ppc_slb_t { - uint64_t tmp64; - uint32_t tmp; + uint64_t esid; + uint64_t vsid; }; +/* Bits in the SLB ESID word */ +#define SLB_ESID_ESID 0xFFFFFFFFF0000000ULL +#define SLB_ESID_V 0x0000000008000000ULL /* valid */ + +/* Bits in the SLB VSID word */ +#define SLB_VSID_SHIFT 12 +#define SLB_VSID_SHIFT_1T 24 +#define SLB_VSID_SSIZE_SHIFT 62 +#define SLB_VSID_B 0xc000000000000000ULL +#define SLB_VSID_B_256M 0x0000000000000000ULL +#define SLB_VSID_B_1T 0x4000000000000000ULL +#define SLB_VSID_VSID 0x3FFFFFFFFFFFF000ULL +#define SLB_VSID_PTEM (SLB_VSID_B | SLB_VSID_VSID) +#define SLB_VSID_KS 0x0000000000000800ULL +#define SLB_VSID_KP 0x0000000000000400ULL +#define SLB_VSID_N 0x0000000000000200ULL /* no-execute */ +#define SLB_VSID_L 0x0000000000000100ULL +#define SLB_VSID_C 0x0000000000000080ULL /* class */ +#define SLB_VSID_LP 0x0000000000000030ULL +#define SLB_VSID_ATTR 0x0000000000000FFFULL + +#define SEGMENT_SHIFT_256M 28 +#define SEGMENT_MASK_256M (~((1ULL << SEGMENT_SHIFT_256M) - 1)) + +#define SEGMENT_SHIFT_1T 40 +#define SEGMENT_MASK_1T (~((1ULL << SEGMENT_SHIFT_1T) - 1)) + + /*****************************************************************************/ /* Machine state register bits definition */ #define MSR_SF 63 /* Sixty-four-bit mode hflags */ @@ -372,6 +432,7 @@ struct ppc_slb_t { #define MSR_CM 31 /* Computation mode for BookE hflags */ #define MSR_ICM 30 /* Interrupt computation mode for BookE */ #define MSR_THV 29 /* hypervisor state for 32 bits PowerPC hflags */ +#define MSR_GS 28 /* guest state for BookE */ #define MSR_UCLE 26 /* User-mode cache lock enable for BookE */ #define MSR_VR 25 /* altivec available x hflags */ #define MSR_SPE 25 /* SPE enable for BookE x hflags */ @@ -409,6 +470,7 @@ struct ppc_slb_t { #define msr_cm ((env->msr >> MSR_CM) & 1) #define msr_icm ((env->msr >> MSR_ICM) & 1) #define msr_thv ((env->msr >> MSR_THV) & 1) +#define msr_gs ((env->msr >> MSR_GS) & 1) #define msr_ucle ((env->msr >> MSR_UCLE) & 1) #define msr_vr ((env->msr >> MSR_VR) & 1) #define msr_spe ((env->msr >> MSR_SPE) & 1) @@ -454,7 +516,22 @@ struct ppc_slb_t { #endif /* Exception state register bits definition */ -#define ESR_ST 23 /* Exception was caused by a store type access. */ +#define ESR_PIL (1 << (63 - 36)) /* Illegal Instruction */ +#define ESR_PPR (1 << (63 - 37)) /* Privileged Instruction */ +#define ESR_PTR (1 << (63 - 38)) /* Trap */ +#define ESR_FP (1 << (63 - 39)) /* Floating-Point Operation */ +#define ESR_ST (1 << (63 - 40)) /* Store Operation */ +#define ESR_AP (1 << (63 - 44)) /* Auxiliary Processor Operation */ +#define ESR_PUO (1 << (63 - 45)) /* Unimplemented Operation */ +#define ESR_BO (1 << (63 - 46)) /* Byte Ordering */ +#define ESR_PIE (1 << (63 - 47)) /* Imprecise exception */ +#define ESR_DATA (1 << (63 - 53)) /* Data Access (Embedded page table) */ +#define ESR_TLBI (1 << (63 - 54)) /* TLB Ineligible (Embedded page table) */ +#define ESR_PT (1 << (63 - 55)) /* Page Table (Embedded page table) */ +#define ESR_SPV (1 << (63 - 56)) /* SPE/VMX operation */ +#define ESR_EPID (1 << (63 - 57)) /* External Process ID operation */ +#define ESR_VLEMI (1 << (63 - 58)) /* VLE operation */ +#define ESR_MIF (1 << (63 - 62)) /* Misaligned instruction (VLE) */ enum { POWERPC_FLAG_NONE = 0x00000000, @@ -478,6 +555,8 @@ enum { /* Decrementer clock: RTC clock (POWER, 601) or bus clock */ POWERPC_FLAG_RTC_CLK = 0x00010000, POWERPC_FLAG_BUS_CLK = 0x00020000, + /* Has CFAR */ + POWERPC_FLAG_CFAR = 0x00040000, }; /*****************************************************************************/ @@ -558,9 +637,243 @@ enum { #define vscr_sat (((env->vscr) >> VSCR_SAT) & 0x1) /*****************************************************************************/ +/* BookE e500 MMU registers */ + +#define MAS0_NV_SHIFT 0 +#define MAS0_NV_MASK (0xfff << MAS0_NV_SHIFT) + +#define MAS0_WQ_SHIFT 12 +#define MAS0_WQ_MASK (3 << MAS0_WQ_SHIFT) +/* Write TLB entry regardless of reservation */ +#define MAS0_WQ_ALWAYS (0 << MAS0_WQ_SHIFT) +/* Write TLB entry only already in use */ +#define MAS0_WQ_COND (1 << MAS0_WQ_SHIFT) +/* Clear TLB entry */ +#define MAS0_WQ_CLR_RSRV (2 << MAS0_WQ_SHIFT) + +#define MAS0_HES_SHIFT 14 +#define MAS0_HES (1 << MAS0_HES_SHIFT) + +#define MAS0_ESEL_SHIFT 16 +#define MAS0_ESEL_MASK (0xfff << MAS0_ESEL_SHIFT) + +#define MAS0_TLBSEL_SHIFT 28 +#define MAS0_TLBSEL_MASK (3 << MAS0_TLBSEL_SHIFT) +#define MAS0_TLBSEL_TLB0 (0 << MAS0_TLBSEL_SHIFT) +#define MAS0_TLBSEL_TLB1 (1 << MAS0_TLBSEL_SHIFT) +#define MAS0_TLBSEL_TLB2 (2 << MAS0_TLBSEL_SHIFT) +#define MAS0_TLBSEL_TLB3 (3 << MAS0_TLBSEL_SHIFT) + +#define MAS0_ATSEL_SHIFT 31 +#define MAS0_ATSEL (1 << MAS0_ATSEL_SHIFT) +#define MAS0_ATSEL_TLB 0 +#define MAS0_ATSEL_LRAT MAS0_ATSEL + +#define MAS1_TSIZE_SHIFT 7 +#define MAS1_TSIZE_MASK (0x1f << MAS1_TSIZE_SHIFT) + +#define MAS1_TS_SHIFT 12 +#define MAS1_TS (1 << MAS1_TS_SHIFT) + +#define MAS1_IND_SHIFT 13 +#define MAS1_IND (1 << MAS1_IND_SHIFT) + +#define MAS1_TID_SHIFT 16 +#define MAS1_TID_MASK (0x3fff << MAS1_TID_SHIFT) + +#define MAS1_IPROT_SHIFT 30 +#define MAS1_IPROT (1 << MAS1_IPROT_SHIFT) + +#define MAS1_VALID_SHIFT 31 +#define MAS1_VALID 0x80000000 + +#define MAS2_EPN_SHIFT 12 +#define MAS2_EPN_MASK (0xfffff << MAS2_EPN_SHIFT) + +#define MAS2_ACM_SHIFT 6 +#define MAS2_ACM (1 << MAS2_ACM_SHIFT) + +#define MAS2_VLE_SHIFT 5 +#define MAS2_VLE (1 << MAS2_VLE_SHIFT) + +#define MAS2_W_SHIFT 4 +#define MAS2_W (1 << MAS2_W_SHIFT) + +#define MAS2_I_SHIFT 3 +#define MAS2_I (1 << MAS2_I_SHIFT) + +#define MAS2_M_SHIFT 2 +#define MAS2_M (1 << MAS2_M_SHIFT) + +#define MAS2_G_SHIFT 1 +#define MAS2_G (1 << MAS2_G_SHIFT) + +#define MAS2_E_SHIFT 0 +#define MAS2_E (1 << MAS2_E_SHIFT) + +#define MAS3_RPN_SHIFT 12 +#define MAS3_RPN_MASK (0xfffff << MAS3_RPN_SHIFT) + +#define MAS3_U0 0x00000200 +#define MAS3_U1 0x00000100 +#define MAS3_U2 0x00000080 +#define MAS3_U3 0x00000040 +#define MAS3_UX 0x00000020 +#define MAS3_SX 0x00000010 +#define MAS3_UW 0x00000008 +#define MAS3_SW 0x00000004 +#define MAS3_UR 0x00000002 +#define MAS3_SR 0x00000001 +#define MAS3_SPSIZE_SHIFT 1 +#define MAS3_SPSIZE_MASK (0x3e << MAS3_SPSIZE_SHIFT) + +#define MAS4_TLBSELD_SHIFT MAS0_TLBSEL_SHIFT +#define MAS4_TLBSELD_MASK MAS0_TLBSEL_MASK +#define MAS4_TIDSELD_MASK 0x00030000 +#define MAS4_TIDSELD_PID0 0x00000000 +#define MAS4_TIDSELD_PID1 0x00010000 +#define MAS4_TIDSELD_PID2 0x00020000 +#define MAS4_TIDSELD_PIDZ 0x00030000 +#define MAS4_INDD 0x00008000 /* Default IND */ +#define MAS4_TSIZED_SHIFT MAS1_TSIZE_SHIFT +#define MAS4_TSIZED_MASK MAS1_TSIZE_MASK +#define MAS4_ACMD 0x00000040 +#define MAS4_VLED 0x00000020 +#define MAS4_WD 0x00000010 +#define MAS4_ID 0x00000008 +#define MAS4_MD 0x00000004 +#define MAS4_GD 0x00000002 +#define MAS4_ED 0x00000001 +#define MAS4_WIMGED_MASK 0x0000001f /* Default WIMGE */ +#define MAS4_WIMGED_SHIFT 0 + +#define MAS5_SGS 0x80000000 +#define MAS5_SLPID_MASK 0x00000fff + +#define MAS6_SPID0 0x3fff0000 +#define MAS6_SPID1 0x00007ffe +#define MAS6_ISIZE(x) MAS1_TSIZE(x) +#define MAS6_SAS 0x00000001 +#define MAS6_SPID MAS6_SPID0 +#define MAS6_SIND 0x00000002 /* Indirect page */ +#define MAS6_SIND_SHIFT 1 +#define MAS6_SPID_MASK 0x3fff0000 +#define MAS6_SPID_SHIFT 16 +#define MAS6_ISIZE_MASK 0x00000f80 +#define MAS6_ISIZE_SHIFT 7 + +#define MAS7_RPN 0xffffffff + +#define MAS8_TGS 0x80000000 +#define MAS8_VF 0x40000000 +#define MAS8_TLBPID 0x00000fff + +/* Bit definitions for MMUCFG */ +#define MMUCFG_MAVN 0x00000003 /* MMU Architecture Version Number */ +#define MMUCFG_MAVN_V1 0x00000000 /* v1.0 */ +#define MMUCFG_MAVN_V2 0x00000001 /* v2.0 */ +#define MMUCFG_NTLBS 0x0000000c /* Number of TLBs */ +#define MMUCFG_PIDSIZE 0x000007c0 /* PID Reg Size */ +#define MMUCFG_TWC 0x00008000 /* TLB Write Conditional (v2.0) */ +#define MMUCFG_LRAT 0x00010000 /* LRAT Supported (v2.0) */ +#define MMUCFG_RASIZE 0x00fe0000 /* Real Addr Size */ +#define MMUCFG_LPIDSIZE 0x0f000000 /* LPID Reg Size */ + +/* Bit definitions for MMUCSR0 */ +#define MMUCSR0_TLB1FI 0x00000002 /* TLB1 Flash invalidate */ +#define MMUCSR0_TLB0FI 0x00000004 /* TLB0 Flash invalidate */ +#define MMUCSR0_TLB2FI 0x00000040 /* TLB2 Flash invalidate */ +#define MMUCSR0_TLB3FI 0x00000020 /* TLB3 Flash invalidate */ +#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \ + MMUCSR0_TLB2FI | MMUCSR0_TLB3FI) +#define MMUCSR0_TLB0PS 0x00000780 /* TLB0 Page Size */ +#define MMUCSR0_TLB1PS 0x00007800 /* TLB1 Page Size */ +#define MMUCSR0_TLB2PS 0x00078000 /* TLB2 Page Size */ +#define MMUCSR0_TLB3PS 0x00780000 /* TLB3 Page Size */ + +/* TLBnCFG encoding */ +#define TLBnCFG_N_ENTRY 0x00000fff /* number of entries */ +#define TLBnCFG_HES 0x00002000 /* HW select supported */ +#define TLBnCFG_AVAIL 0x00004000 /* variable page size */ +#define TLBnCFG_IPROT 0x00008000 /* IPROT supported */ +#define TLBnCFG_GTWE 0x00010000 /* Guest can write */ +#define TLBnCFG_IND 0x00020000 /* IND entries supported */ +#define TLBnCFG_PT 0x00040000 /* Can load from page table */ +#define TLBnCFG_MINSIZE 0x00f00000 /* Minimum Page Size (v1.0) */ +#define TLBnCFG_MINSIZE_SHIFT 20 +#define TLBnCFG_MAXSIZE 0x000f0000 /* Maximum Page Size (v1.0) */ +#define TLBnCFG_MAXSIZE_SHIFT 16 +#define TLBnCFG_ASSOC 0xff000000 /* Associativity */ +#define TLBnCFG_ASSOC_SHIFT 24 + +/* TLBnPS encoding */ +#define TLBnPS_4K 0x00000004 +#define TLBnPS_8K 0x00000008 +#define TLBnPS_16K 0x00000010 +#define TLBnPS_32K 0x00000020 +#define TLBnPS_64K 0x00000040 +#define TLBnPS_128K 0x00000080 +#define TLBnPS_256K 0x00000100 +#define TLBnPS_512K 0x00000200 +#define TLBnPS_1M 0x00000400 +#define TLBnPS_2M 0x00000800 +#define TLBnPS_4M 0x00001000 +#define TLBnPS_8M 0x00002000 +#define TLBnPS_16M 0x00004000 +#define TLBnPS_32M 0x00008000 +#define TLBnPS_64M 0x00010000 +#define TLBnPS_128M 0x00020000 +#define TLBnPS_256M 0x00040000 +#define TLBnPS_512M 0x00080000 +#define TLBnPS_1G 0x00100000 +#define TLBnPS_2G 0x00200000 +#define TLBnPS_4G 0x00400000 +#define TLBnPS_8G 0x00800000 +#define TLBnPS_16G 0x01000000 +#define TLBnPS_32G 0x02000000 +#define TLBnPS_64G 0x04000000 +#define TLBnPS_128G 0x08000000 +#define TLBnPS_256G 0x10000000 + +/* tlbilx action encoding */ +#define TLBILX_T_ALL 0 +#define TLBILX_T_TID 1 +#define TLBILX_T_FULLMATCH 3 +#define TLBILX_T_CLASS0 4 +#define TLBILX_T_CLASS1 5 +#define TLBILX_T_CLASS2 6 +#define TLBILX_T_CLASS3 7 + +/* BookE 2.06 helper defines */ + +#define BOOKE206_FLUSH_TLB0 (1 << 0) +#define BOOKE206_FLUSH_TLB1 (1 << 1) +#define BOOKE206_FLUSH_TLB2 (1 << 2) +#define BOOKE206_FLUSH_TLB3 (1 << 3) + +/* number of possible TLBs */ +#define BOOKE206_MAX_TLBN 4 + +/*****************************************************************************/ /* The whole PowerPC CPU context */ #define NB_MMU_MODES 3 +struct ppc_def_t { + const char *name; + uint32_t pvr; + uint32_t svr; + uint64_t insns_flags; + uint64_t insns_flags2; + uint64_t msr_mask; + powerpc_mmu_t mmu_model; + powerpc_excp_t excp_model; + powerpc_input_t bus_model; + uint32_t flags; + int bfd_mach; + void (*init_proc)(CPUPPCState *env); + int (*check_pow)(CPUPPCState *env); +}; + struct CPUPPCState { /* First are the most commonly used resources * during translated code execution @@ -577,6 +890,10 @@ struct CPUPPCState { target_ulong ctr; /* condition register */ uint32_t crf[8]; +#if defined(TARGET_PPC64) + /* CFAR */ + target_ulong cfar; +#endif /* XER */ target_ulong xer; /* Reservation address */ @@ -619,22 +936,28 @@ struct CPUPPCState { int slb_nr; #endif /* segment registers */ - target_ulong sdr1; + target_phys_addr_t htab_base; + target_phys_addr_t htab_mask; target_ulong sr[32]; + /* externally stored hash table */ + uint8_t *external_htab; /* BATs */ int nb_BATs; target_ulong DBAT[2][8]; target_ulong IBAT[2][8]; - /* PowerPC TLB registers (for 4xx and 60x software driven TLBs) */ + /* PowerPC TLB registers (for 4xx, e500 and 60x software driven TLBs) */ int nb_tlb; /* Total number of TLB */ int tlb_per_way; /* Speed-up helper: used to avoid divisions at run time */ int nb_ways; /* Number of ways in the TLB set */ int last_way; /* Last used way used to allocate TLB in a LRU way */ int id_tlbs; /* If 1, MMU has separated TLBs for instructions & data */ int nb_pids; /* Number of available PID registers */ - ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */ + int tlb_type; /* Type of TLB we're dealing with */ + ppc_tlb_t tlb; /* TLB is optional. Allocate them only if needed */ /* 403 dedicated access protection registers */ target_ulong pb[4]; + bool tlb_dirty; /* Set to non-zero when modifying TLB */ + bool kvm_sw_tlb; /* non-zero if KVM SW TLB API is active */ #endif /* Other registers */ @@ -669,6 +992,14 @@ struct CPUPPCState { int bfd_mach; uint32_t flags; uint64_t insns_flags; + uint64_t insns_flags2; + +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) + target_phys_addr_t vpa; + target_phys_addr_t slb_shadow; + target_phys_addr_t dispatch_trace_log; + uint32_t dtl_size; +#endif /* TARGET_PPC64 */ int error_code; uint32_t pending_interrupts; @@ -703,8 +1034,35 @@ struct CPUPPCState { #if !defined(CONFIG_USER_ONLY) void *load_info; /* Holds boot loading state. */ #endif + + /* booke timers */ + + /* Specifies bit locations of the Time Base used to signal a fixed timer + * exception on a transition from 0 to 1. (watchdog or fixed-interval timer) + * + * 0 selects the least significant bit. + * 63 selects the most significant bit. + */ + uint8_t fit_period[4]; + uint8_t wdt_period[4]; }; +#define SET_FIT_PERIOD(a_, b_, c_, d_) \ +do { \ + env->fit_period[0] = (a_); \ + env->fit_period[1] = (b_); \ + env->fit_period[2] = (c_); \ + env->fit_period[3] = (d_); \ + } while (0) + +#define SET_WDT_PERIOD(a_, b_, c_, d_) \ +do { \ + env->wdt_period[0] = (a_); \ + env->wdt_period[1] = (b_); \ + env->wdt_period[2] = (c_); \ + env->wdt_period[3] = (d_); \ + } while (0) + #if !defined(CONFIG_USER_ONLY) /* Context used internally during MMU translations */ typedef struct mmu_ctx_t mmu_ctx_t; @@ -712,7 +1070,7 @@ struct mmu_ctx_t { target_phys_addr_t raddr; /* Real address */ target_phys_addr_t eaddr; /* Effective address */ int prot; /* Protection bits */ - target_phys_addr_t pg_addr[2]; /* PTE tables base addresses */ + target_phys_addr_t hash[2]; /* Pagetable hash values */ target_ulong ptem; /* Virtual segment ID | API */ int key; /* Access key */ int nx; /* Non-execute area */ @@ -730,7 +1088,7 @@ void cpu_ppc_close (CPUPPCState *s); int cpu_ppc_signal_handler (int host_signum, void *pinfo, void *puc); int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_ppc_handle_mmu_fault #if !defined(CONFIG_USER_ONLY) int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong vaddr, @@ -755,7 +1113,9 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value); void ppc_store_asr (CPUPPCState *env, target_ulong value); target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr); target_ulong ppc_load_sr (CPUPPCState *env, int sr_nr); -void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs); +int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs); +int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt); +int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt); #endif /* defined(TARGET_PPC64) */ void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value); #endif /* !defined(CONFIG_USER_ONLY) */ @@ -763,6 +1123,7 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value); void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf); +const ppc_def_t *ppc_find_by_pvr(uint32_t pvr); const ppc_def_t *cpu_ppc_find_by_name (const char *name); int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def); @@ -793,6 +1154,14 @@ void store_40x_dbcr0 (CPUPPCState *env, uint32_t val); void store_40x_sler (CPUPPCState *env, uint32_t val); void store_booke_tcr (CPUPPCState *env, target_ulong val); void store_booke_tsr (CPUPPCState *env, target_ulong val); +void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot); +target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb); +int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb, + target_phys_addr_t *raddrp, target_ulong address, + uint32_t pid, int ext, int i); +int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb, + target_phys_addr_t *raddrp, target_ulong address, + uint32_t pid); void ppc_tlb_invalidate_all (CPUPPCState *env); void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr); #if defined(TARGET_PPC64) @@ -885,6 +1254,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) #define SPR_601_UDECR (0x006) #define SPR_LR (0x008) #define SPR_CTR (0x009) +#define SPR_DSCR (0x011) #define SPR_DSISR (0x012) #define SPR_DAR (0x013) /* DAE for PowerPC 601 */ #define SPR_601_RTCU (0x014) @@ -893,6 +1263,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) #define SPR_SDR1 (0x019) #define SPR_SRR0 (0x01A) #define SPR_SRR1 (0x01B) +#define SPR_CFAR (0x01C) #define SPR_AMR (0x01D) #define SPR_BOOKE_PID (0x030) #define SPR_BOOKE_DECAR (0x036) @@ -956,6 +1327,8 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) #define SPR_HSPRG1 (0x131) #define SPR_HDSISR (0x132) #define SPR_HDAR (0x133) +#define SPR_BOOKE_EPCR (0x133) +#define SPR_SPURR (0x134) #define SPR_BOOKE_DBCR0 (0x134) #define SPR_IBCR (0x135) #define SPR_PURR (0x135) @@ -1480,6 +1853,43 @@ enum { PPC_DCRX = 0x2000000000000000ULL, /* user-mode DCR access, implemented in PowerPC 460 */ PPC_DCRUX = 0x4000000000000000ULL, + /* popcntw and popcntd instructions */ + PPC_POPCNTWD = 0x8000000000000000ULL, + +#define PPC_TCG_INSNS (PPC_INSNS_BASE | PPC_POWER | PPC_POWER2 \ + | PPC_POWER_RTC | PPC_POWER_BR | PPC_64B \ + | PPC_64BX | PPC_64H | PPC_WAIT | PPC_MFTB \ + | PPC_602_SPEC | PPC_ISEL | PPC_POPCNTB \ + | PPC_STRING | PPC_FLOAT | PPC_FLOAT_EXT \ + | PPC_FLOAT_FSQRT | PPC_FLOAT_FRES \ + | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES \ + | PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX \ + | PPC_ALTIVEC | PPC_SPE | PPC_SPE_SINGLE \ + | PPC_SPE_DOUBLE | PPC_MEM_TLBIA \ + | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC \ + | PPC_MEM_SYNC | PPC_MEM_EIEIO \ + | PPC_CACHE | PPC_CACHE_ICBI \ + | PPC_CACHE_DCBZ | PPC_CACHE_DCBZT \ + | PPC_CACHE_DCBA | PPC_CACHE_LOCK \ + | PPC_EXTERN | PPC_SEGMENT | PPC_6xx_TLB \ + | PPC_74xx_TLB | PPC_40x_TLB | PPC_SEGMENT_64B \ + | PPC_SLBI | PPC_WRTEE | PPC_40x_EXCP \ + | PPC_405_MAC | PPC_440_SPEC | PPC_BOOKE \ + | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \ + | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \ + | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \ + | PPC_POPCNTWD) + + /* extended type values */ + + /* BookE 2.06 PowerPC specification */ + PPC2_BOOKE206 = 0x0000000000000001ULL, + /* VSX (extensions to Altivec / VMX) */ + PPC2_VSX = 0x0000000000000002ULL, + /* Decimal Floating Point (DFP) */ + PPC2_DFP = 0x0000000000000004ULL, + +#define PPC_TCG_INSNS2 (PPC2_BOOKE206) }; /*****************************************************************************/ @@ -1578,6 +1988,15 @@ enum { PPC970_INPUT_THINT = 6, PPC970_INPUT_NB, }; + +enum { + /* POWER7 input pins */ + POWER7_INPUT_INT = 0, + /* POWER7 probably has other inputs, but we don't care about them + * for any existing machine. We can wire these up when we need + * them */ + POWER7_INPUT_NB, +}; #endif /* Hardware exceptions definitions */ @@ -1623,4 +2042,91 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls) #endif } +#if !defined(CONFIG_USER_ONLY) +static inline int booke206_tlbm_id(CPUState *env, ppcmas_tlb_t *tlbm) +{ + uintptr_t tlbml = (uintptr_t)tlbm; + uintptr_t tlbl = (uintptr_t)env->tlb.tlbm; + + return (tlbml - tlbl) / sizeof(env->tlb.tlbm[0]); +} + +static inline int booke206_tlb_size(CPUState *env, int tlbn) +{ + uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; + int r = tlbncfg & TLBnCFG_N_ENTRY; + return r; +} + +static inline int booke206_tlb_ways(CPUState *env, int tlbn) +{ + uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; + int r = tlbncfg >> TLBnCFG_ASSOC_SHIFT; + return r; +} + +static inline int booke206_tlbm_to_tlbn(CPUState *env, ppcmas_tlb_t *tlbm) +{ + int id = booke206_tlbm_id(env, tlbm); + int end = 0; + int i; + + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + end += booke206_tlb_size(env, i); + if (id < end) { + return i; + } + } + + cpu_abort(env, "Unknown TLBe: %d\n", id); + return 0; +} + +static inline int booke206_tlbm_to_way(CPUState *env, ppcmas_tlb_t *tlb) +{ + int tlbn = booke206_tlbm_to_tlbn(env, tlb); + int tlbid = booke206_tlbm_id(env, tlb); + return tlbid & (booke206_tlb_ways(env, tlbn) - 1); +} + +static inline ppcmas_tlb_t *booke206_get_tlbm(CPUState *env, const int tlbn, + target_ulong ea, int way) +{ + int r; + uint32_t ways = booke206_tlb_ways(env, tlbn); + int ways_bits = ffs(ways) - 1; + int tlb_bits = ffs(booke206_tlb_size(env, tlbn)) - 1; + int i; + + way &= ways - 1; + ea >>= MAS2_EPN_SHIFT; + ea &= (1 << (tlb_bits - ways_bits)) - 1; + r = (ea << ways_bits) | way; + + /* bump up to tlbn index */ + for (i = 0; i < tlbn; i++) { + r += booke206_tlb_size(env, i); + } + + return &env->tlb.tlbm[r]; +} + +#endif + +extern void (*cpu_ppc_hypercall)(CPUState *); + +static inline bool cpu_has_work(CPUState *env) +{ + return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD); +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->nip = tb->pc; +} + +void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env); + #endif /* !defined (__CPU_PPC_H__) */ diff --git a/target-ppc/exec.h b/target-ppc/exec.h deleted file mode 100644 index 4688ef5..0000000 --- a/target-ppc/exec.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * PowerPC emulation definitions for qemu. - * - * Copyright (c) 2003-2007 Jocelyn Mayer - * - * 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, see . - */ -#if !defined (__PPC_H__) -#define __PPC_H__ - -#include "config.h" - -#include "dyngen-exec.h" - -#include "cpu.h" -#include "exec-all.h" - -register struct CPUPPCState *env asm(AREG0); - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - -static inline int cpu_has_work(CPUState *env) -{ - return (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD)); -} - - -static inline int cpu_halted(CPUState *env) -{ - if (!env->halted) - return 0; - if (cpu_has_work(env)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->nip = tb->pc; -} - -#endif /* !defined (__PPC_H__) */ diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 4b49101..137a494 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -21,13 +21,13 @@ #include #include #include -#include #include "cpu.h" -#include "exec-all.h" #include "helper_regs.h" #include "qemu-common.h" #include "kvm.h" +#include "kvm_ppc.h" +#include "cpus.h" //#define DEBUG_MMU //#define DEBUG_BATS @@ -70,13 +70,17 @@ # define LOG_EXCP(...) do { } while (0) #endif +/*****************************************************************************/ +/* PowerPC Hypercall emulation */ + +void (*cpu_ppc_hypercall)(CPUState *); /*****************************************************************************/ /* PowerPC MMU emulation */ #if defined(CONFIG_USER_ONLY) int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { int exception, error_code; @@ -320,7 +324,7 @@ static inline void ppc6xx_tlb_invalidate_all(CPUState *env) if (env->id_tlbs == 1) max *= 2; for (nr = 0; nr < max; nr++) { - tlb = &env->tlb[nr].tlb6; + tlb = &env->tlb.tlb6[nr]; pte_invalidate(&tlb->pte0); } tlb_flush(env, 1); @@ -337,7 +341,7 @@ static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env, /* Invalidate ITLB + DTLB, all ways */ for (way = 0; way < env->nb_ways; way++) { nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code); - tlb = &env->tlb[nr].tlb6; + tlb = &env->tlb.tlb6[nr]; if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) { LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr, env->nb_tlb, eaddr); @@ -364,7 +368,7 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, int nr; nr = ppc6xx_tlb_getnum(env, EPN, way, is_code); - tlb = &env->tlb[nr].tlb6; + tlb = &env->tlb.tlb6[nr]; LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1); /* Invalidate any pending reference in Qemu for this virtual address */ @@ -388,7 +392,7 @@ static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx, for (way = 0; way < env->nb_ways; way++) { nr = ppc6xx_tlb_getnum(env, eaddr, way, access_type == ACCESS_CODE ? 1 : 0); - tlb = &env->tlb[nr].tlb6; + tlb = &env->tlb.tlb6[nr]; /* This test "emulates" the PTE index match for hardware TLBs */ if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) { LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx @@ -431,7 +435,7 @@ static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx, LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n", ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret); /* Update page flags */ - pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw); + pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, rw); } return ret; @@ -551,7 +555,7 @@ static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual, BEPIl = *BATu & 0x0FFE0000; bl = (*BATu & 0x00001FFC) << 15; LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx - " BATl " TARGET_FMT_lx " \n\t" TARGET_FMT_lx " " + " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl, BEPIu, BEPIl, bl); @@ -563,21 +567,35 @@ static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual, return ret; } +static inline target_phys_addr_t get_pteg_offset(CPUState *env, + target_phys_addr_t hash, + int pte_size) +{ + return (hash * pte_size * 8) & env->htab_mask; +} + /* PTE table lookup */ -static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw, - int type, int target_page_bits) +static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h, + int rw, int type, int target_page_bits) { - target_ulong base, pte0, pte1; + target_phys_addr_t pteg_off; + target_ulong pte0, pte1; int i, good = -1; int ret, r; ret = -1; /* No entry found */ - base = ctx->pg_addr[h]; + pteg_off = get_pteg_offset(env, ctx->hash[h], + is_64b ? HASH_PTE_SIZE_64 : HASH_PTE_SIZE_32); for (i = 0; i < 8; i++) { #if defined(TARGET_PPC64) if (is_64b) { - pte0 = ldq_phys(base + (i * 16)); - pte1 = ldq_phys(base + (i * 16) + 8); + if (env->external_htab) { + pte0 = ldq_p(env->external_htab + pteg_off + (i * 16)); + pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8); + } else { + pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16)); + pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8); + } /* We have a TLB that saves 4K pages, so let's * split a huge page to 4k chunks */ @@ -588,17 +606,22 @@ static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw, r = pte64_check(ctx, pte0, pte1, h, rw, type); LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " " TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n", - base + (i * 16), pte0, pte1, (int)(pte0 & 1), h, + pteg_off + (i * 16), pte0, pte1, (int)(pte0 & 1), h, (int)((pte0 >> 1) & 1), ctx->ptem); } else #endif { - pte0 = ldl_phys(base + (i * 8)); - pte1 = ldl_phys(base + (i * 8) + 4); + if (env->external_htab) { + pte0 = ldl_p(env->external_htab + pteg_off + (i * 8)); + pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4); + } else { + pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8)); + pte1 = ldl_phys(env->htab_base + pteg_off + (i * 8) + 4); + } r = pte32_check(ctx, pte0, pte1, h, rw, type); LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " " TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n", - base + (i * 8), pte0, pte1, (int)(pte0 >> 31), h, + pteg_off + (i * 8), pte0, pte1, (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1), ctx->ptem); } switch (r) { @@ -634,11 +657,23 @@ static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw, if (pte_update_flags(ctx, &pte1, ret, rw) == 1) { #if defined(TARGET_PPC64) if (is_64b) { - stq_phys_notdirty(base + (good * 16) + 8, pte1); + if (env->external_htab) { + stq_p(env->external_htab + pteg_off + (good * 16) + 8, + pte1); + } else { + stq_phys_notdirty(env->htab_base + pteg_off + + (good * 16) + 8, pte1); + } } else #endif { - stl_phys_notdirty(base + (good * 8) + 4, pte1); + if (env->external_htab) { + stl_p(env->external_htab + pteg_off + (good * 8) + 4, + pte1); + } else { + stl_phys_notdirty(env->htab_base + pteg_off + + (good * 8) + 4, pte1); + } } } } @@ -646,111 +681,45 @@ static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw, return ret; } -static inline int find_pte32(mmu_ctx_t *ctx, int h, int rw, int type, - int target_page_bits) -{ - return _find_pte(ctx, 0, h, rw, type, target_page_bits); -} - -#if defined(TARGET_PPC64) -static inline int find_pte64(mmu_ctx_t *ctx, int h, int rw, int type, - int target_page_bits) -{ - return _find_pte(ctx, 1, h, rw, type, target_page_bits); -} -#endif - static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw, int type, int target_page_bits) { #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) - return find_pte64(ctx, h, rw, type, target_page_bits); + return _find_pte(env, ctx, 1, h, rw, type, target_page_bits); #endif - return find_pte32(ctx, h, rw, type, target_page_bits); + return _find_pte(env, ctx, 0, h, rw, type, target_page_bits); } #if defined(TARGET_PPC64) -static ppc_slb_t *slb_get_entry(CPUPPCState *env, int nr) +static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr) { - ppc_slb_t *retval = &env->slb[nr]; - -#if 0 // XXX implement bridge mode? - if (env->spr[SPR_ASR] & 1) { - target_phys_addr_t sr_base; - - sr_base = env->spr[SPR_ASR] & 0xfffffffffffff000; - sr_base += (12 * nr); - - retval->tmp64 = ldq_phys(sr_base); - retval->tmp = ldl_phys(sr_base + 8); - } -#endif - - return retval; -} - -static void slb_set_entry(CPUPPCState *env, int nr, ppc_slb_t *slb) -{ - ppc_slb_t *entry = &env->slb[nr]; - - if (slb == entry) - return; - - entry->tmp64 = slb->tmp64; - entry->tmp = slb->tmp; -} + uint64_t esid_256M, esid_1T; + int n; -static inline int slb_is_valid(ppc_slb_t *slb) -{ - return (int)(slb->tmp64 & 0x0000000008000000ULL); -} + LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr); -static inline void slb_invalidate(ppc_slb_t *slb) -{ - slb->tmp64 &= ~0x0000000008000000ULL; -} + esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V; + esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V; -static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr, - target_ulong *vsid, target_ulong *page_mask, - int *attr, int *target_page_bits) -{ - target_ulong mask; - int n, ret; - - ret = -5; - LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr); - mask = 0x0000000000000000ULL; /* Avoid gcc warning */ for (n = 0; n < env->slb_nr; n++) { - ppc_slb_t *slb = slb_get_entry(env, n); - - LOG_SLB("%s: seg %d %016" PRIx64 " %08" - PRIx32 "\n", __func__, n, slb->tmp64, slb->tmp); - if (slb_is_valid(slb)) { - /* SLB entry is valid */ - mask = 0xFFFFFFFFF0000000ULL; - if (slb->tmp & 0x8) { - /* 16 MB PTEs */ - if (target_page_bits) - *target_page_bits = 24; - } else { - /* 4 KB PTEs */ - if (target_page_bits) - *target_page_bits = TARGET_PAGE_BITS; - } - if ((eaddr & mask) == (slb->tmp64 & mask)) { - /* SLB match */ - *vsid = ((slb->tmp64 << 24) | (slb->tmp >> 8)) & 0x0003FFFFFFFFFFFFULL; - *page_mask = ~mask; - *attr = slb->tmp & 0xFF; - ret = n; - break; - } + ppc_slb_t *slb = &env->slb[n]; + + LOG_SLB("%s: slot %d %016" PRIx64 " %016" + PRIx64 "\n", __func__, n, slb->esid, slb->vsid); + /* We check for 1T matches on all MMUs here - if the MMU + * doesn't have 1T segment support, we will have prevented 1T + * entries from being inserted in the slbmte code. */ + if (((slb->esid == esid_256M) && + ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M)) + || ((slb->esid == esid_1T) && + ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) { + return slb; } } - return ret; + return NULL; } void ppc_slb_invalidate_all (CPUPPCState *env) @@ -760,11 +729,10 @@ void ppc_slb_invalidate_all (CPUPPCState *env) do_invalidate = 0; /* XXX: Warning: slbia never invalidates the first segment */ for (n = 1; n < env->slb_nr; n++) { - ppc_slb_t *slb = slb_get_entry(env, n); + ppc_slb_t *slb = &env->slb[n]; - if (slb_is_valid(slb)) { - slb_invalidate(slb); - slb_set_entry(env, n, slb); + if (slb->esid & SLB_ESID_V) { + slb->esid &= ~SLB_ESID_V; /* XXX: given the fact that segment size is 256 MB or 1TB, * and we still don't have a tlb_flush_mask(env, n, mask) * in Qemu, we just invalidate all TLBs @@ -778,131 +746,145 @@ void ppc_slb_invalidate_all (CPUPPCState *env) void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0) { - target_ulong vsid, page_mask; - int attr; - int n; + ppc_slb_t *slb; - n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL); - if (n >= 0) { - ppc_slb_t *slb = slb_get_entry(env, n); + slb = slb_lookup(env, T0); + if (!slb) { + return; + } - if (slb_is_valid(slb)) { - slb_invalidate(slb); - slb_set_entry(env, n, slb); - /* XXX: given the fact that segment size is 256 MB or 1TB, - * and we still don't have a tlb_flush_mask(env, n, mask) - * in Qemu, we just invalidate all TLBs - */ - tlb_flush(env, 1); - } + if (slb->esid & SLB_ESID_V) { + slb->esid &= ~SLB_ESID_V; + + /* XXX: given the fact that segment size is 256 MB or 1TB, + * and we still don't have a tlb_flush_mask(env, n, mask) + * in Qemu, we just invalidate all TLBs + */ + tlb_flush(env, 1); } } -target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr) +int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs) { - target_ulong rt; - ppc_slb_t *slb = slb_get_entry(env, slb_nr); + int slot = rb & 0xfff; + ppc_slb_t *slb = &env->slb[slot]; - if (slb_is_valid(slb)) { - /* SLB entry is valid */ - /* Copy SLB bits 62:88 to Rt 37:63 (VSID 23:49) */ - rt = slb->tmp >> 8; /* 65:88 => 40:63 */ - rt |= (slb->tmp64 & 0x7) << 24; /* 62:64 => 37:39 */ - /* Copy SLB bits 89:92 to Rt 33:36 (KsKpNL) */ - rt |= ((slb->tmp >> 4) & 0xF) << 27; - } else { - rt = 0; + if (rb & (0x1000 - env->slb_nr)) { + return -1; /* Reserved bits set or slot too high */ + } + if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) { + return -1; /* Bad segment size */ } - LOG_SLB("%s: %016" PRIx64 " %08" PRIx32 " => %d " - TARGET_FMT_lx "\n", __func__, slb->tmp64, slb->tmp, slb_nr, rt); + if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) { + return -1; /* 1T segment on MMU that doesn't support it */ + } + + /* Mask out the slot number as we store the entry */ + slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V); + slb->vsid = rs; - return rt; + LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64 + " %016" PRIx64 "\n", __func__, slot, rb, rs, + slb->esid, slb->vsid); + + return 0; } -void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs) +int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt) { - ppc_slb_t *slb; - - uint64_t vsid; - uint64_t esid; - int flags, valid, slb_nr; + int slot = rb & 0xfff; + ppc_slb_t *slb = &env->slb[slot]; - vsid = rs >> 12; - flags = ((rs >> 8) & 0xf); + if (slot >= env->slb_nr) { + return -1; + } - esid = rb >> 28; - valid = (rb & (1 << 27)); - slb_nr = rb & 0xfff; + *rt = slb->esid; + return 0; +} - slb = slb_get_entry(env, slb_nr); - slb->tmp64 = (esid << 28) | valid | (vsid >> 24); - slb->tmp = (vsid << 8) | (flags << 3); +int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt) +{ + int slot = rb & 0xfff; + ppc_slb_t *slb = &env->slb[slot]; - LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64 - " %08" PRIx32 "\n", __func__, slb_nr, rb, rs, slb->tmp64, - slb->tmp); + if (slot >= env->slb_nr) { + return -1; + } - slb_set_entry(env, slb_nr, slb); + *rt = slb->vsid; + return 0; } #endif /* defined(TARGET_PPC64) */ /* Perform segment based translation */ -static inline target_phys_addr_t get_pgaddr(target_phys_addr_t sdr1, - int sdr_sh, - target_phys_addr_t hash, - target_phys_addr_t mask) -{ - return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask); -} - static inline int get_segment(CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int type) { - target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask; - target_ulong sr, vsid, vsid_mask, pgidx, page_mask; -#if defined(TARGET_PPC64) - int attr; -#endif - int ds, vsid_sh, sdr_sh, pr, target_page_bits; + target_phys_addr_t hash; + target_ulong vsid; + int ds, pr, target_page_bits; int ret, ret2; pr = msr_pr; + ctx->eaddr = eaddr; #if defined(TARGET_PPC64) if (env->mmu_model & POWERPC_MMU_64) { + ppc_slb_t *slb; + target_ulong pageaddr; + int segment_bits; + LOG_MMU("Check SLBs\n"); - ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr, - &target_page_bits); - if (ret < 0) - return ret; - ctx->key = ((attr & 0x40) && (pr != 0)) || - ((attr & 0x80) && (pr == 0)) ? 1 : 0; + slb = slb_lookup(env, eaddr); + if (!slb) { + return -5; + } + + if (slb->vsid & SLB_VSID_B) { + vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T; + segment_bits = 40; + } else { + vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT; + segment_bits = 28; + } + + target_page_bits = (slb->vsid & SLB_VSID_L) + ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS; + ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP) + : (slb->vsid & SLB_VSID_KS)); ds = 0; - ctx->nx = attr & 0x10 ? 1 : 0; - ctx->eaddr = eaddr; - vsid_mask = 0x00003FFFFFFFFF80ULL; - vsid_sh = 7; - sdr_sh = 18; - sdr_mask = 0x3FF80; + ctx->nx = !!(slb->vsid & SLB_VSID_N); + + pageaddr = eaddr & ((1ULL << segment_bits) + - (1ULL << target_page_bits)); + if (slb->vsid & SLB_VSID_B) { + hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits); + } else { + hash = vsid ^ (pageaddr >> target_page_bits); + } + /* Only 5 bits of the page index are used in the AVPN */ + ctx->ptem = (slb->vsid & SLB_VSID_PTEM) | + ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80)); } else #endif /* defined(TARGET_PPC64) */ { + target_ulong sr, pgidx; + sr = env->sr[eaddr >> 28]; - page_mask = 0x0FFFFFFF; ctx->key = (((sr & 0x20000000) && (pr != 0)) || ((sr & 0x40000000) && (pr == 0))) ? 1 : 0; ds = sr & 0x80000000 ? 1 : 0; ctx->nx = sr & 0x10000000 ? 1 : 0; vsid = sr & 0x00FFFFFF; - vsid_mask = 0x01FFFFC0; - vsid_sh = 6; - sdr_sh = 16; - sdr_mask = 0xFFC0; target_page_bits = TARGET_PAGE_BITS; LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx " ir=%d dr=%d pr=%d %d t=%d\n", eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir, (int)msr_dr, pr != 0 ? 1 : 0, rw, type); + pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits; + hash = vsid ^ pgidx; + ctx->ptem = (vsid << 7) | (pgidx >> 10); } LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n", ctx->key, ds, ctx->nx, vsid); @@ -911,44 +893,12 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx, /* Check if instruction fetch is allowed, if needed */ if (type != ACCESS_CODE || ctx->nx == 0) { /* Page address translation */ - /* Primary table address */ - sdr = env->sdr1; - pgidx = (eaddr & page_mask) >> target_page_bits; -#if defined(TARGET_PPC64) - if (env->mmu_model & POWERPC_MMU_64) { - htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F)); - /* XXX: this is false for 1 TB segments */ - hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask; - } else -#endif - { - htab_mask = sdr & 0x000001FF; - hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask; - } - mask = (htab_mask << sdr_sh) | sdr_mask; - LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx - " mask " TARGET_FMT_plx " " TARGET_FMT_lx "\n", - sdr, sdr_sh, hash, mask, page_mask); - ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask); - /* Secondary table address */ - hash = (~hash) & vsid_mask; - LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx - " mask " TARGET_FMT_plx "\n", sdr, sdr_sh, hash, mask); - ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask); -#if defined(TARGET_PPC64) - if (env->mmu_model & POWERPC_MMU_64) { - /* Only 5 bits of the page index are used in the AVPN */ - if (target_page_bits > 23) { - ctx->ptem = (vsid << 12) | - ((pgidx << (target_page_bits - 16)) & 0xF80); - } else { - ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80); - } - } else -#endif - { - ctx->ptem = (vsid << 7) | (pgidx >> 10); - } + LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx + " hash " TARGET_FMT_plx "\n", + env->htab_base, env->htab_mask, hash); + ctx->hash[0] = hash; + ctx->hash[1] = ~hash; + /* Initialize real address with an invalid value */ ctx->raddr = (target_phys_addr_t)-1ULL; if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx || @@ -956,19 +906,20 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx, /* Software TLB search */ ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); } else { - LOG_MMU("0 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " " - "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx - " pg_addr=" TARGET_FMT_plx "\n", - sdr, vsid, pgidx, hash, ctx->pg_addr[0]); + LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx + " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx + " hash=" TARGET_FMT_plx "\n", + env->htab_base, env->htab_mask, vsid, ctx->ptem, + ctx->hash[0]); /* Primary table lookup */ ret = find_pte(env, ctx, 0, rw, type, target_page_bits); if (ret < 0) { /* Secondary table lookup */ if (eaddr != 0xEFFFFFFF) - LOG_MMU("1 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " " - "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx - " pg_addr=" TARGET_FMT_plx "\n", sdr, vsid, - pgidx, hash, ctx->pg_addr[1]); + LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx + " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx + " hash=" TARGET_FMT_plx "\n", env->htab_base, + env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); ret2 = find_pte(env, ctx, 1, rw, type, target_page_bits); if (ret2 != -1) @@ -999,8 +950,24 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx, ret = -3; } } else { + target_ulong sr; LOG_MMU("direct store...\n"); /* Direct-store segment : absolutely *BUGGY* for now */ + + /* Direct-store implies a 32-bit MMU. + * Check the Segment Register's bus unit ID (BUID). + */ + sr = env->sr[eaddr >> 28]; + if ((sr & 0x1FF00000) >> 20 == 0x07f) { + /* Memory-forced I/O controller interface access */ + /* If T=1 and BUID=x'07F', the 601 performs a memory access + * to SR[28-31] LA[4-31], bypassing all protection mechanisms. + */ + ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF); + ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + return 0; + } + switch (type) { case ACCESS_INT: /* Integer load/store : only access allowed */ @@ -1041,10 +1008,10 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx, } /* Generic TLB check function for embedded PowerPC implementations */ -static inline int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb, - target_phys_addr_t *raddrp, - target_ulong address, uint32_t pid, int ext, - int i) +int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb, + target_phys_addr_t *raddrp, + target_ulong address, uint32_t pid, int ext, + int i) { target_ulong mask; @@ -1054,8 +1021,8 @@ static inline int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb, } mask = ~(tlb->size - 1); LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx - " " TARGET_FMT_lx " %u\n", __func__, i, address, pid, tlb->EPN, - mask, (uint32_t)tlb->PID); + " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN, + mask, (uint32_t)tlb->PID, tlb->prot); /* Check PID */ if (tlb->PID != 0 && tlb->PID != pid) return -1; @@ -1083,7 +1050,7 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid) /* Default return value is no match */ ret = -1; for (i = 0; i < env->nb_tlb; i++) { - tlb = &env->tlb[i].tlbe; + tlb = &env->tlb.tlbe[i]; if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) { ret = i; break; @@ -1100,7 +1067,7 @@ static inline void ppc4xx_tlb_invalidate_all(CPUState *env) int i; for (i = 0; i < env->nb_tlb; i++) { - tlb = &env->tlb[i].tlbe; + tlb = &env->tlb.tlbe[i]; tlb->prot &= ~PAGE_VALID; } tlb_flush(env, 1); @@ -1116,7 +1083,7 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUState *env, int i; for (i = 0; i < env->nb_tlb; i++) { - tlb = &env->tlb[i].tlbe; + tlb = &env->tlb.tlbe[i]; if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) { end = tlb->EPN + tlb->size; for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) @@ -1141,7 +1108,7 @@ static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx, raddr = (target_phys_addr_t)-1ULL; pr = msr_pr; for (i = 0; i < env->nb_tlb; i++) { - tlb = &env->tlb[i].tlbe; + tlb = &env->tlb.tlbe[i]; if (ppcemb_tlb_check(env, tlb, &raddr, address, env->spr[SPR_40x_PID], 0, i) < 0) continue; @@ -1201,52 +1168,394 @@ void store_40x_sler (CPUPPCState *env, uint32_t val) env->spr[SPR_405_SLER] = val; } +static inline int mmubooke_check_tlb (CPUState *env, ppcemb_tlb_t *tlb, + target_phys_addr_t *raddr, int *prot, + target_ulong address, int rw, + int access_type, int i) +{ + int ret, _prot; + + if (ppcemb_tlb_check(env, tlb, raddr, address, + env->spr[SPR_BOOKE_PID], + !env->nb_pids, i) >= 0) { + goto found_tlb; + } + + if (env->spr[SPR_BOOKE_PID1] && + ppcemb_tlb_check(env, tlb, raddr, address, + env->spr[SPR_BOOKE_PID1], 0, i) >= 0) { + goto found_tlb; + } + + if (env->spr[SPR_BOOKE_PID2] && + ppcemb_tlb_check(env, tlb, raddr, address, + env->spr[SPR_BOOKE_PID2], 0, i) >= 0) { + goto found_tlb; + } + + LOG_SWTLB("%s: TLB entry not found\n", __func__); + return -1; + +found_tlb: + + if (msr_pr != 0) { + _prot = tlb->prot & 0xF; + } else { + _prot = (tlb->prot >> 4) & 0xF; + } + + /* Check the address space */ + if (access_type == ACCESS_CODE) { + if (msr_ir != (tlb->attr & 1)) { + LOG_SWTLB("%s: AS doesn't match\n", __func__); + return -1; + } + + *prot = _prot; + if (_prot & PAGE_EXEC) { + LOG_SWTLB("%s: good TLB!\n", __func__); + return 0; + } + + LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot); + ret = -3; + } else { + if (msr_dr != (tlb->attr & 1)) { + LOG_SWTLB("%s: AS doesn't match\n", __func__); + return -1; + } + + *prot = _prot; + if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) { + LOG_SWTLB("%s: found TLB!\n", __func__); + return 0; + } + + LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot); + ret = -2; + } + + return ret; +} + static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong address, int rw, int access_type) { ppcemb_tlb_t *tlb; target_phys_addr_t raddr; - int i, prot, ret; + int i, ret; ret = -1; raddr = (target_phys_addr_t)-1ULL; for (i = 0; i < env->nb_tlb; i++) { - tlb = &env->tlb[i].tlbe; - if (ppcemb_tlb_check(env, tlb, &raddr, address, - env->spr[SPR_BOOKE_PID], 1, i) < 0) - continue; - if (msr_pr != 0) - prot = tlb->prot & 0xF; - else - prot = (tlb->prot >> 4) & 0xF; - /* Check the address space */ - if (access_type == ACCESS_CODE) { - if (msr_ir != (tlb->attr & 1)) - continue; - ctx->prot = prot; - if (prot & PAGE_EXEC) { - ret = 0; - break; + tlb = &env->tlb.tlbe[i]; + ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw, + access_type, i); + if (!ret) { + break; + } + } + + if (ret >= 0) { + ctx->raddr = raddr; + LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx + " %d %d\n", __func__, address, ctx->raddr, ctx->prot, + ret); + } else { + LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx + " %d %d\n", __func__, address, raddr, ctx->prot, ret); + } + + return ret; +} + +void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot) +{ + int tlb_size; + int i, j; + ppcmas_tlb_t *tlb = env->tlb.tlbm; + + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + if (flags & (1 << i)) { + tlb_size = booke206_tlb_size(env, i); + for (j = 0; j < tlb_size; j++) { + if (!check_iprot || !(tlb[j].mas1 & MAS1_IPROT)) { + tlb[j].mas1 &= ~MAS1_VALID; + } } - ret = -3; - } else { - if (msr_dr != (tlb->attr & 1)) - continue; - ctx->prot = prot; - if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) { - ret = 0; - break; + } + tlb += booke206_tlb_size(env, i); + } + + tlb_flush(env, 1); +} + +target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb) +{ + uint32_t tlbncfg; + int tlbn = booke206_tlbm_to_tlbn(env, tlb); + int tlbm_size; + + tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; + + if (tlbncfg & TLBnCFG_AVAIL) { + tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; + } else { + tlbm_size = (tlbncfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT; + tlbm_size <<= 1; + } + + return 1024ULL << tlbm_size; +} + +/* TLB check function for MAS based SoftTLBs */ +int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb, + target_phys_addr_t *raddrp, + target_ulong address, uint32_t pid) +{ + target_ulong mask; + uint32_t tlb_pid; + + /* Check valid flag */ + if (!(tlb->mas1 & MAS1_VALID)) { + return -1; + } + + mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); + LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%" + PRIx64 " mask=0x" TARGET_FMT_lx " MAS7_3=0x%" PRIx64 " MAS8=%x\n", + __func__, address, pid, tlb->mas1, tlb->mas2, mask, tlb->mas7_3, + tlb->mas8); + + /* Check PID */ + tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT; + if (tlb_pid != 0 && tlb_pid != pid) { + return -1; + } + + /* Check effective address */ + if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) { + return -1; + } + *raddrp = (tlb->mas7_3 & mask) | (address & ~mask); + + return 0; +} + +static int mmubooke206_check_tlb(CPUState *env, ppcmas_tlb_t *tlb, + target_phys_addr_t *raddr, int *prot, + target_ulong address, int rw, + int access_type) +{ + int ret; + int _prot = 0; + + if (ppcmas_tlb_check(env, tlb, raddr, address, + env->spr[SPR_BOOKE_PID]) >= 0) { + goto found_tlb; + } + + if (env->spr[SPR_BOOKE_PID1] && + ppcmas_tlb_check(env, tlb, raddr, address, + env->spr[SPR_BOOKE_PID1]) >= 0) { + goto found_tlb; + } + + if (env->spr[SPR_BOOKE_PID2] && + ppcmas_tlb_check(env, tlb, raddr, address, + env->spr[SPR_BOOKE_PID2]) >= 0) { + goto found_tlb; + } + + LOG_SWTLB("%s: TLB entry not found\n", __func__); + return -1; + +found_tlb: + + if (msr_pr != 0) { + if (tlb->mas7_3 & MAS3_UR) { + _prot |= PAGE_READ; + } + if (tlb->mas7_3 & MAS3_UW) { + _prot |= PAGE_WRITE; + } + if (tlb->mas7_3 & MAS3_UX) { + _prot |= PAGE_EXEC; + } + } else { + if (tlb->mas7_3 & MAS3_SR) { + _prot |= PAGE_READ; + } + if (tlb->mas7_3 & MAS3_SW) { + _prot |= PAGE_WRITE; + } + if (tlb->mas7_3 & MAS3_SX) { + _prot |= PAGE_EXEC; + } + } + + /* Check the address space and permissions */ + if (access_type == ACCESS_CODE) { + if (msr_ir != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { + LOG_SWTLB("%s: AS doesn't match\n", __func__); + return -1; + } + + *prot = _prot; + if (_prot & PAGE_EXEC) { + LOG_SWTLB("%s: good TLB!\n", __func__); + return 0; + } + + LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, _prot); + ret = -3; + } else { + if (msr_dr != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { + LOG_SWTLB("%s: AS doesn't match\n", __func__); + return -1; + } + + *prot = _prot; + if ((!rw && _prot & PAGE_READ) || (rw && (_prot & PAGE_WRITE))) { + LOG_SWTLB("%s: found TLB!\n", __func__); + return 0; + } + + LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, _prot); + ret = -2; + } + + return ret; +} + +static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx, + target_ulong address, int rw, + int access_type) +{ + ppcmas_tlb_t *tlb; + target_phys_addr_t raddr; + int i, j, ret; + + ret = -1; + raddr = (target_phys_addr_t)-1ULL; + + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + int ways = booke206_tlb_ways(env, i); + + for (j = 0; j < ways; j++) { + tlb = booke206_get_tlbm(env, i, address, j); + ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address, + rw, access_type); + if (ret != -1) { + goto found_tlb; } - ret = -2; } } - if (ret >= 0) + +found_tlb: + + if (ret >= 0) { ctx->raddr = raddr; + LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx + " %d %d\n", __func__, address, ctx->raddr, ctx->prot, + ret); + } else { + LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx + " %d %d\n", __func__, address, raddr, ctx->prot, ret); + } return ret; } +static const char *book3e_tsize_to_str[32] = { + "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", + "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", + "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G", + "1T", "2T" +}; + +static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf, + CPUState *env, int tlbn, int offset, + int tlbsize) +{ + ppcmas_tlb_t *entry; + int i; + + cpu_fprintf(f, "\nTLB%d:\n", tlbn); + cpu_fprintf(f, "Effective Physical Size TID TS SRWX URWX WIMGE U0123\n"); + + entry = &env->tlb.tlbm[offset]; + for (i = 0; i < tlbsize; i++, entry++) { + target_phys_addr_t ea, pa, size; + int tsize; + + if (!(entry->mas1 & MAS1_VALID)) { + continue; + } + + tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; + size = 1024ULL << tsize; + ea = entry->mas2 & ~(size - 1); + pa = entry->mas7_3 & ~(size - 1); + + cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c U%c%c%c %c%c%c%c%c U%c%c%c%c\n", + (uint64_t)ea, (uint64_t)pa, + book3e_tsize_to_str[tsize], + (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT, + (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT, + entry->mas7_3 & MAS3_SR ? 'R' : '-', + entry->mas7_3 & MAS3_SW ? 'W' : '-', + entry->mas7_3 & MAS3_SX ? 'X' : '-', + entry->mas7_3 & MAS3_UR ? 'R' : '-', + entry->mas7_3 & MAS3_UW ? 'W' : '-', + entry->mas7_3 & MAS3_UX ? 'X' : '-', + entry->mas2 & MAS2_W ? 'W' : '-', + entry->mas2 & MAS2_I ? 'I' : '-', + entry->mas2 & MAS2_M ? 'M' : '-', + entry->mas2 & MAS2_G ? 'G' : '-', + entry->mas2 & MAS2_E ? 'E' : '-', + entry->mas7_3 & MAS3_U0 ? '0' : '-', + entry->mas7_3 & MAS3_U1 ? '1' : '-', + entry->mas7_3 & MAS3_U2 ? '2' : '-', + entry->mas7_3 & MAS3_U3 ? '3' : '-'); + } +} + +static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf, + CPUState *env) +{ + int offset = 0; + int i; + + if (kvm_enabled() && !env->kvm_sw_tlb) { + cpu_fprintf(f, "Cannot access KVM TLB\n"); + return; + } + + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + int size = booke206_tlb_size(env, i); + + if (size == 0) { + continue; + } + + mmubooke206_dump_one_tlb(f, cpu_fprintf, env, i, offset, size); + offset += size; + } +} + +void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env) +{ + switch (env->mmu_model) { + case POWERPC_MMU_BOOKE206: + mmubooke206_dump_mmu(f, cpu_fprintf, env); + break; + default: + cpu_fprintf(f, "%s: unimplemented\n", __func__); + } +} + static inline int check_physical(CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw) { @@ -1268,6 +1577,7 @@ static inline int check_physical(CPUState *env, mmu_ctx_t *ctx, #if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B: + case POWERPC_MMU_2_06: /* Real address are 60 bits long */ ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL; ctx->prot |= PAGE_WRITE; @@ -1301,9 +1611,8 @@ static inline int check_physical(CPUState *env, mmu_ctx_t *ctx, /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; - case POWERPC_MMU_BOOKE_FSL: - /* XXX: TODO */ - cpu_abort(env, "BookE FSL MMU model not implemented\n"); + case POWERPC_MMU_BOOKE206: + cpu_abort(env, "BookE 2.06 MMU doesn't have physical real mode\n"); break; default: cpu_abort(env, "Unknown or invalid MMU model\n"); @@ -1328,6 +1637,9 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, IS and DS bits only affect the address space. */ ret = mmubooke_get_physical_address(env, ctx, eaddr, rw, access_type); + } else if (env->mmu_model == POWERPC_MMU_BOOKE206) { + ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, + access_type); } else { /* No address translation. */ ret = check_physical(env, ctx, eaddr, rw); @@ -1345,6 +1657,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, #if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B: + case POWERPC_MMU_2_06: #endif if (ret < 0) { /* We didn't match any BAT entry or don't have BATs */ @@ -1360,14 +1673,14 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, ret = mmubooke_get_physical_address(env, ctx, eaddr, rw, access_type); break; + case POWERPC_MMU_BOOKE206: + ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw, + access_type); + break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; - case POWERPC_MMU_BOOKE_FSL: - /* XXX: TODO */ - cpu_abort(env, "BookE FSL MMU model not implemented\n"); - return -1; case POWERPC_MMU_REAL: cpu_abort(env, "PowerPC in real mode do not do any translation\n"); return -1; @@ -1394,9 +1707,49 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) return ctx.raddr & TARGET_PAGE_MASK; } +static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address, + int rw) +{ + env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; + env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK; + env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK; + env->spr[SPR_BOOKE_MAS3] = 0; + env->spr[SPR_BOOKE_MAS6] = 0; + env->spr[SPR_BOOKE_MAS7] = 0; + + /* AS */ + if (((rw == 2) && msr_ir) || ((rw != 2) && msr_dr)) { + env->spr[SPR_BOOKE_MAS1] |= MAS1_TS; + env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS; + } + + env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID; + env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK; + + switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) { + case MAS4_TIDSELD_PID0: + env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID] << MAS1_TID_SHIFT; + break; + case MAS4_TIDSELD_PID1: + env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID1] << MAS1_TID_SHIFT; + break; + case MAS4_TIDSELD_PID2: + env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID2] << MAS1_TID_SHIFT; + break; + } + + env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16; + + /* next victim logic */ + env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT; + env->last_way++; + env->last_way &= booke206_tlb_ways(env, 0) - 1; + env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; +} + /* Perform address translation */ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { mmu_ctx_t ctx; int access_type; @@ -1444,19 +1797,19 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, #if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B: + case POWERPC_MMU_2_06: #endif env->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x40000000; break; + case POWERPC_MMU_BOOKE206: + booke206_update_mas_tlb_miss(env, address, rw); + /* fall through */ case POWERPC_MMU_BOOKE: env->exception_index = POWERPC_EXCP_ITLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; return -1; - case POWERPC_MMU_BOOKE_FSL: - /* XXX: TODO */ - cpu_abort(env, "BookE FSL MMU model is not implemented\n"); - return -1; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); @@ -1477,7 +1830,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, break; case -3: /* No execute protection violation */ - if (env->mmu_model == POWERPC_MMU_BOOKE) { + if ((env->mmu_model == POWERPC_MMU_BOOKE) || + (env->mmu_model == POWERPC_MMU_BOOKE206)) { env->spr[SPR_BOOKE_ESR] = 0x00000000; } env->exception_index = POWERPC_EXCP_ISI; @@ -1520,8 +1874,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem; tlb_miss: env->error_code |= ctx.key << 19; - env->spr[SPR_HASH1] = ctx.pg_addr[0]; - env->spr[SPR_HASH2] = ctx.pg_addr[1]; + env->spr[SPR_HASH1] = env->htab_base + + get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32); + env->spr[SPR_HASH2] = env->htab_base + + get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32); break; case POWERPC_MMU_SOFT_74xx: if (rw == 1) { @@ -1551,6 +1907,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, #if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B: + case POWERPC_MMU_2_06: #endif env->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; @@ -1564,15 +1921,14 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; + case POWERPC_MMU_BOOKE206: + booke206_update_mas_tlb_miss(env, address, rw); + /* fall through */ case POWERPC_MMU_BOOKE: env->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_BOOKE_DEAR] = address; - env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0; - return -1; - case POWERPC_MMU_BOOKE_FSL: - /* XXX: TODO */ - cpu_abort(env, "BookE FSL MMU model is not implemented\n"); + env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0; return -1; case POWERPC_MMU_REAL: cpu_abort(env, "PowerPC in real mode should never raise " @@ -1593,9 +1949,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, if (rw) { env->spr[SPR_40x_ESR] |= 0x00800000; } - } else if (env->mmu_model == POWERPC_MMU_BOOKE) { + } else if ((env->mmu_model == POWERPC_MMU_BOOKE) || + (env->mmu_model == POWERPC_MMU_BOOKE206)) { env->spr[SPR_BOOKE_DEAR] = address; - env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0; + env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0; } else { env->spr[SPR_DAR] = address; if (rw == 1) { @@ -1864,16 +2221,15 @@ void ppc_tlb_invalidate_all (CPUPPCState *env) case POWERPC_MMU_BOOKE: tlb_flush(env, 1); break; - case POWERPC_MMU_BOOKE_FSL: - /* XXX: TODO */ - if (!kvm_enabled()) - cpu_abort(env, "BookE MMU model is not implemented\n"); + case POWERPC_MMU_BOOKE206: + booke206_flush_tlb(env, -1, 0); break; case POWERPC_MMU_32B: case POWERPC_MMU_601: #if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B: + case POWERPC_MMU_2_06: #endif /* defined(TARGET_PPC64) */ tlb_flush(env, 1); break; @@ -1910,9 +2266,9 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) /* XXX: TODO */ cpu_abort(env, "BookE MMU model is not implemented\n"); break; - case POWERPC_MMU_BOOKE_FSL: + case POWERPC_MMU_BOOKE206: /* XXX: TODO */ - cpu_abort(env, "BookE FSL MMU model is not implemented\n"); + cpu_abort(env, "BookE 2.06 MMU model is not implemented\n"); break; case POWERPC_MMU_32B: case POWERPC_MMU_601: @@ -1941,6 +2297,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) #if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B: + case POWERPC_MMU_2_06: /* tlbie invalidate TLBs for all segments */ /* XXX: given the fact that there are too many segments to invalidate, * and we still don't have a tlb_flush_mask(env, n, mask) in Qemu, @@ -1974,11 +2331,26 @@ void ppc_store_asr (CPUPPCState *env, target_ulong value) void ppc_store_sdr1 (CPUPPCState *env, target_ulong value) { LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value); - if (env->sdr1 != value) { - /* XXX: for PowerPC 64, should check that the HTABSIZE value - * is <= 28 - */ - env->sdr1 = value; + if (env->spr[SPR_SDR1] != value) { + env->spr[SPR_SDR1] = value; +#if defined(TARGET_PPC64) + if (env->mmu_model & POWERPC_MMU_64) { + target_ulong htabsize = value & SDR_64_HTABSIZE; + + if (htabsize > 28) { + fprintf(stderr, "Invalid HTABSIZE 0x" TARGET_FMT_lx + " stored in SDR1\n", htabsize); + htabsize = 28; + } + env->htab_mask = (1ULL << (htabsize + 18)) - 1; + env->htab_base = value & SDR_64_HTABORG; + } else +#endif /* defined(TARGET_PPC64) */ + { + /* FIXME: Should check for valid HTABMASK values */ + env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF; + env->htab_base = value & SDR_32_HTABORG; + } tlb_flush(env, 1); } } @@ -2009,7 +2381,7 @@ void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value) /* VSID = VSID */ rs |= (value & 0xfffffff) << 12; /* flags = flags */ - rs |= ((value >> 27) & 0xf) << 9; + rs |= ((value >> 27) & 0xf) << 8; ppc_store_slb(env, rb, rs); } else @@ -2203,16 +2575,19 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) if (lpes1 == 0) new_msr |= (target_ulong)MSR_HVB; msr |= 0x00080000; + env->spr[SPR_BOOKE_ESR] = ESR_PIL; break; case POWERPC_EXCP_PRIV: if (lpes1 == 0) new_msr |= (target_ulong)MSR_HVB; msr |= 0x00040000; + env->spr[SPR_BOOKE_ESR] = ESR_PPR; break; case POWERPC_EXCP_TRAP: if (lpes1 == 0) new_msr |= (target_ulong)MSR_HVB; msr |= 0x00020000; + env->spr[SPR_BOOKE_ESR] = ESR_PTR; break; default: /* Should never occur */ @@ -2228,6 +2603,10 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) case POWERPC_EXCP_SYSCALL: /* System call exception */ dump_syscall(env); lev = env->error_code; + if ((lev == 1) && cpu_ppc_hypercall) { + cpu_ppc_hypercall(env); + return; + } if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) new_msr |= (target_ulong)MSR_HVB; goto store_next; @@ -2271,16 +2650,19 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) cpu_abort(env, "Debug exception is not implemented yet !\n"); goto store_next; case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */ + env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_current; case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ /* XXX: TODO */ cpu_abort(env, "Embedded floating point data exception " "is not implemented yet !\n"); + env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_next; case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ /* XXX: TODO */ cpu_abort(env, "Embedded floating point round exception " "is not implemented yet !\n"); + env->spr[SPR_BOOKE_ESR] = ESR_SPV; goto store_next; case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ /* XXX: TODO */ @@ -2610,7 +2992,8 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) env->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; - if (env->mmu_model == POWERPC_MMU_BOOKE) { + if ((env->mmu_model == POWERPC_MMU_BOOKE) || + (env->mmu_model == POWERPC_MMU_BOOKE206)) { /* XXX: The BookE changes address space when switching modes, we should probably implement that as different MMU indexes, but for the moment we do it the slow way and flush all. */ @@ -2803,9 +3186,20 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model) if (!def) return NULL; - env = qemu_mallocz(sizeof(CPUPPCState)); + env = g_malloc0(sizeof(CPUPPCState)); cpu_exec_init(env); - ppc_translate_init(); + if (tcg_enabled()) { + ppc_translate_init(); + } + /* Adjust cpu index for SMT */ +#if !defined(CONFIG_USER_ONLY) + if (kvm_enabled()) { + int smt = kvmppc_smt_threads(); + + env->cpu_index = (env->cpu_index / smp_threads)*smt + + (env->cpu_index % smp_threads); + } +#endif /* !CONFIG_USER_ONLY */ env->cpu_model_str = cpu_model; cpu_ppc_register_internal(env, def); @@ -2817,5 +3211,5 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model) void cpu_ppc_close (CPUPPCState *env) { /* Should also remove all opcode tables... */ - qemu_free(env); + g_free(env); } diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 2bf9283..470e42f 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -38,10 +38,11 @@ DEF_HELPER_2(mulldo, i64, i64, i64) DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) DEF_HELPER_FLAGS_1(popcntb, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) +DEF_HELPER_FLAGS_1(popcntw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) DEF_HELPER_2(sraw, tl, tl, tl) #if defined(TARGET_PPC64) DEF_HELPER_FLAGS_1(cntlzd, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) -DEF_HELPER_FLAGS_1(popcntb_64, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) +DEF_HELPER_FLAGS_1(popcntd, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl) DEF_HELPER_2(srad, tl, tl, tl) #endif @@ -50,9 +51,7 @@ DEF_HELPER_FLAGS_1(cntlzw32, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32) DEF_HELPER_FLAGS_2(brinc, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl) DEF_HELPER_0(float_check_status, void) -#ifdef CONFIG_SOFTFLOAT DEF_HELPER_0(reset_fpstatus, void) -#endif DEF_HELPER_2(compute_fprf, i32, i64, i32) DEF_HELPER_2(store_fpscr, void, i64, i32) DEF_HELPER_1(fpscr_clrbit, void, i32) @@ -333,6 +332,12 @@ DEF_HELPER_1(4xx_tlbsx, tl, tl) DEF_HELPER_2(440_tlbre, tl, i32, tl) DEF_HELPER_3(440_tlbwe, void, i32, tl, tl) DEF_HELPER_1(440_tlbsx, tl, tl) +DEF_HELPER_0(booke206_tlbre, void) +DEF_HELPER_0(booke206_tlbwe, void) +DEF_HELPER_1(booke206_tlbsx, void, tl) +DEF_HELPER_1(booke206_tlbivax, void, tl) +DEF_HELPER_1(booke206_tlbflush, void, i32) +DEF_HELPER_2(booke_setpid, void, i32, tl) DEF_HELPER_1(6xx_tlbd, void, tl) DEF_HELPER_1(6xx_tlbi, void, tl) DEF_HELPER_1(74xx_tlbd, void, tl) @@ -340,8 +345,9 @@ DEF_HELPER_1(74xx_tlbi, void, tl) DEF_HELPER_FLAGS_0(tlbia, TCG_CALL_CONST, void) DEF_HELPER_FLAGS_1(tlbie, TCG_CALL_CONST, void, tl) #if defined(TARGET_PPC64) -DEF_HELPER_FLAGS_1(load_slb, TCG_CALL_CONST, tl, tl) DEF_HELPER_FLAGS_2(store_slb, TCG_CALL_CONST, void, tl, tl) +DEF_HELPER_1(load_slb_esid, tl, tl) +DEF_HELPER_1(load_slb_vsid, tl, tl) DEF_HELPER_FLAGS_0(slbia, TCG_CALL_CONST, void) DEF_HELPER_FLAGS_1(slbie, TCG_CALL_CONST, void, tl) #endif @@ -375,6 +381,7 @@ DEF_HELPER_0(load_601_rtcu, tl) #if !defined(CONFIG_USER_ONLY) #if defined(TARGET_PPC64) DEF_HELPER_1(store_asr, void, tl) +DEF_HELPER_0(load_purr, tl) #endif DEF_HELPER_1(store_sdr1, void, tl) DEF_HELPER_1(store_tbl, void, tl) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 710eca1..0410901 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -2,6 +2,7 @@ * PowerPC implementation of KVM hooks * * Copyright IBM Corp. 2007 + * Copyright (C) 2011 Freescale Semiconductor, Inc. * * Authors: * Jerone Young @@ -13,6 +14,7 @@ * */ +#include #include #include #include @@ -26,6 +28,12 @@ #include "kvm_ppc.h" #include "cpu.h" #include "device_tree.h" +#include "hw/sysbus.h" +#include "hw/spapr.h" + +#include "hw/sysbus.h" +#include "hw/spapr.h" +#include "hw/spapr_vio.h" //#define DEBUG_KVM @@ -37,12 +45,19 @@ do { } while (0) #endif +#define PROC_DEVTREE_CPU "/proc/device-tree/cpus/" + const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; static int cap_interrupt_unset = false; static int cap_interrupt_level = false; +static int cap_segstate; +static int cap_booke_sregs; +static int cap_ppc_smt; +static int cap_ppc_rma; +static int cap_spapr_tce; /* XXX We have a race condition where we actually have a level triggered * interrupt, but the infrastructure can't expose that yet, so the guest @@ -62,12 +77,13 @@ static void kvm_kick_env(void *env) int kvm_arch_init(KVMState *s) { -#ifdef KVM_CAP_PPC_UNSET_IRQ cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ); -#endif -#ifdef KVM_CAP_PPC_IRQ_LEVEL cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL); -#endif + cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE); + cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS); + cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT); + cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA); + cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE); if (!cap_interrupt_level) { fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the " @@ -77,15 +93,98 @@ int kvm_arch_init(KVMState *s) return 0; } -int kvm_arch_init_vcpu(CPUState *cenv) +static int kvm_arch_sync_sregs(CPUState *cenv) { - int ret = 0; struct kvm_sregs sregs; + int ret; + + if (cenv->excp_model == POWERPC_EXCP_BOOKE) { + /* What we're really trying to say is "if we're on BookE, we use + the native PVR for now". This is the only sane way to check + it though, so we potentially confuse users that they can run + BookE guests on BookS. Let's hope nobody dares enough :) */ + return 0; + } else { + if (!cap_segstate) { + fprintf(stderr, "kvm error: missing PVR setting capability\n"); + return -ENOSYS; + } + } + + ret = kvm_vcpu_ioctl(cenv, KVM_GET_SREGS, &sregs); + if (ret) { + return ret; + } sregs.pvr = cenv->spr[SPR_PVR]; - ret = kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs); + return kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs); +} - idle_timer = qemu_new_timer(vm_clock, kvm_kick_env, cenv); +/* Set up a shared TLB array with KVM */ +static int kvm_booke206_tlb_init(CPUState *env) +{ + struct kvm_book3e_206_tlb_params params = {}; + struct kvm_config_tlb cfg = {}; + struct kvm_enable_cap encap = {}; + unsigned int entries = 0; + int ret, i; + + if (!kvm_enabled() || + !kvm_check_extension(env->kvm_state, KVM_CAP_SW_TLB)) { + return 0; + } + + assert(ARRAY_SIZE(params.tlb_sizes) == BOOKE206_MAX_TLBN); + + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + params.tlb_sizes[i] = booke206_tlb_size(env, i); + params.tlb_ways[i] = booke206_tlb_ways(env, i); + entries += params.tlb_sizes[i]; + } + + assert(entries == env->nb_tlb); + assert(sizeof(struct kvm_book3e_206_tlb_entry) == sizeof(ppcmas_tlb_t)); + + env->tlb_dirty = true; + + cfg.array = (uintptr_t)env->tlb.tlbm; + cfg.array_len = sizeof(ppcmas_tlb_t) * entries; + cfg.params = (uintptr_t)¶ms; + cfg.mmu_type = KVM_MMU_FSL_BOOKE_NOHV; + + encap.cap = KVM_CAP_SW_TLB; + encap.args[0] = (uintptr_t)&cfg; + + ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &encap); + if (ret < 0) { + fprintf(stderr, "%s: couldn't enable KVM_CAP_SW_TLB: %s\n", + __func__, strerror(-ret)); + return ret; + } + + env->kvm_sw_tlb = true; + return 0; +} + +int kvm_arch_init_vcpu(CPUState *cenv) +{ + int ret; + + ret = kvm_arch_sync_sregs(cenv); + if (ret) { + return ret; + } + + idle_timer = qemu_new_timer_ns(vm_clock, kvm_kick_env, cenv); + + /* Some targets support access to KVM's guest TLB. */ + switch (cenv->mmu_model) { + case POWERPC_MMU_BOOKE206: + ret = kvm_booke206_tlb_init(cenv); + break; + default: + break; + } return ret; } @@ -94,6 +193,31 @@ void kvm_arch_reset_vcpu(CPUState *env) { } +static void kvm_sw_tlb_put(CPUState *env) +{ + struct kvm_dirty_tlb dirty_tlb; + unsigned char *bitmap; + int ret; + + if (!env->kvm_sw_tlb) { + return; + } + + bitmap = g_malloc((env->nb_tlb + 7) / 8); + memset(bitmap, 0xFF, (env->nb_tlb + 7) / 8); + + dirty_tlb.bitmap = (uintptr_t)bitmap; + dirty_tlb.num_dirty = env->nb_tlb; + + ret = kvm_vcpu_ioctl(env, KVM_DIRTY_TLB, &dirty_tlb); + if (ret) { + fprintf(stderr, "%s: KVM_DIRTY_TLB: %s\n", + __func__, strerror(-ret)); + } + + g_free(bitmap); +} + int kvm_arch_put_registers(CPUState *env, int level) { struct kvm_regs regs; @@ -122,6 +246,8 @@ int kvm_arch_put_registers(CPUState *env, int level) regs.sprg6 = env->spr[SPR_SPRG6]; regs.sprg7 = env->spr[SPR_SPRG7]; + regs.pid = env->spr[SPR_BOOKE_PID]; + for (i = 0;i < 32; i++) regs.gpr[i] = env->gpr[i]; @@ -129,6 +255,11 @@ int kvm_arch_put_registers(CPUState *env, int level) if (ret < 0) return ret; + if (env->tlb_dirty) { + kvm_sw_tlb_put(env); + env->tlb_dirty = false; + } + return ret; } @@ -136,15 +267,18 @@ int kvm_arch_get_registers(CPUState *env) { struct kvm_regs regs; struct kvm_sregs sregs; + uint32_t cr; int i, ret; ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s); if (ret < 0) return ret; - ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs); - if (ret < 0) - return ret; + cr = regs.cr; + for (i = 7; i >= 0; i--) { + env->crf[i] = cr & 15; + cr >>= 4; + } env->ctr = regs.ctr; env->lr = regs.lr; @@ -164,12 +298,122 @@ int kvm_arch_get_registers(CPUState *env) env->spr[SPR_SPRG6] = regs.sprg6; env->spr[SPR_SPRG7] = regs.sprg7; + env->spr[SPR_BOOKE_PID] = regs.pid; + for (i = 0;i < 32; i++) env->gpr[i] = regs.gpr[i]; -#ifdef KVM_CAP_PPC_SEGSTATE - if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_SEGSTATE)) { - env->sdr1 = sregs.u.s.sdr1; + if (cap_booke_sregs) { + ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs); + if (ret < 0) { + return ret; + } + + if (sregs.u.e.features & KVM_SREGS_E_BASE) { + env->spr[SPR_BOOKE_CSRR0] = sregs.u.e.csrr0; + env->spr[SPR_BOOKE_CSRR1] = sregs.u.e.csrr1; + env->spr[SPR_BOOKE_ESR] = sregs.u.e.esr; + env->spr[SPR_BOOKE_DEAR] = sregs.u.e.dear; + env->spr[SPR_BOOKE_MCSR] = sregs.u.e.mcsr; + env->spr[SPR_BOOKE_TSR] = sregs.u.e.tsr; + env->spr[SPR_BOOKE_TCR] = sregs.u.e.tcr; + env->spr[SPR_DECR] = sregs.u.e.dec; + env->spr[SPR_TBL] = sregs.u.e.tb & 0xffffffff; + env->spr[SPR_TBU] = sregs.u.e.tb >> 32; + env->spr[SPR_VRSAVE] = sregs.u.e.vrsave; + } + + if (sregs.u.e.features & KVM_SREGS_E_ARCH206) { + env->spr[SPR_BOOKE_PIR] = sregs.u.e.pir; + env->spr[SPR_BOOKE_MCSRR0] = sregs.u.e.mcsrr0; + env->spr[SPR_BOOKE_MCSRR1] = sregs.u.e.mcsrr1; + env->spr[SPR_BOOKE_DECAR] = sregs.u.e.decar; + env->spr[SPR_BOOKE_IVPR] = sregs.u.e.ivpr; + } + + if (sregs.u.e.features & KVM_SREGS_E_64) { + env->spr[SPR_BOOKE_EPCR] = sregs.u.e.epcr; + } + + if (sregs.u.e.features & KVM_SREGS_E_SPRG8) { + env->spr[SPR_BOOKE_SPRG8] = sregs.u.e.sprg8; + } + + if (sregs.u.e.features & KVM_SREGS_E_IVOR) { + env->spr[SPR_BOOKE_IVOR0] = sregs.u.e.ivor_low[0]; + env->spr[SPR_BOOKE_IVOR1] = sregs.u.e.ivor_low[1]; + env->spr[SPR_BOOKE_IVOR2] = sregs.u.e.ivor_low[2]; + env->spr[SPR_BOOKE_IVOR3] = sregs.u.e.ivor_low[3]; + env->spr[SPR_BOOKE_IVOR4] = sregs.u.e.ivor_low[4]; + env->spr[SPR_BOOKE_IVOR5] = sregs.u.e.ivor_low[5]; + env->spr[SPR_BOOKE_IVOR6] = sregs.u.e.ivor_low[6]; + env->spr[SPR_BOOKE_IVOR7] = sregs.u.e.ivor_low[7]; + env->spr[SPR_BOOKE_IVOR8] = sregs.u.e.ivor_low[8]; + env->spr[SPR_BOOKE_IVOR9] = sregs.u.e.ivor_low[9]; + env->spr[SPR_BOOKE_IVOR10] = sregs.u.e.ivor_low[10]; + env->spr[SPR_BOOKE_IVOR11] = sregs.u.e.ivor_low[11]; + env->spr[SPR_BOOKE_IVOR12] = sregs.u.e.ivor_low[12]; + env->spr[SPR_BOOKE_IVOR13] = sregs.u.e.ivor_low[13]; + env->spr[SPR_BOOKE_IVOR14] = sregs.u.e.ivor_low[14]; + env->spr[SPR_BOOKE_IVOR15] = sregs.u.e.ivor_low[15]; + + if (sregs.u.e.features & KVM_SREGS_E_SPE) { + env->spr[SPR_BOOKE_IVOR32] = sregs.u.e.ivor_high[0]; + env->spr[SPR_BOOKE_IVOR33] = sregs.u.e.ivor_high[1]; + env->spr[SPR_BOOKE_IVOR34] = sregs.u.e.ivor_high[2]; + } + + if (sregs.u.e.features & KVM_SREGS_E_PM) { + env->spr[SPR_BOOKE_IVOR35] = sregs.u.e.ivor_high[3]; + } + + if (sregs.u.e.features & KVM_SREGS_E_PC) { + env->spr[SPR_BOOKE_IVOR36] = sregs.u.e.ivor_high[4]; + env->spr[SPR_BOOKE_IVOR37] = sregs.u.e.ivor_high[5]; + } + } + + if (sregs.u.e.features & KVM_SREGS_E_ARCH206_MMU) { + env->spr[SPR_BOOKE_MAS0] = sregs.u.e.mas0; + env->spr[SPR_BOOKE_MAS1] = sregs.u.e.mas1; + env->spr[SPR_BOOKE_MAS2] = sregs.u.e.mas2; + env->spr[SPR_BOOKE_MAS3] = sregs.u.e.mas7_3 & 0xffffffff; + env->spr[SPR_BOOKE_MAS4] = sregs.u.e.mas4; + env->spr[SPR_BOOKE_MAS6] = sregs.u.e.mas6; + env->spr[SPR_BOOKE_MAS7] = sregs.u.e.mas7_3 >> 32; + env->spr[SPR_MMUCFG] = sregs.u.e.mmucfg; + env->spr[SPR_BOOKE_TLB0CFG] = sregs.u.e.tlbcfg[0]; + env->spr[SPR_BOOKE_TLB1CFG] = sregs.u.e.tlbcfg[1]; + } + + if (sregs.u.e.features & KVM_SREGS_EXP) { + env->spr[SPR_BOOKE_EPR] = sregs.u.e.epr; + } + + if (sregs.u.e.features & KVM_SREGS_E_PD) { + env->spr[SPR_BOOKE_EPLC] = sregs.u.e.eplc; + env->spr[SPR_BOOKE_EPSC] = sregs.u.e.epsc; + } + + if (sregs.u.e.impl_id == KVM_SREGS_E_IMPL_FSL) { + env->spr[SPR_E500_SVR] = sregs.u.e.impl.fsl.svr; + env->spr[SPR_Exxx_MCAR] = sregs.u.e.impl.fsl.mcar; + env->spr[SPR_HID0] = sregs.u.e.impl.fsl.hid0; + + if (sregs.u.e.impl.fsl.features & KVM_SREGS_E_FSL_PIDn) { + env->spr[SPR_BOOKE_PID1] = sregs.u.e.impl.fsl.pid1; + env->spr[SPR_BOOKE_PID2] = sregs.u.e.impl.fsl.pid2; + } + } + } + + if (cap_segstate) { + ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs); + if (ret < 0) { + return ret; + } + + ppc_store_sdr1(env, sregs.u.s.sdr1); /* Sync SLB */ #ifdef TARGET_PPC64 @@ -192,7 +436,6 @@ int kvm_arch_get_registers(CPUState *env) env->IBAT[1][i] = sregs.u.s.ppc32.ibat[i] >> 32; } } -#endif return 0; } @@ -222,7 +465,7 @@ int kvmppc_set_interrupt(CPUState *env, int irq, int level) #define PPC_INPUT_INT PPC6xx_INPUT_INT #endif -int kvm_arch_pre_run(CPUState *env, struct kvm_run *run) +void kvm_arch_pre_run(CPUState *env, struct kvm_run *run) { int r; unsigned irq; @@ -246,24 +489,22 @@ int kvm_arch_pre_run(CPUState *env, struct kvm_run *run) printf("cpu %d fail inject %x\n", env->cpu_index, irq); /* Always wake up soon in case the interrupt was level based */ - qemu_mod_timer(idle_timer, qemu_get_clock(vm_clock) + + qemu_mod_timer(idle_timer, qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 50)); } /* We don't know if there are more interrupts pending after this. However, * the guest will return to userspace in the course of handling this one * anyways, so we will get a chance to deliver the rest. */ - return 0; } -int kvm_arch_post_run(CPUState *env, struct kvm_run *run) +void kvm_arch_post_run(CPUState *env, struct kvm_run *run) { - return 0; } -int kvm_arch_process_irqchip_events(CPUState *env) +int kvm_arch_process_async_events(CPUState *env) { - return 0; + return env->halted; } static int kvmppc_handle_halt(CPUState *env) @@ -273,7 +514,7 @@ static int kvmppc_handle_halt(CPUState *env) env->exception_index = EXCP_HLT; } - return 1; + return 0; } /* map dcr access to existing qemu dcr emulation */ @@ -282,7 +523,7 @@ static int kvmppc_handle_dcr_read(CPUState *env, uint32_t dcrn, uint32_t *data) if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0) fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn); - return 1; + return 0; } static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data) @@ -290,12 +531,12 @@ static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data) if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0) fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn); - return 1; + return 0; } int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run) { - int ret = 0; + int ret; switch (run->exit_reason) { case KVM_EXIT_DCR: @@ -311,6 +552,14 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run) dprintf("handle halt\n"); ret = kvmppc_handle_halt(env); break; +#ifdef CONFIG_PSERIES + case KVM_EXIT_PAPR_HCALL: + dprintf("handle PAPR hypercall\n"); + run->papr_hcall.ret = spapr_hypercall(env, run->papr_hcall.nr, + run->papr_hcall.args); + ret = 1; + break; +#endif default: fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); ret = -1; @@ -368,11 +617,97 @@ uint32_t kvmppc_get_tbfreq(void) return retval; } +/* Try to find a device tree node for a CPU with clock-frequency property */ +static int kvmppc_find_cpu_dt(char *buf, int buf_len) +{ + struct dirent *dirp; + DIR *dp; + + if ((dp = opendir(PROC_DEVTREE_CPU)) == NULL) { + printf("Can't open directory " PROC_DEVTREE_CPU "\n"); + return -1; + } + + buf[0] = '\0'; + while ((dirp = readdir(dp)) != NULL) { + FILE *f; + snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU, + dirp->d_name); + f = fopen(buf, "r"); + if (f) { + snprintf(buf, buf_len, "%s%s", PROC_DEVTREE_CPU, dirp->d_name); + fclose(f); + break; + } + buf[0] = '\0'; + } + closedir(dp); + if (buf[0] == '\0') { + printf("Unknown host!\n"); + return -1; + } + + return 0; +} + +/* Read a CPU node property from the host device tree that's a single + * integer (32-bit or 64-bit). Returns 0 if anything goes wrong + * (can't find or open the property, or doesn't understand the + * format) */ +static uint64_t kvmppc_read_int_cpu_dt(const char *propname) +{ + char buf[PATH_MAX]; + union { + uint32_t v32; + uint64_t v64; + } u; + FILE *f; + int len; + + if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { + return -1; + } + + strncat(buf, "/", sizeof(buf) - strlen(buf)); + strncat(buf, propname, sizeof(buf) - strlen(buf)); + + f = fopen(buf, "rb"); + if (!f) { + return -1; + } + + len = fread(&u, 1, sizeof(u), f); + fclose(f); + switch (len) { + case 4: + /* property is a 32-bit quantity */ + return be32_to_cpu(u.v32); + case 8: + return be64_to_cpu(u.v64); + } + + return 0; +} + +uint64_t kvmppc_get_clockfreq(void) +{ + return kvmppc_read_int_cpu_dt("clock-frequency"); +} + +uint32_t kvmppc_get_vmx(void) +{ + return kvmppc_read_int_cpu_dt("ibm,vmx"); +} + +uint32_t kvmppc_get_dfp(void) +{ + return kvmppc_read_int_cpu_dt("ibm,dfp"); +} + int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) { uint32_t *hc = (uint32_t*)buf; -#ifdef KVM_CAP_PPC_GET_PVINFO struct kvm_ppc_pvinfo pvinfo; if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_GET_PVINFO) && @@ -381,7 +716,6 @@ int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) return 0; } -#endif /* * Fallback to always fail hypercalls: @@ -400,7 +734,216 @@ int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) return 0; } +void kvmppc_set_papr(CPUState *env) +{ + struct kvm_enable_cap cap = {}; + struct kvm_one_reg reg = {}; + struct kvm_sregs sregs = {}; + int ret; + + cap.cap = KVM_CAP_PPC_PAPR; + ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &cap); + + if (ret) { + goto fail; + } + + /* + * XXX We set HIOR here. It really should be a qdev property of + * the CPU node, but we don't have CPUs converted to qdev yet. + * + * Once we have qdev CPUs, move HIOR to a qdev property and + * remove this chunk. + */ + reg.id = KVM_ONE_REG_PPC_HIOR; + reg.u.reg64 = env->spr[SPR_HIOR]; + ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, ®); + if (ret) { + goto fail; + } + + /* Set SDR1 so kernel space finds the HTAB */ + ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs); + if (ret) { + goto fail; + } + + sregs.u.s.sdr1 = env->spr[SPR_SDR1]; + + ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs); + if (ret) { + goto fail; + } + + return; + +fail: + cpu_abort(env, "This KVM version does not support PAPR\n"); +} + +int kvmppc_smt_threads(void) +{ + return cap_ppc_smt ? cap_ppc_smt : 1; +} + +off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem) +{ + void *rma; + off_t size; + int fd; + struct kvm_allocate_rma ret; + MemoryRegion *rma_region; + + /* If cap_ppc_rma == 0, contiguous RMA allocation is not supported + * if cap_ppc_rma == 1, contiguous RMA allocation is supported, but + * not necessary on this hardware + * if cap_ppc_rma == 2, contiguous RMA allocation is needed on this hardware + * + * FIXME: We should allow the user to force contiguous RMA + * allocation in the cap_ppc_rma==1 case. + */ + if (cap_ppc_rma < 2) { + return 0; + } + + fd = kvm_vm_ioctl(kvm_state, KVM_ALLOCATE_RMA, &ret); + if (fd < 0) { + fprintf(stderr, "KVM: Error on KVM_ALLOCATE_RMA: %s\n", + strerror(errno)); + return -1; + } + + size = MIN(ret.rma_size, 256ul << 20); + + rma = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (rma == MAP_FAILED) { + fprintf(stderr, "KVM: Error mapping RMA: %s\n", strerror(errno)); + return -1; + }; + + rma_region = g_new(MemoryRegion, 1); + memory_region_init_ram_ptr(rma_region, NULL, name, size, rma); + memory_region_add_subregion(sysmem, 0, rma_region); + + return size; +} + +void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd) +{ + struct kvm_create_spapr_tce args = { + .liobn = liobn, + .window_size = window_size, + }; + long len; + int fd; + void *table; + + /* Must set fd to -1 so we don't try to munmap when called for + * destroying the table, which the upper layers -will- do + */ + *pfd = -1; + if (!cap_spapr_tce) { + return NULL; + } + + fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args); + if (fd < 0) { + fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n", + liobn); + return NULL; + } + + len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE) * sizeof(VIOsPAPR_RTCE); + /* FIXME: round this up to page size */ + + table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (table == MAP_FAILED) { + fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n", + liobn); + close(fd); + return NULL; + } + + *pfd = fd; + return table; +} + +int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size) +{ + long len; + + if (fd < 0) { + return -1; + } + + len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE); + if ((munmap(table, len) < 0) || + (close(fd) < 0)) { + fprintf(stderr, "KVM: Unexpected error removing TCE table: %s", + strerror(errno)); + /* Leak the table */ + } + + return 0; +} + +static inline uint32_t mfpvr(void) +{ + uint32_t pvr; + + asm ("mfpvr %0" + : "=r"(pvr)); + return pvr; +} + +static void alter_insns(uint64_t *word, uint64_t flags, bool on) +{ + if (on) { + *word |= flags; + } else { + *word &= ~flags; + } +} + +const ppc_def_t *kvmppc_host_cpu_def(void) +{ + uint32_t host_pvr = mfpvr(); + const ppc_def_t *base_spec; + ppc_def_t *spec; + uint32_t vmx = kvmppc_get_vmx(); + uint32_t dfp = kvmppc_get_dfp(); + + base_spec = ppc_find_by_pvr(host_pvr); + + spec = g_malloc0(sizeof(*spec)); + memcpy(spec, base_spec, sizeof(*spec)); + + /* Now fix up the spec with information we can query from the host */ + + if (vmx != -1) { + /* Only override when we know what the host supports */ + alter_insns(&spec->insns_flags, PPC_ALTIVEC, vmx > 0); + alter_insns(&spec->insns_flags2, PPC2_VSX, vmx > 1); + } + if (dfp != -1) { + /* Only override when we know what the host supports */ + alter_insns(&spec->insns_flags2, PPC2_DFP, dfp); + } + + return spec; +} + bool kvm_arch_stop_on_emulation_error(CPUState *env) { return true; } + +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ + return 1; +} + +int kvm_arch_on_sigbus(int code, void *addr) +{ + return 1; +} diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c index 6f0468c..24fc6bc 100644 --- a/target-ppc/kvm_ppc.c +++ b/target-ppc/kvm_ppc.c @@ -21,75 +21,10 @@ static QEMUTimer *kvmppc_timer; static unsigned int kvmppc_timer_rate; -#ifdef CONFIG_FDT -int kvmppc_read_host_property(const char *node_path, const char *prop, - void *val, size_t len) -{ - char *path; - FILE *f; - int ret = 0; - int pathlen; - - pathlen = snprintf(NULL, 0, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop) - + 1; - path = qemu_malloc(pathlen); - - snprintf(path, pathlen, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop); - - f = fopen(path, "rb"); - if (f == NULL) { - ret = errno; - goto free; - } - - len = fread(val, len, 1, f); - if (len != 1) { - ret = ferror(f); - goto close; - } - -close: - fclose(f); -free: - free(path); - return ret; -} - -static int kvmppc_copy_host_cell(void *fdt, const char *node, const char *prop) -{ - uint32_t cell; - int ret; - - ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell)); - if (ret < 0) { - fprintf(stderr, "couldn't read host %s/%s\n", node, prop); - goto out; - } - - ret = qemu_devtree_setprop_cell(fdt, node, prop, cell); - if (ret < 0) { - fprintf(stderr, "couldn't set guest %s/%s\n", node, prop); - goto out; - } - -out: - return ret; -} - -void kvmppc_fdt_update(void *fdt) -{ - /* Copy data from the host device tree into the guest. Since the guest can - * directly access the timebase without host involvement, we must expose - * the correct frequencies. */ - kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "clock-frequency"); - kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "timebase-frequency"); -} -#endif - static void kvmppc_timer_hack(void *opaque) { - qemu_service_io(); - qemu_mod_timer(kvmppc_timer, qemu_get_clock(vm_clock) + kvmppc_timer_rate); + qemu_notify_event(); + qemu_mod_timer(kvmppc_timer, qemu_get_clock_ns(vm_clock) + kvmppc_timer_rate); } void kvmppc_init(void) @@ -99,7 +34,7 @@ void kvmppc_init(void) * run. So, until Qemu gains IO threads, we create this timer to ensure * that the device model gets a chance to run. */ kvmppc_timer_rate = get_ticks_per_sec() / 10; - kvmppc_timer = qemu_new_timer(vm_clock, &kvmppc_timer_hack, NULL); - qemu_mod_timer(kvmppc_timer, qemu_get_clock(vm_clock) + kvmppc_timer_rate); + kvmppc_timer = qemu_new_timer_ns(vm_clock, &kvmppc_timer_hack, NULL); + qemu_mod_timer(kvmppc_timer, qemu_get_clock_ns(vm_clock) + kvmppc_timer_rate); } diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 911b19e..f9c0198 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -9,14 +9,104 @@ #ifndef __KVM_PPC_H__ #define __KVM_PPC_H__ +#include "memory.h" + void kvmppc_init(void); -void kvmppc_fdt_update(void *fdt); -int kvmppc_read_host_property(const char *node_path, const char *prop, - void *val, size_t len); + +#ifdef CONFIG_KVM uint32_t kvmppc_get_tbfreq(void); +uint64_t kvmppc_get_clockfreq(void); +uint32_t kvmppc_get_vmx(void); +uint32_t kvmppc_get_dfp(void); int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len); int kvmppc_set_interrupt(CPUState *env, int irq, int level); +void kvmppc_set_papr(CPUState *env); +int kvmppc_smt_threads(void); +#ifndef CONFIG_USER_ONLY +off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem); +void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd); +int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size); +#endif /* !CONFIG_USER_ONLY */ +const ppc_def_t *kvmppc_host_cpu_def(void); + +#else + +static inline uint32_t kvmppc_get_tbfreq(void) +{ + return 0; +} + +static inline uint64_t kvmppc_get_clockfreq(void) +{ + return 0; +} + +static inline uint32_t kvmppc_get_vmx(void) +{ + return 0; +} + +static inline uint32_t kvmppc_get_dfp(void) +{ + return 0; +} + +static inline int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) +{ + return -1; +} + +static inline int kvmppc_set_interrupt(CPUState *env, int irq, int level) +{ + return -1; +} + +static inline void kvmppc_set_papr(CPUState *env) +{ +} + +static inline int kvmppc_smt_threads(void) +{ + return 1; +} + +#ifndef CONFIG_USER_ONLY +static inline off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem) +{ + return 0; +} + +static inline void *kvmppc_create_spapr_tce(uint32_t liobn, + uint32_t window_size, int *fd) +{ + return NULL; +} + +static inline int kvmppc_remove_spapr_tce(void *table, int pfd, + uint32_t window_size) +{ + return -1; +} +#endif /* !CONFIG_USER_ONLY */ + +static inline const ppc_def_t *kvmppc_host_cpu_def(void) +{ + return NULL; +} + +#endif + +#ifndef CONFIG_KVM +#define kvmppc_eieio() do { } while (0) +#else +#define kvmppc_eieio() \ + do { \ + if (kvm_enabled()) { \ + asm volatile("eieio" : : : "memory"); \ + } \ + } while (0) +#endif #ifndef KVM_INTERRUPT_SET #define KVM_INTERRUPT_SET -1 diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 67de951..1c40d43 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -37,7 +37,7 @@ void cpu_save(QEMUFile *f, void *opaque) qemu_put_betls(f, &env->asr); qemu_put_sbe32s(f, &env->slb_nr); #endif - qemu_put_betls(f, &env->sdr1); + qemu_put_betls(f, &env->spr[SPR_SDR1]); for (i = 0; i < 32; i++) qemu_put_betls(f, &env->sr[i]); for (i = 0; i < 2; i++) @@ -52,12 +52,12 @@ void cpu_save(QEMUFile *f, void *opaque) qemu_put_sbe32s(f, &env->last_way); qemu_put_sbe32s(f, &env->id_tlbs); qemu_put_sbe32s(f, &env->nb_pids); - if (env->tlb) { + if (env->tlb.tlb6) { // XXX assumes 6xx for (i = 0; i < env->nb_tlb; i++) { - qemu_put_betls(f, &env->tlb[i].tlb6.pte0); - qemu_put_betls(f, &env->tlb[i].tlb6.pte1); - qemu_put_betls(f, &env->tlb[i].tlb6.EPN); + qemu_put_betls(f, &env->tlb.tlb6[i].pte0); + qemu_put_betls(f, &env->tlb.tlb6[i].pte1); + qemu_put_betls(f, &env->tlb.tlb6[i].EPN); } } for (i = 0; i < 4; i++) @@ -93,6 +93,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) { CPUState *env = (CPUState *)opaque; unsigned int i, j; + target_ulong sdr1; for (i = 0; i < 32; i++) qemu_get_betls(f, &env->gpr[i]); @@ -124,7 +125,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) qemu_get_betls(f, &env->asr); qemu_get_sbe32s(f, &env->slb_nr); #endif - qemu_get_betls(f, &env->sdr1); + qemu_get_betls(f, &sdr1); for (i = 0; i < 32; i++) qemu_get_betls(f, &env->sr[i]); for (i = 0; i < 2; i++) @@ -139,12 +140,12 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) qemu_get_sbe32s(f, &env->last_way); qemu_get_sbe32s(f, &env->id_tlbs); qemu_get_sbe32s(f, &env->nb_pids); - if (env->tlb) { + if (env->tlb.tlb6) { // XXX assumes 6xx for (i = 0; i < env->nb_tlb; i++) { - qemu_get_betls(f, &env->tlb[i].tlb6.pte0); - qemu_get_betls(f, &env->tlb[i].tlb6.pte1); - qemu_get_betls(f, &env->tlb[i].tlb6.EPN); + qemu_get_betls(f, &env->tlb.tlb6[i].pte0); + qemu_get_betls(f, &env->tlb.tlb6[i].pte1); + qemu_get_betls(f, &env->tlb.tlb6[i].EPN); } } for (i = 0; i < 4; i++) @@ -152,6 +153,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) #endif for (i = 0; i < 1024; i++) qemu_get_betls(f, &env->spr[i]); + ppc_store_sdr1(env, sdr1); qemu_get_be32s(f, &env->vscr); qemu_get_be64s(f, &env->spe_acc); qemu_get_be32s(f, &env->spe_fscr); diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 17e070a..134b0c6 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -17,12 +17,17 @@ * License along with this library; if not, see . */ #include -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "host-utils.h" #include "helper.h" #include "helper_regs.h" +#if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" +#endif /* !defined(CONFIG_USER_ONLY) */ + //#define DEBUG_OP //#define DEBUG_EXCEPTIONS //#define DEBUG_SOFTWARE_TLB @@ -44,7 +49,7 @@ void helper_raise_exception_err (uint32_t exception, uint32_t error_code) #endif env->exception_index = exception; env->error_code = error_code; - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_raise_exception (uint32_t exception) @@ -86,6 +91,13 @@ target_ulong helper_load_atbu (void) return cpu_ppc_load_atbu(env); } +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) +target_ulong helper_load_purr (void) +{ + return (target_ulong)cpu_ppc_load_purr(env); +} +#endif + target_ulong helper_load_601_rtcl (void) { return cpu_ppc601_load_rtcl(env); @@ -355,7 +367,6 @@ void helper_icbi(target_ulong addr) * do the load "by hand". */ ldl(addr); - tb_invalidate_page_range(addr, addr + env->icache_line_size); } // XXX: to be tested @@ -492,6 +503,38 @@ target_ulong helper_srad (target_ulong value, target_ulong shift) } #endif +#if defined(TARGET_PPC64) +target_ulong helper_popcntb (target_ulong val) +{ + val = (val & 0x5555555555555555ULL) + ((val >> 1) & + 0x5555555555555555ULL); + val = (val & 0x3333333333333333ULL) + ((val >> 2) & + 0x3333333333333333ULL); + val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & + 0x0f0f0f0f0f0f0f0fULL); + return val; +} + +target_ulong helper_popcntw (target_ulong val) +{ + val = (val & 0x5555555555555555ULL) + ((val >> 1) & + 0x5555555555555555ULL); + val = (val & 0x3333333333333333ULL) + ((val >> 2) & + 0x3333333333333333ULL); + val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & + 0x0f0f0f0f0f0f0f0fULL); + val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & + 0x00ff00ff00ff00ffULL); + val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & + 0x0000ffff0000ffffULL); + return val; +} + +target_ulong helper_popcntd (target_ulong val) +{ + return ctpop64(val); +} +#else target_ulong helper_popcntb (target_ulong val) { val = (val & 0x55555555) + ((val >> 1) & 0x55555555); @@ -500,12 +543,13 @@ target_ulong helper_popcntb (target_ulong val) return val; } -#if defined(TARGET_PPC64) -target_ulong helper_popcntb_64 (target_ulong val) +target_ulong helper_popcntw (target_ulong val) { - val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL); - val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); - val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL); + val = (val & 0x55555555) + ((val >> 1) & 0x55555555); + val = (val & 0x33333333) + ((val >> 2) & 0x33333333); + val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f); + val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff); + val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff); return val; } #endif @@ -932,7 +976,6 @@ void helper_store_fpscr (uint64_t arg, uint32_t mask) void helper_float_check_status (void) { -#ifdef CONFIG_SOFTFLOAT if (env->exception_index == POWERPC_EXCP_PROGRAM && (env->error_code & POWERPC_EXCP_FP)) { /* Differred floating-point exception after target FPR update */ @@ -950,22 +993,12 @@ void helper_float_check_status (void) float_inexact_excp(); } } -#else - if (env->exception_index == POWERPC_EXCP_PROGRAM && - (env->error_code & POWERPC_EXCP_FP)) { - /* Differred floating-point exception after target FPR update */ - if (msr_fe0 != 0 || msr_fe1 != 0) - helper_raise_exception_err(env->exception_index, env->error_code); - } -#endif } -#ifdef CONFIG_SOFTFLOAT void helper_reset_fpstatus (void) { set_float_exception_flags(0, &env->fp_status); } -#endif /* fadd - fadd. */ uint64_t helper_fadd (uint64_t arg1, uint64_t arg2) @@ -1247,7 +1280,6 @@ uint64_t helper_fmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* sNaN operation */ fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); } -#ifdef FLOAT128 /* This is the way the PowerPC specification defines it */ float128 ft0_128, ft1_128; @@ -1263,10 +1295,6 @@ uint64_t helper_fmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status); farg1.d = float128_to_float64(ft0_128, &env->fp_status); } -#else - /* This is OK on x86 hosts */ - farg1.d = (farg1.d * farg2.d) + farg3.d; -#endif } return farg1.ll; @@ -1292,7 +1320,6 @@ uint64_t helper_fmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* sNaN operation */ fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); } -#ifdef FLOAT128 /* This is the way the PowerPC specification defines it */ float128 ft0_128, ft1_128; @@ -1308,10 +1335,6 @@ uint64_t helper_fmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status); farg1.d = float128_to_float64(ft0_128, &env->fp_status); } -#else - /* This is OK on x86 hosts */ - farg1.d = (farg1.d * farg2.d) - farg3.d; -#endif } return farg1.ll; } @@ -1336,7 +1359,6 @@ uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* sNaN operation */ fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); } -#ifdef FLOAT128 /* This is the way the PowerPC specification defines it */ float128 ft0_128, ft1_128; @@ -1352,10 +1374,6 @@ uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status); farg1.d = float128_to_float64(ft0_128, &env->fp_status); } -#else - /* This is OK on x86 hosts */ - farg1.d = (farg1.d * farg2.d) + farg3.d; -#endif if (likely(!float64_is_any_nan(farg1.d))) { farg1.d = float64_chs(farg1.d); } @@ -1383,7 +1401,6 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* sNaN operation */ fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); } -#ifdef FLOAT128 /* This is the way the PowerPC specification defines it */ float128 ft0_128, ft1_128; @@ -1399,10 +1416,6 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status); farg1.d = float128_to_float64(ft0_128, &env->fp_status); } -#else - /* This is OK on x86 hosts */ - farg1.d = (farg1.d * farg2.d) - farg3.d; -#endif if (likely(!float64_is_any_nan(farg1.d))) { farg1.d = float64_chs(farg1.d); } @@ -3323,7 +3336,7 @@ HELPER_SPE_VECTOR_ARITH(fsmul); HELPER_SPE_VECTOR_ARITH(fsdiv); /* Single-precision floating-point comparisons */ -static inline uint32_t efststlt(uint32_t op1, uint32_t op2) +static inline uint32_t efscmplt(uint32_t op1, uint32_t op2) { CPU_FloatU u1, u2; u1.l = op1; @@ -3331,7 +3344,7 @@ static inline uint32_t efststlt(uint32_t op1, uint32_t op2) return float32_lt(u1.f, u2.f, &env->vec_status) ? 4 : 0; } -static inline uint32_t efststgt(uint32_t op1, uint32_t op2) +static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2) { CPU_FloatU u1, u2; u1.l = op1; @@ -3339,7 +3352,7 @@ static inline uint32_t efststgt(uint32_t op1, uint32_t op2) return float32_le(u1.f, u2.f, &env->vec_status) ? 0 : 4; } -static inline uint32_t efststeq(uint32_t op1, uint32_t op2) +static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2) { CPU_FloatU u1, u2; u1.l = op1; @@ -3347,22 +3360,22 @@ static inline uint32_t efststeq(uint32_t op1, uint32_t op2) return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0; } -static inline uint32_t efscmplt(uint32_t op1, uint32_t op2) +static inline uint32_t efststlt(uint32_t op1, uint32_t op2) { - /* XXX: TODO: test special values (NaN, infinites, ...) */ - return efststlt(op1, op2); + /* XXX: TODO: ignore special values (NaN, infinites, ...) */ + return efscmplt(op1, op2); } -static inline uint32_t efscmpgt(uint32_t op1, uint32_t op2) +static inline uint32_t efststgt(uint32_t op1, uint32_t op2) { - /* XXX: TODO: test special values (NaN, infinites, ...) */ - return efststgt(op1, op2); + /* XXX: TODO: ignore special values (NaN, infinites, ...) */ + return efscmpgt(op1, op2); } -static inline uint32_t efscmpeq(uint32_t op1, uint32_t op2) +static inline uint32_t efststeq(uint32_t op1, uint32_t op2) { - /* XXX: TODO: test special values (NaN, infinites, ...) */ - return efststeq(op1, op2); + /* XXX: TODO: ignore special values (NaN, infinites, ...) */ + return efscmpeq(op1, op2); } #define HELPER_SINGLE_SPE_CMP(name) \ @@ -3658,7 +3671,7 @@ uint32_t helper_efdtsteq (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - return float64_eq(u1.d, u2.d, &env->vec_status) ? 4 : 0; + return float64_eq_quiet(u1.d, u2.d, &env->vec_status) ? 4 : 0; } uint32_t helper_efdcmplt (uint64_t op1, uint64_t op2) @@ -3701,18 +3714,17 @@ uint32_t helper_efdcmpeq (uint64_t op1, uint64_t op2) NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { TranslationBlock *tb; CPUState *saved_env; unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; - ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + env = env1; + ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ @@ -3721,7 +3733,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (likely(tb)) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } helper_raise_exception_err(env->exception_index, env->error_code); @@ -3746,14 +3758,31 @@ void helper_store_sr (target_ulong sr_num, target_ulong val) /* SLB management */ #if defined(TARGET_PPC64) -target_ulong helper_load_slb (target_ulong slb_nr) +void helper_store_slb (target_ulong rb, target_ulong rs) +{ + if (ppc_store_slb(env, rb, rs) < 0) { + helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL); + } +} + +target_ulong helper_load_slb_esid (target_ulong rb) { - return ppc_load_slb(env, slb_nr); + target_ulong rt; + + if (ppc_load_slb_esid(env, rb, &rt) < 0) { + helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL); + } + return rt; } -void helper_store_slb (target_ulong rb, target_ulong rs) +target_ulong helper_load_slb_vsid (target_ulong rb) { - ppc_store_slb(env, rb, rs); + target_ulong rt; + + if (ppc_load_slb_vsid(env, rb, &rt) < 0) { + helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL); + } + return rt; } void helper_slbia (void) @@ -3934,7 +3963,7 @@ target_ulong helper_4xx_tlbre_hi (target_ulong entry) int size; entry &= PPC4XX_TLB_ENTRY_MASK; - tlb = &env->tlb[entry].tlbe; + tlb = &env->tlb.tlbe[entry]; ret = tlb->EPN; if (tlb->prot & PAGE_VALID) { ret |= PPC4XX_TLBHI_V; @@ -3954,7 +3983,7 @@ target_ulong helper_4xx_tlbre_lo (target_ulong entry) target_ulong ret; entry &= PPC4XX_TLB_ENTRY_MASK; - tlb = &env->tlb[entry].tlbe; + tlb = &env->tlb.tlbe[entry]; ret = tlb->RPN; if (tlb->prot & PAGE_EXEC) { ret |= PPC4XX_TLBLO_EX; @@ -3973,7 +4002,7 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val) LOG_SWTLB("%s entry %d val " TARGET_FMT_lx "\n", __func__, (int)entry, val); entry &= PPC4XX_TLB_ENTRY_MASK; - tlb = &env->tlb[entry].tlbe; + tlb = &env->tlb.tlbe[entry]; /* Invalidate previous TLB (if it's valid) */ if (tlb->prot & PAGE_VALID) { end = tlb->EPN + tlb->size; @@ -4031,7 +4060,7 @@ void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val) LOG_SWTLB("%s entry %i val " TARGET_FMT_lx "\n", __func__, (int)entry, val); entry &= PPC4XX_TLB_ENTRY_MASK; - tlb = &env->tlb[entry].tlbe; + tlb = &env->tlb.tlbe[entry]; tlb->attr = val & PPC4XX_TLBLO_ATTR_MASK; tlb->RPN = val & PPC4XX_TLBLO_RPN_MASK; tlb->prot = PAGE_READ; @@ -4066,7 +4095,7 @@ void helper_440_tlbwe (uint32_t word, target_ulong entry, target_ulong value) __func__, word, (int)entry, value); do_flush_tlbs = 0; entry &= 0x3F; - tlb = &env->tlb[entry].tlbe; + tlb = &env->tlb.tlbe[entry]; switch (word) { default: /* Just here to please gcc */ @@ -4125,7 +4154,7 @@ target_ulong helper_440_tlbre (uint32_t word, target_ulong entry) int size; entry &= 0x3F; - tlb = &env->tlb[entry].tlbe; + tlb = &env->tlb.tlbe[entry]; switch (word) { default: /* Just here to please gcc */ @@ -4169,4 +4198,216 @@ target_ulong helper_440_tlbsx (target_ulong address) return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF); } +/* PowerPC BookE 2.06 TLB management */ + +static ppcmas_tlb_t *booke206_cur_tlb(CPUState *env) +{ + uint32_t tlbncfg = 0; + int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT; + int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK); + int tlb; + + tlb = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT; + tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb]; + + if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) { + cpu_abort(env, "we don't support HES yet\n"); + } + + return booke206_get_tlbm(env, tlb, ea, esel); +} + +void helper_booke_setpid(uint32_t pidn, target_ulong pid) +{ + env->spr[pidn] = pid; + /* changing PIDs mean we're in a different address space now */ + tlb_flush(env, 1); +} + +void helper_booke206_tlbwe(void) +{ + uint32_t tlbncfg, tlbn; + ppcmas_tlb_t *tlb; + + switch (env->spr[SPR_BOOKE_MAS0] & MAS0_WQ_MASK) { + case MAS0_WQ_ALWAYS: + /* good to go, write that entry */ + break; + case MAS0_WQ_COND: + /* XXX check if reserved */ + if (0) { + return; + } + break; + case MAS0_WQ_CLR_RSRV: + /* XXX clear entry */ + return; + default: + /* no idea what to do */ + return; + } + + if (((env->spr[SPR_BOOKE_MAS0] & MAS0_ATSEL) == MAS0_ATSEL_LRAT) && + !msr_gs) { + /* XXX we don't support direct LRAT setting yet */ + fprintf(stderr, "cpu: don't support LRAT setting yet\n"); + return; + } + + tlbn = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT; + tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; + + tlb = booke206_cur_tlb(env); + + if (msr_gs) { + cpu_abort(env, "missing HV implementation\n"); + } + tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) | + env->spr[SPR_BOOKE_MAS3]; + tlb->mas1 = env->spr[SPR_BOOKE_MAS1]; + /* XXX needs to change when supporting 64-bit e500 */ + tlb->mas2 = env->spr[SPR_BOOKE_MAS2] & 0xffffffff; + + if (!(tlbncfg & TLBnCFG_IPROT)) { + /* no IPROT supported by TLB */ + tlb->mas1 &= ~MAS1_IPROT; + } + + if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) { + tlb_flush_page(env, tlb->mas2 & MAS2_EPN_MASK); + } else { + tlb_flush(env, 1); + } +} + +static inline void booke206_tlb_to_mas(CPUState *env, ppcmas_tlb_t *tlb) +{ + int tlbn = booke206_tlbm_to_tlbn(env, tlb); + int way = booke206_tlbm_to_way(env, tlb); + + env->spr[SPR_BOOKE_MAS0] = tlbn << MAS0_TLBSEL_SHIFT; + env->spr[SPR_BOOKE_MAS0] |= way << MAS0_ESEL_SHIFT; + env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; + + env->spr[SPR_BOOKE_MAS1] = tlb->mas1; + env->spr[SPR_BOOKE_MAS2] = tlb->mas2; + env->spr[SPR_BOOKE_MAS3] = tlb->mas7_3; + env->spr[SPR_BOOKE_MAS7] = tlb->mas7_3 >> 32; +} + +void helper_booke206_tlbre(void) +{ + ppcmas_tlb_t *tlb = NULL; + + tlb = booke206_cur_tlb(env); + booke206_tlb_to_mas(env, tlb); +} + +void helper_booke206_tlbsx(target_ulong address) +{ + ppcmas_tlb_t *tlb = NULL; + int i, j; + target_phys_addr_t raddr; + uint32_t spid, sas; + + spid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID_MASK) >> MAS6_SPID_SHIFT; + sas = env->spr[SPR_BOOKE_MAS6] & MAS6_SAS; + + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + int ways = booke206_tlb_ways(env, i); + + for (j = 0; j < ways; j++) { + tlb = booke206_get_tlbm(env, i, address, j); + + if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) { + continue; + } + + if (sas != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) { + continue; + } + + booke206_tlb_to_mas(env, tlb); + return; + } + } + + /* no entry found, fill with defaults */ + env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; + env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK; + env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK; + env->spr[SPR_BOOKE_MAS3] = 0; + env->spr[SPR_BOOKE_MAS7] = 0; + + if (env->spr[SPR_BOOKE_MAS6] & MAS6_SAS) { + env->spr[SPR_BOOKE_MAS1] |= MAS1_TS; + } + + env->spr[SPR_BOOKE_MAS1] |= (env->spr[SPR_BOOKE_MAS6] >> 16) + << MAS1_TID_SHIFT; + + /* next victim logic */ + env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT; + env->last_way++; + env->last_way &= booke206_tlb_ways(env, 0) - 1; + env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; +} + +static inline void booke206_invalidate_ea_tlb(CPUState *env, int tlbn, + uint32_t ea) +{ + int i; + int ways = booke206_tlb_ways(env, tlbn); + target_ulong mask; + + for (i = 0; i < ways; i++) { + ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i); + mask = ~(booke206_tlb_to_page_size(env, tlb) - 1); + if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) && + !(tlb->mas1 & MAS1_IPROT)) { + tlb->mas1 &= ~MAS1_VALID; + } + } +} + +void helper_booke206_tlbivax(target_ulong address) +{ + if (address & 0x4) { + /* flush all entries */ + if (address & 0x8) { + /* flush all of TLB1 */ + booke206_flush_tlb(env, BOOKE206_FLUSH_TLB1, 1); + } else { + /* flush all of TLB0 */ + booke206_flush_tlb(env, BOOKE206_FLUSH_TLB0, 0); + } + return; + } + + if (address & 0x8) { + /* flush TLB1 entries */ + booke206_invalidate_ea_tlb(env, 1, address); + tlb_flush(env, 1); + } else { + /* flush TLB0 entries */ + booke206_invalidate_ea_tlb(env, 0, address); + tlb_flush_page(env, address & MAS2_EPN_MASK); + } +} + +void helper_booke206_tlbflush(uint32_t type) +{ + int flags = 0; + + if (type & 2) { + flags |= BOOKE206_FLUSH_TLB1; + } + + if (type & 4) { + flags |= BOOKE206_FLUSH_TLB0; + } + + booke206_flush_tlb(env, flags, 1); +} + #endif /* !CONFIG_USER_ONLY */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 89413c5..66eae30 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -2,6 +2,7 @@ * PowerPC emulation for qemu: main translation routines. * * Copyright (c) 2003-2007 Jocelyn Mayer + * Copyright (C) 2011 Freescale Semiconductor, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,7 +24,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "qemu-common.h" @@ -69,6 +69,9 @@ static TCGv cpu_nip; static TCGv cpu_msr; static TCGv cpu_ctr; static TCGv cpu_lr; +#if defined(TARGET_PPC64) +static TCGv cpu_cfar; +#endif static TCGv cpu_xer; static TCGv cpu_reserve; static TCGv_i32 cpu_fpscr; @@ -154,6 +157,11 @@ void ppc_translate_init(void) cpu_lr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, lr), "lr"); +#if defined(TARGET_PPC64) + cpu_cfar = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, cfar), "cfar"); +#endif + cpu_xer = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, xer), "xer"); @@ -187,6 +195,7 @@ typedef struct DisasContext { int le_mode; #if defined(TARGET_PPC64) int sf_mode; + int has_cfar; #endif int fpu_enabled; int altivec_enabled; @@ -196,10 +205,14 @@ typedef struct DisasContext { } DisasContext; struct opc_handler_t { - /* invalid bits */ - uint32_t inval; + /* invalid bits for instruction 1 (Rc(opcode) == 0) */ + uint32_t inval1; + /* invalid bits for instruction 2 (Rc(opcode) == 1) */ + uint32_t inval2; /* instruction type */ uint64_t type; + /* extended instruction type */ + uint64_t type2; /* handler */ void (*handler)(DisasContext *ctx); #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) @@ -212,9 +225,7 @@ struct opc_handler_t { static inline void gen_reset_fpstatus(void) { -#ifdef CONFIG_SOFTFLOAT gen_helper_reset_fpstatus(); -#endif } static inline void gen_compute_fprf(TCGv_i64 arg, int set_fprf, int set_rc) @@ -287,8 +298,10 @@ static inline void gen_debug_exception(DisasContext *ctx) { TCGv_i32 t0; - if (ctx->exception != POWERPC_EXCP_BRANCH) + if ((ctx->exception != POWERPC_EXCP_BRANCH) && + (ctx->exception != POWERPC_EXCP_SYNC)) { gen_update_nip(ctx, ctx->nip); + } t0 = tcg_const_i32(EXCP_DEBUG); gen_helper_raise_exception(t0); tcg_temp_free_i32(t0); @@ -313,10 +326,16 @@ static inline void gen_sync_exception(DisasContext *ctx) } #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \ -GEN_OPCODE(name, opc1, opc2, opc3, inval, type) +GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE) + +#define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2) \ +GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2) #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type) \ -GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type) +GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE) + +#define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2) \ +GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2) typedef struct opcode_t { unsigned char opc1, opc2, opc3; @@ -456,57 +475,92 @@ static inline target_ulong MASK(uint32_t start, uint32_t end) /* PowerPC instructions table */ #if defined(DO_PPC_STATISTICS) -#define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \ +#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \ +{ \ + .opc1 = op1, \ + .opc2 = op2, \ + .opc3 = op3, \ + .pad = { 0, }, \ + .handler = { \ + .inval1 = invl, \ + .type = _typ, \ + .type2 = _typ2, \ + .handler = &gen_##name, \ + .oname = stringify(name), \ + }, \ + .oname = stringify(name), \ +} +#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \ { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ - .inval = invl, \ + .inval1 = invl1, \ + .inval2 = invl2, \ .type = _typ, \ + .type2 = _typ2, \ .handler = &gen_##name, \ .oname = stringify(name), \ }, \ .oname = stringify(name), \ } -#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ) \ +#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \ { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ - .inval = invl, \ + .inval1 = invl, \ .type = _typ, \ + .type2 = _typ2, \ .handler = &gen_##name, \ .oname = onam, \ }, \ .oname = onam, \ } #else -#define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \ +#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \ { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ - .inval = invl, \ + .inval1 = invl, \ .type = _typ, \ + .type2 = _typ2, \ .handler = &gen_##name, \ }, \ .oname = stringify(name), \ } -#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ) \ +#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \ { \ .opc1 = op1, \ .opc2 = op2, \ .opc3 = op3, \ .pad = { 0, }, \ .handler = { \ - .inval = invl, \ + .inval1 = invl1, \ + .inval2 = invl2, \ .type = _typ, \ + .type2 = _typ2, \ + .handler = &gen_##name, \ + }, \ + .oname = stringify(name), \ +} +#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \ +{ \ + .opc1 = op1, \ + .opc2 = op2, \ + .opc3 = op3, \ + .pad = { 0, }, \ + .handler = { \ + .inval1 = invl, \ + .type = _typ, \ + .type2 = _typ2, \ .handler = &gen_##name, \ }, \ .oname = onam, \ @@ -531,8 +585,10 @@ static void gen_invalid(DisasContext *ctx) } static opc_handler_t invalid_handler = { - .inval = 0xFFFFFFFF, + .inval1 = 0xFFFFFFFF, + .inval2 = 0xFFFFFFFF, .type = PPC_NONE, + .type2 = PPC_NONE, .handler = gen_invalid, }; @@ -1483,13 +1539,21 @@ static void gen_xoris(DisasContext *ctx) /* popcntb : PowerPC 2.03 specification */ static void gen_popcntb(DisasContext *ctx) { + gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); +} + +static void gen_popcntw(DisasContext *ctx) +{ + gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); +} + #if defined(TARGET_PPC64) - if (ctx->sf_mode) - gen_helper_popcntb_64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); - else -#endif - gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); +/* popcntd: PowerPC 2.06 specification */ +static void gen_popcntd(DisasContext *ctx) +{ + gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); } +#endif #if defined(TARGET_PPC64) /* extsw & extsw. */ @@ -3326,6 +3390,14 @@ static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2) /* stfiwx */ GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX); +static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip) +{ +#if defined(TARGET_PPC64) + if (ctx->has_cfar) + tcg_gen_movi_tl(cpu_cfar, nip); +#endif +} + /*** Branch ***/ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) { @@ -3339,7 +3411,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) likely(!ctx->singlestep_enabled)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_nip, dest & ~3); - tcg_gen_exit_tb((long)tb + n); + tcg_gen_exit_tb((tcg_target_long)tb + n); } else { tcg_gen_movi_tl(cpu_nip, dest & ~3); if (unlikely(ctx->singlestep_enabled)) { @@ -3388,6 +3460,7 @@ static void gen_b(DisasContext *ctx) target = li; if (LK(ctx->opcode)) gen_setlr(ctx, ctx->nip); + gen_update_cfar(ctx, ctx->nip); gen_goto_tb(ctx, 0, target); } @@ -3450,6 +3523,7 @@ static inline void gen_bcond(DisasContext *ctx, int type) } tcg_temp_free_i32(temp); } + gen_update_cfar(ctx, ctx->nip); if (type == BCOND_IM) { target_ulong li = (target_long)((int16_t)(BD(ctx->opcode))); if (likely(AA(ctx->opcode) == 0)) { @@ -3561,6 +3635,7 @@ static void gen_rfi(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } + gen_update_cfar(ctx, ctx->nip); gen_helper_rfi(); gen_sync_exception(ctx); #endif @@ -3577,6 +3652,7 @@ static void gen_rfid(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } + gen_update_cfar(ctx, ctx->nip); gen_helper_rfid(); gen_sync_exception(ctx); #endif @@ -3858,24 +3934,19 @@ static void gen_mtmsr(DisasContext *ctx) tcg_gen_or_tl(cpu_msr, cpu_msr, t0); tcg_temp_free(t0); } else { + TCGv msr = tcg_temp_new(); + /* XXX: we need to update nip before the store * if we enter power saving mode, we will exit the loop * directly from ppc_store_msr */ gen_update_nip(ctx, ctx->nip); #if defined(TARGET_PPC64) - if (!ctx->sf_mode) { - TCGv t0 = tcg_temp_new(); - TCGv t1 = tcg_temp_new(); - tcg_gen_andi_tl(t0, cpu_msr, 0xFFFFFFFF00000000ULL); - tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]); - tcg_gen_or_tl(t0, t0, t1); - tcg_temp_free(t1); - gen_helper_store_msr(t0); - tcg_temp_free(t0); - } else + tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32); +#else + tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]); #endif - gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); + gen_helper_store_msr(msr); /* Must stop the translation as machine state (may have) changed */ /* Note that mtmsr is not always defined as context-synchronizing */ gen_stop_exception(ctx); @@ -4227,6 +4298,33 @@ static void gen_slbmte(DisasContext *ctx) #endif } +static void gen_slbmfee(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); +#else + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + return; + } + gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], + cpu_gpr[rB(ctx->opcode)]); +#endif +} + +static void gen_slbmfev(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); +#else + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + return; + } + gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], + cpu_gpr[rB(ctx->opcode)]); +#endif +} #endif /* defined(TARGET_PPC64) */ /*** Lookaside buffer management ***/ @@ -5939,6 +6037,80 @@ static void gen_tlbwe_440(DisasContext *ctx) #endif } +/* TLB management - PowerPC BookE 2.06 implementation */ + +/* tlbre */ +static void gen_tlbre_booke206(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); +#else + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return; + } + + gen_helper_booke206_tlbre(); +#endif +} + +/* tlbsx - tlbsx. */ +static void gen_tlbsx_booke206(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); +#else + TCGv t0; + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return; + } + + if (rA(ctx->opcode)) { + t0 = tcg_temp_new(); + tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]); + } else { + t0 = tcg_const_tl(0); + } + + tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]); + gen_helper_booke206_tlbsx(t0); +#endif +} + +/* tlbwe */ +static void gen_tlbwe_booke206(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); +#else + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return; + } + gen_helper_booke206_tlbwe(); +#endif +} + +static void gen_tlbivax_booke206(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); +#else + TCGv t0; + if (unlikely(!ctx->mem_idx)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return; + } + + t0 = tcg_temp_new(); + gen_addr_reg_index(ctx, t0); + + gen_helper_booke206_tlbivax(t0); +#endif +} + + /* wrtee */ static void gen_wrtee(DisasContext *ctx) { @@ -6502,6 +6674,39 @@ GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) /*** SPE extension ***/ /* Register moves */ + +static inline void gen_evmra(DisasContext *ctx) +{ + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + +#if defined(TARGET_PPC64) + /* rD := rA */ + tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); + + /* spe_acc := rA */ + tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)], + cpu_env, + offsetof(CPUState, spe_acc)); +#else + TCGv_i64 tmp = tcg_temp_new_i64(); + + /* tmp := rA_lo + rA_hi << 32 */ + tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); + + /* spe_acc := tmp */ + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + tcg_temp_free_i64(tmp); + + /* rD := rA */ + tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); + tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); +#endif +} + static inline void gen_load_gpr64(TCGv_i64 t, int reg) { #if defined(TARGET_PPC64) @@ -6524,7 +6729,7 @@ static inline void gen_store_gpr64(int reg, TCGv_i64 t) #endif } -#define GEN_SPE(name0, name1, opc2, opc3, inval, type) \ +#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ { \ if (Rc(ctx->opcode)) \ @@ -6545,7 +6750,7 @@ static inline void gen_speundef(DisasContext *ctx) static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6556,7 +6761,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6581,7 +6786,7 @@ GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6602,7 +6807,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6622,7 +6827,7 @@ GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6643,7 +6848,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \ @@ -6681,7 +6886,7 @@ GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6707,7 +6912,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -6785,7 +6990,7 @@ GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw); static inline void gen_evmergehi(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -6814,7 +7019,7 @@ GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ TCGv_i32 t0 = tcg_temp_local_new_i32(); \ @@ -6835,7 +7040,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ @@ -6853,7 +7058,7 @@ GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32); static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ int l1 = gen_new_label(); \ @@ -6893,7 +7098,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ int l1 = gen_new_label(); \ @@ -6936,13 +7141,13 @@ static inline void gen_brinc(DisasContext *ctx) static inline void gen_evmergelo(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); - tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL); + tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]); tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32); tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); tcg_temp_free(t0); @@ -6955,13 +7160,13 @@ static inline void gen_evmergelo(DisasContext *ctx) static inline void gen_evmergehilo(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); - tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL); + tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]); tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL); tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); tcg_temp_free(t0); @@ -6974,7 +7179,7 @@ static inline void gen_evmergehilo(DisasContext *ctx) static inline void gen_evmergelohi(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7050,14 +7255,14 @@ static inline void gen_evsel(DisasContext *ctx) tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2); tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3); #if defined(TARGET_PPC64) - tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL); + tcg_gen_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]); #else tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); #endif tcg_gen_br(l4); gen_set_label(l3); #if defined(TARGET_PPC64) - tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL); + tcg_gen_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]); #else tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); #endif @@ -7090,31 +7295,192 @@ static void gen_evsel3(DisasContext *ctx) gen_evsel(ctx); } -GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, PPC_SPE); -GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, PPC_SPE); -GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, PPC_SPE); //// -GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, PPC_SPE); //// -GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, PPC_SPE); //// -GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x00000000, PPC_SPE); // -GEN_SPE(speundef, evand, 0x08, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(speundef, evorc, 0x0D, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, PPC_SPE); -GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, PPC_SPE); -GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, PPC_SPE); // -GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, PPC_SPE); -GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, PPC_SPE); //// -GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, PPC_SPE); //// -GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, PPC_SPE); //// -GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); //// +/* Multiply */ + +static inline void gen_evmwumi(DisasContext *ctx) +{ + TCGv_i64 t0, t1; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + /* t0 := rA; t1 := rB */ +#if defined(TARGET_PPC64) + tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]); +#else + tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); +#endif + + tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */ + + gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */ + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +static inline void gen_evmwumia(DisasContext *ctx) +{ + TCGv_i64 tmp; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + + gen_evmwumi(ctx); /* rD := rA * rB */ + + tmp = tcg_temp_new_i64(); + + /* acc := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + tcg_temp_free_i64(tmp); +} + +static inline void gen_evmwumiaa(DisasContext *ctx) +{ + TCGv_i64 acc; + TCGv_i64 tmp; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + + gen_evmwumi(ctx); /* rD := rA * rB */ + + acc = tcg_temp_new_i64(); + tmp = tcg_temp_new_i64(); + + /* tmp := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + + /* Load acc */ + tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* acc := tmp + acc */ + tcg_gen_add_i64(acc, acc, tmp); + + /* Store acc */ + tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* rD := acc */ + gen_store_gpr64(rD(ctx->opcode), acc); + + tcg_temp_free_i64(acc); + tcg_temp_free_i64(tmp); +} + +static inline void gen_evmwsmi(DisasContext *ctx) +{ + TCGv_i64 t0, t1; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + /* t0 := rA; t1 := rB */ +#if defined(TARGET_PPC64) + tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]); +#else + tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); +#endif + + tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */ + + gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */ + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +static inline void gen_evmwsmia(DisasContext *ctx) +{ + TCGv_i64 tmp; + + gen_evmwsmi(ctx); /* rD := rA * rB */ + + tmp = tcg_temp_new_i64(); + + /* acc := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + + tcg_temp_free_i64(tmp); +} + +static inline void gen_evmwsmiaa(DisasContext *ctx) +{ + TCGv_i64 acc = tcg_temp_new_i64(); + TCGv_i64 tmp = tcg_temp_new_i64(); + + gen_evmwsmi(ctx); /* rD := rA * rB */ + + acc = tcg_temp_new_i64(); + tmp = tcg_temp_new_i64(); + + /* tmp := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + + /* Load acc */ + tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* acc := tmp + acc */ + tcg_gen_add_i64(acc, acc, tmp); + + /* Store acc */ + tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* rD := acc */ + gen_store_gpr64(rD(ctx->opcode), acc); + + tcg_temp_free_i64(acc); + tcg_temp_free_i64(tmp); +} + +GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); //// +GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); +GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); //// +GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); +GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); //// +GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); //// +GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); //// +GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); // +GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE); +GEN_SPE(speundef, evand, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); //// +GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); //// +GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); //// +GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); //// +GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evorc, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); //// +GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); //// +GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); //// +GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); //// +GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); +GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); // +GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE); +GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); //// +GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); //// +GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); //// +GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); //// +GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); //// /* SPE load and stores */ static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh) @@ -7437,7 +7803,7 @@ static void glue(gen_, name)(DisasContext *ctx) { \ TCGv t0; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_set_access_type(ctx, ACCESS_INT); \ @@ -7473,78 +7839,74 @@ GEN_SPEOP_LDST(evstwwo, 0x1E, 2); /* Multiply and add - TODO */ #if 0 -GEN_SPE(speundef, evmhessf, 0x01, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhossf, 0x03, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(evmheumi, evmhesmi, 0x04, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhesmf, 0x05, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(evmhoumi, evmhosmi, 0x06, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhosmf, 0x07, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhessfa, 0x11, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhossfa, 0x13, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(evmheumia, evmhesmia, 0x14, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhesmfa, 0x15, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(evmhoumia, evmhosmia, 0x16, 0x10, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhosmfa, 0x17, 0x10, 0x00000000, PPC_SPE); - -GEN_SPE(speundef, evmwhssf, 0x03, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwlumi, speundef, 0x04, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwhumi, evmwhsmi, 0x06, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwhsmf, 0x07, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwssf, 0x09, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwsmf, 0x0D, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwhssfa, 0x13, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwlumia, speundef, 0x14, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwhumia, evmwhsmia, 0x16, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwhsmfa, 0x17, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwssfa, 0x19, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwsmfa, 0x1D, 0x11, 0x00000000, PPC_SPE); - -GEN_SPE(evadduiaaw, evaddsiaaw, 0x00, 0x13, 0x0000F800, PPC_SPE); -GEN_SPE(evsubfusiaaw, evsubfssiaaw, 0x01, 0x13, 0x0000F800, PPC_SPE); -GEN_SPE(evaddumiaaw, evaddsmiaaw, 0x04, 0x13, 0x0000F800, PPC_SPE); -GEN_SPE(evsubfumiaaw, evsubfsmiaaw, 0x05, 0x13, 0x0000F800, PPC_SPE); -GEN_SPE(evdivws, evdivwu, 0x06, 0x13, 0x00000000, PPC_SPE); -GEN_SPE(evmra, speundef, 0x07, 0x13, 0x0000F800, PPC_SPE); - -GEN_SPE(evmheusiaaw, evmhessiaaw, 0x00, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhessfaaw, 0x01, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(evmhousiaaw, evmhossiaaw, 0x02, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhossfaaw, 0x03, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(evmheumiaaw, evmhesmiaaw, 0x04, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhesmfaaw, 0x05, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(evmhoumiaaw, evmhosmiaaw, 0x06, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhosmfaaw, 0x07, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(evmhegumiaa, evmhegsmiaa, 0x14, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhegsmfaa, 0x15, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(evmhogumiaa, evmhogsmiaa, 0x16, 0x14, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhogsmfaa, 0x17, 0x14, 0x00000000, PPC_SPE); - -GEN_SPE(evmwlusiaaw, evmwlssiaaw, 0x00, 0x15, 0x00000000, PPC_SPE); -GEN_SPE(evmwlumiaaw, evmwlsmiaaw, 0x04, 0x15, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwssfaa, 0x09, 0x15, 0x00000000, PPC_SPE); -GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwsmfaa, 0x0D, 0x15, 0x00000000, PPC_SPE); - -GEN_SPE(evmheusianw, evmhessianw, 0x00, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhessfanw, 0x01, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(evmhousianw, evmhossianw, 0x02, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhossfanw, 0x03, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(evmheumianw, evmhesmianw, 0x04, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhesmfanw, 0x05, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(evmhoumianw, evmhosmianw, 0x06, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhosmfanw, 0x07, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(evmhegumian, evmhegsmian, 0x14, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhegsmfan, 0x15, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(evmhigumian, evmhigsmian, 0x16, 0x16, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmhogsmfan, 0x17, 0x16, 0x00000000, PPC_SPE); - -GEN_SPE(evmwlusianw, evmwlssianw, 0x00, 0x17, 0x00000000, PPC_SPE); -GEN_SPE(evmwlumianw, evmwlsmianw, 0x04, 0x17, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwssfan, 0x09, 0x17, 0x00000000, PPC_SPE); -GEN_SPE(evmwumian, evmwsmian, 0x0C, 0x17, 0x00000000, PPC_SPE); -GEN_SPE(speundef, evmwsmfan, 0x0D, 0x17, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhessf, 0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);// +GEN_SPE(speundef, evmhossf, 0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmheumi, evmhesmi, 0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhesmf, 0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhoumi, evmhosmi, 0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhosmf, 0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhessfa, 0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhossfa, 0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmheumia, evmhesmia, 0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhesmfa, 0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhoumia, evmhosmia, 0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhosmfa, 0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE); + +GEN_SPE(speundef, evmwhssf, 0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmwlumi, speundef, 0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE); +GEN_SPE(evmwhumi, evmwhsmi, 0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwhsmf, 0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwssf, 0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwsmf, 0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwhssfa, 0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmwlumia, speundef, 0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE); +GEN_SPE(evmwhumia, evmwhsmia, 0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwhsmfa, 0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwssfa, 0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwsmfa, 0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE); + +GEN_SPE(evadduiaaw, evaddsiaaw, 0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE); +GEN_SPE(evsubfusiaaw, evsubfssiaaw, 0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE); +GEN_SPE(evaddumiaaw, evaddsmiaaw, 0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE); +GEN_SPE(evsubfumiaaw, evsubfsmiaaw, 0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE); +GEN_SPE(evdivws, evdivwu, 0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE); + +GEN_SPE(evmheusiaaw, evmhessiaaw, 0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhessfaaw, 0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhousiaaw, evmhossiaaw, 0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhossfaaw, 0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmheumiaaw, evmhesmiaaw, 0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhesmfaaw, 0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhoumiaaw, evmhosmiaaw, 0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhosmfaaw, 0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhegumiaa, evmhegsmiaa, 0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhegsmfaa, 0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhogumiaa, evmhogsmiaa, 0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhogsmfaa, 0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE); + +GEN_SPE(evmwlusiaaw, evmwlssiaaw, 0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(evmwlumiaaw, evmwlsmiaaw, 0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwssfaa, 0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwsmfaa, 0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE); + +GEN_SPE(evmheusianw, evmhessianw, 0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhessfanw, 0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhousianw, evmhossianw, 0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhossfanw, 0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmheumianw, evmhesmianw, 0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhesmfanw, 0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhoumianw, evmhosmianw, 0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhosmfanw, 0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhegumian, evmhegsmian, 0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhegsmfan, 0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmhigumian, evmhigsmian, 0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmhogsmfan, 0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE); + +GEN_SPE(evmwlusianw, evmwlssianw, 0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(evmwlumianw, evmwlsmianw, 0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwssfan, 0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE); +GEN_SPE(evmwumian, evmwsmian, 0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE); +GEN_SPE(speundef, evmwsmfan, 0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE); #endif /*** SPE floating-point extension ***/ @@ -7599,7 +7961,7 @@ static inline void gen_##name(DisasContext *ctx) \ TCGv_i32 t0, t1; \ TCGv_i64 t2; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i32(); \ @@ -7620,7 +7982,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ @@ -7631,7 +7993,7 @@ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i32 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i32(); \ @@ -7646,7 +8008,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ @@ -7687,7 +8049,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_gpr[rD(ctx->opcode)], \ @@ -7698,7 +8060,7 @@ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i64 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i64(); \ @@ -7714,7 +8076,7 @@ static inline void gen_##name(DisasContext *ctx) \ static inline void gen_##name(DisasContext *ctx) \ { \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \ @@ -7725,7 +8087,7 @@ static inline void gen_##name(DisasContext *ctx) \ { \ TCGv_i64 t0, t1; \ if (unlikely(!ctx->spe_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_APU); \ + gen_exception(ctx, POWERPC_EXCP_SPEU); \ return; \ } \ t0 = tcg_temp_new_i64(); \ @@ -7747,7 +8109,7 @@ GEN_SPEFPUOP_ARITH2_64_64(evfsdiv); static inline void gen_evfsabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7760,7 +8122,7 @@ static inline void gen_evfsabs(DisasContext *ctx) static inline void gen_evfsnabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7773,7 +8135,7 @@ static inline void gen_evfsnabs(DisasContext *ctx) static inline void gen_evfsneg(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7805,20 +8167,20 @@ GEN_SPEFPUOP_COMP_64(evfststlt); GEN_SPEFPUOP_COMP_64(evfststeq); /* Opcodes definitions */ -GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE); // -GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE); // -GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE); // -GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE); // -GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE); // -GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE); // -GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE); // -GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE); // +GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); // +GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); // +GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); // +GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); // +GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); // +GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); // +GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); // +GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); // +GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); // +GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); // /* Single precision floating-point operations */ /* Arithmetic */ @@ -7829,7 +8191,7 @@ GEN_SPEFPUOP_ARITH2_32_32(efsdiv); static inline void gen_efsabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL); @@ -7837,7 +8199,7 @@ static inline void gen_efsabs(DisasContext *ctx) static inline void gen_efsnabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); @@ -7845,7 +8207,7 @@ static inline void gen_efsnabs(DisasContext *ctx) static inline void gen_efsneg(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); @@ -7873,20 +8235,20 @@ GEN_SPEFPUOP_COMP_32(efststlt); GEN_SPEFPUOP_COMP_32(efststeq); /* Opcodes definitions */ -GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE); // -GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE); // -GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE); // -GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE); // -GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE); // -GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE); // -GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE); // -GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE); // -GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE); // +GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); // +GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); // +GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); // +GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); // +GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); // +GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); // +GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); // +GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); // +GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); // +GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); // /* Double precision floating-point operations */ /* Arithmetic */ @@ -7897,7 +8259,7 @@ GEN_SPEFPUOP_ARITH2_64_64(efddiv); static inline void gen_efdabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7910,7 +8272,7 @@ static inline void gen_efdabs(DisasContext *ctx) static inline void gen_efdnabs(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7923,7 +8285,7 @@ static inline void gen_efdnabs(DisasContext *ctx) static inline void gen_efdneg(DisasContext *ctx) { if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_APU); + gen_exception(ctx, POWERPC_EXCP_SPEU); return; } #if defined(TARGET_PPC64) @@ -7960,22 +8322,22 @@ GEN_SPEFPUOP_COMP_64(efdtstlt); GEN_SPEFPUOP_COMP_64(efdtsteq); /* Opcodes definitions */ -GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE); // -GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); // -GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); // -GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE); // -GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE); // -GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE); // -GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE); // -GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE); // -GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE); // +GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); // +GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); // +GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); // +GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); // +GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); // +GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); // +GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); // +GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); // +GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); // +GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); // +GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); // +GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); // +GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); // +GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); // +GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); // +GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); // static opcode_t opcodes[] = { GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE), @@ -8009,7 +8371,9 @@ GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB), +GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD), #if defined(TARGET_PPC64) +GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD), GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B), #endif GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), @@ -8110,7 +8474,9 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B), -GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B), +GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B), +GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B), +GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B), #endif GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE), @@ -8191,7 +8557,7 @@ GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT), GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON), GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON), GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP), -GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE), +GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206), GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI), GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI), GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB), @@ -8200,12 +8566,23 @@ GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB), GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE), GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE), GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE), +GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, + PPC_NONE, PPC2_BOOKE206), +GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, + PPC_NONE, PPC2_BOOKE206), +GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, + PPC_NONE, PPC2_BOOKE206), +GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, + PPC_NONE, PPC2_BOOKE206), GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), -GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE), -GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE), -GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE), +GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, + PPC_BOOKE, PPC2_BOOKE206), +GEN_HANDLER_E(msync, 0x1F, 0x16, 0x12, 0x03FFF801, + PPC_BOOKE, PPC2_BOOKE206), +GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, + PPC_BOOKE, PPC2_BOOKE206), GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC), @@ -8729,80 +9106,84 @@ GEN_VAFORM_PAIRED(vsel, vperm, 21), GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23), #undef GEN_SPE -#define GEN_SPE(name0, name1, opc2, opc3, inval, type) \ -GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) -GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, PPC_SPE), -GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, PPC_SPE), -GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, PPC_SPE), -GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(speundef, evand, 0x08, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(speundef, evorc, 0x0D, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, PPC_SPE), -GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, PPC_SPE), -GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, PPC_SPE), -GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE), - -GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE), -GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE), -GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE), -GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE), -GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE), -GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE), -GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE), -GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE), - -GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE), -GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE), -GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE), -GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE), -GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE), -GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE), -GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE), -GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE), -GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE), - -GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE), -GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE), -GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE), -GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE), -GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE), -GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE), -GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE), -GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE), -GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE), +#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ + GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) +GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE), +GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE), +GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE), +GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE), +GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(speundef, evand, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE), +GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(speundef, evorc, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE), +GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE), +GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE), +GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE), +GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE), +GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE), +GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE), +GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE), + +GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE), +GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE), +GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE), +GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE), +GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE), +GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE), +GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE), +GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE), +GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE), +GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE), + +GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE), +GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE), +GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE), +GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE), +GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE), +GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE), +GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE), +GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE), +GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE), +GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE), + +GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE), +GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE), +GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE), +GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE), +GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE), +GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE), +GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE), +GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE), +GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE), +GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE), +GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE), +GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE), +GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE), +GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE), +GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE), +GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE), #undef GEN_SPEOP_LDST #define GEN_SPEOP_LDST(name, opc2, sh) \ @@ -8891,9 +9272,90 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf, } cpu_fprintf(f, "FPSCR %08x\n", env->fpscr); #if !defined(CONFIG_USER_ONLY) - cpu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx " SDR1 " - TARGET_FMT_lx "\n", env->spr[SPR_SRR0], env->spr[SPR_SRR1], - env->sdr1); + cpu_fprintf(f, " SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx + " PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n", + env->spr[SPR_SRR0], env->spr[SPR_SRR1], + env->spr[SPR_PVR], env->spr[SPR_VRSAVE]); + + cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx + " SPRG2 " TARGET_FMT_lx " SPRG3 " TARGET_FMT_lx "\n", + env->spr[SPR_SPRG0], env->spr[SPR_SPRG1], + env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]); + + cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx + " SPRG6 " TARGET_FMT_lx " SPRG7 " TARGET_FMT_lx "\n", + env->spr[SPR_SPRG4], env->spr[SPR_SPRG5], + env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]); + + if (env->excp_model == POWERPC_EXCP_BOOKE) { + cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx + " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n", + env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1], + env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); + + cpu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx + " ESR " TARGET_FMT_lx " DEAR " TARGET_FMT_lx "\n", + env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR], + env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]); + + cpu_fprintf(f, " PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx + " IVPR " TARGET_FMT_lx " EPCR " TARGET_FMT_lx "\n", + env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR], + env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]); + + cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx + " EPR " TARGET_FMT_lx "\n", + env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8], + env->spr[SPR_BOOKE_EPR]); + + /* FSL-specific */ + cpu_fprintf(f, " MCAR " TARGET_FMT_lx " PID1 " TARGET_FMT_lx + " PID2 " TARGET_FMT_lx " SVR " TARGET_FMT_lx "\n", + env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1], + env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]); + + /* + * IVORs are left out as they are large and do not change often -- + * they can be read with "p $ivor0", "p $ivor1", etc. + */ + } + +#if defined(TARGET_PPC64) + if (env->flags & POWERPC_FLAG_CFAR) { + cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar); + } +#endif + + switch (env->mmu_model) { + case POWERPC_MMU_32B: + case POWERPC_MMU_601: + case POWERPC_MMU_SOFT_6xx: + case POWERPC_MMU_SOFT_74xx: +#if defined(TARGET_PPC64) + case POWERPC_MMU_620: + case POWERPC_MMU_64B: +#endif + cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]); + break; + case POWERPC_MMU_BOOKE206: + cpu_fprintf(f, " MAS0 " TARGET_FMT_lx " MAS1 " TARGET_FMT_lx + " MAS2 " TARGET_FMT_lx " MAS3 " TARGET_FMT_lx "\n", + env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1], + env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]); + + cpu_fprintf(f, " MAS4 " TARGET_FMT_lx " MAS6 " TARGET_FMT_lx + " MAS7 " TARGET_FMT_lx " PID " TARGET_FMT_lx "\n", + env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6], + env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]); + + cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx + " TLB1CFG " TARGET_FMT_lx "\n", + env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG], + env->spr[SPR_BOOKE_TLB1CFG]); + break; + default: + break; + } #endif #undef RGPL @@ -8972,6 +9434,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0; #if defined(TARGET_PPC64) ctx.sf_mode = msr_sf; + ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); #endif ctx.fpu_enabled = msr_fp; if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) @@ -9057,11 +9520,19 @@ static inline void gen_intermediate_code_internal(CPUState *env, opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir); } } else { - if (unlikely((ctx.opcode & handler->inval) != 0)) { + uint32_t inval; + + if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) { + inval = handler->inval2; + } else { + inval = handler->inval1; + } + + if (unlikely((ctx.opcode & inval) != 0)) { if (qemu_log_enabled()) { qemu_log("invalid bits: %08x for opcode: " "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n", - ctx.opcode & handler->inval, opc1(ctx.opcode), + ctx.opcode & inval, opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); } @@ -9134,8 +9605,7 @@ void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) gen_intermediate_code_internal(env, tb, 1); } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->nip = gen_opc_pc[pc_pos]; } diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index dfcd949..8a7233f 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -24,6 +24,8 @@ #include "dis-asm.h" #include "gdbstub.h" +#include +#include "kvm_ppc.h" //#define PPC_DUMP_CPU //#define PPC_DEBUG_SPR @@ -32,21 +34,6 @@ #define TODO_USER_ONLY 1 #endif -struct ppc_def_t { - const char *name; - uint32_t pvr; - uint32_t svr; - uint64_t insns_flags; - uint64_t msr_mask; - powerpc_mmu_t mmu_model; - powerpc_excp_t excp_model; - powerpc_input_t bus_model; - uint32_t flags; - int bfd_mach; - void (*init_proc)(CPUPPCState *env); - int (*check_pow)(CPUPPCState *env); -}; - /* For user-mode emulation, we don't emulate any IRQ controller */ #if defined(CONFIG_USER_ONLY) #define PPC_IRQ_INIT_FN(name) \ @@ -61,6 +48,7 @@ void glue(glue(ppc, name),_irq_init) (CPUPPCState *env); PPC_IRQ_INIT_FN(40x); PPC_IRQ_INIT_FN(6xx); PPC_IRQ_INIT_FN(970); +PPC_IRQ_INIT_FN(POWER7); PPC_IRQ_INIT_FN(e500); /* Generic callbacks: @@ -71,7 +59,7 @@ static void spr_read_generic (void *opaque, int gprn, int sprn) gen_load_spr(cpu_gpr[gprn], sprn); #ifdef PPC_DUMP_SPR_ACCESSES { - TCGv t0 = tcg_const_i32(sprn); + TCGv_i32 t0 = tcg_const_i32(sprn); gen_helper_load_dump_spr(t0); tcg_temp_free_i32(t0); } @@ -83,7 +71,7 @@ static void spr_write_generic (void *opaque, int sprn, int gprn) gen_store_spr(sprn, cpu_gpr[gprn]); #ifdef PPC_DUMP_SPR_ACCESSES { - TCGv t0 = tcg_const_i32(sprn); + TCGv_i32 t0 = tcg_const_i32(sprn); gen_helper_store_dump_spr(t0); tcg_temp_free_i32(t0); } @@ -127,6 +115,19 @@ static void spr_write_lr (void *opaque, int sprn, int gprn) tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]); } +/* CFAR */ +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) +static void spr_read_cfar (void *opaque, int gprn, int sprn) +{ + tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar); +} + +static void spr_write_cfar (void *opaque, int sprn, int gprn) +{ + tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]); +} +#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */ + /* CTR */ static void spr_read_ctr (void *opaque, int gprn, int sprn) { @@ -154,12 +155,26 @@ static void spr_read_ureg (void *opaque, int gprn, int sprn) #if !defined(CONFIG_USER_ONLY) static void spr_read_decr (void *opaque, int gprn, int sprn) { + if (use_icount) { + gen_io_start(); + } gen_helper_load_decr(cpu_gpr[gprn]); + if (use_icount) { + gen_io_end(); + gen_stop_exception(opaque); + } } static void spr_write_decr (void *opaque, int sprn, int gprn) { + if (use_icount) { + gen_io_start(); + } gen_helper_store_decr(cpu_gpr[gprn]); + if (use_icount) { + gen_io_end(); + gen_stop_exception(opaque); + } } #endif @@ -167,12 +182,26 @@ static void spr_write_decr (void *opaque, int sprn, int gprn) /* Time base */ static void spr_read_tbl (void *opaque, int gprn, int sprn) { + if (use_icount) { + gen_io_start(); + } gen_helper_load_tbl(cpu_gpr[gprn]); + if (use_icount) { + gen_io_end(); + gen_stop_exception(opaque); + } } static void spr_read_tbu (void *opaque, int gprn, int sprn) { + if (use_icount) { + gen_io_start(); + } gen_helper_load_tbu(cpu_gpr[gprn]); + if (use_icount) { + gen_io_end(); + gen_stop_exception(opaque); + } } __attribute__ (( unused )) @@ -190,12 +219,26 @@ static void spr_read_atbu (void *opaque, int gprn, int sprn) #if !defined(CONFIG_USER_ONLY) static void spr_write_tbl (void *opaque, int sprn, int gprn) { + if (use_icount) { + gen_io_start(); + } gen_helper_store_tbl(cpu_gpr[gprn]); + if (use_icount) { + gen_io_end(); + gen_stop_exception(opaque); + } } static void spr_write_tbu (void *opaque, int sprn, int gprn) { + if (use_icount) { + gen_io_start(); + } gen_helper_store_tbu(cpu_gpr[gprn]); + if (use_icount) { + gen_io_end(); + gen_stop_exception(opaque); + } } __attribute__ (( unused )) @@ -209,6 +252,14 @@ static void spr_write_atbu (void *opaque, int sprn, int gprn) { gen_helper_store_atbu(cpu_gpr[gprn]); } + +#if defined(TARGET_PPC64) +__attribute__ (( unused )) +static void spr_read_purr (void *opaque, int gprn, int sprn) +{ + gen_helper_load_purr(cpu_gpr[gprn]); +} +#endif #endif #if !defined(CONFIG_USER_ONLY) @@ -293,11 +344,6 @@ static void spr_write_dbatl_h (void *opaque, int sprn, int gprn) } /* SDR1 */ -static void spr_read_sdr1 (void *opaque, int gprn, int sprn) -{ - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, sdr1)); -} - static void spr_write_sdr1 (void *opaque, int sprn, int gprn) { gen_helper_store_sdr1(cpu_gpr[gprn]); @@ -621,7 +667,7 @@ static void gen_spr_ne_601 (CPUPPCState *env) /* Memory management */ spr_register(env, SPR_SDR1, "SDR1", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_sdr1, &spr_write_sdr1, + &spr_read_generic, &spr_write_sdr1, 0x00000000); } @@ -797,6 +843,7 @@ static void gen_6xx_7xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways) env->nb_tlb = nb_tlbs; env->nb_ways = nb_ways; env->id_tlbs = 1; + env->tlb_type = TLB_6XX; spr_register(env, SPR_DMISS, "DMISS", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, @@ -1290,6 +1337,7 @@ static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways) env->nb_tlb = nb_tlbs; env->nb_ways = nb_ways; env->id_tlbs = 1; + env->tlb_type = TLB_6XX; /* XXX : not implemented */ spr_register(env, SPR_PTEHI, "PTEHI", SPR_NOACCESS, SPR_NOACCESS, @@ -1308,6 +1356,31 @@ static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways) #endif } +#if !defined(CONFIG_USER_ONLY) +static void spr_write_e500_l1csr0 (void *opaque, int sprn, int gprn) +{ + TCGv t0 = tcg_temp_new(); + + tcg_gen_andi_tl(t0, cpu_gpr[gprn], ~256); + gen_store_spr(sprn, t0); + tcg_temp_free(t0); +} + +static void spr_write_booke206_mmucsr0 (void *opaque, int sprn, int gprn) +{ + TCGv_i32 t0 = tcg_const_i32(sprn); + gen_helper_booke206_tlbflush(t0); + tcg_temp_free_i32(t0); +} + +static void spr_write_booke_pid (void *opaque, int sprn, int gprn) +{ + TCGv_i32 t0 = tcg_const_i32(sprn); + gen_helper_booke_setpid(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); +} +#endif + static void gen_spr_usprgh (CPUPPCState *env) { spr_register(env, SPR_USPRG4, "USPRG4", @@ -1447,7 +1520,7 @@ static void gen_spr_BookE (CPUPPCState *env, uint64_t ivor_mask) } spr_register(env, SPR_BOOKE_PID, "PID", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_booke_pid, 0x00000000); spr_register(env, SPR_BOOKE_TCR, "TCR", SPR_NOACCESS, SPR_NOACCESS, @@ -1489,8 +1562,19 @@ static void gen_spr_BookE (CPUPPCState *env, uint64_t ivor_mask) 0x00000000); } -/* FSL storage control registers */ -static void gen_spr_BookE_FSL (CPUPPCState *env, uint32_t mas_mask) +static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize, + uint32_t maxsize, uint32_t flags, + uint32_t nentries) +{ + return (assoc << TLBnCFG_ASSOC_SHIFT) | + (minsize << TLBnCFG_MINSIZE_SHIFT) | + (maxsize << TLBnCFG_MAXSIZE_SHIFT) | + flags | nentries; +} + +/* BookE 2.06 storage control registers */ +static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask, + uint32_t *tlbncfg) { #if !defined(CONFIG_USER_ONLY) const char *mas_names[8] = { @@ -1516,14 +1600,14 @@ static void gen_spr_BookE_FSL (CPUPPCState *env, uint32_t mas_mask) /* XXX : not implemented */ spr_register(env, SPR_BOOKE_PID1, "PID1", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_booke_pid, 0x00000000); } if (env->nb_pids > 2) { /* XXX : not implemented */ spr_register(env, SPR_BOOKE_PID2, "PID2", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_booke_pid, 0x00000000); } /* XXX : not implemented */ @@ -1531,45 +1615,38 @@ static void gen_spr_BookE_FSL (CPUPPCState *env, uint32_t mas_mask) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, 0x00000000); /* TOFIX */ - /* XXX : not implemented */ - spr_register(env, SPR_MMUCSR0, "MMUCSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); /* TOFIX */ switch (env->nb_ways) { case 4: - /* XXX : not implemented */ spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, - 0x00000000); /* TOFIX */ + tlbncfg[3]); /* Fallthru */ case 3: - /* XXX : not implemented */ spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, - 0x00000000); /* TOFIX */ + tlbncfg[2]); /* Fallthru */ case 2: - /* XXX : not implemented */ spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, - 0x00000000); /* TOFIX */ + tlbncfg[1]); /* Fallthru */ case 1: - /* XXX : not implemented */ spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, - 0x00000000); /* TOFIX */ + tlbncfg[0]); /* Fallthru */ case 0: default: break; } #endif + + gen_spr_usprgh(env); } /* SPR specific to PowerPC 440 implementation */ @@ -3086,6 +3163,35 @@ static void init_excp_970 (CPUPPCState *env) env->hreset_vector = 0x0000000000000100ULL; #endif } + +static void init_excp_POWER7 (CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; + env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; + env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800; + env->hreset_excp_prefix = 0; + /* Hardware reset vector */ + env->hreset_vector = 0x0000000000000100ULL; +#endif +} #endif /*****************************************************************************/ @@ -3126,6 +3232,7 @@ static int check_pow_hid0_74xx (CPUPPCState *env) PPC_CACHE_DCBZ | \ PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_4xx_COMMON | PPC_40x_EXCP) +#define POWERPC_INSNS2_401 (PPC_NONE) #define POWERPC_MSRM_401 (0x00000000000FD201ULL) #define POWERPC_MMU_401 (POWERPC_MMU_REAL) #define POWERPC_EXCP_401 (POWERPC_EXCP_40x) @@ -3145,6 +3252,9 @@ static void init_proc_401 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 401x2 */ @@ -3155,6 +3265,7 @@ static void init_proc_401 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \ PPC_4xx_COMMON | PPC_40x_EXCP) +#define POWERPC_INSNS2_401x2 (PPC_NONE) #define POWERPC_MSRM_401x2 (0x00000000001FD231ULL) #define POWERPC_MMU_401x2 (POWERPC_MMU_SOFT_4xx_Z) #define POWERPC_EXCP_401x2 (POWERPC_EXCP_40x) @@ -3175,12 +3286,16 @@ static void init_proc_401x2 (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_4xx_softmmu(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 401x3 */ @@ -3191,6 +3306,7 @@ static void init_proc_401x2 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \ PPC_4xx_COMMON | PPC_40x_EXCP) +#define POWERPC_INSNS2_401x3 (PPC_NONE) #define POWERPC_MSRM_401x3 (0x00000000001FD631ULL) #define POWERPC_MMU_401x3 (POWERPC_MMU_SOFT_4xx_Z) #define POWERPC_EXCP_401x3 (POWERPC_EXCP_40x) @@ -3213,6 +3329,9 @@ static void init_proc_401x3 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(16, 20, 24, 28); } /* IOP480 */ @@ -3223,6 +3342,7 @@ static void init_proc_401x3 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \ PPC_4xx_COMMON | PPC_40x_EXCP) +#define POWERPC_INSNS2_IOP480 (PPC_NONE) #define POWERPC_MSRM_IOP480 (0x00000000001FD231ULL) #define POWERPC_MMU_IOP480 (POWERPC_MMU_SOFT_4xx_Z) #define POWERPC_EXCP_IOP480 (POWERPC_EXCP_40x) @@ -3243,12 +3363,16 @@ static void init_proc_IOP480 (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_4xx_softmmu(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 403 */ @@ -3258,6 +3382,7 @@ static void init_proc_IOP480 (CPUPPCState *env) PPC_CACHE_DCBZ | \ PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_4xx_COMMON | PPC_40x_EXCP) +#define POWERPC_INSNS2_403 (PPC_NONE) #define POWERPC_MSRM_403 (0x000000000007D00DULL) #define POWERPC_MMU_403 (POWERPC_MMU_REAL) #define POWERPC_EXCP_403 (POWERPC_EXCP_40x) @@ -3278,6 +3403,9 @@ static void init_proc_403 (CPUPPCState *env) env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 403 GCX */ @@ -3288,6 +3416,7 @@ static void init_proc_403 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \ PPC_4xx_COMMON | PPC_40x_EXCP) +#define POWERPC_INSNS2_403GCX (PPC_NONE) #define POWERPC_MSRM_403GCX (0x000000000007D00DULL) #define POWERPC_MMU_403GCX (POWERPC_MMU_SOFT_4xx_Z) #define POWERPC_EXCP_403GCX (POWERPC_EXCP_40x) @@ -3320,12 +3449,16 @@ static void init_proc_403GCX (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_4xx_softmmu(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 405 */ @@ -3336,6 +3469,7 @@ static void init_proc_403GCX (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \ PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP) +#define POWERPC_INSNS2_405 (PPC_NONE) #define POWERPC_MSRM_405 (0x000000000006E630ULL) #define POWERPC_MMU_405 (POWERPC_MMU_SOFT_4xx) #define POWERPC_EXCP_405 (POWERPC_EXCP_40x) @@ -3367,12 +3501,16 @@ static void init_proc_405 (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_4xx_softmmu(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* Allocate hardware IRQ controller */ ppc40x_irq_init(env); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); } /* PowerPC 440 EP */ @@ -3383,6 +3521,7 @@ static void init_proc_405 (CPUPPCState *env) PPC_MEM_TLBSYNC | PPC_MFTB | \ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \ PPC_440_SPEC) +#define POWERPC_INSNS2_440EP (PPC_NONE) #define POWERPC_MSRM_440EP (0x000000000006D630ULL) #define POWERPC_MMU_440EP (POWERPC_MMU_BOOKE) #define POWERPC_EXCP_440EP (POWERPC_EXCP_BOOKE) @@ -3448,11 +3587,15 @@ static void init_proc_440EP (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_BookE(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 440 GP */ @@ -3463,6 +3606,7 @@ static void init_proc_440EP (CPUPPCState *env) PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB | \ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \ PPC_440_SPEC) +#define POWERPC_INSNS2_440GP (PPC_NONE) #define POWERPC_MSRM_440GP (0x000000000006FF30ULL) #define POWERPC_MMU_440GP (POWERPC_MMU_BOOKE) #define POWERPC_EXCP_440GP (POWERPC_EXCP_BOOKE) @@ -3510,11 +3654,15 @@ static void init_proc_440GP (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_BookE(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 440x4 */ @@ -3525,6 +3673,7 @@ static void init_proc_440GP (CPUPPCState *env) PPC_MEM_TLBSYNC | PPC_MFTB | \ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \ PPC_440_SPEC) +#define POWERPC_INSNS2_440x4 (PPC_NONE) #define POWERPC_MSRM_440x4 (0x000000000006FF30ULL) #define POWERPC_MMU_440x4 (POWERPC_MMU_BOOKE) #define POWERPC_EXCP_440x4 (POWERPC_EXCP_BOOKE) @@ -3572,11 +3721,15 @@ static void init_proc_440x4 (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_BookE(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 440x5 */ @@ -3587,6 +3740,7 @@ static void init_proc_440x4 (CPUPPCState *env) PPC_MEM_TLBSYNC | PPC_MFTB | \ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \ PPC_440_SPEC) +#define POWERPC_INSNS2_440x5 (PPC_NONE) #define POWERPC_MSRM_440x5 (0x000000000006FF30ULL) #define POWERPC_MMU_440x5 (POWERPC_MMU_BOOKE) #define POWERPC_EXCP_440x5 (POWERPC_EXCP_BOOKE) @@ -3651,11 +3805,15 @@ static void init_proc_440x5 (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_BookE(env); env->dcache_line_size = 32; env->icache_line_size = 32; ppc40x_irq_init(env); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 460 (guessed) */ @@ -3667,6 +3825,7 @@ static void init_proc_440x5 (CPUPPCState *env) PPC_MEM_TLBSYNC | PPC_TLBIVA | \ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \ PPC_440_SPEC) +#define POWERPC_INSNS2_460 (PPC_NONE) #define POWERPC_MSRM_460 (0x000000000006FF30ULL) #define POWERPC_MMU_460 (POWERPC_MMU_BOOKE) #define POWERPC_EXCP_460 (POWERPC_EXCP_BOOKE) @@ -3737,11 +3896,15 @@ static void init_proc_460 (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_BookE(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* PowerPC 460F (guessed) */ @@ -3756,6 +3919,7 @@ static void init_proc_460 (CPUPPCState *env) PPC_MEM_TLBSYNC | PPC_TLBIVA | \ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \ PPC_440_SPEC) +#define POWERPC_INSNS2_460F (PPC_NONE) #define POWERPC_MSRM_460 (0x000000000006FF30ULL) #define POWERPC_MMU_460F (POWERPC_MMU_BOOKE) #define POWERPC_EXCP_460F (POWERPC_EXCP_BOOKE) @@ -3826,11 +3990,15 @@ static void init_proc_460F (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_BookE(env); env->dcache_line_size = 32; env->icache_line_size = 32; /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); } /* Freescale 5xx cores (aka RCPU) */ @@ -3838,6 +4006,7 @@ static void init_proc_460F (CPUPPCState *env) PPC_MEM_EIEIO | PPC_MEM_SYNC | \ PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX | \ PPC_MFTB) +#define POWERPC_INSNS2_MPC5xx (PPC_NONE) #define POWERPC_MSRM_MPC5xx (0x000000000001FF43ULL) #define POWERPC_MMU_MPC5xx (POWERPC_MMU_REAL) #define POWERPC_EXCP_MPC5xx (POWERPC_EXCP_603) @@ -3864,6 +4033,7 @@ static void init_proc_MPC5xx (CPUPPCState *env) #define POWERPC_INSNS_MPC8xx (PPC_INSNS_BASE | PPC_STRING | \ PPC_MEM_EIEIO | PPC_MEM_SYNC | \ PPC_CACHE_ICBI | PPC_MFTB) +#define POWERPC_INSNS2_MPC8xx (PPC_NONE) #define POWERPC_MSRM_MPC8xx (0x000000000001F673ULL) #define POWERPC_MMU_MPC8xx (POWERPC_MMU_MPC8xx) #define POWERPC_EXCP_MPC8xx (POWERPC_EXCP_603) @@ -3895,6 +4065,7 @@ static void init_proc_MPC8xx (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_G2 (PPC_NONE) #define POWERPC_MSRM_G2 (0x000000000006FFF2ULL) #define POWERPC_MMU_G2 (POWERPC_MMU_SOFT_6xx) //#define POWERPC_EXCP_G2 (POWERPC_EXCP_G2) @@ -3952,6 +4123,7 @@ static void init_proc_G2 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_G2LE (PPC_NONE) #define POWERPC_MSRM_G2LE (0x000000000007FFF3ULL) #define POWERPC_MMU_G2LE (POWERPC_MMU_SOFT_6xx) #define POWERPC_EXCP_G2LE (POWERPC_EXCP_G2) @@ -4018,8 +4190,9 @@ static void init_proc_G2LE (CPUPPCState *env) PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \ PPC_MEM_TLBSYNC | PPC_TLBIVAX | \ PPC_BOOKE) +#define POWERPC_INSNS2_e200 (PPC_NONE) #define POWERPC_MSRM_e200 (0x000000000606FF30ULL) -#define POWERPC_MMU_e200 (POWERPC_MMU_BOOKE_FSL) +#define POWERPC_MMU_e200 (POWERPC_MMU_BOOKE206) #define POWERPC_EXCP_e200 (POWERPC_EXCP_BOOKE) #define POWERPC_INPUT_e200 (PPC_FLAGS_INPUT_BookE) #define POWERPC_BFDM_e200 (bfd_mach_ppc_860) @@ -4040,7 +4213,7 @@ static void init_proc_e200 (CPUPPCState *env) &spr_read_spefscr, &spr_write_spefscr, 0x00000000); /* Memory management */ - gen_spr_BookE_FSL(env, 0x0000005D); + gen_spr_BookE206(env, 0x0000005D, NULL); /* XXX : not implemented */ spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, @@ -4111,6 +4284,11 @@ static void init_proc_e200 (CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); + /* XXX : not implemented */ + spr_register(env, SPR_MMUCSR0, "MMUCSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); /* TOFIX */ spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, @@ -4123,6 +4301,7 @@ static void init_proc_e200 (CPUPPCState *env) env->nb_tlb = 64; env->nb_ways = 1; env->id_tlbs = 0; + env->tlb_type = TLB_EMB; #endif init_excp_e200(env); env->dcache_line_size = 32; @@ -4138,6 +4317,7 @@ static void init_proc_e200 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_e300 (PPC_NONE) #define POWERPC_MSRM_e300 (0x000000000007FFF3ULL) #define POWERPC_MMU_e300 (POWERPC_MMU_SOFT_6xx) #define POWERPC_EXCP_e300 (POWERPC_EXCP_603) @@ -4187,10 +4367,10 @@ static void init_proc_e300 (CPUPPCState *env) PPC_WRTEE | PPC_RFDI | \ PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \ PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \ - PPC_MEM_TLBSYNC | PPC_TLBIVAX | \ - PPC_BOOKE) + PPC_MEM_TLBSYNC | PPC_TLBIVAX) +#define POWERPC_INSNS2_e500v1 (PPC2_BOOKE206) #define POWERPC_MSRM_e500v1 (0x000000000606FF30ULL) -#define POWERPC_MMU_e500v1 (POWERPC_MMU_BOOKE_FSL) +#define POWERPC_MMU_e500v1 (POWERPC_MMU_BOOKE206) #define POWERPC_EXCP_e500v1 (POWERPC_EXCP_BOOKE) #define POWERPC_INPUT_e500v1 (PPC_FLAGS_INPUT_BookE) #define POWERPC_BFDM_e500v1 (bfd_mach_ppc_860) @@ -4198,7 +4378,7 @@ static void init_proc_e300 (CPUPPCState *env) POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | \ POWERPC_FLAG_BUS_CLK) #define check_pow_e500v1 check_pow_hid0 -#define init_proc_e500v1 init_proc_e500 +#define init_proc_e500v1 init_proc_e500v1 /* e500v2 core */ #define POWERPC_INSNS_e500v2 (PPC_INSNS_BASE | PPC_ISEL | \ @@ -4206,10 +4386,10 @@ static void init_proc_e300 (CPUPPCState *env) PPC_WRTEE | PPC_RFDI | \ PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \ PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \ - PPC_MEM_TLBSYNC | PPC_TLBIVAX | \ - PPC_BOOKE) + PPC_MEM_TLBSYNC | PPC_TLBIVAX) +#define POWERPC_INSNS2_e500v2 (PPC2_BOOKE206) #define POWERPC_MSRM_e500v2 (0x000000000606FF30ULL) -#define POWERPC_MMU_e500v2 (POWERPC_MMU_BOOKE_FSL) +#define POWERPC_MMU_e500v2 (POWERPC_MMU_BOOKE206) #define POWERPC_EXCP_e500v2 (POWERPC_EXCP_BOOKE) #define POWERPC_INPUT_e500v2 (PPC_FLAGS_INPUT_BookE) #define POWERPC_BFDM_e500v2 (bfd_mach_ppc_860) @@ -4217,13 +4397,23 @@ static void init_proc_e300 (CPUPPCState *env) POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | \ POWERPC_FLAG_BUS_CLK) #define check_pow_e500v2 check_pow_hid0 -#define init_proc_e500v2 init_proc_e500 +#define init_proc_e500v2 init_proc_e500v2 -static void init_proc_e500 (CPUPPCState *env) +static void init_proc_e500 (CPUPPCState *env, int version) { + uint32_t tlbncfg[2]; +#if !defined(CONFIG_USER_ONLY) + int i; +#endif + /* Time base */ gen_tbl(env); - gen_spr_BookE(env, 0x0000000F0000FD7FULL); + /* + * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't + * complain when accessing them. + * gen_spr_BookE(env, 0x0000000F0000FD7FULL); + */ + gen_spr_BookE(env, 0x0000000F0000FFFFULL); /* Processor identification */ spr_register(env, SPR_BOOKE_PIR, "PIR", SPR_NOACCESS, SPR_NOACCESS, @@ -4237,8 +4427,24 @@ static void init_proc_e500 (CPUPPCState *env) /* Memory management */ #if !defined(CONFIG_USER_ONLY) env->nb_pids = 3; + env->nb_ways = 2; + env->id_tlbs = 0; + switch (version) { + case 1: + /* e500v1 */ + tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256); + tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16); + break; + case 2: + /* e500v2 */ + tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512); + tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16); + break; + default: + cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]); + } #endif - gen_spr_BookE_FSL(env, 0x0000005F); + gen_spr_BookE206(env, 0x000000DF, tlbncfg); /* XXX : not implemented */ spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, @@ -4287,23 +4493,13 @@ static void init_proc_e500 (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_e500_l1csr0, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); - /* XXX : not implemented */ - spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* XXX : not implemented */ - spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, @@ -4312,11 +4508,19 @@ static void init_proc_e500 (CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); + spr_register(env, SPR_MMUCSR0, "MMUCSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_booke206_mmucsr0, + 0x00000000); + #if !defined(CONFIG_USER_ONLY) - env->nb_tlb = 64; - env->nb_ways = 1; - env->id_tlbs = 0; + env->nb_tlb = 0; + env->tlb_type = TLB_MAS; + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + env->nb_tlb += booke206_tlb_size(env, i); + } #endif + init_excp_e200(env); env->dcache_line_size = 32; env->icache_line_size = 32; @@ -4324,6 +4528,16 @@ static void init_proc_e500 (CPUPPCState *env) ppce500_irq_init(env); } +static void init_proc_e500v1(CPUPPCState *env) +{ + init_proc_e500(env, 1); +} + +static void init_proc_e500v2(CPUPPCState *env) +{ + init_proc_e500(env, 2); +} + /* Non-embedded PowerPC */ /* POWER : same as 601, without mfmsr, mfsr */ @@ -4339,6 +4553,7 @@ static void init_proc_e500 (CPUPPCState *env) PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \ PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_601 (PPC_NONE) #define POWERPC_MSRM_601 (0x000000000000FD70ULL) #define POWERPC_MSRR_601 (0x0000000000001040ULL) //#define POWERPC_MMU_601 (POWERPC_MMU_601) @@ -4391,6 +4606,7 @@ static void init_proc_601 (CPUPPCState *env) PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \ PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_601v (PPC_NONE) #define POWERPC_MSRM_601v (0x000000000000FD70ULL) #define POWERPC_MSRR_601v (0x0000000000001040ULL) #define POWERPC_MMU_601v (POWERPC_MMU_601) @@ -4418,6 +4634,7 @@ static void init_proc_601v (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_602_SPEC) +#define POWERPC_INSNS2_602 (PPC_NONE) #define POWERPC_MSRM_602 (0x0000000000C7FF73ULL) /* XXX: 602 MMU is quite specific. Should add a special case */ #define POWERPC_MMU_602 (POWERPC_MMU_SOFT_6xx) @@ -4463,6 +4680,7 @@ static void init_proc_602 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_603 (PPC_NONE) #define POWERPC_MSRM_603 (0x000000000007FF73ULL) #define POWERPC_MMU_603 (POWERPC_MMU_SOFT_6xx) //#define POWERPC_EXCP_603 (POWERPC_EXCP_603) @@ -4507,6 +4725,7 @@ static void init_proc_603 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_603E (PPC_NONE) #define POWERPC_MSRM_603E (0x000000000007FF73ULL) #define POWERPC_MMU_603E (POWERPC_MMU_SOFT_6xx) //#define POWERPC_EXCP_603E (POWERPC_EXCP_603E) @@ -4556,6 +4775,7 @@ static void init_proc_603E (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_604 (PPC_NONE) #define POWERPC_MSRM_604 (0x000000000005FF77ULL) #define POWERPC_MMU_604 (POWERPC_MMU_32B) //#define POWERPC_EXCP_604 (POWERPC_EXCP_604) @@ -4594,6 +4814,7 @@ static void init_proc_604 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_604E (PPC_NONE) #define POWERPC_MSRM_604E (0x000000000005FF77ULL) #define POWERPC_MMU_604E (POWERPC_MMU_32B) #define POWERPC_EXCP_604E (POWERPC_EXCP_604) @@ -4652,6 +4873,7 @@ static void init_proc_604E (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_740 (PPC_NONE) #define POWERPC_MSRM_740 (0x000000000005FF77ULL) #define POWERPC_MMU_740 (POWERPC_MMU_32B) #define POWERPC_EXCP_740 (POWERPC_EXCP_7x0) @@ -4697,6 +4919,7 @@ static void init_proc_740 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_750 (PPC_NONE) #define POWERPC_MSRM_750 (0x000000000005FF77ULL) #define POWERPC_MMU_750 (POWERPC_MMU_32B) #define POWERPC_EXCP_750 (POWERPC_EXCP_7x0) @@ -4788,6 +5011,7 @@ static void init_proc_750 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_750cl (PPC_NONE) #define POWERPC_MSRM_750cl (0x000000000005FF77ULL) #define POWERPC_MMU_750cl (POWERPC_MMU_32B) #define POWERPC_EXCP_750cl (POWERPC_EXCP_7x0) @@ -4926,6 +5150,7 @@ static void init_proc_750cl (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_750cx (PPC_NONE) #define POWERPC_MSRM_750cx (0x000000000005FF77ULL) #define POWERPC_MMU_750cx (POWERPC_MMU_32B) #define POWERPC_EXCP_750cx (POWERPC_EXCP_7x0) @@ -4983,6 +5208,7 @@ static void init_proc_750cx (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_750fx (PPC_NONE) #define POWERPC_MSRM_750fx (0x000000000005FF77ULL) #define POWERPC_MMU_750fx (POWERPC_MMU_32B) #define POWERPC_EXCP_750fx (POWERPC_EXCP_7x0) @@ -5045,6 +5271,7 @@ static void init_proc_750fx (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_750gx (PPC_NONE) #define POWERPC_MSRM_750gx (0x000000000005FF77ULL) #define POWERPC_MMU_750gx (POWERPC_MMU_32B) #define POWERPC_EXCP_750gx (POWERPC_EXCP_7x0) @@ -5107,6 +5334,7 @@ static void init_proc_750gx (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_745 (PPC_NONE) #define POWERPC_MSRM_745 (0x000000000005FF77ULL) #define POWERPC_MMU_745 (POWERPC_MMU_SOFT_6xx) #define POWERPC_EXCP_745 (POWERPC_EXCP_7x5) @@ -5160,6 +5388,7 @@ static void init_proc_745 (CPUPPCState *env) PPC_MEM_SYNC | PPC_MEM_EIEIO | \ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \ PPC_SEGMENT | PPC_EXTERN) +#define POWERPC_INSNS2_755 (PPC_NONE) #define POWERPC_MSRM_755 (0x000000000005FF77ULL) #define POWERPC_MMU_755 (POWERPC_MMU_SOFT_6xx) #define POWERPC_EXCP_755 (POWERPC_EXCP_7x5) @@ -5228,6 +5457,7 @@ static void init_proc_755 (CPUPPCState *env) PPC_MEM_TLBIA | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_ALTIVEC) +#define POWERPC_INSNS2_7400 (PPC_NONE) #define POWERPC_MSRM_7400 (0x000000000205FF77ULL) #define POWERPC_MMU_7400 (POWERPC_MMU_32B) #define POWERPC_EXCP_7400 (POWERPC_EXCP_74xx) @@ -5280,6 +5510,7 @@ static void init_proc_7400 (CPUPPCState *env) PPC_MEM_TLBIA | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_ALTIVEC) +#define POWERPC_INSNS2_7410 (PPC_NONE) #define POWERPC_MSRM_7410 (0x000000000205FF77ULL) #define POWERPC_MMU_7410 (POWERPC_MMU_32B) #define POWERPC_EXCP_7410 (POWERPC_EXCP_74xx) @@ -5338,6 +5569,7 @@ static void init_proc_7410 (CPUPPCState *env) PPC_MEM_TLBIA | PPC_74xx_TLB | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_ALTIVEC) +#define POWERPC_INSNS2_7440 (PPC_NONE) #define POWERPC_MSRM_7440 (0x000000000205FF77ULL) #define POWERPC_MMU_7440 (POWERPC_MMU_SOFT_74xx) #define POWERPC_EXCP_7440 (POWERPC_EXCP_74xx) @@ -5423,6 +5655,7 @@ static void init_proc_7440 (CPUPPCState *env) PPC_MEM_TLBIA | PPC_74xx_TLB | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_ALTIVEC) +#define POWERPC_INSNS2_7450 (PPC_NONE) #define POWERPC_MSRM_7450 (0x000000000205FF77ULL) #define POWERPC_MMU_7450 (POWERPC_MMU_SOFT_74xx) #define POWERPC_EXCP_7450 (POWERPC_EXCP_74xx) @@ -5534,6 +5767,7 @@ static void init_proc_7450 (CPUPPCState *env) PPC_MEM_TLBIA | PPC_74xx_TLB | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_ALTIVEC) +#define POWERPC_INSNS2_7445 (PPC_NONE) #define POWERPC_MSRM_7445 (0x000000000205FF77ULL) #define POWERPC_MMU_7445 (POWERPC_MMU_SOFT_74xx) #define POWERPC_EXCP_7445 (POWERPC_EXCP_74xx) @@ -5648,6 +5882,7 @@ static void init_proc_7445 (CPUPPCState *env) PPC_MEM_TLBIA | PPC_74xx_TLB | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_ALTIVEC) +#define POWERPC_INSNS2_7455 (PPC_NONE) #define POWERPC_MSRM_7455 (0x000000000205FF77ULL) #define POWERPC_MMU_7455 (POWERPC_MMU_SOFT_74xx) #define POWERPC_EXCP_7455 (POWERPC_EXCP_74xx) @@ -5764,6 +5999,7 @@ static void init_proc_7455 (CPUPPCState *env) PPC_MEM_TLBIA | PPC_74xx_TLB | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_ALTIVEC) +#define POWERPC_INSNS2_7457 (PPC_NONE) #define POWERPC_MSRM_7457 (0x000000000205FF77ULL) #define POWERPC_MMU_7457 (POWERPC_MMU_SOFT_74xx) #define POWERPC_EXCP_7457 (POWERPC_EXCP_74xx) @@ -5903,6 +6139,7 @@ static void init_proc_7457 (CPUPPCState *env) PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_64B | PPC_ALTIVEC | \ PPC_SEGMENT_64B | PPC_SLBI) +#define POWERPC_INSNS2_970 (PPC_NONE) #define POWERPC_MSRM_970 (0x900000000204FF36ULL) #define POWERPC_MMU_970 (POWERPC_MMU_64B) //#define POWERPC_EXCP_970 (POWERPC_EXCP_970) @@ -5998,6 +6235,7 @@ static void init_proc_970 (CPUPPCState *env) PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_64B | PPC_ALTIVEC | \ PPC_SEGMENT_64B | PPC_SLBI) +#define POWERPC_INSNS2_970FX (PPC_NONE) #define POWERPC_MSRM_970FX (0x800000000204FF36ULL) #define POWERPC_MMU_970FX (POWERPC_MMU_64B) #define POWERPC_EXCP_970FX (POWERPC_EXCP_970) @@ -6099,6 +6337,7 @@ static void init_proc_970FX (CPUPPCState *env) PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_64B | PPC_ALTIVEC | \ PPC_SEGMENT_64B | PPC_SLBI) +#define POWERPC_INSNS2_970GX (PPC_NONE) #define POWERPC_MSRM_970GX (0x800000000204FF36ULL) #define POWERPC_MMU_970GX (POWERPC_MMU_64B) #define POWERPC_EXCP_970GX (POWERPC_EXCP_970) @@ -6188,6 +6427,7 @@ static void init_proc_970GX (CPUPPCState *env) PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_64B | PPC_ALTIVEC | \ PPC_SEGMENT_64B | PPC_SLBI) +#define POWERPC_INSNS2_970MP (PPC_NONE) #define POWERPC_MSRM_970MP (0x900000000204FF36ULL) #define POWERPC_MMU_970MP (POWERPC_MMU_64B) #define POWERPC_EXCP_970MP (POWERPC_EXCP_970) @@ -6267,6 +6507,87 @@ static void init_proc_970MP (CPUPPCState *env) vscr_init(env, 0x00010000); } +#if defined(TARGET_PPC64) +/* POWER7 */ +#define POWERPC_INSNS_POWER7 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \ + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \ + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \ + PPC_FLOAT_STFIWX | \ + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZT | \ + PPC_MEM_SYNC | PPC_MEM_EIEIO | \ + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ + PPC_64B | PPC_ALTIVEC | \ + PPC_SEGMENT_64B | PPC_SLBI | \ + PPC_POPCNTB | PPC_POPCNTWD) +#define POWERPC_INSNS2_POWER7 (PPC2_VSX | PPC2_DFP) +#define POWERPC_MSRM_POWER7 (0x800000000204FF36ULL) +#define POWERPC_MMU_POWER7 (POWERPC_MMU_2_06) +#define POWERPC_EXCP_POWER7 (POWERPC_EXCP_POWER7) +#define POWERPC_INPUT_POWER7 (PPC_FLAGS_INPUT_POWER7) +#define POWERPC_BFDM_POWER7 (bfd_mach_ppc64) +#define POWERPC_FLAG_POWER7 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \ + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR) +#define check_pow_POWER7 check_pow_nocheck + +static void init_proc_POWER7 (CPUPPCState *env) +{ + gen_spr_ne_601(env); + gen_spr_7xx(env); + /* Time base */ + gen_tbl(env); +#if !defined(CONFIG_USER_ONLY) + /* PURR & SPURR: Hack - treat these as aliases for the TB for now */ + spr_register(env, SPR_PURR, "PURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPURR, "SPURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_CFAR, "SPR_CFAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_cfar, &spr_write_cfar, + 0x00000000); + spr_register(env, SPR_DSCR, "SPR_DSCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +#endif /* !CONFIG_USER_ONLY */ + /* Memory management */ + /* XXX : not implemented */ + spr_register(env, SPR_MMUCFG, "MMUCFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); /* TOFIX */ + /* XXX : not implemented */ + spr_register(env, SPR_CTRL, "SPR_CTRLT", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x80800000); + spr_register(env, SPR_UCTRL, "SPR_CTRLF", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x80800000); + spr_register(env, SPR_VRSAVE, "SPR_VRSAVE", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + 0x00000000); +#if !defined(CONFIG_USER_ONLY) + env->slb_nr = 32; +#endif + init_excp_POWER7(env); + env->dcache_line_size = 128; + env->icache_line_size = 128; + /* Allocate hardware IRQ controller */ + ppcPOWER7_irq_init(env); + /* Can't find information on what this should be on reset. This + * value is the one used by 74xx processors. */ + vscr_init(env, 0x00010000); +} +#endif /* TARGET_PPC64 */ + /* PowerPC 620 */ #define POWERPC_INSNS_620 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \ @@ -6277,6 +6598,7 @@ static void init_proc_970MP (CPUPPCState *env) PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \ PPC_SEGMENT | PPC_EXTERN | \ PPC_64B | PPC_SLBI) +#define POWERPC_INSNS2_620 (PPC_NONE) #define POWERPC_MSRM_620 (0x800000000005FF77ULL) //#define POWERPC_MMU_620 (POWERPC_MMU_620) #define POWERPC_EXCP_620 (POWERPC_EXCP_970) @@ -6312,6 +6634,7 @@ static void init_proc_620 (CPUPPCState *env) /* Default 32 bits PowerPC target will be 604 */ #define CPU_POWERPC_PPC32 CPU_POWERPC_604 #define POWERPC_INSNS_PPC32 POWERPC_INSNS_604 +#define POWERPC_INSNS2_PPC32 POWERPC_INSNS2_604 #define POWERPC_MSRM_PPC32 POWERPC_MSRM_604 #define POWERPC_MMU_PPC32 POWERPC_MMU_604 #define POWERPC_EXCP_PPC32 POWERPC_EXCP_604 @@ -6324,6 +6647,7 @@ static void init_proc_620 (CPUPPCState *env) /* Default 64 bits PowerPC target will be 970 FX */ #define CPU_POWERPC_PPC64 CPU_POWERPC_970FX #define POWERPC_INSNS_PPC64 POWERPC_INSNS_970FX +#define POWERPC_INSNS2_PPC64 POWERPC_INSNS2_970FX #define POWERPC_MSRM_PPC64 POWERPC_MSRM_970FX #define POWERPC_MMU_PPC64 POWERPC_MMU_970FX #define POWERPC_EXCP_PPC64 POWERPC_EXCP_970FX @@ -6335,27 +6659,29 @@ static void init_proc_620 (CPUPPCState *env) /* Default PowerPC target will be PowerPC 32 */ #if defined (TARGET_PPC64) && 0 // XXX: TODO -#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC64 -#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC64 -#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC64 -#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC64 -#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC64 -#define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC64 -#define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC64 -#define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC64 -#define check_pow_DEFAULT check_pow_PPC64 -#define init_proc_DEFAULT init_proc_PPC64 +#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC64 +#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC64 +#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS_PPC64 +#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC64 +#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC64 +#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC64 +#define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC64 +#define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC64 +#define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC64 +#define check_pow_DEFAULT check_pow_PPC64 +#define init_proc_DEFAULT init_proc_PPC64 #else -#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC32 -#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC32 -#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC32 -#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC32 -#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC32 -#define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC32 -#define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC32 -#define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC32 -#define check_pow_DEFAULT check_pow_PPC32 -#define init_proc_DEFAULT init_proc_PPC32 +#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC32 +#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC32 +#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS_PPC32 +#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC32 +#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC32 +#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC32 +#define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC32 +#define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC32 +#define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC32 +#define check_pow_DEFAULT check_pow_PPC32 +#define init_proc_DEFAULT init_proc_PPC32 #endif /*****************************************************************************/ @@ -6989,6 +7315,10 @@ enum { CPU_POWERPC_POWER6 = 0x003E0000, CPU_POWERPC_POWER6_5 = 0x0F000001, /* POWER6 in POWER5 mode */ CPU_POWERPC_POWER6A = 0x0F000002, +#define CPU_POWERPC_POWER7 CPU_POWERPC_POWER7_v20 + CPU_POWERPC_POWER7_v20 = 0x003F0200, + CPU_POWERPC_POWER7_v21 = 0x003F0201, + CPU_POWERPC_POWER7_v23 = 0x003F0203, CPU_POWERPC_970 = 0x00390202, #define CPU_POWERPC_970FX CPU_POWERPC_970FX_v31 CPU_POWERPC_970FX_v10 = 0x00391100, @@ -7202,18 +7532,19 @@ enum { /* PowerPC CPU definitions */ #define POWERPC_DEF_SVR(_name, _pvr, _svr, _type) \ { \ - .name = _name, \ - .pvr = _pvr, \ - .svr = _svr, \ - .insns_flags = glue(POWERPC_INSNS_,_type), \ - .msr_mask = glue(POWERPC_MSRM_,_type), \ - .mmu_model = glue(POWERPC_MMU_,_type), \ - .excp_model = glue(POWERPC_EXCP_,_type), \ - .bus_model = glue(POWERPC_INPUT_,_type), \ - .bfd_mach = glue(POWERPC_BFDM_,_type), \ - .flags = glue(POWERPC_FLAG_,_type), \ - .init_proc = &glue(init_proc_,_type), \ - .check_pow = &glue(check_pow_,_type), \ + .name = _name, \ + .pvr = _pvr, \ + .svr = _svr, \ + .insns_flags = glue(POWERPC_INSNS_,_type), \ + .insns_flags2 = glue(POWERPC_INSNS2_,_type), \ + .msr_mask = glue(POWERPC_MSRM_,_type), \ + .mmu_model = glue(POWERPC_MMU_,_type), \ + .excp_model = glue(POWERPC_EXCP_,_type), \ + .bus_model = glue(POWERPC_INPUT_,_type), \ + .bfd_mach = glue(POWERPC_BFDM_,_type), \ + .flags = glue(POWERPC_FLAG_,_type), \ + .init_proc = &glue(init_proc_,_type), \ + .check_pow = &glue(check_pow_,_type), \ } #define POWERPC_DEF(_name, _pvr, _type) \ POWERPC_DEF_SVR(_name, _pvr, POWERPC_SVR_NONE, _type) @@ -8791,6 +9122,11 @@ static const ppc_def_t ppc_defs[] = { /* POWER6A */ POWERPC_DEF("POWER6A", CPU_POWERPC_POWER6A, POWER6), #endif + /* POWER7 */ + POWERPC_DEF("POWER7", CPU_POWERPC_POWER7, POWER7), + POWERPC_DEF("POWER7_v2.0", CPU_POWERPC_POWER7_v20, POWER7), + POWERPC_DEF("POWER7_v2.1", CPU_POWERPC_POWER7_v21, POWER7), + POWERPC_DEF("POWER7_v2.3", CPU_POWERPC_POWER7_v23, POWER7), /* PowerPC 970 */ POWERPC_DEF("970", CPU_POWERPC_970, 970), /* PowerPC 970FX (G5) */ @@ -8897,7 +9233,7 @@ static const ppc_def_t ppc_defs[] = { }; /*****************************************************************************/ -/* Generic CPU instanciation routine */ +/* Generic CPU instantiation routine */ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def) { #if !defined(CONFIG_USER_ONLY) @@ -8914,6 +9250,7 @@ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def) env->nb_BATs = 0; env->nb_tlb = 0; env->nb_ways = 0; + env->tlb_type = TLB_NONE; #endif /* Register SPR common to all PowerPC implementations */ gen_spr_generic(env); @@ -9038,7 +9375,17 @@ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def) int nb_tlb = env->nb_tlb; if (env->id_tlbs != 0) nb_tlb *= 2; - env->tlb = qemu_mallocz(nb_tlb * sizeof(ppc_tlb_t)); + switch (env->tlb_type) { + case TLB_6XX: + env->tlb.tlb6 = g_malloc0(nb_tlb * sizeof(ppc6xx_tlb_t)); + break; + case TLB_EMB: + env->tlb.tlbe = g_malloc0(nb_tlb * sizeof(ppcemb_tlb_t)); + break; + case TLB_MAS: + env->tlb.tlbm = g_malloc0(nb_tlb * sizeof(ppcmas_tlb_t)); + break; + } /* Pre-compute some useful values */ env->tlb_per_way = env->nb_tlb / env->nb_ways; } @@ -9285,7 +9632,8 @@ static int create_ppc_opcodes (CPUPPCState *env, const ppc_def_t *def) fill_new_table(env->opcodes, 0x40); for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { - if ((opc->handler.type & def->insns_flags) != 0) { + if (((opc->handler.type & def->insns_flags) != 0) || + ((opc->handler.type2 & def->insns_flags2) != 0)) { if (register_insn(env->opcodes, opc) < 0) { printf("*** ERROR initializing PowerPC instruction " "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2, @@ -9381,8 +9729,7 @@ static int gdb_get_float_reg(CPUState *env, uint8_t *mem_buf, int n) return 8; } if (n == 32) { - /* FPSCR not implemented */ - memset(mem_buf, 0, 4); + stl_p(mem_buf, env->fpscr); return 4; } return 0; @@ -9498,6 +9845,23 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) env->excp_model = def->excp_model; env->bus_model = def->bus_model; env->insns_flags = def->insns_flags; + env->insns_flags2 = def->insns_flags2; + if (!kvm_enabled()) { + /* TCG doesn't (yet) emulate some groups of instructions that + * are implemented on some otherwise supported CPUs (e.g. VSX + * and decimal floating point instructions on POWER7). We + * remove unsupported instruction groups from the cpu state's + * instruction masks and hope the guest can cope. For at + * least the pseries machine, the unavailability of these + * instructions can be advertise to the guest via the device + * tree. + * + * FIXME: we should have a similar masking for CPU features + * not accessible under KVM, but so far, there aren't any of + * those. */ + env->insns_flags &= PPC_TCG_INSNS; + env->insns_flags2 &= PPC_TCG_INSNS2; + } env->flags = def->flags; env->bfd_mach = def->bfd_mach; env->check_pow = def->check_pow; @@ -9547,8 +9911,8 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) case POWERPC_MMU_BOOKE: mmu_model = "PowerPC BookE"; break; - case POWERPC_MMU_BOOKE_FSL: - mmu_model = "PowerPC BookE FSL"; + case POWERPC_MMU_BOOKE206: + mmu_model = "PowerPC BookE 2.06"; break; case POWERPC_MMU_601: mmu_model = "PowerPC 601"; @@ -9683,42 +10047,34 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) return 0; } -static const ppc_def_t *ppc_find_by_pvr (uint32_t pvr) +static bool ppc_cpu_usable(const ppc_def_t *def) { - const ppc_def_t *ret; - uint32_t pvr_rev; - int i, best, match, best_match, max; +#if defined(TARGET_PPCEMB) + /* When using the ppcemb target, we only support 440 style cores */ + if (def->mmu_model != POWERPC_MMU_BOOKE) { + return false; + } +#endif - ret = NULL; - max = ARRAY_SIZE(ppc_defs); - best = -1; - pvr_rev = pvr & 0xFFFF; - /* We want all specified bits to match */ - best_match = 32 - ctz32(pvr_rev); - for (i = 0; i < max; i++) { - /* We check that the 16 higher bits are the same to ensure the CPU - * model will be the choosen one. - */ - if (((pvr ^ ppc_defs[i].pvr) >> 16) == 0) { - /* We want as much as possible of the low-level 16 bits - * to be the same but we allow inexact matches. - */ - match = clz32(pvr_rev ^ (ppc_defs[i].pvr & 0xFFFF)); - /* We check '>=' instead of '>' because the PPC_defs table - * is ordered by increasing revision. - * Then, we will match the higher revision compatible - * with the requested PVR - */ - if (match >= best_match) { - best = i; - best_match = match; - } + return true; +} + +const ppc_def_t *ppc_find_by_pvr(uint32_t pvr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) { + if (!ppc_cpu_usable(&ppc_defs[i])) { + continue; + } + + /* If we have an exact match, we're done */ + if (pvr == ppc_defs[i].pvr) { + return &ppc_defs[i]; } } - if (best != -1) - ret = &ppc_defs[best]; - return ret; + return NULL; } #include @@ -9729,6 +10085,10 @@ const ppc_def_t *cpu_ppc_find_by_name (const char *name) const char *p; int i, max, len; + if (kvm_enabled() && (strcasecmp(name, "host") == 0)) { + return kvmppc_host_cpu_def(); + } + /* Check if the given name is a PVR */ len = strlen(name); if (len == 10 && name[0] == '0' && name[1] == 'x') { @@ -9747,6 +10107,10 @@ const ppc_def_t *cpu_ppc_find_by_name (const char *name) ret = NULL; max = ARRAY_SIZE(ppc_defs); for (i = 0; i < max; i++) { + if (!ppc_cpu_usable(&ppc_defs[i])) { + continue; + } + if (strcasecmp(name, ppc_defs[i].name) == 0) { ret = &ppc_defs[i]; break; @@ -9762,6 +10126,10 @@ void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf) max = ARRAY_SIZE(ppc_defs); for (i = 0; i < max; i++) { + if (!ppc_cpu_usable(&ppc_defs[i])) { + continue; + } + (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n", ppc_defs[i].name, ppc_defs[i].pvr); } diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index e47c372..202c098 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -26,24 +26,35 @@ #define CPUState struct CPUS390XState #include "cpu-defs.h" +#define TARGET_PAGE_BITS 12 + +#define TARGET_PHYS_ADDR_SPACE_BITS 64 +#define TARGET_VIRT_ADDR_SPACE_BITS 64 + +#include "cpu-all.h" #include "softfloat.h" -#define NB_MMU_MODES 2 +#define NB_MMU_MODES 3 -typedef union FPReg { - struct { -#ifdef WORDS_BIGENDIAN - float32 e; - int32_t __pad; -#else - int32_t __pad; - float32 e; -#endif - }; - float64 d; - uint64_t i; -} FPReg; +#define MMU_MODE0_SUFFIX _primary +#define MMU_MODE1_SUFFIX _secondary +#define MMU_MODE2_SUFFIX _home + +#define MMU_USER_IDX 1 + +#define MAX_EXT_QUEUE 16 + +typedef struct PSW { + uint64_t mask; + uint64_t addr; +} PSW; + +typedef struct ExtQueue { + uint32_t code; + uint32_t param; + uint32_t param64; +} ExtQueue; typedef struct CPUS390XState { uint64_t regs[16]; /* GP registers */ @@ -51,42 +62,217 @@ typedef struct CPUS390XState { uint32_t aregs[16]; /* access registers */ uint32_t fpc; /* floating-point control register */ - FPReg fregs[16]; /* FP registers */ + CPU_DoubleU fregs[16]; /* FP registers */ float_status fpu_status; /* passed to softfloat lib */ - struct { - uint64_t mask; - uint64_t addr; - } psw; + PSW psw; - int cc; /* condition code (0-3) */ + uint32_t cc_op; + uint64_t cc_src; + uint64_t cc_dst; + uint64_t cc_vr; uint64_t __excp_addr; + uint64_t psa; + + uint32_t int_pgm_code; + uint32_t int_pgm_ilc; + + uint32_t int_svc_code; + uint32_t int_svc_ilc; + + uint64_t cregs[16]; /* control registers */ + + int pending_int; + ExtQueue ext_queue[MAX_EXT_QUEUE]; + + int ext_index; CPU_COMMON + + /* reset does memset(0) up to here */ + + int cpu_num; + uint8_t *storage_keys; + + uint64_t tod_offset; + uint64_t tod_basetime; + QEMUTimer *tod_timer; + + QEMUTimer *cpu_timer; } CPUS390XState; #if defined(CONFIG_USER_ONLY) static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) { - if (newsp) + if (newsp) { env->regs[15] = newsp; + } env->regs[0] = 0; } #endif -#define MMU_MODE0_SUFFIX _kernel -#define MMU_MODE1_SUFFIX _user -#define MMU_USER_IDX 1 +/* Interrupt Codes */ +/* Program Interrupts */ +#define PGM_OPERATION 0x0001 +#define PGM_PRIVILEGED 0x0002 +#define PGM_EXECUTE 0x0003 +#define PGM_PROTECTION 0x0004 +#define PGM_ADDRESSING 0x0005 +#define PGM_SPECIFICATION 0x0006 +#define PGM_DATA 0x0007 +#define PGM_FIXPT_OVERFLOW 0x0008 +#define PGM_FIXPT_DIVIDE 0x0009 +#define PGM_DEC_OVERFLOW 0x000a +#define PGM_DEC_DIVIDE 0x000b +#define PGM_HFP_EXP_OVERFLOW 0x000c +#define PGM_HFP_EXP_UNDERFLOW 0x000d +#define PGM_HFP_SIGNIFICANCE 0x000e +#define PGM_HFP_DIVIDE 0x000f +#define PGM_SEGMENT_TRANS 0x0010 +#define PGM_PAGE_TRANS 0x0011 +#define PGM_TRANS_SPEC 0x0012 +#define PGM_SPECIAL_OP 0x0013 +#define PGM_OPERAND 0x0015 +#define PGM_TRACE_TABLE 0x0016 +#define PGM_SPACE_SWITCH 0x001c +#define PGM_HFP_SQRT 0x001d +#define PGM_PC_TRANS_SPEC 0x001f +#define PGM_AFX_TRANS 0x0020 +#define PGM_ASX_TRANS 0x0021 +#define PGM_LX_TRANS 0x0022 +#define PGM_EX_TRANS 0x0023 +#define PGM_PRIM_AUTH 0x0024 +#define PGM_SEC_AUTH 0x0025 +#define PGM_ALET_SPEC 0x0028 +#define PGM_ALEN_SPEC 0x0029 +#define PGM_ALE_SEQ 0x002a +#define PGM_ASTE_VALID 0x002b +#define PGM_ASTE_SEQ 0x002c +#define PGM_EXT_AUTH 0x002d +#define PGM_STACK_FULL 0x0030 +#define PGM_STACK_EMPTY 0x0031 +#define PGM_STACK_SPEC 0x0032 +#define PGM_STACK_TYPE 0x0033 +#define PGM_STACK_OP 0x0034 +#define PGM_ASCE_TYPE 0x0038 +#define PGM_REG_FIRST_TRANS 0x0039 +#define PGM_REG_SEC_TRANS 0x003a +#define PGM_REG_THIRD_TRANS 0x003b +#define PGM_MONITOR 0x0040 +#define PGM_PER 0x0080 +#define PGM_CRYPTO 0x0119 + +/* External Interrupts */ +#define EXT_INTERRUPT_KEY 0x0040 +#define EXT_CLOCK_COMP 0x1004 +#define EXT_CPU_TIMER 0x1005 +#define EXT_MALFUNCTION 0x1200 +#define EXT_EMERGENCY 0x1201 +#define EXT_EXTERNAL_CALL 0x1202 +#define EXT_ETR 0x1406 +#define EXT_SERVICE 0x2401 +#define EXT_VIRTIO 0x2603 + +/* PSW defines */ +#undef PSW_MASK_PER +#undef PSW_MASK_DAT +#undef PSW_MASK_IO +#undef PSW_MASK_EXT +#undef PSW_MASK_KEY +#undef PSW_SHIFT_KEY +#undef PSW_MASK_MCHECK +#undef PSW_MASK_WAIT +#undef PSW_MASK_PSTATE +#undef PSW_MASK_ASC +#undef PSW_MASK_CC +#undef PSW_MASK_PM +#undef PSW_MASK_64 + +#define PSW_MASK_PER 0x4000000000000000ULL +#define PSW_MASK_DAT 0x0400000000000000ULL +#define PSW_MASK_IO 0x0200000000000000ULL +#define PSW_MASK_EXT 0x0100000000000000ULL +#define PSW_MASK_KEY 0x00F0000000000000ULL +#define PSW_SHIFT_KEY 56 +#define PSW_MASK_MCHECK 0x0004000000000000ULL +#define PSW_MASK_WAIT 0x0002000000000000ULL +#define PSW_MASK_PSTATE 0x0001000000000000ULL +#define PSW_MASK_ASC 0x0000C00000000000ULL +#define PSW_MASK_CC 0x0000300000000000ULL +#define PSW_MASK_PM 0x00000F0000000000ULL +#define PSW_MASK_64 0x0000000100000000ULL +#define PSW_MASK_32 0x0000000080000000ULL + +#undef PSW_ASC_PRIMARY +#undef PSW_ASC_ACCREG +#undef PSW_ASC_SECONDARY +#undef PSW_ASC_HOME + +#define PSW_ASC_PRIMARY 0x0000000000000000ULL +#define PSW_ASC_ACCREG 0x0000400000000000ULL +#define PSW_ASC_SECONDARY 0x0000800000000000ULL +#define PSW_ASC_HOME 0x0000C00000000000ULL + +/* tb flags */ + +#define FLAG_MASK_PER (PSW_MASK_PER >> 32) +#define FLAG_MASK_DAT (PSW_MASK_DAT >> 32) +#define FLAG_MASK_IO (PSW_MASK_IO >> 32) +#define FLAG_MASK_EXT (PSW_MASK_EXT >> 32) +#define FLAG_MASK_KEY (PSW_MASK_KEY >> 32) +#define FLAG_MASK_MCHECK (PSW_MASK_MCHECK >> 32) +#define FLAG_MASK_WAIT (PSW_MASK_WAIT >> 32) +#define FLAG_MASK_PSTATE (PSW_MASK_PSTATE >> 32) +#define FLAG_MASK_ASC (PSW_MASK_ASC >> 32) +#define FLAG_MASK_CC (PSW_MASK_CC >> 32) +#define FLAG_MASK_PM (PSW_MASK_PM >> 32) +#define FLAG_MASK_64 (PSW_MASK_64 >> 32) +#define FLAG_MASK_32 0x00001000 + static inline int cpu_mmu_index (CPUState *env) { - /* XXX: Currently we don't implement virtual memory */ + if (env->psw.mask & PSW_MASK_PSTATE) { + return 1; + } + + return 0; +} + +static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc, + target_ulong *cs_base, int *flags) +{ + *pc = env->psw.addr; + *cs_base = 0; + *flags = ((env->psw.mask >> 32) & ~FLAG_MASK_CC) | + ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0); +} + +static inline int get_ilc(uint8_t opc) +{ + switch (opc >> 6) { + case 0: + return 1; + case 1: + case 2: + return 2; + case 3: + return 3; + } + return 0; } +#define ILC_LATER 0x20 +#define ILC_LATER_INC 0x21 +#define ILC_LATER_INC_2 0x22 + + CPUS390XState *cpu_s390x_init(const char *cpu_model); +void s390x_translate_init(void); int cpu_s390x_exec(CPUS390XState *s); void cpu_s390x_close(CPUS390XState *s); +void do_interrupt (CPUState *env); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero @@ -94,44 +280,85 @@ void cpu_s390x_close(CPUS390XState *s); int cpu_s390x_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw, - int mmu_idx, int is_softmuu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault -#define TARGET_PAGE_BITS 12 - -/* ??? This is certainly wrong for 64-bit s390x, but given that only KVM - emulation actually works, this is good enough for a placeholder. */ -#define TARGET_PHYS_ADDR_SPACE_BITS 32 -#define TARGET_VIRT_ADDR_SPACE_BITS 32 #ifndef CONFIG_USER_ONLY -int s390_virtio_hypercall(CPUState *env); +int s390_virtio_hypercall(CPUState *env, uint64_t mem, uint64_t hypercall); + +#ifdef CONFIG_KVM +void kvm_s390_interrupt(CPUState *env, int type, uint32_t code); void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token); +void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm, + uint64_t parm64, int vm); +#else +static inline void kvm_s390_interrupt(CPUState *env, int type, uint32_t code) +{ +} + +static inline void kvm_s390_virtio_irq(CPUState *env, int config_change, + uint64_t token) +{ +} + +static inline void kvm_s390_interrupt_internal(CPUState *env, int type, + uint32_t parm, uint64_t parm64, + int vm) +{ +} +#endif CPUState *s390_cpu_addr2state(uint16_t cpu_addr); +void s390_add_running_cpu(CPUState *env); +unsigned s390_del_running_cpu(CPUState *env); + +/* from s390-virtio-bus */ +extern const target_phys_addr_t virtio_size; + +#else +static inline void s390_add_running_cpu(CPUState *env) +{ +} + +static inline unsigned s390_del_running_cpu(CPUState *env) +{ + return 0; +} #endif +void cpu_lock(void); +void cpu_unlock(void); +static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls) +{ + env->aregs[0] = newtls >> 32; + env->aregs[1] = newtls & 0xffffffffULL; +} #define cpu_init cpu_s390x_init #define cpu_exec cpu_s390x_exec #define cpu_gen_code cpu_s390x_gen_code +#define cpu_signal_handler cpu_s390x_signal_handler -#include "cpu-all.h" +#include "exec-all.h" + +#ifdef CONFIG_USER_ONLY #define EXCP_OPEX 1 /* operation exception (sigill) */ #define EXCP_SVC 2 /* supervisor call (syscall) */ #define EXCP_ADDR 5 /* addressing exception */ -#define EXCP_EXECUTE_SVC 0xff00000 /* supervisor call via execute insn */ +#define EXCP_SPEC 6 /* specification exception */ -static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc, - target_ulong *cs_base, int *flags) -{ - *pc = env->psw.addr; - /* XXX this is correct for user-mode emulation, but needs - * the asce register information as well when softmmu - * is implemented in the future */ - *cs_base = 0; - *flags = env->psw.mask; -} +#else + +#define EXCP_EXT 1 /* external interrupt */ +#define EXCP_SVC 2 /* supervisor call (syscall) */ +#define EXCP_PGM 3 /* program interruption */ + +#endif /* CONFIG_USER_ONLY */ + +#define INTERRUPT_EXT (1 << 0) +#define INTERRUPT_TOD (1 << 1) +#define INTERRUPT_CPUTIMER (1 << 2) /* Program Status Word. */ #define S390_PSWM_REGNUM 0 @@ -265,5 +492,500 @@ static inline void cpu_get_tb_cpu_state(CPUState* env, target_ulong *pc, #define S390_NUM_PSEUDO_REGS 2 #define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2) +/* CC optimization */ + +enum cc_op { + CC_OP_CONST0 = 0, /* CC is 0 */ + CC_OP_CONST1, /* CC is 1 */ + CC_OP_CONST2, /* CC is 2 */ + CC_OP_CONST3, /* CC is 3 */ + + CC_OP_DYNAMIC, /* CC calculation defined by env->cc_op */ + CC_OP_STATIC, /* CC value is env->cc_op */ + + CC_OP_NZ, /* env->cc_dst != 0 */ + CC_OP_LTGT_32, /* signed less/greater than (32bit) */ + CC_OP_LTGT_64, /* signed less/greater than (64bit) */ + CC_OP_LTUGTU_32, /* unsigned less/greater than (32bit) */ + CC_OP_LTUGTU_64, /* unsigned less/greater than (64bit) */ + CC_OP_LTGT0_32, /* signed less/greater than 0 (32bit) */ + CC_OP_LTGT0_64, /* signed less/greater than 0 (64bit) */ + + CC_OP_ADD_64, /* overflow on add (64bit) */ + CC_OP_ADDU_64, /* overflow on unsigned add (64bit) */ + CC_OP_SUB_64, /* overflow on substraction (64bit) */ + CC_OP_SUBU_64, /* overflow on unsigned substraction (64bit) */ + CC_OP_ABS_64, /* sign eval on abs (64bit) */ + CC_OP_NABS_64, /* sign eval on nabs (64bit) */ + + CC_OP_ADD_32, /* overflow on add (32bit) */ + CC_OP_ADDU_32, /* overflow on unsigned add (32bit) */ + CC_OP_SUB_32, /* overflow on substraction (32bit) */ + CC_OP_SUBU_32, /* overflow on unsigned substraction (32bit) */ + CC_OP_ABS_32, /* sign eval on abs (64bit) */ + CC_OP_NABS_32, /* sign eval on nabs (64bit) */ + + CC_OP_COMP_32, /* complement */ + CC_OP_COMP_64, /* complement */ + + CC_OP_TM_32, /* test under mask (32bit) */ + CC_OP_TM_64, /* test under mask (64bit) */ + + CC_OP_LTGT_F32, /* FP compare (32bit) */ + CC_OP_LTGT_F64, /* FP compare (64bit) */ + + CC_OP_NZ_F32, /* FP dst != 0 (32bit) */ + CC_OP_NZ_F64, /* FP dst != 0 (64bit) */ + + CC_OP_ICM, /* insert characters under mask */ + CC_OP_SLAG, /* Calculate shift left signed */ + CC_OP_MAX +}; + +static const char *cc_names[] = { + [CC_OP_CONST0] = "CC_OP_CONST0", + [CC_OP_CONST1] = "CC_OP_CONST1", + [CC_OP_CONST2] = "CC_OP_CONST2", + [CC_OP_CONST3] = "CC_OP_CONST3", + [CC_OP_DYNAMIC] = "CC_OP_DYNAMIC", + [CC_OP_STATIC] = "CC_OP_STATIC", + [CC_OP_NZ] = "CC_OP_NZ", + [CC_OP_LTGT_32] = "CC_OP_LTGT_32", + [CC_OP_LTGT_64] = "CC_OP_LTGT_64", + [CC_OP_LTUGTU_32] = "CC_OP_LTUGTU_32", + [CC_OP_LTUGTU_64] = "CC_OP_LTUGTU_64", + [CC_OP_LTGT0_32] = "CC_OP_LTGT0_32", + [CC_OP_LTGT0_64] = "CC_OP_LTGT0_64", + [CC_OP_ADD_64] = "CC_OP_ADD_64", + [CC_OP_ADDU_64] = "CC_OP_ADDU_64", + [CC_OP_SUB_64] = "CC_OP_SUB_64", + [CC_OP_SUBU_64] = "CC_OP_SUBU_64", + [CC_OP_ABS_64] = "CC_OP_ABS_64", + [CC_OP_NABS_64] = "CC_OP_NABS_64", + [CC_OP_ADD_32] = "CC_OP_ADD_32", + [CC_OP_ADDU_32] = "CC_OP_ADDU_32", + [CC_OP_SUB_32] = "CC_OP_SUB_32", + [CC_OP_SUBU_32] = "CC_OP_SUBU_32", + [CC_OP_ABS_32] = "CC_OP_ABS_32", + [CC_OP_NABS_32] = "CC_OP_NABS_32", + [CC_OP_COMP_32] = "CC_OP_COMP_32", + [CC_OP_COMP_64] = "CC_OP_COMP_64", + [CC_OP_TM_32] = "CC_OP_TM_32", + [CC_OP_TM_64] = "CC_OP_TM_64", + [CC_OP_LTGT_F32] = "CC_OP_LTGT_F32", + [CC_OP_LTGT_F64] = "CC_OP_LTGT_F64", + [CC_OP_NZ_F32] = "CC_OP_NZ_F32", + [CC_OP_NZ_F64] = "CC_OP_NZ_F64", + [CC_OP_ICM] = "CC_OP_ICM", + [CC_OP_SLAG] = "CC_OP_SLAG", +}; + +static inline const char *cc_name(int cc_op) +{ + return cc_names[cc_op]; +} + +/* SCLP PV interface defines */ +#define SCLP_CMDW_READ_SCP_INFO 0x00020001 +#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 + +#define SCP_LENGTH 0x00 +#define SCP_FUNCTION_CODE 0x02 +#define SCP_CONTROL_MASK 0x03 +#define SCP_RESPONSE_CODE 0x06 +#define SCP_MEM_CODE 0x08 +#define SCP_INCREMENT 0x0a + +typedef struct LowCore +{ + /* prefix area: defined by architecture */ + uint32_t ccw1[2]; /* 0x000 */ + uint32_t ccw2[4]; /* 0x008 */ + uint8_t pad1[0x80-0x18]; /* 0x018 */ + uint32_t ext_params; /* 0x080 */ + uint16_t cpu_addr; /* 0x084 */ + uint16_t ext_int_code; /* 0x086 */ + uint16_t svc_ilc; /* 0x088 */ + uint16_t svc_code; /* 0x08a */ + uint16_t pgm_ilc; /* 0x08c */ + uint16_t pgm_code; /* 0x08e */ + uint32_t data_exc_code; /* 0x090 */ + uint16_t mon_class_num; /* 0x094 */ + uint16_t per_perc_atmid; /* 0x096 */ + uint64_t per_address; /* 0x098 */ + uint8_t exc_access_id; /* 0x0a0 */ + uint8_t per_access_id; /* 0x0a1 */ + uint8_t op_access_id; /* 0x0a2 */ + uint8_t ar_access_id; /* 0x0a3 */ + uint8_t pad2[0xA8-0xA4]; /* 0x0a4 */ + uint64_t trans_exc_code; /* 0x0a8 */ + uint64_t monitor_code; /* 0x0b0 */ + uint16_t subchannel_id; /* 0x0b8 */ + uint16_t subchannel_nr; /* 0x0ba */ + uint32_t io_int_parm; /* 0x0bc */ + uint32_t io_int_word; /* 0x0c0 */ + uint8_t pad3[0xc8-0xc4]; /* 0x0c4 */ + uint32_t stfl_fac_list; /* 0x0c8 */ + uint8_t pad4[0xe8-0xcc]; /* 0x0cc */ + uint32_t mcck_interruption_code[2]; /* 0x0e8 */ + uint8_t pad5[0xf4-0xf0]; /* 0x0f0 */ + uint32_t external_damage_code; /* 0x0f4 */ + uint64_t failing_storage_address; /* 0x0f8 */ + uint8_t pad6[0x120-0x100]; /* 0x100 */ + PSW restart_old_psw; /* 0x120 */ + PSW external_old_psw; /* 0x130 */ + PSW svc_old_psw; /* 0x140 */ + PSW program_old_psw; /* 0x150 */ + PSW mcck_old_psw; /* 0x160 */ + PSW io_old_psw; /* 0x170 */ + uint8_t pad7[0x1a0-0x180]; /* 0x180 */ + PSW restart_psw; /* 0x1a0 */ + PSW external_new_psw; /* 0x1b0 */ + PSW svc_new_psw; /* 0x1c0 */ + PSW program_new_psw; /* 0x1d0 */ + PSW mcck_new_psw; /* 0x1e0 */ + PSW io_new_psw; /* 0x1f0 */ + PSW return_psw; /* 0x200 */ + uint8_t irb[64]; /* 0x210 */ + uint64_t sync_enter_timer; /* 0x250 */ + uint64_t async_enter_timer; /* 0x258 */ + uint64_t exit_timer; /* 0x260 */ + uint64_t last_update_timer; /* 0x268 */ + uint64_t user_timer; /* 0x270 */ + uint64_t system_timer; /* 0x278 */ + uint64_t last_update_clock; /* 0x280 */ + uint64_t steal_clock; /* 0x288 */ + PSW return_mcck_psw; /* 0x290 */ + uint8_t pad8[0xc00-0x2a0]; /* 0x2a0 */ + /* System info area */ + uint64_t save_area[16]; /* 0xc00 */ + uint8_t pad9[0xd40-0xc80]; /* 0xc80 */ + uint64_t kernel_stack; /* 0xd40 */ + uint64_t thread_info; /* 0xd48 */ + uint64_t async_stack; /* 0xd50 */ + uint64_t kernel_asce; /* 0xd58 */ + uint64_t user_asce; /* 0xd60 */ + uint64_t panic_stack; /* 0xd68 */ + uint64_t user_exec_asce; /* 0xd70 */ + uint8_t pad10[0xdc0-0xd78]; /* 0xd78 */ + + /* SMP info area: defined by DJB */ + uint64_t clock_comparator; /* 0xdc0 */ + uint64_t ext_call_fast; /* 0xdc8 */ + uint64_t percpu_offset; /* 0xdd0 */ + uint64_t current_task; /* 0xdd8 */ + uint32_t softirq_pending; /* 0xde0 */ + uint32_t pad_0x0de4; /* 0xde4 */ + uint64_t int_clock; /* 0xde8 */ + uint8_t pad12[0xe00-0xdf0]; /* 0xdf0 */ + + /* 0xe00 is used as indicator for dump tools */ + /* whether the kernel died with panic() or not */ + uint32_t panic_magic; /* 0xe00 */ + + uint8_t pad13[0x11b8-0xe04]; /* 0xe04 */ + + /* 64 bit extparam used for pfault, diag 250 etc */ + uint64_t ext_params2; /* 0x11B8 */ + + uint8_t pad14[0x1200-0x11C0]; /* 0x11C0 */ + + /* System info area */ + + uint64_t floating_pt_save_area[16]; /* 0x1200 */ + uint64_t gpregs_save_area[16]; /* 0x1280 */ + uint32_t st_status_fixed_logout[4]; /* 0x1300 */ + uint8_t pad15[0x1318-0x1310]; /* 0x1310 */ + uint32_t prefixreg_save_area; /* 0x1318 */ + uint32_t fpt_creg_save_area; /* 0x131c */ + uint8_t pad16[0x1324-0x1320]; /* 0x1320 */ + uint32_t tod_progreg_save_area; /* 0x1324 */ + uint32_t cpu_timer_save_area[2]; /* 0x1328 */ + uint32_t clock_comp_save_area[2]; /* 0x1330 */ + uint8_t pad17[0x1340-0x1338]; /* 0x1338 */ + uint32_t access_regs_save_area[16]; /* 0x1340 */ + uint64_t cregs_save_area[16]; /* 0x1380 */ + + /* align to the top of the prefix area */ + + uint8_t pad18[0x2000-0x1400]; /* 0x1400 */ +} QEMU_PACKED LowCore; + +/* STSI */ +#define STSI_LEVEL_MASK 0x00000000f0000000ULL +#define STSI_LEVEL_CURRENT 0x0000000000000000ULL +#define STSI_LEVEL_1 0x0000000010000000ULL +#define STSI_LEVEL_2 0x0000000020000000ULL +#define STSI_LEVEL_3 0x0000000030000000ULL +#define STSI_R0_RESERVED_MASK 0x000000000fffff00ULL +#define STSI_R0_SEL1_MASK 0x00000000000000ffULL +#define STSI_R1_RESERVED_MASK 0x00000000ffff0000ULL +#define STSI_R1_SEL2_MASK 0x000000000000ffffULL + +/* Basic Machine Configuration */ +struct sysib_111 { + uint32_t res1[8]; + uint8_t manuf[16]; + uint8_t type[4]; + uint8_t res2[12]; + uint8_t model[16]; + uint8_t sequence[16]; + uint8_t plant[4]; + uint8_t res3[156]; +}; + +/* Basic Machine CPU */ +struct sysib_121 { + uint32_t res1[80]; + uint8_t sequence[16]; + uint8_t plant[4]; + uint8_t res2[2]; + uint16_t cpu_addr; + uint8_t res3[152]; +}; + +/* Basic Machine CPUs */ +struct sysib_122 { + uint8_t res1[32]; + uint32_t capability; + uint16_t total_cpus; + uint16_t active_cpus; + uint16_t standby_cpus; + uint16_t reserved_cpus; + uint16_t adjustments[2026]; +}; + +/* LPAR CPU */ +struct sysib_221 { + uint32_t res1[80]; + uint8_t sequence[16]; + uint8_t plant[4]; + uint16_t cpu_id; + uint16_t cpu_addr; + uint8_t res3[152]; +}; + +/* LPAR CPUs */ +struct sysib_222 { + uint32_t res1[32]; + uint16_t lpar_num; + uint8_t res2; + uint8_t lcpuc; + uint16_t total_cpus; + uint16_t conf_cpus; + uint16_t standby_cpus; + uint16_t reserved_cpus; + uint8_t name[8]; + uint32_t caf; + uint8_t res3[16]; + uint16_t dedicated_cpus; + uint16_t shared_cpus; + uint8_t res4[180]; +}; + +/* VM CPUs */ +struct sysib_322 { + uint8_t res1[31]; + uint8_t count; + struct { + uint8_t res2[4]; + uint16_t total_cpus; + uint16_t conf_cpus; + uint16_t standby_cpus; + uint16_t reserved_cpus; + uint8_t name[8]; + uint32_t caf; + uint8_t cpi[16]; + uint8_t res3[24]; + } vm[8]; + uint8_t res4[3552]; +}; + +/* MMU defines */ +#define _ASCE_ORIGIN ~0xfffULL /* segment table origin */ +#define _ASCE_SUBSPACE 0x200 /* subspace group control */ +#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ +#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ +#define _ASCE_SPACE_SWITCH 0x40 /* space switch event */ +#define _ASCE_REAL_SPACE 0x20 /* real space control */ +#define _ASCE_TYPE_MASK 0x0c /* asce table type mask */ +#define _ASCE_TYPE_REGION1 0x0c /* region first table type */ +#define _ASCE_TYPE_REGION2 0x08 /* region second table type */ +#define _ASCE_TYPE_REGION3 0x04 /* region third table type */ +#define _ASCE_TYPE_SEGMENT 0x00 /* segment table type */ +#define _ASCE_TABLE_LENGTH 0x03 /* region table length */ + +#define _REGION_ENTRY_ORIGIN ~0xfffULL /* region/segment table origin */ +#define _REGION_ENTRY_INV 0x20 /* invalid region table entry */ +#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ +#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ +#define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ +#define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */ +#define _REGION_ENTRY_LENGTH 0x03 /* region third length */ + +#define _SEGMENT_ENTRY_ORIGIN ~0x7ffULL /* segment table origin */ +#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ +#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ + +#define _PAGE_RO 0x200 /* HW read-only bit */ +#define _PAGE_INVALID 0x400 /* HW invalid bit */ + +#define SK_C (0x1 << 1) +#define SK_R (0x1 << 2) +#define SK_F (0x1 << 3) +#define SK_ACC_MASK (0xf << 4) + + +/* EBCDIC handling */ +static const uint8_t ebcdic2ascii[] = { + 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, + 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, + 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, + 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, + 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, + 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, + 0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21, + 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, + 0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E, + 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, + 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, + 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, + 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, + 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, + 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, + 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, + 0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, + 0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07, + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, + 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07, +}; + +static const uint8_t ascii2ebcdic [] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF +}; + +static inline void ebcdic_put(uint8_t *p, const char *ascii, int len) +{ + int i; + + for (i = 0; i < len; i++) { + p[i] = ascii2ebcdic[(int)ascii[i]]; + } +} + +#define SIGP_SENSE 0x01 +#define SIGP_EXTERNAL_CALL 0x02 +#define SIGP_EMERGENCY 0x03 +#define SIGP_START 0x04 +#define SIGP_STOP 0x05 +#define SIGP_RESTART 0x06 +#define SIGP_STOP_STORE_STATUS 0x09 +#define SIGP_INITIAL_CPU_RESET 0x0b +#define SIGP_CPU_RESET 0x0c +#define SIGP_SET_PREFIX 0x0d +#define SIGP_STORE_STATUS_ADDR 0x0e +#define SIGP_SET_ARCH 0x12 + +/* cpu status bits */ +#define SIGP_STAT_EQUIPMENT_CHECK 0x80000000UL +#define SIGP_STAT_INCORRECT_STATE 0x00000200UL +#define SIGP_STAT_INVALID_PARAMETER 0x00000100UL +#define SIGP_STAT_EXT_CALL_PENDING 0x00000080UL +#define SIGP_STAT_STOPPED 0x00000040UL +#define SIGP_STAT_OPERATOR_INTERV 0x00000020UL +#define SIGP_STAT_CHECK_STOP 0x00000010UL +#define SIGP_STAT_INOPERATIVE 0x00000004UL +#define SIGP_STAT_INVALID_ORDER 0x00000002UL +#define SIGP_STAT_RECEIVER_CHECK 0x00000001UL + +void load_psw(CPUState *env, uint64_t mask, uint64_t addr); +int mmu_translate(CPUState *env, target_ulong vaddr, int rw, uint64_t asc, + target_ulong *raddr, int *flags); +int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code); +uint32_t calc_cc(CPUState *env, uint32_t cc_op, uint64_t src, uint64_t dst, + uint64_t vr); + +#define TARGET_HAS_ICE 1 + +/* The value of the TOD clock for 1.1.1970. */ +#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL + +/* Converts ns to s390's clock format */ +static inline uint64_t time2tod(uint64_t ns) { + return (ns << 9) / 125; +} + +static inline void cpu_inject_ext(CPUState *env, uint32_t code, uint32_t param, + uint64_t param64) +{ + if (env->ext_index == MAX_EXT_QUEUE - 1) { + /* ugh - can't queue anymore. Let's drop. */ + return; + } + + env->ext_index++; + assert(env->ext_index < MAX_EXT_QUEUE); + + env->ext_queue[env->ext_index].code = code; + env->ext_queue[env->ext_index].param = param; + env->ext_queue[env->ext_index].param64 = param64; + + env->pending_int |= INTERRUPT_EXT; + cpu_interrupt(env, CPU_INTERRUPT_HARD); +} + +static inline bool cpu_has_work(CPUState *env) +{ + return (env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->psw.mask & PSW_MASK_EXT); +} + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb) +{ + env->psw.addr = tb->pc; +} #endif diff --git a/target-s390x/exec.h b/target-s390x/exec.h deleted file mode 100644 index bf3f264..0000000 --- a/target-s390x/exec.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * S/390 execution defines - * - * Copyright (c) 2009 Ulrich Hecht - * - * 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, see . - */ - -#include "dyngen-exec.h" - -register struct CPUS390XState *env asm(AREG0); - -#include "config.h" -#include "cpu.h" -#include "exec-all.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - -static inline int cpu_has_work(CPUState *env) -{ - return env->interrupt_request & CPU_INTERRUPT_HARD; // guess -} - -static inline int cpu_halted(CPUState *env) -{ - if (!env->halted) { - return 0; - } - if (cpu_has_work(env)) { - env->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb) -{ - env->psw.addr = tb->pc; -} - diff --git a/target-s390x/helper.c b/target-s390x/helper.c index 4a5297b..10cc9dd 100644 --- a/target-s390x/helper.c +++ b/target-s390x/helper.c @@ -2,6 +2,7 @@ * S/390 helpers * * Copyright (c) 2009 Ulrich Hecht + * Copyright (c) 2011 Alexander Graf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,30 +23,107 @@ #include #include "cpu.h" -#include "exec-all.h" #include "gdbstub.h" #include "qemu-common.h" +#include "qemu-timer.h" +#ifndef CONFIG_USER_ONLY +#include "sysemu.h" +#endif + +//#define DEBUG_S390 +//#define DEBUG_S390_PTE +//#define DEBUG_S390_STDOUT + +#ifdef DEBUG_S390 +#ifdef DEBUG_S390_STDOUT +#define DPRINTF(fmt, ...) \ + do { fprintf(stderr, fmt, ## __VA_ARGS__); \ + qemu_log(fmt, ##__VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ + do { qemu_log(fmt, ## __VA_ARGS__); } while (0) +#endif +#else +#define DPRINTF(fmt, ...) \ + do { } while (0) +#endif -#include -#include "kvm.h" +#ifdef DEBUG_S390_PTE +#define PTE_DPRINTF DPRINTF +#else +#define PTE_DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +#ifndef CONFIG_USER_ONLY +static void s390x_tod_timer(void *opaque) +{ + CPUState *env = opaque; + + env->pending_int |= INTERRUPT_TOD; + cpu_interrupt(env, CPU_INTERRUPT_HARD); +} + +static void s390x_cpu_timer(void *opaque) +{ + CPUState *env = opaque; + + env->pending_int |= INTERRUPT_CPUTIMER; + cpu_interrupt(env, CPU_INTERRUPT_HARD); +} +#endif CPUS390XState *cpu_s390x_init(const char *cpu_model) { CPUS390XState *env; +#if !defined (CONFIG_USER_ONLY) + struct tm tm; +#endif static int inited = 0; + static int cpu_num = 0; - env = qemu_mallocz(sizeof(CPUS390XState)); + env = g_malloc0(sizeof(CPUS390XState)); cpu_exec_init(env); - if (!inited) { + if (tcg_enabled() && !inited) { inited = 1; + s390x_translate_init(); } +#if !defined(CONFIG_USER_ONLY) + qemu_get_timedate(&tm, 0); + env->tod_offset = TOD_UNIX_EPOCH + + (time2tod(mktimegm(&tm)) * 1000000000ULL); + env->tod_basetime = 0; + env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env); + env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env); +#endif env->cpu_model_str = cpu_model; + env->cpu_num = cpu_num++; + env->ext_index = -1; cpu_reset(env); qemu_init_vcpu(env); return env; } +#if defined(CONFIG_USER_ONLY) + +void do_interrupt (CPUState *env) +{ + env->exception_index = -1; +} + +int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw, + int mmu_idx) +{ + /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d\n", + __FUNCTION__, address, rw, mmu_idx); */ + env->exception_index = EXCP_ADDR; + env->__excp_addr = address; /* FIXME: find out how this works on a real machine */ + return 1; +} + +#endif /* CONFIG_USER_ONLY */ + void cpu_reset(CPUS390XState *env) { if (qemu_loglevel_mask(CPU_LOG_RESET)) { @@ -56,29 +134,515 @@ void cpu_reset(CPUS390XState *env) memset(env, 0, offsetof(CPUS390XState, breakpoints)); /* FIXME: reset vector? */ tlb_flush(env, 1); + s390_add_running_cpu(env); +} + +#ifndef CONFIG_USER_ONLY + +/* Ensure to exit the TB after this call! */ +static void trigger_pgm_exception(CPUState *env, uint32_t code, uint32_t ilc) +{ + env->exception_index = EXCP_PGM; + env->int_pgm_code = code; + env->int_pgm_ilc = ilc; +} + +static int trans_bits(CPUState *env, uint64_t mode) +{ + int bits = 0; + + switch (mode) { + case PSW_ASC_PRIMARY: + bits = 1; + break; + case PSW_ASC_SECONDARY: + bits = 2; + break; + case PSW_ASC_HOME: + bits = 3; + break; + default: + cpu_abort(env, "unknown asc mode\n"); + break; + } + + return bits; +} + +static void trigger_prot_fault(CPUState *env, target_ulong vaddr, uint64_t mode) +{ + int ilc = ILC_LATER_INC_2; + int bits = trans_bits(env, mode) | 4; + + DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __FUNCTION__, vaddr, bits); + + stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits); + trigger_pgm_exception(env, PGM_PROTECTION, ilc); +} + +static void trigger_page_fault(CPUState *env, target_ulong vaddr, uint32_t type, + uint64_t asc, int rw) +{ + int ilc = ILC_LATER; + int bits = trans_bits(env, asc); + + if (rw == 2) { + /* code has is undefined ilc */ + ilc = 2; + } + + DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __FUNCTION__, vaddr, bits); + + stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits); + trigger_pgm_exception(env, type, ilc); } -target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) +static int mmu_translate_asce(CPUState *env, target_ulong vaddr, uint64_t asc, + uint64_t asce, int level, target_ulong *raddr, + int *flags, int rw) { + uint64_t offs = 0; + uint64_t origin; + uint64_t new_asce; + + PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __FUNCTION__, asce); + + if (((level != _ASCE_TYPE_SEGMENT) && (asce & _REGION_ENTRY_INV)) || + ((level == _ASCE_TYPE_SEGMENT) && (asce & _SEGMENT_ENTRY_INV))) { + /* XXX different regions have different faults */ + DPRINTF("%s: invalid region\n", __FUNCTION__); + trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw); + return -1; + } + + if ((level <= _ASCE_TYPE_MASK) && ((asce & _ASCE_TYPE_MASK) != level)) { + trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); + return -1; + } + + if (asce & _ASCE_REAL_SPACE) { + /* direct mapping */ + + *raddr = vaddr; + return 0; + } + + origin = asce & _ASCE_ORIGIN; + + switch (level) { + case _ASCE_TYPE_REGION1 + 4: + offs = (vaddr >> 50) & 0x3ff8; + break; + case _ASCE_TYPE_REGION1: + offs = (vaddr >> 39) & 0x3ff8; + break; + case _ASCE_TYPE_REGION2: + offs = (vaddr >> 28) & 0x3ff8; + break; + case _ASCE_TYPE_REGION3: + offs = (vaddr >> 17) & 0x3ff8; + break; + case _ASCE_TYPE_SEGMENT: + offs = (vaddr >> 9) & 0x07f8; + origin = asce & _SEGMENT_ENTRY_ORIGIN; + break; + } + + /* XXX region protection flags */ + /* *flags &= ~PAGE_WRITE */ + + new_asce = ldq_phys(origin + offs); + PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n", + __FUNCTION__, origin, offs, new_asce); + + if (level != _ASCE_TYPE_SEGMENT) { + /* yet another region */ + return mmu_translate_asce(env, vaddr, asc, new_asce, level - 4, raddr, + flags, rw); + } + + /* PTE */ + if (new_asce & _PAGE_INVALID) { + DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __FUNCTION__, new_asce); + trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw); + return -1; + } + + if (new_asce & _PAGE_RO) { + *flags &= ~PAGE_WRITE; + } + + *raddr = new_asce & _ASCE_ORIGIN; + + PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __FUNCTION__, new_asce); + return 0; } -#ifndef CONFIG_USER_ONLY +static int mmu_translate_asc(CPUState *env, target_ulong vaddr, uint64_t asc, + target_ulong *raddr, int *flags, int rw) +{ + uint64_t asce = 0; + int level, new_level; + int r; -int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + switch (asc) { + case PSW_ASC_PRIMARY: + PTE_DPRINTF("%s: asc=primary\n", __FUNCTION__); + asce = env->cregs[1]; + break; + case PSW_ASC_SECONDARY: + PTE_DPRINTF("%s: asc=secondary\n", __FUNCTION__); + asce = env->cregs[7]; + break; + case PSW_ASC_HOME: + PTE_DPRINTF("%s: asc=home\n", __FUNCTION__); + asce = env->cregs[13]; + break; + } + + switch (asce & _ASCE_TYPE_MASK) { + case _ASCE_TYPE_REGION1: + break; + case _ASCE_TYPE_REGION2: + if (vaddr & 0xffe0000000000000ULL) { + DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 + " 0xffe0000000000000ULL\n", __FUNCTION__, + vaddr); + trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); + return -1; + } + break; + case _ASCE_TYPE_REGION3: + if (vaddr & 0xfffffc0000000000ULL) { + DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 + " 0xfffffc0000000000ULL\n", __FUNCTION__, + vaddr); + trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); + return -1; + } + break; + case _ASCE_TYPE_SEGMENT: + if (vaddr & 0xffffffff80000000ULL) { + DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64 + " 0xffffffff80000000ULL\n", __FUNCTION__, + vaddr); + trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); + return -1; + } + break; + } + + /* fake level above current */ + level = asce & _ASCE_TYPE_MASK; + new_level = level + 4; + asce = (asce & ~_ASCE_TYPE_MASK) | (new_level & _ASCE_TYPE_MASK); + + r = mmu_translate_asce(env, vaddr, asc, asce, new_level, raddr, flags, rw); + + if ((rw == 1) && !(*flags & PAGE_WRITE)) { + trigger_prot_fault(env, vaddr, asc); + return -1; + } + + return r; +} + +int mmu_translate(CPUState *env, target_ulong vaddr, int rw, uint64_t asc, + target_ulong *raddr, int *flags) +{ + int r = -1; + uint8_t *sk; + + *flags = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + vaddr &= TARGET_PAGE_MASK; + + if (!(env->psw.mask & PSW_MASK_DAT)) { + *raddr = vaddr; + r = 0; + goto out; + } + + switch (asc) { + case PSW_ASC_PRIMARY: + case PSW_ASC_HOME: + r = mmu_translate_asc(env, vaddr, asc, raddr, flags, rw); + break; + case PSW_ASC_SECONDARY: + /* + * Instruction: Primary + * Data: Secondary + */ + if (rw == 2) { + r = mmu_translate_asc(env, vaddr, PSW_ASC_PRIMARY, raddr, flags, + rw); + *flags &= ~(PAGE_READ | PAGE_WRITE); + } else { + r = mmu_translate_asc(env, vaddr, PSW_ASC_SECONDARY, raddr, flags, + rw); + *flags &= ~(PAGE_EXEC); + } + break; + case PSW_ASC_ACCREG: + default: + hw_error("guest switched to unknown asc mode\n"); + break; + } + +out: + /* Convert real address -> absolute address */ + if (*raddr < 0x2000) { + *raddr = *raddr + env->psa; + } + + if (*raddr <= ram_size) { + sk = &env->storage_keys[*raddr / TARGET_PAGE_SIZE]; + if (*flags & PAGE_READ) { + *sk |= SK_R; + } + + if (*flags & PAGE_WRITE) { + *sk |= SK_C; + } + } + + return r; +} + +int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong _vaddr, int rw, + int mmu_idx) { - target_ulong phys; + uint64_t asc = env->psw.mask & PSW_MASK_ASC; + target_ulong vaddr, raddr; int prot; - /* XXX: implement mmu */ + DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n", + __FUNCTION__, _vaddr, rw, mmu_idx); + + _vaddr &= TARGET_PAGE_MASK; + vaddr = _vaddr; + + /* 31-Bit mode */ + if (!(env->psw.mask & PSW_MASK_64)) { + vaddr &= 0x7fffffff; + } + + if (mmu_translate(env, vaddr, rw, asc, &raddr, &prot)) { + /* Translation ended in exception */ + return 1; + } + + /* check out of RAM access */ + if (raddr > (ram_size + virtio_size)) { + DPRINTF("%s: aaddr %" PRIx64 " > ram_size %" PRIx64 "\n", __FUNCTION__, + (uint64_t)aaddr, (uint64_t)ram_size); + trigger_pgm_exception(env, PGM_ADDRESSING, ILC_LATER); + return 1; + } - phys = address; - prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + DPRINTF("%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", __FUNCTION__, + (uint64_t)vaddr, (uint64_t)raddr, prot); - tlb_set_page(env, address & TARGET_PAGE_MASK, - phys & TARGET_PAGE_MASK, prot, + tlb_set_page(env, _vaddr, raddr, prot, mmu_idx, TARGET_PAGE_SIZE); + return 0; } + +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong vaddr) +{ + target_ulong raddr; + int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + int old_exc = env->exception_index; + uint64_t asc = env->psw.mask & PSW_MASK_ASC; + + /* 31-Bit mode */ + if (!(env->psw.mask & PSW_MASK_64)) { + vaddr &= 0x7fffffff; + } + + mmu_translate(env, vaddr, 2, asc, &raddr, &prot); + env->exception_index = old_exc; + + return raddr; +} + +void load_psw(CPUState *env, uint64_t mask, uint64_t addr) +{ + if (mask & PSW_MASK_WAIT) { + if (!(mask & (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK))) { + if (s390_del_running_cpu(env) == 0) { +#ifndef CONFIG_USER_ONLY + qemu_system_shutdown_request(); +#endif + } + } + env->halted = 1; + env->exception_index = EXCP_HLT; + } + + env->psw.addr = addr; + env->psw.mask = mask; + env->cc_op = (mask >> 13) & 3; +} + +static uint64_t get_psw_mask(CPUState *env) +{ + uint64_t r = env->psw.mask; + + env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); + + r &= ~(3ULL << 13); + assert(!(env->cc_op & ~3)); + r |= env->cc_op << 13; + + return r; +} + +static void do_svc_interrupt(CPUState *env) +{ + uint64_t mask, addr; + LowCore *lowcore; + target_phys_addr_t len = TARGET_PAGE_SIZE; + + lowcore = cpu_physical_memory_map(env->psa, &len, 1); + + lowcore->svc_code = cpu_to_be16(env->int_svc_code); + lowcore->svc_ilc = cpu_to_be16(env->int_svc_ilc); + lowcore->svc_old_psw.mask = cpu_to_be64(get_psw_mask(env)); + lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + (env->int_svc_ilc)); + mask = be64_to_cpu(lowcore->svc_new_psw.mask); + addr = be64_to_cpu(lowcore->svc_new_psw.addr); + + cpu_physical_memory_unmap(lowcore, len, 1, len); + + load_psw(env, mask, addr); +} + +static void do_program_interrupt(CPUState *env) +{ + uint64_t mask, addr; + LowCore *lowcore; + target_phys_addr_t len = TARGET_PAGE_SIZE; + int ilc = env->int_pgm_ilc; + + switch (ilc) { + case ILC_LATER: + ilc = get_ilc(ldub_code(env->psw.addr)); + break; + case ILC_LATER_INC: + ilc = get_ilc(ldub_code(env->psw.addr)); + env->psw.addr += ilc * 2; + break; + case ILC_LATER_INC_2: + ilc = get_ilc(ldub_code(env->psw.addr)) * 2; + env->psw.addr += ilc; + break; + } + + qemu_log("%s: code=0x%x ilc=%d\n", __FUNCTION__, env->int_pgm_code, ilc); + + lowcore = cpu_physical_memory_map(env->psa, &len, 1); + + lowcore->pgm_ilc = cpu_to_be16(ilc); + lowcore->pgm_code = cpu_to_be16(env->int_pgm_code); + lowcore->program_old_psw.mask = cpu_to_be64(get_psw_mask(env)); + lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr); + mask = be64_to_cpu(lowcore->program_new_psw.mask); + addr = be64_to_cpu(lowcore->program_new_psw.addr); + + cpu_physical_memory_unmap(lowcore, len, 1, len); + + DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __FUNCTION__, + env->int_pgm_code, ilc, env->psw.mask, + env->psw.addr); + + load_psw(env, mask, addr); +} + +#define VIRTIO_SUBCODE_64 0x0D00 + +static void do_ext_interrupt(CPUState *env) +{ + uint64_t mask, addr; + LowCore *lowcore; + target_phys_addr_t len = TARGET_PAGE_SIZE; + ExtQueue *q; + + if (!(env->psw.mask & PSW_MASK_EXT)) { + cpu_abort(env, "Ext int w/o ext mask\n"); + } + + if (env->ext_index < 0 || env->ext_index > MAX_EXT_QUEUE) { + cpu_abort(env, "Ext queue overrun: %d\n", env->ext_index); + } + + q = &env->ext_queue[env->ext_index]; + lowcore = cpu_physical_memory_map(env->psa, &len, 1); + + lowcore->ext_int_code = cpu_to_be16(q->code); + lowcore->ext_params = cpu_to_be32(q->param); + lowcore->ext_params2 = cpu_to_be64(q->param64); + lowcore->external_old_psw.mask = cpu_to_be64(get_psw_mask(env)); + lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr); + lowcore->cpu_addr = cpu_to_be16(env->cpu_num | VIRTIO_SUBCODE_64); + mask = be64_to_cpu(lowcore->external_new_psw.mask); + addr = be64_to_cpu(lowcore->external_new_psw.addr); + + cpu_physical_memory_unmap(lowcore, len, 1, len); + + env->ext_index--; + if (env->ext_index == -1) { + env->pending_int &= ~INTERRUPT_EXT; + } + + DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __FUNCTION__, + env->psw.mask, env->psw.addr); + + load_psw(env, mask, addr); +} + +void do_interrupt (CPUState *env) +{ + qemu_log("%s: %d at pc=%" PRIx64 "\n", __FUNCTION__, env->exception_index, + env->psw.addr); + + s390_add_running_cpu(env); + /* handle external interrupts */ + if ((env->psw.mask & PSW_MASK_EXT) && + env->exception_index == -1) { + if (env->pending_int & INTERRUPT_EXT) { + /* code is already in env */ + env->exception_index = EXCP_EXT; + } else if (env->pending_int & INTERRUPT_TOD) { + cpu_inject_ext(env, 0x1004, 0, 0); + env->exception_index = EXCP_EXT; + env->pending_int &= ~INTERRUPT_EXT; + env->pending_int &= ~INTERRUPT_TOD; + } else if (env->pending_int & INTERRUPT_CPUTIMER) { + cpu_inject_ext(env, 0x1005, 0, 0); + env->exception_index = EXCP_EXT; + env->pending_int &= ~INTERRUPT_EXT; + env->pending_int &= ~INTERRUPT_TOD; + } + } + + switch (env->exception_index) { + case EXCP_PGM: + do_program_interrupt(env); + break; + case EXCP_SVC: + do_svc_interrupt(env); + break; + case EXCP_EXT: + do_ext_interrupt(env); + break; + } + env->exception_index = -1; + + if (!env->pending_int) { + env->interrupt_request &= ~CPU_INTERRUPT_HARD; + } +} + #endif /* CONFIG_USER_ONLY */ diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 38823f5..b1404bf 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -49,13 +49,6 @@ #define DIAG_KVM_HYPERCALL 0x500 #define DIAG_KVM_BREAKPOINT 0x501 -#define SCP_LENGTH 0x00 -#define SCP_FUNCTION_CODE 0x02 -#define SCP_CONTROL_MASK 0x03 -#define SCP_RESPONSE_CODE 0x06 -#define SCP_MEM_CODE 0x08 -#define SCP_INCREMENT 0x0a - #define ICPT_INSTRUCTION 0x04 #define ICPT_WAITPSW 0x1c #define ICPT_SOFT_INTERCEPT 0x24 @@ -169,23 +162,21 @@ int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp) return 0; } -int kvm_arch_pre_run(CPUState *env, struct kvm_run *run) +void kvm_arch_pre_run(CPUState *env, struct kvm_run *run) { - return 0; } -int kvm_arch_post_run(CPUState *env, struct kvm_run *run) +void kvm_arch_post_run(CPUState *env, struct kvm_run *run) { - return 0; } -int kvm_arch_process_irqchip_events(CPUState *env) +int kvm_arch_process_async_events(CPUState *env) { - return 0; + return env->halted; } -static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm, - uint64_t parm64, int vm) +void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm, + uint64_t parm64, int vm) { struct kvm_s390_interrupt kvmint; int r; @@ -194,9 +185,6 @@ static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm, return; } - env->halted = 0; - env->exception_index = -1; - kvmint.type = type; kvmint.parm = parm; kvmint.parm64 = parm64; @@ -219,7 +207,7 @@ void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token) token, 1); } -static void kvm_s390_interrupt(CPUState *env, int type, uint32_t code) +void kvm_s390_interrupt(CPUState *env, int type, uint32_t code) { kvm_s390_interrupt_internal(env, type, code, 0, 0); } @@ -229,16 +217,17 @@ static void enter_pgmcheck(CPUState *env, uint16_t code) kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code); } -static void setcc(CPUState *env, uint64_t cc) +static inline void setcc(CPUState *env, uint64_t cc) { - env->kvm_run->psw_mask &= ~(3ul << 44); + env->kvm_run->psw_mask &= ~(3ull << 44); env->kvm_run->psw_mask |= (cc & 3) << 44; env->psw.mask &= ~(3ul << 44); env->psw.mask |= (cc & 3) << 44; } -static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0) +static int kvm_sclp_service_call(CPUState *env, struct kvm_run *run, + uint16_t ipbh0) { uint32_t sccb; uint64_t code; @@ -248,35 +237,11 @@ static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0) sccb = env->regs[ipbh0 & 0xf]; code = env->regs[(ipbh0 & 0xf0) >> 4]; - dprintf("sclp(0x%x, 0x%lx)\n", sccb, code); - - if (sccb & ~0x7ffffff8ul) { - fprintf(stderr, "KVM: invalid sccb address 0x%x\n", sccb); - r = -1; - goto out; - } - - switch(code) { - case SCLP_CMDW_READ_SCP_INFO: - case SCLP_CMDW_READ_SCP_INFO_FORCED: - stw_phys(sccb + SCP_MEM_CODE, ram_size >> 20); - stb_phys(sccb + SCP_INCREMENT, 1); - stw_phys(sccb + SCP_RESPONSE_CODE, 0x10); - setcc(env, 0); - - kvm_s390_interrupt_internal(env, KVM_S390_INT_SERVICE, - sccb & ~3, 0, 1); - break; - default: - dprintf("KVM: invalid sclp call 0x%x / 0x%lx\n", sccb, code); - r = -1; - break; - } - -out: - if (r < 0) { + r = sclp_service_call(env, sccb, code); + if (r) { setcc(env, 3); } + return 0; } @@ -288,7 +253,7 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1) dprintf("KVM: PRIV: %d\n", ipa1); switch (ipa1) { case PRIV_SCLP_CALL: - r = sclp_service_call(env, run, ipbh0); + r = kvm_sclp_service_call(env, run, ipbh0); break; default: dprintf("KVM: unknown PRIV: 0x%x\n", ipa1); @@ -301,12 +266,10 @@ static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1) static int handle_hypercall(CPUState *env, struct kvm_run *run) { - int r; - cpu_synchronize_state(env); - r = s390_virtio_hypercall(env); + env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]); - return r; + return 0; } static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code) @@ -332,8 +295,7 @@ static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code) static int s390_cpu_restart(CPUState *env) { kvm_s390_interrupt(env, KVM_S390_RESTART, 0); - env->halted = 0; - env->exception_index = -1; + s390_add_running_cpu(env); qemu_cpu_kick(env); dprintf("DONE: SIGP cpu restart: %p\n", env); return 0; @@ -410,7 +372,7 @@ static int handle_sigp(CPUState *env, struct kvm_run *run, uint8_t ipa1) r = s390_cpu_initial_reset(target_env); break; default: - fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", ipa1); + fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", order_code); break; } @@ -442,7 +404,7 @@ static int handle_instruction(CPUState *env, struct kvm_run *run) if (r < 0) { enter_pgmcheck(env, 0x0001); } - return r; + return 0; } static int handle_intercept(CPUState *env) @@ -451,23 +413,23 @@ static int handle_intercept(CPUState *env) int icpt_code = run->s390_sieic.icptcode; int r = 0; - dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code, env->kvm_run->psw_addr); + dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code, + (long)env->kvm_run->psw_addr); switch (icpt_code) { case ICPT_INSTRUCTION: r = handle_instruction(env, run); break; case ICPT_WAITPSW: - /* XXX What to do on system shutdown? */ - env->halted = 1; - env->exception_index = EXCP_HLT; + case ICPT_CPU_STOP: + if (s390_del_running_cpu(env) == 0) { + qemu_system_shutdown_request(); + } + r = EXCP_HALTED; break; case ICPT_SOFT_INTERCEPT: fprintf(stderr, "KVM unimplemented icpt SOFT\n"); exit(1); break; - case ICPT_CPU_STOP: - qemu_system_shutdown_request(); - break; case ICPT_IO: fprintf(stderr, "KVM unimplemented icpt IO\n"); exit(1); @@ -498,6 +460,9 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run) break; } + if (ret == 0) { + ret = EXCP_INTERRUPT; + } return ret; } @@ -505,3 +470,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env) { return true; } + +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ + return 1; +} + +int kvm_arch_on_sigbus(int code, void *addr) +{ + return 1; +} diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c index 402df2d..5ddc7b9 100644 --- a/target-s390x/op_helper.c +++ b/target-s390x/op_helper.c @@ -1,6 +1,7 @@ /* * S/390 helper routines * + * Copyright (c) 2009 Ulrich Hecht * Copyright (c) 2009 Alexander Graf * * This library is free software; you can redistribute it and/or @@ -17,11 +18,25 @@ * License along with this library; if not, see . */ -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" +#include "host-utils.h" +#include "helpers.h" +#include +#include "kvm.h" +#include "qemu-timer.h" +#ifdef CONFIG_KVM +#include +#endif + +#if !defined (CONFIG_USER_ONLY) +#include "sysemu.h" +#endif /*****************************************************************************/ /* Softmmu support */ #if !defined (CONFIG_USER_ONLY) +#include "softmmu_exec.h" #define MMUSUFFIX _mmu @@ -41,18 +56,17 @@ NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { TranslationBlock *tb; CPUState *saved_env; unsigned long pc; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; - ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + env = env1; + ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ @@ -61,13 +75,2952 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) if (likely(tb)) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } - /* XXX */ - /* helper_raise_exception_err(env->exception_index, env->error_code); */ + cpu_loop_exit(env); } env = saved_env; } #endif + +/* #define DEBUG_HELPER */ +#ifdef DEBUG_HELPER +#define HELPER_LOG(x...) qemu_log(x) +#else +#define HELPER_LOG(x...) +#endif + +/* raise an exception */ +void HELPER(exception)(uint32_t excp) +{ + HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp); + env->exception_index = excp; + cpu_loop_exit(env); +} + +#ifndef CONFIG_USER_ONLY +static void mvc_fast_memset(CPUState *env, uint32_t l, uint64_t dest, + uint8_t byte) +{ + target_phys_addr_t dest_phys; + target_phys_addr_t len = l; + void *dest_p; + uint64_t asc = env->psw.mask & PSW_MASK_ASC; + int flags; + + if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) { + stb(dest, byte); + cpu_abort(env, "should never reach here"); + } + dest_phys |= dest & ~TARGET_PAGE_MASK; + + dest_p = cpu_physical_memory_map(dest_phys, &len, 1); + + memset(dest_p, byte, len); + + cpu_physical_memory_unmap(dest_p, 1, len, len); +} + +static void mvc_fast_memmove(CPUState *env, uint32_t l, uint64_t dest, + uint64_t src) +{ + target_phys_addr_t dest_phys; + target_phys_addr_t src_phys; + target_phys_addr_t len = l; + void *dest_p; + void *src_p; + uint64_t asc = env->psw.mask & PSW_MASK_ASC; + int flags; + + if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) { + stb(dest, 0); + cpu_abort(env, "should never reach here"); + } + dest_phys |= dest & ~TARGET_PAGE_MASK; + + if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) { + ldub(src); + cpu_abort(env, "should never reach here"); + } + src_phys |= src & ~TARGET_PAGE_MASK; + + dest_p = cpu_physical_memory_map(dest_phys, &len, 1); + src_p = cpu_physical_memory_map(src_phys, &len, 0); + + memmove(dest_p, src_p, len); + + cpu_physical_memory_unmap(dest_p, 1, len, len); + cpu_physical_memory_unmap(src_p, 0, len, len); +} +#endif + +/* and on array */ +uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src) +{ + int i; + unsigned char x; + uint32_t cc = 0; + + HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", + __FUNCTION__, l, dest, src); + for (i = 0; i <= l; i++) { + x = ldub(dest + i) & ldub(src + i); + if (x) { + cc = 1; + } + stb(dest + i, x); + } + return cc; +} + +/* xor on array */ +uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src) +{ + int i; + unsigned char x; + uint32_t cc = 0; + + HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", + __FUNCTION__, l, dest, src); + +#ifndef CONFIG_USER_ONLY + /* xor with itself is the same as memset(0) */ + if ((l > 32) && (src == dest) && + (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) { + mvc_fast_memset(env, l + 1, dest, 0); + return 0; + } +#else + if (src == dest) { + memset(g2h(dest), 0, l + 1); + return 0; + } +#endif + + for (i = 0; i <= l; i++) { + x = ldub(dest + i) ^ ldub(src + i); + if (x) { + cc = 1; + } + stb(dest + i, x); + } + return cc; +} + +/* or on array */ +uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src) +{ + int i; + unsigned char x; + uint32_t cc = 0; + + HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", + __FUNCTION__, l, dest, src); + for (i = 0; i <= l; i++) { + x = ldub(dest + i) | ldub(src + i); + if (x) { + cc = 1; + } + stb(dest + i, x); + } + return cc; +} + +/* memmove */ +void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src) +{ + int i = 0; + int x = 0; + uint32_t l_64 = (l + 1) / 8; + + HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n", + __FUNCTION__, l, dest, src); + +#ifndef CONFIG_USER_ONLY + if ((l > 32) && + (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) && + (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) { + if (dest == (src + 1)) { + mvc_fast_memset(env, l + 1, dest, ldub(src)); + return; + } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) { + mvc_fast_memmove(env, l + 1, dest, src); + return; + } + } +#else + if (dest == (src + 1)) { + memset(g2h(dest), ldub(src), l + 1); + return; + } else { + memmove(g2h(dest), g2h(src), l + 1); + return; + } +#endif + + /* handle the parts that fit into 8-byte loads/stores */ + if (dest != (src + 1)) { + for (i = 0; i < l_64; i++) { + stq(dest + x, ldq(src + x)); + x += 8; + } + } + + /* slow version crossing pages with byte accesses */ + for (i = x; i <= l; i++) { + stb(dest + i, ldub(src + i)); + } +} + +/* compare unsigned byte arrays */ +uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2) +{ + int i; + unsigned char x,y; + uint32_t cc; + HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n", + __FUNCTION__, l, s1, s2); + for (i = 0; i <= l; i++) { + x = ldub(s1 + i); + y = ldub(s2 + i); + HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y); + if (x < y) { + cc = 1; + goto done; + } else if (x > y) { + cc = 2; + goto done; + } + } + cc = 0; +done: + HELPER_LOG("\n"); + return cc; +} + +/* compare logical under mask */ +uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr) +{ + uint8_t r,d; + uint32_t cc; + HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __FUNCTION__, r1, + mask, addr); + cc = 0; + while (mask) { + if (mask & 8) { + d = ldub(addr); + r = (r1 & 0xff000000UL) >> 24; + HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d, + addr); + if (r < d) { + cc = 1; + break; + } else if (r > d) { + cc = 2; + break; + } + addr++; + } + mask = (mask << 1) & 0xf; + r1 <<= 8; + } + HELPER_LOG("\n"); + return cc; +} + +/* store character under mask */ +void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr) +{ + uint8_t r; + HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __FUNCTION__, r1, mask, + addr); + while (mask) { + if (mask & 8) { + r = (r1 & 0xff000000UL) >> 24; + stb(addr, r); + HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr); + addr++; + } + mask = (mask << 1) & 0xf; + r1 <<= 8; + } + HELPER_LOG("\n"); +} + +/* 64/64 -> 128 unsigned multiplication */ +void HELPER(mlg)(uint32_t r1, uint64_t v2) +{ +#if HOST_LONG_BITS == 64 && defined(__GNUC__) + /* assuming 64-bit hosts have __uint128_t */ + __uint128_t res = (__uint128_t)env->regs[r1 + 1]; + res *= (__uint128_t)v2; + env->regs[r1] = (uint64_t)(res >> 64); + env->regs[r1 + 1] = (uint64_t)res; +#else + mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2); +#endif +} + +/* 128 -> 64/64 unsigned division */ +void HELPER(dlg)(uint32_t r1, uint64_t v2) +{ + uint64_t divisor = v2; + + if (!env->regs[r1]) { + /* 64 -> 64/64 case */ + env->regs[r1] = env->regs[r1+1] % divisor; + env->regs[r1+1] = env->regs[r1+1] / divisor; + return; + } else { + +#if HOST_LONG_BITS == 64 && defined(__GNUC__) + /* assuming 64-bit hosts have __uint128_t */ + __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) | + (env->regs[r1+1]); + __uint128_t quotient = dividend / divisor; + env->regs[r1+1] = quotient; + __uint128_t remainder = dividend % divisor; + env->regs[r1] = remainder; +#else + /* 32-bit hosts would need special wrapper functionality - just abort if + we encounter such a case; it's very unlikely anyways. */ + cpu_abort(env, "128 -> 64/64 division not implemented\n"); +#endif + } +} + +static inline uint64_t get_address(int x2, int b2, int d2) +{ + uint64_t r = d2; + + if (x2) { + r += env->regs[x2]; + } + + if (b2) { + r += env->regs[b2]; + } + + /* 31-Bit mode */ + if (!(env->psw.mask & PSW_MASK_64)) { + r &= 0x7fffffff; + } + + return r; +} + +static inline uint64_t get_address_31fix(int reg) +{ + uint64_t r = env->regs[reg]; + + /* 31-Bit mode */ + if (!(env->psw.mask & PSW_MASK_64)) { + r &= 0x7fffffff; + } + + return r; +} + +/* search string (c is byte to search, r2 is string, r1 end of string) */ +uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2) +{ + uint64_t i; + uint32_t cc = 2; + uint64_t str = get_address_31fix(r2); + uint64_t end = get_address_31fix(r1); + + HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __FUNCTION__, + c, env->regs[r1], env->regs[r2]); + + for (i = str; i != end; i++) { + if (ldub(i) == c) { + env->regs[r1] = i; + cc = 1; + break; + } + } + + return cc; +} + +/* unsigned string compare (c is string terminator) */ +uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2) +{ + uint64_t s1 = get_address_31fix(r1); + uint64_t s2 = get_address_31fix(r2); + uint8_t v1, v2; + uint32_t cc; + c = c & 0xff; +#ifdef CONFIG_USER_ONLY + if (!c) { + HELPER_LOG("%s: comparing '%s' and '%s'\n", + __FUNCTION__, (char*)g2h(s1), (char*)g2h(s2)); + } +#endif + for (;;) { + v1 = ldub(s1); + v2 = ldub(s2); + if ((v1 == c || v2 == c) || (v1 != v2)) { + break; + } + s1++; + s2++; + } + + if (v1 == v2) { + cc = 0; + } else { + cc = (v1 < v2) ? 1 : 2; + /* FIXME: 31-bit mode! */ + env->regs[r1] = s1; + env->regs[r2] = s2; + } + return cc; +} + +/* move page */ +void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2) +{ + /* XXX missing r0 handling */ +#ifdef CONFIG_USER_ONLY + int i; + + for (i = 0; i < TARGET_PAGE_SIZE; i++) { + stb(r1 + i, ldub(r2 + i)); + } +#else + mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2); +#endif +} + +/* string copy (c is string terminator) */ +void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2) +{ + uint64_t dest = get_address_31fix(r1); + uint64_t src = get_address_31fix(r2); + uint8_t v; + c = c & 0xff; +#ifdef CONFIG_USER_ONLY + if (!c) { + HELPER_LOG("%s: copy '%s' to 0x%lx\n", __FUNCTION__, (char*)g2h(src), + dest); + } +#endif + for (;;) { + v = ldub(src); + stb(dest, v); + if (v == c) { + break; + } + src++; + dest++; + } + env->regs[r1] = dest; /* FIXME: 31-bit mode! */ +} + +/* compare and swap 64-bit */ +uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + /* FIXME: locking? */ + uint32_t cc; + uint64_t v2 = ldq(a2); + if (env->regs[r1] == v2) { + cc = 0; + stq(a2, env->regs[r3]); + } else { + cc = 1; + env->regs[r1] = v2; + } + return cc; +} + +/* compare double and swap 64-bit */ +uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + /* FIXME: locking? */ + uint32_t cc; + uint64_t v2_hi = ldq(a2); + uint64_t v2_lo = ldq(a2 + 8); + uint64_t v1_hi = env->regs[r1]; + uint64_t v1_lo = env->regs[r1 + 1]; + + if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) { + cc = 0; + stq(a2, env->regs[r3]); + stq(a2 + 8, env->regs[r3 + 1]); + } else { + cc = 1; + env->regs[r1] = v2_hi; + env->regs[r1 + 1] = v2_lo; + } + + return cc; +} + +/* compare and swap 32-bit */ +uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + /* FIXME: locking? */ + uint32_t cc; + HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __FUNCTION__, r1, a2, r3); + uint32_t v2 = ldl(a2); + if (((uint32_t)env->regs[r1]) == v2) { + cc = 0; + stl(a2, (uint32_t)env->regs[r3]); + } else { + cc = 1; + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2; + } + return cc; +} + +static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask) +{ + int pos = 24; /* top of the lower half of r1 */ + uint64_t rmask = 0xff000000ULL; + uint8_t val = 0; + int ccd = 0; + uint32_t cc = 0; + + while (mask) { + if (mask & 8) { + env->regs[r1] &= ~rmask; + val = ldub(address); + if ((val & 0x80) && !ccd) { + cc = 1; + } + ccd = 1; + if (val && cc == 0) { + cc = 2; + } + env->regs[r1] |= (uint64_t)val << pos; + address++; + } + mask = (mask << 1) & 0xf; + pos -= 8; + rmask >>= 8; + } + + return cc; +} + +/* execute instruction + this instruction executes an insn modified with the contents of r1 + it does not change the executed instruction in memory + it does not change the program counter + in other words: tricky... + currently implemented by interpreting the cases it is most commonly used in + */ +uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret) +{ + uint16_t insn = lduw_code(addr); + HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __FUNCTION__, v1, addr, + insn); + if ((insn & 0xf0ff) == 0xd000) { + uint32_t l, insn2, b1, b2, d1, d2; + l = v1 & 0xff; + insn2 = ldl_code(addr + 2); + b1 = (insn2 >> 28) & 0xf; + b2 = (insn2 >> 12) & 0xf; + d1 = (insn2 >> 16) & 0xfff; + d2 = insn2 & 0xfff; + switch (insn & 0xf00) { + case 0x200: + helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2)); + break; + case 0x500: + cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2)); + break; + case 0x700: + cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2)); + break; + case 0xc00: + helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2)); + break; + default: + goto abort; + break; + } + } else if ((insn & 0xff00) == 0x0a00) { + /* supervisor call */ + HELPER_LOG("%s: svc %ld via execute\n", __FUNCTION__, (insn|v1) & 0xff); + env->psw.addr = ret - 4; + env->int_svc_code = (insn|v1) & 0xff; + env->int_svc_ilc = 4; + helper_exception(EXCP_SVC); + } else if ((insn & 0xff00) == 0xbf00) { + uint32_t insn2, r1, r3, b2, d2; + insn2 = ldl_code(addr + 2); + r1 = (insn2 >> 20) & 0xf; + r3 = (insn2 >> 16) & 0xf; + b2 = (insn2 >> 12) & 0xf; + d2 = insn2 & 0xfff; + cc = helper_icm(r1, get_address(0, b2, d2), r3); + } else { +abort: + cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n", + insn); + } + return cc; +} + +/* absolute value 32-bit */ +uint32_t HELPER(abs_i32)(int32_t val) +{ + if (val < 0) { + return -val; + } else { + return val; + } +} + +/* negative absolute value 32-bit */ +int32_t HELPER(nabs_i32)(int32_t val) +{ + if (val < 0) { + return val; + } else { + return -val; + } +} + +/* absolute value 64-bit */ +uint64_t HELPER(abs_i64)(int64_t val) +{ + HELPER_LOG("%s: val 0x%" PRIx64 "\n", __FUNCTION__, val); + + if (val < 0) { + return -val; + } else { + return val; + } +} + +/* negative absolute value 64-bit */ +int64_t HELPER(nabs_i64)(int64_t val) +{ + if (val < 0) { + return val; + } else { + return -val; + } +} + +/* add with carry 32-bit unsigned */ +uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2) +{ + uint32_t res; + + res = v1 + v2; + if (cc & 2) { + res++; + } + + return res; +} + +/* store character under mask high operates on the upper half of r1 */ +void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask) +{ + int pos = 56; /* top of the upper half of r1 */ + + while (mask) { + if (mask & 8) { + stb(address, (env->regs[r1] >> pos) & 0xff); + address++; + } + mask = (mask << 1) & 0xf; + pos -= 8; + } +} + +/* insert character under mask high; same as icm, but operates on the + upper half of r1 */ +uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask) +{ + int pos = 56; /* top of the upper half of r1 */ + uint64_t rmask = 0xff00000000000000ULL; + uint8_t val = 0; + int ccd = 0; + uint32_t cc = 0; + + while (mask) { + if (mask & 8) { + env->regs[r1] &= ~rmask; + val = ldub(address); + if ((val & 0x80) && !ccd) { + cc = 1; + } + ccd = 1; + if (val && cc == 0) { + cc = 2; + } + env->regs[r1] |= (uint64_t)val << pos; + address++; + } + mask = (mask << 1) & 0xf; + pos -= 8; + rmask >>= 8; + } + + return cc; +} + +/* insert psw mask and condition code into r1 */ +void HELPER(ipm)(uint32_t cc, uint32_t r1) +{ + uint64_t r = env->regs[r1]; + + r &= 0xffffffff00ffffffULL; + r |= (cc << 28) | ( (env->psw.mask >> 40) & 0xf ); + env->regs[r1] = r; + HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __FUNCTION__, + cc, env->psw.mask, r); +} + +/* load access registers r1 to r3 from memory at a2 */ +void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + int i; + + for (i = r1;; i = (i + 1) % 16) { + env->aregs[i] = ldl(a2); + a2 += 4; + + if (i == r3) { + break; + } + } +} + +/* store access registers r1 to r3 in memory at a2 */ +void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + int i; + + for (i = r1;; i = (i + 1) % 16) { + stl(a2, env->aregs[i]); + a2 += 4; + + if (i == r3) { + break; + } + } +} + +/* move long */ +uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2) +{ + uint64_t destlen = env->regs[r1 + 1] & 0xffffff; + uint64_t dest = get_address_31fix(r1); + uint64_t srclen = env->regs[r2 + 1] & 0xffffff; + uint64_t src = get_address_31fix(r2); + uint8_t pad = src >> 24; + uint8_t v; + uint32_t cc; + + if (destlen == srclen) { + cc = 0; + } else if (destlen < srclen) { + cc = 1; + } else { + cc = 2; + } + + if (srclen > destlen) { + srclen = destlen; + } + + for (; destlen && srclen; src++, dest++, destlen--, srclen--) { + v = ldub(src); + stb(dest, v); + } + + for (; destlen; dest++, destlen--) { + stb(dest, pad); + } + + env->regs[r1 + 1] = destlen; + /* can't use srclen here, we trunc'ed it */ + env->regs[r2 + 1] -= src - env->regs[r2]; + env->regs[r1] = dest; + env->regs[r2] = src; + + return cc; +} + +/* move long extended another memcopy insn with more bells and whistles */ +uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + uint64_t destlen = env->regs[r1 + 1]; + uint64_t dest = env->regs[r1]; + uint64_t srclen = env->regs[r3 + 1]; + uint64_t src = env->regs[r3]; + uint8_t pad = a2 & 0xff; + uint8_t v; + uint32_t cc; + + if (!(env->psw.mask & PSW_MASK_64)) { + destlen = (uint32_t)destlen; + srclen = (uint32_t)srclen; + dest &= 0x7fffffff; + src &= 0x7fffffff; + } + + if (destlen == srclen) { + cc = 0; + } else if (destlen < srclen) { + cc = 1; + } else { + cc = 2; + } + + if (srclen > destlen) { + srclen = destlen; + } + + for (; destlen && srclen; src++, dest++, destlen--, srclen--) { + v = ldub(src); + stb(dest, v); + } + + for (; destlen; dest++, destlen--) { + stb(dest, pad); + } + + env->regs[r1 + 1] = destlen; + /* can't use srclen here, we trunc'ed it */ + /* FIXME: 31-bit mode! */ + env->regs[r3 + 1] -= src - env->regs[r3]; + env->regs[r1] = dest; + env->regs[r3] = src; + + return cc; +} + +/* compare logical long extended memcompare insn with padding */ +uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + uint64_t destlen = env->regs[r1 + 1]; + uint64_t dest = get_address_31fix(r1); + uint64_t srclen = env->regs[r3 + 1]; + uint64_t src = get_address_31fix(r3); + uint8_t pad = a2 & 0xff; + uint8_t v1 = 0,v2 = 0; + uint32_t cc = 0; + + if (!(destlen || srclen)) { + return cc; + } + + if (srclen > destlen) { + srclen = destlen; + } + + for (; destlen || srclen; src++, dest++, destlen--, srclen--) { + v1 = srclen ? ldub(src) : pad; + v2 = destlen ? ldub(dest) : pad; + if (v1 != v2) { + cc = (v1 < v2) ? 1 : 2; + break; + } + } + + env->regs[r1 + 1] = destlen; + /* can't use srclen here, we trunc'ed it */ + env->regs[r3 + 1] -= src - env->regs[r3]; + env->regs[r1] = dest; + env->regs[r3] = src; + + return cc; +} + +/* subtract unsigned v2 from v1 with borrow */ +uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2) +{ + uint32_t v1 = env->regs[r1]; + uint32_t res = v1 + (~v2) + (cc >> 1); + + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res; + if (cc & 2) { + /* borrow */ + return v1 ? 1 : 0; + } else { + return v1 ? 3 : 2; + } +} + +/* subtract unsigned v2 from v1 with borrow */ +uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2) +{ + uint64_t res = v1 + (~v2) + (cc >> 1); + + env->regs[r1] = res; + if (cc & 2) { + /* borrow */ + return v1 ? 1 : 0; + } else { + return v1 ? 3 : 2; + } +} + +static inline int float_comp_to_cc(int float_compare) +{ + switch (float_compare) { + case float_relation_equal: + return 0; + case float_relation_less: + return 1; + case float_relation_greater: + return 2; + case float_relation_unordered: + return 3; + default: + cpu_abort(env, "unknown return value for float compare\n"); + } +} + +/* condition codes for binary FP ops */ +static uint32_t set_cc_f32(float32 v1, float32 v2) +{ + return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status)); +} + +static uint32_t set_cc_f64(float64 v1, float64 v2) +{ + return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status)); +} + +/* condition codes for unary FP ops */ +static uint32_t set_cc_nz_f32(float32 v) +{ + if (float32_is_any_nan(v)) { + return 3; + } else if (float32_is_zero(v)) { + return 0; + } else if (float32_is_neg(v)) { + return 1; + } else { + return 2; + } +} + +static uint32_t set_cc_nz_f64(float64 v) +{ + if (float64_is_any_nan(v)) { + return 3; + } else if (float64_is_zero(v)) { + return 0; + } else if (float64_is_neg(v)) { + return 1; + } else { + return 2; + } +} + +static uint32_t set_cc_nz_f128(float128 v) +{ + if (float128_is_any_nan(v)) { + return 3; + } else if (float128_is_zero(v)) { + return 0; + } else if (float128_is_neg(v)) { + return 1; + } else { + return 2; + } +} + +/* convert 32-bit int to 64-bit float */ +void HELPER(cdfbr)(uint32_t f1, int32_t v2) +{ + HELPER_LOG("%s: converting %d to f%d\n", __FUNCTION__, v2, f1); + env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status); +} + +/* convert 32-bit int to 128-bit float */ +void HELPER(cxfbr)(uint32_t f1, int32_t v2) +{ + CPU_QuadU v1; + v1.q = int32_to_float128(v2, &env->fpu_status); + env->fregs[f1].ll = v1.ll.upper; + env->fregs[f1 + 2].ll = v1.ll.lower; +} + +/* convert 64-bit int to 32-bit float */ +void HELPER(cegbr)(uint32_t f1, int64_t v2) +{ + HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1); + env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status); +} + +/* convert 64-bit int to 64-bit float */ +void HELPER(cdgbr)(uint32_t f1, int64_t v2) +{ + HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1); + env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status); +} + +/* convert 64-bit int to 128-bit float */ +void HELPER(cxgbr)(uint32_t f1, int64_t v2) +{ + CPU_QuadU x1; + x1.q = int64_to_float128(v2, &env->fpu_status); + HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __FUNCTION__, v2, + x1.ll.upper, x1.ll.lower); + env->fregs[f1].ll = x1.ll.upper; + env->fregs[f1 + 2].ll = x1.ll.lower; +} + +/* convert 32-bit int to 32-bit float */ +void HELPER(cefbr)(uint32_t f1, int32_t v2) +{ + env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status); + HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __FUNCTION__, v2, + env->fregs[f1].l.upper, f1); +} + +/* 32-bit FP addition RR */ +uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper, + env->fregs[f2].l.upper, + &env->fpu_status); + HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, + env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1); + + return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* 64-bit FP addition RR */ +uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d, + &env->fpu_status); + HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __FUNCTION__, + env->fregs[f2].d, env->fregs[f1].d, f1); + + return set_cc_nz_f64(env->fregs[f1].d); +} + +/* 32-bit FP subtraction RR */ +uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper, + env->fregs[f2].l.upper, + &env->fpu_status); + HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__, + env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1); + + return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* 64-bit FP subtraction RR */ +uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d, + &env->fpu_status); + HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n", + __FUNCTION__, env->fregs[f2].d, env->fregs[f1].d, f1); + + return set_cc_nz_f64(env->fregs[f1].d); +} + +/* 32-bit FP division RR */ +void HELPER(debr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper, + env->fregs[f2].l.upper, + &env->fpu_status); +} + +/* 128-bit FP division RR */ +void HELPER(dxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU v1; + v1.ll.upper = env->fregs[f1].ll; + v1.ll.lower = env->fregs[f1 + 2].ll; + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + CPU_QuadU res; + res.q = float128_div(v1.q, v2.q, &env->fpu_status); + env->fregs[f1].ll = res.ll.upper; + env->fregs[f1 + 2].ll = res.ll.lower; +} + +/* 64-bit FP multiplication RR */ +void HELPER(mdbr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d, + &env->fpu_status); +} + +/* 128-bit FP multiplication RR */ +void HELPER(mxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU v1; + v1.ll.upper = env->fregs[f1].ll; + v1.ll.lower = env->fregs[f1 + 2].ll; + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + CPU_QuadU res; + res.q = float128_mul(v1.q, v2.q, &env->fpu_status); + env->fregs[f1].ll = res.ll.upper; + env->fregs[f1 + 2].ll = res.ll.lower; +} + +/* convert 32-bit float to 64-bit float */ +void HELPER(ldebr)(uint32_t r1, uint32_t r2) +{ + env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper, + &env->fpu_status); +} + +/* convert 128-bit float to 64-bit float */ +void HELPER(ldxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU x2; + x2.ll.upper = env->fregs[f2].ll; + x2.ll.lower = env->fregs[f2 + 2].ll; + env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status); + HELPER_LOG("%s: to 0x%ld\n", __FUNCTION__, env->fregs[f1].d); +} + +/* convert 64-bit float to 128-bit float */ +void HELPER(lxdbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU res; + res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status); + env->fregs[f1].ll = res.ll.upper; + env->fregs[f1 + 2].ll = res.ll.lower; +} + +/* convert 64-bit float to 32-bit float */ +void HELPER(ledbr)(uint32_t f1, uint32_t f2) +{ + float64 d2 = env->fregs[f2].d; + env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status); +} + +/* convert 128-bit float to 32-bit float */ +void HELPER(lexbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU x2; + x2.ll.upper = env->fregs[f2].ll; + x2.ll.lower = env->fregs[f2 + 2].ll; + env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status); + HELPER_LOG("%s: to 0x%d\n", __FUNCTION__, env->fregs[f1].l.upper); +} + +/* absolute value of 32-bit float */ +uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2) +{ + float32 v1; + float32 v2 = env->fregs[f2].d; + v1 = float32_abs(v2); + env->fregs[f1].d = v1; + return set_cc_nz_f32(v1); +} + +/* absolute value of 64-bit float */ +uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2) +{ + float64 v1; + float64 v2 = env->fregs[f2].d; + v1 = float64_abs(v2); + env->fregs[f1].d = v1; + return set_cc_nz_f64(v1); +} + +/* absolute value of 128-bit float */ +uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU v1; + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + v1.q = float128_abs(v2.q); + env->fregs[f1].ll = v1.ll.upper; + env->fregs[f1 + 2].ll = v1.ll.lower; + return set_cc_nz_f128(v1.q); +} + +/* load and test 64-bit float */ +uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].d = env->fregs[f2].d; + return set_cc_nz_f64(env->fregs[f1].d); +} + +/* load and test 32-bit float */ +uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].l.upper = env->fregs[f2].l.upper; + return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* load and test 128-bit float */ +uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU x; + x.ll.upper = env->fregs[f2].ll; + x.ll.lower = env->fregs[f2 + 2].ll; + env->fregs[f1].ll = x.ll.upper; + env->fregs[f1 + 2].ll = x.ll.lower; + return set_cc_nz_f128(x.q); +} + +/* load complement of 32-bit float */ +uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper); + + return set_cc_nz_f32(env->fregs[f1].l.upper); +} + +/* load complement of 64-bit float */ +uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].d = float64_chs(env->fregs[f2].d); + + return set_cc_nz_f64(env->fregs[f1].d); +} + +/* load complement of 128-bit float */ +uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU x1, x2; + x2.ll.upper = env->fregs[f2].ll; + x2.ll.lower = env->fregs[f2 + 2].ll; + x1.q = float128_chs(x2.q); + env->fregs[f1].ll = x1.ll.upper; + env->fregs[f1 + 2].ll = x1.ll.lower; + return set_cc_nz_f128(x1.q); +} + +/* 32-bit FP addition RM */ +void HELPER(aeb)(uint32_t f1, uint32_t val) +{ + float32 v1 = env->fregs[f1].l.upper; + CPU_FloatU v2; + v2.l = val; + HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __FUNCTION__, + v1, f1, v2.f); + env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status); +} + +/* 32-bit FP division RM */ +void HELPER(deb)(uint32_t f1, uint32_t val) +{ + float32 v1 = env->fregs[f1].l.upper; + CPU_FloatU v2; + v2.l = val; + HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __FUNCTION__, + v1, f1, v2.f); + env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status); +} + +/* 32-bit FP multiplication RM */ +void HELPER(meeb)(uint32_t f1, uint32_t val) +{ + float32 v1 = env->fregs[f1].l.upper; + CPU_FloatU v2; + v2.l = val; + HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __FUNCTION__, + v1, f1, v2.f); + env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status); +} + +/* 32-bit FP compare RR */ +uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2) +{ + float32 v1 = env->fregs[f1].l.upper; + float32 v2 = env->fregs[f2].l.upper;; + HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__, + v1, f1, v2); + return set_cc_f32(v1, v2); +} + +/* 64-bit FP compare RR */ +uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2) +{ + float64 v1 = env->fregs[f1].d; + float64 v2 = env->fregs[f2].d;; + HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __FUNCTION__, + v1, f1, v2); + return set_cc_f64(v1, v2); +} + +/* 128-bit FP compare RR */ +uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU v1; + v1.ll.upper = env->fregs[f1].ll; + v1.ll.lower = env->fregs[f1 + 2].ll; + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + + return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q, + &env->fpu_status)); +} + +/* 64-bit FP compare RM */ +uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; + CPU_DoubleU v2; + v2.ll = ldq(a2); + HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __FUNCTION__, v1, + f1, v2.d); + return set_cc_f64(v1, v2.d); +} + +/* 64-bit FP addition RM */ +uint32_t HELPER(adb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; + CPU_DoubleU v2; + v2.ll = ldq(a2); + HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __FUNCTION__, + v1, f1, v2.d); + env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status); + return set_cc_nz_f64(v1); +} + +/* 32-bit FP subtraction RM */ +void HELPER(seb)(uint32_t f1, uint32_t val) +{ + float32 v1 = env->fregs[f1].l.upper; + CPU_FloatU v2; + v2.l = val; + env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status); +} + +/* 64-bit FP subtraction RM */ +uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; + CPU_DoubleU v2; + v2.ll = ldq(a2); + env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status); + return set_cc_nz_f64(v1); +} + +/* 64-bit FP multiplication RM */ +void HELPER(mdb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; + CPU_DoubleU v2; + v2.ll = ldq(a2); + HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __FUNCTION__, + v1, f1, v2.d); + env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status); +} + +/* 64-bit FP division RM */ +void HELPER(ddb)(uint32_t f1, uint64_t a2) +{ + float64 v1 = env->fregs[f1].d; + CPU_DoubleU v2; + v2.ll = ldq(a2); + HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __FUNCTION__, + v1, f1, v2.d); + env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status); +} + +static void set_round_mode(int m3) +{ + switch (m3) { + case 0: + /* current mode */ + break; + case 1: + /* biased round no nearest */ + case 4: + /* round to nearest */ + set_float_rounding_mode(float_round_nearest_even, &env->fpu_status); + break; + case 5: + /* round to zero */ + set_float_rounding_mode(float_round_to_zero, &env->fpu_status); + break; + case 6: + /* round to +inf */ + set_float_rounding_mode(float_round_up, &env->fpu_status); + break; + case 7: + /* round to -inf */ + set_float_rounding_mode(float_round_down, &env->fpu_status); + break; + } +} + +/* convert 32-bit float to 64-bit int */ +uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ + float32 v2 = env->fregs[f2].l.upper; + set_round_mode(m3); + env->regs[r1] = float32_to_int64(v2, &env->fpu_status); + return set_cc_nz_f32(v2); +} + +/* convert 64-bit float to 64-bit int */ +uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ + float64 v2 = env->fregs[f2].d; + set_round_mode(m3); + env->regs[r1] = float64_to_int64(v2, &env->fpu_status); + return set_cc_nz_f64(v2); +} + +/* convert 128-bit float to 64-bit int */ +uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + set_round_mode(m3); + env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status); + if (float128_is_any_nan(v2.q)) { + return 3; + } else if (float128_is_zero(v2.q)) { + return 0; + } else if (float128_is_neg(v2.q)) { + return 1; + } else { + return 2; + } +} + +/* convert 32-bit float to 32-bit int */ +uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ + float32 v2 = env->fregs[f2].l.upper; + set_round_mode(m3); + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | + float32_to_int32(v2, &env->fpu_status); + return set_cc_nz_f32(v2); +} + +/* convert 64-bit float to 32-bit int */ +uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ + float64 v2 = env->fregs[f2].d; + set_round_mode(m3); + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | + float64_to_int32(v2, &env->fpu_status); + return set_cc_nz_f64(v2); +} + +/* convert 128-bit float to 32-bit int */ +uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3) +{ + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | + float128_to_int32(v2.q, &env->fpu_status); + return set_cc_nz_f128(v2.q); +} + +/* load 32-bit FP zero */ +void HELPER(lzer)(uint32_t f1) +{ + env->fregs[f1].l.upper = float32_zero; +} + +/* load 64-bit FP zero */ +void HELPER(lzdr)(uint32_t f1) +{ + env->fregs[f1].d = float64_zero; +} + +/* load 128-bit FP zero */ +void HELPER(lzxr)(uint32_t f1) +{ + CPU_QuadU x; + x.q = float64_to_float128(float64_zero, &env->fpu_status); + env->fregs[f1].ll = x.ll.upper; + env->fregs[f1 + 1].ll = x.ll.lower; +} + +/* 128-bit FP subtraction RR */ +uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU v1; + v1.ll.upper = env->fregs[f1].ll; + v1.ll.lower = env->fregs[f1 + 2].ll; + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + CPU_QuadU res; + res.q = float128_sub(v1.q, v2.q, &env->fpu_status); + env->fregs[f1].ll = res.ll.upper; + env->fregs[f1 + 2].ll = res.ll.lower; + return set_cc_nz_f128(res.q); +} + +/* 128-bit FP addition RR */ +uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2) +{ + CPU_QuadU v1; + v1.ll.upper = env->fregs[f1].ll; + v1.ll.lower = env->fregs[f1 + 2].ll; + CPU_QuadU v2; + v2.ll.upper = env->fregs[f2].ll; + v2.ll.lower = env->fregs[f2 + 2].ll; + CPU_QuadU res; + res.q = float128_add(v1.q, v2.q, &env->fpu_status); + env->fregs[f1].ll = res.ll.upper; + env->fregs[f1 + 2].ll = res.ll.lower; + return set_cc_nz_f128(res.q); +} + +/* 32-bit FP multiplication RR */ +void HELPER(meebr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper, + env->fregs[f2].l.upper, + &env->fpu_status); +} + +/* 64-bit FP division RR */ +void HELPER(ddbr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d, + &env->fpu_status); +} + +/* 64-bit FP multiply and add RM */ +void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3) +{ + HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __FUNCTION__, f1, a2, f3); + CPU_DoubleU v2; + v2.ll = ldq(a2); + env->fregs[f1].d = float64_add(env->fregs[f1].d, + float64_mul(v2.d, env->fregs[f3].d, + &env->fpu_status), + &env->fpu_status); +} + +/* 64-bit FP multiply and add RR */ +void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2) +{ + HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3); + env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d, + env->fregs[f3].d, + &env->fpu_status), + env->fregs[f1].d, &env->fpu_status); +} + +/* 64-bit FP multiply and subtract RR */ +void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2) +{ + HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3); + env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d, + env->fregs[f3].d, + &env->fpu_status), + env->fregs[f1].d, &env->fpu_status); +} + +/* 32-bit FP multiply and add RR */ +void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2) +{ + env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper, + float32_mul(env->fregs[f2].l.upper, + env->fregs[f3].l.upper, + &env->fpu_status), + &env->fpu_status); +} + +/* convert 32-bit float to 64-bit float */ +void HELPER(ldeb)(uint32_t f1, uint64_t a2) +{ + uint32_t v2; + v2 = ldl(a2); + env->fregs[f1].d = float32_to_float64(v2, + &env->fpu_status); +} + +/* convert 64-bit float to 128-bit float */ +void HELPER(lxdb)(uint32_t f1, uint64_t a2) +{ + CPU_DoubleU v2; + v2.ll = ldq(a2); + CPU_QuadU v1; + v1.q = float64_to_float128(v2.d, &env->fpu_status); + env->fregs[f1].ll = v1.ll.upper; + env->fregs[f1 + 2].ll = v1.ll.lower; +} + +/* test data class 32-bit */ +uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2) +{ + float32 v1 = env->fregs[f1].l.upper; + int neg = float32_is_neg(v1); + uint32_t cc = 0; + + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, (long)v1, m2, neg); + if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) || + (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) || + (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || + (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { + cc = 1; + } else if (m2 & (1 << (9-neg))) { + /* assume normalized number */ + cc = 1; + } + + /* FIXME: denormalized? */ + return cc; +} + +/* test data class 64-bit */ +uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2) +{ + float64 v1 = env->fregs[f1].d; + int neg = float64_is_neg(v1); + uint32_t cc = 0; + + HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg); + if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) || + (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) || + (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) || + (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) { + cc = 1; + } else if (m2 & (1 << (9-neg))) { + /* assume normalized number */ + cc = 1; + } + /* FIXME: denormalized? */ + return cc; +} + +/* test data class 128-bit */ +uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2) +{ + CPU_QuadU v1; + uint32_t cc = 0; + v1.ll.upper = env->fregs[f1].ll; + v1.ll.lower = env->fregs[f1 + 2].ll; + + int neg = float128_is_neg(v1.q); + if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) || + (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) || + (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) || + (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) { + cc = 1; + } else if (m2 & (1 << (9-neg))) { + /* assume normalized number */ + cc = 1; + } + /* FIXME: denormalized? */ + return cc; +} + +/* find leftmost one */ +uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2) +{ + uint64_t res = 0; + uint64_t ov2 = v2; + + while (!(v2 & 0x8000000000000000ULL) && v2) { + v2 <<= 1; + res++; + } + + if (!v2) { + env->regs[r1] = 64; + env->regs[r1 + 1] = 0; + return 0; + } else { + env->regs[r1] = res; + env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res); + return 2; + } +} + +/* square root 64-bit RR */ +void HELPER(sqdbr)(uint32_t f1, uint32_t f2) +{ + env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status); +} + +/* checksum */ +void HELPER(cksm)(uint32_t r1, uint32_t r2) +{ + uint64_t src = get_address_31fix(r2); + uint64_t src_len = env->regs[(r2 + 1) & 15]; + uint64_t cksm = (uint32_t)env->regs[r1]; + + while (src_len >= 4) { + cksm += ldl(src); + + /* move to next word */ + src_len -= 4; + src += 4; + } + + switch (src_len) { + case 0: + break; + case 1: + cksm += ldub(src) << 24; + break; + case 2: + cksm += lduw(src) << 16; + break; + case 3: + cksm += lduw(src) << 16; + cksm += ldub(src + 2) << 8; + break; + } + + /* indicate we've processed everything */ + env->regs[r2] = src + src_len; + env->regs[(r2 + 1) & 15] = 0; + + /* store result */ + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | + ((uint32_t)cksm + (cksm >> 32)); +} + +static inline uint32_t cc_calc_ltgt_32(CPUState *env, int32_t src, + int32_t dst) +{ + if (src == dst) { + return 0; + } else if (src < dst) { + return 1; + } else { + return 2; + } +} + +static inline uint32_t cc_calc_ltgt0_32(CPUState *env, int32_t dst) +{ + return cc_calc_ltgt_32(env, dst, 0); +} + +static inline uint32_t cc_calc_ltgt_64(CPUState *env, int64_t src, + int64_t dst) +{ + if (src == dst) { + return 0; + } else if (src < dst) { + return 1; + } else { + return 2; + } +} + +static inline uint32_t cc_calc_ltgt0_64(CPUState *env, int64_t dst) +{ + return cc_calc_ltgt_64(env, dst, 0); +} + +static inline uint32_t cc_calc_ltugtu_32(CPUState *env, uint32_t src, + uint32_t dst) +{ + if (src == dst) { + return 0; + } else if (src < dst) { + return 1; + } else { + return 2; + } +} + +static inline uint32_t cc_calc_ltugtu_64(CPUState *env, uint64_t src, + uint64_t dst) +{ + if (src == dst) { + return 0; + } else if (src < dst) { + return 1; + } else { + return 2; + } +} + +static inline uint32_t cc_calc_tm_32(CPUState *env, uint32_t val, uint32_t mask) +{ + HELPER_LOG("%s: val 0x%x mask 0x%x\n", __FUNCTION__, val, mask); + uint16_t r = val & mask; + if (r == 0 || mask == 0) { + return 0; + } else if (r == mask) { + return 3; + } else { + return 1; + } +} + +/* set condition code for test under mask */ +static inline uint32_t cc_calc_tm_64(CPUState *env, uint64_t val, uint32_t mask) +{ + uint16_t r = val & mask; + HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __FUNCTION__, val, mask, r); + if (r == 0 || mask == 0) { + return 0; + } else if (r == mask) { + return 3; + } else { + while (!(mask & 0x8000)) { + mask <<= 1; + val <<= 1; + } + if (val & 0x8000) { + return 2; + } else { + return 1; + } + } +} + +static inline uint32_t cc_calc_nz(CPUState *env, uint64_t dst) +{ + return !!dst; +} + +static inline uint32_t cc_calc_add_64(CPUState *env, int64_t a1, int64_t a2, + int64_t ar) +{ + if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) { + return 3; /* overflow */ + } else { + if (ar < 0) { + return 1; + } else if (ar > 0) { + return 2; + } else { + return 0; + } + } +} + +static inline uint32_t cc_calc_addu_64(CPUState *env, uint64_t a1, uint64_t a2, + uint64_t ar) +{ + if (ar == 0) { + if (a1) { + return 2; + } else { + return 0; + } + } else { + if (ar < a1 || ar < a2) { + return 3; + } else { + return 1; + } + } +} + +static inline uint32_t cc_calc_sub_64(CPUState *env, int64_t a1, int64_t a2, + int64_t ar) +{ + if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) { + return 3; /* overflow */ + } else { + if (ar < 0) { + return 1; + } else if (ar > 0) { + return 2; + } else { + return 0; + } + } +} + +static inline uint32_t cc_calc_subu_64(CPUState *env, uint64_t a1, uint64_t a2, + uint64_t ar) +{ + if (ar == 0) { + return 2; + } else { + if (a2 > a1) { + return 1; + } else { + return 3; + } + } +} + +static inline uint32_t cc_calc_abs_64(CPUState *env, int64_t dst) +{ + if ((uint64_t)dst == 0x8000000000000000ULL) { + return 3; + } else if (dst) { + return 1; + } else { + return 0; + } +} + +static inline uint32_t cc_calc_nabs_64(CPUState *env, int64_t dst) +{ + return !!dst; +} + +static inline uint32_t cc_calc_comp_64(CPUState *env, int64_t dst) +{ + if ((uint64_t)dst == 0x8000000000000000ULL) { + return 3; + } else if (dst < 0) { + return 1; + } else if (dst > 0) { + return 2; + } else { + return 0; + } +} + + +static inline uint32_t cc_calc_add_32(CPUState *env, int32_t a1, int32_t a2, + int32_t ar) +{ + if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) { + return 3; /* overflow */ + } else { + if (ar < 0) { + return 1; + } else if (ar > 0) { + return 2; + } else { + return 0; + } + } +} + +static inline uint32_t cc_calc_addu_32(CPUState *env, uint32_t a1, uint32_t a2, + uint32_t ar) +{ + if (ar == 0) { + if (a1) { + return 2; + } else { + return 0; + } + } else { + if (ar < a1 || ar < a2) { + return 3; + } else { + return 1; + } + } +} + +static inline uint32_t cc_calc_sub_32(CPUState *env, int32_t a1, int32_t a2, + int32_t ar) +{ + if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) { + return 3; /* overflow */ + } else { + if (ar < 0) { + return 1; + } else if (ar > 0) { + return 2; + } else { + return 0; + } + } +} + +static inline uint32_t cc_calc_subu_32(CPUState *env, uint32_t a1, uint32_t a2, + uint32_t ar) +{ + if (ar == 0) { + return 2; + } else { + if (a2 > a1) { + return 1; + } else { + return 3; + } + } +} + +static inline uint32_t cc_calc_abs_32(CPUState *env, int32_t dst) +{ + if ((uint32_t)dst == 0x80000000UL) { + return 3; + } else if (dst) { + return 1; + } else { + return 0; + } +} + +static inline uint32_t cc_calc_nabs_32(CPUState *env, int32_t dst) +{ + return !!dst; +} + +static inline uint32_t cc_calc_comp_32(CPUState *env, int32_t dst) +{ + if ((uint32_t)dst == 0x80000000UL) { + return 3; + } else if (dst < 0) { + return 1; + } else if (dst > 0) { + return 2; + } else { + return 0; + } +} + +/* calculate condition code for insert character under mask insn */ +static inline uint32_t cc_calc_icm_32(CPUState *env, uint32_t mask, uint32_t val) +{ + HELPER_LOG("%s: mask 0x%x val %d\n", __FUNCTION__, mask, val); + uint32_t cc; + + if (mask == 0xf) { + if (!val) { + return 0; + } else if (val & 0x80000000) { + return 1; + } else { + return 2; + } + } + + if (!val || !mask) { + cc = 0; + } else { + while (mask != 1) { + mask >>= 1; + val >>= 8; + } + if (val & 0x80) { + cc = 1; + } else { + cc = 2; + } + } + return cc; +} + +static inline uint32_t cc_calc_slag(CPUState *env, uint64_t src, uint64_t shift) +{ + uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift); + uint64_t match, r; + + /* check if the sign bit stays the same */ + if (src & (1ULL << 63)) { + match = mask; + } else { + match = 0; + } + + if ((src & mask) != match) { + /* overflow */ + return 3; + } + + r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63)); + + if ((int64_t)r == 0) { + return 0; + } else if ((int64_t)r < 0) { + return 1; + } + + return 2; +} + + +static inline uint32_t do_calc_cc(CPUState *env, uint32_t cc_op, uint64_t src, + uint64_t dst, uint64_t vr) +{ + uint32_t r = 0; + + switch (cc_op) { + case CC_OP_CONST0: + case CC_OP_CONST1: + case CC_OP_CONST2: + case CC_OP_CONST3: + /* cc_op value _is_ cc */ + r = cc_op; + break; + case CC_OP_LTGT0_32: + r = cc_calc_ltgt0_32(env, dst); + break; + case CC_OP_LTGT0_64: + r = cc_calc_ltgt0_64(env, dst); + break; + case CC_OP_LTGT_32: + r = cc_calc_ltgt_32(env, src, dst); + break; + case CC_OP_LTGT_64: + r = cc_calc_ltgt_64(env, src, dst); + break; + case CC_OP_LTUGTU_32: + r = cc_calc_ltugtu_32(env, src, dst); + break; + case CC_OP_LTUGTU_64: + r = cc_calc_ltugtu_64(env, src, dst); + break; + case CC_OP_TM_32: + r = cc_calc_tm_32(env, src, dst); + break; + case CC_OP_TM_64: + r = cc_calc_tm_64(env, src, dst); + break; + case CC_OP_NZ: + r = cc_calc_nz(env, dst); + break; + case CC_OP_ADD_64: + r = cc_calc_add_64(env, src, dst, vr); + break; + case CC_OP_ADDU_64: + r = cc_calc_addu_64(env, src, dst, vr); + break; + case CC_OP_SUB_64: + r = cc_calc_sub_64(env, src, dst, vr); + break; + case CC_OP_SUBU_64: + r = cc_calc_subu_64(env, src, dst, vr); + break; + case CC_OP_ABS_64: + r = cc_calc_abs_64(env, dst); + break; + case CC_OP_NABS_64: + r = cc_calc_nabs_64(env, dst); + break; + case CC_OP_COMP_64: + r = cc_calc_comp_64(env, dst); + break; + + case CC_OP_ADD_32: + r = cc_calc_add_32(env, src, dst, vr); + break; + case CC_OP_ADDU_32: + r = cc_calc_addu_32(env, src, dst, vr); + break; + case CC_OP_SUB_32: + r = cc_calc_sub_32(env, src, dst, vr); + break; + case CC_OP_SUBU_32: + r = cc_calc_subu_32(env, src, dst, vr); + break; + case CC_OP_ABS_32: + r = cc_calc_abs_64(env, dst); + break; + case CC_OP_NABS_32: + r = cc_calc_nabs_64(env, dst); + break; + case CC_OP_COMP_32: + r = cc_calc_comp_32(env, dst); + break; + + case CC_OP_ICM: + r = cc_calc_icm_32(env, src, dst); + break; + case CC_OP_SLAG: + r = cc_calc_slag(env, src, dst); + break; + + case CC_OP_LTGT_F32: + r = set_cc_f32(src, dst); + break; + case CC_OP_LTGT_F64: + r = set_cc_f64(src, dst); + break; + case CC_OP_NZ_F32: + r = set_cc_nz_f32(dst); + break; + case CC_OP_NZ_F64: + r = set_cc_nz_f64(dst); + break; + + default: + cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op)); + } + + HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __FUNCTION__, + cc_name(cc_op), src, dst, vr, r); + return r; +} + +uint32_t calc_cc(CPUState *env, uint32_t cc_op, uint64_t src, uint64_t dst, + uint64_t vr) +{ + return do_calc_cc(env, cc_op, src, dst, vr); +} + +uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst, + uint64_t vr) +{ + return do_calc_cc(env, cc_op, src, dst, vr); +} + +uint64_t HELPER(cvd)(int32_t bin) +{ + /* positive 0 */ + uint64_t dec = 0x0c; + int shift = 4; + + if (bin < 0) { + bin = -bin; + dec = 0x0d; + } + + for (shift = 4; (shift < 64) && bin; shift += 4) { + int current_number = bin % 10; + + dec |= (current_number) << shift; + bin /= 10; + } + + return dec; +} + +void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src) +{ + int len_dest = len >> 4; + int len_src = len & 0xf; + uint8_t b; + int second_nibble = 0; + + dest += len_dest; + src += len_src; + + /* last byte is special, it only flips the nibbles */ + b = ldub(src); + stb(dest, (b << 4) | (b >> 4)); + src--; + len_src--; + + /* now pad every nibble with 0xf0 */ + + while (len_dest > 0) { + uint8_t cur_byte = 0; + + if (len_src > 0) { + cur_byte = ldub(src); + } + + len_dest--; + dest--; + + /* only advance one nibble at a time */ + if (second_nibble) { + cur_byte >>= 4; + len_src--; + src--; + } + second_nibble = !second_nibble; + + /* digit */ + cur_byte = (cur_byte & 0xf); + /* zone bits */ + cur_byte |= 0xf0; + + stb(dest, cur_byte); + } +} + +void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans) +{ + int i; + + for (i = 0; i <= len; i++) { + uint8_t byte = ldub(array + i); + uint8_t new_byte = ldub(trans + byte); + stb(array + i, new_byte); + } +} + +#ifndef CONFIG_USER_ONLY + +void HELPER(load_psw)(uint64_t mask, uint64_t addr) +{ + load_psw(env, mask, addr); + cpu_loop_exit(env); +} + +static void program_interrupt(CPUState *env, uint32_t code, int ilc) +{ + qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr); + + if (kvm_enabled()) { +#ifdef CONFIG_KVM + kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code); +#endif + } else { + env->int_pgm_code = code; + env->int_pgm_ilc = ilc; + env->exception_index = EXCP_PGM; + cpu_loop_exit(env); + } +} + +static void ext_interrupt(CPUState *env, int type, uint32_t param, + uint64_t param64) +{ + cpu_inject_ext(env, type, param, param64); +} + +int sclp_service_call(CPUState *env, uint32_t sccb, uint64_t code) +{ + int r = 0; + int shift = 0; + +#ifdef DEBUG_HELPER + printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code); +#endif + + if (sccb & ~0x7ffffff8ul) { + fprintf(stderr, "KVM: invalid sccb address 0x%x\n", sccb); + r = -1; + goto out; + } + + switch(code) { + case SCLP_CMDW_READ_SCP_INFO: + case SCLP_CMDW_READ_SCP_INFO_FORCED: + while ((ram_size >> (20 + shift)) > 65535) { + shift++; + } + stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift)); + stb_phys(sccb + SCP_INCREMENT, 1 << shift); + stw_phys(sccb + SCP_RESPONSE_CODE, 0x10); + + if (kvm_enabled()) { +#ifdef CONFIG_KVM + kvm_s390_interrupt_internal(env, KVM_S390_INT_SERVICE, + sccb & ~3, 0, 1); +#endif + } else { + env->psw.addr += 4; + ext_interrupt(env, EXT_SERVICE, sccb & ~3, 0); + } + break; + default: +#ifdef DEBUG_HELPER + printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code); +#endif + r = -1; + break; + } + +out: + return r; +} + +/* SCLP service call */ +uint32_t HELPER(servc)(uint32_t r1, uint64_t r2) +{ + if (sclp_service_call(env, r1, r2)) { + return 3; + } + + return 0; +} + +/* DIAG */ +uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code) +{ + uint64_t r; + + switch (num) { + case 0x500: + /* KVM hypercall */ + r = s390_virtio_hypercall(env, mem, code); + break; + case 0x44: + /* yield */ + r = 0; + break; + case 0x308: + /* ipl */ + r = 0; + break; + default: + r = -1; + break; + } + + if (r) { + program_interrupt(env, PGM_OPERATION, ILC_LATER_INC); + } + + return r; +} + +/* Store CPU ID */ +void HELPER(stidp)(uint64_t a1) +{ + stq(a1, env->cpu_num); +} + +/* Set Prefix */ +void HELPER(spx)(uint64_t a1) +{ + uint32_t prefix; + + prefix = ldl(a1); + env->psa = prefix & 0xfffff000; + qemu_log("prefix: %#x\n", prefix); + tlb_flush_page(env, 0); + tlb_flush_page(env, TARGET_PAGE_SIZE); +} + +/* Set Clock */ +uint32_t HELPER(sck)(uint64_t a1) +{ + /* XXX not implemented - is it necessary? */ + + return 0; +} + +static inline uint64_t clock_value(CPUState *env) +{ + uint64_t time; + + time = env->tod_offset + + time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime); + + return time; +} + +/* Store Clock */ +uint32_t HELPER(stck)(uint64_t a1) +{ + stq(a1, clock_value(env)); + + return 0; +} + +/* Store Clock Extended */ +uint32_t HELPER(stcke)(uint64_t a1) +{ + stb(a1, 0); + /* basically the same value as stck */ + stq(a1 + 1, clock_value(env) | env->cpu_num); + /* more fine grained than stck */ + stq(a1 + 9, 0); + /* XXX programmable fields */ + stw(a1 + 17, 0); + + + return 0; +} + +/* Set Clock Comparator */ +void HELPER(sckc)(uint64_t a1) +{ + uint64_t time = ldq(a1); + + if (time == -1ULL) { + return; + } + + /* difference between now and then */ + time -= clock_value(env); + /* nanoseconds */ + time = (time * 125) >> 9; + + qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time); +} + +/* Store Clock Comparator */ +void HELPER(stckc)(uint64_t a1) +{ + /* XXX implement */ + stq(a1, 0); +} + +/* Set CPU Timer */ +void HELPER(spt)(uint64_t a1) +{ + uint64_t time = ldq(a1); + + if (time == -1ULL) { + return; + } + + /* nanoseconds */ + time = (time * 125) >> 9; + + qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time); +} + +/* Store CPU Timer */ +void HELPER(stpt)(uint64_t a1) +{ + /* XXX implement */ + stq(a1, 0); +} + +/* Store System Information */ +uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1) +{ + int cc = 0; + int sel1, sel2; + + if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 && + ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) { + /* valid function code, invalid reserved bits */ + program_interrupt(env, PGM_SPECIFICATION, 2); + } + + sel1 = r0 & STSI_R0_SEL1_MASK; + sel2 = r1 & STSI_R1_SEL2_MASK; + + /* XXX: spec exception if sysib is not 4k-aligned */ + + switch (r0 & STSI_LEVEL_MASK) { + case STSI_LEVEL_1: + if ((sel1 == 1) && (sel2 == 1)) { + /* Basic Machine Configuration */ + struct sysib_111 sysib; + + memset(&sysib, 0, sizeof(sysib)); + ebcdic_put(sysib.manuf, "QEMU ", 16); + /* same as machine type number in STORE CPU ID */ + ebcdic_put(sysib.type, "QEMU", 4); + /* same as model number in STORE CPU ID */ + ebcdic_put(sysib.model, "QEMU ", 16); + ebcdic_put(sysib.sequence, "QEMU ", 16); + ebcdic_put(sysib.plant, "QEMU", 4); + cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1); + } else if ((sel1 == 2) && (sel2 == 1)) { + /* Basic Machine CPU */ + struct sysib_121 sysib; + + memset(&sysib, 0, sizeof(sysib)); + /* XXX make different for different CPUs? */ + ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16); + ebcdic_put(sysib.plant, "QEMU", 4); + stw_p(&sysib.cpu_addr, env->cpu_num); + cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1); + } else if ((sel1 == 2) && (sel2 == 2)) { + /* Basic Machine CPUs */ + struct sysib_122 sysib; + + memset(&sysib, 0, sizeof(sysib)); + stl_p(&sysib.capability, 0x443afc29); + /* XXX change when SMP comes */ + stw_p(&sysib.total_cpus, 1); + stw_p(&sysib.active_cpus, 1); + stw_p(&sysib.standby_cpus, 0); + stw_p(&sysib.reserved_cpus, 0); + cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1); + } else { + cc = 3; + } + break; + case STSI_LEVEL_2: + { + if ((sel1 == 2) && (sel2 == 1)) { + /* LPAR CPU */ + struct sysib_221 sysib; + + memset(&sysib, 0, sizeof(sysib)); + /* XXX make different for different CPUs? */ + ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16); + ebcdic_put(sysib.plant, "QEMU", 4); + stw_p(&sysib.cpu_addr, env->cpu_num); + stw_p(&sysib.cpu_id, 0); + cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1); + } else if ((sel1 == 2) && (sel2 == 2)) { + /* LPAR CPUs */ + struct sysib_222 sysib; + + memset(&sysib, 0, sizeof(sysib)); + stw_p(&sysib.lpar_num, 0); + sysib.lcpuc = 0; + /* XXX change when SMP comes */ + stw_p(&sysib.total_cpus, 1); + stw_p(&sysib.conf_cpus, 1); + stw_p(&sysib.standby_cpus, 0); + stw_p(&sysib.reserved_cpus, 0); + ebcdic_put(sysib.name, "QEMU ", 8); + stl_p(&sysib.caf, 1000); + stw_p(&sysib.dedicated_cpus, 0); + stw_p(&sysib.shared_cpus, 0); + cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1); + } else { + cc = 3; + } + break; + } + case STSI_LEVEL_3: + { + if ((sel1 == 2) && (sel2 == 2)) { + /* VM CPUs */ + struct sysib_322 sysib; + + memset(&sysib, 0, sizeof(sysib)); + sysib.count = 1; + /* XXX change when SMP comes */ + stw_p(&sysib.vm[0].total_cpus, 1); + stw_p(&sysib.vm[0].conf_cpus, 1); + stw_p(&sysib.vm[0].standby_cpus, 0); + stw_p(&sysib.vm[0].reserved_cpus, 0); + ebcdic_put(sysib.vm[0].name, "KVMguest", 8); + stl_p(&sysib.vm[0].caf, 1000); + ebcdic_put(sysib.vm[0].cpi, "KVM/Linux ", 16); + cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1); + } else { + cc = 3; + } + break; + } + case STSI_LEVEL_CURRENT: + env->regs[0] = STSI_LEVEL_3; + break; + default: + cc = 3; + break; + } + + return cc; +} + +void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + int i; + uint64_t src = a2; + + for (i = r1;; i = (i + 1) % 16) { + env->cregs[i] = ldq(src); + HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n", + i, src, env->cregs[i]); + src += sizeof(uint64_t); + + if (i == r3) { + break; + } + } + + tlb_flush(env, 1); +} + +void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + int i; + uint64_t src = a2; + + for (i = r1;; i = (i + 1) % 16) { + env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src); + src += sizeof(uint32_t); + + if (i == r3) { + break; + } + } + + tlb_flush(env, 1); +} + +void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + int i; + uint64_t dest = a2; + + for (i = r1;; i = (i + 1) % 16) { + stq(dest, env->cregs[i]); + dest += sizeof(uint64_t); + + if (i == r3) { + break; + } + } +} + +void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3) +{ + int i; + uint64_t dest = a2; + + for (i = r1;; i = (i + 1) % 16) { + stl(dest, env->cregs[i]); + dest += sizeof(uint32_t); + + if (i == r3) { + break; + } + } +} + +uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2) +{ + /* XXX implement */ + + return 0; +} + +/* insert storage key extended */ +uint64_t HELPER(iske)(uint64_t r2) +{ + uint64_t addr = get_address(0, 0, r2); + + if (addr > ram_size) { + return 0; + } + + return env->storage_keys[addr / TARGET_PAGE_SIZE]; +} + +/* set storage key extended */ +void HELPER(sske)(uint32_t r1, uint64_t r2) +{ + uint64_t addr = get_address(0, 0, r2); + + if (addr > ram_size) { + return; + } + + env->storage_keys[addr / TARGET_PAGE_SIZE] = r1; +} + +/* reset reference bit extended */ +uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2) +{ + uint8_t re; + uint8_t key; + if (r2 > ram_size) { + return 0; + } + + key = env->storage_keys[r2 / TARGET_PAGE_SIZE]; + re = key & (SK_R | SK_C); + env->storage_keys[r2 / TARGET_PAGE_SIZE] = (key & ~SK_R); + + /* + * cc + * + * 0 Reference bit zero; change bit zero + * 1 Reference bit zero; change bit one + * 2 Reference bit one; change bit zero + * 3 Reference bit one; change bit one + */ + + return re >> 1; +} + +/* compare and swap and purge */ +uint32_t HELPER(csp)(uint32_t r1, uint32_t r2) +{ + uint32_t cc; + uint32_t o1 = env->regs[r1]; + uint64_t a2 = get_address_31fix(r2) & ~3ULL; + uint32_t o2 = ldl(a2); + + if (o1 == o2) { + stl(a2, env->regs[(r1 + 1) & 15]); + if (env->regs[r2] & 0x3) { + /* flush TLB / ALB */ + tlb_flush(env, 1); + } + cc = 0; + } else { + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2; + cc = 1; + } + + return cc; +} + +static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2, + uint64_t mode2) +{ + target_ulong src, dest; + int flags, cc = 0, i; + + if (!l) { + return 0; + } else if (l > 256) { + /* max 256 */ + l = 256; + cc = 3; + } + + if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) { + cpu_loop_exit(env); + } + dest |= a1 & ~TARGET_PAGE_MASK; + + if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) { + cpu_loop_exit(env); + } + src |= a2 & ~TARGET_PAGE_MASK; + + /* XXX replace w/ memcpy */ + for (i = 0; i < l; i++) { + /* XXX be more clever */ + if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) || + (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) { + mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2); + break; + } + stb_phys(dest + i, ldub_phys(src + i)); + } + + return cc; +} + +uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2) +{ + HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n", + __FUNCTION__, l, a1, a2); + + return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY); +} + +uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2) +{ + HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n", + __FUNCTION__, l, a1, a2); + + return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY); +} + +uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr) +{ + int cc = 0; + + HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n", + __FUNCTION__, order_code, r1, cpu_addr); + + /* Remember: Use "R1 or R1+1, whichever is the odd-numbered register" + as parameter (input). Status (output) is always R1. */ + + switch (order_code) { + case SIGP_SET_ARCH: + /* switch arch */ + break; + case SIGP_SENSE: + /* enumerate CPU status */ + if (cpu_addr) { + /* XXX implement when SMP comes */ + return 3; + } + env->regs[r1] &= 0xffffffff00000000ULL; + cc = 1; + break; +#if !defined (CONFIG_USER_ONLY) + case SIGP_RESTART: + qemu_system_reset_request(); + cpu_loop_exit(env); + break; + case SIGP_STOP: + qemu_system_shutdown_request(); + cpu_loop_exit(env); + break; +#endif + default: + /* unknown sigp */ + fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code); + cc = 3; + } + + return cc; +} + +void HELPER(sacf)(uint64_t a1) +{ + HELPER_LOG("%s: %16" PRIx64 "\n", __FUNCTION__, a1); + + switch (a1 & 0xf00) { + case 0x000: + env->psw.mask &= ~PSW_MASK_ASC; + env->psw.mask |= PSW_ASC_PRIMARY; + break; + case 0x100: + env->psw.mask &= ~PSW_MASK_ASC; + env->psw.mask |= PSW_ASC_SECONDARY; + break; + case 0x300: + env->psw.mask &= ~PSW_MASK_ASC; + env->psw.mask |= PSW_ASC_HOME; + break; + default: + qemu_log("unknown sacf mode: %" PRIx64 "\n", a1); + program_interrupt(env, PGM_SPECIFICATION, 2); + break; + } +} + +/* invalidate pte */ +void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr) +{ + uint64_t page = vaddr & TARGET_PAGE_MASK; + uint64_t pte = 0; + + /* XXX broadcast to other CPUs */ + + /* XXX Linux is nice enough to give us the exact pte address. + According to spec we'd have to find it out ourselves */ + /* XXX Linux is fine with overwriting the pte, the spec requires + us to only set the invalid bit */ + stq_phys(pte_addr, pte | _PAGE_INVALID); + + /* XXX we exploit the fact that Linux passes the exact virtual + address here - it's not obliged to! */ + tlb_flush_page(env, page); + + /* XXX 31-bit hack */ + if (page & 0x80000000) { + tlb_flush_page(env, page & ~0x80000000); + } else { + tlb_flush_page(env, page | 0x80000000); + } +} + +/* flush local tlb */ +void HELPER(ptlb)(void) +{ + tlb_flush(env, 1); +} + +/* store using real address */ +void HELPER(stura)(uint64_t addr, uint32_t v1) +{ + stw_phys(get_address(0, 0, addr), v1); +} + +/* load real address */ +uint32_t HELPER(lra)(uint64_t addr, uint32_t r1) +{ + uint32_t cc = 0; + int old_exc = env->exception_index; + uint64_t asc = env->psw.mask & PSW_MASK_ASC; + uint64_t ret; + int flags; + + /* XXX incomplete - has more corner cases */ + if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) { + program_interrupt(env, PGM_SPECIAL_OP, 2); + } + + env->exception_index = old_exc; + if (mmu_translate(env, addr, 0, asc, &ret, &flags)) { + cc = 3; + } + if (env->exception_index == EXCP_PGM) { + ret = env->int_pgm_code | 0x80000000; + } else { + ret |= addr & ~TARGET_PAGE_MASK; + } + env->exception_index = old_exc; + + if (!(env->psw.mask & PSW_MASK_64)) { + env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | (ret & 0xffffffffULL); + } else { + env->regs[r1] = ret; + } + + return cc; +} + +#endif diff --git a/target-s390x/translate.c b/target-s390x/translate.c index d33bfb1..ee15672 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -2,6 +2,7 @@ * S/390 translation * * Copyright (c) 2009 Ulrich Hecht + * Copyright (c) 2010 Alexander Graf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,46 +17,5233 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ +#include +#include +#include +#include +#include + +/* #define DEBUG_ILLEGAL_INSTRUCTIONS */ +/* #define DEBUG_INLINE_BRANCHES */ +#define S390X_DEBUG_DISAS +/* #define S390X_DEBUG_DISAS_VERBOSE */ + +#ifdef S390X_DEBUG_DISAS_VERBOSE +# define LOG_DISAS(...) qemu_log(__VA_ARGS__) +#else +# define LOG_DISAS(...) do { } while (0) +#endif #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "qemu-log.h" +/* global register indexes */ +static TCGv_ptr cpu_env; + +#include "gen-icount.h" +#include "helpers.h" +#define GEN_HELPER 1 +#include "helpers.h" + +typedef struct DisasContext DisasContext; +struct DisasContext { + uint64_t pc; + int is_jmp; + enum cc_op cc_op; + struct TranslationBlock *tb; +}; + +#define DISAS_EXCP 4 + +static void gen_op_calc_cc(DisasContext *s); + +#ifdef DEBUG_INLINE_BRANCHES +static uint64_t inline_branch_hit[CC_OP_MAX]; +static uint64_t inline_branch_miss[CC_OP_MAX]; +#endif + +static inline void debug_insn(uint64_t insn) +{ + LOG_DISAS("insn: 0x%" PRIx64 "\n", insn); +} + +static inline uint64_t pc_to_link_info(DisasContext *s, uint64_t pc) +{ + if (!(s->tb->flags & FLAG_MASK_64)) { + if (s->tb->flags & FLAG_MASK_32) { + return pc | 0x80000000; + } + } + return pc; +} + void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, int flags) { int i; + + for (i = 0; i < 16; i++) { + cpu_fprintf(f, "R%02d=%016" PRIx64, i, env->regs[i]); + if ((i % 4) == 3) { + cpu_fprintf(f, "\n"); + } else { + cpu_fprintf(f, " "); + } + } + for (i = 0; i < 16; i++) { - cpu_fprintf(f, "R%02d=%016lx", i, env->regs[i]); + cpu_fprintf(f, "F%02d=%016" PRIx64, i, *(uint64_t *)&env->fregs[i]); if ((i % 4) == 3) { cpu_fprintf(f, "\n"); } else { cpu_fprintf(f, " "); } } + + cpu_fprintf(f, "\n"); + +#ifndef CONFIG_USER_ONLY for (i = 0; i < 16; i++) { - cpu_fprintf(f, "F%02d=%016lx", i, (long)env->fregs[i].i); + cpu_fprintf(f, "C%02d=%016" PRIx64, i, env->cregs[i]); if ((i % 4) == 3) { cpu_fprintf(f, "\n"); } else { cpu_fprintf(f, " "); } } - cpu_fprintf(f, "PSW=mask %016lx addr %016lx cc %02x\n", env->psw.mask, env->psw.addr, env->cc); +#endif + + cpu_fprintf(f, "\n"); + + if (env->cc_op > 3) { + cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %15s\n", + env->psw.mask, env->psw.addr, cc_name(env->cc_op)); + } else { + cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %02x\n", + env->psw.mask, env->psw.addr, env->cc_op); + } + +#ifdef DEBUG_INLINE_BRANCHES + for (i = 0; i < CC_OP_MAX; i++) { + cpu_fprintf(f, " %15s = %10ld\t%10ld\n", cc_name(i), + inline_branch_miss[i], inline_branch_hit[i]); + } +#endif } -void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) +static TCGv_i64 psw_addr; +static TCGv_i64 psw_mask; + +static TCGv_i32 cc_op; +static TCGv_i64 cc_src; +static TCGv_i64 cc_dst; +static TCGv_i64 cc_vr; + +static char cpu_reg_names[10*3 + 6*4]; +static TCGv_i64 regs[16]; + +static uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; + +void s390x_translate_init(void) +{ + int i; + size_t cpu_reg_names_size = sizeof(cpu_reg_names); + char *p; + + cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); + psw_addr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, psw.addr), + "psw_addr"); + psw_mask = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, psw.mask), + "psw_mask"); + + cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op), + "cc_op"); + cc_src = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_src), + "cc_src"); + cc_dst = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_dst), + "cc_dst"); + cc_vr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_vr), + "cc_vr"); + + p = cpu_reg_names; + for (i = 0; i < 16; i++) { + snprintf(p, cpu_reg_names_size, "r%d", i); + regs[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, regs[i]), p); + p += (i < 10) ? 3 : 4; + cpu_reg_names_size -= (i < 10) ? 3 : 4; + } +} + +static inline TCGv_i64 load_reg(int reg) { + TCGv_i64 r = tcg_temp_new_i64(); + tcg_gen_mov_i64(r, regs[reg]); + return r; } -void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) +static inline TCGv_i64 load_freg(int reg) { + TCGv_i64 r = tcg_temp_new_i64(); + tcg_gen_ld_i64(r, cpu_env, offsetof(CPUState, fregs[reg].d)); + return r; } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +static inline TCGv_i32 load_freg32(int reg) { - env->psw.addr = gen_opc_pc[pc_pos]; + TCGv_i32 r = tcg_temp_new_i32(); + tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, fregs[reg].l.upper)); + return r; +} + +static inline TCGv_i32 load_reg32(int reg) +{ + TCGv_i32 r = tcg_temp_new_i32(); + tcg_gen_trunc_i64_i32(r, regs[reg]); + return r; +} + +static inline TCGv_i64 load_reg32_i64(int reg) +{ + TCGv_i64 r = tcg_temp_new_i64(); + tcg_gen_ext32s_i64(r, regs[reg]); + return r; +} + +static inline void store_reg(int reg, TCGv_i64 v) +{ + tcg_gen_mov_i64(regs[reg], v); +} + +static inline void store_freg(int reg, TCGv_i64 v) +{ + tcg_gen_st_i64(v, cpu_env, offsetof(CPUState, fregs[reg].d)); +} + +static inline void store_reg32(int reg, TCGv_i32 v) +{ +#if HOST_LONG_BITS == 32 + tcg_gen_mov_i32(TCGV_LOW(regs[reg]), v); +#else + TCGv_i64 tmp = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(tmp, v); + /* 32 bit register writes keep the upper half */ + tcg_gen_deposit_i64(regs[reg], regs[reg], tmp, 0, 32); + tcg_temp_free_i64(tmp); +#endif +} + +static inline void store_reg32_i64(int reg, TCGv_i64 v) +{ + /* 32 bit register writes keep the upper half */ +#if HOST_LONG_BITS == 32 + tcg_gen_mov_i32(TCGV_LOW(regs[reg]), TCGV_LOW(v)); +#else + tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32); +#endif +} + +static inline void store_reg16(int reg, TCGv_i32 v) +{ + TCGv_i64 tmp = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(tmp, v); + /* 16 bit register writes keep the upper bytes */ + tcg_gen_deposit_i64(regs[reg], regs[reg], tmp, 0, 16); + tcg_temp_free_i64(tmp); +} + +static inline void store_reg8(int reg, TCGv_i64 v) +{ + /* 8 bit register writes keep the upper bytes */ + tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 8); +} + +static inline void store_freg32(int reg, TCGv_i32 v) +{ + tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, fregs[reg].l.upper)); +} + +static inline void update_psw_addr(DisasContext *s) +{ + /* psw.addr */ + tcg_gen_movi_i64(psw_addr, s->pc); +} + +static inline void potential_page_fault(DisasContext *s) +{ +#ifndef CONFIG_USER_ONLY + update_psw_addr(s); + gen_op_calc_cc(s); +#endif +} + +static inline uint64_t ld_code2(uint64_t pc) +{ + return (uint64_t)lduw_code(pc); +} + +static inline uint64_t ld_code4(uint64_t pc) +{ + return (uint64_t)ldl_code(pc); +} + +static inline uint64_t ld_code6(uint64_t pc) +{ + uint64_t opc; + opc = (uint64_t)lduw_code(pc) << 32; + opc |= (uint64_t)(uint32_t)ldl_code(pc+2); + return opc; +} + +static inline int get_mem_index(DisasContext *s) +{ + switch (s->tb->flags & FLAG_MASK_ASC) { + case PSW_ASC_PRIMARY >> 32: + return 0; + case PSW_ASC_SECONDARY >> 32: + return 1; + case PSW_ASC_HOME >> 32: + return 2; + default: + tcg_abort(); + break; + } +} + +static inline void gen_debug(DisasContext *s) +{ + TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG); + update_psw_addr(s); + gen_op_calc_cc(s); + gen_helper_exception(tmp); + tcg_temp_free_i32(tmp); + s->is_jmp = DISAS_EXCP; +} + +#ifdef CONFIG_USER_ONLY + +static void gen_illegal_opcode(DisasContext *s, int ilc) +{ + TCGv_i32 tmp = tcg_const_i32(EXCP_SPEC); + update_psw_addr(s); + gen_op_calc_cc(s); + gen_helper_exception(tmp); + tcg_temp_free_i32(tmp); + s->is_jmp = DISAS_EXCP; +} + +#else /* CONFIG_USER_ONLY */ + +static void debug_print_inst(DisasContext *s, int ilc) +{ +#ifdef DEBUG_ILLEGAL_INSTRUCTIONS + uint64_t inst = 0; + + switch (ilc & 3) { + case 1: + inst = ld_code2(s->pc); + break; + case 2: + inst = ld_code4(s->pc); + break; + case 3: + inst = ld_code6(s->pc); + break; + } + + fprintf(stderr, "Illegal instruction [%d at %016" PRIx64 "]: 0x%016" + PRIx64 "\n", ilc, s->pc, inst); +#endif +} + +static void gen_program_exception(DisasContext *s, int ilc, int code) +{ + TCGv_i32 tmp; + + debug_print_inst(s, ilc); + + /* remember what pgm exeption this was */ + tmp = tcg_const_i32(code); + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, int_pgm_code)); + tcg_temp_free_i32(tmp); + + tmp = tcg_const_i32(ilc); + tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, int_pgm_ilc)); + tcg_temp_free_i32(tmp); + + /* advance past instruction */ + s->pc += (ilc * 2); + update_psw_addr(s); + + /* save off cc */ + gen_op_calc_cc(s); + + /* trigger exception */ + tmp = tcg_const_i32(EXCP_PGM); + gen_helper_exception(tmp); + tcg_temp_free_i32(tmp); + + /* end TB here */ + s->is_jmp = DISAS_EXCP; +} + + +static void gen_illegal_opcode(DisasContext *s, int ilc) +{ + gen_program_exception(s, ilc, PGM_SPECIFICATION); +} + +static void gen_privileged_exception(DisasContext *s, int ilc) +{ + gen_program_exception(s, ilc, PGM_PRIVILEGED); +} + +static void check_privileged(DisasContext *s, int ilc) +{ + if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) { + gen_privileged_exception(s, ilc); + } +} + +#endif /* CONFIG_USER_ONLY */ + +static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2) +{ + TCGv_i64 tmp; + + /* 31-bitify the immediate part; register contents are dealt with below */ + if (!(s->tb->flags & FLAG_MASK_64)) { + d2 &= 0x7fffffffUL; + } + + if (x2) { + if (d2) { + tmp = tcg_const_i64(d2); + tcg_gen_add_i64(tmp, tmp, regs[x2]); + } else { + tmp = load_reg(x2); + } + if (b2) { + tcg_gen_add_i64(tmp, tmp, regs[b2]); + } + } else if (b2) { + if (d2) { + tmp = tcg_const_i64(d2); + tcg_gen_add_i64(tmp, tmp, regs[b2]); + } else { + tmp = load_reg(b2); + } + } else { + tmp = tcg_const_i64(d2); + } + + /* 31-bit mode mask if there are values loaded from registers */ + if (!(s->tb->flags & FLAG_MASK_64) && (x2 || b2)) { + tcg_gen_andi_i64(tmp, tmp, 0x7fffffffUL); + } + + return tmp; +} + +static void gen_op_movi_cc(DisasContext *s, uint32_t val) +{ + s->cc_op = CC_OP_CONST0 + val; +} + +static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst) +{ + tcg_gen_discard_i64(cc_src); + tcg_gen_mov_i64(cc_dst, dst); + tcg_gen_discard_i64(cc_vr); + s->cc_op = op; +} + +static void gen_op_update1_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 dst) +{ + tcg_gen_discard_i64(cc_src); + tcg_gen_extu_i32_i64(cc_dst, dst); + tcg_gen_discard_i64(cc_vr); + s->cc_op = op; +} + +static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src, + TCGv_i64 dst) +{ + tcg_gen_mov_i64(cc_src, src); + tcg_gen_mov_i64(cc_dst, dst); + tcg_gen_discard_i64(cc_vr); + s->cc_op = op; +} + +static void gen_op_update2_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 src, + TCGv_i32 dst) +{ + tcg_gen_extu_i32_i64(cc_src, src); + tcg_gen_extu_i32_i64(cc_dst, dst); + tcg_gen_discard_i64(cc_vr); + s->cc_op = op; +} + +static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src, + TCGv_i64 dst, TCGv_i64 vr) +{ + tcg_gen_mov_i64(cc_src, src); + tcg_gen_mov_i64(cc_dst, dst); + tcg_gen_mov_i64(cc_vr, vr); + s->cc_op = op; +} + +static void gen_op_update3_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 src, + TCGv_i32 dst, TCGv_i32 vr) +{ + tcg_gen_extu_i32_i64(cc_src, src); + tcg_gen_extu_i32_i64(cc_dst, dst); + tcg_gen_extu_i32_i64(cc_vr, vr); + s->cc_op = op; +} + +static inline void set_cc_nz_u32(DisasContext *s, TCGv_i32 val) +{ + gen_op_update1_cc_i32(s, CC_OP_NZ, val); +} + +static inline void set_cc_nz_u64(DisasContext *s, TCGv_i64 val) +{ + gen_op_update1_cc_i64(s, CC_OP_NZ, val); +} + +static inline void cmp_32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, + enum cc_op cond) +{ + gen_op_update2_cc_i32(s, cond, v1, v2); +} + +static inline void cmp_64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2, + enum cc_op cond) +{ + gen_op_update2_cc_i64(s, cond, v1, v2); +} + +static inline void cmp_s32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2) +{ + cmp_32(s, v1, v2, CC_OP_LTGT_32); +} + +static inline void cmp_u32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2) +{ + cmp_32(s, v1, v2, CC_OP_LTUGTU_32); +} + +static inline void cmp_s32c(DisasContext *s, TCGv_i32 v1, int32_t v2) +{ + /* XXX optimize for the constant? put it in s? */ + TCGv_i32 tmp = tcg_const_i32(v2); + cmp_32(s, v1, tmp, CC_OP_LTGT_32); + tcg_temp_free_i32(tmp); +} + +static inline void cmp_u32c(DisasContext *s, TCGv_i32 v1, uint32_t v2) +{ + TCGv_i32 tmp = tcg_const_i32(v2); + cmp_32(s, v1, tmp, CC_OP_LTUGTU_32); + tcg_temp_free_i32(tmp); +} + +static inline void cmp_s64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2) +{ + cmp_64(s, v1, v2, CC_OP_LTGT_64); +} + +static inline void cmp_u64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2) +{ + cmp_64(s, v1, v2, CC_OP_LTUGTU_64); +} + +static inline void cmp_s64c(DisasContext *s, TCGv_i64 v1, int64_t v2) +{ + TCGv_i64 tmp = tcg_const_i64(v2); + cmp_s64(s, v1, tmp); + tcg_temp_free_i64(tmp); +} + +static inline void cmp_u64c(DisasContext *s, TCGv_i64 v1, uint64_t v2) +{ + TCGv_i64 tmp = tcg_const_i64(v2); + cmp_u64(s, v1, tmp); + tcg_temp_free_i64(tmp); +} + +static inline void set_cc_s32(DisasContext *s, TCGv_i32 val) +{ + gen_op_update1_cc_i32(s, CC_OP_LTGT0_32, val); +} + +static inline void set_cc_s64(DisasContext *s, TCGv_i64 val) +{ + gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, val); +} + +static void set_cc_add64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2, TCGv_i64 vr) +{ + gen_op_update3_cc_i64(s, CC_OP_ADD_64, v1, v2, vr); +} + +static void set_cc_addu64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2, + TCGv_i64 vr) +{ + gen_op_update3_cc_i64(s, CC_OP_ADDU_64, v1, v2, vr); +} + +static void set_cc_sub64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2, TCGv_i64 vr) +{ + gen_op_update3_cc_i64(s, CC_OP_SUB_64, v1, v2, vr); +} + +static void set_cc_subu64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2, + TCGv_i64 vr) +{ + gen_op_update3_cc_i64(s, CC_OP_SUBU_64, v1, v2, vr); +} + +static void set_cc_abs64(DisasContext *s, TCGv_i64 v1) +{ + gen_op_update1_cc_i64(s, CC_OP_ABS_64, v1); +} + +static void set_cc_nabs64(DisasContext *s, TCGv_i64 v1) +{ + gen_op_update1_cc_i64(s, CC_OP_NABS_64, v1); +} + +static void set_cc_add32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, TCGv_i32 vr) +{ + gen_op_update3_cc_i32(s, CC_OP_ADD_32, v1, v2, vr); +} + +static void set_cc_addu32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, + TCGv_i32 vr) +{ + gen_op_update3_cc_i32(s, CC_OP_ADDU_32, v1, v2, vr); +} + +static void set_cc_sub32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, TCGv_i32 vr) +{ + gen_op_update3_cc_i32(s, CC_OP_SUB_32, v1, v2, vr); +} + +static void set_cc_subu32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, + TCGv_i32 vr) +{ + gen_op_update3_cc_i32(s, CC_OP_SUBU_32, v1, v2, vr); +} + +static void set_cc_abs32(DisasContext *s, TCGv_i32 v1) +{ + gen_op_update1_cc_i32(s, CC_OP_ABS_32, v1); +} + +static void set_cc_nabs32(DisasContext *s, TCGv_i32 v1) +{ + gen_op_update1_cc_i32(s, CC_OP_NABS_32, v1); +} + +static void set_cc_comp32(DisasContext *s, TCGv_i32 v1) +{ + gen_op_update1_cc_i32(s, CC_OP_COMP_32, v1); +} + +static void set_cc_comp64(DisasContext *s, TCGv_i64 v1) +{ + gen_op_update1_cc_i64(s, CC_OP_COMP_64, v1); +} + +static void set_cc_icm(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2) +{ + gen_op_update2_cc_i32(s, CC_OP_ICM, v1, v2); +} + +static void set_cc_cmp_f32_i64(DisasContext *s, TCGv_i32 v1, TCGv_i64 v2) +{ + tcg_gen_extu_i32_i64(cc_src, v1); + tcg_gen_mov_i64(cc_dst, v2); + tcg_gen_discard_i64(cc_vr); + s->cc_op = CC_OP_LTGT_F32; +} + +static void set_cc_nz_f32(DisasContext *s, TCGv_i32 v1) +{ + gen_op_update1_cc_i32(s, CC_OP_NZ_F32, v1); +} + +static inline void set_cc_nz_f64(DisasContext *s, TCGv_i64 v1) +{ + gen_op_update1_cc_i64(s, CC_OP_NZ_F64, v1); +} + +/* CC value is in env->cc_op */ +static inline void set_cc_static(DisasContext *s) +{ + tcg_gen_discard_i64(cc_src); + tcg_gen_discard_i64(cc_dst); + tcg_gen_discard_i64(cc_vr); + s->cc_op = CC_OP_STATIC; +} + +static inline void gen_op_set_cc_op(DisasContext *s) +{ + if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) { + tcg_gen_movi_i32(cc_op, s->cc_op); + } +} + +static inline void gen_update_cc_op(DisasContext *s) +{ + gen_op_set_cc_op(s); +} + +/* calculates cc into cc_op */ +static void gen_op_calc_cc(DisasContext *s) +{ + TCGv_i32 local_cc_op = tcg_const_i32(s->cc_op); + TCGv_i64 dummy = tcg_const_i64(0); + + switch (s->cc_op) { + case CC_OP_CONST0: + case CC_OP_CONST1: + case CC_OP_CONST2: + case CC_OP_CONST3: + /* s->cc_op is the cc value */ + tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0); + break; + case CC_OP_STATIC: + /* env->cc_op already is the cc value */ + break; + case CC_OP_NZ: + case CC_OP_ABS_64: + case CC_OP_NABS_64: + case CC_OP_ABS_32: + case CC_OP_NABS_32: + case CC_OP_LTGT0_32: + case CC_OP_LTGT0_64: + case CC_OP_COMP_32: + case CC_OP_COMP_64: + case CC_OP_NZ_F32: + case CC_OP_NZ_F64: + /* 1 argument */ + gen_helper_calc_cc(cc_op, local_cc_op, dummy, cc_dst, dummy); + break; + case CC_OP_ICM: + case CC_OP_LTGT_32: + case CC_OP_LTGT_64: + case CC_OP_LTUGTU_32: + case CC_OP_LTUGTU_64: + case CC_OP_TM_32: + case CC_OP_TM_64: + case CC_OP_LTGT_F32: + case CC_OP_LTGT_F64: + case CC_OP_SLAG: + /* 2 arguments */ + gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, dummy); + break; + case CC_OP_ADD_64: + case CC_OP_ADDU_64: + case CC_OP_SUB_64: + case CC_OP_SUBU_64: + case CC_OP_ADD_32: + case CC_OP_ADDU_32: + case CC_OP_SUB_32: + case CC_OP_SUBU_32: + /* 3 arguments */ + gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, cc_vr); + break; + case CC_OP_DYNAMIC: + /* unknown operation - assume 3 arguments and cc_op in env */ + gen_helper_calc_cc(cc_op, cc_op, cc_src, cc_dst, cc_vr); + break; + default: + tcg_abort(); + } + + tcg_temp_free_i32(local_cc_op); + + /* We now have cc in cc_op as constant */ + set_cc_static(s); +} + +static inline void decode_rr(DisasContext *s, uint64_t insn, int *r1, int *r2) +{ + debug_insn(insn); + + *r1 = (insn >> 4) & 0xf; + *r2 = insn & 0xf; +} + +static inline TCGv_i64 decode_rx(DisasContext *s, uint64_t insn, int *r1, + int *x2, int *b2, int *d2) +{ + debug_insn(insn); + + *r1 = (insn >> 20) & 0xf; + *x2 = (insn >> 16) & 0xf; + *b2 = (insn >> 12) & 0xf; + *d2 = insn & 0xfff; + + return get_address(s, *x2, *b2, *d2); +} + +static inline void decode_rs(DisasContext *s, uint64_t insn, int *r1, int *r3, + int *b2, int *d2) +{ + debug_insn(insn); + + *r1 = (insn >> 20) & 0xf; + /* aka m3 */ + *r3 = (insn >> 16) & 0xf; + *b2 = (insn >> 12) & 0xf; + *d2 = insn & 0xfff; +} + +static inline TCGv_i64 decode_si(DisasContext *s, uint64_t insn, int *i2, + int *b1, int *d1) +{ + debug_insn(insn); + + *i2 = (insn >> 16) & 0xff; + *b1 = (insn >> 12) & 0xf; + *d1 = insn & 0xfff; + + return get_address(s, 0, *b1, *d1); +} + +static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc) +{ + TranslationBlock *tb; + + gen_update_cc_op(s); + + tb = s->tb; + /* NOTE: we handle the case where the TB spans two pages here */ + if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || + (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { + /* jump to same page: we can use a direct jump */ + tcg_gen_goto_tb(tb_num); + tcg_gen_movi_i64(psw_addr, pc); + tcg_gen_exit_tb((tcg_target_long)tb + tb_num); + } else { + /* jump to another page: currently not optimized */ + tcg_gen_movi_i64(psw_addr, pc); + tcg_gen_exit_tb(0); + } +} + +static inline void account_noninline_branch(DisasContext *s, int cc_op) +{ +#ifdef DEBUG_INLINE_BRANCHES + inline_branch_miss[cc_op]++; +#endif +} + +static inline void account_inline_branch(DisasContext *s) +{ +#ifdef DEBUG_INLINE_BRANCHES + inline_branch_hit[s->cc_op]++; +#endif +} + +static void gen_jcc(DisasContext *s, uint32_t mask, int skip) +{ + TCGv_i32 tmp, tmp2, r; + TCGv_i64 tmp64; + int old_cc_op; + + switch (s->cc_op) { + case CC_OP_LTGT0_32: + tmp = tcg_temp_new_i32(); + tcg_gen_trunc_i64_i32(tmp, cc_dst); + switch (mask) { + case 0x8 | 0x4: /* dst <= 0 */ + tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, skip); + break; + case 0x8 | 0x2: /* dst >= 0 */ + tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, skip); + break; + case 0x8: /* dst == 0 */ + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, skip); + break; + case 0x7: /* dst != 0 */ + case 0x6: /* dst != 0 */ + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip); + break; + case 0x4: /* dst < 0 */ + tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, skip); + break; + case 0x2: /* dst > 0 */ + tcg_gen_brcondi_i32(TCG_COND_LE, tmp, 0, skip); + break; + default: + tcg_temp_free_i32(tmp); + goto do_dynamic; + } + account_inline_branch(s); + tcg_temp_free_i32(tmp); + break; + case CC_OP_LTGT0_64: + switch (mask) { + case 0x8 | 0x4: /* dst <= 0 */ + tcg_gen_brcondi_i64(TCG_COND_GT, cc_dst, 0, skip); + break; + case 0x8 | 0x2: /* dst >= 0 */ + tcg_gen_brcondi_i64(TCG_COND_LT, cc_dst, 0, skip); + break; + case 0x8: /* dst == 0 */ + tcg_gen_brcondi_i64(TCG_COND_NE, cc_dst, 0, skip); + break; + case 0x7: /* dst != 0 */ + case 0x6: /* dst != 0 */ + tcg_gen_brcondi_i64(TCG_COND_EQ, cc_dst, 0, skip); + break; + case 0x4: /* dst < 0 */ + tcg_gen_brcondi_i64(TCG_COND_GE, cc_dst, 0, skip); + break; + case 0x2: /* dst > 0 */ + tcg_gen_brcondi_i64(TCG_COND_LE, cc_dst, 0, skip); + break; + default: + goto do_dynamic; + } + account_inline_branch(s); + break; + case CC_OP_LTGT_32: + tmp = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i32(); + tcg_gen_trunc_i64_i32(tmp, cc_src); + tcg_gen_trunc_i64_i32(tmp2, cc_dst); + switch (mask) { + case 0x8 | 0x4: /* src <= dst */ + tcg_gen_brcond_i32(TCG_COND_GT, tmp, tmp2, skip); + break; + case 0x8 | 0x2: /* src >= dst */ + tcg_gen_brcond_i32(TCG_COND_LT, tmp, tmp2, skip); + break; + case 0x8: /* src == dst */ + tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, skip); + break; + case 0x7: /* src != dst */ + case 0x6: /* src != dst */ + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, skip); + break; + case 0x4: /* src < dst */ + tcg_gen_brcond_i32(TCG_COND_GE, tmp, tmp2, skip); + break; + case 0x2: /* src > dst */ + tcg_gen_brcond_i32(TCG_COND_LE, tmp, tmp2, skip); + break; + default: + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + goto do_dynamic; + } + account_inline_branch(s); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + break; + case CC_OP_LTGT_64: + switch (mask) { + case 0x8 | 0x4: /* src <= dst */ + tcg_gen_brcond_i64(TCG_COND_GT, cc_src, cc_dst, skip); + break; + case 0x8 | 0x2: /* src >= dst */ + tcg_gen_brcond_i64(TCG_COND_LT, cc_src, cc_dst, skip); + break; + case 0x8: /* src == dst */ + tcg_gen_brcond_i64(TCG_COND_NE, cc_src, cc_dst, skip); + break; + case 0x7: /* src != dst */ + case 0x6: /* src != dst */ + tcg_gen_brcond_i64(TCG_COND_EQ, cc_src, cc_dst, skip); + break; + case 0x4: /* src < dst */ + tcg_gen_brcond_i64(TCG_COND_GE, cc_src, cc_dst, skip); + break; + case 0x2: /* src > dst */ + tcg_gen_brcond_i64(TCG_COND_LE, cc_src, cc_dst, skip); + break; + default: + goto do_dynamic; + } + account_inline_branch(s); + break; + case CC_OP_LTUGTU_32: + tmp = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i32(); + tcg_gen_trunc_i64_i32(tmp, cc_src); + tcg_gen_trunc_i64_i32(tmp2, cc_dst); + switch (mask) { + case 0x8 | 0x4: /* src <= dst */ + tcg_gen_brcond_i32(TCG_COND_GTU, tmp, tmp2, skip); + break; + case 0x8 | 0x2: /* src >= dst */ + tcg_gen_brcond_i32(TCG_COND_LTU, tmp, tmp2, skip); + break; + case 0x8: /* src == dst */ + tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, skip); + break; + case 0x7: /* src != dst */ + case 0x6: /* src != dst */ + tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, skip); + break; + case 0x4: /* src < dst */ + tcg_gen_brcond_i32(TCG_COND_GEU, tmp, tmp2, skip); + break; + case 0x2: /* src > dst */ + tcg_gen_brcond_i32(TCG_COND_LEU, tmp, tmp2, skip); + break; + default: + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + goto do_dynamic; + } + account_inline_branch(s); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + break; + case CC_OP_LTUGTU_64: + switch (mask) { + case 0x8 | 0x4: /* src <= dst */ + tcg_gen_brcond_i64(TCG_COND_GTU, cc_src, cc_dst, skip); + break; + case 0x8 | 0x2: /* src >= dst */ + tcg_gen_brcond_i64(TCG_COND_LTU, cc_src, cc_dst, skip); + break; + case 0x8: /* src == dst */ + tcg_gen_brcond_i64(TCG_COND_NE, cc_src, cc_dst, skip); + break; + case 0x7: /* src != dst */ + case 0x6: /* src != dst */ + tcg_gen_brcond_i64(TCG_COND_EQ, cc_src, cc_dst, skip); + break; + case 0x4: /* src < dst */ + tcg_gen_brcond_i64(TCG_COND_GEU, cc_src, cc_dst, skip); + break; + case 0x2: /* src > dst */ + tcg_gen_brcond_i64(TCG_COND_LEU, cc_src, cc_dst, skip); + break; + default: + goto do_dynamic; + } + account_inline_branch(s); + break; + case CC_OP_NZ: + switch (mask) { + /* dst == 0 || dst != 0 */ + case 0x8 | 0x4: + case 0x8 | 0x4 | 0x2: + case 0x8 | 0x4 | 0x2 | 0x1: + case 0x8 | 0x4 | 0x1: + break; + /* dst == 0 */ + case 0x8: + case 0x8 | 0x2: + case 0x8 | 0x2 | 0x1: + case 0x8 | 0x1: + tcg_gen_brcondi_i64(TCG_COND_NE, cc_dst, 0, skip); + break; + /* dst != 0 */ + case 0x4: + case 0x4 | 0x2: + case 0x4 | 0x2 | 0x1: + case 0x4 | 0x1: + tcg_gen_brcondi_i64(TCG_COND_EQ, cc_dst, 0, skip); + break; + default: + goto do_dynamic; + } + account_inline_branch(s); + break; + case CC_OP_TM_32: + tmp = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i32(); + + tcg_gen_trunc_i64_i32(tmp, cc_src); + tcg_gen_trunc_i64_i32(tmp2, cc_dst); + tcg_gen_and_i32(tmp, tmp, tmp2); + switch (mask) { + case 0x8: /* val & mask == 0 */ + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, skip); + break; + case 0x4 | 0x2 | 0x1: /* val & mask != 0 */ + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip); + break; + default: + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + goto do_dynamic; + } + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + account_inline_branch(s); + break; + case CC_OP_TM_64: + tmp64 = tcg_temp_new_i64(); + + tcg_gen_and_i64(tmp64, cc_src, cc_dst); + switch (mask) { + case 0x8: /* val & mask == 0 */ + tcg_gen_brcondi_i64(TCG_COND_NE, tmp64, 0, skip); + break; + case 0x4 | 0x2 | 0x1: /* val & mask != 0 */ + tcg_gen_brcondi_i64(TCG_COND_EQ, tmp64, 0, skip); + break; + default: + tcg_temp_free_i64(tmp64); + goto do_dynamic; + } + tcg_temp_free_i64(tmp64); + account_inline_branch(s); + break; + case CC_OP_ICM: + switch (mask) { + case 0x8: /* val == 0 */ + tcg_gen_brcondi_i64(TCG_COND_NE, cc_dst, 0, skip); + break; + case 0x4 | 0x2 | 0x1: /* val != 0 */ + case 0x4 | 0x2: /* val != 0 */ + tcg_gen_brcondi_i64(TCG_COND_EQ, cc_dst, 0, skip); + break; + default: + goto do_dynamic; + } + account_inline_branch(s); + break; + case CC_OP_STATIC: + old_cc_op = s->cc_op; + goto do_dynamic_nocccalc; + case CC_OP_DYNAMIC: + default: +do_dynamic: + old_cc_op = s->cc_op; + /* calculate cc value */ + gen_op_calc_cc(s); + +do_dynamic_nocccalc: + /* jump based on cc */ + account_noninline_branch(s, old_cc_op); + + switch (mask) { + case 0x8 | 0x4 | 0x2 | 0x1: + /* always true */ + break; + case 0x8 | 0x4 | 0x2: /* cc != 3 */ + tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 3, skip); + break; + case 0x8 | 0x4 | 0x1: /* cc != 2 */ + tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 2, skip); + break; + case 0x8 | 0x2 | 0x1: /* cc != 1 */ + tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 1, skip); + break; + case 0x8 | 0x2: /* cc == 0 || cc == 2 */ + tmp = tcg_temp_new_i32(); + tcg_gen_andi_i32(tmp, cc_op, 1); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, skip); + tcg_temp_free_i32(tmp); + break; + case 0x8 | 0x4: /* cc < 2 */ + tcg_gen_brcondi_i32(TCG_COND_GEU, cc_op, 2, skip); + break; + case 0x8: /* cc == 0 */ + tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 0, skip); + break; + case 0x4 | 0x2 | 0x1: /* cc != 0 */ + tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 0, skip); + break; + case 0x4 | 0x1: /* cc == 1 || cc == 3 */ + tmp = tcg_temp_new_i32(); + tcg_gen_andi_i32(tmp, cc_op, 1); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip); + tcg_temp_free_i32(tmp); + break; + case 0x4: /* cc == 1 */ + tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 1, skip); + break; + case 0x2 | 0x1: /* cc > 1 */ + tcg_gen_brcondi_i32(TCG_COND_LEU, cc_op, 1, skip); + break; + case 0x2: /* cc == 2 */ + tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 2, skip); + break; + case 0x1: /* cc == 3 */ + tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 3, skip); + break; + default: /* cc is masked by something else */ + tmp = tcg_const_i32(3); + /* 3 - cc */ + tcg_gen_sub_i32(tmp, tmp, cc_op); + tmp2 = tcg_const_i32(1); + /* 1 << (3 - cc) */ + tcg_gen_shl_i32(tmp2, tmp2, tmp); + r = tcg_const_i32(mask); + /* mask & (1 << (3 - cc)) */ + tcg_gen_and_i32(r, r, tmp2); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + + tcg_gen_brcondi_i32(TCG_COND_EQ, r, 0, skip); + tcg_temp_free_i32(r); + break; + } + break; + } +} + +static void gen_bcr(DisasContext *s, uint32_t mask, TCGv_i64 target, + uint64_t offset) +{ + int skip; + + if (mask == 0xf) { + /* unconditional */ + tcg_gen_mov_i64(psw_addr, target); + tcg_gen_exit_tb(0); + } else if (mask == 0) { + /* ignore cc and never match */ + gen_goto_tb(s, 0, offset + 2); + } else { + TCGv_i64 new_addr = tcg_temp_local_new_i64(); + + tcg_gen_mov_i64(new_addr, target); + skip = gen_new_label(); + gen_jcc(s, mask, skip); + tcg_gen_mov_i64(psw_addr, new_addr); + tcg_temp_free_i64(new_addr); + tcg_gen_exit_tb(0); + gen_set_label(skip); + tcg_temp_free_i64(new_addr); + gen_goto_tb(s, 1, offset + 2); + } +} + +static void gen_brc(uint32_t mask, DisasContext *s, int32_t offset) +{ + int skip; + + if (mask == 0xf) { + /* unconditional */ + gen_goto_tb(s, 0, s->pc + offset); + } else if (mask == 0) { + /* ignore cc and never match */ + gen_goto_tb(s, 0, s->pc + 4); + } else { + skip = gen_new_label(); + gen_jcc(s, mask, skip); + gen_goto_tb(s, 0, s->pc + offset); + gen_set_label(skip); + gen_goto_tb(s, 1, s->pc + 4); + } + s->is_jmp = DISAS_TB_JUMP; +} + +static void gen_op_mvc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2) +{ + TCGv_i64 tmp, tmp2; + int i; + int l_memset = gen_new_label(); + int l_out = gen_new_label(); + TCGv_i64 dest = tcg_temp_local_new_i64(); + TCGv_i64 src = tcg_temp_local_new_i64(); + TCGv_i32 vl; + + /* Find out if we should use the inline version of mvc */ + switch (l) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 11: + case 15: + /* use inline */ + break; + default: + /* Fall back to helper */ + vl = tcg_const_i32(l); + potential_page_fault(s); + gen_helper_mvc(vl, s1, s2); + tcg_temp_free_i32(vl); + return; + } + + tcg_gen_mov_i64(dest, s1); + tcg_gen_mov_i64(src, s2); + + if (!(s->tb->flags & FLAG_MASK_64)) { + /* XXX what if we overflow while moving? */ + tcg_gen_andi_i64(dest, dest, 0x7fffffffUL); + tcg_gen_andi_i64(src, src, 0x7fffffffUL); + } + + tmp = tcg_temp_new_i64(); + tcg_gen_addi_i64(tmp, src, 1); + tcg_gen_brcond_i64(TCG_COND_EQ, dest, tmp, l_memset); + tcg_temp_free_i64(tmp); + + switch (l) { + case 0: + tmp = tcg_temp_new_i64(); + + tcg_gen_qemu_ld8u(tmp, src, get_mem_index(s)); + tcg_gen_qemu_st8(tmp, dest, get_mem_index(s)); + + tcg_temp_free_i64(tmp); + break; + case 1: + tmp = tcg_temp_new_i64(); + + tcg_gen_qemu_ld16u(tmp, src, get_mem_index(s)); + tcg_gen_qemu_st16(tmp, dest, get_mem_index(s)); + + tcg_temp_free_i64(tmp); + break; + case 3: + tmp = tcg_temp_new_i64(); + + tcg_gen_qemu_ld32u(tmp, src, get_mem_index(s)); + tcg_gen_qemu_st32(tmp, dest, get_mem_index(s)); + + tcg_temp_free_i64(tmp); + break; + case 4: + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); + + tcg_gen_qemu_ld32u(tmp, src, get_mem_index(s)); + tcg_gen_addi_i64(src, src, 4); + tcg_gen_qemu_ld8u(tmp2, src, get_mem_index(s)); + tcg_gen_qemu_st32(tmp, dest, get_mem_index(s)); + tcg_gen_addi_i64(dest, dest, 4); + tcg_gen_qemu_st8(tmp2, dest, get_mem_index(s)); + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 7: + tmp = tcg_temp_new_i64(); + + tcg_gen_qemu_ld64(tmp, src, get_mem_index(s)); + tcg_gen_qemu_st64(tmp, dest, get_mem_index(s)); + + tcg_temp_free_i64(tmp); + break; + default: + /* The inline version can become too big for too uneven numbers, only + use it on known good lengths */ + tmp = tcg_temp_new_i64(); + tmp2 = tcg_const_i64(8); + for (i = 0; (i + 7) <= l; i += 8) { + tcg_gen_qemu_ld64(tmp, src, get_mem_index(s)); + tcg_gen_qemu_st64(tmp, dest, get_mem_index(s)); + + tcg_gen_add_i64(src, src, tmp2); + tcg_gen_add_i64(dest, dest, tmp2); + } + + tcg_temp_free_i64(tmp2); + tmp2 = tcg_const_i64(1); + + for (; i <= l; i++) { + tcg_gen_qemu_ld8u(tmp, src, get_mem_index(s)); + tcg_gen_qemu_st8(tmp, dest, get_mem_index(s)); + + tcg_gen_add_i64(src, src, tmp2); + tcg_gen_add_i64(dest, dest, tmp2); + } + + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp); + break; + } + + tcg_gen_br(l_out); + + gen_set_label(l_memset); + /* memset case (dest == (src + 1)) */ + + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); + /* fill tmp with the byte */ + tcg_gen_qemu_ld8u(tmp, src, get_mem_index(s)); + tcg_gen_shli_i64(tmp2, tmp, 8); + tcg_gen_or_i64(tmp, tmp, tmp2); + tcg_gen_shli_i64(tmp2, tmp, 16); + tcg_gen_or_i64(tmp, tmp, tmp2); + tcg_gen_shli_i64(tmp2, tmp, 32); + tcg_gen_or_i64(tmp, tmp, tmp2); + tcg_temp_free_i64(tmp2); + + tmp2 = tcg_const_i64(8); + + for (i = 0; (i + 7) <= l; i += 8) { + tcg_gen_qemu_st64(tmp, dest, get_mem_index(s)); + tcg_gen_addi_i64(dest, dest, 8); + } + + tcg_temp_free_i64(tmp2); + tmp2 = tcg_const_i64(1); + + for (; i <= l; i++) { + tcg_gen_qemu_st8(tmp, dest, get_mem_index(s)); + tcg_gen_addi_i64(dest, dest, 1); + } + + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp); + + gen_set_label(l_out); + + tcg_temp_free(dest); + tcg_temp_free(src); +} + +static void gen_op_clc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2) +{ + TCGv_i64 tmp; + TCGv_i64 tmp2; + TCGv_i32 vl; + + /* check for simple 32bit or 64bit match */ + switch (l) { + case 0: + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); + + tcg_gen_qemu_ld8u(tmp, s1, get_mem_index(s)); + tcg_gen_qemu_ld8u(tmp2, s2, get_mem_index(s)); + cmp_u64(s, tmp, tmp2); + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + return; + case 1: + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); + + tcg_gen_qemu_ld16u(tmp, s1, get_mem_index(s)); + tcg_gen_qemu_ld16u(tmp2, s2, get_mem_index(s)); + cmp_u64(s, tmp, tmp2); + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + return; + case 3: + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); + + tcg_gen_qemu_ld32u(tmp, s1, get_mem_index(s)); + tcg_gen_qemu_ld32u(tmp2, s2, get_mem_index(s)); + cmp_u64(s, tmp, tmp2); + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + return; + case 7: + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); + + tcg_gen_qemu_ld64(tmp, s1, get_mem_index(s)); + tcg_gen_qemu_ld64(tmp2, s2, get_mem_index(s)); + cmp_u64(s, tmp, tmp2); + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + return; + } + + potential_page_fault(s); + vl = tcg_const_i32(l); + gen_helper_clc(cc_op, vl, s1, s2); + tcg_temp_free_i32(vl); + set_cc_static(s); +} + +static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2) +{ + TCGv_i64 addr, tmp, tmp2, tmp3, tmp4; + TCGv_i32 tmp32_1, tmp32_2, tmp32_3; + + LOG_DISAS("disas_e3: op 0x%x r1 %d x2 %d b2 %d d2 %d\n", + op, r1, x2, b2, d2); + addr = get_address(s, x2, b2, d2); + switch (op) { + case 0x2: /* LTG R1,D2(X2,B2) [RXY] */ + case 0x4: /* lg r1,d2(x2,b2) */ + tcg_gen_qemu_ld64(regs[r1], addr, get_mem_index(s)); + if (op == 0x2) { + set_cc_s64(s, regs[r1]); + } + break; + case 0x12: /* LT R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + store_reg32(r1, tmp32_1); + set_cc_s32(s, tmp32_1); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0xc: /* MSG R1,D2(X2,B2) [RXY] */ + case 0x1c: /* MSGF R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + if (op == 0xc) { + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + } else { + tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s)); + } + tcg_gen_mul_i64(regs[r1], regs[r1], tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0xd: /* DSG R1,D2(X2,B2) [RXY] */ + case 0x1d: /* DSGF R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + if (op == 0x1d) { + tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s)); + } else { + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + } + tmp4 = load_reg(r1 + 1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_div_i64(tmp3, tmp4, tmp2); + store_reg(r1 + 1, tmp3); + tcg_gen_rem_i64(tmp3, tmp4, tmp2); + store_reg(r1, tmp3); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + tcg_temp_free_i64(tmp4); + break; + case 0x8: /* AG R1,D2(X2,B2) [RXY] */ + case 0xa: /* ALG R1,D2(X2,B2) [RXY] */ + case 0x18: /* AGF R1,D2(X2,B2) [RXY] */ + case 0x1a: /* ALGF R1,D2(X2,B2) [RXY] */ + if (op == 0x1a) { + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + } else if (op == 0x18) { + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s)); + } else { + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + } + tmp4 = load_reg(r1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_add_i64(tmp3, tmp4, tmp2); + store_reg(r1, tmp3); + switch (op) { + case 0x8: + case 0x18: + set_cc_add64(s, tmp4, tmp2, tmp3); + break; + case 0xa: + case 0x1a: + set_cc_addu64(s, tmp4, tmp2, tmp3); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + tcg_temp_free_i64(tmp4); + break; + case 0x9: /* SG R1,D2(X2,B2) [RXY] */ + case 0xb: /* SLG R1,D2(X2,B2) [RXY] */ + case 0x19: /* SGF R1,D2(X2,B2) [RXY] */ + case 0x1b: /* SLGF R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + if (op == 0x19) { + tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s)); + } else if (op == 0x1b) { + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + } else { + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + } + tmp4 = load_reg(r1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_sub_i64(tmp3, tmp4, tmp2); + store_reg(r1, tmp3); + switch (op) { + case 0x9: + case 0x19: + set_cc_sub64(s, tmp4, tmp2, tmp3); + break; + case 0xb: + case 0x1b: + set_cc_subu64(s, tmp4, tmp2, tmp3); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + tcg_temp_free_i64(tmp4); + break; + case 0xf: /* LRVG R1,D2(X2,B2) [RXE] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + tcg_gen_bswap64_i64(tmp2, tmp2); + store_reg(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x14: /* LGF R1,D2(X2,B2) [RXY] */ + case 0x16: /* LLGF R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + if (op == 0x14) { + tcg_gen_ext32s_i64(tmp2, tmp2); + } + store_reg(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x15: /* LGH R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s)); + store_reg(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x17: /* LLGT R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + tcg_gen_andi_i64(tmp2, tmp2, 0x7fffffffULL); + store_reg(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x1e: /* LRV R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + tcg_temp_free_i64(tmp2); + tcg_gen_bswap32_i32(tmp32_1, tmp32_1); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x1f: /* LRVH R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_qemu_ld16u(tmp2, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + tcg_temp_free_i64(tmp2); + tcg_gen_bswap16_i32(tmp32_1, tmp32_1); + store_reg16(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x20: /* CG R1,D2(X2,B2) [RXY] */ + case 0x21: /* CLG R1,D2(X2,B2) */ + case 0x30: /* CGF R1,D2(X2,B2) [RXY] */ + case 0x31: /* CLGF R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + switch (op) { + case 0x20: + case 0x21: + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + break; + case 0x30: + tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s)); + break; + case 0x31: + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + break; + default: + tcg_abort(); + } + switch (op) { + case 0x20: + case 0x30: + cmp_s64(s, regs[r1], tmp2); + break; + case 0x21: + case 0x31: + cmp_u64(s, regs[r1], tmp2); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp2); + break; + case 0x24: /* stg r1, d2(x2,b2) */ + tcg_gen_qemu_st64(regs[r1], addr, get_mem_index(s)); + break; + case 0x3e: /* STRV R1,D2(X2,B2) [RXY] */ + tmp32_1 = load_reg32(r1); + tmp2 = tcg_temp_new_i64(); + tcg_gen_bswap32_i32(tmp32_1, tmp32_1); + tcg_gen_extu_i32_i64(tmp2, tmp32_1); + tcg_temp_free_i32(tmp32_1); + tcg_gen_qemu_st32(tmp2, addr, get_mem_index(s)); + tcg_temp_free_i64(tmp2); + break; + case 0x50: /* STY R1,D2(X2,B2) [RXY] */ + tmp32_1 = load_reg32(r1); + tmp2 = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(tmp2, tmp32_1); + tcg_temp_free_i32(tmp32_1); + tcg_gen_qemu_st32(tmp2, addr, get_mem_index(s)); + tcg_temp_free_i64(tmp2); + break; + case 0x57: /* XY R1,D2(X2,B2) [RXY] */ + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + tcg_temp_free_i64(tmp2); + tcg_gen_xor_i32(tmp32_2, tmp32_1, tmp32_2); + store_reg32(r1, tmp32_2); + set_cc_nz_u32(s, tmp32_2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x58: /* LY R1,D2(X2,B2) [RXY] */ + tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp3, addr, get_mem_index(s)); + store_reg32_i64(r1, tmp3); + tcg_temp_free_i64(tmp3); + break; + case 0x5a: /* AY R1,D2(X2,B2) [RXY] */ + case 0x5b: /* SY R1,D2(X2,B2) [RXY] */ + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp32_3 = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + tcg_temp_free_i64(tmp2); + switch (op) { + case 0x5a: + tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2); + break; + case 0x5b: + tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2); + break; + default: + tcg_abort(); + } + store_reg32(r1, tmp32_3); + switch (op) { + case 0x5a: + set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x5b: + set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3); + break; + default: + tcg_abort(); + } + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x71: /* LAY R1,D2(X2,B2) [RXY] */ + store_reg(r1, addr); + break; + case 0x72: /* STCY R1,D2(X2,B2) [RXY] */ + tmp32_1 = load_reg32(r1); + tmp2 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp2, tmp32_1); + tcg_gen_qemu_st8(tmp2, addr, get_mem_index(s)); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp2); + break; + case 0x73: /* ICY R1,D2(X2,B2) [RXY] */ + tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp3, addr, get_mem_index(s)); + store_reg8(r1, tmp3); + tcg_temp_free_i64(tmp3); + break; + case 0x76: /* LB R1,D2(X2,B2) [RXY] */ + case 0x77: /* LGB R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8s(tmp2, addr, get_mem_index(s)); + switch (op) { + case 0x76: + tcg_gen_ext8s_i64(tmp2, tmp2); + store_reg32_i64(r1, tmp2); + break; + case 0x77: + tcg_gen_ext8s_i64(tmp2, tmp2); + store_reg(r1, tmp2); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp2); + break; + case 0x78: /* LHY R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s)); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x80: /* NG R1,D2(X2,B2) [RXY] */ + case 0x81: /* OG R1,D2(X2,B2) [RXY] */ + case 0x82: /* XG R1,D2(X2,B2) [RXY] */ + tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp3, addr, get_mem_index(s)); + switch (op) { + case 0x80: + tcg_gen_and_i64(regs[r1], regs[r1], tmp3); + break; + case 0x81: + tcg_gen_or_i64(regs[r1], regs[r1], tmp3); + break; + case 0x82: + tcg_gen_xor_i64(regs[r1], regs[r1], tmp3); + break; + default: + tcg_abort(); + } + set_cc_nz_u64(s, regs[r1]); + tcg_temp_free_i64(tmp3); + break; + case 0x86: /* MLG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_const_i32(r1); + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + gen_helper_mlg(tmp32_1, tmp2); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x87: /* DLG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_const_i32(r1); + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + gen_helper_dlg(tmp32_1, tmp2); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x88: /* ALCG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + /* XXX possible optimization point */ + gen_op_calc_cc(s); + tcg_gen_extu_i32_i64(tmp3, cc_op); + tcg_gen_shri_i64(tmp3, tmp3, 1); + tcg_gen_andi_i64(tmp3, tmp3, 1); + tcg_gen_add_i64(tmp3, tmp2, tmp3); + tcg_gen_add_i64(tmp3, regs[r1], tmp3); + store_reg(r1, tmp3); + set_cc_addu64(s, regs[r1], tmp2, tmp3); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x89: /* SLBG R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_const_i32(r1); + tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s)); + /* XXX possible optimization point */ + gen_op_calc_cc(s); + gen_helper_slbg(cc_op, cc_op, tmp32_1, regs[r1], tmp2); + set_cc_static(s); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x90: /* LLGC R1,D2(X2,B2) [RXY] */ + tcg_gen_qemu_ld8u(regs[r1], addr, get_mem_index(s)); + break; + case 0x91: /* LLGH R1,D2(X2,B2) [RXY] */ + tcg_gen_qemu_ld16u(regs[r1], addr, get_mem_index(s)); + break; + case 0x94: /* LLC R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, addr, get_mem_index(s)); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x95: /* LLH R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16u(tmp2, addr, get_mem_index(s)); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x96: /* ML R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp3 = load_reg((r1 + 1) & 15); + tcg_gen_ext32u_i64(tmp3, tmp3); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + tcg_gen_mul_i64(tmp2, tmp2, tmp3); + store_reg32_i64((r1 + 1) & 15, tmp2); + tcg_gen_shri_i64(tmp2, tmp2, 32); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x97: /* DL R1,D2(X2,B2) [RXY] */ + /* reg(r1) = reg(r1, r1+1) % ld32(addr) */ + /* reg(r1+1) = reg(r1, r1+1) / ld32(addr) */ + tmp = load_reg(r1); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + tmp3 = load_reg((r1 + 1) & 15); + tcg_gen_ext32u_i64(tmp2, tmp2); + tcg_gen_ext32u_i64(tmp3, tmp3); + tcg_gen_shli_i64(tmp, tmp, 32); + tcg_gen_or_i64(tmp, tmp, tmp3); + + tcg_gen_rem_i64(tmp3, tmp, tmp2); + tcg_gen_div_i64(tmp, tmp, tmp2); + store_reg32_i64((r1 + 1) & 15, tmp); + store_reg32_i64(r1, tmp3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x98: /* ALC R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp32_3 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + /* XXX possible optimization point */ + gen_op_calc_cc(s); + gen_helper_addc_u32(tmp32_3, cc_op, tmp32_1, tmp32_2); + set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3); + store_reg32(r1, tmp32_3); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x99: /* SLB R1,D2(X2,B2) [RXY] */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + /* XXX possible optimization point */ + gen_op_calc_cc(s); + gen_helper_slb(cc_op, cc_op, tmp32_1, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + default: + LOG_DISAS("illegal e3 operation 0x%x\n", op); + gen_illegal_opcode(s, 3); + break; + } + tcg_temp_free_i64(addr); +} + +#ifndef CONFIG_USER_ONLY +static void disas_e5(DisasContext* s, uint64_t insn) +{ + TCGv_i64 tmp, tmp2; + int op = (insn >> 32) & 0xff; + + tmp = get_address(s, 0, (insn >> 28) & 0xf, (insn >> 16) & 0xfff); + tmp2 = get_address(s, 0, (insn >> 12) & 0xf, insn & 0xfff); + + LOG_DISAS("disas_e5: insn %" PRIx64 "\n", insn); + switch (op) { + case 0x01: /* TPROT D1(B1),D2(B2) [SSE] */ + /* Test Protection */ + potential_page_fault(s); + gen_helper_tprot(cc_op, tmp, tmp2); + set_cc_static(s); + break; + default: + LOG_DISAS("illegal e5 operation 0x%x\n", op); + gen_illegal_opcode(s, 3); + break; + } + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); +} +#endif + +static void disas_eb(DisasContext *s, int op, int r1, int r3, int b2, int d2) +{ + TCGv_i64 tmp, tmp2, tmp3, tmp4; + TCGv_i32 tmp32_1, tmp32_2; + int i, stm_len; + int ilc = 3; + + LOG_DISAS("disas_eb: op 0x%x r1 %d r3 %d b2 %d d2 0x%x\n", + op, r1, r3, b2, d2); + switch (op) { + case 0xc: /* SRLG R1,R3,D2(B2) [RSY] */ + case 0xd: /* SLLG R1,R3,D2(B2) [RSY] */ + case 0xa: /* SRAG R1,R3,D2(B2) [RSY] */ + case 0xb: /* SLAG R1,R3,D2(B2) [RSY] */ + case 0x1c: /* RLLG R1,R3,D2(B2) [RSY] */ + if (b2) { + tmp = get_address(s, 0, b2, d2); + tcg_gen_andi_i64(tmp, tmp, 0x3f); + } else { + tmp = tcg_const_i64(d2 & 0x3f); + } + switch (op) { + case 0xc: + tcg_gen_shr_i64(regs[r1], regs[r3], tmp); + break; + case 0xd: + tcg_gen_shl_i64(regs[r1], regs[r3], tmp); + break; + case 0xa: + tcg_gen_sar_i64(regs[r1], regs[r3], tmp); + break; + case 0xb: + tmp2 = tcg_temp_new_i64(); + tmp3 = tcg_temp_new_i64(); + gen_op_update2_cc_i64(s, CC_OP_SLAG, regs[r3], tmp); + tcg_gen_shl_i64(tmp2, regs[r3], tmp); + /* override sign bit with source sign */ + tcg_gen_andi_i64(tmp2, tmp2, ~0x8000000000000000ULL); + tcg_gen_andi_i64(tmp3, regs[r3], 0x8000000000000000ULL); + tcg_gen_or_i64(regs[r1], tmp2, tmp3); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x1c: + tcg_gen_rotl_i64(regs[r1], regs[r3], tmp); + break; + default: + tcg_abort(); + break; + } + if (op == 0xa) { + set_cc_s64(s, regs[r1]); + } + tcg_temp_free_i64(tmp); + break; + case 0x1d: /* RLL R1,R3,D2(B2) [RSY] */ + if (b2) { + tmp = get_address(s, 0, b2, d2); + tcg_gen_andi_i64(tmp, tmp, 0x3f); + } else { + tmp = tcg_const_i64(d2 & 0x3f); + } + tmp32_1 = tcg_temp_new_i32(); + tmp32_2 = load_reg32(r3); + tcg_gen_trunc_i64_i32(tmp32_1, tmp); + switch (op) { + case 0x1d: + tcg_gen_rotl_i32(tmp32_1, tmp32_2, tmp32_1); + break; + default: + tcg_abort(); + break; + } + store_reg32(r1, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x4: /* LMG R1,R3,D2(B2) [RSE] */ + case 0x24: /* STMG R1,R3,D2(B2) [RSE] */ + stm_len = 8; + goto do_mh; + case 0x26: /* STMH R1,R3,D2(B2) [RSE] */ + case 0x96: /* LMH R1,R3,D2(B2) [RSE] */ + stm_len = 4; +do_mh: + /* Apparently, unrolling lmg/stmg of any size gains performance - + even for very long ones... */ + tmp = get_address(s, 0, b2, d2); + tmp3 = tcg_const_i64(stm_len); + tmp4 = tcg_const_i64(op == 0x26 ? 32 : 4); + for (i = r1;; i = (i + 1) % 16) { + switch (op) { + case 0x4: + tcg_gen_qemu_ld64(regs[i], tmp, get_mem_index(s)); + break; + case 0x96: + tmp2 = tcg_temp_new_i64(); +#if HOST_LONG_BITS == 32 + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(TCGV_HIGH(regs[i]), tmp2); +#else + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_shl_i64(tmp2, tmp2, tmp4); + tcg_gen_ext32u_i64(regs[i], regs[i]); + tcg_gen_or_i64(regs[i], regs[i], tmp2); +#endif + tcg_temp_free_i64(tmp2); + break; + case 0x24: + tcg_gen_qemu_st64(regs[i], tmp, get_mem_index(s)); + break; + case 0x26: + tmp2 = tcg_temp_new_i64(); + tcg_gen_shr_i64(tmp2, regs[i], tmp4); + tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp2); + break; + default: + tcg_abort(); + } + if (i == r3) { + break; + } + tcg_gen_add_i64(tmp, tmp, tmp3); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp3); + tcg_temp_free_i64(tmp4); + break; + case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */ + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_stcmh(tmp32_1, tmp, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; +#ifndef CONFIG_USER_ONLY + case 0x2f: /* LCTLG R1,R3,D2(B2) [RSE] */ + /* Load Control */ + check_privileged(s, ilc); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_lctlg(tmp32_1, tmp, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x25: /* STCTG R1,R3,D2(B2) [RSE] */ + /* Store Control */ + check_privileged(s, ilc); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_stctg(tmp32_1, tmp, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; +#endif + case 0x30: /* CSG R1,R3,D2(B2) [RSY] */ + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + /* XXX rewrite in tcg */ + gen_helper_csg(cc_op, tmp32_1, tmp, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x3e: /* CDSG R1,R3,D2(B2) [RSY] */ + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + /* XXX rewrite in tcg */ + gen_helper_cdsg(cc_op, tmp32_1, tmp, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x51: /* TMY D1(B1),I2 [SIY] */ + tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */ + tmp2 = tcg_const_i64((r1 << 4) | r3); + tcg_gen_qemu_ld8u(tmp, tmp, get_mem_index(s)); + /* yes, this is a 32 bit operation with 64 bit tcg registers, because + that incurs less conversions */ + cmp_64(s, tmp, tmp2, CC_OP_TM_32); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x52: /* MVIY D1(B1),I2 [SIY] */ + tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */ + tmp2 = tcg_const_i64((r1 << 4) | r3); + tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x55: /* CLIY D1(B1),I2 [SIY] */ + tmp3 = get_address(s, 0, b2, d2); /* SIY -> this is the 1st operand */ + tmp = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_qemu_ld8u(tmp, tmp3, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp); + cmp_u32c(s, tmp32_1, (r1 << 4) | r3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp3); + tcg_temp_free_i32(tmp32_1); + break; + case 0x80: /* ICMH R1,M3,D2(B2) [RSY] */ + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + /* XXX split CC calculation out */ + gen_helper_icmh(cc_op, tmp32_1, tmp, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + default: + LOG_DISAS("illegal eb operation 0x%x\n", op); + gen_illegal_opcode(s, ilc); + break; + } +} + +static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2, + int r1b) +{ + TCGv_i32 tmp_r1, tmp32; + TCGv_i64 addr, tmp; + addr = get_address(s, x2, b2, d2); + tmp_r1 = tcg_const_i32(r1); + switch (op) { + case 0x4: /* LDEB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_ldeb(tmp_r1, addr); + break; + case 0x5: /* LXDB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_lxdb(tmp_r1, addr); + break; + case 0x9: /* CEB R1,D2(X2,B2) [RXE] */ + tmp = tcg_temp_new_i64(); + tmp32 = load_freg32(r1); + tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s)); + set_cc_cmp_f32_i64(s, tmp32, tmp); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32); + break; + case 0xa: /* AEB R1,D2(X2,B2) [RXE] */ + tmp = tcg_temp_new_i64(); + tmp32 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32, tmp); + gen_helper_aeb(tmp_r1, tmp32); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32); + + tmp32 = load_freg32(r1); + set_cc_nz_f32(s, tmp32); + tcg_temp_free_i32(tmp32); + break; + case 0xb: /* SEB R1,D2(X2,B2) [RXE] */ + tmp = tcg_temp_new_i64(); + tmp32 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32, tmp); + gen_helper_seb(tmp_r1, tmp32); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32); + + tmp32 = load_freg32(r1); + set_cc_nz_f32(s, tmp32); + tcg_temp_free_i32(tmp32); + break; + case 0xd: /* DEB R1,D2(X2,B2) [RXE] */ + tmp = tcg_temp_new_i64(); + tmp32 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32, tmp); + gen_helper_deb(tmp_r1, tmp32); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32); + break; + case 0x10: /* TCEB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_tceb(cc_op, tmp_r1, addr); + set_cc_static(s); + break; + case 0x11: /* TCDB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_tcdb(cc_op, tmp_r1, addr); + set_cc_static(s); + break; + case 0x12: /* TCXB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_tcxb(cc_op, tmp_r1, addr); + set_cc_static(s); + break; + case 0x17: /* MEEB R1,D2(X2,B2) [RXE] */ + tmp = tcg_temp_new_i64(); + tmp32 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32, tmp); + gen_helper_meeb(tmp_r1, tmp32); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32); + break; + case 0x19: /* CDB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_cdb(cc_op, tmp_r1, addr); + set_cc_static(s); + break; + case 0x1a: /* ADB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_adb(cc_op, tmp_r1, addr); + set_cc_static(s); + break; + case 0x1b: /* SDB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_sdb(cc_op, tmp_r1, addr); + set_cc_static(s); + break; + case 0x1c: /* MDB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_mdb(tmp_r1, addr); + break; + case 0x1d: /* DDB R1,D2(X2,B2) [RXE] */ + potential_page_fault(s); + gen_helper_ddb(tmp_r1, addr); + break; + case 0x1e: /* MADB R1,R3,D2(X2,B2) [RXF] */ + /* for RXF insns, r1 is R3 and r1b is R1 */ + tmp32 = tcg_const_i32(r1b); + potential_page_fault(s); + gen_helper_madb(tmp32, addr, tmp_r1); + tcg_temp_free_i32(tmp32); + break; + default: + LOG_DISAS("illegal ed operation 0x%x\n", op); + gen_illegal_opcode(s, 3); + return; + } + tcg_temp_free_i32(tmp_r1); + tcg_temp_free_i64(addr); +} + +static void disas_a5(DisasContext *s, int op, int r1, int i2) +{ + TCGv_i64 tmp, tmp2; + TCGv_i32 tmp32; + LOG_DISAS("disas_a5: op 0x%x r1 %d i2 0x%x\n", op, r1, i2); + switch (op) { + case 0x0: /* IIHH R1,I2 [RI] */ + tmp = tcg_const_i64(i2); + tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16); + tcg_temp_free_i64(tmp); + break; + case 0x1: /* IIHL R1,I2 [RI] */ + tmp = tcg_const_i64(i2); + tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16); + tcg_temp_free_i64(tmp); + break; + case 0x2: /* IILH R1,I2 [RI] */ + tmp = tcg_const_i64(i2); + tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16); + tcg_temp_free_i64(tmp); + break; + case 0x3: /* IILL R1,I2 [RI] */ + tmp = tcg_const_i64(i2); + tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16); + tcg_temp_free_i64(tmp); + break; + case 0x4: /* NIHH R1,I2 [RI] */ + case 0x8: /* OIHH R1,I2 [RI] */ + tmp = load_reg(r1); + tmp32 = tcg_temp_new_i32(); + switch (op) { + case 0x4: + tmp2 = tcg_const_i64((((uint64_t)i2) << 48) + | 0x0000ffffffffffffULL); + tcg_gen_and_i64(tmp, tmp, tmp2); + break; + case 0x8: + tmp2 = tcg_const_i64(((uint64_t)i2) << 48); + tcg_gen_or_i64(tmp, tmp, tmp2); + break; + default: + tcg_abort(); + } + store_reg(r1, tmp); + tcg_gen_shri_i64(tmp2, tmp, 48); + tcg_gen_trunc_i64_i32(tmp32, tmp2); + set_cc_nz_u32(s, tmp32); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32); + tcg_temp_free_i64(tmp); + break; + case 0x5: /* NIHL R1,I2 [RI] */ + case 0x9: /* OIHL R1,I2 [RI] */ + tmp = load_reg(r1); + tmp32 = tcg_temp_new_i32(); + switch (op) { + case 0x5: + tmp2 = tcg_const_i64((((uint64_t)i2) << 32) + | 0xffff0000ffffffffULL); + tcg_gen_and_i64(tmp, tmp, tmp2); + break; + case 0x9: + tmp2 = tcg_const_i64(((uint64_t)i2) << 32); + tcg_gen_or_i64(tmp, tmp, tmp2); + break; + default: + tcg_abort(); + } + store_reg(r1, tmp); + tcg_gen_shri_i64(tmp2, tmp, 32); + tcg_gen_trunc_i64_i32(tmp32, tmp2); + tcg_gen_andi_i32(tmp32, tmp32, 0xffff); + set_cc_nz_u32(s, tmp32); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32); + tcg_temp_free_i64(tmp); + break; + case 0x6: /* NILH R1,I2 [RI] */ + case 0xa: /* OILH R1,I2 [RI] */ + tmp = load_reg(r1); + tmp32 = tcg_temp_new_i32(); + switch (op) { + case 0x6: + tmp2 = tcg_const_i64((((uint64_t)i2) << 16) + | 0xffffffff0000ffffULL); + tcg_gen_and_i64(tmp, tmp, tmp2); + break; + case 0xa: + tmp2 = tcg_const_i64(((uint64_t)i2) << 16); + tcg_gen_or_i64(tmp, tmp, tmp2); + break; + default: + tcg_abort(); + } + store_reg(r1, tmp); + tcg_gen_shri_i64(tmp, tmp, 16); + tcg_gen_trunc_i64_i32(tmp32, tmp); + tcg_gen_andi_i32(tmp32, tmp32, 0xffff); + set_cc_nz_u32(s, tmp32); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32); + tcg_temp_free_i64(tmp); + break; + case 0x7: /* NILL R1,I2 [RI] */ + case 0xb: /* OILL R1,I2 [RI] */ + tmp = load_reg(r1); + tmp32 = tcg_temp_new_i32(); + switch (op) { + case 0x7: + tmp2 = tcg_const_i64(i2 | 0xffffffffffff0000ULL); + tcg_gen_and_i64(tmp, tmp, tmp2); + break; + case 0xb: + tmp2 = tcg_const_i64(i2); + tcg_gen_or_i64(tmp, tmp, tmp2); + break; + default: + tcg_abort(); + } + store_reg(r1, tmp); + tcg_gen_trunc_i64_i32(tmp32, tmp); + tcg_gen_andi_i32(tmp32, tmp32, 0xffff); + set_cc_nz_u32(s, tmp32); /* signedness should not matter here */ + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32); + tcg_temp_free_i64(tmp); + break; + case 0xc: /* LLIHH R1,I2 [RI] */ + tmp = tcg_const_i64( ((uint64_t)i2) << 48 ); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0xd: /* LLIHL R1,I2 [RI] */ + tmp = tcg_const_i64( ((uint64_t)i2) << 32 ); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0xe: /* LLILH R1,I2 [RI] */ + tmp = tcg_const_i64( ((uint64_t)i2) << 16 ); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0xf: /* LLILL R1,I2 [RI] */ + tmp = tcg_const_i64(i2); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + default: + LOG_DISAS("illegal a5 operation 0x%x\n", op); + gen_illegal_opcode(s, 2); + return; + } +} + +static void disas_a7(DisasContext *s, int op, int r1, int i2) +{ + TCGv_i64 tmp, tmp2; + TCGv_i32 tmp32_1, tmp32_2, tmp32_3; + int l1; + + LOG_DISAS("disas_a7: op 0x%x r1 %d i2 0x%x\n", op, r1, i2); + switch (op) { + case 0x0: /* TMLH or TMH R1,I2 [RI] */ + case 0x1: /* TMLL or TML R1,I2 [RI] */ + case 0x2: /* TMHH R1,I2 [RI] */ + case 0x3: /* TMHL R1,I2 [RI] */ + tmp = load_reg(r1); + tmp2 = tcg_const_i64((uint16_t)i2); + switch (op) { + case 0x0: + tcg_gen_shri_i64(tmp, tmp, 16); + break; + case 0x1: + break; + case 0x2: + tcg_gen_shri_i64(tmp, tmp, 48); + break; + case 0x3: + tcg_gen_shri_i64(tmp, tmp, 32); + break; + } + tcg_gen_andi_i64(tmp, tmp, 0xffff); + cmp_64(s, tmp, tmp2, CC_OP_TM_64); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x4: /* brc m1, i2 */ + gen_brc(r1, s, i2 * 2LL); + return; + case 0x5: /* BRAS R1,I2 [RI] */ + tmp = tcg_const_i64(pc_to_link_info(s, s->pc + 4)); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + gen_goto_tb(s, 0, s->pc + i2 * 2LL); + s->is_jmp = DISAS_TB_JUMP; + break; + case 0x6: /* BRCT R1,I2 [RI] */ + tmp32_1 = load_reg32(r1); + tcg_gen_subi_i32(tmp32_1, tmp32_1, 1); + store_reg32(r1, tmp32_1); + gen_update_cc_op(s); + l1 = gen_new_label(); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp32_1, 0, l1); + gen_goto_tb(s, 0, s->pc + (i2 * 2LL)); + gen_set_label(l1); + gen_goto_tb(s, 1, s->pc + 4); + s->is_jmp = DISAS_TB_JUMP; + tcg_temp_free_i32(tmp32_1); + break; + case 0x7: /* BRCTG R1,I2 [RI] */ + tmp = load_reg(r1); + tcg_gen_subi_i64(tmp, tmp, 1); + store_reg(r1, tmp); + gen_update_cc_op(s); + l1 = gen_new_label(); + tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1); + gen_goto_tb(s, 0, s->pc + (i2 * 2LL)); + gen_set_label(l1); + gen_goto_tb(s, 1, s->pc + 4); + s->is_jmp = DISAS_TB_JUMP; + tcg_temp_free_i64(tmp); + break; + case 0x8: /* lhi r1, i2 */ + tmp32_1 = tcg_const_i32(i2); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x9: /* lghi r1, i2 */ + tmp = tcg_const_i64(i2); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0xa: /* AHI R1,I2 [RI] */ + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp32_3 = tcg_const_i32(i2); + + if (i2 < 0) { + tcg_gen_subi_i32(tmp32_2, tmp32_1, -i2); + } else { + tcg_gen_add_i32(tmp32_2, tmp32_1, tmp32_3); + } + + store_reg32(r1, tmp32_2); + set_cc_add32(s, tmp32_1, tmp32_3, tmp32_2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0xb: /* aghi r1, i2 */ + tmp = load_reg(r1); + tmp2 = tcg_const_i64(i2); + + if (i2 < 0) { + tcg_gen_subi_i64(regs[r1], tmp, -i2); + } else { + tcg_gen_add_i64(regs[r1], tmp, tmp2); + } + set_cc_add64(s, tmp, tmp2, regs[r1]); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0xc: /* MHI R1,I2 [RI] */ + tmp32_1 = load_reg32(r1); + tcg_gen_muli_i32(tmp32_1, tmp32_1, i2); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0xd: /* MGHI R1,I2 [RI] */ + tmp = load_reg(r1); + tcg_gen_muli_i64(tmp, tmp, i2); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0xe: /* CHI R1,I2 [RI] */ + tmp32_1 = load_reg32(r1); + cmp_s32c(s, tmp32_1, i2); + tcg_temp_free_i32(tmp32_1); + break; + case 0xf: /* CGHI R1,I2 [RI] */ + tmp = load_reg(r1); + cmp_s64c(s, tmp, i2); + tcg_temp_free_i64(tmp); + break; + default: + LOG_DISAS("illegal a7 operation 0x%x\n", op); + gen_illegal_opcode(s, 2); + return; + } +} + +static void disas_b2(DisasContext *s, int op, uint32_t insn) +{ + TCGv_i64 tmp, tmp2, tmp3; + TCGv_i32 tmp32_1, tmp32_2, tmp32_3; + int r1, r2; + int ilc = 2; +#ifndef CONFIG_USER_ONLY + int r3, d2, b2; +#endif + + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + + LOG_DISAS("disas_b2: op 0x%x r1 %d r2 %d\n", op, r1, r2); + + switch (op) { + case 0x22: /* IPM R1 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + gen_op_calc_cc(s); + gen_helper_ipm(cc_op, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x41: /* CKSM R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r2); + potential_page_fault(s); + gen_helper_cksm(tmp32_1, tmp32_2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + gen_op_movi_cc(s, 0); + break; + case 0x4e: /* SAR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, aregs[r1])); + tcg_temp_free_i32(tmp32_1); + break; + case 0x4f: /* EAR R1,R2 [RRE] */ + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, aregs[r2])); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x52: /* MSR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r2); + tcg_gen_mul_i32(tmp32_1, tmp32_1, tmp32_2); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x54: /* MVPG R1,R2 [RRE] */ + tmp = load_reg(0); + tmp2 = load_reg(r1); + tmp3 = load_reg(r2); + potential_page_fault(s); + gen_helper_mvpg(tmp, tmp2, tmp3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + /* XXX check CCO bit and set CC accordingly */ + gen_op_movi_cc(s, 0); + break; + case 0x55: /* MVST R1,R2 [RRE] */ + tmp32_1 = load_reg32(0); + tmp32_2 = tcg_const_i32(r1); + tmp32_3 = tcg_const_i32(r2); + potential_page_fault(s); + gen_helper_mvst(tmp32_1, tmp32_2, tmp32_3); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + gen_op_movi_cc(s, 1); + break; + case 0x5d: /* CLST R1,R2 [RRE] */ + tmp32_1 = load_reg32(0); + tmp32_2 = tcg_const_i32(r1); + tmp32_3 = tcg_const_i32(r2); + potential_page_fault(s); + gen_helper_clst(cc_op, tmp32_1, tmp32_2, tmp32_3); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x5e: /* SRST R1,R2 [RRE] */ + tmp32_1 = load_reg32(0); + tmp32_2 = tcg_const_i32(r1); + tmp32_3 = tcg_const_i32(r2); + potential_page_fault(s); + gen_helper_srst(cc_op, tmp32_1, tmp32_2, tmp32_3); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + +#ifndef CONFIG_USER_ONLY + case 0x02: /* STIDP D2(B2) [S] */ + /* Store CPU ID */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_stidp(tmp); + tcg_temp_free_i64(tmp); + break; + case 0x04: /* SCK D2(B2) [S] */ + /* Set Clock */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_sck(cc_op, tmp); + set_cc_static(s); + tcg_temp_free_i64(tmp); + break; + case 0x05: /* STCK D2(B2) [S] */ + /* Store Clock */ + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_stck(cc_op, tmp); + set_cc_static(s); + tcg_temp_free_i64(tmp); + break; + case 0x06: /* SCKC D2(B2) [S] */ + /* Set Clock Comparator */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_sckc(tmp); + tcg_temp_free_i64(tmp); + break; + case 0x07: /* STCKC D2(B2) [S] */ + /* Store Clock Comparator */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_stckc(tmp); + tcg_temp_free_i64(tmp); + break; + case 0x08: /* SPT D2(B2) [S] */ + /* Set CPU Timer */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_spt(tmp); + tcg_temp_free_i64(tmp); + break; + case 0x09: /* STPT D2(B2) [S] */ + /* Store CPU Timer */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_stpt(tmp); + tcg_temp_free_i64(tmp); + break; + case 0x0a: /* SPKA D2(B2) [S] */ + /* Set PSW Key from Address */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_andi_i64(tmp2, psw_mask, ~PSW_MASK_KEY); + tcg_gen_shli_i64(tmp, tmp, PSW_SHIFT_KEY - 4); + tcg_gen_or_i64(psw_mask, tmp2, tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp); + break; + case 0x0d: /* PTLB [S] */ + /* Purge TLB */ + check_privileged(s, ilc); + gen_helper_ptlb(); + break; + case 0x10: /* SPX D2(B2) [S] */ + /* Set Prefix Register */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_spx(tmp); + tcg_temp_free_i64(tmp); + break; + case 0x11: /* STPX D2(B2) [S] */ + /* Store Prefix */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_ld_i64(tmp2, cpu_env, offsetof(CPUState, psa)); + tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x12: /* STAP D2(B2) [S] */ + /* Store CPU Address */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, cpu_num)); + tcg_gen_extu_i32_i64(tmp2, tmp32_1); + tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x21: /* IPTE R1,R2 [RRE] */ + /* Invalidate PTE */ + check_privileged(s, ilc); + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + tmp = load_reg(r1); + tmp2 = load_reg(r2); + gen_helper_ipte(tmp, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x29: /* ISKE R1,R2 [RRE] */ + /* Insert Storage Key Extended */ + check_privileged(s, ilc); + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + tmp = load_reg(r2); + tmp2 = tcg_temp_new_i64(); + gen_helper_iske(tmp2, tmp); + store_reg(r1, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x2a: /* RRBE R1,R2 [RRE] */ + /* Set Storage Key Extended */ + check_privileged(s, ilc); + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + tmp32_1 = load_reg32(r1); + tmp = load_reg(r2); + gen_helper_rrbe(cc_op, tmp32_1, tmp); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0x2b: /* SSKE R1,R2 [RRE] */ + /* Set Storage Key Extended */ + check_privileged(s, ilc); + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + tmp32_1 = load_reg32(r1); + tmp = load_reg(r2); + gen_helper_sske(tmp32_1, tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0x34: /* STCH ? */ + /* Store Subchannel */ + check_privileged(s, ilc); + gen_op_movi_cc(s, 3); + break; + case 0x46: /* STURA R1,R2 [RRE] */ + /* Store Using Real Address */ + check_privileged(s, ilc); + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + tmp32_1 = load_reg32(r1); + tmp = load_reg(r2); + potential_page_fault(s); + gen_helper_stura(tmp, tmp32_1); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0x50: /* CSP R1,R2 [RRE] */ + /* Compare And Swap And Purge */ + check_privileged(s, ilc); + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r2); + gen_helper_csp(cc_op, tmp32_1, tmp32_2); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x5f: /* CHSC ? */ + /* Channel Subsystem Call */ + check_privileged(s, ilc); + gen_op_movi_cc(s, 3); + break; + case 0x78: /* STCKE D2(B2) [S] */ + /* Store Clock Extended */ + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_stcke(cc_op, tmp); + set_cc_static(s); + tcg_temp_free_i64(tmp); + break; + case 0x79: /* SACF D2(B2) [S] */ + /* Store Clock Extended */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + potential_page_fault(s); + gen_helper_sacf(tmp); + tcg_temp_free_i64(tmp); + /* addressing mode has changed, so end the block */ + s->pc += ilc * 2; + update_psw_addr(s); + s->is_jmp = DISAS_EXCP; + break; + case 0x7d: /* STSI D2,(B2) [S] */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = load_reg32(0); + tmp32_2 = load_reg32(1); + potential_page_fault(s); + gen_helper_stsi(cc_op, tmp, tmp32_1, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x9d: /* LFPC D2(B2) [S] */ + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0xb1: /* STFL D2(B2) [S] */ + /* Store Facility List (CPU features) at 200 */ + check_privileged(s, ilc); + tmp2 = tcg_const_i64(0xc0000000); + tmp = tcg_const_i64(200); + tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp); + break; + case 0xb2: /* LPSWE D2(B2) [S] */ + /* Load PSW Extended */ + check_privileged(s, ilc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s)); + tcg_gen_addi_i64(tmp, tmp, 8); + tcg_gen_qemu_ld64(tmp3, tmp, get_mem_index(s)); + gen_helper_load_psw(tmp2, tmp3); + /* we need to keep cc_op intact */ + s->is_jmp = DISAS_JUMP; + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x20: /* SERVC R1,R2 [RRE] */ + /* SCLP Service call (PV hypercall) */ + check_privileged(s, ilc); + potential_page_fault(s); + tmp32_1 = load_reg32(r2); + tmp = load_reg(r1); + gen_helper_servc(cc_op, tmp32_1, tmp); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; +#endif + default: + LOG_DISAS("illegal b2 operation 0x%x\n", op); + gen_illegal_opcode(s, ilc); + break; + } +} + +static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2) +{ + TCGv_i64 tmp; + TCGv_i32 tmp32_1, tmp32_2, tmp32_3; + LOG_DISAS("disas_b3: op 0x%x m3 0x%x r1 %d r2 %d\n", op, m3, r1, r2); +#define FP_HELPER(i) \ + tmp32_1 = tcg_const_i32(r1); \ + tmp32_2 = tcg_const_i32(r2); \ + gen_helper_ ## i (tmp32_1, tmp32_2); \ + tcg_temp_free_i32(tmp32_1); \ + tcg_temp_free_i32(tmp32_2); + +#define FP_HELPER_CC(i) \ + tmp32_1 = tcg_const_i32(r1); \ + tmp32_2 = tcg_const_i32(r2); \ + gen_helper_ ## i (cc_op, tmp32_1, tmp32_2); \ + set_cc_static(s); \ + tcg_temp_free_i32(tmp32_1); \ + tcg_temp_free_i32(tmp32_2); + + switch (op) { + case 0x0: /* LPEBR R1,R2 [RRE] */ + FP_HELPER_CC(lpebr); + break; + case 0x2: /* LTEBR R1,R2 [RRE] */ + FP_HELPER_CC(ltebr); + break; + case 0x3: /* LCEBR R1,R2 [RRE] */ + FP_HELPER_CC(lcebr); + break; + case 0x4: /* LDEBR R1,R2 [RRE] */ + FP_HELPER(ldebr); + break; + case 0x5: /* LXDBR R1,R2 [RRE] */ + FP_HELPER(lxdbr); + break; + case 0x9: /* CEBR R1,R2 [RRE] */ + FP_HELPER_CC(cebr); + break; + case 0xa: /* AEBR R1,R2 [RRE] */ + FP_HELPER_CC(aebr); + break; + case 0xb: /* SEBR R1,R2 [RRE] */ + FP_HELPER_CC(sebr); + break; + case 0xd: /* DEBR R1,R2 [RRE] */ + FP_HELPER(debr); + break; + case 0x10: /* LPDBR R1,R2 [RRE] */ + FP_HELPER_CC(lpdbr); + break; + case 0x12: /* LTDBR R1,R2 [RRE] */ + FP_HELPER_CC(ltdbr); + break; + case 0x13: /* LCDBR R1,R2 [RRE] */ + FP_HELPER_CC(lcdbr); + break; + case 0x15: /* SQBDR R1,R2 [RRE] */ + FP_HELPER(sqdbr); + break; + case 0x17: /* MEEBR R1,R2 [RRE] */ + FP_HELPER(meebr); + break; + case 0x19: /* CDBR R1,R2 [RRE] */ + FP_HELPER_CC(cdbr); + break; + case 0x1a: /* ADBR R1,R2 [RRE] */ + FP_HELPER_CC(adbr); + break; + case 0x1b: /* SDBR R1,R2 [RRE] */ + FP_HELPER_CC(sdbr); + break; + case 0x1c: /* MDBR R1,R2 [RRE] */ + FP_HELPER(mdbr); + break; + case 0x1d: /* DDBR R1,R2 [RRE] */ + FP_HELPER(ddbr); + break; + case 0xe: /* MAEBR R1,R3,R2 [RRF] */ + case 0x1e: /* MADBR R1,R3,R2 [RRF] */ + case 0x1f: /* MSDBR R1,R3,R2 [RRF] */ + /* for RRF insns, m3 is R1, r1 is R3, and r2 is R2 */ + tmp32_1 = tcg_const_i32(m3); + tmp32_2 = tcg_const_i32(r2); + tmp32_3 = tcg_const_i32(r1); + switch (op) { + case 0xe: + gen_helper_maebr(tmp32_1, tmp32_3, tmp32_2); + break; + case 0x1e: + gen_helper_madbr(tmp32_1, tmp32_3, tmp32_2); + break; + case 0x1f: + gen_helper_msdbr(tmp32_1, tmp32_3, tmp32_2); + break; + default: + tcg_abort(); + } + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x40: /* LPXBR R1,R2 [RRE] */ + FP_HELPER_CC(lpxbr); + break; + case 0x42: /* LTXBR R1,R2 [RRE] */ + FP_HELPER_CC(ltxbr); + break; + case 0x43: /* LCXBR R1,R2 [RRE] */ + FP_HELPER_CC(lcxbr); + break; + case 0x44: /* LEDBR R1,R2 [RRE] */ + FP_HELPER(ledbr); + break; + case 0x45: /* LDXBR R1,R2 [RRE] */ + FP_HELPER(ldxbr); + break; + case 0x46: /* LEXBR R1,R2 [RRE] */ + FP_HELPER(lexbr); + break; + case 0x49: /* CXBR R1,R2 [RRE] */ + FP_HELPER_CC(cxbr); + break; + case 0x4a: /* AXBR R1,R2 [RRE] */ + FP_HELPER_CC(axbr); + break; + case 0x4b: /* SXBR R1,R2 [RRE] */ + FP_HELPER_CC(sxbr); + break; + case 0x4c: /* MXBR R1,R2 [RRE] */ + FP_HELPER(mxbr); + break; + case 0x4d: /* DXBR R1,R2 [RRE] */ + FP_HELPER(dxbr); + break; + case 0x65: /* LXR R1,R2 [RRE] */ + tmp = load_freg(r2); + store_freg(r1, tmp); + tcg_temp_free_i64(tmp); + tmp = load_freg(r2 + 2); + store_freg(r1 + 2, tmp); + tcg_temp_free_i64(tmp); + break; + case 0x74: /* LZER R1 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + gen_helper_lzer(tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x75: /* LZDR R1 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + gen_helper_lzdr(tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x76: /* LZXR R1 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + gen_helper_lzxr(tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x84: /* SFPC R1 [RRE] */ + tmp32_1 = load_reg32(r1); + tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc)); + tcg_temp_free_i32(tmp32_1); + break; + case 0x8c: /* EFPC R1 [RRE] */ + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc)); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x94: /* CEFBR R1,R2 [RRE] */ + case 0x95: /* CDFBR R1,R2 [RRE] */ + case 0x96: /* CXFBR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = load_reg32(r2); + switch (op) { + case 0x94: + gen_helper_cefbr(tmp32_1, tmp32_2); + break; + case 0x95: + gen_helper_cdfbr(tmp32_1, tmp32_2); + break; + case 0x96: + gen_helper_cxfbr(tmp32_1, tmp32_2); + break; + default: + tcg_abort(); + } + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x98: /* CFEBR R1,R2 [RRE] */ + case 0x99: /* CFDBR R1,R2 [RRE] */ + case 0x9a: /* CFXBR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r2); + tmp32_3 = tcg_const_i32(m3); + switch (op) { + case 0x98: + gen_helper_cfebr(cc_op, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x99: + gen_helper_cfdbr(cc_op, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x9a: + gen_helper_cfxbr(cc_op, tmp32_1, tmp32_2, tmp32_3); + break; + default: + tcg_abort(); + } + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0xa4: /* CEGBR R1,R2 [RRE] */ + case 0xa5: /* CDGBR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp = load_reg(r2); + switch (op) { + case 0xa4: + gen_helper_cegbr(tmp32_1, tmp); + break; + case 0xa5: + gen_helper_cdgbr(tmp32_1, tmp); + break; + default: + tcg_abort(); + } + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0xa6: /* CXGBR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp = load_reg(r2); + gen_helper_cxgbr(tmp32_1, tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0xa8: /* CGEBR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r2); + tmp32_3 = tcg_const_i32(m3); + gen_helper_cgebr(cc_op, tmp32_1, tmp32_2, tmp32_3); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0xa9: /* CGDBR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r2); + tmp32_3 = tcg_const_i32(m3); + gen_helper_cgdbr(cc_op, tmp32_1, tmp32_2, tmp32_3); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0xaa: /* CGXBR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r2); + tmp32_3 = tcg_const_i32(m3); + gen_helper_cgxbr(cc_op, tmp32_1, tmp32_2, tmp32_3); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + default: + LOG_DISAS("illegal b3 operation 0x%x\n", op); + gen_illegal_opcode(s, 2); + break; + } + +#undef FP_HELPER_CC +#undef FP_HELPER +} + +static void disas_b9(DisasContext *s, int op, int r1, int r2) +{ + TCGv_i64 tmp, tmp2, tmp3; + TCGv_i32 tmp32_1, tmp32_2, tmp32_3; + + LOG_DISAS("disas_b9: op 0x%x r1 %d r2 %d\n", op, r1, r2); + switch (op) { + case 0x0: /* LPGR R1,R2 [RRE] */ + case 0x1: /* LNGR R1,R2 [RRE] */ + case 0x2: /* LTGR R1,R2 [RRE] */ + case 0x3: /* LCGR R1,R2 [RRE] */ + case 0x10: /* LPGFR R1,R2 [RRE] */ + case 0x11: /* LNFGR R1,R2 [RRE] */ + case 0x12: /* LTGFR R1,R2 [RRE] */ + case 0x13: /* LCGFR R1,R2 [RRE] */ + if (op & 0x10) { + tmp = load_reg32_i64(r2); + } else { + tmp = load_reg(r2); + } + switch (op & 0xf) { + case 0x0: /* LP?GR */ + set_cc_abs64(s, tmp); + gen_helper_abs_i64(tmp, tmp); + store_reg(r1, tmp); + break; + case 0x1: /* LN?GR */ + set_cc_nabs64(s, tmp); + gen_helper_nabs_i64(tmp, tmp); + store_reg(r1, tmp); + break; + case 0x2: /* LT?GR */ + if (r1 != r2) { + store_reg(r1, tmp); + } + set_cc_s64(s, tmp); + break; + case 0x3: /* LC?GR */ + tcg_gen_neg_i64(regs[r1], tmp); + set_cc_comp64(s, regs[r1]); + break; + } + tcg_temp_free_i64(tmp); + break; + case 0x4: /* LGR R1,R2 [RRE] */ + store_reg(r1, regs[r2]); + break; + case 0x6: /* LGBR R1,R2 [RRE] */ + tmp2 = load_reg(r2); + tcg_gen_ext8s_i64(tmp2, tmp2); + store_reg(r1, tmp2); + tcg_temp_free_i64(tmp2); + break; + case 0x8: /* AGR R1,R2 [RRE] */ + case 0xa: /* ALGR R1,R2 [RRE] */ + tmp = load_reg(r1); + tmp2 = load_reg(r2); + tmp3 = tcg_temp_new_i64(); + tcg_gen_add_i64(tmp3, tmp, tmp2); + store_reg(r1, tmp3); + switch (op) { + case 0x8: + set_cc_add64(s, tmp, tmp2, tmp3); + break; + case 0xa: + set_cc_addu64(s, tmp, tmp2, tmp3); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x9: /* SGR R1,R2 [RRE] */ + case 0xb: /* SLGR R1,R2 [RRE] */ + case 0x1b: /* SLGFR R1,R2 [RRE] */ + case 0x19: /* SGFR R1,R2 [RRE] */ + tmp = load_reg(r1); + switch (op) { + case 0x1b: + tmp32_1 = load_reg32(r2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(tmp2, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x19: + tmp32_1 = load_reg32(r2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp2, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + default: + tmp2 = load_reg(r2); + break; + } + tmp3 = tcg_temp_new_i64(); + tcg_gen_sub_i64(tmp3, tmp, tmp2); + store_reg(r1, tmp3); + switch (op) { + case 0x9: + case 0x19: + set_cc_sub64(s, tmp, tmp2, tmp3); + break; + case 0xb: + case 0x1b: + set_cc_subu64(s, tmp, tmp2, tmp3); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0xc: /* MSGR R1,R2 [RRE] */ + case 0x1c: /* MSGFR R1,R2 [RRE] */ + tmp = load_reg(r1); + tmp2 = load_reg(r2); + if (op == 0x1c) { + tcg_gen_ext32s_i64(tmp2, tmp2); + } + tcg_gen_mul_i64(tmp, tmp, tmp2); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0xd: /* DSGR R1,R2 [RRE] */ + case 0x1d: /* DSGFR R1,R2 [RRE] */ + tmp = load_reg(r1 + 1); + if (op == 0xd) { + tmp2 = load_reg(r2); + } else { + tmp32_1 = load_reg32(r2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp2, tmp32_1); + tcg_temp_free_i32(tmp32_1); + } + tmp3 = tcg_temp_new_i64(); + tcg_gen_div_i64(tmp3, tmp, tmp2); + store_reg(r1 + 1, tmp3); + tcg_gen_rem_i64(tmp3, tmp, tmp2); + store_reg(r1, tmp3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x14: /* LGFR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tmp = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(tmp, tmp32_1); + store_reg(r1, tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0x16: /* LLGFR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tmp = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(tmp, tmp32_1); + store_reg(r1, tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0x17: /* LLGTR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tmp = tcg_temp_new_i64(); + tcg_gen_andi_i32(tmp32_1, tmp32_1, 0x7fffffffUL); + tcg_gen_extu_i32_i64(tmp, tmp32_1); + store_reg(r1, tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0x18: /* AGFR R1,R2 [RRE] */ + case 0x1a: /* ALGFR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tmp2 = tcg_temp_new_i64(); + if (op == 0x18) { + tcg_gen_ext_i32_i64(tmp2, tmp32_1); + } else { + tcg_gen_extu_i32_i64(tmp2, tmp32_1); + } + tcg_temp_free_i32(tmp32_1); + tmp = load_reg(r1); + tmp3 = tcg_temp_new_i64(); + tcg_gen_add_i64(tmp3, tmp, tmp2); + store_reg(r1, tmp3); + if (op == 0x18) { + set_cc_add64(s, tmp, tmp2, tmp3); + } else { + set_cc_addu64(s, tmp, tmp2, tmp3); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x0f: /* LRVGR R1,R2 [RRE] */ + tcg_gen_bswap64_i64(regs[r1], regs[r2]); + break; + case 0x1f: /* LRVR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tcg_gen_bswap32_i32(tmp32_1, tmp32_1); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x20: /* CGR R1,R2 [RRE] */ + case 0x30: /* CGFR R1,R2 [RRE] */ + tmp2 = load_reg(r2); + if (op == 0x30) { + tcg_gen_ext32s_i64(tmp2, tmp2); + } + tmp = load_reg(r1); + cmp_s64(s, tmp, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x21: /* CLGR R1,R2 [RRE] */ + case 0x31: /* CLGFR R1,R2 [RRE] */ + tmp2 = load_reg(r2); + if (op == 0x31) { + tcg_gen_ext32u_i64(tmp2, tmp2); + } + tmp = load_reg(r1); + cmp_u64(s, tmp, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x26: /* LBR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tcg_gen_ext8s_i32(tmp32_1, tmp32_1); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x27: /* LHR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tcg_gen_ext16s_i32(tmp32_1, tmp32_1); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x80: /* NGR R1,R2 [RRE] */ + case 0x81: /* OGR R1,R2 [RRE] */ + case 0x82: /* XGR R1,R2 [RRE] */ + tmp = load_reg(r1); + tmp2 = load_reg(r2); + switch (op) { + case 0x80: + tcg_gen_and_i64(tmp, tmp, tmp2); + break; + case 0x81: + tcg_gen_or_i64(tmp, tmp, tmp2); + break; + case 0x82: + tcg_gen_xor_i64(tmp, tmp, tmp2); + break; + default: + tcg_abort(); + } + store_reg(r1, tmp); + set_cc_nz_u64(s, tmp); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x83: /* FLOGR R1,R2 [RRE] */ + tmp = load_reg(r2); + tmp32_1 = tcg_const_i32(r1); + gen_helper_flogr(cc_op, tmp32_1, tmp); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + break; + case 0x84: /* LLGCR R1,R2 [RRE] */ + tmp = load_reg(r2); + tcg_gen_andi_i64(tmp, tmp, 0xff); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0x85: /* LLGHR R1,R2 [RRE] */ + tmp = load_reg(r2); + tcg_gen_andi_i64(tmp, tmp, 0xffff); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0x87: /* DLGR R1,R2 [RRE] */ + tmp32_1 = tcg_const_i32(r1); + tmp = load_reg(r2); + gen_helper_dlg(tmp32_1, tmp); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + break; + case 0x88: /* ALCGR R1,R2 [RRE] */ + tmp = load_reg(r1); + tmp2 = load_reg(r2); + tmp3 = tcg_temp_new_i64(); + gen_op_calc_cc(s); + tcg_gen_extu_i32_i64(tmp3, cc_op); + tcg_gen_shri_i64(tmp3, tmp3, 1); + tcg_gen_andi_i64(tmp3, tmp3, 1); + tcg_gen_add_i64(tmp3, tmp2, tmp3); + tcg_gen_add_i64(tmp3, tmp, tmp3); + store_reg(r1, tmp3); + set_cc_addu64(s, tmp, tmp2, tmp3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x89: /* SLBGR R1,R2 [RRE] */ + tmp = load_reg(r1); + tmp2 = load_reg(r2); + tmp32_1 = tcg_const_i32(r1); + gen_op_calc_cc(s); + gen_helper_slbg(cc_op, cc_op, tmp32_1, tmp, tmp2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x94: /* LLCR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xff); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x95: /* LLHR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xffff); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x96: /* MLR R1,R2 [RRE] */ + /* reg(r1, r1+1) = reg(r1+1) * reg(r2) */ + tmp2 = load_reg(r2); + tmp3 = load_reg((r1 + 1) & 15); + tcg_gen_ext32u_i64(tmp2, tmp2); + tcg_gen_ext32u_i64(tmp3, tmp3); + tcg_gen_mul_i64(tmp2, tmp2, tmp3); + store_reg32_i64((r1 + 1) & 15, tmp2); + tcg_gen_shri_i64(tmp2, tmp2, 32); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x97: /* DLR R1,R2 [RRE] */ + /* reg(r1) = reg(r1, r1+1) % reg(r2) */ + /* reg(r1+1) = reg(r1, r1+1) / reg(r2) */ + tmp = load_reg(r1); + tmp2 = load_reg(r2); + tmp3 = load_reg((r1 + 1) & 15); + tcg_gen_ext32u_i64(tmp2, tmp2); + tcg_gen_ext32u_i64(tmp3, tmp3); + tcg_gen_shli_i64(tmp, tmp, 32); + tcg_gen_or_i64(tmp, tmp, tmp3); + + tcg_gen_rem_i64(tmp3, tmp, tmp2); + tcg_gen_div_i64(tmp, tmp, tmp2); + store_reg32_i64((r1 + 1) & 15, tmp); + store_reg32_i64(r1, tmp3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x98: /* ALCR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r2); + tmp32_3 = tcg_temp_new_i32(); + /* XXX possible optimization point */ + gen_op_calc_cc(s); + gen_helper_addc_u32(tmp32_3, cc_op, tmp32_1, tmp32_2); + set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3); + store_reg32(r1, tmp32_3); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x99: /* SLBR R1,R2 [RRE] */ + tmp32_1 = load_reg32(r2); + tmp32_2 = tcg_const_i32(r1); + gen_op_calc_cc(s); + gen_helper_slb(cc_op, cc_op, tmp32_2, tmp32_1); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + default: + LOG_DISAS("illegal b9 operation 0x%x\n", op); + gen_illegal_opcode(s, 2); + break; + } +} + +static void disas_c0(DisasContext *s, int op, int r1, int i2) +{ + TCGv_i64 tmp; + TCGv_i32 tmp32_1, tmp32_2; + uint64_t target = s->pc + i2 * 2LL; + int l1; + + LOG_DISAS("disas_c0: op 0x%x r1 %d i2 %d\n", op, r1, i2); + + switch (op) { + case 0: /* larl r1, i2 */ + tmp = tcg_const_i64(target); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0x1: /* LGFI R1,I2 [RIL] */ + tmp = tcg_const_i64((int64_t)i2); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0x4: /* BRCL M1,I2 [RIL] */ + /* m1 & (1 << (3 - cc)) */ + tmp32_1 = tcg_const_i32(3); + tmp32_2 = tcg_const_i32(1); + gen_op_calc_cc(s); + tcg_gen_sub_i32(tmp32_1, tmp32_1, cc_op); + tcg_gen_shl_i32(tmp32_2, tmp32_2, tmp32_1); + tcg_temp_free_i32(tmp32_1); + tmp32_1 = tcg_const_i32(r1); /* m1 == r1 */ + tcg_gen_and_i32(tmp32_1, tmp32_1, tmp32_2); + l1 = gen_new_label(); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp32_1, 0, l1); + gen_goto_tb(s, 0, target); + gen_set_label(l1); + gen_goto_tb(s, 1, s->pc + 6); + s->is_jmp = DISAS_TB_JUMP; + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x5: /* brasl r1, i2 */ + tmp = tcg_const_i64(pc_to_link_info(s, s->pc + 6)); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + gen_goto_tb(s, 0, target); + s->is_jmp = DISAS_TB_JUMP; + break; + case 0x7: /* XILF R1,I2 [RIL] */ + case 0xb: /* NILF R1,I2 [RIL] */ + case 0xd: /* OILF R1,I2 [RIL] */ + tmp32_1 = load_reg32(r1); + switch (op) { + case 0x7: + tcg_gen_xori_i32(tmp32_1, tmp32_1, (uint32_t)i2); + break; + case 0xb: + tcg_gen_andi_i32(tmp32_1, tmp32_1, (uint32_t)i2); + break; + case 0xd: + tcg_gen_ori_i32(tmp32_1, tmp32_1, (uint32_t)i2); + break; + default: + tcg_abort(); + } + store_reg32(r1, tmp32_1); + set_cc_nz_u32(s, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x9: /* IILF R1,I2 [RIL] */ + tmp32_1 = tcg_const_i32((uint32_t)i2); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0xa: /* NIHF R1,I2 [RIL] */ + tmp = load_reg(r1); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_andi_i64(tmp, tmp, (((uint64_t)((uint32_t)i2)) << 32) + | 0xffffffffULL); + store_reg(r1, tmp); + tcg_gen_shri_i64(tmp, tmp, 32); + tcg_gen_trunc_i64_i32(tmp32_1, tmp); + set_cc_nz_u32(s, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + break; + case 0xe: /* LLIHF R1,I2 [RIL] */ + tmp = tcg_const_i64(((uint64_t)(uint32_t)i2) << 32); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0xf: /* LLILF R1,I2 [RIL] */ + tmp = tcg_const_i64((uint32_t)i2); + store_reg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + default: + LOG_DISAS("illegal c0 operation 0x%x\n", op); + gen_illegal_opcode(s, 3); + break; + } +} + +static void disas_c2(DisasContext *s, int op, int r1, int i2) +{ + TCGv_i64 tmp, tmp2, tmp3; + TCGv_i32 tmp32_1, tmp32_2, tmp32_3; + + switch (op) { + case 0x4: /* SLGFI R1,I2 [RIL] */ + case 0xa: /* ALGFI R1,I2 [RIL] */ + tmp = load_reg(r1); + tmp2 = tcg_const_i64((uint64_t)(uint32_t)i2); + tmp3 = tcg_temp_new_i64(); + switch (op) { + case 0x4: + tcg_gen_sub_i64(tmp3, tmp, tmp2); + set_cc_subu64(s, tmp, tmp2, tmp3); + break; + case 0xa: + tcg_gen_add_i64(tmp3, tmp, tmp2); + set_cc_addu64(s, tmp, tmp2, tmp3); + break; + default: + tcg_abort(); + } + store_reg(r1, tmp3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x5: /* SLFI R1,I2 [RIL] */ + case 0xb: /* ALFI R1,I2 [RIL] */ + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_const_i32(i2); + tmp32_3 = tcg_temp_new_i32(); + switch (op) { + case 0x5: + tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2); + set_cc_subu32(s, tmp32_1, tmp32_2, tmp32_3); + break; + case 0xb: + tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2); + set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3); + break; + default: + tcg_abort(); + } + store_reg32(r1, tmp32_3); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0xc: /* CGFI R1,I2 [RIL] */ + tmp = load_reg(r1); + cmp_s64c(s, tmp, (int64_t)i2); + tcg_temp_free_i64(tmp); + break; + case 0xe: /* CLGFI R1,I2 [RIL] */ + tmp = load_reg(r1); + cmp_u64c(s, tmp, (uint64_t)(uint32_t)i2); + tcg_temp_free_i64(tmp); + break; + case 0xd: /* CFI R1,I2 [RIL] */ + tmp32_1 = load_reg32(r1); + cmp_s32c(s, tmp32_1, i2); + tcg_temp_free_i32(tmp32_1); + break; + case 0xf: /* CLFI R1,I2 [RIL] */ + tmp32_1 = load_reg32(r1); + cmp_u32c(s, tmp32_1, i2); + tcg_temp_free_i32(tmp32_1); + break; + default: + LOG_DISAS("illegal c2 operation 0x%x\n", op); + gen_illegal_opcode(s, 3); + break; + } +} + +static void gen_and_or_xor_i32(int opc, TCGv_i32 tmp, TCGv_i32 tmp2) +{ + switch (opc & 0xf) { + case 0x4: + tcg_gen_and_i32(tmp, tmp, tmp2); + break; + case 0x6: + tcg_gen_or_i32(tmp, tmp, tmp2); + break; + case 0x7: + tcg_gen_xor_i32(tmp, tmp, tmp2); + break; + default: + tcg_abort(); + } +} + +static void disas_s390_insn(DisasContext *s) +{ + TCGv_i64 tmp, tmp2, tmp3, tmp4; + TCGv_i32 tmp32_1, tmp32_2, tmp32_3, tmp32_4; + unsigned char opc; + uint64_t insn; + int op, r1, r2, r3, d1, d2, x2, b1, b2, i, i2, r1b; + TCGv_i32 vl; + int ilc; + int l1; + + opc = ldub_code(s->pc); + LOG_DISAS("opc 0x%x\n", opc); + + ilc = get_ilc(opc); + + switch (opc) { +#ifndef CONFIG_USER_ONLY + case 0x01: /* SAM */ + insn = ld_code2(s->pc); + /* set addressing mode, but we only do 64bit anyways */ + break; +#endif + case 0x6: /* BCTR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r1); + tcg_gen_subi_i32(tmp32_1, tmp32_1, 1); + store_reg32(r1, tmp32_1); + + if (r2) { + gen_update_cc_op(s); + l1 = gen_new_label(); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp32_1, 0, l1); + + /* not taking the branch, jump to after the instruction */ + gen_goto_tb(s, 0, s->pc + 2); + gen_set_label(l1); + + /* take the branch, move R2 into psw.addr */ + tmp32_1 = load_reg32(r2); + tmp = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(tmp, tmp32_1); + tcg_gen_mov_i64(psw_addr, tmp); + s->is_jmp = DISAS_JUMP; + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + } + break; + case 0x7: /* BCR M1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + if (r2) { + tmp = load_reg(r2); + gen_bcr(s, r1, tmp, s->pc); + tcg_temp_free_i64(tmp); + s->is_jmp = DISAS_TB_JUMP; + } else { + /* XXX: "serialization and checkpoint-synchronization function"? */ + } + break; + case 0xa: /* SVC I [RR] */ + insn = ld_code2(s->pc); + debug_insn(insn); + i = insn & 0xff; + update_psw_addr(s); + gen_op_calc_cc(s); + tmp32_1 = tcg_const_i32(i); + tmp32_2 = tcg_const_i32(ilc * 2); + tmp32_3 = tcg_const_i32(EXCP_SVC); + tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, int_svc_code)); + tcg_gen_st_i32(tmp32_2, cpu_env, offsetof(CPUState, int_svc_ilc)); + gen_helper_exception(tmp32_3); + s->is_jmp = DISAS_EXCP; + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0xd: /* BASR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp = tcg_const_i64(pc_to_link_info(s, s->pc + 2)); + store_reg(r1, tmp); + if (r2) { + tmp2 = load_reg(r2); + tcg_gen_mov_i64(psw_addr, tmp2); + tcg_temp_free_i64(tmp2); + s->is_jmp = DISAS_JUMP; + } + tcg_temp_free_i64(tmp); + break; + case 0xe: /* MVCL R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r2); + potential_page_fault(s); + gen_helper_mvcl(cc_op, tmp32_1, tmp32_2); + set_cc_static(s); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x10: /* LPR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r2); + set_cc_abs32(s, tmp32_1); + gen_helper_abs_i32(tmp32_1, tmp32_1); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x11: /* LNR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r2); + set_cc_nabs32(s, tmp32_1); + gen_helper_nabs_i32(tmp32_1, tmp32_1); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x12: /* LTR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r2); + if (r1 != r2) { + store_reg32(r1, tmp32_1); + } + set_cc_s32(s, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x13: /* LCR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r2); + tcg_gen_neg_i32(tmp32_1, tmp32_1); + store_reg32(r1, tmp32_1); + set_cc_comp32(s, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x14: /* NR R1,R2 [RR] */ + case 0x16: /* OR R1,R2 [RR] */ + case 0x17: /* XR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_2 = load_reg32(r2); + tmp32_1 = load_reg32(r1); + gen_and_or_xor_i32(opc, tmp32_1, tmp32_2); + store_reg32(r1, tmp32_1); + set_cc_nz_u32(s, tmp32_1); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x18: /* LR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r2); + store_reg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x15: /* CLR R1,R2 [RR] */ + case 0x19: /* CR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r2); + if (opc == 0x15) { + cmp_u32(s, tmp32_1, tmp32_2); + } else { + cmp_s32(s, tmp32_1, tmp32_2); + } + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x1a: /* AR R1,R2 [RR] */ + case 0x1e: /* ALR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r2); + tmp32_3 = tcg_temp_new_i32(); + tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2); + store_reg32(r1, tmp32_3); + if (opc == 0x1a) { + set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3); + } else { + set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3); + } + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x1b: /* SR R1,R2 [RR] */ + case 0x1f: /* SLR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r2); + tmp32_3 = tcg_temp_new_i32(); + tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2); + store_reg32(r1, tmp32_3); + if (opc == 0x1b) { + set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3); + } else { + set_cc_subu32(s, tmp32_1, tmp32_2, tmp32_3); + } + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x1c: /* MR R1,R2 [RR] */ + /* reg(r1, r1+1) = reg(r1+1) * reg(r2) */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp2 = load_reg(r2); + tmp3 = load_reg((r1 + 1) & 15); + tcg_gen_ext32s_i64(tmp2, tmp2); + tcg_gen_ext32s_i64(tmp3, tmp3); + tcg_gen_mul_i64(tmp2, tmp2, tmp3); + store_reg32_i64((r1 + 1) & 15, tmp2); + tcg_gen_shri_i64(tmp2, tmp2, 32); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x1d: /* DR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r1 + 1); + tmp32_3 = load_reg32(r2); + + tmp = tcg_temp_new_i64(); /* dividend */ + tmp2 = tcg_temp_new_i64(); /* divisor */ + tmp3 = tcg_temp_new_i64(); + + /* dividend is r(r1 << 32) | r(r1 + 1) */ + tcg_gen_extu_i32_i64(tmp, tmp32_1); + tcg_gen_extu_i32_i64(tmp2, tmp32_2); + tcg_gen_shli_i64(tmp, tmp, 32); + tcg_gen_or_i64(tmp, tmp, tmp2); + + /* divisor is r(r2) */ + tcg_gen_ext_i32_i64(tmp2, tmp32_3); + + tcg_gen_div_i64(tmp3, tmp, tmp2); + tcg_gen_rem_i64(tmp, tmp, tmp2); + + tcg_gen_trunc_i64_i32(tmp32_1, tmp); + tcg_gen_trunc_i64_i32(tmp32_2, tmp3); + + store_reg32(r1, tmp32_1); /* remainder */ + store_reg32(r1 + 1, tmp32_2); /* quotient */ + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x28: /* LDR R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp = load_freg(r2); + store_freg(r1, tmp); + tcg_temp_free_i64(tmp); + break; + case 0x38: /* LER R1,R2 [RR] */ + insn = ld_code2(s->pc); + decode_rr(s, insn, &r1, &r2); + tmp32_1 = load_freg32(r2); + store_freg32(r1, tmp32_1); + tcg_temp_free_i32(tmp32_1); + break; + case 0x40: /* STH R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = load_reg(r1); + tcg_gen_qemu_st16(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x41: /* la */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + store_reg(r1, tmp); /* FIXME: 31/24-bit addressing */ + tcg_temp_free_i64(tmp); + break; + case 0x42: /* STC R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = load_reg(r1); + tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x43: /* IC R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s)); + store_reg8(r1, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x44: /* EX R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = load_reg(r1); + tmp3 = tcg_const_i64(s->pc + 4); + update_psw_addr(s); + gen_op_calc_cc(s); + gen_helper_ex(cc_op, cc_op, tmp2, tmp, tmp3); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x46: /* BCT R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tcg_temp_free_i64(tmp); + + tmp32_1 = load_reg32(r1); + tcg_gen_subi_i32(tmp32_1, tmp32_1, 1); + store_reg32(r1, tmp32_1); + + gen_update_cc_op(s); + l1 = gen_new_label(); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp32_1, 0, l1); + + /* not taking the branch, jump to after the instruction */ + gen_goto_tb(s, 0, s->pc + 4); + gen_set_label(l1); + + /* take the branch, move R2 into psw.addr */ + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tcg_gen_mov_i64(psw_addr, tmp); + s->is_jmp = DISAS_JUMP; + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + break; + case 0x47: /* BC M1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + gen_bcr(s, r1, tmp, s->pc + 4); + tcg_temp_free_i64(tmp); + s->is_jmp = DISAS_TB_JUMP; + break; + case 0x48: /* LH R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s)); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x49: /* CH R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + cmp_s32(s, tmp32_1, tmp32_2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x4a: /* AH R1,D2(X2,B2) [RX] */ + case 0x4b: /* SH R1,D2(X2,B2) [RX] */ + case 0x4c: /* MH R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp32_3 = tcg_temp_new_i32(); + + tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + switch (opc) { + case 0x4a: + tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2); + set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x4b: + tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2); + set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x4c: + tcg_gen_mul_i32(tmp32_3, tmp32_1, tmp32_2); + break; + default: + tcg_abort(); + } + store_reg32(r1, tmp32_3); + + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x4d: /* BAS R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_const_i64(pc_to_link_info(s, s->pc + 4)); + store_reg(r1, tmp2); + tcg_gen_mov_i64(psw_addr, tmp); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + s->is_jmp = DISAS_JUMP; + break; + case 0x4e: /* CVD R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_trunc_i64_i32(tmp32_1, regs[r1]); + gen_helper_cvd(tmp2, tmp32_1); + tcg_gen_qemu_st64(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x50: /* st r1, d2(x2, b2) */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = load_reg(r1); + tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x55: /* CL R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tmp32_2 = load_reg32(r1); + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + cmp_u32(s, tmp32_2, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x54: /* N R1,D2(X2,B2) [RX] */ + case 0x56: /* O R1,D2(X2,B2) [RX] */ + case 0x57: /* X R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + gen_and_or_xor_i32(opc, tmp32_1, tmp32_2); + store_reg32(r1, tmp32_1); + set_cc_nz_u32(s, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x58: /* l r1, d2(x2, b2) */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + store_reg32(r1, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x59: /* C R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tmp32_2 = load_reg32(r1); + tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + cmp_s32(s, tmp32_2, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x5a: /* A R1,D2(X2,B2) [RX] */ + case 0x5b: /* S R1,D2(X2,B2) [RX] */ + case 0x5e: /* AL R1,D2(X2,B2) [RX] */ + case 0x5f: /* SL R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp32_3 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32s(tmp, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp); + switch (opc) { + case 0x5a: + case 0x5e: + tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2); + break; + case 0x5b: + case 0x5f: + tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2); + break; + default: + tcg_abort(); + } + store_reg32(r1, tmp32_3); + switch (opc) { + case 0x5a: + set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x5e: + set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x5b: + set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3); + break; + case 0x5f: + set_cc_subu32(s, tmp32_1, tmp32_2, tmp32_3); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + break; + case 0x5c: /* M R1,D2(X2,B2) [RX] */ + /* reg(r1, r1+1) = reg(r1+1) * *(s32*)addr */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s)); + tmp3 = load_reg((r1 + 1) & 15); + tcg_gen_ext32s_i64(tmp2, tmp2); + tcg_gen_ext32s_i64(tmp3, tmp3); + tcg_gen_mul_i64(tmp2, tmp2, tmp3); + store_reg32_i64((r1 + 1) & 15, tmp2); + tcg_gen_shri_i64(tmp2, tmp2, 32); + store_reg32_i64(r1, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x5d: /* D R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp3 = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r1 + 1); + + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); + + /* dividend is r(r1 << 32) | r(r1 + 1) */ + tcg_gen_extu_i32_i64(tmp, tmp32_1); + tcg_gen_extu_i32_i64(tmp2, tmp32_2); + tcg_gen_shli_i64(tmp, tmp, 32); + tcg_gen_or_i64(tmp, tmp, tmp2); + + /* divisor is in memory */ + tcg_gen_qemu_ld32s(tmp2, tmp3, get_mem_index(s)); + + /* XXX divisor == 0 -> FixP divide exception */ + + tcg_gen_div_i64(tmp3, tmp, tmp2); + tcg_gen_rem_i64(tmp, tmp, tmp2); + + tcg_gen_trunc_i64_i32(tmp32_1, tmp); + tcg_gen_trunc_i64_i32(tmp32_2, tmp3); + + store_reg32(r1, tmp32_1); /* remainder */ + store_reg32(r1 + 1, tmp32_2); /* quotient */ + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x60: /* STD R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = load_freg(r1); + tcg_gen_qemu_st64(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x68: /* LD R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s)); + store_freg(r1, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x70: /* STE R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = load_freg32(r1); + tcg_gen_extu_i32_i64(tmp2, tmp32_1); + tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0x71: /* MS R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + tcg_gen_mul_i32(tmp32_1, tmp32_1, tmp32_2); + store_reg32(r1, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x78: /* LE R1,D2(X2,B2) [RX] */ + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = tcg_temp_new_i32(); + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_1, tmp2); + store_freg32(r1, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; +#ifndef CONFIG_USER_ONLY + case 0x80: /* SSM D2(B2) [S] */ + /* Set System Mask */ + check_privileged(s, ilc); + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tmp3 = tcg_temp_new_i64(); + tcg_gen_andi_i64(tmp3, psw_mask, ~0xff00000000000000ULL); + tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s)); + tcg_gen_shli_i64(tmp2, tmp2, 56); + tcg_gen_or_i64(psw_mask, tmp3, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; + case 0x82: /* LPSW D2(B2) [S] */ + /* Load PSW */ + check_privileged(s, ilc); + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tmp3 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_addi_i64(tmp, tmp, 4); + tcg_gen_qemu_ld32u(tmp3, tmp, get_mem_index(s)); + gen_helper_load_psw(tmp2, tmp3); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + /* we need to keep cc_op intact */ + s->is_jmp = DISAS_JUMP; + break; + case 0x83: /* DIAG R1,R3,D2 [RS] */ + /* Diagnose call (KVM hypercall) */ + check_privileged(s, ilc); + potential_page_fault(s); + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp32_1 = tcg_const_i32(insn & 0xfff); + tmp2 = load_reg(2); + tmp3 = load_reg(1); + gen_helper_diag(tmp2, tmp32_1, tmp2, tmp3); + store_reg(2, tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; +#endif + case 0x88: /* SRL R1,D2(B2) [RS] */ + case 0x89: /* SLL R1,D2(B2) [RS] */ + case 0x8a: /* SRA R1,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tcg_gen_trunc_i64_i32(tmp32_2, tmp); + tcg_gen_andi_i32(tmp32_2, tmp32_2, 0x3f); + switch (opc) { + case 0x88: + tcg_gen_shr_i32(tmp32_1, tmp32_1, tmp32_2); + break; + case 0x89: + tcg_gen_shl_i32(tmp32_1, tmp32_1, tmp32_2); + break; + case 0x8a: + tcg_gen_sar_i32(tmp32_1, tmp32_1, tmp32_2); + set_cc_s32(s, tmp32_1); + break; + default: + tcg_abort(); + } + store_reg32(r1, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x8c: /* SRDL R1,D2(B2) [RS] */ + case 0x8d: /* SLDL R1,D2(B2) [RS] */ + case 0x8e: /* SRDA R1,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); /* shift */ + tmp2 = tcg_temp_new_i64(); + tmp32_1 = load_reg32(r1); + tmp32_2 = load_reg32(r1 + 1); + tcg_gen_concat_i32_i64(tmp2, tmp32_2, tmp32_1); /* operand */ + switch (opc) { + case 0x8c: + tcg_gen_shr_i64(tmp2, tmp2, tmp); + break; + case 0x8d: + tcg_gen_shl_i64(tmp2, tmp2, tmp); + break; + case 0x8e: + tcg_gen_sar_i64(tmp2, tmp2, tmp); + set_cc_s64(s, tmp2); + break; + } + tcg_gen_shri_i64(tmp, tmp2, 32); + tcg_gen_trunc_i64_i32(tmp32_1, tmp); + store_reg32(r1, tmp32_1); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + store_reg32(r1 + 1, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x98: /* LM R1,R3,D2(B2) [RS] */ + case 0x90: /* STM R1,R3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tmp3 = tcg_const_i64(4); + tmp4 = tcg_const_i64(0xffffffff00000000ULL); + for (i = r1;; i = (i + 1) % 16) { + if (opc == 0x98) { + tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s)); + tcg_gen_and_i64(regs[i], regs[i], tmp4); + tcg_gen_or_i64(regs[i], regs[i], tmp2); + } else { + tcg_gen_qemu_st32(regs[i], tmp, get_mem_index(s)); + } + if (i == r3) { + break; + } + tcg_gen_add_i64(tmp, tmp, tmp3); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + tcg_temp_free_i64(tmp4); + break; + case 0x91: /* TM D1(B1),I2 [SI] */ + insn = ld_code4(s->pc); + tmp = decode_si(s, insn, &i2, &b1, &d1); + tmp2 = tcg_const_i64(i2); + tcg_gen_qemu_ld8u(tmp, tmp, get_mem_index(s)); + cmp_64(s, tmp, tmp2, CC_OP_TM_32); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x92: /* MVI D1(B1),I2 [SI] */ + insn = ld_code4(s->pc); + tmp = decode_si(s, insn, &i2, &b1, &d1); + tmp2 = tcg_const_i64(i2); + tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s)); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x94: /* NI D1(B1),I2 [SI] */ + case 0x96: /* OI D1(B1),I2 [SI] */ + case 0x97: /* XI D1(B1),I2 [SI] */ + insn = ld_code4(s->pc); + tmp = decode_si(s, insn, &i2, &b1, &d1); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s)); + switch (opc) { + case 0x94: + tcg_gen_andi_i64(tmp2, tmp2, i2); + break; + case 0x96: + tcg_gen_ori_i64(tmp2, tmp2, i2); + break; + case 0x97: + tcg_gen_xori_i64(tmp2, tmp2, i2); + break; + default: + tcg_abort(); + } + tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s)); + set_cc_nz_u64(s, tmp2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x95: /* CLI D1(B1),I2 [SI] */ + insn = ld_code4(s->pc); + tmp = decode_si(s, insn, &i2, &b1, &d1); + tmp2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s)); + cmp_u64c(s, tmp2, i2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0x9a: /* LAM R1,R3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_lam(tmp32_1, tmp, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0x9b: /* STAM R1,R3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_stam(tmp32_1, tmp, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0xa5: + insn = ld_code4(s->pc); + r1 = (insn >> 20) & 0xf; + op = (insn >> 16) & 0xf; + i2 = insn & 0xffff; + disas_a5(s, op, r1, i2); + break; + case 0xa7: + insn = ld_code4(s->pc); + r1 = (insn >> 20) & 0xf; + op = (insn >> 16) & 0xf; + i2 = (short)insn; + disas_a7(s, op, r1, i2); + break; + case 0xa8: /* MVCLE R1,R3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_mvcle(cc_op, tmp32_1, tmp, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0xa9: /* CLCLE R1,R3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_clcle(cc_op, tmp32_1, tmp, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; +#ifndef CONFIG_USER_ONLY + case 0xac: /* STNSM D1(B1),I2 [SI] */ + case 0xad: /* STOSM D1(B1),I2 [SI] */ + check_privileged(s, ilc); + insn = ld_code4(s->pc); + tmp = decode_si(s, insn, &i2, &b1, &d1); + tmp2 = tcg_temp_new_i64(); + tcg_gen_shri_i64(tmp2, psw_mask, 56); + tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s)); + if (opc == 0xac) { + tcg_gen_andi_i64(psw_mask, psw_mask, + ((uint64_t)i2 << 56) | 0x00ffffffffffffffULL); + } else { + tcg_gen_ori_i64(psw_mask, psw_mask, (uint64_t)i2 << 56); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + case 0xae: /* SIGP R1,R3,D2(B2) [RS] */ + check_privileged(s, ilc); + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp2 = load_reg(r3); + tmp32_1 = tcg_const_i32(r1); + potential_page_fault(s); + gen_helper_sigp(cc_op, tmp, tmp32_1, tmp2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + break; + case 0xb1: /* LRA R1,D2(X2, B2) [RX] */ + check_privileged(s, ilc); + insn = ld_code4(s->pc); + tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2); + tmp32_1 = tcg_const_i32(r1); + potential_page_fault(s); + gen_helper_lra(cc_op, tmp, tmp32_1); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + break; +#endif + case 0xb2: + insn = ld_code4(s->pc); + op = (insn >> 16) & 0xff; + switch (op) { + case 0x9c: /* STFPC D2(B2) [S] */ + d2 = insn & 0xfff; + b2 = (insn >> 12) & 0xf; + tmp32_1 = tcg_temp_new_i32(); + tmp = tcg_temp_new_i64(); + tmp2 = get_address(s, 0, b2, d2); + tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc)); + tcg_gen_extu_i32_i64(tmp, tmp32_1); + tcg_gen_qemu_st32(tmp, tmp2, get_mem_index(s)); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; + default: + disas_b2(s, op, insn); + break; + } + break; + case 0xb3: + insn = ld_code4(s->pc); + op = (insn >> 16) & 0xff; + r3 = (insn >> 12) & 0xf; /* aka m3 */ + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + disas_b3(s, op, r3, r1, r2); + break; +#ifndef CONFIG_USER_ONLY + case 0xb6: /* STCTL R1,R3,D2(B2) [RS] */ + /* Store Control */ + check_privileged(s, ilc); + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_stctl(tmp32_1, tmp, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0xb7: /* LCTL R1,R3,D2(B2) [RS] */ + /* Load Control */ + check_privileged(s, ilc); + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_lctl(tmp32_1, tmp, tmp32_2); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; +#endif + case 0xb9: + insn = ld_code4(s->pc); + r1 = (insn >> 4) & 0xf; + r2 = insn & 0xf; + op = (insn >> 16) & 0xff; + disas_b9(s, op, r1, r2); + break; + case 0xba: /* CS R1,R3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_const_i32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_cs(cc_op, tmp32_1, tmp, tmp32_2); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0xbd: /* CLM R1,M3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_clm(cc_op, tmp32_1, tmp32_2, tmp); + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0xbe: /* STCM R1,M3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + tmp = get_address(s, 0, b2, d2); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_const_i32(r3); + potential_page_fault(s); + gen_helper_stcm(tmp32_1, tmp32_2, tmp); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + break; + case 0xbf: /* ICM R1,M3,D2(B2) [RS] */ + insn = ld_code4(s->pc); + decode_rs(s, insn, &r1, &r3, &b2, &d2); + if (r3 == 15) { + /* effectively a 32-bit load */ + tmp = get_address(s, 0, b2, d2); + tmp32_1 = tcg_temp_new_i32(); + tmp32_2 = tcg_const_i32(r3); + tcg_gen_qemu_ld32u(tmp, tmp, get_mem_index(s)); + store_reg32_i64(r1, tmp); + tcg_gen_trunc_i64_i32(tmp32_1, tmp); + set_cc_icm(s, tmp32_2, tmp32_1); + tcg_temp_free_i64(tmp); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + } else if (r3) { + uint32_t mask = 0x00ffffffUL; + uint32_t shift = 24; + int m3 = r3; + tmp = get_address(s, 0, b2, d2); + tmp2 = tcg_temp_new_i64(); + tmp32_1 = load_reg32(r1); + tmp32_2 = tcg_temp_new_i32(); + tmp32_3 = tcg_const_i32(r3); + tmp32_4 = tcg_const_i32(0); + while (m3) { + if (m3 & 8) { + tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s)); + tcg_gen_trunc_i64_i32(tmp32_2, tmp2); + if (shift) { + tcg_gen_shli_i32(tmp32_2, tmp32_2, shift); + } + tcg_gen_andi_i32(tmp32_1, tmp32_1, mask); + tcg_gen_or_i32(tmp32_1, tmp32_1, tmp32_2); + tcg_gen_or_i32(tmp32_4, tmp32_4, tmp32_2); + tcg_gen_addi_i64(tmp, tmp, 1); + } + m3 = (m3 << 1) & 0xf; + mask = (mask >> 8) | 0xff000000UL; + shift -= 8; + } + store_reg32(r1, tmp32_1); + set_cc_icm(s, tmp32_3, tmp32_4); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i32(tmp32_1); + tcg_temp_free_i32(tmp32_2); + tcg_temp_free_i32(tmp32_3); + tcg_temp_free_i32(tmp32_4); + } else { + /* i.e. env->cc = 0 */ + gen_op_movi_cc(s, 0); + } + break; + case 0xc0: + case 0xc2: + insn = ld_code6(s->pc); + r1 = (insn >> 36) & 0xf; + op = (insn >> 32) & 0xf; + i2 = (int)insn; + switch (opc) { + case 0xc0: + disas_c0(s, op, r1, i2); + break; + case 0xc2: + disas_c2(s, op, r1, i2); + break; + default: + tcg_abort(); + } + break; + case 0xd2: /* MVC D1(L,B1),D2(B2) [SS] */ + case 0xd4: /* NC D1(L,B1),D2(B2) [SS] */ + case 0xd5: /* CLC D1(L,B1),D2(B2) [SS] */ + case 0xd6: /* OC D1(L,B1),D2(B2) [SS] */ + case 0xd7: /* XC D1(L,B1),D2(B2) [SS] */ + case 0xdc: /* TR D1(L,B1),D2(B2) [SS] */ + case 0xf3: /* UNPK D1(L1,B1),D2(L2,B2) [SS] */ + insn = ld_code6(s->pc); + vl = tcg_const_i32((insn >> 32) & 0xff); + b1 = (insn >> 28) & 0xf; + b2 = (insn >> 12) & 0xf; + d1 = (insn >> 16) & 0xfff; + d2 = insn & 0xfff; + tmp = get_address(s, 0, b1, d1); + tmp2 = get_address(s, 0, b2, d2); + switch (opc) { + case 0xd2: + gen_op_mvc(s, (insn >> 32) & 0xff, tmp, tmp2); + break; + case 0xd4: + potential_page_fault(s); + gen_helper_nc(cc_op, vl, tmp, tmp2); + set_cc_static(s); + break; + case 0xd5: + gen_op_clc(s, (insn >> 32) & 0xff, tmp, tmp2); + break; + case 0xd6: + potential_page_fault(s); + gen_helper_oc(cc_op, vl, tmp, tmp2); + set_cc_static(s); + break; + case 0xd7: + potential_page_fault(s); + gen_helper_xc(cc_op, vl, tmp, tmp2); + set_cc_static(s); + break; + case 0xdc: + potential_page_fault(s); + gen_helper_tr(vl, tmp, tmp2); + set_cc_static(s); + break; + case 0xf3: + potential_page_fault(s); + gen_helper_unpk(vl, tmp, tmp2); + break; + default: + tcg_abort(); + } + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + break; +#ifndef CONFIG_USER_ONLY + case 0xda: /* MVCP D1(R1,B1),D2(B2),R3 [SS] */ + case 0xdb: /* MVCS D1(R1,B1),D2(B2),R3 [SS] */ + check_privileged(s, ilc); + potential_page_fault(s); + insn = ld_code6(s->pc); + r1 = (insn >> 36) & 0xf; + r3 = (insn >> 32) & 0xf; + b1 = (insn >> 28) & 0xf; + d1 = (insn >> 16) & 0xfff; + b2 = (insn >> 12) & 0xf; + d2 = insn & 0xfff; + tmp = load_reg(r1); + /* XXX key in r3 */ + tmp2 = get_address(s, 0, b1, d1); + tmp3 = get_address(s, 0, b2, d2); + if (opc == 0xda) { + gen_helper_mvcp(cc_op, tmp, tmp2, tmp3); + } else { + gen_helper_mvcs(cc_op, tmp, tmp2, tmp3); + } + set_cc_static(s); + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tmp2); + tcg_temp_free_i64(tmp3); + break; +#endif + case 0xe3: + insn = ld_code6(s->pc); + debug_insn(insn); + op = insn & 0xff; + r1 = (insn >> 36) & 0xf; + x2 = (insn >> 32) & 0xf; + b2 = (insn >> 28) & 0xf; + d2 = ((int)((((insn >> 16) & 0xfff) + | ((insn << 4) & 0xff000)) << 12)) >> 12; + disas_e3(s, op, r1, x2, b2, d2 ); + break; +#ifndef CONFIG_USER_ONLY + case 0xe5: + /* Test Protection */ + check_privileged(s, ilc); + insn = ld_code6(s->pc); + debug_insn(insn); + disas_e5(s, insn); + break; +#endif + case 0xeb: + insn = ld_code6(s->pc); + debug_insn(insn); + op = insn & 0xff; + r1 = (insn >> 36) & 0xf; + r3 = (insn >> 32) & 0xf; + b2 = (insn >> 28) & 0xf; + d2 = ((int)((((insn >> 16) & 0xfff) + | ((insn << 4) & 0xff000)) << 12)) >> 12; + disas_eb(s, op, r1, r3, b2, d2); + break; + case 0xed: + insn = ld_code6(s->pc); + debug_insn(insn); + op = insn & 0xff; + r1 = (insn >> 36) & 0xf; + x2 = (insn >> 32) & 0xf; + b2 = (insn >> 28) & 0xf; + d2 = (short)((insn >> 16) & 0xfff); + r1b = (insn >> 12) & 0xf; + disas_ed(s, op, r1, x2, b2, d2, r1b); + break; + default: + LOG_DISAS("unimplemented opcode 0x%x\n", opc); + gen_illegal_opcode(s, ilc); + break; + } + + /* Instruction length is encoded in the opcode */ + s->pc += (ilc * 2); +} + +static inline void gen_intermediate_code_internal(CPUState *env, + TranslationBlock *tb, + int search_pc) +{ + DisasContext dc; + target_ulong pc_start; + uint64_t next_page_start; + uint16_t *gen_opc_end; + int j, lj = -1; + int num_insns, max_insns; + CPUBreakpoint *bp; + + pc_start = tb->pc; + + /* 31-bit mode */ + if (!(tb->flags & FLAG_MASK_64)) { + pc_start &= 0x7fffffff; + } + + dc.pc = pc_start; + dc.is_jmp = DISAS_NEXT; + dc.tb = tb; + dc.cc_op = CC_OP_DYNAMIC; + + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; + + next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; + + num_insns = 0; + max_insns = tb->cflags & CF_COUNT_MASK; + if (max_insns == 0) { + max_insns = CF_COUNT_MASK; + } + + gen_icount_start(); + + do { + if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { + QTAILQ_FOREACH(bp, &env->breakpoints, entry) { + if (bp->pc == dc.pc) { + gen_debug(&dc); + break; + } + } + } + if (search_pc) { + j = gen_opc_ptr - gen_opc_buf; + if (lj < j) { + lj++; + while (lj < j) { + gen_opc_instr_start[lj++] = 0; + } + } + gen_opc_pc[lj] = dc.pc; + gen_opc_cc_op[lj] = dc.cc_op; + gen_opc_instr_start[lj] = 1; + gen_opc_icount[lj] = num_insns; + } + if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) { + gen_io_start(); + } +#if defined(S390X_DEBUG_DISAS_VERBOSE) + LOG_DISAS("pc " TARGET_FMT_lx "\n", + dc.pc); +#endif + disas_s390_insn(&dc); + + num_insns++; + if (env->singlestep_enabled) { + gen_debug(&dc); + } + } while (!dc.is_jmp && gen_opc_ptr < gen_opc_end && dc.pc < next_page_start + && num_insns < max_insns && !env->singlestep_enabled + && !singlestep); + + if (!dc.is_jmp) { + update_psw_addr(&dc); + } + + if (singlestep && dc.cc_op != CC_OP_DYNAMIC) { + gen_op_calc_cc(&dc); + } else { + /* next TB starts off with CC_OP_DYNAMIC, so make sure the cc op type + is in env */ + gen_op_set_cc_op(&dc); + } + + if (tb->cflags & CF_LAST_IO) { + gen_io_end(); + } + /* Generate the return instruction */ + if (dc.is_jmp != DISAS_TB_JUMP) { + tcg_gen_exit_tb(0); + } + gen_icount_end(tb, num_insns); + *gen_opc_ptr = INDEX_op_end; + if (search_pc) { + j = gen_opc_ptr - gen_opc_buf; + lj++; + while (lj <= j) { + gen_opc_instr_start[lj++] = 0; + } + } else { + tb->size = dc.pc - pc_start; + tb->icount = num_insns; + } +#if defined(S390X_DEBUG_DISAS) + log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0); + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + qemu_log("IN: %s\n", lookup_symbol(pc_start)); + log_target_disas(pc_start, dc.pc - pc_start, 1); + qemu_log("\n"); + } +#endif +} + +void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) +{ + gen_intermediate_code_internal(env, tb, 0); +} + +void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) +{ + gen_intermediate_code_internal(env, tb, 1); +} + +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) +{ + int cc_op; + env->psw.addr = gen_opc_pc[pc_pos]; + cc_op = gen_opc_cc_op[pc_pos]; + if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) { + env->cc_op = cc_op; + } } diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 789d188..7d7fdde 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -184,7 +184,7 @@ typedef struct CPUSH4State { uint32_t cvr; /* Cache Version Register */ void *intc_handle; - int intr_at_halt; /* SR_BL ignored during sleep */ + int in_sleep; /* SR_BL ignored during sleep */ memory_content *movcal_backup; memory_content **movcal_backup_tail; } CPUSH4State; @@ -194,7 +194,7 @@ int cpu_sh4_exec(CPUSH4State * s); int cpu_sh4_signal_handler(int host_signum, void *pinfo, void *puc); int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault void do_interrupt(CPUSH4State * env); @@ -361,4 +361,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */ } +static inline bool cpu_has_work(CPUState *env) +{ + return env->interrupt_request & CPU_INTERRUPT_HARD; +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->pc = tb->pc; + env->flags = tb->flags; +} + #endif /* _CPU_SH4_H */ diff --git a/target-sh4/exec.h b/target-sh4/exec.h deleted file mode 100644 index 2999c02..0000000 --- a/target-sh4/exec.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SH4 emulation - * - * Copyright (c) 2005 Samuel Tardieu - * - * 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, see . - */ -#ifndef _EXEC_SH4_H -#define _EXEC_SH4_H - -#include "config.h" -#include "dyngen-exec.h" - -register struct CPUSH4State *env asm(AREG0); - -#include "cpu.h" -#include "exec-all.h" - -static inline int cpu_has_work(CPUState *env) -{ - return (env->interrupt_request & CPU_INTERRUPT_HARD); -} - -static inline int cpu_halted(CPUState *env) { - if (!env->halted) - return 0; - if (cpu_has_work(env)) { - env->halted = 0; - env->intr_at_halt = 1; - return 0; - } - return EXCP_HALTED; -} - -#ifndef CONFIG_USER_ONLY -#include "softmmu_exec.h" -#endif - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; - env->flags = tb->flags; -} - -#endif /* _EXEC_SH4_H */ diff --git a/target-sh4/helper.c b/target-sh4/helper.c index d2038bd..5a1e15e 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -24,7 +24,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "hw/sh_intc.h" #if defined(CONFIG_USER_ONLY) @@ -35,7 +34,7 @@ void do_interrupt (CPUState *env) } int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { env->tea = address; env->exception_index = -1; @@ -90,11 +89,11 @@ void do_interrupt(CPUState * env) if (do_exp && env->exception_index != 0x1e0) { env->exception_index = 0x000; /* masked exception -> reset */ } - if (do_irq && !env->intr_at_halt) { + if (do_irq && !env->in_sleep) { return; /* masked */ } - env->intr_at_halt = 0; } + env->in_sleep = 0; if (do_irq) { irq_vector = sh_intc_get_pending_vector(env->intc_handle, @@ -441,7 +440,7 @@ static int get_physical_address(CPUState * env, target_ulong * physical, } int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) + int mmu_idx) { target_ulong physical; int prot, ret, access_type; diff --git a/target-sh4/helper.h b/target-sh4/helper.h index 2e52768..95e3c7c 100644 --- a/target-sh4/helper.h +++ b/target-sh4/helper.h @@ -23,31 +23,31 @@ DEF_HELPER_2(macw, void, i32, i32) DEF_HELPER_1(ld_fpscr, void, i32) -DEF_HELPER_1(fabs_FT, i32, i32) -DEF_HELPER_1(fabs_DT, i64, i64) -DEF_HELPER_2(fadd_FT, i32, i32, i32) -DEF_HELPER_2(fadd_DT, i64, i64, i64) -DEF_HELPER_1(fcnvsd_FT_DT, i64, i32) -DEF_HELPER_1(fcnvds_DT_FT, i32, i64) +DEF_HELPER_1(fabs_FT, f32, f32) +DEF_HELPER_1(fabs_DT, f64, f64) +DEF_HELPER_2(fadd_FT, f32, f32, f32) +DEF_HELPER_2(fadd_DT, f64, f64, f64) +DEF_HELPER_1(fcnvsd_FT_DT, f64, f32) +DEF_HELPER_1(fcnvds_DT_FT, f32, f64) -DEF_HELPER_2(fcmp_eq_FT, void, i32, i32) -DEF_HELPER_2(fcmp_eq_DT, void, i64, i64) -DEF_HELPER_2(fcmp_gt_FT, void, i32, i32) -DEF_HELPER_2(fcmp_gt_DT, void, i64, i64) -DEF_HELPER_2(fdiv_FT, i32, i32, i32) -DEF_HELPER_2(fdiv_DT, i64, i64, i64) -DEF_HELPER_1(float_FT, i32, i32) -DEF_HELPER_1(float_DT, i64, i32) -DEF_HELPER_3(fmac_FT, i32, i32, i32, i32) -DEF_HELPER_2(fmul_FT, i32, i32, i32) -DEF_HELPER_2(fmul_DT, i64, i64, i64) -DEF_HELPER_1(fneg_T, i32, i32) -DEF_HELPER_2(fsub_FT, i32, i32, i32) -DEF_HELPER_2(fsub_DT, i64, i64, i64) -DEF_HELPER_1(fsqrt_FT, i32, i32) -DEF_HELPER_1(fsqrt_DT, i64, i64) -DEF_HELPER_1(ftrc_FT, i32, i32) -DEF_HELPER_1(ftrc_DT, i32, i64) +DEF_HELPER_2(fcmp_eq_FT, void, f32, f32) +DEF_HELPER_2(fcmp_eq_DT, void, f64, f64) +DEF_HELPER_2(fcmp_gt_FT, void, f32, f32) +DEF_HELPER_2(fcmp_gt_DT, void, f64, f64) +DEF_HELPER_2(fdiv_FT, f32, f32, f32) +DEF_HELPER_2(fdiv_DT, f64, f64, f64) +DEF_HELPER_1(float_FT, f32, i32) +DEF_HELPER_1(float_DT, f64, i32) +DEF_HELPER_3(fmac_FT, f32, f32, f32, f32) +DEF_HELPER_2(fmul_FT, f32, f32, f32) +DEF_HELPER_2(fmul_DT, f64, f64, f64) +DEF_HELPER_1(fneg_T, f32, f32) +DEF_HELPER_2(fsub_FT, f32, f32, f32) +DEF_HELPER_2(fsub_DT, f64, f64, f64) +DEF_HELPER_1(fsqrt_FT, f32, f32) +DEF_HELPER_1(fsqrt_DT, f64, f64) +DEF_HELPER_1(ftrc_FT, i32, f32) +DEF_HELPER_1(ftrc_DT, i32, f64) DEF_HELPER_2(fipr, void, i32, i32) DEF_HELPER_1(ftrv, void, i32) diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index 30f9842..b299576 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -18,7 +18,8 @@ */ #include #include -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "helper.h" static void cpu_restore_state_from_retaddr(void *retaddr) @@ -32,12 +33,13 @@ static void cpu_restore_state_from_retaddr(void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, NULL); + cpu_restore_state(tb, env, pc); } } } #ifndef CONFIG_USER_ONLY +#include "softmmu_exec.h" #define MMUSUFFIX _mmu @@ -53,20 +55,19 @@ static void cpu_restore_state_from_retaddr(void *retaddr) #define SHIFT 3 #include "softmmu_template.h" -void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { CPUState *saved_env; int ret; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; - ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + env = env1; + ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx); if (ret) { /* now we have a real cpu fault */ cpu_restore_state_from_retaddr(retaddr); - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } @@ -87,7 +88,7 @@ static inline void raise_exception(int index, void *retaddr) { env->exception_index = index; cpu_restore_state_from_retaddr(retaddr); - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_raise_illegal_instruction(void) @@ -113,15 +114,16 @@ void helper_raise_slot_fpu_disable(void) void helper_debug(void) { env->exception_index = EXCP_DEBUG; - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_sleep(uint32_t next_pc) { env->halted = 1; + env->in_sleep = 1; env->exception_index = EXCP_HLT; env->pc = next_pc; - cpu_loop_exit(); + cpu_loop_exit(env); } void helper_trapa(uint32_t tra) @@ -481,58 +483,43 @@ static void update_fpscr(void *retaddr) if (cause & enable) { cpu_restore_state_from_retaddr(retaddr); env->exception_index = 0x120; - cpu_loop_exit(); + cpu_loop_exit(env); } } } -uint32_t helper_fabs_FT(uint32_t t0) +float32 helper_fabs_FT(float32 t0) { - CPU_FloatU f; - f.l = t0; - f.f = float32_abs(f.f); - return f.l; + return float32_abs(t0); } -uint64_t helper_fabs_DT(uint64_t t0) +float64 helper_fabs_DT(float64 t0) { - CPU_DoubleU d; - d.ll = t0; - d.d = float64_abs(d.d); - return d.ll; + return float64_abs(t0); } -uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1) +float32 helper_fadd_FT(float32 t0, float32 t1) { - CPU_FloatU f0, f1; - f0.l = t0; - f1.l = t1; set_float_exception_flags(0, &env->fp_status); - f0.f = float32_add(f0.f, f1.f, &env->fp_status); + t0 = float32_add(t0, t1, &env->fp_status); update_fpscr(GETPC()); - return f0.l; + return t0; } -uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1) +float64 helper_fadd_DT(float64 t0, float64 t1) { - CPU_DoubleU d0, d1; - d0.ll = t0; - d1.ll = t1; set_float_exception_flags(0, &env->fp_status); - d0.d = float64_add(d0.d, d1.d, &env->fp_status); + t0 = float64_add(t0, t1, &env->fp_status); update_fpscr(GETPC()); - return d0.ll; + return t0; } -void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1) +void helper_fcmp_eq_FT(float32 t0, float32 t1) { - CPU_FloatU f0, f1; int relation; - f0.l = t0; - f1.l = t1; set_float_exception_flags(0, &env->fp_status); - relation = float32_compare(f0.f, f1.f, &env->fp_status); + relation = float32_compare(t0, t1, &env->fp_status); if (unlikely(relation == float_relation_unordered)) { update_fpscr(GETPC()); } else if (relation == float_relation_equal) { @@ -542,15 +529,12 @@ void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1) } } -void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1) +void helper_fcmp_eq_DT(float64 t0, float64 t1) { - CPU_DoubleU d0, d1; int relation; - d0.ll = t0; - d1.ll = t1; set_float_exception_flags(0, &env->fp_status); - relation = float64_compare(d0.d, d1.d, &env->fp_status); + relation = float64_compare(t0, t1, &env->fp_status); if (unlikely(relation == float_relation_unordered)) { update_fpscr(GETPC()); } else if (relation == float_relation_equal) { @@ -560,15 +544,12 @@ void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1) } } -void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1) +void helper_fcmp_gt_FT(float32 t0, float32 t1) { - CPU_FloatU f0, f1; int relation; - f0.l = t0; - f1.l = t1; set_float_exception_flags(0, &env->fp_status); - relation = float32_compare(f0.f, f1.f, &env->fp_status); + relation = float32_compare(t0, t1, &env->fp_status); if (unlikely(relation == float_relation_unordered)) { update_fpscr(GETPC()); } else if (relation == float_relation_greater) { @@ -578,15 +559,12 @@ void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1) } } -void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1) +void helper_fcmp_gt_DT(float64 t0, float64 t1) { - CPU_DoubleU d0, d1; int relation; - d0.ll = t0; - d1.ll = t1; set_float_exception_flags(0, &env->fp_status); - relation = float64_compare(d0.d, d1.d, &env->fp_status); + relation = float64_compare(t0, t1, &env->fp_status); if (unlikely(relation == float_relation_unordered)) { update_fpscr(GETPC()); } else if (relation == float_relation_greater) { @@ -596,176 +574,134 @@ void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1) } } -uint64_t helper_fcnvsd_FT_DT(uint32_t t0) +float64 helper_fcnvsd_FT_DT(float32 t0) { - CPU_DoubleU d; - CPU_FloatU f; - f.l = t0; + float64 ret; set_float_exception_flags(0, &env->fp_status); - d.d = float32_to_float64(f.f, &env->fp_status); + ret = float32_to_float64(t0, &env->fp_status); update_fpscr(GETPC()); - return d.ll; + return ret; } -uint32_t helper_fcnvds_DT_FT(uint64_t t0) +float32 helper_fcnvds_DT_FT(float64 t0) { - CPU_DoubleU d; - CPU_FloatU f; - d.ll = t0; + float32 ret; set_float_exception_flags(0, &env->fp_status); - f.f = float64_to_float32(d.d, &env->fp_status); + ret = float64_to_float32(t0, &env->fp_status); update_fpscr(GETPC()); - return f.l; + return ret; } -uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1) +float32 helper_fdiv_FT(float32 t0, float32 t1) { - CPU_FloatU f0, f1; - f0.l = t0; - f1.l = t1; set_float_exception_flags(0, &env->fp_status); - f0.f = float32_div(f0.f, f1.f, &env->fp_status); + t0 = float32_div(t0, t1, &env->fp_status); update_fpscr(GETPC()); - return f0.l; + return t0; } -uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1) +float64 helper_fdiv_DT(float64 t0, float64 t1) { - CPU_DoubleU d0, d1; - d0.ll = t0; - d1.ll = t1; set_float_exception_flags(0, &env->fp_status); - d0.d = float64_div(d0.d, d1.d, &env->fp_status); + t0 = float64_div(t0, t1, &env->fp_status); update_fpscr(GETPC()); - return d0.ll; + return t0; } -uint32_t helper_float_FT(uint32_t t0) +float32 helper_float_FT(uint32_t t0) { - CPU_FloatU f; - + float32 ret; set_float_exception_flags(0, &env->fp_status); - f.f = int32_to_float32(t0, &env->fp_status); + ret = int32_to_float32(t0, &env->fp_status); update_fpscr(GETPC()); - - return f.l; + return ret; } -uint64_t helper_float_DT(uint32_t t0) +float64 helper_float_DT(uint32_t t0) { - CPU_DoubleU d; + float64 ret; set_float_exception_flags(0, &env->fp_status); - d.d = int32_to_float64(t0, &env->fp_status); + ret = int32_to_float64(t0, &env->fp_status); update_fpscr(GETPC()); - return d.ll; + return ret; } -uint32_t helper_fmac_FT(uint32_t t0, uint32_t t1, uint32_t t2) +float32 helper_fmac_FT(float32 t0, float32 t1, float32 t2) { - CPU_FloatU f0, f1, f2; - f0.l = t0; - f1.l = t1; - f2.l = t2; set_float_exception_flags(0, &env->fp_status); - f0.f = float32_mul(f0.f, f1.f, &env->fp_status); - f0.f = float32_add(f0.f, f2.f, &env->fp_status); + t0 = float32_mul(t0, t1, &env->fp_status); + t0 = float32_add(t0, t2, &env->fp_status); update_fpscr(GETPC()); - - return f0.l; + return t0; } -uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1) +float32 helper_fmul_FT(float32 t0, float32 t1) { - CPU_FloatU f0, f1; - f0.l = t0; - f1.l = t1; set_float_exception_flags(0, &env->fp_status); - f0.f = float32_mul(f0.f, f1.f, &env->fp_status); + t0 = float32_mul(t0, t1, &env->fp_status); update_fpscr(GETPC()); - return f0.l; + return t0; } -uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1) +float64 helper_fmul_DT(float64 t0, float64 t1) { - CPU_DoubleU d0, d1; - d0.ll = t0; - d1.ll = t1; set_float_exception_flags(0, &env->fp_status); - d0.d = float64_mul(d0.d, d1.d, &env->fp_status); + t0 = float64_mul(t0, t1, &env->fp_status); update_fpscr(GETPC()); - - return d0.ll; + return t0; } -uint32_t helper_fneg_T(uint32_t t0) +float32 helper_fneg_T(float32 t0) { - CPU_FloatU f; - f.l = t0; - f.f = float32_chs(f.f); - return f.l; + return float32_chs(t0); } -uint32_t helper_fsqrt_FT(uint32_t t0) +float32 helper_fsqrt_FT(float32 t0) { - CPU_FloatU f; - f.l = t0; set_float_exception_flags(0, &env->fp_status); - f.f = float32_sqrt(f.f, &env->fp_status); + t0 = float32_sqrt(t0, &env->fp_status); update_fpscr(GETPC()); - return f.l; + return t0; } -uint64_t helper_fsqrt_DT(uint64_t t0) +float64 helper_fsqrt_DT(float64 t0) { - CPU_DoubleU d; - d.ll = t0; set_float_exception_flags(0, &env->fp_status); - d.d = float64_sqrt(d.d, &env->fp_status); + t0 = float64_sqrt(t0, &env->fp_status); update_fpscr(GETPC()); - return d.ll; + return t0; } -uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1) +float32 helper_fsub_FT(float32 t0, float32 t1) { - CPU_FloatU f0, f1; - f0.l = t0; - f1.l = t1; set_float_exception_flags(0, &env->fp_status); - f0.f = float32_sub(f0.f, f1.f, &env->fp_status); + t0 = float32_sub(t0, t1, &env->fp_status); update_fpscr(GETPC()); - return f0.l; + return t0; } -uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1) +float64 helper_fsub_DT(float64 t0, float64 t1) { - CPU_DoubleU d0, d1; - - d0.ll = t0; - d1.ll = t1; set_float_exception_flags(0, &env->fp_status); - d0.d = float64_sub(d0.d, d1.d, &env->fp_status); + t0 = float64_sub(t0, t1, &env->fp_status); update_fpscr(GETPC()); - return d0.ll; + return t0; } -uint32_t helper_ftrc_FT(uint32_t t0) +uint32_t helper_ftrc_FT(float32 t0) { - CPU_FloatU f; uint32_t ret; - f.l = t0; set_float_exception_flags(0, &env->fp_status); - ret = float32_to_int32_round_to_zero(f.f, &env->fp_status); + ret = float32_to_int32_round_to_zero(t0, &env->fp_status); update_fpscr(GETPC()); return ret; } -uint32_t helper_ftrc_DT(uint64_t t0) +uint32_t helper_ftrc_DT(float64 t0) { - CPU_DoubleU d; uint32_t ret; - d.ll = t0; set_float_exception_flags(0, &env->fp_status); - ret = float64_to_int32_round_to_zero(d.d, &env->fp_status); + ret = float64_to_int32_round_to_zero(t0, &env->fp_status); update_fpscr(GETPC()); return ret; } diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 58e9b8f..e04a6e0 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -27,7 +27,6 @@ //#define SH4_SINGLE_STEP #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "tcg-op.h" #include "qemu-common.h" @@ -280,7 +279,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model) def = cpu_sh4_find_by_name(cpu_model); if (!def) return NULL; - env = qemu_mallocz(sizeof(CPUSH4State)); + env = g_malloc0(sizeof(CPUSH4State)); env->features = def->features; cpu_exec_init(env); env->movcal_backup_tail = &(env->movcal_backup); @@ -302,7 +301,7 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) /* Use a direct jump if in same page and singlestep not enabled */ tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); - tcg_gen_exit_tb((long) tb + n); + tcg_gen_exit_tb((tcg_target_long)tb + n); } else { tcg_gen_movi_i32(cpu_pc, dest); if (ctx->singlestep_enabled) @@ -1653,18 +1652,10 @@ static void _decode_opc(DisasContext * ctx) } return; case 0x00a3: /* ocbp @Rn */ - { - TCGv dummy = tcg_temp_new(); - tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx); - tcg_temp_free(dummy); - } - return; case 0x00b3: /* ocbwb @Rn */ - { - TCGv dummy = tcg_temp_new(); - tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx); - tcg_temp_free(dummy); - } + /* These instructions are supposed to do nothing in case of + a cache miss. Given that we only partially emulate caches + it is safe to simply ignore them. */ return; case 0x0083: /* pref @Rn */ return; @@ -2069,8 +2060,7 @@ void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb) gen_intermediate_code_internal(env, tb, 1); } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { env->pc = gen_opc_pc[pc_pos]; env->flags = gen_opc_hflags[pc_pos]; diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 320530e..38a7074 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -3,16 +3,17 @@ #include "config.h" #include "qemu-common.h" +#include "bswap.h" #if !defined(TARGET_SPARC64) #define TARGET_LONG_BITS 32 -#define TARGET_FPREGS 32 +#define TARGET_DPREGS 16 #define TARGET_PAGE_BITS 12 /* 4k */ #define TARGET_PHYS_ADDR_SPACE_BITS 36 #define TARGET_VIRT_ADDR_SPACE_BITS 32 #else #define TARGET_LONG_BITS 64 -#define TARGET_FPREGS 64 +#define TARGET_DPREGS 32 #define TARGET_PAGE_BITS 13 /* 8k */ #define TARGET_PHYS_ADDR_SPACE_BITS 41 # ifdef TARGET_ABI32 @@ -290,18 +291,72 @@ enum { #endif #define TTE_VALID_BIT (1ULL << 63) +#define TTE_NFO_BIT (1ULL << 60) #define TTE_USED_BIT (1ULL << 41) #define TTE_LOCKED_BIT (1ULL << 6) +#define TTE_SIDEEFFECT_BIT (1ULL << 3) +#define TTE_PRIV_BIT (1ULL << 2) +#define TTE_W_OK_BIT (1ULL << 1) #define TTE_GLOBAL_BIT (1ULL << 0) #define TTE_IS_VALID(tte) ((tte) & TTE_VALID_BIT) +#define TTE_IS_NFO(tte) ((tte) & TTE_NFO_BIT) #define TTE_IS_USED(tte) ((tte) & TTE_USED_BIT) #define TTE_IS_LOCKED(tte) ((tte) & TTE_LOCKED_BIT) +#define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT) +#define TTE_IS_PRIV(tte) ((tte) & TTE_PRIV_BIT) +#define TTE_IS_W_OK(tte) ((tte) & TTE_W_OK_BIT) #define TTE_IS_GLOBAL(tte) ((tte) & TTE_GLOBAL_BIT) #define TTE_SET_USED(tte) ((tte) |= TTE_USED_BIT) #define TTE_SET_UNUSED(tte) ((tte) &= ~TTE_USED_BIT) +#define TTE_PGSIZE(tte) (((tte) >> 61) & 3ULL) +#define TTE_PA(tte) ((tte) & 0x1ffffffe000ULL) + +#define SFSR_NF_BIT (1ULL << 24) /* JPS1 NoFault */ +#define SFSR_TM_BIT (1ULL << 15) /* JPS1 TLB Miss */ +#define SFSR_FT_VA_IMMU_BIT (1ULL << 13) /* USIIi VA out of range (IMMU) */ +#define SFSR_FT_VA_DMMU_BIT (1ULL << 12) /* USIIi VA out of range (DMMU) */ +#define SFSR_FT_NFO_BIT (1ULL << 11) /* NFO page access */ +#define SFSR_FT_ILL_BIT (1ULL << 10) /* illegal LDA/STA ASI */ +#define SFSR_FT_ATOMIC_BIT (1ULL << 9) /* atomic op on noncacheable area */ +#define SFSR_FT_NF_E_BIT (1ULL << 8) /* NF access on side effect area */ +#define SFSR_FT_PRIV_BIT (1ULL << 7) /* privilege violation */ +#define SFSR_PR_BIT (1ULL << 3) /* privilege mode */ +#define SFSR_WRITE_BIT (1ULL << 2) /* write access mode */ +#define SFSR_OW_BIT (1ULL << 1) /* status overwritten */ +#define SFSR_VALID_BIT (1ULL << 0) /* status valid */ + +#define SFSR_ASI_SHIFT 16 /* 23:16 ASI value */ +#define SFSR_ASI_MASK (0xffULL << SFSR_ASI_SHIFT) +#define SFSR_CT_PRIMARY (0ULL << 4) /* 5:4 context type */ +#define SFSR_CT_SECONDARY (1ULL << 4) +#define SFSR_CT_NUCLEUS (2ULL << 4) +#define SFSR_CT_NOTRANS (3ULL << 4) +#define SFSR_CT_MASK (3ULL << 4) + +/* Leon3 cache control */ + +/* Cache control: emulate the behavior of cache control registers but without + any effect on the emulated */ + +#define CACHE_STATE_MASK 0x3 +#define CACHE_DISABLED 0x0 +#define CACHE_FROZEN 0x1 +#define CACHE_ENABLED 0x3 + +/* Cache Control register fields */ + +#define CACHE_CTRL_IF (1 << 4) /* Instruction Cache Freeze on Interrupt */ +#define CACHE_CTRL_DF (1 << 5) /* Data Cache Freeze on Interrupt */ +#define CACHE_CTRL_DP (1 << 14) /* Data cache flush pending */ +#define CACHE_CTRL_IP (1 << 15) /* Instruction cache flush pending */ +#define CACHE_CTRL_IB (1 << 16) /* Instruction burst fetch */ +#define CACHE_CTRL_FI (1 << 21) /* Flush Instruction cache (Write only) */ +#define CACHE_CTRL_FD (1 << 22) /* Flush Data cache (Write only) */ +#define CACHE_CTRL_DS (1 << 23) /* Data cache snoop enable */ + typedef struct SparcTLBEntry { uint64_t tag; uint64_t tte; @@ -341,7 +396,7 @@ typedef struct CPUSPARCState { uint32_t psr; /* processor state register */ target_ulong fsr; /* FPU state register */ - float32 fpr[TARGET_FPREGS]; /* floating point registers */ + CPU_DoubleU fpr[TARGET_DPREGS]; /* floating point registers */ uint32_t cwp; /* index of current register window (extracted from PSR) */ #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32) @@ -403,11 +458,12 @@ typedef struct CPUSPARCState { uint32_t mmuregs[32]; uint64_t mxccdata[4]; uint64_t mxccregs[8]; + uint32_t mmubpctrv, mmubpctrc, mmubpctrs; + uint64_t mmubpaction; uint64_t mmubpregs[4]; uint64_t prom_addr; #endif /* temporary float registers */ - float64 dt0, dt1; float128 qt0, qt1; float_status fp_status; #if defined(TARGET_SPARC64) @@ -443,30 +499,38 @@ typedef struct CPUSPARCState { sparc_def_t *def; void *irq_manager; - void (*qemu_irq_ack) (void *irq_manager, int intno); + void (*qemu_irq_ack)(CPUState *env, void *irq_manager, int intno); /* Leon3 cache control */ uint32_t cache_control; } CPUSPARCState; #ifndef NO_CPU_IO_DEFS -/* helper.c */ +/* cpu_init.c */ CPUSPARCState *cpu_sparc_init(const char *cpu_model); void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf); +/* mmu_helper.c */ int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw, - int mmu_idx, int is_softmmu); + int mmu_idx); #define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env); +#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) +int target_memory_rw_debug(CPUState *env, target_ulong addr, + uint8_t *buf, int len, int is_write); +#define TARGET_CPU_MEMORY_RW_DEBUG +#endif + + /* translate.c */ void gen_intermediate_code_init(CPUSPARCState *env); /* cpu-exec.c */ int cpu_sparc_exec(CPUSPARCState *s); -/* op_helper.c */ +/* win_helper.c */ target_ulong cpu_get_psr(CPUState *env1); void cpu_put_psr(CPUState *env1, target_ulong val); #ifdef TARGET_SPARC64 @@ -474,11 +538,15 @@ target_ulong cpu_get_ccr(CPUState *env1); void cpu_put_ccr(CPUState *env1, target_ulong val); target_ulong cpu_get_cwp64(CPUState *env1); void cpu_put_cwp64(CPUState *env1, int cwp); +void cpu_change_pstate(CPUState *env1, uint32_t new_pstate); #endif int cpu_cwp_inc(CPUState *env1, int cwp); int cpu_cwp_dec(CPUState *env1, int cwp); void cpu_set_cwp(CPUState *env1, int new_cwp); -void leon3_irq_manager(void *irq_manager, int intno); + +/* int_helper.c */ +void do_interrupt(CPUState *env); +void leon3_irq_manager(CPUState *env, void *irq_manager, int intno); /* sun4m.c, sun4u.c */ void cpu_check_irqs(CPUSPARCState *env); @@ -507,12 +575,14 @@ static inline int tlb_compare_context(const SparcTLBEntry *tlb, /* cpu-exec.c */ #if !defined(CONFIG_USER_ONLY) -void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, - int is_asi, int size); +void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr, + int is_write, int is_exec, int is_asi, int size); +#if defined(TARGET_SPARC64) target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr, int mmu_idx); #endif +#endif int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_init cpu_sparc_init @@ -521,7 +591,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_signal_handler cpu_sparc_signal_handler #define cpu_list sparc_cpu_list -#define CPU_SAVE_VERSION 6 +#define CPU_SAVE_VERSION 7 /* MMU modes definitions */ #if defined (TARGET_SPARC64) @@ -603,17 +673,6 @@ static inline int cpu_pil_allowed(CPUState *env1, int pil) #endif } -static inline int cpu_fpu_enabled(CPUState *env1) -{ -#if defined(CONFIG_USER_ONLY) - return 1; -#elif !defined(TARGET_SPARC64) - return env1->psref; -#else - return ((env1->pstate & PS_PEF) != 0) && ((env1->fprs & FPRS_FEF) != 0); -#endif -} - #if defined(CONFIG_USER_ONLY) static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) { @@ -636,6 +695,9 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit); trap_state* cpu_tsptr(CPUState* env); #endif +#define TB_FLAG_FPU_ENABLED (1 << 4) +#define TB_FLAG_AM_ENABLED (1 << 5) + static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { @@ -643,17 +705,56 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, *cs_base = env->npc; #ifdef TARGET_SPARC64 // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled - *flags = ((env->pstate & PS_AM) << 2) /* 5 */ - | (((env->pstate & PS_PEF) >> 1) /* 3 */ - | ((env->fprs & FPRS_FEF) << 2)) /* 4 */ - | (env->pstate & PS_PRIV) /* 2 */ + *flags = (env->pstate & PS_PRIV) /* 2 */ | ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */ | ((env->tl & 0xff) << 8) | (env->dmmu.mmu_primary_context << 16); /* 16... */ + if (env->pstate & PS_AM) { + *flags |= TB_FLAG_AM_ENABLED; + } + if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF) + && (env->fprs & FPRS_FEF)) { + *flags |= TB_FLAG_FPU_ENABLED; + } #else // FPU enable . Supervisor - *flags = (env->psref << 4) | env->psrs; + *flags = env->psrs; + if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) { + *flags |= TB_FLAG_FPU_ENABLED; + } #endif } +static inline bool tb_fpu_enabled(int tb_flags) +{ +#if defined(CONFIG_USER_ONLY) + return true; +#else + return tb_flags & TB_FLAG_FPU_ENABLED; +#endif +} + +static inline bool tb_am_enabled(int tb_flags) +{ +#ifndef TARGET_SPARC64 + return false; +#else + return tb_flags & TB_FLAG_AM_ENABLED; +#endif +} + +static inline bool cpu_has_work(CPUState *env1) +{ + return (env1->interrupt_request & CPU_INTERRUPT_HARD) && + cpu_interrupts_enabled(env1); +} + +#include "exec-all.h" + +static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +{ + env->pc = tb->pc; + env->npc = tb->cs_base; +} + #endif diff --git a/target-sparc/exec.h b/target-sparc/exec.h deleted file mode 100644 index f811571..0000000 --- a/target-sparc/exec.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef EXEC_SPARC_H -#define EXEC_SPARC_H 1 -#include "config.h" -#include "dyngen-exec.h" - -register struct CPUSPARCState *env asm(AREG0); - -#include "cpu.h" -#include "exec-all.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - -/* op_helper.c */ -void do_interrupt(CPUState *env); - -static inline int cpu_has_work(CPUState *env1) -{ - return (env1->interrupt_request & CPU_INTERRUPT_HARD) && - cpu_interrupts_enabled(env1); -} - - -static inline int cpu_halted(CPUState *env1) { - if (!env1->halted) - return 0; - if (cpu_has_work(env1)) { - env1->halted = 0; - return 0; - } - return EXCP_HALTED; -} - -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; - env->npc = tb->cs_base; -} - -#endif diff --git a/target-sparc/helper.c b/target-sparc/helper.c index b2d4d70..037a72c 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -1,5 +1,5 @@ /* - * sparc helpers + * Misc Sparc helpers * * Copyright (c) 2003-2005 Fabrice Bellard * @@ -16,1531 +16,126 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ -#include -#include -#include -#include -#include -#include #include "cpu.h" -#include "exec-all.h" -#include "qemu-common.h" +#include "host-utils.h" +#include "helper.h" +#include "sysemu.h" -//#define DEBUG_MMU -//#define DEBUG_FEATURES - -#ifdef DEBUG_MMU -#define DPRINTF_MMU(fmt, ...) \ - do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF_MMU(fmt, ...) do {} while (0) -#endif - -static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model); - -/* Sparc MMU emulation */ - -#if defined(CONFIG_USER_ONLY) - -int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, - int mmu_idx, int is_softmmu) +void helper_raise_exception(CPUState *env, int tt) { - if (rw & 2) - env1->exception_index = TT_TFAULT; - else - env1->exception_index = TT_DFAULT; - return 1; + env->exception_index = tt; + cpu_loop_exit(env); } -#else - -#ifndef TARGET_SPARC64 -/* - * Sparc V8 Reference MMU (SRMMU) - */ -static const int access_table[8][8] = { - { 0, 0, 0, 0, 8, 0, 12, 12 }, - { 0, 0, 0, 0, 8, 0, 0, 0 }, - { 8, 8, 0, 0, 0, 8, 12, 12 }, - { 8, 8, 0, 0, 0, 8, 0, 0 }, - { 8, 0, 8, 0, 8, 8, 12, 12 }, - { 8, 0, 8, 0, 8, 0, 8, 0 }, - { 8, 8, 8, 0, 8, 8, 12, 12 }, - { 8, 8, 8, 0, 8, 8, 8, 0 } -}; - -static const int perm_table[2][8] = { - { - PAGE_READ, - PAGE_READ | PAGE_WRITE, - PAGE_READ | PAGE_EXEC, - PAGE_READ | PAGE_WRITE | PAGE_EXEC, - PAGE_EXEC, - PAGE_READ | PAGE_WRITE, - PAGE_READ | PAGE_EXEC, - PAGE_READ | PAGE_WRITE | PAGE_EXEC - }, - { - PAGE_READ, - PAGE_READ | PAGE_WRITE, - PAGE_READ | PAGE_EXEC, - PAGE_READ | PAGE_WRITE | PAGE_EXEC, - PAGE_EXEC, - PAGE_READ, - 0, - 0, - } -}; - -static int get_physical_address(CPUState *env, target_phys_addr_t *physical, - int *prot, int *access_index, - target_ulong address, int rw, int mmu_idx, - target_ulong *page_size) +void helper_debug(CPUState *env) { - int access_perms = 0; - target_phys_addr_t pde_ptr; - uint32_t pde; - int error_code = 0, is_dirty, is_user; - unsigned long page_offset; - - is_user = mmu_idx == MMU_USER_IDX; - - if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ - *page_size = TARGET_PAGE_SIZE; - // Boot mode: instruction fetches are taken from PROM - if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) { - *physical = env->prom_addr | (address & 0x7ffffULL); - *prot = PAGE_READ | PAGE_EXEC; - return 0; - } - *physical = address; - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - return 0; - } - - *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1); - *physical = 0xffffffffffff0000ULL; - - /* SPARC reference MMU table walk: Context table->L1->L2->PTE */ - /* Context base + context number */ - pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); - pde = ldl_phys(pde_ptr); - - /* Ctx pde */ - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - return 1 << 2; - case 2: /* L0 PTE, maybe should not happen? */ - case 3: /* Reserved */ - return 4 << 2; - case 1: /* L0 PDE */ - pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4); - pde = ldl_phys(pde_ptr); - - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - return (1 << 8) | (1 << 2); - case 3: /* Reserved */ - return (1 << 8) | (4 << 2); - case 1: /* L1 PDE */ - pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4); - pde = ldl_phys(pde_ptr); - - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - return (2 << 8) | (1 << 2); - case 3: /* Reserved */ - return (2 << 8) | (4 << 2); - case 1: /* L2 PDE */ - pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4); - pde = ldl_phys(pde_ptr); - - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - return (3 << 8) | (1 << 2); - case 1: /* PDE, should not happen */ - case 3: /* Reserved */ - return (3 << 8) | (4 << 2); - case 2: /* L3 PTE */ - page_offset = (address & TARGET_PAGE_MASK) & - (TARGET_PAGE_SIZE - 1); - } - *page_size = TARGET_PAGE_SIZE; - break; - case 2: /* L2 PTE */ - page_offset = address & 0x3ffff; - *page_size = 0x40000; - } - break; - case 2: /* L1 PTE */ - page_offset = address & 0xffffff; - *page_size = 0x1000000; - } - } - - /* check access */ - access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT; - error_code = access_table[*access_index][access_perms]; - if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user)) - return error_code; - - /* update page modified and dirty bits */ - is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK); - if (!(pde & PG_ACCESSED_MASK) || is_dirty) { - pde |= PG_ACCESSED_MASK; - if (is_dirty) - pde |= PG_MODIFIED_MASK; - stl_phys_notdirty(pde_ptr, pde); - } - - /* the page can be put in the TLB */ - *prot = perm_table[is_user][access_perms]; - if (!(pde & PG_MODIFIED_MASK)) { - /* only set write access if already dirty... otherwise wait - for dirty access */ - *prot &= ~PAGE_WRITE; - } - - /* Even if large ptes, we map only one 4KB page in the cache to - avoid filling it too fast */ - *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset; - return error_code; -} - -/* Perform address translation */ -int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) -{ - target_phys_addr_t paddr; - target_ulong vaddr; - target_ulong page_size; - int error_code = 0, prot, access_index; - - error_code = get_physical_address(env, &paddr, &prot, &access_index, - address, rw, mmu_idx, &page_size); - if (error_code == 0) { - vaddr = address & TARGET_PAGE_MASK; - paddr &= TARGET_PAGE_MASK; -#ifdef DEBUG_MMU - printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr " - TARGET_FMT_lx "\n", address, paddr, vaddr); -#endif - tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size); - return 0; - } - - if (env->mmuregs[3]) /* Fault status register */ - env->mmuregs[3] = 1; /* overflow (not read before another fault) */ - env->mmuregs[3] |= (access_index << 5) | error_code | 2; - env->mmuregs[4] = address; /* Fault address register */ - - if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) { - // No fault mode: if a mapping is available, just override - // permissions. If no mapping is available, redirect accesses to - // neverland. Fake/overridden mappings will be flushed when - // switching to normal mode. - vaddr = address & TARGET_PAGE_MASK; - prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - tlb_set_page(env, vaddr, paddr, prot, mmu_idx, TARGET_PAGE_SIZE); - return 0; - } else { - if (rw & 2) - env->exception_index = TT_TFAULT; - else - env->exception_index = TT_DFAULT; - return 1; - } -} - -target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev) -{ - target_phys_addr_t pde_ptr; - uint32_t pde; - - /* Context base + context number */ - pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) + - (env->mmuregs[2] << 2); - pde = ldl_phys(pde_ptr); - - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - case 2: /* PTE, maybe should not happen? */ - case 3: /* Reserved */ - return 0; - case 1: /* L1 PDE */ - if (mmulev == 3) - return pde; - pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4); - pde = ldl_phys(pde_ptr); - - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - case 3: /* Reserved */ - return 0; - case 2: /* L1 PTE */ - return pde; - case 1: /* L2 PDE */ - if (mmulev == 2) - return pde; - pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4); - pde = ldl_phys(pde_ptr); - - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - case 3: /* Reserved */ - return 0; - case 2: /* L2 PTE */ - return pde; - case 1: /* L3 PDE */ - if (mmulev == 1) - return pde; - pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4); - pde = ldl_phys(pde_ptr); - - switch (pde & PTE_ENTRYTYPE_MASK) { - default: - case 0: /* Invalid */ - case 1: /* PDE, should not happen */ - case 3: /* Reserved */ - return 0; - case 2: /* L3 PTE */ - return pde; - } - } - } - } - return 0; + env->exception_index = EXCP_DEBUG; + cpu_loop_exit(env); } -void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env) -{ - target_ulong va, va1, va2; - unsigned int n, m, o; - target_phys_addr_t pde_ptr, pa; - uint32_t pde; - - pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); - pde = ldl_phys(pde_ptr); - (*cpu_fprintf)(f, "Root ptr: " TARGET_FMT_plx ", ctx: %d\n", - (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]); - for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { - pde = mmu_probe(env, va, 2); - if (pde) { - pa = cpu_get_phys_page_debug(env, va); - (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx - " PDE: " TARGET_FMT_lx "\n", va, pa, pde); - for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { - pde = mmu_probe(env, va1, 1); - if (pde) { - pa = cpu_get_phys_page_debug(env, va1); - (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: " - TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n", - va1, pa, pde); - for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { - pde = mmu_probe(env, va2, 0); - if (pde) { - pa = cpu_get_phys_page_debug(env, va2); - (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: " - TARGET_FMT_plx " PTE: " - TARGET_FMT_lx "\n", - va2, pa, pde); - } - } - } - } - } - } -} - -#else /* !TARGET_SPARC64 */ - -// 41 bit physical address space -static inline target_phys_addr_t ultrasparc_truncate_physical(uint64_t x) -{ - return x & 0x1ffffffffffULL; -} - -/* - * UltraSparc IIi I/DMMUs - */ - -// Returns true if TTE tag is valid and matches virtual address value in context -// requires virtual address mask value calculated from TTE entry size -static inline int ultrasparc_tag_match(SparcTLBEntry *tlb, - uint64_t address, uint64_t context, - target_phys_addr_t *physical) -{ - uint64_t mask; - - switch ((tlb->tte >> 61) & 3) { - default: - case 0x0: // 8k - mask = 0xffffffffffffe000ULL; - break; - case 0x1: // 64k - mask = 0xffffffffffff0000ULL; - break; - case 0x2: // 512k - mask = 0xfffffffffff80000ULL; - break; - case 0x3: // 4M - mask = 0xffffffffffc00000ULL; - break; - } - - // valid, context match, virtual address match? - if (TTE_IS_VALID(tlb->tte) && - (TTE_IS_GLOBAL(tlb->tte) || tlb_compare_context(tlb, context)) - && compare_masked(address, tlb->tag, mask)) - { - // decode physical address - *physical = ((tlb->tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL; - return 1; - } - - return 0; -} - -static int get_physical_address_data(CPUState *env, - target_phys_addr_t *physical, int *prot, - target_ulong address, int rw, int mmu_idx) +#ifdef TARGET_SPARC64 +target_ulong helper_popc(target_ulong val) { - unsigned int i; - uint64_t context; - - int is_user = (mmu_idx == MMU_USER_IDX || - mmu_idx == MMU_USER_SECONDARY_IDX); - - if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */ - *physical = ultrasparc_truncate_physical(address); - *prot = PAGE_READ | PAGE_WRITE; - return 0; - } - - switch(mmu_idx) { - case MMU_USER_IDX: - case MMU_KERNEL_IDX: - context = env->dmmu.mmu_primary_context & 0x1fff; - break; - case MMU_USER_SECONDARY_IDX: - case MMU_KERNEL_SECONDARY_IDX: - context = env->dmmu.mmu_secondary_context & 0x1fff; - break; - case MMU_NUCLEUS_IDX: - default: - context = 0; - break; - } - - for (i = 0; i < 64; i++) { - // ctx match, vaddr match, valid? - if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) { - - uint8_t fault_type = 0; - - // access ok? - if ((env->dtlb[i].tte & 0x4) && is_user) { - fault_type |= 1; /* privilege violation */ - env->exception_index = TT_DFAULT; - - DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64 - " mmu_idx=%d tl=%d\n", - address, context, mmu_idx, env->tl); - } else if (!(env->dtlb[i].tte & 0x2) && (rw == 1)) { - env->exception_index = TT_DPROT; - - DPRINTF_MMU("DPROT at %" PRIx64 " context %" PRIx64 - " mmu_idx=%d tl=%d\n", - address, context, mmu_idx, env->tl); - } else { - *prot = PAGE_READ; - if (env->dtlb[i].tte & 0x2) - *prot |= PAGE_WRITE; - - TTE_SET_USED(env->dtlb[i].tte); - - return 0; - } - - if (env->dmmu.sfsr & 1) /* Fault status register */ - env->dmmu.sfsr = 2; /* overflow (not read before - another fault) */ - - env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1; - - env->dmmu.sfsr |= (fault_type << 7); - - env->dmmu.sfar = address; /* Fault address register */ - - env->dmmu.tag_access = (address & ~0x1fffULL) | context; - - return 1; - } - } - - DPRINTF_MMU("DMISS at %" PRIx64 " context %" PRIx64 "\n", - address, context); - - env->dmmu.tag_access = (address & ~0x1fffULL) | context; - env->exception_index = TT_DMISS; - return 1; + return ctpop64(val); } -static int get_physical_address_code(CPUState *env, - target_phys_addr_t *physical, int *prot, - target_ulong address, int mmu_idx) +void helper_tick_set_count(void *opaque, uint64_t count) { - unsigned int i; - uint64_t context; - - int is_user = (mmu_idx == MMU_USER_IDX || - mmu_idx == MMU_USER_SECONDARY_IDX); - - if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) { - /* IMMU disabled */ - *physical = ultrasparc_truncate_physical(address); - *prot = PAGE_EXEC; - return 0; - } - - if (env->tl == 0) { - /* PRIMARY context */ - context = env->dmmu.mmu_primary_context & 0x1fff; - } else { - /* NUCLEUS context */ - context = 0; - } - - for (i = 0; i < 64; i++) { - // ctx match, vaddr match, valid? - if (ultrasparc_tag_match(&env->itlb[i], - address, context, physical)) { - // access ok? - if ((env->itlb[i].tte & 0x4) && is_user) { - if (env->immu.sfsr) /* Fault status register */ - env->immu.sfsr = 2; /* overflow (not read before - another fault) */ - env->immu.sfsr |= (is_user << 3) | 1; - env->exception_index = TT_TFAULT; - - env->immu.tag_access = (address & ~0x1fffULL) | context; - - DPRINTF_MMU("TFAULT at %" PRIx64 " context %" PRIx64 "\n", - address, context); - - return 1; - } - *prot = PAGE_EXEC; - TTE_SET_USED(env->itlb[i].tte); - return 0; - } - } - - DPRINTF_MMU("TMISS at %" PRIx64 " context %" PRIx64 "\n", - address, context); - - /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */ - env->immu.tag_access = (address & ~0x1fffULL) | context; - env->exception_index = TT_TMISS; - return 1; -} - -static int get_physical_address(CPUState *env, target_phys_addr_t *physical, - int *prot, int *access_index, - target_ulong address, int rw, int mmu_idx, - target_ulong *page_size) -{ - /* ??? We treat everything as a small page, then explicitly flush - everything when an entry is evicted. */ - *page_size = TARGET_PAGE_SIZE; - -#if defined (DEBUG_MMU) - /* safety net to catch wrong softmmu index use from dynamic code */ - if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) { - DPRINTF_MMU("get_physical_address %s tl=%d mmu_idx=%d" - " primary context=%" PRIx64 - " secondary context=%" PRIx64 - " address=%" PRIx64 - "\n", - (rw == 2 ? "CODE" : "DATA"), - env->tl, mmu_idx, - env->dmmu.mmu_primary_context, - env->dmmu.mmu_secondary_context, - address); - } +#if !defined(CONFIG_USER_ONLY) + cpu_tick_set_count(opaque, count); #endif - - if (rw == 2) - return get_physical_address_code(env, physical, prot, address, - mmu_idx); - else - return get_physical_address_data(env, physical, prot, address, rw, - mmu_idx); -} - -/* Perform address translation */ -int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int mmu_idx, int is_softmmu) -{ - target_ulong virt_addr, vaddr; - target_phys_addr_t paddr; - target_ulong page_size; - int error_code = 0, prot, access_index; - - error_code = get_physical_address(env, &paddr, &prot, &access_index, - address, rw, mmu_idx, &page_size); - if (error_code == 0) { - virt_addr = address & TARGET_PAGE_MASK; - vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & - (TARGET_PAGE_SIZE - 1)); - - DPRINTF_MMU("Translate at %" PRIx64 " -> %" PRIx64 "," - " vaddr %" PRIx64 - " mmu_idx=%d" - " tl=%d" - " primary context=%" PRIx64 - " secondary context=%" PRIx64 - "\n", - address, paddr, vaddr, mmu_idx, env->tl, - env->dmmu.mmu_primary_context, - env->dmmu.mmu_secondary_context); - - tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size); - return 0; - } - // XXX - return 1; } -void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env) +uint64_t helper_tick_get_count(void *opaque) { - unsigned int i; - const char *mask; - - (*cpu_fprintf)(f, "MMU contexts: Primary: %" PRId64 ", Secondary: %" - PRId64 "\n", - env->dmmu.mmu_primary_context, - env->dmmu.mmu_secondary_context); - if ((env->lsu & DMMU_E) == 0) { - (*cpu_fprintf)(f, "DMMU disabled\n"); - } else { - (*cpu_fprintf)(f, "DMMU dump\n"); - for (i = 0; i < 64; i++) { - switch ((env->dtlb[i].tte >> 61) & 3) { - default: - case 0x0: - mask = " 8k"; - break; - case 0x1: - mask = " 64k"; - break; - case 0x2: - mask = "512k"; - break; - case 0x3: - mask = " 4M"; - break; - } - if ((env->dtlb[i].tte & 0x8000000000000000ULL) != 0) { - (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %" PRIx64 - ", %s, %s, %s, %s, ctx %" PRId64 " %s\n", - i, - env->dtlb[i].tag & (uint64_t)~0x1fffULL, - env->dtlb[i].tte & (uint64_t)0x1ffffffe000ULL, - mask, - env->dtlb[i].tte & 0x4? "priv": "user", - env->dtlb[i].tte & 0x2? "RW": "RO", - env->dtlb[i].tte & 0x40? "locked": "unlocked", - env->dtlb[i].tag & (uint64_t)0x1fffULL, - TTE_IS_GLOBAL(env->dtlb[i].tte)? - "global" : "local"); - } - } - } - if ((env->lsu & IMMU_E) == 0) { - (*cpu_fprintf)(f, "IMMU disabled\n"); - } else { - (*cpu_fprintf)(f, "IMMU dump\n"); - for (i = 0; i < 64; i++) { - switch ((env->itlb[i].tte >> 61) & 3) { - default: - case 0x0: - mask = " 8k"; - break; - case 0x1: - mask = " 64k"; - break; - case 0x2: - mask = "512k"; - break; - case 0x3: - mask = " 4M"; - break; - } - if ((env->itlb[i].tte & 0x8000000000000000ULL) != 0) { - (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %" PRIx64 - ", %s, %s, %s, ctx %" PRId64 " %s\n", - i, - env->itlb[i].tag & (uint64_t)~0x1fffULL, - env->itlb[i].tte & (uint64_t)0x1ffffffe000ULL, - mask, - env->itlb[i].tte & 0x4? "priv": "user", - env->itlb[i].tte & 0x40? "locked": "unlocked", - env->itlb[i].tag & (uint64_t)0x1fffULL, - TTE_IS_GLOBAL(env->itlb[i].tte)? - "global" : "local"); - } - } - } -} - -#endif /* TARGET_SPARC64 */ -#endif /* !CONFIG_USER_ONLY */ - - #if !defined(CONFIG_USER_ONLY) -target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr, - int mmu_idx) -{ - target_phys_addr_t phys_addr; - target_ulong page_size; - int prot, access_index; - - if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, - mmu_idx, &page_size) != 0) - if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, - 0, mmu_idx, &page_size) != 0) - return -1; - if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED) - return -1; - return phys_addr; -} - -target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) -{ - return cpu_get_phys_page_nofault(env, addr, cpu_mmu_index(env)); -} -#endif - -void cpu_reset(CPUSPARCState *env) -{ - if (qemu_loglevel_mask(CPU_LOG_RESET)) { - qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); - log_cpu_state(env, 0); - } - - tlb_flush(env, 1); - env->cwp = 0; -#ifndef TARGET_SPARC64 - env->wim = 1; -#endif - env->regwptr = env->regbase + (env->cwp * 16); - CC_OP = CC_OP_FLAGS; -#if defined(CONFIG_USER_ONLY) -#ifdef TARGET_SPARC64 - env->cleanwin = env->nwindows - 2; - env->cansave = env->nwindows - 2; - env->pstate = PS_RMO | PS_PEF | PS_IE; - env->asi = 0x82; // Primary no-fault -#endif + return cpu_tick_get_count(opaque); #else -#if !defined(TARGET_SPARC64) - env->psret = 0; - env->psrs = 1; - env->psrps = 1; -#endif -#ifdef TARGET_SPARC64 - env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG; - env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0; - env->tl = env->maxtl; - cpu_tsptr(env)->tt = TT_POWER_ON_RESET; - env->lsu = 0; -#else - env->mmuregs[0] &= ~(MMU_E | MMU_NF); - env->mmuregs[0] |= env->def->mmu_bm; -#endif - env->pc = 0; - env->npc = env->pc + 4; + return 0; #endif - env->cache_control = 0; } -static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model) +void helper_tick_set_limit(void *opaque, uint64_t limit) { - sparc_def_t def1, *def = &def1; - - if (cpu_sparc_find_by_name(def, cpu_model) < 0) - return -1; - - env->def = qemu_mallocz(sizeof(*def)); - memcpy(env->def, def, sizeof(*def)); -#if defined(CONFIG_USER_ONLY) - if ((env->def->features & CPU_FEATURE_FLOAT)) - env->def->features |= CPU_FEATURE_FLOAT128; -#endif - env->cpu_model_str = cpu_model; - env->version = def->iu_version; - env->fsr = def->fpu_version; - env->nwindows = def->nwindows; -#if !defined(TARGET_SPARC64) - env->mmuregs[0] |= def->mmu_version; - cpu_sparc_set_id(env, 0); - env->mxccregs[7] |= def->mxcc_version; -#else - env->mmu_version = def->mmu_version; - env->maxtl = def->maxtl; - env->version |= def->maxtl << 8; - env->version |= def->nwindows - 1; +#if !defined(CONFIG_USER_ONLY) + cpu_tick_set_limit(opaque, limit); #endif - return 0; -} - -static void cpu_sparc_close(CPUSPARCState *env) -{ - free(env->def); - free(env); } +#endif -CPUSPARCState *cpu_sparc_init(const char *cpu_model) +static target_ulong helper_udiv_common(CPUState *env, target_ulong a, + target_ulong b, int cc) { - CPUSPARCState *env; + int overflow = 0; + uint64_t x0; + uint32_t x1; - env = qemu_mallocz(sizeof(CPUSPARCState)); - cpu_exec_init(env); + x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); + x1 = (b & 0xffffffff); - gen_intermediate_code_init(env); + if (x1 == 0) { + helper_raise_exception(env, TT_DIV_ZERO); + } - if (cpu_sparc_register(env, cpu_model) < 0) { - cpu_sparc_close(env); - return NULL; + x0 = x0 / x1; + if (x0 > 0xffffffff) { + x0 = 0xffffffff; + overflow = 1; } - qemu_init_vcpu(env); - return env; + if (cc) { + env->cc_dst = x0; + env->cc_src2 = overflow; + env->cc_op = CC_OP_DIV; + } + return x0; } -void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu) +target_ulong helper_udiv(CPUState *env, target_ulong a, target_ulong b) { -#if !defined(TARGET_SPARC64) - env->mxccregs[7] = ((cpu + 8) & 0xf) << 24; -#endif + return helper_udiv_common(env, a, b, 0); } -static const sparc_def_t sparc_defs[] = { -#ifdef TARGET_SPARC64 - { - .name = "Fujitsu Sparc64", - .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 4, - .maxtl = 4, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Fujitsu Sparc64 III", - .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 5, - .maxtl = 4, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Fujitsu Sparc64 IV", - .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Fujitsu Sparc64 V", - .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI UltraSparc I", - .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI UltraSparc II", - .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI UltraSparc IIi", - .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI UltraSparc IIe", - .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Sun UltraSparc III", - .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Sun UltraSparc III Cu", - .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_3, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Sun UltraSparc IIIi", - .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Sun UltraSparc IV", - .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_4, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Sun UltraSparc IV+", - .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT, - }, - { - .name = "Sun UltraSparc IIIi+", - .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_3, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Sun UltraSparc T1", - // defined in sparc_ifu_fdp.v and ctu.h - .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_sun4v, - .nwindows = 8, - .maxtl = 6, - .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT - | CPU_FEATURE_GL, - }, - { - .name = "Sun UltraSparc T2", - // defined in tlu_asi_ctl.v and n2_revid_cust.v - .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_sun4v, - .nwindows = 8, - .maxtl = 6, - .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT - | CPU_FEATURE_GL, - }, - { - .name = "NEC UltraSparc I", - .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)), - .fpu_version = 0x00000000, - .mmu_version = mmu_us_12, - .nwindows = 8, - .maxtl = 5, - .features = CPU_DEFAULT_FEATURES, - }, -#else - { - .name = "Fujitsu MB86900", - .iu_version = 0x00 << 24, /* Impl 0, ver 0 */ - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */ - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 7, - .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD, - }, - { - .name = "Fujitsu MB86904", - .iu_version = 0x04 << 24, /* Impl 0, ver 4 */ - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */ - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x00ffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0x00ffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Fujitsu MB86907", - .iu_version = 0x05 << 24, /* Impl 0, ver 5 */ - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */ - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "LSI L64811", - .iu_version = 0x10 << 24, /* Impl 1, ver 0 */ - .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | - CPU_FEATURE_FSMULD, - }, - { - .name = "Cypress CY7C601", - .iu_version = 0x11 << 24, /* Impl 1, ver 1 */ - .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | - CPU_FEATURE_FSMULD, - }, - { - .name = "Cypress CY7C611", - .iu_version = 0x13 << 24, /* Impl 1, ver 3 */ - .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | - CPU_FEATURE_FSMULD, - }, - { - .name = "TI MicroSparc I", - .iu_version = 0x41000000, - .fpu_version = 4 << 17, - .mmu_version = 0x41000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0x0000003f, - .nwindows = 7, - .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL | - CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | - CPU_FEATURE_FMUL, - }, - { - .name = "TI MicroSparc II", - .iu_version = 0x42000000, - .fpu_version = 4 << 17, - .mmu_version = 0x02000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x00ffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0x00ffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI MicroSparc IIep", - .iu_version = 0x42000000, - .fpu_version = 4 << 17, - .mmu_version = 0x04000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x00ffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016bff, - .mmu_trcr_mask = 0x00ffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI SuperSparc 40", // STP1020NPGA - .iu_version = 0x41000000, // SuperSPARC 2.x - .fpu_version = 0 << 17, - .mmu_version = 0x00000800, // SuperSPARC 2.x, no MXCC - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI SuperSparc 50", // STP1020PGA - .iu_version = 0x40000000, // SuperSPARC 3.x - .fpu_version = 0 << 17, - .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI SuperSparc 51", - .iu_version = 0x40000000, // SuperSPARC 3.x - .fpu_version = 0 << 17, - .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .mxcc_version = 0x00000104, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI SuperSparc 60", // STP1020APGA - .iu_version = 0x40000000, // SuperSPARC 3.x - .fpu_version = 0 << 17, - .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI SuperSparc 61", - .iu_version = 0x44000000, // SuperSPARC 3.x - .fpu_version = 0 << 17, - .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .mxcc_version = 0x00000104, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "TI SuperSparc II", - .iu_version = 0x40000000, // SuperSPARC II 1.x - .fpu_version = 0 << 17, - .mmu_version = 0x08000000, // SuperSPARC II 1.x, MXCC - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .mxcc_version = 0x00000104, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Ross RT625", - .iu_version = 0x1e000000, - .fpu_version = 1 << 17, - .mmu_version = 0x1e000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "Ross RT620", - .iu_version = 0x1f000000, - .fpu_version = 1 << 17, - .mmu_version = 0x1f000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "BIT B5010", - .iu_version = 0x20000000, - .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */ - .mmu_version = 0x20000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | - CPU_FEATURE_FSMULD, - }, - { - .name = "Matsushita MN10501", - .iu_version = 0x50000000, - .fpu_version = 0 << 17, - .mmu_version = 0x50000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT | - CPU_FEATURE_FSMULD, - }, - { - .name = "Weitek W8601", - .iu_version = 0x90 << 24, /* Impl 9, ver 0 */ - .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, - }, - { - .name = "LEON2", - .iu_version = 0xf2000000, - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0xf2000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN, - }, - { - .name = "LEON3", - .iu_version = 0xf3000000, - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0xf3000000, - .mmu_bm = 0x00000000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - .nwindows = 8, - .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN | - CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL, - }, -#endif -}; - -static const char * const feature_name[] = { - "float", - "float128", - "swap", - "mul", - "div", - "flush", - "fsqrt", - "fmul", - "vis1", - "vis2", - "fsmuld", - "hypv", - "cmt", - "gl", -}; - -static void print_features(FILE *f, fprintf_function cpu_fprintf, - uint32_t features, const char *prefix) +target_ulong helper_udiv_cc(CPUState *env, target_ulong a, target_ulong b) { - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(feature_name); i++) - if (feature_name[i] && (features & (1 << i))) { - if (prefix) - (*cpu_fprintf)(f, "%s", prefix); - (*cpu_fprintf)(f, "%s ", feature_name[i]); - } + return helper_udiv_common(env, a, b, 1); } -static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features) +static target_ulong helper_sdiv_common(CPUState *env, target_ulong a, + target_ulong b, int cc) { - unsigned int i; + int overflow = 0; + int64_t x0; + int32_t x1; - for (i = 0; i < ARRAY_SIZE(feature_name); i++) - if (feature_name[i] && !strcmp(flagname, feature_name[i])) { - *features |= 1 << i; - return; - } - fprintf(stderr, "CPU feature %s not found\n", flagname); -} - -static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model) -{ - unsigned int i; - const sparc_def_t *def = NULL; - char *s = strdup(cpu_model); - char *featurestr, *name = strtok(s, ","); - uint32_t plus_features = 0; - uint32_t minus_features = 0; - uint64_t iu_version; - uint32_t fpu_version, mmu_version, nwindows; + x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); + x1 = (b & 0xffffffff); - for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { - if (strcasecmp(name, sparc_defs[i].name) == 0) { - def = &sparc_defs[i]; - } + if (x1 == 0) { + helper_raise_exception(env, TT_DIV_ZERO); } - if (!def) - goto error; - memcpy(cpu_def, def, sizeof(*def)); - - featurestr = strtok(NULL, ","); - while (featurestr) { - char *val; - - if (featurestr[0] == '+') { - add_flagname_to_bitmaps(featurestr + 1, &plus_features); - } else if (featurestr[0] == '-') { - add_flagname_to_bitmaps(featurestr + 1, &minus_features); - } else if ((val = strchr(featurestr, '='))) { - *val = 0; val++; - if (!strcmp(featurestr, "iu_version")) { - char *err; - - iu_version = strtoll(val, &err, 0); - if (!*val || *err) { - fprintf(stderr, "bad numerical value %s\n", val); - goto error; - } - cpu_def->iu_version = iu_version; -#ifdef DEBUG_FEATURES - fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version); -#endif - } else if (!strcmp(featurestr, "fpu_version")) { - char *err; - - fpu_version = strtol(val, &err, 0); - if (!*val || *err) { - fprintf(stderr, "bad numerical value %s\n", val); - goto error; - } - cpu_def->fpu_version = fpu_version; -#ifdef DEBUG_FEATURES - fprintf(stderr, "fpu_version %x\n", fpu_version); -#endif - } else if (!strcmp(featurestr, "mmu_version")) { - char *err; - mmu_version = strtol(val, &err, 0); - if (!*val || *err) { - fprintf(stderr, "bad numerical value %s\n", val); - goto error; - } - cpu_def->mmu_version = mmu_version; -#ifdef DEBUG_FEATURES - fprintf(stderr, "mmu_version %x\n", mmu_version); -#endif - } else if (!strcmp(featurestr, "nwindows")) { - char *err; - - nwindows = strtol(val, &err, 0); - if (!*val || *err || nwindows > MAX_NWINDOWS || - nwindows < MIN_NWINDOWS) { - fprintf(stderr, "bad numerical value %s\n", val); - goto error; - } - cpu_def->nwindows = nwindows; -#ifdef DEBUG_FEATURES - fprintf(stderr, "nwindows %d\n", nwindows); -#endif - } else { - fprintf(stderr, "unrecognized feature %s\n", featurestr); - goto error; - } - } else { - fprintf(stderr, "feature string `%s' not in format " - "(+feature|-feature|feature=xyz)\n", featurestr); - goto error; - } - featurestr = strtok(NULL, ","); + x0 = x0 / x1; + if ((int32_t) x0 != x0) { + x0 = x0 < 0 ? 0x80000000 : 0x7fffffff; + overflow = 1; } - cpu_def->features |= plus_features; - cpu_def->features &= ~minus_features; -#ifdef DEBUG_FEATURES - print_features(stderr, fprintf, cpu_def->features, NULL); -#endif - free(s); - return 0; - - error: - free(s); - return -1; -} - -void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf) -{ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { - (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ", - sparc_defs[i].name, - sparc_defs[i].iu_version, - sparc_defs[i].fpu_version, - sparc_defs[i].mmu_version, - sparc_defs[i].nwindows); - print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES & - ~sparc_defs[i].features, "-"); - print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES & - sparc_defs[i].features, "+"); - (*cpu_fprintf)(f, "\n"); + if (cc) { + env->cc_dst = x0; + env->cc_src2 = overflow; + env->cc_op = CC_OP_DIV; } - (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): "); - print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL); - (*cpu_fprintf)(f, "\n"); - (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): "); - print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL); - (*cpu_fprintf)(f, "\n"); - (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version " - "fpu_version mmu_version nwindows\n"); + return x0; } -static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf, - uint32_t cc) +target_ulong helper_sdiv(CPUState *env, target_ulong a, target_ulong b) { - cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG? 'N' : '-', - cc & PSR_ZERO? 'Z' : '-', cc & PSR_OVF? 'V' : '-', - cc & PSR_CARRY? 'C' : '-'); + return helper_sdiv_common(env, a, b, 0); } -#ifdef TARGET_SPARC64 -#define REGS_PER_LINE 4 -#else -#define REGS_PER_LINE 8 -#endif - -void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, - int flags) +target_ulong helper_sdiv_cc(CPUState *env, target_ulong a, target_ulong b) { - int i, x; - - cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, - env->npc); - cpu_fprintf(f, "General Registers:\n"); - - for (i = 0; i < 8; i++) { - if (i % REGS_PER_LINE == 0) { - cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1); - } - cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]); - if (i % REGS_PER_LINE == REGS_PER_LINE - 1) { - cpu_fprintf(f, "\n"); - } - } - cpu_fprintf(f, "\nCurrent Register Window:\n"); - for (x = 0; x < 3; x++) { - for (i = 0; i < 8; i++) { - if (i % REGS_PER_LINE == 0) { - cpu_fprintf(f, "%%%c%d-%d: ", - x == 0 ? 'o' : (x == 1 ? 'l' : 'i'), - i, i + REGS_PER_LINE - 1); - } - cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]); - if (i % REGS_PER_LINE == REGS_PER_LINE - 1) { - cpu_fprintf(f, "\n"); - } - } - } - cpu_fprintf(f, "\nFloating Point Registers:\n"); - for (i = 0; i < TARGET_FPREGS; i++) { - if ((i & 3) == 0) - cpu_fprintf(f, "%%f%02d:", i); - cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]); - if ((i & 3) == 3) - cpu_fprintf(f, "\n"); - } -#ifdef TARGET_SPARC64 - cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate, - (unsigned)cpu_get_ccr(env)); - cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT); - cpu_fprintf(f, " xcc: "); - cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4)); - cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl, - env->psrpil); - cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d " - "cleanwin: %d cwp: %d\n", - env->cansave, env->canrestore, env->otherwin, env->wstate, - env->cleanwin, env->nwindows - 1 - env->cwp); - cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: " - TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs); -#else - cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env)); - cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env)); - cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs? 'S' : '-', - env->psrps? 'P' : '-', env->psret? 'E' : '-', - env->wim); - cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n", - env->fsr, env->y); -#endif + return helper_sdiv_common(env, a, b, 1); } diff --git a/target-sparc/helper.h b/target-sparc/helper.h index 12e8557..1f67b08 100644 --- a/target-sparc/helper.h +++ b/target-sparc/helper.h @@ -1,166 +1,170 @@ #include "def-helper.h" #ifndef TARGET_SPARC64 -DEF_HELPER_0(rett, void) -DEF_HELPER_1(wrpsr, void, tl) -DEF_HELPER_0(rdpsr, tl) +DEF_HELPER_1(rett, void, env) +DEF_HELPER_2(wrpsr, void, env, tl) +DEF_HELPER_1(rdpsr, tl, env) #else -DEF_HELPER_1(wrpil, void, tl) -DEF_HELPER_1(wrpstate, void, tl) -DEF_HELPER_0(done, void) -DEF_HELPER_0(retry, void) -DEF_HELPER_0(flushw, void) -DEF_HELPER_0(saved, void) -DEF_HELPER_0(restored, void) -DEF_HELPER_0(rdccr, tl) -DEF_HELPER_1(wrccr, void, tl) -DEF_HELPER_0(rdcwp, tl) -DEF_HELPER_1(wrcwp, void, tl) -DEF_HELPER_2(array8, tl, tl, tl) -DEF_HELPER_2(alignaddr, tl, tl, tl) +DEF_HELPER_2(wrpil, void, env, tl) +DEF_HELPER_2(wrpstate, void, env, tl) +DEF_HELPER_1(done, void, env) +DEF_HELPER_1(retry, void, env) +DEF_HELPER_1(flushw, void, env) +DEF_HELPER_1(saved, void, env) +DEF_HELPER_1(restored, void, env) +DEF_HELPER_1(rdccr, tl, env) +DEF_HELPER_2(wrccr, void, env, tl) +DEF_HELPER_1(rdcwp, tl, env) +DEF_HELPER_2(wrcwp, void, env, tl) +DEF_HELPER_FLAGS_2(array8, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl) DEF_HELPER_1(popc, tl, tl) DEF_HELPER_3(ldda_asi, void, tl, int, int) DEF_HELPER_4(ldf_asi, void, tl, int, int, int) DEF_HELPER_4(stf_asi, void, tl, int, int, int) DEF_HELPER_4(cas_asi, tl, tl, tl, tl, i32) DEF_HELPER_4(casx_asi, tl, tl, tl, tl, i32) -DEF_HELPER_1(set_softint, void, i64) -DEF_HELPER_1(clear_softint, void, i64) -DEF_HELPER_1(write_softint, void, i64) +DEF_HELPER_2(set_softint, void, env, i64) +DEF_HELPER_2(clear_softint, void, env, i64) +DEF_HELPER_2(write_softint, void, env, i64) DEF_HELPER_2(tick_set_count, void, ptr, i64) DEF_HELPER_1(tick_get_count, i64, ptr) DEF_HELPER_2(tick_set_limit, void, ptr, i64) #endif DEF_HELPER_2(check_align, void, tl, i32) -DEF_HELPER_0(debug, void) -DEF_HELPER_0(save, void) -DEF_HELPER_0(restore, void) -DEF_HELPER_1(flush, void, tl) -DEF_HELPER_2(udiv, tl, tl, tl) -DEF_HELPER_2(udiv_cc, tl, tl, tl) -DEF_HELPER_2(sdiv, tl, tl, tl) -DEF_HELPER_2(sdiv_cc, tl, tl, tl) -DEF_HELPER_2(stdf, void, tl, int) -DEF_HELPER_2(lddf, void, tl, int) +DEF_HELPER_1(debug, void, env) +DEF_HELPER_1(save, void, env) +DEF_HELPER_1(restore, void, env) +DEF_HELPER_3(udiv, tl, env, tl, tl) +DEF_HELPER_3(udiv_cc, tl, env, tl, tl) +DEF_HELPER_3(sdiv, tl, env, tl, tl) +DEF_HELPER_3(sdiv_cc, tl, env, tl, tl) DEF_HELPER_2(ldqf, void, tl, int) DEF_HELPER_2(stqf, void, tl, int) #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) DEF_HELPER_4(ld_asi, i64, tl, int, int, int) DEF_HELPER_4(st_asi, void, tl, i64, int, int) #endif -DEF_HELPER_1(ldfsr, void, i32) -DEF_HELPER_0(check_ieee_exceptions, void) -DEF_HELPER_0(clear_float_exceptions, void) -DEF_HELPER_1(fabss, f32, f32) -DEF_HELPER_1(fsqrts, f32, f32) -DEF_HELPER_0(fsqrtd, void) -DEF_HELPER_2(fcmps, void, f32, f32) -DEF_HELPER_0(fcmpd, void) -DEF_HELPER_2(fcmpes, void, f32, f32) -DEF_HELPER_0(fcmped, void) -DEF_HELPER_0(fsqrtq, void) -DEF_HELPER_0(fcmpq, void) -DEF_HELPER_0(fcmpeq, void) +DEF_HELPER_2(ldfsr, void, env, i32) +DEF_HELPER_FLAGS_1(fabss, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32) +DEF_HELPER_2(fsqrts, f32, env, f32) +DEF_HELPER_2(fsqrtd, f64, env, f64) +DEF_HELPER_3(fcmps, void, env, f32, f32) +DEF_HELPER_3(fcmpd, void, env, f64, f64) +DEF_HELPER_3(fcmpes, void, env, f32, f32) +DEF_HELPER_3(fcmped, void, env, f64, f64) +DEF_HELPER_1(fsqrtq, void, env) +DEF_HELPER_1(fcmpq, void, env) +DEF_HELPER_1(fcmpeq, void, env) #ifdef TARGET_SPARC64 -DEF_HELPER_1(ldxfsr, void, i64) -DEF_HELPER_0(fabsd, void) -DEF_HELPER_2(fcmps_fcc1, void, f32, f32) -DEF_HELPER_2(fcmps_fcc2, void, f32, f32) -DEF_HELPER_2(fcmps_fcc3, void, f32, f32) -DEF_HELPER_0(fcmpd_fcc1, void) -DEF_HELPER_0(fcmpd_fcc2, void) -DEF_HELPER_0(fcmpd_fcc3, void) -DEF_HELPER_2(fcmpes_fcc1, void, f32, f32) -DEF_HELPER_2(fcmpes_fcc2, void, f32, f32) -DEF_HELPER_2(fcmpes_fcc3, void, f32, f32) -DEF_HELPER_0(fcmped_fcc1, void) -DEF_HELPER_0(fcmped_fcc2, void) -DEF_HELPER_0(fcmped_fcc3, void) -DEF_HELPER_0(fabsq, void) -DEF_HELPER_0(fcmpq_fcc1, void) -DEF_HELPER_0(fcmpq_fcc2, void) -DEF_HELPER_0(fcmpq_fcc3, void) -DEF_HELPER_0(fcmpeq_fcc1, void) -DEF_HELPER_0(fcmpeq_fcc2, void) -DEF_HELPER_0(fcmpeq_fcc3, void) +DEF_HELPER_2(ldxfsr, void, env, i64) +DEF_HELPER_FLAGS_1(fabsd, TCG_CALL_CONST | TCG_CALL_PURE, f64, f64) +DEF_HELPER_3(fcmps_fcc1, void, env, f32, f32) +DEF_HELPER_3(fcmps_fcc2, void, env, f32, f32) +DEF_HELPER_3(fcmps_fcc3, void, env, f32, f32) +DEF_HELPER_3(fcmpd_fcc1, void, env, f64, f64) +DEF_HELPER_3(fcmpd_fcc2, void, env, f64, f64) +DEF_HELPER_3(fcmpd_fcc3, void, env, f64, f64) +DEF_HELPER_3(fcmpes_fcc1, void, env, f32, f32) +DEF_HELPER_3(fcmpes_fcc2, void, env, f32, f32) +DEF_HELPER_3(fcmpes_fcc3, void, env, f32, f32) +DEF_HELPER_3(fcmped_fcc1, void, env, f64, f64) +DEF_HELPER_3(fcmped_fcc2, void, env, f64, f64) +DEF_HELPER_3(fcmped_fcc3, void, env, f64, f64) +DEF_HELPER_1(fabsq, void, env) +DEF_HELPER_1(fcmpq_fcc1, void, env) +DEF_HELPER_1(fcmpq_fcc2, void, env) +DEF_HELPER_1(fcmpq_fcc3, void, env) +DEF_HELPER_1(fcmpeq_fcc1, void, env) +DEF_HELPER_1(fcmpeq_fcc2, void, env) +DEF_HELPER_1(fcmpeq_fcc3, void, env) #endif -DEF_HELPER_1(raise_exception, void, int) -DEF_HELPER_0(shutdown, void) -#define F_HELPER_0_0(name) DEF_HELPER_0(f ## name, void) -#define F_HELPER_DQ_0_0(name) \ - F_HELPER_0_0(name ## d); \ - F_HELPER_0_0(name ## q) +DEF_HELPER_2(raise_exception, void, env, int) +#define F_HELPER_0_1(name) DEF_HELPER_1(f ## name, void, env) -F_HELPER_DQ_0_0(add); -F_HELPER_DQ_0_0(sub); -F_HELPER_DQ_0_0(mul); -F_HELPER_DQ_0_0(div); +DEF_HELPER_3(faddd, f64, env, f64, f64) +DEF_HELPER_3(fsubd, f64, env, f64, f64) +DEF_HELPER_3(fmuld, f64, env, f64, f64) +DEF_HELPER_3(fdivd, f64, env, f64, f64) +F_HELPER_0_1(addq) +F_HELPER_0_1(subq) +F_HELPER_0_1(mulq) +F_HELPER_0_1(divq) -DEF_HELPER_2(fadds, f32, f32, f32) -DEF_HELPER_2(fsubs, f32, f32, f32) -DEF_HELPER_2(fmuls, f32, f32, f32) -DEF_HELPER_2(fdivs, f32, f32, f32) +DEF_HELPER_3(fadds, f32, env, f32, f32) +DEF_HELPER_3(fsubs, f32, env, f32, f32) +DEF_HELPER_3(fmuls, f32, env, f32, f32) +DEF_HELPER_3(fdivs, f32, env, f32, f32) -DEF_HELPER_2(fsmuld, void, f32, f32) -F_HELPER_0_0(dmulq); +DEF_HELPER_3(fsmuld, f64, env, f32, f32) +DEF_HELPER_3(fdmulq, void, env, f64, f64); -DEF_HELPER_1(fnegs, f32, f32) -DEF_HELPER_1(fitod, void, s32) -DEF_HELPER_1(fitoq, void, s32) +DEF_HELPER_FLAGS_1(fnegs, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32) +DEF_HELPER_2(fitod, f64, env, s32) +DEF_HELPER_2(fitoq, void, env, s32) -DEF_HELPER_1(fitos, f32, s32) +DEF_HELPER_2(fitos, f32, env, s32) #ifdef TARGET_SPARC64 -DEF_HELPER_0(fnegd, void) -DEF_HELPER_0(fnegq, void) -DEF_HELPER_0(fxtos, i32) -F_HELPER_DQ_0_0(xto); +DEF_HELPER_FLAGS_1(fnegd, TCG_CALL_CONST | TCG_CALL_PURE, f64, f64) +DEF_HELPER_1(fnegq, void, env) +DEF_HELPER_2(fxtos, f32, env, s64) +DEF_HELPER_2(fxtod, f64, env, s64) +DEF_HELPER_2(fxtoq, void, env, s64) #endif -DEF_HELPER_0(fdtos, f32) -DEF_HELPER_1(fstod, void, f32) -DEF_HELPER_0(fqtos, f32) -DEF_HELPER_1(fstoq, void, f32) -F_HELPER_0_0(qtod); -F_HELPER_0_0(dtoq); -DEF_HELPER_1(fstoi, s32, f32) -DEF_HELPER_0(fdtoi, s32) -DEF_HELPER_0(fqtoi, s32) +DEF_HELPER_2(fdtos, f32, env, f64) +DEF_HELPER_2(fstod, f64, env, f32) +DEF_HELPER_1(fqtos, f32, env) +DEF_HELPER_2(fstoq, void, env, f32) +DEF_HELPER_1(fqtod, f64, env) +DEF_HELPER_2(fdtoq, void, env, f64) +DEF_HELPER_2(fstoi, s32, env, f32) +DEF_HELPER_2(fdtoi, s32, env, f64) +DEF_HELPER_1(fqtoi, s32, env) #ifdef TARGET_SPARC64 -DEF_HELPER_1(fstox, void, i32) -F_HELPER_0_0(dtox); -F_HELPER_0_0(qtox); -F_HELPER_0_0(aligndata); +DEF_HELPER_2(fstox, s64, env, f32) +DEF_HELPER_2(fdtox, s64, env, f64) +DEF_HELPER_1(fqtox, s64, env) -F_HELPER_0_0(pmerge); -F_HELPER_0_0(mul8x16); -F_HELPER_0_0(mul8x16al); -F_HELPER_0_0(mul8x16au); -F_HELPER_0_0(mul8sux16); -F_HELPER_0_0(mul8ulx16); -F_HELPER_0_0(muld8sux16); -F_HELPER_0_0(muld8ulx16); -F_HELPER_0_0(expand); -#define VIS_HELPER(name) \ - F_HELPER_0_0(name##16); \ - DEF_HELPER_2(f ## name ## 16s, i32, i32, i32) \ - F_HELPER_0_0(name##32); \ - DEF_HELPER_2(f ## name ## 32s, i32, i32, i32) +DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmul8x16al, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmul8x16au, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmul8sux16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmul8ulx16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmuld8sux16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fmuld8ulx16, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(fexpand, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_3(pdist, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64, i64) +DEF_HELPER_FLAGS_2(fpack16, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64, i64) +DEF_HELPER_FLAGS_3(fpack32, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64, i64) +DEF_HELPER_FLAGS_2(fpackfix, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64, i64) +DEF_HELPER_FLAGS_3(bshuffle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64, i64) +#define VIS_HELPER(name) \ + DEF_HELPER_FLAGS_2(f ## name ## 16, TCG_CALL_CONST | TCG_CALL_PURE, \ + i64, i64, i64) \ + DEF_HELPER_FLAGS_2(f ## name ## 16s, TCG_CALL_CONST | TCG_CALL_PURE, \ + i32, i32, i32) \ + DEF_HELPER_FLAGS_2(f ## name ## 32, TCG_CALL_CONST | TCG_CALL_PURE, \ + i64, i64, i64) \ + DEF_HELPER_FLAGS_2(f ## name ## 32s, TCG_CALL_CONST | TCG_CALL_PURE, \ + i32, i32, i32) VIS_HELPER(padd); VIS_HELPER(psub); -#define VIS_CMPHELPER(name) \ - F_HELPER_0_0(name##16); \ - F_HELPER_0_0(name##32) +#define VIS_CMPHELPER(name) \ + DEF_HELPER_FLAGS_2(f##name##16, TCG_CALL_CONST | TCG_CALL_PURE, \ + i64, i64, i64) \ + DEF_HELPER_FLAGS_2(f##name##32, TCG_CALL_CONST | TCG_CALL_PURE, \ + i64, i64, i64) VIS_CMPHELPER(cmpgt); VIS_CMPHELPER(cmpeq); VIS_CMPHELPER(cmple); VIS_CMPHELPER(cmpne); #endif -#undef F_HELPER_0_0 -#undef F_HELPER_DQ_0_0 +#undef F_HELPER_0_1 #undef VIS_HELPER #undef VIS_CMPHELPER -DEF_HELPER_0(compute_psr, void); -DEF_HELPER_0(compute_C_icc, i32); +DEF_HELPER_1(compute_psr, void, env); +DEF_HELPER_1(compute_C_icc, i32, env); #include "def-helper.h" diff --git a/target-sparc/machine.c b/target-sparc/machine.c index 752e431..235b088 100644 --- a/target-sparc/machine.c +++ b/target-sparc/machine.c @@ -2,7 +2,7 @@ #include "hw/boards.h" #include "qemu-timer.h" -#include "exec-all.h" +#include "cpu.h" void cpu_save(QEMUFile *f, void *opaque) { @@ -21,13 +21,9 @@ void cpu_save(QEMUFile *f, void *opaque) qemu_put_betls(f, &env->regbase[i]); /* FPU */ - for(i = 0; i < TARGET_FPREGS; i++) { - union { - float32 f; - uint32_t i; - } u; - u.f = env->fpr[i]; - qemu_put_be32(f, u.i); + for (i = 0; i < TARGET_DPREGS; i++) { + qemu_put_be32(f, env->fpr[i].l.upper); + qemu_put_be32(f, env->fpr[i].l.lower); } qemu_put_betls(f, &env->pc); @@ -45,6 +41,19 @@ void cpu_save(QEMUFile *f, void *opaque) /* MMU */ for (i = 0; i < 32; i++) qemu_put_be32s(f, &env->mmuregs[i]); + for (i = 0; i < 4; i++) { + qemu_put_be64s(f, &env->mxccdata[i]); + } + for (i = 0; i < 8; i++) { + qemu_put_be64s(f, &env->mxccregs[i]); + } + qemu_put_be32s(f, &env->mmubpctrv); + qemu_put_be32s(f, &env->mmubpctrc); + qemu_put_be32s(f, &env->mmubpctrs); + qemu_put_be64s(f, &env->mmubpaction); + for (i = 0; i < 4; i++) { + qemu_put_be64s(f, &env->mmubpregs[i]); + } #else qemu_put_be64s(f, &env->lsu); for (i = 0; i < 16; i++) { @@ -115,13 +124,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) qemu_get_betls(f, &env->regbase[i]); /* FPU */ - for(i = 0; i < TARGET_FPREGS; i++) { - union { - float32 f; - uint32_t i; - } u; - u.i = qemu_get_be32(f); - env->fpr[i] = u.f; + for (i = 0; i < TARGET_DPREGS; i++) { + env->fpr[i].l.upper = qemu_get_be32(f); + env->fpr[i].l.lower = qemu_get_be32(f); } qemu_get_betls(f, &env->pc); @@ -141,6 +146,19 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) /* MMU */ for (i = 0; i < 32; i++) qemu_get_be32s(f, &env->mmuregs[i]); + for (i = 0; i < 4; i++) { + qemu_get_be64s(f, &env->mxccdata[i]); + } + for (i = 0; i < 8; i++) { + qemu_get_be64s(f, &env->mxccregs[i]); + } + qemu_get_be32s(f, &env->mmubpctrv); + qemu_get_be32s(f, &env->mmubpctrc); + qemu_get_be32s(f, &env->mmubpctrs); + qemu_get_be64s(f, &env->mmubpaction); + for (i = 0; i < 4; i++) { + qemu_get_be64s(f, &env->mmubpregs[i]); + } #else qemu_get_be64s(f, &env->lsu); for (i = 0; i < 16; i++) { diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 854f168..02b660d 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -1,4349 +1,8 @@ -#include "exec.h" -#include "host-utils.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "helper.h" -#include "sysemu.h" - -//#define DEBUG_MMU -//#define DEBUG_MXCC -//#define DEBUG_UNALIGNED -//#define DEBUG_UNASSIGNED -//#define DEBUG_ASI -//#define DEBUG_PCALL -//#define DEBUG_PSTATE -//#define DEBUG_CACHE_CONTROL - -#ifdef DEBUG_MMU -#define DPRINTF_MMU(fmt, ...) \ - do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF_MMU(fmt, ...) do {} while (0) -#endif - -#ifdef DEBUG_MXCC -#define DPRINTF_MXCC(fmt, ...) \ - do { printf("MXCC: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF_MXCC(fmt, ...) do {} while (0) -#endif - -#ifdef DEBUG_ASI -#define DPRINTF_ASI(fmt, ...) \ - do { printf("ASI: " fmt , ## __VA_ARGS__); } while (0) -#endif - -#ifdef DEBUG_PSTATE -#define DPRINTF_PSTATE(fmt, ...) \ - do { printf("PSTATE: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF_PSTATE(fmt, ...) do {} while (0) -#endif - -#ifdef DEBUG_CACHE_CONTROL -#define DPRINTF_CACHE_CONTROL(fmt, ...) \ - do { printf("CACHE_CONTROL: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF_CACHE_CONTROL(fmt, ...) do {} while (0) -#endif - -#ifdef TARGET_SPARC64 -#ifndef TARGET_ABI32 -#define AM_CHECK(env1) ((env1)->pstate & PS_AM) -#else -#define AM_CHECK(env1) (1) -#endif -#endif - -#define DT0 (env->dt0) -#define DT1 (env->dt1) -#define QT0 (env->qt0) -#define QT1 (env->qt1) - -/* Leon3 cache control */ - -/* Cache control: emulate the behavior of cache control registers but without - any effect on the emulated */ - -#define CACHE_STATE_MASK 0x3 -#define CACHE_DISABLED 0x0 -#define CACHE_FROZEN 0x1 -#define CACHE_ENABLED 0x3 - -/* Cache Control register fields */ - -#define CACHE_CTRL_IF (1 << 4) /* Instruction Cache Freeze on Interrupt */ -#define CACHE_CTRL_DF (1 << 5) /* Data Cache Freeze on Interrupt */ -#define CACHE_CTRL_DP (1 << 14) /* Data cache flush pending */ -#define CACHE_CTRL_IP (1 << 15) /* Instruction cache flush pending */ -#define CACHE_CTRL_IB (1 << 16) /* Instruction burst fetch */ -#define CACHE_CTRL_FI (1 << 21) /* Flush Instruction cache (Write only) */ -#define CACHE_CTRL_FD (1 << 22) /* Flush Data cache (Write only) */ -#define CACHE_CTRL_DS (1 << 23) /* Data cache snoop enable */ - -#if defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64) -static void do_unassigned_access(target_ulong addr, int is_write, int is_exec, - int is_asi, int size); -#endif - -#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) -// Calculates TSB pointer value for fault page size 8k or 64k -static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register, - uint64_t tag_access_register, - int page_size) -{ - uint64_t tsb_base = tsb_register & ~0x1fffULL; - int tsb_split = (tsb_register & 0x1000ULL) ? 1 : 0; - int tsb_size = tsb_register & 0xf; - - // discard lower 13 bits which hold tag access context - uint64_t tag_access_va = tag_access_register & ~0x1fffULL; - - // now reorder bits - uint64_t tsb_base_mask = ~0x1fffULL; - uint64_t va = tag_access_va; - - // move va bits to correct position - if (page_size == 8*1024) { - va >>= 9; - } else if (page_size == 64*1024) { - va >>= 12; - } - - if (tsb_size) { - tsb_base_mask <<= tsb_size; - } - - // calculate tsb_base mask and adjust va if split is in use - if (tsb_split) { - if (page_size == 8*1024) { - va &= ~(1ULL << (13 + tsb_size)); - } else if (page_size == 64*1024) { - va |= (1ULL << (13 + tsb_size)); - } - tsb_base_mask <<= 1; - } - - return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL; -} - -// Calculates tag target register value by reordering bits -// in tag access register -static uint64_t ultrasparc_tag_target(uint64_t tag_access_register) -{ - return ((tag_access_register & 0x1fff) << 48) | (tag_access_register >> 22); -} - -static void replace_tlb_entry(SparcTLBEntry *tlb, - uint64_t tlb_tag, uint64_t tlb_tte, - CPUState *env1) -{ - target_ulong mask, size, va, offset; - - // flush page range if translation is valid - if (TTE_IS_VALID(tlb->tte)) { - - mask = 0xffffffffffffe000ULL; - mask <<= 3 * ((tlb->tte >> 61) & 3); - size = ~mask + 1; - - va = tlb->tag & mask; - - for (offset = 0; offset < size; offset += TARGET_PAGE_SIZE) { - tlb_flush_page(env1, va + offset); - } - } - - tlb->tag = tlb_tag; - tlb->tte = tlb_tte; -} - -static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr, - const char* strmmu, CPUState *env1) -{ - unsigned int i; - target_ulong mask; - uint64_t context; - - int is_demap_context = (demap_addr >> 6) & 1; - - // demap context - switch ((demap_addr >> 4) & 3) { - case 0: // primary - context = env1->dmmu.mmu_primary_context; - break; - case 1: // secondary - context = env1->dmmu.mmu_secondary_context; - break; - case 2: // nucleus - context = 0; - break; - case 3: // reserved - default: - return; - } - - for (i = 0; i < 64; i++) { - if (TTE_IS_VALID(tlb[i].tte)) { - - if (is_demap_context) { - // will remove non-global entries matching context value - if (TTE_IS_GLOBAL(tlb[i].tte) || - !tlb_compare_context(&tlb[i], context)) { - continue; - } - } else { - // demap page - // will remove any entry matching VA - mask = 0xffffffffffffe000ULL; - mask <<= 3 * ((tlb[i].tte >> 61) & 3); - - if (!compare_masked(demap_addr, tlb[i].tag, mask)) { - continue; - } - - // entry should be global or matching context value - if (!TTE_IS_GLOBAL(tlb[i].tte) && - !tlb_compare_context(&tlb[i], context)) { - continue; - } - } - - replace_tlb_entry(&tlb[i], 0, 0, env1); -#ifdef DEBUG_MMU - DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i); - dump_mmu(stdout, fprintf, env1); -#endif - } - } -} - -static void replace_tlb_1bit_lru(SparcTLBEntry *tlb, - uint64_t tlb_tag, uint64_t tlb_tte, - const char* strmmu, CPUState *env1) -{ - unsigned int i, replace_used; - - // Try replacing invalid entry - for (i = 0; i < 64; i++) { - if (!TTE_IS_VALID(tlb[i].tte)) { - replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1); -#ifdef DEBUG_MMU - DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu, i); - dump_mmu(stdout, fprintf, env1); -#endif - return; - } - } - - // All entries are valid, try replacing unlocked entry - - for (replace_used = 0; replace_used < 2; ++replace_used) { - - // Used entries are not replaced on first pass - - for (i = 0; i < 64; i++) { - if (!TTE_IS_LOCKED(tlb[i].tte) && !TTE_IS_USED(tlb[i].tte)) { - - replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1); -#ifdef DEBUG_MMU - DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n", - strmmu, (replace_used?"used":"unused"), i); - dump_mmu(stdout, fprintf, env1); -#endif - return; - } - } - - // Now reset used bit and search for unused entries again - - for (i = 0; i < 64; i++) { - TTE_SET_UNUSED(tlb[i].tte); - } - } - -#ifdef DEBUG_MMU - DPRINTF_MMU("%s lru replacement failed: no entries available\n", strmmu); -#endif - // error state? -} - -#endif - -static inline target_ulong address_mask(CPUState *env1, target_ulong addr) -{ -#ifdef TARGET_SPARC64 - if (AM_CHECK(env1)) - addr &= 0xffffffffULL; -#endif - return addr; -} - -/* returns true if access using this ASI is to have address translated by MMU - otherwise access is to raw physical address */ -static inline int is_translating_asi(int asi) -{ -#ifdef TARGET_SPARC64 - /* Ultrasparc IIi translating asi - - note this list is defined by cpu implementation - */ - switch (asi) { - case 0x04 ... 0x11: - case 0x18 ... 0x19: - case 0x24 ... 0x2C: - case 0x70 ... 0x73: - case 0x78 ... 0x79: - case 0x80 ... 0xFF: - return 1; - - default: - return 0; - } -#else - /* TODO: check sparc32 bits */ - return 0; -#endif -} - -static inline target_ulong asi_address_mask(CPUState *env1, - int asi, target_ulong addr) -{ - if (is_translating_asi(asi)) { - return address_mask(env, addr); - } else { - return addr; - } -} - -static void raise_exception(int tt) -{ - env->exception_index = tt; - cpu_loop_exit(); -} - -void HELPER(raise_exception)(int tt) -{ - raise_exception(tt); -} - -void helper_shutdown(void) -{ -#if !defined(CONFIG_USER_ONLY) - qemu_system_shutdown_request(); -#endif -} - -void helper_check_align(target_ulong addr, uint32_t align) -{ - if (addr & align) { -#ifdef DEBUG_UNALIGNED - printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx - "\n", addr, env->pc); -#endif - raise_exception(TT_UNALIGNED); - } -} - -#define F_HELPER(name, p) void helper_f##name##p(void) - -#define F_BINOP(name) \ - float32 helper_f ## name ## s (float32 src1, float32 src2) \ - { \ - return float32_ ## name (src1, src2, &env->fp_status); \ - } \ - F_HELPER(name, d) \ - { \ - DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \ - } \ - F_HELPER(name, q) \ - { \ - QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \ - } - -F_BINOP(add); -F_BINOP(sub); -F_BINOP(mul); -F_BINOP(div); -#undef F_BINOP - -void helper_fsmuld(float32 src1, float32 src2) -{ - DT0 = float64_mul(float32_to_float64(src1, &env->fp_status), - float32_to_float64(src2, &env->fp_status), - &env->fp_status); -} - -void helper_fdmulq(void) -{ - QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status), - float64_to_float128(DT1, &env->fp_status), - &env->fp_status); -} - -float32 helper_fnegs(float32 src) -{ - return float32_chs(src); -} - -#ifdef TARGET_SPARC64 -F_HELPER(neg, d) -{ - DT0 = float64_chs(DT1); -} - -F_HELPER(neg, q) -{ - QT0 = float128_chs(QT1); -} -#endif - -/* Integer to float conversion. */ -float32 helper_fitos(int32_t src) -{ - return int32_to_float32(src, &env->fp_status); -} - -void helper_fitod(int32_t src) -{ - DT0 = int32_to_float64(src, &env->fp_status); -} - -void helper_fitoq(int32_t src) -{ - QT0 = int32_to_float128(src, &env->fp_status); -} - -#ifdef TARGET_SPARC64 -float32 helper_fxtos(void) -{ - return int64_to_float32(*((int64_t *)&DT1), &env->fp_status); -} - -F_HELPER(xto, d) -{ - DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status); -} - -F_HELPER(xto, q) -{ - QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status); -} -#endif -#undef F_HELPER - -/* floating point conversion */ -float32 helper_fdtos(void) -{ - return float64_to_float32(DT1, &env->fp_status); -} - -void helper_fstod(float32 src) -{ - DT0 = float32_to_float64(src, &env->fp_status); -} - -float32 helper_fqtos(void) -{ - return float128_to_float32(QT1, &env->fp_status); -} - -void helper_fstoq(float32 src) -{ - QT0 = float32_to_float128(src, &env->fp_status); -} - -void helper_fqtod(void) -{ - DT0 = float128_to_float64(QT1, &env->fp_status); -} - -void helper_fdtoq(void) -{ - QT0 = float64_to_float128(DT1, &env->fp_status); -} - -/* Float to integer conversion. */ -int32_t helper_fstoi(float32 src) -{ - return float32_to_int32_round_to_zero(src, &env->fp_status); -} - -int32_t helper_fdtoi(void) -{ - return float64_to_int32_round_to_zero(DT1, &env->fp_status); -} - -int32_t helper_fqtoi(void) -{ - return float128_to_int32_round_to_zero(QT1, &env->fp_status); -} - -#ifdef TARGET_SPARC64 -void helper_fstox(float32 src) -{ - *((int64_t *)&DT0) = float32_to_int64_round_to_zero(src, &env->fp_status); -} - -void helper_fdtox(void) -{ - *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status); -} - -void helper_fqtox(void) -{ - *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status); -} - -void helper_faligndata(void) -{ - uint64_t tmp; - - tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8); - /* on many architectures a shift of 64 does nothing */ - if ((env->gsr & 7) != 0) { - tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8); - } - *((uint64_t *)&DT0) = tmp; -} - -#ifdef HOST_WORDS_BIGENDIAN -#define VIS_B64(n) b[7 - (n)] -#define VIS_W64(n) w[3 - (n)] -#define VIS_SW64(n) sw[3 - (n)] -#define VIS_L64(n) l[1 - (n)] -#define VIS_B32(n) b[3 - (n)] -#define VIS_W32(n) w[1 - (n)] -#else -#define VIS_B64(n) b[n] -#define VIS_W64(n) w[n] -#define VIS_SW64(n) sw[n] -#define VIS_L64(n) l[n] -#define VIS_B32(n) b[n] -#define VIS_W32(n) w[n] -#endif - -typedef union { - uint8_t b[8]; - uint16_t w[4]; - int16_t sw[4]; - uint32_t l[2]; - float64 d; -} vis64; - -typedef union { - uint8_t b[4]; - uint16_t w[2]; - uint32_t l; - float32 f; -} vis32; - -void helper_fpmerge(void) -{ - vis64 s, d; - - s.d = DT0; - d.d = DT1; - - // Reverse calculation order to handle overlap - d.VIS_B64(7) = s.VIS_B64(3); - d.VIS_B64(6) = d.VIS_B64(3); - d.VIS_B64(5) = s.VIS_B64(2); - d.VIS_B64(4) = d.VIS_B64(2); - d.VIS_B64(3) = s.VIS_B64(1); - d.VIS_B64(2) = d.VIS_B64(1); - d.VIS_B64(1) = s.VIS_B64(0); - //d.VIS_B64(0) = d.VIS_B64(0); - - DT0 = d.d; -} - -void helper_fmul8x16(void) -{ - vis64 s, d; - uint32_t tmp; - - s.d = DT0; - d.d = DT1; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \ - if ((tmp & 0xff) > 0x7f) \ - tmp += 0x100; \ - d.VIS_W64(r) = tmp >> 8; - - PMUL(0); - PMUL(1); - PMUL(2); - PMUL(3); -#undef PMUL - - DT0 = d.d; -} - -void helper_fmul8x16al(void) -{ - vis64 s, d; - uint32_t tmp; - - s.d = DT0; - d.d = DT1; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \ - if ((tmp & 0xff) > 0x7f) \ - tmp += 0x100; \ - d.VIS_W64(r) = tmp >> 8; - - PMUL(0); - PMUL(1); - PMUL(2); - PMUL(3); -#undef PMUL - - DT0 = d.d; -} - -void helper_fmul8x16au(void) -{ - vis64 s, d; - uint32_t tmp; - - s.d = DT0; - d.d = DT1; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \ - if ((tmp & 0xff) > 0x7f) \ - tmp += 0x100; \ - d.VIS_W64(r) = tmp >> 8; - - PMUL(0); - PMUL(1); - PMUL(2); - PMUL(3); -#undef PMUL - - DT0 = d.d; -} - -void helper_fmul8sux16(void) -{ - vis64 s, d; - uint32_t tmp; - - s.d = DT0; - d.d = DT1; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \ - if ((tmp & 0xff) > 0x7f) \ - tmp += 0x100; \ - d.VIS_W64(r) = tmp >> 8; - - PMUL(0); - PMUL(1); - PMUL(2); - PMUL(3); -#undef PMUL - - DT0 = d.d; -} - -void helper_fmul8ulx16(void) -{ - vis64 s, d; - uint32_t tmp; - - s.d = DT0; - d.d = DT1; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \ - if ((tmp & 0xff) > 0x7f) \ - tmp += 0x100; \ - d.VIS_W64(r) = tmp >> 8; - - PMUL(0); - PMUL(1); - PMUL(2); - PMUL(3); -#undef PMUL - - DT0 = d.d; -} - -void helper_fmuld8sux16(void) -{ - vis64 s, d; - uint32_t tmp; - - s.d = DT0; - d.d = DT1; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \ - if ((tmp & 0xff) > 0x7f) \ - tmp += 0x100; \ - d.VIS_L64(r) = tmp; - - // Reverse calculation order to handle overlap - PMUL(1); - PMUL(0); -#undef PMUL - - DT0 = d.d; -} - -void helper_fmuld8ulx16(void) -{ - vis64 s, d; - uint32_t tmp; - - s.d = DT0; - d.d = DT1; - -#define PMUL(r) \ - tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \ - if ((tmp & 0xff) > 0x7f) \ - tmp += 0x100; \ - d.VIS_L64(r) = tmp; - - // Reverse calculation order to handle overlap - PMUL(1); - PMUL(0); -#undef PMUL - - DT0 = d.d; -} - -void helper_fexpand(void) -{ - vis32 s; - vis64 d; - - s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff); - d.d = DT1; - d.VIS_W64(0) = s.VIS_B32(0) << 4; - d.VIS_W64(1) = s.VIS_B32(1) << 4; - d.VIS_W64(2) = s.VIS_B32(2) << 4; - d.VIS_W64(3) = s.VIS_B32(3) << 4; - - DT0 = d.d; -} - -#define VIS_HELPER(name, F) \ - void name##16(void) \ - { \ - vis64 s, d; \ - \ - s.d = DT0; \ - d.d = DT1; \ - \ - d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0)); \ - d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1)); \ - d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2)); \ - d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3)); \ - \ - DT0 = d.d; \ - } \ - \ - uint32_t name##16s(uint32_t src1, uint32_t src2) \ - { \ - vis32 s, d; \ - \ - s.l = src1; \ - d.l = src2; \ - \ - d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0)); \ - d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1)); \ - \ - return d.l; \ - } \ - \ - void name##32(void) \ - { \ - vis64 s, d; \ - \ - s.d = DT0; \ - d.d = DT1; \ - \ - d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0)); \ - d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1)); \ - \ - DT0 = d.d; \ - } \ - \ - uint32_t name##32s(uint32_t src1, uint32_t src2) \ - { \ - vis32 s, d; \ - \ - s.l = src1; \ - d.l = src2; \ - \ - d.l = F(d.l, s.l); \ - \ - return d.l; \ - } - -#define FADD(a, b) ((a) + (b)) -#define FSUB(a, b) ((a) - (b)) -VIS_HELPER(helper_fpadd, FADD) -VIS_HELPER(helper_fpsub, FSUB) - -#define VIS_CMPHELPER(name, F) \ - void name##16(void) \ - { \ - vis64 s, d; \ - \ - s.d = DT0; \ - d.d = DT1; \ - \ - d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0; \ - d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0; \ - d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0; \ - d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0; \ - \ - DT0 = d.d; \ - } \ - \ - void name##32(void) \ - { \ - vis64 s, d; \ - \ - s.d = DT0; \ - d.d = DT1; \ - \ - d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0; \ - d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0; \ - \ - DT0 = d.d; \ - } - -#define FCMPGT(a, b) ((a) > (b)) -#define FCMPEQ(a, b) ((a) == (b)) -#define FCMPLE(a, b) ((a) <= (b)) -#define FCMPNE(a, b) ((a) != (b)) - -VIS_CMPHELPER(helper_fcmpgt, FCMPGT) -VIS_CMPHELPER(helper_fcmpeq, FCMPEQ) -VIS_CMPHELPER(helper_fcmple, FCMPLE) -VIS_CMPHELPER(helper_fcmpne, FCMPNE) -#endif - -void helper_check_ieee_exceptions(void) -{ - target_ulong status; - - status = get_float_exception_flags(&env->fp_status); - if (status) { - /* Copy IEEE 754 flags into FSR */ - if (status & float_flag_invalid) - env->fsr |= FSR_NVC; - if (status & float_flag_overflow) - env->fsr |= FSR_OFC; - if (status & float_flag_underflow) - env->fsr |= FSR_UFC; - if (status & float_flag_divbyzero) - env->fsr |= FSR_DZC; - if (status & float_flag_inexact) - env->fsr |= FSR_NXC; - - if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) { - /* Unmasked exception, generate a trap */ - env->fsr |= FSR_FTT_IEEE_EXCP; - raise_exception(TT_FP_EXCP); - } else { - /* Accumulate exceptions */ - env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5; - } - } -} - -void helper_clear_float_exceptions(void) -{ - set_float_exception_flags(0, &env->fp_status); -} - -float32 helper_fabss(float32 src) -{ - return float32_abs(src); -} - -#ifdef TARGET_SPARC64 -void helper_fabsd(void) -{ - DT0 = float64_abs(DT1); -} - -void helper_fabsq(void) -{ - QT0 = float128_abs(QT1); -} -#endif - -float32 helper_fsqrts(float32 src) -{ - return float32_sqrt(src, &env->fp_status); -} - -void helper_fsqrtd(void) -{ - DT0 = float64_sqrt(DT1, &env->fp_status); -} - -void helper_fsqrtq(void) -{ - QT0 = float128_sqrt(QT1, &env->fp_status); -} - -#define GEN_FCMP(name, size, reg1, reg2, FS, E) \ - void glue(helper_, name) (void) \ - { \ - env->fsr &= FSR_FTT_NMASK; \ - if (E && (glue(size, _is_any_nan)(reg1) || \ - glue(size, _is_any_nan)(reg2)) && \ - (env->fsr & FSR_NVM)) { \ - env->fsr |= FSR_NVC; \ - env->fsr |= FSR_FTT_IEEE_EXCP; \ - raise_exception(TT_FP_EXCP); \ - } \ - switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \ - case float_relation_unordered: \ - if ((env->fsr & FSR_NVM)) { \ - env->fsr |= FSR_NVC; \ - env->fsr |= FSR_FTT_IEEE_EXCP; \ - raise_exception(TT_FP_EXCP); \ - } else { \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ - env->fsr |= FSR_NVA; \ - } \ - break; \ - case float_relation_less: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - env->fsr |= FSR_FCC0 << FS; \ - break; \ - case float_relation_greater: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - env->fsr |= FSR_FCC1 << FS; \ - break; \ - default: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - break; \ - } \ - } -#define GEN_FCMPS(name, size, FS, E) \ - void glue(helper_, name)(float32 src1, float32 src2) \ - { \ - env->fsr &= FSR_FTT_NMASK; \ - if (E && (glue(size, _is_any_nan)(src1) || \ - glue(size, _is_any_nan)(src2)) && \ - (env->fsr & FSR_NVM)) { \ - env->fsr |= FSR_NVC; \ - env->fsr |= FSR_FTT_IEEE_EXCP; \ - raise_exception(TT_FP_EXCP); \ - } \ - switch (glue(size, _compare) (src1, src2, &env->fp_status)) { \ - case float_relation_unordered: \ - if ((env->fsr & FSR_NVM)) { \ - env->fsr |= FSR_NVC; \ - env->fsr |= FSR_FTT_IEEE_EXCP; \ - raise_exception(TT_FP_EXCP); \ - } else { \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ - env->fsr |= FSR_NVA; \ - } \ - break; \ - case float_relation_less: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - env->fsr |= FSR_FCC0 << FS; \ - break; \ - case float_relation_greater: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - env->fsr |= FSR_FCC1 << FS; \ - break; \ - default: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ - break; \ - } \ - } - -GEN_FCMPS(fcmps, float32, 0, 0); -GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0); - -GEN_FCMPS(fcmpes, float32, 0, 1); -GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1); - -GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0); -GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1); - -static uint32_t compute_all_flags(void) -{ - return env->psr & PSR_ICC; -} - -static uint32_t compute_C_flags(void) -{ - return env->psr & PSR_CARRY; -} - -static inline uint32_t get_NZ_icc(int32_t dst) -{ - uint32_t ret = 0; - - if (dst == 0) { - ret = PSR_ZERO; - } else if (dst < 0) { - ret = PSR_NEG; - } - return ret; -} - -#ifdef TARGET_SPARC64 -static uint32_t compute_all_flags_xcc(void) -{ - return env->xcc & PSR_ICC; -} - -static uint32_t compute_C_flags_xcc(void) -{ - return env->xcc & PSR_CARRY; -} - -static inline uint32_t get_NZ_xcc(target_long dst) -{ - uint32_t ret = 0; - - if (!dst) { - ret = PSR_ZERO; - } else if (dst < 0) { - ret = PSR_NEG; - } - return ret; -} -#endif - -static inline uint32_t get_V_div_icc(target_ulong src2) -{ - uint32_t ret = 0; - - if (src2 != 0) { - ret = PSR_OVF; - } - return ret; -} - -static uint32_t compute_all_div(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_V_div_icc(CC_SRC2); - return ret; -} - -static uint32_t compute_C_div(void) -{ - return 0; -} - -static inline uint32_t get_C_add_icc(uint32_t dst, uint32_t src1) -{ - uint32_t ret = 0; - - if (dst < src1) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_C_addx_icc(uint32_t dst, uint32_t src1, - uint32_t src2) -{ - uint32_t ret = 0; - - if (((src1 & src2) | (~dst & (src1 | src2))) & (1U << 31)) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_V_add_icc(uint32_t dst, uint32_t src1, - uint32_t src2) -{ - uint32_t ret = 0; - - if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1U << 31)) { - ret = PSR_OVF; - } - return ret; -} - -#ifdef TARGET_SPARC64 -static inline uint32_t get_C_add_xcc(target_ulong dst, target_ulong src1) -{ - uint32_t ret = 0; - - if (dst < src1) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_C_addx_xcc(target_ulong dst, target_ulong src1, - target_ulong src2) -{ - uint32_t ret = 0; - - if (((src1 & src2) | (~dst & (src1 | src2))) & (1ULL << 63)) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_V_add_xcc(target_ulong dst, target_ulong src1, - target_ulong src2) -{ - uint32_t ret = 0; - - if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 63)) { - ret = PSR_OVF; - } - return ret; -} - -static uint32_t compute_all_add_xcc(void) -{ - uint32_t ret; - - ret = get_NZ_xcc(CC_DST); - ret |= get_C_add_xcc(CC_DST, CC_SRC); - ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_add_xcc(void) -{ - return get_C_add_xcc(CC_DST, CC_SRC); -} -#endif - -static uint32_t compute_all_add(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_add_icc(CC_DST, CC_SRC); - ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_add(void) -{ - return get_C_add_icc(CC_DST, CC_SRC); -} - -#ifdef TARGET_SPARC64 -static uint32_t compute_all_addx_xcc(void) -{ - uint32_t ret; - - ret = get_NZ_xcc(CC_DST); - ret |= get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2); - ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_addx_xcc(void) -{ - uint32_t ret; - - ret = get_C_addx_xcc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} -#endif - -static uint32_t compute_all_addx(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_addx_icc(CC_DST, CC_SRC, CC_SRC2); - ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_addx(void) -{ - uint32_t ret; - - ret = get_C_addx_icc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static inline uint32_t get_V_tag_icc(target_ulong src1, target_ulong src2) -{ - uint32_t ret = 0; - - if ((src1 | src2) & 0x3) { - ret = PSR_OVF; - } - return ret; -} - -static uint32_t compute_all_tadd(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_add_icc(CC_DST, CC_SRC); - ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2); - ret |= get_V_tag_icc(CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_all_taddtv(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_add_icc(CC_DST, CC_SRC); - return ret; -} - -static inline uint32_t get_C_sub_icc(uint32_t src1, uint32_t src2) -{ - uint32_t ret = 0; - - if (src1 < src2) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_C_subx_icc(uint32_t dst, uint32_t src1, - uint32_t src2) -{ - uint32_t ret = 0; - - if (((~src1 & src2) | (dst & (~src1 | src2))) & (1U << 31)) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_V_sub_icc(uint32_t dst, uint32_t src1, - uint32_t src2) -{ - uint32_t ret = 0; - - if (((src1 ^ src2) & (src1 ^ dst)) & (1U << 31)) { - ret = PSR_OVF; - } - return ret; -} - - -#ifdef TARGET_SPARC64 -static inline uint32_t get_C_sub_xcc(target_ulong src1, target_ulong src2) -{ - uint32_t ret = 0; - - if (src1 < src2) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_C_subx_xcc(target_ulong dst, target_ulong src1, - target_ulong src2) -{ - uint32_t ret = 0; - - if (((~src1 & src2) | (dst & (~src1 | src2))) & (1ULL << 63)) { - ret = PSR_CARRY; - } - return ret; -} - -static inline uint32_t get_V_sub_xcc(target_ulong dst, target_ulong src1, - target_ulong src2) -{ - uint32_t ret = 0; - - if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 63)) { - ret = PSR_OVF; - } - return ret; -} - -static uint32_t compute_all_sub_xcc(void) -{ - uint32_t ret; - - ret = get_NZ_xcc(CC_DST); - ret |= get_C_sub_xcc(CC_SRC, CC_SRC2); - ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_sub_xcc(void) -{ - return get_C_sub_xcc(CC_SRC, CC_SRC2); -} -#endif - -static uint32_t compute_all_sub(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_sub_icc(CC_SRC, CC_SRC2); - ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_sub(void) -{ - return get_C_sub_icc(CC_SRC, CC_SRC2); -} - -#ifdef TARGET_SPARC64 -static uint32_t compute_all_subx_xcc(void) -{ - uint32_t ret; - - ret = get_NZ_xcc(CC_DST); - ret |= get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2); - ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_subx_xcc(void) -{ - uint32_t ret; - - ret = get_C_subx_xcc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} -#endif - -static uint32_t compute_all_subx(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_subx_icc(CC_DST, CC_SRC, CC_SRC2); - ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_C_subx(void) -{ - uint32_t ret; - - ret = get_C_subx_icc(CC_DST, CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_all_tsub(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_sub_icc(CC_SRC, CC_SRC2); - ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2); - ret |= get_V_tag_icc(CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_all_tsubtv(void) -{ - uint32_t ret; - - ret = get_NZ_icc(CC_DST); - ret |= get_C_sub_icc(CC_SRC, CC_SRC2); - return ret; -} - -static uint32_t compute_all_logic(void) -{ - return get_NZ_icc(CC_DST); -} - -static uint32_t compute_C_logic(void) -{ - return 0; -} - -#ifdef TARGET_SPARC64 -static uint32_t compute_all_logic_xcc(void) -{ - return get_NZ_xcc(CC_DST); -} -#endif - -typedef struct CCTable { - uint32_t (*compute_all)(void); /* return all the flags */ - uint32_t (*compute_c)(void); /* return the C flag */ -} CCTable; - -static const CCTable icc_table[CC_OP_NB] = { - /* CC_OP_DYNAMIC should never happen */ - [CC_OP_FLAGS] = { compute_all_flags, compute_C_flags }, - [CC_OP_DIV] = { compute_all_div, compute_C_div }, - [CC_OP_ADD] = { compute_all_add, compute_C_add }, - [CC_OP_ADDX] = { compute_all_addx, compute_C_addx }, - [CC_OP_TADD] = { compute_all_tadd, compute_C_add }, - [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_add }, - [CC_OP_SUB] = { compute_all_sub, compute_C_sub }, - [CC_OP_SUBX] = { compute_all_subx, compute_C_subx }, - [CC_OP_TSUB] = { compute_all_tsub, compute_C_sub }, - [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_sub }, - [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic }, -}; - -#ifdef TARGET_SPARC64 -static const CCTable xcc_table[CC_OP_NB] = { - /* CC_OP_DYNAMIC should never happen */ - [CC_OP_FLAGS] = { compute_all_flags_xcc, compute_C_flags_xcc }, - [CC_OP_DIV] = { compute_all_logic_xcc, compute_C_logic }, - [CC_OP_ADD] = { compute_all_add_xcc, compute_C_add_xcc }, - [CC_OP_ADDX] = { compute_all_addx_xcc, compute_C_addx_xcc }, - [CC_OP_TADD] = { compute_all_add_xcc, compute_C_add_xcc }, - [CC_OP_TADDTV] = { compute_all_add_xcc, compute_C_add_xcc }, - [CC_OP_SUB] = { compute_all_sub_xcc, compute_C_sub_xcc }, - [CC_OP_SUBX] = { compute_all_subx_xcc, compute_C_subx_xcc }, - [CC_OP_TSUB] = { compute_all_sub_xcc, compute_C_sub_xcc }, - [CC_OP_TSUBTV] = { compute_all_sub_xcc, compute_C_sub_xcc }, - [CC_OP_LOGIC] = { compute_all_logic_xcc, compute_C_logic }, -}; -#endif - -void helper_compute_psr(void) -{ - uint32_t new_psr; - - new_psr = icc_table[CC_OP].compute_all(); - env->psr = new_psr; -#ifdef TARGET_SPARC64 - new_psr = xcc_table[CC_OP].compute_all(); - env->xcc = new_psr; -#endif - CC_OP = CC_OP_FLAGS; -} - -uint32_t helper_compute_C_icc(void) -{ - uint32_t ret; - - ret = icc_table[CC_OP].compute_c() >> PSR_CARRY_SHIFT; - return ret; -} - -static inline void memcpy32(target_ulong *dst, const target_ulong *src) -{ - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - dst[4] = src[4]; - dst[5] = src[5]; - dst[6] = src[6]; - dst[7] = src[7]; -} - -static void set_cwp(int new_cwp) -{ - /* put the modified wrap registers at their proper location */ - if (env->cwp == env->nwindows - 1) { - memcpy32(env->regbase, env->regbase + env->nwindows * 16); - } - env->cwp = new_cwp; - - /* put the wrap registers at their temporary location */ - if (new_cwp == env->nwindows - 1) { - memcpy32(env->regbase + env->nwindows * 16, env->regbase); - } - env->regwptr = env->regbase + (new_cwp * 16); -} - -void cpu_set_cwp(CPUState *env1, int new_cwp) -{ - CPUState *saved_env; - - saved_env = env; - env = env1; - set_cwp(new_cwp); - env = saved_env; -} - -static target_ulong get_psr(void) -{ - helper_compute_psr(); - -#if !defined (TARGET_SPARC64) - return env->version | (env->psr & PSR_ICC) | - (env->psref? PSR_EF : 0) | - (env->psrpil << 8) | - (env->psrs? PSR_S : 0) | - (env->psrps? PSR_PS : 0) | - (env->psret? PSR_ET : 0) | env->cwp; -#else - return env->psr & PSR_ICC; -#endif -} - -target_ulong cpu_get_psr(CPUState *env1) -{ - CPUState *saved_env; - target_ulong ret; - - saved_env = env; - env = env1; - ret = get_psr(); - env = saved_env; - return ret; -} - -static void put_psr(target_ulong val) -{ - env->psr = val & PSR_ICC; -#if !defined (TARGET_SPARC64) - env->psref = (val & PSR_EF)? 1 : 0; - env->psrpil = (val & PSR_PIL) >> 8; -#endif -#if ((!defined (TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY)) - cpu_check_irqs(env); -#endif -#if !defined (TARGET_SPARC64) - env->psrs = (val & PSR_S)? 1 : 0; - env->psrps = (val & PSR_PS)? 1 : 0; - env->psret = (val & PSR_ET)? 1 : 0; - set_cwp(val & PSR_CWP); -#endif - env->cc_op = CC_OP_FLAGS; -} - -void cpu_put_psr(CPUState *env1, target_ulong val) -{ - CPUState *saved_env; - - saved_env = env; - env = env1; - put_psr(val); - env = saved_env; -} - -static int cwp_inc(int cwp) -{ - if (unlikely(cwp >= env->nwindows)) { - cwp -= env->nwindows; - } - return cwp; -} - -int cpu_cwp_inc(CPUState *env1, int cwp) -{ - CPUState *saved_env; - target_ulong ret; - - saved_env = env; - env = env1; - ret = cwp_inc(cwp); - env = saved_env; - return ret; -} - -static int cwp_dec(int cwp) -{ - if (unlikely(cwp < 0)) { - cwp += env->nwindows; - } - return cwp; -} - -int cpu_cwp_dec(CPUState *env1, int cwp) -{ - CPUState *saved_env; - target_ulong ret; - - saved_env = env; - env = env1; - ret = cwp_dec(cwp); - env = saved_env; - return ret; -} - -#ifdef TARGET_SPARC64 -GEN_FCMPS(fcmps_fcc1, float32, 22, 0); -GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0); -GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0); - -GEN_FCMPS(fcmps_fcc2, float32, 24, 0); -GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0); -GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0); - -GEN_FCMPS(fcmps_fcc3, float32, 26, 0); -GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0); -GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0); - -GEN_FCMPS(fcmpes_fcc1, float32, 22, 1); -GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1); -GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1); - -GEN_FCMPS(fcmpes_fcc2, float32, 24, 1); -GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1); -GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1); - -GEN_FCMPS(fcmpes_fcc3, float32, 26, 1); -GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1); -GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1); -#endif -#undef GEN_FCMPS - -#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \ - defined(DEBUG_MXCC) -static void dump_mxcc(CPUState *env) -{ - printf("mxccdata: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 - "\n", - env->mxccdata[0], env->mxccdata[1], - env->mxccdata[2], env->mxccdata[3]); - printf("mxccregs: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 - "\n" - " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 - "\n", - env->mxccregs[0], env->mxccregs[1], - env->mxccregs[2], env->mxccregs[3], - env->mxccregs[4], env->mxccregs[5], - env->mxccregs[6], env->mxccregs[7]); -} -#endif - -#if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \ - && defined(DEBUG_ASI) -static void dump_asi(const char *txt, target_ulong addr, int asi, int size, - uint64_t r1) -{ - switch (size) - { - case 1: - DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt, - addr, asi, r1 & 0xff); - break; - case 2: - DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt, - addr, asi, r1 & 0xffff); - break; - case 4: - DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt, - addr, asi, r1 & 0xffffffff); - break; - case 8: - DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt, - addr, asi, r1); - break; - } -} -#endif - -#ifndef TARGET_SPARC64 -#ifndef CONFIG_USER_ONLY - - -/* Leon3 cache control */ - -static void leon3_cache_control_int(void) -{ - uint32_t state = 0; - - if (env->cache_control & CACHE_CTRL_IF) { - /* Instruction cache state */ - state = env->cache_control & CACHE_STATE_MASK; - if (state == CACHE_ENABLED) { - state = CACHE_FROZEN; - DPRINTF_CACHE_CONTROL("Instruction cache: freeze\n"); - } - - env->cache_control &= ~CACHE_STATE_MASK; - env->cache_control |= state; - } - - if (env->cache_control & CACHE_CTRL_DF) { - /* Data cache state */ - state = (env->cache_control >> 2) & CACHE_STATE_MASK; - if (state == CACHE_ENABLED) { - state = CACHE_FROZEN; - DPRINTF_CACHE_CONTROL("Data cache: freeze\n"); - } - - env->cache_control &= ~(CACHE_STATE_MASK << 2); - env->cache_control |= (state << 2); - } -} - -static void leon3_cache_control_st(target_ulong addr, uint64_t val, int size) -{ - DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64 ", size:%d\n", - addr, val, size); - - if (size != 4) { - DPRINTF_CACHE_CONTROL("32bits only\n"); - return; - } - - switch (addr) { - case 0x00: /* Cache control */ - - /* These values must always be read as zeros */ - val &= ~CACHE_CTRL_FD; - val &= ~CACHE_CTRL_FI; - val &= ~CACHE_CTRL_IB; - val &= ~CACHE_CTRL_IP; - val &= ~CACHE_CTRL_DP; - - env->cache_control = val; - break; - case 0x04: /* Instruction cache configuration */ - case 0x08: /* Data cache configuration */ - /* Read Only */ - break; - default: - DPRINTF_CACHE_CONTROL("write unknown register %08x\n", addr); - break; - }; -} - -static uint64_t leon3_cache_control_ld(target_ulong addr, int size) -{ - uint64_t ret = 0; - - if (size != 4) { - DPRINTF_CACHE_CONTROL("32bits only\n"); - return 0; - } - - switch (addr) { - case 0x00: /* Cache control */ - ret = env->cache_control; - break; - - /* Configuration registers are read and only always keep those - predefined values */ - - case 0x04: /* Instruction cache configuration */ - ret = 0x10220000; - break; - case 0x08: /* Data cache configuration */ - ret = 0x18220000; - break; - default: - DPRINTF_CACHE_CONTROL("read unknown register %08x\n", addr); - break; - }; - DPRINTF_CACHE_CONTROL("ld addr:%08x, ret:0x%" PRIx64 ", size:%d\n", - addr, ret, size); - return ret; -} - -void leon3_irq_manager(void *irq_manager, int intno) -{ - leon3_irq_ack(irq_manager, intno); - leon3_cache_control_int(); -} - -uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) -{ - uint64_t ret = 0; -#if defined(DEBUG_MXCC) || defined(DEBUG_ASI) - uint32_t last_addr = addr; -#endif - - helper_check_align(addr, size - 1); - switch (asi) { - case 2: /* SuperSparc MXCC registers and Leon3 cache control */ - switch (addr) { - case 0x00: /* Leon3 Cache Control */ - case 0x08: /* Leon3 Instruction Cache config */ - case 0x0C: /* Leon3 Date Cache config */ - if (env->def->features & CPU_FEATURE_CACHE_CTRL) { - ret = leon3_cache_control_ld(addr, size); - } - break; - case 0x01c00a00: /* MXCC control register */ - if (size == 8) - ret = env->mxccregs[3]; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00a04: /* MXCC control register */ - if (size == 4) - ret = env->mxccregs[3]; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00c00: /* Module reset register */ - if (size == 8) { - ret = env->mxccregs[5]; - // should we do something here? - } else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00f00: /* MBus port address register */ - if (size == 8) - ret = env->mxccregs[7]; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - default: - DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr, - size); - break; - } - DPRINTF_MXCC("asi = %d, size = %d, sign = %d, " - "addr = %08x -> ret = %" PRIx64 "," - "addr = %08x\n", asi, size, sign, last_addr, ret, addr); -#ifdef DEBUG_MXCC - dump_mxcc(env); -#endif - break; - case 3: /* MMU probe */ - { - int mmulev; - - mmulev = (addr >> 8) & 15; - if (mmulev > 4) - ret = 0; - else - ret = mmu_probe(env, addr, mmulev); - DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n", - addr, mmulev, ret); - } - break; - case 4: /* read MMU regs */ - { - int reg = (addr >> 8) & 0x1f; - - ret = env->mmuregs[reg]; - if (reg == 3) /* Fault status cleared on read */ - env->mmuregs[3] = 0; - else if (reg == 0x13) /* Fault status read */ - ret = env->mmuregs[3]; - else if (reg == 0x14) /* Fault address read */ - ret = env->mmuregs[4]; - DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret); - } - break; - case 5: // Turbosparc ITLB Diagnostic - case 6: // Turbosparc DTLB Diagnostic - case 7: // Turbosparc IOTLB Diagnostic - break; - case 9: /* Supervisor code access */ - switch(size) { - case 1: - ret = ldub_code(addr); - break; - case 2: - ret = lduw_code(addr); - break; - default: - case 4: - ret = ldl_code(addr); - break; - case 8: - ret = ldq_code(addr); - break; - } - break; - case 0xa: /* User data access */ - switch(size) { - case 1: - ret = ldub_user(addr); - break; - case 2: - ret = lduw_user(addr); - break; - default: - case 4: - ret = ldl_user(addr); - break; - case 8: - ret = ldq_user(addr); - break; - } - break; - case 0xb: /* Supervisor data access */ - switch(size) { - case 1: - ret = ldub_kernel(addr); - break; - case 2: - ret = lduw_kernel(addr); - break; - default: - case 4: - ret = ldl_kernel(addr); - break; - case 8: - ret = ldq_kernel(addr); - break; - } - break; - case 0xc: /* I-cache tag */ - case 0xd: /* I-cache data */ - case 0xe: /* D-cache tag */ - case 0xf: /* D-cache data */ - break; - case 0x20: /* MMU passthrough */ - switch(size) { - case 1: - ret = ldub_phys(addr); - break; - case 2: - ret = lduw_phys(addr); - break; - default: - case 4: - ret = ldl_phys(addr); - break; - case 8: - ret = ldq_phys(addr); - break; - } - break; - case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */ - switch(size) { - case 1: - ret = ldub_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32)); - break; - case 2: - ret = lduw_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32)); - break; - default: - case 4: - ret = ldl_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32)); - break; - case 8: - ret = ldq_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32)); - break; - } - break; - case 0x30: // Turbosparc secondary cache diagnostic - case 0x31: // Turbosparc RAM snoop - case 0x32: // Turbosparc page table descriptor diagnostic - case 0x39: /* data cache diagnostic register */ - case 0x4c: /* SuperSPARC MMU Breakpoint Action register */ - ret = 0; - break; - case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */ - { - int reg = (addr >> 8) & 3; - - switch(reg) { - case 0: /* Breakpoint Value (Addr) */ - ret = env->mmubpregs[reg]; - break; - case 1: /* Breakpoint Mask */ - ret = env->mmubpregs[reg]; - break; - case 2: /* Breakpoint Control */ - ret = env->mmubpregs[reg]; - break; - case 3: /* Breakpoint Status */ - ret = env->mmubpregs[reg]; - env->mmubpregs[reg] = 0ULL; - break; - } - DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64 "\n", reg, - ret); - } - break; - case 8: /* User code access, XXX */ - default: - do_unassigned_access(addr, 0, 0, asi, size); - ret = 0; - break; - } - if (sign) { - switch(size) { - case 1: - ret = (int8_t) ret; - break; - case 2: - ret = (int16_t) ret; - break; - case 4: - ret = (int32_t) ret; - break; - default: - break; - } - } -#ifdef DEBUG_ASI - dump_asi("read ", last_addr, asi, size, ret); -#endif - return ret; -} - -void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size) -{ - helper_check_align(addr, size - 1); - switch(asi) { - case 2: /* SuperSparc MXCC registers and Leon3 cache control */ - switch (addr) { - case 0x00: /* Leon3 Cache Control */ - case 0x08: /* Leon3 Instruction Cache config */ - case 0x0C: /* Leon3 Date Cache config */ - if (env->def->features & CPU_FEATURE_CACHE_CTRL) { - leon3_cache_control_st(addr, val, size); - } - break; - - case 0x01c00000: /* MXCC stream data register 0 */ - if (size == 8) - env->mxccdata[0] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00008: /* MXCC stream data register 1 */ - if (size == 8) - env->mxccdata[1] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00010: /* MXCC stream data register 2 */ - if (size == 8) - env->mxccdata[2] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00018: /* MXCC stream data register 3 */ - if (size == 8) - env->mxccdata[3] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00100: /* MXCC stream source */ - if (size == 8) - env->mxccregs[0] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + - 0); - env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + - 8); - env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + - 16); - env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + - 24); - break; - case 0x01c00200: /* MXCC stream destination */ - if (size == 8) - env->mxccregs[1] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - stq_phys((env->mxccregs[1] & 0xffffffffULL) + 0, - env->mxccdata[0]); - stq_phys((env->mxccregs[1] & 0xffffffffULL) + 8, - env->mxccdata[1]); - stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, - env->mxccdata[2]); - stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24, - env->mxccdata[3]); - break; - case 0x01c00a00: /* MXCC control register */ - if (size == 8) - env->mxccregs[3] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00a04: /* MXCC control register */ - if (size == 4) - env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL) - | val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00e00: /* MXCC error register */ - // writing a 1 bit clears the error - if (size == 8) - env->mxccregs[6] &= ~val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - case 0x01c00f00: /* MBus port address register */ - if (size == 8) - env->mxccregs[7] = val; - else - DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, - size); - break; - default: - DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr, - size); - break; - } - DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n", - asi, size, addr, val); -#ifdef DEBUG_MXCC - dump_mxcc(env); -#endif - break; - case 3: /* MMU flush */ - { - int mmulev; - - mmulev = (addr >> 8) & 15; - DPRINTF_MMU("mmu flush level %d\n", mmulev); - switch (mmulev) { - case 0: // flush page - tlb_flush_page(env, addr & 0xfffff000); - break; - case 1: // flush segment (256k) - case 2: // flush region (16M) - case 3: // flush context (4G) - case 4: // flush entire - tlb_flush(env, 1); - break; - default: - break; - } -#ifdef DEBUG_MMU - dump_mmu(stdout, fprintf, env); -#endif - } - break; - case 4: /* write MMU regs */ - { - int reg = (addr >> 8) & 0x1f; - uint32_t oldreg; - - oldreg = env->mmuregs[reg]; - switch(reg) { - case 0: // Control Register - env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) | - (val & 0x00ffffff); - // Mappings generated during no-fault mode or MMU - // disabled mode are invalid in normal mode - if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) != - (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm))) - tlb_flush(env, 1); - break; - case 1: // Context Table Pointer Register - env->mmuregs[reg] = val & env->def->mmu_ctpr_mask; - break; - case 2: // Context Register - env->mmuregs[reg] = val & env->def->mmu_cxr_mask; - if (oldreg != env->mmuregs[reg]) { - /* we flush when the MMU context changes because - QEMU has no MMU context support */ - tlb_flush(env, 1); - } - break; - case 3: // Synchronous Fault Status Register with Clear - case 4: // Synchronous Fault Address Register - break; - case 0x10: // TLB Replacement Control Register - env->mmuregs[reg] = val & env->def->mmu_trcr_mask; - break; - case 0x13: // Synchronous Fault Status Register with Read and Clear - env->mmuregs[3] = val & env->def->mmu_sfsr_mask; - break; - case 0x14: // Synchronous Fault Address Register - env->mmuregs[4] = val; - break; - default: - env->mmuregs[reg] = val; - break; - } - if (oldreg != env->mmuregs[reg]) { - DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n", - reg, oldreg, env->mmuregs[reg]); - } -#ifdef DEBUG_MMU - dump_mmu(stdout, fprintf, env); -#endif - } - break; - case 5: // Turbosparc ITLB Diagnostic - case 6: // Turbosparc DTLB Diagnostic - case 7: // Turbosparc IOTLB Diagnostic - break; - case 0xa: /* User data access */ - switch(size) { - case 1: - stb_user(addr, val); - break; - case 2: - stw_user(addr, val); - break; - default: - case 4: - stl_user(addr, val); - break; - case 8: - stq_user(addr, val); - break; - } - break; - case 0xb: /* Supervisor data access */ - switch(size) { - case 1: - stb_kernel(addr, val); - break; - case 2: - stw_kernel(addr, val); - break; - default: - case 4: - stl_kernel(addr, val); - break; - case 8: - stq_kernel(addr, val); - break; - } - break; - case 0xc: /* I-cache tag */ - case 0xd: /* I-cache data */ - case 0xe: /* D-cache tag */ - case 0xf: /* D-cache data */ - case 0x10: /* I/D-cache flush page */ - case 0x11: /* I/D-cache flush segment */ - case 0x12: /* I/D-cache flush region */ - case 0x13: /* I/D-cache flush context */ - case 0x14: /* I/D-cache flush user */ - break; - case 0x17: /* Block copy, sta access */ - { - // val = src - // addr = dst - // copy 32 bytes - unsigned int i; - uint32_t src = val & ~3, dst = addr & ~3, temp; - - for (i = 0; i < 32; i += 4, src += 4, dst += 4) { - temp = ldl_kernel(src); - stl_kernel(dst, temp); - } - } - break; - case 0x1f: /* Block fill, stda access */ - { - // addr = dst - // fill 32 bytes with val - unsigned int i; - uint32_t dst = addr & 7; - - for (i = 0; i < 32; i += 8, dst += 8) - stq_kernel(dst, val); - } - break; - case 0x20: /* MMU passthrough */ - { - switch(size) { - case 1: - stb_phys(addr, val); - break; - case 2: - stw_phys(addr, val); - break; - case 4: - default: - stl_phys(addr, val); - break; - case 8: - stq_phys(addr, val); - break; - } - } - break; - case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */ - { - switch(size) { - case 1: - stb_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32), val); - break; - case 2: - stw_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32), val); - break; - case 4: - default: - stl_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32), val); - break; - case 8: - stq_phys((target_phys_addr_t)addr - | ((target_phys_addr_t)(asi & 0xf) << 32), val); - break; - } - } - break; - case 0x30: // store buffer tags or Turbosparc secondary cache diagnostic - case 0x31: // store buffer data, Ross RT620 I-cache flush or - // Turbosparc snoop RAM - case 0x32: // store buffer control or Turbosparc page table - // descriptor diagnostic - case 0x36: /* I-cache flash clear */ - case 0x37: /* D-cache flash clear */ - case 0x4c: /* breakpoint action */ - break; - case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/ - { - int reg = (addr >> 8) & 3; - - switch(reg) { - case 0: /* Breakpoint Value (Addr) */ - env->mmubpregs[reg] = (val & 0xfffffffffULL); - break; - case 1: /* Breakpoint Mask */ - env->mmubpregs[reg] = (val & 0xfffffffffULL); - break; - case 2: /* Breakpoint Control */ - env->mmubpregs[reg] = (val & 0x7fULL); - break; - case 3: /* Breakpoint Status */ - env->mmubpregs[reg] = (val & 0xfULL); - break; - } - DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg, - env->mmuregs[reg]); - } - break; - case 8: /* User code access, XXX */ - case 9: /* Supervisor code access, XXX */ - default: - do_unassigned_access(addr, 1, 0, asi, size); - break; - } -#ifdef DEBUG_ASI - dump_asi("write", addr, asi, size, val); -#endif -} - -#endif /* CONFIG_USER_ONLY */ -#else /* TARGET_SPARC64 */ - -#ifdef CONFIG_USER_ONLY -uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) -{ - uint64_t ret = 0; -#if defined(DEBUG_ASI) - target_ulong last_addr = addr; -#endif - - if (asi < 0x80) - raise_exception(TT_PRIV_ACT); - - helper_check_align(addr, size - 1); - addr = asi_address_mask(env, asi, addr); - - switch (asi) { - case 0x82: // Primary no-fault - case 0x8a: // Primary no-fault LE - if (page_check_range(addr, size, PAGE_READ) == -1) { -#ifdef DEBUG_ASI - dump_asi("read ", last_addr, asi, size, ret); -#endif - return 0; - } - // Fall through - case 0x80: // Primary - case 0x88: // Primary LE - { - switch(size) { - case 1: - ret = ldub_raw(addr); - break; - case 2: - ret = lduw_raw(addr); - break; - case 4: - ret = ldl_raw(addr); - break; - default: - case 8: - ret = ldq_raw(addr); - break; - } - } - break; - case 0x83: // Secondary no-fault - case 0x8b: // Secondary no-fault LE - if (page_check_range(addr, size, PAGE_READ) == -1) { -#ifdef DEBUG_ASI - dump_asi("read ", last_addr, asi, size, ret); -#endif - return 0; - } - // Fall through - case 0x81: // Secondary - case 0x89: // Secondary LE - // XXX - break; - default: - break; - } - - /* Convert from little endian */ - switch (asi) { - case 0x88: // Primary LE - case 0x89: // Secondary LE - case 0x8a: // Primary no-fault LE - case 0x8b: // Secondary no-fault LE - switch(size) { - case 2: - ret = bswap16(ret); - break; - case 4: - ret = bswap32(ret); - break; - case 8: - ret = bswap64(ret); - break; - default: - break; - } - default: - break; - } - - /* Convert to signed number */ - if (sign) { - switch(size) { - case 1: - ret = (int8_t) ret; - break; - case 2: - ret = (int16_t) ret; - break; - case 4: - ret = (int32_t) ret; - break; - default: - break; - } - } -#ifdef DEBUG_ASI - dump_asi("read ", last_addr, asi, size, ret); -#endif - return ret; -} - -void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) -{ -#ifdef DEBUG_ASI - dump_asi("write", addr, asi, size, val); -#endif - if (asi < 0x80) - raise_exception(TT_PRIV_ACT); - - helper_check_align(addr, size - 1); - addr = asi_address_mask(env, asi, addr); - - /* Convert to little endian */ - switch (asi) { - case 0x88: // Primary LE - case 0x89: // Secondary LE - switch(size) { - case 2: - val = bswap16(val); - break; - case 4: - val = bswap32(val); - break; - case 8: - val = bswap64(val); - break; - default: - break; - } - default: - break; - } - - switch(asi) { - case 0x80: // Primary - case 0x88: // Primary LE - { - switch(size) { - case 1: - stb_raw(addr, val); - break; - case 2: - stw_raw(addr, val); - break; - case 4: - stl_raw(addr, val); - break; - case 8: - default: - stq_raw(addr, val); - break; - } - } - break; - case 0x81: // Secondary - case 0x89: // Secondary LE - // XXX - return; - - case 0x82: // Primary no-fault, RO - case 0x83: // Secondary no-fault, RO - case 0x8a: // Primary no-fault LE, RO - case 0x8b: // Secondary no-fault LE, RO - default: - do_unassigned_access(addr, 1, 0, 1, size); - return; - } -} - -#else /* CONFIG_USER_ONLY */ - -uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) -{ - uint64_t ret = 0; -#if defined(DEBUG_ASI) - target_ulong last_addr = addr; -#endif - - asi &= 0xff; - - if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) - || (cpu_has_hypervisor(env) - && asi >= 0x30 && asi < 0x80 - && !(env->hpstate & HS_PRIV))) - raise_exception(TT_PRIV_ACT); - - helper_check_align(addr, size - 1); - addr = asi_address_mask(env, asi, addr); - - switch (asi) { - case 0x82: // Primary no-fault - case 0x8a: // Primary no-fault LE - case 0x83: // Secondary no-fault - case 0x8b: // Secondary no-fault LE - { - /* secondary space access has lowest asi bit equal to 1 */ - int access_mmu_idx = ( asi & 1 ) ? MMU_KERNEL_IDX - : MMU_KERNEL_SECONDARY_IDX; - - if (cpu_get_phys_page_nofault(env, addr, access_mmu_idx) == -1ULL) { -#ifdef DEBUG_ASI - dump_asi("read ", last_addr, asi, size, ret); -#endif - return 0; - } - } - // Fall through - case 0x10: // As if user primary - case 0x11: // As if user secondary - case 0x18: // As if user primary LE - case 0x19: // As if user secondary LE - case 0x80: // Primary - case 0x81: // Secondary - case 0x88: // Primary LE - case 0x89: // Secondary LE - case 0xe2: // UA2007 Primary block init - case 0xe3: // UA2007 Secondary block init - if ((asi & 0x80) && (env->pstate & PS_PRIV)) { - if (cpu_hypervisor_mode(env)) { - switch(size) { - case 1: - ret = ldub_hypv(addr); - break; - case 2: - ret = lduw_hypv(addr); - break; - case 4: - ret = ldl_hypv(addr); - break; - default: - case 8: - ret = ldq_hypv(addr); - break; - } - } else { - /* secondary space access has lowest asi bit equal to 1 */ - if (asi & 1) { - switch(size) { - case 1: - ret = ldub_kernel_secondary(addr); - break; - case 2: - ret = lduw_kernel_secondary(addr); - break; - case 4: - ret = ldl_kernel_secondary(addr); - break; - default: - case 8: - ret = ldq_kernel_secondary(addr); - break; - } - } else { - switch(size) { - case 1: - ret = ldub_kernel(addr); - break; - case 2: - ret = lduw_kernel(addr); - break; - case 4: - ret = ldl_kernel(addr); - break; - default: - case 8: - ret = ldq_kernel(addr); - break; - } - } - } - } else { - /* secondary space access has lowest asi bit equal to 1 */ - if (asi & 1) { - switch(size) { - case 1: - ret = ldub_user_secondary(addr); - break; - case 2: - ret = lduw_user_secondary(addr); - break; - case 4: - ret = ldl_user_secondary(addr); - break; - default: - case 8: - ret = ldq_user_secondary(addr); - break; - } - } else { - switch(size) { - case 1: - ret = ldub_user(addr); - break; - case 2: - ret = lduw_user(addr); - break; - case 4: - ret = ldl_user(addr); - break; - default: - case 8: - ret = ldq_user(addr); - break; - } - } - } - break; - case 0x14: // Bypass - case 0x15: // Bypass, non-cacheable - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE - { - switch(size) { - case 1: - ret = ldub_phys(addr); - break; - case 2: - ret = lduw_phys(addr); - break; - case 4: - ret = ldl_phys(addr); - break; - default: - case 8: - ret = ldq_phys(addr); - break; - } - break; - } - case 0x24: // Nucleus quad LDD 128 bit atomic - case 0x2c: // Nucleus quad LDD 128 bit atomic LE - // Only ldda allowed - raise_exception(TT_ILL_INSN); - return 0; - case 0x04: // Nucleus - case 0x0c: // Nucleus Little Endian (LE) - { - switch(size) { - case 1: - ret = ldub_nucleus(addr); - break; - case 2: - ret = lduw_nucleus(addr); - break; - case 4: - ret = ldl_nucleus(addr); - break; - default: - case 8: - ret = ldq_nucleus(addr); - break; - } - break; - } - case 0x4a: // UPA config - // XXX - break; - case 0x45: // LSU - ret = env->lsu; - break; - case 0x50: // I-MMU regs - { - int reg = (addr >> 3) & 0xf; - - if (reg == 0) { - // I-TSB Tag Target register - ret = ultrasparc_tag_target(env->immu.tag_access); - } else { - ret = env->immuregs[reg]; - } - - break; - } - case 0x51: // I-MMU 8k TSB pointer - { - // env->immuregs[5] holds I-MMU TSB register value - // env->immuregs[6] holds I-MMU Tag Access register value - ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access, - 8*1024); - break; - } - case 0x52: // I-MMU 64k TSB pointer - { - // env->immuregs[5] holds I-MMU TSB register value - // env->immuregs[6] holds I-MMU Tag Access register value - ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access, - 64*1024); - break; - } - case 0x55: // I-MMU data access - { - int reg = (addr >> 3) & 0x3f; - - ret = env->itlb[reg].tte; - break; - } - case 0x56: // I-MMU tag read - { - int reg = (addr >> 3) & 0x3f; - - ret = env->itlb[reg].tag; - break; - } - case 0x58: // D-MMU regs - { - int reg = (addr >> 3) & 0xf; - - if (reg == 0) { - // D-TSB Tag Target register - ret = ultrasparc_tag_target(env->dmmu.tag_access); - } else { - ret = env->dmmuregs[reg]; - } - break; - } - case 0x59: // D-MMU 8k TSB pointer - { - // env->dmmuregs[5] holds D-MMU TSB register value - // env->dmmuregs[6] holds D-MMU Tag Access register value - ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access, - 8*1024); - break; - } - case 0x5a: // D-MMU 64k TSB pointer - { - // env->dmmuregs[5] holds D-MMU TSB register value - // env->dmmuregs[6] holds D-MMU Tag Access register value - ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access, - 64*1024); - break; - } - case 0x5d: // D-MMU data access - { - int reg = (addr >> 3) & 0x3f; - - ret = env->dtlb[reg].tte; - break; - } - case 0x5e: // D-MMU tag read - { - int reg = (addr >> 3) & 0x3f; - - ret = env->dtlb[reg].tag; - break; - } - case 0x46: // D-cache data - case 0x47: // D-cache tag access - case 0x4b: // E-cache error enable - case 0x4c: // E-cache asynchronous fault status - case 0x4d: // E-cache asynchronous fault address - case 0x4e: // E-cache tag data - case 0x66: // I-cache instruction access - case 0x67: // I-cache tag access - case 0x6e: // I-cache predecode - case 0x6f: // I-cache LRU etc. - case 0x76: // E-cache tag - case 0x7e: // E-cache tag - break; - case 0x5b: // D-MMU data pointer - case 0x48: // Interrupt dispatch, RO - case 0x49: // Interrupt data receive - case 0x7f: // Incoming interrupt vector, RO - // XXX - break; - case 0x54: // I-MMU data in, WO - case 0x57: // I-MMU demap, WO - case 0x5c: // D-MMU data in, WO - case 0x5f: // D-MMU demap, WO - case 0x77: // Interrupt vector, WO - default: - do_unassigned_access(addr, 0, 0, 1, size); - ret = 0; - break; - } - - /* Convert from little endian */ - switch (asi) { - case 0x0c: // Nucleus Little Endian (LE) - case 0x18: // As if user primary LE - case 0x19: // As if user secondary LE - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE - case 0x88: // Primary LE - case 0x89: // Secondary LE - case 0x8a: // Primary no-fault LE - case 0x8b: // Secondary no-fault LE - switch(size) { - case 2: - ret = bswap16(ret); - break; - case 4: - ret = bswap32(ret); - break; - case 8: - ret = bswap64(ret); - break; - default: - break; - } - default: - break; - } - - /* Convert to signed number */ - if (sign) { - switch(size) { - case 1: - ret = (int8_t) ret; - break; - case 2: - ret = (int16_t) ret; - break; - case 4: - ret = (int32_t) ret; - break; - default: - break; - } - } -#ifdef DEBUG_ASI - dump_asi("read ", last_addr, asi, size, ret); -#endif - return ret; -} - -void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) -{ -#ifdef DEBUG_ASI - dump_asi("write", addr, asi, size, val); -#endif - - asi &= 0xff; - - if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) - || (cpu_has_hypervisor(env) - && asi >= 0x30 && asi < 0x80 - && !(env->hpstate & HS_PRIV))) - raise_exception(TT_PRIV_ACT); - - helper_check_align(addr, size - 1); - addr = asi_address_mask(env, asi, addr); - - /* Convert to little endian */ - switch (asi) { - case 0x0c: // Nucleus Little Endian (LE) - case 0x18: // As if user primary LE - case 0x19: // As if user secondary LE - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE - case 0x88: // Primary LE - case 0x89: // Secondary LE - switch(size) { - case 2: - val = bswap16(val); - break; - case 4: - val = bswap32(val); - break; - case 8: - val = bswap64(val); - break; - default: - break; - } - default: - break; - } - - switch(asi) { - case 0x10: // As if user primary - case 0x11: // As if user secondary - case 0x18: // As if user primary LE - case 0x19: // As if user secondary LE - case 0x80: // Primary - case 0x81: // Secondary - case 0x88: // Primary LE - case 0x89: // Secondary LE - case 0xe2: // UA2007 Primary block init - case 0xe3: // UA2007 Secondary block init - if ((asi & 0x80) && (env->pstate & PS_PRIV)) { - if (cpu_hypervisor_mode(env)) { - switch(size) { - case 1: - stb_hypv(addr, val); - break; - case 2: - stw_hypv(addr, val); - break; - case 4: - stl_hypv(addr, val); - break; - case 8: - default: - stq_hypv(addr, val); - break; - } - } else { - /* secondary space access has lowest asi bit equal to 1 */ - if (asi & 1) { - switch(size) { - case 1: - stb_kernel_secondary(addr, val); - break; - case 2: - stw_kernel_secondary(addr, val); - break; - case 4: - stl_kernel_secondary(addr, val); - break; - case 8: - default: - stq_kernel_secondary(addr, val); - break; - } - } else { - switch(size) { - case 1: - stb_kernel(addr, val); - break; - case 2: - stw_kernel(addr, val); - break; - case 4: - stl_kernel(addr, val); - break; - case 8: - default: - stq_kernel(addr, val); - break; - } - } - } - } else { - /* secondary space access has lowest asi bit equal to 1 */ - if (asi & 1) { - switch(size) { - case 1: - stb_user_secondary(addr, val); - break; - case 2: - stw_user_secondary(addr, val); - break; - case 4: - stl_user_secondary(addr, val); - break; - case 8: - default: - stq_user_secondary(addr, val); - break; - } - } else { - switch(size) { - case 1: - stb_user(addr, val); - break; - case 2: - stw_user(addr, val); - break; - case 4: - stl_user(addr, val); - break; - case 8: - default: - stq_user(addr, val); - break; - } - } - } - break; - case 0x14: // Bypass - case 0x15: // Bypass, non-cacheable - case 0x1c: // Bypass LE - case 0x1d: // Bypass, non-cacheable LE - { - switch(size) { - case 1: - stb_phys(addr, val); - break; - case 2: - stw_phys(addr, val); - break; - case 4: - stl_phys(addr, val); - break; - case 8: - default: - stq_phys(addr, val); - break; - } - } - return; - case 0x24: // Nucleus quad LDD 128 bit atomic - case 0x2c: // Nucleus quad LDD 128 bit atomic LE - // Only ldda allowed - raise_exception(TT_ILL_INSN); - return; - case 0x04: // Nucleus - case 0x0c: // Nucleus Little Endian (LE) - { - switch(size) { - case 1: - stb_nucleus(addr, val); - break; - case 2: - stw_nucleus(addr, val); - break; - case 4: - stl_nucleus(addr, val); - break; - default: - case 8: - stq_nucleus(addr, val); - break; - } - break; - } - - case 0x4a: // UPA config - // XXX - return; - case 0x45: // LSU - { - uint64_t oldreg; - - oldreg = env->lsu; - env->lsu = val & (DMMU_E | IMMU_E); - // Mappings generated during D/I MMU disabled mode are - // invalid in normal mode - if (oldreg != env->lsu) { - DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", - oldreg, env->lsu); -#ifdef DEBUG_MMU - dump_mmu(stdout, fprintf, env1); -#endif - tlb_flush(env, 1); - } - return; - } - case 0x50: // I-MMU regs - { - int reg = (addr >> 3) & 0xf; - uint64_t oldreg; - - oldreg = env->immuregs[reg]; - switch(reg) { - case 0: // RO - return; - case 1: // Not in I-MMU - case 2: - return; - case 3: // SFSR - if ((val & 1) == 0) - val = 0; // Clear SFSR - env->immu.sfsr = val; - break; - case 4: // RO - return; - case 5: // TSB access - DPRINTF_MMU("immu TSB write: 0x%016" PRIx64 " -> 0x%016" - PRIx64 "\n", env->immu.tsb, val); - env->immu.tsb = val; - break; - case 6: // Tag access - env->immu.tag_access = val; - break; - case 7: - case 8: - return; - default: - break; - } - - if (oldreg != env->immuregs[reg]) { - DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64 " -> 0x%016" - PRIx64 "\n", reg, oldreg, env->immuregs[reg]); - } -#ifdef DEBUG_MMU - dump_mmu(stdout, fprintf, env); -#endif - return; - } - case 0x54: // I-MMU data in - replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env); - return; - case 0x55: // I-MMU data access - { - // TODO: auto demap - - unsigned int i = (addr >> 3) & 0x3f; - - replace_tlb_entry(&env->itlb[i], env->immu.tag_access, val, env); - -#ifdef DEBUG_MMU - DPRINTF_MMU("immu data access replaced entry [%i]\n", i); - dump_mmu(stdout, fprintf, env); -#endif - return; - } - case 0x57: // I-MMU demap - demap_tlb(env->itlb, addr, "immu", env); - return; - case 0x58: // D-MMU regs - { - int reg = (addr >> 3) & 0xf; - uint64_t oldreg; - - oldreg = env->dmmuregs[reg]; - switch(reg) { - case 0: // RO - case 4: - return; - case 3: // SFSR - if ((val & 1) == 0) { - val = 0; // Clear SFSR, Fault address - env->dmmu.sfar = 0; - } - env->dmmu.sfsr = val; - break; - case 1: // Primary context - env->dmmu.mmu_primary_context = val; - /* can be optimized to only flush MMU_USER_IDX - and MMU_KERNEL_IDX entries */ - tlb_flush(env, 1); - break; - case 2: // Secondary context - env->dmmu.mmu_secondary_context = val; - /* can be optimized to only flush MMU_USER_SECONDARY_IDX - and MMU_KERNEL_SECONDARY_IDX entries */ - tlb_flush(env, 1); - break; - case 5: // TSB access - DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016" - PRIx64 "\n", env->dmmu.tsb, val); - env->dmmu.tsb = val; - break; - case 6: // Tag access - env->dmmu.tag_access = val; - break; - case 7: // Virtual Watchpoint - case 8: // Physical Watchpoint - default: - env->dmmuregs[reg] = val; - break; - } - - if (oldreg != env->dmmuregs[reg]) { - DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64 " -> 0x%016" - PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]); - } -#ifdef DEBUG_MMU - dump_mmu(stdout, fprintf, env); -#endif - return; - } - case 0x5c: // D-MMU data in - replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env); - return; - case 0x5d: // D-MMU data access - { - unsigned int i = (addr >> 3) & 0x3f; - - replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, val, env); - -#ifdef DEBUG_MMU - DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i); - dump_mmu(stdout, fprintf, env); -#endif - return; - } - case 0x5f: // D-MMU demap - demap_tlb(env->dtlb, addr, "dmmu", env); - return; - case 0x49: // Interrupt data receive - // XXX - return; - case 0x46: // D-cache data - case 0x47: // D-cache tag access - case 0x4b: // E-cache error enable - case 0x4c: // E-cache asynchronous fault status - case 0x4d: // E-cache asynchronous fault address - case 0x4e: // E-cache tag data - case 0x66: // I-cache instruction access - case 0x67: // I-cache tag access - case 0x6e: // I-cache predecode - case 0x6f: // I-cache LRU etc. - case 0x76: // E-cache tag - case 0x7e: // E-cache tag - return; - case 0x51: // I-MMU 8k TSB pointer, RO - case 0x52: // I-MMU 64k TSB pointer, RO - case 0x56: // I-MMU tag read, RO - case 0x59: // D-MMU 8k TSB pointer, RO - case 0x5a: // D-MMU 64k TSB pointer, RO - case 0x5b: // D-MMU data pointer, RO - case 0x5e: // D-MMU tag read, RO - case 0x48: // Interrupt dispatch, RO - case 0x7f: // Incoming interrupt vector, RO - case 0x82: // Primary no-fault, RO - case 0x83: // Secondary no-fault, RO - case 0x8a: // Primary no-fault LE, RO - case 0x8b: // Secondary no-fault LE, RO - default: - do_unassigned_access(addr, 1, 0, 1, size); - return; - } -} -#endif /* CONFIG_USER_ONLY */ - -void helper_ldda_asi(target_ulong addr, int asi, int rd) -{ - if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) - || (cpu_has_hypervisor(env) - && asi >= 0x30 && asi < 0x80 - && !(env->hpstate & HS_PRIV))) - raise_exception(TT_PRIV_ACT); - - addr = asi_address_mask(env, asi, addr); - - switch (asi) { -#if !defined(CONFIG_USER_ONLY) - case 0x24: // Nucleus quad LDD 128 bit atomic - case 0x2c: // Nucleus quad LDD 128 bit atomic LE - helper_check_align(addr, 0xf); - if (rd == 0) { - env->gregs[1] = ldq_nucleus(addr + 8); - if (asi == 0x2c) - bswap64s(&env->gregs[1]); - } else if (rd < 8) { - env->gregs[rd] = ldq_nucleus(addr); - env->gregs[rd + 1] = ldq_nucleus(addr + 8); - if (asi == 0x2c) { - bswap64s(&env->gregs[rd]); - bswap64s(&env->gregs[rd + 1]); - } - } else { - env->regwptr[rd] = ldq_nucleus(addr); - env->regwptr[rd + 1] = ldq_nucleus(addr + 8); - if (asi == 0x2c) { - bswap64s(&env->regwptr[rd]); - bswap64s(&env->regwptr[rd + 1]); - } - } - break; -#endif - default: - helper_check_align(addr, 0x3); - if (rd == 0) - env->gregs[1] = helper_ld_asi(addr + 4, asi, 4, 0); - else if (rd < 8) { - env->gregs[rd] = helper_ld_asi(addr, asi, 4, 0); - env->gregs[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0); - } else { - env->regwptr[rd] = helper_ld_asi(addr, asi, 4, 0); - env->regwptr[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0); - } - break; - } -} - -void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) -{ - unsigned int i; - target_ulong val; - - helper_check_align(addr, 3); - addr = asi_address_mask(env, asi, addr); - - switch (asi) { - case 0xf0: // Block load primary - case 0xf1: // Block load secondary - case 0xf8: // Block load primary LE - case 0xf9: // Block load secondary LE - if (rd & 7) { - raise_exception(TT_ILL_INSN); - return; - } - helper_check_align(addr, 0x3f); - for (i = 0; i < 16; i++) { - *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4, - 0); - addr += 4; - } - - return; - case 0x70: // Block load primary, user privilege - case 0x71: // Block load secondary, user privilege - if (rd & 7) { - raise_exception(TT_ILL_INSN); - return; - } - helper_check_align(addr, 0x3f); - for (i = 0; i < 16; i++) { - *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x1f, 4, - 0); - addr += 4; - } - - return; - default: - break; - } - - val = helper_ld_asi(addr, asi, size, 0); - switch(size) { - default: - case 4: - *((uint32_t *)&env->fpr[rd]) = val; - break; - case 8: - *((int64_t *)&DT0) = val; - break; - case 16: - // XXX - break; - } -} - -void helper_stf_asi(target_ulong addr, int asi, int size, int rd) -{ - unsigned int i; - target_ulong val = 0; - - helper_check_align(addr, 3); - addr = asi_address_mask(env, asi, addr); - - switch (asi) { - case 0xe0: // UA2007 Block commit store primary (cache flush) - case 0xe1: // UA2007 Block commit store secondary (cache flush) - case 0xf0: // Block store primary - case 0xf1: // Block store secondary - case 0xf8: // Block store primary LE - case 0xf9: // Block store secondary LE - if (rd & 7) { - raise_exception(TT_ILL_INSN); - return; - } - helper_check_align(addr, 0x3f); - for (i = 0; i < 16; i++) { - val = *(uint32_t *)&env->fpr[rd++]; - helper_st_asi(addr, val, asi & 0x8f, 4); - addr += 4; - } - - return; - case 0x70: // Block store primary, user privilege - case 0x71: // Block store secondary, user privilege - if (rd & 7) { - raise_exception(TT_ILL_INSN); - return; - } - helper_check_align(addr, 0x3f); - for (i = 0; i < 16; i++) { - val = *(uint32_t *)&env->fpr[rd++]; - helper_st_asi(addr, val, asi & 0x1f, 4); - addr += 4; - } - - return; - default: - break; - } - - switch(size) { - default: - case 4: - val = *((uint32_t *)&env->fpr[rd]); - break; - case 8: - val = *((int64_t *)&DT0); - break; - case 16: - // XXX - break; - } - helper_st_asi(addr, val, asi, size); -} - -target_ulong helper_cas_asi(target_ulong addr, target_ulong val1, - target_ulong val2, uint32_t asi) -{ - target_ulong ret; - - val2 &= 0xffffffffUL; - ret = helper_ld_asi(addr, asi, 4, 0); - ret &= 0xffffffffUL; - if (val2 == ret) - helper_st_asi(addr, val1 & 0xffffffffUL, asi, 4); - return ret; -} - -target_ulong helper_casx_asi(target_ulong addr, target_ulong val1, - target_ulong val2, uint32_t asi) -{ - target_ulong ret; - - ret = helper_ld_asi(addr, asi, 8, 0); - if (val2 == ret) - helper_st_asi(addr, val1, asi, 8); - return ret; -} -#endif /* TARGET_SPARC64 */ - -#ifndef TARGET_SPARC64 -void helper_rett(void) -{ - unsigned int cwp; - - if (env->psret == 1) - raise_exception(TT_ILL_INSN); - - env->psret = 1; - cwp = cwp_inc(env->cwp + 1) ; - if (env->wim & (1 << cwp)) { - raise_exception(TT_WIN_UNF); - } - set_cwp(cwp); - env->psrs = env->psrps; -} -#endif - -static target_ulong helper_udiv_common(target_ulong a, target_ulong b, int cc) -{ - int overflow = 0; - uint64_t x0; - uint32_t x1; - - x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); - x1 = (b & 0xffffffff); - - if (x1 == 0) { - raise_exception(TT_DIV_ZERO); - } - - x0 = x0 / x1; - if (x0 > 0xffffffff) { - x0 = 0xffffffff; - overflow = 1; - } - - if (cc) { - env->cc_dst = x0; - env->cc_src2 = overflow; - env->cc_op = CC_OP_DIV; - } - return x0; -} - -target_ulong helper_udiv(target_ulong a, target_ulong b) -{ - return helper_udiv_common(a, b, 0); -} - -target_ulong helper_udiv_cc(target_ulong a, target_ulong b) -{ - return helper_udiv_common(a, b, 1); -} - -static target_ulong helper_sdiv_common(target_ulong a, target_ulong b, int cc) -{ - int overflow = 0; - int64_t x0; - int32_t x1; - - x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); - x1 = (b & 0xffffffff); - - if (x1 == 0) { - raise_exception(TT_DIV_ZERO); - } - - x0 = x0 / x1; - if ((int32_t) x0 != x0) { - x0 = x0 < 0 ? 0x80000000: 0x7fffffff; - overflow = 1; - } - - if (cc) { - env->cc_dst = x0; - env->cc_src2 = overflow; - env->cc_op = CC_OP_DIV; - } - return x0; -} - -target_ulong helper_sdiv(target_ulong a, target_ulong b) -{ - return helper_sdiv_common(a, b, 0); -} - -target_ulong helper_sdiv_cc(target_ulong a, target_ulong b) -{ - return helper_sdiv_common(a, b, 1); -} - -void helper_stdf(target_ulong addr, int mem_idx) -{ - helper_check_align(addr, 7); -#if !defined(CONFIG_USER_ONLY) - switch (mem_idx) { - case MMU_USER_IDX: - stfq_user(addr, DT0); - break; - case MMU_KERNEL_IDX: - stfq_kernel(addr, DT0); - break; -#ifdef TARGET_SPARC64 - case MMU_HYPV_IDX: - stfq_hypv(addr, DT0); - break; -#endif - default: - DPRINTF_MMU("helper_stdf: need to check MMU idx %d\n", mem_idx); - break; - } -#else - stfq_raw(address_mask(env, addr), DT0); -#endif -} - -void helper_lddf(target_ulong addr, int mem_idx) -{ - helper_check_align(addr, 7); -#if !defined(CONFIG_USER_ONLY) - switch (mem_idx) { - case MMU_USER_IDX: - DT0 = ldfq_user(addr); - break; - case MMU_KERNEL_IDX: - DT0 = ldfq_kernel(addr); - break; -#ifdef TARGET_SPARC64 - case MMU_HYPV_IDX: - DT0 = ldfq_hypv(addr); - break; -#endif - default: - DPRINTF_MMU("helper_lddf: need to check MMU idx %d\n", mem_idx); - break; - } -#else - DT0 = ldfq_raw(address_mask(env, addr)); -#endif -} - -void helper_ldqf(target_ulong addr, int mem_idx) -{ - // XXX add 128 bit load - CPU_QuadU u; - - helper_check_align(addr, 7); -#if !defined(CONFIG_USER_ONLY) - switch (mem_idx) { - case MMU_USER_IDX: - u.ll.upper = ldq_user(addr); - u.ll.lower = ldq_user(addr + 8); - QT0 = u.q; - break; - case MMU_KERNEL_IDX: - u.ll.upper = ldq_kernel(addr); - u.ll.lower = ldq_kernel(addr + 8); - QT0 = u.q; - break; -#ifdef TARGET_SPARC64 - case MMU_HYPV_IDX: - u.ll.upper = ldq_hypv(addr); - u.ll.lower = ldq_hypv(addr + 8); - QT0 = u.q; - break; -#endif - default: - DPRINTF_MMU("helper_ldqf: need to check MMU idx %d\n", mem_idx); - break; - } -#else - u.ll.upper = ldq_raw(address_mask(env, addr)); - u.ll.lower = ldq_raw(address_mask(env, addr + 8)); - QT0 = u.q; -#endif -} - -void helper_stqf(target_ulong addr, int mem_idx) -{ - // XXX add 128 bit store - CPU_QuadU u; - - helper_check_align(addr, 7); -#if !defined(CONFIG_USER_ONLY) - switch (mem_idx) { - case MMU_USER_IDX: - u.q = QT0; - stq_user(addr, u.ll.upper); - stq_user(addr + 8, u.ll.lower); - break; - case MMU_KERNEL_IDX: - u.q = QT0; - stq_kernel(addr, u.ll.upper); - stq_kernel(addr + 8, u.ll.lower); - break; -#ifdef TARGET_SPARC64 - case MMU_HYPV_IDX: - u.q = QT0; - stq_hypv(addr, u.ll.upper); - stq_hypv(addr + 8, u.ll.lower); - break; -#endif - default: - DPRINTF_MMU("helper_stqf: need to check MMU idx %d\n", mem_idx); - break; - } -#else - u.q = QT0; - stq_raw(address_mask(env, addr), u.ll.upper); - stq_raw(address_mask(env, addr + 8), u.ll.lower); -#endif -} - -static inline void set_fsr(void) -{ - int rnd_mode; - - switch (env->fsr & FSR_RD_MASK) { - case FSR_RD_NEAREST: - rnd_mode = float_round_nearest_even; - break; - default: - case FSR_RD_ZERO: - rnd_mode = float_round_to_zero; - break; - case FSR_RD_POS: - rnd_mode = float_round_up; - break; - case FSR_RD_NEG: - rnd_mode = float_round_down; - break; - } - set_float_rounding_mode(rnd_mode, &env->fp_status); -} - -void helper_ldfsr(uint32_t new_fsr) -{ - env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK); - set_fsr(); -} - -#ifdef TARGET_SPARC64 -void helper_ldxfsr(uint64_t new_fsr) -{ - env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK); - set_fsr(); -} -#endif - -void helper_debug(void) -{ - env->exception_index = EXCP_DEBUG; - cpu_loop_exit(); -} - -#ifndef TARGET_SPARC64 -/* XXX: use another pointer for %iN registers to avoid slow wrapping - handling ? */ -void helper_save(void) -{ - uint32_t cwp; - - cwp = cwp_dec(env->cwp - 1); - if (env->wim & (1 << cwp)) { - raise_exception(TT_WIN_OVF); - } - set_cwp(cwp); -} - -void helper_restore(void) -{ - uint32_t cwp; - - cwp = cwp_inc(env->cwp + 1); - if (env->wim & (1 << cwp)) { - raise_exception(TT_WIN_UNF); - } - set_cwp(cwp); -} - -void helper_wrpsr(target_ulong new_psr) -{ - if ((new_psr & PSR_CWP) >= env->nwindows) { - raise_exception(TT_ILL_INSN); - } else { - cpu_put_psr(env, new_psr); - } -} - -target_ulong helper_rdpsr(void) -{ - return get_psr(); -} - -#else -/* XXX: use another pointer for %iN registers to avoid slow wrapping - handling ? */ -void helper_save(void) -{ - uint32_t cwp; - - cwp = cwp_dec(env->cwp - 1); - if (env->cansave == 0) { - raise_exception(TT_SPILL | (env->otherwin != 0 ? - (TT_WOTHER | ((env->wstate & 0x38) >> 1)): - ((env->wstate & 0x7) << 2))); - } else { - if (env->cleanwin - env->canrestore == 0) { - // XXX Clean windows without trap - raise_exception(TT_CLRWIN); - } else { - env->cansave--; - env->canrestore++; - set_cwp(cwp); - } - } -} - -void helper_restore(void) -{ - uint32_t cwp; - - cwp = cwp_inc(env->cwp + 1); - if (env->canrestore == 0) { - raise_exception(TT_FILL | (env->otherwin != 0 ? - (TT_WOTHER | ((env->wstate & 0x38) >> 1)): - ((env->wstate & 0x7) << 2))); - } else { - env->cansave++; - env->canrestore--; - set_cwp(cwp); - } -} - -void helper_flushw(void) -{ - if (env->cansave != env->nwindows - 2) { - raise_exception(TT_SPILL | (env->otherwin != 0 ? - (TT_WOTHER | ((env->wstate & 0x38) >> 1)): - ((env->wstate & 0x7) << 2))); - } -} - -void helper_saved(void) -{ - env->cansave++; - if (env->otherwin == 0) - env->canrestore--; - else - env->otherwin--; -} - -void helper_restored(void) -{ - env->canrestore++; - if (env->cleanwin < env->nwindows - 1) - env->cleanwin++; - if (env->otherwin == 0) - env->cansave--; - else - env->otherwin--; -} - -static target_ulong get_ccr(void) -{ - target_ulong psr; - - psr = get_psr(); - - return ((env->xcc >> 20) << 4) | ((psr & PSR_ICC) >> 20); -} - -target_ulong cpu_get_ccr(CPUState *env1) -{ - CPUState *saved_env; - target_ulong ret; - - saved_env = env; - env = env1; - ret = get_ccr(); - env = saved_env; - return ret; -} - -static void put_ccr(target_ulong val) -{ - target_ulong tmp = val; - - env->xcc = (tmp >> 4) << 20; - env->psr = (tmp & 0xf) << 20; - CC_OP = CC_OP_FLAGS; -} - -void cpu_put_ccr(CPUState *env1, target_ulong val) -{ - CPUState *saved_env; - - saved_env = env; - env = env1; - put_ccr(val); - env = saved_env; -} - -static target_ulong get_cwp64(void) -{ - return env->nwindows - 1 - env->cwp; -} - -target_ulong cpu_get_cwp64(CPUState *env1) -{ - CPUState *saved_env; - target_ulong ret; - - saved_env = env; - env = env1; - ret = get_cwp64(); - env = saved_env; - return ret; -} - -static void put_cwp64(int cwp) -{ - if (unlikely(cwp >= env->nwindows || cwp < 0)) { - cwp %= env->nwindows; - } - set_cwp(env->nwindows - 1 - cwp); -} - -void cpu_put_cwp64(CPUState *env1, int cwp) -{ - CPUState *saved_env; - - saved_env = env; - env = env1; - put_cwp64(cwp); - env = saved_env; -} - -target_ulong helper_rdccr(void) -{ - return get_ccr(); -} - -void helper_wrccr(target_ulong new_ccr) -{ - put_ccr(new_ccr); -} - -// CWP handling is reversed in V9, but we still use the V8 register -// order. -target_ulong helper_rdcwp(void) -{ - return get_cwp64(); -} - -void helper_wrcwp(target_ulong new_cwp) -{ - put_cwp64(new_cwp); -} - -// This function uses non-native bit order -#define GET_FIELD(X, FROM, TO) \ - ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1)) - -// This function uses the order in the manuals, i.e. bit 0 is 2^0 -#define GET_FIELD_SP(X, FROM, TO) \ - GET_FIELD(X, 63 - (TO), 63 - (FROM)) - -target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize) -{ - return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) | - (GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) | - (GET_FIELD_SP(pixel_addr, 17 + cubesize - 1, 17) << 17) | - (GET_FIELD_SP(pixel_addr, 56, 59) << 13) | - (GET_FIELD_SP(pixel_addr, 35, 38) << 9) | - (GET_FIELD_SP(pixel_addr, 13, 16) << 5) | - (((pixel_addr >> 55) & 1) << 4) | - (GET_FIELD_SP(pixel_addr, 33, 34) << 2) | - GET_FIELD_SP(pixel_addr, 11, 12); -} - -target_ulong helper_alignaddr(target_ulong addr, target_ulong offset) -{ - uint64_t tmp; - - tmp = addr + offset; - env->gsr &= ~7ULL; - env->gsr |= tmp & 7ULL; - return tmp & ~7ULL; -} - -target_ulong helper_popc(target_ulong val) -{ - return ctpop64(val); -} - -static inline uint64_t *get_gregset(uint32_t pstate) -{ - switch (pstate) { - default: - DPRINTF_PSTATE("ERROR in get_gregset: active pstate bits=%x%s%s%s\n", - pstate, - (pstate & PS_IG) ? " IG" : "", - (pstate & PS_MG) ? " MG" : "", - (pstate & PS_AG) ? " AG" : ""); - /* pass through to normal set of global registers */ - case 0: - return env->bgregs; - case PS_AG: - return env->agregs; - case PS_MG: - return env->mgregs; - case PS_IG: - return env->igregs; - } -} - -static inline void change_pstate(uint32_t new_pstate) -{ - uint32_t pstate_regs, new_pstate_regs; - uint64_t *src, *dst; - - if (env->def->features & CPU_FEATURE_GL) { - // PS_AG is not implemented in this case - new_pstate &= ~PS_AG; - } - - pstate_regs = env->pstate & 0xc01; - new_pstate_regs = new_pstate & 0xc01; - - if (new_pstate_regs != pstate_regs) { - DPRINTF_PSTATE("change_pstate: switching regs old=%x new=%x\n", - pstate_regs, new_pstate_regs); - // Switch global register bank - src = get_gregset(new_pstate_regs); - dst = get_gregset(pstate_regs); - memcpy32(dst, env->gregs); - memcpy32(env->gregs, src); - } - else { - DPRINTF_PSTATE("change_pstate: regs new=%x (unchanged)\n", - new_pstate_regs); - } - env->pstate = new_pstate; -} - -void helper_wrpstate(target_ulong new_state) -{ - change_pstate(new_state & 0xf3f); - -#if !defined(CONFIG_USER_ONLY) - if (cpu_interrupts_enabled(env)) { - cpu_check_irqs(env); - } -#endif -} - -void helper_wrpil(target_ulong new_pil) -{ -#if !defined(CONFIG_USER_ONLY) - DPRINTF_PSTATE("helper_wrpil old=%x new=%x\n", - env->psrpil, (uint32_t)new_pil); - - env->psrpil = new_pil; - - if (cpu_interrupts_enabled(env)) { - cpu_check_irqs(env); - } -#endif -} - -void helper_done(void) -{ - trap_state* tsptr = cpu_tsptr(env); - - env->pc = tsptr->tnpc; - env->npc = tsptr->tnpc + 4; - put_ccr(tsptr->tstate >> 32); - env->asi = (tsptr->tstate >> 24) & 0xff; - change_pstate((tsptr->tstate >> 8) & 0xf3f); - put_cwp64(tsptr->tstate & 0xff); - env->tl--; - - DPRINTF_PSTATE("... helper_done tl=%d\n", env->tl); - -#if !defined(CONFIG_USER_ONLY) - if (cpu_interrupts_enabled(env)) { - cpu_check_irqs(env); - } -#endif -} - -void helper_retry(void) -{ - trap_state* tsptr = cpu_tsptr(env); - - env->pc = tsptr->tpc; - env->npc = tsptr->tnpc; - put_ccr(tsptr->tstate >> 32); - env->asi = (tsptr->tstate >> 24) & 0xff; - change_pstate((tsptr->tstate >> 8) & 0xf3f); - put_cwp64(tsptr->tstate & 0xff); - env->tl--; - - DPRINTF_PSTATE("... helper_retry tl=%d\n", env->tl); - -#if !defined(CONFIG_USER_ONLY) - if (cpu_interrupts_enabled(env)) { - cpu_check_irqs(env); - } -#endif -} - -static void do_modify_softint(const char* operation, uint32_t value) -{ - if (env->softint != value) { - env->softint = value; - DPRINTF_PSTATE(": %s new %08x\n", operation, env->softint); -#if !defined(CONFIG_USER_ONLY) - if (cpu_interrupts_enabled(env)) { - cpu_check_irqs(env); - } -#endif - } -} - -void helper_set_softint(uint64_t value) -{ - do_modify_softint("helper_set_softint", env->softint | (uint32_t)value); -} - -void helper_clear_softint(uint64_t value) -{ - do_modify_softint("helper_clear_softint", env->softint & (uint32_t)~value); -} - -void helper_write_softint(uint64_t value) -{ - do_modify_softint("helper_write_softint", (uint32_t)value); -} -#endif - -void helper_flush(target_ulong addr) -{ - addr &= ~7; - tb_invalidate_page_range(addr, addr + 8); -} - -#ifdef TARGET_SPARC64 -#ifdef DEBUG_PCALL -static const char * const excp_names[0x80] = { - [TT_TFAULT] = "Instruction Access Fault", - [TT_TMISS] = "Instruction Access MMU Miss", - [TT_CODE_ACCESS] = "Instruction Access Error", - [TT_ILL_INSN] = "Illegal Instruction", - [TT_PRIV_INSN] = "Privileged Instruction", - [TT_NFPU_INSN] = "FPU Disabled", - [TT_FP_EXCP] = "FPU Exception", - [TT_TOVF] = "Tag Overflow", - [TT_CLRWIN] = "Clean Windows", - [TT_DIV_ZERO] = "Division By Zero", - [TT_DFAULT] = "Data Access Fault", - [TT_DMISS] = "Data Access MMU Miss", - [TT_DATA_ACCESS] = "Data Access Error", - [TT_DPROT] = "Data Protection Error", - [TT_UNALIGNED] = "Unaligned Memory Access", - [TT_PRIV_ACT] = "Privileged Action", - [TT_EXTINT | 0x1] = "External Interrupt 1", - [TT_EXTINT | 0x2] = "External Interrupt 2", - [TT_EXTINT | 0x3] = "External Interrupt 3", - [TT_EXTINT | 0x4] = "External Interrupt 4", - [TT_EXTINT | 0x5] = "External Interrupt 5", - [TT_EXTINT | 0x6] = "External Interrupt 6", - [TT_EXTINT | 0x7] = "External Interrupt 7", - [TT_EXTINT | 0x8] = "External Interrupt 8", - [TT_EXTINT | 0x9] = "External Interrupt 9", - [TT_EXTINT | 0xa] = "External Interrupt 10", - [TT_EXTINT | 0xb] = "External Interrupt 11", - [TT_EXTINT | 0xc] = "External Interrupt 12", - [TT_EXTINT | 0xd] = "External Interrupt 13", - [TT_EXTINT | 0xe] = "External Interrupt 14", - [TT_EXTINT | 0xf] = "External Interrupt 15", -}; -#endif - -trap_state* cpu_tsptr(CPUState* env) -{ - return &env->ts[env->tl & MAXTL_MASK]; -} - -void do_interrupt(CPUState *env) -{ - int intno = env->exception_index; - trap_state* tsptr; - -#ifdef DEBUG_PCALL - if (qemu_loglevel_mask(CPU_LOG_INT)) { - static int count; - const char *name; - - if (intno < 0 || intno >= 0x180) - name = "Unknown"; - else if (intno >= 0x100) - name = "Trap Instruction"; - else if (intno >= 0xc0) - name = "Window Fill"; - else if (intno >= 0x80) - name = "Window Spill"; - else { - name = excp_names[intno]; - if (!name) - name = "Unknown"; - } - - qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64 - " SP=%016" PRIx64 "\n", - count, name, intno, - env->pc, - env->npc, env->regwptr[6]); - log_cpu_state(env, 0); -#if 0 - { - int i; - uint8_t *ptr; - - qemu_log(" code="); - ptr = (uint8_t *)env->pc; - for(i = 0; i < 16; i++) { - qemu_log(" %02x", ldub(ptr + i)); - } - qemu_log("\n"); - } -#endif - count++; - } -#endif -#if !defined(CONFIG_USER_ONLY) - if (env->tl >= env->maxtl) { - cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d)," - " Error state", env->exception_index, env->tl, env->maxtl); - return; - } -#endif - if (env->tl < env->maxtl - 1) { - env->tl++; - } else { - env->pstate |= PS_RED; - if (env->tl < env->maxtl) - env->tl++; - } - tsptr = cpu_tsptr(env); - - tsptr->tstate = (get_ccr() << 32) | - ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) | - get_cwp64(); - tsptr->tpc = env->pc; - tsptr->tnpc = env->npc; - tsptr->tt = intno; - - switch (intno) { - case TT_IVEC: - change_pstate(PS_PEF | PS_PRIV | PS_IG); - break; - case TT_TFAULT: - case TT_DFAULT: - case TT_TMISS ... TT_TMISS + 3: - case TT_DMISS ... TT_DMISS + 3: - case TT_DPROT ... TT_DPROT + 3: - change_pstate(PS_PEF | PS_PRIV | PS_MG); - break; - default: - change_pstate(PS_PEF | PS_PRIV | PS_AG); - break; - } - - if (intno == TT_CLRWIN) { - set_cwp(cwp_dec(env->cwp - 1)); - } else if ((intno & 0x1c0) == TT_SPILL) { - set_cwp(cwp_dec(env->cwp - env->cansave - 2)); - } else if ((intno & 0x1c0) == TT_FILL) { - set_cwp(cwp_inc(env->cwp + 1)); - } - env->tbr &= ~0x7fffULL; - env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); - env->pc = env->tbr; - env->npc = env->pc + 4; - env->exception_index = -1; -} -#else -#ifdef DEBUG_PCALL -static const char * const excp_names[0x80] = { - [TT_TFAULT] = "Instruction Access Fault", - [TT_ILL_INSN] = "Illegal Instruction", - [TT_PRIV_INSN] = "Privileged Instruction", - [TT_NFPU_INSN] = "FPU Disabled", - [TT_WIN_OVF] = "Window Overflow", - [TT_WIN_UNF] = "Window Underflow", - [TT_UNALIGNED] = "Unaligned Memory Access", - [TT_FP_EXCP] = "FPU Exception", - [TT_DFAULT] = "Data Access Fault", - [TT_TOVF] = "Tag Overflow", - [TT_EXTINT | 0x1] = "External Interrupt 1", - [TT_EXTINT | 0x2] = "External Interrupt 2", - [TT_EXTINT | 0x3] = "External Interrupt 3", - [TT_EXTINT | 0x4] = "External Interrupt 4", - [TT_EXTINT | 0x5] = "External Interrupt 5", - [TT_EXTINT | 0x6] = "External Interrupt 6", - [TT_EXTINT | 0x7] = "External Interrupt 7", - [TT_EXTINT | 0x8] = "External Interrupt 8", - [TT_EXTINT | 0x9] = "External Interrupt 9", - [TT_EXTINT | 0xa] = "External Interrupt 10", - [TT_EXTINT | 0xb] = "External Interrupt 11", - [TT_EXTINT | 0xc] = "External Interrupt 12", - [TT_EXTINT | 0xd] = "External Interrupt 13", - [TT_EXTINT | 0xe] = "External Interrupt 14", - [TT_EXTINT | 0xf] = "External Interrupt 15", - [TT_TOVF] = "Tag Overflow", - [TT_CODE_ACCESS] = "Instruction Access Error", - [TT_DATA_ACCESS] = "Data Access Error", - [TT_DIV_ZERO] = "Division By Zero", - [TT_NCP_INSN] = "Coprocessor Disabled", -}; -#endif - -void do_interrupt(CPUState *env) -{ - int cwp, intno = env->exception_index; - -#ifdef DEBUG_PCALL - if (qemu_loglevel_mask(CPU_LOG_INT)) { - static int count; - const char *name; - - if (intno < 0 || intno >= 0x100) - name = "Unknown"; - else if (intno >= 0x80) - name = "Trap Instruction"; - else { - name = excp_names[intno]; - if (!name) - name = "Unknown"; - } - - qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n", - count, name, intno, - env->pc, - env->npc, env->regwptr[6]); - log_cpu_state(env, 0); -#if 0 - { - int i; - uint8_t *ptr; - - qemu_log(" code="); - ptr = (uint8_t *)env->pc; - for(i = 0; i < 16; i++) { - qemu_log(" %02x", ldub(ptr + i)); - } - qemu_log("\n"); - } -#endif - count++; - } -#endif -#if !defined(CONFIG_USER_ONLY) - if (env->psret == 0) { - cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", - env->exception_index); - return; - } -#endif - env->psret = 0; - cwp = cwp_dec(env->cwp - 1); - set_cwp(cwp); - env->regwptr[9] = env->pc; - env->regwptr[10] = env->npc; - env->psrps = env->psrs; - env->psrs = 1; - env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); - env->pc = env->tbr; - env->npc = env->pc + 4; - env->exception_index = -1; #if !defined(CONFIG_USER_ONLY) - /* IRQ acknowledgment */ - if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) { - env->qemu_irq_ack(env->irq_manager, intno); - } -#endif -} -#endif - -#if !defined(CONFIG_USER_ONLY) - static void do_unaligned_access(target_ulong addr, int is_write, int is_user, void *retaddr); @@ -4375,7 +34,7 @@ static void cpu_restore_state2(void *retaddr) if (tb) { /* the PC is inside the translated code. It means that we have a virtual CPU fault */ - cpu_restore_state(tb, env, pc, (void *)(long)env->cond); + cpu_restore_state(tb, env, pc); } } } @@ -4388,148 +47,28 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, "\n", addr, env->pc); #endif cpu_restore_state2(retaddr); - raise_exception(TT_UNALIGNED); + helper_raise_exception(env, TT_UNALIGNED); } /* try to fill the TLB and return an exception if error. If retaddr is NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) +void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) { int ret; CPUState *saved_env; - /* XXX: hack to restore env in all cases, even if not called from - generated code */ saved_env = env; - env = cpu_single_env; + env = env1; - ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); + ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx); if (ret) { cpu_restore_state2(retaddr); - cpu_loop_exit(); + cpu_loop_exit(env); } env = saved_env; } #endif /* !CONFIG_USER_ONLY */ - -#ifndef TARGET_SPARC64 -#if !defined(CONFIG_USER_ONLY) -void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, - int is_asi, int size) -{ - CPUState *saved_env; - int fault_type; - - /* XXX: hack to restore env in all cases, even if not called from - generated code */ - saved_env = env; - env = cpu_single_env; -#ifdef DEBUG_UNASSIGNED - if (is_asi) - printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx - " asi 0x%02x from " TARGET_FMT_lx "\n", - is_exec ? "exec" : is_write ? "write" : "read", size, - size == 1 ? "" : "s", addr, is_asi, env->pc); - else - printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx - " from " TARGET_FMT_lx "\n", - is_exec ? "exec" : is_write ? "write" : "read", size, - size == 1 ? "" : "s", addr, env->pc); -#endif - /* Don't overwrite translation and access faults */ - fault_type = (env->mmuregs[3] & 0x1c) >> 2; - if ((fault_type > 4) || (fault_type == 0)) { - env->mmuregs[3] = 0; /* Fault status register */ - if (is_asi) - env->mmuregs[3] |= 1 << 16; - if (env->psrs) - env->mmuregs[3] |= 1 << 5; - if (is_exec) - env->mmuregs[3] |= 1 << 6; - if (is_write) - env->mmuregs[3] |= 1 << 7; - env->mmuregs[3] |= (5 << 2) | 2; - /* SuperSPARC will never place instruction fault addresses in the FAR */ - if (!is_exec) { - env->mmuregs[4] = addr; /* Fault address register */ - } - } - /* overflow (same type fault was not read before another fault) */ - if (fault_type == ((env->mmuregs[3] & 0x1c)) >> 2) { - env->mmuregs[3] |= 1; - } - - if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) { - if (is_exec) - raise_exception(TT_CODE_ACCESS); - else - raise_exception(TT_DATA_ACCESS); - } - - /* flush neverland mappings created during no-fault mode, - so the sequential MMU faults report proper fault types */ - if (env->mmuregs[0] & MMU_NF) { - tlb_flush(env, 1); - } - - env = saved_env; -} -#endif -#else -#if defined(CONFIG_USER_ONLY) -static void do_unassigned_access(target_ulong addr, int is_write, int is_exec, - int is_asi, int size) -#else -void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, - int is_asi, int size) -#endif -{ - CPUState *saved_env; - - /* XXX: hack to restore env in all cases, even if not called from - generated code */ - saved_env = env; - env = cpu_single_env; - -#ifdef DEBUG_UNASSIGNED - printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx - "\n", addr, env->pc); -#endif - - if (is_exec) - raise_exception(TT_CODE_ACCESS); - else - raise_exception(TT_DATA_ACCESS); - - env = saved_env; -} -#endif - - -#ifdef TARGET_SPARC64 -void helper_tick_set_count(void *opaque, uint64_t count) -{ -#if !defined(CONFIG_USER_ONLY) - cpu_tick_set_count(opaque, count); -#endif -} - -uint64_t helper_tick_get_count(void *opaque) -{ -#if !defined(CONFIG_USER_ONLY) - return cpu_tick_get_count(opaque); -#else - return 0; -#endif -} - -void helper_tick_set_limit(void *opaque, uint64_t limit) -{ -#if !defined(CONFIG_USER_ONLY) - cpu_tick_set_limit(opaque, limit); -#endif -} -#endif diff --git a/target-sparc/translate.c b/target-sparc/translate.c index e26462e..d261112 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -25,7 +25,6 @@ #include #include "cpu.h" -#include "exec-all.h" #include "disas.h" #include "helper.h" #include "tcg-op.h" @@ -64,7 +63,7 @@ static TCGv cpu_tmp0; static TCGv_i32 cpu_tmp32; static TCGv_i64 cpu_tmp64; /* Floating point registers */ -static TCGv_i32 cpu_fpr[TARGET_FPREGS]; +static TCGv_i64 cpu_fpr[TARGET_DPREGS]; static target_ulong gen_opc_npc[OPC_BUF_SIZE]; static target_ulong gen_opc_jump_pc[2]; @@ -83,6 +82,8 @@ typedef struct DisasContext { uint32_t cc_op; /* current CC operation */ struct TranslationBlock *tb; sparc_def_t *def; + TCGv_i32 t32[3]; + int n_t32; } DisasContext; // This function uses non-native bit order @@ -115,67 +116,116 @@ static int sign_extend(int x, int len) #define IS_IMM (insn & (1<<13)) +static inline void gen_update_fprs_dirty(int rd) +{ +#if defined(TARGET_SPARC64) + tcg_gen_ori_i32(cpu_fprs, cpu_fprs, (rd < 32) ? 1 : 2); +#endif +} + /* floating point registers moves */ -static void gen_op_load_fpr_DT0(unsigned int src) +static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src) +{ +#if TCG_TARGET_REG_BITS == 32 + if (src & 1) { + return TCGV_LOW(cpu_fpr[src / 2]); + } else { + return TCGV_HIGH(cpu_fpr[src / 2]); + } +#else + if (src & 1) { + return MAKE_TCGV_I32(GET_TCGV_I64(cpu_fpr[src / 2])); + } else { + TCGv_i32 ret = tcg_temp_local_new_i32(); + TCGv_i64 t = tcg_temp_new_i64(); + + tcg_gen_shri_i64(t, cpu_fpr[src / 2], 32); + tcg_gen_trunc_i64_i32(ret, t); + tcg_temp_free_i64(t); + + dc->t32[dc->n_t32++] = ret; + assert(dc->n_t32 <= ARRAY_SIZE(dc->t32)); + + return ret; + } +#endif +} + +static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v) +{ +#if TCG_TARGET_REG_BITS == 32 + if (dst & 1) { + tcg_gen_mov_i32(TCGV_LOW(cpu_fpr[dst / 2]), v); + } else { + tcg_gen_mov_i32(TCGV_HIGH(cpu_fpr[dst / 2]), v); + } +#else + TCGv_i64 t = MAKE_TCGV_I64(GET_TCGV_I32(v)); + tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t, + (dst & 1 ? 0 : 32), 32); +#endif + gen_update_fprs_dirty(dst); +} + +static TCGv_i32 gen_dest_fpr_F(void) +{ + return cpu_tmp32; +} + +static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src) { - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) + - offsetof(CPU_DoubleU, l.upper)); - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) + - offsetof(CPU_DoubleU, l.lower)); + src = DFPREG(src); + return cpu_fpr[src / 2]; } -static void gen_op_load_fpr_DT1(unsigned int src) +static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v) { - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt1) + - offsetof(CPU_DoubleU, l.upper)); - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt1) + - offsetof(CPU_DoubleU, l.lower)); + dst = DFPREG(dst); + tcg_gen_mov_i64(cpu_fpr[dst / 2], v); + gen_update_fprs_dirty(dst); } -static void gen_op_store_DT0_fpr(unsigned int dst) +static TCGv_i64 gen_dest_fpr_D(void) { - tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, dt0) + - offsetof(CPU_DoubleU, l.upper)); - tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, dt0) + - offsetof(CPU_DoubleU, l.lower)); + return cpu_tmp64; } static void gen_op_load_fpr_QT0(unsigned int src) { - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upmost)); - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upper)); - tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lower)); - tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lowest)); + tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.upper)); + tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.lower)); } static void gen_op_load_fpr_QT1(unsigned int src) { - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.upmost)); - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.upper)); - tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.lower)); - tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.lowest)); + tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt1) + + offsetof(CPU_QuadU, ll.upper)); + tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt1) + + offsetof(CPU_QuadU, ll.lower)); } static void gen_op_store_QT0_fpr(unsigned int dst) { - tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upmost)); - tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upper)); - tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lower)); - tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lowest)); + tcg_gen_ld_i64(cpu_fpr[dst / 2], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.upper)); + tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.lower)); } +#ifdef TARGET_SPARC64 +static void gen_move_Q(unsigned int rd, unsigned int rs) +{ + rd = QFPREG(rd); + rs = QFPREG(rs); + + tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]); + tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]); + gen_update_fprs_dirty(rd); +} +#endif + /* moves */ #ifdef CONFIG_USER_ONLY #define supervisor(dc) 0 @@ -241,7 +291,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, tcg_gen_goto_tb(tb_num); tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); - tcg_gen_exit_tb((long)tb + tb_num); + tcg_gen_exit_tb((tcg_target_long)tb + tb_num); } else { /* jump to another page: currently not optimized */ tcg_gen_movi_tl(cpu_pc, pc); @@ -295,7 +345,7 @@ static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2) tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31)); tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1); r_const = tcg_const_i32(TT_TOVF); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); gen_set_label(l1); tcg_temp_free(r_temp); @@ -311,7 +361,7 @@ static inline void gen_tag_tv(TCGv src1, TCGv src2) tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1); r_const = tcg_const_i32(TT_TOVF); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); gen_set_label(l1); } @@ -429,7 +479,7 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1, default: /* We need external help to produce the carry. */ carry_32 = tcg_temp_new_i32(); - gen_helper_compute_C_icc(carry_32); + gen_helper_compute_C_icc(carry_32, cpu_env); break; } @@ -493,7 +543,7 @@ static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2) tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31)); tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1); r_const = tcg_const_i32(TT_TOVF); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); gen_set_label(l1); tcg_temp_free(r_temp); @@ -568,7 +618,7 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1, default: /* We need external help to produce the carry. */ carry_32 = tcg_temp_new_i32(); - gen_helper_compute_C_icc(carry_32); + gen_helper_compute_C_icc(carry_32, cpu_env); break; } @@ -720,7 +770,7 @@ static inline void gen_trap_ifdivzero_tl(TCGv divisor) l1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1); r_const = tcg_const_i32(TT_DIV_ZERO); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); gen_set_label(l1); } @@ -728,19 +778,24 @@ static inline void gen_trap_ifdivzero_tl(TCGv divisor) static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2) { int l1, l2; + TCGv r_temp1, r_temp2; l1 = gen_new_label(); l2 = gen_new_label(); - tcg_gen_mov_tl(cpu_cc_src, src1); - tcg_gen_mov_tl(cpu_cc_src2, src2); - gen_trap_ifdivzero_tl(cpu_cc_src2); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1); + r_temp1 = tcg_temp_local_new(); + r_temp2 = tcg_temp_local_new(); + tcg_gen_mov_tl(r_temp1, src1); + tcg_gen_mov_tl(r_temp2, src2); + gen_trap_ifdivzero_tl(r_temp2); + tcg_gen_brcondi_tl(TCG_COND_NE, r_temp1, INT64_MIN, l1); + tcg_gen_brcondi_tl(TCG_COND_NE, r_temp2, -1, l1); tcg_gen_movi_i64(dst, INT64_MIN); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2); + tcg_gen_div_i64(dst, r_temp1, r_temp2); gen_set_label(l2); + tcg_temp_free(r_temp1); + tcg_temp_free(r_temp2); } #endif @@ -1087,7 +1142,7 @@ static inline void save_state(DisasContext *dc, TCGv cond) /* flush pending conditional evaluations before exposing cpu state */ if (dc->cc_op != CC_OP_FLAGS) { dc->cc_op = CC_OP_FLAGS; - gen_helper_compute_psr(); + gen_helper_compute_psr(cpu_env); } save_npc(dc, cond); } @@ -1129,7 +1184,7 @@ static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond, case CC_OP_FLAGS: break; default: - gen_helper_compute_psr(); + gen_helper_compute_psr(cpu_env); dc->cc_op = CC_OP_FLAGS; break; } @@ -1282,7 +1337,6 @@ static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src) } #endif -/* XXX: potentially incorrect if dynamic npc */ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, TCGv r_cond) { @@ -1317,13 +1371,17 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } } -/* XXX: potentially incorrect if dynamic npc */ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, TCGv r_cond) { @@ -1358,14 +1416,18 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } } #ifdef TARGET_SPARC64 -/* XXX: potentially incorrect if dynamic npc */ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, TCGv r_cond, TCGv r_reg) { @@ -1380,8 +1442,13 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, } else { dc->pc = dc->npc; dc->jump_pc[0] = target; - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; + if (unlikely(dc->npc == DYNAMIC_PC)) { + dc->jump_pc[1] = DYNAMIC_PC; + tcg_gen_addi_tl(cpu_pc, cpu_npc, 4); + } else { + dc->jump_pc[1] = dc->npc + 4; + dc->npc = JUMP_PC; + } } } @@ -1389,34 +1456,34 @@ static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmps(r_rs1, r_rs2); + gen_helper_fcmps(cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmps_fcc1(r_rs1, r_rs2); + gen_helper_fcmps_fcc1(cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmps_fcc2(r_rs1, r_rs2); + gen_helper_fcmps_fcc2(cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmps_fcc3(r_rs1, r_rs2); + gen_helper_fcmps_fcc3(cpu_env, r_rs1, r_rs2); break; } } -static inline void gen_op_fcmpd(int fccno) +static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmpd(); + gen_helper_fcmpd(cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmpd_fcc1(); + gen_helper_fcmpd_fcc1(cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmpd_fcc2(); + gen_helper_fcmpd_fcc2(cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmpd_fcc3(); + gen_helper_fcmpd_fcc3(cpu_env, r_rs1, r_rs2); break; } } @@ -1425,16 +1492,16 @@ static inline void gen_op_fcmpq(int fccno) { switch (fccno) { case 0: - gen_helper_fcmpq(); + gen_helper_fcmpq(cpu_env); break; case 1: - gen_helper_fcmpq_fcc1(); + gen_helper_fcmpq_fcc1(cpu_env); break; case 2: - gen_helper_fcmpq_fcc2(); + gen_helper_fcmpq_fcc2(cpu_env); break; case 3: - gen_helper_fcmpq_fcc3(); + gen_helper_fcmpq_fcc3(cpu_env); break; } } @@ -1443,34 +1510,34 @@ static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmpes(r_rs1, r_rs2); + gen_helper_fcmpes(cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmpes_fcc1(r_rs1, r_rs2); + gen_helper_fcmpes_fcc1(cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmpes_fcc2(r_rs1, r_rs2); + gen_helper_fcmpes_fcc2(cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmpes_fcc3(r_rs1, r_rs2); + gen_helper_fcmpes_fcc3(cpu_env, r_rs1, r_rs2); break; } } -static inline void gen_op_fcmped(int fccno) +static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmped(); + gen_helper_fcmped(cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmped_fcc1(); + gen_helper_fcmped_fcc1(cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmped_fcc2(); + gen_helper_fcmped_fcc2(cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmped_fcc3(); + gen_helper_fcmped_fcc3(cpu_env, r_rs1, r_rs2); break; } } @@ -1479,16 +1546,16 @@ static inline void gen_op_fcmpeq(int fccno) { switch (fccno) { case 0: - gen_helper_fcmpeq(); + gen_helper_fcmpeq(cpu_env); break; case 1: - gen_helper_fcmpeq_fcc1(); + gen_helper_fcmpeq_fcc1(cpu_env); break; case 2: - gen_helper_fcmpeq_fcc2(); + gen_helper_fcmpeq_fcc2(cpu_env); break; case 3: - gen_helper_fcmpeq_fcc3(); + gen_helper_fcmpeq_fcc3(cpu_env); break; } } @@ -1497,32 +1564,32 @@ static inline void gen_op_fcmpeq(int fccno) static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) { - gen_helper_fcmps(r_rs1, r_rs2); + gen_helper_fcmps(cpu_env, r_rs1, r_rs2); } -static inline void gen_op_fcmpd(int fccno) +static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { - gen_helper_fcmpd(); + gen_helper_fcmpd(cpu_env, r_rs1, r_rs2); } static inline void gen_op_fcmpq(int fccno) { - gen_helper_fcmpq(); + gen_helper_fcmpq(cpu_env); } static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) { - gen_helper_fcmpes(r_rs1, r_rs2); + gen_helper_fcmpes(cpu_env, r_rs1, r_rs2); } -static inline void gen_op_fcmped(int fccno) +static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { - gen_helper_fcmped(); + gen_helper_fcmped(cpu_env, r_rs1, r_rs2); } static inline void gen_op_fcmpeq(int fccno) { - gen_helper_fcmpeq(); + gen_helper_fcmpeq(cpu_env); } #endif @@ -1533,7 +1600,7 @@ static inline void gen_op_fpexception_im(int fsr_flags) tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK); tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags); r_const = tcg_const_i32(TT_FP_EXCP); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); } @@ -1545,7 +1612,7 @@ static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond) save_state(dc, r_cond); r_const = tcg_const_i32(TT_NFPU_INSN); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); dc->is_br = 1; return 1; @@ -1559,9 +1626,308 @@ static inline void gen_op_clear_ieee_excp_and_FTT(void) tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK); } -static inline void gen_clear_float_exceptions(void) +static inline void gen_fop_FF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32)) +{ + TCGv_i32 dst, src; + + src = gen_load_fpr_F(dc, rs); + dst = gen_dest_fpr_F(); + + gen(dst, cpu_env, src); + + gen_store_fpr_F(dc, rd, dst); +} + +static inline void gen_ne_fop_FF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i32, TCGv_i32)) +{ + TCGv_i32 dst, src; + + src = gen_load_fpr_F(dc, rs); + dst = gen_dest_fpr_F(); + + gen(dst, src); + + gen_store_fpr_F(dc, rd, dst); +} + +static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32)) +{ + TCGv_i32 dst, src1, src2; + + src1 = gen_load_fpr_F(dc, rs1); + src2 = gen_load_fpr_F(dc, rs2); + dst = gen_dest_fpr_F(); + + gen(dst, cpu_env, src1, src2); + + gen_store_fpr_F(dc, rd, dst); +} + +#ifdef TARGET_SPARC64 +static inline void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32)) +{ + TCGv_i32 dst, src1, src2; + + src1 = gen_load_fpr_F(dc, rs1); + src2 = gen_load_fpr_F(dc, rs2); + dst = gen_dest_fpr_F(); + + gen(dst, src1, src2); + + gen_store_fpr_F(dc, rd, dst); +} +#endif + +static inline void gen_fop_DD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64)) +{ + TCGv_i64 dst, src; + + src = gen_load_fpr_D(dc, rs); + dst = gen_dest_fpr_D(); + + gen(dst, cpu_env, src); + + gen_store_fpr_D(dc, rd, dst); +} + +#ifdef TARGET_SPARC64 +static inline void gen_ne_fop_DD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_i64)) +{ + TCGv_i64 dst, src; + + src = gen_load_fpr_D(dc, rs); + dst = gen_dest_fpr_D(); + + gen(dst, src); + + gen_store_fpr_D(dc, rd, dst); +} +#endif + +static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64)) +{ + TCGv_i64 dst, src1, src2; + + src1 = gen_load_fpr_D(dc, rs1); + src2 = gen_load_fpr_D(dc, rs2); + dst = gen_dest_fpr_D(); + + gen(dst, cpu_env, src1, src2); + + gen_store_fpr_D(dc, rd, dst); +} + +#ifdef TARGET_SPARC64 +static inline void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64)) +{ + TCGv_i64 dst, src1, src2; + + src1 = gen_load_fpr_D(dc, rs1); + src2 = gen_load_fpr_D(dc, rs2); + dst = gen_dest_fpr_D(); + + gen(dst, src1, src2); + + gen_store_fpr_D(dc, rd, dst); +} + +static inline void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) +{ + TCGv_i64 dst, src1, src2; + + src1 = gen_load_fpr_D(dc, rs1); + src2 = gen_load_fpr_D(dc, rs2); + dst = gen_dest_fpr_D(); + + gen(dst, cpu_gsr, src1, src2); + + gen_store_fpr_D(dc, rd, dst); +} + +static inline void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) +{ + TCGv_i64 dst, src0, src1, src2; + + src1 = gen_load_fpr_D(dc, rs1); + src2 = gen_load_fpr_D(dc, rs2); + src0 = gen_load_fpr_D(dc, rd); + dst = gen_dest_fpr_D(); + + gen(dst, src0, src1, src2); + + gen_store_fpr_D(dc, rd, dst); +} +#endif + +static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr)) +{ + gen_op_load_fpr_QT1(QFPREG(rs)); + + gen(cpu_env); + + gen_op_store_QT0_fpr(QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); +} + +#ifdef TARGET_SPARC64 +static inline void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr)) +{ + gen_op_load_fpr_QT1(QFPREG(rs)); + + gen(cpu_env); + + gen_op_store_QT0_fpr(QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); +} +#endif + +static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_ptr)) +{ + gen_op_load_fpr_QT0(QFPREG(rs1)); + gen_op_load_fpr_QT1(QFPREG(rs2)); + + gen(cpu_env); + + gen_op_store_QT0_fpr(QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); +} + +static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32, TCGv_i32)) +{ + TCGv_i64 dst; + TCGv_i32 src1, src2; + + src1 = gen_load_fpr_F(dc, rs1); + src2 = gen_load_fpr_F(dc, rs2); + dst = gen_dest_fpr_D(); + + gen(dst, cpu_env, src1, src2); + + gen_store_fpr_D(dc, rd, dst); +} + +static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2, + void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64)) +{ + TCGv_i64 src1, src2; + + src1 = gen_load_fpr_D(dc, rs1); + src2 = gen_load_fpr_D(dc, rs2); + + gen(cpu_env, src1, src2); + + gen_op_store_QT0_fpr(QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); +} + +#ifdef TARGET_SPARC64 +static inline void gen_fop_DF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32)) +{ + TCGv_i64 dst; + TCGv_i32 src; + + src = gen_load_fpr_F(dc, rs); + dst = gen_dest_fpr_D(); + + gen(dst, cpu_env, src); + + gen_store_fpr_D(dc, rd, dst); +} +#endif + +static inline void gen_ne_fop_DF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32)) +{ + TCGv_i64 dst; + TCGv_i32 src; + + src = gen_load_fpr_F(dc, rs); + dst = gen_dest_fpr_D(); + + gen(dst, cpu_env, src); + + gen_store_fpr_D(dc, rd, dst); +} + +static inline void gen_fop_FD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i64)) +{ + TCGv_i32 dst; + TCGv_i64 src; + + src = gen_load_fpr_D(dc, rs); + dst = gen_dest_fpr_F(); + + gen(dst, cpu_env, src); + + gen_store_fpr_F(dc, rd, dst); +} + +static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i32, TCGv_ptr)) +{ + TCGv_i32 dst; + + gen_op_load_fpr_QT1(QFPREG(rs)); + dst = gen_dest_fpr_F(); + + gen(dst, cpu_env); + + gen_store_fpr_F(dc, rd, dst); +} + +static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_i64, TCGv_ptr)) +{ + TCGv_i64 dst; + + gen_op_load_fpr_QT1(QFPREG(rs)); + dst = gen_dest_fpr_D(); + + gen(dst, cpu_env); + + gen_store_fpr_D(dc, rd, dst); +} + +static inline void gen_ne_fop_QF(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr, TCGv_i32)) +{ + TCGv_i32 src; + + src = gen_load_fpr_F(dc, rs); + + gen(cpu_env, src); + + gen_op_store_QT0_fpr(QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); +} + +static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs, + void (*gen)(TCGv_ptr, TCGv_i64)) { - gen_helper_clear_float_exceptions(); + TCGv_i64 src; + + src = gen_load_fpr_D(dc, rs); + + gen(cpu_env, src); + + gen_op_store_QT0_fpr(QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); } /* asi moves */ @@ -1855,6 +2221,148 @@ static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env) tcg_temp_free_i32(r_tl); } + +static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2, + int width, bool cc, bool left) +{ + TCGv lo1, lo2, t1, t2; + uint64_t amask, tabl, tabr; + int shift, imask, omask; + + if (cc) { + tcg_gen_mov_tl(cpu_cc_src, s1); + tcg_gen_mov_tl(cpu_cc_src2, s2); + tcg_gen_sub_tl(cpu_cc_dst, s1, s2); + tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB); + dc->cc_op = CC_OP_SUB; + } + + /* Theory of operation: there are two tables, left and right (not to + be confused with the left and right versions of the opcode). These + are indexed by the low 3 bits of the inputs. To make things "easy", + these tables are loaded into two constants, TABL and TABR below. + The operation index = (input & imask) << shift calculates the index + into the constant, while val = (table >> index) & omask calculates + the value we're looking for. */ + switch (width) { + case 8: + imask = 0x7; + shift = 3; + omask = 0xff; + if (left) { + tabl = 0x80c0e0f0f8fcfeffULL; + tabr = 0xff7f3f1f0f070301ULL; + } else { + tabl = 0x0103070f1f3f7fffULL; + tabr = 0xfffefcf8f0e0c080ULL; + } + break; + case 16: + imask = 0x6; + shift = 1; + omask = 0xf; + if (left) { + tabl = 0x8cef; + tabr = 0xf731; + } else { + tabl = 0x137f; + tabr = 0xfec8; + } + break; + case 32: + imask = 0x4; + shift = 0; + omask = 0x3; + if (left) { + tabl = (2 << 2) | 3; + tabr = (3 << 2) | 1; + } else { + tabl = (1 << 2) | 3; + tabr = (3 << 2) | 2; + } + break; + default: + abort(); + } + + lo1 = tcg_temp_new(); + lo2 = tcg_temp_new(); + tcg_gen_andi_tl(lo1, s1, imask); + tcg_gen_andi_tl(lo2, s2, imask); + tcg_gen_shli_tl(lo1, lo1, shift); + tcg_gen_shli_tl(lo2, lo2, shift); + + t1 = tcg_const_tl(tabl); + t2 = tcg_const_tl(tabr); + tcg_gen_shr_tl(lo1, t1, lo1); + tcg_gen_shr_tl(lo2, t2, lo2); + tcg_gen_andi_tl(dst, lo1, omask); + tcg_gen_andi_tl(lo2, lo2, omask); + + amask = -8; + if (AM_CHECK(dc)) { + amask &= 0xffffffffULL; + } + tcg_gen_andi_tl(s1, s1, amask); + tcg_gen_andi_tl(s2, s2, amask); + + /* We want to compute + dst = (s1 == s2 ? lo1 : lo1 & lo2). + We've already done dst = lo1, so this reduces to + dst &= (s1 == s2 ? -1 : lo2) + Which we perform by + lo2 |= -(s1 == s2) + dst &= lo2 + */ + tcg_gen_setcond_tl(TCG_COND_EQ, t1, s1, s2); + tcg_gen_neg_tl(t1, t1); + tcg_gen_or_tl(lo2, lo2, t1); + tcg_gen_and_tl(dst, dst, lo2); + + tcg_temp_free(lo1); + tcg_temp_free(lo2); + tcg_temp_free(t1); + tcg_temp_free(t2); +} + +static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left) +{ + TCGv tmp = tcg_temp_new(); + + tcg_gen_add_tl(tmp, s1, s2); + tcg_gen_andi_tl(dst, tmp, -8); + if (left) { + tcg_gen_neg_tl(tmp, tmp); + } + tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3); + + tcg_temp_free(tmp); +} + +static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2) +{ + TCGv t1, t2, shift; + + t1 = tcg_temp_new(); + t2 = tcg_temp_new(); + shift = tcg_temp_new(); + + tcg_gen_andi_tl(shift, gsr, 7); + tcg_gen_shli_tl(shift, shift, 3); + tcg_gen_shl_tl(t1, s1, shift); + + /* A shift of 64 does not produce 0 in TCG. Divide this into a + shift of (up to 63) followed by a constant shift of 1. */ + tcg_gen_xori_tl(shift, shift, 63); + tcg_gen_shr_tl(t2, s2, shift); + tcg_gen_shri_tl(t2, t2, 1); + + tcg_gen_or_tl(dst, t1, t2); + + tcg_temp_free(t1); + tcg_temp_free(t2); + tcg_temp_free(shift); +} #endif #define CHECK_IU_FEATURE(dc, FEATURE) \ @@ -1869,6 +2377,8 @@ static void disas_sparc_insn(DisasContext * dc) { unsigned int insn, opc, rs1, rs2, rd; TCGv cpu_src1, cpu_src2, cpu_tmp1, cpu_tmp2; + TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32; + TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64; target_long simm; if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) @@ -1893,7 +2403,7 @@ static void disas_sparc_insn(DisasContext * dc) int cc; target = GET_FIELD_SP(insn, 0, 18); - target = sign_extend(target, 18); + target = sign_extend(target, 19); target <<= 2; cc = GET_FIELD_SP(insn, 20, 21); if (cc == 0) @@ -2008,15 +2518,8 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK); tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + gen_helper_raise_exception(cpu_env, cpu_tmp32); - if (rs2 == 0 && - dc->def->features & CPU_FEATURE_TA0_SHUTDOWN) { - - gen_helper_shutdown(); - - } else { - gen_helper_raise_exception(cpu_tmp32); - } } else if (cond != 0) { TCGv r_cond = tcg_temp_new(); int l1; @@ -2045,7 +2548,7 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK); tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); - gen_helper_raise_exception(cpu_tmp32); + gen_helper_raise_exception(cpu_env, cpu_tmp32); gen_set_label(l1); tcg_temp_free(r_cond); @@ -2083,8 +2586,8 @@ static void disas_sparc_insn(DisasContext * dc) break; #ifdef TARGET_SPARC64 case 0x2: /* V9 rdccr */ - gen_helper_compute_psr(); - gen_helper_rdccr(cpu_dst); + gen_helper_compute_psr(cpu_env); + gen_helper_rdccr(cpu_dst, cpu_env); gen_movl_TN_reg(rd, cpu_dst); break; case 0x3: /* V9 rdasi */ @@ -2159,9 +2662,9 @@ static void disas_sparc_insn(DisasContext * dc) #ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn; - gen_helper_compute_psr(); + gen_helper_compute_psr(cpu_env); dc->cc_op = CC_OP_FLAGS; - gen_helper_rdpsr(cpu_dst); + gen_helper_rdpsr(cpu_dst, cpu_env); #else CHECK_IU_FEATURE(dc, HYPV); if (!hypervisor(dc)) @@ -2274,7 +2777,7 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 9: // cwp - gen_helper_rdcwp(cpu_tmp0); + gen_helper_rdcwp(cpu_tmp0, cpu_env); break; case 10: // cansave tcg_gen_ld_i32(cpu_tmp32, cpu_env, @@ -2328,7 +2831,7 @@ static void disas_sparc_insn(DisasContext * dc) } else if (xop == 0x2b) { /* rdtbr / V9 flushw */ #ifdef TARGET_SPARC64 save_state(dc, cpu_cond); - gen_helper_flushw(); + gen_helper_flushw(cpu_env); #else if (!supervisor(dc)) goto priv_insn; @@ -2346,302 +2849,162 @@ static void disas_sparc_insn(DisasContext * dc) save_state(dc, cpu_cond); switch (xop) { case 0x1: /* fmovs */ - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); + cpu_src1_32 = gen_load_fpr_F(dc, rs2); + gen_store_fpr_F(dc, rd, cpu_src1_32); break; case 0x5: /* fnegs */ - gen_helper_fnegs(cpu_fpr[rd], cpu_fpr[rs2]); + gen_ne_fop_FF(dc, rd, rs2, gen_helper_fnegs); break; case 0x9: /* fabss */ - gen_helper_fabss(cpu_fpr[rd], cpu_fpr[rs2]); + gen_ne_fop_FF(dc, rd, rs2, gen_helper_fabss); break; case 0x29: /* fsqrts */ CHECK_FPU_FEATURE(dc, FSQRT); - gen_clear_float_exceptions(); - gen_helper_fsqrts(cpu_tmp32, cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts); break; case 0x2a: /* fsqrtd */ CHECK_FPU_FEATURE(dc, FSQRT); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fsqrtd(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DD(dc, rd, rs2, gen_helper_fsqrtd); break; case 0x2b: /* fsqrtq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fsqrtq(); - gen_helper_check_ieee_exceptions(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_fop_QQ(dc, rd, rs2, gen_helper_fsqrtq); break; case 0x41: /* fadds */ - gen_clear_float_exceptions(); - gen_helper_fadds(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fadds); break; case 0x42: /* faddd */ - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_faddd(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_faddd); break; case 0x43: /* faddq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT0(QFPREG(rs1)); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_faddq(); - gen_helper_check_ieee_exceptions(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_faddq); break; case 0x45: /* fsubs */ - gen_clear_float_exceptions(); - gen_helper_fsubs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fsubs); break; case 0x46: /* fsubd */ - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fsubd(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fsubd); break; case 0x47: /* fsubq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT0(QFPREG(rs1)); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fsubq(); - gen_helper_check_ieee_exceptions(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq); break; case 0x49: /* fmuls */ CHECK_FPU_FEATURE(dc, FMUL); - gen_clear_float_exceptions(); - gen_helper_fmuls(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fmuls); break; case 0x4a: /* fmuld */ CHECK_FPU_FEATURE(dc, FMUL); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fmuld(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld); break; case 0x4b: /* fmulq */ CHECK_FPU_FEATURE(dc, FLOAT128); CHECK_FPU_FEATURE(dc, FMUL); - gen_op_load_fpr_QT0(QFPREG(rs1)); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fmulq(); - gen_helper_check_ieee_exceptions(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq); break; case 0x4d: /* fdivs */ - gen_clear_float_exceptions(); - gen_helper_fdivs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fdivs); break; case 0x4e: /* fdivd */ - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fdivd(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fdivd); break; case 0x4f: /* fdivq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT0(QFPREG(rs1)); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fdivq(); - gen_helper_check_ieee_exceptions(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fdivq); break; case 0x69: /* fsmuld */ CHECK_FPU_FEATURE(dc, FSMULD); - gen_clear_float_exceptions(); - gen_helper_fsmuld(cpu_fpr[rs1], cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DFF(dc, rd, rs1, rs2, gen_helper_fsmuld); break; case 0x6e: /* fdmulq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fdmulq(); - gen_helper_check_ieee_exceptions(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_fop_QDD(dc, rd, rs1, rs2, gen_helper_fdmulq); break; case 0xc4: /* fitos */ - gen_clear_float_exceptions(); - gen_helper_fitos(cpu_tmp32, cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FF(dc, rd, rs2, gen_helper_fitos); break; case 0xc6: /* fdtos */ - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fdtos(cpu_tmp32); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FD(dc, rd, rs2, gen_helper_fdtos); break; case 0xc7: /* fqtos */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fqtos(cpu_tmp32); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FQ(dc, rd, rs2, gen_helper_fqtos); break; case 0xc8: /* fitod */ - gen_helper_fitod(cpu_fpr[rs2]); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DF(dc, rd, rs2, gen_helper_fitod); break; case 0xc9: /* fstod */ - gen_helper_fstod(cpu_fpr[rs2]); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DF(dc, rd, rs2, gen_helper_fstod); break; case 0xcb: /* fqtod */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fqtod(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DQ(dc, rd, rs2, gen_helper_fqtod); break; case 0xcc: /* fitoq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_helper_fitoq(cpu_fpr[rs2]); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_ne_fop_QF(dc, rd, rs2, gen_helper_fitoq); break; case 0xcd: /* fstoq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_helper_fstoq(cpu_fpr[rs2]); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_ne_fop_QF(dc, rd, rs2, gen_helper_fstoq); break; case 0xce: /* fdtoq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fdtoq(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq); break; case 0xd1: /* fstoi */ - gen_clear_float_exceptions(); - gen_helper_fstoi(cpu_tmp32, cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FF(dc, rd, rs2, gen_helper_fstoi); break; case 0xd2: /* fdtoi */ - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fdtoi(cpu_tmp32); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FD(dc, rd, rs2, gen_helper_fdtoi); break; case 0xd3: /* fqtoi */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fqtoi(cpu_tmp32); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FQ(dc, rd, rs2, gen_helper_fqtoi); break; #ifdef TARGET_SPARC64 case 0x2: /* V9 fmovd */ - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]); - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + cpu_src1_64 = gen_load_fpr_D(dc, rs2); + gen_store_fpr_D(dc, rd, cpu_src1_64); break; case 0x3: /* V9 fmovq */ CHECK_FPU_FEATURE(dc, FLOAT128); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], - cpu_fpr[QFPREG(rs2) + 1]); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], - cpu_fpr[QFPREG(rs2) + 2]); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], - cpu_fpr[QFPREG(rs2) + 3]); + gen_move_Q(rd, rs2); break; case 0x6: /* V9 fnegd */ - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fnegd(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DD(dc, rd, rs2, gen_helper_fnegd); break; case 0x7: /* V9 fnegq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_helper_fnegq(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fnegq); break; case 0xa: /* V9 fabsd */ - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fabsd(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DD(dc, rd, rs2, gen_helper_fabsd); break; case 0xb: /* V9 fabsq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_helper_fabsq(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq); break; case 0x81: /* V9 fstox */ - gen_clear_float_exceptions(); - gen_helper_fstox(cpu_fpr[rs2]); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DF(dc, rd, rs2, gen_helper_fstox); break; case 0x82: /* V9 fdtox */ - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fdtox(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DD(dc, rd, rs2, gen_helper_fdtox); break; case 0x83: /* V9 fqtox */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_QT1(QFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fqtox(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox); break; case 0x84: /* V9 fxtos */ - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fxtos(cpu_tmp32); - gen_helper_check_ieee_exceptions(); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); + gen_fop_FD(dc, rd, rs2, gen_helper_fxtos); break; case 0x88: /* V9 fxtod */ - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fxtod(); - gen_helper_check_ieee_exceptions(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_fop_DD(dc, rd, rs2, gen_helper_fxtod); break; case 0x8c: /* V9 fxtoq */ CHECK_FPU_FEATURE(dc, FLOAT128); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_clear_float_exceptions(); - gen_helper_fxtoq(); - gen_helper_check_ieee_exceptions(); - gen_op_store_QT0_fpr(QFPREG(rd)); + gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq); break; #endif default: @@ -2667,7 +3030,8 @@ static void disas_sparc_insn(DisasContext * dc) cpu_src1 = get_src1(insn, cpu_src1); tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, 0, l1); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); + cpu_src1_32 = gen_load_fpr_F(dc, rs2); + gen_store_fpr_F(dc, rd, cpu_src1_32); gen_set_label(l1); break; } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr @@ -2678,8 +3042,8 @@ static void disas_sparc_insn(DisasContext * dc) cpu_src1 = get_src1(insn, cpu_src1); tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, 0, l1); - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]); - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]); + cpu_src1_64 = gen_load_fpr_D(dc, rs2); + gen_store_fpr_D(dc, rd, cpu_src1_64); gen_set_label(l1); break; } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr @@ -2691,10 +3055,7 @@ static void disas_sparc_insn(DisasContext * dc) cpu_src1 = get_src1(insn, cpu_src1); tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, 0, l1); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]); - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]); + gen_move_Q(rd, rs2); gen_set_label(l1); break; } @@ -2712,7 +3073,8 @@ static void disas_sparc_insn(DisasContext * dc) gen_fcond(r_cond, fcc, cond); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ 0, l1); \ - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \ + cpu_src1_32 = gen_load_fpr_F(dc, rs2); \ + gen_store_fpr_F(dc, rd, cpu_src1_32); \ gen_set_label(l1); \ tcg_temp_free(r_cond); \ } @@ -2727,10 +3089,8 @@ static void disas_sparc_insn(DisasContext * dc) gen_fcond(r_cond, fcc, cond); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ 0, l1); \ - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \ - cpu_fpr[DFPREG(rs2)]); \ - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \ - cpu_fpr[DFPREG(rs2) + 1]); \ + cpu_src1_64 = gen_load_fpr_D(dc, rs2); \ + gen_store_fpr_D(dc, rd, cpu_src1_64); \ gen_set_label(l1); \ tcg_temp_free(r_cond); \ } @@ -2745,14 +3105,7 @@ static void disas_sparc_insn(DisasContext * dc) gen_fcond(r_cond, fcc, cond); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ 0, l1); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \ - cpu_fpr[QFPREG(rs2)]); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \ - cpu_fpr[QFPREG(rs2) + 1]); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \ - cpu_fpr[QFPREG(rs2) + 2]); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \ - cpu_fpr[QFPREG(rs2) + 3]); \ + gen_move_Q(rd, rs2); \ gen_set_label(l1); \ tcg_temp_free(r_cond); \ } @@ -2810,7 +3163,8 @@ static void disas_sparc_insn(DisasContext * dc) gen_cond(r_cond, icc, cond, dc); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ 0, l1); \ - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \ + cpu_src1_32 = gen_load_fpr_F(dc, rs2); \ + gen_store_fpr_F(dc, rd, cpu_src1_32); \ gen_set_label(l1); \ tcg_temp_free(r_cond); \ } @@ -2825,10 +3179,9 @@ static void disas_sparc_insn(DisasContext * dc) gen_cond(r_cond, icc, cond, dc); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ 0, l1); \ - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \ - cpu_fpr[DFPREG(rs2)]); \ - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \ - cpu_fpr[DFPREG(rs2) + 1]); \ + cpu_src1_64 = gen_load_fpr_D(dc, rs2); \ + gen_store_fpr_D(dc, rd, cpu_src1_64); \ + gen_update_fprs_dirty(DFPREG(rd)); \ gen_set_label(l1); \ tcg_temp_free(r_cond); \ } @@ -2843,14 +3196,7 @@ static void disas_sparc_insn(DisasContext * dc) gen_cond(r_cond, icc, cond, dc); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ 0, l1); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \ - cpu_fpr[QFPREG(rs2)]); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \ - cpu_fpr[QFPREG(rs2) + 1]); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \ - cpu_fpr[QFPREG(rs2) + 2]); \ - tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \ - cpu_fpr[QFPREG(rs2) + 3]); \ + gen_move_Q(rd, rs2); \ gen_set_label(l1); \ tcg_temp_free(r_cond); \ } @@ -2860,6 +3206,7 @@ static void disas_sparc_insn(DisasContext * dc) break; case 0x102: /* V9 fmovdcc %icc */ FMOVDCC(0); + break; case 0x103: /* V9 fmovqcc %icc */ CHECK_FPU_FEATURE(dc, FLOAT128); FMOVQCC(0); @@ -2879,12 +3226,14 @@ static void disas_sparc_insn(DisasContext * dc) #undef FMOVQCC #endif case 0x51: /* fcmps, V9 %fcc */ - gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]); + cpu_src1_32 = gen_load_fpr_F(dc, rs1); + cpu_src2_32 = gen_load_fpr_F(dc, rs2); + gen_op_fcmps(rd & 3, cpu_src1_32, cpu_src2_32); break; case 0x52: /* fcmpd, V9 %fcc */ - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_op_fcmpd(rd & 3); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_op_fcmpd(rd & 3, cpu_src1_64, cpu_src2_64); break; case 0x53: /* fcmpq, V9 %fcc */ CHECK_FPU_FEATURE(dc, FLOAT128); @@ -2893,12 +3242,14 @@ static void disas_sparc_insn(DisasContext * dc) gen_op_fcmpq(rd & 3); break; case 0x55: /* fcmpes, V9 %fcc */ - gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]); + cpu_src1_32 = gen_load_fpr_F(dc, rs1); + cpu_src2_32 = gen_load_fpr_F(dc, rs2); + gen_op_fcmpes(rd & 3, cpu_src1_32, cpu_src2_32); break; case 0x56: /* fcmped, V9 %fcc */ - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_op_fcmped(rd & 3); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_op_fcmped(rd & 3, cpu_src1_64, cpu_src2_64); break; case 0x57: /* fcmpeq, V9 %fcc */ CHECK_FPU_FEATURE(dc, FLOAT128); @@ -3174,28 +3525,39 @@ static void disas_sparc_insn(DisasContext * dc) break; #ifdef TARGET_SPARC64 case 0xd: /* V9 udivx */ - tcg_gen_mov_tl(cpu_cc_src, cpu_src1); - tcg_gen_mov_tl(cpu_cc_src2, cpu_src2); - gen_trap_ifdivzero_tl(cpu_cc_src2); - tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2); + { + TCGv r_temp1, r_temp2; + r_temp1 = tcg_temp_local_new(); + r_temp2 = tcg_temp_local_new(); + tcg_gen_mov_tl(r_temp1, cpu_src1); + tcg_gen_mov_tl(r_temp2, cpu_src2); + gen_trap_ifdivzero_tl(r_temp2); + tcg_gen_divu_i64(cpu_dst, r_temp1, r_temp2); + tcg_temp_free(r_temp1); + tcg_temp_free(r_temp2); + } break; #endif case 0xe: /* udiv */ CHECK_IU_FEATURE(dc, DIV); if (xop & 0x10) { - gen_helper_udiv_cc(cpu_dst, cpu_src1, cpu_src2); + gen_helper_udiv_cc(cpu_dst, cpu_env, cpu_src1, + cpu_src2); dc->cc_op = CC_OP_DIV; } else { - gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2); + gen_helper_udiv(cpu_dst, cpu_env, cpu_src1, + cpu_src2); } break; case 0xf: /* sdiv */ CHECK_IU_FEATURE(dc, DIV); if (xop & 0x10) { - gen_helper_sdiv_cc(cpu_dst, cpu_src1, cpu_src2); + gen_helper_sdiv_cc(cpu_dst, cpu_env, cpu_src1, + cpu_src2); dc->cc_op = CC_OP_DIV; } else { - gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2); + gen_helper_sdiv(cpu_dst, cpu_env, cpu_src1, + cpu_src2); } break; default: @@ -3233,7 +3595,7 @@ static void disas_sparc_insn(DisasContext * dc) dc->cc_op = CC_OP_TSUBTV; break; case 0x24: /* mulscc */ - gen_helper_compute_psr(); + gen_helper_compute_psr(cpu_env); gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2); gen_movl_TN_reg(rd, cpu_dst); tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD); @@ -3291,7 +3653,7 @@ static void disas_sparc_insn(DisasContext * dc) #else case 0x2: /* V9 wrccr */ tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2); - gen_helper_wrccr(cpu_dst); + gen_helper_wrccr(cpu_env, cpu_dst); tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); dc->cc_op = CC_OP_FLAGS; break; @@ -3324,19 +3686,19 @@ static void disas_sparc_insn(DisasContext * dc) if (!supervisor(dc)) goto illegal_insn; tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2); - gen_helper_set_softint(cpu_tmp64); + gen_helper_set_softint(cpu_env, cpu_tmp64); break; case 0x15: /* Softint clear */ if (!supervisor(dc)) goto illegal_insn; tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2); - gen_helper_clear_softint(cpu_tmp64); + gen_helper_clear_softint(cpu_env, cpu_tmp64); break; case 0x16: /* Softint write */ if (!supervisor(dc)) goto illegal_insn; tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2); - gen_helper_write_softint(cpu_tmp64); + gen_helper_write_softint(cpu_env, cpu_tmp64); break; case 0x17: /* Tick compare */ #if !defined(CONFIG_USER_ONLY) @@ -3411,10 +3773,10 @@ static void disas_sparc_insn(DisasContext * dc) #ifdef TARGET_SPARC64 switch (rd) { case 0: - gen_helper_saved(); + gen_helper_saved(cpu_env); break; case 1: - gen_helper_restored(); + gen_helper_restored(cpu_env); break; case 2: /* UA2005 allclean */ case 3: /* UA2005 otherw */ @@ -3426,7 +3788,7 @@ static void disas_sparc_insn(DisasContext * dc) } #else tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2); - gen_helper_wrpsr(cpu_dst); + gen_helper_wrpsr(cpu_env, cpu_dst); tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); dc->cc_op = CC_OP_FLAGS; save_state(dc, cpu_cond); @@ -3505,22 +3867,34 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_mov_tl(cpu_tbr, cpu_tmp0); break; case 6: // pstate - save_state(dc, cpu_cond); - gen_helper_wrpstate(cpu_tmp0); - dc->npc = DYNAMIC_PC; + { + TCGv r_tmp = tcg_temp_local_new(); + + tcg_gen_mov_tl(r_tmp, cpu_tmp0); + save_state(dc, cpu_cond); + gen_helper_wrpstate(cpu_env, r_tmp); + tcg_temp_free(r_tmp); + dc->npc = DYNAMIC_PC; + } break; case 7: // tl - save_state(dc, cpu_cond); - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); - tcg_gen_st_i32(cpu_tmp32, cpu_env, - offsetof(CPUSPARCState, tl)); - dc->npc = DYNAMIC_PC; + { + TCGv r_tmp = tcg_temp_local_new(); + + tcg_gen_mov_tl(r_tmp, cpu_tmp0); + save_state(dc, cpu_cond); + tcg_gen_trunc_tl_i32(cpu_tmp32, r_tmp); + tcg_temp_free(r_tmp); + tcg_gen_st_i32(cpu_tmp32, cpu_env, + offsetof(CPUSPARCState, tl)); + dc->npc = DYNAMIC_PC; + } break; case 8: // pil - gen_helper_wrpil(cpu_tmp0); + gen_helper_wrpil(cpu_env, cpu_tmp0); break; case 9: // cwp - gen_helper_wrcwp(cpu_tmp0); + gen_helper_wrcwp(cpu_env, cpu_tmp0); break; case 10: // cansave tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); @@ -3715,19 +4089,89 @@ static void disas_sparc_insn(DisasContext * dc) switch (opf) { case 0x000: /* VIS I edge8cc */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 0); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x001: /* VIS II edge8n */ + CHECK_FPU_FEATURE(dc, VIS2); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 0); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x002: /* VIS I edge8lcc */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 1); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x003: /* VIS II edge8ln */ + CHECK_FPU_FEATURE(dc, VIS2); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 1); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x004: /* VIS I edge16cc */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 0); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x005: /* VIS II edge16n */ + CHECK_FPU_FEATURE(dc, VIS2); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 0); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x006: /* VIS I edge16lcc */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 1); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x007: /* VIS II edge16ln */ + CHECK_FPU_FEATURE(dc, VIS2); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 1); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x008: /* VIS I edge32cc */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 0); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x009: /* VIS II edge32n */ + CHECK_FPU_FEATURE(dc, VIS2); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 0); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x00a: /* VIS I edge32lcc */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 1); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x00b: /* VIS II edge32ln */ - // XXX - goto illegal_insn; + CHECK_FPU_FEATURE(dc, VIS2); + gen_movl_reg_TN(rs1, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 1); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x010: /* VIS I array8 */ CHECK_FPU_FEATURE(dc, VIS1); cpu_src1 = get_src1(insn, cpu_src1); @@ -3755,372 +4199,317 @@ static void disas_sparc_insn(DisasContext * dc) CHECK_FPU_FEATURE(dc, VIS1); cpu_src1 = get_src1(insn, cpu_src1); gen_movl_reg_TN(rs2, cpu_src2); - gen_helper_alignaddr(cpu_dst, cpu_src1, cpu_src2); + gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 0); gen_movl_TN_reg(rd, cpu_dst); break; - case 0x019: /* VIS II bmask */ case 0x01a: /* VIS I alignaddrl */ - // XXX - goto illegal_insn; + CHECK_FPU_FEATURE(dc, VIS1); + cpu_src1 = get_src1(insn, cpu_src1); + gen_movl_reg_TN(rs2, cpu_src2); + gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 1); + gen_movl_TN_reg(rd, cpu_dst); + break; + case 0x019: /* VIS II bmask */ + CHECK_FPU_FEATURE(dc, VIS2); + cpu_src1 = get_src1(insn, cpu_src1); + cpu_src2 = get_src1(insn, cpu_src2); + tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2); + tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, cpu_dst, 32, 32); + gen_movl_TN_reg(rd, cpu_dst); + break; case 0x020: /* VIS I fcmple16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmple16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmple16(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x022: /* VIS I fcmpne16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmpne16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmpne16(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x024: /* VIS I fcmple32 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmple32(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmple32(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x026: /* VIS I fcmpne32 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmpne32(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmpne32(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x028: /* VIS I fcmpgt16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmpgt16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmpgt16(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x02a: /* VIS I fcmpeq16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmpeq16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmpeq16(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x02c: /* VIS I fcmpgt32 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmpgt32(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmpgt32(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x02e: /* VIS I fcmpeq32 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fcmpeq32(); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + cpu_src2_64 = gen_load_fpr_D(dc, rs2); + gen_helper_fcmpeq32(cpu_dst, cpu_src1_64, cpu_src2_64); + gen_movl_TN_reg(rd, cpu_dst); break; case 0x031: /* VIS I fmul8x16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fmul8x16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16); break; case 0x033: /* VIS I fmul8x16au */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fmul8x16au(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16au); break; case 0x035: /* VIS I fmul8x16al */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fmul8x16al(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16al); break; case 0x036: /* VIS I fmul8sux16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fmul8sux16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8sux16); break; case 0x037: /* VIS I fmul8ulx16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fmul8ulx16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8ulx16); break; case 0x038: /* VIS I fmuld8sux16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fmuld8sux16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8sux16); break; case 0x039: /* VIS I fmuld8ulx16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fmuld8ulx16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8ulx16); break; case 0x03a: /* VIS I fpack32 */ + CHECK_FPU_FEATURE(dc, VIS1); + gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpack32); + break; case 0x03b: /* VIS I fpack16 */ + CHECK_FPU_FEATURE(dc, VIS1); + cpu_src1_64 = gen_load_fpr_D(dc, rs2); + cpu_dst_32 = gen_dest_fpr_F(); + gen_helper_fpack16(cpu_dst_32, cpu_gsr, cpu_src1_64); + gen_store_fpr_F(dc, rd, cpu_dst_32); + break; case 0x03d: /* VIS I fpackfix */ + CHECK_FPU_FEATURE(dc, VIS1); + cpu_src1_64 = gen_load_fpr_D(dc, rs2); + cpu_dst_32 = gen_dest_fpr_F(); + gen_helper_fpackfix(cpu_dst_32, cpu_gsr, cpu_src1_64); + gen_store_fpr_F(dc, rd, cpu_dst_32); + break; case 0x03e: /* VIS I pdist */ - // XXX - goto illegal_insn; + CHECK_FPU_FEATURE(dc, VIS1); + gen_ne_fop_DDDD(dc, rd, rs1, rs2, gen_helper_pdist); + break; case 0x048: /* VIS I faligndata */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_faligndata(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_faligndata); break; case 0x04b: /* VIS I fpmerge */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fpmerge(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpmerge); break; case 0x04c: /* VIS II bshuffle */ - // XXX - goto illegal_insn; + CHECK_FPU_FEATURE(dc, VIS2); + gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_bshuffle); + break; case 0x04d: /* VIS I fexpand */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fexpand(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fexpand); break; case 0x050: /* VIS I fpadd16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fpadd16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd16); break; case 0x051: /* VIS I fpadd16s */ CHECK_FPU_FEATURE(dc, VIS1); - gen_helper_fpadd16s(cpu_fpr[rd], - cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpadd16s); break; case 0x052: /* VIS I fpadd32 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fpadd32(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd32); break; case 0x053: /* VIS I fpadd32s */ CHECK_FPU_FEATURE(dc, VIS1); - gen_helper_fpadd32s(cpu_fpr[rd], - cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_add_i32); break; case 0x054: /* VIS I fpsub16 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fpsub16(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub16); break; case 0x055: /* VIS I fpsub16s */ CHECK_FPU_FEATURE(dc, VIS1); - gen_helper_fpsub16s(cpu_fpr[rd], - cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpsub16s); break; case 0x056: /* VIS I fpsub32 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs1)); - gen_op_load_fpr_DT1(DFPREG(rs2)); - gen_helper_fpsub32(); - gen_op_store_DT0_fpr(DFPREG(rd)); + gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub32); break; case 0x057: /* VIS I fpsub32s */ CHECK_FPU_FEATURE(dc, VIS1); - gen_helper_fpsub32s(cpu_fpr[rd], - cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_sub_i32); break; case 0x060: /* VIS I fzero */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0); - tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0); + cpu_dst_64 = gen_dest_fpr_D(); + tcg_gen_movi_i64(cpu_dst_64, 0); + gen_store_fpr_D(dc, rd, cpu_dst_64); break; case 0x061: /* VIS I fzeros */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_movi_i32(cpu_fpr[rd], 0); + cpu_dst_32 = gen_dest_fpr_F(); + tcg_gen_movi_i32(cpu_dst_32, 0); + gen_store_fpr_F(dc, rd, cpu_dst_32); break; case 0x062: /* VIS I fnor */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)], - cpu_fpr[DFPREG(rs2)]); - tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nor_i64); break; case 0x063: /* VIS I fnors */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nor_i32); break; case 0x064: /* VIS I fandnot2 */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)], - cpu_fpr[DFPREG(rs2)]); - tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs1) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_andc_i64); break; case 0x065: /* VIS I fandnot2s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_andc_i32); break; case 0x066: /* VIS I fnot2 */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]); - tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DD(dc, rd, rs2, tcg_gen_not_i64); break; case 0x067: /* VIS I fnot2s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs2]); + gen_ne_fop_FF(dc, rd, rs2, tcg_gen_not_i32); break; case 0x068: /* VIS I fandnot1 */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)], - cpu_fpr[DFPREG(rs1)]); - tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs2) + 1], - cpu_fpr[DFPREG(rs1) + 1]); + gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64); break; case 0x069: /* VIS I fandnot1s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]); + gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_andc_i32); break; case 0x06a: /* VIS I fnot1 */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]); - tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs1) + 1]); + gen_ne_fop_DD(dc, rd, rs1, tcg_gen_not_i64); break; case 0x06b: /* VIS I fnot1s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs1]); + gen_ne_fop_FF(dc, rd, rs1, tcg_gen_not_i32); break; case 0x06c: /* VIS I fxor */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)], - cpu_fpr[DFPREG(rs2)]); - tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs1) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64); break; case 0x06d: /* VIS I fxors */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_xor_i32); break; case 0x06e: /* VIS I fnand */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)], - cpu_fpr[DFPREG(rs2)]); - tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nand_i64); break; case 0x06f: /* VIS I fnands */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nand_i32); break; case 0x070: /* VIS I fand */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)], - cpu_fpr[DFPREG(rs2)]); - tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs1) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_and_i64); break; case 0x071: /* VIS I fands */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_and_i32); break; case 0x072: /* VIS I fxnor */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1); - tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32, - cpu_fpr[DFPREG(rs1)]); - tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1); - tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32, - cpu_fpr[DFPREG(rs1) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_eqv_i64); break; case 0x073: /* VIS I fxnors */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1); - tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_eqv_i32); break; case 0x074: /* VIS I fsrc1 */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]); - tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs1) + 1]); + cpu_src1_64 = gen_load_fpr_D(dc, rs1); + gen_store_fpr_D(dc, rd, cpu_src1_64); break; case 0x075: /* VIS I fsrc1s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]); + cpu_src1_32 = gen_load_fpr_F(dc, rs1); + gen_store_fpr_F(dc, rd, cpu_src1_32); break; case 0x076: /* VIS I fornot2 */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)], - cpu_fpr[DFPREG(rs2)]); - tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs1) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_orc_i64); break; case 0x077: /* VIS I fornot2s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_orc_i32); break; case 0x078: /* VIS I fsrc2 */ CHECK_FPU_FEATURE(dc, VIS1); - gen_op_load_fpr_DT0(DFPREG(rs2)); - gen_op_store_DT0_fpr(DFPREG(rd)); + cpu_src1_64 = gen_load_fpr_D(dc, rs2); + gen_store_fpr_D(dc, rd, cpu_src1_64); break; case 0x079: /* VIS I fsrc2s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); + cpu_src1_32 = gen_load_fpr_F(dc, rs2); + gen_store_fpr_F(dc, rd, cpu_src1_32); break; case 0x07a: /* VIS I fornot1 */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)], - cpu_fpr[DFPREG(rs1)]); - tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs2) + 1], - cpu_fpr[DFPREG(rs1) + 1]); + gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64); break; case 0x07b: /* VIS I fornot1s */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]); + gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_orc_i32); break; case 0x07c: /* VIS I for */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)], - cpu_fpr[DFPREG(rs2)]); - tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1], - cpu_fpr[DFPREG(rs1) + 1], - cpu_fpr[DFPREG(rs2) + 1]); + gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_or_i64); break; case 0x07d: /* VIS I fors */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]); + gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_or_i32); break; case 0x07e: /* VIS I fone */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1); - tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1); + cpu_dst_64 = gen_dest_fpr_D(); + tcg_gen_movi_i64(cpu_dst_64, -1); + gen_store_fpr_D(dc, rd, cpu_dst_64); break; case 0x07f: /* VIS I fones */ CHECK_FPU_FEATURE(dc, VIS1); - tcg_gen_movi_i32(cpu_fpr[rd], -1); + cpu_dst_32 = gen_dest_fpr_F(); + tcg_gen_movi_i32(cpu_dst_32, -1); + gen_store_fpr_F(dc, rd, cpu_dst_32); break; case 0x080: /* VIS I shutdown */ case 0x081: /* VIS II siam */ @@ -4155,7 +4544,7 @@ static void disas_sparc_insn(DisasContext * dc) } else tcg_gen_mov_tl(cpu_dst, cpu_src1); } - gen_helper_restore(); + gen_helper_restore(cpu_env); gen_mov_pc_npc(dc, cpu_cond); r_const = tcg_const_i32(3); gen_helper_check_align(cpu_dst, r_const); @@ -4207,23 +4596,23 @@ static void disas_sparc_insn(DisasContext * dc) tcg_temp_free_i32(r_const); tcg_gen_mov_tl(cpu_npc, cpu_dst); dc->npc = DYNAMIC_PC; - gen_helper_rett(); + gen_helper_rett(cpu_env); } goto jmp_insn; #endif case 0x3b: /* flush */ if (!((dc)->def->features & CPU_FEATURE_FLUSH)) goto unimp_flush; - gen_helper_flush(cpu_dst); + /* nop */ break; case 0x3c: /* save */ save_state(dc, cpu_cond); - gen_helper_save(); + gen_helper_save(cpu_env); gen_movl_TN_reg(rd, cpu_dst); break; case 0x3d: /* restore */ save_state(dc, cpu_cond); - gen_helper_restore(); + gen_helper_restore(cpu_env); gen_movl_TN_reg(rd, cpu_dst); break; #if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64) @@ -4235,14 +4624,14 @@ static void disas_sparc_insn(DisasContext * dc) goto priv_insn; dc->npc = DYNAMIC_PC; dc->pc = DYNAMIC_PC; - gen_helper_done(); + gen_helper_done(cpu_env); goto jmp_insn; case 1: if (!supervisor(dc)) goto priv_insn; dc->npc = DYNAMIC_PC; dc->pc = DYNAMIC_PC; - gen_helper_retry(); + gen_helper_retry(cpu_env); goto jmp_insn; default: goto illegal_insn; @@ -4265,7 +4654,7 @@ static void disas_sparc_insn(DisasContext * dc) cpu state */ if (dc->cc_op != CC_OP_FLAGS) { dc->cc_op = CC_OP_FLAGS; - gen_helper_compute_psr(); + gen_helper_compute_psr(cpu_env); } cpu_src1 = get_src1(insn, cpu_src1); if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa @@ -4461,19 +4850,31 @@ static void disas_sparc_insn(DisasContext * dc) case 0x2d: /* V9 prefetch, no effect */ goto skip_move; case 0x30: /* V9 ldfa */ + if (gen_trap_ifnofpu(dc, cpu_cond)) { + goto jmp_insn; + } save_state(dc, cpu_cond); gen_ldf_asi(cpu_addr, insn, 4, rd); + gen_update_fprs_dirty(rd); goto skip_move; case 0x33: /* V9 lddfa */ + if (gen_trap_ifnofpu(dc, cpu_cond)) { + goto jmp_insn; + } save_state(dc, cpu_cond); gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd)); + gen_update_fprs_dirty(DFPREG(rd)); goto skip_move; case 0x3d: /* V9 prefetcha, no effect */ goto skip_move; case 0x32: /* V9 ldqfa */ CHECK_FPU_FEATURE(dc, FLOAT128); + if (gen_trap_ifnofpu(dc, cpu_cond)) { + goto jmp_insn; + } save_state(dc, cpu_cond); gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); goto skip_move; #endif default: @@ -4491,23 +4892,25 @@ static void disas_sparc_insn(DisasContext * dc) case 0x20: /* ldf, load fpreg */ gen_address_mask(dc, cpu_addr); tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx); - tcg_gen_trunc_tl_i32(cpu_fpr[rd], cpu_tmp0); + cpu_dst_32 = gen_dest_fpr_F(); + tcg_gen_trunc_tl_i32(cpu_dst_32, cpu_tmp0); + gen_store_fpr_F(dc, rd, cpu_dst_32); break; case 0x21: /* ldfsr, V9 ldxfsr */ #ifdef TARGET_SPARC64 gen_address_mask(dc, cpu_addr); if (rd == 1) { tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx); - gen_helper_ldxfsr(cpu_tmp64); + gen_helper_ldxfsr(cpu_env, cpu_tmp64); } else { tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); - gen_helper_ldfsr(cpu_tmp32); + gen_helper_ldfsr(cpu_env, cpu_tmp32); } #else { tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); - gen_helper_ldfsr(cpu_tmp32); + gen_helper_ldfsr(cpu_env, cpu_tmp32); } #endif break; @@ -4521,18 +4924,14 @@ static void disas_sparc_insn(DisasContext * dc) gen_helper_ldqf(cpu_addr, r_const); tcg_temp_free_i32(r_const); gen_op_store_QT0_fpr(QFPREG(rd)); + gen_update_fprs_dirty(QFPREG(rd)); } break; case 0x23: /* lddf, load double fpreg */ - { - TCGv_i32 r_const; - - r_const = tcg_const_i32(dc->mem_idx); - gen_address_mask(dc, cpu_addr); - gen_helper_lddf(cpu_addr, r_const); - tcg_temp_free_i32(r_const); - gen_op_store_DT0_fpr(DFPREG(rd)); - } + gen_address_mask(dc, cpu_addr); + cpu_dst_64 = gen_dest_fpr_D(); + tcg_gen_qemu_ld64(cpu_dst_64, cpu_addr, dc->mem_idx); + gen_store_fpr_D(dc, rd, cpu_dst_64); break; default: goto illegal_insn; @@ -4639,7 +5038,8 @@ static void disas_sparc_insn(DisasContext * dc) switch (xop) { case 0x24: /* stf, store fpreg */ gen_address_mask(dc, cpu_addr); - tcg_gen_ext_i32_tl(cpu_tmp0, cpu_fpr[rd]); + cpu_src1_32 = gen_load_fpr_F(dc, rd); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_src1_32); tcg_gen_qemu_st32(cpu_tmp0, cpu_addr, dc->mem_idx); break; case 0x25: /* stfsr, V9 stxfsr */ @@ -4682,15 +5082,9 @@ static void disas_sparc_insn(DisasContext * dc) #endif #endif case 0x27: /* stdf, store double fpreg */ - { - TCGv_i32 r_const; - - gen_op_load_fpr_DT0(DFPREG(rd)); - r_const = tcg_const_i32(dc->mem_idx); - gen_address_mask(dc, cpu_addr); - gen_helper_stdf(cpu_addr, r_const); - tcg_temp_free_i32(r_const); - } + gen_address_mask(dc, cpu_addr); + cpu_src1_64 = gen_load_fpr_D(dc, rd); + tcg_gen_qemu_st64(cpu_src1_64, cpu_addr, dc->mem_idx); break; default: goto illegal_insn; @@ -4700,6 +5094,9 @@ static void disas_sparc_insn(DisasContext * dc) switch (xop) { #ifdef TARGET_SPARC64 case 0x34: /* V9 stfa */ + if (gen_trap_ifnofpu(dc, cpu_cond)) { + goto jmp_insn; + } gen_stf_asi(cpu_addr, insn, 4, rd); break; case 0x36: /* V9 stqfa */ @@ -4707,15 +5104,19 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_i32 r_const; CHECK_FPU_FEATURE(dc, FLOAT128); + if (gen_trap_ifnofpu(dc, cpu_cond)) { + goto jmp_insn; + } r_const = tcg_const_i32(7); gen_helper_check_align(cpu_addr, r_const); tcg_temp_free_i32(r_const); - gen_op_load_fpr_QT0(QFPREG(rd)); gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd)); } break; case 0x37: /* V9 stdfa */ - gen_op_load_fpr_DT0(DFPREG(rd)); + if (gen_trap_ifnofpu(dc, cpu_cond)) { + goto jmp_insn; + } gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd)); break; case 0x3c: /* V9 casa */ @@ -4761,7 +5162,7 @@ static void disas_sparc_insn(DisasContext * dc) save_state(dc, cpu_cond); r_const = tcg_const_i32(TT_ILL_INSN); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); dc->is_br = 1; } @@ -4772,7 +5173,7 @@ static void disas_sparc_insn(DisasContext * dc) save_state(dc, cpu_cond); r_const = tcg_const_i32(TT_UNIMP_FLUSH); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); dc->is_br = 1; } @@ -4784,7 +5185,7 @@ static void disas_sparc_insn(DisasContext * dc) save_state(dc, cpu_cond); r_const = tcg_const_i32(TT_PRIV_INSN); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free_i32(r_const); dc->is_br = 1; } @@ -4809,7 +5210,7 @@ static void disas_sparc_insn(DisasContext * dc) save_state(dc, cpu_cond); r_const = tcg_const_i32(TT_NCP_INSN); - gen_helper_raise_exception(r_const); + gen_helper_raise_exception(cpu_env, r_const); tcg_temp_free(r_const); dc->is_br = 1; } @@ -4818,6 +5219,13 @@ static void disas_sparc_insn(DisasContext * dc) egress: tcg_temp_free(cpu_tmp1); tcg_temp_free(cpu_tmp2); + if (dc->n_t32 != 0) { + int i; + for (i = dc->n_t32 - 1; i >= 0; --i) { + tcg_temp_free_i32(dc->t32[i]); + } + dc->n_t32 = 0; + } } static inline void gen_intermediate_code_internal(TranslationBlock * tb, @@ -4840,13 +5248,8 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, dc->cc_op = CC_OP_DYNAMIC; dc->mem_idx = cpu_mmu_index(env); dc->def = env->def; - if ((dc->def->features & CPU_FEATURE_FLOAT)) - dc->fpu_enabled = cpu_fpu_enabled(env); - else - dc->fpu_enabled = 0; -#ifdef TARGET_SPARC64 - dc->address_mask_32bit = env->pstate & PS_AM; -#endif + dc->fpu_enabled = tb_fpu_enabled(tb->flags); + dc->address_mask_32bit = tb_am_enabled(tb->flags); dc->singlestep = (env->singlestep_enabled || singlestep); gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; @@ -4871,7 +5274,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, if (bp->pc == dc->pc) { if (dc->pc != pc_start) save_state(dc, cpu_cond); - gen_helper_debug(); + gen_helper_debug(cpu_env); tcg_gen_exit_tb(0); dc->is_br = 1; goto exit_gen_loop; @@ -4922,6 +5325,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, tcg_temp_free_i64(cpu_tmp64); tcg_temp_free_i32(cpu_tmp32); tcg_temp_free(cpu_tmp0); + if (tb->cflags & CF_LAST_IO) gen_io_end(); if (!dc->is_br) { @@ -4986,15 +5390,11 @@ void gen_intermediate_code_init(CPUSPARCState *env) "g6", "g7", }; - static const char * const fregnames[64] = { - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", - "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", - "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", - "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", + static const char * const fregnames[32] = { + "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14", + "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30", + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", }; /* init various static tables */ @@ -5064,14 +5464,16 @@ void gen_intermediate_code_init(CPUSPARCState *env) cpu_tbr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, tbr), "tbr"); #endif - for (i = 1; i < 8; i++) + for (i = 1; i < 8; i++) { cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gregs[i]), gregnames[i]); - for (i = 0; i < TARGET_FPREGS; i++) - cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0, + } + for (i = 0; i < TARGET_DPREGS; i++) { + cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, fpr[i]), fregnames[i]); + } /* register helpers */ @@ -5080,8 +5482,7 @@ void gen_intermediate_code_init(CPUSPARCState *env) } } -void gen_pc_load(CPUState *env, TranslationBlock *tb, - unsigned long searched_pc, int pc_pos, void *puc) +void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) { target_ulong npc; env->pc = gen_opc_pc[pc_pos]; @@ -5101,6 +5502,6 @@ void gen_pc_load(CPUState *env, TranslationBlock *tb, /* flush pending conditional evaluations before exposing cpu state */ if (CC_OP != CC_OP_FLAGS) { - helper_compute_psr(); + helper_compute_psr(env); } } diff --git a/tcg/README b/tcg/README index 6600122..cfdfd96 100644 --- a/tcg/README +++ b/tcg/README @@ -504,7 +504,15 @@ register. - Don't hesitate to use helpers for complicated or seldom used target instructions. There is little performance advantage in using TCG to implement target instructions taking more than about twenty TCG - instructions. + instructions. Note that this rule of thumb is more applicable to + helpers doing complex logic or arithmetic, where the C compiler has + scope to do a good job of optimisation; it is less relevant where + the instruction is mostly doing loads and stores, and in those cases + inline TCG may still be faster for longer sequences. + +- The hard limit on the number of TCG instructions you can generate + per target instruction is set by MAX_OP_PER_INSTR in exec-all.h -- + you cannot exceed this without risking a buffer overrun. - Use the 'discard' instruction if you know that TCG won't be able to prove that a given global is "dead" at a given program point. The diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index 918e2f7..e05a64f 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -375,6 +375,12 @@ static inline void tcg_out_blx(TCGContext *s, int cond, int rn) tcg_out32(s, (cond << 28) | 0x012fff30 | rn); } +static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset) +{ + tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) | + (((offset - 8) >> 2) & 0x00ffffff)); +} + static inline void tcg_out_dat_reg(TCGContext *s, int cond, int opc, int rd, int rn, int rm, int shift) { @@ -840,6 +846,11 @@ static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr) { int32_t val; + if (addr & 1) { + /* goto to a Thumb destination isn't supported */ + tcg_abort(); + } + val = addr - (tcg_target_long) s->code_ptr; if (val - 8 < 0x01fffffd && val - 8 > -0x01fffffd) tcg_out_b(s, cond, val); @@ -860,14 +871,22 @@ static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr) } } -static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr) +static inline void tcg_out_call(TCGContext *s, uint32_t addr) { int32_t val; val = addr - (tcg_target_long) s->code_ptr; - if (val < 0x01fffffd && val > -0x01fffffd) - tcg_out_bl(s, cond, val); - else { + if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) { + if (addr & 1) { + /* Use BLX if the target is in Thumb mode */ + if (!use_armv5_instructions) { + tcg_abort(); + } + tcg_out_blx_imm(s, val); + } else { + tcg_out_bl(s, COND_AL, val); + } + } else { #if 1 tcg_abort(); #else @@ -1063,8 +1082,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0)); tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index); # endif - tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_ld_helpers[s_bits] - - (tcg_target_long) s->code_ptr); + tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]); switch (opc) { case 0 | 4: @@ -1330,8 +1348,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) } # endif - tcg_out_bl(s, COND_AL, (tcg_target_long) qemu_st_helpers[s_bits] - - (tcg_target_long) s->code_ptr); + tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]); if (opc == 3) tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10); @@ -1443,7 +1460,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_call: if (const_args[0]) - tcg_out_call(s, COND_AL, args[0]); + tcg_out_call(s, args[0]); else tcg_out_callr(s, COND_AL, args[0]); break; @@ -1787,57 +1804,48 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC); tcg_add_target_add_op_defs(arm_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } -static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg, - int arg1, tcg_target_long arg2) +static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { tcg_out_ld32u(s, COND_AL, arg, arg1, arg2); } -static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, - int arg1, tcg_target_long arg2) +static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { tcg_out_st32(s, COND_AL, arg, arg1, arg2); } -static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) -{ - if (val > 0) - if (val < 0x100) - tcg_out_dat_imm(s, COND_AL, ARITH_ADD, reg, reg, val); - else - tcg_abort(); - else if (val < 0) { - if (val > -0x100) - tcg_out_dat_imm(s, COND_AL, ARITH_SUB, reg, reg, -val); - else - tcg_abort(); - } -} - -static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) +static inline void tcg_out_mov(TCGContext *s, TCGType type, + TCGReg ret, TCGReg arg) { tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0)); } static inline void tcg_out_movi(TCGContext *s, TCGType type, - int ret, tcg_target_long arg) + TCGReg ret, tcg_target_long arg) { tcg_out_movi32(s, COND_AL, ret, arg); } static void tcg_target_qemu_prologue(TCGContext *s) { - /* There is no need to save r7, it is used to store the address - of the env structure and is not modified by GCC. */ + /* Calling convention requires us to save r4-r11 and lr; + * save also r12 to maintain stack 8-alignment. + */ + + /* stmdb sp!, { r4 - r12, lr } */ + tcg_out32(s, (COND_AL << 28) | 0x092d5ff0); - /* stmdb sp!, { r4 - r6, r8 - r11, lr } */ - tcg_out32(s, (COND_AL << 28) | 0x092d4f70); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); - tcg_out_bx(s, COND_AL, TCG_REG_R0); + tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]); tb_ret_addr = s->code_ptr; - /* ldmia sp!, { r4 - r6, r8 - r11, pc } */ - tcg_out32(s, (COND_AL << 28) | 0x08bd8f70); + /* ldmia sp!, { r4 - r12, pc } */ + tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0); } diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index d8d7d94..48586c3 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -24,11 +24,10 @@ */ #define TCG_TARGET_ARM 1 -#define TCG_TARGET_REG_BITS 32 #undef TCG_TARGET_WORDS_BIGENDIAN #undef TCG_TARGET_STACK_GROWSUP -enum { +typedef enum { TCG_REG_R0 = 0, TCG_REG_R1, TCG_REG_R2, @@ -45,7 +44,7 @@ enum { TCG_REG_R13, TCG_REG_R14, TCG_REG_PC, -}; +} TCGReg; #define TCG_TARGET_NB_REGS 16 @@ -58,20 +57,22 @@ enum { #define TCG_TARGET_CALL_STACK_OFFSET 0 /* optional instructions */ -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -#undef TCG_TARGET_HAS_ext8u_i32 /* and r0, r1, #0xff */ -#define TCG_TARGET_HAS_ext16u_i32 -#define TCG_TARGET_HAS_bswap16_i32 -#define TCG_TARGET_HAS_bswap32_i32 -#define TCG_TARGET_HAS_not_i32 -#define TCG_TARGET_HAS_neg_i32 -#define TCG_TARGET_HAS_rot_i32 -#define TCG_TARGET_HAS_andc_i32 -// #define TCG_TARGET_HAS_orc_i32 -// #define TCG_TARGET_HAS_eqv_i32 -// #define TCG_TARGET_HAS_nand_i32 -// #define TCG_TARGET_HAS_nor_i32 +#define TCG_TARGET_HAS_div_i32 0 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_ext8u_i32 0 /* and r0, r1, #0xff */ +#define TCG_TARGET_HAS_ext16u_i32 1 +#define TCG_TARGET_HAS_bswap16_i32 1 +#define TCG_TARGET_HAS_bswap32_i32 1 +#define TCG_TARGET_HAS_not_i32 1 +#define TCG_TARGET_HAS_neg_i32 1 +#define TCG_TARGET_HAS_rot_i32 1 +#define TCG_TARGET_HAS_andc_i32 1 +#define TCG_TARGET_HAS_orc_i32 0 +#define TCG_TARGET_HAS_eqv_i32 0 +#define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_nor_i32 0 +#define TCG_TARGET_HAS_deposit_i32 0 #define TCG_TARGET_HAS_GUEST_BASE diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index 7f4653e..59d4d12 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -338,7 +338,7 @@ static int tcg_target_const_match(tcg_target_long val, /* supplied by libgcc */ extern void *__canonicalize_funcptr_for_compare(void *); -static void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) +static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { /* PA1.1 defines COPY as OR r,0,t; PA2.0 defines COPY as LDO 0(r),t but hppa-dis.c is unaware of this definition */ @@ -349,7 +349,7 @@ static void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) } static void tcg_out_movi(TCGContext *s, TCGType type, - int ret, tcg_target_long arg) + TCGReg ret, tcg_target_long arg) { if (check_fit_tl(arg, 14)) { tcg_out32(s, INSN_LDO | INSN_R1(ret) @@ -393,15 +393,15 @@ static void tcg_out_ldst(TCGContext *s, int ret, int addr, } /* This function is required by tcg.c. */ -static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret, - int arg1, tcg_target_long arg2) +static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, + TCGReg arg1, tcg_target_long arg2) { tcg_out_ldst(s, ret, arg1, arg2, INSN_LDW); } /* This function is required by tcg.c. */ -static inline void tcg_out_st(TCGContext *s, TCGType type, int ret, - int arg1, tcg_target_long arg2) +static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg ret, + TCGReg arg1, tcg_target_long arg2) { tcg_out_ldst(s, ret, arg1, arg2, INSN_STW); } @@ -467,6 +467,14 @@ static inline void tcg_out_dep(TCGContext *s, int ret, int arg, | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len)); } +static inline void tcg_out_depi(TCGContext *s, int ret, int arg, + unsigned ofs, unsigned len) +{ + assert(ofs < 32 && len <= 32 - ofs); + tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(arg) + | INSN_SHDEP_CP(31 - ofs) | INSN_DEP_LEN(len)); +} + static inline void tcg_out_shd(TCGContext *s, int ret, int hi, int lo, unsigned count) { @@ -499,8 +507,7 @@ static void tcg_out_ori(TCGContext *s, int ret, int arg, tcg_target_ulong m) assert(bs1 == 32 || (1ul << bs1) > m); tcg_out_mov(s, TCG_TYPE_I32, ret, arg); - tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(-1) - | INSN_SHDEP_CP(31 - bs0) | INSN_DEP_LEN(bs1 - bs0)); + tcg_out_depi(s, ret, -1, bs0, bs1 - bs0); } static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m) @@ -529,8 +536,7 @@ static void tcg_out_andi(TCGContext *s, int ret, int arg, tcg_target_ulong m) tcg_out_extr(s, ret, arg, 0, ls0, 0); } else { tcg_out_mov(s, TCG_TYPE_I32, ret, arg); - tcg_out32(s, INSN_DEPI | INSN_R2(ret) | INSN_IM5(0) - | INSN_SHDEP_CP(31 - ls0) | INSN_DEP_LEN(ls1 - ls0)); + tcg_out_depi(s, ret, 0, ls0, ls1 - ls0); } } @@ -646,14 +652,14 @@ static void tcg_out_xmpyu(TCGContext *s, int retl, int reth, int arg1, int arg2) { /* Store both words into the stack for copy to the FPU. */ - tcg_out_ldst(s, arg1, TCG_REG_SP, STACK_TEMP_OFS, INSN_STW); - tcg_out_ldst(s, arg2, TCG_REG_SP, STACK_TEMP_OFS + 4, INSN_STW); + tcg_out_ldst(s, arg1, TCG_REG_CALL_STACK, STACK_TEMP_OFS, INSN_STW); + tcg_out_ldst(s, arg2, TCG_REG_CALL_STACK, STACK_TEMP_OFS + 4, INSN_STW); /* Load both words into the FPU at the same time. We get away with this because we can address the left and right half of the FPU registers individually once loaded. */ /* fldds stack_temp(sp),fr22 */ - tcg_out32(s, INSN_FLDDS | INSN_R2(TCG_REG_SP) + tcg_out32(s, INSN_FLDDS | INSN_R2(TCG_REG_CALL_STACK) | INSN_IM5(STACK_TEMP_OFS) | INSN_T(22)); /* xmpyu fr22r,fr22,fr22 */ @@ -661,15 +667,16 @@ static void tcg_out_xmpyu(TCGContext *s, int retl, int reth, /* Store the 64-bit result back into the stack. */ /* fstds stack_temp(sp),fr22 */ - tcg_out32(s, INSN_FSTDS | INSN_R2(TCG_REG_SP) + tcg_out32(s, INSN_FSTDS | INSN_R2(TCG_REG_CALL_STACK) | INSN_IM5(STACK_TEMP_OFS) | INSN_T(22)); /* Load the pieces of the result that the caller requested. */ if (reth) { - tcg_out_ldst(s, reth, TCG_REG_SP, STACK_TEMP_OFS, INSN_LDW); + tcg_out_ldst(s, reth, TCG_REG_CALL_STACK, STACK_TEMP_OFS, INSN_LDW); } if (retl) { - tcg_out_ldst(s, retl, TCG_REG_SP, STACK_TEMP_OFS + 4, INSN_LDW); + tcg_out_ldst(s, retl, TCG_REG_CALL_STACK, STACK_TEMP_OFS + 4, + INSN_LDW); } } @@ -1198,7 +1205,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) } tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R23, datahi_reg); tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R24, datalo_reg); - tcg_out_st(s, TCG_TYPE_I32, argreg, TCG_REG_SP, + tcg_out_st(s, TCG_TYPE_I32, argreg, TCG_REG_CALL_STACK, TCG_TARGET_CALL_STACK_OFFSET - 4); break; default: @@ -1458,6 +1465,14 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, args[4], args[5], const_args[2], const_args[4]); break; + case INDEX_op_deposit_i32: + if (const_args[2]) { + tcg_out_depi(s, args[0], args[2], args[3], args[4]); + } else { + tcg_out_dep(s, args[0], args[2], args[3], args[4]); + } + break; + case INDEX_op_qemu_ld8u: tcg_out_qemu_ld(s, args, 0); break; @@ -1551,6 +1566,8 @@ static const TCGTargetOpDef hppa_op_defs[] = { { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rI", "rZ" } }, { INDEX_op_sub2_i32, { "r", "r", "rI", "rZ", "rK", "rZ" } }, + { INDEX_op_deposit_i32, { "r", "0", "rJ" } }, + #if TARGET_LONG_BITS == 32 { INDEX_op_qemu_ld8u, { "r", "L" } }, { INDEX_op_qemu_ld8s, { "r", "L" } }, @@ -1596,7 +1613,7 @@ static int tcg_target_callee_save_regs[] = { TCG_REG_R14, TCG_REG_R15, TCG_REG_R16, - /* R17 is the global env, so no need to save. */ + TCG_REG_R17, /* R17 is the global env. */ TCG_REG_R18 }; @@ -1611,23 +1628,30 @@ static void tcg_target_qemu_prologue(TCGContext *s) /* Allocate space for the saved registers. */ frame_size += ARRAY_SIZE(tcg_target_callee_save_regs) * 4; + /* Allocate space for the TCG temps. */ + frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long); + /* Align the allocated space. */ frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1) & -TCG_TARGET_STACK_ALIGN); /* The return address is stored in the caller's frame. */ - tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_SP, -20); + tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_CALL_STACK, -20); /* Allocate stack frame, saving the first register at the same time. */ tcg_out_ldst(s, tcg_target_callee_save_regs[0], - TCG_REG_SP, frame_size, INSN_STWM); + TCG_REG_CALL_STACK, frame_size, INSN_STWM); /* Save all callee saved registers. */ for (i = 1; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { tcg_out_st(s, TCG_TYPE_PTR, tcg_target_callee_save_regs[i], - TCG_REG_SP, -frame_size + i * 4); + TCG_REG_CALL_STACK, -frame_size + i * 4); } + /* Record the location of the TCG temps. */ + tcg_set_frame(s, TCG_REG_CALL_STACK, -frame_size + i * 4, + CPU_TEMP_BUF_NLONGS * sizeof(long)); + #ifdef CONFIG_USE_GUEST_BASE if (GUEST_BASE != 0) { tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE); @@ -1635,21 +1659,24 @@ static void tcg_target_qemu_prologue(TCGContext *s) } #endif + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* Jump to TB, and adjust R18 to be the return address. */ - tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26)); + tcg_out32(s, INSN_BLE_SR4 | INSN_R2(tcg_target_call_iarg_regs[1])); tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R18, TCG_REG_R31); /* Restore callee saved registers. */ - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_SP, -frame_size - 20); + tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_RP, TCG_REG_CALL_STACK, + -frame_size - 20); for (i = 1; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { tcg_out_ld(s, TCG_TYPE_PTR, tcg_target_callee_save_regs[i], - TCG_REG_SP, -frame_size + i * 4); + TCG_REG_CALL_STACK, -frame_size + i * 4); } /* Deallocate stack frame and return. */ tcg_out32(s, INSN_BV | INSN_R2(TCG_REG_RP)); tcg_out_ldst(s, tcg_target_callee_save_regs[0], - TCG_REG_SP, -frame_size, INSN_LDWM); + TCG_REG_CALL_STACK, -frame_size, INSN_LDWM); } static void tcg_target_init(TCGContext *s) @@ -1676,7 +1703,7 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_R19); /* clobbered w/o pic */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R20); /* reserved */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP); /* data pointer */ - tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */ + tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); /* stack pointer */ tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */ tcg_add_target_add_op_defs(hppa_op_defs); diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h index a5cc440..7f3c4cc 100644 --- a/tcg/hppa/tcg-target.h +++ b/tcg/hppa/tcg-target.h @@ -24,9 +24,7 @@ #define TCG_TARGET_HPPA 1 -#if defined(_PA_RISC1_1) -#define TCG_TARGET_REG_BITS 32 -#else +#if TCG_TARGET_REG_BITS != 32 #error unsupported #endif @@ -34,7 +32,7 @@ #define TCG_TARGET_NB_REGS 32 -enum { +typedef enum { TCG_REG_R0 = 0, TCG_REG_R1, TCG_REG_RP, @@ -67,7 +65,7 @@ enum { TCG_REG_RET1, TCG_REG_SP, TCG_REG_R31, -}; +} TCGReg; #define TCG_CT_CONST_0 0x0100 #define TCG_CT_CONST_S5 0x0200 @@ -85,20 +83,24 @@ enum { #define TCG_TARGET_STACK_GROWSUP /* optional instructions */ -// #define TCG_TARGET_HAS_div_i32 -#define TCG_TARGET_HAS_rot_i32 -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -#define TCG_TARGET_HAS_bswap16_i32 -#define TCG_TARGET_HAS_bswap32_i32 -#define TCG_TARGET_HAS_not_i32 -#define TCG_TARGET_HAS_andc_i32 -// #define TCG_TARGET_HAS_orc_i32 +#define TCG_TARGET_HAS_div_i32 0 +#define TCG_TARGET_HAS_rot_i32 1 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_bswap16_i32 1 +#define TCG_TARGET_HAS_bswap32_i32 1 +#define TCG_TARGET_HAS_not_i32 1 +#define TCG_TARGET_HAS_andc_i32 1 +#define TCG_TARGET_HAS_orc_i32 0 +#define TCG_TARGET_HAS_eqv_i32 0 +#define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_nor_i32 0 +#define TCG_TARGET_HAS_deposit_i32 1 /* optional instructions automatically implemented */ -#undef TCG_TARGET_HAS_neg_i32 /* sub rd, 0, rs */ -#undef TCG_TARGET_HAS_ext8u_i32 /* and rd, rs, 0xff */ -#undef TCG_TARGET_HAS_ext16u_i32 /* and rd, rs, 0xffff */ +#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, 0, rs */ +#define TCG_TARGET_HAS_ext8u_i32 0 /* and rd, rs, 0xff */ +#define TCG_TARGET_HAS_ext16u_i32 0 /* and rd, rs, 0xffff */ #define TCG_TARGET_HAS_GUEST_BASE diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index cc750b4..e4e7e07 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -76,9 +76,11 @@ static const int tcg_target_call_iarg_regs[] = { #endif }; -static const int tcg_target_call_oarg_regs[2] = { +static const int tcg_target_call_oarg_regs[] = { TCG_REG_EAX, +#if TCG_TARGET_REG_BITS == 32 TCG_REG_EDX +#endif }; static uint8_t *tb_ret_addr; @@ -166,6 +168,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) tcg_regset_set32(ct->u.regs, 0, 0xf); } break; + case 'Q': + ct->ct |= TCG_CT_REG; + tcg_regset_set32(ct->u.regs, 0, 0xf); + break; case 'r': ct->ct |= TCG_CT_REG; if (TCG_TARGET_REG_BITS == 64) { @@ -512,7 +518,8 @@ static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src) tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src); } -static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) +static inline void tcg_out_mov(TCGContext *s, TCGType type, + TCGReg ret, TCGReg arg) { if (arg != ret) { int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0); @@ -521,7 +528,7 @@ static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) } static void tcg_out_movi(TCGContext *s, TCGType type, - int ret, tcg_target_long arg) + TCGReg ret, tcg_target_long arg) { if (arg == 0) { tgen_arithr(s, ARITH_XOR, ret, ret); @@ -562,15 +569,15 @@ static inline void tcg_out_pop(TCGContext *s, int reg) tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0); } -static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret, - int arg1, tcg_target_long arg2) +static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, + TCGReg arg1, tcg_target_long arg2) { int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0); tcg_out_modrm_offset(s, opc, ret, arg1, arg2); } -static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, - int arg1, tcg_target_long arg2) +static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0); tcg_out_modrm_offset(s, opc, arg, arg1, arg2); @@ -960,6 +967,7 @@ static void tcg_out_jmp(TCGContext *s, tcg_target_long dest) #include "../../softmmu_defs.h" +#if !defined(CONFIG_QEMU_LDST_OPTIMIZATION) static void *qemu_ld_helpers[4] = { __ldb_mmu, __ldw_mmu, @@ -973,6 +981,7 @@ static void *qemu_st_helpers[4] = { __stl_mmu, __stq_mmu, }; +#endif /* !CONFIG_QEMU_LDST_OPTIMIZATION */ /* Perform the TLB load and compare. @@ -1132,9 +1141,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi, } } -#if !defined(CONFIG_TCG_TARGET_X86_OPT) -/* to suppress warnings */ - +#if !defined(CONFIG_QEMU_LDST_OPTIMIZATION) /* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and EAX. It will be useful once fixed registers globals are less common. */ @@ -1252,7 +1259,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, } #endif } -#endif /* !CONFIG_TCG_TARGET_X86_OPT */ +#endif /* !defined(CONFIG_QEMU_LDST_OPTIMIZATION) */ static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi, int base, tcg_target_long ofs, int sizeop) @@ -1313,9 +1320,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi, } } -#if !defined(CONFIG_TCG_TARGET_X86_OPT) -/* to suppress warnings */ - +#if !defined(CONFIG_QEMU_LDST_OPTIMIZATION) static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc) { @@ -1405,7 +1410,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, /* Pop and discard. This is 2 bytes smaller than the add. */ tcg_out_pop(s, TCG_REG_ECX); } else if (stack_adjust != 0) { - tcg_out_addi(s, TCG_REG_ESP, stack_adjust); + tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust); } /* label2: */ @@ -1433,10 +1438,10 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, } #endif } -#endif /* !CONFIG_TCG_TARGET_X86_OPT */ +#endif /* !defined(CONFIG_QEMU_LDST_OPTIMIZATION) */ -#if defined(CONFIG_TCG_TARGET_X86_OPT) -/* optimization to reduce jump overheads */ +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) +/* optimization to reduce jump overheads for qemu_ld/st IRs */ /* extened versions of MMU helpers */ static void *qemu_ldext_helpers[4] = { @@ -1453,27 +1458,27 @@ static void *qemu_stext_helpers[4] = { }; /* - * qemu_ld/st code generator call add_helper_label, + * qemu_ld/st code generator call add_qemu_ldst_label, * so that slow case(TLB miss or I/O rw) is handled at the end of TB */ -static void add_helper_label(TCGContext *s, - int opc_ext, - int data_reg, - int data_reg2, - int addrlo_reg, - int addrhi_reg, - int mem_index, - uint8_t *raddr, - uint32_t **label_ptr) +static void add_qemu_ldst_label(TCGContext *s, + int opc_ext, + int data_reg, + int data_reg2, + int addrlo_reg, + int addrhi_reg, + int mem_index, + uint8_t *raddr, + uint32_t **label_ptr) { int idx; - HelperLabel *label; + TCGLabelQemuLdst *label; - if (s->nb_helper_labels >= TCG_MAX_HELPER_LABELS) + if (s->nb_qemu_ldst_labels >= TCG_MAX_QEMU_LDST) tcg_abort(); - idx = s->nb_helper_labels++; - label = (HelperLabel *)&s->helper_labels[idx]; + idx = s->nb_qemu_ldst_labels++; + label = (TCGLabelQemuLdst *)&s->qemu_ldst_labels[idx]; label->opc_ext = opc_ext; label->datalo_reg = data_reg; label->datahi_reg = data_reg2; @@ -1489,7 +1494,7 @@ static void add_helper_label(TCGContext *s, } /* generates slow case of qemu_ld at the end of TB */ -static void tcg_out_qemu_ld_helper_call(TCGContext *s, HelperLabel *label) +static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label) { int s_bits, arg_idx; int opc = label->opc_ext & HL_OPC_MASK; @@ -1522,7 +1527,7 @@ static void tcg_out_qemu_ld_helper_call(TCGContext *s, HelperLabel *label) tcg_out_pushi(s, (int)(raddr - 1)); } else { /* 3 word parameters */ - tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_ECX, (int)(raddr - 1)); + tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx++], (int)(raddr - 1)); } tcg_out_calli(s, (tcg_target_long)qemu_ldext_helpers[s_bits]); if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) { @@ -1572,7 +1577,7 @@ static void tcg_out_qemu_ld_helper_call(TCGContext *s, HelperLabel *label) } /* generates slow case of qemu_st at the end of TB */ -static void tcg_out_qemu_st_helper_call(TCGContext *s, HelperLabel *label) +static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *label) { int s_bits; int stack_adjust; @@ -1600,8 +1605,7 @@ static void tcg_out_qemu_st_helper_call(TCGContext *s, HelperLabel *label) tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index); /* return address should indicate qemu_st IR codes */ /* stack growth: 1word * 64bit */ - tcg_out_pushi(s, (int)(raddr - 1)); - stack_adjust = 8; + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RCX, (int)(raddr - 1)); } else if (TARGET_LONG_BITS == 32) { tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_EDX, data_reg); if (opc == 3) { @@ -1655,17 +1659,17 @@ static void tcg_out_qemu_st_helper_call(TCGContext *s, HelperLabel *label) } /* generates all of the slow cases of qemu_ld/st at the end of TB */ -void tcg_out_qemu_ldst_helper_calls(TCGContext *s) +void tcg_out_qemu_ldst_slow_path(TCGContext *s) { int i; - HelperLabel *label; + TCGLabelQemuLdst *label; - for (i = 0; i < s->nb_helper_labels; i++) { - label = (HelperLabel *)&s->helper_labels[i]; + for (i = 0; i < s->nb_qemu_ldst_labels; i++) { + label = (TCGLabelQemuLdst *)&s->qemu_ldst_labels[i]; if (IS_QEMU_LD_LABEL(label)) { - tcg_out_qemu_ld_helper_call(s, label); + tcg_out_qemu_ld_slow_path(s, label); } else { - tcg_out_qemu_st_helper_call(s, label); + tcg_out_qemu_st_slow_path(s, label); } } } @@ -1765,10 +1769,15 @@ static void tcg_out_qemu_ld_opt(TCGContext *s, const TCGArg *args, tcg_target_call_iarg_regs[0], 0, opc); /* helper stub will be jumped back here */ - add_helper_label(s, opc, data_reg, data_reg2, - args[addrlo_idx], - (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) ? args[addrlo_idx + 1] : 0, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, + opc, + data_reg, + data_reg2, + args[addrlo_idx], + args[addrlo_idx + 1], + mem_index, + s->code_ptr, + label_ptr); } @@ -1798,13 +1807,17 @@ static void tcg_out_qemu_st_opt(TCGContext *s, const TCGArg *args, tcg_target_call_iarg_regs[0], 0, opc); /* helper stub will be jumped back here */ - add_helper_label(s, opc | HL_ST_MASK, data_reg, data_reg2, - args[addrlo_idx], - (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) ? args[addrlo_idx + 1] : 0, - mem_index, s->code_ptr, label_ptr); + add_qemu_ldst_label(s, + opc | HL_ST_MASK, + data_reg, + data_reg2, + args[addrlo_idx], + args[addrlo_idx + 1], + mem_index, + s->code_ptr, + label_ptr); } - -#endif /* CONFIG_TCG_TARGET_X86_OPT */ +#endif /* defined(CONFIG_QEMU_LDST_OPTIMIZATION) */ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, const int *const_args) @@ -2018,9 +2031,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext16u(s, args[0], args[1]); break; -#if defined(CONFIG_TCG_TARGET_X86_OPT) && defined(CONFIG_SOFTMMU) +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) #define tcg_out_qemu_ld(S, ARGS, OPC) tcg_out_qemu_ld_opt(S, ARGS, OPC) -#endif /* CONFIG_TCG_TARGET_X86_OPT */ +#endif /* defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) */ case INDEX_op_qemu_ld8u: tcg_out_qemu_ld(s, args, 0); break; @@ -2043,9 +2056,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_ld(s, args, 3); break; -#if defined(CONFIG_TCG_TARGET_X86_OPT) && defined(CONFIG_SOFTMMU) +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) #define tcg_out_qemu_st(S, ARGS, OPC) tcg_out_qemu_st_opt(S, ARGS, OPC) -#endif /* CONFIG_TCG_TARGET_X86_OPT */ +#endif /* defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) */ case INDEX_op_qemu_st8: tcg_out_qemu_st(s, args, 0); break; @@ -2130,6 +2143,22 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, break; #endif + OP_32_64(deposit): + if (args[3] == 0 && args[4] == 8) { + /* load bits 0..7 */ + tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM, + args[2], args[0]); + } else if (args[3] == 8 && args[4] == 8) { + /* load bits 8..15 */ + tcg_out_modrm(s, OPC_MOVB_EvGv, args[2], args[0] + 4); + } else if (args[3] == 0 && args[4] == 16) { + /* load bits 0..15 */ + tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, args[2], args[0]); + } else { + tcg_abort(); + } + break; + default: tcg_abort(); } @@ -2185,6 +2214,8 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_setcond_i32, { "q", "r", "ri" } }, + { INDEX_op_deposit_i32, { "Q", "0", "Q" } }, + #if TCG_TARGET_REG_BITS == 32 { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } }, { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } }, @@ -2236,6 +2267,8 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_ext8u_i64, { "r", "r" } }, { INDEX_op_ext16u_i64, { "r", "r" } }, { INDEX_op_ext32u_i64, { "r", "r" } }, + + { INDEX_op_deposit_i64, { "Q", "0", "Q" } }, #endif #if TCG_TARGET_REG_BITS == 64 @@ -2277,9 +2310,6 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_qemu_st32, { "L", "L", "L" } }, { INDEX_op_qemu_st64, { "L", "L", "L", "L" } }, #endif -#ifdef CONFIG_EXEC_PROFILE - { INDEX_op_prof_tbexec, { } }, -#endif { -1 }, }; @@ -2289,10 +2319,10 @@ static int tcg_target_callee_save_regs[] = { TCG_REG_RBX, TCG_REG_R12, TCG_REG_R13, - /* TCG_REG_R14, */ /* Currently used for the global env. */ + TCG_REG_R14, /* Currently used for the global env. */ TCG_REG_R15, #else - /* TCG_REG_EBP, */ /* Currently used for the global env. */ + TCG_REG_EBP, /* Currently used for the global env. */ TCG_REG_EBX, TCG_REG_ESI, TCG_REG_EDI, @@ -2306,28 +2336,34 @@ static void tcg_target_qemu_prologue(TCGContext *s) /* TB prologue */ - /* Save all callee saved registers. */ - for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { - tcg_out_push(s, tcg_target_callee_save_regs[i]); - } - - /* Reserve some stack space. */ + /* Reserve some stack space, also for TCG temps. */ push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs); push_size *= TCG_TARGET_REG_BITS / 8; - frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE; + frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE + + CPU_TEMP_BUF_NLONGS * sizeof(long); frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & ~(TCG_TARGET_STACK_ALIGN - 1); stack_addend = frame_size - push_size; + tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE, + CPU_TEMP_BUF_NLONGS * sizeof(long)); + + /* Save all callee saved registers. */ + for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { + tcg_out_push(s, tcg_target_callee_save_regs[i]); + } + tcg_out_addi(s, TCG_REG_ESP, -stack_addend); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* jmp *tb. */ - tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]); + tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]); /* TB epilogue */ tb_ret_addr = s->code_ptr; - tcg_out_addi(s, TCG_REG_ESP, stack_addend); + tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend); for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) { tcg_out_pop(s, tcg_target_callee_save_regs[i]); @@ -2364,7 +2400,7 @@ static void tcg_target_init(TCGContext *s) } tcg_regset_clear(s->reserved_regs); - tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP); + tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); tcg_add_target_add_op_defs(x86_op_defs); } diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index bfafbfc..7756e7b 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -36,7 +36,7 @@ # define TCG_TARGET_NB_REGS 8 #endif -enum { +typedef enum { TCG_REG_EAX = 0, TCG_REG_ECX, TCG_REG_EDX, @@ -64,7 +64,7 @@ enum { TCG_REG_RBP = TCG_REG_EBP, TCG_REG_RSI = TCG_REG_ESI, TCG_REG_RDI = TCG_REG_EDI, -}; +} TCGReg; #define TCG_CT_CONST_S32 0x100 #define TCG_CT_CONST_U32 0x200 @@ -75,43 +75,50 @@ enum { #define TCG_TARGET_CALL_STACK_OFFSET 0 /* optional instructions */ -#define TCG_TARGET_HAS_div2_i32 -#define TCG_TARGET_HAS_rot_i32 -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -#define TCG_TARGET_HAS_ext8u_i32 -#define TCG_TARGET_HAS_ext16u_i32 -#define TCG_TARGET_HAS_bswap16_i32 -#define TCG_TARGET_HAS_bswap32_i32 -#define TCG_TARGET_HAS_neg_i32 -#define TCG_TARGET_HAS_not_i32 -// #define TCG_TARGET_HAS_andc_i32 -// #define TCG_TARGET_HAS_orc_i32 -// #define TCG_TARGET_HAS_eqv_i32 -// #define TCG_TARGET_HAS_nand_i32 -// #define TCG_TARGET_HAS_nor_i32 +#define TCG_TARGET_HAS_div2_i32 1 +#define TCG_TARGET_HAS_rot_i32 1 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_ext8u_i32 1 +#define TCG_TARGET_HAS_ext16u_i32 1 +#define TCG_TARGET_HAS_bswap16_i32 1 +#define TCG_TARGET_HAS_bswap32_i32 1 +#define TCG_TARGET_HAS_neg_i32 1 +#define TCG_TARGET_HAS_not_i32 1 +#define TCG_TARGET_HAS_andc_i32 0 +#define TCG_TARGET_HAS_orc_i32 0 +#define TCG_TARGET_HAS_eqv_i32 0 +#define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_nor_i32 0 +#define TCG_TARGET_HAS_deposit_i32 1 #if TCG_TARGET_REG_BITS == 64 -#define TCG_TARGET_HAS_div2_i64 -#define TCG_TARGET_HAS_rot_i64 -#define TCG_TARGET_HAS_ext8s_i64 -#define TCG_TARGET_HAS_ext16s_i64 -#define TCG_TARGET_HAS_ext32s_i64 -#define TCG_TARGET_HAS_ext8u_i64 -#define TCG_TARGET_HAS_ext16u_i64 -#define TCG_TARGET_HAS_ext32u_i64 -#define TCG_TARGET_HAS_bswap16_i64 -#define TCG_TARGET_HAS_bswap32_i64 -#define TCG_TARGET_HAS_bswap64_i64 -#define TCG_TARGET_HAS_neg_i64 -#define TCG_TARGET_HAS_not_i64 -// #define TCG_TARGET_HAS_andc_i64 -// #define TCG_TARGET_HAS_orc_i64 -// #define TCG_TARGET_HAS_eqv_i64 -// #define TCG_TARGET_HAS_nand_i64 -// #define TCG_TARGET_HAS_nor_i64 +#define TCG_TARGET_HAS_div2_i64 1 +#define TCG_TARGET_HAS_rot_i64 1 +#define TCG_TARGET_HAS_ext8s_i64 1 +#define TCG_TARGET_HAS_ext16s_i64 1 +#define TCG_TARGET_HAS_ext32s_i64 1 +#define TCG_TARGET_HAS_ext8u_i64 1 +#define TCG_TARGET_HAS_ext16u_i64 1 +#define TCG_TARGET_HAS_ext32u_i64 1 +#define TCG_TARGET_HAS_bswap16_i64 1 +#define TCG_TARGET_HAS_bswap32_i64 1 +#define TCG_TARGET_HAS_bswap64_i64 1 +#define TCG_TARGET_HAS_neg_i64 1 +#define TCG_TARGET_HAS_not_i64 1 +#define TCG_TARGET_HAS_andc_i64 0 +#define TCG_TARGET_HAS_orc_i64 0 +#define TCG_TARGET_HAS_eqv_i64 0 +#define TCG_TARGET_HAS_nand_i64 0 +#define TCG_TARGET_HAS_nor_i64 0 +#define TCG_TARGET_HAS_deposit_i64 1 #endif +#define TCG_TARGET_deposit_i32_valid(ofs, len) \ + (((ofs) == 0 && (len) == 8) || ((ofs) == 8 && (len) == 8) || \ + ((ofs) == 0 && (len) == 16)) +#define TCG_TARGET_deposit_i64_valid TCG_TARGET_deposit_i32_valid + #define TCG_TARGET_HAS_GUEST_BASE /* Note: must be synced with dyngen-exec.h */ diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 8dac7f7..e3de79f 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -172,9 +172,8 @@ static const int tcg_target_call_iarg_regs[8] = { TCG_REG_R63, }; -static const int tcg_target_call_oarg_regs[2] = { - TCG_REG_R8, - TCG_REG_R9 +static const int tcg_target_call_oarg_regs[] = { + TCG_REG_R8 }; /* maximum number of register used for input function arguments */ @@ -831,7 +830,7 @@ static inline void tcg_out_bundle(TCGContext *s, int template, } static inline void tcg_out_mov(TCGContext *s, TCGType type, - TCGArg ret, TCGArg arg) + TCGReg ret, TCGReg arg) { tcg_out_bundle(s, mmI, tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), @@ -840,7 +839,7 @@ static inline void tcg_out_mov(TCGContext *s, TCGType type, } static inline void tcg_out_movi(TCGContext *s, TCGType type, - TCGArg reg, tcg_target_long arg) + TCGReg reg, tcg_target_long arg) { tcg_out_bundle(s, mLX, tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), @@ -848,25 +847,6 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type, tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, reg, arg)); } -static inline void tcg_out_addi(TCGContext *s, TCGArg reg, tcg_target_long val) -{ - if (val == ((int32_t)val << 10) >> 10) { - tcg_out_bundle(s, MmI, - tcg_opc_a5(TCG_REG_P0, OPC_ADDL_A5, - TCG_REG_R2, val, TCG_REG_R0), - tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), - tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, reg, - reg, TCG_REG_R2)); - } else { - tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, val); - tcg_out_bundle(s, mmI, - tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), - tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), - tcg_opc_a1 (TCG_REG_P0, OPC_ADD_A1, reg, - reg, TCG_REG_R2)); - } -} - static void tcg_out_br(TCGContext *s, int label_index) { TCGLabel *l = &s->labels[label_index]; @@ -992,8 +972,8 @@ static inline void tcg_out_st_rel(TCGContext *s, uint64_t opc_m4, TCGArg arg, } } -static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGArg arg, - TCGArg arg1, tcg_target_long arg2) +static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { if (type == TCG_TYPE_I32) { tcg_out_ld_rel(s, OPC_LD4_M1, arg, arg1, arg2); @@ -1002,8 +982,8 @@ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGArg arg, } } -static inline void tcg_out_st(TCGContext *s, TCGType type, TCGArg arg, - TCGArg arg1, tcg_target_long arg2) +static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { if (type == TCG_TYPE_I32) { tcg_out_st_rel(s, OPC_ST4_M4, arg, arg1, arg2); @@ -2292,7 +2272,7 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34, TCG_REG_R33, 32, 24, 0), tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, - TCG_REG_B6, TCG_REG_R32, 0), + TCG_REG_B6, TCG_REG_R33, 0), tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22, TCG_REG_R32, TCG_REG_B0)); @@ -2308,7 +2288,8 @@ static void tcg_target_qemu_prologue(TCGContext *s) } tcg_out_bundle(s, miB, - tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), + tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, + TCG_AREG0, 0, TCG_REG_R32), tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, TCG_REG_R12, -frame_size, TCG_REG_R12), tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6)); @@ -2387,4 +2368,6 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6); tcg_add_target_add_op_defs(ia64_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h index e56e88f..c388089 100644 --- a/tcg/ia64/tcg-target.h +++ b/tcg/ia64/tcg-target.h @@ -24,11 +24,9 @@ */ #define TCG_TARGET_IA64 1 -#define TCG_TARGET_REG_BITS 64 - /* We only map the first 64 registers */ #define TCG_TARGET_NB_REGS 64 -enum { +typedef enum { TCG_REG_R0 = 0, TCG_REG_R1, TCG_REG_R2, @@ -93,7 +91,7 @@ enum { TCG_REG_R61, TCG_REG_R62, TCG_REG_R63, -}; +} TCGReg; #define TCG_CT_CONST_ZERO 0x100 #define TCG_CT_CONST_S22 0x200 @@ -104,39 +102,43 @@ enum { #define TCG_TARGET_CALL_STACK_OFFSET 16 /* optional instructions */ -#define TCG_TARGET_HAS_andc_i32 -#define TCG_TARGET_HAS_andc_i64 -#define TCG_TARGET_HAS_bswap16_i32 -#define TCG_TARGET_HAS_bswap16_i64 -#define TCG_TARGET_HAS_bswap32_i32 -#define TCG_TARGET_HAS_bswap32_i64 -#define TCG_TARGET_HAS_bswap64_i64 -#define TCG_TARGET_HAS_eqv_i32 -#define TCG_TARGET_HAS_eqv_i64 -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -#define TCG_TARGET_HAS_ext8s_i64 -#define TCG_TARGET_HAS_ext16s_i64 -#define TCG_TARGET_HAS_ext32s_i64 -#define TCG_TARGET_HAS_ext8u_i32 -#define TCG_TARGET_HAS_ext16u_i32 -#define TCG_TARGET_HAS_ext8u_i64 -#define TCG_TARGET_HAS_ext16u_i64 -#define TCG_TARGET_HAS_ext32u_i64 -#define TCG_TARGET_HAS_nand_i32 -#define TCG_TARGET_HAS_nand_i64 -#define TCG_TARGET_HAS_nor_i32 -#define TCG_TARGET_HAS_nor_i64 -#define TCG_TARGET_HAS_orc_i32 -#define TCG_TARGET_HAS_orc_i64 -#define TCG_TARGET_HAS_rot_i32 -#define TCG_TARGET_HAS_rot_i64 +#define TCG_TARGET_HAS_div_i32 0 +#define TCG_TARGET_HAS_div_i64 0 +#define TCG_TARGET_HAS_andc_i32 1 +#define TCG_TARGET_HAS_andc_i64 1 +#define TCG_TARGET_HAS_bswap16_i32 1 +#define TCG_TARGET_HAS_bswap16_i64 1 +#define TCG_TARGET_HAS_bswap32_i32 1 +#define TCG_TARGET_HAS_bswap32_i64 1 +#define TCG_TARGET_HAS_bswap64_i64 1 +#define TCG_TARGET_HAS_eqv_i32 1 +#define TCG_TARGET_HAS_eqv_i64 1 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_ext8s_i64 1 +#define TCG_TARGET_HAS_ext16s_i64 1 +#define TCG_TARGET_HAS_ext32s_i64 1 +#define TCG_TARGET_HAS_ext8u_i32 1 +#define TCG_TARGET_HAS_ext16u_i32 1 +#define TCG_TARGET_HAS_ext8u_i64 1 +#define TCG_TARGET_HAS_ext16u_i64 1 +#define TCG_TARGET_HAS_ext32u_i64 1 +#define TCG_TARGET_HAS_nand_i32 1 +#define TCG_TARGET_HAS_nand_i64 1 +#define TCG_TARGET_HAS_nor_i32 1 +#define TCG_TARGET_HAS_nor_i64 1 +#define TCG_TARGET_HAS_orc_i32 1 +#define TCG_TARGET_HAS_orc_i64 1 +#define TCG_TARGET_HAS_rot_i32 1 +#define TCG_TARGET_HAS_rot_i64 1 +#define TCG_TARGET_HAS_deposit_i32 0 +#define TCG_TARGET_HAS_deposit_i64 0 /* optional instructions automatically implemented */ -#undef TCG_TARGET_HAS_neg_i32 /* sub r1, r0, r3 */ -#undef TCG_TARGET_HAS_neg_i64 /* sub r1, r0, r3 */ -#undef TCG_TARGET_HAS_not_i32 /* xor r1, -1, r3 */ -#undef TCG_TARGET_HAS_not_i64 /* xor r1, -1, r3 */ +#define TCG_TARGET_HAS_neg_i32 0 /* sub r1, r0, r3 */ +#define TCG_TARGET_HAS_neg_i64 0 /* sub r1, r0, r3 */ +#define TCG_TARGET_HAS_not_i32 0 /* xor r1, -1, r3 */ +#define TCG_TARGET_HAS_not_i64 0 /* xor r1, -1, r3 */ /* Note: must be synced with dyngen-exec.h */ #define TCG_AREG0 TCG_REG_R7 diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index e04b0dc..c5c3282 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -379,13 +379,14 @@ static inline void tcg_out_nop(TCGContext *s) tcg_out32(s, 0); } -static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) +static inline void tcg_out_mov(TCGContext *s, TCGType type, + TCGReg ret, TCGReg arg) { tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO); } static inline void tcg_out_movi(TCGContext *s, TCGType type, - int reg, int32_t arg) + TCGReg reg, tcg_target_long arg) { if (arg == (int16_t)arg) { tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg); @@ -480,14 +481,14 @@ static inline void tcg_out_ldst(TCGContext *s, int opc, int arg, } } -static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg, - int arg1, tcg_target_long arg2) +static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { tcg_out_ldst(s, OPC_LW, arg, arg1, arg2); } -static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, - int arg1, tcg_target_long arg2) +static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { tcg_out_ldst(s, OPC_SW, arg, arg1, arg2); } @@ -1452,9 +1453,7 @@ static const TCGTargetOpDef mips_op_defs[] = { }; static int tcg_target_callee_save_regs[] = { -#if 0 /* used for the global env (TCG_AREG0), so no need to save */ - TCG_REG_S0, -#endif + TCG_REG_S0, /* used for the global env (TCG_AREG0) */ TCG_REG_S1, TCG_REG_S2, TCG_REG_S3, @@ -1486,8 +1485,8 @@ static void tcg_target_qemu_prologue(TCGContext *s) } /* Call generated code */ - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0); - tcg_out_nop(s); + tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); tb_ret_addr = s->code_ptr; /* TB epilogue */ @@ -1530,4 +1529,6 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */ tcg_add_target_add_op_defs(mips_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index 0028bfa..477bc38 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -25,14 +25,13 @@ */ #define TCG_TARGET_MIPS 1 -#define TCG_TARGET_REG_BITS 32 #ifdef __MIPSEB__ # define TCG_TARGET_WORDS_BIGENDIAN #endif #define TCG_TARGET_NB_REGS 32 -enum { +typedef enum { TCG_REG_ZERO = 0, TCG_REG_AT, TCG_REG_V0, @@ -65,7 +64,7 @@ enum { TCG_REG_SP, TCG_REG_FP, TCG_REG_RA, -}; +} TCGReg; #define TCG_CT_CONST_ZERO 0x100 #define TCG_CT_CONST_U16 0x200 @@ -78,23 +77,24 @@ enum { #define TCG_TARGET_CALL_ALIGN_ARGS 1 /* optional instructions */ -#define TCG_TARGET_HAS_div_i32 -#define TCG_TARGET_HAS_not_i32 -#define TCG_TARGET_HAS_nor_i32 -#undef TCG_TARGET_HAS_rot_i32 -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -#undef TCG_TARGET_HAS_bswap32_i32 -#undef TCG_TARGET_HAS_bswap16_i32 -#undef TCG_TARGET_HAS_andc_i32 -#undef TCG_TARGET_HAS_orc_i32 -#undef TCG_TARGET_HAS_eqv_i32 -#undef TCG_TARGET_HAS_nand_i32 +#define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_not_i32 1 +#define TCG_TARGET_HAS_nor_i32 1 +#define TCG_TARGET_HAS_rot_i32 0 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_bswap32_i32 0 +#define TCG_TARGET_HAS_bswap16_i32 0 +#define TCG_TARGET_HAS_andc_i32 0 +#define TCG_TARGET_HAS_orc_i32 0 +#define TCG_TARGET_HAS_eqv_i32 0 +#define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_deposit_i32 0 /* optional instructions automatically implemented */ -#undef TCG_TARGET_HAS_neg_i32 /* sub rd, zero, rt */ -#undef TCG_TARGET_HAS_ext8u_i32 /* andi rt, rs, 0xff */ -#undef TCG_TARGET_HAS_ext16u_i32 /* andi rt, rs, 0xffff */ +#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, zero, rt */ +#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */ +#define TCG_TARGET_HAS_ext16u_i32 0 /* andi rt, rs, 0xffff */ /* Note: must be synced with dyngen-exec.h */ #define TCG_AREG0 TCG_REG_S0 @@ -102,7 +102,11 @@ enum { /* guest base is supported */ #define TCG_TARGET_HAS_GUEST_BASE +#ifdef __OpenBSD__ +#include +#else #include +#endif static inline void flush_icache_range(unsigned long start, unsigned long stop) { diff --git a/tcg/optimize.c b/tcg/optimize.c index 0771008..9c65474 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -1,7 +1,8 @@ /* * Optimizations for Tiny Code Generator for QEMU * - * Copyright (c) 2010 Kirill Batuzov + * Copyright (c) 2010 Samsung Electronics. + * Contributed by Kirill Batuzov * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,284 +27,265 @@ #include #include -#include -#include -#ifdef _WIN32 -#include -#endif -#ifdef _AIX -#include -#endif #include "qemu-common.h" -#include "cache-utils.h" -#include "host-utils.h" -#define NO_CPU_IO_DEFS -#include "cpu.h" -#include "exec-all.h" - #include "tcg-op.h" -#include "elf.h" - -#if defined(CONFIG_USE_GUEST_BASE) && !defined(TCG_TARGET_HAS_GUEST_BASE) -#error GUEST_BASE not supported on this host. -#endif - -typedef enum { TCG_TEMP_UNDEF = 0, TCG_TEMP_CONST, TCG_TEMP_COPY, TCG_TEMP_ANY } tcg_temp_state; -const int mov_opc[] = { - INDEX_op_mov_i32, -#if TCG_TARGET_REG_BITS == 64 - INDEX_op_mov_i64, -#endif +#define CASE_OP_32_64(x) \ + glue(glue(case INDEX_op_, x), _i32): \ + glue(glue(case INDEX_op_, x), _i64) + +typedef enum { + TCG_TEMP_UNDEF = 0, + TCG_TEMP_CONST, + TCG_TEMP_COPY, + TCG_TEMP_HAS_COPY, + TCG_TEMP_ANY +} tcg_temp_state; + +struct tcg_temp_info { + tcg_temp_state state; + uint16_t prev_copy; + uint16_t next_copy; + tcg_target_ulong val; }; -static int op_to_opi(int op) +static struct tcg_temp_info temps[TCG_MAX_TEMPS]; + +/* Reset TEMP's state to TCG_TEMP_ANY. If TEMP was a representative of some + class of equivalent temp's, a new representative should be chosen in this + class. */ +static void reset_temp(TCGArg temp, int nb_temps, int nb_globals) { - switch(op) { - case INDEX_op_mov_i32: return INDEX_op_movi_i32; -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_mov_i64: return INDEX_op_movi_i64; -#endif - default: - fprintf(stderr, "INTERNAL ERROR: TCG optimizer encountered an " - "unrecognized operation in op_to_opi.\n"); - exit(1); + int i; + TCGArg new_base = (TCGArg)-1; + if (temps[temp].state == TCG_TEMP_HAS_COPY) { + for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) { + if (i >= nb_globals) { + temps[i].state = TCG_TEMP_HAS_COPY; + new_base = i; + break; + } + } + for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) { + if (new_base == (TCGArg)-1) { + temps[i].state = TCG_TEMP_ANY; + } else { + temps[i].val = new_base; + } + } + temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy; + temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy; + } else if (temps[temp].state == TCG_TEMP_COPY) { + temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy; + temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy; + new_base = temps[temp].val; + } + temps[temp].state = TCG_TEMP_ANY; + if (new_base != (TCGArg)-1 && temps[new_base].next_copy == new_base) { + temps[new_base].state = TCG_TEMP_ANY; } } -static int op_bits(int op) +static int op_bits(TCGOpcode op) { - switch(op) { - case INDEX_op_mov_i32: - case INDEX_op_add_i32: - case INDEX_op_sub_i32: - case INDEX_op_mul_i32: - case INDEX_op_and_i32: - case INDEX_op_or_i32: - case INDEX_op_xor_i32: - case INDEX_op_shl_i32: - case INDEX_op_shr_i32: - case INDEX_op_sar_i32: - case INDEX_op_rotl_i32: - case INDEX_op_rotr_i32: - return 32; -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_mov_i64: - case INDEX_op_add_i64: - case INDEX_op_sub_i64: - case INDEX_op_mul_i64: - case INDEX_op_and_i64: - case INDEX_op_or_i64: - case INDEX_op_xor_i64: - case INDEX_op_shl_i64: - case INDEX_op_shr_i64: - case INDEX_op_sar_i64: - case INDEX_op_rotl_i64: - case INDEX_op_rotr_i64: - return 64; -#endif - default: - fprintf(stderr, "INTERNAL ERROR: TCG optimizer encountered an " - "unrecognized operation in op_bits.\n"); - exit(1); - } + const TCGOpDef *def = &tcg_op_defs[op]; + return def->flags & TCG_OPF_64BIT ? 64 : 32; } -static int op_to_movi(int op) +static TCGOpcode op_to_movi(TCGOpcode op) { - if (op_bits(op) == 32) + switch (op_bits(op)) { + case 32: return INDEX_op_movi_i32; -#if TCG_TARGET_REG_BITS == 64 - if (op_bits(op) == 64) + case 64: return INDEX_op_movi_i64; -#endif - fprintf(stderr, "INTERNAL ERROR: TCG optimizer encountered an " - "unrecognized operation in op_to_movi.\n"); - exit(1); + default: + fprintf(stderr, "op_to_movi: unexpected return value of " + "function op_bits.\n"); + tcg_abort(); + } } -static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y) +static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, TCGArg dst, + TCGArg src, int nb_temps, int nb_globals) { - TCGArg r; - switch(op) { - case INDEX_op_add_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_add_i64: -#endif - return x + y; - - case INDEX_op_sub_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_sub_i64: -#endif - return x - y; - - case INDEX_op_mul_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_mul_i64: -#endif - return x * y; - - case INDEX_op_and_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_and_i64: -#endif - return x & y; - - case INDEX_op_or_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_or_i64: -#endif - return x | y; - - case INDEX_op_xor_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_xor_i64: -#endif - return x ^ y; - - case INDEX_op_shl_i32: -#if TCG_TARGET_REG_BITS == 64 - y &= 0xffffffff; - case INDEX_op_shl_i64: -#endif - return x << y; - - case INDEX_op_shr_i32: -#if TCG_TARGET_REG_BITS == 64 - x &= 0xffffffff; - y &= 0xffffffff; - case INDEX_op_shr_i64: -#endif - /* Assuming TCGArg to be unsigned */ - return x >> y; - - case INDEX_op_sar_i32: -#if TCG_TARGET_REG_BITS == 64 - x &= 0xffffffff; - y &= 0xffffffff; -#endif - r = x & 0x80000000; - x &= ~0x80000000; - x >>= y; - r |= r - (r >> y); - x |= r; - return x; - -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_sar_i64: - r = x & 0x8000000000000000ULL; - x &= ~0x8000000000000000ULL; - x >>= y; - r |= r - (r >> y); - x |= r; - return x; -#endif - - case INDEX_op_rotr_i32: -#if TCG_TARGET_REG_BITS == 64 - x &= 0xffffffff; - y &= 0xffffffff; -#endif - x = (x << (32 - y)) | (x >> y); - return x; - -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_rotr_i64: - x = (x << (64 - y)) | (x >> y); - return x; -#endif - - case INDEX_op_rotl_i32: -#if TCG_TARGET_REG_BITS == 64 - x &= 0xffffffff; - y &= 0xffffffff; -#endif - x = (x << y) | (x >> (32 - y)); - return x; - -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_rotl_i64: - x = (x << y) | (x >> (64 - y)); - return x; -#endif + reset_temp(dst, nb_temps, nb_globals); + assert(temps[src].state != TCG_TEMP_COPY); + /* Don't try to copy if one of temps is a global or either one + is local and another is register */ + if (src >= nb_globals && dst >= nb_globals && + tcg_arg_is_local(s, src) == tcg_arg_is_local(s, dst)) { + assert(temps[src].state != TCG_TEMP_CONST); + if (temps[src].state != TCG_TEMP_HAS_COPY) { + temps[src].state = TCG_TEMP_HAS_COPY; + temps[src].next_copy = src; + temps[src].prev_copy = src; + } + temps[dst].state = TCG_TEMP_COPY; + temps[dst].val = src; + temps[dst].next_copy = temps[src].next_copy; + temps[dst].prev_copy = src; + temps[temps[dst].next_copy].prev_copy = dst; + temps[src].next_copy = dst; + } + gen_args[0] = dst; + gen_args[1] = src; +} - default: - fprintf(stderr, "INTERNAL ERROR: TCG optimizer encountered an " - "unrecognized operation in do_constant_folding.\n"); - exit(1); - } +static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val, + int nb_temps, int nb_globals) +{ + reset_temp(dst, nb_temps, nb_globals); + temps[dst].state = TCG_TEMP_CONST; + temps[dst].val = val; + gen_args[0] = dst; + gen_args[1] = val; } -static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y) +static TCGOpcode op_to_mov(TCGOpcode op) { - TCGArg res = do_constant_folding_2(op, x, y); -#if TCG_TARGET_REG_BITS == 64 - if (op_bits(op) == 32) { - res &= 0xffffffff; + switch (op_bits(op)) { + case 32: + return INDEX_op_mov_i32; + case 64: + return INDEX_op_mov_i64; + default: + fprintf(stderr, "op_to_mov: unexpected return value of " + "function op_bits.\n"); + tcg_abort(); } -#endif - return res; } -static void reset_temp(tcg_temp_state *state, tcg_target_ulong *vals, - TCGArg temp, int nb_temps, int nb_globals) +static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y) { - int i; - TCGArg new_base; - new_base = (TCGArg)-1; -#if 0 - for (i = 0; i < nb_temps; i++) { - if (state[i] == TCG_TEMP_COPY && vals[i] == temp) { - if (new_base == ((TCGArg)-1)) { - new_base = (TCGArg)i; - state[i] = TCG_TEMP_ANY; - } else { - vals[i] = new_base; - } - } - } -#else - for (i = nb_globals; i < nb_temps; i++) { - if (state[i] == TCG_TEMP_COPY && vals[i] == temp) { - if (new_base == ((TCGArg)-1)) { - new_base = (TCGArg)i; - state[i] = TCG_TEMP_ANY; - } else { - vals[i] = new_base; - } - } + switch (op) { + CASE_OP_32_64(add): + return x + y; + + CASE_OP_32_64(sub): + return x - y; + + CASE_OP_32_64(mul): + return x * y; + + CASE_OP_32_64(and): + return x & y; + + CASE_OP_32_64(or): + return x | y; + + CASE_OP_32_64(xor): + return x ^ y; + + case INDEX_op_shl_i32: + return (uint32_t)x << (uint32_t)y; + + case INDEX_op_shl_i64: + return (uint64_t)x << (uint64_t)y; + + case INDEX_op_shr_i32: + return (uint32_t)x >> (uint32_t)y; + + case INDEX_op_shr_i64: + return (uint64_t)x >> (uint64_t)y; + + case INDEX_op_sar_i32: + return (int32_t)x >> (int32_t)y; + + case INDEX_op_sar_i64: + return (int64_t)x >> (int64_t)y; + + case INDEX_op_rotr_i32: + x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y); + return x; + + case INDEX_op_rotr_i64: + x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y); + return x; + + case INDEX_op_rotl_i32: + x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y)); + return x; + + case INDEX_op_rotl_i64: + x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y)); + return x; + + CASE_OP_32_64(not): + return ~x; + + CASE_OP_32_64(neg): + return -x; + + CASE_OP_32_64(andc): + return x & ~y; + + CASE_OP_32_64(orc): + return x | ~y; + + CASE_OP_32_64(eqv): + return ~(x ^ y); + + CASE_OP_32_64(nand): + return ~(x & y); + + CASE_OP_32_64(nor): + return ~(x | y); + + CASE_OP_32_64(ext8s): + return (int8_t)x; + + CASE_OP_32_64(ext16s): + return (int16_t)x; + + CASE_OP_32_64(ext8u): + return (uint8_t)x; + + CASE_OP_32_64(ext16u): + return (uint16_t)x; + + case INDEX_op_ext32s_i64: + return (int32_t)x; + + case INDEX_op_ext32u_i64: + return (uint32_t)x; + + default: + fprintf(stderr, + "Unrecognized operation %d in do_constant_folding.\n", op); + tcg_abort(); } - for (i = 0; i < nb_globals; i++) { - if (state[i] == TCG_TEMP_COPY && vals[i] == temp) { - if (new_base == ((TCGArg)-1)) { - state[i] = TCG_TEMP_ANY; - } else { - vals[i] = new_base; - } - } +} + +static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y) +{ + TCGArg res = do_constant_folding_2(op, x, y); + if (op_bits(op) == 32) { + res &= 0xffffffff; } -#endif - state[temp] = TCG_TEMP_ANY; + return res; } +/* Propagate constants and copies, fold constant expressions. */ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args, TCGOpDef *tcg_op_defs) { - int i, nb_ops, op_index, op, nb_temps, nb_globals; + int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args; + TCGOpcode op; const TCGOpDef *def; TCGArg *gen_args; - tcg_target_ulong *vals; - tcg_temp_state *state; + TCGArg tmp; + /* Array VALS has an element for each temp. + If this temp holds a constant then its value is kept in VALS' element. + If this temp is a copy of other ones then this equivalence class' + representative is kept in VALS' element. + If this temp is neither copy nor constant then corresponding VALS' + element is unused. */ nb_temps = s->nb_temps; nb_globals = s->nb_globals; - state = (tcg_temp_state *)malloc(sizeof(tcg_temp_state) * nb_temps); - vals = (tcg_target_ulong *)malloc(sizeof(tcg_target_ulong) * nb_temps); - memset(state, 0, nb_temps * sizeof(tcg_temp_state)); - - // gen_opc_ptr++; /* Skip end? What is this? */ + memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); nb_ops = tcg_opc_ptr - gen_opc_buf; gen_args = args; @@ -311,170 +293,226 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, op = gen_opc_buf[op_index]; def = &tcg_op_defs[op]; /* Do copy propagation */ - if (op != INDEX_op_call) { + if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS))) { + assert(op != INDEX_op_call); for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) { - if (state[args[i]] == TCG_TEMP_COPY - && !(def->args_ct[i].ct & TCG_CT_IALIAS) - /* TODO: is this check really needed??? */ - && (def->args_ct[i].ct & TCG_CT_REG)) { -/* if (vals[args[i]] < s->nb_globals) - printf("Fuuu\n");*/ - args[i] = vals[args[i]]; + if (temps[args[i]].state == TCG_TEMP_COPY) { + args[i] = temps[args[i]].val; } } } - /* Propagate constants through copy operations and do constant - folding. Constants will be substituted to arguments by register - allocator where needed and possible. Also detect copies. */ - switch(op) { - case INDEX_op_mov_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_mov_i64: -#endif - if ((state[args[1]] == TCG_TEMP_COPY - && vals[args[1]] == args[0]) + /* For commutative operations make constant second argument */ + switch (op) { + CASE_OP_32_64(add): + CASE_OP_32_64(mul): + CASE_OP_32_64(and): + CASE_OP_32_64(or): + CASE_OP_32_64(xor): + CASE_OP_32_64(eqv): + CASE_OP_32_64(nand): + CASE_OP_32_64(nor): + if (temps[args[1]].state == TCG_TEMP_CONST) { + tmp = args[1]; + args[1] = args[2]; + args[2] = tmp; + } + break; + default: + break; + } + + /* Simplify expression if possible. */ + switch (op) { + CASE_OP_32_64(add): + CASE_OP_32_64(sub): + CASE_OP_32_64(shl): + CASE_OP_32_64(shr): + CASE_OP_32_64(sar): + CASE_OP_32_64(rotl): + CASE_OP_32_64(rotr): + if (temps[args[1]].state == TCG_TEMP_CONST) { + /* Proceed with possible constant folding. */ + break; + } + if (temps[args[2]].state == TCG_TEMP_CONST + && temps[args[2]].val == 0) { + if ((temps[args[0]].state == TCG_TEMP_COPY + && temps[args[0]].val == args[1]) || args[0] == args[1]) { - args += 2; + args += 3; gen_opc_buf[op_index] = INDEX_op_nop; - break; - } - if (state[args[1]] != TCG_TEMP_CONST) { - reset_temp(state, vals, args[0], nb_temps, nb_globals); - if (args[1] >= s->nb_globals) { - state[args[0]] = TCG_TEMP_COPY; - vals[args[0]] = args[1]; - } - gen_args[0] = args[0]; - gen_args[1] = args[1]; + } else { + gen_opc_buf[op_index] = op_to_mov(op); + tcg_opt_gen_mov(s, gen_args, args[0], args[1], + nb_temps, nb_globals); gen_args += 2; - args += 2; - break; + args += 3; + } + continue; + } + break; + CASE_OP_32_64(mul): + if ((temps[args[2]].state == TCG_TEMP_CONST + && temps[args[2]].val == 0)) { + gen_opc_buf[op_index] = op_to_movi(op); + tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals); + args += 3; + gen_args += 2; + continue; + } + break; + CASE_OP_32_64(or): + CASE_OP_32_64(and): + if (args[1] == args[2]) { + if (args[1] == args[0]) { + args += 3; + gen_opc_buf[op_index] = INDEX_op_nop; } else { - /* Source argument is constant. Rewrite the operation and - let movi case handle it. */ - op = op_to_opi(op); - gen_opc_buf[op_index] = op; - args[1] = vals[args[1]]; - /* fallthrough */ + gen_opc_buf[op_index] = op_to_mov(op); + tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps, + nb_globals); + gen_args += 2; + args += 3; } - case INDEX_op_movi_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_movi_i64: -#endif - reset_temp(state, vals, args[0], nb_temps, nb_globals); - state[args[0]] = TCG_TEMP_CONST; - vals[args[0]] = args[1]; + continue; + } + break; + default: + break; + } + + /* Propagate constants through copy operations and do constant + folding. Constants will be substituted to arguments by register + allocator where needed and possible. Also detect copies. */ + switch (op) { + CASE_OP_32_64(mov): + if ((temps[args[1]].state == TCG_TEMP_COPY + && temps[args[1]].val == args[0]) + || args[0] == args[1]) { + args += 2; + gen_opc_buf[op_index] = INDEX_op_nop; + break; + } + if (temps[args[1]].state != TCG_TEMP_CONST) { + tcg_opt_gen_mov(s, gen_args, args[0], args[1], + nb_temps, nb_globals); + gen_args += 2; + args += 2; + break; + } + /* Source argument is constant. Rewrite the operation and + let movi case handle it. */ + op = op_to_movi(op); + gen_opc_buf[op_index] = op; + args[1] = temps[args[1]].val; + /* fallthrough */ + CASE_OP_32_64(movi): + tcg_opt_gen_movi(gen_args, args[0], args[1], nb_temps, nb_globals); + gen_args += 2; + args += 2; + break; + CASE_OP_32_64(not): + CASE_OP_32_64(neg): + CASE_OP_32_64(ext8s): + CASE_OP_32_64(ext8u): + CASE_OP_32_64(ext16s): + CASE_OP_32_64(ext16u): + case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: + if (temps[args[1]].state == TCG_TEMP_CONST) { + gen_opc_buf[op_index] = op_to_movi(op); + tmp = do_constant_folding(op, temps[args[1]].val, 0); + tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals); + gen_args += 2; + args += 2; + break; + } else { + reset_temp(args[0], nb_temps, nb_globals); gen_args[0] = args[0]; gen_args[1] = args[1]; gen_args += 2; args += 2; break; - case INDEX_op_or_i32: - case INDEX_op_and_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_and_i64: - case INDEX_op_or_i64: -#endif - if (args[1] == args[2]) { - if (args[1] == args[0]) { - args += 3; - gen_opc_buf[op_index] = INDEX_op_nop; - } else { - reset_temp(state, vals, args[0], nb_temps, nb_globals); - if (args[1] >= s->nb_globals) { - state[args[0]] = TCG_TEMP_COPY; - vals[args[0]] = args[1]; - } - gen_opc_buf[op_index] = mov_opc[op_bits(op) / 32 - 1]; - gen_args[0] = args[0]; - gen_args[1] = args[1]; - gen_args += 2; - args += 3; - } - break; - } - /* Proceede with default binary operation handling */ - case INDEX_op_add_i32: - case INDEX_op_sub_i32: - case INDEX_op_xor_i32: - case INDEX_op_mul_i32: - case INDEX_op_shl_i32: - case INDEX_op_shr_i32: - case INDEX_op_sar_i32: - case INDEX_op_rotl_i32: - case INDEX_op_rotr_i32: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_add_i64: - case INDEX_op_sub_i64: - case INDEX_op_xor_i64: - case INDEX_op_mul_i64: - case INDEX_op_shl_i64: - case INDEX_op_shr_i64: - case INDEX_op_sar_i64: - case INDEX_op_rotl_i64: - case INDEX_op_rotr_i64: -#endif - if (state[args[1]] == TCG_TEMP_CONST - && state[args[2]] == TCG_TEMP_CONST) - { - gen_opc_buf[op_index] = op_to_movi(op); - gen_args[0] = args[0]; - gen_args[1] = do_constant_folding(op, vals[args[1]], vals[args[2]]); - reset_temp(state, vals, gen_args[0], nb_temps, nb_globals); - state[gen_args[0]] = TCG_TEMP_CONST; - vals[gen_args[0]] = gen_args[1]; - gen_args += 2; - args += 3; - break; - } else { - reset_temp(state, vals, args[0], nb_temps, nb_globals); - gen_args[0] = args[0]; - gen_args[1] = args[1]; - gen_args[2] = args[2]; - gen_args += 3; - args += 3; - break; - } - case INDEX_op_call: - case INDEX_op_jmp: - case INDEX_op_br: - case INDEX_op_brcond_i32: - case INDEX_op_set_label: -#if TCG_TARGET_REG_BITS == 64 - case INDEX_op_brcond_i64: -#endif - memset(state, 0, nb_temps * sizeof(tcg_temp_state)); - i = (op == INDEX_op_call) ? - (args[0] >> 16) + (args[0] & 0xffff) + 3 : - def->nb_args; - while (i) { - *gen_args = *args; - args++; - gen_args++; - i--; - } + } + CASE_OP_32_64(add): + CASE_OP_32_64(sub): + CASE_OP_32_64(mul): + CASE_OP_32_64(or): + CASE_OP_32_64(and): + CASE_OP_32_64(xor): + CASE_OP_32_64(shl): + CASE_OP_32_64(shr): + CASE_OP_32_64(sar): + CASE_OP_32_64(rotl): + CASE_OP_32_64(rotr): + CASE_OP_32_64(andc): + CASE_OP_32_64(orc): + CASE_OP_32_64(eqv): + CASE_OP_32_64(nand): + CASE_OP_32_64(nor): + if (temps[args[1]].state == TCG_TEMP_CONST + && temps[args[2]].state == TCG_TEMP_CONST) { + gen_opc_buf[op_index] = op_to_movi(op); + tmp = do_constant_folding(op, temps[args[1]].val, + temps[args[2]].val); + tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals); + gen_args += 2; + args += 3; break; - default: - /* Default case: we do know nothing about operation so no - propagation is done. We only trash output args. */ - for (i = 0; i < def->nb_oargs; i++) { - reset_temp(state, vals, args[i], nb_temps, nb_globals); - } - for (i = 0; i < def->nb_args; i++) { - gen_args[i] = args[i]; - } - args += def->nb_args; - gen_args += def->nb_args; + } else { + reset_temp(args[0], nb_temps, nb_globals); + gen_args[0] = args[0]; + gen_args[1] = args[1]; + gen_args[2] = args[2]; + gen_args += 3; + args += 3; break; + } + case INDEX_op_call: + nb_call_args = (args[0] >> 16) + (args[0] & 0xffff); + if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) { + for (i = 0; i < nb_globals; i++) { + reset_temp(i, nb_temps, nb_globals); + } + } + for (i = 0; i < (args[0] >> 16); i++) { + reset_temp(args[i + 1], nb_temps, nb_globals); + } + i = nb_call_args + 3; + while (i) { + *gen_args = *args; + args++; + gen_args++; + i--; + } + break; + case INDEX_op_set_label: + case INDEX_op_jmp: + case INDEX_op_br: + CASE_OP_32_64(brcond): + memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); + for (i = 0; i < def->nb_args; i++) { + *gen_args = *args; + args++; + gen_args++; + } + break; + default: + /* Default case: we do know nothing about operation so no + propagation is done. We only trash output args. */ + for (i = 0; i < def->nb_oargs; i++) { + reset_temp(args[i], nb_temps, nb_globals); + } + for (i = 0; i < def->nb_args; i++) { + gen_args[i] = args[i]; + } + args += def->nb_args; + gen_args += def->nb_args; + break; } } - if (vals) - free(vals); - if (state) - free(state); - return gen_args; } diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 7970268..f5d9bf3 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -160,8 +160,7 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, - /* TCG_REG_R27, */ /* currently used for the global env, so no - need to save */ + TCG_REG_R27, /* currently used for the global env */ TCG_REG_R28, TCG_REG_R29, TCG_REG_R30, @@ -437,13 +436,13 @@ static const uint32_t tcg_to_bc[10] = { [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE, }; -static void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) +static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { tcg_out32 (s, OR | SAB (arg, ret, arg)); } static void tcg_out_movi(TCGContext *s, TCGType type, - int ret, tcg_target_long arg) + TCGReg ret, tcg_target_long arg) { if (arg == (int16_t) arg) tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff)); @@ -526,14 +525,14 @@ static void *qemu_st_helpers[4] = { static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) { - int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap; + int addr_reg, data_reg, data_reg2, r0, r1, rbase, bswap; #ifdef CONFIG_SOFTMMU - int r2; + int mem_index, s_bits, r2; void *label1_ptr, *label2_ptr; -#endif #if TARGET_LONG_BITS == 64 int addr_reg2; #endif +#endif data_reg = *args++; if (opc == 3) @@ -541,13 +540,13 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) else data_reg2 = 0; addr_reg = *args++; + +#ifdef CONFIG_SOFTMMU #if TARGET_LONG_BITS == 64 addr_reg2 = *args++; #endif mem_index = *args; s_bits = opc & 3; - -#ifdef CONFIG_SOFTMMU r0 = 3; r1 = 4; r2 = 0; @@ -723,14 +722,14 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) { - int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase; + int addr_reg, r0, r1, data_reg, data_reg2, bswap, rbase; #ifdef CONFIG_SOFTMMU - int r2, ir; + int mem_index, r2, ir; void *label1_ptr, *label2_ptr; -#endif #if TARGET_LONG_BITS == 64 int addr_reg2; #endif +#endif data_reg = *args++; if (opc == 3) @@ -738,12 +737,12 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) else data_reg2 = 0; addr_reg = *args++; + +#ifdef CONFIG_SOFTMMU #if TARGET_LONG_BITS == 64 addr_reg2 = *args++; #endif mem_index = *args; - -#ifdef CONFIG_SOFTMMU r0 = 3; r1 = 4; r2 = 0; @@ -908,9 +907,14 @@ static void tcg_target_qemu_prologue (TCGContext *s) + LINKAGE_AREA_SIZE + TCG_STATIC_CALL_ARGS_SIZE + ARRAY_SIZE (tcg_target_callee_save_regs) * 4 + + CPU_TEMP_BUF_NLONGS * sizeof(long) ; frame_size = (frame_size + 15) & ~15; + tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size + - CPU_TEMP_BUF_NLONGS * sizeof(long), + CPU_TEMP_BUF_NLONGS * sizeof(long)); + #ifdef _CALL_AIX { uint32_t addr; @@ -939,7 +943,8 @@ static void tcg_target_qemu_prologue (TCGContext *s) } #endif - tcg_out32 (s, MTSPR | RS (3) | CTR); + tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR); tcg_out32 (s, BCCTR | BO_ALWAYS); tb_ret_addr = s->code_ptr; @@ -956,13 +961,13 @@ static void tcg_target_qemu_prologue (TCGContext *s) tcg_out32 (s, BCLR | BO_ALWAYS); } -static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, +static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, tcg_target_long arg2) { tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX); } -static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1, +static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, tcg_target_long arg2) { tcg_out_ldst (s, arg, arg1, arg2, STW, STWX); @@ -982,11 +987,6 @@ static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si) } } -static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) -{ - ppc_addi (s, reg, reg, val); -} - static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, int const_arg2, int cr) { @@ -1790,6 +1790,16 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, } break; + case INDEX_op_deposit_i32: + tcg_out32 (s, RLWIMI + | RA (args[0]) + | RS (args[2]) + | SH (args[3]) + | MB (32 - args[3] - args[4]) + | ME (31 - args[3]) + ); + break; + default: tcg_dump_ops (s, stderr); tcg_abort (); @@ -1885,6 +1895,8 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_ext16s_i32, { "r", "r" } }, { INDEX_op_ext16u_i32, { "r", "r" } }, + { INDEX_op_deposit_i32, { "r", "0", "r" } }, + { -1 }, }; diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index a1f8599..3f22aaa 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -23,11 +23,10 @@ */ #define TCG_TARGET_PPC 1 -#define TCG_TARGET_REG_BITS 32 #define TCG_TARGET_WORDS_BIGENDIAN #define TCG_TARGET_NB_REGS 32 -enum { +typedef enum { TCG_REG_R0 = 0, TCG_REG_R1, TCG_REG_R2, @@ -60,7 +59,7 @@ enum { TCG_REG_R29, TCG_REG_R30, TCG_REG_R31 -}; +} TCGReg; /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_R1 @@ -77,22 +76,27 @@ enum { #endif /* optional instructions */ -#define TCG_TARGET_HAS_div_i32 -#define TCG_TARGET_HAS_rot_i32 -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -#define TCG_TARGET_HAS_ext8u_i32 -#define TCG_TARGET_HAS_ext16u_i32 -#define TCG_TARGET_HAS_bswap16_i32 -#define TCG_TARGET_HAS_bswap32_i32 -#define TCG_TARGET_HAS_not_i32 -#define TCG_TARGET_HAS_neg_i32 -#define TCG_TARGET_HAS_andc_i32 -#define TCG_TARGET_HAS_orc_i32 -#define TCG_TARGET_HAS_eqv_i32 -#define TCG_TARGET_HAS_nand_i32 -#define TCG_TARGET_HAS_nor_i32 +#define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rot_i32 1 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_ext8u_i32 1 +#define TCG_TARGET_HAS_ext16u_i32 1 +#define TCG_TARGET_HAS_bswap16_i32 1 +#define TCG_TARGET_HAS_bswap32_i32 1 +#define TCG_TARGET_HAS_not_i32 1 +#define TCG_TARGET_HAS_neg_i32 1 +#define TCG_TARGET_HAS_andc_i32 1 +#define TCG_TARGET_HAS_orc_i32 1 +#define TCG_TARGET_HAS_eqv_i32 1 +#define TCG_TARGET_HAS_nand_i32 1 +#define TCG_TARGET_HAS_nor_i32 1 +#define TCG_TARGET_HAS_deposit_i32 1 #define TCG_AREG0 TCG_REG_R27 #define TCG_TARGET_HAS_GUEST_BASE + +#define tcg_qemu_tb_exec(env, tb_ptr) \ + ((long REGPARM __attribute__ ((longcall)) \ + (*)(void *, void *))code_gen_prologue)(env, tb_ptr) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index ebbee34..4419378 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -130,7 +130,7 @@ static const int tcg_target_call_iarg_regs[] = { TCG_REG_R10 }; -static const int tcg_target_call_oarg_regs[2] = { +static const int tcg_target_call_oarg_regs[] = { TCG_REG_R3 }; @@ -151,8 +151,7 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, - /* TCG_REG_R27, */ /* currently used for the global env, so no - need to save */ + TCG_REG_R27, /* currently used for the global env */ TCG_REG_R28, TCG_REG_R29, TCG_REG_R30, @@ -356,6 +355,7 @@ static int tcg_target_const_match (tcg_target_long val, #define SRAWI XO31(824) #define NEG XO31(104) #define MFCR XO31( 19) +#define NOR XO31(124) #define CNTLZW XO31( 26) #define CNTLZD XO31( 58) @@ -435,7 +435,7 @@ static const uint32_t tcg_to_bc[10] = { [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE, }; -static void tcg_out_mov (TCGContext *s, TCGType type, int ret, int arg) +static void tcg_out_mov (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { tcg_out32 (s, OR | SAB (arg, ret, arg)); } @@ -459,7 +459,7 @@ static void tcg_out_movi32 (TCGContext *s, int ret, int32_t arg) } static void tcg_out_movi (TCGContext *s, TCGType type, - int ret, tcg_target_long arg) + TCGReg ret, tcg_target_long arg) { int32_t arg32 = arg; arg = type == TCG_TYPE_I32 ? arg & 0xffffffff : arg; @@ -616,18 +616,19 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2, static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) { - int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap; + int addr_reg, data_reg, r0, r1, rbase, bswap; #ifdef CONFIG_SOFTMMU - int r2; + int r2, mem_index, s_bits; void *label1_ptr, *label2_ptr; #endif data_reg = *args++; addr_reg = *args++; + +#ifdef CONFIG_SOFTMMU mem_index = *args; s_bits = opc & 3; -#ifdef CONFIG_SOFTMMU r0 = 3; r1 = 4; r2 = 0; @@ -763,17 +764,18 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) { - int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap; + int addr_reg, r0, r1, rbase, data_reg, bswap; #ifdef CONFIG_SOFTMMU - int r2; + int r2, mem_index; void *label1_ptr, *label2_ptr; #endif data_reg = *args++; addr_reg = *args++; - mem_index = *args; #ifdef CONFIG_SOFTMMU + mem_index = *args; + r0 = 3; r1 = 4; r2 = 0; @@ -876,9 +878,14 @@ static void tcg_target_qemu_prologue (TCGContext *s) + 8 /* TOC save area */ + TCG_STATIC_CALL_ARGS_SIZE + ARRAY_SIZE (tcg_target_callee_save_regs) * 8 + + CPU_TEMP_BUF_NLONGS * sizeof(long) ; frame_size = (frame_size + 15) & ~15; + tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size + - CPU_TEMP_BUF_NLONGS * sizeof(long), + CPU_TEMP_BUF_NLONGS * sizeof(long)); + #ifndef __APPLE__ /* First emit adhoc function descriptor */ addr = (uint64_t) s->code_ptr + 24; @@ -905,7 +912,8 @@ static void tcg_target_qemu_prologue (TCGContext *s) } #endif - tcg_out32 (s, MTSPR | RS (3) | CTR); + tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR); tcg_out32 (s, BCCTR | BO_ALWAYS); /* Epilogue */ @@ -924,7 +932,7 @@ static void tcg_target_qemu_prologue (TCGContext *s) tcg_out32 (s, BCLR | BO_ALWAYS); } -static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, +static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, tcg_target_long arg2) { if (type == TCG_TYPE_I32) @@ -933,7 +941,7 @@ static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX); } -static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1, +static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, tcg_target_long arg2) { if (type == TCG_TYPE_I32) @@ -968,11 +976,6 @@ static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si) } } -static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val) -{ - ppc_addi64 (s, reg, reg, val); -} - static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, int const_arg2, int cr, int arch64) { @@ -1449,6 +1452,11 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, tcg_out32 (s, NEG | RT (args[0]) | RA (args[1])); break; + case INDEX_op_not_i32: + case INDEX_op_not_i64: + tcg_out32 (s, NOR | SAB (args[1], args[0], args[1])); + break; + case INDEX_op_add_i64: if (const_args[2]) ppc_addi64 (s, args[0], args[1], args[2]); @@ -1553,6 +1561,10 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, tcg_out32 (s, c | RS (args[1]) | RA (args[0])); break; + case INDEX_op_ext32u_i64: + tcg_out_rld (s, RLDICL, args[0], args[1], 0, 32); + break; + case INDEX_op_setcond_i32: tcg_out_setcond (s, TCG_TYPE_I32, args[3], args[0], args[1], args[2], const_args[2]); @@ -1621,6 +1633,7 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_brcond_i64, { "r", "ri" } }, { INDEX_op_neg_i32, { "r", "r" } }, + { INDEX_op_not_i32, { "r", "r" } }, { INDEX_op_add_i64, { "r", "r", "ri" } }, { INDEX_op_sub_i64, { "r", "r", "ri" } }, @@ -1639,6 +1652,7 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_remu_i64, { "r", "r", "r" } }, { INDEX_op_neg_i64, { "r", "r" } }, + { INDEX_op_not_i64, { "r", "r" } }, { INDEX_op_qemu_ld8u, { "r", "L" } }, { INDEX_op_qemu_ld8s, { "r", "L" } }, @@ -1659,6 +1673,7 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_ext8s_i64, { "r", "r" } }, { INDEX_op_ext16s_i64, { "r", "r" } }, { INDEX_op_ext32s_i64, { "r", "r" } }, + { INDEX_op_ext32u_i64, { "r", "r" } }, { INDEX_op_setcond_i32, { "r", "r", "ri" } }, { INDEX_op_setcond_i64, { "r", "r", "ri" } }, diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h index 8a6db11..97eec08 100644 --- a/tcg/ppc64/tcg-target.h +++ b/tcg/ppc64/tcg-target.h @@ -23,11 +23,10 @@ */ #define TCG_TARGET_PPC64 1 -#define TCG_TARGET_REG_BITS 64 #define TCG_TARGET_WORDS_BIGENDIAN #define TCG_TARGET_NB_REGS 32 -enum { +typedef enum { TCG_REG_R0 = 0, TCG_REG_R1, TCG_REG_R2, @@ -60,7 +59,7 @@ enum { TCG_REG_R29, TCG_REG_R30, TCG_REG_R31 -}; +} TCGReg; /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_R1 @@ -68,40 +67,42 @@ enum { #define TCG_TARGET_CALL_STACK_OFFSET 48 /* optional instructions */ -#define TCG_TARGET_HAS_div_i32 -/* #define TCG_TARGET_HAS_rot_i32 */ -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -/* #define TCG_TARGET_HAS_ext8u_i32 */ -/* #define TCG_TARGET_HAS_ext16u_i32 */ -/* #define TCG_TARGET_HAS_bswap16_i32 */ -/* #define TCG_TARGET_HAS_bswap32_i32 */ -/* #define TCG_TARGET_HAS_not_i32 */ -#define TCG_TARGET_HAS_neg_i32 -/* #define TCG_TARGET_HAS_andc_i32 */ -/* #define TCG_TARGET_HAS_orc_i32 */ -/* #define TCG_TARGET_HAS_eqv_i32 */ -/* #define TCG_TARGET_HAS_nand_i32 */ -/* #define TCG_TARGET_HAS_nor_i32 */ +#define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rot_i32 0 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_ext8u_i32 0 +#define TCG_TARGET_HAS_ext16u_i32 0 +#define TCG_TARGET_HAS_bswap16_i32 0 +#define TCG_TARGET_HAS_bswap32_i32 0 +#define TCG_TARGET_HAS_not_i32 1 +#define TCG_TARGET_HAS_neg_i32 1 +#define TCG_TARGET_HAS_andc_i32 0 +#define TCG_TARGET_HAS_orc_i32 0 +#define TCG_TARGET_HAS_eqv_i32 0 +#define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_nor_i32 0 +#define TCG_TARGET_HAS_deposit_i32 0 -#define TCG_TARGET_HAS_div_i64 -/* #define TCG_TARGET_HAS_rot_i64 */ -#define TCG_TARGET_HAS_ext8s_i64 -#define TCG_TARGET_HAS_ext16s_i64 -#define TCG_TARGET_HAS_ext32s_i64 -/* #define TCG_TARGET_HAS_ext8u_i64 */ -/* #define TCG_TARGET_HAS_ext16u_i64 */ -/* #define TCG_TARGET_HAS_ext32u_i64 */ -/* #define TCG_TARGET_HAS_bswap16_i64 */ -/* #define TCG_TARGET_HAS_bswap32_i64 */ -/* #define TCG_TARGET_HAS_bswap64_i64 */ -/* #define TCG_TARGET_HAS_not_i64 */ -#define TCG_TARGET_HAS_neg_i64 -/* #define TCG_TARGET_HAS_andc_i64 */ -/* #define TCG_TARGET_HAS_orc_i64 */ -/* #define TCG_TARGET_HAS_eqv_i64 */ -/* #define TCG_TARGET_HAS_nand_i64 */ -/* #define TCG_TARGET_HAS_nor_i64 */ +#define TCG_TARGET_HAS_div_i64 1 +#define TCG_TARGET_HAS_rot_i64 0 +#define TCG_TARGET_HAS_ext8s_i64 1 +#define TCG_TARGET_HAS_ext16s_i64 1 +#define TCG_TARGET_HAS_ext32s_i64 1 +#define TCG_TARGET_HAS_ext8u_i64 0 +#define TCG_TARGET_HAS_ext16u_i64 0 +#define TCG_TARGET_HAS_ext32u_i64 1 +#define TCG_TARGET_HAS_bswap16_i64 0 +#define TCG_TARGET_HAS_bswap32_i64 0 +#define TCG_TARGET_HAS_bswap64_i64 0 +#define TCG_TARGET_HAS_not_i64 1 +#define TCG_TARGET_HAS_neg_i64 1 +#define TCG_TARGET_HAS_andc_i64 0 +#define TCG_TARGET_HAS_orc_i64 0 +#define TCG_TARGET_HAS_eqv_i64 0 +#define TCG_TARGET_HAS_nand_i64 0 +#define TCG_TARGET_HAS_nor_i64 0 +#define TCG_TARGET_HAS_deposit_i64 0 #define TCG_AREG0 TCG_REG_R27 diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 450fcab..9317fe8 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -252,7 +252,9 @@ static const int tcg_target_call_iarg_regs[] = { static const int tcg_target_call_oarg_regs[] = { TCG_REG_R2, - TCG_REG_R3, +#if TCG_TARGET_REG_BITS == 32 + TCG_REG_R3 +#endif }; #define S390_CC_EQ 8 @@ -2291,6 +2293,8 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); tcg_add_target_add_op_defs(s390_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } static void tcg_target_qemu_prologue(TCGContext *s) @@ -2306,8 +2310,9 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); } - /* br %r2 (go to TB) */ - tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* br %r3 (go to TB) */ + tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]); tb_ret_addr = s->code_ptr; @@ -2317,8 +2322,3 @@ static void tcg_target_qemu_prologue(TCGContext *s) /* br %r14 (return) */ tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14); } - -static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) -{ - tcg_abort(); -} diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index 4e45cf3..e4cd641 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -23,12 +23,6 @@ */ #define TCG_TARGET_S390 1 -#ifdef __s390x__ -#define TCG_TARGET_REG_BITS 64 -#else -#define TCG_TARGET_REG_BITS 32 -#endif - #define TCG_TARGET_WORDS_BIGENDIAN typedef enum TCGReg { @@ -53,41 +47,43 @@ typedef enum TCGReg { #define TCG_TARGET_NB_REGS 16 /* optional instructions */ -#define TCG_TARGET_HAS_div2_i32 -#define TCG_TARGET_HAS_rot_i32 -#define TCG_TARGET_HAS_ext8s_i32 -#define TCG_TARGET_HAS_ext16s_i32 -#define TCG_TARGET_HAS_ext8u_i32 -#define TCG_TARGET_HAS_ext16u_i32 -#define TCG_TARGET_HAS_bswap16_i32 -#define TCG_TARGET_HAS_bswap32_i32 -// #define TCG_TARGET_HAS_not_i32 -#define TCG_TARGET_HAS_neg_i32 -// #define TCG_TARGET_HAS_andc_i32 -// #define TCG_TARGET_HAS_orc_i32 -// #define TCG_TARGET_HAS_eqv_i32 -// #define TCG_TARGET_HAS_nand_i32 -// #define TCG_TARGET_HAS_nor_i32 +#define TCG_TARGET_HAS_div2_i32 1 +#define TCG_TARGET_HAS_rot_i32 1 +#define TCG_TARGET_HAS_ext8s_i32 1 +#define TCG_TARGET_HAS_ext16s_i32 1 +#define TCG_TARGET_HAS_ext8u_i32 1 +#define TCG_TARGET_HAS_ext16u_i32 1 +#define TCG_TARGET_HAS_bswap16_i32 1 +#define TCG_TARGET_HAS_bswap32_i32 1 +#define TCG_TARGET_HAS_not_i32 0 +#define TCG_TARGET_HAS_neg_i32 1 +#define TCG_TARGET_HAS_andc_i32 0 +#define TCG_TARGET_HAS_orc_i32 0 +#define TCG_TARGET_HAS_eqv_i32 0 +#define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_nor_i32 0 +#define TCG_TARGET_HAS_deposit_i32 0 #if TCG_TARGET_REG_BITS == 64 -#define TCG_TARGET_HAS_div2_i64 -#define TCG_TARGET_HAS_rot_i64 -#define TCG_TARGET_HAS_ext8s_i64 -#define TCG_TARGET_HAS_ext16s_i64 -#define TCG_TARGET_HAS_ext32s_i64 -#define TCG_TARGET_HAS_ext8u_i64 -#define TCG_TARGET_HAS_ext16u_i64 -#define TCG_TARGET_HAS_ext32u_i64 -#define TCG_TARGET_HAS_bswap16_i64 -#define TCG_TARGET_HAS_bswap32_i64 -#define TCG_TARGET_HAS_bswap64_i64 -// #define TCG_TARGET_HAS_not_i64 -#define TCG_TARGET_HAS_neg_i64 -// #define TCG_TARGET_HAS_andc_i64 -// #define TCG_TARGET_HAS_orc_i64 -// #define TCG_TARGET_HAS_eqv_i64 -// #define TCG_TARGET_HAS_nand_i64 -// #define TCG_TARGET_HAS_nor_i64 +#define TCG_TARGET_HAS_div2_i64 1 +#define TCG_TARGET_HAS_rot_i64 1 +#define TCG_TARGET_HAS_ext8s_i64 1 +#define TCG_TARGET_HAS_ext16s_i64 1 +#define TCG_TARGET_HAS_ext32s_i64 1 +#define TCG_TARGET_HAS_ext8u_i64 1 +#define TCG_TARGET_HAS_ext16u_i64 1 +#define TCG_TARGET_HAS_ext32u_i64 1 +#define TCG_TARGET_HAS_bswap16_i64 1 +#define TCG_TARGET_HAS_bswap32_i64 1 +#define TCG_TARGET_HAS_bswap64_i64 1 +#define TCG_TARGET_HAS_not_i64 0 +#define TCG_TARGET_HAS_neg_i64 1 +#define TCG_TARGET_HAS_andc_i64 0 +#define TCG_TARGET_HAS_orc_i64 0 +#define TCG_TARGET_HAS_eqv_i64 0 +#define TCG_TARGET_HAS_nand_i64 0 +#define TCG_TARGET_HAS_nor_i64 0 +#define TCG_TARGET_HAS_deposit_i64 0 #endif #define TCG_TARGET_HAS_GUEST_BASE diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 5f1353a..5cd5a3b 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -84,9 +84,11 @@ static const int tcg_target_call_iarg_regs[6] = { TCG_REG_O5, }; -static const int tcg_target_call_oarg_regs[2] = { +static const int tcg_target_call_oarg_regs[] = { TCG_REG_O0, - TCG_REG_O1, +#if TCG_TARGET_REG_BITS == 32 + TCG_REG_O1 +#endif }; static inline int check_fit_tl(tcg_target_long val, unsigned int bits) @@ -304,7 +306,8 @@ static void tcg_out_arithc(TCGContext *s, int rd, int rs1, | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2))); } -static inline void tcg_out_mov(TCGContext *s, TCGType type, int ret, int arg) +static inline void tcg_out_mov(TCGContext *s, TCGType type, + TCGReg ret, TCGReg arg) { tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR); } @@ -331,7 +334,7 @@ static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg) } static inline void tcg_out_movi(TCGContext *s, TCGType type, - int ret, tcg_target_long arg) + TCGReg ret, tcg_target_long arg) { /* All 32-bit constants, as well as 64-bit constants with no high bits set go through movi_imm32. */ @@ -396,8 +399,8 @@ static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr, INSN_ASI(asi) | INSN_RS2(addr)); } -static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret, - int arg1, tcg_target_long arg2) +static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, + TCGReg arg1, tcg_target_long arg2) { if (type == TCG_TYPE_I32) tcg_out_ldst(s, ret, arg1, arg2, LDUW); @@ -405,8 +408,8 @@ static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret, tcg_out_ldst(s, ret, arg1, arg2, LDX); } -static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, - int arg1, tcg_target_long arg2) +static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, + TCGReg arg1, tcg_target_long arg2) { if (type == TCG_TYPE_I32) tcg_out_ldst(s, arg, arg1, arg2, STW); @@ -470,11 +473,9 @@ static inline void tcg_out_nop(TCGContext *s) static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index) { - int32_t val; TCGLabel *l = &s->labels[label_index]; if (l->has_value) { - val = l->u.value - (tcg_target_long)s->code_ptr; tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr))); } else { @@ -486,11 +487,9 @@ static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index) #if TCG_TARGET_REG_BITS == 64 static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index) { - int32_t val; TCGLabel *l = &s->labels[label_index]; if (l->has_value) { - val = l->u.value - (tcg_target_long)s->code_ptr; tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) | (0x5 << 19) | INSN_OFF19(l->u.value - (unsigned long)s->code_ptr))); @@ -693,11 +692,14 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret, /* Generate global QEMU prologue and epilogue code */ static void tcg_target_qemu_prologue(TCGContext *s) { + tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET, + CPU_TEMP_BUF_NLONGS * (int)sizeof(long)); tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) | - INSN_IMM13(-TCG_TARGET_STACK_MINFRAME)); - tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) | + INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME + + CPU_TEMP_BUF_NLONGS * (int)sizeof(long)))); + tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) | INSN_RS2(TCG_REG_G0)); - tcg_out_nop(s); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0); } #if defined(CONFIG_SOFTMMU) diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index df0785e..c3fe131 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -23,17 +23,11 @@ */ #define TCG_TARGET_SPARC 1 -#if defined(__sparc_v9__) && !defined(__sparc_v8plus__) -#define TCG_TARGET_REG_BITS 64 -#else -#define TCG_TARGET_REG_BITS 32 -#endif - #define TCG_TARGET_WORDS_BIGENDIAN #define TCG_TARGET_NB_REGS 32 -enum { +typedef enum { TCG_REG_G0 = 0, TCG_REG_G1, TCG_REG_G2, @@ -66,7 +60,7 @@ enum { TCG_REG_I5, TCG_REG_I6, TCG_REG_I7, -}; +} TCGReg; #define TCG_CT_CONST_S11 0x100 #define TCG_CT_CONST_S13 0x200 @@ -92,41 +86,43 @@ enum { #endif /* optional instructions */ -#define TCG_TARGET_HAS_div_i32 -// #define TCG_TARGET_HAS_rot_i32 -// #define TCG_TARGET_HAS_ext8s_i32 -// #define TCG_TARGET_HAS_ext16s_i32 -// #define TCG_TARGET_HAS_ext8u_i32 -// #define TCG_TARGET_HAS_ext16u_i32 -// #define TCG_TARGET_HAS_bswap16_i32 -// #define TCG_TARGET_HAS_bswap32_i32 -#define TCG_TARGET_HAS_neg_i32 -#define TCG_TARGET_HAS_not_i32 -#define TCG_TARGET_HAS_andc_i32 -#define TCG_TARGET_HAS_orc_i32 -// #define TCG_TARGET_HAS_eqv_i32 -// #define TCG_TARGET_HAS_nand_i32 -// #define TCG_TARGET_HAS_nor_i32 +#define TCG_TARGET_HAS_div_i32 1 +#define TCG_TARGET_HAS_rot_i32 0 +#define TCG_TARGET_HAS_ext8s_i32 0 +#define TCG_TARGET_HAS_ext16s_i32 0 +#define TCG_TARGET_HAS_ext8u_i32 0 +#define TCG_TARGET_HAS_ext16u_i32 0 +#define TCG_TARGET_HAS_bswap16_i32 0 +#define TCG_TARGET_HAS_bswap32_i32 0 +#define TCG_TARGET_HAS_neg_i32 1 +#define TCG_TARGET_HAS_not_i32 1 +#define TCG_TARGET_HAS_andc_i32 1 +#define TCG_TARGET_HAS_orc_i32 1 +#define TCG_TARGET_HAS_eqv_i32 0 +#define TCG_TARGET_HAS_nand_i32 0 +#define TCG_TARGET_HAS_nor_i32 0 +#define TCG_TARGET_HAS_deposit_i32 0 #if TCG_TARGET_REG_BITS == 64 -#define TCG_TARGET_HAS_div_i64 -// #define TCG_TARGET_HAS_rot_i64 -// #define TCG_TARGET_HAS_ext8s_i64 -// #define TCG_TARGET_HAS_ext16s_i64 -#define TCG_TARGET_HAS_ext32s_i64 -// #define TCG_TARGET_HAS_ext8u_i64 -// #define TCG_TARGET_HAS_ext16u_i64 -#define TCG_TARGET_HAS_ext32u_i64 -// #define TCG_TARGET_HAS_bswap16_i64 -// #define TCG_TARGET_HAS_bswap32_i64 -// #define TCG_TARGET_HAS_bswap64_i64 -#define TCG_TARGET_HAS_neg_i64 -#define TCG_TARGET_HAS_not_i64 -#define TCG_TARGET_HAS_andc_i64 -#define TCG_TARGET_HAS_orc_i64 -// #define TCG_TARGET_HAS_eqv_i64 -// #define TCG_TARGET_HAS_nand_i64 -// #define TCG_TARGET_HAS_nor_i64 +#define TCG_TARGET_HAS_div_i64 1 +#define TCG_TARGET_HAS_rot_i64 0 +#define TCG_TARGET_HAS_ext8s_i64 0 +#define TCG_TARGET_HAS_ext16s_i64 0 +#define TCG_TARGET_HAS_ext32s_i64 1 +#define TCG_TARGET_HAS_ext8u_i64 0 +#define TCG_TARGET_HAS_ext16u_i64 0 +#define TCG_TARGET_HAS_ext32u_i64 1 +#define TCG_TARGET_HAS_bswap16_i64 0 +#define TCG_TARGET_HAS_bswap32_i64 0 +#define TCG_TARGET_HAS_bswap64_i64 0 +#define TCG_TARGET_HAS_neg_i64 1 +#define TCG_TARGET_HAS_not_i64 1 +#define TCG_TARGET_HAS_andc_i64 1 +#define TCG_TARGET_HAS_orc_i64 1 +#define TCG_TARGET_HAS_eqv_i64 0 +#define TCG_TARGET_HAS_nand_i64 0 +#define TCG_TARGET_HAS_nor_i64 0 +#define TCG_TARGET_HAS_deposit_i64 0 #endif /* Note: must be synced with dyngen-exec.h */ diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 2b93b7d..82e04e7 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -664,107 +664,81 @@ static inline void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) tcg_temp_free_i32(t0); } -#ifdef TCG_TARGET_HAS_div_i32 static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { - tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2); -} - -static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2); -} - -static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2); -} - -static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2); -} -#elif defined(TCG_TARGET_HAS_div2_i32) -static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - TCGv_i32 t0; - t0 = tcg_temp_new_i32(); - tcg_gen_sari_i32(t0, arg1, 31); - tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2); - tcg_temp_free_i32(t0); -} - -static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - TCGv_i32 t0; - t0 = tcg_temp_new_i32(); - tcg_gen_sari_i32(t0, arg1, 31); - tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2); - tcg_temp_free_i32(t0); -} - -static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - TCGv_i32 t0; - t0 = tcg_temp_new_i32(); - tcg_gen_movi_i32(t0, 0); - tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2); - tcg_temp_free_i32(t0); -} - -static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - TCGv_i32 t0; - t0 = tcg_temp_new_i32(); - tcg_gen_movi_i32(t0, 0); - tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2); - tcg_temp_free_i32(t0); -} -#else -static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) -{ - int sizemask = 0; - /* Return value and both arguments are 32-bit and signed. */ - sizemask |= tcg_gen_sizemask(0, 0, 1); - sizemask |= tcg_gen_sizemask(1, 0, 1); - sizemask |= tcg_gen_sizemask(2, 0, 1); - - tcg_gen_helper32(tcg_helper_div_i32, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i32) { + tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i32) { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_sari_i32(t0, arg1, 31); + tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2); + tcg_temp_free_i32(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 32-bit and signed. */ + sizemask |= tcg_gen_sizemask(0, 0, 1); + sizemask |= tcg_gen_sizemask(1, 0, 1); + sizemask |= tcg_gen_sizemask(2, 0, 1); + tcg_gen_helper32(tcg_helper_div_i32, sizemask, ret, arg1, arg2); + } } static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { - int sizemask = 0; - /* Return value and both arguments are 32-bit and signed. */ - sizemask |= tcg_gen_sizemask(0, 0, 1); - sizemask |= tcg_gen_sizemask(1, 0, 1); - sizemask |= tcg_gen_sizemask(2, 0, 1); - - tcg_gen_helper32(tcg_helper_rem_i32, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i32) { + tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i32) { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_sari_i32(t0, arg1, 31); + tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2); + tcg_temp_free_i32(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 32-bit and signed. */ + sizemask |= tcg_gen_sizemask(0, 0, 1); + sizemask |= tcg_gen_sizemask(1, 0, 1); + sizemask |= tcg_gen_sizemask(2, 0, 1); + tcg_gen_helper32(tcg_helper_rem_i32, sizemask, ret, arg1, arg2); + } } static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { - int sizemask = 0; - /* Return value and both arguments are 32-bit and unsigned. */ - sizemask |= tcg_gen_sizemask(0, 0, 0); - sizemask |= tcg_gen_sizemask(1, 0, 0); - sizemask |= tcg_gen_sizemask(2, 0, 0); - - tcg_gen_helper32(tcg_helper_divu_i32, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i32) { + tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i32) { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_movi_i32(t0, 0); + tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2); + tcg_temp_free_i32(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 32-bit and unsigned. */ + sizemask |= tcg_gen_sizemask(0, 0, 0); + sizemask |= tcg_gen_sizemask(1, 0, 0); + sizemask |= tcg_gen_sizemask(2, 0, 0); + tcg_gen_helper32(tcg_helper_divu_i32, sizemask, ret, arg1, arg2); + } } static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { - int sizemask = 0; - /* Return value and both arguments are 32-bit and unsigned. */ - sizemask |= tcg_gen_sizemask(0, 0, 0); - sizemask |= tcg_gen_sizemask(1, 0, 0); - sizemask |= tcg_gen_sizemask(2, 0, 0); - - tcg_gen_helper32(tcg_helper_remu_i32, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i32) { + tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i32) { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_movi_i32(t0, 0); + tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2); + tcg_temp_free_i32(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 32-bit and unsigned. */ + sizemask |= tcg_gen_sizemask(0, 0, 0); + sizemask |= tcg_gen_sizemask(1, 0, 0); + sizemask |= tcg_gen_sizemask(2, 0, 0); + tcg_gen_helper32(tcg_helper_remu_i32, sizemask, ret, arg1, arg2); + } } -#endif #if TCG_TARGET_REG_BITS == 32 @@ -1063,66 +1037,66 @@ static inline void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg) tcg_gen_op2i_i64(INDEX_op_movi_i64, ret, arg); } -static inline void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_i64 arg2, +static inline void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset); } -static inline void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_i64 arg2, +static inline void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset); } -static inline void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_i64 arg2, +static inline void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset); } -static inline void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_i64 arg2, +static inline void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset); } -static inline void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_i64 arg2, +static inline void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset); } -static inline void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_i64 arg2, +static inline void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset); } -static inline void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_i64 arg2, tcg_target_long offset) +static inline void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset); } -static inline void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_i64 arg2, +static inline void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset); } -static inline void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_i64 arg2, +static inline void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset); } -static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_i64 arg2, +static inline void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset); } -static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_i64 arg2, tcg_target_long offset) +static inline void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset); } @@ -1250,109 +1224,82 @@ static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2); } -#ifdef TCG_TARGET_HAS_div_i64 -static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2); -} - -static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2); -} - -static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2); -} - -static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2); -} -#elif defined(TCG_TARGET_HAS_div2_i64) -static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - TCGv_i64 t0; - t0 = tcg_temp_new_i64(); - tcg_gen_sari_i64(t0, arg1, 63); - tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); - tcg_temp_free_i64(t0); -} - -static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - TCGv_i64 t0; - t0 = tcg_temp_new_i64(); - tcg_gen_sari_i64(t0, arg1, 63); - tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); - tcg_temp_free_i64(t0); -} - -static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - TCGv_i64 t0; - t0 = tcg_temp_new_i64(); - tcg_gen_movi_i64(t0, 0); - tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2); - tcg_temp_free_i64(t0); -} - -static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) -{ - TCGv_i64 t0; - t0 = tcg_temp_new_i64(); - tcg_gen_movi_i64(t0, 0); - tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2); - tcg_temp_free_i64(t0); -} -#else static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { - int sizemask = 0; - /* Return value and both arguments are 64-bit and signed. */ - sizemask |= tcg_gen_sizemask(0, 1, 1); - sizemask |= tcg_gen_sizemask(1, 1, 1); - sizemask |= tcg_gen_sizemask(2, 1, 1); - - tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i64) { + tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i64) { + TCGv_i64 t0 = tcg_temp_new_i64(); + tcg_gen_sari_i64(t0, arg1, 63); + tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); + tcg_temp_free_i64(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 64-bit and signed. */ + sizemask |= tcg_gen_sizemask(0, 1, 1); + sizemask |= tcg_gen_sizemask(1, 1, 1); + sizemask |= tcg_gen_sizemask(2, 1, 1); + tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2); + } } static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { - int sizemask = 0; - /* Return value and both arguments are 64-bit and signed. */ - sizemask |= tcg_gen_sizemask(0, 1, 1); - sizemask |= tcg_gen_sizemask(1, 1, 1); - sizemask |= tcg_gen_sizemask(2, 1, 1); - - tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i64) { + tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i64) { + TCGv_i64 t0 = tcg_temp_new_i64(); + tcg_gen_sari_i64(t0, arg1, 63); + tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); + tcg_temp_free_i64(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 64-bit and signed. */ + sizemask |= tcg_gen_sizemask(0, 1, 1); + sizemask |= tcg_gen_sizemask(1, 1, 1); + sizemask |= tcg_gen_sizemask(2, 1, 1); + tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2); + } } static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { - int sizemask = 0; - /* Return value and both arguments are 64-bit and unsigned. */ - sizemask |= tcg_gen_sizemask(0, 1, 0); - sizemask |= tcg_gen_sizemask(1, 1, 0); - sizemask |= tcg_gen_sizemask(2, 1, 0); - - tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i64) { + tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i64) { + TCGv_i64 t0 = tcg_temp_new_i64(); + tcg_gen_movi_i64(t0, 0); + tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2); + tcg_temp_free_i64(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 64-bit and unsigned. */ + sizemask |= tcg_gen_sizemask(0, 1, 0); + sizemask |= tcg_gen_sizemask(1, 1, 0); + sizemask |= tcg_gen_sizemask(2, 1, 0); + tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2); + } } static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { - int sizemask = 0; - /* Return value and both arguments are 64-bit and unsigned. */ - sizemask |= tcg_gen_sizemask(0, 1, 0); - sizemask |= tcg_gen_sizemask(1, 1, 0); - sizemask |= tcg_gen_sizemask(2, 1, 0); - - tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2); + if (TCG_TARGET_HAS_div_i64) { + tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2); + } else if (TCG_TARGET_HAS_div2_i64) { + TCGv_i64 t0 = tcg_temp_new_i64(); + tcg_gen_movi_i64(t0, 0); + tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2); + tcg_temp_free_i64(t0); + } else { + int sizemask = 0; + /* Return value and both arguments are 64-bit and unsigned. */ + sizemask |= tcg_gen_sizemask(0, 1, 0); + sizemask |= tcg_gen_sizemask(1, 1, 0); + sizemask |= tcg_gen_sizemask(2, 1, 0); + tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2); + } } -#endif - -#endif +#endif /* TCG_TARGET_REG_BITS == 32 */ static inline void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) { @@ -1413,82 +1360,82 @@ static inline void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) static inline void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_ext8s_i32 - tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg); -#else - tcg_gen_shli_i32(ret, arg, 24); - tcg_gen_sari_i32(ret, ret, 24); -#endif + if (TCG_TARGET_HAS_ext8s_i32) { + tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg); + } else { + tcg_gen_shli_i32(ret, arg, 24); + tcg_gen_sari_i32(ret, ret, 24); + } } static inline void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_ext16s_i32 - tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg); -#else - tcg_gen_shli_i32(ret, arg, 16); - tcg_gen_sari_i32(ret, ret, 16); -#endif + if (TCG_TARGET_HAS_ext16s_i32) { + tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg); + } else { + tcg_gen_shli_i32(ret, arg, 16); + tcg_gen_sari_i32(ret, ret, 16); + } } static inline void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_ext8u_i32 - tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg); -#else - tcg_gen_andi_i32(ret, arg, 0xffu); -#endif + if (TCG_TARGET_HAS_ext8u_i32) { + tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg); + } else { + tcg_gen_andi_i32(ret, arg, 0xffu); + } } static inline void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_ext16u_i32 - tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg); -#else - tcg_gen_andi_i32(ret, arg, 0xffffu); -#endif + if (TCG_TARGET_HAS_ext16u_i32) { + tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg); + } else { + tcg_gen_andi_i32(ret, arg, 0xffffu); + } } /* Note: we assume the two high bytes are set to zero */ static inline void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_bswap16_i32 - tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg); -#else - TCGv_i32 t0 = tcg_temp_new_i32(); - - tcg_gen_ext8u_i32(t0, arg); - tcg_gen_shli_i32(t0, t0, 8); - tcg_gen_shri_i32(ret, arg, 8); - tcg_gen_or_i32(ret, ret, t0); - tcg_temp_free_i32(t0); -#endif + if (TCG_TARGET_HAS_bswap16_i32) { + tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg); + } else { + TCGv_i32 t0 = tcg_temp_new_i32(); + + tcg_gen_ext8u_i32(t0, arg); + tcg_gen_shli_i32(t0, t0, 8); + tcg_gen_shri_i32(ret, arg, 8); + tcg_gen_or_i32(ret, ret, t0); + tcg_temp_free_i32(t0); + } } static inline void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_bswap32_i32 - tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg); -#else - TCGv_i32 t0, t1; - t0 = tcg_temp_new_i32(); - t1 = tcg_temp_new_i32(); - - tcg_gen_shli_i32(t0, arg, 24); - - tcg_gen_andi_i32(t1, arg, 0x0000ff00); - tcg_gen_shli_i32(t1, t1, 8); - tcg_gen_or_i32(t0, t0, t1); - - tcg_gen_shri_i32(t1, arg, 8); - tcg_gen_andi_i32(t1, t1, 0x0000ff00); - tcg_gen_or_i32(t0, t0, t1); - - tcg_gen_shri_i32(t1, arg, 24); - tcg_gen_or_i32(ret, t0, t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(t1); -#endif + if (TCG_TARGET_HAS_bswap32_i32) { + tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg); + } else { + TCGv_i32 t0, t1; + t0 = tcg_temp_new_i32(); + t1 = tcg_temp_new_i32(); + + tcg_gen_shli_i32(t0, arg, 24); + + tcg_gen_andi_i32(t1, arg, 0x0000ff00); + tcg_gen_shli_i32(t1, t1, 8); + tcg_gen_or_i32(t0, t0, t1); + + tcg_gen_shri_i32(t1, arg, 8); + tcg_gen_andi_i32(t1, t1, 0x0000ff00); + tcg_gen_or_i32(t0, t0, t1); + + tcg_gen_shri_i32(t1, arg, 24); + tcg_gen_or_i32(ret, t0, t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(t1); + } } #if TCG_TARGET_REG_BITS == 32 @@ -1576,59 +1523,59 @@ static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) static inline void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_ext8s_i64 - tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg); -#else - tcg_gen_shli_i64(ret, arg, 56); - tcg_gen_sari_i64(ret, ret, 56); -#endif + if (TCG_TARGET_HAS_ext8s_i64) { + tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg); + } else { + tcg_gen_shli_i64(ret, arg, 56); + tcg_gen_sari_i64(ret, ret, 56); + } } static inline void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_ext16s_i64 - tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg); -#else - tcg_gen_shli_i64(ret, arg, 48); - tcg_gen_sari_i64(ret, ret, 48); -#endif + if (TCG_TARGET_HAS_ext16s_i64) { + tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg); + } else { + tcg_gen_shli_i64(ret, arg, 48); + tcg_gen_sari_i64(ret, ret, 48); + } } static inline void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_ext32s_i64 - tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg); -#else - tcg_gen_shli_i64(ret, arg, 32); - tcg_gen_sari_i64(ret, ret, 32); -#endif + if (TCG_TARGET_HAS_ext32s_i64) { + tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg); + } else { + tcg_gen_shli_i64(ret, arg, 32); + tcg_gen_sari_i64(ret, ret, 32); + } } static inline void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_ext8u_i64 - tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg); -#else - tcg_gen_andi_i64(ret, arg, 0xffu); -#endif + if (TCG_TARGET_HAS_ext8u_i64) { + tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg); + } else { + tcg_gen_andi_i64(ret, arg, 0xffu); + } } static inline void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_ext16u_i64 - tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg); -#else - tcg_gen_andi_i64(ret, arg, 0xffffu); -#endif + if (TCG_TARGET_HAS_ext16u_i64) { + tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg); + } else { + tcg_gen_andi_i64(ret, arg, 0xffffu); + } } static inline void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_ext32u_i64 - tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg); -#else - tcg_gen_andi_i64(ret, arg, 0xffffffffu); -#endif + if (TCG_TARGET_HAS_ext32u_i64) { + tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg); + } else { + tcg_gen_andi_i64(ret, arg, 0xffffffffu); + } } /* Note: we assume the target supports move between 32 and 64 bit @@ -1655,130 +1602,132 @@ static inline void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg) /* Note: we assume the six high bytes are set to zero */ static inline void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_bswap16_i64 - tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg); -#else - TCGv_i64 t0 = tcg_temp_new_i64(); + if (TCG_TARGET_HAS_bswap16_i64) { + tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg); + } else { + TCGv_i64 t0 = tcg_temp_new_i64(); - tcg_gen_ext8u_i64(t0, arg); - tcg_gen_shli_i64(t0, t0, 8); - tcg_gen_shri_i64(ret, arg, 8); - tcg_gen_or_i64(ret, ret, t0); - tcg_temp_free_i64(t0); -#endif + tcg_gen_ext8u_i64(t0, arg); + tcg_gen_shli_i64(t0, t0, 8); + tcg_gen_shri_i64(ret, arg, 8); + tcg_gen_or_i64(ret, ret, t0); + tcg_temp_free_i64(t0); + } } /* Note: we assume the four high bytes are set to zero */ static inline void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_bswap32_i64 - tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg); -#else - TCGv_i64 t0, t1; - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); + if (TCG_TARGET_HAS_bswap32_i64) { + tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg); + } else { + TCGv_i64 t0, t1; + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); - tcg_gen_shli_i64(t0, arg, 24); - tcg_gen_ext32u_i64(t0, t0); + tcg_gen_shli_i64(t0, arg, 24); + tcg_gen_ext32u_i64(t0, t0); - tcg_gen_andi_i64(t1, arg, 0x0000ff00); - tcg_gen_shli_i64(t1, t1, 8); - tcg_gen_or_i64(t0, t0, t1); + tcg_gen_andi_i64(t1, arg, 0x0000ff00); + tcg_gen_shli_i64(t1, t1, 8); + tcg_gen_or_i64(t0, t0, t1); - tcg_gen_shri_i64(t1, arg, 8); - tcg_gen_andi_i64(t1, t1, 0x0000ff00); - tcg_gen_or_i64(t0, t0, t1); + tcg_gen_shri_i64(t1, arg, 8); + tcg_gen_andi_i64(t1, t1, 0x0000ff00); + tcg_gen_or_i64(t0, t0, t1); - tcg_gen_shri_i64(t1, arg, 24); - tcg_gen_or_i64(ret, t0, t1); - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -#endif + tcg_gen_shri_i64(t1, arg, 24); + tcg_gen_or_i64(ret, t0, t1); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + } } static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_bswap64_i64 - tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg); -#else - TCGv_i64 t0 = tcg_temp_new_i64(); - TCGv_i64 t1 = tcg_temp_new_i64(); - - tcg_gen_shli_i64(t0, arg, 56); - - tcg_gen_andi_i64(t1, arg, 0x0000ff00); - tcg_gen_shli_i64(t1, t1, 40); - tcg_gen_or_i64(t0, t0, t1); - - tcg_gen_andi_i64(t1, arg, 0x00ff0000); - tcg_gen_shli_i64(t1, t1, 24); - tcg_gen_or_i64(t0, t0, t1); - - tcg_gen_andi_i64(t1, arg, 0xff000000); - tcg_gen_shli_i64(t1, t1, 8); - tcg_gen_or_i64(t0, t0, t1); - - tcg_gen_shri_i64(t1, arg, 8); - tcg_gen_andi_i64(t1, t1, 0xff000000); - tcg_gen_or_i64(t0, t0, t1); - - tcg_gen_shri_i64(t1, arg, 24); - tcg_gen_andi_i64(t1, t1, 0x00ff0000); - tcg_gen_or_i64(t0, t0, t1); - - tcg_gen_shri_i64(t1, arg, 40); - tcg_gen_andi_i64(t1, t1, 0x0000ff00); - tcg_gen_or_i64(t0, t0, t1); - - tcg_gen_shri_i64(t1, arg, 56); - tcg_gen_or_i64(ret, t0, t1); - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -#endif + if (TCG_TARGET_HAS_bswap64_i64) { + tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg); + } else { + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + + tcg_gen_shli_i64(t0, arg, 56); + + tcg_gen_andi_i64(t1, arg, 0x0000ff00); + tcg_gen_shli_i64(t1, t1, 40); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_andi_i64(t1, arg, 0x00ff0000); + tcg_gen_shli_i64(t1, t1, 24); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_andi_i64(t1, arg, 0xff000000); + tcg_gen_shli_i64(t1, t1, 8); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_shri_i64(t1, arg, 8); + tcg_gen_andi_i64(t1, t1, 0xff000000); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_shri_i64(t1, arg, 24); + tcg_gen_andi_i64(t1, t1, 0x00ff0000); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_shri_i64(t1, arg, 40); + tcg_gen_andi_i64(t1, t1, 0x0000ff00); + tcg_gen_or_i64(t0, t0, t1); + + tcg_gen_shri_i64(t1, arg, 56); + tcg_gen_or_i64(ret, t0, t1); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + } } #endif static inline void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_neg_i32 - tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg); -#else - TCGv_i32 t0 = tcg_const_i32(0); - tcg_gen_sub_i32(ret, t0, arg); - tcg_temp_free_i32(t0); -#endif + if (TCG_TARGET_HAS_neg_i32) { + tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg); + } else { + TCGv_i32 t0 = tcg_const_i32(0); + tcg_gen_sub_i32(ret, t0, arg); + tcg_temp_free_i32(t0); + } } static inline void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_neg_i64 - tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg); -#else - TCGv_i64 t0 = tcg_const_i64(0); - tcg_gen_sub_i64(ret, t0, arg); - tcg_temp_free_i64(t0); -#endif + if (TCG_TARGET_HAS_neg_i64) { + tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg); + } else { + TCGv_i64 t0 = tcg_const_i64(0); + tcg_gen_sub_i64(ret, t0, arg); + tcg_temp_free_i64(t0); + } } static inline void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg) { -#ifdef TCG_TARGET_HAS_not_i32 - tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg); -#else - tcg_gen_xori_i32(ret, arg, -1); -#endif + if (TCG_TARGET_HAS_not_i32) { + tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg); + } else { + tcg_gen_xori_i32(ret, arg, -1); + } } static inline void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) { -#ifdef TCG_TARGET_HAS_not_i64 - tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg); -#elif defined(TCG_TARGET_HAS_not_i32) && TCG_TARGET_REG_BITS == 32 +#if TCG_TARGET_REG_BITS == 64 + if (TCG_TARGET_HAS_not_i64) { + tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg); + } else { + tcg_gen_xori_i64(ret, arg, -1); + } +#else tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg)); tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg)); -#else - tcg_gen_xori_i64(ret, arg, -1); #endif } @@ -1787,18 +1736,15 @@ static inline void tcg_gen_discard_i32(TCGv_i32 arg) tcg_gen_op1_i32(INDEX_op_discard, arg); } -#if TCG_TARGET_REG_BITS == 32 static inline void tcg_gen_discard_i64(TCGv_i64 arg) { +#if TCG_TARGET_REG_BITS == 32 tcg_gen_discard_i32(TCGV_LOW(arg)); tcg_gen_discard_i32(TCGV_HIGH(arg)); -} #else -static inline void tcg_gen_discard_i64(TCGv_i64 arg) -{ tcg_gen_op1_i64(INDEX_op_discard, arg); -} #endif +} static inline void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high) { @@ -1832,165 +1778,170 @@ static inline void tcg_gen_concat32_i64(TCGv_i64 dest, TCGv_i64 low, TCGv_i64 hi static inline void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -#ifdef TCG_TARGET_HAS_andc_i32 - tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2); -#else - TCGv_i32 t0; - t0 = tcg_temp_new_i32(); - tcg_gen_not_i32(t0, arg2); - tcg_gen_and_i32(ret, arg1, t0); - tcg_temp_free_i32(t0); -#endif + if (TCG_TARGET_HAS_andc_i32) { + tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2); + } else { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_not_i32(t0, arg2); + tcg_gen_and_i32(ret, arg1, t0); + tcg_temp_free_i32(t0); + } } static inline void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { -#ifdef TCG_TARGET_HAS_andc_i64 - tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2); -#elif defined(TCG_TARGET_HAS_andc_i32) && TCG_TARGET_REG_BITS == 32 +#if TCG_TARGET_REG_BITS == 64 + if (TCG_TARGET_HAS_andc_i64) { + tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2); + } else { + TCGv_i64 t0 = tcg_temp_new_i64(); + tcg_gen_not_i64(t0, arg2); + tcg_gen_and_i64(ret, arg1, t0); + tcg_temp_free_i64(t0); + } +#else tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); -#else - TCGv_i64 t0; - t0 = tcg_temp_new_i64(); - tcg_gen_not_i64(t0, arg2); - tcg_gen_and_i64(ret, arg1, t0); - tcg_temp_free_i64(t0); #endif } static inline void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -#ifdef TCG_TARGET_HAS_eqv_i32 - tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2); -#else - tcg_gen_xor_i32(ret, arg1, arg2); - tcg_gen_not_i32(ret, ret); -#endif + if (TCG_TARGET_HAS_eqv_i32) { + tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2); + } else { + tcg_gen_xor_i32(ret, arg1, arg2); + tcg_gen_not_i32(ret, ret); + } } static inline void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { -#ifdef TCG_TARGET_HAS_eqv_i64 - tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2); -#elif defined(TCG_TARGET_HAS_eqv_i32) && TCG_TARGET_REG_BITS == 32 +#if TCG_TARGET_REG_BITS == 64 + if (TCG_TARGET_HAS_eqv_i64) { + tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2); + } else { + tcg_gen_xor_i64(ret, arg1, arg2); + tcg_gen_not_i64(ret, ret); + } +#else tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); -#else - tcg_gen_xor_i64(ret, arg1, arg2); - tcg_gen_not_i64(ret, ret); #endif } static inline void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -#ifdef TCG_TARGET_HAS_nand_i32 - tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2); -#else - tcg_gen_and_i32(ret, arg1, arg2); - tcg_gen_not_i32(ret, ret); -#endif + if (TCG_TARGET_HAS_nand_i32) { + tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2); + } else { + tcg_gen_and_i32(ret, arg1, arg2); + tcg_gen_not_i32(ret, ret); + } } static inline void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { -#ifdef TCG_TARGET_HAS_nand_i64 - tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2); -#elif defined(TCG_TARGET_HAS_nand_i32) && TCG_TARGET_REG_BITS == 32 +#if TCG_TARGET_REG_BITS == 64 + if (TCG_TARGET_HAS_nand_i64) { + tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2); + } else { + tcg_gen_and_i64(ret, arg1, arg2); + tcg_gen_not_i64(ret, ret); + } +#else tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); -#else - tcg_gen_and_i64(ret, arg1, arg2); - tcg_gen_not_i64(ret, ret); #endif } static inline void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -#ifdef TCG_TARGET_HAS_nor_i32 - tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2); -#else - tcg_gen_or_i32(ret, arg1, arg2); - tcg_gen_not_i32(ret, ret); -#endif + if (TCG_TARGET_HAS_nor_i32) { + tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2); + } else { + tcg_gen_or_i32(ret, arg1, arg2); + tcg_gen_not_i32(ret, ret); + } } static inline void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { -#ifdef TCG_TARGET_HAS_nor_i64 - tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2); -#elif defined(TCG_TARGET_HAS_nor_i32) && TCG_TARGET_REG_BITS == 32 +#if TCG_TARGET_REG_BITS == 64 + if (TCG_TARGET_HAS_nor_i64) { + tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2); + } else { + tcg_gen_or_i64(ret, arg1, arg2); + tcg_gen_not_i64(ret, ret); + } +#else tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); -#else - tcg_gen_or_i64(ret, arg1, arg2); - tcg_gen_not_i64(ret, ret); #endif } static inline void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -#ifdef TCG_TARGET_HAS_orc_i32 - tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2); -#else - TCGv_i32 t0; - t0 = tcg_temp_new_i32(); - tcg_gen_not_i32(t0, arg2); - tcg_gen_or_i32(ret, arg1, t0); - tcg_temp_free_i32(t0); -#endif + if (TCG_TARGET_HAS_orc_i32) { + tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2); + } else { + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_not_i32(t0, arg2); + tcg_gen_or_i32(ret, arg1, t0); + tcg_temp_free_i32(t0); + } } static inline void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { -#ifdef TCG_TARGET_HAS_orc_i64 - tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2); -#elif defined(TCG_TARGET_HAS_orc_i32) && TCG_TARGET_REG_BITS == 32 +#if TCG_TARGET_REG_BITS == 64 + if (TCG_TARGET_HAS_orc_i64) { + tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2); + } else { + TCGv_i64 t0 = tcg_temp_new_i64(); + tcg_gen_not_i64(t0, arg2); + tcg_gen_or_i64(ret, arg1, t0); + tcg_temp_free_i64(t0); + } +#else tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); -#else - TCGv_i64 t0; - t0 = tcg_temp_new_i64(); - tcg_gen_not_i64(t0, arg2); - tcg_gen_or_i64(ret, arg1, t0); - tcg_temp_free_i64(t0); #endif } static inline void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -#ifdef TCG_TARGET_HAS_rot_i32 - tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2); -#else - TCGv_i32 t0, t1; + if (TCG_TARGET_HAS_rot_i32) { + tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2); + } else { + TCGv_i32 t0, t1; - t0 = tcg_temp_new_i32(); - t1 = tcg_temp_new_i32(); - tcg_gen_shl_i32(t0, arg1, arg2); - tcg_gen_subfi_i32(t1, 32, arg2); - tcg_gen_shr_i32(t1, arg1, t1); - tcg_gen_or_i32(ret, t0, t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(t1); -#endif + t0 = tcg_temp_new_i32(); + t1 = tcg_temp_new_i32(); + tcg_gen_shl_i32(t0, arg1, arg2); + tcg_gen_subfi_i32(t1, 32, arg2); + tcg_gen_shr_i32(t1, arg1, t1); + tcg_gen_or_i32(ret, t0, t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(t1); + } } static inline void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { -#ifdef TCG_TARGET_HAS_rot_i64 - tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2); -#else - TCGv_i64 t0, t1; - - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - tcg_gen_shl_i64(t0, arg1, arg2); - tcg_gen_subfi_i64(t1, 64, arg2); - tcg_gen_shr_i64(t1, arg1, t1); - tcg_gen_or_i64(ret, t0, t1); - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -#endif + if (TCG_TARGET_HAS_rot_i64) { + tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2); + } else { + TCGv_i64 t0, t1; + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + tcg_gen_shl_i64(t0, arg1, arg2); + tcg_gen_subfi_i64(t1, 64, arg2); + tcg_gen_shr_i64(t1, arg1, t1); + tcg_gen_or_i64(ret, t0, t1); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + } } static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) @@ -1998,12 +1949,11 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) /* some cases can be optimized here */ if (arg2 == 0) { tcg_gen_mov_i32(ret, arg1); - } else { -#ifdef TCG_TARGET_HAS_rot_i32 + } else if (TCG_TARGET_HAS_rot_i32) { TCGv_i32 t0 = tcg_const_i32(arg2); tcg_gen_rotl_i32(ret, arg1, t0); tcg_temp_free_i32(t0); -#else + } else { TCGv_i32 t0, t1; t0 = tcg_temp_new_i32(); t1 = tcg_temp_new_i32(); @@ -2012,7 +1962,6 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) tcg_gen_or_i32(ret, t0, t1); tcg_temp_free_i32(t0); tcg_temp_free_i32(t1); -#endif } } @@ -2021,12 +1970,11 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) /* some cases can be optimized here */ if (arg2 == 0) { tcg_gen_mov_i64(ret, arg1); - } else { -#ifdef TCG_TARGET_HAS_rot_i64 + } else if (TCG_TARGET_HAS_rot_i64) { TCGv_i64 t0 = tcg_const_i64(arg2); tcg_gen_rotl_i64(ret, arg1, t0); tcg_temp_free_i64(t0); -#else + } else { TCGv_i64 t0, t1; t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); @@ -2035,44 +1983,42 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) tcg_gen_or_i64(ret, t0, t1); tcg_temp_free_i64(t0); tcg_temp_free_i64(t1); -#endif } } static inline void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { -#ifdef TCG_TARGET_HAS_rot_i32 - tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2); -#else - TCGv_i32 t0, t1; + if (TCG_TARGET_HAS_rot_i32) { + tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2); + } else { + TCGv_i32 t0, t1; - t0 = tcg_temp_new_i32(); - t1 = tcg_temp_new_i32(); - tcg_gen_shr_i32(t0, arg1, arg2); - tcg_gen_subfi_i32(t1, 32, arg2); - tcg_gen_shl_i32(t1, arg1, t1); - tcg_gen_or_i32(ret, t0, t1); - tcg_temp_free_i32(t0); - tcg_temp_free_i32(t1); -#endif + t0 = tcg_temp_new_i32(); + t1 = tcg_temp_new_i32(); + tcg_gen_shr_i32(t0, arg1, arg2); + tcg_gen_subfi_i32(t1, 32, arg2); + tcg_gen_shl_i32(t1, arg1, t1); + tcg_gen_or_i32(ret, t0, t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(t1); + } } static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) { -#ifdef TCG_TARGET_HAS_rot_i64 - tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2); -#else - TCGv_i64 t0, t1; - - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - tcg_gen_shr_i64(t0, arg1, arg2); - tcg_gen_subfi_i64(t1, 64, arg2); - tcg_gen_shl_i64(t1, arg1, t1); - tcg_gen_or_i64(ret, t0, t1); - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -#endif + if (TCG_TARGET_HAS_rot_i64) { + tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2); + } else { + TCGv_i64 t0, t1; + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + tcg_gen_shr_i64(t0, arg1, arg2); + tcg_gen_subfi_i64(t1, 64, arg2); + tcg_gen_shl_i64(t1, arg1, t1); + tcg_gen_or_i64(ret, t0, t1); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + } } static inline void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) @@ -2096,41 +2042,80 @@ static inline void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) } static inline void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, - TCGv_i32 arg2, unsigned int ofs, - unsigned int len) + TCGv_i32 arg2, unsigned int ofs, + unsigned int len) { -#ifdef TCG_TARGET_HAS_deposit_i32 - tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len); -#else - uint32_t mask = (1u << len) - 1; - TCGv_i32 t1 = tcg_temp_new_i32 (); + uint32_t mask; + TCGv_i32 t1; - tcg_gen_andi_i32(t1, arg2, mask); - tcg_gen_shli_i32(t1, t1, ofs); - tcg_gen_andi_i32(ret, arg1, ~(mask << ofs)); - tcg_gen_or_i32(ret, ret, t1); + if (ofs == 0 && len == 32) { + tcg_gen_mov_i32(ret, arg2); + return; + } + if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) { + tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len); + return; + } - tcg_temp_free_i32(t1); -#endif + mask = (1u << len) - 1; + t1 = tcg_temp_new_i32(); + + if (ofs + len < 32) { + tcg_gen_andi_i32(t1, arg2, mask); + tcg_gen_shli_i32(t1, t1, ofs); + } else { + tcg_gen_shli_i32(t1, arg2, ofs); + } + tcg_gen_andi_i32(ret, arg1, ~(mask << ofs)); + tcg_gen_or_i32(ret, ret, t1); + + tcg_temp_free_i32(t1); } static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, - TCGv_i64 arg2, unsigned int ofs, - unsigned int len) + TCGv_i64 arg2, unsigned int ofs, + unsigned int len) { -#ifdef TCG_TARGET_HAS_deposit_i64 - tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len); -#else - uint64_t mask = (1ull << len) - 1; - TCGv_i64 t1 = tcg_temp_new_i64 (); + uint64_t mask; + TCGv_i64 t1; - tcg_gen_andi_i64(t1, arg2, mask); - tcg_gen_shli_i64(t1, t1, ofs); - tcg_gen_andi_i64(ret, arg1, ~(mask << ofs)); - tcg_gen_or_i64(ret, ret, t1); + if (ofs == 0 && len == 64) { + tcg_gen_mov_i64(ret, arg2); + return; + } + if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) { + tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len); + return; + } - tcg_temp_free_i64(t1); +#if TCG_TARGET_REG_BITS == 32 + if (ofs >= 32) { + tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1)); + tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), + TCGV_LOW(arg2), ofs - 32, len); + return; + } + if (ofs + len <= 32) { + tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1), + TCGV_LOW(arg2), ofs, len); + tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1)); + return; + } #endif + + mask = (1ull << len) - 1; + t1 = tcg_temp_new_i64(); + + if (ofs + len < 64) { + tcg_gen_andi_i64(t1, arg2, mask); + tcg_gen_shli_i64(t1, t1, ofs); + } else { + tcg_gen_shli_i64(t1, arg2, ofs); + } + tcg_gen_andi_i64(ret, arg1, ~(mask << ofs)); + tcg_gen_or_i64(ret, ret, t1); + + tcg_temp_free_i64(t1); } /***************************************/ @@ -2169,22 +2154,13 @@ static inline void tcg_gen_debug_insn_start(uint64_t pc) { /* XXX: must really use a 32 bit size for TCGArg in all cases */ #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS - tcg_gen_op2ii(INDEX_op_debug_insn_start, + tcg_gen_op2ii(INDEX_op_debug_insn_start, (uint32_t)(pc), (uint32_t)(pc >> 32)); #else tcg_gen_op1i(INDEX_op_debug_insn_start, pc); #endif } -#ifdef CONFIG_EXEC_PROFILE -static inline void tcg_gen_prof_tbexec(int idx) -{ - tcg_gen_op1i(INDEX_op_prof_tbexec, idx); -} -#else -# define tcg_gen_prof_tbexec(idx) -#endif /* CONFIG_EXEC_PROFILE */ - static inline void tcg_gen_exit_tb(tcg_target_long val) { tcg_gen_op1i(INDEX_op_exit_tb, val); @@ -2313,8 +2289,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index) #endif } -#define tcg_gen_ld_ptr tcg_gen_ld_i32 -#define tcg_gen_discard_ptr tcg_gen_discard_i32 +#define tcg_gen_ld_ptr(R, A, O) tcg_gen_ld_i32(TCGV_PTR_TO_NAT(R), (A), (O)) +#define tcg_gen_discard_ptr(A) tcg_gen_discard_i32(TCGV_PTR_TO_NAT(A)) #else /* TCG_TARGET_REG_BITS == 32 */ @@ -2381,8 +2357,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index) tcg_gen_qemu_ldst_op_i64(INDEX_op_qemu_st64, arg, addr, mem_index); } -#define tcg_gen_ld_ptr tcg_gen_ld_i64 -#define tcg_gen_discard_ptr tcg_gen_discard_i64 +#define tcg_gen_ld_ptr(R, A, O) tcg_gen_ld_i64(TCGV_PTR_TO_NAT(R), (A), (O)) +#define tcg_gen_discard_ptr(A) tcg_gen_discard_i64(TCGV_PTR_TO_NAT(A)) #endif /* TCG_TARGET_REG_BITS != 32 */ @@ -2532,11 +2508,17 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index) #endif #if TCG_TARGET_REG_BITS == 32 -#define tcg_gen_add_ptr tcg_gen_add_i32 -#define tcg_gen_addi_ptr tcg_gen_addi_i32 -#define tcg_gen_ext_i32_ptr tcg_gen_mov_i32 +#define tcg_gen_add_ptr(R, A, B) tcg_gen_add_i32(TCGV_PTR_TO_NAT(R), \ + TCGV_PTR_TO_NAT(A), \ + TCGV_PTR_TO_NAT(B)) +#define tcg_gen_addi_ptr(R, A, B) tcg_gen_addi_i32(TCGV_PTR_TO_NAT(R), \ + TCGV_PTR_TO_NAT(A), (B)) +#define tcg_gen_ext_i32_ptr(R, A) tcg_gen_mov_i32(TCGV_PTR_TO_NAT(R), (A)) #else /* TCG_TARGET_REG_BITS == 32 */ -#define tcg_gen_add_ptr tcg_gen_add_i64 -#define tcg_gen_addi_ptr tcg_gen_addi_i64 -#define tcg_gen_ext_i32_ptr tcg_gen_ext_i32_i64 +#define tcg_gen_add_ptr(R, A, B) tcg_gen_add_i64(TCGV_PTR_TO_NAT(R), \ + TCGV_PTR_TO_NAT(A), \ + TCGV_PTR_TO_NAT(B)) +#define tcg_gen_addi_ptr(R, A, B) tcg_gen_addi_i64(TCGV_PTR_TO_NAT(R), \ + TCGV_PTR_TO_NAT(A), (B)) +#define tcg_gen_ext_i32_ptr(R, A) tcg_gen_ext_i32_i64(TCGV_PTR_TO_NAT(R), (A)) #endif /* TCG_TARGET_REG_BITS != 32 */ diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index bca40bb..8e06d03 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -41,6 +41,13 @@ DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */ DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) +#define IMPL(X) (X ? 0 : TCG_OPF_NOT_PRESENT) +#if TCG_TARGET_REG_BITS == 32 +# define IMPL64 TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT +#else +# define IMPL64 TCG_OPF_64BIT +#endif + DEF(mov_i32, 1, 1, 0, 0) DEF(movi_i32, 1, 0, 1, 0) DEF(setcond_i32, 1, 2, 1, 0) @@ -57,16 +64,12 @@ DEF(st_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS) DEF(add_i32, 1, 2, 0, 0) DEF(sub_i32, 1, 2, 0, 0) DEF(mul_i32, 1, 2, 0, 0) -#ifdef TCG_TARGET_HAS_div_i32 -DEF(div_i32, 1, 2, 0, 0) -DEF(divu_i32, 1, 2, 0, 0) -DEF(rem_i32, 1, 2, 0, 0) -DEF(remu_i32, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_div2_i32 -DEF(div2_i32, 2, 3, 0, 0) -DEF(divu2_i32, 2, 3, 0, 0) -#endif +DEF(div_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) +DEF(divu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) +DEF(rem_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) +DEF(remu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) +DEF(div2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32)) +DEF(divu2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32)) DEF(and_i32, 1, 2, 0, 0) DEF(or_i32, 1, 2, 0, 0) DEF(xor_i32, 1, 2, 0, 0) @@ -74,157 +77,86 @@ DEF(xor_i32, 1, 2, 0, 0) DEF(shl_i32, 1, 2, 0, 0) DEF(shr_i32, 1, 2, 0, 0) DEF(sar_i32, 1, 2, 0, 0) -#ifdef TCG_TARGET_HAS_rot_i32 -DEF(rotl_i32, 1, 2, 0, 0) -DEF(rotr_i32, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_deposit_i32 -DEF(deposit_i32, 1, 2, 2, 0) -#endif +DEF(rotl_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32)) +DEF(rotr_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32)) +DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32)) DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) -#if TCG_TARGET_REG_BITS == 32 -DEF(add2_i32, 2, 4, 0, 0) -DEF(sub2_i32, 2, 4, 0, 0) -DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) -DEF(mulu2_i32, 2, 2, 0, 0) -DEF(setcond2_i32, 1, 4, 1, 0) -#endif -#ifdef TCG_TARGET_HAS_ext8s_i32 -DEF(ext8s_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext16s_i32 -DEF(ext16s_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext8u_i32 -DEF(ext8u_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext16u_i32 -DEF(ext16u_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_bswap16_i32 -DEF(bswap16_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_bswap32_i32 -DEF(bswap32_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_not_i32 -DEF(not_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_neg_i32 -DEF(neg_i32, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_andc_i32 -DEF(andc_i32, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_orc_i32 -DEF(orc_i32, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_eqv_i32 -DEF(eqv_i32, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_nand_i32 -DEF(nand_i32, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_nor_i32 -DEF(nor_i32, 1, 2, 0, 0) -#endif -#if TCG_TARGET_REG_BITS == 64 -DEF(mov_i64, 1, 1, 0, 0) -DEF(movi_i64, 1, 0, 1, 0) -DEF(setcond_i64, 1, 2, 1, 0) +DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_REG_BITS == 32)) +DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_REG_BITS == 32)) +DEF(brcond2_i32, 0, 4, 2, + TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS | IMPL(TCG_TARGET_REG_BITS == 32)) +DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_REG_BITS == 32)) +DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32)) + +DEF(ext8s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8s_i32)) +DEF(ext16s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16s_i32)) +DEF(ext8u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8u_i32)) +DEF(ext16u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16u_i32)) +DEF(bswap16_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_bswap16_i32)) +DEF(bswap32_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_bswap32_i32)) +DEF(not_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_not_i32)) +DEF(neg_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_neg_i32)) +DEF(andc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_andc_i32)) +DEF(orc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_orc_i32)) +DEF(eqv_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_eqv_i32)) +DEF(nand_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nand_i32)) +DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32)) + +DEF(mov_i64, 1, 1, 0, IMPL64) +DEF(movi_i64, 1, 0, 1, IMPL64) +DEF(setcond_i64, 1, 2, 1, IMPL64) /* load/store */ -DEF(ld8u_i64, 1, 1, 1, 0) -DEF(ld8s_i64, 1, 1, 1, 0) -DEF(ld16u_i64, 1, 1, 1, 0) -DEF(ld16s_i64, 1, 1, 1, 0) -DEF(ld32u_i64, 1, 1, 1, 0) -DEF(ld32s_i64, 1, 1, 1, 0) -DEF(ld_i64, 1, 1, 1, 0) -DEF(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS) -DEF(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS) -DEF(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS) -DEF(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS) +DEF(ld8u_i64, 1, 1, 1, IMPL64) +DEF(ld8s_i64, 1, 1, 1, IMPL64) +DEF(ld16u_i64, 1, 1, 1, IMPL64) +DEF(ld16s_i64, 1, 1, 1, IMPL64) +DEF(ld32u_i64, 1, 1, 1, IMPL64) +DEF(ld32s_i64, 1, 1, 1, IMPL64) +DEF(ld_i64, 1, 1, 1, IMPL64) +DEF(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64) +DEF(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64) +DEF(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64) +DEF(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64) /* arith */ -DEF(add_i64, 1, 2, 0, 0) -DEF(sub_i64, 1, 2, 0, 0) -DEF(mul_i64, 1, 2, 0, 0) -#ifdef TCG_TARGET_HAS_div_i64 -DEF(div_i64, 1, 2, 0, 0) -DEF(divu_i64, 1, 2, 0, 0) -DEF(rem_i64, 1, 2, 0, 0) -DEF(remu_i64, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_div2_i64 -DEF(div2_i64, 2, 3, 0, 0) -DEF(divu2_i64, 2, 3, 0, 0) -#endif -DEF(and_i64, 1, 2, 0, 0) -DEF(or_i64, 1, 2, 0, 0) -DEF(xor_i64, 1, 2, 0, 0) +DEF(add_i64, 1, 2, 0, IMPL64) +DEF(sub_i64, 1, 2, 0, IMPL64) +DEF(mul_i64, 1, 2, 0, IMPL64) +DEF(div_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) +DEF(divu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) +DEF(rem_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) +DEF(remu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) +DEF(div2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64)) +DEF(divu2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64)) +DEF(and_i64, 1, 2, 0, IMPL64) +DEF(or_i64, 1, 2, 0, IMPL64) +DEF(xor_i64, 1, 2, 0, IMPL64) /* shifts/rotates */ -DEF(shl_i64, 1, 2, 0, 0) -DEF(shr_i64, 1, 2, 0, 0) -DEF(sar_i64, 1, 2, 0, 0) -#ifdef TCG_TARGET_HAS_rot_i64 -DEF(rotl_i64, 1, 2, 0, 0) -DEF(rotr_i64, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_deposit_i64 -DEF(deposit_i64, 1, 2, 2, 0) -#endif - -DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) -#ifdef TCG_TARGET_HAS_ext8s_i64 -DEF(ext8s_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext16s_i64 -DEF(ext16s_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext32s_i64 -DEF(ext32s_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext8u_i64 -DEF(ext8u_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext16u_i64 -DEF(ext16u_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_ext32u_i64 -DEF(ext32u_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_bswap16_i64 -DEF(bswap16_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_bswap32_i64 -DEF(bswap32_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_bswap64_i64 -DEF(bswap64_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_not_i64 -DEF(not_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_neg_i64 -DEF(neg_i64, 1, 1, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_andc_i64 -DEF(andc_i64, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_orc_i64 -DEF(orc_i64, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_eqv_i64 -DEF(eqv_i64, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_nand_i64 -DEF(nand_i64, 1, 2, 0, 0) -#endif -#ifdef TCG_TARGET_HAS_nor_i64 -DEF(nor_i64, 1, 2, 0, 0) -#endif -#endif +DEF(shl_i64, 1, 2, 0, IMPL64) +DEF(shr_i64, 1, 2, 0, IMPL64) +DEF(sar_i64, 1, 2, 0, IMPL64) +DEF(rotl_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64)) +DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64)) +DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64)) + +DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS | IMPL64) +DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64)) +DEF(ext16s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16s_i64)) +DEF(ext32s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32s_i64)) +DEF(ext8u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8u_i64)) +DEF(ext16u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16u_i64)) +DEF(ext32u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32u_i64)) +DEF(bswap16_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap16_i64)) +DEF(bswap32_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap32_i64)) +DEF(bswap64_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap64_i64)) +DEF(not_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_not_i64)) +DEF(neg_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_neg_i64)) +DEF(andc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_andc_i64)) +DEF(orc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_orc_i64)) +DEF(eqv_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_eqv_i64)) +DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64)) +DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64)) /* QEMU specific */ #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS @@ -307,8 +239,6 @@ DEF(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS) #endif /* TCG_TARGET_REG_BITS != 32 */ -#ifdef CONFIG_EXEC_PROFILE -DEF(prof_tbexec, 0, 1, 0, 0) -#endif /* CONFIG_EXEC_PROFILE */ - +#undef IMPL +#undef IMPL64 #undef DEF diff --git a/tcg/tcg.c b/tcg/tcg.c index 777a423..bea6031 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -26,7 +26,6 @@ #define USE_LIVENESS_ANALYSIS #define USE_TCG_OPTIMIZATIONS - #include "config.h" #if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG) @@ -56,7 +55,6 @@ instructions */ #define NO_CPU_IO_DEFS #include "cpu.h" -#include "exec-all.h" #include "tcg-op.h" #include "elf.h" @@ -65,16 +63,33 @@ #error GUEST_BASE not supported on this host. #endif +/* Forward declarations for functions declared in tcg-target.c and used here. */ static void tcg_target_init(TCGContext *s); static void tcg_target_qemu_prologue(TCGContext *s); static void patch_reloc(uint8_t *code_ptr, int type, tcg_target_long value, tcg_target_long addend); -static TCGOpDef tcg_op_defs[] = { +/* Forward declarations for functions declared and used in tcg-target.c. */ +static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str); +static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, + tcg_target_long arg2); +static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); +static void tcg_out_movi(TCGContext *s, TCGType type, + TCGReg ret, tcg_target_long arg); +static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, + const int *const_args); +static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, + tcg_target_long arg2); +static int tcg_target_const_match(tcg_target_long val, + const TCGArgConstraint *arg_ct); +static int tcg_target_get_call_iarg_regs_count(int flags); + +TCGOpDef tcg_op_defs[] = { #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags }, #include "tcg-opc.h" #undef DEF }; +const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs); static TCGRegSet tcg_target_available_regs[2]; static TCGRegSet tcg_target_call_clobber_regs; @@ -168,7 +183,7 @@ void *tcg_malloc_internal(TCGContext *s, int size) if (size > TCG_POOL_CHUNK_SIZE) { /* big malloc: insert a new pool (XXX: could optimize) */ - p = qemu_malloc(sizeof(TCGPool) + size); + p = g_malloc(sizeof(TCGPool) + size); p->size = size; if (s->pool_current) s->pool_current->next = p; @@ -185,7 +200,7 @@ void *tcg_malloc_internal(TCGContext *s, int size) if (!p->next) { new_pool: pool_size = TCG_POOL_CHUNK_SIZE; - p = qemu_malloc(sizeof(TCGPool) + pool_size); + p = g_malloc(sizeof(TCGPool) + pool_size); p->size = pool_size; p->next = NULL; if (s->pool_current) @@ -229,8 +244,8 @@ void tcg_context_init(TCGContext *s) total_args += n; } - args_ct = qemu_malloc(sizeof(TCGArgConstraint) * total_args); - sorted_args = qemu_malloc(sizeof(int) * total_args); + args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args); + sorted_args = g_malloc(sizeof(int) * total_args); for(op = 0; op < NB_OPS; op++) { def = &tcg_op_defs[op]; @@ -275,12 +290,15 @@ void tcg_func_start(TCGContext *s) gen_opc_ptr = gen_opc_buf; gen_opparam_ptr = gen_opparam_buf; -#if defined(CONFIG_TCG_TARGET_X86_OPT) && defined(CONFIG_SOFTMMU) - s->helper_labels = tcg_malloc(sizeof(HelperLabel) * TCG_MAX_HELPER_LABELS); - if (!s->helper_labels) { +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) + /* initialize qemu_ld/st labels which help to generate TLB miss case codes at the end of TB */ +#if defined(__i386__) || defined(__x86_64__) + s->qemu_ldst_labels = tcg_malloc(sizeof(TCGLabelQemuLdst) * TCG_MAX_QEMU_LDST); + if (!s->qemu_ldst_labels) { tcg_abort(); } - s->nb_helper_labels = 0; + s->nb_qemu_ldst_labels = 0; +#endif #endif } @@ -459,6 +477,10 @@ static inline int tcg_temp_new_internal(TCGType type, int temp_local) s->nb_temps++; } } + +#if defined(CONFIG_DEBUG_TCG) + s->temps_in_use++; +#endif return idx; } @@ -484,6 +506,13 @@ static inline void tcg_temp_free_internal(int idx) TCGTemp *ts; int k; +#if defined(CONFIG_DEBUG_TCG) + s->temps_in_use--; + if (s->temps_in_use < 0) { + fprintf(stderr, "More temporaries freed than allocated!\n"); + } +#endif + assert(idx >= s->nb_globals && idx < s->nb_temps); ts = &s->temps[idx]; assert(ts->temp_allocated != 0); @@ -537,6 +566,27 @@ TCGv_i64 tcg_const_local_i64(int64_t val) return t0; } +#if defined(CONFIG_DEBUG_TCG) +void tcg_clear_temp_count(void) +{ + TCGContext *s = &tcg_ctx; + s->temps_in_use = 0; +} + +int tcg_check_temp_count(void) +{ + TCGContext *s = &tcg_ctx; + if (s->temps_in_use) { + /* Clear the count so that we don't give another + * warning immediately next time around. + */ + s->temps_in_use = 0; + return 1; + } + return 0; +} +#endif + void tcg_register_helper(void *func, const char *name) { TCGContext *s = &tcg_ctx; @@ -562,7 +612,7 @@ void tcg_register_helper(void *func, const char *name) void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, int sizemask, TCGArg ret, int nargs, TCGArg *args) { -#ifdef TCG_TARGET_I386 +#if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64 int call_type; #endif int i; @@ -589,7 +639,7 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, *gen_opc_ptr++ = INDEX_op_call; nparam = gen_opparam_ptr++; -#ifdef TCG_TARGET_I386 +#if defined(TCG_TARGET_I386) && TCG_TARGET_REG_BITS < 64 call_type = (flags & TCG_CALL_TYPE_MASK); #endif if (ret != TCG_CALL_DUMMY_ARG) { @@ -755,7 +805,9 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size, { TCGTemp *ts; + assert(idx >= 0 && idx < s->nb_temps); ts = &s->temps[idx]; + assert(ts); if (idx < s->nb_globals) { pstrcpy(buf, buf_size, ts->name); } else { @@ -1105,18 +1157,19 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs) #if defined(CONFIG_DEBUG_TCG) i = 0; for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) { - if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) { + const TCGOpDef *def = &tcg_op_defs[op]; + if (op < INDEX_op_call + || op == INDEX_op_debug_insn_start + || (def->flags & TCG_OPF_NOT_PRESENT)) { /* Wrong entry in op definitions? */ - if (tcg_op_defs[op].used) { - fprintf(stderr, "Invalid op definition for %s\n", - tcg_op_defs[op].name); + if (def->used) { + fprintf(stderr, "Invalid op definition for %s\n", def->name); i = 1; } } else { /* Missing entry in op definitions? */ - if (!tcg_op_defs[op].used) { - fprintf(stderr, "Missing op definition for %s\n", - tcg_op_defs[op].name); + if (!def->used) { + fprintf(stderr, "Missing op definition for %s\n", def->name); i = 1; } } @@ -1170,7 +1223,7 @@ static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps) } } -/* Liveness analysis : update the opc_dead_iargs array to tell if a +/* Liveness analysis : update the opc_dead_args array to tell if a given input arguments is dead. Instructions updating dead temporaries are removed. */ static void tcg_liveness_analysis(TCGContext *s) @@ -1180,13 +1233,13 @@ static void tcg_liveness_analysis(TCGContext *s) TCGArg *args; const TCGOpDef *def; uint8_t *dead_temps; - unsigned int dead_iargs; + unsigned int dead_args; gen_opc_ptr++; /* skip end */ nb_ops = gen_opc_ptr - gen_opc_buf; - s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t)); + s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t)); dead_temps = tcg_malloc(s->nb_temps); memset(dead_temps, 1, s->nb_temps); @@ -1222,8 +1275,12 @@ static void tcg_liveness_analysis(TCGContext *s) do_not_remove_call: /* output args are dead */ + dead_args = 0; for(i = 0; i < nb_oargs; i++) { arg = args[i]; + if (dead_temps[arg]) { + dead_args |= (1 << i); + } dead_temps[arg] = 1; } @@ -1233,17 +1290,16 @@ static void tcg_liveness_analysis(TCGContext *s) } /* input args are live */ - dead_iargs = 0; - for(i = 0; i < nb_iargs; i++) { - arg = args[i + nb_oargs]; + for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { + arg = args[i]; if (arg != TCG_CALL_DUMMY_ARG) { if (dead_temps[arg]) { - dead_iargs |= (1 << i); + dead_args |= (1 << i); } dead_temps[arg] = 0; } } - s->op_dead_iargs[op_index] = dead_iargs; + s->op_dead_args[op_index] = dead_args; } args--; } @@ -1290,8 +1346,12 @@ static void tcg_liveness_analysis(TCGContext *s) do_not_remove: /* output args are dead */ + dead_args = 0; for(i = 0; i < nb_oargs; i++) { arg = args[i]; + if (dead_temps[arg]) { + dead_args |= (1 << i); + } dead_temps[arg] = 1; } @@ -1304,15 +1364,14 @@ static void tcg_liveness_analysis(TCGContext *s) } /* input args are live */ - dead_iargs = 0; - for(i = 0; i < nb_iargs; i++) { - arg = args[i + nb_oargs]; + for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) { + arg = args[i]; if (dead_temps[arg]) { - dead_iargs |= (1 << i); + dead_args |= (1 << i); } dead_temps[arg] = 0; } - s->op_dead_iargs[op_index] = dead_iargs; + s->op_dead_args[op_index] = dead_args; } break; } @@ -1329,8 +1388,8 @@ static void tcg_liveness_analysis(TCGContext *s) int nb_ops; nb_ops = gen_opc_ptr - gen_opc_buf; - s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t)); - memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t)); + s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t)); + memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t)); } #endif @@ -1411,13 +1470,19 @@ static void temp_allocate_frame(TCGContext *s, int temp) { TCGTemp *ts; ts = &s->temps[temp]; - s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1); - if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end) +#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */ + s->current_frame_offset = (s->current_frame_offset + + (tcg_target_long)sizeof(tcg_target_long) - 1) & + ~(sizeof(tcg_target_long) - 1); +#endif + if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) > + s->frame_end) { tcg_abort(); + } ts->mem_offset = s->current_frame_offset; ts->mem_reg = s->frame_reg; ts->mem_allocated = 1; - s->current_frame_offset += sizeof(tcg_target_long); + s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long); } /* free register 'reg' by spilling the corresponding temporary if necessary */ @@ -1534,7 +1599,7 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs) save_globals(s, allocated_regs); } -#define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1) +#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1) static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args) { @@ -1559,7 +1624,7 @@ static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args) static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, const TCGArg *args, - unsigned int dead_iargs) + unsigned int dead_args) { TCGTemp *ts, *ots; int reg; @@ -1569,9 +1634,9 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, ts = &s->temps[args[1]]; arg_ct = &def->args_ct[0]; - /* XXX: always mark arg dead if IS_DEAD_IARG(0) */ + /* XXX: always mark arg dead if IS_DEAD_ARG(1) */ if (ts->val_type == TEMP_VAL_REG) { - if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) { + if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) { /* the mov can be suppressed */ if (ots->val_type == TEMP_VAL_REG) s->reg_to_temp[ots->reg] = -1; @@ -1619,7 +1684,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, static void tcg_reg_alloc_op(TCGContext *s, const TCGOpDef *def, TCGOpcode opc, const TCGArg *args, - unsigned int dead_iargs) + unsigned int dead_args) { TCGRegSet allocated_regs; int i, k, nb_iargs, nb_oargs, reg; @@ -1678,8 +1743,9 @@ static void tcg_reg_alloc_op(TCGContext *s, /* if the input is aliased to an output and if it is not dead after the instruction, we must allocate a new register and move it */ - if (!IS_DEAD_IARG(i - nb_oargs)) + if (!IS_DEAD_ARG(i)) { goto allocate_in_reg; + } } } reg = ts->reg; @@ -1702,9 +1768,9 @@ static void tcg_reg_alloc_op(TCGContext *s, tcg_reg_alloc_bb_end(s, allocated_regs); } else { /* mark dead temporaries and free the associated registers */ - for(i = 0; i < nb_iargs; i++) { - arg = args[nb_oargs + i]; - if (IS_DEAD_IARG(i)) { + for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) { + arg = args[i]; + if (IS_DEAD_ARG(i)) { ts = &s->temps[arg]; if (!ts->fixed_reg) { if (ts->val_type == TEMP_VAL_REG) @@ -1752,12 +1818,16 @@ static void tcg_reg_alloc_op(TCGContext *s, if (!ts->fixed_reg) { if (ts->val_type == TEMP_VAL_REG) s->reg_to_temp[ts->reg] = -1; - ts->val_type = TEMP_VAL_REG; - ts->reg = reg; - /* temp value is modified, so the value kept in memory is - potentially not the same */ - ts->mem_coherent = 0; - s->reg_to_temp[reg] = arg; + if (IS_DEAD_ARG(i)) { + ts->val_type = TEMP_VAL_DEAD; + } else { + ts->val_type = TEMP_VAL_REG; + ts->reg = reg; + /* temp value is modified, so the value kept in memory is + potentially not the same */ + ts->mem_coherent = 0; + s->reg_to_temp[reg] = arg; + } } oarg_end: new_args[i] = reg; @@ -1785,7 +1855,7 @@ static void tcg_reg_alloc_op(TCGContext *s, static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, TCGOpcode opc, const TCGArg *args, - unsigned int dead_iargs) + unsigned int dead_args) { int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params; TCGArg arg, func_arg; @@ -1808,13 +1878,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, nb_regs = nb_params; /* assign stack slots first */ - /* XXX: preallocate call stack */ call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long); call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & ~(TCG_TARGET_STACK_ALIGN - 1); allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE); if (allocate_args) { - tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size)); + /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed, + preallocate call stack */ + tcg_abort(); } stack_offset = TCG_TARGET_CALL_STACK_OFFSET; @@ -1907,9 +1978,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, /* mark dead temporaries and free the associated registers */ - for(i = 0; i < nb_iargs; i++) { - arg = args[nb_oargs + i]; - if (IS_DEAD_IARG(i)) { + for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { + arg = args[i]; + if (IS_DEAD_ARG(i)) { ts = &s->temps[arg]; if (!ts->fixed_reg) { if (ts->val_type == TEMP_VAL_REG) @@ -1934,10 +2005,6 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, tcg_out_op(s, opc, &func_arg, &const_func_arg); - if (allocate_args) { - tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size)); - } - /* assign output registers and emit moves if needed */ for(i = 0; i < nb_oargs; i++) { arg = args[i]; @@ -1951,10 +2018,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, } else { if (ts->val_type == TEMP_VAL_REG) s->reg_to_temp[ts->reg] = -1; - ts->val_type = TEMP_VAL_REG; - ts->reg = reg; - ts->mem_coherent = 0; - s->reg_to_temp[reg] = arg; + if (IS_DEAD_ARG(i)) { + ts->val_type = TEMP_VAL_DEAD; + } else { + ts->val_type = TEMP_VAL_REG; + ts->reg = reg; + ts->mem_coherent = 0; + s->reg_to_temp[reg] = arg; + } } } @@ -1984,7 +2055,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, TCGOpcode opc; int op_index; const TCGOpDef *def; - unsigned int dead_iargs; + unsigned int dead_args; const TCGArg *args; #ifdef DEBUG_DISAS @@ -1996,38 +2067,9 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, #endif #ifdef USE_TCG_OPTIMIZATIONS -#ifdef HARDCORE_DEBUG - if (gen_opc_buf[0] != INDEX_op_debug_insn_start) { - fprintf(stderr, "FUUUUUUUUUUUUUUUUUUUUU!!!!!!!!!!!!!!!!\n"); - exit(1); - } -#define OPT_START_ADDR 0x40a5cf1c -#define OPT_END_ADDR 0x40a5cf1f - if (gen_opparam_buf[0] >= OPT_START_ADDR && gen_opparam_buf[0] <= OPT_END_ADDR) { + gen_opparam_ptr = + tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs); #endif -#ifdef CONFIG_PROFILER - s->la_time -= profile_getclock(); -#endif - gen_opparam_ptr = tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs); -#ifdef CONFIG_PROFILER - s->la_time += profile_getclock(); -#endif -#ifdef HARDCORE_DEBUG - } -#undef OPT_START_ADDR -#undef OPT_END_ADDR -#endif /* HARDCORE DEBUG */ -#endif /* USE_TCG_OPTIMIZATIONS */ - -#ifdef DEBUG_DISAS - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { - qemu_log("OP after optimizations:\n"); - tcg_dump_ops(s, logfile); - qemu_log("\n"); - } -#endif - - #ifdef CONFIG_PROFILER s->la_time -= profile_getclock(); @@ -2069,8 +2111,8 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, #if TCG_TARGET_REG_BITS == 64 case INDEX_op_mov_i64: #endif - dead_iargs = s->op_dead_iargs[op_index]; - tcg_reg_alloc_mov(s, def, args, dead_iargs); + dead_args = s->op_dead_args[op_index]; + tcg_reg_alloc_mov(s, def, args, dead_args); break; case INDEX_op_movi_i32: #if TCG_TARGET_REG_BITS == 64 @@ -2106,33 +2148,21 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, tcg_out_label(s, args[0], (long)s->code_ptr); break; case INDEX_op_call: - dead_iargs = s->op_dead_iargs[op_index]; - args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs); + dead_args = s->op_dead_args[op_index]; + args += tcg_reg_alloc_call(s, def, opc, args, dead_args); goto next; case INDEX_op_end: goto the_end; -#ifdef CONFIG_PROFILER_EX - case INDEX_op_qemu_ld8u: - case INDEX_op_qemu_ld8s: - case INDEX_op_qemu_ld16u: - case INDEX_op_qemu_ld16s: - case INDEX_op_qemu_ld32: - case INDEX_op_qemu_ld64: - s->qemu_ld_count++; - goto gen; - case INDEX_op_qemu_st8: - case INDEX_op_qemu_st16: - case INDEX_op_qemu_st32: - case INDEX_op_qemu_st64: - s->qemu_st_count++; - gen: -#endif default: + /* Sanity check that we've not introduced any unhandled opcodes. */ + if (def->flags & TCG_OPF_NOT_PRESENT) { + tcg_abort(); + } /* Note: in order to speed up the code, it would be much faster to have specialized register allocator functions for some common argument patterns */ - dead_iargs = s->op_dead_iargs[op_index]; - tcg_reg_alloc_op(s, def, opc, args, dead_iargs); + dead_args = s->op_dead_args[op_index]; + tcg_reg_alloc_op(s, def, opc, args, dead_args); break; } args += def->nb_args; @@ -2146,9 +2176,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, #endif } the_end: -#if defined(CONFIG_TCG_TARGET_X86_OPT) && defined(CONFIG_SOFTMMU) +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) +#if defined(__i386__) || defined(__x86_64__) /* Generate MMU call helpers at the end of block (currently only for qemu_ld/st) */ - tcg_out_qemu_ldst_helper_calls(s); + tcg_out_qemu_ldst_slow_path(s); +#endif #endif return -1; } diff --git a/tcg/tcg.h b/tcg/tcg.h index a3061c1..0568280 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -22,6 +22,16 @@ * THE SOFTWARE. */ #include "qemu-common.h" + +/* Target word size (must be identical to pointer size). */ +#if UINTPTR_MAX == UINT32_MAX +# define TCG_TARGET_REG_BITS 32 +#elif UINTPTR_MAX == UINT64_MAX +# define TCG_TARGET_REG_BITS 64 +#else +# error Unknown pointer size for tcg target +#endif + #include "tcg-target.h" #include "tcg-runtime.h" @@ -47,6 +57,49 @@ typedef uint64_t TCGRegSet; #error unsupported #endif +/* Turn some undef macros into false macros. */ +#if TCG_TARGET_REG_BITS == 32 +#define TCG_TARGET_HAS_div_i64 0 +#define TCG_TARGET_HAS_div2_i64 0 +#define TCG_TARGET_HAS_rot_i64 0 +#define TCG_TARGET_HAS_ext8s_i64 0 +#define TCG_TARGET_HAS_ext16s_i64 0 +#define TCG_TARGET_HAS_ext32s_i64 0 +#define TCG_TARGET_HAS_ext8u_i64 0 +#define TCG_TARGET_HAS_ext16u_i64 0 +#define TCG_TARGET_HAS_ext32u_i64 0 +#define TCG_TARGET_HAS_bswap16_i64 0 +#define TCG_TARGET_HAS_bswap32_i64 0 +#define TCG_TARGET_HAS_bswap64_i64 0 +#define TCG_TARGET_HAS_neg_i64 0 +#define TCG_TARGET_HAS_not_i64 0 +#define TCG_TARGET_HAS_andc_i64 0 +#define TCG_TARGET_HAS_orc_i64 0 +#define TCG_TARGET_HAS_eqv_i64 0 +#define TCG_TARGET_HAS_nand_i64 0 +#define TCG_TARGET_HAS_nor_i64 0 +#define TCG_TARGET_HAS_deposit_i64 0 +#endif + +#ifndef TCG_TARGET_deposit_i32_valid +#define TCG_TARGET_deposit_i32_valid(ofs, len) 1 +#endif +#ifndef TCG_TARGET_deposit_i64_valid +#define TCG_TARGET_deposit_i64_valid(ofs, len) 1 +#endif + +/* Only one of DIV or DIV2 should be defined. */ +#if defined(TCG_TARGET_HAS_div_i32) +#define TCG_TARGET_HAS_div2_i32 0 +#elif defined(TCG_TARGET_HAS_div2_i32) +#define TCG_TARGET_HAS_div_i32 0 +#endif +#if defined(TCG_TARGET_HAS_div_i64) +#define TCG_TARGET_HAS_div2_i64 0 +#elif defined(TCG_TARGET_HAS_div2_i64) +#define TCG_TARGET_HAS_div_i64 0 +#endif + typedef enum TCGOpcode { #define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name, #include "tcg-opc.h" @@ -122,20 +175,23 @@ typedef enum TCGType { typedef tcg_target_ulong TCGArg; -/* Define a type and accessor macros for varables. Using a struct is +/* Define a type and accessor macros for variables. Using a struct is nice because it gives some level of type safely. Ideally the compiler be able to see through all this. However in practice this is not true, expecially on targets with braindamaged ABIs (e.g. i386). We use plain int by default to avoid this runtime overhead. Users of tcg_gen_* don't need to know about any of this, and should treat TCGv as an opaque type. - In additon we do typechecking for different types of variables. TCGv_i32 + In addition we do typechecking for different types of variables. TCGv_i32 and TCGv_i64 are 32/64-bit variables respectively. TCGv and TCGv_ptr are aliases for target_ulong and host pointer sized values respectively. */ -#if defined(CONFIG_TCG_TARGET_X86_OPT) && defined(CONFIG_SOFTMMU) -#define TCG_MAX_HELPER_LABELS 200 +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) +#if defined(__i386__) || defined(__x86_64__) +/* Macros and structures for qemu_ld/st IR code optimization: + It looks good for TCG_MAX_HELPER_LABELS to be half of OPC_BUF_SIZE in exec-all.h. */ +#define TCG_MAX_QEMU_LDST 320 #define HL_LDST_SHIFT 4 #define HL_LDST_MASK (1 << HL_LDST_SHIFT) #define HL_ST_MASK HL_LDST_MASK @@ -143,17 +199,18 @@ typedef tcg_target_ulong TCGArg; #define IS_QEMU_LD_LABEL(L) (!((L)->opc_ext & HL_LDST_MASK)) #define IS_QEMU_ST_LABEL(L) ((L)->opc_ext & HL_LDST_MASK) -typedef struct HelperLabel { - int opc_ext; - int datalo_reg; - int datahi_reg; - int addrlo_reg; - int addrhi_reg; - int mem_index; - uint8_t *raddr; /* return address */ - uint32_t *label_ptr[2]; /* label pointer to be updated */ -} HelperLabel; -#endif /* CONFIG_TCG_TARGET_X86_OPT */ +typedef struct TCGLabelQemuLdst { + int opc_ext; /* | 27bit (reserved) | 1bit (ld/st flag) | 4bit (opc) | */ + int addrlo_reg; /* reg index for the low word of guest virtual address */ + int addrhi_reg; /* reg index for the high word of guest virtual address */ + int datalo_reg; /* reg index for the low word to be loaded or to be stored */ + int datahi_reg; /* reg index for the high word to be loaded or to be stored */ + int mem_index; /* soft MMU memory index */ + uint8_t *raddr; /* return address (located end of TB) */ + uint32_t *label_ptr[2]; /* label pointers to be updated */ +} TCGLabelQemuLdst; +#endif +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */ #ifdef CONFIG_DEBUG_TCG #define DEBUG_TCGV 1 @@ -171,12 +228,19 @@ typedef struct int i64; } TCGv_i64; +typedef struct { + int iptr; +} TCGv_ptr; + #define MAKE_TCGV_I32(i) __extension__ \ ({ TCGv_i32 make_tcgv_tmp = {i}; make_tcgv_tmp;}) #define MAKE_TCGV_I64(i) __extension__ \ ({ TCGv_i64 make_tcgv_tmp = {i}; make_tcgv_tmp;}) +#define MAKE_TCGV_PTR(i) __extension__ \ + ({ TCGv_ptr make_tcgv_tmp = {i}; make_tcgv_tmp; }) #define GET_TCGV_I32(t) ((t).i32) #define GET_TCGV_I64(t) ((t).i64) +#define GET_TCGV_PTR(t) ((t).iptr) #if TCG_TARGET_REG_BITS == 32 #define TCGV_LOW(t) MAKE_TCGV_I32(GET_TCGV_I64(t)) #define TCGV_HIGH(t) MAKE_TCGV_I32(GET_TCGV_I64(t) + 1) @@ -186,10 +250,17 @@ typedef struct typedef int TCGv_i32; typedef int TCGv_i64; +#if TCG_TARGET_REG_BITS == 32 +#define TCGv_ptr TCGv_i32 +#else +#define TCGv_ptr TCGv_i64 +#endif #define MAKE_TCGV_I32(x) (x) #define MAKE_TCGV_I64(x) (x) +#define MAKE_TCGV_PTR(x) (x) #define GET_TCGV_I32(t) (t) #define GET_TCGV_I64(t) (t) +#define GET_TCGV_PTR(t) (t) #if TCG_TARGET_REG_BITS == 32 #define TCGV_LOW(t) (t) @@ -273,9 +344,9 @@ typedef struct TCGTemp { unsigned int fixed_reg:1; unsigned int mem_coherent:1; unsigned int mem_allocated:1; - unsigned int temp_local:1; /* If true, the temp is saved accross + unsigned int temp_local:1; /* If true, the temp is saved across basic blocks. Otherwise, it is not - preserved accross basic blocks. */ + preserved across basic blocks. */ unsigned int temp_allocated:1; /* never used for code gen */ /* index of next free temp of same base type, -1 if end */ int next_free_temp; @@ -307,8 +378,8 @@ struct TCGContext { uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */ /* liveness analysis */ - uint16_t *op_dead_iargs; /* for each operation, each bit tells if the - corresponding input argument is dead */ + uint16_t *op_dead_args; /* for each operation, each bit tells if the + corresponding argument is dead */ /* tells in which temporary a given register is. It does not take into account fixed registers */ @@ -343,14 +414,17 @@ struct TCGContext { int64_t la_time; int64_t restore_count; int64_t restore_time; -#ifdef CONFIG_PROFILER_EX - int64_t qemu_ld_count; - int64_t qemu_st_count; #endif + +#ifdef CONFIG_DEBUG_TCG + int temps_in_use; #endif -#if defined(CONFIG_TCG_TARGET_X86_OPT) && defined(CONFIG_SOFTMMU) - HelperLabel *helper_labels; - int nb_helper_labels; + +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) + /* labels info for qemu_ld/st IRs + The labels help to generate TLB miss case codes at the end of TB */ + TCGLabelQemuLdst *qemu_ldst_labels; + int nb_qemu_ldst_labels; #endif }; @@ -421,6 +495,24 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void) void tcg_temp_free_i64(TCGv_i64 arg); char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg); +static inline bool tcg_arg_is_local(TCGContext *s, TCGArg arg) +{ + return s->temps[arg].temp_local; +} + +#if defined(CONFIG_DEBUG_TCG) +/* If you call tcg_clear_temp_count() at the start of a section of + * code which is not supposed to leak any TCG temporaries, then + * calling tcg_check_temp_count() at the end of the section will + * return 1 if the section did in fact leak a temporary. + */ +void tcg_clear_temp_count(void); +int tcg_check_temp_count(void); +#else +#define tcg_clear_temp_count() do { } while (0) +#define tcg_check_temp_count() 0 +#endif + void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf); #define TCG_CT_ALIAS 0x80 @@ -438,13 +530,20 @@ typedef struct TCGArgConstraint { #define TCG_MAX_OP_ARGS 16 -#define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic - block */ -#define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers - and potentially update globals. */ -#define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it - cannot be removed if its output - are not used */ +/* Bits for TCGOpDef->flags, 8 bits available. */ +enum { + /* Instruction defines the end of a basic block. */ + TCG_OPF_BB_END = 0x01, + /* Instruction clobbers call registers and potentially update globals. */ + TCG_OPF_CALL_CLOBBER = 0x02, + /* Instruction has side effects: it cannot be removed + if its outputs are not used. */ + TCG_OPF_SIDE_EFFECTS = 0x04, + /* Instruction operands are 64-bits (otherwise 32-bits). */ + TCG_OPF_64BIT = 0x08, + /* Instruction is optional and not implemented by the host. */ + TCG_OPF_NOT_PRESENT = 0x10, +}; typedef struct TCGOpDef { const char *name; @@ -457,6 +556,9 @@ typedef struct TCGOpDef { #endif } TCGOpDef; +extern TCGOpDef tcg_op_defs[]; +extern const size_t tcg_op_defs_max; + typedef struct TCGTargetOpDef { TCGOpcode op; const char *args_ct_str[TCG_MAX_OP_ARGS]; @@ -471,25 +573,27 @@ do {\ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs); #if TCG_TARGET_REG_BITS == 32 -#define tcg_const_ptr tcg_const_i32 -#define tcg_add_ptr tcg_add_i32 -#define tcg_sub_ptr tcg_sub_i32 -#define TCGv_ptr TCGv_i32 -#define GET_TCGV_PTR GET_TCGV_I32 -#define tcg_global_reg_new_ptr tcg_global_reg_new_i32 -#define tcg_global_mem_new_ptr tcg_global_mem_new_i32 -#define tcg_temp_new_ptr tcg_temp_new_i32 -#define tcg_temp_free_ptr tcg_temp_free_i32 +#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n)) +#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n)) + +#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32(V)) +#define tcg_global_reg_new_ptr(R, N) \ + TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N))) +#define tcg_global_mem_new_ptr(R, O, N) \ + TCGV_NAT_TO_PTR(tcg_global_mem_new_i32((R), (O), (N))) +#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i32()) +#define tcg_temp_free_ptr(T) tcg_temp_free_i32(TCGV_PTR_TO_NAT(T)) #else -#define tcg_const_ptr tcg_const_i64 -#define tcg_add_ptr tcg_add_i64 -#define tcg_sub_ptr tcg_sub_i64 -#define TCGv_ptr TCGv_i64 -#define GET_TCGV_PTR GET_TCGV_I64 -#define tcg_global_reg_new_ptr tcg_global_reg_new_i64 -#define tcg_global_mem_new_ptr tcg_global_mem_new_i64 -#define tcg_temp_new_ptr tcg_temp_new_i64 -#define tcg_temp_free_ptr tcg_temp_free_i64 +#define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n)) +#define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n)) + +#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64(V)) +#define tcg_global_reg_new_ptr(R, N) \ + TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N))) +#define tcg_global_mem_new_ptr(R, O, N) \ + TCGV_NAT_TO_PTR(tcg_global_mem_new_i64((R), (O), (N))) +#define tcg_temp_new_ptr() TCGV_NAT_TO_PTR(tcg_temp_new_i64()) +#define tcg_temp_free_ptr(T) tcg_temp_free_i64(TCGV_PTR_TO_NAT(T)) #endif void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, @@ -498,9 +602,8 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags, void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, int c, int right, int arith); -TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, - TCGArg *args, TCGOpDef *tcg_op_defs); - +TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args, + TCGOpDef *tcg_op_def); /* only used for debugging purposes */ void tcg_register_helper(void *func, const char *name); @@ -514,13 +617,14 @@ TCGv_i32 tcg_const_local_i32(int32_t val); TCGv_i64 tcg_const_local_i64(int64_t val); extern uint8_t code_gen_prologue[]; -#if defined(_ARCH_PPC) && !defined(_ARCH_PPC64) -#define tcg_qemu_tb_exec(tb_ptr) \ - ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr) -#else -#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr) + +/* TCG targets may use a different definition of tcg_qemu_tb_exec. */ +#if !defined(tcg_qemu_tb_exec) +# define tcg_qemu_tb_exec(env, tb_ptr) \ + ((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr) #endif -#if defined(CONFIG_TCG_TARGET_X86_OPT) -void tcg_out_qemu_ldst_helper_calls(TCGContext *s); +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) +/* qemu_ld/st generation at the end of TB */ +void tcg_out_qemu_ldst_slow_path(TCGContext *s); #endif diff --git a/tests/Makefile b/tests/Makefile index 9ded4b7..430e0c1 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -142,6 +142,10 @@ hello-mipsel: hello-mips.c test-cris: $(MAKE) -C cris check +# testsuite for the LM32 port. +test-lm32: + $(MAKE) -C lm32 check + clean: rm -f *~ *.o test-i386.out test-i386.ref \ test-x86_64.log test-x86_64.ref qruncom $(TESTS) diff --git a/tests/cris/check_openpf1.c b/tests/cris/check_openpf1.c index 1d71e0b..fdcf4c5 100644 --- a/tests/cris/check_openpf1.c +++ b/tests/cris/check_openpf1.c @@ -27,7 +27,7 @@ int main (int argc, char *argv[]) f = fopen (fnam, "rb"); if (f == NULL) abort (); - close (f); + fclose(f); /* Cover another execution path. */ if (fopen ("/nonexistent", "rb") != NULL diff --git a/tests/cris/check_openpf2.c b/tests/cris/check_openpf2.c index f44a8f3..5d56189 100644 --- a/tests/cris/check_openpf2.c +++ b/tests/cris/check_openpf2.c @@ -10,7 +10,7 @@ int main (int argc, char *argv[]) FILE *f = fopen ("check_openpf2.c", "rb"); if (f == NULL) abort (); - close (f); + fclose(f); printf ("pass\n"); return 0; } diff --git a/tests/cris/check_stat3.c b/tests/cris/check_stat3.c index 3b5b217..36a9d5d 100644 --- a/tests/cris/check_stat3.c +++ b/tests/cris/check_stat3.c @@ -13,7 +13,7 @@ int main (int argc, char *argv[]) char path[1024] = "/"; struct stat buf; - strcat (path, argv[0]); + strncat(path, argv[0], sizeof(path) - 2); if (stat (".", &buf) != 0 || !S_ISDIR (buf.st_mode)) abort (); diff --git a/tests/cris/check_stat4.c b/tests/cris/check_stat4.c index e1955ca..04f21fe 100644 --- a/tests/cris/check_stat4.c +++ b/tests/cris/check_stat4.c @@ -15,7 +15,7 @@ int main (int argc, char *argv[]) char path[1024] = "/"; struct stat buf; - strcat (path, argv[0]); + strncat(path, argv[0], sizeof(path) - 2); if (lstat (".", &buf) != 0 || !S_ISDIR (buf.st_mode)) abort (); diff --git a/tests/linux-test.c b/tests/linux-test.c index 9986e29..2e4a746 100644 --- a/tests/linux-test.c +++ b/tests/linux-test.c @@ -426,7 +426,9 @@ void test_clone(void) CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2")); while (waitpid(pid1, &status1, 0) != pid1); + free(stack1); while (waitpid(pid2, &status2, 0) != pid2); + free(stack2); if (thread1_res != 5 || thread2_res != 6) error("clone"); diff --git a/tests/qruncom.c b/tests/qruncom.c index 079f7a2..2e93aaf 100644 --- a/tests/qruncom.c +++ b/tests/qruncom.c @@ -44,20 +44,20 @@ static void set_idt(int n, unsigned int dpl) set_gate(idt_table + n, 0, dpl, 0, 0); } -void qemu_free(void *ptr) +void g_free(void *ptr) { free(ptr); } -void *qemu_malloc(size_t size) +void *g_malloc(size_t size) { return malloc(size); } -void *qemu_mallocz(size_t size) +void *g_malloc0(size_t size) { void *ptr; - ptr = qemu_malloc(size); + ptr = g_malloc(size); if (!ptr) return NULL; memset(ptr, 0, size); diff --git a/tests/test-i386.c b/tests/test-i386.c index 8f481c7..8e64bba 100644 --- a/tests/test-i386.c +++ b/tests/test-i386.c @@ -773,7 +773,7 @@ void test_fops(double a, double b) void fpu_clear_exceptions(void) { - struct __attribute__((packed)) { + struct QEMU_PACKED { uint16_t fpuc; uint16_t dummy1; uint16_t fpus; @@ -802,7 +802,7 @@ void test_fcmp(double a, double b) "fstsw %%ax\n" : "=a" (fpus) : "t" (a), "u" (b)); - printf("fcom(%f %f)=%04lx \n", + printf("fcom(%f %f)=%04lx\n", a, b, fpus & (0x4500 | FPUS_EMASK)); fpu_clear_exceptions(); asm("fucom %2\n" @@ -924,7 +924,7 @@ void test_fbcd(double a) void test_fenv(void) { - struct __attribute__((packed)) { + struct QEMU_PACKED { uint16_t fpuc; uint16_t dummy1; uint16_t fpus; @@ -934,7 +934,7 @@ void test_fenv(void) uint32_t ignored[4]; long double fpregs[8]; } float_env32; - struct __attribute__((packed)) { + struct QEMU_PACKED { uint16_t fpuc; uint16_t fpus; uint16_t fptag; @@ -1279,7 +1279,7 @@ void test_segs(void) struct { uint32_t offset; uint16_t seg; - } __attribute__((packed)) segoff; + } QEMU_PACKED segoff; ldt.entry_number = 1; ldt.base_addr = (unsigned long)&seg_data1; @@ -1441,7 +1441,7 @@ void test_misc(void) /* XXX: see if Intel Core2 and AMD64 behavior really differ. Here we implemented the Intel way which is not compatible yet with QEMU. */ - static struct __attribute__((packed)) { + static struct QEMU_PACKED { uint64_t offset; uint16_t seg; } desc; @@ -2281,7 +2281,7 @@ void test_sse_comi(double a1, double b1) } /* Force %xmm0 usage to avoid the case where both register index are 0 - to test intruction decoding more extensively */ + to test instruction decoding more extensively */ #define CVT_OP_XMM2MMX(op)\ {\ asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \ diff --git a/tests/test-mmap.c b/tests/test-mmap.c index fcb365f..c67174a 100644 --- a/tests/test-mmap.c +++ b/tests/test-mmap.c @@ -164,6 +164,7 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void) nlen = pagesize * 8; p3 = mmap(NULL, nlen, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + fail_unless (p3 != MAP_FAILED); /* Check if the mmaped areas collide. */ if (p3 < p2 @@ -174,7 +175,6 @@ void check_aligned_anonymous_unfixed_colliding_mmaps(void) /* Make sure we get pages aligned with the pagesize. The target expects this. */ - fail_unless (p3 != MAP_FAILED); p = (uintptr_t) p3; fail_unless ((p & pagemask) == 0); munmap (p2, pagesize); @@ -322,7 +322,7 @@ void check_file_unfixed_eof_mmaps(void) fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] == ((test_fsize - sizeof *p1) / sizeof *p1)); - /* Verify that the end of page is accessable and zeroed. */ + /* Verify that the end of page is accessible and zeroed. */ cp = (void *) p1; fail_unless (cp[pagesize - 4] == 0); munmap (p1, pagesize); @@ -365,7 +365,7 @@ void check_file_fixed_eof_mmaps(void) fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] == ((test_fsize - sizeof *p1) / sizeof *p1)); - /* Verify that the end of page is accessable and zeroed. */ + /* Verify that the end of page is accessible and zeroed. */ cp = (void *)p1; fail_unless (cp[pagesize - 4] == 0); munmap (p1, pagesize); diff --git a/tests/test_path.c b/tests/test_path.c index 234ed97..7265a94 100644 --- a/tests/test_path.c +++ b/tests/test_path.c @@ -4,7 +4,7 @@ #include "../cutils.c" #include "../path.c" #include "../trace.c" -#ifdef CONFIG_SIMPLE_TRACE +#ifdef CONFIG_TRACE_SIMPLE #include "../simpletrace.c" #endif diff --git a/tizen/AUTHOR b/tizen/AUTHOR deleted file mode 100644 index 89e83c9..0000000 --- a/tizen/AUTHOR +++ /dev/null @@ -1,13 +0,0 @@ -HyunGoo Kang -DoHyung Hong -SeokYeon Hwang -Hyunjun Son -SangJin Kim -KiTae Kim -JinHyung Jo -SungMin Ha -MunKyu Im -JiHye Kim -GiWoong Kim -YeongKyoon Lee diff --git a/tizen/COPYING b/tizen/COPYING deleted file mode 100644 index 36be713..0000000 --- a/tizen/COPYING +++ /dev/null @@ -1,341 +0,0 @@ - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin St, 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. - - Preamble - - The licenses for most software are designed to take away your - freedom to share and change it. By contrast, the GNU General Public - License is intended to guarantee your freedom to share and change free - software--to make sure the software is free for all its users. This - General Public License applies to most of the Free Software - Foundation's software and to any other program whose authors commit to - using it. (Some other Free Software Foundation software is covered by - the GNU Library General Public License instead.) You can apply it to - your programs, too. - - When we speak of free software, we are referring to freedom, 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 or use pieces of it - in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid - anyone to deny you these rights or to ask you to surrender the rights. - These restrictions translate to certain responsibilities for you if you - distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether - gratis or for a fee, you must give the recipients all the rights that - you have. You must make sure that they, too, receive or can get the - source code. And you must show them these terms so they know their - rights. - - We protect your rights with two steps: (1) copyright the software, and - (2) offer you this license which gives you legal permission to copy, - distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain - that everyone understands that there is no warranty for this free - software. If the software is modified by someone else and passed on, we - want its recipients to know that what they have is not the original, so - that any problems introduced by others will not reflect on the original - authors' reputations. - - Finally, any free program is threatened constantly by software - patents. We wish to avoid the danger that redistributors of a free - program will individually obtain patent licenses, in effect making the - program proprietary. To prevent this, we have made it clear that any - patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and - modification follow. - \f - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains - a notice placed by the copyright holder saying it may be distributed - under the terms of this General Public License. The "Program", below, - refers to any such program or work, and a "work based on the Program" - means either the Program or any derivative work under copyright law: - that is to say, a work containing the Program or a portion of it, - either verbatim or with modifications and/or translated into another - language. (Hereinafter, translation is included without limitation in - the term "modification".) Each licensee is addressed as "you". - - Activities other than copying, distribution and modification are not - covered by this License; they are outside its scope. The act of - running the Program is not restricted, and the output from the Program - is covered only if its contents constitute a work based on the - Program (independent of having been made by running the Program). - Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's - 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 give any other recipients of the Program a copy of this License - along with the Program. - - 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 Program or any portion - of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - \f - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the Program, - 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 Program, 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 Program. - - In addition, mere aggregation of another work not based on the Program - with the Program (or with a work based on the Program) on a volume of - a storage or distribution medium does not bring the other work under - the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, - under Section 2) in object code or executable form under the terms of - Sections 1 and 2 above provided that you also do one of the following: - - a) 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; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - - The source code for a work means the preferred form of the work for - making modifications to it. For an executable work, 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 executable. However, as a - special exception, the source code 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. - - If distribution of executable or 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 counts as - distribution of the source code, even though third parties are not - compelled to copy the source along with the object code. - \f - 4. You may not copy, modify, sublicense, or distribute the Program - except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. 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 Program or its derivative works. These actions are - prohibited by law if you do not accept this License. Therefore, by - modifying or distributing the Program (or any work based on the - Program), you indicate your acceptance of this License to do so, and - all its terms and conditions for copying, distributing or modifying - the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the - Program), the recipient automatically receives a license from the - original licensor to copy, distribute or modify the Program 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 to - this License. - - 7. 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 Program at all. For example, if a patent - license would not permit royalty-free redistribution of the Program 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 Program. - - 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. - \f - 8. If the distribution and/or use of the Program is restricted in - certain countries either by patents or by copyrighted interfaces, the - original copyright holder who places the Program 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. - - 9. The Free Software Foundation may publish revised and/or new versions - of the 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 Program - 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 Program does not specify a version number of - this License, you may choose any version ever published by the Free Software - Foundation. - - 10. If you wish to incorporate parts of the Program into other free - programs whose distribution conditions are different, 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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY - FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN - OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES - PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE - PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, - REPAIR OR CORRECTION. - - 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER - PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - \f - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest - possible use to the public, the best way to achieve this is to make it - free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA - - - Also add information on how to contact you by electronic and paper mail. - - If the program is interactive, make it output a short notice like this - when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - - The hypothetical commands `show w' and `show c' should show the appropriate - parts of the General Public License. Of course, the commands you use may - be called something other than `show w' and `show c'; they could even be - mouse-clicks or menu items--whatever suits your program. - - You should also get your employer (if you work as a programmer) or your - school, if any, to sign a "copyright disclaimer" for the program, if - necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - - This General Public License does not permit incorporating your program into - proprietary programs. If your program is a subroutine library, you may - consider it more useful to permit linking proprietary applications with the - library. If this is what you want to do, use the GNU Library General - Public License instead of this License. \ No newline at end of file diff --git a/tizen/Makefile.in b/tizen/Makefile.in deleted file mode 100644 index 3a7f248..0000000 --- a/tizen/Makefile.in +++ /dev/null @@ -1,23 +0,0 @@ -prefix = @prefix@ - -PHONE_DIR=Emulator - -all: - cd src && $(MAKE) - -clean: - cd src && $(MAKE) clean - -install: - mkdir -p $(PHONE_DIR) - cd src && $(MAKE) install - cp -dpr ./skins $(PHONE_DIR) - cp -dpr ./data $(PHONE_DIR)/x86 - cp -dpr ./license $(PHONE_DIR) - cp -a ./src/config_x86.ini $(PHONE_DIR)/x86/conf/config.ini - -distclean: clean - cd ../ && $(MAKE) distclean - rm -rf autom4te.cache config.log config.status configure - rm -rf Makefile src/Makefile - diff --git a/tizen/NOTICE b/tizen/NOTICE deleted file mode 100644 index f085dc6..0000000 --- a/tizen/NOTICE +++ /dev/null @@ -1 +0,0 @@ -Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. diff --git a/tizen/README b/tizen/README deleted file mode 100644 index d6b4b1a..0000000 --- a/tizen/README +++ /dev/null @@ -1,10 +0,0 @@ -Building -======== - -Install Ubuntu packages as follows: - -aptitude install bison flex autoconf gcc libglu1-mesa-dev libsdl1.2-dev libgtk2.0-dev libsdl-image1.2-dev libsdl-gfx1.2-dev debhelper libxml2-dev libasound2-dev libx11-dev zlib1g-dev uuid-dev libv4l-dev - -then: - -./build.sh diff --git a/tizen/build.sh b/tizen/build.sh index e615c2c..b353ce1 100755 --- a/tizen/build.sh +++ b/tizen/build.sh @@ -1,7 +1,4 @@ -#!/bin/sh +#!/bin/sh -xe -#Build-Depends: bison, flex, autoconf, gcc, libglu1-mesa-dev, libsdl1.2-dev, libgtk2.0-dev, libsdl-image1.2-dev, libsdl-gfx1.2-dev, debhelper, libxml2-dev, libasound2-dev - -autoconf -./configure -make +./emulator_configure.sh +make -j12 install diff --git a/tizen/configure.ac b/tizen/configure.ac deleted file mode 100755 index 5ad68b5..0000000 --- a/tizen/configure.ac +++ /dev/null @@ -1,101 +0,0 @@ -AC_PREREQ(2.61) -AC_INIT(emulator, 1.0) - -AC_PROG_CC -AC_PROG_MAKE_SET -AC_PROG_CXX - -AC_CHECK_PROGS(PKG_CONFIG, pkg-config, false) -AC_CHECK_PROGS(AR, ar, false) -AC_PREFIX_DEFAULT(`pwd`) - -if test "$PKG_CONFIG" = "false" -then - AC_MSG_ERROR([pkg-config not present, please install]) -fi - -# CFLAGS="-g -Wall -D_FORTIFY_SOURCE=1 -Wl,--export-dynamic" -CFLAGS="-g -Wall -D_FORTIFY_SOURCE=1" - -AC_SUBST(OS_FLAGS) -AC_SUBST(TARGETOS) -AC_SUBST(DEF) -TARGETOS=`uname -s` -if test "$TARGETOS" = "Linux" -then - OS_FLAGS="" - CC+=" $OS_FLAGS" - DEF+="_XOPEN_SOURCE=500" - DEF+=" _BSD_SOURCE" -elif test "$TARGETOS" = "CYGWIN*" -then - OS_FLAGS="-mno-cygwin -mwindows -mconsole" - CC+=" $OS_FLAGS" - DEF+="" -else - OS_FLAGS="-mwindows -mconsole" - CC+=" $OS_FLAGS" - DEF+="" -fi - -# FIXME: might be a better way to do this using debian/rules -deb_changelog="../debian/changelog" -if test -f "$deb_changelog" ; then - DEBIAN_VERSION=`head -1 "$deb_changelog" | cut -f2 -d\( | cut -f1 -d\)` -else - DEBIAN_VERSION="$PACKAGE_VERSION" -fi -AC_SUBST(DEBIAN_VERSION) - - -AC_SUBST(GLIB_CFLAGS) -AC_SUBST(GLIB_LIBS) -GLIB_CFLAGS=`$PKG_CONFIG --cflags glib-2.0` -GLIB_LIBS=`$PKG_CONFIG --libs glib-2.0` - -AC_SUBST(GTK_CFLAGS) -AC_SUBST(GTK_LIBS) -GTK_CFLAGS=`$PKG_CONFIG --cflags gtk+-2.0` -GTK_LIBS=`$PKG_CONFIG --libs gtk+-2.0` - -AC_SUBST(GMODULE_CFLAGS) -AC_SUBST(GMODULE_LIBS) -GMODULE_CFLAGS=`$PKG_CONFIG --cflags gmodule-2.0` -GMODULE_LIBS=`$PKG_CONFIG --libs gmodule-2.0` - -AC_SUBST(XML_CFLAGS) -AC_SUBST(XML_LIBS) -XML_CFLAGS=`$PKG_CONFIG --cflags libxml-2.0` -XML_LIBS=`$PKG_CONFIG --libs libxml-2.0` - -AC_SUBST(GTHREAD_CFLAGS) -AC_SUBST(GTHREAD_LIBS) -GTHREAD_CFLAGS=`$PKG_CONFIG --cflags gthread-2.0` -GTHREAD_LIBS=`$PKG_CONFIG --libs gthread-2.0` - -if test "$TARGETOS" = "Linux" -then - AC_SUBST(ALSA_CFLAGS) - AC_SUBST(ALSA_LIBS) - ALSA_CFLAGS=`$PKG_CONFIG --cflags alsa` - ALSA_LIBS=`$PKG_CONFIG --libs alsa` -fi - -saved_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS $GTK_CFLAGS -Werror" -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[]])], - [noisy_gtk_headers=no],[noisy_gtk_headers=yes]) -CFLAGS="$saved_CFLAGS" - -if test "$noisy_gtk_headers" = "yes" -then - GTK_CFLAGS="$GTK_CFLAGS -DGTK_DISABLE_DEPRECATED" -fi - -AC_CONFIG_FILES([ - Makefile - src/Makefile]) - -(cd ../ && ./qemu_configure.sh) || exit 1 - -AC_OUTPUT diff --git a/tizen/data/pc-bios/bios.bin b/tizen/data/pc-bios/bios.bin deleted file mode 100644 index bd9ad0e78255baf80fdb0c0ad67853db0a9e7c06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131072 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